diff --git a/extensions/gulp/src/main.ts b/extensions/gulp/src/main.ts index 80a9c308920..b535ec5375f 100644 --- a/extensions/gulp/src/main.ts +++ b/extensions/gulp/src/main.ts @@ -73,7 +73,8 @@ function getGulpTasks(): Thenable { if (line.length === 0) { continue; } - result.tasks.push(new vscode.ShellTask(`gulp ${line}`, `gulp ${line}`)); + let task = new vscode.ShellTask(`gulp ${line}`, `gulp ${line}`); + result.tasks.push(task); let lowerCaseLine = line.toLowerCase(); if (lowerCaseLine === 'build') { buildTask = { id: line, rank: 2 }; diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 35bf95fa1f9..307de4a1b5c 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -256,6 +256,11 @@ declare module 'vscode' { * Defaults to `RevealKind.Always`. */ reveal?: RevealKind; + + /** + * Controls whether the command is echoed in the terminal or not. + */ + echo?: boolean; } @@ -331,24 +336,26 @@ declare module 'vscode' { readonly process: string; /** - * The arguments passed to the process. Can be omitted. + * The arguments passed to the process. Defaults to an empty array. */ - args?: string[]; + args: string[]; /** - * The process options used when the process is executed. Can be omitted. + * The process options used when the process is executed. + * Defaults to an empty object literal. */ - options?: ProcessOptions; + options: ProcessOptions; /** - * The terminal options. Can be omitted. + * The terminal options. Defaults to an empty object literal. */ - terminal?: TerminalBehaviour; + terminal: TerminalBehaviour; /** - * The problem matchers attached to the task. + * The problem matchers attached to the task. Defaults to an empty + * array. */ - readonly problemMatchers?: ProblemMatcher[]; + problemMatchers: ProblemMatcher[]; } export interface ShellOptions { @@ -422,19 +429,21 @@ declare module 'vscode' { readonly commandLine: string; /** - * The shell options used when the shell is executed. Can be omitted. + * The shell options used when the shell is executed. Defaults to an + * empty object literal. */ - options?: ShellOptions; + options: ShellOptions; /** - * The terminal options. Can be omitted. + * The terminal options. Defaults to an empty object literal. */ - terminal?: TerminalBehaviour; + terminal: TerminalBehaviour; /** - * The problem matchers attached to the task. + * The problem matchers attached to the task. Defaults to an empty + * array. */ - readonly problemMatchers?: ProblemMatcher[]; + problemMatchers: ProblemMatcher[]; } export type Task = ProcessTask | ShellTask; diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index c63d9d9bc81..44c71b83fb1 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -208,11 +208,11 @@ namespace RevealKind { } namespace TerminalBehaviour { - export function from(value: vscode.TerminalBehaviour): { showOutput: TaskSystem.ShowOutput } { + export function from(value: vscode.TerminalBehaviour): { showOutput: TaskSystem.ShowOutput, echo: boolean } { if (value === void 0 || value === null) { - return { showOutput: TaskSystem.ShowOutput.Always }; + return { showOutput: TaskSystem.ShowOutput.Always, echo: false }; } - return { showOutput: RevealKind.from(value.reveal) }; + return { showOutput: RevealKind.from(value.reveal), echo: !!value.echo }; } } @@ -303,13 +303,14 @@ namespace Tasks { if (command === void 0) { return undefined; } - let outputChannel = TerminalBehaviour.from(task.terminal); + let behaviour = TerminalBehaviour.from(task.terminal); + command.echo = behaviour.echo; let result: TaskSystem.Task = { _id: uuidMap.getUUID(task.identifier), name: task.name, identifier: task.identifier, command: command, - showOutput: outputChannel.showOutput, + showOutput: behaviour.showOutput, isBackground: !!task.isBackground, suppressTaskName: true, problemMatchers: ProblemMatcher.from(task.problemMatchers) diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index ca5a256d710..a9c7b1d30e8 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -992,28 +992,68 @@ export class BaseTask { private _name: string; private _problemMatchers: vscode.ProblemMatcher[]; - - public isBackground: boolean; - public identifier: string; - public terminal: vscode.TerminalBehaviour; + private _identifier: string; + private _isBackground: boolean; + private _terminal: vscode.TerminalBehaviour; constructor(name: string, problemMatchers: vscode.ProblemMatcher[]) { if (typeof name !== 'string') { throw illegalArgument('name'); } this._name = name; - this.identifier = name; - this._problemMatchers = problemMatchers; - this.isBackground = false; + this._identifier = name; + this._problemMatchers = problemMatchers || []; + this._isBackground = false; + this._terminal = Object.create(null); + } + + get identifier(): string { + return this._identifier; + } + + set identifier(value: string) { + if (typeof name !== 'string') { + throw illegalArgument('identifier'); + } + this._identifier = value; } get name(): string { return this._name; } + get isBackground(): boolean { + return this._isBackground; + } + + set isBackground(value: boolean) { + if (value !== true && value !== false) { + value = false; + } + this._isBackground = value; + } + + get terminal(): vscode.TerminalBehaviour { + return this._terminal; + } + + set terminal(value: vscode.TerminalBehaviour) { + if (value === void 0 || value === null) { + value = Object.create(null); + } + this._terminal = value; + } + get problemMatchers(): vscode.ProblemMatcher[] { return this._problemMatchers; } + + set problemMatchers(value: vscode.ProblemMatcher[]) { + if (!Array.isArray(value)) { + value = []; + } + this._problemMatchers = value; + } } namespace ProblemMatcher { @@ -1027,9 +1067,8 @@ namespace ProblemMatcher { export class ProcessTask extends BaseTask { private _process: string; - - public args: string[]; - public options: vscode.ProcessOptions; + private _args: string[]; + private _options: vscode.ProcessOptions; private static parseArguments(restArgs: any[]): { args: string[]; options: vscode.ProcessOptions; problemMatchers: vscode.ProblemMatcher[] } { let args: string[] = []; @@ -1066,20 +1105,41 @@ export class ProcessTask extends BaseTask { let { args, options, problemMatchers } = ProcessTask.parseArguments(rest); super(name, problemMatchers); this._process = process; - this.args = args; - this.options = options; + this._args = args; + this._options = options || Object.create(null); } get process(): string { return this._process; } + + get args(): string[] { + return this._args; + } + + set args(value: string[]) { + if (!Array.isArray(value)) { + value = []; + } + this._args = value; + } + + get options(): vscode.ProcessOptions { + return this._options; + } + + set options(value: vscode.ProcessOptions) { + if (value === void 0 || value === null) { + value = Object.create(null); + } + this._options = value; + } } export class ShellTask extends BaseTask { private _commandLine: string; - - public options: vscode.ShellOptions; + private _options: vscode.ShellOptions; private static parseArguments(restArgs: any[]): { options: vscode.ShellOptions; problemMatchers: vscode.ProblemMatcher[] } { let options: vscode.ShellOptions = undefined; @@ -1109,10 +1169,21 @@ export class ShellTask extends BaseTask { super(name, problemMatchers); this._commandLine = commandLine; - this.options = options; + this._options = options || Object.create(null); } get commandLine(): string { return this._commandLine; } + + get options(): vscode.ShellOptions { + return this._options; + } + + set options(value: vscode.ShellOptions) { + if (value === void 0 || value === null) { + value = Object.create(null); + } + this._options = value; + } } \ No newline at end of file diff --git a/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts b/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts index 3752a1bce17..cd58ad6e24f 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/terminalTaskSystem.ts @@ -370,6 +370,9 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem { }); shellArgs.push(commandLine); shellLaunchConfig.args = Platform.isWindows ? shellArgs.join(' ') : shellArgs; + if (task.command.echo) { + shellLaunchConfig.initialText = `> ${commandLine}`; + } } else { let cwd = options && options.cwd ? options.cwd : process.cwd(); // On Windows executed process must be described absolute. Since we allowed command without an @@ -381,6 +384,18 @@ export class TerminalTaskSystem extends EventEmitter implements ITaskSystem { args, waitOnExit }; + if (task.command.echo) { + let getArgsToEcho = (args: string | string[]): string => { + if (!args || args.length === 0) { + return ''; + } + if (Types.isString(args)) { + return args; + } + return args.join(' '); + }; + shellLaunchConfig.initialText = `> ${shellLaunchConfig.executable} ${getArgsToEcho(shellLaunchConfig.args)}`; + } } if (options.cwd) { shellLaunchConfig.cwd = options.cwd;