Skip to main content

tui/runtime/
terminal.rs

1use crossterm::event::{DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture};
2use crossterm::execute;
3use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
4use std::io;
5
6pub fn terminal_size() -> io::Result<(u16, u16)> {
7    crossterm::terminal::size()
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum MouseCapture {
12    Disabled,
13    Enabled,
14}
15
16#[doc = include_str!("../docs/terminal_session.md")]
17pub struct TerminalSession {
18    enable_bracketed_paste: bool,
19}
20
21impl TerminalSession {
22    pub fn new(enable_bracketed_paste: bool, mouse_capture: MouseCapture) -> io::Result<Self> {
23        enable_raw_mode()?;
24        let mut stdout = io::stdout();
25
26        if enable_bracketed_paste {
27            execute!(stdout, EnableBracketedPaste)?;
28        }
29        if mouse_capture == MouseCapture::Enabled {
30            execute!(stdout, EnableMouseCapture)?;
31        }
32
33        Ok(Self { enable_bracketed_paste })
34    }
35}
36
37impl Drop for TerminalSession {
38    fn drop(&mut self) {
39        let mut stdout = io::stdout();
40        // Always attempt to disable mouse capture defensively: callers may
41        // toggle capture via RendererCommand after session creation, so the
42        // initial `mouse_capture` field may no longer reflect terminal state.
43        let _ = execute!(stdout, DisableMouseCapture);
44        if self.enable_bracketed_paste {
45            let _ = execute!(stdout, DisableBracketedPaste);
46        }
47        let _ = disable_raw_mode();
48    }
49}