Skip to content

fix: pad description box rows by display width - #478

Open
NoirVoider wants to merge 1 commit into
microsoft:mainfrom
NoirVoider:fix-description-box-wide-chars
Open

NoirVoider wants to merge 1 commit into
microsoft:mainfrom
NoirVoider:fix-description-box-wide-chars

Conversation

@NoirVoider

Copy link
Copy Markdown

Description

truncateMultilineText() padded each wrapped row with String#padEnd, which counts UTF-16 code units, while renderBox() draws the description box border assuming the row occupies exactly width terminal columns. Descriptions containing characters whose display width differs from their code-unit length (CJK, BMP-wide emoji such as U+2B50, ZWJ emoji sequences) therefore produced a misaligned right border.

This reuses the display-width helper that already exists in the same file and is already used by truncateText(), so both boxes pad by display width. ASCII descriptions are unaffected (wcswidth(text) === text.length).

Fixes #477

Before / after (width = 28, i.e. descriptionWidth - borderWidth)

sample code units display cells before (padEnd) after (wcPadEnd)
Run OpenCode with a message 27 27 28 ✓ 28 ✓
以一条消息运行 OpenCode 16 23 35 28 ✓
⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ (U+2B50) 10 20 38 28 ✓
🚀🚀🚀🚀🚀🚀🚀🚀 (U+1F680) 16 16 28 ✓ 28 ✓
👨‍👩‍👧👨‍👩‍👧👨‍👩‍👧 24 18 22 28 ✓

Tests

Added a truncateMultilineText suite to src/tests/utils/ui.test.ts:

  • ASCII rows keep the previous padding (regression guard)
  • CJK / BMP emoji / astral emoji / ZWJ rows are padded to the requested display width
  • renderBox(truncateMultilineText(...), width + 2) lines are exactly width + 2 columns
  • maxHeight truncation still marks the last line with

3 of the new assertions fail on main, pass with the fix:

✕ pads wide characters by display width, not by code units
✕ pads emoji by display width
✕ keeps box borders aligned for wide characters
Tests: 3 failed, 7 passed, 10 total

Full suite with the fix:

Test Suites: 1 skipped, 14 passed, 14 of 15 total
Tests:       10 skipped, 208 passed, 218 total
Snapshots:   93 passed, 93 total

truncateMultilineText() padded each wrapped row with String#padEnd,
which counts UTF-16 code units, while renderBox() draws the border
assuming the row occupies exactly `width` terminal columns. Any
description whose display width differs from its code-unit length
(CJK text, BMP-wide emoji such as U+2B50, ZWJ emoji sequences) produced
a misaligned right border; ZWJ sequences pulled it inwards.

Reuse the existing display-width helper (wcPadEnd/wcswidth) so the
description box matches truncateText(), which already pads by width.
@NoirVoider

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

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.

description box: right border is offset for CJK / wide characters (padded by code units, not display width)

1 participant