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 }