diff --git a/src/vs/workbench/api/node/extHostOutputService.ts b/src/vs/workbench/api/node/extHostOutputService.ts index 7872a96702f97acd42638b7ef8ff599ecec33ac0..c9171fda6ce07292083db50bd7ae535453012627 100644 --- a/src/vs/workbench/api/node/extHostOutputService.ts +++ b/src/vs/workbench/api/node/extHostOutputService.ts @@ -88,7 +88,7 @@ export class MainThreadOutputService { } public append(channel: string, value: string): TPromise { - this._outputService.append(channel, value); + this._outputService.getOutputChannel(channel).append(value); return undefined; } diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts index ba67dfe8236368e402c12a1b944805731960f886..e815238d2e7ffd54fd12250ad2d926a80bb69935 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsWidgets.ts @@ -15,7 +15,7 @@ import { IStatusbarItem } from 'vs/workbench/browser/parts/statusbar/statusbar'; import { IOutputService } from 'vs/workbench/parts/output/common/output'; import { IExtensionService, IMessage } from 'vs/platform/extensions/common/extensions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IExtensionsService, ExtensionsLabel, IExtension, IExtensionManifest } from 'vs/workbench/parts/extensions/common/extensions'; +import { IExtensionsService, ExtensionsLabel, ExtensionsChannelId, IExtension, IExtensionManifest } from 'vs/workbench/parts/extensions/common/extensions'; import { IQuickOpenService } from 'vs/workbench/services/quickopen/common/quickOpenService'; import { getOutdatedExtensions } from 'vs/workbench/parts/extensions/common/extensionsUtil'; @@ -115,7 +115,8 @@ export class ExtensionsStatusbarItem implements IStatusbarItem { const name = extension && extension.name; const message = name ? `${ name }: ${ m.message }` : m.message; - this.outputService.append(ExtensionsLabel, message); + const outputChannel = this.outputService.getOutputChannel(ExtensionsChannelId); + outputChannel.append(message); this.outputService.showOutput(ExtensionsLabel, true); }); }); diff --git a/src/vs/workbench/parts/git/browser/gitOutput.ts b/src/vs/workbench/parts/git/browser/gitOutput.ts index e6094253a181f72dcdedb1d739f41acfd4d2f478..9f65bf0172820e8ad256cf302d68565958ea54e2 100644 --- a/src/vs/workbench/parts/git/browser/gitOutput.ts +++ b/src/vs/workbench/parts/git/browser/gitOutput.ts @@ -47,7 +47,7 @@ export class GitOutput implements ext.IWorkbenchContribution { } private onOutput(output: string): void { - this.outputService.append('Git', output); + this.outputService.getOutputChannel('Git').append(output); } public dispose(): void { diff --git a/src/vs/workbench/parts/output/common/output.ts b/src/vs/workbench/parts/output/common/output.ts index 7ba81777a682034674739458d7d0a5dd0edeeee8..953ed0bb1a165b3a341ac877916a994725758792 100644 --- a/src/vs/workbench/parts/output/common/output.ts +++ b/src/vs/workbench/parts/output/common/output.ts @@ -43,7 +43,7 @@ export const MAX_OUTPUT_LENGTH = 10000 /* Max. number of output lines to show in */ export interface IOutputEvent { output: string; - channel?: string; + channelId?: string; } export var IOutputService = createDecorator(OUTPUT_SERVICE_ID); @@ -53,10 +53,8 @@ export var IOutputService = createDecorator(OUTPUT_SERVICE_ID); */ export interface IOutputService { serviceId: ServiceIdentifier; - /** - * Appends output to the given channel. - */ - append(channel: string, output: string): void; + + getOutputChannel(id: string): IOutputChannel; /** * Returns the received output. @@ -110,6 +108,10 @@ export interface IOutputService { export interface IOutputChannel { + /** + * Appends output to the channel. + */ + append(output: string): void; } diff --git a/src/vs/workbench/parts/output/common/outputEditorInput.ts b/src/vs/workbench/parts/output/common/outputEditorInput.ts index 4430df2299634e2abf7adf03fb7628dc40bf0203..f3b0b668c516ef85a3f6db1fe8d174efe0a1dfac 100644 --- a/src/vs/workbench/parts/output/common/outputEditorInput.ts +++ b/src/vs/workbench/parts/output/common/outputEditorInput.ts @@ -86,7 +86,7 @@ export class OutputEditorInput extends StringEditorInput { } private onOutputReceived(e: IOutputEvent): void { - if (this.outputSet && e.channel === this.channel) { + if (this.outputSet && e.channelId === this.channel) { if (e.output) { this.bufferedOutput = strings.appendWithLimit(this.bufferedOutput, e.output, MAX_OUTPUT_LENGTH); this.scheduleOutputAppend(); diff --git a/src/vs/workbench/parts/output/common/outputServices.ts b/src/vs/workbench/parts/output/common/outputServices.ts index 0b8d27aae92e2097856ff67efdae8de9033f8637..801c0c04fc3751eaddb8eb13ed2c02ad21e14a44 100644 --- a/src/vs/workbench/parts/output/common/outputServices.ts +++ b/src/vs/workbench/parts/output/common/outputServices.ts @@ -13,7 +13,7 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage'; import {Registry} from 'vs/platform/platform'; import {EditorOptions} from 'vs/workbench/common/editor'; -import {IOutputEvent, IOutputService, Extensions, OUTPUT_PANEL_ID, IOutputChannelRegistry, MAX_OUTPUT_LENGTH} from 'vs/workbench/parts/output/common/output'; +import {IOutputEvent, IOutputChannel, IOutputService, Extensions, OUTPUT_PANEL_ID, IOutputChannelRegistry, MAX_OUTPUT_LENGTH} from 'vs/workbench/parts/output/common/output'; import {OutputEditorInput} from 'vs/workbench/parts/output/common/outputEditorInput'; import {OutputPanel} from 'vs/workbench/parts/output/browser/outputPanel'; import {IPanelService} from 'vs/workbench/services/panel/common/panelService'; @@ -60,13 +60,20 @@ export class OutputService implements IOutputService { return this._onActiveOutputChannel.event; } - public append(channel: string, output: string): void { + public getOutputChannel(id: string): IOutputChannel { + return { + append: (output: string) => this.append(id, output), + clear: () => this.clearOutput(id) + }; + } + + private append(channelId: string, output: string): void { // Initialize - if (!this.receivedOutput[channel]) { - this.receivedOutput[channel] = ''; + if (!this.receivedOutput[channelId]) { + this.receivedOutput[channelId] = ''; - this._onOutputChannel.fire(channel); // emit event that we have a new channel + this._onOutputChannel.fire(channelId); // emit event that we have a new channel } // Sanitize @@ -74,10 +81,10 @@ export class OutputService implements IOutputService { // Store if (output) { - this.receivedOutput[channel] = strings.appendWithLimit(this.receivedOutput[channel], output, MAX_OUTPUT_LENGTH); + this.receivedOutput[channelId] = strings.appendWithLimit(this.receivedOutput[channelId], output, MAX_OUTPUT_LENGTH); } - this._onOutput.fire({ output: output, channel }); + this._onOutput.fire({ output: output, channelId: channelId }); } public getOutput(channel: string): string { @@ -95,7 +102,7 @@ export class OutputService implements IOutputService { public clearOutput(channel: string): void { this.receivedOutput[channel] = ''; - this._onOutput.fire({ channel: channel, output: null /* indicator to clear output */ }); + this._onOutput.fire({ channelId: channel, output: null /* indicator to clear output */ }); } public showOutput(channel: string, preserveFocus?: boolean): TPromise { diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index 86288ce4886aaf1c4102a81fd792c49b8e45ed59..6657a1d0af1a5e3b929b72e3223c8949466dc0cd 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -182,20 +182,21 @@ class ConfigureTaskRunnerAction extends Action { } let contentPromise: TPromise; if (selection.autoDetect) { - this.outputService.showOutput(TaskService.OutputChannel); - this.outputService.append(TaskService.OutputChannel, nls.localize('ConfigureTaskRunnerAction.autoDetecting', 'Auto detecting tasks for {0}', selection.id) + '\n'); + this.outputService.showOutput(TaskService.OutputChannelId); + const outputChannel = this.outputService.getOutputChannel(TaskService.OutputChannelId); + outputChannel.append(nls.localize('ConfigureTaskRunnerAction.autoDetecting', 'Auto detecting tasks for {0}', selection.id) + '\n'); let detector = new ProcessRunnerDetector(this.fileService, this.contextService, new SystemVariables(this.editorService, this.contextService)); contentPromise = detector.detect(false, selection.id).then((value) => { let config = value.config; if (value.stderr && value.stderr.length > 0) { value.stderr.forEach((line) => { - this.outputService.append(TaskService.OutputChannel, line + '\n'); + outputChannel.append(line + '\n'); }); this.messageService.show(Severity.Warning, nls.localize('ConfigureTaskRunnerAction.autoDetect', 'Auto detecting the task system failed. Using default template. Consult the task output for details.')); return selection.content; } else if (config) { if (value.stdout && value.stdout.length > 0) { - value.stdout.forEach(line => this.outputService.append(TaskService.OutputChannel, line + '\n')); + value.stdout.forEach(line => outputChannel.append(line + '\n')); } let content = JSON.stringify(config, null, '\t'); content = [ @@ -287,7 +288,7 @@ class ShowLogAction extends AbstractTaskAction { } public run(): Promise { - return this.outputService.showOutput(TaskService.OutputChannel); + return this.outputService.showOutput(TaskService.OutputChannelId); } } @@ -452,7 +453,7 @@ interface TaskServiceEventData { class TaskService extends EventEmitter implements ITaskService { public serviceId = ITaskService; public static SERVICE_ID: string = 'taskService'; - public static OutputChannel:string = 'tasks'; + public static OutputChannelId:string = 'tasks'; public static OutputChannelLabel:string = nls.localize('tasks', "Tasks"); private modeService: IModeService; @@ -545,8 +546,9 @@ class TaskService extends EventEmitter implements ITaskService { } } if (isAffected) { - this.outputService.append(TaskService.OutputChannel, nls.localize('TaskSystem.invalidTaskJson', 'Error: The content of the tasks.json file has syntax errors. Please correct them before executing a task.\n')); - this.outputService.showOutput(TaskService.OutputChannel, true); + const outputChannel = this.outputService.getOutputChannel(TaskService.OutputChannelId); + outputChannel.append(nls.localize('TaskSystem.invalidTaskJson', 'Error: The content of the tasks.json file has syntax errors. Please correct them before executing a task.\n')); + this.outputService.showOutput(TaskService.OutputChannelId, true); return TPromise.wrapError({}); } } @@ -594,7 +596,7 @@ class TaskService extends EventEmitter implements ITaskService { if (config.buildSystem === 'service') { result = new LanguageServiceTaskSystem(config, this.telemetryService, this.modeService); } else if (this.isRunnerConfig(config)) { - result = new ProcessRunnerSystem(config, variables, this.markerService, this.modelService, this.telemetryService, this.outputService, TaskService.OutputChannel, clearOutput); + result = new ProcessRunnerSystem(config, variables, this.markerService, this.modelService, this.telemetryService, this.outputService, TaskService.OutputChannelId, clearOutput); } if (result === null) { this._taskSystemPromise = null; @@ -618,9 +620,10 @@ class TaskService extends EventEmitter implements ITaskService { if (stderr && stderr.length > 0) { stderr.forEach((line) => { result = false; - this.outputService.append(TaskService.OutputChannel, line + '\n'); + const outputChannel = this.outputService.getOutputChannel(TaskService.OutputChannelId); + outputChannel.append(line + '\n'); }); - this.outputService.showOutput(TaskService.OutputChannel, true); + this.outputService.showOutput(TaskService.OutputChannelId, true); } return result; } @@ -784,7 +787,7 @@ class TaskService extends EventEmitter implements ITaskService { this.messageService.show(Severity.Error, nls.localize('TaskSystem.unknownError', 'An error has occurred while running a task. See task log for details.')); } if (showOutput) { - this.outputService.showOutput(TaskService.OutputChannel, true); + this.outputService.showOutput(TaskService.OutputChannelId, true); } } } @@ -832,7 +835,7 @@ if (Env.enableTasks) { // Output channel let outputChannelRegistry = Registry.as(OutputExt.OutputChannels); - outputChannelRegistry.registerChannel(TaskService.OutputChannel, TaskService.OutputChannelLabel); + outputChannelRegistry.registerChannel(TaskService.OutputChannelId, TaskService.OutputChannelLabel); (Registry.as(WorkbenchExtensions.Workbench)).registerWorkbenchContribution(TaskServiceParticipant); diff --git a/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts b/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts index 87dbe6edd86ac4ac46899808bd22927f49f37594..9593d57215675b9edada713393a1c2216f654cdb 100644 --- a/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts +++ b/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts @@ -39,7 +39,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { private markerService: IMarkerService; private modelService: IModelService; private outputService: IOutputService; - private outputChannel: string; + private outputChannelId: string; private telemetryService: ITelemetryService; private validationStatus: ValidationStatus; @@ -57,7 +57,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { this.variables = variables; this.markerService = markerService; this.modelService = modelService; - this.outputChannel = outputChannel; + this.outputChannelId = outputChannel; this.outputService = outputService; this.telemetryService = telemetryService; @@ -77,7 +77,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { this.defaultTestTaskIdentifier = parseResult.defaultTestTaskIdentifier; if (!this.validationStatus.isOK()) { - this.outputService.showOutput(this.outputChannel, true); + this.outputService.showOutput(this.outputChannelId, true); } } @@ -177,10 +177,12 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { throw err; } else if (err instanceof Error) { let error = err; - this.outputService.append(this.outputChannel, error.message); + const outputChannel = this.outputService.getOutputChannel(this.outputChannelId); + outputChannel.append(error.message); throw new TaskError(Severity.Error, error.message, TaskErrors.UnknownError); } else { - this.outputService.append(this.outputChannel, err.toString()); + const outputChannel = this.outputService.getOutputChannel(this.outputChannelId); + outputChannel.append(err.toString()); throw new TaskError(Severity.Error, nls.localize('TaskRunnerSystem.unknownError', 'A unknown error has occurred while executing a task. See task output log for details.'), TaskErrors.UnknownError); } } @@ -267,7 +269,8 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { return this.handleError(task, error); }, (progress: LineData) => { let line = Strings.removeAnsiEscapeCodes(progress.line); - this.outputService.append(this.outputChannel, line + '\n'); + const outputChannel = this.outputService.getOutputChannel(this.outputChannelId); + outputChannel.append(line + '\n'); watchingProblemMatcher.processLine(line); if (delayer === null) { delayer = new Async.Delayer(3000); @@ -304,7 +307,8 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { return this.handleError(task, error); }, (progress) => { let line = Strings.removeAnsiEscapeCodes(progress.line); - this.outputService.append(this.outputChannel, line + '\n'); + const outputChannel = this.outputService.getOutputChannel(this.outputChannelId); + outputChannel.append(line + '\n'); startStopProblemMatcher.processLine(line); }); return { promise }; @@ -321,16 +325,16 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { if (error.error && !error.terminated) { let args:string = this.configuration.args ? this.configuration.args.join(' ') : ''; this.log(nls.localize('TaskRunnerSystem.childProcessError', 'Failed to launch external program {0} {1}.', this.configuration.command, args)); - this.outputService.append(this.outputChannel, error.error.message); + this.outputService.getOutputChannel(this.outputChannelId).append(error.error.message); makeVisible = true; } if (error.stdout) { - this.outputService.append(this.outputChannel, error.stdout); + this.outputService.getOutputChannel(this.outputChannelId).append(error.stdout); makeVisible = true; } if (error.stderr) { - this.outputService.append(this.outputChannel, error.stderr); + this.outputService.getOutputChannel(this.outputChannelId).append(error.stderr); makeVisible = true; } makeVisible = this.checkTerminated(task, error) || makeVisible; @@ -398,14 +402,14 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { } public log(value: string): void { - this.outputService.append(this.outputChannel, value + '\n'); + this.outputService.getOutputChannel(this.outputChannelId).append(value + '\n'); } private showOutput(): void { - this.outputService.showOutput(this.outputChannel, true); + this.outputService.showOutput(this.outputChannelId, true); } private clearOutput(): void { - this.outputService.clearOutput(this.outputChannel); + this.outputService.clearOutput(this.outputChannelId); } } \ No newline at end of file