fix: keep position: 'middle' within the column budget - #32
Conversation
With `position: 'middle'`, the budget was split with
`Math.floor(columns / 2)` without reserving room for the truncation
character. When the character did not fit in the remaining space (most
visibly with `space: true`, where it becomes ` … `, width 3), the right
slice clamped to empty while the left slice plus the character already
exceeded `columns`:
cliTruncate('unicorns', 2, {position: 'middle', space: true})
// 'u … ' width 4, over the budget of 2
Cap the left slice at `columns - truncationWidth` so the two slices plus
the character never exceed `columns`, and drop the padding spaces when the
padded character itself would not fit. Normal widths are unchanged
(`columns: 7` still yields `uni … s`); verified width <= columns across
ASCII and wide-character text for every position and `space` setting.
|
I found one case this still misses: the new width reservation does not cover the cliTruncate('unicorns', 4, {position: 'middle', space: true, preferTruncationOnSpace: true});
//=> 'u … ns' // width 6, budget 4That branch still seems to use a hard-coded |
The `position: 'middle'` + `preferTruncationOnSpace` branch computed the
right-hand break point with a hard-coded `+ 1`, so with `space: true`
(truncation character ` … `, width 3) the result could exceed `columns`,
e.g. `cliTruncate('unicorns', 4, {position: 'middle', space: true,
preferTruncationOnSpace: true})` returned `'u … ns'` (width 6).
Use the actual `truncationWidth`, matching the non-prefer branch.
`getIndexOfNearestSpace` only searches rightward here, so it can shorten
the slice but never extend it past the budget. Added a regression test for
the option combo.
|
Good catch, thanks. Fixed: the prefer-on-space |
With
position: 'middle', the budget is split withMath.floor(columns / 2)without reserving room for the truncation character. When the character does not fit in the remaining space (most visibly withspace: true, where it becomes…, width 3), the right slice clamps to empty while the left slice plus the character already exceedcolumns:This breaks the documented invariant that the result occupies at most
columnscolumns (position: 'end'/'start'stay within budget at the same widths).The fix caps the left slice at
columns - truncationWidth, so the two slices plus the truncation character never exceedcolumns, and drops the padding spaces when the padded character itself would not fit (so some text can still be shown). Normal widths are unchanged —columns: 7still yieldsuni … s. Verifiedwidth <= columnsacross ASCII and wide-character text for every position andspacesetting (264 combinations); existing wide-char test (issue #28) still passes. Added regression assertions.