import * as vscode from 'vscode' ; import TelemetryReporter from 'vscode-extension-telemetry' ; import { serverMsg } from '../manager' ; import { EndpointManager } from '../infoManagers/endpointManager' ; import { WorkspaceManager } from '../infoManagers/workspaceManager' ; import { Disposable } from '../utils/dispose' ; import { serverTaskLinkProvider } from './serverTaskLinkProvider' ; import { ServerTaskTerminal } from './serverTaskTerminal' ; import { TASK_TERMINAL_BASE_NAME } from '../utils/constants' ; import { ConnectionManager } from '../infoManagers/connectionManager' ; interface ServerTaskDefinition extends vscode . TaskDefinition { args : string [ ] ; } export const ServerArgs = { verbose : '--verbose' , } ; description export enum ServerStartedStatus { JUST_STARTED , STARTED_BY_EMBEDDED_PREV } description export class ServerTaskProvider extends Disposable implements vscode . TaskProvider { public static CustomBuildScriptType = 'Live Preview' ; private _tasks : vscode . Task [ ] | undefined ; private _terminal : ServerTaskTerminal | undefined ; private _termName = '' ; private _terminalLinkProvider : serverTaskLinkProvider ; private readonly _onRequestToOpenServerEmitter = this . _register ( new vscode . EventEmitter < void > ( ) ) ; public readonly onRequestToOpenServer = this . _onRequestToOpenServerEmitter . event ; private readonly _onRequestOpenEditorToSide = this . _register ( new vscode . EventEmitter < vscode . Uri > ( ) ) ; public readonly onRequestOpenEditorToSide = this . _onRequestOpenEditorToSide . event ; private readonly _onRequestToCloseServerEmitter = this . _register ( new vscode . EventEmitter < void > ( ) ) ; public readonly onRequestToCloseServer = this . _onRequestToCloseServerEmitter . event ; constructor ( private readonly _reporter , endpointManager , private readonly _workspaceManager , _connectionManager ) { super ( ) ; this . _terminalLinkProvider = this . _register ( new serverTaskLinkProvider ( '' , _reporter , endpointManager , _workspaceManager , _connectionManager ) ) ; this . _terminalLinkProvider . onRequestOpenEditorToSide ( ( e ) => { this . _onRequestOpenEditorToSide . fire ( e ) ; } ) ; } public get terminalName ( ) : string { return this . _termName ; } public get isRunning ( ) : boolean { if ( this . _terminal ) { return this . _terminal . running ; } return false ; } param { serverMsg } msg public sendServerInfoToTerminal ( msg ) { if ( this . _terminal && this . _terminal . running ) { this . _terminal . showServerMsg ( msg ) ; } } param { vscode . Uri } externalUri param { ServerStartedStatus } status public serverStarted ( externalUri , status ) { if ( this . _terminal && this . _terminal . running ) { this . _terminal . serverStarted ( externalUri , status ) ; } } param { boolean } now public serverStop ( now ) { if ( this . _terminal && this . _terminal . running ) { if ( now ) { this . _terminal . serverStopped ( ) ; } else { this . _terminal . serverWillBeStopped ( ) ; } } } param { boolean } verbose public extRunTask ( verbose ) { this . _reporter . sendTelemetryEvent ( 'tasks.terminal.startFromExtension' ) ; vscode . tasks . fetchTasks ( { type : ServerTaskProvider . CustomBuildScriptType } ) . then ( ( tasks ) => { const selTasks = tasks . filter ( ( x ) => ( verbose && x . definition . args . length > 0 && x . definition . args [ 0 ] == ServerArgs . verbose ) || ( ! verbose && x . definition . args . length == 0 ) ) ; if ( selTasks . length > 0 ) { vscode . tasks . executeTask ( selTasks [ 0 ] ) ; } } ) ; } public async provideTasks ( ) { return this . _getTasks ( ) ; } public resolveTask ( _task ) { const flavor = _task . definition . flavor ; if ( flavor ) { const definition = < any > _task . definition ; return this . _getTask ( definition . flavor , definition ) ; } return undefined ; } private _getTasks ( ) { if ( this . _tasks !== undefined ) { return this . _tasks ; } const args = [ [ ServerArgs . verbose ] , [ ] ] ; this . _tasks = [ ] ; args . forEach ( ( args ) => { this . _tasks ! . push ( this . _getTask ( args ) ) ; } ) ; return this . _tasks ; } private _getTask ( args , definition ? ) { if ( definition === undefined ) { definition = { type : ServerTaskProvider . CustomBuildScriptType , args , } ; } let taskName = TASK_TERMINAL_BASE_NAME ; for ( const i in args ) { taskName += ` ${ args [ i ] }` ; } if ( this . _terminal && this . _terminal . running ) { return new vscode . Task ( definition , this . _workspaceManager . workspace ?? vscode . TaskScope . Workspace , taskName , ServerTaskProvider . CustomBuildScriptType , undefined ) ; } const custExec = new vscode . CustomExecution ( async ( ) : Promise < ServerTaskTerminal > => { if ( this . _terminal && this . _terminal . running ) { return new ServerTaskTerminal ( [ ] , this . _reporter , false ) ; } this . _terminal = new ServerTaskTerminal ( args , this . _reporter ) ; this . _termName = taskName ; this . _terminalLinkProvider . terminalName = taskName ; this . _terminal . onRequestToOpenServer ( ( e ) => { this . _onRequestToOpenServerEmitter . fire ( e ) ; } ) ; this . _terminal . onRequestToCloseServer ( ( e ) => { this . _onRequestToCloseServerEmitter . fire ( e ) ; } ) ; return this . _terminal ; } ) ; const task = new vscode . Task ( definition , vscode . TaskScope . Workspace , taskName , ServerTaskProvider . CustomBuildScriptType , custExec ) ; task . isBackground = true ; task . presentationOptions . panel = vscode . TaskPanelKind . New ; return task ; } }