fix(coding-agent): stop ESC from aborting agent run while @ autocomplete is open
When the autocomplete popup is visible, ESC unconditionally falls through to the editor base class so it can dismiss the popup. Only an ESC with no popup visible reaches onEscape and routes to the global interrupt handler. Removed the shouldBypassAutocompleteOnEscape callback that paved over the popup-dismissal path whenever the agent was busy (streaming, bash, /btw, auto-compaction, etc.) — that is precisely the moment the user is most likely to hit ESC while the popup is open, and dismissing-then-aborting in one keystroke is a footgun, not a feature. Two-press semantics now match the standard TUI/IDE pattern: first ESC closes the popup, second ESC aborts. Tests cover both branches in custom-editor-keybindings.test.ts and the input-controller escape suite no longer asserts the dead callback. Fixes #1655
This commit is contained in:
@@ -49,7 +49,6 @@ export class CustomEditor extends Editor {
|
||||
* them, skipping any occurrence inside code spans, fenced blocks, or XML sections. */
|
||||
decorateText = (text: string): string => highlightMagicKeywords(text);
|
||||
onEscape?: () => void;
|
||||
shouldBypassAutocompleteOnEscape?: () => boolean;
|
||||
onClear?: () => void;
|
||||
onExit?: () => void;
|
||||
onCycleThinkingLevel?: () => void;
|
||||
@@ -186,12 +185,15 @@ export class CustomEditor extends Editor {
|
||||
}
|
||||
|
||||
// Intercept configured interrupt shortcut.
|
||||
// Default behavior keeps autocomplete dismissal, but parent can prioritize global interrupt handling.
|
||||
if (this.#matchesAction(data, "app.interrupt") && this.onEscape) {
|
||||
if (!this.isShowingAutocomplete() || this.shouldBypassAutocompleteOnEscape?.()) {
|
||||
this.onEscape();
|
||||
return;
|
||||
}
|
||||
// When the autocomplete popup is visible, ESC's first job is to dismiss
|
||||
// the popup — let super.handleInput() route it to #cancelAutocomplete().
|
||||
// The user can press ESC again afterward to fire the global interrupt
|
||||
// handler. This matches the standard TUI/IDE pattern and prevents a
|
||||
// single ESC from both closing an @ completion and aborting an active
|
||||
// agent run (#1655).
|
||||
if (this.#matchesAction(data, "app.interrupt") && this.onEscape && !this.isShowingAutocomplete()) {
|
||||
this.onEscape();
|
||||
return;
|
||||
}
|
||||
|
||||
// Intercept configured clear shortcut
|
||||
|
||||
Reference in New Issue
Block a user