aboutsummaryrefslogtreecommitdiffstats
path: root/lua
diff options
context:
space:
mode:
authorRaphael <glepnir@neovim.pro>2023-05-07 14:14:20 +0800
committerGitHub <noreply@github.com>2023-05-07 14:14:20 +0800
commit5ba7ab746d814413c84ed98c0214c71cd28f130a (patch)
tree4c1ab4ec0497a993418e2de499f5f3a896f03bb0 /lua
parentfeat: wrap get root dir in coroutine . (#2565) (diff)
downloadnvim-lspconfig-5ba7ab746d814413c84ed98c0214c71cd28f130a.tar
nvim-lspconfig-5ba7ab746d814413c84ed98c0214c71cd28f130a.tar.gz
nvim-lspconfig-5ba7ab746d814413c84ed98c0214c71cd28f130a.tar.bz2
nvim-lspconfig-5ba7ab746d814413c84ed98c0214c71cd28f130a.tar.lz
nvim-lspconfig-5ba7ab746d814413c84ed98c0214c71cd28f130a.tar.xz
nvim-lspconfig-5ba7ab746d814413c84ed98c0214c71cd28f130a.tar.zst
nvim-lspconfig-5ba7ab746d814413c84ed98c0214c71cd28f130a.zip
fix: check root already in workspace (#2590)
* fix: check root already in workspace --------- Co-authored-by: github-actions <github-actions@github.com>
Diffstat (limited to 'lua')
-rw-r--r--lua/lspconfig/util.lua85
1 files changed, 38 insertions, 47 deletions
diff --git a/lua/lspconfig/util.lua b/lua/lspconfig/util.lua
index 5aff4f39..6a231308 100644
--- a/lua/lspconfig/util.lua
+++ b/lua/lspconfig/util.lua
@@ -227,6 +227,20 @@ M.path = (function()
}
end)()
+local function check_in_workspace(client, root_dir)
+ if not client.workspace_folders then
+ return false
+ end
+
+ for _, dir in ipairs(client.workspace_folders) do
+ if (root_dir .. '/'):sub(1, #dir.name + 1) == dir.name .. '/' then
+ return true
+ end
+ end
+
+ return false
+end
+
-- Returns a function(root_dir), which, when called with a root_dir it hasn't
-- seen before, will call make_config(root_dir) and start a new client.
function M.server_per_root_dir_manager(make_config)
@@ -264,12 +278,13 @@ function M.server_per_root_dir_manager(make_config)
end
end
- local function register_to_clients(root, id)
+ local function attach_and_cache(root, client_id)
+ lsp.buf_attach_client(bufnr, client_id)
if not clients[root] then
clients[root] = {}
end
- if not vim.tbl_contains(clients[root], id) then
- table.insert(clients[root], id)
+ if not vim.tbl_contains(clients[root], client_id) then
+ clients[root][#clients[root] + 1] = client_id
end
end
@@ -282,16 +297,12 @@ function M.server_per_root_dir_manager(make_config)
removed = {},
},
}
- for _, schema in ipairs(client.workspace_folders or {}) do
- if schema.name == root_dir then
- return
- end
- end
client.rpc.notify('workspace/didChangeWorkspaceFolders', params)
if not client.workspace_folders then
client.workspace_folders = {}
end
- table.insert(client.workspace_folders, params.event.added[1])
+ client.workspace_folders[#client.workspace_folders + 1] = params.event.added[1]
+ attach_and_cache(root_dir, client.id)
end
local function start_new_client()
@@ -331,42 +342,33 @@ function M.server_per_root_dir_manager(make_config)
new_config.root_dir = nil
new_config.workspace_folders = nil
end
- return lsp.start_client(new_config)
+ local client_id = lsp.start_client(new_config)
+ if not client_id then
+ return
+ end
+ attach_and_cache(root_dir, client_id)
end
local function attach_or_spawn(client)
+ if check_in_workspace(client, root_dir) then
+ return attach_and_cache(root_dir, client.id)
+ end
+
local supported = vim.tbl_get(client, 'server_capabilities', 'workspace', 'workspaceFolders', 'supported')
- local client_id
if supported then
- register_workspace_folders(client)
- lsp.buf_attach_client(bufnr, client.id)
- client_id = client.id
- else
- client_id = start_new_client()
- if not client_id then
- return
- end
- lsp.buf_attach_client(bufnr, client_id)
+ return register_workspace_folders(client)
end
- register_to_clients(root_dir, client_id)
+ start_new_client()
end
- -- this function used for some situation like load from session
- -- eg:
- -- session have two same filetype in two project. file A trigger Filetyp event
- -- start server. file B also trigger Filetype event. we start server is async.
- -- that mean when file A spawn new server this server maybe not initialized and
- -- don't exchanged server_capabilities so the File B need wait the server initialized
- -- if server support workspaceFolders then regisert File B root into workspaceFolders
- -- otherwise spawn a new one.
- local attach_after_client_initialized = function(client_instance)
+ local attach_after_client_initialized = function(client)
local timer = vim.loop.new_timer()
timer:start(
0,
10,
vim.schedule_wrap(function()
- if client_instance.initialized and client_instance.server_capabilities and not timer:is_closing() then
- attach_or_spawn(client_instance)
+ if client.initialized and client.server_capabilities and not timer:is_closing() then
+ attach_or_spawn(client)
timer:stop()
timer:close()
end
@@ -377,21 +379,10 @@ function M.server_per_root_dir_manager(make_config)
local client = get_client_from_cache(new_config.name)
if not client then
- local client_id = start_new_client()
- if not client_id then
- return
- end
- lsp.buf_attach_client(bufnr, client_id)
- register_to_clients(root_dir, client_id)
- return
- end
-
- if clients[root_dir] then
- lsp.buf_attach_client(bufnr, client.id)
- return
+ return start_new_client()
end
- if single_file then
+ if clients[root_dir] or single_file then
lsp.buf_attach_client(bufnr, client.id)
return
end
@@ -408,10 +399,10 @@ function M.server_per_root_dir_manager(make_config)
function manager.clients()
local res = {}
for _, client_ids in pairs(clients) do
- for _, id in pairs(client_ids) do
+ for _, id in ipairs(client_ids) do
local client = lsp.get_client_by_id(id)
if client then
- table.insert(res, client)
+ res[#res + 1] = client
end
end
end