Example #1
0
  def ComputeCandidatesInner( self, request_data ):
    if not self._omnifunc:
      return []

    try:
      return_value = int( vim.eval( self._omnifunc + '(1,"")' ) )
      if return_value < 0:
        return []

      omnifunc_call = [ self._omnifunc,
                        "(0,'",
                        vimsupport.EscapeForVim( request_data[ 'query' ] ),
                        "')" ]

      items = vim.eval( ''.join( omnifunc_call ) )

      if 'words' in items:
        items = items[ 'words' ]
      if not hasattr( items, '__iter__' ):
        raise TypeError( OMNIFUNC_NOT_LIST )

      return list( filter( bool, items ) )
    except ( TypeError, ValueError, vim.error ) as error:
      vimsupport.PostVimMessage(
        OMNIFUNC_RETURNED_BAD_VALUE + ' ' + str( error ) )
      return []
Example #2
0
    def ToggleLogs(self, *filenames):
        logfiles = self.GetLogfiles()
        if not filenames:
            sorted_logfiles = sorted(list(logfiles))
            try:
                logfile_index = vimsupport.SelectFromList(
                    'Which logfile do you wish to open (or close if already open)?',
                    sorted_logfiles)
            except RuntimeError as e:
                vimsupport.PostVimMessage(str(e))
                return

            logfile = logfiles[sorted_logfiles[logfile_index]]
            if not vimsupport.BufferIsVisibleForFilename(logfile):
                self._OpenLogfile(logfile)
            else:
                self._CloseLogfile(logfile)
            return

        for filename in set(filenames):
            if filename not in logfiles:
                continue

            logfile = logfiles[filename]

            if not vimsupport.BufferIsVisibleForFilename(logfile):
                self._OpenLogfile(logfile)
                continue

            self._CloseLogfile(logfile)
Example #3
0
    def _NotifyUserIfServerCrashed(self):
        if self._user_notified_about_crash or self.IsServerAlive():
            return
        self._user_notified_about_crash = True

        try:
            vimsupport.CheckFilename(self._server_stderr)
            stderr_message = STDERR_FILE_MESSAGE
        except RuntimeError:
            stderr_message = STDERR_FILE_DELETED_MESSAGE

        message = SERVER_SHUTDOWN_MESSAGE
        return_code = self._server_popen.poll()
        if return_code == server_utils.CORE_UNEXPECTED_STATUS:
            message += ' ' + CORE_UNEXPECTED_MESSAGE + ' ' + stderr_message
        elif return_code == server_utils.CORE_MISSING_STATUS:
            message += ' ' + CORE_MISSING_MESSAGE
        elif return_code == server_utils.CORE_PYTHON2_STATUS:
            message += ' ' + CORE_PYTHON2_MESSAGE
        elif return_code == server_utils.CORE_PYTHON3_STATUS:
            message += ' ' + CORE_PYTHON3_MESSAGE
        elif return_code == server_utils.CORE_OUTDATED_STATUS:
            message += ' ' + CORE_OUTDATED_MESSAGE
        else:
            message += ' ' + stderr_message
        vimsupport.PostVimMessage(message)
Example #4
0
  def NotifyUserIfServerCrashed( self ):
    if ( not self._server_popen or self._user_notified_about_crash or
         self.IsServerAlive() ):
      return
    self._user_notified_about_crash = True

    return_code = self._server_popen.poll()
    logfile = os.path.basename( self._server_stderr )
    # See https://github.com/Valloric/ycmd#exit-codes for the list of exit
    # codes.
    if return_code == 3:
      error_message = CORE_UNEXPECTED_MESSAGE.format( logfile = logfile )
    elif return_code == 4:
      error_message = CORE_MISSING_MESSAGE
    elif return_code == 7:
      error_message = CORE_OUTDATED_MESSAGE
    elif return_code == 8:
      error_message = NO_PYTHON2_SUPPORT_MESSAGE
    else:
      error_message = EXIT_CODE_UNEXPECTED_MESSAGE.format( code = return_code,
                                                           logfile = logfile )

    if return_code != 8:
      error_message = SERVER_SHUTDOWN_MESSAGE + ' ' + error_message
    self._logger.error( error_message )
    vimsupport.PostVimMessage( error_message )
Example #5
0
    def _NotifyUserIfServerCrashed(self):
        if (not self._server_popen or self._user_notified_about_crash
                or self.IsServerAlive()):
            return
        self._user_notified_about_crash = True

        return_code = self._server_popen.poll()
        logfile = os.path.basename(self._server_stderr)
        if return_code == server_utils.CORE_UNEXPECTED_STATUS:
            error_message = CORE_UNEXPECTED_MESSAGE.format(logfile=logfile)
        elif return_code == server_utils.CORE_MISSING_STATUS:
            error_message = CORE_MISSING_MESSAGE
        elif return_code == server_utils.CORE_PYTHON2_STATUS:
            error_message = CORE_PYTHON2_MESSAGE
        elif return_code == server_utils.CORE_PYTHON3_STATUS:
            error_message = CORE_PYTHON3_MESSAGE
        elif return_code == server_utils.CORE_OUTDATED_STATUS:
            error_message = CORE_OUTDATED_MESSAGE
        else:
            error_message = EXIT_CODE_UNEXPECTED_MESSAGE.format(
                code=return_code, logfile=logfile)

        error_message = SERVER_SHUTDOWN_MESSAGE + ' ' + error_message
        self._logger.error(error_message)
        vimsupport.PostVimMessage(error_message)
 def _NotifyUserIfServerCrashed(self):
     if self._user_notified_about_crash or self.IsServerAlive():
         return
     self._user_notified_about_crash = True
     if self._server_stderr:
         try:
             with open(self._server_stderr, 'r') as server_stderr_file:
                 error_output = ''.join(server_stderr_file.readlines()
                                        [:-NUM_YCMD_STDERR_LINES_ON_CRASH])
                 vimsupport.PostMultiLineNotice(
                     SERVER_CRASH_MESSAGE_STDERR_FILE + error_output)
         except IOError:
             vimsupport.PostVimMessage(
                 SERVER_CRASH_MESSAGE_STDERR_FILE_DELETED)
     else:
         vimsupport.PostVimMessage(SERVER_CRASH_MESSAGE_SAME_STDERR)
    def _EchoDiagnosticForLine(self, line_num):
        buffer_num = vim.current.buffer.number
        diags = self._buffer_number_to_line_to_diags[buffer_num][line_num]
        if not diags:
            if self._diag_message_needs_clearing:
                # Clear any previous diag echo
                vimsupport.PostVimMessage('', warning=False)
                self._diag_message_needs_clearing = False
            return

        text = diags[0]['text']
        if diags[0].get('fixit_available', False):
            text += ' (FixIt)'

        vimsupport.PostVimMessage(text, warning=False, truncate=True)
        self._diag_message_needs_clearing = True
Example #8
0
    def ShowDetailedDiagnostic(self):
        detailed_diagnostic = BaseRequest().PostDataToHandler(
            BuildRequestData(), 'detailed_diagnostic')

        if detailed_diagnostic and 'message' in detailed_diagnostic:
            vimsupport.PostVimMessage(detailed_diagnostic['message'],
                                      warning=False)
Example #9
0
    def CandidatesForQueryAsyncInner(self, query, unused_start_column):
        if not self.omnifunc:
            self.stored_candidates = None
            return

        try:
            return_value = int(vim.eval(self.omnifunc + '(1,"")'))
            if return_value < 0:
                self.stored_candidates = None
                return

            omnifunc_call = [
                self.omnifunc, "(0,'",
                vimsupport.EscapeForVim(query), "')"
            ]

            items = vim.eval(''.join(omnifunc_call))

            if 'words' in items:
                items = items['words']
            if not hasattr(items, '__iter__'):
                raise TypeError(OMNIFUNC_NOT_LIST)

            self.stored_candidates = filter(bool, items)
        except (TypeError, ValueError) as error:
            vimsupport.PostVimMessage(OMNIFUNC_RETURNED_BAD_VALUE + ' ' +
                                      str(error))
            self.stored_candidates = None
            return
Example #10
0
    def _GetDefinitionsList(self, declaration=False):
        definitions = []
        script = self._GetJediScript()
        try:
            if declaration:
                definitions = script.goto_definitions()
            else:
                definitions = script.goto_assignments()
        except jedi.NotFoundError:
            vimsupport.PostVimMessage(
                "Cannot follow nothing. Put your cursor on a valid name.")
        except Exception as e:
            vimsupport.PostVimMessage(
                "Caught exception, aborting. Full error: " + str(e))

        return definitions
Example #11
0
  def _SetUpServer( self ):
    self._available_completers = {}
    self._user_notified_about_crash = False
    self._filetypes_with_keywords_loaded = set()
    self._server_is_ready_with_cache = False
    self._message_poll_request = None

    self._user_options = base.GetUserOptions()
    self._omnicomp = OmniCompleter( self._user_options )
    self._buffers = BufferDict( self._user_options )

    self._SetLogLevel()

    hmac_secret = os.urandom( HMAC_SECRET_LENGTH )
    options_dict = dict( self._user_options )
    options_dict[ 'hmac_secret' ] = utils.ToUnicode(
      base64.b64encode( hmac_secret ) )
    options_dict[ 'server_keep_logfiles' ] = self._user_options[
      'keep_logfiles' ]

    # The temp options file is deleted by ycmd during startup.
    with NamedTemporaryFile( delete = False, mode = 'w+' ) as options_file:
      json.dump( options_dict, options_file )

    server_port = utils.GetUnusedLocalhostPort()

    BaseRequest.server_location = 'http://127.0.0.1:' + str( server_port )
    BaseRequest.hmac_secret = hmac_secret

    try:
      python_interpreter = paths.PathToPythonInterpreter()
    except RuntimeError as error:
      error_message = (
        "Unable to start the ycmd server. {0}. "
        "Correct the error then restart the server "
        "with ':YcmRestartServer'.".format( str( error ).rstrip( '.' ) ) )
      self._logger.exception( error_message )
      vimsupport.PostVimMessage( error_message )
      return

    args = [ python_interpreter,
             paths.PathToServerScript(),
             '--port={0}'.format( server_port ),
             '--options_file={0}'.format( options_file.name ),
             '--log={0}'.format( self._user_options[ 'log_level' ] ),
             '--idle_suicide_seconds={0}'.format(
                SERVER_IDLE_SUICIDE_SECONDS ) ]

    self._server_stdout = utils.CreateLogfile(
        SERVER_LOGFILE_FORMAT.format( port = server_port, std = 'stdout' ) )
    self._server_stderr = utils.CreateLogfile(
        SERVER_LOGFILE_FORMAT.format( port = server_port, std = 'stderr' ) )
    args.append( '--stdout={0}'.format( self._server_stdout ) )
    args.append( '--stderr={0}'.format( self._server_stderr ) )

    if self._user_options[ 'keep_logfiles' ]:
      args.append( '--keep_logfiles' )

    self._server_popen = utils.SafePopen( args, stdin_windows = PIPE,
                                          stdout = PIPE, stderr = PIPE )
Example #12
0
    def _NotifyUserIfServerCrashed(self):
        if self._user_notified_about_crash or self.IsServerAlive():
            return
        self._user_notified_about_crash = True

        return_code = self._server_popen.poll()
        if return_code == server_utils.CORE_UNEXPECTED_STATUS:
            error_message = CORE_UNEXPECTED_MESSAGE
        elif return_code == server_utils.CORE_MISSING_STATUS:
            error_message = CORE_MISSING_MESSAGE
        elif return_code == server_utils.CORE_PYTHON2_STATUS:
            error_message = CORE_PYTHON2_MESSAGE
        elif return_code == server_utils.CORE_PYTHON3_STATUS:
            error_message = CORE_PYTHON3_MESSAGE
        elif return_code == server_utils.CORE_OUTDATED_STATUS:
            error_message = CORE_OUTDATED_MESSAGE
        else:
            error_message = EXIT_CODE_UNEXPECTED_MESSAGE.format(
                code=return_code)

        server_stderr = '\n'.join(
            utils.ToUnicode(self._server_popen.stderr.read()).splitlines())
        if server_stderr:
            self._logger.error(server_stderr)

        error_message = SERVER_SHUTDOWN_MESSAGE + ' ' + error_message
        self._logger.error(error_message)
        vimsupport.PostVimMessage(error_message)
Example #13
0
    def _SetUpServer(self):
        self._available_completers = {}
        self._user_notified_about_crash = False
        self._filetypes_with_keywords_loaded = set()
        self._server_is_ready_with_cache = False
        self._message_poll_request = None

        base.LoadJsonDefaultsIntoVim()
        user_options_store.SetAll(base.BuildServerConf())
        self._user_options = user_options_store.GetAll()
        self._omnicomp = OmniCompleter(self._user_options)
        self._buffers = BufferDict(self._user_options)

        self._SetLogLevel()

        hmac_secret = os.urandom(HMAC_SECRET_LENGTH)
        options_dict = dict(self._user_options)
        options_dict['hmac_secret'] = utils.ToUnicode(
            base64.b64encode(hmac_secret))
        options_dict['server_keep_logfiles'] = self._user_options[
            'keep_logfiles']

        # The temp options file is deleted by ycmd during startup.
        with NamedTemporaryFile(delete=False, mode='w+') as options_file:
            json.dump(options_dict, options_file)

        server_port = utils.GetUnusedLocalhostPort()

        BaseRequest.server_location = 'http://127.0.0.1:' + str(server_port)
        BaseRequest.hmac_secret = hmac_secret

        this_file_path = os.path.dirname(os.path.realpath(__file__))
        tabnine_binary_path = os.path.join(this_file_path, '../../binaries/')

        args = [
            '--client=vim', '--port={0}'.format(server_port),
            '--options_file={0}'.format(options_file.name),
            '--log={0}'.format(self._user_options['log_level']),
            '--idle_suicide_seconds={0}'.format(SERVER_IDLE_SUICIDE_SECONDS)
        ]

        self._server_stdout = utils.CreateLogfile(
            SERVER_LOGFILE_FORMAT.format(port=server_port, std='stdout'))
        self._server_stderr = utils.CreateLogfile(
            SERVER_LOGFILE_FORMAT.format(port=server_port, std='stderr'))
        args.append('--stdout={0}'.format(self._server_stdout))
        args.append('--stderr={0}'.format(self._server_stderr))

        if self._user_options['keep_logfiles']:
            args.append('--keep_logfiles')

        try:
            self._server_popen = start_tabnine_proc(
                cmd_args=args, binary_dir=tabnine_binary_path)
        except RuntimeError as error:
            error_message = str(error)
            self._logger.exception(error_message)
            vimsupport.PostVimMessage(error_message)
            return
Example #14
0
    def _GoToDeclaration(self):
        location = self._LocationForGoTo('GetDeclarationLocation')
        if not location or not location.IsValid():
            vimsupport.PostVimMessage('Can\'t jump to declaration.')
            return

        vimsupport.JumpToLocation(location.filename_, location.line_number_,
                                  location.column_number_)
Example #15
0
def HandleServerException(exception):
    serialized_exception = str(exception)

    # We ignore the exception about the file already being parsed since it comes
    # up often and isn't something that's actionable by the user.
    if 'already being parsed' in serialized_exception:
        return
    vimsupport.PostVimMessage(serialized_exception)
Example #16
0
 def _GoToDefinitionElseDeclaration(self):
     definitions = self._GetDefinitionsList() or \
         self._GetDefinitionsList( declaration = True )
     if definitions:
         self._JumpToLocation(definitions)
     else:
         vimsupport.PostVimMessage(
             'Can\'t jump to definition or declaration.')
Example #17
0
    def ShowDetailedDiagnostic(self):
        with HandleServerException():
            detailed_diagnostic = BaseRequest.PostDataToHandler(
                BuildRequestData(), 'detailed_diagnostic')

            if 'message' in detailed_diagnostic:
                vimsupport.PostVimMessage(detailed_diagnostic['message'],
                                          warning=False)
Example #18
0
 def Response(self):
     if not self._response_future:
         return []
     try:
         return _ConvertCompletionResponseToVimDatas(
             JsonFromFuture(self._response_future))
     except Exception as e:
         vimsupport.PostVimMessage(str(e))
     return []
 def Response( self ):
   if not self._response_future:
     return []
   try:
     return [ _ConvertCompletionDataToVimData( x )
              for x in JsonFromFuture( self._response_future ) ]
   except Exception as e:
     vimsupport.PostVimMessage( str( e ) )
   return []
    def _EchoDiagnosticForLine(self, line_num):
        self._previous_diag_line_number = line_num

        diags = self._line_to_diags[line_num]
        if not diags:
            if self._diag_message_needs_clearing:
                # Clear any previous diag echo
                vimsupport.PostVimMessage('', warning=False)
                self._diag_message_needs_clearing = False
            return

        first_diag = diags[0]
        text = first_diag['text']
        if first_diag.get('fixit_available', False):
            text += ' (FixIt)'

        vimsupport.PostVimMessage(text, warning=False, truncate=True)
        self._diag_message_needs_clearing = True
Example #21
0
 def _GoToDefinition(self):
     """ Jump to definition of identifier under cursor """
     definition = self._GetResponse('/gotodefinition',
                                    self._DefaultParameters())
     if definition['FileName'] != None:
         vimsupport.JumpToLocation(definition['FileName'],
                                   definition['Line'], definition['Column'])
     else:
         vimsupport.PostVimMessage('Can\'t jump to definition')
Example #22
0
 def _NotifyUserIfServerCrashed(self):
     if self._IsServerAlive():
         return
     if self._server_stderr:
         with open(self._server_stderr, 'r') as server_stderr_file:
             vimsupport.PostMultiLineNotice(
                 SERVER_CRASH_MESSAGE_STDERR_FILE +
                 server_stderr_file.read())
     else:
         vimsupport.PostVimMessage(SERVER_CRASH_MESSAGE_SAME_STDERR)
Example #23
0
 def ShowDetailedDiagnostic(self):
     if not self.IsServerAlive():
         return
     try:
         debug_info = BaseRequest.PostDataToHandler(BuildRequestData(),
                                                    'detailed_diagnostic')
         if 'message' in debug_info:
             vimsupport.EchoText(debug_info['message'])
     except ServerError as e:
         vimsupport.PostVimMessage(str(e))
Example #24
0
 def CandidatesFromStoredRequest(self):
     if not self.completions_future:
         return []
     results = [
         CompletionDataToDict(x)
         for x in self.completions_future.GetResults()
     ]
     if not results:
         vimsupport.PostVimMessage(
             'No completions found; errors in the file?')
     return results
Example #25
0
    def _HandleFixitResponse(self):
        if not len(self._response['fixits']):
            vimsupport.PostVimMessage('No fixits found for current line',
                                      warning=False)
        else:
            try:
                fixit_index = 0

                # When there are multiple fixit suggestions, present them as a list to
                # the user hand have her choose which one to apply.
                if len(self._response['fixits']) > 1:
                    fixit_index = vimsupport.SelectFromList(
                        "Multiple FixIt suggestions are available at this location. "
                        "Which one would you like to apply?",
                        [fixit['text'] for fixit in self._response['fixits']])

                vimsupport.ReplaceChunks(
                    self._response['fixits'][fixit_index]['chunks'])
            except RuntimeError as e:
                vimsupport.PostVimMessage(str(e))
Example #26
0
 def Start(self):
     request_data = BuildRequestData()
     request_data.update({
         'completer_target': self._completer_target,
         'command_arguments': self._arguments
     })
     try:
         self._response = self.PostDataToHandler(request_data,
                                                 'run_completer_command')
     except ServerError as e:
         vimsupport.PostVimMessage(e)
Example #27
0
 def _NotifyUserIfServerCrashed(self):
     if self._IsServerAlive():
         return
     if self._server_stderr:
         with open(self._server_stderr, 'r') as server_stderr_file:
             error_output = ''.join(server_stderr_file.readlines()
                                    [:-NUM_YCMD_STDERR_LINES_ON_CRASH])
             vimsupport.PostMultiLineNotice(
                 SERVER_CRASH_MESSAGE_STDERR_FILE + error_output)
     else:
         vimsupport.PostVimMessage(SERVER_CRASH_MESSAGE_SAME_STDERR)
Example #28
0
    def ShowDiagnostics(self):
        if not self.ForceCompileAndDiagnostics():
            return

        if not self._PopulateLocationListWithLatestDiagnostics():
            vimsupport.PostVimMessage('No warnings or errors detected.',
                                      warning=False)
            return

        if self._user_options['open_loclist_on_ycm_diags']:
            vimsupport.OpenLocationList(focus=True)
Example #29
0
    def ComputeCandidatesInner(self, request_data):
        if not self._omnifunc:
            return []

        # Calling directly the omnifunc may move the cursor position. This is the
        # case with the default Vim omnifunc for C-family languages
        # (ccomplete#Complete) which calls searchdecl to find a declaration. This
        # function is supposed to move the cursor to the found declaration but it
        # doesn't when called through the omni completion mapping (CTRL-X CTRL-O).
        # So, we restore the cursor position after the omnifunc calls.
        line, column = vimsupport.CurrentLineAndColumn()

        try:
            start_column = vimsupport.GetIntValue(self._omnifunc + '(1,"")')
            if start_column < 0:
                # FIXME: Technically, if the returned value is -1 we should raise an
                # error.
                return []

            # Use the start column calculated by the omnifunc, rather than our own
            # interpretation. This is important for certain languages where our
            # identifier detection is either incorrect or not compatible with the
            # behaviour of the omnifunc. Note: do this before calling the omnifunc
            # because it affects the value returned by 'query'.
            request_data['start_column'] = start_column + 1

            # Vim internally moves the cursor to the start column before calling again
            # the omnifunc. Some omnifuncs like the one defined by the
            # LanguageClient-neovim plugin depend on this behavior to compute the list
            # of candidates.
            vimsupport.SetCurrentLineAndColumn(line, start_column)

            omnifunc_call = [
                self._omnifunc, "(0,'",
                vimsupport.EscapeForVim(request_data['query']), "')"
            ]
            items = vim.eval(''.join(omnifunc_call))

            if isinstance(items, dict) and 'words' in items:
                items = items['words']

            if not hasattr(items, '__iter__'):
                raise TypeError(OMNIFUNC_NOT_LIST)

            return list(filter(bool, items))

        except (TypeError, ValueError, vim.error) as error:
            vimsupport.PostVimMessage(OMNIFUNC_RETURNED_BAD_VALUE + ' ' +
                                      str(error))
            return []

        finally:
            vimsupport.SetCurrentLineAndColumn(line, column)
Example #30
0
 def BuildExtraConfData( extra_conf_vim_data ):
   extra_conf_data = {}
   for expr in extra_conf_vim_data:
     try:
       extra_conf_data[ expr ] = vimsupport.VimExpressionToPythonType( expr )
     except vim.error:
       message = (
         "Error evaluating '{expr}' in the 'g:ycm_extra_conf_vim_data' "
         "option.".format( expr = expr ) )
       vimsupport.PostVimMessage( message, truncate = True )
       self._logger.exception( message )
   return extra_conf_data