diff options
Diffstat (limited to 'vendor/github.com/MichaelMure')
6 files changed, 387 insertions, 46 deletions
diff --git a/vendor/github.com/MichaelMure/go-term-text/.travis.yml b/vendor/github.com/MichaelMure/go-term-text/.travis.yml index 496ca056..c5db9518 100644 --- a/vendor/github.com/MichaelMure/go-term-text/.travis.yml +++ b/vendor/github.com/MichaelMure/go-term-text/.travis.yml @@ -1,9 +1,9 @@ language: go go: - - 1.10.x - 1.11.x - 1.12.x + - 1.13.x env: - GO111MODULE=on diff --git a/vendor/github.com/MichaelMure/go-term-text/Readme.md b/vendor/github.com/MichaelMure/go-term-text/Readme.md index 457b4472..25722ee9 100644 --- a/vendor/github.com/MichaelMure/go-term-text/Readme.md +++ b/vendor/github.com/MichaelMure/go-term-text/Readme.md @@ -20,6 +20,7 @@ Included algorithms cover: - trimming - alignment - escape sequence extraction and reapplication +- escape sequence snapshot and simplification - truncation ## Example @@ -31,7 +32,7 @@ import ( "fmt" "strings" - text "github.com/MichaelMure/go-term-text" + "github.com/MichaelMure/go-term-text" ) func main() { @@ -41,8 +42,10 @@ func main() { "various graphic design. 一只 A Quick \x1b[31m敏捷的狐 Fox " + "狸跳过了\x1b[0mDog一只懒狗。" - output, n := text.WrapWithPadIndent(input, 60, - "\x1b[34m<-indent-> \x1b[0m", "\x1b[33m<-pad-> \x1b[0m") + output, n := text.Wrap(input, 60, + text.WrapIndent("\x1b[34m<-indent-> \x1b[0m"), + text.WrapPad("\x1b[33m<-pad-> \x1b[0m"), + ) fmt.Printf("output has %d lines\n\n", n) diff --git a/vendor/github.com/MichaelMure/go-term-text/escape_state.go b/vendor/github.com/MichaelMure/go-term-text/escape_state.go new file mode 100644 index 00000000..cec35c26 --- /dev/null +++ b/vendor/github.com/MichaelMure/go-term-text/escape_state.go @@ -0,0 +1,265 @@ +package text + +import ( + "fmt" + "strconv" + "strings" +) + +const Escape = '\x1b' + +type EscapeState struct { + Bold bool + Dim bool + Italic bool + Underlined bool + Blink bool + Reverse bool + Hidden bool + CrossedOut bool + + FgColor Color + BgColor Color +} + +type Color interface { + Codes() []string +} + +func (es *EscapeState) Witness(s string) { + inEscape := false + var start int + + runes := []rune(s) + + for i, r := range runes { + if r == Escape { + inEscape = true + start = i + continue + } + if inEscape { + if r == 'm' { + inEscape = false + es.witnessCode(string(runes[start+1 : i])) + } + continue + } + } +} + +func (es *EscapeState) witnessCode(s string) { + if s == "" { + return + } + if s == "[" { + es.reset() + return + } + if len(s) < 2 { + return + } + if s[0] != '[' { + return + } + + s = s[1:] + split := strings.Split(s, ";") + + dequeue := func() { + split = split[1:] + } + + color := func(ground int) Color { + if len(split) < 1 { + // the whole sequence is broken, ignoring the rest + return nil + } + + subCode := split[0] + dequeue() + + switch subCode { + case "2": + if len(split) < 3 { + return nil + } + r, err := strconv.Atoi(split[0]) + dequeue() + if err != nil { + return nil + } + g, err := strconv.Atoi(split[0]) + dequeue() + if err != nil { + return nil + } + b, err := strconv.Atoi(split[0]) + dequeue() + if err != nil { + return nil + } + return &ColorRGB{ground: ground, R: r, G: g, B: b} + + case "5": + if len(split) < 1 { + return nil + } + index, err := strconv.Atoi(split[0]) + dequeue() + if err != nil { + return nil + } + return &Color256{ground: ground, Index: index} + + } + return nil + } + + for len(split) > 0 { + code, err := strconv.Atoi(split[0]) + if err != nil { + return + } + dequeue() + + switch { + case code == 0: + es.reset() + + case code == 1: + es.Bold = true + case code == 2: + es.Dim = true + case code == 3: + es.Italic = true + case code == 4: + es.Underlined = true + case code == 5: + es.Blink = true + // case code == 6: + case code == 7: + es.Reverse = true + case code == 8: + es.Hidden = true + case code == 9: + es.CrossedOut = true + + case code == 21: + es.Bold = false + case code == 22: + es.Dim = false + case code == 23: + es.Italic = false + case code == 24: + es.Underlined = false + case code == 25: + es.Blink = false + // case code == 26: + case code == 27: + es.Reverse = false + case code == 28: + es.Hidden = false + case code == 29: + es.CrossedOut = false + + case (code >= 30 && code <= 37) || code == 39 || (code >= 90 && code <= 97): + es.FgColor = ColorIndex(code) + + case (code >= 40 && code <= 47) || code == 49 || (code >= 100 && code <= 107): + es.BgColor = ColorIndex(code) + + case code == 38: + es.FgColor = color(code) + if es.FgColor == nil { + return + } + + case code == 48: + es.BgColor = color(code) + if es.BgColor == nil { + return + } + } + } +} + +func (es *EscapeState) reset() { + *es = EscapeState{} +} + +func (es *EscapeState) String() string { + var codes []string + + if es.Bold { + codes = append(codes, strconv.Itoa(1)) + } + if es.Dim { + codes = append(codes, strconv.Itoa(2)) + } + if es.Italic { + codes = append(codes, strconv.Itoa(3)) + } + if es.Underlined { + codes = append(codes, strconv.Itoa(4)) + } + if es.Blink { + codes = append(codes, strconv.Itoa(5)) + } + if es.Reverse { + codes = append(codes, strconv.Itoa(7)) + } + if es.Hidden { + codes = append(codes, strconv.Itoa(8)) + } + if es.CrossedOut { + codes = append(codes, strconv.Itoa(9)) + } + + if es.FgColor != nil { + codes = append(codes, es.FgColor.Codes()...) + } + if es.BgColor != nil { + codes = append(codes, es.BgColor.Codes()...) + } + + if len(codes) == 0 { + return "\x1b[0m" + } + + return fmt.Sprintf("\x1b[%sm", strings.Join(codes, ";")) +} + +type ColorIndex int + +func (cInd ColorIndex) Codes() []string { + return []string{strconv.Itoa(int(cInd))} +} + +type Color256 struct { + ground int + Index int +} + +func (c256 Color256) Codes() []string { + return []string{ + strconv.Itoa(c256.ground), + "5", + strconv.Itoa(c256.Index), + } +} + +type ColorRGB struct { + ground int + R, G, B int +} + +func (cRGB ColorRGB) Codes() []string { + return []string{ + strconv.Itoa(cRGB.ground), + "2", + strconv.Itoa(cRGB.R), + strconv.Itoa(cRGB.G), + strconv.Itoa(cRGB.B), + } +} diff --git a/vendor/github.com/MichaelMure/go-term-text/go.mod b/vendor/github.com/MichaelMure/go-term-text/go.mod index 162c5dac..a03c8606 100644 --- a/vendor/github.com/MichaelMure/go-term-text/go.mod +++ b/vendor/github.com/MichaelMure/go-term-text/go.mod @@ -1,8 +1,8 @@ module github.com/MichaelMure/go-term-text -go 1.10 +go 1.11 require ( - github.com/mattn/go-runewidth v0.0.4 + github.com/mattn/go-runewidth v0.0.6 github.com/stretchr/testify v1.3.0 ) diff --git a/vendor/github.com/MichaelMure/go-term-text/go.sum b/vendor/github.com/MichaelMure/go-term-text/go.sum index 0aaedf16..a119b457 100644 --- a/vendor/github.com/MichaelMure/go-term-text/go.sum +++ b/vendor/github.com/MichaelMure/go-term-text/go.sum @@ -1,7 +1,7 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.6 h1:V2iyH+aX9C5fsYCpK60U8BYIvmhqxuOL3JZcqc1NB7k= +github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/vendor/github.com/MichaelMure/go-term-text/wrap.go b/vendor/github.com/MichaelMure/go-term-text/wrap.go index 2fd6ed5f..eba9e0b8 100644 --- a/vendor/github.com/MichaelMure/go-term-text/wrap.go +++ b/vendor/github.com/MichaelMure/go-term-text/wrap.go @@ -13,52 +13,89 @@ func init() { runewidth.DefaultCondition.EastAsianWidth = false } -// Wrap a text for a given line size. -// Handle properly terminal color escape code -func Wrap(text string, lineWidth int) (string, int) { - return WrapLeftPadded(text, lineWidth, 0) +type wrapOpts struct { + indent string + pad string + align Alignment } -// WrapLeftPadded wrap a text for a given line size with a left padding. -// Handle properly terminal color escape code -func WrapLeftPadded(text string, lineWidth int, leftPad int) (string, int) { - pad := strings.Repeat(" ", leftPad) - return WrapWithPad(text, lineWidth, pad) +// WrapOption is a functional option for the Wrap() function +type WrapOption func(opts *wrapOpts) + +// WrapPad configure the padding with a string for Wrap() +func WrapPad(pad string) WrapOption { + return func(opts *wrapOpts) { + opts.pad = pad + } } -// WrapWithPad wrap a text for a given line size with a custom left padding -// Handle properly terminal color escape code -func WrapWithPad(text string, lineWidth int, pad string) (string, int) { - return WrapWithPadIndent(text, lineWidth, pad, pad) +// WrapPadded configure the padding with a number of space characters for Wrap() +func WrapPadded(padLen int) WrapOption { + return func(opts *wrapOpts) { + opts.pad = strings.Repeat(" ", padLen) + } } -// WrapWithPad wrap a text for a given line size with a custom left padding -// This function also align the result depending on the requested alignment. -// Handle properly terminal color escape code -func WrapWithPadAlign(text string, lineWidth int, pad string, align Alignment) (string, int) { - return WrapWithPadIndentAlign(text, lineWidth, pad, pad, align) +// WrapPad configure the indentation on the first line for Wrap() +func WrapIndent(indent string) WrapOption { + return func(opts *wrapOpts) { + opts.indent = indent + } } -// WrapWithPadIndent wrap a text for a given line size with a custom left padding -// and a first line indent. The padding is not effective on the first line, indent -// is used instead, which allow to implement indents and outdents. -// Handle properly terminal color escape code -func WrapWithPadIndent(text string, lineWidth int, indent string, pad string) (string, int) { - return WrapWithPadIndentAlign(text, lineWidth, indent, pad, NoAlign) +// WrapAlign configure the text alignment for Wrap() +func WrapAlign(align Alignment) WrapOption { + return func(opts *wrapOpts) { + opts.align = align + } } -// WrapWithPadIndentAlign wrap a text for a given line size with a custom left padding -// and a first line indent. The padding is not effective on the first line, indent -// is used instead, which allow to implement indents and outdents. -// This function also align the result depending on the requested alignment. +// allWrapOpts compile the set of WrapOption into a final wrapOpts +// from the default values. +func allWrapOpts(opts []WrapOption) *wrapOpts { + wrapOpts := &wrapOpts{ + indent: "", + pad: "", + align: NoAlign, + } + for _, opt := range opts { + opt(wrapOpts) + } + if wrapOpts.indent == "" { + wrapOpts.indent = wrapOpts.pad + } + return wrapOpts +} + +// Wrap a text for a given line size. // Handle properly terminal color escape code -func WrapWithPadIndentAlign(text string, lineWidth int, indent string, pad string, align Alignment) (string, int) { +// Options are accepted to configure things like indent, padding or alignment. +// Return the wrapped text and the number of lines +func Wrap(text string, lineWidth int, opts ...WrapOption) (string, int) { + wrapOpts := allWrapOpts(opts) + + if lineWidth <= 0 { + return "", 1 + } + var lines []string nbLine := 0 + if len(wrapOpts.indent) >= lineWidth { + // fallback rendering + lines = append(lines, strings.Repeat("⭬", lineWidth)) + nbLine++ + wrapOpts.indent = wrapOpts.pad + } + if len(wrapOpts.pad) >= lineWidth { + // fallback rendering + line := strings.Repeat("⭬", lineWidth) + return strings.Repeat(line+"\n", 5), 5 + } + // Start with the indent - padStr := indent - padLen := Len(indent) + padStr := wrapOpts.indent + padLen := Len(wrapOpts.indent) // tabs are formatted as 4 spaces text = strings.Replace(text, "\t", " ", -1) @@ -67,8 +104,8 @@ func WrapWithPadIndentAlign(text string, lineWidth int, indent string, pad strin for i, line := range strings.Split(text, "\n") { // on the second line, use the padding instead if i == 1 { - padStr = pad - padLen = Len(pad) + padStr = wrapOpts.pad + padLen = Len(wrapOpts.pad) } if line == "" || strings.TrimSpace(line) == "" { @@ -87,14 +124,14 @@ func WrapWithPadIndentAlign(text string, lineWidth int, indent string, pad strin // use the first wrapped line, ignore everything else and // wrap the remaining of the line with the normal padding. - content := LineAlign(strings.TrimRight(split[0], " "), lineWidth-padLen, align) + content := LineAlign(strings.TrimRight(split[0], " "), lineWidth-padLen, wrapOpts.align) lines = append(lines, padStr+content) nbLine++ line = strings.TrimPrefix(line, split[0]) line = strings.TrimLeft(line, " ") - padStr = pad - padLen = Len(pad) + padStr = wrapOpts.pad + padLen = Len(wrapOpts.pad) wrapped = softwrapLine(line, lineWidth-padLen) split = strings.Split(wrapped, "\n") } @@ -102,10 +139,10 @@ func WrapWithPadIndentAlign(text string, lineWidth int, indent string, pad strin for j, seg := range split { if j == 0 { // keep the left padding of the wrapped line - content := LineAlign(strings.TrimRight(seg, " "), lineWidth-padLen, align) + content := LineAlign(strings.TrimRight(seg, " "), lineWidth-padLen, wrapOpts.align) lines = append(lines, padStr+content) } else { - content := LineAlign(strings.TrimSpace(seg), lineWidth-padLen, align) + content := LineAlign(strings.TrimSpace(seg), lineWidth-padLen, wrapOpts.align) lines = append(lines, padStr+content) } nbLine++ @@ -115,6 +152,42 @@ func WrapWithPadIndentAlign(text string, lineWidth int, indent string, pad strin return strings.Join(lines, "\n"), nbLine } +// WrapLeftPadded wrap a text for a given line size with a left padding. +// Handle properly terminal color escape code +func WrapLeftPadded(text string, lineWidth int, leftPad int) (string, int) { + return Wrap(text, lineWidth, WrapPadded(leftPad)) +} + +// WrapWithPad wrap a text for a given line size with a custom left padding +// Handle properly terminal color escape code +func WrapWithPad(text string, lineWidth int, pad string) (string, int) { + return Wrap(text, lineWidth, WrapPad(pad)) +} + +// WrapWithPad wrap a text for a given line size with a custom left padding +// This function also align the result depending on the requested alignment. +// Handle properly terminal color escape code +func WrapWithPadAlign(text string, lineWidth int, pad string, align Alignment) (string, int) { + return Wrap(text, lineWidth, WrapPad(pad), WrapAlign(align)) +} + +// WrapWithPadIndent wrap a text for a given line size with a custom left padding +// and a first line indent. The padding is not effective on the first line, indent +// is used instead, which allow to implement indents and outdents. +// Handle properly terminal color escape code +func WrapWithPadIndent(text string, lineWidth int, indent string, pad string) (string, int) { + return Wrap(text, lineWidth, WrapIndent(indent), WrapPad(pad)) +} + +// WrapWithPadIndentAlign wrap a text for a given line size with a custom left padding +// and a first line indent. The padding is not effective on the first line, indent +// is used instead, which allow to implement indents and outdents. +// This function also align the result depending on the requested alignment. +// Handle properly terminal color escape code +func WrapWithPadIndentAlign(text string, lineWidth int, indent string, pad string, align Alignment) (string, int) { + return Wrap(text, lineWidth, WrapIndent(indent), WrapPad(pad), WrapAlign(align)) +} + // Break a line into several lines so that each line consumes at most // 'textWidth' cells. Lines break at groups of white spaces and multibyte // chars. Nothing is removed from the original text so that it behaves like a |