diff options
-rw-r--r-- | runtime/doc/news.txt | 2 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 11 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/protocol.lua | 2 | ||||
-rw-r--r-- | test/functional/fixtures/fake-lsp-server.lua | 14 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 45 |
5 files changed, 66 insertions, 8 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 4667af906f..1b9c3a463f 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -309,6 +309,8 @@ LSP • |vim.lsp.config()| has been added to define default configurations for servers. In addition, configurations can be specified in `lsp/<name>.lua`. • |vim.lsp.enable()| has been added to enable servers. +• |vim.lsp.buf.code_action()| resolves the `command` property during the + `codeAction/resolve` request. LUA diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 47f41b43aa..094be17c83 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -1129,6 +1129,7 @@ local function on_code_action_results(results, opts) if not choice then return end + -- textDocument/codeAction can return either Command[] or CodeAction[] -- -- CodeAction @@ -1140,12 +1141,18 @@ local function on_code_action_results(results, opts) -- title: string -- command: string -- arguments?: any[] - -- + local client = assert(lsp.get_client_by_id(choice.ctx.client_id)) local action = choice.action local bufnr = assert(choice.ctx.bufnr, 'Must have buffer number') - if not action.edit and client:supports_method(ms.codeAction_resolve) then + -- Only code actions are resolved, so if we have a command, just apply it. + if type(action.title) == 'string' and type(action.command) == 'string' then + apply_action(action, client, choice.ctx) + return + end + + if not action.edit or not action.command and client:supports_method(ms.codeAction_resolve) then client:request(ms.codeAction_resolve, action, function(err, resolved_action) if err then if action.command then diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index 7975006f9d..feff9adbd0 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -424,7 +424,7 @@ function protocol.make_client_capabilities() isPreferredSupport = true, dataSupport = true, resolveSupport = { - properties = { 'edit' }, + properties = { 'edit', 'command' }, }, }, codeLens = { diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua index 5d7ab2ad12..6798d53d2b 100644 --- a/test/functional/fixtures/fake-lsp-server.lua +++ b/test/functional/fixtures/fake-lsp-server.lua @@ -789,15 +789,19 @@ function tests.code_action_with_resolve() end, body = function() notify('start') - local cmd = { - title = 'Command 1', - command = 'dummy1', - } + local cmd = { title = 'Action 1' } expect_request('textDocument/codeAction', function() return nil, { cmd } end) expect_request('codeAction/resolve', function() - return nil, cmd + return nil, + { + title = 'Action 1', + command = { + title = 'Command 1', + command = 'dummy1', + }, + } end) notify('shutdown') end, diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 17e3fbbf70..33dfae6b12 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -4591,6 +4591,51 @@ describe('LSP', function() eq('workspace/executeCommand', result[5].method) eq('command:1', result[5].params.command) end) + + it('Resolves command property', function() + clear() + exec_lua(create_server_definition) + local result = exec_lua(function() + local server = _G._create_server({ + capabilities = { + executeCommandProvider = { + commands = { 'command:1' }, + }, + codeActionProvider = { + resolveProvider = true, + }, + }, + handlers = { + ['textDocument/codeAction'] = function(_, _, callback) + callback(nil, { + { title = 'Code Action 1' }, + }) + end, + ['codeAction/resolve'] = function(_, _, callback) + callback(nil, { + title = 'Code Action 1', + command = { + title = 'Command 1', + command = 'command:1', + }, + }) + end, + }, + }) + + local client_id = assert(vim.lsp.start({ + name = 'dummy', + cmd = server.cmd, + })) + + vim.lsp.buf.code_action({ apply = true }) + vim.lsp.stop_client(client_id) + return server.messages + end) + eq('codeAction/resolve', result[4].method) + eq('workspace/executeCommand', result[5].method) + eq('command:1', result[5].params.command) + end) end) describe('vim.lsp.commands', function() |