Compare commits

...
Sign in to create a new pull request.

3 commits

Author SHA1 Message Date
Julia
427dd9443b zed1: Cancel completion resolution when new list (#3389)
Release Notes:

- Fixed a bug where Zed would continue to request documentation for
completion lists which were stale or no longer visible.
2023-11-22 14:24:48 -05:00
Joseph T. Lyons
3eba1baa84 v0.113.x stable 2023-11-22 12:57:14 -05:00
Joseph T. Lyons
6798b949f1 v0.113.x preview 2023-11-15 12:47:19 -05:00
2 changed files with 32 additions and 21 deletions

View file

@ -1001,17 +1001,18 @@ impl CompletionsMenu {
fn pre_resolve_completion_documentation( fn pre_resolve_completion_documentation(
&self, &self,
project: Option<ModelHandle<Project>>, editor: &Editor,
cx: &mut ViewContext<Editor>, cx: &mut ViewContext<Editor>,
) { ) -> Option<Task<()>> {
let settings = settings::get::<EditorSettings>(cx); let settings = settings::get::<EditorSettings>(cx);
if !settings.show_completion_documentation { if !settings.show_completion_documentation {
return; return None;
} }
let Some(project) = project else { let Some(project) = editor.project.clone() else {
return; return None;
}; };
let client = project.read(cx).client(); let client = project.read(cx).client();
let language_registry = project.read(cx).languages().clone(); let language_registry = project.read(cx).languages().clone();
@ -1021,7 +1022,7 @@ impl CompletionsMenu {
let completions = self.completions.clone(); let completions = self.completions.clone();
let completion_indices: Vec<_> = self.matches.iter().map(|m| m.candidate_id).collect(); let completion_indices: Vec<_> = self.matches.iter().map(|m| m.candidate_id).collect();
cx.spawn(move |this, mut cx| async move { Some(cx.spawn(move |this, mut cx| async move {
if is_remote { if is_remote {
let Some(project_id) = project_id else { let Some(project_id) = project_id else {
log::error!("Remote project without remote_id"); log::error!("Remote project without remote_id");
@ -1083,8 +1084,7 @@ impl CompletionsMenu {
_ = this.update(&mut cx, |_, cx| cx.notify()); _ = this.update(&mut cx, |_, cx| cx.notify());
} }
} }
}) }))
.detach();
} }
fn attempt_resolve_selected_completion_documentation( fn attempt_resolve_selected_completion_documentation(
@ -3580,7 +3580,8 @@ impl Editor {
let id = post_inc(&mut self.next_completion_id); let id = post_inc(&mut self.next_completion_id);
let task = cx.spawn(|this, mut cx| { let task = cx.spawn(|this, mut cx| {
async move { async move {
let menu = if let Some(completions) = completions.await.log_err() { let completions = completions.await.log_err();
let (menu, pre_resolve_task) = if let Some(completions) = completions {
let mut menu = CompletionsMenu { let mut menu = CompletionsMenu {
id, id,
initial_position: position, initial_position: position,
@ -3601,21 +3602,26 @@ impl Editor {
selected_item: 0, selected_item: 0,
list: Default::default(), list: Default::default(),
}; };
menu.filter(query.as_deref(), cx.background()).await; menu.filter(query.as_deref(), cx.background()).await;
if menu.matches.is_empty() { if menu.matches.is_empty() {
None (None, None)
} else { } else {
_ = this.update(&mut cx, |editor, cx| { let pre_resolve_task = this
menu.pre_resolve_completion_documentation(editor.project.clone(), cx); .update(&mut cx, |editor, cx| {
}); menu.pre_resolve_completion_documentation(editor, cx)
Some(menu) })
.ok()
.flatten();
(Some(menu), pre_resolve_task)
} }
} else { } else {
None (None, None)
}; };
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
this.completion_tasks.retain(|(task_id, _)| *task_id > id); this.completion_tasks.retain(|(task_id, _)| *task_id >= id);
let mut context_menu = this.context_menu.write(); let mut context_menu = this.context_menu.write();
match context_menu.as_ref() { match context_menu.as_ref() {
@ -3636,10 +3642,10 @@ impl Editor {
drop(context_menu); drop(context_menu);
this.discard_copilot_suggestion(cx); this.discard_copilot_suggestion(cx);
cx.notify(); cx.notify();
} else if this.completion_tasks.is_empty() { } else if this.completion_tasks.len() <= 1 {
// If there are no more completion tasks and the last menu was // If there are no more completion tasks (omitting ourself) and
// empty, we should hide it. If it was already hidden, we should // the last menu was empty, we should hide it. If it was already
// also show the copilot suggestion when available. // hidden, we should also show the copilot suggestion when available.
drop(context_menu); drop(context_menu);
if this.hide_context_menu(cx).is_none() { if this.hide_context_menu(cx).is_none() {
this.update_visible_copilot_suggestion(cx); this.update_visible_copilot_suggestion(cx);
@ -3647,10 +3653,15 @@ impl Editor {
} }
})?; })?;
if let Some(pre_resolve_task) = pre_resolve_task {
pre_resolve_task.await;
}
Ok::<_, anyhow::Error>(()) Ok::<_, anyhow::Error>(())
} }
.log_err() .log_err()
}); });
self.completion_tasks.push((id, task)); self.completion_tasks.push((id, task));
} }

View file

@ -1 +1 @@
dev stable