Skip to main content

mobius_cli/frontend/
terminal.rs

1use std::io;
2use std::time::Duration;
3
4use mobius::Result;
5use ratatui::crossterm::cursor::{Hide, Show};
6use ratatui::crossterm::event::{
7    self, DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture,
8    Event,
9};
10use ratatui::crossterm::execute;
11use ratatui::crossterm::terminal::{
12    EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode,
13};
14
15pub(super) const INPUT_POLL: Duration = Duration::from_millis(16);
16pub(super) const MAX_INPUT_BATCH: usize = 64;
17
18pub fn terminal_text(value: &str) -> String {
19    value
20        .chars()
21        .filter(|character| matches!(character, '\n' | '\t') || !character.is_control())
22        .collect()
23}
24
25pub(super) fn poll_event() -> Result<Option<Event>> {
26    event::poll(Duration::ZERO)?
27        .then(event::read)
28        .transpose()
29        .map_err(Into::into)
30}
31
32pub(super) struct TerminalGuard {
33    mouse_capture: bool,
34}
35
36impl TerminalGuard {
37    pub(super) fn alternate() -> Result<Self> {
38        enable_raw_mode()?;
39        let guard = Self {
40            mouse_capture: true,
41        };
42        execute!(
43            io::stdout(),
44            EnterAlternateScreen,
45            EnableMouseCapture,
46            EnableBracketedPaste,
47            Hide
48        )?;
49        Ok(guard)
50    }
51
52    pub(super) fn set_mouse_capture(&mut self, enabled: bool) -> Result<()> {
53        if self.mouse_capture == enabled {
54            return Ok(());
55        }
56        if enabled {
57            execute!(io::stdout(), EnableMouseCapture)?;
58        } else {
59            execute!(io::stdout(), DisableMouseCapture)?;
60        }
61        self.mouse_capture = enabled;
62        Ok(())
63    }
64}
65
66impl Drop for TerminalGuard {
67    fn drop(&mut self) {
68        let _ = disable_raw_mode();
69        let _ = execute!(
70            io::stdout(),
71            Show,
72            DisableMouseCapture,
73            DisableBracketedPaste,
74            LeaveAlternateScreen
75        );
76    }
77}