Skip to content

Commit ad22ef5

Browse files
feat(compl): complete in (simple) function bodies (#426)
1 parent 513c73c commit ad22ef5

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

crates/pgt_workspace/src/features/completions.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,24 @@ pub(crate) fn get_statement_for_completions(
4949
if count == 1 {
5050
eligible_statements.next()
5151
} else {
52-
let mut prev_stmt = None;
52+
let mut prev_stmt: Option<(StatementId, TextRange, String, Arc<tree_sitter::Tree>)> = None;
5353

5454
for current_stmt in eligible_statements {
5555
/*
5656
* If we have multiple statements, we want to make sure that we do not overlap
5757
* with the next one.
5858
*
5959
* select 1 |select 1;
60+
*
61+
* This is however ok if the current statement is a child of the previous one,
62+
* such as in CREATE FUNCTION bodies.
6063
*/
61-
if prev_stmt.is_some_and(|_| current_stmt.1.contains(position)) {
64+
if prev_stmt.is_some_and(|prev| {
65+
current_stmt.1.contains(position) && !current_stmt.0.is_child_of(&prev.0)
66+
}) {
6267
return None;
6368
}
69+
6470
prev_stmt = Some(current_stmt)
6571
}
6672

@@ -162,6 +168,30 @@ mod tests {
162168
assert_eq!(text, "select * from")
163169
}
164170

171+
#[test]
172+
fn identifies_nested_stmts() {
173+
let sql = format!(
174+
r#"
175+
create or replace function one()
176+
returns integer
177+
language sql
178+
as $$
179+
select {} from cool;
180+
$$;
181+
"#,
182+
CURSOR_POSITION
183+
);
184+
185+
let sql = sql.trim();
186+
187+
let (doc, position) = get_doc_and_pos(sql);
188+
189+
let (_, _, text, _) =
190+
get_statement_for_completions(&doc, position).expect("Expected Statement");
191+
192+
assert_eq!(text.trim(), "select from cool;")
193+
}
194+
165195
#[test]
166196
fn does_not_consider_too_far_offset() {
167197
let sql = format!("select * from {}", CURSOR_POSITION);

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ impl StatementId {
6666
matches!(self, StatementId::Child(_))
6767
}
6868

69+
pub fn is_child_of(&self, maybe_parent: &StatementId) -> bool {
70+
match self {
71+
StatementId::Root(_) => false,
72+
StatementId::Child(child_root) => match maybe_parent {
73+
StatementId::Root(parent_rood) => child_root == parent_rood,
74+
// TODO: can we have multiple nested statements?
75+
StatementId::Child(_) => false,
76+
},
77+
}
78+
}
79+
6980
pub fn parent(&self) -> Option<StatementId> {
7081
match self {
7182
StatementId::Root(_) => None,

0 commit comments

Comments
 (0)