Maintain inline completion order, simplifying how we track pending completions (#21977)
Release Notes: - N/A
This commit is contained in:
parent
306f1c6838
commit
01e5ac0a49
3 changed files with 34 additions and 16 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -16424,6 +16424,7 @@ name = "zeta"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"arrayvec",
|
||||||
"call",
|
"call",
|
||||||
"client",
|
"client",
|
||||||
"clock",
|
"clock",
|
||||||
|
|
|
@ -18,6 +18,7 @@ test-support = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
|
arrayvec.workspace = true
|
||||||
client.workspace = true
|
client.workspace = true
|
||||||
collections.workspace = true
|
collections.workspace = true
|
||||||
editor.workspace = true
|
editor.workspace = true
|
||||||
|
|
|
@ -3,6 +3,7 @@ mod rate_completion_modal;
|
||||||
pub use rate_completion_modal::*;
|
pub use rate_completion_modal::*;
|
||||||
|
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
|
use arrayvec::ArrayVec;
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use collections::{HashMap, HashSet, VecDeque};
|
use collections::{HashMap, HashSet, VecDeque};
|
||||||
use futures::AsyncReadExt;
|
use futures::AsyncReadExt;
|
||||||
|
@ -899,10 +900,15 @@ impl CurrentInlineCompletion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PendingCompletion {
|
||||||
|
id: usize,
|
||||||
|
_task: Task<Result<()>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ZetaInlineCompletionProvider {
|
pub struct ZetaInlineCompletionProvider {
|
||||||
zeta: Model<Zeta>,
|
zeta: Model<Zeta>,
|
||||||
first_pending_completion: Option<Task<Result<()>>>,
|
pending_completions: ArrayVec<PendingCompletion, 2>,
|
||||||
last_pending_completion: Option<Task<Result<()>>>,
|
next_pending_completion_id: usize,
|
||||||
current_completion: Option<CurrentInlineCompletion>,
|
current_completion: Option<CurrentInlineCompletion>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,8 +918,8 @@ impl ZetaInlineCompletionProvider {
|
||||||
pub fn new(zeta: Model<Zeta>) -> Self {
|
pub fn new(zeta: Model<Zeta>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
zeta,
|
zeta,
|
||||||
first_pending_completion: None,
|
pending_completions: ArrayVec::new(),
|
||||||
last_pending_completion: None,
|
next_pending_completion_id: 0,
|
||||||
current_completion: None,
|
current_completion: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -944,7 +950,9 @@ impl inline_completion::InlineCompletionProvider for ZetaInlineCompletionProvide
|
||||||
debounce: bool,
|
debounce: bool,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) {
|
) {
|
||||||
let is_first = self.first_pending_completion.is_none();
|
let pending_completion_id = self.next_pending_completion_id;
|
||||||
|
self.next_pending_completion_id += 1;
|
||||||
|
|
||||||
let task = cx.spawn(|this, mut cx| async move {
|
let task = cx.spawn(|this, mut cx| async move {
|
||||||
if debounce {
|
if debounce {
|
||||||
cx.background_executor().timer(Self::DEBOUNCE_TIMEOUT).await;
|
cx.background_executor().timer(Self::DEBOUNCE_TIMEOUT).await;
|
||||||
|
@ -965,9 +973,10 @@ impl inline_completion::InlineCompletionProvider for ZetaInlineCompletionProvide
|
||||||
}
|
}
|
||||||
|
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
this.first_pending_completion = None;
|
if this.pending_completions[0].id == pending_completion_id {
|
||||||
if !is_first {
|
this.pending_completions.remove(0);
|
||||||
this.last_pending_completion = None;
|
} else {
|
||||||
|
this.pending_completions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(new_completion) = completion {
|
if let Some(new_completion) = completion {
|
||||||
|
@ -993,10 +1002,19 @@ impl inline_completion::InlineCompletionProvider for ZetaInlineCompletionProvide
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if is_first {
|
// We always maintain at most two pending completions. When we already
|
||||||
self.first_pending_completion = Some(task);
|
// have two, we replace the newest one.
|
||||||
} else {
|
if self.pending_completions.len() <= 1 {
|
||||||
self.last_pending_completion = Some(task);
|
self.pending_completions.push(PendingCompletion {
|
||||||
|
id: pending_completion_id,
|
||||||
|
_task: task,
|
||||||
|
});
|
||||||
|
} else if self.pending_completions.len() == 2 {
|
||||||
|
self.pending_completions.pop();
|
||||||
|
self.pending_completions.push(PendingCompletion {
|
||||||
|
id: pending_completion_id,
|
||||||
|
_task: task,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1011,13 +1029,11 @@ impl inline_completion::InlineCompletionProvider for ZetaInlineCompletionProvide
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept(&mut self, _cx: &mut ModelContext<Self>) {
|
fn accept(&mut self, _cx: &mut ModelContext<Self>) {
|
||||||
self.first_pending_completion.take();
|
self.pending_completions.clear();
|
||||||
self.last_pending_completion.take();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn discard(&mut self, _cx: &mut ModelContext<Self>) {
|
fn discard(&mut self, _cx: &mut ModelContext<Self>) {
|
||||||
self.first_pending_completion.take();
|
self.pending_completions.clear();
|
||||||
self.last_pending_completion.take();
|
|
||||||
self.current_completion.take();
|
self.current_completion.take();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue