diff options
author | Sean Dewar <seandewar@users.noreply.github.com> | 2023-08-04 07:10:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-04 08:10:54 +0200 |
commit | cc87dda31a5b5637ade7ddcfe5199f2df5fd47df (patch) | |
tree | b89c503ad28d59898c6b14ed1be7ba9bc6e747e7 /test/functional/plugin/lsp_spec.lua | |
parent | 3d3ec27d51e1608306c9bd78425e3138f293ae69 (diff) | |
download | rneovim-cc87dda31a5b5637ade7ddcfe5199f2df5fd47df.tar.gz rneovim-cc87dda31a5b5637ade7ddcfe5199f2df5fd47df.tar.bz2 rneovim-cc87dda31a5b5637ade7ddcfe5199f2df5fd47df.zip |
fix(lsp): do not assume client capability exists in watchfiles check (#24550)
PR #23689 assumes `client.config.capabilities.workspace.didChangeWatchedFiles`
exists when checking `dynamicRegistration`, but thats's true only if it was
passed to `vim.lsp.start{_client}`.
This caused #23806 (still an issue in v0.9.1; needs manual backport), but #23681
fixed it by defaulting `config.capabilities` to `make_client_capabilities` if
not passed to `vim.lsp.start{_client}`.
However, the bug resurfaces on HEAD if you provide a non-nil `capabilities` to
`vim.lsp.start{_client}` with missing fields (e.g: not made via
`make_client_capabilities`).
From what I see, the spec says such missing fields should be interpreted as an
absence of the capability (including those indicated by missing sub-fields):
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#clientCapabilities
Also, suggest `vim.empty_dict()` for an empty dict in
`:h vim.lsp.start_client()` (`{[vim.type_idx]=vim.types.dictionary}`
no longer works anyway, probably since the cjson switch).
Diffstat (limited to 'test/functional/plugin/lsp_spec.lua')
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 99 |
1 files changed, 60 insertions, 39 deletions
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 7e34946d95..6223c6b8d8 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -4402,58 +4402,79 @@ describe('LSP', function() 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 + exec_lua([[ + server = _create_server() 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 = '**/*', + local function check_registered(capabilities) + return exec_lua([[ + watching = false + local client_id = vim.lsp.start({ + name = 'watchfiles-test', + cmd = server.cmd, + root_dir = 'some_dir', + capabilities = ..., + }, { + reuse_client = function() return false 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 }) + + -- 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 }) + }, { client_id = client_id }) - return watching - ]]) + vim.lsp.stop_client(client_id, true) + return watching + ]], capabilities) + end - eq(false, result) + eq(true, check_registered(nil)) -- start{_client}() defaults to make_client_capabilities(). + eq(false, check_registered(vim.empty_dict())) + eq(false, check_registered({ + workspace = { + ignoreMe = true, + }, + })) + eq(false, check_registered({ + workspace = { + didChangeWatchedFiles = { + dynamicRegistration = false, + }, + }, + })) + eq(true, check_registered({ + workspace = { + didChangeWatchedFiles = { + dynamicRegistration = true, + }, + }, + })) end) end) end) |