diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index ea2582295ea..278937b88ca 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -2421,10 +2421,9 @@ declare namespace vscode { /** * Reveal this channel in the UI. * - * @param column The column in which to show the channel, default in [one](#ViewColumn.One). * @param preserveFocus When `true` the channel will not take focus. */ - show(column?: ViewColumn, preserveFocus?: boolean): void; + show(preserveFocus?: boolean): void; /** * Hide this channel from the UI. diff --git a/src/vs/workbench/api/node/extHostOutputService.ts b/src/vs/workbench/api/node/extHostOutputService.ts index 90fb7faeaff..a455d036c58 100644 --- a/src/vs/workbench/api/node/extHostOutputService.ts +++ b/src/vs/workbench/api/node/extHostOutputService.ts @@ -47,8 +47,8 @@ export class ExtHostOutputChannel implements vscode.OutputChannel { this._proxy.clear(this._name); } - show(column?: vscode.ViewColumn, preserveFocus?: boolean): void { - this._proxy.reveal(this._name, TypeConverters.fromViewColumn(column), preserveFocus); + show(preserveFocus?: boolean): void { + this._proxy.reveal(this._name, preserveFocus); } hide(): void { @@ -95,8 +95,8 @@ export class MainThreadOutputService { return undefined; } - public reveal(channel: string, position: Position, preserveFocus: boolean): TPromise { - this._outputService.showOutput(channel, position, preserveFocus); + public reveal(channel: string, preserveFocus: boolean): TPromise { + this._outputService.showOutput(channel, preserveFocus); return undefined; } diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 5f0a2044275..35c5d47db3c 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -564,7 +564,7 @@ export class DebugService extends ee.EventEmitter implements debug.IDebugService } // no task running, execute the preLaunchTask. - this.outputService.showOutput('Tasks', true, true); + this.outputService.showOutput('Tasks', true); const taskPromise = this.taskService.run(filteredTasks[0].id).then(result => { this.lastTaskEvent = null; diff --git a/src/vs/workbench/parts/output/browser/outputActions.ts b/src/vs/workbench/parts/output/browser/outputActions.ts index 74025236792..3e612a206cb 100644 --- a/src/vs/workbench/parts/output/browser/outputActions.ts +++ b/src/vs/workbench/parts/output/browser/outputActions.ts @@ -69,9 +69,7 @@ export class GlobalShowOutputAction extends Action { channelToOpen = (Registry.as(Extensions.OutputChannels)).getChannels()[0]; } - let sideBySide = !!(event && (event.ctrlKey || event.metaKey)); - - return this.outputService.showOutput(channelToOpen, sideBySide, false /* Do not preserve Focus */); + return this.outputService.showOutput(channelToOpen, false /* Do not preserve Focus */); } } diff --git a/src/vs/workbench/parts/output/common/output.ts b/src/vs/workbench/parts/output/common/output.ts index 4513699d82a..a95b65cdfda 100644 --- a/src/vs/workbench/parts/output/common/output.ts +++ b/src/vs/workbench/parts/output/common/output.ts @@ -89,7 +89,7 @@ export interface IOutputService { * The optional channel allows to show the output for a specific channel. If you leave the * channel out, you show the default channels output. */ - showOutput(channel?: string, sideBySide?: boolean|Position, preserveFocus?: boolean): TPromise; + showOutput(channel?: string, preserveFocus?: boolean): TPromise; /** * Allows to register on Output events @@ -100,6 +100,11 @@ export interface IOutputService { * Allows to register on a new Output channel getting filled with output */ onOutputChannel: Event; + + /** + * Reveals the last line on the editor that has the passed channel set as output. + */ + revealLastLine(): void; } export interface IOutputChannelRegistry { diff --git a/src/vs/workbench/parts/output/common/outputServices.ts b/src/vs/workbench/parts/output/common/outputServices.ts index 7fd1d0bc243..79cdb5bac7b 100644 --- a/src/vs/workbench/parts/output/common/outputServices.ts +++ b/src/vs/workbench/parts/output/common/outputServices.ts @@ -2,7 +2,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import {Promise, TPromise} from 'vs/base/common/winjs.base'; import strings = require('vs/base/common/strings'); @@ -10,11 +9,12 @@ import Event, {Emitter} from 'vs/base/common/event'; import {EditorOptions} from 'vs/workbench/common/editor'; import {OUTPUT_MIME, DEFAULT_OUTPUT_CHANNEL, IOutputEvent, IOutputService} from 'vs/workbench/parts/output/common/output'; import {OutputEditorInput} from 'vs/workbench/parts/output/common/outputEditorInput'; -import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService'; import {IEditor, Position} from 'vs/platform/editor/common/editor'; import {IEventService} from 'vs/platform/event/common/event'; import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle'; +import {OUTPUT_PANEL_ID} from 'vs/workbench/parts/output/common/output'; import {OutputPanel} from 'vs/workbench/parts/output/browser/outputPanel'; +import {IPanelService} from 'vs/workbench/services/panel/common/panelService'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; export class OutputService implements IOutputService { @@ -24,6 +24,7 @@ export class OutputService implements IOutputService { private static OUTPUT_DELAY = 300; // delay in ms to accumulate output before emitting an event about it private receivedOutput: { [channel: string]: string; }; + private outputPanel: OutputPanel; private sendOutputEventsTimerId: number; private lastSentOutputEventsTime: number; @@ -35,8 +36,8 @@ export class OutputService implements IOutputService { constructor( @IInstantiationService private instantiationService: IInstantiationService, @IEventService private eventService: IEventService, - @IWorkbenchEditorService private editorService: IWorkbenchEditorService, - @ILifecycleService private lifecycleService: ILifecycleService + @ILifecycleService private lifecycleService: ILifecycleService, + @IPanelService private panelService: IPanelService ) { this._onOutput = new Emitter(); this._onOutputChannel = new Emitter(); @@ -162,38 +163,30 @@ export class OutputService implements IOutputService { this._onOutput.fire({ channel: channel, output: null /* indicator to clear output */ }); } - public showOutput(channel: string = DEFAULT_OUTPUT_CHANNEL, sideBySide?: boolean | Position, preserveFocus?: boolean): TPromise { - - // If already opened, focus it unless we want to preserve focus - let existingOutputEditor = this.findOutputEditor(channel); - if (existingOutputEditor) { - if (!preserveFocus) { - return this.editorService.focusEditor(existingOutputEditor); - } - - // Still reveal last line - (existingOutputEditor).revealLastLine(); - - return Promise.as(existingOutputEditor); - } - - // Otherwise open new - return this.editorService.openEditor(OutputEditorInput.getInstance(this.instantiationService, channel), preserveFocus ? EditorOptions.create({ preserveFocus: true }) : null, sideBySide); + public showOutput(channel: string = DEFAULT_OUTPUT_CHANNEL, preserveFocus?: boolean): TPromise { + return this.panelService.openPanel(OUTPUT_PANEL_ID, !preserveFocus).then((panel: OutputPanel) => { + this.outputPanel = panel; + return this.setChannel(channel).then(() => this.outputPanel); + }); } - private findOutputEditor(channel: string): IEditor { - let editors = this.editorService.getVisibleEditors(); - for (let i = 0; i < editors.length; i++) { - let editor = editors[i]; - if (editor.input instanceof OutputEditorInput && (editor.input).getChannel() === channel && (editor.input).getMime() === OUTPUT_MIME) { - return editor; - } + public revealLastLine(): void { + if (this.outputPanel) { + this.outputPanel.revealLastLine(); + } + } + + private setChannel(channel: string): Promise { + const input = OutputEditorInput.getInstance(this.instantiationService, channel); + if (this.outputPanel.getInput().getId() !== input.getId()) { + return this.outputPanel.setInput(input, EditorOptions.create({ preserveFocus: true })); } - return null; + return Promise.as(null); } public dispose(): void { + this.outputPanel.dispose(); if (this.sendOutputEventsTimerId !== -1) { clearTimeout(this.sendOutputEventsTimerId); this.sendOutputEventsTimerId = -1; 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 a5cc94314ad..f2875ff79ef 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -214,7 +214,7 @@ class ConfigureTaskRunnerAction extends Action { forceOpen: true } }, sideBySide).then((value) => { - this.outputService.showOutput(TaskService.OutputChannel, true, true); + this.outputService.showOutput(TaskService.OutputChannel, true); return value; }); }, (error) => { @@ -531,7 +531,7 @@ 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, true); + this.outputService.showOutput(TaskService.OutputChannel, true); return TPromise.wrapError({}); } } @@ -605,7 +605,7 @@ class TaskService extends EventEmitter implements ITaskService { result = false; this.outputService.append(TaskService.OutputChannel, line + '\n'); }); - this.outputService.showOutput(TaskService.OutputChannel, true, true); + this.outputService.showOutput(TaskService.OutputChannel, true); } return result; } @@ -761,7 +761,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, false, true); + this.outputService.showOutput(TaskService.OutputChannel, true); } } } diff --git a/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts b/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts index 42f65c9b04a..1a5f767391c 100644 --- a/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts +++ b/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts @@ -76,7 +76,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { this.defaultTestTaskIdentifier = parseResult.defaultTestTaskIdentifier; if (!this.validationStatus.isOK()) { - this.outputService.showOutput(this.outputChannel, false, true); + this.outputService.showOutput(this.outputChannel, true); } } @@ -394,7 +394,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { } private showOutput(): void { - this.outputService.showOutput(this.outputChannel, true, true); + this.outputService.showOutput(this.outputChannel, true); } private clearOutput(): void {