@@ -441,10 +441,10 @@ impl PendingDiff {
async move {
let hunks = compute_hunks(&base_snapshot, &snapshot, operations);
BufferDiffUpdate::from_hunks(
- base_text.clone(),
+ base_text,
+ base_snapshot.as_rope(),
snapshot,
hunks,
- // FIXME options
Some(DiffOptions::default()),
)
}
@@ -54,18 +54,23 @@ impl BufferDiffUpdate {
// FIXME thread through diff options to control word diff
pub fn from_hunks(
base_text: Arc<str>,
+ base_snapshot: &Rope,
buffer_snapshot: text::BufferSnapshot,
edits: Patch<usize>,
diff_options: Option<DiffOptions>,
) -> Self {
let hunks = edits.into_iter().map(|edit| {
- let old_text = &base_text[edit.old.clone()];
- let new_text = buffer_snapshot
- .text_for_range(edit.new.clone())
- .collect::<String>();
+ let buffer_range = buffer_snapshot.anchor_after(edit.new.start)
+ ..buffer_snapshot.anchor_after(edit.new.end);
let (base_word_diffs, buffer_word_diffs) = if let Some(options) = &diff_options {
- word_diff_ranges(old_text, &new_text, options.clone())
+ word_diffs(
+ base_snapshot,
+ edit.old.clone(),
+ &buffer_snapshot,
+ buffer_range,
+ options,
+ )
} else {
(Vec::new(), Vec::new())
};
@@ -74,13 +79,7 @@ impl BufferDiffUpdate {
..buffer_snapshot.anchor_before(edit.new.end),
diff_base_byte_range: edit.old,
base_word_diffs,
- buffer_word_diffs: buffer_word_diffs
- .into_iter()
- .map(|range| {
- buffer_snapshot.anchor_after(range.start)
- ..buffer_snapshot.anchor_after(range.end)
- })
- .collect::<Vec<_>>(),
+ buffer_word_diffs,
}
});
@@ -1461,35 +1460,16 @@ fn process_patch_hunk(
let end = Point::new(buffer_row_range.end, 0);
let buffer_range = buffer.anchor_before(start)..buffer.anchor_before(end);
- let base_line_count = line_item_count.saturating_sub(buffer_row_range.len());
-
- let (base_word_diffs, buffer_word_diffs) = if let Some(diff_options) = diff_options
- && !buffer_row_range.is_empty()
- && base_line_count == buffer_row_range.len()
- && diff_options.max_word_diff_line_count >= base_line_count
- {
- let base_text: String = diff_base
- .chunks_in_range(diff_base_byte_range.clone())
- .collect();
-
- let buffer_text: String = buffer.text_for_range(buffer_range.clone()).collect();
-
- let (base_word_diffs, buffer_word_diffs_relative) =
- word_diff_ranges(&base_text, &buffer_text, diff_options.clone());
-
- let buffer_start_offset = buffer_range.start.to_offset(buffer);
- let buffer_word_diffs = buffer_word_diffs_relative
- .into_iter()
- .map(|range| {
- let start = buffer.anchor_after(buffer_start_offset + range.start);
- let end = buffer.anchor_after(buffer_start_offset + range.end);
- start..end
- })
- .collect();
-
- (base_word_diffs, buffer_word_diffs)
+ let (base_word_diffs, buffer_word_diffs) = if let Some(options) = diff_options {
+ word_diffs(
+ diff_base,
+ diff_base_byte_range.clone(),
+ buffer,
+ buffer_range.clone(),
+ options,
+ )
} else {
- (Vec::default(), Vec::default())
+ (Vec::new(), Vec::new())
};
InternalDiffHunk {
@@ -1500,6 +1480,46 @@ fn process_patch_hunk(
}
}
+fn word_diffs(
+ diff_base: &Rope,
+ diff_base_byte_range: Range<usize>,
+ buffer: &text::BufferSnapshot,
+ buffer_range: Range<Anchor>,
+ options: &DiffOptions,
+) -> (Vec<Range<usize>>, Vec<Range<Anchor>>) {
+ let buffer_rows = buffer.text_summary_for_range::<Point, _>(buffer_range.clone());
+ let base_text_rows = diff_base
+ .cursor(diff_base_byte_range.start)
+ .summary::<Point>(diff_base_byte_range.end);
+ if buffer_rows == Point::zero()
+ || base_text_rows.row != buffer_rows.row
+ || base_text_rows.row > options.max_word_diff_line_count as u32
+ {
+ return (Vec::default(), Vec::default());
+ }
+
+ let base_text: String = diff_base
+ .chunks_in_range(diff_base_byte_range.clone())
+ .collect();
+
+ let buffer_text: String = buffer.text_for_range(buffer_range.clone()).collect();
+
+ let (base_word_diffs, buffer_word_diffs_relative) =
+ word_diff_ranges(&base_text, &buffer_text, options.clone());
+
+ let buffer_start_offset = buffer_range.start.to_offset(buffer);
+ let buffer_word_diffs = buffer_word_diffs_relative
+ .into_iter()
+ .map(|range| {
+ let start = buffer.anchor_after(buffer_start_offset + range.start);
+ let end = buffer.anchor_after(buffer_start_offset + range.end);
+ start..end
+ })
+ .collect();
+
+ (base_word_diffs, buffer_word_diffs)
+}
+
impl std::fmt::Debug for BufferDiff {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BufferChangeSet")