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
LSP: user can easily discover, define client commands #28329
Comments
I think there's a bit of a misunderstanding here. LSP defines two types of commands:
Some of the client commands could become part of the specification. But for some of them there are issues with no clear path forward (E.g. microsoft/language-server-protocol#1641) Other than that, I don't see what else neovim core could do. Other than delegating more of the work to language specific plugins. |
Yes, I'm just feeling around here. I updated the title + description.
✅ Those are discovered and presented via "code actions" menu, correct? So that's already covered.
Using Are these goals tractable:
ExampleCode required to add custom rust-analyzer commands: Beforecodelocal function reload_workspace(bufnr)
bufnr = util.validate_bufnr(bufnr)
local clients = vim.lsp.get_active_clients { name = 'rust_analyzer', bufnr = bufnr }
for _, client in ipairs(clients) do
vim.notify 'Reloading Cargo Workspace'
client.request('rust-analyzer/reloadWorkspace', nil, function(err)
if err then
error(tostring(err))
end
vim.notify 'Cargo workspace reloaded'
end, 0)
end
end
local function open_docs(bufnr)
bufnr = util.validate_bufnr(bufnr)
vim.lsp.buf_request(bufnr, 'experimental/externalDocs', vim.lsp.util.make_position_params(), function(err, url)
if err then
error(tostring(err))
else
vim.fn['netrw#BrowseX'](url, 0)
end
end)
end
vim.lsp.start{
...,
commands = {
CargoReload = {
function()
reload_workspace(0)
end,
description = 'Reload current cargo workspace',
},
RustOpenDocs = {
function()
open_docs(0)
end,
description = 'Open documentation for the symbol under the cursor in default browser',
},
},
} AfterAssuming we provide a util function like:
The code would now look like: TODO |
This comment was marked as resolved.
This comment was marked as resolved.
We could document some examples, but I don't think you can reduce the amount of boilerplate by 2x.
This isn't a client command. It's just a extra LSP method. There is no discovery mechanism for these. Just the documentation of the language server - or in many cases not even that, but reverse engineering of vscode extensions. The main problems here are:
This is all specific to the method. And the Client commands on the other hand can be used instead of server commands, and are part of some other operations like code-actions. The difference to server commands is that they usually have more round-trips. For example nvim-jdtls defines a
This is all completely custom Also note that what lspconfig does (or did?) with |
@asmodeus812 but how are those commands discovered? Where is that info coming from?
That isn't part of the "capabilities" response? It's strange that servers can't list their custom methods.
Understood. But even just listing the names, and point to the upstream docs, would be very helpful, and avoids support requests. Some UX tweaks may be enough. nvim-lspconfig has a CI job that pulls package.json files to get various bits of info. But custom methods aren't declared in package.json files, they are just loosely documented as you mentioned. |
@justinmk they are registered through/using the coc-lsp client's api, by each extension, i think that was obvious from my reply. This is also what vs code does, the commands are registered by the extension, but the api to interact/add/register/use those commands is provided by the vs code lsp client as a library itself. |
We're not VS Code, though, on purpose; neither do we plan on replacing coc.nvim. We implement the LSP specification and nothing but the specification. Anything beyond that is intentionally left for server-specific plugins (which correspond to VS Code extensions) built on top of the base LSP API (as well as other methods that compose nicely, which this may or may not be relevant to). |
@clason in that case if nvim only adheres to the spec and only the spec then this issue can be closed as resolved / not planned. |
Not quite; the last part about "other methods that compose nicely" may still be actionable here. (We do want to add general API methods that makes it easier to write such custom plugins -- given a positive, individual, cost-benefit analysis, of course.) |
No, the capabilities only contain the capabilities defined in the specification and there is also no OpenAPI style dynamic introspection of methods. We could suggest to add that, but even if it were added, due to the BWC nature of the protocol, it would remain optional.
We could add a
|
Problem
LSP servers have various custom capabilities and commands that are not part of the LSP spec, e.g.:
The current situation with nvim-lspconfig is that 10+ lines of code are needed to define each command or custom capability. That's unsustainable, we can't maintain that for 100s of LSP servers.
See also:
Expected behavior
Reduce friction for users to use custom (off-spec) server capabilities/commands:
server capabilitiescustom (off-spec) commands.commands
interface and/or provide util functions so that defining commands/aliases to call custom (off-spec) server commands requires 2x less code.Questions
vim.lsp.get_active_clients()[1].server_capabilities
andvim.lsp.get_active_clients()[1].commands
already exist. What is the remaining friction? Why do we get requests like this? Do we simply need some hints in the documentation that guide users? Do we need a util function that makes it easy for users to define mappings around server commands/capabilities?Possible interface
From neovim/nvim-lspconfig#1937 (comment) (the names don't matter right now, they are just pseudo-code; the point is that we need a generic interface for (1) iterating custom shit from the LSP server and (2) enabling users to create their own mappings to this stuff):
The text was updated successfully, but these errors were encountered: