'use strict' ; import { CompletionItemProvider , CompletionItem , TextDocument , Position , CancellationToken , CompletionContext , Range } from 'vscode' ; import { ProblemInfo } from 'pddl-workspace' ; import { ProblemInitDelegate } from './ProblemInitDelegate' ; import { OperatorDelegate } from './OperatorDelegate' ; import { VariableDelegate } from './VariableDelegate' ; import { TypeDelegate } from './TypeDelegate' ; import { CodePddlWorkspace } from '../workspace/CodePddlWorkspace' ; export class AutoCompletion implements CompletionItemProvider { private operatorDelegate : OperatorDelegate ; private variableDelegate : VariableDelegate ; private typeDelegate : TypeDelegate ; constructor ( public codePddlWorkspace ) { this . operatorDelegate = new OperatorDelegate ( ) ; this . variableDelegate = new VariableDelegate ( codePddlWorkspace ) ; this . typeDelegate = new TypeDelegate ( codePddlWorkspace . pddlWorkspace ) ; } async provideCompletionItems ( document , position , token , context ) { if ( token . isCancellationRequested ) { return [ ] ; } const completionCollector = await new CompletionCollector ( this . codePddlWorkspace , document , position , context , this . operatorDelegate , this . variableDelegate , this . typeDelegate ) . initialize ( ) ; return completionCollector . getCompletions ( ) ; } } class CompletionCollector { private completions : CompletionItem [ ] = [ ] ; private lineText : string ; private leadingText : string ; constructor ( private readonly codePddlWorkspace , private readonly document , private readonly position , private readonly context , private readonly operatorDelegate , private readonly variableDelegate , private readonly typeDelegate ) { this . lineText = document . lineAt ( position . line ) . text ; this . leadingText = this . lineText . substring ( 0 , position . character ) ; } async initialize ( ) { if ( this . leadingText . includes ( ';' ) ) { return this ; } const activeFileInfo = await this . codePddlWorkspace . upsertFile ( this . document ) ; if ( ! activeFileInfo ) { return this ; } if ( activeFileInfo . isProblem ( ) ) { const problemFileInfo = activeFileInfo as ProblemInfo ; this . createProblemCompletionItems ( problemFileInfo ) ; } if ( this . leadingText . length > 0 && this . leadingText . endsWith ( '(' ) ) { this . pushAll ( this . operatorDelegate . getOperatorItems ( ) ) ; this . pushAll ( this . variableDelegate . getVariableItems ( activeFileInfo ) ) ; } else if ( this . leadingText . endsWith ( ' -' ) ) { this . pushAll ( this . typeDelegate . getTypeItems ( activeFileInfo ) ) ; } return this ; } getCompletions ( ) { return this . completions ; } createProblemCompletionItems ( problemFileInfo ) { const folder = this . codePddlWorkspace . pddlWorkspace . getFolderOf ( problemFileInfo ) ; const domainFiles = folder ?. getDomainFilesFor ( problemFileInfo ) ?? [ ] ; if ( this . isInInit ( ) ) { new ProblemInitDelegate ( this . completions , this . context ) . createProblemInitCompletionItems ( problemFileInfo , domainFiles ) ; } } pushAll ( items ) { this . completions . push ( ... items ) ; } isTriggeredByBracket ( ) { return this . leadingText . length > 0 && this . leadingText . endsWith ( '(' ) ; } isInInit ( ) { const startPosition = new Position ( 0 , 0 ) ; const endPosition = new Position ( this . document . lineCount , 10000 ) ; return this . document . getText ( new Range ( startPosition , this . position ) ) . includes ( '(:init' ) && this . document . getText ( new Range ( this . position , endPosition ) ) . includes ( '(:goal' ) ; } }