fix: input keyboard shortcuts (#676)

Fixes keyboard shortcuts:
- ctrl+a/e
- opt+arrow keys
This commit is contained in:
Fouad Matin
2025-04-25 16:58:09 -07:00
committed by GitHub
parent f3ee933a74
commit 3f4762d969
4 changed files with 66 additions and 21 deletions

View File

@@ -106,11 +106,16 @@ export default function TerminalChatInputThinking({
return (
<Box flexDirection="column" gap={1}>
<Box gap={2}>
<Text>{frameWithSeconds}</Text>
<Box justifyContent="space-between">
<Box gap={2}>
<Text>{frameWithSeconds}</Text>
<Text>
Thinking
{dots}
</Text>
</Box>
<Text>
Thinking
{dots}
Press <Text bold>Esc</Text> twice to interrupt
</Text>
</Box>
{awaitingConfirm && (

View File

@@ -412,7 +412,7 @@ export default function TerminalChatInput({
setInput("");
openApprovalOverlay();
return;
} else if (inputValue === "exit") {
} else if (["exit", "q", ":q"].includes(inputValue)) {
setInput("");
setTimeout(() => {
app.exit();
@@ -881,20 +881,30 @@ function TerminalChatInputThinking({
);
return (
<Box flexDirection="column" gap={1}>
<Box gap={2}>
<Text>{frameWithSeconds}</Text>
<Box width="100%" flexDirection="column" gap={1}>
<Box
flexDirection="row"
width="100%"
justifyContent="space-between"
paddingRight={1}
>
<Box gap={2}>
<Text>{frameWithSeconds}</Text>
<Text>
Thinking
{dots}
</Text>
</Box>
<Text>
Thinking
{dots}
<Text dimColor>press</Text> <Text bold>Esc</Text>{" "}
{awaitingConfirm ? (
<Text bold>again</Text>
) : (
<Text dimColor>twice</Text>
)}{" "}
<Text dimColor>to interrupt</Text>
</Text>
</Box>
{awaitingConfirm && (
<Text dimColor>
Press <Text bold>Esc</Text> again to interrupt and enter a new
instruction
</Text>
)}
</Box>
);
}

View File

@@ -73,7 +73,7 @@ const TerminalHeader: React.FC<TerminalHeaderProps> = ({
</Text>
<Text dimColor>
<Text color="blueBright"></Text> approval:{" "}
<Text bold color={colorsByPolicy[approvalPolicy]} dimColor>
<Text bold color={colorsByPolicy[approvalPolicy]}>
{approvalPolicy}
</Text>
</Text>

View File

@@ -610,6 +610,24 @@ export default class TextBuffer {
}
}
/* ------------------------------------------------------------------
* Document-level navigation helpers
* ---------------------------------------------------------------- */
/** Move caret to *absolute* beginning of the buffer (row-0, col-0). */
private moveToStartOfDocument(): void {
this.preferredCol = null;
this.cursorRow = 0;
this.cursorCol = 0;
}
/** Move caret to *absolute* end of the buffer (last row, last column). */
private moveToEndOfDocument(): void {
this.preferredCol = null;
this.cursorRow = this.lines.length - 1;
this.cursorCol = this.lineLen(this.cursorRow);
}
/* =====================================================================
* Higherlevel helpers
* =================================================================== */
@@ -780,6 +798,18 @@ export default class TextBuffer {
key["rightArrow"]
) {
this.move("wordRight");
}
// Many terminal/OS combinations (e.g. macOS Terminal.app & iTerm2 with
// the default key-bindings) translate ⌥← / ⌥→ into the classic readline
// shortcuts ESC-b / ESC-f rather than an ANSI arrow sequence that Ink
// would tag with `leftArrow` / `rightArrow`. Ink parses those 2-byte
// escape sequences into `input === "b"|"f"` with `key.meta === true`.
// Handle this variant explicitly so that Option+Arrow performs word
// navigation consistently across environments.
else if (key["meta"] && (input === "b" || input === "B")) {
this.move("wordLeft");
} else if (key["meta"] && (input === "f" || input === "F")) {
this.move("wordRight");
} else if (key["home"]) {
this.move("home");
} else if (key["end"]) {
@@ -823,11 +853,11 @@ export default class TextBuffer {
// Emacs/readline-style shortcuts
else if (key["ctrl"] && (input === "a" || input === "\x01")) {
// Ctrl+A or ⌥← → start of line
this.move("home");
// Ctrl+A → start of input (first row, first column)
this.moveToStartOfDocument();
} else if (key["ctrl"] && (input === "e" || input === "\x05")) {
// Ctrl+E or ⌥→ → end of line
this.move("end");
// Ctrl+E → end of input (last row, last column)
this.moveToEndOfDocument();
} else if (key["ctrl"] && (input === "b" || input === "\x02")) {
// Ctrl+B → char left
this.move("left");