I was looking for a solution similar to CoC's coc-fix-current but using native lsp for Neovim 0.5 but I did not find such thing in the documentation, is there any way to achieve this through other method?
Asked
Active
Viewed 4,810 times
4 Answers
5
As of neovim 0.8, thanks to this PR, there's an apply
boolean which does just that.
To make sure you only apply relevant fixes, you can use the filter
attribute and look for the "prefered" fixes.
Here's what I've put in my config :
local opts = { noremap=true, silent=true }
local function quickfix()
vim.lsp.buf.code_action({
filter = function(a) return a.isPreferred end,
apply = true
})
end
vim.keymap.set('n', '<leader>qf', quickfix, opts)

ShellCode
- 1,072
- 8
- 17
3
I had this problem and by hacking up the code that the telescope.nvim
plugin uses to list and run code actions, came up with this monstrosity:
local function run_action(action, offse)
if action.edit or type(action.command) == "table" then
if action.edit then
vim.lsp.util.apply_workspace_edit(action.edit, offse)
end
if type(action.command) == "table" then
vim.lsp.buf.execute_command(action.command)
end
else
vim.lsp.buf.execute_command(action)
end
end
local function do_action(action, client)
if
not action.edit
and client
and type(client.resolved_capabilities.code_action) == "table"
and client.resolved_capabilities.code_action.resolveProvider
then
client.request("codeAction/resolve", action, function(err, real)
if err then
return
end
if real then
run_action(real, client.offset_encoding)
else
run_action(action, client.offset_encoding)
end
end)
else
run_action(action, client.offset_encoding)
end
end
return function()
local params = vim.lsp.util.make_range_params() -- get params for current position
params.context = {
diagnostics = vim.lsp.diagnostic.get_line_diagnostics(),
only = {"quickfix"}
}
local results, err = vim.lsp.buf_request_sync(
0, -- current buffer
"textDocument/codeAction", -- get code actions
params,
900
)
if err then return end
if not results or vim.tbl_isempty(results) then
print "No quickfixes!"
return
end
-- we have an action!
for cid, resp in pairs(results) do
if resp.result then
for _, result in pairs(resp.result) do
-- this is the first action, run it
do_action(result, vim.lsp.get_client_by_id(cid))
return
end
end
end
print "No quickfixes!"
end
Since it's lua, you'll need to place it in a .lua
file somewhere that nvim
searches for modules (for example, as ~/.config/nvim/lua/lsp_fixcurrent.lua
) and then bind to :lua require("lsp_fixcurrent")()

mincrmatt12
- 382
- 3
- 12
-
you sir made my day, it may look hacky but works very well, thank you! – Oscar Lastra Oct 28 '21 at 23:58
1
Maybe you are looking for: vim.lsp.buf.code_action()
?

Adrian Mole
- 49,934
- 160
- 51
- 83

KnairWang
- 19
- 1
-
1As far as I understand this is providing a valid answer to the question. Using this function I was able to fix fixable lsp errors. – Sassan Aug 08 '21 at 17:04
-
2While this opens a window to select a code action, it's not actually what I was searching for, i'm searching for a feature like coc's "coc-fix-current" which automatically selects the correct code action upon function invoke, I appreciate the answer anyways. – Oscar Lastra Aug 09 '21 at 03:48
-
In my case I'm using ccls for c++ as lsp server, and I have cases where coc's `coc-fix-current` fixes the issue and the native lsp `vim.lsp.buf.code_action({"quickfix"})` claims there is no code-action, not sure what is going on here (maybe bug, or just something I don't understand). Also haven't tried to accepted answer yet. – Emile Vrijdags Jan 27 '22 at 13:16
-
As for Rust, it seems like `coc-fix-current` will change code to what `cargo clippy` says, but `vim.lsp.buf.code_action()` won't. :( – MrZ Sep 03 '22 at 14:11
1
mincrmatt12 answer, updated for newer neovim (0.8?) which complains client.resolved_capabilities
should not be used.
local function run_action(action, offse)
if action.edit or type(action.command) == "table" then
if action.edit then
vim.lsp.util.apply_workspace_edit(action.edit, offse)
end
if type(action.command) == "table" then
vim.lsp.buf.execute_command(action.command)
end
else
vim.lsp.buf.execute_command(action)
end
end
local function do_action(action, client)
if
not action.edit
and client
and type(client.server_capabilities) == "table"
and client.server_capabilities.resolveProvider
then
client.request("codeAction/resolve", action, function(err, real)
if err then
return
end
if real then
run_action(real, client.offset_encoding)
else
run_action(action, client.offset_encoding)
end
end)
else
run_action(action, client.offset_encoding)
end
end
return function()
local params = vim.lsp.util.make_range_params() -- get params for current position
params.context = {
diagnostics = vim.lsp.diagnostic.get_line_diagnostics(),
only = { "quickfix" },
}
local results, err = vim.lsp.buf_request_sync(
0, -- current buffer
"textDocument/codeAction", -- get code actions
params,
900
)
if err then
return
end
if not results or vim.tbl_isempty(results) then
print("No quickfixes!")
return
end
-- we have an action!
for cid, resp in pairs(results) do
if resp.result then
for _, result in pairs(resp.result) do
-- this is the first action, run it
do_action(result, vim.lsp.get_client_by_id(cid))
return
end
end
end
print("No quickfixes!")
end

alextes
- 1,817
- 2
- 15
- 22