From d4163c70311e90489e2a94d7647410a4c51d5e94 Mon Sep 17 00:00:00 2001 From: galuis116 <116897328+galuis116@users.noreply.github.com> Date: Wed, 22 Apr 2026 10:12:32 -0700 Subject: [PATCH] command_palette: Fix showing keybinding in footer actions on zero matches (#54519) Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Closes #54517 Release Notes: - Fixed Command Palette behavior where footer actions could still route to a fallback hidden command when search returned no matches. --- crates/command_palette/src/command_palette.rs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index d0c7f052f4de15f831afd0724bac7e6975154a41..68d04537a0261c6383b8a53bf15341c77568b055 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -354,6 +354,9 @@ impl CommandPaletteDelegate { } fn selected_command(&self) -> Option<&Command> { + if self.matches.is_empty() { + return None; + } let action_ix = self .matches .get(self.selected_ix) @@ -556,6 +559,9 @@ impl PickerDelegate for CommandPaletteDelegate { fn confirm(&mut self, secondary: bool, window: &mut Window, cx: &mut Context>) { if secondary { + if self.matches.is_empty() { + return; + } let Some(selected_command) = self.selected_command() else { return; }; @@ -859,6 +865,33 @@ mod tests { assert!(palette.delegate.matches.is_empty()) }); } + + #[gpui::test] + async fn test_selected_command_none_when_no_matches(cx: &mut TestAppContext) { + let app_state = init_test(cx); + let project = Project::test(app_state.fs.clone(), [], cx).await; + let (multi_workspace, cx) = + cx.add_window_view(|window, cx| MultiWorkspace::test_new(project.clone(), window, cx)); + let workspace = multi_workspace.read_with(cx, |mw, _| mw.workspace().clone()); + + cx.simulate_keystrokes("cmd-shift-p"); + let picker = workspace.update(cx, |workspace, cx| { + workspace + .active_modal::(cx) + .unwrap() + .read(cx) + .picker + .clone() + }); + + cx.simulate_input("definitely-no-command-should-match-this"); + cx.background_executor.run_until_parked(); + + picker.read_with(cx, |picker, _cx| { + assert!(picker.delegate.matches.is_empty()); + assert!(picker.delegate.selected_command().is_none()); + }); + } #[gpui::test] async fn test_normalized_matches(cx: &mut TestAppContext) { let app_state = init_test(cx);