mirror of
https://github.com/zed-industries/zed.git
synced 2026-08-22 07:24:18 +00:00
Fix docs preprocessor preferring parameterized keybindings over exact matches (#54593)
This PR fixes a bug with the docs pre-processor where it could match on parameterized versions of key binds before exact matches. I noticed this bug in the latest [parallel agent docs:](https://zed.dev/docs/ai/parallel-agents#switching-threads) <img width="717" height="110" alt="SCR-20260423-bhtn" src="https://github.com/user-attachments/assets/ea20b592-55c3-4e92-9c2e-ff821efacdd8" /> Here, the preprocessor is matching on the parameterized version first: ```json "ctrl-tab": "agents_sidebar::ToggleThreadSwitcher", "ctrl-shift-tab": ["agents_sidebar::ToggleThreadSwitcher", { "select_last": true }], ``` This bug surfaced in some other places in the docs as well: - https://zed.dev/docs/ai/agent-panel#multiple-threads - https://zed.dev/docs/finding-navigating#project-search - https://zed.dev/docs/finding-navigating#quick-reference - https://zed.dev/docs/migrate/webstorm#no-indexing - https://zed.dev/docs/migrate/webstorm#differences-in-user-interfaces Self-Review Checklist: - [X] I've reviewed my own diff for quality, security, and reliability - [N/A] Unsafe blocks (if any) have justifying comments - [N/A] 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 Release Notes: - N/A
This commit is contained in:
parent
96eb05166f
commit
d92c12e86e
1 changed files with 85 additions and 9 deletions
|
|
@ -336,17 +336,28 @@ fn is_missing_action(name: &str) -> bool {
|
|||
actions_available() && find_action_by_name(name).is_none()
|
||||
}
|
||||
|
||||
// Find the binding in reverse order, as the last binding takes precedence.
|
||||
// Find the last binding (in keymap order) for the given action.
|
||||
// Exact action matches are preferred over parameterized variants.
|
||||
fn find_binding_in_keymap(keymap: &KeymapFile, action: &str) -> Option<String> {
|
||||
keymap.sections().rev().find_map(|section| {
|
||||
section.bindings().rev().find_map(|(keystroke, a)| {
|
||||
if name_for_action(a.to_string()) == action {
|
||||
Some(keystroke.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
let find = |predicate: &dyn Fn(&str) -> bool| {
|
||||
keymap.sections().rev().find_map(|section| {
|
||||
section.bindings().rev().find_map(|(keystroke, a)| {
|
||||
if predicate(&a.to_string()) {
|
||||
Some(keystroke.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
// Look for exact match
|
||||
if let Some(binding) = find(&|a| a == action) {
|
||||
return Some(binding);
|
||||
}
|
||||
|
||||
// Look for parameterized match
|
||||
find(&|a| name_for_action(a.to_string()) == action)
|
||||
}
|
||||
|
||||
fn find_binding(os: Os, action: &str) -> Option<String> {
|
||||
|
|
@ -872,3 +883,68 @@ fn keymap_schema_for_actions(
|
|||
&deprecation_messages,
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn test_find_binding_prefers_exact_match_over_parameterized() {
|
||||
let keymap: KeymapFile = serde_json::from_value(json!([
|
||||
{
|
||||
"bindings": {
|
||||
"ctrl-tab": "agents_sidebar::ToggleThreadSwitcher",
|
||||
"ctrl-shift-tab": ["agents_sidebar::ToggleThreadSwitcher", { "select_last": true }]
|
||||
}
|
||||
}
|
||||
]))
|
||||
.unwrap();
|
||||
|
||||
let binding = find_binding_in_keymap(&keymap, "agents_sidebar::ToggleThreadSwitcher");
|
||||
assert_eq!(binding.as_deref(), Some("ctrl-tab"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_binding_falls_back_to_parameterized_match() {
|
||||
let keymap: KeymapFile = serde_json::from_value(json!([
|
||||
{
|
||||
"bindings": {
|
||||
"ctrl-shift-tab": ["agents_sidebar::ToggleThreadSwitcher", { "select_last": true }]
|
||||
}
|
||||
}
|
||||
]))
|
||||
.unwrap();
|
||||
|
||||
let binding = find_binding_in_keymap(&keymap, "agents_sidebar::ToggleThreadSwitcher");
|
||||
assert_eq!(binding.as_deref(), Some("ctrl-shift-tab"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_binding_prefers_exact_match_regardless_of_order() {
|
||||
let keymap: KeymapFile = serde_json::from_value(json!([
|
||||
{
|
||||
"bindings": {
|
||||
"ctrl-shift-tab": ["agents_sidebar::ToggleThreadSwitcher", { "select_last": true }],
|
||||
"ctrl-tab": "agents_sidebar::ToggleThreadSwitcher"
|
||||
}
|
||||
}
|
||||
]))
|
||||
.unwrap();
|
||||
|
||||
let binding = find_binding_in_keymap(&keymap, "agents_sidebar::ToggleThreadSwitcher");
|
||||
assert_eq!(binding.as_deref(), Some("ctrl-tab"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_binding_later_section_overrides_earlier() {
|
||||
let keymap: KeymapFile = serde_json::from_value(json!([
|
||||
{ "bindings": { "ctrl-a": "some::Action" } },
|
||||
{ "bindings": { "ctrl-b": "some::Action" } }
|
||||
]))
|
||||
.unwrap();
|
||||
|
||||
let binding = find_binding_in_keymap(&keymap, "some::Action");
|
||||
assert_eq!(binding.as_deref(), Some("ctrl-b"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue