@@ -19,7 +19,7 @@ func IsLikelyEllipsisLeftPart(s string) bool {
1919 return strings .HasSuffix (s , utf8Ellipsis ) || strings .HasSuffix (s , asciiEllipsis )
2020}
2121
22- func ellipsisGuessDisplayWidth (r rune ) int {
22+ func ellipsisDisplayGuessWidth (r rune ) int {
2323 // To make the truncated string as long as possible,
2424 // CJK/emoji chars are considered as 2-ASCII width but not 3-4 bytes width.
2525 // Here we only make the best guess (better than counting them in bytes),
@@ -48,13 +48,17 @@ func ellipsisGuessDisplayWidth(r rune) int {
4848// It appends "…" or "..." at the end of truncated string.
4949// It guarantees the length of the returned runes doesn't exceed the limit.
5050func EllipsisDisplayString (str string , limit int ) string {
51- s , _ , _ , _ := ellipsisDisplayString (str , limit )
51+ s , _ , _ , _ := ellipsisDisplayString (str , limit , ellipsisDisplayGuessWidth )
5252 return s
5353}
5454
5555// EllipsisDisplayStringX works like EllipsisDisplayString while it also returns the right part
5656func EllipsisDisplayStringX (str string , limit int ) (left , right string ) {
57- left , offset , truncated , encounterInvalid := ellipsisDisplayString (str , limit )
57+ return ellipsisDisplayStringX (str , limit , ellipsisDisplayGuessWidth )
58+ }
59+
60+ func ellipsisDisplayStringX (str string , limit int , widthGuess func (rune ) int ) (left , right string ) {
61+ left , offset , truncated , encounterInvalid := ellipsisDisplayString (str , limit , widthGuess )
5862 if truncated {
5963 right = str [offset :]
6064 r , _ := utf8 .DecodeRune (UnsafeStringToBytes (right ))
@@ -68,7 +72,7 @@ func EllipsisDisplayStringX(str string, limit int) (left, right string) {
6872 return left , right
6973}
7074
71- func ellipsisDisplayString (str string , limit int ) (res string , offset int , truncated , encounterInvalid bool ) {
75+ func ellipsisDisplayString (str string , limit int , widthGuess func ( rune ) int ) (res string , offset int , truncated , encounterInvalid bool ) {
7276 if len (str ) <= limit {
7377 return str , len (str ), false , false
7478 }
@@ -81,7 +85,7 @@ func ellipsisDisplayString(str string, limit int) (res string, offset int, trunc
8185 for i , r := range str {
8286 encounterInvalid = encounterInvalid || r == utf8 .RuneError
8387 pos = i
84- runeWidth := ellipsisGuessDisplayWidth (r )
88+ runeWidth := widthGuess (r )
8589 if used + runeWidth + 3 > limit {
8690 break
8791 }
@@ -96,7 +100,7 @@ func ellipsisDisplayString(str string, limit int) (res string, offset int, trunc
96100 if nextCnt >= 4 {
97101 break
98102 }
99- nextWidth += ellipsisGuessDisplayWidth (r )
103+ nextWidth += widthGuess (r )
100104 nextCnt ++
101105 }
102106 if nextCnt <= 3 && used + nextWidth <= limit {
@@ -114,6 +118,10 @@ func ellipsisDisplayString(str string, limit int) (res string, offset int, trunc
114118 return str [:offset ] + ellipsis , offset , true , encounterInvalid
115119}
116120
121+ func EllipsisTruncateRunes (str string , limit int ) (left , right string ) {
122+ return ellipsisDisplayStringX (str , limit , func (r rune ) int { return 1 })
123+ }
124+
117125// TruncateRunes returns a truncated string with given rune limit,
118126// it returns input string if its rune length doesn't exceed the limit.
119127func TruncateRunes (str string , limit int ) string {
0 commit comments