diff --git a/yazi-core/src/tab/commands/shell.rs b/yazi-core/src/tab/commands/shell.rs index 05c1154a..370cf879 100644 --- a/yazi-core/src/tab/commands/shell.rs +++ b/yazi-core/src/tab/commands/shell.rs @@ -1,8 +1,9 @@ -use std::borrow::Cow; +use std::{borrow::Cow, fmt::Display}; +use anyhow::bail; use yazi_config::{open::Opener, popup::InputCfg}; use yazi_proxy::{AppProxy, InputProxy, TasksProxy}; -use yazi_shared::event::Cmd; +use yazi_shared::event::{Cmd, Data}; use crate::tab::Tab; @@ -12,27 +13,40 @@ pub struct Opt { orphan: bool, confirm: bool, interactive: bool, + cursor: Option, } -impl From for Opt { - fn from(mut c: Cmd) -> Self { - Self { +impl TryFrom for Opt { + type Error = anyhow::Error; + + fn try_from(mut c: Cmd) -> Result { + let me = Self { run: c.take_first_str().unwrap_or_default(), block: c.bool("block"), orphan: c.bool("orphan"), confirm: c.bool("confirm"), interactive: c.bool("interactive"), + cursor: c.get("cursor").and_then(Data::as_usize), + }; + + if me.cursor.is_some_and(|c| c > me.run.chars().count()) { + bail!("The cursor position is out of bounds."); } + + Ok(me) } } impl Tab { - pub fn shell(&mut self, opt: impl Into) { + pub fn shell(&mut self, opt: impl TryInto) { if !self.try_escape_visual() { return; } - let mut opt = opt.into() as Opt; + let mut opt = match opt.try_into() { + Ok(o) => o as Opt, + Err(e) => return AppProxy::notify_warn("`shell` command", e), + }; // TODO: Remove in v0.3.2 if !opt.interactive && !opt.confirm { @@ -52,10 +66,10 @@ Please replace e.g. `shell` with `shell --interactive`, `shell "my-template"` wi } let selected = self.hovered_and_selected(true).cloned().collect(); - tokio::spawn(async move { if !opt.confirm || opt.run.is_empty() { - let mut result = InputProxy::show(InputCfg::shell(opt.block).with_value(opt.run)); + let mut result = + InputProxy::show(InputCfg::shell(opt.block).with_value(opt.run).with_cursor(opt.cursor)); match result.recv().await { Some(Ok(e)) => opt.run = e, _ => return, diff --git a/yazi-proxy/src/app.rs b/yazi-proxy/src/app.rs index fcdcb470..4763a36f 100644 --- a/yazi-proxy/src/app.rs +++ b/yazi-proxy/src/app.rs @@ -26,11 +26,11 @@ impl AppProxy { } #[inline] - pub fn notify_warn(title: &str, content: &str) { + pub fn notify_warn(title: &str, content: impl ToString) { emit!(Call( Cmd::new("notify").with_any("option", NotifyOpt { title: title.to_owned(), - content: content.to_owned(), + content: content.to_string(), level: NotifyLevel::Warn, timeout: Duration::from_secs(5), }), @@ -39,11 +39,11 @@ impl AppProxy { } #[inline] - pub fn notify_error(title: &str, content: &str) { + pub fn notify_error(title: &str, content: impl ToString) { emit!(Call( Cmd::new("notify").with_any("option", NotifyOpt { title: title.to_owned(), - content: content.to_owned(), + content: content.to_string(), level: NotifyLevel::Error, timeout: Duration::from_secs(10), }),