feat(vim.fs): dir(), find() error-reporting

Problem:
vim.fs.dir() and vim.fs.find() drop errors returned by uv.fs_scandir().

Solution:
- vim.fs.dir():
  - Return root scan failures as a secondary return value.
  - Propagate recursive scan failures through the iterator. This allows
    callers to distinguish unreadable directories from empty ones.

- vim.fs.find(): Collect errors during search, and return the list as
  a second retval.
This commit is contained in:
Rudrajeet Pal
2026-06-04 16:33:03 +05:30
committed by Justin M. Keyes
parent 0d81f257af
commit 4e04dff228
4 changed files with 276 additions and 30 deletions

View File

@@ -2596,6 +2596,20 @@ vim.fs.dir({path}, {opts}) *vim.fs.dir()*
Gets an iterator over items found in `path` (normalized via
|vim.fs.normalize()|).
Example: >lua
local it, err = vim.fs.dir(path)
if err then
-- Failed to scan the root directory
end
for name, type, err in it do
if err then
-- Failed to scan a child directory
end
end
<
Attributes: ~
Since: 0.8.0
@@ -2611,11 +2625,14 @@ vim.fs.dir({path}, {opts}) *vim.fs.dir()*
current directory. Only useful when depth > 1 Return an
iterator over the items located in {path}
Return: ~
Return (multiple): ~
(`Iterator`) over items in {path}. Each iteration yields two values:
"name" and "type". "name" is the basename of the item relative to
{path}. "type" is one of the following: "file", "directory", "link",
"fifo", "socket", "char", "block", "unknown".
"name" and "type", along with an optional value "err" "name" is the
basename of the item relative to {path}. "type" is one of the
following: "file", "directory", "link", "fifo", "socket", "char",
"block", "unknown". "err" is a string with the format {errname}:
{message}
(`string?`) err Error encountered while scanning the base directory
vim.fs.dirname({file}) *vim.fs.dirname()*
Gets the parent directory of the given path (not expanded/resolved, the
@@ -2708,9 +2725,12 @@ vim.fs.find({names}, {opts}) *vim.fs.find()*
through parent directories. Otherwise, search child
directories (recursively).
Return: ~
(`string[]`) Normalized paths |vim.fs.normalize()| of all matching
items
Return (multiple): ~
(`string[]`) matches Normalized paths |vim.fs.normalize()| of all
matching items
(`table[]`) errors list of errors encountered during the search
• {err} (`string`) Error message
• {path} (`string`) Path at which error was encountered
vim.fs.joinpath({...}) *vim.fs.joinpath()*
Concatenates partial paths (one absolute or relative path followed by zero

View File

@@ -253,6 +253,9 @@ LUA
• |vim.net.request()| can now accept `method` param overload for multiple HTTP methods.
• |writefile()| treats Lua strings as "blob", so it can be used to write
binary data.
• |vim.fs.dir()| and |vim.fs.find()| report errors encountered while
scanning directories that cannot be read (e.g. due to permissions),
instead of treating them as empty.
• |vim.filetype.inspect()| returns a copy of the internal tables used for
filetype detection.
• Added `__eq` metamethod to |vim.VersionRange|. 2 distinct but representing