예제 #1
0
 def run(self):
     log.warn('io thread starts')
     try:
         self._RunEventLoop()
     except:
         log.exception('fatal error, io thread')
     self.shutdown()
예제 #2
0
    def _DetectBinaryUrl(self):
        platform_system = platform.system()
        if platform_system == 'Linux':
            linux_dist = platform.dist()
            # dist turple is like this
            # Ubuntu, 16.04, Xenial
            # or Debian, 8.8, ''
            # fix for debian
            if linux_dist[0].lower() == 'debian':
                linux_dist[1] = str(int(linux_dist[1]))
            platform_version = float(linux_dist[1])
            platform_desc = '%s %s' % (linux_dist[0], platform_version)
        elif platform_system == 'Darwin':
            v, _, _ = platform.mac_ver()
            mac_ver = '.'.join(v.split('.')[:2])
            platform_version = float(mac_ver)
            platform_desc = 'Mac OS X %s' % mac_ver
        elif platform_system == 'Windows':
            win_ver, _, _, _ = platform.win32_ver()
            platform_version = float(win_ver)
        elif platform_system.startswith('MINGW64_NT'):
            # use msvc binary temporarily
            win_ver = float(platform_system.split('-')[1])
            platform_system = 'Windows'
            platform_version = float(win_ver)
        else:
            platform_system = 'Unknown System'
            platform_version = 0.0

        if not platform_desc:
            platform_desc = '%s %f' % (platform_system, platform_version)

        log.warn('detected %s' % platform_desc)

        download_infos = self._LoadDownloadInfo()
        # try to match from a set of download infos
        plats = []
        for plat in download_infos:
            # not trust url outside our mirror site
            if not plat['url'].startswith(DOWNLOAD_URL_PREFIX):
                continue
            if plat['system'] == platform_system:
                if platform_system == 'Linux':
                    if plat['dist'][0].lower() != linux_dist[0].lower():
                        continue
                    plat['version'] = float(plat['dist'][1])
                elif platform_system == 'Darwin':
                    plat['version'] = float(plat['mac_ver'])
                elif platform_system == 'Windows':
                    plat['version'] = float(plat['win_ver'])
                if platform_version < plat['version']:
                    continue
                plats.append(plat)
        if not plats:
            return platform_desc, None
        plats.sort(key=lambda x : x['version'], reverse=True)
        return platform_desc, plats[0]
예제 #3
0
 def StartServer(self):
     if self._loaded:
         return
     self._manager = ClangdManager()
     self._InitTimer()
     if self._timer:
         self._timer.start()
     try:
         self._manager.startServer(confirmed=True)
     except:
         log.exception('failed to start backend')
         return
     log.warn('vim-clangd backend fully loaded')
     self._loaded = True
예제 #4
0
    def StopServer(self):
        if self._timer:
            self._timer.stop()
            self._timer = None
        self._manager.in_shutdown = True
        try:
            # BufUnload won't be called at exit, you need to call it yourself
            self._manager.CloseAllFiles()
            log.warn('vim-clangd closed all files')
        except TimedOutError:
            # safe to ignore
            log.exception("close all files timeout")

        try:
            self._manager.stopServer(confirmed=True, in_shutdown=True)
        except OSError:
            log.exception("clangd refused to shutdown")
        log.warn('vim-clangd backend fully unloaded')
        self._loaded = False
        self._manager = None
예제 #5
0
    def CodeCompleteAtCurrent(self):
        if not self.isAlive():
            return -1
        if not self.OpenCurrentFile():
            return -1

        line, column = vimsupport.CurrentLineAndColumn()
        start_column, start_word = self._CalculateStartColumnAt(
            column, vimsupport.CurrentLine())

        trigger_word = None
        if start_column:
            trigger_word = vimsupport.CurrentLine()[start_column - 1]

        # skip from ';' and '}'
        if trigger_word == ';' or trigger_word == '}' or trigger_word == ']':
            return -1

        if not trigger_word in self._triggerCharacters:
            return -1

        if not self._last_completions_pos == (line - 1, start_column):
            timeout_ms = GetIntValue('g:clangd#codecomplete_timeout')
            try:
                self._last_completions_pos = (line - 1, start_column)
                uri = GetUriFromFilePath(vimsupport.CurrentBufferFileName())
                self._client.codeCompleteAt(
                    uri, line - 1, start_column, timeout_ms=timeout_ms)
            except TimedOutError:
                log.warn('perform clang codecomplete timed out at %d:%d' %
                         (line, column))

        # fetch cachable completions
        tries = self._last_completions

        flat_completions = []
        for kind, trie in tries.items():
            flat_completions.extend(trie.searchPrefix(start_word)[0:10])

        self._computed_completions_words = flat_completions
        return start_column + 1
예제 #6
0
    def downloadBinary(self, script_path):
        platform_desc, plat = self._DetectBinaryUrl()
        if not plat:
            EchoMessage('non supported platform %s' % platform_desc)
            return

        log.warn('downloading clangd binary from url %s' % plat['url'])

        tarball_file, _ = urlretrieve(plat['url'])

        if not plat['md5sum'] or not HashFile(tarball_file, 'md5') == plat['md5sum']:
            if not PresentYesOrNoDialog(
                    'failed to do checksum on %s, should we use this file?' %
                    tarball_file):
                return
        log.warn('downloaded clangd binary to %s' % tarball_file)

        for dir_name in ['bin', 'lib']:
            dir_path = os.path.join(script_path, dir_name)
            if os.path.exists(dir_path):
                rmtree(dir_path)
        tar = tarfile.open(name=tarball_file, mode='r:gz')
        tar.extractall(path=script_path)
        try:
            os.unlink(tarball_file)
            log.info('removed temporary file %s' % tarball_file)
        except OSError:
            log.warn('failed to remove temporary file %s' % tarball_file)
            pass
        EchoMessage('clangd installed')
예제 #7
0
def EchoMessage(text):
    log.warn(text)
    for line in str(text).split('\n'):
        vim.command('{0} \'{1}\''.format('echom', EscapeForVim(line)))
예제 #8
0
 def shutdown(self):
     log.warn('io thread shutdown')
     self._poller.shutdown()
예제 #9
0
 def onServerDown(self):
     if self._is_alive:
         log.warn('rpcclient is down with errors %d, timeouts %d' %
                  (self._client_errs, self._client_timeouts))
         self._is_alive = False
         self._manager.on_server_down()
예제 #10
0
 def on_bad_message_received(self, wc, message):
     log.warn('event: bad message')
예제 #11
0
 def restartServer(self):
     log.warn('restart backend')
     self.stopServer(confirmed=True)
     self.startServer(confirmed=True)