Skip to main content

termina/
event.rs

1// CREDIT: Most event code is adapted from crossterm. The main difference is that I include escape
2// sequences like CSI and DCS in the `Event` struct and do not make a distinction between
3// `InternalEvent` and `Event`. Otherwise all `KeyEvent` code is nearly identical to crossterm.
4
5use crate::{
6    escape::{csi::Csi, dcs::Dcs, osc::Osc},
7    WindowSize,
8};
9
10pub(crate) mod reader;
11pub(crate) mod source;
12#[cfg(feature = "event-stream")]
13pub(crate) mod stream;
14
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum Event {
17    Key(KeyEvent),
18    Mouse(MouseEvent),
19    /// The window was resized to the given dimensions.
20    WindowResized(WindowSize),
21    FocusIn,
22    FocusOut,
23    /// A "bracketed" paste.
24    ///
25    /// Normally pasting into a terminal with Ctrl+v (or Super+v) enters the pasted text as if
26    /// you had typed the keys individually. Terminals commonly support ["bracketed
27    /// paste"](https://en.wikipedia.org/wiki/Bracketed-paste) now however, which uses an escape
28    /// sequence to deliver the entire pasted content.
29    Paste(String),
30    /// A parsed escape sequence starting with CSI (control sequence introducer).
31    Csi(Csi),
32    /// A parsed escape sequence starting with OSC (operating system command).
33    Osc(Osc<'static>),
34    Dcs(Dcs),
35}
36
37impl Event {
38    #[inline]
39    pub fn is_escape(&self) -> bool {
40        matches!(self, Self::Csi(_) | Self::Dcs(_) | Self::Osc(_))
41    }
42}
43
44// CREDIT: <https://github.com/crossterm-rs/crossterm/blob/36d95b26a26e64b0f8c12edfe11f410a6d56a812/src/event.rs#L777-L1158>
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46pub struct KeyEvent {
47    pub code: KeyCode,
48    pub kind: KeyEventKind,
49    pub modifiers: Modifiers,
50    pub state: KeyEventState,
51}
52
53impl KeyEvent {
54    pub const fn new(code: KeyCode, modifiers: Modifiers) -> Self {
55        Self {
56            code,
57            modifiers,
58            kind: KeyEventKind::Press,
59            state: KeyEventState::NONE,
60        }
61    }
62}
63
64impl From<KeyCode> for KeyEvent {
65    fn from(code: KeyCode) -> Self {
66        Self {
67            code,
68            kind: KeyEventKind::Press,
69            modifiers: Modifiers::NONE,
70            state: KeyEventState::NONE,
71        }
72    }
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq)]
76pub enum KeyEventKind {
77    Press,
78    Release,
79    Repeat,
80}
81
82bitflags::bitflags! {
83    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
84    pub struct Modifiers: u8 {
85        const NONE = 0;
86        const SHIFT = 1 << 1;
87        const ALT = 1 << 2;
88        const CONTROL = 1 << 3;
89        const SUPER = 1 << 4;
90        const HYPER = 1 << 5;
91        const META = 1 << 5;
92    }
93}
94
95bitflags::bitflags! {
96    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
97    pub struct KeyEventState: u8 {
98        const NONE = 0;
99        const KEYPAD = 1 << 1;
100        const CAPS_LOCK = 1 << 2;
101        const NUM_LOCK = 1 << 3;
102    }
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq)]
106pub enum KeyCode {
107    Char(char),
108    Enter,
109    Backspace,
110    Tab,
111    Escape,
112    Left,
113    Right,
114    Up,
115    Down,
116    Home,
117    End,
118    BackTab,
119    PageUp,
120    PageDown,
121    Insert,
122    Delete,
123    KeypadBegin,
124    CapsLock,
125    ScrollLock,
126    NumLock,
127    PrintScreen,
128    Pause,
129    Menu,
130    Null,
131    /// F1-F35 "function" keys
132    Function(u8),
133    Modifier(ModifierKeyCode),
134    Media(MediaKeyCode),
135}
136#[derive(Debug, Clone, Copy, PartialEq, Eq)]
137pub enum ModifierKeyCode {
138    /// Left Shift key.
139    LeftShift,
140    /// Left Control key. (Control on macOS, Ctrl on other platforms)
141    LeftControl,
142    /// Left Alt key. (Option on macOS, Alt on other platforms)
143    LeftAlt,
144    /// Left Super key. (Command on macOS, Windows on Windows, Super on other platforms)
145    LeftSuper,
146    /// Left Hyper key.
147    LeftHyper,
148    /// Left Meta key.
149    LeftMeta,
150    /// Right Shift key.
151    RightShift,
152    /// Right Control key. (Control on macOS, Ctrl on other platforms)
153    RightControl,
154    /// Right Alt key. (Option on macOS, Alt on other platforms)
155    RightAlt,
156    /// Right Super key. (Command on macOS, Windows on Windows, Super on other platforms)
157    RightSuper,
158    /// Right Hyper key.
159    RightHyper,
160    /// Right Meta key.
161    RightMeta,
162    /// Iso Level3 Shift key.
163    IsoLevel3Shift,
164    /// Iso Level5 Shift key.
165    IsoLevel5Shift,
166}
167
168#[derive(Debug, Clone, Copy, PartialEq, Eq)]
169pub enum MediaKeyCode {
170    /// Play media key.
171    Play,
172    /// Pause media key.
173    Pause,
174    /// Play/Pause media key.
175    PlayPause,
176    /// Reverse media key.
177    Reverse,
178    /// Stop media key.
179    Stop,
180    /// Fast-forward media key.
181    FastForward,
182    /// Rewind media key.
183    Rewind,
184    /// Next-track media key.
185    TrackNext,
186    /// Previous-track media key.
187    TrackPrevious,
188    /// Record media key.
189    Record,
190    /// Lower-volume media key.
191    LowerVolume,
192    /// Raise-volume media key.
193    RaiseVolume,
194    /// Mute media key.
195    MuteVolume,
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq)]
199pub struct MouseEvent {
200    /// The kind of mouse event that was caused.
201    pub kind: MouseEventKind,
202    /// The column that the event occurred on.
203    pub column: u16,
204    /// The row that the event occurred on.
205    pub row: u16,
206    /// The key modifiers active when the event occurred.
207    pub modifiers: Modifiers,
208}
209
210#[derive(Debug, Clone, Copy, PartialEq, Eq)]
211pub enum MouseEventKind {
212    /// Pressed mouse button. Contains the button that was pressed.
213    Down(MouseButton),
214    /// Released mouse button. Contains the button that was released.
215    Up(MouseButton),
216    /// Moved the mouse cursor while pressing the contained mouse button.
217    Drag(MouseButton),
218    /// Moved the mouse cursor while not pressing a mouse button.
219    Moved,
220    /// Scrolled mouse wheel downwards (towards the user).
221    ScrollDown,
222    /// Scrolled mouse wheel upwards (away from the user).
223    ScrollUp,
224    /// Scrolled mouse wheel left (mostly on a laptop touchpad).
225    ScrollLeft,
226    /// Scrolled mouse wheel right (mostly on a laptop touchpad).
227    ScrollRight,
228}
229
230#[derive(Debug, Clone, Copy, PartialEq, Eq)]
231pub enum MouseButton {
232    /// Left mouse button.
233    Left,
234    /// Right mouse button.
235    Right,
236    /// Middle mouse button.
237    Middle,
238}