From 9c25d24e0270e4d43b20366f5afd55b2914567e5 Mon Sep 17 00:00:00 2001 From: David Chen Date: Sun, 28 Dec 2025 11:55:26 -0800 Subject: [PATCH] upgrade yazi plugins --- yazi/package.toml | 14 +-- yazi/plugins/compress.yazi/main.lua | 4 +- yazi/plugins/git.yazi/README.md | 7 +- yazi/plugins/git.yazi/main.lua | 50 +++++++- yazi/plugins/starship.yazi/README.md | 16 ++- yazi/plugins/starship.yazi/main.lua | 168 ++++++++++++++++++++++----- 6 files changed, 213 insertions(+), 46 deletions(-) diff --git a/yazi/package.toml b/yazi/package.toml index 291677e..60f7b56 100644 --- a/yazi/package.toml +++ b/yazi/package.toml @@ -5,17 +5,17 @@ hash = "f590c5b7d0730e8d6023b1b34ddf7ead" [[plugin.deps]] use = "Rolv-Apneseth/starship" -rev = "6a0f3f7" -hash = "d5a74d95c2e8194ac352c5e10e81e64f" +rev = "eca1861" +hash = "e519d894e94ded741e06aae4d4775981" [[plugin.deps]] use = "yazi-rs/plugins:git" -rev = "5eea960" -hash = "e01006bfb38951ea89031bd918b20dbb" +rev = "7ca66b4" +hash = "d2aa1b2f32c8b4fd1775e8f5c45f8fab" [[plugin.deps]] use = "yazi-rs/plugins:smart-enter" -rev = "5eea960" +rev = "7ca66b4" hash = "56fdabc96fc1f4d53c96eb884b02a5be" [[plugin.deps]] @@ -25,8 +25,8 @@ hash = "7cc42012a7c2099f80064d228feb8d44" [[plugin.deps]] use = "KKV9/compress" -rev = "9fc8fe0" -hash = "2ad086899bf368fba211a33d8f68c39d" +rev = "c264639" +hash = "e17c11b605d989568a1d1741ca17c584" [flavor] deps = [] diff --git a/yazi/plugins/compress.yazi/main.lua b/yazi/plugins/compress.yazi/main.lua index e538c9c..c3c4241 100644 --- a/yazi/plugins/compress.yazi/main.lua +++ b/yazi/plugins/compress.yazi/main.lua @@ -243,13 +243,15 @@ return { is_level = true end end - elseif arg:match("^%w+$") then + elseif arg:match("^%w[%w\\.]*$") then -- Handle default extension (e.g., 7z, zip) if archive_commands["%." .. arg .. "$"] then default_extension = arg else notify_error(string.format("Unsupported extension: %s", arg), "warn") end + else + notify_error(string.format("Unknown argument: %s", arg), "warn") end end end diff --git a/yazi/plugins/git.yazi/README.md b/yazi/plugins/git.yazi/README.md index f1848e9..6d1629b 100644 --- a/yazi/plugins/git.yazi/README.md +++ b/yazi/plugins/git.yazi/README.md @@ -23,17 +23,20 @@ And register it as fetchers in your `~/.config/yazi/yazi.toml`: ```toml [[plugin.prepend_fetchers]] id = "git" -name = "*" +name = "*" # use `url` if you're using the nightly version of Yazi run = "git" [[plugin.prepend_fetchers]] id = "git" -name = "*/" +name = "*/" # use `url` if you're using the nightly version of Yazi run = "git" ``` ## Advanced +> [!NOTE] +> The following configuration must be put before `require("git"):setup()` + You can customize the [Style](https://yazi-rs.github.io/docs/plugins/layout#style) of the status sign with: - `th.git.modified` diff --git a/yazi/plugins/git.yazi/main.lua b/yazi/plugins/git.yazi/main.lua index 140ad5a..75000b1 100644 --- a/yazi/plugins/git.yazi/main.lua +++ b/yazi/plugins/git.yazi/main.lua @@ -5,6 +5,7 @@ local WINDOWS = ya.target_family() == "windows" -- The code of supported git status, -- also used to determine which status to show for directories when they contain different statuses -- see `bubble_up` +---@enum CODES local CODES = { excluded = 100, -- ignored directory ignored = 6, -- ignored file @@ -26,6 +27,8 @@ local PATTERNS = { { "[AD][AD]", CODES.updated }, } +---@param line string +---@return CODES, string local function match(line) local signs = line:sub(1, 2) for _, p in ipairs(PATTERNS) do @@ -41,9 +44,12 @@ local function match(line) else return code, path end + ---@diagnostic disable-next-line: missing-return end end +---@param cwd Url +---@return string? local function root(cwd) local is_worktree = function(url) local file, head = io.open(tostring(url)), nil @@ -64,6 +70,8 @@ local function root(cwd) until not cwd end +---@param changed Changes +---@return Changes local function bubble_up(changed) local new, empty = {}, Url("") for path, code in pairs(changed) do @@ -79,6 +87,10 @@ local function bubble_up(changed) return new end +---@param excluded string[] +---@param cwd Url +---@param repo Url +---@return Changes local function propagate_down(excluded, cwd, repo) local new, rel = {}, cwd:strip_prefix(repo) for _, path in ipairs(excluded) do @@ -95,7 +107,12 @@ local function propagate_down(excluded, cwd, repo) return new end +---@param cwd string +---@param repo string +---@param changed Changes local add = ya.sync(function(st, cwd, repo, changed) + ---@cast st State + st.dirs[cwd] = repo st.repos[repo] = st.repos[repo] or {} for path, code in pairs(changed) do @@ -108,16 +125,29 @@ local add = ya.sync(function(st, cwd, repo, changed) st.repos[repo][path] = code end end - ya.render() + -- TODO: remove this + if ui.render then + ui.render() + else + ya.render() + end end) +---@param cwd string local remove = ya.sync(function(st, cwd) + ---@cast st State + local repo = st.dirs[cwd] if not repo then return end - ya.render() + -- TODO: remove this + if ui.render then + ui.render() + else + ya.render() + end st.dirs[cwd] = nil if not st.repos[repo] then return @@ -131,9 +161,11 @@ local remove = ya.sync(function(st, cwd) st.repos[repo] = nil end) +---@param st State +---@param opts Options local function setup(st, opts) - st.dirs = {} -- Mapping between a directory and its corresponding repository - st.repos = {} -- Mapping between a repository and the status of each of its files + st.dirs = {} + st.repos = {} opts = opts or {} opts.order = opts.order or 1500 @@ -157,8 +189,13 @@ local function setup(st, opts) } Linemode:children_add(function(self) + -- TODO: use `not self._file.in_current` instead + if self._file.in_current == false then + return "" + end + local url = self._file.url - local repo = st.dirs[tostring(url.base)] + local repo = st.dirs[tostring(url.base or url.parent)] local code if repo then code = repo == CODES.excluded and CODES.ignored or st.repos[repo][tostring(url):sub(#repo + 2)] @@ -174,8 +211,9 @@ local function setup(st, opts) end, opts.order) end +---@type UnstableFetcher local function fetch(_, job) - local cwd = job.files[1].url.base + local cwd = job.files[1].url.base or job.files[1].url.parent local repo = root(cwd) if not repo then remove(tostring(cwd)) diff --git a/yazi/plugins/starship.yazi/README.md b/yazi/plugins/starship.yazi/README.md index a9858bc..022c3bd 100644 --- a/yazi/plugins/starship.yazi/README.md +++ b/yazi/plugins/starship.yazi/README.md @@ -40,13 +40,21 @@ Here is an example with all available config options: ```lua require("starship"):setup({ - -- Hide flags (such as filter, find and search). This is recommended for starship themes which - -- are intended to go across the entire width of the terminal. - hide_flags = false, -- Default: false + -- Hide flags (such as filter, find and search). This can be beneficial for starship themes + -- which are intended to go across the entire width of the terminal. + hide_flags = false, -- Whether to place flags after the starship prompt. False means the flags will be placed before the prompt. - flags_after_prompt = true, -- Default: true + flags_after_prompt = true, -- Custom starship configuration file to use config_file = "~/.config/starship_full.toml", -- Default: nil + -- Whether to enable support for starship's right prompt (i.e. `starship prompt --right`). + show_right_prompt = false, + -- Whether to hide the count widget, in case you want only your right prompt to show up. Only has + -- an effect when `show_right_prompt = true` + hide_count = false, + -- Separator to place between the right prompt and the count widget. Use `count_separator = ""` + -- to have no space between the widgets. + count_separator = " ", }) ``` diff --git a/yazi/plugins/starship.yazi/main.lua b/yazi/plugins/starship.yazi/main.lua index 00220d4..b1c9c96 100644 --- a/yazi/plugins/starship.yazi/main.lua +++ b/yazi/plugins/starship.yazi/main.lua @@ -5,9 +5,13 @@ --[[ ya.notify({ title = "Starship", content = message, timeout = 3 }) ]] --[[ end ]] -local save = ya.sync(function(st, _cwd, output) - st.output = output - ya.render() +local save = ya.sync(function(st, outputs) + st.output_left = outputs.left + st.output_right = outputs.right + + -- Support for versions later than v25.5.31 (not yet a full release as of writing this comment) + local render = ui.render or ya.render + render() end) -- Helper function for accessing the `config_file` state variable @@ -16,12 +20,21 @@ local get_config_file = ya.sync(function(st) return st.config_file end) +--- Helper function for accessing `show_right_prompt` state variable +---@return boolean +local should_show_right_prompt = ya.sync(function(st) + return st.show_right_prompt +end) + return { ---User arguments for setup method ---@class SetupArgs - ---@field config_file string Absolute path to a starship config file - ---@field hide_flags boolean Whether to hide all flags (such as filter and search). Recommended for themes which are intended to take the full width of the terminal. - ---@field flags_after_prompt boolean Whether to place flags (such as filter and search) after the starship prompt. By default this is true. + ---@field config_file string Absolute path to a starship config file. + ---@field hide_flags boolean Whether to hide all flags (such as filter and search). Default value is false. + ---@field flags_after_prompt boolean Whether to place flags (such as filter and search) after the starship prompt. Default value is true. + ---@field show_right_prompt boolean Whether to enable starship right prompt support. Default value is false. + ---@field hide_count boolean Whether to hide the count widget. Only has an effect when show_right_prompt is true. Default value is false. + ---@field count_separator string Set a custom separator between the count widget and the right prompt. Default value is " ", set to "" for no space. --- Setup plugin --- @param st table State @@ -29,6 +42,8 @@ return { setup = function(st, args) local hide_flags = false local flags_after_prompt = true + local hide_count = false + local count_separator = " " -- Check setup args if args ~= nil then @@ -48,6 +63,20 @@ return { end end + if args.show_right_prompt ~= nil then + -- Save directly to the plugin state so it can be accessed + -- read from the entry function + st.show_right_prompt = args.show_right_prompt + end + + if args.hide_count ~= nil then + hide_count = args.hide_count + end + + if args.count_separator ~= nil then + count_separator = args.count_separator + end + if args.hide_flags ~= nil then hide_flags = args.hide_flags end @@ -57,20 +86,15 @@ return { end end - -- Replace default header widget + -- Replace default left header widget Header:children_remove(1, Header.LEFT) Header:children_add(function(self) - local max = self._area.w - self._right_width - if max <= 0 then - return "" - end - - if hide_flags or not st.output then - return ui.Line.parse(st.output or "") + if hide_flags or not st.output_left then + return ui.Line.parse(st.output_left or "") end -- Split `st.output` at the first line break (or keep as is if none was found) - local output = st.output:match("([^\n]*)\n?") or st.output + local output = st.output_left:match("([^\n]*)\n?") or st.output_left local flags = self:flags() if flags_after_prompt then @@ -79,9 +103,80 @@ return { output = flags .. " " .. output end - return ui.Line.parse(output) + local line = ui.Line.parse(output) + if line:width() > self._area.w then + return "" + end + + return line end, 1000, Header.LEFT) + -- Support for right prompt, if enabled + if st.show_right_prompt then + -- Remove the default count widget + Header:children_remove(1, Header.RIGHT) + -- Replace with a custom widget combining the right prompt and the count widget + Header:children_add(function(self) + if not st.output_right then + st.output_right = "" + end + local output = st.output_right:match("([^\n]*)\n?") or st.output_right + local line = ui.Line.parse(output) + + -- Custom count widget so that we can measure the combined width + if not hide_count then + local yanked = #cx.yanked + local count, style + if yanked == 0 then + count = #self._tab.selected + style = th.mgr.count_selected + elseif cx.yanked.is_cut then + count = yanked + style = th.mgr.count_cut + else + count = yanked + style = th.mgr.count_copied + end + + -- Append custom count widget + if count ~= 0 then + line = ui.Line({ + line, + ui.Span(count_separator), + ui.Span(string.format(" %d ", count)):style(style), + }) + end + end + + -- Give precedence to the left header widget(s), hiding this component entirely if + -- there is no room for both + local right_width = line:width() + if self._left_width then + local max = self._area.w - self._left_width + if max < right_width then + return "" + end + end + + return line + end, 1000, Header.RIGHT) + + -- Override the header's redraw method, since we want the left side of the header to have + -- precedence over the right, unlike the default behaviour of hiding the left side if + -- there isn't room for both. + function Header:redraw() + local left = self:children_redraw(self.LEFT) + self._left_width = left:width() + + local right = self:children_redraw(self.RIGHT) + + return { + ui.Line(left):area(self._area), + ui.Line(right):area(self._area):align(ui.Align.RIGHT), + } + end + end + -- Pass current working directory and custom config path (if specified) to the plugin's entry point ---Callback for subscribers to update the prompt local callback = function() @@ -106,21 +201,42 @@ return { entry = function(_, job) local args = job.args - local command = Command("starship") - :arg("prompt") - :stdin(Command.INHERIT) - :cwd(args[1]) - :env("STARSHIP_SHELL", "") - -- Point to custom starship config + -- Setup commands for left and right prompts + local function base_command() + return Command("starship") + :arg("prompt") + :stdin(Command.INHERIT) + :cwd(args[1]) + :env("STARSHIP_SHELL", "") + :env("PWD", args[1]) + end + local command_left = base_command() + local command_right = base_command():arg("--right") + + -- Point to custom starship config for both commands local config_file = get_config_file() if config_file then - command = command:env("STARSHIP_CONFIG", config_file) + command_left = command_left:env("STARSHIP_CONFIG", config_file) + command_right = command_right:env("STARSHIP_CONFIG", config_file) end - local output = command:output() - if output then - save(args[1], output.stdout:gsub("^%s+", "")) + -- Execute left prompt command and save output + local outputs = { left = "", right = "" } + local output_left = command_left:output() + if output_left then + outputs.left = output_left.stdout:gsub("^%s+", "") end + + -- If support for right prompt is enabled, execute right prompt command and save output + local show_right_prompt = should_show_right_prompt() + if show_right_prompt then + local output_right = command_right:output() + if output_right then + outputs.right = output_right.stdout:gsub("^%s+", "") + end + end + + save(outputs) end, }