automate/020_yazi-plugin_httm-zdbsta...

182 lines
4.6 KiB
Bash

#!/usr/bin/env bash
: <<!
# ------------------------------------------------------------------------------
# Yazi zdbstat previewer — pure Lua (preview pane, toggleable)
# Shows zdb -dddddddddd output in preview when toggled on
# Requires: zfs, zdb, stat, realpath, sudo/doas/pkexec
# ------------------------------------------------------------------------------
!
set -euo pipefail
DEST=${1:-/etc/skel/}
YAZI_HOME="${DEST}/.config/yazi"
YAZI_PLUGIN_HOME="${YAZI_HOME}/plugins"
ZDBSTAT_PLUGIN_HOME="${YAZI_PLUGIN_HOME}/httm-zdbstat.yazi"
mkdir -p "$PLUGIN_HOME"
cat >"${ZDBSTAT_PLUGIN_HOME}/main.lua" <<'EOF'
-- zdbstat.yazi/init.lua
-- Custom previewer: dump zdb -dddddddddd metadata when mode enabled
local M = {}
-- Global toggle state (persists across calls via _G)
local mode_get = ya.sync(function() return _G.ZDBSTAT_MODE or "none" end)
function M:peek(job)
local mode = mode_get()
if mode == "none" then
return -- Let default previewer handle it
end
local path = tostring(job.url)
-- Resolve realpath
local rp = ""
local rp_child = Command("realpath"):arg(path):stdout(Command.PIPED):spawn()
if rp_child then
rp_child:wait()
rp = rp_child:read_line() or path
rp = rp:gsub("\n$", "")
end
if rp == "" then rp = path end
-- Get dataset via zfs list
local dataset = ""
local ds_child = Command("zfs"):arg("list"):arg("-H"):arg("-o"):arg("name"):arg(rp)
:stdout(Command.PIPED):stderr(Command.PIPED):spawn()
if ds_child then
ds_child:wait()
dataset = ds_child:read_line() or ""
dataset = dataset:gsub("\n$", "")
end
if dataset == "" then
ya.preview_widget(job, ui.Text("Not a ZFS path or dataset not found"):area(job.area))
return
end
-- Get inode
local inode = ""
local st_child = Command("stat"):arg("-c"):arg("%i"):arg(rp)
:stdout(Command.PIPED):spawn()
if st_child then
st_child:wait()
inode = st_child:read_line() or ""
inode = inode:gsub("\n$", "")
end
if inode == "" then
ya.preview_widget(job, ui.Text("Could not get inode"):area(job.area))
return
end
-- Find sudo-like
local elevator = nil
for _, e in ipairs({"sudo", "doas", "pkexec"}) do
local test = Command(e):arg("--version"):stdout(Command.PIPED):stderr(Command.PIPED):spawn()
if test then
test:wait()
if test.status and test.status.success then
elevator = e
break
end
end
end
-- Build zdb command
local zdb_cmd = Command("zdb"):arg("-dddddddddd"):arg(dataset):arg(inode)
if elevator then
zdb_cmd = Command(elevator):arg(zdb_cmd._program):args(zdb_cmd._args or {})
end
-- Capture output (PIPED so we can show in preview)
zdb_cmd:stdout(Command.PIPED):stderr(Command.PIPED)
local child, err = zdb_cmd:spawn()
if not child then
ya.preview_widget(job, ui.Text("Failed to run zdb: " .. tostring(err)):area(job.area))
return
end
child:wait()
local output = ""
for line in child:read_lines() do
output = output .. line .. "\n"
end
if output == "" then
output = "zdb returned no output (check permissions?)"
end
-- Show in preview with log-like highlighting
ya.preview_code({
area = job.area,
content = output,
filetype = "log", -- or "text" if no bat-like highlighting desired
})
end
function M:seek(job)
self:peek(job) -- No advanced seeking needed
end
return M
EOF
cat >"${ZDBSTAT_PLUGIN_HOME}/toggle.lua" <<'EOF'
-- zdbstat.yazi/toggle.lua (separate entry plugin to cycle mode)
return {
entry = function()
local modes = { "none", "zdb" }
local current = _G.ZDBSTAT_MODE or "none"
local next_mode = "none"
for i, m in ipairs(modes) do
if m == current then
next_mode = modes[(i % #modes) + 1]
break
end
end
_G.ZDBSTAT_MODE = next_mode
ya.notify({
title = "zdbstat",
content = "Preview mode: " .. next_mode,
timeout = 2,
})
-- Refresh current preview
if cx.active.current.hovered then
ya.manager_emit("peek", { cx.active.preview.skip or 0, force = true })
end
end,
}
EOF
cat <<'EOF'
Add to your yazi.toml (or yazi.toml.d/):
[plugin.preview]
prepend_previewers = [
{ name = "*", run = "zdbstat", sync = true },
]
Add to keymap.toml:
[[manager.prepend_keymap]]
on = [ "g", "z" ]
run = "plugin zdbstat --args='toggle'"
desc = "Toggle zdbstat preview (zdb metadata / default)"
EOF
echo "zdbstat previewer installed at: ${PLUGIN_HOME}/init.lua"
echo "Toggle entry at: ${PLUGIN_HOME}/toggle.lua"
echo "Restart yazi or :plugin --reload zdbstat"
echo "Press 'gz' to cycle: default preview ↔ zdb metadata preview"
echo "Note: First zdb run may prompt for sudo/doas password (terminal popup)."