editor: Cancel ongoing completion requests more eagerly (#12630)

Previously, we were:
- cancelling previous requests only after the latest one has completed
- always running the debounced documentation resolution to completion,
even when we had no need for it.

In this commit, we drop the ongoing completion requests as soon as the
new one is fired.
Fixes #5166 

Release Notes:

- Improved performance and reliability of completions in large
Typescript projects

Co-authored-by: Bennet Bo <bennet@zed.dev>
This commit is contained in:
Piotr Osiewicz 2024-06-04 12:22:01 +02:00 committed by GitHub
parent 47122a3115
commit 8e79609288
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 7 additions and 12 deletions

View file

@ -29,13 +29,9 @@ impl DebouncedDelay {
let (sender, mut receiver) = oneshot::channel::<()>();
self.cancel_channel = Some(sender);
let previous_task = self.task.take();
drop(self.task.take());
self.task = Some(cx.spawn(move |model, mut cx| async move {
let mut timer = cx.background_executor().timer(delay).fuse();
if let Some(previous_task) = previous_task {
previous_task.await;
}
futures::select_biased! {
_ = receiver => return,
_ = timer => {}

View file

@ -15,18 +15,17 @@
pub mod actions;
mod blame_entry_tooltip;
mod blink_manager;
mod debounced_delay;
pub mod display_map;
mod editor_settings;
mod element;
mod hunk_diff;
mod inlay_hint_cache;
mod debounced_delay;
mod git;
mod highlight_matching_bracket;
mod hover_links;
mod hover_popover;
mod hunk_diff;
mod indent_guides;
mod inlay_hint_cache;
mod inline_completion_provider;
pub mod items;
mod mouse_context_menu;
@ -3806,6 +3805,9 @@ impl Editor {
let id = post_inc(&mut self.next_completion_id);
let task = cx.spawn(|this, mut cx| {
async move {
this.update(&mut cx, |this, _| {
this.completion_tasks.retain(|(task_id, _)| *task_id >= id);
})?;
let completions = completions.await.log_err();
let menu = if let Some(completions) = completions {
let mut menu = CompletionsMenu {
@ -3844,7 +3846,6 @@ impl Editor {
let delay_ms = EditorSettings::get_global(cx)
.completion_documentation_secondary_query_debounce;
let delay = Duration::from_millis(delay_ms);
editor
.completion_documentation_pre_resolve_debounce
.fire_new(delay, cx, |editor, cx| {
@ -3865,8 +3866,6 @@ impl Editor {
};
this.update(&mut cx, |this, cx| {
this.completion_tasks.retain(|(task_id, _)| *task_id >= id);
let mut context_menu = this.context_menu.write();
match context_menu.as_ref() {
None => {}