@@ -1911,6 +1911,67 @@ pub mod tests {
);
}
+ #[gpui::test]
+ fn test_inlays_with_newlines_after_blocks(cx: &mut gpui::TestAppContext) {
+ cx.update(|cx| init_test(cx, |_| {}));
+
+ let buffer = cx.new(|cx| Buffer::local("a", cx));
+ let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));
+ let buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx));
+
+ let font_size = px(14.0);
+ let map = cx.new(|cx| {
+ DisplayMap::new(
+ buffer.clone(),
+ font("Helvetica"),
+ font_size,
+ None,
+ true,
+ 1,
+ 1,
+ 1,
+ FoldPlaceholder::test(),
+ cx,
+ )
+ });
+
+ map.update(cx, |map, cx| {
+ map.insert_blocks(
+ [BlockProperties {
+ placement: BlockPlacement::Above(
+ buffer_snapshot.anchor_before(Point::new(0, 0)),
+ ),
+ height: 2,
+ style: BlockStyle::Sticky,
+ render: Arc::new(|_| div().into_any()),
+ priority: 0,
+ }],
+ cx,
+ );
+ });
+ map.update(cx, |m, cx| assert_eq!(m.snapshot(cx).text(), "\n\na"));
+
+ map.update(cx, |map, cx| {
+ map.splice_inlays(
+ &[],
+ vec![Inlay {
+ id: InlayId::InlineCompletion(0),
+ position: buffer_snapshot.anchor_after(0),
+ text: "\n".into(),
+ }],
+ cx,
+ );
+ });
+ map.update(cx, |m, cx| assert_eq!(m.snapshot(cx).text(), "\n\n\na"));
+
+ // Regression test: updating the display map does not crash when a
+ // block is immediately followed by a multi-line inlay.
+ buffer.update(cx, |buffer, cx| {
+ buffer.edit([(1..1, "b")], None, cx);
+ });
+ map.update(cx, |m, cx| assert_eq!(m.snapshot(cx).text(), "\n\n\nab"));
+ }
+
#[gpui::test]
async fn test_chunks(cx: &mut gpui::TestAppContext) {
let text = r#"
@@ -638,10 +638,13 @@ impl BlockMap {
self.custom_blocks[start_block_ix..end_block_ix]
.iter()
.filter_map(|block| {
- Some((
- block.placement.to_wrap_row(wrap_snapshot)?,
- Block::Custom(block.clone()),
- ))
+ let placement = block.placement.to_wrap_row(wrap_snapshot)?;
+ if let BlockPlacement::Above(row) = placement {
+ if row < new_start {
+ return None;
+ }
+ }
+ Some((placement, Block::Custom(block.clone())))
}),
);