Skip to content

Commit 579785f

Browse files
committed
feat(bookmarks): add bookmark feature for nodes
Uses the signcolum to display the mark status. Marks are saved in memory for now, we'll see if we want to implement a filesystem save for the marks (would not be hard). Added keybindings: - ma -> add a mark on the node - md -> remove a mark from the node - M -> toggle the mark on the node Users can access the marks through `_G.NvimTreeMarks` which is a record of `{ [absolute_path] = true }`. They can call `require "nvim-tree.marks".get_marks()` which returns a list of absolute paths.
1 parent ad1f3ef commit 579785f

File tree

9 files changed

+112
-10
lines changed

9 files changed

+112
-10
lines changed

doc/nvim-tree-lua.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ Subsequent calls to setup will replace the previous configuration.
220220
glyphs = {
221221
default = "",
222222
symlink = "",
223+
bookmark = "",
223224
folder = {
224225
arrow_closed = "",
225226
arrow_open = "",
@@ -1012,6 +1013,9 @@ DEFAULT MAPPINGS *nvim-tree-default-mappings
10121013
`.` run_file_command enter vim command mode with the file the cursor is on
10131014
`<C-k>` toggle_file_info toggle a popup with file infos about the file under the cursor
10141015
`g?` toggle_help toggle help
1016+
`ma` add_mark Bookmark a node
1017+
`md` remove_mark Remove node from bookmarks
1018+
`M` toggle_mark Toggle node in bookmarks
10151019

10161020
>
10171021
view.mappings.list = { -- BEGIN_DEFAULT_MAPPINGS
@@ -1059,6 +1063,9 @@ DEFAULT MAPPINGS *nvim-tree-default-mappings
10591063
{ key = ".", action = "run_file_command" }
10601064
{ key = "<C-k>", action = "toggle_file_info" }
10611065
{ key = "g?", action = "toggle_help" }
1066+
{ key = "ma", action = "add_mark" }
1067+
{ key = "md", action = "remove_mark" }
1068+
{ key = "M", action = "toggle_mark" }
10621069
} -- END_DEFAULT_MAPPINGS
10631070
<
10641071
==============================================================================

lua/nvim-tree.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
469469
glyphs = {
470470
default = "",
471471
symlink = "",
472+
bookmark = "",
472473
folder = {
473474
arrow_closed = "",
474475
arrow_open = "",
@@ -674,6 +675,7 @@ function M.setup(conf)
674675
require("nvim-tree.lib").setup(opts)
675676
require("nvim-tree.renderer").setup(opts)
676677
require("nvim-tree.live-filter").setup(opts)
678+
require("nvim-tree.marks").setup(opts)
677679
if M.config.renderer.icons.show.file and pcall(require, "nvim-web-devicons") then
678680
require("nvim-web-devicons").setup()
679681
end

lua/nvim-tree/actions/dispatch.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ local Actions = {
4545
run_file_command = require("nvim-tree.actions.node.run-command").run_file_command,
4646
toggle_file_info = require("nvim-tree.actions.node.file-popup").toggle_file_info,
4747
system_open = require("nvim-tree.actions.node.system-open").fn,
48+
49+
-- mark
50+
toggle_mark = require("nvim-tree.marks").toggle_mark,
51+
add_mark = require("nvim-tree.marks").add_mark,
52+
remove_mark = require("nvim-tree.marks").remove_mark,
4853
}
4954

5055
local function handle_action_on_help_ui(action)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ function M.fn(node)
113113
-- INFO: defer needed when reload is automatic (watchers)
114114
vim.defer_fn(function()
115115
focus_file(new_file_path)
116-
end, 50)
116+
end, 150)
117117
end)
118118
end
119119

lua/nvim-tree/actions/init.lua

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,21 @@ local DEFAULT_MAPPINGS = {
227227
action = "toggle_help",
228228
desc = "toggle help",
229229
},
230+
{
231+
key = "ma",
232+
action = "add_mark",
233+
desc = "Bookmark a node",
234+
},
235+
{
236+
key = "md",
237+
action = "remove_mark",
238+
desc = "Remove node from bookmarks",
239+
},
240+
{
241+
key = "M",
242+
action = "toggle_mark",
243+
desc = "Toggle node in bookmarks",
244+
},
230245
}
231246
-- END_DEFAULT_MAPPINGS
232247

lua/nvim-tree/colors.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ local function get_hl_groups()
5353
WindowPicker = { gui = "bold", fg = "#ededed", bg = "#4493c8" },
5454
LiveFilterPrefix = { gui = "bold", fg = colors.purple },
5555
LiveFilterValue = { gui = "bold", fg = "#fff" },
56+
57+
Bookmark = { fg = colors.green },
5658
}
5759
end
5860

lua/nvim-tree/iterators/node-iterator.lua

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,25 @@ function NodeIterator:recursor(f)
3838
end
3939

4040
function NodeIterator:iterate()
41+
local iteration_count = 0
4142
local function iter(nodes)
42-
local i = 1
4343
for _, node in ipairs(nodes) do
4444
if self._filter_hidden(node) then
45+
iteration_count = iteration_count + 1
4546
if self._match(node) then
46-
return node, i
47+
return node, iteration_count
4748
end
48-
self._apply_fn_on_node(node)
49+
self._apply_fn_on_node(node, iteration_count)
4950
local children = self._recurse_with(node)
5051
if children then
51-
local n, idx = iter(children)
52-
i = i + idx
52+
local n = iter(children)
5353
if n then
54-
return n, i
54+
return n, iteration_count
5555
end
56-
else
57-
i = i + 1
5856
end
5957
end
6058
end
61-
return nil, i
59+
return nil, 0
6260
end
6361

6462
return iter(self.nodes)

lua/nvim-tree/marks.lua

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
local view = require "nvim-tree.view"
2+
local Iterator = require "nvim-tree.iterators.node-iterator"
3+
local core = require "nvim-tree.core"
4+
5+
_G.NvimTreeMarks = {}
6+
7+
local M = {}
8+
9+
function M.add_mark(node)
10+
_G.NvimTreeMarks[node.absolute_path] = true
11+
M.draw()
12+
end
13+
14+
function M.get_mark(node)
15+
return _G.NvimTreeMarks[node.absolute_path]
16+
end
17+
18+
function M.remove_mark(node)
19+
_G.NvimTreeMarks[node.absolute_path] = nil
20+
M.draw()
21+
end
22+
23+
function M.toggle_mark(node)
24+
if M.get_mark(node) then
25+
M.remove_mark(node)
26+
else
27+
M.add_mark(node)
28+
end
29+
end
30+
31+
function M.get_marks()
32+
local list = {}
33+
for k in pairs(_G.NvimTreeMarks) do
34+
table.insert(list, k)
35+
end
36+
return list
37+
end
38+
39+
local GROUP = "NvimTreeMarkSigns"
40+
local SIGN_NAME = "NvimTreeMark"
41+
42+
function M.clear()
43+
vim.fn.sign_unplace(GROUP)
44+
end
45+
46+
function M.draw()
47+
if not view.is_visible() then
48+
return
49+
end
50+
51+
M.clear()
52+
53+
local buf = view.get_bufnr()
54+
Iterator.builder(core.get_explorer().nodes)
55+
:recursor(function(node)
56+
return node.open and node.nodes
57+
end)
58+
:applier(function(node, idx)
59+
if M.get_mark(node) then
60+
vim.fn.sign_place(0, GROUP, SIGN_NAME, buf, { lnum = idx + 1, priority = 3 })
61+
end
62+
end)
63+
:iterate()
64+
end
65+
66+
function M.setup(opts)
67+
vim.fn.sign_define(SIGN_NAME, { text = opts.renderer.icons.glyphs.bookmark, texthl = "NvimTreeBookmark" })
68+
end
69+
70+
return M

lua/nvim-tree/renderer/init.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ local help = require "nvim-tree.renderer.help"
1010
local git = require "nvim-tree.renderer.components.git"
1111
local Builder = require "nvim-tree.renderer.builder"
1212
local live_filter = require "nvim-tree.live-filter"
13+
local marks = require "nvim-tree.marks"
1314

1415
local api = vim.api
1516

@@ -88,8 +89,10 @@ function M.draw()
8889

8990
if view.is_help_ui() then
9091
diagnostics.clear()
92+
marks.clear()
9193
else
9294
diagnostics.update()
95+
marks.draw()
9396
end
9497

9598
view.grow_from_content()

0 commit comments

Comments
 (0)