Skip to content

Commit 3041d15

Browse files
committed
feat(marks): add navigation next and previous
1 parent df92f15 commit 3041d15

File tree

5 files changed

+116
-12
lines changed

5 files changed

+116
-12
lines changed

doc/nvim-tree-lua.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,17 @@ You can toggle marks on files/folders with
12621262
default.
12631263

12641264
To get the list of marked paths, you can call
1265-
`require("nvim-tree.marks").get_marks()`. This will return `{string}`.
1265+
`require("nvim-tree.marks").get_marks()`. This will return `{node}`.
1266+
1267+
*nvim-tree.bookmarks.navigation*
1268+
1269+
Navigation for marks is not bound by default in nvim-tree because we don't
1270+
want to focus the tree view each time we wish to switch to another mark.
1271+
1272+
This requires binding bookmark navigation yourself.
1273+
1274+
-- in your lua configuration
1275+
vim.keymap.set("n", "<leader>mn", require("nvim-tree.marks.navigation").next)
1276+
vim.keymap.set("n", "<leader>mp", require("nvim-tree.marks.navigation").prev)
12661277

12671278
vim:tw=78:ts=4:sw=4:et:ft=help:norl:

lua/nvim-tree/actions/fs/create-file.lua

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,6 @@ local core = require "nvim-tree.core"
88

99
local M = {}
1010

11-
local function focus_file(file)
12-
local _, i = utils.find_node(core.get_explorer().nodes, function(node)
13-
return node.absolute_path == file
14-
end)
15-
require("nvim-tree.view").set_cursor { i + 1, 1 }
16-
end
17-
1811
local function create_file(file)
1912
if utils.file_exists(file) then
2013
print(file .. " already exists. Overwrite? y/n")
@@ -112,7 +105,7 @@ function M.fn(node)
112105
end
113106
-- INFO: defer needed when reload is automatic (watchers)
114107
vim.defer_fn(function()
115-
focus_file(new_file_path)
108+
utils.focus_file(new_file_path)
116109
end, 150)
117110
end)
118111
end

lua/nvim-tree/marks.lua renamed to lua/nvim-tree/marks/init.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ local NvimTreeMarks = {}
77
local M = {}
88

99
local function add_mark(node)
10-
NvimTreeMarks[node.absolute_path] = true
10+
NvimTreeMarks[node.absolute_path] = node
1111
M.draw()
1212
end
1313

@@ -30,8 +30,8 @@ end
3030

3131
function M.get_marks()
3232
local list = {}
33-
for k in pairs(NvimTreeMarks) do
34-
table.insert(list, k)
33+
for _, n in pairs(NvimTreeMarks) do
34+
table.insert(list, n)
3535
end
3636
return list
3737
end

lua/nvim-tree/marks/navigation.lua

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
local Iterator = require "nvim-tree.iterators.node-iterator"
2+
local core = require "nvim-tree.core"
3+
local Marks = require "nvim-tree.marks"
4+
local open_file = require "nvim-tree.actions.node.open-file"
5+
local utils = require "nvim-tree.utils"
6+
local lib = require "nvim-tree.lib"
7+
8+
local function get_prev_or_next_mark(node, idx_iter)
9+
local found_idx = -1
10+
local marks = Marks.get_marks()
11+
12+
for i, n in ipairs(marks) do
13+
if n.absolute_path == node.absolute_path then
14+
found_idx = i + idx_iter
15+
break
16+
end
17+
end
18+
19+
if found_idx == -1 then
20+
return
21+
end
22+
23+
if found_idx > #marks then
24+
found_idx = 1
25+
elseif found_idx == 0 then
26+
found_idx = #marks
27+
end
28+
29+
return marks[found_idx]
30+
end
31+
32+
local function get_nearest(node, where)
33+
local prev = nil
34+
local found = false
35+
36+
local next = Iterator.builder(core.get_explorer().nodes)
37+
:matcher(function() return found == true end)
38+
:recursor(function(n) return n.open and n.nodes end)
39+
:applier(function(n)
40+
if Marks.get_mark(n) then
41+
prev = n
42+
end
43+
if n.absolute_path == node.absolute_path then
44+
found = true
45+
end
46+
end)
47+
:iterate()
48+
49+
if found then
50+
if where == "next" then
51+
return next
52+
else
53+
return prev
54+
end
55+
end
56+
end
57+
58+
local function get(where, node)
59+
if not node then
60+
return Marks.get_marks()[1]
61+
end
62+
63+
local is_next = where == "next"
64+
if Marks.get_mark(node) then
65+
return get_prev_or_next_mark(node, is_next and 1 or -1)
66+
else
67+
return get_nearest(node, where)
68+
end
69+
end
70+
71+
local function navigate_to(where)
72+
return function(node)
73+
local next = get(where, node)
74+
if next and not next.nodes then
75+
open_file.fn("edit", next.absolute_path)
76+
elseif next then
77+
utils.focus_file(next.absolute_path)
78+
end
79+
end
80+
end
81+
82+
local function inject_node(f)
83+
return function()
84+
f(lib.get_node_at_cursor())
85+
end
86+
end
87+
88+
local M = {}
89+
90+
M.next = inject_node(navigate_to("next"))
91+
M.prev = inject_node(navigate_to("prev"))
92+
93+
return M

lua/nvim-tree/utils.lua

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,13 @@ function M.rename_loaded_buffers(old_path, new_path)
207207
end
208208
end
209209

210+
function M.focus_file(path)
211+
local _, i = M.find_node(require("nvim-tree.core").get_explorer().nodes, function(node)
212+
return node.absolute_path == path
213+
end)
214+
require("nvim-tree.view").set_cursor { i + 1, 1 }
215+
end
216+
210217
--- @param path string path to file or directory
211218
--- @return boolean
212219
function M.file_exists(path)

0 commit comments

Comments
 (0)