Skip to content

Commit 103888f

Browse files
committed
fix: use codepoint count for std.format width padding
Motivation: `std.format("%5s", "😀")` produced 3 spaces + emoji because width was computed using String.length (UTF-16 code units), counting the surrogate pair as 2. go-jsonnet and Python both count codepoints, yielding 4 spaces. Modification: Replace `.length` with `.codePointCount(0, _.length)` in the `widen` function's missingWidth calculation. This is consistent with the precision truncation in the same file which already uses codePointCount. Result: Width padding now counts supplementary characters as 1 codepoint, matching go-jsonnet and Python behavior. ASCII-only strings (the common case) are unaffected since codePointCount == length for BMP text.
1 parent 16e868e commit 103888f

3 files changed

Lines changed: 24 additions & 1 deletion

File tree

sjsonnet/src/sjsonnet/Format.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,10 @@ object Format {
286286
else if (signedConversion && formatted.signCharacter) "+" + lhs
287287
else lhs
288288

289-
val missingWidth = formatted.widthOr(-1) - lhs2.length - mhs.length - rhs.length
289+
val missingWidth = formatted.widthOr(-1) -
290+
lhs2.codePointCount(0, lhs2.length) -
291+
mhs.codePointCount(0, mhs.length) -
292+
rhs.codePointCount(0, rhs.length)
290293

291294
if (missingWidth <= 0) {
292295
// Avoid unnecessary string concatenation when parts are empty
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Width padding must count codepoints, not UTF-16 code units.
2+
// Supplementary characters (surrogate pairs) count as 1 codepoint.
3+
[
4+
std.assertEqual("%5s" % "😀", " 😀"),
5+
std.assertEqual("%-5s" % "😀", "😀 "),
6+
std.assertEqual("%5s" % "a😀b", " a😀b"),
7+
std.assertEqual("%3s" % "😀😀", " 😀😀"),
8+
std.assertEqual("%5.1s" % "😀x", " 😀"),
9+
std.assertEqual("%5s" % "hello", "hello"),
10+
std.assertEqual("%10s" % "hello", " hello"),
11+
]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[
2+
true,
3+
true,
4+
true,
5+
true,
6+
true,
7+
true,
8+
true
9+
]

0 commit comments

Comments
 (0)