diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 8bf3764f5e..ddf2c33b88 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -679,7 +679,7 @@ local function on_code_action_results(results, ctx, options) -- command: string -- arguments?: any[] -- - 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] if not action.edit @@ -688,10 +688,14 @@ local function on_code_action_results(results, ctx, options) then client.request('codeAction/resolve', action, function(err, resolved_action) if err then - vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR) - return + if action.command then + apply_action(action, client) + else + vim.notify(err.code .. ': ' .. err.message, vim.log.levels.ERROR) + end + else + apply_action(resolved_action, client) end - apply_action(resolved_action, client) end) else apply_action(action, client) diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 72ff5864bc..7d91bd6a0b 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -3309,6 +3309,48 @@ describe('LSP', function() 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) describe('vim.lsp.commands', function() it('Accepts only string keys', function()