@@ -5,16 +5,13 @@ use async_helper::run_async;
55use change:: StatementChange ;
66use dashmap:: DashMap ;
77use db_connection:: DbConnection ;
8- pub ( crate ) use document:: StatementId ;
98use document:: { Document , Statement } ;
109use futures:: { StreamExt , stream} ;
11- use itertools:: Itertools ;
1210use pg_query:: PgQueryStore ;
1311use pgt_analyse:: { AnalyserOptions , AnalysisFilter } ;
1412use pgt_analyser:: { Analyser , AnalyserConfig , AnalyserContext } ;
1513use pgt_diagnostics:: { Diagnostic , DiagnosticExt , Severity , serde:: Diagnostic as SDiagnostic } ;
1614use pgt_fs:: { ConfigName , PgTPath } ;
17- use pgt_text_size:: { TextRange , TextSize } ;
1815use pgt_typecheck:: TypecheckParams ;
1916use schema_cache_manager:: SchemaCacheManager ;
2017use sqlx:: Executor ;
@@ -29,7 +26,7 @@ use crate::{
2926 self , CodeAction , CodeActionKind , CodeActionsResult , CommandAction ,
3027 CommandActionCategory , ExecuteStatementParams , ExecuteStatementResult ,
3128 } ,
32- completions:: { CompletionsResult , GetCompletionsParams } ,
29+ completions:: { self , CompletionsResult , GetCompletionsParams } ,
3330 diagnostics:: { PullDiagnosticsParams , PullDiagnosticsResult } ,
3431 } ,
3532 settings:: { Settings , SettingsHandle , SettingsHandleMut } ,
@@ -44,7 +41,7 @@ mod analyser;
4441mod async_helper;
4542mod change;
4643mod db_connection;
47- mod document;
44+ pub ( crate ) mod document;
4845mod migration;
4946mod pg_query;
5047mod schema_cache_manager;
@@ -540,64 +537,12 @@ impl Workspace for WorkspaceServer {
540537 . get ( & params. path )
541538 . ok_or ( WorkspaceError :: not_found ( ) ) ?;
542539
543- let count = doc. statement_count ( ) ;
544- // no arms no cookies
545- if count == 0 {
546- return Ok ( CompletionsResult :: default ( ) ) ;
547- }
548-
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)
540+ let ( statement, stmt_range, text) =
541+ match completions:: get_statement_for_completions ( & doc, params. position ) {
542+ None => return Ok ( CompletionsResult :: default ( ) ) ,
543+ Some ( s) => s,
567544 } ;
568545
569- let maybe_statement = if count == 1 {
570- let ( stmt, range, txt) = doc. iter_statements_with_text_and_range ( ) . next ( ) . unwrap ( ) ;
571- if matches_expanding_range ( stmt. id , range, params. position ) {
572- Some ( ( stmt, range, txt) )
573- } else {
574- None
575- }
576- } else {
577- /*
578- * If we have multiple statements, we want to make sure that we do not overlap
579- * with the next one.
580- *
581- * select 1 |select 1;
582- */
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 )
591- } ;
592-
593- let ( statement, stmt_range, text) = match maybe_statement {
594- Some ( it) => it,
595- None => {
596- tracing:: debug!( "No matching statement found for completion." ) ;
597- return Ok ( CompletionsResult :: default ( ) ) ;
598- }
599- } ;
600-
601546 // `offset` is the position in the document,
602547 // but we need the position within the *statement*.
603548 let position = params. position - stmt_range. start ( ) ;
0 commit comments