@@ -541,61 +541,57 @@ impl Workspace for WorkspaceServer {
541541 . ok_or ( WorkspaceError :: not_found ( ) ) ?;
542542
543543 let count = doc. statement_count ( ) ;
544+ // no arms no cookies
545+ if count == 0 {
546+ return Ok ( CompletionsResult :: default ( ) ) ;
547+ }
544548
545- let maybe_statement = if count == 0 {
546- None
547- } else if count == 1 {
549+ /*
550+ * We allow an offset of two for the statement:
551+ *
552+ * select * from | <-- we want to suggest items for the next token.
553+ *
554+ * However, if the current statement is terminated by a semicolon, we don't apply any
555+ * offset.
556+ *
557+ * select * from users; | <-- no autocompletions here.
558+ */
559+ let matches_expanding_range =
560+ |stmt_id : StatementId , range : & TextRange , position : TextSize | {
561+ let measuring_range = if doc. is_terminated_by_semicolon ( stmt_id) . unwrap ( ) {
562+ * range
563+ } else {
564+ range. checked_expand_end ( 2 . into ( ) ) . unwrap_or ( * range)
565+ } ;
566+ measuring_range. contains ( position)
567+ } ;
568+
569+ let maybe_statement = if count == 1 {
548570 let ( stmt, range, txt) = doc. iter_statements_with_text_and_range ( ) . next ( ) . unwrap ( ) ;
549- let expanded_range = TextRange :: new (
550- range. start ( ) ,
551- range
552- . end ( )
553- . checked_add ( TextSize :: new ( 2 ) )
554- . unwrap_or ( range. end ( ) ) ,
555- ) ;
556- if expanded_range. contains ( params. position ) {
571+ if matches_expanding_range ( stmt. id , range, params. position ) {
557572 Some ( ( stmt, range, txt) )
558573 } else {
559574 None
560575 }
561576 } else {
562- let mut stmts = doc. iter_statements_with_text_and_range ( ) . tuple_windows ( ) ;
563- stmts. find ( |( ( _, rcurrent, _) , ( _, rnext, _) ) | {
564577 /*
565- * We allow an offset of two for the statement:
566- *
567- * (| is the user's cursor.)
568- *
569- * select * from | <-- we want to suggest items for the next token.
578+ * If we have multiple statements, we want to make sure that we do not overlap
579+ * with the next one.
570580 *
581+ * select 1 |select 1;
571582 */
572- let expanded_range = TextRange :: new (
573- rcurrent. start ( ) ,
574- rcurrent
575- . end ( )
576- . checked_add ( TextSize :: new ( 2 ) )
577- . unwrap_or ( rcurrent. end ( ) ) ,
578- ) ;
579- let is_within_range = expanded_range. contains ( params. position ) ;
580-
581- /*
582- * However, we do not allow this if the there the offset overlaps
583- * with an adjacent statement:
584- *
585- * select 1; |select 1;
586- */
587- let overlaps_next = !rnext. contains ( params. position ) ;
588-
589-
590- tracing:: warn!( "Current range {:?}, next range {:?}, position: {:?}, contains range: {}, overlaps :{}" , rcurrent, rnext, params. position, is_within_range, overlaps_next) ;
591-
592- is_within_range && !overlaps_next
593-
594- } ) . map ( |( t1, _t2) | t1)
583+ let mut stmts = doc. iter_statements_with_text_and_range ( ) . tuple_windows ( ) ;
584+ stmts
585+ . find ( |( ( current_stmt, rcurrent, _) , ( _, rnext, _) ) | {
586+ let overlaps_next = rnext. contains ( params. position ) ;
587+ matches_expanding_range ( current_stmt. id , & rcurrent, params. position )
588+ && !overlaps_next
589+ } )
590+ . map ( |t| t. 0 )
595591 } ;
596592
597593 let ( statement, stmt_range, text) = match maybe_statement {
598- Some ( tuple ) => tuple ,
594+ Some ( it ) => it ,
599595 None => {
600596 tracing:: debug!( "No matching statement found for completion." ) ;
601597 return Ok ( CompletionsResult :: default ( ) ) ;
0 commit comments