1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! Classifying a key press: command chord versus plain typed character.
//!
//! The `AltGr` distinction lives here. crossterm reports `AltGr` as
//! `Control + Alt`, so a naive CONTROL check would swallow the characters it
//! types - which is why both predicates compare modifiers exactly.
use ;
/// Whether `key` is a Ctrl **command** chord rather than a typed character.
///
/// A command requires Control *without* Alt: on many keyboards (e.g. German)
/// `AltGr` is reported as `Control + Alt` and produces real characters (`\`,
/// `@`, `[`, `]`, `|`, ...), so those must type, not be swallowed as a chord.
///
/// # Examples
///
/// ```
/// use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
/// use ratada::input::is_command;
///
/// let ctrl_s = KeyEvent::new(KeyCode::Char('s'), KeyModifiers::CONTROL);
/// assert!(is_command(ctrl_s));
///
/// let alt_gr = KeyEvent::new(
/// KeyCode::Char('\\'),
/// KeyModifiers::CONTROL | KeyModifiers::ALT,
/// );
/// assert!(!is_command(alt_gr));
/// ```
/// Whether `key` is a bare printable character: one that has to reach a text
/// field, or trigger a plain single-letter binding, rather than a chord.
///
/// The counterpart of [`is_command`], and deliberately stricter than its
/// negation: this also excludes `AltGr` (`Control + Alt`) and plain `Alt`,
/// which do produce characters but never a bare one. A widget matching a plain
/// letter (`y` to confirm, `j` to move) must gate on this, or both `Ctrl+Y`
/// and `AltGr+Y` silently answer the dialog. `Shift` stays allowed: it is what
/// makes the character uppercase.
///
/// # Examples
///
/// ```
/// use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
/// use ratada::input::is_bare_character;
///
/// let plain = KeyEvent::new(KeyCode::Char('y'), KeyModifiers::NONE);
/// assert!(is_bare_character(plain));
///
/// // Shift only decides the character's case.
/// let shifted = KeyEvent::new(KeyCode::Char('Y'), KeyModifiers::SHIFT);
/// assert!(is_bare_character(shifted));
///
/// let ctrl_y = KeyEvent::new(KeyCode::Char('y'), KeyModifiers::CONTROL);
/// assert!(!is_bare_character(ctrl_y));
///
/// let alt_gr = KeyEvent::new(
/// KeyCode::Char('@'),
/// KeyModifiers::CONTROL | KeyModifiers::ALT,
/// );
/// assert!(!is_bare_character(alt_gr));
///
/// // Alt alone is a chord too, and it is the only case the `Control` half of
/// // the check does not already cover.
/// let alt_y = KeyEvent::new(KeyCode::Char('y'), KeyModifiers::ALT);
/// assert!(!is_bare_character(alt_y));
///
/// // Not a character at all.
/// let enter = KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE);
/// assert!(!is_bare_character(enter));
/// ```