@@ -616,14 +616,6 @@ impl Buffer {
(row_end_offset - row_start_offset) as u32
}
- pub fn rightmost_point(&self) -> Point {
- self.visible_text.summary().rightmost_point
- }
-
- pub fn rightmost_point_in_range(&self, range: Range<usize>) -> Point {
- self.text_summary_for_range(range).rightmost_point
- }
-
pub fn max_point(&self) -> Point {
self.visible_text.max_point()
}
@@ -2360,7 +2352,6 @@ mod tests {
use std::{
cell::RefCell,
cmp::Ordering,
- collections::BTreeMap,
fs,
rc::Rc,
sync::atomic::{self, AtomicUsize},
@@ -2468,33 +2459,11 @@ mod tests {
reference_string = buffer.text();
}
- {
- let line_lengths = line_lengths_in_range(&buffer, 0..buffer.len());
-
- for (len, rows) in &line_lengths {
- for row in rows {
- assert_eq!(buffer.line_len(*row), *len);
- }
- }
-
- 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));
- }
-
- for _ in 0..5 {
- let range = buffer.random_byte_range(0, rng);
- let line_lengths = line_lengths_in_range(&buffer, range.clone());
- let (longest_column, longest_rows) =
- line_lengths.iter().next_back().unwrap();
- let range_sum = buffer.text_summary_for_range(range.clone());
- assert_eq!(range_sum.rightmost_point.column, *longest_column);
- assert!(longest_rows.contains(&range_sum.rightmost_point.row));
- let range_text = &buffer.text()[range];
- assert_eq!(range_sum.bytes, range_text.len());
- }
+ let range = buffer.random_byte_range(0, rng);
+ assert_eq!(
+ buffer.text_summary_for_range(range.clone()),
+ TextSummary::from(&reference_string[range])
+ );
if rng.gen_bool(0.3) {
buffer_versions.push(buffer.clone());
@@ -2545,25 +2514,6 @@ mod tests {
});
}
- #[gpui::test]
- fn test_rightmost_point(ctx: &mut gpui::MutableAppContext) {
- ctx.add_model(|ctx| {
- let mut buffer = Buffer::new(0, "", ctx);
- assert_eq!(buffer.rightmost_point().row, 0);
- buffer.edit(vec![0..0], "abcd\nefg\nhij", None).unwrap();
- assert_eq!(buffer.rightmost_point().row, 0);
- buffer.edit(vec![12..12], "kl\nmno", None).unwrap();
- assert_eq!(buffer.rightmost_point().row, 2);
- buffer.edit(vec![18..18], "\npqrs", None).unwrap();
- assert_eq!(buffer.rightmost_point().row, 2);
- buffer.edit(vec![10..12], "", None).unwrap();
- assert_eq!(buffer.rightmost_point().row, 0);
- buffer.edit(vec![24..24], "tuv", None).unwrap();
- assert_eq!(buffer.rightmost_point().row, 4);
- buffer
- });
- }
-
#[gpui::test]
fn test_text_summary_for_range(ctx: &mut gpui::MutableAppContext) {
ctx.add_model(|ctx| {
@@ -2573,7 +2523,8 @@ mod tests {
TextSummary {
bytes: 2,
lines: Point::new(1, 0),
- first_line_len: 1,
+ first_line_chars: 1,
+ last_line_chars: 0,
rightmost_point: Point::new(0, 1),
}
);
@@ -2582,7 +2533,8 @@ mod tests {
TextSummary {
bytes: 11,
lines: Point::new(3, 0),
- first_line_len: 1,
+ first_line_chars: 1,
+ last_line_chars: 0,
rightmost_point: Point::new(2, 4),
}
);
@@ -2591,7 +2543,8 @@ mod tests {
TextSummary {
bytes: 20,
lines: Point::new(4, 1),
- first_line_len: 2,
+ first_line_chars: 2,
+ last_line_chars: 1,
rightmost_point: Point::new(3, 6),
}
);
@@ -2600,7 +2553,8 @@ mod tests {
TextSummary {
bytes: 22,
lines: Point::new(4, 3),
- first_line_len: 2,
+ first_line_chars: 2,
+ last_line_chars: 3,
rightmost_point: Point::new(3, 6),
}
);
@@ -2609,7 +2563,8 @@ mod tests {
TextSummary {
bytes: 15,
lines: Point::new(2, 3),
- first_line_len: 4,
+ first_line_chars: 4,
+ last_line_chars: 3,
rightmost_point: Point::new(1, 6),
}
);
@@ -3388,20 +3343,4 @@ mod tests {
}
}
}
-
- fn line_lengths_in_range(buffer: &Buffer, range: Range<usize>) -> BTreeMap<u32, HashSet<u32>> {
- let mut lengths = BTreeMap::new();
- for (row, line) in buffer.text()[range.start..range.end].lines().enumerate() {
- lengths
- .entry(line.len() as u32)
- .or_insert(HashSet::default())
- .insert(row as u32);
- }
- if lengths.is_empty() {
- let mut rows = HashSet::default();
- rows.insert(0);
- lengths.insert(0, rows);
- }
- lengths
- }
}
@@ -390,32 +390,41 @@ impl sum_tree::Item for Chunk {
pub struct TextSummary {
pub bytes: usize,
pub lines: Point,
- pub first_line_len: u32,
+ pub first_line_chars: u32,
+ pub last_line_chars: u32,
pub rightmost_point: Point,
}
impl<'a> From<&'a str> for TextSummary {
fn from(text: &'a str) -> Self {
let mut lines = Point::new(0, 0);
- let mut first_line_len = 0;
+ let mut first_line_chars = 0;
+ let mut last_line_chars = 0;
let mut rightmost_point = Point::new(0, 0);
- for (i, line) in text.split('\n').enumerate() {
- if i > 0 {
+ for c in text.chars() {
+ if c == '\n' {
lines.row += 1;
+ lines.column = 0;
+ last_line_chars = 0;
+ } else {
+ lines.column += c.len_utf8() as u32;
+ last_line_chars += 1;
}
- lines.column = line.len() as u32;
- if i == 0 {
- first_line_len = lines.column;
+
+ if lines.row == 0 {
+ first_line_chars = last_line_chars;
}
- if lines.column > rightmost_point.column {
- rightmost_point = lines;
+
+ if last_line_chars > rightmost_point.column {
+ rightmost_point = Point::new(lines.row, last_line_chars);
}
}
TextSummary {
bytes: text.len(),
lines,
- first_line_len,
+ first_line_chars,
+ last_line_chars,
rightmost_point,
}
}
@@ -431,16 +440,22 @@ impl sum_tree::Summary for TextSummary {
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);
+ let joined_chars = self.last_line_chars + other.first_line_chars;
+ if joined_chars > self.rightmost_point.column {
+ self.rightmost_point = Point::new(self.lines.row, joined_chars);
}
if other.rightmost_point.column > self.rightmost_point.column {
- self.rightmost_point = self.lines + &other.rightmost_point;
+ self.rightmost_point = self.lines + other.rightmost_point;
}
if self.lines.row == 0 {
- self.first_line_len += other.first_line_len;
+ self.first_line_chars += other.first_line_chars;
+ }
+
+ if other.lines.row == 0 {
+ self.last_line_chars += other.first_line_chars;
+ } else {
+ self.last_line_chars = other.last_line_chars;
}
self.bytes += other.bytes;
@@ -330,15 +330,17 @@ impl FoldMap {
if fold.end > fold.start {
let display_text = "…";
- let extent = Point::new(0, display_text.len() as u32);
+ let chars = display_text.chars().count() as u32;
+ let lines = Point::new(0, display_text.len() as u32);
new_transforms.push(
Transform {
summary: TransformSummary {
display: TextSummary {
bytes: display_text.len(),
- lines: extent,
- first_line_len: extent.column,
- rightmost_point: extent,
+ lines,
+ first_line_chars: chars,
+ last_line_chars: chars,
+ rightmost_point: Point::new(0, chars),
},
buffer: buffer.text_summary_for_range(fold.start..fold.end),
},
@@ -990,6 +992,7 @@ mod tests {
let rightmost_point = map.rightmost_point(app.as_ref());
let mut display_point = DisplayPoint::new(0, 0);
let mut display_offset = DisplayOffset(0);
+ let mut char_column = 0;
for c in expected_text.chars() {
let buffer_point = map.to_buffer_point(display_point, app.as_ref());
let buffer_offset = buffer_point.to_offset(buffer);
@@ -1015,14 +1018,16 @@ mod tests {
if c == '\n' {
*display_point.row_mut() += 1;
*display_point.column_mut() = 0;
+ char_column = 0;
} else {
*display_point.column_mut() += c.len_utf8() as u32;
+ char_column += 1;
}
display_offset.0 += c.len_utf8();
- if display_point.column() > rightmost_point.column() {
+ if char_column > rightmost_point.column() {
panic!(
- "invalid rightmost point {:?}, found point {:?}",
- rightmost_point, display_point
+ "invalid rightmost point {:?}, found point {:?} (char column: {})",
+ rightmost_point, display_point, char_column
);
}
}