Skip to content

fix: cluster base + U+FE0F as a width-2 emoji glyph#84

Draft
natemoo-re wants to merge 3 commits into
mainfrom
nm/repro/vs16-emoji-width
Draft

fix: cluster base + U+FE0F as a width-2 emoji glyph#84
natemoo-re wants to merge 3 commits into
mainfrom
nm/repro/vs16-emoji-width

Conversation

@natemoo-re
Copy link
Copy Markdown
Member

@natemoo-re natemoo-re commented Jun 5, 2026

  • Fixes 🐛 VS16 (U+FE0F) emoji measured at the wrong width #81
  • measure() and render_text() summed per-codepoint widths with no grapheme awareness, so a base codepoint followed by U+FE0F (variation selector-16) measured as base-width + 0 instead of one width-2 emoji cluster
  • Both loops gain a one-codepoint lookahead: when the next codepoint is U+FE0F, the pair is treated as a single width-2 cluster — only the base glyph is placed and both codepoints are consumed; the wcwidth table is untouched
  • The repro's third assertion (a bordered fit() box rendering ┌──────┐) was rescoped to the render path. It depended on a separate, pre-existing bug: a fit() box's border does not reserve layout space, so even 6-wide ASCII content renders ┌────┐. That behavior is independent of this fix and tracked separately (it conflicts with the committed border-overlay model and its tests)
  • The regression lives in test/width.test.ts under describe("emoji width") rather than a standalone file. fix: collapse orphaned wide-char lead on trailing-column overlay #86 also adds to test/width.test.ts (describe("wide characters")), so whichever merges second needs a trivial rebase to keep both describes
  • Test plan: deno test green (8 passed / 148 steps); deno lint + deno fmt --check clean

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 5, 2026

Size Increased — +0.2 KB

107.6 KB unpacked

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Jun 5, 2026

Open in StackBlitz

npm i https://pkg.pr.new/clayterm@84

commit: 580d6f5

measure() and render_text() summed per-codepoint widths with no
grapheme awareness, so a base codepoint followed by U+FE0F (variation
selector-16) measured as base-width + 0 instead of one width-2 emoji
cluster. Add a one-codepoint lookahead to both loops: when the next
codepoint is U+FE0F, treat the pair as a single width-2 cluster, place
only the base glyph, and consume both. The wcwidth table is untouched.

The repro's bordered-fit assertion was rescoped to the render path;
the separate "fit() border does not reserve layout space" behavior is
tracked in its own issue.

Fixes #81
@natemoo-re natemoo-re force-pushed the nm/repro/vs16-emoji-width branch from 748a88e to c164d29 Compare June 5, 2026 06:14
@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented Jun 5, 2026

Merging this PR will degrade performance by 54.45%

❌ 1 regressed benchmark
✅ 22 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation long input burst (200 bytes) 576.1 µs 1,264.9 µs -54.45%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing nm/repro/vs16-emoji-width (580d6f5) with main (48ff4bb)

Open in CodSpeed

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.

🐛 VS16 (U+FE0F) emoji measured at the wrong width

1 participant