wip

Cole Miller , HactarCE , and Miguel Raz Guzmán Macedo created

Co-authored-by: HactarCE <6060305+HactarCE@users.noreply.github.com>
Co-authored-by: Miguel Raz Guzmán Macedo <miguel@zed.dev>

Change summary

crates/editor/src/split.rs              | 21 +++++++++++++--------
crates/git_ui/src/project_diff.rs       | 22 ++++++++++++++++------
crates/multi_buffer/src/multi_buffer.rs | 26 +++++++++++++++++++-------
3 files changed, 48 insertions(+), 21 deletions(-)

Detailed changes

crates/editor/src/split.rs 🔗

@@ -262,6 +262,9 @@ impl SplittableEditor {
                     context_line_count,
                     cx,
                 );
+                // - we just added some excerpts for a specific buffer to the primary (RHS)
+                // - but the diff for that buffer doesn't get attached to the primary multibuffer until slightly later
+                // - however, for sync_path_excerpts we require that we have a diff for the buffer
                 if let Some(secondary) = &mut self.secondary
                     && let Some(languages) = self
                         .workspace
@@ -348,6 +351,8 @@ impl SecondaryEditor {
             })
             .unwrap_or_else(|| {
                 cx.new(|cx| {
+                    // FIXME we might not have a language at this point for the base text;
+                    // need to handle the case where the language comes in afterward
                     let base_text = diff.base_text();
                     let mut buffer = Buffer::local_normalized(
                         base_text.as_rope().clone(),
@@ -364,18 +369,18 @@ impl SecondaryEditor {
             .excerpts_for_buffer(main_buffer.remote_id(), cx)
             .into_iter()
             .map(|(_, excerpt_range)| {
-                let point_to_base_text_point = |point: Point| {
-                    let row = diff.row_to_base_text_row(point.row, main_buffer);
-                    let column = diff.base_text().line_len(row);
-                    Point::new(row, column)
+                let point_range_to_base_text_point_range = |range: Range<Point>| {
+                    let start_row = diff.row_to_base_text_row(range.start.row, main_buffer);
+                    let start_column = 0;
+                    let end_row = diff.row_to_base_text_row(range.end.row, main_buffer);
+                    let end_column = diff.base_text().line_len(end_row);
+                    Point::new(start_row, start_column)..Point::new(end_row, end_column)
                 };
                 let primary = excerpt_range.primary.to_point(main_buffer);
                 let context = excerpt_range.context.to_point(main_buffer);
                 ExcerptRange {
-                    primary: point_to_base_text_point(primary.start)
-                        ..point_to_base_text_point(primary.end),
-                    context: point_to_base_text_point(context.start)
-                        ..point_to_base_text_point(context.end),
+                    primary: point_range_to_base_text_point_range(primary),
+                    context: point_range_to_base_text_point_range(context),
                 }
             })
             .collect();

crates/git_ui/src/project_diff.rs 🔗

@@ -516,18 +516,28 @@ impl ProjectDiff {
                 .map(|range| range.to_point(&snapshot))
                 .collect::<Vec<_>>();
 
-        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(
+        // if self.branch_diff.read(cx).diff_base().is_merge_base() {
+        // FIXME should have an add diff api for the splittable editor directly
+        self.multibuffer.update(cx, |multibuffer, cx| {
+            multibuffer.add_diff(diff.clone(), cx);
+        });
+        // }
+
+        let (was_empty, is_excerpt_newly_added) = self.editor.update(cx, |editor, cx| {
+            // FIXME should go through the splittable editor
+            let was_empty = editor
+                .primary_editor()
+                .read(cx)
+                .buffer()
+                .read(cx)
+                .is_empty();
+            let (_, is_newly_added) = editor.set_excerpts_for_path(
                 path_key.clone(),
                 buffer,
                 excerpt_ranges,
                 multibuffer_context_lines(cx),
                 cx,
             );
-            if self.branch_diff.read(cx).diff_base().is_merge_base() {
-                multibuffer.add_diff(diff.clone(), cx);
-            }
             (was_empty, is_newly_added)
         });
 

crates/multi_buffer/src/multi_buffer.rs 🔗

@@ -624,7 +624,8 @@ pub struct MultiBufferSnapshot {
     replaced_excerpts: TreeMap<ExcerptId, ExcerptId>,
     trailing_excerpt_update_count: usize,
     all_diff_hunks_expanded: bool,
-    show_deleted_hunks: bool,
+    // FIXME
+    pub show_deleted_hunks: bool,
     show_headers: bool,
 }
 
@@ -3906,18 +3907,29 @@ impl MultiBufferSnapshot {
             let word_diffs = (!hunk.base_word_diffs.is_empty()
                 || !hunk.buffer_word_diffs.is_empty())
             .then(|| {
-                let hunk_start_offset =
-                    Anchor::in_buffer(excerpt.id, hunk.buffer_range.start).to_offset(self);
+                let hunk_start_offset = if is_inverted {
+                    Anchor::in_buffer(
+                        excerpt.id,
+                        excerpt.buffer.anchor_after(hunk.diff_base_byte_range.start),
+                    )
+                    .to_offset(self)
+                } else {
+                    Anchor::in_buffer(excerpt.id, hunk.buffer_range.start).to_offset(self)
+                };
 
-                hunk.base_word_diffs
+                let mut word_diffs = hunk
+                    .base_word_diffs
                     .iter()
                     .map(|diff| hunk_start_offset + diff.start..hunk_start_offset + diff.end)
-                    .chain(
+                    .collect::<Vec<_>>();
+                if !is_inverted {
+                    word_diffs.extend(
                         hunk.buffer_word_diffs
                             .into_iter()
                             .map(|diff| Anchor::range_in_buffer(excerpt.id, diff).to_offset(self)),
-                    )
-                    .collect()
+                    );
+                }
+                word_diffs
             })
             .unwrap_or_default();