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;
@ -7,9 +7,7 @@ pub struct Opt {
}
impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
}
fn from(c: Cmd) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
}
impl Completion {

View File

@ -8,7 +8,7 @@ pub struct 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 {

View File

@ -1,6 +1,6 @@
use std::{mem, ops::ControlFlow};
use yazi_shared::{event::Cmd, render};
use yazi_shared::{event::{Cmd, Data}, render};
use crate::completion::Completion;
@ -19,7 +19,7 @@ impl From<Cmd> for Opt {
cache: c.take_any("cache").unwrap_or_default(),
cache_name: c.take_str("cache-name").unwrap_or_default(),
word: c.take_str("word").unwrap_or_default(),
ticket: c.take_str("ticket").and_then(|v| v.parse().ok()).unwrap_or(0),
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 tokio::fs;
use yazi_shared::{emit, event::Cmd, render, Layer};
use yazi_shared::{emit, event::{Cmd, Data}, render, Layer};
use crate::completion::Completion;
@ -20,7 +20,7 @@ impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
Self {
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 {
fn from(c: &Cmd) -> Self {
match (c.get_bool("smart"), c.get_bool("insensitive")) {
match (c.bool("smart"), c.bool("insensitive")) {
(true, _) => Self::Smart,
(_, false) => Self::Sensitive,
(_, 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;
@ -7,9 +7,7 @@ pub struct Opt {
}
impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
Self { step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
}
fn from(c: Cmd) -> Self { Self { step: c.first().and_then(Data::as_isize).unwrap_or(0) } }
}
impl From<isize> for Opt {
fn from(step: isize) -> Self { Self { step } }

View File

@ -7,7 +7,7 @@ pub struct 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 {
fn from(under: bool) -> Self { Self { under } }

View File

@ -8,7 +8,7 @@ pub struct 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 {
fn from(submit: bool) -> Self { Self { submit } }

View File

@ -1,6 +1,6 @@
use std::path::MAIN_SEPARATOR_STR;
use yazi_shared::{event::Cmd, render};
use yazi_shared::{event::{Cmd, Data}, render};
use crate::input::Input;
@ -19,7 +19,7 @@ impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
Self {
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 {
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 {

View File

@ -7,7 +7,7 @@ pub struct 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 {

View File

@ -7,7 +7,7 @@ pub struct 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 {
fn from(append: bool) -> Self { Self { append } }

View File

@ -1,5 +1,5 @@
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};
@ -9,10 +9,10 @@ pub struct Opt {
}
impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
fn from(c: Cmd) -> Self {
Self {
step: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0),
in_operating: c.get_bool("in-operating"),
step: c.first().and_then(Data::as_isize).unwrap_or(0),
in_operating: c.bool("in-operating"),
}
}
}

View File

@ -7,7 +7,7 @@ pub struct 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 {

View File

@ -12,7 +12,7 @@ pub struct 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 {

View File

@ -1,6 +1,6 @@
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;
@ -9,7 +9,7 @@ pub struct 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 {
fn from(url: Option<Url>) -> Self { Self { url } }

View File

@ -8,7 +8,7 @@ pub struct 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 {

View File

@ -17,7 +17,7 @@ pub struct Opt {
impl From<Cmd> for Opt {
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 {
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 {

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;
@ -13,10 +13,10 @@ pub struct Opt {
impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
Self {
skip: c.take_first_str().and_then(|s| s.parse().ok()),
force: c.get_bool("force"),
only_if: c.take_str("only-if").map(Url::from),
upper_bound: c.get_bool("upper-bound"),
skip: c.first().and_then(Data::as_usize),
force: c.bool("force"),
only_if: c.take("only-if").and_then(Data::into_url),
upper_bound: c.bool("upper-bound"),
}
}
}

View File

@ -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.get_bool("no-cwd-file") } }
fn from(c: Cmd) -> Self { Self { no_cwd_file: c.bool("no-cwd-file") } }
}
impl Manager {

View File

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

View File

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

View File

@ -1,6 +1,6 @@
use yazi_config::PLUGIN;
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;
@ -10,9 +10,7 @@ pub struct Opt {
}
impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
Self { units: c.take_first_str().and_then(|s| s.parse().ok()).unwrap_or(0) }
}
fn from(c: Cmd) -> Self { Self { units: c.first().and_then(Data::as_i16).unwrap_or(0) } }
}
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;
@ -7,9 +7,7 @@ pub struct Opt {
}
impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
Self { idx: c.take_first_str().and_then(|i| i.parse().ok()).unwrap_or(0) }
}
fn from(c: Cmd) -> Self { Self { idx: c.first().and_then(Data::as_usize).unwrap_or(0) } }
}
impl From<usize> for Opt {

View File

@ -1,6 +1,6 @@
use yazi_boot::BOOT;
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};
@ -13,11 +13,11 @@ pub struct Opt {
impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
if c.get_bool("current") {
if c.bool("current") {
Self { url: Default::default(), current: true }
} else {
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,
}
}

View File

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

View File

@ -12,7 +12,7 @@ impl TryFrom<Cmd> for Opt {
type 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};
@ -11,8 +11,8 @@ pub struct Opt {
impl From<Cmd> for Opt {
fn from(mut c: Cmd) -> Self {
Self {
page: c.take_first_str().and_then(|s| s.parse().ok()),
only_if: c.take_str("only-if").map(Url::from),
page: c.first().and_then(Data::as_usize),
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 {
fn from(c: Cmd) -> Self { Self { cut: c.get_bool("cut") } }
fn from(c: Cmd) -> Self { Self { cut: c.bool("cut") } }
}
impl Manager {

View File

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

View File

@ -8,7 +8,7 @@ pub struct 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 {
fn from(submit: bool) -> Self { Self { submit } }

View File

@ -1,6 +1,6 @@
use yazi_dds::Pubsub;
use yazi_proxy::ManagerProxy;
use yazi_shared::{event::Cmd, render};
use yazi_shared::{event::{Cmd, Data}, render};
use crate::{tab::Tab, Step};
@ -10,7 +10,13 @@ pub struct Opt {
impl From<Cmd> for Opt {
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_dds::Pubsub;
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;
@ -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_str().unwrap_or_default());
let mut target = c.take_first().and_then(Data::into_url).unwrap_or_default();
if target.is_regular() {
target.set_path(expand_path(&target))
}
Self { target, interactive: c.get_bool("interactive") }
Self { target, interactive: c.bool("interactive") }
}
}
impl From<Url> for Opt {

View File

@ -20,7 +20,7 @@ impl From<Cmd> for Opt {
Self {
query: c.take_first_str().unwrap_or_default(),
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 {
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 {
fn from(c: Cmd) -> Self { Self { prev: c.get_bool("previous") } }
fn from(c: Cmd) -> Self { Self { prev: c.bool("previous") } }
}
impl Tab {

View File

@ -1,5 +1,5 @@
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;
@ -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_str().unwrap_or_default());
let mut target = c.take_first().and_then(Data::into_url).unwrap_or_default();
if target.is_regular() {
target.set_path(expand_path(&target))
}

View File

@ -1,7 +1,7 @@
use std::borrow::Cow;
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;
@ -13,7 +13,7 @@ pub struct Opt<'a> {
impl<'a> From<Cmd> for Opt<'a> {
fn from(mut c: Cmd) -> 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() {
Some("true") => Some(true),
Some("false") => Some(false),

View File

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

View File

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

View File

@ -9,7 +9,7 @@ pub struct 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 {

View File

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

View File

@ -1,6 +1,6 @@
use tokio::sync::mpsc;
use tracing::error;
use yazi_shared::event::Cmd;
use yazi_shared::event::{Cmd, Data};
use crate::which::Which;
@ -15,7 +15,7 @@ impl TryFrom<Cmd> for Opt {
fn try_from(mut c: Cmd) -> Result<Self, Self::Error> {
Ok(Self {
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 {
cands: c.take_any("candidates").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) {
let (kind, peers) = (body.kind(), PEERS.read());
if peers.values().any(|c| c.able(kind)) {
let kind = body.kind();
if REMOTE.read().contains_key(kind) || PEERS.read().values().any(|c| c.able(kind)) {
Client::push(body.with_severity(severity));
}
}

View File

@ -55,8 +55,8 @@ impl Server {
let clients = CLIENTS.read();
let clients: Vec<_> = if receiver == 0 {
clients.values().filter(|c| c.id != id && c.able(kind)).collect()
} else if let Some(c) = clients.get(&receiver).filter(|c| c.id != id && c.able(kind)) {
clients.values().filter(|c| c.able(kind)).collect()
} else if let Some(c) = clients.get(&receiver).filter(|c| c.able(kind)) {
vec![c]
} else {
vec![]
@ -72,7 +72,7 @@ impl Server {
}
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
}

View File

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

View File

@ -20,13 +20,13 @@ impl TryFrom<Cmd> for Opt {
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()
} else {
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]
pub fn with(mut self, name: impl ToString, value: impl ToString) -> Self {
self.args.insert(name.to_string(), Data::String(value.to_string()));
@ -44,22 +45,33 @@ impl Cmd {
self
}
// --- Get
#[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]
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)
}
#[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]
pub fn take_str(&mut self, name: &str) -> Option<String> {
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]
pub fn take_first_str(&mut self) -> Option<String> {
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())
}
// --- Clone
pub fn shallow_clone(&self) -> Self {
Self {
name: self.name.clone(),

View File

@ -14,7 +14,7 @@ pub enum Data {
Number(f64),
String(String),
Table(HashMap<DataKey, Data>),
#[serde(skip)]
#[serde(skip_deserializing)]
Url(Url),
#[serde(skip)]
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> {
let Self::Table(table) = self else {
return Default::default();
@ -86,7 +95,7 @@ pub enum DataKey {
Integer(i64),
Number(OrderedFloat),
String(String),
#[serde(skip)]
#[serde(skip_deserializing)]
Url(Url),
}
@ -94,3 +103,40 @@ impl DataKey {
#[inline]
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);