commit 13cf80deefe78a362c2c274201c592197922ce9e
parent 51c279916209423612b6f704533dee036a138573
Author: Tristan Knight <admin@snappeh.com>
Date: Mon, 16 Feb 2026 21:20:34 +0000
fix(lsp): map all LSP methods to server capabilities (#37910)
Diffstat:
3 files changed, 66 insertions(+), 15 deletions(-)
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua
@@ -1222,12 +1222,30 @@ protocol._provider_to_client_registration = {
-- stylua: ignore start
-- Generated by gen_lsp.lua, keep at end of file.
--- Maps method names to the required server capability
+-- A server capability equal to the method means there is no related server capability
protocol._request_name_to_server_capability = {
+ ['callHierarchy/incomingCalls'] = { 'callHierarchy/incomingCalls' },
+ ['callHierarchy/outgoingCalls'] = { 'callHierarchy/outgoingCalls' },
+ ['client/registerCapability'] = { 'client/registerCapability' },
+ ['client/unregisterCapability'] = { 'client/unregisterCapability' },
['codeAction/resolve'] = { 'codeActionProvider', 'resolveProvider' },
['codeLens/resolve'] = { 'codeLensProvider', 'resolveProvider' },
['completionItem/resolve'] = { 'completionProvider', 'resolveProvider' },
['documentLink/resolve'] = { 'documentLinkProvider', 'resolveProvider' },
+ ['$/cancelRequest'] = { '$/cancelRequest' },
+ ['$/logTrace'] = { '$/logTrace' },
+ ['$/progress'] = { '$/progress' },
+ ['$/setTrace'] = { '$/setTrace' },
+ ['exit'] = { 'exit' },
+ ['initialize'] = { 'initialize' },
+ ['initialized'] = { 'initialized' },
['inlayHint/resolve'] = { 'inlayHintProvider', 'resolveProvider' },
+ ['notebookDocument/didChange'] = { 'notebookDocument/didChange' },
+ ['notebookDocument/didClose'] = { 'notebookDocument/didClose' },
+ ['notebookDocument/didOpen'] = { 'notebookDocument/didOpen' },
+ ['notebookDocument/didSave'] = { 'notebookDocument/didSave' },
+ ['shutdown'] = { 'shutdown' },
+ ['telemetry/event'] = { 'telemetry/event' },
['textDocument/codeAction'] = { 'codeActionProvider' },
['textDocument/codeLens'] = { 'codeLensProvider' },
['textDocument/colorPresentation'] = { 'colorProvider' },
@@ -1256,6 +1274,7 @@ protocol._request_name_to_server_capability = {
['textDocument/prepareCallHierarchy'] = { 'callHierarchyProvider' },
['textDocument/prepareRename'] = { 'renameProvider', 'prepareProvider' },
['textDocument/prepareTypeHierarchy'] = { 'typeHierarchyProvider' },
+ ['textDocument/publishDiagnostics'] = { 'textDocument/publishDiagnostics' },
['textDocument/rangeFormatting'] = { 'documentRangeFormattingProvider' },
['textDocument/rangesFormatting'] = { 'documentRangeFormattingProvider', 'rangesSupport' },
['textDocument/references'] = { 'referencesProvider' },
@@ -1268,21 +1287,39 @@ protocol._request_name_to_server_capability = {
['textDocument/typeDefinition'] = { 'typeDefinitionProvider' },
['textDocument/willSave'] = { 'textDocumentSync', 'willSave' },
['textDocument/willSaveWaitUntil'] = { 'textDocumentSync', 'willSaveWaitUntil' },
+ ['typeHierarchy/subtypes'] = { 'typeHierarchy/subtypes' },
+ ['typeHierarchy/supertypes'] = { 'typeHierarchy/supertypes' },
+ ['window/logMessage'] = { 'window/logMessage' },
+ ['window/showDocument'] = { 'window/showDocument' },
+ ['window/showMessage'] = { 'window/showMessage' },
+ ['window/showMessageRequest'] = { 'window/showMessageRequest' },
+ ['window/workDoneProgress/cancel'] = { 'window/workDoneProgress/cancel' },
+ ['window/workDoneProgress/create'] = { 'window/workDoneProgress/create' },
['workspaceSymbol/resolve'] = { 'workspaceSymbolProvider', 'resolveProvider' },
+ ['workspace/applyEdit'] = { 'workspace/applyEdit' },
+ ['workspace/codeLens/refresh'] = { 'workspace/codeLens/refresh' },
+ ['workspace/configuration'] = { 'workspace/configuration' },
['workspace/diagnostic'] = { 'diagnosticProvider', 'workspaceDiagnostics' },
+ ['workspace/diagnostic/refresh'] = { 'workspace/diagnostic/refresh' },
+ ['workspace/didChangeConfiguration'] = { 'workspace/didChangeConfiguration' },
+ ['workspace/didChangeWatchedFiles'] = { 'workspace/didChangeWatchedFiles' },
['workspace/didChangeWorkspaceFolders'] = { 'workspace', 'workspaceFolders', 'changeNotifications' },
['workspace/didCreateFiles'] = { 'workspace', 'fileOperations', 'didCreate' },
['workspace/didDeleteFiles'] = { 'workspace', 'fileOperations', 'didDelete' },
['workspace/didRenameFiles'] = { 'workspace', 'fileOperations', 'didRename' },
['workspace/executeCommand'] = { 'executeCommandProvider' },
+ ['workspace/foldingRange/refresh'] = { 'workspace/foldingRange/refresh' },
+ ['workspace/inlayHint/refresh'] = { 'workspace/inlayHint/refresh' },
+ ['workspace/inlineValue/refresh'] = { 'workspace/inlineValue/refresh' },
+ ['workspace/semanticTokens/refresh'] = { 'workspace/semanticTokens/refresh' },
['workspace/symbol'] = { 'workspaceSymbolProvider' },
['workspace/textDocumentContent'] = { 'workspace', 'textDocumentContent' },
+ ['workspace/textDocumentContent/refresh'] = { 'workspace/textDocumentContent/refresh' },
['workspace/willCreateFiles'] = { 'workspace', 'fileOperations', 'willCreate' },
['workspace/willDeleteFiles'] = { 'workspace', 'fileOperations', 'willDelete' },
['workspace/willRenameFiles'] = { 'workspace', 'fileOperations', 'willRename' },
['workspace/workspaceFolders'] = { 'workspace', 'workspaceFolders' },
['textDocument/semanticTokens'] = { 'semanticTokensProvider' },
- ['workspace/didChangeWatchedFiles'] = { 'workspace/didChangeWatchedFiles' },
}
-- stylua: ignore end
diff --git a/src/gen/gen_lsp.lua b/src/gen/gen_lsp.lua
@@ -263,16 +263,15 @@ local function write_to_vim_protocol(protocol)
'-- stylua: ignore start',
'-- Generated by gen_lsp.lua, keep at end of file.',
'--- Maps method names to the required server capability',
+ '-- A server capability equal to the method means there is no related server capability',
'protocol._request_name_to_server_capability = {',
})
for _, item in ipairs(all) do
- if item.serverCapability then
- output[#output + 1] = (" ['%s'] = { %s },"):format(
- item.method,
- "'" .. item.serverCapability:gsub('%.', "', '") .. "'"
- )
- end
+ output[#output + 1] = (" ['%s'] = { %s },"):format(
+ item.method,
+ "'" .. (item.serverCapability or item.method):gsub('%.', "', '") .. "'"
+ )
end
---@type table<string, string[]>
@@ -299,13 +298,6 @@ local function write_to_vim_protocol(protocol)
)
end
- --- workspace/didChangeWatchedFiles has no server capability but we need to map it for
- --- registration
- output[#output + 1] = (" ['%s'] = { '%s' },"):format(
- 'workspace/didChangeWatchedFiles',
- 'workspace/didChangeWatchedFiles'
- )
-
output[#output + 1] = '}'
output[#output + 1] = '-- stylua: ignore end'
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
@@ -5644,6 +5644,9 @@ describe('LSP', function()
didChangeWatchedFiles = {
dynamicRegistration = true,
},
+ didChangeConfiguration = {
+ dynamicRegistration = true,
+ },
},
},
}))
@@ -5806,10 +5809,24 @@ describe('LSP', function()
}, { client_id = client_id })
check('workspace/didChangeWorkspaceFolders')
+ check('workspace/didChangeConfiguration')
+ vim.lsp.handlers['client/registerCapability'](nil, {
+ registrations = {
+ {
+ id = 'didChangeConfiguration-id',
+ method = 'workspace/didChangeConfiguration',
+ registerOptions = {
+ section = 'dummy-section',
+ },
+ },
+ },
+ }, { client_id = client_id })
+ check('workspace/didChangeConfiguration', nil, 'section')
+
return result
end)
- eq(19, #result)
+ eq(21, #result)
eq({ method = 'textDocument/formatting', supported = false }, result[1])
eq({ method = 'textDocument/formatting', supported = true, fname = tmpfile }, result[2])
eq({ method = 'textDocument/rangeFormatting', supported = true }, result[3])
@@ -5839,6 +5856,11 @@ describe('LSP', function()
eq({ method = 'codeAction/resolve', supported = true }, result[17])
eq({ method = 'workspace/didChangeWorkspaceFolders', supported = false }, result[18])
eq({ method = 'workspace/didChangeWorkspaceFolders', supported = true }, result[19])
+ eq({ method = 'workspace/didChangeConfiguration', supported = false }, result[20])
+ eq(
+ { method = 'workspace/didChangeConfiguration', supported = true, cap = { 'dummy-section' } },
+ result[21]
+ )
end)
it('identifies client dynamic registration capability', function()