Path: blob/main/src/vs/workbench/contrib/customEditor/common/extensionPoint.ts
3296 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 { 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, CustomEditorSelector } 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});2324export interface ICustomEditorsExtensionPoint {25readonly [Fields.viewType]: string;26readonly [Fields.displayName]: string;27readonly [Fields.selector]?: readonly CustomEditorSelector[];28readonly [Fields.priority]?: string;29}3031const CustomEditorsContribution: IJSONSchema = {32description: nls.localize('contributes.customEditors', 'Contributed custom editors.'),33type: 'array',34defaultSnippets: [{35body: [{36[Fields.viewType]: '$1',37[Fields.displayName]: '$2',38[Fields.selector]: [{39filenamePattern: '$3'40}],41}]42}],43items: {44type: 'object',45required: [46Fields.viewType,47Fields.displayName,48Fields.selector,49],50properties: {51[Fields.viewType]: {52type: 'string',53markdownDescription: 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).'),54},55[Fields.displayName]: {56type: 'string',57description: nls.localize('contributes.displayName', 'Human readable name of the custom editor. This is displayed to users when selecting which editor to use.'),58},59[Fields.selector]: {60type: 'array',61description: nls.localize('contributes.selector', 'Set of globs that the custom editor is enabled for.'),62items: {63type: 'object',64defaultSnippets: [{65body: {66filenamePattern: '$1',67}68}],69properties: {70filenamePattern: {71type: 'string',72description: nls.localize('contributes.selector.filenamePattern', 'Glob that the custom editor is enabled for.'),73},74}75}76},77[Fields.priority]: {78type: 'string',79markdownDeprecationMessage: 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.'),80enum: [81CustomEditorPriority.default,82CustomEditorPriority.option,83],84markdownEnumDescriptions: [85nls.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.'),86nls.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.'),87],88default: 'default'89}90}91}92};9394export const customEditorsExtensionPoint = ExtensionsRegistry.registerExtensionPoint<ICustomEditorsExtensionPoint[]>({95extensionPoint: 'customEditors',96deps: [languagesExtPoint],97jsonSchema: CustomEditorsContribution,98activationEventsGenerator: (contribs: ICustomEditorsExtensionPoint[], result: { push(item: string): void }) => {99for (const contrib of contribs) {100const viewType = contrib[Fields.viewType];101if (viewType) {102result.push(`onCustomEditor:${viewType}`);103}104}105},106});107108class CustomEditorsDataRenderer extends Disposable implements IExtensionFeatureTableRenderer {109110readonly type = 'table';111112shouldRender(manifest: IExtensionManifest): boolean {113return !!manifest.contributes?.customEditors;114}115116render(manifest: IExtensionManifest): IRenderedData<ITableData> {117const customEditors = manifest.contributes?.customEditors || [];118if (!customEditors.length) {119return { data: { headers: [], rows: [] }, dispose: () => { } };120}121122const headers = [123nls.localize('customEditors view type', "View Type"),124nls.localize('customEditors priority', "Priority"),125nls.localize('customEditors filenamePattern', "Filename Pattern"),126];127128const rows: IRowData[][] = customEditors129.map(customEditor => {130return [131customEditor.viewType,132customEditor.priority ?? '',133coalesce(customEditor.selector.map(x => x.filenamePattern)).join(', ')134];135});136137return {138data: {139headers,140rows141},142dispose: () => { }143};144}145}146147Registry.as<IExtensionFeaturesRegistry>(Extensions.ExtensionFeaturesRegistry).registerExtensionFeature({148id: 'customEditors',149label: nls.localize('customEditors', "Custom Editors"),150access: {151canToggle: false152},153renderer: new SyncDescriptor(CustomEditorsDataRenderer),154});155156157