mirror of
https://github.com/anomalyco/opentui.git
synced 2026-04-25 04:55:58 +03:00
[PR #751] feat(core): expose no_zwj as opt-in WidthMethod #756
Labels
No labels
bug
core
documentation
feature
good first issue
help wanted
pull-request
question
react
solid
tmux
windows
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/opentui#756
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/anomalyco/opentui/pull/751
Author: @Flare576
Created: 2/27/2026
Status: 🔄 Open
Base:
main← Head:feat/no-zwj-width-method📝 Commits (1)
47cc0c2feat(core): expose no_zwj as opt-in WidthMethod option📊 Changes
4 files changed (+11 additions, -11 deletions)
View changed files
📝
packages/core/src/renderer.ts(+1 -1)📝
packages/core/src/types.ts(+1 -1)📝
packages/core/src/zig.ts(+4 -4)📝
packages/core/src/zig/lib.zig(+5 -5)📄 Description
Problem
ZWJ emoji sequences (👩🚀 👨👩👧 🏳️🌈) cause layout corruption in terminals that don't render them as joined glyphs — most notably tmux, but also many older terminals. Text after a ZWJ sequence shifts across the screen, wraps incorrectly, and input box spacing breaks.
The
no_zwjwidth calculation mode already exists in the Zig layer, is fully implemented, and has comprehensive test coverage (utf8_no_zwj_test.zig). The environment variableOPENTUI_FORCE_NOZWJis already registered and wired throughterminal.zig. However,no_zwjis missing from the TypeScriptWidthMethodunion type and from the numeric mapping at the FFI boundary, making it completely unreachable from JavaScript consumers.Solution
Wire
no_zwjthrough the full TypeScript→FFI chain without changing any defaults:packages/core/src/types.ts: Add"no_zwj"to theWidthMethodunionpackages/core/src/zig.ts: Map"no_zwj"→2in the fourwidthMethodCodeconversions (previously only0/1existed)packages/core/src/zig/lib.zig: Mapu8value2→.no_zwjin the four FFI entry points; map.no_zwj→2ingetTerminalCapabilitiesserializationpackages/core/src/renderer.ts: Update thewidthMethodgetter to return"no_zwj"when capabilities report2(e.g. viaOPENTUI_FORCE_NOZWJ)Behavior
unicode(default, unchanged)no_zwj(opt-in)Only ZWJ-joined sequences are affected. Skin tone modifiers, regional indicator flags, combining accents, and CJK characters are all unaffected.
No Breaking Changes
"unicode"everywhere"wcwidth"behavior is unchangedOPENTUI_FORCE_NOZWJenv var now correctly round-trips throughgetTerminalCapabilities→widthMethodgetter"wcwidth"or"unicode"see identical behaviorRelated
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.