Skip to content

Commit 9d4b748

Browse files
committed
fix(files): fix for filter losing state of open folders before search
1 parent 5e620fb commit 9d4b748

File tree

11 files changed

+148
-49
lines changed

11 files changed

+148
-49
lines changed

lua/neo-tree.lua

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ local define_events = function()
5656
args.diagnostics_lookup = utils.get_diagnostic_counts()
5757
end)
5858

59-
events.define_autocmd_event(
60-
events.VIM_BUFFER_CHANGED,
61-
{ "BufDelete", "BufWritePost", "BufFilePost", "BufNew" },
62-
200
63-
)
59+
events.define_autocmd_event(events.VIM_BUFFER_CHANGED, { "BufWritePost", "BufFilePost" }, 200)
60+
61+
events.define_autocmd_event(events.VIM_BUFFER_ADDED, { "BufAdd" }, 200)
62+
63+
events.define_autocmd_event(events.VIM_BUFFER_DELETED, { "BufDelete" }, 200)
6464
events.define_autocmd_event(events.VIM_BUFFER_ENTER, { "BufEnter", "BufWinEnter" }, 0)
6565
events.define_autocmd_event(events.VIM_WIN_ENTER, { "WinEnter" }, 0)
6666
events.define_autocmd_event(events.VIM_DIR_CHANGED, { "DirChanged" }, 200)

lua/neo-tree/events/init.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ local M = {
1313
FILE_RENAMED = "file_renamed",
1414
FS_EVENT = "fs_event",
1515
GIT_EVENT = "git_event",
16+
VIM_BUFFER_ADDED = "vim_buffer_added",
1617
VIM_BUFFER_CHANGED = "vim_buffer_changed",
18+
VIM_BUFFER_DELETED = "vim_buffer_deleted",
1719
VIM_BUFFER_ENTER = "vim_buffer_enter",
1820
VIM_DIAGNOSTIC_CHANGED = "vim_diagnostic_changed",
1921
VIM_DIR_CHANGED = "vim_dir_changed",

lua/neo-tree/log.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ local default_config = {
2626

2727
-- Level configuration
2828
modes = {
29-
{ name = "trace", hl = "Comment" },
30-
{ name = "debug", hl = "Comment" },
29+
{ name = "trace", hl = "None" },
30+
{ name = "debug", hl = "None" },
3131
{ name = "info", hl = "None" },
3232
{ name = "warn", hl = "WarningMsg" },
3333
{ name = "error", hl = "ErrorMsg" },

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

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,30 +130,39 @@ M.setup = function(config, global_config)
130130
--convert to new event system
131131
events.subscribe({
132132
event = events.BEFORE_RENDER,
133-
handler = config.before_render,
133+
handler = function(state)
134+
local this_state = get_state()
135+
if state == this_state then
136+
config.before_render(this_state)
137+
end
138+
end,
134139
id = before_render_id,
135140
})
136141
elseif global_config.enable_git_status then
137142
events.subscribe({
138143
event = events.BEFORE_RENDER,
139144
handler = function(state)
140-
state.git_status_lookup = utils.get_git_status()
145+
local this_state = get_state()
146+
if state == this_state then
147+
state.git_status_lookup = utils.get_git_status()
148+
end
141149
end,
142150
id = before_render_id,
143151
})
144152
end
145153

146-
events.subscribe({
147-
event = events.VIM_BUFFER_ENTER,
148-
handler = M.buffers_changed,
149-
id = "buffers." .. events.VIM_BUFFER_ENTER,
150-
})
151-
152-
events.subscribe({
153-
event = events.VIM_BUFFER_CHANGED,
154-
handler = M.buffers_changed,
155-
id = "buffers." .. events.VIM_BUFFER_CHANGED,
156-
})
154+
local refresh_events = {
155+
events.VIM_BUFFER_CHANGED,
156+
events.VIM_BUFFER_ADDED,
157+
events.VIM_BUFFER_DELETED,
158+
}
159+
for _, e in ipairs(refresh_events) do
160+
events.subscribe({
161+
event = e,
162+
handler = M.buffers_changed,
163+
id = "buffers." .. e,
164+
})
165+
end
157166

158167
if default_config.bind_to_cwd then
159168
events.subscribe({

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

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ local fs_scan = require("neo-tree.sources.filesystem.lib.fs_scan")
77
local renderer = require("neo-tree.ui.renderer")
88
local inputs = require("neo-tree.ui.inputs")
99
local events = require("neo-tree.events")
10+
local log = require("neo-tree.log")
1011

1112
local M = {}
1213
local default_config = nil
@@ -98,6 +99,7 @@ M.focus = function(path_to_reveal, callback)
9899
end
99100

100101
local navigate_internal = function(path, path_to_reveal, callback)
102+
log.trace("navigate_internal", path, path_to_reveal)
101103
local state = get_state()
102104
local pos = utils.get_value(state, "window.position", "left")
103105
local was_float = state.force_float or pos == "float"
@@ -116,6 +118,7 @@ local navigate_internal = function(path, path_to_reveal, callback)
116118
if callback then
117119
callback()
118120
end
121+
state.in_navigate = false
119122
end)
120123
else
121124
local previously_focused = nil
@@ -137,6 +140,7 @@ local navigate_internal = function(path, path_to_reveal, callback)
137140
if callback then
138141
callback()
139142
end
143+
state.in_navigate = false
140144
end)
141145
end
142146

@@ -150,12 +154,16 @@ end
150154
---@param path_to_reveal string Node to focus after the items are loaded.
151155
---@param callback function Callback to call after the items are loaded.
152156
M.navigate = function(path, path_to_reveal, callback)
157+
log.trace("navigate", path, path_to_reveal)
158+
local state = get_state()
159+
state.in_navigate = true
153160
utils.debounce("filesystem_navigate", function()
154161
navigate_internal(path, path_to_reveal, callback)
155162
end, 100)
156163
end
157164

158165
M.reveal_current_file = function(toggle_if_open)
166+
log.trace("Revealing current file")
159167
if toggle_if_open then
160168
if M.close() then
161169
-- It was open, and now it's not.
@@ -191,15 +199,20 @@ M.reveal_current_file = function(toggle_if_open)
191199
end
192200

193201
M.reset_search = function(refresh)
202+
log.trace("reset_search")
203+
local state = get_state()
194204
if refresh == nil then
195205
refresh = true
196206
end
197-
local state = get_state()
198207
if state.open_folders_before_search then
199-
renderer.set_expanded_nodes(state.tree, state.open_folders_before_search)
200-
state.open_folders_before_search = nil
208+
log.trace("reset_search: open_folders_before_search")
209+
state.force_open_folders = utils.table_copy(state.open_folders_before_search)
210+
else
211+
log.trace("reset_search: why are there no open_folders_before_search?")
212+
state.force_open_folders = nil
201213
end
202214
state.search_pattern = nil
215+
state.open_folders_before_search = nil
203216
if refresh then
204217
M.refresh()
205218
end
@@ -246,7 +259,11 @@ end
246259

247260
---Refreshes the tree by scanning the filesystem again.
248261
M.refresh = function(callback)
262+
log.trace("filesystem refresh")
249263
local state = get_state()
264+
if state.in_navigate or state.in_show_nodes then
265+
return
266+
end
250267
if state.path and renderer.window_exists(state) then
251268
if type(callback) ~= "function" then
252269
callback = nil
@@ -270,14 +287,22 @@ M.setup = function(config, global_config)
270287
--convert to new event system
271288
events.subscribe({
272289
event = events.BEFORE_RENDER,
273-
handler = config.before_render,
290+
handler = function(state)
291+
local this_state = get_state()
292+
if state == this_state then
293+
config.before_render(this_state)
294+
end
295+
end,
274296
id = before_render_id,
275297
})
276298
elseif global_config.enable_git_status then
277299
events.subscribe({
278300
event = events.BEFORE_RENDER,
279301
handler = function(state)
280-
state.git_status_lookup = utils.get_git_status()
302+
local this_state = get_state()
303+
if state == this_state then
304+
state.git_status_lookup = utils.get_git_status()
305+
end
281306
end,
282307
id = before_render_id,
283308
})

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

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ local fs = require("neo-tree.sources.filesystem")
77
local inputs = require("neo-tree.ui.inputs")
88
local popups = require("neo-tree.ui.popups")
99
local renderer = require("neo-tree.ui.renderer")
10+
local utils = require("neo-tree.utils")
11+
local log = require("neo-tree.log")
1012

1113
local M = {}
1214

@@ -22,13 +24,13 @@ M.show_filter = function(state, search_as_you_type)
2224
size = width,
2325
})
2426

25-
if
26-
not state.search_pattern
27-
or state.search_pattern == "" and not state.open_folders_before_search
28-
then
27+
local has_pre_search_folders = utils.truthy(state.open_folders_before_search)
28+
if not has_pre_search_folders then
29+
log.trace("No search or pre-search folders, recording pre-search folders now")
2930
state.open_folders_before_search = renderer.get_expanded_nodes(state.tree)
3031
end
3132

33+
local waiting_for_default_value = utils.truthy(state.search_pattern)
3234
local input = Input(popup_options, {
3335
prompt = " ",
3436
default_value = state.search_pattern,
@@ -54,19 +56,46 @@ M.show_filter = function(state, search_as_you_type)
5456
if not search_as_you_type then
5557
return
5658
end
59+
-- apparently when a default value is set, on_change fires for every character
60+
if waiting_for_default_value then
61+
if #value < #state.search_pattern then
62+
return
63+
else
64+
waiting_for_default_value = false
65+
end
66+
end
5767
if value == state.search_pattern then
5868
return
59-
end
60-
if value == nil or value == "" then
69+
elseif value == nil then
70+
return
71+
elseif value == "" then
72+
if state.search_pattern == nil then
73+
return
74+
end
75+
log.trace("Resetting search in on_change")
76+
local original_open_folders = nil
77+
if type(state.open_folders_before_search) == "table" then
78+
original_open_folders = utils.table_copy(state.open_folders_before_search)
79+
end
6180
fs.reset_search()
81+
state.open_folders_before_search = original_open_folders
6282
else
83+
log.trace("Setting search in on_change to: " .. value)
6384
state.search_pattern = value
6485
fs.refresh()
6586
end
6687
end,
6788
})
6889

69-
inputs.show_input(input)
90+
input:mount()
91+
92+
input:map("i", "<esc>", function(bufnr)
93+
input:unmount()
94+
end, { noremap = true })
95+
96+
input:on({ event.BufLeave, event.BufDelete }, function()
97+
input:unmount()
98+
end, { once = true })
7099
end
71100

72101
return M

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ M.get_items_async = function(state, parent_id, path_to_reveal, callback)
6969
root.loaded = true
7070
root.search_pattern = state.search_pattern
7171
context.folders[root.path] = root
72-
state.default_expanded_nodes = { state.path }
72+
state.default_expanded_nodes = state.force_open_folders or { state.path }
7373

7474
context.job_complete = function()
7575
file_items.deep_sort(root.children)
@@ -108,7 +108,11 @@ M.get_items_async = function(state, parent_id, path_to_reveal, callback)
108108
local path = parent_id or state.path
109109
context.paths_to_load = {}
110110
if parent_id == nil then
111-
if state.tree then
111+
if utils.truthy(state.force_open_folders) then
112+
for _, path in ipairs(state.force_open_folders) do
113+
table.insert(context.paths_to_load, path)
114+
end
115+
elseif state.tree then
112116
context.paths_to_load = renderer.get_expanded_nodes(state.tree)
113117
end
114118
if path_to_reveal then

lua/neo-tree/sources/git_status/defaults.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
local highlights = require("neo-tree.ui.highlights")
22

3-
local filesystem = {
3+
local git_status = {
44
window = {
55
position = "left",
66
width = 40,
@@ -62,4 +62,4 @@ local filesystem = {
6262
},
6363
}
6464

65-
return filesystem
65+
return git_status

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@ M.setup = function(config, global_config)
9191
--convert to new event system
9292
events.subscribe({
9393
event = events.BEFORE_RENDER,
94-
handler = config.before_render,
94+
handler = function(state)
95+
local this_state = get_state()
96+
if state == this_state then
97+
config.before_render(this_state)
98+
end
99+
end,
95100
id = config.name .. ".config.before_render",
96101
})
97102
else

lua/neo-tree/ui/renderer.lua

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -259,22 +259,19 @@ M.get_expanded_nodes = function(tree)
259259
end
260260

261261
M.collapse_all_nodes = function(tree)
262-
local function collapse_all(parent_node)
263-
if parent_node:has_children() then
264-
for _, child in ipairs(tree:get_nodes(parent_node:get_id())) do
265-
child:collapse()
266-
end
267-
parent_node:collapse()
268-
end
269-
end
270-
271-
for _, node in ipairs(tree:get_nodes()) do
272-
collapse_all(node)
262+
local expanded = M.get_expanded_nodes(tree)
263+
for _, id in ipairs(expanded) do
264+
local node = tree:get_node(id)
265+
node:collapse(id)
273266
end
267+
-- but make sure the root is expanded
268+
local root = tree:get_nodes()[1]
269+
root:expand()
274270
end
275271

276272
M.set_expanded_nodes = function(tree, expanded_nodes)
277273
M.collapse_all_nodes(tree)
274+
log.debug("Setting expanded nodes")
278275
for _, id in ipairs(expanded_nodes or {}) do
279276
local node = tree:get_node(id)
280277
if node ~= nil then
@@ -466,7 +463,13 @@ local draw = function(nodes, state, parent_id)
466463
-- If we are going to redraw, preserve the current set of expanded nodes.
467464
local expanded_nodes = {}
468465
if parent_id == nil and state.tree ~= nil then
469-
expanded_nodes = M.get_expanded_nodes(state.tree)
466+
if state.force_open_folders then
467+
log.trace("Force open folders")
468+
state.force_open_folders = nil
469+
else
470+
log.trace("Preserving expanded nodes")
471+
expanded_nodes = M.get_expanded_nodes(state.tree)
472+
end
470473
end
471474
for _, id in ipairs(state.default_expanded_nodes) do
472475
table.insert(expanded_nodes, id)

0 commit comments

Comments
 (0)