From 91d4c835ad937024abf2e5c71099819098ea0009 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 14 Apr 2022 12:55:33 +0200 Subject: [PATCH 1/3] Introduce `TabMap::line_len` --- crates/editor/src/display_map/tab_map.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/crates/editor/src/display_map/tab_map.rs b/crates/editor/src/display_map/tab_map.rs index 77ec73d8bf8b3cb8d2e116b401155634efcdc62f..1491c790f60229e68ec86f1b967a157a51378b43 100644 --- a/crates/editor/src/display_map/tab_map.rs +++ b/crates/editor/src/display_map/tab_map.rs @@ -96,6 +96,22 @@ impl TabSnapshot { self.fold_snapshot.buffer_snapshot() } + pub fn line_len(&self, row: u32) -> u32 { + let max_point = self.max_point(); + if row < max_point.row() { + self.chunks( + TabPoint::new(row, 0)..TabPoint::new(row + 1, 0), + false, + None, + ) + .map(|chunk| chunk.text.len() as u32) + .sum::() + - 1 + } else { + max_point.column() + } + } + pub fn text_summary(&self) -> TextSummary { self.text_summary_for_range(TabPoint::zero()..self.max_point()) } @@ -517,8 +533,11 @@ mod tests { actual_summary.longest_row = expected_summary.longest_row; actual_summary.longest_row_chars = expected_summary.longest_row_chars; } + assert_eq!(actual_summary, expected_summary); + } - assert_eq!(actual_summary, expected_summary,); + for row in 0..=text.max_point().row { + assert_eq!(tabs_snapshot.line_len(row), text.line_len(row)); } } } From 1a1d67010400c28a25d0e04b79a6244dca6c35a7 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 14 Apr 2022 13:01:29 +0200 Subject: [PATCH 2/3] Speed up `WrapSnapshot::line_len` using the indexed transforms --- crates/editor/src/display_map/wrap_map.rs | 28 +++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index 00e9b63b1ad66625942c62daf21c4b04c372bb9f..be356044f8b573c13ae0d6614f30cea33af22228 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -599,16 +599,23 @@ impl WrapSnapshot { } pub fn line_len(&self, row: u32) -> u32 { - let mut len = 0; - for chunk in self.text_chunks(row) { - if let Some(newline_ix) = chunk.find('\n') { - len += newline_ix; - break; + let mut cursor = self.transforms.cursor::<(WrapPoint, TabPoint)>(); + cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Left, &()); + if cursor + .item() + .map_or(false, |transform| transform.is_isomorphic()) + { + let overshoot = row - cursor.start().0.row(); + let tab_row = cursor.start().1.row() + overshoot; + let tab_line_len = self.tab_snapshot.line_len(tab_row); + if overshoot == 0 { + cursor.start().0.column() + (tab_line_len - cursor.start().1.column()) } else { - len += chunk.len(); + tab_line_len } + } else { + cursor.start().0.column() } - len as u32 } pub fn soft_wrap_indent(&self, row: u32) -> Option { @@ -741,6 +748,7 @@ impl WrapSnapshot { } } + let text = language::Rope::from(self.text().as_str()); let input_buffer_rows = self.buffer_snapshot().buffer_rows(0).collect::>(); let mut expected_buffer_rows = Vec::new(); let mut prev_tab_row = 0; @@ -754,6 +762,8 @@ impl WrapSnapshot { expected_buffer_rows.push(input_buffer_rows[buffer_point.row as usize]); prev_tab_row = tab_point.row(); } + + assert_eq!(self.line_len(display_row), text.line_len(display_row)); } for start_display_row in 0..expected_buffer_rows.len() { @@ -957,6 +967,10 @@ impl WrapPoint { &mut self.0.row } + pub fn column(self) -> u32 { + self.0.column + } + pub fn column_mut(&mut self) -> &mut u32 { &mut self.0.column } From 6d33697e82e9a55355b7e643d1e3022d2caa614c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 14 Apr 2022 13:03:46 +0200 Subject: [PATCH 3/3] Fix warning --- crates/editor/src/display_map/wrap_map.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index be356044f8b573c13ae0d6614f30cea33af22228..0e88d87bd77b06ff3a4ab8bfb49c7f0c1aa2433e 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -559,11 +559,6 @@ impl WrapSnapshot { Patch::new(wrap_edits) } - pub fn text_chunks(&self, wrap_row: u32) -> impl Iterator { - self.chunks(wrap_row..self.max_point().row() + 1, false, None) - .map(|h| h.text) - } - pub fn chunks<'a>( &'a self, rows: Range, @@ -1286,6 +1281,11 @@ mod tests { self.text_chunks(0).collect() } + pub fn text_chunks(&self, wrap_row: u32) -> impl Iterator { + self.chunks(wrap_row..self.max_point().row() + 1, false, None) + .map(|h| h.text) + } + fn verify_chunks(&mut self, rng: &mut impl Rng) { for _ in 0..5 { let mut end_row = rng.gen_range(0..=self.max_point().row());