From bbbae594da8035c790c7f62bb8a80fe588daaecd Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 21 Jul 2022 13:25:23 +0200 Subject: [PATCH] show "Accept Merge" only for files currently under conflict. (#155822) While the merge editor shows users can handle merge conflicts outside of it, e.g on the console via `git add `. The merge editor should have this graceful and step one is to hide the "Accept Merge" command when the file isn't conflicting anymore * Adds a git-context key that contains all resource-uri-strings under conflict * Enable/placement of the Accept Merge command is driven by that * some merge editor context key sugar --- extensions/git/package.json | 4 ++-- extensions/git/src/repository.ts | 3 +++ .../mergeEditor/browser/view/mergeEditor.ts | 20 ++++++++++++++----- .../contrib/mergeEditor/common/mergeEditor.ts | 8 +++++--- .../userDataSync/browser/userDataSync.ts | 6 +++--- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 8a0a8cf7ed1..831c0319cd2 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -601,7 +601,7 @@ "command": "git.acceptMerge", "title": "%command.git.acceptMerge%", "category": "Git", - "enablement": "isMergeEditor" + "enablement": "isMergeEditor && mergeEditorResultUri in git.mergeChanges" } ], "keybindings": [ @@ -1549,7 +1549,7 @@ "merge/toolbar": [ { "command": "git.acceptMerge", - "when": "isMergeEditor && baseResourceScheme =~ /^git$|^file$/" + "when": "isMergeEditor && mergeEditorBaseUri =~ /^(git|file):/ && mergeEditorResultUri in git.mergeChanges" } ], "scm/change/title": [ diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 7869e17eae5..2cbddcc0caf 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -2028,6 +2028,9 @@ export class Repository implements Disposable { // set count badge this.setCountBadge(); + // set mergeChanges context + commands.executeCommand('setContext', 'git.mergeChanges', merge.map(item => item.resourceUri.toString())); + this._onDidChangeStatus.fire(); this._sourceControl.commitTemplate = await this.getInputTemplate(); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts index 8cb9a104237..84c2b3f80b1 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts @@ -11,7 +11,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Color } from 'vs/base/common/color'; import { BugIndicatingError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { autorunWithStore, IObservable } from 'vs/base/common/observable'; import { basename, isEqual } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; @@ -44,7 +44,7 @@ import { DocumentMapping, getOppositeDirection, MappingDirection } from 'vs/work import { MergeEditorModel } from 'vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel'; import { deepMerge, ReentrancyBarrier, thenIfNotDisposed } from 'vs/workbench/contrib/mergeEditor/browser/utils'; import { MergeEditorViewModel } from 'vs/workbench/contrib/mergeEditor/browser/view/viewModel'; -import { ctxBaseResourceScheme, ctxIsMergeEditor, ctxMergeEditorLayout, MergeEditorLayoutTypes } from 'vs/workbench/contrib/mergeEditor/common/mergeEditor'; +import { ctxMergeBaseUri, ctxIsMergeEditor, ctxMergeEditorLayout, ctxMergeResultUri, MergeEditorLayoutTypes } from 'vs/workbench/contrib/mergeEditor/common/mergeEditor'; import { settingsSashBorder } from 'vs/workbench/contrib/preferences/common/settingsEditorColorRegistry'; import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { EditorInputFactoryFunction, IEditorResolverService, MergeEditorInputFactoryFunction, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService'; @@ -94,7 +94,8 @@ export class MergeEditor extends AbstractTextEditor { private readonly _layoutMode: MergeEditorLayout; private readonly _ctxIsMergeEditor: IContextKey; private readonly _ctxUsesColumnLayout: IContextKey; - private readonly _ctxBaseResourceScheme: IContextKey; + private readonly _ctxResultUri: IContextKey; + private readonly _ctxBaseUri: IContextKey; private _model: MergeEditorModel | undefined; public get model(): MergeEditorModel | undefined { return this._model; } @@ -121,7 +122,8 @@ export class MergeEditor extends AbstractTextEditor { this._ctxIsMergeEditor = ctxIsMergeEditor.bindTo(_contextKeyService); this._ctxUsesColumnLayout = ctxMergeEditorLayout.bindTo(_contextKeyService); - this._ctxBaseResourceScheme = ctxBaseResourceScheme.bindTo(_contextKeyService); + this._ctxBaseUri = ctxMergeBaseUri.bindTo(_contextKeyService); + this._ctxResultUri = ctxMergeResultUri.bindTo(_contextKeyService); this._layoutMode = instantiation.createInstance(MergeEditorLayout); this._ctxUsesColumnLayout.set(this._layoutMode.value); @@ -205,6 +207,7 @@ export class MergeEditor extends AbstractTextEditor { override dispose(): void { this._sessionDisposables.dispose(); this._ctxIsMergeEditor.reset(); + this._ctxUsesColumnLayout.reset(); super.dispose(); } @@ -305,7 +308,14 @@ export class MergeEditor extends AbstractTextEditor { this.input1View.setModel(viewModel, model.input1, model.input1Title || localize('input1', 'Input 1'), model.input1Detail, model.input1Description); this.input2View.setModel(viewModel, model.input2, model.input2Title || localize('input2', 'Input 2',), model.input2Detail, model.input2Description); this.inputResultView.setModel(viewModel, model.result, localize('result', 'Result',), this._labelService.getUriLabel(model.result.uri, { relative: true }), undefined); - this._ctxBaseResourceScheme.set(model.base.uri.scheme); + + // Set/unset context keys based on input + this._ctxResultUri.set(model.result.uri.toString()); + this._ctxBaseUri.set(model.base.uri.toString()); + this._sessionDisposables.add(toDisposable(() => { + this._ctxBaseUri.reset(); + this._ctxResultUri.reset(); + })); const viewState = this.loadEditorViewState(input, context); if (viewState) { diff --git a/src/vs/workbench/contrib/mergeEditor/common/mergeEditor.ts b/src/vs/workbench/contrib/mergeEditor/common/mergeEditor.ts index 9ec46266ae2..e5757fcc8fa 100644 --- a/src/vs/workbench/contrib/mergeEditor/common/mergeEditor.ts +++ b/src/vs/workbench/contrib/mergeEditor/common/mergeEditor.ts @@ -3,10 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { localize } from 'vs/nls'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; export type MergeEditorLayoutTypes = 'mixed' | 'columns'; -export const ctxIsMergeEditor = new RawContextKey('isMergeEditor', false); -export const ctxMergeEditorLayout = new RawContextKey('mergeEditorLayout', 'mixed'); -export const ctxBaseResourceScheme = new RawContextKey('baseResourceScheme', ''); +export const ctxIsMergeEditor = new RawContextKey('isMergeEditor', false, { type: 'boolean', description: localize('is', 'The editor is a merge editor') }); +export const ctxMergeEditorLayout = new RawContextKey('mergeEditorLayout', 'mixed', { type: 'string', description: localize('editorLayout', 'The layout mode of a merge editor') }); +export const ctxMergeBaseUri = new RawContextKey('mergeEditorBaseUri', '', { type: 'string', description: localize('baseUri', 'The uri of the baser of a merge editor') }); +export const ctxMergeResultUri = new RawContextKey('mergeEditorResultUri', '', { type: 'string', description: localize('resultUri', 'The uri of the result of a merge editor') }); diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts index 32242173816..55f61b3c685 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts @@ -18,7 +18,7 @@ import { localize } from 'vs/nls'; import { MenuId, MenuRegistry, registerAction2, Action2 } from 'vs/platform/actions/common/actions'; import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ContextKeyEqualsExpr, ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; +import { ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; @@ -59,7 +59,7 @@ import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { MergeEditorInput } from 'vs/workbench/contrib/mergeEditor/browser/mergeEditorInput'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { ctxIsMergeEditor } from 'vs/workbench/contrib/mergeEditor/common/mergeEditor'; +import { ctxIsMergeEditor, ctxMergeBaseUri } from 'vs/workbench/contrib/mergeEditor/common/mergeEditor'; import { EditorResolution } from 'vs/platform/editor/common/editor'; const CONTEXT_CONFLICTS_SOURCES = new RawContextKey('conflictsSources', ''); @@ -1292,7 +1292,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo title: localize('accept merges title', "Accept Merge"), menu: [{ id: MenuId.MergeToolbar, - when: ContextKeyExpr.and(ctxIsMergeEditor, ContextKeyEqualsExpr.create('baseResourceScheme', USER_DATA_SYNC_SCHEME)), + when: ContextKeyExpr.and(ctxIsMergeEditor, ContextKeyExpr.regex(ctxMergeBaseUri.key, new RegExp(`^${USER_DATA_SYNC_SCHEME}:`))), }], }); }