From 1ecb5f53a739dd84c66b51e2be1ea7f440141db7 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Mon, 17 Jan 2022 21:29:04 +0000 Subject: [PATCH 1/2] Add optional languageId to window.createOutputChannel API (#19561) --- .../api/browser/mainThreadOutputService.ts | 4 ++-- .../workbench/api/common/extHost.api.impl.ts | 7 +++++-- .../workbench/api/common/extHost.protocol.ts | 2 +- src/vs/workbench/api/common/extHostOutput.ts | 8 ++++---- .../contrib/output/browser/outputServices.ts | 4 ++-- .../output/common/outputChannelModel.ts | 13 +++++++----- .../common/outputChannelModelService.ts | 6 +++--- .../common/extensionsApiProposals.ts | 1 + .../services/output/common/output.ts | 1 + ...vscode.proposed.outputChannelLanguage.d.ts | 20 +++++++++++++++++++ 10 files changed, 47 insertions(+), 19 deletions(-) create mode 100644 src/vscode-dts/vscode.proposed.outputChannelLanguage.d.ts diff --git a/src/vs/workbench/api/browser/mainThreadOutputService.ts b/src/vs/workbench/api/browser/mainThreadOutputService.ts index 5e29097d76ec5..42b714e7fdbf5 100644 --- a/src/vs/workbench/api/browser/mainThreadOutputService.ts +++ b/src/vs/workbench/api/browser/mainThreadOutputService.ts @@ -42,12 +42,12 @@ export class MainThreadOutputService extends Disposable implements MainThreadOut setVisibleChannel(); } - public async $register(label: string, log: boolean, file: UriComponents, extensionId: string): Promise { + public async $register(label: string, log: boolean, file: UriComponents, languageId: string, extensionId: string): Promise { const idCounter = (MainThreadOutputService._extensionIdPool.get(extensionId) || 0) + 1; MainThreadOutputService._extensionIdPool.set(extensionId, idCounter); const id = `extension-output-${extensionId}-#${idCounter}`; - Registry.as(Extensions.OutputChannels).registerChannel({ id, label, file: URI.revive(file), log }); + Registry.as(Extensions.OutputChannels).registerChannel({ id, label, file: URI.revive(file), log, languageId }); this._register(toDisposable(() => this.$dispose(id))); return id; } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index dca91a00f0f60..1200f97e0ce18 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -648,8 +648,11 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I withProgress(options: vscode.ProgressOptions, task: (progress: vscode.Progress<{ message?: string; worked?: number }>, token: vscode.CancellationToken) => Thenable) { return extHostProgress.withProgress(extension, options, task); }, - createOutputChannel(name: string): vscode.OutputChannel { - return extHostOutputService.createOutputChannel(name, extension); + createOutputChannel(name: string, languageId?: string): vscode.OutputChannel { + if (languageId) { + checkProposedApiEnabled(extension, 'outputChannelLanguage'); + } + return extHostOutputService.createOutputChannel(name, languageId || '', extension); }, createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean }, options?: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel { return extHostWebviewPanels.createWebviewPanel(extension, viewType, title, showOptions, options); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 61af6759cb5a1..3c3716ffd23c5 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -467,7 +467,7 @@ export interface MainThreadMessageServiceShape extends IDisposable { } export interface MainThreadOutputServiceShape extends IDisposable { - $register(label: string, log: boolean, file: UriComponents, extensionId: string): Promise; + $register(label: string, log: boolean, file: UriComponents, languageId: string, extensionId: string): Promise; $update(channelId: string, mode: OutputChannelUpdateMode.Append): Promise; $update(channelId: string, mode: OutputChannelUpdateMode, till: number): Promise; $reveal(channelId: string, preserveFocus: boolean): Promise; diff --git a/src/vs/workbench/api/common/extHostOutput.ts b/src/vs/workbench/api/common/extHostOutput.ts index 186031d7205f5..26df54d460717 100644 --- a/src/vs/workbench/api/common/extHostOutput.ts +++ b/src/vs/workbench/api/common/extHostOutput.ts @@ -117,12 +117,12 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape { } } - createOutputChannel(name: string, extension: IExtensionDescription): vscode.OutputChannel { + createOutputChannel(name: string, languageId: string, extension: IExtensionDescription): vscode.OutputChannel { name = name.trim(); if (!name) { throw new Error('illegal argument `name`. must not be falsy'); } - const extHostOutputChannel = this.doCreateOutputChannel(name, extension); + const extHostOutputChannel = this.doCreateOutputChannel(name, languageId, extension); extHostOutputChannel.then(channel => { this.channels.set(channel.id, channel); channel.visible = channel.id === this.visibleChannelId; @@ -130,11 +130,11 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape { return this.createExtHostOutputChannel(name, extHostOutputChannel); } - private async doCreateOutputChannel(name: string, extension: IExtensionDescription): Promise { + private async doCreateOutputChannel(name: string, languageId: string, extension: IExtensionDescription): Promise { const outputDir = await this.createOutputDirectory(); const file = this.extHostFileSystemInfo.extUri.joinPath(outputDir, `${this.namePool++}-${name.replace(/[\\/:\*\?"<>\|]/g, '')}.log`); const logger = this.loggerService.createLogger(file, { always: true, donotRotate: true, donotUseFormatters: true }); - const id = await this.proxy.$register(name, false, file, extension.identifier.value); + const id = await this.proxy.$register(name, false, file, languageId, extension.identifier.value); return new ExtHostOutputChannel(id, name, logger, this.proxy); } diff --git a/src/vs/workbench/contrib/output/browser/outputServices.ts b/src/vs/workbench/contrib/output/browser/outputServices.ts index a8dc8204d1bb0..900f4b5d12154 100644 --- a/src/vs/workbench/contrib/output/browser/outputServices.ts +++ b/src/vs/workbench/contrib/output/browser/outputServices.ts @@ -39,7 +39,7 @@ class OutputChannel extends Disposable implements IOutputChannel { this.id = outputChannelDescriptor.id; this.label = outputChannelDescriptor.label; this.uri = URI.from({ scheme: OUTPUT_SCHEME, path: this.id }); - this.model = this._register(outputChannelModelService.createOutputChannelModel(this.id, this.uri, outputChannelDescriptor.log ? LOG_MIME : OUTPUT_MIME, outputChannelDescriptor.file)); + this.model = this._register(outputChannelModelService.createOutputChannelModel(this.id, this.uri, outputChannelDescriptor.log ? LOG_MIME : OUTPUT_MIME, outputChannelDescriptor.file, outputChannelDescriptor.languageId)); } append(output: string): void { @@ -216,7 +216,7 @@ export class LogContentProvider { const channelDisposables: IDisposable[] = []; const outputChannelDescriptor = this.outputService.getChannelDescriptors().filter(({ id }) => id === channelId)[0]; if (outputChannelDescriptor && outputChannelDescriptor.file) { - channelModel = this.outputChannelModelService.createOutputChannelModel(channelId, resource, outputChannelDescriptor.log ? LOG_MIME : OUTPUT_MIME, outputChannelDescriptor.file); + channelModel = this.outputChannelModelService.createOutputChannelModel(channelId, resource, outputChannelDescriptor.log ? LOG_MIME : OUTPUT_MIME, outputChannelDescriptor.file, outputChannelDescriptor.languageId); channelModel.onDispose(() => dispose(channelDisposables), channelDisposables); this.channelModels.set(channelId, channelModel); } diff --git a/src/vs/workbench/contrib/output/common/outputChannelModel.ts b/src/vs/workbench/contrib/output/common/outputChannelModel.ts index 0b51f32b17628..73422d5851ba8 100644 --- a/src/vs/workbench/contrib/output/common/outputChannelModel.ts +++ b/src/vs/workbench/contrib/output/common/outputChannelModel.ts @@ -108,6 +108,7 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel private readonly modelUri: URI, private readonly mimeType: 'text/x-code-log-output' | 'text/x-code-output', private readonly file: URI, + private readonly languageId: string, @IFileService private readonly fileService: IFileService, @IModelService private readonly modelService: IModelService, @ILanguageService private readonly languageService: ILanguageService, @@ -163,7 +164,7 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel if (this.model) { this.model.setValue(content); } else { - this.model = this.modelService.createModel(content, this.languageService.createByMimeType(this.mimeType), this.modelUri); + this.model = this.modelService.createModel(content, this.languageId ? this.languageService.createById(this.languageId) : this.languageService.createByMimeType(this.mimeType), this.modelUri); this.fileHandler.watch(this.etag); const disposable = this.model.onWillDispose(() => { this.cancelModelUpdate(); @@ -326,6 +327,7 @@ class OutputChannelBackedByFile extends FileOutputChannelModel implements IOutpu modelUri: URI, mimeType: 'text/x-code-log-output' | 'text/x-code-output', file: URI, + languageId: string, @IFileService fileService: IFileService, @IModelService modelService: IModelService, @ILanguageService languageService: ILanguageService, @@ -333,7 +335,7 @@ class OutputChannelBackedByFile extends FileOutputChannelModel implements IOutpu @ILogService logService: ILogService, @IEditorWorkerService editorWorkerService: IEditorWorkerService ) { - super(modelUri, mimeType, file, fileService, modelService, languageService, logService, editorWorkerService); + super(modelUri, mimeType, file, languageId, fileService, modelService, languageService, logService, editorWorkerService); // Donot rotate to check for the file reset this.logger = loggerService.createLogger(file, { always: true, donotRotate: true, donotUseFormatters: true }); @@ -373,18 +375,19 @@ export class DelegatedOutputChannelModel extends Disposable implements IOutputCh modelUri: URI, mimeType: 'text/x-code-log-output' | 'text/x-code-output', outputDir: Promise, + languageId: string, @IInstantiationService private readonly instantiationService: IInstantiationService, @IFileService private readonly fileService: IFileService, ) { super(); - this.outputChannelModel = this.createOutputChannelModel(id, modelUri, mimeType, outputDir); + this.outputChannelModel = this.createOutputChannelModel(id, modelUri, mimeType, outputDir, languageId); } - private async createOutputChannelModel(id: string, modelUri: URI, mimeType: 'text/x-code-log-output' | 'text/x-code-output', outputDirPromise: Promise): Promise { + private async createOutputChannelModel(id: string, modelUri: URI, mimeType: 'text/x-code-log-output' | 'text/x-code-output', outputDirPromise: Promise, languageId: string): Promise { const outputDir = await outputDirPromise; const file = resources.joinPath(outputDir, `${id.replace(/[\\/:\*\?"<>\|]/g, '')}.log`); await this.fileService.createFile(file); - const outputChannelModel = this._register(this.instantiationService.createInstance(OutputChannelBackedByFile, id, modelUri, mimeType, file)); + const outputChannelModel = this._register(this.instantiationService.createInstance(OutputChannelBackedByFile, id, modelUri, mimeType, file, languageId)); this._register(outputChannelModel.onDispose(() => this._onDispose.fire())); return outputChannelModel; } diff --git a/src/vs/workbench/contrib/output/common/outputChannelModelService.ts b/src/vs/workbench/contrib/output/common/outputChannelModelService.ts index e003de09770ba..c52f15160d6d1 100644 --- a/src/vs/workbench/contrib/output/common/outputChannelModelService.ts +++ b/src/vs/workbench/contrib/output/common/outputChannelModelService.ts @@ -17,7 +17,7 @@ export const IOutputChannelModelService = createDecorator | null = null; diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index ca0a04329d453..b2cffdc6790ed 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -40,6 +40,7 @@ export const allApiProposals = Object.freeze({ notebookLiveShare: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookLiveShare.d.ts', notebookMessaging: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookMessaging.d.ts', notebookMime: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.notebookMime.d.ts', + outputChannelLanguage: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.outputChannelLanguage.d.ts', portsAttributes: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.portsAttributes.d.ts', quickPickSeparators: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.quickPickSeparators.d.ts', quickPickSortByLabel: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.quickPickSortByLabel.d.ts', diff --git a/src/vs/workbench/services/output/common/output.ts b/src/vs/workbench/services/output/common/output.ts index 1a0833dd8f1b9..7f0eab939b250 100644 --- a/src/vs/workbench/services/output/common/output.ts +++ b/src/vs/workbench/services/output/common/output.ts @@ -16,6 +16,7 @@ export interface IOutputChannelDescriptor { label: string; log: boolean; file?: URI; + languageId?: string; } export interface IFileOutputChannelDescriptor extends IOutputChannelDescriptor { diff --git a/src/vscode-dts/vscode.proposed.outputChannelLanguage.d.ts b/src/vscode-dts/vscode.proposed.outputChannelLanguage.d.ts new file mode 100644 index 0000000000000..1e863abc4fa7a --- /dev/null +++ b/src/vscode-dts/vscode.proposed.outputChannelLanguage.d.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// https://github.com/microsoft/vscode/issues/19561 + +declare module 'vscode' { + + export namespace window { + + /** + * Creates a new {@link OutputChannel output channel} with the given name. + * + * @param name Human-readable string which will be used to represent the channel in the UI. + * @param languageId The identifier of the language associated with the channel. + */ + export function createOutputChannel(name: string, languageId?: string): OutputChannel; + } +} From d20ffc5f8266ac93aab64bccd1c8116cde076b0f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 9 Feb 2022 15:09:53 +0100 Subject: [PATCH 2/2] cleabn up --- .../workbench/api/common/extHost.api.impl.ts | 2 +- .../workbench/api/common/extHost.protocol.ts | 2 +- src/vs/workbench/api/common/extHostOutput.ts | 8 +++++-- .../contrib/output/browser/outputServices.ts | 11 +++++---- .../output/common/outputChannelModel.ts | 23 ++++++++----------- .../common/outputChannelModelService.ts | 7 +++--- .../services/output/common/output.ts | 2 +- 7 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 7124a18d986c8..ba2cc271a3e53 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -653,7 +653,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I if (languageId) { checkProposedApiEnabled(extension, 'outputChannelLanguage'); } - return extHostOutputService.createOutputChannel(name, languageId || '', extension); + return extHostOutputService.createOutputChannel(name, languageId, extension); }, createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn; preserveFocus?: boolean }, options?: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel { return extHostWebviewPanels.createWebviewPanel(extension, viewType, title, showOptions, options); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 7b3d808028152..352e2b8c95a18 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -410,7 +410,7 @@ export interface MainThreadMessageServiceShape extends IDisposable { } export interface MainThreadOutputServiceShape extends IDisposable { - $register(label: string, log: boolean, file: UriComponents, languageId: string, extensionId: string): Promise; + $register(label: string, log: boolean, file: UriComponents, languageId: string | undefined, extensionId: string): Promise; $update(channelId: string, mode: OutputChannelUpdateMode, till?: number): Promise; $reveal(channelId: string, preserveFocus: boolean): Promise; $close(channelId: string): Promise; diff --git a/src/vs/workbench/api/common/extHostOutput.ts b/src/vs/workbench/api/common/extHostOutput.ts index 26df54d460717..12e6570161e44 100644 --- a/src/vs/workbench/api/common/extHostOutput.ts +++ b/src/vs/workbench/api/common/extHostOutput.ts @@ -17,6 +17,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData import { IExtHostFileSystemInfo } from 'vs/workbench/api/common/extHostFileSystemInfo'; import { toLocalISOString } from 'vs/base/common/date'; import { VSBuffer } from 'vs/base/common/buffer'; +import { isString } from 'vs/base/common/types'; export class ExtHostOutputChannel extends Disposable implements vscode.OutputChannel { @@ -117,11 +118,14 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape { } } - createOutputChannel(name: string, languageId: string, extension: IExtensionDescription): vscode.OutputChannel { + createOutputChannel(name: string, languageId: string | undefined, extension: IExtensionDescription): vscode.OutputChannel { name = name.trim(); if (!name) { throw new Error('illegal argument `name`. must not be falsy'); } + if (isString(languageId) && !languageId.trim()) { + throw new Error('illegal argument `languageId`. must not be empty'); + } const extHostOutputChannel = this.doCreateOutputChannel(name, languageId, extension); extHostOutputChannel.then(channel => { this.channels.set(channel.id, channel); @@ -130,7 +134,7 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape { return this.createExtHostOutputChannel(name, extHostOutputChannel); } - private async doCreateOutputChannel(name: string, languageId: string, extension: IExtensionDescription): Promise { + private async doCreateOutputChannel(name: string, languageId: string | undefined, extension: IExtensionDescription): Promise { const outputDir = await this.createOutputDirectory(); const file = this.extHostFileSystemInfo.extUri.joinPath(outputDir, `${this.namePool++}-${name.replace(/[\\/:\*\?"<>\|]/g, '')}.log`); const logger = this.loggerService.createLogger(file, { always: true, donotRotate: true, donotUseFormatters: true }); diff --git a/src/vs/workbench/contrib/output/browser/outputServices.ts b/src/vs/workbench/contrib/output/browser/outputServices.ts index afd393c9a3477..2002fd6402555 100644 --- a/src/vs/workbench/contrib/output/browser/outputServices.ts +++ b/src/vs/workbench/contrib/output/browser/outputServices.ts @@ -20,6 +20,7 @@ import { IOutputChannelModel } from 'vs/workbench/contrib/output/common/outputCh import { IViewsService } from 'vs/workbench/common/views'; import { OutputViewPane } from 'vs/workbench/contrib/output/browser/outputView'; import { IOutputChannelModelService } from 'vs/workbench/contrib/output/common/outputChannelModelService'; +import { ILanguageService } from 'vs/editor/common/languages/language'; const OUTPUT_ACTIVE_CHANNEL_KEY = 'output.activechannel'; @@ -33,13 +34,14 @@ class OutputChannel extends Disposable implements IOutputChannel { constructor( readonly outputChannelDescriptor: IOutputChannelDescriptor, - @IOutputChannelModelService outputChannelModelService: IOutputChannelModelService + @IOutputChannelModelService outputChannelModelService: IOutputChannelModelService, + @ILanguageService languageService: ILanguageService, ) { super(); this.id = outputChannelDescriptor.id; this.label = outputChannelDescriptor.label; this.uri = URI.from({ scheme: OUTPUT_SCHEME, path: this.id }); - this.model = this._register(outputChannelModelService.createOutputChannelModel(this.id, this.uri, outputChannelDescriptor.log ? LOG_MIME : OUTPUT_MIME, outputChannelDescriptor.file, outputChannelDescriptor.languageId)); + this.model = this._register(outputChannelModelService.createOutputChannelModel(this.id, this.uri, outputChannelDescriptor.languageId ? languageService.createById(outputChannelDescriptor.languageId) : languageService.createByMimeType(outputChannelDescriptor.log ? LOG_MIME : OUTPUT_MIME), outputChannelDescriptor.file)); } append(output: string): void { @@ -196,7 +198,8 @@ export class LogContentProvider { constructor( @IOutputService private readonly outputService: IOutputService, - @IOutputChannelModelService private readonly outputChannelModelService: IOutputChannelModelService + @IOutputChannelModelService private readonly outputChannelModelService: IOutputChannelModelService, + @ILanguageService private readonly languageService: ILanguageService ) { } @@ -217,7 +220,7 @@ export class LogContentProvider { const channelDisposables: IDisposable[] = []; const outputChannelDescriptor = this.outputService.getChannelDescriptors().filter(({ id }) => id === channelId)[0]; if (outputChannelDescriptor && outputChannelDescriptor.file) { - channelModel = this.outputChannelModelService.createOutputChannelModel(channelId, resource, outputChannelDescriptor.log ? LOG_MIME : OUTPUT_MIME, outputChannelDescriptor.file, outputChannelDescriptor.languageId); + channelModel = this.outputChannelModelService.createOutputChannelModel(channelId, resource, outputChannelDescriptor.languageId ? this.languageService.createById(outputChannelDescriptor.languageId) : this.languageService.createByMimeType(outputChannelDescriptor.log ? LOG_MIME : OUTPUT_MIME), outputChannelDescriptor.file); channelModel.onDispose(() => dispose(channelDisposables), channelDisposables); this.channelModels.set(channelId, channelModel); } diff --git a/src/vs/workbench/contrib/output/common/outputChannelModel.ts b/src/vs/workbench/contrib/output/common/outputChannelModel.ts index cf4772e2dff2c..daedaaaff8331 100644 --- a/src/vs/workbench/contrib/output/common/outputChannelModel.ts +++ b/src/vs/workbench/contrib/output/common/outputChannelModel.ts @@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri'; import { Promises, ThrottledDelayer } from 'vs/base/common/async'; import { IFileService } from 'vs/platform/files/common/files'; import { IModelService } from 'vs/editor/common/services/model'; -import { ILanguageService } from 'vs/editor/common/languages/language'; +import { ILanguageSelection } from 'vs/editor/common/languages/language'; import { Disposable, toDisposable, IDisposable, dispose, MutableDisposable } from 'vs/base/common/lifecycle'; import { isNumber } from 'vs/base/common/types'; import { EditOperation, ISingleEditOperation } from 'vs/editor/common/core/editOperation'; @@ -106,12 +106,10 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel constructor( private readonly modelUri: URI, - private readonly mimeType: 'text/x-code-log-output' | 'text/x-code-output', + private readonly language: ILanguageSelection, private readonly file: URI, - private readonly languageId: string, @IFileService private readonly fileService: IFileService, @IModelService private readonly modelService: IModelService, - @ILanguageService private readonly languageService: ILanguageService, @ILogService logService: ILogService, @IEditorWorkerService private readonly editorWorkerService: IEditorWorkerService, ) { @@ -164,7 +162,7 @@ export class FileOutputChannelModel extends Disposable implements IOutputChannel if (this.model) { this.model.setValue(content); } else { - this.model = this.modelService.createModel(content, this.languageId ? this.languageService.createById(this.languageId) : this.languageService.createByMimeType(this.mimeType), this.modelUri); + this.model = this.modelService.createModel(content, this.language, this.modelUri); this.fileHandler.watch(this.etag); const disposable = this.model.onWillDispose(() => { this.cancelModelUpdate(); @@ -325,17 +323,15 @@ class OutputChannelBackedByFile extends FileOutputChannelModel implements IOutpu constructor( id: string, modelUri: URI, - mimeType: 'text/x-code-log-output' | 'text/x-code-output', + language: ILanguageSelection, file: URI, - languageId: string, @IFileService fileService: IFileService, @IModelService modelService: IModelService, - @ILanguageService languageService: ILanguageService, @ILoggerService loggerService: ILoggerService, @ILogService logService: ILogService, @IEditorWorkerService editorWorkerService: IEditorWorkerService ) { - super(modelUri, mimeType, file, languageId, fileService, modelService, languageService, logService, editorWorkerService); + super(modelUri, language, file, fileService, modelService, logService, editorWorkerService); // Donot rotate to check for the file reset this.logger = loggerService.createLogger(file, { always: true, donotRotate: true, donotUseFormatters: true }); @@ -373,21 +369,20 @@ export class DelegatedOutputChannelModel extends Disposable implements IOutputCh constructor( id: string, modelUri: URI, - mimeType: 'text/x-code-log-output' | 'text/x-code-output', + language: ILanguageSelection, outputDir: Promise, - languageId: string, @IInstantiationService private readonly instantiationService: IInstantiationService, @IFileService private readonly fileService: IFileService, ) { super(); - this.outputChannelModel = this.createOutputChannelModel(id, modelUri, mimeType, outputDir, languageId); + this.outputChannelModel = this.createOutputChannelModel(id, modelUri, language, outputDir); } - private async createOutputChannelModel(id: string, modelUri: URI, mimeType: 'text/x-code-log-output' | 'text/x-code-output', outputDirPromise: Promise, languageId: string): Promise { + private async createOutputChannelModel(id: string, modelUri: URI, language: ILanguageSelection, outputDirPromise: Promise): Promise { const outputDir = await outputDirPromise; const file = resources.joinPath(outputDir, `${id.replace(/[\\/:\*\?"<>\|]/g, '')}.log`); await this.fileService.createFile(file); - const outputChannelModel = this._register(this.instantiationService.createInstance(OutputChannelBackedByFile, id, modelUri, mimeType, file, languageId)); + const outputChannelModel = this._register(this.instantiationService.createInstance(OutputChannelBackedByFile, id, modelUri, language, file)); this._register(outputChannelModel.onDispose(() => this._onDispose.fire())); return outputChannelModel; } diff --git a/src/vs/workbench/contrib/output/common/outputChannelModelService.ts b/src/vs/workbench/contrib/output/common/outputChannelModelService.ts index c52f15160d6d1..114b99fb652f1 100644 --- a/src/vs/workbench/contrib/output/common/outputChannelModelService.ts +++ b/src/vs/workbench/contrib/output/common/outputChannelModelService.ts @@ -11,13 +11,14 @@ import { toLocalISOString } from 'vs/base/common/date'; import { dirname, joinPath } from 'vs/base/common/resources'; import { DelegatedOutputChannelModel, FileOutputChannelModel, IOutputChannelModel } from 'vs/workbench/contrib/output/common/outputChannelModel'; import { URI } from 'vs/base/common/uri'; +import { ILanguageSelection } from 'vs/editor/common/languages/language'; export const IOutputChannelModelService = createDecorator('outputChannelModelService'); export interface IOutputChannelModelService { readonly _serviceBrand: undefined; - createOutputChannelModel(id: string, modelUri: URI, mimeType: 'text/x-code-log-output' | 'text/x-code-output', file?: URI, languageId?: string): IOutputChannelModel; + createOutputChannelModel(id: string, modelUri: URI, language: ILanguageSelection, file?: URI): IOutputChannelModel; } @@ -31,8 +32,8 @@ export abstract class AbstractOutputChannelModelService { @IInstantiationService protected readonly instantiationService: IInstantiationService ) { } - createOutputChannelModel(id: string, modelUri: URI, mimeType: 'text/x-code-log-output' | 'text/x-code-output', file?: URI, languageId?: string): IOutputChannelModel { - return file ? this.instantiationService.createInstance(FileOutputChannelModel, modelUri, mimeType, file, languageId || '') : this.instantiationService.createInstance(DelegatedOutputChannelModel, id, modelUri, mimeType, this.outputDir, languageId || ''); + createOutputChannelModel(id: string, modelUri: URI, language: ILanguageSelection, file?: URI): IOutputChannelModel { + return file ? this.instantiationService.createInstance(FileOutputChannelModel, modelUri, language, file) : this.instantiationService.createInstance(DelegatedOutputChannelModel, id, modelUri, language, this.outputDir); } private _outputDir: Promise | null = null; diff --git a/src/vs/workbench/services/output/common/output.ts b/src/vs/workbench/services/output/common/output.ts index 7f0eab939b250..f12fa430d7a12 100644 --- a/src/vs/workbench/services/output/common/output.ts +++ b/src/vs/workbench/services/output/common/output.ts @@ -15,8 +15,8 @@ export interface IOutputChannelDescriptor { id: string; label: string; log: boolean; - file?: URI; languageId?: string; + file?: URI; } export interface IFileOutputChannelDescriptor extends IOutputChannelDescriptor {