From 3e2ca55604070bf13ddebb9dbaa2935b6cbe86d2 Mon Sep 17 00:00:00 2001 From: Yegappan Lakshmanan Date: Mon, 17 Jul 2023 22:11:34 -0700 Subject: [PATCH] Update the client capabilities. Pass buffer number to autocmd handler functions. Send pending file changes to the language server before updating inlay hints and highlights --- autoload/lsp/capabilities.vim | 106 +++++++++++++++++++++++++++------- autoload/lsp/inlayhints.vim | 6 +- autoload/lsp/lsp.vim | 24 ++++---- autoload/lsp/lspserver.vim | 8 ++- autoload/lsp/options.vim | 14 +++-- autoload/lsp/signature.vim | 3 +- doc/lsp.txt | 7 ++- plugin/lsp.vim | 2 +- 8 files changed, 123 insertions(+), 47 deletions(-) diff --git a/autoload/lsp/capabilities.vim b/autoload/lsp/capabilities.vim index f29f250..9186a9b 100644 --- a/autoload/lsp/capabilities.vim +++ b/autoload/lsp/capabilities.vim @@ -294,10 +294,12 @@ enddef export def GetClientCaps(): dict # client capabilities (ClientCapabilities) var clientCaps: dict = { - workspace: { - workspaceFolders: true, - applyEdit: true, - configuration: true + general: { + # Currently we always send character count as position offset, + # which meanas only utf-32 is supported. + # Adding utf-16 simply for good mesure, as I'm scared some servers will + # give up if they don't support utf-32 only. + positionEncodings: ['utf-32', 'utf-16'] }, textDocument: { callHierarchy: { @@ -322,43 +324,105 @@ export def GetClientCaps(): dict dynamicRegistration: false, completionItem: { documentationFormat: ['markdown', 'plaintext'], - resolveSupport: {properties: ['detail', 'documentation']}, + resolveSupport: { + properties: ['detail', 'documentation'] + }, snippetSupport: opt.lspOptions.snippetSupport, insertReplaceSupport: false }, - completionItemKind: {valueSet: range(1, 25)} + completionItemKind: { + valueSet: range(1, 25) + } + }, + declaration: { + dynamicRegistration: false, + linkSupport: true + }, + definition: { + dynamicRegistration: false, + linkSupport: true + }, + documentHighlight: { + dynamicRegistration: false }, documentSymbol: { dynamicRegistration: false, + symbolKind: { + valueSet: range(1, 25) + }, hierarchicalDocumentSymbolSupport: true, - symbolKind: {valueSet: range(1, 25)} + labelSupport: false + }, + foldingRange: { + dynamicRegistration: false, + rangeLimit: 5000, + lineFoldingOnly: true, + foldingRangeKind: { + valueSet: ['comment', 'imports', 'region'] + }, + foldingRange: { + collapsedText: true + } + }, + formatting: { + dynamicRegistration: false }, hover: { + dynamicRegistration: false, contentFormat: ['markdown', 'plaintext'] }, - foldingRange: {lineFoldingOnly: true}, - inlayHint: {dynamicRegistration: false}, - synchronization: { - didSave: true + implementation: { + dynamicRegistration: false, + linkSupport: true + }, + inlayHint: { + dynamicRegistration: false + }, + publishDiagnostics: { + relatedInformation: false, + versionSupport: true, + codeDescriptionSupport: true, + dataSupport: true + }, + rangeFormatting: { + dynamicRegistration: false + }, + references: { + dynamicRegistration: false + }, + rename: { + dynamicRegistration: false, + prepareSupport: false, }, - declaration: {linkSupport: true}, - definition: {linkSupport: true}, - typeDefinition: {linkSupport: true}, - implementation: {linkSupport: true}, signatureHelp: { + dynamicRegistration: false, signatureInformation: { documentationFormat: ['markdown', 'plaintext'], activeParameterSupport: true } + }, + synchronization: { + dynamicRegistration: false, + didSave: true, + willSave: false, + WillSaveWaitUntil: false + }, + typeDefinition: { + dynamicRegistration: false, + linkSupport: true + }, + typeHierarchy: { + dynamicRegistration: false, } }, window: {}, - general: { - # Currently we always send character count as position offset, - # which meanas only utf-32 is supported. - # Adding utf-16 simply for good mesure, as I'm scared some servers will - # give up if they don't support utf-32 only. - positionEncodings: ['utf-32', 'utf-16'] + workspace: { + workspaceFolders: true, + applyEdit: true, + configuration: true, + symbol: { + dynamicRegistration: false + } }, # This is the way clangd expects to be informated about supported encodings: # https://clangd.llvm.org/extensions#utf-8-offsets diff --git a/autoload/lsp/inlayhints.vim b/autoload/lsp/inlayhints.vim index 1bbd331..34daee8 100644 --- a/autoload/lsp/inlayhints.vim +++ b/autoload/lsp/inlayhints.vim @@ -76,11 +76,11 @@ enddef # Update all the inlay hints. A timer is used to throttle the updates. def LspInlayHintsUpdate(bnr: number) - if !getbufvar(bnr, 'LspInlayHintsNeedsUpdate', true) + if !bnr->getbufvar('LspInlayHintsNeedsUpdate', true) return endif - var timerid = getbufvar(bnr, 'LspInlayHintsTimer', -1) + var timerid = bnr->getbufvar('LspInlayHintsTimer', -1) if timerid != -1 timerid->timer_stop() setbufvar(bnr, 'LspInlayHintsTimer', -1) @@ -113,7 +113,7 @@ enddef # Stop updating the inlay hints. def LspInlayHintsUpdateStop(bnr: number) - var timerid = getbufvar(bnr, 'LspInlayHintsTimer', -1) + var timerid = bnr->getbufvar('LspInlayHintsTimer', -1) if timerid != -1 timerid->timer_stop() setbufvar(bnr, 'LspInlayHintsTimer', -1) diff --git a/autoload/lsp/lsp.vim b/autoload/lsp/lsp.vim index b2e6baf..930c115 100644 --- a/autoload/lsp/lsp.vim +++ b/autoload/lsp/lsp.vim @@ -337,8 +337,7 @@ def g:LspShowSignature(): string enddef # A buffer is saved. Send the "textDocument/didSave" LSP notification -def LspSavedFile() - var bnr: number = expand('')->str2nr() +def LspSavedFile(bnr: number) var lspservers: list> = buf.BufLspServersGet(bnr)->filter( (key, lspsrv) => !lspsrv->empty() && lspsrv.running ) @@ -371,7 +370,7 @@ def AddBufLocalAutocmds(lspserver: dict, bnr: number): void acmds->add({bufnr: bnr, event: 'BufWritePost', group: 'LSPBufferAutocmds', - cmd: 'LspSavedFile()'}) + cmd: $'LspSavedFile({bnr})'}) # Update the diagnostics when insert mode is stopped acmds->add({bufnr: bnr, @@ -385,7 +384,7 @@ def AddBufLocalAutocmds(lspserver: dict, bnr: number): void acmds->add({bufnr: bnr, event: 'CursorMoved', group: 'LSPBufferAutocmds', - cmd: 'call LspDocHighlightClear() | call LspDocHighlight("silent")'}) + cmd: $'call LspDocHighlightClear({bnr}) | call LspDocHighlight({bnr}, "silent")'}) endif # Show diagnostics on the status line @@ -399,6 +398,8 @@ def AddBufLocalAutocmds(lspserver: dict, bnr: number): void autocmd_add(acmds) enddef +# The LSP server with ID "lspserverId" is ready, initialize the LSP features +# for buffer "bnr". def BufferInit(lspserverId: number, bnr: number): void var lspserver = buf.BufLspServerGetById(bnr, lspserverId) if lspserver->empty() || !lspserver.running @@ -815,28 +816,29 @@ export def ShowReferences(peek: bool) enddef # highlight all the places where a symbol is referenced -def g:LspDocHighlight(cmdmods: string = '') +def g:LspDocHighlight(bnr: number = bufnr(), cmdmods: string = '') var lspserver: dict = buf.CurbufGetServerChecked('documentHighlight') if lspserver->empty() return endif - lspserver.docHighlight(cmdmods) + lspserver.docHighlight(bnr, cmdmods) enddef # clear the symbol reference highlight -def g:LspDocHighlightClear() +def g:LspDocHighlightClear(bnr: number = bufnr()) var lspserver: dict = buf.CurbufGetServerChecked('documentHighlight') if lspserver->empty() return endif + var propNames = ['LspTextRef', 'LspReadRef', 'LspWriteRef'] if has('patch-9.0.0233') - prop_remove({types: ['LspTextRef', 'LspReadRef', 'LspWriteRef'], all: true}) + prop_remove({types: propNames, bufnr: bnr, all: true}) else - prop_remove({type: 'LspTextRef', all: true}) - prop_remove({type: 'LspReadRef', all: true}) - prop_remove({type: 'LspWriteRef', all: true}) + for propName in propNames + prop_remove({type: propName, bufnr: bnr, all: true}) + endfor endif enddef diff --git a/autoload/lsp/lspserver.vim b/autoload/lsp/lspserver.vim index 4ae4019..66e1124 100644 --- a/autoload/lsp/lspserver.vim +++ b/autoload/lsp/lspserver.vim @@ -995,13 +995,16 @@ enddef # Request: "textDocument/documentHighlight" # Param: DocumentHighlightParams -def DocHighlight(lspserver: dict, cmdmods: string): void +def DocHighlight(lspserver: dict, bnr: number, cmdmods: string): void # Check whether LSP server supports getting highlight information if !lspserver.isDocumentHighlightProvider util.ErrMsg('LSP server does not support document highlight') return endif + # Send the pending buffer changes to the language server + bnr->listener_flush() + # interface DocumentHighlightParams # interface TextDocumentPositionParams var params = lspserver.getTextDocPosition(false) @@ -1206,6 +1209,9 @@ def InlayHintsShow(lspserver: dict, bnr: number) return endif + # Send the pending buffer changes to the language server + bnr->listener_flush() + var binfo = bnr->getbufinfo() if binfo->empty() return diff --git a/autoload/lsp/options.vim b/autoload/lsp/options.vim index 26a4785..d682228 100644 --- a/autoload/lsp/options.vim +++ b/autoload/lsp/options.vim @@ -78,15 +78,17 @@ export var lspOptions: dict = { snippetSupport: false, # enable SirVer/ultisnips completion support ultisnipsSupport: false, - # enable hrsh7th/vim-vsnip completion support - vsnipSupport: false, - # Use a floating menu to show the code action menu instead of asking for input + # add to autocomplition list current buffer words + useBufferCompletion: false, + # Use a floating menu to show the code action menu instead of asking for + # input usePopupInCodeAction: false, # ShowReferences in a quickfix list instead of a location list` useQuickfixForLocations: false, - # add to autocomplition list current buffer words - useBufferCompletion: false, - # Limit the time autocompletion searches for words in current buffer (in milliseconds) + # enable hrsh7th/vim-vsnip completion support + vsnipSupport: false, + # Limit the time autocompletion searches for words in current buffer (in + # milliseconds) bufferCompletionTimeout: 100, # Enable support for custom completion kinds customCompletionKinds: false, diff --git a/autoload/lsp/signature.vim b/autoload/lsp/signature.vim index 55bb795..66a325d 100644 --- a/autoload/lsp/signature.vim +++ b/autoload/lsp/signature.vim @@ -34,7 +34,7 @@ export def BufferInit(lspserver: dict) endif if !opt.lspOptions.showSignature - # Show signature are disabled + # Show signature support is disabled return endif @@ -59,7 +59,6 @@ export def SignatureHelp(lspserver: dict, sighelp: any): void endif if sighelp.signatures->len() <= 0 - util.WarnMsg('No signature help available') CloseSignaturePopup(lspserver) return endif diff --git a/doc/lsp.txt b/doc/lsp.txt index d63ddea..7d46ad1 100644 --- a/doc/lsp.txt +++ b/doc/lsp.txt @@ -861,11 +861,14 @@ can map these commands to keys and make it easier to invoke them. *:LspHover* :LspHover Show the documentation for the symbol under the cursor in a popup window. If you want to show the symbol - documentation in the preview window instead of in a - popup set > + documentation in the |preview-window| instead of in a + popup window set > LspOptionsSet({'hoverInPreview': true}) < + You can use the |:pclose| command to close the preview + window. + You can use the |K| key in normal mode to display the documentation for the keyword under the cursor by setting the 'keywordprg' Vim option: > diff --git a/plugin/lsp.vim b/plugin/lsp.vim index 36b7ef4..49d6677 100644 --- a/plugin/lsp.vim +++ b/plugin/lsp.vim @@ -74,7 +74,7 @@ command! -nargs=0 -bar -count LspGotoDeclaration lsp.GotoDeclaration(v:false, , ) command! -nargs=0 -bar -count LspGotoImpl lsp.GotoImplementation(v:false, , ) command! -nargs=0 -bar -count LspGotoTypeDef lsp.GotoTypedef(v:false, , ) -command! -nargs=0 -bar LspHighlight call LspDocHighlight() +command! -nargs=0 -bar LspHighlight call LspDocHighlight(bufnr(), ) command! -nargs=0 -bar LspHighlightClear call LspDocHighlightClear() command! -nargs=? -bar LspHover lsp.Hover() command! -nargs=1 -bar -complete=customlist,lsp.LspInlayHintsComplete LspInlayHints lsp.InlayHints() -- 2.48.1