Skip to content

core: delete a virtual extmark whole when a range cuts into it - #1628

Closed
Nowaker wants to merge 1 commit into
anomalyco:mainfrom
Nowaker:atomic-virtual-extmarks
Closed

Nowaker wants to merge 1 commit into
anomalyco:mainfrom
Nowaker:atomic-virtual-extmarks

Conversation

@Nowaker

@Nowaker Nowaker commented Oct 11, 2026

Copy link
Copy Markdown

A virtual extmark already behaves as one unit for backspace, delete and cursor movement, but deleteRange treated it as plain text. A word or line delete whose boundary falls inside one removed only that part: in opencode, ctrl+w right after a [Pasted ~5 lines] placeholder leaves [Pasted ~5 behind, with the extmark trimmed to match, and ctrl+u / ctrl+k do the same when the line edge cuts into one. deleteWordBackward, deleteWordForward, deleteToLineStart and deleteToLineEnd all delete through deleteRange.

deleteRange now widens the range to cover every virtual extmark it cuts into, adjacent ones included, before it deletes. Non-virtual extmarks are trimmed as before, and undo restores the whole extmark.

Tests in extmarks.test.ts cover word deletes in both directions, a range ending inside an extmark, two adjacent extmarks, a non-virtual extmark still being trimmed, and undo. The four new cases for virtual extmarks fail without the change. The extmark, edit buffer and textarea suites pass (828 tests), and fmt:check and typecheck are clean.

This PR is AI generated, but under direct supervision and on request of @Nowaker.

A virtual extmark is meant to behave as one unit: backspace, delete and
cursor movement already treat it atomically. deleteRange did not, so a
word or line delete whose boundary fell inside one (ctrl+w right after
a "[Pasted ~5 lines]" placeholder, ctrl+u or ctrl+k across part of it)
removed only that part and left a fragment of the label behind, with
the extmark trimmed to match.

deleteRange now widens the range to cover every virtual extmark it cuts
into, adjacent ones included, before deleting. Non-virtual extmarks are
still trimmed as before, and undo restores the whole extmark.
Nowaker added a commit to Nowaker/opencode that referenced this pull request Oct 11, 2026
ctrl+w (or alt+backspace) right after a "[Pasted ~5 lines]" placeholder
deleted only the last word of its label, leaving "[Pasted ~5 " behind
with the pasted text detached from it; ctrl+u and ctrl+k did the same
when the line edge cut into a placeholder. Backspace and delete already
removed it whole.

The cause is in @opentui/core: its extmark controller's deleteRange,
which every word and line delete goes through, trimmed a virtual
extmark instead of treating it as one unit. The fix is upstream as
anomalyco/opentui#1628; patches/@OpenTui%[email protected] backports
it to the pinned 0.4.5 until a release with it is adopted. deleteRange
now widens its range over every virtual extmark it cuts into.

AI-Tool: opencode 1.18.34-vt-194-907b3bc518
AI-Model: anthropic/claude-opus-5-5
AI-Variant: high
AI-Platform: linux
AI-Harness: Vibeterm 9343cff
AI-Session-ID: ses_ed7634c31ffeH84yR0S99Ty8Nd
Nowaker added a commit to Nowaker/opencode that referenced this pull request Oct 11, 2026
ctrl+w (or alt+backspace) right after a "[Pasted ~5 lines]" placeholder
deleted only the last word of its label, leaving "[Pasted ~5 " behind
with the pasted text detached from it; ctrl+u and ctrl+k did the same
when the line edge cut into a placeholder. Backspace and delete already
removed it whole.

The cause is in @opentui/core: its extmark controller's deleteRange,
which every word and line delete goes through, trimmed a virtual
extmark instead of treating it as one unit. The fix is upstream as
anomalyco/opentui#1628; patches/@OpenTui%[email protected] backports
it to the pinned 0.4.5 until a release with it is adopted. deleteRange
now widens its range over every virtual extmark it cuts into.

AI-Tool: opencode 1.18.34-vt-194-907b3bc518
AI-Model: anthropic/claude-opus-5-5
AI-Variant: high
AI-Platform: linux
AI-Harness: Vibeterm 9343cff
AI-Session-ID: ses_ed7634c31ffeH84yR0S99Ty8Nd
@simonklee

Copy link
Copy Markdown
Member

Thanks. There are three PRs for this bug and none merges anymore, so we'll fix it ourselves and I'm closing this one.

@simonklee simonklee closed this Nov 10, 2026
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