Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(lsp): implement textDocument/diagnostic #24128

Merged
merged 2 commits into from
Jul 20, 2023

Conversation

catlee
Copy link
Contributor

@catlee catlee commented Jun 23, 2023

I'm trying to implement the textDocument/diagnostic capability introduced in LSP 3.17.0 (#22838)

The client initiates a request for diagnostics to the server, instead of having the server push diagnostics to the client.

I took a lot of the code from the inlayHints implementation since that also seemed to poll the server in similar way.

Current status:

  • pull diagnostics are enabled when servers advertise the diagnosticProvider capability

TODO:

  • Tests
  • Refactor common code (e.g. timer related stuff) between inlay_hints and diagnostic
  • Docs
  • Should it be enabled by default? Figure out how to get it enabled when ruby-lsp attaches. Does this go into lspconfig?
  • Not sure if the clear function is doing the right thing. I couldn't figure out how to get a client id.
  • File issues for follow-up:

@github-actions github-actions bot added the lsp label Jun 23, 2023
@catlee catlee force-pushed the catlee/diagnostic branch from 2376041 to 2d622f7 Compare June 23, 2023 02:43
runtime/lua/vim/lsp/buf.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp/diagnostic.lua Outdated Show resolved Hide resolved
@clason clason changed the title WIP - implement textDocument/diagnostic feat(lsp): implement textDocument/diagnostic Jun 23, 2023
@catlee catlee force-pushed the catlee/diagnostic branch 3 times, most recently from ef51d39 to e4b5532 Compare June 29, 2023 13:35
@catlee
Copy link
Contributor Author

catlee commented Jun 29, 2023

I wonder if the requests for diagnostics is better done within the changetracking functionality in lua.lsp?

@catlee catlee marked this pull request as ready for review June 29, 2023 14:46
@catlee catlee force-pushed the catlee/diagnostic branch from 3dc4d67 to 959385c Compare June 29, 2023 16:27
runtime/doc/lsp.txt Outdated Show resolved Hide resolved
runtime/doc/news.txt Outdated Show resolved Hide resolved
@justinmk
Copy link
Member

Refactor common code (e.g. timer related stuff) between inlay_hints and diagnostic

I would consider this a blocker. We can't keep duplicating non-trivial caching/debounce/timer logic.

@mfussenegger
Copy link
Member

Refactor common code (e.g. timer related stuff) between inlay_hints and diagnostic

I would consider this a blocker. We can't keep duplicating non-trivial caching/debounce/timer logic.

I was thinking that we could trigger a autocmd when the client sends a didChange to the server. That's already debounced and is the moment when the server gets updated about the document state.
Ideally we'd be able to re-use LspRequest, and have pattern = lsp-method. But I think bufnr and pattern can't be specified at the same time?

runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp/diagnostic.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp/diagnostic.lua Outdated Show resolved Hide resolved
test/functional/plugin/lsp/diagnostic_spec.lua Outdated Show resolved Hide resolved
@justinmk
Copy link
Member

justinmk commented Jul 1, 2023

Ideally we'd be able to re-use LspRequest, and have pattern = lsp-method. But I think bufnr and pattern can't be specified at the same time?

Could add a v:event field.

@catlee

This comment was marked as resolved.

runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
@catlee catlee force-pushed the catlee/diagnostic branch 2 times, most recently from bdb3556 to a256b5b Compare July 4, 2023 21:58
@catlee
Copy link
Contributor Author

catlee commented Jul 5, 2023

Does this approach of using LspDidChange look good? If so, I can tackle porting inlay_hint.lua over as well.

@catlee
Copy link
Contributor Author

catlee commented Jul 5, 2023

Ideally we'd be able to re-use LspRequest, and have pattern = lsp-method. But I think bufnr and pattern can't be specified at the same time?

Could add a v:event field.

Is there a way to set something like v:event.scope from lua?

@justinmk
Copy link
Member

justinmk commented Jul 5, 2023

Does this approach of using LspDidChange look good?

Not really. Why can't LspRequest be re-used?

Is there a way to set something like v:event.scope from lua?

Not currently. But we already are attaching stuff in the data field:

data = { client_id = client_id, request_id = request_id, request = request },
, so we could add another data field instead of bothering with v:event.

@catlee
Copy link
Contributor Author

catlee commented Jul 5, 2023

Does this approach of using LspDidChange look good?

Not really. Why can't LspRequest be re-used?

Is there a way to set something like v:event.scope from lua?

Not currently. But we already are attaching stuff in the data field:

data = { client_id = client_id, request_id = request_id, request = request },

, so we could add another data field instead of bothering with v:event.

Would that mean that any autocmds created for LspRequest would have to manually filter out invocations based on e.g. data.method? They would be triggered for all completed LSP requests on the buffer, and then need to ignore any except for ones with data.method == 'didChange'. Is that ok?

@justinmk
Copy link
Member

justinmk commented Jul 5, 2023

any autocmds created for LspRequest would have to manually filter out invocations based on e.g. data.method?

That seems fine to me. LspRequest after all is a very generic (noisy/expensive) event.

Ideally the event system would allow subscribers to opt-in more granularly, but that's a bigger topic.

@mfussenegger
Copy link
Member

mfussenegger commented Jul 5, 2023

Is there a way to set something like v:event.scope from lua?

Not currently. But we already are attaching stuff in the data field:

+1 for adding the method to the data field

Would that mean that any autocmds created for LspRequest would have to manually filter out invocations based on e.g. data.method?

Also keep in mind that LspRequest is triggered multiple times for the same request (for state changes from pending to either canceled or done)

If so, I can tackle porting inlay_hint.lua over as well.

I think that can also happen in a separate PR to keep the scope of this one smaller. Helps with review and getting it merged faster.

runtime/lua/vim/lsp/diagnostic.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp/diagnostic.lua Show resolved Hide resolved
runtime/lua/vim/lsp/diagnostic.lua Outdated Show resolved Hide resolved
@catlee catlee force-pushed the catlee/diagnostic branch from 66d95a3 to f131755 Compare July 10, 2023 21:22
runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp/diagnostic.lua Show resolved Hide resolved
runtime/lua/vim/lsp/util.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp/util.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp/diagnostic.lua Show resolved Hide resolved
runtime/lua/vim/lsp/diagnostic.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp/diagnostic.lua Outdated Show resolved Hide resolved
@@ -550,6 +551,27 @@ to the callback in the "data" table. The token fields are documented in
Note: doing anything other than calling
|vim.lsp.semantic_tokens.highlight_token()| is considered experimental.

LspNotify *LspNotify*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we sort these entries alphabetically?

@catlee catlee force-pushed the catlee/diagnostic branch from e65e764 to 2d43f83 Compare July 11, 2023 21:08
runtime/lua/vim/lsp.lua Outdated Show resolved Hide resolved
runtime/lua/vim/lsp/diagnostic.lua Show resolved Hide resolved
runtime/lua/vim/lsp/inlay_hint.lua Outdated Show resolved Hide resolved
@catlee catlee force-pushed the catlee/diagnostic branch 2 times, most recently from 0df12b5 to ce3186e Compare July 17, 2023 01:33
@catlee catlee requested a review from justinmk July 17, 2023 13:39
@mfussenegger
Copy link
Member

Looks like this breaks inlay hints, (even) if not enabled:

Error executing vim.schedule lua callback: .../dev/neovim/neovim/runtime/lua/vim/lsp/inlay_hint.lua:49:
 attempt to index local 'bufstate' (a nil value)
stack traceback:
        .../dev/neovim/neovim/runtime/lua/vim/lsp/inlay_hint.lua:49: in function 'handler'
        /dev/neovim/neovim/runtime/lua/vim/lsp.lua:1518: in function ''
        vim/_editor.lua: in function <vim/_editor.lua:0>
Error executing vim.schedule lua callback: .../dev/neovim/neovim/runtime/lua/vim/lsp/inlay_hint.lua:49:
 attempt to index local 'bufstate' (a nil value)
stack traceback:
        .../dev/neovim/neovim/runtime/lua/vim/lsp/inlay_hint.lua:49: in function 'handler'
        /dev/neovim/neovim/runtime/lua/vim/lsp.lua:1518: in function ''
        vim/_editor.lua: in function <vim/_editor.lua:0>

@catlee
Copy link
Contributor Author

catlee commented Jul 17, 2023

Looks like this breaks inlay hints, (even) if not enabled

Ok, I think I fixed that up, and tested it with rust-analyzer.

The problem was that on_refresh was always calling into the new util._refresh function, whether or not the buffer had inlayHints enabled or not.

@catlee catlee force-pushed the catlee/diagnostic branch from 6d6b697 to a18dfda Compare July 18, 2023 18:50
@catlee
Copy link
Contributor Author

catlee commented Jul 19, 2023

Is there anything left to do before we can merge this in?

@mfussenegger mfussenegger merged commit 63b3408 into neovim:master Jul 20, 2023
@github-actions github-actions bot removed request for folke and justinmk July 20, 2023 07:04

local result = rpc.notify(method, params)

if result then
Copy link
Member

@justinmk justinmk Jul 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If result is falsy (i.e. rpc.notify failed?) is that reflected in the logs somehow? If not, should it be?

Copy link
Member

@mfussenegger mfussenegger Jul 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The result is false if the client stopped. In that case no notification is sent.

Other failures would point to client bugs and probably bubble up, or if the payload is wrong, hopefully get handled in a decent way on the server side - since there are no responses to notifications the client probably won't receive an error

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe client_active is a better name for this variable

Suggested change
if result then
if client_active then

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I applied that suggestion in the PR here: #24411

@towry

This comment was marked as resolved.

@catlee
Copy link
Contributor Author

catlee commented Aug 2, 2023

echasnovski/mini.nvim#429

Lately keep getting this kind issues.

This should be fixed by #24469

@neovim neovim locked as resolved and limited conversation to collaborators Aug 2, 2023
@wookayin wookayin added this to the 0.10 milestone Jan 9, 2024
mguellsegarra referenced this pull request in hrsh7th/vscode-langservers-extracted May 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants