on main help sign in
move to v2
commitaf838d1cd62ec03311f13812a0435d33f966f21e authorKujtim Hoxha <kujtimii.h@gmail.com> dateFri 16 May 2025, 18:29 (1 year ago) parent05b0570
48 files changed+1591−2526
cmd/root.go+1−4 go.mod+10−11 go.sum+22−25 internal/diff/diff.go+9−11 internal/format/spinner.go+2−2 internal/tui/components/chat/chat.go+1−1 internal/tui/components/chat/editor.go+25−16 internal/tui/components/chat/list.go+12−12 internal/tui/components/chat/message.go+8−26 internal/tui/components/chat/sidebar.go+4−3 internal/tui/components/core/status.go+3−3 internal/tui/components/dialog/arguments.go+22−28 internal/tui/components/dialog/commands.go+4−4 internal/tui/components/dialog/complete.go+5−5 internal/tui/components/dialog/custom_commands.go+1−1 internal/tui/components/dialog/filepicker.go+13−13 internal/tui/components/dialog/help.go+7−6 internal/tui/components/dialog/init.go+3−3 internal/tui/components/dialog/models.go+4−5 internal/tui/components/dialog/permission.go+17−20 internal/tui/components/dialog/quit.go+5−5 internal/tui/components/dialog/session.go+5−6 internal/tui/components/dialog/theme.go+4−5 internal/tui/components/logs/details.go+11−12 internal/tui/components/logs/table.go+5−6 internal/tui/components/util/simple-list.go+5−4 internal/tui/image/images.go+3−2 internal/tui/layout/container.go+8−8 internal/tui/layout/layout.go+2−2 internal/tui/layout/overlay.go+2−2 internal/tui/layout/split.go+5−5 internal/tui/page/chat.go+6−6 internal/tui/page/logs.go+5−4 internal/tui/styles/background.go−123 internal/tui/styles/markdown.go+59−61 internal/tui/styles/styles.go+20−20 internal/tui/theme/catppuccin.go+135−211 internal/tui/theme/dracula.go+52−220 internal/tui/theme/flexoki.go+131−209 internal/tui/theme/gruvbox.go+128−206 internal/tui/theme/monokai.go+128−206 internal/tui/theme/onedark.go+128−206 internal/tui/theme/opencode.go+132−211 internal/tui/theme/theme.go+161−164 internal/tui/theme/tokyonight.go+128−206 internal/tui/theme/tron.go+128−206 internal/tui/tui.go+16−10 internal/tui/util/util.go+6−1
cmd/root.go+1−4
@@ -7,8 +7,7 @@ import (
77 "sync"
88 "time"
99
10− tea "github.com/charmbracelet/bubbletea"
11− zone "github.com/lrstanley/bubblezone"
10+ tea "github.com/charmbracelet/bubbletea/v2"
1211 "github.com/opencode-ai/opencode/internal/app"
1312 "github.com/opencode-ai/opencode/internal/config"
1413 "github.com/opencode-ai/opencode/internal/db"
@@ -114,9 +113,7 @@ to assist developers in writing, debugging, and understanding code directly from
114113 return app.RunNonInteractive(ctx, prompt, outputFormat, quiet)
115114 }
116115
117− // Interactive mode
118116 // Set up the TUI
119− zone.NewGlobal()
120117 program := tea.NewProgram(
121118 tui.New(app),
122119 tea.WithAltScreen(),
go.mod+10−11
@@ -11,15 +11,14 @@ require (
1111 github.com/aymanbagabas/go-udiff v0.2.0
1212 github.com/bmatcuk/doublestar/v4 v4.8.1
1313 github.com/catppuccin/go v0.3.0
14− github.com/charmbracelet/bubbles v0.21.0
15− github.com/charmbracelet/bubbletea v1.3.5
16− github.com/charmbracelet/glamour v0.9.1
17− github.com/charmbracelet/lipgloss v1.1.0
18− github.com/charmbracelet/x/ansi v0.8.0
14+ github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1
15+ github.com/charmbracelet/bubbletea/v2 v2.0.0-beta1
16+ github.com/charmbracelet/glamour/v2 v2.0.0-20250513163904-eeeced3bb3c6
17+ github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.1.0.20250513162854-28902d027c40
18+ github.com/charmbracelet/x/ansi v0.9.2
1919 github.com/fsnotify/fsnotify v1.8.0
2020 github.com/go-logfmt/logfmt v0.6.0
2121 github.com/google/uuid v1.6.0
22− github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231
2322 github.com/mark3labs/mcp-go v0.17.0
2423 github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6
2524 github.com/muesli/reflow v0.3.0
@@ -58,13 +57,15 @@ require (
5857 github.com/aws/smithy-go v1.20.3 // indirect
5958 github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
6059 github.com/aymerick/douceur v0.2.0 // indirect
61− github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
62− github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
60+ github.com/charmbracelet/colorprofile v0.3.0 // indirect
61+ github.com/charmbracelet/x/cellbuf v0.0.14-0.20250326144200-0875329e71da // indirect
62+ github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect
63+ github.com/charmbracelet/x/input v0.3.4 // indirect
6364 github.com/charmbracelet/x/term v0.2.1 // indirect
65+ github.com/charmbracelet/x/windows v0.2.0 // indirect
6466 github.com/davecgh/go-spew v1.1.1 // indirect
6567 github.com/disintegration/imaging v1.6.2
6668 github.com/dlclark/regexp2 v1.11.4 // indirect
67− github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
6869 github.com/felixge/httpsnoop v1.0.4 // indirect
6970 github.com/go-logr/logr v1.4.2 // indirect
7071 github.com/go-logr/stdr v1.2.2 // indirect
@@ -81,7 +82,6 @@ require (
8182 github.com/lithammer/fuzzysearch v1.1.8
8283 github.com/lucasb-eyer/go-colorful v1.2.0
8384 github.com/mattn/go-isatty v0.0.20 // indirect
84− github.com/mattn/go-localereader v0.0.1 // indirect
8585 github.com/mattn/go-runewidth v0.0.16 // indirect
8686 github.com/mfridman/interpolate v0.0.2 // indirect
8787 github.com/microcosm-cc/bluemonday v1.0.27 // indirect
@@ -119,7 +119,6 @@ require (
119119 golang.org/x/net v0.39.0 // indirect
120120 golang.org/x/sync v0.13.0 // indirect
121121 golang.org/x/sys v0.32.0 // indirect
122− golang.org/x/term v0.31.0 // indirect
123122 golang.org/x/text v0.24.0 // indirect
124123 google.golang.org/genai v1.3.0
125124 google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
go.sum+22−25
@@ -68,24 +68,30 @@ github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR
6868github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
6969github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY=
7070github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
71−github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
72−github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
73−github.com/charmbracelet/bubbletea v1.3.5 h1:JAMNLTbqMOhSwoELIr0qyP4VidFq72/6E9j7HHmRKQc=
74−github.com/charmbracelet/bubbletea v1.3.5/go.mod h1:TkCnmH+aBd4LrXhXcqrKiYwRs7qyQx5rBgH5fVY3v54=
75−github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
76−github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
77−github.com/charmbracelet/glamour v0.9.1 h1:11dEfiGP8q1BEqvGoIjivuc2rBk+5qEXdPtaQ2WoiCM=
78−github.com/charmbracelet/glamour v0.9.1/go.mod h1:+SHvIS8qnwhgTpVMiXwn7OfGomSqff1cHBCI8jLOetk=
79−github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
80−github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
81−github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
82−github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
83−github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
84−github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
85−github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
86−github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
71+github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1 h1:swACzss0FjnyPz1enfX56GKkLiuKg5FlyVmOLIlU2kE=
72+github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1/go.mod h1:6HamsBKWqEC/FVHuQMHgQL+knPyvHH55HwJDHl/adMw=
73+github.com/charmbracelet/bubbletea/v2 v2.0.0-beta1 h1:yaxFt97mvofGY7bYZn8U/aSVoamXGE3O4AEvWhshUDI=
74+github.com/charmbracelet/bubbletea/v2 v2.0.0-beta1/go.mod h1:qbcZLI5z8R49v9xBdU5V5Dh5D2uccx8wSwBqxQyErqc=
75+github.com/charmbracelet/colorprofile v0.3.0 h1:KtLh9uuu1RCt+Hml4s6Hz+kB1PfV3wi++1h5ia65yKQ=
76+github.com/charmbracelet/colorprofile v0.3.0/go.mod h1:oHJ340RS2nmG1zRGPmhJKJ/jf4FPNNk0P39/wBPA1G0=
77+github.com/charmbracelet/glamour/v2 v2.0.0-20250513163904-eeeced3bb3c6 h1:AKhOV8dSRU3KpqMgpGME9JU7ouumB2S6hMmD6PRJeTc=
78+github.com/charmbracelet/glamour/v2 v2.0.0-20250513163904-eeeced3bb3c6/go.mod h1:7xBAUTCSADx9mHG0uBf4NDoVpYxMzIQ2j/NMLGdFsFM=
79+github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.1.0.20250513162854-28902d027c40 h1:SxOUomYAVo5zh+6WCH1bGshlAnSKP0ZeovI0FHAl9kg=
80+github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.1.0.20250513162854-28902d027c40/go.mod h1:tRlx/Hu0lo/j9viunCN2H+Ze6JrmdjQlXUQvvArgaOc=
81+github.com/charmbracelet/x/ansi v0.9.2 h1:92AGsQmNTRMzuzHEYfCdjQeUzTrgE1vfO5/7fEVoXdY=
82+github.com/charmbracelet/x/ansi v0.9.2/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
83+github.com/charmbracelet/x/cellbuf v0.0.14-0.20250326144200-0875329e71da h1:8MGKD5WBtuzfXglq0CnyzVSwGojv57X+H46OL9OUyRA=
84+github.com/charmbracelet/x/cellbuf v0.0.14-0.20250326144200-0875329e71da/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
85+github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a h1:FsHEJ52OC4VuTzU8t+n5frMjLvpYWEznSr/u8tnkCYw=
86+github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
87+github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf h1:rLG0Yb6MQSDKdB52aGX55JT1oi0P0Kuaj7wi1bLUpnI=
88+github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf/go.mod h1:B3UgsnsBZS/eX42BlaNiJkD1pPOUa+oF1IYC6Yd2CEU=
89+github.com/charmbracelet/x/input v0.3.4 h1:Mujmnv/4DaitU0p+kIsrlfZl/UlmeLKw1wAP3e1fMN0=
90+github.com/charmbracelet/x/input v0.3.4/go.mod h1:JI8RcvdZWQIhn09VzeK3hdp4lTz7+yhiEdpEQtZN+2c=
8791github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
8892github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
93+github.com/charmbracelet/x/windows v0.2.0 h1:ilXA1GJjTNkgOm94CLPeSz7rar54jtFatdmoiONPuEw=
94+github.com/charmbracelet/x/windows v0.2.0/go.mod h1:ZibNFR49ZFqCXgP76sYanisxRyC+EYrBE7TTknD8s1s=
8995github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
9096github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9197github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -96,8 +102,6 @@ github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yA
96102github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
97103github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
98104github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
99−github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
100−github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
101105github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
102106github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
103107github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
@@ -146,16 +150,12 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
146150github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
147151github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
148152github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
149−github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231 h1:9rjt7AfnrXKNSZhp36A3/4QAZAwGGCGD/p8Bse26zms=
150−github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231/go.mod h1:S5etECMx+sZnW0Gm100Ma9J1PgVCTgNyFaqGu2b08b4=
151153github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
152154github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
153155github.com/mark3labs/mcp-go v0.17.0 h1:5Ps6T7qXr7De/2QTqs9h6BKeZ/qdeUeGrgM5lPzi930=
154156github.com/mark3labs/mcp-go v0.17.0/go.mod h1:KmJndYv7GIgcPVwEKJjNcbhVQ+hJGJhrCCB/9xITzpE=
155157github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
156158github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
157−github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
158−github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
159159github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
160160github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
161161github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
@@ -297,7 +297,6 @@ golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
297297golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
298298golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
299299golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
300−golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
301300golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
302301golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
303302golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -318,8 +317,6 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
318317golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
319318golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
320319golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
321−golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
322−golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
323320golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
324321golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
325322golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
internal/diff/diff.go+9−11
@@ -3,6 +3,7 @@ package diff
33import (
44 "bytes"
55 "fmt"
6+ "image/color"
67 "io"
78 "regexp"
89 "strconv"
@@ -13,7 +14,7 @@ import (
1314 "github.com/alecthomas/chroma/v2/lexers"
1415 "github.com/alecthomas/chroma/v2/styles"
1516 "github.com/aymanbagabas/go-udiff"
16− "github.com/charmbracelet/lipgloss"
17+ "github.com/charmbracelet/lipgloss/v2"
1718 "github.com/charmbracelet/x/ansi"
1819 "github.com/opencode-ai/opencode/internal/config"
1920 "github.com/opencode-ai/opencode/internal/tui/theme"
@@ -323,7 +324,7 @@ func pairLines(lines []DiffLine) []linePair {
323324// -------------------------------------------------------------------------
324325
325326// SyntaxHighlight applies syntax highlighting to text based on file extension
326−func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg lipgloss.TerminalColor) error {
327+func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg color.Color) error {
327328 t := theme.CurrentTheme()
328329
329330 // Determine the language lexer to use
@@ -531,16 +532,13 @@ func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg lipglos
531532 return f.Format(w, s, it)
532533}
533534
534−// getColor returns the appropriate hex color string based on terminal background
535−func getColor(adaptiveColor lipgloss.AdaptiveColor) string {
536− if lipgloss.HasDarkBackground() {
537− return adaptiveColor.Dark
538− }
539− return adaptiveColor.Light
535+func getColor(c color.Color) string {
536+ rgba := color.RGBAModel.Convert(c).(color.RGBA)
537+ return fmt.Sprintf("#%02x%02x%02x", rgba.R, rgba.G, rgba.B)
540538}
541539
542540// highlightLine applies syntax highlighting to a single line
543−func highlightLine(fileName string, line string, bg lipgloss.TerminalColor) string {
541+func highlightLine(fileName string, line string, bg color.Color) string {
544542 var buf bytes.Buffer
545543 err := SyntaxHighlight(&buf, line, fileName, "terminal16m", bg)
546544 if err != nil {
@@ -563,7 +561,7 @@ func createStyles(t theme.Theme) (removedLineStyle, addedLineStyle, contextLineS
563561// Rendering Functions
564562// -------------------------------------------------------------------------
565563
566−func lipglossToHex(color lipgloss.Color) string {
564+func lipglossToHex(color color.Color) string {
567565 r, g, b, a := color.RGBA()
568566
569567 // Scale uint32 values (0-65535) to uint8 (0-255).
@@ -576,7 +574,7 @@ func lipglossToHex(color lipgloss.Color) string {
576574}
577575
578576// applyHighlighting applies intra-line highlighting to a piece of text
579−func applyHighlighting(content string, segments []Segment, segmentType LineType, highlightBg lipgloss.AdaptiveColor) string {
577+func applyHighlighting(content string, segments []Segment, segmentType LineType, highlightBg color.Color) string {
580578 // Find all ANSI sequences in the content
581579 ansiRegex := regexp.MustCompile(`\x1b(?:[@-Z\\-_]|\[[0-9?]*(?:;[0-9?]*)*[@-~])`)
582580 ansiMatches := ansiRegex.FindAllStringIndex(content, -1)
internal/format/spinner.go+2−2
@@ -5,8 +5,8 @@ import (
55 "fmt"
66 "os"
77
8− "github.com/charmbracelet/bubbles/spinner"
9− tea "github.com/charmbracelet/bubbletea"
8+ "github.com/charmbracelet/bubbles/v2/spinner"
9+ tea "github.com/charmbracelet/bubbletea/v2"
1010)
1111
1212// Spinner wraps the bubbles spinner for non-interactive mode
internal/tui/components/chat/chat.go+1−1
@@ -4,7 +4,7 @@ import (
44 "fmt"
55 "sort"
66
7− "github.com/charmbracelet/lipgloss"
7+ "github.com/charmbracelet/lipgloss/v2"
88 "github.com/charmbracelet/x/ansi"
99 "github.com/opencode-ai/opencode/internal/config"
1010 "github.com/opencode-ai/opencode/internal/message"
internal/tui/components/chat/editor.go+25−16
@@ -8,10 +8,10 @@ import (
88 "strings"
99 "unicode"
1010
11− "github.com/charmbracelet/bubbles/key"
12− "github.com/charmbracelet/bubbles/textarea"
13− tea "github.com/charmbracelet/bubbletea"
14− "github.com/charmbracelet/lipgloss"
11+ "github.com/charmbracelet/bubbles/v2/key"
12+ "github.com/charmbracelet/bubbles/v2/textarea"
13+ tea "github.com/charmbracelet/bubbletea/v2"
14+ "github.com/charmbracelet/lipgloss/v2"
1515 "github.com/opencode-ai/opencode/internal/app"
1616 "github.com/opencode-ai/opencode/internal/logging"
1717 "github.com/opencode-ai/opencode/internal/message"
@@ -162,7 +162,7 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
162162 return m, cmd
163163 }
164164 m.attachments = append(m.attachments, msg.Attachment)
165− case tea.KeyMsg:
165+ case tea.KeyPressMsg:
166166 if key.Matches(msg, DeleteKeyMaps.AttachmentDeleteMode) {
167167 m.deleteMode = true
168168 return m, nil
@@ -172,8 +172,9 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
172172 m.attachments = nil
173173 return m, nil
174174 }
175− if m.deleteMode && len(msg.Runes) > 0 && unicode.IsDigit(msg.Runes[0]) {
176− num := int(msg.Runes[0] - '0')
175+ rune := msg.Code
176+ if m.deleteMode && unicode.IsDigit(rune) {
177+ num := int(rune - '0')
177178 m.deleteMode = false
178179 if num < 10 && len(m.attachments) > num {
179180 if num == 0 {
@@ -286,14 +287,22 @@ func CreateTextArea(existing *textarea.Model) textarea.Model {
286287 textMutedColor := t.TextMuted()
287288
288289 ta := textarea.New()
289− ta.BlurredStyle.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
290− ta.BlurredStyle.CursorLine = styles.BaseStyle().Background(bgColor)
291− ta.BlurredStyle.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
292− ta.BlurredStyle.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
293− ta.FocusedStyle.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
294− ta.FocusedStyle.CursorLine = styles.BaseStyle().Background(bgColor)
295− ta.FocusedStyle.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
296− ta.FocusedStyle.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
290+ s := textarea.DefaultDarkStyles()
291+ b := s.Blurred
292+ b.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
293+ b.CursorLine = styles.BaseStyle().Background(bgColor)
294+ b.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
295+ b.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
296+
297+ f := s.Focused
298+ f.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
299+ f.CursorLine = styles.BaseStyle().Background(bgColor)
300+ f.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
301+ f.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
302+
303+ s.Focused = f
304+ s.Blurred = b
305+ ta.Styles = s
297306
298307 ta.Prompt = " "
299308 ta.ShowLineNumbers = false
@@ -309,7 +318,7 @@ func CreateTextArea(existing *textarea.Model) textarea.Model {
309318 return ta
310319}
311320
312−func NewEditorCmp(app *app.App) tea.Model {
321+func NewEditorCmp(app *app.App) util.Model {
313322 ta := CreateTextArea(nil)
314323 return &editorCmp{
315324 app: app,
internal/tui/components/chat/list.go+12−12
@@ -5,11 +5,11 @@ import (
55 "fmt"
66 "math"
77
8− "github.com/charmbracelet/bubbles/key"
9− "github.com/charmbracelet/bubbles/spinner"
10− "github.com/charmbracelet/bubbles/viewport"
11− tea "github.com/charmbracelet/bubbletea"
12− "github.com/charmbracelet/lipgloss"
8+ "github.com/charmbracelet/bubbles/v2/key"
9+ "github.com/charmbracelet/bubbles/v2/spinner"
10+ "github.com/charmbracelet/bubbles/v2/viewport"
11+ tea "github.com/charmbracelet/bubbletea/v2"
12+ "github.com/charmbracelet/lipgloss/v2"
1313 "github.com/opencode-ai/opencode/internal/app"
1414 "github.com/opencode-ai/opencode/internal/message"
1515 "github.com/opencode-ai/opencode/internal/pubsub"
@@ -426,10 +426,10 @@ func (m *messagesCmp) SetSize(width, height int) tea.Cmd {
426426 }
427427 m.width = width
428428 m.height = height
429− m.viewport.Width = width
430− m.viewport.Height = height - 2
431− m.attachments.Width = width + 40
432− m.attachments.Height = 3
429+ m.viewport.SetWidth(width)
430+ m.viewport.SetHeight(height - 2)
431+ m.attachments.SetWidth(width + 40)
432+ m.attachments.SetHeight(3)
433433 m.rerender()
434434 return nil
435435}
@@ -468,11 +468,11 @@ func (m *messagesCmp) BindingKeys() []key.Binding {
468468 }
469469}
470470
471−func NewMessagesCmp(app *app.App) tea.Model {
471+func NewMessagesCmp(app *app.App) util.Model {
472472 s := spinner.New()
473473 s.Spinner = spinner.Pulse
474− vp := viewport.New(0, 0)
475− attachmets := viewport.New(0, 0)
474+ vp := viewport.New()
475+ attachmets := viewport.New()
476476 vp.KeyMap.PageUp = messageKeys.PageUp
477477 vp.KeyMap.PageDown = messageKeys.PageDown
478478 vp.KeyMap.HalfPageUp = messageKeys.HalfPageUp
internal/tui/components/chat/message.go+8−26
@@ -8,7 +8,7 @@ import (
88 "strings"
99 "time"
1010
11− "github.com/charmbracelet/lipgloss"
11+ "github.com/charmbracelet/lipgloss/v2"
1212 "github.com/charmbracelet/x/ansi"
1313 "github.com/opencode-ai/opencode/internal/config"
1414 "github.com/opencode-ai/opencode/internal/diff"
@@ -60,7 +60,7 @@ func renderMessage(msg string, isUser bool, isFocused bool, width int, info ...s
6060
6161 // Apply markdown formatting and handle background color
6262 parts := []string{
63− styles.ForceReplaceBackgroundWithLipgloss(toMarkdown(msg, isFocused, width), t.Background()),
63+ toMarkdown(msg, isFocused, width),
6464 }
6565
6666 // Remove newline at the end
@@ -454,16 +454,10 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
454454 resultContent := truncateHeight(response.Content, maxResultHeight)
455455 switch toolCall.Name {
456456 case agent.AgentToolName:
457− return styles.ForceReplaceBackgroundWithLipgloss(
458− toMarkdown(resultContent, false, width),
459− t.Background(),
460− )
457+ return toMarkdown(resultContent, false, width)
461458 case tools.BashToolName:
462459 resultContent = fmt.Sprintf("```bash\n%s\n```", resultContent)
463− return styles.ForceReplaceBackgroundWithLipgloss(
464− toMarkdown(resultContent, true, width),
465− t.Background(),
466− )
460+ return toMarkdown(resultContent, true, width)
467461 case tools.EditToolName:
468462 metadata := tools.EditResponseMetadata{}
469463 json.Unmarshal([]byte(response.Metadata), &metadata)
@@ -481,10 +475,7 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
481475 mdFormat = "html"
482476 }
483477 resultContent = fmt.Sprintf("```%s\n%s\n```", mdFormat, resultContent)
484− return styles.ForceReplaceBackgroundWithLipgloss(
485− toMarkdown(resultContent, true, width),
486− t.Background(),
487− )
478+ return toMarkdown(resultContent, true, width)
488479 case tools.GlobToolName:
489480 return baseStyle.Width(width).Foreground(t.TextMuted()).Render(resultContent)
490481 case tools.GrepToolName:
@@ -503,10 +494,7 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
503494 ext = strings.ToLower(ext[1:])
504495 }
505496 resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(metadata.Content, maxResultHeight))
506− return styles.ForceReplaceBackgroundWithLipgloss(
507− toMarkdown(resultContent, true, width),
508− t.Background(),
509− )
497+ return toMarkdown(resultContent, true, width)
510498 case tools.WriteToolName:
511499 params := tools.WriteParams{}
512500 json.Unmarshal([]byte(toolCall.Input), &params)
@@ -519,16 +507,10 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
519507 ext = strings.ToLower(ext[1:])
520508 }
521509 resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(params.Content, maxResultHeight))
522− return styles.ForceReplaceBackgroundWithLipgloss(
523− toMarkdown(resultContent, true, width),
524− t.Background(),
525− )
510+ return toMarkdown(resultContent, true, width)
526511 default:
527512 resultContent = fmt.Sprintf("```text\n%s\n```", resultContent)
528− return styles.ForceReplaceBackgroundWithLipgloss(
529− toMarkdown(resultContent, true, width),
530− t.Background(),
531− )
513+ return toMarkdown(resultContent, true, width)
532514 }
533515}
534516
internal/tui/components/chat/sidebar.go+4−3
@@ -6,8 +6,8 @@ import (
66 "sort"
77 "strings"
88
9− tea "github.com/charmbracelet/bubbletea"
10− "github.com/charmbracelet/lipgloss"
9+ tea "github.com/charmbracelet/bubbletea/v2"
10+ "github.com/charmbracelet/lipgloss/v2"
1111 "github.com/opencode-ai/opencode/internal/config"
1212 "github.com/opencode-ai/opencode/internal/diff"
1313 "github.com/opencode-ai/opencode/internal/history"
@@ -15,6 +15,7 @@ import (
1515 "github.com/opencode-ai/opencode/internal/session"
1616 "github.com/opencode-ai/opencode/internal/tui/styles"
1717 "github.com/opencode-ai/opencode/internal/tui/theme"
18+ "github.com/opencode-ai/opencode/internal/tui/util"
1819)
1920
2021type sidebarCmp struct {
@@ -235,7 +236,7 @@ func (m *sidebarCmp) GetSize() (int, int) {
235236 return m.width, m.height
236237}
237238
238−func NewSidebarCmp(session session.Session, history history.Service) tea.Model {
239+func NewSidebarCmp(session session.Session, history history.Service) util.Model {
239240 return &sidebarCmp{
240241 session: session,
241242 history: history,
internal/tui/components/core/status.go+3−3
@@ -5,8 +5,8 @@ import (
55 "strings"
66 "time"
77
8− tea "github.com/charmbracelet/bubbletea"
9− "github.com/charmbracelet/lipgloss"
8+ tea "github.com/charmbracelet/bubbletea/v2"
9+ "github.com/charmbracelet/lipgloss/v2"
1010 "github.com/opencode-ai/opencode/internal/config"
1111 "github.com/opencode-ai/opencode/internal/llm/models"
1212 "github.com/opencode-ai/opencode/internal/lsp"
@@ -20,7 +20,7 @@ import (
2020)
2121
2222type StatusCmp interface {
23− tea.Model
23+ util.Model
2424}
2525
2626type statusCmp struct {
internal/tui/components/dialog/arguments.go+22−28
@@ -2,10 +2,11 @@ package dialog
22
33import (
44 "fmt"
5− "github.com/charmbracelet/bubbles/key"
6− "github.com/charmbracelet/bubbles/textinput"
7− tea "github.com/charmbracelet/bubbletea"
8− "github.com/charmbracelet/lipgloss"
5+
6+ "github.com/charmbracelet/bubbles/v2/key"
7+ "github.com/charmbracelet/bubbles/v2/textinput"
8+ tea "github.com/charmbracelet/bubbletea/v2"
9+ "github.com/charmbracelet/lipgloss/v2"
910
1011 "github.com/opencode-ai/opencode/internal/tui/styles"
1112 "github.com/opencode-ai/opencode/internal/tui/theme"
@@ -70,17 +71,18 @@ func NewMultiArgumentsDialogCmp(commandID, content string, argNames []string) Mu
7071 for i, name := range argNames {
7172 ti := textinput.New()
7273 ti.Placeholder = fmt.Sprintf("Enter value for %s...", name)
73− ti.Width = 40
74+ ti.SetWidth(40)
7475 ti.Prompt = ""
75− ti.PlaceholderStyle = ti.PlaceholderStyle.Background(t.Background())
76− ti.PromptStyle = ti.PromptStyle.Background(t.Background())
77− ti.TextStyle = ti.TextStyle.Background(t.Background())
78−
76+ ti.Styles.Focused.Placeholder = ti.Styles.Focused.Placeholder.Background(t.Background())
77+ ti.Styles.Blurred.Placeholder = ti.Styles.Blurred.Placeholder.Background(t.Background())
78+ ti.Styles.Focused.Suggestion = ti.Styles.Focused.Suggestion.Background(t.Background()).Foreground(t.Primary())
79+ ti.Styles.Blurred.Suggestion = ti.Styles.Blurred.Suggestion.Background(t.Background())
80+ ti.Styles.Focused.Text = ti.Styles.Focused.Text.Background(t.Background()).Foreground(t.Primary())
81+ ti.Styles.Blurred.Text = ti.Styles.Blurred.Text.Background(t.Background())
82+
7983 // Only focus the first input initially
8084 if i == 0 {
8185 ti.Focus()
82− ti.PromptStyle = ti.PromptStyle.Foreground(t.Primary())
83− ti.TextStyle = ti.TextStyle.Foreground(t.Primary())
8486 } else {
8587 ti.Blur()
8688 }
@@ -89,11 +91,11 @@ func NewMultiArgumentsDialogCmp(commandID, content string, argNames []string) Mu
8991 }
9092
9193 return MultiArgumentsDialogCmp{
92− inputs: inputs,
93− keys: argumentsDialogKeyMap{},
94− commandID: commandID,
95− content: content,
96− argNames: argNames,
94+ inputs: inputs,
95+ keys: argumentsDialogKeyMap{},
96+ commandID: commandID,
97+ content: content,
98+ argNames: argNames,
9799 focusIndex: 0,
98100 }
99101}
@@ -108,15 +110,13 @@ func (m MultiArgumentsDialogCmp) Init() tea.Cmd {
108110 m.inputs[i].Blur()
109111 }
110112 }
111−
113+
112114 return textinput.Blink
113115}
114116
115117// Update implements tea.Model.
116118func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
117119 var cmds []tea.Cmd
118− t := theme.CurrentTheme()
119−
120120 switch msg := msg.(type) {
121121 case tea.KeyMsg:
122122 switch {
@@ -145,22 +145,16 @@ func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
145145 m.inputs[m.focusIndex].Blur()
146146 m.focusIndex++
147147 m.inputs[m.focusIndex].Focus()
148− m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
149− m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
150148 case key.Matches(msg, key.NewBinding(key.WithKeys("tab"))):
151149 // Move to the next input
152150 m.inputs[m.focusIndex].Blur()
153151 m.focusIndex = (m.focusIndex + 1) % len(m.inputs)
154152 m.inputs[m.focusIndex].Focus()
155− m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
156− m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
157153 case key.Matches(msg, key.NewBinding(key.WithKeys("shift+tab"))):
158154 // Move to the previous input
159155 m.inputs[m.focusIndex].Blur()
160156 m.focusIndex = (m.focusIndex - 1 + len(m.inputs)) % len(m.inputs)
161157 m.inputs[m.focusIndex].Focus()
162− m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
163− m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
164158 }
165159 case tea.WindowSizeMsg:
166160 m.width = msg.Width
@@ -206,13 +200,13 @@ func (m MultiArgumentsDialogCmp) View() string {
206200 Width(maxWidth).
207201 Padding(1, 1, 0, 1).
208202 Background(t.Background())
209−
203+
210204 if i == m.focusIndex {
211205 labelStyle = labelStyle.Foreground(t.Primary()).Bold(true)
212206 } else {
213207 labelStyle = labelStyle.Foreground(t.TextMuted())
214208 }
215−
209+
216210 label := labelStyle.Render(m.argNames[i] + ":")
217211
218212 field := lipgloss.NewStyle().
@@ -254,4 +248,4 @@ func (m *MultiArgumentsDialogCmp) SetSize(width, height int) {
254248// Bindings implements layout.Bindings.
255249func (m MultiArgumentsDialogCmp) Bindings() []key.Binding {
256250 return m.keys.ShortHelp()
257−}
251+}
internal/tui/components/dialog/commands.go+4−4
@@ -1,9 +1,9 @@
11package dialog
22
33import (
4− "github.com/charmbracelet/bubbles/key"
5− tea "github.com/charmbracelet/bubbletea"
6− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/bubbles/v2/key"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6+ "github.com/charmbracelet/lipgloss/v2"
77 utilComponents "github.com/opencode-ai/opencode/internal/tui/components/util"
88 "github.com/opencode-ai/opencode/internal/tui/layout"
99 "github.com/opencode-ai/opencode/internal/tui/styles"
@@ -56,7 +56,7 @@ type CloseCommandDialogMsg struct{}
5656
5757// CommandDialog interface for the command selection dialog
5858type CommandDialog interface {
59− tea.Model
59+ util.Model
6060 layout.Bindings
6161 SetCommands(commands []Command)
6262}
internal/tui/components/dialog/complete.go+5−5
@@ -1,10 +1,10 @@
11package dialog
22
33import (
4− "github.com/charmbracelet/bubbles/key"
5− "github.com/charmbracelet/bubbles/textarea"
6− tea "github.com/charmbracelet/bubbletea"
7− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/bubbles/v2/key"
5+ "github.com/charmbracelet/bubbles/v2/textarea"
6+ tea "github.com/charmbracelet/bubbletea/v2"
7+ "github.com/charmbracelet/lipgloss/v2"
88 "github.com/opencode-ai/opencode/internal/logging"
99 utilComponents "github.com/opencode-ai/opencode/internal/tui/components/util"
1010 "github.com/opencode-ai/opencode/internal/tui/layout"
@@ -77,7 +77,7 @@ type CompletionDialogCompleteItemMsg struct {
7777type CompletionDialogCloseMsg struct{}
7878
7979type CompletionDialog interface {
80− tea.Model
80+ util.Model
8181 layout.Bindings
8282 SetWidth(width int)
8383}
internal/tui/components/dialog/custom_commands.go+1−1
@@ -7,7 +7,7 @@ import (
77 "regexp"
88 "strings"
99
10− tea "github.com/charmbracelet/bubbletea"
10+ tea "github.com/charmbracelet/bubbletea/v2"
1111 "github.com/opencode-ai/opencode/internal/config"
1212 "github.com/opencode-ai/opencode/internal/tui/util"
1313)
internal/tui/components/dialog/filepicker.go+13−13
@@ -9,11 +9,11 @@ import (
99 "strings"
1010 "time"
1111
12− "github.com/charmbracelet/bubbles/key"
13− "github.com/charmbracelet/bubbles/textinput"
14− "github.com/charmbracelet/bubbles/viewport"
15− tea "github.com/charmbracelet/bubbletea"
16− "github.com/charmbracelet/lipgloss"
12+ "github.com/charmbracelet/bubbles/v2/key"
13+ "github.com/charmbracelet/bubbles/v2/textinput"
14+ "github.com/charmbracelet/bubbles/v2/viewport"
15+ tea "github.com/charmbracelet/bubbletea/v2"
16+ "github.com/charmbracelet/lipgloss/v2"
1717 "github.com/opencode-ai/opencode/internal/app"
1818 "github.com/opencode-ai/opencode/internal/config"
1919 "github.com/opencode-ai/opencode/internal/logging"
@@ -122,8 +122,8 @@ func (f *filepickerCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
122122 case tea.WindowSizeMsg:
123123 f.width = 60
124124 f.height = 20
125− f.viewport.Width = 80
126− f.viewport.Height = 22
125+ f.viewport.SetWidth(80)
126+ f.viewport.SetHeight(22)
127127 f.cursor = 0
128128 f.getCurrentFileBelowCursor()
129129 case tea.KeyMsg:
@@ -319,7 +319,7 @@ func (f *filepickerCmp) View() string {
319319 Render(f.cwd.View())
320320
321321 viewportstyle := lipgloss.NewStyle().
322− Width(f.viewport.Width).
322+ Width(f.viewport.Width()).
323323 Background(t.Background()).
324324 Border(lipgloss.RoundedBorder()).
325325 BorderForeground(t.TextMuted()).
@@ -353,7 +353,7 @@ func (f *filepickerCmp) View() string {
353353}
354354
355355type FilepickerCmp interface {
356− tea.Model
356+ util.Model
357357 ToggleFilepicker(showFilepicker bool)
358358 IsCWDFocused() bool
359359}
@@ -374,11 +374,11 @@ func NewFilepickerCmp(app *app.App) FilepickerCmp {
374374 }
375375 baseDir := DirNode{parent: nil, directory: homepath}
376376 dirs := readDir(homepath, false)
377− viewport := viewport.New(0, 0)
377+ viewport := viewport.New()
378378 currentDirectory := textinput.New()
379379 currentDirectory.CharLimit = 200
380− currentDirectory.Width = 44
381− currentDirectory.Cursor.Blink = true
380+ currentDirectory.SetWidth(44)
381+ currentDirectory.Cursor().Blink = true
382382 currentDirectory.SetValue(baseDir.directory)
383383 return &filepickerCmp{cwdDetails: &baseDir, dirs: dirs, cursorChain: make(stack, 0), viewport: viewport, cwd: currentDirectory, app: app}
384384}
@@ -396,7 +396,7 @@ func (f *filepickerCmp) getCurrentFileBelowCursor() {
396396 fullPath := f.cwdDetails.directory + "/" + dir.Name()
397397
398398 go func() {
399− imageString, err := image.ImagePreview(f.viewport.Width-4, fullPath)
399+ imageString, err := image.ImagePreview(f.viewport.Width()-4, fullPath)
400400 if err != nil {
401401 logging.Error(err.Error())
402402 f.viewport.SetContent("Preview unavailable")
internal/tui/components/dialog/help.go+7−6
@@ -3,11 +3,12 @@ package dialog
33import (
44 "strings"
55
6− "github.com/charmbracelet/bubbles/key"
7− tea "github.com/charmbracelet/bubbletea"
8− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/bubbles/v2/key"
7+ tea "github.com/charmbracelet/bubbletea/v2"
8+ "github.com/charmbracelet/lipgloss/v2"
99 "github.com/opencode-ai/opencode/internal/tui/styles"
1010 "github.com/opencode-ai/opencode/internal/tui/theme"
11+ "github.com/opencode-ai/opencode/internal/tui/util"
1112)
1213
1314type helpCmp struct {
@@ -134,7 +135,7 @@ func (h *helpCmp) render() string {
134135 pairs = append(pairs, pair)
135136 }
136137
137− // https://github.com/charmbracelet/lipgloss/issues/209
138+ // https://github.com/charmbracelet/lipgloss/v2/issues/209
138139 if len(pairs) > 1 {
139140 prefix := pairs[:len(pairs)-1]
140141 lastPair := pairs[len(pairs)-1]
@@ -144,7 +145,7 @@ func (h *helpCmp) render() string {
144145 lipgloss.Left, // x
145146 lipgloss.Top, // y
146147 lastPair, // content
147− lipgloss.WithWhitespaceBackground(t.Background()),
148+ lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
148149 ))
149150 content := baseStyle.Width(h.width).Render(
150151 lipgloss.JoinHorizontal(
@@ -191,7 +192,7 @@ func (h *helpCmp) View() string {
191192}
192193
193194type HelpCmp interface {
194− tea.Model
195+ util.Model
195196 SetBindings([]key.Binding)
196197}
197198
internal/tui/components/dialog/init.go+3−3
@@ -1,9 +1,9 @@
11package dialog
22
33import (
4− "github.com/charmbracelet/bubbles/key"
5− tea "github.com/charmbracelet/bubbletea"
6− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/bubbles/v2/key"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6+ "github.com/charmbracelet/lipgloss/v2"
77
88 "github.com/opencode-ai/opencode/internal/tui/styles"
99 "github.com/opencode-ai/opencode/internal/tui/theme"
internal/tui/components/dialog/models.go+4−5
@@ -5,9 +5,9 @@ import (
55 "slices"
66 "strings"
77
8− "github.com/charmbracelet/bubbles/key"
9− tea "github.com/charmbracelet/bubbletea"
10− "github.com/charmbracelet/lipgloss"
8+ "github.com/charmbracelet/bubbles/v2/key"
9+ tea "github.com/charmbracelet/bubbletea/v2"
10+ "github.com/charmbracelet/lipgloss/v2"
1111 "github.com/opencode-ai/opencode/internal/config"
1212 "github.com/opencode-ai/opencode/internal/llm/models"
1313 "github.com/opencode-ai/opencode/internal/tui/layout"
@@ -31,7 +31,7 @@ type CloseModelDialogMsg struct{}
3131
3232// ModelDialog interface for the model selection dialog
3333type ModelDialog interface {
34− tea.Model
34+ util.Model
3535 layout.Bindings
3636}
3737
@@ -281,7 +281,6 @@ func (m *modelDialogCmp) setupModels() {
281281}
282282
283283func GetSelectedModel(cfg *config.Config) models.Model {
284−
285284 agentCfg := cfg.Agents[config.AgentCoder]
286285 selectedModelId := agentCfg.Model
287286 return models.SupportedModels[selectedModelId]
internal/tui/components/dialog/permission.go+17−20
@@ -4,10 +4,10 @@ import (
44 "fmt"
55 "strings"
66
7− "github.com/charmbracelet/bubbles/key"
8− "github.com/charmbracelet/bubbles/viewport"
9− tea "github.com/charmbracelet/bubbletea"
10− "github.com/charmbracelet/lipgloss"
7+ "github.com/charmbracelet/bubbles/v2/key"
8+ "github.com/charmbracelet/bubbles/v2/viewport"
9+ tea "github.com/charmbracelet/bubbletea/v2"
10+ "github.com/charmbracelet/lipgloss/v2"
1111 "github.com/opencode-ai/opencode/internal/diff"
1212 "github.com/opencode-ai/opencode/internal/llm/tools"
1313 "github.com/opencode-ai/opencode/internal/permission"
@@ -34,7 +34,7 @@ type PermissionResponseMsg struct {
3434
3535// PermissionDialogCmp interface for permission dialog component
3636type PermissionDialogCmp interface {
37− tea.Model
37+ util.Model
3838 layout.Bindings
3939 SetPermissions(permission permission.PermissionRequest) tea.Cmd
4040}
@@ -268,7 +268,6 @@ func (p *permissionDialogCmp) renderHeader() string {
268268}
269269
270270func (p *permissionDialogCmp) renderBashContent() string {
271− t := theme.CurrentTheme()
272271 baseStyle := styles.BaseStyle()
273272
274273 if pr, ok := p.permission.Params.(tools.BashPermissionsParams); ok {
@@ -278,11 +277,11 @@ func (p *permissionDialogCmp) renderBashContent() string {
278277 renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
279278 r := styles.GetMarkdownRenderer(p.width - 10)
280279 s, err := r.Render(content)
281− return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
280+ return s, err
282281 })
283282
284283 finalContent := baseStyle.
285− Width(p.contentViewPort.Width).
284+ Width(p.contentViewPort.Width()).
286285 Render(renderedContent)
287286 p.contentViewPort.SetContent(finalContent)
288287 return p.styleViewport()
@@ -293,7 +292,7 @@ func (p *permissionDialogCmp) renderBashContent() string {
293292func (p *permissionDialogCmp) renderEditContent() string {
294293 if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
295294 diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
296− return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
295+ return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width()))
297296 })
298297
299298 p.contentViewPort.SetContent(diff)
@@ -305,7 +304,7 @@ func (p *permissionDialogCmp) renderEditContent() string {
305304func (p *permissionDialogCmp) renderPatchContent() string {
306305 if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
307306 diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
308− return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
307+ return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width()))
309308 })
310309
311310 p.contentViewPort.SetContent(diff)
@@ -318,7 +317,7 @@ func (p *permissionDialogCmp) renderWriteContent() string {
318317 if pr, ok := p.permission.Params.(tools.WritePermissionsParams); ok {
319318 // Use the cache for diff rendering
320319 diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
321− return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
320+ return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width()))
322321 })
323322
324323 p.contentViewPort.SetContent(diff)
@@ -328,7 +327,6 @@ func (p *permissionDialogCmp) renderWriteContent() string {
328327}
329328
330329func (p *permissionDialogCmp) renderFetchContent() string {
331− t := theme.CurrentTheme()
332330 baseStyle := styles.BaseStyle()
333331
334332 if pr, ok := p.permission.Params.(tools.FetchPermissionsParams); ok {
@@ -338,11 +336,11 @@ func (p *permissionDialogCmp) renderFetchContent() string {
338336 renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
339337 r := styles.GetMarkdownRenderer(p.width - 10)
340338 s, err := r.Render(content)
341− return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
339+ return s, err
342340 })
343341
344342 finalContent := baseStyle.
345− Width(p.contentViewPort.Width).
343+ Width(p.contentViewPort.Width()).
346344 Render(renderedContent)
347345 p.contentViewPort.SetContent(finalContent)
348346 return p.styleViewport()
@@ -351,7 +349,6 @@ func (p *permissionDialogCmp) renderFetchContent() string {
351349}
352350
353351func (p *permissionDialogCmp) renderDefaultContent() string {
354− t := theme.CurrentTheme()
355352 baseStyle := styles.BaseStyle()
356353
357354 content := p.permission.Description
@@ -360,11 +357,11 @@ func (p *permissionDialogCmp) renderDefaultContent() string {
360357 renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
361358 r := styles.GetMarkdownRenderer(p.width - 10)
362359 s, err := r.Render(content)
363− return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
360+ return s, err
364361 })
365362
366363 finalContent := baseStyle.
367− Width(p.contentViewPort.Width).
364+ Width(p.contentViewPort.Width()).
368365 Render(renderedContent)
369366 p.contentViewPort.SetContent(finalContent)
370367
@@ -398,8 +395,8 @@ func (p *permissionDialogCmp) render() string {
398395 buttons := p.renderButtons()
399396
400397 // Calculate content height dynamically based on window size
401− p.contentViewPort.Height = p.height - lipgloss.Height(headerContent) - lipgloss.Height(buttons) - 2 - lipgloss.Height(title)
402− p.contentViewPort.Width = p.width - 4
398+ p.contentViewPort.SetHeight(p.height - lipgloss.Height(headerContent) - lipgloss.Height(buttons) - 2 - lipgloss.Height(title))
399+ p.contentViewPort.SetWidth(p.width - 4)
403400
404401 // Render content based on tool type
405402 var contentFinal string
@@ -511,7 +508,7 @@ func (c *permissionDialogCmp) GetOrSetMarkdown(key string, generator func() (str
511508
512509func NewPermissionDialogCmp() PermissionDialogCmp {
513510 // Create viewport for content
514− contentViewport := viewport.New(0, 0)
511+ contentViewport := viewport.New()
515512
516513 return &permissionDialogCmp{
517514 contentViewPort: contentViewport,
internal/tui/components/dialog/quit.go+5−5
@@ -3,9 +3,9 @@ package dialog
33import (
44 "strings"
55
6− "github.com/charmbracelet/bubbles/key"
7− tea "github.com/charmbracelet/bubbletea"
8− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/bubbles/v2/key"
7+ tea "github.com/charmbracelet/bubbletea/v2"
8+ "github.com/charmbracelet/lipgloss/v2"
99 "github.com/opencode-ai/opencode/internal/tui/layout"
1010 "github.com/opencode-ai/opencode/internal/tui/styles"
1111 "github.com/opencode-ai/opencode/internal/tui/theme"
@@ -17,7 +17,7 @@ const question = "Are you sure you want to quit?"
1717type CloseQuitMsg struct{}
1818
1919type QuitDialog interface {
20− tea.Model
20+ util.Model
2121 layout.Bindings
2222}
2323
@@ -84,7 +84,7 @@ func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
8484func (q *quitDialogCmp) View() string {
8585 t := theme.CurrentTheme()
8686 baseStyle := styles.BaseStyle()
87−
87+
8888 yesStyle := baseStyle
8989 noStyle := baseStyle
9090 spacerStyle := baseStyle.Background(t.Background())
internal/tui/components/dialog/session.go+5−6
@@ -1,9 +1,9 @@
11package dialog
22
33import (
4− "github.com/charmbracelet/bubbles/key"
5− tea "github.com/charmbracelet/bubbletea"
6− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/bubbles/v2/key"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6+ "github.com/charmbracelet/lipgloss/v2"
77 "github.com/opencode-ai/opencode/internal/session"
88 "github.com/opencode-ai/opencode/internal/tui/layout"
99 "github.com/opencode-ai/opencode/internal/tui/styles"
@@ -21,7 +21,7 @@ type CloseSessionDialogMsg struct{}
2121
2222// SessionDialog interface for the session switching dialog
2323type SessionDialog interface {
24− tea.Model
24+ util.Model
2525 layout.Bindings
2626 SetSessions(sessions []session.Session)
2727 SetSelectedSession(sessionID string)
@@ -108,7 +108,7 @@ func (s *sessionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
108108func (s *sessionDialogCmp) View() string {
109109 t := theme.CurrentTheme()
110110 baseStyle := styles.BaseStyle()
111−
111+
112112 if len(s.sessions) == 0 {
113113 return baseStyle.Padding(1, 2).
114114 Border(lipgloss.RoundedBorder()).
@@ -181,7 +181,6 @@ func (s *sessionDialogCmp) View() string {
181181 Border(lipgloss.RoundedBorder()).
182182 BorderBackground(t.Background()).
183183 BorderForeground(t.TextMuted()).
184− Width(lipgloss.Width(content) + 4).
185184 Render(content)
186185}
187186
internal/tui/components/dialog/theme.go+4−5
@@ -1,9 +1,9 @@
11package dialog
22
33import (
4− "github.com/charmbracelet/bubbles/key"
5− tea "github.com/charmbracelet/bubbletea"
6− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/bubbles/v2/key"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6+ "github.com/charmbracelet/lipgloss/v2"
77 "github.com/opencode-ai/opencode/internal/tui/layout"
88 "github.com/opencode-ai/opencode/internal/tui/styles"
99 "github.com/opencode-ai/opencode/internal/tui/theme"
@@ -20,7 +20,7 @@ type CloseThemeDialogMsg struct{}
2020
2121// ThemeDialog interface for the theme switching dialog
2222type ThemeDialog interface {
23− tea.Model
23+ util.Model
2424 layout.Bindings
2525}
2626
@@ -195,4 +195,3 @@ func NewThemeDialogCmp() ThemeDialog {
195195 currentTheme: "",
196196 }
197197}
198−
internal/tui/components/logs/details.go+11−12
@@ -5,18 +5,18 @@ import (
55 "strings"
66 "time"
77
8− "github.com/charmbracelet/bubbles/key"
9− "github.com/charmbracelet/bubbles/viewport"
10− tea "github.com/charmbracelet/bubbletea"
11− "github.com/charmbracelet/lipgloss"
8+ "github.com/charmbracelet/bubbles/v2/key"
9+ "github.com/charmbracelet/bubbles/v2/viewport"
10+ tea "github.com/charmbracelet/bubbletea/v2"
11+ "github.com/charmbracelet/lipgloss/v2"
1212 "github.com/opencode-ai/opencode/internal/logging"
1313 "github.com/opencode-ai/opencode/internal/tui/layout"
14− "github.com/opencode-ai/opencode/internal/tui/styles"
1514 "github.com/opencode-ai/opencode/internal/tui/theme"
15+ "github.com/opencode-ai/opencode/internal/tui/util"
1616)
1717
1818type DetailComponent interface {
19− tea.Model
19+ util.Model
2020 layout.Sizeable
2121 layout.Bindings
2222}
@@ -99,7 +99,7 @@ func (i *detailCmp) updateContent() {
9999func getLevelStyle(level string) lipgloss.Style {
100100 style := lipgloss.NewStyle().Bold(true)
101101 t := theme.CurrentTheme()
102−
102+
103103 switch strings.ToLower(level) {
104104 case "info":
105105 return style.Foreground(t.Info())
@@ -115,8 +115,7 @@ func getLevelStyle(level string) lipgloss.Style {
115115}
116116
117117func (i *detailCmp) View() string {
118− t := theme.CurrentTheme()
119− return styles.ForceReplaceBackgroundWithLipgloss(i.viewport.View(), t.Background())
118+ return i.viewport.View()
120119}
121120
122121func (i *detailCmp) GetSize() (int, int) {
@@ -126,8 +125,8 @@ func (i *detailCmp) GetSize() (int, int) {
126125func (i *detailCmp) SetSize(width int, height int) tea.Cmd {
127126 i.width = width
128127 i.height = height
129− i.viewport.Width = i.width
130− i.viewport.Height = i.height
128+ i.viewport.SetWidth(i.width)
129+ i.viewport.SetHeight(i.height)
131130 i.updateContent()
132131 return nil
133132}
@@ -138,6 +137,6 @@ func (i *detailCmp) BindingKeys() []key.Binding {
138137
139138func NewLogsDetails() DetailComponent {
140139 return &detailCmp{
141− viewport: viewport.New(0, 0),
140+ viewport: viewport.New(),
142141 }
143142}
internal/tui/components/logs/table.go+5−6
@@ -4,19 +4,18 @@ import (
44 "encoding/json"
55 "slices"
66
7− "github.com/charmbracelet/bubbles/key"
8− "github.com/charmbracelet/bubbles/table"
9− tea "github.com/charmbracelet/bubbletea"
7+ "github.com/charmbracelet/bubbles/v2/key"
8+ "github.com/charmbracelet/bubbles/v2/table"
9+ tea "github.com/charmbracelet/bubbletea/v2"
1010 "github.com/opencode-ai/opencode/internal/logging"
1111 "github.com/opencode-ai/opencode/internal/pubsub"
1212 "github.com/opencode-ai/opencode/internal/tui/layout"
13− "github.com/opencode-ai/opencode/internal/tui/styles"
1413 "github.com/opencode-ai/opencode/internal/tui/theme"
1514 "github.com/opencode-ai/opencode/internal/tui/util"
1615)
1716
1817type TableComponent interface {
19− tea.Model
18+ util.Model
2019 layout.Sizeable
2120 layout.Bindings
2221}
@@ -66,7 +65,7 @@ func (i *tableCmp) View() string {
6665 defaultStyles := table.DefaultStyles()
6766 defaultStyles.Selected = defaultStyles.Selected.Foreground(t.Primary())
6867 i.table.SetStyles(defaultStyles)
69− return styles.ForceReplaceBackgroundWithLipgloss(i.table.View(), t.Background())
68+ return i.table.View()
7069}
7170
7271func (i *tableCmp) GetSize() (int, int) {
internal/tui/components/util/simple-list.go+5−4
@@ -1,12 +1,13 @@
11package utilComponents
22
33import (
4− "github.com/charmbracelet/bubbles/key"
5− tea "github.com/charmbracelet/bubbletea"
6− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/bubbles/v2/key"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6+ "github.com/charmbracelet/lipgloss/v2"
77 "github.com/opencode-ai/opencode/internal/tui/layout"
88 "github.com/opencode-ai/opencode/internal/tui/styles"
99 "github.com/opencode-ai/opencode/internal/tui/theme"
10+ "github.com/opencode-ai/opencode/internal/tui/util"
1011)
1112
1213type SimpleListItem interface {
@@ -14,7 +15,7 @@ type SimpleListItem interface {
1415}
1516
1617type SimpleList[T SimpleListItem] interface {
17− tea.Model
18+ util.Model
1819 layout.Bindings
1920 SetMaxWidth(maxWidth int)
2021 GetSelectedItem() (item T, idx int)
internal/tui/image/images.go+3−2
@@ -3,10 +3,11 @@ package image
33import (
44 "fmt"
55 "image"
6+ "image/color"
67 "os"
78 "strings"
89
9− "github.com/charmbracelet/lipgloss"
10+ "github.com/charmbracelet/lipgloss/v2"
1011 "github.com/disintegration/imaging"
1112 "github.com/lucasb-eyer/go-colorful"
1213)
@@ -36,7 +37,7 @@ func ToString(width int, img image.Image) string {
3637 c1, _ := colorful.MakeColor(img.At(x, heightCounter))
3738 color1 := lipgloss.Color(c1.Hex())
3839
39− var color2 lipgloss.Color
40+ var color2 color.Color
4041 if heightCounter+1 < h {
4142 c2, _ := colorful.MakeColor(img.At(x, heightCounter+1))
4243 color2 = lipgloss.Color(c2.Hex())
internal/tui/layout/container.go+8−8
@@ -1,14 +1,15 @@
11package layout
22
33import (
4− "github.com/charmbracelet/bubbles/key"
5− tea "github.com/charmbracelet/bubbletea"
6− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/bubbles/v2/key"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6+ "github.com/charmbracelet/lipgloss/v2"
77 "github.com/opencode-ai/opencode/internal/tui/theme"
8+ "github.com/opencode-ai/opencode/internal/tui/util"
89)
910
1011type Container interface {
11− tea.Model
12+ util.Model
1213 Sizeable
1314 Bindings
1415}
@@ -16,7 +17,7 @@ type container struct {
1617 width int
1718 height int
1819
19− content tea.Model
20+ content util.Model
2021
2122 // Style options
2223 paddingTop int
@@ -37,7 +38,7 @@ func (c *container) Init() tea.Cmd {
3738
3839func (c *container) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
3940 u, cmd := c.content.Update(msg)
40− c.content = u
41+ c.content = u.(util.Model)
4142 return c, cmd
4243}
4344
@@ -123,8 +124,7 @@ func (c *container) BindingKeys() []key.Binding {
123124
124125type ContainerOption func(*container)
125126
126−func NewContainer(content tea.Model, options ...ContainerOption) Container {
127−
127+func NewContainer(content util.Model, options ...ContainerOption) Container {
128128 c := &container{
129129 content: content,
130130 borderStyle: lipgloss.NormalBorder(),
internal/tui/layout/layout.go+2−2
@@ -3,8 +3,8 @@ package layout
33import (
44 "reflect"
55
6− "github.com/charmbracelet/bubbles/key"
7− tea "github.com/charmbracelet/bubbletea"
6+ "github.com/charmbracelet/bubbles/v2/key"
7+ tea "github.com/charmbracelet/bubbletea/v2"
88)
99
1010type Focusable interface {
internal/tui/layout/overlay.go+2−2
@@ -3,7 +3,7 @@ package layout
33import (
44 "strings"
55
6− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
77 chAnsi "github.com/charmbracelet/x/ansi"
88 "github.com/muesli/ansi"
99 "github.com/muesli/reflow/truncate"
@@ -14,7 +14,7 @@ import (
1414)
1515
1616// Most of this code is borrowed from
17−// https://github.com/charmbracelet/lipgloss/pull/102
17+// https://github.com/charmbracelet/lipgloss/v2/pull/102
1818// as well as the lipgloss library, with some modification for what I needed.
1919
2020// Split a string into lines, additionally returning the size of the widest
internal/tui/layout/split.go+5−5
@@ -1,14 +1,15 @@
11package layout
22
33import (
4− "github.com/charmbracelet/bubbles/key"
5− tea "github.com/charmbracelet/bubbletea"
6− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/bubbles/v2/key"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6+ "github.com/charmbracelet/lipgloss/v2"
77 "github.com/opencode-ai/opencode/internal/tui/theme"
8+ "github.com/opencode-ai/opencode/internal/tui/util"
89)
910
1011type SplitPaneLayout interface {
11− tea.Model
12+ util.Model
1213 Sizeable
1314 Bindings
1415 SetLeftPanel(panel Container) tea.Cmd
@@ -241,7 +242,6 @@ func (s *splitPaneLayout) BindingKeys() []key.Binding {
241242}
242243
243244func NewSplitPane(options ...SplitPaneOption) SplitPaneLayout {
244−
245245 layout := &splitPaneLayout{
246246 ratio: 0.7,
247247 verticalRatio: 0.9, // Default 90% for top section, 10% for bottom
internal/tui/page/chat.go+6−6
@@ -4,9 +4,9 @@ import (
44 "context"
55 "strings"
66
7− "github.com/charmbracelet/bubbles/key"
8− tea "github.com/charmbracelet/bubbletea"
9− "github.com/charmbracelet/lipgloss"
7+ "github.com/charmbracelet/bubbles/v2/key"
8+ tea "github.com/charmbracelet/bubbletea/v2"
9+ "github.com/charmbracelet/lipgloss/v2"
1010 "github.com/opencode-ai/opencode/internal/app"
1111 "github.com/opencode-ai/opencode/internal/completions"
1212 "github.com/opencode-ai/opencode/internal/message"
@@ -76,7 +76,7 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
7676 if p.app.CoderAgent.IsBusy() {
7777 return p, util.ReportWarn("Agent is busy, please wait before executing a command...")
7878 }
79−
79+
8080 // Process the command content with arguments if any
8181 content := msg.Content
8282 if msg.Args != nil {
@@ -86,7 +86,7 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
8686 content = strings.ReplaceAll(content, placeholder, value)
8787 }
8888 }
89−
89+
9090 // Handle custom command execution
9191 cmd := p.sendMessage(content, nil)
9292 if cmd != nil {
@@ -212,7 +212,7 @@ func (p *chatPage) BindingKeys() []key.Binding {
212212 return bindings
213213}
214214
215−func NewChatPage(app *app.App) tea.Model {
215+func NewChatPage(app *app.App) util.Model {
216216 cg := completions.NewFileAndFolderContextGroup()
217217 completionDialog := dialog.NewCompletionDialogCmp(cg)
218218
internal/tui/page/logs.go+5−4
@@ -1,18 +1,19 @@
11package page
22
33import (
4− "github.com/charmbracelet/bubbles/key"
5− tea "github.com/charmbracelet/bubbletea"
6− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/bubbles/v2/key"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6+ "github.com/charmbracelet/lipgloss/v2"
77 "github.com/opencode-ai/opencode/internal/tui/components/logs"
88 "github.com/opencode-ai/opencode/internal/tui/layout"
99 "github.com/opencode-ai/opencode/internal/tui/styles"
10+ "github.com/opencode-ai/opencode/internal/tui/util"
1011)
1112
1213var LogsPage PageID = "logs"
1314
1415type LogPage interface {
15− tea.Model
16+ util.Model
1617 layout.Sizeable
1718 layout.Bindings
1819}
internal/tui/styles/background.godeleted−123
@@ -1,123 +0,0 @@
1−package styles
2−
3−import (
4− "fmt"
5− "regexp"
6− "strings"
7−
8− "github.com/charmbracelet/lipgloss"
9−)
10−
11−var ansiEscape = regexp.MustCompile("\x1b\\[[0-9;]*m")
12−
13−func getColorRGB(c lipgloss.TerminalColor) (uint8, uint8, uint8) {
14− r, g, b, a := c.RGBA()
15−
16− // Un-premultiply alpha if needed
17− if a > 0 && a < 0xffff {
18− r = (r * 0xffff) / a
19− g = (g * 0xffff) / a
20− b = (b * 0xffff) / a
21− }
22−
23− // Convert from 16-bit to 8-bit color
24− return uint8(r >> 8), uint8(g >> 8), uint8(b >> 8)
25−}
26−
27−// ForceReplaceBackgroundWithLipgloss replaces any ANSI background color codes
28−// in `input` with a single 24‑bit background (48;2;R;G;B).
29−func ForceReplaceBackgroundWithLipgloss(input string, newBgColor lipgloss.TerminalColor) string {
30− // Precompute our new-bg sequence once
31− r, g, b := getColorRGB(newBgColor)
32− newBg := fmt.Sprintf("48;2;%d;%d;%d", r, g, b)
33−
34− return ansiEscape.ReplaceAllStringFunc(input, func(seq string) string {
35− const (
36− escPrefixLen = 2 // "\x1b["
37− escSuffixLen = 1 // "m"
38− )
39−
40− raw := seq
41− start := escPrefixLen
42− end := len(raw) - escSuffixLen
43−
44− var sb strings.Builder
45− // reserve enough space: original content minus bg codes + our newBg
46− sb.Grow((end - start) + len(newBg) + 2)
47−
48− // scan from start..end, token by token
49− for i := start; i < end; {
50− // find the next ';' or end
51− j := i
52− for j < end && raw[j] != ';' {
53− j++
54− }
55− token := raw[i:j]
56−
57− // fast‑path: skip "48;5;N" or "48;2;R;G;B"
58− if len(token) == 2 && token[0] == '4' && token[1] == '8' {
59− k := j + 1
60− if k < end {
61− // find next token
62− l := k
63− for l < end && raw[l] != ';' {
64− l++
65− }
66− next := raw[k:l]
67− if next == "5" {
68− // skip "48;5;N"
69− m := l + 1
70− for m < end && raw[m] != ';' {
71− m++
72− }
73− i = m + 1
74− continue
75− } else if next == "2" {
76− // skip "48;2;R;G;B"
77− m := l + 1
78− for count := 0; count < 3 && m < end; count++ {
79− for m < end && raw[m] != ';' {
80− m++
81− }
82− m++
83− }
84− i = m
85− continue
86− }
87− }
88− }
89−
90− // decide whether to keep this token
91− // manually parse ASCII digits to int
92− isNum := true
93− val := 0
94− for p := i; p < j; p++ {
95− c := raw[p]
96− if c < '0' || c > '9' {
97− isNum = false
98− break
99− }
100− val = val*10 + int(c-'0')
101− }
102− keep := !isNum ||
103− ((val < 40 || val > 47) && (val < 100 || val > 107) && val != 49)
104−
105− if keep {
106− if sb.Len() > 0 {
107− sb.WriteByte(';')
108− }
109− sb.WriteString(token)
110− }
111− // advance past this token (and the semicolon)
112− i = j + 1
113− }
114−
115− // append our new background
116− if sb.Len() > 0 {
117− sb.WriteByte(';')
118− }
119− sb.WriteString(newBg)
120−
121− return "\x1b[" + sb.String() + "m"
122− })
123−}
internal/tui/styles/markdown.go+59−61
@@ -1,9 +1,11 @@
11package styles
22
33import (
4− "github.com/charmbracelet/glamour"
5− "github.com/charmbracelet/glamour/ansi"
6− "github.com/charmbracelet/lipgloss"
4+ "fmt"
5+ "image/color"
6+
7+ "github.com/charmbracelet/glamour/v2"
8+ "github.com/charmbracelet/glamour/v2/ansi"
79 "github.com/opencode-ai/opencode/internal/tui/theme"
810)
911
@@ -33,13 +35,13 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
3335 StylePrimitive: ansi.StylePrimitive{
3436 BlockPrefix: "",
3537 BlockSuffix: "",
36− Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
38+ Color: stringPtr(colorToString(t.MarkdownText())),
3739 },
3840 Margin: uintPtr(defaultMargin),
3941 },
4042 BlockQuote: ansi.StyleBlock{
4143 StylePrimitive: ansi.StylePrimitive{
42− Color: stringPtr(adaptiveColorToString(t.MarkdownBlockQuote())),
44+ Color: stringPtr(colorToString(t.MarkdownBlockQuote())),
4345 Italic: boolPtr(true),
4446 Prefix: "┃ ",
4547 },
@@ -51,82 +53,82 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
5153 StyleBlock: ansi.StyleBlock{
5254 IndentToken: stringPtr(BaseStyle().Render(" ")),
5355 StylePrimitive: ansi.StylePrimitive{
54− Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
56+ Color: stringPtr(colorToString(t.MarkdownText())),
5557 },
5658 },
5759 },
5860 Heading: ansi.StyleBlock{
5961 StylePrimitive: ansi.StylePrimitive{
6062 BlockSuffix: "\n",
61− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
63+ Color: stringPtr(colorToString(t.MarkdownHeading())),
6264 Bold: boolPtr(true),
6365 },
6466 },
6567 H1: ansi.StyleBlock{
6668 StylePrimitive: ansi.StylePrimitive{
6769 Prefix: "# ",
68− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
70+ Color: stringPtr(colorToString(t.MarkdownHeading())),
6971 Bold: boolPtr(true),
7072 },
7173 },
7274 H2: ansi.StyleBlock{
7375 StylePrimitive: ansi.StylePrimitive{
7476 Prefix: "## ",
75− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
77+ Color: stringPtr(colorToString(t.MarkdownHeading())),
7678 Bold: boolPtr(true),
7779 },
7880 },
7981 H3: ansi.StyleBlock{
8082 StylePrimitive: ansi.StylePrimitive{
8183 Prefix: "### ",
82− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
84+ Color: stringPtr(colorToString(t.MarkdownHeading())),
8385 Bold: boolPtr(true),
8486 },
8587 },
8688 H4: ansi.StyleBlock{
8789 StylePrimitive: ansi.StylePrimitive{
8890 Prefix: "#### ",
89− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
91+ Color: stringPtr(colorToString(t.MarkdownHeading())),
9092 Bold: boolPtr(true),
9193 },
9294 },
9395 H5: ansi.StyleBlock{
9496 StylePrimitive: ansi.StylePrimitive{
9597 Prefix: "##### ",
96− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
98+ Color: stringPtr(colorToString(t.MarkdownHeading())),
9799 Bold: boolPtr(true),
98100 },
99101 },
100102 H6: ansi.StyleBlock{
101103 StylePrimitive: ansi.StylePrimitive{
102104 Prefix: "###### ",
103− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
105+ Color: stringPtr(colorToString(t.MarkdownHeading())),
104106 Bold: boolPtr(true),
105107 },
106108 },
107109 Strikethrough: ansi.StylePrimitive{
108110 CrossedOut: boolPtr(true),
109− Color: stringPtr(adaptiveColorToString(t.TextMuted())),
111+ Color: stringPtr(colorToString(t.TextMuted())),
110112 },
111113 Emph: ansi.StylePrimitive{
112− Color: stringPtr(adaptiveColorToString(t.MarkdownEmph())),
114+ Color: stringPtr(colorToString(t.MarkdownEmph())),
113115 Italic: boolPtr(true),
114116 },
115117 Strong: ansi.StylePrimitive{
116118 Bold: boolPtr(true),
117− Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
119+ Color: stringPtr(colorToString(t.MarkdownStrong())),
118120 },
119121 HorizontalRule: ansi.StylePrimitive{
120− Color: stringPtr(adaptiveColorToString(t.MarkdownHorizontalRule())),
122+ Color: stringPtr(colorToString(t.MarkdownHorizontalRule())),
121123 Format: "\n─────────────────────────────────────────\n",
122124 },
123125 Item: ansi.StylePrimitive{
124126 BlockPrefix: "• ",
125− Color: stringPtr(adaptiveColorToString(t.MarkdownListItem())),
127+ Color: stringPtr(colorToString(t.MarkdownListItem())),
126128 },
127129 Enumeration: ansi.StylePrimitive{
128130 BlockPrefix: ". ",
129− Color: stringPtr(adaptiveColorToString(t.MarkdownListEnumeration())),
131+ Color: stringPtr(colorToString(t.MarkdownListEnumeration())),
130132 },
131133 Task: ansi.StyleTask{
132134 StylePrimitive: ansi.StylePrimitive{},
@@ -134,25 +136,25 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
134136 Unticked: "[ ] ",
135137 },
136138 Link: ansi.StylePrimitive{
137− Color: stringPtr(adaptiveColorToString(t.MarkdownLink())),
139+ Color: stringPtr(colorToString(t.MarkdownLink())),
138140 Underline: boolPtr(true),
139141 },
140142 LinkText: ansi.StylePrimitive{
141− Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
143+ Color: stringPtr(colorToString(t.MarkdownLinkText())),
142144 Bold: boolPtr(true),
143145 },
144146 Image: ansi.StylePrimitive{
145− Color: stringPtr(adaptiveColorToString(t.MarkdownImage())),
147+ Color: stringPtr(colorToString(t.MarkdownImage())),
146148 Underline: boolPtr(true),
147149 Format: "🖼 {{.text}}",
148150 },
149151 ImageText: ansi.StylePrimitive{
150− Color: stringPtr(adaptiveColorToString(t.MarkdownImageText())),
152+ Color: stringPtr(colorToString(t.MarkdownImageText())),
151153 Format: "{{.text}}",
152154 },
153155 Code: ansi.StyleBlock{
154156 StylePrimitive: ansi.StylePrimitive{
155− Color: stringPtr(adaptiveColorToString(t.MarkdownCode())),
157+ Color: stringPtr(colorToString(t.MarkdownCode())),
156158 Prefix: "",
157159 Suffix: "",
158160 },
@@ -161,90 +163,90 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
161163 StyleBlock: ansi.StyleBlock{
162164 StylePrimitive: ansi.StylePrimitive{
163165 Prefix: " ",
164− Color: stringPtr(adaptiveColorToString(t.MarkdownCodeBlock())),
166+ Color: stringPtr(colorToString(t.MarkdownCodeBlock())),
165167 },
166168 Margin: uintPtr(defaultMargin),
167169 },
168170 Chroma: &ansi.Chroma{
169171 Text: ansi.StylePrimitive{
170− Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
172+ Color: stringPtr(colorToString(t.MarkdownText())),
171173 },
172174 Error: ansi.StylePrimitive{
173− Color: stringPtr(adaptiveColorToString(t.Error())),
175+ Color: stringPtr(colorToString(t.Error())),
174176 },
175177 Comment: ansi.StylePrimitive{
176− Color: stringPtr(adaptiveColorToString(t.SyntaxComment())),
178+ Color: stringPtr(colorToString(t.SyntaxComment())),
177179 },
178180 CommentPreproc: ansi.StylePrimitive{
179− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
181+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
180182 },
181183 Keyword: ansi.StylePrimitive{
182− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
184+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
183185 },
184186 KeywordReserved: ansi.StylePrimitive{
185− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
187+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
186188 },
187189 KeywordNamespace: ansi.StylePrimitive{
188− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
190+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
189191 },
190192 KeywordType: ansi.StylePrimitive{
191− Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
193+ Color: stringPtr(colorToString(t.SyntaxType())),
192194 },
193195 Operator: ansi.StylePrimitive{
194− Color: stringPtr(adaptiveColorToString(t.SyntaxOperator())),
196+ Color: stringPtr(colorToString(t.SyntaxOperator())),
195197 },
196198 Punctuation: ansi.StylePrimitive{
197− Color: stringPtr(adaptiveColorToString(t.SyntaxPunctuation())),
199+ Color: stringPtr(colorToString(t.SyntaxPunctuation())),
198200 },
199201 Name: ansi.StylePrimitive{
200− Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
202+ Color: stringPtr(colorToString(t.SyntaxVariable())),
201203 },
202204 NameBuiltin: ansi.StylePrimitive{
203− Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
205+ Color: stringPtr(colorToString(t.SyntaxVariable())),
204206 },
205207 NameTag: ansi.StylePrimitive{
206− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
208+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
207209 },
208210 NameAttribute: ansi.StylePrimitive{
209− Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
211+ Color: stringPtr(colorToString(t.SyntaxFunction())),
210212 },
211213 NameClass: ansi.StylePrimitive{
212− Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
214+ Color: stringPtr(colorToString(t.SyntaxType())),
213215 },
214216 NameConstant: ansi.StylePrimitive{
215− Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
217+ Color: stringPtr(colorToString(t.SyntaxVariable())),
216218 },
217219 NameDecorator: ansi.StylePrimitive{
218− Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
220+ Color: stringPtr(colorToString(t.SyntaxFunction())),
219221 },
220222 NameFunction: ansi.StylePrimitive{
221− Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
223+ Color: stringPtr(colorToString(t.SyntaxFunction())),
222224 },
223225 LiteralNumber: ansi.StylePrimitive{
224− Color: stringPtr(adaptiveColorToString(t.SyntaxNumber())),
226+ Color: stringPtr(colorToString(t.SyntaxNumber())),
225227 },
226228 LiteralString: ansi.StylePrimitive{
227− Color: stringPtr(adaptiveColorToString(t.SyntaxString())),
229+ Color: stringPtr(colorToString(t.SyntaxString())),
228230 },
229231 LiteralStringEscape: ansi.StylePrimitive{
230− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
232+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
231233 },
232234 GenericDeleted: ansi.StylePrimitive{
233− Color: stringPtr(adaptiveColorToString(t.DiffRemoved())),
235+ Color: stringPtr(colorToString(t.DiffRemoved())),
234236 },
235237 GenericEmph: ansi.StylePrimitive{
236− Color: stringPtr(adaptiveColorToString(t.MarkdownEmph())),
238+ Color: stringPtr(colorToString(t.MarkdownEmph())),
237239 Italic: boolPtr(true),
238240 },
239241 GenericInserted: ansi.StylePrimitive{
240− Color: stringPtr(adaptiveColorToString(t.DiffAdded())),
242+ Color: stringPtr(colorToString(t.DiffAdded())),
241243 },
242244 GenericStrong: ansi.StylePrimitive{
243− Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
245+ Color: stringPtr(colorToString(t.MarkdownStrong())),
244246 Bold: boolPtr(true),
245247 },
246248 GenericSubheading: ansi.StylePrimitive{
247− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
249+ Color: stringPtr(colorToString(t.MarkdownHeading())),
248250 },
249251 },
250252 },
@@ -261,24 +263,20 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
261263 },
262264 DefinitionDescription: ansi.StylePrimitive{
263265 BlockPrefix: "\n ❯ ",
264− Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
266+ Color: stringPtr(colorToString(t.MarkdownLinkText())),
265267 },
266268 Text: ansi.StylePrimitive{
267− Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
269+ Color: stringPtr(colorToString(t.MarkdownText())),
268270 },
269271 Paragraph: ansi.StyleBlock{
270272 StylePrimitive: ansi.StylePrimitive{
271− Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
273+ Color: stringPtr(colorToString(t.MarkdownText())),
272274 },
273275 },
274276 }
275277}
276278
277−// adaptiveColorToString converts a lipgloss.AdaptiveColor to the appropriate
278−// hex color string based on the current terminal background
279−func adaptiveColorToString(color lipgloss.AdaptiveColor) string {
280− if lipgloss.HasDarkBackground() {
281− return color.Dark
282− }
283− return color.Light
279+func colorToString(c color.Color) string {
280+ rgba := color.RGBAModel.Convert(c).(color.RGBA)
281+ return fmt.Sprintf("#%02x%02x%02x", rgba.R, rgba.G, rgba.B)
284282}
internal/tui/styles/styles.go+20−20
@@ -1,13 +1,13 @@
11package styles
22
33import (
4− "github.com/charmbracelet/lipgloss"
4+ "image/color"
5+
6+ "github.com/charmbracelet/lipgloss/v2"
57 "github.com/opencode-ai/opencode/internal/tui/theme"
68)
79
8−var (
9− ImageBakcground = "#212121"
10−)
10+var ImageBakcground = "#212121"
1111
1212// Style generation functions that use the current theme
1313
@@ -75,81 +75,81 @@ func DimBorder() lipgloss.Style {
7575}
7676
7777// PrimaryColor returns the primary color from the current theme
78−func PrimaryColor() lipgloss.AdaptiveColor {
78+func PrimaryColor() color.Color {
7979 return theme.CurrentTheme().Primary()
8080}
8181
8282// SecondaryColor returns the secondary color from the current theme
83−func SecondaryColor() lipgloss.AdaptiveColor {
83+func SecondaryColor() color.Color {
8484 return theme.CurrentTheme().Secondary()
8585}
8686
8787// AccentColor returns the accent color from the current theme
88−func AccentColor() lipgloss.AdaptiveColor {
88+func AccentColor() color.Color {
8989 return theme.CurrentTheme().Accent()
9090}
9191
9292// ErrorColor returns the error color from the current theme
93−func ErrorColor() lipgloss.AdaptiveColor {
93+func ErrorColor() color.Color {
9494 return theme.CurrentTheme().Error()
9595}
9696
9797// WarningColor returns the warning color from the current theme
98−func WarningColor() lipgloss.AdaptiveColor {
98+func WarningColor() color.Color {
9999 return theme.CurrentTheme().Warning()
100100}
101101
102102// SuccessColor returns the success color from the current theme
103−func SuccessColor() lipgloss.AdaptiveColor {
103+func SuccessColor() color.Color {
104104 return theme.CurrentTheme().Success()
105105}
106106
107107// InfoColor returns the info color from the current theme
108−func InfoColor() lipgloss.AdaptiveColor {
108+func InfoColor() color.Color {
109109 return theme.CurrentTheme().Info()
110110}
111111
112112// TextColor returns the text color from the current theme
113−func TextColor() lipgloss.AdaptiveColor {
113+func TextColor() color.Color {
114114 return theme.CurrentTheme().Text()
115115}
116116
117117// TextMutedColor returns the muted text color from the current theme
118−func TextMutedColor() lipgloss.AdaptiveColor {
118+func TextMutedColor() color.Color {
119119 return theme.CurrentTheme().TextMuted()
120120}
121121
122122// TextEmphasizedColor returns the emphasized text color from the current theme
123−func TextEmphasizedColor() lipgloss.AdaptiveColor {
123+func TextEmphasizedColor() color.Color {
124124 return theme.CurrentTheme().TextEmphasized()
125125}
126126
127127// BackgroundColor returns the background color from the current theme
128−func BackgroundColor() lipgloss.AdaptiveColor {
128+func BackgroundColor() color.Color {
129129 return theme.CurrentTheme().Background()
130130}
131131
132132// BackgroundSecondaryColor returns the secondary background color from the current theme
133−func BackgroundSecondaryColor() lipgloss.AdaptiveColor {
133+func BackgroundSecondaryColor() color.Color {
134134 return theme.CurrentTheme().BackgroundSecondary()
135135}
136136
137137// BackgroundDarkerColor returns the darker background color from the current theme
138−func BackgroundDarkerColor() lipgloss.AdaptiveColor {
138+func BackgroundDarkerColor() color.Color {
139139 return theme.CurrentTheme().BackgroundDarker()
140140}
141141
142142// BorderNormalColor returns the normal border color from the current theme
143−func BorderNormalColor() lipgloss.AdaptiveColor {
143+func BorderNormalColor() color.Color {
144144 return theme.CurrentTheme().BorderNormal()
145145}
146146
147147// BorderFocusedColor returns the focused border color from the current theme
148−func BorderFocusedColor() lipgloss.AdaptiveColor {
148+func BorderFocusedColor() color.Color {
149149 return theme.CurrentTheme().BorderFocused()
150150}
151151
152152// BorderDimColor returns the dim border color from the current theme
153−func BorderDimColor() lipgloss.AdaptiveColor {
153+func BorderDimColor() color.Color {
154154 return theme.CurrentTheme().BorderDim()
155155}
internal/tui/theme/catppuccin.go+135−211
@@ -2,7 +2,7 @@ package theme
22
33import (
44 catppuccin "github.com/catppuccin/go"
5− "github.com/charmbracelet/lipgloss"
5+ "github.com/charmbracelet/lipgloss/v2"
66)
77
88// CatppuccinTheme implements the Theme interface with Catppuccin colors.
@@ -11,238 +11,162 @@ type CatppuccinTheme struct {
1111 BaseTheme
1212}
1313
14−// NewCatppuccinTheme creates a new instance of the Catppuccin theme.
15−func NewCatppuccinTheme() *CatppuccinTheme {
16− // Get the Catppuccin palettes
14+// NewCatppuccinMochaTheme creates a new instance of the Catppuccin Mocha theme.
15+func NewCatppuccinMochaTheme() *CatppuccinTheme {
16+ // Get the Catppuccin palette
1717 mocha := catppuccin.Mocha
18+
19+ theme := &CatppuccinTheme{}
20+
21+ // Base colors
22+ theme.PrimaryColor = lipgloss.Color(mocha.Blue().Hex)
23+ theme.SecondaryColor = lipgloss.Color(mocha.Mauve().Hex)
24+ theme.AccentColor = lipgloss.Color(mocha.Peach().Hex)
25+
26+ // Status colors
27+ theme.ErrorColor = lipgloss.Color(mocha.Red().Hex)
28+ theme.WarningColor = lipgloss.Color(mocha.Peach().Hex)
29+ theme.SuccessColor = lipgloss.Color(mocha.Green().Hex)
30+ theme.InfoColor = lipgloss.Color(mocha.Blue().Hex)
31+
32+ // Text colors
33+ theme.TextColor = lipgloss.Color(mocha.Text().Hex)
34+ theme.TextMutedColor = lipgloss.Color(mocha.Subtext0().Hex)
35+ theme.TextEmphasizedColor = lipgloss.Color(mocha.Lavender().Hex)
36+
37+ // Background colors
38+ theme.BackgroundColor = lipgloss.Color("#212121") // From existing styles
39+ theme.BackgroundSecondaryColor = lipgloss.Color("#2c2c2c") // From existing styles
40+ theme.BackgroundDarkerColor = lipgloss.Color("#181818") // From existing styles
41+
42+ // Border colors
43+ theme.BorderNormalColor = lipgloss.Color("#4b4c5c") // From existing styles
44+ theme.BorderFocusedColor = lipgloss.Color(mocha.Blue().Hex)
45+ theme.BorderDimColor = lipgloss.Color(mocha.Surface0().Hex)
46+
47+ // Diff view colors
48+ theme.DiffAddedColor = lipgloss.Color("#478247") // From existing diff.go
49+ theme.DiffRemovedColor = lipgloss.Color("#7C4444") // From existing diff.go
50+ theme.DiffContextColor = lipgloss.Color("#a0a0a0") // From existing diff.go
51+ theme.DiffHunkHeaderColor = lipgloss.Color("#a0a0a0") // From existing diff.go
52+ theme.DiffHighlightAddedColor = lipgloss.Color("#DAFADA") // From existing diff.go
53+ theme.DiffHighlightRemovedColor = lipgloss.Color("#FADADD") // From existing diff.go
54+ theme.DiffAddedBgColor = lipgloss.Color("#303A30") // From existing diff.go
55+ theme.DiffRemovedBgColor = lipgloss.Color("#3A3030") // From existing diff.go
56+ theme.DiffContextBgColor = lipgloss.Color("#212121") // From existing diff.go
57+ theme.DiffLineNumberColor = lipgloss.Color("#888888") // From existing diff.go
58+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#293229") // From existing diff.go
59+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#332929") // From existing diff.go
60+
61+ // Markdown colors
62+ theme.MarkdownTextColor = lipgloss.Color(mocha.Text().Hex)
63+ theme.MarkdownHeadingColor = lipgloss.Color(mocha.Mauve().Hex)
64+ theme.MarkdownLinkColor = lipgloss.Color(mocha.Sky().Hex)
65+ theme.MarkdownLinkTextColor = lipgloss.Color(mocha.Pink().Hex)
66+ theme.MarkdownCodeColor = lipgloss.Color(mocha.Green().Hex)
67+ theme.MarkdownBlockQuoteColor = lipgloss.Color(mocha.Yellow().Hex)
68+ theme.MarkdownEmphColor = lipgloss.Color(mocha.Yellow().Hex)
69+ theme.MarkdownStrongColor = lipgloss.Color(mocha.Peach().Hex)
70+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(mocha.Overlay0().Hex)
71+ theme.MarkdownListItemColor = lipgloss.Color(mocha.Blue().Hex)
72+ theme.MarkdownListEnumerationColor = lipgloss.Color(mocha.Sky().Hex)
73+ theme.MarkdownImageColor = lipgloss.Color(mocha.Sapphire().Hex)
74+ theme.MarkdownImageTextColor = lipgloss.Color(mocha.Pink().Hex)
75+ theme.MarkdownCodeBlockColor = lipgloss.Color(mocha.Text().Hex)
76+
77+ // Syntax highlighting colors
78+ theme.SyntaxCommentColor = lipgloss.Color(mocha.Overlay1().Hex)
79+ theme.SyntaxKeywordColor = lipgloss.Color(mocha.Pink().Hex)
80+ theme.SyntaxFunctionColor = lipgloss.Color(mocha.Green().Hex)
81+ theme.SyntaxVariableColor = lipgloss.Color(mocha.Sky().Hex)
82+ theme.SyntaxStringColor = lipgloss.Color(mocha.Yellow().Hex)
83+ theme.SyntaxNumberColor = lipgloss.Color(mocha.Teal().Hex)
84+ theme.SyntaxTypeColor = lipgloss.Color(mocha.Sky().Hex)
85+ theme.SyntaxOperatorColor = lipgloss.Color(mocha.Pink().Hex)
86+ theme.SyntaxPunctuationColor = lipgloss.Color(mocha.Text().Hex)
87+
88+ return theme
89+}
90+
91+// NewCatppuccinLatteTheme creates a new instance of the Catppuccin Latte theme.
92+func NewCatppuccinLatteTheme() *CatppuccinTheme {
93+ // Get the Catppuccin palette
1894 latte := catppuccin.Latte
1995
2096 theme := &CatppuccinTheme{}
2197
2298 // Base colors
23− theme.PrimaryColor = lipgloss.AdaptiveColor{
24− Dark: mocha.Blue().Hex,
25− Light: latte.Blue().Hex,
26− }
27− theme.SecondaryColor = lipgloss.AdaptiveColor{
28− Dark: mocha.Mauve().Hex,
29− Light: latte.Mauve().Hex,
30− }
31− theme.AccentColor = lipgloss.AdaptiveColor{
32− Dark: mocha.Peach().Hex,
33− Light: latte.Peach().Hex,
34− }
99+ theme.PrimaryColor = lipgloss.Color(latte.Blue().Hex)
100+ theme.SecondaryColor = lipgloss.Color(latte.Mauve().Hex)
101+ theme.AccentColor = lipgloss.Color(latte.Peach().Hex)
35102
36103 // Status colors
37− theme.ErrorColor = lipgloss.AdaptiveColor{
38− Dark: mocha.Red().Hex,
39− Light: latte.Red().Hex,
40− }
41− theme.WarningColor = lipgloss.AdaptiveColor{
42− Dark: mocha.Peach().Hex,
43− Light: latte.Peach().Hex,
44− }
45− theme.SuccessColor = lipgloss.AdaptiveColor{
46− Dark: mocha.Green().Hex,
47− Light: latte.Green().Hex,
48− }
49− theme.InfoColor = lipgloss.AdaptiveColor{
50− Dark: mocha.Blue().Hex,
51− Light: latte.Blue().Hex,
52− }
104+ theme.ErrorColor = lipgloss.Color(latte.Red().Hex)
105+ theme.WarningColor = lipgloss.Color(latte.Peach().Hex)
106+ theme.SuccessColor = lipgloss.Color(latte.Green().Hex)
107+ theme.InfoColor = lipgloss.Color(latte.Blue().Hex)
53108
54109 // Text colors
55− theme.TextColor = lipgloss.AdaptiveColor{
56− Dark: mocha.Text().Hex,
57− Light: latte.Text().Hex,
58− }
59− theme.TextMutedColor = lipgloss.AdaptiveColor{
60− Dark: mocha.Subtext0().Hex,
61− Light: latte.Subtext0().Hex,
62− }
63− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
64− Dark: mocha.Lavender().Hex,
65− Light: latte.Lavender().Hex,
66− }
110+ theme.TextColor = lipgloss.Color(latte.Text().Hex)
111+ theme.TextMutedColor = lipgloss.Color(latte.Subtext0().Hex)
112+ theme.TextEmphasizedColor = lipgloss.Color(latte.Lavender().Hex)
67113
68114 // Background colors
69− theme.BackgroundColor = lipgloss.AdaptiveColor{
70− Dark: "#212121", // From existing styles
71− Light: "#EEEEEE", // Light equivalent
72− }
73− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
74− Dark: "#2c2c2c", // From existing styles
75− Light: "#E0E0E0", // Light equivalent
76− }
77− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
78− Dark: "#181818", // From existing styles
79− Light: "#F5F5F5", // Light equivalent
80− }
115+ theme.BackgroundColor = lipgloss.Color("#EEEEEE") // Light equivalent
116+ theme.BackgroundSecondaryColor = lipgloss.Color("#E0E0E0") // Light equivalent
117+ theme.BackgroundDarkerColor = lipgloss.Color("#F5F5F5") // Light equivalent
81118
82119 // Border colors
83− theme.BorderNormalColor = lipgloss.AdaptiveColor{
84− Dark: "#4b4c5c", // From existing styles
85− Light: "#BDBDBD", // Light equivalent
86− }
87− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
88− Dark: mocha.Blue().Hex,
89− Light: latte.Blue().Hex,
90− }
91− theme.BorderDimColor = lipgloss.AdaptiveColor{
92− Dark: mocha.Surface0().Hex,
93− Light: latte.Surface0().Hex,
94− }
120+ theme.BorderNormalColor = lipgloss.Color("#BDBDBD") // Light equivalent
121+ theme.BorderFocusedColor = lipgloss.Color(latte.Blue().Hex)
122+ theme.BorderDimColor = lipgloss.Color(latte.Surface0().Hex)
95123
96124 // Diff view colors
97− theme.DiffAddedColor = lipgloss.AdaptiveColor{
98− Dark: "#478247", // From existing diff.go
99− Light: "#2E7D32", // Light equivalent
100− }
101− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
102− Dark: "#7C4444", // From existing diff.go
103− Light: "#C62828", // Light equivalent
104− }
105− theme.DiffContextColor = lipgloss.AdaptiveColor{
106− Dark: "#a0a0a0", // From existing diff.go
107− Light: "#757575", // Light equivalent
108− }
109− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
110− Dark: "#a0a0a0", // From existing diff.go
111− Light: "#757575", // Light equivalent
112− }
113− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
114− Dark: "#DAFADA", // From existing diff.go
115− Light: "#A5D6A7", // Light equivalent
116− }
117− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
118− Dark: "#FADADD", // From existing diff.go
119− Light: "#EF9A9A", // Light equivalent
120− }
121− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
122− Dark: "#303A30", // From existing diff.go
123− Light: "#E8F5E9", // Light equivalent
124− }
125− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
126− Dark: "#3A3030", // From existing diff.go
127− Light: "#FFEBEE", // Light equivalent
128− }
129− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
130− Dark: "#212121", // From existing diff.go
131− Light: "#F5F5F5", // Light equivalent
132− }
133− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
134− Dark: "#888888", // From existing diff.go
135− Light: "#9E9E9E", // Light equivalent
136− }
137− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
138− Dark: "#293229", // From existing diff.go
139− Light: "#C8E6C9", // Light equivalent
140− }
141− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
142− Dark: "#332929", // From existing diff.go
143− Light: "#FFCDD2", // Light equivalent
144− }
125+ theme.DiffAddedColor = lipgloss.Color("#2E7D32") // Light equivalent
126+ theme.DiffRemovedColor = lipgloss.Color("#C62828") // Light equivalent
127+ theme.DiffContextColor = lipgloss.Color("#757575") // Light equivalent
128+ theme.DiffHunkHeaderColor = lipgloss.Color("#757575") // Light equivalent
129+ theme.DiffHighlightAddedColor = lipgloss.Color("#A5D6A7") // Light equivalent
130+ theme.DiffHighlightRemovedColor = lipgloss.Color("#EF9A9A") // Light equivalent
131+ theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9") // Light equivalent
132+ theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE") // Light equivalent
133+ theme.DiffContextBgColor = lipgloss.Color("#F5F5F5") // Light equivalent
134+ theme.DiffLineNumberColor = lipgloss.Color("#9E9E9E") // Light equivalent
135+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9") // Light equivalent
136+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2") // Light equivalent
145137
146138 // Markdown colors
147− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
148− Dark: mocha.Text().Hex,
149− Light: latte.Text().Hex,
150− }
151− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
152− Dark: mocha.Mauve().Hex,
153− Light: latte.Mauve().Hex,
154− }
155− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
156− Dark: mocha.Sky().Hex,
157− Light: latte.Sky().Hex,
158− }
159− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
160− Dark: mocha.Pink().Hex,
161− Light: latte.Pink().Hex,
162− }
163− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
164− Dark: mocha.Green().Hex,
165− Light: latte.Green().Hex,
166− }
167− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
168− Dark: mocha.Yellow().Hex,
169− Light: latte.Yellow().Hex,
170− }
171− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
172− Dark: mocha.Yellow().Hex,
173− Light: latte.Yellow().Hex,
174− }
175− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
176− Dark: mocha.Peach().Hex,
177− Light: latte.Peach().Hex,
178− }
179− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
180− Dark: mocha.Overlay0().Hex,
181− Light: latte.Overlay0().Hex,
182− }
183− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
184− Dark: mocha.Blue().Hex,
185− Light: latte.Blue().Hex,
186− }
187− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
188− Dark: mocha.Sky().Hex,
189− Light: latte.Sky().Hex,
190− }
191− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
192− Dark: mocha.Sapphire().Hex,
193− Light: latte.Sapphire().Hex,
194− }
195− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
196− Dark: mocha.Pink().Hex,
197− Light: latte.Pink().Hex,
198− }
199− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
200− Dark: mocha.Text().Hex,
201− Light: latte.Text().Hex,
202− }
139+ theme.MarkdownTextColor = lipgloss.Color(latte.Text().Hex)
140+ theme.MarkdownHeadingColor = lipgloss.Color(latte.Mauve().Hex)
141+ theme.MarkdownLinkColor = lipgloss.Color(latte.Sky().Hex)
142+ theme.MarkdownLinkTextColor = lipgloss.Color(latte.Pink().Hex)
143+ theme.MarkdownCodeColor = lipgloss.Color(latte.Green().Hex)
144+ theme.MarkdownBlockQuoteColor = lipgloss.Color(latte.Yellow().Hex)
145+ theme.MarkdownEmphColor = lipgloss.Color(latte.Yellow().Hex)
146+ theme.MarkdownStrongColor = lipgloss.Color(latte.Peach().Hex)
147+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(latte.Overlay0().Hex)
148+ theme.MarkdownListItemColor = lipgloss.Color(latte.Blue().Hex)
149+ theme.MarkdownListEnumerationColor = lipgloss.Color(latte.Sky().Hex)
150+ theme.MarkdownImageColor = lipgloss.Color(latte.Sapphire().Hex)
151+ theme.MarkdownImageTextColor = lipgloss.Color(latte.Pink().Hex)
152+ theme.MarkdownCodeBlockColor = lipgloss.Color(latte.Text().Hex)
203153
204154 // Syntax highlighting colors
205− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
206− Dark: mocha.Overlay1().Hex,
207− Light: latte.Overlay1().Hex,
208− }
209− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
210− Dark: mocha.Pink().Hex,
211− Light: latte.Pink().Hex,
212− }
213− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
214− Dark: mocha.Green().Hex,
215− Light: latte.Green().Hex,
216− }
217− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
218− Dark: mocha.Sky().Hex,
219− Light: latte.Sky().Hex,
220− }
221− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
222− Dark: mocha.Yellow().Hex,
223− Light: latte.Yellow().Hex,
224− }
225− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
226− Dark: mocha.Teal().Hex,
227− Light: latte.Teal().Hex,
228− }
229− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
230− Dark: mocha.Sky().Hex,
231− Light: latte.Sky().Hex,
232− }
233− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
234− Dark: mocha.Pink().Hex,
235− Light: latte.Pink().Hex,
236− }
237− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
238− Dark: mocha.Text().Hex,
239− Light: latte.Text().Hex,
240− }
155+ theme.SyntaxCommentColor = lipgloss.Color(latte.Overlay1().Hex)
156+ theme.SyntaxKeywordColor = lipgloss.Color(latte.Pink().Hex)
157+ theme.SyntaxFunctionColor = lipgloss.Color(latte.Green().Hex)
158+ theme.SyntaxVariableColor = lipgloss.Color(latte.Sky().Hex)
159+ theme.SyntaxStringColor = lipgloss.Color(latte.Yellow().Hex)
160+ theme.SyntaxNumberColor = lipgloss.Color(latte.Teal().Hex)
161+ theme.SyntaxTypeColor = lipgloss.Color(latte.Sky().Hex)
162+ theme.SyntaxOperatorColor = lipgloss.Color(latte.Pink().Hex)
163+ theme.SyntaxPunctuationColor = lipgloss.Color(latte.Text().Hex)
241164
242165 return theme
243166}
244167
245168func init() {
246− // Register the Catppuccin theme with the theme manager
247− RegisterTheme("catppuccin", NewCatppuccinTheme())
248−}
169+ // Register the Catppuccin themes with the theme manager
170+ RegisterTheme("catppuccin-mocha", NewCatppuccinMochaTheme())
171+ RegisterTheme("catppuccin-latte", NewCatppuccinLatteTheme())
172+}
internal/tui/theme/dracula.go+52−220
@@ -1,7 +1,7 @@
11package theme
22
33import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
55)
66
77// DraculaTheme implements the Theme interface with Dracula colors.
@@ -28,242 +28,74 @@ func NewDraculaTheme() *DraculaTheme {
2828 darkYellow := "#f1fa8c"
2929 darkBorder := "#44475a"
3030
31− // Light mode approximation (Dracula is primarily a dark theme)
32− lightBackground := "#f8f8f2"
33− lightCurrentLine := "#e6e6e6"
34− lightSelection := "#d8d8d8"
35− lightForeground := "#282a36"
36− lightComment := "#6272a4"
37− lightCyan := "#0097a7"
38− lightGreen := "#388e3c"
39− lightOrange := "#f57c00"
40− lightPink := "#d81b60"
41− lightPurple := "#7e57c2"
42− lightRed := "#e53935"
43− lightYellow := "#fbc02d"
44− lightBorder := "#d8d8d8"
45−
4631 theme := &DraculaTheme{}
4732
4833 // Base colors
49− theme.PrimaryColor = lipgloss.AdaptiveColor{
50− Dark: darkPurple,
51− Light: lightPurple,
52− }
53− theme.SecondaryColor = lipgloss.AdaptiveColor{
54− Dark: darkPink,
55− Light: lightPink,
56− }
57− theme.AccentColor = lipgloss.AdaptiveColor{
58− Dark: darkCyan,
59− Light: lightCyan,
60− }
34+ theme.PrimaryColor = lipgloss.Color(darkPurple)
35+ theme.SecondaryColor = lipgloss.Color(darkPink)
36+ theme.AccentColor = lipgloss.Color(darkCyan)
6137
6238 // Status colors
63− theme.ErrorColor = lipgloss.AdaptiveColor{
64− Dark: darkRed,
65− Light: lightRed,
66− }
67− theme.WarningColor = lipgloss.AdaptiveColor{
68− Dark: darkOrange,
69− Light: lightOrange,
70− }
71− theme.SuccessColor = lipgloss.AdaptiveColor{
72− Dark: darkGreen,
73− Light: lightGreen,
74− }
75− theme.InfoColor = lipgloss.AdaptiveColor{
76− Dark: darkCyan,
77− Light: lightCyan,
78− }
39+ theme.ErrorColor = lipgloss.Color(darkRed)
40+ theme.WarningColor = lipgloss.Color(darkOrange)
41+ theme.SuccessColor = lipgloss.Color(darkGreen)
42+ theme.InfoColor = lipgloss.Color(darkCyan)
7943
8044 // Text colors
81− theme.TextColor = lipgloss.AdaptiveColor{
82− Dark: darkForeground,
83− Light: lightForeground,
84− }
85− theme.TextMutedColor = lipgloss.AdaptiveColor{
86− Dark: darkComment,
87− Light: lightComment,
88− }
89− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
90− Dark: darkYellow,
91− Light: lightYellow,
92− }
45+ theme.TextColor = lipgloss.Color(darkForeground)
46+ theme.TextMutedColor = lipgloss.Color(darkComment)
47+ theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
9348
9449 // Background colors
95− theme.BackgroundColor = lipgloss.AdaptiveColor{
96− Dark: darkBackground,
97− Light: lightBackground,
98− }
99− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
100− Dark: darkCurrentLine,
101− Light: lightCurrentLine,
102− }
103− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
104− Dark: "#21222c", // Slightly darker than background
105− Light: "#ffffff", // Slightly lighter than background
106− }
50+ theme.BackgroundColor = lipgloss.Color(darkBackground)
51+ theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
52+ theme.BackgroundDarkerColor = lipgloss.Color("#21222c") // Slightly darker than background
10753
10854 // Border colors
109− theme.BorderNormalColor = lipgloss.AdaptiveColor{
110− Dark: darkBorder,
111− Light: lightBorder,
112− }
113− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
114− Dark: darkPurple,
115− Light: lightPurple,
116− }
117− theme.BorderDimColor = lipgloss.AdaptiveColor{
118− Dark: darkSelection,
119− Light: lightSelection,
120− }
55+ theme.BorderNormalColor = lipgloss.Color(darkBorder)
56+ theme.BorderFocusedColor = lipgloss.Color(darkPurple)
57+ theme.BorderDimColor = lipgloss.Color(darkSelection)
12158
12259 // Diff view colors
123− theme.DiffAddedColor = lipgloss.AdaptiveColor{
124− Dark: darkGreen,
125− Light: lightGreen,
126− }
127− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
128− Dark: darkRed,
129− Light: lightRed,
130− }
131− theme.DiffContextColor = lipgloss.AdaptiveColor{
132− Dark: darkComment,
133− Light: lightComment,
134− }
135− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
136− Dark: darkPurple,
137− Light: lightPurple,
138− }
139− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
140− Dark: "#50fa7b",
141− Light: "#a5d6a7",
142− }
143− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
144− Dark: "#ff5555",
145− Light: "#ef9a9a",
146− }
147− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
148− Dark: "#2c3b2c",
149− Light: "#e8f5e9",
150− }
151− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
152− Dark: "#3b2c2c",
153− Light: "#ffebee",
154− }
155− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
156− Dark: darkBackground,
157− Light: lightBackground,
158− }
159− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
160− Dark: darkComment,
161− Light: lightComment,
162− }
163− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
164− Dark: "#253025",
165− Light: "#c8e6c9",
166− }
167− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
168− Dark: "#302525",
169− Light: "#ffcdd2",
170− }
60+ theme.DiffAddedColor = lipgloss.Color(darkGreen)
61+ theme.DiffRemovedColor = lipgloss.Color(darkRed)
62+ theme.DiffContextColor = lipgloss.Color(darkComment)
63+ theme.DiffHunkHeaderColor = lipgloss.Color(darkPurple)
64+ theme.DiffHighlightAddedColor = lipgloss.Color("#50fa7b")
65+ theme.DiffHighlightRemovedColor = lipgloss.Color("#ff5555")
66+ theme.DiffAddedBgColor = lipgloss.Color("#2c3b2c")
67+ theme.DiffRemovedBgColor = lipgloss.Color("#3b2c2c")
68+ theme.DiffContextBgColor = lipgloss.Color(darkBackground)
69+ theme.DiffLineNumberColor = lipgloss.Color(darkComment)
70+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#253025")
71+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#302525")
17172
17273 // Markdown colors
173− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
174− Dark: darkForeground,
175− Light: lightForeground,
176− }
177− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
178− Dark: darkPink,
179− Light: lightPink,
180− }
181− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
182− Dark: darkPurple,
183− Light: lightPurple,
184− }
185− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
186− Dark: darkCyan,
187− Light: lightCyan,
188− }
189− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
190− Dark: darkGreen,
191− Light: lightGreen,
192− }
193− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
194− Dark: darkYellow,
195− Light: lightYellow,
196− }
197− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
198− Dark: darkYellow,
199− Light: lightYellow,
200− }
201− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
202− Dark: darkOrange,
203− Light: lightOrange,
204− }
205− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
206− Dark: darkComment,
207− Light: lightComment,
208− }
209− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
210− Dark: darkPurple,
211− Light: lightPurple,
212− }
213− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
214− Dark: darkCyan,
215− Light: lightCyan,
216− }
217− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
218− Dark: darkPurple,
219− Light: lightPurple,
220− }
221− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
222− Dark: darkCyan,
223− Light: lightCyan,
224− }
225− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
226− Dark: darkForeground,
227− Light: lightForeground,
228− }
74+ theme.MarkdownTextColor = lipgloss.Color(darkForeground)
75+ theme.MarkdownHeadingColor = lipgloss.Color(darkPink)
76+ theme.MarkdownLinkColor = lipgloss.Color(darkPurple)
77+ theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
78+ theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
79+ theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
80+ theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
81+ theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
82+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
83+ theme.MarkdownListItemColor = lipgloss.Color(darkPurple)
84+ theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
85+ theme.MarkdownImageColor = lipgloss.Color(darkPurple)
86+ theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
87+ theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
22988
23089 // Syntax highlighting colors
231− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
232− Dark: darkComment,
233− Light: lightComment,
234− }
235− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
236− Dark: darkPink,
237− Light: lightPink,
238− }
239− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
240− Dark: darkGreen,
241− Light: lightGreen,
242− }
243− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
244− Dark: darkOrange,
245− Light: lightOrange,
246− }
247− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
248− Dark: darkYellow,
249− Light: lightYellow,
250− }
251− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
252− Dark: darkPurple,
253− Light: lightPurple,
254− }
255− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
256− Dark: darkCyan,
257− Light: lightCyan,
258− }
259− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
260− Dark: darkPink,
261− Light: lightPink,
262− }
263− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
264− Dark: darkForeground,
265− Light: lightForeground,
266− }
90+ theme.SyntaxCommentColor = lipgloss.Color(darkComment)
91+ theme.SyntaxKeywordColor = lipgloss.Color(darkPink)
92+ theme.SyntaxFunctionColor = lipgloss.Color(darkGreen)
93+ theme.SyntaxVariableColor = lipgloss.Color(darkOrange)
94+ theme.SyntaxStringColor = lipgloss.Color(darkYellow)
95+ theme.SyntaxNumberColor = lipgloss.Color(darkPurple)
96+ theme.SyntaxTypeColor = lipgloss.Color(darkCyan)
97+ theme.SyntaxOperatorColor = lipgloss.Color(darkPink)
98+ theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
26799
268100 return theme
269101}
internal/tui/theme/flexoki.go+131−209
@@ -1,7 +1,7 @@
11package theme
22
33import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
55)
66
77// Flexoki color palette constants
@@ -49,234 +49,156 @@ type FlexokiTheme struct {
4949 BaseTheme
5050}
5151
52−// NewFlexokiTheme creates a new instance of the Flexoki theme.
53−func NewFlexokiTheme() *FlexokiTheme {
52+// NewFlexokiDarkTheme creates a new instance of the Flexoki Dark theme.
53+func NewFlexokiDarkTheme() *FlexokiTheme {
5454 theme := &FlexokiTheme{}
5555
5656 // Base colors
57− theme.PrimaryColor = lipgloss.AdaptiveColor{
58− Dark: flexokiBlue400,
59− Light: flexokiBlue600,
60− }
61− theme.SecondaryColor = lipgloss.AdaptiveColor{
62− Dark: flexokiPurple400,
63− Light: flexokiPurple600,
64− }
65− theme.AccentColor = lipgloss.AdaptiveColor{
66− Dark: flexokiOrange400,
67− Light: flexokiOrange600,
68− }
57+ theme.PrimaryColor = lipgloss.Color(flexokiBlue400)
58+ theme.SecondaryColor = lipgloss.Color(flexokiPurple400)
59+ theme.AccentColor = lipgloss.Color(flexokiOrange400)
6960
7061 // Status colors
71− theme.ErrorColor = lipgloss.AdaptiveColor{
72− Dark: flexokiRed400,
73− Light: flexokiRed600,
74− }
75− theme.WarningColor = lipgloss.AdaptiveColor{
76− Dark: flexokiYellow400,
77− Light: flexokiYellow600,
78− }
79− theme.SuccessColor = lipgloss.AdaptiveColor{
80− Dark: flexokiGreen400,
81− Light: flexokiGreen600,
82− }
83− theme.InfoColor = lipgloss.AdaptiveColor{
84− Dark: flexokiCyan400,
85− Light: flexokiCyan600,
86− }
62+ theme.ErrorColor = lipgloss.Color(flexokiRed400)
63+ theme.WarningColor = lipgloss.Color(flexokiYellow400)
64+ theme.SuccessColor = lipgloss.Color(flexokiGreen400)
65+ theme.InfoColor = lipgloss.Color(flexokiCyan400)
8766
8867 // Text colors
89− theme.TextColor = lipgloss.AdaptiveColor{
90− Dark: flexokiBase300,
91− Light: flexokiBase600,
92− }
93− theme.TextMutedColor = lipgloss.AdaptiveColor{
94− Dark: flexokiBase700,
95− Light: flexokiBase500,
96− }
97− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
98− Dark: flexokiYellow400,
99− Light: flexokiYellow600,
100− }
68+ theme.TextColor = lipgloss.Color(flexokiBase300)
69+ theme.TextMutedColor = lipgloss.Color(flexokiBase700)
70+ theme.TextEmphasizedColor = lipgloss.Color(flexokiYellow400)
10171
10272 // Background colors
103− theme.BackgroundColor = lipgloss.AdaptiveColor{
104− Dark: flexokiBlack,
105− Light: flexokiPaper,
106− }
107− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
108− Dark: flexokiBase950,
109− Light: flexokiBase50,
110− }
111− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
112− Dark: flexokiBase900,
113− Light: flexokiBase100,
114− }
73+ theme.BackgroundColor = lipgloss.Color(flexokiBlack)
74+ theme.BackgroundSecondaryColor = lipgloss.Color(flexokiBase950)
75+ theme.BackgroundDarkerColor = lipgloss.Color(flexokiBase900)
11576
11677 // Border colors
117− theme.BorderNormalColor = lipgloss.AdaptiveColor{
118− Dark: flexokiBase900,
119− Light: flexokiBase100,
120− }
121− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
122− Dark: flexokiBlue400,
123− Light: flexokiBlue600,
124− }
125− theme.BorderDimColor = lipgloss.AdaptiveColor{
126− Dark: flexokiBase850,
127− Light: flexokiBase150,
128− }
78+ theme.BorderNormalColor = lipgloss.Color(flexokiBase900)
79+ theme.BorderFocusedColor = lipgloss.Color(flexokiBlue400)
80+ theme.BorderDimColor = lipgloss.Color(flexokiBase850)
12981
13082 // Diff view colors
131− theme.DiffAddedColor = lipgloss.AdaptiveColor{
132− Dark: flexokiGreen400,
133− Light: flexokiGreen600,
134− }
135− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
136− Dark: flexokiRed400,
137− Light: flexokiRed600,
138− }
139− theme.DiffContextColor = lipgloss.AdaptiveColor{
140− Dark: flexokiBase700,
141− Light: flexokiBase500,
142− }
143− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
144− Dark: flexokiBase700,
145− Light: flexokiBase500,
146− }
147− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
148− Dark: flexokiGreen400,
149− Light: flexokiGreen600,
150− }
151− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
152− Dark: flexokiRed400,
153− Light: flexokiRed600,
154− }
155− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
156− Dark: "#1D2419", // Darker green background
157− Light: "#EFF2E2", // Light green background
158− }
159− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
160− Dark: "#241919", // Darker red background
161− Light: "#F2E2E2", // Light red background
162− }
163− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
164− Dark: flexokiBlack,
165− Light: flexokiPaper,
166− }
167− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
168− Dark: flexokiBase700,
169− Light: flexokiBase500,
170− }
171− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
172− Dark: "#1A2017", // Slightly darker green
173− Light: "#E5EBD9", // Light green
174− }
175− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
176− Dark: "#201717", // Slightly darker red
177− Light: "#EBD9D9", // Light red
178− }
83+ theme.DiffAddedColor = lipgloss.Color(flexokiGreen400)
84+ theme.DiffRemovedColor = lipgloss.Color(flexokiRed400)
85+ theme.DiffContextColor = lipgloss.Color(flexokiBase700)
86+ theme.DiffHunkHeaderColor = lipgloss.Color(flexokiBase700)
87+ theme.DiffHighlightAddedColor = lipgloss.Color(flexokiGreen400)
88+ theme.DiffHighlightRemovedColor = lipgloss.Color(flexokiRed400)
89+ theme.DiffAddedBgColor = lipgloss.Color("#1D2419") // Darker green background
90+ theme.DiffRemovedBgColor = lipgloss.Color("#241919") // Darker red background
91+ theme.DiffContextBgColor = lipgloss.Color(flexokiBlack)
92+ theme.DiffLineNumberColor = lipgloss.Color(flexokiBase700)
93+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#1A2017") // Slightly darker green
94+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#201717") // Slightly darker red
17995
18096 // Markdown colors
181− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
182− Dark: flexokiBase300,
183− Light: flexokiBase600,
184− }
185− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
186− Dark: flexokiYellow400,
187− Light: flexokiYellow600,
188− }
189− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
190− Dark: flexokiCyan400,
191− Light: flexokiCyan600,
192− }
193− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
194− Dark: flexokiMagenta400,
195− Light: flexokiMagenta600,
196− }
197− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
198− Dark: flexokiGreen400,
199− Light: flexokiGreen600,
200− }
201− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
202− Dark: flexokiCyan400,
203− Light: flexokiCyan600,
204− }
205− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
206− Dark: flexokiYellow400,
207− Light: flexokiYellow600,
208− }
209− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
210− Dark: flexokiOrange400,
211− Light: flexokiOrange600,
212− }
213− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
214− Dark: flexokiBase800,
215− Light: flexokiBase200,
216− }
217− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
218− Dark: flexokiBlue400,
219− Light: flexokiBlue600,
220− }
221− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
222− Dark: flexokiBlue400,
223− Light: flexokiBlue600,
224− }
225− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
226− Dark: flexokiPurple400,
227− Light: flexokiPurple600,
228− }
229− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
230− Dark: flexokiMagenta400,
231− Light: flexokiMagenta600,
232− }
233− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
234− Dark: flexokiBase300,
235− Light: flexokiBase600,
236− }
97+ theme.MarkdownTextColor = lipgloss.Color(flexokiBase300)
98+ theme.MarkdownHeadingColor = lipgloss.Color(flexokiYellow400)
99+ theme.MarkdownLinkColor = lipgloss.Color(flexokiCyan400)
100+ theme.MarkdownLinkTextColor = lipgloss.Color(flexokiMagenta400)
101+ theme.MarkdownCodeColor = lipgloss.Color(flexokiGreen400)
102+ theme.MarkdownBlockQuoteColor = lipgloss.Color(flexokiCyan400)
103+ theme.MarkdownEmphColor = lipgloss.Color(flexokiYellow400)
104+ theme.MarkdownStrongColor = lipgloss.Color(flexokiOrange400)
105+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(flexokiBase800)
106+ theme.MarkdownListItemColor = lipgloss.Color(flexokiBlue400)
107+ theme.MarkdownListEnumerationColor = lipgloss.Color(flexokiBlue400)
108+ theme.MarkdownImageColor = lipgloss.Color(flexokiPurple400)
109+ theme.MarkdownImageTextColor = lipgloss.Color(flexokiMagenta400)
110+ theme.MarkdownCodeBlockColor = lipgloss.Color(flexokiBase300)
237111
238112 // Syntax highlighting colors (based on Flexoki's mappings)
239− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
240− Dark: flexokiBase700, // tx-3
241− Light: flexokiBase300, // tx-3
242− }
243− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
244− Dark: flexokiGreen400, // gr
245− Light: flexokiGreen600, // gr
246− }
247− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
248− Dark: flexokiOrange400, // or
249− Light: flexokiOrange600, // or
250− }
251− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
252− Dark: flexokiBlue400, // bl
253− Light: flexokiBlue600, // bl
254− }
255− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
256− Dark: flexokiCyan400, // cy
257− Light: flexokiCyan600, // cy
258− }
259− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
260− Dark: flexokiPurple400, // pu
261− Light: flexokiPurple600, // pu
262− }
263− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
264− Dark: flexokiYellow400, // ye
265− Light: flexokiYellow600, // ye
266− }
267− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
268− Dark: flexokiBase500, // tx-2
269− Light: flexokiBase500, // tx-2
270− }
271− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
272− Dark: flexokiBase500, // tx-2
273− Light: flexokiBase500, // tx-2
274− }
113+ theme.SyntaxCommentColor = lipgloss.Color(flexokiBase700) // tx-3
114+ theme.SyntaxKeywordColor = lipgloss.Color(flexokiGreen400) // gr
115+ theme.SyntaxFunctionColor = lipgloss.Color(flexokiOrange400) // or
116+ theme.SyntaxVariableColor = lipgloss.Color(flexokiBlue400) // bl
117+ theme.SyntaxStringColor = lipgloss.Color(flexokiCyan400) // cy
118+ theme.SyntaxNumberColor = lipgloss.Color(flexokiPurple400) // pu
119+ theme.SyntaxTypeColor = lipgloss.Color(flexokiYellow400) // ye
120+ theme.SyntaxOperatorColor = lipgloss.Color(flexokiBase500) // tx-2
121+ theme.SyntaxPunctuationColor = lipgloss.Color(flexokiBase500) // tx-2
122+
123+ return theme
124+}
125+
126+// NewFlexokiLightTheme creates a new instance of the Flexoki Light theme.
127+func NewFlexokiLightTheme() *FlexokiTheme {
128+ theme := &FlexokiTheme{}
129+
130+ // Base colors
131+ theme.PrimaryColor = lipgloss.Color(flexokiBlue600)
132+ theme.SecondaryColor = lipgloss.Color(flexokiPurple600)
133+ theme.AccentColor = lipgloss.Color(flexokiOrange600)
134+
135+ // Status colors
136+ theme.ErrorColor = lipgloss.Color(flexokiRed600)
137+ theme.WarningColor = lipgloss.Color(flexokiYellow600)
138+ theme.SuccessColor = lipgloss.Color(flexokiGreen600)
139+ theme.InfoColor = lipgloss.Color(flexokiCyan600)
140+
141+ // Text colors
142+ theme.TextColor = lipgloss.Color(flexokiBase600)
143+ theme.TextMutedColor = lipgloss.Color(flexokiBase500)
144+ theme.TextEmphasizedColor = lipgloss.Color(flexokiYellow600)
145+
146+ // Background colors
147+ theme.BackgroundColor = lipgloss.Color(flexokiPaper)
148+ theme.BackgroundSecondaryColor = lipgloss.Color(flexokiBase50)
149+ theme.BackgroundDarkerColor = lipgloss.Color(flexokiBase100)
150+
151+ // Border colors
152+ theme.BorderNormalColor = lipgloss.Color(flexokiBase100)
153+ theme.BorderFocusedColor = lipgloss.Color(flexokiBlue600)
154+ theme.BorderDimColor = lipgloss.Color(flexokiBase150)
155+
156+ // Diff view colors
157+ theme.DiffAddedColor = lipgloss.Color(flexokiGreen600)
158+ theme.DiffRemovedColor = lipgloss.Color(flexokiRed600)
159+ theme.DiffContextColor = lipgloss.Color(flexokiBase500)
160+ theme.DiffHunkHeaderColor = lipgloss.Color(flexokiBase500)
161+ theme.DiffHighlightAddedColor = lipgloss.Color(flexokiGreen600)
162+ theme.DiffHighlightRemovedColor = lipgloss.Color(flexokiRed600)
163+ theme.DiffAddedBgColor = lipgloss.Color("#EFF2E2") // Light green background
164+ theme.DiffRemovedBgColor = lipgloss.Color("#F2E2E2") // Light red background
165+ theme.DiffContextBgColor = lipgloss.Color(flexokiPaper)
166+ theme.DiffLineNumberColor = lipgloss.Color(flexokiBase500)
167+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#E5EBD9") // Light green
168+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#EBD9D9") // Light red
169+
170+ // Markdown colors
171+ theme.MarkdownTextColor = lipgloss.Color(flexokiBase600)
172+ theme.MarkdownHeadingColor = lipgloss.Color(flexokiYellow600)
173+ theme.MarkdownLinkColor = lipgloss.Color(flexokiCyan600)
174+ theme.MarkdownLinkTextColor = lipgloss.Color(flexokiMagenta600)
175+ theme.MarkdownCodeColor = lipgloss.Color(flexokiGreen600)
176+ theme.MarkdownBlockQuoteColor = lipgloss.Color(flexokiCyan600)
177+ theme.MarkdownEmphColor = lipgloss.Color(flexokiYellow600)
178+ theme.MarkdownStrongColor = lipgloss.Color(flexokiOrange600)
179+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(flexokiBase200)
180+ theme.MarkdownListItemColor = lipgloss.Color(flexokiBlue600)
181+ theme.MarkdownListEnumerationColor = lipgloss.Color(flexokiBlue600)
182+ theme.MarkdownImageColor = lipgloss.Color(flexokiPurple600)
183+ theme.MarkdownImageTextColor = lipgloss.Color(flexokiMagenta600)
184+ theme.MarkdownCodeBlockColor = lipgloss.Color(flexokiBase600)
185+
186+ // Syntax highlighting colors (based on Flexoki's mappings)
187+ theme.SyntaxCommentColor = lipgloss.Color(flexokiBase300) // tx-3
188+ theme.SyntaxKeywordColor = lipgloss.Color(flexokiGreen600) // gr
189+ theme.SyntaxFunctionColor = lipgloss.Color(flexokiOrange600) // or
190+ theme.SyntaxVariableColor = lipgloss.Color(flexokiBlue600) // bl
191+ theme.SyntaxStringColor = lipgloss.Color(flexokiCyan600) // cy
192+ theme.SyntaxNumberColor = lipgloss.Color(flexokiPurple600) // pu
193+ theme.SyntaxTypeColor = lipgloss.Color(flexokiYellow600) // ye
194+ theme.SyntaxOperatorColor = lipgloss.Color(flexokiBase500) // tx-2
195+ theme.SyntaxPunctuationColor = lipgloss.Color(flexokiBase500) // tx-2
275196
276197 return theme
277198}
278199
279200func init() {
280− // Register the Flexoki theme with the theme manager
281− RegisterTheme("flexoki", NewFlexokiTheme())
201+ // Register the Flexoki themes with the theme manager
202+ RegisterTheme("flexoki-dark", NewFlexokiDarkTheme())
203+ RegisterTheme("flexoki-light", NewFlexokiLightTheme())
282204}
internal/tui/theme/gruvbox.go+128−206
@@ -1,7 +1,7 @@
11package theme
22
33import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
55)
66
77// Gruvbox color palette constants
@@ -74,229 +74,151 @@ func NewGruvboxTheme() *GruvboxTheme {
7474 theme := &GruvboxTheme{}
7575
7676 // Base colors
77− theme.PrimaryColor = lipgloss.AdaptiveColor{
78− Dark: gruvboxDarkBlueBright,
79− Light: gruvboxLightBlueBright,
80− }
81− theme.SecondaryColor = lipgloss.AdaptiveColor{
82− Dark: gruvboxDarkPurpleBright,
83− Light: gruvboxLightPurpleBright,
84− }
85− theme.AccentColor = lipgloss.AdaptiveColor{
86− Dark: gruvboxDarkOrangeBright,
87− Light: gruvboxLightOrangeBright,
88− }
77+ theme.PrimaryColor = lipgloss.Color(gruvboxDarkBlueBright)
78+ theme.SecondaryColor = lipgloss.Color(gruvboxDarkPurpleBright)
79+ theme.AccentColor = lipgloss.Color(gruvboxDarkOrangeBright)
8980
9081 // Status colors
91− theme.ErrorColor = lipgloss.AdaptiveColor{
92− Dark: gruvboxDarkRedBright,
93− Light: gruvboxLightRedBright,
94− }
95− theme.WarningColor = lipgloss.AdaptiveColor{
96− Dark: gruvboxDarkYellowBright,
97− Light: gruvboxLightYellowBright,
98− }
99− theme.SuccessColor = lipgloss.AdaptiveColor{
100− Dark: gruvboxDarkGreenBright,
101− Light: gruvboxLightGreenBright,
102− }
103− theme.InfoColor = lipgloss.AdaptiveColor{
104− Dark: gruvboxDarkBlueBright,
105− Light: gruvboxLightBlueBright,
106− }
82+ theme.ErrorColor = lipgloss.Color(gruvboxDarkRedBright)
83+ theme.WarningColor = lipgloss.Color(gruvboxDarkYellowBright)
84+ theme.SuccessColor = lipgloss.Color(gruvboxDarkGreenBright)
85+ theme.InfoColor = lipgloss.Color(gruvboxDarkBlueBright)
10786
10887 // Text colors
109− theme.TextColor = lipgloss.AdaptiveColor{
110− Dark: gruvboxDarkFg1,
111− Light: gruvboxLightFg1,
112− }
113− theme.TextMutedColor = lipgloss.AdaptiveColor{
114− Dark: gruvboxDarkFg4,
115− Light: gruvboxLightFg4,
116− }
117− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
118− Dark: gruvboxDarkYellowBright,
119− Light: gruvboxLightYellowBright,
120− }
88+ theme.TextColor = lipgloss.Color(gruvboxDarkFg1)
89+ theme.TextMutedColor = lipgloss.Color(gruvboxDarkFg4)
90+ theme.TextEmphasizedColor = lipgloss.Color(gruvboxDarkYellowBright)
12191
12292 // Background colors
123− theme.BackgroundColor = lipgloss.AdaptiveColor{
124− Dark: gruvboxDarkBg0,
125− Light: gruvboxLightBg0,
126− }
127− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
128− Dark: gruvboxDarkBg1,
129− Light: gruvboxLightBg1,
130− }
131− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
132− Dark: gruvboxDarkBg0Soft,
133− Light: gruvboxLightBg0Soft,
134− }
93+ theme.BackgroundColor = lipgloss.Color(gruvboxDarkBg0)
94+ theme.BackgroundSecondaryColor = lipgloss.Color(gruvboxDarkBg1)
95+ theme.BackgroundDarkerColor = lipgloss.Color(gruvboxDarkBg0Soft)
13596
13697 // Border colors
137− theme.BorderNormalColor = lipgloss.AdaptiveColor{
138− Dark: gruvboxDarkBg2,
139− Light: gruvboxLightBg2,
140− }
141− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
142− Dark: gruvboxDarkBlueBright,
143− Light: gruvboxLightBlueBright,
144− }
145− theme.BorderDimColor = lipgloss.AdaptiveColor{
146− Dark: gruvboxDarkBg1,
147− Light: gruvboxLightBg1,
148− }
98+ theme.BorderNormalColor = lipgloss.Color(gruvboxDarkBg2)
99+ theme.BorderFocusedColor = lipgloss.Color(gruvboxDarkBlueBright)
100+ theme.BorderDimColor = lipgloss.Color(gruvboxDarkBg1)
149101
150102 // Diff view colors
151− theme.DiffAddedColor = lipgloss.AdaptiveColor{
152− Dark: gruvboxDarkGreenBright,
153− Light: gruvboxLightGreenBright,
154− }
155− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
156− Dark: gruvboxDarkRedBright,
157− Light: gruvboxLightRedBright,
158− }
159− theme.DiffContextColor = lipgloss.AdaptiveColor{
160− Dark: gruvboxDarkFg4,
161− Light: gruvboxLightFg4,
162− }
163− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
164− Dark: gruvboxDarkFg3,
165− Light: gruvboxLightFg3,
166− }
167− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
168− Dark: gruvboxDarkGreenBright,
169− Light: gruvboxLightGreenBright,
170− }
171− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
172− Dark: gruvboxDarkRedBright,
173− Light: gruvboxLightRedBright,
174− }
175− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
176− Dark: "#3C4C3C", // Darker green background
177− Light: "#E8F5E9", // Light green background
178− }
179− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
180− Dark: "#4C3C3C", // Darker red background
181− Light: "#FFEBEE", // Light red background
182− }
183− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
184− Dark: gruvboxDarkBg0,
185− Light: gruvboxLightBg0,
186− }
187− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
188− Dark: gruvboxDarkFg4,
189− Light: gruvboxLightFg4,
190− }
191− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
192− Dark: "#32432F", // Slightly darker green
193− Light: "#C8E6C9", // Light green
194− }
195− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
196− Dark: "#43322F", // Slightly darker red
197− Light: "#FFCDD2", // Light red
198− }
103+ theme.DiffAddedColor = lipgloss.Color(gruvboxDarkGreenBright)
104+ theme.DiffRemovedColor = lipgloss.Color(gruvboxDarkRedBright)
105+ theme.DiffContextColor = lipgloss.Color(gruvboxDarkFg4)
106+ theme.DiffHunkHeaderColor = lipgloss.Color(gruvboxDarkFg3)
107+ theme.DiffHighlightAddedColor = lipgloss.Color(gruvboxDarkGreenBright)
108+ theme.DiffHighlightRemovedColor = lipgloss.Color(gruvboxDarkRedBright)
109+ theme.DiffAddedBgColor = lipgloss.Color("#3C4C3C") // Darker green background
110+ theme.DiffRemovedBgColor = lipgloss.Color("#4C3C3C") // Darker red background
111+ theme.DiffContextBgColor = lipgloss.Color(gruvboxDarkBg0)
112+ theme.DiffLineNumberColor = lipgloss.Color(gruvboxDarkFg4)
113+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#32432F") // Slightly darker green
114+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#43322F") // Slightly darker red
199115
200116 // Markdown colors
201− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
202− Dark: gruvboxDarkFg1,
203− Light: gruvboxLightFg1,
204− }
205− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
206− Dark: gruvboxDarkYellowBright,
207− Light: gruvboxLightYellowBright,
208− }
209− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
210− Dark: gruvboxDarkBlueBright,
211− Light: gruvboxLightBlueBright,
212− }
213− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
214− Dark: gruvboxDarkAquaBright,
215− Light: gruvboxLightAquaBright,
216− }
217− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
218− Dark: gruvboxDarkGreenBright,
219− Light: gruvboxLightGreenBright,
220− }
221− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
222− Dark: gruvboxDarkAquaBright,
223− Light: gruvboxLightAquaBright,
224− }
225− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
226− Dark: gruvboxDarkYellowBright,
227− Light: gruvboxLightYellowBright,
228− }
229− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
230− Dark: gruvboxDarkOrangeBright,
231− Light: gruvboxLightOrangeBright,
232− }
233− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
234− Dark: gruvboxDarkBg3,
235− Light: gruvboxLightBg3,
236− }
237− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
238− Dark: gruvboxDarkBlueBright,
239− Light: gruvboxLightBlueBright,
240− }
241− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
242− Dark: gruvboxDarkBlueBright,
243− Light: gruvboxLightBlueBright,
244− }
245− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
246− Dark: gruvboxDarkPurpleBright,
247− Light: gruvboxLightPurpleBright,
248− }
249− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
250− Dark: gruvboxDarkAquaBright,
251− Light: gruvboxLightAquaBright,
252− }
253− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
254− Dark: gruvboxDarkFg1,
255− Light: gruvboxLightFg1,
256− }
117+ theme.MarkdownTextColor = lipgloss.Color(gruvboxDarkFg1)
118+ theme.MarkdownHeadingColor = lipgloss.Color(gruvboxDarkYellowBright)
119+ theme.MarkdownLinkColor = lipgloss.Color(gruvboxDarkBlueBright)
120+ theme.MarkdownLinkTextColor = lipgloss.Color(gruvboxDarkAquaBright)
121+ theme.MarkdownCodeColor = lipgloss.Color(gruvboxDarkGreenBright)
122+ theme.MarkdownBlockQuoteColor = lipgloss.Color(gruvboxDarkAquaBright)
123+ theme.MarkdownEmphColor = lipgloss.Color(gruvboxDarkYellowBright)
124+ theme.MarkdownStrongColor = lipgloss.Color(gruvboxDarkOrangeBright)
125+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(gruvboxDarkBg3)
126+ theme.MarkdownListItemColor = lipgloss.Color(gruvboxDarkBlueBright)
127+ theme.MarkdownListEnumerationColor = lipgloss.Color(gruvboxDarkBlueBright)
128+ theme.MarkdownImageColor = lipgloss.Color(gruvboxDarkPurpleBright)
129+ theme.MarkdownImageTextColor = lipgloss.Color(gruvboxDarkAquaBright)
130+ theme.MarkdownCodeBlockColor = lipgloss.Color(gruvboxDarkFg1)
257131
258132 // Syntax highlighting colors
259− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
260− Dark: gruvboxDarkGray,
261− Light: gruvboxLightGray,
262− }
263− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
264− Dark: gruvboxDarkRedBright,
265− Light: gruvboxLightRedBright,
266− }
267− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
268− Dark: gruvboxDarkGreenBright,
269− Light: gruvboxLightGreenBright,
270− }
271− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
272− Dark: gruvboxDarkBlueBright,
273− Light: gruvboxLightBlueBright,
274− }
275− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
276− Dark: gruvboxDarkYellowBright,
277− Light: gruvboxLightYellowBright,
278− }
279− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
280− Dark: gruvboxDarkPurpleBright,
281− Light: gruvboxLightPurpleBright,
282− }
283− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
284− Dark: gruvboxDarkYellow,
285− Light: gruvboxLightYellow,
286− }
287− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
288− Dark: gruvboxDarkAquaBright,
289− Light: gruvboxLightAquaBright,
290− }
291− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
292− Dark: gruvboxDarkFg1,
293− Light: gruvboxLightFg1,
294− }
133+ theme.SyntaxCommentColor = lipgloss.Color(gruvboxDarkGray)
134+ theme.SyntaxKeywordColor = lipgloss.Color(gruvboxDarkRedBright)
135+ theme.SyntaxFunctionColor = lipgloss.Color(gruvboxDarkGreenBright)
136+ theme.SyntaxVariableColor = lipgloss.Color(gruvboxDarkBlueBright)
137+ theme.SyntaxStringColor = lipgloss.Color(gruvboxDarkYellowBright)
138+ theme.SyntaxNumberColor = lipgloss.Color(gruvboxDarkPurpleBright)
139+ theme.SyntaxTypeColor = lipgloss.Color(gruvboxDarkYellow)
140+ theme.SyntaxOperatorColor = lipgloss.Color(gruvboxDarkAquaBright)
141+ theme.SyntaxPunctuationColor = lipgloss.Color(gruvboxDarkFg1)
142+
143+ return theme
144+}
145+
146+// NewGruvboxLightTheme creates a new instance of the Gruvbox Light theme.
147+func NewGruvboxLightTheme() *GruvboxTheme {
148+ theme := &GruvboxTheme{}
149+
150+ // Base colors
151+ theme.PrimaryColor = lipgloss.Color(gruvboxLightBlueBright)
152+ theme.SecondaryColor = lipgloss.Color(gruvboxLightPurpleBright)
153+ theme.AccentColor = lipgloss.Color(gruvboxLightOrangeBright)
154+
155+ // Status colors
156+ theme.ErrorColor = lipgloss.Color(gruvboxLightRedBright)
157+ theme.WarningColor = lipgloss.Color(gruvboxLightYellowBright)
158+ theme.SuccessColor = lipgloss.Color(gruvboxLightGreenBright)
159+ theme.InfoColor = lipgloss.Color(gruvboxLightBlueBright)
160+
161+ // Text colors
162+ theme.TextColor = lipgloss.Color(gruvboxLightFg1)
163+ theme.TextMutedColor = lipgloss.Color(gruvboxLightFg4)
164+ theme.TextEmphasizedColor = lipgloss.Color(gruvboxLightYellowBright)
165+
166+ // Background colors
167+ theme.BackgroundColor = lipgloss.Color(gruvboxLightBg0)
168+ theme.BackgroundSecondaryColor = lipgloss.Color(gruvboxLightBg1)
169+ theme.BackgroundDarkerColor = lipgloss.Color(gruvboxLightBg0Soft)
170+
171+ // Border colors
172+ theme.BorderNormalColor = lipgloss.Color(gruvboxLightBg2)
173+ theme.BorderFocusedColor = lipgloss.Color(gruvboxLightBlueBright)
174+ theme.BorderDimColor = lipgloss.Color(gruvboxLightBg1)
175+
176+ // Diff view colors
177+ theme.DiffAddedColor = lipgloss.Color(gruvboxLightGreenBright)
178+ theme.DiffRemovedColor = lipgloss.Color(gruvboxLightRedBright)
179+ theme.DiffContextColor = lipgloss.Color(gruvboxLightFg4)
180+ theme.DiffHunkHeaderColor = lipgloss.Color(gruvboxLightFg3)
181+ theme.DiffHighlightAddedColor = lipgloss.Color(gruvboxLightGreenBright)
182+ theme.DiffHighlightRemovedColor = lipgloss.Color(gruvboxLightRedBright)
183+ theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9") // Light green background
184+ theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE") // Light red background
185+ theme.DiffContextBgColor = lipgloss.Color(gruvboxLightBg0)
186+ theme.DiffLineNumberColor = lipgloss.Color(gruvboxLightFg4)
187+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9") // Light green
188+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2") // Light red
189+
190+ // Markdown colors
191+ theme.MarkdownTextColor = lipgloss.Color(gruvboxLightFg1)
192+ theme.MarkdownHeadingColor = lipgloss.Color(gruvboxLightYellowBright)
193+ theme.MarkdownLinkColor = lipgloss.Color(gruvboxLightBlueBright)
194+ theme.MarkdownLinkTextColor = lipgloss.Color(gruvboxLightAquaBright)
195+ theme.MarkdownCodeColor = lipgloss.Color(gruvboxLightGreenBright)
196+ theme.MarkdownBlockQuoteColor = lipgloss.Color(gruvboxLightAquaBright)
197+ theme.MarkdownEmphColor = lipgloss.Color(gruvboxLightYellowBright)
198+ theme.MarkdownStrongColor = lipgloss.Color(gruvboxLightOrangeBright)
199+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(gruvboxLightBg3)
200+ theme.MarkdownListItemColor = lipgloss.Color(gruvboxLightBlueBright)
201+ theme.MarkdownListEnumerationColor = lipgloss.Color(gruvboxLightBlueBright)
202+ theme.MarkdownImageColor = lipgloss.Color(gruvboxLightPurpleBright)
203+ theme.MarkdownImageTextColor = lipgloss.Color(gruvboxLightAquaBright)
204+ theme.MarkdownCodeBlockColor = lipgloss.Color(gruvboxLightFg1)
205+
206+ // Syntax highlighting colors
207+ theme.SyntaxCommentColor = lipgloss.Color(gruvboxLightGray)
208+ theme.SyntaxKeywordColor = lipgloss.Color(gruvboxLightRedBright)
209+ theme.SyntaxFunctionColor = lipgloss.Color(gruvboxLightGreenBright)
210+ theme.SyntaxVariableColor = lipgloss.Color(gruvboxLightBlueBright)
211+ theme.SyntaxStringColor = lipgloss.Color(gruvboxLightYellowBright)
212+ theme.SyntaxNumberColor = lipgloss.Color(gruvboxLightPurpleBright)
213+ theme.SyntaxTypeColor = lipgloss.Color(gruvboxLightYellow)
214+ theme.SyntaxOperatorColor = lipgloss.Color(gruvboxLightAquaBright)
215+ theme.SyntaxPunctuationColor = lipgloss.Color(gruvboxLightFg1)
295216
296217 return theme
297218}
298219
299220func init() {
300− // Register the Gruvbox theme with the theme manager
221+ // Register the Gruvbox themes with the theme manager
301222 RegisterTheme("gruvbox", NewGruvboxTheme())
223+ RegisterTheme("gruvbox-light", NewGruvboxLightTheme())
302224}
internal/tui/theme/monokai.go+128−206
@@ -1,7 +1,7 @@
11package theme
22
33import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
55)
66
77// MonokaiProTheme implements the Theme interface with Monokai Pro colors.
@@ -27,6 +27,80 @@ func NewMonokaiProTheme() *MonokaiProTheme {
2727 darkPurple := "#ab9df2"
2828 darkBorder := "#403e41"
2929
30+ theme := &MonokaiProTheme{}
31+
32+ // Base colors
33+ theme.PrimaryColor = lipgloss.Color(darkCyan)
34+ theme.SecondaryColor = lipgloss.Color(darkPurple)
35+ theme.AccentColor = lipgloss.Color(darkOrange)
36+
37+ // Status colors
38+ theme.ErrorColor = lipgloss.Color(darkRed)
39+ theme.WarningColor = lipgloss.Color(darkOrange)
40+ theme.SuccessColor = lipgloss.Color(darkGreen)
41+ theme.InfoColor = lipgloss.Color(darkBlue)
42+
43+ // Text colors
44+ theme.TextColor = lipgloss.Color(darkForeground)
45+ theme.TextMutedColor = lipgloss.Color(darkComment)
46+ theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
47+
48+ // Background colors
49+ theme.BackgroundColor = lipgloss.Color(darkBackground)
50+ theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
51+ theme.BackgroundDarkerColor = lipgloss.Color("#221f22") // Slightly darker than background
52+
53+ // Border colors
54+ theme.BorderNormalColor = lipgloss.Color(darkBorder)
55+ theme.BorderFocusedColor = lipgloss.Color(darkCyan)
56+ theme.BorderDimColor = lipgloss.Color(darkSelection)
57+
58+ // Diff view colors
59+ theme.DiffAddedColor = lipgloss.Color("#a9dc76")
60+ theme.DiffRemovedColor = lipgloss.Color("#ff6188")
61+ theme.DiffContextColor = lipgloss.Color("#a0a0a0")
62+ theme.DiffHunkHeaderColor = lipgloss.Color("#a0a0a0")
63+ theme.DiffHighlightAddedColor = lipgloss.Color("#c2e7a9")
64+ theme.DiffHighlightRemovedColor = lipgloss.Color("#ff8ca6")
65+ theme.DiffAddedBgColor = lipgloss.Color("#3a4a35")
66+ theme.DiffRemovedBgColor = lipgloss.Color("#4a3439")
67+ theme.DiffContextBgColor = lipgloss.Color(darkBackground)
68+ theme.DiffLineNumberColor = lipgloss.Color("#888888")
69+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#2d3a28")
70+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#3d2a2e")
71+
72+ // Markdown colors
73+ theme.MarkdownTextColor = lipgloss.Color(darkForeground)
74+ theme.MarkdownHeadingColor = lipgloss.Color(darkPurple)
75+ theme.MarkdownLinkColor = lipgloss.Color(darkCyan)
76+ theme.MarkdownLinkTextColor = lipgloss.Color(darkBlue)
77+ theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
78+ theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
79+ theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
80+ theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
81+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
82+ theme.MarkdownListItemColor = lipgloss.Color(darkCyan)
83+ theme.MarkdownListEnumerationColor = lipgloss.Color(darkBlue)
84+ theme.MarkdownImageColor = lipgloss.Color(darkCyan)
85+ theme.MarkdownImageTextColor = lipgloss.Color(darkBlue)
86+ theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
87+
88+ // Syntax highlighting colors
89+ theme.SyntaxCommentColor = lipgloss.Color(darkComment)
90+ theme.SyntaxKeywordColor = lipgloss.Color(darkRed)
91+ theme.SyntaxFunctionColor = lipgloss.Color(darkGreen)
92+ theme.SyntaxVariableColor = lipgloss.Color(darkForeground)
93+ theme.SyntaxStringColor = lipgloss.Color(darkYellow)
94+ theme.SyntaxNumberColor = lipgloss.Color(darkPurple)
95+ theme.SyntaxTypeColor = lipgloss.Color(darkBlue)
96+ theme.SyntaxOperatorColor = lipgloss.Color(darkCyan)
97+ theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
98+
99+ return theme
100+}
101+
102+// NewMonokaiProLightTheme creates a new instance of the Monokai Pro Light theme.
103+func NewMonokaiProLightTheme() *MonokaiProTheme {
30104 // Light mode colors (adapted from dark)
31105 lightBackground := "#fafafa"
32106 lightCurrentLine := "#f0f0f0"
@@ -45,229 +119,77 @@ func NewMonokaiProTheme() *MonokaiProTheme {
45119 theme := &MonokaiProTheme{}
46120
47121 // Base colors
48− theme.PrimaryColor = lipgloss.AdaptiveColor{
49− Dark: darkCyan,
50− Light: lightCyan,
51− }
52− theme.SecondaryColor = lipgloss.AdaptiveColor{
53− Dark: darkPurple,
54− Light: lightPurple,
55− }
56− theme.AccentColor = lipgloss.AdaptiveColor{
57− Dark: darkOrange,
58− Light: lightOrange,
59− }
122+ theme.PrimaryColor = lipgloss.Color(lightCyan)
123+ theme.SecondaryColor = lipgloss.Color(lightPurple)
124+ theme.AccentColor = lipgloss.Color(lightOrange)
60125
61126 // Status colors
62− theme.ErrorColor = lipgloss.AdaptiveColor{
63− Dark: darkRed,
64− Light: lightRed,
65− }
66− theme.WarningColor = lipgloss.AdaptiveColor{
67− Dark: darkOrange,
68− Light: lightOrange,
69− }
70− theme.SuccessColor = lipgloss.AdaptiveColor{
71− Dark: darkGreen,
72− Light: lightGreen,
73− }
74− theme.InfoColor = lipgloss.AdaptiveColor{
75− Dark: darkBlue,
76− Light: lightBlue,
77− }
127+ theme.ErrorColor = lipgloss.Color(lightRed)
128+ theme.WarningColor = lipgloss.Color(lightOrange)
129+ theme.SuccessColor = lipgloss.Color(lightGreen)
130+ theme.InfoColor = lipgloss.Color(lightBlue)
78131
79132 // Text colors
80− theme.TextColor = lipgloss.AdaptiveColor{
81− Dark: darkForeground,
82− Light: lightForeground,
83− }
84− theme.TextMutedColor = lipgloss.AdaptiveColor{
85− Dark: darkComment,
86− Light: lightComment,
87− }
88− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
89− Dark: darkYellow,
90− Light: lightYellow,
91− }
133+ theme.TextColor = lipgloss.Color(lightForeground)
134+ theme.TextMutedColor = lipgloss.Color(lightComment)
135+ theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
92136
93137 // Background colors
94− theme.BackgroundColor = lipgloss.AdaptiveColor{
95− Dark: darkBackground,
96− Light: lightBackground,
97− }
98− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
99− Dark: darkCurrentLine,
100− Light: lightCurrentLine,
101− }
102− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
103− Dark: "#221f22", // Slightly darker than background
104− Light: "#ffffff", // Slightly lighter than background
105− }
138+ theme.BackgroundColor = lipgloss.Color(lightBackground)
139+ theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
140+ theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
106141
107142 // Border colors
108− theme.BorderNormalColor = lipgloss.AdaptiveColor{
109− Dark: darkBorder,
110− Light: lightBorder,
111− }
112− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
113− Dark: darkCyan,
114− Light: lightCyan,
115− }
116− theme.BorderDimColor = lipgloss.AdaptiveColor{
117− Dark: darkSelection,
118− Light: lightSelection,
119− }
143+ theme.BorderNormalColor = lipgloss.Color(lightBorder)
144+ theme.BorderFocusedColor = lipgloss.Color(lightCyan)
145+ theme.BorderDimColor = lipgloss.Color(lightSelection)
120146
121147 // Diff view colors
122− theme.DiffAddedColor = lipgloss.AdaptiveColor{
123− Dark: "#a9dc76",
124− Light: "#9bca65",
125− }
126− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
127− Dark: "#ff6188",
128− Light: "#f92672",
129− }
130− theme.DiffContextColor = lipgloss.AdaptiveColor{
131− Dark: "#a0a0a0",
132− Light: "#757575",
133− }
134− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
135− Dark: "#a0a0a0",
136− Light: "#757575",
137− }
138− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
139− Dark: "#c2e7a9",
140− Light: "#c5e0b4",
141− }
142− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
143− Dark: "#ff8ca6",
144− Light: "#ffb3c8",
145− }
146− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
147− Dark: "#3a4a35",
148− Light: "#e8f5e9",
149− }
150− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
151− Dark: "#4a3439",
152− Light: "#ffebee",
153− }
154− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
155− Dark: darkBackground,
156− Light: lightBackground,
157− }
158− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
159− Dark: "#888888",
160− Light: "#9e9e9e",
161− }
162− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
163− Dark: "#2d3a28",
164− Light: "#c8e6c9",
165− }
166− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
167− Dark: "#3d2a2e",
168− Light: "#ffcdd2",
169− }
148+ theme.DiffAddedColor = lipgloss.Color("#9bca65")
149+ theme.DiffRemovedColor = lipgloss.Color("#f92672")
150+ theme.DiffContextColor = lipgloss.Color("#757575")
151+ theme.DiffHunkHeaderColor = lipgloss.Color("#757575")
152+ theme.DiffHighlightAddedColor = lipgloss.Color("#c5e0b4")
153+ theme.DiffHighlightRemovedColor = lipgloss.Color("#ffb3c8")
154+ theme.DiffAddedBgColor = lipgloss.Color("#e8f5e9")
155+ theme.DiffRemovedBgColor = lipgloss.Color("#ffebee")
156+ theme.DiffContextBgColor = lipgloss.Color(lightBackground)
157+ theme.DiffLineNumberColor = lipgloss.Color("#9e9e9e")
158+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#c8e6c9")
159+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#ffcdd2")
170160
171161 // Markdown colors
172− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
173− Dark: darkForeground,
174− Light: lightForeground,
175− }
176− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
177− Dark: darkPurple,
178− Light: lightPurple,
179− }
180− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
181− Dark: darkCyan,
182− Light: lightCyan,
183− }
184− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
185− Dark: darkBlue,
186− Light: lightBlue,
187− }
188− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
189− Dark: darkGreen,
190− Light: lightGreen,
191− }
192− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
193− Dark: darkYellow,
194− Light: lightYellow,
195− }
196− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
197− Dark: darkYellow,
198− Light: lightYellow,
199− }
200− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
201− Dark: darkOrange,
202− Light: lightOrange,
203− }
204− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
205− Dark: darkComment,
206− Light: lightComment,
207− }
208− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
209− Dark: darkCyan,
210− Light: lightCyan,
211− }
212− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
213− Dark: darkBlue,
214− Light: lightBlue,
215− }
216− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
217− Dark: darkCyan,
218− Light: lightCyan,
219− }
220− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
221− Dark: darkBlue,
222− Light: lightBlue,
223− }
224− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
225− Dark: darkForeground,
226− Light: lightForeground,
227− }
162+ theme.MarkdownTextColor = lipgloss.Color(lightForeground)
163+ theme.MarkdownHeadingColor = lipgloss.Color(lightPurple)
164+ theme.MarkdownLinkColor = lipgloss.Color(lightCyan)
165+ theme.MarkdownLinkTextColor = lipgloss.Color(lightBlue)
166+ theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
167+ theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
168+ theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
169+ theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
170+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
171+ theme.MarkdownListItemColor = lipgloss.Color(lightCyan)
172+ theme.MarkdownListEnumerationColor = lipgloss.Color(lightBlue)
173+ theme.MarkdownImageColor = lipgloss.Color(lightCyan)
174+ theme.MarkdownImageTextColor = lipgloss.Color(lightBlue)
175+ theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
228176
229177 // Syntax highlighting colors
230− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
231− Dark: darkComment,
232− Light: lightComment,
233− }
234− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
235− Dark: darkRed,
236− Light: lightRed,
237− }
238− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
239− Dark: darkGreen,
240− Light: lightGreen,
241− }
242− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
243− Dark: darkForeground,
244− Light: lightForeground,
245− }
246− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
247− Dark: darkYellow,
248− Light: lightYellow,
249− }
250− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
251− Dark: darkPurple,
252− Light: lightPurple,
253− }
254− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
255− Dark: darkBlue,
256− Light: lightBlue,
257− }
258− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
259− Dark: darkCyan,
260− Light: lightCyan,
261− }
262− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
263− Dark: darkForeground,
264− Light: lightForeground,
265− }
178+ theme.SyntaxCommentColor = lipgloss.Color(lightComment)
179+ theme.SyntaxKeywordColor = lipgloss.Color(lightRed)
180+ theme.SyntaxFunctionColor = lipgloss.Color(lightGreen)
181+ theme.SyntaxVariableColor = lipgloss.Color(lightForeground)
182+ theme.SyntaxStringColor = lipgloss.Color(lightYellow)
183+ theme.SyntaxNumberColor = lipgloss.Color(lightPurple)
184+ theme.SyntaxTypeColor = lipgloss.Color(lightBlue)
185+ theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
186+ theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
266187
267188 return theme
268189}
269190
270191func init() {
271− // Register the Monokai Pro theme with the theme manager
192+ // Register the Monokai Pro themes with the theme manager
272193 RegisterTheme("monokai", NewMonokaiProTheme())
194+ RegisterTheme("monokai-light", NewMonokaiProLightTheme())
273195}
internal/tui/theme/onedark.go+128−206
@@ -1,7 +1,7 @@
11package theme
22
33import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
55)
66
77// OneDarkTheme implements the Theme interface with Atom's One Dark colors.
@@ -28,6 +28,80 @@ func NewOneDarkTheme() *OneDarkTheme {
2828 darkPurple := "#c678dd"
2929 darkBorder := "#3b4048"
3030
31+ theme := &OneDarkTheme{}
32+
33+ // Base colors
34+ theme.PrimaryColor = lipgloss.Color(darkBlue)
35+ theme.SecondaryColor = lipgloss.Color(darkPurple)
36+ theme.AccentColor = lipgloss.Color(darkOrange)
37+
38+ // Status colors
39+ theme.ErrorColor = lipgloss.Color(darkRed)
40+ theme.WarningColor = lipgloss.Color(darkOrange)
41+ theme.SuccessColor = lipgloss.Color(darkGreen)
42+ theme.InfoColor = lipgloss.Color(darkBlue)
43+
44+ // Text colors
45+ theme.TextColor = lipgloss.Color(darkForeground)
46+ theme.TextMutedColor = lipgloss.Color(darkComment)
47+ theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
48+
49+ // Background colors
50+ theme.BackgroundColor = lipgloss.Color(darkBackground)
51+ theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
52+ theme.BackgroundDarkerColor = lipgloss.Color("#21252b") // Slightly darker than background
53+
54+ // Border colors
55+ theme.BorderNormalColor = lipgloss.Color(darkBorder)
56+ theme.BorderFocusedColor = lipgloss.Color(darkBlue)
57+ theme.BorderDimColor = lipgloss.Color(darkSelection)
58+
59+ // Diff view colors
60+ theme.DiffAddedColor = lipgloss.Color("#478247")
61+ theme.DiffRemovedColor = lipgloss.Color("#7C4444")
62+ theme.DiffContextColor = lipgloss.Color("#a0a0a0")
63+ theme.DiffHunkHeaderColor = lipgloss.Color("#a0a0a0")
64+ theme.DiffHighlightAddedColor = lipgloss.Color("#DAFADA")
65+ theme.DiffHighlightRemovedColor = lipgloss.Color("#FADADD")
66+ theme.DiffAddedBgColor = lipgloss.Color("#303A30")
67+ theme.DiffRemovedBgColor = lipgloss.Color("#3A3030")
68+ theme.DiffContextBgColor = lipgloss.Color(darkBackground)
69+ theme.DiffLineNumberColor = lipgloss.Color("#888888")
70+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#293229")
71+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#332929")
72+
73+ // Markdown colors
74+ theme.MarkdownTextColor = lipgloss.Color(darkForeground)
75+ theme.MarkdownHeadingColor = lipgloss.Color(darkPurple)
76+ theme.MarkdownLinkColor = lipgloss.Color(darkBlue)
77+ theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
78+ theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
79+ theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
80+ theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
81+ theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
82+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
83+ theme.MarkdownListItemColor = lipgloss.Color(darkBlue)
84+ theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
85+ theme.MarkdownImageColor = lipgloss.Color(darkBlue)
86+ theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
87+ theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
88+
89+ // Syntax highlighting colors
90+ theme.SyntaxCommentColor = lipgloss.Color(darkComment)
91+ theme.SyntaxKeywordColor = lipgloss.Color(darkPurple)
92+ theme.SyntaxFunctionColor = lipgloss.Color(darkBlue)
93+ theme.SyntaxVariableColor = lipgloss.Color(darkRed)
94+ theme.SyntaxStringColor = lipgloss.Color(darkGreen)
95+ theme.SyntaxNumberColor = lipgloss.Color(darkOrange)
96+ theme.SyntaxTypeColor = lipgloss.Color(darkYellow)
97+ theme.SyntaxOperatorColor = lipgloss.Color(darkCyan)
98+ theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
99+
100+ return theme
101+}
102+
103+// NewOneLightTheme creates a new instance of the One Light theme.
104+func NewOneLightTheme() *OneDarkTheme {
31105 // Light mode colors from Atom One Light
32106 lightBackground := "#fafafa"
33107 lightCurrentLine := "#f0f0f0"
@@ -46,229 +120,77 @@ func NewOneDarkTheme() *OneDarkTheme {
46120 theme := &OneDarkTheme{}
47121
48122 // Base colors
49− theme.PrimaryColor = lipgloss.AdaptiveColor{
50− Dark: darkBlue,
51− Light: lightBlue,
52− }
53− theme.SecondaryColor = lipgloss.AdaptiveColor{
54− Dark: darkPurple,
55− Light: lightPurple,
56− }
57− theme.AccentColor = lipgloss.AdaptiveColor{
58− Dark: darkOrange,
59− Light: lightOrange,
60− }
123+ theme.PrimaryColor = lipgloss.Color(lightBlue)
124+ theme.SecondaryColor = lipgloss.Color(lightPurple)
125+ theme.AccentColor = lipgloss.Color(lightOrange)
61126
62127 // Status colors
63− theme.ErrorColor = lipgloss.AdaptiveColor{
64− Dark: darkRed,
65− Light: lightRed,
66− }
67− theme.WarningColor = lipgloss.AdaptiveColor{
68− Dark: darkOrange,
69− Light: lightOrange,
70− }
71− theme.SuccessColor = lipgloss.AdaptiveColor{
72− Dark: darkGreen,
73− Light: lightGreen,
74− }
75− theme.InfoColor = lipgloss.AdaptiveColor{
76− Dark: darkBlue,
77− Light: lightBlue,
78− }
128+ theme.ErrorColor = lipgloss.Color(lightRed)
129+ theme.WarningColor = lipgloss.Color(lightOrange)
130+ theme.SuccessColor = lipgloss.Color(lightGreen)
131+ theme.InfoColor = lipgloss.Color(lightBlue)
79132
80133 // Text colors
81− theme.TextColor = lipgloss.AdaptiveColor{
82− Dark: darkForeground,
83− Light: lightForeground,
84− }
85− theme.TextMutedColor = lipgloss.AdaptiveColor{
86− Dark: darkComment,
87− Light: lightComment,
88− }
89− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
90− Dark: darkYellow,
91− Light: lightYellow,
92− }
134+ theme.TextColor = lipgloss.Color(lightForeground)
135+ theme.TextMutedColor = lipgloss.Color(lightComment)
136+ theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
93137
94138 // Background colors
95− theme.BackgroundColor = lipgloss.AdaptiveColor{
96− Dark: darkBackground,
97− Light: lightBackground,
98− }
99− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
100− Dark: darkCurrentLine,
101− Light: lightCurrentLine,
102− }
103− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
104− Dark: "#21252b", // Slightly darker than background
105− Light: "#ffffff", // Slightly lighter than background
106− }
139+ theme.BackgroundColor = lipgloss.Color(lightBackground)
140+ theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
141+ theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
107142
108143 // Border colors
109− theme.BorderNormalColor = lipgloss.AdaptiveColor{
110− Dark: darkBorder,
111− Light: lightBorder,
112− }
113− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
114− Dark: darkBlue,
115− Light: lightBlue,
116− }
117− theme.BorderDimColor = lipgloss.AdaptiveColor{
118− Dark: darkSelection,
119− Light: lightSelection,
120− }
144+ theme.BorderNormalColor = lipgloss.Color(lightBorder)
145+ theme.BorderFocusedColor = lipgloss.Color(lightBlue)
146+ theme.BorderDimColor = lipgloss.Color(lightSelection)
121147
122148 // Diff view colors
123− theme.DiffAddedColor = lipgloss.AdaptiveColor{
124− Dark: "#478247",
125− Light: "#2E7D32",
126− }
127− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
128− Dark: "#7C4444",
129− Light: "#C62828",
130− }
131− theme.DiffContextColor = lipgloss.AdaptiveColor{
132− Dark: "#a0a0a0",
133− Light: "#757575",
134− }
135− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
136− Dark: "#a0a0a0",
137− Light: "#757575",
138− }
139− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
140− Dark: "#DAFADA",
141− Light: "#A5D6A7",
142− }
143− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
144− Dark: "#FADADD",
145− Light: "#EF9A9A",
146− }
147− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
148− Dark: "#303A30",
149− Light: "#E8F5E9",
150− }
151− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
152− Dark: "#3A3030",
153− Light: "#FFEBEE",
154− }
155− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
156− Dark: darkBackground,
157− Light: lightBackground,
158− }
159− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
160− Dark: "#888888",
161− Light: "#9E9E9E",
162− }
163− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
164− Dark: "#293229",
165− Light: "#C8E6C9",
166− }
167− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
168− Dark: "#332929",
169− Light: "#FFCDD2",
170− }
149+ theme.DiffAddedColor = lipgloss.Color("#2E7D32")
150+ theme.DiffRemovedColor = lipgloss.Color("#C62828")
151+ theme.DiffContextColor = lipgloss.Color("#757575")
152+ theme.DiffHunkHeaderColor = lipgloss.Color("#757575")
153+ theme.DiffHighlightAddedColor = lipgloss.Color("#A5D6A7")
154+ theme.DiffHighlightRemovedColor = lipgloss.Color("#EF9A9A")
155+ theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9")
156+ theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE")
157+ theme.DiffContextBgColor = lipgloss.Color(lightBackground)
158+ theme.DiffLineNumberColor = lipgloss.Color("#9E9E9E")
159+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9")
160+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2")
171161
172162 // Markdown colors
173− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
174− Dark: darkForeground,
175− Light: lightForeground,
176− }
177− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
178− Dark: darkPurple,
179− Light: lightPurple,
180− }
181− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
182− Dark: darkBlue,
183− Light: lightBlue,
184− }
185− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
186− Dark: darkCyan,
187− Light: lightCyan,
188− }
189− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
190− Dark: darkGreen,
191− Light: lightGreen,
192− }
193− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
194− Dark: darkYellow,
195− Light: lightYellow,
196− }
197− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
198− Dark: darkYellow,
199− Light: lightYellow,
200− }
201− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
202− Dark: darkOrange,
203− Light: lightOrange,
204− }
205− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
206− Dark: darkComment,
207− Light: lightComment,
208− }
209− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
210− Dark: darkBlue,
211− Light: lightBlue,
212− }
213− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
214− Dark: darkCyan,
215− Light: lightCyan,
216− }
217− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
218− Dark: darkBlue,
219− Light: lightBlue,
220− }
221− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
222− Dark: darkCyan,
223− Light: lightCyan,
224− }
225− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
226− Dark: darkForeground,
227− Light: lightForeground,
228− }
163+ theme.MarkdownTextColor = lipgloss.Color(lightForeground)
164+ theme.MarkdownHeadingColor = lipgloss.Color(lightPurple)
165+ theme.MarkdownLinkColor = lipgloss.Color(lightBlue)
166+ theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
167+ theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
168+ theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
169+ theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
170+ theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
171+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
172+ theme.MarkdownListItemColor = lipgloss.Color(lightBlue)
173+ theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
174+ theme.MarkdownImageColor = lipgloss.Color(lightBlue)
175+ theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
176+ theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
229177
230178 // Syntax highlighting colors
231− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
232− Dark: darkComment,
233− Light: lightComment,
234− }
235− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
236− Dark: darkPurple,
237− Light: lightPurple,
238− }
239− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
240− Dark: darkBlue,
241− Light: lightBlue,
242− }
243− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
244− Dark: darkRed,
245− Light: lightRed,
246− }
247− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
248− Dark: darkGreen,
249− Light: lightGreen,
250− }
251− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
252− Dark: darkOrange,
253− Light: lightOrange,
254− }
255− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
256− Dark: darkYellow,
257− Light: lightYellow,
258− }
259− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
260− Dark: darkCyan,
261− Light: lightCyan,
262− }
263− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
264− Dark: darkForeground,
265− Light: lightForeground,
266− }
179+ theme.SyntaxCommentColor = lipgloss.Color(lightComment)
180+ theme.SyntaxKeywordColor = lipgloss.Color(lightPurple)
181+ theme.SyntaxFunctionColor = lipgloss.Color(lightBlue)
182+ theme.SyntaxVariableColor = lipgloss.Color(lightRed)
183+ theme.SyntaxStringColor = lipgloss.Color(lightGreen)
184+ theme.SyntaxNumberColor = lipgloss.Color(lightOrange)
185+ theme.SyntaxTypeColor = lipgloss.Color(lightYellow)
186+ theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
187+ theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
267188
268189 return theme
269190}
270191
271192func init() {
272− // Register the One Dark theme with the theme manager
193+ // Register the One Dark and One Light themes with the theme manager
273194 RegisterTheme("onedark", NewOneDarkTheme())
195+ RegisterTheme("onelight", NewOneLightTheme())
274196}
internal/tui/theme/opencode.go+132−211
@@ -1,7 +1,7 @@
11package theme
22
33import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
55)
66
77// OpenCodeTheme implements the Theme interface with OpenCode brand colors.
@@ -10,8 +10,8 @@ type OpenCodeTheme struct {
1010 BaseTheme
1111}
1212
13−// NewOpenCodeTheme creates a new instance of the OpenCode theme.
14−func NewOpenCodeTheme() *OpenCodeTheme {
13+// NewOpenCodeDarkTheme creates a new instance of the OpenCode Dark theme.
14+func NewOpenCodeDarkTheme() *OpenCodeTheme {
1515 // OpenCode color palette
1616 // Dark mode colors
1717 darkBackground := "#212121"
@@ -29,6 +29,80 @@ func NewOpenCodeTheme() *OpenCodeTheme {
2929 darkYellow := "#e5c07b" // Emphasized text
3030 darkBorder := "#4b4c5c" // Border color
3131
32+ theme := &OpenCodeTheme{}
33+
34+ // Base colors
35+ theme.PrimaryColor = lipgloss.Color(darkPrimary)
36+ theme.SecondaryColor = lipgloss.Color(darkSecondary)
37+ theme.AccentColor = lipgloss.Color(darkAccent)
38+
39+ // Status colors
40+ theme.ErrorColor = lipgloss.Color(darkRed)
41+ theme.WarningColor = lipgloss.Color(darkOrange)
42+ theme.SuccessColor = lipgloss.Color(darkGreen)
43+ theme.InfoColor = lipgloss.Color(darkCyan)
44+
45+ // Text colors
46+ theme.TextColor = lipgloss.Color(darkForeground)
47+ theme.TextMutedColor = lipgloss.Color(darkComment)
48+ theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
49+
50+ // Background colors
51+ theme.BackgroundColor = lipgloss.Color(darkBackground)
52+ theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
53+ theme.BackgroundDarkerColor = lipgloss.Color("#121212") // Slightly darker than background
54+
55+ // Border colors
56+ theme.BorderNormalColor = lipgloss.Color(darkBorder)
57+ theme.BorderFocusedColor = lipgloss.Color(darkPrimary)
58+ theme.BorderDimColor = lipgloss.Color(darkSelection)
59+
60+ // Diff view colors
61+ theme.DiffAddedColor = lipgloss.Color("#478247")
62+ theme.DiffRemovedColor = lipgloss.Color("#7C4444")
63+ theme.DiffContextColor = lipgloss.Color("#a0a0a0")
64+ theme.DiffHunkHeaderColor = lipgloss.Color("#a0a0a0")
65+ theme.DiffHighlightAddedColor = lipgloss.Color("#DAFADA")
66+ theme.DiffHighlightRemovedColor = lipgloss.Color("#FADADD")
67+ theme.DiffAddedBgColor = lipgloss.Color("#303A30")
68+ theme.DiffRemovedBgColor = lipgloss.Color("#3A3030")
69+ theme.DiffContextBgColor = lipgloss.Color(darkBackground)
70+ theme.DiffLineNumberColor = lipgloss.Color("#888888")
71+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#293229")
72+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#332929")
73+
74+ // Markdown colors
75+ theme.MarkdownTextColor = lipgloss.Color(darkForeground)
76+ theme.MarkdownHeadingColor = lipgloss.Color(darkSecondary)
77+ theme.MarkdownLinkColor = lipgloss.Color(darkPrimary)
78+ theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
79+ theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
80+ theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
81+ theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
82+ theme.MarkdownStrongColor = lipgloss.Color(darkAccent)
83+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
84+ theme.MarkdownListItemColor = lipgloss.Color(darkPrimary)
85+ theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
86+ theme.MarkdownImageColor = lipgloss.Color(darkPrimary)
87+ theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
88+ theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
89+
90+ // Syntax highlighting colors
91+ theme.SyntaxCommentColor = lipgloss.Color(darkComment)
92+ theme.SyntaxKeywordColor = lipgloss.Color(darkSecondary)
93+ theme.SyntaxFunctionColor = lipgloss.Color(darkPrimary)
94+ theme.SyntaxVariableColor = lipgloss.Color(darkRed)
95+ theme.SyntaxStringColor = lipgloss.Color(darkGreen)
96+ theme.SyntaxNumberColor = lipgloss.Color(darkAccent)
97+ theme.SyntaxTypeColor = lipgloss.Color(darkYellow)
98+ theme.SyntaxOperatorColor = lipgloss.Color(darkCyan)
99+ theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
100+
101+ return theme
102+}
103+
104+// NewOpenCodeLightTheme creates a new instance of the OpenCode Light theme.
105+func NewOpenCodeLightTheme() *OpenCodeTheme {
32106 // Light mode colors
33107 lightBackground := "#f8f8f8"
34108 lightCurrentLine := "#f0f0f0"
@@ -48,230 +122,77 @@ func NewOpenCodeTheme() *OpenCodeTheme {
48122 theme := &OpenCodeTheme{}
49123
50124 // Base colors
51− theme.PrimaryColor = lipgloss.AdaptiveColor{
52− Dark: darkPrimary,
53− Light: lightPrimary,
54− }
55− theme.SecondaryColor = lipgloss.AdaptiveColor{
56− Dark: darkSecondary,
57− Light: lightSecondary,
58− }
59− theme.AccentColor = lipgloss.AdaptiveColor{
60− Dark: darkAccent,
61− Light: lightAccent,
62− }
125+ theme.PrimaryColor = lipgloss.Color(lightPrimary)
126+ theme.SecondaryColor = lipgloss.Color(lightSecondary)
127+ theme.AccentColor = lipgloss.Color(lightAccent)
63128
64129 // Status colors
65− theme.ErrorColor = lipgloss.AdaptiveColor{
66− Dark: darkRed,
67− Light: lightRed,
68− }
69− theme.WarningColor = lipgloss.AdaptiveColor{
70− Dark: darkOrange,
71− Light: lightOrange,
72− }
73− theme.SuccessColor = lipgloss.AdaptiveColor{
74− Dark: darkGreen,
75− Light: lightGreen,
76− }
77− theme.InfoColor = lipgloss.AdaptiveColor{
78− Dark: darkCyan,
79− Light: lightCyan,
80− }
130+ theme.ErrorColor = lipgloss.Color(lightRed)
131+ theme.WarningColor = lipgloss.Color(lightOrange)
132+ theme.SuccessColor = lipgloss.Color(lightGreen)
133+ theme.InfoColor = lipgloss.Color(lightCyan)
81134
82135 // Text colors
83− theme.TextColor = lipgloss.AdaptiveColor{
84− Dark: darkForeground,
85− Light: lightForeground,
86− }
87− theme.TextMutedColor = lipgloss.AdaptiveColor{
88− Dark: darkComment,
89− Light: lightComment,
90− }
91− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
92− Dark: darkYellow,
93− Light: lightYellow,
94− }
136+ theme.TextColor = lipgloss.Color(lightForeground)
137+ theme.TextMutedColor = lipgloss.Color(lightComment)
138+ theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
95139
96140 // Background colors
97− theme.BackgroundColor = lipgloss.AdaptiveColor{
98− Dark: darkBackground,
99− Light: lightBackground,
100− }
101− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
102− Dark: darkCurrentLine,
103− Light: lightCurrentLine,
104− }
105− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
106− Dark: "#121212", // Slightly darker than background
107− Light: "#ffffff", // Slightly lighter than background
108− }
141+ theme.BackgroundColor = lipgloss.Color(lightBackground)
142+ theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
143+ theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
109144
110145 // Border colors
111− theme.BorderNormalColor = lipgloss.AdaptiveColor{
112− Dark: darkBorder,
113− Light: lightBorder,
114− }
115− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
116− Dark: darkPrimary,
117− Light: lightPrimary,
118− }
119− theme.BorderDimColor = lipgloss.AdaptiveColor{
120− Dark: darkSelection,
121− Light: lightSelection,
122− }
146+ theme.BorderNormalColor = lipgloss.Color(lightBorder)
147+ theme.BorderFocusedColor = lipgloss.Color(lightPrimary)
148+ theme.BorderDimColor = lipgloss.Color(lightSelection)
123149
124150 // Diff view colors
125− theme.DiffAddedColor = lipgloss.AdaptiveColor{
126− Dark: "#478247",
127− Light: "#2E7D32",
128− }
129− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
130− Dark: "#7C4444",
131− Light: "#C62828",
132− }
133− theme.DiffContextColor = lipgloss.AdaptiveColor{
134− Dark: "#a0a0a0",
135− Light: "#757575",
136− }
137− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
138− Dark: "#a0a0a0",
139− Light: "#757575",
140− }
141− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
142− Dark: "#DAFADA",
143− Light: "#A5D6A7",
144− }
145− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
146− Dark: "#FADADD",
147− Light: "#EF9A9A",
148− }
149− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
150− Dark: "#303A30",
151− Light: "#E8F5E9",
152− }
153− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
154− Dark: "#3A3030",
155− Light: "#FFEBEE",
156− }
157− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
158− Dark: darkBackground,
159− Light: lightBackground,
160− }
161− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
162− Dark: "#888888",
163− Light: "#9E9E9E",
164− }
165− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
166− Dark: "#293229",
167− Light: "#C8E6C9",
168− }
169− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
170− Dark: "#332929",
171− Light: "#FFCDD2",
172− }
151+ theme.DiffAddedColor = lipgloss.Color("#2E7D32")
152+ theme.DiffRemovedColor = lipgloss.Color("#C62828")
153+ theme.DiffContextColor = lipgloss.Color("#757575")
154+ theme.DiffHunkHeaderColor = lipgloss.Color("#757575")
155+ theme.DiffHighlightAddedColor = lipgloss.Color("#A5D6A7")
156+ theme.DiffHighlightRemovedColor = lipgloss.Color("#EF9A9A")
157+ theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9")
158+ theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE")
159+ theme.DiffContextBgColor = lipgloss.Color(lightBackground)
160+ theme.DiffLineNumberColor = lipgloss.Color("#9E9E9E")
161+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9")
162+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2")
173163
174164 // Markdown colors
175− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
176− Dark: darkForeground,
177− Light: lightForeground,
178− }
179− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
180− Dark: darkSecondary,
181− Light: lightSecondary,
182− }
183− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
184− Dark: darkPrimary,
185− Light: lightPrimary,
186− }
187− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
188− Dark: darkCyan,
189− Light: lightCyan,
190− }
191− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
192− Dark: darkGreen,
193− Light: lightGreen,
194− }
195− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
196− Dark: darkYellow,
197− Light: lightYellow,
198− }
199− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
200− Dark: darkYellow,
201− Light: lightYellow,
202− }
203− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
204− Dark: darkAccent,
205− Light: lightAccent,
206− }
207− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
208− Dark: darkComment,
209− Light: lightComment,
210− }
211− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
212− Dark: darkPrimary,
213− Light: lightPrimary,
214− }
215− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
216− Dark: darkCyan,
217− Light: lightCyan,
218− }
219− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
220− Dark: darkPrimary,
221− Light: lightPrimary,
222− }
223− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
224− Dark: darkCyan,
225− Light: lightCyan,
226− }
227− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
228− Dark: darkForeground,
229− Light: lightForeground,
230− }
165+ theme.MarkdownTextColor = lipgloss.Color(lightForeground)
166+ theme.MarkdownHeadingColor = lipgloss.Color(lightSecondary)
167+ theme.MarkdownLinkColor = lipgloss.Color(lightPrimary)
168+ theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
169+ theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
170+ theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
171+ theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
172+ theme.MarkdownStrongColor = lipgloss.Color(lightAccent)
173+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
174+ theme.MarkdownListItemColor = lipgloss.Color(lightPrimary)
175+ theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
176+ theme.MarkdownImageColor = lipgloss.Color(lightPrimary)
177+ theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
178+ theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
231179
232180 // Syntax highlighting colors
233− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
234− Dark: darkComment,
235− Light: lightComment,
236− }
237− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
238− Dark: darkSecondary,
239− Light: lightSecondary,
240− }
241− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
242− Dark: darkPrimary,
243− Light: lightPrimary,
244− }
245− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
246− Dark: darkRed,
247− Light: lightRed,
248− }
249− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
250− Dark: darkGreen,
251− Light: lightGreen,
252− }
253− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
254− Dark: darkAccent,
255− Light: lightAccent,
256− }
257− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
258− Dark: darkYellow,
259− Light: lightYellow,
260− }
261− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
262− Dark: darkCyan,
263− Light: lightCyan,
264− }
265− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
266− Dark: darkForeground,
267− Light: lightForeground,
268− }
181+ theme.SyntaxCommentColor = lipgloss.Color(lightComment)
182+ theme.SyntaxKeywordColor = lipgloss.Color(lightSecondary)
183+ theme.SyntaxFunctionColor = lipgloss.Color(lightPrimary)
184+ theme.SyntaxVariableColor = lipgloss.Color(lightRed)
185+ theme.SyntaxStringColor = lipgloss.Color(lightGreen)
186+ theme.SyntaxNumberColor = lipgloss.Color(lightAccent)
187+ theme.SyntaxTypeColor = lipgloss.Color(lightYellow)
188+ theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
189+ theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
269190
270191 return theme
271192}
272193
273194func init() {
274− // Register the OpenCode theme with the theme manager
275− RegisterTheme("opencode", NewOpenCodeTheme())
276−}
277−
195+ // Register the OpenCode themes with the theme manager
196+ RegisterTheme("opencode-dark", NewOpenCodeDarkTheme())
197+ RegisterTheme("opencode-light", NewOpenCodeLightTheme())
198+}
internal/tui/theme/theme.go+161−164
@@ -1,208 +1,205 @@
11package theme
22
33import (
4− "github.com/charmbracelet/lipgloss"
4+ "image/color"
55)
66
7−// Theme defines the interface for all UI themes in the application.
8−// All colors must be defined as lipgloss.AdaptiveColor to support
9−// both light and dark terminal backgrounds.
107type Theme interface {
118 // Base colors
12− Primary() lipgloss.AdaptiveColor
13− Secondary() lipgloss.AdaptiveColor
14− Accent() lipgloss.AdaptiveColor
9+ Primary() color.Color
10+ Secondary() color.Color
11+ Accent() color.Color
1512
1613 // Status colors
17− Error() lipgloss.AdaptiveColor
18− Warning() lipgloss.AdaptiveColor
19− Success() lipgloss.AdaptiveColor
20− Info() lipgloss.AdaptiveColor
14+ Error() color.Color
15+ Warning() color.Color
16+ Success() color.Color
17+ Info() color.Color
2118
2219 // Text colors
23− Text() lipgloss.AdaptiveColor
24− TextMuted() lipgloss.AdaptiveColor
25− TextEmphasized() lipgloss.AdaptiveColor
20+ Text() color.Color
21+ TextMuted() color.Color
22+ TextEmphasized() color.Color
2623
2724 // Background colors
28− Background() lipgloss.AdaptiveColor
29− BackgroundSecondary() lipgloss.AdaptiveColor
30− BackgroundDarker() lipgloss.AdaptiveColor
25+ Background() color.Color
26+ BackgroundSecondary() color.Color
27+ BackgroundDarker() color.Color
3128
3229 // Border colors
33− BorderNormal() lipgloss.AdaptiveColor
34− BorderFocused() lipgloss.AdaptiveColor
35− BorderDim() lipgloss.AdaptiveColor
30+ BorderNormal() color.Color
31+ BorderFocused() color.Color
32+ BorderDim() color.Color
3633
3734 // Diff view colors
38− DiffAdded() lipgloss.AdaptiveColor
39− DiffRemoved() lipgloss.AdaptiveColor
40− DiffContext() lipgloss.AdaptiveColor
41− DiffHunkHeader() lipgloss.AdaptiveColor
42− DiffHighlightAdded() lipgloss.AdaptiveColor
43− DiffHighlightRemoved() lipgloss.AdaptiveColor
44− DiffAddedBg() lipgloss.AdaptiveColor
45− DiffRemovedBg() lipgloss.AdaptiveColor
46− DiffContextBg() lipgloss.AdaptiveColor
47− DiffLineNumber() lipgloss.AdaptiveColor
48− DiffAddedLineNumberBg() lipgloss.AdaptiveColor
49− DiffRemovedLineNumberBg() lipgloss.AdaptiveColor
35+ DiffAdded() color.Color
36+ DiffRemoved() color.Color
37+ DiffContext() color.Color
38+ DiffHunkHeader() color.Color
39+ DiffHighlightAdded() color.Color
40+ DiffHighlightRemoved() color.Color
41+ DiffAddedBg() color.Color
42+ DiffRemovedBg() color.Color
43+ DiffContextBg() color.Color
44+ DiffLineNumber() color.Color
45+ DiffAddedLineNumberBg() color.Color
46+ DiffRemovedLineNumberBg() color.Color
5047
5148 // Markdown colors
52− MarkdownText() lipgloss.AdaptiveColor
53− MarkdownHeading() lipgloss.AdaptiveColor
54− MarkdownLink() lipgloss.AdaptiveColor
55− MarkdownLinkText() lipgloss.AdaptiveColor
56− MarkdownCode() lipgloss.AdaptiveColor
57− MarkdownBlockQuote() lipgloss.AdaptiveColor
58− MarkdownEmph() lipgloss.AdaptiveColor
59− MarkdownStrong() lipgloss.AdaptiveColor
60− MarkdownHorizontalRule() lipgloss.AdaptiveColor
61− MarkdownListItem() lipgloss.AdaptiveColor
62− MarkdownListEnumeration() lipgloss.AdaptiveColor
63− MarkdownImage() lipgloss.AdaptiveColor
64− MarkdownImageText() lipgloss.AdaptiveColor
65− MarkdownCodeBlock() lipgloss.AdaptiveColor
49+ MarkdownText() color.Color
50+ MarkdownHeading() color.Color
51+ MarkdownLink() color.Color
52+ MarkdownLinkText() color.Color
53+ MarkdownCode() color.Color
54+ MarkdownBlockQuote() color.Color
55+ MarkdownEmph() color.Color
56+ MarkdownStrong() color.Color
57+ MarkdownHorizontalRule() color.Color
58+ MarkdownListItem() color.Color
59+ MarkdownListEnumeration() color.Color
60+ MarkdownImage() color.Color
61+ MarkdownImageText() color.Color
62+ MarkdownCodeBlock() color.Color
6663
6764 // Syntax highlighting colors
68− SyntaxComment() lipgloss.AdaptiveColor
69− SyntaxKeyword() lipgloss.AdaptiveColor
70− SyntaxFunction() lipgloss.AdaptiveColor
71− SyntaxVariable() lipgloss.AdaptiveColor
72− SyntaxString() lipgloss.AdaptiveColor
73− SyntaxNumber() lipgloss.AdaptiveColor
74− SyntaxType() lipgloss.AdaptiveColor
75− SyntaxOperator() lipgloss.AdaptiveColor
76− SyntaxPunctuation() lipgloss.AdaptiveColor
65+ SyntaxComment() color.Color
66+ SyntaxKeyword() color.Color
67+ SyntaxFunction() color.Color
68+ SyntaxVariable() color.Color
69+ SyntaxString() color.Color
70+ SyntaxNumber() color.Color
71+ SyntaxType() color.Color
72+ SyntaxOperator() color.Color
73+ SyntaxPunctuation() color.Color
7774}
7875
7976// BaseTheme provides a default implementation of the Theme interface
8077// that can be embedded in concrete theme implementations.
8178type BaseTheme struct {
8279 // Base colors
83− PrimaryColor lipgloss.AdaptiveColor
84− SecondaryColor lipgloss.AdaptiveColor
85− AccentColor lipgloss.AdaptiveColor
80+ PrimaryColor color.Color
81+ SecondaryColor color.Color
82+ AccentColor color.Color
8683
8784 // Status colors
88− ErrorColor lipgloss.AdaptiveColor
89− WarningColor lipgloss.AdaptiveColor
90− SuccessColor lipgloss.AdaptiveColor
91− InfoColor lipgloss.AdaptiveColor
85+ ErrorColor color.Color
86+ WarningColor color.Color
87+ SuccessColor color.Color
88+ InfoColor color.Color
9289
9390 // Text colors
94− TextColor lipgloss.AdaptiveColor
95− TextMutedColor lipgloss.AdaptiveColor
96− TextEmphasizedColor lipgloss.AdaptiveColor
91+ TextColor color.Color
92+ TextMutedColor color.Color
93+ TextEmphasizedColor color.Color
9794
9895 // Background colors
99− BackgroundColor lipgloss.AdaptiveColor
100− BackgroundSecondaryColor lipgloss.AdaptiveColor
101− BackgroundDarkerColor lipgloss.AdaptiveColor
96+ BackgroundColor color.Color
97+ BackgroundSecondaryColor color.Color
98+ BackgroundDarkerColor color.Color
10299
103100 // Border colors
104− BorderNormalColor lipgloss.AdaptiveColor
105− BorderFocusedColor lipgloss.AdaptiveColor
106− BorderDimColor lipgloss.AdaptiveColor
101+ BorderNormalColor color.Color
102+ BorderFocusedColor color.Color
103+ BorderDimColor color.Color
107104
108105 // Diff view colors
109− DiffAddedColor lipgloss.AdaptiveColor
110− DiffRemovedColor lipgloss.AdaptiveColor
111− DiffContextColor lipgloss.AdaptiveColor
112− DiffHunkHeaderColor lipgloss.AdaptiveColor
113− DiffHighlightAddedColor lipgloss.AdaptiveColor
114− DiffHighlightRemovedColor lipgloss.AdaptiveColor
115− DiffAddedBgColor lipgloss.AdaptiveColor
116− DiffRemovedBgColor lipgloss.AdaptiveColor
117− DiffContextBgColor lipgloss.AdaptiveColor
118− DiffLineNumberColor lipgloss.AdaptiveColor
119− DiffAddedLineNumberBgColor lipgloss.AdaptiveColor
120− DiffRemovedLineNumberBgColor lipgloss.AdaptiveColor
106+ DiffAddedColor color.Color
107+ DiffRemovedColor color.Color
108+ DiffContextColor color.Color
109+ DiffHunkHeaderColor color.Color
110+ DiffHighlightAddedColor color.Color
111+ DiffHighlightRemovedColor color.Color
112+ DiffAddedBgColor color.Color
113+ DiffRemovedBgColor color.Color
114+ DiffContextBgColor color.Color
115+ DiffLineNumberColor color.Color
116+ DiffAddedLineNumberBgColor color.Color
117+ DiffRemovedLineNumberBgColor color.Color
121118
122119 // Markdown colors
123− MarkdownTextColor lipgloss.AdaptiveColor
124− MarkdownHeadingColor lipgloss.AdaptiveColor
125− MarkdownLinkColor lipgloss.AdaptiveColor
126− MarkdownLinkTextColor lipgloss.AdaptiveColor
127− MarkdownCodeColor lipgloss.AdaptiveColor
128− MarkdownBlockQuoteColor lipgloss.AdaptiveColor
129− MarkdownEmphColor lipgloss.AdaptiveColor
130− MarkdownStrongColor lipgloss.AdaptiveColor
131− MarkdownHorizontalRuleColor lipgloss.AdaptiveColor
132− MarkdownListItemColor lipgloss.AdaptiveColor
133− MarkdownListEnumerationColor lipgloss.AdaptiveColor
134− MarkdownImageColor lipgloss.AdaptiveColor
135− MarkdownImageTextColor lipgloss.AdaptiveColor
136− MarkdownCodeBlockColor lipgloss.AdaptiveColor
120+ MarkdownTextColor color.Color
121+ MarkdownHeadingColor color.Color
122+ MarkdownLinkColor color.Color
123+ MarkdownLinkTextColor color.Color
124+ MarkdownCodeColor color.Color
125+ MarkdownBlockQuoteColor color.Color
126+ MarkdownEmphColor color.Color
127+ MarkdownStrongColor color.Color
128+ MarkdownHorizontalRuleColor color.Color
129+ MarkdownListItemColor color.Color
130+ MarkdownListEnumerationColor color.Color
131+ MarkdownImageColor color.Color
132+ MarkdownImageTextColor color.Color
133+ MarkdownCodeBlockColor color.Color
137134
138135 // Syntax highlighting colors
139− SyntaxCommentColor lipgloss.AdaptiveColor
140− SyntaxKeywordColor lipgloss.AdaptiveColor
141− SyntaxFunctionColor lipgloss.AdaptiveColor
142− SyntaxVariableColor lipgloss.AdaptiveColor
143− SyntaxStringColor lipgloss.AdaptiveColor
144− SyntaxNumberColor lipgloss.AdaptiveColor
145− SyntaxTypeColor lipgloss.AdaptiveColor
146− SyntaxOperatorColor lipgloss.AdaptiveColor
147− SyntaxPunctuationColor lipgloss.AdaptiveColor
136+ SyntaxCommentColor color.Color
137+ SyntaxKeywordColor color.Color
138+ SyntaxFunctionColor color.Color
139+ SyntaxVariableColor color.Color
140+ SyntaxStringColor color.Color
141+ SyntaxNumberColor color.Color
142+ SyntaxTypeColor color.Color
143+ SyntaxOperatorColor color.Color
144+ SyntaxPunctuationColor color.Color
148145}
149146
150147// Implement the Theme interface for BaseTheme
151−func (t *BaseTheme) Primary() lipgloss.AdaptiveColor { return t.PrimaryColor }
152−func (t *BaseTheme) Secondary() lipgloss.AdaptiveColor { return t.SecondaryColor }
153−func (t *BaseTheme) Accent() lipgloss.AdaptiveColor { return t.AccentColor }
154−
155−func (t *BaseTheme) Error() lipgloss.AdaptiveColor { return t.ErrorColor }
156−func (t *BaseTheme) Warning() lipgloss.AdaptiveColor { return t.WarningColor }
157−func (t *BaseTheme) Success() lipgloss.AdaptiveColor { return t.SuccessColor }
158−func (t *BaseTheme) Info() lipgloss.AdaptiveColor { return t.InfoColor }
159−
160−func (t *BaseTheme) Text() lipgloss.AdaptiveColor { return t.TextColor }
161−func (t *BaseTheme) TextMuted() lipgloss.AdaptiveColor { return t.TextMutedColor }
162−func (t *BaseTheme) TextEmphasized() lipgloss.AdaptiveColor { return t.TextEmphasizedColor }
163−
164−func (t *BaseTheme) Background() lipgloss.AdaptiveColor { return t.BackgroundColor }
165−func (t *BaseTheme) BackgroundSecondary() lipgloss.AdaptiveColor { return t.BackgroundSecondaryColor }
166−func (t *BaseTheme) BackgroundDarker() lipgloss.AdaptiveColor { return t.BackgroundDarkerColor }
167−
168−func (t *BaseTheme) BorderNormal() lipgloss.AdaptiveColor { return t.BorderNormalColor }
169−func (t *BaseTheme) BorderFocused() lipgloss.AdaptiveColor { return t.BorderFocusedColor }
170−func (t *BaseTheme) BorderDim() lipgloss.AdaptiveColor { return t.BorderDimColor }
171−
172−func (t *BaseTheme) DiffAdded() lipgloss.AdaptiveColor { return t.DiffAddedColor }
173−func (t *BaseTheme) DiffRemoved() lipgloss.AdaptiveColor { return t.DiffRemovedColor }
174−func (t *BaseTheme) DiffContext() lipgloss.AdaptiveColor { return t.DiffContextColor }
175−func (t *BaseTheme) DiffHunkHeader() lipgloss.AdaptiveColor { return t.DiffHunkHeaderColor }
176−func (t *BaseTheme) DiffHighlightAdded() lipgloss.AdaptiveColor { return t.DiffHighlightAddedColor }
177−func (t *BaseTheme) DiffHighlightRemoved() lipgloss.AdaptiveColor { return t.DiffHighlightRemovedColor }
178−func (t *BaseTheme) DiffAddedBg() lipgloss.AdaptiveColor { return t.DiffAddedBgColor }
179−func (t *BaseTheme) DiffRemovedBg() lipgloss.AdaptiveColor { return t.DiffRemovedBgColor }
180−func (t *BaseTheme) DiffContextBg() lipgloss.AdaptiveColor { return t.DiffContextBgColor }
181−func (t *BaseTheme) DiffLineNumber() lipgloss.AdaptiveColor { return t.DiffLineNumberColor }
182−func (t *BaseTheme) DiffAddedLineNumberBg() lipgloss.AdaptiveColor { return t.DiffAddedLineNumberBgColor }
183−func (t *BaseTheme) DiffRemovedLineNumberBg() lipgloss.AdaptiveColor { return t.DiffRemovedLineNumberBgColor }
184−
185−func (t *BaseTheme) MarkdownText() lipgloss.AdaptiveColor { return t.MarkdownTextColor }
186−func (t *BaseTheme) MarkdownHeading() lipgloss.AdaptiveColor { return t.MarkdownHeadingColor }
187−func (t *BaseTheme) MarkdownLink() lipgloss.AdaptiveColor { return t.MarkdownLinkColor }
188−func (t *BaseTheme) MarkdownLinkText() lipgloss.AdaptiveColor { return t.MarkdownLinkTextColor }
189−func (t *BaseTheme) MarkdownCode() lipgloss.AdaptiveColor { return t.MarkdownCodeColor }
190−func (t *BaseTheme) MarkdownBlockQuote() lipgloss.AdaptiveColor { return t.MarkdownBlockQuoteColor }
191−func (t *BaseTheme) MarkdownEmph() lipgloss.AdaptiveColor { return t.MarkdownEmphColor }
192−func (t *BaseTheme) MarkdownStrong() lipgloss.AdaptiveColor { return t.MarkdownStrongColor }
193−func (t *BaseTheme) MarkdownHorizontalRule() lipgloss.AdaptiveColor { return t.MarkdownHorizontalRuleColor }
194−func (t *BaseTheme) MarkdownListItem() lipgloss.AdaptiveColor { return t.MarkdownListItemColor }
195−func (t *BaseTheme) MarkdownListEnumeration() lipgloss.AdaptiveColor { return t.MarkdownListEnumerationColor }
196−func (t *BaseTheme) MarkdownImage() lipgloss.AdaptiveColor { return t.MarkdownImageColor }
197−func (t *BaseTheme) MarkdownImageText() lipgloss.AdaptiveColor { return t.MarkdownImageTextColor }
198−func (t *BaseTheme) MarkdownCodeBlock() lipgloss.AdaptiveColor { return t.MarkdownCodeBlockColor }
199−
200−func (t *BaseTheme) SyntaxComment() lipgloss.AdaptiveColor { return t.SyntaxCommentColor }
201−func (t *BaseTheme) SyntaxKeyword() lipgloss.AdaptiveColor { return t.SyntaxKeywordColor }
202−func (t *BaseTheme) SyntaxFunction() lipgloss.AdaptiveColor { return t.SyntaxFunctionColor }
203−func (t *BaseTheme) SyntaxVariable() lipgloss.AdaptiveColor { return t.SyntaxVariableColor }
204−func (t *BaseTheme) SyntaxString() lipgloss.AdaptiveColor { return t.SyntaxStringColor }
205−func (t *BaseTheme) SyntaxNumber() lipgloss.AdaptiveColor { return t.SyntaxNumberColor }
206−func (t *BaseTheme) SyntaxType() lipgloss.AdaptiveColor { return t.SyntaxTypeColor }
207−func (t *BaseTheme) SyntaxOperator() lipgloss.AdaptiveColor { return t.SyntaxOperatorColor }
208−func (t *BaseTheme) SyntaxPunctuation() lipgloss.AdaptiveColor { return t.SyntaxPunctuationColor }
148+func (t *BaseTheme) Primary() color.Color { return t.PrimaryColor }
149+func (t *BaseTheme) Secondary() color.Color { return t.SecondaryColor }
150+func (t *BaseTheme) Accent() color.Color { return t.AccentColor }
151+
152+func (t *BaseTheme) Error() color.Color { return t.ErrorColor }
153+func (t *BaseTheme) Warning() color.Color { return t.WarningColor }
154+func (t *BaseTheme) Success() color.Color { return t.SuccessColor }
155+func (t *BaseTheme) Info() color.Color { return t.InfoColor }
156+
157+func (t *BaseTheme) Text() color.Color { return t.TextColor }
158+func (t *BaseTheme) TextMuted() color.Color { return t.TextMutedColor }
159+func (t *BaseTheme) TextEmphasized() color.Color { return t.TextEmphasizedColor }
160+
161+func (t *BaseTheme) Background() color.Color { return t.BackgroundColor }
162+func (t *BaseTheme) BackgroundSecondary() color.Color { return t.BackgroundSecondaryColor }
163+func (t *BaseTheme) BackgroundDarker() color.Color { return t.BackgroundDarkerColor }
164+
165+func (t *BaseTheme) BorderNormal() color.Color { return t.BorderNormalColor }
166+func (t *BaseTheme) BorderFocused() color.Color { return t.BorderFocusedColor }
167+func (t *BaseTheme) BorderDim() color.Color { return t.BorderDimColor }
168+
169+func (t *BaseTheme) DiffAdded() color.Color { return t.DiffAddedColor }
170+func (t *BaseTheme) DiffRemoved() color.Color { return t.DiffRemovedColor }
171+func (t *BaseTheme) DiffContext() color.Color { return t.DiffContextColor }
172+func (t *BaseTheme) DiffHunkHeader() color.Color { return t.DiffHunkHeaderColor }
173+func (t *BaseTheme) DiffHighlightAdded() color.Color { return t.DiffHighlightAddedColor }
174+func (t *BaseTheme) DiffHighlightRemoved() color.Color { return t.DiffHighlightRemovedColor }
175+func (t *BaseTheme) DiffAddedBg() color.Color { return t.DiffAddedBgColor }
176+func (t *BaseTheme) DiffRemovedBg() color.Color { return t.DiffRemovedBgColor }
177+func (t *BaseTheme) DiffContextBg() color.Color { return t.DiffContextBgColor }
178+func (t *BaseTheme) DiffLineNumber() color.Color { return t.DiffLineNumberColor }
179+func (t *BaseTheme) DiffAddedLineNumberBg() color.Color { return t.DiffAddedLineNumberBgColor }
180+func (t *BaseTheme) DiffRemovedLineNumberBg() color.Color { return t.DiffRemovedLineNumberBgColor }
181+
182+func (t *BaseTheme) MarkdownText() color.Color { return t.MarkdownTextColor }
183+func (t *BaseTheme) MarkdownHeading() color.Color { return t.MarkdownHeadingColor }
184+func (t *BaseTheme) MarkdownLink() color.Color { return t.MarkdownLinkColor }
185+func (t *BaseTheme) MarkdownLinkText() color.Color { return t.MarkdownLinkTextColor }
186+func (t *BaseTheme) MarkdownCode() color.Color { return t.MarkdownCodeColor }
187+func (t *BaseTheme) MarkdownBlockQuote() color.Color { return t.MarkdownBlockQuoteColor }
188+func (t *BaseTheme) MarkdownEmph() color.Color { return t.MarkdownEmphColor }
189+func (t *BaseTheme) MarkdownStrong() color.Color { return t.MarkdownStrongColor }
190+func (t *BaseTheme) MarkdownHorizontalRule() color.Color { return t.MarkdownHorizontalRuleColor }
191+func (t *BaseTheme) MarkdownListItem() color.Color { return t.MarkdownListItemColor }
192+func (t *BaseTheme) MarkdownListEnumeration() color.Color { return t.MarkdownListEnumerationColor }
193+func (t *BaseTheme) MarkdownImage() color.Color { return t.MarkdownImageColor }
194+func (t *BaseTheme) MarkdownImageText() color.Color { return t.MarkdownImageTextColor }
195+func (t *BaseTheme) MarkdownCodeBlock() color.Color { return t.MarkdownCodeBlockColor }
196+
197+func (t *BaseTheme) SyntaxComment() color.Color { return t.SyntaxCommentColor }
198+func (t *BaseTheme) SyntaxKeyword() color.Color { return t.SyntaxKeywordColor }
199+func (t *BaseTheme) SyntaxFunction() color.Color { return t.SyntaxFunctionColor }
200+func (t *BaseTheme) SyntaxVariable() color.Color { return t.SyntaxVariableColor }
201+func (t *BaseTheme) SyntaxString() color.Color { return t.SyntaxStringColor }
202+func (t *BaseTheme) SyntaxNumber() color.Color { return t.SyntaxNumberColor }
203+func (t *BaseTheme) SyntaxType() color.Color { return t.SyntaxTypeColor }
204+func (t *BaseTheme) SyntaxOperator() color.Color { return t.SyntaxOperatorColor }
205+func (t *BaseTheme) SyntaxPunctuation() color.Color { return t.SyntaxPunctuationColor }
internal/tui/theme/tokyonight.go+128−206
@@ -1,7 +1,7 @@
11package theme
22
33import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
55)
66
77// TokyoNightTheme implements the Theme interface with Tokyo Night colors.
@@ -28,6 +28,80 @@ func NewTokyoNightTheme() *TokyoNightTheme {
2828 darkPurple := "#c099ff"
2929 darkBorder := "#3b4261"
3030
31+ theme := &TokyoNightTheme{}
32+
33+ // Base colors
34+ theme.PrimaryColor = lipgloss.Color(darkBlue)
35+ theme.SecondaryColor = lipgloss.Color(darkPurple)
36+ theme.AccentColor = lipgloss.Color(darkOrange)
37+
38+ // Status colors
39+ theme.ErrorColor = lipgloss.Color(darkRed)
40+ theme.WarningColor = lipgloss.Color(darkOrange)
41+ theme.SuccessColor = lipgloss.Color(darkGreen)
42+ theme.InfoColor = lipgloss.Color(darkBlue)
43+
44+ // Text colors
45+ theme.TextColor = lipgloss.Color(darkForeground)
46+ theme.TextMutedColor = lipgloss.Color(darkComment)
47+ theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
48+
49+ // Background colors
50+ theme.BackgroundColor = lipgloss.Color(darkBackground)
51+ theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
52+ theme.BackgroundDarkerColor = lipgloss.Color("#191B29") // Darker background from palette
53+
54+ // Border colors
55+ theme.BorderNormalColor = lipgloss.Color(darkBorder)
56+ theme.BorderFocusedColor = lipgloss.Color(darkBlue)
57+ theme.BorderDimColor = lipgloss.Color(darkSelection)
58+
59+ // Diff view colors
60+ theme.DiffAddedColor = lipgloss.Color("#4fd6be") // teal from palette
61+ theme.DiffRemovedColor = lipgloss.Color("#c53b53") // red1 from palette
62+ theme.DiffContextColor = lipgloss.Color("#828bb8") // fg_dark from palette
63+ theme.DiffHunkHeaderColor = lipgloss.Color("#828bb8") // fg_dark from palette
64+ theme.DiffHighlightAddedColor = lipgloss.Color("#b8db87") // git.add from palette
65+ theme.DiffHighlightRemovedColor = lipgloss.Color("#e26a75") // git.delete from palette
66+ theme.DiffAddedBgColor = lipgloss.Color("#20303b")
67+ theme.DiffRemovedBgColor = lipgloss.Color("#37222c")
68+ theme.DiffContextBgColor = lipgloss.Color(darkBackground)
69+ theme.DiffLineNumberColor = lipgloss.Color("#545c7e") // dark3 from palette
70+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#1b2b34")
71+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#2d1f26")
72+
73+ // Markdown colors
74+ theme.MarkdownTextColor = lipgloss.Color(darkForeground)
75+ theme.MarkdownHeadingColor = lipgloss.Color(darkPurple)
76+ theme.MarkdownLinkColor = lipgloss.Color(darkBlue)
77+ theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
78+ theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
79+ theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
80+ theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
81+ theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
82+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
83+ theme.MarkdownListItemColor = lipgloss.Color(darkBlue)
84+ theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
85+ theme.MarkdownImageColor = lipgloss.Color(darkBlue)
86+ theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
87+ theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
88+
89+ // Syntax highlighting colors
90+ theme.SyntaxCommentColor = lipgloss.Color(darkComment)
91+ theme.SyntaxKeywordColor = lipgloss.Color(darkPurple)
92+ theme.SyntaxFunctionColor = lipgloss.Color(darkBlue)
93+ theme.SyntaxVariableColor = lipgloss.Color(darkRed)
94+ theme.SyntaxStringColor = lipgloss.Color(darkGreen)
95+ theme.SyntaxNumberColor = lipgloss.Color(darkOrange)
96+ theme.SyntaxTypeColor = lipgloss.Color(darkYellow)
97+ theme.SyntaxOperatorColor = lipgloss.Color(darkCyan)
98+ theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
99+
100+ return theme
101+}
102+
103+// NewTokyoNightDayTheme creates a new instance of the Tokyo Night Day theme.
104+func NewTokyoNightDayTheme() *TokyoNightTheme {
31105 // Light mode colors (Tokyo Night Day)
32106 lightBackground := "#e1e2e7"
33107 lightCurrentLine := "#d5d6db"
@@ -46,229 +120,77 @@ func NewTokyoNightTheme() *TokyoNightTheme {
46120 theme := &TokyoNightTheme{}
47121
48122 // Base colors
49− theme.PrimaryColor = lipgloss.AdaptiveColor{
50− Dark: darkBlue,
51− Light: lightBlue,
52− }
53− theme.SecondaryColor = lipgloss.AdaptiveColor{
54− Dark: darkPurple,
55− Light: lightPurple,
56− }
57− theme.AccentColor = lipgloss.AdaptiveColor{
58− Dark: darkOrange,
59− Light: lightOrange,
60− }
123+ theme.PrimaryColor = lipgloss.Color(lightBlue)
124+ theme.SecondaryColor = lipgloss.Color(lightPurple)
125+ theme.AccentColor = lipgloss.Color(lightOrange)
61126
62127 // Status colors
63− theme.ErrorColor = lipgloss.AdaptiveColor{
64− Dark: darkRed,
65− Light: lightRed,
66− }
67− theme.WarningColor = lipgloss.AdaptiveColor{
68− Dark: darkOrange,
69− Light: lightOrange,
70− }
71− theme.SuccessColor = lipgloss.AdaptiveColor{
72− Dark: darkGreen,
73− Light: lightGreen,
74− }
75− theme.InfoColor = lipgloss.AdaptiveColor{
76− Dark: darkBlue,
77− Light: lightBlue,
78− }
128+ theme.ErrorColor = lipgloss.Color(lightRed)
129+ theme.WarningColor = lipgloss.Color(lightOrange)
130+ theme.SuccessColor = lipgloss.Color(lightGreen)
131+ theme.InfoColor = lipgloss.Color(lightBlue)
79132
80133 // Text colors
81− theme.TextColor = lipgloss.AdaptiveColor{
82− Dark: darkForeground,
83− Light: lightForeground,
84− }
85− theme.TextMutedColor = lipgloss.AdaptiveColor{
86− Dark: darkComment,
87− Light: lightComment,
88− }
89− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
90− Dark: darkYellow,
91− Light: lightYellow,
92− }
134+ theme.TextColor = lipgloss.Color(lightForeground)
135+ theme.TextMutedColor = lipgloss.Color(lightComment)
136+ theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
93137
94138 // Background colors
95− theme.BackgroundColor = lipgloss.AdaptiveColor{
96− Dark: darkBackground,
97− Light: lightBackground,
98− }
99− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
100− Dark: darkCurrentLine,
101− Light: lightCurrentLine,
102− }
103− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
104− Dark: "#191B29", // Darker background from palette
105− Light: "#f0f0f5", // Slightly lighter than background
106− }
139+ theme.BackgroundColor = lipgloss.Color(lightBackground)
140+ theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
141+ theme.BackgroundDarkerColor = lipgloss.Color("#f0f0f5") // Slightly lighter than background
107142
108143 // Border colors
109− theme.BorderNormalColor = lipgloss.AdaptiveColor{
110− Dark: darkBorder,
111− Light: lightBorder,
112− }
113− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
114− Dark: darkBlue,
115− Light: lightBlue,
116− }
117− theme.BorderDimColor = lipgloss.AdaptiveColor{
118− Dark: darkSelection,
119− Light: lightSelection,
120− }
144+ theme.BorderNormalColor = lipgloss.Color(lightBorder)
145+ theme.BorderFocusedColor = lipgloss.Color(lightBlue)
146+ theme.BorderDimColor = lipgloss.Color(lightSelection)
121147
122148 // Diff view colors
123− theme.DiffAddedColor = lipgloss.AdaptiveColor{
124− Dark: "#4fd6be", // teal from palette
125− Light: "#1e725c",
126− }
127− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
128− Dark: "#c53b53", // red1 from palette
129− Light: "#c53b53",
130− }
131− theme.DiffContextColor = lipgloss.AdaptiveColor{
132− Dark: "#828bb8", // fg_dark from palette
133− Light: "#7086b5",
134− }
135− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
136− Dark: "#828bb8", // fg_dark from palette
137− Light: "#7086b5",
138− }
139− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
140− Dark: "#b8db87", // git.add from palette
141− Light: "#4db380",
142− }
143− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
144− Dark: "#e26a75", // git.delete from palette
145− Light: "#f52a65",
146− }
147− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
148− Dark: "#20303b",
149− Light: "#d5e5d5",
150− }
151− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
152− Dark: "#37222c",
153− Light: "#f7d8db",
154− }
155− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
156− Dark: darkBackground,
157− Light: lightBackground,
158− }
159− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
160− Dark: "#545c7e", // dark3 from palette
161− Light: "#848cb5",
162− }
163− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
164− Dark: "#1b2b34",
165− Light: "#c5d5c5",
166− }
167− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
168− Dark: "#2d1f26",
169− Light: "#e7c8cb",
170− }
149+ theme.DiffAddedColor = lipgloss.Color("#1e725c")
150+ theme.DiffRemovedColor = lipgloss.Color("#c53b53")
151+ theme.DiffContextColor = lipgloss.Color("#7086b5")
152+ theme.DiffHunkHeaderColor = lipgloss.Color("#7086b5")
153+ theme.DiffHighlightAddedColor = lipgloss.Color("#4db380")
154+ theme.DiffHighlightRemovedColor = lipgloss.Color("#f52a65")
155+ theme.DiffAddedBgColor = lipgloss.Color("#d5e5d5")
156+ theme.DiffRemovedBgColor = lipgloss.Color("#f7d8db")
157+ theme.DiffContextBgColor = lipgloss.Color(lightBackground)
158+ theme.DiffLineNumberColor = lipgloss.Color("#848cb5")
159+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#c5d5c5")
160+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#e7c8cb")
171161
172162 // Markdown colors
173− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
174− Dark: darkForeground,
175− Light: lightForeground,
176− }
177− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
178− Dark: darkPurple,
179− Light: lightPurple,
180− }
181− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
182− Dark: darkBlue,
183− Light: lightBlue,
184− }
185− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
186− Dark: darkCyan,
187− Light: lightCyan,
188− }
189− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
190− Dark: darkGreen,
191− Light: lightGreen,
192− }
193− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
194− Dark: darkYellow,
195− Light: lightYellow,
196− }
197− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
198− Dark: darkYellow,
199− Light: lightYellow,
200− }
201− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
202− Dark: darkOrange,
203− Light: lightOrange,
204− }
205− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
206− Dark: darkComment,
207− Light: lightComment,
208− }
209− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
210− Dark: darkBlue,
211− Light: lightBlue,
212− }
213− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
214− Dark: darkCyan,
215− Light: lightCyan,
216− }
217− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
218− Dark: darkBlue,
219− Light: lightBlue,
220− }
221− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
222− Dark: darkCyan,
223− Light: lightCyan,
224− }
225− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
226− Dark: darkForeground,
227− Light: lightForeground,
228− }
163+ theme.MarkdownTextColor = lipgloss.Color(lightForeground)
164+ theme.MarkdownHeadingColor = lipgloss.Color(lightPurple)
165+ theme.MarkdownLinkColor = lipgloss.Color(lightBlue)
166+ theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
167+ theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
168+ theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
169+ theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
170+ theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
171+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
172+ theme.MarkdownListItemColor = lipgloss.Color(lightBlue)
173+ theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
174+ theme.MarkdownImageColor = lipgloss.Color(lightBlue)
175+ theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
176+ theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
229177
230178 // Syntax highlighting colors
231− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
232− Dark: darkComment,
233− Light: lightComment,
234− }
235− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
236− Dark: darkPurple,
237− Light: lightPurple,
238− }
239− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
240− Dark: darkBlue,
241− Light: lightBlue,
242− }
243− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
244− Dark: darkRed,
245− Light: lightRed,
246− }
247− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
248− Dark: darkGreen,
249− Light: lightGreen,
250− }
251− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
252− Dark: darkOrange,
253− Light: lightOrange,
254− }
255− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
256− Dark: darkYellow,
257− Light: lightYellow,
258− }
259− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
260− Dark: darkCyan,
261− Light: lightCyan,
262− }
263− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
264− Dark: darkForeground,
265− Light: lightForeground,
266− }
179+ theme.SyntaxCommentColor = lipgloss.Color(lightComment)
180+ theme.SyntaxKeywordColor = lipgloss.Color(lightPurple)
181+ theme.SyntaxFunctionColor = lipgloss.Color(lightBlue)
182+ theme.SyntaxVariableColor = lipgloss.Color(lightRed)
183+ theme.SyntaxStringColor = lipgloss.Color(lightGreen)
184+ theme.SyntaxNumberColor = lipgloss.Color(lightOrange)
185+ theme.SyntaxTypeColor = lipgloss.Color(lightYellow)
186+ theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
187+ theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
267188
268189 return theme
269190}
270191
271192func init() {
272− // Register the Tokyo Night theme with the theme manager
193+ // Register the Tokyo Night themes with the theme manager
273194 RegisterTheme("tokyonight", NewTokyoNightTheme())
195+ RegisterTheme("tokyonight-day", NewTokyoNightDayTheme())
274196}
internal/tui/theme/tron.go+128−206
@@ -1,7 +1,7 @@
11package theme
22
33import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
55)
66
77// TronTheme implements the Theme interface with Tron-inspired colors.
@@ -29,6 +29,80 @@ func NewTronTheme() *TronTheme {
2929 darkGreen := "#00ff8f"
3030 darkBorder := "#1a2633"
3131
32+ theme := &TronTheme{}
33+
34+ // Base colors
35+ theme.PrimaryColor = lipgloss.Color(darkCyan)
36+ theme.SecondaryColor = lipgloss.Color(darkBlue)
37+ theme.AccentColor = lipgloss.Color(darkOrange)
38+
39+ // Status colors
40+ theme.ErrorColor = lipgloss.Color(darkRed)
41+ theme.WarningColor = lipgloss.Color(darkOrange)
42+ theme.SuccessColor = lipgloss.Color(darkGreen)
43+ theme.InfoColor = lipgloss.Color(darkCyan)
44+
45+ // Text colors
46+ theme.TextColor = lipgloss.Color(darkForeground)
47+ theme.TextMutedColor = lipgloss.Color(darkComment)
48+ theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
49+
50+ // Background colors
51+ theme.BackgroundColor = lipgloss.Color(darkBackground)
52+ theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
53+ theme.BackgroundDarkerColor = lipgloss.Color("#070d14") // Slightly darker than background
54+
55+ // Border colors
56+ theme.BorderNormalColor = lipgloss.Color(darkBorder)
57+ theme.BorderFocusedColor = lipgloss.Color(darkCyan)
58+ theme.BorderDimColor = lipgloss.Color(darkSelection)
59+
60+ // Diff view colors
61+ theme.DiffAddedColor = lipgloss.Color(darkGreen)
62+ theme.DiffRemovedColor = lipgloss.Color(darkRed)
63+ theme.DiffContextColor = lipgloss.Color(darkComment)
64+ theme.DiffHunkHeaderColor = lipgloss.Color(darkBlue)
65+ theme.DiffHighlightAddedColor = lipgloss.Color("#00ff8f")
66+ theme.DiffHighlightRemovedColor = lipgloss.Color("#ff3333")
67+ theme.DiffAddedBgColor = lipgloss.Color("#0a2a1a")
68+ theme.DiffRemovedBgColor = lipgloss.Color("#2a0a0a")
69+ theme.DiffContextBgColor = lipgloss.Color(darkBackground)
70+ theme.DiffLineNumberColor = lipgloss.Color(darkComment)
71+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#082015")
72+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#200808")
73+
74+ // Markdown colors
75+ theme.MarkdownTextColor = lipgloss.Color(darkForeground)
76+ theme.MarkdownHeadingColor = lipgloss.Color(darkCyan)
77+ theme.MarkdownLinkColor = lipgloss.Color(darkBlue)
78+ theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
79+ theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
80+ theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
81+ theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
82+ theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
83+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
84+ theme.MarkdownListItemColor = lipgloss.Color(darkBlue)
85+ theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
86+ theme.MarkdownImageColor = lipgloss.Color(darkBlue)
87+ theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
88+ theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
89+
90+ // Syntax highlighting colors
91+ theme.SyntaxCommentColor = lipgloss.Color(darkComment)
92+ theme.SyntaxKeywordColor = lipgloss.Color(darkCyan)
93+ theme.SyntaxFunctionColor = lipgloss.Color(darkGreen)
94+ theme.SyntaxVariableColor = lipgloss.Color(darkOrange)
95+ theme.SyntaxStringColor = lipgloss.Color(darkYellow)
96+ theme.SyntaxNumberColor = lipgloss.Color(darkBlue)
97+ theme.SyntaxTypeColor = lipgloss.Color(darkPurple)
98+ theme.SyntaxOperatorColor = lipgloss.Color(darkPink)
99+ theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
100+
101+ return theme
102+}
103+
104+// NewTronLightTheme creates a new instance of the Tron Light theme.
105+func NewTronLightTheme() *TronTheme {
32106 // Light mode approximation
33107 lightBackground := "#f0f8ff"
34108 lightCurrentLine := "#e0f0ff"
@@ -48,229 +122,77 @@ func NewTronTheme() *TronTheme {
48122 theme := &TronTheme{}
49123
50124 // Base colors
51− theme.PrimaryColor = lipgloss.AdaptiveColor{
52− Dark: darkCyan,
53− Light: lightCyan,
54− }
55− theme.SecondaryColor = lipgloss.AdaptiveColor{
56− Dark: darkBlue,
57− Light: lightBlue,
58− }
59− theme.AccentColor = lipgloss.AdaptiveColor{
60− Dark: darkOrange,
61− Light: lightOrange,
62− }
125+ theme.PrimaryColor = lipgloss.Color(lightCyan)
126+ theme.SecondaryColor = lipgloss.Color(lightBlue)
127+ theme.AccentColor = lipgloss.Color(lightOrange)
63128
64129 // Status colors
65− theme.ErrorColor = lipgloss.AdaptiveColor{
66− Dark: darkRed,
67− Light: lightRed,
68− }
69− theme.WarningColor = lipgloss.AdaptiveColor{
70− Dark: darkOrange,
71− Light: lightOrange,
72− }
73− theme.SuccessColor = lipgloss.AdaptiveColor{
74− Dark: darkGreen,
75− Light: lightGreen,
76− }
77− theme.InfoColor = lipgloss.AdaptiveColor{
78− Dark: darkCyan,
79− Light: lightCyan,
80− }
130+ theme.ErrorColor = lipgloss.Color(lightRed)
131+ theme.WarningColor = lipgloss.Color(lightOrange)
132+ theme.SuccessColor = lipgloss.Color(lightGreen)
133+ theme.InfoColor = lipgloss.Color(lightCyan)
81134
82135 // Text colors
83− theme.TextColor = lipgloss.AdaptiveColor{
84− Dark: darkForeground,
85− Light: lightForeground,
86− }
87− theme.TextMutedColor = lipgloss.AdaptiveColor{
88− Dark: darkComment,
89− Light: lightComment,
90− }
91− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
92− Dark: darkYellow,
93− Light: lightYellow,
94− }
136+ theme.TextColor = lipgloss.Color(lightForeground)
137+ theme.TextMutedColor = lipgloss.Color(lightComment)
138+ theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
95139
96140 // Background colors
97− theme.BackgroundColor = lipgloss.AdaptiveColor{
98− Dark: darkBackground,
99− Light: lightBackground,
100− }
101− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
102− Dark: darkCurrentLine,
103− Light: lightCurrentLine,
104− }
105− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
106− Dark: "#070d14", // Slightly darker than background
107− Light: "#ffffff", // Slightly lighter than background
108− }
141+ theme.BackgroundColor = lipgloss.Color(lightBackground)
142+ theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
143+ theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
109144
110145 // Border colors
111− theme.BorderNormalColor = lipgloss.AdaptiveColor{
112− Dark: darkBorder,
113− Light: lightBorder,
114− }
115− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
116− Dark: darkCyan,
117− Light: lightCyan,
118− }
119− theme.BorderDimColor = lipgloss.AdaptiveColor{
120− Dark: darkSelection,
121− Light: lightSelection,
122− }
146+ theme.BorderNormalColor = lipgloss.Color(lightBorder)
147+ theme.BorderFocusedColor = lipgloss.Color(lightCyan)
148+ theme.BorderDimColor = lipgloss.Color(lightSelection)
123149
124150 // Diff view colors
125− theme.DiffAddedColor = lipgloss.AdaptiveColor{
126− Dark: darkGreen,
127− Light: lightGreen,
128− }
129− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
130− Dark: darkRed,
131− Light: lightRed,
132− }
133− theme.DiffContextColor = lipgloss.AdaptiveColor{
134− Dark: darkComment,
135− Light: lightComment,
136− }
137− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
138− Dark: darkBlue,
139− Light: lightBlue,
140− }
141− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
142− Dark: "#00ff8f",
143− Light: "#a5d6a7",
144− }
145− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
146− Dark: "#ff3333",
147− Light: "#ef9a9a",
148− }
149− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
150− Dark: "#0a2a1a",
151− Light: "#e8f5e9",
152− }
153− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
154− Dark: "#2a0a0a",
155− Light: "#ffebee",
156− }
157− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
158− Dark: darkBackground,
159− Light: lightBackground,
160− }
161− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
162− Dark: darkComment,
163− Light: lightComment,
164− }
165− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
166− Dark: "#082015",
167− Light: "#c8e6c9",
168− }
169− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
170− Dark: "#200808",
171− Light: "#ffcdd2",
172− }
151+ theme.DiffAddedColor = lipgloss.Color(lightGreen)
152+ theme.DiffRemovedColor = lipgloss.Color(lightRed)
153+ theme.DiffContextColor = lipgloss.Color(lightComment)
154+ theme.DiffHunkHeaderColor = lipgloss.Color(lightBlue)
155+ theme.DiffHighlightAddedColor = lipgloss.Color("#a5d6a7")
156+ theme.DiffHighlightRemovedColor = lipgloss.Color("#ef9a9a")
157+ theme.DiffAddedBgColor = lipgloss.Color("#e8f5e9")
158+ theme.DiffRemovedBgColor = lipgloss.Color("#ffebee")
159+ theme.DiffContextBgColor = lipgloss.Color(lightBackground)
160+ theme.DiffLineNumberColor = lipgloss.Color(lightComment)
161+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#c8e6c9")
162+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#ffcdd2")
173163
174164 // Markdown colors
175− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
176− Dark: darkForeground,
177− Light: lightForeground,
178− }
179− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
180− Dark: darkCyan,
181− Light: lightCyan,
182− }
183− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
184− Dark: darkBlue,
185− Light: lightBlue,
186− }
187− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
188− Dark: darkCyan,
189− Light: lightCyan,
190− }
191− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
192− Dark: darkGreen,
193− Light: lightGreen,
194− }
195− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
196− Dark: darkYellow,
197− Light: lightYellow,
198− }
199− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
200− Dark: darkYellow,
201− Light: lightYellow,
202− }
203− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
204− Dark: darkOrange,
205− Light: lightOrange,
206− }
207− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
208− Dark: darkComment,
209− Light: lightComment,
210− }
211− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
212− Dark: darkBlue,
213− Light: lightBlue,
214− }
215− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
216− Dark: darkCyan,
217− Light: lightCyan,
218− }
219− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
220− Dark: darkBlue,
221− Light: lightBlue,
222− }
223− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
224− Dark: darkCyan,
225− Light: lightCyan,
226− }
227− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
228− Dark: darkForeground,
229− Light: lightForeground,
230− }
165+ theme.MarkdownTextColor = lipgloss.Color(lightForeground)
166+ theme.MarkdownHeadingColor = lipgloss.Color(lightCyan)
167+ theme.MarkdownLinkColor = lipgloss.Color(lightBlue)
168+ theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
169+ theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
170+ theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
171+ theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
172+ theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
173+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
174+ theme.MarkdownListItemColor = lipgloss.Color(lightBlue)
175+ theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
176+ theme.MarkdownImageColor = lipgloss.Color(lightBlue)
177+ theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
178+ theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
231179
232180 // Syntax highlighting colors
233− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
234− Dark: darkComment,
235− Light: lightComment,
236− }
237− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
238− Dark: darkCyan,
239− Light: lightCyan,
240− }
241− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
242− Dark: darkGreen,
243− Light: lightGreen,
244− }
245− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
246− Dark: darkOrange,
247− Light: lightOrange,
248− }
249− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
250− Dark: darkYellow,
251− Light: lightYellow,
252− }
253− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
254− Dark: darkBlue,
255− Light: lightBlue,
256− }
257− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
258− Dark: darkPurple,
259− Light: lightPurple,
260− }
261− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
262− Dark: darkPink,
263− Light: lightPink,
264− }
265− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
266− Dark: darkForeground,
267− Light: lightForeground,
268− }
181+ theme.SyntaxCommentColor = lipgloss.Color(lightComment)
182+ theme.SyntaxKeywordColor = lipgloss.Color(lightCyan)
183+ theme.SyntaxFunctionColor = lipgloss.Color(lightGreen)
184+ theme.SyntaxVariableColor = lipgloss.Color(lightOrange)
185+ theme.SyntaxStringColor = lipgloss.Color(lightYellow)
186+ theme.SyntaxNumberColor = lipgloss.Color(lightBlue)
187+ theme.SyntaxTypeColor = lipgloss.Color(lightPurple)
188+ theme.SyntaxOperatorColor = lipgloss.Color(lightPink)
189+ theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
269190
270191 return theme
271192}
272193
273194func init() {
274− // Register the Tron theme with the theme manager
195+ // Register the Tron themes with the theme manager
275196 RegisterTheme("tron", NewTronTheme())
197+ RegisterTheme("tron-light", NewTronLightTheme())
276198}
internal/tui/tui.go+16−10
@@ -5,9 +5,9 @@ import (
55 "fmt"
66 "strings"
77
8− "github.com/charmbracelet/bubbles/key"
9− tea "github.com/charmbracelet/bubbletea"
10− "github.com/charmbracelet/lipgloss"
8+ "github.com/charmbracelet/bubbles/v2/key"
9+ tea "github.com/charmbracelet/bubbletea/v2"
10+ "github.com/charmbracelet/lipgloss/v2"
1111 "github.com/opencode-ai/opencode/internal/app"
1212 "github.com/opencode-ai/opencode/internal/config"
1313 "github.com/opencode-ai/opencode/internal/llm/agent"
@@ -99,7 +99,7 @@ type appModel struct {
9999 width, height int
100100 currentPage page.PageID
101101 previousPage page.PageID
102− pages map[page.PageID]tea.Model
102+ pages map[page.PageID]util.Model
103103 loadedPages map[page.PageID]bool
104104 status core.StatusCmp
105105 app *app.App
@@ -143,6 +143,8 @@ type appModel struct {
143143func (a appModel) Init() tea.Cmd {
144144 var cmds []tea.Cmd
145145 cmd := a.pages[a.currentPage].Init()
146+ t := theme.CurrentTheme()
147+ cmds = append(cmds, tea.SetBackgroundColor(t.Background()))
146148 a.loadedPages[a.currentPage] = true
147149 cmds = append(cmds, cmd)
148150 cmd = a.status.Init()
@@ -189,7 +191,8 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
189191
190192 s, _ := a.status.Update(msg)
191193 a.status = s.(core.StatusCmp)
192− a.pages[a.currentPage], cmd = a.pages[a.currentPage].Update(msg)
194+ updated, cmd := a.pages[a.currentPage].Update(msg)
195+ a.pages[a.currentPage] = updated.(util.Model)
193196 cmds = append(cmds, cmd)
194197
195198 prm, permCmd := a.permissions.Update(msg)
@@ -348,9 +351,11 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
348351 return a, nil
349352
350353 case dialog.ThemeChangedMsg:
351− a.pages[a.currentPage], cmd = a.pages[a.currentPage].Update(msg)
354+ updated, cmd := a.pages[a.currentPage].Update(msg)
355+ a.pages[a.currentPage] = updated.(util.Model)
352356 a.showThemeDialog = false
353− return a, tea.Batch(cmd, util.ReportInfo("Theme changed to: "+msg.ThemeName))
357+ t := theme.CurrentTheme()
358+ return a, tea.Batch(cmd, util.ReportInfo("Theme changed to: "+msg.ThemeName), tea.SetBackgroundColor(t.Background()))
354359
355360 case dialog.CloseModelDialogMsg:
356361 a.showModelDialog = false
@@ -427,7 +432,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
427432 // If submitted, replace all named arguments and run the command
428433 if msg.Submit {
429434 content := msg.Content
430−
435+
431436 // Replace each named argument with its value
432437 for name, value := range msg.Args {
433438 placeholder := "$" + name
@@ -658,7 +663,8 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
658663
659664 s, _ := a.status.Update(msg)
660665 a.status = s.(core.StatusCmp)
661− a.pages[a.currentPage], cmd = a.pages[a.currentPage].Update(msg)
666+ updated, cmd := a.pages[a.currentPage].Update(msg)
667+ a.pages[a.currentPage] = updated.(util.Model)
662668 cmds = append(cmds, cmd)
663669 return a, tea.Batch(cmds...)
664670}
@@ -914,7 +920,7 @@ func New(app *app.App) tea.Model {
914920 themeDialog: dialog.NewThemeDialogCmp(),
915921 app: app,
916922 commands: []dialog.Command{},
917− pages: map[page.PageID]tea.Model{
923+ pages: map[page.PageID]util.Model{
918924 page.ChatPage: page.NewChatPage(app),
919925 page.LogsPage: page.NewLogsPage(),
920926 },
internal/tui/util/util.go+6−1
@@ -3,9 +3,14 @@ package util
33import (
44 "time"
55
6− tea "github.com/charmbracelet/bubbletea"
6+ tea "github.com/charmbracelet/bubbletea/v2"
77)
88
9+type Model interface {
10+ tea.Model
11+ tea.ViewModel
12+}
13+
914func CmdHandler(msg tea.Msg) tea.Cmd {
1015 return func() tea.Msg {
1116 return msg