neovim
neovim copied to clipboard
Supports LSP method `workspace/diagnostic`
Problem
Nvim already has support for textDocument/diagnostic, but with it, developer would only see issues in the files they had open. Changes in one file could introduce errors in other, unopened files, but the developer could remain unaware until those other files were opened.
I think quickfix feature was created partly to target this problem, but it would be great to enhance it with LSP workspace diagnostics
Workspace diagnostics are also useful for LLM, since many AI agents now support editing multiple files. I think it can also be used in a well-formatted "digest" including the project tree
Expected behavior
- Specification
- Users should be able to see workspace diagnostics either via the file explorer or in quickfix list
- There should also be a function that returns workspace diagnostics as a Lua table so I can easily add it to LLM context
What do you think @MariaSolOs
Sounds like a reasonable request to me. Tagging @lewis6991 @gpanders @mfussenegger and @justinmk for the bikeshedding discussion.
Support for this would be great for C# developers who are using the Roslyn LSP. Some relevant discussion here: https://github.com/seblyng/roslyn.nvim/issues/32
- Users should be able to see workspace diagnostics either via the file explorer or in quickfix list
- There should also be a function that returns workspace diagnostics as a Lua table so I can easily add it to LLM context
Those SGTM, though the file-explorer part should be ignored until we have a non-netrw answer for that.
Summarizing some of the discussion I had on Matrix with @lewis6991 and @clason about the implementation details of this:
- We would need a new
vim.lsp.workspace_diagnostics()function that returns all workspace diagnostics as the current architecture ofvim.diagnosticis mostly "push" and we would like to keepvim.diagnostic.get()sync. vim.lsp.workspace_diagnostics()would callvim.diagnostic.get()andvim.diagnostic.set()to handle the results following the spec ("diagnostics for a higher document version should win over those from a lower document version" and "diagnostics from a document pull should win over diagnostics from a workspace pull").
I'm happy to work on this, but before I start coding I would appreciate the input of @gpanders and @mfussenegger here too :)
need a new
vim.lsp.workspace_diagnostics()
nit: all of our current workspace-related functions are in vim.lsp.buf. The new one should go there too (or in vim.lsp.diagnostic ?), though it probably makes sense to introduce vim.lsp.workspace and relocate stuff there.
If anything I'd prefer to move all the vim.lsp.buf functions into vim.lsp.
Workspace diagnostics also isn't related to any buffer so can't go there anyway.
It shouldn't go in vim.diagnostic as it just doesn't belong there. Vim.diagnostic does not make LSP requests
To quote from the docs:
The
vim.lsp.buf_…functions perform operations for LSP clients attached to the current buffer.
So it's not about "buffer functions" but about all client functions for the current buffer, which makes it an appropriate place for requesting workspace diagnostics. (Of course, this becomes iffy with multiple clients per buffer...)
It's for sure not the most fortunate name for that module. Maybe we can find a better one to shove all client functions (buffer or workspace) under (keeping buf around as a compat shim)? (lsp.client or lsp.request come to mind)
It shouldn't go in
vim.diagnosticas it just doesn't belong there. Vim.diagnostic does not make LSP requests
This feels like an implementation detail though. From a public API standpoint, it does feel strange to have a diagnostic function outside vim.diagnostic.
It’s not an implementation detail. In the old days, diagnostics and LSP were intertwined. It was messy and there was no clean way to add diagnostics from non-LSP sources. Dedicated plugins existed solely to shim non-LSP diagnostics into LSP.
vim.diagnostic was created with the clear intent of separating generic diagnostics (which can come from anywhere, including but not limited to LSP) from LSP diagnostics. If we start adding LSP-isms back into vim.diagnostic then we are just moving backward to the point where we didn’t have a clear abstraction boundary between separate ideas.
It’s fine to have diagnostics functions under vim.lsp that are specific to LSP diagnostics. We already have a whole file dedicated to that.
This feels like an implementation detail though. From a public API standpoint, it does feel strange to have a diagnostic function outside vim.diagnostic.
It is not. It is a specific design detail of the interface. We discussed this at length and how to address it. At the moment vim.diagnostic just stores diagnostics that are pushed to it via vim.diagnostic.set() which can then be retrieved via vim.diagnostic.get(). There is no public or even private API for vim.diagnostic to pull diagnostics.
Fair enough. Thank you @gpanders and @lewis6991 for explaining. I apologize if I'm being slow in understanding the design decisions here, but as someone who lacks some of the historical context I was confused by the desire to keep vim.diagnostic LSP-independent, but thanks to @gpanders I finally get it.
To quote from the docs:
The
vim.lsp.buf_…functions perform operations for LSP clients attached to the current buffer.So it's not about "buffer functions" but about all client functions for the current buffer, which makes it an appropriate place for requesting workspace diagnostics. (Of course, this becomes iffy with multiple clients per buffer...)
It's for sure not the most fortunate name for that module. Maybe we can find a better one to shove all client functions (buffer or workspace) under (keeping
bufaround as a compat shim)? (lsp.clientorlsp.requestcome to mind)
After looking at what's already in vim.lsp.buf, I agree, we can just add a new function there for now. We can bikeshed a new home/namespace later.
After looking at what's already in
vim.lsp.buf, I agree, we can just add a new function there for now. We can bikeshed a new home/namespace later.
Why not just add the new function in vim.lsp.diagnostic?
Because that module is deprecated. (It's part of the old, bad, design we have replaced.)
After looking at what's already in
vim.lsp.buf, I agree, we can just add a new function there for now. We can bikeshed a new home/namespace later.Why not just add the new function in
vim.lsp.diagnostic?
Just like the quick fix entries structure, the vim.diagnostic structure can be used anywhere across the whole project. We don't need to add (or replace) a dedicated module for anything that uses vim.Diagnostic.
Okay then. I’ll add the new function to (the poorly named) vim.lsp.buf.
I've been playing around with workspace diagnostics (using the Roslyn LSP mentioned earlier in this thread) and have a question about this: when would we pull workspace diagnostics? Would this implementation include that? When testing with VS Code, it seems like it always has the most recent workspace diagnostics. I'm not sure how this implementation works or how to implement it. Would it get called on project open and when edits are made? Pulling workspace diagnostics can sometimes take a while. I know some LSPs implement PartialResultParams. What would happen if I make a change to a file that means there would be updated diagnostics for a document I already got results for, but the workspace pull isn't finished yet? Would we have to wait for it to finish before calling it again?
Because that module is deprecated. (It's part of the old, bad, design we have replaced.)
Afaik not all of it. See :help lsp-diagnostic. These functions aren't deprecated, and afaik there is no plan to change that?
Silly me, thinking :h vim.lsp.diagnostic would give me the right help tag.
(Still, the remaining functions are really low-level and not on the same level as a major LSP request.)
@brianhuster Or anyone else following this thread: Do you have a (preferably easy to set up) language server that supports workspace diagnostics that I can use to test https://github.com/neovim/neovim/pull/34262?
I think basedpyright (an LS for Python) supports workspace diagnostic. The config could look like this (assuming you also use nvim-lspconfig)
---@type vim.lsp.Config
vim.lsp.config.basedpyright = {
settings = {
basedpyright = {
analysis = {
diagnosticMode = 'workspace'
}
}
}
}
vim.lsp.enable 'basedpyright'
I think basedpyright (an LS for Python) supports workspace diagnostic. The config could look like this (assuming you also use nvim-lspconfig)
---@type vim.lsp.Config vim.lsp.config.basedpyright = { settings = { basedpyright = { analysis = { diagnosticMode = 'workspace' } } } } vim.lsp.enable 'basedpyright'
Hmm it doesn't seem like it supports the workspace/diagnostic request:
https://github.com/DetachHead/basedpyright/blob/0618b0988d6733f758bef6c0812780efd7e77bbe/packages/pyright-internal/src/languageServerBase.ts#L723
Microsoft's roslyn lsp does support workspace/diagnostic though it is pretty annoying to install. Also the server capabilities DiagnosticOptions.workspaceDiagnostics = false. Not sure if I have to change something in client capabilities. But you should get a response when sending the workspace/diagnostic or at least I do.
Hello there, i really want this in neovim, read through it here https://neovim.io/doc/user/lsp.html#vim.lsp.buf.workspace_diagnostics() and loved it, but i couldn't find anywhere that says in what version it is being planned to come... Is there such a place in the docs or here in the github?
thanks btw for the merge, this will help me out a lot <3
Features will land in the next minor release after the merge, in this case 0.12.