diff --git a/crates/ui-egui/src/dialogs/command_search.rs b/crates/ui-egui/src/dialogs/command_search.rs
--- a/crates/ui-egui/src/dialogs/command_search.rs
+++ b/crates/ui-egui/src/dialogs/command_search.rs
@@ -20,13 +20,20 @@ pub(super) fn command_search(app: &mut SheetApp, ui: &mut egui::Ui, d: &mut Dial
     }
 
     let q = d.search.to_ascii_lowercase();
-    let cmds: Vec<(String, String, String)> = app
+    let cmds: Vec<(String, String, String, Option<&str>)> = app
         .session
         .commands()
         .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(" › ")))
+        .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),
+            )
+        })
         .take(40)
         .collect();
 
@@ -62,8 +69,13 @@ 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)) in cmds.iter().enumerate() {
-            let r = ui.add(egui::Button::selectable(i == d.list_index, format!("{label}    {menu}")).min_size(vec2(scroll_area_width, 20.0)));
+        for (i, (id, label, menu, shortcut)) in cmds.iter().enumerate() {
+            let shortcut = shortcut.map(|keys| if cfg!(target_os = "macos") { keys.to_string() } else { keys.replace("Cmd+", "Ctrl+") });
+            let text = match shortcut {
+                Some(keys) => format!("{label}  ({keys})    {menu}"),
+                None => format!("{label}    {menu}"),
+            };
+            let r = ui.add(egui::Button::selectable(i == d.list_index, text).truncate().min_size(vec2(scroll_area_width, 20.0)));
 
             if (down || up || home || end || pgup || pgdn) && i == d.list_index && !ui.clip_rect().contains_rect(r.rect) {
                 r.scroll_to_me(Some(if down || end || pgdn { egui::Align::Max } else { egui::Align::Min }));
diff --git a/crates/ui-egui/tests/it/dialog_focus.rs b/crates/ui-egui/tests/it/dialog_focus.rs
--- a/crates/ui-egui/tests/it/dialog_focus.rs
+++ b/crates/ui-egui/tests/it/dialog_focus.rs
@@ -2,6 +2,7 @@
 //! column width without clicking into the field first.
 
 use egui::{Event, Key, vec2};
+use egui_kittest::kittest::Queryable;
 use gridcraft_engine::Session;
 use gridcraft_engine::core::CellRef;
 use gridcraft_ui_egui::SheetApp;
@@ -81,3 +82,22 @@ fn command_search_arrow_and_page_keys_move_the_selection_and_keep_the_search_foc
     assert!(after_page > 2, "PageDown moved past the third row, got {after_page}");
     assert!(h.ctx.memory(|m| m.focused()).is_some(), "the search field kept focus");
 }
+
+#[test]
+fn command_search_shows_shortcuts_for_current_platform() {
+    let mut h = harness();
+    h.state_mut().open_dialog("commandSearch", json!({}));
+    h.run_steps(6);
+
+    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)" };
+    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)" };
+    h.get_by_label_contains(filter);
+}
