Neovim Lsp Auto-Fix / Fix-Current?
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...
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?
4 Answers
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)
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")()
Maybe you are looking for: vim.lsp.buf.code_action()?
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