@@ -3,6 +3,7 @@ local view = require "nvim-tree.view"
3
3
local core = require " nvim-tree.core"
4
4
local utils = require " nvim-tree.utils"
5
5
local events = require " nvim-tree.events"
6
+ local explorer_node = require " nvim-tree.explorer.node"
6
7
7
8
--- @class LibOpenOpts
8
9
--- @field path string | nil path
@@ -86,6 +87,34 @@ function M.get_last_group_node(node)
86
87
return node
87
88
end
88
89
90
+ --- Group empty folders
91
+ -- Recursively group nodes
92
+ --- @param node Node
93
+ --- @return Node[]
94
+ function M .group_empty_folders (node )
95
+ local is_root = not node .parent
96
+ local child_folder_only = explorer_node .has_one_child_folder (node ) and node .nodes [1 ]
97
+ if M .group_empty and not is_root and child_folder_only then
98
+ node .group_next = child_folder_only
99
+ local ns = M .group_empty_folders (child_folder_only )
100
+ node .nodes = ns or {}
101
+ return ns
102
+ end
103
+ return node .nodes
104
+ end
105
+
106
+ --- Ungroup empty folders
107
+ -- If a node is grouped, ungroup it: put node.group_next to the node.nodes and set node.group_next to nil
108
+ --- @param node Node
109
+ function M .ungroup_empty_folders (node )
110
+ local cur = node
111
+ while cur and cur .group_next do
112
+ cur .nodes = { cur .group_next }
113
+ cur .group_next = nil
114
+ cur = cur .nodes [1 ]
115
+ end
116
+ end
117
+
89
118
--- @param node Node
90
119
--- @return Node[]
91
120
function M .get_all_nodes_in_group (node )
@@ -98,8 +127,21 @@ function M.get_all_nodes_in_group(node)
98
127
return nodes
99
128
end
100
129
130
+ -- Toggle group empty folders
131
+ --- @param head_node Node
132
+ local function toggle_group_folders (head_node )
133
+ local is_grouped = head_node .group_next ~= nil
134
+
135
+ if is_grouped then
136
+ M .ungroup_empty_folders (head_node )
137
+ else
138
+ M .group_empty_folders (head_node )
139
+ end
140
+ end
141
+
101
142
--- @param node Node
102
- function M .expand_or_collapse (node )
143
+ function M .expand_or_collapse (node , toggle_group )
144
+ toggle_group = toggle_group or false
103
145
if node .has_children then
104
146
node .has_children = false
105
147
end
@@ -108,9 +150,20 @@ function M.expand_or_collapse(node)
108
150
core .get_explorer ():expand (node )
109
151
end
110
152
111
- local open = not M .get_last_group_node (node ).open
112
- for _ , n in ipairs (M .get_all_nodes_in_group (node )) do
113
- n .open = open
153
+ local head_node = utils .get_parent_of_group (node )
154
+ if toggle_group then
155
+ toggle_group_folders (head_node )
156
+ end
157
+
158
+ local open = M .get_last_group_node (node ).open
159
+ local next_open
160
+ if toggle_group then
161
+ next_open = open
162
+ else
163
+ next_open = not open
164
+ end
165
+ for _ , n in ipairs (M .get_all_nodes_in_group (head_node )) do
166
+ n .open = next_open
114
167
end
115
168
116
169
renderer .draw ()
@@ -213,6 +266,7 @@ function M.setup(opts)
213
266
M .hijack_directories = opts .hijack_directories
214
267
M .respect_buf_cwd = opts .respect_buf_cwd
215
268
M .select_prompts = opts .select_prompts
269
+ M .group_empty = opts .renderer .group_empty
216
270
end
217
271
218
272
return M
0 commit comments