opencode_voice/input/
hotkey.rs1#[cfg(target_os = "macos")]
9#[path = "hotkey_macos.rs"]
10mod platform;
11
12#[cfg(target_os = "linux")]
13#[path = "hotkey_linux.rs"]
14mod platform;
15
16pub use platform::GlobalHotkey;
19
20pub fn format_key_name(input: &str) -> String {
22 input
23 .split('_')
24 .map(|word| {
25 let mut chars = word.chars();
26 match chars.next() {
27 None => String::new(),
28 Some(c) => c.to_uppercase().to_string() + chars.as_str(),
29 }
30 })
31 .collect::<Vec<_>>()
32 .join(" ")
33}
34
35pub fn list_key_names() -> Vec<&'static str> {
40 let mut names: Vec<&'static str> = platform::get_key_map().keys().copied().collect();
41 names.sort();
42 names
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn test_format_key_name_right_option() {
51 assert_eq!(format_key_name("right_option"), "Right Option");
52 }
53
54 #[test]
55 fn test_format_key_name_f13() {
56 assert_eq!(format_key_name("f13"), "F13");
57 }
58
59 #[test]
60 fn test_format_key_name_numpad_enter() {
61 assert_eq!(format_key_name("numpad_enter"), "Numpad Enter");
62 }
63
64 #[test]
65 fn test_format_key_name_space() {
66 assert_eq!(format_key_name("space"), "Space");
67 }
68
69 #[test]
70 fn test_list_key_names_sorted() {
71 let names = list_key_names();
72 assert!(!names.is_empty());
73 assert!(names.windows(2).all(|w| w[0] <= w[1]));
74 assert!(names.contains(&"right_option"));
75 assert!(names.contains(&"space"));
76 assert!(names.contains(&"f1"));
77 }
78
79 #[test]
80 fn test_key_map_has_60_plus_entries() {
81 let names = list_key_names();
82 assert!(
83 names.len() >= 60,
84 "KEY_MAP should have at least 60 entries, has {}",
85 names.len()
86 );
87 }
88
89 #[test]
90 fn test_list_key_names_includes_section() {
91 let names = list_key_names();
92 assert!(names.contains(&"section"));
93 }
94
95 #[test]
96 fn test_list_key_names_includes_numpad_clear() {
97 let names = list_key_names();
98 assert!(names.contains(&"numpad_clear"));
99 }
100}