aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/news.txt2
-rw-r--r--runtime/lua/vim/lsp/buf.lua11
-rw-r--r--runtime/lua/vim/lsp/protocol.lua2
-rw-r--r--test/functional/fixtures/fake-lsp-server.lua14
-rw-r--r--test/functional/plugin/lsp_spec.lua45
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()