Skip to content

Commit 06e48c2

Browse files
authored
chore(watchers): refactor events and make debouncer safe
- fs poll -> fs events - make debouncer safe and fix diagnostics events
1 parent 26512c3 commit 06e48c2

File tree

12 files changed

+156
-83
lines changed

12 files changed

+156
-83
lines changed

doc/nvim-tree-lua.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ Subsequent calls to setup will replace the previous configuration.
263263
diagnostics = {
264264
enable = false,
265265
show_on_dirs = false,
266+
debounce_delay = 50,
266267
icons = {
267268
hint = "",
268269
info = "",
@@ -328,6 +329,7 @@ Subsequent calls to setup will replace the previous configuration.
328329
all = false,
329330
config = false,
330331
copy_paste = false,
332+
dev = false,
331333
diagnostics = false,
332334
git = false,
333335
profile = false,
@@ -471,6 +473,10 @@ Show LSP and COC diagnostics in the signcolumn
471473
Enable/disable the feature.
472474
Type: `boolean`, Default: `false`
473475

476+
*nvim-tree.diagnostics.debounce_delay*
477+
Idle milliseconds between diagnostic event and update.
478+
Type: `number`, Default: `50` (ms)
479+
474480
*nvim-tree.diagnostics.show_on_dirs*
475481
Show diagnostic icons on parent directories.
476482
Type: `boolean`, Default: `false`
@@ -888,6 +894,10 @@ Configuration for diagnostic logging.
888894
File copy and paste actions.
889895
Type: `boolean`, Default: `false`
890896

897+
*nvim-tree.log.types.dev*
898+
Used for local development only. Not useful for users.
899+
Type: `boolean`, Default: `false`
900+
891901
*nvim-tree.log.types.diagnostics*
892902
LSP and COC processing, verbose.
893903
Type: `boolean`, Default: `false`

lua/nvim-tree.lua

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,11 +395,17 @@ local function setup_autocommands(opts)
395395

396396
if opts.diagnostics.enable then
397397
create_nvim_tree_autocmd("DiagnosticChanged", {
398-
callback = require("nvim-tree.diagnostics").update,
398+
callback = function()
399+
log.line("diagnostics", "DiagnosticChanged")
400+
require("nvim-tree.diagnostics").update()
401+
end,
399402
})
400403
create_nvim_tree_autocmd("User", {
401404
pattern = "CocDiagnosticChange",
402-
callback = require("nvim-tree.diagnostics").update,
405+
callback = function()
406+
log.line("diagnostics", "CocDiagnosticChange")
407+
require("nvim-tree.diagnostics").update()
408+
end,
403409
})
404410
end
405411
end
@@ -511,6 +517,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
511517
diagnostics = {
512518
enable = false,
513519
show_on_dirs = false,
520+
debounce_delay = 50,
514521
icons = {
515522
hint = "",
516523
info = "",
@@ -576,6 +583,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
576583
all = false,
577584
config = false,
578585
copy_paste = false,
586+
dev = false,
579587
diagnostics = false,
580588
git = false,
581589
profile = false,

lua/nvim-tree/core.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ local first_init_done = false
1010

1111
function M.init(foldername)
1212
if TreeExplorer then
13-
TreeExplorer:_clear_watchers()
13+
TreeExplorer:destroy()
1414
end
1515
TreeExplorer = explorer.Explorer.new(foldername)
1616
if not first_init_done then

lua/nvim-tree/diagnostics.lua

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -90,43 +90,45 @@ function M.update()
9090
if not M.enable or not core.get_explorer() or not view.is_buf_valid(view.get_bufnr()) then
9191
return
9292
end
93-
local ps = log.profile_start "diagnostics update"
94-
log.line("diagnostics", "update")
95-
96-
local buffer_severity
97-
if is_using_coc() then
98-
buffer_severity = from_coc()
99-
else
100-
buffer_severity = from_nvim_lsp()
101-
end
93+
utils.debounce("diagnostics", M.debounce_delay, function()
94+
local ps = log.profile_start "diagnostics update"
95+
log.line("diagnostics", "update")
96+
97+
local buffer_severity
98+
if is_using_coc() then
99+
buffer_severity = from_coc()
100+
else
101+
buffer_severity = from_nvim_lsp()
102+
end
102103

103-
M.clear()
104+
M.clear()
104105

105-
local nodes_by_line = utils.get_nodes_by_line(core.get_explorer().nodes, core.get_nodes_starting_line())
106-
for _, node in pairs(nodes_by_line) do
107-
node.diag_status = nil
108-
end
106+
local nodes_by_line = utils.get_nodes_by_line(core.get_explorer().nodes, core.get_nodes_starting_line())
107+
for _, node in pairs(nodes_by_line) do
108+
node.diag_status = nil
109+
end
109110

110-
for bufname, severity in pairs(buffer_severity) do
111-
local bufpath = utils.canonical_path(bufname)
112-
log.line("diagnostics", " bufpath '%s' severity %d", bufpath, severity)
113-
if 0 < severity and severity < 5 then
114-
for line, node in pairs(nodes_by_line) do
115-
local nodepath = utils.canonical_path(node.absolute_path)
116-
log.line("diagnostics", " %d checking nodepath '%s'", line, nodepath)
117-
if M.show_on_dirs and vim.startswith(bufpath, nodepath) then
118-
log.line("diagnostics", " matched fold node '%s'", node.absolute_path)
119-
node.diag_status = severity
120-
add_sign(line, severity)
121-
elseif nodepath == bufpath then
122-
log.line("diagnostics", " matched file node '%s'", node.absolute_path)
123-
node.diag_status = severity
124-
add_sign(line, severity)
111+
for bufname, severity in pairs(buffer_severity) do
112+
local bufpath = utils.canonical_path(bufname)
113+
log.line("diagnostics", " bufpath '%s' severity %d", bufpath, severity)
114+
if 0 < severity and severity < 5 then
115+
for line, node in pairs(nodes_by_line) do
116+
local nodepath = utils.canonical_path(node.absolute_path)
117+
log.line("diagnostics", " %d checking nodepath '%s'", line, nodepath)
118+
if M.show_on_dirs and vim.startswith(bufpath, nodepath) then
119+
log.line("diagnostics", " matched fold node '%s'", node.absolute_path)
120+
node.diag_status = severity
121+
add_sign(line, severity)
122+
elseif nodepath == bufpath then
123+
log.line("diagnostics", " matched file node '%s'", node.absolute_path)
124+
node.diag_status = severity
125+
add_sign(line, severity)
126+
end
125127
end
126128
end
127129
end
128-
end
129-
log.profile_end(ps, "diagnostics update")
130+
log.profile_end(ps, "diagnostics update")
131+
end)
130132
end
131133

132134
local links = {
@@ -138,6 +140,7 @@ local links = {
138140

139141
function M.setup(opts)
140142
M.enable = opts.diagnostics.enable
143+
M.debounce_delay = opts.diagnostics.debounce_delay
141144

142145
if M.enable then
143146
log.line("diagnostics", "setup")

lua/nvim-tree/explorer/common.lua

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ function M.update_git_status(node, parent_ignored, status)
4343
end
4444
end
4545

46+
function M.node_destroy(node)
47+
if not node then
48+
return
49+
end
50+
51+
if node.watcher then
52+
node.watcher:destroy()
53+
end
54+
end
55+
4656
function M.setup(opts)
4757
M.config = {
4858
git = opts.git,

lua/nvim-tree/explorer/init.lua

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ local uv = vim.loop
22

33
local git = require "nvim-tree.git"
44
local watch = require "nvim-tree.explorer.watch"
5+
local common = require "nvim-tree.explorer.common"
56

67
local M = {}
78

@@ -33,22 +34,16 @@ function Explorer:expand(node)
3334
self:_load(node)
3435
end
3536

36-
function Explorer.clear_watchers_for(root_node)
37+
function Explorer:destroy()
3738
local function iterate(node)
38-
if node.watcher then
39-
node.watcher:stop()
39+
common.node_destroy(node)
40+
if node.nodes then
4041
for _, child in pairs(node.nodes) do
41-
if child.watcher then
42-
iterate(child)
43-
end
42+
iterate(child)
4443
end
4544
end
4645
end
47-
iterate(root_node)
48-
end
49-
50-
function Explorer:_clear_watchers()
51-
Explorer.clear_watchers_for(self)
46+
iterate(self)
5247
end
5348

5449
function M.setup(opts)

lua/nvim-tree/explorer/reload.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ function M.reload(node, status)
6969
node.nodes = vim.tbl_map(
7070
update_status(nodes_by_path, node_ignored, status),
7171
vim.tbl_filter(function(n)
72-
return child_names[n.absolute_path]
72+
if child_names[n.absolute_path] then
73+
return child_names[n.absolute_path]
74+
else
75+
common.node_destroy(n)
76+
return nil
77+
end
7378
end, node.nodes)
7479
)
7580

lua/nvim-tree/explorer/watch.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ function M.create_watcher(absolute_path)
4646
end
4747

4848
log.line("watcher", "node start '%s'", absolute_path)
49-
Watcher.new {
49+
return Watcher.new {
5050
absolute_path = absolute_path,
5151
interval = M.interval,
5252
on_event = function(opts)

lua/nvim-tree/git/init.lua

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ function M.reload_project(project_root, path)
2929
return
3030
end
3131

32-
if path and not path:match("^" .. project_root) then
33-
path = nil
32+
if path and path:find(project_root, 1, true) ~= 1 then
33+
return
3434
end
3535

3636
local git_status = Runner.run {
@@ -43,7 +43,7 @@ function M.reload_project(project_root, path)
4343

4444
if path then
4545
for p in pairs(project.files) do
46-
if p:match("^" .. path) then
46+
if p:find(path, 1, true) == 1 then
4747
project.files[p] = nil
4848
end
4949
end
@@ -138,10 +138,6 @@ function M.load_project_status(cwd)
138138
reload_tree_at(opts.project_root)
139139
end)
140140
end,
141-
on_event0 = function()
142-
log.line("watcher", "git event")
143-
M.reload_tree_at(project_root)
144-
end,
145141
}
146142
end
147143

lua/nvim-tree/git/runner.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ function Runner.run(opts)
147147
log.profile_end(ps, "git job %s %s", opts.project_root, opts.path)
148148

149149
if self.rc == -1 then
150-
log.line("git", "job timed out")
150+
log.line("git", "job timed out %s %s", opts.project_root, opts.path)
151151
elseif self.rc ~= 0 then
152-
log.line("git", "job failed with return code %d", self.rc)
152+
log.line("git", "job fail rc %d %s %s", self.rc, opts.project_root, opts.path)
153153
else
154-
log.line("git", "job success")
154+
log.line("git", "job success %s %s", opts.project_root, opts.path)
155155
end
156156

157157
return self.output

0 commit comments

Comments
 (0)