diff --git a/extensions/git/package.json b/extensions/git/package.json index 2d3da8735b3..ced39d466d1 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -11,6 +11,7 @@ "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "enabledApiProposals": [ "diffCommand", + "contribMergeEditorToolbar", "contribViewsWelcome", "scmActionButton", "scmSelectedProvider", @@ -550,6 +551,11 @@ "command": "git.api.getRemoteSources", "title": "%command.api.getRemoteSources%", "category": "Git API" + }, + { + "command": "git.acceptMerge", + "title": "%command.git.acceptMerge%", + "category": "Git" } ], "keybindings": [ @@ -1419,6 +1425,12 @@ "when": "isInDiffRightEditor && !isInEmbeddedDiffEditor && config.git.enabled && !git.missing && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/" } ], + "merge/toolbar": [ + { + "command": "git.acceptMerge", + "when": "isMergeEditor" + } + ], "scm/change/title": [ { "command": "git.stageChange", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 523b9945928..2a1ec856252 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -97,6 +97,7 @@ "command.api.getRepositories": "Get Repositories", "command.api.getRepositoryState": "Get Repository State", "command.api.getRemoteSources": "Get Remote Sources", + "command.git.acceptMerge": "Accept Merge", "config.enabled": "Whether git is enabled.", "config.path": "Path and filename of the git executable, e.g. `C:\\Program Files\\Git\\bin\\git.exe` (Windows). This can also be an array of string values containing multiple paths to look up.", "config.autoRepositoryDetection": "Configures when repositories should be automatically detected.", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index a3479a0b3b5..93cf4df895a 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -1033,6 +1033,19 @@ export class CommandCenter { await this._stageChanges(textEditor, selectedChanges); } + @command('git.acceptMerge') + async acceptMerge(uri: Uri | unknown): Promise { + // TODO@jrieken make this proper, needs help from SCM folks + if (!(uri instanceof Uri)) { + return; + } + const repository = this.model.getRepository(uri); + if (!repository) { + return; + } + await repository.add([uri]); + } + private async _stageChanges(textEditor: TextEditor, changes: LineChange[]): Promise { const modifiedDocument = textEditor.document; const modifiedUri = modifiedDocument.uri; diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index e97c241b95c..aef37651a7d 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -158,6 +158,7 @@ export class MenuId { static readonly WebviewContext = new MenuId('WebviewContext'); static readonly InlineCompletionsActions = new MenuId('InlineCompletionsActions'); static readonly NewFile = new MenuId('NewFile'); + static readonly MergeToolbar = new MenuId('MergeToolbar'); readonly id: number; readonly _debugName: string; diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts index a9446f8a183..88fc90c9d2a 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts @@ -17,9 +17,6 @@ import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/merge import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { MergeEditorSerializer } from './mergeEditorSerializer'; - -//#region Editor Descriptior - Registry.as(EditorExtensions.EditorPane).registerEditorPane( EditorPaneDescriptor.create( MergeEditor, diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.ts index 3a1e6b68079..d3a8f704b36 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.ts @@ -29,8 +29,13 @@ import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel'; import { localize } from 'vs/nls'; import { ILabelService } from 'vs/platform/label/common/label'; import { FloatingClickWidget } from 'vs/workbench/browser/codeeditor'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; +import { IMenuService, MenuId } from 'vs/platform/actions/common/actions'; +import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; +import { IAction } from 'vs/base/common/actions'; + +export const ctxIsMergeEditor = new RawContextKey('isMergeEditor', false); export class MergeEditor extends EditorPane { @@ -47,12 +52,16 @@ export class MergeEditor extends EditorPane { constructor( @IInstantiationService private readonly instantiation: IInstantiationService, @ILabelService private readonly _labelService: ILabelService, + @IMenuService private readonly _menuService: IMenuService, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, @ITelemetryService telemetryService: ITelemetryService, @IStorageService storageService: IStorageService, @IThemeService themeService: IThemeService, ) { super(MergeEditor.ID, telemetryService, themeService, storageService); + ctxIsMergeEditor.bindTo(_contextKeyService).set(true); + const reentrancyBarrier = new ReentrancyBarrier(); this._store.add(this.inputOneView.editor.onDidScrollChange(c => { if (c.scrollTopChanged) { @@ -80,10 +89,25 @@ export class MergeEditor extends EditorPane { })); // TODO@jrieken make this proper: add menu id and allow extensions to contribute - const acceptBtn = this.instantiation.createInstance(FloatingClickWidget, this.inputResultView.editor, 'Accept Merge', ''); - acceptBtn.render(); - this._store.add(acceptBtn.onClick(() => { console.log('DO IT'); })); - this._store.add(acceptBtn); + const toolbarMenu = this._menuService.createMenu(MenuId.MergeToolbar, this._contextKeyService); + const toolbarMenuDisposables = new DisposableStore(); + const toolbarMenuRender = () => { + toolbarMenuDisposables.clear(); + + const actions: IAction[] = []; + createAndFillInActionBarActions(toolbarMenu, { renderShortTitle: true, shouldForwardArgs: true }, actions); + if (actions.length > 0) { + const [first] = actions; + const acceptBtn = this.instantiation.createInstance(FloatingClickWidget, this.inputResultView.editor, first.label, first.id); + toolbarMenuDisposables.add(acceptBtn.onClick(() => first.run(this.inputResultView.editor.getModel()?.uri))); + toolbarMenuDisposables.add(acceptBtn); + acceptBtn.render(); + } + }; + this._store.add(toolbarMenu); + this._store.add(toolbarMenuDisposables); + this._store.add(toolbarMenu.onDidChange(toolbarMenuRender)); + toolbarMenuRender(); } override dispose(): void { @@ -116,7 +140,6 @@ export class MergeEditor extends EditorPane { this.inputOneView.setModel(model.inputOne, localize('yours', 'Yours'), undefined); this.inputTwoView.setModel(model.inputTwo, localize('theirs', 'Theirs',), undefined); this.inputResultView.setModel(model.result, localize('result', 'Result',), this._labelService.getUriLabel(model.result.uri, { relative: true })); - } // override clearInput(): void { diff --git a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts index 7e06c120f95..b43e964676d 100644 --- a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts +++ b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts @@ -252,6 +252,12 @@ const apiMenus: IAPIMenu[] = [ supportsSubmenus: false, proposed: 'inlineCompletions' }, + { + key: 'merge/toolbar', + id: MenuId.MergeToolbar, + description: localize('merge.toolbar', "The prominent botton in the merge editor"), + proposed: 'contribMergeEditorToolbar' + } ]; namespace schema { diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index 4b51252484a..bf9cf9d7024 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -11,6 +11,7 @@ export const allApiProposals = Object.freeze({ commentsResolvedState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.commentsResolvedState.d.ts', contribLabelFormatterWorkspaceTooltip: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribLabelFormatterWorkspaceTooltip.d.ts', contribMenuBarHome: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribMenuBarHome.d.ts', + contribMergeEditorToolbar: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribMergeEditorToolbar.d.ts', contribRemoteHelp: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribRemoteHelp.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.contribMergeEditorToolbar.d.ts b/src/vscode-dts/vscode.proposed.contribMergeEditorToolbar.d.ts new file mode 100644 index 00000000000..323ff90cecb --- /dev/null +++ b/src/vscode-dts/vscode.proposed.contribMergeEditorToolbar.d.ts @@ -0,0 +1,6 @@ +/*--------------------------------------------------------------------------------------------- + * 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 `mergeEditor/toolbar` menu