Skip to main content

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
162    (keycode press Media($code:ident)) => {
163        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
164            code: $crate::crossterm::event::KeyCode::Media($code),
165            modifiers: $crate::crossterm::modifiers::NONE,
166            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
167            ..
168        })
169    };
170    (keycode press $mod:ident-Media($code:ident)) => {
171        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
172            code: $crate::crossterm::event::KeyCode::Media($code),
173            modifiers: $crate::crossterm::modifiers::$mod,
174            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
175            ..
176        })
177    };
178
179    (keycode press $code:ident) => {
180        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
181            code: $crate::crossterm::event::KeyCode::$code,
182            modifiers: $crate::crossterm::modifiers::NONE,
183            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
184            ..
185        })
186    };
187    (keycode press $mod:ident-$code:ident) => {
188        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
189            code: $crate::crossterm::event::KeyCode::$code,
190            modifiers: $crate::crossterm::modifiers::$mod,
191            kind: $crate::crossterm::event::KeyEventKind::Press|$crate::crossterm::event::KeyEventKind::Repeat,
192            ..
193        })
194    };
195
196    (keycode release F($code:literal)) => {
197        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
198            code: $crate::crossterm::event::KeyCode::F($code),
199            modifiers: $crate::crossterm::modifiers::NONE,
200            kind: $crate::crossterm::event::KeyEventKind::Release,
201            ..
202        })
203    };
204    (keycode release $mod:ident-F($code:literal)) => {
205        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
206            code: $crate::crossterm::event::KeyCode::F($code),
207            modifiers: $crate::crossterm::modifiers::$mod,
208            kind: $crate::crossterm::event::KeyEventKind::Release,
209            ..
210        })
211    };
212    (keycode release Media($code:ident)) => {
213        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
214            code: $crate::crossterm::event::KeyCode::Media($code),
215            modifiers: $crate::crossterm::modifiers::NONE,
216            kind: $crate::crossterm::event::KeyEventKind::Release,
217            ..
218        })
219    };
220    (keycode release $mod:ident-Media($code:ident)) => {
221        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
222            code: $crate::crossterm::event::KeyCode::Media($code),
223            modifiers: $crate::crossterm::modifiers::$mod,
224            kind: $crate::crossterm::event::KeyEventKind::Release,
225            ..
226        })
227    };
228
229    (keycode release $code:ident) => {
230        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
231            code: $crate::crossterm::event::KeyCode::$code,
232            modifiers: $crate::crossterm::modifiers::NONE,
233            kind: $crate::crossterm::event::KeyEventKind::Release,
234            ..
235        })
236    };
237    (keycode release $mod:ident-$code:ident) => {
238        $crate::crossterm::event::Event::Key($crate::crossterm::event::KeyEvent {
239            code: $crate::crossterm::event::KeyCode::$code,
240            modifiers: $crate::crossterm::modifiers::$mod,
241            kind: $crate::crossterm::event::KeyEventKind::Release,
242            ..
243        })
244    };
245
246    (mouse down $button:ident for $col:ident, $row:ident ) => {
247        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
248            kind: $crate::crossterm::event::MouseEventKind::Down($crate::crossterm::event::MouseButton::$button),
249            column: $col,
250            row: $row,
251            modifiers: $crate::crossterm::modifiers::NONE,
252        })
253    };
254    (mouse down $mod:ident-$button:ident for $col:ident, $row:ident ) => {
255        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
256            kind: $crate::crossterm::event::MouseEventKind::Down($crate::crossterm::event::MouseButton::$button),
257            column: $col,
258            row: $row,
259            modifiers: $crate::crossterm::modifiers::$mod,
260        })
261    };
262    (mouse up $button:ident for $col:ident, $row:ident ) => {
263        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
264            kind: $crate::crossterm::event::MouseEventKind::Up($crate::crossterm::event::MouseButton::$button),
265            column: $col,
266            row: $row,
267            modifiers: $crate::crossterm::modifiers::NONE,
268        })
269    };
270    (mouse up $mod:ident-$button:ident for $col:ident, $row:ident ) => {
271        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
272            kind: $crate::crossterm::event::MouseEventKind::Up($crate::crossterm::event::MouseButton::$button),
273            column: $col,
274            row: $row,
275            modifiers: $crate::crossterm::modifiers::$mod,
276        })
277    };
278    (mouse drag $button:ident for $col:ident, $row:ident ) => {
279        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
280            kind: $crate::crossterm::event::MouseEventKind::Drag($crate::crossterm::event::MouseButton::$button),
281            column: $col,
282            row: $row,
283            modifiers: $crate::crossterm::modifiers::NONE,
284        })
285    };
286    (mouse drag $mod:ident-$button:ident for $col:ident, $row:ident ) => {
287        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
288            kind: $crate::crossterm::event::MouseEventKind::Drag($crate::crossterm::event::MouseButton::$button),
289            column: $col,
290            row: $row,
291            modifiers: $crate::crossterm::modifiers::$mod,
292        })
293    };
294
295
296    (mouse any for $mouse:ident) => {
297        $crate::crossterm::event::Event::Mouse($mouse)
298    };
299    (mouse any $mod:ident for $mouse:ident ) => {
300        $crate::crossterm::event::Event::Mouse($mouse @ $crate::crossterm::event::MouseEvent {
301            modifiers: $crate::crossterm::modifiers::$mod,
302            ..
303        })
304    };
305
306    (mouse moved ) => {
307        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
308            kind: $crate::crossterm::event::MouseEventKind::Moved,
309            modifiers: $crate::crossterm::modifiers::NONE,
310            ..
311        })
312    };
313    (mouse moved for $col:ident, $row:ident) => {
314        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
315            kind: $crate::crossterm::event::MouseEventKind::Moved,
316            column: $col,
317            row: $row,
318            modifiers: $crate::crossterm::modifiers::NONE,
319        })
320    };
321
322    (scroll $mod:ident down for $col:ident, $row:ident) => {
323        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
324            kind: $crate::crossterm::event::MouseEventKind::ScrollDown,
325            column: $col,
326            row: $row,
327            modifiers: $crate::crossterm::modifiers::$mod,
328        })
329    };
330    (scroll down for $col:ident, $row:ident) => {
331        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
332            kind: $crate::crossterm::event::MouseEventKind::ScrollDown,
333            column: $col,
334            row: $row,
335            modifiers: $crate::crossterm::modifiers::NONE,
336        })
337    };
338    (scroll down) => {
339        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
340            kind: $crate::crossterm::event::MouseEventKind::ScrollDown,
341            modifiers: $crate::crossterm::modifiers::NONE,
342            ..
343        })
344    };
345    (scroll $mod:ident up for $col:ident, $row:ident) => {
346        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
347            kind: $crate::crossterm::event::MouseEventKind::ScrollUp,
348            column: $col,
349            row: $row,
350            modifiers: $crate::crossterm::modifiers::$mod,
351        })
352    };
353    (scroll up for $col:ident, $row:ident) => {
354        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
355            kind: $crate::crossterm::event::MouseEventKind::ScrollUp,
356            column: $col,
357            row: $row,
358            modifiers: $crate::crossterm::modifiers::NONE,
359        })
360    };
361    (scroll up) => {
362        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
363            kind: $crate::crossterm::event::MouseEventKind::ScrollUp,
364            modifiers: $crate::crossterm::modifiers::NONE,
365            ..
366        })
367    };
368
369    //??
370    (scroll left for $col:ident, $row:ident) => {
371        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
372            kind: $crate::crossterm::event::MouseEventKind::ScrollLeft,
373            column: $col,
374            row: $row,
375            modifiers: $crate::crossterm::modifiers::NONE,
376        })
377    };
378    (scroll left) => {
379        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
380            kind: $crate::crossterm::event::MouseEventKind::ScrollLeft,
381            modifiers: $crate::crossterm::modifiers::NONE,
382            ..
383        })
384    };
385    //??
386    (scroll right for $col:ident, $row:ident) => {
387        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
388            kind: $crate::crossterm::event::MouseEventKind::ScrollRight,
389            column: $col,
390            row: $row,
391            modifiers: $crate::crossterm::modifiers::NONE,
392        })
393    };
394    (scroll right) => {
395        $crate::crossterm::event::Event::Mouse($crate::crossterm::event::MouseEvent {
396            kind: $crate::crossterm::event::MouseEventKind::ScrollRight,
397            modifiers: $crate::crossterm::modifiers::NONE,
398            ..
399        })
400    };
401
402    (resized) => {
403        $crate::crossterm::event::Event::Resize(_, _)
404    };
405    (resized for $cols:ident, $rows:ident ) => {
406        $crate::crossterm::event::Event::Resize($cols, $rows)
407    };
408    (focus_gained) => {
409        $crate::crossterm::event::Event::FocusGained
410    };
411    (focus_lost) => {
412        $crate::crossterm::event::Event::FocusLost
413    };
414    (paste $value:ident) => {
415        $crate::crossterm::event::Event::Paste($value)
416    };
417}