Path: blob/main/src/vs/workbench/contrib/customEditor/common/extensionPoint.ts
5267 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { coalesce } from '../../../../base/common/arrays.js';6import { TypeFromJsonSchema, IJSONSchema } from '../../../../base/common/jsonSchema.js';7import { Disposable } from '../../../../base/common/lifecycle.js';8import * as nls from '../../../../nls.js';9import { IExtensionManifest } from '../../../../platform/extensions/common/extensions.js';10import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';11import { Registry } from '../../../../platform/registry/common/platform.js';12import { CustomEditorPriority } from './customEditor.js';13import { Extensions, IExtensionFeatureTableRenderer, IExtensionFeaturesRegistry, IRenderedData, IRowData, ITableData } from '../../../services/extensionManagement/common/extensionFeatures.js';14import { ExtensionsRegistry } from '../../../services/extensions/common/extensionsRegistry.js';15import { languagesExtPoint } from '../../../services/language/common/languageService.js';1617const Fields = Object.freeze({18viewType: 'viewType',19displayName: 'displayName',20selector: 'selector',21priority: 'priority',22});2324const customEditorsContributionSchema = {25type: 'object',26required: [27Fields.viewType,28Fields.displayName,29Fields.selector,30],31additionalProperties: false,32properties: {33[Fields.viewType]: {34type: 'string',35markdownDescription: nls.localize('contributes.viewType', 'Identifier for the custom editor. This must be unique across all custom editors, so we recommend including your extension id as part of `viewType`. The `viewType` is used when registering custom editors with `vscode.registerCustomEditorProvider` and in the `onCustomEditor:${id}` [activation event](https://code.visualstudio.com/api/references/activation-events).'),36},37[Fields.displayName]: {38type: 'string',39description: nls.localize('contributes.displayName', 'Human readable name of the custom editor. This is displayed to users when selecting which editor to use.'),40},41[Fields.selector]: {42type: 'array',43description: nls.localize('contributes.selector', 'Set of globs that the custom editor is enabled for.'),44items: {45type: 'object',46defaultSnippets: [{47body: {48filenamePattern: '$1',49}50}],51additionalProperties: false,52properties: {53filenamePattern: {54type: 'string',55description: nls.localize('contributes.selector.filenamePattern', 'Glob that the custom editor is enabled for.'),56},57}58}59},60[Fields.priority]: {61type: 'string',62markdownDeprecationMessage: nls.localize('contributes.priority', 'Controls if the custom editor is enabled automatically when the user opens a file. This may be overridden by users using the `workbench.editorAssociations` setting.'),63enum: [64CustomEditorPriority.default,65CustomEditorPriority.option,66],67markdownEnumDescriptions: [68nls.localize('contributes.priority.default', 'The editor is automatically used when the user opens a resource, provided that no other default custom editors are registered for that resource.'),69nls.localize('contributes.priority.option', 'The editor is not automatically used when the user opens a resource, but a user can switch to the editor using the `Reopen With` command.'),70],71default: CustomEditorPriority.default72}73}74} as const satisfies IJSONSchema;7576export type ICustomEditorsExtensionPoint = TypeFromJsonSchema<typeof customEditorsContributionSchema>;7778export const customEditorsExtensionPoint = ExtensionsRegistry.registerExtensionPoint<ICustomEditorsExtensionPoint[]>({79extensionPoint: 'customEditors',80deps: [languagesExtPoint],81jsonSchema: {82description: nls.localize('contributes.customEditors', 'Contributed custom editors.'),83type: 'array',84defaultSnippets: [{85body: [{86[Fields.viewType]: '$1',87[Fields.displayName]: '$2',88[Fields.selector]: [{89filenamePattern: '$3'90}],91}]92}],93items: customEditorsContributionSchema94},95activationEventsGenerator: function* (contribs: readonly ICustomEditorsExtensionPoint[]) {96for (const contrib of contribs) {97const viewType = contrib[Fields.viewType];98if (viewType) {99yield `onCustomEditor:${viewType}`;100}101}102},103});104105class CustomEditorsDataRenderer extends Disposable implements IExtensionFeatureTableRenderer {106107readonly type = 'table';108109shouldRender(manifest: IExtensionManifest): boolean {110return !!manifest.contributes?.customEditors;111}112113render(manifest: IExtensionManifest): IRenderedData<ITableData> {114const customEditors = manifest.contributes?.customEditors || [];115if (!customEditors.length) {116return { data: { headers: [], rows: [] }, dispose: () => { } };117}118119const headers = [120nls.localize('customEditors view type', "View Type"),121nls.localize('customEditors priority', "Priority"),122nls.localize('customEditors filenamePattern', "Filename Pattern"),123];124125const rows: IRowData[][] = customEditors126.map(customEditor => {127return [128customEditor.viewType,129customEditor.priority ?? '',130coalesce(customEditor.selector.map(x => x.filenamePattern)).join(', ')131];132});133134return {135data: {136headers,137rows138},139dispose: () => { }140};141}142}143144Registry.as<IExtensionFeaturesRegistry>(Extensions.ExtensionFeaturesRegistry).registerExtensionFeature({145id: 'customEditors',146label: nls.localize('customEditors', "Custom Editors"),147access: {148canToggle: false149},150renderer: new SyncDescriptor(CustomEditorsDataRenderer),151});152153154