fix: forward Ctrl+Enter as kitty CSI-u

Fixes #5966.

Co-authored-by: gatsby74 <166927047+gatsby74@users.noreply.github.com>
This commit is contained in:
gatsby74 2026-06-26 01:38:05 +02:00 committed by GitHub
parent db0865ce2c
commit 4e45df92ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 64 additions and 0 deletions

View File

@ -107,6 +107,43 @@ describe('resolveTerminalShortcutAction', () => {
})
})
it('forwards Ctrl+Enter as the kitty CSI-u chord so TUIs can cue instead of send', () => {
// Why: xterm.js collapses Ctrl+Enter to a bare CR; intercept upstream and
// emit the kitty sequence (modifier code 5 = Ctrl) so probing TUIs receive
// the distinct chord on every platform.
expect(
resolveTerminalShortcutAction(event({ key: 'Enter', code: 'Enter', ctrlKey: true }), true)
).toEqual({ type: 'sendInput', data: '\x1b[13;5u' })
expect(
resolveTerminalShortcutAction(event({ key: 'Enter', code: 'Enter', ctrlKey: true }), false)
).toEqual({ type: 'sendInput', data: '\x1b[13;5u' })
// Windows uses the same kitty sequence for now: no TUI is known to treat the
// CSI-u Ctrl+Enter form as inert (cf. the Shift+Enter Codex-on-PowerShell case).
expect(
resolveTerminalShortcutAction(
event({ key: 'Enter', code: 'Enter', ctrlKey: true }),
false,
'false',
0,
true
)
).toEqual({ type: 'sendInput', data: '\x1b[13;5u' })
// Modifier combos that are NOT plain Ctrl+Enter must keep falling through.
expect(
resolveTerminalShortcutAction(
event({ key: 'Enter', code: 'Enter', ctrlKey: true, shiftKey: true }),
true
)
).toBeNull()
expect(
resolveTerminalShortcutAction(
event({ key: 'Enter', code: 'Enter', ctrlKey: true, metaKey: true }),
true
)
).toBeNull()
})
it('translates Cmd+←/→ on macOS to readline start/end-of-line (Ctrl+A/E)', () => {
expect(
resolveTerminalShortcutAction(

View File

@ -103,6 +103,23 @@ export function resolveTerminalShortcutAction(
return { type: 'sendInput', data: isWindows ? '\x1b\r' : '\x1b[13;2u' }
}
if (
event.ctrlKey &&
!event.metaKey &&
!event.altKey &&
!event.shiftKey &&
event.key === 'Enter'
) {
// Why: xterm.js collapses Ctrl+Enter to a bare CR, so TUIs that expect
// modified Enter chords never receive the distinct input and treat it as
// plain Enter. Forward the kitty CSI-u sequence directly (modifier code
// 5 = Ctrl; cf. 2 = Shift above) so cue/queue behavior reaches the TUI.
// Sibling of the Shift+Enter case; a Windows fallback is not added yet
// because, unlike #2418's Codex-on-PowerShell inertness, no Windows TUI is
// known to drop the CSI-u form for Ctrl+Enter.
return { type: 'sendInput', data: '\x1b[13;5u' }
}
if (
event.ctrlKey &&
!event.metaKey &&

View File

@ -495,6 +495,16 @@ test.describe('Terminal Shortcuts', () => {
)
})
test('Ctrl+Enter writes the kitty modified-enter chord for terminal TUIs', async ({
orcaPage,
electronApp
}) => {
await installMainProcessPtyWriteSpy(electronApp)
await waitForActivePanePtyId(orcaPage)
await pressAndExpectWrite(orcaPage, electronApp, 'Control+Enter', '\x1b[13;5u')
})
test('plain Ctrl+C sends ETX under kitty keyboard reporting', async ({
orcaPage,
electronApp