diff options
| author | adamdottv <[email protected]> | 2025-04-30 11:05:59 -0500 |
|---|---|---|
| committer | adamdottv <[email protected]> | 2025-04-30 11:05:59 -0500 |
| commit | 91ae9b33d37df7a53bda958d787268ef0f917ffd (patch) | |
| tree | 27d1ceb87f30c666e20ebf6c7baeb8e1bd34693a /internal/tui/theme/theme.go | |
| parent | a42175c067dd6b3e594d1e8de4f39a441bd9603b (diff) | |
| download | opencode-91ae9b33d37df7a53bda958d787268ef0f917ffd.tar.gz opencode-91ae9b33d37df7a53bda958d787268ef0f917ffd.zip | |
feat: custom themes
Diffstat (limited to 'internal/tui/theme/theme.go')
| -rw-r--r-- | internal/tui/theme/theme.go | 51 |
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 |
