on master help sign in
helix-term/commands: implement cquit (#1096)

This allows you to exit helix with an exit code, e.g. `:cq 2`.

commit87e61a0894d6af1838c5d288fae83279004026fb authorCole Helbling <cole.e.helbling@outlook.com> dateSun 14 Nov 2021, 20:06 (5 years ago) parentf5e070e
4 files changed+40−5
helix-term/src/application.rs+2−2 helix-term/src/commands.rs+26 helix-term/src/main.rs+9−3 helix-view/src/editor.rs+3
helix-term/src/application.rs+2−2
@@ -599,7 +599,7 @@ impl Application {
599599 Ok(())
600600 }
601601
602− pub async fn run(&mut self) -> Result<(), Error> {
602+ pub async fn run(&mut self) -> Result<i32, Error> {
603603 self.claim_term().await?;
604604
605605 // Exit the alternate screen and disable raw mode before panicking
@@ -622,6 +622,6 @@ impl Application {
622622
623623 self.restore_term()?;
624624
625− Ok(())
625+ Ok(self.editor.exit_code)
626626 }
627627}
helix-term/src/commands.rs+26
@@ -2042,6 +2042,25 @@ mod cmd {
20422042 quit_all_impl(&mut cx.editor, args, event, true)
20432043 }
20442044
2045+ fn cquit(
2046+ cx: &mut compositor::Context,
2047+ args: &[&str],
2048+ _event: PromptEvent,
2049+ ) -> anyhow::Result<()> {
2050+ let exit_code = args
2051+ .first()
2052+ .and_then(|code| code.parse::<i32>().ok())
2053+ .unwrap_or(1);
2054+ cx.editor.exit_code = exit_code;
2055+
2056+ let views: Vec<_> = cx.editor.tree.views().map(|(view, _)| view.id).collect();
2057+ for view_id in views {
2058+ cx.editor.close(view_id, false);
2059+ }
2060+
2061+ Ok(())
2062+ }
2063+
20452064 fn theme(
20462065 cx: &mut compositor::Context,
20472066 args: &[&str],
@@ -2411,6 +2430,13 @@ mod cmd {
24112430 fun: force_quit_all,
24122431 completer: None,
24132432 },
2433+ TypableCommand {
2434+ name: "cquit",
2435+ aliases: &["cq"],
2436+ doc: "Quit with exit code (default 1). Accepts an optional integer exit code (:cq 2).",
2437+ fun: cquit,
2438+ completer: None,
2439+ },
24142440 TypableCommand {
24152441 name: "theme",
24162442 aliases: &[],
helix-term/src/main.rs+9−3
@@ -38,8 +38,13 @@ fn setup_logging(logpath: PathBuf, verbosity: u64) -> Result<()> {
3838 Ok(())
3939}
4040
41+fn main() -> Result<()> {
42+ let exit_code = main_impl()?;
43+ std::process::exit(exit_code);
44+}
45+
4146#[tokio::main]
42−async fn main() -> Result<()> {
47+async fn main_impl() -> Result<i32> {
4348 let cache_dir = helix_core::cache_dir();
4449 if !cache_dir.exists() {
4550 std::fs::create_dir_all(&cache_dir).ok();
@@ -109,7 +114,8 @@ FLAGS:
109114
110115 // TODO: use the thread local executor to spawn the application task separately from the work pool
111116 let mut app = Application::new(args, config).context("unable to create new application")?;
112− app.run().await.unwrap();
113117
114− Ok(())
118+ let exit_code = app.run().await?;
119+
120+ Ok(exit_code)
115121}
helix-view/src/editor.rs+3
@@ -129,6 +129,8 @@ pub struct Editor {
129129
130130 pub idle_timer: Pin<Box<Sleep>>,
131131 pub last_motion: Option<Motion>,
132+
133+ pub exit_code: i32,
132134}
133135
134136#[derive(Debug, Copy, Clone)]
@@ -167,6 +169,7 @@ impl Editor {
167169 idle_timer: Box::pin(sleep(config.idle_timeout)),
168170 last_motion: None,
169171 config,
172+ exit_code: 0,
170173 }
171174 }
172175