mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +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])
|
- Custom tab name ([#3666])
|
||||||
- New `--in` for `search` action to set search directory ([#3696])
|
- New `--in` for `search` action to set search directory ([#3696])
|
||||||
|
- Multi-file spotter ([#3733])
|
||||||
- New `hovered` condition specifying different icons for hovered files ([#3728])
|
- New `hovered` condition specifying different icons for hovered files ([#3728])
|
||||||
- Allow using `ps.sub()` in `init.lua` directly without a plugin ([#3638])
|
- Allow using `ps.sub()` in `init.lua` directly without a plugin ([#3638])
|
||||||
- New `sort_fallback` option to control fallback sorting behavior ([#3077])
|
- 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
|
[#3708]: https://github.com/sxyazi/yazi/pull/3708
|
||||||
[#3725]: https://github.com/sxyazi/yazi/pull/3725
|
[#3725]: https://github.com/sxyazi/yazi/pull/3725
|
||||||
[#3728]: https://github.com/sxyazi/yazi/pull/3728
|
[#3728]: https://github.com/sxyazi/yazi/pull/3728
|
||||||
|
[#3733]: https://github.com/sxyazi/yazi/pull/3733
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use yazi_macro::succ;
|
use yazi_macro::{act, succ};
|
||||||
use yazi_parser::mgr::SpotOpt;
|
use yazi_parser::mgr::SpotOpt;
|
||||||
use yazi_shared::data::Data;
|
use yazi_shared::{data::Data, pool::InternStr};
|
||||||
|
|
||||||
use crate::{Actor, Ctx};
|
use crate::{Actor, Ctx};
|
||||||
|
|
||||||
|
|
@ -13,9 +13,15 @@ impl Actor for Spot {
|
||||||
const NAME: &str = "spot";
|
const NAME: &str = "spot";
|
||||||
|
|
||||||
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
|
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
|
||||||
|
act!(mgr:escape_visual, cx)?;
|
||||||
let Some(hovered) = cx.hovered().cloned() else { succ!() };
|
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) {
|
// if !self.active().spot.same_file(&hovered, &mime) {
|
||||||
// self.active_mut().spot.reset();
|
// self.active_mut().spot.reset();
|
||||||
// }
|
// }
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,9 @@ fetchers = [
|
||||||
{ id = "mime", url = "remote://*", run = "mime.remote", prio = "high" },
|
{ id = "mime", url = "remote://*", run = "mime.remote", prio = "high" },
|
||||||
]
|
]
|
||||||
spotters = [
|
spotters = [
|
||||||
|
# Multi-file
|
||||||
|
{ mime = "multi/*", run = "multi" },
|
||||||
|
# Folder
|
||||||
{ url = "*/", run = "folder" },
|
{ url = "*/", run = "folder" },
|
||||||
# Code
|
# Code
|
||||||
{ mime = "text/*", run = "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.dir".to_owned(), preset!("plugins/mime-dir").into()),
|
||||||
("mime.local".to_owned(), preset!("plugins/mime-local").into()),
|
("mime.local".to_owned(), preset!("plugins/mime-local").into()),
|
||||||
("mime.remote".to_owned(), preset!("plugins/mime-remote").into()),
|
("mime.remote".to_owned(), preset!("plugins/mime-remote").into()),
|
||||||
|
("multi".to_owned(), preset!("plugins/multi").into()),
|
||||||
("noop".to_owned(), preset!("plugins/noop").into()),
|
("noop".to_owned(), preset!("plugins/noop").into()),
|
||||||
("null".to_owned(), preset!("plugins/null").into()),
|
("null".to_owned(), preset!("plugins/null").into()),
|
||||||
("pdf".to_owned(), preset!("plugins/pdf").into()),
|
("pdf".to_owned(), preset!("plugins/pdf").into()),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue