fix seed 13

Cole Miller and Piotr Osiewicz created

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>

Change summary

crates/multi_buffer/src/multi_buffer.rs       |   3 
crates/multi_buffer/src/multi_buffer_tests.rs | 123 +++++++++++++-------
crates/multi_buffer/src/path_key.rs           |  15 ++
3 files changed, 96 insertions(+), 45 deletions(-)

Detailed changes

crates/multi_buffer/src/multi_buffer.rs 🔗

@@ -2607,7 +2607,6 @@ impl MultiBuffer {
         }
 
         paths_to_edit.sort_unstable_by_key(|(path, _, _)| path.clone());
-        dbg!(&paths_to_edit);
 
         let mut edits = Vec::new();
         let mut new_excerpts = SumTree::default();
@@ -6903,7 +6902,7 @@ impl Excerpt {
             path_key,
             path_key_index,
             buffer_id: buffer_snapshot.remote_id(),
-            max_buffer_row: dbg!(range.context.end.to_point(&buffer_snapshot).row),
+            max_buffer_row: range.context.end.to_point(&buffer_snapshot).row,
             text_summary: buffer_snapshot.text_summary_for_range::<TextSummary, _>(
                 range.context.to_offset(&buffer_snapshot),
             ),

crates/multi_buffer/src/multi_buffer_tests.rs 🔗

@@ -2815,6 +2815,87 @@ async fn test_random_set_ranges(cx: &mut TestAppContext, mut rng: StdRng) {
     }
 }
 
+#[gpui::test]
+async fn test_remove_last_excerpt(cx: &mut TestAppContext) {
+    let buffer = cx.new(|cx| {
+        Buffer::local(
+            indoc! {"
+    aaa
+    bbb
+    ccc
+    ddd
+    eee
+    fff
+    ggg
+    hhh
+    "},
+            cx,
+        )
+    });
+    let buffer_snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
+
+    let multibuffer = cx.new(|cx| {
+        let mut multibuffer = MultiBuffer::new(Capability::ReadWrite);
+        multibuffer.set_excerpt_ranges_for_path(
+            PathKey::sorted(0),
+            buffer.clone(),
+            &buffer_snapshot,
+            vec![
+                ExcerptRange::new(Point::zero()..Point::new(3, 0)),
+                ExcerptRange::new(Point::new(5, 0)..Point::new(7, 0)),
+            ],
+            cx,
+        );
+        multibuffer
+    });
+
+    multibuffer.read_with(cx, |multibuffer, cx| {
+        let snapshot = multibuffer.snapshot(cx);
+
+        let actual_boundary_rows = snapshot
+            .excerpt_boundaries_in_range(MultiBufferOffset(0)..)
+            .map(|b| b.row)
+            .collect::<HashSet<_>>();
+        let actual_row_infos = snapshot.row_infos(MultiBufferRow(0)).collect::<Vec<_>>();
+        let text = snapshot.text();
+        eprintln!(
+            "{}",
+            format_diff(&text, &actual_row_infos, &actual_boundary_rows, Some(false))
+        );
+    });
+
+    multibuffer.update(cx, |multibuffer, cx| {
+        multibuffer.set_excerpt_ranges_for_path(
+            PathKey::sorted(0),
+            buffer,
+            &buffer_snapshot,
+            vec![ExcerptRange::new(Point::zero()..Point::new(3, 0))],
+            cx,
+        );
+    });
+
+    multibuffer.read_with(cx, |multibuffer, cx| {
+        let snapshot = multibuffer.snapshot(cx);
+        let actual_text = snapshot.text();
+        let actual_boundary_rows = snapshot
+            .excerpt_boundaries_in_range(MultiBufferOffset(0)..)
+            .map(|b| b.row)
+            .collect::<HashSet<_>>();
+        let actual_row_infos = snapshot.row_infos(MultiBufferRow(0)).collect::<Vec<_>>();
+        let text = snapshot.text();
+
+        eprintln!(
+            "{}",
+            format_diff(
+                &actual_text,
+                &actual_row_infos,
+                &actual_boundary_rows,
+                Some(false)
+            )
+        );
+    });
+}
+
 #[gpui::test(iterations = 100)]
 async fn test_random_multibuffer(cx: &mut TestAppContext, mut rng: StdRng) {
     let operations = env::var("OPERATIONS")
@@ -3160,17 +3241,6 @@ fn check_multibuffer(
     );
 
     log::info!("Multibuffer content:\n{}", actual_diff);
-    dbg!(
-        snapshot
-            .excerpts()
-            .map(|(buffer_snapshot, excerpt)| {
-                (
-                    buffer_snapshot.remote_id(),
-                    excerpt.range.to_point(&buffer_snapshot),
-                )
-            })
-            .collect::<Vec<_>>()
-    );
 
     assert_eq!(
         actual_row_infos.len(),
@@ -3193,27 +3263,6 @@ fn check_multibuffer(
             start_row
         );
     }
-    // dbg!(&expected_row_infos);
-
-    // dbg!(
-    //     snapshot
-    //         .excerpts()
-    //         .map(|(buffer_snapshot, excerpt)| {
-    //             (
-    //                 buffer_snapshot.remote_id(),
-    //                 excerpt.range.to_point(&buffer_snapshot),
-    //             )
-    //         })
-    //         .collect::<Vec<_>>()
-    // );
-    // dbg!(&expected_row_infos);
-    // dbg!(
-    //     reference
-    //         .excerpts
-    //         .iter()
-    //         .map(|excerpt| { excerpt.range.to_point(&excerpt.buffer.read(cx).snapshot()) })
-    //         .collect::<Vec<_>>()
-    // );
 
     assert_eq!(
         snapshot.widest_line_number(),
@@ -3235,16 +3284,6 @@ fn check_multibuffer(
             .unwrap()
             + 1
     );
-    // let reference_ranges = reference
-    //     .excerpts
-    //     .iter()
-    //     .map(|excerpt| {
-    //         (
-    //             excerpt.info(cx),
-    //             excerpt.range.to_offset(&excerpt.buffer.read(cx).snapshot()),
-    //         )
-    //     })
-    //     .collect::<Vec<_>>();
     for i in 0..snapshot.len().0 {
         // todo!() this seems not useful
         let excerpt = snapshot

crates/multi_buffer/src/path_key.rs 🔗

@@ -423,9 +423,21 @@ impl MultiBuffer {
         }
 
         // remove any further trailing excerpts
-        let before = cursor.position.1;
+        let mut before = cursor.position.1;
         cursor.seek_forward(&path_key, Bias::Right);
         let after = cursor.position.1;
+        // if we removed the previous last excerpt, remove the trailing newline from the new last excerpt
+        if cursor.item().is_none() && to_insert.peek().is_none() {
+            new_excerpts.update_last(
+                |excerpt| {
+                    if excerpt.has_trailing_newline {
+                        before -= 1;
+                        excerpt.has_trailing_newline = false;
+                    }
+                },
+                (),
+            );
+        }
         patch.push(Edit {
             old: before..after,
             new: new_excerpts.summary().len()..new_excerpts.summary().len(),
@@ -459,6 +471,7 @@ impl MultiBuffer {
         let changed_trailing_excerpt = suffix.is_empty();
         new_excerpts.append(suffix, ());
         drop(cursor);
+
         snapshot.excerpts = new_excerpts;
         snapshot.buffers.insert(
             buffer_id,