aboutsummaryrefslogtreecommitdiffstats
path: root/lib/parse
diff options
context:
space:
mode:
authorTim Culverhouse <tim@timculverhouse.com>2024-02-12 06:26:20 -0600
committerRobin Jarry <robin@jarry.cc>2024-02-12 13:48:50 +0100
commita60f2c19a0a962167067547c2a74988012cf2f44 (patch)
treee3c98d3d0f7ac934eb6ee0c4cb19b1a1377cc2a8 /lib/parse
parentcdc90afbaa1a6ff7d0900b6ce904a1e51e31bcd1 (diff)
downloadaerc-a60f2c19a0a962167067547c2a74988012cf2f44.tar.gz
style: use vaxis style everywhere
Replace all tcell.Style objects with vaxis.Style objects Signed-off-by: Tim Culverhouse <tim@timculverhouse.com> Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'lib/parse')
-rw-r--r--lib/parse/ansi.go202
-rw-r--r--lib/parse/ansi_test.go8
2 files changed, 109 insertions, 101 deletions
diff --git a/lib/parse/ansi.go b/lib/parse/ansi.go
index 3a802a51..7fc37834 100644
--- a/lib/parse/ansi.go
+++ b/lib/parse/ansi.go
@@ -12,7 +12,7 @@ import (
"strings"
"git.sr.ht/~rjarry/aerc/log"
- "github.com/gdamore/tcell/v2"
+ "git.sr.ht/~rockorager/vaxis"
"github.com/mattn/go-runewidth"
)
@@ -63,10 +63,10 @@ func StripAnsi(r io.Reader) io.Reader {
type StyledRune struct {
Value rune
Width int
- Style tcell.Style
+ Style vaxis.Style
}
-// RuneBuffer is a buffer of runes styled with tcell.Style objects
+// RuneBuffer is a buffer of runes styled with vaxis.Style objects
type RuneBuffer struct {
buf []*StyledRune
}
@@ -77,13 +77,13 @@ func (rb *RuneBuffer) Runes() []*StyledRune {
}
// Write writes a rune and it's associated style to the RuneBuffer
-func (rb *RuneBuffer) Write(r rune, style tcell.Style) {
+func (rb *RuneBuffer) Write(r rune, style vaxis.Style) {
w := runewidth.RuneWidth(r)
rb.buf = append(rb.buf, &StyledRune{r, w, style})
}
// Prepend inserts the rune at the beginning of the rune buffer
-func (rb *RuneBuffer) PadLeft(width int, r rune, style tcell.Style) {
+func (rb *RuneBuffer) PadLeft(width int, r rune, style vaxis.Style) {
w := rb.Len()
if w >= width {
return
@@ -96,7 +96,7 @@ func (rb *RuneBuffer) PadLeft(width int, r rune, style tcell.Style) {
}
}
-func (rb *RuneBuffer) PadRight(width int, r rune, style tcell.Style) {
+func (rb *RuneBuffer) PadRight(width int, r rune, style vaxis.Style) {
w := rb.Len()
if w >= width {
return
@@ -119,7 +119,7 @@ func (rb *RuneBuffer) String() string {
func (rb *RuneBuffer) string(n int, left bool, char rune) string {
var (
s = bytes.NewBuffer(nil)
- style = tcell.StyleDefault
+ style = vaxis.Style{}
hasStyle = false
// w will track the length we have written, or would have
// written in the case of left truncate
@@ -136,52 +136,55 @@ func (rb *RuneBuffer) string(n int, left bool, char rune) string {
hasStyle = true
style = r.Style
s.WriteString(attrOff)
- fg, bg, attrs := style.Decompose()
-
- switch {
- case fg.IsRGB() && bg.IsRGB():
- fr, fg, fb := fg.RGB()
- br, bg, bb := bg.RGB()
- fmt.Fprintf(s, setfgbgrgb, fr, fg, fb, br, bg, bb)
- case fg.IsRGB():
- // RGB
- r, g, b := fg.RGB()
- fmt.Fprintf(s, setfgrgb, r, g, b)
- case bg.IsRGB():
- // RGB
- r, g, b := bg.RGB()
- fmt.Fprintf(s, setbgrgb, r, g, b)
-
- // Indexed
- case fg.Valid() && bg.Valid():
- fmt.Fprintf(s, setfgbg, fg&0xFF, bg&0xFF)
- case fg.Valid():
- fmt.Fprintf(s, setfg, fg&0xFF)
- case bg.Valid():
- fmt.Fprintf(s, setbg, bg&0xFF)
+ // fg, bg, attrs := style.Decompose()
+ fg := style.Foreground.Params()
+ switch len(fg) {
+ case 0:
+ // default
+ case 1:
+ // indexed
+ fmt.Fprintf(s, setfg, fg[0])
+ case 3:
+ // rgb
+ fmt.Fprintf(s, setfgrgb, fg[0], fg[1], fg[2])
}
- if attrs&tcell.AttrBold != 0 {
- s.WriteString(bold)
+ bg := style.Background.Params()
+ switch len(bg) {
+ case 0:
+ // default
+ case 1:
+ // indexed
+ fmt.Fprintf(s, setbg, bg[0])
+ case 3:
+ // rgb
+ fmt.Fprintf(s, setbgrgb, bg[0], bg[1], bg[2])
}
- if attrs&tcell.AttrUnderline != 0 {
- s.WriteString(underline)
+
+ attrs := style.Attribute
+
+ if attrs&vaxis.AttrBold != 0 {
+ s.WriteString(bold)
}
- if attrs&tcell.AttrReverse != 0 {
+ if attrs&vaxis.AttrReverse != 0 {
s.WriteString(reverse)
}
- if attrs&tcell.AttrBlink != 0 {
+ if attrs&vaxis.AttrBlink != 0 {
s.WriteString(blink)
}
- if attrs&tcell.AttrDim != 0 {
+ if attrs&vaxis.AttrDim != 0 {
s.WriteString(dim)
}
- if attrs&tcell.AttrItalic != 0 {
+ if attrs&vaxis.AttrItalic != 0 {
s.WriteString(italic)
}
- if attrs&tcell.AttrStrikeThrough != 0 {
+ if attrs&vaxis.AttrStrikethrough != 0 {
s.WriteString(strikethrough)
}
+
+ if style.UnderlineStyle != vaxis.UnderlineOff {
+ s.WriteString(underline)
+ }
}
w += r.Width
@@ -230,9 +233,10 @@ func (rb *RuneBuffer) TruncateHead(n int, char rune) string {
// Applies a style to the buffer. Any currently applied styles will not be
// overwritten
-func (rb *RuneBuffer) ApplyStyle(style tcell.Style) {
+func (rb *RuneBuffer) ApplyStyle(style vaxis.Style) {
+ d := vaxis.Style{}
for _, sr := range rb.buf {
- if sr.Style == tcell.StyleDefault {
+ if sr.Style == d {
sr.Style = style
}
}
@@ -240,26 +244,30 @@ func (rb *RuneBuffer) ApplyStyle(style tcell.Style) {
// ApplyAttrs applies the style, and if another style is present ORs the
// attributes
-func (rb *RuneBuffer) ApplyAttrs(style tcell.Style) {
- fg, bg, attrs := style.Decompose()
+func (rb *RuneBuffer) ApplyAttrs(style vaxis.Style) {
for _, sr := range rb.buf {
- srFg, srBg, srAttrs := sr.Style.Decompose()
- if fg != tcell.ColorDefault {
- srFg = fg
+ if style.Foreground != 0 {
+ sr.Style.Foreground = style.Foreground
+ }
+ if style.Background != 0 {
+ sr.Style.Background = style.Background
+ }
+ sr.Style.Attribute |= style.Attribute
+ if style.UnderlineColor != 0 {
+ sr.Style.UnderlineColor = style.UnderlineColor
}
- if bg != tcell.ColorDefault {
- srBg = bg
+ if style.UnderlineStyle != vaxis.UnderlineOff {
+ sr.Style.UnderlineStyle = style.UnderlineStyle
}
- sr.Style = sr.Style.Attributes(attrs | srAttrs).
- Foreground(srFg).Background(srBg)
}
}
// Applies a style to a string. Any currently applied styles will not be overwritten
-func ApplyStyle(style tcell.Style, str string) string {
+func ApplyStyle(style vaxis.Style, str string) string {
rb := ParseANSI(str)
+ d := vaxis.Style{}
for _, sr := range rb.buf {
- if sr.Style == tcell.StyleDefault {
+ if sr.Style == d {
sr.Style = style
}
}
@@ -270,7 +278,7 @@ func ApplyStyle(style tcell.Style, str string) string {
func ParseANSI(s string) *RuneBuffer {
p := &parser{
buf: &RuneBuffer{},
- curStyle: tcell.StyleDefault,
+ curStyle: vaxis.Style{},
}
rdr := strings.NewReader(s)
@@ -292,7 +300,7 @@ func ParseANSI(s string) *RuneBuffer {
// A parser parses a string into a RuneBuffer
type parser struct {
buf *RuneBuffer
- curStyle tcell.Style
+ curStyle vaxis.Style
}
func (p *parser) handleSeq(rdr io.RuneReader) {
@@ -357,97 +365,97 @@ outer:
param := params[i]
switch param {
case 0:
- p.curStyle = tcell.StyleDefault
+ p.curStyle = vaxis.Style{}
case 1:
- p.curStyle = p.curStyle.Bold(true)
+ p.curStyle.Attribute |= vaxis.AttrBold
case 2:
- p.curStyle = p.curStyle.Dim(true)
+ p.curStyle.Attribute |= vaxis.AttrDim
case 3:
- p.curStyle = p.curStyle.Italic(true)
+ p.curStyle.Attribute |= vaxis.AttrItalic
case 4:
- p.curStyle = p.curStyle.Underline(true)
+ p.curStyle.UnderlineStyle = vaxis.UnderlineSingle
case 5:
- p.curStyle = p.curStyle.Blink(true)
+ p.curStyle.Attribute |= vaxis.AttrBlink
case 6:
- // rapid blink, not supported by tcell. fallback to slow
+ // rapid blink, not supported by vaxis. fallback to slow
// blink
- p.curStyle = p.curStyle.Blink(true)
+ p.curStyle.Attribute |= vaxis.AttrBlink
case 7:
- p.curStyle = p.curStyle.Reverse(true)
+ p.curStyle.Attribute |= vaxis.AttrReverse
case 8:
- // Hidden. not supported by tcell
+ // Hidden. not supported by vaxis
case 9:
- p.curStyle = p.curStyle.StrikeThrough(true)
+ p.curStyle.Attribute |= vaxis.AttrStrikethrough
case 21:
- p.curStyle = p.curStyle.Bold(false)
+ p.curStyle.Attribute &^= vaxis.AttrBold
case 22:
- p.curStyle = p.curStyle.Dim(false)
+ p.curStyle.Attribute &^= vaxis.AttrDim
case 23:
- p.curStyle = p.curStyle.Italic(false)
+ p.curStyle.Attribute &^= vaxis.AttrItalic
case 24:
- p.curStyle = p.curStyle.Underline(false)
+ p.curStyle.UnderlineStyle = vaxis.UnderlineOff
case 25:
- p.curStyle = p.curStyle.Blink(false)
+ p.curStyle.Attribute &^= vaxis.AttrBlink
case 26:
- // rapid blink, not supported by tcell. fallback to slow
+ // rapid blink, not supported by vaxis. fallback to slow
// blink
- p.curStyle = p.curStyle.Blink(false)
+ p.curStyle.Attribute &^= vaxis.AttrBlink
case 27:
- p.curStyle = p.curStyle.Reverse(false)
+ p.curStyle.Attribute &^= vaxis.AttrReverse
case 28:
- // Hidden. unsupported by tcell
+ // Hidden. unsupported by vaxis
case 29:
- p.curStyle = p.curStyle.StrikeThrough(false)
+ p.curStyle.Attribute &^= vaxis.AttrStrikethrough
case 30, 31, 32, 33, 34, 35, 36, 37:
- p.curStyle = p.curStyle.Foreground(tcell.PaletteColor(param - 30))
+ p.curStyle.Foreground = vaxis.IndexColor(uint8(param - 30))
case 38:
if i+2 < len(params) && params[i+1] == 5 {
- p.curStyle = p.curStyle.Foreground(tcell.PaletteColor(params[i+2]))
+ p.curStyle.Foreground = vaxis.IndexColor(uint8(params[i+2]))
i += 2
}
if i+4 < len(params) && params[i+1] == 2 {
switch len(params) {
case 6:
- r := int32(params[i+3])
- g := int32(params[i+4])
- b := int32(params[i+5])
- p.curStyle = p.curStyle.Foreground(tcell.NewRGBColor(r, g, b))
+ r := uint8(params[i+3])
+ g := uint8(params[i+4])
+ b := uint8(params[i+5])
+ p.curStyle.Foreground = vaxis.RGBColor(r, g, b)
i += 5
default:
- r := int32(params[i+2])
- g := int32(params[i+3])
- b := int32(params[i+4])
- p.curStyle = p.curStyle.Foreground(tcell.NewRGBColor(r, g, b))
+ r := uint8(params[i+2])
+ g := uint8(params[i+3])
+ b := uint8(params[i+4])
+ p.curStyle.Foreground = vaxis.RGBColor(r, g, b)
i += 4
}
}
case 40, 41, 42, 43, 44, 45, 46, 47:
- p.curStyle = p.curStyle.Background(tcell.PaletteColor(param - 40))
+ p.curStyle.Background = vaxis.IndexColor(uint8(param - 40))
case 48:
if i+2 < len(params) && params[i+1] == 5 {
- p.curStyle = p.curStyle.Background(tcell.PaletteColor(params[i+2]))
+ p.curStyle.Background = vaxis.IndexColor(uint8(params[i+2]))
i += 2
}
if i+4 < len(params) && params[i+1] == 2 {
switch len(params) {
case 6:
- r := int32(params[i+3])
- g := int32(params[i+4])
- b := int32(params[i+5])
- p.curStyle = p.curStyle.Background(tcell.NewRGBColor(r, g, b))
+ r := uint8(params[i+3])
+ g := uint8(params[i+4])
+ b := uint8(params[i+5])
+ p.curStyle.Background = vaxis.RGBColor(r, g, b)
i += 5
default:
- r := int32(params[i+2])
- g := int32(params[i+3])
- b := int32(params[i+4])
- p.curStyle = p.curStyle.Background(tcell.NewRGBColor(r, g, b))
+ r := uint8(params[i+2])
+ g := uint8(params[i+3])
+ b := uint8(params[i+4])
+ p.curStyle.Background = vaxis.RGBColor(r, g, b)
i += 4
}
}
case 90, 91, 92, 93, 94, 95, 96, 97:
- p.curStyle = p.curStyle.Foreground(tcell.PaletteColor(param - 90 + 8))
+ p.curStyle.Foreground = vaxis.IndexColor(uint8(param - 90 + 8))
case 100, 101, 102, 103, 104, 105, 106, 107:
- p.curStyle = p.curStyle.Background(tcell.PaletteColor(param - 100 + 8))
+ p.curStyle.Background = vaxis.IndexColor(uint8(param - 100 + 8))
}
}
}
diff --git a/lib/parse/ansi_test.go b/lib/parse/ansi_test.go
index 6aa95b18..5d8e8572 100644
--- a/lib/parse/ansi_test.go
+++ b/lib/parse/ansi_test.go
@@ -110,7 +110,7 @@ func TestParser(t *testing.T) {
{
name: "8 bit color: foreground and background",
input: "\x1b[31;41mhello, world",
- expectedString: "\x1b[m\x1b[38;5;1;48;5;1mhello, world\x1b[m",
+ expectedString: "\x1b[m\x1b[38;5;1m\x1b[48;5;1mhello, world\x1b[m",
expectedLen: 12,
},
{
@@ -128,7 +128,7 @@ func TestParser(t *testing.T) {
{
name: "16 bit color: foreground and background",
input: "\x1b[91;101mhello, world",
- expectedString: "\x1b[m\x1b[38;5;9;48;5;9mhello, world\x1b[m",
+ expectedString: "\x1b[m\x1b[38;5;9m\x1b[48;5;9mhello, world\x1b[m",
expectedLen: 12,
},
{
@@ -152,7 +152,7 @@ func TestParser(t *testing.T) {
{
name: "256 color: foreground and background",
input: "\x1b[38;5;20;48;5;20mhello, world",
- expectedString: "\x1b[m\x1b[38;5;20;48;5;20mhello, world\x1b[m",
+ expectedString: "\x1b[m\x1b[38;5;20m\x1b[48;5;20mhello, world\x1b[m",
expectedLen: 12,
},
{
@@ -194,7 +194,7 @@ func TestParser(t *testing.T) {
{
name: "true color: foreground and background",
input: "\x1b[38;2;200;200;200;48;2;0;0;0mhello, world",
- expectedString: "\x1b[m\x1b[38;2;200;200;200;48;2;0;0;0mhello, world\x1b[m",
+ expectedString: "\x1b[m\x1b[38;2;200;200;200m\x1b[48;2;0;0;0mhello, world\x1b[m",
expectedLen: 12,
},
}