Skip to content

Commit dbf178b

Browse files
authored
fix: infinite recursion in empty folder with hide_root_node = true (#729)
fixes #714
1 parent 28fdd1a commit dbf178b

File tree

2 files changed

+40
-40
lines changed

2 files changed

+40
-40
lines changed

lua/neo-tree/sources/common/commands.lua

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,41 @@ local log = require("neo-tree.log")
1111
local help = require("neo-tree.sources.common.help")
1212
local Preview = require("neo-tree.sources.common.preview")
1313

14-
---Gets the node parent folder recursively
15-
---@param tree table to look for nodes
16-
---@param node table to look for folder parent
17-
---@return table table
18-
local function get_folder_node(state, node)
14+
---Gets the node parent folder
15+
---@param state table to look for nodes
16+
---@return table? node
17+
local function get_folder_node(state)
1918
local tree = state.tree
20-
if not node then
21-
node = tree:get_node()
22-
end
19+
local node = tree:get_node()
20+
local last_id = node:get_id()
21+
22+
while node do
23+
local insert_as_local = state.config.insert_as
24+
local insert_as_global = require("neo-tree").config.window.insert_as
25+
local use_parent
26+
if insert_as_local then
27+
use_parent = insert_as_local == "sibling"
28+
else
29+
use_parent = insert_as_global == "sibling"
30+
end
2331

24-
local insert_as_local = state.config.insert_as
25-
local insert_as_global = require("neo-tree").config.window.insert_as
26-
local use_parent
27-
if insert_as_local then
28-
use_parent = insert_as_local == "sibling"
29-
else
30-
use_parent = insert_as_global == "sibling"
31-
end
32+
local is_open_dir = node.type == "directory" and (node:is_expanded() or node.empty_expanded)
33+
if use_parent and not is_open_dir then
34+
return tree:get_node(node:get_parent_id())
35+
end
3236

33-
local is_open_dir = node.type == "directory" and (node:is_expanded() or node.empty_expanded)
34-
if use_parent and not is_open_dir then
35-
return tree:get_node(node:get_parent_id())
36-
end
37+
if node.type == "directory" then
38+
return node
39+
end
3740

38-
if node.type == "directory" then
39-
return node
41+
local parent_id = node:get_parent_id()
42+
if parent_id or parent_id == last_id then
43+
return node
44+
else
45+
last_id = parent_id
46+
node = tree:get_node(parent_id)
47+
end
4048
end
41-
return get_folder_node(state, tree:get_node(node:get_parent_id()))
4249
end
4350

4451
---The using_root_directory is used to decide what part of the filename to show

lua/neo-tree/ui/renderer.lua

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ create_nodes = function(source_items, state, level)
216216
extra = item.extra,
217217
is_nested = item.is_nested,
218218
skip_node = item.skip_node,
219+
is_empty_with_hidden_root = item.is_empty_with_hidden_root,
219220
-- TODO: The below properties are not universal and should not be here.
220221
-- Maybe they should be moved to the "extra" field?
221222
is_link = item.is_link,
@@ -315,7 +316,13 @@ end
315316

316317
local prepare_node = function(item, state)
317318
if item.skip_node then
318-
return nil
319+
if item.is_empty_with_hidden_root then
320+
local line = NuiLine()
321+
line:append("(empty folder)", highlights.MESSAGE)
322+
return line
323+
else
324+
return nil
325+
end
319326
end
320327
-- pre_render is used to calculate the longest node width
321328
-- without actually rendering the node.
@@ -1074,7 +1081,6 @@ M.show_nodes = function(sourceItems, state, parentId, callback)
10741081
--local id = string.format("show_nodes %s:%s [%s]", state.name, state.force_float, state.tabnr)
10751082
--utils.debounce(id, function()
10761083
events.fire_event(events.BEFORE_RENDER, state)
1077-
local is_empty_with_hidden_root = false
10781084
state.longest_width_exact = 0
10791085
local parent
10801086
local level = 0
@@ -1093,10 +1099,8 @@ M.show_nodes = function(sourceItems, state, parentId, callback)
10931099
if config.hide_root_node then
10941100
if not parentId then
10951101
sourceItems[1].skip_node = true
1096-
if sourceItems[1].children and #sourceItems[1].children > 0 then
1097-
is_empty_with_hidden_root = false
1098-
else
1099-
is_empty_with_hidden_root = true
1102+
if not (sourceItems[1].children and #sourceItems[1].children > 0) then
1103+
sourceItems[1].is_empty_with_hidden_root = true
11001104
end
11011105
end
11021106
if not config.retain_hidden_root_indent then
@@ -1163,17 +1167,6 @@ M.show_nodes = function(sourceItems, state, parentId, callback)
11631167
if sourceItems then
11641168
-- normal path
11651169
local nodes = create_nodes(sourceItems, state, level)
1166-
if is_empty_with_hidden_root then
1167-
local nodeData = {
1168-
id = state.path .. "_empty_message",
1169-
name = "(empty folder)",
1170-
type = "message",
1171-
level = 0,
1172-
is_last_child = true,
1173-
}
1174-
local node = NuiTree.Node(nodeData, {})
1175-
table.insert(nodes, node)
1176-
end
11771170
draw(nodes, state, parentId)
11781171
else
11791172
-- this was a force grouping of a lazy loaded folder

0 commit comments

Comments
 (0)