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