Skip to content

Commit

Permalink
Merge pull request #50 from nfginola/goto_within_list
Browse files Browse the repository at this point in the history
Goto within list
  • Loading branch information
LintaoAmons authored Dec 28, 2024
2 parents 5ff9870 + cfde233 commit 4648756
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 20 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ Check the default config in [config.lua](./lua/bookmarks/config.lua)
| `BookmarksGoto` | Go to bookmark at current active BookmarkList |
| `BookmarksGotoNext` | Go to next bookmark in line number order within the current active BookmarkList |
| `BookmarksGotoPrev` | Go to previous bookmark in line number order within the current active BookmarkList |
| `BookmarksGotoNextInList` | Go to next bookmark by order id within the current active BookmarkList |
| `BookmarksGotoPrevInList` | Go to next bookmark by order id within the current active BookmarkList |
| `BookmarksDesc` | Add description to the bookmark under cursor, if no bookmark, then mark it first |
| `BookmarksTree` | Browse bookmarks in tree view |
| `BookmarksCommands` | Find bookmark commands and trigger it |
Expand Down
4 changes: 2 additions & 2 deletions lua/bookmarks/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ local default_config = {

-- Navigation configurations
navigation = {
-- Enable/disable wrap-around when navigating to next/previous bookmark
next_prev_wraparound = true,
-- Enable/disable wrap-around when navigating to next/previous bookmark within the same file
next_prev_wraparound_same_file = true,
},

-- Bookmarks sign configurations
Expand Down
92 changes: 79 additions & 13 deletions lua/bookmarks/domain/service.lua
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,66 @@ end

local FindDirection = { FORWARD = 0, BACKWARD = 1 }

--- finds the next bookmark in a given direction within the current active BookmarkList
--- finds the bookmark in a given direction by 'order id' within a BookmarkList
---@param callback fun(bookmark: Bookmarks.Node): nil
---@param direction
---@param fail_msg
local function find_closest_bookmark_in_order(callback, direction, fail_msg)
local enable_wraparound = vim.g.bookmarks_config.navigation.next_prev_wraparound
local active_list = Repo.ensure_and_get_active_list()
local bookmarks = Node.get_all_bookmarks(active_list)
---@param bookmark_list Bookmarks.Node
---@param direction number
---@param fail_msg string
local function find_bookmark_in_id_order(callback, bookmark_list, direction, fail_msg)
local bookmarks = Node.get_all_bookmarks(bookmark_list)
local cur_lnr = vim.api.nvim_win_get_cursor(0)[1]

if #bookmarks == 0 then
vim.notify("No bookmarks available in this BookmarkList", vim.log.levels.WARN)
return
end

-- sort in ascending by order id
table.sort(bookmarks, function(lhs, rhs)
return lhs.order < rhs.order
end)

-- find last visited bookmark in list
local bm_idx
local running_max = 0
for i, bookmark in ipairs(bookmarks) do
if bookmark.visited_at > running_max then
bm_idx = i
running_max = bookmark.visited_at
elseif bookmark.visited_at == running_max and bookmark.location.line == cur_lnr then
-- if at least two bookmarks have same visited time, goto is being performed
-- too fast for time tracking to keep up
-- default to bookmark under cursor as last visited
bm_idx = i
break
end
end

local selected_bm
-- circular traverse
if direction == FindDirection.FORWARD then
selected_bm = bookmarks[(bm_idx - 1 + 1) % #bookmarks + 1]
elseif direction == FindDirection.BACKWARD then
selected_bm = bookmarks[(bm_idx - 1 - 1) % #bookmarks + 1]
else
error("Invalid direction, not a valid call to this function")
end

if selected_bm then
callback(selected_bm)
else
vim.notify(fail_msg, vim.log.levels.WARN)
end
end

--- finds the bookmark in a given direction in 'line order' within a BookmarkList
---@param callback fun(bookmark: Bookmarks.Node): nil
---@param bookmark_list Bookmarks.Node
---@param direction number
---@param fail_msg string
local function find_closest_bookmark_in_line_order(callback, bookmark_list, direction, fail_msg)
local enable_wraparound = vim.g.bookmarks_config.navigation.next_prev_wraparound_same_file
local bookmarks = Node.get_all_bookmarks(bookmark_list)
local filepath = vim.fn.expand("%:p")
local cur_lnr = vim.api.nvim_win_get_cursor(0)[1]
local file_bms = {}
Expand All @@ -155,7 +207,7 @@ local function find_closest_bookmark_in_order(callback, direction, fail_msg)
end

if #file_bms == 0 then
vim.notify("No bookmarks available in this buffer", vim.log.levels.WARN)
vim.notify("No bookmarks available in this file", vim.log.levels.WARN)
return
end

Expand Down Expand Up @@ -203,15 +255,29 @@ end

--- finds the next bookmark in line number order within the current active BookmarkList
---@param callback fun(bookmark: Bookmarks.Node): nil
function M.find_next_bookmark(callback)
find_closest_bookmark_in_order(callback, FindDirection.FORWARD,
"No next bookmark found within the active BookmarkList")
function M.find_next_bookmark_line_order(callback)
find_closest_bookmark_in_line_order(callback, Repo.ensure_and_get_active_list(), FindDirection.FORWARD,
"No next bookmark found within the active BookmarkList in this file")
end

--- finds the previous bookmark in line number order within the current active BookmarkList
---@param callback fun(bookmark: Bookmarks.Node): nil
function M.find_prev_bookmark(callback)
find_closest_bookmark_in_order(callback, FindDirection.BACKWARD,
function M.find_prev_bookmark_line_order(callback)
find_closest_bookmark_in_line_order(callback, Repo.ensure_and_get_active_list(), FindDirection.BACKWARD,
"No previous bookmark found within the active BookmarkList in this file")
end

--- finds the next bookmark by order id within the current active BookmarkList
---@param callback fun(bookmark: Bookmarks.Node): nil
function M.find_next_bookmark_id_order(callback)
find_bookmark_in_id_order(callback, Repo.ensure_and_get_active_list(), FindDirection.FORWARD,
"No next bookmark found within the active BookmarkList")
end

--- finds the previous bookmark by order id within the current active BookmarkList
---@param callback fun(bookmark: Bookmarks.Node): nil
function M.find_prev_bookmark_id_order(callback)
find_bookmark_in_id_order(callback, Repo.ensure_and_get_active_list(), FindDirection.BACKWARD,
"No previous bookmark found within the active BookmarkList")
end

Expand Down
23 changes: 21 additions & 2 deletions lua/bookmarks/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ M.goto_bookmark = function()
end

M.goto_next_bookmark = function()
Service.find_next_bookmark(function(bookmark)
Service.find_next_bookmark_line_order(function(bookmark)
if bookmark then
Service.goto_bookmark(bookmark.id)
Sign.safe_refresh_signs()
Expand All @@ -41,14 +41,33 @@ M.goto_next_bookmark = function()
end

M.goto_prev_bookmark = function()
Service.find_prev_bookmark(function(bookmark)
Service.find_prev_bookmark_line_order(function(bookmark)
if bookmark then
Service.goto_bookmark(bookmark.id)
Sign.safe_refresh_signs()
end
end)
end

M.goto_next_list_bookmark = function()
Service.find_next_bookmark_id_order(function(bookmark)
if bookmark then
Service.goto_bookmark(bookmark.id)
Sign.safe_refresh_signs()
end
end)
end

M.goto_prev_list_bookmark = function()
Service.find_prev_bookmark_id_order(function(bookmark)
if bookmark then
Service.goto_bookmark(bookmark.id)
Sign.safe_refresh_signs()
end
end)
end


M.grep_bookmarks = function()
require("bookmarks.picker").grep_bookmark()
end
Expand Down
22 changes: 19 additions & 3 deletions plugin/bookmarks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ vim.g.bookmark_tree_view_ctx = nil
local bookmarks = require("bookmarks")

vim.api.nvim_create_user_command("BookmarksMark", bookmarks.toggle_mark, {
desc = "Mark current line into active BookmarkList. Rename existing bookmark under cursor. Toggle it off if the new name is an empty string",
desc =
"Mark current line into active BookmarkList. Rename existing bookmark under cursor. Toggle it off if the new name is an empty string",
})

vim.api.nvim_create_user_command("BookmarksDesc", bookmarks.attach_desc, {
Expand All @@ -43,6 +44,19 @@ vim.api.nvim_create_user_command(
{ desc = "Go to previous bookmark in line number order within the current active BookmarkList" }
)

vim.api.nvim_create_user_command(
"BookmarksGotoNextInList",
bookmarks.goto_next_list_bookmark,
{ desc = "Go to next bookmark within the current active BookmarkList" }
)

vim.api.nvim_create_user_command(
"BookmarksGotoPrevInList",
bookmarks.goto_prev_list_bookmark,
{ desc = "Go to previous bookmark within the current active BookmarkList" }
)


vim.api.nvim_create_user_command(
"BookmarksGrep",
bookmarks.grep_bookmarks,
Expand All @@ -60,7 +74,8 @@ vim.api.nvim_create_user_command(
vim.api.nvim_create_user_command("BookmarksInfo", bookmarks.info, { desc = "Show bookmark.nvim plugin info" })

-- TODO: find a better way to do this
vim.api.nvim_create_user_command("BookmarksInfoCurrentBookmark", bookmarks.bookmark_info, { desc = "Show bookmark.nvim plugin info" })
vim.api.nvim_create_user_command("BookmarksInfoCurrentBookmark", bookmarks.bookmark_info,
{ desc = "Show bookmark.nvim plugin info" })

vim.api.nvim_create_user_command(
"BookmarksCommands",
Expand All @@ -70,4 +85,5 @@ vim.api.nvim_create_user_command(

vim.api.nvim_create_user_command("BookmarksTree", bookmarks.toggle_treeview, { desc = "browse bookmarks in tree view" })

vim.api.nvim_create_user_command("BookmarkRebindOrphanNode", bookmarks.rebind_orphan_node, { desc = "rebind the orphaned node to the root node" })
vim.api.nvim_create_user_command("BookmarkRebindOrphanNode", bookmarks.rebind_orphan_node,
{ desc = "rebind the orphaned node to the root node" })

0 comments on commit 4648756

Please sign in to comment.