Fix all FoldMap tests (without real inlays inside)
Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
This commit is contained in:
parent
29bb6c67b0
commit
f2c510000b
3 changed files with 159 additions and 171 deletions
|
@ -1031,7 +1031,7 @@ mod tests {
|
|||
let buffer_snapshot = buffer.read(cx).snapshot(cx);
|
||||
let subscription = buffer.update(cx, |buffer, _| buffer.subscribe());
|
||||
let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
|
||||
let (fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot);
|
||||
let (mut 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);
|
||||
|
@ -1277,7 +1277,7 @@ mod tests {
|
|||
|
||||
let mut buffer_snapshot = buffer.read(cx).snapshot(cx);
|
||||
let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
|
||||
let (fold_map, fold_snapshot) = FoldMap::new(inlay_snapshot);
|
||||
let (mut 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);
|
||||
|
|
|
@ -1,21 +1,16 @@
|
|||
use super::{
|
||||
inlay_map::{InlayBufferRows, InlayEdit, InlayOffset, InlayPoint, InlaySnapshot},
|
||||
inlay_map::{InlayBufferRows, InlayChunks, InlayEdit, InlayOffset, InlayPoint, InlaySnapshot},
|
||||
TextHighlights,
|
||||
};
|
||||
use crate::{
|
||||
multi_buffer::{MultiBufferChunks, MultiBufferRows},
|
||||
Anchor, AnchorRangeExt, MultiBufferSnapshot, ToOffset,
|
||||
};
|
||||
use crate::{Anchor, AnchorRangeExt, MultiBufferSnapshot, ToOffset};
|
||||
use collections::BTreeMap;
|
||||
use gpui::{color::Color, fonts::HighlightStyle};
|
||||
use language::{Chunk, Edit, Point, TextSummary};
|
||||
use parking_lot::Mutex;
|
||||
use std::{
|
||||
any::TypeId,
|
||||
cmp::{self, Ordering},
|
||||
iter::{self, Peekable},
|
||||
ops::{Add, AddAssign, Range, Sub},
|
||||
sync::atomic::Ordering::SeqCst,
|
||||
vec,
|
||||
};
|
||||
use sum_tree::{Bias, Cursor, FilterCursor, SumTree};
|
||||
|
@ -51,15 +46,6 @@ impl FoldPoint {
|
|||
InlayPoint(cursor.start().1 .0 + overshoot)
|
||||
}
|
||||
|
||||
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
|
||||
.inlay_snapshot
|
||||
.to_offset(InlayPoint(cursor.start().1 .0 + overshoot))
|
||||
}
|
||||
|
||||
pub fn to_offset(self, snapshot: &FoldSnapshot) -> FoldOffset {
|
||||
let mut cursor = snapshot
|
||||
.transforms
|
||||
|
@ -94,7 +80,7 @@ impl<'a> FoldMapWriter<'a> {
|
|||
) -> (FoldSnapshot, Vec<FoldEdit>) {
|
||||
let mut edits = Vec::new();
|
||||
let mut folds = Vec::new();
|
||||
let snapshot = self.0.inlay_snapshot.lock().clone();
|
||||
let snapshot = self.0.snapshot.inlay_snapshot.clone();
|
||||
for range in ranges.into_iter() {
|
||||
let buffer = &snapshot.buffer;
|
||||
let range = range.start.to_offset(&buffer)..range.end.to_offset(&buffer);
|
||||
|
@ -123,9 +109,9 @@ impl<'a> FoldMapWriter<'a> {
|
|||
let buffer = &snapshot.buffer;
|
||||
folds.sort_unstable_by(|a, b| sum_tree::SeekTarget::cmp(a, b, buffer));
|
||||
|
||||
self.0.folds = {
|
||||
self.0.snapshot.folds = {
|
||||
let mut new_tree = SumTree::new();
|
||||
let mut cursor = self.0.folds.cursor::<Fold>();
|
||||
let mut cursor = self.0.snapshot.folds.cursor::<Fold>();
|
||||
for fold in folds {
|
||||
new_tree.append(cursor.slice(&fold, Bias::Right, buffer), buffer);
|
||||
new_tree.push(fold, buffer);
|
||||
|
@ -136,14 +122,7 @@ impl<'a> FoldMapWriter<'a> {
|
|||
|
||||
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(),
|
||||
inlay_snapshot: snapshot,
|
||||
version: self.0.version,
|
||||
ellipses_color: self.0.ellipses_color,
|
||||
};
|
||||
(snapshot, edits)
|
||||
(self.0.snapshot.clone(), edits)
|
||||
}
|
||||
|
||||
pub fn unfold<T: ToOffset>(
|
||||
|
@ -153,11 +132,12 @@ impl<'a> FoldMapWriter<'a> {
|
|||
) -> (FoldSnapshot, Vec<FoldEdit>) {
|
||||
let mut edits = Vec::new();
|
||||
let mut fold_ixs_to_delete = Vec::new();
|
||||
let snapshot = self.0.inlay_snapshot.lock().clone();
|
||||
let snapshot = self.0.snapshot.inlay_snapshot.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(&snapshot, &self.0.folds, range, inclusive);
|
||||
let mut folds_cursor =
|
||||
intersecting_folds(&snapshot, &self.0.snapshot.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);
|
||||
if offset_range.end > offset_range.start {
|
||||
|
@ -176,8 +156,8 @@ impl<'a> FoldMapWriter<'a> {
|
|||
fold_ixs_to_delete.sort_unstable();
|
||||
fold_ixs_to_delete.dedup();
|
||||
|
||||
self.0.folds = {
|
||||
let mut cursor = self.0.folds.cursor::<usize>();
|
||||
self.0.snapshot.folds = {
|
||||
let mut cursor = self.0.snapshot.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);
|
||||
|
@ -189,69 +169,48 @@ impl<'a> FoldMapWriter<'a> {
|
|||
|
||||
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(),
|
||||
inlay_snapshot: snapshot,
|
||||
version: self.0.version,
|
||||
ellipses_color: self.0.ellipses_color,
|
||||
};
|
||||
(snapshot, edits)
|
||||
(self.0.snapshot.clone(), edits)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FoldMap {
|
||||
inlay_snapshot: Mutex<InlaySnapshot>,
|
||||
transforms: Mutex<SumTree<Transform>>,
|
||||
folds: SumTree<Fold>,
|
||||
version: usize,
|
||||
snapshot: FoldSnapshot,
|
||||
ellipses_color: Option<Color>,
|
||||
}
|
||||
|
||||
impl FoldMap {
|
||||
pub fn new(inlay_snapshot: InlaySnapshot) -> (Self, FoldSnapshot) {
|
||||
let this = Self {
|
||||
inlay_snapshot: Mutex::new(inlay_snapshot.clone()),
|
||||
folds: Default::default(),
|
||||
transforms: Mutex::new(SumTree::from_item(
|
||||
Transform {
|
||||
summary: TransformSummary {
|
||||
input: inlay_snapshot.text_summary(),
|
||||
output: inlay_snapshot.text_summary(),
|
||||
snapshot: FoldSnapshot {
|
||||
folds: Default::default(),
|
||||
transforms: SumTree::from_item(
|
||||
Transform {
|
||||
summary: TransformSummary {
|
||||
input: inlay_snapshot.text_summary(),
|
||||
output: inlay_snapshot.text_summary(),
|
||||
},
|
||||
output_text: None,
|
||||
},
|
||||
output_text: None,
|
||||
},
|
||||
&(),
|
||||
)),
|
||||
ellipses_color: None,
|
||||
version: 0,
|
||||
};
|
||||
|
||||
let snapshot = FoldSnapshot {
|
||||
transforms: this.transforms.lock().clone(),
|
||||
folds: this.folds.clone(),
|
||||
inlay_snapshot: inlay_snapshot.clone(),
|
||||
version: this.version,
|
||||
&(),
|
||||
),
|
||||
inlay_snapshot: inlay_snapshot.clone(),
|
||||
version: 0,
|
||||
ellipses_color: None,
|
||||
},
|
||||
ellipses_color: None,
|
||||
};
|
||||
let snapshot = this.snapshot.clone();
|
||||
(this, snapshot)
|
||||
}
|
||||
|
||||
pub fn read(
|
||||
&self,
|
||||
&mut self,
|
||||
inlay_snapshot: InlaySnapshot,
|
||||
edits: Vec<InlayEdit>,
|
||||
) -> (FoldSnapshot, Vec<FoldEdit>) {
|
||||
let edits = self.sync(inlay_snapshot, edits);
|
||||
self.check_invariants();
|
||||
let snapshot = FoldSnapshot {
|
||||
transforms: self.transforms.lock().clone(),
|
||||
folds: self.folds.clone(),
|
||||
inlay_snapshot: self.inlay_snapshot.lock().clone(),
|
||||
version: self.version,
|
||||
ellipses_color: self.ellipses_color,
|
||||
};
|
||||
(snapshot, edits)
|
||||
(self.snapshot.clone(), edits)
|
||||
}
|
||||
|
||||
pub fn write(
|
||||
|
@ -274,17 +233,20 @@ impl FoldMap {
|
|||
|
||||
fn check_invariants(&self) {
|
||||
if cfg!(test) {
|
||||
let inlay_snapshot = self.inlay_snapshot.lock();
|
||||
assert_eq!(
|
||||
self.transforms.lock().summary().input.len,
|
||||
inlay_snapshot.to_buffer_offset(inlay_snapshot.len()),
|
||||
self.snapshot.transforms.summary().input.len,
|
||||
self.snapshot
|
||||
.inlay_snapshot
|
||||
.to_buffer_offset(self.snapshot.inlay_snapshot.len()),
|
||||
"transform tree does not match inlay snapshot's length"
|
||||
);
|
||||
|
||||
let mut folds = self.folds.iter().peekable();
|
||||
let mut folds = self.snapshot.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.inlay_snapshot.lock().buffer);
|
||||
let comparison = fold
|
||||
.0
|
||||
.cmp(&next_fold.0, &self.snapshot.inlay_snapshot.buffer);
|
||||
assert!(comparison.is_le());
|
||||
}
|
||||
}
|
||||
|
@ -297,17 +259,16 @@ impl FoldMap {
|
|||
inlay_edits: Vec<InlayEdit>,
|
||||
) -> Vec<FoldEdit> {
|
||||
if inlay_edits.is_empty() {
|
||||
if self.inlay_snapshot.lock().version != inlay_snapshot.version {
|
||||
self.version += 1;
|
||||
if self.snapshot.inlay_snapshot.version != inlay_snapshot.version {
|
||||
self.snapshot.version += 1;
|
||||
}
|
||||
*self.inlay_snapshot.lock() = inlay_snapshot;
|
||||
self.snapshot.inlay_snapshot = inlay_snapshot;
|
||||
Vec::new()
|
||||
} else {
|
||||
let mut inlay_edits_iter = inlay_edits.iter().cloned().peekable();
|
||||
|
||||
let mut new_transforms = SumTree::new();
|
||||
let mut transforms = self.transforms.lock();
|
||||
let mut cursor = transforms.cursor::<InlayOffset>();
|
||||
let mut cursor = self.snapshot.transforms.cursor::<InlayOffset>();
|
||||
cursor.seek(&InlayOffset(0), Bias::Right, &());
|
||||
|
||||
while let Some(mut edit) = inlay_edits_iter.next() {
|
||||
|
@ -346,7 +307,7 @@ impl FoldMap {
|
|||
let anchor = inlay_snapshot
|
||||
.buffer
|
||||
.anchor_before(inlay_snapshot.to_buffer_offset(edit.new.start));
|
||||
let mut folds_cursor = self.folds.cursor::<Fold>();
|
||||
let mut folds_cursor = self.snapshot.folds.cursor::<Fold>();
|
||||
folds_cursor.seek(
|
||||
&Fold(anchor..Anchor::max()),
|
||||
Bias::Left,
|
||||
|
@ -451,7 +412,10 @@ impl FoldMap {
|
|||
|
||||
let mut fold_edits = Vec::with_capacity(inlay_edits.len());
|
||||
{
|
||||
let mut old_transforms = transforms.cursor::<(InlayOffset, FoldOffset)>();
|
||||
let mut old_transforms = self
|
||||
.snapshot
|
||||
.transforms
|
||||
.cursor::<(InlayOffset, FoldOffset)>();
|
||||
let mut new_transforms = new_transforms.cursor::<(InlayOffset, FoldOffset)>();
|
||||
|
||||
for mut edit in inlay_edits {
|
||||
|
@ -494,9 +458,9 @@ impl FoldMap {
|
|||
consolidate_fold_edits(&mut fold_edits);
|
||||
}
|
||||
|
||||
*transforms = new_transforms;
|
||||
*self.inlay_snapshot.lock() = inlay_snapshot;
|
||||
self.version += 1;
|
||||
self.snapshot.transforms = new_transforms;
|
||||
self.snapshot.inlay_snapshot = inlay_snapshot;
|
||||
self.snapshot.version += 1;
|
||||
fold_edits
|
||||
}
|
||||
}
|
||||
|
@ -524,10 +488,6 @@ impl FoldSnapshot {
|
|||
self.folds.items(&self.inlay_snapshot.buffer).len()
|
||||
}
|
||||
|
||||
pub fn text_summary(&self) -> TextSummary {
|
||||
self.transforms.summary().output.clone()
|
||||
}
|
||||
|
||||
pub fn text_summary_for_range(&self, range: Range<FoldPoint>) -> TextSummary {
|
||||
let mut summary = TextSummary::default();
|
||||
|
||||
|
@ -655,21 +615,24 @@ impl FoldSnapshot {
|
|||
where
|
||||
T: ToOffset,
|
||||
{
|
||||
let offset = offset.to_offset(&self.inlay_snapshot.buffer);
|
||||
let mut cursor = self.transforms.cursor::<usize>();
|
||||
cursor.seek(&offset, Bias::Right, &());
|
||||
let buffer_offset = offset.to_offset(&self.inlay_snapshot.buffer);
|
||||
let inlay_offset = self.inlay_snapshot.to_inlay_offset(buffer_offset);
|
||||
let mut cursor = self.transforms.cursor::<InlayOffset>();
|
||||
cursor.seek(&inlay_offset, Bias::Right, &());
|
||||
cursor.item().map_or(false, |t| t.output_text.is_some())
|
||||
}
|
||||
|
||||
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, &());
|
||||
let inlay_point = self
|
||||
.inlay_snapshot
|
||||
.to_inlay_point(Point::new(buffer_row, 0));
|
||||
let mut cursor = self.transforms.cursor::<InlayPoint>();
|
||||
cursor.seek(&inlay_point, Bias::Right, &());
|
||||
while let Some(transform) = cursor.item() {
|
||||
if transform.output_text.is_some() {
|
||||
return true;
|
||||
}
|
||||
if cursor.end(&()).row == buffer_row {
|
||||
if cursor.end(&()).row() == inlay_point.row() {
|
||||
cursor.next(&())
|
||||
} else {
|
||||
break;
|
||||
|
@ -683,39 +646,43 @@ impl FoldSnapshot {
|
|||
range: Range<FoldOffset>,
|
||||
language_aware: bool,
|
||||
text_highlights: Option<&'a TextHighlights>,
|
||||
// TODO kb need to call inlay chunks and style them
|
||||
inlay_highlights: Option<HighlightStyle>,
|
||||
) -> FoldChunks<'a> {
|
||||
let mut highlight_endpoints = Vec::new();
|
||||
let mut transform_cursor = self.transforms.cursor::<(FoldOffset, usize)>();
|
||||
let mut transform_cursor = self.transforms.cursor::<(FoldOffset, InlayOffset)>();
|
||||
|
||||
let buffer_end = {
|
||||
let inlay_end = {
|
||||
transform_cursor.seek(&range.end, Bias::Right, &());
|
||||
let overshoot = range.end.0 - transform_cursor.start().0 .0;
|
||||
transform_cursor.start().1 + overshoot
|
||||
transform_cursor.start().1 + InlayOffset(overshoot)
|
||||
};
|
||||
|
||||
let buffer_start = {
|
||||
let inlay_start = {
|
||||
transform_cursor.seek(&range.start, Bias::Right, &());
|
||||
let overshoot = range.start.0 - transform_cursor.start().0 .0;
|
||||
transform_cursor.start().1 + overshoot
|
||||
transform_cursor.start().1 + InlayOffset(overshoot)
|
||||
};
|
||||
|
||||
if let Some(text_highlights) = text_highlights {
|
||||
if !text_highlights.is_empty() {
|
||||
while transform_cursor.start().0 < range.end {
|
||||
if !transform_cursor.item().unwrap().is_fold() {
|
||||
let transform_start = self
|
||||
.inlay_snapshot
|
||||
.buffer
|
||||
.anchor_after(cmp::max(buffer_start, transform_cursor.start().1));
|
||||
let transform_start = self.inlay_snapshot.buffer.anchor_after(
|
||||
self.inlay_snapshot.to_buffer_offset(cmp::max(
|
||||
inlay_start,
|
||||
transform_cursor.start().1,
|
||||
)),
|
||||
);
|
||||
|
||||
let transform_end = {
|
||||
let overshoot = range.end.0 - transform_cursor.start().0 .0;
|
||||
self.inlay_snapshot.buffer.anchor_before(cmp::min(
|
||||
transform_cursor.end(&()).1,
|
||||
transform_cursor.start().1 + overshoot,
|
||||
))
|
||||
let overshoot =
|
||||
InlayOffset(range.end.0 - transform_cursor.start().0 .0);
|
||||
self.inlay_snapshot.buffer.anchor_before(
|
||||
self.inlay_snapshot.to_buffer_offset(cmp::min(
|
||||
transform_cursor.end(&()).1,
|
||||
transform_cursor.start().1 + overshoot,
|
||||
)),
|
||||
)
|
||||
};
|
||||
|
||||
for (tag, highlights) in text_highlights.iter() {
|
||||
|
@ -743,13 +710,17 @@ impl FoldSnapshot {
|
|||
}
|
||||
|
||||
highlight_endpoints.push(HighlightEndpoint {
|
||||
offset: range.start.to_offset(&self.inlay_snapshot.buffer),
|
||||
offset: self.inlay_snapshot.to_inlay_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.inlay_snapshot.buffer),
|
||||
offset: self.inlay_snapshot.to_inlay_offset(
|
||||
range.end.to_offset(&self.inlay_snapshot.buffer),
|
||||
),
|
||||
is_start: false,
|
||||
tag: *tag,
|
||||
style,
|
||||
|
@ -767,12 +738,13 @@ impl FoldSnapshot {
|
|||
|
||||
FoldChunks {
|
||||
transform_cursor,
|
||||
buffer_chunks: self
|
||||
.inlay_snapshot
|
||||
.buffer
|
||||
.chunks(buffer_start..buffer_end, language_aware),
|
||||
inlay_chunks: self.inlay_snapshot.chunks(
|
||||
inlay_start..inlay_end,
|
||||
language_aware,
|
||||
inlay_highlights,
|
||||
),
|
||||
inlay_chunk: None,
|
||||
buffer_offset: buffer_start,
|
||||
inlay_offset: inlay_start,
|
||||
output_offset: range.start.0,
|
||||
max_output_offset: range.end.0,
|
||||
highlight_endpoints: highlight_endpoints.into_iter().peekable(),
|
||||
|
@ -788,33 +760,15 @@ impl FoldSnapshot {
|
|||
|
||||
#[cfg(test)]
|
||||
pub fn clip_offset(&self, offset: FoldOffset, bias: Bias) -> FoldOffset {
|
||||
let mut cursor = self.transforms.cursor::<(FoldOffset, usize)>();
|
||||
cursor.seek(&offset, Bias::Right, &());
|
||||
if let Some(transform) = cursor.item() {
|
||||
let transform_start = cursor.start().0 .0;
|
||||
if transform.output_text.is_some() {
|
||||
if offset.0 == transform_start || matches!(bias, Bias::Left) {
|
||||
FoldOffset(transform_start)
|
||||
} else {
|
||||
FoldOffset(cursor.end(&()).0 .0)
|
||||
}
|
||||
} else {
|
||||
let overshoot = offset.0 - transform_start;
|
||||
let buffer_offset = cursor.start().1 + overshoot;
|
||||
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,
|
||||
)
|
||||
}
|
||||
if offset > self.len() {
|
||||
self.len()
|
||||
} else {
|
||||
FoldOffset(self.transforms.summary().output.len)
|
||||
self.clip_point(offset.to_point(self), bias).to_offset(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clip_point(&self, point: FoldPoint, bias: Bias) -> FoldPoint {
|
||||
let mut cursor = self.transforms.cursor::<(FoldPoint, Point)>();
|
||||
let mut cursor = self.transforms.cursor::<(FoldPoint, InlayPoint)>();
|
||||
cursor.seek(&point, Bias::Right, &());
|
||||
if let Some(transform) = cursor.item() {
|
||||
let transform_start = cursor.start().0 .0;
|
||||
|
@ -825,11 +779,10 @@ impl FoldSnapshot {
|
|||
FoldPoint(cursor.end(&()).0 .0)
|
||||
}
|
||||
} else {
|
||||
let overshoot = point.0 - transform_start;
|
||||
let buffer_position = cursor.start().1 + overshoot;
|
||||
let clipped_buffer_position =
|
||||
self.inlay_snapshot.buffer.clip_point(buffer_position, bias);
|
||||
FoldPoint(cursor.start().0 .0 + (clipped_buffer_position - cursor.start().1))
|
||||
let overshoot = InlayPoint(point.0 - transform_start);
|
||||
let inlay_point = cursor.start().1 + overshoot;
|
||||
let clipped_inlay_point = self.inlay_snapshot.clip_point(inlay_point, bias);
|
||||
FoldPoint(cursor.start().0 .0 + (clipped_inlay_point - cursor.start().1).0)
|
||||
}
|
||||
} else {
|
||||
FoldPoint(self.transforms.summary().output.lines)
|
||||
|
@ -1067,10 +1020,10 @@ impl<'a> Iterator for FoldBufferRows<'a> {
|
|||
}
|
||||
|
||||
pub struct FoldChunks<'a> {
|
||||
transform_cursor: Cursor<'a, Transform, (FoldOffset, usize)>,
|
||||
buffer_chunks: MultiBufferChunks<'a>,
|
||||
inlay_chunk: Option<(usize, Chunk<'a>)>,
|
||||
buffer_offset: usize,
|
||||
transform_cursor: Cursor<'a, Transform, (FoldOffset, InlayOffset)>,
|
||||
inlay_chunks: InlayChunks<'a>,
|
||||
inlay_chunk: Option<(InlayOffset, Chunk<'a>)>,
|
||||
inlay_offset: InlayOffset,
|
||||
output_offset: usize,
|
||||
max_output_offset: usize,
|
||||
highlight_endpoints: Peekable<vec::IntoIter<HighlightEndpoint>>,
|
||||
|
@ -1092,10 +1045,10 @@ impl<'a> Iterator for FoldChunks<'a> {
|
|||
// advance the transform and buffer cursors to the end of the fold.
|
||||
if let Some(output_text) = transform.output_text {
|
||||
self.inlay_chunk.take();
|
||||
self.buffer_offset += transform.summary.input.len;
|
||||
self.buffer_chunks.seek(self.buffer_offset);
|
||||
self.inlay_offset += InlayOffset(transform.summary.input.len);
|
||||
self.inlay_chunks.seek(self.inlay_offset);
|
||||
|
||||
while self.buffer_offset >= self.transform_cursor.end(&()).1
|
||||
while self.inlay_offset >= self.transform_cursor.end(&()).1
|
||||
&& self.transform_cursor.item().is_some()
|
||||
{
|
||||
self.transform_cursor.next(&());
|
||||
|
@ -1112,9 +1065,9 @@ impl<'a> Iterator for FoldChunks<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
let mut next_highlight_endpoint = usize::MAX;
|
||||
let mut next_highlight_endpoint = InlayOffset(usize::MAX);
|
||||
while let Some(endpoint) = self.highlight_endpoints.peek().copied() {
|
||||
if endpoint.offset <= self.buffer_offset {
|
||||
if endpoint.offset <= self.inlay_offset {
|
||||
if endpoint.is_start {
|
||||
self.active_highlights.insert(endpoint.tag, endpoint.style);
|
||||
} else {
|
||||
|
@ -1129,20 +1082,20 @@ impl<'a> Iterator for FoldChunks<'a> {
|
|||
|
||||
// Retrieve a chunk from the current location in the buffer.
|
||||
if self.inlay_chunk.is_none() {
|
||||
let chunk_offset = self.buffer_chunks.offset();
|
||||
self.inlay_chunk = self.buffer_chunks.next().map(|chunk| (chunk_offset, chunk));
|
||||
let chunk_offset = self.inlay_chunks.offset();
|
||||
self.inlay_chunk = self.inlay_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.inlay_chunk {
|
||||
let buffer_chunk_end = buffer_chunk_start + chunk.text.len();
|
||||
let buffer_chunk_end = buffer_chunk_start + InlayOffset(chunk.text.len());
|
||||
let transform_end = self.transform_cursor.end(&()).1;
|
||||
let chunk_end = buffer_chunk_end
|
||||
.min(transform_end)
|
||||
.min(next_highlight_endpoint);
|
||||
|
||||
chunk.text = &chunk.text
|
||||
[self.buffer_offset - buffer_chunk_start..chunk_end - buffer_chunk_start];
|
||||
[(self.inlay_offset - buffer_chunk_start).0..(chunk_end - buffer_chunk_start).0];
|
||||
|
||||
if !self.active_highlights.is_empty() {
|
||||
let mut highlight_style = HighlightStyle::default();
|
||||
|
@ -1158,7 +1111,7 @@ impl<'a> Iterator for FoldChunks<'a> {
|
|||
self.inlay_chunk.take();
|
||||
}
|
||||
|
||||
self.buffer_offset = chunk_end;
|
||||
self.inlay_offset = chunk_end;
|
||||
self.output_offset += chunk.text.len();
|
||||
return Some(chunk);
|
||||
}
|
||||
|
@ -1169,7 +1122,7 @@ impl<'a> Iterator for FoldChunks<'a> {
|
|||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
struct HighlightEndpoint {
|
||||
offset: usize,
|
||||
offset: InlayOffset,
|
||||
is_start: bool,
|
||||
tag: Option<TypeId>,
|
||||
style: HighlightStyle,
|
||||
|
@ -1667,6 +1620,7 @@ mod tests {
|
|||
buffer_snapshot.clip_offset(rng.gen_range(0..=buffer_snapshot.len()), Right);
|
||||
let start = buffer_snapshot.clip_offset(rng.gen_range(0..=end), Left);
|
||||
let expected_folds = map
|
||||
.snapshot
|
||||
.folds
|
||||
.items(&buffer_snapshot)
|
||||
.into_iter()
|
||||
|
@ -1754,9 +1708,9 @@ mod tests {
|
|||
|
||||
impl FoldMap {
|
||||
fn merged_fold_ranges(&self) -> Vec<Range<usize>> {
|
||||
let inlay_snapshot = self.inlay_snapshot.lock().clone();
|
||||
let inlay_snapshot = self.snapshot.inlay_snapshot.clone();
|
||||
let buffer = &inlay_snapshot.buffer;
|
||||
let mut folds = self.folds.items(buffer);
|
||||
let mut folds = self.snapshot.folds.items(buffer);
|
||||
// Ensure sorting doesn't change how folds get merged and displayed.
|
||||
folds.sort_by(|a, b| a.0.cmp(&b.0, buffer));
|
||||
let mut fold_ranges = folds
|
||||
|
@ -1789,8 +1743,8 @@ mod tests {
|
|||
) -> Vec<(FoldSnapshot, Vec<FoldEdit>)> {
|
||||
let mut snapshot_edits = Vec::new();
|
||||
match rng.gen_range(0..=100) {
|
||||
0..=39 if !self.folds.is_empty() => {
|
||||
let inlay_snapshot = self.inlay_snapshot.lock().clone();
|
||||
0..=39 if !self.snapshot.folds.is_empty() => {
|
||||
let inlay_snapshot = self.snapshot.inlay_snapshot.clone();
|
||||
let buffer = &inlay_snapshot.buffer;
|
||||
let mut to_unfold = Vec::new();
|
||||
for _ in 0..rng.gen_range(1..=3) {
|
||||
|
@ -1805,7 +1759,7 @@ mod tests {
|
|||
snapshot_edits.push((snapshot, edits));
|
||||
}
|
||||
_ => {
|
||||
let inlay_snapshot = self.inlay_snapshot.lock().clone();
|
||||
let inlay_snapshot = self.snapshot.inlay_snapshot.clone();
|
||||
let buffer = &inlay_snapshot.buffer;
|
||||
let mut to_fold = Vec::new();
|
||||
for _ in 0..rng.gen_range(1..=2) {
|
||||
|
|
|
@ -108,6 +108,22 @@ impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayOffset {
|
|||
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
|
||||
pub struct InlayPoint(pub Point);
|
||||
|
||||
impl Add for InlayPoint {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self(self.0 + rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for InlayPoint {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self(self.0 - rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayPoint {
|
||||
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
|
||||
self.0 += &summary.output.lines;
|
||||
|
@ -142,6 +158,23 @@ pub struct InlayChunks<'a> {
|
|||
output_offset: InlayOffset,
|
||||
max_output_offset: InlayOffset,
|
||||
highlight_style: Option<HighlightStyle>,
|
||||
snapshot: &'a InlaySnapshot,
|
||||
}
|
||||
|
||||
impl<'a> InlayChunks<'a> {
|
||||
pub fn seek(&mut self, offset: InlayOffset) {
|
||||
self.transforms.seek(&offset, Bias::Right, &());
|
||||
|
||||
let buffer_offset = self.snapshot.to_buffer_offset(offset);
|
||||
self.buffer_chunks.seek(buffer_offset);
|
||||
self.inlay_chunks = None;
|
||||
self.buffer_chunk = None;
|
||||
self.output_offset = offset;
|
||||
}
|
||||
|
||||
pub fn offset(&self) -> InlayOffset {
|
||||
self.output_offset
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for InlayChunks<'a> {
|
||||
|
@ -470,7 +503,7 @@ impl InlayMap {
|
|||
|
||||
let mut to_remove = Vec::new();
|
||||
let mut to_insert = Vec::new();
|
||||
let mut snapshot = self.snapshot.lock();
|
||||
let snapshot = self.snapshot.lock();
|
||||
for _ in 0..rng.gen_range(1..=5) {
|
||||
if self.inlays.is_empty() || rng.gen() {
|
||||
let position = snapshot.buffer.random_byte_range(0, rng).start;
|
||||
|
@ -768,6 +801,7 @@ impl InlaySnapshot {
|
|||
output_offset: range.start,
|
||||
max_output_offset: range.end,
|
||||
highlight_style: inlay_highlight_style,
|
||||
snapshot: self,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1079,7 +1113,7 @@ mod tests {
|
|||
);
|
||||
|
||||
assert_eq!(
|
||||
inlay_snapshot.text_summary_for_range(start..end),
|
||||
inlay_snapshot.text_summary_for_range(InlayOffset(start)..InlayOffset(end)),
|
||||
expected_text.slice(start..end).summary()
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue