def AddBufferIdentifiers( self, request_data ): filetype = request_data[ 'filetypes' ][ 0 ] filepath = request_data[ 'filepath' ] collect_from_comments_and_strings = bool( self.user_options[ 'collect_identifiers_from_comments_and_strings' ] ) if not filetype or not filepath: return text = request_data[ 'file_data' ][ filepath ][ 'contents' ] self._logger.info( 'Adding buffer identifiers for file: %s', filepath ) self._completer.AddIdentifiersToDatabaseFromBuffer( ToUtf8IfNeeded( text ), ToUtf8IfNeeded( filetype ), ToUtf8IfNeeded( filepath ), collect_from_comments_and_strings )
def _FlagsForRequest(self, request_data): filename = ToUtf8IfNeeded(request_data['filepath']) if 'compilation_flags' in request_data: return PrepareFlagsForClang(request_data['compilation_flags'], filename) client_data = request_data.get('extra_conf_data', None) return self._flags.FlagsForFile(filename, client_data=client_data)
def ComputeCandidatesInner(self, request_data): current_line = request_data['line_value'] start_column = request_data['start_column'] filepath = ToUtf8IfNeeded(request_data['filepath']) filetypes = request_data['file_data'][filepath]['filetypes'] line = current_line[:start_column] if InCFamilyFile(filetypes): include_match = self._include_regex.search(line) if include_match: path_dir = line[include_match.end():] # We do what GCC does for <> versus "": # http://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html include_current_file_dir = '<' not in include_match.group() return _GenerateCandidatesForPaths( self.GetPathsIncludeCase(path_dir, include_current_file_dir, filepath)) path_match = self._path_regex.search(line) path_dir = os.path.expanduser(path_match.group()) if path_match else '' return _GenerateCandidatesForPaths( _GetPathsStandardCase( path_dir, self.user_options['filepath_completion_use_working_dir'], filepath))
def AtIncludeStatementStart(self, request_data): start_column = request_data['start_column'] current_line = request_data['line_value'] filepath = ToUtf8IfNeeded(request_data['filepath']) filetypes = request_data['file_data'][filepath]['filetypes'] return (InCFamilyFile(filetypes) and self._include_start_regex.match( current_line[:start_column]))
def GetUnsavedFilesVector(self, request_data): files = ycm_core.UnsavedFileVec() for filename, file_data in request_data['file_data'].iteritems(): if not ClangAvailableForFiletypes(file_data['filetypes']): continue contents = file_data['contents'] if not contents or not filename: continue unsaved_file = ycm_core.UnsavedFile() utf8_contents = ToUtf8IfNeeded(contents) unsaved_file.contents_ = utf8_contents unsaved_file.length_ = len(utf8_contents) unsaved_file.filename_ = ToUtf8IfNeeded(filename) files.append(unsaved_file) return files
def _ConvertCompletionDataToVimData( completion_data ): # see :h complete-items for a description of the dictionary fields vim_data = { 'word' : ToUtf8IfNeeded( completion_data[ 'insertion_text' ] ), 'dup' : 1, } if 'menu_text' in completion_data: vim_data[ 'abbr' ] = ToUtf8IfNeeded( completion_data[ 'menu_text' ] ) if 'extra_menu_info' in completion_data: vim_data[ 'menu' ] = ToUtf8IfNeeded( completion_data[ 'extra_menu_info' ] ) if 'kind' in completion_data: vim_data[ 'kind' ] = ToUtf8IfNeeded( completion_data[ 'kind' ] ) if 'detailed_info' in completion_data: vim_data[ 'info' ] = ToUtf8IfNeeded( completion_data[ 'detailed_info' ] ) return vim_data
def _CallExtraConfFlagsForFile(module, filename, client_data): filename = ToUtf8IfNeeded(filename) # For the sake of backwards compatibility, we need to first check whether the # FlagsForFile function in the extra conf module even allows keyword args. if inspect.getargspec(module.FlagsForFile).keywords: return module.FlagsForFile(filename, client_data=client_data) else: return module.FlagsForFile(filename)
def ComputeCandidatesInner(self, request_data): filename = request_data['filepath'] if not filename: return if self._completer.UpdatingTranslationUnit(ToUtf8IfNeeded(filename)): raise RuntimeError(PARSING_FILE_MESSAGE) flags = self._FlagsForRequest(request_data) if not flags: raise RuntimeError(NO_COMPILE_FLAGS_MESSAGE) files = self.GetUnsavedFilesVector(request_data) line = request_data['line_num'] + 1 column = request_data['start_column'] + 1 results = self._completer.CandidatesForLocationInFile( ToUtf8IfNeeded(filename), line, column, files, flags) if not results: raise RuntimeError(NO_COMPLETIONS_MESSAGE) return [ConvertCompletionData(x) for x in results]
def EchoTextVimWidth( text ): vim_width = GetIntValue( '&columns' ) truncated_text = ToUtf8IfNeeded( text )[ : int( vim_width * 0.9 ) ] truncated_text.replace( '\n', ' ' ) old_ruler = GetIntValue( '&ruler' ) old_showcmd = GetIntValue( '&showcmd' ) vim.command( 'set noruler noshowcmd' ) EchoText( truncated_text, False ) vim.command( 'let &ruler = {0}'.format( old_ruler ) ) vim.command( 'let &showcmd = {0}'.format( old_showcmd ) )
def ConvertDiagnosticToQfFormat( diagnostic ): # see :h getqflist for a description of the dictionary fields # Note that, as usual, Vim is completely inconsistent about whether # line/column numbers are 1 or 0 based in its various APIs. Here, it wants # them to be 1-based. location = diagnostic[ 'location' ] return { 'bufnr' : GetBufferNumberForFilename( location[ 'filepath' ] ), 'lnum' : location[ 'line_num' ] + 1, 'col' : location[ 'column_num' ] + 1, 'text' : ToUtf8IfNeeded( diagnostic[ 'text' ] ), 'type' : diagnostic[ 'kind' ], 'valid' : 1 }
def _LocationForGoTo(self, goto_function, request_data): filename = request_data['filepath'] if not filename: raise ValueError(INVALID_FILE_MESSAGE) flags = self._FlagsForRequest(request_data) if not flags: raise ValueError(NO_COMPILE_FLAGS_MESSAGE) files = self.GetUnsavedFilesVector(request_data) line = request_data['line_num'] + 1 column = request_data['column_num'] + 1 return getattr(self._completer, goto_function)(ToUtf8IfNeeded(filename), line, column, files, flags)
def FilterAndSortCandidates(self, candidates, query): if not candidates: return [] # We need to handle both an omni_completer style completer and a server # style completer if 'words' in candidates: candidates = candidates['words'] sort_property = '' if 'word' in candidates[0]: sort_property = 'word' elif 'insertion_text' in candidates[0]: sort_property = 'insertion_text' matches = FilterAndSortCandidates(candidates, sort_property, ToUtf8IfNeeded(query)) return matches
def AddIdentifiersFromTagFiles(self, tag_files): absolute_paths_to_tag_files = ycm_core.StringVec() for tag_file in tag_files: try: current_mtime = os.path.getmtime(tag_file) except: continue last_mtime = self._tags_file_last_mtime[tag_file] # We don't want to repeatedly process the same file over and over; we only # process if it's changed since the last time we looked at it if current_mtime <= last_mtime: continue self._tags_file_last_mtime[tag_file] = current_mtime absolute_paths_to_tag_files.append(ToUtf8IfNeeded(tag_file)) if not absolute_paths_to_tag_files: return self._completer.AddIdentifiersToDatabaseFromTagFiles( absolute_paths_to_tag_files)
def _SanitizeFlags(flags): """Drops unsafe flags. Currently these are only -arch flags; they tend to crash libclang.""" sanitized_flags = [] saw_arch = False for i, flag in enumerate(flags): if flag == '-arch': saw_arch = True continue elif flag.startswith('-arch'): continue elif saw_arch: saw_arch = False continue sanitized_flags.append(flag) vector = ycm_core.StringVec() for flag in sanitized_flags: vector.append(ToUtf8IfNeeded(flag)) return vector
def OnFileReadyToParse(self, request_data): filename = request_data['filepath'] contents = request_data['file_data'][filename]['contents'] if contents.count('\n') < MIN_LINES_IN_FILE_TO_PARSE: raise ValueError(FILE_TOO_SHORT_MESSAGE) if not filename: raise ValueError(INVALID_FILE_MESSAGE) flags = self._FlagsForRequest(request_data) if not flags: raise ValueError(NO_COMPILE_FLAGS_MESSAGE) diagnostics = self._completer.UpdateTranslationUnit( ToUtf8IfNeeded(filename), self.GetUnsavedFilesVector(request_data), flags) self._diagnostic_store = DiagnosticsToDiagStructure(diagnostics) return [ ConvertToDiagnosticResponse(x) for x in diagnostics[:self._max_diagnostics_to_display] ]
def OnBufferUnload(self, request_data): self._completer.DeleteCachesForFile( ToUtf8IfNeeded(request_data['unloaded_buffer']))