def __init__( self, user_options ): super( FilenameCompleter, self ).__init__( user_options ) # On Windows, backslashes are also valid path separators. self._triggers = [ '/', '\\' ] if OnWindows() else [ '/' ] self._path_regex = re.compile( """ # Head part (?: # 'D:/'-like token [A-z]+:[%(sep)s]| # '/', './', '../', or '~' \.{0,2}[%(sep)s]|~| # '$var/' \$[A-Za-z0-9{}_]+[%(sep)s] )+ # Tail part (?: # any alphanumeric, symbol or space literal [ %(sep)sa-zA-Z0-9(){}$+_~.\x80-\xff-\[\]]| # skip any special symbols [^\x20-\x7E]| # backslash and 1 char after it \\. )*$ """ % { 'sep': '/\\\\' if OnWindows() else '/' }, re.X )
def __init__( self, user_options ): super( FilenameCompleter, self ).__init__( user_options ) # On Windows, backslashes are also valid path separators. self._triggers = [ '/', '\\' ] if OnWindows() else [ '/' ] self._path_regex = re.compile( """ # Head part (?: # 'D:/'-like token [A-z]+:[%(sep)s]| # '/', './', '../', or '~' \.{0,2}[%(sep)s]|~| # '$var/' \$[A-Za-z0-9{}_]+[%(sep)s] )+ # Tail part (?: # any alphanumeric, symbol or space literal [ %(sep)sa-zA-Z0-9(){}$+_~.\x80-\xff-\[\]]| # skip any special symbols [^\x20-\x7E]| # backslash and 1 char after it \\. )*$ """ % { 'sep': '/\\\\' if OnWindows() else '/' }, re.X )
def __init__( self, user_options ): super( FilenameCompleter, self ).__init__( user_options ) if OnWindows(): self._path_separators = r'/\\' self._head_path_pattern = HEAD_PATH_PATTERN_WINDOWS else: self._path_separators = '/' self._head_path_pattern = HEAD_PATH_PATTERN_UNIX self._path_separators_regex = re.compile( PATH_SEPARATORS_PATTERN.format( seps = self._path_separators ) ) self._head_path_for_directory = {} self._candidates_for_directory = {}
def __init__(self, user_options): super(FilenameCompleter, self).__init__(user_options) if OnWindows(): self._path_separators = r'/\\' self._head_path_pattern = HEAD_PATH_PATTERN_WINDOWS else: self._path_separators = '/' self._head_path_pattern = HEAD_PATH_PATTERN_UNIX self._path_separators_regex = re.compile( PATH_SEPARATORS_PATTERN.format(seps=self._path_separators)) self._head_path_for_directory = {} self._candidates_for_directory = {}
def GetCompiledHeadRegexForDirectory(self, directory): mtime = GetModificationTime(directory) try: head_regex = self._head_path_for_directory[directory] if mtime and mtime <= head_regex['mtime']: return head_regex['regex'] except KeyError: pass current_paths = ListDirectory(directory) current_paths_pattern = '|'.join( [re.escape(path) for path in current_paths]) head_pattern = ('(' + self._head_path_pattern + '|' + current_paths_pattern + ')$') head_regex = re.compile(head_pattern, re.VERBOSE) if mtime: self._head_path_for_directory[directory] = { 'regex': head_regex, 'mtime': mtime } return head_regex
def GetCompiledHeadRegexForDirectory( self, directory ): mtime = GetModificationTime( directory ) try: head_regex = self._head_path_for_directory[ directory ] if mtime and mtime <= head_regex[ 'mtime' ]: return head_regex[ 'regex' ] except KeyError: pass current_paths = ListDirectory( directory ) current_paths_pattern = '|'.join( [ re.escape( path ) for path in current_paths ] ) head_pattern = ( '(' + self._head_path_pattern + '|' + current_paths_pattern + ')$' ) head_regex = re.compile( head_pattern, re.VERBOSE ) if mtime: self._head_path_for_directory[ directory ] = { 'regex': head_regex, 'mtime': mtime } return head_regex
import logging import os from subprocess import PIPE from ycmd import responses, utils from ycmd.completers.language_server import language_server_completer from ycmd.utils import LOGGER, re LOGFILE_FORMAT = 'ra_' RUST_ROOT = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', '..', 'third_party', 'rust-analyzer')) RA_BIN_DIR = os.path.join(RUST_ROOT, 'bin') RUSTC_EXECUTABLE = utils.FindExecutable(os.path.join(RA_BIN_DIR, 'rustc')) RA_EXECUTABLE = utils.FindExecutable(os.path.join(RA_BIN_DIR, 'rust-analyzer')) RA_VERSION_REGEX = re.compile(r'^rust-analyzer (?P<version>.*)$') def _GetCommandOutput(command): return utils.ToUnicode( utils.SafePopen(command, stdin_windows=PIPE, stdout=PIPE, stderr=PIPE).communicate()[0].rstrip()) def _GetRAVersion(ra_path): ra_version = _GetCommandOutput([ra_path, '--version']) match = RA_VERSION_REGEX.match(ra_version) if not match: LOGGER.error('Cannot parse Rust Language Server version: %s', ra_version) return None
# 3. the escaped double quote inside the string DOUBLE_QUOTE_STRING = r'(?<!\\)"(?:\\\\|\\"|.)*?"' # Anything inside back quotes, `...`, but mind: # 1. that the starting back quote is not escaped # 2. the escaped slash (\\) # 3. the escaped back quote inside the string BACK_QUOTE_STRING = r'(?<!\\)`(?:\\\\|\\`|.)*?`' # Python-style multiline single-quote string MULTILINE_SINGLE_QUOTE_STRING = "'''(?:\n|.)*?'''" # Python-style multiline double-quote string MULTILINE_DOUBLE_QUOTE_STRING = '"""(?:\n|.)*?"""' DEFAULT_COMMENT_AND_STRING_REGEX = re.compile( "|".join( [ C_STYLE_COMMENT, CPP_STYLE_COMMENT, PYTHON_STYLE_COMMENT, MULTILINE_SINGLE_QUOTE_STRING, MULTILINE_DOUBLE_QUOTE_STRING, SINGLE_QUOTE_STRING, DOUBLE_QUOTE_STRING ] ), re.MULTILINE ) FILETYPE_TO_COMMENT_AND_STRING_REGEX = { # Spec: # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf 'cpp': re.compile( "|".join( [ C_STYLE_COMMENT, CPP_STYLE_COMMENT, SINGLE_QUOTE_STRING, DOUBLE_QUOTE_STRING ] ), re.MULTILINE ), # Spec: # https://golang.org/ref/spec#Comments # https://golang.org/ref/spec#String_literals
from ycmd.completers.completer import Completer from ycmd.completers.cpp.flags import ( Flags, PrepareFlagsForClang, UserIncludePaths ) from ycmd.completers.cpp.ephemeral_values_set import EphemeralValuesSet from ycmd.completers.cpp.include_cache import IncludeCache, IncludeList from ycmd.responses import NoExtraConfDetected, UnknownExtraConf CLANG_FILETYPES = { 'c', 'cpp', 'cuda', 'objc', 'objcpp' } PARSING_FILE_MESSAGE = 'Still parsing file.' NO_COMPILE_FLAGS_MESSAGE = 'Still no compile flags.' NO_COMPLETIONS_MESSAGE = 'No completions found; errors in the file?' NO_DIAGNOSTIC_MESSAGE = 'No diagnostic for current line!' PRAGMA_DIAG_TEXT_TO_IGNORE = '#pragma once in main file' TOO_MANY_ERRORS_DIAG_TEXT_TO_IGNORE = 'too many errors emitted, stopping now' NO_DOCUMENTATION_MESSAGE = 'No documentation available for current context' INCLUDE_REGEX = re.compile( '(\\s*#\\s*(?:include|import)\\s*)(?:"[^"]*|<[^>]*)' ) class ClangCompleter( Completer ): def __init__( self, user_options ): super( ClangCompleter, self ).__init__( user_options ) self._completer = ycm_core.ClangCompleter() self._flags = Flags() self._include_cache = IncludeCache() self._diagnostic_store = None self._files_being_compiled = EphemeralValuesSet() def SupportedFiletypes( self ): return CLANG_FILETYPES
STATE_FLAGS_TO_SKIP_WIN_STYLE = { '/c' } # The -M* flags spec: # https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Preprocessor-Options.html FILE_FLAGS_TO_SKIP = { '-MF', '-MT', '-MQ', '-o', '--serialize-diagnostics' } # Use a regex to correctly detect c++/c language for both versioned and # non-versioned compiler executable names suffixes # (e.g., c++, g++, clang++, g++-4.9, clang++-3.7, c++-10.2 etc). # See Valloric/ycmd#266 CPP_COMPILER_REGEX = re.compile( r'\+\+(-\d+(\.\d+){0,2})?$' ) # Use a regex to match all the possible forms of clang-cl or cl compiler CL_COMPILER_REGEX = re.compile( r'(?:cl|clang-cl)(.exe)?$', re.IGNORECASE ) # List of file extensions to be considered "header" files and thus not present # in the compilation database. The logic will try and find an associated # "source" file (see SOURCE_EXTENSIONS below) and use the flags for that. HEADER_EXTENSIONS = [ '.h', '.hxx', '.hpp', '.hh', '.cuh' ] # List of file extensions which are considered "source" files for the purposes # of heuristically locating the flags for a header file. SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.cu', '.m', '.mm' ] EMPTY_FLAGS = { 'flags': [],
from ycmd.completers.completer import Completer from ycmd.completers.cpp.flags import (Flags, PrepareFlagsForClang, UserIncludePaths) from ycmd.completers.cpp.ephemeral_values_set import EphemeralValuesSet from ycmd.completers.cpp.include_cache import IncludeCache, IncludeList from ycmd.responses import NoExtraConfDetected, UnknownExtraConf CLANG_FILETYPES = {'c', 'cpp', 'cuda', 'objc', 'objcpp'} PARSING_FILE_MESSAGE = 'Still parsing file.' NO_COMPILE_FLAGS_MESSAGE = 'Still no compile flags.' NO_COMPLETIONS_MESSAGE = 'No completions found; errors in the file?' NO_DIAGNOSTIC_MESSAGE = 'No diagnostic for current line!' PRAGMA_DIAG_TEXT_TO_IGNORE = '#pragma once in main file' TOO_MANY_ERRORS_DIAG_TEXT_TO_IGNORE = 'too many errors emitted, stopping now' NO_DOCUMENTATION_MESSAGE = 'No documentation available for current context' INCLUDE_REGEX = re.compile( '(\\s*#\\s*(?:include|import)\\s*)(?:"[^"]*|<[^>]*)') class ClangCompleter(Completer): def __init__(self, user_options): super(ClangCompleter, self).__init__(user_options) self._completer = ycm_core.ClangCompleter() self._flags = Flags() self._include_cache = IncludeCache() self._diagnostic_store = None self._files_being_compiled = EphemeralValuesSet() def SupportedFiletypes(self): return CLANG_FILETYPES def GetUnsavedFilesVector(self, request_data):
STATE_FLAGS_TO_SKIP_WIN_STYLE = { '/c' } # The -M* flags spec: # https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Preprocessor-Options.html FILE_FLAGS_TO_SKIP = { '-MF', '-MT', '-MQ', '-o', '--serialize-diagnostics' } # Use a regex to correctly detect c++/c language for both versioned and # non-versioned compiler executable names suffixes # (e.g., c++, g++, clang++, g++-4.9, clang++-3.7, c++-10.2 etc). # See Valloric/ycmd#266 CPP_COMPILER_REGEX = re.compile( r'\+\+(-\d+(\.\d+){0,2})?$' ) # Use a regex to match all the possible forms of clang-cl or cl compiler CL_COMPILER_REGEX = re.compile( r'(?:cl|clang-cl)(.exe)?$', re.IGNORECASE ) # List of file extensions to be considered "header" files and thus not present # in the compilation database. The logic will try and find an associated # "source" file (see SOURCE_EXTENSIONS below) and use the flags for that. HEADER_EXTENSIONS = [ '.h', '.hxx', '.hpp', '.hh', '.cuh' ] # List of file extensions which are considered "source" files for the purposes # of heuristically locating the flags for a header file. SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.cu', '.m', '.mm' ] EMPTY_FLAGS = { 'flags': [],
import logging import os import subprocess from ycmd import extra_conf_store, responses from ycmd.completers.cpp.flags import (AddMacIncludePaths, RemoveUnusedFlags, ShouldAllowWinStyleFlags) from ycmd.completers.language_server import language_server_completer from ycmd.completers.language_server import language_server_protocol as lsp from ycmd.utils import (CLANG_RESOURCE_DIR, GetExecutable, ExpandVariablesInPath, FindExecutable, LOGGER, OnMac, PathsToAllParentFolders, re) MIN_SUPPORTED_VERSION = (10, 0, 0) INCLUDE_REGEX = re.compile( '(\\s*#\\s*(?:include|import)\\s*)(?:"[^"]*|<[^>]*)') NOT_CACHED = 'NOT_CACHED' CLANGD_COMMAND = NOT_CACHED PRE_BUILT_CLANGD_DIR = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', '..', 'third_party', 'clangd', 'output', 'bin')) PRE_BUILT_CLANDG_PATH = os.path.join(PRE_BUILT_CLANGD_DIR, 'clangd') def ParseClangdVersion(version_str): version_regexp = r'(\d+)\.(\d+)\.(\d+)' m = re.search(version_regexp, version_str) try: version = tuple(int(x) for x in m.groups()) except AttributeError: # Custom builds might have different versioning info.
# 3. the escaped double quote inside the string DOUBLE_QUOTE_STRING = r'(?<!\\)"(?:\\\\|\\"|.)*?"' # Anything inside back quotes, `...`, but mind: # 1. that the starting back quote is not escaped # 2. the escaped slash (\\) # 3. the escaped back quote inside the string BACK_QUOTE_STRING = r'(?<!\\)`(?:\\\\|\\`|.)*?`' # Python-style multiline single-quote string MULTILINE_SINGLE_QUOTE_STRING = "'''(?:\n|.)*?'''" # Python-style multiline double-quote string MULTILINE_DOUBLE_QUOTE_STRING = '"""(?:\n|.)*?"""' DEFAULT_COMMENT_AND_STRING_REGEX = re.compile( "|".join( [ C_STYLE_COMMENT, CPP_STYLE_COMMENT, PYTHON_STYLE_COMMENT, MULTILINE_SINGLE_QUOTE_STRING, MULTILINE_DOUBLE_QUOTE_STRING, SINGLE_QUOTE_STRING, DOUBLE_QUOTE_STRING ] ), re.MULTILINE ) FILETYPE_TO_COMMENT_AND_STRING_REGEX = { # Spec: # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf 'cpp': re.compile( "|".join( [ C_STYLE_COMMENT, CPP_STYLE_COMMENT, SINGLE_QUOTE_STRING, DOUBLE_QUOTE_STRING ] ), re.MULTILINE ), # Spec: # https://golang.org/ref/spec#Comments # https://golang.org/ref/spec#String_literals
# 2. the escaped slash (\\) # 3. the escaped double quote inside the string DOUBLE_QUOTE_STRING = r'(?<!\\)"(?:\\\\|\\"|.)*?"' # Anything inside back quotes, `...`, but mind: # 1. that the starting back quote is not escaped # 2. the escaped slash (\\) # 3. the escaped back quote inside the string BACK_QUOTE_STRING = r'(?<!\\)`(?:\\\\|\\`|.)*?`' # Python-style multiline single-quote string MULTILINE_SINGLE_QUOTE_STRING = "'''(?:\n|.)*?'''" # Python-style multiline double-quote string MULTILINE_DOUBLE_QUOTE_STRING = '"""(?:\n|.)*?"""' DEFAULT_COMMENT_AND_STRING_REGEX = re.compile( "|".join([ C_STYLE_COMMENT, CPP_STYLE_COMMENT, PYTHON_STYLE_COMMENT, MULTILINE_SINGLE_QUOTE_STRING, MULTILINE_DOUBLE_QUOTE_STRING, SINGLE_QUOTE_STRING, DOUBLE_QUOTE_STRING ]), re.MULTILINE) FILETYPE_TO_COMMENT_AND_STRING_REGEX = { # Spec: # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf 'cpp': re.compile( "|".join([ C_STYLE_COMMENT, CPP_STYLE_COMMENT, SINGLE_QUOTE_STRING, DOUBLE_QUOTE_STRING ]), re.MULTILINE), # Spec: # https://golang.org/ref/spec#Comments
import subprocess from ycmd import responses from ycmd.completers.completer_utils import GetFileLines from ycmd.completers.language_server import simple_language_server_completer from ycmd.completers.language_server import language_server_completer from ycmd.completers.language_server import language_server_protocol as lsp from ycmd.utils import ( CLANG_RESOURCE_DIR, GetExecutable, ExpandVariablesInPath, FindExecutable, LOGGER, re ) MIN_SUPPORTED_VERSION = '7.0.0' INCLUDE_REGEX = re.compile( '(\\s*#\\s*(?:include|import)\\s*)(?:"[^"]*|<[^>]*)' ) NOT_CACHED = 'NOT_CACHED' CLANGD_COMMAND = NOT_CACHED PRE_BUILT_CLANGD_DIR = os.path.abspath( os.path.join( os.path.dirname( __file__ ), '..', '..', '..', 'third_party', 'clangd', 'output', 'bin' ) ) PRE_BUILT_CLANDG_PATH = os.path.join( PRE_BUILT_CLANGD_DIR, 'clangd' ) def DistanceOfPointToRange( point, range ):
def _PrepareTrigger( trigger ): trigger = ToUnicode( trigger ) if trigger.startswith( TRIGGER_REGEX_PREFIX ): return re.compile( trigger[ len( TRIGGER_REGEX_PREFIX ) : ], re.UNICODE ) return re.compile( re.escape( trigger ), re.UNICODE )
def _PrepareTrigger( trigger ): trigger = ToUnicode( trigger ) if trigger.startswith( TRIGGER_REGEX_PREFIX ): return re.compile( trigger[ len( TRIGGER_REGEX_PREFIX ) : ], re.UNICODE ) return re.compile( re.escape( trigger ), re.UNICODE )
import os from future.utils import itervalues from subprocess import PIPE from ycmd import responses, utils from ycmd.completers.language_server import (simple_language_server_completer, language_server_completer) from ycmd.utils import LOGGER, re LOGFILE_FORMAT = 'rls_' RLS_BIN_DIR = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', '..', 'third_party', 'rls', 'bin')) RUSTC_EXECUTABLE = utils.FindExecutable(os.path.join(RLS_BIN_DIR, 'rustc')) RLS_EXECUTABLE = utils.FindExecutable(os.path.join(RLS_BIN_DIR, 'rls')) RLS_VERSION_REGEX = re.compile(r'^rls (?P<version>.*)$') def _GetCommandOutput(command): return utils.ToUnicode( utils.SafePopen(command, stdin_windows=PIPE, stdout=PIPE, stderr=PIPE).communicate()[0].rstrip()) def _GetRlsVersion(): rls_version = _GetCommandOutput([RLS_EXECUTABLE, '--version']) match = RLS_VERSION_REGEX.match(rls_version) if not match: LOGGER.error('Cannot parse Rust Language Server version: %s', rls_version) return None