From 4bc838c64966e827b8abee680b1a977348cf10b6 Mon Sep 17 00:00:00 2001
From: David Chen
Date: Tue, 13 Jan 2026 14:54:33 -0800
Subject: [PATCH] yazi plugin updates
---
yazi/package.toml | 14 +-
yazi/plugins/compress.yazi/README.md | 24 +-
yazi/plugins/compress.yazi/main.lua | 11 +-
yazi/plugins/git.yazi/README.md | 12 +-
yazi/plugins/git.yazi/main.lua | 31 +-
yazi/plugins/git.yazi/types.lua | 12 +
yazi/plugins/yamb.yazi/README.md | 44 +-
yazi/plugins/yamb.yazi/main.lua | 632 ++++++++++++++-------------
yazi/plugins/yaziline.yazi/main.lua | 135 +++---
9 files changed, 432 insertions(+), 483 deletions(-)
create mode 100644 yazi/plugins/git.yazi/types.lua
diff --git a/yazi/package.toml b/yazi/package.toml
index 60f7b56..8a43dec 100644
--- a/yazi/package.toml
+++ b/yazi/package.toml
@@ -10,23 +10,23 @@ hash = "e519d894e94ded741e06aae4d4775981"
[[plugin.deps]]
use = "yazi-rs/plugins:git"
-rev = "7ca66b4"
-hash = "d2aa1b2f32c8b4fd1775e8f5c45f8fab"
+rev = "57f1863"
+hash = "36a484acf6a0a0219c543ccb4cee218f"
[[plugin.deps]]
use = "yazi-rs/plugins:smart-enter"
-rev = "7ca66b4"
+rev = "57f1863"
hash = "56fdabc96fc1f4d53c96eb884b02a5be"
[[plugin.deps]]
use = "h-hg/yamb"
-rev = "22af003"
-hash = "7cc42012a7c2099f80064d228feb8d44"
+rev = "5f2e22e"
+hash = "699fe07e0d2d1b4af8dafb84168eeb04"
[[plugin.deps]]
use = "KKV9/compress"
-rev = "c264639"
-hash = "e17c11b605d989568a1d1741ca17c584"
+rev = "e6007f7"
+hash = "e0b1051849756dd72fca874c320259a"
[flavor]
deps = []
diff --git a/yazi/plugins/compress.yazi/README.md b/yazi/plugins/compress.yazi/README.md
index ae1f329..8d5eab0 100644
--- a/yazi/plugins/compress.yazi/README.md
+++ b/yazi/plugins/compress.yazi/README.md
@@ -4,8 +4,6 @@
Effortlessly compress your files and folders with style!
----
-
## 📖 Table of Contents
- [Features](#-features)
@@ -17,8 +15,6 @@
- [Tips](#-tips)
- [Credits](#-credits)
----
-
## 🚀 Features
- 🗂️ **Multi-format support:** zip, 7z, rar, tar, tar.gz, tar.xz, tar.bz2, tar.zst, tar.lz4, tar.lha
@@ -29,8 +25,6 @@
- 🛑 **Overwrite safety:** Never lose files by accident
- 🎯 **Seamless Yazi integration:** Fast, native-like UX
----
-
## 📦 Supported File Types
| Extension | Default Command | 7z Command | Bsdtar Command (Win10+ & Unix) |
@@ -46,7 +40,6 @@
| `.tar.lz4` | `tar rpf + lz4` | | |
| `.tar.lha` | `tar rpf + lha` | | |
----
## ⚡️ Installation
@@ -60,9 +53,6 @@ git clone https://github.com/KKV9/compress.yazi.git %AppData%\yazi\config\plugin
# Or with yazi plugin manager
ya pkg add KKV9/compress
```
-
----
-
### 🔧 Extras (Windows)
To enable additional compression formats and features on Windows, follow these steps:
@@ -81,8 +71,6 @@ To enable additional compression formats and features on Windows, follow these s
4. **Install Additional Tools:**
To use formats like `lha`, `lz4`, `gzip`, etc., install their respective tools and ensure they are added to your `PATH`.
----
-
## 🎹 Keymap Example
Add this to your `keymap.toml`:
@@ -115,8 +103,6 @@ run = "plugin compress -phl"
desc = "Archive selected files (password+header+level)"
```
----
-
## 🛠️ Usage
1. **Select files/folders** in Yazi.
@@ -132,8 +118,6 @@ desc = "Archive selected files (password+header+level)"
6. **Overwrite protect** if a file already exists, the new file will be given a suffix _#.
7. Enjoy your shiny new archive!
----
-
## 🏳️🌈 Flags
- Combine flags for more power!
@@ -154,20 +138,14 @@ on = [ "c", "a", "r" ]
run = "plugin compress '-p -l rar'"
desc = "Archive selected files to rar (password+level)"
```
-
----
-
## 💡 Tips
- The file extension **must** match a supported type.
- The required compression tool **must** be installed and in your `PATH` (7zip/rar etc.).
- If no extention is provided, the default extention (zip) will be appended automatically.
-
----
+- If you leave the filename blank, the plugin will use the selected filename or parent directory, when multiple files are selected, to name the archive.
## 📣 Credits
Made with ❤️ for [Yazi](https://github.com/sxyazi/yazi) by [KKV9](https://github.com/KKV9).
Contributions are welcome! Feel free to submit a pull request.
-
----
diff --git a/yazi/plugins/compress.yazi/main.lua b/yazi/plugins/compress.yazi/main.lua
index c3c4241..2b8a750 100644
--- a/yazi/plugins/compress.yazi/main.lua
+++ b/yazi/plugins/compress.yazi/main.lua
@@ -243,7 +243,7 @@ return {
is_level = true
end
end
- elseif arg:match("^%w[%w\\.]*$") then
+ elseif arg:match("^[%w%.]+$") then
-- Handle default extension (e.g., 7z, zip)
if archive_commands["%." .. arg .. "$"] then
default_extension = arg
@@ -265,7 +265,7 @@ return {
ya.input(
{
title = "Create archive:",
- position = {"top-center", y = 3, w = 40}
+ pos = {"top-center", y = 3, w = 40}
}
)
if event ~= 1 then
@@ -362,7 +362,7 @@ return {
{
title = "Enter password:",
obscure = true,
- position = {"top-center", y = 3, w = 40}
+ pos = {"top-center", y = 3, w = 40}
}
)
if event ~= 1 then
@@ -388,7 +388,7 @@ return {
ya.input(
{
title = string.format("Enter compression level (%s - %s)", archive_level_min, archive_level_max),
- position = {"top-center", y = 3, w = 40}
+ pos = {"top-center", y = 3, w = 40}
}
)
if event ~= 1 then
@@ -476,7 +476,7 @@ return {
-- Move the final file from the temporary directory to the output directory
local final_output_url, temp_url_processed = combine_url(output_dir, original_name), combine_url(temp_dir, original_name)
final_output_url, _ = tostring(fs.unique_name(Url(final_output_url)))
- local move_status, move_err = os.rename(temp_url_processed, final_output_url)
+ local move_status, move_err = fs.rename(Url(temp_url_processed), Url(final_output_url))
if not move_status then
-- Notify the user if the move operation fails and clean up the temporary directory
notify_error(string.format("Failed to move %s to %s, error: %s", temp_url_processed, final_output_url, move_err), "error")
@@ -494,3 +494,4 @@ return {
end
end
}
+
diff --git a/yazi/plugins/git.yazi/README.md b/yazi/plugins/git.yazi/README.md
index 6d1629b..23b3bbb 100644
--- a/yazi/plugins/git.yazi/README.md
+++ b/yazi/plugins/git.yazi/README.md
@@ -22,14 +22,14 @@ And register it as fetchers in your `~/.config/yazi/yazi.toml`:
```toml
[[plugin.prepend_fetchers]]
-id = "git"
-name = "*" # use `url` if you're using the nightly version of Yazi
-run = "git"
+id = "git"
+url = "*"
+run = "git"
[[plugin.prepend_fetchers]]
-id = "git"
-name = "*/" # use `url` if you're using the nightly version of Yazi
-run = "git"
+id = "git"
+url = "*/"
+run = "git"
```
## Advanced
diff --git a/yazi/plugins/git.yazi/main.lua b/yazi/plugins/git.yazi/main.lua
index 75000b1..cdc1532 100644
--- a/yazi/plugins/git.yazi/main.lua
+++ b/yazi/plugins/git.yazi/main.lua
@@ -1,4 +1,4 @@
---- @since 25.5.31
+--- @since 25.12.29
local WINDOWS = ya.target_family() == "windows"
@@ -125,12 +125,7 @@ local add = ya.sync(function(st, cwd, repo, changed)
st.repos[repo][path] = code
end
end
- -- TODO: remove this
- if ui.render then
- ui.render()
- else
- ya.render()
- end
+ ui.render()
end)
---@param cwd string
@@ -142,12 +137,7 @@ local remove = ya.sync(function(st, cwd)
return
end
- -- TODO: remove this
- if ui.render then
- ui.render()
- else
- ya.render()
- end
+ ui.render()
st.dirs[cwd] = nil
if not st.repos[repo] then
return
@@ -180,17 +170,16 @@ local function setup(st, opts)
[CODES.updated] = t.updated and ui.Style(t.updated) or ui.Style():fg("yellow"),
}
local signs = {
- [CODES.ignored] = t.ignored_sign or "",
- [CODES.untracked] = t.untracked_sign or "?",
- [CODES.modified] = t.modified_sign or "",
- [CODES.added] = t.added_sign or "",
- [CODES.deleted] = t.deleted_sign or "",
- [CODES.updated] = t.updated_sign or "",
+ [CODES.ignored] = t.ignored_sign or " ",
+ [CODES.untracked] = t.untracked_sign or "? ",
+ [CODES.modified] = t.modified_sign or " ",
+ [CODES.added] = t.added_sign or " ",
+ [CODES.deleted] = t.deleted_sign or " ",
+ [CODES.updated] = t.updated_sign or " ",
}
Linemode:children_add(function(self)
- -- TODO: use `not self._file.in_current` instead
- if self._file.in_current == false then
+ if not self._file.in_current then
return ""
end
diff --git a/yazi/plugins/git.yazi/types.lua b/yazi/plugins/git.yazi/types.lua
new file mode 100644
index 0000000..9936849
--- /dev/null
+++ b/yazi/plugins/git.yazi/types.lua
@@ -0,0 +1,12 @@
+---@class State
+---@field dirs table Mapping between a directory and its corresponding repository
+---@field repos table Mapping between a repository and the status of each of its files
+
+---@class Options
+---@field order number The order in which the status is displayed
+---@field renamed boolean Whether to include renamed files in the status (or treat them as modified)
+
+-- TODO: move this to `types.yazi` once it's get stable
+---@alias UnstableFetcher fun(self: unknown, job: { files: File[] }): boolean, Error?
+
+---@alias Changes table
diff --git a/yazi/plugins/yamb.yazi/README.md b/yazi/plugins/yamb.yazi/README.md
index 5f322de..26f82db 100644
--- a/yazi/plugins/yamb.yazi/README.md
+++ b/yazi/plugins/yamb.yazi/README.md
@@ -10,17 +10,10 @@ A [Yazi](https://github.com/sxyazi/yazi) plugin for bookmark management, support
## Installation
> [!NOTE]
-> Yazi >= 0.25.
+> Yazi >= 25.6.11
```sh
-# Linux/macOS
-git clone https://github.com/h-hg/yamb.yazi.git ~/.config/yazi/plugins/yamb.yazi
-
-# Windows
-git clone https://github.com/h-hg/yamb.yazi.git $env:APPDATA\yazi\config\plugins\yamb.yazi
-
-# if you are using Yazi version >= 3.0
-ya pack -a h-hg/yamb
+ya pkg add h-hg/yamb
```
## Usage
@@ -36,7 +29,6 @@ local home_path = ya.target_family() == "windows" and os.getenv("USERPROFILE") o
if ya.target_family() == "windows" then
table.insert(bookmarks, {
tag = "Scoop Local",
-
path = (os.getenv("SCOOP") or home_path .. "\\scoop") .. "\\",
key = "p"
})
@@ -70,43 +62,43 @@ require("yamb"):setup {
Add this to your `keymap.toml`:
```toml
-[[manager.prepend_keymap]]
+[[mgr.prepend_keymap]]
on = [ "u", "a" ]
-run = "plugin yamb save"
+run = "plugin yamb -- save"
desc = "Add bookmark"
-[[manager.prepend_keymap]]
+[[mgr.prepend_keymap]]
on = [ "u", "g" ]
-run = "plugin yamb jump_by_key"
+run = "plugin yamb -- jump_by_key"
desc = "Jump bookmark by key"
-[[manager.prepend_keymap]]
+[[mgr.prepend_keymap]]
on = [ "u", "G" ]
-run = "plugin yamb jump_by_fzf"
+run = "plugin yamb -- jump_by_fzf"
desc = "Jump bookmark by fzf"
-[[manager.prepend_keymap]]
+[[mgr.prepend_keymap]]
on = [ "u", "d" ]
-run = "plugin yamb delete_by_key"
+run = "plugin yamb -- delete_by_key"
desc = "Delete bookmark by key"
-[[manager.prepend_keymap]]
+[[mgr.prepend_keymap]]
on = [ "u", "D" ]
-run = "plugin yamb delete_by_fzf"
+run = "plugin yamb -- delete_by_fzf"
desc = "Delete bookmark by fzf"
-[[manager.prepend_keymap]]
+[[mgr.prepend_keymap]]
on = [ "u", "A" ]
-run = "plugin yamb delete_all"
+run = "plugin yamb -- delete_all"
desc = "Delete all bookmarks"
-[[manager.prepend_keymap]]
+[[mgr.prepend_keymap]]
on = [ "u", "r" ]
-run = "plugin yamb rename_by_key"
+run = "plugin yamb -- rename_by_key"
desc = "Rename bookmark by key"
-[[manager.prepend_keymap]]
+[[mgr.prepend_keymap]]
on = [ "u", "R" ]
-run = "plugin yamb rename_by_fzf"
+run = "plugin yamb -- rename_by_fzf"
desc = "Rename bookmark by fzf"
```
diff --git a/yazi/plugins/yamb.yazi/main.lua b/yazi/plugins/yamb.yazi/main.lua
index 383b492..1c61426 100644
--- a/yazi/plugins/yamb.yazi/main.lua
+++ b/yazi/plugins/yamb.yazi/main.lua
@@ -1,355 +1,367 @@
+--- @since 25.6.11
local path_sep = package.config:sub(1, 1)
local get_hovered_path = ya.sync(function(state)
- local h = cx.active.current.hovered
- if h then
- local path = tostring(h.url)
- if h.cha.is_dir then
- return path .. path_sep
- end
- return path
- else
- return ''
- end
+ local h = cx.active.current.hovered
+ if h then
+ local path = tostring(h.url)
+ if h.cha.is_dir then
+ return path .. path_sep
+ end
+ return path
+ else
+ return ""
+ end
end)
local get_state_attr = ya.sync(function(state, attr)
- return state[attr]
+ return state[attr]
end)
local set_state_attr = ya.sync(function(state, attr, value)
- state[attr] = value
+ state[attr] = value
end)
local set_bookmarks = ya.sync(function(state, path, value)
- state.bookmarks[path] = value
+ state.bookmarks[path] = value
end)
local sort_bookmarks = function(bookmarks, key1, key2, reverse)
- reverse = reverse or false
- table.sort(bookmarks, function(x, y)
- if x[key1] == nil and y[key1] == nil then
- return x[key2] < y[key2]
- elseif x[key1] == nil then
- return false
- elseif y[key1] == nil then
- return true
- else
- return x[key1] < y[key1]
- end
- end)
- if reverse then
- local n = #bookmarks
- for i = 1, math.floor(n / 2) do
- bookmarks[i], bookmarks[n - i + 1] = bookmarks[n - i + 1], bookmarks[i]
- end
- end
- return bookmarks
+ reverse = reverse or false
+ table.sort(bookmarks, function(x, y)
+ if x[key1] == nil and y[key1] == nil then
+ return x[key2] < y[key2]
+ elseif x[key1] == nil then
+ return false
+ elseif y[key1] == nil then
+ return true
+ else
+ return x[key1] < y[key1]
+ end
+ end)
+ if reverse then
+ local n = #bookmarks
+ for i = 1, math.floor(n / 2) do
+ bookmarks[i], bookmarks[n - i + 1] = bookmarks[n - i + 1], bookmarks[i]
+ end
+ end
+ return bookmarks
end
local save_to_file = function(mb_path, bookmarks)
- local file = io.open(mb_path, "w")
- if file == nil then
- return
- end
- local array = {}
- for _, item in pairs(bookmarks) do
- table.insert(array, item)
- end
- sort_bookmarks(array, "tag", "key", true)
- for _, item in ipairs(array) do
- file:write(string.format("%s\t%s\t%s\n", item.tag, item.path, item.key))
- end
- file:close()
+ local file = io.open(mb_path, "w")
+ if file == nil then
+ return
+ end
+ local array = {}
+ for _, item in pairs(bookmarks) do
+ table.insert(array, item)
+ end
+ sort_bookmarks(array, "tag", "key", true)
+ for _, item in ipairs(array) do
+ file:write(string.format("%s\t%s\t%s\n", item.tag, item.path, item.key))
+ end
+ file:close()
end
local fzf_find = function(cli, mb_path)
- local permit = ya.hide()
- local cmd = string.format("%s < \"%s\"", cli, mb_path)
- local handle = io.popen(cmd, "r")
- local result = ""
- if handle then
- -- strip
- result = string.gsub(handle:read("*all") or "", "^%s*(.-)%s*$", "%1")
- handle:close()
- end
- permit:drop()
- local tag, path, key = string.match(result or "", "(.-)\t(.-)\t(.*)")
- return path
+ local permit = ya.hide()
+ local cmd = string.format('%s < "%s"', cli, mb_path)
+ local handle = io.popen(cmd, "r")
+ local result = ""
+ if handle then
+ -- strip
+ result = string.gsub(handle:read("*all") or "", "^%s*(.-)%s*$", "%1")
+ handle:close()
+ end
+ permit:drop()
+ local tag, path, key = string.match(result or "", "(.-)\t(.-)\t(.*)")
+ return path
end
local which_find = function(bookmarks)
- local cands = {}
- for path, item in pairs(bookmarks) do
- if #item.tag ~= 0 then
- table.insert(cands, { desc = item.tag, on = item.key, path = item.path })
- end
- end
- sort_bookmarks(cands, "on", "desc", false)
- if #cands == 0 then
- ya.notify {
- title = "Bookmarks",
- content = "Empty bookmarks",
- timeout = 2,
- level = "info",
- }
- return nil
- end
- local idx = ya.which { cands = cands }
- if idx == nil then
- return nil
- end
- return cands[idx].path
+ local cands = {}
+ for path, item in pairs(bookmarks) do
+ if #item.tag ~= 0 then
+ table.insert(cands, { desc = item.tag, on = item.key, path = item.path })
+ end
+ end
+ sort_bookmarks(cands, "on", "desc", false)
+ if #cands == 0 then
+ ya.notify({
+ title = "Bookmarks",
+ content = "Empty bookmarks",
+ timeout = 2,
+ level = "info",
+ })
+ return nil
+ end
+ local idx = ya.which({ cands = cands })
+ if idx == nil then
+ return nil
+ end
+ return cands[idx].path
end
local action_jump = function(bookmarks, path, jump_notify)
- if path == nil then
- return
- end
- local tag = bookmarks[path].tag
- if string.sub(path, -1) == path_sep then
- ya.manager_emit("cd", { path })
- else
- ya.manager_emit("reveal", { path })
- end
- if jump_notify then
- ya.notify {
- title = "Bookmarks",
- content = 'Jump to "' .. tag .. '"',
- timeout = 2,
- level = "info",
- }
- end
+ if path == nil then
+ return
+ end
+ local tag = bookmarks[path].tag
+ if string.sub(path, -1) == path_sep then
+ ya.emit("cd", { path, raw = true })
+ else
+ ya.emit("reveal", { path, no_dummy = true, raw = true })
+ end
+ if jump_notify then
+ ya.notify({
+ title = "Bookmarks",
+ content = 'Jump to "' .. tag .. '"',
+ timeout = 2,
+ level = "info",
+ })
+ end
end
local generate_key = function(bookmarks)
- local keys = get_state_attr("keys")
- local key2rank = get_state_attr("key2rank")
- local mb = {}
- for _, item in pairs(bookmarks) do
- if #item.key == 1 then
- table.insert(mb, item.key)
- end
- end
- if #mb == 0 then
- return keys[1]
- end
- table.sort(mb, function(a, b)
- return key2rank[a] < key2rank[b]
- end)
- local idx = 1
- for _, key in ipairs(keys) do
- if idx > #mb or key2rank[key] < key2rank[mb[idx]] then
- return key
- end
- idx = idx + 1
- end
- return nil
+ local keys = get_state_attr("keys")
+ local key2rank = get_state_attr("key2rank")
+ local mb = {}
+ for _, item in pairs(bookmarks) do
+ if #item.key == 1 then
+ table.insert(mb, item.key)
+ end
+ end
+ if #mb == 0 then
+ return keys[1]
+ end
+ table.sort(mb, function(a, b)
+ return key2rank[a] < key2rank[b]
+ end)
+ local idx = 1
+ for _, key in ipairs(keys) do
+ if idx > #mb or key2rank[key] < key2rank[mb[idx]] then
+ return key
+ end
+ idx = idx + 1
+ end
+ return nil
end
local action_save = function(mb_path, bookmarks, path)
- if path == nil or #path == 0 then
- return
- end
+ if path == nil or #path == 0 then
+ return
+ end
- local path_obj = bookmarks[path]
- -- check tag
- local tag = path_obj and path_obj.tag or path:match(".*[\\/]([^\\/]+)[\\/]?$")
- while true do
- local value, event = ya.input({
- title = "Tag (alias name)",
- value = tag,
- position = { "top-center", y = 3, w = 40 },
- })
- if event ~= 1 then
- return
- end
- tag = value or ''
- if #tag == 0 then
- ya.notify {
- title = "Bookmarks",
- content = "Empty tag",
- timeout = 2,
- level = "info",
- }
- else
- -- check the tag
- local tag_obj = nil
- for _, item in pairs(bookmarks) do
- if item.tag == tag then
- tag_obj = item
- break
- end
- end
- if tag_obj == nil or tag_obj.path == path then
- break
- end
- ya.notify {
- title = "Bookmarks",
- content = "Duplicated tag",
- timeout = 2,
- level = "info",
- }
- end
- end
- -- check key
- local key = path_obj and path_obj.key or generate_key(bookmarks)
- while true do
- local value, event = ya.input({
- title = "Key (1 character, optional)",
- value = key,
- position = { "top-center", y = 3, w = 40 },
- })
- if event ~= 1 then
- return
- end
- key = value or ""
- if key == "" then
- key = ""
- break
- elseif #key == 1 then
- -- check the key
- local key_obj = nil
- for _, item in pairs(bookmarks) do
- if item.key == key then
- key_obj = item
- break
- end
- end
- if key_obj == nil or key_obj.path == path then
- break
- else
- ya.notify {
- title = "Bookmarks",
- content = "Duplicated key",
- timeout = 2,
- level = "info",
- }
- end
- else
- ya.notify {
- title = "Bookmarks",
- content = "The length of key shoule be 1",
- timeout = 2,
- level = "info",
- }
- end
- end
- -- save
- set_bookmarks(path, { tag = tag, path = path, key = key })
- bookmarks = get_state_attr("bookmarks")
- save_to_file(mb_path, bookmarks)
- ya.notify {
- title = "Bookmarks",
- content = '"' .. tag .. '" saved"',
- timeout = 2,
- level = "info",
- }
+ local path_obj = bookmarks[path]
+ -- check tag
+ local tag = path_obj and path_obj.tag or path:match(".*[\\/]([^\\/]+)[\\/]?$")
+ while true do
+ local value, event = ya.input({
+ title = "Tag (alias name)",
+ value = tag,
+ pos = { "top-center", y = 3, w = 40 },
+ -- TODO: remove this after next yazi released
+ position = { "top-center", y = 3, w = 40 },
+ })
+ if event ~= 1 then
+ return
+ end
+ tag = value or ""
+ if #tag == 0 then
+ ya.notify({
+ title = "Bookmarks",
+ content = "Empty tag",
+ timeout = 2,
+ level = "info",
+ })
+ else
+ -- check the tag
+ local tag_obj = nil
+ for _, item in pairs(bookmarks) do
+ if item.tag == tag then
+ tag_obj = item
+ break
+ end
+ end
+ if tag_obj == nil or tag_obj.path == path then
+ break
+ end
+ ya.notify({
+ title = "Bookmarks",
+ content = "Duplicated tag",
+ timeout = 2,
+ level = "info",
+ })
+ end
+ end
+ -- check key
+ local key = path_obj and path_obj.key or generate_key(bookmarks)
+ while true do
+ local value, event = ya.input({
+ title = "Key (1 character, optional)",
+ value = key,
+ pos = { "top-center", y = 3, w = 40 },
+ -- TODO: remove this after next yazi released
+ position = { "top-center", y = 3, w = 40 },
+ })
+ if event ~= 1 then
+ return
+ end
+ key = value or ""
+ if key == "" then
+ key = ""
+ break
+ elseif #key == 1 then
+ -- check the key
+ local key_obj = nil
+ for _, item in pairs(bookmarks) do
+ if item.key == key then
+ key_obj = item
+ break
+ end
+ end
+ if key_obj == nil or key_obj.path == path then
+ break
+ else
+ ya.notify({
+ title = "Bookmarks",
+ content = "Duplicated key",
+ timeout = 2,
+ level = "info",
+ })
+ end
+ else
+ ya.notify({
+ title = "Bookmarks",
+ content = "The length of key shoule be 1",
+ timeout = 2,
+ level = "info",
+ })
+ end
+ end
+ -- save
+ set_bookmarks(path, { tag = tag, path = path, key = key })
+ bookmarks = get_state_attr("bookmarks")
+ save_to_file(mb_path, bookmarks)
+ ya.notify({
+ title = "Bookmarks",
+ content = '"' .. tag .. '" saved"',
+ timeout = 2,
+ level = "info",
+ })
end
local action_delete = function(mb_path, bookmarks, path)
- if path == nil then
- return
- end
- local tag = bookmarks[path].tag
- set_bookmarks(path, nil)
- bookmarks = get_state_attr("bookmarks")
- save_to_file(mb_path, bookmarks)
- ya.notify {
- title = "Bookmarks",
- content = '"' .. tag .. '" deleted',
- timeout = 2,
- level = "info",
- }
+ if path == nil then
+ return
+ end
+ local tag = bookmarks[path].tag
+ set_bookmarks(path, nil)
+ bookmarks = get_state_attr("bookmarks")
+ save_to_file(mb_path, bookmarks)
+ ya.notify({
+ title = "Bookmarks",
+ content = '"' .. tag .. '" deleted',
+ timeout = 2,
+ level = "info",
+ })
end
local action_delete_all = function(mb_path)
- local value, event = ya.input({
- title = "Delete all bookmarks? (y/n)",
- position = { "top-center", y = 3, w = 40 },
- })
- if event ~= 1 then
- return
- end
- if string.lower(value) == "y" then
- set_state_attr("bookmarks", {})
- save_to_file(mb_path, {})
- ya.notify {
- title = "Bookmarks",
- content = "All bookmarks deleted",
- timeout = 2,
- level = "info",
- }
- else
- ya.notify {
- title = "Bookmarks",
- content = "Cancel delete",
- timeout = 2,
- level = "info",
- }
- end
+ local value, event = ya.input({
+ title = "Delete all bookmarks? (y/n)",
+ pos = { "top-center", y = 3, w = 40 },
+ -- TODO: remove this after next yazi released
+ position = { "top-center", y = 3, w = 40 },
+ })
+ if event ~= 1 then
+ return
+ end
+ if value and string.lower(value) == "y" then
+ set_state_attr("bookmarks", {})
+ save_to_file(mb_path, {})
+ ya.notify({
+ title = "Bookmarks",
+ content = "All bookmarks deleted",
+ timeout = 2,
+ level = "info",
+ })
+ else
+ ya.notify({
+ title = "Bookmarks",
+ content = "Cancel delete",
+ timeout = 2,
+ level = "info",
+ })
+ end
end
return {
- setup = function(state, options)
- state.path = options.path or
- (ya.target_family() == "windows" and os.getenv("APPDATA") .. "\\yazi\\config\\bookmark") or
- (os.getenv("HOME") .. "/.config/yazi/bookmark")
- state.cli = options.cli or "fzf"
- state.jump_notify = options.jump_notify and true
- -- init the keys
- local keys = options.keys or "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
- state.keys = {}
- state.key2rank = {}
- for i = 1, #keys do
- local char = keys:sub(i, i)
- table.insert(state.keys, char)
- state.key2rank[char] = i
- end
+ setup = function(state, options)
+ state.path = options.path
+ or (ya.target_family() == "windows" and os.getenv("APPDATA") .. "\\yazi\\config\\bookmark")
+ or (os.getenv("HOME") .. "/.config/yazi/bookmark")
+ state.cli = options.cli or "fzf"
+ state.jump_notify = options.jump_notify and true
+ -- init the keys
+ local keys = options.keys or "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ state.keys = {}
+ state.key2rank = {}
+ for i = 1, #keys do
+ local char = keys:sub(i, i)
+ table.insert(state.keys, char)
+ state.key2rank[char] = i
+ end
- -- init the bookmarks
- local bookmarks = {}
- for _, item in pairs(options.bookmarks or {}) do
- bookmarks[item.path] = { tag = item.tag, path = item.path, key = item.key }
- end
- -- load the config
- local file = io.open(state.path, "r")
- if file ~= nil then
- for line in file:lines() do
- local tag, path, key = string.match(line, "(.-)\t(.-)\t(.*)")
- if tag and path then
- key = key or ""
- bookmarks[path] = { tag = tag, path = path, key = key }
- end
- end
- file:close()
- end
- -- create bookmarks file to enable fzf
- save_to_file(state.path, bookmarks)
- state.bookmarks = bookmarks
- end,
- entry = function(self, jobs)
- local action = jobs.args[1]
- if not action then
- return
- end
- local mb_path, cli, bookmarks, jump_notify = get_state_attr("path"), get_state_attr("cli"), get_state_attr("bookmarks"), get_state_attr("jump_notify")
- if action == "save" then
- action_save(mb_path, bookmarks, get_hovered_path())
- elseif action == "delete_by_key" then
- action_delete(mb_path, bookmarks, which_find(bookmarks))
- elseif action == "delete_by_fzf" then
- action_delete(mb_path, bookmarks, fzf_find(cli, mb_path))
- elseif action == "delete_all" then
- action_delete_all(mb_path)
- elseif action == "jump_by_key" then
- action_jump(bookmarks, which_find(bookmarks), jump_notify)
- elseif action == "jump_by_fzf" then
- action_jump(bookmarks, fzf_find(cli, mb_path), jump_notify)
- elseif action == "rename_by_key" then
- action_save(mb_path, bookmarks, which_find(bookmarks))
- elseif action == "rename_by_fzf" then
- action_save(mb_path, bookmarks, fzf_find(cli, mb_path))
- end
- end,
+ -- init the bookmarks
+ local bookmarks = {}
+ for _, item in pairs(options.bookmarks or {}) do
+ bookmarks[item.path] = { tag = item.tag, path = item.path, key = item.key }
+ if not state.key2rank[item.key] then
+ state.key2rank[item.key] = #state.key2rank + 1
+ state.keys[#state.keys + 1] = item.key
+ end
+ end
+ -- load the config
+ local file = io.open(state.path, "r")
+ if file ~= nil then
+ for line in file:lines() do
+ local tag, path, key = string.match(line, "(.-)\t(.-)\t(.*)")
+ if tag and path then
+ key = key or ""
+ bookmarks[path] = { tag = tag, path = path, key = key }
+ end
+ end
+ file:close()
+ end
+ -- create bookmarks file to enable fzf
+ save_to_file(state.path, bookmarks)
+ state.bookmarks = bookmarks
+ end,
+ entry = function(self, jobs)
+ local action = jobs.args[1]
+ if not action then
+ return
+ end
+ local mb_path, cli, bookmarks, jump_notify =
+ get_state_attr("path"), get_state_attr("cli"), get_state_attr("bookmarks"), get_state_attr("jump_notify")
+ if action == "save" then
+ action_save(mb_path, bookmarks, get_hovered_path())
+ elseif action == "delete_by_key" then
+ action_delete(mb_path, bookmarks, which_find(bookmarks))
+ elseif action == "delete_by_fzf" then
+ action_delete(mb_path, bookmarks, fzf_find(cli, mb_path))
+ elseif action == "delete_all" then
+ action_delete_all(mb_path)
+ elseif action == "jump_by_key" then
+ action_jump(bookmarks, which_find(bookmarks), jump_notify)
+ elseif action == "jump_by_fzf" then
+ action_jump(bookmarks, fzf_find(cli, mb_path), jump_notify)
+ elseif action == "rename_by_key" then
+ action_save(mb_path, bookmarks, which_find(bookmarks))
+ elseif action == "rename_by_fzf" then
+ action_save(mb_path, bookmarks, fzf_find(cli, mb_path))
+ end
+ end,
}
diff --git a/yazi/plugins/yaziline.yazi/main.lua b/yazi/plugins/yaziline.yazi/main.lua
index 3906079..2f67070 100644
--- a/yazi/plugins/yaziline.yazi/main.lua
+++ b/yazi/plugins/yaziline.yazi/main.lua
@@ -1,16 +1,13 @@
---@diagnostic disable: undefined-global
-
local function setup(_, options)
options = options or {}
-
local default_separators = {
- angly = { "", "", "", "" },
- curvy = { "", "", "", "" },
+ angly = { "", "", "", "" },
+ curvy = { "", "", "", "" },
liney = { "", "", "|", "|" },
empty = { "", "", "", "" },
}
local separators = default_separators[options.separator_style or "angly"]
-
local config = {
separator_styles = {
separator_open = options.separator_open or separators[1],
@@ -22,147 +19,121 @@ local function setup(_, options)
},
select_symbol = options.select_symbol or "S",
yank_symbol = options.yank_symbol or "Y",
-
filename_max_length = options.filename_max_length or 24,
filename_truncate_length = options.filename_truncate_length or 6,
filename_truncate_separator = options.filename_truncate_separator or "...",
-
color = options.color or nil,
- secondary_color = options.secondary_color or nil,
- default_files_color = options.default_files_color
- or th.which.separator_style.fg
- or "darkgray",
- selected_files_color = options.selected_files_color
- or th.mgr.count_selected.bg
- or "white",
- yanked_files_color = options.selected_files_color
- or th.mgr.count_copied.bg
- or "green",
- cut_files_color = options.cut_files_color
- or th.mgr.count_cut.bg
- or "red",
+ secondary_color = options.secondary_color or nil,
+ default_files_color = options.default_files_color
+ or th.which.separator_style:fg()
+ or "darkgray",
+ selected_files_color = options.selected_files_color
+ or th.mgr.count_selected:bg()
+ or "white",
+ yanked_files_color = options.selected_files_color
+ or th.mgr.count_copied:bg()
+ or "green",
+ cut_files_color = options.cut_files_color
+ or th.mgr.count_cut:bg()
+ or "red",
}
-
local current_separator_style = config.separator_styles
-
function Header:count()
return ui.Line({})
end
-
function Status:mode()
local mode = tostring(self._tab.mode):upper()
-
local style = self:style()
return ui.Line({
ui.Span(current_separator_style.separator_head)
- :fg(config.color or style.main.bg),
+ :fg(config.color or style.main:bg()),
ui.Span(" " .. mode .. " ")
- :fg(th.which.mask.bg)
- :bg(config.color or style.main.bg),
+ :fg(th.which.mask:bg())
+ :bg(config.color or style.main:bg()),
})
end
-
function Status:size()
local h = self._current.hovered
local size = h and (h:size() or h.cha.len) or 0
-
local style = self:style()
return ui.Span(current_separator_style.separator_close .. " " .. ya.readable_size(size) .. " ")
- :fg(config.color or style.main.bg)
- :bg(config.secondary_color or th.which.separator_style.fg)
+ :fg(config.color or style.main:bg())
+ :bg(config.secondary_color or th.which.separator_style:fg())
end
-
function Status:utf8_sub(str, start_char, end_char)
local start_byte = utf8.offset(str, start_char)
local end_byte = end_char and (utf8.offset(str, end_char + 1) - 1) or #str
-
if not start_byte or not end_byte then
return ""
end
-
return string.sub(str, start_byte, end_byte)
end
-
function Status:truncate_name(filename, max_length)
local base_name, extension = filename:match("^(.+)(%.[^%.]+)$")
base_name = base_name or filename
extension = extension or ""
-
if utf8.len(base_name) > max_length then
base_name = self:utf8_sub(base_name, 1, config.filename_truncate_length)
.. config.filename_truncate_separator
.. self:utf8_sub(base_name, -config.filename_truncate_length)
end
-
return base_name .. extension
end
-
function Status:name()
local h = self._current.hovered
+ local style = self:style()
if not h then
return ui.Line({
ui.Span(current_separator_style.separator_close .. " ")
- :fg(config.secondary_color or th.which.separator_style.fg),
+ :fg(config.secondary_color or th.which.separator_style:fg()),
ui.Span("Empty dir")
- :fg(config.color or style.main.bg),
+ :fg(config.color or style.main:bg()),
})
end
-
local truncated_name = self:truncate_name(h.name, config.filename_max_length)
-
- local style = self:style()
return ui.Line({
ui.Span(current_separator_style.separator_close .. " ")
- :fg(config.secondary_color or th.which.separator_style.fg),
+ :fg(config.secondary_color or th.which.separator_style:fg()),
ui.Span(truncated_name)
- :fg(config.color or style.main.bg),
+ :fg(config.color or style.main:bg()),
})
end
-
function Status:files()
local files_yanked = #cx.yanked
local files_selected = #cx.active.selected
local files_cut = cx.yanked.is_cut
-
local selected_fg = files_selected > 0
- and config.selected_files_color
- or config.default_files_color
- local yanked_fg = files_yanked > 0
- and
- (files_cut
- and config.cut_files_color
- or config.yanked_files_color
- )
+ and config.selected_files_color
+ or config.default_files_color
+ local yanked_fg = files_yanked > 0
+ and
+ (files_cut
+ and config.cut_files_color
+ or config.yanked_files_color
+ )
or config.default_files_color
-
local yanked_text = files_yanked > 0
- and config.yank_symbol .. " " .. files_yanked
- or config.yank_symbol .. " 0"
-
+ and config.yank_symbol .. " " .. files_yanked
+ or config.yank_symbol .. " 0"
return ui.Line({
ui.Span(" " .. current_separator_style.separator_close_thin .. " ")
- :fg(th.which.separator_style.fg),
+ :fg(th.which.separator_style:fg()),
ui.Span(config.select_symbol .. " " .. files_selected .. " ")
- :fg(selected_fg),
- ui.Span(yanked_text .. " ")
- :fg(yanked_fg),
+ :fg(selected_fg),
+ ui.Span(yanked_text .. " ")
+ :fg(yanked_fg),
})
end
-
function Status:modified()
local hovered = cx.active.current.hovered
-
if not hovered then
return ""
end
-
local cha = hovered.cha
local time = (cha.mtime or 0) // 1
-
return ui.Span(os.date("%Y-%m-%d %H:%M", time) .. " " .. current_separator_style.separator_open_thin .. " ")
- :fg(th.which.separator_style.fg)
+ :fg(th.which.separator_style:fg())
end
-
function Status:percent()
local percent = 0
local cursor = self._tab.current.cursor
@@ -170,7 +141,6 @@ local function setup(_, options)
if cursor ~= 0 and length ~= 0 then
percent = math.floor((cursor + 1) * 100 / length)
end
-
if percent == 0 then
percent = " Top "
elseif percent == 100 then
@@ -178,35 +148,30 @@ local function setup(_, options)
else
percent = string.format(" %2d%% ", percent)
end
-
local style = self:style()
return ui.Line({
- ui.Span(" " .. current_separator_style.separator_open)
- :fg(config.secondary_color or th.which.separator_style.fg),
+ ui.Span(" " .. current_separator_style.separator_open)
+ :fg(config.secondary_color or th.which.separator_style:fg()),
ui.Span(percent)
- :fg(config.color or style.main.bg)
- :bg(config.secondary_color or th.which.separator_style.fg),
+ :fg(config.color or style.main:bg())
+ :bg(config.secondary_color or th.which.separator_style:fg()),
ui.Span(current_separator_style.separator_open)
- :fg(config.color or style.main.bg)
- :bg(config.secondary_color or th.which.separator_style.fg),
+ :fg(config.color or style.main:bg())
+ :bg(config.secondary_color or th.which.separator_style:fg()),
})
end
-
function Status:position()
local cursor = self._tab.current.cursor
local length = #self._tab.current.files
-
local style = self:style()
return ui.Line({
ui.Span(string.format(" %2d/%-2d ", math.min(cursor + 1, length), length))
- :fg(th.which.mask.bg)
- :bg(config.color or style.main.bg),
- ui.Span(current_separator_style.separator_tail):fg(config.color or style.main.bg),
+ :fg(th.which.mask:bg())
+ :bg(config.color or style.main:bg()),
+ ui.Span(current_separator_style.separator_tail):fg(config.color or style.main:bg()),
})
end
-
Status:children_add(Status.files, 4000, Status.LEFT)
Status:children_add(Status.modified, 0, Status.RIGHT)
end
-
-return { setup = setup }
\ No newline at end of file
+return { setup = setup }