From 20460239a027ec80f683719e5035120780d14e0d Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 14 Feb 2025 11:18:07 -0700 Subject: [PATCH] Fix scroll to top on multibuffer save (#24885) Co-Authored-By: Cole Closes #ISSUE Release Notes: - N/A --------- Co-authored-by: Cole --- crates/git_ui/src/project_diff.rs | 28 +++++++------------ crates/multi_buffer/src/multi_buffer.rs | 9 ++++-- crates/multi_buffer/src/multi_buffer_tests.rs | 6 ++-- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/crates/git_ui/src/project_diff.rs b/crates/git_ui/src/project_diff.rs index 8b8907ecbe5e68..87098c374c0cc9 100644 --- a/crates/git_ui/src/project_diff.rs +++ b/crates/git_ui/src/project_diff.rs @@ -3,7 +3,7 @@ use std::any::{Any, TypeId}; use anyhow::Result; use buffer_diff::BufferDiff; use collections::HashSet; -use editor::{scroll::Autoscroll, Editor, EditorEvent}; +use editor::{scroll::Autoscroll, Editor, EditorEvent, ToPoint}; use feature_flags::FeatureFlagViewExt; use futures::StreamExt; use gpui::{ @@ -180,13 +180,6 @@ impl ProjectDiff { }; let repo = git_repo.read(cx); - let Some(abs_path) = repo - .repo_path_to_project_path(&entry.repo_path) - .and_then(|project_path| self.project.read(cx).absolute_path(&project_path, cx)) - else { - return; - }; - let namespace = if repo.has_conflict(&entry.repo_path) { CONFLICT_NAMESPACE } else if entry.status.is_created() { @@ -195,7 +188,7 @@ impl ProjectDiff { TRACKED_NAMESPACE }; - let path_key = PathKey::namespaced(namespace, &abs_path); + let path_key = PathKey::namespaced(namespace, entry.repo_path.0.clone()); self.scroll_to_path(path_key, window, cx) } @@ -222,7 +215,12 @@ impl ProjectDiff { match event { EditorEvent::ScrollPositionChanged { .. } => editor.update(cx, |editor, cx| { let anchor = editor.scroll_manager.anchor().anchor; - let Some((_, buffer, _)) = self.multibuffer.read(cx).excerpt_containing(anchor, cx) + let multibuffer = self.multibuffer.read(cx); + let snapshot = multibuffer.snapshot(cx); + let mut point = anchor.to_point(&snapshot); + point.row = (point.row + 1).min(snapshot.max_row().0); + + let Some((_, buffer, _)) = self.multibuffer.read(cx).excerpt_containing(point, cx) else { return; }; @@ -266,9 +264,6 @@ impl ProjectDiff { let Some(project_path) = repo.repo_path_to_project_path(&entry.repo_path) else { continue; }; - let Some(abs_path) = self.project.read(cx).absolute_path(&project_path, cx) else { - continue; - }; let namespace = if repo.has_conflict(&entry.repo_path) { CONFLICT_NAMESPACE } else if entry.status.is_created() { @@ -276,7 +271,7 @@ impl ProjectDiff { } else { TRACKED_NAMESPACE }; - let path_key = PathKey::namespaced(namespace, &abs_path); + let path_key = PathKey::namespaced(namespace, entry.repo_path.0.clone()); previous_paths.remove(&path_key); let load_buffer = self @@ -344,12 +339,9 @@ impl ProjectDiff { .contains_focused(window, cx) { self.focus_handle.focus(window); - } else if self.focus_handle.contains_focused(window, cx) - && !self.multibuffer.read(cx).is_empty() - { + } else if self.focus_handle.is_focused(window) && !self.multibuffer.read(cx).is_empty() { self.editor.update(cx, |editor, cx| { editor.focus_handle(cx).focus(window); - editor.move_to_beginning(&Default::default(), window, cx); }); } if self.pending_scroll.as_ref() == Some(&path_key) { diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index e75bc586decd18..82242ae04282c2 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -149,11 +149,14 @@ impl MultiBufferDiffHunk { } #[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Hash, Debug)] -pub struct PathKey(String); +pub struct PathKey { + namespace: &'static str, + path: Arc, +} impl PathKey { - pub fn namespaced(namespace: &str, path: &Path) -> Self { - Self(format!("{}/{}", namespace, path.to_string_lossy())) + pub fn namespaced(namespace: &'static str, path: Arc) -> Self { + Self { namespace, path } } } diff --git a/crates/multi_buffer/src/multi_buffer_tests.rs b/crates/multi_buffer/src/multi_buffer_tests.rs index 3b8d0e2a165833..23a5af7c336c6d 100644 --- a/crates/multi_buffer/src/multi_buffer_tests.rs +++ b/crates/multi_buffer/src/multi_buffer_tests.rs @@ -1599,7 +1599,7 @@ fn test_set_excerpts_for_buffer_ordering(cx: &mut TestAppContext) { cx, ) }); - let path1: PathKey = PathKey::namespaced("0", Path::new("/")); + let path1: PathKey = PathKey::namespaced("0", Path::new("/").into()); let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite)); multibuffer.update(cx, |multibuffer, cx| { @@ -1695,7 +1695,7 @@ fn test_set_excerpts_for_buffer(cx: &mut TestAppContext) { cx, ) }); - let path1: PathKey = PathKey::namespaced("0", Path::new("/")); + let path1: PathKey = PathKey::namespaced("0", Path::new("/").into()); let buf2 = cx.new(|cx| { Buffer::local( indoc! { @@ -1714,7 +1714,7 @@ fn test_set_excerpts_for_buffer(cx: &mut TestAppContext) { cx, ) }); - let path2 = PathKey::namespaced("x", Path::new("/")); + let path2 = PathKey::namespaced("x", Path::new("/").into()); let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite)); multibuffer.update(cx, |multibuffer, cx| {