Skip to content

fix(web): preserve shifted terminal input - #5277

Open
cedi wants to merge 1 commit into
pingdotgg:mainfrom
cedi:fix/terminal-shifted-printable-input
Open

fix(web): preserve shifted terminal input#5277
cedi wants to merge 1 commit into
pingdotgg:mainfrom
cedi:fix/terminal-shifted-printable-input

Conversation

@cedi

@cedi cedi commented Aug 3, 2026

Copy link
Copy Markdown

Problem

Fixes #5276

Neovim enables Kitty keyboard disambiguation when it starts in the built-in terminal. Pressing Shift+; should produce : and open the Neovim command line, but T3 Code encoded it as ESC[59;2u, so Neovim handled it as ; instead.

This appeared specific to Neovim because a regular shell uses the legacy keyboard path, where the browser-provided : text was already emitted correctly.

Root cause

The web Ghostty bridge passed 0 to ghostty_key_event_set_consumed_mods for every key event. That told the Kitty encoder that Shift was still an effective modifier even when the browser had already consumed Shift to translate the layout base character ; into :.

The encoder therefore emitted a modified unshifted codepoint instead of the translated printable text.

Fix

  • Derive the unshifted codepoint once from the active browser keyboard layout, retaining the existing US-layout fallback.
  • Mark Shift as consumed only when Shift is pressed, the event produced one Unicode codepoint, a valid unshifted codepoint exists, and the produced character differs from that base codepoint.
  • Pass that consumed-modifier mask and the same unshifted codepoint into the Ghostty WASM encoder.

This is deliberately a general shifted-printable fix rather than a colon special case. Shift remains effective for functional keys and for printable keys it does not transform, such as Shift+Space.

Behavior before and after

Input Before After
Shift+; in a normal shell : :
Shift+; after Neovim enables Kitty disambiguation ESC[59;2u and Neovim sees ; literal : and the command line opens
Shift+Space / Shift+Tab Shift remains distinguishable unchanged
Shifted printable keys on a non-US layout could be encoded as a modified base key browser-translated character is preserved

Scope and risk

  • Limited to browser-to-PTY key encoding in apps/web/src/terminal/ghostty.
  • Covers local web, hosted web, and desktop because they share this terminal implementation.
  • Does not change server or WebSocket contracts, terminal session state, mobile native input, or visual rendering.
  • Falls back to the prior behavior when the browser cannot provide a trustworthy unshifted codepoint.

Screenshots are not applicable because this has no visual UI change; the user-visible difference is the terminal byte sequence shown above.

Verification

  • cd apps/web && vp test run src/terminal/ghostty/keyCodes.test.ts src/terminal/ghostty/runtimeAbi.test.ts --project unit — 14 tests passed.
  • The helper tests cover shifted punctuation, shifted letters, a non-US layout map, Shift+Space, Shift+Tab, and unmodified text.
  • The pinned Ghostty WASM ABI test enables Kitty disambiguation with CSI > 1 u and verifies Shift+; emits exactly :.
  • Targeted vp lint passed for all four changed files.
  • vp run --filter @t3tools/web typecheck passed.

Implemented with GPT-5.6-sol via the Codex harness in T3 Code.


Note

Medium Risk
Changes only browser-to-PTY key encoding for the Ghostty web terminal; behavior shifts for Shift+printable keys under Kitty modes, with tests but limited surface area outside terminal input.

Overview
Fixes shifted printable input in the web Ghostty bridge when apps use Kitty keyboard disambiguation (e.g. Neovim in the built-in terminal). The bridge always sent zero consumed modifiers, so Shift+; was encoded like a modified ; instead of plain :.

Adds ghosttyConsumedMods, which marks Shift consumed when the pressed character differs from the layout-aware unshifted codepoint (reuses the same unshifted value already passed to the encoder). encodeKey in core.ts passes that value to ghostty_key_event_set_consumed_mods instead of 0. Shift stays visible for keys where it does not change the character (space, Tab, etc.).

Unit tests cover the helper; the vendored WASM ABI test asserts Shift+; encodes as : in Kitty mode.

Reviewed by Cursor Bugbot for commit a4ecfbc. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Fix shifted terminal input by marking Shift as a consumed modifier when it transforms a printable character

  • Adds ghosttyConsumedMods in keyCodes.ts to compute consumed modifier bits: returns the Shift bit when Shift produces a different printable character than the unshifted codepoint, otherwise returns 0.
  • Updates the key event handler in core.ts to pass the result of ghosttyConsumedMods to ghostty_key_event_set_consumed_mods instead of the previous hardcoded 0.
  • Behavioral Change: keys like : (Shift+Semicolon) now correctly report Shift as consumed, fixing shifted character input that was previously broken.

Macroscope summarized a4ecfbc.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 225e8543-bc86-4a04-8b3e-e740861ce699

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Aug 3, 2026
@macroscopeapp

macroscopeapp Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR changes runtime behavior for how shifted keyboard input is processed in the terminal, affecting modifier consumption logic. While the fix has good test coverage, terminal input handling changes can have subtle effects across keyboard layouts and warrant human review.

You can customize Macroscope's approvability policy. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Shifted punctuation is misencoded in Neovim terminal sessions

1 participant