1- use std:: borrow:: Cow ;
1+ use std:: { borrow:: Cow , cmp :: max } ;
22
33use pgt_text_size:: TextSize ;
44
2424 if cursor_inbetween_nodes ( params. tree , params. position )
2525 || cursor_prepared_to_write_token_after_last_node ( params. tree , params. position )
2626 || cursor_before_semicolon ( params. tree , params. position )
27+ || cursor_on_a_dot ( & params. text , params. position )
2728 {
2829 SanitizedCompletionParams :: with_adjusted_sql ( params)
2930 } else {
@@ -44,12 +45,13 @@ where
4445
4546 let mut sql_iter = params. text . chars ( ) ;
4647
47- for idx in 0 ..cursor_pos + 1 {
48+ let max = max ( cursor_pos + 1 , params. text . len ( ) ) ;
49+
50+ for idx in 0 ..max {
4851 match sql_iter. next ( ) {
4952 Some ( c) => {
5053 if idx == cursor_pos {
5154 sql. push_str ( SANITIZED_TOKEN ) ;
52- sql. push ( ' ' ) ;
5355 }
5456 sql. push ( c) ;
5557 }
@@ -149,6 +151,11 @@ fn cursor_prepared_to_write_token_after_last_node(
149151 cursor_pos == tree. root_node ( ) . end_byte ( ) + 1
150152}
151153
154+ fn cursor_on_a_dot ( sql : & str , position : TextSize ) -> bool {
155+ let position: usize = position. into ( ) ;
156+ sql. chars ( ) . nth ( position - 1 ) . is_some_and ( |c| c == '.' )
157+ }
158+
152159fn cursor_before_semicolon ( tree : & tree_sitter:: Tree , position : TextSize ) -> bool {
153160 let mut cursor = tree. walk ( ) ;
154161 let mut leaf_node = tree. root_node ( ) ;
@@ -198,7 +205,7 @@ mod tests {
198205 use pgt_text_size:: TextSize ;
199206
200207 use crate :: sanitization:: {
201- cursor_before_semicolon, cursor_inbetween_nodes,
208+ cursor_before_semicolon, cursor_inbetween_nodes, cursor_on_a_dot ,
202209 cursor_prepared_to_write_token_after_last_node,
203210 } ;
204211
@@ -263,6 +270,20 @@ mod tests {
263270 ) ) ;
264271 }
265272
273+ #[ test]
274+ fn on_a_dot ( ) {
275+ let input = "select * from private." ;
276+
277+ // select * from private.| <-- on a dot
278+ assert ! ( cursor_on_a_dot( input, TextSize :: new( 22 ) ) ) ;
279+
280+ // select * from private|. <-- before the dot
281+ assert ! ( !cursor_on_a_dot( input, TextSize :: new( 21 ) ) ) ;
282+
283+ // select * from private. | <-- too far off the dot
284+ assert ! ( !cursor_on_a_dot( input, TextSize :: new( 23 ) ) ) ;
285+ }
286+
266287 #[ test]
267288 fn test_cursor_before_semicolon ( ) {
268289 // Idx "13" is the exlusive end of `select * from` (first space after from)
0 commit comments