wip: refactoring tui

This commit is contained in:
adamdottv
2025-06-12 05:35:40 -05:00
parent a1ce35c208
commit cce2e4ad75
47 changed files with 1018 additions and 3406 deletions

View File

@@ -3,7 +3,8 @@ package styles
import (
"github.com/charmbracelet/glamour"
"github.com/charmbracelet/glamour/ansi"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/v2/compat"
"github.com/lucasb-eyer/go-colorful"
"github.com/sst/opencode/internal/theme"
)
@@ -15,117 +16,120 @@ func stringPtr(s string) *string { return &s }
func uintPtr(u uint) *uint { return &u }
// returns a glamour TermRenderer configured with the current theme
func GetMarkdownRenderer(width int) *glamour.TermRenderer {
func GetMarkdownRenderer(width int, backgroundColor compat.AdaptiveColor) *glamour.TermRenderer {
r, _ := glamour.NewTermRenderer(
glamour.WithStyles(generateMarkdownStyleConfig()),
glamour.WithStyles(generateMarkdownStyleConfig(backgroundColor)),
glamour.WithWordWrap(width),
glamour.WithChromaFormatter("terminal16m"),
)
return r
}
// creates an ansi.StyleConfig for markdown rendering
// using adaptive colors from the provided theme.
func generateMarkdownStyleConfig() ansi.StyleConfig {
func generateMarkdownStyleConfig(backgroundColor compat.AdaptiveColor) ansi.StyleConfig {
t := theme.CurrentTheme()
background := stringPtr(AdaptiveColorToString(backgroundColor))
return ansi.StyleConfig{
Document: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
BlockPrefix: "",
BlockSuffix: "",
Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
BlockPrefix: "",
BlockSuffix: "",
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
},
},
BlockQuote: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownBlockQuote())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownBlockQuote())),
Italic: boolPtr(true),
Prefix: "┃ ",
},
Indent: uintPtr(1),
IndentToken: stringPtr(BaseStyle().Render(" ")),
IndentToken: stringPtr(" "),
},
List: ansi.StyleList{
LevelIndent: defaultMargin,
StyleBlock: ansi.StyleBlock{
IndentToken: stringPtr(BaseStyle().Render(" ")),
IndentToken: stringPtr(" "),
StylePrimitive: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
},
},
},
Heading: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
BlockSuffix: "\n",
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H1: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "# ",
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H2: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "## ",
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H3: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "### ",
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H4: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "#### ",
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H5: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "##### ",
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H6: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "###### ",
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
Strikethrough: ansi.StylePrimitive{
CrossedOut: boolPtr(true),
Color: stringPtr(adaptiveColorToString(t.TextMuted())),
Color: stringPtr(AdaptiveColorToString(t.TextMuted())),
},
Emph: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownEmph())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownEmph())),
Italic: boolPtr(true),
},
Strong: ansi.StylePrimitive{
Bold: boolPtr(true),
Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownStrong())),
},
HorizontalRule: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownHorizontalRule())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownHorizontalRule())),
Format: "\n─────────────────────────────────────────\n",
},
Item: ansi.StylePrimitive{
BlockPrefix: "• ",
Color: stringPtr(adaptiveColorToString(t.MarkdownListItem())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownListItem())),
},
Enumeration: ansi.StylePrimitive{
BlockPrefix: ". ",
Color: stringPtr(adaptiveColorToString(t.MarkdownListEnumeration())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownListEnumeration())),
},
Task: ansi.StyleTask{
StylePrimitive: ansi.StylePrimitive{},
@@ -133,116 +137,147 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
Unticked: "[ ] ",
},
Link: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownLink())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownLink())),
Underline: boolPtr(true),
},
LinkText: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownLinkText())),
Bold: boolPtr(true),
},
Image: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownImage())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownImage())),
Underline: boolPtr(true),
Format: "🖼 {{.text}}",
},
ImageText: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownImageText())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownImageText())),
Format: "{{.text}}",
},
Code: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownCode())),
Prefix: "",
Suffix: "",
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.MarkdownCode())),
Prefix: "",
Suffix: "",
},
},
CodeBlock: ansi.StyleCodeBlock{
StyleBlock: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: " ",
Color: stringPtr(adaptiveColorToString(t.MarkdownCodeBlock())),
BackgroundColor: background,
Prefix: " ",
Color: stringPtr(AdaptiveColorToString(t.MarkdownCodeBlock())),
},
},
Chroma: &ansi.Chroma{
Background: ansi.StylePrimitive{
BackgroundColor: background,
},
Text: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
},
Error: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.Error())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.Error())),
},
Comment: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxComment())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxComment())),
},
CommentPreproc: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
Keyword: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
KeywordReserved: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
KeywordNamespace: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
KeywordType: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxType())),
},
Operator: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxOperator())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxOperator())),
},
Punctuation: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxPunctuation())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxPunctuation())),
},
Name: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxVariable())),
},
NameBuiltin: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxVariable())),
},
NameTag: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
NameAttribute: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxFunction())),
},
NameClass: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxType())),
},
NameConstant: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxVariable())),
},
NameDecorator: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxFunction())),
},
NameFunction: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxFunction())),
},
LiteralNumber: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxNumber())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxNumber())),
},
LiteralString: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxString())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxString())),
},
LiteralStringEscape: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
GenericDeleted: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.DiffRemoved())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.DiffRemoved())),
},
GenericEmph: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownEmph())),
Italic: boolPtr(true),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.MarkdownEmph())),
Italic: boolPtr(true),
},
GenericInserted: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.DiffAdded())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.DiffAdded())),
},
GenericStrong: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
Bold: boolPtr(true),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.MarkdownStrong())),
Bold: boolPtr(true),
},
GenericSubheading: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
BackgroundColor: background,
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
},
},
},
@@ -259,24 +294,26 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
},
DefinitionDescription: ansi.StylePrimitive{
BlockPrefix: "\n ",
Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownLinkText())),
},
Text: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
},
Paragraph: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
},
},
}
}
// adaptiveColorToString converts a lipgloss.AdaptiveColor to the appropriate
// AdaptiveColorToString converts a compat.AdaptiveColor to the appropriate
// hex color string based on the current terminal background
func adaptiveColorToString(color lipgloss.AdaptiveColor) string {
if lipgloss.HasDarkBackground() {
return color.Dark
func AdaptiveColorToString(color compat.AdaptiveColor) string {
if Terminal.BackgroundIsDark {
c1, _ := colorful.MakeColor(color.Dark)
return c1.Hex()
}
return color.Light
c1, _ := colorful.MakeColor(color.Light)
return c1.Hex()
}