-
-
Save alextes/e6704e5376709d194d21f615f8542ccb to your computer and use it in GitHub Desktop.
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 actions_per_client, err = vim.lsp.buf_request_sync( | |
0, | |
"textDocument/codeAction", | |
params, | |
900 | |
) | |
if err then | |
return | |
end | |
if actions_per_client == nil or vim.tbl_isempty(actions_per_client) or #actions_per_client == 0 then | |
vim.notify("no quickfixes available") | |
return | |
end | |
-- Collect the available actions | |
local actions = {} | |
for cid, resp in pairs(actions_per_client) do | |
if resp.result ~= nil then | |
for _, result in pairs(resp.result) do | |
-- add the actions with a cid to the table | |
local action = {} | |
action["cid"] = cid | |
for k, v in pairs(result) do | |
action[k] = v | |
end | |
table.insert(actions, action) | |
end | |
end | |
end | |
-- Try to find a preferred action. | |
local preferred_action = nil | |
for _, action in ipairs(actions) do | |
if action.isPreferred then | |
preferred_action = action | |
break | |
end | |
end | |
-- If we failed to find a preferred action, try to find a non-null-ls action. | |
local non_null_ls_action = nil | |
for _, action in ipairs(actions) do | |
if action.command ~= "NULL_LS_CODE_ACTION" then | |
non_null_ls_action = action | |
break | |
end | |
end | |
-- If we failed to find a non-null-ls action, use the first one. | |
local first_action = nil | |
if #actions > 0 then | |
first_action = actions[1] | |
end | |
-- Using null-ls a lot of quickfixes are returned but all tend to be | |
-- worse than what the real LSP is offering, we try to use other | |
-- actions first, then only fall back to whatever null-ls is offering. | |
local top_action = preferred_action or non_null_ls_action or first_action | |
-- print(vim.inspect(top_action)) | |
local picked_one = false | |
vim.lsp.buf.code_action({ | |
context = { | |
only = { "quickfix" }, | |
}, | |
filter = function(action, ctx) | |
if picked_one then | |
return true | |
elseif top_action ~= nil and action.title == top_action.title then | |
picked_one = true | |
return false | |
else | |
return true | |
end | |
end, | |
apply = true, | |
}) | |
end |
local on_attach = function(client, bufnr) | |
local nmap = function(keys, func, desc) | |
if desc then | |
desc = "LSP: " .. desc | |
end | |
vim.keymap.set("n", keys, func, { buffer = bufnr, desc = desc }) | |
end | |
nmap("gq", require("fixcurrent"), "[G]o [Q]uickfix") | |
end | |
local servers = { | |
gopls = {}, | |
-- pyright = {}, | |
rust_analyzer = {}, | |
tsserver = {}, | |
lua_ls = { | |
Lua = { | |
workspace = { checkThirdParty = false }, | |
telemetry = { enable = false }, | |
}, | |
}, | |
} | |
local capabilities = vim.lsp.protocol.make_client_capabilities() | |
-- Setup mason so it can manage external tooling | |
require("mason").setup() | |
-- Ensure the servers above are installed | |
local mason_lspconfig = require("mason-lspconfig") | |
mason_lspconfig.setup({ | |
ensure_installed = vim.tbl_keys(servers), | |
}) | |
mason_lspconfig.setup_handlers({ | |
function(server_name) | |
require("lspconfig")[server_name].setup({ | |
capabilities = capabilities, | |
on_attach = on_attach, | |
settings = servers[server_name], | |
}) | |
end, | |
}) |
Yes, it does. I removed the part about null-ls
as I use jdtls
with neovim-lsp
directly, so it's just local top_action = actions[1]
. The error I got is
E5108: Error executing lua: /usr/share/nvim/runtime/lua/vim/lsp/buf.lua:796: command: expected string, got nil
and a stack trace pointing to https://gist.github.com/alextes/e6704e5376709d194d21f615f8542ccb#file-init-lua-L10. Seems like a validate()
call inside vim.lsp.buf.execute_command
expects the argument passed in to be a table containing command
key, but the action
object here does not have that key.
{
cid = 1,
data = {
pid = "0",
rid = "0"
},
diagnostics = { {
code = "570425394",
data = { "Micronaut" },
message = "Micronaut cannot be resolved",
range = {
["end"] = {
character = 17,
line = 4
},
start = {
character = 8,
line = 4
}
},
severity = 1,
source = "Java"
} },
kind = "quickfix",
title = "Import 'Micronaut' (io.micronaut.runtime)"
}
I don't know much about LSP or Neovim API, so I can't fix it for now. Just commented to show appreciation, as all the language servers I used advertised isPreferred
support, but none have that key in the action :|
@duongdominhchau my bad! I didn't notice what you're looking at is very old!! I'll update the gist right now.
Thanks for the appreciation 💛
Thank you for the update. I tried this new config but cannot autofix with Ruff, to make it works, I flipped the boolean value returned from filter
and remove the only = "quickfix"
. It sounds reasonable to me, not sure why it needs to be removed 🤷
Writing it here in case someone else gets into the same issue as me.
Edit: Wonderful, the new solution works with both jdtls
and ruff_lsp
. Thanks again.
@duongdominhchau yea, Rust isn't handling every action either, only most. It is however quite easy to sprinkle some
print(vim.inspect(...))
in there and see why it isn't picking the action you like. Feel free to check why it doesn't and suggest improvements if you like. Does jdtls report any actions?