diff --git a/packages/coding-agent/src/modes/components/custom-editor.ts b/packages/coding-agent/src/modes/components/custom-editor.ts index 1cc4e32d7..9e27cbb4b 100644 --- a/packages/coding-agent/src/modes/components/custom-editor.ts +++ b/packages/coding-agent/src/modes/components/custom-editor.ts @@ -586,8 +586,15 @@ export class CustomEditor extends Editor { return; } - // Intercept configured retry shortcut + // Intercept configured retry shortcut. Later user/custom handlers keep + // precedence so adding the default Alt+R binding does not steal existing + // shortcuts such as app.plan.toggle or extension commands. if (this.#matchesAction(canonical, "app.retry") && this.onRetry) { + const customHandler = this.#customMatchKeys.get(canonical); + if (customHandler) { + customHandler(); + return; + } this.onRetry(); return; } diff --git a/packages/coding-agent/test/custom-editor-keybindings.test.ts b/packages/coding-agent/test/custom-editor-keybindings.test.ts index 3e40f027a..e0f3a71fa 100644 --- a/packages/coding-agent/test/custom-editor-keybindings.test.ts +++ b/packages/coding-agent/test/custom-editor-keybindings.test.ts @@ -17,4 +17,17 @@ describe("CustomEditor keybindings", () => { expect(onRetry).toHaveBeenCalledTimes(1); }); + + it("lets custom handlers keep precedence over the default retry chord", () => { + const editor = new CustomEditor(getEditorTheme()); + const onRetry = vi.fn(); + const customHandler = vi.fn(); + + editor.onRetry = onRetry; + editor.setCustomKeyHandler("alt+r", customHandler); + editor.handleInput("\x1br"); + + expect(customHandler).toHaveBeenCalledTimes(1); + expect(onRetry).not.toHaveBeenCalled(); + }); });