Update dependencies
This commit is contained in:
parent
576bab9e2e
commit
e48ff5bea4
2
Gopkg.lock
generated
2
Gopkg.lock
generated
@ -139,7 +139,7 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "maunium.net/go/tview"
|
name = "maunium.net/go/tview"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "6146b7fe2331e23a78e217016705bc6801bfc55a"
|
revision = "7eabba90a261a481d36ace89daa79c56582238d7"
|
||||||
|
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
|
5
vendor/maunium.net/go/tview/README.md
generated
vendored
5
vendor/maunium.net/go/tview/README.md
generated
vendored
@ -64,6 +64,11 @@ Add your issue here on GitHub. Feel free to get in touch if you have any questio
|
|||||||
|
|
||||||
(There are no corresponding tags in the project. I only keep such a history in this README.)
|
(There are no corresponding tags in the project. I only keep such a history in this README.)
|
||||||
|
|
||||||
|
- v0.14 (2018-04-13)
|
||||||
|
- Added an `Escape()` function which keep strings like color or region tags from being recognized as such.
|
||||||
|
- Added `ANSIIWriter()` and `TranslateANSII()` which convert ANSII escape sequences to `tview` color tags.
|
||||||
|
- v0.13 (2018-04-01)
|
||||||
|
- Added background colors and text attributes to color tags.
|
||||||
- v0.12 (2018-03-13)
|
- v0.12 (2018-03-13)
|
||||||
- Added "suspended mode" to `Application`.
|
- Added "suspended mode" to `Application`.
|
||||||
- v0.11 (2018-03-02)
|
- v0.11 (2018-03-02)
|
||||||
|
237
vendor/maunium.net/go/tview/ansii.go
generated
vendored
Normal file
237
vendor/maunium.net/go/tview/ansii.go
generated
vendored
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
package tview
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The states of the ANSII escape code parser.
|
||||||
|
const (
|
||||||
|
ansiiText = iota
|
||||||
|
ansiiEscape
|
||||||
|
ansiiSubstring
|
||||||
|
ansiiControlSequence
|
||||||
|
)
|
||||||
|
|
||||||
|
// ansii is a io.Writer which translates ANSII escape codes into tview color
|
||||||
|
// tags.
|
||||||
|
type ansii struct {
|
||||||
|
io.Writer
|
||||||
|
|
||||||
|
// Reusable buffers.
|
||||||
|
buffer *bytes.Buffer // The entire output text of one Write().
|
||||||
|
csiParameter, csiIntermediate *bytes.Buffer // Partial CSI strings.
|
||||||
|
|
||||||
|
// The current state of the parser. One of the ansii constants.
|
||||||
|
state int
|
||||||
|
}
|
||||||
|
|
||||||
|
// ANSIIWriter returns an io.Writer which translates any ANSII escape codes
|
||||||
|
// written to it into tview color tags. Other escape codes don't have an effect
|
||||||
|
// and are simply removed. The translated text is written to the provided
|
||||||
|
// writer.
|
||||||
|
func ANSIIWriter(writer io.Writer) io.Writer {
|
||||||
|
return &ansii{
|
||||||
|
Writer: writer,
|
||||||
|
buffer: new(bytes.Buffer),
|
||||||
|
csiParameter: new(bytes.Buffer),
|
||||||
|
csiIntermediate: new(bytes.Buffer),
|
||||||
|
state: ansiiText,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write parses the given text as a string of runes, translates ANSII escape
|
||||||
|
// codes to color tags and writes them to the output writer.
|
||||||
|
func (a *ansii) Write(text []byte) (int, error) {
|
||||||
|
defer func() {
|
||||||
|
a.buffer.Reset()
|
||||||
|
}()
|
||||||
|
|
||||||
|
for _, r := range string(text) {
|
||||||
|
switch a.state {
|
||||||
|
|
||||||
|
// We just entered an escape sequence.
|
||||||
|
case ansiiEscape:
|
||||||
|
switch r {
|
||||||
|
case '[': // Control Sequence Introducer.
|
||||||
|
a.csiParameter.Reset()
|
||||||
|
a.csiIntermediate.Reset()
|
||||||
|
a.state = ansiiControlSequence
|
||||||
|
case 'c': // Reset.
|
||||||
|
fmt.Fprint(a.buffer, "[-:-:-]")
|
||||||
|
a.state = ansiiText
|
||||||
|
case 'P', ']', 'X', '^', '_': // Substrings and commands.
|
||||||
|
a.state = ansiiSubstring
|
||||||
|
default: // Ignore.
|
||||||
|
a.state = ansiiText
|
||||||
|
}
|
||||||
|
|
||||||
|
// CSI Sequences.
|
||||||
|
case ansiiControlSequence:
|
||||||
|
switch {
|
||||||
|
case r >= 0x30 && r <= 0x3f: // Parameter bytes.
|
||||||
|
if _, err := a.csiParameter.WriteRune(r); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
case r >= 0x20 && r <= 0x2f: // Intermediate bytes.
|
||||||
|
if _, err := a.csiIntermediate.WriteRune(r); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
case r >= 0x40 && r <= 0x7e: // Final byte.
|
||||||
|
switch r {
|
||||||
|
case 'E': // Next line.
|
||||||
|
count, _ := strconv.Atoi(a.csiParameter.String())
|
||||||
|
if count == 0 {
|
||||||
|
count = 1
|
||||||
|
}
|
||||||
|
fmt.Fprint(a.buffer, strings.Repeat("\n", count))
|
||||||
|
case 'm': // Select Graphic Rendition.
|
||||||
|
var (
|
||||||
|
background, foreground, attributes string
|
||||||
|
clearAttributes bool
|
||||||
|
)
|
||||||
|
fields := strings.Split(a.csiParameter.String(), ";")
|
||||||
|
if len(fields) == 0 || len(fields) == 1 && fields[0] == "0" {
|
||||||
|
// Reset.
|
||||||
|
if _, err := a.buffer.WriteString("[-:-:-]"); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
lookupColor := func(colorNumber int, bright bool) string {
|
||||||
|
if colorNumber < 0 || colorNumber > 7 {
|
||||||
|
return "black"
|
||||||
|
}
|
||||||
|
if bright {
|
||||||
|
colorNumber += 8
|
||||||
|
}
|
||||||
|
return [...]string{
|
||||||
|
"black",
|
||||||
|
"red",
|
||||||
|
"green",
|
||||||
|
"yellow",
|
||||||
|
"blue",
|
||||||
|
"darkmagenta",
|
||||||
|
"darkcyan",
|
||||||
|
"white",
|
||||||
|
"#7f7f7f",
|
||||||
|
"#ff0000",
|
||||||
|
"#00ff00",
|
||||||
|
"#ffff00",
|
||||||
|
"#5c5cff",
|
||||||
|
"#ff00ff",
|
||||||
|
"#00ffff",
|
||||||
|
"#ffffff",
|
||||||
|
}[colorNumber]
|
||||||
|
}
|
||||||
|
for index, field := range fields {
|
||||||
|
switch field {
|
||||||
|
case "1", "01":
|
||||||
|
attributes += "b"
|
||||||
|
case "2", "02":
|
||||||
|
attributes += "d"
|
||||||
|
case "4", "04":
|
||||||
|
attributes += "u"
|
||||||
|
case "5", "05":
|
||||||
|
attributes += "l"
|
||||||
|
case "7", "07":
|
||||||
|
attributes += "7"
|
||||||
|
case "22", "24", "25", "27":
|
||||||
|
clearAttributes = true
|
||||||
|
case "30", "31", "32", "33", "34", "35", "36", "37":
|
||||||
|
colorNumber, _ := strconv.Atoi(field)
|
||||||
|
foreground = lookupColor(colorNumber-30, false)
|
||||||
|
case "40", "41", "42", "43", "44", "45", "46", "47":
|
||||||
|
colorNumber, _ := strconv.Atoi(field)
|
||||||
|
background = lookupColor(colorNumber-40, false)
|
||||||
|
case "90", "91", "92", "93", "94", "95", "96", "97":
|
||||||
|
colorNumber, _ := strconv.Atoi(field)
|
||||||
|
foreground = lookupColor(colorNumber-90, true)
|
||||||
|
case "100", "101", "102", "103", "104", "105", "106", "107":
|
||||||
|
colorNumber, _ := strconv.Atoi(field)
|
||||||
|
background = lookupColor(colorNumber-100, true)
|
||||||
|
case "38", "48":
|
||||||
|
var color string
|
||||||
|
if len(fields) > index+1 {
|
||||||
|
if fields[index+1] == "5" && len(fields) > index+2 { // 8-bit colors.
|
||||||
|
colorNumber, _ := strconv.Atoi(fields[index+2])
|
||||||
|
if colorNumber <= 7 {
|
||||||
|
color = lookupColor(colorNumber, false)
|
||||||
|
} else if colorNumber <= 15 {
|
||||||
|
color = lookupColor(colorNumber, true)
|
||||||
|
} else if colorNumber <= 231 {
|
||||||
|
red := (colorNumber - 16) / 36
|
||||||
|
green := ((colorNumber - 16) / 6) % 6
|
||||||
|
blue := (colorNumber - 16) % 6
|
||||||
|
color = fmt.Sprintf("%02x%02x%02x", 255*red/5, 255*green/5, 255*blue/5)
|
||||||
|
} else if colorNumber <= 255 {
|
||||||
|
grey := 255 * (colorNumber - 232) / 23
|
||||||
|
color = fmt.Sprintf("%02x%02x%02x", grey, grey, grey)
|
||||||
|
}
|
||||||
|
} else if fields[index+1] == "2" && len(fields) > index+4 { // 24-bit colors.
|
||||||
|
red, _ := strconv.Atoi(fields[index+2])
|
||||||
|
green, _ := strconv.Atoi(fields[index+3])
|
||||||
|
blue, _ := strconv.Atoi(fields[index+4])
|
||||||
|
color = fmt.Sprintf("%02x%02x%02x", red, green, blue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(color) > 0 {
|
||||||
|
if field == "38" {
|
||||||
|
foreground = color
|
||||||
|
} else {
|
||||||
|
background = color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(attributes) > 0 || clearAttributes {
|
||||||
|
attributes = ":" + attributes
|
||||||
|
}
|
||||||
|
if len(foreground) > 0 || len(background) > 0 || len(attributes) > 0 {
|
||||||
|
fmt.Fprintf(a.buffer, "[%s:%s%s]", foreground, background, attributes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a.state = ansiiText
|
||||||
|
default: // Undefined byte.
|
||||||
|
a.state = ansiiText // Abort CSI.
|
||||||
|
}
|
||||||
|
|
||||||
|
// We just entered a substring/command sequence.
|
||||||
|
case ansiiSubstring:
|
||||||
|
if r == 27 { // Most likely the end of the substring.
|
||||||
|
a.state = ansiiEscape
|
||||||
|
} // Ignore all other characters.
|
||||||
|
|
||||||
|
// "ansiiText" and all others.
|
||||||
|
default:
|
||||||
|
if r == 27 {
|
||||||
|
// This is the start of an escape sequence.
|
||||||
|
a.state = ansiiEscape
|
||||||
|
} else {
|
||||||
|
// Just a regular rune. Send to buffer.
|
||||||
|
if _, err := a.buffer.WriteRune(r); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write buffer to target writer.
|
||||||
|
n, err := a.buffer.WriteTo(a.Writer)
|
||||||
|
if err != nil {
|
||||||
|
return int(n), err
|
||||||
|
}
|
||||||
|
return len(text), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TranslateANSII replaces ANSII escape sequences found in the provided string
|
||||||
|
// with tview's color tags and returns the resulting string.
|
||||||
|
func TranslateANSII(text string) string {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
writer := ANSIIWriter(&buffer)
|
||||||
|
writer.Write([]byte(text))
|
||||||
|
return buffer.String()
|
||||||
|
}
|
20
vendor/maunium.net/go/tview/application.go
generated
vendored
20
vendor/maunium.net/go/tview/application.go
generated
vendored
@ -38,6 +38,8 @@ type Application struct {
|
|||||||
// be forwarded).
|
// be forwarded).
|
||||||
mouseCapture func(event *tcell.EventMouse) *tcell.EventMouse
|
mouseCapture func(event *tcell.EventMouse) *tcell.EventMouse
|
||||||
|
|
||||||
|
pasteCapture func(event *tcell.EventPaste) *tcell.EventPaste
|
||||||
|
|
||||||
// An optional callback function which is invoked just before the root
|
// An optional callback function which is invoked just before the root
|
||||||
// primitive is drawn.
|
// primitive is drawn.
|
||||||
beforeDraw func(screen tcell.Screen) bool
|
beforeDraw func(screen tcell.Screen) bool
|
||||||
@ -190,6 +192,24 @@ func (a *Application) Run() error {
|
|||||||
//a.Draw()
|
//a.Draw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case *tcell.EventPaste:
|
||||||
|
a.RLock()
|
||||||
|
p := a.focus
|
||||||
|
a.RUnlock()
|
||||||
|
|
||||||
|
if a.pasteCapture != nil {
|
||||||
|
event = a.pasteCapture(event)
|
||||||
|
if event == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p != nil {
|
||||||
|
if handler := p.PasteHandler(); handler != nil {
|
||||||
|
handler(event)
|
||||||
|
a.Draw()
|
||||||
|
}
|
||||||
|
}
|
||||||
case *tcell.EventResize:
|
case *tcell.EventResize:
|
||||||
a.Lock()
|
a.Lock()
|
||||||
screen := a.screen
|
screen := a.screen
|
||||||
|
32
vendor/maunium.net/go/tview/box.go
generated
vendored
32
vendor/maunium.net/go/tview/box.go
generated
vendored
@ -62,6 +62,8 @@ type Box struct {
|
|||||||
// nothing should be forwarded).
|
// nothing should be forwarded).
|
||||||
mouseCapture func(event *tcell.EventMouse) *tcell.EventMouse
|
mouseCapture func(event *tcell.EventMouse) *tcell.EventMouse
|
||||||
|
|
||||||
|
pasteCapture func(event *tcell.EventPaste) *tcell.EventPaste
|
||||||
|
|
||||||
// An optional function which is called before the box is drawn.
|
// An optional function which is called before the box is drawn.
|
||||||
draw func(screen tcell.Screen, x, y, width, height int) (int, int, int, int)
|
draw func(screen tcell.Screen, x, y, width, height int) (int, int, int, int)
|
||||||
}
|
}
|
||||||
@ -218,6 +220,36 @@ func (b *Box) GetMouseCapture() func(event *tcell.EventMouse) *tcell.EventMouse
|
|||||||
return b.mouseCapture
|
return b.mouseCapture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Box) WrapPasteHandler(pasteHandler func(*tcell.EventPaste)) func(*tcell.EventPaste) {
|
||||||
|
return func(event *tcell.EventPaste) {
|
||||||
|
if b.pasteCapture != nil {
|
||||||
|
event = b.pasteCapture(event)
|
||||||
|
}
|
||||||
|
if event != nil && pasteHandler != nil {
|
||||||
|
pasteHandler(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Box) PasteHandler() func(event *tcell.EventPaste) {
|
||||||
|
return b.WrapPasteHandler(func(event *tcell.EventPaste) {
|
||||||
|
// Default paste handler just calls input handler with each character.
|
||||||
|
inputHandler := b.InputHandler()
|
||||||
|
for _, char := range event.Text() {
|
||||||
|
inputHandler(tcell.NewEventKey(tcell.KeyRune, char, tcell.ModNone), nil)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Box) SetPasteCapture(capture func(event *tcell.EventPaste) *tcell.EventPaste) *Box {
|
||||||
|
b.pasteCapture = capture
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Box) GetPasteCapture() func(event *tcell.EventPaste) *tcell.EventPaste {
|
||||||
|
return b.pasteCapture
|
||||||
|
}
|
||||||
|
|
||||||
// SetBackgroundColor sets the box's background color.
|
// SetBackgroundColor sets the box's background color.
|
||||||
func (b *Box) SetBackgroundColor(color tcell.Color) *Box {
|
func (b *Box) SetBackgroundColor(color tcell.Color) *Box {
|
||||||
b.backgroundColor = color
|
b.backgroundColor = color
|
||||||
|
36
vendor/maunium.net/go/tview/checkbox.go
generated
vendored
36
vendor/maunium.net/go/tview/checkbox.go
generated
vendored
@ -17,6 +17,10 @@ type Checkbox struct {
|
|||||||
// The text to be displayed before the input area.
|
// The text to be displayed before the input area.
|
||||||
label string
|
label string
|
||||||
|
|
||||||
|
// The screen width of the label area. A value of 0 means use the width of
|
||||||
|
// the label text.
|
||||||
|
labelWidth int
|
||||||
|
|
||||||
// The label color.
|
// The label color.
|
||||||
labelColor tcell.Color
|
labelColor tcell.Color
|
||||||
|
|
||||||
@ -34,6 +38,10 @@ type Checkbox struct {
|
|||||||
// are done entering text. The key which was pressed is provided (tab,
|
// are done entering text. The key which was pressed is provided (tab,
|
||||||
// shift-tab, or escape).
|
// shift-tab, or escape).
|
||||||
done func(tcell.Key)
|
done func(tcell.Key)
|
||||||
|
|
||||||
|
// A callback function set by the Form class and called when the user leaves
|
||||||
|
// this form item.
|
||||||
|
finished func(tcell.Key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCheckbox returns a new input field.
|
// NewCheckbox returns a new input field.
|
||||||
@ -68,6 +76,13 @@ func (c *Checkbox) GetLabel() string {
|
|||||||
return c.label
|
return c.label
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetLabelWidth sets the screen width of the label. A value of 0 will cause the
|
||||||
|
// primitive to use the width of the label string.
|
||||||
|
func (c *Checkbox) SetLabelWidth(width int) *Checkbox {
|
||||||
|
c.labelWidth = width
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// SetLabelColor sets the color of the label.
|
// SetLabelColor sets the color of the label.
|
||||||
func (c *Checkbox) SetLabelColor(color tcell.Color) *Checkbox {
|
func (c *Checkbox) SetLabelColor(color tcell.Color) *Checkbox {
|
||||||
c.labelColor = color
|
c.labelColor = color
|
||||||
@ -87,8 +102,8 @@ func (c *Checkbox) SetFieldTextColor(color tcell.Color) *Checkbox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetFormAttributes sets attributes shared by all form items.
|
// SetFormAttributes sets attributes shared by all form items.
|
||||||
func (c *Checkbox) SetFormAttributes(label string, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem {
|
func (c *Checkbox) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem {
|
||||||
c.label = label
|
c.labelWidth = labelWidth
|
||||||
c.labelColor = labelColor
|
c.labelColor = labelColor
|
||||||
c.backgroundColor = bgColor
|
c.backgroundColor = bgColor
|
||||||
c.fieldTextColor = fieldTextColor
|
c.fieldTextColor = fieldTextColor
|
||||||
@ -121,9 +136,10 @@ func (c *Checkbox) SetDoneFunc(handler func(key tcell.Key)) *Checkbox {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFinishedFunc calls SetDoneFunc().
|
// SetFinishedFunc sets a callback invoked when the user leaves this form item.
|
||||||
func (c *Checkbox) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
|
func (c *Checkbox) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
|
||||||
return c.SetDoneFunc(handler)
|
c.finished = handler
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws this primitive onto the screen.
|
// Draw draws this primitive onto the screen.
|
||||||
@ -138,8 +154,17 @@ func (c *Checkbox) Draw(screen tcell.Screen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw label.
|
// Draw label.
|
||||||
|
if c.labelWidth > 0 {
|
||||||
|
labelWidth := c.labelWidth
|
||||||
|
if labelWidth > rightLimit-x {
|
||||||
|
labelWidth = rightLimit - x
|
||||||
|
}
|
||||||
|
Print(screen, c.label, x, y, labelWidth, AlignLeft, c.labelColor)
|
||||||
|
x += labelWidth
|
||||||
|
} else {
|
||||||
_, drawnWidth := Print(screen, c.label, x, y, rightLimit-x, AlignLeft, c.labelColor)
|
_, drawnWidth := Print(screen, c.label, x, y, rightLimit-x, AlignLeft, c.labelColor)
|
||||||
x += drawnWidth
|
x += drawnWidth
|
||||||
|
}
|
||||||
|
|
||||||
// Draw checkbox.
|
// Draw checkbox.
|
||||||
fieldStyle := tcell.StyleDefault.Background(c.fieldBackgroundColor).Foreground(c.fieldTextColor)
|
fieldStyle := tcell.StyleDefault.Background(c.fieldBackgroundColor).Foreground(c.fieldTextColor)
|
||||||
@ -170,6 +195,9 @@ func (c *Checkbox) InputHandler() func(event *tcell.EventKey, setFocus func(p Pr
|
|||||||
if c.done != nil {
|
if c.done != nil {
|
||||||
c.done(key)
|
c.done(key)
|
||||||
}
|
}
|
||||||
|
if c.finished != nil {
|
||||||
|
c.finished(key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
42
vendor/maunium.net/go/tview/doc.go
generated
vendored
42
vendor/maunium.net/go/tview/doc.go
generated
vendored
@ -77,13 +77,53 @@ applies to almost everything from box titles, list text, form item labels, to
|
|||||||
table cells. In a TextView, this functionality has to be switched on explicitly.
|
table cells. In a TextView, this functionality has to be switched on explicitly.
|
||||||
See the TextView documentation for more information.
|
See the TextView documentation for more information.
|
||||||
|
|
||||||
|
Color tags may contain not just the foreground (text) color but also the
|
||||||
|
background color and additional flags. In fact, the full definition of a color
|
||||||
|
tag is as follows:
|
||||||
|
|
||||||
|
[<foreground>:<background>:<flags>]
|
||||||
|
|
||||||
|
Each of the three fields can be left blank and trailing fields can be ommitted.
|
||||||
|
(Empty square brackets "[]", however, are not considered color tags.) Colors
|
||||||
|
that are not specified will be left unchanged. A field with just a dash ("-")
|
||||||
|
means "reset to default".
|
||||||
|
|
||||||
|
You can specify the following flags (some flags may not be supported by your
|
||||||
|
terminal):
|
||||||
|
|
||||||
|
l: blink
|
||||||
|
b: bold
|
||||||
|
d: dim
|
||||||
|
r: reverse (switch foreground and background color)
|
||||||
|
u: underline
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
[yellow]Yellow text
|
||||||
|
[yellow:red]Yellow text on red background
|
||||||
|
[:red]Red background, text color unchanged
|
||||||
|
[yellow::u]Yellow text underlined
|
||||||
|
[::bl]Bold, blinking text
|
||||||
|
[::-]Colors unchanged, flags reset
|
||||||
|
[-]Reset foreground color
|
||||||
|
[-:-:-]Reset everything
|
||||||
|
[:]No effect
|
||||||
|
[]Not a valid color tag, will print square brackets as they are
|
||||||
|
|
||||||
In the rare event that you want to display a string such as "[red]" or
|
In the rare event that you want to display a string such as "[red]" or
|
||||||
"[#00ff1a]" without applying its effect, you need to put an opening square
|
"[#00ff1a]" without applying its effect, you need to put an opening square
|
||||||
bracket before the closing square bracket. Examples:
|
bracket before the closing square bracket. Note that the text inside the
|
||||||
|
brackets will be matched less strictly than region or colors tags. I.e. any
|
||||||
|
character that may be used in color or region tags will be recognized. Examples:
|
||||||
|
|
||||||
[red[] will be output as [red]
|
[red[] will be output as [red]
|
||||||
["123"[] will be output as ["123"]
|
["123"[] will be output as ["123"]
|
||||||
[#6aff00[[] will be output as [#6aff00[]
|
[#6aff00[[] will be output as [#6aff00[]
|
||||||
|
[a#"[[[] will be output as [a#"[[]
|
||||||
|
[] will be output as [] (see color tags above)
|
||||||
|
[[] will be output as [[] (not an escaped tag)
|
||||||
|
|
||||||
|
You can use the Escape() function to insert brackets automatically where needed.
|
||||||
|
|
||||||
Styles
|
Styles
|
||||||
|
|
||||||
|
36
vendor/maunium.net/go/tview/dropdown.go
generated
vendored
36
vendor/maunium.net/go/tview/dropdown.go
generated
vendored
@ -51,6 +51,10 @@ type DropDown struct {
|
|||||||
// The color for prefixes.
|
// The color for prefixes.
|
||||||
prefixTextColor tcell.Color
|
prefixTextColor tcell.Color
|
||||||
|
|
||||||
|
// The screen width of the label area. A value of 0 means use the width of
|
||||||
|
// the label text.
|
||||||
|
labelWidth int
|
||||||
|
|
||||||
// The screen width of the input area. A value of 0 means extend as much as
|
// The screen width of the input area. A value of 0 means extend as much as
|
||||||
// possible.
|
// possible.
|
||||||
fieldWidth int
|
fieldWidth int
|
||||||
@ -59,6 +63,10 @@ type DropDown struct {
|
|||||||
// are done selecting options. The key which was pressed is provided (tab,
|
// are done selecting options. The key which was pressed is provided (tab,
|
||||||
// shift-tab, or escape).
|
// shift-tab, or escape).
|
||||||
done func(tcell.Key)
|
done func(tcell.Key)
|
||||||
|
|
||||||
|
// A callback function set by the Form class and called when the user leaves
|
||||||
|
// this form item.
|
||||||
|
finished func(tcell.Key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDropDown returns a new drop-down.
|
// NewDropDown returns a new drop-down.
|
||||||
@ -113,6 +121,13 @@ func (d *DropDown) GetLabel() string {
|
|||||||
return d.label
|
return d.label
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetLabelWidth sets the screen width of the label. A value of 0 will cause the
|
||||||
|
// primitive to use the width of the label string.
|
||||||
|
func (d *DropDown) SetLabelWidth(width int) *DropDown {
|
||||||
|
d.labelWidth = width
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
// SetLabelColor sets the color of the label.
|
// SetLabelColor sets the color of the label.
|
||||||
func (d *DropDown) SetLabelColor(color tcell.Color) *DropDown {
|
func (d *DropDown) SetLabelColor(color tcell.Color) *DropDown {
|
||||||
d.labelColor = color
|
d.labelColor = color
|
||||||
@ -140,8 +155,8 @@ func (d *DropDown) SetPrefixTextColor(color tcell.Color) *DropDown {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetFormAttributes sets attributes shared by all form items.
|
// SetFormAttributes sets attributes shared by all form items.
|
||||||
func (d *DropDown) SetFormAttributes(label string, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem {
|
func (d *DropDown) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem {
|
||||||
d.label = label
|
d.labelWidth = labelWidth
|
||||||
d.labelColor = labelColor
|
d.labelColor = labelColor
|
||||||
d.backgroundColor = bgColor
|
d.backgroundColor = bgColor
|
||||||
d.fieldTextColor = fieldTextColor
|
d.fieldTextColor = fieldTextColor
|
||||||
@ -210,9 +225,10 @@ func (d *DropDown) SetDoneFunc(handler func(key tcell.Key)) *DropDown {
|
|||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFinishedFunc calls SetDoneFunc().
|
// SetFinishedFunc sets a callback invoked when the user leaves this form item.
|
||||||
func (d *DropDown) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
|
func (d *DropDown) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
|
||||||
return d.SetDoneFunc(handler)
|
d.finished = handler
|
||||||
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws this primitive onto the screen.
|
// Draw draws this primitive onto the screen.
|
||||||
@ -227,8 +243,17 @@ func (d *DropDown) Draw(screen tcell.Screen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw label.
|
// Draw label.
|
||||||
|
if d.labelWidth > 0 {
|
||||||
|
labelWidth := d.labelWidth
|
||||||
|
if labelWidth > rightLimit-x {
|
||||||
|
labelWidth = rightLimit - x
|
||||||
|
}
|
||||||
|
Print(screen, d.label, x, y, labelWidth, AlignLeft, d.labelColor)
|
||||||
|
x += labelWidth
|
||||||
|
} else {
|
||||||
_, drawnWidth := Print(screen, d.label, x, y, rightLimit-x, AlignLeft, d.labelColor)
|
_, drawnWidth := Print(screen, d.label, x, y, rightLimit-x, AlignLeft, d.labelColor)
|
||||||
x += drawnWidth
|
x += drawnWidth
|
||||||
|
}
|
||||||
|
|
||||||
// What's the longest option text?
|
// What's the longest option text?
|
||||||
maxWidth := 0
|
maxWidth := 0
|
||||||
@ -359,6 +384,9 @@ func (d *DropDown) InputHandler() func(event *tcell.EventKey, setFocus func(p Pr
|
|||||||
if d.done != nil {
|
if d.done != nil {
|
||||||
d.done(key)
|
d.done(key)
|
||||||
}
|
}
|
||||||
|
if d.finished != nil {
|
||||||
|
d.finished(key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
4
vendor/maunium.net/go/tview/flex.go
generated
vendored
4
vendor/maunium.net/go/tview/flex.go
generated
vendored
@ -69,8 +69,8 @@ func (f *Flex) SetFullScreen(fullScreen bool) *Flex {
|
|||||||
// that its size is flexible and may be changed. The "proportion" argument
|
// that its size is flexible and may be changed. The "proportion" argument
|
||||||
// defines the relative size of the item compared to other flexible-size items.
|
// defines the relative size of the item compared to other flexible-size items.
|
||||||
// For example, items with a proportion of 2 will be twice as large as items
|
// For example, items with a proportion of 2 will be twice as large as items
|
||||||
// with a proportion of 1. Must be at least 1 if fixedSize > 0 (ignored
|
// with a proportion of 1. The proportion must be at least 1 if fixedSize == 0
|
||||||
// otherwise)
|
// (ignored otherwise).
|
||||||
//
|
//
|
||||||
// If "focus" is set to true, the item will receive focus when the Flex
|
// If "focus" is set to true, the item will receive focus when the Flex
|
||||||
// primitive receives focus. If multiple items have the "focus" flag set to
|
// primitive receives focus. If multiple items have the "focus" flag set to
|
||||||
|
36
vendor/maunium.net/go/tview/form.go
generated
vendored
36
vendor/maunium.net/go/tview/form.go
generated
vendored
@ -1,8 +1,6 @@
|
|||||||
package tview
|
package tview
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"maunium.net/go/tcell"
|
"maunium.net/go/tcell"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,7 +18,7 @@ type FormItem interface {
|
|||||||
GetLabel() string
|
GetLabel() string
|
||||||
|
|
||||||
// SetFormAttributes sets a number of item attributes at once.
|
// SetFormAttributes sets a number of item attributes at once.
|
||||||
SetFormAttributes(label string, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem
|
SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem
|
||||||
|
|
||||||
// GetFieldWidth returns the width of the form item's field (the area which
|
// GetFieldWidth returns the width of the form item's field (the area which
|
||||||
// is manipulated by the user) in number of screen cells. A value of 0
|
// is manipulated by the user) in number of screen cells. A value of 0
|
||||||
@ -233,7 +231,14 @@ func (f *Form) Clear(includeButtons bool) *Form {
|
|||||||
|
|
||||||
// AddFormItem adds a new item to the form. This can be used to add your own
|
// AddFormItem adds a new item to the form. This can be used to add your own
|
||||||
// objects to the form. Note, however, that the Form class will override some
|
// objects to the form. Note, however, that the Form class will override some
|
||||||
// of its attributes to make it work in the form context.
|
// of its attributes to make it work in the form context. Specifically, these
|
||||||
|
// are:
|
||||||
|
//
|
||||||
|
// - The label width
|
||||||
|
// - The label color
|
||||||
|
// - The background color
|
||||||
|
// - The field text color
|
||||||
|
// - The field background color
|
||||||
func (f *Form) AddFormItem(item FormItem) *Form {
|
func (f *Form) AddFormItem(item FormItem) *Form {
|
||||||
f.items = append(f.items, item)
|
f.items = append(f.items, item)
|
||||||
return f
|
return f
|
||||||
@ -246,6 +251,18 @@ func (f *Form) GetFormItem(index int) FormItem {
|
|||||||
return f.items[index]
|
return f.items[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFormItemByLabel returns the first form element with the given label. If
|
||||||
|
// no such element is found, nil is returned. Buttons are not searched and will
|
||||||
|
// therefore not be returned.
|
||||||
|
func (f *Form) GetFormItemByLabel(label string) FormItem {
|
||||||
|
for _, item := range f.items {
|
||||||
|
if item.GetLabel() == label {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetCancelFunc sets a handler which is called when the user hits the Escape
|
// SetCancelFunc sets a handler which is called when the user hits the Escape
|
||||||
// key.
|
// key.
|
||||||
func (f *Form) SetCancelFunc(callback func()) *Form {
|
func (f *Form) SetCancelFunc(callback func()) *Form {
|
||||||
@ -267,8 +284,7 @@ func (f *Form) Draw(screen tcell.Screen) {
|
|||||||
// Find the longest label.
|
// Find the longest label.
|
||||||
var maxLabelWidth int
|
var maxLabelWidth int
|
||||||
for _, item := range f.items {
|
for _, item := range f.items {
|
||||||
label := strings.TrimSpace(item.GetLabel())
|
labelWidth := StringWidth(item.GetLabel())
|
||||||
labelWidth := StringWidth(label)
|
|
||||||
if labelWidth > maxLabelWidth {
|
if labelWidth > maxLabelWidth {
|
||||||
maxLabelWidth = labelWidth
|
maxLabelWidth = labelWidth
|
||||||
}
|
}
|
||||||
@ -280,20 +296,18 @@ func (f *Form) Draw(screen tcell.Screen) {
|
|||||||
var focusedPosition struct{ x, y, width, height int }
|
var focusedPosition struct{ x, y, width, height int }
|
||||||
for index, item := range f.items {
|
for index, item := range f.items {
|
||||||
// Calculate the space needed.
|
// Calculate the space needed.
|
||||||
label := strings.TrimSpace(item.GetLabel())
|
labelWidth := StringWidth(item.GetLabel())
|
||||||
labelWidth := StringWidth(label)
|
|
||||||
var itemWidth int
|
var itemWidth int
|
||||||
if f.horizontal {
|
if f.horizontal {
|
||||||
fieldWidth := item.GetFieldWidth()
|
fieldWidth := item.GetFieldWidth()
|
||||||
if fieldWidth == 0 {
|
if fieldWidth == 0 {
|
||||||
fieldWidth = DefaultFormFieldWidth
|
fieldWidth = DefaultFormFieldWidth
|
||||||
}
|
}
|
||||||
label += " "
|
|
||||||
labelWidth++
|
labelWidth++
|
||||||
itemWidth = labelWidth + fieldWidth
|
itemWidth = labelWidth + fieldWidth
|
||||||
} else {
|
} else {
|
||||||
// We want all fields to align vertically.
|
// We want all fields to align vertically.
|
||||||
label += strings.Repeat(" ", maxLabelWidth-labelWidth)
|
labelWidth = maxLabelWidth
|
||||||
itemWidth = width
|
itemWidth = width
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +322,7 @@ func (f *Form) Draw(screen tcell.Screen) {
|
|||||||
itemWidth = rightLimit - x
|
itemWidth = rightLimit - x
|
||||||
}
|
}
|
||||||
item.SetFormAttributes(
|
item.SetFormAttributes(
|
||||||
label,
|
labelWidth,
|
||||||
f.labelColor,
|
f.labelColor,
|
||||||
f.backgroundColor,
|
f.backgroundColor,
|
||||||
f.fieldTextColor,
|
f.fieldTextColor,
|
||||||
|
2
vendor/maunium.net/go/tview/grid.go
generated
vendored
2
vendor/maunium.net/go/tview/grid.go
generated
vendored
@ -258,7 +258,7 @@ func (g *Grid) HasFocus() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return g.hasFocus
|
||||||
}
|
}
|
||||||
|
|
||||||
// InputHandler returns the handler for this primitive.
|
// InputHandler returns the handler for this primitive.
|
||||||
|
44
vendor/maunium.net/go/tview/inputfield.go
generated
vendored
44
vendor/maunium.net/go/tview/inputfield.go
generated
vendored
@ -41,6 +41,10 @@ type InputField struct {
|
|||||||
// The text color of the placeholder.
|
// The text color of the placeholder.
|
||||||
placeholderTextColor tcell.Color
|
placeholderTextColor tcell.Color
|
||||||
|
|
||||||
|
// The screen width of the label area. A value of 0 means use the width of
|
||||||
|
// the label text.
|
||||||
|
labelWidth int
|
||||||
|
|
||||||
// The screen width of the input area. A value of 0 means extend as much as
|
// The screen width of the input area. A value of 0 means extend as much as
|
||||||
// possible.
|
// possible.
|
||||||
fieldWidth int
|
fieldWidth int
|
||||||
@ -59,6 +63,10 @@ type InputField struct {
|
|||||||
// are done entering text. The key which was pressed is provided (tab,
|
// are done entering text. The key which was pressed is provided (tab,
|
||||||
// shift-tab, enter, or escape).
|
// shift-tab, enter, or escape).
|
||||||
done func(tcell.Key)
|
done func(tcell.Key)
|
||||||
|
|
||||||
|
// A callback function set by the Form class and called when the user leaves
|
||||||
|
// this form item.
|
||||||
|
finished func(tcell.Key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInputField returns a new input field.
|
// NewInputField returns a new input field.
|
||||||
@ -97,6 +105,13 @@ func (i *InputField) GetLabel() string {
|
|||||||
return i.label
|
return i.label
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetLabelWidth sets the screen width of the label. A value of 0 will cause the
|
||||||
|
// primitive to use the width of the label string.
|
||||||
|
func (i *InputField) SetLabelWidth(width int) *InputField {
|
||||||
|
i.labelWidth = width
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
// SetPlaceholder sets the text to be displayed when the input text is empty.
|
// SetPlaceholder sets the text to be displayed when the input text is empty.
|
||||||
func (i *InputField) SetPlaceholder(text string) *InputField {
|
func (i *InputField) SetPlaceholder(text string) *InputField {
|
||||||
i.placeholder = text
|
i.placeholder = text
|
||||||
@ -121,15 +136,15 @@ func (i *InputField) SetFieldTextColor(color tcell.Color) *InputField {
|
|||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPlaceholderExtColor sets the text color of placeholder text.
|
// SetPlaceholderTextColor sets the text color of placeholder text.
|
||||||
func (i *InputField) SetPlaceholderExtColor(color tcell.Color) *InputField {
|
func (i *InputField) SetPlaceholderTextColor(color tcell.Color) *InputField {
|
||||||
i.placeholderTextColor = color
|
i.placeholderTextColor = color
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFormAttributes sets attributes shared by all form items.
|
// SetFormAttributes sets attributes shared by all form items.
|
||||||
func (i *InputField) SetFormAttributes(label string, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem {
|
func (i *InputField) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem {
|
||||||
i.label = label
|
i.labelWidth = labelWidth
|
||||||
i.labelColor = labelColor
|
i.labelColor = labelColor
|
||||||
i.backgroundColor = bgColor
|
i.backgroundColor = bgColor
|
||||||
i.fieldTextColor = fieldTextColor
|
i.fieldTextColor = fieldTextColor
|
||||||
@ -186,9 +201,10 @@ func (i *InputField) SetDoneFunc(handler func(key tcell.Key)) *InputField {
|
|||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFinishedFunc calls SetDoneFunc().
|
// SetFinishedFunc sets a callback invoked when the user leaves this form item.
|
||||||
func (i *InputField) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
|
func (i *InputField) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
|
||||||
return i.SetDoneFunc(handler)
|
i.finished = handler
|
||||||
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw draws this primitive onto the screen.
|
// Draw draws this primitive onto the screen.
|
||||||
@ -203,8 +219,17 @@ func (i *InputField) Draw(screen tcell.Screen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw label.
|
// Draw label.
|
||||||
|
if i.labelWidth > 0 {
|
||||||
|
labelWidth := i.labelWidth
|
||||||
|
if labelWidth > rightLimit-x {
|
||||||
|
labelWidth = rightLimit - x
|
||||||
|
}
|
||||||
|
Print(screen, i.label, x, y, labelWidth, AlignLeft, i.labelColor)
|
||||||
|
x += labelWidth
|
||||||
|
} else {
|
||||||
_, drawnWidth := Print(screen, i.label, x, y, rightLimit-x, AlignLeft, i.labelColor)
|
_, drawnWidth := Print(screen, i.label, x, y, rightLimit-x, AlignLeft, i.labelColor)
|
||||||
x += drawnWidth
|
x += drawnWidth
|
||||||
|
}
|
||||||
|
|
||||||
// Draw input area.
|
// Draw input area.
|
||||||
fieldWidth := i.fieldWidth
|
fieldWidth := i.fieldWidth
|
||||||
@ -280,7 +305,11 @@ func (i *InputField) setCursor(screen tcell.Screen) {
|
|||||||
if i.fieldWidth > 0 && fieldWidth > i.fieldWidth-1 {
|
if i.fieldWidth > 0 && fieldWidth > i.fieldWidth-1 {
|
||||||
fieldWidth = i.fieldWidth - 1
|
fieldWidth = i.fieldWidth - 1
|
||||||
}
|
}
|
||||||
|
if i.labelWidth > 0 {
|
||||||
|
x += i.labelWidth + fieldWidth
|
||||||
|
} else {
|
||||||
x += StringWidth(i.label) + fieldWidth
|
x += StringWidth(i.label) + fieldWidth
|
||||||
|
}
|
||||||
if x >= rightLimit {
|
if x >= rightLimit {
|
||||||
x = rightLimit - 1
|
x = rightLimit - 1
|
||||||
}
|
}
|
||||||
@ -323,6 +352,9 @@ func (i *InputField) InputHandler() func(event *tcell.EventKey, setFocus func(p
|
|||||||
if i.done != nil {
|
if i.done != nil {
|
||||||
i.done(key)
|
i.done(key)
|
||||||
}
|
}
|
||||||
|
if i.finished != nil {
|
||||||
|
i.finished(key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
20
vendor/maunium.net/go/tview/list.go
generated
vendored
20
vendor/maunium.net/go/tview/list.go
generated
vendored
@ -173,6 +173,26 @@ func (l *List) AddItem(mainText, secondaryText string, shortcut rune, selected f
|
|||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetItemCount returns the number of items in the list.
|
||||||
|
func (l *List) GetItemCount() int {
|
||||||
|
return len(l.items)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetItemText returns an item's texts (main and secondary). Panics if the index
|
||||||
|
// is out of range.
|
||||||
|
func (l *List) GetItemText(index int) (main, secondary string) {
|
||||||
|
return l.items[index].MainText, l.items[index].SecondaryText
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetItemText sets an item's main and secondary text. Panics if the index is
|
||||||
|
// out of range.
|
||||||
|
func (l *List) SetItemText(index int, main, secondary string) *List {
|
||||||
|
item := l.items[index]
|
||||||
|
item.MainText = main
|
||||||
|
item.SecondaryText = secondary
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
// Clear removes all items from the list.
|
// Clear removes all items from the list.
|
||||||
func (l *List) Clear() *List {
|
func (l *List) Clear() *List {
|
||||||
l.items = nil
|
l.items = nil
|
||||||
|
2
vendor/maunium.net/go/tview/primitive.go
generated
vendored
2
vendor/maunium.net/go/tview/primitive.go
generated
vendored
@ -36,6 +36,8 @@ type Primitive interface {
|
|||||||
|
|
||||||
MouseHandler() func(event *tcell.EventMouse, setFocus func(p Primitive))
|
MouseHandler() func(event *tcell.EventMouse, setFocus func(p Primitive))
|
||||||
|
|
||||||
|
PasteHandler() func(event *tcell.EventPaste)
|
||||||
|
|
||||||
// Focus is called by the application when the primitive receives focus.
|
// Focus is called by the application when the primitive receives focus.
|
||||||
// Implementers may call delegate() to pass the focus on to another primitive.
|
// Implementers may call delegate() to pass the focus on to another primitive.
|
||||||
Focus(delegate func(p Primitive))
|
Focus(delegate func(p Primitive))
|
||||||
|
2
vendor/maunium.net/go/tview/table.go
generated
vendored
2
vendor/maunium.net/go/tview/table.go
generated
vendored
@ -590,7 +590,7 @@ ColumnLoop:
|
|||||||
expansion := 0
|
expansion := 0
|
||||||
for _, row := range rows {
|
for _, row := range rows {
|
||||||
if cell := getCell(row, column); cell != nil {
|
if cell := getCell(row, column); cell != nil {
|
||||||
cellWidth := StringWidth(cell.Text)
|
_, _, _, _, cellWidth := decomposeString(cell.Text)
|
||||||
if cell.MaxWidth > 0 && cell.MaxWidth < cellWidth {
|
if cell.MaxWidth > 0 && cell.MaxWidth < cellWidth {
|
||||||
cellWidth = cell.MaxWidth
|
cellWidth = cell.MaxWidth
|
||||||
}
|
}
|
||||||
|
71
vendor/maunium.net/go/tview/textview.go
generated
vendored
71
vendor/maunium.net/go/tview/textview.go
generated
vendored
@ -8,6 +8,7 @@ import (
|
|||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"maunium.net/go/tcell"
|
"maunium.net/go/tcell"
|
||||||
|
"github.com/lucasb-eyer/go-colorful"
|
||||||
runewidth "github.com/mattn/go-runewidth"
|
runewidth "github.com/mattn/go-runewidth"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,7 +22,9 @@ type textViewIndex struct {
|
|||||||
Pos int // The index into the "buffer" string (byte position).
|
Pos int // The index into the "buffer" string (byte position).
|
||||||
NextPos int // The (byte) index of the next character in this buffer line.
|
NextPos int // The (byte) index of the next character in this buffer line.
|
||||||
Width int // The screen width of this line.
|
Width int // The screen width of this line.
|
||||||
Color tcell.Color // The starting color.
|
ForegroundColor string // The starting foreground color ("" = don't change, "-" = reset).
|
||||||
|
BackgroundColor string // The starting background color ("" = don't change, "-" = reset).
|
||||||
|
Attributes string // The starting attributes ("" = don't change, "-" = reset).
|
||||||
Region string // The starting region ID.
|
Region string // The starting region ID.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,7 +502,6 @@ func (t *TextView) reindexBuffer(width int) {
|
|||||||
// Initial states.
|
// Initial states.
|
||||||
regionID := ""
|
regionID := ""
|
||||||
var highlighted bool
|
var highlighted bool
|
||||||
color := t.textColor
|
|
||||||
|
|
||||||
// Go through each line in the buffer.
|
// Go through each line in the buffer.
|
||||||
for bufferIndex, str := range t.buffer {
|
for bufferIndex, str := range t.buffer {
|
||||||
@ -507,11 +509,10 @@ func (t *TextView) reindexBuffer(width int) {
|
|||||||
var (
|
var (
|
||||||
colorTagIndices [][]int
|
colorTagIndices [][]int
|
||||||
colorTags [][]string
|
colorTags [][]string
|
||||||
|
escapeIndices [][]int
|
||||||
)
|
)
|
||||||
if t.dynamicColors {
|
if t.dynamicColors {
|
||||||
colorTagIndices = colorPattern.FindAllStringIndex(str, -1)
|
colorTagIndices, colorTags, escapeIndices, str, _ = decomposeString(str)
|
||||||
colorTags = colorPattern.FindAllStringSubmatch(str, -1)
|
|
||||||
str = colorPattern.ReplaceAllString(str, "")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all regions in this line. Then remove them.
|
// Find all regions in this line. Then remove them.
|
||||||
@ -523,14 +524,12 @@ func (t *TextView) reindexBuffer(width int) {
|
|||||||
regionIndices = regionPattern.FindAllStringIndex(str, -1)
|
regionIndices = regionPattern.FindAllStringIndex(str, -1)
|
||||||
regions = regionPattern.FindAllStringSubmatch(str, -1)
|
regions = regionPattern.FindAllStringSubmatch(str, -1)
|
||||||
str = regionPattern.ReplaceAllString(str, "")
|
str = regionPattern.ReplaceAllString(str, "")
|
||||||
}
|
if !t.dynamicColors {
|
||||||
|
// We haven't detected escape tags yet. Do it now.
|
||||||
// Find all replace tags in this line. Then replace them.
|
|
||||||
var escapeIndices [][]int
|
|
||||||
if t.dynamicColors || t.regions {
|
|
||||||
escapeIndices = escapePattern.FindAllStringIndex(str, -1)
|
escapeIndices = escapePattern.FindAllStringIndex(str, -1)
|
||||||
str = escapePattern.ReplaceAllString(str, "[$1$2]")
|
str = escapePattern.ReplaceAllString(str, "[$1$2]")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Split the line if required.
|
// Split the line if required.
|
||||||
var splitLines []string
|
var splitLines []string
|
||||||
@ -559,12 +558,17 @@ func (t *TextView) reindexBuffer(width int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create index from split lines.
|
// Create index from split lines.
|
||||||
var originalPos, colorPos, regionPos, escapePos int
|
var (
|
||||||
|
originalPos, colorPos, regionPos, escapePos int
|
||||||
|
foregroundColor, backgroundColor, attributes string
|
||||||
|
)
|
||||||
for _, splitLine := range splitLines {
|
for _, splitLine := range splitLines {
|
||||||
line := &textViewIndex{
|
line := &textViewIndex{
|
||||||
Line: bufferIndex,
|
Line: bufferIndex,
|
||||||
Pos: originalPos,
|
Pos: originalPos,
|
||||||
Color: color,
|
ForegroundColor: foregroundColor,
|
||||||
|
BackgroundColor: backgroundColor,
|
||||||
|
Attributes: attributes,
|
||||||
Region: regionID,
|
Region: regionID,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,7 +578,7 @@ func (t *TextView) reindexBuffer(width int) {
|
|||||||
if colorPos < len(colorTagIndices) && colorTagIndices[colorPos][0] <= originalPos+lineLength {
|
if colorPos < len(colorTagIndices) && colorTagIndices[colorPos][0] <= originalPos+lineLength {
|
||||||
// Process color tags.
|
// Process color tags.
|
||||||
originalPos += colorTagIndices[colorPos][1] - colorTagIndices[colorPos][0]
|
originalPos += colorTagIndices[colorPos][1] - colorTagIndices[colorPos][0]
|
||||||
color = tcell.GetColor(colorTags[colorPos][1])
|
foregroundColor, backgroundColor, attributes = styleFromTag(foregroundColor, backgroundColor, attributes, colorTags[colorPos])
|
||||||
colorPos++
|
colorPos++
|
||||||
} else if regionPos < len(regionIndices) && regionIndices[regionPos][0] <= originalPos+lineLength {
|
} else if regionPos < len(regionIndices) && regionIndices[regionPos][0] <= originalPos+lineLength {
|
||||||
// Process region tags.
|
// Process region tags.
|
||||||
@ -712,6 +716,7 @@ func (t *TextView) Draw(screen tcell.Screen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw the buffer.
|
// Draw the buffer.
|
||||||
|
defaultStyle := tcell.StyleDefault.Foreground(t.textColor)
|
||||||
for line := t.lineOffset; line < len(t.index); line++ {
|
for line := t.lineOffset; line < len(t.index); line++ {
|
||||||
// Are we done?
|
// Are we done?
|
||||||
if line-t.lineOffset >= height {
|
if line-t.lineOffset >= height {
|
||||||
@ -721,17 +726,19 @@ func (t *TextView) Draw(screen tcell.Screen) {
|
|||||||
// Get the text for this line.
|
// Get the text for this line.
|
||||||
index := t.index[line]
|
index := t.index[line]
|
||||||
text := t.buffer[index.Line][index.Pos:index.NextPos]
|
text := t.buffer[index.Line][index.Pos:index.NextPos]
|
||||||
color := index.Color
|
foregroundColor := index.ForegroundColor
|
||||||
|
backgroundColor := index.BackgroundColor
|
||||||
|
attributes := index.Attributes
|
||||||
regionID := index.Region
|
regionID := index.Region
|
||||||
|
|
||||||
// Get color tags.
|
// Get color tags.
|
||||||
var (
|
var (
|
||||||
colorTagIndices [][]int
|
colorTagIndices [][]int
|
||||||
colorTags [][]string
|
colorTags [][]string
|
||||||
|
escapeIndices [][]int
|
||||||
)
|
)
|
||||||
if t.dynamicColors {
|
if t.dynamicColors {
|
||||||
colorTagIndices = colorPattern.FindAllStringIndex(text, -1)
|
colorTagIndices, colorTags, escapeIndices, _, _ = decomposeString(text)
|
||||||
colorTags = colorPattern.FindAllStringSubmatch(text, -1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get regions.
|
// Get regions.
|
||||||
@ -742,13 +749,10 @@ func (t *TextView) Draw(screen tcell.Screen) {
|
|||||||
if t.regions {
|
if t.regions {
|
||||||
regionIndices = regionPattern.FindAllStringIndex(text, -1)
|
regionIndices = regionPattern.FindAllStringIndex(text, -1)
|
||||||
regions = regionPattern.FindAllStringSubmatch(text, -1)
|
regions = regionPattern.FindAllStringSubmatch(text, -1)
|
||||||
}
|
if !t.dynamicColors {
|
||||||
|
|
||||||
// Get escape tags.
|
|
||||||
var escapeIndices [][]int
|
|
||||||
if t.dynamicColors || t.regions {
|
|
||||||
escapeIndices = escapePattern.FindAllStringIndex(text, -1)
|
escapeIndices = escapePattern.FindAllStringIndex(text, -1)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the position of the line.
|
// Calculate the position of the line.
|
||||||
var skip, posX int
|
var skip, posX int
|
||||||
@ -770,7 +774,7 @@ func (t *TextView) Draw(screen tcell.Screen) {
|
|||||||
// Get the color.
|
// Get the color.
|
||||||
if currentTag < len(colorTags) && pos >= colorTagIndices[currentTag][0] && pos < colorTagIndices[currentTag][1] {
|
if currentTag < len(colorTags) && pos >= colorTagIndices[currentTag][0] && pos < colorTagIndices[currentTag][1] {
|
||||||
if pos == colorTagIndices[currentTag][1]-1 {
|
if pos == colorTagIndices[currentTag][1]-1 {
|
||||||
color = tcell.GetColor(colorTags[currentTag][1])
|
foregroundColor, backgroundColor, attributes = styleFromTag(foregroundColor, backgroundColor, attributes, colorTags[currentTag])
|
||||||
currentTag++
|
currentTag++
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -811,13 +815,32 @@ func (t *TextView) Draw(screen tcell.Screen) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mix the existing style with the new style.
|
||||||
|
_, _, existingStyle, _ := screen.GetContent(x+posX, y+line-t.lineOffset)
|
||||||
|
_, background, _ := existingStyle.Decompose()
|
||||||
|
style := overlayStyle(background, defaultStyle, foregroundColor, backgroundColor, attributes)
|
||||||
|
|
||||||
// Do we highlight this character?
|
// Do we highlight this character?
|
||||||
style := tcell.StyleDefault.Background(t.backgroundColor).Foreground(color)
|
var highlighted bool
|
||||||
if len(regionID) > 0 {
|
if len(regionID) > 0 {
|
||||||
if _, ok := t.highlights[regionID]; ok {
|
if _, ok := t.highlights[regionID]; ok {
|
||||||
style = tcell.StyleDefault.Background(color).Foreground(t.backgroundColor)
|
highlighted = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if highlighted {
|
||||||
|
fg, bg, _ := style.Decompose()
|
||||||
|
if bg == tcell.ColorDefault {
|
||||||
|
r, g, b := fg.RGB()
|
||||||
|
c := colorful.Color{R: float64(r) / 255, G: float64(g) / 255, B: float64(b) / 255}
|
||||||
|
_, _, li := c.Hcl()
|
||||||
|
if li < .5 {
|
||||||
|
bg = tcell.ColorWhite
|
||||||
|
} else {
|
||||||
|
bg = tcell.ColorBlack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
style = style.Background(fg).Foreground(bg)
|
||||||
|
}
|
||||||
|
|
||||||
// Draw the character.
|
// Draw the character.
|
||||||
for offset := 0; offset < chWidth; offset++ {
|
for offset := 0; offset < chWidth; offset++ {
|
||||||
|
216
vendor/maunium.net/go/tview/util.go
generated
vendored
216
vendor/maunium.net/go/tview/util.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package tview
|
package tview
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -104,13 +105,21 @@ var joints = map[string]rune{
|
|||||||
|
|
||||||
// Common regular expressions.
|
// Common regular expressions.
|
||||||
var (
|
var (
|
||||||
colorPattern = regexp.MustCompile(`\[([a-zA-Z]+|#[0-9a-zA-Z]{6})\]`)
|
colorPattern = regexp.MustCompile(`\[([a-zA-Z]+|#[0-9a-zA-Z]{6}|\-)?(:([a-zA-Z]+|#[0-9a-zA-Z]{6}|\-)?(:([lbdru]+|\-)?)?)?\]`)
|
||||||
regionPattern = regexp.MustCompile(`\["([a-zA-Z0-9_,;: \-\.]*)"\]`)
|
regionPattern = regexp.MustCompile(`\["([a-zA-Z0-9_,;: \-\.]*)"\]`)
|
||||||
escapePattern = regexp.MustCompile(`\[("[a-zA-Z0-9_,;: \-\.]*"|[a-zA-Z]+|#[0-9a-zA-Z]{6})\[(\[*)\]`)
|
escapePattern = regexp.MustCompile(`\[([a-zA-Z0-9_,;: \-\."#]+)\[(\[*)\]`)
|
||||||
|
nonEscapePattern = regexp.MustCompile(`(\[[a-zA-Z0-9_,;: \-\."#]+\[*)\]`)
|
||||||
boundaryPattern = regexp.MustCompile("([[:punct:]]\\s*|\\s+)")
|
boundaryPattern = regexp.MustCompile("([[:punct:]]\\s*|\\s+)")
|
||||||
spacePattern = regexp.MustCompile(`\s+`)
|
spacePattern = regexp.MustCompile(`\s+`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Positions of substrings in regular expressions.
|
||||||
|
const (
|
||||||
|
colorForegroundPos = 1
|
||||||
|
colorBackgroundPos = 3
|
||||||
|
colorFlagPos = 5
|
||||||
|
)
|
||||||
|
|
||||||
// Predefined InputField acceptance functions.
|
// Predefined InputField acceptance functions.
|
||||||
var (
|
var (
|
||||||
// InputFieldInteger accepts integers.
|
// InputFieldInteger accepts integers.
|
||||||
@ -150,40 +159,168 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// styleFromTag takes the given style, defined by a foreground color (fgColor),
|
||||||
|
// a background color (bgColor), and style attributes, and modifies it based on
|
||||||
|
// the substrings (tagSubstrings) extracted by the regular expression for color
|
||||||
|
// tags. The new colors and attributes are returned where empty strings mean
|
||||||
|
// "don't modify" and a dash ("-") means "reset to default".
|
||||||
|
func styleFromTag(fgColor, bgColor, attributes string, tagSubstrings []string) (newFgColor, newBgColor, newAttributes string) {
|
||||||
|
if tagSubstrings[colorForegroundPos] != "" {
|
||||||
|
color := tagSubstrings[colorForegroundPos]
|
||||||
|
if color == "-" {
|
||||||
|
fgColor = "-"
|
||||||
|
} else if color != "" {
|
||||||
|
fgColor = color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tagSubstrings[colorBackgroundPos-1] != "" {
|
||||||
|
color := tagSubstrings[colorBackgroundPos]
|
||||||
|
if color == "-" {
|
||||||
|
bgColor = "-"
|
||||||
|
} else if color != "" {
|
||||||
|
bgColor = color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tagSubstrings[colorFlagPos-1] != "" {
|
||||||
|
flags := tagSubstrings[colorFlagPos]
|
||||||
|
if flags == "-" {
|
||||||
|
attributes = "-"
|
||||||
|
} else if flags != "" {
|
||||||
|
attributes = flags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fgColor, bgColor, attributes
|
||||||
|
}
|
||||||
|
|
||||||
|
// overlayStyle mixes a background color with a foreground color (fgColor),
|
||||||
|
// a (possibly new) background color (bgColor), and style attributes, and
|
||||||
|
// returns the resulting style. For a definition of the colors and attributes,
|
||||||
|
// see styleFromTag(). Reset instructions cause the corresponding part of the
|
||||||
|
// default style to be used.
|
||||||
|
func overlayStyle(background tcell.Color, defaultStyle tcell.Style, fgColor, bgColor, attributes string) tcell.Style {
|
||||||
|
defFg, defBg, defAttr := defaultStyle.Decompose()
|
||||||
|
style := defaultStyle.Background(background)
|
||||||
|
|
||||||
|
if fgColor == "-" {
|
||||||
|
style = style.Foreground(defFg)
|
||||||
|
} else if fgColor != "" {
|
||||||
|
style = style.Foreground(tcell.GetColor(fgColor))
|
||||||
|
}
|
||||||
|
|
||||||
|
if bgColor == "-" {
|
||||||
|
style = style.Background(defBg)
|
||||||
|
} else if bgColor != "" {
|
||||||
|
style = style.Background(tcell.GetColor(bgColor))
|
||||||
|
}
|
||||||
|
|
||||||
|
if attributes == "-" {
|
||||||
|
style = style.Bold(defAttr&tcell.AttrBold > 0)
|
||||||
|
style = style.Blink(defAttr&tcell.AttrBlink > 0)
|
||||||
|
style = style.Reverse(defAttr&tcell.AttrReverse > 0)
|
||||||
|
style = style.Underline(defAttr&tcell.AttrUnderline > 0)
|
||||||
|
style = style.Dim(defAttr&tcell.AttrDim > 0)
|
||||||
|
} else if attributes != "" {
|
||||||
|
style = style.Normal()
|
||||||
|
for _, flag := range attributes {
|
||||||
|
switch flag {
|
||||||
|
case 'l':
|
||||||
|
style = style.Blink(true)
|
||||||
|
case 'b':
|
||||||
|
style = style.Bold(true)
|
||||||
|
case 'd':
|
||||||
|
style = style.Dim(true)
|
||||||
|
case 'r':
|
||||||
|
style = style.Reverse(true)
|
||||||
|
case 'u':
|
||||||
|
style = style.Underline(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
|
||||||
|
// decomposeString returns information about a string which may contain color
|
||||||
|
// tags. It returns the indices of the color tags (as returned by
|
||||||
|
// re.FindAllStringIndex()), the color tags themselves (as returned by
|
||||||
|
// re.FindAllStringSubmatch()), the indices of an escaped tags, the string
|
||||||
|
// stripped by any color tags and escaped, and the screen width of the stripped
|
||||||
|
// string.
|
||||||
|
func decomposeString(text string) (colorIndices [][]int, colors [][]string, escapeIndices [][]int, stripped string, width int) {
|
||||||
|
// Get positions of color and escape tags.
|
||||||
|
colorIndices = colorPattern.FindAllStringIndex(text, -1)
|
||||||
|
colors = colorPattern.FindAllStringSubmatch(text, -1)
|
||||||
|
escapeIndices = escapePattern.FindAllStringIndex(text, -1)
|
||||||
|
|
||||||
|
// Because the color pattern detects empty tags, we need to filter them out.
|
||||||
|
for i := len(colorIndices) - 1; i >= 0; i-- {
|
||||||
|
if colorIndices[i][1]-colorIndices[i][0] == 2 {
|
||||||
|
colorIndices = append(colorIndices[:i], colorIndices[i+1:]...)
|
||||||
|
colors = append(colors[:i], colors[i+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the color tags from the original string.
|
||||||
|
var from int
|
||||||
|
buf := make([]byte, 0, len(text))
|
||||||
|
for _, indices := range colorIndices {
|
||||||
|
buf = append(buf, []byte(text[from:indices[0]])...)
|
||||||
|
from = indices[1]
|
||||||
|
}
|
||||||
|
buf = append(buf, text[from:]...)
|
||||||
|
|
||||||
|
// Escape string.
|
||||||
|
stripped = string(escapePattern.ReplaceAll(buf, []byte("[$1$2]")))
|
||||||
|
|
||||||
|
// Get the width of the stripped string.
|
||||||
|
width = runewidth.StringWidth(stripped)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Print prints text onto the screen into the given box at (x,y,maxWidth,1),
|
// Print prints text onto the screen into the given box at (x,y,maxWidth,1),
|
||||||
// not exceeding that box. "align" is one of AlignLeft, AlignCenter, or
|
// not exceeding that box. "align" is one of AlignLeft, AlignCenter, or
|
||||||
// AlignRight. The screen's background color will not be changed.
|
// AlignRight. The screen's background color will not be changed.
|
||||||
//
|
//
|
||||||
// You can change the text color mid-text by inserting a color tag. See the
|
// You can change the colors and text styles mid-text by inserting a color tag.
|
||||||
// package description for details.
|
// See the package description for details.
|
||||||
//
|
//
|
||||||
// Returns the number of actual runes printed (not including color tags) and the
|
// Returns the number of actual runes printed (not including color tags) and the
|
||||||
// actual width used for the printed runes.
|
// actual width used for the printed runes.
|
||||||
func Print(screen tcell.Screen, text string, x, y, maxWidth, align int, color tcell.Color) (int, int) {
|
func Print(screen tcell.Screen, text string, x, y, maxWidth, align int, color tcell.Color) (int, int) {
|
||||||
|
return printWithStyle(screen, text, x, y, maxWidth, align, tcell.StyleDefault.Foreground(color))
|
||||||
|
}
|
||||||
|
|
||||||
|
// printWithStyle works like Print() but it takes a style instead of just a
|
||||||
|
// foreground color.
|
||||||
|
func printWithStyle(screen tcell.Screen, text string, x, y, maxWidth, align int, style tcell.Style) (int, int) {
|
||||||
if maxWidth < 0 {
|
if maxWidth < 0 {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get positions of color and escape tags. Remove them from original string.
|
// Decompose the text.
|
||||||
colorIndices := colorPattern.FindAllStringIndex(text, -1)
|
colorIndices, colors, escapeIndices, strippedText, _ := decomposeString(text)
|
||||||
colors := colorPattern.FindAllStringSubmatch(text, -1)
|
|
||||||
escapeIndices := escapePattern.FindAllStringIndex(text, -1)
|
|
||||||
strippedText := escapePattern.ReplaceAllString(colorPattern.ReplaceAllString(text, ""), "[$1$2]")
|
|
||||||
|
|
||||||
// We deal with runes, not with bytes.
|
// We deal with runes, not with bytes.
|
||||||
runes := []rune(strippedText)
|
runes := []rune(strippedText)
|
||||||
|
|
||||||
// This helper function takes positions for a substring of "runes" and a start
|
// This helper function takes positions for a substring of "runes" and returns
|
||||||
// color and returns the substring with the original tags and the new start
|
// a new string corresponding to this substring, making sure printing that
|
||||||
// color.
|
// substring will observe color tags.
|
||||||
substring := func(from, to int, color tcell.Color) (string, tcell.Color) {
|
substring := func(from, to int) string {
|
||||||
var colorPos, escapePos, runePos, startPos int
|
var (
|
||||||
|
colorPos, escapePos, runePos, startPos int
|
||||||
|
foregroundColor, backgroundColor, attributes string
|
||||||
|
)
|
||||||
for pos := range text {
|
for pos := range text {
|
||||||
// Handle color tags.
|
// Handle color tags.
|
||||||
if colorPos < len(colorIndices) && pos >= colorIndices[colorPos][0] && pos < colorIndices[colorPos][1] {
|
if colorPos < len(colorIndices) && pos >= colorIndices[colorPos][0] && pos < colorIndices[colorPos][1] {
|
||||||
if pos == colorIndices[colorPos][1]-1 {
|
if pos == colorIndices[colorPos][1]-1 {
|
||||||
if runePos <= from {
|
if runePos <= from {
|
||||||
color = tcell.GetColor(colors[colorPos][1])
|
foregroundColor, backgroundColor, attributes = styleFromTag(foregroundColor, backgroundColor, attributes, colors[colorPos])
|
||||||
}
|
}
|
||||||
colorPos++
|
colorPos++
|
||||||
}
|
}
|
||||||
@ -203,13 +340,13 @@ func Print(screen tcell.Screen, text string, x, y, maxWidth, align int, color tc
|
|||||||
if runePos == from {
|
if runePos == from {
|
||||||
startPos = pos
|
startPos = pos
|
||||||
} else if runePos >= to {
|
} else if runePos >= to {
|
||||||
return text[startPos:pos], color
|
return fmt.Sprintf(`[%s:%s:%s]%s`, foregroundColor, backgroundColor, attributes, text[startPos:pos])
|
||||||
}
|
}
|
||||||
|
|
||||||
runePos++
|
runePos++
|
||||||
}
|
}
|
||||||
|
|
||||||
return text[startPos:], color
|
return fmt.Sprintf(`[%s:%s:%s]%s`, foregroundColor, backgroundColor, attributes, text[startPos:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want to reduce everything to AlignLeft.
|
// We want to reduce everything to AlignLeft.
|
||||||
@ -224,17 +361,16 @@ func Print(screen tcell.Screen, text string, x, y, maxWidth, align int, color tc
|
|||||||
width += w
|
width += w
|
||||||
start = index
|
start = index
|
||||||
}
|
}
|
||||||
text, color = substring(start, len(runes), color)
|
return printWithStyle(screen, substring(start, len(runes)), x+maxWidth-width, y, width, AlignLeft, style)
|
||||||
return Print(screen, text, x+maxWidth-width, y, width, AlignLeft, color)
|
|
||||||
} else if align == AlignCenter {
|
} else if align == AlignCenter {
|
||||||
width := runewidth.StringWidth(strippedText)
|
width := runewidth.StringWidth(strippedText)
|
||||||
if width == maxWidth {
|
if width == maxWidth {
|
||||||
// Use the exact space.
|
// Use the exact space.
|
||||||
return Print(screen, text, x, y, maxWidth, AlignLeft, color)
|
return printWithStyle(screen, text, x, y, maxWidth, AlignLeft, style)
|
||||||
} else if width < maxWidth {
|
} else if width < maxWidth {
|
||||||
// We have more space than we need.
|
// We have more space than we need.
|
||||||
half := (maxWidth - width) / 2
|
half := (maxWidth - width) / 2
|
||||||
return Print(screen, text, x+half, y, maxWidth-half, AlignLeft, color)
|
return printWithStyle(screen, text, x+half, y, maxWidth-half, AlignLeft, style)
|
||||||
} else {
|
} else {
|
||||||
// Chop off runes until we have a perfect fit.
|
// Chop off runes until we have a perfect fit.
|
||||||
var choppedLeft, choppedRight, leftIndex, rightIndex int
|
var choppedLeft, choppedRight, leftIndex, rightIndex int
|
||||||
@ -250,20 +386,22 @@ func Print(screen tcell.Screen, text string, x, y, maxWidth, align int, color tc
|
|||||||
rightIndex--
|
rightIndex--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
text, color = substring(leftIndex, rightIndex, color)
|
return printWithStyle(screen, substring(leftIndex, rightIndex), x, y, maxWidth, AlignLeft, style)
|
||||||
return Print(screen, text, x, y, maxWidth, AlignLeft, color)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw text.
|
// Draw text.
|
||||||
drawn := 0
|
drawn := 0
|
||||||
drawnWidth := 0
|
drawnWidth := 0
|
||||||
var colorPos, escapePos int
|
var (
|
||||||
|
colorPos, escapePos int
|
||||||
|
foregroundColor, backgroundColor, attributes string
|
||||||
|
)
|
||||||
for pos, ch := range text {
|
for pos, ch := range text {
|
||||||
// Handle color tags.
|
// Handle color tags.
|
||||||
if colorPos < len(colorIndices) && pos >= colorIndices[colorPos][0] && pos < colorIndices[colorPos][1] {
|
if colorPos < len(colorIndices) && pos >= colorIndices[colorPos][0] && pos < colorIndices[colorPos][1] {
|
||||||
if pos == colorIndices[colorPos][1]-1 {
|
if pos == colorIndices[colorPos][1]-1 {
|
||||||
color = tcell.GetColor(colors[colorPos][1])
|
foregroundColor, backgroundColor, attributes = styleFromTag(foregroundColor, backgroundColor, attributes, colors[colorPos])
|
||||||
colorPos++
|
colorPos++
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -286,11 +424,12 @@ func Print(screen tcell.Screen, text string, x, y, maxWidth, align int, color tc
|
|||||||
finalX := x + drawnWidth
|
finalX := x + drawnWidth
|
||||||
|
|
||||||
// Print the rune.
|
// Print the rune.
|
||||||
_, _, style, _ := screen.GetContent(finalX, y)
|
_, _, finalStyle, _ := screen.GetContent(finalX, y)
|
||||||
style = style.Foreground(color)
|
_, background, _ := finalStyle.Decompose()
|
||||||
|
finalStyle = overlayStyle(background, style, foregroundColor, backgroundColor, attributes)
|
||||||
for offset := 0; offset < chWidth; offset++ {
|
for offset := 0; offset < chWidth; offset++ {
|
||||||
// To avoid undesired effects, we place the same character in all cells.
|
// To avoid undesired effects, we place the same character in all cells.
|
||||||
screen.SetContent(finalX+offset, y, ch, nil, style)
|
screen.SetContent(finalX+offset, y, ch, nil, finalStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
drawn++
|
drawn++
|
||||||
@ -308,7 +447,8 @@ func PrintSimple(screen tcell.Screen, text string, x, y int) {
|
|||||||
// StringWidth returns the width of the given string needed to print it on
|
// StringWidth returns the width of the given string needed to print it on
|
||||||
// screen. The text may contain color tags which are not counted.
|
// screen. The text may contain color tags which are not counted.
|
||||||
func StringWidth(text string) int {
|
func StringWidth(text string) int {
|
||||||
return runewidth.StringWidth(escapePattern.ReplaceAllString(colorPattern.ReplaceAllString(text, ""), "[$1$2]"))
|
_, _, _, _, width := decomposeString(text)
|
||||||
|
return width
|
||||||
}
|
}
|
||||||
|
|
||||||
// WordWrap splits a text such that each resulting line does not exceed the
|
// WordWrap splits a text such that each resulting line does not exceed the
|
||||||
@ -319,13 +459,7 @@ func StringWidth(text string) int {
|
|||||||
//
|
//
|
||||||
// Text is always split at newline characters ('\n').
|
// Text is always split at newline characters ('\n').
|
||||||
func WordWrap(text string, width int) (lines []string) {
|
func WordWrap(text string, width int) (lines []string) {
|
||||||
// Strip color tags.
|
colorTagIndices, _, escapeIndices, strippedText, _ := decomposeString(text)
|
||||||
strippedText := escapePattern.ReplaceAllString(colorPattern.ReplaceAllString(text, ""), "[$1$2]")
|
|
||||||
|
|
||||||
// Keep track of color tags and escape patterns so we can restore the original
|
|
||||||
// indices.
|
|
||||||
colorTagIndices := colorPattern.FindAllStringIndex(text, -1)
|
|
||||||
escapeIndices := escapePattern.FindAllStringIndex(text, -1)
|
|
||||||
|
|
||||||
// Find candidate breakpoints.
|
// Find candidate breakpoints.
|
||||||
breakPoints := boundaryPattern.FindAllStringIndex(strippedText, -1)
|
breakPoints := boundaryPattern.FindAllStringIndex(strippedText, -1)
|
||||||
@ -454,3 +588,13 @@ func PrintJoinedBorder(screen tcell.Screen, x, y int, ch rune, color tcell.Color
|
|||||||
// We only print something if we have something.
|
// We only print something if we have something.
|
||||||
screen.SetContent(x, y, result, nil, style)
|
screen.SetContent(x, y, result, nil, style)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Escape escapes the given text such that color and/or region tags are not
|
||||||
|
// recognized and substituted by the print functions of this package. For
|
||||||
|
// example, to include a tag-like string in a box title or in a TextView:
|
||||||
|
//
|
||||||
|
// box.SetTitle(tview.Escape("[squarebrackets]"))
|
||||||
|
// fmt.Fprint(textView, tview.Escape(`["quoted"]`))
|
||||||
|
func Escape(text string) string {
|
||||||
|
return nonEscapePattern.ReplaceAllString(text, "$1[]")
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user