summaryrefslogtreecommitdiffhomepage
path: root/internal/tui/theme/theme.go
diff options
context:
space:
mode:
authoradamdottv <[email protected]>2025-04-30 11:05:59 -0500
committeradamdottv <[email protected]>2025-04-30 11:05:59 -0500
commit91ae9b33d37df7a53bda958d787268ef0f917ffd (patch)
tree27d1ceb87f30c666e20ebf6c7baeb8e1bd34693a /internal/tui/theme/theme.go
parenta42175c067dd6b3e594d1e8de4f39a441bd9603b (diff)
downloadopencode-91ae9b33d37df7a53bda958d787268ef0f917ffd.tar.gz
opencode-91ae9b33d37df7a53bda958d787268ef0f917ffd.zip
feat: custom themes
Diffstat (limited to 'internal/tui/theme/theme.go')
-rw-r--r--internal/tui/theme/theme.go51
1 files changed, 50 insertions, 1 deletions
diff --git a/internal/tui/theme/theme.go b/internal/tui/theme/theme.go
index 4ee14a07f..d0c64eb43 100644
--- a/internal/tui/theme/theme.go
+++ b/internal/tui/theme/theme.go
@@ -1,6 +1,9 @@
package theme
import (
+ "fmt"
+ "regexp"
+
"github.com/charmbracelet/lipgloss"
)
@@ -205,4 +208,50 @@ func (t *BaseTheme) SyntaxString() lipgloss.AdaptiveColor { return t.SyntaxStrin
func (t *BaseTheme) SyntaxNumber() lipgloss.AdaptiveColor { return t.SyntaxNumberColor }
func (t *BaseTheme) SyntaxType() lipgloss.AdaptiveColor { return t.SyntaxTypeColor }
func (t *BaseTheme) SyntaxOperator() lipgloss.AdaptiveColor { return t.SyntaxOperatorColor }
-func (t *BaseTheme) SyntaxPunctuation() lipgloss.AdaptiveColor { return t.SyntaxPunctuationColor } \ No newline at end of file
+func (t *BaseTheme) SyntaxPunctuation() lipgloss.AdaptiveColor { return t.SyntaxPunctuationColor }
+
+// ParseAdaptiveColor parses a color value from the config file into a lipgloss.AdaptiveColor.
+// It accepts either a string (hex color) or a map with "dark" and "light" keys.
+func ParseAdaptiveColor(value any) (lipgloss.AdaptiveColor, error) {
+ // Regular expression to validate hex color format
+ hexColorRegex := regexp.MustCompile(`^#[0-9a-fA-F]{6}$`)
+
+ // Case 1: String value (same color for both dark and light modes)
+ if hexColor, ok := value.(string); ok {
+ if !hexColorRegex.MatchString(hexColor) {
+ return lipgloss.AdaptiveColor{}, fmt.Errorf("invalid hex color format: %s", hexColor)
+ }
+ return lipgloss.AdaptiveColor{
+ Dark: hexColor,
+ Light: hexColor,
+ }, nil
+ }
+
+ // Case 2: Map with dark and light keys
+ if colorMap, ok := value.(map[string]any); ok {
+ darkVal, darkOk := colorMap["dark"]
+ lightVal, lightOk := colorMap["light"]
+
+ if !darkOk || !lightOk {
+ return lipgloss.AdaptiveColor{}, fmt.Errorf("color map must contain both 'dark' and 'light' keys")
+ }
+
+ darkHex, darkIsString := darkVal.(string)
+ lightHex, lightIsString := lightVal.(string)
+
+ if !darkIsString || !lightIsString {
+ return lipgloss.AdaptiveColor{}, fmt.Errorf("color values must be strings")
+ }
+
+ if !hexColorRegex.MatchString(darkHex) || !hexColorRegex.MatchString(lightHex) {
+ return lipgloss.AdaptiveColor{}, fmt.Errorf("invalid hex color format")
+ }
+
+ return lipgloss.AdaptiveColor{
+ Dark: darkHex,
+ Light: lightHex,
+ }, nil
+ }
+
+ return lipgloss.AdaptiveColor{}, fmt.Errorf("color must be either a hex string or an object with dark/light keys")
+} \ No newline at end of file