Skip to content

Commit a2e4640

Browse files
feat(completions): nicer function completions (#401)
1 parent 7ffbca6 commit a2e4640

File tree

6 files changed

+55
-8
lines changed

6 files changed

+55
-8
lines changed

crates/pgt_completions/src/item.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub struct CompletionText {
4141
/// others naively insert the text.
4242
/// Having a range where start == end makes it an insertion.
4343
pub range: TextRange,
44+
45+
pub is_snippet: bool,
4446
}
4547

4648
#[derive(Debug, Serialize, Deserialize)]

crates/pgt_completions/src/providers/functions.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
use pgt_schema_cache::Function;
2+
13
use crate::{
2-
CompletionItemKind,
4+
CompletionItemKind, CompletionText,
35
builder::{CompletionBuilder, PossibleCompletionItem},
46
context::CompletionContext,
7+
providers::helper::get_range_to_replace,
58
relevance::{CompletionRelevanceData, filtering::CompletionFilter, scoring::CompletionScore},
69
};
710

@@ -19,17 +22,46 @@ pub fn complete_functions<'a>(ctx: &'a CompletionContext, builder: &mut Completi
1922
filter: CompletionFilter::from(relevance),
2023
description: format!("Schema: {}", func.schema),
2124
kind: CompletionItemKind::Function,
22-
completion_text: get_completion_text_with_schema_or_alias(
23-
ctx,
24-
&func.name,
25-
&func.schema,
26-
),
25+
completion_text: Some(get_completion_text(ctx, func)),
2726
};
2827

2928
builder.add_item(item);
3029
}
3130
}
3231

32+
fn get_completion_text(ctx: &CompletionContext, func: &Function) -> CompletionText {
33+
let range = get_range_to_replace(ctx);
34+
let mut text = get_completion_text_with_schema_or_alias(ctx, &func.name, &func.schema)
35+
.map(|ct| ct.text)
36+
.unwrap_or(func.name.to_string());
37+
38+
if ctx.is_invocation {
39+
CompletionText {
40+
text,
41+
range,
42+
is_snippet: false,
43+
}
44+
} else {
45+
text.push('(');
46+
47+
let num_args = func.args.args.len();
48+
for (idx, arg) in func.args.args.iter().enumerate() {
49+
text.push_str(format!(r#"${{{}:{}}}"#, idx + 1, arg.name).as_str());
50+
if idx < num_args - 1 {
51+
text.push_str(", ");
52+
}
53+
}
54+
55+
text.push(')');
56+
57+
CompletionText {
58+
text,
59+
range,
60+
is_snippet: num_args > 0,
61+
}
62+
}
63+
}
64+
3365
#[cfg(test)]
3466
mod tests {
3567
use crate::{

crates/pgt_completions/src/providers/helper.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,17 @@ pub(crate) fn get_completion_text_with_schema_or_alias(
3434
item_name: &str,
3535
schema_or_alias_name: &str,
3636
) -> Option<CompletionText> {
37-
if schema_or_alias_name == "public" || ctx.schema_or_alias_name.is_some() {
37+
let is_already_prefixed_with_schema_name = ctx.schema_or_alias_name.is_some();
38+
39+
if schema_or_alias_name == "public" || is_already_prefixed_with_schema_name {
3840
None
3941
} else {
4042
let range = get_range_to_replace(ctx);
4143

4244
Some(CompletionText {
4345
text: format!("{}.{}", schema_or_alias_name, item_name),
4446
range,
47+
is_snippet: false,
4548
})
4649
}
4750
}

crates/pgt_completions/src/providers/policies.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub fn complete_policies<'a>(ctx: &CompletionContext<'a>, builder: &mut Completi
2525
let range = get_range_to_replace(ctx);
2626
Some(CompletionText {
2727
text: pol.name.clone(),
28+
is_snippet: false,
2829
range: TextRange::new(
2930
range.start() + TextSize::new(1),
3031
range.end() - TextSize::new(1),
@@ -34,6 +35,7 @@ pub fn complete_policies<'a>(ctx: &CompletionContext<'a>, builder: &mut Completi
3435
// If we aren't within quotes, we want to complete the
3536
// full policy including quotation marks.
3637
Some(CompletionText {
38+
is_snippet: false,
3739
text: format!("\"{}\"", pol.name),
3840
range: get_range_to_replace(ctx),
3941
})

crates/pgt_lsp/src/handlers/completions.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ use crate::{
55
};
66
use anyhow::Result;
77
use pgt_workspace::{WorkspaceError, features::completions::GetCompletionsParams};
8-
use tower_lsp::lsp_types::{self, CompletionItem, CompletionItemLabelDetails, TextEdit};
8+
use tower_lsp::lsp_types::{
9+
self, CompletionItem, CompletionItemLabelDetails, InsertTextFormat, TextEdit,
10+
};
911

1012
#[tracing::instrument(level = "debug", skip(session), err)]
1113
pub fn get_completions(
@@ -43,6 +45,11 @@ pub fn get_completions(
4345
}),
4446
preselect: Some(i.preselected),
4547
sort_text: Some(i.sort_text),
48+
insert_text_format: if i.completion_text.as_ref().is_some_and(|c| c.is_snippet) {
49+
Some(InsertTextFormat::SNIPPET)
50+
} else {
51+
Some(InsertTextFormat::PLAIN_TEXT)
52+
},
4653
text_edit: i.completion_text.map(|c| {
4754
lsp_types::CompletionTextEdit::Edit(TextEdit {
4855
new_text: c.text,

crates/pgt_workspace/src/workspace/server/sql_function.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub struct SQLFunctionArg {
1515

1616
#[derive(Debug, Clone)]
1717
pub struct SQLFunctionSignature {
18+
#[allow(dead_code)]
1819
pub schema: Option<String>,
1920
pub name: String,
2021
pub args: Vec<SQLFunctionArg>,

0 commit comments

Comments
 (0)