fix: input keyboard shortcuts (#676)
Fixes keyboard shortcuts: - ctrl+a/e - opt+arrow keys
This commit is contained in:
@@ -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 && (
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
* Higher‑level 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");
|
||||
|
||||
Reference in New Issue
Block a user