summaryrefslogtreecommitdiffhomepage
path: root/internal/tui/styles
diff options
context:
space:
mode:
authorKujtim Hoxha <[email protected]>2025-03-21 18:20:28 +0100
committerKujtim Hoxha <[email protected]>2025-03-21 18:20:28 +0100
commit4b0ea68d7af9a6031a7ffda7ad66e0cb83315750 (patch)
tree8220c1bf6f107ea76dd78c7f57b77000c0c98a22 /internal/tui/styles
downloadopencode-4b0ea68d7af9a6031a7ffda7ad66e0cb83315750.tar.gz
opencode-4b0ea68d7af9a6031a7ffda7ad66e0cb83315750.zip
initial
Diffstat (limited to 'internal/tui/styles')
-rw-r--r--internal/tui/styles/icons.go12
-rw-r--r--internal/tui/styles/markdown.go498
-rw-r--r--internal/tui/styles/styles.go121
3 files changed, 631 insertions, 0 deletions
diff --git a/internal/tui/styles/icons.go b/internal/tui/styles/icons.go
new file mode 100644
index 000000000..81a55aa07
--- /dev/null
+++ b/internal/tui/styles/icons.go
@@ -0,0 +1,12 @@
+package styles
+
+const (
+ SessionsIcon string = "󰧑"
+ ChatIcon string = "󰭹"
+
+ BotIcon string = "󰚩"
+ ToolIcon string = ""
+ UserIcon string = ""
+
+ SleepIcon string = "󰒲"
+)
diff --git a/internal/tui/styles/markdown.go b/internal/tui/styles/markdown.go
new file mode 100644
index 000000000..cadb9a2e3
--- /dev/null
+++ b/internal/tui/styles/markdown.go
@@ -0,0 +1,498 @@
+package styles
+
+import (
+ "github.com/charmbracelet/glamour/ansi"
+ "github.com/charmbracelet/lipgloss"
+)
+
+const defaultMargin = 2
+
+// Helper functions for style pointers
+func boolPtr(b bool) *bool { return &b }
+func stringPtr(s string) *string { return &s }
+func uintPtr(u uint) *uint { return &u }
+
+// CatppuccinMarkdownStyle is the Catppuccin Mocha style for Glamour markdown rendering.
+func CatppuccinMarkdownStyle() ansi.StyleConfig {
+ isDark := lipgloss.HasDarkBackground()
+ if isDark {
+ return catppuccinDark
+ }
+ return catppuccinLight
+}
+
+var catppuccinDark = ansi.StyleConfig{
+ Document: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ BlockPrefix: "\n",
+ BlockSuffix: "\n",
+ Color: stringPtr(dark.Text().Hex),
+ },
+ Margin: uintPtr(defaultMargin),
+ },
+ BlockQuote: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Color: stringPtr(dark.Yellow().Hex),
+ Italic: boolPtr(true),
+ Prefix: "┃ ",
+ },
+ Indent: uintPtr(1),
+ Margin: uintPtr(defaultMargin),
+ },
+ List: ansi.StyleList{
+ LevelIndent: defaultMargin,
+ StyleBlock: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Color: stringPtr(dark.Text().Hex),
+ },
+ },
+ },
+ Heading: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ BlockSuffix: "\n",
+ Color: stringPtr(dark.Mauve().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ H1: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "# ",
+ Color: stringPtr(dark.Lavender().Hex),
+ Bold: boolPtr(true),
+ BlockPrefix: "\n",
+ },
+ },
+ H2: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "## ",
+ Color: stringPtr(dark.Mauve().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ H3: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "### ",
+ Color: stringPtr(dark.Pink().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ H4: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "#### ",
+ Color: stringPtr(dark.Flamingo().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ H5: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "##### ",
+ Color: stringPtr(dark.Rosewater().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ H6: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "###### ",
+ Color: stringPtr(dark.Rosewater().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ Strikethrough: ansi.StylePrimitive{
+ CrossedOut: boolPtr(true),
+ Color: stringPtr(dark.Overlay1().Hex),
+ },
+ Emph: ansi.StylePrimitive{
+ Color: stringPtr(dark.Yellow().Hex),
+ Italic: boolPtr(true),
+ },
+ Strong: ansi.StylePrimitive{
+ Bold: boolPtr(true),
+ Color: stringPtr(dark.Peach().Hex),
+ },
+ HorizontalRule: ansi.StylePrimitive{
+ Color: stringPtr(dark.Overlay0().Hex),
+ Format: "\n─────────────────────────────────────────\n",
+ },
+ Item: ansi.StylePrimitive{
+ BlockPrefix: "• ",
+ Color: stringPtr(dark.Blue().Hex),
+ },
+ Enumeration: ansi.StylePrimitive{
+ BlockPrefix: ". ",
+ Color: stringPtr(dark.Sky().Hex),
+ },
+ Task: ansi.StyleTask{
+ StylePrimitive: ansi.StylePrimitive{},
+ Ticked: "[✓] ",
+ Unticked: "[ ] ",
+ },
+ Link: ansi.StylePrimitive{
+ Color: stringPtr(dark.Sky().Hex),
+ Underline: boolPtr(true),
+ },
+ LinkText: ansi.StylePrimitive{
+ Color: stringPtr(dark.Pink().Hex),
+ Bold: boolPtr(true),
+ },
+ Image: ansi.StylePrimitive{
+ Color: stringPtr(dark.Sapphire().Hex),
+ Underline: boolPtr(true),
+ Format: "🖼 {{.text}}",
+ },
+ ImageText: ansi.StylePrimitive{
+ Color: stringPtr(dark.Pink().Hex),
+ Format: "{{.text}}",
+ },
+ Code: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Color: stringPtr(dark.Green().Hex),
+ Prefix: " ",
+ Suffix: " ",
+ },
+ },
+ CodeBlock: ansi.StyleCodeBlock{
+ StyleBlock: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: " ",
+ Color: stringPtr(dark.Text().Hex),
+ },
+
+ Margin: uintPtr(defaultMargin),
+ },
+ Chroma: &ansi.Chroma{
+ Text: ansi.StylePrimitive{
+ Color: stringPtr(dark.Text().Hex),
+ },
+ Error: ansi.StylePrimitive{
+ Color: stringPtr(dark.Text().Hex),
+ },
+ Comment: ansi.StylePrimitive{
+ Color: stringPtr(dark.Overlay1().Hex),
+ },
+ CommentPreproc: ansi.StylePrimitive{
+ Color: stringPtr(dark.Pink().Hex),
+ },
+ Keyword: ansi.StylePrimitive{
+ Color: stringPtr(dark.Pink().Hex),
+ },
+ KeywordReserved: ansi.StylePrimitive{
+ Color: stringPtr(dark.Pink().Hex),
+ },
+ KeywordNamespace: ansi.StylePrimitive{
+ Color: stringPtr(dark.Pink().Hex),
+ },
+ KeywordType: ansi.StylePrimitive{
+ Color: stringPtr(dark.Sky().Hex),
+ },
+ Operator: ansi.StylePrimitive{
+ Color: stringPtr(dark.Pink().Hex),
+ },
+ Punctuation: ansi.StylePrimitive{
+ Color: stringPtr(dark.Text().Hex),
+ },
+ Name: ansi.StylePrimitive{
+ Color: stringPtr(dark.Sky().Hex),
+ },
+ NameBuiltin: ansi.StylePrimitive{
+ Color: stringPtr(dark.Sky().Hex),
+ },
+ NameTag: ansi.StylePrimitive{
+ Color: stringPtr(dark.Pink().Hex),
+ },
+ NameAttribute: ansi.StylePrimitive{
+ Color: stringPtr(dark.Green().Hex),
+ },
+ NameClass: ansi.StylePrimitive{
+ Color: stringPtr(dark.Sky().Hex),
+ },
+ NameConstant: ansi.StylePrimitive{
+ Color: stringPtr(dark.Mauve().Hex),
+ },
+ NameDecorator: ansi.StylePrimitive{
+ Color: stringPtr(dark.Green().Hex),
+ },
+ NameFunction: ansi.StylePrimitive{
+ Color: stringPtr(dark.Green().Hex),
+ },
+ LiteralNumber: ansi.StylePrimitive{
+ Color: stringPtr(dark.Teal().Hex),
+ },
+ LiteralString: ansi.StylePrimitive{
+ Color: stringPtr(dark.Yellow().Hex),
+ },
+ LiteralStringEscape: ansi.StylePrimitive{
+ Color: stringPtr(dark.Pink().Hex),
+ },
+ GenericDeleted: ansi.StylePrimitive{
+ Color: stringPtr(dark.Red().Hex),
+ },
+ GenericEmph: ansi.StylePrimitive{
+ Color: stringPtr(dark.Yellow().Hex),
+ Italic: boolPtr(true),
+ },
+ GenericInserted: ansi.StylePrimitive{
+ Color: stringPtr(dark.Green().Hex),
+ },
+ GenericStrong: ansi.StylePrimitive{
+ Color: stringPtr(dark.Peach().Hex),
+ Bold: boolPtr(true),
+ },
+ GenericSubheading: ansi.StylePrimitive{
+ Color: stringPtr(dark.Mauve().Hex),
+ },
+ },
+ },
+ Table: ansi.StyleTable{
+ StyleBlock: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ BlockPrefix: "\n",
+ BlockSuffix: "\n",
+ },
+ },
+ CenterSeparator: stringPtr("┼"),
+ ColumnSeparator: stringPtr("│"),
+ RowSeparator: stringPtr("─"),
+ },
+ DefinitionDescription: ansi.StylePrimitive{
+ BlockPrefix: "\n ❯ ",
+ Color: stringPtr(dark.Sapphire().Hex),
+ },
+}
+
+var catppuccinLight = ansi.StyleConfig{
+ Document: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ BlockPrefix: "\n",
+ BlockSuffix: "\n",
+ Color: stringPtr(light.Text().Hex),
+ },
+ Margin: uintPtr(defaultMargin),
+ },
+ BlockQuote: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Color: stringPtr(light.Yellow().Hex),
+ Italic: boolPtr(true),
+ Prefix: "┃ ",
+ },
+ Indent: uintPtr(1),
+ Margin: uintPtr(defaultMargin),
+ },
+ List: ansi.StyleList{
+ LevelIndent: defaultMargin,
+ StyleBlock: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Color: stringPtr(light.Text().Hex),
+ },
+ },
+ },
+ Heading: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ BlockSuffix: "\n",
+ Color: stringPtr(light.Mauve().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ H1: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "# ",
+ Color: stringPtr(light.Lavender().Hex),
+ Bold: boolPtr(true),
+ BlockPrefix: "\n",
+ },
+ },
+ H2: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "## ",
+ Color: stringPtr(light.Mauve().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ H3: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "### ",
+ Color: stringPtr(light.Pink().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ H4: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "#### ",
+ Color: stringPtr(light.Flamingo().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ H5: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "##### ",
+ Color: stringPtr(light.Rosewater().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ H6: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: "###### ",
+ Color: stringPtr(light.Rosewater().Hex),
+ Bold: boolPtr(true),
+ },
+ },
+ Strikethrough: ansi.StylePrimitive{
+ CrossedOut: boolPtr(true),
+ Color: stringPtr(light.Overlay1().Hex),
+ },
+ Emph: ansi.StylePrimitive{
+ Color: stringPtr(light.Yellow().Hex),
+ Italic: boolPtr(true),
+ },
+ Strong: ansi.StylePrimitive{
+ Bold: boolPtr(true),
+ Color: stringPtr(light.Peach().Hex),
+ },
+ HorizontalRule: ansi.StylePrimitive{
+ Color: stringPtr(light.Overlay0().Hex),
+ Format: "\n─────────────────────────────────────────\n",
+ },
+ Item: ansi.StylePrimitive{
+ BlockPrefix: "• ",
+ Color: stringPtr(light.Blue().Hex),
+ },
+ Enumeration: ansi.StylePrimitive{
+ BlockPrefix: ". ",
+ Color: stringPtr(light.Sky().Hex),
+ },
+ Task: ansi.StyleTask{
+ StylePrimitive: ansi.StylePrimitive{},
+ Ticked: "[✓] ",
+ Unticked: "[ ] ",
+ },
+ Link: ansi.StylePrimitive{
+ Color: stringPtr(light.Sky().Hex),
+ Underline: boolPtr(true),
+ },
+ LinkText: ansi.StylePrimitive{
+ Color: stringPtr(light.Pink().Hex),
+ Bold: boolPtr(true),
+ },
+ Image: ansi.StylePrimitive{
+ Color: stringPtr(light.Sapphire().Hex),
+ Underline: boolPtr(true),
+ Format: "🖼 {{.text}}",
+ },
+ ImageText: ansi.StylePrimitive{
+ Color: stringPtr(light.Pink().Hex),
+ Format: "{{.text}}",
+ },
+ Code: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Color: stringPtr(light.Green().Hex),
+ Prefix: " ",
+ Suffix: " ",
+ },
+ },
+ CodeBlock: ansi.StyleCodeBlock{
+ StyleBlock: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ Prefix: " ",
+ Color: stringPtr(light.Text().Hex),
+ },
+
+ Margin: uintPtr(defaultMargin),
+ },
+ Chroma: &ansi.Chroma{
+ Text: ansi.StylePrimitive{
+ Color: stringPtr(light.Text().Hex),
+ },
+ Error: ansi.StylePrimitive{
+ Color: stringPtr(light.Text().Hex),
+ },
+ Comment: ansi.StylePrimitive{
+ Color: stringPtr(light.Overlay1().Hex),
+ },
+ CommentPreproc: ansi.StylePrimitive{
+ Color: stringPtr(light.Pink().Hex),
+ },
+ Keyword: ansi.StylePrimitive{
+ Color: stringPtr(light.Pink().Hex),
+ },
+ KeywordReserved: ansi.StylePrimitive{
+ Color: stringPtr(light.Pink().Hex),
+ },
+ KeywordNamespace: ansi.StylePrimitive{
+ Color: stringPtr(light.Pink().Hex),
+ },
+ KeywordType: ansi.StylePrimitive{
+ Color: stringPtr(light.Sky().Hex),
+ },
+ Operator: ansi.StylePrimitive{
+ Color: stringPtr(light.Pink().Hex),
+ },
+ Punctuation: ansi.StylePrimitive{
+ Color: stringPtr(light.Text().Hex),
+ },
+ Name: ansi.StylePrimitive{
+ Color: stringPtr(light.Sky().Hex),
+ },
+ NameBuiltin: ansi.StylePrimitive{
+ Color: stringPtr(light.Sky().Hex),
+ },
+ NameTag: ansi.StylePrimitive{
+ Color: stringPtr(light.Pink().Hex),
+ },
+ NameAttribute: ansi.StylePrimitive{
+ Color: stringPtr(light.Green().Hex),
+ },
+ NameClass: ansi.StylePrimitive{
+ Color: stringPtr(light.Sky().Hex),
+ },
+ NameConstant: ansi.StylePrimitive{
+ Color: stringPtr(light.Mauve().Hex),
+ },
+ NameDecorator: ansi.StylePrimitive{
+ Color: stringPtr(light.Green().Hex),
+ },
+ NameFunction: ansi.StylePrimitive{
+ Color: stringPtr(light.Green().Hex),
+ },
+ LiteralNumber: ansi.StylePrimitive{
+ Color: stringPtr(light.Teal().Hex),
+ },
+ LiteralString: ansi.StylePrimitive{
+ Color: stringPtr(light.Yellow().Hex),
+ },
+ LiteralStringEscape: ansi.StylePrimitive{
+ Color: stringPtr(light.Pink().Hex),
+ },
+ GenericDeleted: ansi.StylePrimitive{
+ Color: stringPtr(light.Red().Hex),
+ },
+ GenericEmph: ansi.StylePrimitive{
+ Color: stringPtr(light.Yellow().Hex),
+ Italic: boolPtr(true),
+ },
+ GenericInserted: ansi.StylePrimitive{
+ Color: stringPtr(light.Green().Hex),
+ },
+ GenericStrong: ansi.StylePrimitive{
+ Color: stringPtr(light.Peach().Hex),
+ Bold: boolPtr(true),
+ },
+ GenericSubheading: ansi.StylePrimitive{
+ Color: stringPtr(light.Mauve().Hex),
+ },
+ },
+ },
+ Table: ansi.StyleTable{
+ StyleBlock: ansi.StyleBlock{
+ StylePrimitive: ansi.StylePrimitive{
+ BlockPrefix: "\n",
+ BlockSuffix: "\n",
+ },
+ },
+ CenterSeparator: stringPtr("┼"),
+ ColumnSeparator: stringPtr("│"),
+ RowSeparator: stringPtr("─"),
+ },
+ DefinitionDescription: ansi.StylePrimitive{
+ BlockPrefix: "\n ❯ ",
+ Color: stringPtr(light.Sapphire().Hex),
+ },
+}
diff --git a/internal/tui/styles/styles.go b/internal/tui/styles/styles.go
new file mode 100644
index 000000000..a52a8a2eb
--- /dev/null
+++ b/internal/tui/styles/styles.go
@@ -0,0 +1,121 @@
+package styles
+
+import (
+ catppuccin "github.com/catppuccin/go"
+ "github.com/charmbracelet/lipgloss"
+)
+
+var (
+ light = catppuccin.Latte
+ dark = catppuccin.Mocha
+)
+
+var (
+ Regular = lipgloss.NewStyle()
+ Bold = Regular.Bold(true)
+ Padded = Regular.Padding(0, 1)
+
+ Border = Regular.Border(lipgloss.NormalBorder())
+ ThickBorder = Regular.Border(lipgloss.ThickBorder())
+ DoubleBorder = Regular.Border(lipgloss.DoubleBorder())
+ // Colors
+
+ Surface0 = lipgloss.AdaptiveColor{
+ Dark: dark.Surface0().Hex,
+ Light: light.Surface0().Hex,
+ }
+
+ Overlay0 = lipgloss.AdaptiveColor{
+ Dark: dark.Overlay0().Hex,
+ Light: light.Overlay0().Hex,
+ }
+
+ Ovelay1 = lipgloss.AdaptiveColor{
+ Dark: dark.Overlay1().Hex,
+ Light: light.Overlay1().Hex,
+ }
+
+ Text = lipgloss.AdaptiveColor{
+ Dark: dark.Text().Hex,
+ Light: light.Text().Hex,
+ }
+
+ SubText0 = lipgloss.AdaptiveColor{
+ Dark: dark.Subtext0().Hex,
+ Light: light.Subtext0().Hex,
+ }
+
+ SubText1 = lipgloss.AdaptiveColor{
+ Dark: dark.Subtext1().Hex,
+ Light: light.Subtext1().Hex,
+ }
+
+ LightGrey = lipgloss.AdaptiveColor{
+ Dark: dark.Surface0().Hex,
+ Light: light.Surface0().Hex,
+ }
+ Grey = lipgloss.AdaptiveColor{
+ Dark: dark.Surface1().Hex,
+ Light: light.Surface1().Hex,
+ }
+
+ DarkGrey = lipgloss.AdaptiveColor{
+ Dark: dark.Surface2().Hex,
+ Light: light.Surface2().Hex,
+ }
+
+ Base = lipgloss.AdaptiveColor{
+ Dark: dark.Base().Hex,
+ Light: light.Base().Hex,
+ }
+
+ Crust = lipgloss.AdaptiveColor{
+ Dark: dark.Crust().Hex,
+ Light: light.Crust().Hex,
+ }
+
+ Blue = lipgloss.AdaptiveColor{
+ Dark: dark.Blue().Hex,
+ Light: light.Blue().Hex,
+ }
+
+ Red = lipgloss.AdaptiveColor{
+ Dark: dark.Red().Hex,
+ Light: light.Red().Hex,
+ }
+
+ Green = lipgloss.AdaptiveColor{
+ Dark: dark.Green().Hex,
+ Light: light.Green().Hex,
+ }
+
+ Mauve = lipgloss.AdaptiveColor{
+ Dark: dark.Mauve().Hex,
+ Light: light.Mauve().Hex,
+ }
+
+ Teal = lipgloss.AdaptiveColor{
+ Dark: dark.Teal().Hex,
+ Light: light.Teal().Hex,
+ }
+
+ Rosewater = lipgloss.AdaptiveColor{
+ Dark: dark.Rosewater().Hex,
+ Light: light.Rosewater().Hex,
+ }
+
+ Flamingo = lipgloss.AdaptiveColor{
+ Dark: dark.Flamingo().Hex,
+ Light: light.Flamingo().Hex,
+ }
+
+ Lavender = lipgloss.AdaptiveColor{
+ Dark: dark.Lavender().Hex,
+ Light: light.Lavender().Hex,
+ }
+
+ Peach = lipgloss.AdaptiveColor{
+ Dark: dark.Peach().Hex,
+ Light: light.Peach().Hex,
+ }
+)