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