@@ -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