From af92b92da81addab089e0f490f79f09a6f63857f Mon Sep 17 00:00:00 2001 From: Nicholas42 Date: Sat, 12 Apr 2025 11:59:23 +0200 Subject: [PATCH] feat: allow custom exit code with `quit --code` (#2609) Co-authored-by: Nicholas Schwab Co-authored-by: sxyazi --- yazi-core/src/mgr/commands/close.rs | 12 +++----- yazi-core/src/mgr/commands/open.rs | 27 ++++------------- yazi-core/src/mgr/commands/quit.rs | 45 ++++++++++++++++++++++++----- yazi-fm/src/app/commands/quit.rs | 2 +- yazi-fm/src/panic.rs | 2 +- yazi-fm/src/term.rs | 4 +-- yazi-shared/src/event/data.rs | 1 + yazi-shared/src/event/event.rs | 1 + 8 files changed, 52 insertions(+), 42 deletions(-) diff --git a/yazi-core/src/mgr/commands/close.rs b/yazi-core/src/mgr/commands/close.rs index a71f9d9f..becfd17a 100644 --- a/yazi-core/src/mgr/commands/close.rs +++ b/yazi-core/src/mgr/commands/close.rs @@ -3,14 +3,10 @@ use yazi_shared::event::CmdCow; use crate::{mgr::{Mgr, commands::quit}, tasks::Tasks}; #[derive(Default)] -struct Opt { - no_cwd_file: bool, -} +struct Opt(quit::Opt); + impl From for Opt { - fn from(c: CmdCow) -> Self { Self { no_cwd_file: c.bool("no-cwd-file") } } -} -impl From for quit::Opt { - fn from(value: Opt) -> Self { Self { no_cwd_file: value.no_cwd_file } } + fn from(c: CmdCow) -> Self { Self(c.into()) } } impl Mgr { @@ -19,6 +15,6 @@ impl Mgr { if self.tabs.len() > 1 { return self.tabs.close(self.tabs.cursor); } - self.quit(opt, tasks); + self.quit(opt.0, tasks); } } diff --git a/yazi-core/src/mgr/commands/open.rs b/yazi-core/src/mgr/commands/open.rs index 232c7fb4..716a0948 100644 --- a/yazi-core/src/mgr/commands/open.rs +++ b/yazi-core/src/mgr/commands/open.rs @@ -1,20 +1,18 @@ -use std::{borrow::Cow, ffi::OsString}; +use std::borrow::Cow; use tracing::error; -use yazi_boot::ARGS; use yazi_config::{YAZI, popup::PickCfg}; use yazi_fs::File; -use yazi_macro::emit; use yazi_plugin::isolate; use yazi_proxy::{MgrProxy, PickProxy, TasksProxy, options::OpenDoOpt}; -use yazi_shared::{MIME_DIR, event::{CmdCow, EventQuit}, url::Url}; +use yazi_shared::{MIME_DIR, event::CmdCow, url::Url}; use crate::{mgr::Mgr, tab::Folder, tasks::Tasks}; #[derive(Clone, Copy)] -struct Opt { - interactive: bool, - hovered: bool, +pub(super) struct Opt { + pub(super) interactive: bool, + pub(super) hovered: bool, } impl From for Opt { @@ -120,19 +118,4 @@ impl Mgr { || find(self.hovered_folder()) || find(self.active().history.get(&p)) } - - fn quit_with_selected(opt: Opt, selected: &[&Url]) -> bool { - if opt.interactive || ARGS.chooser_file.is_none() { - return false; - } - - let paths = selected.iter().fold(OsString::new(), |mut s, &u| { - s.push(u.as_os_str()); - s.push("\n"); - s - }); - - emit!(Quit(EventQuit { selected: Some(paths), ..Default::default() })); - true - } } diff --git a/yazi-core/src/mgr/commands/quit.rs b/yazi-core/src/mgr/commands/quit.rs index 343ed732..52457c78 100644 --- a/yazi-core/src/mgr/commands/quit.rs +++ b/yazi-core/src/mgr/commands/quit.rs @@ -1,25 +1,39 @@ -use std::time::Duration; +use std::{ffi::OsString, time::Duration}; use tokio::{select, time}; +use yazi_boot::ARGS; use yazi_config::popup::ConfirmCfg; use yazi_macro::emit; use yazi_proxy::ConfirmProxy; -use yazi_shared::event::{CmdCow, EventQuit}; +use yazi_shared::{event::{CmdCow, Data, EventQuit}, url::Url}; use crate::{mgr::Mgr, tasks::Tasks}; #[derive(Default)] pub(super) struct Opt { + pub(super) code: i32, pub(super) no_cwd_file: bool, } + impl From for Opt { - fn from(c: CmdCow) -> Self { Self { no_cwd_file: c.bool("no-cwd-file") } } + fn from(c: CmdCow) -> Self { + Self { + code: c.get("code").and_then(Data::as_i32).unwrap_or_default(), + no_cwd_file: c.bool("no-cwd-file"), + } + } +} + +impl From for EventQuit { + fn from(value: Opt) -> Self { + EventQuit { code: value.code, no_cwd_file: value.no_cwd_file, ..Default::default() } + } } impl Mgr { #[yazi_codegen::command] pub fn quit(&self, opt: Opt, tasks: &Tasks) { - let opt = EventQuit { no_cwd_file: opt.no_cwd_file, ..Default::default() }; + let event = opt.into(); let ongoing = tasks.ongoing().clone(); let (left, left_names) = { @@ -28,7 +42,7 @@ impl Mgr { }; if left == 0 { - emit!(Quit(opt)); + emit!(Quit(event)); return; } @@ -41,13 +55,13 @@ impl Mgr { i += 1; if i > 40 { break } else if ongoing.lock().is_empty() { - emit!(Quit(opt)); + emit!(Quit(event)); return; } } b = &mut rx => { if b.unwrap_or(false) { - emit!(Quit(opt)); + emit!(Quit(event)); } return; } @@ -55,8 +69,23 @@ impl Mgr { } if rx.await.unwrap_or(false) { - emit!(Quit(opt)); + emit!(Quit(event)); } }); } + + pub(super) fn quit_with_selected(opt: super::open::Opt, selected: &[&Url]) -> bool { + if opt.interactive || ARGS.chooser_file.is_none() { + return false; + } + + let paths = selected.iter().fold(OsString::new(), |mut s, &u| { + s.push(u.as_os_str()); + s.push("\n"); + s + }); + + emit!(Quit(EventQuit { selected: Some(paths), ..Default::default() })); + true + } } diff --git a/yazi-fm/src/app/commands/quit.rs b/yazi-fm/src/app/commands/quit.rs index 9b725a50..72a9f4ec 100644 --- a/yazi-fm/src/app/commands/quit.rs +++ b/yazi-fm/src/app/commands/quit.rs @@ -19,7 +19,7 @@ impl App { self.selected_to_file(selected); } - Term::goodbye(|| false); + Term::goodbye(|| opt.code); } fn cwd_to_file(&self) { diff --git a/yazi-fm/src/panic.rs b/yazi-fm/src/panic.rs index ca8cedfe..3c832d78 100644 --- a/yazi-fm/src/panic.rs +++ b/yazi-fm/src/panic.rs @@ -10,7 +10,7 @@ impl Panic { std::panic::set_hook(Box::new(move |info| { Term::goodbye(|| { hook(info); - true + 1 }); })); } diff --git a/yazi-fm/src/term.rs b/yazi-fm/src/term.rs index f26a03fc..59bdeea0 100644 --- a/yazi-fm/src/term.rs +++ b/yazi-fm/src/term.rs @@ -89,7 +89,7 @@ impl Term { Ok(disable_raw_mode()?) } - pub(super) fn goodbye(f: impl FnOnce() -> bool) -> ! { + pub(super) fn goodbye(f: impl FnOnce() -> i32) -> ! { if CSI_U.swap(false, Ordering::Relaxed) { PopKeyboardEnhancementFlags.write_ansi(&mut TTY.writer()).ok(); } @@ -111,7 +111,7 @@ impl Term { disable_raw_mode().ok(); - std::process::exit(f() as i32); + std::process::exit(f()); } pub(super) fn draw(&mut self, f: impl FnOnce(&mut Frame)) -> io::Result { diff --git a/yazi-shared/src/event/data.rs b/yazi-shared/src/event/data.rs index fac8cc4a..1eab3f7b 100644 --- a/yazi-shared/src/event/data.rs +++ b/yazi-shared/src/event/data.rs @@ -182,6 +182,7 @@ macro_rules! impl_number_as { impl_integer_as!(usize, as_usize); impl_integer_as!(isize, as_isize); impl_integer_as!(i16, as_i16); +impl_integer_as!(i32, as_i32); impl_number_as!(f64, as_f64); diff --git a/yazi-shared/src/event/event.rs b/yazi-shared/src/event/event.rs index 9bb24f48..b95fc305 100644 --- a/yazi-shared/src/event/event.rs +++ b/yazi-shared/src/event/event.rs @@ -23,6 +23,7 @@ pub enum Event { #[derive(Debug, Default)] pub struct EventQuit { + pub code: i32, pub no_cwd_file: bool, pub selected: Option, }