Skip to content

Commit 2e820a2

Browse files
committed
Upgraded to latest rivo/uniseg. Also implemented basic emoji handling in StringWidth. See #59
1 parent a8413cf commit 2e820a2

File tree

8 files changed

+31
-18
lines changed

8 files changed

+31
-18
lines changed

.github/workflows/test.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
strategy:
1212
matrix:
1313
os: [windows-latest, macos-latest, ubuntu-latest]
14-
go: ["1.15", "1.16"]
14+
go: ["1.18.x", "1.19.x"]
1515
runs-on: ${{ matrix.os }}
1616
steps:
1717
- uses: actions/checkout@v2

benchmark_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,21 +113,19 @@ func benchString1Width(b *testing.B, eastAsianWidth bool, start, stop rune, want
113113
return n
114114
}
115115
func BenchmarkString1WidthAll(b *testing.B) {
116-
benchSink = benchString1Width(b, false, 0, utf8.MaxRune+1, 1295990)
116+
benchSink = benchString1Width(b, false, 0, utf8.MaxRune+1, 1298422)
117117
}
118118
func BenchmarkString1Width768(b *testing.B) {
119119
benchSink = benchString1Width(b, false, 0, 0x300, 702)
120120
}
121121
func BenchmarkString1WidthAllEastAsian(b *testing.B) {
122-
benchSink = benchString1Width(b, true, 0, utf8.MaxRune+1, 1436664)
122+
benchSink = benchString1Width(b, true, 0, utf8.MaxRune+1, 1439014)
123123
}
124124
func BenchmarkString1Width768EastAsian(b *testing.B) {
125125
benchSink = benchString1Width(b, true, 0, 0x300, 794)
126126
}
127127

128-
//
129128
// tables
130-
//
131129
func benchTable(b *testing.B, tbl table) int {
132130
n := 0
133131
for i := 0; i < b.N; i++ {

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module github.com/mattn/go-runewidth
22

3-
go 1.9
3+
go 1.18
44

5-
require github.com/rivo/uniseg v0.3.1
5+
require github.com/rivo/uniseg v0.4.2

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
github.com/rivo/uniseg v0.3.1 h1:SDPP7SHNl1L7KrEFCSJslJ/DM9DT02Nq2C61XrfHMmk=
22
github.com/rivo/uniseg v0.3.1/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
3+
github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8=
4+
github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=

runewidth.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,12 @@ func (c *Condition) StringWidth(s string) (width int) {
179179
for len(s) > 0 {
180180
var chWidth int
181181
cl, s, _, state = uniseg.FirstGraphemeClusterInString(s, state)
182-
for _, r := range cl {
183-
chWidth = c.RuneWidth(r)
184-
if chWidth > 0 {
185-
break // Our best guess at this point is to use the width of the first non-zero-width rune.
182+
for index, r := range cl {
183+
if index == 0 && inTable(r, emoji) {
184+
chWidth = 2 // Not the optimal solution but it will work in most cases.
185+
break
186186
}
187+
chWidth += c.RuneWidth(r)
187188
}
188189
width += chWidth
189190
}
@@ -204,11 +205,12 @@ func (c *Condition) Truncate(s string, w int, tail string) string {
204205
chWidth int
205206
)
206207
ch, substr, _, state = uniseg.FirstGraphemeClusterInString(substr, state)
207-
for _, r := range ch {
208-
chWidth = c.RuneWidth(r)
209-
if chWidth > 0 {
210-
break // See StringWidth() for details.
208+
for index, r := range ch {
209+
if index == 0 && inTable(r, emoji) {
210+
chWidth = 2 // Not the optimal solution but it will work in most cases.
211+
break
211212
}
213+
chWidth += c.RuneWidth(r)
212214
}
213215
if width+chWidth > w {
214216
break

runewidth_table.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runewidth_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ var tables = []tableInfo{
4444
{combining, "combining", 465, "3cce13deb5e23f9f7327f2b1ef162328285a7dcf277a98302a8f7cdd43971268"},
4545
{doublewidth, "doublewidth", 182440, "3d16eda8650dc2c92d6318d32f0b4a74fda5a278db2d4544b1dd65863394823c"},
4646
{ambiguous, "ambiguous", 138739, "d05e339a10f296de6547ff3d6c5aee32f627f6555477afebd4a3b7e3cf74c9e3"},
47-
{emoji, "emoji", 3535, "9ec17351601d49c535658de8d129c1d0ccda2e620669fc39a2faaee7dedcef6d"},
47+
{emoji, "emoji", 3561, "3f1ae3b21ead544a59ab68fe541e8b098adc4fe1ffe3389a523a01dbfd8c1d75"},
4848
{narrow, "narrow", 111, "fa897699c5e3cd9141c638d539331b0bdd508b874e22996c5e929767d455fc5a"},
4949
{neutral, "neutral", 27333, "5455f5e75c307f70b4e9b2384dc5a8bcd91a4c5e2b24b2b185dfad4d860ee5c2"},
5050
}
@@ -462,7 +462,7 @@ func TestZeroWidthJoiner(t *testing.T) {
462462
{"\u200d🍳", 2},
463463
{"👨\u200d👨", 2},
464464
{"👨\u200d👨\u200d👧", 2},
465-
{"🏳️\u200d🌈", 1},
465+
{"🏳️\u200d🌈", 2},
466466
{"あ👩\u200d🍳い", 6},
467467
{"あ\u200d🍳い", 6},
468468
{"あ\u200dい", 4},

script/generate.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//go:build ignore
12
// +build ignore
23

34
// Generate runewidth_table.go from data at https://unicode.org/
@@ -166,6 +167,16 @@ func emoji(out io.Writer, in io.Reader) error {
166167
})
167168
}
168169

170+
// We also want regional indicator symbols (flags) to be part of the Emoji
171+
// table. They are U+1F1E6..U+1F1FF.
172+
for index, r := range arr {
173+
if r.lo >= 0x1f1ff {
174+
arr = append(arr[:index+1], arr[index:]...)
175+
arr[index] = rrange{lo: 0x1f1e6, hi: 0x1f1ff}
176+
break
177+
}
178+
}
179+
169180
shapeup(&arr)
170181
generate(out, "emoji", arr)
171182

0 commit comments

Comments
 (0)