Skip to content

fix(web): surround selected text with dead-key quotes - #21360

Open
Gustav0ar wants to merge 4 commits into
pingdotgg:mainfrom
Gustav0ar:fix/composer-dead-key-quotes
Open

Gustav0ar wants to merge 4 commits into
pingdotgg:mainfrom
Gustav0ar:fix/composer-dead-key-quotes

Conversation

@Gustav0ar

@Gustav0ar Gustav0ar commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

With US-International input, selecting word and pressing apostrophe then Space replaces the word with ' on Linux and macOS. This restores the existing selection-surround behavior for dead keys after https://git.cafe/pingdotgg/t3code/pulls/20350. Related: the maintainer's request to verify selection wrapping.

Keep eligible selected text in place while the dead key resolves, then surround it when a delimiter commits. Accented letters still replace the selection. Handle both native composition and Windows' direct text commits, preserve one-step undo, and discard stale selections.

Verification:

  • 32 focused browser tests pass across the input, navigation, and citation-draft tests. They cover preedit replacement, wrapping, accents, cancellation, undo/redo, and stale selections.
  • Web typecheck, targeted lint, and formatting pass. The shared web/desktop editor is covered in rich and plain modes; mobile uses a separate native input.
  • Native Electron 44.4.5: 16 cases pass per target across rich and plain modes on Windows, macOS, Linux X11, and native Linux Wayland. OS layout probes precede the composer tests. Selected words stay present throughout wrapping, with one-step undo and redo.
  • Linux automation uses Ubuntu 24.04 with Xvfb/Openbox for X11 and isolated Sway for Wayland. Wayland has XWayland disabled and no X11 display, and the test verifies an Electron xdg_shell surface. The reporter also verified the isolated desktop build on CachyOS/Wayland.

Reproduce the focused browser checks with:

cd apps/web
../../node_modules/.bin/vp test run --project browser src/components/ComposerPromptEditorTiptap.{input,navigation,citationDraft}.browser.test.tsx

macOS before the fix: apostrophe + Space replaces the selected word with '.

macOS before the fix: only an apostrophe remains

macos-before.mp4

macOS after the fix: apostrophe + Space produces 'word' and keeps word selected.

macOS after the fix: the selected word is surrounded by apostrophes

macos-after.mp4
Windows native verification

All 16 cases pass in rich and plain modes, including accents, selection wrapping, and undo/redo.

Windows after the fix: the selected word is surrounded by apostrophes

windows-after.mp4
Linux X11 and native Wayland verification

X11: all 16 native cases pass under Xvfb/Openbox.

Linux X11: the selected word remains surrounded by apostrophes

linux-x11-after.mp4

Native Wayland: all 16 cases pass under Sway, with XWayland disabled. The selected word remains in every recorded transaction and frame.

Native Linux Wayland: the selected word remains surrounded by apostrophes

linux-wayland-after.mp4

Passing Linux run, X11 environment and event traces, and Wayland environment, surface, and event traces.

The recordings include layout probes and native keyboard cases. Passing Windows and macOS native run, macOS event traces, and Windows event traces. The test code stays on the fork's test branch.

Implemented with GPT-6.1-sol in Codex.

main replaces selected word with an apostrophe

dead-key quote surrounds word and preserves its selection

Copilot AI balanced review requested due to automatic review settings October 18, 2026 23:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Oct 18, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This production editor fix adds substantial cross-platform composition and dead-key state handling, including asynchronous reconciliation and undo integration. Its focused tests reduce risk, but the new runtime state machine is complex enough to merit human review.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 18e33fb and 23f6098.

Files selected for processing: 2
  • apps/web/src/components/ComposerPromptEditorTiptap.input.browser.test.tsx
  • apps/web/src/components/ComposerPromptEditorTiptap.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

Walkthrough

The editor preserves eligible selections during dead-key input. It wraps selected text for paired characters or replaces the selection with committed text. It discards pending input when the captured editor state no longer matches. Browser tests cover composition, selection changes, cancellation, and undo and redo.

Changes: Dead-key input

Layer / File(s) Summary
Selection eligibility and pending state
apps/web/src/components/ComposerPromptEditorTiptap.tsx
The editor validates selections for wrapping and stores the selection, editor state, and composition transaction ID while dead-key input is pending.
Dead-key capture, resolution, and validation
apps/web/src/components/ComposerPromptEditorTiptap.tsx, apps/web/src/components/ComposerPromptEditorTiptap.input.browser.test.tsx
The editor handles dead-key input during composition and text input. Browser tests cover wrapping, replacement, cancellation, selection cases, and undo and redo.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant ComposerPromptEditorTiptap
  participant ProseMirror
  Browser->>ComposerPromptEditorTiptap: Send Dead or Process keydown
  ComposerPromptEditorTiptap->>ProseMirror: Save eligible selection and editor state
  Browser->>ComposerPromptEditorTiptap: Send composition or committed text
  ComposerPromptEditorTiptap->>ProseMirror: Wrap, replace, or restore selection
Loading

Suggested reviewers: juliusmarminge

Merge Risk: Minimal · up to 23f60

No confirmed issue blocks merging after normal checks.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary change: restoring dead-key quote surrounding for selected text.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed PASS. The description explains the problem and change, links the related issue and maintainer request, and provides detailed verification results, commands, platform coverage, and UI evidence. It does…
Full details: Description check

Explanation

PASS. The description explains the problem and change, links the related issue and maintainer request, and provides detailed verification results, commands, platform coverage, and UI evidence. It does not use the template headings for Problem, Change, or Scope and approval, but the required information is present.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

maria-rcks commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

thanks @Gustav0ar. your latest implementation preserves the selection through native composition, supports direct Windows commits, and groups the result with undo. i kept that implementation and both of your commits.

i merged current main, resolved the editor conflicts while preserving main's callback and history fixes, and migrated your tests to the current disposable render and timer setup. removed an unused editor ref. the diff against main remains limited to the editor and its existing input test file.

verification on 23f609877fa5eebe5cb88c9614c9da2f65bc9284:

  • reproduced on main: selected word becomes ', in both a failing browser test and the real app.
  • blacksmith vp run check:changed passes format, lint, knip, affected typechecks, and 31 browser tests. rich/plain composition, accents, cancellation, stale selections, chips, and undo are covered.
  • system chrome in the real app: apostrophe and double-quote composition surround word; accented é replaces it; undo/redo and the narrow composer pass. ordinary bracket behavior matches main.
  • all 28 head checks are green, with no conflicts.
  • two independent editor reviews found no issues on this head.
  • unverified here: native macOS, Windows, X11, and Wayland keyboard layouts, and the Electron shell. chrome composition was driven through CDP, not an OS layout. mobile uses a separate native input.

before on main:

main replaces selected word with an apostrophe

main dead-key composition recording

after on this head:

dead-key quote surrounds word and preserves its selection

dead-key composition with one-step undo and redo

recording playback and seeking were checked directly in chrome; git.cafe displays the external video embeds as links.

@Gustav0ar

Copy link
Copy Markdown
Contributor Author

Thanks @maria-rcks , pls let me know what is missing for approval

This branch has not been deployed

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

Labels

size:L 100-499 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.

3 participants