48 Commits
0.2.5 ... main

Author SHA1 Message Date
Diogo Duarte
9ef1254d8a Merge pull request #52 from segur7g/patch-1
Update README.md
2025-07-09 22:24:49 +01:00
Diogo Duarte
fcf947a3e5 Merge pull request #50 from KaiExec/main
Add the support of higher version.
2025-07-09 22:23:08 +01:00
Diogo Duarte
320ac801ea Merge pull request #48 from nisemono0/show_saved_keys
Show keys when saving bookmark
2025-07-09 22:21:26 +01:00
Cristhian Betancur
e3b69263e1 Update README.md
A small update to the installation command on line 21
2025-06-21 04:47:45 -05:00
KaiExecutor
c6ea5aece0 Update README.md
Add the support of higher version.
2025-06-10 17:02:17 +08:00
nisemono0
c841641bfa Update README.md 2025-06-04 17:25:26 +03:00
nisemono0
0f27237688 Add option to show available keys when saving a bookmark
Useful to not accidentally overwrite a saved bookmark
2025-06-04 17:10:59 +03:00
Diogo Duarte
fbb7c00b6f Merge pull request #46 from kirpy0x/description-format
Make desk_format apply when creating new bookmarks
2025-05-06 11:22:24 +01:00
Richard Potter
3b6932eea6 Make desk_format apply when creating new bookmarks
fixes: https://github.com/dedukun/bookmarks.yazi/issues/45

If a user may choose to set multiple marks in the same parent dir for
various hovered items, this won't look good. They would be better off
setting desc_format = "full".

This is however closer to Ranger marks and will look clean for those who
only set one mark per directory.
2025-04-24 20:34:31 -06:00
Diogo Duarte
a70648a22b Merge branch 'main' of github.com:dedukun/bookmarks.yazi 2025-04-16 10:54:22 +01:00
Diogo Duarte
41536aac59 Removed deprecated functions + minimal yazi version is now v25.4.8 2025-04-16 10:54:10 +01:00
Diogo Duarte
95b2c586f4 Merge pull request #41 from dedukun/last_dir_mode
Add different behaviours for `last` jump
2025-02-26 10:25:55 +00:00
Diogo Duarte
430592ba57 Update README 2025-02-26 10:25:33 +00:00
Diogo Duarte
7a2f62fbb3 Change default mode to 'dir' 2025-02-26 10:23:59 +00:00
Diogo Duarte
d897f6b0bd Merge branch 'main' into last_dir_mode 2025-02-26 10:21:12 +00:00
Diogo Duarte
a7963b784a Merge pull request #40 from panda7789/feature/allow-custom-bookmark-description
Add custom bookmark description when creating
2025-02-26 10:19:13 +00:00
Diogo Duarte
e2614a18fc Save last_dir before jump 2025-02-23 22:30:33 +00:00
Linhart Lukáš
a0c8299704 formatting 2025-02-19 22:58:19 +01:00
Linhart Lukáš
2fc6a0a938 Add custom bookmark description when creating 2025-02-19 22:58:19 +01:00
Diogo Duarte
fe0b1de939 minimum required version is now Yazi v25.2.7 2025-02-18 11:15:14 +00:00
Diogo Duarte
023bde5a53 Add last modes 2025-02-18 11:07:42 +00:00
Diogo Duarte
420a384f51 Merge pull request #37 from dedukun/import-export-readme
Update README with import/export documentation
2025-02-16 18:42:41 +00:00
Diogo Duarte
af92d051ee Merge branch 'main' into import-export-readme 2025-02-16 18:42:05 +00:00
Diogo Duarte
3382460eb0 Update README.md 2025-02-16 18:38:11 +00:00
Diogo Duarte
14573ea884 Update README.md 2025-01-29 18:08:36 +00:00
Diogo Duarte
202e450b00 Update README.md 2025-01-07 14:58:11 +00:00
Diogo Duarte
5116df5e95 Remove deprecated code 2025-01-06 11:48:18 +00:00
Diogo Duarte
35da1073b7 Merge pull request #31 from wekauwau/main
Sort bookmarks when saving
2024-12-18 11:16:40 +00:00
wekauwau
a91fe1cb85 sort bookmarks when saving 2024-12-16 14:29:38 +07:00
Diogo Duarte
20ece7e1ef Add support in the entry function for Yazi stable release 2024-12-03 21:43:32 +00:00
Diogo Duarte
e755ebc1e6 Merge pull request #29 from TornaxO7/update-config
update config according to https://github.com/sxyazi/yazi/pull/1966
2024-12-02 16:28:38 +00:00
TornaxO7
d9b722a7e4 update config according to https://github.com/sxyazi/yazi/pull/1966 2024-11-29 17:36:50 +01:00
Diogo Duarte
600f87c021 Update README.md 2024-09-09 12:05:21 +01:00
Diogo Duarte
ae06e0c1c0 Merge pull request #24 from nralbrecht/bookmark_file_pick_mode
Add option to disable using hovered directory
2024-08-30 20:53:47 +01:00
nralbrecht
6769310fa2 Change to directory if the parent is stored
When storing a hovered file as bookmark it makes sense to use the reveal command to move to it. When storing the parent directory however, one has to cd to it. Otherwise the parent directory is opened and the stored directory is only focused.
2024-08-28 17:34:29 +02:00
nralbrecht
5b4258225b Rename bookmark_file_pick_mode option to file_pick_mode 2024-08-28 17:18:29 +02:00
nralbrecht
7ef1a95da1 Add bookmark_file_pick_mode option to README 2024-08-27 20:04:01 +02:00
nralbrecht
53ae96aed8 Rename bookmark_file_pick_mode option value from current to parent 2024-08-27 20:02:38 +02:00
nralbrecht
17702a3752 Add option to always pick the current folder and ignore hovered folder 2024-08-27 17:43:40 +02:00
Diogo Duarte
f65fa5e7e9 Merge pull request #23 from dedukun/save-last-bookmark
Save last bookmark
2024-08-18 17:11:49 +01:00
Diogo Duarte
5039aaa7d3 Update README.md 2024-08-14 09:56:02 +01:00
Diogo Duarte
944f7fd2b3 update README 2024-08-14 09:51:58 +01:00
Diogo Duarte
a5a4ea1bd1 Update README 2024-08-14 09:46:09 +01:00
Diogo Duarte
feffe662ee refactored last_directory configs + added persistence to last directory 2024-08-14 09:44:02 +01:00
Diogo Duarte
748efed3b9 Merge branch 'main' of github.com:dedukun/bookmarks.yazi 2024-07-14 19:56:48 +01:00
Diogo Duarte
b5dd86a7dd adapt to sxyazi/yazi#1257 2024-07-14 19:56:40 +01:00
Diogo Duarte
08b3f85c5d Update README.md 2024-06-28 21:34:39 +01:00
Diogo Duarte
15304f3535 Updated DDS interface 2024-06-24 13:05:31 +01:00
3 changed files with 462 additions and 299 deletions

View File

@@ -6,7 +6,7 @@ https://github.com/dedukun/bookmarks.yazi/assets/25795432/9a9fe345-dd06-442e-99f
## Requirements ## Requirements
- [Yazi](https://github.com/sxyazi/yazi) v0.2.5+ - [Yazi](https://github.com/sxyazi/yazi) v25.4.8+
## Features ## Features
@@ -17,59 +17,41 @@ https://github.com/dedukun/bookmarks.yazi/assets/25795432/9a9fe345-dd06-442e-99f
## Installation ## Installation
<details>
<summary>Yazi v0.2.5 (manual installation)</summary>
```sh ```sh
# Linux/macOS ya pkg add dedukun/bookmarks
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
``` ```
</details> ## Import/Export bookmarks
This plugin uses [Yazi's DDS](https://yazi-rs.github.io/docs/dds/) for bookmark persistence, as such,
the bookmarks are saved in DDS's state file (`~/.local/state/yazi/.dds` on Linux and `C:\Users\USERNAME\AppData\Roaming\yazi\state\.dds` on Windows)
<details> **_NOTE:_** This system may be used by other plugins that you have installed, so this file might have more data than just the bookmarks.
<summary>Latest commit in Yazi (package manager)</summary>
```sh
# Add the plugin
ya pack -a dedukun/bookmarks
# Install plugin
ya pack -i
# Update plugin
ya pack -u
```
</details>
## Configuration ## Configuration
Add this to your `keymap.toml`: Add this to your `keymap.toml`:
```toml ```toml
[[manager.prepend_keymap]] # If your yazi version is lower than v25.5.28, repleace "mgr" by "manager".
[[mgr.prepend_keymap]]
on = [ "m" ] on = [ "m" ]
run = "plugin bookmarks --args=save" run = "plugin bookmarks save"
desc = "Save current position as a bookmark" desc = "Save current position as a bookmark"
[[manager.prepend_keymap]] [[mgr.prepend_keymap]]
on = [ "'" ] on = [ "'" ]
run = "plugin bookmarks --args=jump" run = "plugin bookmarks jump"
desc = "Jump to a bookmark" desc = "Jump to a bookmark"
[[manager.prepend_keymap]] [[mgr.prepend_keymap]]
on = [ "b", "d" ] on = [ "b", "d" ]
run = "plugin bookmarks --args=delete" run = "plugin bookmarks delete"
desc = "Delete a bookmark" desc = "Delete a bookmark"
[[manager.prepend_keymap]] [[mgr.prepend_keymap]]
on = [ "b", "D" ] on = [ "b", "D" ]
run = "plugin bookmarks --args=delete_all" run = "plugin bookmarks delete_all"
desc = "Delete all bookmarks" desc = "Delete all bookmarks"
``` ```
@@ -81,9 +63,12 @@ The following are the default configurations:
```lua ```lua
-- ~/.config/yazi/init.lua -- ~/.config/yazi/init.lua
require("bookmarks"):setup({ require("bookmarks"):setup({
save_last_directory = false, last_directory = { enable = false, persist = false, mode="dir" },
persist = "none", persist = "none",
desc_format = "full", desc_format = "full",
file_pick_mode = "hover",
custom_desc_input = false,
show_keys = false,
notify = { notify = {
enable = false, enable = false,
timeout = 1, timeout = 1,
@@ -96,11 +81,21 @@ require("bookmarks"):setup({
}) })
``` ```
### `save_last_directory` ### `last_directory`
When enabled, a new bookmark is automatically created in `'` which allows the user to jump back to When enabled, a new bookmark is automatically created in `'` which allows the user to jump back to
the last directory. the last directory.
There's also the option to enable persistence to this automatic bookmark.
Finally, there's a `mode` option with the following options:
| Value | Description |
| ------ | ------------------------------------------------------------ |
| `jump` | It saves the position before the last used mark |
| `mark` | It saves the last created mark |
| `dir` | Default, it saves the last visited directory (old behaviour) |
### `persist` ### `persist`
When enabled the bookmarks will persist, i.e. if you close and reopen Yazi they will still be When enabled the bookmarks will persist, i.e. if you close and reopen Yazi they will still be
@@ -125,6 +120,17 @@ There are two possible values for this option:
| `full` | The default, it shows the full path of the bookmark, i.e., the parent folder + the hovered file | | `full` | The default, it shows the full path of the bookmark, i.e., the parent folder + the hovered file |
| `parent` | Only shows the parent folder of the bookmark | | `parent` | Only shows the parent folder of the bookmark |
### `file_pick_mode`
The mode for choosing which directory to bookmark.
There are two possible values for this option:
| Value | Description |
| -------- | ------------------------------------------------------------------- |
| `hover` | The default, it uses the path of the hovered file for new bookmarks |
| `parent` | Uses the path of the parent folder for new bookmarks |
### `notify` ### `notify`
When enabled, notifications will be shown when the user creates a new bookmark and deletes one or When enabled, notifications will be shown when the user creates a new bookmark and deletes one or
@@ -134,3 +140,19 @@ By default the notification has a 1 second timeout that can be changed with `not
Furthermore, you can customize the notification messages with `notify.message`. Furthermore, you can customize the notification messages with `notify.message`.
For the `new` and `delete` messages, the `<key>` and `<folder>` keywords can be used, which will be replaced by the respective new/deleted bookmark's associated key and folder. For the `new` and `delete` messages, the `<key>` and `<folder>` keywords can be used, which will be replaced by the respective new/deleted bookmark's associated key and folder.
### `custom_desc_input`
When enabled, user can change description for new bookmark before it is saved.
By default the custom description input is filled with path.
### `show_keys`
When enabled, saving a new bookmark will display a list of all available keys.
If a key already has a saved bookmark, its description will be shown.
This helps prevent accidental overwriting of existing bookmarks.
By default no information is shown.

264
init.lua
View File

@@ -1,264 +0,0 @@
-- stylua: ignore
local SUPPORTED_KEYS = {
{ on = "0"}, { on = "1"}, { on = "2"}, { on = "3"}, { on = "4"},
{ on = "5"}, { on = "6"}, { on = "7"}, { on = "8"}, { on = "9"},
{ on = "A"}, { on = "B"}, { on = "C"}, { on = "D"}, { on = "E"},
{ on = "F"}, { on = "G"}, { on = "H"}, { on = "I"}, { on = "J"},
{ on = "K"}, { on = "L"}, { on = "M"}, { on = "N"}, { on = "O"},
{ on = "P"}, { on = "Q"}, { on = "R"}, { on = "S"}, { on = "T"},
{ on = "U"}, { on = "V"}, { on = "W"}, { on = "X"}, { on = "Y"}, { on = "Z"},
{ on = "a"}, { on = "b"}, { on = "c"}, { on = "d"}, { on = "e"},
{ on = "f"}, { on = "g"}, { on = "h"}, { on = "i"}, { on = "j"},
{ on = "k"}, { on = "l"}, { on = "m"}, { on = "n"}, { on = "o"},
{ on = "p"}, { on = "q"}, { on = "r"}, { on = "s"}, { on = "t"},
{ on = "u"}, { on = "v"}, { on = "w"}, { on = "x"}, { on = "y"}, { on = "z"},
}
local _send_notification = ya.sync(
function(state, message)
ya.notify {
title = "Bookmarks",
content = message,
timeout = state.notify.timeout,
}
end
)
local _get_real_index = ya.sync(function(state, idx)
for key, value in pairs(state.bookmarks) do
if value.on == SUPPORTED_KEYS[idx].on then
return key
end
end
return nil
end)
local _get_hovered_file = ya.sync(function()
local folder = Folder:by_kind(Folder.CURRENT)
if not folder.hovered then
return { url = folder.cwd, is_cwd = true }
end
return { url = folder.hovered.url, is_cwd = false }
end)
local _generate_description = ya.sync(function(state, file)
-- if this is true, we don't have information about the folder, so just return the folder url
if file.is_cwd then
return tostring(file.url)
end
if state.desc_format == "parent" then
return tostring(file.url:parent())
end
-- full description
return tostring(file.url)
end)
local _load_state = ya.sync(function(state)
ps.sub_remote("bookmarks", function(body)
if not state.bookmarks and body then
state.bookmarks = {}
for _, value in pairs(body) do
table.insert(state.bookmarks, value)
end
end
end)
end)
local _save_state = ya.sync(function(state, bookmarks)
if not bookmarks then
ps.pub_static(10, "bookmarks", nil)
return
end
local save_state = {}
if state.persist == "all" then
save_state = bookmarks
else -- VIM mode
local idx = 1
for _, value in pairs(bookmarks) do
-- Only save bookmarks in upper case keys
if string.match(value.on, "%u") then
save_state[idx] = value
idx = idx + 1
end
end
end
ps.pub_static(10, "bookmarks", save_state)
end)
local _save_last_directory = ya.sync(function(state)
ps.sub("cd", function()
local file = _get_hovered_file()
state.last_dir = state.curr_dir
state.curr_dir = {
on = "'",
desc = _generate_description(file),
path = tostring(file.url),
}
end)
ps.sub("hover", function()
local file = _get_hovered_file()
state.curr_dir.desc = _generate_description(file)
state.curr_dir.path = tostring(file.url)
end)
end)
-- ***********************************************
-- **============= C O M M A N D S =============**
-- ***********************************************
local save_bookmark = ya.sync(function(state, idx)
local file = _get_hovered_file()
state.bookmarks = state.bookmarks or {}
local _idx = _get_real_index(idx)
if not _idx then
_idx = #state.bookmarks + 1
end
state.bookmarks[_idx] = {
on = SUPPORTED_KEYS[idx].on,
desc = _generate_description(file),
path = tostring(file.url),
}
if state.persist then
_save_state(state.bookmarks)
end
if state.notify and state.notify.enable then
local message = state.notify.message.new
message, _ = message:gsub("<key>", state.bookmarks[_idx].on)
message, _ = message:gsub("<folder>", state.bookmarks[_idx].desc)
_send_notification(message)
end
end)
local all_bookmarks = ya.sync(function(state, append_last_dir)
local bookmarks = {}
if state.bookmarks then
for _, value in pairs(state.bookmarks) do
table.insert(bookmarks, value)
end
end
if append_last_dir and state.last_dir then
table.insert(bookmarks, state.last_dir)
end
return bookmarks
end)
local delete_bookmark = ya.sync(function(state, idx)
if state.notify and state.notify.enable then
local message = state.notify.message.delete
message, _ = message:gsub("<key>", state.bookmarks[idx].on)
message, _ = message:gsub("<folder>", state.bookmarks[idx].desc)
_send_notification(message)
end
table.remove(state.bookmarks, idx)
if state.persist then
_save_state(state.bookmarks)
end
end)
local delete_all_bookmarks = ya.sync(function(state)
state.bookmarks = nil
if state.persist then
_save_state(nil)
end
if state.notify and state.notify.enable then
_send_notification(state.notify.message.delete_all)
end
end)
return {
entry = function(_, args)
local action = args[1]
if not action then
return
end
if action == "save" then
local key = ya.which { cands = SUPPORTED_KEYS, silent = true }
if key then
save_bookmark(key)
end
return
end
if action == "delete_all" then
return delete_all_bookmarks()
end
local bookmarks = all_bookmarks(action == "jump")
local selected = #bookmarks > 0 and ya.which { cands = bookmarks }
if not selected then
return
end
if action == "jump" then
ya.manager_emit("reveal", { bookmarks[selected].path })
elseif action == "delete" then
delete_bookmark(selected)
end
end,
setup = function(state, args)
if not args then
return
end
if args.save_last_directory then
_save_last_directory()
end
if args.persist == "all" or args.persist == "vim" then
state.persist = args.persist
_load_state()
end
if args.desc_format == "parent" then
state.desc_format = "parent"
else
state.desc_format = "full"
end
state.notify = {
enable = false,
timeout = 1,
message = {
new = "New bookmark '<key>' -> '<folder>'",
delete = "Deleted bookmark in '<key>'",
delete_all = "Deleted all bookmarks",
},
}
if type(args.notify) == "table" then
if type(args.notify.enable) == "boolean" then
state.notify.enable = args.notify.enable
end
if type(args.notify.timeout) == "number" then
state.notify.timeout = args.notify.timeout
end
if type(args.notify.message) == "table" then
if type(args.notify.message.new) == "string" then
state.notify.message.new = args.notify.message.new
end
if type(args.notify.message.delete) == "string" then
state.notify.message.delete = args.notify.message.delete
end
if type(args.notify.message.delete_all) == "string" then
state.notify.message.delete_all = args.notify.message.delete_all
end
end
end
end,
}

405
main.lua Normal file
View File

@@ -0,0 +1,405 @@
--- @since 25.4.8
-- stylua: ignore
local SUPPORTED_KEYS = {
{ on = "0", desc = "Free" }, { on = "1", desc = "Free" }, { on = "2", desc = "Free" }, { on = "3", desc = "Free" }, { on = "4", desc = "Free"},
{ on = "5", desc = "Free" }, { on = "6", desc = "Free" }, { on = "7", desc = "Free" }, { on = "8", desc = "Free" }, { on = "9", desc = "Free"},
{ on = "A", desc = "Free" }, { on = "B", desc = "Free" }, { on = "C", desc = "Free" }, { on = "D", desc = "Free" }, { on = "E", desc = "Free"},
{ on = "F", desc = "Free" }, { on = "G", desc = "Free" }, { on = "H", desc = "Free" }, { on = "I", desc = "Free" }, { on = "J", desc = "Free"},
{ on = "K", desc = "Free" }, { on = "L", desc = "Free" }, { on = "M", desc = "Free" }, { on = "N", desc = "Free" }, { on = "O", desc = "Free"},
{ on = "P", desc = "Free" }, { on = "Q", desc = "Free" }, { on = "R", desc = "Free" }, { on = "S", desc = "Free" }, { on = "T", desc = "Free"},
{ on = "U", desc = "Free" }, { on = "V", desc = "Free" }, { on = "W", desc = "Free" }, { on = "X", desc = "Free" }, { on = "Y", desc = "Free"}, { on = "Z", desc = "Free" },
{ on = "a", desc = "Free" }, { on = "b", desc = "Free" }, { on = "c", desc = "Free" }, { on = "d", desc = "Free" }, { on = "e", desc = "Free"},
{ on = "f", desc = "Free" }, { on = "g", desc = "Free" }, { on = "h", desc = "Free" }, { on = "i", desc = "Free" }, { on = "j", desc = "Free"},
{ on = "k", desc = "Free" }, { on = "l", desc = "Free" }, { on = "m", desc = "Free" }, { on = "n", desc = "Free" }, { on = "o", desc = "Free"},
{ on = "p", desc = "Free" }, { on = "q", desc = "Free" }, { on = "r", desc = "Free" }, { on = "s", desc = "Free" }, { on = "t", desc = "Free"},
{ on = "u", desc = "Free" }, { on = "v", desc = "Free" }, { on = "w", desc = "Free" }, { on = "x", desc = "Free" }, { on = "y", desc = "Free"}, { on = "z", desc = "Free" },
}
local _send_notification = ya.sync(
function(state, message)
ya.notify {
title = "Bookmarks",
content = message,
timeout = state.notify.timeout,
}
end
)
local _get_real_index = ya.sync(function(state, idx)
for key, value in pairs(state.bookmarks) do
if value.on == SUPPORTED_KEYS[idx].on then
return key
end
end
return nil
end)
local _get_bookmark_file = ya.sync(function(state)
local folder = cx.active.current
if state.file_pick_mode == "parent" or not folder.hovered then
return { url = folder.cwd, is_parent = true }
end
return { url = folder.hovered.url, is_parent = false }
end)
local _generate_description = ya.sync(function(state, file)
-- if this is true, we don't have information about the folder, so just return the folder url
if file.is_parent then
return tostring(file.url)
end
if state.desc_format == "parent" then
return tostring(file.url.parent)
end
-- full description
return tostring(file.url)
end)
local _load_state = ya.sync(function(state)
ps.sub_remote("@bookmarks", function(body)
if not state.bookmarks and body then
state.bookmarks = {}
for _, value in pairs(body) do
table.insert(state.bookmarks, value)
end
end
end)
end)
local _save_state = ya.sync(function(state, bookmarks)
if not bookmarks then
ps.pub_to(0, "@bookmarks", nil)
return
end
local save_state = {}
if state.persist == "all" then
save_state = bookmarks
else -- VIM mode
local idx = 1
for _, value in pairs(bookmarks) do
-- Only save bookmarks in upper case keys
if string.match(value.on, "%u") then
save_state[idx] = value
idx = idx + 1
end
end
end
ps.pub_to(0, "@bookmarks", save_state)
end)
local _load_last = ya.sync(function(state)
ps.sub_remote("@bookmarks-last", function(body)
state.last_dir = body
if state.last_mode ~= "dir" then
ps.unsub_remote("@bookmarks-last")
end
end)
end)
local _save_last = ya.sync(function(state, persist, imediate)
local file = _get_bookmark_file()
local curr = {
on = "'",
desc = _generate_description(file),
path = tostring(file.url),
is_parent = file.is_parent,
}
if imediate then
state.curr_dir = nil
state.last_dir = curr
else
state.last_dir = state.curr_dir
state.curr_dir = curr
end
if persist and state.last_dir then
ps.pub_to(0, "@bookmarks-last", state.last_dir)
end
end)
local get_last_mode = ya.sync(function(state) return state.last_mode end)
local save_last_dir = ya.sync(function(state)
ps.sub("cd", function() _save_last(state.last_persist, false) end)
ps.sub("hover", function()
local file = _get_bookmark_file()
state.curr_dir.desc = _generate_description(file)
state.curr_dir.path = tostring(file.url)
end)
end)
local save_last_jump = ya.sync(function(state) _save_last(state.last_persist, true) end)
local save_last_mark = ya.sync(function(state) _save_last(state.last_persist, true) end)
local _is_show_keys_enabled = ya.sync(function(state) return state.show_keys end)
local _is_custom_desc_input_enabled = ya.sync(function(state) return state.custom_desc_input end)
-- ***********************************************
-- **============= C O M M A N D S =============**
-- ***********************************************
local get_updated_keys = ya.sync(function(state, keys)
if state.bookmarks then
for _, bookmarks_value in pairs(state.bookmarks) do
for _, keys_value in pairs(keys) do
if keys_value.on == bookmarks_value.on then
keys_value.desc = bookmarks_value.desc
end
end
end
end
return keys
end)
local save_bookmark = ya.sync(function(state, idx, custom_desc)
local file = _get_bookmark_file()
state.bookmarks = state.bookmarks or {}
local _idx = _get_real_index(idx)
if not _idx then
_idx = #state.bookmarks + 1
end
local bookmark_desc = tostring(_generate_description(file))
if custom_desc then
bookmark_desc = tostring(custom_desc)
end
state.bookmarks[_idx] = {
on = SUPPORTED_KEYS[idx].on,
desc = bookmark_desc,
path = tostring(file.url),
is_parent = file.is_parent,
}
-- Custom sorting function
table.sort(state.bookmarks, function(a, b)
local key_a, key_b = a.on, b.on
-- Numbers first
if key_a:match("%d") and not key_b:match("%d") then
return true
elseif key_b:match("%d") and not key_a:match("%d") then
return false
end
-- Uppercase before lowercase
if key_a:match("%u") and key_b:match("%l") then
return true
elseif key_b:match("%u") and key_a:match("%l") then
return false
end
-- Regular alphabetical sorting
return key_a < key_b
end)
if state.persist then
_save_state(state.bookmarks)
end
if state.notify and state.notify.enable then
local message = state.notify.message.new
message, _ = message:gsub("<key>", state.bookmarks[_idx].on)
message, _ = message:gsub("<folder>", state.bookmarks[_idx].desc)
_send_notification(message)
end
if get_last_mode() == "mark" then
save_last_mark()
end
end)
local all_bookmarks = ya.sync(function(state, append_last_dir)
local bookmarks = {}
if state.bookmarks then
for _, value in pairs(state.bookmarks) do
table.insert(bookmarks, value)
end
end
if append_last_dir and state.last_dir then
table.insert(bookmarks, state.last_dir)
end
return bookmarks
end)
local delete_bookmark = ya.sync(function(state, idx)
if state.notify and state.notify.enable then
local message = state.notify.message.delete
message, _ = message:gsub("<key>", state.bookmarks[idx].on)
message, _ = message:gsub("<folder>", state.bookmarks[idx].desc)
_send_notification(message)
end
table.remove(state.bookmarks, idx)
if state.persist then
_save_state(state.bookmarks)
end
end)
local delete_all_bookmarks = ya.sync(function(state)
state.bookmarks = nil
if state.persist then
_save_state(nil)
end
if state.notify and state.notify.enable then
_send_notification(state.notify.message.delete_all)
end
end)
return {
entry = function(_, job)
local action = job.args[1]
if not action then
return
end
if action == "save" then
if _is_show_keys_enabled() then
SUPPORTED_KEYS = get_updated_keys(SUPPORTED_KEYS)
end
local key = ya.which { cands = SUPPORTED_KEYS, silent = not _is_show_keys_enabled() }
if key then
if _is_custom_desc_input_enabled() then
local value, event = ya.input {
title = "Save with custom description:",
position = { "top-center", y = 3, w = 60 },
value = tostring(_get_bookmark_file().url),
}
if event ~= 1 then
return
end
save_bookmark(key, value)
return
end
save_bookmark(key)
end
return
end
if action == "delete_all" then
return delete_all_bookmarks()
end
local bookmarks = all_bookmarks(action == "jump")
local selected = #bookmarks > 0 and ya.which { cands = bookmarks }
if not selected then
return
end
if action == "jump" then
if get_last_mode() == "jump" then
save_last_jump()
end
if bookmarks[selected].is_parent then
ya.mgr_emit("cd", { bookmarks[selected].path })
else
ya.mgr_emit("reveal", { bookmarks[selected].path })
end
elseif action == "delete" then
delete_bookmark(selected)
end
end,
setup = function(state, args)
if not args then
return
end
if type(args.last_directory) == "table" then
if args.last_directory.enable then
if args.last_directory.mode == "mark" then
state.last_persist = args.last_directory.persist
state.last_mode = "mark"
elseif args.last_directory.mode == "jump" then
state.last_persist = args.last_directory.persist
state.last_mode = "jump"
elseif args.last_directory.mode == "dir" then
state.last_persist = args.last_directory.persist
state.last_mode = "dir"
save_last_dir()
else
-- default
state.last_persist = args.last_directory.persist
state.last_mode = "dir"
save_last_dir()
end
if args.last_directory.persist then
_load_last()
end
end
end
if args.persist == "all" or args.persist == "vim" then
state.persist = args.persist
_load_state()
end
if args.desc_format == "parent" then
state.desc_format = "parent"
else
state.desc_format = "full"
end
if args.file_pick_mode == "parent" then
state.file_pick_mode = "parent"
else
state.file_pick_mode = "hover"
end
if type(args.custom_desc_input) == "boolean" then
state.custom_desc_input = args.custom_desc_input
end
if type(args.show_keys) == "boolean" then
state.show_keys = args.show_keys
end
state.notify = {
enable = false,
timeout = 1,
message = {
new = "New bookmark '<key>' -> '<folder>'",
delete = "Deleted bookmark in '<key>'",
delete_all = "Deleted all bookmarks",
},
}
if type(args.notify) == "table" then
if type(args.notify.enable) == "boolean" then
state.notify.enable = args.notify.enable
end
if type(args.notify.timeout) == "number" then
state.notify.timeout = args.notify.timeout
end
if type(args.notify.message) == "table" then
if type(args.notify.message.new) == "string" then
state.notify.message.new = args.notify.message.new
end
if type(args.notify.message.delete) == "string" then
state.notify.message.delete = args.notify.message.delete
end
if type(args.notify.message.delete_all) == "string" then
state.notify.message.delete_all = args.notify.message.delete_all
end
end
end
end,
}