Skip to content

Commit b356e92

Browse files
authored
Merge pull request #150 from juleswritescode/completions/table-names
2 parents d994149 + e37202f commit b356e92

File tree

18 files changed

+815
-267
lines changed

18 files changed

+815
-267
lines changed

Cargo.lock

Lines changed: 116 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ line_index = { path = "./lib/line_index", version = "0.0.0" }
1717
tree_sitter_sql = { path = "./lib/tree_sitter_sql", version = "0.0.0" }
1818
tree-sitter = "0.20.10"
1919
tracing = "0.1.40"
20+
tower-lsp = "0.20.0"
2021
sqlx = { version = "0.8.2", features = [ "runtime-async-std", "tls-rustls", "postgres", "json" ] }
2122

2223
# postgres specific crates

crates/pg_completions/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Auto-Completions
2+
3+
## What does this crate do?
4+
5+
The `pg_completions` identifies and ranks autocompletion items that can be displayed in your code editor.
6+
Its main export is the `complete` function. The function takes a PostgreSQL statement, a cursor position, and a datastructure representing the underlying databases schema. It returns a list of completion items.
7+
8+
Postgres's statement-parsing-engine, `libpg_query`, which is used in other parts of this LSP, is only capable of parsing _complete and valid_ statements. Since autocompletion should work for incomplete statements, we rely heavily on tree-sitter – an incremental parsing library.
9+
10+
### Working with TreeSitter
11+
12+
In the `pg_test_utils` crate, there's a binary that parses an SQL file and prints out the matching tree-sitter tree.
13+
This makes writing tree-sitter queries for this crate easy.
14+
15+
To print a tree, run `cargo run --bin tree_print -- -f <your_sql_file>`.

crates/pg_completions/src/builder.rs

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,50 @@
1-
use crate::{CompletionItem, CompletionResult};
1+
use crate::{item::CompletionItem, CompletionResult};
22

3-
pub struct CompletionBuilder<'a> {
4-
pub items: Vec<CompletionItem<'a>>,
3+
pub(crate) struct CompletionBuilder {
4+
items: Vec<CompletionItem>,
55
}
66

7-
pub struct CompletionConfig {}
7+
impl CompletionBuilder {
8+
pub fn new() -> Self {
9+
CompletionBuilder { items: vec![] }
10+
}
811

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);
1214
}
13-
}
1415

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)));
2319

24-
self.items.dedup_by(|a, b| a.data.label() == b.data.label());
20+
self.items.dedup_by(|a, b| a.label == b.label);
2521
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+
2737
CompletionResult { items }
2838
}
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+
}
2950
}

0 commit comments

Comments
 (0)