binocular/infra/
terminal.rs1use 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}