mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
feat: new experimental ya.co() API that creates a coroutine (#3757)
This commit is contained in:
parent
e4829372db
commit
3534ba0705
7 changed files with 126 additions and 118 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 ([#3757])
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
@ -1680,3 +1681,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/):
|
||||||
[#3733]: https://github.com/sxyazi/yazi/pull/3733
|
[#3733]: https://github.com/sxyazi/yazi/pull/3733
|
||||||
[#3744]: https://github.com/sxyazi/yazi/pull/3744
|
[#3744]: https://github.com/sxyazi/yazi/pull/3744
|
||||||
[#3748]: https://github.com/sxyazi/yazi/pull/3748
|
[#3748]: https://github.com/sxyazi/yazi/pull/3748
|
||||||
|
[#3757]: https://github.com/sxyazi/yazi/pull/3757
|
||||||
|
|
|
||||||
53
Cargo.lock
generated
53
Cargo.lock
generated
|
|
@ -1970,9 +1970,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.25.9"
|
version = "0.25.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a"
|
checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"byteorder-lite",
|
"byteorder-lite",
|
||||||
|
|
@ -1980,15 +1980,15 @@ dependencies = [
|
||||||
"exr",
|
"exr",
|
||||||
"gif",
|
"gif",
|
||||||
"image-webp",
|
"image-webp",
|
||||||
"moxcms 0.7.11",
|
"moxcms",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"png",
|
"png",
|
||||||
"qoi",
|
"qoi",
|
||||||
"ravif",
|
"ravif",
|
||||||
"rgb",
|
"rgb",
|
||||||
"tiff",
|
"tiff",
|
||||||
"zune-core 0.5.1",
|
"zune-core",
|
||||||
"zune-jpeg 0.5.12",
|
"zune-jpeg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2533,16 +2533,6 @@ dependencies = [
|
||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "moxcms"
|
|
||||||
version = "0.7.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ac9557c559cd6fc9867e122e20d2cbefc9ca29d80d027a8e39310920ed2f0a97"
|
|
||||||
dependencies = [
|
|
||||||
"num-traits",
|
|
||||||
"pxfm",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "moxcms"
|
name = "moxcms"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
|
@ -3590,9 +3580,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ravif"
|
name = "ravif"
|
||||||
version = "0.12.0"
|
version = "0.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef69c1990ceef18a116855938e74793a5f7496ee907562bd0857b6ac734ab285"
|
checksum = "e52310197d971b0f5be7fe6b57530dcd27beb35c1b013f29d66c1ad73fbbcc45"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"avif-serialize",
|
"avif-serialize",
|
||||||
"imgref",
|
"imgref",
|
||||||
|
|
@ -4531,16 +4521,16 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiff"
|
name = "tiff"
|
||||||
version = "0.10.3"
|
version = "0.11.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f"
|
checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fax",
|
"fax",
|
||||||
"flate2",
|
"flate2",
|
||||||
"half",
|
"half",
|
||||||
"quick-error",
|
"quick-error",
|
||||||
"weezl",
|
"weezl",
|
||||||
"zune-jpeg 0.4.21",
|
"zune-jpeg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -5739,7 +5729,7 @@ dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"crossterm 0.29.0",
|
"crossterm 0.29.0",
|
||||||
"image",
|
"image",
|
||||||
"moxcms 0.8.1",
|
"moxcms",
|
||||||
"palette",
|
"palette",
|
||||||
"quantette",
|
"quantette",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
|
|
@ -6329,12 +6319,6 @@ version = "1.0.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zune-core"
|
|
||||||
version = "0.4.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zune-core"
|
name = "zune-core"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
|
@ -6352,18 +6336,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zune-jpeg"
|
name = "zune-jpeg"
|
||||||
version = "0.4.21"
|
version = "0.5.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713"
|
checksum = "ec5f41c76397b7da451efd19915684f727d7e1d516384ca6bd0ec43ec94de23c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zune-core 0.4.12",
|
"zune-core",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zune-jpeg"
|
|
||||||
version = "0.5.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "410e9ecef634c709e3831c2cfdb8d9c32164fae1c67496d5b68fff728eec37fe"
|
|
||||||
dependencies = [
|
|
||||||
"zune-core 0.5.1",
|
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ ansi-to-tui = { workspace = true }
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
base64 = { workspace = true }
|
base64 = { workspace = true }
|
||||||
crossterm = { workspace = true }
|
crossterm = { workspace = true }
|
||||||
image = { version = "0.25.9", default-features = false, features = [ "avif", "bmp", "dds", "exr", "ff", "gif", "hdr", "ico", "jpeg", "png", "pnm", "qoi", "tga", "tiff", "webp" ] }
|
image = { version = "0.25.10", default-features = false, features = [ "avif", "bmp", "dds", "exr", "ff", "gif", "hdr", "ico", "jpeg", "png", "pnm", "qoi", "tga", "tiff", "webp" ] }
|
||||||
moxcms = "0.8.1"
|
moxcms = "0.8.1"
|
||||||
palette = { version = "0.7.6", default-features = false }
|
palette = { version = "0.7.6", default-features = false }
|
||||||
quantette = { version = "0.5.1", default-features = false }
|
quantette = { version = "0.5.1", default-features = false }
|
||||||
|
|
|
||||||
|
|
@ -50,50 +50,57 @@ function M:seek(job)
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:spot(job)
|
function M:spot(job)
|
||||||
self.size, self.last = 0, 0
|
local i, url = 0, job.file.url
|
||||||
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
|
||||||
|
if self.size then
|
||||||
|
ya.emit("update_files", { op = fs.op("size", { url = url.parent, sizes = { [url.urn] = self.size } }) })
|
||||||
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 = {
|
self.size = nil
|
||||||
ui.Row({ "Folder" }):style(ui.Style():fg("green")),
|
return ya.co(function()
|
||||||
ui.Row { " Size:", ya.readable_size(self.size) .. (comp and "" or " (?)") },
|
yield("0B (?)")
|
||||||
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
|
||||||
|
|
||||||
|
self.size = size
|
||||||
|
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 or nil
|
||||||
: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, mut 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()
|
||||||
|
{
|
||||||
|
args = 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