#!/usr/bin/env bash : <"${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)."