fix(tui): preserve summarized paste order with wide text#25855
fix(tui): preserve summarized paste order with wide text#25855zclllyybb wants to merge 1 commit intoanomalyco:devfrom
Conversation
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
OpenTUI extmark ranges are display-width offsets, but the prompt submit path used them directly as JavaScript string indices when replacing virtual paste summaries with the original pasted text. If the prompt before a [Pasted ~N lines] marker contained wide characters such as Chinese, the replacement range was shifted and the submitted prompt could splice the pasted content into the wrong position. Convert display offsets to string indices before expanding text parts, fall back to the virtual marker text when extmark offsets were adjusted using string length semantics, and size virtual extmark ranges with Bun.stringWidth. Add regression coverage for Chinese text, newlines, multiple paste summaries, and shifted extmarks.
There was a problem hiding this comment.
Pull request overview
Fixes a TUI prompt submission bug where OpenTUI extmark ranges (display-width offsets) were incorrectly treated as JavaScript string indices when expanding paste summaries, causing pasted content to be spliced into the wrong position when wide characters (e.g., Chinese) appear earlier in the prompt.
Changes:
- Add display-offset ↔ string-index conversion utilities and a robust “virtual marker range” resolver for paste summary expansion.
- Update prompt submission to expand pasted text via the new helper (instead of slicing by raw extmark offsets).
- Correct extmark sizing for virtual paste/file markers using
Bun.stringWidth, and add regression tests covering wide text, newlines, multiple paste summaries, and shifted extmarks.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/opencode/src/cli/cmd/tui/component/prompt/paste.ts | New helper to map display offsets to string indices and expand paste-summary parts safely. |
| packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx | Use the new expansion helper on submit; size virtual extmarks using display width. |
| packages/opencode/test/cli/cmd/tui/prompt-paste.test.ts | Regression tests for wide characters/newlines/multiple summaries and extmark drift fallback. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- anomalyco/opencode#25959 keep-alive newlines on POST /session/:id/message [merge-after-nits] - anomalyco/opencode#25855 wide-text paste-summary order fix via Intl.Segmenter [merge-after-nits] - openai/codex#21290 extract codex-file-watcher crate from core [merge-after-nits] - openai/codex#21272 add 'compact' SessionStartSource with FIFO queue [merge-after-nits]
|
@kitlangton @thdxr @rekram1-node Sorry to bother, but I believe this is a real correctness issue affecting many users. Can someone help to move this PR forward? |
Issue for this PR
Closes #25854
Type of change
What does this PR do?
OpenTUI extmark ranges are display-width offsets, but the prompt submit path used them directly as JavaScript string indices when replacing virtual paste summaries with the original pasted text. If the prompt before a [Pasted ~N lines] marker contained wide characters such as Chinese, the replacement range was shifted and the submitted prompt could splice the pasted content into the wrong position.
Convert display offsets to string indices before expanding text parts, fall back to the virtual marker text when extmark offsets were adjusted using string length semantics, and size virtual extmark ranges with Bun.stringWidth. Add regression coverage for Chinese text, newlines, multiple paste summaries, and shifted extmarks.
How did you verify your code works?
I added a testcase in
packages/opencode/test/cli/cmd/tui/prompt-paste.test.ts. And I have performed e2e testing locally, the following screenshots can prove the repair results.Screenshots / recordings
when I actually enter:
with the pasted line:
before fix:

after fix:

Checklist