Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/cli/src/tests/prompt-input-keys.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,17 @@ test("parseTerminalInput recognizes alternate shifted return sequences", () => {
}
});

test("parseTerminalInput recognizes ctrl+enter modifyOtherKeys sequences as newline", () => {
for (const sequence of ["\u001B[13;5u", "\u001B[27;5;13~"]) {
const { input, key } = parseTerminalInput(sequence);
assert.equal(key.return, true);
assert.equal(key.ctrl, true);
assert.equal(key.shift, false);
assert.equal(getPromptReturnKeyAction(key), "newline");
assert.equal(input.startsWith("["), true);
}
});

test("terminal extended key helpers request and restore modifyOtherKeys mode", () => {
assert.equal(enableTerminalExtendedKeys(), "\u001B[>4;1m");
assert.equal(disableTerminalExtendedKeys(), "\u001B[>4;0m");
Expand Down
10 changes: 8 additions & 2 deletions packages/cli/src/ui/hooks/useTerminalInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ const HOME_SEQUENCES = new Set(["\u001B[H", "\u001B[1~", "\u001B[7~", "\u001BOH"
const END_SEQUENCES = new Set(["\u001B[F", "\u001B[4~", "\u001B[8~", "\u001BOF"]);
const SHIFT_RETURN_SEQUENCES = new Set(["\u001B\r", "\u001B[13;2u", "\u001B[13;2~", "\u001B[27;2;13~"]);
const META_RETURN_SEQUENCES = new Set(["\u001B[13;3u", "\u001B[13;4u"]);
// Ctrl+Enter in modifyOtherKeys mode: keycode 13 (Enter), modifier 5 (Ctrl).
const CTRL_RETURN_SEQUENCES = new Set(["\u001B[13;5u", "\u001B[27;5;13~"]);
const CTRL_LEFT_SEQUENCES = new Set(["\u001B[1;5D", "\u001B[5D"]);
const CTRL_RIGHT_SEQUENCES = new Set(["\u001B[1;5C", "\u001B[5C"]);
const META_LEFT_SEQUENCES = new Set(["\u001B[1;3D", "\u001B[3D", "\u001Bb"]);
Expand Down Expand Up @@ -124,9 +126,13 @@ export function parseTerminalInput(data: Buffer | string): { input: string; key:
end: END_SEQUENCES.has(raw),
pageDown: raw === "\u001B[6~",
pageUp: raw === "\u001B[5~",
return: raw === "\r" || SHIFT_RETURN_SEQUENCES.has(raw) || META_RETURN_SEQUENCES.has(raw),
return:
raw === "\r" ||
SHIFT_RETURN_SEQUENCES.has(raw) ||
META_RETURN_SEQUENCES.has(raw) ||
CTRL_RETURN_SEQUENCES.has(raw),
escape: raw === "\u001B",
ctrl: CTRL_LEFT_SEQUENCES.has(raw) || CTRL_RIGHT_SEQUENCES.has(raw),
ctrl: CTRL_LEFT_SEQUENCES.has(raw) || CTRL_RIGHT_SEQUENCES.has(raw) || CTRL_RETURN_SEQUENCES.has(raw),
shift: SHIFT_RETURN_SEQUENCES.has(raw),
tab: raw === "\t" || raw === "\u001B[Z",
backspace: BACKSPACE_BYTES.has(raw),
Expand Down
8 changes: 5 additions & 3 deletions packages/cli/src/ui/views/PromptInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export const PromptInput = React.memo(function PromptInput({
? statusMessage
: busy
? busyStatusText
: `enter send · shift+enter newline · @ files · ctrl+v image · / commands · ctrl+d exit${processOrPasteHint}`;
: `enter send · shift+enter/ctrl+enter newline · @ files · ctrl+v image · / commands · ctrl+d exit${processOrPasteHint}`;
const showFooterText = useMemo(
() => showMenu || showSkillsDropdown || openRawModelDropdown || showModelDropdown || showFileMentionMenu,
[showMenu, showSkillsDropdown, showModelDropdown, openRawModelDropdown, showFileMentionMenu]
Expand Down Expand Up @@ -968,11 +968,13 @@ export function isRawModeShortcut(input: string, key: Pick<InputKey, "ctrl">): b

export type PromptReturnKeyAction = "submit" | "newline" | null;

export function getPromptReturnKeyAction(key: Pick<InputKey, "return" | "shift" | "meta">): PromptReturnKeyAction {
export function getPromptReturnKeyAction(
key: Pick<InputKey, "return" | "shift" | "meta" | "ctrl">
): PromptReturnKeyAction {
if (!key.return) {
return null;
}
if (key.shift || key.meta) {
if (key.shift || key.meta || key.ctrl) {
return "newline";
}
return "submit";
Expand Down