Manually specify the closing SGR for a span
This commit is contained in:
parent
6590be84a2
commit
de9edb6ff5
@ -328,8 +328,8 @@ func SGRFromCSI(csi string) (ans SGR) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Span struct {
|
type Span struct {
|
||||||
Offset, Size int // in bytes
|
Offset, Size int // in bytes
|
||||||
SGR SGR
|
opening_sgr, closing_sgr SGR
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSpan(offset, size int) *Span {
|
func NewSpan(offset, size int) *Span {
|
||||||
@ -354,102 +354,93 @@ func (self *ColorVal) Set(val any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Span) SetForeground(val any) *Span {
|
func (self *Span) SetForeground(val any) *Span {
|
||||||
self.SGR.Foreground.Set(val)
|
self.opening_sgr.Foreground.Set(val)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Span) SetBackground(val any) *Span {
|
func (self *Span) SetBackground(val any) *Span {
|
||||||
self.SGR.Background.Set(val)
|
self.opening_sgr.Background.Set(val)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Span) SetUnderlineColor(val any) *Span {
|
func (self *Span) SetUnderlineColor(val any) *Span {
|
||||||
self.SGR.Underline_color.Set(val)
|
self.opening_sgr.Underline_color.Set(val)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Span) SetItalic(val bool) *Span {
|
func (self *Span) SetItalic(val bool) *Span {
|
||||||
self.SGR.Italic.Set(val)
|
self.opening_sgr.Italic.Set(val)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Span) SetBold(val bool) *Span {
|
func (self *Span) SetBold(val bool) *Span {
|
||||||
self.SGR.Bold.Set(val)
|
self.opening_sgr.Bold.Set(val)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
func (self *Span) SetReverse(val bool) *Span {
|
func (self *Span) SetReverse(val bool) *Span {
|
||||||
self.SGR.Reverse.Set(val)
|
self.opening_sgr.Reverse.Set(val)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
func (self *Span) SetDim(val bool) *Span {
|
func (self *Span) SetDim(val bool) *Span {
|
||||||
self.SGR.Dim.Set(val)
|
self.opening_sgr.Dim.Set(val)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
func (self *Span) SetStrikethrough(val bool) *Span {
|
func (self *Span) SetStrikethrough(val bool) *Span {
|
||||||
self.SGR.Strikethrough.Set(val)
|
self.opening_sgr.Strikethrough.Set(val)
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
func (self *Span) SetUnderlineStyle(val UnderlineStyle) *Span {
|
func (self *Span) SetUnderlineStyle(val UnderlineStyle) *Span {
|
||||||
self.SGR.Underline_style.Is_set = true
|
self.opening_sgr.Underline_style.Is_set = true
|
||||||
self.SGR.Underline_style.Val = val
|
self.opening_sgr.Underline_style.Val = val
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
type defaulting_val interface {
|
func (self *Span) SetClosingForeground(val any) *Span {
|
||||||
DefaultCSI() string
|
self.closing_sgr.Foreground.Set(val)
|
||||||
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func append_default_csi(x defaulting_val, ans []byte) []byte {
|
func (self *Span) SetClosingBackground(val any) *Span {
|
||||||
val := x.DefaultCSI()
|
self.closing_sgr.Background.Set(val)
|
||||||
if val != "" {
|
return self
|
||||||
ans = append(ans, val...)
|
|
||||||
ans = append(ans, ';')
|
|
||||||
}
|
|
||||||
return ans
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Span) ClosingCSI() string {
|
func (self *Span) SetClosingUnderlineColor(val any) *Span {
|
||||||
ans := make([]byte, 0, 16)
|
self.closing_sgr.Underline_color.Set(val)
|
||||||
w := func(x string) {
|
return self
|
||||||
if x != "" {
|
}
|
||||||
ans = append(append(ans, x...), ';')
|
|
||||||
}
|
func (self *Span) SetClosingItalic(val bool) *Span {
|
||||||
}
|
self.closing_sgr.Italic.Set(val)
|
||||||
if self.SGR.Bold.Is_set {
|
return self
|
||||||
w(self.SGR.Bold.AsCSI("1", "221"))
|
}
|
||||||
}
|
|
||||||
if self.SGR.Dim.Is_set {
|
func (self *Span) SetClosingBold(val bool) *Span {
|
||||||
w(self.SGR.Dim.AsCSI("2", "222"))
|
self.closing_sgr.Bold.Set(val)
|
||||||
}
|
return self
|
||||||
if self.SGR.Italic.Is_set {
|
}
|
||||||
w(self.SGR.Italic.AsCSI("3", "23"))
|
func (self *Span) SetClosingReverse(val bool) *Span {
|
||||||
}
|
self.closing_sgr.Reverse.Set(val)
|
||||||
if self.SGR.Reverse.Is_set {
|
return self
|
||||||
w(self.SGR.Reverse.AsCSI("7", "27"))
|
}
|
||||||
}
|
func (self *Span) SetClosingDim(val bool) *Span {
|
||||||
if self.SGR.Strikethrough.Is_set {
|
self.closing_sgr.Dim.Set(val)
|
||||||
w(self.SGR.Strikethrough.AsCSI("9", "29"))
|
return self
|
||||||
}
|
}
|
||||||
wc := func(cval ColorVal, base int) {
|
func (self *Span) SetClosingStrikethrough(val bool) *Span {
|
||||||
if cval.Is_set {
|
self.closing_sgr.Strikethrough.Set(val)
|
||||||
cval.Is_default = true
|
return self
|
||||||
w(cval.AsCSI(base))
|
}
|
||||||
}
|
func (self *Span) SetClosingUnderlineStyle(val UnderlineStyle) *Span {
|
||||||
}
|
self.closing_sgr.Underline_style.Is_set = true
|
||||||
wc(self.SGR.Foreground, 30)
|
self.opening_sgr.Underline_style.Val = val
|
||||||
wc(self.SGR.Background, 40)
|
return self
|
||||||
wc(self.SGR.Underline_color, 50)
|
|
||||||
if len(ans) > 0 {
|
|
||||||
ans = ans[:len(ans)-1]
|
|
||||||
ans = append(ans, 'm')
|
|
||||||
}
|
|
||||||
return utils.UnsafeBytesToString(ans)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert formatting into text at the specified offsets, overriding any existing formatting, and restoring
|
// Insert formatting into text at the specified offsets, overriding any existing formatting, and restoring
|
||||||
// existing formatting after the replaced sections.
|
// existing formatting after the replaced sections.
|
||||||
func InsertFormatting(text string, spans ...*Span) string {
|
func InsertFormatting(text string, spans ...*Span) string {
|
||||||
spans = utils.Filter(spans, func(s *Span) bool { return !s.SGR.IsEmpty() })
|
spans = utils.Filter(spans, func(s *Span) bool { return !s.opening_sgr.IsEmpty() })
|
||||||
if len(spans) == 0 {
|
if len(spans) == 0 {
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
@ -470,7 +461,7 @@ func InsertFormatting(text string, spans ...*Span) string {
|
|||||||
in_span = spans[0]
|
in_span = spans[0]
|
||||||
spans = spans[1:]
|
spans = spans[1:]
|
||||||
if in_span.Size > 0 {
|
if in_span.Size > 0 {
|
||||||
write_csi(in_span.SGR.AsCSI())
|
write_csi(in_span.opening_sgr.AsCSI())
|
||||||
} else {
|
} else {
|
||||||
in_span = nil
|
in_span = nil
|
||||||
}
|
}
|
||||||
@ -478,7 +469,7 @@ func InsertFormatting(text string, spans ...*Span) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
close_span := func() {
|
close_span := func() {
|
||||||
write_csi(in_span.ClosingCSI())
|
write_csi(in_span.closing_sgr.AsCSI())
|
||||||
write_csi(overall_sgr_state.AsCSI())
|
write_csi(overall_sgr_state.AsCSI())
|
||||||
in_span = nil
|
in_span = nil
|
||||||
}
|
}
|
||||||
@ -515,7 +506,7 @@ func InsertFormatting(text string, spans ...*Span) string {
|
|||||||
if in_span == nil {
|
if in_span == nil {
|
||||||
write_csi(csi)
|
write_csi(csi)
|
||||||
} else {
|
} else {
|
||||||
sgr.ApplyMask(in_span.SGR)
|
sgr.ApplyMask(in_span.opening_sgr)
|
||||||
csi := sgr.AsCSI()
|
csi := sgr.AsCSI()
|
||||||
write_csi(csi)
|
write_csi(csi)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,16 +21,16 @@ func TestInsertFormatting(t *testing.T) {
|
|||||||
test(
|
test(
|
||||||
"\x1b[44m abcd \x1b[49m",
|
"\x1b[44m abcd \x1b[49m",
|
||||||
"\x1b[44m a\x1b[33;41mbc\x1b[39;49m\x1b[44md \x1b[49m",
|
"\x1b[44m a\x1b[33;41mbc\x1b[39;49m\x1b[44md \x1b[49m",
|
||||||
NewSpan(2, 2).SetForeground(3).SetBackground(1),
|
NewSpan(2, 2).SetForeground(3).SetBackground(1).SetClosingForeground(nil).SetClosingBackground(nil),
|
||||||
)
|
)
|
||||||
test(
|
test(
|
||||||
"abcd",
|
"abcd",
|
||||||
"a\x1b[92mbcd\x1b[39m",
|
"a\x1b[92mbcd\x1b[39m",
|
||||||
NewSpan(1, 11).SetForeground(10),
|
NewSpan(1, 11).SetForeground(10).SetClosingForeground(nil),
|
||||||
)
|
)
|
||||||
test(
|
test(
|
||||||
"AB\x1b[1mC\x1b[221mDE",
|
"AB\x1b[1mC\x1b[221mDE",
|
||||||
"A\x1b[37mB\x1b[1mC\x1b[221mDE\x1b[39m\x1b[221m",
|
"A\x1b[37mB\x1b[1mC\x1b[221mDE\x1b[39m\x1b[221m",
|
||||||
NewSpan(1, 11).SetForeground(7),
|
NewSpan(1, 11).SetForeground(7).SetClosingForeground(nil),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user