Skip to main content

binocular/infra/
terminal.rs

1use crossterm::{
2    cursor::SetCursorStyle,
3    execute,
4    terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
5};
6use std::io;
7
8pub struct TerminalSessionGuard {
9    cursor_style_is_bar: bool,
10}
11
12impl TerminalSessionGuard {
13    pub fn enter() -> anyhow::Result<Self> {
14        enable_raw_mode()?;
15        execute!(
16            io::stderr(),
17            EnterAlternateScreen,
18            SetCursorStyle::BlinkingBlock
19        )?;
20        Ok(Self {
21            cursor_style_is_bar: false,
22        })
23    }
24
25    pub fn sync_cursor_style(&mut self, should_be_bar: bool) {
26        if should_be_bar == self.cursor_style_is_bar {
27            return;
28        }
29
30        let style = if should_be_bar {
31            SetCursorStyle::BlinkingBar
32        } else {
33            SetCursorStyle::BlinkingBlock
34        };
35        let _ = execute!(io::stderr(), style);
36        self.cursor_style_is_bar = should_be_bar;
37    }
38}
39
40impl Drop for TerminalSessionGuard {
41    fn drop(&mut self) {
42        let _ = execute!(io::stderr(), SetCursorStyle::BlinkingBlock);
43        let _ = execute!(io::stderr(), LeaveAlternateScreen);
44        let _ = disable_raw_mode();
45    }
46}