neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit d75ffa59344b9cefc8d1e29b2b0110dee6d81775
parent a5f236291c0c64d02f1977ee790f741e88850dfb
Author: Maria José Solano <majosolano99@gmail.com>
Date:   Mon,  9 Jun 2025 10:01:26 -0700

feat(lsp): static registration support (#34371)


Diffstat:
Mruntime/lua/vim/lsp/client.lua | 44++++++++++++++++++++++++++++++++++++++++++++
Mtest/functional/plugin/lsp_spec.lua | 22++++++++++++++++++++++
2 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua @@ -554,6 +554,8 @@ function Client:initialize() assert(result.capabilities, "initialize result doesn't contain capabilities") self.server_capabilities = assert(lsp.protocol.resolve_capabilities(self.server_capabilities)) + self:_process_static_registrations() + if self.server_capabilities.positionEncoding then self.offset_encoding = self.server_capabilities.positionEncoding end @@ -585,6 +587,48 @@ function Client:initialize() end) end +-- Server capabilities for methods that support static registration. +local static_registration_capabilities = { + [ms.textDocument_prepareCallHierarchy] = 'callHierarchyProvider', + [ms.textDocument_documentColor] = 'colorProvider', + [ms.textDocument_declaration] = 'declarationProvider', + [ms.textDocument_diagnostic] = 'diagnosticProvider', + [ms.textDocument_foldingRange] = 'foldingRangeProvider', + [ms.textDocument_implementation] = 'implementationProvider', + [ms.textDocument_inlayHint] = 'inlayHintProvider', + [ms.textDocument_inlineValue] = 'inlineValueProvider', + [ms.textDocument_linkedEditingRange] = 'linkedEditingRangeProvider', + [ms.textDocument_moniker] = 'monikerProvider', + [ms.textDocument_selectionRange] = 'selectionRangeProvider', + [ms.textDocument_semanticTokens_full] = 'semanticTokensProvider', + [ms.textDocument_typeDefinition] = 'typeDefinitionProvider', + [ms.textDocument_prepareTypeHierarchy] = 'typeHierarchyProvider', +} + +--- @private +function Client:_process_static_registrations() + local static_registrations = {} ---@type lsp.Registration[] + + for method, capability in pairs(static_registration_capabilities) do + if + vim.tbl_get(self.server_capabilities, capability, 'id') + and self:_supports_registration(method) + then + static_registrations[#static_registrations + 1] = { + id = self.server_capabilities[capability].id, + method = method, + registerOptions = { + documentSelector = self.server_capabilities[capability].documentSelector, ---@type lsp.DocumentSelector? + }, + } + end + end + + if next(static_registrations) then + self:_register_dynamic(static_registrations) + end +end + --- @private --- Returns the handler associated with an LSP method. --- Returns the default handler if the user hasn't set a custom one. diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua @@ -5727,6 +5727,28 @@ describe('LSP', function() eq({ method = 'textDocument/rangeFormatting', supported = true, fname = tmpfile }, result[4]) eq({ method = 'textDocument/completion', supported = false }, result[5]) end) + + it('supports static registration', function() + exec_lua(create_server_definition) + + local client_id = exec_lua(function() + local server = _G._create_server({ + capabilities = { + colorProvider = { id = 'color-registration' }, + }, + }) + + return assert(vim.lsp.start({ name = 'dynamic-test', cmd = server.cmd })) + end) + + eq( + true, + exec_lua(function() + local client = assert(vim.lsp.get_client_by_id(client_id)) + return client.dynamic_capabilities:get('textDocument/documentColor') ~= nil + end) + ) + end) end) describe('vim.lsp._watchfiles', function()