summaryrefslogtreecommitdiffhomepage
path: root/internal/tui/styles/background.go
diff options
context:
space:
mode:
authorKujtim Hoxha <[email protected]>2025-04-18 20:17:38 +0200
committerKujtim Hoxha <[email protected]>2025-04-21 13:42:27 +0200
commit333ea6ec4b2abfc2c1a9c3f6b0918ca5d296347f (patch)
treee0d456417368e8716c81ee43b82be3d6ed39c59e /internal/tui/styles/background.go
parent05d0e86f10369fd0e51a924ac88029fb92591499 (diff)
downloadopencode-333ea6ec4b2abfc2c1a9c3f6b0918ca5d296347f.tar.gz
opencode-333ea6ec4b2abfc2c1a9c3f6b0918ca5d296347f.zip
implement patch, update ui, improve rendering
Diffstat (limited to 'internal/tui/styles/background.go')
-rw-r--r--internal/tui/styles/background.go114
1 files changed, 78 insertions, 36 deletions
diff --git a/internal/tui/styles/background.go b/internal/tui/styles/background.go
index bf6cbc105..2fbb34efb 100644
--- a/internal/tui/styles/background.go
+++ b/internal/tui/styles/background.go
@@ -3,7 +3,6 @@ package styles
import (
"fmt"
"regexp"
- "strconv"
"strings"
"github.com/charmbracelet/lipgloss"
@@ -25,57 +24,100 @@ func getColorRGB(c lipgloss.TerminalColor) (uint8, uint8, uint8) {
return uint8(r >> 8), uint8(g >> 8), uint8(b >> 8)
}
+// ForceReplaceBackgroundWithLipgloss replaces any ANSI background color codes
+// in `input` with a single 24‑bit background (48;2;R;G;B).
func ForceReplaceBackgroundWithLipgloss(input string, newBgColor lipgloss.TerminalColor) string {
+ // Precompute our new-bg sequence once
r, g, b := getColorRGB(newBgColor)
-
newBg := fmt.Sprintf("48;2;%d;%d;%d", r, g, b)
return ansiEscape.ReplaceAllStringFunc(input, func(seq string) string {
- // Extract content between "\x1b[" and "m"
- content := seq[2 : len(seq)-1]
- tokens := strings.Split(content, ";")
- var newTokens []string
-
- // Skip background color tokens
- for i := 0; i < len(tokens); i++ {
- if tokens[i] == "" {
- continue
- }
+ const (
+ escPrefixLen = 2 // "\x1b["
+ escSuffixLen = 1 // "m"
+ )
+
+ raw := seq
+ start := escPrefixLen
+ end := len(raw) - escSuffixLen
- val, err := strconv.Atoi(tokens[i])
- if err != nil {
- newTokens = append(newTokens, tokens[i])
- continue
+ var sb strings.Builder
+ // reserve enough space: original content minus bg codes + our newBg
+ sb.Grow((end - start) + len(newBg) + 2)
+
+ // scan from start..end, token by token
+ for i := start; i < end; {
+ // find the next ';' or end
+ j := i
+ for j < end && raw[j] != ';' {
+ j++
}
+ token := raw[i:j]
- // Skip background color tokens
- if val == 48 {
- // Skip "48;5;N" or "48;2;R;G;B" sequences
- if i+1 < len(tokens) {
- if nextVal, err := strconv.Atoi(tokens[i+1]); err == nil {
- switch nextVal {
- case 5:
- i += 2 // Skip "5" and color index
- case 2:
- i += 4 // Skip "2" and RGB components
+ // fast‑path: skip "48;5;N" or "48;2;R;G;B"
+ if len(token) == 2 && token[0] == '4' && token[1] == '8' {
+ k := j + 1
+ if k < end {
+ // find next token
+ l := k
+ for l < end && raw[l] != ';' {
+ l++
+ }
+ next := raw[k:l]
+ if next == "5" {
+ // skip "48;5;N"
+ m := l + 1
+ for m < end && raw[m] != ';' {
+ m++
+ }
+ i = m + 1
+ continue
+ } else if next == "2" {
+ // skip "48;2;R;G;B"
+ m := l + 1
+ for count := 0; count < 3 && m < end; count++ {
+ for m < end && raw[m] != ';' {
+ m++
+ }
+ m++
}
+ i = m
+ continue
}
}
- } else if (val < 40 || val > 47) && (val < 100 || val > 107) && val != 49 {
- // Keep non-background tokens
- newTokens = append(newTokens, tokens[i])
}
- }
- // Add new background if provided
- if newBg != "" {
- newTokens = append(newTokens, strings.Split(newBg, ";")...)
+ // decide whether to keep this token
+ // manually parse ASCII digits to int
+ isNum := true
+ val := 0
+ for p := i; p < j; p++ {
+ c := raw[p]
+ if c < '0' || c > '9' {
+ isNum = false
+ break
+ }
+ val = val*10 + int(c-'0')
+ }
+ keep := !isNum ||
+ ((val < 40 || val > 47) && (val < 100 || val > 107) && val != 49)
+
+ if keep {
+ if sb.Len() > 0 {
+ sb.WriteByte(';')
+ }
+ sb.WriteString(token)
+ }
+ // advance past this token (and the semicolon)
+ i = j + 1
}
- if len(newTokens) == 0 {
- return ""
+ // append our new background
+ if sb.Len() > 0 {
+ sb.WriteByte(';')
}
+ sb.WriteString(newBg)
- return "\x1b[" + strings.Join(newTokens, ";") + "m"
+ return "\x1b[" + sb.String() + "m"
})
}