Skip to content

Commit bcbdc86

Browse files
committed
fix(tables): measure columns by terminal cell width, not code units
`displayWidth` used `stripAnsi(text).length`, which counts UTF-16 code units instead of rendered terminal cells. Full-width CJK, emoji, and combined-code-point glyphs each reported width 1–2 code units even when the terminal renders them as 2 columns, and surrogate pairs (non-BMP emoji) were double-counted as 2 for a single glyph. Columns containing such values misaligned in both `formatSimpleTable` and `formatTable`. Routes the measurement through `stringWidth` (Intl.Segmenter + East Asian Width), which already strips ANSI and reports actual cell counts.
1 parent 6781565 commit bcbdc86

1 file changed

Lines changed: 6 additions & 5 deletions

File tree

src/tables.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import colors from './external/yoctocolors-cjs'
7-
import { stripAnsi } from './strings'
7+
import { stringWidth } from './strings'
88

99
export type ColumnAlignment = 'left' | 'right' | 'center'
1010

@@ -20,10 +20,12 @@ export type TableColumn = {
2020
}
2121

2222
/**
23-
* Calculate display width accounting for ANSI codes.
23+
* Calculate display width accounting for ANSI codes, CJK, and emoji.
24+
* Uses `stringWidth` so multi-cell glyphs (full-width CJK, emoji, combined
25+
* code points) contribute their actual terminal column count to padding.
2426
*/
2527
function displayWidth(text: string): number {
26-
return stripAnsi(text).length
28+
return stringWidth(text)
2729
}
2830

2931
/**
@@ -34,8 +36,7 @@ function padText(
3436
width: number,
3537
align: ColumnAlignment = 'left',
3638
): string {
37-
const stripped = stripAnsi(text)
38-
const textWidth = stripped.length
39+
const textWidth = displayWidth(text)
3940
const padding = Math.max(0, width - textWidth)
4041

4142
switch (align) {

0 commit comments

Comments
 (0)