Move InlayId generation back to InlayCache
This commit is contained in:
parent
e82b4d8957
commit
8c03e9e122
7 changed files with 147 additions and 133 deletions
|
@ -4,7 +4,7 @@ mod inlay_map;
|
||||||
mod tab_map;
|
mod tab_map;
|
||||||
mod wrap_map;
|
mod wrap_map;
|
||||||
|
|
||||||
use crate::{Anchor, AnchorRangeExt, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint};
|
use crate::{Anchor, AnchorRangeExt, InlayId, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint};
|
||||||
pub use block_map::{BlockMap, BlockPoint};
|
pub use block_map::{BlockMap, BlockPoint};
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
use fold_map::FoldMap;
|
use fold_map::FoldMap;
|
||||||
|
@ -28,7 +28,7 @@ pub use block_map::{
|
||||||
BlockDisposition, BlockId, BlockProperties, BlockStyle, RenderBlock, TransformBlock,
|
BlockDisposition, BlockId, BlockProperties, BlockStyle, RenderBlock, TransformBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use self::inlay_map::{Inlay, InlayId, InlayProperties};
|
pub use self::inlay_map::{Inlay, InlayProperties};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum FoldStatus {
|
pub enum FoldStatus {
|
||||||
|
@ -249,11 +249,11 @@ impl DisplayMap {
|
||||||
pub fn splice_inlays<T: Into<Rope>>(
|
pub fn splice_inlays<T: Into<Rope>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
to_remove: Vec<InlayId>,
|
to_remove: Vec<InlayId>,
|
||||||
to_insert: Vec<(Option<InlayId>, InlayProperties<T>)>,
|
to_insert: Vec<(InlayId, InlayProperties<T>)>,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> Vec<InlayId> {
|
) {
|
||||||
if to_remove.is_empty() && to_insert.is_empty() {
|
if to_remove.is_empty() && to_insert.is_empty() {
|
||||||
return Vec::new();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let buffer_snapshot = self.buffer.read(cx).snapshot(cx);
|
let buffer_snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
|
@ -267,14 +267,13 @@ impl DisplayMap {
|
||||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||||
self.block_map.read(snapshot, edits);
|
self.block_map.read(snapshot, edits);
|
||||||
|
|
||||||
let (snapshot, edits, new_inlay_ids) = self.inlay_map.splice(to_remove, to_insert);
|
let (snapshot, edits) = self.inlay_map.splice(to_remove, to_insert);
|
||||||
let (snapshot, edits) = self.fold_map.read(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.tab_map.sync(snapshot, edits, tab_size);
|
||||||
let (snapshot, edits) = self
|
let (snapshot, edits) = self
|
||||||
.wrap_map
|
.wrap_map
|
||||||
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
.update(cx, |map, cx| map.sync(snapshot, edits, cx));
|
||||||
self.block_map.read(snapshot, edits);
|
self.block_map.read(snapshot, edits);
|
||||||
new_inlay_ids
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tab_size(buffer: &ModelHandle<MultiBuffer>, cx: &mut ModelContext<Self>) -> NonZeroU32 {
|
fn tab_size(buffer: &ModelHandle<MultiBuffer>, cx: &mut ModelContext<Self>) -> NonZeroU32 {
|
||||||
|
|
|
@ -1475,6 +1475,7 @@ mod tests {
|
||||||
Arc::new((HighlightStyle::default(), highlight_ranges)),
|
Arc::new((HighlightStyle::default(), highlight_ranges)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut next_inlay_id = 0;
|
||||||
for _ in 0..operations {
|
for _ in 0..operations {
|
||||||
log::info!("text: {:?}", buffer_snapshot.text());
|
log::info!("text: {:?}", buffer_snapshot.text());
|
||||||
let mut buffer_edits = Vec::new();
|
let mut buffer_edits = Vec::new();
|
||||||
|
@ -1484,7 +1485,7 @@ mod tests {
|
||||||
snapshot_edits.extend(map.randomly_mutate(&mut rng));
|
snapshot_edits.extend(map.randomly_mutate(&mut rng));
|
||||||
}
|
}
|
||||||
40..=59 => {
|
40..=59 => {
|
||||||
let (_, edits) = inlay_map.randomly_mutate(&mut rng);
|
let (_, edits) = inlay_map.randomly_mutate(&mut next_inlay_id, &mut rng);
|
||||||
inlay_edits = edits;
|
inlay_edits = edits;
|
||||||
}
|
}
|
||||||
_ => buffer.update(cx, |buffer, cx| {
|
_ => buffer.update(cx, |buffer, cx| {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
multi_buffer::{MultiBufferChunks, MultiBufferRows},
|
multi_buffer::{MultiBufferChunks, MultiBufferRows},
|
||||||
Anchor, MultiBufferSnapshot, ToOffset,
|
Anchor, InlayId, MultiBufferSnapshot, ToOffset,
|
||||||
};
|
};
|
||||||
use collections::{BTreeSet, HashMap};
|
use collections::{BTreeSet, HashMap};
|
||||||
use gpui::fonts::HighlightStyle;
|
use gpui::fonts::HighlightStyle;
|
||||||
|
@ -12,13 +12,11 @@ use std::{
|
||||||
};
|
};
|
||||||
use sum_tree::{Bias, Cursor, SumTree};
|
use sum_tree::{Bias, Cursor, SumTree};
|
||||||
use text::Patch;
|
use text::Patch;
|
||||||
use util::post_inc;
|
|
||||||
|
|
||||||
pub struct InlayMap {
|
pub struct InlayMap {
|
||||||
snapshot: Mutex<InlaySnapshot>,
|
snapshot: Mutex<InlaySnapshot>,
|
||||||
inlays_by_id: HashMap<InlayId, Inlay>,
|
inlays_by_id: HashMap<InlayId, Inlay>,
|
||||||
inlays: Vec<Inlay>,
|
inlays: Vec<Inlay>,
|
||||||
next_inlay_id: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -34,9 +32,6 @@ enum Transform {
|
||||||
Inlay(Inlay),
|
Inlay(Inlay),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
pub struct InlayId(usize);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Inlay {
|
pub struct Inlay {
|
||||||
pub id: InlayId,
|
pub id: InlayId,
|
||||||
|
@ -316,7 +311,6 @@ impl InlayMap {
|
||||||
snapshot: Mutex::new(snapshot.clone()),
|
snapshot: Mutex::new(snapshot.clone()),
|
||||||
inlays_by_id: HashMap::default(),
|
inlays_by_id: HashMap::default(),
|
||||||
inlays: Vec::new(),
|
inlays: Vec::new(),
|
||||||
next_inlay_id: 0,
|
|
||||||
},
|
},
|
||||||
snapshot,
|
snapshot,
|
||||||
)
|
)
|
||||||
|
@ -461,8 +455,8 @@ impl InlayMap {
|
||||||
pub fn splice<T: Into<Rope>>(
|
pub fn splice<T: Into<Rope>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
to_remove: Vec<InlayId>,
|
to_remove: Vec<InlayId>,
|
||||||
to_insert: Vec<(Option<InlayId>, InlayProperties<T>)>,
|
to_insert: Vec<(InlayId, InlayProperties<T>)>,
|
||||||
) -> (InlaySnapshot, Vec<InlayEdit>, Vec<InlayId>) {
|
) -> (InlaySnapshot, Vec<InlayEdit>) {
|
||||||
let snapshot = self.snapshot.lock();
|
let snapshot = self.snapshot.lock();
|
||||||
let mut edits = BTreeSet::new();
|
let mut edits = BTreeSet::new();
|
||||||
|
|
||||||
|
@ -474,16 +468,12 @@ impl InlayMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut new_inlay_ids = Vec::with_capacity(to_insert.len());
|
|
||||||
for (existing_id, properties) in to_insert {
|
for (existing_id, properties) in to_insert {
|
||||||
let inlay = Inlay {
|
let inlay = Inlay {
|
||||||
id: existing_id.unwrap_or_else(|| InlayId(post_inc(&mut self.next_inlay_id))),
|
id: existing_id,
|
||||||
position: properties.position,
|
position: properties.position,
|
||||||
text: properties.text.into(),
|
text: properties.text.into(),
|
||||||
};
|
};
|
||||||
if existing_id.is_none() {
|
|
||||||
new_inlay_ids.push(inlay.id);
|
|
||||||
}
|
|
||||||
self.inlays_by_id.insert(inlay.id, inlay.clone());
|
self.inlays_by_id.insert(inlay.id, inlay.clone());
|
||||||
match self
|
match self
|
||||||
.inlays
|
.inlays
|
||||||
|
@ -508,7 +498,7 @@ impl InlayMap {
|
||||||
let buffer_snapshot = snapshot.buffer.clone();
|
let buffer_snapshot = snapshot.buffer.clone();
|
||||||
drop(snapshot);
|
drop(snapshot);
|
||||||
let (snapshot, edits) = self.sync(buffer_snapshot, buffer_edits);
|
let (snapshot, edits) = self.sync(buffer_snapshot, buffer_edits);
|
||||||
(snapshot, edits, new_inlay_ids)
|
(snapshot, edits)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_inlays(&self) -> impl Iterator<Item = &Inlay> {
|
pub fn current_inlays(&self) -> impl Iterator<Item = &Inlay> {
|
||||||
|
@ -518,9 +508,11 @@ impl InlayMap {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn randomly_mutate(
|
pub(crate) fn randomly_mutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
next_inlay_id: &mut usize,
|
||||||
rng: &mut rand::rngs::StdRng,
|
rng: &mut rand::rngs::StdRng,
|
||||||
) -> (InlaySnapshot, Vec<InlayEdit>) {
|
) -> (InlaySnapshot, Vec<InlayEdit>) {
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
use util::post_inc;
|
||||||
|
|
||||||
let mut to_remove = Vec::new();
|
let mut to_remove = Vec::new();
|
||||||
let mut to_insert = Vec::new();
|
let mut to_insert = Vec::new();
|
||||||
|
@ -541,7 +533,7 @@ impl InlayMap {
|
||||||
text
|
text
|
||||||
);
|
);
|
||||||
to_insert.push((
|
to_insert.push((
|
||||||
None,
|
InlayId(post_inc(next_inlay_id)),
|
||||||
InlayProperties {
|
InlayProperties {
|
||||||
position: snapshot.buffer.anchor_at(position, bias),
|
position: snapshot.buffer.anchor_at(position, bias),
|
||||||
text,
|
text,
|
||||||
|
@ -554,7 +546,7 @@ impl InlayMap {
|
||||||
log::info!("removing inlays: {:?}", to_remove);
|
log::info!("removing inlays: {:?}", to_remove);
|
||||||
|
|
||||||
drop(snapshot);
|
drop(snapshot);
|
||||||
let (snapshot, edits, _) = self.splice(to_remove, to_insert);
|
let (snapshot, edits) = self.splice(to_remove, to_insert);
|
||||||
(snapshot, edits)
|
(snapshot, edits)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -860,12 +852,13 @@ fn push_isomorphic(sum_tree: &mut SumTree<Transform>, summary: TextSummary) {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::MultiBuffer;
|
use crate::{InlayId, MultiBuffer};
|
||||||
use gpui::AppContext;
|
use gpui::AppContext;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use settings::SettingsStore;
|
use settings::SettingsStore;
|
||||||
use std::env;
|
use std::env;
|
||||||
use text::Patch;
|
use text::Patch;
|
||||||
|
use util::post_inc;
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_basic_inlays(cx: &mut AppContext) {
|
fn test_basic_inlays(cx: &mut AppContext) {
|
||||||
|
@ -873,11 +866,12 @@ mod tests {
|
||||||
let buffer_edits = buffer.update(cx, |buffer, _| buffer.subscribe());
|
let buffer_edits = buffer.update(cx, |buffer, _| buffer.subscribe());
|
||||||
let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer.read(cx).snapshot(cx));
|
let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer.read(cx).snapshot(cx));
|
||||||
assert_eq!(inlay_snapshot.text(), "abcdefghi");
|
assert_eq!(inlay_snapshot.text(), "abcdefghi");
|
||||||
|
let mut next_inlay_id = 0;
|
||||||
|
|
||||||
let (inlay_snapshot, _, _) = inlay_map.splice(
|
let (inlay_snapshot, _) = inlay_map.splice(
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
vec![(
|
vec![(
|
||||||
None,
|
InlayId(post_inc(&mut next_inlay_id)),
|
||||||
InlayProperties {
|
InlayProperties {
|
||||||
position: buffer.read(cx).snapshot(cx).anchor_after(3),
|
position: buffer.read(cx).snapshot(cx).anchor_after(3),
|
||||||
text: "|123|",
|
text: "|123|",
|
||||||
|
@ -952,18 +946,18 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(inlay_snapshot.text(), "abxyDzefghi");
|
assert_eq!(inlay_snapshot.text(), "abxyDzefghi");
|
||||||
|
|
||||||
let (inlay_snapshot, _, _) = inlay_map.splice(
|
let (inlay_snapshot, _) = inlay_map.splice(
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
None,
|
InlayId(post_inc(&mut next_inlay_id)),
|
||||||
InlayProperties {
|
InlayProperties {
|
||||||
position: buffer.read(cx).snapshot(cx).anchor_before(3),
|
position: buffer.read(cx).snapshot(cx).anchor_before(3),
|
||||||
text: "|123|",
|
text: "|123|",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
None,
|
InlayId(post_inc(&mut next_inlay_id)),
|
||||||
InlayProperties {
|
InlayProperties {
|
||||||
position: buffer.read(cx).snapshot(cx).anchor_after(3),
|
position: buffer.read(cx).snapshot(cx).anchor_after(3),
|
||||||
text: "|456|",
|
text: "|456|",
|
||||||
|
@ -982,7 +976,7 @@ mod tests {
|
||||||
assert_eq!(inlay_snapshot.text(), "abx|123|JKL|456|yDzefghi");
|
assert_eq!(inlay_snapshot.text(), "abx|123|JKL|456|yDzefghi");
|
||||||
|
|
||||||
// The inlays can be manually removed.
|
// The inlays can be manually removed.
|
||||||
let (inlay_snapshot, _, _) = inlay_map
|
let (inlay_snapshot, _) = inlay_map
|
||||||
.splice::<String>(inlay_map.inlays_by_id.keys().copied().collect(), Vec::new());
|
.splice::<String>(inlay_map.inlays_by_id.keys().copied().collect(), Vec::new());
|
||||||
assert_eq!(inlay_snapshot.text(), "abxJKLyDzefghi");
|
assert_eq!(inlay_snapshot.text(), "abxJKLyDzefghi");
|
||||||
}
|
}
|
||||||
|
@ -992,26 +986,27 @@ mod tests {
|
||||||
let buffer = MultiBuffer::build_simple("abc\ndef\nghi", cx);
|
let buffer = MultiBuffer::build_simple("abc\ndef\nghi", cx);
|
||||||
let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer.read(cx).snapshot(cx));
|
let (mut inlay_map, inlay_snapshot) = InlayMap::new(buffer.read(cx).snapshot(cx));
|
||||||
assert_eq!(inlay_snapshot.text(), "abc\ndef\nghi");
|
assert_eq!(inlay_snapshot.text(), "abc\ndef\nghi");
|
||||||
|
let mut next_inlay_id = 0;
|
||||||
|
|
||||||
let (inlay_snapshot, _, _) = inlay_map.splice(
|
let (inlay_snapshot, _) = inlay_map.splice(
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
None,
|
InlayId(post_inc(&mut next_inlay_id)),
|
||||||
InlayProperties {
|
InlayProperties {
|
||||||
position: buffer.read(cx).snapshot(cx).anchor_before(0),
|
position: buffer.read(cx).snapshot(cx).anchor_before(0),
|
||||||
text: "|123|\n",
|
text: "|123|\n",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
None,
|
InlayId(post_inc(&mut next_inlay_id)),
|
||||||
InlayProperties {
|
InlayProperties {
|
||||||
position: buffer.read(cx).snapshot(cx).anchor_before(4),
|
position: buffer.read(cx).snapshot(cx).anchor_before(4),
|
||||||
text: "|456|",
|
text: "|456|",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
None,
|
InlayId(post_inc(&mut next_inlay_id)),
|
||||||
InlayProperties {
|
InlayProperties {
|
||||||
position: buffer.read(cx).snapshot(cx).anchor_before(7),
|
position: buffer.read(cx).snapshot(cx).anchor_before(7),
|
||||||
text: "\n|567|\n",
|
text: "\n|567|\n",
|
||||||
|
@ -1044,6 +1039,7 @@ mod tests {
|
||||||
MultiBuffer::build_random(&mut rng, cx)
|
MultiBuffer::build_random(&mut rng, cx)
|
||||||
};
|
};
|
||||||
let mut buffer_snapshot = buffer.read(cx).snapshot(cx);
|
let mut buffer_snapshot = buffer.read(cx).snapshot(cx);
|
||||||
|
let mut next_inlay_id = 0;
|
||||||
log::info!("buffer text: {:?}", buffer_snapshot.text());
|
log::info!("buffer text: {:?}", buffer_snapshot.text());
|
||||||
|
|
||||||
let (mut inlay_map, mut inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
|
let (mut inlay_map, mut inlay_snapshot) = InlayMap::new(buffer_snapshot.clone());
|
||||||
|
@ -1054,7 +1050,7 @@ mod tests {
|
||||||
let mut buffer_edits = Vec::new();
|
let mut buffer_edits = Vec::new();
|
||||||
match rng.gen_range(0..=100) {
|
match rng.gen_range(0..=100) {
|
||||||
0..=50 => {
|
0..=50 => {
|
||||||
let (snapshot, edits) = inlay_map.randomly_mutate(&mut rng);
|
let (snapshot, edits) = inlay_map.randomly_mutate(&mut next_inlay_id, &mut rng);
|
||||||
log::info!("mutated text: {:?}", snapshot.text());
|
log::info!("mutated text: {:?}", snapshot.text());
|
||||||
inlay_edits = Patch::new(edits);
|
inlay_edits = Patch::new(edits);
|
||||||
}
|
}
|
||||||
|
|
|
@ -708,7 +708,7 @@ mod tests {
|
||||||
fold_map.randomly_mutate(&mut rng);
|
fold_map.randomly_mutate(&mut rng);
|
||||||
let (fold_snapshot, _) = fold_map.read(inlay_snapshot, vec![]);
|
let (fold_snapshot, _) = fold_map.read(inlay_snapshot, vec![]);
|
||||||
log::info!("FoldMap text: {:?}", fold_snapshot.text());
|
log::info!("FoldMap text: {:?}", fold_snapshot.text());
|
||||||
let (inlay_snapshot, _) = inlay_map.randomly_mutate(&mut rng);
|
let (inlay_snapshot, _) = inlay_map.randomly_mutate(&mut 0, &mut rng);
|
||||||
log::info!("InlayMap text: {:?}", inlay_snapshot.text());
|
log::info!("InlayMap text: {:?}", inlay_snapshot.text());
|
||||||
|
|
||||||
let (tab_map, _) = TabMap::new(fold_snapshot.clone(), tab_size);
|
let (tab_map, _) = TabMap::new(fold_snapshot.clone(), tab_size);
|
||||||
|
|
|
@ -1119,6 +1119,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
log::info!("Wrapped text: {:?}", actual_text);
|
log::info!("Wrapped text: {:?}", actual_text);
|
||||||
|
|
||||||
|
let mut next_inlay_id = 0;
|
||||||
let mut edits = Vec::new();
|
let mut edits = Vec::new();
|
||||||
for _i in 0..operations {
|
for _i in 0..operations {
|
||||||
log::info!("{} ==============================================", _i);
|
log::info!("{} ==============================================", _i);
|
||||||
|
@ -1146,7 +1147,8 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
40..=59 => {
|
40..=59 => {
|
||||||
let (inlay_snapshot, inlay_edits) = inlay_map.randomly_mutate(&mut rng);
|
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 (fold_snapshot, fold_edits) = fold_map.read(inlay_snapshot, inlay_edits);
|
||||||
let (tabs_snapshot, tab_edits) =
|
let (tabs_snapshot, tab_edits) =
|
||||||
tab_map.sync(fold_snapshot, fold_edits, tab_size);
|
tab_map.sync(fold_snapshot, fold_edits, tab_size);
|
||||||
|
|
|
@ -185,6 +185,9 @@ pub struct GutterHover {
|
||||||
pub hovered: bool,
|
pub hovered: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct InlayId(usize);
|
||||||
|
|
||||||
actions!(
|
actions!(
|
||||||
editor,
|
editor,
|
||||||
[
|
[
|
||||||
|
@ -541,6 +544,7 @@ pub struct Editor {
|
||||||
link_go_to_definition_state: LinkGoToDefinitionState,
|
link_go_to_definition_state: LinkGoToDefinitionState,
|
||||||
copilot_state: CopilotState,
|
copilot_state: CopilotState,
|
||||||
inlay_hint_cache: InlayHintCache,
|
inlay_hint_cache: InlayHintCache,
|
||||||
|
next_inlay_id: usize,
|
||||||
_subscriptions: Vec<Subscription>,
|
_subscriptions: Vec<Subscription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1339,6 +1343,7 @@ impl Editor {
|
||||||
.add_view(|cx| context_menu::ContextMenu::new(editor_view_id, cx)),
|
.add_view(|cx| context_menu::ContextMenu::new(editor_view_id, cx)),
|
||||||
completion_tasks: Default::default(),
|
completion_tasks: Default::default(),
|
||||||
next_completion_id: 0,
|
next_completion_id: 0,
|
||||||
|
next_inlay_id: 0,
|
||||||
available_code_actions: Default::default(),
|
available_code_actions: Default::default(),
|
||||||
code_actions_task: Default::default(),
|
code_actions_task: Default::default(),
|
||||||
document_highlights_task: Default::default(),
|
document_highlights_task: Default::default(),
|
||||||
|
@ -2664,7 +2669,7 @@ impl Editor {
|
||||||
to_insert,
|
to_insert,
|
||||||
} = editor
|
} = editor
|
||||||
.update(&mut cx, |editor, cx| {
|
.update(&mut cx, |editor, cx| {
|
||||||
editor.inlay_hint_cache.append_inlays(
|
editor.inlay_hint_cache.append_hints(
|
||||||
multi_buffer_handle,
|
multi_buffer_handle,
|
||||||
std::iter::once(updated_range_query),
|
std::iter::once(updated_range_query),
|
||||||
cx,
|
cx,
|
||||||
|
@ -2693,7 +2698,7 @@ impl Editor {
|
||||||
to_insert,
|
to_insert,
|
||||||
} = editor
|
} = editor
|
||||||
.update(&mut cx, |editor, cx| {
|
.update(&mut cx, |editor, cx| {
|
||||||
editor.inlay_hint_cache.replace_inlays(
|
editor.inlay_hint_cache.replace_hints(
|
||||||
multi_buffer_handle,
|
multi_buffer_handle,
|
||||||
replacement_queries.into_iter(),
|
replacement_queries.into_iter(),
|
||||||
currently_shown_inlay_hints,
|
currently_shown_inlay_hints,
|
||||||
|
@ -2738,7 +2743,7 @@ impl Editor {
|
||||||
fn splice_inlay_hints(
|
fn splice_inlay_hints(
|
||||||
&self,
|
&self,
|
||||||
to_remove: Vec<InlayId>,
|
to_remove: Vec<InlayId>,
|
||||||
to_insert: Vec<(Option<InlayId>, Anchor, project::InlayHint)>,
|
to_insert: Vec<(InlayId, Anchor, project::InlayHint)>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
let buffer = self.buffer.read(cx).read(cx);
|
let buffer = self.buffer.read(cx).read(cx);
|
||||||
|
@ -3514,23 +3519,19 @@ impl Editor {
|
||||||
to_remove.push(suggestion.id);
|
to_remove.push(suggestion.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let suggestion_inlay_id = self.next_inlay_id();
|
||||||
let to_insert = vec![(
|
let to_insert = vec![(
|
||||||
None,
|
suggestion_inlay_id,
|
||||||
InlayProperties {
|
InlayProperties {
|
||||||
position: cursor,
|
position: cursor,
|
||||||
text: text.clone(),
|
text: text.clone(),
|
||||||
},
|
},
|
||||||
)];
|
)];
|
||||||
let new_inlay_ids = self.display_map.update(cx, move |map, cx| {
|
self.display_map.update(cx, move |map, cx| {
|
||||||
map.splice_inlays(to_remove, to_insert, cx)
|
map.splice_inlays(to_remove, to_insert, cx)
|
||||||
});
|
});
|
||||||
assert_eq!(
|
|
||||||
new_inlay_ids.len(),
|
|
||||||
1,
|
|
||||||
"Expecting only copilot suggestion id generated"
|
|
||||||
);
|
|
||||||
self.copilot_state.suggestion = Some(Inlay {
|
self.copilot_state.suggestion = Some(Inlay {
|
||||||
id: new_inlay_ids.into_iter().next().unwrap(),
|
id: suggestion_inlay_id,
|
||||||
position: cursor,
|
position: cursor,
|
||||||
text,
|
text,
|
||||||
});
|
});
|
||||||
|
@ -7687,6 +7688,10 @@ impl Editor {
|
||||||
let Some(lines) = serde_json::to_string_pretty(&lines).log_err() else { return; };
|
let Some(lines) = serde_json::to_string_pretty(&lines).log_err() else { return; };
|
||||||
cx.write_to_clipboard(ClipboardItem::new(lines));
|
cx.write_to_clipboard(ClipboardItem::new(lines));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn next_inlay_id(&mut self) -> InlayId {
|
||||||
|
InlayId(post_inc(&mut self.next_inlay_id))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inlay_hint_query(
|
fn inlay_hint_query(
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
display_map::InlayId, editor_settings, scroll::ScrollAnchor, Anchor, Editor, ExcerptId,
|
editor_settings, scroll::ScrollAnchor, Anchor, Editor, ExcerptId, InlayId, MultiBuffer,
|
||||||
MultiBuffer,
|
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clock::Global;
|
use clock::Global;
|
||||||
|
@ -12,6 +11,7 @@ use log::error;
|
||||||
use project::{InlayHint, InlayHintKind};
|
use project::{InlayHint, InlayHintKind};
|
||||||
|
|
||||||
use collections::{hash_map, HashMap, HashSet};
|
use collections::{hash_map, HashMap, HashSet};
|
||||||
|
use util::post_inc;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum InlayRefreshReason {
|
pub enum InlayRefreshReason {
|
||||||
|
@ -20,26 +20,39 @@ pub enum InlayRefreshReason {
|
||||||
VisibleExcerptsChange,
|
VisibleExcerptsChange,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct InlayHintCache {
|
pub struct InlayHintCache {
|
||||||
inlay_hints: HashMap<InlayId, InlayHint>,
|
inlay_hints: HashMap<InlayId, InlayHint>,
|
||||||
inlays_in_buffers: HashMap<u64, BufferInlays<(Anchor, InlayId)>>,
|
hints_in_buffers: HashMap<u64, BufferHints<(Anchor, InlayId)>>,
|
||||||
allowed_hint_kinds: HashSet<Option<InlayHintKind>>,
|
allowed_hint_kinds: HashSet<Option<InlayHintKind>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug)]
|
||||||
struct BufferInlays<I> {
|
struct BufferHints<I> {
|
||||||
buffer_version: Global,
|
buffer_version: Global,
|
||||||
cached_ranges: HashMap<ExcerptId, Vec<Range<usize>>>,
|
hints_per_excerpt: HashMap<ExcerptId, ExcerptHints<I>>,
|
||||||
excerpt_inlays: HashMap<ExcerptId, Vec<I>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> BufferInlays<I> {
|
#[derive(Clone, Debug)]
|
||||||
|
struct ExcerptHints<I> {
|
||||||
|
cached_excerpt_offsets: Vec<Range<usize>>,
|
||||||
|
hints: Vec<I>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> Default for ExcerptHints<I> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
cached_excerpt_offsets: Vec::new(),
|
||||||
|
hints: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> BufferHints<I> {
|
||||||
fn new(buffer_version: Global) -> Self {
|
fn new(buffer_version: Global) -> Self {
|
||||||
Self {
|
Self {
|
||||||
buffer_version,
|
buffer_version,
|
||||||
excerpt_inlays: HashMap::default(),
|
hints_per_excerpt: HashMap::default(),
|
||||||
cached_ranges: HashMap::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +60,7 @@ impl<I> BufferInlays<I> {
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct InlaySplice {
|
pub struct InlaySplice {
|
||||||
pub to_remove: Vec<InlayId>,
|
pub to_remove: Vec<InlayId>,
|
||||||
pub to_insert: Vec<(Option<InlayId>, Anchor, InlayHint)>,
|
pub to_insert: Vec<(InlayId, Anchor, InlayHint)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InlayHintQuery {
|
pub struct InlayHintQuery {
|
||||||
|
@ -61,7 +74,7 @@ impl InlayHintCache {
|
||||||
pub fn new(inlay_hint_settings: editor_settings::InlayHints) -> Self {
|
pub fn new(inlay_hint_settings: editor_settings::InlayHints) -> Self {
|
||||||
Self {
|
Self {
|
||||||
allowed_hint_kinds: allowed_inlay_hint_types(inlay_hint_settings),
|
allowed_hint_kinds: allowed_inlay_hint_types(inlay_hint_settings),
|
||||||
inlays_in_buffers: HashMap::default(),
|
hints_in_buffers: HashMap::default(),
|
||||||
inlay_hints: HashMap::default(),
|
inlay_hints: HashMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,26 +130,27 @@ impl InlayHintCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
let reenabled_hints = self
|
let reenabled_hints = self
|
||||||
.inlays_in_buffers
|
.hints_in_buffers
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(cached_buffer_id, cached_hints_per_excerpt)| {
|
.filter_map(|(cached_buffer_id, cached_hints_per_excerpt)| {
|
||||||
let considered_hints_in_excerpts = considered_hints.get(cached_buffer_id)?;
|
let considered_hints_in_excerpts = considered_hints.get(cached_buffer_id)?;
|
||||||
let not_considered_cached_inlays = cached_hints_per_excerpt
|
let not_considered_cached_hints = cached_hints_per_excerpt
|
||||||
.excerpt_inlays
|
.hints_per_excerpt
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(cached_excerpt_id, cached_hints)| {
|
.filter_map(|(cached_excerpt_id, cached_excerpt_hints)| {
|
||||||
let considered_excerpt_hints =
|
let considered_excerpt_hints =
|
||||||
considered_hints_in_excerpts.get(&cached_excerpt_id)?;
|
considered_hints_in_excerpts.get(&cached_excerpt_id)?;
|
||||||
let not_considered_cached_inlays = cached_hints
|
let not_considered_cached_hints = cached_excerpt_hints
|
||||||
|
.hints
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, cached_hint_id)| {
|
.filter(|(_, cached_hint_id)| {
|
||||||
!considered_excerpt_hints.contains(cached_hint_id)
|
!considered_excerpt_hints.contains(cached_hint_id)
|
||||||
})
|
})
|
||||||
.copied();
|
.copied();
|
||||||
Some(not_considered_cached_inlays)
|
Some(not_considered_cached_hints)
|
||||||
})
|
})
|
||||||
.flatten();
|
.flatten();
|
||||||
Some(not_considered_cached_inlays)
|
Some(not_considered_cached_hints)
|
||||||
})
|
})
|
||||||
.flatten()
|
.flatten()
|
||||||
.filter_map(|(cached_anchor, cached_inlay_id)| {
|
.filter_map(|(cached_anchor, cached_inlay_id)| {
|
||||||
|
@ -148,11 +162,7 @@ impl InlayHintCache {
|
||||||
})
|
})
|
||||||
.filter(|(_, _, cached_inlay)| self.allowed_hint_kinds.contains(&cached_inlay.kind))
|
.filter(|(_, _, cached_inlay)| self.allowed_hint_kinds.contains(&cached_inlay.kind))
|
||||||
.map(|(cached_anchor, cached_inlay_id, reenabled_inlay)| {
|
.map(|(cached_anchor, cached_inlay_id, reenabled_inlay)| {
|
||||||
(
|
(cached_inlay_id, cached_anchor, reenabled_inlay.clone())
|
||||||
Some(cached_inlay_id),
|
|
||||||
cached_anchor,
|
|
||||||
reenabled_inlay.clone(),
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
to_insert.extend(reenabled_hints);
|
to_insert.extend(reenabled_hints);
|
||||||
|
|
||||||
|
@ -173,25 +183,25 @@ impl InlayHintCache {
|
||||||
|
|
||||||
pub fn clear(&mut self) -> Vec<InlayId> {
|
pub fn clear(&mut self) -> Vec<InlayId> {
|
||||||
let ids_to_remove = self.inlay_hints.drain().map(|(id, _)| id).collect();
|
let ids_to_remove = self.inlay_hints.drain().map(|(id, _)| id).collect();
|
||||||
self.inlays_in_buffers.clear();
|
self.hints_in_buffers.clear();
|
||||||
ids_to_remove
|
ids_to_remove
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append_inlays(
|
pub fn append_hints(
|
||||||
&mut self,
|
&mut self,
|
||||||
multi_buffer: ModelHandle<MultiBuffer>,
|
multi_buffer: ModelHandle<MultiBuffer>,
|
||||||
ranges_to_add: impl Iterator<Item = InlayHintQuery>,
|
ranges_to_add: impl Iterator<Item = InlayHintQuery>,
|
||||||
cx: &mut ViewContext<Editor>,
|
cx: &mut ViewContext<Editor>,
|
||||||
) -> Task<anyhow::Result<InlaySplice>> {
|
) -> Task<anyhow::Result<InlaySplice>> {
|
||||||
let queries = ranges_to_add.filter_map(|additive_query| {
|
let queries = ranges_to_add.filter_map(|additive_query| {
|
||||||
let Some(cached_buffer_inlays) = self.inlays_in_buffers.get(&additive_query.buffer_id)
|
let Some(cached_buffer_hints) = self.hints_in_buffers.get(&additive_query.buffer_id)
|
||||||
else { return Some(vec![additive_query]) };
|
else { return Some(vec![additive_query]) };
|
||||||
if cached_buffer_inlays.buffer_version.changed_since(&additive_query.buffer_version) {
|
if cached_buffer_hints.buffer_version.changed_since(&additive_query.buffer_version) {
|
||||||
return None
|
return None
|
||||||
}
|
}
|
||||||
let Some(excerpt_cached_ranges) = cached_buffer_inlays.cached_ranges.get(&additive_query.excerpt_id)
|
let Some(excerpt_hints) = cached_buffer_hints.hints_per_excerpt.get(&additive_query.excerpt_id)
|
||||||
else { return Some(vec![additive_query]) };
|
else { return Some(vec![additive_query]) };
|
||||||
let non_cached_ranges = missing_subranges(&excerpt_cached_ranges, &additive_query.excerpt_offset_query_range);
|
let non_cached_ranges = missing_subranges(&excerpt_hints.cached_excerpt_offsets, &additive_query.excerpt_offset_query_range);
|
||||||
if non_cached_ranges.is_empty() {
|
if non_cached_ranges.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -210,55 +220,59 @@ impl InlayHintCache {
|
||||||
let new_hints = fetch_queries_task.await?;
|
let new_hints = fetch_queries_task.await?;
|
||||||
editor.update(&mut cx, |editor, cx| {
|
editor.update(&mut cx, |editor, cx| {
|
||||||
let multi_buffer_snapshot = task_multi_buffer.read(cx).snapshot(cx);
|
let multi_buffer_snapshot = task_multi_buffer.read(cx).snapshot(cx);
|
||||||
let inlay_hint_cache = &mut editor.inlay_hint_cache;
|
|
||||||
let mut to_insert = Vec::new();
|
let mut to_insert = Vec::new();
|
||||||
for (new_buffer_id, new_hints_per_buffer) in new_hints {
|
for (new_buffer_id, new_hints_per_buffer) in new_hints {
|
||||||
let cached_buffer_inlays = inlay_hint_cache
|
let cached_buffer_hints = editor
|
||||||
.inlays_in_buffers
|
.inlay_hint_cache
|
||||||
|
.hints_in_buffers
|
||||||
.entry(new_buffer_id)
|
.entry(new_buffer_id)
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
BufferInlays::new(new_hints_per_buffer.buffer_version.clone())
|
BufferHints::new(new_hints_per_buffer.buffer_version.clone())
|
||||||
});
|
});
|
||||||
if cached_buffer_inlays
|
if cached_buffer_hints
|
||||||
.buffer_version
|
.buffer_version
|
||||||
.changed_since(&new_hints_per_buffer.buffer_version)
|
.changed_since(&new_hints_per_buffer.buffer_version)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (new_excerpt_id, new_ranges) in new_hints_per_buffer.cached_ranges {
|
for (new_excerpt_id, new_excerpt_hints) in
|
||||||
let cached_ranges = cached_buffer_inlays
|
new_hints_per_buffer.hints_per_excerpt
|
||||||
.cached_ranges
|
{
|
||||||
|
let cached_excerpt_hints = cached_buffer_hints
|
||||||
|
.hints_per_excerpt
|
||||||
.entry(new_excerpt_id)
|
.entry(new_excerpt_id)
|
||||||
.or_default();
|
.or_insert_with(|| ExcerptHints::default());
|
||||||
for new_range in new_ranges {
|
for new_range in new_excerpt_hints.cached_excerpt_offsets {
|
||||||
insert_and_merge_ranges(cached_ranges, &new_range)
|
insert_and_merge_ranges(
|
||||||
|
&mut cached_excerpt_hints.cached_excerpt_offsets,
|
||||||
|
&new_range,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
for new_inlay_hint in new_excerpt_hints.hints {
|
||||||
for (new_excerpt_id, new_hints) in new_hints_per_buffer.excerpt_inlays {
|
|
||||||
let cached_inlays = cached_buffer_inlays
|
|
||||||
.excerpt_inlays
|
|
||||||
.entry(new_excerpt_id)
|
|
||||||
.or_default();
|
|
||||||
for new_inlay_hint in new_hints {
|
|
||||||
let new_inlay_id = todo!("TODO kb");
|
|
||||||
let hint_anchor = multi_buffer_snapshot
|
let hint_anchor = multi_buffer_snapshot
|
||||||
.anchor_in_excerpt(new_excerpt_id, new_inlay_hint.position);
|
.anchor_in_excerpt(new_excerpt_id, new_inlay_hint.position);
|
||||||
match cached_inlays.binary_search_by(|probe| {
|
let insert_ix =
|
||||||
|
match cached_excerpt_hints.hints.binary_search_by(|probe| {
|
||||||
hint_anchor.cmp(&probe.0, &multi_buffer_snapshot)
|
hint_anchor.cmp(&probe.0, &multi_buffer_snapshot)
|
||||||
}) {
|
}) {
|
||||||
Ok(ix) | Err(ix) => {
|
Ok(ix) | Err(ix) => ix,
|
||||||
cached_inlays.insert(ix, (hint_anchor, new_inlay_id))
|
};
|
||||||
}
|
|
||||||
}
|
let new_inlay_id = InlayId(post_inc(&mut editor.next_inlay_id));
|
||||||
inlay_hint_cache
|
cached_excerpt_hints
|
||||||
|
.hints
|
||||||
|
.insert(insert_ix, (hint_anchor, new_inlay_id));
|
||||||
|
editor
|
||||||
|
.inlay_hint_cache
|
||||||
.inlay_hints
|
.inlay_hints
|
||||||
.insert(new_inlay_id, new_inlay_hint.clone());
|
.insert(new_inlay_id, new_inlay_hint.clone());
|
||||||
if inlay_hint_cache
|
if editor
|
||||||
|
.inlay_hint_cache
|
||||||
.allowed_hint_kinds
|
.allowed_hint_kinds
|
||||||
.contains(&new_inlay_hint.kind)
|
.contains(&new_inlay_hint.kind)
|
||||||
{
|
{
|
||||||
to_insert.push((Some(new_inlay_id), hint_anchor, new_inlay_hint));
|
to_insert.push((new_inlay_id, hint_anchor, new_inlay_hint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,7 +286,7 @@ impl InlayHintCache {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replace_inlays(
|
pub fn replace_hints(
|
||||||
&mut self,
|
&mut self,
|
||||||
multi_buffer: ModelHandle<MultiBuffer>,
|
multi_buffer: ModelHandle<MultiBuffer>,
|
||||||
new_ranges: impl Iterator<Item = InlayHintQuery>,
|
new_ranges: impl Iterator<Item = InlayHintQuery>,
|
||||||
|
@ -401,7 +415,7 @@ fn fetch_queries<'a, 'b>(
|
||||||
multi_buffer: ModelHandle<MultiBuffer>,
|
multi_buffer: ModelHandle<MultiBuffer>,
|
||||||
queries: impl Iterator<Item = InlayHintQuery>,
|
queries: impl Iterator<Item = InlayHintQuery>,
|
||||||
cx: &mut ViewContext<'a, 'b, Editor>,
|
cx: &mut ViewContext<'a, 'b, Editor>,
|
||||||
) -> Task<anyhow::Result<HashMap<u64, BufferInlays<InlayHint>>>> {
|
) -> Task<anyhow::Result<HashMap<u64, BufferHints<InlayHint>>>> {
|
||||||
let mut inlay_fetch_tasks = Vec::new();
|
let mut inlay_fetch_tasks = Vec::new();
|
||||||
for query in queries {
|
for query in queries {
|
||||||
let task_multi_buffer = multi_buffer.clone();
|
let task_multi_buffer = multi_buffer.clone();
|
||||||
|
@ -434,33 +448,30 @@ fn fetch_queries<'a, 'b>(
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.spawn(|editor, cx| async move {
|
cx.spawn(|editor, cx| async move {
|
||||||
let mut inlay_updates: HashMap<u64, BufferInlays<InlayHint>> = HashMap::default();
|
let mut inlay_updates: HashMap<u64, BufferHints<InlayHint>> = HashMap::default();
|
||||||
for task_result in futures::future::join_all(inlay_fetch_tasks).await {
|
for task_result in futures::future::join_all(inlay_fetch_tasks).await {
|
||||||
match task_result {
|
match task_result {
|
||||||
Ok((query, Some(response_inlays))) => {
|
Ok((query, Some(response_hints))) => {
|
||||||
let Some(buffer_snapshot) = editor.read_with(&cx, |editor, cx| {
|
let Some(buffer_snapshot) = editor.read_with(&cx, |editor, cx| {
|
||||||
editor.buffer().read(cx).buffer(query.buffer_id).map(|buffer| buffer.read(cx).snapshot())
|
editor.buffer().read(cx).buffer(query.buffer_id).map(|buffer| buffer.read(cx).snapshot())
|
||||||
})? else { continue; };
|
})? else { continue; };
|
||||||
let buffer_inlays = inlay_updates
|
let buffer_hints = inlay_updates
|
||||||
.entry(query.buffer_id)
|
.entry(query.buffer_id)
|
||||||
.or_insert_with(|| BufferInlays::new(query.buffer_version.clone()));
|
.or_insert_with(|| BufferHints::new(query.buffer_version.clone()));
|
||||||
assert_eq!(buffer_inlays.buffer_version, query.buffer_version);
|
if buffer_snapshot.version().changed_since(&buffer_hints.buffer_version) {
|
||||||
{
|
continue;
|
||||||
let cached_ranges = buffer_inlays
|
}
|
||||||
.cached_ranges
|
let cached_excerpt_hints = buffer_hints
|
||||||
|
.hints_per_excerpt
|
||||||
.entry(query.excerpt_id)
|
.entry(query.excerpt_id)
|
||||||
.or_default();
|
.or_default();
|
||||||
insert_and_merge_ranges(cached_ranges, &query.excerpt_offset_query_range);
|
insert_and_merge_ranges(&mut cached_excerpt_hints.cached_excerpt_offsets, &query.excerpt_offset_query_range);
|
||||||
let excerpt_inlays = buffer_inlays
|
let excerpt_hints = &mut cached_excerpt_hints.hints;
|
||||||
.excerpt_inlays
|
for inlay in response_hints {
|
||||||
.entry(query.excerpt_id)
|
match excerpt_hints.binary_search_by(|probe| {
|
||||||
.or_default();
|
|
||||||
for inlay in response_inlays {
|
|
||||||
match excerpt_inlays.binary_search_by(|probe| {
|
|
||||||
inlay.position.cmp(&probe.position, &buffer_snapshot)
|
inlay.position.cmp(&probe.position, &buffer_snapshot)
|
||||||
}) {
|
}) {
|
||||||
Ok(ix) | Err(ix) => excerpt_inlays.insert(ix, inlay),
|
Ok(ix) | Err(ix) => excerpt_hints.insert(ix, inlay),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue