Nvim-lspconfig: add diagnostics to quicklist

Created on 9 Dec 2019  路  10Comments  路  Source: neovim/nvim-lspconfig

hi,

Some things I miss from coc.nvim:

  • having whole project diagnostics open in the quickfix
  • file specific diagnostics in locationlist

Then I suppose this is out of scope for the plugin, but coc.nvim has mappings to go to next diagnostic from current line. In case you have such a snippet, I am eager :p

enhancement

Most helpful comment

Here's a snippet for how to do it for all servers by changing the default callback. You could also do this on a per client level with setup { callbacks = { ["textDocument/publishDiagnostics"] = ... } }

do
  local method = 'textDocument/publishDiagnostics'
  local default_callback = vim.lsp.callbacks[method]
  vim.lsp.callbacks[method] = function(err, method, result, client_id)
    default_callback(err, method, result, client_id)
    if result and result.diagnostics then
      for _, v in ipairs(result.diagnostics) do
        v.uri = v.uri or result.uri
      end
      vim.lsp.util.set_qflist(result.diagnostics)
    end
  end
end

The reason I loop and set uri is because set_qflist expects a list of Locations and the diagnostics usually are set for a single (in this case the current) file.

All 10 comments

Here's a snippet for how to do it for all servers by changing the default callback. You could also do this on a per client level with setup { callbacks = { ["textDocument/publishDiagnostics"] = ... } }

do
  local method = 'textDocument/publishDiagnostics'
  local default_callback = vim.lsp.callbacks[method]
  vim.lsp.callbacks[method] = function(err, method, result, client_id)
    default_callback(err, method, result, client_id)
    if result and result.diagnostics then
      for _, v in ipairs(result.diagnostics) do
        v.uri = v.uri or result.uri
      end
      vim.lsp.util.set_qflist(result.diagnostics)
    end
  end
end

The reason I loop and set uri is because set_qflist expects a list of Locations and the diagnostics usually are set for a single (in this case the current) file.

is textDocument/publishDiagnostics sent passively, or does it require some request to be sent first?

It's a notification, which means server sent one way communique.

thanks for the snippet. Seems like it stopped working (callback member disappeared ?).
Also the snippet displayed the buffer line in quickfix rather than the error (more useful, especially when the screen is too narrow to display the virtualtext).

@teto could you expand on what "callback member disappeared" means? The specific error message would be good.

And yeah, that's a good point, the set_qflist was something I designed originally for locations and didn't consider that they could be reused with custom messages (such as from diagnostics). I'll see about adding that as a modification of the utility function or in addition to it.

If you're interested in doing it yourself and maybe contributing to neovim builtin lsp, I would recommend looking at https://github.com/neovim/neovim/blob/master/runtime/lua/vim/lsp/util.lua#L595 for how it's currently being implemented. The simplest modification would be to make the line that reads text = line to consider the custom message in row.

nevermind it worked again. thanks for the pointer. I might have a look, I have a few PRs in the pipeline I would liketo merge first.

works now on master ty.

@norcalli thanks for the snippet!!!
@teto I use vim-qf to "tame the quickfix" as the plugin claims, this is what I've come up that is very similar to coc

Plug 'romainl/vim-qf'

...

nmap <leader>qq <Plug>(qf_qf_toggle)
nmap gn     <Plug>(qf_qf_next)
nmap gp     <Plug>(qf_qf_previous)

@norcalli thanks for your snippet! It actually creates multiple quick lists with the same diagnostics. I don't suppose it should do that. A single quick fix list should be created for project-wide all open buffers diagnostics and I assume multiple location lists for several buffers.
I am very new to Lua, although I have found it to be easier to understand and write. Here is my lua config. I would really appreciate some pointers to achieve this.

Thank you for the snippet! However, either set_qflist has changed, or the format of the diagnostics tables, so I had to tweak it a little bit to get it to work:

do
  local method = "textDocument/publishDiagnostics"
  local default_callback = vim.lsp.callbacks[method]
  vim.lsp.callbacks[method] = function(err, method, result, client_id)
    default_callback(err, method, result, client_id)
    if result and result.diagnostics then
      for _, v in ipairs(result.diagnostics) do
        v.bufnr = client_id
        v.lnum = v.range.start.line + 1
        v.col = v.range.start.character + 1
        v.text = v.message
      end
      vim.lsp.util.set_qflist(result.diagnostics)
    end
  end
end

If anyone else ends up needing to tweak this: figure out the structure of the diagnostics tables by putting print(vim.inspect(v)) inside the for loop (you might have to run :messages to display the results). Run :help setqflist to see what keys you need to set.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ahmedelgabri picture ahmedelgabri  路  4Comments

RefusesNames picture RefusesNames  路  3Comments

mcepl picture mcepl  路  8Comments

dlukes picture dlukes  路  4Comments

DarkDefender picture DarkDefender  路  3Comments