diff --git a/crates/engine/src/macros/mod.rs b/crates/engine/src/macros/mod.rs index f500b9815..ecbe6f674 100644 --- a/crates/engine/src/macros/mod.rs +++ b/crates/engine/src/macros/mod.rs @@ -435,15 +435,19 @@ pub const RESERVED_SHORTCUTS: &[(char, &str)] = &[ ('Z', "Redo"), ]; -/// The letter of a macro shortcut: `"Ctrl+Shift+M"`, `"⌘⇧M"` and `"m"` all give `'M'`. `None` -/// when it is not one letter from A to Z. +/// The letter of a macro shortcut: `"Ctrl+Shift+M"`, `"Cmd+Shift+M"`, `"⌘⇧M"` and `"m"` all give +/// `'M'`. `None` when it is not one letter from A to Z, alone or after Ctrl+Shift (Cmd+Shift): +/// other modifiers (`"Ctrl+Alt+M"`) are refused rather than read as Ctrl+Shift. pub fn parse_shortcut(s: &str) -> Option { - let last = s.trim().rsplit(['+', '⇧', '⌘']).next()?.trim(); - let mut chars = last.chars(); - match (chars.next(), chars.next()) { - (Some(c), None) if c.is_ascii_alphabetic() => Some(c.to_ascii_uppercase()), - _ => None, - } + let letter = |t: &str| { + let mut chars = t.trim().chars(); + match (chars.next(), chars.next()) { + (Some(c), None) if c.is_ascii_alphabetic() => Some(c.to_ascii_uppercase()), + _ => None, + } + }; + let t = s.trim().to_ascii_lowercase(); + ["ctrl+shift+", "cmd+shift+", "⌘⇧"].iter().find_map(|p| t.strip_prefix(p)).map_or_else(|| letter(&t), letter) } /// How a shortcut is stored and shown: `Ctrl+Shift+M`. diff --git a/crates/engine/src/tests/macros.rs b/crates/engine/src/tests/macros.rs index 19a23a1ac..2903ac79a 100644 --- a/crates/engine/src/tests/macros.rs +++ b/crates/engine/src/tests/macros.rs @@ -2400,7 +2400,9 @@ fn shortcuts_parse_to_one_letter_and_avoid_reserved_and_taken_ones() { assert_eq!(parse_shortcut("Ctrl+Shift+M"), Some('M')); assert_eq!(parse_shortcut("⌘⇧k"), Some('K')); assert_eq!(parse_shortcut(" q "), Some('Q')); - for bad in ["Ctrl+Shift+F5", "Ctrl+Shift+", "", "Ctrl+Shift+é"] { + assert_eq!(parse_shortcut("cmd+shift+r"), Some('R')); + // Other modifiers are refused, not read as Ctrl+Shift. + for bad in ["Ctrl+Shift+F5", "Ctrl+Shift+", "", "Ctrl+Shift+é", "Ctrl+Alt+M", "Shift+M", "Alt+M", "Ctrl+M"] { assert_eq!(parse_shortcut(bad), None, "{bad}"); } assert_eq!(shortcut_text('m'), "Ctrl+Shift+M");