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

Respect vim.lsp.commands, client.commands, and server capabilities when executing CompletionItem.command #73

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

rjooske
Copy link

@rjooske rjooske commented Oct 16, 2024

Currently, when cmp-nvim-lsp receives a CompletionItem with a Command, it executes the command by directly making a workspace/executeCommand request.
This behavior fails to respect the user-defined command handlers in vim.lsp.commands and client.commands, as well as whether the language server is capable of handling the command.
This PR addresses this issue by using the client:_exec_cmd() method, which does respect vim.lsp.commands, client.commands, and server capabilities.

I am aware that client:_exec_cmd() is probably meant to be a private method and that relying on it might become a problem in the future.
However, I'm not sure if copying the whole method over to this plugin would be any better, and a quick search reveals that there are some plugins that do rely on client:_exec_cmd().
Please let me know if you have a better idea.

@rjooske
Copy link
Author

rjooske commented Oct 16, 2024

I just noticed that cmp behaves weird in certain situations with this change applied. I'll keep this PR as a draft until I figure out why.

@rjooske rjooske marked this pull request as draft October 16, 2024 15:31
@rjooske
Copy link
Author

rjooske commented Oct 17, 2024

Turns out that I actually had to copy and paste the logic inside the client:_exec_cmd() since there was no way to tell if the command was handled by a user-defined handler or the language server, making it not possible to call the callback argument correctly.
The weird behavior I mentioned was because callback was not being called correctly and is fixed now.

@rjooske rjooske marked this pull request as ready for review October 17, 2024 08:07
@rjooske
Copy link
Author

rjooske commented Oct 17, 2024

I think it's also worth talking about how I got here for the future googlers.

The first symptom of this bug that this PR fixes was rust-analyzer flooding the LSP log file with this error message:

[ERROR][2024-10-11 02:08:36] .../vim/lsp/rpc.lua:770	"rpc"	"/Users/rjooske/.cargo/bin/rust-analyzer"	"stderr"	'2024-10-10T17:08:36.571952Z ERROR rust_analyzer::dispatch: unknown request: Request { id: RequestId(I32(16)), method: "workspace/executeCommand", params: Object {"command": String("rust-analyzer.triggerParameterHints"), "title": String("triggerParameterHints")} }\n'

(and the manually formatted version for legibility:)

rust_analyzer::dispatch: unknown request: Request {
    id: RequestId(I32(16)),
    method: "workspace/executeCommand",
    params: Object {
        "command": String("rust-analyzer.triggerParameterHints"),
        "title": String("triggerParameterHints")
    }
}

I found out that the rust-analyzer.triggerParameterHints command in CompletionItem.commands was being sent to rust-analyzer as workspace/executeCommand requests, which rust-analyzer was rejecting since it doesn't have such a command.
Trying to fix this, I tried to handle the commands by using vim.lsp.commands and client.commands as documented here, but nothing I did worked and the commands were still being sent to rust-analyzer.
Eventually I found out that it was cmp-nvim-lsp that failed to account for vim.lsp.commands and client.commands, as well as the server capabilities.

Also, after this PR is applied, you'll probably see this warning when accepting a completion item from rust-analyzer (assuming you don't have the config discussed below), which I'm guessing will be googled in the future.

cmp_nvim_lsp: Language server `rust_analyzer` does not support command `rust-analyzer.triggerParameterHints`. This command may require a client extension.

This is because the commands from completion items are now being handled properly and by default there's no handlers on the client (neovim) side for the rust-analyzer.triggerParameterHints command.
You can put this in your config to show the parameter hints in neovim after accepting a completion item, which is the intended behavior of rust-analyzer's clients, and to make the warning go away.

vim.lsp.commands["rust-analyzer.triggerParameterHints"] = function()
  vim.lsp.buf.signature_help()
end

Alternatively, you can just do nothing and only get rid of the warning if you find the parameter hints annoying.

vim.lsp.commands["rust-analyzer.triggerParameterHints"] = function() end

If you don't want to modify the global command handlers, you can also put the handler in client.commands (documented here), which has a higher precedence.

@hrsh7th
Copy link
Owner

hrsh7th commented Dec 10, 2024

I understand your PR, but I'm not sure if the language server is returning server_capabilities.executeCommandProvider properly.

If the language server sends a supported command without returning server_capabilities.executeCommandProvider, won't this process cause an error?

@hrsh7th
Copy link
Owner

hrsh7th commented Dec 10, 2024

IMO, we should check client command first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants