返回 CodeWhale
key_hint.rs
根目录 / crates / tui / src / tui / widgets / key_hint.rs
1 //! Platform-aware Alt labels and AltGr disambiguation for terminal shortcuts.
2 //!
3 //! Windows keyboard layouts commonly report AltGr as `Ctrl+Alt`. The helpers
4 //! here keep those glyph-producing events from triggering Ctrl/Alt shortcuts,
5 //! while preserving the platform-specific label used by hotbar hints.
6
7 use crossterm::event::KeyModifiers;
8
9 #[cfg(test)]
10 const ALT_PREFIX: &str = "⌥+";
11 #[cfg(all(not(test), target_os = "macos"))]
12 const ALT_PREFIX: &str = "⌥+";
13 #[cfg(all(not(test), not(target_os = "macos")))]
14 const ALT_PREFIX: &str = "alt+";
15
16 /// Platform-specific prefix for `Alt`-modified chords, matching how the rest
17 /// of the TUI labels them: `⌥+` on macOS and `alt+` on Linux/Windows.
18 pub fn alt_prefix() -> &'static str {
19 ALT_PREFIX
20 }
21
22 /// `true` if `mods` carries Ctrl or Alt, except for the AltGr Ctrl+Alt
23 /// combination on Windows.
24 pub fn has_ctrl_or_alt(mods: KeyModifiers) -> bool {
25 (mods.contains(KeyModifiers::CONTROL) || mods.contains(KeyModifiers::ALT)) && !is_altgr(mods)
26 }
27
28 /// On Windows, AltGr is delivered as `Ctrl+Alt`. Crossterm does not expose a
29 /// portable left-vs-right modifier distinction, so treat that exact pair as
30 /// AltGr. Other platforms do not need the disambiguation.
31 #[cfg(windows)]
32 #[inline]
33 pub fn is_altgr(mods: KeyModifiers) -> bool {
34 mods.contains(KeyModifiers::ALT) && mods.contains(KeyModifiers::CONTROL)
35 }
36
37 #[cfg(not(windows))]
38 #[inline]
39 pub fn is_altgr(_mods: KeyModifiers) -> bool {
40 false
41 }
42
43 #[cfg(test)]
44 mod tests {
45 use super::*;
46
47 #[test]
48 fn altgr_only_fires_on_windows() {
49 let altgr_mods = KeyModifiers::ALT | KeyModifiers::CONTROL;
50 if cfg!(windows) {
51 assert!(is_altgr(altgr_mods));
52 assert!(!has_ctrl_or_alt(altgr_mods));
53 } else {
54 assert!(!is_altgr(altgr_mods));
55 assert!(has_ctrl_or_alt(altgr_mods));
56 }
57 assert!(!is_altgr(KeyModifiers::ALT));
58 assert!(has_ctrl_or_alt(KeyModifiers::ALT));
59 assert!(!has_ctrl_or_alt(KeyModifiers::NONE));
60 }
61
62 #[test]
63 fn alt_prefix_uses_deterministic_test_spelling() {
64 assert_eq!(alt_prefix(), "⌥+");
65 }
66 }
67
67 lines RUST