Clean up completion tasks, even if they fail or return no results
This fixes a bug where leaving the completion task in `completion_tasks` could cause the Copilot suggestion to not be shown due to the LSP not successfully return a completion.
This commit is contained in:
parent
75d6b6360f
commit
d26d0ac56f
1 changed files with 53 additions and 40 deletions
|
@ -20,7 +20,7 @@ mod editor_tests;
|
||||||
pub mod test;
|
pub mod test;
|
||||||
|
|
||||||
use aho_corasick::AhoCorasick;
|
use aho_corasick::AhoCorasick;
|
||||||
use anyhow::Result;
|
use anyhow::{anyhow, Result};
|
||||||
use blink_manager::BlinkManager;
|
use blink_manager::BlinkManager;
|
||||||
use clock::ReplicaId;
|
use clock::ReplicaId;
|
||||||
use collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque};
|
use collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque};
|
||||||
|
@ -2352,53 +2352,66 @@ impl Editor {
|
||||||
let id = post_inc(&mut self.next_completion_id);
|
let id = post_inc(&mut self.next_completion_id);
|
||||||
let task = cx.spawn_weak(|this, mut cx| {
|
let task = cx.spawn_weak(|this, mut cx| {
|
||||||
async move {
|
async move {
|
||||||
let completions = completions.await?;
|
let menu = if let Some(completions) = completions.await.log_err() {
|
||||||
if completions.is_empty() {
|
let mut menu = CompletionsMenu {
|
||||||
return Ok(());
|
id,
|
||||||
}
|
initial_position: position,
|
||||||
|
match_candidates: completions
|
||||||
let mut menu = CompletionsMenu {
|
.iter()
|
||||||
id,
|
.enumerate()
|
||||||
initial_position: position,
|
.map(|(id, completion)| {
|
||||||
match_candidates: completions
|
StringMatchCandidate::new(
|
||||||
.iter()
|
id,
|
||||||
.enumerate()
|
completion.label.text[completion.label.filter_range.clone()]
|
||||||
.map(|(id, completion)| {
|
.into(),
|
||||||
StringMatchCandidate::new(
|
)
|
||||||
id,
|
})
|
||||||
completion.label.text[completion.label.filter_range.clone()].into(),
|
.collect(),
|
||||||
)
|
buffer,
|
||||||
})
|
completions: completions.into(),
|
||||||
.collect(),
|
matches: Vec::new().into(),
|
||||||
buffer,
|
selected_item: 0,
|
||||||
completions: completions.into(),
|
list: Default::default(),
|
||||||
matches: Vec::new().into(),
|
};
|
||||||
selected_item: 0,
|
menu.filter(query.as_deref(), cx.background()).await;
|
||||||
list: Default::default(),
|
if menu.matches.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(menu)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
menu.filter(query.as_deref(), cx.background()).await;
|
let this = this
|
||||||
|
.upgrade(&cx)
|
||||||
|
.ok_or_else(|| anyhow!("editor was dropped"))?;
|
||||||
|
this.update(&mut cx, |this, cx| {
|
||||||
|
this.completion_tasks.retain(|(task_id, _)| *task_id > id);
|
||||||
|
|
||||||
if let Some(this) = this.upgrade(&cx) {
|
match this.context_menu.as_ref() {
|
||||||
this.update(&mut cx, |this, cx| {
|
None => {}
|
||||||
match this.context_menu.as_ref() {
|
Some(ContextMenu::Completions(prev_menu)) => {
|
||||||
None => {}
|
if prev_menu.id > id {
|
||||||
Some(ContextMenu::Completions(prev_menu)) => {
|
return;
|
||||||
if prev_menu.id > menu.id {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => return,
|
|
||||||
}
|
}
|
||||||
|
_ => return,
|
||||||
|
}
|
||||||
|
|
||||||
this.completion_tasks.retain(|(id, _)| *id > menu.id);
|
if this.focused && menu.is_some() {
|
||||||
if this.focused && !menu.matches.is_empty() {
|
let menu = menu.unwrap();
|
||||||
this.show_context_menu(ContextMenu::Completions(menu), cx);
|
this.show_context_menu(ContextMenu::Completions(menu), cx);
|
||||||
} else if this.hide_context_menu(cx).is_none() {
|
} else if this.completion_tasks.is_empty() {
|
||||||
|
// If there are no more completion tasks and the last menu was
|
||||||
|
// empty, we should hide it. If it was already hidden, we should
|
||||||
|
// also show the copilot suggestion when available.
|
||||||
|
if this.hide_context_menu(cx).is_none() {
|
||||||
this.update_visible_copilot_suggestion(cx);
|
this.update_visible_copilot_suggestion(cx);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
Ok::<_, anyhow::Error>(())
|
Ok::<_, anyhow::Error>(())
|
||||||
}
|
}
|
||||||
.log_err()
|
.log_err()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue