Skip to content

Handle Windows Shift+Enter newlines#115

Closed
nedtwigg wants to merge 3 commits into
mainfrom
shift-enter-windows-codex
Closed

Handle Windows Shift+Enter newlines#115
nedtwigg wants to merge 3 commits into
mainfrom
shift-enter-windows-codex

Conversation

@nedtwigg
Copy link
Copy Markdown
Member

@nedtwigg nedtwigg commented May 29, 2026

Summary

  • normalize Windows Shift+Enter before xterm handles it so terminal TUIs receive multiline input instead of normal Enter
  • send a bracketed-paste LF (\x1b[200~\n\x1b[201~) when the foreground app has enabled bracketed paste, with bare LF (\x0a) as the fallback
  • keep the normalization in the shared terminal input path so activity, untouched state, and prompt tracking still run
  • document the passthrough-mode behavior and add regression coverage

Verification

  • pnpm.cmd --filter dormouse-lib exec vitest run src/lib/terminal-keyboard.test.ts src/lib/terminal-registry.alert.test.ts
  • pnpm.cmd --filter dormouse-lib build
  • pnpm.cmd --filter dormouse build:frontend
  • pnpm.cmd --filter dormouse build

Note: full pnpm.cmd --filter dormouse-lib test had 2 unrelated clipboard expectation failures about quoted file paths before this follow-up.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 29, 2026

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 187d4c0
Status: ✅  Deploy successful!
Preview URL: https://d5dd5b13.mouseterm.pages.dev
Branch Preview URL: https://shift-enter-windows-codex.mouseterm.pages.dev

View logs

Copy link
Copy Markdown
Collaborator

@dormouse-bot dormouse-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing as a draft — flagging anything that looks worth a quick fix. Mark ready for a full review.

The new integration test fails on Linux CI

The new terminal-registry.alert.test.ts case "sends LF for Windows Shift+Enter before xterm handles Enter normally" fails when run on ubuntu-latest (what ci.yml uses):

 FAIL  src/lib/terminal-registry.alert.test.ts > terminal-registry alert behavior > sends LF for Windows Shift+Enter before xterm handles Enter normally
AssertionError: expected null to be false

IS_WINDOWS in lib/src/lib/platform/index.ts is computed once at module load from navigator.userAgent. On the Linux runner it evaluates to false, so attachCustomKeyEventHandler is never invoked (the gate in terminal-lifecycle.ts is IS_WINDOWS || getPlatform().runWorkbenchCommand, and FakePtyAdapter has no runWorkbenchCommand). emitKeyDown then returns null rather than false, and no writes happen. The change passed locally because the verification was run with pnpm.cmd on Windows.

Easiest fix is to override IS_WINDOWS in the existing platform mock so the handler is always attached in this test file:

vi.mock('./platform', async () => {
  const actual = await vi.importActual<typeof import('./platform')>('./platform');
  const fakePlatform = new actual.FakePtyAdapter();
  return {
    ...actual,
    IS_WINDOWS: true,
    getPlatform: () => fakePlatform,
    __fakePlatform: fakePlatform,
  };
});

The other tests in this file all drive input via emitInput (the xterm onData path), so forcing IS_WINDOWS: true just attaches a handler nothing else calls.

Windows non–VS-Code hosts now suppress browser defaults for VS Code chords

if (IS_WINDOWS || getPlatform().runWorkbenchCommand) causes the handler to attach on Windows even when runWorkbenchCommand is undefined (Tauri standalone, the fake adapter, anything that isn't the VS Code adapter). The fallthrough branch then runs vscodeWorkbenchCommandForKeydown for every keydown. On a match (F1, Ctrl+P, Ctrl+Shift+P, Ctrl+B) the handler calls event.preventDefault() + event.stopPropagation(), no-ops getPlatform().runWorkbenchCommand?.(command), and returns true so xterm still processes the key. Net behavior: the browser default for those chords is silently suppressed on Windows non–VS-Code hosts without any compensating workbench command running. Probably benign in a terminal pane, but it's an unannounced side effect that wasn't in scope for this PR.

Gating the workbench branch on runWorkbenchCommand keeps the Shift+Enter normalization Windows-wide while leaving non–VS-Code hosts otherwise untouched:

if (shouldSendLfForShiftEnter(event, { isWindows: IS_WINDOWS })) {
  event.preventDefault();
  event.stopPropagation();
  handleTerminalInput(id, terminal, SHIFT_ENTER_NEWLINE_INPUT);
  return false;
}
const runWorkbench = getPlatform().runWorkbenchCommand;
if (!runWorkbench) return true;
const command = vscodeWorkbenchCommandForKeydown(event, { isMac: IS_MAC });
if (!command) return true;
event.preventDefault();
event.stopPropagation();
runWorkbench(command);
return true;

@nedtwigg
Copy link
Copy Markdown
Member Author

@dormouse-bot please push a fix to this branch

@nedtwigg nedtwigg force-pushed the shift-enter-windows-codex branch from 9acc44e to c0b53d7 Compare May 29, 2026 02:26
@dormouse-bot
Copy link
Copy Markdown
Collaborator

Pushed db88304 addressing both review points.

  • terminal-registry.alert.test.ts now mocks IS_WINDOWS: true so the Shift+Enter handler attaches on Linux CI (the gate in terminal-lifecycle.ts reads IS_WINDOWS once at module load).
  • terminal-lifecycle.ts gates the workbench branch on runWorkbenchCommand being defined, so non-VS-Code Windows hosts no longer swallow browser defaults for F1/Ctrl+P/Ctrl+Shift+P/Ctrl+B. Shift+Enter normalization still runs Windows-wide.

Verified: pnpm --filter dormouse-lib exec vitest run src/lib/terminal-keyboard.test.ts src/lib/terminal-registry.alert.test.ts (54 passed) and pnpm --filter dormouse-lib build.

@nedtwigg nedtwigg changed the title Send LF for Windows Shift+Enter Handle Windows Shift+Enter newlines May 29, 2026
@nedtwigg nedtwigg force-pushed the shift-enter-windows-codex branch from db88304 to e9e1a6d Compare May 29, 2026 02:37
Copy link
Copy Markdown
Collaborator

@dormouse-bot dormouse-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing as a draft — flagging anything that looks worth a quick fix. Mark ready for a full review.

The two concerns from my previous review are addressed: the Linux CI test now mocks IS_WINDOWS: true, and the workbench-chord branch is gated on runWorkbenchCommand so non–VS-Code Windows hosts no longer suppress browser defaults for F1 / Ctrl+P / etc.

Two new things on the Try bracketed paste commit, both inline.

Comment thread lib/src/lib/terminal-keyboard.ts Outdated
Comment thread lib/src/lib/terminal-keyboard.ts
@nedtwigg
Copy link
Copy Markdown
Member Author

Wrong track

@nedtwigg nedtwigg closed this May 29, 2026
@nedtwigg nedtwigg deleted the shift-enter-windows-codex branch May 29, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants