From 00b5cc472effd6751d6d882306584e294785e6e1 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 17 Nov 2021 14:54:47 -0800 Subject: [PATCH] Fix BlockSnapshot::chunks when starting in a block Co-Authored-By: Nathan Sobo --- crates/editor/src/display_map/block_map.rs | 65 ++++++++++++++-------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index 6dae5d8d9c..29be478406 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -89,7 +89,6 @@ pub struct Chunks<'a> { block_chunks: Option>, output_row: u32, max_output_row: u32, - max_input_row: u32, } struct BlockChunks<'a> { @@ -464,33 +463,41 @@ impl BlockSnapshot { } pub fn chunks(&self, rows: Range, highlights: bool) -> Chunks { - let max_input_row = self.transforms.summary().input_rows; let max_output_row = cmp::min(rows.end, self.transforms.summary().output_rows); let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(); - let output_row = rows.start; - cursor.seek(&BlockRow(output_row), Bias::Right, &()); - let (input_start, output_start) = cursor.start(); - let overshoot = rows.start - output_start.0; - let output_end_row = max_output_row.saturating_sub(1); - let input_start_row = input_start.0 + overshoot; - let input_end_row = self - .to_wrap_point(BlockPoint::new( - output_end_row, - self.wrap_snapshot.line_len(output_end_row), - )) - .row() - + 1; - let input_chunks = self - .wrap_snapshot - .chunks(input_start_row..input_end_row, highlights); + let input_end = { + cursor.seek(&BlockRow(rows.end), Bias::Right, &()); + let overshoot = if cursor + .item() + .map_or(false, |transform| transform.is_isomorphic()) + { + rows.end - cursor.start().0 .0 + } else { + 0 + }; + cursor.start().1 .0 + overshoot + }; + let input_start = { + cursor.seek(&BlockRow(rows.start), Bias::Right, &()); + let overshoot = if cursor + .item() + .map_or(false, |transform| transform.is_isomorphic()) + { + rows.start - cursor.start().0 .0 + } else { + 0 + }; + cursor.start().1 .0 + overshoot + }; Chunks { - input_chunks, + input_chunks: self + .wrap_snapshot + .chunks(input_start..input_end, highlights), input_chunk: Default::default(), block_chunks: None, transforms: cursor, - output_row, + output_row: rows.start, max_output_row, - max_input_row, } } @@ -1253,7 +1260,21 @@ mod tests { } } - assert_eq!(blocks_snapshot.text(), expected_text); + let expected_lines = expected_text.split('\n').collect::>(); + let expected_row_count = expected_lines.len(); + for start_row in 0..expected_row_count { + let expected_text = expected_lines[start_row..].join("\n"); + let actual_text = blocks_snapshot + .chunks(start_row as u32..expected_row_count as u32, false) + .map(|chunk| chunk.text) + .collect::(); + assert_eq!( + actual_text, expected_text, + "incorrect text starting from row {}", + start_row + ); + } + 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);