diff --git a/Cargo.lock b/Cargo.lock index f08ed4cd173f7aa68ad62b99a0c3f4692fde60e2..ea4070305367ca766c3ee889ab9f358daa4fbc68 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7221,6 +7221,7 @@ dependencies = [ "git", "git_ui", "gpui", + "menu", "project", "rand 0.9.2", "recent_projects", diff --git a/crates/git_graph/Cargo.toml b/crates/git_graph/Cargo.toml index b3bcbc4c726973dd4b212b630a043fca7ecb9912..518798279ddbd21cd95a044387204d6d64104dba 100644 --- a/crates/git_graph/Cargo.toml +++ b/crates/git_graph/Cargo.toml @@ -26,6 +26,7 @@ feature_flags.workspace = true git.workspace = true git_ui.workspace = true gpui.workspace = true +menu.workspace = true project.workspace = true settings.workspace = true smallvec.workspace = true diff --git a/crates/git_graph/src/git_graph.rs b/crates/git_graph/src/git_graph.rs index fb59826397d432c63479fbba550b9d5fadb72b13..284d5758f1d6ed0ede9bb4dd6de9818980fe6c8d 100644 --- a/crates/git_graph/src/git_graph.rs +++ b/crates/git_graph/src/git_graph.rs @@ -9,9 +9,10 @@ use git_ui::commit_tooltip::CommitAvatar; use gpui::{ AnyElement, App, Bounds, ClipboardItem, Context, Corner, DefiniteLength, ElementId, Entity, EventEmitter, FocusHandle, Focusable, FontWeight, Hsla, InteractiveElement, ParentElement, - PathBuilder, Pixels, Point, Render, ScrollWheelEvent, SharedString, Styled, Subscription, Task, - WeakEntity, Window, actions, anchored, deferred, point, px, + PathBuilder, Pixels, Point, Render, ScrollStrategy, ScrollWheelEvent, SharedString, Styled, + Subscription, Task, WeakEntity, Window, actions, anchored, deferred, point, px, }; +use menu::{SelectNext, SelectPrevious}; use project::{ Project, git_store::{CommitDataState, GitStoreEvent, Repository, RepositoryEvent}, @@ -844,6 +845,22 @@ impl GitGraph { .collect() } + fn select_prev(&mut self, _: &SelectPrevious, _window: &mut Window, cx: &mut Context) { + if let Some(selected_entry_idx) = &self.selected_entry_idx { + self.select_entry(selected_entry_idx.saturating_sub(1), cx); + } else { + self.select_entry(0, cx); + } + } + + fn select_next(&mut self, _: &SelectNext, window: &mut Window, cx: &mut Context) { + if let Some(selected_entry_idx) = &self.selected_entry_idx { + self.select_entry(selected_entry_idx.saturating_add(1), cx); + } else { + self.select_prev(&SelectPrevious, window, cx); + } + } + fn select_entry(&mut self, idx: usize, cx: &mut Context) { if self.selected_entry_idx == Some(idx) { return; @@ -851,6 +868,12 @@ impl GitGraph { self.selected_entry_idx = Some(idx); self.selected_commit_diff = None; + self.table_interaction_state.update(cx, |state, cx| { + state + .scroll_handle + .scroll_to_item(idx, ScrollStrategy::Nearest); + cx.notify(); + }); let Some(commit) = self.graph_data.commits.get(idx) else { return; @@ -1604,6 +1627,8 @@ impl Render for GitGraph { .bg(cx.theme().colors().editor_background) .key_context("GitGraph") .track_focus(&self.focus_handle) + .on_action(cx.listener(Self::select_prev)) + .on_action(cx.listener(Self::select_next)) .child(content) .children(self.context_menu.as_ref().map(|(menu, position, _)| { deferred(