mirror of
https://github.com/aljazceru/opencode.git
synced 2026-01-07 09:54:56 +01:00
feat: themes
This commit is contained in:
248
internal/tui/theme/catppuccin.go
Normal file
248
internal/tui/theme/catppuccin.go
Normal file
@@ -0,0 +1,248 @@
|
||||
package theme
|
||||
|
||||
import (
|
||||
catppuccin "github.com/catppuccin/go"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
// CatppuccinTheme implements the Theme interface with Catppuccin colors.
|
||||
// It provides both dark (Mocha) and light (Latte) variants.
|
||||
type CatppuccinTheme struct {
|
||||
BaseTheme
|
||||
}
|
||||
|
||||
// NewCatppuccinTheme creates a new instance of the Catppuccin theme.
|
||||
func NewCatppuccinTheme() *CatppuccinTheme {
|
||||
// Get the Catppuccin palettes
|
||||
mocha := catppuccin.Mocha
|
||||
latte := catppuccin.Latte
|
||||
|
||||
theme := &CatppuccinTheme{}
|
||||
|
||||
// Base colors
|
||||
theme.PrimaryColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Blue().Hex,
|
||||
Light: latte.Blue().Hex,
|
||||
}
|
||||
theme.SecondaryColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Mauve().Hex,
|
||||
Light: latte.Mauve().Hex,
|
||||
}
|
||||
theme.AccentColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Peach().Hex,
|
||||
Light: latte.Peach().Hex,
|
||||
}
|
||||
|
||||
// Status colors
|
||||
theme.ErrorColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Red().Hex,
|
||||
Light: latte.Red().Hex,
|
||||
}
|
||||
theme.WarningColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Peach().Hex,
|
||||
Light: latte.Peach().Hex,
|
||||
}
|
||||
theme.SuccessColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Green().Hex,
|
||||
Light: latte.Green().Hex,
|
||||
}
|
||||
theme.InfoColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Blue().Hex,
|
||||
Light: latte.Blue().Hex,
|
||||
}
|
||||
|
||||
// Text colors
|
||||
theme.TextColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Text().Hex,
|
||||
Light: latte.Text().Hex,
|
||||
}
|
||||
theme.TextMutedColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Subtext0().Hex,
|
||||
Light: latte.Subtext0().Hex,
|
||||
}
|
||||
theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Lavender().Hex,
|
||||
Light: latte.Lavender().Hex,
|
||||
}
|
||||
|
||||
// Background colors
|
||||
theme.BackgroundColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#212121", // From existing styles
|
||||
Light: "#EEEEEE", // Light equivalent
|
||||
}
|
||||
theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#2c2c2c", // From existing styles
|
||||
Light: "#E0E0E0", // Light equivalent
|
||||
}
|
||||
theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#181818", // From existing styles
|
||||
Light: "#F5F5F5", // Light equivalent
|
||||
}
|
||||
|
||||
// Border colors
|
||||
theme.BorderNormalColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#4b4c5c", // From existing styles
|
||||
Light: "#BDBDBD", // Light equivalent
|
||||
}
|
||||
theme.BorderFocusedColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Blue().Hex,
|
||||
Light: latte.Blue().Hex,
|
||||
}
|
||||
theme.BorderDimColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Surface0().Hex,
|
||||
Light: latte.Surface0().Hex,
|
||||
}
|
||||
|
||||
// Diff view colors
|
||||
theme.DiffAddedColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#478247", // From existing diff.go
|
||||
Light: "#2E7D32", // Light equivalent
|
||||
}
|
||||
theme.DiffRemovedColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#7C4444", // From existing diff.go
|
||||
Light: "#C62828", // Light equivalent
|
||||
}
|
||||
theme.DiffContextColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#a0a0a0", // From existing diff.go
|
||||
Light: "#757575", // Light equivalent
|
||||
}
|
||||
theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#a0a0a0", // From existing diff.go
|
||||
Light: "#757575", // Light equivalent
|
||||
}
|
||||
theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#DAFADA", // From existing diff.go
|
||||
Light: "#A5D6A7", // Light equivalent
|
||||
}
|
||||
theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#FADADD", // From existing diff.go
|
||||
Light: "#EF9A9A", // Light equivalent
|
||||
}
|
||||
theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#303A30", // From existing diff.go
|
||||
Light: "#E8F5E9", // Light equivalent
|
||||
}
|
||||
theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#3A3030", // From existing diff.go
|
||||
Light: "#FFEBEE", // Light equivalent
|
||||
}
|
||||
theme.DiffContextBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#212121", // From existing diff.go
|
||||
Light: "#F5F5F5", // Light equivalent
|
||||
}
|
||||
theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#888888", // From existing diff.go
|
||||
Light: "#9E9E9E", // Light equivalent
|
||||
}
|
||||
theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#293229", // From existing diff.go
|
||||
Light: "#C8E6C9", // Light equivalent
|
||||
}
|
||||
theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#332929", // From existing diff.go
|
||||
Light: "#FFCDD2", // Light equivalent
|
||||
}
|
||||
|
||||
// Markdown colors
|
||||
theme.MarkdownTextColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Text().Hex,
|
||||
Light: latte.Text().Hex,
|
||||
}
|
||||
theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Mauve().Hex,
|
||||
Light: latte.Mauve().Hex,
|
||||
}
|
||||
theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Sky().Hex,
|
||||
Light: latte.Sky().Hex,
|
||||
}
|
||||
theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Pink().Hex,
|
||||
Light: latte.Pink().Hex,
|
||||
}
|
||||
theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Green().Hex,
|
||||
Light: latte.Green().Hex,
|
||||
}
|
||||
theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Yellow().Hex,
|
||||
Light: latte.Yellow().Hex,
|
||||
}
|
||||
theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Yellow().Hex,
|
||||
Light: latte.Yellow().Hex,
|
||||
}
|
||||
theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Peach().Hex,
|
||||
Light: latte.Peach().Hex,
|
||||
}
|
||||
theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Overlay0().Hex,
|
||||
Light: latte.Overlay0().Hex,
|
||||
}
|
||||
theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Blue().Hex,
|
||||
Light: latte.Blue().Hex,
|
||||
}
|
||||
theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Sky().Hex,
|
||||
Light: latte.Sky().Hex,
|
||||
}
|
||||
theme.MarkdownImageColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Sapphire().Hex,
|
||||
Light: latte.Sapphire().Hex,
|
||||
}
|
||||
theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Pink().Hex,
|
||||
Light: latte.Pink().Hex,
|
||||
}
|
||||
theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Text().Hex,
|
||||
Light: latte.Text().Hex,
|
||||
}
|
||||
|
||||
// Syntax highlighting colors
|
||||
theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Overlay1().Hex,
|
||||
Light: latte.Overlay1().Hex,
|
||||
}
|
||||
theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Pink().Hex,
|
||||
Light: latte.Pink().Hex,
|
||||
}
|
||||
theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Green().Hex,
|
||||
Light: latte.Green().Hex,
|
||||
}
|
||||
theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Sky().Hex,
|
||||
Light: latte.Sky().Hex,
|
||||
}
|
||||
theme.SyntaxStringColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Yellow().Hex,
|
||||
Light: latte.Yellow().Hex,
|
||||
}
|
||||
theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Teal().Hex,
|
||||
Light: latte.Teal().Hex,
|
||||
}
|
||||
theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Sky().Hex,
|
||||
Light: latte.Sky().Hex,
|
||||
}
|
||||
theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Pink().Hex,
|
||||
Light: latte.Pink().Hex,
|
||||
}
|
||||
theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
|
||||
Dark: mocha.Text().Hex,
|
||||
Light: latte.Text().Hex,
|
||||
}
|
||||
|
||||
return theme
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Register the Catppuccin theme with the theme manager
|
||||
RegisterTheme("catppuccin", NewCatppuccinTheme())
|
||||
}
|
||||
302
internal/tui/theme/gruvbox.go
Normal file
302
internal/tui/theme/gruvbox.go
Normal file
@@ -0,0 +1,302 @@
|
||||
package theme
|
||||
|
||||
import (
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
// Gruvbox color palette constants
|
||||
const (
|
||||
// Dark theme colors
|
||||
gruvboxDarkBg0 = "#282828"
|
||||
gruvboxDarkBg0Soft = "#32302f"
|
||||
gruvboxDarkBg1 = "#3c3836"
|
||||
gruvboxDarkBg2 = "#504945"
|
||||
gruvboxDarkBg3 = "#665c54"
|
||||
gruvboxDarkBg4 = "#7c6f64"
|
||||
gruvboxDarkFg0 = "#fbf1c7"
|
||||
gruvboxDarkFg1 = "#ebdbb2"
|
||||
gruvboxDarkFg2 = "#d5c4a1"
|
||||
gruvboxDarkFg3 = "#bdae93"
|
||||
gruvboxDarkFg4 = "#a89984"
|
||||
gruvboxDarkGray = "#928374"
|
||||
gruvboxDarkRed = "#cc241d"
|
||||
gruvboxDarkRedBright = "#fb4934"
|
||||
gruvboxDarkGreen = "#98971a"
|
||||
gruvboxDarkGreenBright = "#b8bb26"
|
||||
gruvboxDarkYellow = "#d79921"
|
||||
gruvboxDarkYellowBright = "#fabd2f"
|
||||
gruvboxDarkBlue = "#458588"
|
||||
gruvboxDarkBlueBright = "#83a598"
|
||||
gruvboxDarkPurple = "#b16286"
|
||||
gruvboxDarkPurpleBright = "#d3869b"
|
||||
gruvboxDarkAqua = "#689d6a"
|
||||
gruvboxDarkAquaBright = "#8ec07c"
|
||||
gruvboxDarkOrange = "#d65d0e"
|
||||
gruvboxDarkOrangeBright = "#fe8019"
|
||||
|
||||
// Light theme colors
|
||||
gruvboxLightBg0 = "#fbf1c7"
|
||||
gruvboxLightBg0Soft = "#f2e5bc"
|
||||
gruvboxLightBg1 = "#ebdbb2"
|
||||
gruvboxLightBg2 = "#d5c4a1"
|
||||
gruvboxLightBg3 = "#bdae93"
|
||||
gruvboxLightBg4 = "#a89984"
|
||||
gruvboxLightFg0 = "#282828"
|
||||
gruvboxLightFg1 = "#3c3836"
|
||||
gruvboxLightFg2 = "#504945"
|
||||
gruvboxLightFg3 = "#665c54"
|
||||
gruvboxLightFg4 = "#7c6f64"
|
||||
gruvboxLightGray = "#928374"
|
||||
gruvboxLightRed = "#9d0006"
|
||||
gruvboxLightRedBright = "#cc241d"
|
||||
gruvboxLightGreen = "#79740e"
|
||||
gruvboxLightGreenBright = "#98971a"
|
||||
gruvboxLightYellow = "#b57614"
|
||||
gruvboxLightYellowBright = "#d79921"
|
||||
gruvboxLightBlue = "#076678"
|
||||
gruvboxLightBlueBright = "#458588"
|
||||
gruvboxLightPurple = "#8f3f71"
|
||||
gruvboxLightPurpleBright = "#b16286"
|
||||
gruvboxLightAqua = "#427b58"
|
||||
gruvboxLightAquaBright = "#689d6a"
|
||||
gruvboxLightOrange = "#af3a03"
|
||||
gruvboxLightOrangeBright = "#d65d0e"
|
||||
)
|
||||
|
||||
// GruvboxTheme implements the Theme interface with Gruvbox colors.
|
||||
// It provides both dark and light variants.
|
||||
type GruvboxTheme struct {
|
||||
BaseTheme
|
||||
}
|
||||
|
||||
// NewGruvboxTheme creates a new instance of the Gruvbox theme.
|
||||
func NewGruvboxTheme() *GruvboxTheme {
|
||||
theme := &GruvboxTheme{}
|
||||
|
||||
// Base colors
|
||||
theme.PrimaryColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBlueBright,
|
||||
Light: gruvboxLightBlueBright,
|
||||
}
|
||||
theme.SecondaryColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkPurpleBright,
|
||||
Light: gruvboxLightPurpleBright,
|
||||
}
|
||||
theme.AccentColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkOrangeBright,
|
||||
Light: gruvboxLightOrangeBright,
|
||||
}
|
||||
|
||||
// Status colors
|
||||
theme.ErrorColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkRedBright,
|
||||
Light: gruvboxLightRedBright,
|
||||
}
|
||||
theme.WarningColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkYellowBright,
|
||||
Light: gruvboxLightYellowBright,
|
||||
}
|
||||
theme.SuccessColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkGreenBright,
|
||||
Light: gruvboxLightGreenBright,
|
||||
}
|
||||
theme.InfoColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBlueBright,
|
||||
Light: gruvboxLightBlueBright,
|
||||
}
|
||||
|
||||
// Text colors
|
||||
theme.TextColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkFg1,
|
||||
Light: gruvboxLightFg1,
|
||||
}
|
||||
theme.TextMutedColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkFg4,
|
||||
Light: gruvboxLightFg4,
|
||||
}
|
||||
theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkYellowBright,
|
||||
Light: gruvboxLightYellowBright,
|
||||
}
|
||||
|
||||
// Background colors
|
||||
theme.BackgroundColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBg0,
|
||||
Light: gruvboxLightBg0,
|
||||
}
|
||||
theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBg1,
|
||||
Light: gruvboxLightBg1,
|
||||
}
|
||||
theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBg0Soft,
|
||||
Light: gruvboxLightBg0Soft,
|
||||
}
|
||||
|
||||
// Border colors
|
||||
theme.BorderNormalColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBg2,
|
||||
Light: gruvboxLightBg2,
|
||||
}
|
||||
theme.BorderFocusedColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBlueBright,
|
||||
Light: gruvboxLightBlueBright,
|
||||
}
|
||||
theme.BorderDimColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBg1,
|
||||
Light: gruvboxLightBg1,
|
||||
}
|
||||
|
||||
// Diff view colors
|
||||
theme.DiffAddedColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkGreenBright,
|
||||
Light: gruvboxLightGreenBright,
|
||||
}
|
||||
theme.DiffRemovedColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkRedBright,
|
||||
Light: gruvboxLightRedBright,
|
||||
}
|
||||
theme.DiffContextColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkFg4,
|
||||
Light: gruvboxLightFg4,
|
||||
}
|
||||
theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkFg3,
|
||||
Light: gruvboxLightFg3,
|
||||
}
|
||||
theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkGreenBright,
|
||||
Light: gruvboxLightGreenBright,
|
||||
}
|
||||
theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkRedBright,
|
||||
Light: gruvboxLightRedBright,
|
||||
}
|
||||
theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#3C4C3C", // Darker green background
|
||||
Light: "#E8F5E9", // Light green background
|
||||
}
|
||||
theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#4C3C3C", // Darker red background
|
||||
Light: "#FFEBEE", // Light red background
|
||||
}
|
||||
theme.DiffContextBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBg0,
|
||||
Light: gruvboxLightBg0,
|
||||
}
|
||||
theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkFg4,
|
||||
Light: gruvboxLightFg4,
|
||||
}
|
||||
theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#32432F", // Slightly darker green
|
||||
Light: "#C8E6C9", // Light green
|
||||
}
|
||||
theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
|
||||
Dark: "#43322F", // Slightly darker red
|
||||
Light: "#FFCDD2", // Light red
|
||||
}
|
||||
|
||||
// Markdown colors
|
||||
theme.MarkdownTextColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkFg1,
|
||||
Light: gruvboxLightFg1,
|
||||
}
|
||||
theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkYellowBright,
|
||||
Light: gruvboxLightYellowBright,
|
||||
}
|
||||
theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBlueBright,
|
||||
Light: gruvboxLightBlueBright,
|
||||
}
|
||||
theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkAquaBright,
|
||||
Light: gruvboxLightAquaBright,
|
||||
}
|
||||
theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkGreenBright,
|
||||
Light: gruvboxLightGreenBright,
|
||||
}
|
||||
theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkAquaBright,
|
||||
Light: gruvboxLightAquaBright,
|
||||
}
|
||||
theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkYellowBright,
|
||||
Light: gruvboxLightYellowBright,
|
||||
}
|
||||
theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkOrangeBright,
|
||||
Light: gruvboxLightOrangeBright,
|
||||
}
|
||||
theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBg3,
|
||||
Light: gruvboxLightBg3,
|
||||
}
|
||||
theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBlueBright,
|
||||
Light: gruvboxLightBlueBright,
|
||||
}
|
||||
theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBlueBright,
|
||||
Light: gruvboxLightBlueBright,
|
||||
}
|
||||
theme.MarkdownImageColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkPurpleBright,
|
||||
Light: gruvboxLightPurpleBright,
|
||||
}
|
||||
theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkAquaBright,
|
||||
Light: gruvboxLightAquaBright,
|
||||
}
|
||||
theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkFg1,
|
||||
Light: gruvboxLightFg1,
|
||||
}
|
||||
|
||||
// Syntax highlighting colors
|
||||
theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkGray,
|
||||
Light: gruvboxLightGray,
|
||||
}
|
||||
theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkRedBright,
|
||||
Light: gruvboxLightRedBright,
|
||||
}
|
||||
theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkGreenBright,
|
||||
Light: gruvboxLightGreenBright,
|
||||
}
|
||||
theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkBlueBright,
|
||||
Light: gruvboxLightBlueBright,
|
||||
}
|
||||
theme.SyntaxStringColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkYellowBright,
|
||||
Light: gruvboxLightYellowBright,
|
||||
}
|
||||
theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkPurpleBright,
|
||||
Light: gruvboxLightPurpleBright,
|
||||
}
|
||||
theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkYellow,
|
||||
Light: gruvboxLightYellow,
|
||||
}
|
||||
theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkAquaBright,
|
||||
Light: gruvboxLightAquaBright,
|
||||
}
|
||||
theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
|
||||
Dark: gruvboxDarkFg1,
|
||||
Light: gruvboxLightFg1,
|
||||
}
|
||||
|
||||
return theme
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Register the Gruvbox theme with the theme manager
|
||||
RegisterTheme("gruvbox", NewGruvboxTheme())
|
||||
}
|
||||
113
internal/tui/theme/manager.go
Normal file
113
internal/tui/theme/manager.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package theme
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/alecthomas/chroma/v2/styles"
|
||||
"github.com/opencode-ai/opencode/internal/config"
|
||||
"github.com/opencode-ai/opencode/internal/logging"
|
||||
)
|
||||
|
||||
// Manager handles theme registration, selection, and retrieval.
|
||||
// It maintains a registry of available themes and tracks the currently active theme.
|
||||
type Manager struct {
|
||||
themes map[string]Theme
|
||||
currentName string
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// Global instance of the theme manager
|
||||
var globalManager = &Manager{
|
||||
themes: make(map[string]Theme),
|
||||
currentName: "",
|
||||
}
|
||||
|
||||
// RegisterTheme adds a new theme to the registry.
|
||||
// If this is the first theme registered, it becomes the default.
|
||||
func RegisterTheme(name string, theme Theme) {
|
||||
globalManager.mu.Lock()
|
||||
defer globalManager.mu.Unlock()
|
||||
|
||||
globalManager.themes[name] = theme
|
||||
|
||||
// If this is the first theme, make it the default
|
||||
if globalManager.currentName == "" {
|
||||
globalManager.currentName = name
|
||||
}
|
||||
}
|
||||
|
||||
// SetTheme changes the active theme to the one with the specified name.
|
||||
// Returns an error if the theme doesn't exist.
|
||||
func SetTheme(name string) error {
|
||||
globalManager.mu.Lock()
|
||||
defer globalManager.mu.Unlock()
|
||||
|
||||
delete(styles.Registry, "charm")
|
||||
if _, exists := globalManager.themes[name]; !exists {
|
||||
return fmt.Errorf("theme '%s' not found", name)
|
||||
}
|
||||
|
||||
globalManager.currentName = name
|
||||
|
||||
// Update the config file using viper
|
||||
if err := updateConfigTheme(name); err != nil {
|
||||
// Log the error but don't fail the theme change
|
||||
logging.Warn("Warning: Failed to update config file with new theme", "err", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CurrentTheme returns the currently active theme.
|
||||
// If no theme is set, it returns nil.
|
||||
func CurrentTheme() Theme {
|
||||
globalManager.mu.RLock()
|
||||
defer globalManager.mu.RUnlock()
|
||||
|
||||
if globalManager.currentName == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return globalManager.themes[globalManager.currentName]
|
||||
}
|
||||
|
||||
// CurrentThemeName returns the name of the currently active theme.
|
||||
func CurrentThemeName() string {
|
||||
globalManager.mu.RLock()
|
||||
defer globalManager.mu.RUnlock()
|
||||
|
||||
return globalManager.currentName
|
||||
}
|
||||
|
||||
// AvailableThemes returns a list of all registered theme names.
|
||||
func AvailableThemes() []string {
|
||||
globalManager.mu.RLock()
|
||||
defer globalManager.mu.RUnlock()
|
||||
|
||||
names := make([]string, 0, len(globalManager.themes))
|
||||
for name := range globalManager.themes {
|
||||
names = append(names, name)
|
||||
}
|
||||
slices.SortFunc(names, func(a, b string) int {
|
||||
return strings.Compare(a, b)
|
||||
})
|
||||
return names
|
||||
}
|
||||
|
||||
// GetTheme returns a specific theme by name.
|
||||
// Returns nil if the theme doesn't exist.
|
||||
func GetTheme(name string) Theme {
|
||||
globalManager.mu.RLock()
|
||||
defer globalManager.mu.RUnlock()
|
||||
|
||||
return globalManager.themes[name]
|
||||
}
|
||||
|
||||
// updateConfigTheme updates the theme setting in the configuration file
|
||||
func updateConfigTheme(themeName string) error {
|
||||
// Use the config package to update the theme
|
||||
return config.UpdateTheme(themeName)
|
||||
}
|
||||
208
internal/tui/theme/theme.go
Normal file
208
internal/tui/theme/theme.go
Normal file
@@ -0,0 +1,208 @@
|
||||
package theme
|
||||
|
||||
import (
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
// Theme defines the interface for all UI themes in the application.
|
||||
// All colors must be defined as lipgloss.AdaptiveColor to support
|
||||
// both light and dark terminal backgrounds.
|
||||
type Theme interface {
|
||||
// Base colors
|
||||
Primary() lipgloss.AdaptiveColor
|
||||
Secondary() lipgloss.AdaptiveColor
|
||||
Accent() lipgloss.AdaptiveColor
|
||||
|
||||
// Status colors
|
||||
Error() lipgloss.AdaptiveColor
|
||||
Warning() lipgloss.AdaptiveColor
|
||||
Success() lipgloss.AdaptiveColor
|
||||
Info() lipgloss.AdaptiveColor
|
||||
|
||||
// Text colors
|
||||
Text() lipgloss.AdaptiveColor
|
||||
TextMuted() lipgloss.AdaptiveColor
|
||||
TextEmphasized() lipgloss.AdaptiveColor
|
||||
|
||||
// Background colors
|
||||
Background() lipgloss.AdaptiveColor
|
||||
BackgroundSecondary() lipgloss.AdaptiveColor
|
||||
BackgroundDarker() lipgloss.AdaptiveColor
|
||||
|
||||
// Border colors
|
||||
BorderNormal() lipgloss.AdaptiveColor
|
||||
BorderFocused() lipgloss.AdaptiveColor
|
||||
BorderDim() lipgloss.AdaptiveColor
|
||||
|
||||
// Diff view colors
|
||||
DiffAdded() lipgloss.AdaptiveColor
|
||||
DiffRemoved() lipgloss.AdaptiveColor
|
||||
DiffContext() lipgloss.AdaptiveColor
|
||||
DiffHunkHeader() lipgloss.AdaptiveColor
|
||||
DiffHighlightAdded() lipgloss.AdaptiveColor
|
||||
DiffHighlightRemoved() lipgloss.AdaptiveColor
|
||||
DiffAddedBg() lipgloss.AdaptiveColor
|
||||
DiffRemovedBg() lipgloss.AdaptiveColor
|
||||
DiffContextBg() lipgloss.AdaptiveColor
|
||||
DiffLineNumber() lipgloss.AdaptiveColor
|
||||
DiffAddedLineNumberBg() lipgloss.AdaptiveColor
|
||||
DiffRemovedLineNumberBg() lipgloss.AdaptiveColor
|
||||
|
||||
// Markdown colors
|
||||
MarkdownText() lipgloss.AdaptiveColor
|
||||
MarkdownHeading() lipgloss.AdaptiveColor
|
||||
MarkdownLink() lipgloss.AdaptiveColor
|
||||
MarkdownLinkText() lipgloss.AdaptiveColor
|
||||
MarkdownCode() lipgloss.AdaptiveColor
|
||||
MarkdownBlockQuote() lipgloss.AdaptiveColor
|
||||
MarkdownEmph() lipgloss.AdaptiveColor
|
||||
MarkdownStrong() lipgloss.AdaptiveColor
|
||||
MarkdownHorizontalRule() lipgloss.AdaptiveColor
|
||||
MarkdownListItem() lipgloss.AdaptiveColor
|
||||
MarkdownListEnumeration() lipgloss.AdaptiveColor
|
||||
MarkdownImage() lipgloss.AdaptiveColor
|
||||
MarkdownImageText() lipgloss.AdaptiveColor
|
||||
MarkdownCodeBlock() lipgloss.AdaptiveColor
|
||||
|
||||
// Syntax highlighting colors
|
||||
SyntaxComment() lipgloss.AdaptiveColor
|
||||
SyntaxKeyword() lipgloss.AdaptiveColor
|
||||
SyntaxFunction() lipgloss.AdaptiveColor
|
||||
SyntaxVariable() lipgloss.AdaptiveColor
|
||||
SyntaxString() lipgloss.AdaptiveColor
|
||||
SyntaxNumber() lipgloss.AdaptiveColor
|
||||
SyntaxType() lipgloss.AdaptiveColor
|
||||
SyntaxOperator() lipgloss.AdaptiveColor
|
||||
SyntaxPunctuation() lipgloss.AdaptiveColor
|
||||
}
|
||||
|
||||
// BaseTheme provides a default implementation of the Theme interface
|
||||
// that can be embedded in concrete theme implementations.
|
||||
type BaseTheme struct {
|
||||
// Base colors
|
||||
PrimaryColor lipgloss.AdaptiveColor
|
||||
SecondaryColor lipgloss.AdaptiveColor
|
||||
AccentColor lipgloss.AdaptiveColor
|
||||
|
||||
// Status colors
|
||||
ErrorColor lipgloss.AdaptiveColor
|
||||
WarningColor lipgloss.AdaptiveColor
|
||||
SuccessColor lipgloss.AdaptiveColor
|
||||
InfoColor lipgloss.AdaptiveColor
|
||||
|
||||
// Text colors
|
||||
TextColor lipgloss.AdaptiveColor
|
||||
TextMutedColor lipgloss.AdaptiveColor
|
||||
TextEmphasizedColor lipgloss.AdaptiveColor
|
||||
|
||||
// Background colors
|
||||
BackgroundColor lipgloss.AdaptiveColor
|
||||
BackgroundSecondaryColor lipgloss.AdaptiveColor
|
||||
BackgroundDarkerColor lipgloss.AdaptiveColor
|
||||
|
||||
// Border colors
|
||||
BorderNormalColor lipgloss.AdaptiveColor
|
||||
BorderFocusedColor lipgloss.AdaptiveColor
|
||||
BorderDimColor lipgloss.AdaptiveColor
|
||||
|
||||
// Diff view colors
|
||||
DiffAddedColor lipgloss.AdaptiveColor
|
||||
DiffRemovedColor lipgloss.AdaptiveColor
|
||||
DiffContextColor lipgloss.AdaptiveColor
|
||||
DiffHunkHeaderColor lipgloss.AdaptiveColor
|
||||
DiffHighlightAddedColor lipgloss.AdaptiveColor
|
||||
DiffHighlightRemovedColor lipgloss.AdaptiveColor
|
||||
DiffAddedBgColor lipgloss.AdaptiveColor
|
||||
DiffRemovedBgColor lipgloss.AdaptiveColor
|
||||
DiffContextBgColor lipgloss.AdaptiveColor
|
||||
DiffLineNumberColor lipgloss.AdaptiveColor
|
||||
DiffAddedLineNumberBgColor lipgloss.AdaptiveColor
|
||||
DiffRemovedLineNumberBgColor lipgloss.AdaptiveColor
|
||||
|
||||
// Markdown colors
|
||||
MarkdownTextColor lipgloss.AdaptiveColor
|
||||
MarkdownHeadingColor lipgloss.AdaptiveColor
|
||||
MarkdownLinkColor lipgloss.AdaptiveColor
|
||||
MarkdownLinkTextColor lipgloss.AdaptiveColor
|
||||
MarkdownCodeColor lipgloss.AdaptiveColor
|
||||
MarkdownBlockQuoteColor lipgloss.AdaptiveColor
|
||||
MarkdownEmphColor lipgloss.AdaptiveColor
|
||||
MarkdownStrongColor lipgloss.AdaptiveColor
|
||||
MarkdownHorizontalRuleColor lipgloss.AdaptiveColor
|
||||
MarkdownListItemColor lipgloss.AdaptiveColor
|
||||
MarkdownListEnumerationColor lipgloss.AdaptiveColor
|
||||
MarkdownImageColor lipgloss.AdaptiveColor
|
||||
MarkdownImageTextColor lipgloss.AdaptiveColor
|
||||
MarkdownCodeBlockColor lipgloss.AdaptiveColor
|
||||
|
||||
// Syntax highlighting colors
|
||||
SyntaxCommentColor lipgloss.AdaptiveColor
|
||||
SyntaxKeywordColor lipgloss.AdaptiveColor
|
||||
SyntaxFunctionColor lipgloss.AdaptiveColor
|
||||
SyntaxVariableColor lipgloss.AdaptiveColor
|
||||
SyntaxStringColor lipgloss.AdaptiveColor
|
||||
SyntaxNumberColor lipgloss.AdaptiveColor
|
||||
SyntaxTypeColor lipgloss.AdaptiveColor
|
||||
SyntaxOperatorColor lipgloss.AdaptiveColor
|
||||
SyntaxPunctuationColor lipgloss.AdaptiveColor
|
||||
}
|
||||
|
||||
// Implement the Theme interface for BaseTheme
|
||||
func (t *BaseTheme) Primary() lipgloss.AdaptiveColor { return t.PrimaryColor }
|
||||
func (t *BaseTheme) Secondary() lipgloss.AdaptiveColor { return t.SecondaryColor }
|
||||
func (t *BaseTheme) Accent() lipgloss.AdaptiveColor { return t.AccentColor }
|
||||
|
||||
func (t *BaseTheme) Error() lipgloss.AdaptiveColor { return t.ErrorColor }
|
||||
func (t *BaseTheme) Warning() lipgloss.AdaptiveColor { return t.WarningColor }
|
||||
func (t *BaseTheme) Success() lipgloss.AdaptiveColor { return t.SuccessColor }
|
||||
func (t *BaseTheme) Info() lipgloss.AdaptiveColor { return t.InfoColor }
|
||||
|
||||
func (t *BaseTheme) Text() lipgloss.AdaptiveColor { return t.TextColor }
|
||||
func (t *BaseTheme) TextMuted() lipgloss.AdaptiveColor { return t.TextMutedColor }
|
||||
func (t *BaseTheme) TextEmphasized() lipgloss.AdaptiveColor { return t.TextEmphasizedColor }
|
||||
|
||||
func (t *BaseTheme) Background() lipgloss.AdaptiveColor { return t.BackgroundColor }
|
||||
func (t *BaseTheme) BackgroundSecondary() lipgloss.AdaptiveColor { return t.BackgroundSecondaryColor }
|
||||
func (t *BaseTheme) BackgroundDarker() lipgloss.AdaptiveColor { return t.BackgroundDarkerColor }
|
||||
|
||||
func (t *BaseTheme) BorderNormal() lipgloss.AdaptiveColor { return t.BorderNormalColor }
|
||||
func (t *BaseTheme) BorderFocused() lipgloss.AdaptiveColor { return t.BorderFocusedColor }
|
||||
func (t *BaseTheme) BorderDim() lipgloss.AdaptiveColor { return t.BorderDimColor }
|
||||
|
||||
func (t *BaseTheme) DiffAdded() lipgloss.AdaptiveColor { return t.DiffAddedColor }
|
||||
func (t *BaseTheme) DiffRemoved() lipgloss.AdaptiveColor { return t.DiffRemovedColor }
|
||||
func (t *BaseTheme) DiffContext() lipgloss.AdaptiveColor { return t.DiffContextColor }
|
||||
func (t *BaseTheme) DiffHunkHeader() lipgloss.AdaptiveColor { return t.DiffHunkHeaderColor }
|
||||
func (t *BaseTheme) DiffHighlightAdded() lipgloss.AdaptiveColor { return t.DiffHighlightAddedColor }
|
||||
func (t *BaseTheme) DiffHighlightRemoved() lipgloss.AdaptiveColor { return t.DiffHighlightRemovedColor }
|
||||
func (t *BaseTheme) DiffAddedBg() lipgloss.AdaptiveColor { return t.DiffAddedBgColor }
|
||||
func (t *BaseTheme) DiffRemovedBg() lipgloss.AdaptiveColor { return t.DiffRemovedBgColor }
|
||||
func (t *BaseTheme) DiffContextBg() lipgloss.AdaptiveColor { return t.DiffContextBgColor }
|
||||
func (t *BaseTheme) DiffLineNumber() lipgloss.AdaptiveColor { return t.DiffLineNumberColor }
|
||||
func (t *BaseTheme) DiffAddedLineNumberBg() lipgloss.AdaptiveColor { return t.DiffAddedLineNumberBgColor }
|
||||
func (t *BaseTheme) DiffRemovedLineNumberBg() lipgloss.AdaptiveColor { return t.DiffRemovedLineNumberBgColor }
|
||||
|
||||
func (t *BaseTheme) MarkdownText() lipgloss.AdaptiveColor { return t.MarkdownTextColor }
|
||||
func (t *BaseTheme) MarkdownHeading() lipgloss.AdaptiveColor { return t.MarkdownHeadingColor }
|
||||
func (t *BaseTheme) MarkdownLink() lipgloss.AdaptiveColor { return t.MarkdownLinkColor }
|
||||
func (t *BaseTheme) MarkdownLinkText() lipgloss.AdaptiveColor { return t.MarkdownLinkTextColor }
|
||||
func (t *BaseTheme) MarkdownCode() lipgloss.AdaptiveColor { return t.MarkdownCodeColor }
|
||||
func (t *BaseTheme) MarkdownBlockQuote() lipgloss.AdaptiveColor { return t.MarkdownBlockQuoteColor }
|
||||
func (t *BaseTheme) MarkdownEmph() lipgloss.AdaptiveColor { return t.MarkdownEmphColor }
|
||||
func (t *BaseTheme) MarkdownStrong() lipgloss.AdaptiveColor { return t.MarkdownStrongColor }
|
||||
func (t *BaseTheme) MarkdownHorizontalRule() lipgloss.AdaptiveColor { return t.MarkdownHorizontalRuleColor }
|
||||
func (t *BaseTheme) MarkdownListItem() lipgloss.AdaptiveColor { return t.MarkdownListItemColor }
|
||||
func (t *BaseTheme) MarkdownListEnumeration() lipgloss.AdaptiveColor { return t.MarkdownListEnumerationColor }
|
||||
func (t *BaseTheme) MarkdownImage() lipgloss.AdaptiveColor { return t.MarkdownImageColor }
|
||||
func (t *BaseTheme) MarkdownImageText() lipgloss.AdaptiveColor { return t.MarkdownImageTextColor }
|
||||
func (t *BaseTheme) MarkdownCodeBlock() lipgloss.AdaptiveColor { return t.MarkdownCodeBlockColor }
|
||||
|
||||
func (t *BaseTheme) SyntaxComment() lipgloss.AdaptiveColor { return t.SyntaxCommentColor }
|
||||
func (t *BaseTheme) SyntaxKeyword() lipgloss.AdaptiveColor { return t.SyntaxKeywordColor }
|
||||
func (t *BaseTheme) SyntaxFunction() lipgloss.AdaptiveColor { return t.SyntaxFunctionColor }
|
||||
func (t *BaseTheme) SyntaxVariable() lipgloss.AdaptiveColor { return t.SyntaxVariableColor }
|
||||
func (t *BaseTheme) SyntaxString() lipgloss.AdaptiveColor { return t.SyntaxStringColor }
|
||||
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 }
|
||||
89
internal/tui/theme/theme_test.go
Normal file
89
internal/tui/theme/theme_test.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package theme
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestThemeRegistration(t *testing.T) {
|
||||
// Get list of available themes
|
||||
availableThemes := AvailableThemes()
|
||||
|
||||
// Check if "catppuccin" theme is registered
|
||||
catppuccinFound := false
|
||||
for _, themeName := range availableThemes {
|
||||
if themeName == "catppuccin" {
|
||||
catppuccinFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !catppuccinFound {
|
||||
t.Errorf("Catppuccin theme is not registered")
|
||||
}
|
||||
|
||||
// Check if "gruvbox" theme is registered
|
||||
gruvboxFound := false
|
||||
for _, themeName := range availableThemes {
|
||||
if themeName == "gruvbox" {
|
||||
gruvboxFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !gruvboxFound {
|
||||
t.Errorf("Gruvbox theme is not registered")
|
||||
}
|
||||
|
||||
// Check if "monokai" theme is registered
|
||||
monokaiFound := false
|
||||
for _, themeName := range availableThemes {
|
||||
if themeName == "monokai" {
|
||||
monokaiFound = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !monokaiFound {
|
||||
t.Errorf("Monokai theme is not registered")
|
||||
}
|
||||
|
||||
// Try to get the themes and make sure they're not nil
|
||||
catppuccin := GetTheme("catppuccin")
|
||||
if catppuccin == nil {
|
||||
t.Errorf("Catppuccin theme is nil")
|
||||
}
|
||||
|
||||
gruvbox := GetTheme("gruvbox")
|
||||
if gruvbox == nil {
|
||||
t.Errorf("Gruvbox theme is nil")
|
||||
}
|
||||
|
||||
monokai := GetTheme("monokai")
|
||||
if monokai == nil {
|
||||
t.Errorf("Monokai theme is nil")
|
||||
}
|
||||
|
||||
// Test switching theme
|
||||
originalTheme := CurrentThemeName()
|
||||
|
||||
err := SetTheme("gruvbox")
|
||||
if err != nil {
|
||||
t.Errorf("Failed to set theme to gruvbox: %v", err)
|
||||
}
|
||||
|
||||
if CurrentThemeName() != "gruvbox" {
|
||||
t.Errorf("Theme not properly switched to gruvbox")
|
||||
}
|
||||
|
||||
err = SetTheme("monokai")
|
||||
if err != nil {
|
||||
t.Errorf("Failed to set theme to monokai: %v", err)
|
||||
}
|
||||
|
||||
if CurrentThemeName() != "monokai" {
|
||||
t.Errorf("Theme not properly switched to monokai")
|
||||
}
|
||||
|
||||
// Switch back to original theme
|
||||
_ = SetTheme(originalTheme)
|
||||
}
|
||||
Reference in New Issue
Block a user