From 880b3f087f1a9fb149c1ab6c9794da154a7721c1 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 16 Nov 2021 12:14:00 -0700 Subject: [PATCH] Insert empty isomorphic transforms on empty lines Co-Authored-By: Max Brunsfeld Co-Authored-By: Antonio Scandurra --- crates/editor/src/display_map/block_map.rs | 41 +++++++++++++++++----- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 9da39f0a61..247e022279 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -104,16 +104,14 @@ pub struct BufferRows<'a> { impl BlockMap { pub fn new(buffer: ModelHandle, wrap_snapshot: WrapSnapshot) -> Self { - let mut transforms = SumTree::new(); - let lines = wrap_snapshot.text_summary().lines; - if !lines.is_zero() { - transforms.push(Transform::isomorphic(lines), &()); - } Self { buffer, next_block_id: AtomicUsize::new(0), blocks: Vec::new(), - transforms: Mutex::new(transforms), + transforms: Mutex::new(SumTree::from_item( + Transform::isomorphic(wrap_snapshot.text_summary().lines), + &(), + )), wrap_snapshot: Mutex::new(wrap_snapshot), } } @@ -242,8 +240,13 @@ impl BlockMap { Point::new(block_row, wrap_snapshot.line_len(block_row)) } }; + let extent_before_block = block_insertion_point - new_transforms.summary().input; push_isomorphic(&mut new_transforms, extent_before_block); + if block.disposition == BlockDisposition::Below { + ensure_last_is_isomorphic_or_below_block(&mut new_transforms); + } + new_transforms.push(Transform::block(block.clone()), &()); } @@ -260,6 +263,7 @@ impl BlockMap { } new_transforms.push_tree(cursor.suffix(&()), &()); + ensure_last_is_isomorphic_or_below_block(&mut new_transforms); debug_assert_eq!(new_transforms.summary().input, wrap_snapshot.max_point().0); drop(cursor); @@ -267,6 +271,17 @@ impl BlockMap { } } +fn ensure_last_is_isomorphic_or_below_block(tree: &mut SumTree) { + if tree.last().map_or(true, |transform| { + transform + .block + .as_ref() + .map_or(false, |block| block.disposition.is_above()) + }) { + tree.push(Transform::isomorphic(Point::zero()), &()) + } +} + fn push_isomorphic(tree: &mut SumTree, extent: Point) { if extent.is_zero() { return; @@ -690,6 +705,7 @@ impl<'a> Iterator for BufferRows<'a> { } let (buffer_row, _) = self.input_buffer_row.unwrap(); + log::info!( "Called next. Output row: {}, Input row: {}, Buffer row: {}", self.output_row, @@ -771,6 +787,10 @@ impl BlockDisposition { fn is_above(&self) -> bool { matches!(self, BlockDisposition::Above) } + + fn is_below(&self) -> bool { + matches!(self, BlockDisposition::Below) + } } // Count the number of bytes prior to a target point. If the string doesn't contain the target @@ -1157,8 +1177,7 @@ mod tests { } } - let soft_wrapped = - wraps_snapshot.to_tab_point(WrapPoint::new(row, 0)).column() != 0; + let soft_wrapped = wraps_snapshot.to_tab_point(WrapPoint::new(row, 0)).column() > 0; expected_buffer_rows.push((buffer_row, false)); expected_text.push_str(input_line); @@ -1178,6 +1197,12 @@ mod tests { } assert_eq!(blocks_snapshot.text(), expected_text); + for row in 0..=blocks_snapshot.wrap_snapshot.max_point().row() { + let wrap_point = WrapPoint::new(row, 0); + let block_point = blocks_snapshot.to_block_point(wrap_point); + assert_eq!(blocks_snapshot.to_wrap_point(block_point), wrap_point); + } + assert_eq!( blocks_snapshot.buffer_rows(0).collect::>(), expected_buffer_rows