diff --git a/CHANGELOG.md b/CHANGELOG.md index 03c08279..7640c944 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/): ## [Unreleased] +### Added + +- New `ind-which-show` DDS event to change the which component behavior ([#3608]) + ### Fixed - Archive extraction fails for target paths with non-ASCII characters on Windows ([#3607]) @@ -1617,3 +1621,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/): [#3582]: https://github.com/sxyazi/yazi/pull/3582 [#3594]: https://github.com/sxyazi/yazi/pull/3594 [#3607]: https://github.com/sxyazi/yazi/pull/3607 +[#3608]: https://github.com/sxyazi/yazi/pull/3608 diff --git a/Cargo.lock b/Cargo.lock index 50bef066..19715034 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,9 +541,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.53" +version = "1.2.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" +checksum = "6354c81bbfd62d9cfa9cb3c773c2b7b2a3a482d569de977fd0e961f6e7c00583" dependencies = [ "find-msvc-tools", "jobserver", @@ -919,9 +919,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.0-rc.10" +version = "0.2.0-rc.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fc0003068acd7e9cb6659fd956dc4d671f102a06cc115990b9e7bb5745c25" +checksum = "c7722afd27468475c9b6063dc03a57ef2ca833816981619f8ebe64d38d207eef" dependencies = [ "hybrid-array", ] @@ -1203,13 +1203,13 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.0-rc.6" +version = "0.11.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2778ee7344f47967d6701053913962accf9bfdb0caa4b6d921b7c4a615f658d0" +checksum = "2fc1408b7a9f59a7b933faff3e9e7fc15a05a524effd3b3d1601156944c8077f" dependencies = [ "block-buffer 0.11.0", "const-oid 0.10.2", - "crypto-common 0.2.0-rc.10", + "crypto-common 0.2.0-rc.13", ] [[package]] @@ -1856,9 +1856,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f471e0a81b2f90ffc0cb2f951ae04da57de8baa46fa99112b062a5173a5088d0" +checksum = "b41fb3dc24fe72c2e3a4685eed55917c2fb228851257f4a8f2d985da9443c3e5" dependencies = [ "typenum", ] @@ -2004,7 +2004,7 @@ checksum = "fe44f2bbd99fcb302e246e2d6bcf51aeda346d02a365f80296a07a8c711b6da6" dependencies = [ "argon2", "bcrypt-pbkdf", - "digest 0.11.0-rc.6", + "digest 0.11.0-rc.8", "ecdsa", "ed25519-dalek", "hex", @@ -2017,7 +2017,7 @@ dependencies = [ "rsa", "sec1", "sha1 0.10.6", - "sha1 0.11.0-rc.3", + "sha1 0.11.0-rc.4", "sha2 0.10.9", "signature 2.2.0", "signature 3.0.0-rc.6", @@ -2215,9 +2215,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" @@ -2567,9 +2567,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-derive" @@ -3264,9 +3264,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -3628,11 +3628,11 @@ dependencies = [ "const-oid 0.10.2", "crypto-bigint 0.7.0-rc.18", "crypto-primes", - "digest 0.11.0-rc.6", + "digest 0.11.0-rc.8", "pkcs1", "pkcs8 0.11.0-rc.9", "rand_core 0.10.0-rc-3", - "sha2 0.11.0-rc.3", + "sha2 0.11.0-rc.4", "signature 3.0.0-rc.6", "spki 0.8.0-rc.4", "zeroize", @@ -3640,9 +3640,9 @@ dependencies = [ [[package]] name = "russh" -version = "0.56.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdbb7dcdd62c17ac911307ff693f55b3ec6712004d2d66ffdb8c0fa00269fd66" +checksum = "01fe22d10a0e39c1134a971d5b8db8a40357b48ef22d81fa8d6eac22202dd782" dependencies = [ "aes", "bitflags 2.10.0", @@ -3680,8 +3680,8 @@ dependencies = [ "pkcs1", "pkcs5", "pkcs8 0.10.2", - "rand 0.8.5", - "rand_core 0.6.4", + "rand 0.9.2", + "rand_core 0.10.0-rc-3", "ring", "rsa", "russh-cryptovec", @@ -3932,13 +3932,13 @@ dependencies = [ [[package]] name = "sha1" -version = "0.11.0-rc.3" +version = "0.11.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa1ae819b9870cadc959a052363de870944a1646932d274a4e270f64bf79e5ef" +checksum = "9c777f0a122a53fddb0beb6e706771197000b8eb5c9f42b5b850f450ef48c788" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-rc.6", + "digest 0.11.0-rc.8", ] [[package]] @@ -3954,13 +3954,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.11.0-rc.3" +version = "0.11.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d43dc0354d88b791216bb5c1bfbb60c0814460cc653ae0ebd71f286d0bd927" +checksum = "7535f94fa3339fe9e5e9be6260a909e62af97f6e14b32345ccf79b92b8b81233" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.11.0-rc.6", + "digest 0.11.0-rc.8", ] [[package]] @@ -3990,9 +3990,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a37d01603c37b5466f808de79f845c7116049b0579adb70a6b7d47c1fa3a952" +checksum = "3b57709da74f9ff9f4a27dce9526eec25ca8407c45a7887243b031a58935fb8e" dependencies = [ "libc", "signal-hook-registry", @@ -4027,7 +4027,7 @@ checksum = "e513e435a8898a0002270f29d0a708b7879708fb5c4d00e46983ca2d2d378cf0" dependencies = [ "futures-core", "libc", - "signal-hook 0.4.1", + "signal-hook 0.4.3", "tokio", ] @@ -4047,7 +4047,7 @@ version = "3.0.0-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a96996ccff7dfa16f052bd995b4cecc72af22c35138738dc029f0ead6608d" dependencies = [ - "digest 0.11.0-rc.6", + "digest 0.11.0-rc.8", "rand_core 0.10.0-rc-3", ] @@ -4092,9 +4092,9 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", "windows-sys 0.60.2", @@ -4408,9 +4408,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.45" +version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" +checksum = "9da98b7d9b7dad93488a84b8248efc35352b0b2657397d4167e7ad67e5d535e5" dependencies = [ "deranged", "itoa", @@ -4425,15 +4425,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" +checksum = "78cc610bac2dcee56805c99642447d4c5dbde4d01f752ffea0199aee1f601dc4" dependencies = [ "num-conv", "time-core", @@ -4653,9 +4653,9 @@ dependencies = [ [[package]] name = "typed-path" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7922f2cdc51280d47b491af9eafc41eb0cdab85eabcb390c854412fcbf26dbe8" +checksum = "e43ffa54726cdc9ea78392023ffe9fe9cf9ac779e1c6fcb0d23f9862e3879d20" [[package]] name = "typeid" @@ -5484,6 +5484,7 @@ dependencies = [ "tracing", "unicode-width", "yazi-adapter", + "yazi-codegen", "yazi-config", "yazi-fs", "yazi-macro", diff --git a/Cargo.toml b/Cargo.toml index 300552c5..5a6168ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ percent-encoding = "2.3.2" rand = { version = "0.9.2", default-features = false, features = [ "os_rng", "small_rng", "std" ] } ratatui = { version = "0.30.0", features = [ "serde", "unstable-rendered-line-info", "unstable-widget-ref" ] } regex = "1.12.2" -russh = { version = "0.56.0", default-features = false, features = [ "ring", "rsa" ] } +russh = { version = "0.57.0", default-features = false, features = [ "ring", "rsa" ] } scopeguard = "1.2.0" serde = { version = "1.0.228", features = [ "derive" ] } serde_json = "1.0.149" @@ -62,7 +62,7 @@ tokio-util = "0.7.18" toml = { version = "0.9.11" } tracing = { version = "0.1.44", features = [ "max_level_debug", "release_max_level_debug" ] } twox-hash = { version = "2.1.2", default-features = false, features = [ "std", "random", "xxhash3_128" ] } -typed-path = "0.12.0" +typed-path = "0.12.1" unicode-width = { version = "0.2.2", default-features = false } uzers = "0.12.2" diff --git a/yazi-actor/src/lives/tasks.rs b/yazi-actor/src/lives/tasks.rs index e39129cc..e547c138 100644 --- a/yazi-actor/src/lives/tasks.rs +++ b/yazi-actor/src/lives/tasks.rs @@ -1,7 +1,7 @@ use std::ops::Deref; use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields, Value}; -use yazi_binding::{SER_OPT, cached_field, deprecate}; +use yazi_binding::{SER_OPT, cached_field}; use super::{Lives, PtrCell}; use crate::lives::TaskSnap; @@ -9,9 +9,8 @@ use crate::lives::TaskSnap; pub(super) struct Tasks { inner: PtrCell, - v_snaps: Option, - v_summary: Option, - v_progress: Option, + v_snaps: Option, + v_summary: Option, } impl Deref for Tasks { @@ -25,9 +24,8 @@ impl Tasks { Lives::scoped_userdata(Self { inner: inner.into(), - v_snaps: None, - v_summary: None, - v_progress: None, + v_snaps: None, + v_summary: None, }) } } @@ -45,19 +43,5 @@ impl UserData for Tasks { }); cached_field!(fields, summary, |lua, me| lua.to_value_with(&me.summary, SER_OPT)); - - cached_field!(fields, progress, |lua, me| { - deprecate!( - lua, - "`cx.tasks.progress` is deprecated, use `cx.tasks.summary` instead, in your {}" - ); - lua.create_table_from([ - ("total", me.summary.total), - ("succ", me.summary.success), - ("fail", me.summary.failed), - ("found", 0), - ("processed", 0), - ]) - }); } } diff --git a/yazi-actor/src/which/show.rs b/yazi-actor/src/which/show.rs index 40b13c25..0f63b691 100644 --- a/yazi-actor/src/which/show.rs +++ b/yazi-actor/src/which/show.rs @@ -1,7 +1,9 @@ use anyhow::Result; +use yazi_core::which::WhichSorter; +use yazi_dds::spark::SparkKind; use yazi_macro::{render, succ}; use yazi_parser::which::ShowOpt; -use yazi_shared::data::Data; +use yazi_shared::{Source, data::Data}; use crate::{Actor, Ctx}; @@ -12,17 +14,27 @@ impl Actor for Show { const NAME: &str = "show"; - fn act(cx: &mut Ctx, opt: Self::Options) -> Result { + fn act(cx: &mut Ctx, mut opt: Self::Options) -> Result { + opt.cands.retain(|c| c.on.len() > opt.times); + WhichSorter::default().sort(&mut opt.cands); + if opt.cands.is_empty() { succ!(); } let which = &mut cx.which; - which.times = 0; - which.cands = opt.cands.into_iter().map(|c| c.into()).collect(); + which.times = opt.times; + which.cands = opt.cands; which.visible = true; which.silent = opt.silent; succ!(render!()); } + + fn hook(cx: &Ctx, _opt: &Self::Options) -> Option { + match cx.source() { + Source::Unknown => Some(SparkKind::IndWhichShow), + _ => None, + } + } } diff --git a/yazi-binding/Cargo.toml b/yazi-binding/Cargo.toml index 660f878d..01421358 100644 --- a/yazi-binding/Cargo.toml +++ b/yazi-binding/Cargo.toml @@ -17,6 +17,7 @@ vendored-lua = [ "mlua/vendored" ] [dependencies] yazi-adapter = { path = "../yazi-adapter", version = "26.1.22" } +yazi-codegen = { path = "../yazi-codegen", version = "26.1.22" } yazi-config = { path = "../yazi-config", version = "26.1.22" } yazi-fs = { path = "../yazi-fs", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" } diff --git a/yazi-binding/src/chord_cow.rs b/yazi-binding/src/chord_cow.rs new file mode 100644 index 00000000..796c9ef4 --- /dev/null +++ b/yazi-binding/src/chord_cow.rs @@ -0,0 +1,11 @@ +use mlua::UserData; +use yazi_codegen::FromLuaOwned; + +#[derive(FromLuaOwned)] +pub struct ChordCow(pub yazi_config::keymap::ChordCow); + +impl From for yazi_config::keymap::ChordCow { + fn from(value: ChordCow) -> Self { value.0 } +} + +impl UserData for ChordCow {} diff --git a/yazi-binding/src/elements/rect.rs b/yazi-binding/src/elements/rect.rs index f54d9069..44f902d4 100644 --- a/yazi-binding/src/elements/rect.rs +++ b/yazi-binding/src/elements/rect.rs @@ -3,7 +3,6 @@ use std::ops::Deref; use mlua::{FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value}; use super::Pad; -use crate::deprecate; #[derive(Clone, Copy, Debug, Default, FromLua)] pub struct Rect(pub ratatui::layout::Rect); @@ -35,20 +34,8 @@ impl Rect { })) })?; - let index = lua.create_function(move |lua, (_, key): (Table, mlua::String)| { - Ok(match &*key.as_bytes() { - b"default" => { - deprecate!(lua, "`ui.Rect.default` is deprecated, use `ui.Rect{{}}` instead, in your {}\nSee #2927 for more details: https://github.com/sxyazi/yazi/pull/2927"); - Some(Self(Default::default())) - } - _ => None, - }) - })?; - let rect = lua.create_table()?; - rect.set_metatable(Some( - lua.create_table_from([(MetaMethod::Call.name(), new), (MetaMethod::Index.name(), index)])?, - ))?; + rect.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?))?; rect.into_lua(lua) } diff --git a/yazi-binding/src/error.rs b/yazi-binding/src/error.rs index e53698ae..4adada26 100644 --- a/yazi-binding/src/error.rs +++ b/yazi-binding/src/error.rs @@ -1,10 +1,10 @@ use std::{borrow::Cow, fmt::Display}; -use mlua::{ExternalError, FromLua, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, Value}; +use mlua::{ExternalError, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, Value}; +use yazi_codegen::FromLuaOwned; use yazi_shared::SStr; -const EXPECTED: &str = "expected a Error"; - +#[derive(FromLuaOwned)] pub enum Error { Io(std::io::Error), Fs(yazi_fs::error::Error), @@ -53,15 +53,6 @@ impl Display for Error { } } -impl FromLua for Error { - fn from_lua(value: Value, _: &Lua) -> mlua::Result { - match value { - Value::UserData(ud) => ud.take(), - _ => Err(EXPECTED.into_lua_err()), - } - } -} - impl UserData for Error { fn add_fields>(fields: &mut F) { fields.add_field_method_get("code", |_, me| { diff --git a/yazi-binding/src/file.rs b/yazi-binding/src/file.rs index 8555d9e5..19eed92b 100644 --- a/yazi-binding/src/file.rs +++ b/yazi-binding/src/file.rs @@ -1,6 +1,7 @@ use std::ops::Deref; -use mlua::{AnyUserData, ExternalError, FromLua, Lua, ObjectLike, Table, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; +use mlua::{AnyUserData, ExternalError, Lua, ObjectLike, Table, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; +use yazi_codegen::FromLuaOwned; use crate::{Cha, Url, impl_file_fields, impl_file_methods}; @@ -8,7 +9,7 @@ pub type FileRef = UserDataRef; const EXPECTED: &str = "expected a table, File, or fs::File"; -#[derive(Clone)] +#[derive(Clone, FromLuaOwned)] pub struct File { inner: yazi_fs::File, @@ -82,15 +83,6 @@ impl TryFrom for File { } } -impl FromLua for File { - fn from_lua(value: Value, _: &Lua) -> mlua::Result { - Ok(match value { - Value::UserData(ud) => Self::new(ud.take::()?.inner), - _ => Err("expected a File".into_lua_err())?, - }) - } -} - impl UserData for File { fn add_fields>(fields: &mut F) { impl_file_fields!(fields); diff --git a/yazi-binding/src/lib.rs b/yazi-binding/src/lib.rs index e23749be..c09b2627 100644 --- a/yazi-binding/src/lib.rs +++ b/yazi-binding/src/lib.rs @@ -2,4 +2,4 @@ mod macros; yazi_macro::mod_pub!(elements); -yazi_macro::mod_flat!(cha color composer error file handle icon id iter path permit runtime scheme stage style url utils); +yazi_macro::mod_flat!(cha chord_cow color composer error file handle icon id iter path permit runtime scheme stage style url utils); diff --git a/yazi-binding/src/path.rs b/yazi-binding/src/path.rs index 609c18b0..47ab66ae 100644 --- a/yazi-binding/src/path.rs +++ b/yazi-binding/src/path.rs @@ -1,12 +1,14 @@ use std::ops::Deref; -use mlua::{ExternalError, ExternalResult, FromLua, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; +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; pub type PathRef = UserDataRef; +#[derive(FromLuaOwned)] pub struct Path { inner: PathBufDyn, @@ -106,15 +108,6 @@ impl Path { } } -impl FromLua for Path { - fn from_lua(value: Value, _: &Lua) -> mlua::Result { - Ok(match value { - Value::UserData(ud) => ud.take()?, - _ => Err("Expected a Path".into_lua_err())?, - }) - } -} - impl UserData for Path { fn add_fields>(fields: &mut F) { cached_field!(fields, ext, |lua, me| { diff --git a/yazi-binding/src/url.rs b/yazi-binding/src/url.rs index 41da1ef6..d9c449f0 100644 --- a/yazi-binding/src/url.rs +++ b/yazi-binding/src/url.rs @@ -1,15 +1,17 @@ use std::ops::Deref; -use mlua::{AnyUserData, ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; +use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; +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 crate::{Path, Scheme, cached_field, deprecate}; +use crate::{Path, Scheme, cached_field}; pub type UrlRef = UserDataRef; const EXPECTED: &str = "expected a string, Url, or Path"; +#[derive(FromLuaOwned)] pub struct Url { inner: yazi_shared::url::UrlBuf, @@ -162,15 +164,6 @@ impl Url { } } -impl FromLua for Url { - fn from_lua(value: Value, _: &Lua) -> mlua::Result { - Ok(match value { - Value::UserData(ud) => ud.take()?, - _ => Err("Expected a Url".into_lua_err())?, - }) - } -} - impl UserData for Url { fn add_fields>(fields: &mut F) { cached_field!(fields, path, |_, me| Ok(Path::new(me.loc()))); @@ -196,11 +189,6 @@ impl UserData for Url { cached_field!(fields, cache, |_, me| Ok(me.cache().map(Path::new))); - fields.add_field_method_get("frag", |lua, me| { - deprecate!(lua, "`frag` property of Url is deprecated and renamed to `domain`, please use the new name instead, in your {}"); - me.scheme().domain().map(|s| lua.create_string(s)).transpose() - }); - fields.add_field_method_get("is_regular", |_, me| Ok(me.is_regular())); fields.add_field_method_get("is_search", |_, me| Ok(me.is_search())); fields.add_field_method_get("is_archive", |_, me| Ok(me.is_archive())); diff --git a/yazi-codegen/Cargo.toml b/yazi-codegen/Cargo.toml index baf24254..3b75e411 100644 --- a/yazi-codegen/Cargo.toml +++ b/yazi-codegen/Cargo.toml @@ -17,4 +17,4 @@ proc-macro = true [dependencies] # External dependencies syn = { version = "2.0.114", features = [ "full" ] } -quote = "1.0.43" +quote = "1.0.44" diff --git a/yazi-codegen/src/lib.rs b/yazi-codegen/src/lib.rs index 02bcf65c..d5d40ba0 100644 --- a/yazi-codegen/src/lib.rs +++ b/yazi-codegen/src/lib.rs @@ -144,3 +144,28 @@ pub fn deserialize_over2(input: TokenStream) -> TokenStream { } .into() } + +#[proc_macro_derive(FromLuaOwned)] +pub fn from_lua(input: TokenStream) -> TokenStream { + let DeriveInput { ident, generics, .. } = parse_macro_input!(input as DeriveInput); + + let ident_str = ident.to_string(); + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + quote! { + impl #impl_generics ::mlua::FromLua for #ident #ty_generics #where_clause { + #[inline] + fn from_lua(value: ::mlua::Value, _: &::mlua::Lua) -> ::mlua::Result { + match value { + ::mlua::Value::UserData(ud) => ud.take::(), + _ => Err(::mlua::Error::FromLuaConversionError { + from: value.type_name(), + to: #ident_str.to_owned(), + message: None, + }), + } + } + } + } + .into() +} diff --git a/yazi-config/src/keymap/cow.rs b/yazi-config/src/keymap/cow.rs index e9a1199f..d30e25b2 100644 --- a/yazi-config/src/keymap/cow.rs +++ b/yazi-config/src/keymap/cow.rs @@ -30,14 +30,17 @@ impl Deref for ChordCow { } impl Default for ChordCow { - fn default() -> Self { Self::Owned(Chord::default()) } + fn default() -> Self { + const C: &Chord = &Chord { on: vec![], run: vec![], desc: None, r#for: None }; + Self::Borrowed(C) + } } impl ChordCow { pub fn into_seq(self) -> Vec { match self { - Self::Owned(c) => c.run.into_iter().rev().map(|c| c.into()).collect(), - Self::Borrowed(c) => c.run.iter().rev().map(|c| c.into()).collect(), + Self::Owned(c) => c.run.into_iter().rev().map(Into::into).collect(), + Self::Borrowed(c) => c.run.iter().rev().map(Into::into).collect(), } } } diff --git a/yazi-core/src/which/sorter.rs b/yazi-core/src/which/sorter.rs index c5ced22c..a74c9215 100644 --- a/yazi-core/src/which/sorter.rs +++ b/yazi-core/src/which/sorter.rs @@ -23,7 +23,7 @@ impl Default for WhichSorter { } impl WhichSorter { - pub(super) fn sort(&self, items: &mut Vec) { + pub fn sort(&self, items: &mut Vec) { if self.by == SortBy::None || items.is_empty() { return; } diff --git a/yazi-core/src/which/which.rs b/yazi-core/src/which/which.rs index 3c2c7d68..d499f1a6 100644 --- a/yazi-core/src/which/which.rs +++ b/yazi-core/src/which/which.rs @@ -1,8 +1,5 @@ -use yazi_config::{KEYMAP, keymap::{ChordCow, Key}}; -use yazi_macro::{emit, render, render_and}; -use yazi_shared::Layer; - -use crate::which::WhichSorter; +use yazi_config::keymap::{ChordCow, Key}; +use yazi_macro::{emit, render_and}; #[derive(Default)] pub struct Which { @@ -39,19 +36,4 @@ impl Which { self.visible = false; self.silent = false; } - - pub fn show_with(&mut self, key: Key, layer: Layer) { - self.times = 1; - self.cands = KEYMAP - .get(layer) - .iter() - .filter(|c| c.on.len() > 1 && c.on[0] == key) - .map(|c| c.into()) - .collect(); - - WhichSorter::default().sort(&mut self.cands); - self.visible = true; - self.silent = false; - render!(); - } } diff --git a/yazi-dds/src/spark/kind.rs b/yazi-dds/src/spark/kind.rs index bea38725..1ab6c3fd 100644 --- a/yazi-dds/src/spark/kind.rs +++ b/yazi-dds/src/spark/kind.rs @@ -2,27 +2,31 @@ use std::fmt::Display; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum SparkKind { - // Sort + // sort KeySort, IndSort, - // Stash + // stash IndStash, RelayStash, - // Quit + // quit KeyQuit, + // which:show + IndWhichShow, } impl AsRef for SparkKind { fn as_ref(&self) -> &str { match self { - // Sort + // sort Self::KeySort => "key-sort", Self::IndSort => "ind-sort", - // Stash + // stash Self::IndStash => "ind-stash", Self::RelayStash => "relay-stash", - // Quit + // quit Self::KeyQuit => "key-quit", + // which:show + Self::IndWhichShow => "ind-which-show", } } } diff --git a/yazi-dds/src/spark/spark.rs b/yazi-dds/src/spark/spark.rs index 8aad493a..dc8d3a93 100644 --- a/yazi-dds/src/spark/spark.rs +++ b/yazi-dds/src/spark/spark.rs @@ -140,14 +140,16 @@ impl<'a> Spark<'a> { use SparkKind::*; Ok(match kind { - // Sort + // sort KeySort => Self::Sort(<_>::from_lua(value, lua)?), IndSort => Self::Sort(<_>::from_lua(value, lua)?), - // Stash + // stash IndStash => Self::Stash(<_>::from_lua(value, lua)?), RelayStash => Self::Stash(<_>::from_lua(value, lua)?), - // Quit + // quit KeyQuit => Self::Quit(<_>::from_lua(value, lua)?), + // which:show + IndWhichShow => Self::WhichShow(<_>::from_lua(value, lua)?), }) } } diff --git a/yazi-fm/src/router.rs b/yazi-fm/src/router.rs index b90fb540..df6febe0 100644 --- a/yazi-fm/src/router.rs +++ b/yazi-fm/src/router.rs @@ -1,6 +1,7 @@ use anyhow::Result; +use yazi_actor::Ctx; use yazi_config::{KEYMAP, keymap::{Chord, ChordCow, Key}}; -use yazi_macro::emit; +use yazi_macro::{act, emit}; use yazi_shared::Layer; use crate::app::App; @@ -41,7 +42,8 @@ impl<'a> Router<'a> { } if on.len() > 1 { - self.app.core.which.show_with(key, layer); + let cx = &mut Ctx::active(&mut self.app.core); + act!(which:show, cx, (layer, key)).ok(); } else { emit!(Seq(ChordCow::from(chord).into_seq())); } diff --git a/yazi-parser/src/which/show.rs b/yazi-parser/src/which/show.rs index 41a2440a..8e1039f5 100644 --- a/yazi-parser/src/which/show.rs +++ b/yazi-parser/src/which/show.rs @@ -1,29 +1,68 @@ -use mlua::{ExternalError, FromLua, IntoLua, Lua, Value}; -use yazi_config::keymap::Chord; -use yazi_shared::event::CmdCow; +use anyhow::bail; +use mlua::{ExternalError, FromLua, IntoLua, Lua, Table, Value}; +use yazi_config::{KEYMAP, keymap::{ChordCow, Key}}; +use yazi_shared::{Layer, event::CmdCow}; #[derive(Debug)] pub struct ShowOpt { - pub cands: Vec, + pub cands: Vec, pub silent: bool, + pub times: usize, } impl TryFrom for ShowOpt { type Error = anyhow::Error; fn try_from(mut c: CmdCow) -> Result { - if let Some(opt) = c.take_any2("opt") { - return opt; + match c.take_any2("opt") { + Some(opt) => opt, + None => bail!("missing 'opt' argument"), } + } +} - Ok(Self { cands: c.take_any("candidates").unwrap_or_default(), silent: c.bool("silent") }) +impl From<(Layer, Key)> for ShowOpt { + fn from((layer, key): (Layer, Key)) -> Self { + Self { + cands: KEYMAP + .get(layer) + .iter() + .filter(|c| c.on.len() > 1 && c.on[0] == key) + .map(Into::into) + .collect(), + times: 1, + silent: false, + } } } impl FromLua for ShowOpt { - fn from_lua(_: Value, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + let Value::Table(t) = value else { + return Err("expected a table".into_lua_err()); + }; + + Ok(ShowOpt { + cands: t + .raw_get::("cands")? + .sequence_values::() + .map(|c| c.map(Into::into)) + .collect::>>()?, + times: t.raw_get("times").unwrap_or_default(), + silent: t.raw_get("silent")?, + }) + } } impl IntoLua for ShowOpt { - fn into_lua(self, _: &Lua) -> mlua::Result { Err("unsupported".into_lua_err()) } + #[rustfmt::skip] + fn into_lua(self, lua: &Lua) -> mlua::Result { + lua + .create_table_from([ + ("cands", lua.create_sequence_from(self.cands.into_iter().map(yazi_binding::ChordCow))?.into_lua(lua)?), + ("times", self.times.into_lua(lua)?), + ("silent", self.silent.into_lua(lua)?), + ])? + .into_lua(lua) + } } diff --git a/yazi-plugin/preset/plugins/mime.lua b/yazi-plugin/preset/plugins/mime.lua index 37f82421..e69de29b 100644 --- a/yazi-plugin/preset/plugins/mime.lua +++ b/yazi-plugin/preset/plugins/mime.lua @@ -1,12 +0,0 @@ -local function fetch(_, job) - ya.notify { - title = "Deprecated plugin", - content = "The `mime` fetcher is deprecated, use `mime.local` instead in your `yazi.toml`\n\nSee https://github.com/sxyazi/yazi/pull/3222 for more details.", - timeout = 15, - level = "warn", - } - - return require("mime.local"):fetch(job) -end - -return { fetch = fetch } diff --git a/yazi-plugin/src/elements/elements.rs b/yazi-plugin/src/elements/elements.rs index af94fe47..af16cb1f 100644 --- a/yazi-plugin/src/elements/elements.rs +++ b/yazi-plugin/src/elements/elements.rs @@ -138,7 +138,7 @@ pub(super) fn truncate(lua: &Lua) -> mlua::Result { } let lossy = String::from_utf8_lossy(&b); - let rtl = t.raw_get("rtl").unwrap_or(false); + let rtl = t.raw_get("rtl")?; let (idx, width, remain) = if rtl { traverse(lossy.char_indices().rev(), max) } else { diff --git a/yazi-plugin/src/fs/fs.rs b/yazi-plugin/src/fs/fs.rs index 2cc15b77..3fd3d09e 100644 --- a/yazi-plugin/src/fs/fs.rs +++ b/yazi-plugin/src/fs/fs.rs @@ -134,7 +134,7 @@ fn read_dir(lua: &Lua) -> mlua::Result { }; let limit = options.raw_get("limit").unwrap_or(usize::MAX); - let resolve = options.raw_get("resolve").unwrap_or(false); + let resolve = options.raw_get::("resolve")?; let mut it = match provider::read_dir(&*dir).await { Ok(it) => it, diff --git a/yazi-plugin/src/loader/loader.rs b/yazi-plugin/src/loader/loader.rs index 5ef40fa9..b689a695 100644 --- a/yazi-plugin/src/loader/loader.rs +++ b/yazi-plugin/src/loader/loader.rs @@ -38,7 +38,7 @@ impl Default for Loader { ("image".to_owned(), preset!("plugins/image").into()), ("json".to_owned(), preset!("plugins/json").into()), ("magick".to_owned(), preset!("plugins/magick").into()), - ("mime".to_owned(), preset!("plugins/mime").into()), // TODO: remove this + ("mime".to_owned(), preset!("plugins/mime").into()), ("mime.dir".to_owned(), preset!("plugins/mime-dir").into()), ("mime.local".to_owned(), preset!("plugins/mime-local").into()), ("mime.remote".to_owned(), preset!("plugins/mime-remote").into()), diff --git a/yazi-plugin/src/theme/theme.rs b/yazi-plugin/src/theme/theme.rs index 49015e5c..2a8489c4 100644 --- a/yazi-plugin/src/theme/theme.rs +++ b/yazi-plugin/src/theme/theme.rs @@ -1,5 +1,5 @@ use mlua::{IntoLua, Lua, Value}; -use yazi_binding::{Composer, ComposerGet, ComposerSet, Style, Url, deprecate}; +use yazi_binding::{Composer, ComposerGet, ComposerSet, Style, Url}; use yazi_config::THEME; pub fn compose() -> Composer { @@ -51,21 +51,6 @@ fn mgr() -> Composer { match key { b"cwd" => Style::from(m.cwd).into_lua(lua), - b"hovered" => { - deprecate!( - lua, - "`th.mgr.hovered` is deprecated, use `th.indicator.current` instead, in your {}\nSee #3419 for more details: https://github.com/sxyazi/yazi/pull/3419" - ); - Style::from(THEME.indicator.current).into_lua(lua) - } - b"preview_hovered" => { - deprecate!( - lua, - "`th.mgr.preview_hovered` is deprecated, use `th.indicator.preview` instead, in your {}\nSee #3419 for more details: https://github.com/sxyazi/yazi/pull/3419" - ); - Style::from(THEME.indicator.preview).into_lua(lua) - } - b"find_keyword" => Style::from(m.find_keyword).into_lua(lua), b"find_position" => Style::from(m.find_position).into_lua(lua), diff --git a/yazi-plugin/src/utils/app.rs b/yazi-plugin/src/utils/app.rs index ec48ebbd..8481871b 100644 --- a/yazi-plugin/src/utils/app.rs +++ b/yazi-plugin/src/utils/app.rs @@ -2,8 +2,7 @@ use std::any::TypeId; use mlua::{AnyUserData, ExternalError, Function, Lua}; use tokio::process::{ChildStderr, ChildStdin, ChildStdout}; -use yazi_binding::{Id, Permit, PermitRef, deprecate}; -use yazi_proxy::{AppProxy, HIDER}; +use yazi_binding::Id; use super::Utils; @@ -30,20 +29,4 @@ impl Utils { ud.destroy() }) } - - pub(super) fn hide(lua: &Lua) -> mlua::Result { - lua.create_async_function(|lua, ()| async move { - deprecate!(lua, "`ya.hide()` is deprecated, use `ui.hide()` instead, in your {}\nSee #2939 for more details: https://github.com/sxyazi/yazi/pull/2939"); - - if lua.named_registry_value::("HIDE_PERMIT").is_ok_and(|h| h.is_some()) { - return Err("Cannot hide while already hidden".into_lua_err()); - } - - let permit = HIDER.acquire().await.unwrap(); - AppProxy::stop().await; - - lua.set_named_registry_value("HIDE_PERMIT", Permit::new(permit, AppProxy::resume()))?; - lua.named_registry_value::("HIDE_PERMIT") - }) - } } diff --git a/yazi-plugin/src/utils/call.rs b/yazi-plugin/src/utils/call.rs index ba320088..4b68bd9b 100644 --- a/yazi-plugin/src/utils/call.rs +++ b/yazi-plugin/src/utils/call.rs @@ -1,21 +1,11 @@ use mlua::{Function, Lua, Table}; -use yazi_binding::deprecate; use yazi_dds::Sendable; -use yazi_macro::{emit, render}; +use yazi_macro::emit; use yazi_shared::{Layer, Source, event::Cmd}; use super::Utils; impl Utils { - pub(super) fn render(lua: &Lua) -> mlua::Result { - lua.create_function(|lua, ()| { - deprecate!(lua, "`ya.render()` is deprecated, use `ui.render()` instead, in your {}\nSee #2939 for more details: https://github.com/sxyazi/yazi/pull/2939"); - - render!(); - Ok(()) - }) - } - pub(super) fn emit(lua: &Lua) -> mlua::Result { lua.create_function(|lua, (name, args): (String, Table)| { let mut cmd = Cmd::new(name, Source::Emit, Some(Layer::Mgr))?; diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index e688b716..129402bd 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -3,8 +3,8 @@ use std::{str::FromStr, time::Duration}; use mlua::{ExternalError, ExternalResult, Function, IntoLuaMulti, Lua, Table, Value}; use tokio::sync::mpsc; use tokio_stream::wrappers::UnboundedReceiverStream; -use yazi_binding::{deprecate, elements::{Line, Pos, Text}, runtime}; -use yazi_config::{keymap::{Chord, Key}, popup::{ConfirmCfg, InputCfg}}; +use yazi_binding::{elements::{Line, Pos, Text}, runtime}; +use yazi_config::{keymap::{Chord, ChordCow, Key}, popup::{ConfirmCfg, InputCfg}}; use yazi_macro::relay; use yazi_parser::which::ShowOpt; use yazi_proxy::{AppProxy, ConfirmProxy, InputProxy, WhichProxy}; @@ -27,17 +27,17 @@ impl Utils { .enumerate() .map(|(i, cand)| { let cand = cand?; - Ok(Chord { + Ok(ChordCow::Owned(Chord { on: Self::parse_keys(cand.raw_get("on")?)?, run: vec![relay!(which:callback, [i]).with_any("tx", tx.clone())], desc: cand.raw_get("desc").ok(), r#for: None, - }) + })) }) .collect::>()?; drop(tx); - WhichProxy::show(ShowOpt { cands, silent: t.raw_get("silent").unwrap_or_default() }); + WhichProxy::show(ShowOpt { cands, times: 0, silent: t.raw_get("silent")? }); Ok(rx.recv().await.map(|idx| idx + 1)) }) @@ -49,21 +49,13 @@ impl Utils { return Err("Cannot call `ya.input()` while main thread is blocked".into_lua_err()); } - let mut pos = t.raw_get::("pos")?; - if pos.is_nil() { - pos = t.raw_get("position")?; - if !pos.is_nil() { - deprecate!(lua, "The `position` property of `ya.input()` is deprecated, use `pos` instead in your {}\nSee #2921 for more details: https://github.com/sxyazi/yazi/pull/2921"); - } - } - - let realtime = t.raw_get("realtime").unwrap_or_default(); + let realtime = t.raw_get("realtime")?; let rx = UnboundedReceiverStream::new(InputProxy::show(InputCfg { title: t.raw_get("title")?, value: t.raw_get("value").unwrap_or_default(), cursor: None, // TODO - obscure: t.raw_get("obscure").unwrap_or_default(), - position: Pos::new_input(pos)?.into(), + obscure: t.raw_get("obscure")?, + position: Pos::new_input(t.raw_get("pos")?)?.into(), realtime, completion: false, })); diff --git a/yazi-plugin/src/utils/text.rs b/yazi-plugin/src/utils/text.rs index 0b34d0e2..ed892f34 100644 --- a/yazi-plugin/src/utils/text.rs +++ b/yazi-plugin/src/utils/text.rs @@ -1,7 +1,5 @@ -use mlua::{Function, Lua, Table}; +use mlua::{Function, Lua}; use twox_hash::XxHash3_128; -use unicode_width::UnicodeWidthChar; -use yazi_binding::deprecate; use yazi_widgets::CLIPBOARD; use super::Utils; @@ -25,66 +23,6 @@ impl Utils { }) } - pub(super) fn truncate(lua: &Lua) -> mlua::Result { - fn traverse( - it: impl Iterator, - max: usize, - ) -> (Option, usize, bool) { - let (mut adv, mut last) = (0, 0); - let idx = it - .take_while(|&(_, c)| { - (last, adv) = (adv, adv + c.width().unwrap_or(0)); - adv <= max - }) - .map(|(i, _)| i) - .last(); - (idx, last, adv > max) - } - - lua.create_function(|lua, (s, t): (mlua::String, Table)| { - deprecate!(lua, "`ya.truncate()` is deprecated, use `ui.truncate()` instead, in your {}\nSee #2939 for more details: https://github.com/sxyazi/yazi/pull/2939"); - - let b = s.as_bytes(); - if b.is_empty() { - return Ok(s); - } - - let max = t.raw_get("max")?; - if b.len() <= max { - return Ok(s); - } else if max < 1 { - return lua.create_string(""); - } - - let lossy = String::from_utf8_lossy(&b); - let rtl = t.raw_get("rtl").unwrap_or(false); - let (idx, width, remain) = if rtl { - traverse(lossy.char_indices().rev(), max) - } else { - traverse(lossy.char_indices(), max) - }; - - let Some(idx) = idx else { return lua.create_string("…") }; - if !remain { - return Ok(s); - } - - let result: Vec<_> = match (rtl, width == max) { - (false, false) => { - let len = lossy[idx..].chars().next().map_or(0, |c| c.len_utf8()); - lossy[..idx + len].bytes().chain("…".bytes()).collect() - } - (false, true) => lossy[..idx].bytes().chain("…".bytes()).collect(), - (true, false) => "…".bytes().chain(lossy[idx..].bytes()).collect(), - (true, true) => { - let len = lossy[idx..].chars().next().map_or(0, |c| c.len_utf8()); - "…".bytes().chain(lossy[idx + len..].bytes()).collect() - } - }; - lua.create_string(result) - }) - } - pub(super) fn clipboard(lua: &Lua) -> mlua::Result { lua.create_async_function(|lua, text: Option| async move { if let Some(text) = text { diff --git a/yazi-plugin/src/utils/utils.rs b/yazi-plugin/src/utils/utils.rs index a6ffe9d0..fa246071 100644 --- a/yazi-plugin/src/utils/utils.rs +++ b/yazi-plugin/src/utils/utils.rs @@ -11,13 +11,11 @@ pub fn compose( // App b"id" => Utils::id(lua)?, b"drop" => Utils::drop(lua)?, - b"hide" => Utils::hide(lua)?, // Cache b"file_cache" => Utils::file_cache(lua)?, // Call - b"render" => Utils::render(lua)?, b"emit" => Utils::emit(lua)?, b"mgr_emit" => Utils::mgr_emit(lua)?, @@ -65,7 +63,6 @@ pub fn compose( // Text b"hash" => Utils::hash(lua)?, b"quote" => Utils::quote(lua)?, - b"truncate" => Utils::truncate(lua)?, b"clipboard" => Utils::clipboard(lua)?, // Time