From abd2f00bcc13f99127e5089f391e2055be39fed5 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 27 Nov 2023 12:17:26 +0100 Subject: [PATCH] SCM - implement scm/inputBox menu (#199147) * SCM - fix regression related to the scm input box action button * Single action working as expected * Saving my work * Fix enablement when there is only one action * More polish when there are multiple actions * WIP - Select default action * Add proposal * Another refactoring * Update setting type * Remove setting, store last executed command * Revert code that was used for testing * Fix compilation errors * Remove test commands --- extensions/git/package.json | 3 +- .../dropdownWithPrimaryActionViewItem.ts | 8 +- src/vs/platform/actions/common/actions.ts | 1 + .../contrib/scm/browser/media/scm.css | 15 ++ .../contrib/scm/browser/scmViewPane.ts | 219 ++++++++++-------- .../actions/common/menusExtensionPoint.ts | 6 + .../common/extensionsApiProposals.ts | 1 + ...osed.contribSourceControlInputBoxMenu.d.ts | 7 + 8 files changed, 158 insertions(+), 102 deletions(-) create mode 100644 src/vscode-dts/vscode.proposed.contribSourceControlInputBoxMenu.d.ts diff --git a/extensions/git/package.json b/extensions/git/package.json index 893bb9c05d585..6398bb581e6b7 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -25,7 +25,8 @@ "timeline", "contribMergeEditorMenus", "scmInputBoxActionButton", - "scmInputBoxValueProvider" + "scmInputBoxValueProvider", + "contribSourceControlInputBoxMenu" ], "categories": [ "Other" diff --git a/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts b/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts index ea66a1e2c502e..654c1c336e917 100644 --- a/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts +++ b/src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts @@ -7,7 +7,7 @@ import * as DOM from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ActionViewItem, BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem'; -import { IAction } from 'vs/base/common/actions'; +import { IAction, IActionRunner } from 'vs/base/common/actions'; import { Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import { ResolvedKeybinding } from 'vs/base/common/keybindings'; @@ -21,6 +21,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; export interface IDropdownWithPrimaryActionViewItemOptions { + actionRunner?: IActionRunner; getKeyBinding?: (action: IAction) => ResolvedKeybinding | undefined; } @@ -49,9 +50,14 @@ export class DropdownWithPrimaryActionViewItem extends BaseActionViewItem { ) { super(null, primaryAction); this._primaryAction = new MenuEntryActionViewItem(primaryAction, undefined, _keybindingService, _notificationService, _contextKeyService, _themeService, _contextMenuProvider, _accessibilityService); + if (_options?.actionRunner) { + this._primaryAction.actionRunner = _options.actionRunner; + } + this._dropdown = new DropdownMenuActionViewItem(dropdownAction, dropdownMenuActions, this._contextMenuProvider, { menuAsChild: true, classNames: className ? ['codicon', 'codicon-chevron-down', className] : ['codicon', 'codicon-chevron-down'], + actionRunner: this._options?.actionRunner, keybindingProvider: this._options?.getKeyBinding }); } diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 2071f3c7c2ff6..37d341a06d2ae 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -104,6 +104,7 @@ export class MenuId { static readonly OpenEditorsContext = new MenuId('OpenEditorsContext'); static readonly OpenEditorsContextShare = new MenuId('OpenEditorsContextShare'); static readonly ProblemsPanelContext = new MenuId('ProblemsPanelContext'); + static readonly SCMInputBox = new MenuId('SCMInputBox'); static readonly SCMHistoryItem = new MenuId('SCMHistoryItem'); static readonly SCMChangeContext = new MenuId('SCMChangeContext'); static readonly SCMResourceContext = new MenuId('SCMResourceContext'); diff --git a/src/vs/workbench/contrib/scm/browser/media/scm.css b/src/vs/workbench/contrib/scm/browser/media/scm.css index 9e3d6bbd5ca24..95cf07c183b57 100644 --- a/src/vs/workbench/contrib/scm/browser/media/scm.css +++ b/src/vs/workbench/contrib/scm/browser/media/scm.css @@ -303,6 +303,21 @@ display: none; } +.scm-view .scm-input .scm-editor .scm-editor-toolbar.disabled .action-item { + cursor: default; + opacity: 0.6; +} + +.scm-view .scm-input .scm-editor .scm-editor-toolbar.disabled .action-label:hover { + outline: unset; + outline-offset: unset; + background-color: unset; +} + +.scm-view .scm-input .scm-editor .scm-editor-toolbar.disabled .action-item.monaco-dropdown-with-primary:hover { + background-color: unset; +} + .scm-view .scm-input .scm-editor .scm-editor-toolbar.scroll-decoration { box-shadow: var(--vscode-scrollbar-shadow) 0 6px 6px -6px inset; } diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index 27ea98174e34a..a75598d1eb3ed 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -11,7 +11,7 @@ import { ViewPane, IViewPaneOptions, ViewAction } from 'vs/workbench/browser/par import { append, $, Dimension, asCSSUrl, trackFocus, clearNode, prepend } from 'vs/base/browser/dom'; import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list'; import { ISCMHistoryItem, ISCMHistoryItemChange, ISCMHistoryProviderCacheEntry, SCMHistoryItemChangeTreeElement, SCMHistoryItemGroupTreeElement, SCMHistoryItemTreeElement, SCMViewSeparatorElement } from 'vs/workbench/contrib/scm/common/history'; -import { ISCMResourceGroup, ISCMResource, InputValidationType, ISCMRepository, ISCMInput, IInputValidation, ISCMViewService, ISCMViewVisibleRepositoryChangeEvent, ISCMService, SCMInputChangeReason, VIEW_PANE_ID, ISCMActionButton, ISCMActionButtonDescriptor, ISCMRepositorySortKey, REPOSITORIES_VIEW_PANE_ID, ISCMInputValueProviderContext, ISCMInputValueProvider } from 'vs/workbench/contrib/scm/common/scm'; +import { ISCMResourceGroup, ISCMResource, InputValidationType, ISCMRepository, ISCMInput, IInputValidation, ISCMViewService, ISCMViewVisibleRepositoryChangeEvent, ISCMService, SCMInputChangeReason, VIEW_PANE_ID, ISCMActionButton, ISCMActionButtonDescriptor, ISCMRepositorySortKey, REPOSITORIES_VIEW_PANE_ID, ISCMInputValueProviderContext } from 'vs/workbench/contrib/scm/common/scm'; import { ResourceLabels, IResourceLabel, IFileLabelOptions } from 'vs/workbench/browser/labels'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -75,7 +75,7 @@ import { ColorScheme } from 'vs/platform/theme/common/theme'; import { LabelFuzzyScore } from 'vs/base/browser/ui/tree/abstractTree'; import { Selection } from 'vs/editor/common/core/selection'; import { API_OPEN_DIFF_EDITOR_COMMAND_ID, API_OPEN_EDITOR_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands'; -import { createActionViewItem, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; +import { createActionViewItem, createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { MarkdownRenderer, openLinkFromMarkdown } from 'vs/editor/contrib/markdownRenderer/browser/markdownRenderer'; import { Button, ButtonWithDescription, ButtonWithDropdown } from 'vs/base/browser/ui/button/button'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -100,10 +100,9 @@ import { EditOperation } from 'vs/editor/common/core/editOperation'; import { stripIcons } from 'vs/base/common/iconLabels'; import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel'; import { foreground, listActiveSelectionForeground, registerColor, transparent } from 'vs/platform/theme/common/colorRegistry'; -import { WorkbenchToolBar } from 'vs/platform/actions/browser/toolbar'; -import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; -import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; -import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; +import { IMenuWorkbenchToolBarOptions, WorkbenchToolBar } from 'vs/platform/actions/browser/toolbar'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; +import { DropdownWithPrimaryActionViewItem } from 'vs/platform/actions/browser/dropdownWithPrimaryActionViewItem'; // type SCMResourceTreeNode = IResourceNode; // type SCMHistoryItemChangeResourceTreeNode = IResourceNode; @@ -1775,123 +1774,142 @@ class HistoryItemViewChangesAction extends Action2 { registerAction2(HistoryItemViewChangesAction); -export const enum SCMInputCommandId { - ProvideValue = 'scm.input.provideValue' +const enum SCMInputCommandId { + CancelAction = 'scm.input.cancelAction', + SelectDefaultAction = 'scm.input.selectDefaultAction' } +const SCMInputContextKeys = { + ActionIsEnabled: new RawContextKey('scmInputActionIsEnabled', false), + ActionIsRunning: new RawContextKey('scmInputActionIsRunning', false), +}; + class SCMInputWidgetActionRunner extends ActionRunner { + private _runningActions = new Set(); + private _ctxIsActionRunning: IContextKey; private _cts: CancellationTokenSource | undefined; - private _isActionRunning: boolean = false; - get isActionRunning(): boolean { return this._isActionRunning; } - constructor( private readonly input: ISCMInput, - @IProgressService private readonly progressService: IProgressService + @IContextKeyService private readonly contextKeyService: IContextKeyService, + @IStorageService private readonly storageService: IStorageService ) { super(); - } - override async run(action: IAction, context?: unknown): Promise { - if (!action.enabled) { - return; - } - - // Cancel previous action - if (this._isActionRunning) { - this._cts?.cancel(); + this._ctxIsActionRunning = SCMInputContextKeys.ActionIsRunning.bindTo(contextKeyService); + } - // Cancel button was clicked - if (action instanceof SCMInputWidgetButtonAction) { + protected override async runAction(action: IAction): Promise { + try { + // Check if toolbar is disabled + if (this.contextKeyService.getContextKeyValue(SCMInputContextKeys.ActionIsEnabled.key) === false) { return; } - } - - this._isActionRunning = true; - super.run(action, context); - } + // Cancel previous action + if (this._ctxIsActionRunning.get() === true) { + this._cts?.cancel(); - protected override async runAction(action: IAction): Promise { - try { - await this.progressService.withProgress({ location: ProgressLocation.Scm }, async () => { - const context: ISCMInputValueProviderContext[] = []; - for (const group of this.input.repository.provider.groups) { - context.push({ - resourceGroupId: group.id, - resources: [...group.resources.map(r => r.sourceUri)] - }); + if (action.id === SCMInputCommandId.CancelAction) { + return; } + } - this._cts = new CancellationTokenSource(); - await action.run(context, this._cts.token); - }); + this._runningActions.add(action); + if (action.id !== SCMInputCommandId.SelectDefaultAction) { + this._ctxIsActionRunning.set(true); + } + + const context: ISCMInputValueProviderContext[] = []; + for (const group of this.input.repository.provider.groups) { + context.push({ + resourceGroupId: group.id, + resources: [...group.resources.map(r => r.sourceUri)] + }); + } + + this._cts = new CancellationTokenSource(); + await action.run(...[this.input.repository.provider.rootUri, context, this._cts.token]); + this.storageService.store('scm.input.lastActionId', action.id, StorageScope.PROFILE, StorageTarget.USER); } finally { - this._isActionRunning = false; + this._runningActions.delete(action); + + if (this._runningActions.size === 0) { + this._ctxIsActionRunning.set(false); + } } } } -class SCMInputWidgetButtonAction extends Action { +class SCMInputWidgetToolbar extends WorkbenchToolBar { + + private _dropdownActions: IAction[] = []; + get dropdownActions(): IAction[] { return this._dropdownActions; } constructor( - private readonly input: ISCMInput, - private readonly provider: ISCMInputValueProvider, - readonly repository: ISCMRepository + container: HTMLElement, + menuId: MenuId, + options: IMenuWorkbenchToolBarOptions | undefined, + @IMenuService menuService: IMenuService, + @IContextKeyService contextKeyService: IContextKeyService, + @IContextMenuService contextMenuService: IContextMenuService, + @ICommandService commandService: ICommandService, + @IKeybindingService keybindingService: IKeybindingService, + @IStorageService storageService: IStorageService, + @ITelemetryService telemetryService: ITelemetryService, ) { - super( - SCMInputCommandId.ProvideValue, - provider.label, - ThemeIcon.isThemeIcon(provider.icon) ? ThemeIcon.asClassName(provider.icon) : ThemeIcon.asClassName(Codicon.sparkle), - repository.provider.groups.some(g => g.resources.length > 0)); + super(container, { resetMenu: menuId, ...options }, menuService, contextKeyService, contextMenuService, keybindingService, telemetryService); - this._register(repository.provider.onDidChangeResources(() => this.enabled = repository.provider.groups.some(g => g.resources.length > 0))); - } + const menu = this._store.add(menuService.createMenu(menuId, contextKeyService, { emitEventsForSubmenuChanges: true })); - override async run(context: ISCMInputValueProviderContext[], token: CancellationToken): Promise { - const value = await this.provider.provideValue(this.input.repository.provider.rootUri!, context, token); + const cancelAction = new MenuItemAction({ + id: SCMInputCommandId.CancelAction, + title: localize('scmInputCancelAction', "Cancel"), + icon: Codicon.debugStop, + }, undefined, undefined, undefined, contextKeyService, commandService); - if (value) { - this.input.setValue(value, false); - } - } + const updateToolbar = () => { + this._dropdownActions = []; -} + const actions: IAction[] = []; + createAndFillInActionBarActions(menu, options?.menuOptions, actions); -class SCMInputWidgetButtonActionViewItem extends ActionViewItem { + let primaryAction: IAction | undefined = undefined; - constructor(action: IAction, actionRunner: SCMInputWidgetActionRunner) { - super(undefined, action, { icon: true, label: false }); + if (contextKeyService.getContextKeyValue(SCMInputContextKeys.ActionIsRunning.key) === true) { + primaryAction = cancelAction; + } else if (actions.length === 1) { + primaryAction = actions[0]; + } else if (actions.length > 1) { + const lastActionId = storageService.get('scm.input.lastActionId', StorageScope.PROFILE, ''); + primaryAction = actions.find(a => a.id === lastActionId) ?? actions[0]; + } - this.actionRunner = actionRunner; + if (actions.length > 1) { + for (const action of actions) { + this._dropdownActions.push(action); + } + } - this._register(Event.any(actionRunner.onWillRun, actionRunner.onDidRun)(() => { - this.updateTooltip(); - this.updateClass(); - })); - } + container.classList.toggle('has-no-actions', actions.length === 0); + container.classList.toggle('disabled', contextKeyService.getContextKeyValue(SCMInputContextKeys.ActionIsEnabled.key) !== true); - protected override getClass(): string | undefined { - if (this.actionRunner instanceof SCMInputWidgetActionRunner) { - return this.actionRunner.isActionRunning ? ThemeIcon.asClassName(Codicon.debugStop) : super.getClass(); - } + super.setActions(primaryAction ? [primaryAction] : [], []); + }; - return super.getClass(); - } + this._store.add(menu.onDidChange(() => updateToolbar())); - protected override getTooltip(): string | undefined { - if (this.actionRunner instanceof SCMInputWidgetActionRunner) { - return this.actionRunner.isActionRunning ? localize('cancel', "Cancel") : super.getTooltip(); - } + const ctxKeys = new Set([SCMInputContextKeys.ActionIsEnabled.key, SCMInputContextKeys.ActionIsRunning.key]); + Event.filter(contextKeyService.onDidChangeContext, e => e.affectsSome(ctxKeys))(() => updateToolbar()); - return super.getTooltip(); + // Delay initial update to finish class initialization + setTimeout(() => updateToolbar(), 0); } } - class SCMInputWidget { private static readonly ValidationTimeouts: { [severity: number]: number } = { @@ -2103,34 +2121,34 @@ class SCMInputWidget { } private createToolbar(input: ISCMInput): void { - const actionRunner = this.instantiationService.createInstance(SCMInputWidgetActionRunner, input); + const contextKeyService2 = this.contextKeyService.createScoped(this.toolbarContainer); + + const services = new ServiceCollection([IContextKeyService, contextKeyService2]); + const instantiationService2 = this.instantiationService.createChild(services); + + const ctxIsActionEnabled = SCMInputContextKeys.ActionIsEnabled.bindTo(contextKeyService2); + this.repositoryDisposables.add(input.repository.provider.onDidChangeResources(() => ctxIsActionEnabled.set(input.repository.provider.groups.some(r => r.resources.length > 0)))); + + const actionRunner = instantiationService2.createInstance(SCMInputWidgetActionRunner, input); this.repositoryDisposables.add(actionRunner); - const toolbar = this.instantiationService.createInstance(WorkbenchToolBar, this.toolbarContainer, { + const toolbar: SCMInputWidgetToolbar = instantiationService2.createInstance(SCMInputWidgetToolbar, this.toolbarContainer, MenuId.SCMInputBox, { actionRunner, actionViewItemProvider: action => { - // Button (single provider) - if (action instanceof SCMInputWidgetButtonAction) { - return this.instantiationService.createInstance(SCMInputWidgetButtonActionViewItem, action, actionRunner); + if (action instanceof MenuItemAction && toolbar.dropdownActions.length > 1) { + const scmInputActionIsEnabled = contextKeyService2.getContextKeyValue('scmInputActionIsEnabled') === true; + const dropdownAction = new Action('scmInputMoreActions', localize('scmInputMoreActions', 'More Actions...'), 'codicon-chevron-down', scmInputActionIsEnabled); + + return instantiationService2.createInstance(DropdownWithPrimaryActionViewItem, action, dropdownAction, toolbar.dropdownActions, '', this.contextMenuService, { actionRunner }); } - return createActionViewItem(this.instantiationService, action); + return createActionViewItem(instantiationService2, action); }, - + menuOptions: { + shouldForwardArgs: true + } }); this.repositoryDisposables.add(toolbar); - - const updateToolbar = () => { - const showInputActionButton = this.configurationService.getValue('scm.showInputActionButton') === true; - const defaultProvider = this.scmService.getDefaultInputValueProvider(input.repository); - toolbar.setActions(showInputActionButton && defaultProvider ? [this.instantiationService.createInstance(SCMInputWidgetButtonAction, input, defaultProvider, input.repository)] : []); - - toolbar.getElement().classList.toggle('hidden', !showInputActionButton || defaultProvider === undefined); - this.layout(); - }; - this.repositoryDisposables.add(this.scmService.onDidChangeInputValueProviders(updateToolbar, this)); - this.repositoryDisposables.add(Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('scm.showInputActionButton'))(updateToolbar, this)); - updateToolbar(); } private setValidation(validation: IInputValidation | undefined, options?: { focus?: boolean; timeout?: boolean }) { @@ -2154,7 +2172,7 @@ class SCMInputWidget { constructor( container: HTMLElement, overflowWidgetsDomNode: HTMLElement, - @IContextKeyService contextKeyService: IContextKeyService, + @IContextKeyService private readonly contextKeyService: IContextKeyService, @IModelService private modelService: IModelService, @ITextModelService private textModelService: ITextModelService, @IKeybindingService private keybindingService: IKeybindingService, @@ -2164,6 +2182,7 @@ class SCMInputWidget { @ISCMViewService private readonly scmViewService: ISCMViewService, @IContextViewService private readonly contextViewService: IContextViewService, @IOpenerService private readonly openerService: IOpenerService, + @IContextMenuService private readonly contextMenuService: IContextMenuService, @ICommandService private readonly commandService: ICommandService ) { this.element = append(container, $('.scm-editor')); diff --git a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts index bb1993e9d95ee..8bf3f2c149f91 100644 --- a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts +++ b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts @@ -144,6 +144,12 @@ const apiMenus: IAPIMenu[] = [ id: MenuId.SCMChangeContext, description: localize('menus.changeTitle', "The Source Control inline change menu") }, + { + key: 'scm/inputBox', + id: MenuId.SCMInputBox, + description: localize('menus.input', "The Source Control input box menu"), + proposed: 'contribSourceControlInputBoxMenu' + }, { key: 'statusBar/remoteIndicator', id: MenuId.StatusBarRemoteIndicatorMenu, diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index ac57eb9fb759e..9f0da9dbb1e52 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -31,6 +31,7 @@ export const allApiProposals = Object.freeze({ contribNotebookStaticPreloads: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribNotebookStaticPreloads.d.ts', contribRemoteHelp: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribRemoteHelp.d.ts', contribShareMenu: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribShareMenu.d.ts', + contribSourceControlInputBoxMenu: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribSourceControlInputBoxMenu.d.ts', contribStatusBarItems: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribStatusBarItems.d.ts', contribViewsRemote: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribViewsRemote.d.ts', contribViewsWelcome: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribViewsWelcome.d.ts', diff --git a/src/vscode-dts/vscode.proposed.contribSourceControlInputBoxMenu.d.ts b/src/vscode-dts/vscode.proposed.contribSourceControlInputBoxMenu.d.ts new file mode 100644 index 0000000000000..44da3d0a31b69 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.contribSourceControlInputBoxMenu.d.ts @@ -0,0 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// empty placeholder declaration for the `scm/inputBox`-menu contribution point +// https://github.com/microsoft/vscode/issues/195474