Share the restore_term code between panic and normal exits (#3612)

It was starting to diverge as the normal exit code was restoring the prompt but the panic code
wasn't, and the panic code was disabling bracketed paste but the normal code wasn't.

This changes the panic path slightly in that we won't disable raw mode if exiting alternate screen
and disabling bracketed paste fails. If that happens, things are so busted I don't think it matters
anyway.
imgbot
Charlie Groves 2 years ago committed by GitHub
parent 93c6a337c4
commit 5c3f43a7f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -85,6 +85,22 @@ fn setup_integration_logging() {
.apply(); .apply();
} }
fn restore_term() -> Result<(), Error> {
let mut stdout = stdout();
// reset cursor shape
write!(stdout, "\x1B[0 q")?;
// Ignore errors on disabling, this might trigger on windows if we call
// disable without calling enable previously
let _ = execute!(stdout, DisableMouseCapture);
execute!(
stdout,
DisableBracketedPaste,
terminal::LeaveAlternateScreen
)?;
terminal::disable_raw_mode()?;
Ok(())
}
impl Application { impl Application {
pub fn new(args: Args, config: Config) -> Result<Self, Error> { pub fn new(args: Args, config: Config) -> Result<Self, Error> {
#[cfg(feature = "integration")] #[cfg(feature = "integration")]
@ -389,7 +405,7 @@ impl Application {
match signal { match signal {
signal::SIGTSTP => { signal::SIGTSTP => {
self.compositor.save_cursor(); self.compositor.save_cursor();
self.restore_term().unwrap(); restore_term().unwrap();
low_level::emulate_default_handler(signal::SIGTSTP).unwrap(); low_level::emulate_default_handler(signal::SIGTSTP).unwrap();
} }
signal::SIGCONT => { signal::SIGCONT => {
@ -803,18 +819,6 @@ impl Application {
Ok(()) Ok(())
} }
fn restore_term(&mut self) -> Result<(), Error> {
let mut stdout = stdout();
// reset cursor shape
write!(stdout, "\x1B[0 q")?;
// Ignore errors on disabling, this might trigger on windows if we call
// disable without calling enable previously
let _ = execute!(stdout, DisableMouseCapture);
execute!(stdout, terminal::LeaveAlternateScreen)?;
terminal::disable_raw_mode()?;
Ok(())
}
pub async fn run<S>(&mut self, input_stream: &mut S) -> Result<i32, Error> pub async fn run<S>(&mut self, input_stream: &mut S) -> Result<i32, Error>
where where
S: Stream<Item = crossterm::Result<crossterm::event::Event>> + Unpin, S: Stream<Item = crossterm::Result<crossterm::event::Event>> + Unpin,
@ -826,20 +830,14 @@ impl Application {
std::panic::set_hook(Box::new(move |info| { std::panic::set_hook(Box::new(move |info| {
// We can't handle errors properly inside this closure. And it's // We can't handle errors properly inside this closure. And it's
// probably not a good idea to `unwrap()` inside a panic handler. // probably not a good idea to `unwrap()` inside a panic handler.
// So we just ignore the `Result`s. // So we just ignore the `Result`.
let _ = execute!(std::io::stdout(), DisableMouseCapture); let _ = restore_term();
let _ = execute!(
std::io::stdout(),
terminal::LeaveAlternateScreen,
DisableBracketedPaste
);
let _ = terminal::disable_raw_mode();
hook(info); hook(info);
})); }));
self.event_loop(input_stream).await; self.event_loop(input_stream).await;
self.close().await?; self.close().await?;
self.restore_term()?; restore_term()?;
Ok(self.editor.exit_code) Ok(self.editor.exit_code)
} }

Loading…
Cancel
Save