fix(ask): honor app interrupt in prompt editor

This commit is contained in:
Vu Anh Nguyen
2026-03-26 16:50:03 +07:00
parent 5a616b3cd6
commit d28e3eb950
2 changed files with 28 additions and 4 deletions
@@ -80,8 +80,8 @@ export class HookEditorComponent extends Container {
/** Prompt-style: raw Enter submits; Editor owns newline-producing sequences. */
#handlePromptStyleInput(keyData: string): void {
// Escape to cancel
if (matchesKey(keyData, "escape") || matchesKey(keyData, "esc")) {
// Prompt-style keeps Escape as an explicit cancel key and also honors app.interrupt remaps.
if (matchesKey(keyData, "escape") || matchesKey(keyData, "esc") || matchesAppInterrupt(keyData)) {
this.#onCancelCallback();
return;
}
+26 -2
View File
@@ -1,9 +1,10 @@
import { beforeAll, describe, expect, it, vi } from "bun:test";
import { afterEach, beforeAll, describe, expect, it, vi } from "bun:test";
import { KeybindingsManager } from "@oh-my-pi/pi-coding-agent/config/keybindings";
import { HookEditorComponent } from "@oh-my-pi/pi-coding-agent/modes/components/hook-editor";
import { ExtensionUiController } from "@oh-my-pi/pi-coding-agent/modes/controllers/extension-ui-controller";
import { getThemeByName, setThemeInstance } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
import type { InteractiveModeContext } from "@oh-my-pi/pi-coding-agent/modes/types";
import type { TUI } from "@oh-my-pi/pi-tui";
import { setKeybindings, type TUI } from "@oh-my-pi/pi-tui";
beforeAll(async () => {
const theme = await getThemeByName("dark");
@@ -13,6 +14,11 @@ beforeAll(async () => {
setThemeInstance(theme);
});
afterEach(() => {
setKeybindings(KeybindingsManager.inMemory());
vi.restoreAllMocks();
});
function createTui(): TUI {
return {
requestRender: vi.fn(),
@@ -260,6 +266,24 @@ describe("HookEditorComponent prompt-style mode", () => {
expect(onCancel).toHaveBeenCalledTimes(1);
expect(onSubmit).not.toHaveBeenCalled();
});
it("cancels on app.interrupt in prompt-style mode even when remapped", () => {
setKeybindings(
KeybindingsManager.inMemory({
"app.interrupt": "ctrl+c",
}),
);
const onSubmit = vi.fn();
const onCancel = vi.fn();
const component = new HookEditorComponent(createTui(), "Prompt", "draft", onSubmit, onCancel, {
promptStyle: true,
});
component.handleInput("\x03");
expect(onCancel).toHaveBeenCalledTimes(1);
expect(onSubmit).not.toHaveBeenCalled();
});
});
describe("ExtensionUiController hook editor abort", () => {