Move highlighted_text_in_range from Buffer to buffer::Snapshot

This commit is contained in:
Antonio Scandurra
2021-05-25 11:51:29 +02:00
parent e54a31ead2
commit aeb68867da
6 changed files with 182 additions and 200 deletions
+26 -41
View File
@@ -46,7 +46,7 @@ impl FoldMap {
pub fn snapshot(&self, ctx: &AppContext) -> FoldMapSnapshot {
FoldMapSnapshot {
transforms: self.sync(ctx).clone(),
buffer: self.buffer.clone(),
buffer: self.buffer.read(ctx).snapshot(),
}
}
@@ -210,11 +210,11 @@ impl FoldMap {
}
pub fn to_buffer_offset(&self, point: DisplayPoint, ctx: &AppContext) -> usize {
self.snapshot(ctx).to_buffer_offset(point, ctx)
self.snapshot(ctx).to_buffer_offset(point)
}
pub fn to_display_offset(&self, point: DisplayPoint, ctx: &AppContext) -> DisplayOffset {
self.snapshot(ctx).to_display_offset(point, ctx)
self.snapshot(ctx).to_display_offset(point)
}
pub fn to_buffer_point(&self, display_point: DisplayPoint, ctx: &AppContext) -> Point {
@@ -394,7 +394,7 @@ impl FoldMap {
pub struct FoldMapSnapshot {
transforms: SumTree<Transform>,
buffer: ModelHandle<Buffer>,
buffer: buffer::Snapshot,
}
impl FoldMapSnapshot {
@@ -413,13 +413,12 @@ impl FoldMapSnapshot {
}
}
pub fn chunks_at<'a>(&'a self, offset: DisplayOffset, ctx: &'a AppContext) -> Chunks<'a> {
pub fn chunks_at(&self, offset: DisplayOffset) -> Chunks {
let mut transform_cursor = self.transforms.cursor::<DisplayOffset, TransformSummary>();
transform_cursor.seek(&offset, SeekBias::Right, &());
let overshoot = offset.0 - transform_cursor.start().display.bytes;
let buffer_offset = transform_cursor.start().buffer.bytes + overshoot;
let buffer = self.buffer.read(ctx);
let rope_cursor = buffer.text_for_range(buffer_offset..buffer.len());
let rope_cursor = self.buffer.text_for_range(buffer_offset..self.buffer.len());
Chunks {
transform_cursor,
buffer_offset,
@@ -427,34 +426,27 @@ impl FoldMapSnapshot {
}
}
pub fn highlighted_chunks_at<'a>(
&'a self,
offset: DisplayOffset,
ctx: &'a AppContext,
) -> HighlightedChunks<'a> {
pub fn highlighted_chunks_at(&mut self, offset: DisplayOffset) -> HighlightedChunks {
let mut transform_cursor = self.transforms.cursor::<DisplayOffset, TransformSummary>();
transform_cursor.seek(&offset, SeekBias::Right, &());
let overshoot = offset.0 - transform_cursor.start().display.bytes;
let buffer_offset = transform_cursor.start().buffer.bytes + overshoot;
let buffer = self.buffer.read(ctx);
HighlightedChunks {
transform_cursor,
buffer_offset,
buffer_chunks: buffer.highlighted_text_for_range(buffer_offset..buffer.len()),
buffer_chunks: self
.buffer
.highlighted_text_for_range(buffer_offset..self.buffer.len()),
buffer_chunk: None,
}
}
pub fn chars_at<'a>(
&'a self,
point: DisplayPoint,
ctx: &'a AppContext,
) -> impl Iterator<Item = char> + 'a {
let offset = self.to_display_offset(point, ctx);
self.chunks_at(offset, ctx).flat_map(str::chars)
pub fn chars_at<'a>(&'a self, point: DisplayPoint) -> impl Iterator<Item = char> + 'a {
let offset = self.to_display_offset(point);
self.chunks_at(offset).flat_map(str::chars)
}
pub fn to_display_offset(&self, point: DisplayPoint, ctx: &AppContext) -> DisplayOffset {
pub fn to_display_offset(&self, point: DisplayPoint) -> DisplayOffset {
let mut cursor = self.transforms.cursor::<DisplayPoint, TransformSummary>();
cursor.seek(&point, SeekBias::Right, &());
let overshoot = point.0 - cursor.start().display.lines;
@@ -462,27 +454,24 @@ impl FoldMapSnapshot {
if !overshoot.is_zero() {
let transform = cursor.item().expect("display point out of range");
assert!(transform.display_text.is_none());
let end_buffer_offset =
(cursor.start().buffer.lines + overshoot).to_offset(self.buffer.read(ctx));
let end_buffer_offset = self
.buffer
.to_offset(cursor.start().buffer.lines + overshoot);
offset += end_buffer_offset - cursor.start().buffer.bytes;
}
DisplayOffset(offset)
}
pub fn to_buffer_offset(&self, point: DisplayPoint, ctx: &AppContext) -> usize {
pub fn to_buffer_offset(&self, point: DisplayPoint) -> usize {
let mut cursor = self.transforms.cursor::<DisplayPoint, TransformSummary>();
cursor.seek(&point, SeekBias::Right, &());
let overshoot = point.0 - cursor.start().display.lines;
(cursor.start().buffer.lines + overshoot).to_offset(self.buffer.read(ctx))
self.buffer
.to_offset(cursor.start().buffer.lines + overshoot)
}
#[cfg(test)]
pub fn clip_offset(
&self,
offset: DisplayOffset,
bias: Bias,
ctx: &AppContext,
) -> DisplayOffset {
pub fn clip_offset(&self, offset: DisplayOffset, bias: Bias) -> DisplayOffset {
let mut cursor = self.transforms.cursor::<DisplayOffset, TransformSummary>();
cursor.seek(&offset, SeekBias::Right, &());
if let Some(transform) = cursor.item() {
@@ -496,7 +485,7 @@ impl FoldMapSnapshot {
} else {
let overshoot = offset.0 - transform_start;
let buffer_offset = cursor.start().buffer.bytes + overshoot;
let clipped_buffer_offset = self.buffer.read(ctx).clip_offset(buffer_offset, bias);
let clipped_buffer_offset = self.buffer.clip_offset(buffer_offset, bias);
DisplayOffset(
(offset.0 as isize + (clipped_buffer_offset as isize - buffer_offset as isize))
as usize,
@@ -507,7 +496,7 @@ impl FoldMapSnapshot {
}
}
pub fn clip_point(&self, point: DisplayPoint, bias: Bias, ctx: &AppContext) -> DisplayPoint {
pub fn clip_point(&self, point: DisplayPoint, bias: Bias) -> DisplayPoint {
let mut cursor = self.transforms.cursor::<DisplayPoint, TransformSummary>();
cursor.seek(&point, SeekBias::Right, &());
if let Some(transform) = cursor.item() {
@@ -521,8 +510,7 @@ impl FoldMapSnapshot {
} else {
let overshoot = point.0 - transform_start;
let buffer_position = cursor.start().buffer.lines + overshoot;
let clipped_buffer_position =
self.buffer.read(ctx).clip_point(buffer_position, bias);
let clipped_buffer_position = self.buffer.clip_point(buffer_position, bias);
DisplayPoint::new(
point.row(),
((point.column() as i32) + clipped_buffer_position.column as i32
@@ -1131,11 +1119,10 @@ mod tests {
let offset = map.snapshot(app.as_ref()).clip_offset(
DisplayOffset(rng.gen_range(0..=map.len(app.as_ref()))),
Bias::Right,
app.as_ref(),
);
assert_eq!(
map.snapshot(app.as_ref())
.chunks_at(offset, app.as_ref())
.chunks_at(offset)
.collect::<String>(),
&expected_text[offset.0..],
);
@@ -1218,9 +1205,7 @@ mod tests {
impl FoldMap {
fn text(&self, app: &AppContext) -> String {
self.snapshot(app)
.chunks_at(DisplayOffset(0), app)
.collect()
self.snapshot(app).chunks_at(DisplayOffset(0)).collect()
}
fn merged_fold_ranges(&self, app: &AppContext) -> Vec<Range<usize>> {
+34 -57
View File
@@ -62,16 +62,14 @@ impl DisplayMap {
}
pub fn text(&self, ctx: &AppContext) -> String {
self.snapshot(ctx)
.chunks_at(DisplayPoint::zero(), ctx)
.collect()
self.snapshot(ctx).chunks_at(DisplayPoint::zero()).collect()
}
pub fn line(&self, display_row: u32, ctx: &AppContext) -> String {
let mut result = String::new();
for chunk in self
.snapshot(ctx)
.chunks_at(DisplayPoint::new(display_row, 0), ctx)
.chunks_at(DisplayPoint::new(display_row, 0))
{
if let Some(ix) = chunk.find('\n') {
result.push_str(&chunk[0..ix]);
@@ -88,7 +86,7 @@ impl DisplayMap {
let mut is_blank = true;
for c in self
.snapshot(ctx)
.chars_at(DisplayPoint::new(display_row, 0), ctx)
.chars_at(DisplayPoint::new(display_row, 0))
{
if c == ' ' {
indent += 1;
@@ -138,12 +136,11 @@ impl DisplayMapSnapshot {
self.folds_snapshot.buffer_rows(start_row)
}
pub fn chunks_at<'a>(&'a self, point: DisplayPoint, app: &'a AppContext) -> Chunks<'a> {
let (point, expanded_char_column, to_next_stop) =
self.collapse_tabs(point, Bias::Left, app);
pub fn chunks_at(&self, point: DisplayPoint) -> Chunks {
let (point, expanded_char_column, to_next_stop) = self.collapse_tabs(point, Bias::Left);
let fold_chunks = self
.folds_snapshot
.chunks_at(self.folds_snapshot.to_display_offset(point, app), app);
.chunks_at(self.folds_snapshot.to_display_offset(point));
Chunks {
fold_chunks,
column: expanded_char_column,
@@ -153,15 +150,11 @@ impl DisplayMapSnapshot {
}
}
pub fn highlighted_chunks_at<'a>(
&'a self,
row: u32,
app: &'a AppContext,
) -> HighlightedChunks<'a> {
pub fn highlighted_chunks_at(&mut self, row: u32) -> HighlightedChunks {
let point = DisplayPoint::new(row, 0);
let offset = self.folds_snapshot.to_display_offset(point, app);
let offset = self.folds_snapshot.to_display_offset(point);
HighlightedChunks {
fold_chunks: self.folds_snapshot.highlighted_chunks_at(offset, app),
fold_chunks: self.folds_snapshot.highlighted_chunks_at(offset),
column: 0,
tab_size: self.tab_size,
chunk: "",
@@ -169,18 +162,14 @@ impl DisplayMapSnapshot {
}
}
pub fn chars_at<'a>(
&'a self,
point: DisplayPoint,
app: &'a AppContext,
) -> impl Iterator<Item = char> + 'a {
self.chunks_at(point, app).flat_map(str::chars)
pub fn chars_at<'a>(&'a self, point: DisplayPoint) -> impl Iterator<Item = char> + 'a {
self.chunks_at(point).flat_map(str::chars)
}
pub fn column_to_chars(&self, display_row: u32, target: u32, ctx: &AppContext) -> u32 {
pub fn column_to_chars(&self, display_row: u32, target: u32) -> u32 {
let mut count = 0;
let mut column = 0;
for c in self.chars_at(DisplayPoint::new(display_row, 0), ctx) {
for c in self.chars_at(DisplayPoint::new(display_row, 0)) {
if column >= target {
break;
}
@@ -190,10 +179,10 @@ impl DisplayMapSnapshot {
count
}
pub fn column_from_chars(&self, display_row: u32, char_count: u32, ctx: &AppContext) -> u32 {
pub fn column_from_chars(&self, display_row: u32, char_count: u32) -> u32 {
let mut count = 0;
let mut column = 0;
for c in self.chars_at(DisplayPoint::new(display_row, 0), ctx) {
for c in self.chars_at(DisplayPoint::new(display_row, 0)) {
if c == '\n' || count >= char_count {
break;
}
@@ -203,32 +192,26 @@ impl DisplayMapSnapshot {
column
}
pub fn clip_point(&self, point: DisplayPoint, bias: Bias, ctx: &AppContext) -> DisplayPoint {
pub fn clip_point(&self, point: DisplayPoint, bias: Bias) -> DisplayPoint {
self.expand_tabs(
self.folds_snapshot
.clip_point(self.collapse_tabs(point, bias, ctx).0, bias, ctx),
ctx,
.clip_point(self.collapse_tabs(point, bias).0, bias),
)
}
fn expand_tabs(&self, mut point: DisplayPoint, ctx: &AppContext) -> DisplayPoint {
fn expand_tabs(&self, mut point: DisplayPoint) -> DisplayPoint {
let chars = self
.folds_snapshot
.chars_at(DisplayPoint(Point::new(point.row(), 0)), ctx);
.chars_at(DisplayPoint(Point::new(point.row(), 0)));
let expanded = expand_tabs(chars, point.column() as usize, self.tab_size);
*point.column_mut() = expanded as u32;
point
}
fn collapse_tabs(
&self,
mut point: DisplayPoint,
bias: Bias,
ctx: &AppContext,
) -> (DisplayPoint, usize, usize) {
fn collapse_tabs(&self, mut point: DisplayPoint, bias: Bias) -> (DisplayPoint, usize, usize) {
let chars = self
.folds_snapshot
.chars_at(DisplayPoint(Point::new(point.row(), 0)), ctx);
.chars_at(DisplayPoint(Point::new(point.row(), 0)));
let expanded = point.column() as usize;
let (collapsed, expanded_char_column, to_next_stop) =
collapse_tabs(chars, expanded, bias, self.tab_size);
@@ -276,11 +259,11 @@ impl DisplayPoint {
}
fn expand_tabs(self, map: &DisplayMap, ctx: &AppContext) -> Self {
map.snapshot(ctx).expand_tabs(self, ctx)
map.snapshot(ctx).expand_tabs(self)
}
fn collapse_tabs(self, map: &DisplayMap, bias: Bias, ctx: &AppContext) -> Self {
map.snapshot(ctx).collapse_tabs(self, bias, ctx).0
map.snapshot(ctx).collapse_tabs(self, bias).0
}
}
@@ -288,7 +271,7 @@ impl Point {
pub fn to_display_point(self, map: &DisplayMap, ctx: &AppContext) -> DisplayPoint {
let mut display_point = map.fold_map.to_display_point(self, ctx);
let snapshot = map.fold_map.snapshot(ctx);
let chars = snapshot.chars_at(DisplayPoint::new(display_point.row(), 0), ctx);
let chars = snapshot.chars_at(DisplayPoint::new(display_point.row(), 0));
*display_point.column_mut() =
expand_tabs(chars, display_point.column() as usize, map.tab_size) as u32;
display_point
@@ -487,19 +470,19 @@ mod tests {
assert_eq!(
&map.snapshot(app.as_ref())
.chunks_at(DisplayPoint::new(1, 0), app.as_ref())
.chunks_at(DisplayPoint::new(1, 0))
.collect::<String>()[0..10],
" b bb"
);
assert_eq!(
&map.snapshot(app.as_ref())
.chunks_at(DisplayPoint::new(1, 2), app.as_ref())
.chunks_at(DisplayPoint::new(1, 2))
.collect::<String>()[0..10],
" b bbbb"
);
assert_eq!(
&map.snapshot(app.as_ref())
.chunks_at(DisplayPoint::new(1, 6), app.as_ref())
.chunks_at(DisplayPoint::new(1, 6))
.collect::<String>()[0..13],
" bbbbb\nc c"
);
@@ -534,7 +517,7 @@ mod tests {
),
] {
assert_eq!(
map.clip_point(DisplayPoint::new(1, input_column as u32), bias, ctx),
map.clip_point(DisplayPoint::new(1, input_column as u32), bias),
DisplayPoint::new(1, output_column as u32),
"clip_point(({}, {}))",
1,
@@ -584,7 +567,7 @@ mod tests {
);
assert_eq!(
map.snapshot(ctx)
.chunks_at(DisplayPoint::new(0, "✅ ".len() as u32), ctx)
.chunks_at(DisplayPoint::new(0, "✅ ".len() as u32))
.collect::<String>(),
" α\nβ \n🏀β γ"
);
@@ -598,26 +581,20 @@ mod tests {
);
assert_eq!(
map.snapshot(ctx)
.chunks_at(DisplayPoint::new(0, "✅ ".len() as u32), ctx)
.chunks_at(DisplayPoint::new(0, "✅ ".len() as u32))
.collect::<String>(),
" α\nβ \n🏀β γ"
);
// Clipping display points inside of multi-byte characters
assert_eq!(
map.snapshot(ctx).clip_point(
DisplayPoint::new(0, "✅".len() as u32 - 1),
Bias::Left,
ctx
),
map.snapshot(ctx)
.clip_point(DisplayPoint::new(0, "✅".len() as u32 - 1), Bias::Left),
DisplayPoint::new(0, 0)
);
assert_eq!(
map.snapshot(ctx).clip_point(
DisplayPoint::new(0, "✅".len() as u32 - 1),
Bias::Right,
ctx
),
map.snapshot(ctx)
.clip_point(DisplayPoint::new(0, "✅".len() as u32 - 1), Bias::Right),
DisplayPoint::new(0, "✅".len() as u32)
);
}