From 6f4fdc7bcc3a1ba041c6196b85b506bd0c207cf0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Magnus=20Gro=C3=9F?= Date: Mon, 4 Sep 2023 00:57:59 +0200 Subject: [PATCH] Add support for CompletionItem commands When we resolve a completion item with a "completionItem/resolve" request, the LSP server returns a CompletionItem object [0], which may contain an optional "command" field. This field describes a command that must be called **after** inserting the completion. For example the haskell-language-server may respond with the following command after autocompleting an unimported function (arguments are left out for brevity): {'command': '10619:ghcide-extend-import-action:extendImport', 'arguments': [], 'title': 'extend import'} Then when we send the matching "workspace/executeCommand" request, the server will respond with a "workspace/applyEdit" request, that autoimports the function. Technically the specification dictates that servers should prefer to set "additionalTextEdits" for that usecase, but there is still some use for doing it this way, e.g. haskell-language-server also wants to display an info message to the user, which doesn't happen with "additionalTextEdits". In any case it is important to support the "command" field, as it may also contain actions unrelated to "additionalTextEdits". [0] https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionItem --- autoload/lsp/completion.vim | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/autoload/lsp/completion.vim b/autoload/lsp/completion.vim index 3d1c2be..0d64e2b 100644 --- a/autoload/lsp/completion.vim +++ b/autoload/lsp/completion.vim @@ -7,6 +7,7 @@ import './buffer.vim' as buf import './options.vim' as opt import './textedit.vim' import './snippet.vim' +import './codeaction.vim' # per-filetype omni-completion enabled/disabled table var ftypeOmniCtrlMap: dict = {} @@ -590,12 +591,17 @@ def LspCompleteDone(bnr: number) # additional text edits. So try to resolve the completion item now to get # the text edits. completionData = lspserver.resolveCompletion(completionData, true) - if completionData->get('additionalTextEdits', {})->empty() - return + if !completionData->get('additionalTextEdits', {})->empty() + textedit.ApplyTextEdits(bnr, completionData.additionalTextEdits) endif endif - textedit.ApplyTextEdits(bnr, completionData.additionalTextEdits) + if completionData->has_key('command') + # Some language servers (e.g. haskell-language-server) want to apply + # additional commands after completion. + codeaction.DoCommand(lspserver, completionData.command) + endif + enddef # Initialize buffer-local completion options and autocmds -- 2.44.0