feat(lsp): send didChangeConfiguration after init (#18847)

Most LSP servers require the notification to correctly load the
settings and for those who don't it doesn't cause any harm.

So far this is done in lspconfig, but with the addition of vim.lsp.start
it should be part of core.
This commit is contained in:
Mathias Fußenegger 2022-06-03 18:16:11 +02:00 committed by GitHub
parent 9aba204335
commit c6d747e6a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 4 deletions

View File

@ -1117,6 +1117,10 @@ function lsp.start_client(config)
end end
end end
if next(config.settings) then
client.notify('workspace/didChangeConfiguration', { settings = config.settings })
end
if config.on_init then if config.on_init then
local status, err = pcall(config.on_init, client, result) local status, err = pcall(config.on_init, client, result)
if not status then if not status then

View File

@ -116,6 +116,19 @@ function tests.basic_init()
} }
end end
function tests.basic_init_did_change_configuration()
skeleton({
on_init = function(_)
return {
capabilities = {},
}
end,
body = function()
expect_notification('workspace/didChangeConfiguration', { settings = { dummy = 1 } })
end,
})
end
function tests.check_workspace_configuration() function tests.check_workspace_configuration()
skeleton { skeleton {
on_init = function(_params) on_init = function(_params)

View File

@ -45,10 +45,10 @@ local function clear_notrace()
end end
local function fake_lsp_server_setup(test_name, timeout_ms, options) local function fake_lsp_server_setup(test_name, timeout_ms, options, settings)
exec_lua([=[ exec_lua([=[
lsp = require('vim.lsp') lsp = require('vim.lsp')
local test_name, fixture_filename, logfile, timeout, options = ... local test_name, fixture_filename, logfile, timeout, options, settings = ...
TEST_RPC_CLIENT_ID = lsp.start_client { TEST_RPC_CLIENT_ID = lsp.start_client {
cmd_env = { cmd_env = {
NVIM_LOG_FILE = logfile; NVIM_LOG_FILE = logfile;
@ -79,17 +79,18 @@ local function fake_lsp_server_setup(test_name, timeout_ms, options)
allow_incremental_sync = options.allow_incremental_sync or false; allow_incremental_sync = options.allow_incremental_sync or false;
debounce_text_changes = options.debounce_text_changes or 0; debounce_text_changes = options.debounce_text_changes or 0;
}; };
settings = settings;
on_exit = function(...) on_exit = function(...)
vim.rpcnotify(1, "exit", ...) vim.rpcnotify(1, "exit", ...)
end; end;
} }
]=], test_name, fake_lsp_code, fake_lsp_logfile, timeout_ms or 1e3, options or {}) ]=], test_name, fake_lsp_code, fake_lsp_logfile, timeout_ms or 1e3, options or {}, settings or {})
end end
local function test_rpc_server(config) local function test_rpc_server(config)
if config.test_name then if config.test_name then
clear_notrace() clear_notrace()
fake_lsp_server_setup(config.test_name, config.timeout_ms or 1e3, config.options) fake_lsp_server_setup(config.test_name, config.timeout_ms or 1e3, config.options, config.settings)
end end
local client = setmetatable({}, { local client = setmetatable({}, {
__index = function(_, name) __index = function(_, name)
@ -298,6 +299,22 @@ describe('LSP', function()
} }
end) end)
it('should send didChangeConfiguration after initialize if there are settings', function()
test_rpc_server({
test_name = 'basic_init_did_change_configuration',
on_init = function(client, _)
client.stop()
end,
on_exit = function(code, signal)
eq(0, code, 'exit code', fake_lsp_logfile)
eq(0, signal, 'exit signal', fake_lsp_logfile)
end,
settings = {
dummy = 1,
},
})
end)
it('should succeed with manual shutdown', function() it('should succeed with manual shutdown', function()
if isCI() then if isCI() then
pending('hangs the build on CI #14028, re-enable with freeze timeout #14204') pending('hangs the build on CI #14028, re-enable with freeze timeout #14204')