Path: blob/main/src/vs/workbench/contrib/localization/common/localization.contribution.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 { Disposable } from '../../../../base/common/lifecycle.js';6import { localize } from '../../../../nls.js';7import { registerAction2 } from '../../../../platform/actions/common/actions.js';8import { IExtensionManifest } from '../../../../platform/extensions/common/extensions.js';9import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';10import { Registry } from '../../../../platform/registry/common/platform.js';11import { IWorkbenchContribution } from '../../../common/contributions.js';12import { ClearDisplayLanguageAction, ConfigureDisplayLanguageAction } from './localizationsActions.js';13import { IExtensionFeatureTableRenderer, IRenderedData, ITableData, IRowData, IExtensionFeaturesRegistry, Extensions } from '../../../services/extensionManagement/common/extensionFeatures.js';14import { ExtensionsRegistry } from '../../../services/extensions/common/extensionsRegistry.js';1516export class BaseLocalizationWorkbenchContribution extends Disposable implements IWorkbenchContribution {17constructor() {18super();1920// Register action to configure locale and related settings21registerAction2(ConfigureDisplayLanguageAction);22registerAction2(ClearDisplayLanguageAction);2324ExtensionsRegistry.registerExtensionPoint({25extensionPoint: 'localizations',26defaultExtensionKind: ['ui', 'workspace'],27jsonSchema: {28description: localize('vscode.extension.contributes.localizations', "Contributes localizations to the editor"),29type: 'array',30default: [],31items: {32type: 'object',33required: ['languageId', 'translations'],34defaultSnippets: [{ body: { languageId: '', languageName: '', localizedLanguageName: '', translations: [{ id: 'vscode', path: '' }] } }],35properties: {36languageId: {37description: localize('vscode.extension.contributes.localizations.languageId', 'Id of the language into which the display strings are translated.'),38type: 'string'39},40languageName: {41description: localize('vscode.extension.contributes.localizations.languageName', 'Name of the language in English.'),42type: 'string'43},44localizedLanguageName: {45description: localize('vscode.extension.contributes.localizations.languageNameLocalized', 'Name of the language in contributed language.'),46type: 'string'47},48translations: {49description: localize('vscode.extension.contributes.localizations.translations', 'List of translations associated to the language.'),50type: 'array',51default: [{ id: 'vscode', path: '' }],52items: {53type: 'object',54required: ['id', 'path'],55properties: {56id: {57type: 'string',58description: localize('vscode.extension.contributes.localizations.translations.id', "Id of VS Code or Extension for which this translation is contributed to. Id of VS Code is always `vscode` and of extension should be in format `publisherId.extensionName`."),59pattern: '^((vscode)|([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*))$',60patternErrorMessage: localize('vscode.extension.contributes.localizations.translations.id.pattern', "Id should be `vscode` or in format `publisherId.extensionName` for translating VS code or an extension respectively.")61},62path: {63type: 'string',64description: localize('vscode.extension.contributes.localizations.translations.path', "A relative path to a file containing translations for the language.")65}66},67defaultSnippets: [{ body: { id: '', path: '' } }],68},69}70}71}72}73});74}75}7677class LocalizationsDataRenderer extends Disposable implements IExtensionFeatureTableRenderer {7879readonly type = 'table';8081shouldRender(manifest: IExtensionManifest): boolean {82return !!manifest.contributes?.localizations;83}8485render(manifest: IExtensionManifest): IRenderedData<ITableData> {86const localizations = manifest.contributes?.localizations || [];87if (!localizations.length) {88return { data: { headers: [], rows: [] }, dispose: () => { } };89}9091const headers = [92localize('language id', "Language ID"),93localize('localizations language name', "Language Name"),94localize('localizations localized language name', "Language Name (Localized)"),95];9697const rows: IRowData[][] = localizations98.sort((a, b) => a.languageId.localeCompare(b.languageId))99.map(localization => {100return [101localization.languageId,102localization.languageName ?? '',103localization.localizedLanguageName ?? ''104];105});106107return {108data: {109headers,110rows111},112dispose: () => { }113};114}115}116117Registry.as<IExtensionFeaturesRegistry>(Extensions.ExtensionFeaturesRegistry).registerExtensionFeature({118id: 'localizations',119label: localize('localizations', "Langauage Packs"),120access: {121canToggle: false122},123renderer: new SyncDescriptor(LocalizationsDataRenderer),124});125126127