Skip to content

Commit 254753a

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 `m` keybinding to toggle the mark on the node. Users can call `require "nvim-tree.marks".get_marks()` which returns a list of absolute paths.
1 parent ad1f3ef commit 254753a

File tree

9 files changed

+94
-10
lines changed

9 files changed

+94
-10
lines changed

doc/nvim-tree-lua.txt

Lines changed: 3 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,7 @@ 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+
`m` toggle_mark Toggle node in bookmarks
10151017

10161018
>
10171019
view.mappings.list = { -- BEGIN_DEFAULT_MAPPINGS
@@ -1059,6 +1061,7 @@ DEFAULT MAPPINGS *nvim-tree-default-mappings
10591061
{ key = ".", action = "run_file_command" }
10601062
{ key = "<C-k>", action = "toggle_file_info" }
10611063
{ key = "g?", action = "toggle_help" }
1064+
{ key = "m", action = "toggle_mark" }
10621065
} -- END_DEFAULT_MAPPINGS
10631066
<
10641067
==============================================================================

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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ 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+
toggle_mark = require("nvim-tree.marks").toggle_mark,
4849
}
4950

5051
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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ local DEFAULT_MAPPINGS = {
227227
action = "toggle_help",
228228
desc = "toggle help",
229229
},
230+
{
231+
key = "m",
232+
action = "toggle_mark",
233+
desc = "Toggle node in bookmarks",
234+
},
230235
}
231236
-- END_DEFAULT_MAPPINGS
232237

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+
local NvimTreeMarks = {}
6+
7+
local M = {}
8+
9+
local function add_mark(node)
10+
NvimTreeMarks[node.absolute_path] = true
11+
M.draw()
12+
end
13+
14+
local function remove_mark(node)
15+
NvimTreeMarks[node.absolute_path] = nil
16+
M.draw()
17+
end
18+
19+
function M.toggle_mark(node)
20+
if M.get_mark(node) then
21+
remove_mark(node)
22+
else
23+
add_mark(node)
24+
end
25+
end
26+
27+
function M.get_mark(node)
28+
return NvimTreeMarks[node.absolute_path]
29+
end
30+
31+
function M.get_marks()
32+
local list = {}
33+
for k in pairs(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)