Skip to content

fix(#3178): handle Windows paths in ignore_dirs and add .zig-cache to defaults#3261

Open
Uanela wants to merge 21 commits intomasterfrom
fix/windows-path-resolution
Open

fix(#3178): handle Windows paths in ignore_dirs and add .zig-cache to defaults#3261
Uanela wants to merge 21 commits intomasterfrom
fix/windows-path-resolution

Conversation

@Uanela
Copy link
Collaborator

@Uanela Uanela commented Feb 11, 2026

This PR fixes a critical memory leak issue on Windows where nvim-tree.lua spawns infinite filesystem watchers when the .zig-cache/tmp folder creates temporary files during a build process. The watcher locks these files, preventing Zig from deleting them and causing memory to grow by 10-20 MB/second.

Changes

  1. Added .zig-cache to default ignore_dirs - This directory contains build artifacts not under version control, similar to existing defaults like node_modules and build.

  2. Fixed Windows path handling in ignore_dirs - The forward slash prefix (e.g., /node_modules) used in default ignore patterns wasn't matching Windows paths (e.g., M:\path\to\node_modules). The fix converts forward slashes to backslashes on Windows to ensure proper pattern matching.

Technical Details

The existing utils.escape_special_characters utility was not suitable for this fix as it only handles parentheses and curly braces in paths, not the fundamental path separator difference between Unix (/) and Windows (\).

The solution implements OS-specific path normalization in is_folder_ignored() by converting forward slashes to backslashes on Windows systems before pattern matching with vim.fn.match().

Testing

Tested on Windows 10 with Zig build process. The .zig-cache directory is now properly ignored, and existing defaults like node_modules now correctly match on Windows paths.

Closes #3178

@Uanela Uanela requested a review from alex-courtis February 11, 2026 09:07
Copy link
Member

@alex-courtis alex-courtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing utils.escape_special_characters utility was not suitable for this fix as it only handles parentheses and curly braces in paths, not the fundamental path separator difference between Unix (/) and Windows ().

Good call. There may be unintended side effects.

Tested on Windows 10 with Zig build process.

Many thanks for the detailed testing!

Please:

Comment on lines 83 to 91
notify.error(
string.format(
"Observed %d consecutive file system events with interval < %dms, exceeding filesystem_watchers.max_events=%s. Disabling watcher for directory '%s'. Consider adding this directory to filesystem_watchers.ignore_dirs",
watcher.data.outstanding_events,
M.config.filesystem_watchers.max_events,
M.config.filesystem_watchers.debounce_delay,
node.absolute_path
)
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not make any formatting changes unrelated to this PR.

if type(M.config.filesystem_watchers.ignore_dirs) == "table" then
for _, ignore_dir in ipairs(M.config.filesystem_watchers.ignore_dirs) do
if utils.is_windows or true then
ignore_dir = ignore_dir:gsub("/", "\\") or ignore_dir
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to double escape the backslashes as per testing: #3178 (comment)

@Uanela
Copy link
Collaborator Author

Uanela commented Feb 15, 2026

I've reverted the unrelated formatting (sorry for this one) and double escaped the backslashes I searched about what it would cause and makes sense thanks again for the call.

Even after reverting the formatting there still some checks that are not passing even on my local I need to commit with --no-verify.

@Uanela Uanela requested a review from alex-courtis February 15, 2026 20:32
end

if type(M.config.filesystem_watchers.ignore_dirs) == "table" then
print(vim.inspect(M.config.filesystem_watchers.ignore_dirs))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the print...

Copy link
Member

@alex-courtis alex-courtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reverted the unrelated formatting (sorry for this one) and double escaped the backslashes I searched about what it would cause and makes sense thanks again for the call.

Even after reverting the formatting there still some checks that are not passing even on my local I need to commit with --no-verify.

I see. It looks like is_folder_ignored is indented with tabs, not spaces. You can format just that file with :lua vim.lsp.buf.format() or gg=G

You have identified a bigger problem: style-check does not identify all the issue that style-fix does. Issue incoming... #3271

Please:

  • format watch.lua
  • remove the print statement

@Uanela
Copy link
Collaborator Author

Uanela commented Feb 17, 2026

All good to go Sir Alex

@Uanela Uanela requested a review from alex-courtis February 17, 2026 11:43
Copy link
Member

@alex-courtis alex-courtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"/build",
"/node_modules",
"/target",
"/.zig-cache",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not present in nvim-tree.lua DEFAULT_OPTS

Please add it and re-generate the help: https://github.com/nvim-tree/nvim-tree.lua/blob/master/CONTRIBUTING.md#help-documentation


if type(M.config.filesystem_watchers.ignore_dirs) == "table" then
for _, ignore_dir in ipairs(M.config.filesystem_watchers.ignore_dirs) do
if utils.is_windows or true then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should that true be there?

Testing shows a regression:

mkdir foo
mkdir .ccls-cache

Set filters.dotfiles and git_ignored false
Open tree and directories

touch foo/1

Expected: 1 appears immediately.

touch .ccls-cache/2

Expected: 2 does not appear until R
Actual: appears immediately

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a testing I was doing my bad, I should have removed it

@Uanela
Copy link
Collaborator Author

Uanela commented Feb 18, 2026

@alex-courtis I've opened 3 PR so far and some issues, where 2 PR's refactors and one bug fix (very simple and with clear hints).

How would you rate my contributions from 0-10 so far, only rate if possible, maybe you lack some data I don't know.

@alex-courtis
Copy link
Member

Tested OK:

mkdir foo
mkdir .ccls-cache
mkdir .zig-cache

Set filters.dotfiles and git_ignored false
Open tree and directories

touch foo/1

Expected: 1 appears immediately.

touch .ccls-cache/2

Expected: 2 does not appear until R

touch .zig-cache/3

Expected: 3 does not appear until R

Copy link
Member

@alex-courtis alex-courtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested OK: #3261 (comment) on linux and you have tested windows.

Please accept my deepest apologies, I missed this one: we need to update the defaults in lua/nvim-tree/_meta/config/filesystem_watchers.lua and generate help.

How do you like to handle these tiny nits?

  1. Fix it yourself
  2. I push a fix
    No drama either way, everyone has their preference.

@Uanela
Copy link
Collaborator Author

Uanela commented Feb 19, 2026

Done.

Copy link
Member

@alex-courtis alex-courtis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love your work @Uanela

Edit: apologies, approved too early.

We're getting a CI fail on the help txt for the new default: https://github.com/nvim-tree/nvim-tree.lua/actions/runs/22170271960/job/64106472696?pr=3261

Please:

@alex-courtis alex-courtis self-requested a review February 19, 2026 23:14
@Uanela
Copy link
Collaborator Author

Uanela commented Feb 20, 2026

Docs regeneration done.

I got the problem that wasn't allowing me to regenerate the docs:

/tmp/src/neovim-stable/src/gen/gen_vimdoc.lua.org -> /tmp/src/neovim-stable/src/gen/gen_vimdoc.lua
scripts/help-defaults.sh
sed: -e: No such file or directory
make: *** [help-update] Error 1
uanela_como@Uanelas-MacBook-Pro nvim-tree.lua % sudo make help-update

the sed command on macos is gsed for (GNU sed) so I need to export gsed to sed in order to be able to update the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

filesystem_watchers.ignore_dirs Handle Windows Paths, Add /.zig-cache To Defaults

2 participants

Comments