From 7d13baadc84d7377a352c6d58ed9deeea2c918be Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Thu, 26 Jun 2025 10:16:07 -0500 Subject: feat: default system theme (#419) Co-authored-by: adamdottv <2363879+adamdottv@users.noreply.github.com> --- packages/tui/internal/util/color.go | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 packages/tui/internal/util/color.go (limited to 'packages/tui/internal/util') diff --git a/packages/tui/internal/util/color.go b/packages/tui/internal/util/color.go new file mode 100644 index 000000000..f0d73bcb2 --- /dev/null +++ b/packages/tui/internal/util/color.go @@ -0,0 +1,93 @@ +package util + +import ( + "regexp" + "strings" +) + +var csiRE *regexp.Regexp + +func init() { + csiRE = regexp.MustCompile(`\x1b\[([0-9;]+)m`) +} + +var targetFGMap = map[string]string{ + "0;0;0": "\x1b[30m", // Black + "128;0;0": "\x1b[31m", // Red + "0;128;0": "\x1b[32m", // Green + "128;128;0": "\x1b[33m", // Yellow + "0;0;128": "\x1b[34m", // Blue + "128;0;128": "\x1b[35m", // Magenta + "0;128;128": "\x1b[36m", // Cyan + "192;192;192": "\x1b[37m", // White (light grey) + "128;128;128": "\x1b[90m", // Bright Black (dark grey) + "255;0;0": "\x1b[91m", // Bright Red + "0;255;0": "\x1b[92m", // Bright Green + "255;255;0": "\x1b[93m", // Bright Yellow + "0;0;255": "\x1b[94m", // Bright Blue + "255;0;255": "\x1b[95m", // Bright Magenta + "0;255;255": "\x1b[96m", // Bright Cyan + "255;255;255": "\x1b[97m", // Bright White +} + +var targetBGMap = map[string]string{ + "0;0;0": "\x1b[40m", + "128;0;0": "\x1b[41m", + "0;128;0": "\x1b[42m", + "128;128;0": "\x1b[43m", + "0;0;128": "\x1b[44m", + "128;0;128": "\x1b[45m", + "0;128;128": "\x1b[46m", + "192;192;192": "\x1b[47m", + "128;128;128": "\x1b[100m", + "255;0;0": "\x1b[101m", + "0;255;0": "\x1b[102m", + "255;255;0": "\x1b[103m", + "0;0;255": "\x1b[104m", + "255;0;255": "\x1b[105m", + "0;255;255": "\x1b[106m", + "255;255;255": "\x1b[107m", +} + +func ConvertRGBToAnsi16Colors(s string) string { + return csiRE.ReplaceAllStringFunc(s, func(seq string) string { + params := strings.Split(csiRE.FindStringSubmatch(seq)[1], ";") + out := make([]string, 0, len(params)) + + for i := 0; i < len(params); { + // Detect “38 | 48 ; 2 ; r ; g ; b ( ; alpha? )” + if (params[i] == "38" || params[i] == "48") && + i+4 < len(params) && + params[i+1] == "2" { + + key := strings.Join(params[i+2:i+5], ";") + var repl string + if params[i] == "38" { + repl = targetFGMap[key] + } else { + repl = targetBGMap[key] + } + + if repl != "" { // exact RGB hit + out = append(out, repl[2:len(repl)-1]) + i += 5 // skip 38/48;2;r;g;b + + // if i == len(params)-1 && looksLikeByte(params[i]) { + // i++ // swallow the alpha byte + // } + continue + } + } + // Normal token — keep verbatim. + out = append(out, params[i]) + i++ + } + + return "\x1b[" + strings.Join(out, ";") + "m" + }) +} + +// func looksLikeByte(tok string) bool { +// v, err := strconv.Atoi(tok) +// return err == nil && v >= 0 && v <= 255 +// } -- cgit v1.2.3