feat: add node.open.toggle_group_empty, default mapping L (#2647)
* feat: ungrouping empty directories * add a new api to toggle empty folders * solve comments * solve comments * update help --------- Co-authored-by: juefei yan <juefeiyan@juefeis-MacBook-Air.local> Co-authored-by: Alexander Courtis <alex@courtis.org>
This commit is contained in:
parent
f39f7b6fcd
commit
8cbb1db8e9
@ -181,6 +181,7 @@ Show the mappings: `g?`
|
||||
`I` Toggle Filter: Git Ignore |nvim-tree-api.tree.toggle_gitignore_filter()|
|
||||
`J` Last Sibling |nvim-tree-api.node.navigate.sibling.last()|
|
||||
`K` First Sibling |nvim-tree-api.node.navigate.sibling.first()|
|
||||
`L` Toggle Group Empty |nvim-tree-api.node.open.toggle_group_empty()|
|
||||
`M` Toggle Filter: No Bookmark |nvim-tree-api.tree.toggle_no_bookmark_filter()|
|
||||
`m` Toggle Bookmark |nvim-tree-api.marks.toggle()|
|
||||
`o` Open |nvim-tree-api.node.open.edit()|
|
||||
@ -1848,6 +1849,12 @@ node.open.vertical() *nvim-tree-api.node.open.vertical()*
|
||||
node.open.horizontal() *nvim-tree-api.node.open.horizontal()*
|
||||
|nvim-tree-api.node.edit()|, file will be opened in a new horizontal split.
|
||||
|
||||
*nvim-tree-api.node.open.toggle_group_empty()*
|
||||
node.open.toggle_group_empty()
|
||||
Toggle |nvim-tree.renderer.group_empty| for a specific folder.
|
||||
Does nothing on files.
|
||||
Needs |nvim-tree.renderer.group_empty| set.
|
||||
|
||||
node.open.drop() *nvim-tree-api.node.open.drop()*
|
||||
Switch to window with selected file if it exists.
|
||||
Open file otherwise.
|
||||
@ -2196,6 +2203,7 @@ You are encouraged to copy these to your own |nvim-tree.on_attach| function.
|
||||
vim.keymap.set('n', 'I', api.tree.toggle_gitignore_filter, opts('Toggle Filter: Git Ignore'))
|
||||
vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts('Last Sibling'))
|
||||
vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts('First Sibling'))
|
||||
vim.keymap.set('n', 'L', api.node.open.toggle_group_empty, opts('Toggle Group Empty'))
|
||||
vim.keymap.set('n', 'M', api.tree.toggle_no_bookmark_filter, opts('Toggle Filter: No Bookmark'))
|
||||
vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark'))
|
||||
vim.keymap.set('n', 'o', api.node.open.edit, opts('Open'))
|
||||
|
||||
@ -175,13 +175,13 @@ end
|
||||
|
||||
---@param mode string
|
||||
---@return fun(node: table)
|
||||
local function open_or_expand_or_dir_up(mode)
|
||||
local function open_or_expand_or_dir_up(mode, toggle_group)
|
||||
return function(node)
|
||||
if node.name == ".." then
|
||||
actions.root.change_dir.fn ".."
|
||||
elseif node.nodes then
|
||||
lib.expand_or_collapse(node)
|
||||
else
|
||||
lib.expand_or_collapse(node, toggle_group)
|
||||
elseif not toggle_group then
|
||||
edit(mode, node)
|
||||
end
|
||||
end
|
||||
@ -195,6 +195,7 @@ Api.node.open.no_window_picker = wrap_node(open_or_expand_or_dir_up "edit_no_pic
|
||||
Api.node.open.vertical = wrap_node(open_or_expand_or_dir_up "vsplit")
|
||||
Api.node.open.horizontal = wrap_node(open_or_expand_or_dir_up "split")
|
||||
Api.node.open.tab = wrap_node(open_or_expand_or_dir_up "tabnew")
|
||||
Api.node.open.toggle_group_empty = wrap_node(open_or_expand_or_dir_up("toggle_group_empty", true))
|
||||
Api.node.open.preview = wrap_node(open_or_expand_or_dir_up "preview")
|
||||
Api.node.open.preview_no_picker = wrap_node(open_or_expand_or_dir_up "preview_no_picker")
|
||||
|
||||
|
||||
@ -72,6 +72,7 @@ function M.default_on_attach(bufnr)
|
||||
vim.keymap.set('n', 'I', api.tree.toggle_gitignore_filter, opts('Toggle Filter: Git Ignore'))
|
||||
vim.keymap.set('n', 'J', api.node.navigate.sibling.last, opts('Last Sibling'))
|
||||
vim.keymap.set('n', 'K', api.node.navigate.sibling.first, opts('First Sibling'))
|
||||
vim.keymap.set('n', 'L', api.node.open.toggle_group_empty, opts('Toggle Group Empty'))
|
||||
vim.keymap.set('n', 'M', api.tree.toggle_no_bookmark_filter, opts('Toggle Filter: No Bookmark'))
|
||||
vim.keymap.set('n', 'm', api.marks.toggle, opts('Toggle Bookmark'))
|
||||
vim.keymap.set('n', 'o', api.node.open.edit, opts('Open'))
|
||||
|
||||
@ -3,6 +3,7 @@ local view = require "nvim-tree.view"
|
||||
local core = require "nvim-tree.core"
|
||||
local utils = require "nvim-tree.utils"
|
||||
local events = require "nvim-tree.events"
|
||||
local explorer_node = require "nvim-tree.explorer.node"
|
||||
|
||||
---@class LibOpenOpts
|
||||
---@field path string|nil path
|
||||
@ -86,6 +87,34 @@ function M.get_last_group_node(node)
|
||||
return node
|
||||
end
|
||||
|
||||
---Group empty folders
|
||||
-- Recursively group nodes
|
||||
---@param node Node
|
||||
---@return Node[]
|
||||
function M.group_empty_folders(node)
|
||||
local is_root = not node.parent
|
||||
local child_folder_only = explorer_node.has_one_child_folder(node) and node.nodes[1]
|
||||
if M.group_empty and not is_root and child_folder_only then
|
||||
node.group_next = child_folder_only
|
||||
local ns = M.group_empty_folders(child_folder_only)
|
||||
node.nodes = ns or {}
|
||||
return ns
|
||||
end
|
||||
return node.nodes
|
||||
end
|
||||
|
||||
---Ungroup empty folders
|
||||
-- If a node is grouped, ungroup it: put node.group_next to the node.nodes and set node.group_next to nil
|
||||
---@param node Node
|
||||
function M.ungroup_empty_folders(node)
|
||||
local cur = node
|
||||
while cur and cur.group_next do
|
||||
cur.nodes = { cur.group_next }
|
||||
cur.group_next = nil
|
||||
cur = cur.nodes[1]
|
||||
end
|
||||
end
|
||||
|
||||
---@param node Node
|
||||
---@return Node[]
|
||||
function M.get_all_nodes_in_group(node)
|
||||
@ -98,8 +127,21 @@ function M.get_all_nodes_in_group(node)
|
||||
return nodes
|
||||
end
|
||||
|
||||
-- Toggle group empty folders
|
||||
---@param head_node Node
|
||||
local function toggle_group_folders(head_node)
|
||||
local is_grouped = head_node.group_next ~= nil
|
||||
|
||||
if is_grouped then
|
||||
M.ungroup_empty_folders(head_node)
|
||||
else
|
||||
M.group_empty_folders(head_node)
|
||||
end
|
||||
end
|
||||
|
||||
---@param node Node
|
||||
function M.expand_or_collapse(node)
|
||||
function M.expand_or_collapse(node, toggle_group)
|
||||
toggle_group = toggle_group or false
|
||||
if node.has_children then
|
||||
node.has_children = false
|
||||
end
|
||||
@ -108,9 +150,20 @@ function M.expand_or_collapse(node)
|
||||
core.get_explorer():expand(node)
|
||||
end
|
||||
|
||||
local open = not M.get_last_group_node(node).open
|
||||
for _, n in ipairs(M.get_all_nodes_in_group(node)) do
|
||||
n.open = open
|
||||
local head_node = utils.get_parent_of_group(node)
|
||||
if toggle_group then
|
||||
toggle_group_folders(head_node)
|
||||
end
|
||||
|
||||
local open = M.get_last_group_node(node).open
|
||||
local next_open
|
||||
if toggle_group then
|
||||
next_open = open
|
||||
else
|
||||
next_open = not open
|
||||
end
|
||||
for _, n in ipairs(M.get_all_nodes_in_group(head_node)) do
|
||||
n.open = next_open
|
||||
end
|
||||
|
||||
renderer.draw()
|
||||
@ -213,6 +266,7 @@ function M.setup(opts)
|
||||
M.hijack_directories = opts.hijack_directories
|
||||
M.respect_buf_cwd = opts.respect_buf_cwd
|
||||
M.select_prompts = opts.select_prompts
|
||||
M.group_empty = opts.renderer.group_empty
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
Loading…
Reference in New Issue
Block a user