def _InitTimer(self): native_timer = GetBoolValue('has("s:timer")') if native_timer: log.debug('vim native timer support found and used') # FIXME use abstract timer else: self._timer = EmulateTimer(self)
def OnTimerCallback(self): log.debug('OnTimer') self._manager.HandleClientRequests() if FilterCurrentFile(): return self._manager.GetDiagnosticsForCurrentFile() self._manager.EchoErrorMessageForCurrentLine()
def sendRequest(self, method, params, nullResponse, timeout_ms): Id = self._no self._no = self._no + 1 r = self.SendMsg(method, params, Id=Id) if nullResponse: return None log.debug('send request: %s' % r) if timeout_ms is None: timeout_ms = DEFAULT_TIMEOUT_MS while timeout_ms >= IDLE_INTERVAL_MS: if self._is_stop: self._observer.onServerDown() raise OSError('client is down') try: rr = self._read_queue.get_nowait() except queue.Empty: sleep(IDLE_INTERVAL_MS * 0.001) timeout_ms -= IDLE_INTERVAL_MS continue if rr == None: self._observer.onServerDown() raise OSError('io thread stopped') rr = self.RecvMsg(rr) if 'id' in rr and rr['id'] == Id: if 'error' in rr: raise OSError('bad error_code %d' % rr['error']) return rr['result'] raise TimedOutError('msg timeout') return None
def _FlushSendBuffer(self): while self._writebuf: written = WriteUtf8(self._input_fd, self._writebuf) if not written: break self._writebuf = self._writebuf[written:] log.debug('written %d bytes remains %d bytes' % (written, len(self._writebuf)))
def _FetchRecvBuffer(self, buffer_len=256): while buffer_len: chunk = ReadUtf8(self._output_fd, buffer_len) if not chunk: break log.debug('read %d bytes with buffer %d bytes' % (len(chunk), buffer_len)) buffer_len -= len(chunk) self._readbuf += chunk
def on_server_down(self): log.debug('event: backend is down unexceptedly') self.lined_diagnostics = {} vimsupport.ClearClangdSyntaxMatches() vimsupport.UnplaceAllSigns() if not self._in_shutdown: self.stopServer(confirmed=True) if GetBoolValue('g:clangd#restart_after_crash'): self.startServer(confirmed=True)
def didOpenFile(self, buf): file_name = buf.name uri = GetUriFromFilePath(buf.name) if uri in self._documents: return file_type = buf.options['filetype'].decode('utf-8') text = vimsupport.ExtractUTF8Text(buf) self._documents[uri] = {} self._documents[uri]['version'] = 1 self._client.didOpenTestDocument(uri, text, file_type) log.debug('file %s opened' % file_name)
def SaveFile(self, file_name): if not self.isAlive(): return True uri = GetUriFromFilePath(file_name) try: self._client.didSaveTestDocument(uri) except TimedOutError: log.exception('unable to save %s' % file_name) return False log.debug('file %s saved' % file_name) return True
def CloseFile(self, file_name): if not self.isAlive(): return True uri = GetUriFromFilePath(file_name) if not uri in self._documents: return version = self._documents.pop(uri)['version'] try: self._client.didCloseTestDocument(uri) except TimedOutError: log.exception('failed to close file %s' % file_name) return False log.debug('file %s closed' % file_name) return True
def initialize(self): try: rr = self._SendRequest(Initialize_REQUEST, { 'processId': os.getpid(), 'rootUri': 'file://' + os.getcwd(), 'capabilities': {}, 'trace': 'off' }, timeout_ms=5000) except TimedOutError as e: log.exception('initialize timedout') # ignore timedout rr = {} pass if not 'capabilities' in rr: rr['capabilities'] = {} log.debug('clangd connected with backend server') for k in rr['capabilities']: v = rr['capabilities'][k] if v: log.info('clangd server capability: %s' % k) self._manager.on_server_connected() return rr
def onCodeCompletions(self, uri, line, column, completions): if uri not in self._documents: return if uri != GetUriFromFilePath(vimsupport.CurrentBufferFileName()): return if not self._last_completions_pos == (line, column): return tries = self._GetEmptyCompletions() log.debug('performed clang codecomplete at %d:%d, result %d items' % (line, column, len(completions))) for completion in completions: if not 'kind' in completion: continue kind = CompletionItemKind(completion['kind']) # insertText is missing from old clangd, we try to keep compatibility here word = completion[ 'insertText'] if 'insertText' in completion else completion[ 'label'] # description info = completion[ 'detail'] if 'detail' in completion else completion['label'] # actual results to feed vim tries[kind].insert( word, { 'word': # The actual completion word, 'kind': # The type of completion, one character kind, 'info': info, # description 'icase': 1, # ignore case 'dup': 1 # allow duplicates }) # update cache self._last_completions = tries
def OnBufferReadPost(self, file_name): log.debug('BufferReadPost %s' % file_name)
def onDiagnostics(self, uri, diagnostics): if uri not in self._documents: return log.debug('diagnostics for %s is updated' % uri) self._documents[uri]['diagnostics'] = diagnostics
def OnInsertEnter(self): log.debug('InsertEnter')
def OnTextChanged(self): # After a change was made to the text in the current buffer in Normal mode. log.debug('TextChanged') self._manager.UpdateCurrentBuffer()
def OnInsertLeave(self): log.debug('InsertLeave')
def __init__(self): log.debug('using python %d' % PY_VERSION) self._timer = None self._loaded = False
def on_server_connected(self): log.debug('event: backend is up') self._client.onInitialized() # wipe all exist documents self._documents = {}
def OnBufferDelete(self, file_name): log.debug('BufferDelete %s' % file_name) self._manager.CloseFile(file_name)
def OnVimEnter(self): log.debug('VimEnter') autostart = GetBoolValue('g:clangd#autostart') if autostart: self.StartServer() return
def OnVimLeave(self): log.debug('VimLeave') self.StopServer()
def OnResponse(self, request, response): log.debug('recv response from: %s' % request['method']) self._observer.onResponse(request, response['result'])
def OnFileType(self): log.debug('Current FileType Changed To %s' % CurrentFileTypes()[0]) self._manager.CloseCurrentFile() self._manager.OpenCurrentFile() self._manager.GetDiagnosticsForCurrentFile()
def OnBufferWritePost(self, file_name): # FIXME should we use buffer_number? self._manager.SaveFile(file_name) log.debug('BufferWritePost %s' % file_name)
def OnBufferUnload(self, file_name): log.debug('BufferUnload %s' % file_name) self._manager.CloseFile(file_name)