From d20dd645d25297a80f3438719c2c9363b0e3034d Mon Sep 17 00:00:00 2001 From: Lars Kappert Date: Sat, 21 Jun 2025 19:39:58 +0200 Subject: [PATCH] Add support for "surrogate pairs" in unmatched characters # Conflicts: # src/index.ts # test/index.js --- src/index.ts | 14 +++++--------- test/index.js | 12 ++++++++++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index fa3304f..9c4d2e1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -52,8 +52,6 @@ const getStringTruncatedWidth = ( input: string, truncationOptions: TruncationOp let truncationEnabled = false; let truncationIndex = length; let truncationLimit = Math.max ( 0, LIMIT - ELLIPSIS_WIDTH ); - let unmatchedStart = 0; - let unmatchedEnd = 0; let width = 0; let widthExtra = 0; @@ -64,9 +62,9 @@ const getStringTruncatedWidth = ( input: string, truncationOptions: TruncationOp /* UNMATCHED */ - if ( ( unmatchedEnd > unmatchedStart ) || ( index >= length && index > indexPrev ) ) { + if ( index > indexPrev ) { - const unmatched = input.slice ( unmatchedStart, unmatchedEnd ) || input.slice ( indexPrev, index ); + const unmatched = input.slice ( indexPrev, index ); lengthExtra = 0; @@ -83,7 +81,7 @@ const getStringTruncatedWidth = ( input: string, truncationOptions: TruncationOp } if ( ( width + widthExtra ) > truncationLimit ) { - truncationIndex = Math.min ( truncationIndex, Math.max ( unmatchedStart, indexPrev ) + lengthExtra ); + truncationIndex = Math.min ( truncationIndex, indexPrev + lengthExtra ); } if ( ( width + widthExtra ) > LIMIT ) { @@ -96,7 +94,7 @@ const getStringTruncatedWidth = ( input: string, truncationOptions: TruncationOp } - unmatchedStart = unmatchedEnd = 0; + indexPrev = index; } @@ -129,8 +127,6 @@ const getStringTruncatedWidth = ( input: string, truncationOptions: TruncationOp } width += widthExtra; - unmatchedStart = indexPrev; - unmatchedEnd = index; index = indexPrev = BLOCK_RE.lastIndex; continue outer; @@ -141,7 +137,7 @@ const getStringTruncatedWidth = ( input: string, truncationOptions: TruncationOp /* UNMATCHED INDEX */ - index += 1; + index += ( input.codePointAt(index) || 0 ) > 0xffff ? 2 : 1; } diff --git a/test/index.js b/test/index.js index a09d84f..f09f770 100644 --- a/test/index.js +++ b/test/index.js @@ -296,6 +296,18 @@ describe ( 'Fast String Width', () => { }); + it( 'supports "surrogate pairs" in unmatched characters', (t) => { + + t.is(getTruncated("██ █", { limit: 4 }), "██ █"); + t.is(getTruncated("██ █", { limit: 3 }), "██ "); + t.is(getTruncated("██ █", { limit: 2 }), "██"); + + t.is(getTruncated("██ █", { limit: 4, ellipsis: "…" }), "██ █"); + t.is(getTruncated("██ █", { limit: 3, ellipsis: "…" }), "██…"); + t.is(getTruncated("██ █", { limit: 2, ellipsis: "…" }), "█…"); + + }); + }); });