sxyazi
2025-05-28 22:13:48 +08:00
parent ecffbf71dc
commit d642bfb082
15 changed files with 52 additions and 61 deletions

View File

@@ -1,4 +1,4 @@
--- @since 25.2.26 --- @since 25.5.28
local selected_or_hovered = ya.sync(function() local selected_or_hovered = ya.sync(function()
local tab, paths = cx.active, {} local tab, paths = cx.active, {}
@@ -13,7 +13,7 @@ end)
return { return {
entry = function() entry = function()
ya.mgr_emit("escape", { visual = true }) ya.emit("escape", { visual = true })
local urls = selected_or_hovered() local urls = selected_or_hovered()
if #urls == 0 then if #urls == 0 then
@@ -28,7 +28,7 @@ return {
return return
end end
local status, err = Command("chmod"):arg(value):args(urls):spawn():wait() local status, err = Command("chmod"):arg(value):arg(urls):spawn():wait()
if not status or not status.success then if not status or not status.success then
ya.notify { ya.notify {
title = "Chmod", title = "Chmod",

View File

@@ -1,8 +1,5 @@
# git.yazi # git.yazi
> [!NOTE]
> Yazi v25.2.26 or later is required for this plugin to work.
Show the status of Git file changes as linemode in the file list. Show the status of Git file changes as linemode in the file list.
https://github.com/user-attachments/assets/34976be9-a871-4ffe-9d5a-c4cdd0bf4576 https://github.com/user-attachments/assets/34976be9-a871-4ffe-9d5a-c4cdd0bf4576

View File

@@ -1,4 +1,4 @@
--- @since 25.4.4 --- @since 25.5.28
local WINDOWS = ya.target_family() == "windows" local WINDOWS = ya.target_family() == "windows"
@@ -190,8 +190,8 @@ local function fetch(_, job)
-- stylua: ignore -- stylua: ignore
local output, err = Command("git") local output, err = Command("git")
:cwd(tostring(cwd)) :cwd(tostring(cwd))
:args({ "--no-optional-locks", "-c", "core.quotePath=", "status", "--porcelain", "-unormal", "--no-renames", "--ignored=matching" }) :arg({ "--no-optional-locks", "-c", "core.quotePath=", "status", "--porcelain", "-unormal", "--no-renames", "--ignored=matching" })
:args(paths) :arg(paths)
:stdout(Command.PIPED) :stdout(Command.PIPED)
:output() :output()
if not output then if not output then

View File

@@ -1,4 +1,4 @@
--- @since 25.2.26 --- @since 25.5.28
local AVAILABLE_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789." local AVAILABLE_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789."
@@ -24,9 +24,9 @@ return {
local kw = escape(cands[idx].on) local kw = escape(cands[idx].on)
if changed(kw) then if changed(kw) then
ya.mgr_emit("find_do", { "^" .. kw }) ya.emit("find_do", { "^" .. kw })
else else
ya.mgr_emit("find_arrow", {}) ya.emit("find_arrow", {})
end end
end, end,
} }

View File

@@ -1,4 +1,4 @@
--- @since 25.2.26 --- @since 25.5.28
local M = {} local M = {}
@@ -32,9 +32,9 @@ function M:peek(job)
child:start_kill() child:start_kill()
if job.skip > 0 and i < job.skip + limit then if job.skip > 0 and i < job.skip + limit then
ya.mgr_emit("peek", { math.max(0, i - limit), only_if = job.file.url, upper_bound = true }) ya.emit("peek", { math.max(0, i - limit), only_if = job.file.url, upper_bound = true })
else else
ya.preview_widgets(job, { ui.Text(lines):area(job.area) }) ya.preview_widget(job, ui.Text(lines):area(job.area))
end end
end end

View File

@@ -1,4 +1,4 @@
--- @since 25.4.4 --- @since 25.5.28
local update = ya.sync(function(st, tags) local update = ya.sync(function(st, tags)
for path, tag in pairs(tags) do for path, tag in pairs(tags) do
@@ -43,7 +43,7 @@ local function fetch(_, job)
paths[#paths + 1] = tostring(file.url) paths[#paths + 1] = tostring(file.url)
end end
local output, err = Command("tag"):args(paths):stdout(Command.PIPED):output() local output, err = Command("tag"):arg(paths):stdout(Command.PIPED):output()
if not output then if not output then
return true, Err("Cannot spawn `tag` command, error: %s", err) return true, Err("Cannot spawn `tag` command, error: %s", err)
end end
@@ -76,7 +76,7 @@ end)
local function entry(self, job) local function entry(self, job)
assert(job.args[1] == "add" or job.args[1] == "remove", "Invalid action") assert(job.args[1] == "add" or job.args[1] == "remove", "Invalid action")
ya.mgr_emit("escape", { visual = true }) ya.emit("escape", { visual = true })
local cands = cands() local cands = cands()
local choice = ya.which { cands = cands } local choice = ya.which { cands = cands }
@@ -91,7 +91,7 @@ local function entry(self, job)
files[#files + 1] = { url = url } files[#files + 1] = { url = url }
end end
local status = Command("tag"):args(t):status() local status = Command("tag"):arg(t):status()
if status.success then if status.success then
fetch(self, { files = files }) fetch(self, { files = files })
end end

View File

@@ -1,4 +1,4 @@
--- @since 25.4.4 --- @since 25.5.28
local FILES = { local FILES = {
[".envrc"] = "text/plain", [".envrc"] = "text/plain",
@@ -1096,7 +1096,7 @@ function M:fetch(job)
end end
if next(updates) then if next(updates) then
ya.mgr_emit("update_mimes", { updates = updates }) ya.emit("update_mimes", { updates = updates })
end end
if #unknown > 0 then if #unknown > 0 then

View File

@@ -1,8 +1,5 @@
# mount.yazi # mount.yazi
> [!NOTE]
> Yazi v25.2.7 or later is required for this plugin to work.
A mount manager for Yazi, providing disk mount, unmount, and eject functionality. A mount manager for Yazi, providing disk mount, unmount, and eject functionality.
Supported platforms: Supported platforms:

View File

@@ -1,4 +1,4 @@
--- @since 25.2.26 --- @since 25.5.28
local toggle_ui = ya.sync(function(self) local toggle_ui = ya.sync(function(self)
if self.children then if self.children then
@@ -12,7 +12,7 @@ end)
local subscribe = ya.sync(function(self) local subscribe = ya.sync(function(self)
ps.unsub("mount") ps.unsub("mount")
ps.sub("mount", function() ya.mgr_emit("plugin", { self._id, "refresh" }) end) ps.sub("mount", function() ya.emit("plugin", { self._id, "refresh" }) end)
end) end)
local update_partitions = ya.sync(function(self, partitions) local update_partitions = ya.sync(function(self, partitions)
@@ -113,7 +113,7 @@ function M:entry(job)
elseif run == "enter" then elseif run == "enter" then
local active = active_partition() local active = active_partition()
if active and active.dist then if active and active.dist then
ya.mgr_emit("cd", { active.dist }) ya.emit("cd", { active.dist })
end end
else else
tx2:send(run) tx2:send(run)
@@ -233,7 +233,7 @@ function M.fillin(tbl)
return tbl return tbl
end end
local output, err = Command("lsblk"):args({ "-p", "-o", "name,fstype", "-J" }):args(sources):output() local output, err = Command("lsblk"):arg({ "-p", "-o", "name,fstype", "-J" }):arg(sources):output()
if err then if err then
ya.dbg("Failed to fetch filesystem types for unmounted partitions: " .. err) ya.dbg("Failed to fetch filesystem types for unmounted partitions: " .. err)
return tbl return tbl
@@ -256,14 +256,14 @@ function M.operate(type)
local output, err local output, err
if ya.target_os() == "macos" then if ya.target_os() == "macos" then
output, err = Command("diskutil"):args({ type, active.src }):output() output, err = Command("diskutil"):arg({ type, active.src }):output()
end end
if ya.target_os() == "linux" then if ya.target_os() == "linux" then
if type == "eject" then if type == "eject" then
Command("udisksctl"):args({ "unmount", "-b", active.src }):status() Command("udisksctl"):arg({ "unmount", "-b", active.src }):status()
output, err = Command("udisksctl"):args({ "power-off", "-b", active.src }):output() output, err = Command("udisksctl"):arg({ "power-off", "-b", active.src }):output()
else else
output, err = Command("udisksctl"):args({ type, "-b", active.src }):output() output, err = Command("udisksctl"):arg({ type, "-b", active.src }):output()
end end
end end

View File

@@ -1,4 +1,4 @@
--- @since 25.4.8 --- @since 25.5.28
local M = {} local M = {}
@@ -10,13 +10,9 @@ end
function M:peek(job) function M:peek(job)
local child, err = Command("sh") local child, err = Command("sh")
:args({ :arg({ "-c", job.args[1], "sh", tostring(job.file.url) })
"-c",
job.args[1],
})
:env("w", job.area.w) :env("w", job.area.w)
:env("h", job.area.h) :env("h", job.area.h)
:args({ "sh", tostring(job.file.url) })
:stdout(Command.PIPED) :stdout(Command.PIPED)
:stderr(Command.PIPED) :stderr(Command.PIPED)
:spawn() :spawn()
@@ -45,7 +41,7 @@ function M:peek(job)
if #errs > 0 then if #errs > 0 then
fail(job, table.concat(errs, "")) fail(job, table.concat(errs, ""))
elseif job.skip > 0 and i < job.skip + limit then elseif job.skip > 0 and i < job.skip + limit then
ya.mgr_emit("peek", { math.max(0, i - limit), only_if = job.file.url, upper_bound = true }) ya.emit("peek", { math.max(0, i - limit), only_if = job.file.url, upper_bound = true })
else else
ya.preview_widgets(job, { M.format(job, outs) }) ya.preview_widgets(job, { M.format(job, outs) })
end end

View File

@@ -1,11 +1,11 @@
--- @since 25.2.26 --- @since 25.5.28
--- @sync entry --- @sync entry
local function setup(self, opts) self.open_multi = opts.open_multi end local function setup(self, opts) self.open_multi = opts.open_multi end
local function entry(self) local function entry(self)
local h = cx.active.current.hovered local h = cx.active.current.hovered
ya.mgr_emit(h and h.cha.is_dir and "enter" or "open", { hovered = not self.open_multi }) ya.emit(h and h.cha.is_dir and "enter" or "open", { hovered = not self.open_multi })
end end
return { entry = entry, setup = setup } return { entry = entry, setup = setup }

View File

@@ -1,4 +1,4 @@
--- @since 25.2.26 --- @since 25.5.28
local hovered = ya.sync(function() local hovered = ya.sync(function()
local h = cx.active.current.hovered local h = cx.active.current.hovered
@@ -28,20 +28,20 @@ local function entry()
while true do while true do
local value, event = input:recv() local value, event = input:recv()
if event ~= 1 and event ~= 3 then if event ~= 1 and event ~= 3 then
ya.mgr_emit("escape", { filter = true }) ya.emit("escape", { filter = true })
break break
end end
ya.mgr_emit("filter_do", { value, smart = true }) ya.emit("filter_do", { value, smart = true })
local h = hovered() local h = hovered()
if h.unique and h.is_dir then if h.unique and h.is_dir then
ya.mgr_emit("escape", { filter = true }) ya.emit("escape", { filter = true })
ya.mgr_emit("enter", {}) ya.emit("enter", {})
input = prompt() input = prompt()
elseif event == 1 then elseif event == 1 then
ya.mgr_emit("escape", { filter = true }) ya.emit("escape", { filter = true })
ya.mgr_emit(h.is_dir and "enter" or "open", { h.url }) ya.emit(h.is_dir and "enter" or "open", { h.url })
end end
end end
end end

View File

@@ -1,13 +1,14 @@
--- @since 25.5.28
--- @sync entry --- @sync entry
return { return {
entry = function() entry = function()
local h = cx.active.current.hovered local h = cx.active.current.hovered
if h and h.cha.is_dir then if h and h.cha.is_dir then
ya.mgr_emit("enter", {}) ya.emit("enter", {})
ya.mgr_emit("paste", {}) ya.emit("paste", {})
ya.mgr_emit("leave", {}) ya.emit("leave", {})
else else
ya.mgr_emit("paste", {}) ya.emit("paste", {})
end end
end, end,
} }

View File

@@ -1,9 +1,9 @@
--- @since 25.2.7 --- @since 25.5.28
--- Verify if `sudo` is already authenticated --- Verify if `sudo` is already authenticated
--- @return boolean --- @return boolean
local function sudo_already() local function sudo_already()
local status = Command("sudo"):args({ "--validate", "--non-interactive" }):status() local status = Command("sudo"):arg({ "--validate", "--non-interactive" }):status()
assert(status, "Failed to run `sudo --validate --non-interactive`") assert(status, "Failed to run `sudo --validate --non-interactive`")
return status.success return status.success
end end
@@ -16,7 +16,7 @@ end
--- nil: no error --- nil: no error
--- 1: sudo failed --- 1: sudo failed
local function run_with_sudo(program, args) local function run_with_sudo(program, args)
local cmd = Command("sudo"):args { program, table.unpack(args) } local cmd = Command("sudo"):arg(program):arg(args)
if sudo_already() then if sudo_already() then
return cmd:output() return cmd:output()
end end

View File

@@ -1,4 +1,4 @@
--- @since 25.4.8 --- @since 25.5.28
local root = ya.sync(function() return cx.active.current.cwd end) local root = ya.sync(function() return cx.active.current.cwd end)
@@ -6,7 +6,7 @@ local function fail(content) return ya.notify { title = "VCS Files", content = c
local function entry() local function entry()
local root = root() local root = root()
local output, err = Command("git"):cwd(tostring(root)):args({ "diff", "--name-only", "HEAD" }):output() local output, err = Command("git"):cwd(tostring(root)):arg({ "diff", "--name-only", "HEAD" }):output()
if err then if err then
return fail("Failed to run `git diff`, error: " .. err) return fail("Failed to run `git diff`, error: " .. err)
elseif not output.status.success then elseif not output.status.success then
@@ -15,8 +15,8 @@ local function entry()
local id = ya.id("ft") local id = ya.id("ft")
local cwd = root:into_search("Git changes") local cwd = root:into_search("Git changes")
ya.mgr_emit("cd", { Url(cwd) }) ya.emit("cd", { Url(cwd) })
ya.mgr_emit("update_files", { op = fs.op("part", { id = id, url = Url(cwd), files = {} }) }) ya.emit("update_files", { op = fs.op("part", { id = id, url = Url(cwd), files = {} }) })
local files = {} local files = {}
for line in output.stdout:gmatch("[^\r\n]+") do for line in output.stdout:gmatch("[^\r\n]+") do
@@ -26,8 +26,8 @@ local function entry()
files[#files + 1] = File { url = url, cha = cha } files[#files + 1] = File { url = url, cha = cha }
end end
end end
ya.mgr_emit("update_files", { op = fs.op("part", { id = id, url = Url(cwd), files = files }) }) ya.emit("update_files", { op = fs.op("part", { id = id, url = Url(cwd), files = files }) })
ya.mgr_emit("update_files", { op = fs.op("done", { id = id, url = cwd, cha = Cha { kind = 16 } }) }) ya.emit("update_files", { op = fs.op("done", { id = id, url = cwd, cha = Cha { kind = 16 } }) })
end end
return { entry = entry } return { entry = entry }