Add a history list key context to the Git panel (#63689)
# Objective The Git Panel exposes the `ChangesList` key context while its list is focused, including when the History tab is active. This causes Changes-only keybindings to match in History and provides no context for History-specific bindings. This is a fresh submission of the revised change from #63669, as requested in that PR's discussion. Fixes #61012 ## Solution Select the list key context from the active Git Panel tab. Changes exposes `ChangesList`, while History exposes `HistoryList`. The shared `GitPanel` and `menu` contexts remain unchanged. Preserve compatible keyboard behavior by sharing navigation, confirmation, and cancellation bindings between `ChangesList` and `HistoryList` on macOS, Linux, Windows, and Vim. File, staging, restore, and commit-editor bindings remain exclusive to `ChangesList`. Extend the dispatch-context test to verify that the list contexts are mutually exclusive and absent while the commit editor is focused. ## Testing - `cargo fmt --package git_ui -- --check` - `./script/check-keymaps` - `git diff --check` - `cargo test -p git_ui test_dispatch_context_with_focus_states -- --nocapture` - `cargo test -p git_ui` (153 passed) - `cargo build -p zed` - Manually verified on macOS that History reports `HistoryList` without `ChangesList`, arrow navigation selects commits, and Enter opens the selected commit - Linux and Windows keymaps were updated and checked, but not manually exercised on those platforms ## 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 adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase The Keyboard Context view shows `GitPanel`, `menu`, and `HistoryList` while the History tab is focused. `ChangesList` is absent.  --- Release Notes: - Fixed Git Panel keybindings matching the Changes tab while the History tab is active.
This commit is contained in:
1 parent
998775e60d
commit
c2f6ece4e2
5 files changed
+81
-22
No files matched your search
@@ -1035,6 +1035,17 @@
|
||||
"ctrl-2": "git_panel::ActivateHistoryTab",
|
||||
},
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && (ChangesList || HistoryList) && !GitBranchSelector && !GitRepositorySelector",
|
||||
"bindings": {
|
||||
"up": "menu::SelectPrevious",
|
||||
"down": "menu::SelectNext",
|
||||
"shift-up": "menu::SelectPrevious",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"enter": "menu::Confirm",
|
||||
"escape": "menu::Cancel",
|
||||
},
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && ChangesList && !GitBranchSelector && !GitRepositorySelector",
|
||||
"bindings": {
|
||||
@@ -1042,9 +1053,6 @@
|
||||
"right": "git_panel::ExpandSelectedEntry",
|
||||
"up": "git_panel::PreviousEntry",
|
||||
"down": "git_panel::NextEntry",
|
||||
"shift-up": "menu::SelectPrevious",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"enter": "menu::Confirm",
|
||||
"alt-y": "git::StageFile",
|
||||
"alt-shift-y": "git::UnstageFile",
|
||||
"ctrl-alt-y": "git::ToggleStaged",
|
||||
@@ -1056,7 +1064,6 @@
|
||||
"alt-ctrl-shift-c": "workspace::CopyRelativePath",
|
||||
"tab": "git_panel::FocusEditor",
|
||||
"shift-tab": "git_panel::FocusEditor",
|
||||
"escape": "menu::Cancel",
|
||||
"alt-enter": "menu::SecondaryConfirm",
|
||||
"delete": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
"backspace": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
|
||||
@@ -1094,19 +1094,28 @@
|
||||
"cmd-2": "git_panel::ActivateHistoryTab",
|
||||
},
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && (ChangesList || HistoryList) && !GitBranchSelector && !GitRepositorySelector",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"up": "menu::SelectPrevious",
|
||||
"down": "menu::SelectNext",
|
||||
"shift-up": "menu::SelectPrevious",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"enter": "menu::Confirm",
|
||||
"escape": "menu::Cancel",
|
||||
},
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && ChangesList && !GitBranchSelector && !GitRepositorySelector",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"up": "git_panel::PreviousEntry",
|
||||
"down": "git_panel::NextEntry",
|
||||
"shift-up": "menu::SelectPrevious",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"cmd-up": "git_panel::FirstEntry",
|
||||
"cmd-down": "git_panel::LastEntry",
|
||||
"left": "git_panel::CollapseSelectedEntry",
|
||||
"right": "git_panel::ExpandSelectedEntry",
|
||||
"enter": "menu::Confirm",
|
||||
"cmd-alt-y": "git::ToggleStaged",
|
||||
"space": "git::ToggleStaged",
|
||||
"shift-space": "git::StageRange",
|
||||
@@ -1117,7 +1126,6 @@
|
||||
"alt-down": "git_panel::FocusEditor",
|
||||
"tab": "git_panel::FocusEditor",
|
||||
"shift-tab": "git_panel::FocusEditor",
|
||||
"escape": "menu::Cancel",
|
||||
"backspace": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
"delete": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
"cmd-backspace": ["git::RestoreFile", { "skip_prompt": true }],
|
||||
|
||||
@@ -1028,17 +1028,26 @@
|
||||
"ctrl-2": "git_panel::ActivateHistoryTab",
|
||||
},
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && (ChangesList || HistoryList) && !GitBranchSelector && !GitRepositorySelector",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"up": "menu::SelectPrevious",
|
||||
"down": "menu::SelectNext",
|
||||
"shift-up": "menu::SelectPrevious",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"enter": "menu::Confirm",
|
||||
"escape": "menu::Cancel",
|
||||
},
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && ChangesList && !GitBranchSelector && !GitRepositorySelector",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"up": "git_panel::PreviousEntry",
|
||||
"down": "git_panel::NextEntry",
|
||||
"shift-up": "menu::SelectPrevious",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"left": "git_panel::CollapseSelectedEntry",
|
||||
"right": "git_panel::ExpandSelectedEntry",
|
||||
"enter": "menu::Confirm",
|
||||
"alt-y": "git::StageFile",
|
||||
"shift-alt-y": "git::UnstageFile",
|
||||
"space": "git::ToggleStaged",
|
||||
@@ -1047,7 +1056,6 @@
|
||||
"ctrl-k ctrl-shift-c": "workspace::CopyRelativePath",
|
||||
"tab": "git_panel::FocusEditor",
|
||||
"shift-tab": "git_panel::FocusEditor",
|
||||
"escape": "menu::Cancel",
|
||||
"alt-enter": "menu::SecondaryConfirm",
|
||||
"delete": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
"backspace": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
|
||||
@@ -1123,17 +1123,23 @@
|
||||
"g g": "menu::SelectFirst",
|
||||
},
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && (ChangesList || HistoryList) && !GitBranchSelector && !GitRepositorySelector",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"j": "menu::SelectNext",
|
||||
"k": "menu::SelectPrevious",
|
||||
"g f": "menu::Confirm",
|
||||
},
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && ChangesList && !GitBranchSelector && !GitRepositorySelector",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"h": "git_panel::CollapseSelectedEntry",
|
||||
"j": "menu::SelectNext",
|
||||
"k": "menu::SelectPrevious",
|
||||
"l": "git_panel::ExpandSelectedEntry",
|
||||
"g g": "menu::SelectFirst",
|
||||
"shift-g": "menu::SelectLast",
|
||||
"g f": "menu::Confirm",
|
||||
"i": "git_panel::FocusEditor",
|
||||
"x": "git::ToggleStaged",
|
||||
"shift-x": "git::StageAll",
|
||||
|
||||
@@ -1858,12 +1858,15 @@ impl GitPanel {
|
||||
if self.commit_editor.read(cx).is_focused(window) {
|
||||
dispatch_context.add("CommitEditor");
|
||||
} else if self.focus_handle.contains_focused(window, cx) || self.context_menu.is_some() {
|
||||
// Preserve the panel's `ChangesList` context while a context menu
|
||||
// is open. Its focus handle may not appear as a descendant of the
|
||||
// panel until the next frame, so `FocusHandle::contains_focused`
|
||||
// would return `false`.
|
||||
// Preserve the panel's list context while a context menu is open.
|
||||
// Its focus handle may not appear as a descendant of the panel
|
||||
// until the next frame, so `FocusHandle::contains_focused` would
|
||||
// return `false`.
|
||||
dispatch_context.add("menu");
|
||||
dispatch_context.add("ChangesList");
|
||||
match self.active_tab {
|
||||
GitPanelTab::Changes => dispatch_context.add("ChangesList"),
|
||||
GitPanelTab::History => dispatch_context.add("HistoryList"),
|
||||
}
|
||||
}
|
||||
|
||||
dispatch_context
|
||||
@@ -13506,6 +13509,10 @@ mod tests {
|
||||
!context.contains("ChangesList"),
|
||||
"should not have ChangesList context when commit editor is focused"
|
||||
);
|
||||
assert!(
|
||||
!context.contains("HistoryList"),
|
||||
"should not have HistoryList context when commit editor is focused"
|
||||
);
|
||||
});
|
||||
|
||||
// Case 2: Focus the panel's focus handle directly — should have "menu" and "ChangesList".
|
||||
@@ -13530,13 +13537,36 @@ mod tests {
|
||||
context.contains("ChangesList"),
|
||||
"should have ChangesList context when changes list is focused"
|
||||
);
|
||||
assert!(
|
||||
!context.contains("HistoryList"),
|
||||
"should not have HistoryList context when changes list is focused"
|
||||
);
|
||||
assert!(
|
||||
!context.contains("CommitEditor"),
|
||||
"should not have CommitEditor context when changes list is focused"
|
||||
);
|
||||
});
|
||||
|
||||
// Case 3: Switch back to commit editor and verify context switches correctly
|
||||
// Case 3: Switch to the History tab and verify its list context.
|
||||
panel.update_in(cx, |panel, window, cx| {
|
||||
panel.active_tab = GitPanelTab::History;
|
||||
let context = panel.dispatch_context(window, cx);
|
||||
assert!(
|
||||
context.contains("menu"),
|
||||
"should have menu context when history list is focused"
|
||||
);
|
||||
assert!(
|
||||
context.contains("HistoryList"),
|
||||
"should have HistoryList context when history list is focused"
|
||||
);
|
||||
assert!(
|
||||
!context.contains("ChangesList"),
|
||||
"should not have ChangesList context when history list is focused"
|
||||
);
|
||||
panel.active_tab = GitPanelTab::Changes;
|
||||
});
|
||||
|
||||
// Case 4: Switch back to commit editor and verify context switches correctly
|
||||
panel.update_in(cx, |panel, window, cx| {
|
||||
panel.focus_editor(&FocusEditor, window, cx);
|
||||
});
|
||||
@@ -13553,7 +13583,7 @@ mod tests {
|
||||
);
|
||||
});
|
||||
|
||||
// Case 4: Re-focus changes list and verify it transitions back correctly
|
||||
// Case 5: Re-focus changes list and verify it transitions back correctly
|
||||
panel.update_in(cx, |panel, window, cx| {
|
||||
panel.focus_handle.focus(window, cx);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user