Shift+F3 runs Change Case again, not Find Previous (#186) (#221)

* Shift+F3 runs Change Case again, not Find Previous (#186)

edit.findPrevious and format.changeCase were both bound to Shift+F3.
Registry::by_shortcut returns the first match, so Find Previous won
and Change Case never ran from the keyboard. Find Previous keeps
Mod+Shift+G. A new test fails if any two commands share a shortcut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Contributors: credit vangel76 by their GitHub profile name

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
Valentin Klein 2026-10-10 15:27:11 +02:00 committed by GitHub
parent 58ae1d5685
commit 919d74bee6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 19 additions and 1 deletions

View File

@ -29,3 +29,6 @@ sync_github_name = false
[people.saeedemperor]
real_name = "Saeed Azarehgar"
[people.vangel76]
sync_github_name = true

View File

@ -37,7 +37,7 @@ pub fn specs() -> Vec<CommandSpec> {
.params(r#"{"text": string, "matchCase"?: bool, "wholeWord"?: bool, "regex"?: bool}"#)
.pure(),
CommandSpec::new("edit.findNext", "Find Next", "Home › Editing › Find", |s, _| step(s, 1)).key("Mod+G / F3").pure(),
CommandSpec::new("edit.findPrevious", "Find Previous", "Home › Editing › Find", |s, _| step(s, -1)).key("Mod+Shift+G / Shift+F3").pure(),
CommandSpec::new("edit.findPrevious", "Find Previous", "Home › Editing › Find", |s, _| step(s, -1)).key("Mod+Shift+G").pure(),
CommandSpec::new("edit.replace", "Replace", "Home › Editing", replace).key("Mod+H").params(r#"{"text": string, "with": string}"#),
CommandSpec::new("edit.replaceAll", "Replace All", "Home › Editing › Replace", replace_all)
.params(r#"{"text": string, "with": string, "matchCase"?: bool, "wholeWord"?: bool, "regex"?: bool}"#),

View File

@ -36,6 +36,21 @@ fn every_command_has_unique_id() {
assert!(n > 150, "{n} commands");
}
#[test]
fn every_shortcut_runs_one_command() {
// `by_shortcut` takes the first match, so a shared key silently shadows the later command (#186).
let reg = cmd::registry();
let mut seen = std::collections::HashMap::new();
for c in reg.all() {
for k in c.shortcut.split(" / ").filter(|k| !k.is_empty()) {
if let Some(other) = seen.insert(k.to_ascii_lowercase(), c.id) {
panic!("{k} is bound to both {other} and {}", c.id);
}
}
}
assert_eq!(reg.by_shortcut("Shift+F3").map(|c| c.id), Some("format.changeCase"));
}
#[test]
fn typing_enter_undo() {
let mut s = s();