-
-
Save phelipetls/0aeb9f4aca9af25d9f45ee56e0c5a340 to your computer and use it in GitHub Desktop.
local severity_map = { "E", "W", "I", "H" } | |
local parse_diagnostics = function(diagnostics) | |
if not diagnostics then return end | |
local items = {} | |
for _, diagnostic in ipairs(diagnostics) do | |
local fname = vim.fn.bufname() | |
local position = diagnostic.range.start | |
local severity = diagnostic.severity | |
table.insert(items, { | |
filename = fname, | |
type = severity_map[severity], | |
lnum = position.line + 1, | |
col = position.character + 1, | |
text = diagnostic.message:gsub("\r", ""):gsub("\n", " ") | |
}) | |
end | |
return items | |
end | |
-- redefine unwanted callbacks to be an empty function | |
-- notice that I keep `vim.lsp.util.buf_diagnostics_underline()` | |
vim.lsp.util.buf_diagnostics_signs = function() return end | |
vim.lsp.util.buf_diagnostics_virtual_text = function() return end | |
update_diagnostics_loclist = function() | |
bufnr = vim.fn.bufnr() | |
diagnostics = vim.lsp.util.diagnostics_by_buf[bufnr] | |
items = parse_diagnostics(diagnostics) | |
vim.lsp.util.set_loclist(items) | |
vim.api.nvim_command("doautocmd QuickFixCmdPost") | |
end | |
vim.api.nvim_command [[autocmd! User LspDiagnosticsChanged lua update_diagnostics_loclist()]] |
For people like me that want to both have the diagnostics in the location list, and keep the virtual text, I suggest the following approach instead:
- Subscribe to the
LspDiagnosticsChanged
autocmd - Get the diagnostics for the current buffer by calling
vim.lsp.util.diagnostics_by_buf
- Add these to location list
@svermeulen Utilizing the LspDiagnosticsChanged
autocmd and vim.lsp.util.diagnostics_by_buf
is certainly the better approach, but it's worth mentioning that vim.lsp.util.diagnostics_by_buf
did not exist until neovim/neovim@ef0398f, 14 days after the current revision of this gist (as of writing).
Additionally, if somebody did want to prevent the virtual text, it may be better to not override the textDocument/publishDiagnostics
callback, and instead redefine vim.lsp.util.diagnostics_virtual_text
to be an empty function. This is a hack since there's currently not a global option to disable virtual text (I suspect there will be one in the near future), but it's a lesser evil than redefining the entire diagnostics callback to prevent virtual text. By redefining the callback, you run the risk of falling out of sync with upstream.
I have taken your advice into account and updated the gist. It's much cleaner now, thanks!
I wonder though, is that function parse_diagnostics
really necessary? vim.lsp.util.locations_to_items
doesn't work for me... although by the source code it does seem to kinda do what I want, but it does it in a more complex/sophisticated way.
Thanks for this! Using NVIM v0.5.0-dev+94cf7bb
I had to change diagnostics = vim.lsp.util.diagnostics_by_buf[bufnr]
to vim.lsp.diagnostic.get()
.
This is pretty old already, I believe you can just use vim.lsp.diagnostic.set_loclist()
. At least that's what I'm using and it works.
Awesome, thanks! That seems to work for me too.
From lsp documentation
vim.lsp.diagnostic.set_loclist() Use vim.diagnostic.setloclist() instead
Yes, it was added inside neovim api. One could write it as this snippet:
-- Populate loclist with the current buffer diagnostics
vim.api.nvim_create_autocmd('DiagnosticChanged', {
callback = function(args)
vim.diagnostic.setloclist({open = false})
end,
})
Later I preferred to put it into the location list so it wouldn't conflict with a quickfix list if there is one (for example, if I did some grep and then save the file, the grep qflist would be gone which is not what I want).
So, in this way, the LSP diagnostics will be put into the location list, which will be opened on save and closed when it's empty.
This is more appropriate because the location list really is meant to be used per window and the quickfix list is a more generic thing.