aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/fs.lua
Commit message (Collapse)AuthorAge
* fix(vim.fs): find{follow=true} skips symlink targets of the given `type` #42246Justin M. Keyes2026-10-05
| | | | | | | | | Problem: `vim.fs.find()` checks `type` against the symlink itself, so `{ type='file', follow=true }` skips symlinked files (e.g. `:helptags`). Solution: With `follow=true`, a symlink has the type of its target. Thus `type='link'` only matches broken symlinks (like `find -L -type l`).
* fix(lua): enable param-type-mismatch diagnosticLewis Russell2026-09-28
| | | | | | | | | Problem: Argument type mismatches are excluded from EmmyLua checks. Solution: Correct runtime annotations and calls, document local checker workarounds, and enable the diagnostic. AI-assisted
* fix(lua): enable unnecessary-assert diagnosticLewis Russell2026-09-28
| | | | AI-assisted
* fix(lua): enable assignment type checking in runtime codeLewis Russell2026-09-25
| | | | | | | | | | | Enable EmmyLua's assign-type-mismatch diagnostic after correcting the runtime annotations and assignments it flags. Correct option, tuple, and return types, and use separate locals when a value changes representation. Add guards and narrow casts where needed so the runtime passes the stricter check. Regenerate the affected docs. AI-assisted
* fix(lua): add missing param annotations (#41911)Lewis Russell2026-09-15
|
* fix(fs): honor the starting directory as an upward search stop #41886Volodymyr Chernetskyi2026-09-15
| | | | | | | | | | | | Problem: An upward find() searches its initial directory before checking stop, so path=stop can return a match or continue above the stop directory. Downward search already stops before searching when path equals stop. Solution: Check the starting path before searching upward, matching the existing downward search behavior. AI-assisted
* refactor(help): reuse help.lua to generate build tagsLewis Russell2026-09-10
| | | | | | | | | | Make gen_helptags.lua call help.lua instead of keeping its own tag parser. Builds and :helptags now use the same code. Allow the shared code to run without Neovim, and fail the build when tag generation reports an error. AI-assisted
* perf(fs): defer path joining in find()Lewis Russell2026-09-10
| | | | | | | | Only join paths for matches and entries needed for traversal. This avoids string processing for rejected files and improves selective searches across the Neovim tree by about 19-25%. AI-assisted
* build: enable more EmmyLua checksLewis Russell2026-09-09
| | | | | | | | | | Enable checks for unused code, deprecated calls, return types, and annotations. Fix the warnings and replace the deprecated highlight function. Keep exceptions where old APIs are still needed or the checker gets it wrong. AI-assisted
* build: replace LuaLS with EmmyLuaLewis Russell2026-09-07
| | | | | | | | | | | | | | | Problem: LuaLS struggles with the generics used in Nvim's runtime, requiring broad diagnostic suppressions. Indexing is also slow. Solution: Use EmmyLua for type checks in the build and CI. It offers more sophisticated type checking, substantially better support for generics, and much better flow analysis. Correct the affected annotations. Use `@internal`, supported directly by EmmyLua, instead of `@nodoc` for shared internal declarations, and support it in the help parser. AI-assisted
* feat(vim.fs): slug() supports URI #41241Willaaaaaaa2026-08-16
| | | | | | | | | | Problem: `vim.fs.slug()` does not handle URIs like `term://foo//123:bash`, so callers (e.g. terminal persistence) must strip the scheme before calling `slug()`. Solution: Detect `scheme://` from the raw input before `normalize()` and replace it with a `=uri-<scheme>-` prefix.
* refactor(vim.fs): slug() minor cleanupJustin M. Keyes2026-08-06
|
* docs: misc, :bcd, slug()Justin M. Keyes2026-08-06
|
* feat(fs): vim.fs.normalize{plain:boolean} #41127Olivia Kinnear2026-08-05
| | | | | | `opts.plain=true` does not expand tildes in addition to environment variables, unlike `opts.expand_env=false`. `opts.expand_env=false` is soft-deprecated.
* feat(lua): vim.fs.slug() #41005Willaaaaaaa2026-08-04
| | | | | | | | | | | | | | | | Problem: Several subsystems need to derive a short, filesystem-safe identifier from an arbitrary path, and each reinvents it ad-hoc: - `'undodir'` and `swapfiles` encode the full path into a single filename, which may exceed filesystem length-limits. - `:connect ssh://` needs the SSH ControlPath socket name to stay under the 104-byte `sun_path` limit on macOS; today the path overflows it. - the upcoming :terminal state dir. - arbitrary plugin purposes. Solution: Provide `vim.fs.slug()`, which generates a bounded, one-way filename from an arbitrary string. The input is normalized so equivalent paths produce the same result. An 8-char hash is appended for uniqueness
* docs: func/expr options, misc #41102Justin M. Keyes2026-08-01
|
* feat(vim.fs): abspath({cwd, plain}) #40597AlexCodesApps2026-08-01
| | | | | Adds optional parameters to `vim.fs.abspath`: 1. `cwd` to specify directory akin to `--relative-from` in `realpath(1)`. 2. `plain` disables expansion of tilde (~) in paths.
* docs: misc #41063Justin M. Keyes2026-07-30
|
* feat(vim.fs): dir(opts.normalize)Barrett Ruth2026-07-25
|
* feat(vim.fs): vim.fs.mkdir() #40599Barrett Ruth2026-07-08
| | | | | | | | | Problem: `vim.fs` does not provide a directory creation helper matching its filesystem API shape. Solution: Add `vim.fs.mkdir()` as a thin wrapper around `vim.fn.mkdir()`, with `parents` and `mode` options.
* feat(vim.fs): dir() ergonomicsJustin M. Keyes2026-07-01
|
* fix(vim.fs): dir(), find() error-reportingJustin M. Keyes2026-07-01
|
* feat(vim.fs): dir(), find() error-reportingRudrajeet Pal2026-07-01
| | | | | | | | | | | | | | 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.
* refactor: cleanup, docs #40480Justin M. Keyes2026-06-29
|
* fix(vim.fs): fs.dir() may return nil "type" on some filesystems #39749abdulahmoda2026-05-29
| | | | | | | | | | | | | | Problem: Currently, only some filesystems (Btrfs, ext2, ext3, ext4) have full support of accessing the `dirent` entry-type. On other filesystems, `uv.fs_scandir_next` may return `nil` for an existing but unsupported entry-type. This means consumers (such as `fs.dir()`), cannot know if `nil` means "non-existent" or "unsupported". Solution: Fall back to `uv.fs_lstat` when `etype` is `nil`; return "unknown" if it fails.
* refactor(vim.fs): deduplicate by using vim.fn #39782Justin M. Keyes2026-05-14
| | | | | | | | | | | | | | Problem: 61e99217e684 replaced usages of `vim.fn`. This duplicates non-trivial logic and may have introduced bugs like 38e38d1b401e. Later on, b02eeb6a7281 graduated `fnamemodify` to `fast`, so avoiding it in `vim.fs` is no longer necessary. Solution: Use `vim.fn` to deduplicate `vim.fs.dirname()` and `vim.fs.basename()`. Note: the "nvim -l" test-runner switch from the original PR (#30483) is already done by 9432e6c1e2e9 (#39676).
* docs: misc #39256Justin M. Keyes2026-04-25
|
* docs: misc #39045Justin M. Keyes2026-04-18
|
* docs: news #38464Justin M. Keyes2026-03-28
|
* feat(stdlib): vim.fs.ext() returns file extension #36997Yochem van Rosmalen2026-03-20
| | | | | | | | | | | | | | | | | Problem: Checking the extension of a file is done often, e.g. in Nvim's codebase for differentiating Lua and Vimscript files in the runtime. The current way to do this in Lua is (1) a Lua pattern match, which has pitfalls such as not considering filenames starting with a dot, or (2) fnamemodify() which is both hard to discover and hard to use / read if not very familiar with the possible modifiers. vim.fs.ext() returns the file extension including the leading dot of the extension. Similar to the "file extension" implementation of many other stdlibs (including fnamemodify(file, ":e")), a leading dot doesn't indicate the start of the extension. E.g.: the .git folder in a repository doesn't have the extension .git, but it simply has no extension, similar to a folder named git or any other filename without dot(s).
* refactor: integer functions, optimize asserts #34112Lewis Russell2026-03-12
| | | | | | | | | | | | refactor(lua): add integer coercion helpers Add vim._tointeger() and vim._ensure_integer(), including optional base support, and switch integer-only tonumber()/assert call sites in the Lua runtime to use them. This also cleans up related integer parsing in LSP, health, loader, URI, tohtml, and Treesitter code. supported by AI
* fix(vim.fs): joinpath() should ignore empty items #38077Yochem van Rosmalen2026-02-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: vim.fs.joinpath treats empty string as a path segment (it adds a path separator for each empty item): print(vim.fs.joinpath('', 'after/lsp', '')) -- '/after/lsp/' print(vim.fs.joinpath('', '')) -- '/' Especially problematic if the empty segment is the first segment, as that converts the path to an absolute path. Solution: Ignore empty (length of 0) path segments. Benchmark: local function test(func) local t = vim.uv.hrtime() for _ = 1, 100000, 1 do func('', 'this/is', 'a/very/long/path', '', 'it', 'really', 'is') end print(math.floor((vim.uv.hrtime() - t) / 1e6), 'ms') end - with Iter():filter() --> 370 ms - building new segments table --> 208 ms - with vim.tbl_filter --> 232 ms - Instead of gsub split on `/` in all parts --> 1870 ms
* docs: vim.fs path expansionJustin M. Keyes2026-02-12
| | | | fix #37583
* fix(vim.fs): make `rm()` work with symlink to a directoryEvgeni Chasnovski2026-02-10
|
* fix: misc typos #37471phanium2026-01-27
|
* fix(vim.fs): avoid fn.fnamemodify in fs.root #37162Jason Shipman2025-12-30
| | | | | | | | | | Problem: vim.fs.root uses vim.fn.fnamemodify. vim.fn table isn't available from nvim -ll or thread contexts. Solution: Swap out vim.fn.fnamemodify for vim.fs.abspath. This is a temporary workaround and may be reverted since the long-term plan is to use more fast=true "fn" functions from vim.fs where possible.
* fix(vim.fs): abspath(".") returns "/…/." #36583Justin M. Keyes2025-11-16
|
* fix(vim.fs): root() should always return absolute path #36466Cameron Ring2025-11-16
|
* docs: getpos, getregion, lspJustin M. Keyes2025-11-15
|
* refactor(lua): consistent use of local aliasesChristian Clason2025-08-28
|
* docs: vim.fs.dir.Opts type #34546phanium2025-06-17
| | | Follow the pattern of vim.fs.find.Opts
* docs: vim.fs., diagnostics, lsp #34402Justin M. Keyes2025-06-13
|
* feat(vim.fs): root() can specify "equal priority" #34276Siddhant Agarwal2025-06-09
|
* docs: lsp, emoji, startup #33446Justin M. Keyes2025-04-27
| | | Co-authored-by: Maria José Solano <majosolano99@gmail.com>
* fix(vim.fs): default to follow=false #32859Mike2025-03-14
| | | | | | | Problem: Following symlinks can have surprising behavior and slow performance. Solution: Do not set it by default.
* fix: resolve all remaining LuaLS diagnosticsLewis Russell2025-01-27
|
* feat(vim.fs): find(), dir() can "follow" symlinks #31551Mike2025-01-14
| | | | | | | | Problem: vim.fs.dir(), vim.fs.find() do not follow symlinks. Solution: - Add "follow" flag. - Enable it by default.
* feat: add vim.fs.relpathdundargoc2025-01-13
| | | | | This is needed to replace the nvim-lspconfig function is_descendant that some lspconfg configurations still use.
* fix(vim.fs.normalize): normalize case for windows drive letterdundargoc2025-01-04
| | | | | Also add tests for the current path casing behavior so it doesn't get accidentally changed.
* fix(vim.fs.abspath): correctly handle UNC pathsdundargoc2025-01-01
|