on master help sign in
helix-term/commands: implement cquit (#1096)
87e61a0Cole Helbling
helix-term/src/application.rs+2−2
@@ -599,7 +599,7 @@ impl Application {
599 Ok(())
599 Ok(())
600 }
600 }
601
601
602− pub async fn run(&mut self) -> Result<(), Error> {
602+ pub async fn run(&mut self) -> Result<i32, Error> {
603 self.claim_term().await?;
603 self.claim_term().await?;
604
604
605 // Exit the alternate screen and disable raw mode before panicking
605 // Exit the alternate screen and disable raw mode before panicking
@@ -622,6 +622,6 @@ impl Application {
622
622
623 self.restore_term()?;
623 self.restore_term()?;
624
624
625− Ok(())
625+ Ok(self.editor.exit_code)
626 }
626 }
627}
627}
helix-term/src/commands.rs+26
@@ -2042,6 +2042,25 @@ mod cmd {
2042 quit_all_impl(&mut cx.editor, args, event, true)
2042 quit_all_impl(&mut cx.editor, args, event, true)
2043 }
2043 }
2044
2044
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+
2045 fn theme(
2064 fn theme(
2046 cx: &mut compositor::Context,
2065 cx: &mut compositor::Context,
2047 args: &[&str],
2066 args: &[&str],
@@ -2411,6 +2430,13 @@ mod cmd {
2411 fun: force_quit_all,
2430 fun: force_quit_all,
2412 completer: None,
2431 completer: None,
2413 },
2432 },
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+ },
2414 TypableCommand {
2440 TypableCommand {
2415 name: "theme",
2441 name: "theme",
2416 aliases: &[],
2442 aliases: &[],
helix-term/src/main.rs+9−3
@@ -38,8 +38,13 @@ fn setup_logging(logpath: PathBuf, verbosity: u64) -> Result<()> {
38 Ok(())
38 Ok(())
39}
39}
40
40
41+fn main() -> Result<()> {
42+ let exit_code = main_impl()?;
43+ std::process::exit(exit_code);
44+}
45+
41#[tokio::main]
46#[tokio::main]
42−async fn main() -> Result<()> {
47+async fn main_impl() -> Result<i32> {
43 let cache_dir = helix_core::cache_dir();
48 let cache_dir = helix_core::cache_dir();
44 if !cache_dir.exists() {
49 if !cache_dir.exists() {
45 std::fs::create_dir_all(&cache_dir).ok();
50 std::fs::create_dir_all(&cache_dir).ok();
@@ -109,7 +114,8 @@ FLAGS:
109
114
110 // TODO: use the thread local executor to spawn the application task separately from the work pool
115 // TODO: use the thread local executor to spawn the application task separately from the work pool
111 let mut app = Application::new(args, config).context("unable to create new application")?;
116 let mut app = Application::new(args, config).context("unable to create new application")?;
112− app.run().await.unwrap();
113
117
114− Ok(())
118+ let exit_code = app.run().await?;
119+
120+ Ok(exit_code)
115}
121}
helix-view/src/editor.rs+3
@@ -129,6 +129,8 @@ pub struct Editor {
129
129
130 pub idle_timer: Pin<Box<Sleep>>,
130 pub idle_timer: Pin<Box<Sleep>>,
131 pub last_motion: Option<Motion>,
131 pub last_motion: Option<Motion>,
132+
133+ pub exit_code: i32,
132}
134}
133
135
134#[derive(Debug, Copy, Clone)]
136#[derive(Debug, Copy, Clone)]
@@ -167,6 +169,7 @@ impl Editor {
167 idle_timer: Box::pin(sleep(config.idle_timeout)),
169 idle_timer: Box::pin(sleep(config.idle_timeout)),
168 last_motion: None,
170 last_motion: None,
169 config,
171 config,
172+ exit_code: 0,
170 }
173 }
171 }
174 }
172
175