-- with lazy.nvim
return {
"LintaoAmons/bookmarks.nvim",
-- tag = "v0.5.4", -- optional, pin the plugin at specific version for stability
dependencies = {
{"nvim-telescope/telescope.nvim"},
{"stevearc/dressing.nvim"} -- optional: to have the same UI shown in the GIF
}
}
return {
"LintaoAmons/bookmarks.nvim",
-- recommand, pin the plugin at specific version for stability
-- backup your db.json file when you want to upgrade the plugin
tag = "v1.4.1",
dependencies = {
{ "nvim-telescope/telescope.nvim" },
{ "stevearc/dressing.nvim" }, -- optional: to have the same UI shown in the GIF
},
config = function()
local opts = {
-- where you want to put your bookmarks db file (a simple readable json file, which you can edit manually as well)
json_db_path = vim.fs.normalize(vim.fn.stdpath("config") .. "/bookmarks.db.json"),
-- This is how the sign looks.
signs = {
mark = { icon = "", color = "red", line_bg = "#572626" },
},
picker = {
-- choose built-in sort logic by name: string, find all the sort logics in `bookmarks.adapter.sort-logic`
-- or custom sort logic: function(bookmarks: Bookmarks.Bookmark[]): nil
sort_by = "last_visited",
},
-- optional, backup the json db file when a new neovim session started and you try to mark a place
-- you can find the file under the same folder
enable_backup = true,
-- optional, show the result of the calibration when you try to calibrate the bookmarks
show_calibrate_result = true,
-- optional, auto calibrate the current buffer when you enter it
auto_calibrate_cur_buf = true,
-- treeview options
treeview = {
bookmark_format = function(bookmark)
if bookmark.name ~= "" then return bookmark.name else return "[No Name]" end
end,
keymap = {
quit = { "q", "<ESC>" },
refresh = "R",
create_folder = "a",
tree_cut = "x",
tree_paste = "p",
collapse = "o",
delete = "d",
active = "s",
copy = "c",
},
},
-- do whatever you like by hooks
hooks = {
{
---a sample hook that change the working directory when goto bookmark
---@param bookmark Bookmarks.Bookmark
---@param projects Bookmarks.Project[]
callback = function(bookmark, projects)
local project_path
for _, p in ipairs(projects) do
if p.name == bookmark.location.project_name then
project_path = p.path
end
end
if project_path then
vim.cmd("cd " .. project_path)
end
end,
},
},
}
require("bookmarks").setup(opts)
end,
}
There's two key concepts in this plugin: BookmarkList
and Bookmark
.
You can look into the code to find the structure of those two domain objects.
Command | Description |
---|---|
BookmarksMark |
Mark current line into active BookmarkList. Rename existing bookmark under cursor. Toggle it off if the new name is an empty string |
BookmarksGoto |
Go to bookmark at current active BookmarkList |
BookmarksCommands |
Find and trigger a bookmark command. |
BookmarksGotoRecent |
Go to latest visited/created Bookmark |
BookmarksEditJsonFile |
An shortcut to edit bookmark jsonfile |
BookmarksTree |
Display all bookmarks with tree-view, and use "cut", "paste", "create folder" to edit the tree. |
just because I don't know how to write Telescope extension, so I somehow do it this way.
Command | Description |
---|---|
[List] new | create a new BookmarkList and set it to active and mark current line into this BookmarkList |
[List] rename | rename a BookmarkList |
[List] delete | delete a bookmark list |
[List] set active | set a BookmarkList as active |
[List] Browsing all lists | |
[Mark] mark to list | bookmark current line and add it to specific bookmark list |
[Mark] rename bookmark | rename selected bookmark |
[Mark] Browsing all marks | |
[Mark] Bookmarks of current project | |
[Mark] grep the marked files | grep in all the files that contain bookmarks |
[Mark] delete bookmark | delete selected bookmarks |
Also if you want to bind a shortcut to those commands, you can do it by writing some code....
local function call_bookmark_command()
local commands = require("bookmarks.adapter.commands").commands
local command
for _, c in ipairs(commands) do
if c.name == "[Mark] Bookmarks of current project" then -- change it to one of the command above
command = c
end
end
if command then
command.callback()
end
end
vim.keymap.set("n", "<leader>ll", call_bookmark_command)
Check the tree section in the config to find out all the actions you can use.
This plugin doesn't provide any default keybinding. I recommend you to have these four keybindings.
vim.keymap.set({ "n", "v" }, "mm", "<cmd>BookmarksMark<cr>", { desc = "Mark current line into active BookmarkList." })
vim.keymap.set({ "n", "v" }, "mo", "<cmd>BookmarksGoto<cr>", { desc = "Go to bookmark at current active BookmarkList" })
vim.keymap.set({ "n", "v" }, "ma", "<cmd>BookmarksCommands<cr>", { desc = "Find and trigger a bookmark command." })
vim.keymap.set({ "n", "v" }, "mg", "<cmd>BookmarksGotoRecent<cr>", { desc = "Go to latest visited/created Bookmark" })
Don't hesitate to ask me anything about the codebase if you want to contribute.
By telegram or 微信: CateFat
plugin/bookmarks.lua
the entry point of the pluginlua/bookmarks/domain
where the main objects/concepts livelua/bookmarks/adapter
--> lua/bookmarks/api
--> lua/bookmarks/repo
--> json db!
considered as command.!newlist [listname]
bookmark current line into a newly created bookmark list and set the list as current active list.BookmarkCommands
commands picker, a picker allow user to trigger any bookmark command.u
undo. Expecially for unexpected d
deletesmart-open.nvim
[actor] -->actor sequance_number :: desc