fix(ui): verify command shortcuts for runtime OS

This commit is contained in:
AnhNgoo
2026-10-28 08:39:37 +07:00
parent 6e7fb6ce0b
commit f77d70502a
2 changed files with 90 additions and 20 deletions
+37 -17
View File
@@ -20,6 +20,7 @@ pub(super) fn command_search(app: &mut SheetApp, ui: &mut egui::Ui, d: &mut Dial
d.focus_initialized = true;
}
let mac = ui.ctx().os() == egui::os::OperatingSystem::Mac;
let q = d.search.to_ascii_lowercase();
let cmds: Vec<(String, String, String, Option<&str>)> = app
.session
@@ -27,14 +28,7 @@ pub(super) fn command_search(app: &mut SheetApp, ui: &mut egui::Ui, d: &mut Dial
.into_iter()
.filter(|c| c.enabled)
.filter(|c| q.is_empty() || c.label.to_ascii_lowercase().contains(&q) || c.id.to_ascii_lowercase().contains(&q))
.map(|c| {
(
c.id.to_string(),
c.label.to_string(),
c.menu.join(" › "),
crate::widgets::tooltip_shortcut(c.label, cfg!(target_os = "macos")).or(c.shortcut),
)
})
.map(|c| (c.id.to_string(), c.label.to_string(), c.menu.join(" › "), command_search_shortcut(c.id, mac)))
.take(40)
.collect();
@@ -71,15 +65,6 @@ pub(super) fn command_search(app: &mut SheetApp, ui: &mut egui::Ui, d: &mut Dial
egui::ScrollArea::vertical().max_height(LIST_HEIGHT).auto_shrink([true, false]).show(ui, |ui| {
let scroll_area_width = ui.available_width();
for (i, (id, label, menu, shortcut)) in cmds.iter().enumerate() {
let shortcut = shortcut.map(|keys| {
if cfg!(target_os = "macos") {
keys.to_string()
} else if keys == "Ctrl+Cmd+V" {
"Ctrl+Alt+V".to_string()
} else {
keys.strip_prefix("Cmd+").map_or_else(|| keys.to_string(), |rest| format!("Ctrl+{rest}"))
}
});
let text = match shortcut {
Some(keys) => format!("{label} ({keys}) {menu}"),
None => format!("{label} {menu}"),
@@ -107,3 +92,38 @@ pub(super) fn command_search(app: &mut SheetApp, ui: &mut egui::Ui, d: &mut Dial
app.run_or_alert(&id, json!({}));
}
}
/// Only advertises shortcuts verified against the grid keymap and ribbon.
/// Commands without a confirmed binding are shown without a shortcut.
fn command_search_shortcut(id: &str, mac: bool) -> Option<&'static str> {
let (mac_keys, other_keys) = match id {
"file.new" => ("⌘N", Some("Ctrl+N")),
"file.open" => ("⌘O", Some("Ctrl+O")),
"file.save" => ("⌘S", Some("Ctrl+S")),
"file.saveAs" => ("⌘⇧S", Some("Ctrl+Shift+S")),
"file.close" => ("⌘W", Some("Ctrl+W")),
"edit.copy" => ("⌘C", Some("Ctrl+C")),
"edit.cut" => ("⌘X", Some("Ctrl+X")),
"edit.paste" => ("⌘V", Some("Ctrl+V")),
"edit.undo" => ("⌘Z", Some("Ctrl+Z")),
"edit.redo" => ("⌘Y", Some("Ctrl+Y")),
"edit.selectAll" => ("⌘A", Some("Ctrl+A")),
"edit.fillDown" => ("⌘D", Some("Ctrl+D")),
"edit.fillRight" => ("⌘R", Some("Ctrl+R")),
"home.bold" => ("⌘B", Some("Ctrl+B")),
"home.italic" => ("⌘I", Some("Ctrl+I")),
"home.underline" => ("⌘U", Some("Ctrl+U")),
"formulas.autoSum" => ("⌘⇧T", Some("Alt+=")),
"insert.table" => ("⌘T", Some("Ctrl+T")),
"data.filter" => ("⌘⇧F", Some("Ctrl+Shift+L")),
"edit.flashFill" => ("Control+E", Some("Ctrl+E")),
"edit.pasteSpecial" => ("Ctrl+Cmd+V", Some("Ctrl+Alt+V")),
"home.alignLeft" => ("⌘L", None),
"home.alignCenter" => ("⌘E", None),
"view.showObjects" => ("Ctrl+6", Some("Ctrl+6")),
"formulas.showFormulas" => ("⌘`", Some("Ctrl+`")),
_ => return None,
};
if mac { Some(mac_keys) } else { other_keys }
}
+53 -3
View File
@@ -93,13 +93,13 @@ fn command_search_shows_shortcuts_for_current_platform() {
h.state_mut().dialog.as_mut().unwrap().search = "bold".into();
h.run_steps(3);
let bold = if cfg!(target_os = "macos") { "Bold (⌘B)" } else { "Bold (Ctrl+B)" };
let bold = if h.ctx.os() == egui::os::OperatingSystem::Mac { "Bold (⌘B)" } else { "Bold (Ctrl+B)" };
h.get_by_label_contains(bold);
h.state_mut().dialog.as_mut().unwrap().search = "filter".into();
h.run_steps(3);
let filter = if cfg!(target_os = "macos") { "Filter (⌘⇧F)" } else { "Filter (Ctrl+Shift+L)" };
let filter = if h.ctx.os() == egui::os::OperatingSystem::Mac { "Filter (⌘⇧F)" } else { "Filter (Ctrl+Shift+L)" };
h.get_by_label_contains(filter);
}
@@ -117,7 +117,57 @@ fn command_search_shows_paste_special_shortcut() {
h.state_mut().dialog.as_mut().unwrap().search = "pasteSpecial".into();
h.run_steps(3);
let expected = if cfg!(target_os = "macos") { "Paste Special… (Ctrl+Cmd+V)" } else { "Paste Special… (Ctrl+Alt+V)" };
let expected = if h.ctx.os() == egui::os::OperatingSystem::Mac { "Paste Special… (Ctrl+Cmd+V)" } else { "Paste Special… (Ctrl+Alt+V)" };
h.get_by_label_contains(expected);
}
/// Checks both OS mappings on one host, including commands with conflicting keys.
#[test]
fn command_search_uses_runtime_os_and_verified_shortcuts() {
use egui::os::OperatingSystem;
for (os, bold, filter, flash, paste, left, center) in [
(
OperatingSystem::Windows,
"Bold (Ctrl+B)",
"Filter (Ctrl+Shift+L)",
"Flash Fill (Ctrl+E)",
"Paste Special… (Ctrl+Alt+V)",
"Align Left Home",
"Center Home",
),
(
OperatingSystem::Mac,
"Bold (⌘B)",
"Filter (⌘⇧F)",
"Flash Fill (Control+E)",
"Paste Special… (Ctrl+Cmd+V)",
"Align Left (⌘L)",
"Center (⌘E)",
),
] {
let mut h = harness();
h.ctx.set_os(os);
h.run_steps(2);
h.state_mut().session.execute("cell.set", json!({"cell": "C3", "input": "copied"})).unwrap();
h.state_mut().session.execute("edit.copy", json!({"range": "C3"})).unwrap();
h.state_mut().open_dialog("commandSearch", json!({}));
h.run_steps(6);
for (query, expected) in [
("bold", bold),
("filter", filter),
("edit.flashFill", flash),
("edit.pasteSpecial", paste),
("home.alignLeft", left),
("home.alignCenter", center),
] {
h.state_mut().dialog.as_mut().unwrap().search = query.into();
h.run_steps(3);
h.get_by_label_contains(expected);
}
}
}