mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-30 21:16:23 +00:00
Implement chunks of the InlayMap
Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
This commit is contained in:
parent
3028767d12
commit
5ad85b44d6
2 changed files with 112 additions and 16 deletions
|
@ -2,7 +2,7 @@
|
|||
// TODO kb
|
||||
|
||||
use std::{
|
||||
cmp::Reverse,
|
||||
cmp::{self, Reverse},
|
||||
ops::{Add, AddAssign, Range, Sub},
|
||||
sync::atomic::{self, AtomicUsize},
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ use language::{Chunk, Edit, Point, Rope, TextSummary};
|
|||
use parking_lot::Mutex;
|
||||
use project::InlayHint;
|
||||
use rand::Rng;
|
||||
use sum_tree::{Bias, SumTree};
|
||||
use sum_tree::{Bias, Cursor, SumTree};
|
||||
use util::post_inc;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
|
@ -42,7 +42,7 @@ pub struct InlaySnapshot {
|
|||
pub version: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
enum Transform {
|
||||
Isomorphic(TextSummary),
|
||||
Inlay(Inlay),
|
||||
|
@ -107,6 +107,18 @@ impl AddAssign for InlayOffset {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayOffset {
|
||||
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) {
|
||||
self.0 += &summary.output.len;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> sum_tree::Dimension<'a, TransformSummary> for SuggestionOffset {
|
||||
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);
|
||||
|
||||
|
@ -128,7 +140,12 @@ pub struct InlayBufferRows<'a> {
|
|||
}
|
||||
|
||||
pub struct InlayChunks<'a> {
|
||||
transforms: Cursor<'a, Transform, (InlayOffset, SuggestionOffset)>,
|
||||
suggestion_chunks: SuggestionChunks<'a>,
|
||||
suggestion_chunk: Option<Chunk<'a>>,
|
||||
inlay_chunks: Option<text::Chunks<'a>>,
|
||||
output_offset: InlayOffset,
|
||||
max_output_offset: InlayOffset,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -147,7 +164,49 @@ impl<'a> Iterator for InlayChunks<'a> {
|
|||
type Item = Chunk<'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.suggestion_chunks.next()
|
||||
if self.output_offset == self.max_output_offset {
|
||||
return None;
|
||||
}
|
||||
|
||||
let chunk = match self.transforms.item()? {
|
||||
Transform::Isomorphic(transform) => {
|
||||
let chunk = self
|
||||
.suggestion_chunk
|
||||
.get_or_insert_with(|| self.suggestion_chunks.next().unwrap());
|
||||
if chunk.text.is_empty() {
|
||||
*chunk = self.suggestion_chunks.next().unwrap();
|
||||
}
|
||||
|
||||
let (prefix, suffix) = chunk.text.split_at(transform.len);
|
||||
chunk.text = suffix;
|
||||
self.output_offset.0 += prefix.len();
|
||||
Chunk {
|
||||
text: prefix,
|
||||
..chunk.clone()
|
||||
}
|
||||
}
|
||||
Transform::Inlay(inlay) => {
|
||||
let inlay_chunks = self.inlay_chunks.get_or_insert_with(|| {
|
||||
let start = self.output_offset - self.transforms.start().0;
|
||||
let end = cmp::min(self.max_output_offset, self.transforms.end(&()).0)
|
||||
- self.transforms.start().0;
|
||||
inlay.properties.text.chunks_in_range(start.0..end.0)
|
||||
});
|
||||
|
||||
let chunk = inlay_chunks.next().unwrap();
|
||||
self.output_offset.0 += chunk.len();
|
||||
Chunk {
|
||||
text: chunk,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if self.output_offset == self.transforms.end(&()).0 {
|
||||
self.transforms.next(&());
|
||||
}
|
||||
|
||||
Some(chunk)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +237,10 @@ impl InlayMap {
|
|||
let snapshot = InlaySnapshot {
|
||||
suggestion_snapshot: suggestion_snapshot.clone(),
|
||||
version: 0,
|
||||
transforms: SumTree::new(),
|
||||
transforms: SumTree::from_item(
|
||||
Transform::Isomorphic(suggestion_snapshot.text_summary()),
|
||||
&(),
|
||||
),
|
||||
};
|
||||
|
||||
(
|
||||
|
@ -348,9 +410,12 @@ impl InlaySnapshot {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn len(&self) -> InlayOffset {
|
||||
InlayOffset(self.transforms.summary().output.len)
|
||||
}
|
||||
|
||||
pub fn max_point(&self) -> InlayPoint {
|
||||
// TODO kb copied from suggestion_map
|
||||
self.to_inlay_point(self.suggestion_snapshot.max_point())
|
||||
InlayPoint(self.transforms.summary().output.lines)
|
||||
}
|
||||
|
||||
pub fn to_offset(&self, point: InlayPoint) -> InlayOffset {
|
||||
|
@ -372,6 +437,19 @@ impl InlaySnapshot {
|
|||
SuggestionPoint(point.0)
|
||||
}
|
||||
|
||||
pub fn to_suggestion_offset(&self, offset: InlayOffset) -> SuggestionOffset {
|
||||
let mut cursor = self.transforms.cursor::<(InlayOffset, SuggestionOffset)>();
|
||||
cursor.seek(&offset, Bias::Right, &());
|
||||
match cursor.item() {
|
||||
Some(Transform::Isomorphic(transform)) => {
|
||||
let overshoot = offset - cursor.start().0;
|
||||
cursor.start().1 + SuggestionOffset(overshoot.0)
|
||||
}
|
||||
Some(Transform::Inlay(inlay)) => cursor.start().1,
|
||||
None => self.suggestion_snapshot.len(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_inlay_point(&self, point: SuggestionPoint) -> InlayPoint {
|
||||
InlayPoint(point.0)
|
||||
}
|
||||
|
@ -410,21 +488,35 @@ impl InlaySnapshot {
|
|||
text_highlights: Option<&'a TextHighlights>,
|
||||
suggestion_highlight: Option<HighlightStyle>,
|
||||
) -> InlayChunks<'a> {
|
||||
// TODO kb copied from suggestion_map
|
||||
dbg!(self.transforms.items(&()));
|
||||
|
||||
let mut cursor = self.transforms.cursor::<(InlayOffset, SuggestionOffset)>();
|
||||
cursor.seek(&range.start, Bias::Right, &());
|
||||
|
||||
let suggestion_range =
|
||||
self.to_suggestion_offset(range.start)..self.to_suggestion_offset(range.end);
|
||||
let suggestion_chunks = self.suggestion_snapshot.chunks(
|
||||
suggestion_range,
|
||||
language_aware,
|
||||
text_highlights,
|
||||
suggestion_highlight,
|
||||
);
|
||||
|
||||
InlayChunks {
|
||||
suggestion_chunks: self.suggestion_snapshot.chunks(
|
||||
SuggestionOffset(range.start.0)..SuggestionOffset(range.end.0),
|
||||
language_aware,
|
||||
text_highlights,
|
||||
suggestion_highlight,
|
||||
),
|
||||
transforms: cursor,
|
||||
suggestion_chunks,
|
||||
inlay_chunks: None,
|
||||
suggestion_chunk: None,
|
||||
output_offset: range.start,
|
||||
max_output_offset: range.end,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn text(&self) -> String {
|
||||
// TODO kb copied from suggestion_map
|
||||
self.suggestion_snapshot.text()
|
||||
self.chunks(Default::default()..self.len(), false, None, None)
|
||||
.map(|chunk| chunk.text)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -358,6 +358,10 @@ impl SuggestionSnapshot {
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue