Skip to content

Commit aaae3fa

Browse files
feat: better autocompletions
1 parent 1ecb7f0 commit aaae3fa

File tree

9 files changed

+438
-86
lines changed

9 files changed

+438
-86
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.

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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ impl CompletionBuilder {
1212
}
1313

1414
pub fn add_item(&mut self, item: CompletionItemWithScore) {
15-
self.items.push(item)
15+
self.items.push(item);
1616
}
1717

1818
pub fn finish(mut self) -> CompletionResult {

crates/pg_completions/src/complete.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use text_size::TextSize;
22
use tower_lsp::lsp_types::CompletionItem;
33

4-
use crate::{builder::CompletionBuilder, context::CompletionContext, providers};
4+
use crate::{builder::CompletionBuilder, context::CompletionContext, providers::complete_tables};
55

66
pub const LIMIT: usize = 50;
77

@@ -20,17 +20,10 @@ pub struct CompletionResult {
2020

2121
pub fn complete(params: CompletionParams) -> CompletionResult {
2222
let ctx = CompletionContext::new(&params);
23+
2324
let mut builder = CompletionBuilder::new();
2425

25-
if let Some(node) = ctx.ts_node {
26-
println!("{}", node.kind());
27-
match node.kind() {
28-
"relation" => providers::complete_tables(&ctx, &mut builder),
29-
_ => {}
30-
}
31-
} else {
32-
// if query emtpy, autocomplete select keywords etc?
33-
}
26+
complete_tables(&ctx, &mut builder);
3427

3528
builder.finish()
3629
}
@@ -96,16 +89,16 @@ mod tests {
9689
let test_db = get_new_test_db().await;
9790

9891
let setup = r#"
99-
create schema open;
92+
create schema customer_support;
10093
create schema private;
10194
102-
create table private.users (
95+
create table private.user_z (
10396
id serial primary key,
10497
name text,
10598
password text
10699
);
107100
108-
create table open.user_requests (
101+
create table customer_support.user_y (
109102
id serial primary key,
110103
request text,
111104
send_at timestamp with time zone
@@ -124,9 +117,13 @@ mod tests {
124117
.set_language(tree_sitter_sql::language())
125118
.expect("Error loading sql language");
126119

127-
// testing the private schema
128-
{
129-
let input = "select * from private.u";
120+
let test_cases = vec![
121+
("select * from u", "user_y"), // user_y is preferred alphanumerically
122+
("select * from private.u", "user_z"),
123+
("select * from customer_support.u", "user_y"),
124+
];
125+
126+
for (input, expected_label) in test_cases {
130127
let tree = parser.parse(input, None).unwrap();
131128

132129
let p = CompletionParams {
@@ -143,7 +140,7 @@ mod tests {
143140
let best_match = &result.items[0];
144141

145142
assert_eq!(
146-
best_match.label, "users",
143+
best_match.label, expected_label,
147144
"Does not return the expected table to autocomplete: {}",
148145
best_match.label
149146
)

0 commit comments

Comments
 (0)