diff --git a/src/main.rs b/src/main.rs index 7c1d394..8b0e677 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ use kmon::args; use kmon::event::Events; use kmon::kernel::Kernel; +use kmon::util; use ratatui::backend::TermionBackend; use ratatui::Terminal; use std::error::Error; @@ -25,6 +26,7 @@ fn main() -> Result<(), Box> { &kernel.logs, ); if !cfg!(test) { + util::setup_panic_hook()?; let stdout = stdout().into_raw_mode()?.into_alternate_screen()?; let stdout = MouseTerminal::from(stdout); let backend = TermionBackend::new(stdout); diff --git a/src/util.rs b/src/util.rs index a1c0268..dbd499c 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,4 +1,8 @@ +use std::error::Error; +use std::io::{self, Write}; +use std::panic; use std::process::Command; +use termion::raw::IntoRawMode; /* Macro for concise initialization of hashmap */ macro_rules! map { @@ -62,6 +66,39 @@ pub fn exec_cmd(cmd: &str, cmd_args: &[&str]) -> Result { } } +/** + * Sets up the panic hook for the terminal. + * + * See + * + * @return Result + */ +pub fn setup_panic_hook() -> Result<(), Box> { + let raw_output = io::stdout().into_raw_mode()?; + raw_output.suspend_raw_mode()?; + + let panic_hook = panic::take_hook(); + panic::set_hook(Box::new(move |panic| { + let panic_cleanup = || -> Result<(), Box> { + let mut output = io::stdout(); + write!( + output, + "{}{}{}", + termion::clear::All, + termion::screen::ToMainScreen, + termion::cursor::Show + )?; + raw_output.suspend_raw_mode()?; + output.flush()?; + Ok(()) + }; + panic_cleanup().expect("failed to clean up for panic"); + panic_hook(panic); + })); + + Ok(()) +} + #[cfg(test)] mod tests { use super::*;