mirror of
https://github.com/zed-industries/zed.git
synced 2026-05-31 19:05:00 +07:00
git_graph: Wire up Vim mode navigation (#53609)
Added Vim mode navigation (`j`, `k`, `gg`, `G`) to the Git Graph view. [gitgraph-vim.webm](https://github.com/user-attachments/assets/b2dd31a5-deb0-48ab-a48d-8721ee500dad) 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 #53525 Release Notes: - Added vim mode navigation to git graph --------- Co-authored-by: Anthony Eid <anthony@zed.dev>
This commit is contained in:
parent
eced4eab77
commit
fdbdb1707d
2 changed files with 149 additions and 0 deletions
|
|
@ -1033,6 +1033,15 @@
|
|||
"enter": "menu::Cancel",
|
||||
},
|
||||
},
|
||||
{
|
||||
"context": "GitGraph",
|
||||
"bindings": {
|
||||
"j": "vim::MenuSelectNext",
|
||||
"k": "vim::MenuSelectPrevious",
|
||||
"shift-g": "menu::SelectLast",
|
||||
"g g": "menu::SelectFirst"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && ChangesList && !GitBranchSelector",
|
||||
"use_key_equivalents": true,
|
||||
|
|
|
|||
|
|
@ -5072,4 +5072,144 @@ mod tests {
|
|||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_git_graph_navigation(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
Path::new("/project"),
|
||||
serde_json::json!({
|
||||
".git": {},
|
||||
"file.txt": "content",
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut rng = StdRng::seed_from_u64(42);
|
||||
let commits = generate_random_commit_dag(&mut rng, 10, false);
|
||||
fs.set_graph_commits(Path::new("/project/.git"), commits);
|
||||
|
||||
let project = Project::test(fs.clone(), [Path::new("/project")], cx).await;
|
||||
cx.run_until_parked();
|
||||
|
||||
let repository = project.read_with(cx, |project, cx| {
|
||||
project
|
||||
.active_repository(cx)
|
||||
.expect("should have a repository")
|
||||
});
|
||||
|
||||
let (multi_workspace, cx) = cx.add_window_view(|window, cx| {
|
||||
workspace::MultiWorkspace::test_new(project.clone(), window, cx)
|
||||
});
|
||||
|
||||
let workspace_weak =
|
||||
multi_workspace.read_with(&*cx, |multi, _| multi.workspace().downgrade());
|
||||
|
||||
let git_graph = cx.new_window_entity(|window, cx| {
|
||||
GitGraph::new(
|
||||
repository.read(cx).id,
|
||||
project.read(cx).git_store().clone(),
|
||||
workspace_weak,
|
||||
None,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
||||
git_graph.update_in(cx, |graph, window, cx| {
|
||||
graph.focus_handle(cx).focus(window, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
||||
cx.draw(
|
||||
point(px(0.), px(0.)),
|
||||
gpui::size(px(1200.), px(800.)),
|
||||
|_, _| git_graph.clone().into_any_element(),
|
||||
);
|
||||
cx.run_until_parked();
|
||||
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
assert_eq!(graph.graph_data.commits.len(), 10);
|
||||
});
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
assert_eq!(graph.selected_entry_idx, None);
|
||||
});
|
||||
|
||||
git_graph.update_in(cx, |graph, window, cx| {
|
||||
graph.select_first(&menu::SelectFirst, window, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
assert_eq!(graph.selected_entry_idx, Some(0));
|
||||
});
|
||||
|
||||
git_graph.update_in(cx, |graph, window, cx| {
|
||||
graph.select_next(&menu::SelectNext, window, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
assert_eq!(graph.selected_entry_idx, Some(1));
|
||||
});
|
||||
|
||||
git_graph.update_in(cx, |graph, window, cx| {
|
||||
graph.select_prev(&menu::SelectPrevious, window, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
assert_eq!(graph.selected_entry_idx, Some(0));
|
||||
});
|
||||
|
||||
git_graph.update_in(cx, |graph, window, cx| {
|
||||
graph.select_last(&menu::SelectLast, window, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
assert_eq!(graph.selected_entry_idx, Some(9));
|
||||
});
|
||||
|
||||
git_graph.update_in(cx, |graph, window, cx| {
|
||||
graph.select_next(&menu::SelectNext, window, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
assert_eq!(graph.selected_entry_idx, Some(9));
|
||||
});
|
||||
|
||||
git_graph.update_in(cx, |graph, window, cx| {
|
||||
graph.select_prev(&menu::SelectPrevious, window, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
assert_eq!(graph.selected_entry_idx, Some(8));
|
||||
});
|
||||
|
||||
git_graph.update(cx, |graph, cx| {
|
||||
graph.selected_entry_idx = None;
|
||||
cx.notify();
|
||||
});
|
||||
cx.run_until_parked();
|
||||
git_graph.update_in(cx, |graph, window, cx| {
|
||||
graph.select_prev(&menu::SelectPrevious, window, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
assert_eq!(graph.selected_entry_idx, Some(0));
|
||||
});
|
||||
|
||||
git_graph.update(cx, |graph, cx| {
|
||||
graph.selected_entry_idx = None;
|
||||
cx.notify();
|
||||
});
|
||||
cx.run_until_parked();
|
||||
git_graph.update_in(cx, |graph, window, cx| {
|
||||
graph.select_next(&menu::SelectNext, window, cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
git_graph.read_with(&*cx, |graph, _| {
|
||||
assert_eq!(graph.selected_entry_idx, Some(0));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue