mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
perf!: cache UserData fields (#2572)
This commit is contained in:
parent
3c9f619b84
commit
9565c1b6fd
82 changed files with 810 additions and 562 deletions
54
Cargo.lock
generated
54
Cargo.lock
generated
|
|
@ -725,9 +725,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
|
|
@ -3140,7 +3140,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-adapter"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"ansi-to-tui",
|
||||
"anyhow",
|
||||
|
|
@ -3157,9 +3157,21 @@ dependencies = [
|
|||
"yazi-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yazi-binding"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"mlua",
|
||||
"paste",
|
||||
"serde_json",
|
||||
"yazi-fs",
|
||||
"yazi-macro",
|
||||
"yazi-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yazi-boot"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap_complete",
|
||||
|
|
@ -3177,7 +3189,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-cli"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
|
|
@ -3200,7 +3212,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-codegen"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
|
|
@ -3208,7 +3220,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-config"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.9.0",
|
||||
|
|
@ -3228,7 +3240,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-core"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.9.0",
|
||||
|
|
@ -3263,7 +3275,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-dds"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"mlua",
|
||||
|
|
@ -3276,6 +3288,7 @@ dependencies = [
|
|||
"tracing",
|
||||
"uzers",
|
||||
"vergen-gitcl",
|
||||
"yazi-binding",
|
||||
"yazi-boot",
|
||||
"yazi-fs",
|
||||
"yazi-macro",
|
||||
|
|
@ -3284,7 +3297,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-ffi"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"core-foundation-sys",
|
||||
|
|
@ -3295,16 +3308,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-fm"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"better-panic",
|
||||
"crossterm",
|
||||
"fdlimit",
|
||||
"foldhash",
|
||||
"futures",
|
||||
"indexmap",
|
||||
"libc",
|
||||
"mlua",
|
||||
"paste",
|
||||
"ratatui",
|
||||
"scopeguard",
|
||||
"signal-hook-tokio",
|
||||
|
|
@ -3316,6 +3331,7 @@ dependencies = [
|
|||
"tracing-appender",
|
||||
"tracing-subscriber",
|
||||
"yazi-adapter",
|
||||
"yazi-binding",
|
||||
"yazi-boot",
|
||||
"yazi-codegen",
|
||||
"yazi-config",
|
||||
|
|
@ -3331,7 +3347,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-fs"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
|
|
@ -3357,11 +3373,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-macro"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
|
||||
[[package]]
|
||||
name = "yazi-plugin"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"ansi-to-tui",
|
||||
"anyhow",
|
||||
|
|
@ -3373,6 +3389,7 @@ dependencies = [
|
|||
"md-5",
|
||||
"mlua",
|
||||
"parking_lot",
|
||||
"paste",
|
||||
"ratatui",
|
||||
"serde_json",
|
||||
"syntect",
|
||||
|
|
@ -3384,6 +3401,7 @@ dependencies = [
|
|||
"unicode-width 0.2.0",
|
||||
"uzers",
|
||||
"yazi-adapter",
|
||||
"yazi-binding",
|
||||
"yazi-boot",
|
||||
"yazi-config",
|
||||
"yazi-dds",
|
||||
|
|
@ -3402,7 +3420,7 @@ checksum = "33232d9116df6415ddfcdf72701b1b7439ce87f240a14723e8dd5d17e7ed5f98"
|
|||
|
||||
[[package]]
|
||||
name = "yazi-proxy"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"mlua",
|
||||
|
|
@ -3415,7 +3433,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-scheduler"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-priority-channel",
|
||||
|
|
@ -3438,7 +3456,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-shared"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"crossterm",
|
||||
|
|
@ -3458,7 +3476,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "yazi-widgets"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"ratatui",
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ md-5 = "0.10.6"
|
|||
mlua = { version = "0.10.3", features = [ "anyhow", "async", "error-send", "lua54", "macros", "serialize" ] }
|
||||
objc = "0.2.7"
|
||||
parking_lot = "0.12.3"
|
||||
paste = "1.0.15"
|
||||
ratatui = { version = "0.29.0", features = [ "unstable-rendered-line-info" ] }
|
||||
regex = "1.11.1"
|
||||
scopeguard = "1.2.0"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-adapter"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,9 +9,9 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-config = { path = "../yazi-config", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
ansi-to-tui = { workspace = true }
|
||||
|
|
|
|||
17
yazi-binding/Cargo.toml
Normal file
17
yazi-binding/Cargo.toml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "yazi-binding"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
description = "Yazi Lua bindings"
|
||||
homepage = "https://yazi-rs.github.io"
|
||||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
mlua = { workspace = true }
|
||||
paste = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
3
yazi-binding/src/lib.rs
Normal file
3
yazi-binding/src/lib.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
mod macros;
|
||||
|
||||
yazi_macro::mod_flat!(error stage url);
|
||||
19
yazi-binding/src/macros.rs
Normal file
19
yazi-binding/src/macros.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#[macro_export]
|
||||
macro_rules! cached_field {
|
||||
($fields:ident, $key:ident, $value:expr) => {
|
||||
$fields.add_field_function_get(stringify!($key), |lua, ud| {
|
||||
use mlua::IntoLua;
|
||||
ud.borrow_mut_scoped::<Self, mlua::Result<mlua::Value>>(|me| {
|
||||
match paste::paste! { &me.[<v_ $key>] } {
|
||||
Some(v) => Ok(v.clone()),
|
||||
None => {
|
||||
let v: mlua::Result<_> = $value(lua, me);
|
||||
let v = v?.into_lua(lua)?;
|
||||
paste::paste! { me.[<v_ $key>] = Some(v.clone()) };
|
||||
Ok(v)
|
||||
}
|
||||
}
|
||||
})?
|
||||
});
|
||||
};
|
||||
}
|
||||
21
yazi-binding/src/stage.rs
Normal file
21
yazi-binding/src/stage.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
use mlua::{IntoLuaMulti, MetaMethod, UserData, UserDataMethods};
|
||||
|
||||
pub struct FolderStage(yazi_fs::FolderStage);
|
||||
|
||||
impl FolderStage {
|
||||
pub fn new(inner: yazi_fs::FolderStage) -> Self { Self(inner) }
|
||||
}
|
||||
|
||||
impl UserData for FolderStage {
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::Call, |lua, me, ()| {
|
||||
use yazi_fs::FolderStage::*;
|
||||
|
||||
match me.0 {
|
||||
Loading => false.into_lua_multi(lua),
|
||||
Loaded => true.into_lua_multi(lua),
|
||||
Failed(kind) => (true, crate::Error::IoKind(kind)).into_lua_multi(lua),
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
141
yazi-binding/src/url.rs
Normal file
141
yazi-binding/src/url.rs
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
use std::{ops::Deref, path::Path};
|
||||
|
||||
use mlua::{AnyUserData, ExternalError, FromLua, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRef, Value};
|
||||
|
||||
use crate::cached_field;
|
||||
|
||||
pub type UrlRef = UserDataRef<Url>;
|
||||
|
||||
pub struct Url {
|
||||
inner: yazi_shared::url::Url,
|
||||
|
||||
v_name: Option<Value>,
|
||||
v_stem: Option<Value>,
|
||||
v_ext: Option<Value>,
|
||||
v_base: Option<Value>,
|
||||
v_parent: Option<Value>,
|
||||
v_frag: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for Url {
|
||||
type Target = yazi_shared::url::Url;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl AsRef<Path> for Url {
|
||||
fn as_ref(&self) -> &Path { self.inner.as_path() }
|
||||
}
|
||||
|
||||
impl From<Url> for yazi_shared::url::Url {
|
||||
fn from(value: Url) -> Self { value.inner }
|
||||
}
|
||||
|
||||
impl Url {
|
||||
pub fn new(url: impl Into<yazi_shared::url::Url>) -> Self {
|
||||
Self {
|
||||
inner: url.into(),
|
||||
|
||||
v_name: None,
|
||||
v_stem: None,
|
||||
v_ext: None,
|
||||
v_base: None,
|
||||
v_parent: None,
|
||||
v_frag: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.globals().raw_set(
|
||||
"Url",
|
||||
lua.create_function(|_, value: Value| {
|
||||
Ok(match value {
|
||||
Value::String(s) => Self::new(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => Self::new(ud.borrow::<Self>()?.inner.clone()),
|
||||
_ => Err("Expected a string or a Url".into_lua_err())?,
|
||||
})
|
||||
})?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromLua for Url {
|
||||
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
|
||||
Ok(match value {
|
||||
Value::UserData(ud) => Self::new(ud.take::<Self>()?.inner),
|
||||
_ => Err("Expected a Url".into_lua_err())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for Url {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
cached_field!(fields, name, |lua: &Lua, me: &Self| {
|
||||
Some(me.name())
|
||||
.filter(|&s| !s.is_empty())
|
||||
.map(|s| lua.create_string(s.as_encoded_bytes()))
|
||||
.transpose()
|
||||
});
|
||||
cached_field!(fields, stem, |lua: &Lua, me: &Self| {
|
||||
me.file_stem().map(|s| lua.create_string(s.as_encoded_bytes())).transpose()
|
||||
});
|
||||
cached_field!(fields, ext, |lua: &Lua, me: &Self| {
|
||||
me.extension().map(|s| lua.create_string(s.as_encoded_bytes())).transpose()
|
||||
});
|
||||
cached_field!(fields, parent, |_, me: &Self| Ok(me.parent_url().map(Self::new)));
|
||||
cached_field!(fields, base, |_, me: &Self| {
|
||||
Ok(if me.base().as_os_str().is_empty() { None } else { Some(Self::new(me.base())) })
|
||||
});
|
||||
cached_field!(fields, frag, |lua: &Lua, me: &Self| lua.create_string(me.frag()));
|
||||
|
||||
fields.add_field_method_get("is_regular", |_, me| Ok(me.is_regular()));
|
||||
fields.add_field_method_get("is_search", |_, me| Ok(me.is_search()));
|
||||
fields.add_field_method_get("is_archive", |_, me| Ok(me.is_archive()));
|
||||
fields.add_field_method_get("is_absolute", |_, me| Ok(me.is_absolute()));
|
||||
fields.add_field_method_get("has_root", |_, me| Ok(me.has_root()));
|
||||
}
|
||||
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_method("join", |_, me, other: Value| {
|
||||
Ok(Self::new(match other {
|
||||
Value::String(s) => me.join(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => me.join(&ud.borrow::<Self>()?.inner),
|
||||
_ => Err("must be a string or a Url".into_lua_err())?,
|
||||
}))
|
||||
});
|
||||
methods.add_method("starts_with", |_, me, base: Value| {
|
||||
Ok(match base {
|
||||
Value::String(s) => me.starts_with(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => me.starts_with(&ud.borrow::<Self>()?.inner),
|
||||
_ => Err("must be a string or a Url".into_lua_err())?,
|
||||
})
|
||||
});
|
||||
methods.add_method("ends_with", |_, me, child: Value| {
|
||||
Ok(match child {
|
||||
Value::String(s) => me.ends_with(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => me.ends_with(&ud.borrow::<Self>()?.inner),
|
||||
_ => Err("must be a string or a Url".into_lua_err())?,
|
||||
})
|
||||
});
|
||||
methods.add_method("strip_prefix", |_, me, base: Value| {
|
||||
let path = match base {
|
||||
Value::String(s) => me.strip_prefix(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => me.strip_prefix(&ud.borrow::<Self>()?.inner),
|
||||
_ => Err("must be a string or a Url".into_lua_err())?,
|
||||
};
|
||||
Ok(path.ok().map(Self::new))
|
||||
});
|
||||
|
||||
methods.add_function_mut("into_search", |_, (ud, frag): (AnyUserData, mlua::String)| {
|
||||
Ok(Self::new(ud.take::<Self>()?.inner.into_search(&frag.to_str()?)))
|
||||
});
|
||||
|
||||
methods.add_meta_method(MetaMethod::Eq, |_, me, other: UrlRef| Ok(me.inner == other.inner));
|
||||
methods.add_meta_method(MetaMethod::ToString, |lua, me, ()| {
|
||||
lua.create_string(me.as_os_str().as_encoded_bytes())
|
||||
});
|
||||
methods.add_meta_method(MetaMethod::Concat, |lua, lhs, rhs: mlua::String| {
|
||||
lua.create_string([lhs.as_os_str().as_encoded_bytes(), rhs.as_bytes().as_ref()].concat())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-boot"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,11 +9,11 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.3.7" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.3.7" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.4.4" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.4.4" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
clap = { workspace = true }
|
||||
|
|
@ -21,7 +21,7 @@ regex = { workspace = true }
|
|||
serde = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
clap = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-cli"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,11 +9,11 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.3.7" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.3.7" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.4.4" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.4.4" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
@ -26,7 +26,7 @@ toml = { workspace = true }
|
|||
twox-hash = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External build dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-codegen"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-config"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,10 +9,10 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-codegen = { path = "../yazi-codegen", version = "25.3.7" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-codegen = { path = "../yazi-codegen", version = "25.4.4" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-core"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,18 +9,18 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.3.7" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.3.7" }
|
||||
yazi-codegen = { path = "../yazi-codegen", version = "25.3.7" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.3.7" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.3.7" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.3.7" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.3.7" }
|
||||
yazi-scheduler = { path = "../yazi-scheduler", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.3.7" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.4.4" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.4.4" }
|
||||
yazi-codegen = { path = "../yazi-codegen", version = "25.4.4" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.4.4" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.4.4" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.4.4" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.4.4" }
|
||||
yazi-scheduler = { path = "../yazi-scheduler", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-dds"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -13,10 +13,11 @@ default = [ "vendored-lua" ]
|
|||
vendored-lua = [ "mlua/vendored" ]
|
||||
|
||||
[dependencies]
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.3.7" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.4.4" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.4.4" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ impl UserData for BodyBulkIter {
|
|||
methods.add_meta_function(MetaMethod::Pairs, |lua, me: AnyUserData| {
|
||||
let iter = lua.create_function(|lua, mut me: UserDataRefMut<Self>| {
|
||||
if let Some((Cow::Owned(from), Cow::Owned(to))) = me.inner.next() {
|
||||
(lua.create_any_userdata(from)?, lua.create_any_userdata(to)?).into_lua_multi(lua)
|
||||
(yazi_binding::Url::new(from), yazi_binding::Url::new(to)).into_lua_multi(lua)
|
||||
} else {
|
||||
().into_lua_multi(lua)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ impl IntoLua for BodyCd<'static> {
|
|||
if let Some(Cow::Owned(url)) = Some(self.url).filter(|_| !self.dummy) {
|
||||
lua.create_table_from([
|
||||
("tab", self.tab.get().into_lua(lua)?),
|
||||
("url", lua.create_any_userdata(url)?.into_lua(lua)?),
|
||||
("url", yazi_binding::Url::new(url).into_lua(lua)?),
|
||||
])?
|
||||
} else {
|
||||
lua.create_table_from([("tab", self.tab.get())])?
|
||||
|
|
|
|||
|
|
@ -27,10 +27,8 @@ impl<'a> From<BodyDelete<'a>> for Body<'a> {
|
|||
|
||||
impl IntoLua for BodyDelete<'static> {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
let urls = lua.create_table_with_capacity(self.urls.len(), 0)?;
|
||||
for (i, url) in self.urls.into_owned().into_iter().enumerate() {
|
||||
urls.raw_set(i + 1, lua.create_any_userdata(url)?)?;
|
||||
}
|
||||
let urls =
|
||||
lua.create_sequence_from(self.urls.into_owned().into_iter().map(yazi_binding::Url::new))?;
|
||||
|
||||
lua.create_table_from([("urls", urls)])?.into_lua(lua)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ impl IntoLua for BodyHover<'static> {
|
|||
if let Some(Cow::Owned(url)) = self.url {
|
||||
lua.create_table_from([
|
||||
("tab", self.tab.get().into_lua(lua)?),
|
||||
("url", lua.create_any_userdata(url)?.into_lua(lua)?),
|
||||
("url", yazi_binding::Url::new(url).into_lua(lua)?),
|
||||
])?
|
||||
} else {
|
||||
lua.create_table_from([("tab", self.tab.get())])?
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ impl IntoLua for BodyLoad<'static> {
|
|||
lua
|
||||
.create_table_from([
|
||||
("tab", self.tab.get().into_lua(lua)?),
|
||||
("url", lua.create_any_userdata(self.url.into_owned())?.into_lua(lua)?),
|
||||
("stage", lua.create_any_userdata(self.stage)?.into_lua(lua)?),
|
||||
("url", yazi_binding::Url::new(self.url.into_owned()).into_lua(lua)?),
|
||||
("stage", yazi_binding::FolderStage::new(self.stage).into_lua(lua)?),
|
||||
])?
|
||||
.into_lua(lua)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ impl IntoLua for BodyMoveItem {
|
|||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
lua
|
||||
.create_table_from([
|
||||
("from", lua.create_any_userdata(self.from)?),
|
||||
("to", lua.create_any_userdata(self.to)?),
|
||||
("from", yazi_binding::Url::new(self.from)),
|
||||
("to", yazi_binding::Url::new(self.to)),
|
||||
])?
|
||||
.into_lua(lua)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ impl IntoLua for BodyRename<'static> {
|
|||
lua
|
||||
.create_table_from([
|
||||
("tab", self.tab.get().into_lua(lua)?),
|
||||
("from", lua.create_any_userdata(self.from.into_owned())?.into_lua(lua)?),
|
||||
("to", lua.create_any_userdata(self.to.into_owned())?.into_lua(lua)?),
|
||||
("from", yazi_binding::Url::new(self.from.into_owned()).into_lua(lua)?),
|
||||
("to", yazi_binding::Url::new(self.to.into_owned()).into_lua(lua)?),
|
||||
])?
|
||||
.into_lua(lua)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,10 +27,8 @@ impl<'a> From<BodyTrash<'a>> for Body<'a> {
|
|||
|
||||
impl IntoLua for BodyTrash<'static> {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
let urls = lua.create_table_with_capacity(self.urls.len(), 0)?;
|
||||
for (i, url) in self.urls.into_owned().into_iter().enumerate() {
|
||||
urls.raw_set(i + 1, lua.create_any_userdata(url)?)?;
|
||||
}
|
||||
let urls =
|
||||
lua.create_sequence_from(self.urls.into_owned().into_iter().map(yazi_binding::Url::new))?;
|
||||
|
||||
lua.create_table_from([("urls", urls)])?.into_lua(lua)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,12 +57,12 @@ impl UserData for BodyYankIter {
|
|||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.urls.len()));
|
||||
|
||||
methods.add_meta_method(MetaMethod::Index, |lua, me, idx: usize| {
|
||||
if idx > me.urls.len() || idx == 0 {
|
||||
Ok(None)
|
||||
methods.add_meta_method(MetaMethod::Index, |_, me, idx: usize| {
|
||||
Ok(if idx > me.urls.len() || idx == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(lua.create_any_userdata(me.urls[idx - 1].clone())).transpose()
|
||||
}
|
||||
Some(yazi_binding::Url::new(me.urls[idx - 1].clone()))
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::{borrow::Cow, collections::HashMap};
|
||||
|
||||
use mlua::{ExternalError, Lua, MultiValue, Table, Value};
|
||||
use mlua::{ExternalError, IntoLua, Lua, MultiValue, Table, Value};
|
||||
use yazi_shared::{OrderedFloat, event::{Data, DataKey}, replace_cow};
|
||||
|
||||
pub struct Sendable;
|
||||
|
|
@ -41,8 +41,8 @@ impl Sendable {
|
|||
Value::Function(_) => Err("function is not supported".into_lua_err())?,
|
||||
Value::Thread(_) => Err("thread is not supported".into_lua_err())?,
|
||||
Value::UserData(ud) => {
|
||||
if let Ok(t) = ud.take::<yazi_shared::url::Url>() {
|
||||
Data::Url(t)
|
||||
if let Ok(t) = ud.take::<yazi_binding::Url>() {
|
||||
Data::Url(t.into())
|
||||
} else if let Ok(t) = ud.take::<yazi_fs::FilesOp>() {
|
||||
Data::Any(Box::new(t))
|
||||
} else if let Ok(t) = ud.take::<super::body::BodyYankIter>() {
|
||||
|
|
@ -73,7 +73,7 @@ impl Sendable {
|
|||
}
|
||||
Value::Table(tbl)
|
||||
}
|
||||
Data::Url(u) => Value::UserData(lua.create_any_userdata(u)?),
|
||||
Data::Url(u) => yazi_binding::Url::new(u).into_lua(lua)?,
|
||||
Data::Any(a) => Value::UserData(if a.is::<yazi_fs::FilesOp>() {
|
||||
lua.create_any_userdata(*a.downcast::<yazi_fs::FilesOp>().unwrap())?
|
||||
} else if a.is::<super::body::BodyYankIter>() {
|
||||
|
|
@ -107,7 +107,7 @@ impl Sendable {
|
|||
}
|
||||
Value::Table(tbl)
|
||||
}
|
||||
Data::Url(u) => Value::UserData(lua.create_any_userdata(u.clone())?),
|
||||
Data::Url(u) => yazi_binding::Url::new(u.clone()).into_lua(lua)?,
|
||||
Data::Bytes(b) => Value::String(lua.create_string(b)?),
|
||||
Data::Any(a) => Value::UserData(if let Some(t) = a.downcast_ref::<yazi_fs::FilesOp>() {
|
||||
lua.create_any_userdata(t.clone())?
|
||||
|
|
@ -189,8 +189,8 @@ impl Sendable {
|
|||
Value::Function(_) => Err("function is not supported".into_lua_err())?,
|
||||
Value::Thread(_) => Err("thread is not supported".into_lua_err())?,
|
||||
Value::UserData(ud) => {
|
||||
if let Ok(t) = ud.take::<yazi_shared::url::Url>() {
|
||||
DataKey::Url(t)
|
||||
if let Ok(t) = ud.take::<yazi_binding::Url>() {
|
||||
DataKey::Url(t.into())
|
||||
} else {
|
||||
Err("unsupported userdata included".into_lua_err())?
|
||||
}
|
||||
|
|
@ -202,7 +202,7 @@ impl Sendable {
|
|||
|
||||
fn key_to_value(lua: &Lua, key: DataKey) -> mlua::Result<Value> {
|
||||
Ok(match key {
|
||||
DataKey::Url(u) => Value::UserData(lua.create_any_userdata(u)?),
|
||||
DataKey::Url(u) => yazi_binding::Url::new(u).into_lua(lua)?,
|
||||
key => Self::key_to_value_ref(lua, &key)?,
|
||||
})
|
||||
}
|
||||
|
|
@ -214,7 +214,7 @@ impl Sendable {
|
|||
DataKey::Integer(i) => Value::Integer(*i),
|
||||
DataKey::Number(n) => Value::Number(n.get()),
|
||||
DataKey::String(s) => Value::String(lua.create_string(s.as_ref())?),
|
||||
DataKey::Url(u) => Value::UserData(lua.create_any_userdata(u.clone())?),
|
||||
DataKey::Url(u) => yazi_binding::Url::new(u.clone()).into_lua(lua)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-ffi"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,7 +9,7 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-fm"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -13,27 +13,30 @@ default = [ "vendored-lua" ]
|
|||
vendored-lua = [ "mlua/vendored" ]
|
||||
|
||||
[dependencies]
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.3.7" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.3.7" }
|
||||
yazi-codegen = { path = "../yazi-codegen", version = "25.3.7" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.3.7" }
|
||||
yazi-core = { path = "../yazi-core", version = "25.3.7" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.3.7" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.3.7" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.3.7" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.4.4" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.4.4" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.4.4" }
|
||||
yazi-codegen = { path = "../yazi-codegen", version = "25.4.4" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.4.4" }
|
||||
yazi-core = { path = "../yazi-core", version = "25.4.4" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.4.4" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.4.4" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
yazi-widgets = { path = "../yazi-widgets", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
better-panic = "0.3.0"
|
||||
crossterm = { workspace = true }
|
||||
fdlimit = "0.3.0"
|
||||
foldhash = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
indexmap = { workspace = true }
|
||||
mlua = { workspace = true }
|
||||
paste = { workspace = true }
|
||||
ratatui = { workspace = true }
|
||||
scopeguard = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use yazi_macro::emit;
|
|||
use yazi_shared::event::{CmdCow, Event, NEED_RENDER};
|
||||
use yazi_widgets::input::InputMode;
|
||||
|
||||
use crate::{Ctx, Executor, Router, Signals, Term, lives::Lives};
|
||||
use crate::{Ctx, Executor, Router, Signals, Term};
|
||||
|
||||
pub(crate) struct App {
|
||||
pub(crate) cx: Ctx,
|
||||
|
|
@ -20,7 +20,6 @@ impl App {
|
|||
let term = Term::start()?;
|
||||
let (mut rx, signals) = (Event::take(), Signals::start()?);
|
||||
|
||||
Lives::register()?;
|
||||
let mut app = Self { cx: Ctx::make(), term: Some(term), signals };
|
||||
app.render();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,38 +1,66 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, IntoLua, MetaMethod, UserData, Value};
|
||||
use paste::paste;
|
||||
|
||||
use super::Lives;
|
||||
use super::{Lives, PtrCell};
|
||||
|
||||
pub(super) struct Ctx {
|
||||
inner: *const crate::Ctx,
|
||||
inner: PtrCell<crate::Ctx>,
|
||||
|
||||
c_active: Option<Value>,
|
||||
c_tabs: Option<Value>,
|
||||
c_tasks: Option<Value>,
|
||||
c_yanked: Option<Value>,
|
||||
c_layer: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for Ctx {
|
||||
type Target = crate::Ctx;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Ctx {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &crate::Ctx) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self {
|
||||
inner: inner.into(),
|
||||
|
||||
c_active: None,
|
||||
c_tabs: None,
|
||||
c_tasks: None,
|
||||
c_yanked: None,
|
||||
c_layer: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for Ctx {
|
||||
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::Index, |lua, me, key: mlua::String| {
|
||||
match key.as_bytes().as_ref() {
|
||||
b"active" => super::Tab::make(me.active())?,
|
||||
b"tabs" => super::Tabs::make(&me.mgr.tabs)?,
|
||||
b"tasks" => super::Tasks::make(&me.tasks)?,
|
||||
b"yanked" => super::Yanked::make(&me.mgr.yanked)?,
|
||||
b"layer" => return yazi_plugin::bindings::Layer::from(me.layer()).into_lua(lua),
|
||||
_ => return Ok(Value::Nil),
|
||||
methods.add_meta_method_mut(MetaMethod::Index, |lua, me, key: mlua::String| {
|
||||
macro_rules! reuse {
|
||||
($key:ident, $value:expr) => {
|
||||
match paste! { &me.[<c_ $key>] } {
|
||||
Some(v) => v.clone(),
|
||||
None => {
|
||||
let v = $value?.into_lua(lua)?;
|
||||
paste! { me.[<c_ $key>] = Some(v.clone()); };
|
||||
v
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
.into_lua(lua)
|
||||
Ok(match key.as_bytes().as_ref() {
|
||||
b"active" => reuse!(active, super::Tab::make(me.active())),
|
||||
b"tabs" => reuse!(tabs, super::Tabs::make(&me.mgr.tabs)),
|
||||
b"tasks" => reuse!(tasks, super::Tasks::make(&me.tasks)),
|
||||
b"yanked" => reuse!(yanked, super::Yanked::make(&me.mgr.yanked)),
|
||||
b"layer" => {
|
||||
reuse!(layer, Ok::<_, mlua::Error>(yazi_plugin::bindings::Layer::from(me.layer())))
|
||||
}
|
||||
_ => Value::Nil,
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,27 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, IntoLua, UserData, UserDataFields, UserDataMethods};
|
||||
use mlua::{AnyUserData, IntoLua, UserData, UserDataFields, UserDataMethods, Value};
|
||||
use yazi_config::THEME;
|
||||
use yazi_plugin::{bindings::Range, elements::Style};
|
||||
|
||||
use super::Lives;
|
||||
use crate::Ctx;
|
||||
use crate::{Ctx, lives::PtrCell};
|
||||
|
||||
pub(super) struct File {
|
||||
idx: usize,
|
||||
folder: *const yazi_core::tab::Folder,
|
||||
tab: *const yazi_core::tab::Tab,
|
||||
folder: PtrCell<yazi_core::tab::Folder>,
|
||||
tab: PtrCell<yazi_core::tab::Tab>,
|
||||
|
||||
v_cha: Option<Value>,
|
||||
v_url: Option<Value>,
|
||||
v_link_to: Option<Value>,
|
||||
v_name: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for File {
|
||||
type Target = yazi_fs::File;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.folder().files[self.idx] }
|
||||
fn deref(&self) -> &Self::Target { &self.folder.files[self.idx] }
|
||||
}
|
||||
|
||||
impl AsRef<yazi_fs::File> for File {
|
||||
|
|
@ -30,14 +35,26 @@ impl File {
|
|||
folder: &yazi_core::tab::Folder,
|
||||
tab: &yazi_core::tab::Tab,
|
||||
) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { idx, folder, tab })
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
Ok(match super::FILE_CACHE.borrow_mut().entry(PtrCell(&folder.files[idx])) {
|
||||
Entry::Occupied(oe) => oe.into_mut().clone(),
|
||||
Entry::Vacant(ve) => {
|
||||
let ud = Lives::scoped_userdata(Self {
|
||||
idx,
|
||||
folder: folder.into(),
|
||||
tab: tab.into(),
|
||||
|
||||
v_cha: None,
|
||||
v_url: None,
|
||||
v_link_to: None,
|
||||
v_name: None,
|
||||
})?;
|
||||
ve.insert(ud.clone());
|
||||
ud
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn folder(&self) -> &yazi_core::tab::Folder { unsafe { &*self.folder } }
|
||||
|
||||
#[inline]
|
||||
fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } }
|
||||
}
|
||||
|
||||
impl UserData for File {
|
||||
|
|
@ -45,13 +62,17 @@ impl UserData for File {
|
|||
yazi_plugin::impl_file_fields!(fields);
|
||||
|
||||
fields.add_field_method_get("idx", |_, me| Ok(me.idx + 1));
|
||||
fields.add_field_method_get("is_hovered", |_, me| Ok(me.idx == me.folder.cursor));
|
||||
fields.add_field_method_get("in_preview", |_, me| {
|
||||
Ok(me.tab.hovered().is_some_and(|f| f.url == me.folder.url))
|
||||
});
|
||||
}
|
||||
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
yazi_plugin::impl_file_methods!(methods);
|
||||
|
||||
methods.add_method("size", |_, me, ()| {
|
||||
Ok(if me.is_dir() { me.folder().files.sizes.get(me.urn()).copied() } else { Some(me.len) })
|
||||
Ok(if me.is_dir() { me.folder.files.sizes.get(me.urn()).copied() } else { Some(me.len) })
|
||||
});
|
||||
methods.add_method("mime", |lua, me, ()| {
|
||||
lua.named_registry_value::<AnyUserData>("cx")?.borrow_scoped(|cx: &Ctx| {
|
||||
|
|
@ -59,11 +80,11 @@ impl UserData for File {
|
|||
})?
|
||||
});
|
||||
methods.add_method("prefix", |lua, me, ()| {
|
||||
if !me.folder().url.is_search() {
|
||||
if !me.folder.url.is_search() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let mut p = me.url.strip_prefix(&me.folder().url).unwrap_or(&me.url).components();
|
||||
let mut p = me.url.strip_prefix(&me.folder.url).unwrap_or(&me.url).components();
|
||||
p.next_back();
|
||||
Some(lua.create_string(p.as_path().as_os_str().as_encoded_bytes())).transpose()
|
||||
});
|
||||
|
|
@ -73,7 +94,6 @@ impl UserData for File {
|
|||
THEME.filetype.iter().find(|&x| x.matches(me, mime)).map(|x| Style::from(x.style))
|
||||
})
|
||||
});
|
||||
methods.add_method("is_hovered", |_, me, ()| Ok(me.idx == me.folder().cursor));
|
||||
methods.add_method("is_yanked", |lua, me, ()| {
|
||||
lua.named_registry_value::<AnyUserData>("cx")?.borrow_scoped(|cx: &Ctx| {
|
||||
if !cx.mgr.yanked.contains(&me.url) {
|
||||
|
|
@ -87,24 +107,17 @@ impl UserData for File {
|
|||
});
|
||||
methods.add_method("is_marked", |_, me, ()| {
|
||||
use yazi_core::tab::Mode::*;
|
||||
if !me.tab().mode.is_visual() || me.folder().url != me.tab().current.url {
|
||||
if !me.tab.mode.is_visual() || me.folder.url != me.tab.current.url {
|
||||
return Ok(0u8);
|
||||
}
|
||||
|
||||
Ok(match &me.tab().mode {
|
||||
Ok(match &me.tab.mode {
|
||||
Select(_, indices) if indices.contains(&me.idx) => 1u8,
|
||||
Unset(_, indices) if indices.contains(&me.idx) => 2u8,
|
||||
_ => 0u8,
|
||||
})
|
||||
});
|
||||
methods.add_method("is_selected", |_, me, ()| Ok(me.tab().selected.contains_key(&me.url)));
|
||||
methods.add_method("in_parent", |_, me, ()| {
|
||||
Ok(me.tab().parent.as_ref().is_some_and(|f| me.folder().url == f.url))
|
||||
});
|
||||
methods.add_method("in_current", |_, me, ()| Ok(me.folder().url == me.tab().current.url));
|
||||
methods.add_method("in_preview", |_, me, ()| {
|
||||
Ok(me.tab().hovered().is_some_and(|f| f.url == me.folder().url))
|
||||
});
|
||||
methods.add_method("is_selected", |_, me, ()| Ok(me.tab.selected.contains_key(&me.url)));
|
||||
methods.add_method("found", |lua, me, ()| {
|
||||
lua.named_registry_value::<AnyUserData>("cx")?.borrow_scoped(|cx: &Ctx| {
|
||||
let Some(finder) = &cx.active().finder else {
|
||||
|
|
@ -124,7 +137,7 @@ impl UserData for File {
|
|||
let Some(finder) = &cx.active().finder else {
|
||||
return None;
|
||||
};
|
||||
if me.folder().url != me.tab().current.url {
|
||||
if me.folder.url != me.tab.current.url {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
use std::ops::{Deref, Range};
|
||||
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods};
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods, Value};
|
||||
use yazi_binding::cached_field;
|
||||
|
||||
use super::{File, Filter, Lives};
|
||||
use super::{File, Filter, Lives, PtrCell};
|
||||
|
||||
pub(super) struct Files {
|
||||
window: Range<usize>,
|
||||
folder: *const yazi_core::tab::Folder,
|
||||
tab: *const yazi_core::tab::Tab,
|
||||
folder: PtrCell<yazi_core::tab::Folder>,
|
||||
tab: PtrCell<yazi_core::tab::Tab>,
|
||||
|
||||
v_filter: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for Files {
|
||||
type Target = yazi_fs::Files;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.folder().files }
|
||||
fn deref(&self) -> &Self::Target { &self.folder.files }
|
||||
}
|
||||
|
||||
impl Files {
|
||||
|
|
@ -23,19 +26,13 @@ impl Files {
|
|||
folder: &yazi_core::tab::Folder,
|
||||
tab: &yazi_core::tab::Tab,
|
||||
) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { window, folder, tab })
|
||||
Lives::scoped_userdata(Self { window, folder: folder.into(), tab: tab.into(), v_filter: None })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn folder(&self) -> &yazi_core::tab::Folder { unsafe { &*self.folder } }
|
||||
|
||||
#[inline]
|
||||
fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } }
|
||||
}
|
||||
|
||||
impl UserData for Files {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("filter", |_, me| me.filter().map(Filter::make).transpose());
|
||||
cached_field!(fields, filter, |_, me: &Self| me.filter().map(Filter::make).transpose());
|
||||
}
|
||||
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
|
|
@ -46,7 +43,7 @@ impl UserData for Files {
|
|||
if idx > me.window.end || idx == 0 {
|
||||
Ok(None)
|
||||
} else {
|
||||
Some(File::make(idx - 1, me.folder(), me.tab())).transpose()
|
||||
Some(File::make(idx - 1, &me.folder, &me.tab)).transpose()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,22 +2,22 @@ use std::ops::Deref;
|
|||
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataMethods};
|
||||
|
||||
use super::Lives;
|
||||
use super::{Lives, PtrCell};
|
||||
|
||||
pub(super) struct Filter {
|
||||
inner: *const yazi_fs::Filter,
|
||||
inner: PtrCell<yazi_fs::Filter>,
|
||||
}
|
||||
|
||||
impl Deref for Filter {
|
||||
type Target = yazi_fs::Filter;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Filter {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_fs::Filter) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner: inner.into() })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,22 +2,22 @@ use std::ops::Deref;
|
|||
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataMethods};
|
||||
|
||||
use super::Lives;
|
||||
use super::{Lives, PtrCell};
|
||||
|
||||
pub(super) struct Finder {
|
||||
inner: *const yazi_core::tab::Finder,
|
||||
inner: PtrCell<yazi_core::tab::Finder>,
|
||||
}
|
||||
|
||||
impl Deref for Finder {
|
||||
type Target = yazi_core::tab::Finder;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Finder {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Finder) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner: inner.into() })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
use std::ops::{Deref, Range};
|
||||
|
||||
use mlua::{AnyUserData, IntoLuaMulti, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods};
|
||||
use mlua::{AnyUserData, Lua, UserData, UserDataFields, Value};
|
||||
use yazi_binding::{FolderStage, Url, cached_field};
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_plugin::url::Url;
|
||||
|
||||
use super::{File, Files, Lives};
|
||||
use super::{File, Files, Lives, PtrCell};
|
||||
|
||||
pub(super) struct Folder {
|
||||
window: Range<usize>,
|
||||
inner: *const yazi_core::tab::Folder,
|
||||
tab: *const yazi_core::tab::Tab,
|
||||
inner: PtrCell<yazi_core::tab::Folder>,
|
||||
tab: PtrCell<yazi_core::tab::Tab>,
|
||||
|
||||
v_cwd: Option<Value>,
|
||||
v_files: Option<Value>,
|
||||
v_stage: Option<Value>,
|
||||
v_window: Option<Value>,
|
||||
v_hovered: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for Folder {
|
||||
type Target = yazi_core::tab::Folder;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Folder {
|
||||
|
|
@ -33,38 +39,31 @@ impl Folder {
|
|||
}
|
||||
};
|
||||
|
||||
Lives::scoped_userdata(Self { window, inner, tab })
|
||||
Lives::scoped_userdata(Self {
|
||||
window,
|
||||
inner: inner.into(),
|
||||
tab: tab.into(),
|
||||
|
||||
v_cwd: None,
|
||||
v_files: None,
|
||||
v_stage: None,
|
||||
v_window: None,
|
||||
v_hovered: None,
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<yazi_fs::FolderStage>(|reg| {
|
||||
use yazi_fs::FolderStage;
|
||||
|
||||
reg.add_meta_method(MetaMethod::Call, |lua, me, ()| match me {
|
||||
FolderStage::Loading => false.into_lua_multi(lua),
|
||||
FolderStage::Loaded => true.into_lua_multi(lua),
|
||||
FolderStage::Failed(kind) => (true, yazi_plugin::Error::IoKind(*kind)).into_lua_multi(lua),
|
||||
});
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } }
|
||||
}
|
||||
|
||||
impl UserData for Folder {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("cwd", |_, me| Ok(Url(me.url.to_owned())));
|
||||
fields.add_field_method_get("files", |_, me| Files::make(0..me.files.len(), me, me.tab()));
|
||||
fields.add_field_method_get("stage", |lua, me| lua.create_any_userdata(me.stage));
|
||||
fields.add_field_method_get("window", |_, me| Files::make(me.window.clone(), me, me.tab()));
|
||||
cached_field!(fields, cwd, |_, me: &Self| Ok(Url::new(me.url.to_owned())));
|
||||
cached_field!(fields, files, |_, me: &Self| Files::make(0..me.files.len(), me, &me.tab));
|
||||
cached_field!(fields, stage, |_: &Lua, me: &Self| Ok(FolderStage::new(me.stage)));
|
||||
cached_field!(fields, window, |_, me: &Self| Files::make(me.window.clone(), me, &me.tab));
|
||||
|
||||
fields.add_field_method_get("offset", |_, me| Ok(me.offset));
|
||||
fields.add_field_method_get("cursor", |_, me| Ok(me.cursor));
|
||||
fields.add_field_method_get("hovered", |_, me| {
|
||||
me.hovered().map(|_| File::make(me.cursor, me, me.tab())).transpose()
|
||||
cached_field!(fields, hovered, |_, me: &Self| {
|
||||
me.hovered().map(|_| File::make(me.cursor, me, &me.tab)).transpose()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,26 @@
|
|||
use std::cell::RefCell;
|
||||
|
||||
use foldhash::HashMap;
|
||||
use mlua::{AnyUserData, UserData};
|
||||
use scopeguard::defer;
|
||||
use tracing::error;
|
||||
use yazi_plugin::LUA;
|
||||
use yazi_shared::RoCell;
|
||||
|
||||
use super::PtrCell;
|
||||
use crate::Ctx;
|
||||
|
||||
static TO_DESTROY: RoCell<RefCell<Vec<AnyUserData>>> = RoCell::new_const(RefCell::new(Vec::new()));
|
||||
pub(super) static FILE_CACHE: RoCell<RefCell<HashMap<PtrCell<yazi_fs::File>, AnyUserData>>> =
|
||||
RoCell::new();
|
||||
|
||||
pub(crate) struct Lives;
|
||||
|
||||
impl Lives {
|
||||
pub(crate) fn register() -> mlua::Result<()> {
|
||||
super::Folder::register(&LUA)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn scope<T>(cx: &Ctx, f: impl FnOnce() -> mlua::Result<T>) -> mlua::Result<T> {
|
||||
FILE_CACHE.init(Default::default());
|
||||
defer! { FILE_CACHE.drop(); }
|
||||
|
||||
let result = LUA.scope(|scope| {
|
||||
scope.add_destructor(|| {
|
||||
for ud in TO_DESTROY.borrow_mut().drain(..) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
yazi_macro::mod_flat!(context file files filter finder folder iter lives mode preference preview selected tab tabs tasks yanked);
|
||||
yazi_macro::mod_flat!(context file files filter finder folder iter lives mode preference preview ptr selected tab tabs tasks yanked);
|
||||
|
|
|
|||
|
|
@ -2,22 +2,22 @@ use std::ops::Deref;
|
|||
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods};
|
||||
|
||||
use super::Lives;
|
||||
use super::{Lives, PtrCell};
|
||||
|
||||
pub(super) struct Mode {
|
||||
inner: *const yazi_core::tab::Mode,
|
||||
inner: PtrCell<yazi_core::tab::Mode>,
|
||||
}
|
||||
|
||||
impl Deref for Mode {
|
||||
type Target = yazi_core::tab::Mode;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Mode {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Mode) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner: inner.into() })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,35 +1,39 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, UserData, UserDataFields};
|
||||
use mlua::{AnyUserData, UserData, UserDataFields, Value};
|
||||
use yazi_binding::cached_field;
|
||||
|
||||
use super::Lives;
|
||||
use super::{Lives, PtrCell};
|
||||
|
||||
pub(super) struct Preference {
|
||||
inner: *const yazi_core::tab::Preference,
|
||||
inner: PtrCell<yazi_core::tab::Preference>,
|
||||
|
||||
v_sort_by: Option<Value>,
|
||||
v_linemode: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for Preference {
|
||||
type Target = yazi_core::tab::Preference;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Preference {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Preference) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner: inner.into(), v_sort_by: None, v_linemode: None })
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for Preference {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("sort_by", |_, me| Ok(me.sort_by.to_string()));
|
||||
cached_field!(fields, sort_by, |_, me: &Self| Ok(me.sort_by.to_string()));
|
||||
fields.add_field_method_get("sort_sensitive", |_, me| Ok(me.sort_sensitive));
|
||||
fields.add_field_method_get("sort_reverse", |_, me| Ok(me.sort_reverse));
|
||||
fields.add_field_method_get("sort_dir_first", |_, me| Ok(me.sort_dir_first));
|
||||
fields.add_field_method_get("sort_translit", |_, me| Ok(me.sort_translit));
|
||||
|
||||
fields.add_field_method_get("linemode", |_, me| Ok(me.linemode.to_owned()));
|
||||
cached_field!(fields, linemode, |_, me: &Self| Ok(me.linemode.to_string()));
|
||||
fields.add_field_method_get("show_hidden", |_, me| Ok(me.show_hidden));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,39 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, UserData, UserDataFields};
|
||||
use mlua::{AnyUserData, UserData, UserDataFields, Value};
|
||||
use yazi_binding::cached_field;
|
||||
use yazi_config::LAYOUT;
|
||||
|
||||
use super::{Folder, Lives};
|
||||
use super::{Folder, Lives, PtrCell};
|
||||
|
||||
pub(super) struct Preview {
|
||||
tab: *const yazi_core::tab::Tab,
|
||||
tab: PtrCell<yazi_core::tab::Tab>,
|
||||
|
||||
v_folder: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for Preview {
|
||||
type Target = yazi_core::tab::Preview;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.tab().preview }
|
||||
fn deref(&self) -> &Self::Target { &self.tab.preview }
|
||||
}
|
||||
|
||||
impl Preview {
|
||||
#[inline]
|
||||
pub(super) fn make(tab: &yazi_core::tab::Tab) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { tab })
|
||||
Lives::scoped_userdata(Self { tab: tab.into(), v_folder: None })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } }
|
||||
}
|
||||
|
||||
impl UserData for Preview {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("skip", |_, me| Ok(me.skip));
|
||||
fields.add_field_method_get("folder", |_, me| {
|
||||
me.tab()
|
||||
cached_field!(fields, folder, |_, me: &Self| {
|
||||
me.tab
|
||||
.hovered_folder()
|
||||
.map(|f| {
|
||||
let limit = LAYOUT.get().preview.height as usize;
|
||||
Folder::make(Some(me.skip..f.files.len().min(me.skip + limit)), f, me.tab())
|
||||
Folder::make(Some(me.skip..f.files.len().min(me.skip + limit)), f, &me.tab)
|
||||
})
|
||||
.transpose()
|
||||
});
|
||||
|
|
|
|||
34
yazi-fm/src/lives/ptr.rs
Normal file
34
yazi-fm/src/lives/ptr.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
use std::{hash::{Hash, Hasher}, ops::Deref};
|
||||
|
||||
pub(super) struct PtrCell<T>(pub(super) *const T);
|
||||
|
||||
impl<T> Deref for PtrCell<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.0 } }
|
||||
}
|
||||
|
||||
impl<T> From<&T> for PtrCell<T> {
|
||||
fn from(value: &T) -> Self { Self(value) }
|
||||
}
|
||||
|
||||
impl<T> Clone for PtrCell<T> {
|
||||
fn clone(&self) -> Self { *self }
|
||||
}
|
||||
|
||||
impl<T> Copy for PtrCell<T> {}
|
||||
|
||||
impl<T> PartialEq for PtrCell<T> {
|
||||
fn eq(&self, other: &Self) -> bool { self.0.addr() == other.0.addr() }
|
||||
}
|
||||
|
||||
impl<T> Eq for PtrCell<T> {}
|
||||
|
||||
impl<T> Hash for PtrCell<T> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) { state.write_usize(self.0.addr()); }
|
||||
}
|
||||
|
||||
impl<T> PtrCell<T> {
|
||||
#[inline]
|
||||
pub(super) fn as_static(&self) -> &'static T { unsafe { &*self.0 } }
|
||||
}
|
||||
|
|
@ -2,29 +2,26 @@ use std::ops::Deref;
|
|||
|
||||
use indexmap::{IndexMap, map::Keys};
|
||||
use mlua::{AnyUserData, IntoLuaMulti, MetaMethod, UserData, UserDataMethods, UserDataRefMut};
|
||||
use yazi_plugin::url::Url;
|
||||
use yazi_binding::Url;
|
||||
|
||||
use super::{Iter, Lives};
|
||||
use super::{Iter, Lives, PtrCell};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(super) struct Selected {
|
||||
inner: *const IndexMap<yazi_shared::url::Url, u64>,
|
||||
inner: PtrCell<IndexMap<yazi_shared::url::Url, u64>>,
|
||||
}
|
||||
|
||||
impl Deref for Selected {
|
||||
type Target = IndexMap<yazi_shared::url::Url, u64>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { self.inner() }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Selected {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &IndexMap<yazi_shared::url::Url, u64>) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner: inner.into() })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inner(&self) -> &'static IndexMap<yazi_shared::url::Url, u64> { unsafe { &*self.inner } }
|
||||
}
|
||||
|
||||
impl UserData for Selected {
|
||||
|
|
@ -35,14 +32,14 @@ impl UserData for Selected {
|
|||
let iter = lua.create_function(
|
||||
|lua, mut iter: UserDataRefMut<Iter<Keys<yazi_shared::url::Url, u64>, _>>| {
|
||||
if let Some(next) = iter.next() {
|
||||
(next.0, Url(next.1.clone())).into_lua_multi(lua)
|
||||
(next.0, Url::new(next.1.clone())).into_lua_multi(lua)
|
||||
} else {
|
||||
().into_lua_multi(lua)
|
||||
}
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok((iter, Iter::make(me.inner().keys())))
|
||||
Ok((iter, Iter::make(me.inner.as_static().keys())))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,47 +1,69 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, UserData, UserDataFields, UserDataMethods};
|
||||
use yazi_plugin::url::UrlRef;
|
||||
use mlua::{AnyUserData, Lua, UserData, UserDataFields, UserDataMethods, Value};
|
||||
use yazi_binding::{UrlRef, cached_field};
|
||||
use yazi_plugin::Id;
|
||||
|
||||
use super::{Finder, Folder, Lives, Mode, Preference, Preview, Selected};
|
||||
use super::{Finder, Folder, Lives, Mode, Preference, Preview, PtrCell, Selected};
|
||||
|
||||
pub(super) struct Tab {
|
||||
inner: *const yazi_core::tab::Tab,
|
||||
inner: PtrCell<yazi_core::tab::Tab>,
|
||||
|
||||
v_name: Option<Value>,
|
||||
v_mode: Option<Value>,
|
||||
v_pref: Option<Value>,
|
||||
v_current: Option<Value>,
|
||||
v_parent: Option<Value>,
|
||||
v_selected: Option<Value>,
|
||||
v_preview: Option<Value>,
|
||||
v_finder: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for Tab {
|
||||
type Target = yazi_core::tab::Tab;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tab::Tab) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self {
|
||||
inner: inner.into(),
|
||||
|
||||
v_name: None,
|
||||
v_mode: None,
|
||||
v_pref: None,
|
||||
v_current: None,
|
||||
v_parent: None,
|
||||
v_selected: None,
|
||||
v_preview: None,
|
||||
v_finder: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for Tab {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("id", |_, me| Ok(me.id.get()));
|
||||
fields.add_field_method_get("mode", |_, me| Mode::make(&me.mode));
|
||||
fields.add_field_method_get("pref", |_, me| Preference::make(&me.pref));
|
||||
fields.add_field_method_get("current", |_, me| Folder::make(None, &me.current, me));
|
||||
fields.add_field_method_get("parent", |_, me| {
|
||||
fields.add_field_method_get("id", |_, me| Ok(Id(me.id)));
|
||||
cached_field!(fields, name, |lua: &Lua, me: &Self| {
|
||||
lua.create_string(me.current.url.name().as_encoded_bytes())
|
||||
});
|
||||
|
||||
cached_field!(fields, mode, |_, me: &Self| Mode::make(&me.mode));
|
||||
cached_field!(fields, pref, |_, me: &Self| Preference::make(&me.pref));
|
||||
cached_field!(fields, current, |_, me: &Self| Folder::make(None, &me.current, me));
|
||||
cached_field!(fields, parent, |_, me: &Self| {
|
||||
me.parent.as_ref().map(|f| Folder::make(None, f, me)).transpose()
|
||||
});
|
||||
|
||||
fields.add_field_method_get("selected", |_, me| Selected::make(&me.selected));
|
||||
cached_field!(fields, selected, |_, me: &Self| Selected::make(&me.selected));
|
||||
|
||||
fields.add_field_method_get("preview", |_, me| Preview::make(me));
|
||||
fields.add_field_method_get("finder", |_, me| me.finder.as_ref().map(Finder::make).transpose());
|
||||
cached_field!(fields, preview, |_, me: &Self| Preview::make(me));
|
||||
cached_field!(fields, finder, |_, me: &Self| me.finder.as_ref().map(Finder::make).transpose());
|
||||
}
|
||||
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_method("name", |lua, me, ()| {
|
||||
lua.create_string(me.current.url.name().as_encoded_bytes())
|
||||
});
|
||||
methods.add_method("history", |_, me, url: UrlRef| {
|
||||
me.history.get(&url).map(|f| Folder::make(None, f, me)).transpose()
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,22 +2,22 @@ use std::ops::Deref;
|
|||
|
||||
use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods};
|
||||
|
||||
use super::{Lives, Tab};
|
||||
use super::{Lives, PtrCell, Tab};
|
||||
|
||||
pub(super) struct Tabs {
|
||||
inner: *const yazi_core::mgr::Tabs,
|
||||
inner: PtrCell<yazi_core::mgr::Tabs>,
|
||||
}
|
||||
|
||||
impl Deref for Tabs {
|
||||
type Target = yazi_core::mgr::Tabs;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Tabs {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::mgr::Tabs) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner: inner.into() })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,31 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields};
|
||||
use mlua::{AnyUserData, Lua, LuaSerdeExt, UserData, UserDataFields, Value};
|
||||
use yazi_binding::cached_field;
|
||||
|
||||
use super::Lives;
|
||||
use super::{Lives, PtrCell};
|
||||
|
||||
pub(super) struct Tasks {
|
||||
inner: *const yazi_core::tasks::Tasks,
|
||||
inner: PtrCell<yazi_core::tasks::Tasks>,
|
||||
|
||||
v_progress: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for Tasks {
|
||||
type Target = yazi_core::tasks::Tasks;
|
||||
|
||||
fn deref(&self) -> &Self::Target { unsafe { &*self.inner } }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Tasks {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::tasks::Tasks) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner: inner.into(), v_progress: None })
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for Tasks {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("progress", |lua, me| lua.to_value(&me.progress))
|
||||
cached_field!(fields, progress, |lua: &Lua, me: &Self| lua.to_value(&me.progress));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,25 @@
|
|||
use std::{collections::hash_set, ops::Deref};
|
||||
|
||||
use mlua::{AnyUserData, IntoLuaMulti, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRefMut};
|
||||
use yazi_plugin::url::Url;
|
||||
use yazi_binding::Url;
|
||||
|
||||
use super::{Iter, Lives};
|
||||
use super::{Iter, Lives, PtrCell};
|
||||
|
||||
pub(super) struct Yanked {
|
||||
inner: *const yazi_core::mgr::Yanked,
|
||||
inner: PtrCell<yazi_core::mgr::Yanked>,
|
||||
}
|
||||
|
||||
impl Deref for Yanked {
|
||||
type Target = yazi_core::mgr::Yanked;
|
||||
|
||||
fn deref(&self) -> &Self::Target { self.inner() }
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl Yanked {
|
||||
#[inline]
|
||||
pub(super) fn make(inner: &yazi_core::mgr::Yanked) -> mlua::Result<AnyUserData> {
|
||||
Lives::scoped_userdata(Self { inner })
|
||||
Lives::scoped_userdata(Self { inner: inner.into() })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn inner(&self) -> &'static yazi_core::mgr::Yanked { unsafe { &*self.inner } }
|
||||
}
|
||||
|
||||
impl UserData for Yanked {
|
||||
|
|
@ -37,14 +34,14 @@ impl UserData for Yanked {
|
|||
let iter = lua.create_function(
|
||||
|lua, mut iter: UserDataRefMut<Iter<hash_set::Iter<yazi_shared::url::Url>, _>>| {
|
||||
if let Some(next) = iter.next() {
|
||||
(next.0, Url(next.1.clone())).into_lua_multi(lua)
|
||||
(next.0, Url::new(next.1.clone())).into_lua_multi(lua)
|
||||
} else {
|
||||
().into_lua_multi(lua)
|
||||
}
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok((iter, Iter::make(me.inner().iter())))
|
||||
Ok((iter, Iter::make(me.inner.as_static().iter())))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-fs"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,9 +9,9 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-ffi = { path = "../yazi-ffi", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-ffi = { path = "../yazi-ffi", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-macro"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-plugin"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -13,14 +13,15 @@ default = [ "vendored-lua" ]
|
|||
vendored-lua = [ "mlua/vendored" ]
|
||||
|
||||
[dependencies]
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.3.7" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.3.7" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.3.7" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.3.7" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-adapter = { path = "../yazi-adapter", version = "25.4.4" }
|
||||
yazi-binding = { path = "../yazi-binding", version = "25.4.4" }
|
||||
yazi-boot = { path = "../yazi-boot", version = "25.4.4" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.4.4" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.4.4" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
ansi-to-tui = { workspace = true }
|
||||
|
|
@ -32,6 +33,7 @@ globset = { workspace = true }
|
|||
md-5 = { workspace = true }
|
||||
mlua = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
paste = { workspace = true }
|
||||
ratatui = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
syntect = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ function Entity:icon()
|
|||
local icon = self._file:icon()
|
||||
if not icon then
|
||||
return ""
|
||||
elseif self._file:is_hovered() then
|
||||
elseif self._file.is_hovered then
|
||||
return icon.text .. " "
|
||||
else
|
||||
return ui.Line(icon.text .. " "):style(icon.style)
|
||||
|
|
@ -52,7 +52,7 @@ function Entity:highlights()
|
|||
end
|
||||
|
||||
function Entity:found()
|
||||
if not self._file:is_hovered() then
|
||||
if not self._file.is_hovered then
|
||||
return ""
|
||||
end
|
||||
|
||||
|
|
@ -86,9 +86,9 @@ end
|
|||
|
||||
function Entity:style()
|
||||
local s = self._file:style()
|
||||
if not self._file:is_hovered() then
|
||||
if not self._file.is_hovered then
|
||||
return s
|
||||
elseif self._file:in_preview() then
|
||||
elseif self._file.in_preview then
|
||||
return s and s:patch(th.mgr.preview_hovered) or th.mgr.preview_hovered
|
||||
else
|
||||
return s and s:patch(th.mgr.hovered) or th.mgr.hovered
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ function Header:flags()
|
|||
|
||||
local t = {}
|
||||
if cwd.is_search then
|
||||
t[#t + 1] = string.format("search: %s", cwd:frag())
|
||||
t[#t + 1] = string.format("search: %s", cwd.frag)
|
||||
end
|
||||
if filter then
|
||||
t[#t + 1] = string.format("filter: %s", filter)
|
||||
|
|
@ -84,7 +84,7 @@ function Header:tabs()
|
|||
for i = 1, tabs do
|
||||
local text = i
|
||||
if th.mgr.tab_width > 2 then
|
||||
text = ya.truncate(text .. " " .. cx.tabs[i]:name(), { max = th.mgr.tab_width })
|
||||
text = ya.truncate(text .. " " .. cx.tabs[i].name, { max = th.mgr.tab_width })
|
||||
end
|
||||
if i == cx.tabs.idx then
|
||||
spans[#spans + 1] = ui.Span(" " .. text .. " "):style(th.mgr.tab_active)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ function M:entry(job)
|
|||
end
|
||||
|
||||
local value, event = ya.input {
|
||||
title = string.format('Password for "%s":', from:name()),
|
||||
title = string.format('Password for "%s":', from.name),
|
||||
position = { "center", w = 50 },
|
||||
}
|
||||
if event == 1 then
|
||||
|
|
@ -39,7 +39,7 @@ function M:entry(job)
|
|||
end
|
||||
|
||||
function M:try_with(from, pwd, to)
|
||||
to = to or from:parent()
|
||||
to = to or from.parent
|
||||
if not to then
|
||||
fail("Invalid URL '%s'", from)
|
||||
end
|
||||
|
|
@ -90,7 +90,7 @@ function M:tidy(from, to, tmp)
|
|||
if only then
|
||||
target = to:join(outs[1].name)
|
||||
else
|
||||
target = to:join(self.trim_ext(from:name()))
|
||||
target = to:join(self.trim_ext(from.name))
|
||||
end
|
||||
|
||||
target = fs.unique_name(target)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use mlua::{ExternalError, IntoLuaMulti, UserData, Value};
|
||||
|
||||
use crate::Error;
|
||||
use yazi_binding::Error;
|
||||
|
||||
pub struct MpscTx(pub tokio::sync::mpsc::Sender<Value>);
|
||||
pub struct MpscRx(pub tokio::sync::mpsc::Receiver<Value>);
|
||||
|
|
|
|||
|
|
@ -1,24 +1,32 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use mlua::{UserData, UserDataFields};
|
||||
use mlua::{Lua, UserData, UserDataFields, Value};
|
||||
use yazi_binding::cached_field;
|
||||
|
||||
use crate::elements::Style;
|
||||
|
||||
pub struct Icon(&'static yazi_shared::theme::Icon);
|
||||
pub struct Icon {
|
||||
inner: &'static yazi_shared::theme::Icon,
|
||||
|
||||
v_text: Option<Value>,
|
||||
v_style: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for Icon {
|
||||
type Target = yazi_shared::theme::Icon;
|
||||
|
||||
fn deref(&self) -> &Self::Target { self.0 }
|
||||
fn deref(&self) -> &Self::Target { self.inner }
|
||||
}
|
||||
|
||||
impl From<&'static yazi_shared::theme::Icon> for Icon {
|
||||
fn from(icon: &'static yazi_shared::theme::Icon) -> Self { Self(icon) }
|
||||
fn from(icon: &'static yazi_shared::theme::Icon) -> Self {
|
||||
Self { inner: icon, v_text: None, v_style: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for Icon {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("text", |lua, me| lua.create_string(&me.text));
|
||||
fields.add_field_method_get("style", |_, me| Ok(Style::from(me.style)));
|
||||
cached_field!(fields, text, |lua: &Lua, me: &Self| lua.create_string(&me.text));
|
||||
cached_field!(fields, style, |_, me: &Self| Ok(Style::from(me.style)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use mlua::{Function, IntoLua, Lua, UserData, Value};
|
||||
use yazi_binding::{UrlRef, cached_field};
|
||||
use yazi_config::YAZI;
|
||||
|
||||
use crate::{Composer, file::FileRef, url::UrlRef};
|
||||
use crate::{Composer, file::FileRef};
|
||||
|
||||
pub(super) struct Plugin;
|
||||
|
||||
|
|
@ -21,61 +22,93 @@ impl Plugin {
|
|||
|
||||
fn fetchers(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|lua, (file, mime): (FileRef, mlua::String)| {
|
||||
lua.create_sequence_from(YAZI.plugin.fetchers(&file.url, &mime.to_str()?).map(Fetcher))
|
||||
lua.create_sequence_from(YAZI.plugin.fetchers(&file.url, &mime.to_str()?).map(Fetcher::new))
|
||||
})
|
||||
}
|
||||
|
||||
fn spotter(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|_, (url, mime): (UrlRef, mlua::String)| {
|
||||
Ok(YAZI.plugin.spotter(&url, &mime.to_str()?).map(Spotter))
|
||||
Ok(YAZI.plugin.spotter(&url, &mime.to_str()?).map(Spotter::new))
|
||||
})
|
||||
}
|
||||
|
||||
fn preloaders(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|lua, (url, mime): (UrlRef, mlua::String)| {
|
||||
lua.create_sequence_from(YAZI.plugin.preloaders(&url, &mime.to_str()?).map(Preloader))
|
||||
lua.create_sequence_from(YAZI.plugin.preloaders(&url, &mime.to_str()?).map(Preloader::new))
|
||||
})
|
||||
}
|
||||
|
||||
fn previewer(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|_, (url, mime): (UrlRef, mlua::String)| {
|
||||
Ok(YAZI.plugin.previewer(&url, &mime.to_str()?).map(Previewer))
|
||||
Ok(YAZI.plugin.previewer(&url, &mime.to_str()?).map(Previewer::new))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// --- Fetcher
|
||||
struct Fetcher(&'static yazi_config::plugin::Fetcher);
|
||||
struct Fetcher {
|
||||
inner: &'static yazi_config::plugin::Fetcher,
|
||||
|
||||
v_cmd: Option<Value>,
|
||||
}
|
||||
|
||||
impl Fetcher {
|
||||
pub fn new(inner: &'static yazi_config::plugin::Fetcher) -> Self { Self { inner, v_cmd: None } }
|
||||
}
|
||||
|
||||
impl UserData for Fetcher {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("cmd", |lua, me| lua.create_string(&me.0.run.name));
|
||||
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
|
||||
}
|
||||
}
|
||||
|
||||
// --- Spotter
|
||||
struct Spotter(&'static yazi_config::plugin::Spotter);
|
||||
struct Spotter {
|
||||
inner: &'static yazi_config::plugin::Spotter,
|
||||
|
||||
v_cmd: Option<Value>,
|
||||
}
|
||||
|
||||
impl Spotter {
|
||||
pub fn new(inner: &'static yazi_config::plugin::Spotter) -> Self { Self { inner, v_cmd: None } }
|
||||
}
|
||||
|
||||
impl UserData for Spotter {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("cmd", |lua, me| lua.create_string(&me.0.run.name));
|
||||
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
|
||||
}
|
||||
}
|
||||
|
||||
// --- Preloader
|
||||
struct Preloader(&'static yazi_config::plugin::Preloader);
|
||||
struct Preloader {
|
||||
inner: &'static yazi_config::plugin::Preloader,
|
||||
|
||||
v_cmd: Option<Value>,
|
||||
}
|
||||
|
||||
impl Preloader {
|
||||
pub fn new(inner: &'static yazi_config::plugin::Preloader) -> Self { Self { inner, v_cmd: None } }
|
||||
}
|
||||
|
||||
impl UserData for Preloader {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("cmd", |lua, me| lua.create_string(&me.0.run.name));
|
||||
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
|
||||
}
|
||||
}
|
||||
|
||||
// --- Previewer
|
||||
struct Previewer(&'static yazi_config::plugin::Previewer);
|
||||
struct Previewer {
|
||||
inner: &'static yazi_config::plugin::Previewer,
|
||||
|
||||
v_cmd: Option<Value>,
|
||||
}
|
||||
|
||||
impl Previewer {
|
||||
pub fn new(inner: &'static yazi_config::plugin::Previewer) -> Self { Self { inner, v_cmd: None } }
|
||||
}
|
||||
|
||||
impl UserData for Previewer {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("cmd", |lua, me| lua.create_string(&me.0.run.name));
|
||||
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
use mlua::{IntoLua, Lua, LuaSerdeExt, SerializeOptions, Value};
|
||||
use yazi_adapter::EMULATOR;
|
||||
use yazi_binding::Url;
|
||||
use yazi_boot::ARGS;
|
||||
use yazi_config::{THEME, YAZI};
|
||||
use yazi_config::YAZI;
|
||||
|
||||
use crate::{Composer, url::Url};
|
||||
use crate::Composer;
|
||||
|
||||
pub const OPTS: SerializeOptions =
|
||||
SerializeOptions::new().serialize_none_to_null(false).serialize_unit_to_null(false);
|
||||
|
||||
pub struct Runtime<'a> {
|
||||
lua: &'a Lua,
|
||||
}
|
||||
pub struct Runtime;
|
||||
|
||||
impl<'a> Runtime<'a> {
|
||||
impl Runtime {
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
Composer::make(lua, 10, |lua, key| {
|
||||
match key {
|
||||
|
|
@ -30,9 +29,9 @@ impl<'a> Runtime<'a> {
|
|||
|
||||
fn args(lua: &Lua) -> mlua::Result<Value> {
|
||||
Composer::make(lua, 5, |lua, key| match key {
|
||||
b"entries" => lua.create_sequence_from(ARGS.entries.iter().map(Url::from))?.into_lua(lua),
|
||||
b"cwd_file" => ARGS.cwd_file.as_ref().map(Url::from).into_lua(lua),
|
||||
b"chooser_file" => ARGS.chooser_file.as_ref().map(Url::from).into_lua(lua),
|
||||
b"entries" => lua.create_sequence_from(ARGS.entries.iter().map(Url::new))?.into_lua(lua),
|
||||
b"cwd_file" => ARGS.cwd_file.as_ref().map(Url::new).into_lua(lua),
|
||||
b"chooser_file" => ARGS.chooser_file.as_ref().map(Url::new).into_lua(lua),
|
||||
_ => Ok(Value::Nil),
|
||||
})
|
||||
}
|
||||
|
|
@ -106,24 +105,4 @@ impl<'a> Runtime<'a> {
|
|||
.into_lua(lua)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new(lua: &'a Lua) -> Self { Self { lua } }
|
||||
|
||||
// TODO: remove this
|
||||
pub fn install_manager(self) -> mlua::Result<Self> {
|
||||
self.lua.globals().raw_set("MANAGER", self.lua.to_value_with(&YAZI.mgr, OPTS)?)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
// TODO: remove this
|
||||
pub fn install_theme(self) -> mlua::Result<Self> {
|
||||
self.lua.globals().raw_set("THEME", self.lua.to_value_with(&*THEME, OPTS)?)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
// TODO: remove this
|
||||
pub fn install_preview(self) -> mlua::Result<Self> {
|
||||
self.lua.globals().raw_set("PREVIEW", self.lua.to_value_with(&YAZI.preview, OPTS)?)?;
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ impl Pos {
|
|||
|
||||
impl UserData for Pos {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
// TODO: cache
|
||||
fields.add_field_method_get(1, |_, me| Ok(me.origin.to_string()));
|
||||
fields.add_field_method_get("x", |_, me| Ok(me.offset.x));
|
||||
fields.add_field_method_get("y", |_, me| Ok(me.offset.y));
|
||||
|
|
|
|||
|
|
@ -1,26 +1,44 @@
|
|||
use mlua::{AnyUserData, ExternalError, FromLua, IntoLua, Lua, Table, UserDataRef, Value};
|
||||
use std::ops::Deref;
|
||||
|
||||
use mlua::{ExternalError, FromLua, Lua, Table, UserData, UserDataFields, UserDataMethods, UserDataRef, Value};
|
||||
use yazi_binding::Url;
|
||||
|
||||
use crate::{bindings::Cha, impl_file_fields, impl_file_methods};
|
||||
|
||||
pub type FileRef = UserDataRef<yazi_fs::File>;
|
||||
pub type FileRef = UserDataRef<File>;
|
||||
|
||||
pub struct File(pub yazi_fs::File);
|
||||
pub struct File {
|
||||
inner: yazi_fs::File,
|
||||
|
||||
v_cha: Option<Value>,
|
||||
v_url: Option<Value>,
|
||||
v_link_to: Option<Value>,
|
||||
v_name: Option<Value>,
|
||||
}
|
||||
|
||||
impl Deref for File {
|
||||
type Target = yazi_fs::File;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
}
|
||||
|
||||
impl From<File> for yazi_fs::File {
|
||||
fn from(value: File) -> Self { value.inner }
|
||||
}
|
||||
|
||||
impl File {
|
||||
#[inline]
|
||||
pub fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<yazi_fs::File>(|reg| {
|
||||
impl_file_fields!(reg);
|
||||
impl_file_methods!(reg);
|
||||
})
|
||||
pub fn new(inner: yazi_fs::File) -> Self {
|
||||
Self { inner, v_cha: None, v_url: None, v_link_to: None, v_name: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl File {
|
||||
pub fn install(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.globals().raw_set(
|
||||
"File",
|
||||
lua.create_function(|_, t: Table| {
|
||||
Ok(Self(yazi_fs::File {
|
||||
url: t.raw_get::<AnyUserData>("url")?.take()?,
|
||||
Ok(Self::new(yazi_fs::File {
|
||||
url: t.raw_get::<Url>("url")?.into(),
|
||||
cha: *t.raw_get::<Cha>("cha")?,
|
||||
..Default::default()
|
||||
}))
|
||||
|
|
@ -32,14 +50,18 @@ impl File {
|
|||
impl FromLua for File {
|
||||
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
|
||||
match value {
|
||||
Value::UserData(ud) => ud.take().map(Self),
|
||||
Value::UserData(ud) => ud.take().map(Self::new),
|
||||
_ => Err("Expected a File".into_lua_err()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua for File {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
lua.create_any_userdata(self.0)?.into_lua(lua)
|
||||
impl UserData for File {
|
||||
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
||||
impl_file_fields!(fields);
|
||||
}
|
||||
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
impl_file_methods!(methods);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,3 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
use mlua::Lua;
|
||||
|
||||
yazi_macro::mod_flat!(file);
|
||||
|
||||
pub fn pour(lua: &Lua) -> mlua::Result<()> {
|
||||
file::File::register(lua)?;
|
||||
file::File::install(lua)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use globset::GlobBuilder;
|
||||
use mlua::{ExternalError, ExternalResult, Function, IntoLua, IntoLuaMulti, Lua, Table, Value};
|
||||
use tokio::fs;
|
||||
use yazi_binding::{Error, Url, UrlRef};
|
||||
use yazi_fs::{mounts::PARTITIONS, remove_dir_clean};
|
||||
|
||||
use crate::{Composer, Error, bindings::Cha, file::File, url::{Url, UrlRef}};
|
||||
use crate::{Composer, bindings::Cha, file::File};
|
||||
|
||||
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
|
||||
Composer::make(lua, 10, |lua, key| {
|
||||
|
|
@ -34,7 +35,7 @@ fn op(lua: &Lua) -> mlua::Result<Function> {
|
|||
|
||||
fn cwd(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|lua, ()| match std::env::current_dir() {
|
||||
Ok(p) => (Url::from(p), Value::Nil).into_lua_multi(lua),
|
||||
Ok(p) => (Url::new(p), Value::Nil).into_lua_multi(lua),
|
||||
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(lua),
|
||||
})
|
||||
}
|
||||
|
|
@ -139,7 +140,7 @@ fn read_dir(lua: &Lua) -> mlua::Result<Function> {
|
|||
} else {
|
||||
yazi_fs::File::from_dummy(url, next.file_type().await.ok())
|
||||
};
|
||||
files.push(File(file));
|
||||
files.push(File::new(file));
|
||||
}
|
||||
|
||||
let tbl = lua.create_table_with_capacity(files.len(), 0)?;
|
||||
|
|
@ -154,9 +155,9 @@ fn read_dir(lua: &Lua) -> mlua::Result<Function> {
|
|||
fn expand_url(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_function(|_, value: Value| {
|
||||
use yazi_fs::expand_path;
|
||||
Ok(Url::from(match value {
|
||||
Ok(Url::new(match value {
|
||||
Value::String(s) => expand_path(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => expand_path(&*ud.borrow::<yazi_shared::url::Url>()?),
|
||||
Value::UserData(ud) => expand_path(&*ud.borrow::<yazi_binding::Url>()?),
|
||||
_ => Err("must be a string or a Url".into_lua_err())?,
|
||||
}))
|
||||
})
|
||||
|
|
@ -165,7 +166,7 @@ fn expand_url(lua: &Lua) -> mlua::Result<Function> {
|
|||
fn unique_name(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_async_function(|lua, url: UrlRef| async move {
|
||||
match yazi_fs::unique_name(url.clone(), async { false }).await {
|
||||
Ok(u) => (Url(u), Value::Nil).into_lua_multi(&lua),
|
||||
Ok(u) => (Url::new(u), Value::Nil).into_lua_multi(&lua),
|
||||
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use mlua::{IntoLua, Lua, Table};
|
||||
use yazi_binding::Url;
|
||||
|
||||
use crate::{Id, bindings::Cha, file::File, url::Url};
|
||||
use crate::{Id, bindings::Cha, file::File};
|
||||
|
||||
pub(super) struct FilesOp(yazi_fs::FilesOp);
|
||||
|
||||
|
|
@ -11,8 +12,11 @@ impl FilesOp {
|
|||
let files: Table = t.raw_get("files")?;
|
||||
|
||||
Ok(Self(yazi_fs::FilesOp::Part(
|
||||
url.0,
|
||||
files.sequence_values::<File>().map(|f| f.map(|f| f.0)).collect::<mlua::Result<Vec<_>>>()?,
|
||||
url.into(),
|
||||
files
|
||||
.sequence_values::<File>()
|
||||
.map(|f| f.map(Into::into))
|
||||
.collect::<mlua::Result<Vec<_>>>()?,
|
||||
*id,
|
||||
)))
|
||||
}
|
||||
|
|
@ -22,7 +26,7 @@ impl FilesOp {
|
|||
let cha: Cha = t.raw_get("cha")?;
|
||||
let url: Url = t.raw_get("url")?;
|
||||
|
||||
Ok(Self(yazi_fs::FilesOp::Done(url.0, *cha, *id)))
|
||||
Ok(Self(yazi_fs::FilesOp::Done(url.into(), *cha, *id)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,6 @@ impl FromLua for Id {
|
|||
|
||||
impl UserData for Id {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("value", |_, me: &Self| Ok(me.0.get()));
|
||||
fields.add_field_method_get("value", |_, me| Ok(me.0.get()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use mlua::{ExternalResult, FromLua, IntoLua, Lua, ObjectLike, Value};
|
||||
use tokio::runtime::Handle;
|
||||
use yazi_binding::Error;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_shared::event::CmdCow;
|
||||
|
||||
use super::slim_lua;
|
||||
use crate::{Error, file::File, loader::LOADER};
|
||||
use crate::{file::File, loader::LOADER};
|
||||
|
||||
pub async fn fetch(
|
||||
cmd: CmdCow,
|
||||
|
|
@ -23,7 +24,7 @@ pub async fn fetch(
|
|||
"fetch",
|
||||
lua.create_table_from([
|
||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||
("files", lua.create_sequence_from(files.into_iter().map(File))?.into_lua(&lua)?),
|
||||
("files", lua.create_sequence_from(files.into_iter().map(File::new))?.into_lua(&lua)?),
|
||||
])?,
|
||||
))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ use crate::runtime::Runtime;
|
|||
pub fn slim_lua(name: &str) -> mlua::Result<Lua> {
|
||||
let lua = Lua::new();
|
||||
lua.set_named_registry_value("ir", Runtime::new(name))?;
|
||||
crate::config::Runtime::new(&lua).install_preview()?;
|
||||
|
||||
// Base
|
||||
let globals = lua.globals();
|
||||
|
|
@ -17,10 +16,10 @@ pub fn slim_lua(name: &str) -> mlua::Result<Lua> {
|
|||
globals.raw_set("th", crate::config::Theme::compose(&lua)?)?;
|
||||
|
||||
crate::bindings::Cha::install(&lua)?;
|
||||
crate::file::pour(&lua)?;
|
||||
crate::url::pour(&lua)?;
|
||||
crate::file::File::install(&lua)?;
|
||||
yazi_binding::Url::install(&lua)?;
|
||||
|
||||
crate::Error::install(&lua)?;
|
||||
yazi_binding::Error::install(&lua)?;
|
||||
crate::loader::install_isolate(&lua)?;
|
||||
crate::process::install(&lua)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ fn peek_sync(cmd: &'static Cmd, file: yazi_fs::File, mime: Cow<'static, str>, sk
|
|||
let job = lua.create_table_from([
|
||||
("area", Rect::from(LAYOUT.get().preview).into_lua(lua)?),
|
||||
("args", Sendable::args_to_table_ref(lua, &cmd.args)?.into_lua(lua)?),
|
||||
("file", File(file).into_lua(lua)?),
|
||||
("file", File::new(file).into_lua(lua)?),
|
||||
("mime", mime.into_lua(lua)?),
|
||||
("skip", skip.into_lua(lua)?),
|
||||
])?;
|
||||
|
|
@ -88,7 +88,7 @@ fn peek_async(
|
|||
let job = lua.create_table_from([
|
||||
("area", Rect::from(LAYOUT.get().preview).into_lua(&lua)?),
|
||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||
("file", File(file).into_lua(&lua)?),
|
||||
("file", File::new(file).into_lua(&lua)?),
|
||||
("mime", mime.into_lua(&lua)?),
|
||||
("skip", skip.into_lua(&lua)?),
|
||||
])?;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
use mlua::{ExternalResult, IntoLua, ObjectLike};
|
||||
use tokio::runtime::Handle;
|
||||
use yazi_binding::Error;
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_shared::event::Cmd;
|
||||
|
||||
use super::slim_lua;
|
||||
use crate::{Error, elements::Rect, file::File, loader::LOADER};
|
||||
use crate::{elements::Rect, file::File, loader::LOADER};
|
||||
|
||||
pub async fn preload(
|
||||
cmd: &'static Cmd,
|
||||
|
|
@ -20,7 +21,7 @@ pub async fn preload(
|
|||
let job = lua.create_table_from([
|
||||
("area", Rect::from(LAYOUT.get().preview).into_lua(&lua)?),
|
||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||
("file", File(file).into_lua(&lua)?),
|
||||
("file", File::new(file).into_lua(&lua)?),
|
||||
("skip", 0.into_lua(&lua)?),
|
||||
])?;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use crate::{elements::Rect, file::File};
|
|||
pub fn seek_sync(cmd: &'static Cmd, file: yazi_fs::File, units: i16) {
|
||||
let cb: PluginCallback = Box::new(move |lua, plugin| {
|
||||
let job = lua.create_table_from([
|
||||
("file", File(file).into_lua(lua)?),
|
||||
("file", File::new(file).into_lua(lua)?),
|
||||
("area", Rect::from(LAYOUT.get().preview).into_lua(lua)?),
|
||||
("units", units.into_lua(lua)?),
|
||||
])?;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ pub fn spot(
|
|||
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
||||
let job = lua.create_table_from([
|
||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||
("file", File(file).into_lua(&lua)?),
|
||||
("file", File::new(file).into_lua(&lua)?),
|
||||
("mime", mime.into_lua(&lua)?),
|
||||
("skip", skip.into_lua(&lua)?),
|
||||
])?;
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
mod macros;
|
||||
|
||||
yazi_macro::mod_pub!(bindings config elements external file fs isolate loader process pubsub url utils);
|
||||
yazi_macro::mod_pub!(bindings config elements external file fs isolate loader process pubsub utils);
|
||||
|
||||
yazi_macro::mod_flat!(clipboard composer error id lua runtime);
|
||||
yazi_macro::mod_flat!(clipboard composer id lua runtime);
|
||||
|
||||
pub fn init() -> anyhow::Result<()> {
|
||||
CLIPBOARD.with(<_>::default);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ pub(super) fn init_lua() -> Result<()> {
|
|||
|
||||
fn stage_1(lua: &'static Lua) -> Result<()> {
|
||||
lua.set_named_registry_value("ir", Runtime::default())?;
|
||||
crate::config::Runtime::new(lua).install_manager()?.install_theme()?;
|
||||
|
||||
// Base
|
||||
let globals = lua.globals();
|
||||
|
|
@ -29,11 +28,11 @@ fn stage_1(lua: &'static Lua) -> Result<()> {
|
|||
globals.raw_set("rt", crate::config::Runtime::compose(lua)?)?;
|
||||
globals.raw_set("th", crate::config::Theme::compose(lua)?)?;
|
||||
|
||||
crate::Error::install(lua)?;
|
||||
yazi_binding::Error::install(lua)?;
|
||||
crate::bindings::Cha::install(lua)?;
|
||||
crate::loader::install(lua)?;
|
||||
crate::file::pour(lua)?;
|
||||
crate::url::pour(lua)?;
|
||||
crate::file::File::install(lua)?;
|
||||
yazi_binding::Url::install(lua)?;
|
||||
|
||||
// Addons
|
||||
lua.load(preset!("ya")).set_name("ya.lua").exec()?;
|
||||
|
|
|
|||
|
|
@ -81,14 +81,17 @@ macro_rules! impl_style_shorthands {
|
|||
#[macro_export]
|
||||
macro_rules! impl_file_fields {
|
||||
($fields:ident) => {
|
||||
use mlua::UserDataFields;
|
||||
yazi_binding::cached_field!($fields, cha, |_, me: &Self| Ok($crate::bindings::Cha::from(
|
||||
me.cha
|
||||
)));
|
||||
yazi_binding::cached_field!($fields, url, |_, me: &Self| Ok(yazi_binding::Url::new(
|
||||
me.url_owned()
|
||||
)));
|
||||
yazi_binding::cached_field!($fields, link_to, |_, me: &Self| Ok(
|
||||
me.link_to.clone().map(yazi_binding::Url::new)
|
||||
));
|
||||
|
||||
$fields.add_field_method_get("cha", |_, me| Ok($crate::bindings::Cha::from(me.cha)));
|
||||
$fields.add_field_method_get("url", |_, me| Ok($crate::url::Url(me.url_owned())));
|
||||
$fields
|
||||
.add_field_method_get("link_to", |_, me| Ok(me.link_to.clone().map(|u| $crate::url::Url(u))));
|
||||
|
||||
$fields.add_field_method_get("name", |lua, me| {
|
||||
yazi_binding::cached_field!($fields, name, |lua: &mlua::Lua, me: &Self| {
|
||||
Some(me.name())
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(|s| lua.create_string(s.as_encoded_bytes()))
|
||||
|
|
@ -100,8 +103,6 @@ macro_rules! impl_file_fields {
|
|||
#[macro_export]
|
||||
macro_rules! impl_file_methods {
|
||||
($methods:ident) => {
|
||||
use mlua::UserDataMethods;
|
||||
|
||||
$methods.add_method("hash", |_, me, ()| Ok(me.hash()));
|
||||
|
||||
$methods.add_method("icon", |_, me, ()| {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ use std::{ops::DerefMut, time::Duration};
|
|||
use futures::future::try_join3;
|
||||
use mlua::{AnyUserData, ExternalError, IntoLua, IntoLuaMulti, Table, UserData, Value};
|
||||
use tokio::{io::{self, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, process::{ChildStderr, ChildStdin, ChildStdout}, select};
|
||||
use yazi_binding::Error;
|
||||
|
||||
use super::Status;
|
||||
use crate::{Error, process::Output};
|
||||
use crate::process::Output;
|
||||
|
||||
pub struct Child {
|
||||
inner: tokio::process::Child,
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@ use std::process::Stdio;
|
|||
|
||||
use mlua::{AnyUserData, ExternalError, IntoLuaMulti, Lua, MetaMethod, Table, UserData, Value};
|
||||
use tokio::process::{ChildStderr, ChildStdin, ChildStdout};
|
||||
use yazi_binding::Error;
|
||||
|
||||
use super::{Child, output::Output};
|
||||
use crate::{Error, process::Status};
|
||||
use crate::process::Status;
|
||||
|
||||
pub struct Command {
|
||||
inner: tokio::process::Command,
|
||||
|
|
|
|||
|
|
@ -1,19 +1,26 @@
|
|||
use mlua::UserData;
|
||||
use mlua::{Lua, UserData, Value};
|
||||
use yazi_binding::cached_field;
|
||||
|
||||
use super::Status;
|
||||
|
||||
pub struct Output {
|
||||
inner: std::process::Output,
|
||||
|
||||
v_status: Option<Value>,
|
||||
v_stdout: Option<Value>,
|
||||
v_stderr: Option<Value>,
|
||||
}
|
||||
|
||||
impl Output {
|
||||
pub fn new(inner: std::process::Output) -> Self { Self { inner } }
|
||||
pub fn new(inner: std::process::Output) -> Self {
|
||||
Self { inner, v_status: None, v_stdout: None, v_stderr: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for Output {
|
||||
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
|
||||
fields.add_field_method_get("status", |_, me| Ok(Status::new(me.inner.status)));
|
||||
fields.add_field_method_get("stdout", |lua, me| lua.create_string(&me.inner.stdout));
|
||||
fields.add_field_method_get("stderr", |lua, me| lua.create_string(&me.inner.stderr));
|
||||
cached_field!(fields, status, |_, me: &Self| Ok(Status::new(me.inner.status)));
|
||||
cached_field!(fields, stdout, |lua: &Lua, me: &Self| lua.create_string(&me.inner.stdout));
|
||||
cached_field!(fields, stderr, |lua: &Lua, me: &Self| lua.create_string(&me.inner.stderr));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
use mlua::Lua;
|
||||
|
||||
yazi_macro::mod_flat!(url);
|
||||
|
||||
pub fn pour(lua: &Lua) -> mlua::Result<()> {
|
||||
url::Url::register(lua)?;
|
||||
url::Url::install(lua)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
use mlua::{AnyUserData, ExternalError, FromLua, IntoLua, Lua, MetaMethod, UserDataFields, UserDataMethods, UserDataRef, Value};
|
||||
|
||||
pub type UrlRef = UserDataRef<yazi_shared::url::Url>;
|
||||
|
||||
pub struct Url(pub yazi_shared::url::Url);
|
||||
|
||||
impl Url {
|
||||
pub fn register(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.register_userdata_type::<yazi_shared::url::Url>(|reg| {
|
||||
reg.add_method("frag", |lua, me, ()| lua.create_string(me.frag()));
|
||||
reg.add_field_method_get("base", |_, me| {
|
||||
Ok(if me.base().as_os_str().is_empty() { None } else { Some(Self::from(me.base())) })
|
||||
});
|
||||
reg.add_field_method_get("is_regular", |_, me| Ok(me.is_regular()));
|
||||
reg.add_field_method_get("is_search", |_, me| Ok(me.is_search()));
|
||||
reg.add_field_method_get("is_archive", |_, me| Ok(me.is_archive()));
|
||||
reg.add_field_method_get("is_absolute", |_, me| Ok(me.is_absolute()));
|
||||
reg.add_field_method_get("has_root", |_, me| Ok(me.has_root()));
|
||||
|
||||
reg.add_method("name", |lua, me, ()| {
|
||||
Some(me.name())
|
||||
.filter(|&s| !s.is_empty())
|
||||
.map(|s| lua.create_string(s.as_encoded_bytes()))
|
||||
.transpose()
|
||||
});
|
||||
reg.add_method("stem", |lua, me, ()| {
|
||||
me.file_stem().map(|s| lua.create_string(s.as_encoded_bytes())).transpose()
|
||||
});
|
||||
reg.add_method("ext", |lua, me, ()| {
|
||||
me.extension().map(|s| lua.create_string(s.as_encoded_bytes())).transpose()
|
||||
});
|
||||
reg.add_method("join", |_, me, other: Value| {
|
||||
Ok(Self(match other {
|
||||
Value::String(s) => me.join(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => me.join(&*ud.borrow::<yazi_shared::url::Url>()?),
|
||||
_ => Err("must be a string or a Url".into_lua_err())?,
|
||||
}))
|
||||
});
|
||||
reg.add_method("parent", |_, me, ()| Ok(me.parent_url().map(Self)));
|
||||
reg.add_method("starts_with", |_, me, base: Value| {
|
||||
Ok(match base {
|
||||
Value::String(s) => me.starts_with(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => me.starts_with(&*ud.borrow::<yazi_shared::url::Url>()?),
|
||||
_ => Err("must be a string or a Url".into_lua_err())?,
|
||||
})
|
||||
});
|
||||
reg.add_method("ends_with", |_, me, child: Value| {
|
||||
Ok(match child {
|
||||
Value::String(s) => me.ends_with(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => me.ends_with(&*ud.borrow::<yazi_shared::url::Url>()?),
|
||||
_ => Err("must be a string or a Url".into_lua_err())?,
|
||||
})
|
||||
});
|
||||
reg.add_method("strip_prefix", |_, me, base: Value| {
|
||||
let path = match base {
|
||||
Value::String(s) => me.strip_prefix(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => me.strip_prefix(&*ud.borrow::<yazi_shared::url::Url>()?),
|
||||
_ => Err("must be a string or a Url".into_lua_err())?,
|
||||
};
|
||||
Ok(path.ok().map(Self::from))
|
||||
});
|
||||
|
||||
reg.add_function_mut("into_search", |_, (ud, frag): (AnyUserData, mlua::String)| {
|
||||
Ok(Self(ud.take::<yazi_shared::url::Url>()?.into_search(&frag.to_str()?)))
|
||||
});
|
||||
|
||||
reg.add_meta_method(MetaMethod::Eq, |_, me, other: UrlRef| Ok(me == &*other));
|
||||
reg.add_meta_method(MetaMethod::ToString, |lua, me, ()| {
|
||||
lua.create_string(me.as_os_str().as_encoded_bytes())
|
||||
});
|
||||
reg.add_meta_method(MetaMethod::Concat, |lua, lhs, rhs: mlua::String| {
|
||||
lua.create_string([lhs.as_os_str().as_encoded_bytes(), rhs.as_bytes().as_ref()].concat())
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
pub fn install(lua: &Lua) -> mlua::Result<()> {
|
||||
lua.globals().raw_set(
|
||||
"Url",
|
||||
lua.create_function(|_, value: Value| {
|
||||
Ok(match value {
|
||||
Value::String(s) => Self::from(s.to_str()?.as_ref()),
|
||||
Value::UserData(ud) => Self(ud.borrow::<yazi_shared::url::Url>()?.clone()),
|
||||
_ => Err("Expected a string or a Url".into_lua_err())?,
|
||||
})
|
||||
})?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<yazi_shared::url::Url>> From<T> for Url {
|
||||
fn from(value: T) -> Self { Self(value.into()) }
|
||||
}
|
||||
|
||||
impl FromLua for Url {
|
||||
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
|
||||
match value {
|
||||
Value::UserData(ud) => ud.take().map(Self),
|
||||
_ => Err("Expected a Url".into_lua_err()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoLua for Url {
|
||||
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
|
||||
lua.create_any_userdata(self.0)?.into_lua(lua)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
use mlua::{Function, Lua, Table};
|
||||
use twox_hash::XxHash3_128;
|
||||
use yazi_binding::Url;
|
||||
use yazi_config::YAZI;
|
||||
|
||||
use super::Utils;
|
||||
use crate::{file::FileRef, url::Url};
|
||||
use crate::file::FileRef;
|
||||
|
||||
impl Utils {
|
||||
pub(super) fn file_cache(lua: &Lua) -> mlua::Result<Function> {
|
||||
|
|
@ -20,7 +21,7 @@ impl Utils {
|
|||
format!("{:x}", h.finish_128())
|
||||
};
|
||||
|
||||
Ok(Some(Url::from(YAZI.preview.cache_dir.join(hex))))
|
||||
Ok(Some(Url::new(YAZI.preview.cache_dir.join(hex))))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use mlua::{Function, IntoLua, Lua, Value};
|
||||
use yazi_adapter::{ADAPTOR, Image};
|
||||
use yazi_binding::UrlRef;
|
||||
|
||||
use super::Utils;
|
||||
use crate::{bindings::ImageInfo, elements::Rect, url::UrlRef};
|
||||
use crate::{bindings::ImageInfo, elements::Rect};
|
||||
|
||||
impl Utils {
|
||||
pub(super) fn image_info(lua: &Lua) -> mlua::Result<Function> {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use mlua::{Function, IntoLuaMulti, Lua, LuaSerdeExt, Value};
|
||||
use yazi_binding::Error;
|
||||
|
||||
use super::Utils;
|
||||
use crate::{Error, config::OPTS};
|
||||
use crate::config::OPTS;
|
||||
|
||||
impl Utils {
|
||||
pub(super) fn json_encode(lua: &Lua) -> mlua::Result<Function> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-proxy"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -13,9 +13,9 @@ default = [ "vendored-lua" ]
|
|||
vendored-lua = [ "mlua/vendored" ]
|
||||
|
||||
[dependencies]
|
||||
yazi-config = { path = "../yazi-config", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-scheduler"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -9,13 +9,13 @@ homepage = "https://yazi-rs.github.io"
|
|||
repository = "https://github.com/sxyazi/yazi"
|
||||
|
||||
[dependencies]
|
||||
yazi-config = { path = "../yazi-config", version = "25.3.7" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.3.7" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.3.7" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.4.4" }
|
||||
yazi-dds = { path = "../yazi-dds", version = "25.4.4" }
|
||||
yazi-fs = { path = "../yazi-fs", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.4.4" }
|
||||
yazi-proxy = { path = "../yazi-proxy", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-shared"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -10,7 +10,7 @@ repository = "https://github.com/sxyazi/yazi"
|
|||
rust-version = "1.83.0"
|
||||
|
||||
[dependencies]
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "yazi-widgets"
|
||||
version = "25.3.7"
|
||||
version = "25.4.4"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = [ "sxyazi <sxyazi@gmail.com>" ]
|
||||
|
|
@ -10,11 +10,11 @@ repository = "https://github.com/sxyazi/yazi"
|
|||
rust-version = "1.83.0"
|
||||
|
||||
[dependencies]
|
||||
yazi-codegen = { path = "../yazi-codegen", version = "25.3.7" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.3.7" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.3.7" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.3.7" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.3.7" }
|
||||
yazi-codegen = { path = "../yazi-codegen", version = "25.4.4" }
|
||||
yazi-config = { path = "../yazi-config", version = "25.4.4" }
|
||||
yazi-macro = { path = "../yazi-macro", version = "25.4.4" }
|
||||
yazi-plugin = { path = "../yazi-plugin", version = "25.4.4" }
|
||||
yazi-shared = { path = "../yazi-shared", version = "25.4.4" }
|
||||
|
||||
# External dependencies
|
||||
futures = { workspace = true }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue