in src/vs/workbench/contrib/extensions/browser/extensions.contribution.ts [221:775]
description: localize('extensions.supportUntrustedWorkspaces.version', "Defines the version of the extension for which the override should be applied. If not specified, the override will be applied independent of the extension version."),
}
}
}
}
}
}
});
const jsonRegistry = <jsonContributionRegistry.IJSONContributionRegistry>Registry.as(jsonContributionRegistry.Extensions.JSONContribution);
jsonRegistry.registerSchema(ExtensionsConfigurationSchemaId, ExtensionsConfigurationSchema);
// Register Commands
CommandsRegistry.registerCommand('_extensions.manage', (accessor: ServicesAccessor, extensionId: string, tab?: ExtensionEditorTab) => {
const extensionService = accessor.get(IExtensionsWorkbenchService);
const extension = extensionService.local.filter(e => areSameExtensions(e.identifier, { id: extensionId }));
if (extension.length === 1) {
extensionService.open(extension[0], { tab });
}
});
CommandsRegistry.registerCommand('extension.open', async (accessor: ServicesAccessor, extensionId: string, tab?: ExtensionEditorTab) => {
const extensionService = accessor.get(IExtensionsWorkbenchService);
const commandService = accessor.get(ICommandService);
const [extension] = await extensionService.getExtensions([{ id: extensionId }], CancellationToken.None);
if (extension) {
return extensionService.open(extension, { tab });
}
return commandService.executeCommand('_extensions.manage', extensionId, tab);
});
CommandsRegistry.registerCommand({
id: 'workbench.extensions.installExtension',
description: {
description: localize('workbench.extensions.installExtension.description', "Install the given extension"),
args: [
{
name: 'extensionIdOrVSIXUri',
description: localize('workbench.extensions.installExtension.arg.decription', "Extension id or VSIX resource uri"),
constraint: (value: any) => typeof value === 'string' || value instanceof URI,
},
{
name: 'options',
description: '(optional) Options for installing the extension. Object with the following properties: ' +
'`installOnlyNewlyAddedFromExtensionPackVSIX`: When enabled, VS Code installs only newly added extensions from the extension pack VSIX. This option is considered only when installing VSIX. ',
isOptional: true,
schema: {
'type': 'object',
'properties': {
'installOnlyNewlyAddedFromExtensionPackVSIX': {
'type': 'boolean',
'description': localize('workbench.extensions.installExtension.option.installOnlyNewlyAddedFromExtensionPackVSIX', "When enabled, VS Code installs only newly added extensions from the extension pack VSIX. This option is considered only while installing a VSIX."),
default: false
},
'installPreReleaseVersion': {
'type': 'boolean',
'description': localize('workbench.extensions.installExtension.option.installPreReleaseVersion', "When enabled, VS Code installs the pre-release version of the extension if available."),
default: false
},
'donotSync': {
'type': 'boolean',
'description': localize('workbench.extensions.installExtension.option.donotSync', "When enabled, VS Code do not sync this extension when Settings Sync is on."),
default: false
}
}
}
}
]
},
handler: async (accessor, arg: string | UriComponents, options?: { installOnlyNewlyAddedFromExtensionPackVSIX?: boolean, installPreReleaseVersion?: boolean, donotSync?: boolean }) => {
const extensionsWorkbenchService = accessor.get(IExtensionsWorkbenchService);
try {
if (typeof arg === 'string') {
const [id, version] = getIdAndVersion(arg);
const [extension] = await extensionsWorkbenchService.getExtensions([{ id, preRelease: options?.installPreReleaseVersion }], CancellationToken.None);
if (extension) {
const installOptions: InstallOptions = {
isMachineScoped: options?.donotSync ? true : undefined, /* do not allow syncing extensions automatically while installing through the command */
installPreReleaseVersion: options?.installPreReleaseVersion,
installGivenVersion: !!version
};
if (version) {
await extensionsWorkbenchService.installVersion(extension, version, installOptions);
} else {
await extensionsWorkbenchService.install(extension, installOptions);
}
} else {
throw new Error(localize('notFound', "Extension '{0}' not found.", arg));
}
} else {
const vsix = URI.revive(arg);
await extensionsWorkbenchService.install(vsix, { installOnlyNewlyAddedFromExtensionPack: options?.installOnlyNewlyAddedFromExtensionPackVSIX });
}
} 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();
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));
}
if (extensionToUninstall.isBuiltin) {
throw new Error(localize('builtin', "Extension '{0}' is a Built-in extension and cannot be installed", id));
}
try {
await extensionManagementService.uninstall(extensionToUninstall);
} 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 paneCompositeService = accessor.get(IPaneCompositePartService);
const viewlet = await paneCompositeService.openPaneComposite(VIEWLET_ID, ViewContainerLocation.Sidebar, true);
if (!viewlet) {
return;
}
(viewlet.getViewPaneContainer() as IExtensionsViewPaneContainer).search(query);
viewlet.focus();
}
});
function overrideActionForActiveExtensionEditorWebview(command: MultiCommand | undefined, f: (webview: IWebview) => void) {
command?.addImplementation(105, 'extensions-editor', (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<boolean>('hasGallery', false);
export const CONTEXT_HAS_LOCAL_SERVER = new RawContextKey<boolean>('hasLocalServer', false);
export const CONTEXT_HAS_REMOTE_SERVER = new RawContextKey<boolean>('hasRemoteServer', false);
export const CONTEXT_HAS_WEB_SERVER = new RawContextKey<boolean>('hasWebServer', false);
async function runAction(action: IAction): Promise<void> {
try {
await action.run();
} finally {
action.dispose();
}
}
interface IExtensionActionOptions extends IAction2Options {
menuTitles?: { [id: number]: string };
run(accessor: ServicesAccessor, ...args: any[]): Promise<any>;
}
class ExtensionsContributions extends Disposable implements IWorkbenchContribution {
constructor(
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
@IExtensionGalleryService extensionGalleryService: IExtensionGalleryService,
@IContextKeyService contextKeyService: IContextKeyService,
@IPaneCompositePartService private readonly paneCompositeService: IPaneCompositePartService,
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
@IWorkbenchExtensionEnablementService private readonly extensionEnablementService: IWorkbenchExtensionEnablementService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IDialogService private readonly dialogService: IDialogService,
@ICommandService private readonly commandService: ICommandService,
) {
super();
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<IQuickAccessRegistry>(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 {
this._register(MenuRegistry.appendMenuItems([{
id: MenuId.MenubarPreferencesMenu,
item: {
command: {
id: VIEWLET_ID,
title: localize({ key: 'miPreferencesExtensions', comment: ['&& denotes a mnemonic'] }, "&&Extensions")
},
group: '1_settings',
order: 4
}
}, {
id: MenuId.GlobalActivity,
item: {
command: {
id: VIEWLET_ID,
title: localize('showExtensions', "Extensions")
},
group: '2_configuration',
order: 3
}
}]));
this.registerExtensionAction({
id: 'workbench.extensions.action.installExtensions',
title: { value: localize('installExtensions', "Install Extensions"), original: 'Install Extensions' },
category: ExtensionsLocalizedLabel,
menu: {
id: MenuId.CommandPalette,
when: ContextKeyExpr.and(CONTEXT_HAS_GALLERY, ContextKeyExpr.or(CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER))
},
run: async (accessor: ServicesAccessor) => {
accessor.get(IViewsService).openViewContainer(VIEWLET_ID);
}
});
this.registerExtensionAction({
id: 'workbench.extensions.action.showRecommendedKeymapExtensions',
title: { value: localize('showRecommendedKeymapExtensionsShort', "Keymaps"), original: 'Keymaps' },
category: PreferencesLocalizedLabel,
menu: [{
id: MenuId.CommandPalette,
when: CONTEXT_HAS_GALLERY
}, {
id: MenuId.MenubarPreferencesMenu,
group: '2_keybindings',
order: 2
}, {
id: MenuId.GlobalActivity,
group: '2_keybindings',
order: 2
}],
menuTitles: {
[MenuId.MenubarPreferencesMenu.id]: localize({ key: 'miimportKeyboardShortcutsFrom', comment: ['&& denotes a mnemonic'] }, "&&Migrate Keyboard Shortcuts from..."),
[MenuId.GlobalActivity.id]: localize('importKeyboardShortcutsFroms', "Migrate Keyboard Shortcuts from...")
},
run: () => runAction(this.instantiationService.createInstance(SearchExtensionsAction, '@recommended:keymaps '))
});
this.registerExtensionAction({
id: 'workbench.extensions.action.showLanguageExtensions',
title: { value: localize('showLanguageExtensionsShort', "Language Extensions"), original: 'Language Extensions' },
category: PreferencesLocalizedLabel,
menu: {
id: MenuId.CommandPalette,
when: CONTEXT_HAS_GALLERY
},
run: () => runAction(this.instantiationService.createInstance(SearchExtensionsAction, '@recommended:languages '))
});
this.registerExtensionAction({
id: 'workbench.extensions.action.checkForUpdates',
title: { value: localize('checkForUpdates', "Check for Extension Updates"), original: 'Check for Extension Updates' },
category: ExtensionsLocalizedLabel,
menu: [{
id: MenuId.CommandPalette,
when: ContextKeyExpr.and(CONTEXT_HAS_GALLERY, ContextKeyExpr.or(CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER))
}, {
id: MenuId.ViewContainerTitle,
when: ContextKeyExpr.equals('viewContainer', VIEWLET_ID),
group: '1_updates',
order: 1
}],
run: async () => {
await this.extensionsWorkbenchService.checkForUpdates();
const outdated = this.extensionsWorkbenchService.outdated;
if (outdated.length) {
return runAction(this.instantiationService.createInstance(SearchExtensionsAction, '@outdated '));
} else {
return this.dialogService.show(Severity.Info, localize('noUpdatesAvailable', "All extensions are up to date."));
}
}
});
const autoUpdateExtensionsSubMenu = new MenuId('autoUpdateExtensionsSubMenu');
MenuRegistry.appendMenuItem(MenuId.ViewContainerTitle, <ISubmenuItem>{
submenu: autoUpdateExtensionsSubMenu,
title: localize('configure auto updating extensions', "Auto Update Extensions"),
when: ContextKeyExpr.equals('viewContainer', VIEWLET_ID),
group: '1_updates',
order: 5,
});
this.registerExtensionAction({
id: 'configureExtensionsAutoUpdate.all',
title: localize('configureExtensionsAutoUpdate.all', "All Extensions"),
toggled: ContextKeyExpr.and(ContextKeyExpr.has(`config.${AutoUpdateConfigurationKey}`), ContextKeyExpr.notEquals(`config.${AutoUpdateConfigurationKey}`, 'onlyEnabledExtensions')),
menu: [{
id: autoUpdateExtensionsSubMenu,
order: 1,
}],
run: (accessor: ServicesAccessor) => accessor.get(IConfigurationService).updateValue(AutoUpdateConfigurationKey, true)
});
this.registerExtensionAction({
id: 'configureExtensionsAutoUpdate.enabled',
title: localize('configureExtensionsAutoUpdate.enabled', "Only Enabled Extensions"),
toggled: ContextKeyExpr.equals(`config.${AutoUpdateConfigurationKey}`, 'onlyEnabledExtensions'),
menu: [{
id: autoUpdateExtensionsSubMenu,
order: 2,
}],
run: (accessor: ServicesAccessor) => accessor.get(IConfigurationService).updateValue(AutoUpdateConfigurationKey, 'onlyEnabledExtensions')
});
this.registerExtensionAction({
id: 'configureExtensionsAutoUpdate.none',
title: localize('configureExtensionsAutoUpdate.none', "None"),
toggled: ContextKeyExpr.equals(`config.${AutoUpdateConfigurationKey}`, false),
menu: [{
id: autoUpdateExtensionsSubMenu,
order: 3,
}],
run: (accessor: ServicesAccessor) => accessor.get(IConfigurationService).updateValue(AutoUpdateConfigurationKey, false)
});
this.registerExtensionAction({
id: 'workbench.extensions.action.updateAllExtensions',
title: { value: localize('updateAll', "Update All Extensions"), original: 'Update All Extensions' },
category: ExtensionsLocalizedLabel,
precondition: HasOutdatedExtensionsContext,
menu: [{
id: MenuId.CommandPalette,
when: ContextKeyExpr.and(CONTEXT_HAS_GALLERY, ContextKeyExpr.or(CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER))
}, {
id: MenuId.ViewContainerTitle,
when: ContextKeyExpr.and(ContextKeyExpr.equals('viewContainer', VIEWLET_ID), ContextKeyExpr.or(ContextKeyExpr.has(`config.${AutoUpdateConfigurationKey}`).negate(), ContextKeyExpr.equals(`config.${AutoUpdateConfigurationKey}`, 'onlyEnabledExtensions'))),
group: '1_updates',
order: 2
}],
run: () => {
return Promise.all(this.extensionsWorkbenchService.outdated.map(async extension => {
try {
await this.extensionsWorkbenchService.install(extension);
} catch (err) {
runAction(this.instantiationService.createInstance(PromptExtensionInstallFailureAction, extension, extension.latestVersion, InstallOperation.Update, undefined, err));
}
}));
}
});
this.registerExtensionAction({
id: 'workbench.extensions.action.disableAutoUpdate',
title: { value: localize('disableAutoUpdate', "Disable Auto Update for all extensions"), original: 'Disable Auto Update for all extensions' },
category: ExtensionsLocalizedLabel,
f1: true,
run: (accessor: ServicesAccessor) => accessor.get(IConfigurationService).updateValue(AutoUpdateConfigurationKey, false)
});
this.registerExtensionAction({
id: 'workbench.extensions.action.enableAutoUpdate',
title: { value: localize('enableAutoUpdate', "Enable Auto Update for all extensions"), original: 'Enable Auto Update for all extensions' },
category: ExtensionsLocalizedLabel,
f1: true,
run: (accessor: ServicesAccessor) => accessor.get(IConfigurationService).updateValue(AutoUpdateConfigurationKey, true)
});
this.registerExtensionAction({
id: 'workbench.extensions.action.enableAll',
title: { value: localize('enableAll', "Enable All Extensions"), original: 'Enable All Extensions' },
category: ExtensionsLocalizedLabel,
menu: [{
id: MenuId.CommandPalette,
when: ContextKeyExpr.or(CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER)
}, {
id: MenuId.ViewContainerTitle,
when: ContextKeyExpr.equals('viewContainer', VIEWLET_ID),
group: '2_enablement',
order: 1
}],
run: async () => {
const extensionsToEnable = this.extensionsWorkbenchService.local.filter(e => !!e.local && this.extensionEnablementService.canChangeEnablement(e.local) && !this.extensionEnablementService.isEnabled(e.local));
if (extensionsToEnable.length) {
await this.extensionsWorkbenchService.setEnablement(extensionsToEnable, EnablementState.EnabledGlobally);
}
}
});
this.registerExtensionAction({
id: 'workbench.extensions.action.enableAllWorkspace',
title: { value: localize('enableAllWorkspace', "Enable All Extensions for this Workspace"), original: 'Enable All Extensions for this Workspace' },
category: ExtensionsLocalizedLabel,
menu: {
id: MenuId.CommandPalette,
when: ContextKeyExpr.and(WorkbenchStateContext.notEqualsTo('empty'), ContextKeyExpr.or(CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER))
},
run: async () => {
const extensionsToEnable = this.extensionsWorkbenchService.local.filter(e => !!e.local && this.extensionEnablementService.canChangeEnablement(e.local) && !this.extensionEnablementService.isEnabled(e.local));
if (extensionsToEnable.length) {
await this.extensionsWorkbenchService.setEnablement(extensionsToEnable, EnablementState.EnabledWorkspace);
}
}
});
this.registerExtensionAction({
id: 'workbench.extensions.action.disableAll',
title: { value: localize('disableAll', "Disable All Installed Extensions"), original: 'Disable All Installed Extensions' },
category: ExtensionsLocalizedLabel,
menu: [{
id: MenuId.CommandPalette,
when: ContextKeyExpr.or(CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER)
}, {
id: MenuId.ViewContainerTitle,
when: ContextKeyExpr.equals('viewContainer', VIEWLET_ID),
group: '2_enablement',
order: 2
}],
run: async () => {
const extensionsToDisable = this.extensionsWorkbenchService.local.filter(e => !e.isBuiltin && !!e.local && this.extensionEnablementService.isEnabled(e.local) && this.extensionEnablementService.canChangeEnablement(e.local));
if (extensionsToDisable.length) {
await this.extensionsWorkbenchService.setEnablement(extensionsToDisable, EnablementState.DisabledGlobally);
}
}
});
this.registerExtensionAction({
id: 'workbench.extensions.action.disableAllWorkspace',
title: { value: localize('disableAllWorkspace', "Disable All Installed Extensions for this Workspace"), original: 'Disable All Installed Extensions for this Workspace' },
category: ExtensionsLocalizedLabel,
menu: {
id: MenuId.CommandPalette,
when: ContextKeyExpr.and(WorkbenchStateContext.notEqualsTo('empty'), ContextKeyExpr.or(CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER, CONTEXT_HAS_WEB_SERVER))
},
run: async () => {
const extensionsToDisable = this.extensionsWorkbenchService.local.filter(e => !e.isBuiltin && !!e.local && this.extensionEnablementService.isEnabled(e.local) && this.extensionEnablementService.canChangeEnablement(e.local));
if (extensionsToDisable.length) {
await this.extensionsWorkbenchService.setEnablement(extensionsToDisable, EnablementState.DisabledWorkspace);
}
}
});
this.registerExtensionAction({
id: SELECT_INSTALL_VSIX_EXTENSION_COMMAND_ID,
title: { value: localize('InstallFromVSIX', "Install from VSIX..."), original: 'Install from VSIX...' },
category: ExtensionsLocalizedLabel,
menu: [{
id: MenuId.CommandPalette,
when: ContextKeyExpr.or(CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER)
}, {
id: MenuId.ViewContainerTitle,
when: ContextKeyExpr.and(ContextKeyExpr.equals('viewContainer', VIEWLET_ID), ContextKeyExpr.or(CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER)),
group: '3_install',
order: 1
}],
run: async (accessor: ServicesAccessor) => {
const fileDialogService = accessor.get(IFileDialogService);
const commandService = accessor.get(ICommandService);
const vsixPaths = await fileDialogService.showOpenDialog({
title: localize('installFromVSIX', "Install from VSIX"),
filters: [{ name: 'VSIX Extensions', extensions: ['vsix'] }],
canSelectFiles: true,
canSelectMany: true,
openLabel: mnemonicButtonLabel(localize({ key: 'installButton', comment: ['&& denotes a mnemonic'] }, "&&Install"))
});
if (vsixPaths) {
await commandService.executeCommand(INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID, vsixPaths);
}
}
});
this.registerExtensionAction({
id: INSTALL_EXTENSION_FROM_VSIX_COMMAND_ID,
title: localize('installVSIX', "Install Extension VSIX"),
menu: [{
id: MenuId.ExplorerContext,
group: 'extensions',
when: ContextKeyExpr.and(ResourceContextKey.Extension.isEqualTo('.vsix'), ContextKeyExpr.or(CONTEXT_HAS_LOCAL_SERVER, CONTEXT_HAS_REMOTE_SERVER)),
}],
run: async (accessor: ServicesAccessor, resources: URI[] | URI) => {
const extensionService = accessor.get(IExtensionService);
const extensionsWorkbenchService = accessor.get(IExtensionsWorkbenchService);
const hostService = accessor.get(IHostService);
const notificationService = accessor.get(INotificationService);
const extensions = Array.isArray(resources) ? resources : [resources];
await Promises.settled(extensions.map(async (vsix) => await extensionsWorkbenchService.install(vsix)))
.then(async (extensions) => {
for (const extension of extensions) {
const requireReload = !(extension.local && extensionService.canAddExtension(toExtensionDescription(extension.local)));
const message = requireReload ? localize('InstallVSIXAction.successReload', "Completed installing {0} extension from VSIX. Please reload Visual Studio Code to enable it.", extension.displayName || extension.name)
: localize('InstallVSIXAction.success', "Completed installing {0} extension from VSIX.", extension.displayName || extension.name);
const actions = requireReload ? [{