text: hopefuly fix the handling of chinese

Michael Muré created

Change summary

util/text/text.go      | 17 ++++++++++-------
util/text/text_test.go | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 7 deletions(-)

Detailed changes

util/text/text.go 🔗

@@ -98,6 +98,7 @@ func WrapLeftPadded(text string, lineWidth int, leftPad int) (string, int) {
 	return textBuffer.String(), nbLine
 }
 
+// wordLen return the length of a word, while ignoring the terminal escape sequences
 func wordLen(word string) int {
 	length := 0
 	escape := false
@@ -119,8 +120,10 @@ func wordLen(word string) int {
 	return length
 }
 
+// splitWord split a word at the given length, while ignoring the terminal escape sequences
 func splitWord(word string, length int) (string, string) {
-	result := ""
+	runes := []rune(word)
+	var result []rune
 	added := 0
 	escape := false
 
@@ -128,12 +131,12 @@ func splitWord(word string, length int) (string, string) {
 		return "", word
 	}
 
-	for _, char := range word {
-		if char == '\x1b' {
+	for _, r := range runes {
+		if r == '\x1b' {
 			escape = true
 		}
 
-		result += string(char)
+		result = append(result, r)
 
 		if !escape {
 			added++
@@ -142,14 +145,14 @@ func splitWord(word string, length int) (string, string) {
 			}
 		}
 
-		if char == 'm' {
+		if r == 'm' {
 			escape = false
 		}
 	}
 
-	leftover := word[len(result):]
+	leftover := runes[len(result):]
 
-	return result, leftover
+	return string(result), string(leftover)
 }
 
 func minInt(a, b int) int {

util/text/text_test.go 🔗

@@ -89,6 +89,18 @@ func TestWrap(t *testing.T) {
 			" This\nis a\nlist:\n\n\n    *\nfoo\n    *\nbar\n\n\n    *\nbaz\nBAM\n",
 			6,
 		},
+		// Handle chinese
+		{
+			"婞一枳郲逴靲屮蜧曀殳,掫乇峔掮傎溒兀緉冘仜。",
+			"婞一枳郲逴靲屮蜧曀殳,掫\n乇峔掮傎溒兀緉冘仜。",
+			12,
+		},
+		// Handle chinese with colors
+		{
+			"婞一枳郲逴\x1b[31m靲屮蜧曀殳,掫乇峔掮傎溒\x1b[0m兀緉冘仜。",
+			"婞一枳郲逴\x1b[31m靲屮蜧曀殳,掫\n乇峔掮傎溒\x1b[0m兀緉冘仜。",
+			12,
+		},
 	}
 
 	for i, tc := range cases {
@@ -126,6 +138,16 @@ func TestWordLen(t *testing.T) {
 			"foo\x1b[31mfoobarHoy\x1b[0mbaaar",
 			17,
 		},
+		// Handle chinese
+		{
+			"快檢什麼望對",
+			6,
+		},
+		// Handle chinese with colors
+		{
+			"快\x1b[31m檢什麼\x1b[0m望對",
+			6,
+		},
 	}
 
 	for i, tc := range cases {
@@ -179,6 +201,18 @@ func TestSplitWord(t *testing.T) {
 			0,
 			"", "foo",
 		},
+		// Handle chinese
+		{
+			"快檢什麼望對",
+			2,
+			"快檢", "什麼望對",
+		},
+		// Handle chinese with colors
+		{
+			"快\x1b[31m檢什麼\x1b[0m望對",
+			2,
+			"快\x1b[31m檢", "什麼\x1b[0m望對",
+		},
 	}
 
 	for i, tc := range cases {