From 56ede51c53eaee1ae763d46bc1208c3a710a07a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20=C2=B7=20Misaki=20Masa?= Date: Mon, 22 Jan 2024 18:43:50 +0800 Subject: [PATCH] perf: new event system (#561) --- yazi-config/src/keymap/control.rs | 15 +---- yazi-core/src/completion/commands/arrow.rs | 6 +- yazi-core/src/completion/commands/close.rs | 11 ++-- yazi-core/src/completion/commands/show.rs | 26 ++++----- yazi-core/src/completion/commands/trigger.rs | 23 ++++---- yazi-core/src/completion/completion.rs | 2 +- yazi-core/src/help/commands/arrow.rs | 6 +- yazi-core/src/help/commands/escape.rs | 2 +- yazi-core/src/help/commands/filter.rs | 2 +- yazi-core/src/input/commands/backspace.rs | 4 +- yazi-core/src/input/commands/backward.rs | 2 +- yazi-core/src/input/commands/close.rs | 4 +- yazi-core/src/input/commands/complete.rs | 19 +++---- yazi-core/src/input/commands/delete.rs | 4 +- yazi-core/src/input/commands/escape.rs | 4 +- yazi-core/src/input/commands/forward.rs | 4 +- yazi-core/src/input/commands/insert.rs | 4 +- yazi-core/src/input/commands/kill.rs | 12 ++-- yazi-core/src/input/commands/move_.rs | 6 +- yazi-core/src/input/commands/paste.rs | 4 +- yazi-core/src/input/commands/redo.rs | 2 +- yazi-core/src/input/commands/show.rs | 6 +- yazi-core/src/input/commands/type_.rs | 4 +- yazi-core/src/input/commands/undo.rs | 2 +- yazi-core/src/input/commands/visual.rs | 2 +- yazi-core/src/input/commands/yank.rs | 2 +- yazi-core/src/manager/commands/close.rs | 2 +- yazi-core/src/manager/commands/create.rs | 4 +- yazi-core/src/manager/commands/hover.rs | 6 +- yazi-core/src/manager/commands/link.rs | 4 +- yazi-core/src/manager/commands/open.rs | 6 +- yazi-core/src/manager/commands/paste.rs | 4 +- yazi-core/src/manager/commands/peek.rs | 10 ++-- yazi-core/src/manager/commands/quit.rs | 4 +- yazi-core/src/manager/commands/refresh.rs | 4 +- yazi-core/src/manager/commands/remove.rs | 4 +- yazi-core/src/manager/commands/rename.rs | 20 +++---- yazi-core/src/manager/commands/seek.rs | 6 +- yazi-core/src/manager/commands/suspend.rs | 2 +- yazi-core/src/manager/commands/tab_close.rs | 6 +- yazi-core/src/manager/commands/tab_create.rs | 6 +- yazi-core/src/manager/commands/tab_swap.rs | 6 +- yazi-core/src/manager/commands/tab_switch.rs | 6 +- .../src/manager/commands/update_files.rs | 6 +- .../src/manager/commands/update_mimetype.rs | 6 +- .../src/manager/commands/update_paged.rs | 12 ++-- yazi-core/src/manager/commands/yank.rs | 4 +- yazi-core/src/select/commands/arrow.rs | 6 +- yazi-core/src/select/commands/close.rs | 4 +- yazi-core/src/select/commands/show.rs | 6 +- yazi-core/src/tab/commands/arrow.rs | 6 +- yazi-core/src/tab/commands/backstack.rs | 4 +- yazi-core/src/tab/commands/cd.rs | 8 +-- yazi-core/src/tab/commands/copy.rs | 12 ++-- yazi-core/src/tab/commands/enter.rs | 4 +- yazi-core/src/tab/commands/escape.rs | 20 +++---- yazi-core/src/tab/commands/filter.rs | 21 ++++--- yazi-core/src/tab/commands/find.rs | 25 ++++----- yazi-core/src/tab/commands/hidden.rs | 8 +-- yazi-core/src/tab/commands/jump.rs | 4 +- yazi-core/src/tab/commands/leave.rs | 4 +- yazi-core/src/tab/commands/linemode.rs | 6 +- yazi-core/src/tab/commands/preview.rs | 6 +- yazi-core/src/tab/commands/reveal.rs | 8 +-- yazi-core/src/tab/commands/search.rs | 12 ++-- yazi-core/src/tab/commands/select.rs | 4 +- yazi-core/src/tab/commands/shell.rs | 6 +- yazi-core/src/tab/commands/sort.rs | 2 +- yazi-core/src/tab/commands/visual_mode.rs | 4 +- yazi-core/src/tasks/commands/arrow.rs | 6 +- yazi-core/src/tasks/commands/cancel.rs | 2 +- yazi-core/src/tasks/commands/inspect.rs | 2 +- yazi-core/src/tasks/commands/open.rs | 6 +- yazi-core/src/tasks/commands/toggle.rs | 4 +- yazi-core/src/tasks/tasks.rs | 3 +- yazi-core/src/which/which.rs | 4 +- yazi-fm/src/app/app.rs | 30 +++++++--- yazi-fm/src/app/commands/plugin.rs | 2 +- yazi-fm/src/app/commands/resume.rs | 2 +- yazi-fm/src/app/commands/stop.rs | 4 +- yazi-fm/src/app/commands/update_progress.rs | 4 +- yazi-fm/src/executor.rs | 55 ++++++++++--------- yazi-fm/src/main.rs | 1 + yazi-plugin/src/bindings/mod.rs | 1 + yazi-plugin/src/isolate/peek.rs | 2 +- yazi-plugin/src/isolate/seek.rs | 2 +- yazi-plugin/src/opt.rs | 12 ++-- yazi-plugin/src/utils/call.rs | 2 +- yazi-plugin/src/utils/preview.rs | 6 +- yazi-scheduler/src/scheduler.rs | 4 +- yazi-shared/src/event/event.rs | 8 ++- yazi-shared/src/event/exec.rs | 31 ++++++++--- yazi-shared/src/fs/op.rs | 2 +- 93 files changed, 353 insertions(+), 328 deletions(-) diff --git a/yazi-config/src/keymap/control.rs b/yazi-config/src/keymap/control.rs index a3b1af64..aa178c63 100644 --- a/yazi-config/src/keymap/control.rs +++ b/yazi-config/src/keymap/control.rs @@ -1,4 +1,4 @@ -use std::borrow::Cow; +use std::{borrow::Cow, collections::VecDeque}; use serde::Deserialize; use yazi_shared::event::Exec; @@ -14,17 +14,8 @@ pub struct Control { } impl Control { - pub fn to_call(&self) -> Vec { - self - .exec - .iter() - .map(|e| Exec { - cmd: e.cmd.clone(), - args: e.args.clone(), - named: e.named.clone(), - ..Default::default() - }) - .collect() + pub fn to_seq(&self) -> VecDeque { + self.exec.iter().map(|e| e.clone_without_data()).collect() } } diff --git a/yazi-core/src/completion/commands/arrow.rs b/yazi-core/src/completion/commands/arrow.rs index 998af286..c8bc0ba1 100644 --- a/yazi-core/src/completion/commands/arrow.rs +++ b/yazi-core/src/completion/commands/arrow.rs @@ -6,9 +6,9 @@ pub struct Opt { step: isize, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - Self { step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0) } +impl From for Opt { + fn from(mut e: Exec) -> Self { + Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) } } } diff --git a/yazi-core/src/completion/commands/close.rs b/yazi-core/src/completion/commands/close.rs index b5876c82..c0c6f812 100644 --- a/yazi-core/src/completion/commands/close.rs +++ b/yazi-core/src/completion/commands/close.rs @@ -6,20 +6,21 @@ pub struct Opt { submit: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { submit: e.named.contains_key("submit") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { submit: e.named.contains_key("submit") } } } impl Completion { #[inline] pub fn _close() { - emit!(Call(Exec::call("close", vec![]).vec(), Layer::Completion)); + emit!(Call(Exec::call("close", vec![]), Layer::Completion)); } pub fn close(&mut self, opt: impl Into) { let opt = opt.into() as Opt; - if opt.submit { - Input::_complete(self.selected(), self.ticket); + + if let Some(s) = self.selected().filter(|_| opt.submit) { + Input::_complete(s, self.ticket); } self.caches.clear(); diff --git a/yazi-core/src/completion/commands/show.rs b/yazi-core/src/completion/commands/show.rs index 609cebba..963ed471 100644 --- a/yazi-core/src/completion/commands/show.rs +++ b/yazi-core/src/completion/commands/show.rs @@ -6,20 +6,20 @@ use crate::completion::Completion; const LIMIT: usize = 30; -pub struct Opt<'a> { - cache: &'a Vec, - cache_name: &'a str, - word: &'a str, +pub struct Opt { + cache: Vec, + cache_name: String, + word: String, ticket: usize, } -impl<'a> From<&'a Exec> for Opt<'a> { - fn from(e: &'a Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { - cache: &e.args, - cache_name: e.named.get("cache-name").map(|n| n.as_str()).unwrap_or_default(), - word: e.named.get("word").map(|w| w.as_str()).unwrap_or_default(), - ticket: e.named.get("ticket").and_then(|v| v.parse().ok()).unwrap_or(0), + cache: mem::take(&mut e.args), + cache_name: e.take_name("cache-name").unwrap_or_default(), + word: e.take_name("word").unwrap_or_default(), + ticket: e.take_name("ticket").and_then(|v| v.parse().ok()).unwrap_or(0), } } } @@ -54,7 +54,7 @@ impl Completion { prefixed.into_iter().map(ToOwned::to_owned).collect() } - pub fn show<'a>(&mut self, opt: impl Into>) { + pub fn show(&mut self, opt: impl Into) { let opt = opt.into() as Opt; if self.ticket != opt.ticket { return; @@ -63,12 +63,12 @@ impl Completion { if !opt.cache.is_empty() { self.caches.insert(opt.cache_name.to_owned(), opt.cache.clone()); } - let Some(cache) = self.caches.get(opt.cache_name) else { + let Some(cache) = self.caches.get(&opt.cache_name) else { return; }; self.ticket = opt.ticket; - self.cands = Self::match_candidates(opt.word, cache); + self.cands = Self::match_candidates(&opt.word, cache); if self.cands.is_empty() { return render!(mem::replace(&mut self.visible, false)); } diff --git a/yazi-core/src/completion/commands/trigger.rs b/yazi-core/src/completion/commands/trigger.rs index 85180bce..44869ab7 100644 --- a/yazi-core/src/completion/commands/trigger.rs +++ b/yazi-core/src/completion/commands/trigger.rs @@ -5,16 +5,16 @@ use yazi_shared::{emit, event::Exec, render, Layer}; use crate::completion::Completion; -pub struct Opt<'a> { - word: &'a str, +pub struct Opt { + word: String, ticket: usize, } -impl<'a> From<&'a Exec> for Opt<'a> { - fn from(e: &'a Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { - word: e.args.first().map(|s| s.as_str()).unwrap_or_default(), - ticket: e.named.get("ticket").and_then(|s| s.parse().ok()).unwrap_or(0), + word: e.take_first().unwrap_or_default(), + ticket: e.take_name("ticket").and_then(|s| s.parse().ok()).unwrap_or(0), } } } @@ -23,23 +23,23 @@ impl Completion { #[inline] pub fn _trigger(word: &str, ticket: usize) { emit!(Call( - Exec::call("trigger", vec![word.to_owned()]).with("ticket", ticket).vec(), + Exec::call("trigger", vec![word.to_owned()]).with("ticket", ticket), Layer::Completion )); } - pub fn trigger<'a>(&mut self, opt: impl Into>) { + pub fn trigger(&mut self, opt: impl Into) { let opt = opt.into() as Opt; if opt.ticket < self.ticket { return; } self.ticket = opt.ticket; - let (parent, child) = Self::split_path(opt.word); + let (parent, child) = Self::split_path(&opt.word); if self.caches.contains_key(&parent) { return self.show( - &Exec::call("show", vec![]) + Exec::call("show", vec![]) .with("cache-name", parent) .with("word", child) .with("ticket", opt.ticket), @@ -67,8 +67,7 @@ impl Completion { Exec::call("show", cache) .with("cache-name", parent) .with("word", child) - .with("ticket", ticket) - .vec(), + .with("ticket", ticket), Layer::Completion )); } diff --git a/yazi-core/src/completion/completion.rs b/yazi-core/src/completion/completion.rs index a1c72ceb..af5279e4 100644 --- a/yazi-core/src/completion/completion.rs +++ b/yazi-core/src/completion/completion.rs @@ -23,7 +23,7 @@ impl Completion { pub fn limit(&self) -> usize { self.cands.len().min(10) } #[inline] - pub fn selected(&self) -> &String { &self.cands[self.cursor] } + pub fn selected(&self) -> Option<&String> { self.cands.get(self.cursor) } // --- Cursor #[inline] diff --git a/yazi-core/src/help/commands/arrow.rs b/yazi-core/src/help/commands/arrow.rs index df51e04b..59b98137 100644 --- a/yazi-core/src/help/commands/arrow.rs +++ b/yazi-core/src/help/commands/arrow.rs @@ -6,9 +6,9 @@ pub struct Opt { step: isize, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - Self { step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0) } +impl From for Opt { + fn from(mut e: Exec) -> Self { + Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) } } } impl From for Opt { diff --git a/yazi-core/src/help/commands/escape.rs b/yazi-core/src/help/commands/escape.rs index b85b4845..35d4a7e6 100644 --- a/yazi-core/src/help/commands/escape.rs +++ b/yazi-core/src/help/commands/escape.rs @@ -3,7 +3,7 @@ use yazi_shared::{event::Exec, render}; use crate::help::Help; impl Help { - pub fn escape(&mut self, _: &Exec) { + pub fn escape(&mut self, _: Exec) { if self.in_filter.is_none() { return self.toggle(self.layer); } diff --git a/yazi-core/src/help/commands/filter.rs b/yazi-core/src/help/commands/filter.rs index f559f8c5..992486a3 100644 --- a/yazi-core/src/help/commands/filter.rs +++ b/yazi-core/src/help/commands/filter.rs @@ -4,7 +4,7 @@ use yazi_shared::{event::Exec, render}; use crate::{help::Help, input::Input}; impl Help { - pub fn filter(&mut self, _: &Exec) { + pub fn filter(&mut self, _: Exec) { let mut input = Input::default(); input.position = Position::new(Origin::BottomLeft, Offset::line()); diff --git a/yazi-core/src/input/commands/backspace.rs b/yazi-core/src/input/commands/backspace.rs index 51d17539..d73eb1d0 100644 --- a/yazi-core/src/input/commands/backspace.rs +++ b/yazi-core/src/input/commands/backspace.rs @@ -6,8 +6,8 @@ pub struct Opt { under: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { under: e.named.contains_key("under") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { under: e.named.contains_key("under") } } } impl From for Opt { fn from(under: bool) -> Self { Self { under } } diff --git a/yazi-core/src/input/commands/backward.rs b/yazi-core/src/input/commands/backward.rs index 30d18af6..37d44640 100644 --- a/yazi-core/src/input/commands/backward.rs +++ b/yazi-core/src/input/commands/backward.rs @@ -3,7 +3,7 @@ use yazi_shared::{event::Exec, CharKind}; use crate::input::Input; impl Input { - pub fn backward(&mut self, _: &Exec) { + pub fn backward(&mut self, _: Exec) { let snap = self.snap(); if snap.cursor == 0 { return self.move_(0); diff --git a/yazi-core/src/input/commands/close.rs b/yazi-core/src/input/commands/close.rs index 1224c156..7ddd9b71 100644 --- a/yazi-core/src/input/commands/close.rs +++ b/yazi-core/src/input/commands/close.rs @@ -6,8 +6,8 @@ pub struct Opt { submit: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { submit: e.named.contains_key("submit") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { submit: e.named.contains_key("submit") } } } impl From for Opt { fn from(submit: bool) -> Self { Self { submit } } diff --git a/yazi-core/src/input/commands/complete.rs b/yazi-core/src/input/commands/complete.rs index 11cabf91..d3097ae0 100644 --- a/yazi-core/src/input/commands/complete.rs +++ b/yazi-core/src/input/commands/complete.rs @@ -4,16 +4,16 @@ use yazi_shared::{emit, event::Exec, render, Layer}; use crate::input::Input; -pub struct Opt<'a> { - word: &'a str, +pub struct Opt { + word: String, ticket: usize, } -impl<'a> From<&'a Exec> for Opt<'a> { - fn from(e: &'a Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { - word: e.args.first().map(|w| w.as_str()).unwrap_or_default(), - ticket: e.named.get("ticket").and_then(|s| s.parse().ok()).unwrap_or(0), + word: e.take_first().unwrap_or_default(), + ticket: e.take_name("ticket").and_then(|s| s.parse().ok()).unwrap_or(0), } } } @@ -21,13 +21,10 @@ impl<'a> From<&'a Exec> for Opt<'a> { impl Input { #[inline] pub fn _complete(word: &str, ticket: usize) { - emit!(Call( - Exec::call("complete", vec![word.to_owned()]).with("ticket", ticket).vec(), - Layer::Input - )); + emit!(Call(Exec::call("complete", vec![word.to_owned()]).with("ticket", ticket), Layer::Input)); } - pub fn complete<'a>(&mut self, opt: impl Into>) { + pub fn complete(&mut self, opt: impl Into) { let opt = opt.into() as Opt; if self.ticket != opt.ticket { return; diff --git a/yazi-core/src/input/commands/delete.rs b/yazi-core/src/input/commands/delete.rs index 4101bf5d..e99d670f 100644 --- a/yazi-core/src/input/commands/delete.rs +++ b/yazi-core/src/input/commands/delete.rs @@ -7,8 +7,8 @@ pub struct Opt { insert: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(e: Exec) -> Self { Self { cut: e.named.contains_key("cut"), insert: e.named.contains_key("insert") } } } diff --git a/yazi-core/src/input/commands/escape.rs b/yazi-core/src/input/commands/escape.rs index ad713e22..bd29c553 100644 --- a/yazi-core/src/input/commands/escape.rs +++ b/yazi-core/src/input/commands/escape.rs @@ -4,8 +4,8 @@ use crate::{completion::Completion, input::{op::InputOp, Input, InputMode}}; pub struct Opt; -impl From<&Exec> for Opt { - fn from(_: &Exec) -> Self { Self } +impl From for Opt { + fn from(_: Exec) -> Self { Self } } impl From<()> for Opt { fn from(_: ()) -> Self { Self } diff --git a/yazi-core/src/input/commands/forward.rs b/yazi-core/src/input/commands/forward.rs index bbaff4ab..a374e6cf 100644 --- a/yazi-core/src/input/commands/forward.rs +++ b/yazi-core/src/input/commands/forward.rs @@ -6,8 +6,8 @@ pub struct Opt { end_of_word: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { end_of_word: e.named.contains_key("end-of-word") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { end_of_word: e.named.contains_key("end-of-word") } } } impl Input { diff --git a/yazi-core/src/input/commands/insert.rs b/yazi-core/src/input/commands/insert.rs index d95226fa..23523be5 100644 --- a/yazi-core/src/input/commands/insert.rs +++ b/yazi-core/src/input/commands/insert.rs @@ -6,8 +6,8 @@ pub struct Opt { append: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { append: e.named.contains_key("append") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { append: e.named.contains_key("append") } } } impl From for Opt { fn from(append: bool) -> Self { Self { append } } diff --git a/yazi-core/src/input/commands/kill.rs b/yazi-core/src/input/commands/kill.rs index 1e1b2fa0..b86bee85 100644 --- a/yazi-core/src/input/commands/kill.rs +++ b/yazi-core/src/input/commands/kill.rs @@ -4,14 +4,12 @@ use yazi_shared::{event::Exec, render, CharKind}; use crate::input::Input; -pub struct Opt<'a> { - kind: &'a str, +pub struct Opt { + kind: String, } -impl<'a> From<&'a Exec> for Opt<'a> { - fn from(e: &'a Exec) -> Self { - Self { kind: e.args.first().map(|s| s.as_str()).unwrap_or_default() } - } +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { kind: e.take_first().unwrap_or_default() } } } impl Input { @@ -67,7 +65,7 @@ impl Input { input.take(n).fold(0, |acc, c| acc + c.len_utf8()) } - pub fn kill<'a>(&mut self, opt: impl Into>) { + pub fn kill(&mut self, opt: impl Into) { let opt = opt.into() as Opt; let snap = self.snap_mut(); diff --git a/yazi-core/src/input/commands/move_.rs b/yazi-core/src/input/commands/move_.rs index c056010e..c3d20821 100644 --- a/yazi-core/src/input/commands/move_.rs +++ b/yazi-core/src/input/commands/move_.rs @@ -8,10 +8,10 @@ pub struct Opt { in_operating: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { - step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0), + step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0), in_operating: e.named.contains_key("in-operating"), } } diff --git a/yazi-core/src/input/commands/paste.rs b/yazi-core/src/input/commands/paste.rs index 59879910..8ee5be5e 100644 --- a/yazi-core/src/input/commands/paste.rs +++ b/yazi-core/src/input/commands/paste.rs @@ -6,8 +6,8 @@ pub struct Opt { before: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { before: e.named.contains_key("before") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { before: e.named.contains_key("before") } } } impl Input { diff --git a/yazi-core/src/input/commands/redo.rs b/yazi-core/src/input/commands/redo.rs index 3ca7ca1c..329635a9 100644 --- a/yazi-core/src/input/commands/redo.rs +++ b/yazi-core/src/input/commands/redo.rs @@ -3,7 +3,7 @@ use yazi_shared::{event::Exec, render}; use crate::input::Input; impl Input { - pub fn redo(&mut self, _: &Exec) { + pub fn redo(&mut self, _: Exec) { render!(self.snaps.redo()); } } diff --git a/yazi-core/src/input/commands/show.rs b/yazi-core/src/input/commands/show.rs index cdb3b87b..482e6a62 100644 --- a/yazi-core/src/input/commands/show.rs +++ b/yazi-core/src/input/commands/show.rs @@ -9,16 +9,16 @@ pub struct Opt { tx: mpsc::UnboundedSender>, } -impl TryFrom<&Exec> for Opt { +impl TryFrom for Opt { type Error = (); - fn try_from(e: &Exec) -> Result { e.take_data().ok_or(()) } + fn try_from(mut e: Exec) -> Result { e.take_data().ok_or(()) } } impl Input { pub fn _show(cfg: InputCfg) -> mpsc::UnboundedReceiver> { let (tx, rx) = mpsc::unbounded_channel(); - emit!(Call(Exec::call("show", vec![]).with_data(Opt { cfg, tx }).vec(), Layer::Input)); + emit!(Call(Exec::call("show", vec![]).with_data(Opt { cfg, tx }), Layer::Input)); rx } diff --git a/yazi-core/src/input/commands/type_.rs b/yazi-core/src/input/commands/type_.rs index 81c88b25..1da405dc 100644 --- a/yazi-core/src/input/commands/type_.rs +++ b/yazi-core/src/input/commands/type_.rs @@ -5,8 +5,8 @@ use crate::input::{Input, InputMode}; pub struct Opt; -impl From<&Exec> for Opt { - fn from(_: &Exec) -> Self { Self } +impl From for Opt { + fn from(_: Exec) -> Self { Self } } impl Input { diff --git a/yazi-core/src/input/commands/undo.rs b/yazi-core/src/input/commands/undo.rs index e0001c9f..c111e6ac 100644 --- a/yazi-core/src/input/commands/undo.rs +++ b/yazi-core/src/input/commands/undo.rs @@ -3,7 +3,7 @@ use yazi_shared::{event::Exec, render}; use crate::input::{Input, InputMode}; impl Input { - pub fn undo(&mut self, _: &Exec) { + pub fn undo(&mut self, _: Exec) { if !self.snaps.undo() { return; } diff --git a/yazi-core/src/input/commands/visual.rs b/yazi-core/src/input/commands/visual.rs index bffdf6cd..98a4ca5d 100644 --- a/yazi-core/src/input/commands/visual.rs +++ b/yazi-core/src/input/commands/visual.rs @@ -4,7 +4,7 @@ use crate::input::{op::InputOp, Input, InputMode}; impl Input { #[inline] - pub fn visual(&mut self, _: &Exec) { + pub fn visual(&mut self, _: Exec) { let snap = self.snap_mut(); if snap.mode != InputMode::Normal { return; diff --git a/yazi-core/src/input/commands/yank.rs b/yazi-core/src/input/commands/yank.rs index 7ae6ebb4..4bc38729 100644 --- a/yazi-core/src/input/commands/yank.rs +++ b/yazi-core/src/input/commands/yank.rs @@ -3,7 +3,7 @@ use yazi_shared::{event::Exec, render}; use crate::input::{op::InputOp, Input}; impl Input { - pub fn yank(&mut self, _: &Exec) { + pub fn yank(&mut self, _: Exec) { match self.snap().op { InputOp::None => { self.snap_mut().op = InputOp::Yank(self.snap().cursor); diff --git a/yazi-core/src/manager/commands/close.rs b/yazi-core/src/manager/commands/close.rs index 53a7ffb9..aa199942 100644 --- a/yazi-core/src/manager/commands/close.rs +++ b/yazi-core/src/manager/commands/close.rs @@ -3,7 +3,7 @@ use yazi_shared::event::Exec; use crate::{manager::Manager, tasks::Tasks}; impl Manager { - pub fn close(&mut self, _: &Exec, tasks: &Tasks) { + pub fn close(&mut self, _: Exec, tasks: &Tasks) { if self.tabs.len() > 1 { return self.tabs.close(self.tabs.idx); } diff --git a/yazi-core/src/manager/commands/create.rs b/yazi-core/src/manager/commands/create.rs index 7e46def5..de7e4687 100644 --- a/yazi-core/src/manager/commands/create.rs +++ b/yazi-core/src/manager/commands/create.rs @@ -10,8 +10,8 @@ pub struct Opt { force: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { force: e.named.contains_key("force") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { force: e.named.contains_key("force") } } } impl Manager { diff --git a/yazi-core/src/manager/commands/hover.rs b/yazi-core/src/manager/commands/hover.rs index 7c9b4177..5cd6180e 100644 --- a/yazi-core/src/manager/commands/hover.rs +++ b/yazi-core/src/manager/commands/hover.rs @@ -8,8 +8,8 @@ pub struct Opt { url: Option, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { url: e.args.first().map(Url::from) } } +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { url: e.take_first().map(Url::from) } } } impl From> for Opt { fn from(url: Option) -> Self { Self { url } } @@ -19,7 +19,7 @@ impl Manager { #[inline] pub fn _hover(url: Option) { emit!(Call( - Exec::call("hover", url.map_or_else(Vec::new, |u| vec![u.to_string()])).vec(), + Exec::call("hover", url.map_or_else(Vec::new, |u| vec![u.to_string()])), Layer::Manager )); } diff --git a/yazi-core/src/manager/commands/link.rs b/yazi-core/src/manager/commands/link.rs index 8046764d..747dde1c 100644 --- a/yazi-core/src/manager/commands/link.rs +++ b/yazi-core/src/manager/commands/link.rs @@ -7,8 +7,8 @@ pub struct Opt { force: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(e: Exec) -> Self { Self { relative: e.named.contains_key("relative"), force: e.named.contains_key("force") } } } diff --git a/yazi-core/src/manager/commands/open.rs b/yazi-core/src/manager/commands/open.rs index 1009cc98..e682aa10 100644 --- a/yazi-core/src/manager/commands/open.rs +++ b/yazi-core/src/manager/commands/open.rs @@ -12,8 +12,8 @@ pub struct Opt { interactive: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { targets: e.take_data(), interactive: e.named.contains_key("interactive") } } } @@ -57,7 +57,7 @@ impl Manager { #[inline] pub fn _open_do(interactive: bool, targets: Vec<(Url, Option)>) { emit!(Call( - Exec::call("open_do", vec![]).with_bool("interactive", interactive).with_data(targets).vec(), + Exec::call("open_do", vec![]).with_bool("interactive", interactive).with_data(targets), Layer::Manager )); } diff --git a/yazi-core/src/manager/commands/paste.rs b/yazi-core/src/manager/commands/paste.rs index e12a670d..40fb3743 100644 --- a/yazi-core/src/manager/commands/paste.rs +++ b/yazi-core/src/manager/commands/paste.rs @@ -7,8 +7,8 @@ pub struct Opt { follow: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(e: Exec) -> Self { Self { force: e.named.contains_key("force"), follow: e.named.contains_key("follow") } } } diff --git a/yazi-core/src/manager/commands/peek.rs b/yazi-core/src/manager/commands/peek.rs index bb12712a..73bca19c 100644 --- a/yazi-core/src/manager/commands/peek.rs +++ b/yazi-core/src/manager/commands/peek.rs @@ -10,12 +10,12 @@ pub struct Opt { upper_bound: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { - skip: e.args.first().and_then(|s| s.parse().ok()), + skip: e.take_first().and_then(|s| s.parse().ok()), force: e.named.contains_key("force"), - only_if: e.named.get("only-if").map(Url::from), + only_if: e.take_name("only-if").map(Url::from), upper_bound: e.named.contains_key("upper-bound"), } } @@ -27,7 +27,7 @@ impl From for Opt { impl Manager { #[inline] pub fn _peek(force: bool) { - emit!(Call(Exec::call("peek", vec![]).with_bool("force", force).vec(), Layer::Manager)); + emit!(Call(Exec::call("peek", vec![]).with_bool("force", force), Layer::Manager)); } pub fn peek(&mut self, opt: impl Into) { diff --git a/yazi-core/src/manager/commands/quit.rs b/yazi-core/src/manager/commands/quit.rs index daa94593..c6e4c16c 100644 --- a/yazi-core/src/manager/commands/quit.rs +++ b/yazi-core/src/manager/commands/quit.rs @@ -10,8 +10,8 @@ pub struct Opt { impl From<()> for Opt { fn from(_: ()) -> Self { Self::default() } } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { no_cwd_file: e.named.contains_key("no-cwd-file") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { no_cwd_file: e.named.contains_key("no-cwd-file") } } } impl Manager { diff --git a/yazi-core/src/manager/commands/refresh.rs b/yazi-core/src/manager/commands/refresh.rs index 2446b286..3f45893c 100644 --- a/yazi-core/src/manager/commands/refresh.rs +++ b/yazi-core/src/manager/commands/refresh.rs @@ -7,10 +7,10 @@ use crate::{manager::Manager, tasks::Tasks}; impl Manager { #[inline] pub fn _refresh() { - emit!(Call(Exec::call("refresh", vec![]).vec(), Layer::Manager)); + emit!(Call(Exec::call("refresh", vec![]), Layer::Manager)); } - pub fn refresh(&mut self, _: &Exec, tasks: &Tasks) { + pub fn refresh(&mut self, _: Exec, tasks: &Tasks) { env::set_current_dir(self.cwd()).ok(); env::set_var("PWD", self.cwd()); diff --git a/yazi-core/src/manager/commands/remove.rs b/yazi-core/src/manager/commands/remove.rs index a3896e88..c6904bdb 100644 --- a/yazi-core/src/manager/commands/remove.rs +++ b/yazi-core/src/manager/commands/remove.rs @@ -7,8 +7,8 @@ pub struct Opt { permanently: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(e: Exec) -> Self { Self { force: e.named.contains_key("force"), permanently: e.named.contains_key("permanently"), diff --git a/yazi-core/src/manager/commands/rename.rs b/yazi-core/src/manager/commands/rename.rs index a4b56119..fd27295a 100644 --- a/yazi-core/src/manager/commands/rename.rs +++ b/yazi-core/src/manager/commands/rename.rs @@ -9,18 +9,18 @@ use yazi_shared::{event::Exec, fs::{max_common_root, File, FilesOp, Url}, term:: use crate::{input::Input, manager::Manager}; -pub struct Opt<'a> { +pub struct Opt { force: bool, - empty: &'a str, - cursor: &'a str, + empty: String, + cursor: String, } -impl<'a> From<&'a Exec> for Opt<'a> { - fn from(e: &'a Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { force: e.named.contains_key("force"), - empty: e.named.get("empty").map(|s| s.as_str()).unwrap_or_default(), - cursor: e.named.get("cursor").map(|s| s.as_str()).unwrap_or_default(), + empty: e.take_name("empty").unwrap_or_default(), + cursor: e.take_name("cursor").unwrap_or_default(), } } } @@ -51,7 +51,7 @@ impl Manager { Ok(Self::_hover(Some(new))) } - pub fn rename<'a>(&self, opt: impl Into>) { + pub fn rename(&self, opt: impl Into) { if self.active().in_selecting() { return self.bulk_rename(); } @@ -61,8 +61,8 @@ impl Manager { }; let opt = opt.into() as Opt; - let name = Self::empty_url_part(&hovered, opt.empty); - let cursor = match opt.cursor { + let name = Self::empty_url_part(&hovered, &opt.empty); + let cursor = match opt.cursor.as_str() { "start" => Some(0), "before_ext" => name .chars() diff --git a/yazi-core/src/manager/commands/seek.rs b/yazi-core/src/manager/commands/seek.rs index ecfb7c26..3395fefd 100644 --- a/yazi-core/src/manager/commands/seek.rs +++ b/yazi-core/src/manager/commands/seek.rs @@ -9,9 +9,9 @@ pub struct Opt { units: i16, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - Self { units: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0) } +impl From for Opt { + fn from(mut e: Exec) -> Self { + Self { units: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) } } } diff --git a/yazi-core/src/manager/commands/suspend.rs b/yazi-core/src/manager/commands/suspend.rs index 6218993f..62481eb2 100644 --- a/yazi-core/src/manager/commands/suspend.rs +++ b/yazi-core/src/manager/commands/suspend.rs @@ -4,7 +4,7 @@ use yazi_shared::event::Exec; use crate::manager::Manager; impl Manager { - pub fn suspend(&mut self, _: &Exec) { + pub fn suspend(&mut self, _: Exec) { #[cfg(unix)] tokio::spawn(async move { Scheduler::app_stop().await; diff --git a/yazi-core/src/manager/commands/tab_close.rs b/yazi-core/src/manager/commands/tab_close.rs index 356b4dc7..f74abce1 100644 --- a/yazi-core/src/manager/commands/tab_close.rs +++ b/yazi-core/src/manager/commands/tab_close.rs @@ -6,9 +6,9 @@ pub struct Opt { idx: usize, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - Self { idx: e.args.first().and_then(|i| i.parse().ok()).unwrap_or(0) } +impl From for Opt { + fn from(mut e: Exec) -> Self { + Self { idx: e.take_first().and_then(|i| i.parse().ok()).unwrap_or(0) } } } diff --git a/yazi-core/src/manager/commands/tab_create.rs b/yazi-core/src/manager/commands/tab_create.rs index 2ad51d0a..43dfb5be 100644 --- a/yazi-core/src/manager/commands/tab_create.rs +++ b/yazi-core/src/manager/commands/tab_create.rs @@ -9,12 +9,12 @@ pub struct Opt { current: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { let mut opt = Self { url: None, current: e.named.contains_key("current") }; if !opt.current { - opt.url = Some(e.args.first().map_or_else(|| Url::from("."), Url::from)); + opt.url = Some(e.take_first().map_or_else(|| Url::from("."), Url::from)); } opt } diff --git a/yazi-core/src/manager/commands/tab_swap.rs b/yazi-core/src/manager/commands/tab_swap.rs index aae8300c..5a148d0d 100644 --- a/yazi-core/src/manager/commands/tab_swap.rs +++ b/yazi-core/src/manager/commands/tab_swap.rs @@ -6,9 +6,9 @@ pub struct Opt { step: isize, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - Self { step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0) } +impl From for Opt { + fn from(mut e: Exec) -> Self { + Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) } } } diff --git a/yazi-core/src/manager/commands/tab_switch.rs b/yazi-core/src/manager/commands/tab_switch.rs index 7cd134a6..83f644a3 100644 --- a/yazi-core/src/manager/commands/tab_switch.rs +++ b/yazi-core/src/manager/commands/tab_switch.rs @@ -7,10 +7,10 @@ pub struct Opt { relative: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { - step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0), + step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0), relative: e.named.contains_key("relative"), } } diff --git a/yazi-core/src/manager/commands/update_files.rs b/yazi-core/src/manager/commands/update_files.rs index 888ee1a3..29be95b5 100644 --- a/yazi-core/src/manager/commands/update_files.rs +++ b/yazi-core/src/manager/commands/update_files.rs @@ -8,10 +8,12 @@ pub struct Opt { op: FilesOp, } -impl TryFrom<&Exec> for Opt { +impl TryFrom for Opt { type Error = (); - fn try_from(e: &Exec) -> Result { Ok(Self { op: e.take_data().ok_or(())? }) } + fn try_from(mut e: Exec) -> Result { + Ok(Self { op: e.take_data().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 63e84151..81ef9e9b 100644 --- a/yazi-core/src/manager/commands/update_mimetype.rs +++ b/yazi-core/src/manager/commands/update_mimetype.rs @@ -9,10 +9,12 @@ pub struct Opt { data: ValueSendable, } -impl TryFrom<&Exec> for Opt { +impl TryFrom for Opt { type Error = (); - fn try_from(e: &Exec) -> Result { Ok(Self { data: e.take_data().ok_or(())? }) } + fn try_from(mut e: Exec) -> Result { + Ok(Self { data: e.take_data().ok_or(())? }) + } } impl Manager { diff --git a/yazi-core/src/manager/commands/update_paged.rs b/yazi-core/src/manager/commands/update_paged.rs index ebb43758..38c0fd6b 100644 --- a/yazi-core/src/manager/commands/update_paged.rs +++ b/yazi-core/src/manager/commands/update_paged.rs @@ -8,11 +8,11 @@ pub struct Opt { only_if: Option, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { - page: e.args.first().and_then(|s| s.parse().ok()), - only_if: e.named.get("only-if").map(Url::from), + page: e.take_first().and_then(|s| s.parse().ok()), + only_if: e.take_name("only-if").map(Url::from), } } } @@ -24,13 +24,13 @@ impl From<()> for Opt { impl Manager { #[inline] pub fn _update_paged() { - emit!(Call(Exec::call("update_paged", vec![]).vec(), Layer::Manager)); + emit!(Call(Exec::call("update_paged", vec![]), Layer::Manager)); } #[inline] pub fn _update_paged_by(page: usize, only_if: &Url) { emit!(Call( - Exec::call("update_paged", vec![page.to_string()]).with("only-if", only_if.to_string()).vec(), + Exec::call("update_paged", vec![page.to_string()]).with("only-if", only_if.to_string()), Layer::Manager )); } diff --git a/yazi-core/src/manager/commands/yank.rs b/yazi-core/src/manager/commands/yank.rs index bb917e37..eae09b72 100644 --- a/yazi-core/src/manager/commands/yank.rs +++ b/yazi-core/src/manager/commands/yank.rs @@ -6,8 +6,8 @@ pub struct Opt { cut: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { cut: e.named.contains_key("cut") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { cut: e.named.contains_key("cut") } } } impl Manager { diff --git a/yazi-core/src/select/commands/arrow.rs b/yazi-core/src/select/commands/arrow.rs index 7948d965..067b417c 100644 --- a/yazi-core/src/select/commands/arrow.rs +++ b/yazi-core/src/select/commands/arrow.rs @@ -6,9 +6,9 @@ pub struct Opt { step: isize, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - Self { step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0) } +impl From for Opt { + fn from(mut e: Exec) -> Self { + Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) } } } diff --git a/yazi-core/src/select/commands/close.rs b/yazi-core/src/select/commands/close.rs index bdf0eb68..0a5acbf0 100644 --- a/yazi-core/src/select/commands/close.rs +++ b/yazi-core/src/select/commands/close.rs @@ -7,8 +7,8 @@ pub struct Opt { submit: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { submit: e.named.contains_key("submit") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { submit: e.named.contains_key("submit") } } } impl From for Opt { fn from(submit: bool) -> Self { Self { submit } } diff --git a/yazi-core/src/select/commands/show.rs b/yazi-core/src/select/commands/show.rs index d817df5e..181ffd61 100644 --- a/yazi-core/src/select/commands/show.rs +++ b/yazi-core/src/select/commands/show.rs @@ -10,16 +10,16 @@ pub struct Opt { tx: oneshot::Sender>, } -impl TryFrom<&Exec> for Opt { +impl TryFrom for Opt { type Error = (); - fn try_from(e: &Exec) -> Result { e.take_data().ok_or(()) } + fn try_from(mut e: Exec) -> Result { e.take_data().ok_or(()) } } impl Select { pub async fn _show(cfg: SelectCfg) -> Result { let (tx, rx) = oneshot::channel(); - emit!(Call(Exec::call("show", vec![]).with_data(Opt { cfg, tx }).vec(), Layer::Select)); + emit!(Call(Exec::call("show", vec![]).with_data(Opt { cfg, tx }), Layer::Select)); rx.await.unwrap_or_else(|_| Term::goodbye(|| false)) } diff --git a/yazi-core/src/tab/commands/arrow.rs b/yazi-core/src/tab/commands/arrow.rs index e7512ef5..5d2ccf3c 100644 --- a/yazi-core/src/tab/commands/arrow.rs +++ b/yazi-core/src/tab/commands/arrow.rs @@ -6,9 +6,9 @@ pub struct Opt { step: Step, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - Self { step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or_default() } +impl From for Opt { + fn from(mut e: Exec) -> Self { + Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or_default() } } } diff --git a/yazi-core/src/tab/commands/backstack.rs b/yazi-core/src/tab/commands/backstack.rs index 7bd9cad1..4e8b7f96 100644 --- a/yazi-core/src/tab/commands/backstack.rs +++ b/yazi-core/src/tab/commands/backstack.rs @@ -6,8 +6,8 @@ pub struct Opt; impl From<()> for Opt { fn from(_: ()) -> Self { Self } } -impl From<&Exec> for Opt { - fn from(_: &Exec) -> Self { Self } +impl From for Opt { + fn from(_: Exec) -> Self { Self } } impl Tab { diff --git a/yazi-core/src/tab/commands/cd.rs b/yazi-core/src/tab/commands/cd.rs index 38b1b550..5ea4c198 100644 --- a/yazi-core/src/tab/commands/cd.rs +++ b/yazi-core/src/tab/commands/cd.rs @@ -12,9 +12,9 @@ pub struct Opt { interactive: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - let mut target = Url::from(e.args.first().map(|s| s.as_str()).unwrap_or("")); +impl From for Opt { + fn from(mut e: Exec) -> Self { + let mut target = Url::from(e.take_first().unwrap_or_default()); if target.is_regular() { target.set_path(expand_path(&target)) } @@ -29,7 +29,7 @@ impl From for Opt { impl Tab { #[inline] pub fn _cd(target: &Url) { - emit!(Call(Exec::call("cd", vec![target.to_string()]).vec(), Layer::Manager)); + emit!(Call(Exec::call("cd", vec![target.to_string()]), Layer::Manager)); } pub fn cd(&mut self, opt: impl Into) { diff --git a/yazi-core/src/tab/commands/copy.rs b/yazi-core/src/tab/commands/copy.rs index ddc327f4..b9ede0ca 100644 --- a/yazi-core/src/tab/commands/copy.rs +++ b/yazi-core/src/tab/commands/copy.rs @@ -4,22 +4,22 @@ use yazi_shared::event::Exec; use crate::{tab::Tab, CLIPBOARD}; -pub struct Opt<'a> { - type_: &'a str, +pub struct Opt { + type_: String, } -impl<'a> From<&'a Exec> for Opt<'a> { - fn from(e: &'a Exec) -> Self { Self { type_: e.args.first().map(|s| s.as_str()).unwrap_or("") } } +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { type_: e.take_first().unwrap_or_default() } } } impl Tab { - pub fn copy<'a>(&self, opt: impl Into>) { + pub fn copy(&self, opt: impl Into) { let opt = opt.into() as Opt; let mut s = OsString::new(); let mut it = self.selected().into_iter().peekable(); while let Some(f) = it.next() { - s.push(match opt.type_ { + s.push(match opt.type_.as_str() { "path" => f.url.as_os_str(), "dirname" => f.url.parent().map_or(OsStr::new(""), |p| p.as_os_str()), "filename" => f.name().unwrap_or(OsStr::new("")), diff --git a/yazi-core/src/tab/commands/enter.rs b/yazi-core/src/tab/commands/enter.rs index e84da7e3..6c3391dd 100644 --- a/yazi-core/src/tab/commands/enter.rs +++ b/yazi-core/src/tab/commands/enter.rs @@ -8,8 +8,8 @@ pub struct Opt; impl From<()> for Opt { fn from(_: ()) -> Self { Self } } -impl From<&Exec> for Opt { - fn from(_: &Exec) -> Self { Self } +impl From for Opt { + fn from(_: Exec) -> Self { Self } } impl Tab { diff --git a/yazi-core/src/tab/commands/escape.rs b/yazi-core/src/tab/commands/escape.rs index 052443aa..ce72a1cc 100644 --- a/yazi-core/src/tab/commands/escape.rs +++ b/yazi-core/src/tab/commands/escape.rs @@ -13,15 +13,15 @@ bitflags! { } } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - e.named.iter().fold(Opt::empty(), |acc, (k, _)| match k.as_bytes() { - b"all" => Self::all(), - b"find" => acc | Self::FIND, - b"visual" => acc | Self::VISUAL, - b"select" => acc | Self::SELECT, - b"filter" => acc | Self::FILTER, - b"search" => acc | Self::SEARCH, +impl From for Opt { + fn from(e: Exec) -> Self { + e.named.iter().fold(Opt::empty(), |acc, (k, _)| match k.as_str() { + "all" => Self::all(), + "find" => acc | Self::FIND, + "visual" => acc | Self::VISUAL, + "select" => acc | Self::SELECT, + "filter" => acc | Self::FILTER, + "search" => acc | Self::SEARCH, _ => acc, }) } @@ -47,7 +47,7 @@ impl Tab { #[inline] fn escape_filter(&mut self) -> bool { let b = self.current.files.filter().is_some(); - self.filter_do(super::filter::Opt { query: "", ..Default::default() }); + self.filter_do(super::filter::Opt::default()); b } diff --git a/yazi-core/src/tab/commands/filter.rs b/yazi-core/src/tab/commands/filter.rs index a6378f8a..544ac6f9 100644 --- a/yazi-core/src/tab/commands/filter.rs +++ b/yazi-core/src/tab/commands/filter.rs @@ -8,24 +8,24 @@ use yazi_shared::{emit, event::Exec, render, Debounce, InputError, Layer}; use crate::{folder::{Filter, FilterCase}, input::Input, manager::Manager, tab::Tab}; #[derive(Default)] -pub struct Opt<'a> { - pub query: &'a str, +pub struct Opt { + pub query: String, pub case: FilterCase, pub done: bool, } -impl<'a> From<&'a Exec> for Opt<'a> { - fn from(e: &'a Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { - query: e.args.first().map(|s| s.as_str()).unwrap_or_default(), - case: e.into(), + query: e.take_first().unwrap_or_default(), + case: FilterCase::from(&e), done: e.named.contains_key("done"), } } } impl Tab { - pub fn filter<'a>(&mut self, opt: impl Into>) { + pub fn filter(&mut self, opt: impl Into) { let opt = opt.into() as Opt; tokio::spawn(async move { let rx = Input::_show(InputCfg::filter()); @@ -43,20 +43,19 @@ impl Tab { Exec::call("filter_do", vec![s]) .with_bool("smart", opt.case == FilterCase::Smart) .with_bool("insensitive", opt.case == FilterCase::Insensitive) - .with_bool("done", done) - .vec(), + .with_bool("done", done), Layer::Manager )); } }); } - pub fn filter_do<'a>(&mut self, opt: impl Into>) { + pub fn filter_do(&mut self, opt: impl Into) { let opt = opt.into() as Opt; let filter = if opt.query.is_empty() { None - } else if let Ok(f) = Filter::new(opt.query, opt.case) { + } else if let Ok(f) = Filter::new(&opt.query, opt.case) { Some(f) } else { return; diff --git a/yazi-core/src/tab/commands/find.rs b/yazi-core/src/tab/commands/find.rs index f865c6d2..9dea52f9 100644 --- a/yazi-core/src/tab/commands/find.rs +++ b/yazi-core/src/tab/commands/find.rs @@ -7,18 +7,18 @@ use yazi_shared::{emit, event::Exec, render, Debounce, InputError, Layer}; use crate::{folder::FilterCase, input::Input, tab::{Finder, Tab}}; -pub struct Opt<'a> { - query: Option<&'a str>, +pub struct Opt { + query: Option, prev: bool, case: FilterCase, } -impl<'a> From<&'a Exec> for Opt<'a> { - fn from(e: &'a Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { - query: e.args.first().map(|s| s.as_str()), + query: e.take_first(), prev: e.named.contains_key("previous"), - case: e.into(), + case: FilterCase::from(&e), } } } @@ -27,12 +27,12 @@ pub struct ArrowOpt { prev: bool, } -impl From<&Exec> for ArrowOpt { - fn from(e: &Exec) -> Self { Self { prev: e.named.contains_key("previous") } } +impl From for ArrowOpt { + fn from(e: Exec) -> Self { Self { prev: e.named.contains_key("previous") } } } impl Tab { - pub fn find<'a>(&mut self, opt: impl Into>) { + pub fn find(&mut self, opt: impl Into) { let opt = opt.into() as Opt; tokio::spawn(async move { let rx = Input::_show(InputCfg::find(opt.prev)); @@ -45,15 +45,14 @@ impl Tab { Exec::call("find_do", vec![s]) .with_bool("previous", opt.prev) .with_bool("smart", opt.case == FilterCase::Smart) - .with_bool("insensitive", opt.case == FilterCase::Insensitive) - .vec(), + .with_bool("insensitive", opt.case == FilterCase::Insensitive), Layer::Manager )); } }); } - pub fn find_do<'a>(&mut self, opt: impl Into>) { + pub fn find_do(&mut self, opt: impl Into) { let opt = opt.into() as Opt; let Some(query) = opt.query else { return; @@ -62,7 +61,7 @@ impl Tab { return self.escape(super::escape::Opt::FIND); } - let Ok(finder) = Finder::new(query, opt.case) else { + let Ok(finder) = Finder::new(&query, opt.case) else { return; }; if matches!(&self.finder, Some(f) if f.filter == finder.filter) { diff --git a/yazi-core/src/tab/commands/hidden.rs b/yazi-core/src/tab/commands/hidden.rs index 8dd8f6e5..84a3e93f 100644 --- a/yazi-core/src/tab/commands/hidden.rs +++ b/yazi-core/src/tab/commands/hidden.rs @@ -3,10 +3,10 @@ use yazi_shared::event::Exec; use crate::{manager::Manager, tab::Tab}; impl Tab { - pub fn hidden(&mut self, e: &Exec) { - self.conf.show_hidden = match e.args.first().map(|s| s.as_bytes()) { - Some(b"show") => true, - Some(b"hide") => false, + pub fn hidden(&mut self, e: Exec) { + self.conf.show_hidden = match e.args.first().map(|s| s.as_str()) { + Some("show") => true, + Some("hide") => false, _ => !self.conf.show_hidden, }; diff --git a/yazi-core/src/tab/commands/jump.rs b/yazi-core/src/tab/commands/jump.rs index e1876753..e88ad072 100644 --- a/yazi-core/src/tab/commands/jump.rs +++ b/yazi-core/src/tab/commands/jump.rs @@ -15,8 +15,8 @@ pub enum OptType { Zoxide, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(e: Exec) -> Self { Self { type_: match e.args.first().map(|s| s.as_str()) { Some("fzf") => OptType::Fzf, diff --git a/yazi-core/src/tab/commands/leave.rs b/yazi-core/src/tab/commands/leave.rs index 226a18fa..e7c5519c 100644 --- a/yazi-core/src/tab/commands/leave.rs +++ b/yazi-core/src/tab/commands/leave.rs @@ -8,8 +8,8 @@ pub struct Opt; impl From<()> for Opt { fn from(_: ()) -> Self { Self } } -impl From<&Exec> for Opt { - fn from(_: &Exec) -> Self { Self } +impl From for Opt { + fn from(_: Exec) -> Self { Self } } impl Tab { diff --git a/yazi-core/src/tab/commands/linemode.rs b/yazi-core/src/tab/commands/linemode.rs index 7e66fda5..b3fb5384 100644 --- a/yazi-core/src/tab/commands/linemode.rs +++ b/yazi-core/src/tab/commands/linemode.rs @@ -3,13 +3,13 @@ use yazi_shared::{event::Exec, render}; use crate::tab::Tab; impl Tab { - pub fn linemode(&mut self, e: &Exec) { + pub fn linemode(&mut self, mut e: Exec) { render!(self.conf.patch(|c| { - let Some(mode) = e.args.first() else { + let Some(mode) = e.take_first() else { return; }; if !mode.is_empty() && mode.len() <= 20 { - c.linemode = mode.to_owned(); + c.linemode = mode; } })); } diff --git a/yazi-core/src/tab/commands/preview.rs b/yazi-core/src/tab/commands/preview.rs index 9951eab0..a67e2d97 100644 --- a/yazi-core/src/tab/commands/preview.rs +++ b/yazi-core/src/tab/commands/preview.rs @@ -7,10 +7,12 @@ pub struct Opt { lock: PreviewLock, } -impl TryFrom<&Exec> for Opt { +impl TryFrom for Opt { type Error = (); - fn try_from(e: &Exec) -> Result { Ok(Self { lock: e.take_data().ok_or(())? }) } + fn try_from(mut e: Exec) -> Result { + Ok(Self { lock: e.take_data().ok_or(())? }) + } } impl Tab { diff --git a/yazi-core/src/tab/commands/reveal.rs b/yazi-core/src/tab/commands/reveal.rs index ff0e51ab..bb80fed3 100644 --- a/yazi-core/src/tab/commands/reveal.rs +++ b/yazi-core/src/tab/commands/reveal.rs @@ -6,9 +6,9 @@ pub struct Opt { target: Url, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - let mut target = Url::from(e.args.first().map(|s| s.as_str()).unwrap_or("")); +impl From for Opt { + fn from(mut e: Exec) -> Self { + let mut target = Url::from(e.take_first().unwrap_or_default()); if target.is_regular() { target.set_path(expand_path(&target)) } @@ -23,7 +23,7 @@ impl From for Opt { impl Tab { #[inline] pub fn _reveal(target: &Url) { - emit!(Call(Exec::call("reveal", vec![target.to_string()]).vec(), Layer::Manager)); + emit!(Call(Exec::call("reveal", vec![target.to_string()]), Layer::Manager)); } pub fn reveal(&mut self, opt: impl Into) { diff --git a/yazi-core/src/tab/commands/search.rs b/yazi-core/src/tab/commands/search.rs index 861b37f2..ad5d2166 100644 --- a/yazi-core/src/tab/commands/search.rs +++ b/yazi-core/src/tab/commands/search.rs @@ -16,9 +16,9 @@ pub enum OptType { Fd, } -impl From<&str> for OptType { - fn from(value: &str) -> Self { - match value { +impl From for OptType { + fn from(value: String) -> Self { + match value.as_str() { "rg" => Self::Rg, "fd" => Self::Fd, _ => Self::None, @@ -41,10 +41,8 @@ pub struct Opt { pub type_: OptType, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - Self { type_: e.args.first().map(|s| s.as_str()).unwrap_or_default().into() } - } +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { type_: e.take_first().unwrap_or_default().into() } } } impl Tab { diff --git a/yazi-core/src/tab/commands/select.rs b/yazi-core/src/tab/commands/select.rs index 0170f0d5..d25c4636 100644 --- a/yazi-core/src/tab/commands/select.rs +++ b/yazi-core/src/tab/commands/select.rs @@ -6,8 +6,8 @@ pub struct Opt { state: Option, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { +impl From for Opt { + fn from(e: Exec) -> Self { Self { state: match e.named.get("state").map(|s| s.as_str()) { Some("true") => Some(true), diff --git a/yazi-core/src/tab/commands/shell.rs b/yazi-core/src/tab/commands/shell.rs index 94d0aaff..8f42a367 100644 --- a/yazi-core/src/tab/commands/shell.rs +++ b/yazi-core/src/tab/commands/shell.rs @@ -9,10 +9,10 @@ pub struct Opt { confirm: bool, } -impl<'a> From<&'a Exec> for Opt { - fn from(e: &'a Exec) -> Self { +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { - cmd: e.args.first().map(|e| e.to_owned()).unwrap_or_default(), + cmd: e.take_first().unwrap_or_default(), block: e.named.contains_key("block"), confirm: e.named.contains_key("confirm"), } diff --git a/yazi-core/src/tab/commands/sort.rs b/yazi-core/src/tab/commands/sort.rs index c9e3ce74..70586e0b 100644 --- a/yazi-core/src/tab/commands/sort.rs +++ b/yazi-core/src/tab/commands/sort.rs @@ -6,7 +6,7 @@ use yazi_shared::event::Exec; use crate::{manager::Manager, tab::Tab, tasks::Tasks}; impl Tab { - pub fn sort(&mut self, e: &Exec, tasks: &Tasks) { + pub fn sort(&mut self, e: Exec, tasks: &Tasks) { if let Some(by) = e.args.first() { self.conf.sort_by = SortBy::from_str(by).unwrap_or_default(); } diff --git a/yazi-core/src/tab/commands/visual_mode.rs b/yazi-core/src/tab/commands/visual_mode.rs index b5b1386e..8fb8ea70 100644 --- a/yazi-core/src/tab/commands/visual_mode.rs +++ b/yazi-core/src/tab/commands/visual_mode.rs @@ -8,8 +8,8 @@ pub struct Opt { unset: bool, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { unset: e.named.contains_key("unset") } } +impl From for Opt { + fn from(e: Exec) -> Self { Self { unset: e.named.contains_key("unset") } } } impl Tab { diff --git a/yazi-core/src/tasks/commands/arrow.rs b/yazi-core/src/tasks/commands/arrow.rs index c62059e8..aaf9bbe1 100644 --- a/yazi-core/src/tasks/commands/arrow.rs +++ b/yazi-core/src/tasks/commands/arrow.rs @@ -6,9 +6,9 @@ pub struct Opt { step: isize, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { - Self { step: e.args.first().and_then(|s| s.parse().ok()).unwrap_or(0) } +impl From for Opt { + fn from(mut e: Exec) -> Self { + Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) } } } diff --git a/yazi-core/src/tasks/commands/cancel.rs b/yazi-core/src/tasks/commands/cancel.rs index 6f2c222b..31d126eb 100644 --- a/yazi-core/src/tasks/commands/cancel.rs +++ b/yazi-core/src/tasks/commands/cancel.rs @@ -3,7 +3,7 @@ use yazi_shared::{event::Exec, render}; use crate::tasks::Tasks; impl Tasks { - pub fn cancel(&mut self, _: &Exec) { + pub fn cancel(&mut self, _: Exec) { let id = self.scheduler.running.lock().get_id(self.cursor); if id.map(|id| self.scheduler.cancel(id)) != Some(true) { return; diff --git a/yazi-core/src/tasks/commands/inspect.rs b/yazi-core/src/tasks/commands/inspect.rs index 54da115b..f19cd47b 100644 --- a/yazi-core/src/tasks/commands/inspect.rs +++ b/yazi-core/src/tasks/commands/inspect.rs @@ -8,7 +8,7 @@ use yazi_shared::{event::Exec, term::Term, Defer}; use crate::tasks::Tasks; impl Tasks { - pub fn inspect(&self, _: &Exec) { + pub fn inspect(&self, _: Exec) { let Some(id) = self.scheduler.running.lock().get_id(self.cursor) else { return; }; diff --git a/yazi-core/src/tasks/commands/open.rs b/yazi-core/src/tasks/commands/open.rs index ac2106b5..6ec3f63b 100644 --- a/yazi-core/src/tasks/commands/open.rs +++ b/yazi-core/src/tasks/commands/open.rs @@ -8,15 +8,15 @@ pub struct Opt { opener: Opener, } -impl TryFrom<&Exec> for Opt { +impl TryFrom for Opt { type Error = (); - fn try_from(e: &Exec) -> Result { e.take_data().ok_or(()) } + fn try_from(mut e: Exec) -> Result { e.take_data().ok_or(()) } } impl Tasks { pub fn _open(targets: Vec, opener: Opener) { - emit!(Call(Exec::call("open", vec![]).with_data(Opt { targets, opener }).vec(), Layer::Tasks)); + emit!(Call(Exec::call("open", vec![]).with_data(Opt { targets, opener }), Layer::Tasks)); } pub fn open(&mut self, opt: impl TryInto) { diff --git a/yazi-core/src/tasks/commands/toggle.rs b/yazi-core/src/tasks/commands/toggle.rs index 57534395..391ee072 100644 --- a/yazi-core/src/tasks/commands/toggle.rs +++ b/yazi-core/src/tasks/commands/toggle.rs @@ -4,8 +4,8 @@ use crate::tasks::Tasks; pub struct Opt; -impl From<&Exec> for Opt { - fn from(_: &Exec) -> Self { Self } +impl From for Opt { + fn from(_: Exec) -> Self { Self } } impl From<()> for Opt { fn from(_: ()) -> Self { Self } diff --git a/yazi-core/src/tasks/tasks.rs b/yazi-core/src/tasks/tasks.rs index 5656da71..351d7410 100644 --- a/yazi-core/src/tasks/tasks.rs +++ b/yazi-core/src/tasks/tasks.rs @@ -35,7 +35,7 @@ impl Tasks { let new = TasksProgress::from(&*running.lock()); if last != new { last = new; - emit!(Call(Exec::call("update_progress", vec![]).with_data(new).vec(), Layer::App)); + emit!(Call(Exec::call("update_progress", vec![]).with_data(new), Layer::App)); } } }); @@ -187,6 +187,7 @@ impl Tasks { self.scheduler.preload_paged(rule, targets); }; + #[allow(clippy::needless_range_loop)] for i in 0..PLUGIN.preloaders.len() { if !multi_tasks[i].is_empty() { go(&PLUGIN.preloaders[i], mem::take(&mut multi_tasks[i])); diff --git a/yazi-core/src/which/which.rs b/yazi-core/src/which/which.rs index df096002..5b3ade0f 100644 --- a/yazi-core/src/which/which.rs +++ b/yazi-core/src/which/which.rs @@ -36,10 +36,10 @@ impl Which { self.visible = false; } else if self.cands.len() == 1 { self.visible = false; - emit!(Call(self.cands[0].to_call(), self.layer)); + emit!(Seq(self.cands[0].to_seq(), self.layer)); } else if let Some(i) = self.cands.iter().position(|c| c.on.len() == self.times + 1) { self.visible = false; - emit!(Call(self.cands[i].to_call(), self.layer)); + emit!(Seq(self.cands[i].to_seq(), self.layer)); } self.times += 1; diff --git a/yazi-fm/src/app/app.rs b/yazi-fm/src/app/app.rs index 78ef15a3..1b1f9805 100644 --- a/yazi-fm/src/app/app.rs +++ b/yazi-fm/src/app/app.rs @@ -1,6 +1,6 @@ -use std::{mem, sync::atomic::Ordering}; +use std::{collections::VecDeque, mem, sync::atomic::Ordering}; -use anyhow::{Ok, Result}; +use anyhow::Result; use crossterm::event::KeyEvent; use yazi_config::keymap::Key; use yazi_core::input::InputMode; @@ -25,12 +25,13 @@ impl App { let mut app = Self { cx: Ctx::make(), term: Some(term), signals }; app.render()?; - let mut events = Vec::with_capacity(10); + let mut events = Vec::with_capacity(50); let mut render_in_place = false; - while app.signals.rx.recv_many(&mut events, 10).await > 0 { + while app.signals.rx.recv_many(&mut events, 50).await > 0 { for event in events.drain(..) { match event { Event::Call(exec, layer) => app.dispatch_call(exec, layer), + Event::Seq(execs, layer) => app.dispatch_seq(execs, layer), Event::Render => render_in_place = true, Event::Key(key) => app.dispatch_key(key), Event::Resize => app.resize()?, @@ -43,7 +44,12 @@ impl App { } if mem::replace(&mut render_in_place, false) { - app.render()?; + if let Ok(event) = app.signals.rx.try_recv() { + events.push(event); + NEED_RENDER.store(true, Ordering::Relaxed); + } else { + app.render()?; + } } if NEED_RENDER.swap(false, Ordering::Relaxed) { @@ -66,7 +72,17 @@ impl App { } #[inline] - fn dispatch_call(&mut self, exec: Vec, layer: Layer) { - Executor::new(self).dispatch(&exec, layer); + fn dispatch_call(&mut self, exec: Exec, layer: Layer) { + Executor::new(self).dispatch(exec, layer); + } + + #[inline] + fn dispatch_seq(&mut self, mut execs: VecDeque, layer: Layer) { + if let Some(exec) = execs.pop_front() { + Executor::new(self).dispatch(exec, layer); + } + if !execs.is_empty() { + emit!(Seq(execs, layer)); + } } } diff --git a/yazi-fm/src/app/commands/plugin.rs b/yazi-fm/src/app/commands/plugin.rs index 2a5adcb5..6331ae5f 100644 --- a/yazi-fm/src/app/commands/plugin.rs +++ b/yazi-fm/src/app/commands/plugin.rs @@ -21,7 +21,7 @@ impl App { tokio::spawn(async move { if LOADED.ensure(&opt.name).await.is_ok() { - emit!(Call(Exec::call("plugin_do", vec![opt.name]).with_data(opt.data).vec(), Layer::App)); + emit!(Call(Exec::call("plugin_do", vec![opt.name]).with_data(opt.data), Layer::App)); } }); } diff --git a/yazi-fm/src/app/commands/resume.rs b/yazi-fm/src/app/commands/resume.rs index ecdf925c..e299c5a6 100644 --- a/yazi-fm/src/app/commands/resume.rs +++ b/yazi-fm/src/app/commands/resume.rs @@ -3,7 +3,7 @@ use yazi_shared::{event::Exec, term::Term}; use crate::app::App; impl App { - pub(crate) fn resume(&mut self, _: &Exec) { + pub(crate) fn resume(&mut self, _: Exec) { self.cx.manager.active_mut().preview.reset_image(); self.term = Some(Term::start().unwrap()); diff --git a/yazi-fm/src/app/commands/stop.rs b/yazi-fm/src/app/commands/stop.rs index 64529e0d..ef4dc3b8 100644 --- a/yazi-fm/src/app/commands/stop.rs +++ b/yazi-fm/src/app/commands/stop.rs @@ -7,8 +7,8 @@ pub struct Opt { tx: Option>, } -impl From<&Exec> for Opt { - fn from(e: &Exec) -> Self { Self { tx: e.take_data() } } +impl From for Opt { + fn from(mut e: Exec) -> Self { Self { tx: e.take_data() } } } impl App { diff --git a/yazi-fm/src/app/commands/update_progress.rs b/yazi-fm/src/app/commands/update_progress.rs index 448af77a..45535c54 100644 --- a/yazi-fm/src/app/commands/update_progress.rs +++ b/yazi-fm/src/app/commands/update_progress.rs @@ -8,10 +8,10 @@ pub struct Opt { progress: TasksProgress, } -impl TryFrom<&Exec> for Opt { +impl TryFrom for Opt { type Error = (); - fn try_from(e: &Exec) -> Result { + fn try_from(mut e: Exec) -> Result { Ok(Self { progress: e.take_data().ok_or(())? }) } } diff --git a/yazi-fm/src/executor.rs b/yazi-fm/src/executor.rs index 010eb57e..54b7cb9e 100644 --- a/yazi-fm/src/executor.rs +++ b/yazi-fm/src/executor.rs @@ -1,6 +1,6 @@ use yazi_config::{keymap::{Control, Key}, KEYMAP}; use yazi_core::input::InputMode; -use yazi_shared::{event::Exec, Layer}; +use yazi_shared::{emit, event::Exec, Layer}; use crate::app::App; @@ -12,6 +12,20 @@ impl<'a> Executor<'a> { #[inline] pub(super) fn new(app: &'a mut App) -> Self { Self { app } } + #[inline] + pub(super) fn dispatch(&mut self, exec: Exec, layer: Layer) { + match layer { + Layer::App => self.app(exec), + Layer::Manager => self.manager(exec), + Layer::Tasks => self.tasks(exec), + Layer::Select => self.select(exec), + Layer::Input => self.input(exec), + Layer::Help => self.help(exec), + Layer::Completion => self.completion(exec), + Layer::Which => unreachable!(), + } + } + pub(super) fn handle(&mut self, key: Key) -> bool { let cx = &mut self.app.cx; @@ -42,7 +56,7 @@ impl<'a> Executor<'a> { #[inline] fn matches(&mut self, layer: Layer, key: Key) -> bool { - for Control { on, exec, .. } in KEYMAP.get(layer) { + for ctrl @ Control { on, .. } in KEYMAP.get(layer) { if on.is_empty() || on[0] != key { continue; } @@ -50,30 +64,14 @@ impl<'a> Executor<'a> { if on.len() > 1 { self.app.cx.which.show(&key, layer); } else { - self.dispatch(exec, layer); + emit!(Seq(ctrl.to_seq(), layer)); } return true; } false } - #[inline] - pub(super) fn dispatch(&mut self, exec: &[Exec], layer: Layer) { - for e in exec { - match layer { - Layer::App => self.app(e), - Layer::Manager => self.manager(e), - Layer::Tasks => self.tasks(e), - Layer::Select => self.select(e), - Layer::Input => self.input(e), - Layer::Help => self.help(e), - Layer::Completion => self.completion(e), - Layer::Which => unreachable!(), - }; - } - } - - fn app(&mut self, exec: &Exec) { + fn app(&mut self, exec: Exec) { macro_rules! on { ($name:ident) => { if exec.cmd == stringify!($name) { @@ -89,7 +87,7 @@ impl<'a> Executor<'a> { on!(resume); } - fn manager(&mut self, exec: &Exec) { + fn manager(&mut self, exec: Exec) { macro_rules! on { (MANAGER, $name:ident $(,$args:expr)*) => { if exec.cmd == stringify!($name) { @@ -180,7 +178,7 @@ impl<'a> Executor<'a> { } } - fn tasks(&mut self, exec: &Exec) { + fn tasks(&mut self, exec: Exec) { macro_rules! on { ($name:ident) => { if exec.cmd == stringify!($name) { @@ -200,13 +198,14 @@ impl<'a> Executor<'a> { on!(inspect); on!(cancel); + #[allow(clippy::single_match)] match exec.cmd.as_str() { "help" => self.app.cx.help.toggle(Layer::Tasks), _ => {} } } - fn select(&mut self, exec: &Exec) { + fn select(&mut self, exec: Exec) { macro_rules! on { ($name:ident) => { if exec.cmd == stringify!($name) { @@ -219,13 +218,14 @@ impl<'a> Executor<'a> { on!(close); on!(arrow); + #[allow(clippy::single_match)] match exec.cmd.as_str() { "help" => self.app.cx.help.toggle(Layer::Select), _ => {} } } - fn input(&mut self, exec: &Exec) { + fn input(&mut self, exec: Exec) { macro_rules! on { ($name:ident) => { if exec.cmd == stringify!($name) { @@ -266,6 +266,7 @@ impl<'a> Executor<'a> { on!(undo); on!(redo); + #[allow(clippy::single_match)] match exec.cmd.as_str() { "help" => self.app.cx.help.toggle(Layer::Input), _ => {} @@ -278,7 +279,7 @@ impl<'a> Executor<'a> { } } - fn help(&mut self, exec: &Exec) { + fn help(&mut self, exec: Exec) { macro_rules! on { ($name:ident) => { if exec.cmd == stringify!($name) { @@ -291,13 +292,14 @@ impl<'a> Executor<'a> { on!(arrow); on!(filter); + #[allow(clippy::single_match)] match exec.cmd.as_str() { "close" => self.app.cx.help.toggle(Layer::Help), _ => {} } } - fn completion(&mut self, exec: &Exec) { + fn completion(&mut self, exec: Exec) { macro_rules! on { ($name:ident) => { if exec.cmd == stringify!($name) { @@ -311,6 +313,7 @@ impl<'a> Executor<'a> { on!(close); on!(arrow); + #[allow(clippy::single_match)] match exec.cmd.as_str() { "help" => self.app.cx.help.toggle(Layer::Completion), _ => {} diff --git a/yazi-fm/src/main.rs b/yazi-fm/src/main.rs index 0ecd9e90..ecd90bb9 100644 --- a/yazi-fm/src/main.rs +++ b/yazi-fm/src/main.rs @@ -21,6 +21,7 @@ use context::*; use executor::*; use logs::*; use panic::*; +#[allow(unused_imports)] use root::*; use signals::*; diff --git a/yazi-plugin/src/bindings/mod.rs b/yazi-plugin/src/bindings/mod.rs index 48adf297..ed97e037 100644 --- a/yazi-plugin/src/bindings/mod.rs +++ b/yazi-plugin/src/bindings/mod.rs @@ -8,6 +8,7 @@ mod range; mod url; mod window; +#[allow(unused_imports)] pub use bindings::*; pub use cha::*; pub use file::*; diff --git a/yazi-plugin/src/isolate/peek.rs b/yazi-plugin/src/isolate/peek.rs index 456c04b8..3faff38f 100644 --- a/yazi-plugin/src/isolate/peek.rs +++ b/yazi-plugin/src/isolate/peek.rs @@ -68,7 +68,7 @@ pub fn peek_sync(exec: &Exec, file: yazi_shared::fs::File, skip: usize) { tx: None, }; emit!(Call( - Exec::call("plugin", vec![exec.cmd.to_owned()]).with_bool("sync", true).with_data(data).vec(), + Exec::call("plugin", vec![exec.cmd.to_owned()]).with_bool("sync", true).with_data(data), Layer::App )); } diff --git a/yazi-plugin/src/isolate/seek.rs b/yazi-plugin/src/isolate/seek.rs index ec1b4e4d..6527cd99 100644 --- a/yazi-plugin/src/isolate/seek.rs +++ b/yazi-plugin/src/isolate/seek.rs @@ -15,7 +15,7 @@ pub fn seek_sync(exec: &Exec, file: yazi_shared::fs::File, units: i16) { tx: None, }; emit!(Call( - Exec::call("plugin", vec![exec.cmd.to_owned()]).with_bool("sync", true).with_data(data).vec(), + Exec::call("plugin", vec![exec.cmd.to_owned()]).with_bool("sync", true).with_data(data), Layer::App )); } diff --git a/yazi-plugin/src/opt.rs b/yazi-plugin/src/opt.rs index 7e0aaa16..1daa6f1c 100644 --- a/yazi-plugin/src/opt.rs +++ b/yazi-plugin/src/opt.rs @@ -18,18 +18,14 @@ pub struct OptData { pub tx: Option>, } -impl TryFrom<&Exec> for Opt { +impl TryFrom for Opt { type Error = anyhow::Error; - fn try_from(e: &Exec) -> Result { - let Some(name) = e.args.first().filter(|s| !s.is_empty()) else { + fn try_from(mut e: Exec) -> Result { + let Some(name) = e.take_first().filter(|s| !s.is_empty()) else { bail!("invalid plugin name"); }; - Ok(Self { - name: name.to_owned(), - sync: e.named.contains_key("sync"), - data: e.take_data().unwrap_or_default(), - }) + Ok(Self { name, sync: e.named.contains_key("sync"), data: e.take_data().unwrap_or_default() }) } } diff --git a/yazi-plugin/src/utils/call.rs b/yazi-plugin/src/utils/call.rs index f4cb282b..d827a784 100644 --- a/yazi-plugin/src/utils/call.rs +++ b/yazi-plugin/src/utils/call.rs @@ -48,7 +48,7 @@ impl Utils { exec = exec.with_data(data); } - emit!(Call(exec.vec(), Layer::Manager)); + emit!(Call(exec, Layer::Manager)); Ok(()) }, )?, diff --git a/yazi-plugin/src/utils/preview.rs b/yazi-plugin/src/utils/preview.rs index 372d275e..f3afc84d 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(Exec::call("preview", vec![]).with_data(lock).vec(), Layer::Manager)); + emit!(Call(Exec::call("preview", vec![]).with_data(lock), Layer::Manager)); (true, Value::Nil).into_lua_multi(lua) })?, )?; @@ -67,7 +67,7 @@ impl Utils { ..Default::default() })]; - emit!(Call(Exec::call("preview", vec![]).with_data(lock).vec(), Layer::Manager)); + emit!(Call(Exec::call("preview", vec![]).with_data(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(Exec::call("preview", vec![]).with_data(lock).vec(), Layer::Manager)); + emit!(Call(Exec::call("preview", vec![]).with_data(lock), Layer::Manager)); Ok(()) })?, )?; diff --git a/yazi-scheduler/src/scheduler.rs b/yazi-scheduler/src/scheduler.rs index 7270cc11..510a141f 100644 --- a/yazi-scheduler/src/scheduler.rs +++ b/yazi-scheduler/src/scheduler.rs @@ -164,12 +164,12 @@ impl Scheduler { pub async fn app_stop() { let (tx, rx) = oneshot::channel::<()>(); - emit!(Call(Exec::call("stop", vec![]).with_data(tx).vec(), Layer::App)); + emit!(Call(Exec::call("stop", vec![]).with_data(tx), Layer::App)); rx.await.ok(); } pub fn app_resume() { - emit!(Call(Exec::call("resume", vec![]).vec(), Layer::App)); + emit!(Call(Exec::call("resume", vec![]), Layer::App)); } pub fn file_cut(&self, from: Url, mut to: Url, force: bool) { diff --git a/yazi-shared/src/event/event.rs b/yazi-shared/src/event/event.rs index 256cabb5..7f03f897 100644 --- a/yazi-shared/src/event/event.rs +++ b/yazi-shared/src/event/event.rs @@ -1,4 +1,4 @@ -use std::ffi::OsString; +use std::{collections::VecDeque, ffi::OsString}; use crossterm::event::KeyEvent; use tokio::sync::{mpsc, oneshot}; @@ -10,7 +10,8 @@ static TX: RoCell> = RoCell::new(); #[derive(Debug)] pub enum Event { - Call(Vec, Layer), + Call(Exec, Layer), + Seq(VecDeque, Layer), Render, Key(KeyEvent), Resize, @@ -46,6 +47,9 @@ macro_rules! emit { (Call($exec:expr, $layer:expr)) => { $crate::event::Event::Call($exec, $layer).emit(); }; + (Seq($execs:expr, $layer:expr)) => { + $crate::event::Event::Seq($execs, $layer).emit(); + }; ($event:ident) => { $crate::event::Event::$event.emit(); }; diff --git a/yazi-shared/src/event/exec.rs b/yazi-shared/src/event/exec.rs index ee28c6d7..5a05ee4e 100644 --- a/yazi-shared/src/event/exec.rs +++ b/yazi-shared/src/event/exec.rs @@ -1,11 +1,11 @@ -use std::{any::Any, cell::RefCell, collections::BTreeMap, fmt::{self, Display}}; +use std::{any::Any, collections::BTreeMap, fmt::{self, Display}, mem}; #[derive(Debug, Default)] pub struct Exec { pub cmd: String, pub args: Vec, pub named: BTreeMap, - pub data: RefCell>>, + pub data: Option>, } impl Exec { @@ -19,9 +19,6 @@ impl Exec { Exec { cmd: cwd.to_owned(), named, ..Default::default() } } - #[inline] - pub fn vec(self) -> Vec { vec![self] } - #[inline] pub fn with(mut self, name: impl ToString, value: impl ToString) -> Self { self.named.insert(name.to_string(), value.to_string()); @@ -38,13 +35,31 @@ impl Exec { #[inline] pub fn with_data(mut self, data: impl Any + Send) -> Self { - self.data = RefCell::new(Some(Box::new(data))); + self.data = Some(Box::new(data)); self } #[inline] - pub fn take_data(&self) -> Option { - self.data.replace(None).and_then(|d| d.downcast::().ok()).map(|d| *d) + pub fn take_data(&mut self) -> Option { + self.data.take().and_then(|d| d.downcast::().ok()).map(|d| *d) + } + + #[inline] + pub fn take_first(&mut self) -> Option { + if self.args.is_empty() { None } else { Some(mem::take(&mut self.args[0])) } + } + + #[inline] + pub fn take_name(&mut self, name: &str) -> Option { self.named.remove(name) } + + #[inline] + pub fn clone_without_data(&self) -> Self { + Self { + cmd: self.cmd.clone(), + args: self.args.clone(), + named: self.named.clone(), + ..Default::default() + } } } diff --git a/yazi-shared/src/fs/op.rs b/yazi-shared/src/fs/op.rs index 52692a31..856f226c 100644 --- a/yazi-shared/src/fs/op.rs +++ b/yazi-shared/src/fs/op.rs @@ -36,7 +36,7 @@ impl FilesOp { #[inline] pub fn emit(self) { - emit!(Call(Exec::call("update_files", vec![]).with_data(self).vec(), Layer::Manager)); + emit!(Call(Exec::call("update_files", vec![]).with_data(self), Layer::Manager)); } pub fn prepare(url: &Url) -> u64 {