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 []
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)
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)
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 )
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
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)
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
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
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 )
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)
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
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_)
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)
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.')
def ShowDetailedDiagnostic(self): with HandleServerException(): detailed_diagnostic = BaseRequest.PostDataToHandler( BuildRequestData(), 'detailed_diagnostic') if 'message' in detailed_diagnostic: vimsupport.PostVimMessage(detailed_diagnostic['message'], warning=False)
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
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')
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)
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))
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
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))
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)
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)
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)
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)
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