Skip to main content

pacsea/app/
terminal.rs

1use crossterm::{
2    event::{DisableMouseCapture, EnableMouseCapture},
3    execute,
4    terminal::{EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode},
5};
6
7/// Result type alias for terminal operations.
8type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
9
10/// What: Enter raw mode and switch to the alternate screen with mouse capture enabled.
11///
12/// Inputs:
13/// - None
14///
15/// Output:
16/// - `Ok(())` if the terminal was prepared; `Err` on I/O or terminal backend failure.
17///
18/// # Errors
19///
20/// Returns an error if raw mode cannot be enabled or the alternate screen cannot be entered.
21pub fn setup_terminal() -> Result<()> {
22    if std::env::var("PACSEA_TEST_HEADLESS").ok().as_deref() == Some("1") {
23        // Skip raw TTY setup in headless/test mode
24        // Explicitly disable mouse reporting to prevent mouse position escape sequences
25        // from appearing in test output when mouse moves over terminal
26        let _ = execute!(std::io::stdout(), DisableMouseCapture);
27        return Ok(());
28    }
29    enable_raw_mode()?;
30    execute!(std::io::stdout(), EnterAlternateScreen, EnableMouseCapture)?;
31    Ok(())
32}
33
34/// What: Restore terminal to normal mode, leave the alternate screen, and disable mouse capture.
35///
36/// Inputs:
37/// - None
38///
39/// Output:
40/// - `Ok(())` when restoration succeeds; `Err` if underlying terminal operations fail.
41///
42/// # Errors
43///
44/// Returns an error if raw mode cannot be disabled or the alternate screen cannot be left.
45pub fn restore_terminal() -> Result<()> {
46    if std::env::var("PACSEA_TEST_HEADLESS").ok().as_deref() == Some("1") {
47        // Skip terminal restore in headless/test mode
48        return Ok(());
49    }
50    disable_raw_mode()?;
51    execute!(std::io::stdout(), DisableMouseCapture, LeaveAlternateScreen)?;
52    Ok(())
53}