From 48ae93f7ef033021deec2beddd1ac291814f98b9 Mon Sep 17 00:00:00 2001 From: figsoda Date: Wed, 13 Nov 2024 23:30:50 -0500 Subject: [PATCH] review: reset the terminal when interrupted --- Cargo.lock | 29 +++++++++++++++++++++++++++++ Cargo.toml | 1 + src/cmd/review.rs | 22 +++++++++++++++++++--- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d303867..53164ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,6 +198,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "clap" version = "4.5.21" @@ -336,6 +342,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "ctrlc" +version = "3.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +dependencies = [ + "nix", + "windows-sys 0.59.0", +] + [[package]] name = "deranged" version = "0.3.11" @@ -568,6 +584,7 @@ dependencies = [ "clap_complete", "clap_mangen", "color-eyre", + "ctrlc", "dialoguer", "eyre", "monostate", @@ -579,6 +596,18 @@ dependencies = [ "toml", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nu-ansi-term" version = "0.49.0" diff --git a/Cargo.toml b/Cargo.toml index 3b44a93..73b5178 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ categories = ["command-line-utilities", "development-tools::testing"] [dependencies] bstr = "1.11.0" color-eyre = "0.6.3" +ctrlc = "3.4.5" dialoguer = "0.11.0" eyre = "0.6.12" monostate = "0.1.13" diff --git a/src/cmd/review.rs b/src/cmd/review.rs index ed99080..c6d2192 100644 --- a/src/cmd/review.rs +++ b/src/cmd/review.rs @@ -1,11 +1,14 @@ use std::{ ffi::OsStr, fs::{read_dir, remove_file, rename, File}, - io::{stderr, BufRead, Write}, + io::{self, stderr, BufRead, Write}, path::Path, + process::exit, + thread::sleep, + time::Duration, }; -use dialoguer::{theme::ColorfulTheme, Select}; +use dialoguer::{console::Term, theme::ColorfulTheme, Select}; use eyre::{eyre, Result}; use owo_colors::OwoColorize; use similar::{ChangeTag, TextDiff}; @@ -19,6 +22,12 @@ use crate::{ pub fn review(opts: Opts, cfg: Option) -> Result<()> { let output = nix_eval(opts, cfg)?; + let _ = ctrlc::set_handler(|| { + let mut term = Term::stderr(); + let _ = term.show_cursor(); + let _ = writeln!(term, "interrupted"); + exit(0); + }); for line in output.stderr.lines() { let line = line?; @@ -115,7 +124,14 @@ fn ask(name: &OsStr, old: &Path, new: &Path) -> Result<()> { .item("skip".blue()) .default(0) .with_prompt(format!("Review {}", name.to_string_lossy())) - .interact()?; + .interact() + .inspect_err(|dialoguer::Error::IO(e)| { + if e.kind() == io::ErrorKind::Interrupted { + // make sure ctrlc handler has reset the terminal + sleep(Duration::from_millis(16)); + exit(0); + } + })?; match choice { 0 => rename(new, old).map_err(Into::into),