contributedCustomEditors.ts 4.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import { Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import * as nls from 'vs/nls';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
M
Matt Bierner 已提交
11 12 13
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { Memento } from 'vs/workbench/common/memento';
import { CustomEditorDescriptor, CustomEditorInfo, CustomEditorPriority } from 'vs/workbench/contrib/customEditor/common/customEditor';
14 15
import { customEditorsExtensionPoint, ICustomEditorsExtensionPoint } from 'vs/workbench/contrib/customEditor/common/extensionPoint';
import { DEFAULT_EDITOR_ID } from 'vs/workbench/contrib/files/common/files';
M
Matt Bierner 已提交
16
import { IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
17 18 19 20

const builtinProviderDisplayName = nls.localize('builtinProviderDisplayName', "Built-in");

export const defaultCustomEditor = new CustomEditorInfo({
21
	id: DEFAULT_EDITOR_ID,
22 23 24 25 26 27 28 29 30 31
	displayName: nls.localize('promptOpenWith.defaultEditor.displayName', "Text Editor"),
	providerDisplayName: builtinProviderDisplayName,
	selector: [
		{ filenamePattern: '*' }
	],
	priority: CustomEditorPriority.default,
});

export class ContributedCustomEditors extends Disposable {

M
Matt Bierner 已提交
32 33 34
	private static readonly CUSTOM_EDITORS_STORAGE_ID = 'customEditors';
	private static readonly CUSTOM_EDITORS_ENTRY_ID = 'editors';

35
	private readonly _editors = new Map<string, CustomEditorInfo>();
M
Matt Bierner 已提交
36
	private readonly _memento: Memento;
37

M
Matt Bierner 已提交
38
	constructor(storageService: IStorageService) {
39 40
		super();

M
Matt Bierner 已提交
41 42 43 44 45 46 47
		this._memento = new Memento(ContributedCustomEditors.CUSTOM_EDITORS_STORAGE_ID, storageService);

		const mementoObject = this._memento.getMemento(StorageScope.GLOBAL);
		for (const info of (mementoObject[ContributedCustomEditors.CUSTOM_EDITORS_ENTRY_ID] || []) as CustomEditorDescriptor[]) {
			this.add(new CustomEditorInfo(info));
		}

M
Matt Bierner 已提交
48
		customEditorsExtensionPoint.setHandler(extensions => {
M
Matt Bierner 已提交
49
			this.update(extensions);
50 51 52 53 54 55
		});
	}

	private readonly _onChange = this._register(new Emitter<void>());
	public readonly onChange = this._onChange.event;

M
Matt Bierner 已提交
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
	private update(extensions: readonly IExtensionPointUser<ICustomEditorsExtensionPoint[]>[]) {
		this._editors.clear();

		for (const extension of extensions) {
			for (const webviewEditorContribution of extension.value) {
				this.add(new CustomEditorInfo({
					id: webviewEditorContribution.viewType,
					displayName: webviewEditorContribution.displayName,
					providerDisplayName: extension.description.isBuiltin ? builtinProviderDisplayName : extension.description.displayName || extension.description.identifier.value,
					selector: webviewEditorContribution.selector || [],
					priority: getPriorityFromContribution(webviewEditorContribution, extension.description),
				}));
			}
		}

		const mementoObject = this._memento.getMemento(StorageScope.GLOBAL);
		mementoObject[ContributedCustomEditors.CUSTOM_EDITORS_ENTRY_ID] = Array.from(this._editors.values());
		this._memento.saveMemento();

		this._onChange.fire();
	}

78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
	public [Symbol.iterator](): Iterator<CustomEditorInfo> {
		return this._editors.values();
	}

	public get(viewType: string): CustomEditorInfo | undefined {
		return viewType === defaultCustomEditor.id
			? defaultCustomEditor
			: this._editors.get(viewType);
	}

	public getContributedEditors(resource: URI): readonly CustomEditorInfo[] {
		return Array.from(this._editors.values())
			.filter(customEditor => customEditor.matches(resource));
	}

	private add(info: CustomEditorInfo): void {
		if (info.id === defaultCustomEditor.id || this._editors.has(info.id)) {
			console.error(`Custom editor with id '${info.id}' already registered`);
			return;
		}
		this._editors.set(info.id, info);
	}
}

function getPriorityFromContribution(
M
Matt Bierner 已提交
103
	contribution: ICustomEditorsExtensionPoint,
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
	extension: IExtensionDescription,
): CustomEditorPriority {
	switch (contribution.priority) {
		case CustomEditorPriority.default:
		case CustomEditorPriority.option:
			return contribution.priority;

		case CustomEditorPriority.builtin:
			// Builtin is only valid for builtin extensions
			return extension.isBuiltin ? CustomEditorPriority.builtin : CustomEditorPriority.default;

		default:
			return CustomEditorPriority.default;
	}
}