Exemplo n.º 1
0
  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' )
Exemplo n.º 2
0
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'])
Exemplo n.º 3
0
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'])
Exemplo n.º 4
0
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." )
Exemplo n.º 5
0
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.")
Exemplo n.º 6
0
  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')
Exemplo n.º 8
0
    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')
Exemplo n.º 10
0
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'])
Exemplo n.º 11
0
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." )
Exemplo n.º 12
0
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!')
Exemplo n.º 13
0
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.")
Exemplo n.º 14
0
def PathToFirstExistingExecutable_Failure_test():
    ok_(not utils.PathToFirstExistingExecutable(['ycmd-foobar']))
Exemplo n.º 15
0
def PathToFirstExistingExecutable_Basic_test():
    if utils.OnWindows():
        ok_(utils.PathToFirstExistingExecutable(['notepad.exe']))
    else:
        ok_(utils.PathToFirstExistingExecutable(['cat']))
Exemplo n.º 16
0
 def test_PathToFirstExistingExecutable_Failure(self):
     assert_that(not utils.PathToFirstExistingExecutable(['ycmd-foobar']))
Exemplo n.º 17
0
 def test_PathToFirstExistingExecutable_Basic(self):
     if utils.OnWindows():
         assert_that(utils.PathToFirstExistingExecutable(['notepad.exe']))
     else:
         assert_that(utils.PathToFirstExistingExecutable(['cat']))
Exemplo n.º 18
0
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.
#
Exemplo n.º 19
0
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."""
Exemplo n.º 20
0
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: