Skip to content

Commit

Permalink
Merge pull request #140876 from gjsjohnmurray/output-channel-language
Browse files Browse the repository at this point in the history
Add optional languageId to window.createOutputChannel API (#19561)
  • Loading branch information
sandy081 authored Feb 9, 2022
2 parents 2c0cbe4 + d20ffc5 commit 4af4717
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 27 deletions.
4 changes: 2 additions & 2 deletions src/vs/workbench/api/browser/mainThreadOutputService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ export class MainThreadOutputService extends Disposable implements MainThreadOut
setVisibleChannel();
}

public async $register(label: string, log: boolean, file: UriComponents, extensionId: string): Promise<string> {
public async $register(label: string, log: boolean, file: UriComponents, languageId: string, extensionId: string): Promise<string> {
const idCounter = (MainThreadOutputService._extensionIdPool.get(extensionId) || 0) + 1;
MainThreadOutputService._extensionIdPool.set(extensionId, idCounter);
const id = `extension-output-${extensionId}-#${idCounter}`;

Registry.as<IOutputChannelRegistry>(Extensions.OutputChannels).registerChannel({ id, label, file: URI.revive(file), log });
Registry.as<IOutputChannelRegistry>(Extensions.OutputChannels).registerChannel({ id, label, file: URI.revive(file), log, languageId });
this._register(toDisposable(() => this.$dispose(id)));
return id;
}
Expand Down
7 changes: 5 additions & 2 deletions src/vs/workbench/api/common/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -649,8 +649,11 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
withProgress<R>(options: vscode.ProgressOptions, task: (progress: vscode.Progress<{ message?: string; worked?: number }>, token: vscode.CancellationToken) => Thenable<R>) {
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);
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/api/common/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ export interface MainThreadMessageServiceShape extends IDisposable {
}

export interface MainThreadOutputServiceShape extends IDisposable {
$register(label: string, log: boolean, file: UriComponents, extensionId: string): Promise<string>;
$register(label: string, log: boolean, file: UriComponents, languageId: string | undefined, extensionId: string): Promise<string>;
$update(channelId: string, mode: OutputChannelUpdateMode, till?: number): Promise<void>;
$reveal(channelId: string, preserveFocus: boolean): Promise<void>;
$close(channelId: string): Promise<void>;
Expand Down
12 changes: 8 additions & 4 deletions src/vs/workbench/api/common/extHostOutput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -117,24 +118,27 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
}
}

createOutputChannel(name: 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');
}
const extHostOutputChannel = this.doCreateOutputChannel(name, extension);
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);
channel.visible = channel.id === this.visibleChannelId;
});
return this.createExtHostOutputChannel(name, extHostOutputChannel);
}

private async doCreateOutputChannel(name: string, extension: IExtensionDescription): Promise<ExtHostOutputChannel> {
private async doCreateOutputChannel(name: string, languageId: string | undefined, extension: IExtensionDescription): Promise<ExtHostOutputChannel> {
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);
}

Expand Down
11 changes: 7 additions & 4 deletions src/vs/workbench/contrib/output/browser/outputServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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));
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 {
Expand Down Expand Up @@ -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
) {
}

Expand All @@ -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);
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);
}
Expand Down
20 changes: 9 additions & 11 deletions src/vs/workbench/contrib/output/common/outputChannelModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -106,11 +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,
@IFileService private readonly fileService: IFileService,
@IModelService private readonly modelService: IModelService,
@ILanguageService private readonly languageService: ILanguageService,
@ILogService logService: ILogService,
@IEditorWorkerService private readonly editorWorkerService: IEditorWorkerService,
) {
Expand Down Expand Up @@ -163,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.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();
Expand Down Expand Up @@ -324,16 +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,
@IFileService fileService: IFileService,
@IModelService modelService: IModelService,
@ILanguageService languageService: ILanguageService,
@ILoggerService loggerService: ILoggerService,
@ILogService logService: ILogService,
@IEditorWorkerService editorWorkerService: IEditorWorkerService
) {
super(modelUri, mimeType, file, 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 });
Expand Down Expand Up @@ -371,20 +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<URI>,
@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, language, outputDir);
}

private async createOutputChannelModel(id: string, modelUri: URI, mimeType: 'text/x-code-log-output' | 'text/x-code-output', outputDirPromise: Promise<URI>): Promise<IOutputChannelModel> {
private async createOutputChannelModel(id: string, modelUri: URI, language: ILanguageSelection, outputDirPromise: Promise<URI>): Promise<IOutputChannelModel> {
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, language, file));
this._register(outputChannelModel.onDispose(() => this._onDispose.fire()));
return outputChannelModel;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<IOutputChannelModelService>('outputChannelModelService');

export interface IOutputChannelModelService {
readonly _serviceBrand: undefined;

createOutputChannelModel(id: string, modelUri: URI, mimeType: 'text/x-code-log-output' | 'text/x-code-output', file?: URI): IOutputChannelModel;
createOutputChannelModel(id: string, modelUri: URI, language: ILanguageSelection, file?: URI): IOutputChannelModel;

}

Expand All @@ -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): IOutputChannelModel {
return file ? this.instantiationService.createInstance(FileOutputChannelModel, modelUri, mimeType, file) : this.instantiationService.createInstance(DelegatedOutputChannelModel, id, modelUri, mimeType, this.outputDir);
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<URI> | null = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,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',
quickPickSortByLabel: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.quickPickSortByLabel.d.ts',
resolvers: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.resolvers.d.ts',
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/services/output/common/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface IOutputChannelDescriptor {
id: string;
label: string;
log: boolean;
languageId?: string;
file?: URI;
}

Expand Down
20 changes: 20 additions & 0 deletions src/vscode-dts/vscode.proposed.outputChannelLanguage.d.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}

0 comments on commit 4af4717

Please sign in to comment.