mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 03:05:11 -07:00
fix(lsp): don't register didChangeWatchedFiles when capability not set (#23689)
Some LSP servers (tailwindcss, rome) are known to request registration for `workspace/didChangeWatchedFiles` even when the corresponding client capability does not advertise support. This change adds an extra check in the `client/registerCapability` handler not to start a watch unless the client capability is set appropriately.
This commit is contained in:
parent
413d57ae71
commit
073035a030
@ -193,7 +193,12 @@ local to_lsp_change_type = {
|
|||||||
function M.register(reg, ctx)
|
function M.register(reg, ctx)
|
||||||
local client_id = ctx.client_id
|
local client_id = ctx.client_id
|
||||||
local client = vim.lsp.get_client_by_id(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
|
return
|
||||||
end
|
end
|
||||||
local watch_regs = {}
|
local watch_regs = {}
|
||||||
|
@ -3778,6 +3778,13 @@ describe('LSP', function()
|
|||||||
name = 'watchfiles-test',
|
name = 'watchfiles-test',
|
||||||
cmd = server.cmd,
|
cmd = server.cmd,
|
||||||
root_dir = root_dir,
|
root_dir = root_dir,
|
||||||
|
capabilities = {
|
||||||
|
workspace = {
|
||||||
|
didChangeWatchedFiles = {
|
||||||
|
dynamicRegistration = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
local expected_messages = 2 -- initialize, initialized
|
local expected_messages = 2 -- initialize, initialized
|
||||||
@ -3865,6 +3872,13 @@ describe('LSP', function()
|
|||||||
name = 'watchfiles-test',
|
name = 'watchfiles-test',
|
||||||
cmd = server.cmd,
|
cmd = server.cmd,
|
||||||
root_dir = root_dir,
|
root_dir = root_dir,
|
||||||
|
capabilities = {
|
||||||
|
workspace = {
|
||||||
|
didChangeWatchedFiles = {
|
||||||
|
dynamicRegistration = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
local expected_messages = 2 -- initialize, initialized
|
local expected_messages = 2 -- initialize, initialized
|
||||||
@ -3982,6 +3996,13 @@ describe('LSP', function()
|
|||||||
name = 'watchfiles-test',
|
name = 'watchfiles-test',
|
||||||
cmd = server.cmd,
|
cmd = server.cmd,
|
||||||
root_dir = root_dir,
|
root_dir = root_dir,
|
||||||
|
capabilities = {
|
||||||
|
workspace = {
|
||||||
|
didChangeWatchedFiles = {
|
||||||
|
dynamicRegistration = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
local expected_messages = 2 -- initialize, initialized
|
local expected_messages = 2 -- initialize, initialized
|
||||||
@ -4116,6 +4137,13 @@ describe('LSP', function()
|
|||||||
name = 'watchfiles-test',
|
name = 'watchfiles-test',
|
||||||
cmd = server.cmd,
|
cmd = server.cmd,
|
||||||
root_dir = root_dir,
|
root_dir = root_dir,
|
||||||
|
capabilities = {
|
||||||
|
workspace = {
|
||||||
|
didChangeWatchedFiles = {
|
||||||
|
dynamicRegistration = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
local expected_messages = 2 -- initialize, initialized
|
local expected_messages = 2 -- initialize, initialized
|
||||||
@ -4186,5 +4214,61 @@ describe('LSP', function()
|
|||||||
},
|
},
|
||||||
}, result[3].params)
|
}, result[3].params)
|
||||||
end)
|
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)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user