fix(lsp): fix multi client handling workspace_folder methods (#18839)

`buf_notify` sends the notification to all clients of a buffer, calling
that inside a loop over clients multiplies the amount of notifications.
This commit is contained in:
Mathias Fußenegger 2023-07-25 16:57:19 +02:00 committed by GitHub
parent aba3ceccb7
commit 74bd4aba57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -480,11 +480,13 @@ function M.add_workspace_folder(workspace_folder)
print(workspace_folder, ' is not a valid directory') print(workspace_folder, ' is not a valid directory')
return return
end end
local params = util.make_workspace_params( local new_workspace = {
{ { uri = vim.uri_from_fname(workspace_folder), name = workspace_folder } }, uri = vim.uri_from_fname(workspace_folder),
{} name = workspace_folder,
) }
for _, client in pairs(vim.lsp.get_clients({ bufnr = 0 })) do local params = { event = { added = { new_workspace }, removed = {} } }
local bufnr = vim.api.nvim_get_current_buf()
for _, client in pairs(vim.lsp.get_clients({ bufnr = bufnr })) do
local found = false local found = false
for _, folder in pairs(client.workspace_folders or {}) do for _, folder in pairs(client.workspace_folders or {}) do
if folder.name == workspace_folder then if folder.name == workspace_folder then
@ -494,11 +496,11 @@ function M.add_workspace_folder(workspace_folder)
end end
end end
if not found then if not found then
vim.lsp.buf_notify(0, 'workspace/didChangeWorkspaceFolders', params) client.notify('workspace/didChangeWorkspaceFolders', params)
if not client.workspace_folders then if not client.workspace_folders then
client.workspace_folders = {} client.workspace_folders = {}
end end
table.insert(client.workspace_folders, params.event.added[1]) table.insert(client.workspace_folders, new_workspace)
end end
end end
end end
@ -513,14 +515,16 @@ function M.remove_workspace_folder(workspace_folder)
if not (workspace_folder and #workspace_folder > 0) then if not (workspace_folder and #workspace_folder > 0) then
return return
end end
local params = util.make_workspace_params( local workspace = {
{}, uri = vim.uri_from_fname(workspace_folder),
{ { uri = vim.uri_from_fname(workspace_folder), name = workspace_folder } } name = workspace_folder,
) }
for _, client in pairs(vim.lsp.get_clients({ bufnr = 0 })) do local params = { event = { added = {}, removed = { workspace } } }
for idx, folder in pairs(client.workspace_folders or {}) do local bufnr = vim.api.nvim_get_current_buf()
for _, client in pairs(vim.lsp.get_clients({ bufnr = bufnr })) do
for idx, folder in pairs(client.workspace_folders) do
if folder.name == workspace_folder then if folder.name == workspace_folder then
vim.lsp.buf_notify(0, 'workspace/didChangeWorkspaceFolders', params) client.notify('workspace/didChangeWorkspaceFolders', params)
client.workspace_folders[idx] = nil client.workspace_folders[idx] = nil
return return
end end