Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow to expand until certain condition is met #2790

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion doc/nvim-tree-lua.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1808,10 +1808,29 @@ tree.collapse_all({keep_buffers}) *nvim-tree-api.tree.collapse_all()*
Parameters: ~
• {keep_buffers} (boolean) do not collapse nodes with open buffers.

tree.expand_all() *nvim-tree-api.tree.expand_all()*
tree.expand_all({opts}) *nvim-tree-api.tree.expand_all()*
Recursively expand all nodes in the tree.
Folder: only the nodes underneath that folder.

Parameters: ~
• {opts} (table) optional parameters

Options: ~
• {expand_until} (function) A function returning boolean that
specifies terminating condition for node/tree expansion. If not
provided the function that expands recursively entire node/tree will be
used.
Example: >

-- expand only 5 levels deep
local function my_expand(expansion_count, node)
local should_halt = expansion_count >= 5
return not should_halt
end

-- on_attach
vim.keymap.set('n', 'Z', api.tree.expand_all(node, { expand_until = my_expand }))
Copy link
Member

@alex-courtis alex-courtis Sep 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed to wrap this in a function:

  vim.keymap.set("n", "Z", function()
    api.tree.expand_all(nil, { expand_until = my_expand_until })
  end, opts("My Expand All"))

or

local function my_expand_all()
  api.tree.expand_all(nil, { expand_until = my_expand_until })
end
---
  vim.keymap.set("n", "Z", my_expand_all, opts("My Expand All"))

We've hit two edges in our documentation here:

  1. We don't specify how to inject a node when there are {opts} - this is the first one.
  2. We don't give instructions on the need to use a function when parameters are needed.

That's OK - we can add those in a follow up PR to keep this one clear: #2899

Pushed minimal doc update.

<
*nvim-tree-api.tree.toggle_enable_filters()*
tree.toggle_enable_filters()
Toggle |nvim-tree.filters.enable| all filters.
Expand Down
33 changes: 24 additions & 9 deletions lua/nvim-tree/actions/tree/modifiers/expand-all.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,37 @@ local function to_lookup_table(list)
end

---@param node Node
local function expand(node)
node = lib.get_last_group_node(node)
node.open = true
local function populate_node(node)
-- noop if it is a file
if node.nodes == nil then
return
end
if #node.nodes == 0 then
local cwd = node.link_to or node.absolute_path
local handle = vim.loop.fs_scandir(cwd)
if not handle then
return
end
core.get_explorer():expand(node)
end
end

---@param expansion_count integer
---@param node Node
---@return boolean
local function should_expand(expansion_count, node)
local function expand_until_max_or_empty(expansion_count, node)
local should_halt = expansion_count >= M.MAX_FOLDER_DISCOVERY
local should_exclude = M.EXCLUDE[node.name]
return not should_halt and node.nodes and not node.open and not should_exclude
end

local function gen_iterator()
local function gen_iterator(should_expand)
local expansion_count = 0
local function expand(node)
populate_node(node)
node = lib.get_last_group_node(node)
node.open = true
end

return function(parent)
if parent.parent and parent.nodes and not parent.open then
Expand All @@ -47,13 +59,14 @@ local function gen_iterator()
Iterator.builder(parent.nodes)
:hidden()
:applier(function(node)
if should_expand(expansion_count, node) then
if should_expand(expansion_count, node, populate_node) then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20240907_150214

This appears unused. Can we remove it?

expansion_count = expansion_count + 1
expand(node)
end
end)
:recursor(function(node)
return expansion_count < M.MAX_FOLDER_DISCOVERY and (node.group_next and { node.group_next } or (node.open and node.nodes))
local should_recurse = should_expand(expansion_count - 1, node, populate_node)
return expansion_count < M.MAX_FOLDER_DISCOVERY and should_recurse and node.nodes
end)
:iterate()

Expand All @@ -64,9 +77,11 @@ local function gen_iterator()
end

---@param base_node table
function M.fn(base_node)
---@param expand_opts ApiTreeExpandAllOpts|nil
function M.fn(base_node, expand_opts)
local expand_until = (expand_opts and expand_opts.expand_until) or expand_until_max_or_empty
local node = base_node.nodes and base_node or core.get_explorer()
if gen_iterator()(node) then
if gen_iterator(expand_until)(node) then
notify.warn("expansion iteration was halted after " .. M.MAX_FOLDER_DISCOVERY .. " discovered folders")
end
renderer.draw()
Expand Down
5 changes: 5 additions & 0 deletions lua/nvim-tree/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,12 @@ Api.tree.get_nodes = wrap(lib.get_nodes)
Api.tree.find_file = wrap(actions.tree.find_file.fn)
Api.tree.search_node = wrap(actions.finders.search_node.fn)
Api.tree.collapse_all = wrap(actions.tree.modifiers.collapse_all.fn)

---@class ApiTreeExpandAllOpts
---@field expand_until function|nil

Api.tree.expand_all = wrap_node(actions.tree.modifiers.expand_all.fn)

Api.tree.toggle_enable_filters = wrap(actions.tree.modifiers.toggles.enable)
Api.tree.toggle_gitignore_filter = wrap(actions.tree.modifiers.toggles.git_ignored)
Api.tree.toggle_git_clean_filter = wrap(actions.tree.modifiers.toggles.git_clean)
Expand Down
2 changes: 1 addition & 1 deletion lua/nvim-tree/explorer/node.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ end
---@param node Node
---@return boolean
function M.has_one_child_folder(node)
return #node.nodes == 1 and node.nodes[1].nodes and vim.loop.fs_access(node.nodes[1].absolute_path, "R") or false
return node.nodes ~= nil and #node.nodes == 1 and node.nodes[1].nodes and vim.loop.fs_access(node.nodes[1].absolute_path, "R") or false
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: guarding against calling this function with a file node

end

---@param node Node
Expand Down
Loading