diff --git a/src/tui.rs b/src/tui.rs index 635ccb8..1cd331a 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -4,6 +4,7 @@ use crate::ui; use crossterm::event::{DisableMouseCapture, EnableMouseCapture}; use crossterm::terminal::{self, EnterAlternateScreen, LeaveAlternateScreen}; use std::io; +use std::panic; use tui::backend::Backend; use tui::Terminal; @@ -31,6 +32,15 @@ impl Tui { pub fn init(&mut self) -> AppResult<()> { terminal::enable_raw_mode()?; crossterm::execute!(io::stderr(), EnterAlternateScreen, EnableMouseCapture)?; + + // Define a custom panic hook to reset the terminal properties. + // This way, you won't have your terminal messed up if an unexpected error happens. + let panic_hook = panic::take_hook(); + panic::set_hook(Box::new(move |panic| { + Self::reset().expect("failed to reset the terminal"); + panic_hook(panic); + })); + self.terminal.hide_cursor()?; self.terminal.clear()?; Ok(()) @@ -45,12 +55,21 @@ impl Tui { Ok(()) } + /// Resets the terminal interface. + /// + /// This function is also used for the panic hook to revert + /// the terminal properties if unexpected errors occur. + fn reset() -> AppResult<()> { + terminal::disable_raw_mode()?; + crossterm::execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture)?; + Ok(()) + } + /// Exits the terminal interface. /// /// It disables the raw mode and reverts back the terminal properties. pub fn exit(&mut self) -> AppResult<()> { - terminal::disable_raw_mode()?; - crossterm::execute!(io::stderr(), LeaveAlternateScreen, DisableMouseCapture)?; + Self::reset()?; self.terminal.show_cursor()?; Ok(()) }