@@ -5,7 +5,9 @@ mod suggestion_map;
mod tab_map;
mod wrap_map;
-use crate::{Anchor, AnchorRangeExt, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint};
+use crate::{
+ Anchor, AnchorRangeExt, InlayHintLocation, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint,
+};
pub use block_map::{BlockMap, BlockPoint};
use collections::{HashMap, HashSet};
use fold_map::{FoldMap, FoldOffset};
@@ -284,19 +286,12 @@ impl DisplayMap {
pub fn set_inlay_hints(
&mut self,
- new_hints: &[project::InlayHint],
+ new_hints: &HashMap<InlayHintLocation, Vec<project::InlayHint>>,
cx: &mut ModelContext<Self>,
) {
+ // TODO kb map this to Anchor and set to the map
let multi_buffer = self.buffer.read(cx);
- // TODO kb carry both remote and local ids of the buffer?
- // now, `.buffer` requires remote id, hence this map.
- let buffers_to_local_id = multi_buffer
- .all_buffers()
- .into_iter()
- .map(|buffer_handle| (buffer_handle.id(), buffer_handle))
- .collect::<HashMap<_, _>>();
-
// multi_buffer.anchor_in_excerpt(excerpt_id, hint.position);
// TODO kb !!! rework things from buffer_id to excerpt_id
// let hint_anchor = multi_buffer
@@ -7,7 +7,7 @@ use std::{
sync::atomic::{self, AtomicUsize},
};
-use crate::{Anchor, MultiBufferSnapshot, ToOffset, ToPoint};
+use crate::{Anchor, ExcerptId, InlayHintLocation, MultiBufferSnapshot, ToOffset, ToPoint};
use super::{
suggestion_map::{
@@ -31,7 +31,7 @@ pub struct InlayId(usize);
pub struct InlayMap {
snapshot: Mutex<InlaySnapshot>,
next_inlay_id: usize,
- inlays: HashMap<InlayId, Inlay>,
+ inlays: HashMap<InlayId, (InlayHintLocation, Inlay)>,
}
#[derive(Clone)]
@@ -224,18 +224,18 @@ impl InlayMap {
pub fn splice(
&mut self,
to_remove: HashSet<InlayId>,
- to_insert: Vec<InlayProperties>,
+ to_insert: Vec<(InlayHintLocation, InlayProperties)>,
) -> (InlaySnapshot, Vec<InlayEdit>, Vec<InlayId>) {
let mut snapshot = self.snapshot.lock();
let mut inlays = BTreeMap::new();
let mut new_ids = Vec::new();
- for properties in to_insert {
+ for (location, properties) in to_insert {
let inlay = Inlay {
id: InlayId(post_inc(&mut self.next_inlay_id)),
properties,
};
- self.inlays.insert(inlay.id, inlay.clone());
+ self.inlays.insert(inlay.id, (location, inlay.clone()));
new_ids.push(inlay.id);
let buffer_point = inlay
@@ -253,7 +253,7 @@ impl InlayMap {
}
for inlay_id in to_remove {
- if let Some(inlay) = self.inlays.remove(&inlay_id) {
+ if let Some((_, inlay)) = self.inlays.remove(&inlay_id) {
let buffer_point = inlay
.properties
.position
@@ -448,10 +448,16 @@ mod tests {
let (inlay_snapshot, _, inlay_ids) = inlay_map.splice(
HashSet::default(),
- vec![InlayProperties {
- position: buffer.read(cx).read(cx).anchor_before(3),
- text: "|123|".into(),
- }],
+ vec![(
+ InlayHintLocation {
+ buffer_id: 0,
+ excerpt_id: ExcerptId::default(),
+ },
+ InlayProperties {
+ position: buffer.read(cx).read(cx).anchor_before(3),
+ text: "|123|".into(),
+ },
+ )],
);
assert_eq!(inlay_snapshot.text(), "abc|123|defghi");
@@ -1153,24 +1153,30 @@ impl CopilotState {
}
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub struct InlayHintLocation {
+ pub buffer_id: u64,
+ pub excerpt_id: ExcerptId,
+}
+
// TODO kb
#[derive(Debug, Default, Clone)]
struct InlayHintVersions {
- last_buffer_versions_with_hints: HashMap<usize, Global>,
+ last_buffer_versions_with_hints: HashMap<InlayHintLocation, Global>,
}
impl InlayHintVersions {
- fn absent_or_newer(&self, buffer_id: usize, new_version: &Global) -> bool {
+ fn absent_or_newer(&self, location: &InlayHintLocation, new_version: &Global) -> bool {
self.last_buffer_versions_with_hints
- .get(&buffer_id)
+ .get(location)
.map(|last_version_with_hints| new_version.changed_since(&last_version_with_hints))
.unwrap_or(true)
}
- fn insert(&mut self, buffer_id: usize, new_version: Global) -> bool {
- if self.absent_or_newer(buffer_id, &new_version) {
+ fn insert(&mut self, location: InlayHintLocation, new_version: Global) -> bool {
+ if self.absent_or_newer(&location, &new_version) {
self.last_buffer_versions_with_hints
- .insert(buffer_id, new_version);
+ .insert(location, new_version);
true
} else {
false
@@ -2617,50 +2623,40 @@ impl Editor {
return;
}
- let hint_fetch_tasks = self
- .buffer()
- .read(cx)
- .all_buffers()
- .into_iter()
- .map(|buffer_handle| {
- let buffer_id = buffer_handle.id();
+ let multi_buffer = self.buffer().read(cx);
+ let buffer_snapshot = multi_buffer.snapshot(cx);
+ let hint_fetch_tasks = buffer_snapshot
+ .excerpts()
+ .map(|(excerpt_id, excerpt_buffer_snapshot, _)| {
+ (excerpt_id, excerpt_buffer_snapshot.clone())
+ })
+ .map(|(excerpt_id, excerpt_buffer_snapshot)| {
cx.spawn(|editor, mut cx| async move {
- let task_data = editor
+ let task = editor
.update(&mut cx, |editor, cx| {
editor.project.as_ref().and_then(|project| {
project.update(cx, |project, cx| {
- let buffer = buffer_handle.read(cx);
- let end = buffer.len();
- let version = buffer.version();
-
- if editor
- .inlay_hint_versions
- .absent_or_newer(buffer_id, &version)
- {
- Some((
- version,
- project.inlay_hints_for_buffer(
- buffer_handle,
- 0..end,
- cx,
- ),
- ))
- } else {
- None
- }
+ Some(
+ project.inlay_hints_for_buffer(
+ editor
+ .buffer()
+ .read(cx)
+ .buffer(excerpt_buffer_snapshot.remote_id())?,
+ 0..excerpt_buffer_snapshot.len(),
+ cx,
+ ),
+ )
})
})
})
.context("inlay hints fecth task spawn")?;
anyhow::Ok((
- buffer_id,
- match task_data {
- Some((buffer_version, task)) => Some((
- buffer_version,
- task.await.context("inlay hints for buffer task")?,
- )),
- None => None,
+ excerpt_id,
+ excerpt_buffer_snapshot,
+ match task {
+ Some(task) => task.await.context("inlay hints for buffer task")?,
+ None => Vec::new(),
},
))
})
@@ -2668,21 +2664,32 @@ impl Editor {
.collect::<Vec<_>>();
cx.spawn(|editor, mut cx| async move {
- let mut new_hints = Vec::new();
+ let mut new_hints: HashMap<InlayHintLocation, Vec<project::InlayHint>> =
+ HashMap::default();
for task_result in futures::future::join_all(hint_fetch_tasks).await {
match task_result {
- Ok((_buffer_id, None)) => {}
- Ok((buffer_id, Some((buffer_with_hints_version, buffer_hints)))) => {
+ Ok((excerpt_id, excerpt_buffer_snapshot, excerpt_hints)) => {
+ let buffer_id = excerpt_buffer_snapshot.remote_id();
let should_update_hints = editor
.update(&mut cx, |editor, _| {
- editor
- .inlay_hint_versions
- .insert(buffer_id, buffer_with_hints_version)
+ editor.inlay_hint_versions.insert(
+ InlayHintLocation {
+ buffer_id,
+ excerpt_id,
+ },
+ excerpt_buffer_snapshot.version().clone(),
+ )
})
.log_err()
.unwrap_or(false);
if should_update_hints {
- new_hints.extend(buffer_hints);
+ new_hints
+ .entry(InlayHintLocation {
+ buffer_id,
+ excerpt_id,
+ })
+ .or_default()
+ .extend(excerpt_hints);
}
}
Err(e) => error!("Failed to update hints for buffer: {e:#}"),