@@ -4,7 +4,7 @@ use pgt_treesitter::TreesitterContext;
4
4
use crate :: {
5
5
CompletionItemKind , CompletionText ,
6
6
builder:: { CompletionBuilder , PossibleCompletionItem } ,
7
- providers:: helper:: get_range_to_replace,
7
+ providers:: helper:: { get_range_to_replace, node_text_surrounded_by_quotes , only_leading_quote } ,
8
8
relevance:: { CompletionRelevanceData , filtering:: CompletionFilter , scoring:: CompletionScore } ,
9
9
} ;
10
10
@@ -37,7 +37,7 @@ pub fn complete_functions<'a>(
37
37
fn get_completion_text ( ctx : & TreesitterContext , func : & Function ) -> CompletionText {
38
38
let mut text = with_schema_or_alias ( ctx, func. name . as_str ( ) , Some ( func. schema . as_str ( ) ) ) ;
39
39
40
- let range = get_range_to_replace ( ctx) ;
40
+ let mut range = get_range_to_replace ( ctx) ;
41
41
42
42
if ctx. is_invocation {
43
43
CompletionText {
@@ -46,6 +46,11 @@ fn get_completion_text(ctx: &TreesitterContext, func: &Function) -> CompletionTe
46
46
is_snippet : false ,
47
47
}
48
48
} else {
49
+ if node_text_surrounded_by_quotes ( ctx) && !only_leading_quote ( ctx) {
50
+ text. push ( '"' ) ;
51
+ range = range. checked_expand_end ( 1 . into ( ) ) . unwrap_or ( range) ;
52
+ }
53
+
49
54
text. push ( '(' ) ;
50
55
51
56
let num_args = func. args . args . len ( ) ;
@@ -68,6 +73,7 @@ fn get_completion_text(ctx: &TreesitterContext, func: &Function) -> CompletionTe
68
73
69
74
#[ cfg( test) ]
70
75
mod tests {
76
+ use pgt_text_size:: TextRange ;
71
77
use sqlx:: { Executor , PgPool } ;
72
78
73
79
use crate :: {
@@ -294,4 +300,68 @@ mod tests {
294
300
)
295
301
. await ;
296
302
}
303
+
304
+ #[ sqlx:: test( migrator = "pgt_test_utils::MIGRATIONS" ) ]
305
+ async fn autocompletes_after_schema_in_quotes ( pool : PgPool ) {
306
+ let setup = r#"
307
+ create schema auth;
308
+
309
+ create or replace function auth.my_cool_foo()
310
+ returns trigger
311
+ language plpgsql
312
+ security invoker
313
+ as $$
314
+ begin
315
+ raise exception 'dont matter';
316
+ end;
317
+ $$;
318
+ "# ;
319
+
320
+ pool. execute ( setup) . await . unwrap ( ) ;
321
+
322
+ assert_complete_results (
323
+ format ! (
324
+ r#"select "auth".{}"# ,
325
+ QueryWithCursorPosition :: cursor_marker( )
326
+ )
327
+ . as_str ( ) ,
328
+ vec ! [ CompletionAssertion :: CompletionTextAndRange (
329
+ "my_cool_foo()" . into( ) ,
330
+ TextRange :: new( 14 . into( ) , 14 . into( ) ) ,
331
+ ) ] ,
332
+ None ,
333
+ & pool,
334
+ )
335
+ . await ;
336
+
337
+ assert_complete_results (
338
+ format ! (
339
+ r#"select "auth"."{}"# ,
340
+ QueryWithCursorPosition :: cursor_marker( )
341
+ )
342
+ . as_str ( ) ,
343
+ vec ! [ CompletionAssertion :: CompletionTextAndRange (
344
+ r#"my_cool_foo"()"# . into( ) ,
345
+ TextRange :: new( 15 . into( ) , 15 . into( ) ) ,
346
+ ) ] ,
347
+ None ,
348
+ & pool,
349
+ )
350
+ . await ;
351
+
352
+ assert_complete_results (
353
+ format ! (
354
+ r#"select "auth"."{}""# ,
355
+ QueryWithCursorPosition :: cursor_marker( )
356
+ )
357
+ . as_str ( ) ,
358
+ vec ! [ CompletionAssertion :: CompletionTextAndRange (
359
+ r#"my_cool_foo"()"# . into( ) ,
360
+ TextRange :: new( 15 . into( ) , 16 . into( ) ) ,
361
+ ) ] ,
362
+ None ,
363
+ & pool,
364
+ )
365
+ . await ;
366
+ }
297
367
}
0 commit comments