mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-06 10:42:08 +00:00
Only skip /refresh inlay queries when vislble range is not updated
This commit is contained in:
parent
096bad1f73
commit
67214f0e55
1 changed files with 172 additions and 181 deletions
|
@ -57,6 +57,39 @@ struct ExcerptDimensions {
|
||||||
excerpt_visible_range_end: language::Anchor,
|
excerpt_visible_range_end: language::Anchor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ExcerptQuery {
|
||||||
|
fn hints_fetch_ranges(&self, buffer: &BufferSnapshot) -> HintFetchRanges {
|
||||||
|
let visible_range =
|
||||||
|
self.dimensions.excerpt_visible_range_start..self.dimensions.excerpt_visible_range_end;
|
||||||
|
let mut other_ranges = Vec::new();
|
||||||
|
if self
|
||||||
|
.dimensions
|
||||||
|
.excerpt_range_start
|
||||||
|
.cmp(&self.dimensions.excerpt_visible_range_start, buffer)
|
||||||
|
.is_lt()
|
||||||
|
{
|
||||||
|
let mut end = self.dimensions.excerpt_visible_range_start;
|
||||||
|
end.offset -= 1;
|
||||||
|
other_ranges.push(self.dimensions.excerpt_range_start..end);
|
||||||
|
}
|
||||||
|
if self
|
||||||
|
.dimensions
|
||||||
|
.excerpt_range_end
|
||||||
|
.cmp(&self.dimensions.excerpt_visible_range_end, buffer)
|
||||||
|
.is_gt()
|
||||||
|
{
|
||||||
|
let mut start = self.dimensions.excerpt_visible_range_end;
|
||||||
|
start.offset += 1;
|
||||||
|
other_ranges.push(start..self.dimensions.excerpt_range_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
HintFetchRanges {
|
||||||
|
visible_range,
|
||||||
|
other_ranges: other_ranges.into_iter().map(|range| range).collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl UpdateTask {
|
impl UpdateTask {
|
||||||
fn new(invalidation_strategy: InvalidationStrategy, spawned_task: SpawnedTask) -> Self {
|
fn new(invalidation_strategy: InvalidationStrategy, spawned_task: SpawnedTask) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -427,17 +460,18 @@ fn new_update_task(
|
||||||
buffer_snapshot: BufferSnapshot,
|
buffer_snapshot: BufferSnapshot,
|
||||||
visible_hints: Arc<Vec<Inlay>>,
|
visible_hints: Arc<Vec<Inlay>>,
|
||||||
cached_excerpt_hints: Option<Arc<RwLock<CachedExcerptHints>>>,
|
cached_excerpt_hints: Option<Arc<RwLock<CachedExcerptHints>>>,
|
||||||
previous_task: Option<smol::channel::Receiver<()>>,
|
task_before_refresh: Option<smol::channel::Receiver<()>>,
|
||||||
cx: &mut ViewContext<'_, '_, Editor>,
|
cx: &mut ViewContext<'_, '_, Editor>,
|
||||||
) -> SpawnedTask {
|
) -> SpawnedTask {
|
||||||
let hints_fetch_tasks = hints_fetch_tasks(query, &buffer_snapshot, cx);
|
let hints_fetch_tasks = query.hints_fetch_ranges(&buffer_snapshot);
|
||||||
let (is_running_tx, is_running_rx) = smol::channel::bounded(1);
|
let (is_running_tx, is_running_rx) = smol::channel::bounded(1);
|
||||||
|
let is_refresh_task = task_before_refresh.is_some();
|
||||||
let _task = cx.spawn(|editor, cx| async move {
|
let _task = cx.spawn(|editor, cx| async move {
|
||||||
let _is_running_tx = is_running_tx;
|
let _is_running_tx = is_running_tx;
|
||||||
if let Some(previous_task) = previous_task {
|
if let Some(task_before_refresh) = task_before_refresh {
|
||||||
previous_task.recv().await.ok();
|
task_before_refresh.recv().await.ok();
|
||||||
}
|
}
|
||||||
let create_update_task = |range, hint_fetch_task| {
|
let create_update_task = |range| {
|
||||||
fetch_and_update_hints(
|
fetch_and_update_hints(
|
||||||
editor.clone(),
|
editor.clone(),
|
||||||
multi_buffer_snapshot.clone(),
|
multi_buffer_snapshot.clone(),
|
||||||
|
@ -446,14 +480,13 @@ fn new_update_task(
|
||||||
cached_excerpt_hints.as_ref().map(Arc::clone),
|
cached_excerpt_hints.as_ref().map(Arc::clone),
|
||||||
query,
|
query,
|
||||||
range,
|
range,
|
||||||
hint_fetch_task,
|
|
||||||
cx.clone(),
|
cx.clone(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (visible_range, visible_range_hint_fetch_task) = hints_fetch_tasks.visible_range;
|
if is_refresh_task {
|
||||||
let visible_range_has_updates =
|
let visible_range_has_updates =
|
||||||
match create_update_task(visible_range, visible_range_hint_fetch_task).await {
|
match create_update_task(hints_fetch_tasks.visible_range).await {
|
||||||
Ok(updated) => updated,
|
Ok(updated) => updated,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("inlay hint visible range update task failed: {e:#}");
|
error!("inlay hint visible range update task failed: {e:#}");
|
||||||
|
@ -462,12 +495,12 @@ fn new_update_task(
|
||||||
};
|
};
|
||||||
|
|
||||||
if visible_range_has_updates {
|
if visible_range_has_updates {
|
||||||
let other_update_results =
|
let other_update_results = futures::future::join_all(
|
||||||
futures::future::join_all(hints_fetch_tasks.other_ranges.into_iter().map(
|
hints_fetch_tasks
|
||||||
|(fetch_range, hints_fetch_task)| {
|
.other_ranges
|
||||||
create_update_task(fetch_range, hints_fetch_task)
|
.into_iter()
|
||||||
},
|
.map(create_update_task),
|
||||||
))
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
for result in other_update_results {
|
for result in other_update_results {
|
||||||
|
@ -477,6 +510,20 @@ fn new_update_task(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let task_update_results = futures::future::join_all(
|
||||||
|
std::iter::once(hints_fetch_tasks.visible_range)
|
||||||
|
.chain(hints_fetch_tasks.other_ranges.into_iter())
|
||||||
|
.map(create_update_task),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
for result in task_update_results {
|
||||||
|
if let Err(e) = result {
|
||||||
|
error!("inlay hint update task failed: {e:#}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
SpawnedTask {
|
SpawnedTask {
|
||||||
|
@ -494,12 +541,29 @@ async fn fetch_and_update_hints(
|
||||||
cached_excerpt_hints: Option<Arc<RwLock<CachedExcerptHints>>>,
|
cached_excerpt_hints: Option<Arc<RwLock<CachedExcerptHints>>>,
|
||||||
query: ExcerptQuery,
|
query: ExcerptQuery,
|
||||||
fetch_range: Range<language::Anchor>,
|
fetch_range: Range<language::Anchor>,
|
||||||
hints_fetch_task: Task<anyhow::Result<Option<Vec<InlayHint>>>>,
|
|
||||||
mut cx: gpui::AsyncAppContext,
|
mut cx: gpui::AsyncAppContext,
|
||||||
) -> anyhow::Result<bool> {
|
) -> anyhow::Result<bool> {
|
||||||
|
let inlay_hints_fetch_task = editor
|
||||||
|
.update(&mut cx, |editor, cx| {
|
||||||
|
editor
|
||||||
|
.buffer()
|
||||||
|
.read(cx)
|
||||||
|
.buffer(query.buffer_id)
|
||||||
|
.and_then(|buffer| {
|
||||||
|
let project = editor.project.as_ref()?;
|
||||||
|
Some(project.update(cx, |project, cx| {
|
||||||
|
project.inlay_hints(buffer, fetch_range.clone(), cx)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
.flatten();
|
||||||
let mut update_happened = false;
|
let mut update_happened = false;
|
||||||
match hints_fetch_task.await.context("inlay hint fetch task")? {
|
let Some(inlay_hints_fetch_task) = inlay_hints_fetch_task else { return Ok(update_happened) };
|
||||||
Some(new_hints) => {
|
|
||||||
|
let new_hints = inlay_hints_fetch_task
|
||||||
|
.await
|
||||||
|
.context("inlay hint fetch task")?;
|
||||||
let background_task_buffer_snapshot = buffer_snapshot.clone();
|
let background_task_buffer_snapshot = buffer_snapshot.clone();
|
||||||
let backround_fetch_range = fetch_range.clone();
|
let backround_fetch_range = fetch_range.clone();
|
||||||
if let Some(new_update) = cx
|
if let Some(new_update) = cx
|
||||||
|
@ -559,11 +623,9 @@ async fn fetch_and_update_hints(
|
||||||
.allowed_hint_kinds
|
.allowed_hint_kinds
|
||||||
.contains(&new_hint.kind)
|
.contains(&new_hint.kind)
|
||||||
{
|
{
|
||||||
splice.to_insert.push((
|
splice
|
||||||
new_hint_position,
|
.to_insert
|
||||||
new_inlay_id,
|
.push((new_hint_position, new_inlay_id, new_hint.clone()));
|
||||||
new_hint.clone(),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cached_excerpt_hints.hints.push((new_inlay_id, new_hint));
|
cached_excerpt_hints.hints.push((new_inlay_id, new_hint));
|
||||||
|
@ -586,9 +648,6 @@ async fn fetch_and_update_hints(
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(update_happened)
|
Ok(update_happened)
|
||||||
}
|
}
|
||||||
|
@ -713,77 +772,9 @@ fn allowed_hint_types(
|
||||||
new_allowed_hint_types
|
new_allowed_hint_types
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HintFetchTasks {
|
struct HintFetchRanges {
|
||||||
visible_range: (
|
visible_range: Range<language::Anchor>,
|
||||||
Range<language::Anchor>,
|
other_ranges: Vec<Range<language::Anchor>>,
|
||||||
Task<anyhow::Result<Option<Vec<InlayHint>>>>,
|
|
||||||
),
|
|
||||||
other_ranges: Vec<(
|
|
||||||
Range<language::Anchor>,
|
|
||||||
Task<anyhow::Result<Option<Vec<InlayHint>>>>,
|
|
||||||
)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hints_fetch_tasks(
|
|
||||||
query: ExcerptQuery,
|
|
||||||
buffer: &BufferSnapshot,
|
|
||||||
cx: &mut ViewContext<'_, '_, Editor>,
|
|
||||||
) -> HintFetchTasks {
|
|
||||||
let visible_range =
|
|
||||||
query.dimensions.excerpt_visible_range_start..query.dimensions.excerpt_visible_range_end;
|
|
||||||
let mut other_ranges = Vec::new();
|
|
||||||
if query
|
|
||||||
.dimensions
|
|
||||||
.excerpt_range_start
|
|
||||||
.cmp(&query.dimensions.excerpt_visible_range_start, buffer)
|
|
||||||
.is_lt()
|
|
||||||
{
|
|
||||||
let mut end = query.dimensions.excerpt_visible_range_start;
|
|
||||||
end.offset -= 1;
|
|
||||||
other_ranges.push(query.dimensions.excerpt_range_start..end);
|
|
||||||
}
|
|
||||||
if query
|
|
||||||
.dimensions
|
|
||||||
.excerpt_range_end
|
|
||||||
.cmp(&query.dimensions.excerpt_visible_range_end, buffer)
|
|
||||||
.is_gt()
|
|
||||||
{
|
|
||||||
let mut start = query.dimensions.excerpt_visible_range_end;
|
|
||||||
start.offset += 1;
|
|
||||||
other_ranges.push(start..query.dimensions.excerpt_range_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut query_task_for_range = |range_to_query| {
|
|
||||||
cx.spawn(|editor, mut cx| async move {
|
|
||||||
let task = editor
|
|
||||||
.update(&mut cx, |editor, cx| {
|
|
||||||
editor
|
|
||||||
.buffer()
|
|
||||||
.read(cx)
|
|
||||||
.buffer(query.buffer_id)
|
|
||||||
.and_then(|buffer| {
|
|
||||||
let project = editor.project.as_ref()?;
|
|
||||||
Some(project.update(cx, |project, cx| {
|
|
||||||
project.inlay_hints(buffer, range_to_query, cx)
|
|
||||||
}))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
.flatten();
|
|
||||||
anyhow::Ok(match task {
|
|
||||||
Some(task) => Some(task.await.context("inlays for buffer task")?),
|
|
||||||
None => None,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
HintFetchTasks {
|
|
||||||
visible_range: (visible_range.clone(), query_task_for_range(visible_range)),
|
|
||||||
other_ranges: other_ranges
|
|
||||||
.into_iter()
|
|
||||||
.map(|range| (range.clone(), query_task_for_range(range)))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contains_position(
|
fn contains_position(
|
||||||
|
|
Loading…
Reference in a new issue