Skip to content

Commit 8ce1931

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

File tree

5 files changed

+120
-12
lines changed

5 files changed

+120
-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: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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()
38+
return found == true
39+
end)
40+
:recursor(function(n)
41+
return n.open and n.nodes
42+
end)
43+
:applier(function(n)
44+
if Marks.get_mark(n) then
45+
prev = n
46+
end
47+
if n.absolute_path == node.absolute_path then
48+
found = true
49+
end
50+
end)
51+
:iterate()
52+
53+
if found then
54+
if where == "next" then
55+
return next
56+
else
57+
return prev
58+
end
59+
end
60+
end
61+
62+
local function get(where, node)
63+
if not node then
64+
return Marks.get_marks()[1]
65+
end
66+
67+
local is_next = where == "next"
68+
if Marks.get_mark(node) then
69+
return get_prev_or_next_mark(node, is_next and 1 or -1)
70+
else
71+
return get_nearest(node, where)
72+
end
73+
end
74+
75+
local function navigate_to(where)
76+
return function(node)
77+
local next = get(where, node)
78+
if next and not next.nodes then
79+
open_file.fn("edit", next.absolute_path)
80+
elseif next then
81+
utils.focus_file(next.absolute_path)
82+
end
83+
end
84+
end
85+
86+
local function inject_node(f)
87+
return function()
88+
f(lib.get_node_at_cursor())
89+
end
90+
end
91+
92+
local M = {}
93+
94+
M.next = inject_node(navigate_to "next")
95+
M.prev = inject_node(navigate_to "prev")
96+
97+
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)