Skip to content

Commit 89becc7

Browse files
authored
feat(marks): add navigation (next, previous, select) (#1415)
1 parent b32c883 commit 89becc7

File tree

4 files changed

+116
-12
lines changed

4 files changed

+116
-12
lines changed

doc/nvim-tree-lua.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,4 +1264,16 @@ default.
12641264
To get the list of marked paths, you can call
12651265
`require("nvim-tree.marks").get_marks()`. This will return `{node}`.
12661266

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)
1277+
vim.keymap.set("n", "<leader>ms", require("nvim-tree.marks.navigation").select)
1278+
12671279
vim:tw=78:ts=4:sw=4:et:ft=help:norl:

lua/nvim-tree/actions/node/open-file.lua

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -220,17 +220,6 @@ local function open_in_new_window(filename, mode, win_ids)
220220
lib.set_target_win()
221221
end
222222

223-
local function is_already_open(filename, win_ids)
224-
for _, id in ipairs(win_ids) do
225-
if filename == api.nvim_buf_get_name(api.nvim_win_get_buf(id)) then
226-
api.nvim_set_current_win(id)
227-
return true
228-
end
229-
end
230-
231-
return false
232-
end
233-
234223
local function is_already_loaded(filename)
235224
for _, buf_id in ipairs(api.nvim_list_bufs()) do
236225
if api.nvim_buf_is_loaded(buf_id) and filename == api.nvim_buf_get_name(buf_id) then
@@ -258,7 +247,7 @@ function M.fn(mode, filename)
258247
local win_ids = api.nvim_tabpage_list_wins(tabpage)
259248
local buf_loaded = is_already_loaded(filename)
260249

261-
local found = is_already_open(filename, win_ids)
250+
local found = utils.is_in_displayed_buffer(filename)
262251
if found and mode == "preview" then
263252
return
264253
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_nearest(node, where)
9+
local first, prev, next, last = nil, nil, nil, nil
10+
local found = false
11+
12+
Iterator.builder(core.get_explorer().nodes)
13+
:recursor(function(n)
14+
return n.open and n.nodes
15+
end)
16+
:applier(function(n)
17+
if n.absolute_path == node.absolute_path then
18+
found = true
19+
return
20+
end
21+
22+
if not Marks.get_mark(n) then
23+
return
24+
end
25+
26+
last = n
27+
first = first or n
28+
29+
if found and not next then
30+
next = n
31+
end
32+
33+
if not found then
34+
prev = n
35+
end
36+
end)
37+
:iterate()
38+
39+
if not found then
40+
return
41+
end
42+
43+
if where == "next" then
44+
return next or first
45+
else
46+
return prev or last
47+
end
48+
end
49+
50+
local function get(where, node)
51+
if node then
52+
return get_nearest(node, where)
53+
end
54+
end
55+
56+
local function open_or_focus(node)
57+
if node and not node.nodes and not utils.is_in_displayed_buffer(node.absolute_path) then
58+
open_file.fn("edit", node.absolute_path)
59+
elseif node then
60+
utils.focus_file(node.absolute_path)
61+
end
62+
end
63+
64+
local function navigate_to(where)
65+
return function()
66+
local node = lib.get_node_at_cursor()
67+
local next = get(where, node)
68+
open_or_focus(next)
69+
end
70+
end
71+
72+
local M = {}
73+
74+
M.next = navigate_to "next"
75+
M.prev = navigate_to "prev"
76+
77+
function M.select()
78+
local list = vim.tbl_map(function(n)
79+
return n.absolute_path
80+
end, Marks.get_marks())
81+
82+
vim.ui.select(list, {
83+
prompt = "Select a file to open or a folder to focus",
84+
}, function(choice)
85+
if not choice or choice == "" then
86+
return
87+
end
88+
local node = Marks.get_mark { absolute_path = choice }
89+
open_or_focus(node)
90+
end)
91+
end
92+
93+
return M

lua/nvim-tree/utils.lua

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,4 +335,14 @@ function M.focus_file(path)
335335
require("nvim-tree.view").set_cursor { i + 1, 1 }
336336
end
337337

338+
function M.is_in_displayed_buffer(path)
339+
for _, w in pairs(vim.api.nvim_tabpage_list_wins(0)) do
340+
local b = vim.api.nvim_win_get_buf(w)
341+
if vim.api.nvim_buf_get_name(b) == path then
342+
return true
343+
end
344+
end
345+
return false
346+
end
347+
338348
return M

0 commit comments

Comments
 (0)