wip small fixes

Kujtim Hoxha created

Change summary

internal/tui/components/chat/sidebar/sidebar.go |   8 
internal/tui/components/core/helpers.go         |   2 
internal/tui/layout/split.go                    |   9 
internal/tui/page/chat/chat.go                  |   2 
internal/tui/styles/markdown.go                 |   2 
internal/tui/styles/theme.go                    | 221 ++++++++++++++++++
6 files changed, 230 insertions(+), 14 deletions(-)

Detailed changes

internal/tui/components/chat/sidebar/sidebar.go 🔗

@@ -115,7 +115,7 @@ func (m *sidebarCmp) lspBlock() string {
 	t := styles.CurrentTheme()
 
 	section := t.S().Muted.Render(
-		core.Section("Configured LSPs", maxWidth),
+		core.Section("LSPs", maxWidth),
 	)
 
 	lspList := []string{section, ""}
@@ -126,7 +126,7 @@ func (m *sidebarCmp) lspBlock() string {
 			lipgloss.Left,
 			section,
 			"",
-			t.S().Muted.Render("No LSPs configured."),
+			t.S().Base.Foreground(t.Border).Render("None"),
 		)
 	}
 
@@ -158,7 +158,7 @@ func (m *sidebarCmp) mcpBlock() string {
 	t := styles.CurrentTheme()
 
 	section := t.S().Muted.Render(
-		core.Section("Configured MCPs", maxWidth),
+		core.Section("MCPs", maxWidth),
 	)
 
 	mcpList := []string{section, ""}
@@ -169,7 +169,7 @@ func (m *sidebarCmp) mcpBlock() string {
 			lipgloss.Left,
 			section,
 			"",
-			t.S().Muted.Render("No MCPs configured."),
+			t.S().Base.Foreground(t.Border).Render("None"),
 		)
 	}
 

internal/tui/components/core/helpers.go 🔗

@@ -15,7 +15,7 @@ func Section(title string, width int) string {
 	length := len(title) + 1
 	remainingWidth := width - length
 	if remainingWidth > 0 {
-		title = title + " " + t.S().Subtle.Render(strings.Repeat(char, remainingWidth))
+		title = title + " " + t.S().Base.Foreground(t.Border).Render(strings.Repeat(char, remainingWidth))
 	}
 	return title
 }

internal/tui/layout/split.go 🔗

@@ -4,7 +4,7 @@ import (
 	"github.com/charmbracelet/bubbles/v2/key"
 	tea "github.com/charmbracelet/bubbletea/v2"
 	"github.com/charmbracelet/lipgloss/v2"
-	"github.com/opencode-ai/opencode/internal/tui/theme"
+	"github.com/opencode-ai/opencode/internal/tui/styles"
 	"github.com/opencode-ai/opencode/internal/tui/util"
 )
 
@@ -126,12 +126,11 @@ func (s *splitPaneLayout) View() tea.View {
 		cursor = s.leftPanel.View().Cursor()
 	}
 
-	t := theme.CurrentTheme()
+	t := styles.CurrentTheme()
 
-	style := lipgloss.NewStyle().
+	style := t.S().Base.
 		Width(s.width).
-		Height(s.height).
-		Background(t.Background())
+		Height(s.height)
 
 	view := tea.NewView(style.Render(finalView))
 	view.SetCursor(cursor)

internal/tui/page/chat/chat.go 🔗

@@ -166,7 +166,7 @@ func NewChatPage(app *app.App) util.Model {
 		layout: layout.NewSplitPane(
 			layout.WithRightPanel(sidebarContainer),
 			layout.WithBottomPanel(editorContainer),
-			layout.WithFixedBottomHeight(3),
+			layout.WithFixedBottomHeight(5),
 			layout.WithFixedRightWidth(31),
 		),
 	}

internal/tui/styles/markdown.go 🔗

@@ -9,8 +9,6 @@ import (
 	"github.com/opencode-ai/opencode/internal/tui/theme"
 )
 
-const defaultMargin = 1
-
 // Helper functions for style pointers
 func boolPtr(b bool) *bool       { return &b }
 func stringPtr(s string) *string { return &s }

internal/tui/styles/theme.go 🔗

@@ -6,9 +6,16 @@ import (
 
 	"github.com/charmbracelet/bubbles/v2/textarea"
 	tea "github.com/charmbracelet/bubbletea/v2"
+	"github.com/charmbracelet/glamour/v2/ansi"
 	"github.com/charmbracelet/lipgloss/v2"
 )
 
+const (
+	defaultListIndent      = 2
+	defaultListLevelIndent = 4
+	defaultMargin          = 2
+)
+
 type Theme struct {
 	Name   string
 	IsDark bool
@@ -56,6 +63,9 @@ type Styles struct {
 	Error   lipgloss.Style
 	Warning lipgloss.Style
 	Info    lipgloss.Style
+	// Markdown & Chroma
+
+	Markdown ansi.StyleConfig
 
 	// Inputs
 	TextArea textarea.Styles
@@ -70,7 +80,6 @@ func (t *Theme) S() *Styles {
 
 func (t *Theme) buildStyles() *Styles {
 	base := lipgloss.NewStyle().
-		Background(t.BgBase).
 		Foreground(t.FgBase)
 	return &Styles{
 		Base: base,
@@ -122,6 +131,216 @@ func (t *Theme) buildStyles() *Styles {
 				Blink: true,
 			},
 		},
+
+		// TODO:  update using the colors and add colors if missing
+		Markdown: ansi.StyleConfig{
+			Document: ansi.StyleBlock{
+				StylePrimitive: ansi.StylePrimitive{
+					BlockPrefix: "\n",
+					BlockSuffix: "\n",
+					Color:       stringPtr("252"),
+				},
+				Margin: uintPtr(defaultMargin),
+			},
+			BlockQuote: ansi.StyleBlock{
+				StylePrimitive: ansi.StylePrimitive{},
+				Indent:         uintPtr(1),
+				IndentToken:    stringPtr("│ "),
+			},
+			List: ansi.StyleList{
+				LevelIndent: defaultListIndent,
+			},
+			Heading: ansi.StyleBlock{
+				StylePrimitive: ansi.StylePrimitive{
+					BlockSuffix: "\n",
+					Color:       stringPtr("39"),
+					Bold:        boolPtr(true),
+				},
+			},
+			H1: ansi.StyleBlock{
+				StylePrimitive: ansi.StylePrimitive{
+					Prefix:          " ",
+					Suffix:          " ",
+					Color:           stringPtr("228"),
+					BackgroundColor: stringPtr("63"),
+					Bold:            boolPtr(true),
+				},
+			},
+			H2: ansi.StyleBlock{
+				StylePrimitive: ansi.StylePrimitive{
+					Prefix: "## ",
+				},
+			},
+			H3: ansi.StyleBlock{
+				StylePrimitive: ansi.StylePrimitive{
+					Prefix: "### ",
+				},
+			},
+			H4: ansi.StyleBlock{
+				StylePrimitive: ansi.StylePrimitive{
+					Prefix: "#### ",
+				},
+			},
+			H5: ansi.StyleBlock{
+				StylePrimitive: ansi.StylePrimitive{
+					Prefix: "##### ",
+				},
+			},
+			H6: ansi.StyleBlock{
+				StylePrimitive: ansi.StylePrimitive{
+					Prefix: "###### ",
+					Color:  stringPtr("35"),
+					Bold:   boolPtr(false),
+				},
+			},
+			Strikethrough: ansi.StylePrimitive{
+				CrossedOut: boolPtr(true),
+			},
+			Emph: ansi.StylePrimitive{
+				Italic: boolPtr(true),
+			},
+			Strong: ansi.StylePrimitive{
+				Bold: boolPtr(true),
+			},
+			HorizontalRule: ansi.StylePrimitive{
+				Color:  stringPtr("240"),
+				Format: "\n--------\n",
+			},
+			Item: ansi.StylePrimitive{
+				BlockPrefix: "• ",
+			},
+			Enumeration: ansi.StylePrimitive{
+				BlockPrefix: ". ",
+			},
+			Task: ansi.StyleTask{
+				StylePrimitive: ansi.StylePrimitive{},
+				Ticked:         "[✓] ",
+				Unticked:       "[ ] ",
+			},
+			Link: ansi.StylePrimitive{
+				Color:     stringPtr("30"),
+				Underline: boolPtr(true),
+			},
+			LinkText: ansi.StylePrimitive{
+				Color: stringPtr("35"),
+				Bold:  boolPtr(true),
+			},
+			Image: ansi.StylePrimitive{
+				Color:     stringPtr("212"),
+				Underline: boolPtr(true),
+			},
+			ImageText: ansi.StylePrimitive{
+				Color:  stringPtr("243"),
+				Format: "Image: {{.text}} →",
+			},
+			Code: ansi.StyleBlock{
+				StylePrimitive: ansi.StylePrimitive{
+					Prefix:          " ",
+					Suffix:          " ",
+					Color:           stringPtr("203"),
+					BackgroundColor: stringPtr("236"),
+				},
+			},
+			CodeBlock: ansi.StyleCodeBlock{
+				StyleBlock: ansi.StyleBlock{
+					StylePrimitive: ansi.StylePrimitive{
+						Color: stringPtr("244"),
+					},
+					Margin: uintPtr(defaultMargin),
+				},
+				Chroma: &ansi.Chroma{
+					Text: ansi.StylePrimitive{
+						Color: stringPtr("#C4C4C4"),
+					},
+					Error: ansi.StylePrimitive{
+						Color:           stringPtr("#F1F1F1"),
+						BackgroundColor: stringPtr("#F05B5B"),
+					},
+					Comment: ansi.StylePrimitive{
+						Color: stringPtr("#676767"),
+					},
+					CommentPreproc: ansi.StylePrimitive{
+						Color: stringPtr("#FF875F"),
+					},
+					Keyword: ansi.StylePrimitive{
+						Color: stringPtr("#00AAFF"),
+					},
+					KeywordReserved: ansi.StylePrimitive{
+						Color: stringPtr("#FF5FD2"),
+					},
+					KeywordNamespace: ansi.StylePrimitive{
+						Color: stringPtr("#FF5F87"),
+					},
+					KeywordType: ansi.StylePrimitive{
+						Color: stringPtr("#6E6ED8"),
+					},
+					Operator: ansi.StylePrimitive{
+						Color: stringPtr("#EF8080"),
+					},
+					Punctuation: ansi.StylePrimitive{
+						Color: stringPtr("#E8E8A8"),
+					},
+					Name: ansi.StylePrimitive{
+						Color: stringPtr("#C4C4C4"),
+					},
+					NameBuiltin: ansi.StylePrimitive{
+						Color: stringPtr("#FF8EC7"),
+					},
+					NameTag: ansi.StylePrimitive{
+						Color: stringPtr("#B083EA"),
+					},
+					NameAttribute: ansi.StylePrimitive{
+						Color: stringPtr("#7A7AE6"),
+					},
+					NameClass: ansi.StylePrimitive{
+						Color:     stringPtr("#F1F1F1"),
+						Underline: boolPtr(true),
+						Bold:      boolPtr(true),
+					},
+					NameDecorator: ansi.StylePrimitive{
+						Color: stringPtr("#FFFF87"),
+					},
+					NameFunction: ansi.StylePrimitive{
+						Color: stringPtr("#00D787"),
+					},
+					LiteralNumber: ansi.StylePrimitive{
+						Color: stringPtr("#6EEFC0"),
+					},
+					LiteralString: ansi.StylePrimitive{
+						Color: stringPtr("#C69669"),
+					},
+					LiteralStringEscape: ansi.StylePrimitive{
+						Color: stringPtr("#AFFFD7"),
+					},
+					GenericDeleted: ansi.StylePrimitive{
+						Color: stringPtr("#FD5B5B"),
+					},
+					GenericEmph: ansi.StylePrimitive{
+						Italic: boolPtr(true),
+					},
+					GenericInserted: ansi.StylePrimitive{
+						Color: stringPtr("#00D787"),
+					},
+					GenericStrong: ansi.StylePrimitive{
+						Bold: boolPtr(true),
+					},
+					GenericSubheading: ansi.StylePrimitive{
+						Color: stringPtr("#777777"),
+					},
+					Background: ansi.StylePrimitive{
+						BackgroundColor: stringPtr("#373737"),
+					},
+				},
+			},
+			Table: ansi.StyleTable{
+				StyleBlock: ansi.StyleBlock{
+					StylePrimitive: ansi.StylePrimitive{},
+				},
+			},
+			DefinitionDescription: ansi.StylePrimitive{
+				BlockPrefix: "\n ",
+			},
+		},
 	}
 }