mirror of
https://github.com/neovim/neovim.git
synced 2025-09-07 11:58:17 +00:00
feat(lsp): handle disabled code actions (#34453)
This commit also makes it so that disabled code actions are not displayed unless the trigger kind is "Invoked".
This commit is contained in:
@@ -174,6 +174,7 @@ LSP
|
|||||||
• Incremental selection is now supported via `textDocument/selectionRange`.
|
• Incremental selection is now supported via `textDocument/selectionRange`.
|
||||||
`an` selects outwards and `in` selects inwards.
|
`an` selects outwards and `in` selects inwards.
|
||||||
• Support for multiline semantic tokens.
|
• Support for multiline semantic tokens.
|
||||||
|
• Support for the `disabled` field on code actions.
|
||||||
|
|
||||||
LUA
|
LUA
|
||||||
|
|
||||||
|
@@ -1141,20 +1141,26 @@ local function on_code_action_results(results, opts)
|
|||||||
---@param a lsp.Command|lsp.CodeAction
|
---@param a lsp.Command|lsp.CodeAction
|
||||||
local function action_filter(a)
|
local function action_filter(a)
|
||||||
-- filter by specified action kind
|
-- filter by specified action kind
|
||||||
if opts and opts.context and opts.context.only then
|
if opts and opts.context then
|
||||||
if not a.kind then
|
if opts.context.only then
|
||||||
return false
|
if not a.kind then
|
||||||
end
|
return false
|
||||||
local found = false
|
end
|
||||||
for _, o in ipairs(opts.context.only) do
|
local found = false
|
||||||
-- action kinds are hierarchical with . as a separator: when requesting only 'type-annotate'
|
for _, o in ipairs(opts.context.only) do
|
||||||
-- this filter allows both 'type-annotate' and 'type-annotate.foo', for example
|
-- action kinds are hierarchical with . as a separator: when requesting only 'type-annotate'
|
||||||
if a.kind == o or vim.startswith(a.kind, o .. '.') then
|
-- this filter allows both 'type-annotate' and 'type-annotate.foo', for example
|
||||||
found = true
|
if a.kind == o or vim.startswith(a.kind, o .. '.') then
|
||||||
break
|
found = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not found then
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not found then
|
-- Only show disabled code actions when the trigger kind is "Invoked".
|
||||||
|
if a.disabled and opts.context.triggerKind ~= lsp.protocol.CodeActionTriggerKind.Invoked then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1223,6 +1229,11 @@ local function on_code_action_results(results, opts)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if action.disabled then
|
||||||
|
vim.notify(action.disabled.reason, vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if not (action.edit and action.command) and client:supports_method(ms.codeAction_resolve) then
|
if not (action.edit and 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
|
||||||
@@ -1253,6 +1264,10 @@ local function on_code_action_results(results, opts)
|
|||||||
local clients = lsp.get_clients({ bufnr = item.ctx.bufnr })
|
local clients = lsp.get_clients({ bufnr = item.ctx.bufnr })
|
||||||
local title = item.action.title:gsub('\r\n', '\\r\\n'):gsub('\n', '\\n')
|
local title = item.action.title:gsub('\r\n', '\\r\\n'):gsub('\n', '\\n')
|
||||||
|
|
||||||
|
if item.action.disabled then
|
||||||
|
title = title .. ' (disabled)'
|
||||||
|
end
|
||||||
|
|
||||||
if #clients == 1 then
|
if #clients == 1 then
|
||||||
return title
|
return title
|
||||||
end
|
end
|
||||||
|
@@ -430,6 +430,7 @@ function protocol.make_client_capabilities()
|
|||||||
resolveSupport = {
|
resolveSupport = {
|
||||||
properties = { 'edit', 'command' },
|
properties = { 'edit', 'command' },
|
||||||
},
|
},
|
||||||
|
disabledSupport = true,
|
||||||
},
|
},
|
||||||
codeLens = {
|
codeLens = {
|
||||||
dynamicRegistration = false,
|
dynamicRegistration = false,
|
||||||
|
@@ -4718,6 +4718,70 @@ 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('supports disabled actions', function()
|
||||||
|
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',
|
||||||
|
disabled = {
|
||||||
|
reason = 'This action is disabled',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
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,
|
||||||
|
}))
|
||||||
|
|
||||||
|
--- @diagnostic disable-next-line:duplicate-set-field
|
||||||
|
vim.notify = function(message, code)
|
||||||
|
server.messages[#server.messages + 1] = {
|
||||||
|
params = {
|
||||||
|
message = message,
|
||||||
|
code = code,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.lsp.buf.code_action({ apply = true })
|
||||||
|
vim.lsp.stop_client(client_id)
|
||||||
|
return server.messages
|
||||||
|
end)
|
||||||
|
eq(
|
||||||
|
exec_lua(function()
|
||||||
|
return { message = 'This action is disabled', code = vim.log.levels.ERROR }
|
||||||
|
end),
|
||||||
|
result[4].params
|
||||||
|
)
|
||||||
|
-- No command is resolved/applied after selecting a disabled code action
|
||||||
|
eq('shutdown', result[5].method)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('vim.lsp.commands', function()
|
describe('vim.lsp.commands', function()
|
||||||
|
Reference in New Issue
Block a user