diff --git a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts index 6f533f17b438f..c38dc40be0647 100644 --- a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts +++ b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts @@ -29,6 +29,7 @@ import { RepositoryPicker, SCMViewService } from './scmViewService.js'; import { SCMRepositoriesViewPane } from './scmRepositoriesViewPane.js'; import { IInstantiationService, ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js'; import { Context as SuggestContext } from '../../../../editor/contrib/suggest/browser/suggest.js'; +import { InlineCompletionContextKeys } from '../../../../editor/contrib/inlineCompletions/browser/controller/inlineCompletionContextKeys.js'; import { MANAGE_TRUST_COMMAND_ID, WorkspaceTrustContext } from '../../workspace/common/workspace.js'; import { IQuickDiffService } from '../common/quickDiff.js'; import { QuickDiffService } from '../common/quickDiffService.js'; @@ -459,10 +460,28 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ } }); +KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: 'scm.clearValidation', + weight: KeybindingWeight.WorkbenchContrib, + when: ContextKeyExpr.and( + ContextKeyExpr.has('scmRepository'), + ContextKeys.SCMInputHasValidationMessage), + primary: KeyCode.Escape, + handler: async (accessor) => { + const scmViewService = accessor.get(ISCMViewService); + scmViewService.activeRepository.get()?.repository.input.clearValidation(); + } +}); + KeybindingsRegistry.registerCommandAndKeybindingRule({ id: 'scm.clearInput', weight: KeybindingWeight.WorkbenchContrib, - when: ContextKeyExpr.and(ContextKeyExpr.has('scmRepository'), SuggestContext.Visible.toNegated(), EditorContextKeys.hasNonEmptySelection.toNegated()), + when: ContextKeyExpr.and( + ContextKeyExpr.has('scmRepository'), + SuggestContext.Visible.toNegated(), + InlineCompletionContextKeys.inlineSuggestionVisible.toNegated(), + ContextKeys.SCMInputHasValidationMessage.toNegated(), + EditorContextKeys.hasNonEmptySelection.toNegated()), primary: KeyCode.Escape, handler: async (accessor) => { const scmService = accessor.get(ISCMService); diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index cfea0879c9d7f..158af1b23887b 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -981,6 +981,7 @@ export const ContextKeys = { SCMCurrentHistoryItemRefInFilter: new RawContextKey('scmCurrentHistoryItemRefInFilter', false), RepositoryCount: new RawContextKey('scmRepositoryCount', 0), RepositoryVisibilityCount: new RawContextKey('scmRepositoryVisibleCount', 0), + SCMInputHasValidationMessage: new RawContextKey('scmInputHasValidationMessage', false), RepositoryVisibility(repository: ISCMRepository) { return new RawContextKey(`scmRepositoryVisible:${repository.provider.id}`, false); } @@ -1696,6 +1697,7 @@ class SCMInputWidget { private model: { readonly input: ISCMInput; readonly textModel: ITextModel } | undefined; private repositoryIdContextKey: IContextKey; + private validationMessageContextKey: IContextKey; private readonly repositoryDisposables = new DisposableStore(); private validation: IInputValidation | undefined; @@ -1777,6 +1779,7 @@ class SCMInputWidget { this.repositoryDisposables.add(input.onDidChangeFocus(() => this.focus())); this.repositoryDisposables.add(input.onDidChangeValidationMessage((e) => this.setValidation(e, { focus: true, timeout: true }))); this.repositoryDisposables.add(input.onDidChangeValidateInput((e) => triggerValidation())); + this.repositoryDisposables.add(input.onDidClearValidation(() => this.clearValidation())); // Keep API in sync with model and validate this.repositoryDisposables.add(textModel.onDidChangeContent(() => { @@ -1906,6 +1909,7 @@ class SCMInputWidget { this.contextKeyService = contextKeyService.createScoped(this.element); this.repositoryIdContextKey = this.contextKeyService.createKey('scmRepository', undefined); + this.validationMessageContextKey = ContextKeys.SCMInputHasValidationMessage.bindTo(this.contextKeyService); this.inputEditorOptions = new SCMInputWidgetEditorOptions(overflowWidgetsDomNode, this.configurationService); this.disposables.add(this.inputEditorOptions.onDidChange(this.onDidChangeEditorOptions, this)); @@ -2069,6 +2073,7 @@ class SCMInputWidget { return; } + this.validationMessageContextKey.set(true); const disposables = new DisposableStore(); this.validationContextView = this.contextViewService.showContextView({ @@ -2146,6 +2151,7 @@ class SCMInputWidget { this.validationContextView?.close(); this.validationContextView = undefined; this.validationHasFocus = false; + this.validationMessageContextKey.set(false); } dispose(): void { diff --git a/src/vs/workbench/contrib/scm/common/scm.ts b/src/vs/workbench/contrib/scm/common/scm.ts index 63a864b9faa41..1bf661ed07248 100644 --- a/src/vs/workbench/contrib/scm/common/scm.ts +++ b/src/vs/workbench/contrib/scm/common/scm.ts @@ -163,6 +163,9 @@ export interface ISCMInput { showValidationMessage(message: string | IMarkdownString, type: InputValidationType): void; readonly onDidChangeValidationMessage: Event; + clearValidation(): void; + readonly onDidClearValidation: Event; + showNextHistoryValue(): void; showPreviousHistoryValue(): void; } diff --git a/src/vs/workbench/contrib/scm/common/scmService.ts b/src/vs/workbench/contrib/scm/common/scmService.ts index bd3c282b499e1..a0f2ebc47dad4 100644 --- a/src/vs/workbench/contrib/scm/common/scmService.ts +++ b/src/vs/workbench/contrib/scm/common/scmService.ts @@ -86,6 +86,13 @@ class SCMInput extends Disposable implements ISCMInput { private readonly _onDidChangeValidationMessage = new Emitter(); readonly onDidChangeValidationMessage: Event = this._onDidChangeValidationMessage.event; + clearValidation(): void { + this._onDidClearValidation.fire(); + } + + private readonly _onDidClearValidation = new Emitter(); + readonly onDidClearValidation: Event = this._onDidClearValidation.event; + private _validateInput: IInputValidator = () => Promise.resolve(undefined); get validateInput(): IInputValidator {