Maintain inline completion order, simplifying how we track pending completions (#21977)

Release Notes:

- N/A
This commit is contained in:
Antonio Scandurra 2024-12-13 17:24:07 +01:00 committed by GitHub
parent 306f1c6838
commit 01e5ac0a49
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 16 deletions

1
Cargo.lock generated
View file

@ -16424,6 +16424,7 @@ name = "zeta"
version = "0.1.0"
dependencies = [
"anyhow",
"arrayvec",
"call",
"client",
"clock",

View file

@ -18,6 +18,7 @@ test-support = []
[dependencies]
anyhow.workspace = true
arrayvec.workspace = true
client.workspace = true
collections.workspace = true
editor.workspace = true

View file

@ -3,6 +3,7 @@ mod rate_completion_modal;
pub use rate_completion_modal::*;
use anyhow::{anyhow, Context as _, Result};
use arrayvec::ArrayVec;
use client::Client;
use collections::{HashMap, HashSet, VecDeque};
use futures::AsyncReadExt;
@ -899,10 +900,15 @@ impl CurrentInlineCompletion {
}
}
struct PendingCompletion {
id: usize,
_task: Task<Result<()>>,
}
pub struct ZetaInlineCompletionProvider {
zeta: Model<Zeta>,
first_pending_completion: Option<Task<Result<()>>>,
last_pending_completion: Option<Task<Result<()>>>,
pending_completions: ArrayVec<PendingCompletion, 2>,
next_pending_completion_id: usize,
current_completion: Option<CurrentInlineCompletion>,
}
@ -912,8 +918,8 @@ impl ZetaInlineCompletionProvider {
pub fn new(zeta: Model<Zeta>) -> Self {
Self {
zeta,
first_pending_completion: None,
last_pending_completion: None,
pending_completions: ArrayVec::new(),
next_pending_completion_id: 0,
current_completion: None,
}
}
@ -944,7 +950,9 @@ impl inline_completion::InlineCompletionProvider for ZetaInlineCompletionProvide
debounce: bool,
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 {
if debounce {
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.first_pending_completion = None;
if !is_first {
this.last_pending_completion = None;
if this.pending_completions[0].id == pending_completion_id {
this.pending_completions.remove(0);
} else {
this.pending_completions.clear();
}
if let Some(new_completion) = completion {
@ -993,10 +1002,19 @@ impl inline_completion::InlineCompletionProvider for ZetaInlineCompletionProvide
})
});
if is_first {
self.first_pending_completion = Some(task);
} else {
self.last_pending_completion = Some(task);
// We always maintain at most two pending completions. When we already
// have two, we replace the newest one.
if self.pending_completions.len() <= 1 {
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>) {
self.first_pending_completion.take();
self.last_pending_completion.take();
self.pending_completions.clear();
}
fn discard(&mut self, _cx: &mut ModelContext<Self>) {
self.first_pending_completion.take();
self.last_pending_completion.take();
self.pending_completions.clear();
self.current_completion.take();
}