diff --git a/README.md b/README.md index dae70a1..63f8741 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,35 @@ -# bookmarks.yazi +# Bookmarks.yazi A [Yazi](https://github.com/sxyazi/yazi) plugin that adds the basic functionality of [vi-like marks](https://neovim.io/doc/user/motion.html#mark-motions). -> [!NOTE] -> The latest main branch of Yazi is required at the moment. - https://github.com/dedukun/bookmarks.yazi/assets/25795432/9a9fe345-dd06-442e-99f1-8475ab22fad5 -## Installation - -```sh -# Linux/macOS -git clone https://github.com/dedukun/bookmarks.yazi.git ~/.config/yazi/plugins/bookmarks.yazi - -# Windows -git clone https://github.com/dedukun/bookmarks.yazi.git %AppData%\yazi\config\plugins\bookmarks.yazi -``` - ## Usage -Add this to your `keymap.toml`: - ```toml [[manager.prepend_keymap]] on = [ "m" ] -exec = "plugin bookmarks --args=save" -desc = "Save current position as a bookmark" +exec = "plugin bookmarks --sync --args='set'" +desc = "Set a bookmark" +``` +```toml [[manager.prepend_keymap]] on = [ "'" ] -exec = "plugin bookmarks --args=jump" +exec = "plugin bookmarks --sync --args='jump'" desc = "Jump to a bookmark" +``` +```toml [[manager.prepend_keymap]] on = [ "b", "d" ] -exec = "plugin bookmarks --args=delete" -desc = "Delete a bookmark" +exec = "plugin bookmarks --sync --args='delete'" +desc = "Jump to a bookmark" +``` +```toml [[manager.prepend_keymap]] on = [ "b", "D" ] -exec = "plugin bookmarks --args=delete_all" -desc = "Delete all bookmarks" +exec = "plugin bookmarks --sync --args='deleteall'" +desc = "Jump to a bookmark" ``` diff --git a/init.lua b/init.lua index b3a7ace..f070d62 100644 --- a/init.lua +++ b/init.lua @@ -14,20 +14,41 @@ local SUPPORTED_KEYS = { { on = "u"}, { on = "v"}, { on = "w"}, { on = "x"}, { on = "y"}, { on = "z"}, } -local save_bookmark = ya.sync(function(idx) +local function save_bookmark(idx) + if idx == -1 then + return + end + + local folder = Folder:by_kind(Folder.CURRENT) + + local key = SUPPORTED_KEYS[idx].on + state.bookmarks = state.bookmarks or {} - state.bookmarks[#state.bookmarks + 1] = { - on = SUPPORTED_KEYS[idx].on, - desc = tostring(folder.cwd), - cursor = Folder:by_kind(Folder.CURRENT).cursor, - } -end) + state.bookmarks[key] = { cursor = folder.cursor, path = tostring(folder.cwd) } +end -local all_bookmarks = ya.sync(function() return state.bookmarks or {} end) +local function jump_to_bookmark(bookmark) + state.bookmarks = state.bookmarks or {} -local delete_bookmark = ya.sync(function(idx) table.remove(state.bookmarks, idx) end) + local selected_bookmark = state.bookmarks[bookmark] -local delete_all_bookmarks = ya.sync(function() state.bookmarks = nil end) + ya.manager_emit("cd", { selected_bookmark.path }) + ya.manager_emit("arrow", { -99999999 }) + ya.manager_emit("arrow", { selected_bookmark.cursor }) +end + +local function delete_bookmark(bookmark) + state.bookmarks = state.bookmarks or {} + state.bookmarks[bookmark] = nil +end + +local function delete_all_bookmarks() + state.bookmarks = nil +end + +local function next(sync, args) + ya.manager_emit("plugin", { "bookmarks", sync = sync, args = table.concat(args, " ") }) +end return { entry = function(_, args) @@ -36,30 +57,67 @@ return { return end - if action == "save" then - local key = ya.which { cands = SUPPORTED_KEYS, silent = true } - if key then - save_bookmark(key) + if action == "set" then + local key = args[2] + if not key then + next(false, { "_set" }) + else + save_bookmark(tonumber(key)) end - return - end + elseif action == "_set" then + local key = ya.which({ + cands = SUPPORTED_KEYS, + silent = true, + }) - if action == "delete_all" then - return delete_all_bookmarks() - end + if not key then + -- selection was cancelled + return + end - local bookmarks = all_bookmarks() - local selected = #bookmarks > 0 and ya.which { cands = bookmarks } - if not selected then - return - end + next(true, { "set", key }) + elseif action == "jump" or action == "delete" then + local bookmark = args[2] + if not bookmark then + -- tried to use ya.sync but was unsuccessful, doing this way for the moment + if state.bookmarks then + local arguments = { "_" .. action } + for k, _ in pairs(state.bookmarks) do + table.insert(arguments, k) + table.insert(arguments, state.bookmarks[k].path) + end + next(false, arguments) + end + else + if action == "jump" then + jump_to_bookmark(bookmark) + elseif action == "delete" then + delete_bookmark(bookmark) + end + end + elseif action == "_jump" or action == "_delete" then + if #args == 1 then + -- Should never enter here, but just to be safe + return + end - if action == "jump" then - ya.manager_emit("cd", { bookmarks[selected].desc }) - ya.manager_emit("arrow", { -99999999 }) - ya.manager_emit("arrow", { bookmarks[selected].cursor }) - elseif action == "delete" then - delete_bookmark(selected) + local marked_keys = {} + for i = 2, #args, 2 do + table.insert(marked_keys, { on = args[i], desc = args[i + 1] }) + end + + local selected_bookmark = ya.which({ + cands = marked_keys, + }) + + if not selected_bookmark then + -- selection was cancelled + return + end + + next(true, { string.sub(action, 2), marked_keys[selected_bookmark].on }) + elseif action == "deleteall" then + delete_all_bookmarks() end end, }