use std::io;
use ratatui::crossterm::event::{
DisableMouseCapture, EnableMouseCapture, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags,
PushKeyboardEnhancementFlags,
};
use ratatui::crossterm::execute;
use ratatui::crossterm::terminal::supports_keyboard_enhancement;
#[derive(Debug)]
pub struct TerminalGuard {
keyboard_enhancement_active: bool,
}
impl TerminalGuard {
pub fn install(keyboard_enhancement: bool) -> io::Result<Self> {
let enhanced = keyboard_enhancement && supports_keyboard_enhancement().unwrap_or(false);
if enhanced {
execute!(
io::stdout(),
PushKeyboardEnhancementFlags(KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES),
)?;
}
execute!(io::stdout(), EnableMouseCapture)?;
let previous_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| {
let _ = execute!(io::stdout(), DisableMouseCapture);
if enhanced {
let _ = execute!(io::stdout(), PopKeyboardEnhancementFlags);
}
previous_hook(info);
}));
Ok(Self {
keyboard_enhancement_active: enhanced,
})
}
pub fn keyboard_enhancement_active(&self) -> bool {
self.keyboard_enhancement_active
}
}
impl Drop for TerminalGuard {
fn drop(&mut self) {
if self.keyboard_enhancement_active {
let _ = execute!(io::stdout(), PopKeyboardEnhancementFlags);
}
let _ = execute!(io::stdout(), DisableMouseCapture);
}
}