Skip to content

Commit 1ecb7f0

Browse files
ok
1 parent 99c1463 commit 1ecb7f0

File tree

4 files changed

+61
-34
lines changed

4 files changed

+61
-34
lines changed

crates/pg_completions/src/builder.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,55 @@
1-
use crate::{item::CompletionItemWithRelevance, CompletionResult};
1+
use tower_lsp::lsp_types::CompletionItem;
2+
3+
use crate::{item::CompletionItemWithScore, CompletionResult};
24

35
pub(crate) struct CompletionBuilder {
4-
items: Vec<CompletionItemWithRelevance>,
6+
items: Vec<CompletionItemWithScore>,
57
}
68

79
impl CompletionBuilder {
810
pub fn new() -> Self {
911
CompletionBuilder { items: vec![] }
1012
}
1113

12-
pub fn add_item(&mut self, item: CompletionItemWithRelevance) {
14+
pub fn add_item(&mut self, item: CompletionItemWithScore) {
1315
self.items.push(item)
1416
}
1517

1618
pub fn finish(mut self) -> CompletionResult {
1719
self.items.sort_by(|a, b| {
18-
b.score()
19-
.cmp(&a.score())
20+
b.score
21+
.cmp(&a.score)
2022
.then_with(|| a.label().cmp(&b.label()))
2123
});
2224

2325
self.items.dedup_by(|a, b| a.label() == b.label());
2426
self.items.truncate(crate::LIMIT);
2527

26-
let Self { items, .. } = self;
28+
let should_preselect_first_item = self.should_preselect_first_item();
29+
30+
let items: Vec<CompletionItem> = self
31+
.items
32+
.into_iter()
33+
.enumerate()
34+
.map(|(idx, mut item)| {
35+
if idx == 0 {
36+
item.set_preselected(should_preselect_first_item);
37+
}
38+
item.into()
39+
})
40+
.collect();
2741

2842
CompletionResult { items }
2943
}
44+
45+
fn should_preselect_first_item(&mut self) -> bool {
46+
let mut items_iter = self.items.iter();
47+
let first = items_iter.next();
48+
let second = items_iter.next();
49+
50+
first.is_some_and(|f| match second {
51+
Some(s) => (f.score - s.score) > 10,
52+
None => true,
53+
})
54+
}
3055
}

crates/pg_completions/src/complete.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
use text_size::TextSize;
2+
use tower_lsp::lsp_types::CompletionItem;
23

3-
use crate::{
4-
builder::CompletionBuilder, context::CompletionContext, item::CompletionItemWithRelevance,
5-
providers,
6-
};
4+
use crate::{builder::CompletionBuilder, context::CompletionContext, providers};
75

86
pub const LIMIT: usize = 50;
97

@@ -17,14 +15,15 @@ pub struct CompletionParams<'a> {
1715

1816
#[derive(Debug, Default)]
1917
pub struct CompletionResult {
20-
pub items: Vec<CompletionItemWithRelevance>,
18+
pub items: Vec<CompletionItem>,
2119
}
2220

2321
pub fn complete(params: CompletionParams) -> CompletionResult {
2422
let ctx = CompletionContext::new(&params);
2523
let mut builder = CompletionBuilder::new();
2624

2725
if let Some(node) = ctx.ts_node {
26+
println!("{}", node.kind());
2827
match node.kind() {
2928
"relation" => providers::complete_tables(&ctx, &mut builder),
3029
_ => {}
@@ -92,11 +91,12 @@ mod tests {
9291
)
9392
}
9493

94+
#[tokio::test]
9595
async fn autocompletes_table_with_schema() {
9696
let test_db = get_new_test_db().await;
9797

9898
let setup = r#"
99-
create schema public;
99+
create schema open;
100100
create schema private;
101101
102102
create table private.users (
@@ -105,7 +105,7 @@ mod tests {
105105
password text
106106
);
107107
108-
create table public.user_requests (
108+
create table open.user_requests (
109109
id serial primary key,
110110
request text,
111111
send_at timestamp with time zone

crates/pg_completions/src/item.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
1-
use tower_lsp::lsp_types;
1+
use tower_lsp::lsp_types::{self, CompletionItem};
22

33
use crate::{data::CompletionItemData, relevance::CompletionRelevance};
44

55
#[derive(Debug)]
6-
pub struct CompletionItemWithRelevance {
7-
item: lsp_types::CompletionItem,
8-
relevance: CompletionRelevance,
6+
pub struct CompletionItemWithScore {
7+
pub item: lsp_types::CompletionItem,
8+
pub score: i32,
99
}
1010

11-
impl CompletionItemWithRelevance {
11+
impl CompletionItemWithScore {
1212
pub(crate) fn new(data: CompletionItemData, relevance: CompletionRelevance) -> Self {
1313
Self {
1414
item: data.into(),
15-
relevance,
15+
score: relevance.score(),
1616
}
1717
}
1818

19-
pub(crate) fn score(&self) -> i32 {
20-
self.relevance.score()
21-
}
22-
2319
pub(crate) fn label(&self) -> &str {
2420
&self.item.label
2521
}
22+
23+
pub(crate) fn set_preselected(&mut self, is_preselected: bool) {
24+
self.item.preselect = Some(is_preselected)
25+
}
26+
}
27+
28+
impl Into<CompletionItem> for CompletionItemWithScore {
29+
fn into(self) -> CompletionItem {
30+
self.item
31+
}
2632
}
Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
1-
use pg_schema_cache::Table;
2-
31
use crate::{
42
builder::CompletionBuilder, context::CompletionContext, data::CompletionItemData,
5-
item::CompletionItemWithRelevance, relevance::CompletionRelevance,
3+
item::CompletionItemWithScore, relevance::CompletionRelevance,
64
};
75

86
pub fn complete_tables(ctx: &CompletionContext, builder: &mut CompletionBuilder) {
97
let available_tables = &ctx.schema_cache.tables;
108

11-
let completion_items: Vec<CompletionItemWithRelevance> = available_tables
9+
let completion_items: Vec<CompletionItemWithScore> = available_tables
1210
.iter()
13-
.map(|table| to_completion_item(ctx, table))
11+
.map(|table| {
12+
let data = CompletionItemData::Table(table);
13+
let relevance = CompletionRelevance::from_data_and_ctx(&data, ctx);
14+
CompletionItemWithScore::new(data, relevance)
15+
})
1416
.collect();
1517

1618
for item in completion_items {
1719
builder.add_item(item);
1820
}
1921
}
20-
21-
fn to_completion_item(ctx: &CompletionContext, table: &Table) -> CompletionItemWithRelevance {
22-
let data = CompletionItemData::Table(table);
23-
let relevance = CompletionRelevance::from_data_and_ctx(&data, ctx);
24-
CompletionItemWithRelevance::new(data, relevance)
25-
}

0 commit comments

Comments
 (0)