Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions doc/nvim-tree-lua.txt
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ Following is the default configuration. See |nvim-tree-opts| for details. >lua
filesystem_watchers = {
enable = true,
debounce_delay = 50,
max_outstanding_events = 100,
ignore_dirs = {
"/.ccls-cache",
"/build",
Expand Down Expand Up @@ -1450,6 +1451,15 @@ Enable / disable the feature.
Idle milliseconds between filesystem change and action.
Type: `number`, Default: `50` (ms)

*nvim-tree.filesystem_watchers.max_outstanding_events*
Maximum number of consecutive file system events for a single directory with
an interval < |nvim-tree.filesystem_watchers.debounce_delay|
When this is exceeded a warning notification will be shown and the file system
watcher disabled for the directory.
This has been observed when running on Windows PowerShell.
Consider adding this directory to |filesystem_watchers.ignore_dirs|
Type: `number`, Default: `100`

*nvim-tree.filesystem_watchers.ignore_dirs*
List of vim regex for absolute directory paths that will not be watched or
function returning whether a path should be ignored.
Expand Down Expand Up @@ -3203,6 +3213,7 @@ highlight group is not, hard linking as follows: >
|nvim-tree.filesystem_watchers.debounce_delay|
|nvim-tree.filesystem_watchers.enable|
|nvim-tree.filesystem_watchers.ignore_dirs|
|nvim-tree.filesystem_watchers.max_outstanding_events|
|nvim-tree.filters.custom|
|nvim-tree.filters.dotfiles|
|nvim-tree.filters.enable|
Expand Down
1 change: 1 addition & 0 deletions lua/nvim-tree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
filesystem_watchers = {
enable = true,
debounce_delay = 50,
max_outstanding_events = 100,
ignore_dirs = {
"/.ccls-cache",
"/build",
Expand Down
24 changes: 23 additions & 1 deletion lua/nvim-tree/explorer/watch.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local log = require("nvim-tree.log")
local git = require("nvim-tree.git")
local utils = require("nvim-tree.utils")
local notify = require("nvim-tree.notify")
local Watcher = require("nvim-tree.watcher").Watcher

local M = {
Expand Down Expand Up @@ -69,10 +70,30 @@ function M.create_watcher(node)
---@param watcher Watcher
local function callback(watcher)
log.line("watcher", "node event scheduled refresh %s", watcher.data.context)

-- event is awaiting debouncing and handling
watcher.data.outstanding_events = watcher.data.outstanding_events + 1

-- disable watcher when outstanding exceeds max
if watcher.data.outstanding_events > M.config.filesystem_watchers.max_outstanding_events then
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_outstanding_events,
M.config.filesystem_watchers.debounce_delay,
node.absolute_path
))
node:destroy_watcher()
end

utils.debounce(watcher.data.context, M.config.filesystem_watchers.debounce_delay, function()
if watcher.destroyed then
return
end

-- event has been handled
watcher.data.outstanding_events = 0

if node.link_to then
log.line("watcher", "node event executing refresh '%s' -> '%s'", node.link_to, node.absolute_path)
else
Expand All @@ -87,7 +108,8 @@ function M.create_watcher(node)
path = path,
callback = callback,
data = {
context = "explorer:watch:" .. path .. ":" .. M.uid
context = "explorer:watch:" .. path .. ":" .. M.uid,
outstanding_events = 0, -- unprocessed events that have not been debounced
}
})
end
Expand Down
13 changes: 9 additions & 4 deletions lua/nvim-tree/node/directory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ function DirectoryNode:new(args)
end

function DirectoryNode:destroy()
if self.watcher then
self.watcher:destroy()
self.watcher = nil
end
self:destroy_watcher()

if self.nodes then
for _, node in pairs(self.nodes) do
Expand All @@ -50,6 +47,14 @@ function DirectoryNode:destroy()
Node.destroy(self)
end

---Halt and remove the watcher for this node
function DirectoryNode:destroy_watcher()
if self.watcher then
self.watcher:destroy()
self.watcher = nil
end
end

---Update the git_status of the directory
---@param parent_ignored boolean
---@param project GitProject?
Expand Down
Loading