mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
fix(lsp): check for configuration workspace folders when reusing clients
This commit is contained in:
parent
9c278af7cc
commit
c2bf09ddff
@ -872,7 +872,9 @@ start({config}, {opts}) *vim.lsp.start()*
|
|||||||
(`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean`)
|
(`fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean`)
|
||||||
Predicate used to decide if a client should be re-used.
|
Predicate used to decide if a client should be re-used.
|
||||||
Used on all running clients. The default implementation
|
Used on all running clients. The default implementation
|
||||||
re-uses a client if name and root_dir matches.
|
re-uses a client if it has the same name and if the given
|
||||||
|
workspace folders (or root_dir) are all included in the
|
||||||
|
client's workspace folders.
|
||||||
• {bufnr}? (`integer`) Buffer handle to attach to if
|
• {bufnr}? (`integer`) Buffer handle to attach to if
|
||||||
starting or re-using a client (0 for current).
|
starting or re-using a client (0 for current).
|
||||||
• {attach}? (`boolean`) Whether to attach the client to a
|
• {attach}? (`boolean`) Whether to attach the client to a
|
||||||
|
@ -114,6 +114,22 @@ function lsp._unsupported_method(method)
|
|||||||
return msg
|
return msg
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@private
|
||||||
|
---@param workspace_folders string|lsp.WorkspaceFolder[]?
|
||||||
|
---@return lsp.WorkspaceFolder[]?
|
||||||
|
function lsp._get_workspace_folders(workspace_folders)
|
||||||
|
if type(workspace_folders) == 'table' then
|
||||||
|
return workspace_folders
|
||||||
|
elseif type(workspace_folders) == 'string' then
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
uri = vim.uri_from_fname(workspace_folders),
|
||||||
|
name = workspace_folders,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local wait_result_reason = { [-1] = 'timeout', [-2] = 'interrupted', [-3] = 'error' }
|
local wait_result_reason = { [-1] = 'timeout', [-2] = 'interrupted', [-3] = 'error' }
|
||||||
|
|
||||||
local format_line_ending = {
|
local format_line_ending = {
|
||||||
@ -196,19 +212,24 @@ local function reuse_client_default(client, config)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
if config.root_dir then
|
local config_folders = lsp._get_workspace_folders(config.workspace_folders or config.root_dir)
|
||||||
local root = vim.uri_from_fname(config.root_dir)
|
or {}
|
||||||
for _, dir in ipairs(client.workspace_folders or {}) do
|
local config_folders_included = 0
|
||||||
-- note: do not need to check client.root_dir since that should be client.workspace_folders[1]
|
|
||||||
if root == dir.uri then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- TODO(lewis6991): also check config.workspace_folders
|
|
||||||
|
|
||||||
|
if not next(config_folders) then
|
||||||
return false
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, config_folder in ipairs(config_folders) do
|
||||||
|
for _, client_folder in ipairs(client.workspace_folders) do
|
||||||
|
if config_folder.uri == client_folder.uri then
|
||||||
|
config_folders_included = config_folders_included + 1
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return config_folders_included == #config_folders
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Reset defaults set by `set_defaults`.
|
--- Reset defaults set by `set_defaults`.
|
||||||
@ -311,9 +332,10 @@ end
|
|||||||
--- @inlinedoc
|
--- @inlinedoc
|
||||||
---
|
---
|
||||||
--- Predicate used to decide if a client should be re-used. Used on all
|
--- Predicate used to decide if a client should be re-used. Used on all
|
||||||
--- running clients. The default implementation re-uses a client if name and
|
--- running clients. The default implementation re-uses a client if it has the
|
||||||
--- root_dir matches.
|
--- same name and if the given workspace folders (or root_dir) are all included
|
||||||
--- @field reuse_client? (fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean)
|
--- in the client's workspace folders.
|
||||||
|
--- @field reuse_client? fun(client: vim.lsp.Client, config: vim.lsp.ClientConfig): boolean
|
||||||
---
|
---
|
||||||
--- Buffer handle to attach to if starting or re-using a client (0 for current).
|
--- Buffer handle to attach to if starting or re-using a client (0 for current).
|
||||||
--- @field bufnr? integer
|
--- @field bufnr? integer
|
||||||
|
@ -365,21 +365,6 @@ local function get_name(id, config)
|
|||||||
return tostring(id)
|
return tostring(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param workspace_folders string|lsp.WorkspaceFolder[]?
|
|
||||||
--- @return lsp.WorkspaceFolder[]?
|
|
||||||
local function get_workspace_folders(workspace_folders)
|
|
||||||
if type(workspace_folders) == 'table' then
|
|
||||||
return workspace_folders
|
|
||||||
elseif type(workspace_folders) == 'string' then
|
|
||||||
return {
|
|
||||||
{
|
|
||||||
uri = vim.uri_from_fname(workspace_folders),
|
|
||||||
name = workspace_folders,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @generic T
|
--- @generic T
|
||||||
--- @param x elem_or_list<T>?
|
--- @param x elem_or_list<T>?
|
||||||
--- @return T[]
|
--- @return T[]
|
||||||
@ -417,7 +402,7 @@ function Client.create(config)
|
|||||||
flags = config.flags or {},
|
flags = config.flags or {},
|
||||||
get_language_id = config.get_language_id or default_get_language_id,
|
get_language_id = config.get_language_id or default_get_language_id,
|
||||||
capabilities = config.capabilities or lsp.protocol.make_client_capabilities(),
|
capabilities = config.capabilities or lsp.protocol.make_client_capabilities(),
|
||||||
workspace_folders = get_workspace_folders(config.workspace_folders or config.root_dir),
|
workspace_folders = lsp._get_workspace_folders(config.workspace_folders or config.root_dir),
|
||||||
root_dir = config.root_dir,
|
root_dir = config.root_dir,
|
||||||
_before_init_cb = config.before_init,
|
_before_init_cb = config.before_init,
|
||||||
_on_init_cbs = ensure_list(config.on_init),
|
_on_init_cbs = ensure_list(config.on_init),
|
||||||
@ -1174,7 +1159,7 @@ function Client:_add_workspace_folder(dir)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local wf = assert(get_workspace_folders(dir))
|
local wf = assert(lsp._get_workspace_folders(dir))
|
||||||
|
|
||||||
self:notify(ms.workspace_didChangeWorkspaceFolders, {
|
self:notify(ms.workspace_didChangeWorkspaceFolders, {
|
||||||
event = { added = wf, removed = {} },
|
event = { added = wf, removed = {} },
|
||||||
@ -1189,7 +1174,7 @@ end
|
|||||||
--- Remove a directory to the workspace folders.
|
--- Remove a directory to the workspace folders.
|
||||||
--- @param dir string?
|
--- @param dir string?
|
||||||
function Client:_remove_workspace_folder(dir)
|
function Client:_remove_workspace_folder(dir)
|
||||||
local wf = assert(get_workspace_folders(dir))
|
local wf = assert(lsp._get_workspace_folders(dir))
|
||||||
|
|
||||||
self:notify(ms.workspace_didChangeWorkspaceFolders, {
|
self:notify(ms.workspace_didChangeWorkspaceFolders, {
|
||||||
event = { added = {}, removed = wf },
|
event = { added = {}, removed = wf },
|
||||||
|
Loading…
Reference in New Issue
Block a user