mirror of
https://github.com/talwat/lowfi
synced 2026-06-23 16:13:14 +00:00
97 lines
2.7 KiB
Rust
97 lines
2.7 KiB
Rust
//! Contains the initialization and other handling of the terminal environment.
|
|
|
|
use std::{io::stdout, panic};
|
|
|
|
use crossterm::{
|
|
cursor::{Hide, MoveTo, Show},
|
|
event::{KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags},
|
|
terminal::{self, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen},
|
|
};
|
|
|
|
/// Represents the terminal environment, and is used to properly
|
|
/// initialize and clean up the terminal.
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct Environment {
|
|
/// Whether keyboard enhancements are enabled.
|
|
enhancement: bool,
|
|
|
|
/// Whether the terminal is in an alternate screen or not.
|
|
alternate: bool,
|
|
|
|
/// Whether the UI is actually enabled at all.
|
|
/// This will effectively make the environment just do nothing.
|
|
enabled: bool,
|
|
}
|
|
|
|
impl Environment {
|
|
/// This prepares the terminal, returning an [Environment] helpful
|
|
/// for cleaning up afterwards.
|
|
pub fn ready(args: &crate::Args) -> super::Result<Self> {
|
|
let enabled = !crate::env("LOWFI_DISABLE_UI");
|
|
if !enabled {
|
|
return Ok(Self {
|
|
enhancement: false,
|
|
alternate: args.alternate,
|
|
enabled,
|
|
});
|
|
}
|
|
|
|
let mut lock = stdout().lock();
|
|
|
|
crossterm::execute!(lock, Hide)?;
|
|
if args.alternate {
|
|
crossterm::execute!(lock, EnterAlternateScreen, MoveTo(0, 0))?;
|
|
}
|
|
|
|
terminal::enable_raw_mode()?;
|
|
|
|
let enhancement = terminal::supports_keyboard_enhancement().unwrap_or_default();
|
|
if enhancement {
|
|
crossterm::execute!(
|
|
lock,
|
|
PushKeyboardEnhancementFlags(KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES)
|
|
)?;
|
|
}
|
|
|
|
let environment = Self {
|
|
enabled,
|
|
enhancement,
|
|
alternate: args.alternate,
|
|
};
|
|
|
|
panic::set_hook(Box::new(move |info| {
|
|
let _ = environment.cleanup(false);
|
|
eprintln!("panic: {info}");
|
|
}));
|
|
|
|
Ok(environment)
|
|
}
|
|
|
|
/// Uses the information collected from initialization to safely close down
|
|
/// the terminal & restore it to it's previous state.
|
|
pub fn cleanup(&self, elegant: bool) -> super::Result<()> {
|
|
if !self.enabled {
|
|
return Ok(());
|
|
}
|
|
|
|
let mut lock = stdout().lock();
|
|
|
|
if self.alternate {
|
|
crossterm::execute!(lock, LeaveAlternateScreen)?;
|
|
}
|
|
|
|
crossterm::execute!(lock, Clear(ClearType::FromCursorDown), Show)?;
|
|
|
|
if self.enhancement {
|
|
crossterm::execute!(lock, PopKeyboardEnhancementFlags)?;
|
|
}
|
|
|
|
terminal::disable_raw_mode()?;
|
|
if elegant {
|
|
eprintln!("bye! :)");
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|