Skip to content

Commit caa64cf

Browse files
committed
fix: cleanup debounce functionality, may fix #111 and #109
1 parent 1e1bca3 commit caa64cf

File tree

4 files changed

+65
-44
lines changed

4 files changed

+65
-44
lines changed

lua/neo-tree/sources/filesystem/init.lua

+7-5
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,10 @@ M.follow = function(callback, force_show)
116116
end
117117
utils.debounce("neo-tree-follow", function()
118118
return follow_internal(callback, force_show)
119-
end, 200, utils.debounce_strategy.CALL_LAST_ONLY)
119+
end, 100, utils.debounce_strategy.CALL_LAST_ONLY)
120120
end
121121

122-
local navigate_internal = function(path, path_to_reveal, callback)
122+
M._navigate_internal = function(path, path_to_reveal, callback)
123123
log.trace("navigate_internal", path, path_to_reveal)
124124
local state = get_state()
125125
state.dirty = false
@@ -138,7 +138,8 @@ local navigate_internal = function(path, path_to_reveal, callback)
138138
state.position.set(path_to_reveal)
139139
fs_scan.get_items_async(state, nil, path_to_reveal, callback)
140140
else
141-
local follow_file = state.follow_current_file and manager.get_path_to_reveal()
141+
local is_search = utils.truthy(state.search_pattern)
142+
local follow_file = not is_search and state.follow_current_file and manager.get_path_to_reveal()
142143
local handled = false
143144
if utils.truthy(follow_file) then
144145
handled = follow_internal(callback, true)
@@ -170,8 +171,8 @@ M.navigate = function(path, path_to_reveal, callback)
170171
local state = get_state()
171172
state.in_navigate = true
172173
utils.debounce("filesystem_navigate", function()
173-
navigate_internal(path, path_to_reveal, callback)
174-
end, utils.debounce_strategy.CALL_FIRST_AND_LAST, 200)
174+
M._navigate_internal(path, path_to_reveal, callback)
175+
end, utils.debounce_strategy.CALL_FIRST_AND_LAST, 500)
175176
end
176177

177178
M.reset_search = function(refresh)
@@ -268,6 +269,7 @@ M.setup = function(config, global_config)
268269
log.trace("Ignoring vim_buffer_changed event from " .. source)
269270
return
270271
end
272+
log.trace("refreshing due to vim_buffer_changed event: ", afile)
271273
manager.refresh(M.name)
272274
end,
273275
})

lua/neo-tree/sources/filesystem/lib/filter.lua

+16-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,22 @@ M.show_filter = function(state, search_as_you_type)
8383
else
8484
log.trace("Setting search in on_change to: " .. value)
8585
state.search_pattern = value
86-
manager.refresh("filesystem")
86+
local len = #value
87+
local delay = 500
88+
89+
if len > 5 then
90+
delay = 100
91+
elseif len > 3 then
92+
delay = 200
93+
elseif len > 2 then
94+
delay = 400
95+
end
96+
utils.debounce(
97+
"filesystem_filter",
98+
fs._navigate_internal,
99+
delay,
100+
utils.debounce_strategy.CALL_LAST_ONLY
101+
)
87102
end
88103
end,
89104
})

lua/neo-tree/sources/manager.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -304,11 +304,11 @@ end
304304

305305
---Refreshes the tree by scanning the filesystem again.
306306
M.refresh = function(source_name, callback)
307-
log.trace(source_name, " refresh")
308307
local current_tabnr = vim.api.nvim_get_current_tabpage()
309308
local sd = get_source_data(source_name)
310309
for _, state in pairs(sd.state_by_tab) do
311310
if state.tabnr == current_tabnr and state.path and renderer.window_exists(state) then
311+
log.trace(source_name, " refresh")
312312
if type(callback) ~= "function" then
313313
callback = nil
314314
end

lua/neo-tree/utils.lua

+41-37
Original file line numberDiff line numberDiff line change
@@ -34,64 +34,68 @@ M.debounce_strategy = {
3434
---@param frequency_in_ms number Miniumum amount of time between invocations of fn.
3535
---@param strategy number The debounce_strategy to use, determines which calls to fn are not dropped.
3636
---@param callback function Called with the result of executing fn as: callback(success, result)
37-
M.debounce = function(id, fn, frequency_in_ms, strategy, callback)
38-
strategy = strategy or M.debounce_strategy.CALL_FIRST_AND_LAST
37+
M.debounce = function(id, fn, frequency_in_ms, strategy)
3938
local fn_data = tracked_functions[id]
39+
40+
local defer_function = function()
41+
fn_data.in_debounce_period = true
42+
vim.defer_fn(function()
43+
local current_data = tracked_functions[id]
44+
local _fn = current_data.fn
45+
current_data.fn = nil
46+
current_data.in_debounce_period = false
47+
if _fn ~= nil then
48+
M.debounce(id, _fn, current_data.frequency_in_ms, strategy)
49+
end
50+
end, frequency_in_ms)
51+
end
52+
4053
if fn_data == nil then
4154
-- first call for this id
4255
fn_data = {
4356
id = id,
44-
fn = nil,
57+
in_debounce_period = false,
58+
fn = fn,
4559
frequency_in_ms = frequency_in_ms,
46-
postponed_callback = nil,
47-
in_debounce_period = true,
4860
}
49-
if strategy == M.debounce_strategy.CALL_LAST_ONLY then
50-
fn_data.in_debounce_period = true
51-
end
5261
tracked_functions[id] = fn_data
53-
else
54-
if fn_data.in_debounce_period then
55-
-- This id was called recently and can't be executed again yet.
56-
-- Just keep track of the details for this request so it
57-
-- can be executed at the end of the debounce period.
58-
-- Last one in wins.
59-
fn_data.fn = fn
60-
fn_data.frequency_in_ms = frequency_in_ms
61-
fn_data.postponed_callback = callback
62+
if strategy == M.debounce_strategy.CALL_LAST_ONLY then
63+
defer_function()
6264
return
6365
end
66+
else
67+
fn_data.fn = fn
68+
fn_data.frequency_in_ms = frequency_in_ms
69+
end
70+
71+
if fn_data.in_debounce_period then
72+
-- This id was called recently and can't be executed again yet.
73+
-- Last one in wins.
74+
return
6475
end
6576

6677
-- Run the requested function normally.
6778
-- Use a pcall to ensure the debounce period is still respected even if
6879
-- this call throws an error.
6980
fn_data.in_debounce_period = true
7081
local success, result = pcall(fn)
82+
fn_data.fn = nil
83+
fn = nil
7184

7285
if not success then
73-
log.error("Error in neo-tree.utils.debounce: ", result)
86+
log.error(result)
7487
end
7588

76-
-- Now schedule the next earliest execution.
77-
-- If there are no calls to run the same function between now
78-
-- and when this deferred executes, nothing will happen.
79-
-- If there are several calls, only the last one in will run.
80-
vim.defer_fn(function()
81-
local current_data = tracked_functions[id]
82-
local _callback = current_data.postponed_callback
83-
local _fn = current_data.fn
84-
current_data.postponed_callback = nil
85-
current_data.fn = nil
86-
current_data.in_debounce_period = false
87-
if _fn ~= nil then
88-
M.debounce(id, _fn, current_data.frequency_in_ms, strategy, _callback)
89-
end
90-
end, frequency_in_ms)
91-
92-
-- The callback function is outside the scope of the debounce period
93-
if type(callback) == "function" then
94-
callback(success, result)
89+
if strategy == M.debounce_strategy.CALL_LAST_ONLY then
90+
-- We are done with this debounce
91+
tracked_functions[id] = nil
92+
else
93+
-- Now schedule the next earliest execution.
94+
-- If there are no calls to run the same function between now
95+
-- and when this deferred executes, nothing will happen.
96+
-- If there are several calls, only the last one in will run.
97+
strategy = M.debounce_strategy.CALL_LAST_ONLY
98+
defer_function()
9599
end
96100
end
97101

0 commit comments

Comments
 (0)