1use crossterm::event::{
2 DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture, KeyboardEnhancementFlags,
3 PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,
4};
5use crossterm::execute;
6use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
7use std::io;
8
9pub fn terminal_size() -> io::Result<(u16, u16)> {
10 crossterm::terminal::size()
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum MouseCapture {
15 Disabled,
16 Enabled,
17}
18
19#[doc = include_str!("../docs/terminal_session.md")]
20pub struct TerminalSession {
21 enable_bracketed_paste: bool,
22 keyboard_enhancement_enabled: bool,
23}
24
25impl TerminalSession {
26 pub fn new(enable_bracketed_paste: bool, mouse_capture: MouseCapture) -> io::Result<Self> {
27 enable_raw_mode()?;
28 let mut stdout = io::stdout();
29 let flags = KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
30 | KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS
31 | KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES;
32 let keyboard_enhancement_enabled = execute!(stdout, PushKeyboardEnhancementFlags(flags)).is_ok();
33
34 if enable_bracketed_paste {
35 execute!(stdout, EnableBracketedPaste)?;
36 }
37 if mouse_capture == MouseCapture::Enabled {
38 execute!(stdout, EnableMouseCapture)?;
39 }
40
41 Ok(Self { enable_bracketed_paste, keyboard_enhancement_enabled })
42 }
43}
44
45impl Drop for TerminalSession {
46 fn drop(&mut self) {
47 let mut stdout = io::stdout();
48 let _ = execute!(stdout, DisableMouseCapture);
52 if self.keyboard_enhancement_enabled {
53 let _ = execute!(stdout, PopKeyboardEnhancementFlags);
54 }
55 if self.enable_bracketed_paste {
56 let _ = execute!(stdout, DisableBracketedPaste);
57 }
58 let _ = disable_raw_mode();
59 }
60}