|
1 | | -use crate::{CompletionItem, CompletionResult}; |
| 1 | +use crate::{item::CompletionItem, CompletionResult}; |
2 | 2 |
|
3 | | -pub struct CompletionBuilder<'a> { |
4 | | - pub items: Vec<CompletionItem<'a>>, |
| 3 | +pub(crate) struct CompletionBuilder { |
| 4 | + items: Vec<CompletionItem>, |
5 | 5 | } |
6 | 6 |
|
7 | | -pub struct CompletionConfig {} |
| 7 | +impl CompletionBuilder { |
| 8 | + pub fn new() -> Self { |
| 9 | + CompletionBuilder { items: vec![] } |
| 10 | + } |
8 | 11 |
|
9 | | -impl<'a> From<&'a CompletionConfig> for CompletionBuilder<'a> { |
10 | | - fn from(_config: &CompletionConfig) -> Self { |
11 | | - Self { items: Vec::new() } |
| 12 | + pub fn add_item(&mut self, item: CompletionItem) { |
| 13 | + self.items.push(item); |
12 | 14 | } |
13 | | -} |
14 | 15 |
|
15 | | -impl<'a> CompletionBuilder<'a> { |
16 | | - pub fn finish(mut self) -> CompletionResult<'a> { |
17 | | - self.items.sort_by(|a, b| { |
18 | | - b.preselect |
19 | | - .cmp(&a.preselect) |
20 | | - .then_with(|| b.score.cmp(&a.score)) |
21 | | - .then_with(|| a.data.label().cmp(b.data.label())) |
22 | | - }); |
| 16 | + pub fn finish(mut self) -> CompletionResult { |
| 17 | + self.items |
| 18 | + .sort_by(|a, b| b.score.cmp(&a.score).then_with(|| a.label.cmp(&b.label))); |
23 | 19 |
|
24 | | - self.items.dedup_by(|a, b| a.data.label() == b.data.label()); |
| 20 | + self.items.dedup_by(|a, b| a.label == b.label); |
25 | 21 | self.items.truncate(crate::LIMIT); |
26 | | - let Self { items, .. } = self; |
| 22 | + |
| 23 | + let should_preselect_first_item = self.should_preselect_first_item(); |
| 24 | + |
| 25 | + let items: Vec<CompletionItem> = self |
| 26 | + .items |
| 27 | + .into_iter() |
| 28 | + .enumerate() |
| 29 | + .map(|(idx, mut item)| { |
| 30 | + if idx == 0 { |
| 31 | + item.preselected = Some(should_preselect_first_item); |
| 32 | + } |
| 33 | + item.into() |
| 34 | + }) |
| 35 | + .collect(); |
| 36 | + |
27 | 37 | CompletionResult { items } |
28 | 38 | } |
| 39 | + |
| 40 | + fn should_preselect_first_item(&mut self) -> bool { |
| 41 | + let mut items_iter = self.items.iter(); |
| 42 | + let first = items_iter.next(); |
| 43 | + let second = items_iter.next(); |
| 44 | + |
| 45 | + first.is_some_and(|f| match second { |
| 46 | + Some(s) => (f.score - s.score) > 10, |
| 47 | + None => true, |
| 48 | + }) |
| 49 | + } |
29 | 50 | } |
0 commit comments