Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

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

Open
#81 0 comments 0 reactions 1 assignee View on GitHub

@natemoo-re is already working on this.

Since Jun 7, 2026.

Assessment

This issue has not been assessed yet.

Description

bug
  • Package: clayterm
  • Version: v0.6.0 (reproduced on main @ d75fb4b)
  • Runtime: Deno 2.x
  • OS: platform-independent (WASM); reproduced on macOS

Describe the bug

We measure text width by summing per-codepoint widths with no grapheme-cluster awareness, so a base character followed by U+FE0F (variation selector-16) is mis-measured—the base keeps its text-presentation width and FE0F adds 0, instead of the pair clustering into one width-2 emoji glyph. 🌡️⚠️✅ measures 1+0+1+0+2 = 4 columns instead of 6, and a lone ⚠️ measures 1 instead of 2. Plain CJK (你好你 => 6) and already-emoji-presentation bases (🌊🌊 => 4) are correct, so the gap is specifically base + FE0F.

To Reproduce

A base codepoint immediately followed by U+FE0F should be a single width-2 cluster. The lone ⚠️ box reports bounds.width 1 (want 2), the 🌡️⚠️✅ fit box reports 4 (want 6), and a fit-bordered box prints ┌──┐ instead of ┌──────┐.

Expected behavior

FE0F promotes its base to width-2 emoji presentation instead of collapsing to 0. 🌡️⚠️✅ is 2+2+2 = 6, and a fit-bordered box around it is 8 cells wide (6 content + 2 border) with a top border of ┌──────┐.

Additional Information

Failing test case on nm/repro/vs16-emoji-width (test · diff).

The width table is fine; the gap is in the measurement loops. measure() (src/clayterm.c:677) does w += wcwidth(cp) with no lookahead (src/clayterm.c:693-695), and wcwidth() (src/wcwidth.c:1095) maps U+FE0F to 0 (src/wcwidth.c:547) by design; render_text() (src/clayterm.c:269) has the same per-codepoint loop (src/clayterm.c:288). The fix likely lives in those two loops as a one-codepoint lookahead—when the next codepoint is U+FE0F, treat base + FE0F as a single width-2 cluster and consume both, leaving the table and wcwidth() untouched.

Dominant language
TypeScript
Stars
42
Forks
2
Avg merge
2d 5h
Merged PRs (30d)
12

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from bombshell-dev/tty

All issues in bombshell-dev/tty

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.