fix: always persist static messages even when there are no remote clients (#928)

This commit is contained in:
三咲雅 · Misaki Masa 2024-04-19 16:26:02 +08:00 committed by sxyazi
parent 09bc9aa371
commit ff14b9a265
No known key found for this signature in database
52 changed files with 162 additions and 114 deletions

View file

@ -1,4 +1,4 @@
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::completion::Completion; use crate::completion::Completion;
@ -7,9 +7,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(c: Cmd) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
}
} }
impl Completion { impl Completion {

View file

@ -8,7 +8,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { submit: c.get_bool("submit") } } fn from(c: Cmd) -> Self { Self { submit: c.bool("submit") } }
} }
impl Completion { impl Completion {

View file

@ -1,6 +1,6 @@
use std::{mem, ops::ControlFlow}; use std::{mem, ops::ControlFlow};
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::completion::Completion; use crate::completion::Completion;
@ -19,7 +19,7 @@ impl From<Cmd> for Opt {
cache: c.take_any("cache").unwrap_or_default(), cache: c.take_any("cache").unwrap_or_default(),
cache_name: c.take_str("cache-name").unwrap_or_default(), cache_name: c.take_str("cache-name").unwrap_or_default(),
word: c.take_str("word").unwrap_or_default(), word: c.take_str("word").unwrap_or_default(),
ticket: c.take_str("ticket").and_then(|v| v.parse().ok()).unwrap_or(0), ticket: c.get("ticket").and_then(Data::as_usize).unwrap_or(0),
} }
} }
} }

View file

@ -1,7 +1,7 @@
use std::{mem, path::{MAIN_SEPARATOR, MAIN_SEPARATOR_STR}}; use std::{mem, path::{MAIN_SEPARATOR, MAIN_SEPARATOR_STR}};
use tokio::fs; use tokio::fs;
use yazi_shared::{emit, event::Cmd, render, Layer}; use yazi_shared::{emit, event::{Cmd, Data}, render, Layer};
use crate::completion::Completion; use crate::completion::Completion;
@ -20,7 +20,7 @@ impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
Self { Self {
word: c.take_first_str().unwrap_or_default(), word: c.take_first_str().unwrap_or_default(),
ticket: c.take_str("ticket").and_then(|s| s.parse().ok()).unwrap_or(0), ticket: c.get("ticket").and_then(Data::as_usize).unwrap_or(0),
} }
} }
} }

View file

@ -45,7 +45,7 @@ pub enum FilterCase {
impl From<&Cmd> for FilterCase { impl From<&Cmd> for FilterCase {
fn from(c: &Cmd) -> Self { fn from(c: &Cmd) -> Self {
match (c.get_bool("smart"), c.get_bool("insensitive")) { match (c.bool("smart"), c.bool("insensitive")) {
(true, _) => Self::Smart, (true, _) => Self::Smart,
(_, false) => Self::Sensitive, (_, false) => Self::Sensitive,
(_, true) => Self::Insensitive, (_, true) => Self::Insensitive,

View file

@ -1,4 +1,4 @@
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::help::Help; use crate::help::Help;
@ -7,9 +7,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(c: Cmd) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
}
} }
impl From<isize> for Opt { impl From<isize> for Opt {
fn from(step: isize) -> Self { Self { step } } fn from(step: isize) -> Self { Self { step } }

View file

@ -7,7 +7,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { under: c.get_bool("under") } } fn from(c: Cmd) -> Self { Self { under: c.bool("under") } }
} }
impl From<bool> for Opt { impl From<bool> for Opt {
fn from(under: bool) -> Self { Self { under } } fn from(under: bool) -> Self { Self { under } }

View file

@ -8,7 +8,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { submit: c.get_bool("submit") } } fn from(c: Cmd) -> Self { Self { submit: c.bool("submit") } }
} }
impl From<bool> for Opt { impl From<bool> for Opt {
fn from(submit: bool) -> Self { Self { submit } } fn from(submit: bool) -> Self { Self { submit } }

View file

@ -1,6 +1,6 @@
use std::path::MAIN_SEPARATOR_STR; use std::path::MAIN_SEPARATOR_STR;
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::input::Input; use crate::input::Input;
@ -19,7 +19,7 @@ impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
Self { Self {
word: c.take_first_str().unwrap_or_default(), word: c.take_first_str().unwrap_or_default(),
ticket: c.take_str("ticket").and_then(|s| s.parse().ok()).unwrap_or(0), ticket: c.get("ticket").and_then(Data::as_usize).unwrap_or(0),
} }
} }
} }

View file

@ -8,7 +8,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { cut: c.get_bool("cut"), insert: c.get_bool("insert") } } fn from(c: Cmd) -> Self { Self { cut: c.bool("cut"), insert: c.bool("insert") } }
} }
impl Input { impl Input {

View file

@ -7,7 +7,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { end_of_word: c.get_bool("end-of-word") } } fn from(c: Cmd) -> Self { Self { end_of_word: c.bool("end-of-word") } }
} }
impl Input { impl Input {

View file

@ -7,7 +7,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { append: c.get_bool("append") } } fn from(c: Cmd) -> Self { Self { append: c.bool("append") } }
} }
impl From<bool> for Opt { impl From<bool> for Opt {
fn from(append: bool) -> Self { Self { append } } fn from(append: bool) -> Self { Self { append } }

View file

@ -1,5 +1,5 @@
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::input::{op::InputOp, snap::InputSnap, Input}; use crate::input::{op::InputOp, snap::InputSnap, Input};
@ -9,10 +9,10 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(c: Cmd) -> Self {
Self { Self {
step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0), step: c.first().and_then(Data::as_isize).unwrap_or(0),
in_operating: c.get_bool("in-operating"), in_operating: c.bool("in-operating"),
} }
} }
} }

View file

@ -7,7 +7,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { before: c.get_bool("before") } } fn from(c: Cmd) -> Self { Self { before: c.bool("before") } }
} }
impl Input { impl Input {

View file

@ -12,7 +12,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { force: c.get_bool("force") } } fn from(c: Cmd) -> Self { Self { force: c.bool("force") } }
} }
impl Manager { impl Manager {

View file

@ -1,6 +1,6 @@
use std::collections::HashSet; use std::collections::HashSet;
use yazi_shared::{event::Cmd, fs::Url, render}; use yazi_shared::{event::{Cmd, Data}, fs::Url, render};
use crate::manager::Manager; use crate::manager::Manager;
@ -9,7 +9,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { Self { url: c.take_first_str().map(Url::from) } } fn from(mut c: Cmd) -> Self { Self { url: c.take_first().and_then(Data::into_url) } }
} }
impl From<Option<Url>> for Opt { impl From<Option<Url>> for Opt {
fn from(url: Option<Url>) -> Self { Self { url } } fn from(url: Option<Url>) -> Self { Self { url } }

View file

@ -8,7 +8,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { relative: c.get_bool("relative"), force: c.get_bool("force") } } fn from(c: Cmd) -> Self { Self { relative: c.bool("relative"), force: c.bool("force") } }
} }
impl Manager { impl Manager {

View file

@ -17,7 +17,7 @@ pub struct Opt {
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { fn from(c: Cmd) -> Self {
Self { interactive: c.get_bool("interactive"), hovered: c.get_bool("hovered") } Self { interactive: c.bool("interactive"), hovered: c.bool("hovered") }
} }
} }

View file

@ -8,7 +8,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { force: c.get_bool("force"), follow: c.get_bool("follow") } } fn from(c: Cmd) -> Self { Self { force: c.bool("force"), follow: c.bool("follow") } }
} }
impl Manager { impl Manager {

View file

@ -1,4 +1,4 @@
use yazi_shared::{event::Cmd, fs::Url, render}; use yazi_shared::{event::{Cmd, Data}, fs::Url, render};
use crate::manager::Manager; use crate::manager::Manager;
@ -13,10 +13,10 @@ pub struct Opt {
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
Self { Self {
skip: c.take_first_str().and_then(|s| s.parse().ok()), skip: c.first().and_then(Data::as_usize),
force: c.get_bool("force"), force: c.bool("force"),
only_if: c.take_str("only-if").map(Url::from), only_if: c.take("only-if").and_then(Data::into_url),
upper_bound: c.get_bool("upper-bound"), upper_bound: c.bool("upper-bound"),
} }
} }
} }

View file

@ -12,7 +12,7 @@ impl From<()> for Opt {
fn from(_: ()) -> Self { Self::default() } fn from(_: ()) -> Self { Self::default() }
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { no_cwd_file: c.get_bool("no-cwd-file") } } fn from(c: Cmd) -> Self { Self { no_cwd_file: c.bool("no-cwd-file") } }
} }
impl Manager { impl Manager {

View file

@ -13,8 +13,8 @@ pub struct Opt {
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
Self { Self {
force: c.get_bool("force"), force: c.bool("force"),
permanently: c.get_bool("permanently"), permanently: c.bool("permanently"),
targets: c.take_any("targets").unwrap_or_default(), targets: c.take_any("targets").unwrap_or_default(),
} }
} }

View file

@ -18,7 +18,7 @@ pub struct Opt {
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
Self { Self {
force: c.get_bool("force"), force: c.bool("force"),
empty: c.take_str("empty").unwrap_or_default(), empty: c.take_str("empty").unwrap_or_default(),
cursor: c.take_str("cursor").unwrap_or_default(), cursor: c.take_str("cursor").unwrap_or_default(),
} }

View file

@ -1,6 +1,6 @@
use yazi_config::PLUGIN; use yazi_config::PLUGIN;
use yazi_plugin::isolate; use yazi_plugin::isolate;
use yazi_shared::{event::Cmd, render, MIME_DIR}; use yazi_shared::{event::{Cmd, Data}, render, MIME_DIR};
use crate::manager::Manager; use crate::manager::Manager;
@ -10,9 +10,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(c: Cmd) -> Self { Self { units: c.first().and_then(Data::as_i16).unwrap_or(0) } }
Self { units: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
}
} }
impl Manager { impl Manager {

View file

@ -1,4 +1,4 @@
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::manager::Tabs; use crate::manager::Tabs;
@ -7,9 +7,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(c: Cmd) -> Self { Self { idx: c.first().and_then(Data::as_usize).unwrap_or(0) } }
Self { idx: c.take_first_str().and_then(|i| i.parse().ok()).unwrap_or(0) }
}
} }
impl From<usize> for Opt { impl From<usize> for Opt {

View file

@ -1,6 +1,6 @@
use yazi_boot::BOOT; use yazi_boot::BOOT;
use yazi_proxy::AppProxy; use yazi_proxy::AppProxy;
use yazi_shared::{event::Cmd, fs::Url, render}; use yazi_shared::{event::{Cmd, Data}, fs::Url, render};
use crate::{manager::Tabs, tab::Tab}; use crate::{manager::Tabs, tab::Tab};
@ -13,11 +13,11 @@ pub struct Opt {
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
if c.get_bool("current") { if c.bool("current") {
Self { url: Default::default(), current: true } Self { url: Default::default(), current: true }
} else { } else {
Self { Self {
url: c.take_first_str().map_or_else(|| Url::from(&BOOT.cwd), Url::from), url: c.take_first().and_then(Data::into_url).unwrap_or_else(|| Url::from(&BOOT.cwd)),
current: false, current: false,
} }
} }

View file

@ -1,4 +1,4 @@
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::manager::Tabs; use crate::manager::Tabs;
@ -7,9 +7,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(c: Cmd) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
}
} }
impl Tabs { impl Tabs {

View file

@ -1,4 +1,4 @@
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::manager::Tabs; use crate::manager::Tabs;
@ -8,11 +8,8 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(c: Cmd) -> Self {
Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0), relative: c.bool("relative") }
step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0),
relative: c.get_bool("relative"),
}
} }
} }

View file

@ -12,7 +12,7 @@ impl TryFrom<Cmd> for Opt {
type Error = (); type Error = ();
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { fn try_from(mut c: Cmd) -> Result<Self, Self::Error> {
Ok(Self { updates: c.take_data("updates").ok_or(())?.into_table_string() }) Ok(Self { updates: c.take("updates").ok_or(())?.into_table_string() })
} }
} }

View file

@ -1,4 +1,4 @@
use yazi_shared::{event::Cmd, fs::Url}; use yazi_shared::{event::{Cmd, Data}, fs::Url};
use crate::{manager::Manager, tasks::Tasks}; use crate::{manager::Manager, tasks::Tasks};
@ -11,8 +11,8 @@ pub struct Opt {
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
Self { Self {
page: c.take_first_str().and_then(|s| s.parse().ok()), page: c.first().and_then(Data::as_usize),
only_if: c.take_str("only-if").map(Url::from), only_if: c.take("only-if").and_then(Data::into_url),
} }
} }
} }

View file

@ -8,7 +8,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { cut: c.get_bool("cut") } } fn from(c: Cmd) -> Self { Self { cut: c.bool("cut") } }
} }
impl Manager { impl Manager {

View file

@ -1,7 +1,7 @@
use std::time::Duration; use std::time::Duration;
use ratatui::layout::Rect; use ratatui::layout::Rect;
use yazi_shared::{emit, event::Cmd, Layer}; use yazi_shared::{emit, event::{Cmd, Data}, Layer};
use crate::notify::Notify; use crate::notify::Notify;
@ -12,8 +12,8 @@ pub struct Opt {
impl TryFrom<Cmd> for Opt { impl TryFrom<Cmd> for Opt {
type Error = (); type Error = ();
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { fn try_from(c: Cmd) -> Result<Self, Self::Error> {
let interval = c.take_first_str().and_then(|s| s.parse::<f64>().ok()).ok_or(())?; let interval = c.first().and_then(Data::as_f64).ok_or(())?;
if interval < 0.0 { if interval < 0.0 {
return Err(()); return Err(());
} }

View file

@ -1,4 +1,4 @@
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::select::Select; use crate::select::Select;
@ -7,9 +7,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(c: Cmd) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
}
} }
impl Select { impl Select {

View file

@ -8,7 +8,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { submit: c.get_bool("submit") } } fn from(c: Cmd) -> Self { Self { submit: c.bool("submit") } }
} }
impl From<bool> for Opt { impl From<bool> for Opt {
fn from(submit: bool) -> Self { Self { submit } } fn from(submit: bool) -> Self { Self { submit } }

View file

@ -1,6 +1,6 @@
use yazi_dds::Pubsub; use yazi_dds::Pubsub;
use yazi_proxy::ManagerProxy; use yazi_proxy::ManagerProxy;
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::{tab::Tab, Step}; use crate::{tab::Tab, Step};
@ -10,7 +10,13 @@ pub struct Opt {
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or_default() } let step = match c.take_first() {
Some(Data::Integer(i)) => Step::from(i as isize),
Some(Data::String(s)) => s.parse().unwrap_or_default(),
_ => Step::default(),
};
Self { step }
} }
} }

View file

@ -5,7 +5,7 @@ use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt};
use yazi_config::popup::InputCfg; use yazi_config::popup::InputCfg;
use yazi_dds::Pubsub; use yazi_dds::Pubsub;
use yazi_proxy::{CompletionProxy, InputProxy, ManagerProxy, TabProxy}; use yazi_proxy::{CompletionProxy, InputProxy, ManagerProxy, TabProxy};
use yazi_shared::{event::Cmd, fs::{expand_path, Url}, render, Debounce, InputError}; use yazi_shared::{event::{Cmd, Data}, fs::{expand_path, Url}, render, Debounce, InputError};
use crate::tab::Tab; use crate::tab::Tab;
@ -16,12 +16,12 @@ pub struct Opt {
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
let mut target = Url::from(c.take_first_str().unwrap_or_default()); let mut target = c.take_first().and_then(Data::into_url).unwrap_or_default();
if target.is_regular() { if target.is_regular() {
target.set_path(expand_path(&target)) target.set_path(expand_path(&target))
} }
Self { target, interactive: c.get_bool("interactive") } Self { target, interactive: c.bool("interactive") }
} }
} }
impl From<Url> for Opt { impl From<Url> for Opt {

View file

@ -20,7 +20,7 @@ impl From<Cmd> for Opt {
Self { Self {
query: c.take_first_str().unwrap_or_default(), query: c.take_first_str().unwrap_or_default(),
case: FilterCase::from(&c), case: FilterCase::from(&c),
done: c.get_bool("done"), done: c.bool("done"),
} }
} }
} }

View file

@ -16,7 +16,7 @@ pub struct Opt {
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
Self { query: c.take_first_str(), prev: c.get_bool("previous"), case: FilterCase::from(&c) } Self { query: c.take_first_str(), prev: c.bool("previous"), case: FilterCase::from(&c) }
} }
} }
@ -25,7 +25,7 @@ pub struct ArrowOpt {
} }
impl From<Cmd> for ArrowOpt { impl From<Cmd> for ArrowOpt {
fn from(c: Cmd) -> Self { Self { prev: c.get_bool("previous") } } fn from(c: Cmd) -> Self { Self { prev: c.bool("previous") } }
} }
impl Tab { impl Tab {

View file

@ -1,5 +1,5 @@
use yazi_proxy::ManagerProxy; use yazi_proxy::ManagerProxy;
use yazi_shared::{event::Cmd, fs::{expand_path, File, FilesOp, Url}}; use yazi_shared::{event::{Cmd, Data}, fs::{expand_path, File, FilesOp, Url}};
use crate::tab::Tab; use crate::tab::Tab;
@ -9,7 +9,7 @@ pub struct Opt {
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
let mut target = Url::from(c.take_first_str().unwrap_or_default()); let mut target = c.take_first().and_then(Data::into_url).unwrap_or_default();
if target.is_regular() { if target.is_regular() {
target.set_path(expand_path(&target)) target.set_path(expand_path(&target))
} }

View file

@ -1,7 +1,7 @@
use std::borrow::Cow; use std::borrow::Cow;
use yazi_proxy::AppProxy; use yazi_proxy::AppProxy;
use yazi_shared::{event::Cmd, fs::Url, render, render_and}; use yazi_shared::{event::{Cmd, Data}, fs::Url, render, render_and};
use crate::tab::Tab; use crate::tab::Tab;
@ -13,7 +13,7 @@ pub struct Opt<'a> {
impl<'a> From<Cmd> for Opt<'a> { impl<'a> From<Cmd> for Opt<'a> {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
Self { Self {
url: c.take_str("url").map(|s| Cow::Owned(Url::from(s))), url: c.take("url").and_then(Data::into_url).map(Cow::Owned),
state: match c.take_str("state").as_deref() { state: match c.take_str("state").as_deref() {
Some("true") => Some(true), Some("true") => Some(true),
Some("false") => Some(false), Some("false") => Some(false),

View file

@ -17,9 +17,9 @@ impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(mut c: Cmd) -> Self {
Self { Self {
run: c.take_first_str().unwrap_or_default(), run: c.take_first_str().unwrap_or_default(),
block: c.get_bool("block"), block: c.bool("block"),
orphan: c.get_bool("orphan"), orphan: c.bool("orphan"),
confirm: c.get_bool("confirm"), confirm: c.bool("confirm"),
} }
} }
} }

View file

@ -11,9 +11,9 @@ impl Tab {
if let Some(by) = c.take_first_str() { if let Some(by) = c.take_first_str() {
self.conf.sort_by = SortBy::from_str(&by).unwrap_or_default(); self.conf.sort_by = SortBy::from_str(&by).unwrap_or_default();
} }
self.conf.sort_sensitive = c.get_bool("sensitive"); self.conf.sort_sensitive = c.bool("sensitive");
self.conf.sort_reverse = c.get_bool("reverse"); self.conf.sort_reverse = c.bool("reverse");
self.conf.sort_dir_first = c.get_bool("dir-first"); self.conf.sort_dir_first = c.bool("dir-first");
self.apply_files_attrs(); self.apply_files_attrs();
ManagerProxy::update_paged(); ManagerProxy::update_paged();

View file

@ -9,7 +9,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { unset: c.get_bool("unset") } } fn from(c: Cmd) -> Self { Self { unset: c.bool("unset") } }
} }
impl Tab { impl Tab {

View file

@ -1,4 +1,4 @@
use yazi_shared::{event::Cmd, render}; use yazi_shared::{event::{Cmd, Data}, render};
use crate::tasks::Tasks; use crate::tasks::Tasks;
@ -7,9 +7,7 @@ pub struct Opt {
} }
impl From<Cmd> for Opt { impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self { fn from(c: Cmd) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
}
} }
impl From<isize> for Opt { impl From<isize> for Opt {

View file

@ -1,6 +1,6 @@
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tracing::error; use tracing::error;
use yazi_shared::event::Cmd; use yazi_shared::event::{Cmd, Data};
use crate::which::Which; use crate::which::Which;
@ -15,7 +15,7 @@ impl TryFrom<Cmd> for Opt {
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> { fn try_from(mut c: Cmd) -> Result<Self, Self::Error> {
Ok(Self { Ok(Self {
tx: c.take_any("tx").ok_or(())?, tx: c.take_any("tx").ok_or(())?,
idx: c.take_first_str().and_then(|s| s.parse().ok()).ok_or(())?, idx: c.first().and_then(Data::as_usize).ok_or(())?,
}) })
} }
} }

View file

@ -18,7 +18,7 @@ impl TryFrom<Cmd> for Opt {
Ok(Self { Ok(Self {
cands: c.take_any("candidates").unwrap_or_default(), cands: c.take_any("candidates").unwrap_or_default(),
layer: Layer::from_str(&c.take_str("layer").unwrap_or_default())?, layer: Layer::from_str(&c.take_str("layer").unwrap_or_default())?,
silent: c.get_bool("silent"), silent: c.bool("silent"),
}) })
} }
} }

View file

@ -81,8 +81,8 @@ impl Pubsub {
} }
pub fn pub_static(severity: u16, body: Body) { pub fn pub_static(severity: u16, body: Body) {
let (kind, peers) = (body.kind(), PEERS.read()); let kind = body.kind();
if peers.values().any(|c| c.able(kind)) { if REMOTE.read().contains_key(kind) || PEERS.read().values().any(|c| c.able(kind)) {
Client::push(body.with_severity(severity)); Client::push(body.with_severity(severity));
} }
} }

View file

@ -55,8 +55,8 @@ impl Server {
let clients = CLIENTS.read(); let clients = CLIENTS.read();
let clients: Vec<_> = if receiver == 0 { let clients: Vec<_> = if receiver == 0 {
clients.values().filter(|c| c.id != id && c.able(kind)).collect() clients.values().filter(|c| c.able(kind)).collect()
} else if let Some(c) = clients.get(&receiver).filter(|c| c.id != id && c.able(kind)) { } else if let Some(c) = clients.get(&receiver).filter(|c| c.able(kind)) {
vec![c] vec![c]
} else { } else {
vec![] vec![]
@ -72,7 +72,7 @@ impl Server {
} }
line.push('\n'); line.push('\n');
clients.into_iter().for_each(|c| _ = c.tx.send(line.clone())); clients.into_iter().filter(|c| c.id != id).for_each(|c| _ = c.tx.send(line.clone()));
} }
else => break else => break
} }

View file

@ -214,7 +214,7 @@ impl<'a> Executor<'a> {
on!(forward); on!(forward);
if cmd.name.as_str() == "complete" { if cmd.name.as_str() == "complete" {
return if cmd.get_bool("trigger") { return if cmd.bool("trigger") {
self.app.cx.completion.trigger(cmd) self.app.cx.completion.trigger(cmd)
} else { } else {
self.app.cx.input.complete(cmd) self.app.cx.input.complete(cmd)

View file

@ -20,13 +20,13 @@ impl TryFrom<Cmd> for Opt {
bail!("plugin name cannot be empty"); bail!("plugin name cannot be empty");
}; };
let args = if let Some(s) = c.get_str("args") { let args = if let Some(s) = c.str("args") {
shell_words::split(s)?.into_iter().map(Data::String).collect() shell_words::split(s)?.into_iter().map(Data::String).collect()
} else { } else {
c.take_any::<Vec<Data>>("args").unwrap_or_default() c.take_any::<Vec<Data>>("args").unwrap_or_default()
}; };
Ok(Self { name, sync: c.get_bool("sync"), args, cb: c.take_any("callback") }) Ok(Self { name, sync: c.bool("sync"), args, cb: c.take_any("callback") })
} }
} }

View file

@ -20,6 +20,7 @@ impl Cmd {
} }
} }
// --- With
#[inline] #[inline]
pub fn with(mut self, name: impl ToString, value: impl ToString) -> Self { pub fn with(mut self, name: impl ToString, value: impl ToString) -> Self {
self.args.insert(name.to_string(), Data::String(value.to_string())); self.args.insert(name.to_string(), Data::String(value.to_string()));
@ -44,22 +45,33 @@ impl Cmd {
self self
} }
// --- Get
#[inline] #[inline]
pub fn get_str(&self, name: &str) -> Option<&str> { self.args.get(name).and_then(Data::as_str) } pub fn get(&self, name: &str) -> Option<&Data> { self.args.get(name) }
#[inline] #[inline]
pub fn get_bool(&self, name: &str) -> bool { pub fn str(&self, name: &str) -> Option<&str> { self.args.get(name).and_then(Data::as_str) }
#[inline]
pub fn bool(&self, name: &str) -> bool {
self.args.get(name).and_then(Data::as_bool).unwrap_or(false) self.args.get(name).and_then(Data::as_bool).unwrap_or(false)
} }
#[inline] #[inline]
pub fn take_data(&mut self, name: &str) -> Option<Data> { self.args.remove(name) } pub fn first(&self) -> Option<&Data> { self.args.get("0") }
// --- Take
#[inline]
pub fn take(&mut self, name: &str) -> Option<Data> { self.args.remove(name) }
#[inline] #[inline]
pub fn take_str(&mut self, name: &str) -> Option<String> { pub fn take_str(&mut self, name: &str) -> Option<String> {
if let Some(Data::String(s)) = self.args.remove(name) { Some(s) } else { None } if let Some(Data::String(s)) = self.args.remove(name) { Some(s) } else { None }
} }
#[inline]
pub fn take_first(&mut self) -> Option<Data> { self.args.remove("0") }
#[inline] #[inline]
pub fn take_first_str(&mut self) -> Option<String> { pub fn take_first_str(&mut self) -> Option<String> {
if let Some(Data::String(s)) = self.args.remove("0") { Some(s) } else { None } if let Some(Data::String(s)) = self.args.remove("0") { Some(s) } else { None }
@ -70,6 +82,7 @@ impl Cmd {
self.args.remove(name).and_then(|d| d.into_any()) self.args.remove(name).and_then(|d| d.into_any())
} }
// --- Clone
pub fn shallow_clone(&self) -> Self { pub fn shallow_clone(&self) -> Self {
Self { Self {
name: self.name.clone(), name: self.name.clone(),

View file

@ -14,7 +14,7 @@ pub enum Data {
Number(f64), Number(f64),
String(String), String(String),
Table(HashMap<DataKey, Data>), Table(HashMap<DataKey, Data>),
#[serde(skip)] #[serde(skip_deserializing)]
Url(Url), Url(Url),
#[serde(skip)] #[serde(skip)]
Any(Box<dyn Any + Send>), Any(Box<dyn Any + Send>),
@ -53,6 +53,15 @@ impl Data {
} }
} }
#[inline]
pub fn into_url(self) -> Option<Url> {
match self {
Data::String(s) => Some(Url::from(s)),
Data::Url(u) => Some(u),
_ => None,
}
}
pub fn into_table_string(self) -> HashMap<String, String> { pub fn into_table_string(self) -> HashMap<String, String> {
let Self::Table(table) = self else { let Self::Table(table) = self else {
return Default::default(); return Default::default();
@ -86,7 +95,7 @@ pub enum DataKey {
Integer(i64), Integer(i64),
Number(OrderedFloat), Number(OrderedFloat),
String(String), String(String),
#[serde(skip)] #[serde(skip_deserializing)]
Url(Url), Url(Url),
} }
@ -94,3 +103,40 @@ impl DataKey {
#[inline] #[inline]
pub fn is_numeric(&self) -> bool { matches!(self, Self::Integer(_) | Self::Number(_)) } pub fn is_numeric(&self) -> bool { matches!(self, Self::Integer(_) | Self::Number(_)) }
} }
// --- Macros
macro_rules! impl_integer_as {
($t:ty, $name:ident) => {
impl Data {
#[inline]
pub fn $name(&self) -> Option<$t> {
match self {
Data::Integer(i) => <$t>::try_from(*i).ok(),
Data::String(s) => s.parse().ok(),
_ => None,
}
}
}
};
}
macro_rules! impl_number_as {
($t:ty, $name:ident) => {
impl Data {
#[inline]
pub fn $name(&self) -> Option<$t> {
match self {
Data::Number(n) => <$t>::try_from(*n).ok(),
Data::String(s) => s.parse().ok(),
_ => None,
}
}
}
};
}
impl_integer_as!(usize, as_usize);
impl_integer_as!(isize, as_isize);
impl_integer_as!(i16, as_i16);
impl_number_as!(f64, as_f64);