From 88d12750feaa05429ec64ac5fe96f885c1c1f0bf Mon Sep 17 00:00:00 2001 From: David Alecrim <35930364+davidalecrim1@users.noreply.github.com> Date: Tue, 31 Mar 2026 16:09:16 -0300 Subject: [PATCH] command_palette: Fix keymap editor not matching actions with underscored namespaces (#50415) Closes https://github.com/zed-industries/zed/issues/50223 ## Summary When clicking **Change Keybinding** from the command palette on an action whose namespace contains underscores (e.g. `terminal_panel::Toggle`, `project_panel::ToggleFocus`), the keymap editor showed **"No matches found for the provided query"**. Actions without underscores (e.g. `zed::OpenLog`) worked fine. I opened this issue for this https://github.com/zed-industries/zed/issues/50223, but took the liberty of sending a PR. **Root cause:** `normalize_action_query` preserved underscores in the query, but the search candidates are built with `humanize_action_name` which converts underscores to spaces. The fuzzy matcher looked for `_` in a candidate like `"terminal panel: toggle"` where it doesn't exist, so matching always failed. **Fix:** `normalize_action_query` now converts underscores to spaces before the deduplication checks, consistent with `humanize_action_name`. This also correctly collapses consecutive underscores with adjacent spaces. All three call sites of `normalize_action_query` (command palette search, keymap editor filter, action completion provider) match against humanized candidates, so the fix improves consistency across all of them. ## Before (Left) / After (Right) Screenshot 2026-02-28 at 17 56 05 Screenshot 2026-02-28 at 17 55 38 Release Notes: - Fixed keymap editor showing no results when opening "Change Keybinding" from the command palette for actions with underscores in their namespace (e.g. `terminal_panel::Toggle`, `project_panel::ToggleFocus`) --- crates/command_palette/src/command_palette.rs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/crates/command_palette/src/command_palette.rs b/crates/command_palette/src/command_palette.rs index 90ed7d0d3518aa4f6d49bb4cc18cbf3c275ce7c5..4a80740c3765f25ee878a60fa061c17e3a795b5f 100644 --- a/crates/command_palette/src/command_palette.rs +++ b/crates/command_palette/src/command_palette.rs @@ -43,24 +43,28 @@ pub struct CommandPalette { picker: Entity>, } -/// Removes subsequent whitespace characters and double colons from the query. +/// Removes subsequent whitespace characters and double colons from the query, and converts +/// underscores to spaces. /// /// This improves the likelihood of a match by either humanized name or keymap-style name. +/// Underscores are converted to spaces because `humanize_action_name` converts them to spaces +/// when building the search candidates (e.g. `terminal_panel::Toggle` -> `terminal panel: toggle`). pub fn normalize_action_query(input: &str) -> String { let mut result = String::with_capacity(input.len()); let mut last_char = None; for char in input.trim().chars() { - match (last_char, char) { + let normalized_char = if char == '_' { ' ' } else { char }; + match (last_char, normalized_char) { (Some(':'), ':') => continue, - (Some(last_char), char) if last_char.is_whitespace() && char.is_whitespace() => { + (Some(last_char), c) if last_char.is_whitespace() && c.is_whitespace() => { continue; } _ => { - last_char = Some(char); + last_char = Some(normalized_char); } } - result.push(char); + result.push(normalized_char); } result @@ -775,6 +779,14 @@ mod tests { normalize_action_query("editor: :GoToDefinition"), "editor: :GoToDefinition" ); + assert_eq!( + normalize_action_query("terminal_panel::Toggle"), + "terminal panel:Toggle" + ); + assert_eq!( + normalize_action_query("project_panel::ToggleFocus"), + "project panel:ToggleFocus" + ); } #[gpui::test]