tui: add double-esc interrupt mechanism for long-running operations

Users can now press escape twice within 5 seconds to interrupt long-running
operations in the TUI. The first press shows a visual hint, and the second
press aborts the current session.
This commit is contained in:
Dax Raad
2025-11-11 22:03:54 -05:00
parent 18260b037b
commit e3a2728fa3

View File

@@ -228,11 +228,21 @@ export function Prompt(props: PromptProps) {
if (!props.sessionID) return if (!props.sessionID) return
if (autocomplete.visible) return if (autocomplete.visible) return
if (!input.focused) return if (!input.focused) return
sdk.client.session.abort({
path: { setStore("interrupt", store.interrupt + 1)
id: props.sessionID,
}, setTimeout(() => {
}) setStore("interrupt", 0)
}, 5000)
if (store.interrupt >= 2) {
sdk.client.session.abort({
path: {
id: props.sessionID,
},
})
setStore("interrupt", 0)
}
dialog.clear() dialog.clear()
}, },
}, },
@@ -252,6 +262,7 @@ export function Prompt(props: PromptProps) {
prompt: PromptInfo prompt: PromptInfo
mode: "normal" | "shell" mode: "normal" | "shell"
extmarkToPartIndex: Map<number, number> extmarkToPartIndex: Map<number, number>
interrupt: number
}>({ }>({
prompt: { prompt: {
input: "", input: "",
@@ -259,6 +270,7 @@ export function Prompt(props: PromptProps) {
}, },
mode: "normal", mode: "normal",
extmarkToPartIndex: new Map(), extmarkToPartIndex: new Map(),
interrupt: 0,
}) })
createEffect(() => { createEffect(() => {
@@ -746,8 +758,11 @@ export function Prompt(props: PromptProps) {
</Match> </Match>
<Match when={status() === "working"}> <Match when={status() === "working"}>
<box flexDirection="row" gap={1}> <box flexDirection="row" gap={1}>
<text fg={theme.text}> <text fg={store.interrupt > 0 ? theme.primary : theme.text}>
esc <span style={{ fg: theme.textMuted }}>interrupt</span> esc{" "}
<span style={{ fg: store.interrupt > 0 ? theme.primary : theme.textMuted }}>
{store.interrupt > 0 ? "again to interrupt" : "interrupt"}
</span>
</text> </text>
</box> </box>
</Match> </Match>