import { CompletionItem , TextDocument , workspace } from 'vscode' ; import { ext , ICompletionsSpyResult } from '../../extension.bundle' ; import { delay } from '../support/delay' ; const defaultTimeout = 30 * 1000 ; export function getEventPromise < T > ( eventName , executor , timeout = defaultTimeout ) { return new Promise < T > ( async ( resolve , reject ) : Promise < void > => { try { let completed = false ; executor ( ( value ) => { completed = true ; resolve ( value ) ; } , ( reason ? ) => { completed = true ; reject ( reason ) ; } ) ; await delay ( timeout ) ; if ( ! completed ) { reject ( new TimeoutError ( `Timed out waiting for event "${ eventName }"` ) ) ; } } catch ( err ) { reject ( err ) ; } } ) ; } export class TimeoutError extends Error { public constructor ( message ) { super ( message ) ; } } export async function actThenWait < T , U > ( action , promise ) { await action ( ) ; return await promise ; } export function getDocumentChangedPromise ( document , timeout = defaultTimeout ) { return getEventPromise < string > ( "onDidChangeTextDocument" , ( resolve , reject ) => { const disposable = workspace . onDidChangeTextDocument ( e => { if ( e . document === document ) { disposable . dispose ( ) ; resolve ( document . getText ( ) ) ; } } ) ; } , timeout ) ; } export function getCompletionItemsPromise ( document , timeout = defaultTimeout ) { return getEventPromise ( "onCompletionItems" , ( resolve , reject ) => { const disposable = ext . completionItemsSpy . onCompletionItems ( e => { if ( e . document . documentUri . fsPath === document . uri . fsPath ) { disposable . dispose ( ) ; resolve ( e ) ; } } ) ; } , timeout ) ; } export function getCompletionItemResolutionPromise ( item ? , timeout = defaultTimeout ) { return getEventPromise ( "onCompletionItemResolved" , ( resolve , reject ) => { const disposable = ext . completionItemsSpy . onCompletionItemResolved ( e => { if ( ! item || e === item ) { disposable . dispose ( ) ; resolve ( e ) ; } } ) ; } , timeout ) ; }