diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt index dad3d92238..29b6db69b0 100644 --- a/runtime/doc/lua.txt +++ b/runtime/doc/lua.txt @@ -3042,6 +3042,9 @@ vim.fs.find({names}, {opts}) *vim.fs.find()* • {limit}? (`number`, default: `1`) Stop the search after finding this many matches. Use `math.huge` to place no limit on the number of matches. + • {skip}? (`fun(dir: string): boolean`) Do not traverse + matching directories. If omitted, all directories are + searched recursively. Return: ~ (`string[]`) Normalized paths |vim.fs.normalize()| of all matching diff --git a/runtime/lua/vim/fs.lua b/runtime/lua/vim/fs.lua index 2f007d97c3..904dc77054 100644 --- a/runtime/lua/vim/fs.lua +++ b/runtime/lua/vim/fs.lua @@ -202,6 +202,10 @@ end --- Use `math.huge` to place no limit on the number of matches. --- (default: `1`) --- @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. --- @@ -247,6 +251,7 @@ function M.find(names, opts) vim.validate('stop', opts.stop, 'string', true) vim.validate('type', opts.type, 'string', true) vim.validate('limit', opts.limit, 'number', true) + vim.validate('skip', opts.skip, 'function', true) if type(names) == 'string' then names = { names } @@ -336,7 +341,7 @@ function M.find(names, opts) end end - if type_ == 'directory' then + if (type_ == 'directory') and (not opts.skip or opts.skip(f) ~= false) then dirs[#dirs + 1] = f end end diff --git a/test/functional/lua/fs_spec.lua b/test/functional/lua/fs_spec.lua index 89f6ad6a0e..a17fab84cd 100644 --- a/test/functional/lua/fs_spec.lua +++ b/test/functional/lua/fs_spec.lua @@ -224,6 +224,17 @@ describe('vim.fs', function() ) 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('^(.*/)([^/]+)$') eq({ nvim_dir }, vim.fs.find(name, { path = parent, upward = true, type = 'directory' })) end)