/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { Registry } from 'vs/platform/registry/common/platform'; import { MenuRegistry, MenuId, registerAction2, Action2 } from 'vs/platform/actions/common/actions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ExtensionsLabel, ExtensionsLocalizedLabel, ExtensionsChannelId, IExtensionManagementService, IExtensionGalleryService, PreferencesLocalizedLabel } from 'vs/platform/extensionManagement/common/extensionManagement'; import { IExtensionManagementServerService, IExtensionRecommendationsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IOutputChannelRegistry, Extensions as OutputExtensions } from 'vs/workbench/services/output/common/output'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { VIEWLET_ID, IExtensionsWorkbenchService, IExtensionsViewPaneContainer, TOGGLE_IGNORE_EXTENSION_ACTION_ID } from 'vs/workbench/contrib/extensions/common/extensions'; import { OpenExtensionsViewletAction, InstallExtensionsAction, ShowOutdatedExtensionsAction, ShowRecommendedExtensionsAction, ShowRecommendedKeymapExtensionsAction, ShowPopularExtensionsAction, ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowDisabledExtensionsAction, ShowBuiltInExtensionsAction, UpdateAllAction, EnableAllAction, EnableAllWorkspaceAction, DisableAllAction, DisableAllWorkspaceAction, CheckForUpdatesAction, ShowLanguageExtensionsAction, EnableAutoUpdateAction, DisableAutoUpdateAction, ConfigureRecommendedExtensionsCommandsContributor, InstallVSIXAction, ReinstallAction, InstallSpecificVersionOfExtensionAction, ClearExtensionsSearchResultsAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput'; import { ExtensionEditor } from 'vs/workbench/contrib/extensions/browser/extensionEditor'; import { StatusUpdater, MaliciousExtensionChecker, ExtensionsViewletViewsContribution, ExtensionsViewPaneContainer } from 'vs/workbench/contrib/extensions/browser/extensionsViewlet'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import * as jsonContributionRegistry from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; import { ExtensionsConfigurationSchema, ExtensionsConfigurationSchemaId } from 'vs/workbench/contrib/extensions/common/extensionsFileTemplate'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { KeymapExtensions } from 'vs/workbench/contrib/extensions/common/extensionsUtils'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { EditorDescriptor, IEditorRegistry, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ExtensionActivationProgress } from 'vs/workbench/contrib/extensions/browser/extensionsActivationProgress'; import { onUnexpectedError } from 'vs/base/common/errors'; import { ExtensionDependencyChecker } from 'vs/workbench/contrib/extensions/browser/extensionsDependencyChecker'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { RemoteExtensionsInstaller } from 'vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller'; import { IViewContainersRegistry, ViewContainerLocation, Extensions as ViewContainerExtensions } from 'vs/workbench/common/views'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { ContextKeyAndExpr, ContextKeyExpr, ContextKeyOrExpr, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IQuickAccessRegistry, Extensions } from 'vs/platform/quickinput/common/quickAccess'; import { InstallExtensionQuickAccessProvider, ManageExtensionsQuickAccessProvider } from 'vs/workbench/contrib/extensions/browser/extensionsQuickAccess'; import { ExtensionRecommendationsService } from 'vs/workbench/contrib/extensions/browser/extensionRecommendationsService'; import { CONTEXT_SYNC_ENABLEMENT } from 'vs/workbench/services/userDataSync/common/userDataSync'; import { CopyAction, CutAction, PasteAction } from 'vs/editor/contrib/clipboard/clipboard'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { MultiCommand } from 'vs/editor/browser/editorExtensions'; import { Webview } from 'vs/workbench/contrib/webview/browser/webview'; import { ExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { WorkbenchStateContext } from 'vs/workbench/browser/contextkeys'; import { CATEGORIES } from 'vs/workbench/common/actions'; // Singletons registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService); registerSingleton(IExtensionRecommendationsService, ExtensionRecommendationsService); Registry.as(OutputExtensions.OutputChannels) .registerChannel({ id: ExtensionsChannelId, label: ExtensionsLabel, log: false }); // Quick Access Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ ctor: ManageExtensionsQuickAccessProvider, prefix: ManageExtensionsQuickAccessProvider.PREFIX, placeholder: localize('manageExtensionsQuickAccessPlaceholder', "Press Enter to manage extensions."), helpEntries: [{ description: localize('manageExtensionsHelp', "Manage Extensions"), needsEditor: false }] }); // Editor Registry.as(EditorExtensions.Editors).registerEditor( EditorDescriptor.create( ExtensionEditor, ExtensionEditor.ID, localize('extension', "Extension") ), [ new SyncDescriptor(ExtensionsInput) ]); Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer( { id: VIEWLET_ID, name: localize('extensions', "Extensions"), ctorDescriptor: new SyncDescriptor(ExtensionsViewPaneContainer), icon: 'codicon-extensions', order: 4, rejectAddedViews: true, alwaysUseContainerInfo: true }, ViewContainerLocation.Sidebar); Registry.as(ConfigurationExtensions.Configuration) .registerConfiguration({ id: 'extensions', order: 30, title: localize('extensionsConfigurationTitle', "Extensions"), type: 'object', properties: { 'extensions.autoUpdate': { type: 'boolean', description: localize('extensionsAutoUpdate', "When enabled, automatically installs updates for extensions. The updates are fetched from a Microsoft online service."), default: true, scope: ConfigurationScope.APPLICATION, tags: ['usesOnlineServices'] }, 'extensions.autoCheckUpdates': { type: 'boolean', description: localize('extensionsCheckUpdates', "When enabled, automatically checks extensions for updates. If an extension has an update, it is marked as outdated in the Extensions view. The updates are fetched from a Microsoft online service."), default: true, scope: ConfigurationScope.APPLICATION, tags: ['usesOnlineServices'] }, 'extensions.ignoreRecommendations': { type: 'boolean', description: localize('extensionsIgnoreRecommendations', "When enabled, the notifications for extension recommendations will not be shown."), default: false }, 'extensions.showRecommendationsOnlyOnDemand': { type: 'boolean', description: localize('extensionsShowRecommendationsOnlyOnDemand', "When enabled, recommendations will not be fetched or shown unless specifically requested by the user. Some recommendations are fetched from a Microsoft online service."), default: false, tags: ['usesOnlineServices'] }, 'extensions.closeExtensionDetailsOnViewChange': { type: 'boolean', description: localize('extensionsCloseExtensionDetailsOnViewChange', "When enabled, editors with extension details will be automatically closed upon navigating away from the Extensions View."), default: false }, 'extensions.confirmedUriHandlerExtensionIds': { type: 'array', description: localize('handleUriConfirmedExtensions', "When an extension is listed here, a confirmation prompt will not be shown when that extension handles a URI."), default: [] }, 'extensions.webWorker': { type: 'boolean', description: localize('extensionsWebWorker', "Enable web worker extension host."), default: false } } }); const jsonRegistry = Registry.as(jsonContributionRegistry.Extensions.JSONContribution); jsonRegistry.registerSchema(ExtensionsConfigurationSchemaId, ExtensionsConfigurationSchema); // Register Commands CommandsRegistry.registerCommand('_extensions.manage', (accessor: ServicesAccessor, extensionId: string) => { const extensionService = accessor.get(IExtensionsWorkbenchService); const extension = extensionService.local.filter(e => areSameExtensions(e.identifier, { id: extensionId })); if (extension.length === 1) { extensionService.open(extension[0]); } }); CommandsRegistry.registerCommand('extension.open', (accessor: ServicesAccessor, extensionId: string) => { const extensionService = accessor.get(IExtensionsWorkbenchService); return extensionService.queryGallery({ names: [extensionId], pageSize: 1 }, CancellationToken.None).then(pager => { if (pager.total !== 1) { return; } extensionService.open(pager.firstPage[0]); }); }); CommandsRegistry.registerCommand({ id: 'workbench.extensions.installExtension', description: { description: localize('workbench.extensions.installExtension.description', "Install the given extension"), args: [ { name: localize('workbench.extensions.installExtension.arg.name', "Extension id or VSIX resource uri"), schema: { 'type': ['object', 'string'] } } ] }, handler: async (accessor, arg: string | UriComponents) => { const extensionManagementService = accessor.get(IExtensionManagementService); const extensionGalleryService = accessor.get(IExtensionGalleryService); try { if (typeof arg === 'string') { const extension = await extensionGalleryService.getCompatibleExtension({ id: arg }); if (extension) { await extensionManagementService.installFromGallery(extension); } else { throw new Error(localize('notFound', "Extension '{0}' not found.", arg)); } } else { const vsix = URI.revive(arg); await extensionManagementService.install(vsix); } } catch (e) { onUnexpectedError(e); throw e; } } }); CommandsRegistry.registerCommand({ id: 'workbench.extensions.uninstallExtension', description: { description: localize('workbench.extensions.uninstallExtension.description', "Uninstall the given extension"), args: [ { name: localize('workbench.extensions.uninstallExtension.arg.name', "Id of the extension to uninstall"), schema: { 'type': 'string' } } ] }, handler: async (accessor, id: string) => { if (!id) { throw new Error(localize('id required', "Extension id required.")); } const extensionManagementService = accessor.get(IExtensionManagementService); const installed = await extensionManagementService.getInstalled(ExtensionType.User); const [extensionToUninstall] = installed.filter(e => areSameExtensions(e.identifier, { id })); if (!extensionToUninstall) { throw new Error(localize('notInstalled', "Extension '{0}' is not installed. Make sure you use the full extension ID, including the publisher, e.g.: ms-dotnettools.csharp.", id)); } try { await extensionManagementService.uninstall(extensionToUninstall, true); } catch (e) { onUnexpectedError(e); throw e; } } }); CommandsRegistry.registerCommand({ id: 'workbench.extensions.search', description: { description: localize('workbench.extensions.search.description', "Search for a specific extension"), args: [ { name: localize('workbench.extensions.search.arg.name', "Query to use in search"), schema: { 'type': 'string' } } ] }, handler: async (accessor, query: string = '') => { const viewletService = accessor.get(IViewletService); const viewlet = await viewletService.openViewlet(VIEWLET_ID, true); if (!viewlet) { return; } (viewlet.getViewPaneContainer() as IExtensionsViewPaneContainer).search(query); viewlet.focus(); } }); // File menu registration MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { group: '2_keybindings', command: { id: ShowRecommendedKeymapExtensionsAction.ID, title: localize({ key: 'miOpenKeymapExtensions', comment: ['&& denotes a mnemonic'] }, "&&Keymaps") }, order: 2 }); MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { group: '2_keybindings', command: { id: ShowRecommendedKeymapExtensionsAction.ID, title: localize('miOpenKeymapExtensions2', "Keymaps") }, order: 2 }); MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, { group: '1_settings', command: { id: VIEWLET_ID, title: localize({ key: 'miPreferencesExtensions', comment: ['&& denotes a mnemonic'] }, "&&Extensions") }, order: 3 }); // View menu MenuRegistry.appendMenuItem(MenuId.MenubarViewMenu, { group: '3_views', command: { id: VIEWLET_ID, title: localize({ key: 'miViewExtensions', comment: ['&& denotes a mnemonic'] }, "E&&xtensions") }, order: 5 }); // Global Activity Menu MenuRegistry.appendMenuItem(MenuId.GlobalActivity, { group: '2_configuration', command: { id: VIEWLET_ID, title: localize('showExtensions', "Extensions") }, order: 3 }); function overrideActionForActiveExtensionEditorWebview(command: MultiCommand | undefined, f: (webview: Webview) => void) { command?.addImplementation(105, (accessor) => { const editorService = accessor.get(IEditorService); const editor = editorService.activeEditorPane; if (editor instanceof ExtensionEditor) { if (editor.activeWebview?.isFocused) { f(editor.activeWebview); return true; } } return false; }); } overrideActionForActiveExtensionEditorWebview(CopyAction, webview => webview.copy()); overrideActionForActiveExtensionEditorWebview(CutAction, webview => webview.cut()); overrideActionForActiveExtensionEditorWebview(PasteAction, webview => webview.paste()); // Contexts export const CONTEXT_HAS_GALLERY = new RawContextKey('hasGallery', false); export const CONTEXT_HAS_LOCAL_SERVER = new RawContextKey('hasLocalServer', false); export const CONTEXT_HAS_REMOTE_SERVER = new RawContextKey('hasRemoteServer', false); export const CONTEXT_HAS_WEB_SERVER = new RawContextKey('hasWebServer', false); class ExtensionsContributions implements IWorkbenchContribution { constructor( @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService, @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, @IContextKeyService contextKeyService: IContextKeyService, ) { const hasGalleryContext = CONTEXT_HAS_GALLERY.bindTo(contextKeyService); if (extensionGalleryService.isEnabled()) { hasGalleryContext.set(true); } const hasLocalServerContext = CONTEXT_HAS_LOCAL_SERVER.bindTo(contextKeyService); if (this.extensionManagementServerService.localExtensionManagementServer) { hasLocalServerContext.set(true); } const hasRemoteServerContext = CONTEXT_HAS_REMOTE_SERVER.bindTo(contextKeyService); if (this.extensionManagementServerService.remoteExtensionManagementServer) { hasRemoteServerContext.set(true); } const hasWebServerContext = CONTEXT_HAS_WEB_SERVER.bindTo(contextKeyService); if (this.extensionManagementServerService.webExtensionManagementServer) { hasWebServerContext.set(true); } this.registerGlobalActions(); this.registerContextMenuActions(); this.registerQuickAccessProvider(); } private registerQuickAccessProvider(): void { if (this.extensionManagementServerService.localExtensionManagementServer || this.extensionManagementServerService.remoteExtensionManagementServer || this.extensionManagementServerService.webExtensionManagementServer ) { Registry.as(Extensions.Quickaccess).registerQuickAccessProvider({ ctor: InstallExtensionQuickAccessProvider, prefix: InstallExtensionQuickAccessProvider.PREFIX, placeholder: localize('installExtensionQuickAccessPlaceholder', "Type the name of an extension to install or search."), helpEntries: [{ description: localize('installExtensionQuickAccessHelp', "Install or Search Extensions"), needsEditor: false }] }); } } // Global actions private registerGlobalActions(): void { registerAction2(class extends Action2 { constructor() { super({ id: OpenExtensionsViewletAction.ID, title: { value: OpenExtensionsViewletAction.LABEL, original: 'Show Extensions' }, category: CATEGORIES.View, menu: { id: MenuId.CommandPalette, }, keybinding: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_X, weight: KeybindingWeight.WorkbenchContrib } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(OpenExtensionsViewletAction, OpenExtensionsViewletAction.ID, OpenExtensionsViewletAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: InstallExtensionsAction.ID, title: { value: InstallExtensionsAction.LABEL, original: 'Install Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyAndExpr.create([CONTEXT_HAS_GALLERY, ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER])]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(InstallExtensionsAction, InstallExtensionsAction.ID, InstallExtensionsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ShowOutdatedExtensionsAction.ID, title: { value: ShowOutdatedExtensionsAction.LABEL, original: 'Show Outdated Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyAndExpr.create([CONTEXT_HAS_GALLERY, ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER])]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ShowOutdatedExtensionsAction, ShowOutdatedExtensionsAction.ID, ShowOutdatedExtensionsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ShowRecommendedExtensionsAction.ID, title: { value: ShowRecommendedExtensionsAction.LABEL, original: 'Show Recommended Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: CONTEXT_HAS_GALLERY } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ShowRecommendedExtensionsAction, ShowRecommendedExtensionsAction.ID, ShowRecommendedExtensionsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ShowRecommendedKeymapExtensionsAction.ID, title: { value: ShowRecommendedKeymapExtensionsAction.LABEL, original: 'Keymaps' }, category: PreferencesLocalizedLabel, menu: { id: MenuId.CommandPalette, when: CONTEXT_HAS_GALLERY }, keybinding: { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_M), weight: KeybindingWeight.WorkbenchContrib } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ShowRecommendedKeymapExtensionsAction, ShowRecommendedKeymapExtensionsAction.ID, ShowRecommendedKeymapExtensionsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ShowLanguageExtensionsAction.ID, title: { value: ShowLanguageExtensionsAction.LABEL, original: 'Language Extensions' }, category: PreferencesLocalizedLabel, menu: { id: MenuId.CommandPalette, when: CONTEXT_HAS_GALLERY } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ShowLanguageExtensionsAction, ShowLanguageExtensionsAction.ID, ShowLanguageExtensionsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ShowPopularExtensionsAction.ID, title: { value: ShowPopularExtensionsAction.LABEL, original: 'Show Popular Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: CONTEXT_HAS_GALLERY } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ShowPopularExtensionsAction, ShowPopularExtensionsAction.ID, ShowPopularExtensionsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ShowEnabledExtensionsAction.ID, title: { value: ShowEnabledExtensionsAction.LABEL, original: 'Show Enabled Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ShowEnabledExtensionsAction, ShowEnabledExtensionsAction.ID, ShowEnabledExtensionsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ShowInstalledExtensionsAction.ID, title: { value: ShowInstalledExtensionsAction.LABEL, original: 'Show Installed Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ShowInstalledExtensionsAction, ShowInstalledExtensionsAction.ID, ShowInstalledExtensionsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ShowDisabledExtensionsAction.ID, title: { value: ShowDisabledExtensionsAction.LABEL, original: 'Show Disabled Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ShowDisabledExtensionsAction, ShowDisabledExtensionsAction.ID, ShowDisabledExtensionsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ShowBuiltInExtensionsAction.ID, title: { value: ShowBuiltInExtensionsAction.LABEL, original: 'Show Built-in Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ShowBuiltInExtensionsAction, ShowBuiltInExtensionsAction.ID, ShowBuiltInExtensionsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: UpdateAllAction.ID, title: { value: UpdateAllAction.LABEL, original: 'Update All Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyAndExpr.create([CONTEXT_HAS_GALLERY, ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER])]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(UpdateAllAction, UpdateAllAction.ID, UpdateAllAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: InstallVSIXAction.ID, title: { value: InstallVSIXAction.LABEL, original: 'Install from VSIX...' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(InstallVSIXAction, InstallVSIXAction.ID, InstallVSIXAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: DisableAllAction.ID, title: { value: DisableAllAction.LABEL, original: 'Disable All Installed Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(DisableAllAction, DisableAllAction.ID, DisableAllAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: DisableAllWorkspaceAction.ID, title: { value: DisableAllWorkspaceAction.LABEL, original: 'Disable All Installed Extensions for this Workspace' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyAndExpr.create([WorkbenchStateContext.notEqualsTo('empty'), ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER])]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(DisableAllWorkspaceAction, DisableAllWorkspaceAction.ID, DisableAllWorkspaceAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: EnableAllAction.ID, title: { value: EnableAllAction.LABEL, original: 'Enable All Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(EnableAllAction, EnableAllAction.ID, EnableAllAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: EnableAllWorkspaceAction.ID, title: { value: EnableAllWorkspaceAction.LABEL, original: 'Enable All Extensions for this Workspace' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyAndExpr.create([WorkbenchStateContext.notEqualsTo('empty'), ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER])]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(EnableAllWorkspaceAction, EnableAllWorkspaceAction.ID, EnableAllWorkspaceAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: CheckForUpdatesAction.ID, title: { value: CheckForUpdatesAction.LABEL, original: 'Check for Extension Updates' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyAndExpr.create([CONTEXT_HAS_GALLERY, ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER])]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(CheckForUpdatesAction, CheckForUpdatesAction.ID, CheckForUpdatesAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ClearExtensionsSearchResultsAction.ID, title: { value: ClearExtensionsSearchResultsAction.LABEL, original: 'Clear Extensions Search Results' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ClearExtensionsSearchResultsAction, ClearExtensionsSearchResultsAction.ID, ClearExtensionsSearchResultsAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: EnableAutoUpdateAction.ID, title: { value: EnableAutoUpdateAction.LABEL, original: 'Enable Auto Updating Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(EnableAutoUpdateAction, EnableAutoUpdateAction.ID, EnableAutoUpdateAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: DisableAutoUpdateAction.ID, title: { value: DisableAutoUpdateAction.LABEL, original: 'Disable Auto Updating Extensions' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(DisableAutoUpdateAction, DisableAutoUpdateAction.ID, DisableAutoUpdateAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: InstallSpecificVersionOfExtensionAction.ID, title: { value: InstallSpecificVersionOfExtensionAction.LABEL, original: 'Install Specific Version of Extension...' }, category: ExtensionsLocalizedLabel, menu: { id: MenuId.CommandPalette, when: ContextKeyAndExpr.create([CONTEXT_HAS_GALLERY, ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER])]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(InstallSpecificVersionOfExtensionAction, InstallSpecificVersionOfExtensionAction.ID, InstallSpecificVersionOfExtensionAction.LABEL).run(); } }); registerAction2(class extends Action2 { constructor() { super({ id: ReinstallAction.ID, title: { value: ReinstallAction.LABEL, original: 'Reinstall Extension...' }, category: CATEGORIES.Developer, menu: { id: MenuId.CommandPalette, when: ContextKeyAndExpr.create([CONTEXT_HAS_GALLERY, ContextKeyOrExpr.create([CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER])]) } }); } run(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(ReinstallAction, ReinstallAction.ID, ReinstallAction.LABEL).run(); } }); } // Extension Context Menu private registerContextMenuActions(): void { registerAction2(class extends Action2 { constructor() { super({ id: 'workbench.extensions.action.copyExtension', title: { value: localize('workbench.extensions.action.copyExtension', "Copy"), original: 'Copy' }, menu: { id: MenuId.ExtensionContext, group: '1_copy' } }); } async run(accessor: ServicesAccessor, extensionId: string) { const extensionWorkbenchService = accessor.get(IExtensionsWorkbenchService); let extension = extensionWorkbenchService.local.filter(e => areSameExtensions(e.identifier, { id: extensionId }))[0] || (await extensionWorkbenchService.queryGallery({ names: [extensionId], pageSize: 1 }, CancellationToken.None)).firstPage[0]; if (extension) { const name = localize('extensionInfoName', 'Name: {0}', extension.displayName); const id = localize('extensionInfoId', 'Id: {0}', extensionId); const description = localize('extensionInfoDescription', 'Description: {0}', extension.description); const verision = localize('extensionInfoVersion', 'Version: {0}', extension.version); const publisher = localize('extensionInfoPublisher', 'Publisher: {0}', extension.publisherDisplayName); const link = extension.url ? localize('extensionInfoVSMarketplaceLink', 'VS Marketplace Link: {0}', `${extension.url}`) : null; const clipboardStr = `${name}\n${id}\n${description}\n${verision}\n${publisher}${link ? '\n' + link : ''}`; await accessor.get(IClipboardService).writeText(clipboardStr); } } }); registerAction2(class extends Action2 { constructor() { super({ id: 'workbench.extensions.action.copyExtensionId', title: { value: localize('workbench.extensions.action.copyExtensionId', "Copy Extension Id"), original: 'Copy Extension Id' }, menu: { id: MenuId.ExtensionContext, group: '1_copy' } }); } async run(accessor: ServicesAccessor, id: string) { await accessor.get(IClipboardService).writeText(id); } }); registerAction2(class extends Action2 { constructor() { super({ id: 'workbench.extensions.action.configure', title: { value: localize('workbench.extensions.action.configure', "Extension Settings"), original: 'Extension Settings' }, menu: { id: MenuId.ExtensionContext, group: '2_configure', when: ContextKeyExpr.and(ContextKeyExpr.equals('extensionStatus', 'installed'), ContextKeyExpr.has('extensionHasConfiguration')) } }); } async run(accessor: ServicesAccessor, id: string) { await accessor.get(IPreferencesService).openSettings(false, `@ext:${id}`); } }); registerAction2(class extends Action2 { constructor() { super({ id: TOGGLE_IGNORE_EXTENSION_ACTION_ID, title: { value: localize('workbench.extensions.action.toggleIgnoreExtension', "Sync This Extension"), original: `Sync This Extension` }, menu: { id: MenuId.ExtensionContext, group: '2_configure', when: CONTEXT_SYNC_ENABLEMENT }, }); } async run(accessor: ServicesAccessor, id: string) { const extensionsWorkbenchService = accessor.get(IExtensionsWorkbenchService); const extension = extensionsWorkbenchService.local.find(e => areSameExtensions({ id }, e.identifier)); if (extension) { return extensionsWorkbenchService.toggleExtensionIgnoredToSync(extension); } } }); } } const workbenchRegistry = Registry.as(WorkbenchExtensions.Workbench); workbenchRegistry.registerWorkbenchContribution(ExtensionsContributions, LifecyclePhase.Starting); workbenchRegistry.registerWorkbenchContribution(StatusUpdater, LifecyclePhase.Restored); workbenchRegistry.registerWorkbenchContribution(MaliciousExtensionChecker, LifecyclePhase.Eventually); workbenchRegistry.registerWorkbenchContribution(ConfigureRecommendedExtensionsCommandsContributor, LifecyclePhase.Eventually); workbenchRegistry.registerWorkbenchContribution(KeymapExtensions, LifecyclePhase.Restored); workbenchRegistry.registerWorkbenchContribution(ExtensionsViewletViewsContribution, LifecyclePhase.Starting); workbenchRegistry.registerWorkbenchContribution(ExtensionActivationProgress, LifecyclePhase.Eventually); workbenchRegistry.registerWorkbenchContribution(ExtensionDependencyChecker, LifecyclePhase.Eventually); workbenchRegistry.registerWorkbenchContribution(RemoteExtensionsInstaller, LifecyclePhase.Eventually);