Improve on inlya locations
This commit is contained in:
parent
b193d62a5d
commit
3028767d12
3 changed files with 75 additions and 67 deletions
|
@ -5,7 +5,9 @@ mod suggestion_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, InlayHintLocation, 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, FoldOffset};
|
use fold_map::{FoldMap, FoldOffset};
|
||||||
|
@ -284,19 +286,12 @@ impl DisplayMap {
|
||||||
|
|
||||||
pub fn set_inlay_hints(
|
pub fn set_inlay_hints(
|
||||||
&mut self,
|
&mut self,
|
||||||
new_hints: &[project::InlayHint],
|
new_hints: &HashMap<InlayHintLocation, Vec<project::InlayHint>>,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) {
|
) {
|
||||||
|
// TODO kb map this to Anchor and set to the map
|
||||||
let multi_buffer = self.buffer.read(cx);
|
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);
|
// multi_buffer.anchor_in_excerpt(excerpt_id, hint.position);
|
||||||
// TODO kb !!! rework things from buffer_id to excerpt_id
|
// TODO kb !!! rework things from buffer_id to excerpt_id
|
||||||
// let hint_anchor = multi_buffer
|
// let hint_anchor = multi_buffer
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::{
|
||||||
sync::atomic::{self, AtomicUsize},
|
sync::atomic::{self, AtomicUsize},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Anchor, MultiBufferSnapshot, ToOffset, ToPoint};
|
use crate::{Anchor, ExcerptId, InlayHintLocation, MultiBufferSnapshot, ToOffset, ToPoint};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
suggestion_map::{
|
suggestion_map::{
|
||||||
|
@ -31,7 +31,7 @@ pub struct InlayId(usize);
|
||||||
pub struct InlayMap {
|
pub struct InlayMap {
|
||||||
snapshot: Mutex<InlaySnapshot>,
|
snapshot: Mutex<InlaySnapshot>,
|
||||||
next_inlay_id: usize,
|
next_inlay_id: usize,
|
||||||
inlays: HashMap<InlayId, Inlay>,
|
inlays: HashMap<InlayId, (InlayHintLocation, Inlay)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -224,18 +224,18 @@ impl InlayMap {
|
||||||
pub fn splice(
|
pub fn splice(
|
||||||
&mut self,
|
&mut self,
|
||||||
to_remove: HashSet<InlayId>,
|
to_remove: HashSet<InlayId>,
|
||||||
to_insert: Vec<InlayProperties>,
|
to_insert: Vec<(InlayHintLocation, InlayProperties)>,
|
||||||
) -> (InlaySnapshot, Vec<InlayEdit>, Vec<InlayId>) {
|
) -> (InlaySnapshot, Vec<InlayEdit>, Vec<InlayId>) {
|
||||||
let mut snapshot = self.snapshot.lock();
|
let mut snapshot = self.snapshot.lock();
|
||||||
|
|
||||||
let mut inlays = BTreeMap::new();
|
let mut inlays = BTreeMap::new();
|
||||||
let mut new_ids = Vec::new();
|
let mut new_ids = Vec::new();
|
||||||
for properties in to_insert {
|
for (location, properties) in to_insert {
|
||||||
let inlay = Inlay {
|
let inlay = Inlay {
|
||||||
id: InlayId(post_inc(&mut self.next_inlay_id)),
|
id: InlayId(post_inc(&mut self.next_inlay_id)),
|
||||||
properties,
|
properties,
|
||||||
};
|
};
|
||||||
self.inlays.insert(inlay.id, inlay.clone());
|
self.inlays.insert(inlay.id, (location, inlay.clone()));
|
||||||
new_ids.push(inlay.id);
|
new_ids.push(inlay.id);
|
||||||
|
|
||||||
let buffer_point = inlay
|
let buffer_point = inlay
|
||||||
|
@ -253,7 +253,7 @@ impl InlayMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
for inlay_id in to_remove {
|
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
|
let buffer_point = inlay
|
||||||
.properties
|
.properties
|
||||||
.position
|
.position
|
||||||
|
@ -448,10 +448,16 @@ mod tests {
|
||||||
|
|
||||||
let (inlay_snapshot, _, inlay_ids) = inlay_map.splice(
|
let (inlay_snapshot, _, inlay_ids) = inlay_map.splice(
|
||||||
HashSet::default(),
|
HashSet::default(),
|
||||||
vec![InlayProperties {
|
vec![(
|
||||||
position: buffer.read(cx).read(cx).anchor_before(3),
|
InlayHintLocation {
|
||||||
text: "|123|".into(),
|
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");
|
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
|
// TODO kb
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
struct InlayHintVersions {
|
struct InlayHintVersions {
|
||||||
last_buffer_versions_with_hints: HashMap<usize, Global>,
|
last_buffer_versions_with_hints: HashMap<InlayHintLocation, Global>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InlayHintVersions {
|
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
|
self.last_buffer_versions_with_hints
|
||||||
.get(&buffer_id)
|
.get(location)
|
||||||
.map(|last_version_with_hints| new_version.changed_since(&last_version_with_hints))
|
.map(|last_version_with_hints| new_version.changed_since(&last_version_with_hints))
|
||||||
.unwrap_or(true)
|
.unwrap_or(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert(&mut self, buffer_id: usize, new_version: Global) -> bool {
|
fn insert(&mut self, location: InlayHintLocation, new_version: Global) -> bool {
|
||||||
if self.absent_or_newer(buffer_id, &new_version) {
|
if self.absent_or_newer(&location, &new_version) {
|
||||||
self.last_buffer_versions_with_hints
|
self.last_buffer_versions_with_hints
|
||||||
.insert(buffer_id, new_version);
|
.insert(location, new_version);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -2617,50 +2623,40 @@ impl Editor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hint_fetch_tasks = self
|
let multi_buffer = self.buffer().read(cx);
|
||||||
.buffer()
|
let buffer_snapshot = multi_buffer.snapshot(cx);
|
||||||
.read(cx)
|
let hint_fetch_tasks = buffer_snapshot
|
||||||
.all_buffers()
|
.excerpts()
|
||||||
.into_iter()
|
.map(|(excerpt_id, excerpt_buffer_snapshot, _)| {
|
||||||
.map(|buffer_handle| {
|
(excerpt_id, excerpt_buffer_snapshot.clone())
|
||||||
let buffer_id = buffer_handle.id();
|
})
|
||||||
|
.map(|(excerpt_id, excerpt_buffer_snapshot)| {
|
||||||
cx.spawn(|editor, mut cx| async move {
|
cx.spawn(|editor, mut cx| async move {
|
||||||
let task_data = editor
|
let task = editor
|
||||||
.update(&mut cx, |editor, cx| {
|
.update(&mut cx, |editor, cx| {
|
||||||
editor.project.as_ref().and_then(|project| {
|
editor.project.as_ref().and_then(|project| {
|
||||||
project.update(cx, |project, cx| {
|
project.update(cx, |project, cx| {
|
||||||
let buffer = buffer_handle.read(cx);
|
Some(
|
||||||
let end = buffer.len();
|
project.inlay_hints_for_buffer(
|
||||||
let version = buffer.version();
|
editor
|
||||||
|
.buffer()
|
||||||
if editor
|
.read(cx)
|
||||||
.inlay_hint_versions
|
.buffer(excerpt_buffer_snapshot.remote_id())?,
|
||||||
.absent_or_newer(buffer_id, &version)
|
0..excerpt_buffer_snapshot.len(),
|
||||||
{
|
cx,
|
||||||
Some((
|
),
|
||||||
version,
|
)
|
||||||
project.inlay_hints_for_buffer(
|
|
||||||
buffer_handle,
|
|
||||||
0..end,
|
|
||||||
cx,
|
|
||||||
),
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.context("inlay hints fecth task spawn")?;
|
.context("inlay hints fecth task spawn")?;
|
||||||
|
|
||||||
anyhow::Ok((
|
anyhow::Ok((
|
||||||
buffer_id,
|
excerpt_id,
|
||||||
match task_data {
|
excerpt_buffer_snapshot,
|
||||||
Some((buffer_version, task)) => Some((
|
match task {
|
||||||
buffer_version,
|
Some(task) => task.await.context("inlay hints for buffer task")?,
|
||||||
task.await.context("inlay hints for buffer task")?,
|
None => Vec::new(),
|
||||||
)),
|
|
||||||
None => None,
|
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
@ -2668,21 +2664,32 @@ impl Editor {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
cx.spawn(|editor, mut cx| async move {
|
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 {
|
for task_result in futures::future::join_all(hint_fetch_tasks).await {
|
||||||
match task_result {
|
match task_result {
|
||||||
Ok((_buffer_id, None)) => {}
|
Ok((excerpt_id, excerpt_buffer_snapshot, excerpt_hints)) => {
|
||||||
Ok((buffer_id, Some((buffer_with_hints_version, buffer_hints)))) => {
|
let buffer_id = excerpt_buffer_snapshot.remote_id();
|
||||||
let should_update_hints = editor
|
let should_update_hints = editor
|
||||||
.update(&mut cx, |editor, _| {
|
.update(&mut cx, |editor, _| {
|
||||||
editor
|
editor.inlay_hint_versions.insert(
|
||||||
.inlay_hint_versions
|
InlayHintLocation {
|
||||||
.insert(buffer_id, buffer_with_hints_version)
|
buffer_id,
|
||||||
|
excerpt_id,
|
||||||
|
},
|
||||||
|
excerpt_buffer_snapshot.version().clone(),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.log_err()
|
.log_err()
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if should_update_hints {
|
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:#}"),
|
Err(e) => error!("Failed to update hints for buffer: {e:#}"),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue