diff --git a/yazi-core/src/completion/commands/show.rs b/yazi-core/src/completion/commands/show.rs index 86476b43..60c49918 100644 --- a/yazi-core/src/completion/commands/show.rs +++ b/yazi-core/src/completion/commands/show.rs @@ -19,9 +19,9 @@ impl From for Opt { // cache: mem::take(&mut c.args), // TODO: Fix this cache: vec![], - cache_name: c.take_name_str("cache-name").unwrap_or_default(), - word: c.take_name_str("word").unwrap_or_default(), - ticket: c.take_name_str("ticket").and_then(|v| v.parse().ok()).unwrap_or(0), + cache_name: c.take_str("cache-name").unwrap_or_default(), + word: c.take_str("word").unwrap_or_default(), + ticket: c.take_str("ticket").and_then(|v| v.parse().ok()).unwrap_or(0), } } } diff --git a/yazi-core/src/completion/commands/trigger.rs b/yazi-core/src/completion/commands/trigger.rs index ab46984a..d64bc0fc 100644 --- a/yazi-core/src/completion/commands/trigger.rs +++ b/yazi-core/src/completion/commands/trigger.rs @@ -20,7 +20,7 @@ impl From for Opt { fn from(mut c: Cmd) -> Self { Self { word: c.take_first_str().unwrap_or_default(), - ticket: c.take_name_str("ticket").and_then(|s| s.parse().ok()).unwrap_or(0), + ticket: c.take_str("ticket").and_then(|s| s.parse().ok()).unwrap_or(0), } } } diff --git a/yazi-core/src/input/commands/complete.rs b/yazi-core/src/input/commands/complete.rs index 82c592c4..e2272695 100644 --- a/yazi-core/src/input/commands/complete.rs +++ b/yazi-core/src/input/commands/complete.rs @@ -19,7 +19,7 @@ impl From for Opt { fn from(mut c: Cmd) -> Self { Self { word: c.take_first_str().unwrap_or_default(), - ticket: c.take_name_str("ticket").and_then(|s| s.parse().ok()).unwrap_or(0), + ticket: c.take_str("ticket").and_then(|s| s.parse().ok()).unwrap_or(0), } } } diff --git a/yazi-core/src/manager/commands/peek.rs b/yazi-core/src/manager/commands/peek.rs index 36bff3f9..2c3e40b9 100644 --- a/yazi-core/src/manager/commands/peek.rs +++ b/yazi-core/src/manager/commands/peek.rs @@ -15,7 +15,7 @@ impl From for Opt { Self { skip: c.take_first_str().and_then(|s| s.parse().ok()), force: c.get_bool("force"), - only_if: c.take_name_str("only-if").map(Url::from), + only_if: c.take_str("only-if").map(Url::from), upper_bound: c.get_bool("upper-bound"), } } diff --git a/yazi-core/src/manager/commands/remove.rs b/yazi-core/src/manager/commands/remove.rs index 521c6e3e..3826b175 100644 --- a/yazi-core/src/manager/commands/remove.rs +++ b/yazi-core/src/manager/commands/remove.rs @@ -15,7 +15,7 @@ impl From for Opt { Self { force: c.get_bool("force"), permanently: c.get_bool("permanently"), - targets: c.take_data().unwrap_or_default(), + targets: c.take_any("targets").unwrap_or_default(), } } } diff --git a/yazi-core/src/manager/commands/rename.rs b/yazi-core/src/manager/commands/rename.rs index e786bead..d9fffff4 100644 --- a/yazi-core/src/manager/commands/rename.rs +++ b/yazi-core/src/manager/commands/rename.rs @@ -19,8 +19,8 @@ impl From for Opt { fn from(mut c: Cmd) -> Self { Self { force: c.get_bool("force"), - empty: c.take_name_str("empty").unwrap_or_default(), - cursor: c.take_name_str("cursor").unwrap_or_default(), + empty: c.take_str("empty").unwrap_or_default(), + cursor: c.take_str("cursor").unwrap_or_default(), } } } diff --git a/yazi-core/src/manager/commands/update_files.rs b/yazi-core/src/manager/commands/update_files.rs index 690d3e74..6be2cfcd 100644 --- a/yazi-core/src/manager/commands/update_files.rs +++ b/yazi-core/src/manager/commands/update_files.rs @@ -12,7 +12,9 @@ pub struct Opt { impl TryFrom for Opt { type Error = (); - fn try_from(mut c: Cmd) -> Result { Ok(Self { op: c.take_data().ok_or(())? }) } + fn try_from(mut c: Cmd) -> Result { + Ok(Self { op: c.take_any("op").ok_or(())? }) + } } impl Manager { diff --git a/yazi-core/src/manager/commands/update_mimetype.rs b/yazi-core/src/manager/commands/update_mimetype.rs index 9e8131d1..23c425ec 100644 --- a/yazi-core/src/manager/commands/update_mimetype.rs +++ b/yazi-core/src/manager/commands/update_mimetype.rs @@ -1,18 +1,18 @@ use std::collections::HashMap; -use yazi_shared::{event::{Cmd, Data}, fs::Url, render}; +use yazi_shared::{event::Cmd, fs::Url, render}; use crate::{manager::{Manager, LINKED}, tasks::Tasks}; pub struct Opt { - data: Data, + updates: HashMap, } impl TryFrom for Opt { type Error = (); fn try_from(mut c: Cmd) -> Result { - Ok(Self { data: c.take_data().ok_or(())? }) + Ok(Self { updates: c.take_data("updates").ok_or(())?.into_table_string() }) } } @@ -24,8 +24,7 @@ impl Manager { let linked = LINKED.read(); let updates = opt - .data - .into_table_string() + .updates .into_iter() .map(|(url, mime)| (Url::from(url), mime)) .filter(|(url, mime)| self.mimetype.get(url) != Some(mime)) diff --git a/yazi-core/src/manager/commands/update_paged.rs b/yazi-core/src/manager/commands/update_paged.rs index 165f8693..378c874e 100644 --- a/yazi-core/src/manager/commands/update_paged.rs +++ b/yazi-core/src/manager/commands/update_paged.rs @@ -12,7 +12,7 @@ impl From for Opt { fn from(mut c: Cmd) -> Self { Self { page: c.take_first_str().and_then(|s| s.parse().ok()), - only_if: c.take_name_str("only-if").map(Url::from), + only_if: c.take_str("only-if").map(Url::from), } } } diff --git a/yazi-core/src/tab/commands/preview.rs b/yazi-core/src/tab/commands/preview.rs index 8c1b68a2..ed838b82 100644 --- a/yazi-core/src/tab/commands/preview.rs +++ b/yazi-core/src/tab/commands/preview.rs @@ -11,7 +11,7 @@ impl TryFrom for Opt { type Error = (); fn try_from(mut c: Cmd) -> Result { - Ok(Self { lock: c.take_data().ok_or(())? }) + Ok(Self { lock: c.take_any("lock").ok_or(())? }) } } diff --git a/yazi-core/src/tab/commands/select.rs b/yazi-core/src/tab/commands/select.rs index b4ad21c6..75382923 100644 --- a/yazi-core/src/tab/commands/select.rs +++ b/yazi-core/src/tab/commands/select.rs @@ -13,8 +13,8 @@ pub struct Opt<'a> { impl<'a> From for Opt<'a> { fn from(mut c: Cmd) -> Self { Self { - url: c.take_name_str("url").map(|s| Cow::Owned(Url::from(s))), - state: match c.take_name_str("state").as_deref() { + url: c.take_str("url").map(|s| Cow::Owned(Url::from(s))), + state: match c.take_str("state").as_deref() { Some("true") => Some(true), Some("false") => Some(false), _ => None, diff --git a/yazi-core/src/tab/commands/select_all.rs b/yazi-core/src/tab/commands/select_all.rs index a3a9b61d..f87f9b70 100644 --- a/yazi-core/src/tab/commands/select_all.rs +++ b/yazi-core/src/tab/commands/select_all.rs @@ -10,7 +10,7 @@ pub struct Opt { impl From for Opt { fn from(mut c: Cmd) -> Self { Self { - state: match c.take_name_str("state").as_deref() { + state: match c.take_str("state").as_deref() { Some("true") => Some(true), Some("false") => Some(false), _ => None, diff --git a/yazi-core/src/tasks/tasks.rs b/yazi-core/src/tasks/tasks.rs index 2b680d46..1f137867 100644 --- a/yazi-core/src/tasks/tasks.rs +++ b/yazi-core/src/tasks/tasks.rs @@ -29,7 +29,7 @@ impl Tasks { let new = TasksProgress::from(&*ongoing.lock()); if last != new { last = new; - emit!(Call(Cmd::new("update_progress").with_data(new), Layer::App)); + emit!(Call(Cmd::new("update_progress").with_any("progress", new), Layer::App)); } } }); diff --git a/yazi-core/src/which/commands/callback.rs b/yazi-core/src/which/commands/callback.rs index 6c2ce1aa..3970f214 100644 --- a/yazi-core/src/which/commands/callback.rs +++ b/yazi-core/src/which/commands/callback.rs @@ -14,7 +14,7 @@ impl TryFrom for Opt { fn try_from(mut c: Cmd) -> Result { Ok(Self { - tx: c.take_data().ok_or(())?, + tx: c.take_any("tx").ok_or(())?, idx: c.take_first_str().and_then(|s| s.parse().ok()).ok_or(())?, }) } diff --git a/yazi-core/src/which/commands/show.rs b/yazi-core/src/which/commands/show.rs index 8cae69f0..ea68d690 100644 --- a/yazi-core/src/which/commands/show.rs +++ b/yazi-core/src/which/commands/show.rs @@ -16,8 +16,8 @@ impl TryFrom for Opt { fn try_from(mut c: Cmd) -> Result { Ok(Self { - cands: c.take_data().unwrap_or_default(), - layer: Layer::from_str(&c.take_name_str("layer").unwrap_or_default())?, + cands: c.take_any("candidates").unwrap_or_default(), + layer: Layer::from_str(&c.take_str("layer").unwrap_or_default())?, silent: c.get_bool("silent"), }) } diff --git a/yazi-dds/src/payload.rs b/yazi-dds/src/payload.rs index 2365dc61..855a7794 100644 --- a/yazi-dds/src/payload.rs +++ b/yazi-dds/src/payload.rs @@ -67,7 +67,7 @@ impl Payload<'static> { pub(super) fn emit(self) { self.try_flush(); - emit!(Call(Cmd::new("accept_payload").with_data(self), Layer::App)); + emit!(Call(Cmd::new("accept_payload").with_any("payload", self), Layer::App)); } } diff --git a/yazi-fm/src/app/commands/accept_payload.rs b/yazi-fm/src/app/commands/accept_payload.rs index 6e678187..7048a6e5 100644 --- a/yazi-fm/src/app/commands/accept_payload.rs +++ b/yazi-fm/src/app/commands/accept_payload.rs @@ -8,7 +8,7 @@ use crate::{app::App, lives::Lives}; impl App { pub(crate) fn accept_payload(&mut self, mut cmd: Cmd) { - let Some(payload) = cmd.take_data::() else { + let Some(payload) = cmd.take_any::("payload") else { return; }; diff --git a/yazi-fm/src/app/commands/plugin.rs b/yazi-fm/src/app/commands/plugin.rs index 9b8e43e6..cc2ee9be 100644 --- a/yazi-fm/src/app/commands/plugin.rs +++ b/yazi-fm/src/app/commands/plugin.rs @@ -4,7 +4,7 @@ use mlua::TableExt; use scopeguard::defer; use tracing::warn; use yazi_dds::Sendable; -use yazi_plugin::{loader::LOADER, OptData, RtRef, LUA}; +use yazi_plugin::{loader::LOADER, RtRef, LUA}; use yazi_shared::{emit, event::Cmd, Layer}; use crate::{app::App, lives::Lives}; @@ -17,7 +17,7 @@ impl App { }; if !opt.sync { - return self.cx.tasks.plugin_micro(opt.name, opt.data.args); + return self.cx.tasks.plugin_micro(opt.name, opt.args); } if LOADER.read().contains_key(&opt.name) { @@ -26,14 +26,15 @@ impl App { tokio::spawn(async move { if LOADER.ensure(&opt.name).await.is_ok() { - Self::_plugin_do(opt.name, opt.data); + Self::_plugin_do(opt); } }); } #[inline] - pub(crate) fn _plugin_do(name: String, data: OptData) { - emit!(Call(Cmd::args("plugin_do", vec![name]).with_data(data), Layer::App)); + pub(crate) fn _plugin_do(opt: yazi_plugin::Opt) { + let cmd: Cmd = opt.into(); + emit!(Call(cmd.with_name("plugin_do"), Layer::App)); } pub(crate) fn plugin_do(&mut self, opt: impl TryInto) { @@ -54,10 +55,10 @@ impl App { }; _ = Lives::scope(&self.cx, |_| { - if let Some(cb) = opt.data.cb { + if let Some(cb) = opt.cb { cb(&LUA, plugin) } else { - plugin.call_method("entry", Sendable::vec_to_table(&LUA, opt.data.args)?) + plugin.call_method("entry", Sendable::vec_to_table(&LUA, opt.args)?) } }); } diff --git a/yazi-fm/src/app/commands/stop.rs b/yazi-fm/src/app/commands/stop.rs index cfc0e125..1088c7d7 100644 --- a/yazi-fm/src/app/commands/stop.rs +++ b/yazi-fm/src/app/commands/stop.rs @@ -8,7 +8,7 @@ pub struct Opt { } impl From for Opt { - fn from(mut c: Cmd) -> Self { Self { tx: c.take_data() } } + fn from(mut c: Cmd) -> Self { Self { tx: c.take_any("tx") } } } impl App { diff --git a/yazi-fm/src/app/commands/update_progress.rs b/yazi-fm/src/app/commands/update_progress.rs index ed2756b4..21a62690 100644 --- a/yazi-fm/src/app/commands/update_progress.rs +++ b/yazi-fm/src/app/commands/update_progress.rs @@ -12,7 +12,7 @@ impl TryFrom for Opt { type Error = (); fn try_from(mut c: Cmd) -> Result { - Ok(Self { progress: c.take_data().ok_or(())? }) + Ok(Self { progress: c.take_any("progress").ok_or(())? }) } } diff --git a/yazi-plugin/preset/plugins/mime.lua b/yazi-plugin/preset/plugins/mime.lua index 61327da3..33416965 100644 --- a/yazi-plugin/preset/plugins/mime.lua +++ b/yazi-plugin/preset/plugins/mime.lua @@ -22,18 +22,18 @@ function M:preload() return 0 end - local mimes, last = {}, ya.time() + local updates, last = {}, ya.time() local flush = function(force) if not force and ya.time() - last < 0.3 then return end - if next(mimes) then - ya.manager_emit("update_mimetype", {}, mimes) - mimes, last = {}, ya.time() + if next(updates) then + ya.manager_emit("update_mimetype", { updates = updates }) + updates, last = {}, ya.time() end end - local i, j, mime = 1, 0, nil + local i, j, valid = 1, 0, nil repeat local line, event = child:read_line_with { timeout = 300 } if event == 3 then @@ -43,11 +43,11 @@ function M:preload() break end - mime = match_mimetype(line) - if mime and string.find(line, mime, 1, true) ~= 1 then + valid = match_mimetype(line) + if valid and string.find(line, valid, 1, true) ~= 1 then goto continue - elseif mime then - j, mimes[urls[i]] = j + 1, mime + elseif valid then + j, updates[urls[i]] = j + 1, valid flush(false) end diff --git a/yazi-plugin/src/isolate/peek.rs b/yazi-plugin/src/isolate/peek.rs index 2ad97463..886caf94 100644 --- a/yazi-plugin/src/isolate/peek.rs +++ b/yazi-plugin/src/isolate/peek.rs @@ -6,7 +6,7 @@ use yazi_config::LAYOUT; use yazi_shared::{emit, event::Cmd, Layer}; use super::slim_lua; -use crate::{bindings::{Cast, File, Window}, elements::Rect, loader::LOADER, OptData, LUA}; +use crate::{bindings::{Cast, File, Window}, elements::Rect, loader::LOADER, Opt, OptCallback, LUA}; pub fn peek(cmd: &Cmd, file: yazi_shared::fs::File, skip: usize) -> CancellationToken { let ct = CancellationToken::new(); @@ -56,18 +56,16 @@ pub fn peek(cmd: &Cmd, file: yazi_shared::fs::File, skip: usize) -> Cancellation } pub fn peek_sync(cmd: &Cmd, file: yazi_shared::fs::File, skip: usize) { - let data = OptData { - cb: Some(Box::new(move |_, plugin| { - plugin.raw_set("file", File::cast(&LUA, file)?)?; - plugin.raw_set("skip", skip)?; - plugin.raw_set("area", Rect::cast(&LUA, LAYOUT.load().preview)?)?; - plugin.raw_set("window", Window::default())?; - plugin.call_method("peek", ()) - })), - ..Default::default() - }; - emit!(Call( - Cmd::args("plugin", vec![cmd.name.to_owned()]).with_bool("sync", true).with_data(data), - Layer::App - )); + let cb: OptCallback = Box::new(move |_, plugin| { + plugin.raw_set("file", File::cast(&LUA, file)?)?; + plugin.raw_set("skip", skip)?; + plugin.raw_set("area", Rect::cast(&LUA, LAYOUT.load().preview)?)?; + plugin.raw_set("window", Window::default())?; + plugin.call_method("peek", ()) + }); + + let cmd: Cmd = + Opt { name: cmd.name.to_owned(), sync: true, cb: Some(cb), ..Default::default() }.into(); + + emit!(Call(cmd.with_name("plugin"), Layer::App)); } diff --git a/yazi-plugin/src/isolate/seek.rs b/yazi-plugin/src/isolate/seek.rs index 56a3cdcc..74af4f86 100644 --- a/yazi-plugin/src/isolate/seek.rs +++ b/yazi-plugin/src/isolate/seek.rs @@ -2,19 +2,17 @@ use mlua::TableExt; use yazi_config::LAYOUT; use yazi_shared::{emit, event::Cmd, Layer}; -use crate::{bindings::{Cast, File}, elements::Rect, OptData, LUA}; +use crate::{bindings::{Cast, File}, elements::Rect, Opt, OptCallback, LUA}; pub fn seek_sync(cmd: &Cmd, file: yazi_shared::fs::File, units: i16) { - let data = OptData { - cb: Some(Box::new(move |_, plugin| { - plugin.raw_set("file", File::cast(&LUA, file)?)?; - plugin.raw_set("area", Rect::cast(&LUA, LAYOUT.load().preview)?)?; - plugin.call_method("seek", units) - })), - ..Default::default() - }; - emit!(Call( - Cmd::args("plugin", vec![cmd.name.to_owned()]).with_bool("sync", true).with_data(data), - Layer::App - )); + let cb: OptCallback = Box::new(move |_, plugin| { + plugin.raw_set("file", File::cast(&LUA, file)?)?; + plugin.raw_set("area", Rect::cast(&LUA, LAYOUT.load().preview)?)?; + plugin.call_method("seek", units) + }); + + let cmd: Cmd = + Opt { name: cmd.name.to_owned(), sync: true, cb: Some(cb), ..Default::default() }.into(); + + emit!(Call(cmd.with_name("plugin"), Layer::App)); } diff --git a/yazi-plugin/src/opt.rs b/yazi-plugin/src/opt.rs index 14b69cc8..898b1450 100644 --- a/yazi-plugin/src/opt.rs +++ b/yazi-plugin/src/opt.rs @@ -2,16 +2,14 @@ use anyhow::bail; use mlua::{Lua, Table}; use yazi_shared::event::{Cmd, Data}; +pub(super) type OptCallback = Box mlua::Result<()> + Send>; + +#[derive(Default)] pub struct Opt { pub name: String, pub sync: bool, - pub data: OptData, -} - -#[derive(Default)] -pub struct OptData { pub args: Vec, - pub cb: Option mlua::Result<()> + Send>>, + pub cb: Option, } impl TryFrom for Opt { @@ -22,12 +20,24 @@ impl TryFrom for Opt { bail!("plugin name cannot be empty"); }; - let mut data: OptData = c.take_data().unwrap_or_default(); + let args = if let Some(s) = c.get_str("args") { + shell_words::split(s)?.into_iter().map(Data::String).collect() + } else { + c.take_any::>("args").unwrap_or_default() + }; - if let Some(args) = c.get_str("args") { - data.args = shell_words::split(args)?.into_iter().map(Data::String).collect(); - } - - Ok(Self { name, sync: c.get_bool("sync"), data }) + Ok(Self { name, sync: c.get_bool("sync"), args, cb: c.take_any::("callback") }) + } +} + +impl From for Cmd { + fn from(value: Opt) -> Self { + let mut cmd = + Cmd::args("", vec![value.name]).with_bool("sync", value.sync).with_any("args", value.args); + + if let Some(cb) = value.cb { + cmd = cmd.with_any("callback", cb); + } + cmd } } diff --git a/yazi-plugin/src/utils/call.rs b/yazi-plugin/src/utils/call.rs index eb522e2d..3fe96a40 100644 --- a/yazi-plugin/src/utils/call.rs +++ b/yazi-plugin/src/utils/call.rs @@ -38,9 +38,9 @@ impl Utils { } #[inline] - fn create_cmd(name: String, table: Table, data: Option) -> mlua::Result { + fn create_cmd(name: String, args: Value) -> mlua::Result { // TODO: Fix this - return Ok(Cmd { name, args: Default::default(), data: None }); + return Ok(Cmd { name, args: Default::default() }); // let (args, named) = Self::parse_args(table)?; // let mut cmd = Cmd { name, args, named, ..Default::default() }; @@ -62,16 +62,16 @@ impl Utils { ya.raw_set( "app_emit", - lua.create_function(|_, (name, table, data): (String, Table, Option)| { - emit!(Call(Self::create_cmd(name, table, data)?, Layer::App)); + lua.create_function(|_, (name, args): (String, Value)| { + emit!(Call(Self::create_cmd(name, args)?, Layer::App)); Ok(()) })?, )?; ya.raw_set( "manager_emit", - lua.create_function(|_, (name, table, data): (String, Table, Option)| { - emit!(Call(Self::create_cmd(name, table, data)?, Layer::Manager)); + lua.create_function(|_, (name, args): (String, Value)| { + emit!(Call(Self::create_cmd(name, args)?, Layer::Manager)); Ok(()) })?, )?; diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index 90bff80a..75a720af 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -37,7 +37,7 @@ impl Utils { let cand = cand?; cands.push(Control { on: Self::parse_keys(cand.raw_get("on")?)?, - run: vec![Cmd::args("callback", vec![i.to_string()]).with_data(tx.clone())], + run: vec![Cmd::args("callback", vec![i.to_string()]).with_any("tx", tx.clone())], desc: cand.raw_get("desc").ok(), }); } @@ -47,7 +47,7 @@ impl Utils { Cmd::new("show") .with("layer", Layer::Which) .with_bool("silent", t.raw_get("silent").unwrap_or_default()) - .with_data(cands), + .with_any("candidates", cands), Layer::Which )); diff --git a/yazi-plugin/src/utils/preview.rs b/yazi-plugin/src/utils/preview.rs index 54eec697..73a6aed9 100644 --- a/yazi-plugin/src/utils/preview.rs +++ b/yazi-plugin/src/utils/preview.rs @@ -44,7 +44,7 @@ impl Utils { }; lock.data = vec![Box::new(Paragraph { area: *area, text, ..Default::default() })]; - emit!(Call(Cmd::new("preview").with_data(lock), Layer::Manager)); + emit!(Call(Cmd::new("preview").with_any("lock", lock), Layer::Manager)); (true, Value::Nil).into_lua_multi(lua) })?, )?; @@ -67,7 +67,7 @@ impl Utils { ..Default::default() })]; - emit!(Call(Cmd::new("preview").with_data(lock), Layer::Manager)); + emit!(Call(Cmd::new("preview").with_any("lock", lock), Layer::Manager)); (true, Value::Nil).into_lua_multi(lua) })?, )?; @@ -78,7 +78,7 @@ impl Utils { let mut lock = PreviewLock::try_from(t)?; lock.data = widgets.into_iter().filter_map(cast_to_renderable).collect(); - emit!(Call(Cmd::new("preview").with_data(lock), Layer::Manager)); + emit!(Call(Cmd::new("preview").with_any("lock", lock), Layer::Manager)); Ok(()) })?, )?; diff --git a/yazi-plugin/src/utils/sync.rs b/yazi-plugin/src/utils/sync.rs index 70e0a993..667c3f44 100644 --- a/yazi-plugin/src/utils/sync.rs +++ b/yazi-plugin/src/utils/sync.rs @@ -4,7 +4,7 @@ use yazi_dds::Sendable; use yazi_shared::{emit, event::{Cmd, Data}, Layer}; use super::Utils; -use crate::{loader::LOADER, runtime::RtRef, OptData}; +use crate::{loader::LOADER, runtime::RtRef, OptCallback}; impl Utils { pub(super) fn sync(lua: &'static Lua, ya: &Table) -> mlua::Result<()> { @@ -53,29 +53,28 @@ impl Utils { let args = Sendable::variadic_to_vec(args)?; let (tx, rx) = oneshot::channel::>(); - let data = OptData { - cb: Some({ - let name = name.clone(); - Box::new(move |lua, plugin| { - let Some(block) = lua.named_registry_value::("rt")?.get_block(&name, calls) else { - return Err("sync block not found".into_lua_err()); - }; + let callback: OptCallback = { + let name = name.clone(); + Box::new(move |lua, plugin| { + let Some(block) = lua.named_registry_value::("rt")?.get_block(&name, calls) else { + return Err("sync block not found".into_lua_err()); + }; - let mut self_args = Vec::with_capacity(args.len() + 1); - self_args.push(Value::Table(plugin)); - for arg in args { - self_args.push(Sendable::data_to_value(lua, arg)?); - } + let mut self_args = Vec::with_capacity(args.len() + 1); + self_args.push(Value::Table(plugin)); + for arg in args { + self_args.push(Sendable::data_to_value(lua, arg)?); + } - let values = Sendable::variadic_to_vec(block.call(Variadic::from_iter(self_args))?)?; - tx.send(values).map_err(|_| "send failed".into_lua_err()) - }) - }), - ..Default::default() + let values = Sendable::variadic_to_vec(block.call(Variadic::from_iter(self_args))?)?; + tx.send(values).map_err(|_| "send failed".into_lua_err()) + }) }; emit!(Call( - Cmd::args("plugin", vec![name.clone()]).with_bool("sync", true).with_data(data), + Cmd::args("plugin", vec![name.clone()]) + .with_bool("sync", true) + .with_any("callback", callback), Layer::App )); diff --git a/yazi-proxy/src/app.rs b/yazi-proxy/src/app.rs index 9b67dfeb..add88327 100644 --- a/yazi-proxy/src/app.rs +++ b/yazi-proxy/src/app.rs @@ -11,7 +11,7 @@ impl AppProxy { #[inline] pub async fn stop() { let (tx, rx) = oneshot::channel::<()>(); - emit!(Call(Cmd::new("stop").with_data(tx), Layer::App)); + emit!(Call(Cmd::new("stop").with_any("tx", tx), Layer::App)); rx.await.ok(); } @@ -22,13 +22,13 @@ impl AppProxy { #[inline] pub fn notify(opt: NotifyOpt) { - emit!(Call(Cmd::new("notify").with_data(opt), Layer::App)); + emit!(Call(Cmd::new("notify").with_any("option", opt), Layer::App)); } #[inline] pub fn notify_warn(title: &str, content: &str) { emit!(Call( - Cmd::new("notify").with_data(NotifyOpt { + Cmd::new("notify").with_any("option", NotifyOpt { title: title.to_owned(), content: content.to_owned(), level: NotifyLevel::Warn, diff --git a/yazi-proxy/src/input.rs b/yazi-proxy/src/input.rs index 66a7491d..76e23c88 100644 --- a/yazi-proxy/src/input.rs +++ b/yazi-proxy/src/input.rs @@ -10,7 +10,7 @@ impl InputProxy { #[inline] pub fn show(cfg: InputCfg) -> mpsc::UnboundedReceiver> { let (tx, rx) = mpsc::unbounded_channel(); - emit!(Call(Cmd::new("show").with_data(InputOpt { cfg, tx }), Layer::Input)); + emit!(Call(Cmd::new("show").with_any("option", InputOpt { cfg, tx }), Layer::Input)); rx } diff --git a/yazi-proxy/src/manager.rs b/yazi-proxy/src/manager.rs index f690ed6a..60088df3 100644 --- a/yazi-proxy/src/manager.rs +++ b/yazi-proxy/src/manager.rs @@ -25,13 +25,13 @@ impl ManagerProxy { #[inline] pub fn open_do(opt: OpenDoOpt) { - emit!(Call(Cmd::new("open_do").with_data(opt), Layer::Manager)); + emit!(Call(Cmd::new("open_do").with_any("option", opt), Layer::Manager)); } #[inline] pub fn remove_do(targets: Vec, permanently: bool) { emit!(Call( - Cmd::new("remove_do").with_bool("permanently", permanently).with_data(targets), + Cmd::new("remove_do").with_bool("permanently", permanently).with_any("targets", targets), Layer::Manager )); } diff --git a/yazi-proxy/src/options/input.rs b/yazi-proxy/src/options/input.rs index b524a33c..7345e5ec 100644 --- a/yazi-proxy/src/options/input.rs +++ b/yazi-proxy/src/options/input.rs @@ -10,5 +10,5 @@ pub struct InputOpt { impl TryFrom for InputOpt { type Error = (); - fn try_from(mut c: Cmd) -> Result { c.take_data().ok_or(()) } + fn try_from(mut c: Cmd) -> Result { c.take_any("option").ok_or(()) } } diff --git a/yazi-proxy/src/options/notify.rs b/yazi-proxy/src/options/notify.rs index a8884d66..d4b10962 100644 --- a/yazi-proxy/src/options/notify.rs +++ b/yazi-proxy/src/options/notify.rs @@ -14,7 +14,7 @@ pub struct NotifyOpt { impl TryFrom for NotifyOpt { type Error = (); - fn try_from(mut c: Cmd) -> Result { c.take_data().ok_or(()) } + fn try_from(mut c: Cmd) -> Result { c.take_any("option").ok_or(()) } } impl<'a> TryFrom> for NotifyOpt { diff --git a/yazi-proxy/src/options/open.rs b/yazi-proxy/src/options/open.rs index 77ff707d..3e8101b6 100644 --- a/yazi-proxy/src/options/open.rs +++ b/yazi-proxy/src/options/open.rs @@ -12,7 +12,7 @@ pub struct OpenDoOpt { } impl From for OpenDoOpt { - fn from(mut c: Cmd) -> Self { c.take_data().unwrap_or_default() } + fn from(mut c: Cmd) -> Self { c.take_any("option").unwrap_or_default() } } // --- Open with @@ -24,5 +24,5 @@ pub struct OpenWithOpt { impl TryFrom for OpenWithOpt { type Error = (); - fn try_from(mut c: Cmd) -> Result { c.take_data().ok_or(()) } + fn try_from(mut c: Cmd) -> Result { c.take_any("option").ok_or(()) } } diff --git a/yazi-proxy/src/options/process.rs b/yazi-proxy/src/options/process.rs index 00daf667..28b3b8ec 100644 --- a/yazi-proxy/src/options/process.rs +++ b/yazi-proxy/src/options/process.rs @@ -14,5 +14,5 @@ pub struct ProcessExecOpt { impl TryFrom for ProcessExecOpt { type Error = (); - fn try_from(mut c: Cmd) -> Result { c.take_data().ok_or(()) } + fn try_from(mut c: Cmd) -> Result { c.take_any("option").ok_or(()) } } diff --git a/yazi-proxy/src/options/select.rs b/yazi-proxy/src/options/select.rs index 0478f4a3..df010c79 100644 --- a/yazi-proxy/src/options/select.rs +++ b/yazi-proxy/src/options/select.rs @@ -10,5 +10,5 @@ pub struct SelectOpt { impl TryFrom for SelectOpt { type Error = (); - fn try_from(mut c: Cmd) -> Result { c.take_data().ok_or(()) } + fn try_from(mut c: Cmd) -> Result { c.take_any("option").ok_or(()) } } diff --git a/yazi-proxy/src/select.rs b/yazi-proxy/src/select.rs index fd00aca9..e56f8386 100644 --- a/yazi-proxy/src/select.rs +++ b/yazi-proxy/src/select.rs @@ -10,7 +10,7 @@ impl SelectProxy { #[inline] pub async fn show(cfg: SelectCfg) -> anyhow::Result { let (tx, rx) = oneshot::channel(); - emit!(Call(Cmd::new("show").with_data(SelectOpt { cfg, tx }), Layer::Select)); + emit!(Call(Cmd::new("show").with_any("option", SelectOpt { cfg, tx }), Layer::Select)); rx.await? } } diff --git a/yazi-proxy/src/tasks.rs b/yazi-proxy/src/tasks.rs index b07bdf2c..10f0f9ca 100644 --- a/yazi-proxy/src/tasks.rs +++ b/yazi-proxy/src/tasks.rs @@ -11,14 +11,17 @@ pub struct TasksProxy; impl TasksProxy { #[inline] pub fn open_with(targets: Vec, opener: Cow<'static, Opener>) { - emit!(Call(Cmd::new("open_with").with_data(OpenWithOpt { targets, opener }), Layer::Tasks)); + emit!(Call( + Cmd::new("open_with").with_any("option", OpenWithOpt { targets, opener }), + Layer::Tasks + )); } #[inline] pub async fn process_exec(args: Vec, opener: Cow<'static, Opener>) { let (tx, rx) = oneshot::channel(); emit!(Call( - Cmd::new("process_exec").with_data(ProcessExecOpt { args, opener, done: tx }), + Cmd::new("process_exec").with_any("option", ProcessExecOpt { args, opener, done: tx }), Layer::Tasks )); rx.await.ok(); diff --git a/yazi-shared/src/event/cmd.rs b/yazi-shared/src/event/cmd.rs index 61211df5..e1fc3fb6 100644 --- a/yazi-shared/src/event/cmd.rs +++ b/yazi-shared/src/event/cmd.rs @@ -6,7 +6,6 @@ use super::Data; pub struct Cmd { pub name: String, pub args: HashMap, - pub data: Option>, } impl Cmd { @@ -18,7 +17,6 @@ impl Cmd { Self { name: name.to_owned(), args: args.into_iter().enumerate().map(|(i, s)| (i.to_string(), Data::String(s))).collect(), - ..Default::default() } } @@ -35,8 +33,14 @@ impl Cmd { } #[inline] - pub fn with_data(mut self, data: impl Any + Send) -> Self { - self.data = Some(Box::new(data)); + pub fn with_any(mut self, name: impl ToString, data: impl Any + Send) -> Self { + self.args.insert(name.to_string(), Data::Any(Box::new(data))); + self + } + + #[inline] + pub fn with_name(mut self, name: impl ToString) -> Self { + self.name = name.to_string(); self } @@ -49,8 +53,11 @@ impl Cmd { } #[inline] - pub fn take_data(&mut self) -> Option { - self.data.take().and_then(|d| d.downcast::().ok()).map(|d| *d) + pub fn take_data(&mut self, name: &str) -> Option { self.args.remove(name) } + + #[inline] + pub fn take_str(&mut self, name: &str) -> Option { + if let Some(Data::String(s)) = self.args.remove(name) { Some(s) } else { None } } #[inline] @@ -59,8 +66,8 @@ impl Cmd { } #[inline] - pub fn take_name_str(&mut self, name: &str) -> Option { - if let Some(Data::String(s)) = self.args.remove(name) { Some(s) } else { None } + pub fn take_any(&mut self, name: &str) -> Option { + self.args.remove(name).and_then(|d| d.into_any()) } pub fn shallow_clone(&self) -> Self { @@ -70,7 +77,7 @@ impl Cmd { .filter_map(|(k, v)| v.as_str().map(|s| (k.clone(), Data::String(s.to_owned())))) .collect(); - Self { name: self.name.clone(), args, data: None } + Self { name: self.name.clone(), args } } } diff --git a/yazi-shared/src/event/data.rs b/yazi-shared/src/event/data.rs index 4b661e06..14732efc 100644 --- a/yazi-shared/src/event/data.rs +++ b/yazi-shared/src/event/data.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::{fs::Url, OrderedFloat}; -// --- Arg +// --- Data #[derive(Debug, Serialize, Deserialize)] #[serde(untagged)] pub enum Data { @@ -37,6 +37,22 @@ impl Data { } } + #[inline] + pub fn as_any(&self) -> Option<&T> { + match self { + Self::Any(b) => b.downcast_ref::(), + _ => None, + } + } + + #[inline] + pub fn into_any(self) -> Option { + match self { + Data::Any(b) => b.downcast::().ok().map(|b| *b), + _ => None, + } + } + pub fn into_table_string(self) -> HashMap { let Self::Table(table) = self else { return Default::default(); diff --git a/yazi-shared/src/fs/op.rs b/yazi-shared/src/fs/op.rs index 9db7972b..43c6c6c9 100644 --- a/yazi-shared/src/fs/op.rs +++ b/yazi-shared/src/fs/op.rs @@ -38,7 +38,7 @@ impl FilesOp { #[inline] pub fn emit(self) { - emit!(Call(Cmd::new("update_files").with_data(self), Layer::Manager)); + emit!(Call(Cmd::new("update_files").with_any("op", self), Layer::Manager)); } pub fn prepare(url: &Url) -> u64 {