mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 14:51:03 +00:00
feat: multi-file spotter (#3733)
Co-authored-by: sxyazi <sxyazi@gmail.com>
This commit is contained in:
parent
be91b4111c
commit
dbf81deeab
5 changed files with 88 additions and 3 deletions
|
|
@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
|
||||
- Custom tab name ([#3666])
|
||||
- New `--in` for `search` action to set search directory ([#3696])
|
||||
- Multi-file spotter ([#3733])
|
||||
- New `hovered` condition specifying different icons for hovered files ([#3728])
|
||||
- Allow using `ps.sub()` in `init.lua` directly without a plugin ([#3638])
|
||||
- New `sort_fallback` option to control fallback sorting behavior ([#3077])
|
||||
|
|
@ -1672,3 +1673,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
|||
[#3708]: https://github.com/sxyazi/yazi/pull/3708
|
||||
[#3725]: https://github.com/sxyazi/yazi/pull/3725
|
||||
[#3728]: https://github.com/sxyazi/yazi/pull/3728
|
||||
[#3733]: https://github.com/sxyazi/yazi/pull/3733
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::Result;
|
||||
use yazi_macro::succ;
|
||||
use yazi_macro::{act, succ};
|
||||
use yazi_parser::mgr::SpotOpt;
|
||||
use yazi_shared::data::Data;
|
||||
use yazi_shared::{data::Data, pool::InternStr};
|
||||
|
||||
use crate::{Actor, Ctx};
|
||||
|
||||
|
|
@ -13,9 +13,15 @@ impl Actor for Spot {
|
|||
const NAME: &str = "spot";
|
||||
|
||||
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
|
||||
act!(mgr:escape_visual, cx)?;
|
||||
let Some(hovered) = cx.hovered().cloned() else { succ!() };
|
||||
|
||||
let mime = cx.mgr.mimetype.owned(&hovered.url).unwrap_or_default();
|
||||
let mime = if cx.tab().selected.is_empty() {
|
||||
cx.mgr.mimetype.owned(&hovered.url).unwrap_or_default()
|
||||
} else {
|
||||
"multi/unknown".intern()
|
||||
};
|
||||
|
||||
// if !self.active().spot.same_file(&hovered, &mime) {
|
||||
// self.active_mut().spot.reset();
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -105,6 +105,9 @@ fetchers = [
|
|||
{ id = "mime", url = "remote://*", run = "mime.remote", prio = "high" },
|
||||
]
|
||||
spotters = [
|
||||
# Multi-file
|
||||
{ mime = "multi/*", run = "multi" },
|
||||
# Folder
|
||||
{ url = "*/", run = "folder" },
|
||||
# Code
|
||||
{ mime = "text/*", run = "code" },
|
||||
|
|
|
|||
73
yazi-plugin/preset/plugins/multi.lua
Normal file
73
yazi-plugin/preset/plugins/multi.lua
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
--- @sync peek
|
||||
|
||||
local M = {}
|
||||
|
||||
local selected = ya.sync(function()
|
||||
local urls = {}
|
||||
for _, u in pairs(cx.active.selected) do
|
||||
urls[#urls + 1] = u
|
||||
end
|
||||
return urls
|
||||
end)
|
||||
|
||||
function M:spot(job)
|
||||
self.sum, self.sizes, self.last, self.selected = 0, {}, 0, selected()
|
||||
self:spot_multi(job, false)
|
||||
|
||||
for _, u in ipairs(self.selected) do
|
||||
local it, size = fs.calc_size(u), 0
|
||||
while true do
|
||||
local next = it:recv()
|
||||
if next then
|
||||
size, self.sum = size + next, self.sum + next
|
||||
self:spot_multi(job, false)
|
||||
else
|
||||
self.sizes[u], size = size, 0
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:spot_multi(job, true)
|
||||
end
|
||||
|
||||
function M:spot_multi(job, comp)
|
||||
local now = ya.time()
|
||||
if not comp and now < self.last + 0.1 then
|
||||
return
|
||||
end
|
||||
|
||||
local rows = {
|
||||
ui.Row({ "Multi" }):style(ui.Style():fg("green")),
|
||||
ui.Row { " Count:", string.format("%d selected", #self.selected) },
|
||||
ui.Row { " Size:", ya.readable_size(self.sum) .. (comp and "" or " (?)") },
|
||||
}
|
||||
|
||||
ya.spot_table(
|
||||
job,
|
||||
ui.Table(rows)
|
||||
:area(ui.Pos { "center", w = 60, h = 20 })
|
||||
:row(self.last == 0 and 1 or nil)
|
||||
:col(1)
|
||||
:col_style(th.spot.tbl_col)
|
||||
:cell_style(th.spot.tbl_cell)
|
||||
:widths { ui.Constraint.Length(14), ui.Constraint.Fill(1) }
|
||||
)
|
||||
|
||||
self:update_sizes()
|
||||
self.last = now
|
||||
end
|
||||
|
||||
function M:update_sizes()
|
||||
local parents = {}
|
||||
for url, size in pairs(self.sizes) do
|
||||
local p = url.parent
|
||||
parents[p] = parents[p] or {}
|
||||
parents[p][url.urn] = size
|
||||
end
|
||||
for parent, sizes in pairs(parents) do
|
||||
ya.emit("update_files", { op = fs.op("size", { url = parent, sizes = sizes }) })
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
@ -44,6 +44,7 @@ impl Default for Loader {
|
|||
("mime.dir".to_owned(), preset!("plugins/mime-dir").into()),
|
||||
("mime.local".to_owned(), preset!("plugins/mime-local").into()),
|
||||
("mime.remote".to_owned(), preset!("plugins/mime-remote").into()),
|
||||
("multi".to_owned(), preset!("plugins/multi").into()),
|
||||
("noop".to_owned(), preset!("plugins/noop").into()),
|
||||
("null".to_owned(), preset!("plugins/null").into()),
|
||||
("pdf".to_owned(), preset!("plugins/pdf").into()),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue