Skip to content

Commit

Permalink
fix: util.root_pattern prioritises pattern order (#2885)
Browse files Browse the repository at this point in the history
* fix: util.root_pattern prioritises pattern order

Instead of traversing the filesystem upwards once and
returning the first match of all the patterns, it traverses
the filesystem upwards once for each pattern. This means
that the order of the patterns provided matters, and the
highest priority patterns should be put first. Also updated
corresponding tests.

* docs: update util.root_pattern description
  • Loading branch information
emilioziniades authored Nov 18, 2023
1 parent a4083b0 commit 7384e71
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 10 deletions.
3 changes: 2 additions & 1 deletion doc/lspconfig.txt
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,8 @@ below returns a function that takes as its argument the current buffer path.
- `util.root_pattern`: function which takes multiple arguments, each
corresponding to a different root pattern against which the contents of the
current directory are matched using |vim.fn.glob()| while traversing up the
filesystem.
filesystem. Parent directories are traversed once per pattern, in the order
the patterns are specified.
>
root_dir = util.root_pattern('pyproject.toml', 'requirements.txt')
<
Expand Down
19 changes: 11 additions & 8 deletions lua/lspconfig/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -250,19 +250,22 @@ end

function M.root_pattern(...)
local patterns = vim.tbl_flatten { ... }
local function matcher(path)
return function(startpath)
startpath = M.strip_archive_subpath(startpath)
for _, pattern in ipairs(patterns) do
for _, p in ipairs(vim.fn.glob(M.path.join(M.path.escape_wildcards(path), pattern), true, true)) do
if M.path.exists(p) then
return path
local match = M.search_ancestors(startpath, function(path)
for _, p in ipairs(vim.fn.glob(M.path.join(M.path.escape_wildcards(path), pattern), true, true)) do
if M.path.exists(p) then
return path
end
end
end)

if match ~= nil then
return match
end
end
end
return function(startpath)
startpath = M.strip_archive_subpath(startpath)
return M.search_ancestors(startpath, matcher)
end
end

function M.find_git_ancestor(startpath)
Expand Down
2 changes: 1 addition & 1 deletion test/lspconfig_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ describe('lspconfig', function()
-- change the working directory to test directory
vim.api.nvim_command 'cd ./test/test_dir/a'
local cwd = vim.fn.getcwd()
eq(true, cwd == lspconfig.util.root_pattern { 'root_marker.txt', 'a_marker.txt' }(cwd))
eq(true, cwd == lspconfig.util.root_pattern { 'a_marker.txt', 'root_marker.txt' }(cwd))
end)

it('resolves to root_marker.txt', function()
Expand Down

0 comments on commit 7384e71

Please sign in to comment.