diff --git a/crates/editor/src/split.rs b/crates/editor/src/split.rs index d527c54b4e68d553caca718ada6d8ba58e56a8cb..96d6c70c900d2501c3e3d45bf3f3361fa178c533 100644 --- a/crates/editor/src/split.rs +++ b/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| { + 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(); diff --git a/crates/git_ui/src/project_diff.rs b/crates/git_ui/src/project_diff.rs index 0a8667ba6c753f9b7925948f212388f0668c1c92..1dd6e7e3e35d28af6b3ac736610d497f07aa6e47 100644 --- a/crates/git_ui/src/project_diff.rs +++ b/crates/git_ui/src/project_diff.rs @@ -516,18 +516,28 @@ impl ProjectDiff { .map(|range| range.to_point(&snapshot)) .collect::>(); - 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) }); diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index ab590d4adb86b9c6df892af811adc24d9b4508a5..2a1a68a94ae1c33bbc954e831bc78e1f6f33ead5 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -624,7 +624,8 @@ pub struct MultiBufferSnapshot { replaced_excerpts: TreeMap, 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::>(); + 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();