vendor: github.com/mattn/go-runewidth v0.0.23
full diff: https://github.com/mattn/go-runewidth/compare/v0.0.22...v0.0.23 Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
+69
-22
@@ -24,10 +24,48 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
zerowidth table // combining + nonprint merged for faster zero-width lookup
|
||||
widewidth table // ambiguous + doublewidth merged for EA path
|
||||
)
|
||||
|
||||
func init() {
|
||||
zerowidth = mergeIntervals(combining, nonprint)
|
||||
widewidth = mergeIntervals(ambiguous, doublewidth)
|
||||
handleEnv()
|
||||
}
|
||||
|
||||
func mergeIntervals(t1, t2 table) table {
|
||||
merged := make(table, 0, len(t1)+len(t2))
|
||||
i, j := 0, 0
|
||||
for i < len(t1) && j < len(t2) {
|
||||
if t1[i].first <= t2[j].first {
|
||||
merged = append(merged, t1[i])
|
||||
i++
|
||||
} else {
|
||||
merged = append(merged, t2[j])
|
||||
j++
|
||||
}
|
||||
}
|
||||
merged = append(merged, t1[i:]...)
|
||||
merged = append(merged, t2[j:]...)
|
||||
if len(merged) == 0 {
|
||||
return merged
|
||||
}
|
||||
result := merged[:1]
|
||||
for _, iv := range merged[1:] {
|
||||
last := &result[len(result)-1]
|
||||
if iv.first <= last.last+1 {
|
||||
if iv.last > last.last {
|
||||
last.last = iv.last
|
||||
}
|
||||
} else {
|
||||
result = append(result, iv)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func handleEnv() {
|
||||
env := os.Getenv("RUNEWIDTH_EASTASIAN")
|
||||
if env == "" {
|
||||
@@ -52,15 +90,6 @@ type interval struct {
|
||||
|
||||
type table []interval
|
||||
|
||||
func inTables(r rune, ts ...table) bool {
|
||||
for _, t := range ts {
|
||||
if inTable(r, t) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func inTable(r rune, t table) bool {
|
||||
if r < t[0].first {
|
||||
return false
|
||||
@@ -131,9 +160,7 @@ func (c *Condition) RuneWidth(r rune) int {
|
||||
return 0
|
||||
case r < 0x300:
|
||||
return 1
|
||||
case inTable(r, narrow):
|
||||
return 1
|
||||
case inTables(r, nonprint, combining):
|
||||
case inTable(r, zerowidth):
|
||||
return 0
|
||||
case inTable(r, doublewidth):
|
||||
return 2
|
||||
@@ -142,13 +169,13 @@ func (c *Condition) RuneWidth(r rune) int {
|
||||
}
|
||||
} else {
|
||||
switch {
|
||||
case inTables(r, nonprint, combining):
|
||||
case inTable(r, zerowidth):
|
||||
return 0
|
||||
case inTable(r, narrow):
|
||||
return 1
|
||||
case inTables(r, ambiguous, doublewidth):
|
||||
case inTable(r, widewidth):
|
||||
return 2
|
||||
case !c.StrictEmojiNeutral && inTables(r, ambiguous, emoji, narrow):
|
||||
case !c.StrictEmojiNeutral && inTable(r, emoji):
|
||||
return 2
|
||||
default:
|
||||
return 1
|
||||
@@ -185,6 +212,16 @@ func (c *Condition) StringWidth(s string) (width int) {
|
||||
return c.RuneWidth(r)
|
||||
}
|
||||
}
|
||||
// ASCII fast path: no grapheme clustering needed for pure ASCII
|
||||
if isAllASCII(s) {
|
||||
for i := 0; i < len(s); i++ {
|
||||
b := s[i]
|
||||
if b >= 0x20 && b != 0x7F {
|
||||
width++
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
g := graphemes.FromString(s)
|
||||
for g.Next() {
|
||||
var chWidth int
|
||||
@@ -199,6 +236,15 @@ func (c *Condition) StringWidth(s string) (width int) {
|
||||
return
|
||||
}
|
||||
|
||||
func isAllASCII(s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] >= 0x80 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Truncate return string truncated with w cells
|
||||
func (c *Condition) Truncate(s string, w int, tail string) string {
|
||||
if c.StringWidth(s) <= w {
|
||||
@@ -264,24 +310,25 @@ func (c *Condition) TruncateLeft(s string, w int, prefix string) string {
|
||||
// Wrap return string wrapped with w cells
|
||||
func (c *Condition) Wrap(s string, w int) string {
|
||||
width := 0
|
||||
out := ""
|
||||
var out strings.Builder
|
||||
out.Grow(len(s) + len(s)/w + 1)
|
||||
for _, r := range s {
|
||||
cw := c.RuneWidth(r)
|
||||
if r == '\n' {
|
||||
out += string(r)
|
||||
out.WriteRune(r)
|
||||
width = 0
|
||||
continue
|
||||
} else if width+cw > w {
|
||||
out += "\n"
|
||||
out.WriteByte('\n')
|
||||
width = 0
|
||||
out += string(r)
|
||||
out.WriteRune(r)
|
||||
width += cw
|
||||
continue
|
||||
}
|
||||
out += string(r)
|
||||
out.WriteRune(r)
|
||||
width += cw
|
||||
}
|
||||
return out
|
||||
return out.String()
|
||||
}
|
||||
|
||||
// FillLeft return string filled in left by spaces in w cells
|
||||
@@ -320,7 +367,7 @@ func RuneWidth(r rune) int {
|
||||
|
||||
// IsAmbiguousWidth returns whether is ambiguous width or not.
|
||||
func IsAmbiguousWidth(r rune) bool {
|
||||
return inTables(r, private, ambiguous)
|
||||
return inTable(r, private) || inTable(r, ambiguous)
|
||||
}
|
||||
|
||||
// IsCombiningWidth returns whether is combining width or not.
|
||||
|
||||
Vendored
+1
-1
@@ -634,7 +634,7 @@ github.com/lestrrat-go/option
|
||||
# github.com/lestrrat-go/option/v2 v2.0.0
|
||||
## explicit; go 1.23
|
||||
github.com/lestrrat-go/option/v2
|
||||
# github.com/mattn/go-runewidth v0.0.22
|
||||
# github.com/mattn/go-runewidth v0.0.23
|
||||
## explicit; go 1.20
|
||||
github.com/mattn/go-runewidth
|
||||
# github.com/mattn/go-shellwords v1.0.12
|
||||
|
||||
Reference in New Issue
Block a user