Skip to content

Commit 5f4b5b7

Browse files
committed
feat(live-filter): add ability to live filter out nodes in the tree
1 parent 00fd8ae commit 5f4b5b7

File tree

10 files changed

+323
-162
lines changed

10 files changed

+323
-162
lines changed

lua/nvim-tree/actions/find-file.lua

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,35 +29,37 @@ function M.fn(fname)
2929

3030
local function iterate_nodes(nodes)
3131
for _, node in ipairs(nodes) do
32-
i = i + 1
32+
if not node.hidden then
33+
i = i + 1
3334

34-
if not node.absolute_path or not uv.fs_stat(node.absolute_path) then
35-
break
36-
end
37-
38-
-- match against node absolute and link, as symlinks themselves will differ
39-
if node.absolute_path == fname_real or node.link_to == fname_real then
40-
return i
41-
end
42-
local abs_match = vim.startswith(fname_real, node.absolute_path .. utils.path_separator)
43-
local link_match = node.link_to and vim.startswith(fname_real, node.link_to .. utils.path_separator)
44-
local path_matches = node.nodes and (abs_match or link_match)
45-
if path_matches then
46-
if not node.open then
47-
node.open = true
48-
tree_altered = true
35+
if not node.absolute_path or not uv.fs_stat(node.absolute_path) then
36+
break
4937
end
5038

51-
if #node.nodes == 0 then
52-
core.get_explorer():expand(node)
39+
-- match against node absolute and link, as symlinks themselves will differ
40+
if node.absolute_path == fname_real or node.link_to == fname_real then
41+
return i
5342
end
43+
local abs_match = vim.startswith(fname_real, node.absolute_path .. utils.path_separator)
44+
local link_match = node.link_to and vim.startswith(fname_real, node.link_to .. utils.path_separator)
45+
local path_matches = node.nodes and (abs_match or link_match)
46+
if path_matches then
47+
if not node.open then
48+
node.open = true
49+
tree_altered = true
50+
end
5451

55-
if iterate_nodes(node.nodes) ~= nil then
56-
return i
52+
if #node.nodes == 0 then
53+
core.get_explorer():expand(node)
54+
end
55+
56+
if iterate_nodes(node.nodes) ~= nil then
57+
return i
58+
end
59+
-- mandatory to iterate i
60+
elseif node.open then
61+
iterate_nodes(node.nodes)
5762
end
58-
-- mandatory to iterate i
59-
elseif node.open then
60-
iterate_nodes(node.nodes)
6163
end
6264
end
6365
end

lua/nvim-tree/actions/init.lua

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ local M = {
4040
{ key = "]c", action = "next_git_item" },
4141
{ key = "-", action = "dir_up" },
4242
{ key = "s", action = "system_open" },
43+
{ key = "f", action = "live_filter" },
4344
{ key = "q", action = "close" },
4445
{ key = "g?", action = "toggle_help" },
4546
{ key = "W", action = "collapse_all" },
@@ -65,6 +66,7 @@ local keypress_funcs = {
6566
first_sibling = require("nvim-tree.actions.movements").sibling(-math.huge),
6667
full_rename = require("nvim-tree.actions.rename-file").fn(true),
6768
last_sibling = require("nvim-tree.actions.movements").sibling(math.huge),
69+
live_filter = require("nvim-tree.live-filter").start_filtering,
6870
next_git_item = require("nvim-tree.actions.movements").find_git_item "next",
6971
next_sibling = require("nvim-tree.actions.movements").sibling(1),
7072
parent_node = require("nvim-tree.actions.movements").parent_node(false),
@@ -92,6 +94,11 @@ function M.on_keypress(action)
9294
if view.is_help_ui() and action ~= "toggle_help" then
9395
return
9496
end
97+
98+
if action == "live_filter" then
99+
return keypress_funcs[action]()
100+
end
101+
95102
local node = lib.get_node_at_cursor()
96103
if not node then
97104
return

lua/nvim-tree/actions/movements.lua

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ local view = require "nvim-tree.view"
33
local diagnostics = require "nvim-tree.diagnostics"
44
local renderer = require "nvim-tree.renderer"
55
local core = require "nvim-tree.core"
6-
76
local lib = function()
87
return require "nvim-tree.lib"
98
end
@@ -20,16 +19,18 @@ local function get_line_from_node(node, find_parent)
2019
local line = core.get_nodes_starting_line()
2120
local function iter(nodes, recursive)
2221
for _, _node in ipairs(nodes) do
23-
local n = lib().get_last_group_node(_node)
24-
if node_path == n.absolute_path then
25-
return line, _node
26-
end
22+
if not _node.hidden then
23+
local n = lib().get_last_group_node(_node)
24+
if node_path == n.absolute_path then
25+
return line, _node
26+
end
2727

28-
line = line + 1
29-
if _node.open == true and recursive then
30-
local _, child = iter(_node.nodes, recursive)
31-
if child ~= nil then
32-
return line, child
28+
line = line + 1
29+
if _node.open == true and recursive then
30+
local _, child = iter(_node.nodes, recursive)
31+
if child ~= nil then
32+
return line, child
33+
end
3334
end
3435
end
3536
end
@@ -38,36 +39,28 @@ local function get_line_from_node(node, find_parent)
3839
end
3940

4041
function M.parent_node(should_close)
42+
should_close = should_close or false
43+
4144
return function(node)
4245
if node.name == ".." then
4346
return
4447
end
4548

46-
should_close = should_close or false
47-
local altered_tree = false
48-
49-
local iter = get_line_from_node(node, true)
49+
local line, parent = get_line_from_node(node, true)(core.get_explorer().nodes, true)
5050
if node.open == true and should_close then
5151
node.open = false
52-
altered_tree = true
52+
view.set_cursor { line, 0 }
5353
else
54-
local line, parent = iter(core.get_explorer().nodes, true)
5554
if parent == nil then
5655
line = 1
5756
elseif should_close then
5857
parent.open = false
59-
altered_tree = true
60-
end
61-
if not view.is_root_folder_visible(core.get_cwd()) then
62-
line = line - 1
6358
end
6459
view.set_cursor { line, 0 }
6560
end
6661

67-
if altered_tree then
68-
diagnostics.update()
69-
renderer.draw()
70-
end
62+
diagnostics.update()
63+
renderer.draw()
7164
end
7265
end
7366

@@ -91,7 +84,7 @@ function M.sibling(direction)
9184
end
9285

9386
if line > 0 then
94-
parent = core.get_explorer()
87+
parent = core.get_explorer().nodes
9588
else
9689
_, parent = iter(core.get_explorer().nodes, true)
9790
if parent ~= nil and #parent.nodes > 1 then
@@ -111,9 +104,6 @@ function M.sibling(direction)
111104
local target_node = parent.nodes[index]
112105

113106
line, _ = get_line_from_node(target_node)(core.get_explorer().nodes, true)
114-
if not view.is_root_folder_visible(core.get_cwd()) then
115-
line = line - 1
116-
end
117107
view.set_cursor { line, 0 }
118108
end
119109
end

lua/nvim-tree/core.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
local events = require "nvim-tree.events"
22
local explorer = require "nvim-tree.explorer"
3+
local live_filter = require "nvim-tree.live-filter"
34
local view = require "nvim-tree.view"
45

56
local M = {}
@@ -28,6 +29,9 @@ function M.get_nodes_starting_line()
2829
if view.is_root_folder_visible(M.get_cwd()) then
2930
offset = offset + 1
3031
end
32+
if live_filter.filter then
33+
return offset + 1
34+
end
3135
return offset
3236
end
3337

lua/nvim-tree/explorer/explore.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ local builders = require "nvim-tree.explorer.node-builders"
66
local common = require "nvim-tree.explorer.common"
77
local sorters = require "nvim-tree.explorer.sorters"
88
local filters = require "nvim-tree.explorer.filters"
9+
local live_filter = require "nvim-tree.live-filter"
910

1011
local M = {}
1112

@@ -66,6 +67,7 @@ function M.explore(node, status)
6667
end
6768

6869
sorters.merge_sort(node.nodes, sorters.node_comparator)
70+
live_filter.apply_filter(node)
6971
return node.nodes
7072
end
7173

lua/nvim-tree/explorer/reload.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ local builders = require "nvim-tree.explorer.node-builders"
66
local common = require "nvim-tree.explorer.common"
77
local filters = require "nvim-tree.explorer.filters"
88
local sorters = require "nvim-tree.explorer.sorters"
9+
local live_filter = require "nvim-tree.live-filter"
910

1011
local M = {}
1112

@@ -89,6 +90,7 @@ function M.reload(node, status)
8990
end
9091

9192
sorters.merge_sort(node.nodes, sorters.node_comparator)
93+
live_filter.apply_filter(node)
9294
return node.nodes
9395
end
9496

lua/nvim-tree/lib.lua

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ function M.get_nodes_by_line(nodes_all, line_start)
1414
local line = line_start
1515
local function iter(nodes)
1616
for _, node in ipairs(nodes) do
17-
nodes_by_line[line] = node
18-
line = line + 1
19-
if node.open == true then
20-
local child = iter(node.nodes)
21-
if child ~= nil then
22-
return child
17+
if not node.hidden then
18+
nodes_by_line[line] = node
19+
line = line + 1
20+
if node.open == true then
21+
local child = iter(node.nodes)
22+
if child ~= nil then
23+
return child
24+
end
2325
end
2426
end
2527
end
@@ -32,27 +34,25 @@ function M.get_node_at_cursor()
3234
if not core.get_explorer() then
3335
return
3436
end
37+
3538
local winnr = view.get_winnr()
36-
local hide_root_folder = view.View.hide_root_folder
3739
if not winnr then
3840
return
3941
end
42+
4043
local cursor = api.nvim_win_get_cursor(view.get_winnr())
4144
local line = cursor[1]
4245
if view.is_help_ui() then
4346
local help_lines = require("nvim-tree.renderer.help").compute_lines()
4447
local help_text = M.get_nodes_by_line(help_lines, 1)[line]
4548
return { name = help_text }
46-
else
47-
if line == 1 and core.get_explorer().cwd ~= "/" and not hide_root_folder then
48-
return { name = ".." }
49-
end
49+
end
5050

51-
if core.get_explorer().cwd == "/" then
52-
line = line + 1
53-
end
54-
return M.get_nodes_by_line(core.get_explorer().nodes, core.get_nodes_starting_line())[line]
51+
if line == 1 and view.is_root_folder_visible(core.get_cwd()) then
52+
return { name = ".." }
5553
end
54+
55+
return M.get_nodes_by_line(core.get_explorer().nodes, core.get_nodes_starting_line())[line]
5656
end
5757

5858
-- If node is grouped, return the last node in the group. Otherwise, return the given node.

0 commit comments

Comments
 (0)