on main help sign in
wip small fixes
dff1bacKujtim Hoxha
internal/tui/components/chat/sidebar/sidebar.go+4−4
@@ -115,7 +115,7 @@ func (m *sidebarCmp) lspBlock() string {
115 t := styles.CurrentTheme()
115 t := styles.CurrentTheme()
116
116
117 section := t.S().Muted.Render(
117 section := t.S().Muted.Render(
118− core.Section("Configured LSPs", maxWidth),
118+ core.Section("LSPs", maxWidth),
119 )
119 )
120
120
121 lspList := []string{section, ""}
121 lspList := []string{section, ""}
@@ -126,7 +126,7 @@ func (m *sidebarCmp) lspBlock() string {
126 lipgloss.Left,
126 lipgloss.Left,
127 section,
127 section,
128 "",
128 "",
129− t.S().Muted.Render("No LSPs configured."),
129+ t.S().Base.Foreground(t.Border).Render("None"),
130 )
130 )
131 }
131 }
132
132
@@ -158,7 +158,7 @@ func (m *sidebarCmp) mcpBlock() string {
158 t := styles.CurrentTheme()
158 t := styles.CurrentTheme()
159
159
160 section := t.S().Muted.Render(
160 section := t.S().Muted.Render(
161− core.Section("Configured MCPs", maxWidth),
161+ core.Section("MCPs", maxWidth),
162 )
162 )
163
163
164 mcpList := []string{section, ""}
164 mcpList := []string{section, ""}
@@ -169,7 +169,7 @@ func (m *sidebarCmp) mcpBlock() string {
169 lipgloss.Left,
169 lipgloss.Left,
170 section,
170 section,
171 "",
171 "",
172− t.S().Muted.Render("No MCPs configured."),
172+ t.S().Base.Foreground(t.Border).Render("None"),
173 )
173 )
174 }
174 }
175
175
internal/tui/components/core/helpers.go+1−1
@@ -15,7 +15,7 @@ func Section(title string, width int) string {
15 length := len(title) + 1
15 length := len(title) + 1
16 remainingWidth := width - length
16 remainingWidth := width - length
17 if remainingWidth > 0 {
17 if remainingWidth > 0 {
18− title = title + " " + t.S().Subtle.Render(strings.Repeat(char, remainingWidth))
18+ title = title + " " + t.S().Base.Foreground(t.Border).Render(strings.Repeat(char, remainingWidth))
19 }
19 }
20 return title
20 return title
21}
21}
internal/tui/layout/split.go+4−5
@@ -4,7 +4,7 @@ import (
4 "github.com/charmbracelet/bubbles/v2/key"
4 "github.com/charmbracelet/bubbles/v2/key"
5 tea "github.com/charmbracelet/bubbletea/v2"
5 tea "github.com/charmbracelet/bubbletea/v2"
6 "github.com/charmbracelet/lipgloss/v2"
6 "github.com/charmbracelet/lipgloss/v2"
7− "github.com/opencode-ai/opencode/internal/tui/theme"
7+ "github.com/opencode-ai/opencode/internal/tui/styles"
8 "github.com/opencode-ai/opencode/internal/tui/util"
8 "github.com/opencode-ai/opencode/internal/tui/util"
9)
9)
10
10
@@ -126,12 +126,11 @@ func (s *splitPaneLayout) View() tea.View {
126 cursor = s.leftPanel.View().Cursor()
126 cursor = s.leftPanel.View().Cursor()
127 }
127 }
128
128
129− t := theme.CurrentTheme()
129+ t := styles.CurrentTheme()
130
130
131− style := lipgloss.NewStyle().
131+ style := t.S().Base.
132 Width(s.width).
132 Width(s.width).
133− Height(s.height).
133+ Height(s.height)
134− Background(t.Background())
135
134
136 view := tea.NewView(style.Render(finalView))
135 view := tea.NewView(style.Render(finalView))
137 view.SetCursor(cursor)
136 view.SetCursor(cursor)
internal/tui/page/chat/chat.go+1−1
@@ -166,7 +166,7 @@ func NewChatPage(app *app.App) util.Model {
166 layout: layout.NewSplitPane(
166 layout: layout.NewSplitPane(
167 layout.WithRightPanel(sidebarContainer),
167 layout.WithRightPanel(sidebarContainer),
168 layout.WithBottomPanel(editorContainer),
168 layout.WithBottomPanel(editorContainer),
169− layout.WithFixedBottomHeight(3),
169+ layout.WithFixedBottomHeight(5),
170 layout.WithFixedRightWidth(31),
170 layout.WithFixedRightWidth(31),
171 ),
171 ),
172 }
172 }
internal/tui/styles/markdown.go−2
@@ -9,8 +9,6 @@ import (
9 "github.com/opencode-ai/opencode/internal/tui/theme"
9 "github.com/opencode-ai/opencode/internal/tui/theme"
10)
10)
11
11
12−const defaultMargin = 1
13−
14// Helper functions for style pointers
12// Helper functions for style pointers
15func boolPtr(b bool) *bool { return &b }
13func boolPtr(b bool) *bool { return &b }
16func stringPtr(s string) *string { return &s }
14func stringPtr(s string) *string { return &s }
internal/tui/styles/theme.go+220−1
@@ -6,9 +6,16 @@ import (
6
6
7 "github.com/charmbracelet/bubbles/v2/textarea"
7 "github.com/charmbracelet/bubbles/v2/textarea"
8 tea "github.com/charmbracelet/bubbletea/v2"
8 tea "github.com/charmbracelet/bubbletea/v2"
9+ "github.com/charmbracelet/glamour/v2/ansi"
9 "github.com/charmbracelet/lipgloss/v2"
10 "github.com/charmbracelet/lipgloss/v2"
10)
11)
11
12
13+const (
14+ defaultListIndent = 2
15+ defaultListLevelIndent = 4
16+ defaultMargin = 2
17+)
18+
12type Theme struct {
19type Theme struct {
13 Name string
20 Name string
14 IsDark bool
21 IsDark bool
@@ -56,6 +63,9 @@ type Styles struct {
56 Error lipgloss.Style
63 Error lipgloss.Style
57 Warning lipgloss.Style
64 Warning lipgloss.Style
58 Info lipgloss.Style
65 Info lipgloss.Style
66+ // Markdown & Chroma
67+
68+ Markdown ansi.StyleConfig
59
69
60 // Inputs
70 // Inputs
61 TextArea textarea.Styles
71 TextArea textarea.Styles
@@ -70,7 +80,6 @@ func (t *Theme) S() *Styles {
70
80
71func (t *Theme) buildStyles() *Styles {
81func (t *Theme) buildStyles() *Styles {
72 base := lipgloss.NewStyle().
82 base := lipgloss.NewStyle().
73− Background(t.BgBase).
74 Foreground(t.FgBase)
83 Foreground(t.FgBase)
75 return &Styles{
84 return &Styles{
76 Base: base,
85 Base: base,
@@ -122,6 +131,216 @@ func (t *Theme) buildStyles() *Styles {
122 Blink: true,
131 Blink: true,
123 },
132 },
124 },
133 },
134+
135+ // TODO: update using the colors and add colors if missing
136+ Markdown: ansi.StyleConfig{
137+ Document: ansi.StyleBlock{
138+ StylePrimitive: ansi.StylePrimitive{
139+ BlockPrefix: "\n",
140+ BlockSuffix: "\n",
141+ Color: stringPtr("252"),
142+ },
143+ Margin: uintPtr(defaultMargin),
144+ },
145+ BlockQuote: ansi.StyleBlock{
146+ StylePrimitive: ansi.StylePrimitive{},
147+ Indent: uintPtr(1),
148+ IndentToken: stringPtr("│ "),
149+ },
150+ List: ansi.StyleList{
151+ LevelIndent: defaultListIndent,
152+ },
153+ Heading: ansi.StyleBlock{
154+ StylePrimitive: ansi.StylePrimitive{
155+ BlockSuffix: "\n",
156+ Color: stringPtr("39"),
157+ Bold: boolPtr(true),
158+ },
159+ },
160+ H1: ansi.StyleBlock{
161+ StylePrimitive: ansi.StylePrimitive{
162+ Prefix: " ",
163+ Suffix: " ",
164+ Color: stringPtr("228"),
165+ BackgroundColor: stringPtr("63"),
166+ Bold: boolPtr(true),
167+ },
168+ },
169+ H2: ansi.StyleBlock{
170+ StylePrimitive: ansi.StylePrimitive{
171+ Prefix: "## ",
172+ },
173+ },
174+ H3: ansi.StyleBlock{
175+ StylePrimitive: ansi.StylePrimitive{
176+ Prefix: "### ",
177+ },
178+ },
179+ H4: ansi.StyleBlock{
180+ StylePrimitive: ansi.StylePrimitive{
181+ Prefix: "#### ",
182+ },
183+ },
184+ H5: ansi.StyleBlock{
185+ StylePrimitive: ansi.StylePrimitive{
186+ Prefix: "##### ",
187+ },
188+ },
189+ H6: ansi.StyleBlock{
190+ StylePrimitive: ansi.StylePrimitive{
191+ Prefix: "###### ",
192+ Color: stringPtr("35"),
193+ Bold: boolPtr(false),
194+ },
195+ },
196+ Strikethrough: ansi.StylePrimitive{
197+ CrossedOut: boolPtr(true),
198+ },
199+ Emph: ansi.StylePrimitive{
200+ Italic: boolPtr(true),
201+ },
202+ Strong: ansi.StylePrimitive{
203+ Bold: boolPtr(true),
204+ },
205+ HorizontalRule: ansi.StylePrimitive{
206+ Color: stringPtr("240"),
207+ Format: "\n--------\n",
208+ },
209+ Item: ansi.StylePrimitive{
210+ BlockPrefix: "• ",
211+ },
212+ Enumeration: ansi.StylePrimitive{
213+ BlockPrefix: ". ",
214+ },
215+ Task: ansi.StyleTask{
216+ StylePrimitive: ansi.StylePrimitive{},
217+ Ticked: "[✓] ",
218+ Unticked: "[ ] ",
219+ },
220+ Link: ansi.StylePrimitive{
221+ Color: stringPtr("30"),
222+ Underline: boolPtr(true),
223+ },
224+ LinkText: ansi.StylePrimitive{
225+ Color: stringPtr("35"),
226+ Bold: boolPtr(true),
227+ },
228+ Image: ansi.StylePrimitive{
229+ Color: stringPtr("212"),
230+ Underline: boolPtr(true),
231+ },
232+ ImageText: ansi.StylePrimitive{
233+ Color: stringPtr("243"),
234+ Format: "Image: {{.text}} →",
235+ },
236+ Code: ansi.StyleBlock{
237+ StylePrimitive: ansi.StylePrimitive{
238+ Prefix: " ",
239+ Suffix: " ",
240+ Color: stringPtr("203"),
241+ BackgroundColor: stringPtr("236"),
242+ },
243+ },
244+ CodeBlock: ansi.StyleCodeBlock{
245+ StyleBlock: ansi.StyleBlock{
246+ StylePrimitive: ansi.StylePrimitive{
247+ Color: stringPtr("244"),
248+ },
249+ Margin: uintPtr(defaultMargin),
250+ },
251+ Chroma: &ansi.Chroma{
252+ Text: ansi.StylePrimitive{
253+ Color: stringPtr("#C4C4C4"),
254+ },
255+ Error: ansi.StylePrimitive{
256+ Color: stringPtr("#F1F1F1"),
257+ BackgroundColor: stringPtr("#F05B5B"),
258+ },
259+ Comment: ansi.StylePrimitive{
260+ Color: stringPtr("#676767"),
261+ },
262+ CommentPreproc: ansi.StylePrimitive{
263+ Color: stringPtr("#FF875F"),
264+ },
265+ Keyword: ansi.StylePrimitive{
266+ Color: stringPtr("#00AAFF"),
267+ },
268+ KeywordReserved: ansi.StylePrimitive{
269+ Color: stringPtr("#FF5FD2"),
270+ },
271+ KeywordNamespace: ansi.StylePrimitive{
272+ Color: stringPtr("#FF5F87"),
273+ },
274+ KeywordType: ansi.StylePrimitive{
275+ Color: stringPtr("#6E6ED8"),
276+ },
277+ Operator: ansi.StylePrimitive{
278+ Color: stringPtr("#EF8080"),
279+ },
280+ Punctuation: ansi.StylePrimitive{
281+ Color: stringPtr("#E8E8A8"),
282+ },
283+ Name: ansi.StylePrimitive{
284+ Color: stringPtr("#C4C4C4"),
285+ },
286+ NameBuiltin: ansi.StylePrimitive{
287+ Color: stringPtr("#FF8EC7"),
288+ },
289+ NameTag: ansi.StylePrimitive{
290+ Color: stringPtr("#B083EA"),
291+ },
292+ NameAttribute: ansi.StylePrimitive{
293+ Color: stringPtr("#7A7AE6"),
294+ },
295+ NameClass: ansi.StylePrimitive{
296+ Color: stringPtr("#F1F1F1"),
297+ Underline: boolPtr(true),
298+ Bold: boolPtr(true),
299+ },
300+ NameDecorator: ansi.StylePrimitive{
301+ Color: stringPtr("#FFFF87"),
302+ },
303+ NameFunction: ansi.StylePrimitive{
304+ Color: stringPtr("#00D787"),
305+ },
306+ LiteralNumber: ansi.StylePrimitive{
307+ Color: stringPtr("#6EEFC0"),
308+ },
309+ LiteralString: ansi.StylePrimitive{
310+ Color: stringPtr("#C69669"),
311+ },
312+ LiteralStringEscape: ansi.StylePrimitive{
313+ Color: stringPtr("#AFFFD7"),
314+ },
315+ GenericDeleted: ansi.StylePrimitive{
316+ Color: stringPtr("#FD5B5B"),
317+ },
318+ GenericEmph: ansi.StylePrimitive{
319+ Italic: boolPtr(true),
320+ },
321+ GenericInserted: ansi.StylePrimitive{
322+ Color: stringPtr("#00D787"),
323+ },
324+ GenericStrong: ansi.StylePrimitive{
325+ Bold: boolPtr(true),
326+ },
327+ GenericSubheading: ansi.StylePrimitive{
328+ Color: stringPtr("#777777"),
329+ },
330+ Background: ansi.StylePrimitive{
331+ BackgroundColor: stringPtr("#373737"),
332+ },
333+ },
334+ },
335+ Table: ansi.StyleTable{
336+ StyleBlock: ansi.StyleBlock{
337+ StylePrimitive: ansi.StylePrimitive{},
338+ },
339+ },
340+ DefinitionDescription: ansi.StylePrimitive{
341+ BlockPrefix: "\n ",
342+ },
343+ },
125 }
344 }
126}
345}
127
346