def GetClangdExecutableAndResourceDir(user_options): """Return the Clangd binary from the path specified in the 'clangd_binary_path' option. Let the binary find its resource directory in that case. If no binary is found or if it's out-of-date, return nothing. If 'clangd_binary_path' is empty, return the third-party Clangd and its resource directory if the user downloaded it and if it's up to date. Otherwise, return nothing.""" clangd = user_options['clangd_binary_path'] resource_dir = None if clangd: clangd = FindExecutable(ExpandVariablesInPath(clangd)) if not clangd: LOGGER.error('No Clangd executable found at %s', user_options['clangd_binary_path']) return None, None if not CheckClangdVersion(clangd): LOGGER.error('Clangd at %s is out-of-date', clangd) return None, None # Try looking for the pre-built binary. else: third_party_clangd = GetThirdPartyClangd() if not third_party_clangd: return None, None clangd = third_party_clangd resource_dir = CLANG_RESOURCE_DIR LOGGER.info('Using Clangd from %s', clangd) return clangd, resource_dir
def _GetRustSrcPath( self ): """ Attempt to read user option for rust_src_path. Fallback to environment variable if it's not provided. Finally try to be smart and figure out the path assuming the user set up rust by the means of rustup. """ rust_src_path = ( self.user_options[ 'rust_src_path' ] or os.environ.get( 'RUST_SRC_PATH' ) ) if rust_src_path: return ExpandVariablesInPath( rust_src_path ) # Try to figure out the src path using rustup rustc_executable = FindExecutable( 'rustc' ) if not rustc_executable: return None rust_sysroot = _GetRustSysroot( rustc_executable ) rust_src_path = p.join( rust_sysroot, 'lib', 'rustlib', 'src', 'rust', 'src' ) return rust_src_path if p.isdir( rust_src_path ) else None
def _MatchesGlobPattern(filename, glob): """Returns true if a filename matches a given pattern. Environment variables and a '~' in glob will be expanded and checking will be performed using absolute paths with symlinks resolved (except on Windows). See the documentation of fnmatch for the supported patterns.""" # NOTE: os.path.realpath does not resolve symlinks on Windows. # See https://bugs.python.org/issue9949 realpath = os.path.realpath(filename) return fnmatch(realpath, os.path.realpath(ExpandVariablesInPath(glob)))
def _EnvironmentForInterpreterPath( self, interpreter_path ): if interpreter_path: resolved_interpreter_path = FindExecutable( ExpandVariablesInPath( interpreter_path ) ) if not resolved_interpreter_path: raise RuntimeError( 'Cannot find Python interpreter path {}.'.format( interpreter_path ) ) interpreter_path = os.path.normpath( resolved_interpreter_path ) try: return self._environment_for_interpreter_path[ interpreter_path ] except KeyError: pass # Assume paths specified by the user are safe. environment = ( jedi.get_default_environment() if not interpreter_path else jedi.create_environment( interpreter_path, safe = False ) ) self._environment_for_interpreter_path[ interpreter_path ] = environment return environment
def ComputeCandidatesInner( self, request_data ): current_line = request_data[ 'line_value' ] start_codepoint = request_data[ 'start_codepoint' ] - 1 filepath = request_data[ 'filepath' ] line = current_line[ : start_codepoint ] path_match = self._path_regex.search( line ) path_dir = ExpandVariablesInPath( path_match.group() ) if path_match else '' # If the client supplied its working directory, use that instead of the # working directory of ycmd working_dir = request_data.get( 'working_dir' ) return GeneratePathCompletionData( _GetPathCompletionCandidates( path_dir, self.user_options[ 'filepath_completion_use_working_dir' ], filepath, working_dir ) )
def SearchPath(self, request_data): """Return the tuple (|path|, |start_column|) where |path| is a path that could be completed on the current line before the cursor and |start_column| is the column where the completion should start. (None, None) is returned if no suitable path is found.""" # Find all path separators on the current line before the cursor. Return # early if no separators are found. current_line = request_data['prefix'] matches = list(self._path_separators_regex.finditer(current_line)) if not matches: return None, None working_dir = self.GetWorkingDirectory(request_data) head_regex = self.GetCompiledHeadRegexForDirectory(working_dir) last_match = matches[-1] last_match_start = last_match.start(1) # Go through all path separators from left to right. for match in matches: # Check if ".", "..", "~", an environment variable, one of the current # directories, or a drive letter on Windows match just before the # separator. If so, extract the path from the start of the match to the # latest path separator. Expand "~" and the environment variables in the # path. If the path is relative, convert it to an absolute path relative # to the working directory. If the resulting path exists, return it and # the column just after the latest path separator as the starting column. head_match = head_regex.search(current_line[:match.start()]) if head_match: path = current_line[head_match.start(1):last_match_start] path = ExpandVariablesInPath(path + os.path.sep) if not os.path.isabs(path): path = os.path.join(working_dir, path) if os.path.exists(path): # +2 because last_match_start is the 0-indexed position just before # the latest path separator whose length is 1 on all platforms we # support. return path, last_match_start + 2 # Otherwise, the path may start with "/" (or "\" on Windows). Extract the # path from the current path separator to the latest one. If the path is # not empty and does not only consist of path separators, expand "~" and # the environment variables in the path. If the resulting path exists, # return it and the column just after the latest path separator as the # starting column. path = current_line[match.start():last_match_start] if path.strip(self._path_separators): path = ExpandVariablesInPath(path + os.path.sep) if os.path.exists(path): return path, last_match_start + 2 # No suitable paths have been found after going through all separators. The # path could be exactly "/" (or "\" on Windows). Only return the path if # there are no other path separators on the line. This prevents always # completing the root directory if nothing is matched. # TODO: completion on a single "/" or "\" is not really desirable in # languages where such characters are part of special constructs like # comments in C/C++ or closing tags in HTML. This behavior could be improved # by using rules that depend on the filetype. if len(matches) == 1: return os.path.sep, last_match_start + 2 return None, None
def _GlobalYcmExtraConfFileLocation(): return ExpandVariablesInPath( user_options_store.Value('global_ycm_extra_conf'))
def SearchPath( self, request_data ): """Return the tuple (|path|, |start_column|) where |path| is a path that could be completed on the current line before the cursor and |start_column| is the column where the completion should start. (None, None) is returned if no suitable path is found.""" # Find all path separators on the current line before the cursor. Return # early if no separators are found. current_line = request_data[ 'prefix' ] matches = list( self._path_separators_regex.finditer( current_line ) ) if not matches: return None, None working_dir = self.GetWorkingDirectory( request_data ) head_regex = self.GetCompiledHeadRegexForDirectory( working_dir ) last_match = matches[ -1 ] last_match_start = last_match.start( 1 ) # Go through all path separators from left to right. for match in matches: # Check if ".", "..", "~", an environment variable, one of the current # directories, or a drive letter on Windows match just before the # separator. If so, extract the path from the start of the match to the # latest path separator. Expand "~" and the environment variables in the # path. If the path is relative, convert it to an absolute path relative # to the working directory. If the resulting path exists, return it and # the column just after the latest path separator as the starting column. head_match = head_regex.search( current_line[ : match.start() ] ) if head_match: path = current_line[ head_match.start( 1 ) : last_match_start ] path = ExpandVariablesInPath( path + os.path.sep ) if not os.path.isabs( path ): path = os.path.join( working_dir, path ) if os.path.exists( path ): # +2 because last_match_start is the 0-indexed position just before # the latest path separator whose length is 1 on all platforms we # support. return path, last_match_start + 2 # Otherwise, the path may start with "/" (or "\" on Windows). Extract the # path from the current path separator to the latest one. If the path is # not empty and does not only consist of path separators, expand "~" and # the environment variables in the path. If the resulting path exists, # return it and the column just after the latest path separator as the # starting column. path = current_line[ match.start() : last_match_start ] if path.strip( self._path_separators ): path = ExpandVariablesInPath( path + os.path.sep ) if os.path.exists( path ): return path, last_match_start + 2 # No suitable paths have been found after going through all separators. The # path could be exactly "/" (or "\" on Windows). Only return the path if # there are no other path separators on the line. This prevents always # completing the root directory if nothing is matched. # TODO: completion on a single "/" or "\" is not really desirable in # languages where such characters are part of special constructs like # comments in C/C++ or closing tags in HTML. This behavior could be improved # by using rules that depend on the filetype. if len( matches ) == 1: return os.path.sep, last_match_start + 2 return None, None