diff --git a/Cargo.lock b/Cargo.lock index becc77037..45687e29a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -117,15 +117,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arbitrary" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775a8770d29db3dadcb858482cc240af7b2ffde4ac4de67d1d4955728103f0e2" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" [[package]] name = "arg_enum_proc_macro" @@ -327,9 +327,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.35" +version = "1.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57c4b4da2a9d619dd035f27316d7a426305b75be93d09e92f2b9229c34feaf" +checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70" dependencies = [ "jobserver", "libc", @@ -1392,19 +1392,18 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.161" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libfuzzer-sys" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" dependencies = [ "arbitrary", "cc", - "once_cell", ] [[package]] @@ -1539,17 +1538,18 @@ dependencies = [ [[package]] name = "mlua" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7" +version = "0.10.0" +source = "git+https://github.com/mlua-rs/mlua.git#c7094d470ff377775ba267ea78650d095db9b017" dependencies = [ + "anyhow", "bstr", + "either", "erased-serde", "futures-util", "mlua-sys", "mlua_derive", "num-traits", - "once_cell", + "parking_lot", "rustc-hash", "serde", "serde-value", @@ -1558,8 +1558,7 @@ dependencies = [ [[package]] name = "mlua-sys" version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9eebac25c35a13285456c88ee2fde93d9aee8bcfdaf03f9d6d12be3391351ec" +source = "git+https://github.com/mlua-rs/mlua.git#c7094d470ff377775ba267ea78650d095db9b017" dependencies = [ "cc", "cfg-if", @@ -1570,11 +1569,10 @@ dependencies = [ [[package]] name = "mlua_derive" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09697a6cec88e7f58a02c7ab5c18c611c6907c8654613df9cc0192658a4fb859" +version = "0.10.0" +source = "git+https://github.com/mlua-rs/mlua.git#c7094d470ff377775ba267ea78650d095db9b017" dependencies = [ - "itertools 0.12.1", + "itertools 0.13.0", "once_cell", "proc-macro-error", "proc-macro2", @@ -2591,9 +2589,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.41.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 8076c5237..343920de3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ strip = true [workspace.dependencies] ansi-to-tui = "7.0.0" -anyhow = "1.0.92" +anyhow = "1.0.93" base64 = "0.22.1" bitflags = "2.6.0" clap = { version = "4.5.20", features = [ "derive" ] } @@ -19,9 +19,9 @@ crossterm = { version = "0.28.1", features = [ "event-stream" ] } dirs = "5.0.1" futures = "0.3.31" globset = "0.4.15" -libc = "0.2.161" +libc = "0.2.162" md-5 = "0.10.6" -mlua = { version = "0.9.9", features = [ "lua54", "serialize", "macros", "async" ] } +mlua = { git = "https://github.com/mlua-rs/mlua.git", features = [ "anyhow", "async", "error-send", "lua54", "macros", "serialize" ] } parking_lot = "0.12.3" ratatui = { version = "0.29.0", features = [ "unstable-rendered-line-info" ] } regex = "1.11.1" @@ -29,7 +29,7 @@ scopeguard = "1.2.0" serde = { version = "1.0.214", features = [ "derive" ] } serde_json = "1.0.132" shell-words = "1.1.0" -tokio = { version = "1.41.0", features = [ "full" ] } +tokio = { version = "1.41.1", features = [ "full" ] } tokio-stream = "0.1.16" tokio-util = "0.7.12" tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] } diff --git a/yazi-dds/src/body/body.rs b/yazi-dds/src/body/body.rs index 7fd6fb1eb..a8ea4da5e 100644 --- a/yazi-dds/src/body/body.rs +++ b/yazi-dds/src/body/body.rs @@ -107,7 +107,7 @@ impl<'a> Body<'a> { pub fn with_sender(self, sender: u64) -> Payload<'a> { Payload::new(self).with_sender(sender) } } -impl IntoLua<'_> for Body<'static> { +impl IntoLua for Body<'static> { fn into_lua(self, lua: &Lua) -> mlua::Result { match self { Self::Hi(b) => b.into_lua(lua), diff --git a/yazi-dds/src/body/bulk.rs b/yazi-dds/src/body/bulk.rs index cd9f33ddf..3f17fb14c 100644 --- a/yazi-dds/src/body/bulk.rs +++ b/yazi-dds/src/body/bulk.rs @@ -36,7 +36,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyBulk<'a>) -> Self { Self::Bulk(value) } } -impl IntoLua<'_> for BodyBulk<'static> { +impl IntoLua for BodyBulk<'static> { fn into_lua(self, lua: &Lua) -> mlua::Result { BodyBulkIter { inner: self.changes.into_iter() }.into_lua(lua) } @@ -48,7 +48,7 @@ pub struct BodyBulkIter { } impl UserData for BodyBulkIter { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.inner.len())); methods.add_meta_function(MetaMethod::Pairs, |lua, me: AnyUserData| { diff --git a/yazi-dds/src/body/bye.rs b/yazi-dds/src/body/bye.rs index 256bd1d93..137a298a6 100644 --- a/yazi-dds/src/body/bye.rs +++ b/yazi-dds/src/body/bye.rs @@ -15,8 +15,8 @@ impl<'a> From for Body<'a> { fn from(value: BodyBye) -> Self { Self::Bye(value) } } -impl IntoLua<'_> for BodyBye { - fn into_lua(self, _: &Lua) -> mlua::Result> { +impl IntoLua for BodyBye { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("BodyBye cannot be converted to Lua").into_lua_err() } } diff --git a/yazi-dds/src/body/cd.rs b/yazi-dds/src/body/cd.rs index c6711c75f..f0bc9095e 100644 --- a/yazi-dds/src/body/cd.rs +++ b/yazi-dds/src/body/cd.rs @@ -32,7 +32,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyCd<'a>) -> Self { Self::Cd(value) } } -impl IntoLua<'_> for BodyCd<'static> { +impl IntoLua for BodyCd<'static> { fn into_lua(self, lua: &Lua) -> mlua::Result { if let Some(Cow::Owned(url)) = Some(self.url).filter(|_| !self.dummy) { lua.create_table_from([ diff --git a/yazi-dds/src/body/custom.rs b/yazi-dds/src/body/custom.rs index 3ef50058d..1d6b131cc 100644 --- a/yazi-dds/src/body/custom.rs +++ b/yazi-dds/src/body/custom.rs @@ -27,7 +27,7 @@ impl From for Body<'_> { fn from(value: BodyCustom) -> Self { Self::Custom(value) } } -impl IntoLua<'_> for BodyCustom { +impl IntoLua for BodyCustom { fn into_lua(self, lua: &Lua) -> mlua::Result { Sendable::data_to_value(lua, self.data) } } diff --git a/yazi-dds/src/body/delete.rs b/yazi-dds/src/body/delete.rs index 41ae524d4..002ffe47e 100644 --- a/yazi-dds/src/body/delete.rs +++ b/yazi-dds/src/body/delete.rs @@ -25,8 +25,8 @@ impl<'a> From> for Body<'a> { fn from(value: BodyDelete<'a>) -> Self { Self::Delete(value) } } -impl IntoLua<'_> for BodyDelete<'static> { - fn into_lua(self, lua: &Lua) -> mlua::Result> { +impl IntoLua for BodyDelete<'static> { + fn into_lua(self, lua: &Lua) -> mlua::Result { let urls = lua.create_table_with_capacity(self.urls.len(), 0)?; // In most cases, `self.urls` will be `Cow::Owned`, so diff --git a/yazi-dds/src/body/hey.rs b/yazi-dds/src/body/hey.rs index 58d8cf93a..fa1de98be 100644 --- a/yazi-dds/src/body/hey.rs +++ b/yazi-dds/src/body/hey.rs @@ -23,8 +23,8 @@ impl From for Body<'_> { fn from(value: BodyHey) -> Self { Self::Hey(value) } } -impl IntoLua<'_> for BodyHey { - fn into_lua(self, _: &Lua) -> mlua::Result> { +impl IntoLua for BodyHey { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("BodyHey cannot be converted to Lua").into_lua_err() } } diff --git a/yazi-dds/src/body/hi.rs b/yazi-dds/src/body/hi.rs index c80e6f119..ff38b7538 100644 --- a/yazi-dds/src/body/hi.rs +++ b/yazi-dds/src/body/hi.rs @@ -31,8 +31,8 @@ impl<'a> From> for Body<'a> { fn from(value: BodyHi<'a>) -> Self { Self::Hi(value) } } -impl IntoLua<'_> for BodyHi<'_> { - fn into_lua(self, _: &Lua) -> mlua::Result> { +impl IntoLua for BodyHi<'_> { + fn into_lua(self, _: &Lua) -> mlua::Result { Err("BodyHi cannot be converted to Lua").into_lua_err() } } diff --git a/yazi-dds/src/body/hover.rs b/yazi-dds/src/body/hover.rs index 893ca699d..3ec674350 100644 --- a/yazi-dds/src/body/hover.rs +++ b/yazi-dds/src/body/hover.rs @@ -28,7 +28,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyHover<'a>) -> Self { Self::Hover(value) } } -impl IntoLua<'_> for BodyHover<'static> { +impl IntoLua for BodyHover<'static> { fn into_lua(self, lua: &Lua) -> mlua::Result { if let Some(Cow::Owned(url)) = self.url { lua.create_table_from([ diff --git a/yazi-dds/src/body/move_.rs b/yazi-dds/src/body/move_.rs index 26aea7afe..5721f058a 100644 --- a/yazi-dds/src/body/move_.rs +++ b/yazi-dds/src/body/move_.rs @@ -29,7 +29,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyMove<'a>) -> Self { Self::Move(value) } } -impl IntoLua<'_> for BodyMove<'static> { +impl IntoLua for BodyMove<'static> { fn into_lua(self, lua: &Lua) -> mlua::Result { lua.create_table_from([("items", self.items.into_owned())])?.into_lua(lua) } @@ -42,7 +42,7 @@ pub struct BodyMoveItem { pub to: Url, } -impl IntoLua<'_> for BodyMoveItem { +impl IntoLua for BodyMoveItem { fn into_lua(self, lua: &Lua) -> mlua::Result { lua .create_table_from([ diff --git a/yazi-dds/src/body/rename.rs b/yazi-dds/src/body/rename.rs index 55dd68abe..c19c7f3a4 100644 --- a/yazi-dds/src/body/rename.rs +++ b/yazi-dds/src/body/rename.rs @@ -31,7 +31,7 @@ impl<'a> From> for Body<'a> { fn from(value: BodyRename<'a>) -> Self { Self::Rename(value) } } -impl IntoLua<'_> for BodyRename<'static> { +impl IntoLua for BodyRename<'static> { fn into_lua(self, lua: &Lua) -> mlua::Result { lua .create_table_from([ diff --git a/yazi-dds/src/body/tab.rs b/yazi-dds/src/body/tab.rs index 0a2020ede..6ca5ed599 100644 --- a/yazi-dds/src/body/tab.rs +++ b/yazi-dds/src/body/tab.rs @@ -17,7 +17,7 @@ impl<'a> From for Body<'a> { fn from(value: BodyTab) -> Self { Self::Tab(value) } } -impl IntoLua<'_> for BodyTab { +impl IntoLua for BodyTab { fn into_lua(self, lua: &Lua) -> mlua::Result { lua.create_table_from([("idx", self.idx)])?.into_lua(lua) } diff --git a/yazi-dds/src/body/trash.rs b/yazi-dds/src/body/trash.rs index cac54fd98..02e1cea51 100644 --- a/yazi-dds/src/body/trash.rs +++ b/yazi-dds/src/body/trash.rs @@ -25,8 +25,8 @@ impl<'a> From> for Body<'a> { fn from(value: BodyTrash<'a>) -> Self { Self::Trash(value) } } -impl IntoLua<'_> for BodyTrash<'static> { - fn into_lua(self, lua: &Lua) -> mlua::Result> { +impl IntoLua for BodyTrash<'static> { + fn into_lua(self, lua: &Lua) -> mlua::Result { let urls = lua.create_table_with_capacity(self.urls.len(), 0)?; // In most cases, `self.urls` will be `Cow::Owned`, so diff --git a/yazi-dds/src/body/yank.rs b/yazi-dds/src/body/yank.rs index 708b4ff10..a5cb99524 100644 --- a/yazi-dds/src/body/yank.rs +++ b/yazi-dds/src/body/yank.rs @@ -32,8 +32,8 @@ impl<'a> From> for Body<'a> { fn from(value: BodyYank<'a>) -> Self { Self::Yank(value) } } -impl IntoLua<'_> for BodyYank<'static> { - fn into_lua(self, lua: &Lua) -> mlua::Result> { +impl IntoLua for BodyYank<'static> { + fn into_lua(self, lua: &Lua) -> mlua::Result { if let Some(Cow::Owned(urls)) = Some(self.urls).filter(|_| !self.dummy) { BodyYankIter { cut: self.cut, urls: urls.into_iter().collect() }.into_lua(lua) } else { @@ -49,11 +49,11 @@ pub struct BodyYankIter { } impl UserData for BodyYankIter { - fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { + fn add_fields>(fields: &mut F) { fields.add_field_method_get("cut", |_, me| Ok(me.cut)); } - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.urls.len())); methods.add_meta_method(MetaMethod::Index, |lua, me, idx: usize| { diff --git a/yazi-dds/src/pubsub.rs b/yazi-dds/src/pubsub.rs index 0be6b36d8..807294e54 100644 --- a/yazi-dds/src/pubsub.rs +++ b/yazi-dds/src/pubsub.rs @@ -7,15 +7,13 @@ use yazi_shared::{Id, RoCell, fs::Url}; use crate::{Client, ID, PEERS, body::{Body, BodyBulk, BodyCd, BodyDelete, BodyHi, BodyHover, BodyMove, BodyMoveItem, BodyRename, BodyTab, BodyTrash, BodyYank}}; -pub static LOCAL: RoCell>>>> = - RoCell::new(); +pub static LOCAL: RoCell>>> = RoCell::new(); -pub static REMOTE: RoCell>>>> = - RoCell::new(); +pub static REMOTE: RoCell>>> = RoCell::new(); macro_rules! sub { ($var:ident) => { - |plugin: &str, kind: &str, f: Function<'static>| { + |plugin: &str, kind: &str, f: Function| { let mut var = $var.write(); let Some(map) = var.get_mut(kind) else { var.insert(kind.to_owned(), HashMap::from_iter([(plugin.to_owned(), f)])); @@ -51,11 +49,9 @@ macro_rules! unsub { pub struct Pubsub; impl Pubsub { - pub fn sub(plugin: &str, kind: &str, f: Function<'static>) -> bool { - sub!(LOCAL)(plugin, kind, f) - } + pub fn sub(plugin: &str, kind: &str, f: Function) -> bool { sub!(LOCAL)(plugin, kind, f) } - pub fn sub_remote(plugin: &str, kind: &str, f: Function<'static>) -> bool { + pub fn sub_remote(plugin: &str, kind: &str, f: Function) -> bool { sub!(REMOTE)(plugin, kind, f) && Self::pub_from_hi() } diff --git a/yazi-dds/src/sendable.rs b/yazi-dds/src/sendable.rs index 0a0335e7f..841d502f9 100644 --- a/yazi-dds/src/sendable.rs +++ b/yazi-dds/src/sendable.rs @@ -44,6 +44,7 @@ impl Sendable { } } Value::Error(_) => Err("error is not supported".into_lua_err())?, + Value::Other(..) => Err("unknown data is not supported".into_lua_err())?, }) } @@ -117,6 +118,7 @@ impl Sendable { } } Value::Error(_) => Err("error is not supported".into_lua_err())?, + Value::Other(..) => Err("unknown data is not supported".into_lua_err())?, }) } diff --git a/yazi-fm/src/app/commands/accept_payload.rs b/yazi-fm/src/app/commands/accept_payload.rs index 4f88f167b..df3dcaa83 100644 --- a/yazi-fm/src/app/commands/accept_payload.rs +++ b/yazi-fm/src/app/commands/accept_payload.rs @@ -23,10 +23,10 @@ impl App { return; }; - _ = Lives::scope(&self.cx, |_| { + _ = Lives::scope(&self.cx, || { let body = payload.body.into_lua(&LUA)?; for f in map.values() { - if let Err(e) = f.call::<_, ()>(body.clone()) { + if let Err(e) = f.call::<()>(body.clone()) { error!("Failed to call `{kind}` handler: {e}"); } } diff --git a/yazi-fm/src/app/commands/mouse.rs b/yazi-fm/src/app/commands/mouse.rs index 11f65fbfc..2e1b3a5c7 100644 --- a/yazi-fm/src/app/commands/mouse.rs +++ b/yazi-fm/src/app/commands/mouse.rs @@ -1,5 +1,5 @@ use crossterm::event::{MouseEvent, MouseEventKind}; -use mlua::{Table, TableExt}; +use mlua::{ObjectLike, Table}; use tracing::error; use yazi_config::MANAGER; use yazi_plugin::{LUA, bindings::Cast}; @@ -21,9 +21,9 @@ impl App { let Some(size) = self.term.as_ref().and_then(|t| t.size().ok()) else { return }; let Ok(evt) = yazi_plugin::bindings::MouseEvent::cast(&LUA, event) else { return }; - let res = Lives::scope(&self.cx, move |_| { + let res = Lives::scope(&self.cx, move || { let area = yazi_plugin::elements::Rect::from(size); - let root = LUA.globals().raw_get::<_, Table>("Root")?.call_method::<_, Table>("new", area)?; + let root = LUA.globals().raw_get::("Root")?.call_method::
("new", area)?; if matches!(event.kind, MouseEventKind::Down(_) if MANAGER.mouse_events.draggable()) { root.raw_set("_drag_start", evt.clone())?; diff --git a/yazi-fm/src/app/commands/plugin.rs b/yazi-fm/src/app/commands/plugin.rs index a1b93d5bb..c924b6f2d 100644 --- a/yazi-fm/src/app/commands/plugin.rs +++ b/yazi-fm/src/app/commands/plugin.rs @@ -1,6 +1,6 @@ use std::fmt::Display; -use mlua::TableExt; +use mlua::ObjectLike; use scopeguard::defer; use tracing::warn; use yazi_dds::Sendable; @@ -62,7 +62,7 @@ impl App { }; drop(loader); - _ = Lives::scope(&self.cx, |_| { + _ = Lives::scope(&self.cx, || { if let Some(cb) = opt.cb { cb(&LUA, plugin) } else { diff --git a/yazi-fm/src/app/commands/reflow.rs b/yazi-fm/src/app/commands/reflow.rs index 20451fd6d..c6d9a30db 100644 --- a/yazi-fm/src/app/commands/reflow.rs +++ b/yazi-fm/src/app/commands/reflow.rs @@ -23,7 +23,7 @@ impl App { let Some(size) = self.term.as_ref().and_then(|t| t.size().ok()) else { return }; let mut layout = LAYOUT.get(); - let result = Lives::scope(&self.cx, |_| { + let result = Lives::scope(&self.cx, || { let comps = Root::reflow((Position::ORIGIN, size).into())?; for v in comps.sequence_values::() { @@ -33,10 +33,10 @@ impl App { }; let id: mlua::String = t.get("_id")?; - match id.to_str()? { - "current" => layout.current = *t.raw_get::<_, yazi_plugin::elements::Rect>("_area")?, - "preview" => layout.preview = *t.raw_get::<_, yazi_plugin::elements::Rect>("_area")?, - "progress" => layout.progress = *t.raw_get::<_, yazi_plugin::elements::Rect>("_area")?, + match id.to_str()?.as_ref() { + "current" => layout.current = *t.raw_get::("_area")?, + "preview" => layout.preview = *t.raw_get::("_area")?, + "progress" => layout.progress = *t.raw_get::("_area")?, _ => {} } } diff --git a/yazi-fm/src/app/commands/render.rs b/yazi-fm/src/app/commands/render.rs index 123e146a4..597abf7a6 100644 --- a/yazi-fm/src/app/commands/render.rs +++ b/yazi-fm/src/app/commands/render.rs @@ -19,7 +19,7 @@ impl App { let collision = COLLISION.swap(false, Ordering::Relaxed); let frame = term .draw(|f| { - _ = Lives::scope(&self.cx, |_| Ok(f.render_widget(Root::new(&self.cx), f.area()))); + _ = Lives::scope(&self.cx, || Ok(f.render_widget(Root::new(&self.cx), f.area()))); if let Some(pos) = self.cx.cursor() { f.set_cursor_position(pos); @@ -48,7 +48,7 @@ impl App { let frame = term .draw_partial(|f| { - _ = Lives::scope(&self.cx, |_| { + _ = Lives::scope(&self.cx, || { f.render_widget(crate::tasks::Progress, f.area()); f.render_widget(crate::notify::Notify::new(&self.cx), f.area()); Ok(()) diff --git a/yazi-fm/src/lives/config.rs b/yazi-fm/src/lives/config.rs index aa2f598be..6761ddf11 100644 --- a/yazi-fm/src/lives/config.rs +++ b/yazi-fm/src/lives/config.rs @@ -1,8 +1,8 @@ use std::ops::Deref; -use mlua::{AnyUserData, Lua, UserDataFields}; +use mlua::{AnyUserData, UserData, UserDataFields}; -use super::SCOPE; +use super::Lives; pub(super) struct Config { inner: *const yazi_core::tab::Config, @@ -16,20 +16,20 @@ impl Deref for Config { impl Config { #[inline] - pub(super) fn make(inner: &yazi_core::tab::Config) -> mlua::Result> { - SCOPE.create_any_userdata(Self { inner }) + pub(super) fn make(inner: &yazi_core::tab::Config) -> mlua::Result { + Lives::scoped_userdata(Self { inner }) } +} + +impl UserData for Config { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("sort_by", |_, me| 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)); - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("sort_by", |_, me| Ok(me.sort_by.to_string())); - reg.add_field_method_get("sort_sensitive", |_, me| Ok(me.sort_sensitive)); - reg.add_field_method_get("sort_reverse", |_, me| Ok(me.sort_reverse)); - reg.add_field_method_get("sort_dir_first", |_, me| Ok(me.sort_dir_first)); - reg.add_field_method_get("sort_translit", |_, me| Ok(me.sort_translit)); - - reg.add_field_method_get("linemode", |_, me| Ok(me.linemode.to_owned())); - reg.add_field_method_get("show_hidden", |_, me| Ok(me.show_hidden)); - }) + fields.add_field_method_get("linemode", |_, me| Ok(me.linemode.to_owned())); + fields.add_field_method_get("show_hidden", |_, me| Ok(me.show_hidden)); } } diff --git a/yazi-fm/src/lives/file.rs b/yazi-fm/src/lives/file.rs index a0e287765..fa062da74 100644 --- a/yazi-fm/src/lives/file.rs +++ b/yazi-fm/src/lives/file.rs @@ -1,11 +1,12 @@ use std::ops::Deref; -use mlua::{AnyUserData, IntoLua, Lua, UserDataFields, UserDataMethods}; +use mlua::{AnyUserData, IntoLua, UserData, UserDataFields, UserDataMethods}; use yazi_config::THEME; use yazi_plugin::{bindings::Range, elements::Style}; use yazi_shared::MIME_DIR; -use super::{CtxRef, SCOPE}; +use super::Lives; +use crate::Ctx; pub(super) struct File { idx: usize, @@ -29,71 +30,86 @@ impl File { idx: usize, folder: &yazi_fs::Folder, tab: &yazi_core::tab::Tab, - ) -> mlua::Result> { - SCOPE.create_any_userdata(Self { idx, folder, tab }) + ) -> mlua::Result { + Lives::scoped_userdata(Self { idx, folder, tab }) } - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - yazi_plugin::file::File::register_with(reg); - - reg.add_field_method_get("idx", |_, me| Ok(me.idx + 1)); - reg.add_method("size", |_, me, ()| { - Ok(if me.is_dir() { me.folder().files.sizes.get(me.urn()).copied() } else { Some(me.len) }) - }); - reg.add_method("mime", |lua, me, ()| { - let cx = lua.named_registry_value::("cx")?; - Ok(cx.manager.mimetype.get_owned(&me.url)) - }); - reg.add_method("prefix", |lua, me, ()| { - if !me.folder().url.is_search() { - return Ok(None); - } + #[inline] + fn folder(&self) -> &yazi_fs::Folder { unsafe { &*self.folder } } + + #[inline] + fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } } +} + +impl UserData for File { + fn add_fields>(fields: &mut F) { + yazi_plugin::impl_file_fields!(fields); - 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() - }); - reg.add_method("style", |lua, me, ()| { - let cx = lua.named_registry_value::("cx")?; + fields.add_field_method_get("idx", |_, me| Ok(me.idx + 1)); + } + + fn add_methods>(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) }) + }); + methods.add_method("mime", |lua, me, ()| { + lua + .named_registry_value::("cx")? + .borrow_scoped(|cx: &Ctx| cx.manager.mimetype.get_owned(&me.url)) + }); + methods.add_method("prefix", |lua, me, ()| { + if !me.folder().url.is_search() { + return Ok(None); + } + + 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() + }); + methods.add_method("style", |lua, me, ()| { + lua.named_registry_value::("cx")?.borrow_scoped(|cx: &Ctx| { let mime = if me.is_dir() { MIME_DIR } else { cx.manager.mimetype.get(&me.url).unwrap_or_default() }; - Ok(THEME.filetypes.iter().find(|&x| x.matches(me, mime)).map(|x| Style::from(x.style))) - }); - reg.add_method("is_hovered", |_, me, ()| Ok(me.idx == me.folder().cursor)); - reg.add_method("is_yanked", |lua, me, ()| { - let cx = lua.named_registry_value::("cx")?; - Ok(if !cx.manager.yanked.contains(&me.url) { + THEME.filetypes.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::("cx")?.borrow_scoped(|cx: &Ctx| { + if !cx.manager.yanked.contains(&me.url) { 0u8 } else if cx.manager.yanked.cut { 2u8 } else { 1u8 - }) - }); - reg.add_method("is_marked", |_, me, ()| { - use yazi_core::tab::Mode::*; - if !me.tab().mode.is_visual() || me.folder().url != me.tab().current.url { - return Ok(0u8); } - - Ok(match &me.tab().mode { - Select(_, indices) if indices.contains(&me.idx) => 1u8, - Unset(_, indices) if indices.contains(&me.idx) => 2u8, - _ => 0u8, - }) - }); - reg.add_method("is_selected", |_, me, ()| Ok(me.tab().selected.contains_key(&me.url))); - reg.add_method("in_parent", |_, me, ()| { - Ok(me.tab().parent.as_ref().is_some_and(|f| me.folder().url == f.url)) - }); - reg.add_method("in_current", |_, me, ()| Ok(me.folder().url == me.tab().current.url)); - reg.add_method("in_preview", |_, me, ()| { - Ok(me.tab().hovered().is_some_and(|f| f.url == me.folder().url)) - }); - reg.add_method("found", |lua, me, ()| { - let cx = lua.named_registry_value::("cx")?; + }) + }); + methods.add_method("is_marked", |_, me, ()| { + use yazi_core::tab::Mode::*; + if !me.tab().mode.is_visual() || me.folder().url != me.tab().current.url { + return Ok(0u8); + } + + 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("found", |lua, me, ()| { + lua.named_registry_value::("cx")?.borrow_scoped(|cx: &Ctx| { let Some(finder) = &cx.manager.active().finder else { return Ok(None); }; @@ -104,29 +120,20 @@ impl File { Some(lua.create_sequence_from([idx.into_lua(lua)?, finder.matched().len().into_lua(lua)?])) .transpose() - }); - reg.add_method("highlights", |lua, me, ()| { - let cx = lua.named_registry_value::("cx")?; + }) + }); + methods.add_method("highlights", |lua, me, ()| { + lua.named_registry_value::("cx")?.borrow_scoped(|cx: &Ctx| { let Some(finder) = &cx.manager.active().finder else { - return Ok(None); + return None; }; if me.folder().url != me.tab().current.url { - return Ok(None); + return None; } - let Some(h) = finder.filter.highlighted(me.name()) else { - return Ok(None); - }; - - Ok(Some(h.into_iter().map(Range::from).collect::>())) - }); - })?; - Ok(()) + let h = finder.filter.highlighted(me.name())?; + Some(h.into_iter().map(Range::from).collect::>()) + }) + }); } - - #[inline] - fn folder(&self) -> &yazi_fs::Folder { unsafe { &*self.folder } } - - #[inline] - fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } } } diff --git a/yazi-fm/src/lives/files.rs b/yazi-fm/src/lives/files.rs index bb19233c0..af747a1d1 100644 --- a/yazi-fm/src/lives/files.rs +++ b/yazi-fm/src/lives/files.rs @@ -1,8 +1,8 @@ use std::ops::{Deref, Range}; -use mlua::{AnyUserData, Lua, MetaMethod, UserDataFields, UserDataMethods}; +use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods}; -use super::{File, Filter, SCOPE}; +use super::{File, Filter, Lives}; pub(super) struct Files { window: Range, @@ -22,27 +22,8 @@ impl Files { window: Range, folder: &yazi_fs::Folder, tab: &yazi_core::tab::Tab, - ) -> mlua::Result> { - SCOPE.create_any_userdata(Self { window, folder, tab }) - } - - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("filter", |_, me| me.filter().map(Filter::make).transpose()); - - reg.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.window.end - me.window.start)); - - reg.add_meta_method(MetaMethod::Index, |_, me, mut idx: usize| { - idx += me.window.start; - if idx > me.window.end || idx == 0 { - Ok(None) - } else { - Some(File::make(idx - 1, me.folder(), me.tab())).transpose() - } - }); - })?; - - Ok(()) + ) -> mlua::Result { + Lives::scoped_userdata(Self { window, folder, tab }) } #[inline] @@ -51,3 +32,22 @@ impl Files { #[inline] fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } } } + +impl UserData for Files { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("filter", |_, me| me.filter().map(Filter::make).transpose()); + } + + fn add_methods>(methods: &mut M) { + methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.window.end - me.window.start)); + + methods.add_meta_method(MetaMethod::Index, |_, me, mut idx: usize| { + idx += me.window.start; + if idx > me.window.end || idx == 0 { + Ok(None) + } else { + Some(File::make(idx - 1, me.folder(), me.tab())).transpose() + } + }); + } +} diff --git a/yazi-fm/src/lives/filter.rs b/yazi-fm/src/lives/filter.rs index c437b5090..4c6a68139 100644 --- a/yazi-fm/src/lives/filter.rs +++ b/yazi-fm/src/lives/filter.rs @@ -1,8 +1,8 @@ use std::ops::Deref; -use mlua::{AnyUserData, Lua, MetaMethod, UserDataMethods}; +use mlua::{AnyUserData, MetaMethod, UserData, UserDataMethods}; -use super::SCOPE; +use super::Lives; pub(super) struct Filter { inner: *const yazi_fs::Filter, @@ -16,13 +16,13 @@ impl Deref for Filter { impl Filter { #[inline] - pub(super) fn make(inner: &yazi_fs::Filter) -> mlua::Result> { - SCOPE.create_any_userdata(Self { inner }) + pub(super) fn make(inner: &yazi_fs::Filter) -> mlua::Result { + Lives::scoped_userdata(Self { inner }) } +} - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.to_string())); - }) +impl UserData for Filter { + fn add_methods>(methods: &mut M) { + methods.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.to_string())); } } diff --git a/yazi-fm/src/lives/finder.rs b/yazi-fm/src/lives/finder.rs index a2e14a1a0..2b53d9cfe 100644 --- a/yazi-fm/src/lives/finder.rs +++ b/yazi-fm/src/lives/finder.rs @@ -1,8 +1,8 @@ use std::ops::Deref; -use mlua::{AnyUserData, Lua, MetaMethod, UserDataMethods}; +use mlua::{AnyUserData, MetaMethod, UserData, UserDataMethods}; -use super::SCOPE; +use super::Lives; pub(super) struct Finder { inner: *const yazi_core::tab::Finder, @@ -16,13 +16,13 @@ impl Deref for Finder { impl Finder { #[inline] - pub(super) fn make(inner: &yazi_core::tab::Finder) -> mlua::Result> { - SCOPE.create_any_userdata(Self { inner }) + pub(super) fn make(inner: &yazi_core::tab::Finder) -> mlua::Result { + Lives::scoped_userdata(Self { inner }) } +} - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.filter.to_string())); - }) +impl UserData for Finder { + fn add_methods>(methods: &mut M) { + methods.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.filter.to_string())); } } diff --git a/yazi-fm/src/lives/folder.rs b/yazi-fm/src/lives/folder.rs index 3a855ba54..3c13ca5c6 100644 --- a/yazi-fm/src/lives/folder.rs +++ b/yazi-fm/src/lives/folder.rs @@ -1,10 +1,10 @@ use std::ops::{Deref, Range}; -use mlua::{AnyUserData, Lua, UserDataFields}; +use mlua::{AnyUserData, Lua, UserData, UserDataFields}; use yazi_config::LAYOUT; use yazi_plugin::{bindings::Cast, url::Url}; -use super::{File, Files, SCOPE}; +use super::{File, Files, Lives}; pub(super) struct Folder { window: Range, @@ -24,7 +24,7 @@ impl Folder { window: Option>, inner: &yazi_fs::Folder, tab: &yazi_core::tab::Tab, - ) -> mlua::Result> { + ) -> mlua::Result { let window = match window { Some(w) => w, None => { @@ -33,23 +33,10 @@ impl Folder { } }; - SCOPE.create_any_userdata(Self { window, inner, tab }) + Lives::scoped_userdata(Self { window, inner, tab }) } pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("cwd", |lua, me| Url::cast(lua, me.url.to_owned())); - reg.add_field_method_get("files", |_, me| Files::make(0..me.files.len(), me, me.tab())); - reg.add_field_method_get("stage", |lua, me| lua.create_any_userdata(me.stage)); - reg.add_field_method_get("window", |_, me| Files::make(me.window.clone(), me, me.tab())); - - reg.add_field_method_get("offset", |_, me| Ok(me.offset)); - reg.add_field_method_get("cursor", |_, me| Ok(me.cursor)); - reg.add_field_method_get("hovered", |_, me| { - me.hovered().map(|_| File::make(me.cursor, me, me.tab())).transpose() - }); - })?; - lua.register_userdata_type::(|reg| { reg.add_field_method_get("is_loading", |_, me| Ok(*me == yazi_fs::FolderStage::Loading)); })?; @@ -60,3 +47,18 @@ impl Folder { #[inline] fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } } } + +impl UserData for Folder { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("cwd", |lua, me| Url::cast(lua, 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())); + + 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() + }); + } +} diff --git a/yazi-fm/src/lives/iter.rs b/yazi-fm/src/lives/iter.rs index 4b0e0989b..845a8e307 100644 --- a/yazi-fm/src/lives/iter.rs +++ b/yazi-fm/src/lives/iter.rs @@ -1,6 +1,6 @@ -use mlua::AnyUserData; +use mlua::{AnyUserData, UserData}; -use super::SCOPE; +use super::Lives; pub(super) struct Iter, T> { inner: I, @@ -9,8 +9,8 @@ pub(super) struct Iter, T> { impl + 'static, T: 'static> Iter { #[inline] - pub(super) fn make(inner: I) -> mlua::Result> { - SCOPE.create_any_userdata(Self { inner, count: 0 }) + pub(super) fn make(inner: I) -> mlua::Result { + Lives::scoped_userdata(Self { inner, count: 0 }) } } @@ -23,3 +23,5 @@ impl, T> Iterator for Iter { Some((self.count, next)) } } + +impl, T> UserData for Iter {} diff --git a/yazi-fm/src/lives/lives.rs b/yazi-fm/src/lives/lives.rs index bd991132e..7ffd4d803 100644 --- a/yazi-fm/src/lives/lives.rs +++ b/yazi-fm/src/lives/lives.rs @@ -1,49 +1,33 @@ -use std::mem; +use std::cell::RefCell; -use mlua::Scope; -use scopeguard::defer; +use mlua::{AnyUserData, UserData}; use tracing::error; use yazi_plugin::LUA; use yazi_shared::RoCell; use crate::Ctx; -pub(super) static SCOPE: RoCell<&mlua::Scope> = RoCell::new(); +static TO_DESTROY: RoCell>> = RoCell::new_const(RefCell::new(Vec::new())); pub(crate) struct Lives; impl Lives { pub(crate) fn register() -> mlua::Result<()> { - super::Config::register(&LUA)?; - super::File::register(&LUA)?; - super::Files::register(&LUA)?; - super::Filter::register(&LUA)?; - super::Finder::register(&LUA)?; super::Folder::register(&LUA)?; - super::Mode::register(&LUA)?; - super::Preview::register(&LUA)?; - super::Selected::register(&LUA)?; - super::Tab::register(&LUA)?; - super::Tabs::register(&LUA)?; - super::Tasks::register(&LUA)?; - super::Yanked::register(&LUA)?; Ok(()) } - pub(crate) fn scope<'a, T>( - cx: &'a Ctx, - f: impl FnOnce(&Scope<'a, 'a>) -> mlua::Result, - ) -> mlua::Result { + pub(crate) fn scope(cx: &Ctx, f: impl FnOnce() -> mlua::Result) -> mlua::Result { let result = LUA.scope(|scope| { - defer! { SCOPE.drop(); } - SCOPE.init(unsafe { - mem::transmute::<&mlua::Scope<'a, 'a>, &mlua::Scope<'static, 'static>>(scope) + scope.add_destructor(|| { + for ud in TO_DESTROY.borrow_mut().drain(..) { + ud.destroy().expect("failed to destruct scoped userdata"); + } }); - LUA.set_named_registry_value("cx", scope.create_any_userdata_ref(cx)?)?; - let globals = LUA.globals(); - globals.raw_set( + LUA.set_named_registry_value("cx", scope.create_any_userdata_ref(cx)?)?; + LUA.globals().raw_set( "cx", LUA.create_table_from([ ("active", super::Tab::make(cx.manager.active())?), @@ -53,7 +37,7 @@ impl Lives { ])?, )?; - f(scope) + f() }); if let Err(ref e) = result { @@ -61,4 +45,14 @@ impl Lives { } result } + + #[inline] + pub(crate) fn scoped_userdata(data: T) -> mlua::Result + where + T: UserData + 'static, + { + let ud = LUA.create_userdata(data)?; + TO_DESTROY.borrow_mut().push(ud.clone()); + Ok(ud) + } } diff --git a/yazi-fm/src/lives/mod.rs b/yazi-fm/src/lives/mod.rs index 953601bce..2b8b33e69 100644 --- a/yazi-fm/src/lives/mod.rs +++ b/yazi-fm/src/lives/mod.rs @@ -4,5 +4,3 @@ yazi_macro::mod_flat!( config file files filter finder folder iter lives mode preview selected tab tabs tasks yanked ); - -type CtxRef<'lua> = mlua::UserDataRef<'lua, crate::Ctx>; diff --git a/yazi-fm/src/lives/mode.rs b/yazi-fm/src/lives/mode.rs index 46f0742d3..902bd9919 100644 --- a/yazi-fm/src/lives/mode.rs +++ b/yazi-fm/src/lives/mode.rs @@ -1,8 +1,8 @@ use std::ops::Deref; -use mlua::{AnyUserData, Lua, MetaMethod, UserDataFields, UserDataMethods}; +use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods}; -use super::SCOPE; +use super::Lives; pub(super) struct Mode { inner: *const yazi_core::tab::Mode, @@ -16,17 +16,19 @@ impl Deref for Mode { impl Mode { #[inline] - pub(super) fn make(inner: &yazi_core::tab::Mode) -> mlua::Result> { - SCOPE.create_any_userdata(Self { inner }) + pub(super) fn make(inner: &yazi_core::tab::Mode) -> mlua::Result { + Lives::scoped_userdata(Self { inner }) } +} - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("is_select", |_, me| Ok(me.is_select())); - reg.add_field_method_get("is_unset", |_, me| Ok(me.is_unset())); - reg.add_field_method_get("is_visual", |_, me| Ok(me.is_visual())); +impl UserData for Mode { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("is_select", |_, me| Ok(me.is_select())); + fields.add_field_method_get("is_unset", |_, me| Ok(me.is_unset())); + fields.add_field_method_get("is_visual", |_, me| Ok(me.is_visual())); + } - reg.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.to_string())); - }) + fn add_methods>(methods: &mut M) { + methods.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.to_string())); } } diff --git a/yazi-fm/src/lives/preview.rs b/yazi-fm/src/lives/preview.rs index 402ec170a..cdc85d94e 100644 --- a/yazi-fm/src/lives/preview.rs +++ b/yazi-fm/src/lives/preview.rs @@ -1,9 +1,9 @@ use std::ops::Deref; -use mlua::{AnyUserData, Lua, UserDataFields}; +use mlua::{AnyUserData, UserData, UserDataFields}; use yazi_config::LAYOUT; -use super::{Folder, SCOPE}; +use super::{Folder, Lives}; pub(super) struct Preview { tab: *const yazi_core::tab::Tab, @@ -17,25 +17,25 @@ impl Deref for Preview { impl Preview { #[inline] - pub(super) fn make(tab: &yazi_core::tab::Tab) -> mlua::Result> { - SCOPE.create_any_userdata(Self { tab }) - } - - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("skip", |_, me| Ok(me.skip)); - reg.add_field_method_get("folder", |_, me| { - 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()) - }) - .transpose() - }); - }) + pub(super) fn make(tab: &yazi_core::tab::Tab) -> mlua::Result { + Lives::scoped_userdata(Self { tab }) } #[inline] fn tab(&self) -> &yazi_core::tab::Tab { unsafe { &*self.tab } } } + +impl UserData for Preview { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("skip", |_, me| Ok(me.skip)); + fields.add_field_method_get("folder", |_, me| { + 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()) + }) + .transpose() + }); + } +} diff --git a/yazi-fm/src/lives/selected.rs b/yazi-fm/src/lives/selected.rs index 3e446eaf0..d2de2a38c 100644 --- a/yazi-fm/src/lives/selected.rs +++ b/yazi-fm/src/lives/selected.rs @@ -1,9 +1,9 @@ use std::{collections::{HashMap, hash_map}, ops::Deref}; -use mlua::{AnyUserData, IntoLuaMulti, Lua, MetaMethod, UserDataMethods, UserDataRefMut}; +use mlua::{AnyUserData, IntoLuaMulti, MetaMethod, UserData, UserDataMethods, UserDataRefMut}; use yazi_plugin::{bindings::Cast, url::Url}; -use super::{Iter, SCOPE}; +use super::{Iter, Lives}; #[derive(Clone, Copy)] pub(super) struct Selected { @@ -18,34 +18,30 @@ impl Deref for Selected { impl Selected { #[inline] - pub(super) fn make( - inner: &HashMap, - ) -> mlua::Result> { - SCOPE.create_any_userdata(Self { inner }) - } - - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len())); - - reg.add_meta_method(MetaMethod::Pairs, |lua, me, ()| { - let iter = lua.create_function( - |lua, mut iter: UserDataRefMut, _>>| { - if let Some(next) = iter.next() { - (next.0, Url::cast(lua, next.1.clone())?).into_lua_multi(lua) - } else { - ().into_lua_multi(lua) - } - }, - )?; - - Ok((iter, Iter::make(me.inner().keys()))) - }); - })?; - - Ok(()) + pub(super) fn make(inner: &HashMap) -> mlua::Result { + Lives::scoped_userdata(Self { inner }) } #[inline] fn inner(&self) -> &'static HashMap { unsafe { &*self.inner } } } + +impl UserData for Selected { + fn add_methods>(methods: &mut M) { + methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len())); + + methods.add_meta_method(MetaMethod::Pairs, |lua, me, ()| { + let iter = lua.create_function( + |lua, mut iter: UserDataRefMut, _>>| { + if let Some(next) = iter.next() { + (next.0, Url::cast(lua, next.1.clone())?).into_lua_multi(lua) + } else { + ().into_lua_multi(lua) + } + }, + )?; + + Ok((iter, Iter::make(me.inner().keys()))) + }); + } +} diff --git a/yazi-fm/src/lives/tab.rs b/yazi-fm/src/lives/tab.rs index eaff877b7..c0ebaa13b 100644 --- a/yazi-fm/src/lives/tab.rs +++ b/yazi-fm/src/lives/tab.rs @@ -1,9 +1,9 @@ use std::ops::Deref; -use mlua::{AnyUserData, Lua, UserDataFields, UserDataMethods}; +use mlua::{AnyUserData, UserData, UserDataFields, UserDataMethods}; use yazi_plugin::url::UrlRef; -use super::{Config, Finder, Folder, Mode, Preview, SCOPE, Selected}; +use super::{Config, Finder, Folder, Lives, Mode, Preview, Selected}; pub(super) struct Tab { inner: *const yazi_core::tab::Tab, @@ -17,33 +17,33 @@ impl Deref for Tab { impl Tab { #[inline] - pub(super) fn make(inner: &yazi_core::tab::Tab) -> mlua::Result> { - SCOPE.create_any_userdata(Self { inner }) + pub(super) fn make(inner: &yazi_core::tab::Tab) -> mlua::Result { + Lives::scoped_userdata(Self { inner }) + } +} + +impl UserData for Tab { + fn add_fields>(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("conf", |_, me| Config::make(&me.conf)); + fields.add_field_method_get("current", |_, me| Folder::make(None, &me.current, me)); + fields.add_field_method_get("parent", |_, me| { + me.parent.as_ref().map(|f| Folder::make(None, f, me)).transpose() + }); + + fields.add_field_method_get("selected", |_, me| 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()); } - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("id", |_, me| Ok(me.id.get())); - reg.add_method("name", |lua, me, ()| { - lua.create_string(me.current.url.name().as_encoded_bytes()) - }); - - reg.add_field_method_get("mode", |_, me| Mode::make(&me.mode)); - reg.add_field_method_get("conf", |_, me| Config::make(&me.conf)); - reg.add_field_method_get("current", |_, me| Folder::make(None, &me.current, me)); - reg.add_field_method_get("parent", |_, me| { - me.parent.as_ref().map(|f| Folder::make(None, f, me)).transpose() - }); - - reg.add_method("history", |_, me, url: UrlRef| { - me.history.get(&url).map(|f| Folder::make(None, f, me)).transpose() - }); - reg.add_field_method_get("selected", |_, me| Selected::make(&me.selected)); - - reg.add_field_method_get("preview", |_, me| Preview::make(me)); - reg.add_field_method_get("finder", |_, me| me.finder.as_ref().map(Finder::make).transpose()); - })?; - - Ok(()) + fn add_methods>(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() + }); } } diff --git a/yazi-fm/src/lives/tabs.rs b/yazi-fm/src/lives/tabs.rs index c95c19064..dc3a2b66e 100644 --- a/yazi-fm/src/lives/tabs.rs +++ b/yazi-fm/src/lives/tabs.rs @@ -1,8 +1,8 @@ use std::ops::Deref; -use mlua::{AnyUserData, Lua, MetaMethod, UserDataFields, UserDataMethods}; +use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods}; -use super::{SCOPE, Tab}; +use super::{Lives, Tab}; pub(super) struct Tabs { inner: *const yazi_core::manager::Tabs, @@ -16,25 +16,21 @@ impl Deref for Tabs { impl Tabs { #[inline] - pub(super) fn make(inner: &yazi_core::manager::Tabs) -> mlua::Result> { - SCOPE.create_any_userdata(Self { inner }) + pub(super) fn make(inner: &yazi_core::manager::Tabs) -> mlua::Result { + Lives::scoped_userdata(Self { inner }) } +} - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("idx", |_, me| Ok(me.cursor + 1)); - - reg.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len())); +impl UserData for Tabs { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("idx", |_, me| Ok(me.cursor + 1)); + } - reg.add_meta_method(MetaMethod::Index, |_, me, idx: usize| { - if idx > me.len() || idx == 0 { - Ok(None) - } else { - Some(Tab::make(&me[idx - 1])).transpose() - } - }); - })?; + fn add_methods>(methods: &mut M) { + methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len())); - Ok(()) + methods.add_meta_method(MetaMethod::Index, |_, me, idx: usize| { + if idx > me.len() || idx == 0 { Ok(None) } else { Some(Tab::make(&me[idx - 1])).transpose() } + }); } } diff --git a/yazi-fm/src/lives/tasks.rs b/yazi-fm/src/lives/tasks.rs index 481e7004a..60aac480f 100644 --- a/yazi-fm/src/lives/tasks.rs +++ b/yazi-fm/src/lives/tasks.rs @@ -1,8 +1,8 @@ use std::ops::Deref; -use mlua::{AnyUserData, Lua, LuaSerdeExt, UserDataFields}; +use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields}; -use super::SCOPE; +use super::Lives; pub(super) struct Tasks { inner: *const yazi_core::tasks::Tasks, @@ -16,15 +16,13 @@ impl Deref for Tasks { impl Tasks { #[inline] - pub(super) fn make(inner: &yazi_core::tasks::Tasks) -> mlua::Result> { - SCOPE.create_any_userdata(Self { inner }) + pub(super) fn make(inner: &yazi_core::tasks::Tasks) -> mlua::Result { + Lives::scoped_userdata(Self { inner }) } +} - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("progress", |lua, me| lua.to_value(&me.progress)) - })?; - - Ok(()) +impl UserData for Tasks { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("progress", |lua, me| lua.to_value(&me.progress)) } } diff --git a/yazi-fm/src/lives/yanked.rs b/yazi-fm/src/lives/yanked.rs index 9c35b79b1..0ca5262ec 100644 --- a/yazi-fm/src/lives/yanked.rs +++ b/yazi-fm/src/lives/yanked.rs @@ -1,9 +1,9 @@ use std::{collections::hash_set, ops::Deref}; -use mlua::{AnyUserData, IntoLuaMulti, Lua, MetaMethod, UserDataFields, UserDataMethods, UserDataRefMut}; +use mlua::{AnyUserData, IntoLuaMulti, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRefMut}; use yazi_plugin::{bindings::Cast, url::Url}; -use super::{Iter, SCOPE}; +use super::{Iter, Lives}; pub(super) struct Yanked { inner: *const yazi_core::manager::Yanked, @@ -17,32 +17,34 @@ impl Deref for Yanked { impl Yanked { #[inline] - pub(super) fn make(inner: &yazi_core::manager::Yanked) -> mlua::Result> { - SCOPE.create_any_userdata(Self { inner }) - } - - pub(super) fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(|reg| { - reg.add_field_method_get("is_cut", |_, me| Ok(me.cut)); - - reg.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len())); - - reg.add_meta_method(MetaMethod::Pairs, |lua, me, ()| { - let iter = lua.create_function( - |lua, mut iter: UserDataRefMut, _>>| { - if let Some(next) = iter.next() { - (next.0, Url::cast(lua, next.1.clone())?).into_lua_multi(lua) - } else { - ().into_lua_multi(lua) - } - }, - )?; - - Ok((iter, Iter::make(me.inner().iter()))) - }); - }) + pub(super) fn make(inner: &yazi_core::manager::Yanked) -> mlua::Result { + Lives::scoped_userdata(Self { inner }) } #[inline] fn inner(&self) -> &'static yazi_core::manager::Yanked { unsafe { &*self.inner } } } + +impl UserData for Yanked { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("is_cut", |_, me| Ok(me.cut)); + } + + fn add_methods>(methods: &mut M) { + methods.add_meta_method(MetaMethod::Len, |_, me, ()| Ok(me.len())); + + methods.add_meta_method(MetaMethod::Pairs, |lua, me, ()| { + let iter = lua.create_function( + |lua, mut iter: UserDataRefMut, _>>| { + if let Some(next) = iter.next() { + (next.0, Url::cast(lua, next.1.clone())?).into_lua_multi(lua) + } else { + ().into_lua_multi(lua) + } + }, + )?; + + Ok((iter, Iter::make(me.inner().iter()))) + }); + } +} diff --git a/yazi-fm/src/root.rs b/yazi-fm/src/root.rs index 2f847f4f9..54bdcf704 100644 --- a/yazi-fm/src/root.rs +++ b/yazi-fm/src/root.rs @@ -1,4 +1,4 @@ -use mlua::{Table, TableExt}; +use mlua::{ObjectLike, Table}; use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget}; use tracing::error; use yazi_plugin::{LUA, elements::render_widgets}; @@ -13,9 +13,9 @@ pub(super) struct Root<'a> { impl<'a> Root<'a> { pub(super) fn new(cx: &'a Ctx) -> Self { Self { cx } } - pub(super) fn reflow<'lua>(area: Rect) -> mlua::Result> { + pub(super) fn reflow(area: Rect) -> mlua::Result
{ let area = yazi_plugin::elements::Rect::from(area); - let root = LUA.globals().raw_get::<_, Table>("Root")?.call_method::<_, Table>("new", area)?; + let root = LUA.globals().raw_get::
("Root")?.call_method::
("new", area)?; root.call_method("reflow", ()) } } @@ -24,7 +24,7 @@ impl<'a> Widget for Root<'a> { fn render(self, area: Rect, buf: &mut Buffer) { let mut f = || { let area = yazi_plugin::elements::Rect::from(area); - let root = LUA.globals().raw_get::<_, Table>("Root")?.call_method::<_, Table>("new", area)?; + let root = LUA.globals().raw_get::
("Root")?.call_method::
("new", area)?; render_widgets(root.call_method("redraw", ())?, buf); Ok::<_, mlua::Error>(()) diff --git a/yazi-fm/src/tasks/progress.rs b/yazi-fm/src/tasks/progress.rs index f9795dccd..cb58dc053 100644 --- a/yazi-fm/src/tasks/progress.rs +++ b/yazi-fm/src/tasks/progress.rs @@ -1,4 +1,4 @@ -use mlua::{Table, TableExt}; +use mlua::{ObjectLike, Table}; use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget}; use tracing::error; use yazi_config::LAYOUT; @@ -11,7 +11,7 @@ impl Widget for Progress { let mut f = || { let area = yazi_plugin::elements::Rect::from(LAYOUT.get().progress); let progress = - LUA.globals().raw_get::<_, Table>("Progress")?.call_method::<_, Table>("use", area)?; + LUA.globals().raw_get::
("Progress")?.call_method::
("use", area)?; render_widgets(progress.call_method("redraw", ())?, buf); Ok::<_, mlua::Error>(()) diff --git a/yazi-plugin/src/bindings/bindings.rs b/yazi-plugin/src/bindings/bindings.rs index 3b04e52f7..91caff8db 100644 --- a/yazi-plugin/src/bindings/bindings.rs +++ b/yazi-plugin/src/bindings/bindings.rs @@ -1,3 +1,5 @@ +use mlua::Lua; + pub trait Cast { - fn cast(lua: &mlua::Lua, data: T) -> mlua::Result; + fn cast(lua: &Lua, data: T) -> mlua::Result; } diff --git a/yazi-plugin/src/bindings/icon.rs b/yazi-plugin/src/bindings/icon.rs index 07382e0e5..6a1688d2d 100644 --- a/yazi-plugin/src/bindings/icon.rs +++ b/yazi-plugin/src/bindings/icon.rs @@ -17,10 +17,7 @@ impl Icon { } impl Cast<&'static yazi_shared::theme::Icon> for Icon { - fn cast<'lua>( - lua: &'lua Lua, - data: &'static yazi_shared::theme::Icon, - ) -> mlua::Result> { + fn cast(lua: &Lua, data: &'static yazi_shared::theme::Icon) -> mlua::Result { lua.create_any_userdata(data) } } diff --git a/yazi-plugin/src/bindings/input.rs b/yazi-plugin/src/bindings/input.rs index d865fec9e..e56b5fb9e 100644 --- a/yazi-plugin/src/bindings/input.rs +++ b/yazi-plugin/src/bindings/input.rs @@ -28,8 +28,8 @@ impl>> InputRx { } impl> + 'static> UserData for InputRx { - fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { - methods.add_async_method_mut("recv", |_, me, ()| async move { + fn add_methods>(methods: &mut M) { + methods.add_async_method_mut("recv", |_, mut me, ()| async move { let mut inner = unsafe { Pin::new_unchecked(&mut me.inner) }; Ok(inner.next().await.map(Self::parse).unwrap_or((None, 0))) }); diff --git a/yazi-plugin/src/bindings/permit.rs b/yazi-plugin/src/bindings/permit.rs index 81555f0f2..2d16037ff 100644 --- a/yazi-plugin/src/bindings/permit.rs +++ b/yazi-plugin/src/bindings/permit.rs @@ -3,7 +3,7 @@ use std::{mem, ops::Deref}; use mlua::{UserData, prelude::LuaUserDataMethods}; use tokio::sync::SemaphorePermit; -pub type PermitRef<'lua, F> = mlua::UserDataRef<'lua, Permit>; +pub type PermitRef = mlua::UserDataRef>; pub struct Permit { inner: Option>, @@ -36,7 +36,7 @@ impl Drop for Permit { } impl UserData for Permit { - fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { methods.add_method_mut("drop", |_, me, ()| Ok(me.dropping())); } } diff --git a/yazi-plugin/src/bindings/position.rs b/yazi-plugin/src/bindings/position.rs index e5151bdaf..95aa033c8 100644 --- a/yazi-plugin/src/bindings/position.rs +++ b/yazi-plugin/src/bindings/position.rs @@ -1,6 +1,6 @@ use std::{ops::Deref, str::FromStr}; -use mlua::{ExternalResult, IntoLua}; +use mlua::{ExternalResult, IntoLua, Lua}; pub struct Position(yazi_config::popup::Position); @@ -14,14 +14,14 @@ impl From for yazi_config::popup::Position { fn from(value: Position) -> Self { value.0 } } -impl<'a> TryFrom> for Position { +impl TryFrom for Position { type Error = mlua::Error; - fn try_from(t: mlua::Table<'a>) -> Result { + fn try_from(t: mlua::Table) -> Result { use yazi_config::popup::{Offset, Origin, Position}; Ok(Self(Position { - origin: Origin::from_str(t.raw_get::<_, mlua::String>(1)?.to_str()?).into_lua_err()?, + origin: Origin::from_str(&t.raw_get::(1)?.to_str()?).into_lua_err()?, offset: Offset { x: t.raw_get("x").unwrap_or_default(), y: t.raw_get("y").unwrap_or_default(), @@ -32,8 +32,8 @@ impl<'a> TryFrom> for Position { } } -impl IntoLua<'_> for Position { - fn into_lua(self, lua: &mlua::Lua) -> mlua::Result { +impl IntoLua for Position { + fn into_lua(self, lua: &Lua) -> mlua::Result { lua .create_table_from([ (1.into_lua(lua)?, self.origin.to_string().into_lua(lua)?), diff --git a/yazi-plugin/src/bindings/range.rs b/yazi-plugin/src/bindings/range.rs index 516c26076..aa864e044 100644 --- a/yazi-plugin/src/bindings/range.rs +++ b/yazi-plugin/src/bindings/range.rs @@ -1,4 +1,4 @@ -use mlua::IntoLua; +use mlua::{IntoLua, Lua}; pub struct Range(std::ops::Range); @@ -6,11 +6,11 @@ impl From> for Range { fn from(value: std::ops::Range) -> Self { Self(value) } } -impl<'lua, T> IntoLua<'lua> for Range +impl IntoLua for Range where - T: IntoLua<'lua>, + T: IntoLua, { - fn into_lua(self, lua: &'lua mlua::Lua) -> mlua::Result> { + fn into_lua(self, lua: &Lua) -> mlua::Result { lua.create_sequence_from([self.0.start, self.0.end])?.into_lua(lua) } } diff --git a/yazi-plugin/src/bindings/window.rs b/yazi-plugin/src/bindings/window.rs index b4d63bbb5..86bf1ab58 100644 --- a/yazi-plugin/src/bindings/window.rs +++ b/yazi-plugin/src/bindings/window.rs @@ -17,7 +17,7 @@ impl Default for Window { } impl UserData for Window { - fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { + fn add_fields>(fields: &mut F) { fields.add_field_method_get("rows", |_, me| Ok(me.rows)); fields.add_field_method_get("cols", |_, me| Ok(me.cols)); fields.add_field_method_get("width", |_, me| Ok(me.width)); diff --git a/yazi-plugin/src/cha/mod.rs b/yazi-plugin/src/cha/mod.rs index 011a648d5..60e8ee9f2 100644 --- a/yazi-plugin/src/cha/mod.rs +++ b/yazi-plugin/src/cha/mod.rs @@ -1,8 +1,10 @@ #![allow(clippy::module_inception)] +use mlua::Lua; + yazi_macro::mod_flat!(cha); -pub fn pour(lua: &mlua::Lua) -> mlua::Result<()> { +pub fn pour(lua: &Lua) -> mlua::Result<()> { cha::Cha::register(lua)?; cha::Cha::install(lua)?; diff --git a/yazi-plugin/src/elements/bar.rs b/yazi-plugin/src/elements/bar.rs index bb0e49539..b8a42d308 100644 --- a/yazi-plugin/src/elements/bar.rs +++ b/yazi-plugin/src/elements/bar.rs @@ -35,7 +35,7 @@ impl Bar { } impl UserData for Bar { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); crate::impl_style_method!(methods, style); diff --git a/yazi-plugin/src/elements/border.rs b/yazi-plugin/src/elements/border.rs index de86e1e2c..2b6476f8b 100644 --- a/yazi-plugin/src/elements/border.rs +++ b/yazi-plugin/src/elements/border.rs @@ -53,7 +53,7 @@ impl Border { } impl UserData for Border { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); crate::impl_style_method!(methods, style); diff --git a/yazi-plugin/src/elements/clear.rs b/yazi-plugin/src/elements/clear.rs index c11c43ac8..e1f887780 100644 --- a/yazi-plugin/src/elements/clear.rs +++ b/yazi-plugin/src/elements/clear.rs @@ -55,7 +55,7 @@ impl Renderable for Clear { } impl UserData for Clear { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); } } diff --git a/yazi-plugin/src/elements/constraint.rs b/yazi-plugin/src/elements/constraint.rs index 34ffecc32..de79dd81e 100644 --- a/yazi-plugin/src/elements/constraint.rs +++ b/yazi-plugin/src/elements/constraint.rs @@ -14,7 +14,7 @@ impl From for ratatui::layout::Constraint { } impl UserData for Constraint { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { use ratatui::layout::Constraint as C; methods.add_function("Min", |_, n: u16| Ok(Self(C::Min(n)))); diff --git a/yazi-plugin/src/elements/gauge.rs b/yazi-plugin/src/elements/gauge.rs index fbfd00be0..f2908000f 100644 --- a/yazi-plugin/src/elements/gauge.rs +++ b/yazi-plugin/src/elements/gauge.rs @@ -21,7 +21,7 @@ impl Gauge { } impl UserData for Gauge { - fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); crate::impl_style_method!(methods, style); diff --git a/yazi-plugin/src/elements/layout.rs b/yazi-plugin/src/elements/layout.rs index b56bd12cc..f3cd67f3f 100644 --- a/yazi-plugin/src/elements/layout.rs +++ b/yazi-plugin/src/elements/layout.rs @@ -25,7 +25,7 @@ impl Layout { } impl UserData for Layout { - fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { methods.add_function_mut("direction", |_, (ud, value): (AnyUserData, bool)| { ud.borrow_mut::()?.direction = value; Ok(ud) diff --git a/yazi-plugin/src/elements/line.rs b/yazi-plugin/src/elements/line.rs index 0be95c949..1af27ed50 100644 --- a/yazi-plugin/src/elements/line.rs +++ b/yazi-plugin/src/elements/line.rs @@ -20,7 +20,8 @@ impl Line { let new = lua.create_function(|_, (_, value): (Table, Value)| Line::try_from(value))?; let parse = lua.create_function(|_, code: mlua::String| { - let Some(line) = code.as_bytes().split_inclusive(|&b| b == b'\n').next() else { + let code = code.as_bytes(); + let Some(line) = code.split_inclusive(|&b| b == b'\n').next() else { return Ok(Line(Default::default())); }; @@ -46,13 +47,13 @@ impl Line { } } -impl TryFrom> for Line { +impl TryFrom for Line { type Error = mlua::Error; fn try_from(value: Value) -> Result { Ok(Self(match value { Value::Table(tb) => return Self::try_from(tb), - Value::String(s) => s.to_string_lossy().into_owned().into(), + Value::String(s) => s.to_string_lossy().into(), Value::UserData(ud) => { if let Ok(Span(span)) = ud.take() { span.into() @@ -68,14 +69,14 @@ impl TryFrom> for Line { } } -impl TryFrom> for Line { +impl TryFrom
for Line { type Error = mlua::Error; fn try_from(tb: Table) -> Result { let mut spans = Vec::with_capacity(tb.raw_len()); for v in tb.sequence_values() { match v? { - Value::String(s) => spans.push(s.to_string_lossy().into_owned().into()), + Value::String(s) => spans.push(s.to_string_lossy().into()), Value::UserData(ud) => { if let Ok(Span(span)) = ud.take() { spans.push(span); @@ -94,7 +95,7 @@ impl TryFrom> for Line { } impl UserData for Line { - fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_style_method!(methods, 0.style); crate::impl_style_shorthands!(methods, 0.style); diff --git a/yazi-plugin/src/elements/list.rs b/yazi-plugin/src/elements/list.rs index a2c5b3621..30b622c9d 100644 --- a/yazi-plugin/src/elements/list.rs +++ b/yazi-plugin/src/elements/list.rs @@ -31,7 +31,7 @@ impl List { } impl UserData for List { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); } } diff --git a/yazi-plugin/src/elements/padding.rs b/yazi-plugin/src/elements/padding.rs index 295e90fbe..a0fda8f66 100644 --- a/yazi-plugin/src/elements/padding.rs +++ b/yazi-plugin/src/elements/padding.rs @@ -49,7 +49,7 @@ impl Padding { } impl UserData for Padding { - fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { + fn add_fields>(fields: &mut F) { fields.add_field_method_get("left", |_, me| Ok(me.left)); fields.add_field_method_get("right", |_, me| Ok(me.right)); fields.add_field_method_get("top", |_, me| Ok(me.top)); diff --git a/yazi-plugin/src/elements/paragraph.rs b/yazi-plugin/src/elements/paragraph.rs index fb3974bcb..7bf8f39e0 100644 --- a/yazi-plugin/src/elements/paragraph.rs +++ b/yazi-plugin/src/elements/paragraph.rs @@ -41,7 +41,7 @@ impl Paragraph { .load(mlua::chunk! { return ui.Text($lines):area($area) }) - .call::<_, MultiValue>(()) + .call::(()) })?, ), ( @@ -52,7 +52,7 @@ impl Paragraph { .load(mlua::chunk! { return ui.Text[$key] }) - .call::<_, MultiValue>(()) + .call::(()) })?, ), ])?; diff --git a/yazi-plugin/src/elements/position.rs b/yazi-plugin/src/elements/position.rs index 171fa8cba..c062bd345 100644 --- a/yazi-plugin/src/elements/position.rs +++ b/yazi-plugin/src/elements/position.rs @@ -30,7 +30,7 @@ impl Position { } impl UserData for Position { - fn add_fields<'lua, F: UserDataFields<'lua, Self>>(fields: &mut F) { + fn add_fields>(fields: &mut F) { fields.add_field_method_get("x", |_, me| Ok(me.x)); fields.add_field_method_get("y", |_, me| Ok(me.y)); } diff --git a/yazi-plugin/src/elements/rect.rs b/yazi-plugin/src/elements/rect.rs index 1efddfc6d..ef8a78757 100644 --- a/yazi-plugin/src/elements/rect.rs +++ b/yazi-plugin/src/elements/rect.rs @@ -43,7 +43,7 @@ impl Rect { } impl UserData for Rect { - fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { + fn add_fields>(fields: &mut F) { fields.add_field_method_get("x", |_, me| Ok(me.x)); fields.add_field_method_get("y", |_, me| Ok(me.y)); fields.add_field_method_get("w", |_, me| Ok(me.width)); @@ -55,7 +55,7 @@ impl UserData for Rect { fields.add_field_method_get("bottom", |_, me| Ok(me.bottom())); } - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { methods.add_method("padding", |_, me, padding: Padding| { let mut r = **me; r.x = r.x.saturating_add(padding.left); diff --git a/yazi-plugin/src/elements/span.rs b/yazi-plugin/src/elements/span.rs index 5e185380b..d121dd664 100644 --- a/yazi-plugin/src/elements/span.rs +++ b/yazi-plugin/src/elements/span.rs @@ -12,12 +12,12 @@ impl Span { } } -impl TryFrom> for Span { +impl TryFrom for Span { type Error = mlua::Error; - fn try_from(value: Value<'_>) -> Result { + fn try_from(value: Value) -> Result { Ok(Self(match value { - Value::String(s) => s.to_string_lossy().into_owned().into(), + Value::String(s) => s.to_string_lossy().into(), Value::UserData(ud) => { if let Ok(Span(span)) = ud.take() { span @@ -31,7 +31,7 @@ impl TryFrom> for Span { } impl UserData for Span { - fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_style_method!(methods, 0.style); crate::impl_style_shorthands!(methods, 0.style); diff --git a/yazi-plugin/src/elements/style.rs b/yazi-plugin/src/elements/style.rs index caef4089e..bd9476f09 100644 --- a/yazi-plugin/src/elements/style.rs +++ b/yazi-plugin/src/elements/style.rs @@ -17,16 +17,16 @@ impl Style { } } -impl<'a> TryFrom> for Style { +impl TryFrom
for Style { type Error = mlua::Error; - fn try_from(value: Table<'a>) -> Result { + fn try_from(value: Table) -> Result { let mut style = ratatui::style::Style::default(); - if let Ok(fg) = value.raw_get::<_, mlua::String>("fg") { - style.fg = Some(Color::from_str(fg.to_str()?).into_lua_err()?.into()); + if let Ok(fg) = value.raw_get::("fg") { + style.fg = Some(Color::from_str(&fg.to_str()?).into_lua_err()?.into()); } - if let Ok(bg) = value.raw_get::<_, mlua::String>("bg") { - style.bg = Some(Color::from_str(bg.to_str()?).into_lua_err()?.into()); + if let Ok(bg) = value.raw_get::("bg") { + style.bg = Some(Color::from_str(&bg.to_str()?).into_lua_err()?.into()); } style.add_modifier = ratatui::style::Modifier::from_bits_truncate(value.raw_get("modifier").unwrap_or_default()); @@ -34,10 +34,10 @@ impl<'a> TryFrom> for Style { } } -impl<'a> TryFrom> for Style { +impl TryFrom for Style { type Error = mlua::Error; - fn try_from(value: Value<'a>) -> Result { + fn try_from(value: Value) -> Result { Ok(Self(match value { Value::Nil => Default::default(), Value::Table(tb) => Self::try_from(tb)?.0, @@ -52,7 +52,7 @@ impl From for Style { } impl UserData for Style { - fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_style_shorthands!(methods, 0); methods.add_function_mut("patch", |_, (ud, value): (AnyUserData, Value)| { diff --git a/yazi-plugin/src/elements/table.rs b/yazi-plugin/src/elements/table.rs index 5c62bc8e1..33e119b46 100644 --- a/yazi-plugin/src/elements/table.rs +++ b/yazi-plugin/src/elements/table.rs @@ -36,7 +36,7 @@ impl Table { } impl UserData for Table { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); methods.add_function_mut("header", |_, (ud, row): (AnyUserData, TableRow)| { @@ -114,7 +114,7 @@ impl From for ratatui::widgets::Row<'static> { } impl UserData for TableRow { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_style_method!(methods, style); methods.add_function_mut("height", |_, (ud, value): (AnyUserData, u16)| { diff --git a/yazi-plugin/src/elements/text.rs b/yazi-plugin/src/elements/text.rs index 04cb12f53..082e2cb74 100644 --- a/yazi-plugin/src/elements/text.rs +++ b/yazi-plugin/src/elements/text.rs @@ -31,7 +31,7 @@ impl Text { let new = lua.create_function(|_, (_, value): (Table, Value)| Text::try_from(value))?; let parse = lua.create_function(|_, code: mlua::String| { - Ok(Text { inner: code.into_text().into_lua_err()?, ..Default::default() }) + Ok(Text { inner: code.as_bytes().into_text().into_lua_err()?, ..Default::default() }) })?; let text = lua.create_table_from([ @@ -52,13 +52,13 @@ impl Text { } } -impl TryFrom> for Text { +impl TryFrom for Text { type Error = mlua::Error; fn try_from(value: Value) -> mlua::Result { let inner = match value { Value::Table(tb) => return Self::try_from(tb), - Value::String(s) => s.to_string_lossy().into_owned().into(), + Value::String(s) => s.to_string_lossy().into(), Value::UserData(ud) => { if let Ok(Line(line)) = ud.take() { line.into() @@ -74,14 +74,14 @@ impl TryFrom> for Text { } } -impl TryFrom> for Text { +impl TryFrom
for Text { type Error = mlua::Error; - fn try_from(tb: Table<'_>) -> Result { + fn try_from(tb: Table) -> Result { let mut lines = Vec::with_capacity(tb.raw_len()); for v in tb.sequence_values() { match v? { - Value::String(s) => lines.push(s.to_string_lossy().into_owned().into()), + Value::String(s) => lines.push(s.to_string_lossy().into()), Value::UserData(ud) => { if let Ok(Span(span)) = ud.take() { lines.push(span.into()); @@ -116,7 +116,7 @@ impl From for ratatui::widgets::Paragraph<'static> { } impl UserData for Text { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); crate::impl_style_method!(methods, inner.style); crate::impl_style_shorthands!(methods, inner.style); diff --git a/yazi-plugin/src/file/file.rs b/yazi-plugin/src/file/file.rs index cf7c0daaa..61de7b680 100644 --- a/yazi-plugin/src/file/file.rs +++ b/yazi-plugin/src/file/file.rs @@ -1,49 +1,18 @@ -use mlua::{AnyUserData, Lua, Table, UserDataFields, UserDataMethods, UserDataRef, UserDataRegistry}; -use yazi_config::THEME; +use mlua::{AnyUserData, Lua, Table, UserDataRef}; -use crate::{bindings::{Cast, Icon}, cha::Cha, url::Url}; +use crate::{bindings::Cast, impl_file_fields, impl_file_methods}; -pub type FileRef<'lua> = UserDataRef<'lua, yazi_shared::fs::File>; +pub type FileRef = UserDataRef; pub struct File; impl File { #[inline] pub fn register(lua: &Lua) -> mlua::Result<()> { - lua.register_userdata_type::(Self::register_with) - } - - pub fn register_with(reg: &mut UserDataRegistry) - where - T: AsRef, - { - reg.add_field_method_get("cha", |lua, me| Cha::cast(lua, me.as_ref().cha)); - reg.add_field_method_get("url", |lua, me| Url::cast(lua, me.as_ref().url_owned())); - reg.add_field_method_get("link_to", |lua, me| { - me.as_ref().link_to.clone().map(|u| Url::cast(lua, u)).transpose() - }); - - reg.add_field_method_get("name", |lua, me| { - Some(me.as_ref().name()) - .filter(|s| !s.is_empty()) - .map(|s| lua.create_string(s.as_encoded_bytes())) - .transpose() - }); - - reg.add_method("icon", |lua, me, ()| { - use yazi_shared::theme::IconCache; - - let me = me.as_ref(); - match me.icon.get() { - IconCache::Missing => { - let matched = THEME.icons.matches(me); - me.icon.set(matched.map_or(IconCache::Undefined, IconCache::Icon)); - matched.map(|i| Icon::cast(lua, i)).transpose() - } - IconCache::Undefined => Ok(None), - IconCache::Icon(cached) => Some(Icon::cast(lua, cached)).transpose(), - } - }); + lua.register_userdata_type::(|reg| { + impl_file_fields!(reg); + impl_file_methods!(reg); + }) } pub fn install(lua: &Lua) -> mlua::Result<()> { @@ -51,8 +20,8 @@ impl File { "File", lua.create_function(|lua, t: Table| { Self::cast(lua, yazi_shared::fs::File { - url: t.raw_get::<_, AnyUserData>("url")?.take()?, - cha: t.raw_get::<_, AnyUserData>("cha")?.take()?, + url: t.raw_get::("url")?.take()?, + cha: t.raw_get::("cha")?.take()?, ..Default::default() }) })?, diff --git a/yazi-plugin/src/file/mod.rs b/yazi-plugin/src/file/mod.rs index cf5846923..640debc41 100644 --- a/yazi-plugin/src/file/mod.rs +++ b/yazi-plugin/src/file/mod.rs @@ -1,8 +1,10 @@ #![allow(clippy::module_inception)] +use mlua::Lua; + yazi_macro::mod_flat!(file); -pub fn pour(lua: &mlua::Lua) -> mlua::Result<()> { +pub fn pour(lua: &Lua) -> mlua::Result<()> { file::File::register(lua)?; file::File::install(lua)?; diff --git a/yazi-plugin/src/fs/fs.rs b/yazi-plugin/src/fs/fs.rs index 4af0c3601..9fa6af13c 100644 --- a/yazi-plugin/src/fs/fs.rs +++ b/yazi-plugin/src/fs/fs.rs @@ -19,24 +19,24 @@ pub fn install(lua: &Lua) -> mlua::Result<()> { }; match meta { - Ok(m) => (Cha::cast(lua, m)?, Value::Nil).into_lua_multi(lua), - Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua), + Ok(m) => (Cha::cast(&lua, m)?, Value::Nil).into_lua_multi(&lua), + Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua), } })?, ), ( "write", lua.create_async_function(|lua, (url, data): (UrlRef, mlua::String)| async move { - match fs::write(&*url, data).await { - Ok(_) => (true, Value::Nil).into_lua_multi(lua), - Err(e) => (false, e.raw_os_error()).into_lua_multi(lua), + match fs::write(&*url, data.as_bytes()).await { + Ok(_) => (true, Value::Nil).into_lua_multi(&lua), + Err(e) => (false, e.raw_os_error()).into_lua_multi(&lua), } })?, ), ( "remove", lua.create_async_function(|lua, (type_, url): (mlua::String, UrlRef)| async move { - let result = match type_.to_str()? { + let result = match &*type_.to_str()? { "file" => fs::remove_file(&*url).await, "dir" => fs::remove_dir(&*url).await, "dir_all" => fs::remove_dir_all(&*url).await, @@ -47,17 +47,17 @@ pub fn install(lua: &Lua) -> mlua::Result<()> { }; match result { - Ok(_) => (true, Value::Nil).into_lua_multi(lua), - Err(e) => (false, e.raw_os_error()).into_lua_multi(lua), + Ok(_) => (true, Value::Nil).into_lua_multi(&lua), + Err(e) => (false, e.raw_os_error()).into_lua_multi(&lua), } })?, ), ( "read_dir", lua.create_async_function(|lua, (dir, options): (UrlRef, Table)| async move { - let glob = if let Ok(s) = options.raw_get::<_, mlua::String>("glob") { + let glob = if let Ok(s) = options.raw_get::("glob") { Some( - GlobBuilder::new(s.to_str()?) + GlobBuilder::new(&s.to_str()?) .case_insensitive(true) .literal_separator(true) .backslash_escape(false) @@ -75,7 +75,7 @@ pub fn install(lua: &Lua) -> mlua::Result<()> { let mut it = match fs::read_dir(&*dir).await { Ok(it) => it, - Err(e) => return (Value::Nil, e.raw_os_error()).into_lua_multi(lua), + Err(e) => return (Value::Nil, e.raw_os_error()).into_lua_multi(&lua), }; let mut files = vec![]; @@ -97,7 +97,7 @@ pub fn install(lua: &Lua) -> mlua::Result<()> { } else { yazi_shared::fs::File::from_dummy(url, next.file_type().await.ok()) }; - files.push(File::cast(lua, file)?); + files.push(File::cast(&lua, file)?); } let tbl = lua.create_table_with_capacity(files.len(), 0)?; @@ -105,15 +105,15 @@ pub fn install(lua: &Lua) -> mlua::Result<()> { tbl.raw_push(f)?; } - (tbl, Value::Nil).into_lua_multi(lua) + (tbl, Value::Nil).into_lua_multi(&lua) })?, ), ( "unique_name", lua.create_async_function(|lua, url: UrlRef| async move { match yazi_shared::fs::unique_name(url.clone(), async { false }).await { - Ok(u) => (Url::cast(lua, u)?, Value::Nil).into_lua_multi(lua), - Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua), + Ok(u) => (Url::cast(&lua, u)?, Value::Nil).into_lua_multi(&lua), + Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua), } })?, ), diff --git a/yazi-plugin/src/isolate/entry.rs b/yazi-plugin/src/isolate/entry.rs index f4f5ca52a..65f4cc7be 100644 --- a/yazi-plugin/src/isolate/entry.rs +++ b/yazi-plugin/src/isolate/entry.rs @@ -1,4 +1,4 @@ -use mlua::{ExternalError, ExternalResult, Table, TableExt}; +use mlua::{ExternalError, ExternalResult, ObjectLike, Table}; use tokio::runtime::Handle; use yazi_dds::Sendable; use yazi_shared::event::Data; diff --git a/yazi-plugin/src/isolate/fetch.rs b/yazi-plugin/src/isolate/fetch.rs index e7fa97f25..2b665241e 100644 --- a/yazi-plugin/src/isolate/fetch.rs +++ b/yazi-plugin/src/isolate/fetch.rs @@ -1,4 +1,4 @@ -use mlua::{ExternalError, ExternalResult, Table, TableExt}; +use mlua::{ExternalError, ExternalResult, ObjectLike, Table}; use tokio::runtime::Handle; use yazi_config::LAYOUT; diff --git a/yazi-plugin/src/isolate/peek.rs b/yazi-plugin/src/isolate/peek.rs index afd5204bb..3435f43dd 100644 --- a/yazi-plugin/src/isolate/peek.rs +++ b/yazi-plugin/src/isolate/peek.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use mlua::{ExternalError, ExternalResult, HookTriggers, Table, TableExt}; +use mlua::{ExternalError, ExternalResult, HookTriggers, ObjectLike, Table, VmState}; use tokio::{runtime::Handle, select}; use tokio_util::sync::CancellationToken; use tracing::error; @@ -29,7 +29,11 @@ pub fn peek( lua.set_hook( HookTriggers::new().on_calls().on_returns().every_nth_instruction(2000), move |_, _| { - if ct1.is_cancelled() { Err("Peek task cancelled".into_lua_err()) } else { Ok(()) } + if ct1.is_cancelled() { + Err("Peek task cancelled".into_lua_err()) + } else { + Ok(VmState::Continue) + } }, ); diff --git a/yazi-plugin/src/isolate/preload.rs b/yazi-plugin/src/isolate/preload.rs index e7d582bf4..b8397a783 100644 --- a/yazi-plugin/src/isolate/preload.rs +++ b/yazi-plugin/src/isolate/preload.rs @@ -1,4 +1,4 @@ -use mlua::{ExternalError, ExternalResult, Table, TableExt}; +use mlua::{ExternalError, ExternalResult, ObjectLike, Table}; use tokio::runtime::Handle; use yazi_config::LAYOUT; diff --git a/yazi-plugin/src/isolate/seek.rs b/yazi-plugin/src/isolate/seek.rs index 38d140573..490696c2b 100644 --- a/yazi-plugin/src/isolate/seek.rs +++ b/yazi-plugin/src/isolate/seek.rs @@ -1,4 +1,4 @@ -use mlua::TableExt; +use mlua::ObjectLike; use yazi_config::LAYOUT; use yazi_proxy::{AppProxy, options::{PluginCallback, PluginOpt}}; use yazi_shared::event::Cmd; diff --git a/yazi-plugin/src/loader/loader.rs b/yazi-plugin/src/loader/loader.rs index 989dac93f..64a9360cb 100644 --- a/yazi-plugin/src/loader/loader.rs +++ b/yazi-plugin/src/loader/loader.rs @@ -63,9 +63,9 @@ impl Loader { Ok(()) } - pub fn load<'a>(&self, lua: &'a Lua, id: &str) -> mlua::Result> { - let loaded: Table = lua.globals().raw_get::<_, Table>("package")?.raw_get("loaded")?; - if let Ok(t) = loaded.raw_get::<_, Table>(id) { + pub fn load(&self, lua: &Lua, id: &str) -> mlua::Result
{ + let loaded: Table = lua.globals().raw_get::
("package")?.raw_get("loaded")?; + if let Ok(t) = loaded.raw_get::
(id) { return Ok(t); } @@ -79,14 +79,14 @@ impl Loader { Ok(t) } - pub fn try_load<'a>(&self, lua: &'a Lua, id: &str) -> mlua::Result> { - let loaded: Table = lua.globals().raw_get::<_, Table>("package")?.raw_get("loaded")?; + pub fn try_load(&self, lua: &Lua, id: &str) -> mlua::Result
{ + let loaded: Table = lua.globals().raw_get::
("package")?.raw_get("loaded")?; loaded.raw_get(id) } - pub fn load_with<'a>(&self, lua: &'a Lua, id: &str, chunk: &Chunk) -> mlua::Result> { - let loaded: Table = lua.globals().raw_get::<_, Table>("package")?.raw_get("loaded")?; - if let Ok(t) = loaded.raw_get::<_, Table>(id) { + pub fn load_with(&self, lua: &Lua, id: &str, chunk: &Chunk) -> mlua::Result
{ + let loaded: Table = lua.globals().raw_get::
("package")?.raw_get("loaded")?; + if let Ok(t) = loaded.raw_get::
(id) { return Ok(t); } diff --git a/yazi-plugin/src/loader/require.rs b/yazi-plugin/src/loader/require.rs index d3510d121..1f6c11162 100644 --- a/yazi-plugin/src/loader/require.rs +++ b/yazi-plugin/src/loader/require.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use mlua::{ExternalResult, Function, IntoLua, Lua, MultiValue, Table, TableExt, Value}; +use mlua::{ExternalResult, Function, IntoLua, Lua, MultiValue, ObjectLike, Table, Value}; use super::LOADER; use crate::RtRef; @@ -12,7 +12,7 @@ impl Require { lua.globals().raw_set( "require", lua.create_function(|lua, id: mlua::String| { - let s = id.to_str()?; + let s = &id.to_str()?; futures::executor::block_on(LOADER.ensure(s)).into_lua_err()?; lua.named_registry_value::("rt")?.push(s); @@ -28,27 +28,27 @@ impl Require { lua.globals().raw_set( "require", lua.create_async_function(|lua, id: mlua::String| async move { - let s = id.to_str()?; + let s = &id.to_str()?; LOADER.ensure(s).await.into_lua_err()?; lua.named_registry_value::("rt")?.push(s); - let mod_ = LOADER.load(lua, s); + let mod_ = LOADER.load(&lua, s); lua.named_registry_value::("rt")?.pop(); - Self::create_mt(lua, s, mod_?, false) + Self::create_mt(&lua, s, mod_?, false) })?, ) } - fn create_mt<'a>(lua: &'a Lua, id: &str, mod_: Table<'a>, sync: bool) -> mlua::Result> { + fn create_mt(lua: &Lua, id: &str, mod_: Table, sync: bool) -> mlua::Result
{ let id: Arc = Arc::from(id); let mt = lua.create_table_from([ ( "__index", lua.create_function(move |lua, (ts, key): (Table, mlua::String)| { - match ts.raw_get::<_, Table>("__mod")?.raw_get::<_, Value>(&key)? { + match ts.raw_get::
("__mod")?.raw_get::(&key)? { Value::Function(_) => { - Self::create_wrapper(lua, id.clone(), key.to_str()?, sync)?.into_lua(lua) + Self::create_wrapper(lua, id.clone(), &key.to_str()?, sync)?.into_lua(lua) } v => Ok(v), } @@ -57,7 +57,7 @@ impl Require { ( "__newindex", lua.create_function(move |_, (ts, key, value): (Table, mlua::String, Value)| { - ts.raw_get::<_, Table>("__mod")?.raw_set(key, value) + ts.raw_get::
("__mod")?.raw_set(key, value) })?, ), ])?; @@ -67,19 +67,14 @@ impl Require { Ok(ts) } - fn create_wrapper<'a>( - lua: &'a Lua, - id: Arc, - f: &str, - sync: bool, - ) -> mlua::Result> { + fn create_wrapper(lua: &Lua, id: Arc, f: &str, sync: bool) -> mlua::Result { let f: Arc = Arc::from(f); if sync { lua.create_function(move |lua, args: MultiValue| { let (mod_, args) = Self::split_mod_and_args(lua, &id, args)?; lua.named_registry_value::("rt")?.push(&id); - let result = mod_.call_function::<_, MultiValue>(&f, args); + let result = mod_.call_function::(&f, args); lua.named_registry_value::("rt")?.pop(); result }) @@ -87,9 +82,9 @@ impl Require { lua.create_async_function(move |lua, args: MultiValue| { let (id, f) = (id.clone(), f.clone()); async move { - let (mod_, args) = Self::split_mod_and_args(lua, &id, args)?; + let (mod_, args) = Self::split_mod_and_args(&lua, &id, args)?; lua.named_registry_value::("rt")?.push(&id); - let result = mod_.call_async_function::<_, MultiValue>(&f, args).await; + let result = mod_.call_async_function::(&f, args).await; lua.named_registry_value::("rt")?.pop(); result } @@ -97,11 +92,11 @@ impl Require { } } - fn split_mod_and_args<'a>( - lua: &'a Lua, + fn split_mod_and_args( + lua: &Lua, id: &str, - mut args: MultiValue<'a>, - ) -> mlua::Result<(Table<'a>, MultiValue<'a>)> { + mut args: MultiValue, + ) -> mlua::Result<(Table, MultiValue)> { let Some(front) = args.pop_front() else { return Ok((LOADER.try_load(lua, id)?, args)); }; @@ -109,7 +104,7 @@ impl Require { args.push_front(front); return Ok((LOADER.try_load(lua, id)?, args)); }; - Ok(if let Ok(mod_) = tbl.raw_get::<_, Table>("__mod") { + Ok(if let Ok(mod_) = tbl.raw_get::
("__mod") { args.push_front(Value::Table(mod_.clone())); (mod_, args) } else { diff --git a/yazi-plugin/src/macros.rs b/yazi-plugin/src/macros.rs index 6da7d302a..75aa3b2c3 100644 --- a/yazi-plugin/src/macros.rs +++ b/yazi-plugin/src/macros.rs @@ -78,3 +78,46 @@ macro_rules! impl_style_shorthands { }); }; } + +#[macro_export] +macro_rules! impl_file_fields { + ($fields:ident) => { + use mlua::UserDataFields; + use $crate::bindings::Cast; + + $fields.add_field_method_get("cha", |lua, me| $crate::cha::Cha::cast(lua, me.cha)); + $fields.add_field_method_get("url", |lua, me| $crate::url::Url::cast(lua, me.url_owned())); + $fields.add_field_method_get("link_to", |lua, me| { + me.link_to.clone().map(|u| $crate::url::Url::cast(lua, u)).transpose() + }); + + $fields.add_field_method_get("name", |lua, me| { + Some(me.name()) + .filter(|s| !s.is_empty()) + .map(|s| lua.create_string(s.as_encoded_bytes())) + .transpose() + }); + }; +} + +#[macro_export] +macro_rules! impl_file_methods { + ($methods:ident) => { + use mlua::UserDataMethods; + + $methods.add_method("icon", |lua, me, ()| { + use yazi_shared::theme::IconCache; + use $crate::bindings::{Cast, Icon}; + + match me.icon.get() { + IconCache::Missing => { + let matched = yazi_config::THEME.icons.matches(me); + me.icon.set(matched.map_or(IconCache::Undefined, IconCache::Icon)); + matched.map(|i| Icon::cast(lua, i)).transpose() + } + IconCache::Undefined => Ok(None), + IconCache::Icon(cached) => Some(Icon::cast(lua, cached)).transpose(), + } + }); + }; +} diff --git a/yazi-plugin/src/process/child.rs b/yazi-plugin/src/process/child.rs index fc740d169..a538341e1 100644 --- a/yazi-plugin/src/process/child.rs +++ b/yazi-plugin/src/process/child.rs @@ -1,4 +1,4 @@ -use std::time::Duration; +use std::{ops::DerefMut, time::Duration}; use futures::future::try_join3; use mlua::{AnyUserData, ExternalError, IntoLua, IntoLuaMulti, Table, UserData, Value}; @@ -24,7 +24,7 @@ impl Child { } impl UserData for Child { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { #[inline] async fn read_line(me: &mut Child) -> (Option>, u8) { async fn read(r: Option) -> Option> { @@ -42,7 +42,7 @@ impl UserData for Child { } } - methods.add_async_method_mut("read", |_, me, len: usize| async move { + methods.add_async_method_mut("read", |_, mut me, len: usize| async move { async fn read(r: Option, len: usize) -> Option> { let mut r = r?; let mut buf = vec![0; len]; @@ -53,53 +53,54 @@ impl UserData for Child { Some(buf) } + let me = me.deref_mut(); Ok(select! { Some(r) = read(me.stdout.as_mut(), len) => (r, 0u8), Some(r) = read(me.stderr.as_mut(), len) => (r, 1u8), else => (vec![], 2u8) }) }); - methods.add_async_method_mut("read_line", |lua, me, ()| async move { - match read_line(me).await { - (Some(b), event) => (lua.create_string(b)?, event).into_lua_multi(lua), - (None, event) => (Value::Nil, event).into_lua_multi(lua), + methods.add_async_method_mut("read_line", |lua, mut me, ()| async move { + match read_line(&mut me).await { + (Some(b), event) => (lua.create_string(b)?, event).into_lua_multi(&lua), + (None, event) => (Value::Nil, event).into_lua_multi(&lua), } }); - methods.add_async_method_mut("read_line_with", |lua, me, options: Table| async move { + methods.add_async_method_mut("read_line_with", |lua, mut me, options: Table| async move { let timeout = Duration::from_millis(options.raw_get("timeout")?); - let Ok(result) = tokio::time::timeout(timeout, read_line(me)).await else { - return (Value::Nil, 3u8).into_lua_multi(lua); + let Ok(result) = tokio::time::timeout(timeout, read_line(&mut me)).await else { + return (Value::Nil, 3u8).into_lua_multi(&lua); }; match result { - (Some(b), event) => (lua.create_string(b)?, event).into_lua_multi(lua), - (None, event) => (Value::Nil, event).into_lua_multi(lua), + (Some(b), event) => (lua.create_string(b)?, event).into_lua_multi(&lua), + (None, event) => (Value::Nil, event).into_lua_multi(&lua), } }); - methods.add_async_method_mut("write_all", |lua, me, src: mlua::String| async move { + methods.add_async_method_mut("write_all", |lua, mut me, src: mlua::String| async move { let Some(stdin) = &mut me.stdin else { return Err("stdin is not piped".into_lua_err()); }; - match stdin.write_all(src.as_bytes()).await { - Ok(()) => (true, Value::Nil).into_lua_multi(lua), - Err(e) => (false, e.raw_os_error()).into_lua_multi(lua), + match stdin.write_all(&src.as_bytes()).await { + Ok(()) => (true, Value::Nil).into_lua_multi(&lua), + Err(e) => (false, e.raw_os_error()).into_lua_multi(&lua), } }); - methods.add_async_method_mut("flush", |lua, me, ()| async move { + methods.add_async_method_mut("flush", |lua, mut me, ()| async move { let Some(stdin) = &mut me.stdin else { return Err("stdin is not piped".into_lua_err()); }; match stdin.flush().await { - Ok(()) => (true, Value::Nil).into_lua_multi(lua), - Err(e) => (false, e.raw_os_error()).into_lua_multi(lua), + Ok(()) => (true, Value::Nil).into_lua_multi(&lua), + Err(e) => (false, e.raw_os_error()).into_lua_multi(&lua), } }); - methods.add_async_method_mut("wait", |lua, me, ()| async move { + methods.add_async_method_mut("wait", |lua, mut me, ()| async move { drop(me.stdin.take()); match me.inner.wait().await { - Ok(status) => (Status::new(status), Value::Nil).into_lua_multi(lua), - Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua), + Ok(status) => (Status::new(status), Value::Nil).into_lua_multi(&lua), + Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua), } }); methods.add_async_function("wait_with_output", |lua, ud: AnyUserData| async move { @@ -126,9 +127,9 @@ impl UserData for Child { match result { Ok((status, stdout, stderr)) => { (Output::new(std::process::Output { status, stdout, stderr }), Value::Nil) - .into_lua_multi(lua) + .into_lua_multi(&lua) } - Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua), + Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua), } }); methods.add_method_mut("start_kill", |lua, me, ()| match me.inner.start_kill() { diff --git a/yazi-plugin/src/process/command.rs b/yazi-plugin/src/process/command.rs index f3ff918e0..7a36e5948 100644 --- a/yazi-plugin/src/process/command.rs +++ b/yazi-plugin/src/process/command.rs @@ -37,7 +37,7 @@ impl Command { } impl UserData for Command { - fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { + fn add_methods>(methods: &mut M) { #[inline] fn make_stdio(v: Value) -> mlua::Result { match v { @@ -66,28 +66,26 @@ impl UserData for Command { } methods.add_function_mut("arg", |_, (ud, arg): (AnyUserData, mlua::String)| { - ud.borrow_mut::()?.inner.arg(arg.to_string_lossy().as_ref()); + ud.borrow_mut::()?.inner.arg(arg.to_string_lossy()); Ok(ud) }); methods.add_function_mut("args", |_, (ud, args): (AnyUserData, Vec)| { { let mut me = ud.borrow_mut::()?; for arg in args { - me.inner.arg(arg.to_string_lossy().as_ref()); + me.inner.arg(arg.to_string_lossy()); } } Ok(ud) }); methods.add_function_mut("cwd", |_, (ud, dir): (AnyUserData, mlua::String)| { - ud.borrow_mut::()?.inner.current_dir(dir.to_str()?); + ud.borrow_mut::()?.inner.current_dir(dir.to_str()?.as_ref()); Ok(ud) }); methods.add_function_mut( "env", |_, (ud, key, value): (AnyUserData, mlua::String, mlua::String)| { - ud.borrow_mut::()? - .inner - .env(key.to_string_lossy().as_ref(), value.to_string_lossy().as_ref()); + ud.borrow_mut::()?.inner.env(key.to_string_lossy(), value.to_string_lossy()); Ok(ud) }, ); @@ -107,16 +105,16 @@ impl UserData for Command { Ok(child) => (Child::new(child), Value::Nil).into_lua_multi(lua), Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua), }); - methods.add_async_method_mut("output", |lua, me, ()| async move { + methods.add_async_method_mut("output", |lua, mut me, ()| async move { match me.inner.output().await { - Ok(output) => (Output::new(output), Value::Nil).into_lua_multi(lua), - Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua), + Ok(output) => (Output::new(output), Value::Nil).into_lua_multi(&lua), + Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua), } }); - methods.add_async_method_mut("status", |lua, me, ()| async move { + methods.add_async_method_mut("status", |lua, mut me, ()| async move { match me.inner.status().await { - Ok(status) => (Status::new(status), Value::Nil).into_lua_multi(lua), - Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua), + Ok(status) => (Status::new(status), Value::Nil).into_lua_multi(&lua), + Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua), } }); } diff --git a/yazi-plugin/src/process/output.rs b/yazi-plugin/src/process/output.rs index 66ef04ce6..421786588 100644 --- a/yazi-plugin/src/process/output.rs +++ b/yazi-plugin/src/process/output.rs @@ -11,7 +11,7 @@ impl Output { } impl UserData for Output { - fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { + fn add_fields>(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)); diff --git a/yazi-plugin/src/process/status.rs b/yazi-plugin/src/process/status.rs index ef7116f20..a81025e0a 100644 --- a/yazi-plugin/src/process/status.rs +++ b/yazi-plugin/src/process/status.rs @@ -9,7 +9,7 @@ impl Status { } impl UserData for Status { - fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) { + fn add_fields>(fields: &mut F) { fields.add_field_method_get("success", |_, me| Ok(me.inner.success())); fields.add_field_method_get("code", |_, me| Ok(me.inner.code())); } diff --git a/yazi-plugin/src/pubsub/mod.rs b/yazi-plugin/src/pubsub/mod.rs index 5d087d043..ce42b0db3 100644 --- a/yazi-plugin/src/pubsub/mod.rs +++ b/yazi-plugin/src/pubsub/mod.rs @@ -1,8 +1,10 @@ #![allow(clippy::module_inception)] +use mlua::Lua; + yazi_macro::mod_flat!(pubsub); -pub(super) fn install(lua: &'static mlua::Lua) -> mlua::Result<()> { +pub(super) fn install(lua: &'static Lua) -> mlua::Result<()> { Pubsub::install(lua)?; Ok(()) diff --git a/yazi-plugin/src/pubsub/pubsub.rs b/yazi-plugin/src/pubsub/pubsub.rs index 220bd8b9e..0ba5476bd 100644 --- a/yazi-plugin/src/pubsub/pubsub.rs +++ b/yazi-plugin/src/pubsub/pubsub.rs @@ -12,7 +12,7 @@ impl Pubsub { ps.raw_set( "pub", lua.create_function(|_, (kind, value): (mlua::String, Value)| { - yazi_dds::Pubsub::pub_(Body::from_lua(kind.to_str()?, value)?); + yazi_dds::Pubsub::pub_(Body::from_lua(&kind.to_str()?, value)?); Ok(()) })?, )?; @@ -20,7 +20,7 @@ impl Pubsub { ps.raw_set( "pub_to", lua.create_function(|_, (receiver, kind, value): (u64, mlua::String, Value)| { - yazi_dds::Pubsub::pub_to(receiver, Body::from_lua(kind.to_str()?, value)?); + yazi_dds::Pubsub::pub_to(receiver, Body::from_lua(&kind.to_str()?, value)?); Ok(()) })?, )?; @@ -32,7 +32,7 @@ impl Pubsub { let Some(cur) = rt.current() else { return Err("`sub()` must be called in a sync plugin").into_lua_err(); }; - if !yazi_dds::Pubsub::sub(cur, kind.to_str()?, f) { + if !yazi_dds::Pubsub::sub(cur, &kind.to_str()?, f) { return Err("`sub()` called twice").into_lua_err(); } Ok(()) @@ -46,7 +46,7 @@ impl Pubsub { let Some(cur) = rt.current() else { return Err("`sub_remote()` must be called in a sync plugin").into_lua_err(); }; - if !yazi_dds::Pubsub::sub_remote(cur, kind.to_str()?, f) { + if !yazi_dds::Pubsub::sub_remote(cur, &kind.to_str()?, f) { return Err("`sub_remote()` called twice").into_lua_err(); } Ok(()) @@ -57,7 +57,7 @@ impl Pubsub { "unsub", lua.create_function(|_, kind: mlua::String| { if let Some(cur) = lua.named_registry_value::("rt")?.current() { - Ok(yazi_dds::Pubsub::unsub(cur, kind.to_str()?)) + Ok(yazi_dds::Pubsub::unsub(cur, &kind.to_str()?)) } else { Err("`unsub()` must be called in a sync plugin").into_lua_err() } @@ -68,7 +68,7 @@ impl Pubsub { "unsub_remote", lua.create_function(|_, kind: mlua::String| { if let Some(cur) = lua.named_registry_value::("rt")?.current() { - Ok(yazi_dds::Pubsub::unsub_remote(cur, kind.to_str()?)) + Ok(yazi_dds::Pubsub::unsub_remote(cur, &kind.to_str()?)) } else { Err("`unsub_remote()` must be called in a sync plugin").into_lua_err() } diff --git a/yazi-plugin/src/runtime.rs b/yazi-plugin/src/runtime.rs index 7a33be183..3f4c8957c 100644 --- a/yazi-plugin/src/runtime.rs +++ b/yazi-plugin/src/runtime.rs @@ -5,7 +5,7 @@ use mlua::{Function, UserData}; #[derive(Default)] pub struct Runtime { frames: VecDeque, - blocks: HashMap>>, + blocks: HashMap>, } struct RuntimeFrame { @@ -13,7 +13,7 @@ struct RuntimeFrame { calls: usize, } -pub type RtRef<'lua> = mlua::UserDataRefMut<'lua, Runtime>; +pub type RtRef = mlua::UserDataRefMut; impl Runtime { pub fn new(id: &str) -> Self { @@ -38,11 +38,11 @@ impl Runtime { }) } - pub fn get_block(&self, id: &str, calls: usize) -> Option> { + pub fn get_block(&self, id: &str, calls: usize) -> Option { self.blocks.get(id).and_then(|v| v.get(calls)).cloned() } - pub fn put_block(&mut self, f: Function<'static>) -> bool { + pub fn put_block(&mut self, f: Function) -> bool { let Some(cur) = self.frames.back() else { return false }; if let Some(v) = self.blocks.get_mut(&cur.id) { v.push(f); diff --git a/yazi-plugin/src/url/mod.rs b/yazi-plugin/src/url/mod.rs index ba07b8b81..4afe04c79 100644 --- a/yazi-plugin/src/url/mod.rs +++ b/yazi-plugin/src/url/mod.rs @@ -1,8 +1,10 @@ #![allow(clippy::module_inception)] +use mlua::Lua; + yazi_macro::mod_flat!(url); -pub fn pour(lua: &mlua::Lua) -> mlua::Result<()> { +pub fn pour(lua: &Lua) -> mlua::Result<()> { url::Url::register(lua)?; url::Url::install(lua)?; diff --git a/yazi-plugin/src/url/url.rs b/yazi-plugin/src/url/url.rs index 125768e87..8cc9d9949 100644 --- a/yazi-plugin/src/url/url.rs +++ b/yazi-plugin/src/url/url.rs @@ -2,7 +2,7 @@ use mlua::{AnyUserData, ExternalError, Lua, MetaMethod, UserDataFields, UserData use crate::bindings::Cast; -pub type UrlRef<'lua> = UserDataRef<'lua, yazi_shared::fs::Url>; +pub type UrlRef = UserDataRef; pub struct Url; @@ -27,7 +27,7 @@ impl Url { }); reg.add_method("join", |lua, me, other: Value| { Self::cast(lua, match other { - Value::String(s) => me.join(s.to_str()?), + Value::String(s) => me.join(s.to_str()?.as_ref()), Value::UserData(ud) => me.join(&*ud.borrow::()?), _ => Err("must be a string or a Url".into_lua_err())?, }) @@ -37,21 +37,21 @@ impl Url { }); reg.add_method("starts_with", |_, me, base: Value| { Ok(match base { - Value::String(s) => me.starts_with(s.to_str()?), + Value::String(s) => me.starts_with(s.to_str()?.as_ref()), Value::UserData(ud) => me.starts_with(&*ud.borrow::()?), _ => 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()?), + Value::String(s) => me.ends_with(s.to_str()?.as_ref()), Value::UserData(ud) => me.ends_with(&*ud.borrow::()?), _ => Err("must be a string or a Url".into_lua_err())?, }) }); reg.add_method("strip_prefix", |lua, me, base: Value| { let path = match base { - Value::String(s) => me.strip_prefix(s.to_str()?), + Value::String(s) => me.strip_prefix(s.to_str()?.as_ref()), Value::UserData(ud) => me.strip_prefix(&*ud.borrow::()?), _ => Err("must be a string or a Url".into_lua_err())?, }; @@ -68,7 +68,7 @@ impl Url { let mut out = Vec::with_capacity(me.len() + other.len()); out.extend_from_slice(me); - out.extend_from_slice(other); + out.extend_from_slice(&other); lua.create_string(out) }); }) @@ -78,7 +78,7 @@ impl Url { lua.globals().raw_set( "Url", lua.create_function(|lua, url: mlua::String| { - Self::cast(lua, yazi_shared::fs::Url::from(url.to_str()?)) + Self::cast(lua, yazi_shared::fs::Url::from(url.to_str()?.as_ref())) })?, ) } diff --git a/yazi-plugin/src/utils/call.rs b/yazi-plugin/src/utils/call.rs index 20faeb517..11d303e1c 100644 --- a/yazi-plugin/src/utils/call.rs +++ b/yazi-plugin/src/utils/call.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use mlua::{ExternalError, Lua, Table, TableExt, Value}; +use mlua::{ExternalError, Lua, ObjectLike, Table, Value}; use tracing::error; use yazi_config::LAYOUT; use yazi_dds::Sendable; @@ -43,15 +43,15 @@ impl Utils { let id = id.to_str()?; let mut layout = LAYOUT.get(); - match id { - "current" => layout.current = *c.raw_get::<_, crate::elements::Rect>("_area")?, - "preview" => layout.preview = *c.raw_get::<_, crate::elements::Rect>("_area")?, - "progress" => layout.progress = *c.raw_get::<_, crate::elements::Rect>("_area")?, + match id.as_ref() { + "current" => layout.current = *c.raw_get::("_area")?, + "preview" => layout.preview = *c.raw_get::("_area")?, + "progress" => layout.progress = *c.raw_get::("_area")?, _ => {} } LAYOUT.set(layout); - match c.call_method::<_, Table>("redraw", ()) { + match c.call_method::
("redraw", ()) { Err(e) => { error!("Failed to `redraw()` the `{id}` component:\n{e}"); lua.create_table() diff --git a/yazi-plugin/src/utils/image.rs b/yazi-plugin/src/utils/image.rs index 9dfc388a4..5021c9ff2 100644 --- a/yazi-plugin/src/utils/image.rs +++ b/yazi-plugin/src/utils/image.rs @@ -10,9 +10,9 @@ impl Utils { "image_show", lua.create_async_function(|lua, (url, rect): (UrlRef, Rect)| async move { if let Ok(area) = ADAPTOR.image_show(&url, *rect).await { - Rect::from(area).into_lua(lua) + Rect::from(area).into_lua(&lua) } else { - Value::Nil.into_lua(lua) + Value::Nil.into_lua(&lua) } })?, )?; diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index 587fbfc6c..374e94ac9 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -15,12 +15,12 @@ impl Utils { fn parse_keys(value: Value) -> mlua::Result> { Ok(match value { Value::String(s) => { - vec![Key::from_str(s.to_str()?).into_lua_err()?] + vec![Key::from_str(&s.to_str()?).into_lua_err()?] } Value::Table(t) => { let mut v = Vec::with_capacity(10); for s in t.sequence_values::() { - v.push(Key::from_str(s?.to_str()?).into_lua_err()?); + v.push(Key::from_str(&s?.to_str()?).into_lua_err()?); } v } @@ -35,7 +35,7 @@ impl Utils { let (tx, mut rx) = mpsc::channel::(1); let mut cands = Vec::with_capacity(30); - for (i, cand) in t.raw_get::<_, Table>("cands")?.sequence_values::
().enumerate() { + for (i, cand) in t.raw_get::
("cands")?.sequence_values::
().enumerate() { let cand = cand?; cands.push(Chord { on: Self::parse_keys(cand.raw_get("on")?)?, @@ -65,24 +65,24 @@ impl Utils { title: t.raw_get("title")?, value: t.raw_get("value").unwrap_or_default(), cursor: None, // TODO - position: Position::try_from(t.raw_get::<_, Table>("position")?)?.into(), + position: Position::try_from(t.raw_get::
("position")?)?.into(), realtime, completion: false, highlight: false, })); if !realtime { - return InputRx::consume(rx).await.into_lua_multi(lua); + return InputRx::consume(rx).await.into_lua_multi(&lua); } - let debounce = t.raw_get::<_, f64>("debounce").unwrap_or_default(); + let debounce = t.raw_get::("debounce").unwrap_or_default(); if debounce < 0.0 { Err("negative debounce duration".into_lua_err()) } else if debounce == 0.0 { - (InputRx::new(rx), Value::Nil).into_lua_multi(lua) + (InputRx::new(rx), Value::Nil).into_lua_multi(&lua) } else { (InputRx::new(Debounce::new(rx, Duration::from_secs_f64(debounce))), Value::Nil) - .into_lua_multi(lua) + .into_lua_multi(&lua) } })?, )?; diff --git a/yazi-plugin/src/utils/preview.rs b/yazi-plugin/src/utils/preview.rs index ee08fbb69..5ce720bb7 100644 --- a/yazi-plugin/src/utils/preview.rs +++ b/yazi-plugin/src/utils/preview.rs @@ -16,7 +16,7 @@ pub struct PreviewLock { pub data: Vec>, } -impl<'a> TryFrom> for PreviewLock { +impl TryFrom
for PreviewLock { type Error = mlua::Error; fn try_from(t: Table) -> Result { @@ -43,9 +43,9 @@ impl Utils { let inner = match Highlighter::new(&lock.url).highlight(lock.skip, *area).await { Ok(text) => text, - Err(e @ PeekError::Exceed(max)) => return (e.to_string(), max).into_lua_multi(lua), + Err(e @ PeekError::Exceed(max)) => return (e.to_string(), max).into_lua_multi(&lua), Err(e @ PeekError::Unexpected(_)) => { - return (e.to_string(), Value::Nil).into_lua_multi(lua); + return (e.to_string(), Value::Nil).into_lua_multi(&lua); } }; @@ -56,7 +56,7 @@ impl Utils { })]; emit!(Call(Cmd::new("update_peeked").with_any("lock", lock), Layer::Manager)); - (Value::Nil, Value::Nil).into_lua_multi(lua) + (Value::Nil, Value::Nil).into_lua_multi(&lua) })?, )?; diff --git a/yazi-plugin/src/utils/sync.rs b/yazi-plugin/src/utils/sync.rs index 3bddf3dea..9af522496 100644 --- a/yazi-plugin/src/utils/sync.rs +++ b/yazi-plugin/src/utils/sync.rs @@ -11,7 +11,7 @@ impl Utils { pub(super) fn sync(lua: &'static Lua, ya: &Table) -> mlua::Result<()> { ya.raw_set( "sync", - lua.create_function(|lua, f: Function<'static>| { + lua.create_function(|lua, f: Function| { let mut rt = lua.named_registry_value::("rt")?; if !rt.put_block(f.clone()) { return Err("`ya.sync()` must be called in a plugin").into_lua_err(); @@ -20,7 +20,7 @@ impl Utils { let cur = rt.current().unwrap().to_owned(); lua.create_function(move |lua, mut args: MultiValue| { args.push_front(Value::Table(LOADER.try_load(lua, &cur)?)); - f.call::<_, MultiValue>(args) + f.call::(args) }) })?, )?; @@ -38,7 +38,7 @@ impl Utils { lua.create_async_function(move |lua, args: MultiValue| async move { if let Some(cur) = lua.named_registry_value::("rt")?.current() { - Sendable::list_to_values(lua, Self::retrieve(cur, block, args).await?) + Sendable::list_to_values(&lua, Self::retrieve(cur, block, args).await?) } else { Err("block spawned by `ya.sync()` must be called in a plugin").into_lua_err() } @@ -49,7 +49,7 @@ impl Utils { Ok(()) } - async fn retrieve(id: &str, calls: usize, args: MultiValue<'_>) -> mlua::Result> { + async fn retrieve(id: &str, calls: usize, args: MultiValue) -> mlua::Result> { let args = Sendable::values_to_vec(args)?; let (tx, rx) = oneshot::channel::>(); @@ -65,7 +65,8 @@ impl Utils { .chain(args.into_iter().map(|d| Sendable::data_to_value(lua, d))) .collect::>()?; - let values = Sendable::values_to_vec(block.call(MultiValue::from_vec(args))?)?; + // TODO: avoid unnecessary allocation + let values = Sendable::values_to_vec(block.call(MultiValue::from_iter(args))?)?; tx.send(values).map_err(|_| "send failed".into_lua_err()) }) }; diff --git a/yazi-plugin/src/utils/text.rs b/yazi-plugin/src/utils/text.rs index 83ce73f2e..74f626ab8 100644 --- a/yazi-plugin/src/utils/text.rs +++ b/yazi-plugin/src/utils/text.rs @@ -26,13 +26,14 @@ impl Utils { ya.raw_set( "quote", - lua.create_function(|_, (s, unix): (mlua::String, Option)| { + lua.create_function(|lua, (s, unix): (mlua::String, Option)| { + let s = s.to_str()?; let s = match unix { - Some(true) => yazi_shared::shell::escape_unix(s.to_str()?), - Some(false) => yazi_shared::shell::escape_windows(s.to_str()?), - None => yazi_shared::shell::escape_native(s.to_str()?), + Some(true) => yazi_shared::shell::escape_unix(s.as_ref()), + Some(false) => yazi_shared::shell::escape_windows(s.as_ref()), + None => yazi_shared::shell::escape_native(s.as_ref()), }; - Ok(s.into_owned()) + lua.create_string(s.as_ref()) })?, )?; diff --git a/yazi-plugin/src/utils/utils.rs b/yazi-plugin/src/utils/utils.rs index 929284c81..8cc7164de 100644 --- a/yazi-plugin/src/utils/utils.rs +++ b/yazi-plugin/src/utils/utils.rs @@ -1,9 +1,11 @@ +use mlua::Lua; + #[cfg(unix)] pub(super) static HOSTNAME_CACHE: std::sync::OnceLock> = std::sync::OnceLock::new(); pub(super) struct Utils; -pub fn install(lua: &'static mlua::Lua) -> mlua::Result<()> { +pub fn install(lua: &'static Lua) -> mlua::Result<()> { let ya = lua.create_table()?; Utils::app(lua, &ya)?; @@ -22,7 +24,7 @@ pub fn install(lua: &'static mlua::Lua) -> mlua::Result<()> { lua.globals().raw_set("ya", ya) } -pub fn install_isolate(lua: &mlua::Lua) -> mlua::Result<()> { +pub fn install_isolate(lua: &Lua) -> mlua::Result<()> { let ya = lua.create_table()?; Utils::app(lua, &ya)?; diff --git a/yazi-proxy/src/options/notify.rs b/yazi-proxy/src/options/notify.rs index bded3d233..3eaba76e9 100644 --- a/yazi-proxy/src/options/notify.rs +++ b/yazi-proxy/src/options/notify.rs @@ -18,16 +18,16 @@ impl TryFrom for NotifyOpt { fn try_from(mut c: Cmd) -> Result { c.take_any("option").ok_or(()) } } -impl<'a> TryFrom> for NotifyOpt { +impl TryFrom for NotifyOpt { type Error = mlua::Error; fn try_from(t: mlua::Table) -> Result { - let timeout = t.raw_get::<_, f64>("timeout")?; + let timeout = t.raw_get("timeout")?; if timeout < 0.0 { return Err("timeout must be non-negative".into_lua_err()); } - let level = if let Ok(s) = t.raw_get::<_, mlua::String>("level") { + let level = if let Ok(s) = t.raw_get::("level") { s.to_str()?.parse().into_lua_err()? } else { Default::default() diff --git a/yazi-shared/src/fs/file.rs b/yazi-shared/src/fs/file.rs index 41e1bf0a1..7e90809f9 100644 --- a/yazi-shared/src/fs/file.rs +++ b/yazi-shared/src/fs/file.rs @@ -21,11 +21,6 @@ impl Deref for File { fn deref(&self) -> &Self::Target { &self.cha } } -impl AsRef for File { - #[inline] - fn as_ref(&self) -> &File { self } -} - impl File { #[inline] pub async fn from(url: Url) -> Result { diff --git a/yazi-shared/src/ro_cell.rs b/yazi-shared/src/ro_cell.rs index e5c830fde..2667355b2 100644 --- a/yazi-shared/src/ro_cell.rs +++ b/yazi-shared/src/ro_cell.rs @@ -11,6 +11,9 @@ impl RoCell { #[inline] pub const fn new() -> Self { Self(UnsafeCell::new(None)) } + #[inline] + pub const fn new_const(value: T) -> Self { Self(UnsafeCell::new(Some(value))) } + #[inline] pub fn init(&self, value: T) { debug_assert!(!self.initialized());