mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: experimental ya.co() API that creates a coroutine
This commit is contained in:
parent
e4829372db
commit
6ca1c6315a
5 changed files with 105 additions and 78 deletions
|
|
@ -31,6 +31,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
||||||
- New `ind-which-activate` DDS event to change the which component behavior ([#3608])
|
- New `ind-which-activate` DDS event to change the which component behavior ([#3608])
|
||||||
- New `hey` DDS event fires when static messages are restored from persistence ([#3725])
|
- New `hey` DDS event fires when static messages are restored from persistence ([#3725])
|
||||||
- New `cx.which` API to access the which component state ([#3617])
|
- New `cx.which` API to access the which component state ([#3617])
|
||||||
|
- New experimental `ya.co()` API that creates a coroutine ([#1234])
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,50 +50,52 @@ function M:seek(job)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:spot(job)
|
function M:spot(job)
|
||||||
self.size, self.last = 0, 0
|
local i = 0
|
||||||
self:spot_multi(job, false)
|
for rows in self:spot_base(job) do
|
||||||
|
i, rows[#rows + 1] = i + 1, ui.Row {}
|
||||||
local url = job.file.url
|
ya.spot_table(
|
||||||
local it = fs.calc_size(url)
|
job,
|
||||||
while it do
|
ui.Table(ya.list_merge(rows, require("file"):spot_base(job)))
|
||||||
local next = it:recv()
|
:area(ui.Pos { "center", w = 60, h = 20 })
|
||||||
if next then
|
:row(i == 1 and 1 or nil)
|
||||||
self.size = self.size + next
|
:col(1)
|
||||||
self:spot_multi(job, false)
|
:col_style(th.spot.tbl_col)
|
||||||
else
|
:cell_style(th.spot.tbl_cell)
|
||||||
break
|
:widths { ui.Constraint.Length(14), ui.Constraint.Fill(1) }
|
||||||
end
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
local op = fs.op("size", { url = url.parent, sizes = { [url.urn] = self.size } })
|
|
||||||
ya.emit("update_files", { op = op })
|
|
||||||
|
|
||||||
self:spot_multi(job, true)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:spot_multi(job, comp)
|
function M:spot_base(job)
|
||||||
local now = ya.time()
|
local function yield(s)
|
||||||
if not comp and now < self.last + 0.1 then
|
coroutine.yield {
|
||||||
return
|
ui.Row({ "Folder" }):style(ui.Style():fg("green")),
|
||||||
|
ui.Row { " Size:", s },
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local rows = {
|
return ya.co(function()
|
||||||
ui.Row({ "Folder" }):style(ui.Style():fg("green")),
|
yield("0B (?)")
|
||||||
ui.Row { " Size:", ya.readable_size(self.size) .. (comp and "" or " (?)") },
|
|
||||||
ui.Row {},
|
|
||||||
}
|
|
||||||
|
|
||||||
ya.spot_table(
|
local it, size, last = fs.calc_size(job.file.url), 0, 0
|
||||||
job,
|
if not it then
|
||||||
ui.Table(ya.list_merge(rows, require("file"):spot_base(job)))
|
return yield("Error")
|
||||||
:area(ui.Pos { "center", w = 60, h = 20 })
|
end
|
||||||
:row(self.last == 0 and 1 or nil)
|
|
||||||
:col(1)
|
while true do
|
||||||
:col_style(th.spot.tbl_col)
|
local next, now = it:recv(), ya.time()
|
||||||
:cell_style(th.spot.tbl_cell)
|
if not next then
|
||||||
:widths { ui.Constraint.Length(14), ui.Constraint.Fill(1) }
|
break
|
||||||
)
|
elseif now >= last + 0.1 then
|
||||||
self.last = now
|
last, size = now, size + next
|
||||||
|
yield(ya.readable_size(size) .. " (?)")
|
||||||
|
else
|
||||||
|
size = size + next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
yield(ya.readable_size(size))
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -9,53 +9,55 @@ local selected = ya.sync(function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
function M:spot(job)
|
function M:spot(job)
|
||||||
self.sum, self.sizes, self.last, self.selected = 0, {}, 0, selected()
|
local i = 0
|
||||||
self:spot_multi(job, false)
|
for rows in self:spot_base(job, selected()) do
|
||||||
|
i = i + 1
|
||||||
for _, u in ipairs(self.selected) do
|
ya.spot_table(
|
||||||
local it, size = fs.calc_size(u), 0
|
job,
|
||||||
while it do
|
ui.Table(rows)
|
||||||
local next = it:recv()
|
:area(ui.Pos { "center", w = 60, h = 20 })
|
||||||
if next then
|
:row(i == 1 and 1 or nil)
|
||||||
size, self.sum = size + next, self.sum + next
|
:col(1)
|
||||||
self:spot_multi(job, false)
|
:col_style(th.spot.tbl_col)
|
||||||
elseif it.cha.is_dir then
|
:cell_style(th.spot.tbl_cell)
|
||||||
self.sizes[u] = size
|
:widths { ui.Constraint.Length(14), ui.Constraint.Fill(1) }
|
||||||
break
|
)
|
||||||
else
|
self:update_sizes()
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
self:spot_multi(job, true)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:spot_multi(job, comp)
|
function M:spot_base(_, selected)
|
||||||
local now = ya.time()
|
local function yield(s)
|
||||||
if not comp and now < self.last + 0.1 then
|
coroutine.yield {
|
||||||
return
|
ui.Row({ "Multi" }):style(ui.Style():fg("green")),
|
||||||
|
ui.Row { " Size:", s },
|
||||||
|
ui.Row { " Count:", string.format("%d selected", #selected) },
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local rows = {
|
self.sizes = {}
|
||||||
ui.Row({ "Multi" }):style(ui.Style():fg("green")),
|
return ya.co(function()
|
||||||
ui.Row { " Size:", ya.readable_size(self.sum) .. (comp and "" or " (?)") },
|
yield("0B (?)")
|
||||||
ui.Row { " Count:", string.format("%d selected", #self.selected) },
|
|
||||||
}
|
|
||||||
|
|
||||||
ya.spot_table(
|
local sum, last = 0, 0
|
||||||
job,
|
for _, url in ipairs(selected) do
|
||||||
ui.Table(rows)
|
local it, size = fs.calc_size(url), 0
|
||||||
:area(ui.Pos { "center", w = 60, h = 20 })
|
while it do
|
||||||
:row(self.last == 0 and 1 or nil)
|
local next, now = it:recv(), ya.time()
|
||||||
:col(1)
|
if not next then
|
||||||
:col_style(th.spot.tbl_col)
|
self.sizes[url] = it.cha.is_dir and size
|
||||||
:cell_style(th.spot.tbl_cell)
|
break
|
||||||
:widths { ui.Constraint.Length(14), ui.Constraint.Fill(1) }
|
elseif now >= last + 0.1 then
|
||||||
)
|
last, size, sum = now, size + next, sum + next
|
||||||
|
yield(ya.readable_size(sum) .. " (?)")
|
||||||
|
else
|
||||||
|
size, sum = size + next, sum + next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
self:update_sizes()
|
yield(ya.readable_size(sum))
|
||||||
self.last = now
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:update_sizes()
|
function M:update_sizes()
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,27 @@ use super::Utils;
|
||||||
use crate::loader::LOADER;
|
use crate::loader::LOADER;
|
||||||
|
|
||||||
impl Utils {
|
impl Utils {
|
||||||
|
pub(super) fn co(lua: &Lua) -> mlua::Result<Function> {
|
||||||
|
lua.create_function(|lua, f: Function| {
|
||||||
|
let thread = lua.create_thread(f)?;
|
||||||
|
lua.create_async_function(move |lua, args: MultiValue| {
|
||||||
|
let thread = thread.clone();
|
||||||
|
async move {
|
||||||
|
loop {
|
||||||
|
let values: MultiValue = thread.resume(&args)?;
|
||||||
|
if let Some(Value::LightUserData(ud)) = values.get(0)
|
||||||
|
&& *ud == Lua::poll_pending()
|
||||||
|
{
|
||||||
|
lua.yield_with::<()>(values).await?;
|
||||||
|
} else {
|
||||||
|
return Ok(values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn sync(lua: &Lua) -> mlua::Result<Function> {
|
pub(super) fn sync(lua: &Lua) -> mlua::Result<Function> {
|
||||||
lua.create_function(|lua, f: Function| {
|
lua.create_function(|lua, f: Function| {
|
||||||
let mut rt = runtime_mut!(lua)?;
|
let mut rt = runtime_mut!(lua)?;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ pub fn compose(
|
||||||
b"spot_widgets" => Utils::spot_widgets(lua)?,
|
b"spot_widgets" => Utils::spot_widgets(lua)?,
|
||||||
|
|
||||||
// Sync
|
// Sync
|
||||||
|
b"co" => Utils::co(lua)?,
|
||||||
b"sync" => Utils::sync(lua)?,
|
b"sync" => Utils::sync(lua)?,
|
||||||
b"async" => Utils::r#async(lua, isolate)?,
|
b"async" => Utils::r#async(lua, isolate)?,
|
||||||
b"chan" => Utils::chan(lua)?,
|
b"chan" => Utils::chan(lua)?,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue