func interpretCode(ansiCode string, prevState *ansiState) *ansiState { // State var state *ansiState if prevState == nil { state = &ansiState{-1, -1, 0} } else { state = &ansiState{prevState.fg, prevState.bg, prevState.attr} } if ansiCode[0] != '\x1b' || ansiCode[1] != '[' || ansiCode[len(ansiCode)-1] != 'm' { return state } ptr := &state.fg state256 := 0 init := func() { state.fg = -1 state.bg = -1 state.attr = 0 state256 = 0 } ansiCode = ansiCode[2 : len(ansiCode)-1] if len(ansiCode) == 0 { init() } for _, code := range strings.Split(ansiCode, ";") { if num, err := strconv.Atoi(code); err == nil { switch state256 { case 0: switch num { case 38: ptr = &state.fg state256++ case 48: ptr = &state.bg state256++ case 39: state.fg = -1 case 49: state.bg = -1 case 1: state.attr = tui.Bold case 2: state.attr = tui.Dim case 4: state.attr = tui.Underline case 5: state.attr = tui.Blink case 7: state.attr = tui.Reverse case 0: init() default: if num >= 30 && num <= 37 { state.fg = tui.Color(num - 30) } else if num >= 40 && num <= 47 { state.bg = tui.Color(num - 40) } else if num >= 90 && num <= 97 { state.fg = tui.Color(num - 90 + 8) } else if num >= 100 && num <= 107 { state.bg = tui.Color(num - 100 + 8) } } case 1: switch num { case 5: state256++ default: state256 = 0 } case 2: *ptr = tui.Color(num) state256 = 0 } } } return state }
func parseTheme(defaultTheme *tui.ColorTheme, str string) *tui.ColorTheme { theme := dupeTheme(defaultTheme) for _, str := range strings.Split(strings.ToLower(str), ",") { switch str { case "dark": theme = dupeTheme(tui.Dark256) case "light": theme = dupeTheme(tui.Light256) case "16": theme = dupeTheme(tui.Default16) case "bw", "no": theme = nil default: fail := func() { errorExit("invalid color specification: " + str) } // Color is disabled if theme == nil { continue } pair := strings.Split(str, ":") if len(pair) != 2 { fail() } ansi32, err := strconv.Atoi(pair[1]) if err != nil || ansi32 < -1 || ansi32 > 255 { fail() } ansi := tui.Color(ansi32) switch pair[0] { case "fg": theme.Fg = ansi case "bg": theme.Bg = ansi case "fg+": theme.Current = ansi case "bg+": theme.DarkBg = ansi case "hl": theme.Match = ansi case "hl+": theme.CurrentMatch = ansi case "border": theme.Border = ansi case "prompt": theme.Prompt = ansi case "spinner": theme.Spinner = ansi case "info": theme.Info = ansi case "pointer": theme.Cursor = ansi case "marker": theme.Selected = ansi case "header": theme.Header = ansi default: fail() } } } return theme }