fix(tui): treat Apple Terminal ESC+Return with Shift held as Shift+Enter

This commit is contained in:
triagent 2026-10-29 09:50:33 +00:00
parent babe30a7e6
commit 6100617ba9
2 changed files with 26 additions and 2 deletions

View file

@ -70,6 +70,8 @@ export function normalizeNativeShiftEnterInput(
}
export function normalizeAppleTerminalInput(data: string, isAppleTerminal: boolean, isShiftPressed: boolean): string {
// Apple Terminal sends ESC + Return for Shift+Enter in some versions, which would otherwise parse as Alt+Enter.
if (isAppleTerminal && data === "\x1b\r" && isShiftPressed) return NATIVE_SHIFT_ENTER_SEQUENCE;
return normalizeNativeShiftEnterInput(data, isAppleTerminal, isShiftPressed);
}
@ -396,8 +398,18 @@ export class ProcessTerminal implements Terminal {
private forwardInputSequence(sequence: string): void {
if (!this.inputHandler) return;
const shouldDetectNativeShiftEnter =
sequence === "\r" && (isAppleTerminalSession() || process.platform === "win32");
if (isAppleTerminalSession()) {
const shouldDetectNativeShiftEnter = sequence === "\r" || sequence === "\x1b\r";
this.inputHandler(
normalizeAppleTerminalInput(
sequence,
shouldDetectNativeShiftEnter,
shouldDetectNativeShiftEnter && isNativeModifierPressed("shift"),
),
);
return;
}
const shouldDetectNativeShiftEnter = sequence === "\r" && process.platform === "win32";
const input = normalizeNativeShiftEnterInput(
sequence,
shouldDetectNativeShiftEnter,

View file

@ -59,6 +59,18 @@ describe("normalizeAppleTerminalInput", () => {
assert.equal(normalizeAppleTerminalInput("\r", true, false), "\r");
});
it("rewrites Apple Terminal ESC + Return to CSI-u Shift+Enter when Shift is pressed", () => {
assert.equal(normalizeAppleTerminalInput("\x1b\r", true, true), "\x1b[13;2u");
});
it("leaves Apple Terminal ESC + Return unchanged when Shift is not pressed", () => {
assert.equal(normalizeAppleTerminalInput("\x1b\r", true, false), "\x1b\r");
});
it("leaves non-Apple Terminal ESC + Return unchanged when Shift is pressed", () => {
assert.equal(normalizeAppleTerminalInput("\x1b\r", false, true), "\x1b\r");
});
it("leaves non-Apple Terminal Return unchanged when Shift is pressed", () => {
assert.equal(normalizeAppleTerminalInput("\r", false, true), "\r");
});