diff --git a/Cargo.lock b/Cargo.lock index 2ad2822a..9f54b156 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1935,9 +1935,9 @@ dependencies = [ [[package]] name = "imgref" -version = "1.12.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40fac9d56ed6437b198fddba683305e8e2d651aa42647f00f5ae542e7f5c94a2" +checksum = "89194689a993ab15268672e99e7b0e19da2da3268ac682e8f02d29d4d1434cd7" [[package]] name = "indexmap" @@ -3337,9 +3337,8 @@ checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] name = "ratatui" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1ce67fb8ba4446454d1c8dbaeda0557ff5e94d39d5e5ed7f10a65eb4c8266bc" +version = "0.30.1" +source = "git+https://github.com/yazi-rs/ratatui.git?rev=a1c4922a242861d755163ae85d7e41b85ed277d2#a1c4922a242861d755163ae85d7e41b85ed277d2" dependencies = [ "instability", "ratatui-core", @@ -3353,8 +3352,7 @@ dependencies = [ [[package]] name = "ratatui-core" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3603f354bba8c595fa47860e60142d7372b7210c27044c6a7d0e1a4336b44" +source = "git+https://github.com/yazi-rs/ratatui.git?rev=a1c4922a242861d755163ae85d7e41b85ed277d2#a1c4922a242861d755163ae85d7e41b85ed277d2" dependencies = [ "bitflags 2.13.0", "compact_str", @@ -3366,7 +3364,7 @@ dependencies = [ "lru", "palette", "serde", - "strum 0.28.0", + "strum", "thiserror 2.0.18", "unicode-segmentation", "unicode-truncate", @@ -3376,8 +3374,7 @@ dependencies = [ [[package]] name = "ratatui-crossterm" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2867bedcbd6a690ca4f8672a687b730ec07660c79844517b084311b529980c" +source = "git+https://github.com/yazi-rs/ratatui.git?rev=a1c4922a242861d755163ae85d7e41b85ed277d2#a1c4922a242861d755163ae85d7e41b85ed277d2" dependencies = [ "cfg-if", "crossterm 0.28.1", @@ -3389,8 +3386,7 @@ dependencies = [ [[package]] name = "ratatui-termion" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c16cc35a9d9114e0b2bb4b22018b96ae7f5fe60e2595dc73e622b4e78624835" +source = "git+https://github.com/yazi-rs/ratatui.git?rev=a1c4922a242861d755163ae85d7e41b85ed277d2#a1c4922a242861d755163ae85d7e41b85ed277d2" dependencies = [ "instability", "ratatui-core", @@ -3400,8 +3396,7 @@ dependencies = [ [[package]] name = "ratatui-termwiz" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "386b8ff8f74ed749509391c56d549761a2fcdb408e1f42e467286bcb7dac8967" +source = "git+https://github.com/yazi-rs/ratatui.git?rev=a1c4922a242861d755163ae85d7e41b85ed277d2#a1c4922a242861d755163ae85d7e41b85ed277d2" dependencies = [ "ratatui-core", "termwiz", @@ -3409,19 +3404,18 @@ dependencies = [ [[package]] name = "ratatui-widgets" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db" +version = "0.3.1" +source = "git+https://github.com/yazi-rs/ratatui.git?rev=a1c4922a242861d755163ae85d7e41b85ed277d2#a1c4922a242861d755163ae85d7e41b85ed277d2" dependencies = [ "bitflags 2.13.0", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "indoc", "instability", "itertools", "line-clipping", "ratatui-core", "serde", - "strum 0.27.2", + "strum", "time", "unicode-segmentation", "unicode-width", @@ -4221,34 +4215,13 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" -dependencies = [ - "strum_macros 0.27.2", -] - [[package]] name = "strum" version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" dependencies = [ - "strum_macros 0.28.0", -] - -[[package]] -name = "strum_macros" -version = "0.27.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.117", + "strum_macros", ] [[package]] @@ -5131,9 +5104,9 @@ dependencies = [ [[package]] name = "which" -version = "8.0.2" +version = "8.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81995fafaaaf6ae47a7d0cc83c67caf92aeb7e5331650ae6ff856f7c0c60c459" +checksum = "c789537cf2f7f55be8e6192f92e464174ee55f91af622777f7f1ceb0dbccd03e" dependencies = [ "libc", ] @@ -5674,7 +5647,7 @@ dependencies = [ "palette", "quantette", "ratatui", - "strum 0.28.0", + "strum", "tokio", "tracing", "yazi-config", @@ -5695,8 +5668,10 @@ dependencies = [ "anyhow", "futures", "hashbrown 0.17.1", + "inventory", "libc", "mlua", + "ordered-float 5.3.0", "paste", "ratatui", "serde_json", @@ -5797,7 +5772,7 @@ dependencies = [ "regex", "serde", "serde_with", - "strum 0.28.0", + "strum", "tokio", "toml", "tracing", @@ -5823,7 +5798,7 @@ dependencies = [ "ratatui", "serde", "serde_with", - "strum 0.28.0", + "strum", "syntect", "tokio", "tokio-stream", @@ -5856,7 +5831,6 @@ dependencies = [ "indexmap 2.14.0", "inventory", "mlua", - "ordered-float 5.3.0", "parking_lot", "paste", "serde", @@ -5966,7 +5940,7 @@ dependencies = [ "regex", "scopeguard", "serde", - "strum 0.28.0", + "strum", "tokio", "tracing", "trash", @@ -5999,7 +5973,7 @@ dependencies = [ "ratatui", "serde", "serde_with", - "strum 0.28.0", + "strum", "tokio", "yazi-binding", "yazi-boot", @@ -6089,7 +6063,6 @@ dependencies = [ "tracing", "yazi-binding", "yazi-config", - "yazi-dds", "yazi-fs", "yazi-macro", "yazi-shared", @@ -6111,7 +6084,7 @@ dependencies = [ "ordered-float 5.3.0", "parking_lot", "serde", - "strum 0.28.0", + "strum", "tokio", "tracing", "yazi-binding", @@ -6156,7 +6129,7 @@ dependencies = [ "percent-encoding", "serde", "serde_with", - "strum 0.28.0", + "strum", "thiserror 2.0.18", "tokio", "typed-path", @@ -6199,7 +6172,7 @@ dependencies = [ "rustix 1.1.4", "serde", "signal-hook 0.4.4", - "strum 0.28.0", + "strum", "thiserror 2.0.18", "tokio", "windows-sys 0.61.2", diff --git a/Cargo.toml b/Cargo.toml index 1056c8b0..8e5b77ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ parking_lot = "0.12.5" paste = "1.0.15" percent-encoding = "2.3.2" rand = { version = "0.10.1", default-features = false, features = [ "std", "sys_rng" ] } -ratatui = { version = "=0.30.0", default-features = false, features = [ "layout-cache", "serde", "underline-color", "unstable-rendered-line-info", "unstable-widget-ref" ] } +ratatui = { version = "0.30.1", default-features = false, features = [ "std", "layout-cache", "serde", "underline-color", "unstable-rendered-line-info", "unstable-widget-ref" ] } regex = "1.12.3" russh = { version = "0.61.2", default-features = false, features = [ "ring", "rsa" ] } scopeguard = "1.2.0" @@ -91,3 +91,8 @@ module_inception = "allow" option_map_unit_fn = "allow" unit_arg = "allow" use_self = "warn" + +[patch.crates-io] +ratatui = { git = "https://github.com/yazi-rs/ratatui.git", package = "ratatui", rev = "a1c4922a242861d755163ae85d7e41b85ed277d2" } +ratatui-core = { git = "https://github.com/yazi-rs/ratatui.git", package = "ratatui-core", rev = "a1c4922a242861d755163ae85d7e41b85ed277d2" } +ratatui-widgets = { git = "https://github.com/yazi-rs/ratatui.git", package = "ratatui-widgets", rev = "a1c4922a242861d755163ae85d7e41b85ed277d2" } diff --git a/nix/yazi-unwrapped.nix b/nix/yazi-unwrapped.nix index bba98fbf..543a6470 100644 --- a/nix/yazi-unwrapped.nix +++ b/nix/yazi-unwrapped.nix @@ -28,6 +28,9 @@ rustPlatform.buildRustPackage (finalAttrs: { cargoLock = { lockFile = "${src}/Cargo.lock"; + outputHashes = { + "ratatui-0.30.1" = "sha256-wkEOgwAhW0ObtPDlJmOOoY5qf9c/P79ktN4b43jtcGw="; + }; }; env = { @@ -72,7 +75,7 @@ rustPlatform.buildRustPackage (finalAttrs: { hash = "sha256-kEVXejDg4ChFoMNBvKlwdFEyUuTcY2VuK9j0PdafKus="; }; }; - + meta = { description = "Blazing fast terminal file manager written in Rust, based on async I/O"; diff --git a/yazi-actor/src/app/lua.rs b/yazi-actor/src/app/lua.rs index 65a50abf..a2c793b1 100644 --- a/yazi-actor/src/app/lua.rs +++ b/yazi-actor/src/app/lua.rs @@ -1,6 +1,5 @@ use anyhow::Result; -use yazi_binding::runtime_scope; -use yazi_dds::Sendable; +use yazi_binding::{Sendable, runtime_scope}; use yazi_macro::succ; use yazi_parser::app::LuaForm; use yazi_plugin::LUA; diff --git a/yazi-actor/src/lives/file.rs b/yazi-actor/src/lives/file.rs index 3f259675..1aebfff2 100644 --- a/yazi-actor/src/lives/file.rs +++ b/yazi-actor/src/lives/file.rs @@ -1,7 +1,7 @@ use std::{ops::Deref, ptr}; -use mlua::{AnyUserData, IntoLua, UserData, UserDataFields, UserDataMethods, Value}; -use yazi_binding::{Range, Style, cached_field}; +use mlua::{AnyUserData, IntoLua, UserData, UserDataFields, UserDataMethods}; +use yazi_binding::{Range, Style}; use yazi_config::THEME; use yazi_shared::{path::AsPath, url::UrlLike}; @@ -12,16 +12,6 @@ pub(super) struct File { idx: usize, folder: PtrCell, tab: PtrCell, - - v_cha: Option, - v_url: Option, - v_link_to: Option, - - v_name: Option, - v_path: Option, - v_cache: Option, - - v_bare: Option, } impl Deref for File { @@ -45,21 +35,7 @@ impl File { Ok(match super::FILE_CACHE.borrow_mut().entry(PtrCell(&folder.files[idx])) { Entry::Occupied(oe) => oe.into_mut().clone(), Entry::Vacant(ve) => { - let ud = Lives::scoped_userdata(Self { - idx, - folder: folder.into(), - tab: tab.into(), - - v_cha: None, - v_url: None, - v_link_to: None, - - v_name: None, - v_path: None, - v_cache: None, - - v_bare: None, - })?; + let ud = Lives::scoped_userdata(Self { idx, folder: folder.into(), tab: tab.into() })?; ve.insert(ud.clone()); ud } @@ -73,7 +49,7 @@ impl File { impl UserData for File { fn add_fields>(fields: &mut F) { yazi_binding::impl_file_fields!(fields); - cached_field!(fields, bare, |_, me| Ok(yazi_binding::File::new(&**me))); + fields.add_cached_field("bare", |_, me| Ok(yazi_binding::File::new(&**me))); fields.add_field_method_get("idx", |_, me| Ok(me.idx + 1)); fields.add_field_method_get("is_hovered", |_, me| Ok(me.is_hovered())); diff --git a/yazi-actor/src/lives/files.rs b/yazi-actor/src/lives/files.rs index 884f03dc..e67998ae 100644 --- a/yazi-actor/src/lives/files.rs +++ b/yazi-actor/src/lives/files.rs @@ -1,7 +1,7 @@ use std::ops::{Deref, Range}; -use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods, Value}; -use yazi_binding::cached_field; +use mlua::{AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMethods}; +use yazi_shim::mlua::UserDataFieldsExt; use super::{File, Filter, Lives, PtrCell}; @@ -9,8 +9,6 @@ pub(super) struct Files { window: Range, folder: PtrCell, tab: PtrCell, - - v_filter: Option, } impl Deref for Files { @@ -25,13 +23,13 @@ impl Files { folder: &yazi_core::tab::Folder, tab: &yazi_core::tab::Tab, ) -> mlua::Result { - Lives::scoped_userdata(Self { window, folder: folder.into(), tab: tab.into(), v_filter: None }) + Lives::scoped_userdata(Self { window, folder: folder.into(), tab: tab.into() }) } } impl UserData for Files { fn add_fields>(fields: &mut F) { - cached_field!(fields, filter, |_, me| me.filter().map(Filter::make).transpose()); + fields.add_static_field("filter", |_, me| me.filter().map(Filter::make).transpose()); } fn add_methods>(methods: &mut M) { diff --git a/yazi-actor/src/lives/folder.rs b/yazi-actor/src/lives/folder.rs index ab4ed872..c6f59d6e 100644 --- a/yazi-actor/src/lives/folder.rs +++ b/yazi-actor/src/lives/folder.rs @@ -1,8 +1,9 @@ use std::ops::{Deref, Range}; -use mlua::{AnyUserData, UserData, UserDataFields, Value}; -use yazi_binding::{FolderStage, Url, cached_field}; +use mlua::{AnyUserData, UserData, UserDataFields}; +use yazi_binding::{FolderStage, Url}; use yazi_config::LAYOUT; +use yazi_shim::mlua::UserDataFieldsExt; use super::{File, Files, Lives, PtrCell}; @@ -10,12 +11,6 @@ pub(super) struct Folder { window: Range, inner: PtrCell, tab: PtrCell, - - v_cwd: Option, - v_files: Option, - v_stage: Option, - v_window: Option, - v_hovered: Option, } impl Deref for Folder { @@ -38,30 +33,20 @@ impl Folder { } }; - Lives::scoped_userdata(Self { - window, - inner: inner.into(), - tab: tab.into(), - - v_cwd: None, - v_files: None, - v_stage: None, - v_window: None, - v_hovered: None, - }) + Lives::scoped_userdata(Self { window, inner: inner.into(), tab: tab.into() }) } } impl UserData for Folder { fn add_fields>(fields: &mut F) { - cached_field!(fields, cwd, |_, me| Ok(Url::new(&me.url))); - cached_field!(fields, files, |_, me| Files::make(0..me.files.len(), me, &me.tab)); - cached_field!(fields, stage, |_, me| Ok(FolderStage::new(me.stage.clone()))); - cached_field!(fields, window, |_, me| Files::make(me.window.clone(), me, &me.tab)); + fields.add_cached_field("cwd", |_, me| Ok(Url::new(&me.url))); + fields.add_static_field("files", |_, me| Files::make(0..me.files.len(), me, &me.tab)); + fields.add_cached_field("stage", |_, me| Ok(FolderStage::new(me.stage.clone()))); + fields.add_static_field("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)); - cached_field!(fields, hovered, |_, me| { + fields.add_static_field("hovered", |_, me| { me.hovered().map(|_| File::make(me.cursor, me, &me.tab)).transpose() }); } diff --git a/yazi-actor/src/lives/preference.rs b/yazi-actor/src/lives/preference.rs index 011a8c64..db772993 100644 --- a/yazi-actor/src/lives/preference.rs +++ b/yazi-actor/src/lives/preference.rs @@ -1,18 +1,12 @@ use std::ops::Deref; -use mlua::{AnyUserData, UserData, UserDataFields, Value}; -use yazi_binding::cached_field; -use yazi_shim::strum::IntoStr; +use mlua::{AnyUserData, UserData, UserDataFields}; +use yazi_shim::{mlua::UserDataFieldsExt, strum::IntoStr}; use super::{Lives, PtrCell}; pub(super) struct Preference { inner: PtrCell, - - v_name: Option, - v_linemode: Option, - - v_sort_by: Option, } impl Deref for Preference { @@ -23,26 +17,19 @@ impl Deref for Preference { impl Preference { pub(super) fn make(inner: &yazi_core::tab::Preference) -> mlua::Result { - Lives::scoped_userdata(Self { - inner: inner.into(), - - v_name: None, - v_linemode: None, - - v_sort_by: None, - }) + Lives::scoped_userdata(Self { inner: inner.into() }) } } impl UserData for Preference { fn add_fields>(fields: &mut F) { // Display - cached_field!(fields, name, |lua, me| lua.create_string(&me.name)); - cached_field!(fields, linemode, |lua, me| lua.create_string(&*me.linemode)); + fields.add_cached_field("name", |lua, me| lua.create_string(&me.name)); + fields.add_cached_field("linemode", |lua, me| lua.create_string(&*me.linemode)); fields.add_field_method_get("show_hidden", |_, me| Ok(me.show_hidden)); // Sorting - cached_field!(fields, sort_by, |_, me| Ok(me.sort_by.into_str())); + fields.add_cached_field("sort_by", |_, me| Ok(me.sort_by.into_str())); 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)); diff --git a/yazi-actor/src/lives/preview.rs b/yazi-actor/src/lives/preview.rs index 30a4a1c1..fee0997e 100644 --- a/yazi-actor/src/lives/preview.rs +++ b/yazi-actor/src/lives/preview.rs @@ -1,15 +1,13 @@ use std::ops::Deref; -use mlua::{AnyUserData, UserData, UserDataFields, Value}; -use yazi_binding::cached_field; +use mlua::{AnyUserData, UserData, UserDataFields}; use yazi_config::LAYOUT; +use yazi_shim::mlua::UserDataFieldsExt; use super::{Folder, Lives, PtrCell}; pub(super) struct Preview { tab: PtrCell, - - v_folder: Option, } impl Deref for Preview { @@ -20,14 +18,14 @@ impl Deref for Preview { impl Preview { pub(super) fn make(tab: &yazi_core::tab::Tab) -> mlua::Result { - Lives::scoped_userdata(Self { tab: tab.into(), v_folder: None }) + Lives::scoped_userdata(Self { tab: tab.into() }) } } impl UserData for Preview { fn add_fields>(fields: &mut F) { fields.add_field_method_get("skip", |_, me| Ok(me.skip)); - cached_field!(fields, folder, |_, me| { + fields.add_static_field("folder", |_, me| { me.tab .hovered_folder() .map(|f| { diff --git a/yazi-actor/src/lives/tab.rs b/yazi-actor/src/lives/tab.rs index 69d5abb0..33571779 100644 --- a/yazi-actor/src/lives/tab.rs +++ b/yazi-actor/src/lives/tab.rs @@ -1,21 +1,13 @@ use std::{borrow::Cow, ops::Deref}; -use mlua::{AnyUserData, UserData, UserDataFields, UserDataMethods, Value}; -use yazi_binding::{Id, UrlRef, cached_field}; +use mlua::{AnyUserData, UserData, UserDataFields, UserDataMethods}; +use yazi_binding::{Id, UrlRef}; +use yazi_shim::mlua::UserDataFieldsExt; use super::{Finder, Folder, Lives, Mode, Preference, Preview, PtrCell, Selected}; pub(super) struct Tab { inner: PtrCell, - - v_name: Option, - v_mode: Option, - v_pref: Option, - v_current: Option, - v_parent: Option, - v_selected: Option, - v_preview: Option, - v_finder: Option, } impl Deref for Tab { @@ -26,42 +18,29 @@ impl Deref for Tab { impl Tab { pub(super) fn make(inner: &yazi_core::tab::Tab) -> mlua::Result { - Lives::scoped_userdata(Self { - inner: inner.into(), - - v_name: None, - v_mode: None, - v_pref: None, - v_current: None, - v_parent: None, - v_selected: None, - v_preview: None, - v_finder: None, - }) + Lives::scoped_userdata(Self { inner: inner.into() }) } } impl UserData for Tab { fn add_fields>(fields: &mut F) { fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); - cached_field!(fields, name, |lua, me| { - match me.name() { - Cow::Borrowed(s) => lua.create_string(s), - Cow::Owned(s) => lua.create_external_string(s), - } + fields.add_cached_field("name", |lua, me| match me.name() { + Cow::Borrowed(s) => lua.create_string(s), + Cow::Owned(s) => lua.create_external_string(s), }); - cached_field!(fields, mode, |_, me| Mode::make(&me.mode)); - cached_field!(fields, pref, |_, me| Preference::make(&me.pref)); - cached_field!(fields, current, |_, me| Folder::make(None, &me.current, me)); - cached_field!(fields, parent, |_, me| { + fields.add_static_field("mode", |_, me| Mode::make(&me.mode)); + fields.add_static_field("pref", |_, me| Preference::make(&me.pref)); + fields.add_static_field("current", |_, me| Folder::make(None, &me.current, me)); + fields.add_static_field("parent", |_, me| { me.parent.as_ref().map(|f| Folder::make(None, f, me)).transpose() }); - cached_field!(fields, selected, |_, me| Selected::make(&me.selected)); + fields.add_static_field("selected", |_, me| Selected::make(&me.selected)); - cached_field!(fields, preview, |_, me| Preview::make(me)); - cached_field!(fields, finder, |_, me| me.finder.as_ref().map(Finder::make).transpose()); + fields.add_static_field("preview", |_, me| Preview::make(me)); + fields.add_static_field("finder", |_, me| me.finder.as_ref().map(Finder::make).transpose()); } fn add_methods>(methods: &mut M) { diff --git a/yazi-actor/src/lives/task.rs b/yazi-actor/src/lives/task.rs index 7deaae8e..ca465a01 100644 --- a/yazi-actor/src/lives/task.rs +++ b/yazi-actor/src/lives/task.rs @@ -1,16 +1,14 @@ use std::ops::Deref; -use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields, Value}; -use yazi_binding::{SER_OPT, cached_field}; +use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields}; +use yazi_binding::SER_OPT; use yazi_scheduler::Progress; +use yazi_shim::mlua::UserDataFieldsExt; use super::{Lives, PtrCell}; pub(super) struct TaskSnap { inner: PtrCell, - - v_title: Option, - v_prog: Option, } impl Deref for TaskSnap { @@ -21,14 +19,14 @@ impl Deref for TaskSnap { impl TaskSnap { pub(super) fn make(inner: &yazi_scheduler::TaskSnap) -> mlua::Result { - Lives::scoped_userdata(Self { inner: inner.into(), v_title: None, v_prog: None }) + Lives::scoped_userdata(Self { inner: inner.into() }) } } impl UserData for TaskSnap { fn add_fields>(fields: &mut F) { - cached_field!(fields, title, |lua, me| lua.create_string(&me.title)); - cached_field!(fields, prog, |lua, me| lua.to_value_with(&me.prog, SER_OPT)); + fields.add_cached_field("title", |lua, me| lua.create_string(&me.title)); + fields.add_cached_field("prog", |lua, me| lua.to_value_with(&me.prog, SER_OPT)); fields.add_field_method_get("running", |_, me| Ok(me.prog.running())); fields.add_field_method_get("cooked", |_, me| Ok(me.prog.cooked())); diff --git a/yazi-actor/src/lives/tasks.rs b/yazi-actor/src/lives/tasks.rs index b19da6cb..d6c31dce 100644 --- a/yazi-actor/src/lives/tasks.rs +++ b/yazi-actor/src/lives/tasks.rs @@ -1,17 +1,14 @@ use std::ops::Deref; -use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields, Value}; -use yazi_binding::{SER_OPT, cached_field}; +use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields}; +use yazi_binding::SER_OPT; +use yazi_shim::mlua::UserDataFieldsExt; use super::{Lives, PtrCell}; use crate::lives::{Behavior, TaskSnap}; pub(super) struct Tasks { inner: PtrCell, - - v_behavior: Option, - v_snaps: Option, - v_summary: Option, } impl Deref for Tasks { @@ -22,13 +19,7 @@ impl Deref for Tasks { impl Tasks { pub(super) fn make(inner: &yazi_core::tasks::Tasks) -> mlua::Result { - Lives::scoped_userdata(Self { - inner: inner.into(), - - v_behavior: None, - v_snaps: None, - v_summary: None, - }) + Lives::scoped_userdata(Self { inner: inner.into() }) } } @@ -36,9 +27,9 @@ impl UserData for Tasks { fn add_fields>(fields: &mut F) { fields.add_field_method_get("cursor", |_, me| Ok(me.cursor)); - cached_field!(fields, behavior, |_, me| Behavior::make(&me.scheduler.behavior)); + fields.add_static_field("behavior", |_, me| Behavior::make(&me.scheduler.behavior)); - cached_field!(fields, snaps, |lua, me| { + fields.add_static_field("snaps", |lua, me| { let tbl = lua.create_table_with_capacity(me.snaps.len(), 0)?; for snap in &me.snaps { tbl.raw_push(TaskSnap::make(snap)?)?; @@ -46,6 +37,6 @@ impl UserData for Tasks { Ok(tbl) }); - cached_field!(fields, summary, |lua, me| lua.to_value_with(&me.summary, SER_OPT)); + fields.add_cached_field("summary", |lua, me| lua.to_value_with(&me.summary, SER_OPT)); } } diff --git a/yazi-actor/src/lives/which.rs b/yazi-actor/src/lives/which.rs index e44281aa..8046728a 100644 --- a/yazi-actor/src/lives/which.rs +++ b/yazi-actor/src/lives/which.rs @@ -1,15 +1,12 @@ use std::ops::Deref; -use mlua::{AnyUserData, UserData, UserDataFields, Value}; -use yazi_binding::cached_field; +use mlua::{AnyUserData, UserData, UserDataFields}; +use yazi_shim::mlua::UserDataFieldsExt; use super::{Lives, PtrCell}; pub(super) struct Which { inner: PtrCell, - - v_tx: Option, - v_cands: Option, } impl Deref for Which { @@ -20,15 +17,15 @@ impl Deref for Which { impl Which { pub(super) fn make(inner: &yazi_core::which::Which) -> mlua::Result { - Lives::scoped_userdata(Self { inner: inner.into(), v_tx: None, v_cands: None }) + Lives::scoped_userdata(Self { inner: inner.into() }) } } impl UserData for Which { fn add_fields>(fields: &mut F) { - cached_field!(fields, tx, |_, me| Ok(me.tx.clone().map(yazi_binding::MpscUnboundedTx))); + fields.add_cached_field("tx", |_, me| Ok(me.tx.clone().map(yazi_binding::MpscUnboundedTx))); fields.add_field_method_get("times", |_, me| Ok(me.inner.times)); - cached_field!(fields, cands, |lua, me| { + fields.add_cached_field("cands", |lua, me| { lua.create_sequence_from(me.inner.cands.iter().cloned().map(yazi_binding::keymap::ChordCow)) }); diff --git a/yazi-binding/Cargo.toml b/yazi-binding/Cargo.toml index ccd2385a..9a27f52e 100644 --- a/yazi-binding/Cargo.toml +++ b/yazi-binding/Cargo.toml @@ -34,7 +34,9 @@ ansi-to-tui = { workspace = true } anyhow = { workspace = true } futures = { workspace = true } hashbrown = { workspace = true } +inventory = { workspace = true } mlua = { workspace = true } +ordered-float = { workspace = true } paste = { workspace = true } ratatui = { workspace = true } serde_json = { workspace = true } diff --git a/yazi-binding/src/config/fetcher.rs b/yazi-binding/src/config/fetcher.rs index 00ab805e..68d76725 100644 --- a/yazi-binding/src/config/fetcher.rs +++ b/yazi-binding/src/config/fetcher.rs @@ -2,14 +2,13 @@ use std::{ops::Deref, sync::Arc}; use mlua::{ExternalError, FromLua, IntoLua, Lua, Table, UserData, UserDataFields, Value}; use yazi_config::YAZI; +use yazi_shim::mlua::UserDataFieldsExt; -use crate::{FileRef, Id, Iter, cached_field}; +use crate::{FileRef, Id, Iter}; #[derive(Clone)] pub struct Fetcher { inner: Arc, - - v_name: Option, } impl Deref for Fetcher { @@ -20,7 +19,7 @@ impl Deref for Fetcher { impl Fetcher { pub fn new(inner: impl Into>) -> Self { - Self { inner: inner.into(), v_name: None } + Self { inner: inner.into() } } } @@ -28,7 +27,7 @@ impl UserData for Fetcher { fn add_fields>(fields: &mut F) { fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); - cached_field!(fields, name, |lua, me| lua.create_string(&*me.name)); + fields.add_cached_field("name", |lua, me| lua.create_string(&*me.name)); } } diff --git a/yazi-binding/src/config/open_rule.rs b/yazi-binding/src/config/open_rule.rs index 73acfaf7..64fdc129 100644 --- a/yazi-binding/src/config/open_rule.rs +++ b/yazi-binding/src/config/open_rule.rs @@ -2,13 +2,12 @@ use std::{ops::Deref, sync::Arc}; use mlua::{ExternalError, FromLua, IntoLua, Lua, LuaSerdeExt, Table, UserData, UserDataFields, Value}; use yazi_config::YAZI; +use yazi_shim::mlua::UserDataFieldsExt; -use crate::{FileRef, Id, Iter, cached_field}; +use crate::{FileRef, Id, Iter}; pub struct OpenRule { inner: Arc, - - v_use: Option, } impl Deref for OpenRule { @@ -23,7 +22,7 @@ impl From for Arc { impl OpenRule { pub fn new(inner: impl Into>) -> Self { - Self { inner: inner.into(), v_use: None } + Self { inner: inner.into() } } } @@ -36,7 +35,7 @@ impl FromLua for OpenRule { impl UserData for OpenRule { fn add_fields>(fields: &mut F) { fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); - cached_field!(fields, use, |lua, me| { + fields.add_cached_field("use", |lua, me| { lua.create_sequence_from(me.r#use.iter().map(|s| s.as_str())) }); } diff --git a/yazi-binding/src/config/opener_rule.rs b/yazi-binding/src/config/opener_rule.rs index 0ce390f3..3e1b03ef 100644 --- a/yazi-binding/src/config/opener_rule.rs +++ b/yazi-binding/src/config/opener_rule.rs @@ -1,14 +1,12 @@ use std::{ops::Deref, sync::Arc}; use mlua::{ExternalError, FromLua, IntoLua, Lua, LuaSerdeExt, Table, UserData, UserDataFields, Value}; +use yazi_shim::mlua::UserDataFieldsExt; -use crate::{Id, Iter, cached_field}; +use crate::{Id, Iter}; pub struct OpenerRule { inner: Arc, - - v_run: Option, - v_desc: Option, } impl Deref for OpenerRule { @@ -23,7 +21,7 @@ impl From for Arc { impl OpenerRule { pub fn new(inner: impl Into>) -> Self { - Self { inner: inner.into(), v_run: None, v_desc: None } + Self { inner: inner.into() } } } @@ -39,10 +37,10 @@ impl FromLua for OpenerRule { impl UserData for OpenerRule { fn add_fields>(fields: &mut F) { fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); - cached_field!(fields, run, |lua, me| lua.create_string(&*me.run)); + fields.add_cached_field("run", |lua, me| lua.create_string(&*me.run)); fields.add_field_method_get("block", |_, me| Ok(me.block)); fields.add_field_method_get("orphan", |_, me| Ok(me.orphan)); - cached_field!(fields, desc, |lua, me| lua.create_string(&*me.desc)); + fields.add_cached_field("desc", |lua, me| lua.create_string(&*me.desc)); } } diff --git a/yazi-binding/src/config/preloader.rs b/yazi-binding/src/config/preloader.rs index 1d81e0eb..3848ceda 100644 --- a/yazi-binding/src/config/preloader.rs +++ b/yazi-binding/src/config/preloader.rs @@ -2,14 +2,13 @@ use std::{ops::Deref, sync::Arc}; use mlua::{ExternalError, FromLua, IntoLua, Lua, Table, UserData, UserDataFields, Value}; use yazi_config::YAZI; +use yazi_shim::mlua::UserDataFieldsExt; -use crate::{FileRef, Id, Iter, cached_field}; +use crate::{FileRef, Id, Iter}; #[derive(Clone)] pub struct Preloader { inner: Arc, - - v_name: Option, } impl Deref for Preloader { @@ -20,7 +19,7 @@ impl Deref for Preloader { impl Preloader { pub fn new(inner: impl Into>) -> Self { - Self { inner: inner.into(), v_name: None } + Self { inner: inner.into() } } } @@ -28,7 +27,7 @@ impl UserData for Preloader { fn add_fields>(fields: &mut F) { fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); - cached_field!(fields, name, |lua, me| lua.create_string(&*me.name)); + fields.add_cached_field("name", |lua, me| lua.create_string(&*me.name)); } } diff --git a/yazi-binding/src/config/previewer.rs b/yazi-binding/src/config/previewer.rs index 4863a972..b3c5e4eb 100644 --- a/yazi-binding/src/config/previewer.rs +++ b/yazi-binding/src/config/previewer.rs @@ -2,14 +2,13 @@ use std::{ops::Deref, sync::Arc}; use mlua::{ExternalError, FromLua, IntoLua, Lua, LuaSerdeExt, Table, UserData, UserDataFields, Value}; use yazi_config::YAZI; +use yazi_shim::mlua::UserDataFieldsExt; -use crate::{FileRef, Id, Iter, cached_field}; +use crate::{FileRef, Id, Iter}; #[derive(Clone)] pub struct Previewer { inner: Arc, - - v_name: Option, } impl Deref for Previewer { @@ -24,7 +23,7 @@ impl From for Arc { impl Previewer { pub fn new(inner: impl Into>) -> Self { - Self { inner: inner.into(), v_name: None } + Self { inner: inner.into() } } } @@ -38,7 +37,7 @@ impl UserData for Previewer { fn add_fields>(fields: &mut F) { fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); - cached_field!(fields, name, |lua, me| lua.create_string(&*me.name)); + fields.add_cached_field("name", |lua, me| lua.create_string(&*me.name)); } } diff --git a/yazi-binding/src/config/spotter.rs b/yazi-binding/src/config/spotter.rs index 719331ff..d116dde8 100644 --- a/yazi-binding/src/config/spotter.rs +++ b/yazi-binding/src/config/spotter.rs @@ -2,14 +2,13 @@ use std::{ops::Deref, sync::Arc}; use mlua::{ExternalError, FromLua, IntoLua, Lua, Table, UserData, UserDataFields, Value}; use yazi_config::YAZI; +use yazi_shim::mlua::UserDataFieldsExt; -use crate::{FileRef, Id, Iter, cached_field}; +use crate::{FileRef, Id, Iter}; #[derive(Clone)] pub struct Spotter { inner: Arc, - - v_name: Option, } impl Deref for Spotter { @@ -20,7 +19,7 @@ impl Deref for Spotter { impl Spotter { pub fn new(inner: impl Into>) -> Self { - Self { inner: inner.into(), v_name: None } + Self { inner: inner.into() } } } @@ -28,7 +27,7 @@ impl UserData for Spotter { fn add_fields>(fields: &mut F) { fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); - cached_field!(fields, name, |lua, me| lua.create_string(&*me.name)); + fields.add_cached_field("name", |lua, me| lua.create_string(&*me.name)); } } diff --git a/yazi-binding/src/dnd.rs b/yazi-binding/src/dnd.rs index 6689acd8..b294e0f6 100644 --- a/yazi-binding/src/dnd.rs +++ b/yazi-binding/src/dnd.rs @@ -1,16 +1,11 @@ use std::{mem, ops::Deref}; -use mlua::{UserData, UserDataFields, Value}; -use yazi_shim::strum::IntoStr; +use mlua::{IntoLua, UserData, UserDataFields, Value}; +use yazi_shim::{mlua::UserDataFieldsExt, strum::IntoStr}; use yazi_term::event::{DndDropArrive, DndEvent as Inner}; -use crate::{cached_field, cached_field_mut}; - pub struct DndEvent { inner: Inner, - - v_mimes: Option, - v_data: Option>, } impl Deref for DndEvent { @@ -20,7 +15,7 @@ impl Deref for DndEvent { } impl From for DndEvent { - fn from(inner: Inner) -> Self { Self { inner, v_mimes: None, v_data: None } } + fn from(inner: Inner) -> Self { Self { inner } } } impl UserData for DndEvent { @@ -35,7 +30,7 @@ impl UserData for DndEvent { fields.add_field_method_get("op", |_, me| Ok(me.inner.op().map(IntoStr::into_str))); - cached_field!(fields, mimes, |lua, me| { + fields.add_cached_field("mimes", |lua, me| { if let Some(mimes) = me.inner.mimes() { lua.create_sequence_from(mimes.iter())?.into_lua(lua) } else { @@ -43,13 +38,11 @@ impl UserData for DndEvent { } }); - cached_field_mut!(fields, data, |lua, me| { - match &mut me.inner { - Inner::DropArrive(DndDropArrive { data, .. }) => { - lua.create_external_string(mem::take(data))?.into_lua(lua) - } - _ => Ok(Value::Nil), + fields.add_cached_field_mut("data", |lua, me| match &mut me.inner { + Inner::DropArrive(DndDropArrive { data, .. }) => { + lua.create_external_string(mem::take(data))?.into_lua(lua) } + _ => Ok(Value::Nil), }); } } diff --git a/yazi-binding/src/event/action.rs b/yazi-binding/src/event/action.rs index d108be34..d100e10a 100644 --- a/yazi-binding/src/event/action.rs +++ b/yazi-binding/src/event/action.rs @@ -1,6 +1,9 @@ -use std::ops::Deref; +use std::{mem, ops::{Deref, DerefMut}}; -use mlua::UserData; +use mlua::{UserData, UserDataFields}; +use yazi_shim::mlua::UserDataFieldsExt; + +use crate::event::Cmd; pub struct Action { inner: yazi_shared::event::Action, @@ -12,8 +15,16 @@ impl Deref for Action { fn deref(&self) -> &Self::Target { &self.inner } } +impl DerefMut for Action { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } +} + impl Action { pub fn new(inner: impl Into) -> Self { Self { inner: inner.into() } } } -impl UserData for Action {} +impl UserData for Action { + fn add_fields>(fields: &mut F) { + fields.add_cached_field_mut("cmd", |_, me| Ok(Cmd::new(mem::take(&mut me.cmd)))); + } +} diff --git a/yazi-binding/src/event/cmd.rs b/yazi-binding/src/event/cmd.rs index bd46f44e..5bd17115 100644 --- a/yazi-binding/src/event/cmd.rs +++ b/yazi-binding/src/event/cmd.rs @@ -1,6 +1,9 @@ -use std::ops::Deref; +use std::{mem, ops::{Deref, DerefMut}}; -use mlua::UserData; +use mlua::{UserData, UserDataFields}; +use yazi_shim::mlua::UserDataFieldsExt; + +use crate::Sendable; pub struct Cmd { inner: yazi_shared::event::Cmd, @@ -12,8 +15,20 @@ impl Deref for Cmd { fn deref(&self) -> &Self::Target { &self.inner } } +impl DerefMut for Cmd { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } +} + impl Cmd { pub fn new(inner: impl Into) -> Self { Self { inner: inner.into() } } } -impl UserData for Cmd {} +impl UserData for Cmd { + fn add_fields>(fields: &mut F) { + fields.add_cached_field_mut("name", |_, me| Ok(mem::take(&mut me.name))); + + fields.add_cached_field_mut("args", |lua, me| { + Sendable::args_to_table(lua, mem::take(&mut me.args)) + }); + } +} diff --git a/yazi-binding/src/file.rs b/yazi-binding/src/file.rs index 0ef0b640..0224fb91 100644 --- a/yazi-binding/src/file.rs +++ b/yazi-binding/src/file.rs @@ -11,14 +11,6 @@ const EXPECTED: &str = "expected a table, File, or fs::File"; #[derive(Clone)] pub struct File { pub(crate) inner: yazi_fs::File, - - v_cha: Option, - v_url: Option, - v_link_to: Option, - - v_name: Option, - v_path: Option, - v_cache: Option, } impl Deref for File { @@ -32,18 +24,7 @@ impl From for yazi_fs::File { } impl File { - pub fn new(inner: impl Into) -> Self { - Self { - inner: inner.into(), - v_cha: None, - v_url: None, - v_link_to: None, - - v_name: None, - v_path: None, - v_cache: None, - } - } + pub fn new(inner: impl Into) -> Self { Self { inner: inner.into() } } pub fn install(lua: &Lua) -> mlua::Result<()> { lua.globals().raw_set("File", lua.create_function(|_, file: Self| Ok(file))?) diff --git a/yazi-binding/src/keymap/chord.rs b/yazi-binding/src/keymap/chord.rs index dc0a6b4f..057c6015 100644 --- a/yazi-binding/src/keymap/chord.rs +++ b/yazi-binding/src/keymap/chord.rs @@ -1,14 +1,12 @@ use std::{ops::Deref, sync::Arc}; use mlua::{ExternalError, FromLua, IntoLua, Lua, LuaSerdeExt, Table, UserData, UserDataFields, Value}; +use yazi_shim::mlua::UserDataFieldsExt; -use crate::{Id, Iter, cached_field, event::Action, keymap::Key}; +use crate::{Id, Iter, event::Action, keymap::Key}; pub struct Chord { inner: Arc, - - v_on: Option, - v_run: Option, } impl Deref for Chord { @@ -23,7 +21,7 @@ impl From for Arc { impl Chord { pub fn new(inner: impl Into>) -> Self { - Self { inner: inner.into(), v_on: None, v_run: None } + Self { inner: inner.into() } } } @@ -37,10 +35,14 @@ impl UserData for Chord { fn add_fields>(fields: &mut F) { fields.add_field_method_get("id", |_, me| Ok(Id(me.inner.id))); - cached_field!(fields, on, |lua, me| lua.create_sequence_from(me.on.iter().copied().map(Key))); + fields + .add_cached_field("on", |lua, me| lua.create_sequence_from(me.on.iter().copied().map(Key))); - cached_field!(fields, run, |lua, me| lua - .create_sequence_from(me.run.iter().cloned().map(Action::new))); + fields.add_cached_field("run", |lua, me| { + lua.create_sequence_from(me.run.iter().cloned().map(Action::new)) + }); + + fields.add_cached_field("desc", |lua, me| lua.create_string(&me.desc)); } } diff --git a/yazi-binding/src/keymap/section.rs b/yazi-binding/src/keymap/section.rs index 7f8ee4de..99894e0c 100644 --- a/yazi-binding/src/keymap/section.rs +++ b/yazi-binding/src/keymap/section.rs @@ -1,16 +1,15 @@ use std::ops::Deref; use anyhow::bail; -use mlua::{UserData, UserDataFields, Value}; +use mlua::{UserData, UserDataFields}; use yazi_config::KEYMAP; use yazi_shared::Layer; +use yazi_shim::mlua::UserDataFieldsExt; -use crate::{cached_field, keymap::Chords}; +use crate::keymap::Chords; pub struct KeymapSection { inner: &'static yazi_config::keymap::KeymapSection, - - v_rules: Option, } impl Deref for KeymapSection { @@ -37,12 +36,12 @@ impl TryFrom for KeymapSection { Layer::Notify => bail!("invalid layer"), }; - Ok(Self { inner, v_rules: None }) + Ok(Self { inner }) } } impl UserData for KeymapSection { fn add_fields>(fields: &mut F) { - cached_field!(fields, rules, |_, me| Ok(Chords::new(me.inner))); + fields.add_cached_field("rules", |_, me| Ok(Chords::new(me.inner))); } } diff --git a/yazi-binding/src/lib.rs b/yazi-binding/src/lib.rs index 4efa34b6..8c52be9e 100644 --- a/yazi-binding/src/lib.rs +++ b/yazi-binding/src/lib.rs @@ -2,4 +2,4 @@ mod macros; yazi_macro::mod_pub!(config elements event keymap process theme); -yazi_macro::mod_flat!(access calculator cha chan composer dnd error fd file handle icon id image input iter layer mouse path permit range runtime scheme selector stage style tty url utils); +yazi_macro::mod_flat!(access calculator cha chan composer dnd error fd file handle icon id image input iter layer mouse path permit range runtime scheme selector sendable stage style tty url utils); diff --git a/yazi-binding/src/macros.rs b/yazi-binding/src/macros.rs index 94f7c220..18b415e6 100644 --- a/yazi-binding/src/macros.rs +++ b/yazi-binding/src/macros.rs @@ -43,48 +43,6 @@ macro_rules! deprecate { }}; } -#[macro_export] -macro_rules! cached_field { - ($fields:ident, $key:ident, $value:expr) => { - $fields.add_field_function_get(stringify!($key), |lua, ud| { - use mlua::{Error::UserDataDestructed, IntoLua, Lua, Result, Value, Value::UserData}; - ud.borrow_mut_scoped::>(|me| match paste::paste! { &me.[] } { - Some(v) if !v.is_userdata() => Ok(v.clone()), - Some(v @ UserData(ud)) if !matches!(ud.borrow::<()>(), Err(UserDataDestructed)) => { - Ok(v.clone()) - } - _ => { - let v = ($value as fn(&Lua, &Self) -> Result<_>)(lua, me)?.into_lua(lua)?; - paste::paste! { me.[] = Some(v.clone()) }; - Ok(v) - } - })? - }); - }; -} - -#[macro_export] -macro_rules! cached_field_mut { - ($fields:ident, $key:ident, $value:expr) => { - $fields.add_field_function_get(stringify!($key), |lua, ud| { - use mlua::{Error::UserDataDestructed, IntoLua, Lua, Result, Value, Value::UserData}; - ud.borrow_mut_scoped::>(|me| match paste::paste! { &me.[] } { - Some(Ok(v)) if !v.is_userdata() => Ok(v.clone()), - Some(Ok(v @ UserData(ud))) if !matches!(ud.borrow::<()>(), Err(UserDataDestructed)) => { - Ok(v.clone()) - } - Some(Err(e)) => Err(e.clone()), - _ => { - let v = - ($value as fn(&Lua, &mut Self) -> Result<_>)(lua, me).and_then(|v| v.into_lua(lua)); - paste::paste! { me.[] = Some(v.clone()) }; - v - } - })? - }); - }; -} - #[macro_export] macro_rules! impl_area_method { ($methods:ident) => { @@ -245,19 +203,21 @@ macro_rules! impl_style_shorthands { #[macro_export] macro_rules! impl_file_fields { ($fields:ident) => { - $crate::cached_field!($fields, cha, |_, me| Ok($crate::Cha(me.cha))); - $crate::cached_field!($fields, url, |_, me| Ok($crate::Url::new(me.url_owned()))); - $crate::cached_field!($fields, link_to, |_, me| Ok(me.link_to.as_ref().map($crate::Path::new))); + use yazi_shim::mlua::UserDataFieldsExt; - $crate::cached_field!($fields, name, |lua, me| { + $fields.add_cached_field("cha", |_, me| Ok($crate::Cha(me.cha))); + $fields.add_cached_field("url", |_, me| Ok($crate::Url::new(me.url_owned()))); + $fields.add_cached_field("link_to", |_, me| Ok(me.link_to.as_ref().map($crate::Path::new))); + + $fields.add_cached_field("name", |lua, me| { me.name().map(|s| lua.create_string(s.encoded_bytes())).transpose() }); - $crate::cached_field!($fields, path, |_, me| { + $fields.add_cached_field("path", |_, me| { use yazi_fs::FsUrl; use yazi_shared::url::AsUrl; Ok($crate::Path::new(me.url.as_url().unified_path())) }); - $crate::cached_field!($fields, cache, |_, me| { + $fields.add_cached_field("cache", |_, me| { use yazi_fs::FsUrl; Ok(me.url.cache().map($crate::Path::new)) }); diff --git a/yazi-binding/src/path.rs b/yazi-binding/src/path.rs index 09cc38d2..4ec51086 100644 --- a/yazi-binding/src/path.rs +++ b/yazi-binding/src/path.rs @@ -3,19 +3,13 @@ use std::ops::Deref; use mlua::{ExternalError, ExternalResult, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; use yazi_codegen::FromLuaOwned; use yazi_shared::{path::{PathBufDyn, PathLike, StripPrefixError}, strand::{AsStrand, Strand, StrandCow}}; - -use crate::cached_field; +use yazi_shim::mlua::UserDataFieldsExt; pub type PathRef = UserDataRef; #[derive(FromLuaOwned)] pub struct Path { inner: PathBufDyn, - - v_ext: Option, - v_name: Option, - v_parent: Option, - v_stem: Option, } impl Deref for Path { @@ -37,16 +31,7 @@ impl AsStrand for &Path { } impl Path { - pub fn new(path: impl Into) -> Self { - Self { - inner: path.into(), - - v_ext: None, - v_name: None, - v_parent: None, - v_stem: None, - } - } + pub fn new(path: impl Into) -> Self { Self { inner: path.into() } } pub fn install(lua: &Lua) -> mlua::Result<()> { lua.globals().raw_set( @@ -110,14 +95,14 @@ impl Path { impl UserData for Path { fn add_fields>(fields: &mut F) { - cached_field!(fields, ext, |lua, me| { + fields.add_cached_field("ext", |lua, me| { me.ext().map(|s| lua.create_string(s.encoded_bytes())).transpose() }); - cached_field!(fields, name, |lua, me| { + fields.add_cached_field("name", |lua, me| { me.name().map(|s| lua.create_string(s.encoded_bytes())).transpose() }); - cached_field!(fields, parent, |_, me| Ok(me.parent().map(Self::new))); - cached_field!(fields, stem, |lua, me| { + fields.add_cached_field("parent", |_, me| Ok(me.parent().map(Self::new))); + fields.add_cached_field("stem", |lua, me| { me.stem().map(|s| lua.create_string(s.encoded_bytes())).transpose() }); diff --git a/yazi-binding/src/process/output.rs b/yazi-binding/src/process/output.rs index 97508849..7b0056cd 100644 --- a/yazi-binding/src/process/output.rs +++ b/yazi-binding/src/process/output.rs @@ -1,31 +1,25 @@ use std::mem; -use mlua::{UserData, UserDataFields, Value}; +use mlua::{UserData, UserDataFields}; +use yazi_shim::mlua::UserDataFieldsExt; use super::Status; -use crate::{cached_field, cached_field_mut}; pub struct Output { inner: std::process::Output, - - v_status: Option, - v_stdout: Option>, - v_stderr: Option>, } impl Output { - pub fn new(inner: std::process::Output) -> Self { - Self { inner, v_status: None, v_stdout: None, v_stderr: None } - } + pub fn new(inner: std::process::Output) -> Self { Self { inner } } } impl UserData for Output { fn add_fields>(fields: &mut F) { - cached_field!(fields, status, |_, me| Ok(Status::new(me.inner.status))); - cached_field_mut!(fields, stdout, |lua, me| { + fields.add_cached_field("status", |_, me| Ok(Status::new(me.inner.status))); + fields.add_cached_field_mut("stdout", |lua, me| { lua.create_external_string(mem::take(&mut me.inner.stdout)) }); - cached_field_mut!(fields, stderr, |lua, me| { + fields.add_cached_field_mut("stderr", |lua, me| { lua.create_external_string(mem::take(&mut me.inner.stderr)) }); } diff --git a/yazi-binding/src/scheme.rs b/yazi-binding/src/scheme.rs index 93bc9fd8..d4fe16a6 100644 --- a/yazi-binding/src/scheme.rs +++ b/yazi-binding/src/scheme.rs @@ -1,17 +1,14 @@ use std::ops::Deref; -use mlua::{UserData, UserDataFields, Value}; +use mlua::{UserData, UserDataFields}; use yazi_fs::FsScheme; use yazi_shared::scheme::SchemeLike; -use yazi_shim::strum::IntoStr; +use yazi_shim::{mlua::UserDataFieldsExt, strum::IntoStr}; -use crate::{Path, cached_field}; +use crate::Path; pub struct Scheme { inner: yazi_shared::scheme::Scheme, - - v_kind: Option, - v_cache: Option, } impl Deref for Scheme { @@ -22,14 +19,14 @@ impl Deref for Scheme { impl Scheme { pub fn new(scheme: impl Into) -> Self { - Self { inner: scheme.into(), v_kind: None, v_cache: None } + Self { inner: scheme.into() } } } impl UserData for Scheme { fn add_fields>(fields: &mut F) { - cached_field!(fields, kind, |_, me| Ok(me.kind().into_str())); - cached_field!(fields, cache, |_, me| Ok(me.cache().map(Path::new))); + fields.add_cached_field("kind", |_, me| Ok(me.kind().into_str())); + fields.add_cached_field("cache", |_, me| Ok(me.cache().map(Path::new))); fields.add_field_method_get("is_virtual", |_, me| Ok(me.is_virtual())); } diff --git a/yazi-dds/src/sendable.rs b/yazi-binding/src/sendable.rs similarity index 84% rename from yazi-dds/src/sendable.rs rename to yazi-binding/src/sendable.rs index 93d8f6dc..4d474b0d 100644 --- a/yazi-dds/src/sendable.rs +++ b/yazi-binding/src/sendable.rs @@ -5,6 +5,8 @@ use mlua::{ExternalError, IntoLua, Lua, MultiValue, Table, Value}; use ordered_float::OrderedFloat; use yazi_shared::{any_data::AnyData, data::{Data, DataInventory, DataKey}, replace_cow}; +use crate::{Id, Path, Url}; + pub struct Sendable; impl Sendable { @@ -40,14 +42,14 @@ impl Sendable { }); } Value::UserData(ud) => match ud.type_id() { - Some(t) if t == TypeId::of::() => { - return Ok(Data::Url(ud.take::()?.into())); + Some(t) if t == TypeId::of::() => { + return Ok(Data::Url(ud.take::()?.into())); } - Some(t) if t == TypeId::of::() => { - return Ok(Data::Path(ud.take::()?.into())); + Some(t) if t == TypeId::of::() => { + return Ok(Data::Path(ud.take::()?.into())); } - Some(t) if t == TypeId::of::() => { - return Ok(Data::Id(**ud.borrow::()?)); + Some(t) if t == TypeId::of::() => { + return Ok(Data::Id(**ud.borrow::()?)); } Some(t) if t == TypeId::of::() => return Ok(Data::Any(ud.take::()?.0)), _ => {} @@ -87,8 +89,8 @@ impl Sendable { } Value::Table(tbl) } - Data::Url(u) => yazi_binding::Url::new(u).into_lua(lua)?, - Data::Path(u) => yazi_binding::Path::new(u).into_lua(lua)?, + Data::Url(u) => Url::new(u).into_lua(lua)?, + Data::Path(u) => Path::new(u).into_lua(lua)?, Data::Bytes(b) => Value::String(lua.create_external_string(b)?), Data::Any(a) => a.into_lua(lua)?, _ => Self::data_to_value_ref(lua, &data)?, @@ -117,9 +119,9 @@ impl Sendable { } Value::Table(tbl) } - Data::Id(i) => yazi_binding::Id(*i).into_lua(lua)?, - Data::Url(u) => yazi_binding::Url::new(u).into_lua(lua)?, - Data::Path(u) => yazi_binding::Path::new(u).into_lua(lua)?, + Data::Id(i) => Id(*i).into_lua(lua)?, + Data::Url(u) => Url::new(u).into_lua(lua)?, + Data::Path(u) => Path::new(u).into_lua(lua)?, Data::Bytes(b) => Value::String(lua.create_string(b)?), Data::Any(a) => a.to_lua(lua)?, }) @@ -201,15 +203,9 @@ impl Sendable { Value::Function(_) => Err("function is not supported".into_lua_err())?, Value::Thread(_) => Err("thread is not supported".into_lua_err())?, Value::UserData(ud) => match ud.type_id() { - Some(t) if t == TypeId::of::() => { - DataKey::Url(ud.take::()?.into()) - } - Some(t) if t == TypeId::of::() => { - DataKey::Path(ud.take::()?.into()) - } - Some(t) if t == TypeId::of::() => { - DataKey::Id(**ud.borrow::()?) - } + Some(t) if t == TypeId::of::() => DataKey::Url(ud.take::()?.into()), + Some(t) if t == TypeId::of::() => DataKey::Path(ud.take::()?.into()), + Some(t) if t == TypeId::of::() => DataKey::Id(**ud.borrow::()?), _ => Err(format!("unsupported userdata included: {ud:?}").into_lua_err())?, }, Value::Error(_) => Err("error is not supported".into_lua_err())?, @@ -220,8 +216,8 @@ impl Sendable { fn key_to_value(lua: &Lua, key: DataKey) -> mlua::Result { match key { DataKey::String(Cow::Owned(s)) => lua.create_external_string(s).map(Value::String), - DataKey::Url(u) => yazi_binding::Url::new(u).into_lua(lua), - DataKey::Path(u) => yazi_binding::Path::new(u).into_lua(lua), + DataKey::Url(u) => Url::new(u).into_lua(lua), + DataKey::Path(u) => Path::new(u).into_lua(lua), DataKey::Bytes(b) => lua.create_external_string(b).map(Value::String), _ => Self::key_to_value_ref(lua, &key), } @@ -234,9 +230,9 @@ impl Sendable { DataKey::Integer(i) => Value::Integer(*i), DataKey::Number(n) => Value::Number(n.0), DataKey::String(s) => Value::String(lua.create_string(&**s)?), - DataKey::Id(i) => yazi_binding::Id(*i).into_lua(lua)?, - DataKey::Url(u) => yazi_binding::Url::new(u).into_lua(lua)?, - DataKey::Path(u) => yazi_binding::Path::new(u).into_lua(lua)?, + DataKey::Id(i) => Id(*i).into_lua(lua)?, + DataKey::Url(u) => Url::new(u).into_lua(lua)?, + DataKey::Path(u) => Path::new(u).into_lua(lua)?, DataKey::Bytes(b) => Value::String(lua.create_string(b)?), }) } diff --git a/yazi-binding/src/url.rs b/yazi-binding/src/url.rs index 4064a285..edc34b7e 100644 --- a/yazi-binding/src/url.rs +++ b/yazi-binding/src/url.rs @@ -4,8 +4,9 @@ use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, use yazi_codegen::FromLuaOwned; use yazi_fs::{FsHash64, FsHash128, FsUrl}; use yazi_shared::{path::{PathLike, StripPrefixError}, scheme::{SchemeCow, SchemeLike}, strand::{StrandLike, ToStrand}, url::{AsUrl, UrlCow, UrlLike}}; +use yazi_shim::mlua::UserDataFieldsExt; -use crate::{Path, Scheme, cached_field}; +use crate::{Path, Scheme}; pub type UrlRef = UserDataRef; @@ -14,19 +15,6 @@ const EXPECTED: &str = "expected a string, Url, or Path"; #[derive(FromLuaOwned)] pub struct Url { inner: yazi_shared::url::UrlBuf, - - v_path: Option, - v_name: Option, - v_stem: Option, - v_ext: Option, - v_urn: Option, - v_base: Option, - v_parent: Option, - - v_scheme: Option, - v_domain: Option, - - v_cache: Option, } impl Deref for Url { @@ -62,24 +50,7 @@ impl TryFrom<&[u8]> for Url { } impl Url { - pub fn new(url: impl Into) -> Self { - Self { - inner: url.into(), - - v_path: None, - v_name: None, - v_stem: None, - v_ext: None, - v_urn: None, - v_base: None, - v_parent: None, - - v_scheme: None, - v_domain: None, - - v_cache: None, - } - } + pub fn new(url: impl Into) -> Self { Self { inner: url.into() } } pub fn install(lua: &Lua) -> mlua::Result<()> { lua.globals().raw_set( @@ -171,28 +142,28 @@ impl Url { impl UserData for Url { fn add_fields>(fields: &mut F) { - cached_field!(fields, path, |_, me| Ok(Path::new(me.loc()))); - cached_field!(fields, name, |lua, me| { + fields.add_cached_field("path", |_, me| Ok(Path::new(me.loc()))); + fields.add_cached_field("name", |lua, me| { me.name().map(|s| lua.create_string(s.encoded_bytes())).transpose() }); - cached_field!(fields, stem, |lua, me| { + fields.add_cached_field("stem", |lua, me| { me.stem().map(|s| lua.create_string(s.encoded_bytes())).transpose() }); - cached_field!(fields, ext, |lua, me| { + fields.add_cached_field("ext", |lua, me| { me.ext().map(|s| lua.create_string(s.encoded_bytes())).transpose() }); - cached_field!(fields, urn, |_, me| Ok(Path::new(me.urn()))); - cached_field!(fields, base, |_, me| { + fields.add_cached_field("urn", |_, me| Ok(Path::new(me.urn()))); + fields.add_cached_field("base", |_, me| { Ok(Some(me.base()).filter(|u| !u.loc().is_empty()).map(Self::new)) }); - cached_field!(fields, parent, |_, me| Ok(me.parent().map(Self::new))); + fields.add_cached_field("parent", |_, me| Ok(me.parent().map(Self::new))); - cached_field!(fields, scheme, |_, me| Ok(Scheme::new(me.scheme()))); - cached_field!(fields, domain, |lua, me| { + fields.add_cached_field("scheme", |_, me| Ok(Scheme::new(me.scheme()))); + fields.add_cached_field("domain", |lua, me| { me.scheme().domain().map(|s| lua.create_string(s)).transpose() }); - cached_field!(fields, cache, |_, me| Ok(me.cache().map(Path::new))); + fields.add_cached_field("cache", |_, me| Ok(me.cache().map(Path::new))); fields.add_field_method_get("is_regular", |_, me| Ok(me.is_regular())); fields.add_field_method_get("is_search", |_, me| Ok(me.is_search())); diff --git a/yazi-config/src/keymap/chord.rs b/yazi-config/src/keymap/chord.rs index a69b18be..98aba87e 100644 --- a/yazi-config/src/keymap/chord.rs +++ b/yazi-config/src/keymap/chord.rs @@ -3,7 +3,7 @@ use std::{borrow::Cow, hash::{Hash, Hasher}, sync::{Arc, OnceLock}}; use regex::Regex; use serde::{Deserialize, Deserializer, de}; use serde_with::{DeserializeAs, DisplayFromStr, OneOrMany}; -use yazi_shared::{Id, Layer, Source, event::Action}; +use yazi_shared::{Id, Layer, event::{Actions, deserialize_actions}}; use super::{Key, ids::chord_id}; use crate::{Mixable, Platform, keymap::Chords}; @@ -16,8 +16,8 @@ pub struct Chord { pub id: Id, #[serde(deserialize_with = "deserialize_on")] pub on: Vec, - #[serde(deserialize_with = "deserialize_run::")] - pub run: Vec, + #[serde(deserialize_with = "deserialize_actions::")] + pub run: Actions, #[serde(default)] pub desc: String, #[serde(default)] @@ -95,26 +95,6 @@ where Ok(keys) } -fn deserialize_run<'de, const L: u8, D>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, -{ - let Some(layer) = Layer::from_repr(L) else { - return Err(de::Error::custom(format!("invalid keymap layer const: {L}"))); - }; - - let mut actions: Vec = OneOrMany::::deserialize_as(deserializer)?; - - for action in &mut actions { - action.source = Source::Key; - if action.layer == Layer::Null { - action.layer = layer; - } - } - - Ok(actions) -} - // --- Matcher #[derive(Default)] pub struct ChordMatcher { diff --git a/yazi-config/src/keymap/cow.rs b/yazi-config/src/keymap/chord_cow.rs similarity index 100% rename from yazi-config/src/keymap/cow.rs rename to yazi-config/src/keymap/chord_cow.rs diff --git a/yazi-config/src/keymap/mod.rs b/yazi-config/src/keymap/mod.rs index b608ba6a..bd0d6786 100644 --- a/yazi-config/src/keymap/mod.rs +++ b/yazi-config/src/keymap/mod.rs @@ -1 +1 @@ -yazi_macro::mod_flat!(chord chords cow ids key keymap section); +yazi_macro::mod_flat!(chord chord_cow chords ids key keymap section); diff --git a/yazi-dds/Cargo.toml b/yazi-dds/Cargo.toml index ad770cab..e763a4d9 100644 --- a/yazi-dds/Cargo.toml +++ b/yazi-dds/Cargo.toml @@ -31,7 +31,6 @@ hashbrown = { workspace = true } indexmap = { workspace = true } inventory = { workspace = true } mlua = { workspace = true } -ordered-float = { workspace = true } parking_lot = { workspace = true } paste = { workspace = true } serde = { workspace = true } diff --git a/yazi-dds/src/ember/custom.rs b/yazi-dds/src/ember/custom.rs index 8f3a8f64..78d2de76 100644 --- a/yazi-dds/src/ember/custom.rs +++ b/yazi-dds/src/ember/custom.rs @@ -1,9 +1,9 @@ use mlua::{IntoLua, Lua, Value}; use serde::Serialize; +use yazi_binding::Sendable; use yazi_shared::data::Data; use super::Ember; -use crate::Sendable; #[derive(Clone, Debug)] pub struct EmberCustom { diff --git a/yazi-dds/src/lib.rs b/yazi-dds/src/lib.rs index aa41ee8f..d97c5a25 100644 --- a/yazi-dds/src/lib.rs +++ b/yazi-dds/src/lib.rs @@ -1,6 +1,6 @@ yazi_macro::mod_pub!(ember); -yazi_macro::mod_flat!(client payload pubsub pump sendable server state stream); +yazi_macro::mod_flat!(client payload pubsub pump server state stream); pub fn init() { let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); diff --git a/yazi-emulator/Cargo.toml b/yazi-emulator/Cargo.toml index 7f3c1fb8..5afd92ef 100644 --- a/yazi-emulator/Cargo.toml +++ b/yazi-emulator/Cargo.toml @@ -20,9 +20,9 @@ yazi-term = { path = "../yazi-term", version = "26.5.6" } yazi-tty = { path = "../yazi-tty", version = "26.5.9" } # External dependencies -anyhow = { workspace = true } -either = { workspace = true } -ratatui = { workspace = true } -scopeguard = { workspace = true } -tokio = { workspace = true } -tracing = { workspace = true } +anyhow = { workspace = true } +either = { workspace = true } +ratatui = { workspace = true } +scopeguard = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } diff --git a/yazi-plugin/src/utils/call.rs b/yazi-plugin/src/utils/call.rs index b816e685..5703e9a5 100644 --- a/yazi-plugin/src/utils/call.rs +++ b/yazi-plugin/src/utils/call.rs @@ -1,6 +1,6 @@ use mlua::{ExternalError, Function, Lua, Table}; use tokio::sync::mpsc; -use yazi_dds::Sendable; +use yazi_binding::Sendable; use yazi_macro::emit; use yazi_shared::{Layer, Source, event::Action}; diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index 4dd058d8..586ffedf 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -27,7 +27,7 @@ impl Utils { Ok(ChordCow::Owned(Chord { id: yazi_config::keymap::chord_id(), on: Self::parse_keys(cand.raw_get("on")?)?, - run: vec![relay!(which:callback, [i + 1])], + run: relay!(which:callback, [i + 1]).into(), desc: cand.raw_get("desc").unwrap_or_default(), r#for: Platform::All, })) diff --git a/yazi-plugin/src/utils/sync.rs b/yazi-plugin/src/utils/sync.rs index 1f224783..0706bc7f 100644 --- a/yazi-plugin/src/utils/sync.rs +++ b/yazi-plugin/src/utils/sync.rs @@ -2,9 +2,8 @@ use anyhow::Context; use futures::future::join_all; use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, MultiValue, Table, Value, Variadic}; use tokio::sync::mpsc; -use yazi_binding::{Handle, MpscRx, MpscTx, MpscUnboundedRx, MpscUnboundedTx, OneshotRx, OneshotTx, runtime, runtime_mut}; +use yazi_binding::{Handle, MpscRx, MpscTx, MpscUnboundedRx, MpscUnboundedTx, OneshotRx, OneshotTx, Sendable, runtime, runtime_mut}; use yazi_core::{AppProxy, app::PluginOpt}; -use yazi_dds::Sendable; use yazi_runner::loader::LOADER; use yazi_shared::{LOCAL_SET, data::Data}; diff --git a/yazi-runner/Cargo.toml b/yazi-runner/Cargo.toml index 18a4eb21..29506f35 100644 --- a/yazi-runner/Cargo.toml +++ b/yazi-runner/Cargo.toml @@ -19,7 +19,6 @@ vendored-lua = [ "mlua/vendored" ] [dependencies] yazi-binding = { path = "../yazi-binding", version = "26.5.6" } yazi-config = { path = "../yazi-config", version = "26.5.6" } -yazi-dds = { path = "../yazi-dds", version = "26.5.6" } yazi-fs = { path = "../yazi-fs", version = "26.5.6" } yazi-macro = { path = "../yazi-macro", version = "26.5.6" } yazi-shared = { path = "../yazi-shared", version = "26.5.6" } diff --git a/yazi-runner/src/entry/job.rs b/yazi-runner/src/entry/job.rs index 773616ae..57af8558 100644 --- a/yazi-runner/src/entry/job.rs +++ b/yazi-runner/src/entry/job.rs @@ -1,6 +1,6 @@ use hashbrown::HashMap; use mlua::{IntoLua, Lua, Value}; -use yazi_dds::Sendable; +use yazi_binding::Sendable; use yazi_shared::{Id, SStr, data::{Data, DataKey}}; #[derive(Clone, Debug, Default)] diff --git a/yazi-runner/src/fetcher/job.rs b/yazi-runner/src/fetcher/job.rs index 5ef3eccf..bde5d942 100644 --- a/yazi-runner/src/fetcher/job.rs +++ b/yazi-runner/src/fetcher/job.rs @@ -1,8 +1,7 @@ use std::sync::Arc; use mlua::{IntoLua, Lua, Value}; -use yazi_binding::File; -use yazi_dds::Sendable; +use yazi_binding::{File, Sendable}; pub struct FetchJob { pub fetcher: Arc, diff --git a/yazi-runner/src/preloader/job.rs b/yazi-runner/src/preloader/job.rs index 1ae1ebe5..cc396b05 100644 --- a/yazi-runner/src/preloader/job.rs +++ b/yazi-runner/src/preloader/job.rs @@ -1,9 +1,8 @@ use std::sync::Arc; use mlua::{IntoLua, Lua, Value}; -use yazi_binding::{File, elements::Rect}; +use yazi_binding::{File, Sendable, elements::Rect}; use yazi_config::LAYOUT; -use yazi_dds::Sendable; pub struct PreloadJob { pub preloader: Arc, diff --git a/yazi-runner/src/previewer/job.rs b/yazi-runner/src/previewer/job.rs index 09a2a1ab..34b0b2b3 100644 --- a/yazi-runner/src/previewer/job.rs +++ b/yazi-runner/src/previewer/job.rs @@ -1,9 +1,8 @@ use std::sync::Arc; use mlua::{IntoLua, Lua, Value}; -use yazi_binding::{File, elements::Rect}; +use yazi_binding::{File, Sendable, elements::Rect}; use yazi_config::LAYOUT; -use yazi_dds::Sendable; use yazi_shared::pool::Symbol; #[derive(Clone, Debug)] diff --git a/yazi-runner/src/spot.rs b/yazi-runner/src/spot.rs index e23e8f7b..e63fd245 100644 --- a/yazi-runner/src/spot.rs +++ b/yazi-runner/src/spot.rs @@ -4,9 +4,8 @@ use mlua::{ExternalError, ExternalResult, HookTriggers, IntoLua, ObjectLike, VmS use tokio::{runtime::Handle, select}; use tokio_util::sync::CancellationToken; use tracing::error; -use yazi_binding::{File, Id}; +use yazi_binding::{File, Id, Sendable}; use yazi_config::plugin::Spotter; -use yazi_dds::Sendable; use yazi_shared::{Ids, pool::Symbol}; use crate::{Runner, loader::LOADER}; diff --git a/yazi-scheduler/src/plugin/in.rs b/yazi-scheduler/src/plugin/in.rs index 371c60f4..0f2c453d 100644 --- a/yazi-scheduler/src/plugin/in.rs +++ b/yazi-scheduler/src/plugin/in.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use hashbrown::HashMap; use mlua::{ExternalError, FromLua, Lua, Value}; -use yazi_dds::Sendable; +use yazi_binding::Sendable; use yazi_runner::entry::EntryJob; use yazi_shared::{Id, SStr, data::{Data, DataKey}}; diff --git a/yazi-shared/src/event/cow.rs b/yazi-shared/src/event/action_cow.rs similarity index 100% rename from yazi-shared/src/event/cow.rs rename to yazi-shared/src/event/action_cow.rs diff --git a/yazi-shared/src/event/actions.rs b/yazi-shared/src/event/actions.rs new file mode 100644 index 00000000..96892cc0 --- /dev/null +++ b/yazi-shared/src/event/actions.rs @@ -0,0 +1,57 @@ +use std::{ops::{Deref, DerefMut}, slice, vec}; + +use serde::{Deserializer, de}; +use serde_with::{DeserializeAs, DisplayFromStr, OneOrMany}; + +use crate::{Layer, Source, event::Action}; + +#[derive(Clone, Debug, Default)] +pub struct Actions(Vec); + +impl Deref for Actions { + type Target = Vec; + + fn deref(&self) -> &Self::Target { &self.0 } +} + +impl DerefMut for Actions { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } +} + +impl From for Actions { + fn from(value: Action) -> Self { Self(vec![value]) } +} + +impl IntoIterator for Actions { + type IntoIter = vec::IntoIter; + type Item = Action; + + fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } +} + +impl<'a> IntoIterator for &'a Actions { + type IntoIter = slice::Iter<'a, Action>; + type Item = &'a Action; + + fn into_iter(self) -> Self::IntoIter { self.0.iter() } +} + +pub fn deserialize_actions<'de, const L: u8, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let Some(layer) = Layer::from_repr(L) else { + return Err(de::Error::custom(format!("invalid keymap layer const: {L}"))); + }; + + let mut actions: Vec = OneOrMany::::deserialize_as(deserializer)?; + + for action in &mut actions { + action.source = Source::Key; + if action.layer == Layer::Null { + action.layer = layer; + } + } + + Ok(Actions(actions)) +} diff --git a/yazi-shared/src/event/mod.rs b/yazi-shared/src/event/mod.rs index 49963f67..2b0615a8 100644 --- a/yazi-shared/src/event/mod.rs +++ b/yazi-shared/src/event/mod.rs @@ -1,4 +1,4 @@ -yazi_macro::mod_flat!(action cmd cow de de_owned event); +yazi_macro::mod_flat!(action action_cow actions cmd de de_owned event); pub type Replier = tokio::sync::mpsc::UnboundedSender>; diff --git a/yazi-shim/src/mlua/cache.rs b/yazi-shim/src/mlua/cache.rs new file mode 100644 index 00000000..5897fc56 --- /dev/null +++ b/yazi-shim/src/mlua/cache.rs @@ -0,0 +1,9 @@ +use mlua::{Error::UserDataDestructed, Value}; + +pub(super) fn is_alive(v: &Value) -> bool { + if let Value::UserData(ud) = v { + !matches!(ud.borrow::<()>(), Err(UserDataDestructed)) + } else { + true + } +} diff --git a/yazi-shim/src/mlua/mod.rs b/yazi-shim/src/mlua/mod.rs index 65220acf..de755c23 100644 --- a/yazi-shim/src/mlua/mod.rs +++ b/yazi-shim/src/mlua/mod.rs @@ -1 +1 @@ -yazi_macro::mod_flat!(sequence string traits); +yazi_macro::mod_flat!(cache sequence string traits); diff --git a/yazi-shim/src/mlua/traits.rs b/yazi-shim/src/mlua/traits.rs index 68b037b5..82488cba 100644 --- a/yazi-shim/src/mlua/traits.rs +++ b/yazi-shim/src/mlua/traits.rs @@ -1,8 +1,8 @@ use std::marker::PhantomData; -use mlua::{ExternalError, FromLua, Lua, Table, Value}; +use mlua::{ExternalError, FromLua, IntoLua, Lua, Table, UserData, UserDataFields, Value}; -use crate::{mlua::SequenceIter, toml::DeserializeOverWith}; +use crate::{mlua::{SequenceIter, is_alive}, toml::DeserializeOverWith}; // --- DeserializeOverLua pub trait DeserializeOverLua: DeserializeOverWith { @@ -29,3 +29,67 @@ impl LuaTableExt for Table { } } } + +// --- UserDataFieldsExt +pub trait UserDataFieldsExt: UserDataFields { + fn add_cached_field( + &mut self, + key: &'static str, + compute: fn(&Lua, &S) -> mlua::Result, + ) -> &mut Self { + self.add_field_function_get(key, move |lua, ud| { + match ud.named_user_value::>(key)? { + Some(v) if is_alive(&v) => Ok(v), + _ => { + let v = compute(lua, &*ud.borrow::()?)?.into_lua(lua)?; + ud.set_named_user_value(key, &v)?; + Ok(v) + } + } + }); + self + } + + fn add_cached_field_mut( + &mut self, + key: &'static str, + compute: fn(&Lua, &mut S) -> mlua::Result, + ) -> &mut Self { + self.add_field_function_get(key, move |lua, ud| { + match ud.named_user_value::>(key)? { + Some(Value::Error(e)) => Err(*e), + Some(v) if is_alive(&v) => Ok(v), + _ => { + let v = match compute(lua, &mut *ud.borrow_mut::()?).and_then(|r| r.into_lua(lua)) { + Ok(v) => v, + Err(e) => Value::Error(Box::new(e)), + }; + + ud.set_named_user_value(key, &v)?; + Ok(v) + } + } + }); + self + } + + fn add_static_field( + &mut self, + key: &'static str, + compute: fn(&Lua, &S) -> mlua::Result, + ) -> &mut Self { + self.add_field_function_get(key, move |lua, ud| { + match ud.named_user_value::>(key)? { + Some(v) => Ok(v), + _ => { + let v = compute(lua, &*ud.borrow::()?)?.into_lua(lua)?; + ud.set_named_user_value(key, &v)?; + Ok(v) + } + } + }); + self + } +} + +impl> UserDataFieldsExt for F {}