Skip to content

Commit 6eaf74c

Browse files
authored
feat(#3292): add nvim_tree.config.filesystem_watchers.whitelist_dirs - strongly recommended for windows (#3298)
* feat(#3292): add nvim_tree.config.filesystem_watchers.whitelist_dirs * feat(#3292): add nvim_tree.config.filesystem_watchers.whitelist_dirs * feat(#3292): add nvim_tree.config.filesystem_watchers.whitelist_dirs
1 parent 3d385d3 commit 6eaf74c

File tree

4 files changed

+69
-15
lines changed

4 files changed

+69
-15
lines changed

doc/nvim-tree-lua.txt

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,9 @@ Windows WSL and PowerShell
844844
- Executable file detection is disabled as this is non-performant and can
845845
freeze Nvim
846846
- Some filesystem watcher error related to permissions will not be reported
847+
- Filesystem watchers can experience severe performance issues. It is strongly
848+
recommended to tightly control watcher usage via
849+
|nvim_tree.config.filesystem_watchers| {whitelist_dirs}
847850

848851
Powershell
849852
- Observed Nvim hanging after a runaway (infinite) number of events on a
@@ -1692,25 +1695,36 @@ Config: filesystem_watchers *nvim-tree-config-filesystem-watchers*
16921695
With this feature, the tree will be partially updated on specific
16931696
directory changes, resulting in better performance.
16941697

1695-
Watchers may be disabled for absolute directory paths via {ignore_dirs}.
1696-
• A list of |regular-expression| to match a path, backslash escaped e.g.
1697-
`"my-proj/\\.build$"` OR
1698-
• A function that is passed an absolute path and returns `true` to disable
1699-
This may be useful when a path is not in `.gitignore` or git integration
1700-
is disabled.
1698+
Blacklist watching absolute directory paths via {ignore_dirs} and
1699+
optionally whitelist via {whitelist_dirs}:
1700+
• A table of |regular-expression| that will be passed to `vim.fn.match`
1701+
• Backslashes must be escaped e.g. `"my-proj/\\.build$"`
1702+
• Literal backslashes must be double escaped to avoid |/magic| e.g.
1703+
`"C:\\\\src\\\\my-proj"`
1704+
• OR a `fun(path: string): boolean` that is passed an absolute path:
1705+
• {ignore_dirs}: return `true` to disable
1706+
• {whitelist_dirs}: return `true` to enable
1707+
1708+
{whitelist_dirs} is STRONGLY recommended for windows:
1709+
|nvim-tree-os-specific|.
17011710

17021711
After {max_events} consecutive filesystem events on a single directory
17031712
with an interval < {debounce_delay}:
17041713
• The filesystem watcher will be disabled for that directory.
17051714
• A warning notification will be shown.
17061715
• Consider adding this directory to {ignore_dirs}
17071716

1717+
By default, {max_events} is only enabled for windows.
1718+
17081719
Fields: ~
17091720
{enable}? (`boolean`) (default: `true`)
17101721
• {debounce_delay}? (`integer`, default: `50`) Idle milliseconds
17111722
between filesystem change and tree update.
17121723
• {ignore_dirs}? (`string[]|(fun(path: string): boolean)`, default: `{ "/.ccls-cache", "/build", "/node_modules", "/target", "/.zig-cache"}`)
17131724
Disable for specific directories.
1725+
• {whitelist_dirs}? (`string[]|(fun(path: string): boolean)`, default:
1726+
`{}`) Optionally enable only for specific
1727+
directories.
17141728
• {max_events}? (`integer`, default: `0` or `1000` on windows)
17151729
Disable for a single directory after {max_events}
17161730
consecutive events with an interval <
@@ -2199,6 +2213,7 @@ Following is the default configuration, see |nvim_tree.config| for details. >lua
21992213
"/target",
22002214
"/.zig-cache",
22012215
},
2216+
whitelist_dirs = {},
22022217
},
22032218
actions = {
22042219
use_system_clipboard = true,

lua/nvim-tree/_meta/config/filesystem_watchers.lua

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,23 @@ error("Cannot require a meta file")
77
---
88
---With this feature, the tree will be partially updated on specific directory changes, resulting in better performance.
99
---
10-
---Watchers may be disabled for absolute directory paths via {ignore_dirs}.
11-
--- - A list of [regular-expression] to match a path, backslash escaped e.g. `"my-proj/\\.build$"` OR
12-
--- - A function that is passed an absolute path and returns `true` to disable
13-
---This may be useful when a path is not in `.gitignore` or git integration is disabled.
10+
---Blacklist watching absolute directory paths via {ignore_dirs} and optionally whitelist via {whitelist_dirs}:
11+
---- A table of |regular-expression| that will be passed to `vim.fn.match`
12+
--- - Backslashes must be escaped e.g. `"my-proj/\\.build$"`
13+
--- - Literal backslashes must be double escaped to avoid |/magic| e.g. `"C:\\\\src\\\\my-proj"`
14+
---- OR a `fun(path: string): boolean` that is passed an absolute path:
15+
--- - {ignore_dirs}: return `true` to disable
16+
--- - {whitelist_dirs}: return `true` to enable
17+
---
18+
---{whitelist_dirs} is STRONGLY recommended for windows: [nvim-tree-os-specific].
1419
---
1520
---After {max_events} consecutive filesystem events on a single directory with an interval < {debounce_delay}:
1621
---- The filesystem watcher will be disabled for that directory.
1722
---- A warning notification will be shown.
1823
---- Consider adding this directory to {ignore_dirs}
1924
---
25+
---By default, {max_events} is only enabled for windows.
26+
---
2027
---@class nvim_tree.config.filesystem_watchers
2128
---
2229
---(default: `true`)
@@ -30,6 +37,10 @@ error("Cannot require a meta file")
3037
---(default: `{ "/.ccls-cache", "/build", "/node_modules", "/target", "/.zig-cache"}`)
3138
---@field ignore_dirs? string[]|(fun(path: string): boolean)
3239
---
40+
---Optionally enable only for specific directories.
41+
---(default: `{}`)
42+
---@field whitelist_dirs? string[]|(fun(path: string): boolean)
43+
---
3344
---Disable for a single directory after {max_events} consecutive events with an interval < {debounce_delay}.
3445
---Set to 0 to allow unlimited consecutive events.
3546
---(default: `0` or `1000` on windows)

lua/nvim-tree/config.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ M.d = { -- config-default-start
218218
"/target",
219219
"/.zig-cache",
220220
},
221+
whitelist_dirs = {},
221222
},
222223
actions = {
223224
use_system_clipboard = true,
@@ -348,6 +349,7 @@ local ACCEPTED_TYPES = {
348349
},
349350
filesystem_watchers = {
350351
ignore_dirs = { "function" },
352+
whitelist_dirs = { "function" },
351353
},
352354
actions = {
353355
open_file = {

lua/nvim-tree/explorer/watch.lua

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ local IGNORED_PATHS = {
3333
"/dev",
3434
}
3535

36+
---Return true when a path is:
37+
---- Blacklisted via {ignore_dirs}
38+
---- Not whitelisted via {whitelist_dirs}, when it is not an empty table.
3639
---@param path string
3740
---@return boolean
3841
local function is_folder_ignored(path)
@@ -42,18 +45,41 @@ local function is_folder_ignored(path)
4245
end
4346
end
4447

45-
if type(M.config.filesystem_watchers.ignore_dirs) == "table" then
46-
for _, ignore_dir in ipairs(M.config.filesystem_watchers.ignore_dirs) do
48+
---Return true when p matches an entry in dirs, escaping for windows
49+
---@param p string absolute path
50+
---@param dirs string[] absolute or relative
51+
---@return boolean
52+
local function matches_dirs(p, dirs)
53+
for _, dir in ipairs(dirs) do
4754
if utils.is_windows then
48-
ignore_dir = ignore_dir:gsub("/", "\\\\") or ignore_dir
55+
dir = dir:gsub("/", "\\\\") or dir
4956
end
5057

51-
if vim.fn.match(path, ignore_dir) ~= -1 then
58+
if vim.fn.match(p, dir) ~= -1 then
5259
return true
5360
end
5461
end
62+
return false
63+
end
64+
65+
if type(M.config.filesystem_watchers.ignore_dirs) == "table" then
66+
if matches_dirs(path, M.config.filesystem_watchers.ignore_dirs) then
67+
return true
68+
end
5569
elseif type(M.config.filesystem_watchers.ignore_dirs) == "function" then
56-
return M.config.filesystem_watchers.ignore_dirs(path)
70+
if M.config.filesystem_watchers.ignore_dirs(path) then
71+
return true
72+
end
73+
end
74+
75+
if type(M.config.filesystem_watchers.whitelist_dirs) == "table" and #M.config.filesystem_watchers.whitelist_dirs > 0 then
76+
if not matches_dirs(path, M.config.filesystem_watchers.whitelist_dirs) then
77+
return true
78+
end
79+
elseif type(M.config.filesystem_watchers.whitelist_dirs) == "function" then
80+
if not M.config.filesystem_watchers.whitelist_dirs(path) then
81+
return true
82+
end
5783
end
5884

5985
return false

0 commit comments

Comments
 (0)