From 9aeb35bfab08c1673d91d60879d2ae4c8fa1869c Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 13 May 2021 11:54:29 -0700 Subject: [PATCH] Get tests passing using a slow rightmost_point impl Co-Authored-By: Nathan Sobo --- zed/src/editor/buffer/mod.rs | 104 +++++++++++++------------ zed/src/editor/display_map/fold_map.rs | 18 +++-- 2 files changed, 68 insertions(+), 54 deletions(-) diff --git a/zed/src/editor/buffer/mod.rs b/zed/src/editor/buffer/mod.rs index 31e35643de6096506d70294635aaeed671434daf..23077a25a900adf02cc8901983bac6f183f83130 100644 --- a/zed/src/editor/buffer/mod.rs +++ b/zed/src/editor/buffer/mod.rs @@ -309,33 +309,56 @@ pub struct TextSummary { pub chars: usize, pub bytes: usize, pub lines: Point, + pub first_line_len: u32, + pub rightmost_point: Point, } impl<'a> From> for TextSummary { fn from(slice: RopeSlice<'a>) -> Self { let last_row = slice.len_lines() - 1; let last_column = slice.line(last_row).len_chars(); + + let mut point = Point::default(); + let mut rightmost_point = point; + let mut first_line_len = None; + for (i, c) in slice.chars().enumerate() { + if c == '\n' { + if first_line_len.is_none() { + first_line_len = Some(i as u32); + } + point.row += 1; + point.column = 0; + } else { + point.column += 1; + if point.column > rightmost_point.column { + rightmost_point = point; + } + } + } + Self { chars: slice.len_chars(), bytes: slice.len_bytes(), lines: Point::new(last_row as u32, last_column as u32), + first_line_len: first_line_len.unwrap_or(slice.len_chars() as u32), + rightmost_point, } } } impl<'a> std::ops::AddAssign<&'a Self> for TextSummary { fn add_assign(&mut self, other: &'a Self) { - // let joined_line_len = self.lines.column + other.first_line_len; - // if joined_line_len > self.rightmost_point.column { - // self.rightmost_point = Point::new(self.lines.row, joined_line_len); - // } - // if other.rightmost_point.column > self.rightmost_point.column { - // self.rightmost_point = self.lines + &other.rightmost_point; - // } - - // if self.lines.row == 0 { - // self.first_line_len += other.first_line_len; - // } + let joined_line_len = self.lines.column + other.first_line_len; + if joined_line_len > self.rightmost_point.column { + self.rightmost_point = Point::new(self.lines.row, joined_line_len); + } + if other.rightmost_point.column > self.rightmost_point.column { + self.rightmost_point = self.lines + &other.rightmost_point; + } + + if self.lines.row == 0 { + self.first_line_len += other.first_line_len; + } self.chars += other.chars; self.bytes += other.bytes; @@ -662,35 +685,11 @@ impl Buffer { } pub fn rightmost_point(&self) -> Point { - todo!() - // self.fragments.summary().text_summary.rightmost_point + self.rightmost_point_in_range(0..self.len()) } pub fn rightmost_point_in_range(&self, range: Range) -> Point { - todo!() - // let mut summary = TextSummary::default(); - - // let mut cursor = self.fragments.cursor::(); - // cursor.seek(&range.start, SeekBias::Right, &()); - - // if let Some(fragment) = cursor.item() { - // let summary_start = cmp::max(*cursor.start(), range.start) - cursor.start(); - // let summary_end = cmp::min(range.end - cursor.start(), fragment.len()); - // summary += fragment.text.slice(summary_start..summary_end).summary(); - // cursor.next(); - // } - - // if range.end > *cursor.start() { - // summary += cursor.summary::(&range.end, SeekBias::Right, &()); - - // if let Some(fragment) = cursor.item() { - // let summary_start = cmp::max(*cursor.start(), range.start) - cursor.start(); - // let summary_end = cmp::min(range.end - cursor.start(), fragment.len()); - // summary += fragment.text.slice(summary_start..summary_end).summary(); - // } - // } - - // summary.rightmost_point + self.text_summary_for_range(range).rightmost_point } pub fn max_point(&self) -> Point { @@ -2594,9 +2593,9 @@ mod tests { let (longest_column, longest_rows) = line_lengths.iter().next_back().unwrap(); - // let rightmost_point = buffer.rightmost_point(); - // assert_eq!(rightmost_point.column, *longest_column); - // assert!(longest_rows.contains(&rightmost_point.row)); + let rightmost_point = buffer.rightmost_point(); + assert_eq!(rightmost_point.column, *longest_column); + assert!(longest_rows.contains(&rightmost_point.row)); } for _ in 0..5 { @@ -2607,9 +2606,8 @@ mod tests { let (longest_column, longest_rows) = line_lengths.iter().next_back().unwrap(); let range_sum = buffer.text_summary_for_range(start..end); - // TODO: re-enable when we have rightmost point again. - // assert_eq!(range_sum.rightmost_point.column, *longest_column); - // assert!(longest_rows.contains(&range_sum.rightmost_point.row)); + assert_eq!(range_sum.rightmost_point.column, *longest_column); + assert!(longest_rows.contains(&range_sum.rightmost_point.row)); let range_text = &buffer.text()[start..end]; assert_eq!(range_sum.chars, range_text.chars().count()); assert_eq!(range_sum.bytes, range_text.len()); @@ -2693,7 +2691,9 @@ mod tests { TextSummary { chars: 2, bytes: 2, - lines: Point::new(1, 0) + lines: Point::new(1, 0), + first_line_len: 1, + rightmost_point: Point::new(0, 1), } ); assert_eq!( @@ -2701,7 +2701,9 @@ mod tests { TextSummary { chars: 11, bytes: 11, - lines: Point::new(3, 0) + lines: Point::new(3, 0), + first_line_len: 1, + rightmost_point: Point::new(2, 4), } ); assert_eq!( @@ -2709,7 +2711,9 @@ mod tests { TextSummary { chars: 20, bytes: 20, - lines: Point::new(4, 1) + lines: Point::new(4, 1), + first_line_len: 2, + rightmost_point: Point::new(3, 6), } ); assert_eq!( @@ -2717,7 +2721,9 @@ mod tests { TextSummary { chars: 22, bytes: 22, - lines: Point::new(4, 3) + lines: Point::new(4, 3), + first_line_len: 2, + rightmost_point: Point::new(3, 6), } ); assert_eq!( @@ -2725,7 +2731,9 @@ mod tests { TextSummary { chars: 15, bytes: 15, - lines: Point::new(2, 3) + lines: Point::new(2, 3), + first_line_len: 4, + rightmost_point: Point::new(1, 6), } ); buffer diff --git a/zed/src/editor/display_map/fold_map.rs b/zed/src/editor/display_map/fold_map.rs index b2e36e0867b248afcd1759e94d726e51240b8dd4..daf182c2e79ffbb3ab219e8a42c6892d033c5083 100644 --- a/zed/src/editor/display_map/fold_map.rs +++ b/zed/src/editor/display_map/fold_map.rs @@ -1,5 +1,5 @@ use super::{ - buffer::{self, AnchorRangeExt, TextSummary}, + buffer::{AnchorRangeExt, TextSummary}, Anchor, Buffer, DisplayPoint, Edit, Point, ToOffset, }; use crate::{ @@ -72,8 +72,7 @@ impl FoldMap { } pub fn rightmost_point(&self, ctx: &AppContext) -> DisplayPoint { - todo!() - // DisplayPoint(self.sync(ctx).summary().display.rightmost_point) + DisplayPoint(self.sync(ctx).summary().display.rightmost_point) } pub fn folds_in_range<'a, T>( @@ -353,8 +352,8 @@ impl FoldMap { chars: 1, bytes: '…'.len_utf8(), lines: Point::new(0, 1), - // first_line_len: 1, - // rightmost_point: Point::new(0, 1), + first_line_len: 1, + rightmost_point: Point::new(0, 1), }, buffer: buffer.text_summary_for_range(fold.start..fold.end), }, @@ -670,8 +669,8 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize { #[cfg(test)] mod tests { use super::*; + use crate::editor::buffer::ToPoint; use crate::test::sample_text; - use buffer::ToPoint; #[gpui::test] fn test_basic_folds(app: &mut gpui::MutableAppContext) { @@ -917,6 +916,7 @@ mod tests { assert_eq!(line_len, line.chars().count() as u32); } + let rightmost_point = map.rightmost_point(app.as_ref()); let mut display_point = DisplayPoint::new(0, 0); let mut display_offset = DisplayOffset(0); for c in expected_text.chars() { @@ -942,6 +942,12 @@ mod tests { *display_point.column_mut() += 1; } display_offset.0 += 1; + if display_point.column() > rightmost_point.column() { + panic!( + "invalid rightmost point {:?}, found point {:?}", + rightmost_point, display_point + ); + } } for _ in 0..5 {