feat: add skip predicate to vim.fs.find

Add `skip` predicate controls directory traversal.
This commit is contained in:
Mike 2024-12-11 15:34:16 +01:00
parent 442d338cb5
commit d952c976ba
No known key found for this signature in database
GPG Key ID: B27ADEA45243EBEE
3 changed files with 20 additions and 1 deletions

View File

@ -3042,6 +3042,9 @@ vim.fs.find({names}, {opts}) *vim.fs.find()*
• {limit}? (`number`, default: `1`) Stop the search after • {limit}? (`number`, default: `1`) Stop the search after
finding this many matches. Use `math.huge` to place no finding this many matches. Use `math.huge` to place no
limit on the number of matches. limit on the number of matches.
• {skip}? (`fun(dir: string): boolean`) Do not traverse
matching directories. If omitted, all directories are
searched recursively.
Return: ~ Return: ~
(`string[]`) Normalized paths |vim.fs.normalize()| of all matching (`string[]`) Normalized paths |vim.fs.normalize()| of all matching

View File

@ -202,6 +202,10 @@ end
--- Use `math.huge` to place no limit on the number of matches. --- Use `math.huge` to place no limit on the number of matches.
--- (default: `1`) --- (default: `1`)
--- @field limit? number --- @field limit? number
---
--- Do not traverse matching directories.
--- If omitted, all directories are searched recursively.
--- @field skip? (fun(dir: string): boolean)
--- Find files or directories (or other items as specified by `opts.type`) in the given path. --- Find files or directories (or other items as specified by `opts.type`) in the given path.
--- ---
@ -247,6 +251,7 @@ function M.find(names, opts)
vim.validate('stop', opts.stop, 'string', true) vim.validate('stop', opts.stop, 'string', true)
vim.validate('type', opts.type, 'string', true) vim.validate('type', opts.type, 'string', true)
vim.validate('limit', opts.limit, 'number', true) vim.validate('limit', opts.limit, 'number', true)
vim.validate('skip', opts.skip, 'function', true)
if type(names) == 'string' then if type(names) == 'string' then
names = { names } names = { names }
@ -336,7 +341,7 @@ function M.find(names, opts)
end end
end end
if type_ == 'directory' then if (type_ == 'directory') and (not opts.skip or opts.skip(f) ~= false) then
dirs[#dirs + 1] = f dirs[#dirs + 1] = f
end end
end end

View File

@ -224,6 +224,17 @@ describe('vim.fs', function()
) )
eq({ nvim_prog }, vim.fs.find(nvim_prog_basename, { path = test_build_dir, type = 'file' })) eq({ nvim_prog }, vim.fs.find(nvim_prog_basename, { path = test_build_dir, type = 'file' }))
eq(
{},
vim.fs.find(nvim_prog_basename, {
path = vim.fs.dirname(test_build_dir),
type = 'file',
skip = function(dir)
return not (vim.fs.basename(dir):match('^build'))
end,
})
)
local parent, name = nvim_dir:match('^(.*/)([^/]+)$') local parent, name = nvim_dir:match('^(.*/)([^/]+)$')
eq({ nvim_dir }, vim.fs.find(name, { path = parent, upward = true, type = 'directory' })) eq({ nvim_dir }, vim.fs.find(name, { path = parent, upward = true, type = 'directory' }))
end) end)