Skip to content

Commit

Permalink
fix(lsp): prioritise workspace_folders for root directory detection
Browse files Browse the repository at this point in the history
Some LSP clients can have more than one workspace folder, which
can be added via
[`workspace/didChangeWorkspaceFolders`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_didChangeWorkspaceFolders).

This is especially useful for resource-hungry clients, like
rust-analyzer or haskell-language-server, in order to avoid spawning
multiple clients.

Using `lsp.Client.config.root_dir` as the source of truth results
in this plugin detecting the wrong project root in this scenario.

This PR fixes that, by first searching through the
`lsp.Client.workspace_folder`s,
and then falling back to the `config.root_dir` if no matching
workspace folder is found.
  • Loading branch information
mrcjkb committed May 27, 2024
1 parent 8c6bad7 commit 008fb3d
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion lua/project_nvim/project.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,27 @@ local M = {}
M.attached_lsp = false
M.last_project = nil

---@param client lsp.Client
---@param buf_name string
local function lsp_get_buf_root(client, buf_name)
-- LSP clients can have multiple workspace folders
if client.workspace_folders then
for _, workspace_folder in pairs(client.workspace_folders) do
local folder_name = vim.uri_to_fname(workspace_folder.uri)
if folder_name and vim.startswith(buf_name, folder_name) then
return folder_name
end
end
end
-- Fall back to root_dir
return client.config.root_dir
end

function M.find_lsp_root()
-- Get lsp client for current buffer
-- Returns nil or string
local buf_ft = vim.api.nvim_buf_get_option(0, "filetype")
local buf_name = vim.api.nvim_buf_get_name(0)
local clients = vim.lsp.buf_get_clients()
if next(clients) == nil then
return nil
Expand All @@ -22,7 +39,8 @@ function M.find_lsp_root()
local filetypes = client.config.filetypes
if filetypes and vim.tbl_contains(filetypes, buf_ft) then
if not vim.tbl_contains(config.options.ignore_lsp, client.name) then
return client.config.root_dir, client.name
local lsp_root = lsp_get_buf_root(client, buf_name)
return lsp_root, client.name
end
end
end
Expand Down

0 comments on commit 008fb3d

Please sign in to comment.