git: More rigorously test excerpt syncing for split diff, and fix a couple of bugs (#49907)
This PR adds a more rigorous test for the excerpt syncing logic in `SplittableEditor`, in preparation for refactoring that code, since we've had some bugs there. The new test covers - edits within the RHS multibuffer - edits to the individual main buffers, not necessarily within the excerpt bounds of the split diff - excerpt expansion - excerpt removal - excerpt recalculation based on diff hunk ranges Bugs fixed: - incorrect edit merging logic in `patches_for_range` - `merge_excerpts` leaving stale excerpt IDs in `excerpts_by_path` Before you mark this PR as ready for review, make sure that you have: - [x] Added a solid test coverage and/or screenshots from doing manual testing - [x] Done a self-review taking into account security and performance aspects - [ ] Aligned any UI changes with the [UI checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - N/A
This commit is contained in:
1 parent
7ffd4c0a95
commit
00b9127309
4 files changed
+355
-153
No files matched your search
@@ -595,14 +595,12 @@ impl DiffState {
|
||||
base_text_changed_range,
|
||||
extended_range: _,
|
||||
}) => {
|
||||
if let Some(base_text_changed_range) = base_text_changed_range.clone() {
|
||||
this.inverted_buffer_diff_changed(
|
||||
diff,
|
||||
main_buffer,
|
||||
base_text_changed_range,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
this.inverted_buffer_diff_changed(
|
||||
diff,
|
||||
main_buffer,
|
||||
base_text_changed_range.clone(),
|
||||
cx,
|
||||
);
|
||||
cx.emit(Event::BufferDiffChanged);
|
||||
}
|
||||
BufferDiffEvent::LanguageChanged => {
|
||||
@@ -2202,7 +2200,19 @@ impl MultiBuffer {
|
||||
drop(snapshot);
|
||||
|
||||
self.resize_excerpt(excerpt_ids[0], union_range, cx);
|
||||
self.remove_excerpts(excerpt_ids[1..].iter().copied(), cx);
|
||||
let removed = &excerpt_ids[1..];
|
||||
for &excerpt_id in removed {
|
||||
if let Some(path) = self.paths_by_excerpt.get(&excerpt_id) {
|
||||
if let Some(excerpt_list) = self.excerpts_by_path.get_mut(path) {
|
||||
excerpt_list.retain(|id| *id != excerpt_id);
|
||||
if excerpt_list.is_empty() {
|
||||
let path = path.clone();
|
||||
self.excerpts_by_path.remove(&path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.remove_excerpts(removed.iter().copied(), cx);
|
||||
|
||||
excerpt_ids[0]
|
||||
}
|
||||
@@ -2489,7 +2499,7 @@ impl MultiBuffer {
|
||||
&mut self,
|
||||
diff: Entity<BufferDiff>,
|
||||
main_buffer: Entity<language::Buffer>,
|
||||
diff_change_range: Range<usize>,
|
||||
diff_change_range: Option<Range<usize>>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.sync_mut(cx);
|
||||
@@ -2510,6 +2520,10 @@ impl MultiBuffer {
|
||||
.diffs
|
||||
.insert_or_replace(base_text_buffer_id, new_diff);
|
||||
|
||||
let Some(diff_change_range) = diff_change_range else {
|
||||
return;
|
||||
};
|
||||
|
||||
let excerpt_edits = snapshot.excerpt_edits_for_diff_change(buffer_state, diff_change_range);
|
||||
let edits = Self::sync_diff_transforms(
|
||||
&mut snapshot,
|
||||
@@ -2705,7 +2719,12 @@ impl MultiBuffer {
|
||||
let base_text_buffer_id = snapshot.remote_id();
|
||||
let diff_change_range = 0..snapshot.len();
|
||||
self.snapshot.get_mut().has_inverted_diff = true;
|
||||
self.inverted_buffer_diff_changed(diff.clone(), main_buffer.clone(), diff_change_range, cx);
|
||||
self.inverted_buffer_diff_changed(
|
||||
diff.clone(),
|
||||
main_buffer.clone(),
|
||||
Some(diff_change_range),
|
||||
cx,
|
||||
);
|
||||
self.diffs.insert(
|
||||
base_text_buffer_id,
|
||||
DiffState::new_inverted(diff, main_buffer, cx),
|
||||
|
||||
Reference in new issue
Block a user