mirror of
https://github.com/sxyazi/yazi.git
synced 2025-01-02 05:32:03 +03:00
perf: new event system (#561)
This commit is contained in:
parent
acb8b47eee
commit
56ede51c53
@ -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<Exec> {
|
||||
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<Exec> {
|
||||
self.exec.iter().map(|e| e.clone_without_data()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self {
|
||||
Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Exec> 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<Opt>) {
|
||||
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();
|
||||
|
@ -6,20 +6,20 @@ use crate::completion::Completion;
|
||||
|
||||
const LIMIT: usize = 30;
|
||||
|
||||
pub struct Opt<'a> {
|
||||
cache: &'a Vec<String>,
|
||||
cache_name: &'a str,
|
||||
word: &'a str,
|
||||
pub struct Opt {
|
||||
cache: Vec<String>,
|
||||
cache_name: String,
|
||||
word: String,
|
||||
ticket: usize,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Exec> for Opt<'a> {
|
||||
fn from(e: &'a Exec) -> Self {
|
||||
impl From<Exec> 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<Opt<'a>>) {
|
||||
pub fn show(&mut self, opt: impl Into<Opt>) {
|
||||
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));
|
||||
}
|
||||
|
@ -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<Exec> 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<Opt<'a>>) {
|
||||
pub fn trigger(&mut self, opt: impl Into<Opt>) {
|
||||
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
|
||||
));
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self {
|
||||
Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
impl From<isize> for Opt {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self { Self { under: e.named.contains_key("under") } }
|
||||
}
|
||||
impl From<bool> for Opt {
|
||||
fn from(under: bool) -> Self { Self { under } }
|
||||
|
@ -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);
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self { Self { submit: e.named.contains_key("submit") } }
|
||||
}
|
||||
impl From<bool> for Opt {
|
||||
fn from(submit: bool) -> Self { Self { submit } }
|
||||
|
@ -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<Exec> 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<Opt<'a>>) {
|
||||
pub fn complete(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
if self.ticket != opt.ticket {
|
||||
return;
|
||||
|
@ -7,8 +7,8 @@ pub struct Opt {
|
||||
insert: bool,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self {
|
||||
Self { cut: e.named.contains_key("cut"), insert: e.named.contains_key("insert") }
|
||||
}
|
||||
}
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(_: Exec) -> Self { Self }
|
||||
}
|
||||
impl From<()> for Opt {
|
||||
fn from(_: ()) -> Self { Self }
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self { Self { end_of_word: e.named.contains_key("end-of-word") } }
|
||||
}
|
||||
|
||||
impl Input {
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self { Self { append: e.named.contains_key("append") } }
|
||||
}
|
||||
impl From<bool> for Opt {
|
||||
fn from(append: bool) -> Self { Self { append } }
|
||||
|
@ -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<Exec> 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<Opt<'a>>) {
|
||||
pub fn kill(&mut self, opt: impl Into<Opt>) {
|
||||
let opt = opt.into() as Opt;
|
||||
let snap = self.snap_mut();
|
||||
|
||||
|
@ -8,10 +8,10 @@ pub struct Opt {
|
||||
in_operating: bool,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> 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"),
|
||||
}
|
||||
}
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self { Self { before: e.named.contains_key("before") } }
|
||||
}
|
||||
|
||||
impl Input {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -9,16 +9,16 @@ pub struct Opt {
|
||||
tx: mpsc::UnboundedSender<Result<String, InputError>>,
|
||||
}
|
||||
|
||||
impl TryFrom<&Exec> for Opt {
|
||||
impl TryFrom<Exec> for Opt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(e: &Exec) -> Result<Self, Self::Error> { e.take_data().ok_or(()) }
|
||||
fn try_from(mut e: Exec) -> Result<Self, Self::Error> { e.take_data().ok_or(()) }
|
||||
}
|
||||
|
||||
impl Input {
|
||||
pub fn _show(cfg: InputCfg) -> mpsc::UnboundedReceiver<Result<String, InputError>> {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@ use crate::input::{Input, InputMode};
|
||||
|
||||
pub struct Opt;
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(_: &Exec) -> Self { Self }
|
||||
impl From<Exec> for Opt {
|
||||
fn from(_: Exec) -> Self { Self }
|
||||
}
|
||||
|
||||
impl Input {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self { Self { force: e.named.contains_key("force") } }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
|
@ -8,8 +8,8 @@ pub struct Opt {
|
||||
url: Option<Url>,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self { Self { url: e.args.first().map(Url::from) } }
|
||||
impl From<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self { Self { url: e.take_first().map(Url::from) } }
|
||||
}
|
||||
impl From<Option<Url>> for Opt {
|
||||
fn from(url: Option<Url>) -> Self { Self { url } }
|
||||
@ -19,7 +19,7 @@ impl Manager {
|
||||
#[inline]
|
||||
pub fn _hover(url: Option<Url>) {
|
||||
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
|
||||
));
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ pub struct Opt {
|
||||
force: bool,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self {
|
||||
Self { relative: e.named.contains_key("relative"), force: e.named.contains_key("force") }
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ pub struct Opt {
|
||||
interactive: bool,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> 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<String>)>) {
|
||||
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
|
||||
));
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ pub struct Opt {
|
||||
follow: bool,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self {
|
||||
Self { force: e.named.contains_key("force"), follow: e.named.contains_key("follow") }
|
||||
}
|
||||
}
|
||||
|
@ -10,12 +10,12 @@ pub struct Opt {
|
||||
upper_bound: bool,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> 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<bool> 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<Opt>) {
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self { Self { no_cwd_file: e.named.contains_key("no-cwd-file") } }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
|
@ -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());
|
||||
|
||||
|
@ -7,8 +7,8 @@ pub struct Opt {
|
||||
permanently: bool,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self {
|
||||
Self {
|
||||
force: e.named.contains_key("force"),
|
||||
permanently: e.named.contains_key("permanently"),
|
||||
|
@ -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<Exec> 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<Opt<'a>>) {
|
||||
pub fn rename(&self, opt: impl Into<Opt>) {
|
||||
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()
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self {
|
||||
Self { units: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self {
|
||||
Self { idx: e.take_first().and_then(|i| i.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,12 +9,12 @@ pub struct Opt {
|
||||
current: bool,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> 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
|
||||
}
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self {
|
||||
Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,10 @@ pub struct Opt {
|
||||
relative: bool,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> 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"),
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,12 @@ pub struct Opt {
|
||||
op: FilesOp,
|
||||
}
|
||||
|
||||
impl TryFrom<&Exec> for Opt {
|
||||
impl TryFrom<Exec> for Opt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(e: &Exec) -> Result<Self, Self::Error> { Ok(Self { op: e.take_data().ok_or(())? }) }
|
||||
fn try_from(mut e: Exec) -> Result<Self, Self::Error> {
|
||||
Ok(Self { op: e.take_data().ok_or(())? })
|
||||
}
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
|
@ -9,10 +9,12 @@ pub struct Opt {
|
||||
data: ValueSendable,
|
||||
}
|
||||
|
||||
impl TryFrom<&Exec> for Opt {
|
||||
impl TryFrom<Exec> for Opt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(e: &Exec) -> Result<Self, Self::Error> { Ok(Self { data: e.take_data().ok_or(())? }) }
|
||||
fn try_from(mut e: Exec) -> Result<Self, Self::Error> {
|
||||
Ok(Self { data: e.take_data().ok_or(())? })
|
||||
}
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
|
@ -8,11 +8,11 @@ pub struct Opt {
|
||||
only_if: Option<Url>,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> 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
|
||||
));
|
||||
}
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self { Self { cut: e.named.contains_key("cut") } }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self {
|
||||
Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self { Self { submit: e.named.contains_key("submit") } }
|
||||
}
|
||||
impl From<bool> for Opt {
|
||||
fn from(submit: bool) -> Self { Self { submit } }
|
||||
|
@ -10,16 +10,16 @@ pub struct Opt {
|
||||
tx: oneshot::Sender<Result<usize>>,
|
||||
}
|
||||
|
||||
impl TryFrom<&Exec> for Opt {
|
||||
impl TryFrom<Exec> for Opt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(e: &Exec) -> Result<Self, Self::Error> { e.take_data().ok_or(()) }
|
||||
fn try_from(mut e: Exec) -> Result<Self, Self::Error> { e.take_data().ok_or(()) }
|
||||
}
|
||||
|
||||
impl Select {
|
||||
pub async fn _show(cfg: SelectCfg) -> Result<usize> {
|
||||
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))
|
||||
}
|
||||
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self {
|
||||
Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or_default() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(_: Exec) -> Self { Self }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
@ -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<Exec> 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<Url> 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<Opt>) {
|
||||
|
@ -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<Exec> 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<Opt<'a>>) {
|
||||
pub fn copy(&self, opt: impl Into<Opt>) {
|
||||
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("")),
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(_: Exec) -> Self { Self }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
@ -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<Exec> 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
|
||||
}
|
||||
|
||||
|
@ -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<Exec> 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<Opt<'a>>) {
|
||||
pub fn filter(&mut self, opt: impl Into<Opt>) {
|
||||
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<Opt<'a>>) {
|
||||
pub fn filter_do(&mut self, opt: impl Into<Opt>) {
|
||||
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;
|
||||
|
@ -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<String>,
|
||||
prev: bool,
|
||||
case: FilterCase,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Exec> for Opt<'a> {
|
||||
fn from(e: &'a Exec) -> Self {
|
||||
impl From<Exec> 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<Exec> 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<Opt<'a>>) {
|
||||
pub fn find(&mut self, opt: impl Into<Opt>) {
|
||||
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<Opt<'a>>) {
|
||||
pub fn find_do(&mut self, opt: impl Into<Opt>) {
|
||||
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) {
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -15,8 +15,8 @@ pub enum OptType {
|
||||
Zoxide,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self {
|
||||
Self {
|
||||
type_: match e.args.first().map(|s| s.as_str()) {
|
||||
Some("fzf") => OptType::Fzf,
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(_: Exec) -> Self { Self }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
@ -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;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -7,10 +7,12 @@ pub struct Opt {
|
||||
lock: PreviewLock,
|
||||
}
|
||||
|
||||
impl TryFrom<&Exec> for Opt {
|
||||
impl TryFrom<Exec> for Opt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(e: &Exec) -> Result<Self, Self::Error> { Ok(Self { lock: e.take_data().ok_or(())? }) }
|
||||
fn try_from(mut e: Exec) -> Result<Self, Self::Error> {
|
||||
Ok(Self { lock: e.take_data().ok_or(())? })
|
||||
}
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
@ -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<Exec> 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<Url> 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<Opt>) {
|
||||
|
@ -16,9 +16,9 @@ pub enum OptType {
|
||||
Fd,
|
||||
}
|
||||
|
||||
impl From<&str> for OptType {
|
||||
fn from(value: &str) -> Self {
|
||||
match value {
|
||||
impl From<String> 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<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self { Self { type_: e.take_first().unwrap_or_default().into() } }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
@ -6,8 +6,8 @@ pub struct Opt {
|
||||
state: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self {
|
||||
impl From<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self {
|
||||
Self {
|
||||
state: match e.named.get("state").map(|s| s.as_str()) {
|
||||
Some("true") => Some(true),
|
||||
|
@ -9,10 +9,10 @@ pub struct Opt {
|
||||
confirm: bool,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Exec> for Opt {
|
||||
fn from(e: &'a Exec) -> Self {
|
||||
impl From<Exec> 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"),
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(e: Exec) -> Self { Self { unset: e.named.contains_key("unset") } }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
@ -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<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self {
|
||||
Self { step: e.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -8,15 +8,15 @@ pub struct Opt {
|
||||
opener: Opener,
|
||||
}
|
||||
|
||||
impl TryFrom<&Exec> for Opt {
|
||||
impl TryFrom<Exec> for Opt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(e: &Exec) -> Result<Self, Self::Error> { e.take_data().ok_or(()) }
|
||||
fn try_from(mut e: Exec) -> Result<Self, Self::Error> { e.take_data().ok_or(()) }
|
||||
}
|
||||
|
||||
impl Tasks {
|
||||
pub fn _open(targets: Vec<Url>, 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<Opt>) {
|
||||
|
@ -4,8 +4,8 @@ use crate::tasks::Tasks;
|
||||
|
||||
pub struct Opt;
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(_: &Exec) -> Self { Self }
|
||||
impl From<Exec> for Opt {
|
||||
fn from(_: Exec) -> Self { Self }
|
||||
}
|
||||
impl From<()> for Opt {
|
||||
fn from(_: ()) -> Self { Self }
|
||||
|
@ -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]));
|
||||
|
@ -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;
|
||||
|
@ -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<Exec>, 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<Exec>, layer: Layer) {
|
||||
if let Some(exec) = execs.pop_front() {
|
||||
Executor::new(self).dispatch(exec, layer);
|
||||
}
|
||||
if !execs.is_empty() {
|
||||
emit!(Seq(execs, layer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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());
|
||||
|
||||
|
@ -7,8 +7,8 @@ pub struct Opt {
|
||||
tx: Option<oneshot::Sender<()>>,
|
||||
}
|
||||
|
||||
impl From<&Exec> for Opt {
|
||||
fn from(e: &Exec) -> Self { Self { tx: e.take_data() } }
|
||||
impl From<Exec> for Opt {
|
||||
fn from(mut e: Exec) -> Self { Self { tx: e.take_data() } }
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
@ -8,10 +8,10 @@ pub struct Opt {
|
||||
progress: TasksProgress,
|
||||
}
|
||||
|
||||
impl TryFrom<&Exec> for Opt {
|
||||
impl TryFrom<Exec> for Opt {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(e: &Exec) -> Result<Self, Self::Error> {
|
||||
fn try_from(mut e: Exec) -> Result<Self, Self::Error> {
|
||||
Ok(Self { progress: e.take_data().ok_or(())? })
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
_ => {}
|
||||
|
@ -21,6 +21,7 @@ use context::*;
|
||||
use executor::*;
|
||||
use logs::*;
|
||||
use panic::*;
|
||||
#[allow(unused_imports)]
|
||||
use root::*;
|
||||
use signals::*;
|
||||
|
||||
|
@ -8,6 +8,7 @@ mod range;
|
||||
mod url;
|
||||
mod window;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
pub use bindings::*;
|
||||
pub use cha::*;
|
||||
pub use file::*;
|
||||
|
@ -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
|
||||
));
|
||||
}
|
||||
|
@ -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
|
||||
));
|
||||
}
|
||||
|
@ -18,18 +18,14 @@ pub struct OptData {
|
||||
pub tx: Option<oneshot::Sender<ValueSendable>>,
|
||||
}
|
||||
|
||||
impl TryFrom<&Exec> for Opt {
|
||||
impl TryFrom<Exec> for Opt {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(e: &Exec) -> Result<Self, Self::Error> {
|
||||
let Some(name) = e.args.first().filter(|s| !s.is_empty()) else {
|
||||
fn try_from(mut e: Exec) -> Result<Self, Self::Error> {
|
||||
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() })
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ impl Utils {
|
||||
exec = exec.with_data(data);
|
||||
}
|
||||
|
||||
emit!(Call(exec.vec(), Layer::Manager));
|
||||
emit!(Call(exec, Layer::Manager));
|
||||
Ok(())
|
||||
},
|
||||
)?,
|
||||
|
@ -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(())
|
||||
})?,
|
||||
)?;
|
||||
|
@ -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) {
|
||||
|
@ -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<mpsc::UnboundedSender<Event>> = RoCell::new();
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Event {
|
||||
Call(Vec<Exec>, Layer),
|
||||
Call(Exec, Layer),
|
||||
Seq(VecDeque<Exec>, 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();
|
||||
};
|
||||
|
@ -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<String>,
|
||||
pub named: BTreeMap<String, String>,
|
||||
pub data: RefCell<Option<Box<dyn Any + Send>>>,
|
||||
pub data: Option<Box<dyn Any + Send>>,
|
||||
}
|
||||
|
||||
impl Exec {
|
||||
@ -19,9 +19,6 @@ impl Exec {
|
||||
Exec { cmd: cwd.to_owned(), named, ..Default::default() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn vec(self) -> Vec<Self> { 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<T: 'static>(&self) -> Option<T> {
|
||||
self.data.replace(None).and_then(|d| d.downcast::<T>().ok()).map(|d| *d)
|
||||
pub fn take_data<T: 'static>(&mut self) -> Option<T> {
|
||||
self.data.take().and_then(|d| d.downcast::<T>().ok()).map(|d| *d)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn take_first(&mut self) -> Option<String> {
|
||||
if self.args.is_empty() { None } else { Some(mem::take(&mut self.args[0])) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn take_name(&mut self, name: &str) -> Option<String> { 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user