760cbfa00375ddaff353cbe9eab26f54509816074e9e33d3b40ad9d8499ad2ec5ea374c49b35ef5793584d7663e975c0901f11a12021bbb4dd64b542bbb2f1 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  6. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  7. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  8. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  9. return c > 3 && r && Object.defineProperty(target, key, r), r;
  10. };
  11. var __param = (this && this.__param) || function (paramIndex, decorator) {
  12. return function (target, key) { decorator(target, key, paramIndex); }
  13. };
  14. import { Separator, SubmenuAction } from '../../../base/common/actions.js';
  15. import { CSSIcon } from '../../../base/common/codicons.js';
  16. import { Emitter } from '../../../base/common/event.js';
  17. import { Iterable } from '../../../base/common/iterator.js';
  18. import { toDisposable } from '../../../base/common/lifecycle.js';
  19. import { LinkedList } from '../../../base/common/linkedList.js';
  20. import { ICommandService } from '../../commands/common/commands.js';
  21. import { IContextKeyService } from '../../contextkey/common/contextkey.js';
  22. import { createDecorator } from '../../instantiation/common/instantiation.js';
  23. import { ThemeIcon } from '../../theme/common/themeService.js';
  24. export function isIMenuItem(item) {
  25. return item.command !== undefined;
  26. }
  27. export class MenuId {
  28. /**
  29. * Create a new `MenuId` with the unique identifier. Will throw if a menu
  30. * with the identifier already exists, use `MenuId.for(ident)` or a unique
  31. * identifier
  32. */
  33. constructor(identifier) {
  34. if (MenuId._instances.has(identifier)) {
  35. throw new TypeError(`MenuId with identifier '${identifier}' already exists. Use MenuId.for(ident) or a unique identifier`);
  36. }
  37. MenuId._instances.set(identifier, this);
  38. this.id = identifier;
  39. }
  40. }
  41. MenuId._instances = new Map();
  42. MenuId.CommandPalette = new MenuId('CommandPalette');
  43. MenuId.DebugBreakpointsContext = new MenuId('DebugBreakpointsContext');
  44. MenuId.DebugCallStackContext = new MenuId('DebugCallStackContext');
  45. MenuId.DebugConsoleContext = new MenuId('DebugConsoleContext');
  46. MenuId.DebugVariablesContext = new MenuId('DebugVariablesContext');
  47. MenuId.DebugWatchContext = new MenuId('DebugWatchContext');
  48. MenuId.DebugToolBar = new MenuId('DebugToolBar');
  49. MenuId.DebugToolBarStop = new MenuId('DebugToolBarStop');
  50. MenuId.EditorContext = new MenuId('EditorContext');
  51. MenuId.SimpleEditorContext = new MenuId('SimpleEditorContext');
  52. MenuId.EditorContextCopy = new MenuId('EditorContextCopy');
  53. MenuId.EditorContextPeek = new MenuId('EditorContextPeek');
  54. MenuId.EditorContextShare = new MenuId('EditorContextShare');
  55. MenuId.EditorTitle = new MenuId('EditorTitle');
  56. MenuId.EditorTitleRun = new MenuId('EditorTitleRun');
  57. MenuId.EditorTitleContext = new MenuId('EditorTitleContext');
  58. MenuId.EmptyEditorGroup = new MenuId('EmptyEditorGroup');
  59. MenuId.EmptyEditorGroupContext = new MenuId('EmptyEditorGroupContext');
  60. MenuId.ExplorerContext = new MenuId('ExplorerContext');
  61. MenuId.ExtensionContext = new MenuId('ExtensionContext');
  62. MenuId.GlobalActivity = new MenuId('GlobalActivity');
  63. MenuId.CommandCenter = new MenuId('CommandCenter');
  64. MenuId.LayoutControlMenuSubmenu = new MenuId('LayoutControlMenuSubmenu');
  65. MenuId.LayoutControlMenu = new MenuId('LayoutControlMenu');
  66. MenuId.MenubarMainMenu = new MenuId('MenubarMainMenu');
  67. MenuId.MenubarAppearanceMenu = new MenuId('MenubarAppearanceMenu');
  68. MenuId.MenubarDebugMenu = new MenuId('MenubarDebugMenu');
  69. MenuId.MenubarEditMenu = new MenuId('MenubarEditMenu');
  70. MenuId.MenubarCopy = new MenuId('MenubarCopy');
  71. MenuId.MenubarFileMenu = new MenuId('MenubarFileMenu');
  72. MenuId.MenubarGoMenu = new MenuId('MenubarGoMenu');
  73. MenuId.MenubarHelpMenu = new MenuId('MenubarHelpMenu');
  74. MenuId.MenubarLayoutMenu = new MenuId('MenubarLayoutMenu');
  75. MenuId.MenubarNewBreakpointMenu = new MenuId('MenubarNewBreakpointMenu');
  76. MenuId.MenubarPanelAlignmentMenu = new MenuId('MenubarPanelAlignmentMenu');
  77. MenuId.MenubarPanelPositionMenu = new MenuId('MenubarPanelPositionMenu');
  78. MenuId.MenubarPreferencesMenu = new MenuId('MenubarPreferencesMenu');
  79. MenuId.MenubarRecentMenu = new MenuId('MenubarRecentMenu');
  80. MenuId.MenubarSelectionMenu = new MenuId('MenubarSelectionMenu');
  81. MenuId.MenubarShare = new MenuId('MenubarShare');
  82. MenuId.MenubarSwitchEditorMenu = new MenuId('MenubarSwitchEditorMenu');
  83. MenuId.MenubarSwitchGroupMenu = new MenuId('MenubarSwitchGroupMenu');
  84. MenuId.MenubarTerminalMenu = new MenuId('MenubarTerminalMenu');
  85. MenuId.MenubarViewMenu = new MenuId('MenubarViewMenu');
  86. MenuId.MenubarHomeMenu = new MenuId('MenubarHomeMenu');
  87. MenuId.OpenEditorsContext = new MenuId('OpenEditorsContext');
  88. MenuId.ProblemsPanelContext = new MenuId('ProblemsPanelContext');
  89. MenuId.SCMChangeContext = new MenuId('SCMChangeContext');
  90. MenuId.SCMResourceContext = new MenuId('SCMResourceContext');
  91. MenuId.SCMResourceFolderContext = new MenuId('SCMResourceFolderContext');
  92. MenuId.SCMResourceGroupContext = new MenuId('SCMResourceGroupContext');
  93. MenuId.SCMSourceControl = new MenuId('SCMSourceControl');
  94. MenuId.SCMTitle = new MenuId('SCMTitle');
  95. MenuId.SearchContext = new MenuId('SearchContext');
  96. MenuId.StatusBarWindowIndicatorMenu = new MenuId('StatusBarWindowIndicatorMenu');
  97. MenuId.StatusBarRemoteIndicatorMenu = new MenuId('StatusBarRemoteIndicatorMenu');
  98. MenuId.TestItem = new MenuId('TestItem');
  99. MenuId.TestItemGutter = new MenuId('TestItemGutter');
  100. MenuId.TestPeekElement = new MenuId('TestPeekElement');
  101. MenuId.TestPeekTitle = new MenuId('TestPeekTitle');
  102. MenuId.TouchBarContext = new MenuId('TouchBarContext');
  103. MenuId.TitleBarContext = new MenuId('TitleBarContext');
  104. MenuId.TitleBarTitleContext = new MenuId('TitleBarTitleContext');
  105. MenuId.TunnelContext = new MenuId('TunnelContext');
  106. MenuId.TunnelPrivacy = new MenuId('TunnelPrivacy');
  107. MenuId.TunnelProtocol = new MenuId('TunnelProtocol');
  108. MenuId.TunnelPortInline = new MenuId('TunnelInline');
  109. MenuId.TunnelTitle = new MenuId('TunnelTitle');
  110. MenuId.TunnelLocalAddressInline = new MenuId('TunnelLocalAddressInline');
  111. MenuId.TunnelOriginInline = new MenuId('TunnelOriginInline');
  112. MenuId.ViewItemContext = new MenuId('ViewItemContext');
  113. MenuId.ViewContainerTitle = new MenuId('ViewContainerTitle');
  114. MenuId.ViewContainerTitleContext = new MenuId('ViewContainerTitleContext');
  115. MenuId.ViewTitle = new MenuId('ViewTitle');
  116. MenuId.ViewTitleContext = new MenuId('ViewTitleContext');
  117. MenuId.CommentThreadTitle = new MenuId('CommentThreadTitle');
  118. MenuId.CommentThreadActions = new MenuId('CommentThreadActions');
  119. MenuId.CommentTitle = new MenuId('CommentTitle');
  120. MenuId.CommentActions = new MenuId('CommentActions');
  121. MenuId.InteractiveToolbar = new MenuId('InteractiveToolbar');
  122. MenuId.InteractiveCellTitle = new MenuId('InteractiveCellTitle');
  123. MenuId.InteractiveCellDelete = new MenuId('InteractiveCellDelete');
  124. MenuId.InteractiveCellExecute = new MenuId('InteractiveCellExecute');
  125. MenuId.InteractiveInputExecute = new MenuId('InteractiveInputExecute');
  126. MenuId.NotebookToolbar = new MenuId('NotebookToolbar');
  127. MenuId.NotebookCellTitle = new MenuId('NotebookCellTitle');
  128. MenuId.NotebookCellDelete = new MenuId('NotebookCellDelete');
  129. MenuId.NotebookCellInsert = new MenuId('NotebookCellInsert');
  130. MenuId.NotebookCellBetween = new MenuId('NotebookCellBetween');
  131. MenuId.NotebookCellListTop = new MenuId('NotebookCellTop');
  132. MenuId.NotebookCellExecute = new MenuId('NotebookCellExecute');
  133. MenuId.NotebookCellExecutePrimary = new MenuId('NotebookCellExecutePrimary');
  134. MenuId.NotebookDiffCellInputTitle = new MenuId('NotebookDiffCellInputTitle');
  135. MenuId.NotebookDiffCellMetadataTitle = new MenuId('NotebookDiffCellMetadataTitle');
  136. MenuId.NotebookDiffCellOutputsTitle = new MenuId('NotebookDiffCellOutputsTitle');
  137. MenuId.NotebookOutputToolbar = new MenuId('NotebookOutputToolbar');
  138. MenuId.NotebookEditorLayoutConfigure = new MenuId('NotebookEditorLayoutConfigure');
  139. MenuId.NotebookKernelSource = new MenuId('NotebookKernelSource');
  140. MenuId.BulkEditTitle = new MenuId('BulkEditTitle');
  141. MenuId.BulkEditContext = new MenuId('BulkEditContext');
  142. MenuId.TimelineItemContext = new MenuId('TimelineItemContext');
  143. MenuId.TimelineTitle = new MenuId('TimelineTitle');
  144. MenuId.TimelineTitleContext = new MenuId('TimelineTitleContext');
  145. MenuId.TimelineFilterSubMenu = new MenuId('TimelineFilterSubMenu');
  146. MenuId.AccountsContext = new MenuId('AccountsContext');
  147. MenuId.PanelTitle = new MenuId('PanelTitle');
  148. MenuId.AuxiliaryBarTitle = new MenuId('AuxiliaryBarTitle');
  149. MenuId.TerminalInstanceContext = new MenuId('TerminalInstanceContext');
  150. MenuId.TerminalEditorInstanceContext = new MenuId('TerminalEditorInstanceContext');
  151. MenuId.TerminalNewDropdownContext = new MenuId('TerminalNewDropdownContext');
  152. MenuId.TerminalTabContext = new MenuId('TerminalTabContext');
  153. MenuId.TerminalTabEmptyAreaContext = new MenuId('TerminalTabEmptyAreaContext');
  154. MenuId.TerminalInlineTabContext = new MenuId('TerminalInlineTabContext');
  155. MenuId.WebviewContext = new MenuId('WebviewContext');
  156. MenuId.InlineCompletionsActions = new MenuId('InlineCompletionsActions');
  157. MenuId.NewFile = new MenuId('NewFile');
  158. MenuId.MergeToolbar = new MenuId('MergeToolbar');
  159. MenuId.MergeInput1Toolbar = new MenuId('MergeToolbar1Toolbar');
  160. MenuId.MergeInput2Toolbar = new MenuId('MergeToolbar2Toolbar');
  161. export const IMenuService = createDecorator('menuService');
  162. export const MenuRegistry = new class {
  163. constructor() {
  164. this._commands = new Map();
  165. this._menuItems = new Map();
  166. this._onDidChangeMenu = new Emitter();
  167. this.onDidChangeMenu = this._onDidChangeMenu.event;
  168. this._commandPaletteChangeEvent = {
  169. has: id => id === MenuId.CommandPalette
  170. };
  171. }
  172. addCommand(command) {
  173. return this.addCommands(Iterable.single(command));
  174. }
  175. addCommands(commands) {
  176. for (const command of commands) {
  177. this._commands.set(command.id, command);
  178. }
  179. this._onDidChangeMenu.fire(this._commandPaletteChangeEvent);
  180. return toDisposable(() => {
  181. let didChange = false;
  182. for (const command of commands) {
  183. didChange = this._commands.delete(command.id) || didChange;
  184. }
  185. if (didChange) {
  186. this._onDidChangeMenu.fire(this._commandPaletteChangeEvent);
  187. }
  188. });
  189. }
  190. getCommand(id) {
  191. return this._commands.get(id);
  192. }
  193. getCommands() {
  194. const map = new Map();
  195. this._commands.forEach((value, key) => map.set(key, value));
  196. return map;
  197. }
  198. appendMenuItem(id, item) {
  199. return this.appendMenuItems(Iterable.single({ id, item }));
  200. }
  201. appendMenuItems(items) {
  202. const changedIds = new Set();
  203. const toRemove = new LinkedList();
  204. for (const { id, item } of items) {
  205. let list = this._menuItems.get(id);
  206. if (!list) {
  207. list = new LinkedList();
  208. this._menuItems.set(id, list);
  209. }
  210. toRemove.push(list.push(item));
  211. changedIds.add(id);
  212. }
  213. this._onDidChangeMenu.fire(changedIds);
  214. return toDisposable(() => {
  215. if (toRemove.size > 0) {
  216. for (const fn of toRemove) {
  217. fn();
  218. }
  219. this._onDidChangeMenu.fire(changedIds);
  220. toRemove.clear();
  221. }
  222. });
  223. }
  224. getMenuItems(id) {
  225. let result;
  226. if (this._menuItems.has(id)) {
  227. result = [...this._menuItems.get(id)];
  228. }
  229. else {
  230. result = [];
  231. }
  232. if (id === MenuId.CommandPalette) {
  233. // CommandPalette is special because it shows
  234. // all commands by default
  235. this._appendImplicitItems(result);
  236. }
  237. return result;
  238. }
  239. _appendImplicitItems(result) {
  240. const set = new Set();
  241. for (const item of result) {
  242. if (isIMenuItem(item)) {
  243. set.add(item.command.id);
  244. if (item.alt) {
  245. set.add(item.alt.id);
  246. }
  247. }
  248. }
  249. this._commands.forEach((command, id) => {
  250. if (!set.has(id)) {
  251. result.push({ command });
  252. }
  253. });
  254. }
  255. };
  256. export class SubmenuItemAction extends SubmenuAction {
  257. constructor(item, _menuService, _contextKeyService, _options) {
  258. super(`submenuitem.${item.submenu.id}`, typeof item.title === 'string' ? item.title : item.title.value, [], 'submenu');
  259. this.item = item;
  260. this._menuService = _menuService;
  261. this._contextKeyService = _contextKeyService;
  262. this._options = _options;
  263. }
  264. get actions() {
  265. const result = [];
  266. const menu = this._menuService.createMenu(this.item.submenu, this._contextKeyService);
  267. const groups = menu.getActions(this._options);
  268. menu.dispose();
  269. for (const [, actions] of groups) {
  270. if (actions.length > 0) {
  271. result.push(...actions);
  272. result.push(new Separator());
  273. }
  274. }
  275. if (result.length) {
  276. result.pop(); // remove last separator
  277. }
  278. return result;
  279. }
  280. }
  281. // implements IAction, does NOT extend Action, so that no one
  282. // subscribes to events of Action or modified properties
  283. let MenuItemAction = class MenuItemAction {
  284. constructor(item, alt, options, hideActions, contextKeyService, _commandService) {
  285. var _a, _b;
  286. this.hideActions = hideActions;
  287. this._commandService = _commandService;
  288. this.id = item.id;
  289. this.label = (options === null || options === void 0 ? void 0 : options.renderShortTitle) && item.shortTitle
  290. ? (typeof item.shortTitle === 'string' ? item.shortTitle : item.shortTitle.value)
  291. : (typeof item.title === 'string' ? item.title : item.title.value);
  292. this.tooltip = (_b = (typeof item.tooltip === 'string' ? item.tooltip : (_a = item.tooltip) === null || _a === void 0 ? void 0 : _a.value)) !== null && _b !== void 0 ? _b : '';
  293. this.enabled = !item.precondition || contextKeyService.contextMatchesRules(item.precondition);
  294. this.checked = undefined;
  295. if (item.toggled) {
  296. const toggled = (item.toggled.condition ? item.toggled : { condition: item.toggled });
  297. this.checked = contextKeyService.contextMatchesRules(toggled.condition);
  298. if (this.checked && toggled.tooltip) {
  299. this.tooltip = typeof toggled.tooltip === 'string' ? toggled.tooltip : toggled.tooltip.value;
  300. }
  301. if (toggled.title) {
  302. this.label = typeof toggled.title === 'string' ? toggled.title : toggled.title.value;
  303. }
  304. }
  305. this.item = item;
  306. this.alt = alt ? new MenuItemAction(alt, undefined, options, hideActions, contextKeyService, _commandService) : undefined;
  307. this._options = options;
  308. if (ThemeIcon.isThemeIcon(item.icon)) {
  309. this.class = CSSIcon.asClassName(item.icon);
  310. }
  311. }
  312. dispose() {
  313. // there is NOTHING to dispose and the MenuItemAction should
  314. // never have anything to dispose as it is a convenience type
  315. // to bridge into the rendering world.
  316. }
  317. run(...args) {
  318. var _a, _b;
  319. let runArgs = [];
  320. if ((_a = this._options) === null || _a === void 0 ? void 0 : _a.arg) {
  321. runArgs = [...runArgs, this._options.arg];
  322. }
  323. if ((_b = this._options) === null || _b === void 0 ? void 0 : _b.shouldForwardArgs) {
  324. runArgs = [...runArgs, ...args];
  325. }
  326. return this._commandService.executeCommand(this.id, ...runArgs);
  327. }
  328. };
  329. MenuItemAction = __decorate([
  330. __param(4, IContextKeyService),
  331. __param(5, ICommandService)
  332. ], MenuItemAction);
  333. export { MenuItemAction };
  334. //#endregion