import * as vscode from 'vscode' ; import { shellEnvironment } from './shell' ; import { showWorkspaceFolderPick } from './hostutils' ; import { Dictionary } from './utils/dictionary' ; export interface Host { showErrorMessage ( message , ... items ) : Thenable < string | undefined > ; showWarningMessage ( message , ... items ) : Thenable < string | undefined > ; showInformationMessage ( message , ... items ) : Thenable < string | undefined > ; showInputBox ( options , token ? ) : Thenable < string | undefined > ; showQuickPick ( items , options ) : Thenable < string | undefined > ; showQuickPick < T extends vscode . QuickPickItem > ( items , options ) : Thenable < T | undefined > ; withProgress < R > ( task ) : Thenable < R > ; getConfiguration ( key ) : any ; createTerminal ( name ? , shellPath ? , shellArgs ? ) : vscode . Terminal ; onDidCloseTerminal ( listener ) : vscode . Disposable ; onDidChangeConfiguration ( listener ) : vscode . Disposable ; activeDocument ( ) : vscode . TextDocument | undefined ; showDocument ( uri ) : Promise < vscode . TextDocument > ; readDocument ( uri ) : Promise < vscode . TextDocument > ; selectRootFolder ( ) : Promise < string | undefined > ; longRunning < T > ( uiOptions , action ) : Promise < T > ; } export const host = { showErrorMessage : showErrorMessage , showWarningMessage : showWarningMessage , showInformationMessage : showInformationMessage , showQuickPick : showQuickPickAny , withProgress : withProgress , getConfiguration : getConfiguration , createTerminal : createTerminal , onDidCloseTerminal : onDidCloseTerminal , onDidChangeConfiguration : onDidChangeConfiguration , showInputBox : showInputBox , activeDocument : activeDocument , showDocument : showDocument , readDocument : readDocument , selectRootFolder : selectRootFolder , longRunning : longRunning } ; export interface LongRunningUIOptions { readonly title : string ; readonly operationKey ? : string ; } function showInputBox ( options , token ? ) { return vscode . window . showInputBox ( options , token ) ; } function showErrorMessage ( message , ... items ) { return vscode . window . showErrorMessage ( message , ... items ) ; } function showWarningMessage ( message , ... items ) { return vscode . window . showWarningMessage ( message , ... items ) ; } function showInformationMessage ( message , ... items ) { return vscode . window . showInformationMessage ( message , ... items ) ; } function showQuickPickStr ( items , options ? ) { return vscode . window . showQuickPick ( items , options ) ; } function showQuickPickT < T extends vscode . QuickPickItem > ( items , options ? ) { return vscode . window . showQuickPick ( items , options ) ; } function showQuickPickAny ( items , options ) { if ( ! Array . isArray ( items ) ) { throw 'unexpected type passed to showQuickPick' ; } if ( items . length === 0 ) { return showQuickPickStr ( items , options ) ; } const item = items [ 0 ] ; if ( typeof item === 'string' || item instanceof String ) { return showQuickPickStr ( items , options ) ; } else { return showQuickPickT ( items , options ) ; } } function withProgress < R > ( task ) { return vscode . window . withProgress ( { location : vscode . ProgressLocation . Window } , task ) ; } function getConfiguration ( key ) { return vscode . workspace . getConfiguration ( key ) ; } function createTerminal ( name ? , shellPath ? , shellArgs ? ) { const terminalOptions = { name : name , shellPath : shellPath , shellArgs : shellArgs , env : shellEnvironment ( process . env ) } ; return vscode . window . createTerminal ( terminalOptions ) ; } function onDidCloseTerminal ( listener ) { return vscode . window . onDidCloseTerminal ( listener ) ; } function onDidChangeConfiguration ( listener ) { return vscode . workspace . onDidChangeConfiguration ( listener ) ; } function activeDocument ( ) { const activeEditor = vscode . window . activeTextEditor ; if ( activeEditor ) { return activeEditor . document ; } return undefined ; } async function showDocument ( uri ) { const document = await vscode . workspace . openTextDocument ( uri ) ; if ( document ) { await vscode . window . showTextDocument ( document ) ; } return document ; } async function readDocument ( uri ) { return await vscode . workspace . openTextDocument ( uri ) ; } async function selectRootFolder ( ) { const folder = await showWorkspaceFolderPick ( ) ; if ( ! folder ) { return undefined ; } if ( folder . uri . scheme !== 'file' ) { vscode . window . showErrorMessage ( "This command requires a filesystem folder" ) ; return undefined ; } return folder . uri . fsPath ; } const ACTIVE_LONG_RUNNING_OPERATIONS = Dictionary . of < boolean > ( ) ; async function longRunning < T > ( uiOptions , action ) { const uiOptionsObj = uiOptionsObjectOf ( uiOptions ) ; const options = { location : vscode . ProgressLocation . Notification , title : uiOptionsObj . title } ; return await underLongRunningOperationKeyGuard ( uiOptionsObj . operationKey , async ( alreadyShowingUI ) => alreadyShowingUI ? await action ( ) : await vscode . window . withProgress ( options , ( _ ) => action ( ) ) ) ; } async function underLongRunningOperationKeyGuard < T > ( operationKey , action ) { const alreadyShowingUI = ! ! operationKey && ( ACTIVE_LONG_RUNNING_OPERATIONS [ operationKey ] || false ) ; if ( operationKey ) { ACTIVE_LONG_RUNNING_OPERATIONS [ operationKey ] = true ; } try { const result = await action ( alreadyShowingUI ) ; return result ; } finally { if ( operationKey ) { delete ACTIVE_LONG_RUNNING_OPERATIONS [ operationKey ] ; } } } function uiOptionsObjectOf ( uiOptions ) { if ( isLongRunningUIOptions ( uiOptions ) ) { return uiOptions ; } return { title : uiOptions } ; } function isLongRunningUIOptions ( obj ) { return ! ! ( ( obj as LongRunningUIOptions ) . title ) ; }