From cc3b5c729e71ddd697ca7cf93e5e46e00885e1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Marcos?= Date: Thu, 27 Feb 2025 14:19:44 -0300 Subject: [PATCH] Keep cursor at top when diff view is first opened (#25682) Previously, we had the cursor at the bottom while the scroll stayed at the top. Now, if you run `git: diff`, the cursor will also be at the top. The cursor moving to the end was possibly a side-effect of using `Bias::Right` for selections. --- Release Notes: - N/A Co-authored-by: Max Brunsfeld --- crates/git_ui/src/project_diff.rs | 39 ++++++++++++++++++------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/crates/git_ui/src/project_diff.rs b/crates/git_ui/src/project_diff.rs index a5c72df4f8..22096ca999 100644 --- a/crates/git_ui/src/project_diff.rs +++ b/crates/git_ui/src/project_diff.rs @@ -106,7 +106,7 @@ impl ProjectDiff { }; if let Some(entry) = entry { project_diff.update(cx, |project_diff, cx| { - project_diff.scroll_to(entry, window, cx); + project_diff.move_to_entry(entry, window, cx); }) } } @@ -168,7 +168,7 @@ impl ProjectDiff { } } - pub fn scroll_to( + pub fn move_to_entry( &mut self, entry: GitStatusEntry, window: &mut Window, @@ -189,16 +189,16 @@ impl ProjectDiff { let path_key = PathKey::namespaced(namespace, entry.repo_path.0.clone()); - self.scroll_to_path(path_key, window, cx) + self.move_to_path(path_key, window, cx) } - fn scroll_to_path(&mut self, path_key: PathKey, window: &mut Window, cx: &mut Context) { + fn move_to_path(&mut self, path_key: PathKey, window: &mut Window, cx: &mut Context) { if let Some(position) = self.multibuffer.read(cx).location_for_path(&path_key, cx) { self.editor.update(cx, |editor, cx| { editor.change_selections(Some(Autoscroll::focused()), window, cx, |s| { s.select_ranges([position..position]); }) - }) + }); } else { self.pending_scroll = Some(path_key); } @@ -385,21 +385,28 @@ impl ProjectDiff { .collect::>() }; - let is_excerpt_newly_added = self.multibuffer.update(cx, |multibuffer, cx| { - multibuffer.set_excerpts_for_path( + let (was_empty, is_excerpt_newly_added) = self.multibuffer.update(cx, |multibuffer, cx| { + let was_empty = multibuffer.is_empty(); + let is_newly_added = multibuffer.set_excerpts_for_path( path_key.clone(), buffer, diff_hunk_ranges, editor::DEFAULT_MULTIBUFFER_CONTEXT, cx, - ) + ); + (was_empty, is_newly_added) }); - if is_excerpt_newly_added && diff_buffer.file_status.is_deleted() { - self.editor.update(cx, |editor, cx| { + self.editor.update(cx, |editor, cx| { + if was_empty { + editor.change_selections(None, window, cx, |selections| { + selections.select_ranges([0..0]) + }); + } + if is_excerpt_newly_added && diff_buffer.file_status.is_deleted() { editor.fold_buffer(snapshot.text.remote_id(), cx) - }); - } + } + }); if self.multibuffer.read(cx).is_empty() && self @@ -415,7 +422,7 @@ impl ProjectDiff { }); } if self.pending_scroll.as_ref() == Some(&path_key) { - self.scroll_to_path(path_key, window, cx); + self.move_to_path(path_key, window, cx); } } @@ -995,13 +1002,13 @@ mod tests { cx, &" - foo - + FOO - ˇ" + + ˇFOO + " .unindent(), ); editor.update_in(cx, |editor, window, cx| { - editor.restore_file(&Default::default(), window, cx); + editor.git_restore(&Default::default(), window, cx); }); fs.with_git_state(path!("/project/.git").as_ref(), true, |state| { state.statuses = HashMap::default();