def __init__( self, user_options ): super( TypeScriptCompleter, self ).__init__( user_options ) # Used to prevent threads from concurrently reading and writing to # the tsserver process' stdout and stdin self._lock = Lock() binarypath = utils.PathToFirstExistingExecutable( [ 'tsserver' ] ) if not binarypath: _logger.error( BINARY_NOT_FOUND_MESSAGE ) raise RuntimeError( BINARY_NOT_FOUND_MESSAGE ) # Each request sent to tsserver must have a sequence id. # Responses contain the id sent in the corresponding request. self._sequenceid = 0 # TSServer ignores the fact that newlines are two characters on Windows # (\r\n) instead of one on other platforms (\n), so we use the # universal_newlines option to convert those newlines to \n. See the issue # https://github.com/Microsoft/TypeScript/issues/3403 # TODO: remove this option when the issue is fixed. # We also need to redirect the error stream to the output one on Windows. self._tsserver_handle = utils.SafePopen( binarypath, stdout = subprocess.PIPE, stdin = subprocess.PIPE, stderr = subprocess.STDOUT, universal_newlines = True ) _logger.info( 'Enabling typescript completion' )
def FindGoCodeBinary(user_options): ''' Find the path to the gocode binary. TODO(ekfriis): Test. If 'gocode_binary_path' in the options is blank, use the version installed with YCM, if it exists, then the one on the path, if not. If the 'gocode_binary_path' is specified, use it as an absolute path. If the resolved binary exists, return the path, otherwise return None. ''' if user_options.get('gocode_binary_path'): # The user has explicitly specified a path. if os.path.exists(user_options['gocode_binary_path']): return user_options['gocode_binary_path'] else: return None # Try to use the bundled binary or one on the path. if os.path.exists(PATH_TO_GOCODE_BINARY): return PATH_TO_GOCODE_BINARY return utils.PathToFirstExistingExecutable(['gocode'])
def FindRacerdBinary(user_options): """ Find path to racerd binary This function prefers the 'racerd_binary_path' value as provided in user_options if available. It then falls back to ycmd's racerd build. If that's not found, attempts to use racerd from current path. """ racerd_user_binary = user_options.get('racerd_binary_path') if racerd_user_binary: # The user has explicitly specified a path. if os.path.isfile(racerd_user_binary): return racerd_user_binary _logger.warning('User-provided racerd_binary_path does not exist.') if os.path.isfile(RACERD_BINARY_RELEASE): return RACERD_BINARY_RELEASE # We want to support using the debug binary for the sake of debugging; also, # building the release version on Travis takes too long. if os.path.isfile(RACERD_BINARY_DEBUG): _logger.warning('Using racerd DEBUG binary; performance will suffer!') return RACERD_BINARY_DEBUG return utils.PathToFirstExistingExecutable(['racerd'])
def PathToPythonInterpreter(): from ycmd import utils python_interpreter = vim.eval( 'g:ycm_path_to_python_interpreter' ) if python_interpreter: if IsPythonVersionCorrect( python_interpreter ): return python_interpreter raise RuntimeError( "Path in 'g:ycm_path_to_python_interpreter' option " "does not point to a valid Python 2.6 or 2.7." ) # On UNIX platforms, we use sys.executable as the Python interpreter path. # We cannot use sys.executable on Windows because for unknown reasons, it # returns the Vim executable. Instead, we use sys.exec_prefix to deduce the # interpreter path. python_interpreter = ( WIN_PYTHON_PATH if utils.OnWindows() else sys.executable ) if IsPythonVersionCorrect( python_interpreter ): return python_interpreter # As a last resort, we search python in the PATH. We check 'python2' before # 'python' because on some distributions (Arch Linux for example), python # refers to python3. python_interpreter = utils.PathToFirstExistingExecutable( [ 'python2', 'python' ] ) if IsPythonVersionCorrect( python_interpreter ): return python_interpreter raise RuntimeError( "Cannot find Python 2.6 or 2.7. You can set its path " "using the 'g:ycm_path_to_python_interpreter' " "option." )
def PathToPythonInterpreter(): # Not calling the Python interpreter to check its version as it significantly # impacts startup time. from ycmd import utils python_interpreter = vim.eval('g:ycm_server_python_interpreter') if python_interpreter: python_interpreter = utils.FindExecutable(python_interpreter) if python_interpreter: return python_interpreter raise RuntimeError("Path in 'g:ycm_server_python_interpreter' option " "does not point to a valid Python 3.5+.") python_interpreter = _PathToPythonUsedDuringBuild() if python_interpreter and utils.GetExecutable(python_interpreter): return python_interpreter # On UNIX platforms, we use sys.executable as the Python interpreter path. # We cannot use sys.executable on Windows because for unknown reasons, it # returns the Vim executable. Instead, we use sys.exec_prefix to deduce the # interpreter path. python_interpreter = (WIN_PYTHON_PATH if utils.OnWindows() else sys.executable) if _EndsWithPython(python_interpreter): return python_interpreter python_interpreter = utils.PathToFirstExistingExecutable( ['python3', 'python']) if python_interpreter: return python_interpreter raise RuntimeError("Cannot find Python 3.5+. " "Set the 'g:ycm_server_python_interpreter' option " "to a Python interpreter path.")
def FindBinary( self, binary, user_options ): """ Find the path to the gocode/godef binary. If 'gocode_binary_path' or 'godef_binary_path' in the options is blank, use the version installed with YCM, if it exists, then the one on the path, if not. If the 'gocode_binary_path' or 'godef_binary_path' is specified, use it as an absolute path. If the resolved binary exists, return the path, otherwise return None. """ if user_options.get( '%s_binary_path' % binary ): # The user has explicitly specified a path. if os.path.isfile( user_options[ '%s_binary_path' % binary] ): return user_options[ '%s_binary_path' % binary] else: return None # Try to use the bundled binary or one on the path. if binary == 'gocode': if os.path.isfile( PATH_TO_GOCODE_BINARY ): return PATH_TO_GOCODE_BINARY elif binary == 'godef': if os.path.isfile( PATH_TO_GODEF_BINARY ): return PATH_TO_GODEF_BINARY return utils.PathToFirstExistingExecutable( [ binary ] )
def __init__(self, user_options): super(TypeScriptCompleter, self).__init__(user_options) self._tsserver_handle = None # Used to prevent threads from concurrently writing to # the tsserver process' stdin self._write_lock = threading.Lock() # TODO: if we follow the path of tern_completer we can extract a # `ShouldEnableTypescriptCompleter` and use it in hook.py self._binary_path = utils.PathToFirstExistingExecutable(['tsserver']) if not self._binary_path: _logger.error(BINARY_NOT_FOUND_MESSAGE) raise RuntimeError(BINARY_NOT_FOUND_MESSAGE) _logger.info('Found TSServer at {0}'.format(self._binary_path)) self._logfile = _LogFileName() tsserver_log = '-file {path} -level {level}'.format(path=self._logfile, level=_LogLevel()) # TSServer get the configuration for the log file through the environment # variable 'TSS_LOG'. This seems to be undocumented but looking at the # source code it seems like this is the way: # https://github.com/Microsoft/TypeScript/blob/8a93b489454fdcbdf544edef05f73a913449be1d/src/server/server.ts#L136 self._environ = os.environ.copy() utils.SetEnviron(self._environ, 'TSS_LOG', tsserver_log) _logger.info('TSServer log file: {0}'.format(self._logfile)) # Each request sent to tsserver must have a sequence id. # Responses contain the id sent in the corresponding request. self._sequenceid = itertools.count() # Used to prevent threads from concurrently accessing the sequence counter self._sequenceid_lock = threading.Lock() self._server_lock = threading.RLock() # We first start the server and then the response-reading queue, so it will # certainly find a responding TSServer. self._StartServer() # Used to map sequence id's to their corresponding DeferredResponse # objects. The reader loop uses this to hand out responses. self._pending = {} # Used to prevent threads from concurrently reading and writing to # the pending response dictionary self._pending_lock = threading.Lock() # Start a thread to read response from TSServer. self._thread = threading.Thread(target=self._ReaderLoop, args=()) self._thread.daemon = True self._thread.start() _logger.info('Enabling typescript completion')
def __init__(self, user_options): super(TypeScriptCompleter, self).__init__(user_options) # Used to prevent threads from concurrently writing to # the tsserver process' stdin self._writelock = Lock() binarypath = utils.PathToFirstExistingExecutable(['tsserver']) if not binarypath: _logger.error(BINARY_NOT_FOUND_MESSAGE) raise RuntimeError(BINARY_NOT_FOUND_MESSAGE) self._logfile = _LogFileName() tsserver_log = '-file {path} -level {level}'.format(path=self._logfile, level=_LogLevel()) # TSServer get the configuration for the log file through the environment # variable 'TSS_LOG'. This seems to be undocumented but looking at the # source code it seems like this is the way: # https://github.com/Microsoft/TypeScript/blob/8a93b489454fdcbdf544edef05f73a913449be1d/src/server/server.ts#L136 self._environ = os.environ.copy() utils.SetEnviron(self._environ, 'TSS_LOG', tsserver_log) # Each request sent to tsserver must have a sequence id. # Responses contain the id sent in the corresponding request. self._sequenceid = itertools.count() # Used to prevent threads from concurrently accessing the sequence counter self._sequenceid_lock = Lock() # TSServer ignores the fact that newlines are two characters on Windows # (\r\n) instead of one on other platforms (\n), so we use the # universal_newlines option to convert those newlines to \n. See the issue # https://github.com/Microsoft/TypeScript/issues/3403 # TODO: remove this option when the issue is fixed. # We also need to redirect the error stream to the output one on Windows. self._tsserver_handle = utils.SafePopen(binarypath, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, env=self._environ, universal_newlines=True) # Used to map sequence id's to their corresponding DeferredResponse # objects. The reader loop uses this to hand out responses. self._pending = {} # Used to prevent threads from concurrently reading and writing to # the pending response dictionary self._pendinglock = Lock() # Start a thread to read response from TSServer. self._thread = Thread(target=self._ReaderLoop, args=()) self._thread.daemon = True self._thread.start() _logger.info('Enabling typescript completion')
def __init__(self, user_options): super(NimsuggestCompleter, self).__init__(user_options) self._popener = utils.SafePopen self._binary = utils.PathToFirstExistingExecutable(['nimsuggest']) self._dataqueue = Queue() if not self._binary: msg = "Couldn't find nimsuggest binary. Is it in the path?" error(msg) raise RuntimeError(msg) info('Nimsuggest completer loaded')
def FindRacerdBinary(user_options): """ Find path to racerd binary This function prefers the 'racerd_binary_path' value as provided in user_options if available. It then falls back to ycmd's racerd build. If that's not found, attempts to use racerd from current path. """ racerd_user_binary = user_options.get('racerd_binary_path') if racerd_user_binary: # The user has explicitly specified a path. if os.path.isfile(racerd_user_binary): return racerd_user_binary else: _logger.warn('user provided racerd_binary_path is not file') if os.path.isfile(RACERD_BINARY): return RACERD_BINARY return utils.PathToFirstExistingExecutable(['racerd'])
def PathToPythonInterpreter(): # Not calling the Python interpreter to check its version as it significantly # impacts startup time. from ycmd import utils python_interpreter = vim.eval( 'g:ycm_server_python_interpreter' ) if python_interpreter: python_interpreter = utils.FindExecutable( python_interpreter ) if python_interpreter: return python_interpreter raise RuntimeError( "Path in 'g:ycm_server_python_interpreter' option " "does not point to a valid Python 2.6+ or 3.3+." ) python_interpreter = _PathToPythonUsedDuringBuild() if python_interpreter and utils.GetExecutable( python_interpreter ): return python_interpreter # On UNIX platforms, we use sys.executable as the Python interpreter path. # We cannot use sys.executable on Windows because for unknown reasons, it # returns the Vim executable. Instead, we use sys.exec_prefix to deduce the # interpreter path. python_interpreter = ( WIN_PYTHON_PATH if utils.OnWindows() else sys.executable ) if _EndsWithPython( python_interpreter ): return python_interpreter # As a last resort, we search python in the PATH. We prefer Python 2 over 3 # for the sake of backwards compatibility with ycm_extra_conf.py files out # there; few people wrote theirs to work on py3. # So we check 'python2' before 'python' because on some distributions (Arch # Linux for example), python refers to python3. python_interpreter = utils.PathToFirstExistingExecutable( [ 'python2', 'python', 'python3' ] ) if python_interpreter: return python_interpreter raise RuntimeError( "Cannot find Python 2.6+ or 3.3+. " "Set the 'g:ycm_server_python_interpreter' option " "to a Python interpreter path." )
def PathToPythonInterpreter(): user_path_to_python = vim.eval('g:ycm_path_to_python_interpreter') if user_path_to_python: return user_path_to_python # We check for 'python2' before 'python' because some OS's (I'm looking at # you Arch Linux) have made the... interesting decision to point # /usr/bin/python to python3. python_names = ['python2', 'python'] path_to_python = utils.PathToFirstExistingExecutable(python_names) if path_to_python: return path_to_python # On Windows, Python may not be on the PATH at all, so we check some common # install locations. if utils.OnWindows(): if os.path.exists(WIN_PYTHON27_PATH): return WIN_PYTHON27_PATH elif os.path.exists(WIN_PYTHON26_PATH): return WIN_PYTHON26_PATH raise RuntimeError('Python 2.7/2.6 not installed!')
def PathToPythonInterpreter(): from ycmd import utils python_interpreter = vim.eval('g:ycm_path_to_python_interpreter') if python_interpreter: if IsPythonVersionCorrect(python_interpreter): return python_interpreter raise RuntimeError("Path in 'g:ycm_path_to_python_interpreter' option " "does not point to a valid Python 2.6+ or 3.3+.") # On UNIX platforms, we use sys.executable as the Python interpreter path. # We cannot use sys.executable on Windows because for unknown reasons, it # returns the Vim executable. Instead, we use sys.exec_prefix to deduce the # interpreter path. python_interpreter = (WIN_PYTHON_PATH if utils.OnWindows() else sys.executable) if IsPythonVersionCorrect(python_interpreter): return python_interpreter # As a last resort, we search python in the PATH. We prefer Python 2 over 3 # for the sake of backwards compatibility with ycm_extra_conf.py files out # there; few people wrote theirs to work on py3. # So we check 'python2' before 'python' because on some distributions (Arch # Linux for example), python refers to python3. python_interpreter = utils.PathToFirstExistingExecutable( ['python2', 'python', 'python3']) if IsPythonVersionCorrect(python_interpreter): return python_interpreter raise RuntimeError("Cannot find Python 2.6+ or 3.3+. You can set its path " "using the 'g:ycm_path_to_python_interpreter' " "option.")
def PathToFirstExistingExecutable_Failure_test(): ok_(not utils.PathToFirstExistingExecutable(['ycmd-foobar']))
def PathToFirstExistingExecutable_Basic_test(): if utils.OnWindows(): ok_(utils.PathToFirstExistingExecutable(['notepad.exe'])) else: ok_(utils.PathToFirstExistingExecutable(['cat']))
def test_PathToFirstExistingExecutable_Failure(self): assert_that(not utils.PathToFirstExistingExecutable(['ycmd-foobar']))
def test_PathToFirstExistingExecutable_Basic(self): if utils.OnWindows(): assert_that(utils.PathToFirstExistingExecutable(['notepad.exe'])) else: assert_that(utils.PathToFirstExistingExecutable(['cat']))
import shutil import tempfile import threading from ycmd import responses, utils from ycmd.completers.language_server import language_server_protocol as lsp from ycmd.completers.language_server import simple_language_server_completer from ycmd.utils import LOGGER NO_DOCUMENTATION_MESSAGE = 'No documentation available for current context' LANGUAGE_SERVER_HOME = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', '..', 'third_party', 'eclipse.jdt.ls', 'target', 'repository')) PATH_TO_JAVA = utils.PathToFirstExistingExecutable(['java']) PROJECT_FILE_TAILS = ['.project', 'pom.xml', 'build.gradle'] DEFAULT_WORKSPACE_ROOT_PATH = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', '..', 'third_party', 'eclipse.jdt.ls', 'workspace')) DEFAULT_EXTENSION_PATH = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', '..', 'third_party', 'eclipse.jdt.ls', 'extensions')) # The authors of jdt.ls say that we should re-use workspaces. They also say that # occasionally, the workspace becomes corrupt, and has to be deleted. This is # frustrating. #
import requests import threading from subprocess import PIPE from ycmd import utils, responses from ycmd.completers.completer import Completer from ycmd.completers.completer_utils import GetFileContents _logger = logging.getLogger(__name__) PATH_TO_TERN_BINARY = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..', '..', 'third_party', 'tern_runtime', 'node_modules', 'tern', 'bin', 'tern')) # On Debian-based distributions, node is by default installed as nodejs. PATH_TO_NODE = utils.PathToFirstExistingExecutable(['nodejs', 'node']) # host name/address on which the tern server should listen # note: we use 127.0.0.1 rather than localhost because on some platforms # localhost might not be correctly configured as an alias for the loopback # address. (ahem: Windows) SERVER_HOST = '127.0.0.1' LOGFILE_FORMAT = 'tern_{port}_{std}_' def ShouldEnableTernCompleter(): """Returns whether or not the tern completer is 'installed'. That is whether or not the tern submodule has a 'node_modules' directory. This is pretty much the only way we can know if the user added '--tern-completer' on install or manually ran 'npm install' in the tern submodule directory."""
import logging import os import shutil import tempfile import threading from subprocess import PIPE from ycmd import utils, responses from ycmd.completers.language_server import language_server_completer from ycmd.completers.language_server import language_server_protocol as lsp NO_DOCUMENTATION_MESSAGE = 'No documentation available for current context' _logger = logging.getLogger(__name__) PATH_TO_DART = utils.PathToFirstExistingExecutable(['dart_language_server']) PROJECT_FILE_TAILS = [ 'pubspec.yaml', ] def ShouldEnableDartCompleter(): if not PATH_TO_DART: _logger.warning("Not enabling dart completion: Couldn't find dart") return False return True def _MakeProjectFilesForPath(path): for tail in PROJECT_FILE_TAILS: