mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: calculate real-time directory size in spotter (#2695)
This commit is contained in:
parent
54687181b3
commit
eba9f1e4f0
18 changed files with 170 additions and 26 deletions
|
|
@ -1,3 +1,3 @@
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
yazi_macro::mod_flat!(error id stage url);
|
yazi_macro::mod_flat!(error id stage url urn);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::{ops::Deref, path::Path};
|
||||||
|
|
||||||
use mlua::{AnyUserData, ExternalError, FromLua, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRef, Value};
|
use mlua::{AnyUserData, ExternalError, FromLua, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRef, Value};
|
||||||
|
|
||||||
use crate::cached_field;
|
use crate::{Urn, cached_field};
|
||||||
|
|
||||||
pub type UrlRef = UserDataRef<Url>;
|
pub type UrlRef = UserDataRef<Url>;
|
||||||
|
|
||||||
|
|
@ -12,6 +12,7 @@ pub struct Url {
|
||||||
v_name: Option<Value>,
|
v_name: Option<Value>,
|
||||||
v_stem: Option<Value>,
|
v_stem: Option<Value>,
|
||||||
v_ext: Option<Value>,
|
v_ext: Option<Value>,
|
||||||
|
v_urn: Option<Value>,
|
||||||
v_base: Option<Value>,
|
v_base: Option<Value>,
|
||||||
v_parent: Option<Value>,
|
v_parent: Option<Value>,
|
||||||
v_frag: Option<Value>,
|
v_frag: Option<Value>,
|
||||||
|
|
@ -39,6 +40,7 @@ impl Url {
|
||||||
v_name: None,
|
v_name: None,
|
||||||
v_stem: None,
|
v_stem: None,
|
||||||
v_ext: None,
|
v_ext: None,
|
||||||
|
v_urn: None,
|
||||||
v_base: None,
|
v_base: None,
|
||||||
v_parent: None,
|
v_parent: None,
|
||||||
v_frag: None,
|
v_frag: None,
|
||||||
|
|
@ -83,6 +85,7 @@ impl UserData for Url {
|
||||||
me.extension().map(|s| lua.create_string(s.as_encoded_bytes())).transpose()
|
me.extension().map(|s| lua.create_string(s.as_encoded_bytes())).transpose()
|
||||||
});
|
});
|
||||||
cached_field!(fields, parent, |_, me| Ok(me.parent_url().map(Self::new)));
|
cached_field!(fields, parent, |_, me| Ok(me.parent_url().map(Self::new)));
|
||||||
|
cached_field!(fields, urn, |_, me| Ok(Urn::new(me.urn_owned())));
|
||||||
cached_field!(fields, base, |_, me| {
|
cached_field!(fields, base, |_, me| {
|
||||||
Ok(if me.base().as_os_str().is_empty() { None } else { Some(Self::new(me.base())) })
|
Ok(if me.base().as_os_str().is_empty() { None } else { Some(Self::new(me.base())) })
|
||||||
});
|
});
|
||||||
|
|
|
||||||
32
yazi-binding/src/urn.rs
Normal file
32
yazi-binding/src/urn.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use mlua::{ExternalError, FromLua, Lua, UserData, Value};
|
||||||
|
|
||||||
|
pub struct Urn {
|
||||||
|
inner: yazi_shared::url::UrnBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Urn {
|
||||||
|
type Target = yazi_shared::url::UrnBuf;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target { &self.inner }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Urn> for yazi_shared::url::UrnBuf {
|
||||||
|
fn from(value: Urn) -> Self { value.inner }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Urn {
|
||||||
|
pub fn new(urn: yazi_shared::url::UrnBuf) -> Self { Self { inner: urn } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromLua for Urn {
|
||||||
|
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
|
||||||
|
Ok(match value {
|
||||||
|
Value::UserData(ud) => ud.take()?,
|
||||||
|
_ => Err("Expected a Urn".into_lua_err())?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UserData for Urn {}
|
||||||
|
|
@ -20,7 +20,7 @@ impl TryFrom<CmdCow> for Opt {
|
||||||
|
|
||||||
impl Mgr {
|
impl Mgr {
|
||||||
pub fn update_mimes(&mut self, opt: impl TryInto<Opt>, tasks: &Tasks) {
|
pub fn update_mimes(&mut self, opt: impl TryInto<Opt>, tasks: &Tasks) {
|
||||||
let Ok(opt) = opt.try_into() else {
|
let Ok(opt): Result<Opt, _> = opt.try_into() else {
|
||||||
return error!("invalid arguments for update_mimes");
|
return error!("invalid arguments for update_mimes");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
use yazi_macro::render;
|
|
||||||
use yazi_shared::event::CmdCow;
|
use yazi_shared::event::CmdCow;
|
||||||
|
|
||||||
use crate::spot::Spot;
|
use crate::spot::Spot;
|
||||||
|
|
@ -14,8 +13,5 @@ impl From<()> for Opt {
|
||||||
|
|
||||||
impl Spot {
|
impl Spot {
|
||||||
#[yazi_codegen::command]
|
#[yazi_codegen::command]
|
||||||
pub fn close(&mut self, _: Opt) {
|
pub fn close(&mut self, _: Opt) { self.reset(); }
|
||||||
self.abort();
|
|
||||||
render!(self.lock.take().is_some());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use std::borrow::Cow;
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use yazi_config::YAZI;
|
use yazi_config::YAZI;
|
||||||
use yazi_fs::File;
|
use yazi_fs::File;
|
||||||
|
use yazi_macro::render;
|
||||||
use yazi_plugin::{isolate, utils::SpotLock};
|
use yazi_plugin::{isolate, utils::SpotLock};
|
||||||
use yazi_shared::url::Url;
|
use yazi_shared::url::Url;
|
||||||
|
|
||||||
|
|
@ -36,6 +37,12 @@ impl Spot {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn abort(&mut self) { self.ct.take().map(|ct| ct.cancel()); }
|
pub fn abort(&mut self) { self.ct.take().map(|ct| ct.cancel()); }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.abort();
|
||||||
|
render!(self.lock.take().is_some());
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn same_url(&self, url: &Url) -> bool { self.lock.as_ref().is_some_and(|l| *url == l.url) }
|
pub fn same_url(&self, url: &Url) -> bool { self.lock.as_ref().is_some_and(|l| *url == l.url) }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,10 @@ impl TryFrom<CmdCow> for Opt {
|
||||||
impl Tab {
|
impl Tab {
|
||||||
pub fn update_spotted(&mut self, opt: impl TryInto<Opt>) {
|
pub fn update_spotted(&mut self, opt: impl TryInto<Opt>) {
|
||||||
let Some(hovered) = self.hovered().map(|h| &h.url) else {
|
let Some(hovered) = self.hovered().map(|h| &h.url) else {
|
||||||
return self.preview.reset();
|
return self.spot.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(opt) = opt.try_into() else {
|
let Ok(mut opt): Result<Opt, _> = opt.try_into() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -30,7 +30,14 @@ impl Tab {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.spot.skip = opt.lock.selected().unwrap_or_default();
|
if self.spot.lock.as_ref().is_none_or(|l| l.id != opt.lock.id) {
|
||||||
|
self.spot.skip = opt.lock.selected().unwrap_or_default();
|
||||||
|
} else if let Some(s) = opt.lock.selected() {
|
||||||
|
self.spot.skip = s;
|
||||||
|
} else {
|
||||||
|
opt.lock.select(Some(self.spot.skip));
|
||||||
|
}
|
||||||
|
|
||||||
self.spot.lock = Some(opt.lock);
|
self.spot.lock = Some(opt.lock);
|
||||||
render!();
|
render!();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@ impl Sendable {
|
||||||
Value::UserData(ud) => {
|
Value::UserData(ud) => {
|
||||||
if let Ok(t) = ud.take::<yazi_binding::Url>() {
|
if let Ok(t) = ud.take::<yazi_binding::Url>() {
|
||||||
Data::Url(t.into())
|
Data::Url(t.into())
|
||||||
|
} else if let Ok(t) = ud.take::<yazi_binding::Urn>() {
|
||||||
|
Data::Urn(t.into())
|
||||||
} else if let Ok(t) = ud.borrow::<yazi_binding::Id>() {
|
} else if let Ok(t) = ud.borrow::<yazi_binding::Id>() {
|
||||||
Data::Id(**t)
|
Data::Id(**t)
|
||||||
} else if let Ok(t) = ud.take::<yazi_fs::FilesOp>() {
|
} else if let Ok(t) = ud.take::<yazi_fs::FilesOp>() {
|
||||||
|
|
@ -50,7 +52,7 @@ impl Sendable {
|
||||||
} else if let Ok(t) = ud.take::<super::body::BodyYankIter>() {
|
} else if let Ok(t) = ud.take::<super::body::BodyYankIter>() {
|
||||||
Data::Any(Box::new(t))
|
Data::Any(Box::new(t))
|
||||||
} else {
|
} else {
|
||||||
Err("unsupported userdata included".into_lua_err())?
|
Err(format!("unsupported userdata included: {ud:?}").into_lua_err())?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Error(_) => Err("error is not supported".into_lua_err())?,
|
Value::Error(_) => Err("error is not supported".into_lua_err())?,
|
||||||
|
|
@ -76,12 +78,13 @@ impl Sendable {
|
||||||
Value::Table(tbl)
|
Value::Table(tbl)
|
||||||
}
|
}
|
||||||
Data::Url(u) => yazi_binding::Url::new(u).into_lua(lua)?,
|
Data::Url(u) => yazi_binding::Url::new(u).into_lua(lua)?,
|
||||||
|
Data::Urn(u) => yazi_binding::Urn::new(u).into_lua(lua)?,
|
||||||
Data::Any(a) => Value::UserData(if a.is::<yazi_fs::FilesOp>() {
|
Data::Any(a) => Value::UserData(if a.is::<yazi_fs::FilesOp>() {
|
||||||
lua.create_any_userdata(*a.downcast::<yazi_fs::FilesOp>().unwrap())?
|
lua.create_any_userdata(*a.downcast::<yazi_fs::FilesOp>().unwrap())?
|
||||||
} else if a.is::<super::body::BodyYankIter>() {
|
} else if a.is::<super::body::BodyYankIter>() {
|
||||||
lua.create_userdata(*a.downcast::<super::body::BodyYankIter>().unwrap())?
|
lua.create_userdata(*a.downcast::<super::body::BodyYankIter>().unwrap())?
|
||||||
} else {
|
} else {
|
||||||
Err("unsupported userdata included".into_lua_err())?
|
Err("unsupported Data::Any included".into_lua_err())?
|
||||||
}),
|
}),
|
||||||
data => Self::data_to_value_ref(lua, &data)?,
|
data => Self::data_to_value_ref(lua, &data)?,
|
||||||
})
|
})
|
||||||
|
|
@ -111,13 +114,14 @@ impl Sendable {
|
||||||
}
|
}
|
||||||
Data::Id(i) => yazi_binding::Id(*i).into_lua(lua)?,
|
Data::Id(i) => yazi_binding::Id(*i).into_lua(lua)?,
|
||||||
Data::Url(u) => yazi_binding::Url::new(u.clone()).into_lua(lua)?,
|
Data::Url(u) => yazi_binding::Url::new(u.clone()).into_lua(lua)?,
|
||||||
|
Data::Urn(u) => yazi_binding::Urn::new(u.clone()).into_lua(lua)?,
|
||||||
Data::Bytes(b) => Value::String(lua.create_string(b)?),
|
Data::Bytes(b) => Value::String(lua.create_string(b)?),
|
||||||
Data::Any(a) => Value::UserData(if let Some(t) = a.downcast_ref::<yazi_fs::FilesOp>() {
|
Data::Any(a) => Value::UserData(if let Some(t) = a.downcast_ref::<yazi_fs::FilesOp>() {
|
||||||
lua.create_any_userdata(t.clone())?
|
lua.create_any_userdata(t.clone())?
|
||||||
} else if let Some(t) = a.downcast_ref::<super::body::BodyYankIter>() {
|
} else if let Some(t) = a.downcast_ref::<super::body::BodyYankIter>() {
|
||||||
lua.create_userdata(t.clone())?
|
lua.create_userdata(t.clone())?
|
||||||
} else {
|
} else {
|
||||||
Err("unsupported userdata included".into_lua_err())?
|
Err("unsupported Data::Any included".into_lua_err())?
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -191,7 +195,17 @@ impl Sendable {
|
||||||
Value::Table(_) => Err("table is not supported".into_lua_err())?,
|
Value::Table(_) => Err("table is not supported".into_lua_err())?,
|
||||||
Value::Function(_) => Err("function is not supported".into_lua_err())?,
|
Value::Function(_) => Err("function is not supported".into_lua_err())?,
|
||||||
Value::Thread(_) => Err("thread is not supported".into_lua_err())?,
|
Value::Thread(_) => Err("thread is not supported".into_lua_err())?,
|
||||||
Value::UserData(_) => Err("userdata is not supported".into_lua_err())?,
|
Value::UserData(ud) => {
|
||||||
|
if let Ok(t) = ud.take::<yazi_binding::Url>() {
|
||||||
|
DataKey::Url(t.into())
|
||||||
|
} else if let Ok(t) = ud.take::<yazi_binding::Urn>() {
|
||||||
|
DataKey::Urn(t.into())
|
||||||
|
} else if let Ok(t) = ud.borrow::<yazi_binding::Id>() {
|
||||||
|
DataKey::Id(**t)
|
||||||
|
} else {
|
||||||
|
Err(format!("unsupported userdata included: {ud:?}").into_lua_err())?
|
||||||
|
}
|
||||||
|
}
|
||||||
Value::Error(_) => Err("error is not supported".into_lua_err())?,
|
Value::Error(_) => Err("error is not supported".into_lua_err())?,
|
||||||
Value::Other(..) => Err("unknown data is not supported".into_lua_err())?,
|
Value::Other(..) => Err("unknown data is not supported".into_lua_err())?,
|
||||||
})
|
})
|
||||||
|
|
@ -199,7 +213,11 @@ impl Sendable {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn key_to_value(lua: &Lua, key: DataKey) -> mlua::Result<Value> {
|
fn key_to_value(lua: &Lua, key: DataKey) -> mlua::Result<Value> {
|
||||||
Self::key_to_value_ref(lua, &key)
|
match key {
|
||||||
|
DataKey::Url(u) => yazi_binding::Url::new(u).into_lua(lua),
|
||||||
|
DataKey::Urn(u) => yazi_binding::Urn::new(u).into_lua(lua),
|
||||||
|
_ => Self::key_to_value_ref(lua, &key),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_to_value_ref(lua: &Lua, key: &DataKey) -> mlua::Result<Value> {
|
fn key_to_value_ref(lua: &Lua, key: &DataKey) -> mlua::Result<Value> {
|
||||||
|
|
@ -209,6 +227,9 @@ impl Sendable {
|
||||||
DataKey::Integer(i) => Value::Integer(*i),
|
DataKey::Integer(i) => Value::Integer(*i),
|
||||||
DataKey::Number(n) => Value::Number(n.get()),
|
DataKey::Number(n) => Value::Number(n.get()),
|
||||||
DataKey::String(s) => Value::String(lua.create_string(s.as_ref())?),
|
DataKey::String(s) => Value::String(lua.create_string(s.as_ref())?),
|
||||||
|
DataKey::Id(i) => yazi_binding::Id(*i).into_lua(lua)?,
|
||||||
|
DataKey::Url(u) => yazi_binding::Url::new(u.clone()).into_lua(lua)?,
|
||||||
|
DataKey::Urn(u) => yazi_binding::Urn::new(u.clone()).into_lua(lua)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,11 @@ impl Files {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_size(&mut self, sizes: HashMap<UrnBuf, u64>) {
|
pub fn update_size(&mut self, mut sizes: HashMap<UrnBuf, u64>) {
|
||||||
|
if sizes.len() <= 50 {
|
||||||
|
sizes.retain(|k, v| self.sizes.get(k) != Some(v));
|
||||||
|
}
|
||||||
|
|
||||||
if sizes.is_empty() {
|
if sizes.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,50 @@ function M:seek(job)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:spot(job) require("file"):spot(job) end
|
function M:spot(job)
|
||||||
|
self.size, self.last = 0, 0
|
||||||
|
|
||||||
|
local url = job.file.url
|
||||||
|
local it = fs.calc_size(url)
|
||||||
|
while true do
|
||||||
|
local next = it:recv()
|
||||||
|
if next then
|
||||||
|
self.size = self.size + next
|
||||||
|
self:spot_multi(job, false)
|
||||||
|
else
|
||||||
|
break
|
||||||
|
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
|
||||||
|
|
||||||
|
function M:spot_multi(job, force)
|
||||||
|
local now = ya.time()
|
||||||
|
if not force and now < self.last + 0.1 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local rows = {
|
||||||
|
ui.Row({ "Folder" }):style(ui.Style():fg("green")),
|
||||||
|
ui.Row { " Size:", ya.readable_size(self.size) .. (force and "" or " (?)") },
|
||||||
|
ui.Row {},
|
||||||
|
}
|
||||||
|
|
||||||
|
ya.spot_table(
|
||||||
|
job,
|
||||||
|
ui.Table(ya.list_merge(rows, require("file"):spot_base(job)))
|
||||||
|
: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.last = now
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ function ya.readable_size(size)
|
||||||
size = size / 1024
|
size = size / 1024
|
||||||
i = i + 1
|
i = i + 1
|
||||||
end
|
end
|
||||||
return string.format("%.1f%s", size, units[i]):gsub("[.,]0", "", 1)
|
local s = string.format("%.1f%s", size, units[i]):gsub("[.,]0", "", 1)
|
||||||
|
return s
|
||||||
end
|
end
|
||||||
|
|
||||||
function ya.readable_path(path)
|
function ya.readable_path(path)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ fn op(lua: &Lua) -> mlua::Result<Function> {
|
||||||
lua.create_function(|lua, (name, t): (mlua::String, Table)| match name.as_bytes().as_ref() {
|
lua.create_function(|lua, (name, t): (mlua::String, Table)| match name.as_bytes().as_ref() {
|
||||||
b"part" => super::FilesOp::part(lua, t),
|
b"part" => super::FilesOp::part(lua, t),
|
||||||
b"done" => super::FilesOp::done(lua, t),
|
b"done" => super::FilesOp::done(lua, t),
|
||||||
|
b"size" => super::FilesOp::size(lua, t),
|
||||||
_ => Err("Unknown operation".into_lua_err())?,
|
_ => Err("Unknown operation".into_lua_err())?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use mlua::{IntoLua, Lua, Table};
|
use mlua::{IntoLua, Lua, Table};
|
||||||
use yazi_binding::{Id, Url};
|
use yazi_binding::{Id, Url, Urn};
|
||||||
|
|
||||||
use crate::{bindings::Cha, file::File};
|
use crate::{bindings::Cha, file::File};
|
||||||
|
|
||||||
|
|
@ -28,6 +28,19 @@ impl FilesOp {
|
||||||
|
|
||||||
Ok(Self(yazi_fs::FilesOp::Done(url.into(), *cha, *id)))
|
Ok(Self(yazi_fs::FilesOp::Done(url.into(), *cha, *id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn size(_: &Lua, t: Table) -> mlua::Result<Self> {
|
||||||
|
let url: Url = t.raw_get("url")?;
|
||||||
|
let sizes: Table = t.raw_get("sizes")?;
|
||||||
|
|
||||||
|
Ok(Self(yazi_fs::FilesOp::Size(
|
||||||
|
url.into(),
|
||||||
|
sizes
|
||||||
|
.pairs::<Urn, u64>()
|
||||||
|
.map(|r| r.map(|(urn, size)| (urn.into(), size)))
|
||||||
|
.collect::<mlua::Result<_>>()?,
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoLua for FilesOp {
|
impl IntoLua for FilesOp {
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,9 @@ pub fn peek(
|
||||||
_ = ct_.cancelled() => {},
|
_ = ct_.cancelled() => {},
|
||||||
Ok(b) = LOADER.ensure(&cmd.name, |c| c.sync_peek) => {
|
Ok(b) = LOADER.ensure(&cmd.name, |c| c.sync_peek) => {
|
||||||
if b {
|
if b {
|
||||||
peek_sync(cmd, file, mime, skip);
|
peek_sync( cmd, file, mime, skip);
|
||||||
} else {
|
} else {
|
||||||
peek_async(cmd, file, mime, skip, ct_);
|
peek_async( cmd, file, mime, skip, ct_);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
else => {}
|
else => {}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,15 @@ use mlua::{ExternalError, ExternalResult, HookTriggers, IntoLua, ObjectLike, VmS
|
||||||
use tokio::{runtime::Handle, select};
|
use tokio::{runtime::Handle, select};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
use yazi_binding::Id;
|
||||||
use yazi_dds::Sendable;
|
use yazi_dds::Sendable;
|
||||||
use yazi_shared::event::Cmd;
|
use yazi_shared::{Ids, event::Cmd};
|
||||||
|
|
||||||
use super::slim_lua;
|
use super::slim_lua;
|
||||||
use crate::{file::File, loader::LOADER};
|
use crate::{file::File, loader::LOADER};
|
||||||
|
|
||||||
|
static IDS: Ids = Ids::new();
|
||||||
|
|
||||||
pub fn spot(
|
pub fn spot(
|
||||||
cmd: &'static Cmd,
|
cmd: &'static Cmd,
|
||||||
file: yazi_fs::File,
|
file: yazi_fs::File,
|
||||||
|
|
@ -37,6 +40,7 @@ pub fn spot(
|
||||||
|
|
||||||
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
||||||
let job = lua.create_table_from([
|
let job = lua.create_table_from([
|
||||||
|
("id", Id(IDS.next()).into_lua(&lua)?),
|
||||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||||
("file", File::new(file).into_lua(&lua)?),
|
("file", File::new(file).into_lua(&lua)?),
|
||||||
("mime", mime.into_lua(&lua)?),
|
("mime", mime.into_lua(&lua)?),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use mlua::{AnyUserData, Function, Lua, Table};
|
use mlua::{AnyUserData, Function, Lua, Table};
|
||||||
use yazi_config::THEME;
|
use yazi_config::THEME;
|
||||||
use yazi_macro::emit;
|
use yazi_macro::emit;
|
||||||
use yazi_shared::event::Cmd;
|
use yazi_shared::{Id, event::Cmd};
|
||||||
|
|
||||||
use super::Utils;
|
use super::Utils;
|
||||||
use crate::{elements::Renderable, file::FileRef};
|
use crate::{elements::Renderable, file::FileRef};
|
||||||
|
|
@ -11,6 +11,7 @@ pub struct SpotLock {
|
||||||
pub cha: yazi_fs::cha::Cha,
|
pub cha: yazi_fs::cha::Cha,
|
||||||
pub mime: String,
|
pub mime: String,
|
||||||
|
|
||||||
|
pub id: Id,
|
||||||
pub skip: usize,
|
pub skip: usize,
|
||||||
pub data: Vec<Renderable>,
|
pub data: Vec<Renderable>,
|
||||||
}
|
}
|
||||||
|
|
@ -25,6 +26,7 @@ impl TryFrom<Table> for SpotLock {
|
||||||
cha: file.cha,
|
cha: file.cha,
|
||||||
mime: t.raw_get("mime")?,
|
mime: t.raw_get("mime")?,
|
||||||
|
|
||||||
|
id: *t.raw_get::<yazi_binding::Id>("id")?,
|
||||||
skip: t.raw_get("skip")?,
|
skip: t.raw_get("skip")?,
|
||||||
data: Default::default(),
|
data: Default::default(),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::{any::Any, borrow::Cow, collections::HashMap};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize, de};
|
use serde::{Deserialize, Serialize, de};
|
||||||
|
|
||||||
use crate::{Id, OrderedFloat, url::Url};
|
use crate::{Id, OrderedFloat, url::{Url, UrnBuf}};
|
||||||
|
|
||||||
// --- Data
|
// --- Data
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
|
@ -18,6 +18,8 @@ pub enum Data {
|
||||||
Id(Id),
|
Id(Id),
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
Url(Url),
|
Url(Url),
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
Urn(UrnBuf),
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
Bytes(Vec<u8>),
|
Bytes(Vec<u8>),
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
|
|
@ -106,6 +108,11 @@ pub enum DataKey {
|
||||||
Integer(i64),
|
Integer(i64),
|
||||||
Number(OrderedFloat),
|
Number(OrderedFloat),
|
||||||
String(Cow<'static, str>),
|
String(Cow<'static, str>),
|
||||||
|
Id(Id),
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
Url(Url),
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
Urn(UrnBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataKey {
|
impl DataKey {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
use std::{borrow::{Borrow, Cow}, ffi::OsStr, ops::Deref, path::{Path, PathBuf}};
|
use std::{borrow::{Borrow, Cow}, ffi::OsStr, ops::Deref, path::{Path, PathBuf}};
|
||||||
|
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Urn(Path);
|
pub struct Urn(Path);
|
||||||
|
|
@ -48,7 +50,7 @@ impl PartialEq<Cow<'_, OsStr>> for &Urn {
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- UrnBuf
|
// --- UrnBuf
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||||
pub struct UrnBuf(PathBuf);
|
pub struct UrnBuf(PathBuf);
|
||||||
|
|
||||||
impl Borrow<Urn> for UrnBuf {
|
impl Borrow<Urn> for UrnBuf {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue