mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: expand the types supported by the event system
This commit is contained in:
parent
2975b999bf
commit
8ed0def9c6
61 changed files with 246 additions and 157 deletions
|
|
@ -15,9 +15,7 @@ pub struct Control {
|
|||
|
||||
impl Control {
|
||||
#[inline]
|
||||
pub fn to_seq(&self) -> VecDeque<Cmd> {
|
||||
self.run.iter().map(|e| e.clone_without_data()).collect()
|
||||
}
|
||||
pub fn to_seq(&self) -> VecDeque<Cmd> { self.run.iter().map(|c| c.shallow_clone()).collect() }
|
||||
}
|
||||
|
||||
impl Control {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::fmt;
|
||||
use std::{fmt, mem};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use serde::{de::{self, Visitor}, Deserializer};
|
||||
use yazi_shared::event::Cmd;
|
||||
use yazi_shared::event::{Arg, Cmd};
|
||||
|
||||
pub(super) fn run_deserialize<'de, D>(deserializer: D) -> Result<Vec<Cmd>, D::Error>
|
||||
where
|
||||
|
|
@ -11,20 +11,24 @@ where
|
|||
struct RunVisitor;
|
||||
|
||||
fn parse(s: &str) -> Result<Cmd> {
|
||||
let s = shell_words::split(s)?;
|
||||
if s.is_empty() {
|
||||
let mut args = shell_words::split(s)?;
|
||||
if args.is_empty() {
|
||||
bail!("`run` cannot be empty");
|
||||
}
|
||||
|
||||
let mut cmd = Cmd { name: s[0].clone(), ..Default::default() };
|
||||
for arg in s.into_iter().skip(1) {
|
||||
if arg.starts_with("--") {
|
||||
let mut arg = arg.splitn(2, '=');
|
||||
let key = arg.next().unwrap().trim_start_matches('-');
|
||||
let val = arg.next().unwrap_or("").to_string();
|
||||
cmd.named.insert(key.to_string(), val);
|
||||
let mut cmd = Cmd { name: mem::take(&mut args[0]), ..Default::default() };
|
||||
for (i, arg) in args.into_iter().skip(1).enumerate() {
|
||||
if !arg.starts_with("--") {
|
||||
cmd.args.insert(i.to_string(), Arg::String(arg));
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut parts = arg.splitn(2, '=');
|
||||
let key = parts.next().unwrap().trim_start_matches('-').to_owned();
|
||||
if let Some(val) = parts.next() {
|
||||
cmd.args.insert(key, Arg::String(val.to_owned()));
|
||||
} else {
|
||||
cmd.args.push(arg);
|
||||
cmd.args.insert(key, Arg::Boolean(true));
|
||||
}
|
||||
}
|
||||
Ok(cmd)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self { step: c.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { submit: c.named.contains_key("submit") } }
|
||||
fn from(c: Cmd) -> Self { Self { submit: c.get_bool("submit") } }
|
||||
}
|
||||
|
||||
impl Completion {
|
||||
|
|
|
|||
|
|
@ -16,10 +16,12 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
cache: mem::take(&mut c.args),
|
||||
cache_name: c.take_name("cache-name").unwrap_or_default(),
|
||||
word: c.take_name("word").unwrap_or_default(),
|
||||
ticket: c.take_name("ticket").and_then(|v| v.parse().ok()).unwrap_or(0),
|
||||
// cache: mem::take(&mut c.args),
|
||||
// TODO: Fix this
|
||||
cache: vec![],
|
||||
cache_name: c.take_name_str("cache-name").unwrap_or_default(),
|
||||
word: c.take_name_str("word").unwrap_or_default(),
|
||||
ticket: c.take_name_str("ticket").and_then(|v| v.parse().ok()).unwrap_or(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
word: c.take_first().unwrap_or_default(),
|
||||
ticket: c.take_name("ticket").and_then(|s| s.parse().ok()).unwrap_or(0),
|
||||
word: c.take_first_str().unwrap_or_default(),
|
||||
ticket: c.take_name_str("ticket").and_then(|s| s.parse().ok()).unwrap_or(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ pub enum FilterCase {
|
|||
|
||||
impl From<&Cmd> for FilterCase {
|
||||
fn from(c: &Cmd) -> Self {
|
||||
match (c.named.contains_key("smart"), c.named.contains_key("insensitive")) {
|
||||
match (c.get_bool("smart"), c.get_bool("insensitive")) {
|
||||
(true, _) => Self::Smart,
|
||||
(_, false) => Self::Sensitive,
|
||||
(_, true) => Self::Insensitive,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self { step: c.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
impl From<isize> for Opt {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { under: c.named.contains_key("under") } }
|
||||
fn from(c: Cmd) -> Self { Self { under: c.get_bool("under") } }
|
||||
}
|
||||
impl From<bool> for Opt {
|
||||
fn from(under: bool) -> Self { Self { under } }
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { submit: c.named.contains_key("submit") } }
|
||||
fn from(c: Cmd) -> Self { Self { submit: c.get_bool("submit") } }
|
||||
}
|
||||
impl From<bool> for Opt {
|
||||
fn from(submit: bool) -> Self { Self { submit } }
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
word: c.take_first().unwrap_or_default(),
|
||||
ticket: c.take_name("ticket").and_then(|s| s.parse().ok()).unwrap_or(0),
|
||||
word: c.take_first_str().unwrap_or_default(),
|
||||
ticket: c.take_name_str("ticket").and_then(|s| s.parse().ok()).unwrap_or(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self {
|
||||
Self { cut: c.named.contains_key("cut"), insert: c.named.contains_key("insert") }
|
||||
}
|
||||
fn from(c: Cmd) -> Self { Self { cut: c.get_bool("cut"), insert: c.get_bool("insert") } }
|
||||
}
|
||||
|
||||
impl Input {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { end_of_word: c.named.contains_key("end-of-word") } }
|
||||
fn from(c: Cmd) -> Self { Self { end_of_word: c.get_bool("end-of-word") } }
|
||||
}
|
||||
|
||||
impl Input {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { append: c.named.contains_key("append") } }
|
||||
fn from(c: Cmd) -> Self { Self { append: c.get_bool("append") } }
|
||||
}
|
||||
impl From<bool> for Opt {
|
||||
fn from(append: bool) -> Self { Self { append } }
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self { Self { kind: c.take_first().unwrap_or_default() } }
|
||||
fn from(mut c: Cmd) -> Self { Self { kind: c.take_first_str().unwrap_or_default() } }
|
||||
}
|
||||
|
||||
impl Input {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
step: c.take_first().and_then(|s| s.parse().ok()).unwrap_or(0),
|
||||
in_operating: c.named.contains_key("in-operating"),
|
||||
step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0),
|
||||
in_operating: c.get_bool("in-operating"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { before: c.named.contains_key("before") } }
|
||||
fn from(c: Cmd) -> Self { Self { before: c.get_bool("before") } }
|
||||
}
|
||||
|
||||
impl Input {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { force: c.named.contains_key("force") } }
|
||||
fn from(c: Cmd) -> Self { Self { force: c.get_bool("force") } }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self { Self { url: c.take_first().map(Url::from) } }
|
||||
fn from(mut c: Cmd) -> Self { Self { url: c.take_first_str().map(Url::from) } }
|
||||
}
|
||||
impl From<Option<Url>> for Opt {
|
||||
fn from(url: Option<Url>) -> Self { Self { url } }
|
||||
|
|
|
|||
|
|
@ -8,9 +8,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self {
|
||||
Self { relative: c.named.contains_key("relative"), force: c.named.contains_key("force") }
|
||||
}
|
||||
fn from(c: Cmd) -> Self { Self { relative: c.get_bool("relative"), force: c.get_bool("force") } }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self {
|
||||
Self {
|
||||
interactive: c.named.contains_key("interactive"),
|
||||
hovered: c.named.contains_key("hovered"),
|
||||
}
|
||||
Self { interactive: c.get_bool("interactive"), hovered: c.get_bool("hovered") }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self {
|
||||
Self { force: c.named.contains_key("force"), follow: c.named.contains_key("follow") }
|
||||
}
|
||||
fn from(c: Cmd) -> Self { Self { force: c.get_bool("force"), follow: c.get_bool("follow") } }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
skip: c.take_first().and_then(|s| s.parse().ok()),
|
||||
force: c.named.contains_key("force"),
|
||||
only_if: c.take_name("only-if").map(Url::from),
|
||||
upper_bound: c.named.contains_key("upper-bound"),
|
||||
skip: c.take_first_str().and_then(|s| s.parse().ok()),
|
||||
force: c.get_bool("force"),
|
||||
only_if: c.take_name_str("only-if").map(Url::from),
|
||||
upper_bound: c.get_bool("upper-bound"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ impl From<()> for Opt {
|
|||
fn from(_: ()) -> Self { Self::default() }
|
||||
}
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { no_cwd_file: c.named.contains_key("no-cwd-file") } }
|
||||
fn from(c: Cmd) -> Self { Self { no_cwd_file: c.get_bool("no-cwd-file") } }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
force: c.named.contains_key("force"),
|
||||
permanently: c.named.contains_key("permanently"),
|
||||
force: c.get_bool("force"),
|
||||
permanently: c.get_bool("permanently"),
|
||||
targets: c.take_data().unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
force: c.named.contains_key("force"),
|
||||
empty: c.take_name("empty").unwrap_or_default(),
|
||||
cursor: c.take_name("cursor").unwrap_or_default(),
|
||||
force: c.get_bool("force"),
|
||||
empty: c.take_name_str("empty").unwrap_or_default(),
|
||||
cursor: c.take_name_str("cursor").unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self { units: c.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
Self { units: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self { idx: c.take_first().and_then(|i| i.parse().ok()).unwrap_or(0) }
|
||||
Self { idx: c.take_first_str().and_then(|i| i.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
if c.named.contains_key("current") {
|
||||
if c.get_bool("current") {
|
||||
Self { url: Default::default(), current: true }
|
||||
} else {
|
||||
Self {
|
||||
url: c.take_first().map_or_else(|| Url::from(&BOOT.cwd), Url::from),
|
||||
url: c.take_first_str().map_or_else(|| Url::from(&BOOT.cwd), Url::from),
|
||||
current: false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self { step: c.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
step: c.take_first().and_then(|s| s.parse().ok()).unwrap_or(0),
|
||||
relative: c.named.contains_key("relative"),
|
||||
step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0),
|
||||
relative: c.get_bool("relative"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
page: c.take_first().and_then(|s| s.parse().ok()),
|
||||
only_if: c.take_name("only-if").map(Url::from),
|
||||
page: c.take_first_str().and_then(|s| s.parse().ok()),
|
||||
only_if: c.take_name_str("only-if").map(Url::from),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { cut: c.named.contains_key("cut") } }
|
||||
fn from(c: Cmd) -> Self { Self { cut: c.get_bool("cut") } }
|
||||
}
|
||||
|
||||
impl Manager {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ impl TryFrom<Cmd> for Opt {
|
|||
type Error = ();
|
||||
|
||||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> {
|
||||
let interval = c.take_first().and_then(|s| s.parse::<f64>().ok()).ok_or(())?;
|
||||
let interval = c.take_first_str().and_then(|s| s.parse::<f64>().ok()).ok_or(())?;
|
||||
if interval < 0.0 {
|
||||
return Err(());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self { step: c.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { submit: c.named.contains_key("submit") } }
|
||||
fn from(c: Cmd) -> Self { Self { submit: c.get_bool("submit") } }
|
||||
}
|
||||
impl From<bool> for Opt {
|
||||
fn from(submit: bool) -> Self { Self { submit } }
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self { step: c.take_first().and_then(|s| s.parse().ok()).unwrap_or_default() }
|
||||
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or_default() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
let mut target = Url::from(c.take_first().unwrap_or_default());
|
||||
let mut target = Url::from(c.take_first_str().unwrap_or_default());
|
||||
if target.is_regular() {
|
||||
target.set_path(expand_path(&target))
|
||||
}
|
||||
|
||||
Self { target, interactive: c.named.contains_key("interactive") }
|
||||
Self { target, interactive: c.get_bool("interactive") }
|
||||
}
|
||||
}
|
||||
impl From<Url> for Opt {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self { Self { type_: c.take_first().unwrap_or_default() } }
|
||||
fn from(mut c: Cmd) -> Self { Self { type_: c.take_first_str().unwrap_or_default() } }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
|
|
|||
|
|
@ -16,14 +16,16 @@ bitflags! {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self {
|
||||
c.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,
|
||||
c.args.iter().fold(Opt::empty(), |acc, (k, v)| {
|
||||
match (k.as_str(), v.as_bool().unwrap_or(false)) {
|
||||
("all", true) => Self::all(),
|
||||
("find", true) => acc | Self::FIND,
|
||||
("visual", true) => acc | Self::VISUAL,
|
||||
("select", true) => acc | Self::SELECT,
|
||||
("filter", true) => acc | Self::FILTER,
|
||||
("search", true) => acc | Self::SEARCH,
|
||||
_ => acc,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
query: c.take_first().unwrap_or_default(),
|
||||
query: c.take_first_str().unwrap_or_default(),
|
||||
case: FilterCase::from(&c),
|
||||
done: c.named.contains_key("done"),
|
||||
done: c.get_bool("done"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
query: c.take_first(),
|
||||
prev: c.named.contains_key("previous"),
|
||||
case: FilterCase::from(&c),
|
||||
}
|
||||
Self { query: c.take_first_str(), prev: c.get_bool("previous"), case: FilterCase::from(&c) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +25,7 @@ pub struct ArrowOpt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for ArrowOpt {
|
||||
fn from(c: Cmd) -> Self { Self { prev: c.named.contains_key("previous") } }
|
||||
fn from(c: Cmd) -> Self { Self { prev: c.get_bool("previous") } }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use yazi_shared::event::Cmd;
|
|||
use crate::tab::Tab;
|
||||
|
||||
impl Tab {
|
||||
pub fn hidden(&mut self, c: Cmd) {
|
||||
self.conf.show_hidden = match c.args.first().map(|s| s.as_str()) {
|
||||
pub fn hidden(&mut self, mut c: Cmd) {
|
||||
self.conf.show_hidden = match c.take_first_str().as_deref() {
|
||||
Some("show") => true,
|
||||
Some("hide") => false,
|
||||
_ => !self.conf.show_hidden,
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ pub enum OptType {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
type_: match c.args.first().map(|s| s.as_str()) {
|
||||
type_: match c.take_first_str().as_deref() {
|
||||
Some("fzf") => OptType::Fzf,
|
||||
Some("zoxide") => OptType::Zoxide,
|
||||
_ => OptType::None,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use crate::tab::Tab;
|
|||
impl Tab {
|
||||
pub fn linemode(&mut self, mut c: Cmd) {
|
||||
render!(self.conf.patch(|new| {
|
||||
let Some(mode) = c.take_first() else {
|
||||
let Some(mode) = c.take_first_str() else {
|
||||
return;
|
||||
};
|
||||
if !mode.is_empty() && mode.len() <= 20 {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
let mut target = Url::from(c.take_first().unwrap_or_default());
|
||||
let mut target = Url::from(c.take_first_str().unwrap_or_default());
|
||||
if target.is_regular() {
|
||||
target.set_path(expand_path(&target))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self { Self { type_: c.take_first().unwrap_or_default().into() } }
|
||||
fn from(mut c: Cmd) -> Self { Self { type_: c.take_first_str().unwrap_or_default().into() } }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ pub struct Opt<'a> {
|
|||
impl<'a> From<Cmd> for Opt<'a> {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
url: c.take_name("url").map(|s| Cow::Owned(Url::from(s))),
|
||||
state: match c.named.get("state").map(|s| s.as_str()) {
|
||||
url: c.take_name_str("url").map(|s| Cow::Owned(Url::from(s))),
|
||||
state: match c.take_name_str("state").as_deref() {
|
||||
Some("true") => Some(true),
|
||||
Some("false") => Some(false),
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
state: match c.named.get("state").map(|s| s.as_str()) {
|
||||
state: match c.take_name_str("state").as_deref() {
|
||||
Some("true") => Some(true),
|
||||
Some("false") => Some(false),
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@ pub struct Opt {
|
|||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self {
|
||||
run: c.take_first().unwrap_or_default(),
|
||||
block: c.named.contains_key("block"),
|
||||
orphan: c.named.contains_key("orphan"),
|
||||
confirm: c.named.contains_key("confirm"),
|
||||
run: c.take_first_str().unwrap_or_default(),
|
||||
block: c.get_bool("block"),
|
||||
orphan: c.get_bool("orphan"),
|
||||
confirm: c.get_bool("confirm"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ use yazi_shared::event::Cmd;
|
|||
use crate::{tab::Tab, tasks::Tasks};
|
||||
|
||||
impl Tab {
|
||||
pub fn sort(&mut self, c: Cmd, tasks: &Tasks) {
|
||||
if let Some(by) = c.args.first() {
|
||||
self.conf.sort_by = SortBy::from_str(by).unwrap_or_default();
|
||||
pub fn sort(&mut self, mut c: Cmd, tasks: &Tasks) {
|
||||
if let Some(by) = c.take_first_str() {
|
||||
self.conf.sort_by = SortBy::from_str(&by).unwrap_or_default();
|
||||
}
|
||||
self.conf.sort_sensitive = c.named.contains_key("sensitive");
|
||||
self.conf.sort_reverse = c.named.contains_key("reverse");
|
||||
self.conf.sort_dir_first = c.named.contains_key("dir-first");
|
||||
self.conf.sort_sensitive = c.get_bool("sensitive");
|
||||
self.conf.sort_reverse = c.get_bool("reverse");
|
||||
self.conf.sort_dir_first = c.get_bool("dir-first");
|
||||
|
||||
self.apply_files_attrs();
|
||||
ManagerProxy::update_paged();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub struct Opt {
|
|||
}
|
||||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(c: Cmd) -> Self { Self { unset: c.named.contains_key("unset") } }
|
||||
fn from(c: Cmd) -> Self { Self { unset: c.get_bool("unset") } }
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Opt {
|
|||
|
||||
impl From<Cmd> for Opt {
|
||||
fn from(mut c: Cmd) -> Self {
|
||||
Self { step: c.take_first().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ impl TryFrom<Cmd> for Opt {
|
|||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
tx: c.take_data().ok_or(())?,
|
||||
idx: c.take_first().and_then(|s| s.parse().ok()).ok_or(())?,
|
||||
idx: c.take_first_str().and_then(|s| s.parse().ok()).ok_or(())?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ impl TryFrom<Cmd> for Opt {
|
|||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
cands: c.take_data().unwrap_or_default(),
|
||||
layer: Layer::from_str(&c.take_name("layer").unwrap_or_default())?,
|
||||
silent: c.named.contains_key("silent"),
|
||||
layer: Layer::from_str(&c.take_name_str("layer").unwrap_or_default())?,
|
||||
silent: c.get_bool("silent"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ impl<'a> Executor<'a> {
|
|||
on!(forward);
|
||||
|
||||
if cmd.name.as_str() == "complete" {
|
||||
return if cmd.named.contains_key("trigger") {
|
||||
return if cmd.get_bool("trigger") {
|
||||
self.app.cx.completion.trigger(cmd)
|
||||
} else {
|
||||
self.app.cx.input.complete(cmd)
|
||||
|
|
|
|||
|
|
@ -19,16 +19,16 @@ impl TryFrom<Cmd> for Opt {
|
|||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> {
|
||||
let Some(name) = c.take_first().filter(|s| !s.is_empty()) else {
|
||||
let Some(name) = c.take_first_str().filter(|s| !s.is_empty()) else {
|
||||
bail!("plugin name cannot be empty");
|
||||
};
|
||||
|
||||
let mut data: OptData = c.take_data().unwrap_or_default();
|
||||
|
||||
if let Some(args) = c.named.get("args") {
|
||||
if let Some(args) = c.get_str("args") {
|
||||
data.args = shell_words::split(args)?.into_iter().map(ValueSendable::String).collect();
|
||||
}
|
||||
|
||||
Ok(Self { name, sync: c.named.contains_key("sync"), data })
|
||||
Ok(Self { name, sync: c.get_bool("sync"), data })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,13 +40,16 @@ impl Utils {
|
|||
|
||||
#[inline]
|
||||
fn create_cmd(name: String, table: Table, data: Option<Value>) -> mlua::Result<Cmd> {
|
||||
let (args, named) = Self::parse_args(table)?;
|
||||
let mut cmd = Cmd { name, args, named, ..Default::default() };
|
||||
// TODO: Fix this
|
||||
return Ok(Cmd { name, args: Default::default(), data: None });
|
||||
|
||||
if let Some(data) = data.and_then(|v| ValueSendable::try_from(v).ok()) {
|
||||
cmd = cmd.with_data(data);
|
||||
}
|
||||
Ok(cmd)
|
||||
// let (args, named) = Self::parse_args(table)?;
|
||||
// let mut cmd = Cmd { name, args, named, ..Default::default() };
|
||||
|
||||
// if let Some(data) = data.and_then(|v| ValueSendable::try_from(v).ok()) {
|
||||
// cmd = cmd.with_data(data);
|
||||
// }
|
||||
// Ok(cmd)
|
||||
}
|
||||
|
||||
pub(super) fn call(lua: &Lua, ya: &Table) -> mlua::Result<()> {
|
||||
|
|
|
|||
76
yazi-shared/src/event/arg.rs
Normal file
76
yazi-shared/src/event/arg.rs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::bail;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::OrderedFloat;
|
||||
|
||||
// --- Arg
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum Arg {
|
||||
Nil,
|
||||
Boolean(bool),
|
||||
Integer(i64),
|
||||
Number(f64),
|
||||
String(String),
|
||||
Table(HashMap<ArgKey, Arg>),
|
||||
}
|
||||
|
||||
impl Arg {
|
||||
#[inline]
|
||||
pub fn as_bool(&self) -> Option<bool> {
|
||||
match self {
|
||||
Self::Boolean(b) => Some(*b),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_str(&self) -> Option<&str> {
|
||||
match self {
|
||||
Self::String(s) => Some(s),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_table_string(self) -> HashMap<String, String> {
|
||||
let Self::Table(table) = self else {
|
||||
return Default::default();
|
||||
};
|
||||
|
||||
let mut map = HashMap::with_capacity(table.len());
|
||||
for pair in table {
|
||||
if let (ArgKey::String(k), Self::String(v)) = pair {
|
||||
map.insert(k, v);
|
||||
}
|
||||
}
|
||||
map
|
||||
}
|
||||
}
|
||||
|
||||
// --- Key
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ArgKey {
|
||||
Nil,
|
||||
Boolean(bool),
|
||||
Integer(i64),
|
||||
Number(OrderedFloat),
|
||||
String(String),
|
||||
}
|
||||
|
||||
impl TryInto<ArgKey> for Arg {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_into(self) -> Result<ArgKey, Self::Error> {
|
||||
Ok(match self {
|
||||
Self::Nil => ArgKey::Nil,
|
||||
Self::Boolean(v) => ArgKey::Boolean(v),
|
||||
Self::Integer(v) => ArgKey::Integer(v),
|
||||
Self::Number(v) => ArgKey::Number(OrderedFloat::new(v)),
|
||||
Self::String(v) => ArgKey::String(v),
|
||||
Self::Table(_) => bail!("table is not supported"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
use std::{any::Any, collections::HashMap, fmt::{self, Display}, mem};
|
||||
use std::{any::Any, collections::HashMap, fmt::{self, Display}};
|
||||
|
||||
use super::Arg;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Cmd {
|
||||
pub name: String,
|
||||
pub args: Vec<String>,
|
||||
pub named: HashMap<String, String>,
|
||||
pub data: Option<Box<dyn Any + Send>>,
|
||||
pub name: String,
|
||||
pub args: HashMap<String, Arg>,
|
||||
pub data: Option<Box<dyn Any + Send>>,
|
||||
}
|
||||
|
||||
impl Cmd {
|
||||
|
|
@ -14,20 +15,22 @@ impl Cmd {
|
|||
|
||||
#[inline]
|
||||
pub fn args(name: &str, args: Vec<String>) -> Self {
|
||||
Self { name: name.to_owned(), args, ..Default::default() }
|
||||
Self {
|
||||
name: name.to_owned(),
|
||||
args: args.into_iter().enumerate().map(|(i, s)| (i.to_string(), Arg::String(s))).collect(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with(mut self, name: impl ToString, value: impl ToString) -> Self {
|
||||
self.named.insert(name.to_string(), value.to_string());
|
||||
self.args.insert(name.to_string(), Arg::String(value.to_string()));
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_bool(mut self, name: impl ToString, state: bool) -> Self {
|
||||
if state {
|
||||
self.named.insert(name.to_string(), Default::default());
|
||||
}
|
||||
self.args.insert(name.to_string(), Arg::Boolean(state));
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -37,40 +40,52 @@ impl Cmd {
|
|||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_str(&self, name: &str) -> Option<&str> { self.args.get(name).and_then(Arg::as_str) }
|
||||
|
||||
#[inline]
|
||||
pub fn get_bool(&self, name: &str) -> bool {
|
||||
self.args.get(name).and_then(Arg::as_bool).unwrap_or(false)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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])) }
|
||||
pub fn take_first_str(&mut self) -> Option<String> {
|
||||
if let Some(Arg::String(s)) = self.args.remove("0") { Some(s) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn take_name(&mut self, name: &str) -> Option<String> { self.named.remove(name) }
|
||||
pub fn take_name_str(&mut self, name: &str) -> Option<String> {
|
||||
if let Some(Arg::String(s)) = self.args.remove(name) { Some(s) } else { None }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clone_without_data(&self) -> Self {
|
||||
Self {
|
||||
name: self.name.clone(),
|
||||
args: self.args.clone(),
|
||||
named: self.named.clone(),
|
||||
data: None,
|
||||
}
|
||||
pub fn shallow_clone(&self) -> Self {
|
||||
let args = self
|
||||
.args
|
||||
.iter()
|
||||
.filter_map(|(k, v)| v.as_str().map(|s| (k.clone(), Arg::String(s.to_owned()))))
|
||||
.collect();
|
||||
|
||||
Self { name: self.name.clone(), args, data: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Cmd {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.name)?;
|
||||
if !self.args.is_empty() {
|
||||
write!(f, " {}", self.args.join(" "))?;
|
||||
}
|
||||
for (k, v) in &self.named {
|
||||
write!(f, " --{k}")?;
|
||||
if !v.is_empty() {
|
||||
write!(f, "={v}")?;
|
||||
for (k, v) in &self.args {
|
||||
if k.as_bytes().first().is_some_and(|b| b.is_ascii_digit()) {
|
||||
if let Some(s) = v.as_str() {
|
||||
write!(f, " {s}")?;
|
||||
}
|
||||
} else if v.as_bool().is_some_and(|b| b) {
|
||||
write!(f, " --{k}")?;
|
||||
} else if let Some(s) = v.as_str() {
|
||||
write!(f, " --{k}={s}")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
#![allow(clippy::module_inception)]
|
||||
|
||||
mod arg;
|
||||
mod cmd;
|
||||
mod event;
|
||||
mod render;
|
||||
|
||||
pub use arg::*;
|
||||
pub use cmd::*;
|
||||
pub use event::*;
|
||||
pub use render::*;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue