mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +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",
|
"enter": "menu::Cancel",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"context": "GitGraph",
|
||||||
|
"bindings": {
|
||||||
|
"j": "vim::MenuSelectNext",
|
||||||
|
"k": "vim::MenuSelectPrevious",
|
||||||
|
"shift-g": "menu::SelectLast",
|
||||||
|
"g g": "menu::SelectFirst"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"context": "GitPanel && ChangesList && !GitBranchSelector",
|
"context": "GitPanel && ChangesList && !GitBranchSelector",
|
||||||
"use_key_equivalents": true,
|
"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