diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 25874457a8e3d4..399575ad7f7c2e 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -1368,50 +1368,49 @@ impl BlockMap { let mut delta = their_baseline.0 as i32 - our_baseline.0 as i32; - // If we started out in the middle of a hunk/group, work up to the end of that group to set up the main loop below. - if edit_for_first_point.old.start < first_point { - let mut current_boundary = first_point; - let current_range = edit_for_first_point.new; - while let Some(next_point) = source_points.peek().cloned() { - let edit_for_next_point = excerpt.patch.edit_for_old_position(next_point); - if edit_for_next_point.new.end > current_range.end { - break; - } - source_points.next(); - current_boundary = next_point; - } - - let (new_delta, spacer) = determine_spacer( - &mut our_wrapper, - &mut companion_wrapper, - current_boundary, - current_range.end.min(excerpt.target_excerpt_range.end), - delta, - Bias::Left, - ); - - delta = new_delta; - if let Some((wrap_row, height)) = spacer { - result.push(( - BlockPlacement::Above(wrap_row), - Block::Spacer { - id: SpacerId(self.next_block_id.fetch_add(1, SeqCst)), - height, - is_below: false, - }, - )); - } - } - while let Some(source_point) = source_points.next() { let mut current_boundary = source_point; - let current_range = excerpt.patch.edit_for_old_position(current_boundary).new; + let current_edit = excerpt.patch.edit_for_old_position(current_boundary); + let current_range = current_edit.new; if current_boundary.column > 0 { debug_assert_eq!(current_boundary, excerpt.source_excerpt_range.end); break; } + if current_edit.old.start < current_boundary { + while let Some(next_point) = source_points.peek().copied() { + let edit_for_next_point = excerpt.patch.edit_for_old_position(next_point); + if edit_for_next_point.new.end > current_range.end { + break; + } + current_boundary = next_point; + source_points.next(); + } + + let (new_delta, spacer) = determine_spacer( + &mut our_wrapper, + &mut companion_wrapper, + current_boundary, + current_range.end.min(excerpt.target_excerpt_range.end), + delta, + Bias::Left, + ); + + delta = new_delta; + if let Some((wrap_row, height)) = spacer { + result.push(( + BlockPlacement::Above(wrap_row), + Block::Spacer { + id: SpacerId(self.next_block_id.fetch_add(1, SeqCst)), + height, + is_below: false, + }, + )); + } + continue; + } + let (delta_at_start, mut spacer_at_start) = determine_spacer( &mut our_wrapper, &mut companion_wrapper, diff --git a/crates/editor/src/split.rs b/crates/editor/src/split.rs index ee15583072144c..f8e0708c562fec 100644 --- a/crates/editor/src/split.rs +++ b/crates/editor/src/split.rs @@ -6058,6 +6058,121 @@ mod tests { cx.run_until_parked(); } + #[gpui::test] + async fn test_spacer_blocks_revert_after_temporary_edit(cx: &mut gpui::TestAppContext) { + use rope::Point; + use unindent::Unindent as _; + + let (editor, mut cx) = init_test(cx, SoftWrap::EditorWidth, DiffViewStyle::Split).await; + + let base_text = " + aaa + bbb + " + .unindent(); + let current_text = " + aaa + bbb + ccc + " + .unindent(); + + let (buffer, diff) = buffer_with_diff(&base_text, ¤t_text, &mut cx); + + editor.update(cx, |editor, cx| { + let path = PathKey::for_buffer(&buffer, cx); + editor.update_excerpts_for_path( + path, + buffer.clone(), + vec![Point::new(0, 0)..buffer.read(cx).max_point()], + 0, + diff.clone(), + cx, + ); + }); + + cx.run_until_parked(); + + assert_split_content( + &editor, + " + § + § ----- + aaa + bbb + ccc" + .unindent(), + " + § + § ----- + aaa + bbb + § spacer" + .unindent(), + &mut cx, + ); + + let buffer_snapshot = buffer.update(cx, |buffer, cx| { + buffer.edit([(Point::new(0, 3)..Point::new(0, 3), "\n")], None, cx); + buffer.text_snapshot() + }); + diff.update(cx, |diff, cx| { + diff.recalculate_diff_sync(&buffer_snapshot, cx); + }); + + cx.run_until_parked(); + + assert_split_content( + &editor, + " + § + § ----- + aaa + + bbb + ccc" + .unindent(), + " + § + § ----- + aaa + § spacer + bbb + § spacer" + .unindent(), + &mut cx, + ); + + let buffer_snapshot = buffer.update(cx, |buffer, cx| { + buffer.edit([(Point::new(0, 3)..Point::new(1, 0), "")], None, cx); + buffer.text_snapshot() + }); + diff.update(cx, |diff, cx| { + diff.recalculate_diff_sync(&buffer_snapshot, cx); + }); + + cx.run_until_parked(); + + assert_split_content( + &editor, + " + § + § ----- + aaa + bbb + ccc" + .unindent(), + " + § + § ----- + aaa + bbb + § spacer" + .unindent(), + &mut cx, + ); + } + #[gpui::test] async fn test_act_as_type(cx: &mut gpui::TestAppContext) { let (splittable_editor, cx) = init_test(cx, SoftWrap::None, DiffViewStyle::Split).await;