mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
feat(lsp): fallback to code-action command on resolve failure (#25464)
The haskell-language-server supports resolve only for a subset of code actions. For many code actions trying to resolve the `edit` property results in an error, but the unresolved action already contains a command that can be executed without issue. The protocol specification is unfortunately a bit vague about this, and what the haskell-language-server does seems to be valid. Example: newtype Dummy = Dummy Int instance Num Dummy where Triggering code actions on "Num Dummy" and choosing "Add placeholders for all missing methods" resulted in: -32601: No plugin enabled for SMethod_CodeActionResolve, potentially available: explicit-fields, importLens, hlint, overloaded-record-dot With this change it will insert the missing methods: instance Num Dummy where (+) = _ (-) = _ (*) = _ negate = _ abs = _ signum = _ fromInteger = _
This commit is contained in:
parent
09a17f91d0
commit
4a09c178a1
@ -652,7 +652,7 @@ local function on_code_action_results(results, ctx, options)
|
|||||||
-- arguments?: any[]
|
-- arguments?: any[]
|
||||||
--
|
--
|
||||||
---@type lsp.Client
|
---@type lsp.Client
|
||||||
local client = vim.lsp.get_client_by_id(action_tuple[1])
|
local client = assert(vim.lsp.get_client_by_id(action_tuple[1]))
|
||||||
local action = action_tuple[2]
|
local action = action_tuple[2]
|
||||||
|
|
||||||
local reg = client.dynamic_capabilities:get(ms.textDocument_codeAction, { bufnr = ctx.bufnr })
|
local reg = client.dynamic_capabilities:get(ms.textDocument_codeAction, { bufnr = ctx.bufnr })
|
||||||
@ -663,10 +663,14 @@ local function on_code_action_results(results, ctx, options)
|
|||||||
if not action.edit and client and supports_resolve then
|
if not action.edit and client and supports_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
|
||||||
vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR)
|
if action.command then
|
||||||
return
|
apply_action(action, client)
|
||||||
|
else
|
||||||
|
vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
apply_action(resolved_action, client)
|
||||||
end
|
end
|
||||||
apply_action(resolved_action, client)
|
|
||||||
end, ctx.bufnr)
|
end, ctx.bufnr)
|
||||||
else
|
else
|
||||||
apply_action(action, client)
|
apply_action(action, client)
|
||||||
|
@ -3483,6 +3483,50 @@ describe('LSP', function()
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
it("Fallback to command execution on resolve error", function()
|
||||||
|
clear()
|
||||||
|
exec_lua(create_server_definition)
|
||||||
|
local result = exec_lua([[
|
||||||
|
local server = _create_server({
|
||||||
|
capabilities = {
|
||||||
|
executeCommandProvider = {
|
||||||
|
commands = {"command:1"},
|
||||||
|
},
|
||||||
|
codeActionProvider = {
|
||||||
|
resolveProvider = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handlers = {
|
||||||
|
["textDocument/codeAction"] = function()
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
title = "Code Action 1",
|
||||||
|
command = {
|
||||||
|
title = "Command 1",
|
||||||
|
command = "command:1",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
["codeAction/resolve"] = function()
|
||||||
|
return nil, "resolve failed"
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
local client_id = vim.lsp.start({
|
||||||
|
name = "dummy",
|
||||||
|
cmd = server.cmd,
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.lsp.buf.code_action({ apply = true })
|
||||||
|
vim.lsp.stop_client(client_id)
|
||||||
|
return server.messages
|
||||||
|
]])
|
||||||
|
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()
|
||||||
it('Accepts only string keys', function()
|
it('Accepts only string keys', function()
|
||||||
|
Loading…
Reference in New Issue
Block a user