From a1895f024a4cc9bb4389deae2a6686a34d3329f7 Mon Sep 17 00:00:00 2001 From: Tim Pope Date: Sun, 15 Feb 2026 11:37:24 -0500 Subject: [PATCH] fix(lsp): support workspace/configuation with no section #27510 The [spec for `workspace/configuration`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_configuration) marks the `section` property of each item in `items` optional. Therefore, I believe it violates the spec to skip over items without a section, because then the length of the results won't match the length of a valid `items` input. The spec does not elaborate on _what_ to return in this case, but I don't think it would be controversial to say that returning the full configuration, as done for an empty string, is the most natural interpretation. That empty string case, by the way, was initially [added in response](https://github.com/neovim/nvim-lspconfig/commit/5da124fc82c24592abc3a97c68363bb4e85e3c85) to a real world implementation requesting it. I don't have a similar real world implementation to point to for the omitted `section`, but I would note that `getConfiguration()` from `vscode-languageserver-node` [defaults to a request with no section](https://github.com/Microsoft/vscode-languageserver-node/blob/d859bb14d1bcb3923eecaf0ef587e55c48502ccc/server/src/common/configuration.ts#L24-L26) when called with no arguments. I surmise that this is intended as a way to retrieve the full configuration. --- runtime/lua/vim/lsp/handlers.lua | 3 +++ test/functional/fixtures/fake-lsp-server.lua | 9 ++++++++- test/functional/plugin/lsp_spec.lua | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 1f6f22cfc8..25570aa92f 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -230,6 +230,9 @@ RSC['workspace/configuration'] = function(_, params, ctx) value = vim.NIL end table.insert(response, value) + else + -- If no section is provided, return settings as is + table.insert(response, client.settings) end end return response diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua index 360d115586..6962d9b3ed 100644 --- a/test/functional/fixtures/fake-lsp-server.lua +++ b/test/functional/fixtures/fake-lsp-server.lua @@ -150,9 +150,16 @@ function tests.check_workspace_configuration() { section = 'testSetting2' }, { section = 'test.Setting3' }, { section = 'test.Setting4' }, + {}, + { section = '' }, }, }) - expect_notification('workspace/configuration', { true, false, 'nested', vim.NIL }) + local all = { + testSetting1 = true, + testSetting2 = false, + test = { Setting3 = 'nested' }, + } + expect_notification('workspace/configuration', { true, false, 'nested', vim.NIL, all, all }) notify('shutdown') end, } diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 891aed0028..7abad1757f 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -681,6 +681,8 @@ describe('LSP', function() { section = 'testSetting2' }, { section = 'test.Setting3' }, { section = 'test.Setting4' }, + {}, + { section = '' }, }, }, { method = 'workspace/configuration', client_id = 1 },