mirror of
https://github.com/neovim/neovim
synced 2025-07-16 17:21:49 +00:00
feat(lsp): support for resolving code action command (#32704)
* fix(lsp): don't call codeAction_resolve with commands * feat(lsp): support for resolving code action command
This commit is contained in:
committed by
GitHub
parent
0c0352783f
commit
41b07b128c
@ -309,6 +309,8 @@ LSP
|
|||||||
• |vim.lsp.config()| has been added to define default configurations for
|
• |vim.lsp.config()| has been added to define default configurations for
|
||||||
servers. In addition, configurations can be specified in `lsp/<name>.lua`.
|
servers. In addition, configurations can be specified in `lsp/<name>.lua`.
|
||||||
• |vim.lsp.enable()| has been added to enable servers.
|
• |vim.lsp.enable()| has been added to enable servers.
|
||||||
|
• |vim.lsp.buf.code_action()| resolves the `command` property during the
|
||||||
|
`codeAction/resolve` request.
|
||||||
|
|
||||||
LUA
|
LUA
|
||||||
|
|
||||||
|
@ -1129,6 +1129,7 @@ local function on_code_action_results(results, opts)
|
|||||||
if not choice then
|
if not choice then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- textDocument/codeAction can return either Command[] or CodeAction[]
|
-- textDocument/codeAction can return either Command[] or CodeAction[]
|
||||||
--
|
--
|
||||||
-- CodeAction
|
-- CodeAction
|
||||||
@ -1140,12 +1141,18 @@ local function on_code_action_results(results, opts)
|
|||||||
-- title: string
|
-- title: string
|
||||||
-- command: string
|
-- command: string
|
||||||
-- arguments?: any[]
|
-- arguments?: any[]
|
||||||
--
|
|
||||||
local client = assert(lsp.get_client_by_id(choice.ctx.client_id))
|
local client = assert(lsp.get_client_by_id(choice.ctx.client_id))
|
||||||
local action = choice.action
|
local action = choice.action
|
||||||
local bufnr = assert(choice.ctx.bufnr, 'Must have buffer number')
|
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)
|
client:request(ms.codeAction_resolve, action, function(err, resolved_action)
|
||||||
if err then
|
if err then
|
||||||
if action.command then
|
if action.command then
|
||||||
|
@ -424,7 +424,7 @@ function protocol.make_client_capabilities()
|
|||||||
isPreferredSupport = true,
|
isPreferredSupport = true,
|
||||||
dataSupport = true,
|
dataSupport = true,
|
||||||
resolveSupport = {
|
resolveSupport = {
|
||||||
properties = { 'edit' },
|
properties = { 'edit', 'command' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
codeLens = {
|
codeLens = {
|
||||||
|
@ -789,15 +789,19 @@ function tests.code_action_with_resolve()
|
|||||||
end,
|
end,
|
||||||
body = function()
|
body = function()
|
||||||
notify('start')
|
notify('start')
|
||||||
local cmd = {
|
local cmd = { title = 'Action 1' }
|
||||||
title = 'Command 1',
|
|
||||||
command = 'dummy1',
|
|
||||||
}
|
|
||||||
expect_request('textDocument/codeAction', function()
|
expect_request('textDocument/codeAction', function()
|
||||||
return nil, { cmd }
|
return nil, { cmd }
|
||||||
end)
|
end)
|
||||||
expect_request('codeAction/resolve', function()
|
expect_request('codeAction/resolve', function()
|
||||||
return nil, cmd
|
return nil,
|
||||||
|
{
|
||||||
|
title = 'Action 1',
|
||||||
|
command = {
|
||||||
|
title = 'Command 1',
|
||||||
|
command = 'dummy1',
|
||||||
|
},
|
||||||
|
}
|
||||||
end)
|
end)
|
||||||
notify('shutdown')
|
notify('shutdown')
|
||||||
end,
|
end,
|
||||||
|
@ -4591,6 +4591,51 @@ describe('LSP', function()
|
|||||||
eq('workspace/executeCommand', result[5].method)
|
eq('workspace/executeCommand', result[5].method)
|
||||||
eq('command:1', result[5].params.command)
|
eq('command:1', result[5].params.command)
|
||||||
end)
|
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)
|
end)
|
||||||
|
|
||||||
describe('vim.lsp.commands', function()
|
describe('vim.lsp.commands', function()
|
||||||
|
Reference in New Issue
Block a user