Skip to content

Commit d036b06

Browse files
juefei yanjuefei yan
juefei yan
authored and
juefei yan
committed
add a new api to toggle empty folders
1 parent 161b7bd commit d036b06

File tree

4 files changed

+38
-12
lines changed

4 files changed

+38
-12
lines changed

doc/nvim-tree-lua.txt

+5
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ Show the mappings: `g?`
181181
`I` Toggle Filter: Git Ignore |nvim-tree-api.tree.toggle_gitignore_filter()|
182182
`J` Last Sibling |nvim-tree-api.node.navigate.sibling.last()|
183183
`K` First Sibling |nvim-tree-api.node.navigate.sibling.first()|
184+
`L` Group or Ungroup Folders |nvim-tree-api.node.tree.toggle_grouped_folders()|
184185
`M` Toggle Filter: No Bookmark |nvim-tree-api.tree.toggle_no_bookmark_filter()|
185186
`m` Toggle Bookmark |nvim-tree-api.marks.toggle()|
186187
`o` Open |nvim-tree-api.node.open.edit()|
@@ -1848,6 +1849,9 @@ node.open.vertical() *nvim-tree-api.node.open.vertical()*
18481849
node.open.horizontal() *nvim-tree-api.node.open.horizontal()*
18491850
|nvim-tree-api.node.edit()|, file will be opened in a new horizontal split.
18501851

1852+
node.open.toggle_grouped_folders() *nvim-tree-api.node.open.toggle_grouped_folders()*
1853+
|nvim-tree-api.node.edit()|, empty folders would be grouped or ungrouped.
1854+
18511855
node.open.drop() *nvim-tree-api.node.open.drop()*
18521856
Switch to window with selected file if it exists.
18531857
Open file otherwise.
@@ -2196,6 +2200,7 @@ You are encouraged to copy these to your own |nvim-tree.on_attach| function.
21962200
vim.keymap.set('n', 'I', api.tree.toggle_gitignore_filter, opts('Toggle Filter: Git Ignore'))
21972201
vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts('Last Sibling'))
21982202
vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts('First Sibling'))
2203+
vim.keymap.set('n', 'L', api.node.open.toggle_grouped_folders,opts('Toggle Grouped Folders'))
21992204
vim.keymap.set('n', 'M', api.tree.toggle_no_bookmark_filter, opts('Toggle Filter: No Bookmark'))
22002205
vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark'))
22012206
vim.keymap.set('n', 'o', api.node.open.edit, opts('Open'))

lua/nvim-tree/api.lua

+3-2
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,12 @@ end
175175

176176
---@param mode string
177177
---@return fun(node: table)
178-
local function open_or_expand_or_dir_up(mode)
178+
local function open_or_expand_or_dir_up(mode, toggle_group)
179179
return function(node)
180180
if node.name == ".." then
181181
actions.root.change_dir.fn ".."
182182
elseif node.nodes then
183-
lib.expand_or_collapse(node)
183+
lib.expand_or_collapse(node, toggle_group)
184184
else
185185
edit(mode, node)
186186
end
@@ -195,6 +195,7 @@ Api.node.open.no_window_picker = wrap_node(open_or_expand_or_dir_up "edit_no_pic
195195
Api.node.open.vertical = wrap_node(open_or_expand_or_dir_up "vsplit")
196196
Api.node.open.horizontal = wrap_node(open_or_expand_or_dir_up "split")
197197
Api.node.open.tab = wrap_node(open_or_expand_or_dir_up "tabnew")
198+
Api.node.open.toggle_grouped_folders = wrap_node(open_or_expand_or_dir_up("toggle_grouped_folders", true))
198199
Api.node.open.preview = wrap_node(open_or_expand_or_dir_up "preview")
199200
Api.node.open.preview_no_picker = wrap_node(open_or_expand_or_dir_up "preview_no_picker")
200201

lua/nvim-tree/keymap.lua

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ function M.default_on_attach(bufnr)
7272
vim.keymap.set('n', 'I', api.tree.toggle_gitignore_filter, opts('Toggle Filter: Git Ignore'))
7373
vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts('Last Sibling'))
7474
vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts('First Sibling'))
75+
vim.keymap.set('n', 'L', api.node.open.toggle_grouped_folders,opts('Toggle Grouped Folders'))
7576
vim.keymap.set('n', 'M', api.tree.toggle_no_bookmark_filter, opts('Toggle Filter: No Bookmark'))
7677
vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark'))
7778
vim.keymap.set('n', 'o', api.node.open.edit, opts('Open'))

lua/nvim-tree/lib.lua

+29-10
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ function M.get_last_group_node(node)
8888
end
8989

9090
---Group empty folders
91+
-- Recursively group nodes
9192
---@param node Node
9293
---@return Node[]
9394
function M.group_empty_folders(node)
@@ -102,7 +103,8 @@ function M.group_empty_folders(node)
102103
return node.nodes
103104
end
104105

105-
---Group empty folders
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
106108
---@param node Node
107109
function M.ungroup_empty_folders(node)
108110
local cur = node
@@ -125,8 +127,26 @@ function M.get_all_nodes_in_group(node)
125127
return nodes
126128
end
127129

130+
-- If a folder is grouped and closed -> group folder and open
131+
-- If a folder is grouped and opened -> ungroup folder and open
132+
-- If a folder is ungrouped and opened -> group folder and close
133+
---@param head_node Node
134+
---@param open boolean
135+
---@return boolean
136+
local function toggle_group_folders(head_node, open)
137+
local is_grouped = head_node.group_next ~= nil
138+
139+
if open and is_grouped then
140+
M.ungroup_empty_folders(head_node)
141+
elseif open then
142+
M.group_empty_folders(head_node)
143+
end
144+
return is_grouped or not open
145+
end
146+
128147
---@param node Node
129-
function M.expand_or_collapse(node)
148+
function M.expand_or_collapse(node, toggle_group)
149+
toggle_group = toggle_group or false
130150
if node.has_children then
131151
node.has_children = false
132152
end
@@ -135,17 +155,16 @@ function M.expand_or_collapse(node)
135155
core.get_explorer():expand(node)
136156
end
137157

138-
local open = M.get_last_group_node(node).open
139158
local head_node = utils.get_parent_of_group(node)
140-
local is_grouped = head_node.group_next ~= nil
141-
142-
if open and is_grouped then
143-
M.ungroup_empty_folders(head_node)
144-
elseif open then
145-
M.group_empty_folders(head_node)
159+
local open = M.get_last_group_node(node).open
160+
if toggle_group then
161+
open = toggle_group_folders(head_node, open)
162+
else
163+
open = not open
146164
end
165+
147166
for _, n in ipairs(M.get_all_nodes_in_group(head_node)) do
148-
n.open = is_grouped or not open
167+
n.open = open
149168
end
150169

151170
renderer.draw()

0 commit comments

Comments
 (0)