aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/lua/vim/lsp/_watchfiles.lua7
-rw-r--r--test/functional/plugin/lsp_spec.lua84
2 files changed, 90 insertions, 1 deletions
diff --git a/runtime/lua/vim/lsp/_watchfiles.lua b/runtime/lua/vim/lsp/_watchfiles.lua
index 3a78724d79..cf2c57db1f 100644
--- a/runtime/lua/vim/lsp/_watchfiles.lua
+++ b/runtime/lua/vim/lsp/_watchfiles.lua
@@ -193,7 +193,12 @@ local to_lsp_change_type = {
function M.register(reg, ctx)
local client_id = ctx.client_id
local client = vim.lsp.get_client_by_id(client_id)
- if not client.workspace_folders then
+ if
+ -- Ill-behaved servers may not honor the client capability and try to register
+ -- anyway, so ignore requests when the user has opted out of the feature.
+ not client.config.capabilities.workspace.didChangeWatchedFiles.dynamicRegistration
+ or not client.workspace_folders
+ then
return
end
local watch_regs = {}
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index fc7b2dafb8..506bc1333b 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -3778,6 +3778,13 @@ describe('LSP', function()
name = 'watchfiles-test',
cmd = server.cmd,
root_dir = root_dir,
+ capabilities = {
+ workspace = {
+ didChangeWatchedFiles = {
+ dynamicRegistration = true,
+ },
+ },
+ },
})
local expected_messages = 2 -- initialize, initialized
@@ -3865,6 +3872,13 @@ describe('LSP', function()
name = 'watchfiles-test',
cmd = server.cmd,
root_dir = root_dir,
+ capabilities = {
+ workspace = {
+ didChangeWatchedFiles = {
+ dynamicRegistration = true,
+ },
+ },
+ },
})
local expected_messages = 2 -- initialize, initialized
@@ -3982,6 +3996,13 @@ describe('LSP', function()
name = 'watchfiles-test',
cmd = server.cmd,
root_dir = root_dir,
+ capabilities = {
+ workspace = {
+ didChangeWatchedFiles = {
+ dynamicRegistration = true,
+ },
+ },
+ },
})
local expected_messages = 2 -- initialize, initialized
@@ -4116,6 +4137,13 @@ describe('LSP', function()
name = 'watchfiles-test',
cmd = server.cmd,
root_dir = root_dir,
+ capabilities = {
+ workspace = {
+ didChangeWatchedFiles = {
+ dynamicRegistration = true,
+ },
+ },
+ },
})
local expected_messages = 2 -- initialize, initialized
@@ -4186,5 +4214,61 @@ describe('LSP', function()
},
}, result[3].params)
end)
+
+ it("ignores registrations by servers when the client doesn't advertise support", function()
+ exec_lua(create_server_definition)
+ local result = exec_lua([[
+ local server = _create_server()
+ local client_id = vim.lsp.start({
+ name = 'watchfiles-test',
+ cmd = server.cmd,
+ root_dir = 'some_dir',
+ capabilities = {
+ workspace = {
+ didChangeWatchedFiles = {
+ dynamicRegistration = false,
+ },
+ },
+ },
+ })
+
+ local watching = false
+ require('vim.lsp._watchfiles')._watchfunc = function(_, _, callback)
+ -- Since the registration is ignored, this should not execute and `watching` should stay false
+ watching = true
+ return function() end
+ end
+
+ vim.lsp.handlers['client/registerCapability'](nil, {
+ registrations = {
+ {
+ id = 'watchfiles-test-kind',
+ method = 'workspace/didChangeWatchedFiles',
+ registerOptions = {
+ watchers = {
+ {
+ globPattern = '**/*',
+ },
+ },
+ },
+ },
+ },
+ }, { client_id = client_id })
+
+ -- Ensure no errors occur when unregistering something that was never really registered.
+ vim.lsp.handlers['client/unregisterCapability'](nil, {
+ unregisterations = {
+ {
+ id = 'watchfiles-test-kind',
+ method = 'workspace/didChangeWatchedFiles',
+ },
+ },
+ }, { client_id = client_id })
+
+ return watching
+ ]])
+
+ eq(false, result)
+ end)
end)
end)