keep ansi attributes at next line

This commit is contained in:
Gokcehan 2017-11-22 17:17:23 +03:00
parent ba0a9005b1
commit 946de57f26

61
ui.go
View File

@ -20,7 +20,10 @@ import (
"github.com/nsf/termbox-go" "github.com/nsf/termbox-go"
) )
const gEscapeCode = 27 const (
gEscapeCode = 27
gAnsiColorResetMask = termbox.AttrBold | termbox.AttrUnderline | termbox.AttrReverse
)
var gAnsiCodes = map[int]termbox.Attribute{ var gAnsiCodes = map[int]termbox.Attribute{
0: termbox.ColorDefault, 0: termbox.ColorDefault,
@ -125,18 +128,8 @@ func (win *win) renew(w, h, x, y int) {
win.w, win.h, win.x, win.y = w, h, x, y win.w, win.h, win.x, win.y = w, h, x, y
} }
func (win *win) print(x, y int, fg, bg termbox.Attribute, s string) { func applyAnsiCodes(s string, fg, bg termbox.Attribute) (termbox.Attribute, termbox.Attribute) {
off := x toks := strings.Split(s, ";")
for i := 0; i < len(s); i++ {
r, w := utf8.DecodeRuneInString(s[i:])
if r == gEscapeCode && i+1 < len(s) && s[i+1] == '[' {
j := strings.IndexByte(s[i:min(len(s), i+32)], 'm')
if j == -1 {
continue
}
toks := strings.Split(s[i+2:i+j], ";")
var nums []int var nums []int
for _, t := range toks { for _, t := range toks {
@ -153,29 +146,41 @@ func (win *win) print(x, y int, fg, bg termbox.Attribute, s string) {
nums = append(nums, n) nums = append(nums, n)
} }
for _, n := range nums {
if 30 <= n && n <= 37 {
fg = termbox.ColorDefault
}
if 40 <= n && n <= 47 {
bg = termbox.ColorDefault
}
}
for _, n := range nums { for _, n := range nums {
attr, ok := gAnsiCodes[n] attr, ok := gAnsiCodes[n]
if !ok { if !ok {
log.Printf("unknown ansi code: %d", n) log.Printf("unknown ansi code: %d", n)
continue continue
} }
if 1 <= n && n <= 37 { switch {
case n == 0:
fg, bg = attr, attr
case n == 1 || n == 4 || n == 7:
fg |= attr fg |= attr
} case 30 <= n && n <= 37:
if 40 <= n && n <= 47 { fg &= gAnsiColorResetMask
bg |= attr fg |= attr
case 40 <= n && n <= 47:
bg = attr
} }
} }
return fg, bg
}
func (win *win) print(x, y int, fg, bg termbox.Attribute, s string) (termbox.Attribute, termbox.Attribute) {
off := x
for i := 0; i < len(s); i++ {
r, w := utf8.DecodeRuneInString(s[i:])
if r == gEscapeCode && i+1 < len(s) && s[i+1] == '[' {
j := strings.IndexByte(s[i:min(len(s), i+32)], 'm')
if j == -1 {
continue
}
fg, bg = applyAnsiCodes(s[i+2:i+j], fg, bg)
i += j i += j
continue continue
} }
@ -194,6 +199,8 @@ func (win *win) print(x, y int, fg, bg termbox.Attribute, s string) {
x += runewidth.RuneWidth(r) x += runewidth.RuneWidth(r)
} }
} }
return fg, bg
} }
func (win *win) printf(x, y int, fg, bg termbox.Attribute, format string, a ...interface{}) { func (win *win) printf(x, y int, fg, bg termbox.Attribute, format string, a ...interface{}) {
@ -208,7 +215,7 @@ func (win *win) printReg(reg []string) {
fg, bg := termbox.ColorDefault, termbox.ColorDefault fg, bg := termbox.ColorDefault, termbox.ColorDefault
for i, l := range reg { for i, l := range reg {
win.print(2, i, fg, bg, l) fg, bg = win.print(2, i, fg, bg, l)
} }
return return