sshd/terminal: Add fullwidth check for CJK in visualLength

This commit is contained in:
yumaokao 2020-03-21 19:57:39 +08:00
parent 80ddf1f43a
commit 8c7ea173ad
4 changed files with 38 additions and 1 deletions

1
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/shazow/rateio v0.0.0-20150116013248-e8e00881e5c1
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54
golang.org/x/text v0.3.2
)
go 1.13

3
go.sum
View File

@ -11,3 +11,6 @@ golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACk
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54 h1:xe1/2UUJRmA9iDglQSlkx8c5n3twv58+K0mPpC2zmhA=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -10,6 +10,7 @@ import (
"strconv"
"sync"
"unicode/utf8"
"golang.org/x/text/width"
)
// EscapeCodes contains escape sequences that can be written to the terminal in
@ -262,7 +263,7 @@ func (t *Terminal) moveCursorToPos(pos int) {
return
}
x := visualLength(t.prompt) + pos
x := visualLength(t.prompt) + visualLength(t.line[:pos])
y := x / t.termWidth
x = x % t.termWidth
@ -351,6 +352,7 @@ func (t *Terminal) setLine(newLine []rune, newPos int) {
for i := len(newLine); i < len(t.line); i++ {
t.writeLine(space)
}
t.line = newLine
t.moveCursorToPos(newPos)
}
t.line = newLine
@ -462,6 +464,10 @@ func visualLength(runes []rune) int {
inEscapeSeq = true
default:
length++
kind := width.LookupRune(r).Kind()
if kind == width.EastAsianFullwidth || kind == width.EastAsianWide {
length++
}
}
}

View File

@ -12,6 +12,7 @@ import (
"os"
"runtime"
"testing"
"unicode/utf8"
)
type MockTerminal struct {
@ -406,3 +407,29 @@ func TestOutputNewlines(t *testing.T) {
t.Errorf("incorrect output: was %q, expected %q", output, expected)
}
}
func TestTerminalvisualLength(t *testing.T) {
var tests = []struct {
input string
want int
}{
{"hello world", 11},
{"babalala", 8},
{"端子", 4},
{"を搭載", 6},
{"baba端子lalaを搭載", 18},
}
for _, test := range tests {
var runes []rune
for i, w := 0, 0; i < len(test.input); i += w {
runeValue, width := utf8.DecodeRuneInString(test.input[i:])
runes = append(runes, runeValue)
w = width
}
output := visualLength(runes)
if output != test.want {
t.Errorf("incorrect [%s] output: was %d, expected %d",
test.input, output, test.want)
}
}
}