rat_event/
crossterm.rs

1//! Support for the [ct_event!](macro.ct_event.html) macro.
2
3#![allow(dead_code)]
4
5pub mod event {
6    pub use ratatui_crossterm::crossterm::event::Event;
7    pub use ratatui_crossterm::crossterm::event::KeyCode;
8    pub use ratatui_crossterm::crossterm::event::KeyEvent;
9    pub use ratatui_crossterm::crossterm::event::KeyEventKind;
10    pub use ratatui_crossterm::crossterm::event::KeyModifiers;
11    pub use ratatui_crossterm::crossterm::event::MouseButton;
12    pub use ratatui_crossterm::crossterm::event::MouseEvent;
13    pub use ratatui_crossterm::crossterm::event::MouseEventKind;
14}
15
16/// A copy of the crossterm-KeyModifiers. Plus a few combinations of modifiers.
17pub mod modifiers {
18    use crate::crossterm::event::KeyModifiers;
19
20    pub const NONE: KeyModifiers = KeyModifiers::NONE;
21    pub const CONTROL: KeyModifiers = KeyModifiers::CONTROL;
22    pub const SHIFT: KeyModifiers = KeyModifiers::SHIFT;
23    pub const ALT: KeyModifiers = KeyModifiers::ALT;
24    pub const META: KeyModifiers = KeyModifiers::META;
25    pub const SUPER: KeyModifiers = KeyModifiers::SUPER;
26    pub const HYPER: KeyModifiers = KeyModifiers::HYPER;
27    pub const CONTROL_ALT: KeyModifiers = KeyModifiers::from_bits_truncate(0b0000_0110);
28    pub const CONTROL_SHIFT: KeyModifiers = KeyModifiers::from_bits_truncate(0b0000_0011);
29    pub const ALT_SHIFT: KeyModifiers = KeyModifiers::from_bits_truncate(0b0000_0101);
30}
31
32/// This macro produces pattern matches for crossterm events.
33///
34/// Example:
35/// ```rust ignore
36/// match event {
37///     ct_event!(keycode press Left) => self.move_to_prev(false),
38///     ct_event!(keycode press Right) => self .move_to_next(false),
39///     ct_event!(keycode press CONTROL-Left) => {
40///         let pos = self.prev_word_boundary();
41///         self.set_cursor(pos, false);
42///     }
43///     ct_event!(keycode press CONTROL_SHIFT-Left) => {
44///         let pos = self.prev_word_boundary();
45///         self.set_cursor(pos, true);
46///     }
47///     ct_event!(key press CONTROL-'a') => self.set_selection(0, self.len()),
48///     ct_event!(key press c) | ct_event!(key press SHIFT-c) => self.insert_char( * c),
49///
50///     ct_event!(mouse down Left for column,row) => {
51///         // ...
52///     }
53///     ct_event!(mouse drag Left for column, _row) => {
54///         // ...
55///     }
56///     ct_event!(mouse moved) => {
57///         // ...
58///     }
59/// }
60/// ```
61///
62/// __Caveat__
63/// press covers both KeyEventKind::Press and KeyEventKind::Repeat
64/// which is probably what you expect. This macro doesn't cover
65/// the case where those two need to be distinguished.
66///
67///
68/// Syntax:
69/// ```bnf
70/// "key" ("press"|"release") (modifier "-")? "'" char "'"
71/// "keycode" ("press"|"release") (modifier "-")? keycode
72/// "mouse" ("down"|"up"|"drag") (modifier "-")? button "for" col_id "," row_id
73/// "mouse" "any" (modifier)? ("for" mouseevt)?
74/// "mouse" "moved" ("for" col_id "," row_id)?
75/// "scroll" ("up"|"down") "for" col_id "," row_id
76/// "resized" "for" cols_id "," rows_id
77/// "focus_gained"
78/// "focus_lost"
79/// "paste" identifier
80/// ```
81///
82/// where
83///
84/// ```bnf
85/// modifier := <<one of the KeyModifiers's>> | "CONTROL_SHIFT" | "ALT_SHIFT"
86/// char := <<some character>>
87/// keycode := <<one of the defined KeyCode's>>
88/// button := <<one of the defined MouseButton's>>
89/// ```
90///
91/// __Caveat__
92/// `ct_event!(key press SHIFT-'f')` doesn't work. It must be
93/// `ct_event!(key press SHIFT-'F')` with capital F. This holds for
94/// any combination of SHIFT too.
95///
96#[macro_export]
97macro_rules! ct_event {
98    (key press $keychar:pat) => {
99        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
100            code: $crate::crossterm::event::KeyCode::Char($keychar),
101            modifiers: $crate::crossterm::modifiers::NONE,
102            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
103            ..
104        })
105    };
106    (key press ANY-$keychar:pat) => {
107        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
108            code: $crate::crossterm::event::KeyCode::Char($keychar),
109            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
110            ..
111        })
112    };
113    (key press $mod:ident-$keychar:pat) => {
114        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
115            code: $crate::crossterm::event::KeyCode::Char($keychar),
116            modifiers: $crate::crossterm::modifiers::$mod,
117            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
118            ..
119        })
120    };
121    (key release $keychar:pat) => {
122        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
123            code: $crate::crossterm::event::KeyCode::Char($keychar),
124            modifiers: $crate::crossterm::modifiers::NONE,
125            kind: $crate::crossterm::event::KeyEventKind::Release,
126            ..
127        })
128    };
129    (key release ANY-$keychar:pat) => {
130        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
131            code: $crate::crossterm::event::KeyCode::Char($keychar),
132            kind: $crate::crossterm::event::KeyEventKind::Release,
133            ..
134        })
135    };
136    (key release $mod:ident-$keychar:pat) => {
137        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
138            code: $crate::crossterm::event::KeyCode::Char($keychar),
139            modifiers: $crate::crossterm::modifiers::$mod,
140            kind: $crate::crossterm::event::KeyEventKind::Release,
141            ..
142        })
143    };
144
145    (keycode press F($code:literal)) => {
146        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
147            code: $crate::crossterm::event::KeyCode::F($code),
148            modifiers: $crate::crossterm::modifiers::NONE,
149            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
150            ..
151        })
152    };
153    (keycode press $mod:ident-F($code:literal)) => {
154        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
155            code: $crate::crossterm::event::KeyCode::F($code),
156            modifiers: $crate::crossterm::modifiers::$mod,
157            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
158            ..
159        })
160    };
161    (keycode press $code:ident) => {
162        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
163            code: $crate::crossterm::event::KeyCode::$code,
164            modifiers: $crate::crossterm::modifiers::NONE,
165            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
166            ..
167        })
168    };
169    (keycode press $mod:ident-$code:ident) => {
170        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
171            code: $crate::crossterm::event::KeyCode::$code,
172            modifiers: $crate::crossterm::modifiers::$mod,
173            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
174            ..
175        })
176    };
177    (keycode release F($code:literal)) => {
178        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
179            code: $crate::crossterm::event::KeyCode::F($code),
180            modifiers: $crate::crossterm::modifiers::NONE,
181            kind: $crate::crossterm::event::KeyEventKind::Release,
182            ..
183        })
184    };
185    (keycode release $mod:ident-F($code:literal)) => {
186        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
187            code: $crate::crossterm::event::KeyCode::F($code),
188            modifiers: $crate::crossterm::modifiers::$mod,
189            kind: $crate::crossterm::event::KeyEventKind::Release,
190            ..
191        })
192    };
193    (keycode release $code:ident) => {
194        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
195            code: $crate::crossterm::event::KeyCode::$code,
196            modifiers: $crate::crossterm::modifiers::NONE,
197            kind: $crate::crossterm::event::KeyEventKind::Release,
198            ..
199        })
200    };
201    (keycode release $mod:ident-$code:ident) => {
202        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
203            code: $crate::crossterm::event::KeyCode::$code,
204            modifiers: $crate::crossterm::modifiers::$mod,
205            kind: $crate::crossterm::event::KeyEventKind::Release,
206            ..
207        })
208    };
209
210    (mouse down $button:ident for $col:ident, $row:ident ) => {
211        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
212            kind: $crate::crossterm::event::MouseEventKind::Down($crate::crossterm::event::MouseButton::$button),
213            column: $col,
214            row: $row,
215            modifiers: $crate::crossterm::modifiers::NONE,
216        })
217    };
218    (mouse down $mod:ident-$button:ident for $col:ident, $row:ident ) => {
219        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
220            kind: $crate::crossterm::event::MouseEventKind::Down($crate::crossterm::event::MouseButton::$button),
221            column: $col,
222            row: $row,
223            modifiers: $crate::crossterm::modifiers::$mod,
224        })
225    };
226    (mouse up $button:ident for $col:ident, $row:ident ) => {
227        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
228            kind: $crate::crossterm::event::MouseEventKind::Up($crate::crossterm::event::MouseButton::$button),
229            column: $col,
230            row: $row,
231            modifiers: $crate::crossterm::modifiers::NONE,
232        })
233    };
234    (mouse up $mod:ident-$button:ident for $col:ident, $row:ident ) => {
235        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
236            kind: $crate::crossterm::event::MouseEventKind::Up($crate::crossterm::event::MouseButton::$button),
237            column: $col,
238            row: $row,
239            modifiers: $crate::crossterm::modifiers::$mod,
240        })
241    };
242    (mouse drag $button:ident for $col:ident, $row:ident ) => {
243        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
244            kind: $crate::crossterm::event::MouseEventKind::Drag($crate::crossterm::event::MouseButton::$button),
245            column: $col,
246            row: $row,
247            modifiers: $crate::crossterm::modifiers::NONE,
248        })
249    };
250    (mouse drag $mod:ident-$button:ident for $col:ident, $row:ident ) => {
251        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
252            kind: $crate::crossterm::event::MouseEventKind::Drag($crate::crossterm::event::MouseButton::$button),
253            column: $col,
254            row: $row,
255            modifiers: $crate::crossterm::modifiers::$mod,
256        })
257    };
258
259
260    (mouse any for $mouse:ident) => {
261        $crate::crossterm::event::Event::Mouse($mouse)
262    };
263    (mouse any $mod:ident for $mouse:ident ) => {
264        $crate::crossterm::event::Event::Mouse($mouse @ $crate::crossterm::event::MouseEvent {
265            modifiers: $crate::crossterm::modifiers::$mod,
266            ..
267        })
268    };
269
270    (mouse moved ) => {
271        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
272            kind: $crate::crossterm::event::MouseEventKind::Moved,
273            modifiers: $crate::crossterm::modifiers::NONE,
274            ..
275        })
276    };
277    (mouse moved for $col:ident, $row:ident) => {
278        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
279            kind: $crate::crossterm::event::MouseEventKind::Moved,
280            column: $col,
281            row: $row,
282            modifiers: $crate::crossterm::modifiers::NONE,
283        })
284    };
285
286    (scroll $mod:ident down for $col:ident, $row:ident) => {
287        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
288            kind: $crate::crossterm::event::MouseEventKind::ScrollDown,
289            column: $col,
290            row: $row,
291            modifiers: $crate::crossterm::modifiers::$mod,
292        })
293    };
294    (scroll down for $col:ident, $row:ident) => {
295        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
296            kind: $crate::crossterm::event::MouseEventKind::ScrollDown,
297            column: $col,
298            row: $row,
299            modifiers: $crate::crossterm::modifiers::NONE,
300        })
301    };
302    (scroll down) => {
303        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
304            kind: $crate::crossterm::event::MouseEventKind::ScrollDown,
305            modifiers: $crate::crossterm::modifiers::NONE,
306            ..
307        })
308    };
309    (scroll $mod:ident up for $col:ident, $row:ident) => {
310        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
311            kind: $crate::crossterm::event::MouseEventKind::ScrollUp,
312            column: $col,
313            row: $row,
314            modifiers: $crate::crossterm::modifiers::$mod,
315        })
316    };
317    (scroll up for $col:ident, $row:ident) => {
318        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
319            kind: $crate::crossterm::event::MouseEventKind::ScrollUp,
320            column: $col,
321            row: $row,
322            modifiers: $crate::crossterm::modifiers::NONE,
323        })
324    };
325    (scroll up) => {
326        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
327            kind: $crate::crossterm::event::MouseEventKind::ScrollUp,
328            modifiers: $crate::crossterm::modifiers::NONE,
329            ..
330        })
331    };
332
333    //??
334    (scroll left for $col:ident, $row:ident) => {
335        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
336            kind: $crate::crossterm::event::MouseEventKind::ScrollLeft,
337            column: $col,
338            row: $row,
339            modifiers: $crate::crossterm::modifiers::NONE,
340        })
341    };
342    (scroll left) => {
343        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
344            kind: $crate::crossterm::event::MouseEventKind::ScrollLeft,
345            modifiers: $crate::crossterm::modifiers::NONE,
346            ..
347        })
348    };
349    //??
350    (scroll right for $col:ident, $row:ident) => {
351        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
352            kind: $crate::crossterm::event::MouseEventKind::ScrollRight,
353            column: $col,
354            row: $row,
355            modifiers: $crate::crossterm::modifiers::NONE,
356        })
357    };
358    (scroll right) => {
359        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
360            kind: $crate::crossterm::event::MouseEventKind::ScrollRight,
361            modifiers: $crate::crossterm::modifiers::NONE,
362            ..
363        })
364    };
365
366    (resized) => {
367        $crate::crossterm::event::Event::Resize(_, _)
368    };
369    (resized for $cols:ident, $rows:ident ) => {
370        $crate::crossterm::event::Event::Resize($cols, $rows)
371    };
372    (focus_gained) => {
373        $crate::crossterm::event::Event::FocusGained
374    };
375    (focus_lost) => {
376        $crate::crossterm::event::Event::FocusLost
377    };
378    (paste $value:ident) => {
379        $crate::crossterm::event::Event::Paste($value)
380    };
381}