/**
 *****************************************
 * Created by edonet@163.com
 * Created on 2020-08-15 21:18:39
 *****************************************
 */ 'use strict' ; /**
 *****************************************
 * 加载依赖
 *****************************************
 */ import * as vscode from 'vscode' ; import replace from './helpers/replace' ; import Accessor , { VariableScope } from './Accessor' ; /**
 *****************************************
 * 命令执行参数
 *****************************************
 */ export type TerminalOptions = Partial < vscode . TerminalOptions > & { autoFocus ? : boolean ; autoClear ? : boolean ; sorted ? : string [ ] ; } ; /**
 *****************************************
 * 创建终端
 *****************************************
 */ function createTerminal ( options ) { const { window } = vscode ; const { name } = options ; if ( name && typeof name === 'string' ) { return ( window . terminals . find ( term => term . name === name ) || window . createTerminal ( options ) ) ; } return window . activeTerminal || window . createTerminal ( options ) ; } /**
 *****************************************
 * 命令行工具
 *****************************************
 */ export default class Command { private context : vscode . ExtensionContext ; private $files : string [ ] = [ ] ; private $accessor = new Accessor ( ) ; public constructor ( context ) { this . context = context ; } public get commands ( ) { return this . $accessor . commands ( ) ; } public addFile ( file ? ) { file && this . $files . push ( JSON . stringify ( file ) ) ; } public async resolve ( cmd ) { return cmd && replace ( cmd , async ( str ) => { let [ variable , args = '' ] = str . split ( ':' ) ; variable = variable . trim ( ) ; args = args . trim ( ) ; switch ( variable ) { case 'config' : return args && this . $accessor . config ( args ) as string ; case 'env' : return args && this . $accessor . env ( args ) ; case 'input' : return await this . $accessor . input ( args ) || args ; case 'command' : args && vscode . commands . executeCommand ( args ) ; return '' ; default : return this . $accessor . variable ( variable as VariableScope ) ; } } ) ; } public async pick ( options ? ) { const commands = this . $accessor . commands ( ) ; const keys = Object . keys ( commands ) ; if ( ! keys . length ) { keys . push ( 'This is an example as `echo "${workspaceFolder}"`' ) ; commands [ 'This is an example as `echo "${workspaceFolder}"`' ] = 'echo "${workspaceFolder}"' ; } const recent = this . context . workspaceState . get ( 'COMMAND_RUNNER_RECENT' , [ ] as string [ ] ) ; if ( recent && recent . length ) { keys . unshift . apply ( keys , recent . filter ( key => { const idx = keys . indexOf ( key ) ; if ( idx > - 1 ) { return keys . splice ( idx , 1 ) ; } } ) ) ; } try { const cmd = await vscode . window . showQuickPick ( keys , { placeHolder : 'Type or select command to run' } ) ; this . context . workspaceState . update ( 'COMMAND_RUNNER_RECENT' , [ cmd , ... keys ] ) ; if ( cmd ) { await this . execute ( commands [ cmd ] , options ) ; } } catch ( err ) { } } public async execute ( cmd , options ? ) { const { autoClear , autoFocus , ... terminalOptions } = { ... this . $accessor . config ( 'command-runner.terminal' ) , ... options , hideFromUser : false , } ; const terminal = createTerminal ( terminalOptions ) ; if ( autoFocus ) { terminal . show ( ) ; } if ( autoClear ) { await vscode . commands . executeCommand ( 'workbench.action.terminal.clear' ) ; } const command = cmd + ' ' + this . $files . join ( ' ' ) ; terminal . sendText ( await this . resolve ( command ) ) ; console . log ( '--> Run Command:' , command ) ; } public async executeSelectText ( options ? ) { await this . execute ( this . $accessor . variable ( 'selectedTextSection' ) , options ) ; } }