diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index ea76a384e8ecfd54668f30784e6f316ae0470865..30efbaa4eb653b520795932cb080b1d99adc9746 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -118,7 +118,7 @@ export interface IMenuService { } export interface IMenuRegistry { - addCommand(userCommand: ICommandAction): boolean; + addCommand(userCommand: ICommandAction): IDisposable; getCommand(id: string): ICommandAction; getCommands(): ICommandsMap; appendMenuItem(menu: MenuId, item: IMenuItem | ISubmenuItem): IDisposable; @@ -138,10 +138,11 @@ export const MenuRegistry: IMenuRegistry = new class implements IMenuRegistry { readonly onDidChangeMenu: Event = this._onDidChangeMenu.event; - addCommand(command: ICommandAction): boolean { - const old = this._commands[command.id]; + addCommand(command: ICommandAction): IDisposable { this._commands[command.id] = command; - return old !== void 0; + return { + dispose: () => delete this._commands[command.id] + }; } getCommand(id: string): ICommandAction { diff --git a/src/vs/workbench/services/actions/electron-browser/menusExtensionPoint.ts b/src/vs/workbench/services/actions/electron-browser/menusExtensionPoint.ts index b7435e930dc1da3b4d424ec863bd943479bed556..2b4c5afbd60839f9cd67a697907b0c2a5b5114b4 100644 --- a/src/vs/workbench/services/actions/electron-browser/menusExtensionPoint.ts +++ b/src/vs/workbench/services/actions/electron-browser/menusExtensionPoint.ts @@ -12,6 +12,7 @@ import { IExtensionPointUser, ExtensionMessageCollector, ExtensionsRegistry } fr import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { MenuId, MenuRegistry, ILocalizedString, IMenuItem } from 'vs/platform/actions/common/actions'; import { URI } from 'vs/base/common/uri'; +import { IDisposable, dispose } from 'vs/base/common/lifecycle'; namespace schema { @@ -276,12 +277,15 @@ namespace schema { }; } +let _commandRegistrations: IDisposable[] = []; + ExtensionsRegistry.registerExtensionPoint({ extensionPoint: 'commands', - jsonSchema: schema.commandsContribution + jsonSchema: schema.commandsContribution, + isDynamic: true }).setHandler(extensions => { - function handleCommand(userFriendlyCommand: schema.IUserFriendlyCommand, extension: IExtensionPointUser) { + function handleCommand(userFriendlyCommand: schema.IUserFriendlyCommand, extension: IExtensionPointUser, disposables: IDisposable[]) { if (!schema.isValidCommand(userFriendlyCommand, extension.collector)) { return; @@ -301,28 +305,39 @@ ExtensionsRegistry.registerExtensionPoint(value)) { for (let command of value) { - handleCommand(command, extension); + handleCommand(command, extension, _commandRegistrations); } } else { - handleCommand(value, extension); + handleCommand(value, extension, _commandRegistrations); } } }); +let _menuRegistrations: IDisposable[] = []; ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyMenuItem[] }>({ extensionPoint: 'menus', - jsonSchema: schema.menusContribtion + jsonSchema: schema.menusContribtion, + isDynamic: true }).setHandler(extensions => { + + // remove all previous menu registrations + _menuRegistrations = dispose(_menuRegistrations); + for (let extension of extensions) { const { value, collector } = extension; @@ -364,13 +379,14 @@ ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: schema.IUserFriendlyM } } - MenuRegistry.appendMenuItem(menu, { + const registration = MenuRegistry.appendMenuItem(menu, { command, alt, group, order, when: ContextKeyExpr.deserialize(item.when) } as IMenuItem); + _menuRegistrations.push(registration); } }); }