1use crossterm::event::{
2 KeyCode,
3 KeyEvent,
4 KeyEventKind,
5 KeyModifiers,
6};
7
8#[derive(Debug, Clone, PartialEq)]
13pub enum Event {
14 Key(KeyEvent),
16 Mouse(crossterm::event::MouseEvent),
18 Resize(u16, u16),
20 Paste(String),
22 FocusGained,
24 FocusLost,
26}
27
28#[derive(Debug, Clone, PartialEq, Eq, Hash)]
34pub enum Key {
35 Char(char, Modifiers),
37 Code(KeyCode, Modifiers),
39}
40
41#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
43pub struct Modifiers {
44 pub shift: bool,
46 pub ctrl: bool,
48 pub alt: bool,
50}
51
52impl Modifiers {
53 pub fn none() -> Self {
55 Self::default()
56 }
57
58 pub fn ctrl() -> Self {
60 Self {
61 ctrl: true,
62 ..Default::default()
63 }
64 }
65
66 pub fn shift() -> Self {
68 Self {
69 shift: true,
70 ..Default::default()
71 }
72 }
73
74 pub fn alt() -> Self {
76 Self {
77 alt: true,
78 ..Default::default()
79 }
80 }
81
82 pub fn ctrl_shift() -> Self {
84 Self {
85 ctrl: true,
86 shift: true,
87 ..Default::default()
88 }
89 }
90}
91
92impl Key {
93 pub fn enter() -> Self {
95 Key::Code(KeyCode::Enter, Modifiers::none())
96 }
97
98 pub fn left() -> Self {
100 Key::Code(KeyCode::Left, Modifiers::none())
101 }
102
103 pub fn right() -> Self {
105 Key::Code(KeyCode::Right, Modifiers::none())
106 }
107
108 pub fn up() -> Self {
110 Key::Code(KeyCode::Up, Modifiers::none())
111 }
112
113 pub fn down() -> Self {
115 Key::Code(KeyCode::Down, Modifiers::none())
116 }
117
118 pub fn backspace() -> Self {
120 Key::Code(KeyCode::Backspace, Modifiers::none())
121 }
122
123 pub fn delete() -> Self {
125 Key::Code(KeyCode::Delete, Modifiers::none())
126 }
127
128 pub fn home() -> Self {
130 Key::Code(KeyCode::Home, Modifiers::none())
131 }
132
133 pub fn end() -> Self {
135 Key::Code(KeyCode::End, Modifiers::none())
136 }
137
138 pub fn tab() -> Self {
140 Key::Code(KeyCode::Tab, Modifiers::none())
141 }
142
143 pub fn esc() -> Self {
145 Key::Code(KeyCode::Esc, Modifiers::none())
146 }
147
148 pub fn ctrl(c: char) -> Self {
150 Key::Char(c, Modifiers::ctrl())
151 }
152
153 pub fn ctrl_shift(c: char) -> Self {
155 Key::Char(c, Modifiers::ctrl_shift())
156 }
157
158 pub fn alt(c: char) -> Self {
160 Key::Char(c, Modifiers::alt())
161 }
162
163 pub fn char(c: char) -> Self {
165 Key::Char(c, Modifiers::none())
166 }
167}
168
169pub fn matches_key(event: &Event, key: &Key) -> bool {
192 let Event::Key(key_event) = event else {
193 return false;
194 };
195 if key_event.kind == KeyEventKind::Release {
196 return false;
197 }
198 let km = key_event.modifiers;
199 let mods = Modifiers {
200 shift: km.contains(KeyModifiers::SHIFT),
201 ctrl: km.contains(KeyModifiers::CONTROL),
202 alt: km.contains(KeyModifiers::ALT),
203 };
204 match key {
205 | Key::Char(expected, expected_mods) => {
206 if let KeyCode::Char(c) = key_event.code {
207 c == *expected && mods == *expected_mods
208 } else {
209 false
210 }
211 },
212 | Key::Code(expected, expected_mods) => {
213 key_event.code == *expected && mods == *expected_mods
214 },
215 }
216}