Detailed changes
@@ -72,8 +72,8 @@ impl DisplayMap {
let buffer_subscription = buffer.update(cx, |buffer, _| buffer.subscribe());
let tab_size = Self::tab_size(&buffer, cx);
- let (fold_map, snapshot) = FoldMap::new(buffer.read(cx).snapshot(cx));
- let (inlay_map, snapshot) = InlayMap::new(snapshot);
+ let (inlay_map, snapshot) = InlayMap::new(buffer.read(cx).snapshot(cx));
+ let (fold_map, snapshot) = FoldMap::new(snapshot);
let (tab_map, snapshot) = TabMap::new(snapshot, tab_size);
let (wrap_map, snapshot) = WrapMap::new(snapshot, font_id, font_size, wrap_width, cx);
let block_map = BlockMap::new(snapshot, buffer_header_height, excerpt_header_height);
@@ -94,10 +94,10 @@ impl DisplayMap {
pub fn snapshot(&mut self, cx: &mut ModelContext<Self>) -> DisplaySnapshot {
let buffer_snapshot = self.buffer.read(cx).snapshot(cx);
let edits = self.buffer_subscription.consume().into_inner();
- let (fold_snapshot, edits) = self.fold_map.read(buffer_snapshot, edits);
- let (inlay_snapshot, edits) = self.inlay_map.sync(fold_snapshot.clone(), edits);
+ let (inlay_snapshot, edits) = self.inlay_map.sync(buffer_snapshot, edits);
+ let (fold_snapshot, edits) = self.fold_map.read(inlay_snapshot.clone(), edits);
let tab_size = Self::tab_size(&self.buffer, cx);
- let (tab_snapshot, edits) = self.tab_map.sync(inlay_snapshot.clone(), edits, tab_size);
+ let (tab_snapshot, edits) = self.tab_map.sync(fold_snapshot.clone(), edits, tab_size);
let (wrap_snapshot, edits) = self
.wrap_map
.update(cx, |map, cx| map.sync(tab_snapshot.clone(), edits, cx));
@@ -132,15 +132,14 @@ impl DisplayMap {
let snapshot = self.buffer.read(cx).snapshot(cx);
let edits = self.buffer_subscription.consume().into_inner();
let tab_size = Self::tab_size(&self.buffer, cx);
- let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
let (snapshot, edits) = self.inlay_map.sync(snapshot, edits);
+ let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
let (snapshot, edits) = self
.wrap_map
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
self.block_map.read(snapshot, edits);
let (snapshot, edits) = fold_map.fold(ranges);
- let (snapshot, edits) = self.inlay_map.sync(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
let (snapshot, edits) = self
.wrap_map
@@ -157,15 +156,14 @@ impl DisplayMap {
let snapshot = self.buffer.read(cx).snapshot(cx);
let edits = self.buffer_subscription.consume().into_inner();
let tab_size = Self::tab_size(&self.buffer, cx);
- let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
let (snapshot, edits) = self.inlay_map.sync(snapshot, edits);
+ let (mut fold_map, snapshot, edits) = self.fold_map.write(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
let (snapshot, edits) = self
.wrap_map
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
self.block_map.read(snapshot, edits);
let (snapshot, edits) = fold_map.unfold(ranges, inclusive);
- let (snapshot, edits) = self.inlay_map.sync(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
let (snapshot, edits) = self
.wrap_map
@@ -181,8 +179,8 @@ impl DisplayMap {
let snapshot = self.buffer.read(cx).snapshot(cx);
let edits = self.buffer_subscription.consume().into_inner();
let tab_size = Self::tab_size(&self.buffer, cx);
- let (snapshot, edits) = self.fold_map.read(snapshot, edits);
let (snapshot, edits) = self.inlay_map.sync(snapshot, edits);
+ let (snapshot, edits) = self.fold_map.read(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
let (snapshot, edits) = self
.wrap_map
@@ -199,8 +197,8 @@ impl DisplayMap {
let snapshot = self.buffer.read(cx).snapshot(cx);
let edits = self.buffer_subscription.consume().into_inner();
let tab_size = Self::tab_size(&self.buffer, cx);
- let (snapshot, edits) = self.fold_map.read(snapshot, edits);
let (snapshot, edits) = self.inlay_map.sync(snapshot, edits);
+ let (snapshot, edits) = self.fold_map.read(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
let (snapshot, edits) = self
.wrap_map
@@ -253,9 +251,9 @@ impl DisplayMap {
) {
let buffer_snapshot = self.buffer.read(cx).snapshot(cx);
let edits = self.buffer_subscription.consume().into_inner();
+ let (snapshot, edits) = self.inlay_map.sync(buffer_snapshot, edits);
+ let (snapshot, edits) = self.fold_map.read(snapshot, edits);
let tab_size = Self::tab_size(&self.buffer, cx);
- let (snapshot, edits) = self.fold_map.read(buffer_snapshot.clone(), edits);
- let (snapshot, edits) = self.inlay_map.sync(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
let (snapshot, edits) = self
.wrap_map
@@ -263,6 +261,7 @@ impl DisplayMap {
self.block_map.read(snapshot, edits);
let (snapshot, edits) = self.inlay_map.splice(to_remove, to_insert);
+ let (snapshot, edits) = self.fold_map.read(snapshot, edits);
let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size);
let (snapshot, edits) = self
.wrap_map
@@ -315,9 +314,9 @@ impl DisplaySnapshot {
pub fn prev_line_boundary(&self, mut point: Point) -> (Point, DisplayPoint) {
loop {
- let mut fold_point = self.fold_snapshot.to_fold_point(point, Bias::Left);
- *fold_point.column_mut() = 0;
- point = fold_point.to_buffer_point(&self.fold_snapshot);
+ let mut inlay_point = self.inlay_snapshot.to_inlay_point(point);
+ inlay_point.0.column = 0;
+ point = self.inlay_snapshot.to_buffer_point(inlay_point);
let mut display_point = self.point_to_display_point(point, Bias::Left);
*display_point.column_mut() = 0;
@@ -331,9 +330,9 @@ impl DisplaySnapshot {
pub fn next_line_boundary(&self, mut point: Point) -> (Point, DisplayPoint) {
loop {
- let mut fold_point = self.fold_snapshot.to_fold_point(point, Bias::Right);
- *fold_point.column_mut() = self.fold_snapshot.line_len(fold_point.row());
- point = fold_point.to_buffer_point(&self.fold_snapshot);
+ let mut inlay_point = self.inlay_snapshot.to_inlay_point(point);
+ inlay_point.0.column = self.inlay_snapshot.line_len(inlay_point.row());
+ point = self.inlay_snapshot.to_buffer_point(inlay_point);
let mut display_point = self.point_to_display_point(point, Bias::Right);
*display_point.column_mut() = self.line_len(display_point.row());
@@ -363,9 +362,9 @@ impl DisplaySnapshot {
}
fn point_to_display_point(&self, point: Point, bias: Bias) -> DisplayPoint {
- let fold_point = self.fold_snapshot.to_fold_point(point, bias);
- let inlay_point = self.inlay_snapshot.to_inlay_point(fold_point);
- let tab_point = self.tab_snapshot.to_tab_point(inlay_point);
+ let inlay_point = self.inlay_snapshot.to_inlay_point(point);
+ let fold_point = self.fold_snapshot.to_fold_point(inlay_point, bias);
+ let tab_point = self.tab_snapshot.to_tab_point(fold_point);
let wrap_point = self.wrap_snapshot.tab_point_to_wrap_point(tab_point);
let block_point = self.block_snapshot.to_block_point(wrap_point);
DisplayPoint(block_point)
@@ -375,9 +374,9 @@ impl DisplaySnapshot {
let block_point = point.0;
let wrap_point = self.block_snapshot.to_wrap_point(block_point);
let tab_point = self.wrap_snapshot.to_tab_point(wrap_point);
- let inlay_point = self.tab_snapshot.to_inlay_point(tab_point, bias).0;
- let fold_point = self.inlay_snapshot.to_fold_point(inlay_point);
- fold_point.to_buffer_point(&self.fold_snapshot)
+ let fold_point = self.tab_snapshot.to_fold_point(tab_point, bias).0;
+ let inlay_point = fold_point.to_inlay_point(&self.fold_snapshot);
+ self.inlay_snapshot.to_buffer_point(inlay_point)
}
pub fn max_point(&self) -> DisplayPoint {
@@ -407,13 +406,13 @@ impl DisplaySnapshot {
&self,
display_rows: Range<u32>,
language_aware: bool,
- suggestion_highlight: Option<HighlightStyle>,
+ inlay_highlights: Option<HighlightStyle>,
) -> DisplayChunks<'_> {
self.block_snapshot.chunks(
display_rows,
language_aware,
Some(&self.text_highlights),
- suggestion_highlight,
+ inlay_highlights,
)
}
@@ -789,9 +788,10 @@ impl DisplayPoint {
pub fn to_offset(self, map: &DisplaySnapshot, bias: Bias) -> usize {
let wrap_point = map.block_snapshot.to_wrap_point(self.0);
let tab_point = map.wrap_snapshot.to_tab_point(wrap_point);
- let inlay_point = map.tab_snapshot.to_inlay_point(tab_point, bias).0;
- let fold_point = map.inlay_snapshot.to_fold_point(inlay_point);
- fold_point.to_buffer_offset(&map.fold_snapshot)
+ let fold_point = map.tab_snapshot.to_fold_point(tab_point, bias).0;
+ let inlay_point = fold_point.to_inlay_point(&map.fold_snapshot);
+ map.inlay_snapshot
+ .to_buffer_offset(map.inlay_snapshot.to_offset(inlay_point))
}
}
@@ -583,7 +583,7 @@ impl BlockSnapshot {
rows: Range<u32>,
language_aware: bool,
text_highlights: Option<&'a TextHighlights>,
- suggestion_highlight: Option<HighlightStyle>,
+ inlay_highlights: Option<HighlightStyle>,
) -> BlockChunks<'a> {
let max_output_row = cmp::min(rows.end, self.transforms.summary().output_rows);
let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>();
@@ -616,7 +616,7 @@ impl BlockSnapshot {
input_start..input_end,
language_aware,
text_highlights,
- suggestion_highlight,
+ inlay_highlights,
),
input_chunk: Default::default(),
transforms: cursor,
@@ -1030,9 +1030,9 @@ mod tests {
let buffer = MultiBuffer::build_simple(text, cx);
let buffer_snapshot = buffer.read(cx).snapshot(cx);
let subscription = buffer.update(cx, |buffer, _| buffer.subscribe());
- let (fold_map, fold_snapshot) = FoldMap::new(buffer_snapshot.clone());
- let (mut inlay_map, inlay_snapshot) = InlayMap::new(fold_snapshot);
- let (tab_map, tab_snapshot) = TabMap::new(inlay_snapshot, 1.try_into().unwrap());
+ let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
+ let (fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot);
+ let (tab_map, tab_snapshot) = TabMap::new(fold_snapshot, 1.try_into().unwrap());
let (wrap_map, wraps_snapshot) = WrapMap::new(tab_snapshot, font_id, 14.0, None, cx);
let mut block_map = BlockMap::new(wraps_snapshot.clone(), 1, 1);
@@ -1175,11 +1175,11 @@ mod tests {
buffer.snapshot(cx)
});
- let (fold_snapshot, fold_edits) =
- fold_map.read(buffer_snapshot, subscription.consume().into_inner());
- let (inlay_snapshot, inlay_edits) = inlay_map.sync(fold_snapshot, fold_edits);
+ let (inlay_snapshot, inlay_edits) =
+ inlay_map.sync(buffer_snapshot, subscription.consume().into_inner());
+ let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
let (tab_snapshot, tab_edits) =
- tab_map.sync(inlay_snapshot, inlay_edits, 4.try_into().unwrap());
+ tab_map.sync(fold_snapshot, fold_edits, 4.try_into().unwrap());
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
wrap_map.sync(tab_snapshot, tab_edits, cx)
});
@@ -1204,9 +1204,9 @@ mod tests {
let buffer = MultiBuffer::build_simple(text, cx);
let buffer_snapshot = buffer.read(cx).snapshot(cx);
- let (_, fold_snapshot) = FoldMap::new(buffer_snapshot.clone());
- let (_, inlay_snapshot) = InlayMap::new(fold_snapshot);
- let (_, tab_snapshot) = TabMap::new(inlay_snapshot, 4.try_into().unwrap());
+ let (_, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
+ let (_, fold_snapshot) = FoldMap::new(inlay_snapshot);
+ let (_, tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap());
let (_, wraps_snapshot) = WrapMap::new(tab_snapshot, font_id, 14.0, Some(60.), cx);
let mut block_map = BlockMap::new(wraps_snapshot.clone(), 1, 1);
@@ -1276,9 +1276,9 @@ mod tests {
};
let mut buffer_snapshot = buffer.read(cx).snapshot(cx);
- let (fold_map, fold_snapshot) = FoldMap::new(buffer_snapshot.clone());
- let (mut inlay_map, inlay_snapshot) = InlayMap::new(fold_snapshot);
- let (tab_map, tab_snapshot) = TabMap::new(inlay_snapshot, 4.try_into().unwrap());
+ let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
+ let (fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot);
+ let (tab_map, tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap());
let (wrap_map, wraps_snapshot) =
WrapMap::new(tab_snapshot, font_id, font_size, wrap_width, cx);
let mut block_map = BlockMap::new(
@@ -1331,11 +1331,11 @@ mod tests {
})
.collect::<Vec<_>>();
- let (fold_snapshot, fold_edits) =
- fold_map.read(buffer_snapshot.clone(), vec![]);
- let (inlay_snapshot, inlay_edits) = inlay_map.sync(fold_snapshot, fold_edits);
+ let (inlay_snapshot, inlay_edits) =
+ inlay_map.sync(buffer_snapshot.clone(), vec![]);
+ let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
let (tab_snapshot, tab_edits) =
- tab_map.sync(inlay_snapshot, inlay_edits, tab_size);
+ tab_map.sync(fold_snapshot, fold_edits, tab_size);
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
wrap_map.sync(tab_snapshot, tab_edits, cx)
});
@@ -1355,11 +1355,11 @@ mod tests {
})
.collect();
- let (fold_snapshot, fold_edits) =
- fold_map.read(buffer_snapshot.clone(), vec![]);
- let (inlay_snapshot, inlay_edits) = inlay_map.sync(fold_snapshot, fold_edits);
+ let (inlay_snapshot, inlay_edits) =
+ inlay_map.sync(buffer_snapshot.clone(), vec![]);
+ let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
let (tab_snapshot, tab_edits) =
- tab_map.sync(inlay_snapshot, inlay_edits, tab_size);
+ tab_map.sync(fold_snapshot, fold_edits, tab_size);
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
wrap_map.sync(tab_snapshot, tab_edits, cx)
});
@@ -1378,9 +1378,10 @@ mod tests {
}
}
- let (fold_snapshot, fold_edits) = fold_map.read(buffer_snapshot.clone(), buffer_edits);
- let (inlay_snapshot, inlay_edits) = inlay_map.sync(fold_snapshot, fold_edits);
- let (tab_snapshot, tab_edits) = tab_map.sync(inlay_snapshot, inlay_edits, tab_size);
+ let (inlay_snapshot, inlay_edits) =
+ inlay_map.sync(buffer_snapshot.clone(), buffer_edits);
+ let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
+ let (tab_snapshot, tab_edits) = tab_map.sync(fold_snapshot, fold_edits, tab_size);
let (wraps_snapshot, wrap_edits) = wrap_map.update(cx, |wrap_map, cx| {
wrap_map.sync(tab_snapshot, tab_edits, cx)
});
@@ -1,7 +1,10 @@
-use super::TextHighlights;
+use super::{
+ inlay_map::{InlayEdit, InlayOffset, InlayPoint, InlaySnapshot},
+ TextHighlights,
+};
use crate::{
- multi_buffer::MultiBufferRows, Anchor, AnchorRangeExt, MultiBufferChunks, MultiBufferSnapshot,
- ToOffset,
+ multi_buffer::{MultiBufferChunks, MultiBufferRows},
+ Anchor, AnchorRangeExt, MultiBufferSnapshot, ToOffset,
};
use collections::BTreeMap;
use gpui::{color::Color, fonts::HighlightStyle};
@@ -29,6 +32,10 @@ impl FoldPoint {
self.0.row
}
+ pub fn column(self) -> u32 {
+ self.0.column
+ }
+
pub fn row_mut(&mut self) -> &mut u32 {
&mut self.0.row
}
@@ -37,20 +44,20 @@ impl FoldPoint {
&mut self.0.column
}
- pub fn to_buffer_point(self, snapshot: &FoldSnapshot) -> Point {
- let mut cursor = snapshot.transforms.cursor::<(FoldPoint, Point)>();
+ pub fn to_inlay_point(self, snapshot: &FoldSnapshot) -> InlayPoint {
+ let mut cursor = snapshot.transforms.cursor::<(FoldPoint, InlayPoint)>();
cursor.seek(&self, Bias::Right, &());
let overshoot = self.0 - cursor.start().0 .0;
- cursor.start().1 + overshoot
+ InlayPoint(cursor.start().1 .0 + overshoot)
}
- pub fn to_buffer_offset(self, snapshot: &FoldSnapshot) -> usize {
- let mut cursor = snapshot.transforms.cursor::<(FoldPoint, Point)>();
+ pub fn to_inlay_offset(self, snapshot: &FoldSnapshot) -> InlayOffset {
+ let mut cursor = snapshot.transforms.cursor::<(FoldPoint, InlayPoint)>();
cursor.seek(&self, Bias::Right, &());
let overshoot = self.0 - cursor.start().0 .0;
snapshot
- .buffer_snapshot
- .point_to_offset(cursor.start().1 + overshoot)
+ .inlay_snapshot
+ .to_offset(InlayPoint(cursor.start().1 .0 + overshoot))
}
pub fn to_offset(self, snapshot: &FoldSnapshot) -> FoldOffset {
@@ -58,17 +65,25 @@ impl FoldPoint {
.transforms
.cursor::<(FoldPoint, TransformSummary)>();
cursor.seek(&self, Bias::Right, &());
+ let inlay_snapshot = &snapshot.inlay_snapshot;
+ let to_inlay_offset = |buffer_offset: usize| {
+ let buffer_point = inlay_snapshot.buffer.offset_to_point(buffer_offset);
+ inlay_snapshot.to_offset(inlay_snapshot.to_inlay_point(buffer_point))
+ };
+ let mut inlay_offset = to_inlay_offset(cursor.start().1.output.len);
let overshoot = self.0 - cursor.start().1.output.lines;
- let mut offset = cursor.start().1.output.len;
if !overshoot.is_zero() {
let transform = cursor.item().expect("display point out of range");
assert!(transform.output_text.is_none());
- let end_buffer_offset = snapshot
- .buffer_snapshot
- .point_to_offset(cursor.start().1.input.lines + overshoot);
- offset += end_buffer_offset - cursor.start().1.input.len;
+ let end_snapshot_offset = snapshot
+ .inlay_snapshot
+ .to_offset(InlayPoint(cursor.start().1.input.lines + overshoot));
+ inlay_offset += end_snapshot_offset - to_inlay_offset(cursor.start().1.input.len);
}
- FoldOffset(offset)
+
+ snapshot
+ .to_fold_point(inlay_snapshot.to_point(inlay_offset), Bias::Right)
+ .to_offset(snapshot)
}
}
@@ -87,8 +102,9 @@ impl<'a> FoldMapWriter<'a> {
) -> (FoldSnapshot, Vec<FoldEdit>) {
let mut edits = Vec::new();
let mut folds = Vec::new();
- let buffer = self.0.buffer.lock().clone();
+ let snapshot = self.0.inlay_snapshot.lock().clone();
for range in ranges.into_iter() {
+ let buffer = &snapshot.buffer;
let range = range.start.to_offset(&buffer)..range.end.to_offset(&buffer);
// Ignore any empty ranges.
@@ -103,31 +119,35 @@ impl<'a> FoldMapWriter<'a> {
}
folds.push(fold);
- edits.push(text::Edit {
- old: range.clone(),
- new: range,
+
+ let inlay_range =
+ snapshot.to_inlay_offset(range.start)..snapshot.to_inlay_offset(range.end);
+ edits.push(InlayEdit {
+ old: inlay_range.clone(),
+ new: inlay_range,
});
}
- folds.sort_unstable_by(|a, b| sum_tree::SeekTarget::cmp(a, b, &buffer));
+ let buffer = &snapshot.buffer;
+ folds.sort_unstable_by(|a, b| sum_tree::SeekTarget::cmp(a, b, buffer));
self.0.folds = {
let mut new_tree = SumTree::new();
let mut cursor = self.0.folds.cursor::<Fold>();
for fold in folds {
- new_tree.append(cursor.slice(&fold, Bias::Right, &buffer), &buffer);
- new_tree.push(fold, &buffer);
+ new_tree.append(cursor.slice(&fold, Bias::Right, buffer), buffer);
+ new_tree.push(fold, buffer);
}
- new_tree.append(cursor.suffix(&buffer), &buffer);
+ new_tree.append(cursor.suffix(buffer), buffer);
new_tree
};
- consolidate_buffer_edits(&mut edits);
- let edits = self.0.sync(buffer.clone(), edits);
+ consolidate_inlay_edits(&mut edits);
+ let edits = self.0.sync(snapshot.clone(), edits);
let snapshot = FoldSnapshot {
transforms: self.0.transforms.lock().clone(),
folds: self.0.folds.clone(),
- buffer_snapshot: buffer,
+ inlay_snapshot: snapshot,
version: self.0.version.load(SeqCst),
ellipses_color: self.0.ellipses_color,
};
@@ -141,20 +161,23 @@ impl<'a> FoldMapWriter<'a> {
) -> (FoldSnapshot, Vec<FoldEdit>) {
let mut edits = Vec::new();
let mut fold_ixs_to_delete = Vec::new();
- let buffer = self.0.buffer.lock().clone();
+ let snapshot = self.0.inlay_snapshot.lock().clone();
+ let buffer = &snapshot.buffer;
for range in ranges.into_iter() {
// Remove intersecting folds and add their ranges to edits that are passed to sync.
- let mut folds_cursor = intersecting_folds(&buffer, &self.0.folds, range, inclusive);
+ let mut folds_cursor = intersecting_folds(&snapshot, &self.0.folds, range, inclusive);
while let Some(fold) = folds_cursor.item() {
- let offset_range = fold.0.start.to_offset(&buffer)..fold.0.end.to_offset(&buffer);
+ let offset_range = fold.0.start.to_offset(buffer)..fold.0.end.to_offset(buffer);
if offset_range.end > offset_range.start {
- edits.push(text::Edit {
- old: offset_range.clone(),
- new: offset_range,
+ let inlay_range = snapshot.to_inlay_offset(offset_range.start)
+ ..snapshot.to_inlay_offset(offset_range.end);
+ edits.push(InlayEdit {
+ old: inlay_range.clone(),
+ new: inlay_range,
});
}
fold_ixs_to_delete.push(*folds_cursor.start());
- folds_cursor.next(&buffer);
+ folds_cursor.next(buffer);
}
}
@@ -165,19 +188,19 @@ impl<'a> FoldMapWriter<'a> {
let mut cursor = self.0.folds.cursor::<usize>();
let mut folds = SumTree::new();
for fold_ix in fold_ixs_to_delete {
- folds.append(cursor.slice(&fold_ix, Bias::Right, &buffer), &buffer);
- cursor.next(&buffer);
+ folds.append(cursor.slice(&fold_ix, Bias::Right, buffer), buffer);
+ cursor.next(buffer);
}
- folds.append(cursor.suffix(&buffer), &buffer);
+ folds.append(cursor.suffix(buffer), buffer);
folds
};
- consolidate_buffer_edits(&mut edits);
- let edits = self.0.sync(buffer.clone(), edits);
+ consolidate_inlay_edits(&mut edits);
+ let edits = self.0.sync(snapshot.clone(), edits);
let snapshot = FoldSnapshot {
transforms: self.0.transforms.lock().clone(),
folds: self.0.folds.clone(),
- buffer_snapshot: buffer,
+ inlay_snapshot: snapshot,
version: self.0.version.load(SeqCst),
ellipses_color: self.0.ellipses_color,
};
@@ -186,7 +209,7 @@ impl<'a> FoldMapWriter<'a> {
}
pub struct FoldMap {
- buffer: Mutex<MultiBufferSnapshot>,
+ inlay_snapshot: Mutex<InlaySnapshot>,
transforms: Mutex<SumTree<Transform>>,
folds: SumTree<Fold>,
version: AtomicUsize,
@@ -194,15 +217,15 @@ pub struct FoldMap {
}
impl FoldMap {
- pub fn new(buffer: MultiBufferSnapshot) -> (Self, FoldSnapshot) {
+ pub fn new(inlay_snapshot: InlaySnapshot) -> (Self, FoldSnapshot) {
let this = Self {
- buffer: Mutex::new(buffer.clone()),
+ inlay_snapshot: Mutex::new(inlay_snapshot.clone()),
folds: Default::default(),
transforms: Mutex::new(SumTree::from_item(
Transform {
summary: TransformSummary {
- input: buffer.text_summary(),
- output: buffer.text_summary(),
+ input: inlay_snapshot.text_summary(),
+ output: inlay_snapshot.text_summary(),
},
output_text: None,
},
@@ -215,7 +238,7 @@ impl FoldMap {
let snapshot = FoldSnapshot {
transforms: this.transforms.lock().clone(),
folds: this.folds.clone(),
- buffer_snapshot: this.buffer.lock().clone(),
+ inlay_snapshot: inlay_snapshot.clone(),
version: this.version.load(SeqCst),
ellipses_color: None,
};
@@ -224,15 +247,15 @@ impl FoldMap {
pub fn read(
&self,
- buffer: MultiBufferSnapshot,
- edits: Vec<Edit<usize>>,
+ inlay_snapshot: InlaySnapshot,
+ edits: Vec<InlayEdit>,
) -> (FoldSnapshot, Vec<FoldEdit>) {
- let edits = self.sync(buffer, edits);
+ let edits = self.sync(inlay_snapshot, edits);
self.check_invariants();
let snapshot = FoldSnapshot {
transforms: self.transforms.lock().clone(),
folds: self.folds.clone(),
- buffer_snapshot: self.buffer.lock().clone(),
+ inlay_snapshot: self.inlay_snapshot.lock().clone(),
version: self.version.load(SeqCst),
ellipses_color: self.ellipses_color,
};
@@ -241,10 +264,10 @@ impl FoldMap {
pub fn write(
&mut self,
- buffer: MultiBufferSnapshot,
- edits: Vec<Edit<usize>>,
+ inlay_snapshot: InlaySnapshot,
+ edits: Vec<InlayEdit>,
) -> (FoldMapWriter, FoldSnapshot, Vec<FoldEdit>) {
- let (snapshot, edits) = self.read(buffer, edits);
+ let (snapshot, edits) = self.read(inlay_snapshot, edits);
(FoldMapWriter(self), snapshot, edits)
}
@@ -259,146 +282,109 @@ impl FoldMap {
fn check_invariants(&self) {
if cfg!(test) {
+ let inlay_snapshot = self.inlay_snapshot.lock();
assert_eq!(
self.transforms.lock().summary().input.len,
- self.buffer.lock().len(),
- "transform tree does not match buffer's length"
+ inlay_snapshot.to_buffer_offset(inlay_snapshot.len()),
+ "transform tree does not match inlay snapshot's length"
);
let mut folds = self.folds.iter().peekable();
while let Some(fold) = folds.next() {
if let Some(next_fold) = folds.peek() {
- let comparison = fold.0.cmp(&next_fold.0, &self.buffer.lock());
+ let comparison = fold.0.cmp(&next_fold.0, &self.inlay_snapshot.lock().buffer);
assert!(comparison.is_le());
}
}
}
}
- fn sync(
- &self,
- new_buffer: MultiBufferSnapshot,
- buffer_edits: Vec<text::Edit<usize>>,
- ) -> Vec<FoldEdit> {
- if buffer_edits.is_empty() {
- let mut buffer = self.buffer.lock();
- if buffer.edit_count() != new_buffer.edit_count()
- || buffer.parse_count() != new_buffer.parse_count()
- || buffer.diagnostics_update_count() != new_buffer.diagnostics_update_count()
- || buffer.git_diff_update_count() != new_buffer.git_diff_update_count()
- || buffer.trailing_excerpt_update_count()
- != new_buffer.trailing_excerpt_update_count()
- {
- self.version.fetch_add(1, SeqCst);
- }
- *buffer = new_buffer;
- Vec::new()
- } else {
- let mut buffer_edits_iter = buffer_edits.iter().cloned().peekable();
+ fn sync(&self, inlay_snapshot: InlaySnapshot, inlay_edits: Vec<InlayEdit>) -> Vec<FoldEdit> {
+ let buffer = &inlay_snapshot.buffer;
+ let mut snapshot = self.inlay_snapshot.lock();
- let mut new_transforms = SumTree::new();
- let mut transforms = self.transforms.lock();
- let mut cursor = transforms.cursor::<usize>();
- cursor.seek(&0, Bias::Right, &());
+ let mut new_snapshot = snapshot.clone();
+ if new_snapshot.version != inlay_snapshot.version {
+ new_snapshot.version += 1;
+ }
- while let Some(mut edit) = buffer_edits_iter.next() {
- new_transforms.append(cursor.slice(&edit.old.start, Bias::Left, &()), &());
- edit.new.start -= edit.old.start - cursor.start();
- edit.old.start = *cursor.start();
+ let mut inlay_edits_iter = inlay_edits.iter().cloned().peekable();
- cursor.seek(&edit.old.end, Bias::Right, &());
- cursor.next(&());
+ let mut new_transforms = SumTree::new();
+ let mut transforms = self.transforms.lock();
+ let mut cursor = transforms.cursor::<usize>();
+ cursor.seek(&0, Bias::Right, &());
- let mut delta = edit.new.len() as isize - edit.old.len() as isize;
- loop {
- edit.old.end = *cursor.start();
+ while let Some(mut edit) = inlay_edits_iter.next() {
+ new_transforms.append(cursor.slice(&edit.old.start, Bias::Left, &()), &());
+ edit.new.start -= edit.old.start - cursor.start();
+ edit.old.start = *cursor.start();
- if let Some(next_edit) = buffer_edits_iter.peek() {
- if next_edit.old.start > edit.old.end {
- break;
- }
+ cursor.seek(&edit.old.end, Bias::Right, &());
+ cursor.next(&());
- let next_edit = buffer_edits_iter.next().unwrap();
- delta += next_edit.new.len() as isize - next_edit.old.len() as isize;
+ let mut delta = edit.new.len() as isize - edit.old.len() as isize;
+ loop {
+ edit.old.end = *cursor.start();
- if next_edit.old.end >= edit.old.end {
- edit.old.end = next_edit.old.end;
- cursor.seek(&edit.old.end, Bias::Right, &());
- cursor.next(&());
- }
- } else {
+ if let Some(next_edit) = inlay_edits_iter.peek() {
+ if next_edit.old.start > edit.old.end {
break;
}
- }
-
- edit.new.end = ((edit.new.start + edit.old.len()) as isize + delta) as usize;
- let anchor = new_buffer.anchor_before(edit.new.start);
- let mut folds_cursor = self.folds.cursor::<Fold>();
- folds_cursor.seek(&Fold(anchor..Anchor::max()), Bias::Left, &new_buffer);
+ let next_edit = inlay_edits_iter.next().unwrap();
+ delta += next_edit.new.len() as isize - next_edit.old.len() as isize;
- let mut folds = iter::from_fn({
- let buffer = &new_buffer;
- move || {
- let item = folds_cursor
- .item()
- .map(|f| f.0.start.to_offset(buffer)..f.0.end.to_offset(buffer));
- folds_cursor.next(buffer);
- item
+ if next_edit.old.end >= edit.old.end {
+ edit.old.end = next_edit.old.end;
+ cursor.seek(&edit.old.end, Bias::Right, &());
+ cursor.next(&());
}
- })
- .peekable();
+ } else {
+ break;
+ }
+ }
- while folds.peek().map_or(false, |fold| fold.start < edit.new.end) {
- let mut fold = folds.next().unwrap();
- let sum = new_transforms.summary();
+ edit.new.end = ((edit.new.start + edit.old.len()) as isize + delta) as usize;
- assert!(fold.start >= sum.input.len);
+ let anchor = buffer.anchor_before(inlay_snapshot.to_buffer_offset(edit.new.start));
+ let mut folds_cursor = self.folds.cursor::<Fold>();
+ folds_cursor.seek(&Fold(anchor..Anchor::max()), Bias::Left, &buffer);
- while folds
- .peek()
- .map_or(false, |next_fold| next_fold.start <= fold.end)
- {
- let next_fold = folds.next().unwrap();
- if next_fold.end > fold.end {
- fold.end = next_fold.end;
- }
- }
+ let mut folds = iter::from_fn({
+ move || {
+ let item = folds_cursor.item().map(|f| {
+ let fold_buffer_start = f.0.start.to_offset(buffer);
+ let fold_buffer_end = f.0.end.to_offset(buffer);
- if fold.start > sum.input.len {
- let text_summary = new_buffer
- .text_summary_for_range::<TextSummary, _>(sum.input.len..fold.start);
- new_transforms.push(
- Transform {
- summary: TransformSummary {
- output: text_summary.clone(),
- input: text_summary,
- },
- output_text: None,
- },
- &(),
- );
- }
+ inlay_snapshot.to_inlay_offset(fold_buffer_start)
+ ..inlay_snapshot.to_inlay_offset(fold_buffer_end)
+ });
+ folds_cursor.next(buffer);
+ item
+ }
+ })
+ .peekable();
- if fold.end > fold.start {
- let output_text = "⋯";
- new_transforms.push(
- Transform {
- summary: TransformSummary {
- output: TextSummary::from(output_text),
- input: new_buffer.text_summary_for_range(fold.start..fold.end),
- },
- output_text: Some(output_text),
- },
- &(),
- );
+ while folds.peek().map_or(false, |fold| fold.start < edit.new.end) {
+ let mut fold = folds.next().unwrap();
+ let sum = new_transforms.summary();
+
+ assert!(fold.start >= sum.input.len);
+
+ while folds
+ .peek()
+ .map_or(false, |next_fold| next_fold.start <= fold.end)
+ {
+ let next_fold = folds.next().unwrap();
+ if next_fold.end > fold.end {
+ fold.end = next_fold.end;
}
}
- let sum = new_transforms.summary();
- if sum.input.len < edit.new.end {
- let text_summary = new_buffer
- .text_summary_for_range::<TextSummary, _>(sum.input.len..edit.new.end);
+ if fold.start > sum.input.len {
+ let text_summary =
+ buffer.text_summary_for_range::<TextSummary, _>(sum.input.len..fold.start);
new_transforms.push(
Transform {
summary: TransformSummary {
@@ -410,11 +396,25 @@ impl FoldMap {
&(),
);
}
+
+ if fold.end > fold.start {
+ let output_text = "⋯";
+ new_transforms.push(
+ Transform {
+ summary: TransformSummary {
+ output: TextSummary::from(output_text),
+ input: buffer.text_summary_for_range(fold.start..fold.end),
+ },
+ output_text: Some(output_text),
+ },
+ &(),
+ );
+ }
}
- new_transforms.append(cursor.suffix(&()), &());
- if new_transforms.is_empty() {
- let text_summary = new_buffer.text_summary();
+ let sum = new_transforms.summary();
+ if sum.input.len < edit.new.end {
+ let text_summary = buffer.text_summary_for_range(sum.input.len..edit.new.end);
new_transforms.push(
Transform {
summary: TransformSummary {
@@ -426,59 +426,74 @@ impl FoldMap {
&(),
);
}
+ }
- drop(cursor);
+ new_transforms.append(cursor.suffix(&()), &());
+ if new_transforms.is_empty() {
+ let text_summary = inlay_snapshot.text_summary();
+ new_transforms.push(
+ Transform {
+ summary: TransformSummary {
+ output: text_summary.clone(),
+ input: text_summary,
+ },
+ output_text: None,
+ },
+ &(),
+ );
+ }
- let mut fold_edits = Vec::with_capacity(buffer_edits.len());
- {
- let mut old_transforms = transforms.cursor::<(usize, FoldOffset)>();
- let mut new_transforms = new_transforms.cursor::<(usize, FoldOffset)>();
+ drop(cursor);
- for mut edit in buffer_edits {
- old_transforms.seek(&edit.old.start, Bias::Left, &());
- if old_transforms.item().map_or(false, |t| t.is_fold()) {
- edit.old.start = old_transforms.start().0;
- }
- let old_start =
- old_transforms.start().1 .0 + (edit.old.start - old_transforms.start().0);
+ let mut fold_edits = Vec::with_capacity(inlay_edits.len());
+ {
+ let mut old_transforms = transforms.cursor::<(usize, FoldOffset)>();
+ let mut new_transforms = new_transforms.cursor::<(usize, FoldOffset)>();
- old_transforms.seek_forward(&edit.old.end, Bias::Right, &());
- if old_transforms.item().map_or(false, |t| t.is_fold()) {
- old_transforms.next(&());
- edit.old.end = old_transforms.start().0;
- }
- let old_end =
- old_transforms.start().1 .0 + (edit.old.end - old_transforms.start().0);
+ for mut edit in inlay_edits {
+ old_transforms.seek(&edit.old.start, Bias::Left, &());
+ if old_transforms.item().map_or(false, |t| t.is_fold()) {
+ edit.old.start = old_transforms.start().0;
+ }
+ let old_start =
+ old_transforms.start().1 .0 + (edit.old.start - old_transforms.start().0);
- new_transforms.seek(&edit.new.start, Bias::Left, &());
- if new_transforms.item().map_or(false, |t| t.is_fold()) {
- edit.new.start = new_transforms.start().0;
- }
- let new_start =
- new_transforms.start().1 .0 + (edit.new.start - new_transforms.start().0);
+ old_transforms.seek_forward(&edit.old.end, Bias::Right, &());
+ if old_transforms.item().map_or(false, |t| t.is_fold()) {
+ old_transforms.next(&());
+ edit.old.end = old_transforms.start().0;
+ }
+ let old_end =
+ old_transforms.start().1 .0 + (edit.old.end - old_transforms.start().0);
- new_transforms.seek_forward(&edit.new.end, Bias::Right, &());
- if new_transforms.item().map_or(false, |t| t.is_fold()) {
- new_transforms.next(&());
- edit.new.end = new_transforms.start().0;
- }
- let new_end =
- new_transforms.start().1 .0 + (edit.new.end - new_transforms.start().0);
+ new_transforms.seek(&edit.new.start, Bias::Left, &());
+ if new_transforms.item().map_or(false, |t| t.is_fold()) {
+ edit.new.start = new_transforms.start().0;
+ }
+ let new_start =
+ new_transforms.start().1 .0 + (edit.new.start - new_transforms.start().0);
- fold_edits.push(FoldEdit {
- old: FoldOffset(old_start)..FoldOffset(old_end),
- new: FoldOffset(new_start)..FoldOffset(new_end),
- });
+ new_transforms.seek_forward(&edit.new.end, Bias::Right, &());
+ if new_transforms.item().map_or(false, |t| t.is_fold()) {
+ new_transforms.next(&());
+ edit.new.end = new_transforms.start().0;
}
+ let new_end =
+ new_transforms.start().1 .0 + (edit.new.end - new_transforms.start().0);
- consolidate_fold_edits(&mut fold_edits);
+ fold_edits.push(FoldEdit {
+ old: FoldOffset(old_start)..FoldOffset(old_end),
+ new: FoldOffset(new_start)..FoldOffset(new_end),
+ });
}
- *transforms = new_transforms;
- *self.buffer.lock() = new_buffer;
- self.version.fetch_add(1, SeqCst);
- fold_edits
+ consolidate_fold_edits(&mut fold_edits);
}
+
+ *transforms = new_transforms;
+ *self.inlay_snapshot.lock() = inlay_snapshot;
+ self.version.fetch_add(1, SeqCst);
+ fold_edits
}
}
@@ -486,26 +501,22 @@ impl FoldMap {
pub struct FoldSnapshot {
transforms: SumTree<Transform>,
folds: SumTree<Fold>,
- buffer_snapshot: MultiBufferSnapshot,
+ pub inlay_snapshot: InlaySnapshot,
pub version: usize,
pub ellipses_color: Option<Color>,
}
impl FoldSnapshot {
- pub fn buffer_snapshot(&self) -> &MultiBufferSnapshot {
- &self.buffer_snapshot
- }
-
#[cfg(test)]
pub fn text(&self) -> String {
- self.chunks(FoldOffset(0)..self.len(), false, None)
+ self.chunks(FoldOffset(0)..self.len(), false, None, None)
.map(|c| c.text)
.collect()
}
#[cfg(test)]
pub fn fold_count(&self) -> usize {
- self.folds.items(&self.buffer_snapshot).len()
+ self.folds.items(&self.inlay_snapshot.buffer).len()
}
pub fn text_summary(&self) -> TextSummary {
@@ -529,7 +540,8 @@ impl FoldSnapshot {
let buffer_start = cursor.start().1 + start_in_transform;
let buffer_end = cursor.start().1 + end_in_transform;
summary = self
- .buffer_snapshot
+ .inlay_snapshot
+ .buffer
.text_summary_for_range(buffer_start..buffer_end);
}
}
@@ -547,7 +559,8 @@ impl FoldSnapshot {
let buffer_start = cursor.start().1;
let buffer_end = cursor.start().1 + end_in_transform;
summary += self
- .buffer_snapshot
+ .inlay_snapshot
+ .buffer
.text_summary_for_range::<TextSummary, _>(buffer_start..buffer_end);
}
}
@@ -556,8 +569,8 @@ impl FoldSnapshot {
summary
}
- pub fn to_fold_point(&self, point: Point, bias: Bias) -> FoldPoint {
- let mut cursor = self.transforms.cursor::<(Point, FoldPoint)>();
+ pub fn to_fold_point(&self, point: InlayPoint, bias: Bias) -> FoldPoint {
+ let mut cursor = self.transforms.cursor::<(InlayPoint, FoldPoint)>();
cursor.seek(&point, Bias::Right, &());
if cursor.item().map_or(false, |t| t.is_fold()) {
if bias == Bias::Left || point == cursor.start().0 {
@@ -566,7 +579,7 @@ impl FoldSnapshot {
cursor.end(&()).1
}
} else {
- let overshoot = point - cursor.start().0;
+ let overshoot = InlayPoint(point.0 - cursor.start().0 .0);
FoldPoint(cmp::min(
cursor.start().1 .0 + overshoot,
cursor.end(&()).1 .0,
@@ -599,7 +612,7 @@ impl FoldSnapshot {
let overshoot = fold_point.0 - cursor.start().0 .0;
let buffer_point = cursor.start().1 + overshoot;
- let input_buffer_rows = self.buffer_snapshot.buffer_rows(buffer_point.row);
+ let input_buffer_rows = self.inlay_snapshot.buffer.buffer_rows(buffer_point.row);
FoldBufferRows {
fold_point,
@@ -621,10 +634,10 @@ impl FoldSnapshot {
where
T: ToOffset,
{
- let mut folds = intersecting_folds(&self.buffer_snapshot, &self.folds, range, false);
+ let mut folds = intersecting_folds(&self.inlay_snapshot, &self.folds, range, false);
iter::from_fn(move || {
let item = folds.item().map(|f| &f.0);
- folds.next(&self.buffer_snapshot);
+ folds.next(&self.inlay_snapshot.buffer);
item
})
}
@@ -633,7 +646,7 @@ impl FoldSnapshot {
where
T: ToOffset,
{
- let offset = offset.to_offset(&self.buffer_snapshot);
+ let offset = offset.to_offset(&self.inlay_snapshot.buffer);
let mut cursor = self.transforms.cursor::<usize>();
cursor.seek(&offset, Bias::Right, &());
cursor.item().map_or(false, |t| t.output_text.is_some())
@@ -641,6 +654,7 @@ impl FoldSnapshot {
pub fn is_line_folded(&self, buffer_row: u32) -> bool {
let mut cursor = self.transforms.cursor::<Point>();
+ // TODO kb is this right?
cursor.seek(&Point::new(buffer_row, 0), Bias::Right, &());
while let Some(transform) = cursor.item() {
if transform.output_text.is_some() {
@@ -660,6 +674,7 @@ impl FoldSnapshot {
range: Range<FoldOffset>,
language_aware: bool,
text_highlights: Option<&'a TextHighlights>,
+ inlay_highlights: Option<HighlightStyle>,
) -> FoldChunks<'a> {
let mut highlight_endpoints = Vec::new();
let mut transform_cursor = self.transforms.cursor::<(FoldOffset, usize)>();
@@ -681,12 +696,13 @@ impl FoldSnapshot {
while transform_cursor.start().0 < range.end {
if !transform_cursor.item().unwrap().is_fold() {
let transform_start = self
- .buffer_snapshot
+ .inlay_snapshot
+ .buffer
.anchor_after(cmp::max(buffer_start, transform_cursor.start().1));
let transform_end = {
let overshoot = range.end.0 - transform_cursor.start().0 .0;
- self.buffer_snapshot.anchor_before(cmp::min(
+ self.inlay_snapshot.buffer.anchor_before(cmp::min(
transform_cursor.end(&()).1,
transform_cursor.start().1 + overshoot,
))
@@ -697,7 +713,8 @@ impl FoldSnapshot {
let ranges = &highlights.1;
let start_ix = match ranges.binary_search_by(|probe| {
- let cmp = probe.end.cmp(&transform_start, self.buffer_snapshot());
+ let cmp =
+ probe.end.cmp(&transform_start, &self.inlay_snapshot.buffer);
if cmp.is_gt() {
Ordering::Greater
} else {
@@ -709,20 +726,20 @@ impl FoldSnapshot {
for range in &ranges[start_ix..] {
if range
.start
- .cmp(&transform_end, &self.buffer_snapshot)
+ .cmp(&transform_end, &self.inlay_snapshot.buffer)
.is_ge()
{
break;
}
highlight_endpoints.push(HighlightEndpoint {
- offset: range.start.to_offset(&self.buffer_snapshot),
+ offset: range.start.to_offset(&self.inlay_snapshot.buffer),
is_start: true,
tag: *tag,
style,
});
highlight_endpoints.push(HighlightEndpoint {
- offset: range.end.to_offset(&self.buffer_snapshot),
+ offset: range.end.to_offset(&self.inlay_snapshot.buffer),
is_start: false,
tag: *tag,
style,
@@ -741,9 +758,10 @@ impl FoldSnapshot {
FoldChunks {
transform_cursor,
buffer_chunks: self
- .buffer_snapshot
+ .inlay_snapshot
+ .buffer
.chunks(buffer_start..buffer_end, language_aware),
- buffer_chunk: None,
+ inlay_chunk: None,
buffer_offset: buffer_start,
output_offset: range.start.0,
max_output_offset: range.end.0,
@@ -753,6 +771,11 @@ impl FoldSnapshot {
}
}
+ pub fn chars_at(&self, start: FoldPoint) -> impl '_ + Iterator<Item = char> {
+ self.chunks(start.to_offset(self)..self.len(), false, None, None)
+ .flat_map(|chunk| chunk.text.chars())
+ }
+
#[cfg(test)]
pub fn clip_offset(&self, offset: FoldOffset, bias: Bias) -> FoldOffset {
let mut cursor = self.transforms.cursor::<(FoldOffset, usize)>();
@@ -768,7 +791,8 @@ impl FoldSnapshot {
} else {
let overshoot = offset.0 - transform_start;
let buffer_offset = cursor.start().1 + overshoot;
- let clipped_buffer_offset = self.buffer_snapshot.clip_offset(buffer_offset, bias);
+ let clipped_buffer_offset =
+ self.inlay_snapshot.buffer.clip_offset(buffer_offset, bias);
FoldOffset(
(offset.0 as isize + (clipped_buffer_offset as isize - buffer_offset as isize))
as usize,
@@ -794,7 +818,7 @@ impl FoldSnapshot {
let overshoot = point.0 - transform_start;
let buffer_position = cursor.start().1 + overshoot;
let clipped_buffer_position =
- self.buffer_snapshot.clip_point(buffer_position, bias);
+ self.inlay_snapshot.buffer.clip_point(buffer_position, bias);
FoldPoint(cursor.start().0 .0 + (clipped_buffer_position - cursor.start().1))
}
} else {
@@ -804,7 +828,7 @@ impl FoldSnapshot {
}
fn intersecting_folds<'a, T>(
- buffer: &'a MultiBufferSnapshot,
+ inlay_snapshot: &'a InlaySnapshot,
folds: &'a SumTree<Fold>,
range: Range<T>,
inclusive: bool,
@@ -812,6 +836,7 @@ fn intersecting_folds<'a, T>(
where
T: ToOffset,
{
+ let buffer = &inlay_snapshot.buffer;
let start = buffer.anchor_before(range.start.to_offset(buffer));
let end = buffer.anchor_after(range.end.to_offset(buffer));
let mut cursor = folds.filter::<_, usize>(move |summary| {
@@ -828,7 +853,7 @@ where
cursor
}
-fn consolidate_buffer_edits(edits: &mut Vec<text::Edit<usize>>) {
+fn consolidate_inlay_edits(edits: &mut Vec<InlayEdit>) {
edits.sort_unstable_by(|a, b| {
a.old
.start
@@ -956,7 +981,7 @@ impl Default for FoldSummary {
impl sum_tree::Summary for FoldSummary {
type Context = MultiBufferSnapshot;
- fn add_summary(&mut self, other: &Self, buffer: &MultiBufferSnapshot) {
+ fn add_summary(&mut self, other: &Self, buffer: &Self::Context) {
if other.min_start.cmp(&self.min_start, buffer) == Ordering::Less {
self.min_start = other.min_start.clone();
}
@@ -1034,7 +1059,7 @@ impl<'a> Iterator for FoldBufferRows<'a> {
pub struct FoldChunks<'a> {
transform_cursor: Cursor<'a, Transform, (FoldOffset, usize)>,
buffer_chunks: MultiBufferChunks<'a>,
- buffer_chunk: Option<(usize, Chunk<'a>)>,
+ inlay_chunk: Option<(usize, Chunk<'a>)>,
buffer_offset: usize,
output_offset: usize,
max_output_offset: usize,
@@ -1056,7 +1081,7 @@ impl<'a> Iterator for FoldChunks<'a> {
// If we're in a fold, then return the fold's display text and
// advance the transform and buffer cursors to the end of the fold.
if let Some(output_text) = transform.output_text {
- self.buffer_chunk.take();
+ self.inlay_chunk.take();
self.buffer_offset += transform.summary.input.len;
self.buffer_chunks.seek(self.buffer_offset);
@@ -1093,13 +1118,13 @@ impl<'a> Iterator for FoldChunks<'a> {
}
// Retrieve a chunk from the current location in the buffer.
- if self.buffer_chunk.is_none() {
+ if self.inlay_chunk.is_none() {
let chunk_offset = self.buffer_chunks.offset();
- self.buffer_chunk = self.buffer_chunks.next().map(|chunk| (chunk_offset, chunk));
+ self.inlay_chunk = self.buffer_chunks.next().map(|chunk| (chunk_offset, chunk));
}
// Otherwise, take a chunk from the buffer's text.
- if let Some((buffer_chunk_start, mut chunk)) = self.buffer_chunk {
+ if let Some((buffer_chunk_start, mut chunk)) = self.inlay_chunk {
let buffer_chunk_end = buffer_chunk_start + chunk.text.len();
let transform_end = self.transform_cursor.end(&()).1;
let chunk_end = buffer_chunk_end
@@ -1120,7 +1145,7 @@ impl<'a> Iterator for FoldChunks<'a> {
if chunk_end == transform_end {
self.transform_cursor.next(&());
} else if chunk_end == buffer_chunk_end {
- self.buffer_chunk.take();
+ self.inlay_chunk.take();
}
self.buffer_offset = chunk_end;
@@ -1163,11 +1188,15 @@ impl FoldOffset {
.transforms
.cursor::<(FoldOffset, TransformSummary)>();
cursor.seek(&self, Bias::Right, &());
+ // TODO kb seems wrong to use buffer points?
let overshoot = if cursor.item().map_or(true, |t| t.is_fold()) {
Point::new(0, (self.0 - cursor.start().0 .0) as u32)
} else {
let buffer_offset = cursor.start().1.input.len + self.0 - cursor.start().0 .0;
- let buffer_point = snapshot.buffer_snapshot.offset_to_point(buffer_offset);
+ let buffer_point = snapshot
+ .inlay_snapshot
+ .buffer
+ .offset_to_point(buffer_offset);
buffer_point - cursor.start().1.input.lines
};
FoldPoint(cursor.start().1.output.lines + overshoot)
@@ -1202,6 +1231,18 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldOffset {
}
}
+impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayPoint {
+ fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
+ self.0 += &summary.input.lines;
+ }
+}
+
+impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayOffset {
+ fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
+ self.0 += &summary.input.len;
+ }
+}
+
impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point {
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
*self += &summary.input.lines;
@@ -1219,7 +1260,7 @@ pub type FoldEdit = Edit<FoldOffset>;
#[cfg(test)]
mod tests {
use super::*;
- use crate::{MultiBuffer, ToPoint};
+ use crate::{display_map::inlay_map::InlayMap, MultiBuffer, ToPoint};
use collections::HashSet;
use rand::prelude::*;
use settings::SettingsStore;
@@ -1235,9 +1276,10 @@ mod tests {
let buffer = MultiBuffer::build_simple(&sample_text(5, 6, 'a'), cx);
let subscription = buffer.update(cx, |buffer, _| buffer.subscribe());
let buffer_snapshot = buffer.read(cx).snapshot(cx);
- let mut map = FoldMap::new(buffer_snapshot.clone()).0;
+ let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
+ let mut map = FoldMap::new(inlay_snapshot.clone()).0;
- let (mut writer, _, _) = map.write(buffer_snapshot, vec![]);
+ let (mut writer, _, _) = map.write(inlay_snapshot, vec![]);
let (snapshot2, edits) = writer.fold(vec![
Point::new(0, 2)..Point::new(2, 2),
Point::new(2, 4)..Point::new(4, 1),
@@ -1268,7 +1310,10 @@ mod tests {
);
buffer.snapshot(cx)
});
- let (snapshot3, edits) = map.read(buffer_snapshot, subscription.consume().into_inner());
+
+ let (inlay_snapshot, inlay_edits) =
+ inlay_map.sync(buffer_snapshot, subscription.consume().into_inner());
+ let (snapshot3, edits) = map.read(inlay_snapshot, inlay_edits);
assert_eq!(snapshot3.text(), "123a⋯c123c⋯eeeee");
assert_eq!(
edits,
@@ -1288,17 +1333,19 @@ mod tests {
buffer.edit([(Point::new(2, 6)..Point::new(4, 3), "456")], None, cx);
buffer.snapshot(cx)
});
- let (snapshot4, _) = map.read(buffer_snapshot.clone(), subscription.consume().into_inner());
+ let (inlay_snapshot, inlay_edits) =
+ inlay_map.sync(buffer_snapshot, subscription.consume().into_inner());
+ let (snapshot4, _) = map.read(inlay_snapshot.clone(), inlay_edits);
assert_eq!(snapshot4.text(), "123a⋯c123456eee");
- let (mut writer, _, _) = map.write(buffer_snapshot.clone(), vec![]);
+ let (mut writer, _, _) = map.write(inlay_snapshot.clone(), vec![]);
writer.unfold(Some(Point::new(0, 4)..Point::new(0, 4)), false);
- let (snapshot5, _) = map.read(buffer_snapshot.clone(), vec![]);
+ let (snapshot5, _) = map.read(inlay_snapshot.clone(), vec![]);
assert_eq!(snapshot5.text(), "123a⋯c123456eee");
- let (mut writer, _, _) = map.write(buffer_snapshot.clone(), vec![]);
+ let (mut writer, _, _) = map.write(inlay_snapshot.clone(), vec![]);
writer.unfold(Some(Point::new(0, 4)..Point::new(0, 4)), true);
- let (snapshot6, _) = map.read(buffer_snapshot, vec![]);
+ let (snapshot6, _) = map.read(inlay_snapshot, vec![]);
assert_eq!(snapshot6.text(), "123aaaaa\nbbbbbb\nccc123456eee");
}
@@ -1,9 +1,6 @@
-use super::{
- fold_map::{FoldBufferRows, FoldChunks, FoldEdit, FoldOffset, FoldPoint, FoldSnapshot},
- TextHighlights,
-};
use crate::{
inlay_cache::{Inlay, InlayId, InlayProperties},
+ multi_buffer::{MultiBufferChunks, MultiBufferRows},
MultiBufferSnapshot, ToPoint,
};
use collections::{BTreeSet, HashMap};
@@ -16,17 +13,19 @@ use std::{
};
use sum_tree::{Bias, Cursor, SumTree};
use text::Patch;
+use util::post_inc;
pub struct InlayMap {
- snapshot: Mutex<InlaySnapshot>,
+ buffer: Mutex<MultiBufferSnapshot>,
+ transforms: SumTree<Transform>,
inlays_by_id: HashMap<InlayId, Inlay>,
inlays: Vec<Inlay>,
+ version: usize,
}
#[derive(Clone)]
pub struct InlaySnapshot {
- // TODO kb merge these two together
- pub fold_snapshot: FoldSnapshot,
+ pub buffer: MultiBufferSnapshot,
transforms: SumTree<Transform>,
pub version: usize,
}
@@ -102,12 +101,6 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayOffset {
}
}
-impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldOffset {
- fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
- self.0 += &summary.input.len;
- }
-}
-
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
pub struct InlayPoint(pub Point);
@@ -117,23 +110,29 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayPoint {
}
}
-impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldPoint {
+impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize {
+ fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
+ *self += &summary.input.len;
+ }
+}
+
+impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point {
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
- self.0 += &summary.input.lines;
+ *self += &summary.input.lines;
}
}
#[derive(Clone)]
pub struct InlayBufferRows<'a> {
- transforms: Cursor<'a, Transform, (InlayPoint, FoldPoint)>,
- fold_rows: FoldBufferRows<'a>,
+ transforms: Cursor<'a, Transform, (InlayPoint, Point)>,
+ buffer_rows: MultiBufferRows<'a>,
inlay_row: u32,
}
pub struct InlayChunks<'a> {
- transforms: Cursor<'a, Transform, (InlayOffset, FoldOffset)>,
- fold_chunks: FoldChunks<'a>,
- fold_chunk: Option<Chunk<'a>>,
+ transforms: Cursor<'a, Transform, (InlayOffset, usize)>,
+ buffer_chunks: MultiBufferChunks<'a>,
+ buffer_chunk: Option<Chunk<'a>>,
inlay_chunks: Option<text::Chunks<'a>>,
output_offset: InlayOffset,
max_output_offset: InlayOffset,
@@ -151,10 +150,10 @@ impl<'a> Iterator for InlayChunks<'a> {
let chunk = match self.transforms.item()? {
Transform::Isomorphic(_) => {
let chunk = self
- .fold_chunk
- .get_or_insert_with(|| self.fold_chunks.next().unwrap());
+ .buffer_chunk
+ .get_or_insert_with(|| self.buffer_chunks.next().unwrap());
if chunk.text.is_empty() {
- *chunk = self.fold_chunks.next().unwrap();
+ *chunk = self.buffer_chunks.next().unwrap();
}
let (prefix, suffix) = chunk.text.split_at(cmp::min(
@@ -201,11 +200,11 @@ impl<'a> Iterator for InlayBufferRows<'a> {
fn next(&mut self) -> Option<Self::Item> {
let buffer_row = if self.inlay_row == 0 {
- self.fold_rows.next().unwrap()
+ self.buffer_rows.next().unwrap()
} else {
match self.transforms.item()? {
Transform::Inlay(_) => None,
- Transform::Isomorphic(_) => self.fold_rows.next().unwrap(),
+ Transform::Isomorphic(_) => self.buffer_rows.next().unwrap(),
}
};
@@ -232,21 +231,21 @@ impl InlayPoint {
}
impl InlayMap {
- pub fn new(fold_snapshot: FoldSnapshot) -> (Self, InlaySnapshot) {
+ pub fn new(buffer: MultiBufferSnapshot) -> (Self, InlaySnapshot) {
+ let version = 0;
let snapshot = InlaySnapshot {
- fold_snapshot: fold_snapshot.clone(),
- version: 0,
- transforms: SumTree::from_item(
- Transform::Isomorphic(fold_snapshot.text_summary()),
- &(),
- ),
+ buffer: buffer.clone(),
+ transforms: SumTree::from_item(Transform::Isomorphic(buffer.text_summary()), &()),
+ version,
};
(
Self {
- snapshot: Mutex::new(snapshot.clone()),
+ buffer: Mutex::new(buffer),
+ transforms: snapshot.transforms.clone(),
inlays_by_id: Default::default(),
inlays: Default::default(),
+ version,
},
snapshot,
)
@@ -254,144 +253,140 @@ impl InlayMap {
pub fn sync(
&mut self,
- fold_snapshot: FoldSnapshot,
- mut fold_edits: Vec<FoldEdit>,
+ buffer_snapshot: MultiBufferSnapshot,
+ buffer_edits: Vec<text::Edit<usize>>,
) -> (InlaySnapshot, Vec<InlayEdit>) {
- let mut snapshot = self.snapshot.lock();
+ let mut buffer = self.buffer.lock();
+ if buffer_edits.is_empty() {
+ let new_version = if buffer.edit_count() != buffer_snapshot.edit_count()
+ || buffer.parse_count() != buffer_snapshot.parse_count()
+ || buffer.diagnostics_update_count() != buffer_snapshot.diagnostics_update_count()
+ || buffer.git_diff_update_count() != buffer_snapshot.git_diff_update_count()
+ || buffer.trailing_excerpt_update_count()
+ != buffer_snapshot.trailing_excerpt_update_count()
+ {
+ post_inc(&mut self.version)
+ } else {
+ self.version
+ };
- let mut new_snapshot = snapshot.clone();
- if new_snapshot.fold_snapshot.version != fold_snapshot.version {
- new_snapshot.version += 1;
- }
+ *buffer = buffer_snapshot.clone();
+ (
+ InlaySnapshot {
+ buffer: buffer_snapshot,
+ transforms: SumTree::default(),
+ version: new_version,
+ },
+ Vec::new(),
+ )
+ } else {
+ let mut inlay_edits = Patch::default();
+ let mut new_transforms = SumTree::new();
+ // TODO kb something is wrong with how we store it?
+ let mut transforms = self.transforms;
+ let mut cursor = transforms.cursor::<(usize, InlayOffset)>();
+ let mut buffer_edits_iter = buffer_edits.iter().peekable();
+ while let Some(buffer_edit) = buffer_edits_iter.next() {
+ new_transforms
+ .push_tree(cursor.slice(&buffer_edit.old.start, Bias::Left, &()), &());
+ if let Some(Transform::Isomorphic(transform)) = cursor.item() {
+ if cursor.end(&()).0 == buffer_edit.old.start {
+ new_transforms.push(Transform::Isomorphic(transform.clone()), &());
+ cursor.next(&());
+ }
+ }
- if fold_snapshot
- .buffer_snapshot()
- .trailing_excerpt_update_count()
- != snapshot
- .fold_snapshot
- .buffer_snapshot()
- .trailing_excerpt_update_count()
- {
- if fold_edits.is_empty() {
- fold_edits.push(Edit {
- old: snapshot.fold_snapshot.len()..snapshot.fold_snapshot.len(),
- new: fold_snapshot.len()..fold_snapshot.len(),
- });
- }
- }
+ // Remove all the inlays and transforms contained by the edit.
+ let old_start =
+ cursor.start().1 + InlayOffset(buffer_edit.old.start - cursor.start().0);
+ cursor.seek(&buffer_edit.old.end, Bias::Right, &());
+ let old_end =
+ cursor.start().1 + InlayOffset(buffer_edit.old.end - cursor.start().0);
- let mut inlay_edits = Patch::default();
- let mut new_transforms = SumTree::new();
- let mut cursor = snapshot.transforms.cursor::<(FoldOffset, InlayOffset)>();
- let mut fold_edits_iter = fold_edits.iter().peekable();
- while let Some(fold_edit) = fold_edits_iter.next() {
- new_transforms.push_tree(cursor.slice(&fold_edit.old.start, Bias::Left, &()), &());
- if let Some(Transform::Isomorphic(transform)) = cursor.item() {
- if cursor.end(&()).0 == fold_edit.old.start {
- new_transforms.push(Transform::Isomorphic(transform.clone()), &());
- cursor.next(&());
- }
- }
+ // Push the unchanged prefix.
+ let prefix_start = new_transforms.summary().input.len;
+ let prefix_end = buffer_edit.new.start;
+ push_isomorphic(
+ &mut new_transforms,
+ buffer_snapshot.text_summary_for_range(prefix_start..prefix_end),
+ );
+ let new_start = InlayOffset(new_transforms.summary().output.len);
+
+ let start_point = buffer_edit.new.start.to_point(&buffer_snapshot);
+ let start_ix = match self.inlays.binary_search_by(|probe| {
+ probe
+ .position
+ .to_point(&buffer_snapshot)
+ .cmp(&start_point)
+ .then(std::cmp::Ordering::Greater)
+ }) {
+ Ok(ix) | Err(ix) => ix,
+ };
+
+ for inlay in &self.inlays[start_ix..] {
+ let buffer_point = inlay.position.to_point(&buffer_snapshot);
+ let buffer_offset = buffer_snapshot.point_to_offset(buffer_point);
+ if buffer_offset > buffer_edit.new.end {
+ break;
+ }
- // Remove all the inlays and transforms contained by the edit.
- let old_start =
- cursor.start().1 + InlayOffset(fold_edit.old.start.0 - cursor.start().0 .0);
- cursor.seek(&fold_edit.old.end, Bias::Right, &());
- let old_end = cursor.start().1 + InlayOffset(fold_edit.old.end.0 - cursor.start().0 .0);
-
- // Push the unchanged prefix.
- let prefix_start = FoldOffset(new_transforms.summary().input.len);
- let prefix_end = fold_edit.new.start;
- push_isomorphic(
- &mut new_transforms,
- fold_snapshot.text_summary_for_range(
- prefix_start.to_point(&fold_snapshot)..prefix_end.to_point(&fold_snapshot),
- ),
- );
- let new_start = InlayOffset(new_transforms.summary().output.len);
-
- let start_point = fold_edit
- .new
- .start
- .to_point(&fold_snapshot)
- .to_buffer_point(&fold_snapshot);
- let start_ix = match self.inlays.binary_search_by(|probe| {
- probe
- .position
- .to_point(&fold_snapshot.buffer_snapshot())
- .cmp(&start_point)
- .then(std::cmp::Ordering::Greater)
- }) {
- Ok(ix) | Err(ix) => ix,
- };
+ let prefix_start = new_transforms.summary().input.len;
+ let prefix_end = buffer_offset;
+ push_isomorphic(
+ &mut new_transforms,
+ buffer_snapshot.text_summary_for_range(prefix_start..prefix_end),
+ );
- for inlay in &self.inlays[start_ix..] {
- let buffer_point = inlay.position.to_point(fold_snapshot.buffer_snapshot());
- let fold_point = fold_snapshot.to_fold_point(buffer_point, Bias::Left);
- let fold_offset = fold_point.to_offset(&fold_snapshot);
- if fold_offset > fold_edit.new.end {
- break;
+ if inlay.position.is_valid(&buffer_snapshot) {
+ new_transforms.push(Transform::Inlay(inlay.clone()), &());
+ }
}
- let prefix_start = FoldOffset(new_transforms.summary().input.len);
- let prefix_end = fold_offset;
+ // Apply the rest of the edit.
+ let transform_start = new_transforms.summary().input.len;
push_isomorphic(
&mut new_transforms,
- fold_snapshot.text_summary_for_range(
- prefix_start.to_point(&fold_snapshot)..prefix_end.to_point(&fold_snapshot),
- ),
+ buffer_snapshot.text_summary_for_range(transform_start..buffer_edit.new.end),
);
+ let new_end = InlayOffset(new_transforms.summary().output.len);
+ inlay_edits.push(Edit {
+ old: old_start..old_end,
+ new: new_start..new_end,
+ });
- if inlay.position.is_valid(fold_snapshot.buffer_snapshot()) {
- new_transforms.push(Transform::Inlay(inlay.clone()), &());
+ // If the next edit doesn't intersect the current isomorphic transform, then
+ // we can push its remainder.
+ if buffer_edits_iter
+ .peek()
+ .map_or(true, |edit| edit.old.start >= cursor.end(&()).0)
+ {
+ let transform_start = new_transforms.summary().input.len;
+ let transform_end =
+ buffer_edit.new.end + (cursor.end(&()).0 - buffer_edit.old.end);
+ push_isomorphic(
+ &mut new_transforms,
+ buffer_snapshot.text_summary_for_range(transform_start..transform_end),
+ );
+ cursor.next(&());
}
}
- // Apply the rest of the edit.
- let transform_start = FoldOffset(new_transforms.summary().input.len);
- push_isomorphic(
- &mut new_transforms,
- fold_snapshot.text_summary_for_range(
- transform_start.to_point(&fold_snapshot)
- ..fold_edit.new.end.to_point(&fold_snapshot),
- ),
- );
- let new_end = InlayOffset(new_transforms.summary().output.len);
- inlay_edits.push(Edit {
- old: old_start..old_end,
- new: new_start..new_end,
- });
-
- // If the next edit doesn't intersect the current isomorphic transform, then
- // we can push its remainder.
- if fold_edits_iter
- .peek()
- .map_or(true, |edit| edit.old.start >= cursor.end(&()).0)
- {
- let transform_start = FoldOffset(new_transforms.summary().input.len);
- let transform_end = fold_edit.new.end + (cursor.end(&()).0 - fold_edit.old.end);
- push_isomorphic(
- &mut new_transforms,
- fold_snapshot.text_summary_for_range(
- transform_start.to_point(&fold_snapshot)
- ..transform_end.to_point(&fold_snapshot),
- ),
- );
- cursor.next(&());
+ new_transforms.push_tree(cursor.suffix(&()), &());
+ if new_transforms.first().is_none() {
+ new_transforms.push(Transform::Isomorphic(Default::default()), &());
}
- }
- new_transforms.push_tree(cursor.suffix(&()), &());
- if new_transforms.first().is_none() {
- new_transforms.push(Transform::Isomorphic(Default::default()), &());
- }
- new_snapshot.transforms = new_transforms;
- new_snapshot.fold_snapshot = fold_snapshot;
- new_snapshot.check_invariants();
- drop(cursor);
+ let new_snapshot = InlaySnapshot {
+ buffer: buffer_snapshot,
+ transforms: new_transforms,
+ version: post_inc(&mut self.version),
+ };
+ new_snapshot.check_invariants();
+ drop(cursor);
- *snapshot = new_snapshot.clone();
- (new_snapshot, inlay_edits.into_inner())
+ *buffer = buffer_snapshot.clone();
+ (new_snapshot, inlay_edits.into_inner())
+ }
}
pub fn splice<T: Into<Rope>>(
@@ -399,20 +394,15 @@ impl InlayMap {
to_remove: Vec<InlayId>,
to_insert: Vec<(InlayId, InlayProperties<T>)>,
) -> (InlaySnapshot, Vec<InlayEdit>) {
- let mut snapshot = self.snapshot.lock();
- snapshot.version += 1;
-
+ let mut buffer_snapshot = self.buffer.lock();
let mut edits = BTreeSet::new();
self.inlays.retain(|inlay| !to_remove.contains(&inlay.id));
for inlay_id in to_remove {
if let Some(inlay) = self.inlays_by_id.remove(&inlay_id) {
- let buffer_point = inlay.position.to_point(snapshot.buffer_snapshot());
- let fold_point = snapshot
- .fold_snapshot
- .to_fold_point(buffer_point, Bias::Left);
- let fold_offset = fold_point.to_offset(&snapshot.fold_snapshot);
- edits.insert(fold_offset);
+ let buffer_point = inlay.position.to_point(&buffer_snapshot);
+ let buffer_offset = buffer_snapshot.point_to_offset(buffer_point);
+ edits.insert(buffer_offset);
}
}
@@ -423,34 +413,28 @@ impl InlayMap {
text: properties.text.into(),
};
self.inlays_by_id.insert(inlay.id, inlay.clone());
- match self.inlays.binary_search_by(|probe| {
- probe
- .position
- .cmp(&inlay.position, snapshot.buffer_snapshot())
- }) {
+ match self
+ .inlays
+ .binary_search_by(|probe| probe.position.cmp(&inlay.position, &buffer_snapshot))
+ {
Ok(ix) | Err(ix) => {
self.inlays.insert(ix, inlay.clone());
}
}
- let buffer_point = inlay.position.to_point(snapshot.buffer_snapshot());
- let fold_point = snapshot
- .fold_snapshot
- .to_fold_point(buffer_point, Bias::Left);
- let fold_offset = fold_point.to_offset(&snapshot.fold_snapshot);
- edits.insert(fold_offset);
+ let buffer_point = inlay.position.to_point(&buffer_snapshot);
+ let buffer_offset = buffer_snapshot.point_to_offset(buffer_point);
+ edits.insert(buffer_offset);
}
- let fold_snapshot = snapshot.fold_snapshot.clone();
- let fold_edits = edits
+ let buffer_edits = edits
.into_iter()
.map(|offset| Edit {
old: offset..offset,
new: offset..offset,
})
.collect();
- drop(snapshot);
- self.sync(fold_snapshot, fold_edits)
+ self.sync(buffer_snapshot.clone(), buffer_edits)
}
#[cfg(any(test, feature = "test-support"))]
@@ -460,14 +444,12 @@ impl InlayMap {
rng: &mut rand::rngs::StdRng,
) -> (InlaySnapshot, Vec<InlayEdit>) {
use rand::prelude::*;
- use util::post_inc;
let mut to_remove = Vec::new();
let mut to_insert = Vec::new();
- let snapshot = self.snapshot.lock();
+ let buffer_snapshot = self.buffer.lock();
for _ in 0..rng.gen_range(1..=5) {
if self.inlays.is_empty() || rng.gen() {
- let buffer_snapshot = snapshot.buffer_snapshot();
let position = buffer_snapshot.random_byte_range(0, rng).start;
let bias = if rng.gen() { Bias::Left } else { Bias::Right };
let len = rng.gen_range(1..=5);
@@ -494,29 +476,25 @@ impl InlayMap {
}
log::info!("removing inlays: {:?}", to_remove);
- drop(snapshot);
+ drop(buffer_snapshot);
self.splice(to_remove, to_insert)
}
}
impl InlaySnapshot {
- pub fn buffer_snapshot(&self) -> &MultiBufferSnapshot {
- self.fold_snapshot.buffer_snapshot()
- }
-
pub fn to_point(&self, offset: InlayOffset) -> InlayPoint {
let mut cursor = self
.transforms
- .cursor::<(InlayOffset, (InlayPoint, FoldOffset))>();
+ .cursor::<(InlayOffset, (InlayPoint, usize))>();
cursor.seek(&offset, Bias::Right, &());
let overshoot = offset.0 - cursor.start().0 .0;
match cursor.item() {
Some(Transform::Isomorphic(_)) => {
- let fold_offset_start = cursor.start().1 .1;
- let fold_offset_end = FoldOffset(fold_offset_start.0 + overshoot);
- let fold_start = fold_offset_start.to_point(&self.fold_snapshot);
- let fold_end = fold_offset_end.to_point(&self.fold_snapshot);
- InlayPoint(cursor.start().1 .0 .0 + (fold_end.0 - fold_start.0))
+ let buffer_offset_start = cursor.start().1 .1;
+ let buffer_offset_end = buffer_offset_start + overshoot;
+ let buffer_start = self.buffer.offset_to_point(buffer_offset_start);
+ let buffer_end = self.buffer.offset_to_point(buffer_offset_end);
+ InlayPoint(cursor.start().1 .0 .0 + (buffer_end - buffer_start))
}
Some(Transform::Inlay(inlay)) => {
let overshoot = inlay.text.offset_to_point(overshoot);
@@ -537,16 +515,16 @@ impl InlaySnapshot {
pub fn to_offset(&self, point: InlayPoint) -> InlayOffset {
let mut cursor = self
.transforms
- .cursor::<(InlayPoint, (InlayOffset, FoldPoint))>();
+ .cursor::<(InlayPoint, (InlayOffset, Point))>();
cursor.seek(&point, Bias::Right, &());
let overshoot = point.0 - cursor.start().0 .0;
match cursor.item() {
Some(Transform::Isomorphic(_)) => {
- let fold_point_start = cursor.start().1 .1;
- let fold_point_end = FoldPoint(fold_point_start.0 + overshoot);
- let fold_start = fold_point_start.to_offset(&self.fold_snapshot);
- let fold_end = fold_point_end.to_offset(&self.fold_snapshot);
- InlayOffset(cursor.start().1 .0 .0 + (fold_end.0 - fold_start.0))
+ let buffer_point_start = cursor.start().1 .1;
+ let buffer_point_end = buffer_point_start + overshoot;
+ let buffer_offset_start = self.buffer.point_to_offset(buffer_point_start);
+ let buffer_offset_end = self.buffer.point_to_offset(buffer_point_end);
+ InlayOffset(cursor.start().1 .0 .0 + (buffer_offset_end - buffer_offset_start))
}
Some(Transform::Inlay(inlay)) => {
let overshoot = inlay.text.point_to_offset(overshoot);
@@ -557,42 +535,55 @@ impl InlaySnapshot {
}
pub fn chars_at(&self, start: InlayPoint) -> impl '_ + Iterator<Item = char> {
- self.chunks(self.to_offset(start)..self.len(), false, None, None)
+ self.chunks(self.to_offset(start)..self.len(), false, None)
.flat_map(|chunk| chunk.text.chars())
}
- pub fn to_fold_point(&self, point: InlayPoint) -> FoldPoint {
- let mut cursor = self.transforms.cursor::<(InlayPoint, FoldPoint)>();
+ pub fn to_buffer_point(&self, point: InlayPoint) -> Point {
+ let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>();
cursor.seek(&point, Bias::Right, &());
match cursor.item() {
Some(Transform::Isomorphic(_)) => {
let overshoot = point.0 - cursor.start().0 .0;
- FoldPoint(cursor.start().1 .0 + overshoot)
+ cursor.start().1 + overshoot
}
Some(Transform::Inlay(_)) => cursor.start().1,
- None => self.fold_snapshot.max_point(),
+ None => self.buffer.max_point(),
}
}
- pub fn to_fold_offset(&self, offset: InlayOffset) -> FoldOffset {
- let mut cursor = self.transforms.cursor::<(InlayOffset, FoldOffset)>();
+ pub fn to_buffer_offset(&self, offset: InlayOffset) -> usize {
+ let mut cursor = self.transforms.cursor::<(InlayOffset, usize)>();
cursor.seek(&offset, Bias::Right, &());
match cursor.item() {
Some(Transform::Isomorphic(_)) => {
let overshoot = offset - cursor.start().0;
- cursor.start().1 + FoldOffset(overshoot.0)
+ cursor.start().1 + overshoot.0
+ }
+ Some(Transform::Inlay(_)) => cursor.start().1,
+ None => self.buffer.len(),
+ }
+ }
+
+ pub fn to_inlay_offset(&self, offset: usize) -> InlayOffset {
+ let mut cursor = self.transforms.cursor::<(Point, InlayOffset)>();
+ cursor.seek(&offset, Bias::Left, &());
+ match cursor.item() {
+ Some(Transform::Isomorphic(_)) => {
+ let overshoot = offset - cursor.start().0;
+ InlayOffset(cursor.start().1 .0 + overshoot)
}
Some(Transform::Inlay(_)) => cursor.start().1,
- None => self.fold_snapshot.len(),
+ None => self.len(),
}
}
- pub fn to_inlay_point(&self, point: FoldPoint) -> InlayPoint {
- let mut cursor = self.transforms.cursor::<(FoldPoint, InlayPoint)>();
+ pub fn to_inlay_point(&self, point: Point) -> InlayPoint {
+ let mut cursor = self.transforms.cursor::<(Point, InlayPoint)>();
cursor.seek(&point, Bias::Left, &());
match cursor.item() {
Some(Transform::Isomorphic(_)) => {
- let overshoot = point.0 - cursor.start().0 .0;
+ let overshoot = point - cursor.start().0;
InlayPoint(cursor.start().1 .0 + overshoot)
}
Some(Transform::Inlay(_)) => cursor.start().1,
@@ -601,7 +592,7 @@ impl InlaySnapshot {
}
pub fn clip_point(&self, point: InlayPoint, bias: Bias) -> InlayPoint {
- let mut cursor = self.transforms.cursor::<(InlayPoint, FoldPoint)>();
+ let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>();
cursor.seek(&point, Bias::Left, &());
let mut bias = bias;
@@ -623,9 +614,9 @@ impl InlaySnapshot {
} else {
point.0 - cursor.start().0 .0
};
- let fold_point = FoldPoint(cursor.start().1 .0 + overshoot);
- let clipped_fold_point = self.fold_snapshot.clip_point(fold_point, bias);
- let clipped_overshoot = clipped_fold_point.0 - cursor.start().1 .0;
+ let buffer_point = cursor.start().1 + overshoot;
+ let clipped_buffer_point = self.buffer.clip_point(buffer_point, bias);
+ let clipped_overshoot = clipped_buffer_point - cursor.start().1;
return InlayPoint(cursor.start().0 .0 + clipped_overshoot);
}
Some(Transform::Inlay(_)) => skipped_inlay = true,
@@ -643,23 +634,24 @@ impl InlaySnapshot {
}
}
+ pub fn text_summary(&self) -> TextSummary {
+ self.transforms.summary().output
+ }
+
pub fn text_summary_for_range(&self, range: Range<InlayPoint>) -> TextSummary {
let mut summary = TextSummary::default();
- let mut cursor = self.transforms.cursor::<(InlayPoint, FoldPoint)>();
+ let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>();
cursor.seek(&range.start, Bias::Right, &());
let overshoot = range.start.0 - cursor.start().0 .0;
match cursor.item() {
Some(Transform::Isomorphic(_)) => {
- let fold_start = cursor.start().1 .0;
- let suffix_start = FoldPoint(fold_start + overshoot);
- let suffix_end = FoldPoint(
- fold_start + (cmp::min(cursor.end(&()).0, range.end).0 - cursor.start().0 .0),
- );
- summary = self
- .fold_snapshot
- .text_summary_for_range(suffix_start..suffix_end);
+ let buffer_start = cursor.start().1;
+ let suffix_start = buffer_start + overshoot;
+ let suffix_end =
+ buffer_start + (cmp::min(cursor.end(&()).0, range.end).0 - cursor.start().0 .0);
+ summary = self.buffer.text_summary_for_range(suffix_start..suffix_end);
cursor.next(&());
}
Some(Transform::Inlay(inlay)) => {
@@ -682,10 +674,10 @@ impl InlaySnapshot {
match cursor.item() {
Some(Transform::Isomorphic(_)) => {
let prefix_start = cursor.start().1;
- let prefix_end = FoldPoint(prefix_start.0 + overshoot);
+ let prefix_end = prefix_start + overshoot;
summary += self
- .fold_snapshot
- .text_summary_for_range(prefix_start..prefix_end);
+ .buffer
+ .text_summary_for_range::<TextSummary, Point>(prefix_start..prefix_end);
}
Some(Transform::Inlay(inlay)) => {
let prefix_end = inlay.text.point_to_offset(overshoot);
@@ -699,27 +691,27 @@ impl InlaySnapshot {
}
pub fn buffer_rows<'a>(&'a self, row: u32) -> InlayBufferRows<'a> {
- let mut cursor = self.transforms.cursor::<(InlayPoint, FoldPoint)>();
+ let mut cursor = self.transforms.cursor::<(InlayPoint, Point)>();
let inlay_point = InlayPoint::new(row, 0);
cursor.seek(&inlay_point, Bias::Left, &());
- let mut fold_point = cursor.start().1;
- let fold_row = if row == 0 {
+ let mut buffer_point = cursor.start().1;
+ let buffer_row = if row == 0 {
0
} else {
match cursor.item() {
Some(Transform::Isomorphic(_)) => {
- fold_point.0 += inlay_point.0 - cursor.start().0 .0;
- fold_point.row()
+ buffer_point += inlay_point.0 - cursor.start().0 .0;
+ buffer_point.row
}
- _ => cmp::min(fold_point.row() + 1, self.fold_snapshot.max_point().row()),
+ _ => cmp::min(buffer_point.row + 1, self.buffer.max_point().row),
}
};
InlayBufferRows {
transforms: cursor,
inlay_row: inlay_point.row(),
- fold_rows: self.fold_snapshot.buffer_rows(fold_row),
+ buffer_rows: self.buffer.buffer_rows(buffer_row),
}
}
@@ -737,22 +729,19 @@ impl InlaySnapshot {
&'a self,
range: Range<InlayOffset>,
language_aware: bool,
- text_highlights: Option<&'a TextHighlights>,
inlay_highlight_style: Option<HighlightStyle>,
) -> InlayChunks<'a> {
- let mut cursor = self.transforms.cursor::<(InlayOffset, FoldOffset)>();
+ let mut cursor = self.transforms.cursor::<(InlayOffset, usize)>();
cursor.seek(&range.start, Bias::Right, &());
- let fold_range = self.to_fold_offset(range.start)..self.to_fold_offset(range.end);
- let fold_chunks = self
- .fold_snapshot
- .chunks(fold_range, language_aware, text_highlights);
+ let buffer_range = self.to_buffer_offset(range.start)..self.to_buffer_offset(range.end);
+ let buffer_chunks = self.buffer.chunks(buffer_range, language_aware);
InlayChunks {
transforms: cursor,
- fold_chunks,
+ buffer_chunks,
inlay_chunks: None,
- fold_chunk: None,
+ buffer_chunk: None,
output_offset: range.start,
max_output_offset: range.end,
highlight_style: inlay_highlight_style,
@@ -761,7 +750,7 @@ impl InlaySnapshot {
#[cfg(test)]
pub fn text(&self) -> String {
- self.chunks(Default::default()..self.len(), false, None, None)
+ self.chunks(Default::default()..self.len(), false, None)
.map(|chunk| chunk.text)
.collect()
}
@@ -769,10 +758,7 @@ impl InlaySnapshot {
fn check_invariants(&self) {
#[cfg(any(debug_assertions, feature = "test-support"))]
{
- assert_eq!(
- self.transforms.summary().input,
- self.fold_snapshot.text_summary()
- );
+ assert_eq!(self.transforms.summary().input, self.buffer.text_summary());
}
}
}
@@ -800,7 +786,7 @@ fn push_isomorphic(sum_tree: &mut SumTree<Transform>, summary: TextSummary) {
#[cfg(test)]
mod tests {
use super::*;
- use crate::{display_map::fold_map::FoldMap, MultiBuffer};
+ use crate::MultiBuffer;
use gpui::AppContext;
use rand::prelude::*;
use settings::SettingsStore;
@@ -812,8 +798,7 @@ mod tests {
fn test_basic_inlays(cx: &mut AppContext) {
let buffer = MultiBuffer::build_simple("abcdefghi", cx);
let buffer_edits = buffer.update(cx, |buffer, _| buffer.subscribe());
- let (fold_map, fold_snapshot) = FoldMap::new(buffer.read(cx).snapshot(cx));
- let (mut inlay_map, inlay_snapshot) = InlayMap::new(fold_snapshot.clone());
+ let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer.read(cx).snapshot(cx));
assert_eq!(inlay_snapshot.text(), "abcdefghi");
let mut next_inlay_id = 0;
@@ -829,27 +814,27 @@ mod tests {
);
assert_eq!(inlay_snapshot.text(), "abc|123|defghi");
assert_eq!(
- inlay_snapshot.to_inlay_point(FoldPoint::new(0, 0)),
+ inlay_snapshot.to_inlay_point(Point::new(0, 0)),
InlayPoint::new(0, 0)
);
assert_eq!(
- inlay_snapshot.to_inlay_point(FoldPoint::new(0, 1)),
+ inlay_snapshot.to_inlay_point(Point::new(0, 1)),
InlayPoint::new(0, 1)
);
assert_eq!(
- inlay_snapshot.to_inlay_point(FoldPoint::new(0, 2)),
+ inlay_snapshot.to_inlay_point(Point::new(0, 2)),
InlayPoint::new(0, 2)
);
assert_eq!(
- inlay_snapshot.to_inlay_point(FoldPoint::new(0, 3)),
+ inlay_snapshot.to_inlay_point(Point::new(0, 3)),
InlayPoint::new(0, 3)
);
assert_eq!(
- inlay_snapshot.to_inlay_point(FoldPoint::new(0, 4)),
+ inlay_snapshot.to_inlay_point(Point::new(0, 4)),
InlayPoint::new(0, 9)
);
assert_eq!(
- inlay_snapshot.to_inlay_point(FoldPoint::new(0, 5)),
+ inlay_snapshot.to_inlay_point(Point::new(0, 5)),
InlayPoint::new(0, 10)
);
assert_eq!(
@@ -881,20 +866,18 @@ mod tests {
buffer.update(cx, |buffer, cx| {
buffer.edit([(2..3, "x"), (3..3, "y"), (4..4, "z")], None, cx)
});
- let (fold_snapshot, fold_edits) = fold_map.read(
+ let (inlay_snapshot, _) = inlay_map.sync(
buffer.read(cx).snapshot(cx),
buffer_edits.consume().into_inner(),
);
- let (inlay_snapshot, _) = inlay_map.sync(fold_snapshot.clone(), fold_edits);
assert_eq!(inlay_snapshot.text(), "abxy|123|dzefghi");
// An edit surrounding the inlay should invalidate it.
buffer.update(cx, |buffer, cx| buffer.edit([(4..5, "D")], None, cx));
- let (fold_snapshot, fold_edits) = fold_map.read(
+ let (inlay_snapshot, _) = inlay_map.sync(
buffer.read(cx).snapshot(cx),
buffer_edits.consume().into_inner(),
);
- let (inlay_snapshot, _) = inlay_map.sync(fold_snapshot.clone(), fold_edits);
assert_eq!(inlay_snapshot.text(), "abxyDzefghi");
let (inlay_snapshot, _) = inlay_map.splice(
@@ -920,11 +903,10 @@ mod tests {
// Edits ending where the inlay starts should not move it if it has a left bias.
buffer.update(cx, |buffer, cx| buffer.edit([(3..3, "JKL")], None, cx));
- let (fold_snapshot, fold_edits) = fold_map.read(
+ let (inlay_snapshot, _) = inlay_map.sync(
buffer.read(cx).snapshot(cx),
buffer_edits.consume().into_inner(),
);
- let (inlay_snapshot, _) = inlay_map.sync(fold_snapshot.clone(), fold_edits);
assert_eq!(inlay_snapshot.text(), "abx|123|JKL|456|yDzefghi");
// The inlays can be manually removed.
@@ -936,8 +918,7 @@ mod tests {
#[gpui::test]
fn test_buffer_rows(cx: &mut AppContext) {
let buffer = MultiBuffer::build_simple("abc\ndef\nghi", cx);
- let (_, fold_snapshot) = FoldMap::new(buffer.read(cx).snapshot(cx));
- let (mut inlay_map, inlay_snapshot) = InlayMap::new(fold_snapshot.clone());
+ let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer.read(cx).snapshot(cx));
assert_eq!(inlay_snapshot.text(), "abc\ndef\nghi");
let (inlay_snapshot, _) = inlay_map.splice(
@@ -993,27 +974,20 @@ mod tests {
let mut buffer_snapshot = buffer.read(cx).snapshot(cx);
log::info!("buffer text: {:?}", buffer_snapshot.text());
- let (mut fold_map, mut fold_snapshot) = FoldMap::new(buffer_snapshot.clone());
- let (mut inlay_map, mut inlay_snapshot) = InlayMap::new(fold_snapshot.clone());
+ let (mut inlay_map, mut inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
let mut next_inlay_id = 0;
for _ in 0..operations {
- let mut fold_edits = Patch::default();
let mut inlay_edits = Patch::default();
let mut prev_inlay_text = inlay_snapshot.text();
let mut buffer_edits = Vec::new();
match rng.gen_range(0..=100) {
- 0..=29 => {
+ 0..=50 => {
let (snapshot, edits) = inlay_map.randomly_mutate(&mut next_inlay_id, &mut rng);
log::info!("mutated text: {:?}", snapshot.text());
inlay_edits = Patch::new(edits);
}
- 30..=59 => {
- for (_, edits) in fold_map.randomly_mutate(&mut rng) {
- fold_edits = fold_edits.compose(edits);
- }
- }
_ => buffer.update(cx, |buffer, cx| {
let subscription = buffer.subscribe();
let edit_count = rng.gen_range(1..=5);
@@ -1025,17 +999,12 @@ mod tests {
}),
};
- let (new_fold_snapshot, new_fold_edits) =
- fold_map.read(buffer_snapshot.clone(), buffer_edits);
- fold_snapshot = new_fold_snapshot;
- fold_edits = fold_edits.compose(new_fold_edits);
let (new_inlay_snapshot, new_inlay_edits) =
- inlay_map.sync(fold_snapshot.clone(), fold_edits.into_inner());
+ inlay_map.sync(buffer_snapshot.clone(), buffer_edits);
inlay_snapshot = new_inlay_snapshot;
inlay_edits = inlay_edits.compose(new_inlay_edits);
log::info!("buffer text: {:?}", buffer_snapshot.text());
- log::info!("folds text: {:?}", fold_snapshot.text());
log::info!("inlay text: {:?}", inlay_snapshot.text());
let inlays = inlay_map
@@ -1044,14 +1013,13 @@ mod tests {
.filter(|inlay| inlay.position.is_valid(&buffer_snapshot))
.map(|inlay| {
let buffer_point = inlay.position.to_point(&buffer_snapshot);
- let fold_point = fold_snapshot.to_fold_point(buffer_point, Bias::Left);
- let fold_offset = fold_point.to_offset(&fold_snapshot);
- (fold_offset, inlay.clone())
+ let buffer_offset = buffer_snapshot.point_to_offset(buffer_point);
+ (buffer_offset, inlay.clone())
})
.collect::<Vec<_>>();
- let mut expected_text = Rope::from(fold_snapshot.text().as_str());
+ let mut expected_text = Rope::from(buffer_snapshot.text().as_str());
for (offset, inlay) in inlays.into_iter().rev() {
- expected_text.replace(offset.0..offset.0, &inlay.text.to_string());
+ expected_text.replace(offset..offset, &inlay.text.to_string());
}
assert_eq!(inlay_snapshot.text(), expected_text.to_string());
@@ -1078,7 +1046,7 @@ mod tests {
start = expected_text.clip_offset(start, Bias::Right);
let actual_text = inlay_snapshot
- .chunks(InlayOffset(start)..InlayOffset(end), false, None, None)
+ .chunks(InlayOffset(start)..InlayOffset(end), false, None)
.map(|chunk| chunk.text)
.collect::<String>();
assert_eq!(
@@ -1123,11 +1091,11 @@ mod tests {
inlay_offset
);
assert_eq!(
- inlay_snapshot.to_inlay_point(inlay_snapshot.to_fold_point(inlay_point)),
+ inlay_snapshot.to_inlay_point(inlay_snapshot.to_buffer_point(inlay_point)),
inlay_snapshot.clip_point(inlay_point, Bias::Left),
- "to_fold_point({:?}) = {:?}",
+ "to_buffer_point({:?}) = {:?}",
inlay_point,
- inlay_snapshot.to_fold_point(inlay_point),
+ inlay_snapshot.to_buffer_point(inlay_point),
);
let mut bytes = [0; 4];
@@ -1,875 +0,0 @@
-use super::{
- fold_map::{FoldBufferRows, FoldChunks, FoldEdit, FoldOffset, FoldPoint, FoldSnapshot},
- TextHighlights,
-};
-use crate::{MultiBufferSnapshot, ToPoint};
-use gpui::fonts::HighlightStyle;
-use language::{Bias, Chunk, Edit, Patch, Point, Rope, TextSummary};
-use parking_lot::Mutex;
-use std::{
- cmp,
- ops::{Add, AddAssign, Range, Sub},
-};
-use util::post_inc;
-
-pub type SuggestionEdit = Edit<SuggestionOffset>;
-
-#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
-pub struct SuggestionOffset(pub usize);
-
-impl Add for SuggestionOffset {
- type Output = Self;
-
- fn add(self, rhs: Self) -> Self::Output {
- Self(self.0 + rhs.0)
- }
-}
-
-impl Sub for SuggestionOffset {
- type Output = Self;
-
- fn sub(self, rhs: Self) -> Self::Output {
- Self(self.0 - rhs.0)
- }
-}
-
-impl AddAssign for SuggestionOffset {
- fn add_assign(&mut self, rhs: Self) {
- self.0 += rhs.0;
- }
-}
-
-#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
-pub struct SuggestionPoint(pub Point);
-
-impl SuggestionPoint {
- pub fn new(row: u32, column: u32) -> Self {
- Self(Point::new(row, column))
- }
-
- pub fn row(self) -> u32 {
- self.0.row
- }
-
- pub fn column(self) -> u32 {
- self.0.column
- }
-}
-
-#[derive(Clone, Debug)]
-pub struct Suggestion<T> {
- pub position: T,
- pub text: Rope,
-}
-
-pub struct SuggestionMap(Mutex<SuggestionSnapshot>);
-
-impl SuggestionMap {
- pub fn new(fold_snapshot: FoldSnapshot) -> (Self, SuggestionSnapshot) {
- let snapshot = SuggestionSnapshot {
- fold_snapshot,
- suggestion: None,
- version: 0,
- };
- (Self(Mutex::new(snapshot.clone())), snapshot)
- }
-
- pub fn replace<T>(
- &self,
- new_suggestion: Option<Suggestion<T>>,
- fold_snapshot: FoldSnapshot,
- fold_edits: Vec<FoldEdit>,
- ) -> (
- SuggestionSnapshot,
- Vec<SuggestionEdit>,
- Option<Suggestion<FoldOffset>>,
- )
- where
- T: ToPoint,
- {
- let new_suggestion = new_suggestion.map(|new_suggestion| {
- let buffer_point = new_suggestion
- .position
- .to_point(fold_snapshot.buffer_snapshot());
- let fold_point = fold_snapshot.to_fold_point(buffer_point, Bias::Left);
- let fold_offset = fold_point.to_offset(&fold_snapshot);
- Suggestion {
- position: fold_offset,
- text: new_suggestion.text,
- }
- });
-
- let (_, edits) = self.sync(fold_snapshot, fold_edits);
- let mut snapshot = self.0.lock();
-
- let mut patch = Patch::new(edits);
- let old_suggestion = snapshot.suggestion.take();
- if let Some(suggestion) = &old_suggestion {
- patch = patch.compose([SuggestionEdit {
- old: SuggestionOffset(suggestion.position.0)
- ..SuggestionOffset(suggestion.position.0 + suggestion.text.len()),
- new: SuggestionOffset(suggestion.position.0)
- ..SuggestionOffset(suggestion.position.0),
- }]);
- }
-
- if let Some(suggestion) = new_suggestion.as_ref() {
- patch = patch.compose([SuggestionEdit {
- old: SuggestionOffset(suggestion.position.0)
- ..SuggestionOffset(suggestion.position.0),
- new: SuggestionOffset(suggestion.position.0)
- ..SuggestionOffset(suggestion.position.0 + suggestion.text.len()),
- }]);
- }
-
- snapshot.suggestion = new_suggestion;
- snapshot.version += 1;
- (snapshot.clone(), patch.into_inner(), old_suggestion)
- }
-
- pub fn sync(
- &self,
- fold_snapshot: FoldSnapshot,
- fold_edits: Vec<FoldEdit>,
- ) -> (SuggestionSnapshot, Vec<SuggestionEdit>) {
- let mut snapshot = self.0.lock();
-
- if snapshot.fold_snapshot.version != fold_snapshot.version {
- snapshot.version += 1;
- }
-
- let mut suggestion_edits = Vec::new();
-
- let mut suggestion_old_len = 0;
- let mut suggestion_new_len = 0;
- for fold_edit in fold_edits {
- let start = fold_edit.new.start;
- let end = FoldOffset(start.0 + fold_edit.old_len().0);
- if let Some(suggestion) = snapshot.suggestion.as_mut() {
- if end <= suggestion.position {
- suggestion.position.0 += fold_edit.new_len().0;
- suggestion.position.0 -= fold_edit.old_len().0;
- } else if start > suggestion.position {
- suggestion_old_len = suggestion.text.len();
- suggestion_new_len = suggestion_old_len;
- } else {
- suggestion_old_len = suggestion.text.len();
- snapshot.suggestion.take();
- suggestion_edits.push(SuggestionEdit {
- old: SuggestionOffset(fold_edit.old.start.0)
- ..SuggestionOffset(fold_edit.old.end.0 + suggestion_old_len),
- new: SuggestionOffset(fold_edit.new.start.0)
- ..SuggestionOffset(fold_edit.new.end.0),
- });
- continue;
- }
- }
-
- suggestion_edits.push(SuggestionEdit {
- old: SuggestionOffset(fold_edit.old.start.0 + suggestion_old_len)
- ..SuggestionOffset(fold_edit.old.end.0 + suggestion_old_len),
- new: SuggestionOffset(fold_edit.new.start.0 + suggestion_new_len)
- ..SuggestionOffset(fold_edit.new.end.0 + suggestion_new_len),
- });
- }
- snapshot.fold_snapshot = fold_snapshot;
-
- (snapshot.clone(), suggestion_edits)
- }
-
- pub fn has_suggestion(&self) -> bool {
- let snapshot = self.0.lock();
- snapshot.suggestion.is_some()
- }
-}
-
-#[derive(Clone)]
-pub struct SuggestionSnapshot {
- pub fold_snapshot: FoldSnapshot,
- pub suggestion: Option<Suggestion<FoldOffset>>,
- pub version: usize,
-}
-
-impl SuggestionSnapshot {
- pub fn buffer_snapshot(&self) -> &MultiBufferSnapshot {
- self.fold_snapshot.buffer_snapshot()
- }
-
- pub fn max_point(&self) -> SuggestionPoint {
- if let Some(suggestion) = self.suggestion.as_ref() {
- let suggestion_point = suggestion.position.to_point(&self.fold_snapshot);
- let mut max_point = suggestion_point.0;
- max_point += suggestion.text.max_point();
- max_point += self.fold_snapshot.max_point().0 - suggestion_point.0;
- SuggestionPoint(max_point)
- } else {
- SuggestionPoint(self.fold_snapshot.max_point().0)
- }
- }
-
- pub fn len(&self) -> SuggestionOffset {
- if let Some(suggestion) = self.suggestion.as_ref() {
- let mut len = suggestion.position.0;
- len += suggestion.text.len();
- len += self.fold_snapshot.len().0 - suggestion.position.0;
- SuggestionOffset(len)
- } else {
- SuggestionOffset(self.fold_snapshot.len().0)
- }
- }
-
- pub fn line_len(&self, row: u32) -> u32 {
- if let Some(suggestion) = &self.suggestion {
- let suggestion_start = suggestion.position.to_point(&self.fold_snapshot).0;
- let suggestion_end = suggestion_start + suggestion.text.max_point();
-
- if row < suggestion_start.row {
- self.fold_snapshot.line_len(row)
- } else if row > suggestion_end.row {
- self.fold_snapshot
- .line_len(suggestion_start.row + (row - suggestion_end.row))
- } else {
- let mut result = suggestion.text.line_len(row - suggestion_start.row);
- if row == suggestion_start.row {
- result += suggestion_start.column;
- }
- if row == suggestion_end.row {
- result +=
- self.fold_snapshot.line_len(suggestion_start.row) - suggestion_start.column;
- }
- result
- }
- } else {
- self.fold_snapshot.line_len(row)
- }
- }
-
- pub fn clip_point(&self, point: SuggestionPoint, bias: Bias) -> SuggestionPoint {
- if let Some(suggestion) = self.suggestion.as_ref() {
- let suggestion_start = suggestion.position.to_point(&self.fold_snapshot).0;
- let suggestion_end = suggestion_start + suggestion.text.max_point();
- if point.0 <= suggestion_start {
- SuggestionPoint(self.fold_snapshot.clip_point(FoldPoint(point.0), bias).0)
- } else if point.0 > suggestion_end {
- let fold_point = self.fold_snapshot.clip_point(
- FoldPoint(suggestion_start + (point.0 - suggestion_end)),
- bias,
- );
- let suggestion_point = suggestion_end + (fold_point.0 - suggestion_start);
- if bias == Bias::Left && suggestion_point == suggestion_end {
- SuggestionPoint(suggestion_start)
- } else {
- SuggestionPoint(suggestion_point)
- }
- } else if bias == Bias::Left || suggestion_start == self.fold_snapshot.max_point().0 {
- SuggestionPoint(suggestion_start)
- } else {
- let fold_point = if self.fold_snapshot.line_len(suggestion_start.row)
- > suggestion_start.column
- {
- FoldPoint(suggestion_start + Point::new(0, 1))
- } else {
- FoldPoint(suggestion_start + Point::new(1, 0))
- };
- let clipped_fold_point = self.fold_snapshot.clip_point(fold_point, bias);
- SuggestionPoint(suggestion_end + (clipped_fold_point.0 - suggestion_start))
- }
- } else {
- SuggestionPoint(self.fold_snapshot.clip_point(FoldPoint(point.0), bias).0)
- }
- }
-
- pub fn to_offset(&self, point: SuggestionPoint) -> SuggestionOffset {
- if let Some(suggestion) = self.suggestion.as_ref() {
- let suggestion_start = suggestion.position.to_point(&self.fold_snapshot).0;
- let suggestion_end = suggestion_start + suggestion.text.max_point();
-
- if point.0 <= suggestion_start {
- SuggestionOffset(FoldPoint(point.0).to_offset(&self.fold_snapshot).0)
- } else if point.0 > suggestion_end {
- let fold_offset = FoldPoint(suggestion_start + (point.0 - suggestion_end))
- .to_offset(&self.fold_snapshot);
- SuggestionOffset(fold_offset.0 + suggestion.text.len())
- } else {
- let offset_in_suggestion =
- suggestion.text.point_to_offset(point.0 - suggestion_start);
- SuggestionOffset(suggestion.position.0 + offset_in_suggestion)
- }
- } else {
- SuggestionOffset(FoldPoint(point.0).to_offset(&self.fold_snapshot).0)
- }
- }
-
- pub fn to_point(&self, offset: SuggestionOffset) -> SuggestionPoint {
- if let Some(suggestion) = self.suggestion.as_ref() {
- let suggestion_point_start = suggestion.position.to_point(&self.fold_snapshot).0;
- if offset.0 <= suggestion.position.0 {
- SuggestionPoint(FoldOffset(offset.0).to_point(&self.fold_snapshot).0)
- } else if offset.0 > (suggestion.position.0 + suggestion.text.len()) {
- let fold_point = FoldOffset(offset.0 - suggestion.text.len())
- .to_point(&self.fold_snapshot)
- .0;
-
- SuggestionPoint(
- suggestion_point_start
- + suggestion.text.max_point()
- + (fold_point - suggestion_point_start),
- )
- } else {
- let point_in_suggestion = suggestion
- .text
- .offset_to_point(offset.0 - suggestion.position.0);
- SuggestionPoint(suggestion_point_start + point_in_suggestion)
- }
- } else {
- SuggestionPoint(FoldOffset(offset.0).to_point(&self.fold_snapshot).0)
- }
- }
-
- pub fn to_fold_point(&self, point: SuggestionPoint) -> FoldPoint {
- if let Some(suggestion) = self.suggestion.as_ref() {
- let suggestion_start = suggestion.position.to_point(&self.fold_snapshot).0;
- let suggestion_end = suggestion_start + suggestion.text.max_point();
-
- if point.0 <= suggestion_start {
- FoldPoint(point.0)
- } else if point.0 > suggestion_end {
- FoldPoint(suggestion_start + (point.0 - suggestion_end))
- } else {
- FoldPoint(suggestion_start)
- }
- } else {
- FoldPoint(point.0)
- }
- }
-
- pub fn to_suggestion_point(&self, point: FoldPoint) -> SuggestionPoint {
- if let Some(suggestion) = self.suggestion.as_ref() {
- let suggestion_start = suggestion.position.to_point(&self.fold_snapshot).0;
-
- if point.0 <= suggestion_start {
- SuggestionPoint(point.0)
- } else {
- let suggestion_end = suggestion_start + suggestion.text.max_point();
- SuggestionPoint(suggestion_end + (point.0 - suggestion_start))
- }
- } else {
- SuggestionPoint(point.0)
- }
- }
-
- pub fn text_summary(&self) -> TextSummary {
- self.text_summary_for_range(Default::default()..self.max_point())
- }
-
- pub fn text_summary_for_range(&self, range: Range<SuggestionPoint>) -> TextSummary {
- if let Some(suggestion) = self.suggestion.as_ref() {
- let suggestion_start = suggestion.position.to_point(&self.fold_snapshot).0;
- let suggestion_end = suggestion_start + suggestion.text.max_point();
- let mut summary = TextSummary::default();
-
- let prefix_range =
- cmp::min(range.start.0, suggestion_start)..cmp::min(range.end.0, suggestion_start);
- if prefix_range.start < prefix_range.end {
- summary += self.fold_snapshot.text_summary_for_range(
- FoldPoint(prefix_range.start)..FoldPoint(prefix_range.end),
- );
- }
-
- let suggestion_range =
- cmp::max(range.start.0, suggestion_start)..cmp::min(range.end.0, suggestion_end);
- if suggestion_range.start < suggestion_range.end {
- let point_range = suggestion_range.start - suggestion_start
- ..suggestion_range.end - suggestion_start;
- let offset_range = suggestion.text.point_to_offset(point_range.start)
- ..suggestion.text.point_to_offset(point_range.end);
- summary += suggestion
- .text
- .cursor(offset_range.start)
- .summary::<TextSummary>(offset_range.end);
- }
-
- let suffix_range = cmp::max(range.start.0, suggestion_end)..range.end.0;
- if suffix_range.start < suffix_range.end {
- let start = suggestion_start + (suffix_range.start - suggestion_end);
- let end = suggestion_start + (suffix_range.end - suggestion_end);
- summary += self
- .fold_snapshot
- .text_summary_for_range(FoldPoint(start)..FoldPoint(end));
- }
-
- summary
- } else {
- self.fold_snapshot
- .text_summary_for_range(FoldPoint(range.start.0)..FoldPoint(range.end.0))
- }
- }
-
- pub fn chars_at(&self, start: SuggestionPoint) -> impl '_ + Iterator<Item = char> {
- let start = self.to_offset(start);
- self.chunks(start..self.len(), false, None, None)
- .flat_map(|chunk| chunk.text.chars())
- }
-
- pub fn chunks<'a>(
- &'a self,
- range: Range<SuggestionOffset>,
- language_aware: bool,
- text_highlights: Option<&'a TextHighlights>,
- suggestion_highlight: Option<HighlightStyle>,
- ) -> SuggestionChunks<'a> {
- if let Some(suggestion) = self.suggestion.as_ref() {
- let suggestion_range =
- suggestion.position.0..suggestion.position.0 + suggestion.text.len();
-
- let prefix_chunks = if range.start.0 < suggestion_range.start {
- Some(self.fold_snapshot.chunks(
- FoldOffset(range.start.0)
- ..cmp::min(FoldOffset(suggestion_range.start), FoldOffset(range.end.0)),
- language_aware,
- text_highlights,
- ))
- } else {
- None
- };
-
- let clipped_suggestion_range = cmp::max(range.start.0, suggestion_range.start)
- ..cmp::min(range.end.0, suggestion_range.end);
- let suggestion_chunks = if clipped_suggestion_range.start < clipped_suggestion_range.end
- {
- let start = clipped_suggestion_range.start - suggestion_range.start;
- let end = clipped_suggestion_range.end - suggestion_range.start;
- Some(suggestion.text.chunks_in_range(start..end))
- } else {
- None
- };
-
- let suffix_chunks = if range.end.0 > suggestion_range.end {
- let start = cmp::max(suggestion_range.end, range.start.0) - suggestion_range.len();
- let end = range.end.0 - suggestion_range.len();
- Some(self.fold_snapshot.chunks(
- FoldOffset(start)..FoldOffset(end),
- language_aware,
- text_highlights,
- ))
- } else {
- None
- };
-
- SuggestionChunks {
- prefix_chunks,
- suggestion_chunks,
- suffix_chunks,
- highlight_style: suggestion_highlight,
- }
- } else {
- SuggestionChunks {
- prefix_chunks: Some(self.fold_snapshot.chunks(
- FoldOffset(range.start.0)..FoldOffset(range.end.0),
- language_aware,
- text_highlights,
- )),
- suggestion_chunks: None,
- suffix_chunks: None,
- highlight_style: None,
- }
- }
- }
-
- pub fn buffer_rows<'a>(&'a self, row: u32) -> SuggestionBufferRows<'a> {
- let suggestion_range = if let Some(suggestion) = self.suggestion.as_ref() {
- let start = suggestion.position.to_point(&self.fold_snapshot).0;
- let end = start + suggestion.text.max_point();
- start.row..end.row
- } else {
- u32::MAX..u32::MAX
- };
-
- let fold_buffer_rows = if row <= suggestion_range.start {
- self.fold_snapshot.buffer_rows(row)
- } else if row > suggestion_range.end {
- self.fold_snapshot
- .buffer_rows(row - (suggestion_range.end - suggestion_range.start))
- } else {
- let mut rows = self.fold_snapshot.buffer_rows(suggestion_range.start);
- rows.next();
- rows
- };
-
- SuggestionBufferRows {
- current_row: row,
- suggestion_row_start: suggestion_range.start,
- suggestion_row_end: suggestion_range.end,
- fold_buffer_rows,
- }
- }
-
- #[cfg(test)]
- pub fn text(&self) -> String {
- self.chunks(Default::default()..self.len(), false, None, None)
- .map(|chunk| chunk.text)
- .collect()
- }
-}
-
-pub struct SuggestionChunks<'a> {
- prefix_chunks: Option<FoldChunks<'a>>,
- suggestion_chunks: Option<text::Chunks<'a>>,
- suffix_chunks: Option<FoldChunks<'a>>,
- highlight_style: Option<HighlightStyle>,
-}
-
-impl<'a> Iterator for SuggestionChunks<'a> {
- type Item = Chunk<'a>;
-
- fn next(&mut self) -> Option<Self::Item> {
- if let Some(chunks) = self.prefix_chunks.as_mut() {
- if let Some(chunk) = chunks.next() {
- return Some(chunk);
- } else {
- self.prefix_chunks = None;
- }
- }
-
- if let Some(chunks) = self.suggestion_chunks.as_mut() {
- if let Some(chunk) = chunks.next() {
- return Some(Chunk {
- text: chunk,
- highlight_style: self.highlight_style,
- ..Default::default()
- });
- } else {
- self.suggestion_chunks = None;
- }
- }
-
- if let Some(chunks) = self.suffix_chunks.as_mut() {
- if let Some(chunk) = chunks.next() {
- return Some(chunk);
- } else {
- self.suffix_chunks = None;
- }
- }
-
- None
- }
-}
-
-#[derive(Clone)]
-pub struct SuggestionBufferRows<'a> {
- current_row: u32,
- suggestion_row_start: u32,
- suggestion_row_end: u32,
- fold_buffer_rows: FoldBufferRows<'a>,
-}
-
-impl<'a> Iterator for SuggestionBufferRows<'a> {
- type Item = Option<u32>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let row = post_inc(&mut self.current_row);
- if row <= self.suggestion_row_start || row > self.suggestion_row_end {
- self.fold_buffer_rows.next()
- } else {
- Some(None)
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::{display_map::fold_map::FoldMap, MultiBuffer};
- use gpui::AppContext;
- use rand::{prelude::StdRng, Rng};
- use settings::SettingsStore;
- use std::{
- env,
- ops::{Bound, RangeBounds},
- };
-
- #[gpui::test]
- fn test_basic(cx: &mut AppContext) {
- let buffer = MultiBuffer::build_simple("abcdefghi", cx);
- let buffer_edits = buffer.update(cx, |buffer, _| buffer.subscribe());
- let (mut fold_map, fold_snapshot) = FoldMap::new(buffer.read(cx).snapshot(cx));
- let (suggestion_map, suggestion_snapshot) = SuggestionMap::new(fold_snapshot.clone());
- assert_eq!(suggestion_snapshot.text(), "abcdefghi");
-
- let (suggestion_snapshot, _, _) = suggestion_map.replace(
- Some(Suggestion {
- position: 3,
- text: "123\n456".into(),
- }),
- fold_snapshot,
- Default::default(),
- );
- assert_eq!(suggestion_snapshot.text(), "abc123\n456defghi");
-
- buffer.update(cx, |buffer, cx| {
- buffer.edit(
- [(0..0, "ABC"), (3..3, "DEF"), (4..4, "GHI"), (9..9, "JKL")],
- None,
- cx,
- )
- });
- let (fold_snapshot, fold_edits) = fold_map.read(
- buffer.read(cx).snapshot(cx),
- buffer_edits.consume().into_inner(),
- );
- let (suggestion_snapshot, _) = suggestion_map.sync(fold_snapshot.clone(), fold_edits);
- assert_eq!(suggestion_snapshot.text(), "ABCabcDEF123\n456dGHIefghiJKL");
-
- let (mut fold_map_writer, _, _) =
- fold_map.write(buffer.read(cx).snapshot(cx), Default::default());
- let (fold_snapshot, fold_edits) = fold_map_writer.fold([0..3]);
- let (suggestion_snapshot, _) = suggestion_map.sync(fold_snapshot, fold_edits);
- assert_eq!(suggestion_snapshot.text(), "⋯abcDEF123\n456dGHIefghiJKL");
-
- let (mut fold_map_writer, _, _) =
- fold_map.write(buffer.read(cx).snapshot(cx), Default::default());
- let (fold_snapshot, fold_edits) = fold_map_writer.fold([6..10]);
- let (suggestion_snapshot, _) = suggestion_map.sync(fold_snapshot, fold_edits);
- assert_eq!(suggestion_snapshot.text(), "⋯abc⋯GHIefghiJKL");
- }
-
- #[gpui::test(iterations = 100)]
- fn test_random_suggestions(cx: &mut AppContext, mut rng: StdRng) {
- init_test(cx);
-
- let operations = env::var("OPERATIONS")
- .map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
- .unwrap_or(10);
-
- let len = rng.gen_range(0..30);
- let buffer = if rng.gen() {
- let text = util::RandomCharIter::new(&mut rng)
- .take(len)
- .collect::<String>();
- MultiBuffer::build_simple(&text, cx)
- } else {
- MultiBuffer::build_random(&mut rng, cx)
- };
- let mut buffer_snapshot = buffer.read(cx).snapshot(cx);
- log::info!("buffer text: {:?}", buffer_snapshot.text());
-
- let (mut fold_map, mut fold_snapshot) = FoldMap::new(buffer_snapshot.clone());
- let (suggestion_map, mut suggestion_snapshot) = SuggestionMap::new(fold_snapshot.clone());
-
- for _ in 0..operations {
- let mut suggestion_edits = Patch::default();
-
- let mut prev_suggestion_text = suggestion_snapshot.text();
- let mut buffer_edits = Vec::new();
- match rng.gen_range(0..=100) {
- 0..=29 => {
- let (_, edits) = suggestion_map.randomly_mutate(&mut rng);
- suggestion_edits = suggestion_edits.compose(edits);
- }
- 30..=59 => {
- for (new_fold_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) {
- fold_snapshot = new_fold_snapshot;
- let (_, edits) = suggestion_map.sync(fold_snapshot.clone(), fold_edits);
- suggestion_edits = suggestion_edits.compose(edits);
- }
- }
- _ => buffer.update(cx, |buffer, cx| {
- let subscription = buffer.subscribe();
- let edit_count = rng.gen_range(1..=5);
- buffer.randomly_mutate(&mut rng, edit_count, cx);
- buffer_snapshot = buffer.snapshot(cx);
- let edits = subscription.consume().into_inner();
- log::info!("editing {:?}", edits);
- buffer_edits.extend(edits);
- }),
- };
-
- let (new_fold_snapshot, fold_edits) =
- fold_map.read(buffer_snapshot.clone(), buffer_edits);
- fold_snapshot = new_fold_snapshot;
- let (new_suggestion_snapshot, edits) =
- suggestion_map.sync(fold_snapshot.clone(), fold_edits);
- suggestion_snapshot = new_suggestion_snapshot;
- suggestion_edits = suggestion_edits.compose(edits);
-
- log::info!("buffer text: {:?}", buffer_snapshot.text());
- log::info!("folds text: {:?}", fold_snapshot.text());
- log::info!("suggestions text: {:?}", suggestion_snapshot.text());
-
- let mut expected_text = Rope::from(fold_snapshot.text().as_str());
- let mut expected_buffer_rows = fold_snapshot.buffer_rows(0).collect::<Vec<_>>();
- if let Some(suggestion) = suggestion_snapshot.suggestion.as_ref() {
- expected_text.replace(
- suggestion.position.0..suggestion.position.0,
- &suggestion.text.to_string(),
- );
- let suggestion_start = suggestion.position.to_point(&fold_snapshot).0;
- let suggestion_end = suggestion_start + suggestion.text.max_point();
- expected_buffer_rows.splice(
- (suggestion_start.row + 1) as usize..(suggestion_start.row + 1) as usize,
- (0..suggestion_end.row - suggestion_start.row).map(|_| None),
- );
- }
- assert_eq!(suggestion_snapshot.text(), expected_text.to_string());
- for row_start in 0..expected_buffer_rows.len() {
- assert_eq!(
- suggestion_snapshot
- .buffer_rows(row_start as u32)
- .collect::<Vec<_>>(),
- &expected_buffer_rows[row_start..],
- "incorrect buffer rows starting at {}",
- row_start
- );
- }
-
- for _ in 0..5 {
- let mut end = rng.gen_range(0..=suggestion_snapshot.len().0);
- end = expected_text.clip_offset(end, Bias::Right);
- let mut start = rng.gen_range(0..=end);
- start = expected_text.clip_offset(start, Bias::Right);
-
- let actual_text = suggestion_snapshot
- .chunks(
- SuggestionOffset(start)..SuggestionOffset(end),
- false,
- None,
- None,
- )
- .map(|chunk| chunk.text)
- .collect::<String>();
- assert_eq!(
- actual_text,
- expected_text.slice(start..end).to_string(),
- "incorrect text in range {:?}",
- start..end
- );
-
- let start_point = SuggestionPoint(expected_text.offset_to_point(start));
- let end_point = SuggestionPoint(expected_text.offset_to_point(end));
- assert_eq!(
- suggestion_snapshot.text_summary_for_range(start_point..end_point),
- expected_text.slice(start..end).summary()
- );
- }
-
- for edit in suggestion_edits.into_inner() {
- prev_suggestion_text.replace_range(
- edit.new.start.0..edit.new.start.0 + edit.old_len().0,
- &suggestion_snapshot.text()[edit.new.start.0..edit.new.end.0],
- );
- }
- assert_eq!(prev_suggestion_text, suggestion_snapshot.text());
-
- assert_eq!(expected_text.max_point(), suggestion_snapshot.max_point().0);
- assert_eq!(expected_text.len(), suggestion_snapshot.len().0);
-
- let mut suggestion_point = SuggestionPoint::default();
- let mut suggestion_offset = SuggestionOffset::default();
- for ch in expected_text.chars() {
- assert_eq!(
- suggestion_snapshot.to_offset(suggestion_point),
- suggestion_offset,
- "invalid to_offset({:?})",
- suggestion_point
- );
- assert_eq!(
- suggestion_snapshot.to_point(suggestion_offset),
- suggestion_point,
- "invalid to_point({:?})",
- suggestion_offset
- );
- assert_eq!(
- suggestion_snapshot
- .to_suggestion_point(suggestion_snapshot.to_fold_point(suggestion_point)),
- suggestion_snapshot.clip_point(suggestion_point, Bias::Left),
- );
-
- let mut bytes = [0; 4];
- for byte in ch.encode_utf8(&mut bytes).as_bytes() {
- suggestion_offset.0 += 1;
- if *byte == b'\n' {
- suggestion_point.0 += Point::new(1, 0);
- } else {
- suggestion_point.0 += Point::new(0, 1);
- }
-
- let clipped_left_point =
- suggestion_snapshot.clip_point(suggestion_point, Bias::Left);
- let clipped_right_point =
- suggestion_snapshot.clip_point(suggestion_point, Bias::Right);
- assert!(
- clipped_left_point <= clipped_right_point,
- "clipped left point {:?} is greater than clipped right point {:?}",
- clipped_left_point,
- clipped_right_point
- );
- assert_eq!(
- clipped_left_point.0,
- expected_text.clip_point(clipped_left_point.0, Bias::Left)
- );
- assert_eq!(
- clipped_right_point.0,
- expected_text.clip_point(clipped_right_point.0, Bias::Right)
- );
- assert!(clipped_left_point <= suggestion_snapshot.max_point());
- assert!(clipped_right_point <= suggestion_snapshot.max_point());
-
- if let Some(suggestion) = suggestion_snapshot.suggestion.as_ref() {
- let suggestion_start = suggestion.position.to_point(&fold_snapshot).0;
- let suggestion_end = suggestion_start + suggestion.text.max_point();
- let invalid_range = (
- Bound::Excluded(suggestion_start),
- Bound::Included(suggestion_end),
- );
- assert!(
- !invalid_range.contains(&clipped_left_point.0),
- "clipped left point {:?} is inside invalid suggestion range {:?}",
- clipped_left_point,
- invalid_range
- );
- assert!(
- !invalid_range.contains(&clipped_right_point.0),
- "clipped right point {:?} is inside invalid suggestion range {:?}",
- clipped_right_point,
- invalid_range
- );
- }
- }
- }
- }
- }
-
- fn init_test(cx: &mut AppContext) {
- cx.set_global(SettingsStore::test(cx));
- theme::init((), cx);
- }
-
- impl SuggestionMap {
- pub fn randomly_mutate(
- &self,
- rng: &mut impl Rng,
- ) -> (SuggestionSnapshot, Vec<SuggestionEdit>) {
- let fold_snapshot = self.0.lock().fold_snapshot.clone();
- let new_suggestion = if rng.gen_bool(0.3) {
- None
- } else {
- let index = rng.gen_range(0..=fold_snapshot.buffer_snapshot().len());
- let len = rng.gen_range(0..30);
- Some(Suggestion {
- position: index,
- text: util::RandomCharIter::new(rng)
- .take(len)
- .filter(|ch| *ch != '\r')
- .collect::<String>()
- .as_str()
- .into(),
- })
- };
-
- log::info!("replacing suggestion with {:?}", new_suggestion);
- let (snapshot, edits, _) =
- self.replace(new_suggestion, fold_snapshot, Default::default());
- (snapshot, edits)
- }
- }
-}
@@ -1,5 +1,5 @@
use super::{
- inlay_map::{self, InlayChunks, InlayEdit, InlayPoint, InlaySnapshot},
+ fold_map::{self, FoldChunks, FoldEdit, FoldPoint, FoldSnapshot},
TextHighlights,
};
use crate::MultiBufferSnapshot;
@@ -14,9 +14,9 @@ const MAX_EXPANSION_COLUMN: u32 = 256;
pub struct TabMap(Mutex<TabSnapshot>);
impl TabMap {
- pub fn new(input: InlaySnapshot, tab_size: NonZeroU32) -> (Self, TabSnapshot) {
+ pub fn new(fold_snapshot: FoldSnapshot, tab_size: NonZeroU32) -> (Self, TabSnapshot) {
let snapshot = TabSnapshot {
- inlay_snapshot: input,
+ fold_snapshot,
tab_size,
max_expansion_column: MAX_EXPANSION_COLUMN,
version: 0,
@@ -32,45 +32,42 @@ impl TabMap {
pub fn sync(
&self,
- inlay_snapshot: InlaySnapshot,
- mut suggestion_edits: Vec<InlayEdit>,
+ fold_snapshot: FoldSnapshot,
+ mut fold_edits: Vec<FoldEdit>,
tab_size: NonZeroU32,
) -> (TabSnapshot, Vec<TabEdit>) {
let mut old_snapshot = self.0.lock();
let mut new_snapshot = TabSnapshot {
- inlay_snapshot,
+ fold_snapshot,
tab_size,
max_expansion_column: old_snapshot.max_expansion_column,
version: old_snapshot.version,
};
- if old_snapshot.inlay_snapshot.version != new_snapshot.inlay_snapshot.version {
+ if old_snapshot.fold_snapshot.version != new_snapshot.fold_snapshot.version {
new_snapshot.version += 1;
}
- let mut tab_edits = Vec::with_capacity(suggestion_edits.len());
+ let mut tab_edits = Vec::with_capacity(fold_edits.len());
if old_snapshot.tab_size == new_snapshot.tab_size {
// Expand each edit to include the next tab on the same line as the edit,
// and any subsequent tabs on that line that moved across the tab expansion
// boundary.
- for suggestion_edit in &mut suggestion_edits {
- let old_end = old_snapshot
- .inlay_snapshot
- .to_point(suggestion_edit.old.end);
- let old_end_row_successor_offset = old_snapshot.inlay_snapshot.to_offset(cmp::min(
- InlayPoint::new(old_end.row() + 1, 0),
- old_snapshot.inlay_snapshot.max_point(),
- ));
- let new_end = new_snapshot
- .inlay_snapshot
- .to_point(suggestion_edit.new.end);
+ for fold_edit in &mut fold_edits {
+ let old_end = fold_edit.old.end.to_point(&old_snapshot.fold_snapshot);
+ let old_end_row_successor_offset = cmp::min(
+ FoldPoint::new(old_end.row() + 1, 0),
+ old_snapshot.fold_snapshot.max_point(),
+ )
+ .to_offset(&old_snapshot.fold_snapshot);
+ let new_end = fold_edit.new.end.to_point(&new_snapshot.fold_snapshot);
let mut offset_from_edit = 0;
let mut first_tab_offset = None;
let mut last_tab_with_changed_expansion_offset = None;
- 'outer: for chunk in old_snapshot.inlay_snapshot.chunks(
- suggestion_edit.old.end..old_end_row_successor_offset,
+ 'outer: for chunk in old_snapshot.fold_snapshot.chunks(
+ fold_edit.old.end..old_end_row_successor_offset,
false,
None,
None,
@@ -101,39 +98,31 @@ impl TabMap {
}
if let Some(offset) = last_tab_with_changed_expansion_offset.or(first_tab_offset) {
- suggestion_edit.old.end.0 += offset as usize + 1;
- suggestion_edit.new.end.0 += offset as usize + 1;
+ fold_edit.old.end.0 += offset as usize + 1;
+ fold_edit.new.end.0 += offset as usize + 1;
}
}
// Combine any edits that overlap due to the expansion.
let mut ix = 1;
- while ix < suggestion_edits.len() {
- let (prev_edits, next_edits) = suggestion_edits.split_at_mut(ix);
+ while ix < fold_edits.len() {
+ let (prev_edits, next_edits) = fold_edits.split_at_mut(ix);
let prev_edit = prev_edits.last_mut().unwrap();
let edit = &next_edits[0];
if prev_edit.old.end >= edit.old.start {
prev_edit.old.end = edit.old.end;
prev_edit.new.end = edit.new.end;
- suggestion_edits.remove(ix);
+ fold_edits.remove(ix);
} else {
ix += 1;
}
}
- for suggestion_edit in suggestion_edits {
- let old_start = old_snapshot
- .inlay_snapshot
- .to_point(suggestion_edit.old.start);
- let old_end = old_snapshot
- .inlay_snapshot
- .to_point(suggestion_edit.old.end);
- let new_start = new_snapshot
- .inlay_snapshot
- .to_point(suggestion_edit.new.start);
- let new_end = new_snapshot
- .inlay_snapshot
- .to_point(suggestion_edit.new.end);
+ for fold_edit in fold_edits {
+ let old_start = fold_edit.old.start.to_point(&old_snapshot.fold_snapshot);
+ let old_end = fold_edit.old.end.to_point(&old_snapshot.fold_snapshot);
+ let new_start = fold_edit.new.start.to_point(&new_snapshot.fold_snapshot);
+ let new_end = fold_edit.new.end.to_point(&new_snapshot.fold_snapshot);
tab_edits.push(TabEdit {
old: old_snapshot.to_tab_point(old_start)..old_snapshot.to_tab_point(old_end),
new: new_snapshot.to_tab_point(new_start)..new_snapshot.to_tab_point(new_end),
@@ -154,7 +143,7 @@ impl TabMap {
#[derive(Clone)]
pub struct TabSnapshot {
- pub inlay_snapshot: InlaySnapshot,
+ pub fold_snapshot: FoldSnapshot,
pub tab_size: NonZeroU32,
pub max_expansion_column: u32,
pub version: usize,
@@ -162,13 +151,13 @@ pub struct TabSnapshot {
impl TabSnapshot {
pub fn buffer_snapshot(&self) -> &MultiBufferSnapshot {
- self.inlay_snapshot.buffer_snapshot()
+ &self.fold_snapshot.inlay_snapshot.buffer
}
pub fn line_len(&self, row: u32) -> u32 {
let max_point = self.max_point();
if row < max_point.row() {
- self.to_tab_point(InlayPoint::new(row, self.inlay_snapshot.line_len(row)))
+ self.to_tab_point(FoldPoint::new(row, self.fold_snapshot.line_len(row)))
.0
.column
} else {
@@ -181,10 +170,10 @@ impl TabSnapshot {
}
pub fn text_summary_for_range(&self, range: Range<TabPoint>) -> TextSummary {
- let input_start = self.to_inlay_point(range.start, Bias::Left).0;
- let input_end = self.to_inlay_point(range.end, Bias::Right).0;
+ let input_start = self.to_fold_point(range.start, Bias::Left).0;
+ let input_end = self.to_fold_point(range.end, Bias::Right).0;
let input_summary = self
- .inlay_snapshot
+ .fold_snapshot
.text_summary_for_range(input_start..input_end);
let mut first_line_chars = 0;
@@ -234,15 +223,16 @@ impl TabSnapshot {
range: Range<TabPoint>,
language_aware: bool,
text_highlights: Option<&'a TextHighlights>,
- suggestion_highlight: Option<HighlightStyle>,
+ inlay_highlights: Option<HighlightStyle>,
) -> TabChunks<'a> {
let (input_start, expanded_char_column, to_next_stop) =
- self.to_inlay_point(range.start, Bias::Left);
+ self.to_fold_point(range.start, Bias::Left);
let input_column = input_start.column();
- let input_start = self.inlay_snapshot.to_offset(input_start);
+ let input_start = input_start.to_offset(&self.fold_snapshot);
let input_end = self
- .inlay_snapshot
- .to_offset(self.to_inlay_point(range.end, Bias::Right).0);
+ .to_fold_point(range.end, Bias::Right)
+ .0
+ .to_offset(&self.fold_snapshot);
let to_next_stop = if range.start.0 + Point::new(0, to_next_stop) > range.end.0 {
range.end.column() - range.start.column()
} else {
@@ -250,11 +240,11 @@ impl TabSnapshot {
};
TabChunks {
- inlay_chunks: self.inlay_snapshot.chunks(
+ fold_chunks: self.fold_snapshot.chunks(
input_start..input_end,
language_aware,
text_highlights,
- suggestion_highlight,
+ inlay_highlights,
),
input_column,
column: expanded_char_column,
@@ -271,8 +261,8 @@ impl TabSnapshot {
}
}
- pub fn buffer_rows(&self, row: u32) -> inlay_map::InlayBufferRows<'_> {
- self.inlay_snapshot.buffer_rows(row)
+ pub fn buffer_rows(&self, row: u32) -> fold_map::FoldBufferRows<'_> {
+ self.fold_snapshot.buffer_rows(row)
}
#[cfg(test)]
@@ -283,48 +273,46 @@ impl TabSnapshot {
}
pub fn max_point(&self) -> TabPoint {
- self.to_tab_point(self.inlay_snapshot.max_point())
+ self.to_tab_point(self.fold_snapshot.max_point())
}
pub fn clip_point(&self, point: TabPoint, bias: Bias) -> TabPoint {
self.to_tab_point(
- self.inlay_snapshot
- .clip_point(self.to_inlay_point(point, bias).0, bias),
+ self.fold_snapshot
+ .clip_point(self.to_fold_point(point, bias).0, bias),
)
}
- pub fn to_tab_point(&self, input: InlayPoint) -> TabPoint {
- let chars = self
- .inlay_snapshot
- .chars_at(InlayPoint::new(input.row(), 0));
+ pub fn to_tab_point(&self, input: FoldPoint) -> TabPoint {
+ let chars = self.fold_snapshot.chars_at(FoldPoint::new(input.row(), 0));
let expanded = self.expand_tabs(chars, input.column());
TabPoint::new(input.row(), expanded)
}
- pub fn to_inlay_point(&self, output: TabPoint, bias: Bias) -> (InlayPoint, u32, u32) {
- let chars = self
- .inlay_snapshot
- .chars_at(InlayPoint::new(output.row(), 0));
+ pub fn to_fold_point(&self, output: TabPoint, bias: Bias) -> (FoldPoint, u32, u32) {
+ let chars = self.fold_snapshot.chars_at(FoldPoint::new(output.row(), 0));
let expanded = output.column();
let (collapsed, expanded_char_column, to_next_stop) =
self.collapse_tabs(chars, expanded, bias);
(
- InlayPoint::new(output.row(), collapsed as u32),
+ FoldPoint::new(output.row(), collapsed as u32),
expanded_char_column,
to_next_stop,
)
}
pub fn make_tab_point(&self, point: Point, bias: Bias) -> TabPoint {
- let fold_point = self.inlay_snapshot.fold_snapshot.to_fold_point(point, bias);
- let inlay_point = self.inlay_snapshot.to_inlay_point(fold_point);
- self.to_tab_point(inlay_point)
+ let inlay_point = self.fold_snapshot.inlay_snapshot.to_inlay_point(point);
+ let fold_point = self.fold_snapshot.to_fold_point(inlay_point, bias);
+ self.to_tab_point(fold_point)
}
pub fn to_point(&self, point: TabPoint, bias: Bias) -> Point {
- let inlay_point = self.to_inlay_point(point, bias).0;
- let fold_point = self.inlay_snapshot.to_fold_point(inlay_point);
- fold_point.to_buffer_point(&self.inlay_snapshot.fold_snapshot)
+ let fold_point = self.to_fold_point(point, bias).0;
+ let inlay_point = fold_point.to_inlay_point(&self.fold_snapshot);
+ self.fold_snapshot
+ .inlay_snapshot
+ .to_buffer_point(inlay_point)
}
fn expand_tabs(&self, chars: impl Iterator<Item = char>, column: u32) -> u32 {
@@ -483,7 +471,7 @@ impl<'a> std::ops::AddAssign<&'a Self> for TextSummary {
const SPACES: &str = " ";
pub struct TabChunks<'a> {
- inlay_chunks: InlayChunks<'a>,
+ fold_chunks: FoldChunks<'a>,
chunk: Chunk<'a>,
column: u32,
max_expansion_column: u32,
@@ -499,7 +487,7 @@ impl<'a> Iterator for TabChunks<'a> {
fn next(&mut self) -> Option<Self::Item> {
if self.chunk.text.is_empty() {
- if let Some(chunk) = self.inlay_chunks.next() {
+ if let Some(chunk) = self.fold_chunks.next() {
self.chunk = chunk;
if self.inside_leading_tab {
self.chunk.text = &self.chunk.text[1..];
@@ -576,9 +564,9 @@ mod tests {
fn test_expand_tabs(cx: &mut gpui::AppContext) {
let buffer = MultiBuffer::build_simple("", cx);
let buffer_snapshot = buffer.read(cx).snapshot(cx);
- let (_, fold_snapshot) = FoldMap::new(buffer_snapshot.clone());
- let (_, inlay_snapshot) = InlayMap::new(fold_snapshot);
- let (_, tab_snapshot) = TabMap::new(inlay_snapshot, 4.try_into().unwrap());
+ let (_, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
+ let (_, fold_snapshot) = FoldMap::new(inlay_snapshot);
+ let (_, tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap());
assert_eq!(tab_snapshot.expand_tabs("\t".chars(), 0), 0);
assert_eq!(tab_snapshot.expand_tabs("\t".chars(), 1), 4);
@@ -593,9 +581,9 @@ mod tests {
let buffer = MultiBuffer::build_simple(input, cx);
let buffer_snapshot = buffer.read(cx).snapshot(cx);
- let (_, fold_snapshot) = FoldMap::new(buffer_snapshot.clone());
- let (_, inlay_snapshot) = InlayMap::new(fold_snapshot);
- let (_, mut tab_snapshot) = TabMap::new(inlay_snapshot, 4.try_into().unwrap());
+ let (_, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
+ let (_, fold_snapshot) = FoldMap::new(inlay_snapshot);
+ let (_, mut tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap());
tab_snapshot.max_expansion_column = max_expansion_column;
assert_eq!(tab_snapshot.text(), output);
@@ -619,16 +607,16 @@ mod tests {
let input_point = Point::new(0, ix as u32);
let output_point = Point::new(0, output.find(c).unwrap() as u32);
assert_eq!(
- tab_snapshot.to_tab_point(InlayPoint(input_point)),
+ tab_snapshot.to_tab_point(FoldPoint(input_point)),
TabPoint(output_point),
"to_tab_point({input_point:?})"
);
assert_eq!(
tab_snapshot
- .to_inlay_point(TabPoint(output_point), Bias::Left)
+ .to_fold_point(TabPoint(output_point), Bias::Left)
.0,
- InlayPoint(input_point),
- "to_suggestion_point({output_point:?})"
+ FoldPoint(input_point),
+ "to_fold_point({output_point:?})"
);
}
}
@@ -641,9 +629,9 @@ mod tests {
let buffer = MultiBuffer::build_simple(input, cx);
let buffer_snapshot = buffer.read(cx).snapshot(cx);
- let (_, fold_snapshot) = FoldMap::new(buffer_snapshot.clone());
- let (_, inlay_snapshot) = InlayMap::new(fold_snapshot);
- let (_, mut tab_snapshot) = TabMap::new(inlay_snapshot, 4.try_into().unwrap());
+ let (_, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
+ let (_, fold_snapshot) = FoldMap::new(inlay_snapshot);
+ let (_, mut tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap());
tab_snapshot.max_expansion_column = max_expansion_column;
assert_eq!(tab_snapshot.text(), input);
@@ -655,9 +643,9 @@ mod tests {
let buffer = MultiBuffer::build_simple(&input, cx);
let buffer_snapshot = buffer.read(cx).snapshot(cx);
- let (_, fold_snapshot) = FoldMap::new(buffer_snapshot.clone());
- let (_, inlay_snapshot) = InlayMap::new(fold_snapshot);
- let (_, tab_snapshot) = TabMap::new(inlay_snapshot, 4.try_into().unwrap());
+ let (_, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
+ let (_, fold_snapshot) = FoldMap::new(inlay_snapshot);
+ let (_, tab_snapshot) = TabMap::new(fold_snapshot, 4.try_into().unwrap());
assert_eq!(
chunks(&tab_snapshot, TabPoint::zero()),
@@ -714,15 +702,16 @@ mod tests {
let buffer_snapshot = buffer.read(cx).snapshot(cx);
log::info!("Buffer text: {:?}", buffer_snapshot.text());
- let (mut fold_map, _) = FoldMap::new(buffer_snapshot.clone());
+ let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
+ log::info!("InlayMap text: {:?}", inlay_snapshot.text());
+ let (mut fold_map, _) = FoldMap::new(inlay_snapshot.clone());
fold_map.randomly_mutate(&mut rng);
- let (fold_snapshot, _) = fold_map.read(buffer_snapshot, vec![]);
+ let (fold_snapshot, _) = fold_map.read(inlay_snapshot, vec![]);
log::info!("FoldMap text: {:?}", fold_snapshot.text());
- let (mut inlay_map, _) = InlayMap::new(fold_snapshot.clone());
let (inlay_snapshot, _) = inlay_map.randomly_mutate(&mut 0, &mut rng);
log::info!("InlayMap text: {:?}", inlay_snapshot.text());
- let (tab_map, _) = TabMap::new(inlay_snapshot.clone(), tab_size);
+ let (tab_map, _) = TabMap::new(fold_snapshot.clone(), tab_size);
let tabs_snapshot = tab_map.set_max_expansion_column(32);
let text = text::Rope::from(tabs_snapshot.text().as_str());
@@ -1,5 +1,5 @@
use super::{
- inlay_map::InlayBufferRows,
+ fold_map::FoldBufferRows,
tab_map::{self, TabEdit, TabPoint, TabSnapshot},
TextHighlights,
};
@@ -65,7 +65,7 @@ pub struct WrapChunks<'a> {
#[derive(Clone)]
pub struct WrapBufferRows<'a> {
- input_buffer_rows: InlayBufferRows<'a>,
+ input_buffer_rows: FoldBufferRows<'a>,
input_buffer_row: Option<u32>,
output_row: u32,
soft_wrapped: bool,
@@ -575,7 +575,7 @@ impl WrapSnapshot {
rows: Range<u32>,
language_aware: bool,
text_highlights: Option<&'a TextHighlights>,
- suggestion_highlight: Option<HighlightStyle>,
+ inlay_highlights: Option<HighlightStyle>,
) -> WrapChunks<'a> {
let output_start = WrapPoint::new(rows.start, 0);
let output_end = WrapPoint::new(rows.end, 0);
@@ -593,7 +593,7 @@ impl WrapSnapshot {
input_start..input_end,
language_aware,
text_highlights,
- suggestion_highlight,
+ inlay_highlights,
),
input_chunk: Default::default(),
output_position: output_start,
@@ -762,13 +762,16 @@ impl WrapSnapshot {
let mut prev_fold_row = 0;
for display_row in 0..=self.max_point().row() {
let tab_point = self.to_tab_point(WrapPoint::new(display_row, 0));
- let inlay_point = self.tab_snapshot.to_inlay_point(tab_point, Bias::Left).0;
- let fold_point = self.tab_snapshot.inlay_snapshot.to_fold_point(inlay_point);
+ let fold_point = self.tab_snapshot.to_fold_point(tab_point, Bias::Left).0;
if fold_point.row() == prev_fold_row && display_row != 0 {
expected_buffer_rows.push(None);
} else {
- let buffer_point =
- fold_point.to_buffer_point(&self.tab_snapshot.inlay_snapshot.fold_snapshot);
+ let inlay_point = fold_point.to_inlay_point(&self.tab_snapshot.fold_snapshot);
+ let buffer_point = self
+ .tab_snapshot
+ .fold_snapshot
+ .inlay_snapshot
+ .to_buffer_point(inlay_point);
expected_buffer_rows.push(input_buffer_rows[buffer_point.row as usize]);
prev_fold_row = fold_point.row();
}
@@ -1083,11 +1086,11 @@ mod tests {
});
let mut buffer_snapshot = buffer.read_with(cx, |buffer, cx| buffer.snapshot(cx));
log::info!("Buffer text: {:?}", buffer_snapshot.text());
- let (mut fold_map, fold_snapshot) = FoldMap::new(buffer_snapshot.clone());
+ let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
+ log::info!("InlayMap text: {:?}", inlay_snapshot.text());
+ let (mut fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot.clone());
log::info!("FoldMap text: {:?}", fold_snapshot.text());
- let (mut inlay_map, inlay_snapshot) = InlayMap::new(fold_snapshot.clone());
- log::info!("InlaysMap text: {:?}", inlay_snapshot.text());
- let (tab_map, _) = TabMap::new(inlay_snapshot.clone(), tab_size);
+ let (tab_map, _) = TabMap::new(fold_snapshot.clone(), tab_size);
let tabs_snapshot = tab_map.set_max_expansion_column(32);
log::info!("TabMap text: {:?}", tabs_snapshot.text());
@@ -1134,10 +1137,8 @@ mod tests {
}
20..=39 => {
for (fold_snapshot, fold_edits) in fold_map.randomly_mutate(&mut rng) {
- let (inlay_snapshot, inlay_edits) =
- inlay_map.sync(fold_snapshot, fold_edits);
let (tabs_snapshot, tab_edits) =
- tab_map.sync(inlay_snapshot, inlay_edits, tab_size);
+ tab_map.sync(fold_snapshot, fold_edits, tab_size);
let (mut snapshot, wrap_edits) =
wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx));
snapshot.check_invariants();
@@ -1148,8 +1149,9 @@ mod tests {
40..=59 => {
let (inlay_snapshot, inlay_edits) =
inlay_map.randomly_mutate(&mut next_inlay_id, &mut rng);
+ let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
let (tabs_snapshot, tab_edits) =
- tab_map.sync(inlay_snapshot, inlay_edits, tab_size);
+ tab_map.sync(fold_snapshot, fold_edits, tab_size);
let (mut snapshot, wrap_edits) =
wrap_map.update(cx, |map, cx| map.sync(tabs_snapshot, tab_edits, cx));
snapshot.check_invariants();
@@ -1168,11 +1170,12 @@ mod tests {
}
log::info!("Buffer text: {:?}", buffer_snapshot.text());
- let (fold_snapshot, fold_edits) = fold_map.read(buffer_snapshot.clone(), buffer_edits);
- log::info!("FoldMap text: {:?}", fold_snapshot.text());
- let (inlay_snapshot, inlay_edits) = inlay_map.sync(fold_snapshot, fold_edits);
+ let (inlay_snapshot, inlay_edits) =
+ inlay_map.sync(buffer_snapshot.clone(), buffer_edits);
log::info!("InlayMap text: {:?}", inlay_snapshot.text());
- let (tabs_snapshot, tab_edits) = tab_map.sync(inlay_snapshot, inlay_edits, tab_size);
+ let (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
+ log::info!("FoldMap text: {:?}", fold_snapshot.text());
+ let (tabs_snapshot, tab_edits) = tab_map.sync(fold_snapshot, fold_edits, tab_size);
log::info!("TabMap text: {:?}", tabs_snapshot.text());
let unwrapped_text = tabs_snapshot.text();
@@ -1220,7 +1223,7 @@ mod tests {
if tab_size.get() == 1
|| !wrapped_snapshot
.tab_snapshot
- .inlay_snapshot
+ .fold_snapshot
.text()
.contains('\t')
{
@@ -70,11 +70,11 @@ use link_go_to_definition::{
hide_link_definition, show_link_definition, LinkDefinitionKind, LinkGoToDefinitionState,
};
use log::error;
+use multi_buffer::ToOffsetUtf16;
pub use multi_buffer::{
Anchor, AnchorRangeExt, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, ToOffset,
ToPoint,
};
-use multi_buffer::{MultiBufferChunks, ToOffsetUtf16};
use ordered_float::OrderedFloat;
use project::{FormatTrigger, Location, LocationLink, Project, ProjectPath, ProjectTransaction};
use scroll::{