on main help sign in
move to v2
af838d1Kujtim Hoxha
cmd/root.go+1−4
@@ -7,8 +7,7 @@ import (
7 "sync"
7 "sync"
8 "time"
8 "time"
9
9
10− tea "github.com/charmbracelet/bubbletea"
10+ tea "github.com/charmbracelet/bubbletea/v2"
11− zone "github.com/lrstanley/bubblezone"
12 "github.com/opencode-ai/opencode/internal/app"
11 "github.com/opencode-ai/opencode/internal/app"
13 "github.com/opencode-ai/opencode/internal/config"
12 "github.com/opencode-ai/opencode/internal/config"
14 "github.com/opencode-ai/opencode/internal/db"
13 "github.com/opencode-ai/opencode/internal/db"
@@ -114,9 +113,7 @@ to assist developers in writing, debugging, and understanding code directly from
114 return app.RunNonInteractive(ctx, prompt, outputFormat, quiet)
113 return app.RunNonInteractive(ctx, prompt, outputFormat, quiet)
115 }
114 }
116
115
117− // Interactive mode
118 // Set up the TUI
116 // Set up the TUI
119− zone.NewGlobal()
120 program := tea.NewProgram(
117 program := tea.NewProgram(
121 tui.New(app),
118 tui.New(app),
122 tea.WithAltScreen(),
119 tea.WithAltScreen(),
go.mod+10−11
@@ -11,15 +11,14 @@ require (
11 github.com/aymanbagabas/go-udiff v0.2.0
11 github.com/aymanbagabas/go-udiff v0.2.0
12 github.com/bmatcuk/doublestar/v4 v4.8.1
12 github.com/bmatcuk/doublestar/v4 v4.8.1
13 github.com/catppuccin/go v0.3.0
13 github.com/catppuccin/go v0.3.0
14− github.com/charmbracelet/bubbles v0.21.0
14+ github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1
15− github.com/charmbracelet/bubbletea v1.3.5
15+ github.com/charmbracelet/bubbletea/v2 v2.0.0-beta1
16− github.com/charmbracelet/glamour v0.9.1
16+ github.com/charmbracelet/glamour/v2 v2.0.0-20250513163904-eeeced3bb3c6
17− github.com/charmbracelet/lipgloss v1.1.0
17+ github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.1.0.20250513162854-28902d027c40
18− github.com/charmbracelet/x/ansi v0.8.0
18+ github.com/charmbracelet/x/ansi v0.9.2
19 github.com/fsnotify/fsnotify v1.8.0
19 github.com/fsnotify/fsnotify v1.8.0
20 github.com/go-logfmt/logfmt v0.6.0
20 github.com/go-logfmt/logfmt v0.6.0
21 github.com/google/uuid v1.6.0
21 github.com/google/uuid v1.6.0
22− github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231
23 github.com/mark3labs/mcp-go v0.17.0
22 github.com/mark3labs/mcp-go v0.17.0
24 github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6
23 github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6
25 github.com/muesli/reflow v0.3.0
24 github.com/muesli/reflow v0.3.0
@@ -58,13 +57,15 @@ require (
58 github.com/aws/smithy-go v1.20.3 // indirect
57 github.com/aws/smithy-go v1.20.3 // indirect
59 github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
58 github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
60 github.com/aymerick/douceur v0.2.0 // indirect
59 github.com/aymerick/douceur v0.2.0 // indirect
61− github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
60+ github.com/charmbracelet/colorprofile v0.3.0 // indirect
62− github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // 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
63 github.com/charmbracelet/x/term v0.2.1 // indirect
64 github.com/charmbracelet/x/term v0.2.1 // indirect
65+ github.com/charmbracelet/x/windows v0.2.0 // indirect
64 github.com/davecgh/go-spew v1.1.1 // indirect
66 github.com/davecgh/go-spew v1.1.1 // indirect
65 github.com/disintegration/imaging v1.6.2
67 github.com/disintegration/imaging v1.6.2
66 github.com/dlclark/regexp2 v1.11.4 // indirect
68 github.com/dlclark/regexp2 v1.11.4 // indirect
67− github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
68 github.com/felixge/httpsnoop v1.0.4 // indirect
69 github.com/felixge/httpsnoop v1.0.4 // indirect
69 github.com/go-logr/logr v1.4.2 // indirect
70 github.com/go-logr/logr v1.4.2 // indirect
70 github.com/go-logr/stdr v1.2.2 // indirect
71 github.com/go-logr/stdr v1.2.2 // indirect
@@ -81,7 +82,6 @@ require (
81 github.com/lithammer/fuzzysearch v1.1.8
82 github.com/lithammer/fuzzysearch v1.1.8
82 github.com/lucasb-eyer/go-colorful v1.2.0
83 github.com/lucasb-eyer/go-colorful v1.2.0
83 github.com/mattn/go-isatty v0.0.20 // indirect
84 github.com/mattn/go-isatty v0.0.20 // indirect
84− github.com/mattn/go-localereader v0.0.1 // indirect
85 github.com/mattn/go-runewidth v0.0.16 // indirect
85 github.com/mattn/go-runewidth v0.0.16 // indirect
86 github.com/mfridman/interpolate v0.0.2 // indirect
86 github.com/mfridman/interpolate v0.0.2 // indirect
87 github.com/microcosm-cc/bluemonday v1.0.27 // indirect
87 github.com/microcosm-cc/bluemonday v1.0.27 // indirect
@@ -119,7 +119,6 @@ require (
119 golang.org/x/net v0.39.0 // indirect
119 golang.org/x/net v0.39.0 // indirect
120 golang.org/x/sync v0.13.0 // indirect
120 golang.org/x/sync v0.13.0 // indirect
121 golang.org/x/sys v0.32.0 // indirect
121 golang.org/x/sys v0.32.0 // indirect
122− golang.org/x/term v0.31.0 // indirect
123 golang.org/x/text v0.24.0 // indirect
122 golang.org/x/text v0.24.0 // indirect
124 google.golang.org/genai v1.3.0
123 google.golang.org/genai v1.3.0
125 google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
124 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
68github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
68github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
69github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY=
69github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY=
70github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
70github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
71−github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
71+github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1 h1:swACzss0FjnyPz1enfX56GKkLiuKg5FlyVmOLIlU2kE=
72−github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
72+github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1/go.mod h1:6HamsBKWqEC/FVHuQMHgQL+knPyvHH55HwJDHl/adMw=
73−github.com/charmbracelet/bubbletea v1.3.5 h1:JAMNLTbqMOhSwoELIr0qyP4VidFq72/6E9j7HHmRKQc=
73+github.com/charmbracelet/bubbletea/v2 v2.0.0-beta1 h1:yaxFt97mvofGY7bYZn8U/aSVoamXGE3O4AEvWhshUDI=
74−github.com/charmbracelet/bubbletea v1.3.5/go.mod h1:TkCnmH+aBd4LrXhXcqrKiYwRs7qyQx5rBgH5fVY3v54=
74+github.com/charmbracelet/bubbletea/v2 v2.0.0-beta1/go.mod h1:qbcZLI5z8R49v9xBdU5V5Dh5D2uccx8wSwBqxQyErqc=
75−github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
75+github.com/charmbracelet/colorprofile v0.3.0 h1:KtLh9uuu1RCt+Hml4s6Hz+kB1PfV3wi++1h5ia65yKQ=
76−github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
76+github.com/charmbracelet/colorprofile v0.3.0/go.mod h1:oHJ340RS2nmG1zRGPmhJKJ/jf4FPNNk0P39/wBPA1G0=
77−github.com/charmbracelet/glamour v0.9.1 h1:11dEfiGP8q1BEqvGoIjivuc2rBk+5qEXdPtaQ2WoiCM=
77+github.com/charmbracelet/glamour/v2 v2.0.0-20250513163904-eeeced3bb3c6 h1:AKhOV8dSRU3KpqMgpGME9JU7ouumB2S6hMmD6PRJeTc=
78−github.com/charmbracelet/glamour v0.9.1/go.mod h1:+SHvIS8qnwhgTpVMiXwn7OfGomSqff1cHBCI8jLOetk=
78+github.com/charmbracelet/glamour/v2 v2.0.0-20250513163904-eeeced3bb3c6/go.mod h1:7xBAUTCSADx9mHG0uBf4NDoVpYxMzIQ2j/NMLGdFsFM=
79−github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
79+github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.1.0.20250513162854-28902d027c40 h1:SxOUomYAVo5zh+6WCH1bGshlAnSKP0ZeovI0FHAl9kg=
80−github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
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.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
81+github.com/charmbracelet/x/ansi v0.9.2 h1:92AGsQmNTRMzuzHEYfCdjQeUzTrgE1vfO5/7fEVoXdY=
82−github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
82+github.com/charmbracelet/x/ansi v0.9.2/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
83−github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
83+github.com/charmbracelet/x/cellbuf v0.0.14-0.20250326144200-0875329e71da h1:8MGKD5WBtuzfXglq0CnyzVSwGojv57X+H46OL9OUyRA=
84−github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
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-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
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-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
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=
87github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
91github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
88github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
92github.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=
89github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
95github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
90github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
96github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
91github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
97github.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
96github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
102github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
97github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
103github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
98github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
104github.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=
101github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
105github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
102github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
106github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
103github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
107github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
@@ -146,16 +150,12 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
146github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
150github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
147github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
151github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
148github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
152github.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=
151github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
153github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
152github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
154github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
153github.com/mark3labs/mcp-go v0.17.0 h1:5Ps6T7qXr7De/2QTqs9h6BKeZ/qdeUeGrgM5lPzi930=
155github.com/mark3labs/mcp-go v0.17.0 h1:5Ps6T7qXr7De/2QTqs9h6BKeZ/qdeUeGrgM5lPzi930=
154github.com/mark3labs/mcp-go v0.17.0/go.mod h1:KmJndYv7GIgcPVwEKJjNcbhVQ+hJGJhrCCB/9xITzpE=
156github.com/mark3labs/mcp-go v0.17.0/go.mod h1:KmJndYv7GIgcPVwEKJjNcbhVQ+hJGJhrCCB/9xITzpE=
155github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
157github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
156github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
158github.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=
159github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
159github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
160github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
160github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
161github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
161github.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=
297golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
297golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
298golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
298golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
299golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
299golang.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=
301golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
300golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
302golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
301golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
303golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
302golang.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=
318golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
317golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
319golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
318golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
320golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
319golang.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=
323golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
320golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
324golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
321golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
325golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
322golang.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
3import (
3import (
4 "bytes"
4 "bytes"
5 "fmt"
5 "fmt"
6+ "image/color"
6 "io"
7 "io"
7 "regexp"
8 "regexp"
8 "strconv"
9 "strconv"
@@ -13,7 +14,7 @@ import (
13 "github.com/alecthomas/chroma/v2/lexers"
14 "github.com/alecthomas/chroma/v2/lexers"
14 "github.com/alecthomas/chroma/v2/styles"
15 "github.com/alecthomas/chroma/v2/styles"
15 "github.com/aymanbagabas/go-udiff"
16 "github.com/aymanbagabas/go-udiff"
16− "github.com/charmbracelet/lipgloss"
17+ "github.com/charmbracelet/lipgloss/v2"
17 "github.com/charmbracelet/x/ansi"
18 "github.com/charmbracelet/x/ansi"
18 "github.com/opencode-ai/opencode/internal/config"
19 "github.com/opencode-ai/opencode/internal/config"
19 "github.com/opencode-ai/opencode/internal/tui/theme"
20 "github.com/opencode-ai/opencode/internal/tui/theme"
@@ -323,7 +324,7 @@ func pairLines(lines []DiffLine) []linePair {
323// -------------------------------------------------------------------------
324// -------------------------------------------------------------------------
324
325
325// SyntaxHighlight applies syntax highlighting to text based on file extension
326// 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 {
327 t := theme.CurrentTheme()
328 t := theme.CurrentTheme()
328
329
329 // Determine the language lexer to use
330 // Determine the language lexer to use
@@ -531,16 +532,13 @@ func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg lipglos
531 return f.Format(w, s, it)
532 return f.Format(w, s, it)
532}
533}
533
534
534−// getColor returns the appropriate hex color string based on terminal background
535−func getColor(adaptiveColor lipgloss.AdaptiveColor) string {
535+func getColor(c color.Color) string {
536− if lipgloss.HasDarkBackground() {
536+ rgba := color.RGBAModel.Convert(c).(color.RGBA)
537− return adaptiveColor.Dark
537+ return fmt.Sprintf("#%02x%02x%02x", rgba.R, rgba.G, rgba.B)
538− }
539− return adaptiveColor.Light
540}
538}
541
539
542// highlightLine applies syntax highlighting to a single line
540// 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 {
544 var buf bytes.Buffer
542 var buf bytes.Buffer
545 err := SyntaxHighlight(&buf, line, fileName, "terminal16m", bg)
543 err := SyntaxHighlight(&buf, line, fileName, "terminal16m", bg)
546 if err != nil {
544 if err != nil {
@@ -563,7 +561,7 @@ func createStyles(t theme.Theme) (removedLineStyle, addedLineStyle, contextLineS
563// Rendering Functions
561// Rendering Functions
564// -------------------------------------------------------------------------
562// -------------------------------------------------------------------------
565
563
566−func lipglossToHex(color lipgloss.Color) string {
564+func lipglossToHex(color color.Color) string {
567 r, g, b, a := color.RGBA()
565 r, g, b, a := color.RGBA()
568
566
569 // Scale uint32 values (0-65535) to uint8 (0-255).
567 // Scale uint32 values (0-65535) to uint8 (0-255).
@@ -576,7 +574,7 @@ func lipglossToHex(color lipgloss.Color) string {
576}
574}
577
575
578// applyHighlighting applies intra-line highlighting to a piece of text
576// 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 {
580 // Find all ANSI sequences in the content
578 // Find all ANSI sequences in the content
581 ansiRegex := regexp.MustCompile(`\x1b(?:[@-Z\\-_]|\[[0-9?]*(?:;[0-9?]*)*[@-~])`)
579 ansiRegex := regexp.MustCompile(`\x1b(?:[@-Z\\-_]|\[[0-9?]*(?:;[0-9?]*)*[@-~])`)
582 ansiMatches := ansiRegex.FindAllStringIndex(content, -1)
580 ansiMatches := ansiRegex.FindAllStringIndex(content, -1)
internal/format/spinner.go+2−2
@@ -5,8 +5,8 @@ import (
5 "fmt"
5 "fmt"
6 "os"
6 "os"
7
7
8− "github.com/charmbracelet/bubbles/spinner"
8+ "github.com/charmbracelet/bubbles/v2/spinner"
9− tea "github.com/charmbracelet/bubbletea"
9+ tea "github.com/charmbracelet/bubbletea/v2"
10)
10)
11
11
12// Spinner wraps the bubbles spinner for non-interactive mode
12// Spinner wraps the bubbles spinner for non-interactive mode
internal/tui/components/chat/chat.go+1−1
@@ -4,7 +4,7 @@ import (
4 "fmt"
4 "fmt"
5 "sort"
5 "sort"
6
6
7− "github.com/charmbracelet/lipgloss"
7+ "github.com/charmbracelet/lipgloss/v2"
8 "github.com/charmbracelet/x/ansi"
8 "github.com/charmbracelet/x/ansi"
9 "github.com/opencode-ai/opencode/internal/config"
9 "github.com/opencode-ai/opencode/internal/config"
10 "github.com/opencode-ai/opencode/internal/message"
10 "github.com/opencode-ai/opencode/internal/message"
internal/tui/components/chat/editor.go+25−16
@@ -8,10 +8,10 @@ import (
8 "strings"
8 "strings"
9 "unicode"
9 "unicode"
10
10
11− "github.com/charmbracelet/bubbles/key"
11+ "github.com/charmbracelet/bubbles/v2/key"
12− "github.com/charmbracelet/bubbles/textarea"
12+ "github.com/charmbracelet/bubbles/v2/textarea"
13− tea "github.com/charmbracelet/bubbletea"
13+ tea "github.com/charmbracelet/bubbletea/v2"
14− "github.com/charmbracelet/lipgloss"
14+ "github.com/charmbracelet/lipgloss/v2"
15 "github.com/opencode-ai/opencode/internal/app"
15 "github.com/opencode-ai/opencode/internal/app"
16 "github.com/opencode-ai/opencode/internal/logging"
16 "github.com/opencode-ai/opencode/internal/logging"
17 "github.com/opencode-ai/opencode/internal/message"
17 "github.com/opencode-ai/opencode/internal/message"
@@ -162,7 +162,7 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
162 return m, cmd
162 return m, cmd
163 }
163 }
164 m.attachments = append(m.attachments, msg.Attachment)
164 m.attachments = append(m.attachments, msg.Attachment)
165− case tea.KeyMsg:
165+ case tea.KeyPressMsg:
166 if key.Matches(msg, DeleteKeyMaps.AttachmentDeleteMode) {
166 if key.Matches(msg, DeleteKeyMaps.AttachmentDeleteMode) {
167 m.deleteMode = true
167 m.deleteMode = true
168 return m, nil
168 return m, nil
@@ -172,8 +172,9 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
172 m.attachments = nil
172 m.attachments = nil
173 return m, nil
173 return m, nil
174 }
174 }
175+ rune := msg.Code
175− if m.deleteMode && len(msg.Runes) > 0 && unicode.IsDigit(msg.Runes[0]) {
176+ if m.deleteMode && unicode.IsDigit(rune) {
176− num := int(msg.Runes[0] - '0')
177+ num := int(rune - '0')
177 m.deleteMode = false
178 m.deleteMode = false
178 if num < 10 && len(m.attachments) > num {
179 if num < 10 && len(m.attachments) > num {
179 if num == 0 {
180 if num == 0 {
@@ -286,14 +287,22 @@ func CreateTextArea(existing *textarea.Model) textarea.Model {
286 textMutedColor := t.TextMuted()
287 textMutedColor := t.TextMuted()
287
288
288 ta := textarea.New()
289 ta := textarea.New()
290+ s := textarea.DefaultDarkStyles()
291+ b := s.Blurred
289− ta.BlurredStyle.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
292+ b.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
290− ta.BlurredStyle.CursorLine = styles.BaseStyle().Background(bgColor)
293+ b.CursorLine = styles.BaseStyle().Background(bgColor)
291− ta.BlurredStyle.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
294+ b.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
292− ta.BlurredStyle.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
295+ b.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
296+
297+ f := s.Focused
293− ta.FocusedStyle.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
298+ f.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
294− ta.FocusedStyle.CursorLine = styles.BaseStyle().Background(bgColor)
299+ f.CursorLine = styles.BaseStyle().Background(bgColor)
295− ta.FocusedStyle.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
300+ f.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
296− ta.FocusedStyle.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
301+ f.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
302+
303+ s.Focused = f
304+ s.Blurred = b
305+ ta.Styles = s
297
306
298 ta.Prompt = " "
307 ta.Prompt = " "
299 ta.ShowLineNumbers = false
308 ta.ShowLineNumbers = false
@@ -309,7 +318,7 @@ func CreateTextArea(existing *textarea.Model) textarea.Model {
309 return ta
318 return ta
310}
319}
311
320
312−func NewEditorCmp(app *app.App) tea.Model {
321+func NewEditorCmp(app *app.App) util.Model {
313 ta := CreateTextArea(nil)
322 ta := CreateTextArea(nil)
314 return &editorCmp{
323 return &editorCmp{
315 app: app,
324 app: app,
internal/tui/components/chat/list.go+12−12
@@ -5,11 +5,11 @@ import (
5 "fmt"
5 "fmt"
6 "math"
6 "math"
7
7
8− "github.com/charmbracelet/bubbles/key"
8+ "github.com/charmbracelet/bubbles/v2/key"
9− "github.com/charmbracelet/bubbles/spinner"
9+ "github.com/charmbracelet/bubbles/v2/spinner"
10− "github.com/charmbracelet/bubbles/viewport"
10+ "github.com/charmbracelet/bubbles/v2/viewport"
11− tea "github.com/charmbracelet/bubbletea"
11+ tea "github.com/charmbracelet/bubbletea/v2"
12− "github.com/charmbracelet/lipgloss"
12+ "github.com/charmbracelet/lipgloss/v2"
13 "github.com/opencode-ai/opencode/internal/app"
13 "github.com/opencode-ai/opencode/internal/app"
14 "github.com/opencode-ai/opencode/internal/message"
14 "github.com/opencode-ai/opencode/internal/message"
15 "github.com/opencode-ai/opencode/internal/pubsub"
15 "github.com/opencode-ai/opencode/internal/pubsub"
@@ -426,10 +426,10 @@ func (m *messagesCmp) SetSize(width, height int) tea.Cmd {
426 }
426 }
427 m.width = width
427 m.width = width
428 m.height = height
428 m.height = height
429− m.viewport.Width = width
429+ m.viewport.SetWidth(width)
430− m.viewport.Height = height - 2
430+ m.viewport.SetHeight(height - 2)
431− m.attachments.Width = width + 40
431+ m.attachments.SetWidth(width + 40)
432− m.attachments.Height = 3
432+ m.attachments.SetHeight(3)
433 m.rerender()
433 m.rerender()
434 return nil
434 return nil
435}
435}
@@ -468,11 +468,11 @@ func (m *messagesCmp) BindingKeys() []key.Binding {
468 }
468 }
469}
469}
470
470
471−func NewMessagesCmp(app *app.App) tea.Model {
471+func NewMessagesCmp(app *app.App) util.Model {
472 s := spinner.New()
472 s := spinner.New()
473 s.Spinner = spinner.Pulse
473 s.Spinner = spinner.Pulse
474− vp := viewport.New(0, 0)
474+ vp := viewport.New()
475− attachmets := viewport.New(0, 0)
475+ attachmets := viewport.New()
476 vp.KeyMap.PageUp = messageKeys.PageUp
476 vp.KeyMap.PageUp = messageKeys.PageUp
477 vp.KeyMap.PageDown = messageKeys.PageDown
477 vp.KeyMap.PageDown = messageKeys.PageDown
478 vp.KeyMap.HalfPageUp = messageKeys.HalfPageUp
478 vp.KeyMap.HalfPageUp = messageKeys.HalfPageUp
internal/tui/components/chat/message.go+8−26
@@ -8,7 +8,7 @@ import (
8 "strings"
8 "strings"
9 "time"
9 "time"
10
10
11− "github.com/charmbracelet/lipgloss"
11+ "github.com/charmbracelet/lipgloss/v2"
12 "github.com/charmbracelet/x/ansi"
12 "github.com/charmbracelet/x/ansi"
13 "github.com/opencode-ai/opencode/internal/config"
13 "github.com/opencode-ai/opencode/internal/config"
14 "github.com/opencode-ai/opencode/internal/diff"
14 "github.com/opencode-ai/opencode/internal/diff"
@@ -60,7 +60,7 @@ func renderMessage(msg string, isUser bool, isFocused bool, width int, info ...s
60
60
61 // Apply markdown formatting and handle background color
61 // Apply markdown formatting and handle background color
62 parts := []string{
62 parts := []string{
63− styles.ForceReplaceBackgroundWithLipgloss(toMarkdown(msg, isFocused, width), t.Background()),
63+ toMarkdown(msg, isFocused, width),
64 }
64 }
65
65
66 // Remove newline at the end
66 // Remove newline at the end
@@ -454,16 +454,10 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
454 resultContent := truncateHeight(response.Content, maxResultHeight)
454 resultContent := truncateHeight(response.Content, maxResultHeight)
455 switch toolCall.Name {
455 switch toolCall.Name {
456 case agent.AgentToolName:
456 case agent.AgentToolName:
457− return styles.ForceReplaceBackgroundWithLipgloss(
458− toMarkdown(resultContent, false, width),
457+ return toMarkdown(resultContent, false, width)
459− t.Background(),
460− )
461 case tools.BashToolName:
458 case tools.BashToolName:
462 resultContent = fmt.Sprintf("```bash\n%s\n```", resultContent)
459 resultContent = fmt.Sprintf("```bash\n%s\n```", resultContent)
463− return styles.ForceReplaceBackgroundWithLipgloss(
464− toMarkdown(resultContent, true, width),
460+ return toMarkdown(resultContent, true, width)
465− t.Background(),
466− )
467 case tools.EditToolName:
461 case tools.EditToolName:
468 metadata := tools.EditResponseMetadata{}
462 metadata := tools.EditResponseMetadata{}
469 json.Unmarshal([]byte(response.Metadata), &metadata)
463 json.Unmarshal([]byte(response.Metadata), &metadata)
@@ -481,10 +475,7 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
481 mdFormat = "html"
475 mdFormat = "html"
482 }
476 }
483 resultContent = fmt.Sprintf("```%s\n%s\n```", mdFormat, resultContent)
477 resultContent = fmt.Sprintf("```%s\n%s\n```", mdFormat, resultContent)
484− return styles.ForceReplaceBackgroundWithLipgloss(
485− toMarkdown(resultContent, true, width),
478+ return toMarkdown(resultContent, true, width)
486− t.Background(),
487− )
488 case tools.GlobToolName:
479 case tools.GlobToolName:
489 return baseStyle.Width(width).Foreground(t.TextMuted()).Render(resultContent)
480 return baseStyle.Width(width).Foreground(t.TextMuted()).Render(resultContent)
490 case tools.GrepToolName:
481 case tools.GrepToolName:
@@ -503,10 +494,7 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
503 ext = strings.ToLower(ext[1:])
494 ext = strings.ToLower(ext[1:])
504 }
495 }
505 resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(metadata.Content, maxResultHeight))
496 resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(metadata.Content, maxResultHeight))
506− return styles.ForceReplaceBackgroundWithLipgloss(
507− toMarkdown(resultContent, true, width),
497+ return toMarkdown(resultContent, true, width)
508− t.Background(),
509− )
510 case tools.WriteToolName:
498 case tools.WriteToolName:
511 params := tools.WriteParams{}
499 params := tools.WriteParams{}
512 json.Unmarshal([]byte(toolCall.Input), &params)
500 json.Unmarshal([]byte(toolCall.Input), &params)
@@ -519,16 +507,10 @@ func renderToolResponse(toolCall message.ToolCall, response message.ToolResult,
519 ext = strings.ToLower(ext[1:])
507 ext = strings.ToLower(ext[1:])
520 }
508 }
521 resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(params.Content, maxResultHeight))
509 resultContent = fmt.Sprintf("```%s\n%s\n```", ext, truncateHeight(params.Content, maxResultHeight))
522− return styles.ForceReplaceBackgroundWithLipgloss(
523− toMarkdown(resultContent, true, width),
510+ return toMarkdown(resultContent, true, width)
524− t.Background(),
525− )
526 default:
511 default:
527 resultContent = fmt.Sprintf("```text\n%s\n```", resultContent)
512 resultContent = fmt.Sprintf("```text\n%s\n```", resultContent)
528− return styles.ForceReplaceBackgroundWithLipgloss(
529− toMarkdown(resultContent, true, width),
513+ return toMarkdown(resultContent, true, width)
530− t.Background(),
531− )
532 }
514 }
533}
515}
534
516
internal/tui/components/chat/sidebar.go+4−3
@@ -6,8 +6,8 @@ import (
6 "sort"
6 "sort"
7 "strings"
7 "strings"
8
8
9− tea "github.com/charmbracelet/bubbletea"
9+ tea "github.com/charmbracelet/bubbletea/v2"
10− "github.com/charmbracelet/lipgloss"
10+ "github.com/charmbracelet/lipgloss/v2"
11 "github.com/opencode-ai/opencode/internal/config"
11 "github.com/opencode-ai/opencode/internal/config"
12 "github.com/opencode-ai/opencode/internal/diff"
12 "github.com/opencode-ai/opencode/internal/diff"
13 "github.com/opencode-ai/opencode/internal/history"
13 "github.com/opencode-ai/opencode/internal/history"
@@ -15,6 +15,7 @@ import (
15 "github.com/opencode-ai/opencode/internal/session"
15 "github.com/opencode-ai/opencode/internal/session"
16 "github.com/opencode-ai/opencode/internal/tui/styles"
16 "github.com/opencode-ai/opencode/internal/tui/styles"
17 "github.com/opencode-ai/opencode/internal/tui/theme"
17 "github.com/opencode-ai/opencode/internal/tui/theme"
18+ "github.com/opencode-ai/opencode/internal/tui/util"
18)
19)
19
20
20type sidebarCmp struct {
21type sidebarCmp struct {
@@ -235,7 +236,7 @@ func (m *sidebarCmp) GetSize() (int, int) {
235 return m.width, m.height
236 return m.width, m.height
236}
237}
237
238
238−func NewSidebarCmp(session session.Session, history history.Service) tea.Model {
239+func NewSidebarCmp(session session.Session, history history.Service) util.Model {
239 return &sidebarCmp{
240 return &sidebarCmp{
240 session: session,
241 session: session,
241 history: history,
242 history: history,
internal/tui/components/core/status.go+3−3
@@ -5,8 +5,8 @@ import (
5 "strings"
5 "strings"
6 "time"
6 "time"
7
7
8− tea "github.com/charmbracelet/bubbletea"
8+ tea "github.com/charmbracelet/bubbletea/v2"
9− "github.com/charmbracelet/lipgloss"
9+ "github.com/charmbracelet/lipgloss/v2"
10 "github.com/opencode-ai/opencode/internal/config"
10 "github.com/opencode-ai/opencode/internal/config"
11 "github.com/opencode-ai/opencode/internal/llm/models"
11 "github.com/opencode-ai/opencode/internal/llm/models"
12 "github.com/opencode-ai/opencode/internal/lsp"
12 "github.com/opencode-ai/opencode/internal/lsp"
@@ -20,7 +20,7 @@ import (
20)
20)
21
21
22type StatusCmp interface {
22type StatusCmp interface {
23− tea.Model
23+ util.Model
24}
24}
25
25
26type statusCmp struct {
26type statusCmp struct {
internal/tui/components/dialog/arguments.go+22−28
@@ -2,10 +2,11 @@ package dialog
2
2
3import (
3import (
4 "fmt"
4 "fmt"
5+
5− "github.com/charmbracelet/bubbles/key"
6+ "github.com/charmbracelet/bubbles/v2/key"
6− "github.com/charmbracelet/bubbles/textinput"
7+ "github.com/charmbracelet/bubbles/v2/textinput"
7− tea "github.com/charmbracelet/bubbletea"
8+ tea "github.com/charmbracelet/bubbletea/v2"
8− "github.com/charmbracelet/lipgloss"
9+ "github.com/charmbracelet/lipgloss/v2"
9
10
10 "github.com/opencode-ai/opencode/internal/tui/styles"
11 "github.com/opencode-ai/opencode/internal/tui/styles"
11 "github.com/opencode-ai/opencode/internal/tui/theme"
12 "github.com/opencode-ai/opencode/internal/tui/theme"
@@ -70,17 +71,18 @@ func NewMultiArgumentsDialogCmp(commandID, content string, argNames []string) Mu
70 for i, name := range argNames {
71 for i, name := range argNames {
71 ti := textinput.New()
72 ti := textinput.New()
72 ti.Placeholder = fmt.Sprintf("Enter value for %s...", name)
73 ti.Placeholder = fmt.Sprintf("Enter value for %s...", name)
73− ti.Width = 40
74+ ti.SetWidth(40)
74 ti.Prompt = ""
75 ti.Prompt = ""
75− ti.PlaceholderStyle = ti.PlaceholderStyle.Background(t.Background())
76+ ti.Styles.Focused.Placeholder = ti.Styles.Focused.Placeholder.Background(t.Background())
76− ti.PromptStyle = ti.PromptStyle.Background(t.Background())
77+ ti.Styles.Blurred.Placeholder = ti.Styles.Blurred.Placeholder.Background(t.Background())
77− ti.TextStyle = ti.TextStyle.Background(t.Background())
78+ ti.Styles.Focused.Suggestion = ti.Styles.Focused.Suggestion.Background(t.Background()).Foreground(t.Primary())
78−
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+
79 // Only focus the first input initially
83 // Only focus the first input initially
80 if i == 0 {
84 if i == 0 {
81 ti.Focus()
85 ti.Focus()
82− ti.PromptStyle = ti.PromptStyle.Foreground(t.Primary())
83− ti.TextStyle = ti.TextStyle.Foreground(t.Primary())
84 } else {
86 } else {
85 ti.Blur()
87 ti.Blur()
86 }
88 }
@@ -89,11 +91,11 @@ func NewMultiArgumentsDialogCmp(commandID, content string, argNames []string) Mu
89 }
91 }
90
92
91 return MultiArgumentsDialogCmp{
93 return MultiArgumentsDialogCmp{
92− inputs: inputs,
94+ inputs: inputs,
93− keys: argumentsDialogKeyMap{},
95+ keys: argumentsDialogKeyMap{},
94− commandID: commandID,
96+ commandID: commandID,
95− content: content,
97+ content: content,
96− argNames: argNames,
98+ argNames: argNames,
97 focusIndex: 0,
99 focusIndex: 0,
98 }
100 }
99}
101}
@@ -108,15 +110,13 @@ func (m MultiArgumentsDialogCmp) Init() tea.Cmd {
108 m.inputs[i].Blur()
110 m.inputs[i].Blur()
109 }
111 }
110 }
112 }
111−
113+
112 return textinput.Blink
114 return textinput.Blink
113}
115}
114
116
115// Update implements tea.Model.
117// Update implements tea.Model.
116func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
118func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
117 var cmds []tea.Cmd
119 var cmds []tea.Cmd
118− t := theme.CurrentTheme()
119−
120 switch msg := msg.(type) {
120 switch msg := msg.(type) {
121 case tea.KeyMsg:
121 case tea.KeyMsg:
122 switch {
122 switch {
@@ -145,22 +145,16 @@ func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
145 m.inputs[m.focusIndex].Blur()
145 m.inputs[m.focusIndex].Blur()
146 m.focusIndex++
146 m.focusIndex++
147 m.inputs[m.focusIndex].Focus()
147 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())
150 case key.Matches(msg, key.NewBinding(key.WithKeys("tab"))):
148 case key.Matches(msg, key.NewBinding(key.WithKeys("tab"))):
151 // Move to the next input
149 // Move to the next input
152 m.inputs[m.focusIndex].Blur()
150 m.inputs[m.focusIndex].Blur()
153 m.focusIndex = (m.focusIndex + 1) % len(m.inputs)
151 m.focusIndex = (m.focusIndex + 1) % len(m.inputs)
154 m.inputs[m.focusIndex].Focus()
152 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())
157 case key.Matches(msg, key.NewBinding(key.WithKeys("shift+tab"))):
153 case key.Matches(msg, key.NewBinding(key.WithKeys("shift+tab"))):
158 // Move to the previous input
154 // Move to the previous input
159 m.inputs[m.focusIndex].Blur()
155 m.inputs[m.focusIndex].Blur()
160 m.focusIndex = (m.focusIndex - 1 + len(m.inputs)) % len(m.inputs)
156 m.focusIndex = (m.focusIndex - 1 + len(m.inputs)) % len(m.inputs)
161 m.inputs[m.focusIndex].Focus()
157 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())
164 }
158 }
165 case tea.WindowSizeMsg:
159 case tea.WindowSizeMsg:
166 m.width = msg.Width
160 m.width = msg.Width
@@ -206,13 +200,13 @@ func (m MultiArgumentsDialogCmp) View() string {
206 Width(maxWidth).
200 Width(maxWidth).
207 Padding(1, 1, 0, 1).
201 Padding(1, 1, 0, 1).
208 Background(t.Background())
202 Background(t.Background())
209−
203+
210 if i == m.focusIndex {
204 if i == m.focusIndex {
211 labelStyle = labelStyle.Foreground(t.Primary()).Bold(true)
205 labelStyle = labelStyle.Foreground(t.Primary()).Bold(true)
212 } else {
206 } else {
213 labelStyle = labelStyle.Foreground(t.TextMuted())
207 labelStyle = labelStyle.Foreground(t.TextMuted())
214 }
208 }
215−
209+
216 label := labelStyle.Render(m.argNames[i] + ":")
210 label := labelStyle.Render(m.argNames[i] + ":")
217
211
218 field := lipgloss.NewStyle().
212 field := lipgloss.NewStyle().
@@ -254,4 +248,4 @@ func (m *MultiArgumentsDialogCmp) SetSize(width, height int) {
254// Bindings implements layout.Bindings.
248// Bindings implements layout.Bindings.
255func (m MultiArgumentsDialogCmp) Bindings() []key.Binding {
249func (m MultiArgumentsDialogCmp) Bindings() []key.Binding {
256 return m.keys.ShortHelp()
250 return m.keys.ShortHelp()
257−}
251+}
internal/tui/components/dialog/commands.go+4−4
@@ -1,9 +1,9 @@
1package dialog
1package dialog
2
2
3import (
3import (
4− "github.com/charmbracelet/bubbles/key"
4+ "github.com/charmbracelet/bubbles/v2/key"
5− tea "github.com/charmbracelet/bubbletea"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
7 utilComponents "github.com/opencode-ai/opencode/internal/tui/components/util"
7 utilComponents "github.com/opencode-ai/opencode/internal/tui/components/util"
8 "github.com/opencode-ai/opencode/internal/tui/layout"
8 "github.com/opencode-ai/opencode/internal/tui/layout"
9 "github.com/opencode-ai/opencode/internal/tui/styles"
9 "github.com/opencode-ai/opencode/internal/tui/styles"
@@ -56,7 +56,7 @@ type CloseCommandDialogMsg struct{}
56
56
57// CommandDialog interface for the command selection dialog
57// CommandDialog interface for the command selection dialog
58type CommandDialog interface {
58type CommandDialog interface {
59− tea.Model
59+ util.Model
60 layout.Bindings
60 layout.Bindings
61 SetCommands(commands []Command)
61 SetCommands(commands []Command)
62}
62}
internal/tui/components/dialog/complete.go+5−5
@@ -1,10 +1,10 @@
1package dialog
1package dialog
2
2
3import (
3import (
4− "github.com/charmbracelet/bubbles/key"
4+ "github.com/charmbracelet/bubbles/v2/key"
5− "github.com/charmbracelet/bubbles/textarea"
5+ "github.com/charmbracelet/bubbles/v2/textarea"
6− tea "github.com/charmbracelet/bubbletea"
6+ tea "github.com/charmbracelet/bubbletea/v2"
7− "github.com/charmbracelet/lipgloss"
7+ "github.com/charmbracelet/lipgloss/v2"
8 "github.com/opencode-ai/opencode/internal/logging"
8 "github.com/opencode-ai/opencode/internal/logging"
9 utilComponents "github.com/opencode-ai/opencode/internal/tui/components/util"
9 utilComponents "github.com/opencode-ai/opencode/internal/tui/components/util"
10 "github.com/opencode-ai/opencode/internal/tui/layout"
10 "github.com/opencode-ai/opencode/internal/tui/layout"
@@ -77,7 +77,7 @@ type CompletionDialogCompleteItemMsg struct {
77type CompletionDialogCloseMsg struct{}
77type CompletionDialogCloseMsg struct{}
78
78
79type CompletionDialog interface {
79type CompletionDialog interface {
80− tea.Model
80+ util.Model
81 layout.Bindings
81 layout.Bindings
82 SetWidth(width int)
82 SetWidth(width int)
83}
83}
internal/tui/components/dialog/custom_commands.go+1−1
@@ -7,7 +7,7 @@ import (
7 "regexp"
7 "regexp"
8 "strings"
8 "strings"
9
9
10− tea "github.com/charmbracelet/bubbletea"
10+ tea "github.com/charmbracelet/bubbletea/v2"
11 "github.com/opencode-ai/opencode/internal/config"
11 "github.com/opencode-ai/opencode/internal/config"
12 "github.com/opencode-ai/opencode/internal/tui/util"
12 "github.com/opencode-ai/opencode/internal/tui/util"
13)
13)
internal/tui/components/dialog/filepicker.go+13−13
@@ -9,11 +9,11 @@ import (
9 "strings"
9 "strings"
10 "time"
10 "time"
11
11
12− "github.com/charmbracelet/bubbles/key"
12+ "github.com/charmbracelet/bubbles/v2/key"
13− "github.com/charmbracelet/bubbles/textinput"
13+ "github.com/charmbracelet/bubbles/v2/textinput"
14− "github.com/charmbracelet/bubbles/viewport"
14+ "github.com/charmbracelet/bubbles/v2/viewport"
15− tea "github.com/charmbracelet/bubbletea"
15+ tea "github.com/charmbracelet/bubbletea/v2"
16− "github.com/charmbracelet/lipgloss"
16+ "github.com/charmbracelet/lipgloss/v2"
17 "github.com/opencode-ai/opencode/internal/app"
17 "github.com/opencode-ai/opencode/internal/app"
18 "github.com/opencode-ai/opencode/internal/config"
18 "github.com/opencode-ai/opencode/internal/config"
19 "github.com/opencode-ai/opencode/internal/logging"
19 "github.com/opencode-ai/opencode/internal/logging"
@@ -122,8 +122,8 @@ func (f *filepickerCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
122 case tea.WindowSizeMsg:
122 case tea.WindowSizeMsg:
123 f.width = 60
123 f.width = 60
124 f.height = 20
124 f.height = 20
125− f.viewport.Width = 80
125+ f.viewport.SetWidth(80)
126− f.viewport.Height = 22
126+ f.viewport.SetHeight(22)
127 f.cursor = 0
127 f.cursor = 0
128 f.getCurrentFileBelowCursor()
128 f.getCurrentFileBelowCursor()
129 case tea.KeyMsg:
129 case tea.KeyMsg:
@@ -319,7 +319,7 @@ func (f *filepickerCmp) View() string {
319 Render(f.cwd.View())
319 Render(f.cwd.View())
320
320
321 viewportstyle := lipgloss.NewStyle().
321 viewportstyle := lipgloss.NewStyle().
322− Width(f.viewport.Width).
322+ Width(f.viewport.Width()).
323 Background(t.Background()).
323 Background(t.Background()).
324 Border(lipgloss.RoundedBorder()).
324 Border(lipgloss.RoundedBorder()).
325 BorderForeground(t.TextMuted()).
325 BorderForeground(t.TextMuted()).
@@ -353,7 +353,7 @@ func (f *filepickerCmp) View() string {
353}
353}
354
354
355type FilepickerCmp interface {
355type FilepickerCmp interface {
356− tea.Model
356+ util.Model
357 ToggleFilepicker(showFilepicker bool)
357 ToggleFilepicker(showFilepicker bool)
358 IsCWDFocused() bool
358 IsCWDFocused() bool
359}
359}
@@ -374,11 +374,11 @@ func NewFilepickerCmp(app *app.App) FilepickerCmp {
374 }
374 }
375 baseDir := DirNode{parent: nil, directory: homepath}
375 baseDir := DirNode{parent: nil, directory: homepath}
376 dirs := readDir(homepath, false)
376 dirs := readDir(homepath, false)
377− viewport := viewport.New(0, 0)
377+ viewport := viewport.New()
378 currentDirectory := textinput.New()
378 currentDirectory := textinput.New()
379 currentDirectory.CharLimit = 200
379 currentDirectory.CharLimit = 200
380− currentDirectory.Width = 44
380+ currentDirectory.SetWidth(44)
381− currentDirectory.Cursor.Blink = true
381+ currentDirectory.Cursor().Blink = true
382 currentDirectory.SetValue(baseDir.directory)
382 currentDirectory.SetValue(baseDir.directory)
383 return &filepickerCmp{cwdDetails: &baseDir, dirs: dirs, cursorChain: make(stack, 0), viewport: viewport, cwd: currentDirectory, app: app}
383 return &filepickerCmp{cwdDetails: &baseDir, dirs: dirs, cursorChain: make(stack, 0), viewport: viewport, cwd: currentDirectory, app: app}
384}
384}
@@ -396,7 +396,7 @@ func (f *filepickerCmp) getCurrentFileBelowCursor() {
396 fullPath := f.cwdDetails.directory + "/" + dir.Name()
396 fullPath := f.cwdDetails.directory + "/" + dir.Name()
397
397
398 go func() {
398 go func() {
399− imageString, err := image.ImagePreview(f.viewport.Width-4, fullPath)
399+ imageString, err := image.ImagePreview(f.viewport.Width()-4, fullPath)
400 if err != nil {
400 if err != nil {
401 logging.Error(err.Error())
401 logging.Error(err.Error())
402 f.viewport.SetContent("Preview unavailable")
402 f.viewport.SetContent("Preview unavailable")
internal/tui/components/dialog/help.go+7−6
@@ -3,11 +3,12 @@ package dialog
3import (
3import (
4 "strings"
4 "strings"
5
5
6− "github.com/charmbracelet/bubbles/key"
6+ "github.com/charmbracelet/bubbles/v2/key"
7− tea "github.com/charmbracelet/bubbletea"
7+ tea "github.com/charmbracelet/bubbletea/v2"
8− "github.com/charmbracelet/lipgloss"
8+ "github.com/charmbracelet/lipgloss/v2"
9 "github.com/opencode-ai/opencode/internal/tui/styles"
9 "github.com/opencode-ai/opencode/internal/tui/styles"
10 "github.com/opencode-ai/opencode/internal/tui/theme"
10 "github.com/opencode-ai/opencode/internal/tui/theme"
11+ "github.com/opencode-ai/opencode/internal/tui/util"
11)
12)
12
13
13type helpCmp struct {
14type helpCmp struct {
@@ -134,7 +135,7 @@ func (h *helpCmp) render() string {
134 pairs = append(pairs, pair)
135 pairs = append(pairs, pair)
135 }
136 }
136
137
137− // https://github.com/charmbracelet/lipgloss/issues/209
138+ // https://github.com/charmbracelet/lipgloss/v2/issues/209
138 if len(pairs) > 1 {
139 if len(pairs) > 1 {
139 prefix := pairs[:len(pairs)-1]
140 prefix := pairs[:len(pairs)-1]
140 lastPair := pairs[len(pairs)-1]
141 lastPair := pairs[len(pairs)-1]
@@ -144,7 +145,7 @@ func (h *helpCmp) render() string {
144 lipgloss.Left, // x
145 lipgloss.Left, // x
145 lipgloss.Top, // y
146 lipgloss.Top, // y
146 lastPair, // content
147 lastPair, // content
147− lipgloss.WithWhitespaceBackground(t.Background()),
148+ lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
148 ))
149 ))
149 content := baseStyle.Width(h.width).Render(
150 content := baseStyle.Width(h.width).Render(
150 lipgloss.JoinHorizontal(
151 lipgloss.JoinHorizontal(
@@ -191,7 +192,7 @@ func (h *helpCmp) View() string {
191}
192}
192
193
193type HelpCmp interface {
194type HelpCmp interface {
194− tea.Model
195+ util.Model
195 SetBindings([]key.Binding)
196 SetBindings([]key.Binding)
196}
197}
197
198
internal/tui/components/dialog/init.go+3−3
@@ -1,9 +1,9 @@
1package dialog
1package dialog
2
2
3import (
3import (
4− "github.com/charmbracelet/bubbles/key"
4+ "github.com/charmbracelet/bubbles/v2/key"
5− tea "github.com/charmbracelet/bubbletea"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
7
7
8 "github.com/opencode-ai/opencode/internal/tui/styles"
8 "github.com/opencode-ai/opencode/internal/tui/styles"
9 "github.com/opencode-ai/opencode/internal/tui/theme"
9 "github.com/opencode-ai/opencode/internal/tui/theme"
internal/tui/components/dialog/models.go+4−5
@@ -5,9 +5,9 @@ import (
5 "slices"
5 "slices"
6 "strings"
6 "strings"
7
7
8− "github.com/charmbracelet/bubbles/key"
8+ "github.com/charmbracelet/bubbles/v2/key"
9− tea "github.com/charmbracelet/bubbletea"
9+ tea "github.com/charmbracelet/bubbletea/v2"
10− "github.com/charmbracelet/lipgloss"
10+ "github.com/charmbracelet/lipgloss/v2"
11 "github.com/opencode-ai/opencode/internal/config"
11 "github.com/opencode-ai/opencode/internal/config"
12 "github.com/opencode-ai/opencode/internal/llm/models"
12 "github.com/opencode-ai/opencode/internal/llm/models"
13 "github.com/opencode-ai/opencode/internal/tui/layout"
13 "github.com/opencode-ai/opencode/internal/tui/layout"
@@ -31,7 +31,7 @@ type CloseModelDialogMsg struct{}
31
31
32// ModelDialog interface for the model selection dialog
32// ModelDialog interface for the model selection dialog
33type ModelDialog interface {
33type ModelDialog interface {
34− tea.Model
34+ util.Model
35 layout.Bindings
35 layout.Bindings
36}
36}
37
37
@@ -281,7 +281,6 @@ func (m *modelDialogCmp) setupModels() {
281}
281}
282
282
283func GetSelectedModel(cfg *config.Config) models.Model {
283func GetSelectedModel(cfg *config.Config) models.Model {
284−
285 agentCfg := cfg.Agents[config.AgentCoder]
284 agentCfg := cfg.Agents[config.AgentCoder]
286 selectedModelId := agentCfg.Model
285 selectedModelId := agentCfg.Model
287 return models.SupportedModels[selectedModelId]
286 return models.SupportedModels[selectedModelId]
internal/tui/components/dialog/permission.go+17−20
@@ -4,10 +4,10 @@ import (
4 "fmt"
4 "fmt"
5 "strings"
5 "strings"
6
6
7− "github.com/charmbracelet/bubbles/key"
7+ "github.com/charmbracelet/bubbles/v2/key"
8− "github.com/charmbracelet/bubbles/viewport"
8+ "github.com/charmbracelet/bubbles/v2/viewport"
9− tea "github.com/charmbracelet/bubbletea"
9+ tea "github.com/charmbracelet/bubbletea/v2"
10− "github.com/charmbracelet/lipgloss"
10+ "github.com/charmbracelet/lipgloss/v2"
11 "github.com/opencode-ai/opencode/internal/diff"
11 "github.com/opencode-ai/opencode/internal/diff"
12 "github.com/opencode-ai/opencode/internal/llm/tools"
12 "github.com/opencode-ai/opencode/internal/llm/tools"
13 "github.com/opencode-ai/opencode/internal/permission"
13 "github.com/opencode-ai/opencode/internal/permission"
@@ -34,7 +34,7 @@ type PermissionResponseMsg struct {
34
34
35// PermissionDialogCmp interface for permission dialog component
35// PermissionDialogCmp interface for permission dialog component
36type PermissionDialogCmp interface {
36type PermissionDialogCmp interface {
37− tea.Model
37+ util.Model
38 layout.Bindings
38 layout.Bindings
39 SetPermissions(permission permission.PermissionRequest) tea.Cmd
39 SetPermissions(permission permission.PermissionRequest) tea.Cmd
40}
40}
@@ -268,7 +268,6 @@ func (p *permissionDialogCmp) renderHeader() string {
268}
268}
269
269
270func (p *permissionDialogCmp) renderBashContent() string {
270func (p *permissionDialogCmp) renderBashContent() string {
271− t := theme.CurrentTheme()
272 baseStyle := styles.BaseStyle()
271 baseStyle := styles.BaseStyle()
273
272
274 if pr, ok := p.permission.Params.(tools.BashPermissionsParams); ok {
273 if pr, ok := p.permission.Params.(tools.BashPermissionsParams); ok {
@@ -278,11 +277,11 @@ func (p *permissionDialogCmp) renderBashContent() string {
278 renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
277 renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
279 r := styles.GetMarkdownRenderer(p.width - 10)
278 r := styles.GetMarkdownRenderer(p.width - 10)
280 s, err := r.Render(content)
279 s, err := r.Render(content)
281− return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
280+ return s, err
282 })
281 })
283
282
284 finalContent := baseStyle.
283 finalContent := baseStyle.
285− Width(p.contentViewPort.Width).
284+ Width(p.contentViewPort.Width()).
286 Render(renderedContent)
285 Render(renderedContent)
287 p.contentViewPort.SetContent(finalContent)
286 p.contentViewPort.SetContent(finalContent)
288 return p.styleViewport()
287 return p.styleViewport()
@@ -293,7 +292,7 @@ func (p *permissionDialogCmp) renderBashContent() string {
293func (p *permissionDialogCmp) renderEditContent() string {
292func (p *permissionDialogCmp) renderEditContent() string {
294 if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
293 if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
295 diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
294 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()))
297 })
296 })
298
297
299 p.contentViewPort.SetContent(diff)
298 p.contentViewPort.SetContent(diff)
@@ -305,7 +304,7 @@ func (p *permissionDialogCmp) renderEditContent() string {
305func (p *permissionDialogCmp) renderPatchContent() string {
304func (p *permissionDialogCmp) renderPatchContent() string {
306 if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
305 if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
307 diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
306 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()))
309 })
308 })
310
309
311 p.contentViewPort.SetContent(diff)
310 p.contentViewPort.SetContent(diff)
@@ -318,7 +317,7 @@ func (p *permissionDialogCmp) renderWriteContent() string {
318 if pr, ok := p.permission.Params.(tools.WritePermissionsParams); ok {
317 if pr, ok := p.permission.Params.(tools.WritePermissionsParams); ok {
319 // Use the cache for diff rendering
318 // Use the cache for diff rendering
320 diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
319 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()))
322 })
321 })
323
322
324 p.contentViewPort.SetContent(diff)
323 p.contentViewPort.SetContent(diff)
@@ -328,7 +327,6 @@ func (p *permissionDialogCmp) renderWriteContent() string {
328}
327}
329
328
330func (p *permissionDialogCmp) renderFetchContent() string {
329func (p *permissionDialogCmp) renderFetchContent() string {
331− t := theme.CurrentTheme()
332 baseStyle := styles.BaseStyle()
330 baseStyle := styles.BaseStyle()
333
331
334 if pr, ok := p.permission.Params.(tools.FetchPermissionsParams); ok {
332 if pr, ok := p.permission.Params.(tools.FetchPermissionsParams); ok {
@@ -338,11 +336,11 @@ func (p *permissionDialogCmp) renderFetchContent() string {
338 renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
336 renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
339 r := styles.GetMarkdownRenderer(p.width - 10)
337 r := styles.GetMarkdownRenderer(p.width - 10)
340 s, err := r.Render(content)
338 s, err := r.Render(content)
341− return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
339+ return s, err
342 })
340 })
343
341
344 finalContent := baseStyle.
342 finalContent := baseStyle.
345− Width(p.contentViewPort.Width).
343+ Width(p.contentViewPort.Width()).
346 Render(renderedContent)
344 Render(renderedContent)
347 p.contentViewPort.SetContent(finalContent)
345 p.contentViewPort.SetContent(finalContent)
348 return p.styleViewport()
346 return p.styleViewport()
@@ -351,7 +349,6 @@ func (p *permissionDialogCmp) renderFetchContent() string {
351}
349}
352
350
353func (p *permissionDialogCmp) renderDefaultContent() string {
351func (p *permissionDialogCmp) renderDefaultContent() string {
354− t := theme.CurrentTheme()
355 baseStyle := styles.BaseStyle()
352 baseStyle := styles.BaseStyle()
356
353
357 content := p.permission.Description
354 content := p.permission.Description
@@ -360,11 +357,11 @@ func (p *permissionDialogCmp) renderDefaultContent() string {
360 renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
357 renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) {
361 r := styles.GetMarkdownRenderer(p.width - 10)
358 r := styles.GetMarkdownRenderer(p.width - 10)
362 s, err := r.Render(content)
359 s, err := r.Render(content)
363− return styles.ForceReplaceBackgroundWithLipgloss(s, t.Background()), err
360+ return s, err
364 })
361 })
365
362
366 finalContent := baseStyle.
363 finalContent := baseStyle.
367− Width(p.contentViewPort.Width).
364+ Width(p.contentViewPort.Width()).
368 Render(renderedContent)
365 Render(renderedContent)
369 p.contentViewPort.SetContent(finalContent)
366 p.contentViewPort.SetContent(finalContent)
370
367
@@ -398,8 +395,8 @@ func (p *permissionDialogCmp) render() string {
398 buttons := p.renderButtons()
395 buttons := p.renderButtons()
399
396
400 // Calculate content height dynamically based on window size
397 // Calculate content height dynamically based on window size
401− p.contentViewPort.Height = p.height - lipgloss.Height(headerContent) - lipgloss.Height(buttons) - 2 - lipgloss.Height(title)
398+ p.contentViewPort.SetHeight(p.height - lipgloss.Height(headerContent) - lipgloss.Height(buttons) - 2 - lipgloss.Height(title))
402− p.contentViewPort.Width = p.width - 4
399+ p.contentViewPort.SetWidth(p.width - 4)
403
400
404 // Render content based on tool type
401 // Render content based on tool type
405 var contentFinal string
402 var contentFinal string
@@ -511,7 +508,7 @@ func (c *permissionDialogCmp) GetOrSetMarkdown(key string, generator func() (str
511
508
512func NewPermissionDialogCmp() PermissionDialogCmp {
509func NewPermissionDialogCmp() PermissionDialogCmp {
513 // Create viewport for content
510 // Create viewport for content
514− contentViewport := viewport.New(0, 0)
511+ contentViewport := viewport.New()
515
512
516 return &permissionDialogCmp{
513 return &permissionDialogCmp{
517 contentViewPort: contentViewport,
514 contentViewPort: contentViewport,
internal/tui/components/dialog/quit.go+5−5
@@ -3,9 +3,9 @@ package dialog
3import (
3import (
4 "strings"
4 "strings"
5
5
6− "github.com/charmbracelet/bubbles/key"
6+ "github.com/charmbracelet/bubbles/v2/key"
7− tea "github.com/charmbracelet/bubbletea"
7+ tea "github.com/charmbracelet/bubbletea/v2"
8− "github.com/charmbracelet/lipgloss"
8+ "github.com/charmbracelet/lipgloss/v2"
9 "github.com/opencode-ai/opencode/internal/tui/layout"
9 "github.com/opencode-ai/opencode/internal/tui/layout"
10 "github.com/opencode-ai/opencode/internal/tui/styles"
10 "github.com/opencode-ai/opencode/internal/tui/styles"
11 "github.com/opencode-ai/opencode/internal/tui/theme"
11 "github.com/opencode-ai/opencode/internal/tui/theme"
@@ -17,7 +17,7 @@ const question = "Are you sure you want to quit?"
17type CloseQuitMsg struct{}
17type CloseQuitMsg struct{}
18
18
19type QuitDialog interface {
19type QuitDialog interface {
20− tea.Model
20+ util.Model
21 layout.Bindings
21 layout.Bindings
22}
22}
23
23
@@ -84,7 +84,7 @@ func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
84func (q *quitDialogCmp) View() string {
84func (q *quitDialogCmp) View() string {
85 t := theme.CurrentTheme()
85 t := theme.CurrentTheme()
86 baseStyle := styles.BaseStyle()
86 baseStyle := styles.BaseStyle()
87−
87+
88 yesStyle := baseStyle
88 yesStyle := baseStyle
89 noStyle := baseStyle
89 noStyle := baseStyle
90 spacerStyle := baseStyle.Background(t.Background())
90 spacerStyle := baseStyle.Background(t.Background())
internal/tui/components/dialog/session.go+5−6
@@ -1,9 +1,9 @@
1package dialog
1package dialog
2
2
3import (
3import (
4− "github.com/charmbracelet/bubbles/key"
4+ "github.com/charmbracelet/bubbles/v2/key"
5− tea "github.com/charmbracelet/bubbletea"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
7 "github.com/opencode-ai/opencode/internal/session"
7 "github.com/opencode-ai/opencode/internal/session"
8 "github.com/opencode-ai/opencode/internal/tui/layout"
8 "github.com/opencode-ai/opencode/internal/tui/layout"
9 "github.com/opencode-ai/opencode/internal/tui/styles"
9 "github.com/opencode-ai/opencode/internal/tui/styles"
@@ -21,7 +21,7 @@ type CloseSessionDialogMsg struct{}
21
21
22// SessionDialog interface for the session switching dialog
22// SessionDialog interface for the session switching dialog
23type SessionDialog interface {
23type SessionDialog interface {
24− tea.Model
24+ util.Model
25 layout.Bindings
25 layout.Bindings
26 SetSessions(sessions []session.Session)
26 SetSessions(sessions []session.Session)
27 SetSelectedSession(sessionID string)
27 SetSelectedSession(sessionID string)
@@ -108,7 +108,7 @@ func (s *sessionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
108func (s *sessionDialogCmp) View() string {
108func (s *sessionDialogCmp) View() string {
109 t := theme.CurrentTheme()
109 t := theme.CurrentTheme()
110 baseStyle := styles.BaseStyle()
110 baseStyle := styles.BaseStyle()
111−
111+
112 if len(s.sessions) == 0 {
112 if len(s.sessions) == 0 {
113 return baseStyle.Padding(1, 2).
113 return baseStyle.Padding(1, 2).
114 Border(lipgloss.RoundedBorder()).
114 Border(lipgloss.RoundedBorder()).
@@ -181,7 +181,6 @@ func (s *sessionDialogCmp) View() string {
181 Border(lipgloss.RoundedBorder()).
181 Border(lipgloss.RoundedBorder()).
182 BorderBackground(t.Background()).
182 BorderBackground(t.Background()).
183 BorderForeground(t.TextMuted()).
183 BorderForeground(t.TextMuted()).
184− Width(lipgloss.Width(content) + 4).
185 Render(content)
184 Render(content)
186}
185}
187
186
internal/tui/components/dialog/theme.go+4−5
@@ -1,9 +1,9 @@
1package dialog
1package dialog
2
2
3import (
3import (
4− "github.com/charmbracelet/bubbles/key"
4+ "github.com/charmbracelet/bubbles/v2/key"
5− tea "github.com/charmbracelet/bubbletea"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
7 "github.com/opencode-ai/opencode/internal/tui/layout"
7 "github.com/opencode-ai/opencode/internal/tui/layout"
8 "github.com/opencode-ai/opencode/internal/tui/styles"
8 "github.com/opencode-ai/opencode/internal/tui/styles"
9 "github.com/opencode-ai/opencode/internal/tui/theme"
9 "github.com/opencode-ai/opencode/internal/tui/theme"
@@ -20,7 +20,7 @@ type CloseThemeDialogMsg struct{}
20
20
21// ThemeDialog interface for the theme switching dialog
21// ThemeDialog interface for the theme switching dialog
22type ThemeDialog interface {
22type ThemeDialog interface {
23− tea.Model
23+ util.Model
24 layout.Bindings
24 layout.Bindings
25}
25}
26
26
@@ -195,4 +195,3 @@ func NewThemeDialogCmp() ThemeDialog {
195 currentTheme: "",
195 currentTheme: "",
196 }
196 }
197}
197}
198−
internal/tui/components/logs/details.go+11−12
@@ -5,18 +5,18 @@ import (
5 "strings"
5 "strings"
6 "time"
6 "time"
7
7
8− "github.com/charmbracelet/bubbles/key"
8+ "github.com/charmbracelet/bubbles/v2/key"
9− "github.com/charmbracelet/bubbles/viewport"
9+ "github.com/charmbracelet/bubbles/v2/viewport"
10− tea "github.com/charmbracelet/bubbletea"
10+ tea "github.com/charmbracelet/bubbletea/v2"
11− "github.com/charmbracelet/lipgloss"
11+ "github.com/charmbracelet/lipgloss/v2"
12 "github.com/opencode-ai/opencode/internal/logging"
12 "github.com/opencode-ai/opencode/internal/logging"
13 "github.com/opencode-ai/opencode/internal/tui/layout"
13 "github.com/opencode-ai/opencode/internal/tui/layout"
14− "github.com/opencode-ai/opencode/internal/tui/styles"
15 "github.com/opencode-ai/opencode/internal/tui/theme"
14 "github.com/opencode-ai/opencode/internal/tui/theme"
15+ "github.com/opencode-ai/opencode/internal/tui/util"
16)
16)
17
17
18type DetailComponent interface {
18type DetailComponent interface {
19− tea.Model
19+ util.Model
20 layout.Sizeable
20 layout.Sizeable
21 layout.Bindings
21 layout.Bindings
22}
22}
@@ -99,7 +99,7 @@ func (i *detailCmp) updateContent() {
99func getLevelStyle(level string) lipgloss.Style {
99func getLevelStyle(level string) lipgloss.Style {
100 style := lipgloss.NewStyle().Bold(true)
100 style := lipgloss.NewStyle().Bold(true)
101 t := theme.CurrentTheme()
101 t := theme.CurrentTheme()
102−
102+
103 switch strings.ToLower(level) {
103 switch strings.ToLower(level) {
104 case "info":
104 case "info":
105 return style.Foreground(t.Info())
105 return style.Foreground(t.Info())
@@ -115,8 +115,7 @@ func getLevelStyle(level string) lipgloss.Style {
115}
115}
116
116
117func (i *detailCmp) View() string {
117func (i *detailCmp) View() string {
118− t := theme.CurrentTheme()
119− return styles.ForceReplaceBackgroundWithLipgloss(i.viewport.View(), t.Background())
118+ return i.viewport.View()
120}
119}
121
120
122func (i *detailCmp) GetSize() (int, int) {
121func (i *detailCmp) GetSize() (int, int) {
@@ -126,8 +125,8 @@ func (i *detailCmp) GetSize() (int, int) {
126func (i *detailCmp) SetSize(width int, height int) tea.Cmd {
125func (i *detailCmp) SetSize(width int, height int) tea.Cmd {
127 i.width = width
126 i.width = width
128 i.height = height
127 i.height = height
129− i.viewport.Width = i.width
128+ i.viewport.SetWidth(i.width)
130− i.viewport.Height = i.height
129+ i.viewport.SetHeight(i.height)
131 i.updateContent()
130 i.updateContent()
132 return nil
131 return nil
133}
132}
@@ -138,6 +137,6 @@ func (i *detailCmp) BindingKeys() []key.Binding {
138
137
139func NewLogsDetails() DetailComponent {
138func NewLogsDetails() DetailComponent {
140 return &detailCmp{
139 return &detailCmp{
141− viewport: viewport.New(0, 0),
140+ viewport: viewport.New(),
142 }
141 }
143}
142}
internal/tui/components/logs/table.go+5−6
@@ -4,19 +4,18 @@ import (
4 "encoding/json"
4 "encoding/json"
5 "slices"
5 "slices"
6
6
7− "github.com/charmbracelet/bubbles/key"
7+ "github.com/charmbracelet/bubbles/v2/key"
8− "github.com/charmbracelet/bubbles/table"
8+ "github.com/charmbracelet/bubbles/v2/table"
9− tea "github.com/charmbracelet/bubbletea"
9+ tea "github.com/charmbracelet/bubbletea/v2"
10 "github.com/opencode-ai/opencode/internal/logging"
10 "github.com/opencode-ai/opencode/internal/logging"
11 "github.com/opencode-ai/opencode/internal/pubsub"
11 "github.com/opencode-ai/opencode/internal/pubsub"
12 "github.com/opencode-ai/opencode/internal/tui/layout"
12 "github.com/opencode-ai/opencode/internal/tui/layout"
13− "github.com/opencode-ai/opencode/internal/tui/styles"
14 "github.com/opencode-ai/opencode/internal/tui/theme"
13 "github.com/opencode-ai/opencode/internal/tui/theme"
15 "github.com/opencode-ai/opencode/internal/tui/util"
14 "github.com/opencode-ai/opencode/internal/tui/util"
16)
15)
17
16
18type TableComponent interface {
17type TableComponent interface {
19− tea.Model
18+ util.Model
20 layout.Sizeable
19 layout.Sizeable
21 layout.Bindings
20 layout.Bindings
22}
21}
@@ -66,7 +65,7 @@ func (i *tableCmp) View() string {
66 defaultStyles := table.DefaultStyles()
65 defaultStyles := table.DefaultStyles()
67 defaultStyles.Selected = defaultStyles.Selected.Foreground(t.Primary())
66 defaultStyles.Selected = defaultStyles.Selected.Foreground(t.Primary())
68 i.table.SetStyles(defaultStyles)
67 i.table.SetStyles(defaultStyles)
69− return styles.ForceReplaceBackgroundWithLipgloss(i.table.View(), t.Background())
68+ return i.table.View()
70}
69}
71
70
72func (i *tableCmp) GetSize() (int, int) {
71func (i *tableCmp) GetSize() (int, int) {
internal/tui/components/util/simple-list.go+5−4
@@ -1,12 +1,13 @@
1package utilComponents
1package utilComponents
2
2
3import (
3import (
4− "github.com/charmbracelet/bubbles/key"
4+ "github.com/charmbracelet/bubbles/v2/key"
5− tea "github.com/charmbracelet/bubbletea"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
7 "github.com/opencode-ai/opencode/internal/tui/layout"
7 "github.com/opencode-ai/opencode/internal/tui/layout"
8 "github.com/opencode-ai/opencode/internal/tui/styles"
8 "github.com/opencode-ai/opencode/internal/tui/styles"
9 "github.com/opencode-ai/opencode/internal/tui/theme"
9 "github.com/opencode-ai/opencode/internal/tui/theme"
10+ "github.com/opencode-ai/opencode/internal/tui/util"
10)
11)
11
12
12type SimpleListItem interface {
13type SimpleListItem interface {
@@ -14,7 +15,7 @@ type SimpleListItem interface {
14}
15}
15
16
16type SimpleList[T SimpleListItem] interface {
17type SimpleList[T SimpleListItem] interface {
17− tea.Model
18+ util.Model
18 layout.Bindings
19 layout.Bindings
19 SetMaxWidth(maxWidth int)
20 SetMaxWidth(maxWidth int)
20 GetSelectedItem() (item T, idx int)
21 GetSelectedItem() (item T, idx int)
internal/tui/image/images.go+3−2
@@ -3,10 +3,11 @@ package image
3import (
3import (
4 "fmt"
4 "fmt"
5 "image"
5 "image"
6+ "image/color"
6 "os"
7 "os"
7 "strings"
8 "strings"
8
9
9− "github.com/charmbracelet/lipgloss"
10+ "github.com/charmbracelet/lipgloss/v2"
10 "github.com/disintegration/imaging"
11 "github.com/disintegration/imaging"
11 "github.com/lucasb-eyer/go-colorful"
12 "github.com/lucasb-eyer/go-colorful"
12)
13)
@@ -36,7 +37,7 @@ func ToString(width int, img image.Image) string {
36 c1, _ := colorful.MakeColor(img.At(x, heightCounter))
37 c1, _ := colorful.MakeColor(img.At(x, heightCounter))
37 color1 := lipgloss.Color(c1.Hex())
38 color1 := lipgloss.Color(c1.Hex())
38
39
39− var color2 lipgloss.Color
40+ var color2 color.Color
40 if heightCounter+1 < h {
41 if heightCounter+1 < h {
41 c2, _ := colorful.MakeColor(img.At(x, heightCounter+1))
42 c2, _ := colorful.MakeColor(img.At(x, heightCounter+1))
42 color2 = lipgloss.Color(c2.Hex())
43 color2 = lipgloss.Color(c2.Hex())
internal/tui/layout/container.go+8−8
@@ -1,14 +1,15 @@
1package layout
1package layout
2
2
3import (
3import (
4− "github.com/charmbracelet/bubbles/key"
4+ "github.com/charmbracelet/bubbles/v2/key"
5− tea "github.com/charmbracelet/bubbletea"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
7 "github.com/opencode-ai/opencode/internal/tui/theme"
7 "github.com/opencode-ai/opencode/internal/tui/theme"
8+ "github.com/opencode-ai/opencode/internal/tui/util"
8)
9)
9
10
10type Container interface {
11type Container interface {
11− tea.Model
12+ util.Model
12 Sizeable
13 Sizeable
13 Bindings
14 Bindings
14}
15}
@@ -16,7 +17,7 @@ type container struct {
16 width int
17 width int
17 height int
18 height int
18
19
19− content tea.Model
20+ content util.Model
20
21
21 // Style options
22 // Style options
22 paddingTop int
23 paddingTop int
@@ -37,7 +38,7 @@ func (c *container) Init() tea.Cmd {
37
38
38func (c *container) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
39func (c *container) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
39 u, cmd := c.content.Update(msg)
40 u, cmd := c.content.Update(msg)
40− c.content = u
41+ c.content = u.(util.Model)
41 return c, cmd
42 return c, cmd
42}
43}
43
44
@@ -123,8 +124,7 @@ func (c *container) BindingKeys() []key.Binding {
123
124
124type ContainerOption func(*container)
125type ContainerOption func(*container)
125
126
126−func NewContainer(content tea.Model, options ...ContainerOption) Container {
127+func NewContainer(content util.Model, options ...ContainerOption) Container {
127−
128 c := &container{
128 c := &container{
129 content: content,
129 content: content,
130 borderStyle: lipgloss.NormalBorder(),
130 borderStyle: lipgloss.NormalBorder(),
internal/tui/layout/layout.go+2−2
@@ -3,8 +3,8 @@ package layout
3import (
3import (
4 "reflect"
4 "reflect"
5
5
6− "github.com/charmbracelet/bubbles/key"
6+ "github.com/charmbracelet/bubbles/v2/key"
7− tea "github.com/charmbracelet/bubbletea"
7+ tea "github.com/charmbracelet/bubbletea/v2"
8)
8)
9
9
10type Focusable interface {
10type Focusable interface {
internal/tui/layout/overlay.go+2−2
@@ -3,7 +3,7 @@ package layout
3import (
3import (
4 "strings"
4 "strings"
5
5
6− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
7 chAnsi "github.com/charmbracelet/x/ansi"
7 chAnsi "github.com/charmbracelet/x/ansi"
8 "github.com/muesli/ansi"
8 "github.com/muesli/ansi"
9 "github.com/muesli/reflow/truncate"
9 "github.com/muesli/reflow/truncate"
@@ -14,7 +14,7 @@ import (
14)
14)
15
15
16// Most of this code is borrowed from
16// Most of this code is borrowed from
17−// https://github.com/charmbracelet/lipgloss/pull/102
17+// https://github.com/charmbracelet/lipgloss/v2/pull/102
18// as well as the lipgloss library, with some modification for what I needed.
18// as well as the lipgloss library, with some modification for what I needed.
19
19
20// Split a string into lines, additionally returning the size of the widest
20// Split a string into lines, additionally returning the size of the widest
internal/tui/layout/split.go+5−5
@@ -1,14 +1,15 @@
1package layout
1package layout
2
2
3import (
3import (
4− "github.com/charmbracelet/bubbles/key"
4+ "github.com/charmbracelet/bubbles/v2/key"
5− tea "github.com/charmbracelet/bubbletea"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
7 "github.com/opencode-ai/opencode/internal/tui/theme"
7 "github.com/opencode-ai/opencode/internal/tui/theme"
8+ "github.com/opencode-ai/opencode/internal/tui/util"
8)
9)
9
10
10type SplitPaneLayout interface {
11type SplitPaneLayout interface {
11− tea.Model
12+ util.Model
12 Sizeable
13 Sizeable
13 Bindings
14 Bindings
14 SetLeftPanel(panel Container) tea.Cmd
15 SetLeftPanel(panel Container) tea.Cmd
@@ -241,7 +242,6 @@ func (s *splitPaneLayout) BindingKeys() []key.Binding {
241}
242}
242
243
243func NewSplitPane(options ...SplitPaneOption) SplitPaneLayout {
244func NewSplitPane(options ...SplitPaneOption) SplitPaneLayout {
244−
245 layout := &splitPaneLayout{
245 layout := &splitPaneLayout{
246 ratio: 0.7,
246 ratio: 0.7,
247 verticalRatio: 0.9, // Default 90% for top section, 10% for bottom
247 verticalRatio: 0.9, // Default 90% for top section, 10% for bottom
internal/tui/page/chat.go+6−6
@@ -4,9 +4,9 @@ import (
4 "context"
4 "context"
5 "strings"
5 "strings"
6
6
7− "github.com/charmbracelet/bubbles/key"
7+ "github.com/charmbracelet/bubbles/v2/key"
8− tea "github.com/charmbracelet/bubbletea"
8+ tea "github.com/charmbracelet/bubbletea/v2"
9− "github.com/charmbracelet/lipgloss"
9+ "github.com/charmbracelet/lipgloss/v2"
10 "github.com/opencode-ai/opencode/internal/app"
10 "github.com/opencode-ai/opencode/internal/app"
11 "github.com/opencode-ai/opencode/internal/completions"
11 "github.com/opencode-ai/opencode/internal/completions"
12 "github.com/opencode-ai/opencode/internal/message"
12 "github.com/opencode-ai/opencode/internal/message"
@@ -76,7 +76,7 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
76 if p.app.CoderAgent.IsBusy() {
76 if p.app.CoderAgent.IsBusy() {
77 return p, util.ReportWarn("Agent is busy, please wait before executing a command...")
77 return p, util.ReportWarn("Agent is busy, please wait before executing a command...")
78 }
78 }
79−
79+
80 // Process the command content with arguments if any
80 // Process the command content with arguments if any
81 content := msg.Content
81 content := msg.Content
82 if msg.Args != nil {
82 if msg.Args != nil {
@@ -86,7 +86,7 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
86 content = strings.ReplaceAll(content, placeholder, value)
86 content = strings.ReplaceAll(content, placeholder, value)
87 }
87 }
88 }
88 }
89−
89+
90 // Handle custom command execution
90 // Handle custom command execution
91 cmd := p.sendMessage(content, nil)
91 cmd := p.sendMessage(content, nil)
92 if cmd != nil {
92 if cmd != nil {
@@ -212,7 +212,7 @@ func (p *chatPage) BindingKeys() []key.Binding {
212 return bindings
212 return bindings
213}
213}
214
214
215−func NewChatPage(app *app.App) tea.Model {
215+func NewChatPage(app *app.App) util.Model {
216 cg := completions.NewFileAndFolderContextGroup()
216 cg := completions.NewFileAndFolderContextGroup()
217 completionDialog := dialog.NewCompletionDialogCmp(cg)
217 completionDialog := dialog.NewCompletionDialogCmp(cg)
218
218
internal/tui/page/logs.go+5−4
@@ -1,18 +1,19 @@
1package page
1package page
2
2
3import (
3import (
4− "github.com/charmbracelet/bubbles/key"
4+ "github.com/charmbracelet/bubbles/v2/key"
5− tea "github.com/charmbracelet/bubbletea"
5+ tea "github.com/charmbracelet/bubbletea/v2"
6− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
7 "github.com/opencode-ai/opencode/internal/tui/components/logs"
7 "github.com/opencode-ai/opencode/internal/tui/components/logs"
8 "github.com/opencode-ai/opencode/internal/tui/layout"
8 "github.com/opencode-ai/opencode/internal/tui/layout"
9 "github.com/opencode-ai/opencode/internal/tui/styles"
9 "github.com/opencode-ai/opencode/internal/tui/styles"
10+ "github.com/opencode-ai/opencode/internal/tui/util"
10)
11)
11
12
12var LogsPage PageID = "logs"
13var LogsPage PageID = "logs"
13
14
14type LogPage interface {
15type LogPage interface {
15− tea.Model
16+ util.Model
16 layout.Sizeable
17 layout.Sizeable
17 layout.Bindings
18 layout.Bindings
18}
19}
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 @@
1package styles
1package styles
2
2
3import (
3import (
4+ "fmt"
5+ "image/color"
6+
4− "github.com/charmbracelet/glamour"
7+ "github.com/charmbracelet/glamour/v2"
5− "github.com/charmbracelet/glamour/ansi"
8+ "github.com/charmbracelet/glamour/v2/ansi"
6− "github.com/charmbracelet/lipgloss"
7 "github.com/opencode-ai/opencode/internal/tui/theme"
9 "github.com/opencode-ai/opencode/internal/tui/theme"
8)
10)
9
11
@@ -33,13 +35,13 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
33 StylePrimitive: ansi.StylePrimitive{
35 StylePrimitive: ansi.StylePrimitive{
34 BlockPrefix: "",
36 BlockPrefix: "",
35 BlockSuffix: "",
37 BlockSuffix: "",
36− Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
38+ Color: stringPtr(colorToString(t.MarkdownText())),
37 },
39 },
38 Margin: uintPtr(defaultMargin),
40 Margin: uintPtr(defaultMargin),
39 },
41 },
40 BlockQuote: ansi.StyleBlock{
42 BlockQuote: ansi.StyleBlock{
41 StylePrimitive: ansi.StylePrimitive{
43 StylePrimitive: ansi.StylePrimitive{
42− Color: stringPtr(adaptiveColorToString(t.MarkdownBlockQuote())),
44+ Color: stringPtr(colorToString(t.MarkdownBlockQuote())),
43 Italic: boolPtr(true),
45 Italic: boolPtr(true),
44 Prefix: "┃ ",
46 Prefix: "┃ ",
45 },
47 },
@@ -51,82 +53,82 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
51 StyleBlock: ansi.StyleBlock{
53 StyleBlock: ansi.StyleBlock{
52 IndentToken: stringPtr(BaseStyle().Render(" ")),
54 IndentToken: stringPtr(BaseStyle().Render(" ")),
53 StylePrimitive: ansi.StylePrimitive{
55 StylePrimitive: ansi.StylePrimitive{
54− Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
56+ Color: stringPtr(colorToString(t.MarkdownText())),
55 },
57 },
56 },
58 },
57 },
59 },
58 Heading: ansi.StyleBlock{
60 Heading: ansi.StyleBlock{
59 StylePrimitive: ansi.StylePrimitive{
61 StylePrimitive: ansi.StylePrimitive{
60 BlockSuffix: "\n",
62 BlockSuffix: "\n",
61− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
63+ Color: stringPtr(colorToString(t.MarkdownHeading())),
62 Bold: boolPtr(true),
64 Bold: boolPtr(true),
63 },
65 },
64 },
66 },
65 H1: ansi.StyleBlock{
67 H1: ansi.StyleBlock{
66 StylePrimitive: ansi.StylePrimitive{
68 StylePrimitive: ansi.StylePrimitive{
67 Prefix: "# ",
69 Prefix: "# ",
68− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
70+ Color: stringPtr(colorToString(t.MarkdownHeading())),
69 Bold: boolPtr(true),
71 Bold: boolPtr(true),
70 },
72 },
71 },
73 },
72 H2: ansi.StyleBlock{
74 H2: ansi.StyleBlock{
73 StylePrimitive: ansi.StylePrimitive{
75 StylePrimitive: ansi.StylePrimitive{
74 Prefix: "## ",
76 Prefix: "## ",
75− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
77+ Color: stringPtr(colorToString(t.MarkdownHeading())),
76 Bold: boolPtr(true),
78 Bold: boolPtr(true),
77 },
79 },
78 },
80 },
79 H3: ansi.StyleBlock{
81 H3: ansi.StyleBlock{
80 StylePrimitive: ansi.StylePrimitive{
82 StylePrimitive: ansi.StylePrimitive{
81 Prefix: "### ",
83 Prefix: "### ",
82− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
84+ Color: stringPtr(colorToString(t.MarkdownHeading())),
83 Bold: boolPtr(true),
85 Bold: boolPtr(true),
84 },
86 },
85 },
87 },
86 H4: ansi.StyleBlock{
88 H4: ansi.StyleBlock{
87 StylePrimitive: ansi.StylePrimitive{
89 StylePrimitive: ansi.StylePrimitive{
88 Prefix: "#### ",
90 Prefix: "#### ",
89− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
91+ Color: stringPtr(colorToString(t.MarkdownHeading())),
90 Bold: boolPtr(true),
92 Bold: boolPtr(true),
91 },
93 },
92 },
94 },
93 H5: ansi.StyleBlock{
95 H5: ansi.StyleBlock{
94 StylePrimitive: ansi.StylePrimitive{
96 StylePrimitive: ansi.StylePrimitive{
95 Prefix: "##### ",
97 Prefix: "##### ",
96− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
98+ Color: stringPtr(colorToString(t.MarkdownHeading())),
97 Bold: boolPtr(true),
99 Bold: boolPtr(true),
98 },
100 },
99 },
101 },
100 H6: ansi.StyleBlock{
102 H6: ansi.StyleBlock{
101 StylePrimitive: ansi.StylePrimitive{
103 StylePrimitive: ansi.StylePrimitive{
102 Prefix: "###### ",
104 Prefix: "###### ",
103− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
105+ Color: stringPtr(colorToString(t.MarkdownHeading())),
104 Bold: boolPtr(true),
106 Bold: boolPtr(true),
105 },
107 },
106 },
108 },
107 Strikethrough: ansi.StylePrimitive{
109 Strikethrough: ansi.StylePrimitive{
108 CrossedOut: boolPtr(true),
110 CrossedOut: boolPtr(true),
109− Color: stringPtr(adaptiveColorToString(t.TextMuted())),
111+ Color: stringPtr(colorToString(t.TextMuted())),
110 },
112 },
111 Emph: ansi.StylePrimitive{
113 Emph: ansi.StylePrimitive{
112− Color: stringPtr(adaptiveColorToString(t.MarkdownEmph())),
114+ Color: stringPtr(colorToString(t.MarkdownEmph())),
113 Italic: boolPtr(true),
115 Italic: boolPtr(true),
114 },
116 },
115 Strong: ansi.StylePrimitive{
117 Strong: ansi.StylePrimitive{
116 Bold: boolPtr(true),
118 Bold: boolPtr(true),
117− Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
119+ Color: stringPtr(colorToString(t.MarkdownStrong())),
118 },
120 },
119 HorizontalRule: ansi.StylePrimitive{
121 HorizontalRule: ansi.StylePrimitive{
120− Color: stringPtr(adaptiveColorToString(t.MarkdownHorizontalRule())),
122+ Color: stringPtr(colorToString(t.MarkdownHorizontalRule())),
121 Format: "\n─────────────────────────────────────────\n",
123 Format: "\n─────────────────────────────────────────\n",
122 },
124 },
123 Item: ansi.StylePrimitive{
125 Item: ansi.StylePrimitive{
124 BlockPrefix: "• ",
126 BlockPrefix: "• ",
125− Color: stringPtr(adaptiveColorToString(t.MarkdownListItem())),
127+ Color: stringPtr(colorToString(t.MarkdownListItem())),
126 },
128 },
127 Enumeration: ansi.StylePrimitive{
129 Enumeration: ansi.StylePrimitive{
128 BlockPrefix: ". ",
130 BlockPrefix: ". ",
129− Color: stringPtr(adaptiveColorToString(t.MarkdownListEnumeration())),
131+ Color: stringPtr(colorToString(t.MarkdownListEnumeration())),
130 },
132 },
131 Task: ansi.StyleTask{
133 Task: ansi.StyleTask{
132 StylePrimitive: ansi.StylePrimitive{},
134 StylePrimitive: ansi.StylePrimitive{},
@@ -134,25 +136,25 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
134 Unticked: "[ ] ",
136 Unticked: "[ ] ",
135 },
137 },
136 Link: ansi.StylePrimitive{
138 Link: ansi.StylePrimitive{
137− Color: stringPtr(adaptiveColorToString(t.MarkdownLink())),
139+ Color: stringPtr(colorToString(t.MarkdownLink())),
138 Underline: boolPtr(true),
140 Underline: boolPtr(true),
139 },
141 },
140 LinkText: ansi.StylePrimitive{
142 LinkText: ansi.StylePrimitive{
141− Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
143+ Color: stringPtr(colorToString(t.MarkdownLinkText())),
142 Bold: boolPtr(true),
144 Bold: boolPtr(true),
143 },
145 },
144 Image: ansi.StylePrimitive{
146 Image: ansi.StylePrimitive{
145− Color: stringPtr(adaptiveColorToString(t.MarkdownImage())),
147+ Color: stringPtr(colorToString(t.MarkdownImage())),
146 Underline: boolPtr(true),
148 Underline: boolPtr(true),
147 Format: "🖼 {{.text}}",
149 Format: "🖼 {{.text}}",
148 },
150 },
149 ImageText: ansi.StylePrimitive{
151 ImageText: ansi.StylePrimitive{
150− Color: stringPtr(adaptiveColorToString(t.MarkdownImageText())),
152+ Color: stringPtr(colorToString(t.MarkdownImageText())),
151 Format: "{{.text}}",
153 Format: "{{.text}}",
152 },
154 },
153 Code: ansi.StyleBlock{
155 Code: ansi.StyleBlock{
154 StylePrimitive: ansi.StylePrimitive{
156 StylePrimitive: ansi.StylePrimitive{
155− Color: stringPtr(adaptiveColorToString(t.MarkdownCode())),
157+ Color: stringPtr(colorToString(t.MarkdownCode())),
156 Prefix: "",
158 Prefix: "",
157 Suffix: "",
159 Suffix: "",
158 },
160 },
@@ -161,90 +163,90 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
161 StyleBlock: ansi.StyleBlock{
163 StyleBlock: ansi.StyleBlock{
162 StylePrimitive: ansi.StylePrimitive{
164 StylePrimitive: ansi.StylePrimitive{
163 Prefix: " ",
165 Prefix: " ",
164− Color: stringPtr(adaptiveColorToString(t.MarkdownCodeBlock())),
166+ Color: stringPtr(colorToString(t.MarkdownCodeBlock())),
165 },
167 },
166 Margin: uintPtr(defaultMargin),
168 Margin: uintPtr(defaultMargin),
167 },
169 },
168 Chroma: &ansi.Chroma{
170 Chroma: &ansi.Chroma{
169 Text: ansi.StylePrimitive{
171 Text: ansi.StylePrimitive{
170− Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
172+ Color: stringPtr(colorToString(t.MarkdownText())),
171 },
173 },
172 Error: ansi.StylePrimitive{
174 Error: ansi.StylePrimitive{
173− Color: stringPtr(adaptiveColorToString(t.Error())),
175+ Color: stringPtr(colorToString(t.Error())),
174 },
176 },
175 Comment: ansi.StylePrimitive{
177 Comment: ansi.StylePrimitive{
176− Color: stringPtr(adaptiveColorToString(t.SyntaxComment())),
178+ Color: stringPtr(colorToString(t.SyntaxComment())),
177 },
179 },
178 CommentPreproc: ansi.StylePrimitive{
180 CommentPreproc: ansi.StylePrimitive{
179− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
181+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
180 },
182 },
181 Keyword: ansi.StylePrimitive{
183 Keyword: ansi.StylePrimitive{
182− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
184+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
183 },
185 },
184 KeywordReserved: ansi.StylePrimitive{
186 KeywordReserved: ansi.StylePrimitive{
185− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
187+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
186 },
188 },
187 KeywordNamespace: ansi.StylePrimitive{
189 KeywordNamespace: ansi.StylePrimitive{
188− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
190+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
189 },
191 },
190 KeywordType: ansi.StylePrimitive{
192 KeywordType: ansi.StylePrimitive{
191− Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
193+ Color: stringPtr(colorToString(t.SyntaxType())),
192 },
194 },
193 Operator: ansi.StylePrimitive{
195 Operator: ansi.StylePrimitive{
194− Color: stringPtr(adaptiveColorToString(t.SyntaxOperator())),
196+ Color: stringPtr(colorToString(t.SyntaxOperator())),
195 },
197 },
196 Punctuation: ansi.StylePrimitive{
198 Punctuation: ansi.StylePrimitive{
197− Color: stringPtr(adaptiveColorToString(t.SyntaxPunctuation())),
199+ Color: stringPtr(colorToString(t.SyntaxPunctuation())),
198 },
200 },
199 Name: ansi.StylePrimitive{
201 Name: ansi.StylePrimitive{
200− Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
202+ Color: stringPtr(colorToString(t.SyntaxVariable())),
201 },
203 },
202 NameBuiltin: ansi.StylePrimitive{
204 NameBuiltin: ansi.StylePrimitive{
203− Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
205+ Color: stringPtr(colorToString(t.SyntaxVariable())),
204 },
206 },
205 NameTag: ansi.StylePrimitive{
207 NameTag: ansi.StylePrimitive{
206− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
208+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
207 },
209 },
208 NameAttribute: ansi.StylePrimitive{
210 NameAttribute: ansi.StylePrimitive{
209− Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
211+ Color: stringPtr(colorToString(t.SyntaxFunction())),
210 },
212 },
211 NameClass: ansi.StylePrimitive{
213 NameClass: ansi.StylePrimitive{
212− Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
214+ Color: stringPtr(colorToString(t.SyntaxType())),
213 },
215 },
214 NameConstant: ansi.StylePrimitive{
216 NameConstant: ansi.StylePrimitive{
215− Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
217+ Color: stringPtr(colorToString(t.SyntaxVariable())),
216 },
218 },
217 NameDecorator: ansi.StylePrimitive{
219 NameDecorator: ansi.StylePrimitive{
218− Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
220+ Color: stringPtr(colorToString(t.SyntaxFunction())),
219 },
221 },
220 NameFunction: ansi.StylePrimitive{
222 NameFunction: ansi.StylePrimitive{
221− Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
223+ Color: stringPtr(colorToString(t.SyntaxFunction())),
222 },
224 },
223 LiteralNumber: ansi.StylePrimitive{
225 LiteralNumber: ansi.StylePrimitive{
224− Color: stringPtr(adaptiveColorToString(t.SyntaxNumber())),
226+ Color: stringPtr(colorToString(t.SyntaxNumber())),
225 },
227 },
226 LiteralString: ansi.StylePrimitive{
228 LiteralString: ansi.StylePrimitive{
227− Color: stringPtr(adaptiveColorToString(t.SyntaxString())),
229+ Color: stringPtr(colorToString(t.SyntaxString())),
228 },
230 },
229 LiteralStringEscape: ansi.StylePrimitive{
231 LiteralStringEscape: ansi.StylePrimitive{
230− Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
232+ Color: stringPtr(colorToString(t.SyntaxKeyword())),
231 },
233 },
232 GenericDeleted: ansi.StylePrimitive{
234 GenericDeleted: ansi.StylePrimitive{
233− Color: stringPtr(adaptiveColorToString(t.DiffRemoved())),
235+ Color: stringPtr(colorToString(t.DiffRemoved())),
234 },
236 },
235 GenericEmph: ansi.StylePrimitive{
237 GenericEmph: ansi.StylePrimitive{
236− Color: stringPtr(adaptiveColorToString(t.MarkdownEmph())),
238+ Color: stringPtr(colorToString(t.MarkdownEmph())),
237 Italic: boolPtr(true),
239 Italic: boolPtr(true),
238 },
240 },
239 GenericInserted: ansi.StylePrimitive{
241 GenericInserted: ansi.StylePrimitive{
240− Color: stringPtr(adaptiveColorToString(t.DiffAdded())),
242+ Color: stringPtr(colorToString(t.DiffAdded())),
241 },
243 },
242 GenericStrong: ansi.StylePrimitive{
244 GenericStrong: ansi.StylePrimitive{
243− Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
245+ Color: stringPtr(colorToString(t.MarkdownStrong())),
244 Bold: boolPtr(true),
246 Bold: boolPtr(true),
245 },
247 },
246 GenericSubheading: ansi.StylePrimitive{
248 GenericSubheading: ansi.StylePrimitive{
247− Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
249+ Color: stringPtr(colorToString(t.MarkdownHeading())),
248 },
250 },
249 },
251 },
250 },
252 },
@@ -261,24 +263,20 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
261 },
263 },
262 DefinitionDescription: ansi.StylePrimitive{
264 DefinitionDescription: ansi.StylePrimitive{
263 BlockPrefix: "\n ❯ ",
265 BlockPrefix: "\n ❯ ",
264− Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
266+ Color: stringPtr(colorToString(t.MarkdownLinkText())),
265 },
267 },
266 Text: ansi.StylePrimitive{
268 Text: ansi.StylePrimitive{
267− Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
269+ Color: stringPtr(colorToString(t.MarkdownText())),
268 },
270 },
269 Paragraph: ansi.StyleBlock{
271 Paragraph: ansi.StyleBlock{
270 StylePrimitive: ansi.StylePrimitive{
272 StylePrimitive: ansi.StylePrimitive{
271− Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
273+ Color: stringPtr(colorToString(t.MarkdownText())),
272 },
274 },
273 },
275 },
274 }
276 }
275}
277}
276
278
277−// adaptiveColorToString converts a lipgloss.AdaptiveColor to the appropriate
279+func colorToString(c color.Color) string {
278−// hex color string based on the current terminal background
280+ rgba := color.RGBAModel.Convert(c).(color.RGBA)
279−func adaptiveColorToString(color lipgloss.AdaptiveColor) string {
281+ return fmt.Sprintf("#%02x%02x%02x", rgba.R, rgba.G, rgba.B)
280− if lipgloss.HasDarkBackground() {
281− return color.Dark
282− }
283− return color.Light
284}
282}
internal/tui/styles/styles.go+20−20
@@ -1,13 +1,13 @@
1package styles
1package styles
2
2
3import (
3import (
4+ "image/color"
5+
4− "github.com/charmbracelet/lipgloss"
6+ "github.com/charmbracelet/lipgloss/v2"
5 "github.com/opencode-ai/opencode/internal/tui/theme"
7 "github.com/opencode-ai/opencode/internal/tui/theme"
6)
8)
7
9
8−var (
9− ImageBakcground = "#212121"
10+var ImageBakcground = "#212121"
10−)
11
11
12// Style generation functions that use the current theme
12// Style generation functions that use the current theme
13
13
@@ -75,81 +75,81 @@ func DimBorder() lipgloss.Style {
75}
75}
76
76
77// PrimaryColor returns the primary color from the current theme
77// PrimaryColor returns the primary color from the current theme
78−func PrimaryColor() lipgloss.AdaptiveColor {
78+func PrimaryColor() color.Color {
79 return theme.CurrentTheme().Primary()
79 return theme.CurrentTheme().Primary()
80}
80}
81
81
82// SecondaryColor returns the secondary color from the current theme
82// SecondaryColor returns the secondary color from the current theme
83−func SecondaryColor() lipgloss.AdaptiveColor {
83+func SecondaryColor() color.Color {
84 return theme.CurrentTheme().Secondary()
84 return theme.CurrentTheme().Secondary()
85}
85}
86
86
87// AccentColor returns the accent color from the current theme
87// AccentColor returns the accent color from the current theme
88−func AccentColor() lipgloss.AdaptiveColor {
88+func AccentColor() color.Color {
89 return theme.CurrentTheme().Accent()
89 return theme.CurrentTheme().Accent()
90}
90}
91
91
92// ErrorColor returns the error color from the current theme
92// ErrorColor returns the error color from the current theme
93−func ErrorColor() lipgloss.AdaptiveColor {
93+func ErrorColor() color.Color {
94 return theme.CurrentTheme().Error()
94 return theme.CurrentTheme().Error()
95}
95}
96
96
97// WarningColor returns the warning color from the current theme
97// WarningColor returns the warning color from the current theme
98−func WarningColor() lipgloss.AdaptiveColor {
98+func WarningColor() color.Color {
99 return theme.CurrentTheme().Warning()
99 return theme.CurrentTheme().Warning()
100}
100}
101
101
102// SuccessColor returns the success color from the current theme
102// SuccessColor returns the success color from the current theme
103−func SuccessColor() lipgloss.AdaptiveColor {
103+func SuccessColor() color.Color {
104 return theme.CurrentTheme().Success()
104 return theme.CurrentTheme().Success()
105}
105}
106
106
107// InfoColor returns the info color from the current theme
107// InfoColor returns the info color from the current theme
108−func InfoColor() lipgloss.AdaptiveColor {
108+func InfoColor() color.Color {
109 return theme.CurrentTheme().Info()
109 return theme.CurrentTheme().Info()
110}
110}
111
111
112// TextColor returns the text color from the current theme
112// TextColor returns the text color from the current theme
113−func TextColor() lipgloss.AdaptiveColor {
113+func TextColor() color.Color {
114 return theme.CurrentTheme().Text()
114 return theme.CurrentTheme().Text()
115}
115}
116
116
117// TextMutedColor returns the muted text color from the current theme
117// TextMutedColor returns the muted text color from the current theme
118−func TextMutedColor() lipgloss.AdaptiveColor {
118+func TextMutedColor() color.Color {
119 return theme.CurrentTheme().TextMuted()
119 return theme.CurrentTheme().TextMuted()
120}
120}
121
121
122// TextEmphasizedColor returns the emphasized text color from the current theme
122// TextEmphasizedColor returns the emphasized text color from the current theme
123−func TextEmphasizedColor() lipgloss.AdaptiveColor {
123+func TextEmphasizedColor() color.Color {
124 return theme.CurrentTheme().TextEmphasized()
124 return theme.CurrentTheme().TextEmphasized()
125}
125}
126
126
127// BackgroundColor returns the background color from the current theme
127// BackgroundColor returns the background color from the current theme
128−func BackgroundColor() lipgloss.AdaptiveColor {
128+func BackgroundColor() color.Color {
129 return theme.CurrentTheme().Background()
129 return theme.CurrentTheme().Background()
130}
130}
131
131
132// BackgroundSecondaryColor returns the secondary background color from the current theme
132// BackgroundSecondaryColor returns the secondary background color from the current theme
133−func BackgroundSecondaryColor() lipgloss.AdaptiveColor {
133+func BackgroundSecondaryColor() color.Color {
134 return theme.CurrentTheme().BackgroundSecondary()
134 return theme.CurrentTheme().BackgroundSecondary()
135}
135}
136
136
137// BackgroundDarkerColor returns the darker background color from the current theme
137// BackgroundDarkerColor returns the darker background color from the current theme
138−func BackgroundDarkerColor() lipgloss.AdaptiveColor {
138+func BackgroundDarkerColor() color.Color {
139 return theme.CurrentTheme().BackgroundDarker()
139 return theme.CurrentTheme().BackgroundDarker()
140}
140}
141
141
142// BorderNormalColor returns the normal border color from the current theme
142// BorderNormalColor returns the normal border color from the current theme
143−func BorderNormalColor() lipgloss.AdaptiveColor {
143+func BorderNormalColor() color.Color {
144 return theme.CurrentTheme().BorderNormal()
144 return theme.CurrentTheme().BorderNormal()
145}
145}
146
146
147// BorderFocusedColor returns the focused border color from the current theme
147// BorderFocusedColor returns the focused border color from the current theme
148−func BorderFocusedColor() lipgloss.AdaptiveColor {
148+func BorderFocusedColor() color.Color {
149 return theme.CurrentTheme().BorderFocused()
149 return theme.CurrentTheme().BorderFocused()
150}
150}
151
151
152// BorderDimColor returns the dim border color from the current theme
152// BorderDimColor returns the dim border color from the current theme
153−func BorderDimColor() lipgloss.AdaptiveColor {
153+func BorderDimColor() color.Color {
154 return theme.CurrentTheme().BorderDim()
154 return theme.CurrentTheme().BorderDim()
155}
155}
internal/tui/theme/catppuccin.go+135−211
@@ -2,7 +2,7 @@ package theme
2
2
3import (
3import (
4 catppuccin "github.com/catppuccin/go"
4 catppuccin "github.com/catppuccin/go"
5− "github.com/charmbracelet/lipgloss"
5+ "github.com/charmbracelet/lipgloss/v2"
6)
6)
7
7
8// CatppuccinTheme implements the Theme interface with Catppuccin colors.
8// CatppuccinTheme implements the Theme interface with Catppuccin colors.
@@ -11,238 +11,162 @@ type CatppuccinTheme struct {
11 BaseTheme
11 BaseTheme
12}
12}
13
13
14−// NewCatppuccinTheme creates a new instance of the Catppuccin theme.
14+// NewCatppuccinMochaTheme creates a new instance of the Catppuccin Mocha theme.
15−func NewCatppuccinTheme() *CatppuccinTheme {
15+func NewCatppuccinMochaTheme() *CatppuccinTheme {
16− // Get the Catppuccin palettes
16+ // Get the Catppuccin palette
17 mocha := catppuccin.Mocha
17 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
18 latte := catppuccin.Latte
94 latte := catppuccin.Latte
19
95
20 theme := &CatppuccinTheme{}
96 theme := &CatppuccinTheme{}
21
97
22 // Base colors
98 // Base colors
23− theme.PrimaryColor = lipgloss.AdaptiveColor{
99+ theme.PrimaryColor = lipgloss.Color(latte.Blue().Hex)
24− Dark: mocha.Blue().Hex,
25− Light: latte.Blue().Hex,
26− }
27− theme.SecondaryColor = lipgloss.AdaptiveColor{
100+ theme.SecondaryColor = lipgloss.Color(latte.Mauve().Hex)
28− Dark: mocha.Mauve().Hex,
29− Light: latte.Mauve().Hex,
30− }
31− theme.AccentColor = lipgloss.AdaptiveColor{
101+ theme.AccentColor = lipgloss.Color(latte.Peach().Hex)
32− Dark: mocha.Peach().Hex,
33− Light: latte.Peach().Hex,
34− }
35
102
36 // Status colors
103 // Status colors
37− theme.ErrorColor = lipgloss.AdaptiveColor{
104+ theme.ErrorColor = lipgloss.Color(latte.Red().Hex)
38− Dark: mocha.Red().Hex,
39− Light: latte.Red().Hex,
40− }
41− theme.WarningColor = lipgloss.AdaptiveColor{
105+ theme.WarningColor = lipgloss.Color(latte.Peach().Hex)
42− Dark: mocha.Peach().Hex,
43− Light: latte.Peach().Hex,
44− }
45− theme.SuccessColor = lipgloss.AdaptiveColor{
106+ theme.SuccessColor = lipgloss.Color(latte.Green().Hex)
46− Dark: mocha.Green().Hex,
47− Light: latte.Green().Hex,
48− }
49− theme.InfoColor = lipgloss.AdaptiveColor{
107+ theme.InfoColor = lipgloss.Color(latte.Blue().Hex)
50− Dark: mocha.Blue().Hex,
51− Light: latte.Blue().Hex,
52− }
53
108
54 // Text colors
109 // Text colors
55− theme.TextColor = lipgloss.AdaptiveColor{
110+ theme.TextColor = lipgloss.Color(latte.Text().Hex)
56− Dark: mocha.Text().Hex,
57− Light: latte.Text().Hex,
58− }
59− theme.TextMutedColor = lipgloss.AdaptiveColor{
111+ theme.TextMutedColor = lipgloss.Color(latte.Subtext0().Hex)
60− Dark: mocha.Subtext0().Hex,
61− Light: latte.Subtext0().Hex,
62− }
63− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
112+ theme.TextEmphasizedColor = lipgloss.Color(latte.Lavender().Hex)
64− Dark: mocha.Lavender().Hex,
65− Light: latte.Lavender().Hex,
66− }
67
113
68 // Background colors
114 // Background colors
69− theme.BackgroundColor = lipgloss.AdaptiveColor{
115+ theme.BackgroundColor = lipgloss.Color("#EEEEEE") // Light equivalent
70− Dark: "#212121", // From existing styles
71− Light: "#EEEEEE", // Light equivalent
72− }
73− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
116+ theme.BackgroundSecondaryColor = lipgloss.Color("#E0E0E0") // Light equivalent
74− Dark: "#2c2c2c", // From existing styles
75− Light: "#E0E0E0", // Light equivalent
76− }
77− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
117+ theme.BackgroundDarkerColor = lipgloss.Color("#F5F5F5") // Light equivalent
78− Dark: "#181818", // From existing styles
79− Light: "#F5F5F5", // Light equivalent
80− }
81
118
82 // Border colors
119 // Border colors
83− theme.BorderNormalColor = lipgloss.AdaptiveColor{
120+ theme.BorderNormalColor = lipgloss.Color("#BDBDBD") // Light equivalent
84− Dark: "#4b4c5c", // From existing styles
85− Light: "#BDBDBD", // Light equivalent
86− }
87− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
121+ theme.BorderFocusedColor = lipgloss.Color(latte.Blue().Hex)
88− Dark: mocha.Blue().Hex,
89− Light: latte.Blue().Hex,
90− }
91− theme.BorderDimColor = lipgloss.AdaptiveColor{
122+ theme.BorderDimColor = lipgloss.Color(latte.Surface0().Hex)
92− Dark: mocha.Surface0().Hex,
93− Light: latte.Surface0().Hex,
94− }
95
123
96 // Diff view colors
124 // Diff view colors
97− theme.DiffAddedColor = lipgloss.AdaptiveColor{
125+ theme.DiffAddedColor = lipgloss.Color("#2E7D32") // Light equivalent
98− Dark: "#478247", // From existing diff.go
99− Light: "#2E7D32", // Light equivalent
100− }
101− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
126+ theme.DiffRemovedColor = lipgloss.Color("#C62828") // Light equivalent
102− Dark: "#7C4444", // From existing diff.go
103− Light: "#C62828", // Light equivalent
104− }
105− theme.DiffContextColor = lipgloss.AdaptiveColor{
127+ theme.DiffContextColor = lipgloss.Color("#757575") // Light equivalent
106− Dark: "#a0a0a0", // From existing diff.go
107− Light: "#757575", // Light equivalent
108− }
109− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
128+ theme.DiffHunkHeaderColor = lipgloss.Color("#757575") // Light equivalent
110− Dark: "#a0a0a0", // From existing diff.go
111− Light: "#757575", // Light equivalent
112− }
113− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
129+ theme.DiffHighlightAddedColor = lipgloss.Color("#A5D6A7") // Light equivalent
114− Dark: "#DAFADA", // From existing diff.go
115− Light: "#A5D6A7", // Light equivalent
116− }
117− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
130+ theme.DiffHighlightRemovedColor = lipgloss.Color("#EF9A9A") // Light equivalent
118− Dark: "#FADADD", // From existing diff.go
119− Light: "#EF9A9A", // Light equivalent
120− }
121− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
131+ theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9") // Light equivalent
122− Dark: "#303A30", // From existing diff.go
123− Light: "#E8F5E9", // Light equivalent
124− }
125− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
132+ theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE") // Light equivalent
126− Dark: "#3A3030", // From existing diff.go
127− Light: "#FFEBEE", // Light equivalent
128− }
129− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
133+ theme.DiffContextBgColor = lipgloss.Color("#F5F5F5") // Light equivalent
130− Dark: "#212121", // From existing diff.go
131− Light: "#F5F5F5", // Light equivalent
132− }
133− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
134+ theme.DiffLineNumberColor = lipgloss.Color("#9E9E9E") // Light equivalent
134− Dark: "#888888", // From existing diff.go
135− Light: "#9E9E9E", // Light equivalent
136− }
137− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
135+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9") // Light equivalent
138− Dark: "#293229", // From existing diff.go
139− Light: "#C8E6C9", // Light equivalent
140− }
141− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
136+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2") // Light equivalent
142− Dark: "#332929", // From existing diff.go
143− Light: "#FFCDD2", // Light equivalent
144− }
145
137
146 // Markdown colors
138 // Markdown colors
147− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
139+ theme.MarkdownTextColor = lipgloss.Color(latte.Text().Hex)
148− Dark: mocha.Text().Hex,
149− Light: latte.Text().Hex,
150− }
151− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
140+ theme.MarkdownHeadingColor = lipgloss.Color(latte.Mauve().Hex)
152− Dark: mocha.Mauve().Hex,
153− Light: latte.Mauve().Hex,
154− }
155− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
141+ theme.MarkdownLinkColor = lipgloss.Color(latte.Sky().Hex)
156− Dark: mocha.Sky().Hex,
157− Light: latte.Sky().Hex,
158− }
159− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
142+ theme.MarkdownLinkTextColor = lipgloss.Color(latte.Pink().Hex)
160− Dark: mocha.Pink().Hex,
161− Light: latte.Pink().Hex,
162− }
163− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
143+ theme.MarkdownCodeColor = lipgloss.Color(latte.Green().Hex)
164− Dark: mocha.Green().Hex,
165− Light: latte.Green().Hex,
166− }
167− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
144+ theme.MarkdownBlockQuoteColor = lipgloss.Color(latte.Yellow().Hex)
168− Dark: mocha.Yellow().Hex,
169− Light: latte.Yellow().Hex,
170− }
171− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
145+ theme.MarkdownEmphColor = lipgloss.Color(latte.Yellow().Hex)
172− Dark: mocha.Yellow().Hex,
173− Light: latte.Yellow().Hex,
174− }
175− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
146+ theme.MarkdownStrongColor = lipgloss.Color(latte.Peach().Hex)
176− Dark: mocha.Peach().Hex,
177− Light: latte.Peach().Hex,
178− }
179− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
147+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(latte.Overlay0().Hex)
180− Dark: mocha.Overlay0().Hex,
181− Light: latte.Overlay0().Hex,
182− }
183− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
148+ theme.MarkdownListItemColor = lipgloss.Color(latte.Blue().Hex)
184− Dark: mocha.Blue().Hex,
185− Light: latte.Blue().Hex,
186− }
187− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
149+ theme.MarkdownListEnumerationColor = lipgloss.Color(latte.Sky().Hex)
188− Dark: mocha.Sky().Hex,
189− Light: latte.Sky().Hex,
190− }
191− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
150+ theme.MarkdownImageColor = lipgloss.Color(latte.Sapphire().Hex)
192− Dark: mocha.Sapphire().Hex,
193− Light: latte.Sapphire().Hex,
194− }
195− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
151+ theme.MarkdownImageTextColor = lipgloss.Color(latte.Pink().Hex)
196− Dark: mocha.Pink().Hex,
197− Light: latte.Pink().Hex,
198− }
199− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
152+ theme.MarkdownCodeBlockColor = lipgloss.Color(latte.Text().Hex)
200− Dark: mocha.Text().Hex,
201− Light: latte.Text().Hex,
202− }
203
153
204 // Syntax highlighting colors
154 // Syntax highlighting colors
205− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
155+ theme.SyntaxCommentColor = lipgloss.Color(latte.Overlay1().Hex)
206− Dark: mocha.Overlay1().Hex,
207− Light: latte.Overlay1().Hex,
208− }
209− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
156+ theme.SyntaxKeywordColor = lipgloss.Color(latte.Pink().Hex)
210− Dark: mocha.Pink().Hex,
211− Light: latte.Pink().Hex,
212− }
213− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
157+ theme.SyntaxFunctionColor = lipgloss.Color(latte.Green().Hex)
214− Dark: mocha.Green().Hex,
215− Light: latte.Green().Hex,
216− }
217− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
158+ theme.SyntaxVariableColor = lipgloss.Color(latte.Sky().Hex)
218− Dark: mocha.Sky().Hex,
219− Light: latte.Sky().Hex,
220− }
221− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
159+ theme.SyntaxStringColor = lipgloss.Color(latte.Yellow().Hex)
222− Dark: mocha.Yellow().Hex,
223− Light: latte.Yellow().Hex,
224− }
225− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
160+ theme.SyntaxNumberColor = lipgloss.Color(latte.Teal().Hex)
226− Dark: mocha.Teal().Hex,
227− Light: latte.Teal().Hex,
228− }
229− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
161+ theme.SyntaxTypeColor = lipgloss.Color(latte.Sky().Hex)
230− Dark: mocha.Sky().Hex,
231− Light: latte.Sky().Hex,
232− }
233− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
162+ theme.SyntaxOperatorColor = lipgloss.Color(latte.Pink().Hex)
234− Dark: mocha.Pink().Hex,
235− Light: latte.Pink().Hex,
236− }
237− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
163+ theme.SyntaxPunctuationColor = lipgloss.Color(latte.Text().Hex)
238− Dark: mocha.Text().Hex,
239− Light: latte.Text().Hex,
240− }
241
164
242 return theme
165 return theme
243}
166}
244
167
245func init() {
168func init() {
246− // Register the Catppuccin theme with the theme manager
169+ // Register the Catppuccin themes with the theme manager
247− RegisterTheme("catppuccin", NewCatppuccinTheme())
170+ RegisterTheme("catppuccin-mocha", NewCatppuccinMochaTheme())
171+ RegisterTheme("catppuccin-latte", NewCatppuccinLatteTheme())
248−}
172+}
internal/tui/theme/dracula.go+52−220
@@ -1,7 +1,7 @@
1package theme
1package theme
2
2
3import (
3import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
5)
5)
6
6
7// DraculaTheme implements the Theme interface with Dracula colors.
7// DraculaTheme implements the Theme interface with Dracula colors.
@@ -28,242 +28,74 @@ func NewDraculaTheme() *DraculaTheme {
28 darkYellow := "#f1fa8c"
28 darkYellow := "#f1fa8c"
29 darkBorder := "#44475a"
29 darkBorder := "#44475a"
30
30
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−
46 theme := &DraculaTheme{}
31 theme := &DraculaTheme{}
47
32
48 // Base colors
33 // Base colors
49− theme.PrimaryColor = lipgloss.AdaptiveColor{
34+ theme.PrimaryColor = lipgloss.Color(darkPurple)
50− Dark: darkPurple,
51− Light: lightPurple,
52− }
53− theme.SecondaryColor = lipgloss.AdaptiveColor{
35+ theme.SecondaryColor = lipgloss.Color(darkPink)
54− Dark: darkPink,
55− Light: lightPink,
56− }
57− theme.AccentColor = lipgloss.AdaptiveColor{
36+ theme.AccentColor = lipgloss.Color(darkCyan)
58− Dark: darkCyan,
59− Light: lightCyan,
60− }
61
37
62 // Status colors
38 // Status colors
63− theme.ErrorColor = lipgloss.AdaptiveColor{
39+ theme.ErrorColor = lipgloss.Color(darkRed)
64− Dark: darkRed,
65− Light: lightRed,
66− }
67− theme.WarningColor = lipgloss.AdaptiveColor{
40+ theme.WarningColor = lipgloss.Color(darkOrange)
68− Dark: darkOrange,
69− Light: lightOrange,
70− }
71− theme.SuccessColor = lipgloss.AdaptiveColor{
41+ theme.SuccessColor = lipgloss.Color(darkGreen)
72− Dark: darkGreen,
73− Light: lightGreen,
74− }
75− theme.InfoColor = lipgloss.AdaptiveColor{
42+ theme.InfoColor = lipgloss.Color(darkCyan)
76− Dark: darkCyan,
77− Light: lightCyan,
78− }
79
43
80 // Text colors
44 // Text colors
81− theme.TextColor = lipgloss.AdaptiveColor{
45+ theme.TextColor = lipgloss.Color(darkForeground)
82− Dark: darkForeground,
83− Light: lightForeground,
84− }
85− theme.TextMutedColor = lipgloss.AdaptiveColor{
46+ theme.TextMutedColor = lipgloss.Color(darkComment)
86− Dark: darkComment,
87− Light: lightComment,
88− }
89− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
47+ theme.TextEmphasizedColor = lipgloss.Color(darkYellow)
90− Dark: darkYellow,
91− Light: lightYellow,
92− }
93
48
94 // Background colors
49 // Background colors
95− theme.BackgroundColor = lipgloss.AdaptiveColor{
50+ theme.BackgroundColor = lipgloss.Color(darkBackground)
96− Dark: darkBackground,
97− Light: lightBackground,
98− }
99− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
51+ theme.BackgroundSecondaryColor = lipgloss.Color(darkCurrentLine)
100− Dark: darkCurrentLine,
101− Light: lightCurrentLine,
102− }
103− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
104− Dark: "#21222c", // Slightly darker than background
52+ theme.BackgroundDarkerColor = lipgloss.Color("#21222c") // Slightly darker than background
105− Light: "#ffffff", // Slightly lighter than background
106− }
107
53
108 // Border colors
54 // Border colors
109− theme.BorderNormalColor = lipgloss.AdaptiveColor{
55+ theme.BorderNormalColor = lipgloss.Color(darkBorder)
110− Dark: darkBorder,
111− Light: lightBorder,
112− }
113− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
56+ theme.BorderFocusedColor = lipgloss.Color(darkPurple)
114− Dark: darkPurple,
115− Light: lightPurple,
116− }
117− theme.BorderDimColor = lipgloss.AdaptiveColor{
57+ theme.BorderDimColor = lipgloss.Color(darkSelection)
118− Dark: darkSelection,
119− Light: lightSelection,
120− }
121
58
122 // Diff view colors
59 // Diff view colors
123− theme.DiffAddedColor = lipgloss.AdaptiveColor{
60+ theme.DiffAddedColor = lipgloss.Color(darkGreen)
124− Dark: darkGreen,
125− Light: lightGreen,
126− }
127− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
61+ theme.DiffRemovedColor = lipgloss.Color(darkRed)
128− Dark: darkRed,
129− Light: lightRed,
130− }
131− theme.DiffContextColor = lipgloss.AdaptiveColor{
62+ theme.DiffContextColor = lipgloss.Color(darkComment)
132− Dark: darkComment,
133− Light: lightComment,
134− }
135− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
63+ theme.DiffHunkHeaderColor = lipgloss.Color(darkPurple)
136− Dark: darkPurple,
137− Light: lightPurple,
138− }
139− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
64+ theme.DiffHighlightAddedColor = lipgloss.Color("#50fa7b")
140− Dark: "#50fa7b",
141− Light: "#a5d6a7",
142− }
143− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
65+ theme.DiffHighlightRemovedColor = lipgloss.Color("#ff5555")
144− Dark: "#ff5555",
145− Light: "#ef9a9a",
146− }
147− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
66+ theme.DiffAddedBgColor = lipgloss.Color("#2c3b2c")
148− Dark: "#2c3b2c",
149− Light: "#e8f5e9",
150− }
151− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
67+ theme.DiffRemovedBgColor = lipgloss.Color("#3b2c2c")
152− Dark: "#3b2c2c",
153− Light: "#ffebee",
154− }
155− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
68+ theme.DiffContextBgColor = lipgloss.Color(darkBackground)
156− Dark: darkBackground,
157− Light: lightBackground,
158− }
159− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
69+ theme.DiffLineNumberColor = lipgloss.Color(darkComment)
160− Dark: darkComment,
161− Light: lightComment,
162− }
163− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
70+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#253025")
164− Dark: "#253025",
165− Light: "#c8e6c9",
166− }
167− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
71+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#302525")
168− Dark: "#302525",
169− Light: "#ffcdd2",
170− }
171
72
172 // Markdown colors
73 // Markdown colors
173− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
74+ theme.MarkdownTextColor = lipgloss.Color(darkForeground)
174− Dark: darkForeground,
175− Light: lightForeground,
176− }
177− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
75+ theme.MarkdownHeadingColor = lipgloss.Color(darkPink)
178− Dark: darkPink,
179− Light: lightPink,
180− }
181− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
76+ theme.MarkdownLinkColor = lipgloss.Color(darkPurple)
182− Dark: darkPurple,
183− Light: lightPurple,
184− }
185− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
77+ theme.MarkdownLinkTextColor = lipgloss.Color(darkCyan)
186− Dark: darkCyan,
187− Light: lightCyan,
188− }
189− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
78+ theme.MarkdownCodeColor = lipgloss.Color(darkGreen)
190− Dark: darkGreen,
191− Light: lightGreen,
192− }
193− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
79+ theme.MarkdownBlockQuoteColor = lipgloss.Color(darkYellow)
194− Dark: darkYellow,
195− Light: lightYellow,
196− }
197− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
80+ theme.MarkdownEmphColor = lipgloss.Color(darkYellow)
198− Dark: darkYellow,
199− Light: lightYellow,
200− }
201− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
81+ theme.MarkdownStrongColor = lipgloss.Color(darkOrange)
202− Dark: darkOrange,
203− Light: lightOrange,
204− }
205− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
82+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(darkComment)
206− Dark: darkComment,
207− Light: lightComment,
208− }
209− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
83+ theme.MarkdownListItemColor = lipgloss.Color(darkPurple)
210− Dark: darkPurple,
211− Light: lightPurple,
212− }
213− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
84+ theme.MarkdownListEnumerationColor = lipgloss.Color(darkCyan)
214− Dark: darkCyan,
215− Light: lightCyan,
216− }
217− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
85+ theme.MarkdownImageColor = lipgloss.Color(darkPurple)
218− Dark: darkPurple,
219− Light: lightPurple,
220− }
221− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
86+ theme.MarkdownImageTextColor = lipgloss.Color(darkCyan)
222− Dark: darkCyan,
223− Light: lightCyan,
224− }
225− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
87+ theme.MarkdownCodeBlockColor = lipgloss.Color(darkForeground)
226− Dark: darkForeground,
227− Light: lightForeground,
228− }
229
88
230 // Syntax highlighting colors
89 // Syntax highlighting colors
231− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
90+ theme.SyntaxCommentColor = lipgloss.Color(darkComment)
232− Dark: darkComment,
233− Light: lightComment,
234− }
235− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
91+ theme.SyntaxKeywordColor = lipgloss.Color(darkPink)
236− Dark: darkPink,
237− Light: lightPink,
238− }
239− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
92+ theme.SyntaxFunctionColor = lipgloss.Color(darkGreen)
240− Dark: darkGreen,
241− Light: lightGreen,
242− }
243− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
93+ theme.SyntaxVariableColor = lipgloss.Color(darkOrange)
244− Dark: darkOrange,
245− Light: lightOrange,
246− }
247− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
94+ theme.SyntaxStringColor = lipgloss.Color(darkYellow)
248− Dark: darkYellow,
249− Light: lightYellow,
250− }
251− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
95+ theme.SyntaxNumberColor = lipgloss.Color(darkPurple)
252− Dark: darkPurple,
253− Light: lightPurple,
254− }
255− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
96+ theme.SyntaxTypeColor = lipgloss.Color(darkCyan)
256− Dark: darkCyan,
257− Light: lightCyan,
258− }
259− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
97+ theme.SyntaxOperatorColor = lipgloss.Color(darkPink)
260− Dark: darkPink,
261− Light: lightPink,
262− }
263− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
98+ theme.SyntaxPunctuationColor = lipgloss.Color(darkForeground)
264− Dark: darkForeground,
265− Light: lightForeground,
266− }
267
99
268 return theme
100 return theme
269}
101}
internal/tui/theme/flexoki.go+131−209
@@ -1,7 +1,7 @@
1package theme
1package theme
2
2
3import (
3import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
5)
5)
6
6
7// Flexoki color palette constants
7// Flexoki color palette constants
@@ -49,234 +49,156 @@ type FlexokiTheme struct {
49 BaseTheme
49 BaseTheme
50}
50}
51
51
52−// NewFlexokiTheme creates a new instance of the Flexoki theme.
52+// NewFlexokiDarkTheme creates a new instance of the Flexoki Dark theme.
53−func NewFlexokiTheme() *FlexokiTheme {
53+func NewFlexokiDarkTheme() *FlexokiTheme {
54 theme := &FlexokiTheme{}
54 theme := &FlexokiTheme{}
55
55
56 // Base colors
56 // Base colors
57− theme.PrimaryColor = lipgloss.AdaptiveColor{
57+ theme.PrimaryColor = lipgloss.Color(flexokiBlue400)
58− Dark: flexokiBlue400,
59− Light: flexokiBlue600,
60− }
61− theme.SecondaryColor = lipgloss.AdaptiveColor{
58+ theme.SecondaryColor = lipgloss.Color(flexokiPurple400)
62− Dark: flexokiPurple400,
63− Light: flexokiPurple600,
64− }
65− theme.AccentColor = lipgloss.AdaptiveColor{
59+ theme.AccentColor = lipgloss.Color(flexokiOrange400)
66− Dark: flexokiOrange400,
67− Light: flexokiOrange600,
68− }
69
60
70 // Status colors
61 // Status colors
71− theme.ErrorColor = lipgloss.AdaptiveColor{
62+ theme.ErrorColor = lipgloss.Color(flexokiRed400)
72− Dark: flexokiRed400,
73− Light: flexokiRed600,
74− }
75− theme.WarningColor = lipgloss.AdaptiveColor{
63+ theme.WarningColor = lipgloss.Color(flexokiYellow400)
76− Dark: flexokiYellow400,
77− Light: flexokiYellow600,
78− }
79− theme.SuccessColor = lipgloss.AdaptiveColor{
64+ theme.SuccessColor = lipgloss.Color(flexokiGreen400)
80− Dark: flexokiGreen400,
81− Light: flexokiGreen600,
82− }
83− theme.InfoColor = lipgloss.AdaptiveColor{
65+ theme.InfoColor = lipgloss.Color(flexokiCyan400)
84− Dark: flexokiCyan400,
85− Light: flexokiCyan600,
86− }
87
66
88 // Text colors
67 // Text colors
89− theme.TextColor = lipgloss.AdaptiveColor{
68+ theme.TextColor = lipgloss.Color(flexokiBase300)
90− Dark: flexokiBase300,
91− Light: flexokiBase600,
92− }
93− theme.TextMutedColor = lipgloss.AdaptiveColor{
69+ theme.TextMutedColor = lipgloss.Color(flexokiBase700)
94− Dark: flexokiBase700,
95− Light: flexokiBase500,
96− }
97− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
70+ theme.TextEmphasizedColor = lipgloss.Color(flexokiYellow400)
98− Dark: flexokiYellow400,
99− Light: flexokiYellow600,
100− }
101
71
102 // Background colors
72 // Background colors
103− theme.BackgroundColor = lipgloss.AdaptiveColor{
73+ theme.BackgroundColor = lipgloss.Color(flexokiBlack)
104− Dark: flexokiBlack,
105− Light: flexokiPaper,
106− }
107− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
74+ theme.BackgroundSecondaryColor = lipgloss.Color(flexokiBase950)
108− Dark: flexokiBase950,
109− Light: flexokiBase50,
110− }
111− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
75+ theme.BackgroundDarkerColor = lipgloss.Color(flexokiBase900)
112− Dark: flexokiBase900,
113− Light: flexokiBase100,
114− }
115
76
116 // Border colors
77 // Border colors
117− theme.BorderNormalColor = lipgloss.AdaptiveColor{
78+ theme.BorderNormalColor = lipgloss.Color(flexokiBase900)
118− Dark: flexokiBase900,
119− Light: flexokiBase100,
120− }
121− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
79+ theme.BorderFocusedColor = lipgloss.Color(flexokiBlue400)
122− Dark: flexokiBlue400,
123− Light: flexokiBlue600,
124− }
125− theme.BorderDimColor = lipgloss.AdaptiveColor{
80+ theme.BorderDimColor = lipgloss.Color(flexokiBase850)
126− Dark: flexokiBase850,
127− Light: flexokiBase150,
128− }
129
81
130 // Diff view colors
82 // Diff view colors
131− theme.DiffAddedColor = lipgloss.AdaptiveColor{
83+ theme.DiffAddedColor = lipgloss.Color(flexokiGreen400)
132− Dark: flexokiGreen400,
133− Light: flexokiGreen600,
134− }
135− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
84+ theme.DiffRemovedColor = lipgloss.Color(flexokiRed400)
136− Dark: flexokiRed400,
137− Light: flexokiRed600,
138− }
139− theme.DiffContextColor = lipgloss.AdaptiveColor{
85+ theme.DiffContextColor = lipgloss.Color(flexokiBase700)
140− Dark: flexokiBase700,
141− Light: flexokiBase500,
142− }
143− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
86+ theme.DiffHunkHeaderColor = lipgloss.Color(flexokiBase700)
144− Dark: flexokiBase700,
145− Light: flexokiBase500,
146− }
147− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
87+ theme.DiffHighlightAddedColor = lipgloss.Color(flexokiGreen400)
148− Dark: flexokiGreen400,
149− Light: flexokiGreen600,
150− }
151− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
88+ theme.DiffHighlightRemovedColor = lipgloss.Color(flexokiRed400)
152− Dark: flexokiRed400,
153− Light: flexokiRed600,
154− }
155− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
156− Dark: "#1D2419", // Darker green background
89+ theme.DiffAddedBgColor = lipgloss.Color("#1D2419") // Darker green background
157− Light: "#EFF2E2", // Light green background
158− }
159− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
90+ theme.DiffRemovedBgColor = lipgloss.Color("#241919") // Darker red background
160− Dark: "#241919", // Darker red background
161− Light: "#F2E2E2", // Light red background
162− }
163− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
91+ theme.DiffContextBgColor = lipgloss.Color(flexokiBlack)
164− Dark: flexokiBlack,
165− Light: flexokiPaper,
166− }
167− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
92+ theme.DiffLineNumberColor = lipgloss.Color(flexokiBase700)
168− Dark: flexokiBase700,
169− Light: flexokiBase500,
170− }
171− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
93+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#1A2017") // Slightly darker green
172− Dark: "#1A2017", // Slightly darker green
173− Light: "#E5EBD9", // Light green
174− }
175− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
94+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#201717") // Slightly darker red
176− Dark: "#201717", // Slightly darker red
177− Light: "#EBD9D9", // Light red
178− }
179
95
180 // Markdown colors
96 // Markdown colors
181− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
97+ theme.MarkdownTextColor = lipgloss.Color(flexokiBase300)
182− Dark: flexokiBase300,
183− Light: flexokiBase600,
184− }
185− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
98+ theme.MarkdownHeadingColor = lipgloss.Color(flexokiYellow400)
186− Dark: flexokiYellow400,
187− Light: flexokiYellow600,
188− }
189− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
99+ theme.MarkdownLinkColor = lipgloss.Color(flexokiCyan400)
190− Dark: flexokiCyan400,
191− Light: flexokiCyan600,
192− }
193− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
100+ theme.MarkdownLinkTextColor = lipgloss.Color(flexokiMagenta400)
194− Dark: flexokiMagenta400,
195− Light: flexokiMagenta600,
196− }
197− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
101+ theme.MarkdownCodeColor = lipgloss.Color(flexokiGreen400)
198− Dark: flexokiGreen400,
199− Light: flexokiGreen600,
200− }
201− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
102+ theme.MarkdownBlockQuoteColor = lipgloss.Color(flexokiCyan400)
202− Dark: flexokiCyan400,
203− Light: flexokiCyan600,
204− }
205− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
103+ theme.MarkdownEmphColor = lipgloss.Color(flexokiYellow400)
206− Dark: flexokiYellow400,
207− Light: flexokiYellow600,
208− }
209− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
104+ theme.MarkdownStrongColor = lipgloss.Color(flexokiOrange400)
210− Dark: flexokiOrange400,
211− Light: flexokiOrange600,
212− }
213− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
105+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(flexokiBase800)
214− Dark: flexokiBase800,
215− Light: flexokiBase200,
216− }
217− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
106+ theme.MarkdownListItemColor = lipgloss.Color(flexokiBlue400)
218− Dark: flexokiBlue400,
219− Light: flexokiBlue600,
220− }
221− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
107+ theme.MarkdownListEnumerationColor = lipgloss.Color(flexokiBlue400)
222− Dark: flexokiBlue400,
223− Light: flexokiBlue600,
224− }
225− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
108+ theme.MarkdownImageColor = lipgloss.Color(flexokiPurple400)
226− Dark: flexokiPurple400,
227− Light: flexokiPurple600,
228− }
229− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
109+ theme.MarkdownImageTextColor = lipgloss.Color(flexokiMagenta400)
230− Dark: flexokiMagenta400,
231− Light: flexokiMagenta600,
232− }
233− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
110+ theme.MarkdownCodeBlockColor = lipgloss.Color(flexokiBase300)
234− Dark: flexokiBase300,
235− Light: flexokiBase600,
236− }
237
111
238 // Syntax highlighting colors (based on Flexoki's mappings)
112 // Syntax highlighting colors (based on Flexoki's mappings)
239− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
113+ theme.SyntaxCommentColor = lipgloss.Color(flexokiBase700) // tx-3
240− Dark: flexokiBase700, // tx-3
241− Light: flexokiBase300, // tx-3
242− }
243− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
114+ theme.SyntaxKeywordColor = lipgloss.Color(flexokiGreen400) // gr
244− Dark: flexokiGreen400, // gr
245− Light: flexokiGreen600, // gr
246− }
247− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
115+ theme.SyntaxFunctionColor = lipgloss.Color(flexokiOrange400) // or
248− Dark: flexokiOrange400, // or
249− Light: flexokiOrange600, // or
250− }
251− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
116+ theme.SyntaxVariableColor = lipgloss.Color(flexokiBlue400) // bl
252− Dark: flexokiBlue400, // bl
253− Light: flexokiBlue600, // bl
254− }
255− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
117+ theme.SyntaxStringColor = lipgloss.Color(flexokiCyan400) // cy
256− Dark: flexokiCyan400, // cy
257− Light: flexokiCyan600, // cy
258− }
259− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
118+ theme.SyntaxNumberColor = lipgloss.Color(flexokiPurple400) // pu
260− Dark: flexokiPurple400, // pu
261− Light: flexokiPurple600, // pu
262− }
263− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
119+ theme.SyntaxTypeColor = lipgloss.Color(flexokiYellow400) // ye
264− Dark: flexokiYellow400, // ye
120+ theme.SyntaxOperatorColor = lipgloss.Color(flexokiBase500) // tx-2
265− Light: flexokiYellow600, // ye
121+ theme.SyntaxPunctuationColor = lipgloss.Color(flexokiBase500) // tx-2
266− }
122+
267− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
123+ return theme
268− Dark: flexokiBase500, // tx-2
124+}
269− Light: flexokiBase500, // tx-2
125+
270− }
126+// NewFlexokiLightTheme creates a new instance of the Flexoki Light theme.
271− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
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
272− Dark: flexokiBase500, // tx-2
194+ theme.SyntaxOperatorColor = lipgloss.Color(flexokiBase500) // tx-2
273− Light: flexokiBase500, // tx-2
195+ theme.SyntaxPunctuationColor = lipgloss.Color(flexokiBase500) // tx-2
274− }
275
196
276 return theme
197 return theme
277}
198}
278
199
279func init() {
200func init() {
280− // Register the Flexoki theme with the theme manager
201+ // Register the Flexoki themes with the theme manager
281− RegisterTheme("flexoki", NewFlexokiTheme())
202+ RegisterTheme("flexoki-dark", NewFlexokiDarkTheme())
203+ RegisterTheme("flexoki-light", NewFlexokiLightTheme())
282}
204}
internal/tui/theme/gruvbox.go+128−206
@@ -1,7 +1,7 @@
1package theme
1package theme
2
2
3import (
3import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
5)
5)
6
6
7// Gruvbox color palette constants
7// Gruvbox color palette constants
@@ -74,229 +74,151 @@ func NewGruvboxTheme() *GruvboxTheme {
74 theme := &GruvboxTheme{}
74 theme := &GruvboxTheme{}
75
75
76 // Base colors
76 // Base colors
77− theme.PrimaryColor = lipgloss.AdaptiveColor{
77+ theme.PrimaryColor = lipgloss.Color(gruvboxDarkBlueBright)
78− Dark: gruvboxDarkBlueBright,
79− Light: gruvboxLightBlueBright,
80− }
81− theme.SecondaryColor = lipgloss.AdaptiveColor{
78+ theme.SecondaryColor = lipgloss.Color(gruvboxDarkPurpleBright)
82− Dark: gruvboxDarkPurpleBright,
83− Light: gruvboxLightPurpleBright,
84− }
85− theme.AccentColor = lipgloss.AdaptiveColor{
86− Dark: gruvboxDarkOrangeBright,
79+ theme.AccentColor = lipgloss.Color(gruvboxDarkOrangeBright)
87− Light: gruvboxLightOrangeBright,
88− }
89
80
90 // Status colors
81 // Status colors
91− theme.ErrorColor = lipgloss.AdaptiveColor{
92− Dark: gruvboxDarkRedBright,
82+ theme.ErrorColor = lipgloss.Color(gruvboxDarkRedBright)
93− Light: gruvboxLightRedBright,
94− }
95− theme.WarningColor = lipgloss.AdaptiveColor{
96− Dark: gruvboxDarkYellowBright,
83+ theme.WarningColor = lipgloss.Color(gruvboxDarkYellowBright)
97− Light: gruvboxLightYellowBright,
98− }
99− theme.SuccessColor = lipgloss.AdaptiveColor{
100− Dark: gruvboxDarkGreenBright,
84+ theme.SuccessColor = lipgloss.Color(gruvboxDarkGreenBright)
101− Light: gruvboxLightGreenBright,
102− }
103− theme.InfoColor = lipgloss.AdaptiveColor{
104− Dark: gruvboxDarkBlueBright,
85+ theme.InfoColor = lipgloss.Color(gruvboxDarkBlueBright)
105− Light: gruvboxLightBlueBright,
106− }
107
86
108 // Text colors
87 // Text colors
109− theme.TextColor = lipgloss.AdaptiveColor{
88+ theme.TextColor = lipgloss.Color(gruvboxDarkFg1)
110− Dark: gruvboxDarkFg1,
111− Light: gruvboxLightFg1,
112− }
113− theme.TextMutedColor = lipgloss.AdaptiveColor{
89+ theme.TextMutedColor = lipgloss.Color(gruvboxDarkFg4)
114− Dark: gruvboxDarkFg4,
115− Light: gruvboxLightFg4,
116− }
117− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
90+ theme.TextEmphasizedColor = lipgloss.Color(gruvboxDarkYellowBright)
118− Dark: gruvboxDarkYellowBright,
119− Light: gruvboxLightYellowBright,
120− }
121
91
122 // Background colors
92 // Background colors
123− theme.BackgroundColor = lipgloss.AdaptiveColor{
93+ theme.BackgroundColor = lipgloss.Color(gruvboxDarkBg0)
124− Dark: gruvboxDarkBg0,
125− Light: gruvboxLightBg0,
126− }
127− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
94+ theme.BackgroundSecondaryColor = lipgloss.Color(gruvboxDarkBg1)
128− Dark: gruvboxDarkBg1,
129− Light: gruvboxLightBg1,
130− }
131− theme.BackgroundDarkerColor = lipgloss.AdaptiveColor{
95+ theme.BackgroundDarkerColor = lipgloss.Color(gruvboxDarkBg0Soft)
132− Dark: gruvboxDarkBg0Soft,
133− Light: gruvboxLightBg0Soft,
134− }
135
96
136 // Border colors
97 // Border colors
137− theme.BorderNormalColor = lipgloss.AdaptiveColor{
98+ theme.BorderNormalColor = lipgloss.Color(gruvboxDarkBg2)
138− Dark: gruvboxDarkBg2,
139− Light: gruvboxLightBg2,
140− }
141− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
99+ theme.BorderFocusedColor = lipgloss.Color(gruvboxDarkBlueBright)
142− Dark: gruvboxDarkBlueBright,
143− Light: gruvboxLightBlueBright,
144− }
145− theme.BorderDimColor = lipgloss.AdaptiveColor{
100+ theme.BorderDimColor = lipgloss.Color(gruvboxDarkBg1)
146− Dark: gruvboxDarkBg1,
147− Light: gruvboxLightBg1,
148− }
149
101
150 // Diff view colors
102 // Diff view colors
151− theme.DiffAddedColor = lipgloss.AdaptiveColor{
103+ theme.DiffAddedColor = lipgloss.Color(gruvboxDarkGreenBright)
152− Dark: gruvboxDarkGreenBright,
153− Light: gruvboxLightGreenBright,
154− }
155− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
104+ theme.DiffRemovedColor = lipgloss.Color(gruvboxDarkRedBright)
156− Dark: gruvboxDarkRedBright,
157− Light: gruvboxLightRedBright,
158− }
159− theme.DiffContextColor = lipgloss.AdaptiveColor{
105+ theme.DiffContextColor = lipgloss.Color(gruvboxDarkFg4)
160− Dark: gruvboxDarkFg4,
161− Light: gruvboxLightFg4,
162− }
163− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
106+ theme.DiffHunkHeaderColor = lipgloss.Color(gruvboxDarkFg3)
164− Dark: gruvboxDarkFg3,
165− Light: gruvboxLightFg3,
166− }
167− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
107+ theme.DiffHighlightAddedColor = lipgloss.Color(gruvboxDarkGreenBright)
168− Dark: gruvboxDarkGreenBright,
169− Light: gruvboxLightGreenBright,
170− }
171− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
108+ theme.DiffHighlightRemovedColor = lipgloss.Color(gruvboxDarkRedBright)
172− Dark: gruvboxDarkRedBright,
173− Light: gruvboxLightRedBright,
174− }
175− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
176− Dark: "#3C4C3C", // Darker green background
109+ theme.DiffAddedBgColor = lipgloss.Color("#3C4C3C") // Darker green background
177− Light: "#E8F5E9", // Light green background
178− }
179− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
110+ theme.DiffRemovedBgColor = lipgloss.Color("#4C3C3C") // Darker red background
180− Dark: "#4C3C3C", // Darker red background
181− Light: "#FFEBEE", // Light red background
182− }
183− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
111+ theme.DiffContextBgColor = lipgloss.Color(gruvboxDarkBg0)
184− Dark: gruvboxDarkBg0,
185− Light: gruvboxLightBg0,
186− }
187− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
112+ theme.DiffLineNumberColor = lipgloss.Color(gruvboxDarkFg4)
188− Dark: gruvboxDarkFg4,
189− Light: gruvboxLightFg4,
190− }
191− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
113+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#32432F") // Slightly darker green
192− Dark: "#32432F", // Slightly darker green
193− Light: "#C8E6C9", // Light green
194− }
195− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
114+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#43322F") // Slightly darker red
196− Dark: "#43322F", // Slightly darker red
197− Light: "#FFCDD2", // Light red
198− }
199
115
200 // Markdown colors
116 // Markdown colors
201− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
117+ theme.MarkdownTextColor = lipgloss.Color(gruvboxDarkFg1)
202− Dark: gruvboxDarkFg1,
203− Light: gruvboxLightFg1,
204− }
205− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
118+ theme.MarkdownHeadingColor = lipgloss.Color(gruvboxDarkYellowBright)
206− Dark: gruvboxDarkYellowBright,
207− Light: gruvboxLightYellowBright,
208− }
209− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
119+ theme.MarkdownLinkColor = lipgloss.Color(gruvboxDarkBlueBright)
210− Dark: gruvboxDarkBlueBright,
211− Light: gruvboxLightBlueBright,
212− }
213− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
120+ theme.MarkdownLinkTextColor = lipgloss.Color(gruvboxDarkAquaBright)
214− Dark: gruvboxDarkAquaBright,
215− Light: gruvboxLightAquaBright,
216− }
217− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
121+ theme.MarkdownCodeColor = lipgloss.Color(gruvboxDarkGreenBright)
218− Dark: gruvboxDarkGreenBright,
219− Light: gruvboxLightGreenBright,
220− }
221− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
122+ theme.MarkdownBlockQuoteColor = lipgloss.Color(gruvboxDarkAquaBright)
222− Dark: gruvboxDarkAquaBright,
223− Light: gruvboxLightAquaBright,
224− }
225− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
123+ theme.MarkdownEmphColor = lipgloss.Color(gruvboxDarkYellowBright)
226− Dark: gruvboxDarkYellowBright,
227− Light: gruvboxLightYellowBright,
228− }
229− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
124+ theme.MarkdownStrongColor = lipgloss.Color(gruvboxDarkOrangeBright)
230− Dark: gruvboxDarkOrangeBright,
231− Light: gruvboxLightOrangeBright,
232− }
233− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
125+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(gruvboxDarkBg3)
234− Dark: gruvboxDarkBg3,
235− Light: gruvboxLightBg3,
236− }
237− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
126+ theme.MarkdownListItemColor = lipgloss.Color(gruvboxDarkBlueBright)
238− Dark: gruvboxDarkBlueBright,
239− Light: gruvboxLightBlueBright,
240− }
241− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
127+ theme.MarkdownListEnumerationColor = lipgloss.Color(gruvboxDarkBlueBright)
242− Dark: gruvboxDarkBlueBright,
243− Light: gruvboxLightBlueBright,
244− }
245− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
128+ theme.MarkdownImageColor = lipgloss.Color(gruvboxDarkPurpleBright)
246− Dark: gruvboxDarkPurpleBright,
247− Light: gruvboxLightPurpleBright,
248− }
249− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
129+ theme.MarkdownImageTextColor = lipgloss.Color(gruvboxDarkAquaBright)
250− Dark: gruvboxDarkAquaBright,
251− Light: gruvboxLightAquaBright,
252− }
253− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
130+ theme.MarkdownCodeBlockColor = lipgloss.Color(gruvboxDarkFg1)
254− Dark: gruvboxDarkFg1,
255− Light: gruvboxLightFg1,
256− }
257
131
258 // Syntax highlighting colors
132 // Syntax highlighting colors
259− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
133+ theme.SyntaxCommentColor = lipgloss.Color(gruvboxDarkGray)
260− Dark: gruvboxDarkGray,
261− Light: gruvboxLightGray,
262− }
263− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
134+ theme.SyntaxKeywordColor = lipgloss.Color(gruvboxDarkRedBright)
264− Dark: gruvboxDarkRedBright,
265− Light: gruvboxLightRedBright,
266− }
267− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
135+ theme.SyntaxFunctionColor = lipgloss.Color(gruvboxDarkGreenBright)
268− Dark: gruvboxDarkGreenBright,
269− Light: gruvboxLightGreenBright,
270− }
271− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
136+ theme.SyntaxVariableColor = lipgloss.Color(gruvboxDarkBlueBright)
272− Dark: gruvboxDarkBlueBright,
273− Light: gruvboxLightBlueBright,
274− }
275− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
137+ theme.SyntaxStringColor = lipgloss.Color(gruvboxDarkYellowBright)
276− Dark: gruvboxDarkYellowBright,
277− Light: gruvboxLightYellowBright,
278− }
279− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
138+ theme.SyntaxNumberColor = lipgloss.Color(gruvboxDarkPurpleBright)
280− Dark: gruvboxDarkPurpleBright,
281− Light: gruvboxLightPurpleBright,
282− }
283− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
139+ theme.SyntaxTypeColor = lipgloss.Color(gruvboxDarkYellow)
284− Dark: gruvboxDarkYellow,
285− Light: gruvboxLightYellow,
286− }
287− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
140+ theme.SyntaxOperatorColor = lipgloss.Color(gruvboxDarkAquaBright)
288− Dark: gruvboxDarkAquaBright,
289− Light: gruvboxLightAquaBright,
290− }
291− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
141+ theme.SyntaxPunctuationColor = lipgloss.Color(gruvboxDarkFg1)
292− Dark: gruvboxDarkFg1,
142+
293− Light: gruvboxLightFg1,
143+ return theme
294− }
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)
295
216
296 return theme
217 return theme
297}
218}
298
219
299func init() {
220func init() {
300− // Register the Gruvbox theme with the theme manager
221+ // Register the Gruvbox themes with the theme manager
301 RegisterTheme("gruvbox", NewGruvboxTheme())
222 RegisterTheme("gruvbox", NewGruvboxTheme())
223+ RegisterTheme("gruvbox-light", NewGruvboxLightTheme())
302}
224}
internal/tui/theme/monokai.go+128−206
@@ -1,7 +1,7 @@
1package theme
1package theme
2
2
3import (
3import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
5)
5)
6
6
7// MonokaiProTheme implements the Theme interface with Monokai Pro colors.
7// MonokaiProTheme implements the Theme interface with Monokai Pro colors.
@@ -27,6 +27,80 @@ func NewMonokaiProTheme() *MonokaiProTheme {
27 darkPurple := "#ab9df2"
27 darkPurple := "#ab9df2"
28 darkBorder := "#403e41"
28 darkBorder := "#403e41"
29
29
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 {
30 // Light mode colors (adapted from dark)
104 // Light mode colors (adapted from dark)
31 lightBackground := "#fafafa"
105 lightBackground := "#fafafa"
32 lightCurrentLine := "#f0f0f0"
106 lightCurrentLine := "#f0f0f0"
@@ -45,229 +119,77 @@ func NewMonokaiProTheme() *MonokaiProTheme {
45 theme := &MonokaiProTheme{}
119 theme := &MonokaiProTheme{}
46
120
47 // Base colors
121 // Base colors
48− theme.PrimaryColor = lipgloss.AdaptiveColor{
122+ theme.PrimaryColor = lipgloss.Color(lightCyan)
49− Dark: darkCyan,
50− Light: lightCyan,
51− }
52− theme.SecondaryColor = lipgloss.AdaptiveColor{
123+ theme.SecondaryColor = lipgloss.Color(lightPurple)
53− Dark: darkPurple,
54− Light: lightPurple,
55− }
56− theme.AccentColor = lipgloss.AdaptiveColor{
124+ theme.AccentColor = lipgloss.Color(lightOrange)
57− Dark: darkOrange,
58− Light: lightOrange,
59− }
60
125
61 // Status colors
126 // Status colors
62− theme.ErrorColor = lipgloss.AdaptiveColor{
127+ theme.ErrorColor = lipgloss.Color(lightRed)
63− Dark: darkRed,
64− Light: lightRed,
65− }
66− theme.WarningColor = lipgloss.AdaptiveColor{
128+ theme.WarningColor = lipgloss.Color(lightOrange)
67− Dark: darkOrange,
68− Light: lightOrange,
69− }
70− theme.SuccessColor = lipgloss.AdaptiveColor{
129+ theme.SuccessColor = lipgloss.Color(lightGreen)
71− Dark: darkGreen,
72− Light: lightGreen,
73− }
74− theme.InfoColor = lipgloss.AdaptiveColor{
130+ theme.InfoColor = lipgloss.Color(lightBlue)
75− Dark: darkBlue,
76− Light: lightBlue,
77− }
78
131
79 // Text colors
132 // Text colors
80− theme.TextColor = lipgloss.AdaptiveColor{
133+ theme.TextColor = lipgloss.Color(lightForeground)
81− Dark: darkForeground,
82− Light: lightForeground,
83− }
84− theme.TextMutedColor = lipgloss.AdaptiveColor{
134+ theme.TextMutedColor = lipgloss.Color(lightComment)
85− Dark: darkComment,
86− Light: lightComment,
87− }
88− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
135+ theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
89− Dark: darkYellow,
90− Light: lightYellow,
91− }
92
136
93 // Background colors
137 // Background colors
94− theme.BackgroundColor = lipgloss.AdaptiveColor{
138+ theme.BackgroundColor = lipgloss.Color(lightBackground)
95− Dark: darkBackground,
96− Light: lightBackground,
97− }
98− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
139+ theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
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
140+ theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
105− }
106
141
107 // Border colors
142 // Border colors
108− theme.BorderNormalColor = lipgloss.AdaptiveColor{
143+ theme.BorderNormalColor = lipgloss.Color(lightBorder)
109− Dark: darkBorder,
110− Light: lightBorder,
111− }
112− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
144+ theme.BorderFocusedColor = lipgloss.Color(lightCyan)
113− Dark: darkCyan,
114− Light: lightCyan,
115− }
116− theme.BorderDimColor = lipgloss.AdaptiveColor{
145+ theme.BorderDimColor = lipgloss.Color(lightSelection)
117− Dark: darkSelection,
118− Light: lightSelection,
119− }
120
146
121 // Diff view colors
147 // Diff view colors
122− theme.DiffAddedColor = lipgloss.AdaptiveColor{
148+ theme.DiffAddedColor = lipgloss.Color("#9bca65")
123− Dark: "#a9dc76",
124− Light: "#9bca65",
125− }
126− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
149+ theme.DiffRemovedColor = lipgloss.Color("#f92672")
127− Dark: "#ff6188",
128− Light: "#f92672",
129− }
130− theme.DiffContextColor = lipgloss.AdaptiveColor{
150+ theme.DiffContextColor = lipgloss.Color("#757575")
131− Dark: "#a0a0a0",
132− Light: "#757575",
133− }
134− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
151+ theme.DiffHunkHeaderColor = lipgloss.Color("#757575")
135− Dark: "#a0a0a0",
136− Light: "#757575",
137− }
138− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
152+ theme.DiffHighlightAddedColor = lipgloss.Color("#c5e0b4")
139− Dark: "#c2e7a9",
140− Light: "#c5e0b4",
141− }
142− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
153+ theme.DiffHighlightRemovedColor = lipgloss.Color("#ffb3c8")
143− Dark: "#ff8ca6",
144− Light: "#ffb3c8",
145− }
146− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
154+ theme.DiffAddedBgColor = lipgloss.Color("#e8f5e9")
147− Dark: "#3a4a35",
148− Light: "#e8f5e9",
149− }
150− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
155+ theme.DiffRemovedBgColor = lipgloss.Color("#ffebee")
151− Dark: "#4a3439",
152− Light: "#ffebee",
153− }
154− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
156+ theme.DiffContextBgColor = lipgloss.Color(lightBackground)
155− Dark: darkBackground,
156− Light: lightBackground,
157− }
158− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
157+ theme.DiffLineNumberColor = lipgloss.Color("#9e9e9e")
159− Dark: "#888888",
160− Light: "#9e9e9e",
161− }
162− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
158+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#c8e6c9")
163− Dark: "#2d3a28",
164− Light: "#c8e6c9",
165− }
166− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
159+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#ffcdd2")
167− Dark: "#3d2a2e",
168− Light: "#ffcdd2",
169− }
170
160
171 // Markdown colors
161 // Markdown colors
172− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
162+ theme.MarkdownTextColor = lipgloss.Color(lightForeground)
173− Dark: darkForeground,
174− Light: lightForeground,
175− }
176− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
163+ theme.MarkdownHeadingColor = lipgloss.Color(lightPurple)
177− Dark: darkPurple,
178− Light: lightPurple,
179− }
180− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
164+ theme.MarkdownLinkColor = lipgloss.Color(lightCyan)
181− Dark: darkCyan,
182− Light: lightCyan,
183− }
184− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
165+ theme.MarkdownLinkTextColor = lipgloss.Color(lightBlue)
185− Dark: darkBlue,
186− Light: lightBlue,
187− }
188− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
166+ theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
189− Dark: darkGreen,
190− Light: lightGreen,
191− }
192− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
167+ theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
193− Dark: darkYellow,
194− Light: lightYellow,
195− }
196− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
168+ theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
197− Dark: darkYellow,
198− Light: lightYellow,
199− }
200− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
169+ theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
201− Dark: darkOrange,
202− Light: lightOrange,
203− }
204− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
170+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
205− Dark: darkComment,
206− Light: lightComment,
207− }
208− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
171+ theme.MarkdownListItemColor = lipgloss.Color(lightCyan)
209− Dark: darkCyan,
210− Light: lightCyan,
211− }
212− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
172+ theme.MarkdownListEnumerationColor = lipgloss.Color(lightBlue)
213− Dark: darkBlue,
214− Light: lightBlue,
215− }
216− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
173+ theme.MarkdownImageColor = lipgloss.Color(lightCyan)
217− Dark: darkCyan,
218− Light: lightCyan,
219− }
220− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
174+ theme.MarkdownImageTextColor = lipgloss.Color(lightBlue)
221− Dark: darkBlue,
222− Light: lightBlue,
223− }
224− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
175+ theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
225− Dark: darkForeground,
226− Light: lightForeground,
227− }
228
176
229 // Syntax highlighting colors
177 // Syntax highlighting colors
230− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
178+ theme.SyntaxCommentColor = lipgloss.Color(lightComment)
231− Dark: darkComment,
232− Light: lightComment,
233− }
234− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
179+ theme.SyntaxKeywordColor = lipgloss.Color(lightRed)
235− Dark: darkRed,
236− Light: lightRed,
237− }
238− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
180+ theme.SyntaxFunctionColor = lipgloss.Color(lightGreen)
239− Dark: darkGreen,
240− Light: lightGreen,
241− }
242− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
181+ theme.SyntaxVariableColor = lipgloss.Color(lightForeground)
243− Dark: darkForeground,
244− Light: lightForeground,
245− }
246− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
182+ theme.SyntaxStringColor = lipgloss.Color(lightYellow)
247− Dark: darkYellow,
248− Light: lightYellow,
249− }
250− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
183+ theme.SyntaxNumberColor = lipgloss.Color(lightPurple)
251− Dark: darkPurple,
252− Light: lightPurple,
253− }
254− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
184+ theme.SyntaxTypeColor = lipgloss.Color(lightBlue)
255− Dark: darkBlue,
256− Light: lightBlue,
257− }
258− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
185+ theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
259− Dark: darkCyan,
260− Light: lightCyan,
261− }
262− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
186+ theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
263− Dark: darkForeground,
264− Light: lightForeground,
265− }
266
187
267 return theme
188 return theme
268}
189}
269
190
270func init() {
191func init() {
271− // Register the Monokai Pro theme with the theme manager
192+ // Register the Monokai Pro themes with the theme manager
272 RegisterTheme("monokai", NewMonokaiProTheme())
193 RegisterTheme("monokai", NewMonokaiProTheme())
194+ RegisterTheme("monokai-light", NewMonokaiProLightTheme())
273}
195}
internal/tui/theme/onedark.go+128−206
@@ -1,7 +1,7 @@
1package theme
1package theme
2
2
3import (
3import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
5)
5)
6
6
7// OneDarkTheme implements the Theme interface with Atom's One Dark colors.
7// OneDarkTheme implements the Theme interface with Atom's One Dark colors.
@@ -28,6 +28,80 @@ func NewOneDarkTheme() *OneDarkTheme {
28 darkPurple := "#c678dd"
28 darkPurple := "#c678dd"
29 darkBorder := "#3b4048"
29 darkBorder := "#3b4048"
30
30
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 {
31 // Light mode colors from Atom One Light
105 // Light mode colors from Atom One Light
32 lightBackground := "#fafafa"
106 lightBackground := "#fafafa"
33 lightCurrentLine := "#f0f0f0"
107 lightCurrentLine := "#f0f0f0"
@@ -46,229 +120,77 @@ func NewOneDarkTheme() *OneDarkTheme {
46 theme := &OneDarkTheme{}
120 theme := &OneDarkTheme{}
47
121
48 // Base colors
122 // Base colors
49− theme.PrimaryColor = lipgloss.AdaptiveColor{
123+ theme.PrimaryColor = lipgloss.Color(lightBlue)
50− Dark: darkBlue,
51− Light: lightBlue,
52− }
53− theme.SecondaryColor = lipgloss.AdaptiveColor{
124+ theme.SecondaryColor = lipgloss.Color(lightPurple)
54− Dark: darkPurple,
55− Light: lightPurple,
56− }
57− theme.AccentColor = lipgloss.AdaptiveColor{
125+ theme.AccentColor = lipgloss.Color(lightOrange)
58− Dark: darkOrange,
59− Light: lightOrange,
60− }
61
126
62 // Status colors
127 // Status colors
63− theme.ErrorColor = lipgloss.AdaptiveColor{
128+ theme.ErrorColor = lipgloss.Color(lightRed)
64− Dark: darkRed,
65− Light: lightRed,
66− }
67− theme.WarningColor = lipgloss.AdaptiveColor{
129+ theme.WarningColor = lipgloss.Color(lightOrange)
68− Dark: darkOrange,
69− Light: lightOrange,
70− }
71− theme.SuccessColor = lipgloss.AdaptiveColor{
130+ theme.SuccessColor = lipgloss.Color(lightGreen)
72− Dark: darkGreen,
73− Light: lightGreen,
74− }
75− theme.InfoColor = lipgloss.AdaptiveColor{
131+ theme.InfoColor = lipgloss.Color(lightBlue)
76− Dark: darkBlue,
77− Light: lightBlue,
78− }
79
132
80 // Text colors
133 // Text colors
81− theme.TextColor = lipgloss.AdaptiveColor{
134+ theme.TextColor = lipgloss.Color(lightForeground)
82− Dark: darkForeground,
83− Light: lightForeground,
84− }
85− theme.TextMutedColor = lipgloss.AdaptiveColor{
135+ theme.TextMutedColor = lipgloss.Color(lightComment)
86− Dark: darkComment,
87− Light: lightComment,
88− }
89− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
136+ theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
90− Dark: darkYellow,
91− Light: lightYellow,
92− }
93
137
94 // Background colors
138 // Background colors
95− theme.BackgroundColor = lipgloss.AdaptiveColor{
139+ theme.BackgroundColor = lipgloss.Color(lightBackground)
96− Dark: darkBackground,
97− Light: lightBackground,
98− }
99− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
140+ theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
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
141+ theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
106− }
107
142
108 // Border colors
143 // Border colors
109− theme.BorderNormalColor = lipgloss.AdaptiveColor{
144+ theme.BorderNormalColor = lipgloss.Color(lightBorder)
110− Dark: darkBorder,
111− Light: lightBorder,
112− }
113− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
145+ theme.BorderFocusedColor = lipgloss.Color(lightBlue)
114− Dark: darkBlue,
115− Light: lightBlue,
116− }
117− theme.BorderDimColor = lipgloss.AdaptiveColor{
146+ theme.BorderDimColor = lipgloss.Color(lightSelection)
118− Dark: darkSelection,
119− Light: lightSelection,
120− }
121
147
122 // Diff view colors
148 // Diff view colors
123− theme.DiffAddedColor = lipgloss.AdaptiveColor{
149+ theme.DiffAddedColor = lipgloss.Color("#2E7D32")
124− Dark: "#478247",
125− Light: "#2E7D32",
126− }
127− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
150+ theme.DiffRemovedColor = lipgloss.Color("#C62828")
128− Dark: "#7C4444",
129− Light: "#C62828",
130− }
131− theme.DiffContextColor = lipgloss.AdaptiveColor{
151+ theme.DiffContextColor = lipgloss.Color("#757575")
132− Dark: "#a0a0a0",
133− Light: "#757575",
134− }
135− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
152+ theme.DiffHunkHeaderColor = lipgloss.Color("#757575")
136− Dark: "#a0a0a0",
137− Light: "#757575",
138− }
139− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
153+ theme.DiffHighlightAddedColor = lipgloss.Color("#A5D6A7")
140− Dark: "#DAFADA",
141− Light: "#A5D6A7",
142− }
143− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
154+ theme.DiffHighlightRemovedColor = lipgloss.Color("#EF9A9A")
144− Dark: "#FADADD",
145− Light: "#EF9A9A",
146− }
147− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
155+ theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9")
148− Dark: "#303A30",
149− Light: "#E8F5E9",
150− }
151− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
156+ theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE")
152− Dark: "#3A3030",
153− Light: "#FFEBEE",
154− }
155− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
157+ theme.DiffContextBgColor = lipgloss.Color(lightBackground)
156− Dark: darkBackground,
157− Light: lightBackground,
158− }
159− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
158+ theme.DiffLineNumberColor = lipgloss.Color("#9E9E9E")
160− Dark: "#888888",
161− Light: "#9E9E9E",
162− }
163− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
159+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9")
164− Dark: "#293229",
165− Light: "#C8E6C9",
166− }
167− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
160+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2")
168− Dark: "#332929",
169− Light: "#FFCDD2",
170− }
171
161
172 // Markdown colors
162 // Markdown colors
173− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
163+ theme.MarkdownTextColor = lipgloss.Color(lightForeground)
174− Dark: darkForeground,
175− Light: lightForeground,
176− }
177− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
164+ theme.MarkdownHeadingColor = lipgloss.Color(lightPurple)
178− Dark: darkPurple,
179− Light: lightPurple,
180− }
181− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
165+ theme.MarkdownLinkColor = lipgloss.Color(lightBlue)
182− Dark: darkBlue,
183− Light: lightBlue,
184− }
185− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
166+ theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
186− Dark: darkCyan,
187− Light: lightCyan,
188− }
189− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
167+ theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
190− Dark: darkGreen,
191− Light: lightGreen,
192− }
193− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
168+ theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
194− Dark: darkYellow,
195− Light: lightYellow,
196− }
197− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
169+ theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
198− Dark: darkYellow,
199− Light: lightYellow,
200− }
201− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
170+ theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
202− Dark: darkOrange,
203− Light: lightOrange,
204− }
205− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
171+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
206− Dark: darkComment,
207− Light: lightComment,
208− }
209− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
172+ theme.MarkdownListItemColor = lipgloss.Color(lightBlue)
210− Dark: darkBlue,
211− Light: lightBlue,
212− }
213− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
173+ theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
214− Dark: darkCyan,
215− Light: lightCyan,
216− }
217− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
174+ theme.MarkdownImageColor = lipgloss.Color(lightBlue)
218− Dark: darkBlue,
219− Light: lightBlue,
220− }
221− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
175+ theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
222− Dark: darkCyan,
223− Light: lightCyan,
224− }
225− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
176+ theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
226− Dark: darkForeground,
227− Light: lightForeground,
228− }
229
177
230 // Syntax highlighting colors
178 // Syntax highlighting colors
231− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
179+ theme.SyntaxCommentColor = lipgloss.Color(lightComment)
232− Dark: darkComment,
233− Light: lightComment,
234− }
235− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
180+ theme.SyntaxKeywordColor = lipgloss.Color(lightPurple)
236− Dark: darkPurple,
237− Light: lightPurple,
238− }
239− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
181+ theme.SyntaxFunctionColor = lipgloss.Color(lightBlue)
240− Dark: darkBlue,
241− Light: lightBlue,
242− }
243− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
182+ theme.SyntaxVariableColor = lipgloss.Color(lightRed)
244− Dark: darkRed,
245− Light: lightRed,
246− }
247− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
183+ theme.SyntaxStringColor = lipgloss.Color(lightGreen)
248− Dark: darkGreen,
249− Light: lightGreen,
250− }
251− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
184+ theme.SyntaxNumberColor = lipgloss.Color(lightOrange)
252− Dark: darkOrange,
253− Light: lightOrange,
254− }
255− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
185+ theme.SyntaxTypeColor = lipgloss.Color(lightYellow)
256− Dark: darkYellow,
257− Light: lightYellow,
258− }
259− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
186+ theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
260− Dark: darkCyan,
261− Light: lightCyan,
262− }
263− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
187+ theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
264− Dark: darkForeground,
265− Light: lightForeground,
266− }
267
188
268 return theme
189 return theme
269}
190}
270
191
271func init() {
192func init() {
272− // Register the One Dark theme with the theme manager
193+ // Register the One Dark and One Light themes with the theme manager
273 RegisterTheme("onedark", NewOneDarkTheme())
194 RegisterTheme("onedark", NewOneDarkTheme())
195+ RegisterTheme("onelight", NewOneLightTheme())
274}
196}
internal/tui/theme/opencode.go+132−211
@@ -1,7 +1,7 @@
1package theme
1package theme
2
2
3import (
3import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
5)
5)
6
6
7// OpenCodeTheme implements the Theme interface with OpenCode brand colors.
7// OpenCodeTheme implements the Theme interface with OpenCode brand colors.
@@ -10,8 +10,8 @@ type OpenCodeTheme struct {
10 BaseTheme
10 BaseTheme
11}
11}
12
12
13−// NewOpenCodeTheme creates a new instance of the OpenCode theme.
13+// NewOpenCodeDarkTheme creates a new instance of the OpenCode Dark theme.
14−func NewOpenCodeTheme() *OpenCodeTheme {
14+func NewOpenCodeDarkTheme() *OpenCodeTheme {
15 // OpenCode color palette
15 // OpenCode color palette
16 // Dark mode colors
16 // Dark mode colors
17 darkBackground := "#212121"
17 darkBackground := "#212121"
@@ -29,6 +29,80 @@ func NewOpenCodeTheme() *OpenCodeTheme {
29 darkYellow := "#e5c07b" // Emphasized text
29 darkYellow := "#e5c07b" // Emphasized text
30 darkBorder := "#4b4c5c" // Border color
30 darkBorder := "#4b4c5c" // Border color
31
31
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 {
32 // Light mode colors
106 // Light mode colors
33 lightBackground := "#f8f8f8"
107 lightBackground := "#f8f8f8"
34 lightCurrentLine := "#f0f0f0"
108 lightCurrentLine := "#f0f0f0"
@@ -48,230 +122,77 @@ func NewOpenCodeTheme() *OpenCodeTheme {
48 theme := &OpenCodeTheme{}
122 theme := &OpenCodeTheme{}
49
123
50 // Base colors
124 // Base colors
51− theme.PrimaryColor = lipgloss.AdaptiveColor{
125+ theme.PrimaryColor = lipgloss.Color(lightPrimary)
52− Dark: darkPrimary,
53− Light: lightPrimary,
54− }
55− theme.SecondaryColor = lipgloss.AdaptiveColor{
126+ theme.SecondaryColor = lipgloss.Color(lightSecondary)
56− Dark: darkSecondary,
57− Light: lightSecondary,
58− }
59− theme.AccentColor = lipgloss.AdaptiveColor{
127+ theme.AccentColor = lipgloss.Color(lightAccent)
60− Dark: darkAccent,
61− Light: lightAccent,
62− }
63
128
64 // Status colors
129 // Status colors
65− theme.ErrorColor = lipgloss.AdaptiveColor{
130+ theme.ErrorColor = lipgloss.Color(lightRed)
66− Dark: darkRed,
67− Light: lightRed,
68− }
69− theme.WarningColor = lipgloss.AdaptiveColor{
131+ theme.WarningColor = lipgloss.Color(lightOrange)
70− Dark: darkOrange,
71− Light: lightOrange,
72− }
73− theme.SuccessColor = lipgloss.AdaptiveColor{
132+ theme.SuccessColor = lipgloss.Color(lightGreen)
74− Dark: darkGreen,
75− Light: lightGreen,
76− }
77− theme.InfoColor = lipgloss.AdaptiveColor{
133+ theme.InfoColor = lipgloss.Color(lightCyan)
78− Dark: darkCyan,
79− Light: lightCyan,
80− }
81
134
82 // Text colors
135 // Text colors
83− theme.TextColor = lipgloss.AdaptiveColor{
136+ theme.TextColor = lipgloss.Color(lightForeground)
84− Dark: darkForeground,
85− Light: lightForeground,
86− }
87− theme.TextMutedColor = lipgloss.AdaptiveColor{
137+ theme.TextMutedColor = lipgloss.Color(lightComment)
88− Dark: darkComment,
89− Light: lightComment,
90− }
91− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
138+ theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
92− Dark: darkYellow,
93− Light: lightYellow,
94− }
95
139
96 // Background colors
140 // Background colors
97− theme.BackgroundColor = lipgloss.AdaptiveColor{
141+ theme.BackgroundColor = lipgloss.Color(lightBackground)
98− Dark: darkBackground,
99− Light: lightBackground,
100− }
101− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
142+ theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
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
143+ theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
108− }
109
144
110 // Border colors
145 // Border colors
111− theme.BorderNormalColor = lipgloss.AdaptiveColor{
146+ theme.BorderNormalColor = lipgloss.Color(lightBorder)
112− Dark: darkBorder,
113− Light: lightBorder,
114− }
115− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
147+ theme.BorderFocusedColor = lipgloss.Color(lightPrimary)
116− Dark: darkPrimary,
117− Light: lightPrimary,
118− }
119− theme.BorderDimColor = lipgloss.AdaptiveColor{
148+ theme.BorderDimColor = lipgloss.Color(lightSelection)
120− Dark: darkSelection,
121− Light: lightSelection,
122− }
123
149
124 // Diff view colors
150 // Diff view colors
125− theme.DiffAddedColor = lipgloss.AdaptiveColor{
151+ theme.DiffAddedColor = lipgloss.Color("#2E7D32")
126− Dark: "#478247",
127− Light: "#2E7D32",
128− }
129− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
152+ theme.DiffRemovedColor = lipgloss.Color("#C62828")
130− Dark: "#7C4444",
131− Light: "#C62828",
132− }
133− theme.DiffContextColor = lipgloss.AdaptiveColor{
153+ theme.DiffContextColor = lipgloss.Color("#757575")
134− Dark: "#a0a0a0",
135− Light: "#757575",
136− }
137− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
154+ theme.DiffHunkHeaderColor = lipgloss.Color("#757575")
138− Dark: "#a0a0a0",
139− Light: "#757575",
140− }
141− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
155+ theme.DiffHighlightAddedColor = lipgloss.Color("#A5D6A7")
142− Dark: "#DAFADA",
143− Light: "#A5D6A7",
144− }
145− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
156+ theme.DiffHighlightRemovedColor = lipgloss.Color("#EF9A9A")
146− Dark: "#FADADD",
147− Light: "#EF9A9A",
148− }
149− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
157+ theme.DiffAddedBgColor = lipgloss.Color("#E8F5E9")
150− Dark: "#303A30",
151− Light: "#E8F5E9",
152− }
153− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
158+ theme.DiffRemovedBgColor = lipgloss.Color("#FFEBEE")
154− Dark: "#3A3030",
155− Light: "#FFEBEE",
156− }
157− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
159+ theme.DiffContextBgColor = lipgloss.Color(lightBackground)
158− Dark: darkBackground,
159− Light: lightBackground,
160− }
161− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
160+ theme.DiffLineNumberColor = lipgloss.Color("#9E9E9E")
162− Dark: "#888888",
163− Light: "#9E9E9E",
164− }
165− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
161+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#C8E6C9")
166− Dark: "#293229",
167− Light: "#C8E6C9",
168− }
169− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
162+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#FFCDD2")
170− Dark: "#332929",
171− Light: "#FFCDD2",
172− }
173
163
174 // Markdown colors
164 // Markdown colors
175− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
165+ theme.MarkdownTextColor = lipgloss.Color(lightForeground)
176− Dark: darkForeground,
177− Light: lightForeground,
178− }
179− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
166+ theme.MarkdownHeadingColor = lipgloss.Color(lightSecondary)
180− Dark: darkSecondary,
181− Light: lightSecondary,
182− }
183− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
167+ theme.MarkdownLinkColor = lipgloss.Color(lightPrimary)
184− Dark: darkPrimary,
185− Light: lightPrimary,
186− }
187− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
168+ theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
188− Dark: darkCyan,
189− Light: lightCyan,
190− }
191− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
169+ theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
192− Dark: darkGreen,
193− Light: lightGreen,
194− }
195− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
170+ theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
196− Dark: darkYellow,
197− Light: lightYellow,
198− }
199− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
171+ theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
200− Dark: darkYellow,
201− Light: lightYellow,
202− }
203− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
172+ theme.MarkdownStrongColor = lipgloss.Color(lightAccent)
204− Dark: darkAccent,
205− Light: lightAccent,
206− }
207− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
173+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
208− Dark: darkComment,
209− Light: lightComment,
210− }
211− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
174+ theme.MarkdownListItemColor = lipgloss.Color(lightPrimary)
212− Dark: darkPrimary,
213− Light: lightPrimary,
214− }
215− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
175+ theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
216− Dark: darkCyan,
217− Light: lightCyan,
218− }
219− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
176+ theme.MarkdownImageColor = lipgloss.Color(lightPrimary)
220− Dark: darkPrimary,
221− Light: lightPrimary,
222− }
223− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
177+ theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
224− Dark: darkCyan,
225− Light: lightCyan,
226− }
227− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
178+ theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
228− Dark: darkForeground,
229− Light: lightForeground,
230− }
231
179
232 // Syntax highlighting colors
180 // Syntax highlighting colors
233− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
181+ theme.SyntaxCommentColor = lipgloss.Color(lightComment)
234− Dark: darkComment,
235− Light: lightComment,
236− }
237− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
182+ theme.SyntaxKeywordColor = lipgloss.Color(lightSecondary)
238− Dark: darkSecondary,
239− Light: lightSecondary,
240− }
241− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
183+ theme.SyntaxFunctionColor = lipgloss.Color(lightPrimary)
242− Dark: darkPrimary,
243− Light: lightPrimary,
244− }
245− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
184+ theme.SyntaxVariableColor = lipgloss.Color(lightRed)
246− Dark: darkRed,
247− Light: lightRed,
248− }
249− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
185+ theme.SyntaxStringColor = lipgloss.Color(lightGreen)
250− Dark: darkGreen,
251− Light: lightGreen,
252− }
253− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
186+ theme.SyntaxNumberColor = lipgloss.Color(lightAccent)
254− Dark: darkAccent,
255− Light: lightAccent,
256− }
257− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
187+ theme.SyntaxTypeColor = lipgloss.Color(lightYellow)
258− Dark: darkYellow,
259− Light: lightYellow,
260− }
261− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
188+ theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
262− Dark: darkCyan,
263− Light: lightCyan,
264− }
265− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
189+ theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
266− Dark: darkForeground,
267− Light: lightForeground,
268− }
269
190
270 return theme
191 return theme
271}
192}
272
193
273func init() {
194func init() {
274− // Register the OpenCode theme with the theme manager
195+ // Register the OpenCode themes with the theme manager
275− RegisterTheme("opencode", NewOpenCodeTheme())
196+ RegisterTheme("opencode-dark", NewOpenCodeDarkTheme())
197+ RegisterTheme("opencode-light", NewOpenCodeLightTheme())
276−}
198+}
277−
internal/tui/theme/theme.go+161−164
@@ -1,208 +1,205 @@
1package theme
1package theme
2
2
3import (
3import (
4− "github.com/charmbracelet/lipgloss"
4+ "image/color"
5)
5)
6
6
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.
10type Theme interface {
7type Theme interface {
11 // Base colors
8 // Base colors
12− Primary() lipgloss.AdaptiveColor
9+ Primary() color.Color
13− Secondary() lipgloss.AdaptiveColor
10+ Secondary() color.Color
14− Accent() lipgloss.AdaptiveColor
11+ Accent() color.Color
15
12
16 // Status colors
13 // Status colors
17− Error() lipgloss.AdaptiveColor
14+ Error() color.Color
18− Warning() lipgloss.AdaptiveColor
15+ Warning() color.Color
19− Success() lipgloss.AdaptiveColor
16+ Success() color.Color
20− Info() lipgloss.AdaptiveColor
17+ Info() color.Color
21
18
22 // Text colors
19 // Text colors
23− Text() lipgloss.AdaptiveColor
20+ Text() color.Color
24− TextMuted() lipgloss.AdaptiveColor
21+ TextMuted() color.Color
25− TextEmphasized() lipgloss.AdaptiveColor
22+ TextEmphasized() color.Color
26
23
27 // Background colors
24 // Background colors
28− Background() lipgloss.AdaptiveColor
25+ Background() color.Color
29− BackgroundSecondary() lipgloss.AdaptiveColor
26+ BackgroundSecondary() color.Color
30− BackgroundDarker() lipgloss.AdaptiveColor
27+ BackgroundDarker() color.Color
31
28
32 // Border colors
29 // Border colors
33− BorderNormal() lipgloss.AdaptiveColor
30+ BorderNormal() color.Color
34− BorderFocused() lipgloss.AdaptiveColor
31+ BorderFocused() color.Color
35− BorderDim() lipgloss.AdaptiveColor
32+ BorderDim() color.Color
36
33
37 // Diff view colors
34 // Diff view colors
38− DiffAdded() lipgloss.AdaptiveColor
35+ DiffAdded() color.Color
39− DiffRemoved() lipgloss.AdaptiveColor
36+ DiffRemoved() color.Color
40− DiffContext() lipgloss.AdaptiveColor
37+ DiffContext() color.Color
41− DiffHunkHeader() lipgloss.AdaptiveColor
38+ DiffHunkHeader() color.Color
42− DiffHighlightAdded() lipgloss.AdaptiveColor
39+ DiffHighlightAdded() color.Color
43− DiffHighlightRemoved() lipgloss.AdaptiveColor
40+ DiffHighlightRemoved() color.Color
44− DiffAddedBg() lipgloss.AdaptiveColor
41+ DiffAddedBg() color.Color
45− DiffRemovedBg() lipgloss.AdaptiveColor
42+ DiffRemovedBg() color.Color
46− DiffContextBg() lipgloss.AdaptiveColor
43+ DiffContextBg() color.Color
47− DiffLineNumber() lipgloss.AdaptiveColor
44+ DiffLineNumber() color.Color
48− DiffAddedLineNumberBg() lipgloss.AdaptiveColor
45+ DiffAddedLineNumberBg() color.Color
49− DiffRemovedLineNumberBg() lipgloss.AdaptiveColor
46+ DiffRemovedLineNumberBg() color.Color
50
47
51 // Markdown colors
48 // Markdown colors
52− MarkdownText() lipgloss.AdaptiveColor
49+ MarkdownText() color.Color
53− MarkdownHeading() lipgloss.AdaptiveColor
50+ MarkdownHeading() color.Color
54− MarkdownLink() lipgloss.AdaptiveColor
51+ MarkdownLink() color.Color
55− MarkdownLinkText() lipgloss.AdaptiveColor
52+ MarkdownLinkText() color.Color
56− MarkdownCode() lipgloss.AdaptiveColor
53+ MarkdownCode() color.Color
57− MarkdownBlockQuote() lipgloss.AdaptiveColor
54+ MarkdownBlockQuote() color.Color
58− MarkdownEmph() lipgloss.AdaptiveColor
55+ MarkdownEmph() color.Color
59− MarkdownStrong() lipgloss.AdaptiveColor
56+ MarkdownStrong() color.Color
60− MarkdownHorizontalRule() lipgloss.AdaptiveColor
57+ MarkdownHorizontalRule() color.Color
61− MarkdownListItem() lipgloss.AdaptiveColor
58+ MarkdownListItem() color.Color
62− MarkdownListEnumeration() lipgloss.AdaptiveColor
59+ MarkdownListEnumeration() color.Color
63− MarkdownImage() lipgloss.AdaptiveColor
60+ MarkdownImage() color.Color
64− MarkdownImageText() lipgloss.AdaptiveColor
61+ MarkdownImageText() color.Color
65− MarkdownCodeBlock() lipgloss.AdaptiveColor
62+ MarkdownCodeBlock() color.Color
66
63
67 // Syntax highlighting colors
64 // Syntax highlighting colors
68− SyntaxComment() lipgloss.AdaptiveColor
65+ SyntaxComment() color.Color
69− SyntaxKeyword() lipgloss.AdaptiveColor
66+ SyntaxKeyword() color.Color
70− SyntaxFunction() lipgloss.AdaptiveColor
67+ SyntaxFunction() color.Color
71− SyntaxVariable() lipgloss.AdaptiveColor
68+ SyntaxVariable() color.Color
72− SyntaxString() lipgloss.AdaptiveColor
69+ SyntaxString() color.Color
73− SyntaxNumber() lipgloss.AdaptiveColor
70+ SyntaxNumber() color.Color
74− SyntaxType() lipgloss.AdaptiveColor
71+ SyntaxType() color.Color
75− SyntaxOperator() lipgloss.AdaptiveColor
72+ SyntaxOperator() color.Color
76− SyntaxPunctuation() lipgloss.AdaptiveColor
73+ SyntaxPunctuation() color.Color
77}
74}
78
75
79// BaseTheme provides a default implementation of the Theme interface
76// BaseTheme provides a default implementation of the Theme interface
80// that can be embedded in concrete theme implementations.
77// that can be embedded in concrete theme implementations.
81type BaseTheme struct {
78type BaseTheme struct {
82 // Base colors
79 // Base colors
83− PrimaryColor lipgloss.AdaptiveColor
80+ PrimaryColor color.Color
84− SecondaryColor lipgloss.AdaptiveColor
81+ SecondaryColor color.Color
85− AccentColor lipgloss.AdaptiveColor
82+ AccentColor color.Color
86
83
87 // Status colors
84 // Status colors
88− ErrorColor lipgloss.AdaptiveColor
85+ ErrorColor color.Color
89− WarningColor lipgloss.AdaptiveColor
86+ WarningColor color.Color
90− SuccessColor lipgloss.AdaptiveColor
87+ SuccessColor color.Color
91− InfoColor lipgloss.AdaptiveColor
88+ InfoColor color.Color
92
89
93 // Text colors
90 // Text colors
94− TextColor lipgloss.AdaptiveColor
91+ TextColor color.Color
95− TextMutedColor lipgloss.AdaptiveColor
92+ TextMutedColor color.Color
96− TextEmphasizedColor lipgloss.AdaptiveColor
93+ TextEmphasizedColor color.Color
97
94
98 // Background colors
95 // Background colors
99− BackgroundColor lipgloss.AdaptiveColor
96+ BackgroundColor color.Color
100− BackgroundSecondaryColor lipgloss.AdaptiveColor
97+ BackgroundSecondaryColor color.Color
101− BackgroundDarkerColor lipgloss.AdaptiveColor
98+ BackgroundDarkerColor color.Color
102
99
103 // Border colors
100 // Border colors
104− BorderNormalColor lipgloss.AdaptiveColor
101+ BorderNormalColor color.Color
105− BorderFocusedColor lipgloss.AdaptiveColor
102+ BorderFocusedColor color.Color
106− BorderDimColor lipgloss.AdaptiveColor
103+ BorderDimColor color.Color
107
104
108 // Diff view colors
105 // Diff view colors
109− DiffAddedColor lipgloss.AdaptiveColor
106+ DiffAddedColor color.Color
110− DiffRemovedColor lipgloss.AdaptiveColor
107+ DiffRemovedColor color.Color
111− DiffContextColor lipgloss.AdaptiveColor
108+ DiffContextColor color.Color
112− DiffHunkHeaderColor lipgloss.AdaptiveColor
109+ DiffHunkHeaderColor color.Color
113− DiffHighlightAddedColor lipgloss.AdaptiveColor
110+ DiffHighlightAddedColor color.Color
114− DiffHighlightRemovedColor lipgloss.AdaptiveColor
111+ DiffHighlightRemovedColor color.Color
115− DiffAddedBgColor lipgloss.AdaptiveColor
112+ DiffAddedBgColor color.Color
116− DiffRemovedBgColor lipgloss.AdaptiveColor
113+ DiffRemovedBgColor color.Color
117− DiffContextBgColor lipgloss.AdaptiveColor
114+ DiffContextBgColor color.Color
118− DiffLineNumberColor lipgloss.AdaptiveColor
115+ DiffLineNumberColor color.Color
119− DiffAddedLineNumberBgColor lipgloss.AdaptiveColor
116+ DiffAddedLineNumberBgColor color.Color
120− DiffRemovedLineNumberBgColor lipgloss.AdaptiveColor
117+ DiffRemovedLineNumberBgColor color.Color
121
118
122 // Markdown colors
119 // Markdown colors
123− MarkdownTextColor lipgloss.AdaptiveColor
120+ MarkdownTextColor color.Color
124− MarkdownHeadingColor lipgloss.AdaptiveColor
121+ MarkdownHeadingColor color.Color
125− MarkdownLinkColor lipgloss.AdaptiveColor
122+ MarkdownLinkColor color.Color
126− MarkdownLinkTextColor lipgloss.AdaptiveColor
123+ MarkdownLinkTextColor color.Color
127− MarkdownCodeColor lipgloss.AdaptiveColor
124+ MarkdownCodeColor color.Color
128− MarkdownBlockQuoteColor lipgloss.AdaptiveColor
125+ MarkdownBlockQuoteColor color.Color
129− MarkdownEmphColor lipgloss.AdaptiveColor
126+ MarkdownEmphColor color.Color
130− MarkdownStrongColor lipgloss.AdaptiveColor
127+ MarkdownStrongColor color.Color
131− MarkdownHorizontalRuleColor lipgloss.AdaptiveColor
128+ MarkdownHorizontalRuleColor color.Color
132− MarkdownListItemColor lipgloss.AdaptiveColor
129+ MarkdownListItemColor color.Color
133− MarkdownListEnumerationColor lipgloss.AdaptiveColor
130+ MarkdownListEnumerationColor color.Color
134− MarkdownImageColor lipgloss.AdaptiveColor
131+ MarkdownImageColor color.Color
135− MarkdownImageTextColor lipgloss.AdaptiveColor
132+ MarkdownImageTextColor color.Color
136− MarkdownCodeBlockColor lipgloss.AdaptiveColor
133+ MarkdownCodeBlockColor color.Color
137
134
138 // Syntax highlighting colors
135 // Syntax highlighting colors
139− SyntaxCommentColor lipgloss.AdaptiveColor
136+ SyntaxCommentColor color.Color
140− SyntaxKeywordColor lipgloss.AdaptiveColor
137+ SyntaxKeywordColor color.Color
141− SyntaxFunctionColor lipgloss.AdaptiveColor
138+ SyntaxFunctionColor color.Color
142− SyntaxVariableColor lipgloss.AdaptiveColor
139+ SyntaxVariableColor color.Color
143− SyntaxStringColor lipgloss.AdaptiveColor
140+ SyntaxStringColor color.Color
144− SyntaxNumberColor lipgloss.AdaptiveColor
141+ SyntaxNumberColor color.Color
145− SyntaxTypeColor lipgloss.AdaptiveColor
142+ SyntaxTypeColor color.Color
146− SyntaxOperatorColor lipgloss.AdaptiveColor
143+ SyntaxOperatorColor color.Color
147− SyntaxPunctuationColor lipgloss.AdaptiveColor
144+ SyntaxPunctuationColor color.Color
148}
145}
149
146
150// Implement the Theme interface for BaseTheme
147// Implement the Theme interface for BaseTheme
151−func (t *BaseTheme) Primary() lipgloss.AdaptiveColor { return t.PrimaryColor }
148+func (t *BaseTheme) Primary() color.Color { return t.PrimaryColor }
152−func (t *BaseTheme) Secondary() lipgloss.AdaptiveColor { return t.SecondaryColor }
149+func (t *BaseTheme) Secondary() color.Color { return t.SecondaryColor }
153−func (t *BaseTheme) Accent() lipgloss.AdaptiveColor { return t.AccentColor }
150+func (t *BaseTheme) Accent() color.Color { return t.AccentColor }
154−
151+
155−func (t *BaseTheme) Error() lipgloss.AdaptiveColor { return t.ErrorColor }
152+func (t *BaseTheme) Error() color.Color { return t.ErrorColor }
156−func (t *BaseTheme) Warning() lipgloss.AdaptiveColor { return t.WarningColor }
153+func (t *BaseTheme) Warning() color.Color { return t.WarningColor }
157−func (t *BaseTheme) Success() lipgloss.AdaptiveColor { return t.SuccessColor }
154+func (t *BaseTheme) Success() color.Color { return t.SuccessColor }
158−func (t *BaseTheme) Info() lipgloss.AdaptiveColor { return t.InfoColor }
155+func (t *BaseTheme) Info() color.Color { return t.InfoColor }
159−
156+
160−func (t *BaseTheme) Text() lipgloss.AdaptiveColor { return t.TextColor }
157+func (t *BaseTheme) Text() color.Color { return t.TextColor }
161−func (t *BaseTheme) TextMuted() lipgloss.AdaptiveColor { return t.TextMutedColor }
158+func (t *BaseTheme) TextMuted() color.Color { return t.TextMutedColor }
162−func (t *BaseTheme) TextEmphasized() lipgloss.AdaptiveColor { return t.TextEmphasizedColor }
159+func (t *BaseTheme) TextEmphasized() color.Color { return t.TextEmphasizedColor }
163−
160+
164−func (t *BaseTheme) Background() lipgloss.AdaptiveColor { return t.BackgroundColor }
161+func (t *BaseTheme) Background() color.Color { return t.BackgroundColor }
165−func (t *BaseTheme) BackgroundSecondary() lipgloss.AdaptiveColor { return t.BackgroundSecondaryColor }
162+func (t *BaseTheme) BackgroundSecondary() color.Color { return t.BackgroundSecondaryColor }
166−func (t *BaseTheme) BackgroundDarker() lipgloss.AdaptiveColor { return t.BackgroundDarkerColor }
163+func (t *BaseTheme) BackgroundDarker() color.Color { return t.BackgroundDarkerColor }
167−
164+
168−func (t *BaseTheme) BorderNormal() lipgloss.AdaptiveColor { return t.BorderNormalColor }
165+func (t *BaseTheme) BorderNormal() color.Color { return t.BorderNormalColor }
169−func (t *BaseTheme) BorderFocused() lipgloss.AdaptiveColor { return t.BorderFocusedColor }
166+func (t *BaseTheme) BorderFocused() color.Color { return t.BorderFocusedColor }
170−func (t *BaseTheme) BorderDim() lipgloss.AdaptiveColor { return t.BorderDimColor }
167+func (t *BaseTheme) BorderDim() color.Color { return t.BorderDimColor }
171−
168+
172−func (t *BaseTheme) DiffAdded() lipgloss.AdaptiveColor { return t.DiffAddedColor }
169+func (t *BaseTheme) DiffAdded() color.Color { return t.DiffAddedColor }
173−func (t *BaseTheme) DiffRemoved() lipgloss.AdaptiveColor { return t.DiffRemovedColor }
170+func (t *BaseTheme) DiffRemoved() color.Color { return t.DiffRemovedColor }
174−func (t *BaseTheme) DiffContext() lipgloss.AdaptiveColor { return t.DiffContextColor }
171+func (t *BaseTheme) DiffContext() color.Color { return t.DiffContextColor }
175−func (t *BaseTheme) DiffHunkHeader() lipgloss.AdaptiveColor { return t.DiffHunkHeaderColor }
172+func (t *BaseTheme) DiffHunkHeader() color.Color { return t.DiffHunkHeaderColor }
176−func (t *BaseTheme) DiffHighlightAdded() lipgloss.AdaptiveColor { return t.DiffHighlightAddedColor }
173+func (t *BaseTheme) DiffHighlightAdded() color.Color { return t.DiffHighlightAddedColor }
177−func (t *BaseTheme) DiffHighlightRemoved() lipgloss.AdaptiveColor { return t.DiffHighlightRemovedColor }
174+func (t *BaseTheme) DiffHighlightRemoved() color.Color { return t.DiffHighlightRemovedColor }
178−func (t *BaseTheme) DiffAddedBg() lipgloss.AdaptiveColor { return t.DiffAddedBgColor }
175+func (t *BaseTheme) DiffAddedBg() color.Color { return t.DiffAddedBgColor }
179−func (t *BaseTheme) DiffRemovedBg() lipgloss.AdaptiveColor { return t.DiffRemovedBgColor }
176+func (t *BaseTheme) DiffRemovedBg() color.Color { return t.DiffRemovedBgColor }
180−func (t *BaseTheme) DiffContextBg() lipgloss.AdaptiveColor { return t.DiffContextBgColor }
177+func (t *BaseTheme) DiffContextBg() color.Color { return t.DiffContextBgColor }
181−func (t *BaseTheme) DiffLineNumber() lipgloss.AdaptiveColor { return t.DiffLineNumberColor }
178+func (t *BaseTheme) DiffLineNumber() color.Color { return t.DiffLineNumberColor }
182−func (t *BaseTheme) DiffAddedLineNumberBg() lipgloss.AdaptiveColor { return t.DiffAddedLineNumberBgColor }
179+func (t *BaseTheme) DiffAddedLineNumberBg() color.Color { return t.DiffAddedLineNumberBgColor }
183−func (t *BaseTheme) DiffRemovedLineNumberBg() lipgloss.AdaptiveColor { return t.DiffRemovedLineNumberBgColor }
180+func (t *BaseTheme) DiffRemovedLineNumberBg() color.Color { return t.DiffRemovedLineNumberBgColor }
184−
181+
185−func (t *BaseTheme) MarkdownText() lipgloss.AdaptiveColor { return t.MarkdownTextColor }
182+func (t *BaseTheme) MarkdownText() color.Color { return t.MarkdownTextColor }
186−func (t *BaseTheme) MarkdownHeading() lipgloss.AdaptiveColor { return t.MarkdownHeadingColor }
183+func (t *BaseTheme) MarkdownHeading() color.Color { return t.MarkdownHeadingColor }
187−func (t *BaseTheme) MarkdownLink() lipgloss.AdaptiveColor { return t.MarkdownLinkColor }
184+func (t *BaseTheme) MarkdownLink() color.Color { return t.MarkdownLinkColor }
188−func (t *BaseTheme) MarkdownLinkText() lipgloss.AdaptiveColor { return t.MarkdownLinkTextColor }
185+func (t *BaseTheme) MarkdownLinkText() color.Color { return t.MarkdownLinkTextColor }
189−func (t *BaseTheme) MarkdownCode() lipgloss.AdaptiveColor { return t.MarkdownCodeColor }
186+func (t *BaseTheme) MarkdownCode() color.Color { return t.MarkdownCodeColor }
190−func (t *BaseTheme) MarkdownBlockQuote() lipgloss.AdaptiveColor { return t.MarkdownBlockQuoteColor }
187+func (t *BaseTheme) MarkdownBlockQuote() color.Color { return t.MarkdownBlockQuoteColor }
191−func (t *BaseTheme) MarkdownEmph() lipgloss.AdaptiveColor { return t.MarkdownEmphColor }
188+func (t *BaseTheme) MarkdownEmph() color.Color { return t.MarkdownEmphColor }
192−func (t *BaseTheme) MarkdownStrong() lipgloss.AdaptiveColor { return t.MarkdownStrongColor }
189+func (t *BaseTheme) MarkdownStrong() color.Color { return t.MarkdownStrongColor }
193−func (t *BaseTheme) MarkdownHorizontalRule() lipgloss.AdaptiveColor { return t.MarkdownHorizontalRuleColor }
190+func (t *BaseTheme) MarkdownHorizontalRule() color.Color { return t.MarkdownHorizontalRuleColor }
194−func (t *BaseTheme) MarkdownListItem() lipgloss.AdaptiveColor { return t.MarkdownListItemColor }
191+func (t *BaseTheme) MarkdownListItem() color.Color { return t.MarkdownListItemColor }
195−func (t *BaseTheme) MarkdownListEnumeration() lipgloss.AdaptiveColor { return t.MarkdownListEnumerationColor }
192+func (t *BaseTheme) MarkdownListEnumeration() color.Color { return t.MarkdownListEnumerationColor }
196−func (t *BaseTheme) MarkdownImage() lipgloss.AdaptiveColor { return t.MarkdownImageColor }
193+func (t *BaseTheme) MarkdownImage() color.Color { return t.MarkdownImageColor }
197−func (t *BaseTheme) MarkdownImageText() lipgloss.AdaptiveColor { return t.MarkdownImageTextColor }
194+func (t *BaseTheme) MarkdownImageText() color.Color { return t.MarkdownImageTextColor }
198−func (t *BaseTheme) MarkdownCodeBlock() lipgloss.AdaptiveColor { return t.MarkdownCodeBlockColor }
195+func (t *BaseTheme) MarkdownCodeBlock() color.Color { return t.MarkdownCodeBlockColor }
199−
196+
200−func (t *BaseTheme) SyntaxComment() lipgloss.AdaptiveColor { return t.SyntaxCommentColor }
197+func (t *BaseTheme) SyntaxComment() color.Color { return t.SyntaxCommentColor }
201−func (t *BaseTheme) SyntaxKeyword() lipgloss.AdaptiveColor { return t.SyntaxKeywordColor }
198+func (t *BaseTheme) SyntaxKeyword() color.Color { return t.SyntaxKeywordColor }
202−func (t *BaseTheme) SyntaxFunction() lipgloss.AdaptiveColor { return t.SyntaxFunctionColor }
199+func (t *BaseTheme) SyntaxFunction() color.Color { return t.SyntaxFunctionColor }
203−func (t *BaseTheme) SyntaxVariable() lipgloss.AdaptiveColor { return t.SyntaxVariableColor }
200+func (t *BaseTheme) SyntaxVariable() color.Color { return t.SyntaxVariableColor }
204−func (t *BaseTheme) SyntaxString() lipgloss.AdaptiveColor { return t.SyntaxStringColor }
201+func (t *BaseTheme) SyntaxString() color.Color { return t.SyntaxStringColor }
205−func (t *BaseTheme) SyntaxNumber() lipgloss.AdaptiveColor { return t.SyntaxNumberColor }
202+func (t *BaseTheme) SyntaxNumber() color.Color { return t.SyntaxNumberColor }
206−func (t *BaseTheme) SyntaxType() lipgloss.AdaptiveColor { return t.SyntaxTypeColor }
203+func (t *BaseTheme) SyntaxType() color.Color { return t.SyntaxTypeColor }
207−func (t *BaseTheme) SyntaxOperator() lipgloss.AdaptiveColor { return t.SyntaxOperatorColor }
204+func (t *BaseTheme) SyntaxOperator() color.Color { return t.SyntaxOperatorColor }
208−func (t *BaseTheme) SyntaxPunctuation() lipgloss.AdaptiveColor { return t.SyntaxPunctuationColor }
205+func (t *BaseTheme) SyntaxPunctuation() color.Color { return t.SyntaxPunctuationColor }
internal/tui/theme/tokyonight.go+128−206
@@ -1,7 +1,7 @@
1package theme
1package theme
2
2
3import (
3import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
5)
5)
6
6
7// TokyoNightTheme implements the Theme interface with Tokyo Night colors.
7// TokyoNightTheme implements the Theme interface with Tokyo Night colors.
@@ -28,6 +28,80 @@ func NewTokyoNightTheme() *TokyoNightTheme {
28 darkPurple := "#c099ff"
28 darkPurple := "#c099ff"
29 darkBorder := "#3b4261"
29 darkBorder := "#3b4261"
30
30
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 {
31 // Light mode colors (Tokyo Night Day)
105 // Light mode colors (Tokyo Night Day)
32 lightBackground := "#e1e2e7"
106 lightBackground := "#e1e2e7"
33 lightCurrentLine := "#d5d6db"
107 lightCurrentLine := "#d5d6db"
@@ -46,229 +120,77 @@ func NewTokyoNightTheme() *TokyoNightTheme {
46 theme := &TokyoNightTheme{}
120 theme := &TokyoNightTheme{}
47
121
48 // Base colors
122 // Base colors
49− theme.PrimaryColor = lipgloss.AdaptiveColor{
123+ theme.PrimaryColor = lipgloss.Color(lightBlue)
50− Dark: darkBlue,
51− Light: lightBlue,
52− }
53− theme.SecondaryColor = lipgloss.AdaptiveColor{
124+ theme.SecondaryColor = lipgloss.Color(lightPurple)
54− Dark: darkPurple,
55− Light: lightPurple,
56− }
57− theme.AccentColor = lipgloss.AdaptiveColor{
125+ theme.AccentColor = lipgloss.Color(lightOrange)
58− Dark: darkOrange,
59− Light: lightOrange,
60− }
61
126
62 // Status colors
127 // Status colors
63− theme.ErrorColor = lipgloss.AdaptiveColor{
128+ theme.ErrorColor = lipgloss.Color(lightRed)
64− Dark: darkRed,
65− Light: lightRed,
66− }
67− theme.WarningColor = lipgloss.AdaptiveColor{
129+ theme.WarningColor = lipgloss.Color(lightOrange)
68− Dark: darkOrange,
69− Light: lightOrange,
70− }
71− theme.SuccessColor = lipgloss.AdaptiveColor{
130+ theme.SuccessColor = lipgloss.Color(lightGreen)
72− Dark: darkGreen,
73− Light: lightGreen,
74− }
75− theme.InfoColor = lipgloss.AdaptiveColor{
131+ theme.InfoColor = lipgloss.Color(lightBlue)
76− Dark: darkBlue,
77− Light: lightBlue,
78− }
79
132
80 // Text colors
133 // Text colors
81− theme.TextColor = lipgloss.AdaptiveColor{
134+ theme.TextColor = lipgloss.Color(lightForeground)
82− Dark: darkForeground,
83− Light: lightForeground,
84− }
85− theme.TextMutedColor = lipgloss.AdaptiveColor{
135+ theme.TextMutedColor = lipgloss.Color(lightComment)
86− Dark: darkComment,
87− Light: lightComment,
88− }
89− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
136+ theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
90− Dark: darkYellow,
91− Light: lightYellow,
92− }
93
137
94 // Background colors
138 // Background colors
95− theme.BackgroundColor = lipgloss.AdaptiveColor{
139+ theme.BackgroundColor = lipgloss.Color(lightBackground)
96− Dark: darkBackground,
97− Light: lightBackground,
98− }
99− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
140+ theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
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
141+ theme.BackgroundDarkerColor = lipgloss.Color("#f0f0f5") // Slightly lighter than background
106− }
107
142
108 // Border colors
143 // Border colors
109− theme.BorderNormalColor = lipgloss.AdaptiveColor{
144+ theme.BorderNormalColor = lipgloss.Color(lightBorder)
110− Dark: darkBorder,
111− Light: lightBorder,
112− }
113− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
145+ theme.BorderFocusedColor = lipgloss.Color(lightBlue)
114− Dark: darkBlue,
115− Light: lightBlue,
116− }
117− theme.BorderDimColor = lipgloss.AdaptiveColor{
146+ theme.BorderDimColor = lipgloss.Color(lightSelection)
118− Dark: darkSelection,
119− Light: lightSelection,
120− }
121
147
122 // Diff view colors
148 // Diff view colors
123− theme.DiffAddedColor = lipgloss.AdaptiveColor{
149+ theme.DiffAddedColor = lipgloss.Color("#1e725c")
124− Dark: "#4fd6be", // teal from palette
125− Light: "#1e725c",
126− }
127− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
150+ theme.DiffRemovedColor = lipgloss.Color("#c53b53")
128− Dark: "#c53b53", // red1 from palette
129− Light: "#c53b53",
130− }
131− theme.DiffContextColor = lipgloss.AdaptiveColor{
151+ theme.DiffContextColor = lipgloss.Color("#7086b5")
132− Dark: "#828bb8", // fg_dark from palette
133− Light: "#7086b5",
134− }
135− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
152+ theme.DiffHunkHeaderColor = lipgloss.Color("#7086b5")
136− Dark: "#828bb8", // fg_dark from palette
137− Light: "#7086b5",
138− }
139− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
153+ theme.DiffHighlightAddedColor = lipgloss.Color("#4db380")
140− Dark: "#b8db87", // git.add from palette
141− Light: "#4db380",
142− }
143− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
154+ theme.DiffHighlightRemovedColor = lipgloss.Color("#f52a65")
144− Dark: "#e26a75", // git.delete from palette
145− Light: "#f52a65",
146− }
147− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
155+ theme.DiffAddedBgColor = lipgloss.Color("#d5e5d5")
148− Dark: "#20303b",
149− Light: "#d5e5d5",
150− }
151− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
156+ theme.DiffRemovedBgColor = lipgloss.Color("#f7d8db")
152− Dark: "#37222c",
153− Light: "#f7d8db",
154− }
155− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
157+ theme.DiffContextBgColor = lipgloss.Color(lightBackground)
156− Dark: darkBackground,
157− Light: lightBackground,
158− }
159− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
158+ theme.DiffLineNumberColor = lipgloss.Color("#848cb5")
160− Dark: "#545c7e", // dark3 from palette
161− Light: "#848cb5",
162− }
163− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
159+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#c5d5c5")
164− Dark: "#1b2b34",
165− Light: "#c5d5c5",
166− }
167− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
160+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#e7c8cb")
168− Dark: "#2d1f26",
169− Light: "#e7c8cb",
170− }
171
161
172 // Markdown colors
162 // Markdown colors
173− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
163+ theme.MarkdownTextColor = lipgloss.Color(lightForeground)
174− Dark: darkForeground,
175− Light: lightForeground,
176− }
177− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
164+ theme.MarkdownHeadingColor = lipgloss.Color(lightPurple)
178− Dark: darkPurple,
179− Light: lightPurple,
180− }
181− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
165+ theme.MarkdownLinkColor = lipgloss.Color(lightBlue)
182− Dark: darkBlue,
183− Light: lightBlue,
184− }
185− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
166+ theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
186− Dark: darkCyan,
187− Light: lightCyan,
188− }
189− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
167+ theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
190− Dark: darkGreen,
191− Light: lightGreen,
192− }
193− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
168+ theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
194− Dark: darkYellow,
195− Light: lightYellow,
196− }
197− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
169+ theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
198− Dark: darkYellow,
199− Light: lightYellow,
200− }
201− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
170+ theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
202− Dark: darkOrange,
203− Light: lightOrange,
204− }
205− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
171+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
206− Dark: darkComment,
207− Light: lightComment,
208− }
209− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
172+ theme.MarkdownListItemColor = lipgloss.Color(lightBlue)
210− Dark: darkBlue,
211− Light: lightBlue,
212− }
213− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
173+ theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
214− Dark: darkCyan,
215− Light: lightCyan,
216− }
217− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
174+ theme.MarkdownImageColor = lipgloss.Color(lightBlue)
218− Dark: darkBlue,
219− Light: lightBlue,
220− }
221− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
175+ theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
222− Dark: darkCyan,
223− Light: lightCyan,
224− }
225− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
176+ theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
226− Dark: darkForeground,
227− Light: lightForeground,
228− }
229
177
230 // Syntax highlighting colors
178 // Syntax highlighting colors
231− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
179+ theme.SyntaxCommentColor = lipgloss.Color(lightComment)
232− Dark: darkComment,
233− Light: lightComment,
234− }
235− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
180+ theme.SyntaxKeywordColor = lipgloss.Color(lightPurple)
236− Dark: darkPurple,
237− Light: lightPurple,
238− }
239− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
181+ theme.SyntaxFunctionColor = lipgloss.Color(lightBlue)
240− Dark: darkBlue,
241− Light: lightBlue,
242− }
243− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
182+ theme.SyntaxVariableColor = lipgloss.Color(lightRed)
244− Dark: darkRed,
245− Light: lightRed,
246− }
247− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
183+ theme.SyntaxStringColor = lipgloss.Color(lightGreen)
248− Dark: darkGreen,
249− Light: lightGreen,
250− }
251− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
184+ theme.SyntaxNumberColor = lipgloss.Color(lightOrange)
252− Dark: darkOrange,
253− Light: lightOrange,
254− }
255− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
185+ theme.SyntaxTypeColor = lipgloss.Color(lightYellow)
256− Dark: darkYellow,
257− Light: lightYellow,
258− }
259− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
186+ theme.SyntaxOperatorColor = lipgloss.Color(lightCyan)
260− Dark: darkCyan,
261− Light: lightCyan,
262− }
263− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
187+ theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
264− Dark: darkForeground,
265− Light: lightForeground,
266− }
267
188
268 return theme
189 return theme
269}
190}
270
191
271func init() {
192func init() {
272− // Register the Tokyo Night theme with the theme manager
193+ // Register the Tokyo Night themes with the theme manager
273 RegisterTheme("tokyonight", NewTokyoNightTheme())
194 RegisterTheme("tokyonight", NewTokyoNightTheme())
195+ RegisterTheme("tokyonight-day", NewTokyoNightDayTheme())
274}
196}
internal/tui/theme/tron.go+128−206
@@ -1,7 +1,7 @@
1package theme
1package theme
2
2
3import (
3import (
4− "github.com/charmbracelet/lipgloss"
4+ "github.com/charmbracelet/lipgloss/v2"
5)
5)
6
6
7// TronTheme implements the Theme interface with Tron-inspired colors.
7// TronTheme implements the Theme interface with Tron-inspired colors.
@@ -29,6 +29,80 @@ func NewTronTheme() *TronTheme {
29 darkGreen := "#00ff8f"
29 darkGreen := "#00ff8f"
30 darkBorder := "#1a2633"
30 darkBorder := "#1a2633"
31
31
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 {
32 // Light mode approximation
106 // Light mode approximation
33 lightBackground := "#f0f8ff"
107 lightBackground := "#f0f8ff"
34 lightCurrentLine := "#e0f0ff"
108 lightCurrentLine := "#e0f0ff"
@@ -48,229 +122,77 @@ func NewTronTheme() *TronTheme {
48 theme := &TronTheme{}
122 theme := &TronTheme{}
49
123
50 // Base colors
124 // Base colors
51− theme.PrimaryColor = lipgloss.AdaptiveColor{
125+ theme.PrimaryColor = lipgloss.Color(lightCyan)
52− Dark: darkCyan,
53− Light: lightCyan,
54− }
55− theme.SecondaryColor = lipgloss.AdaptiveColor{
126+ theme.SecondaryColor = lipgloss.Color(lightBlue)
56− Dark: darkBlue,
57− Light: lightBlue,
58− }
59− theme.AccentColor = lipgloss.AdaptiveColor{
127+ theme.AccentColor = lipgloss.Color(lightOrange)
60− Dark: darkOrange,
61− Light: lightOrange,
62− }
63
128
64 // Status colors
129 // Status colors
65− theme.ErrorColor = lipgloss.AdaptiveColor{
130+ theme.ErrorColor = lipgloss.Color(lightRed)
66− Dark: darkRed,
67− Light: lightRed,
68− }
69− theme.WarningColor = lipgloss.AdaptiveColor{
131+ theme.WarningColor = lipgloss.Color(lightOrange)
70− Dark: darkOrange,
71− Light: lightOrange,
72− }
73− theme.SuccessColor = lipgloss.AdaptiveColor{
132+ theme.SuccessColor = lipgloss.Color(lightGreen)
74− Dark: darkGreen,
75− Light: lightGreen,
76− }
77− theme.InfoColor = lipgloss.AdaptiveColor{
133+ theme.InfoColor = lipgloss.Color(lightCyan)
78− Dark: darkCyan,
79− Light: lightCyan,
80− }
81
134
82 // Text colors
135 // Text colors
83− theme.TextColor = lipgloss.AdaptiveColor{
136+ theme.TextColor = lipgloss.Color(lightForeground)
84− Dark: darkForeground,
85− Light: lightForeground,
86− }
87− theme.TextMutedColor = lipgloss.AdaptiveColor{
137+ theme.TextMutedColor = lipgloss.Color(lightComment)
88− Dark: darkComment,
89− Light: lightComment,
90− }
91− theme.TextEmphasizedColor = lipgloss.AdaptiveColor{
138+ theme.TextEmphasizedColor = lipgloss.Color(lightYellow)
92− Dark: darkYellow,
93− Light: lightYellow,
94− }
95
139
96 // Background colors
140 // Background colors
97− theme.BackgroundColor = lipgloss.AdaptiveColor{
141+ theme.BackgroundColor = lipgloss.Color(lightBackground)
98− Dark: darkBackground,
99− Light: lightBackground,
100− }
101− theme.BackgroundSecondaryColor = lipgloss.AdaptiveColor{
142+ theme.BackgroundSecondaryColor = lipgloss.Color(lightCurrentLine)
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
143+ theme.BackgroundDarkerColor = lipgloss.Color("#ffffff") // Slightly lighter than background
108− }
109
144
110 // Border colors
145 // Border colors
111− theme.BorderNormalColor = lipgloss.AdaptiveColor{
146+ theme.BorderNormalColor = lipgloss.Color(lightBorder)
112− Dark: darkBorder,
113− Light: lightBorder,
114− }
115− theme.BorderFocusedColor = lipgloss.AdaptiveColor{
147+ theme.BorderFocusedColor = lipgloss.Color(lightCyan)
116− Dark: darkCyan,
117− Light: lightCyan,
118− }
119− theme.BorderDimColor = lipgloss.AdaptiveColor{
148+ theme.BorderDimColor = lipgloss.Color(lightSelection)
120− Dark: darkSelection,
121− Light: lightSelection,
122− }
123
149
124 // Diff view colors
150 // Diff view colors
125− theme.DiffAddedColor = lipgloss.AdaptiveColor{
151+ theme.DiffAddedColor = lipgloss.Color(lightGreen)
126− Dark: darkGreen,
127− Light: lightGreen,
128− }
129− theme.DiffRemovedColor = lipgloss.AdaptiveColor{
152+ theme.DiffRemovedColor = lipgloss.Color(lightRed)
130− Dark: darkRed,
131− Light: lightRed,
132− }
133− theme.DiffContextColor = lipgloss.AdaptiveColor{
153+ theme.DiffContextColor = lipgloss.Color(lightComment)
134− Dark: darkComment,
135− Light: lightComment,
136− }
137− theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
154+ theme.DiffHunkHeaderColor = lipgloss.Color(lightBlue)
138− Dark: darkBlue,
139− Light: lightBlue,
140− }
141− theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
155+ theme.DiffHighlightAddedColor = lipgloss.Color("#a5d6a7")
142− Dark: "#00ff8f",
143− Light: "#a5d6a7",
144− }
145− theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
156+ theme.DiffHighlightRemovedColor = lipgloss.Color("#ef9a9a")
146− Dark: "#ff3333",
147− Light: "#ef9a9a",
148− }
149− theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
157+ theme.DiffAddedBgColor = lipgloss.Color("#e8f5e9")
150− Dark: "#0a2a1a",
151− Light: "#e8f5e9",
152− }
153− theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
158+ theme.DiffRemovedBgColor = lipgloss.Color("#ffebee")
154− Dark: "#2a0a0a",
155− Light: "#ffebee",
156− }
157− theme.DiffContextBgColor = lipgloss.AdaptiveColor{
159+ theme.DiffContextBgColor = lipgloss.Color(lightBackground)
158− Dark: darkBackground,
159− Light: lightBackground,
160− }
161− theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
160+ theme.DiffLineNumberColor = lipgloss.Color(lightComment)
162− Dark: darkComment,
163− Light: lightComment,
164− }
165− theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
161+ theme.DiffAddedLineNumberBgColor = lipgloss.Color("#c8e6c9")
166− Dark: "#082015",
167− Light: "#c8e6c9",
168− }
169− theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
162+ theme.DiffRemovedLineNumberBgColor = lipgloss.Color("#ffcdd2")
170− Dark: "#200808",
171− Light: "#ffcdd2",
172− }
173
163
174 // Markdown colors
164 // Markdown colors
175− theme.MarkdownTextColor = lipgloss.AdaptiveColor{
165+ theme.MarkdownTextColor = lipgloss.Color(lightForeground)
176− Dark: darkForeground,
177− Light: lightForeground,
178− }
179− theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
166+ theme.MarkdownHeadingColor = lipgloss.Color(lightCyan)
180− Dark: darkCyan,
181− Light: lightCyan,
182− }
183− theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
167+ theme.MarkdownLinkColor = lipgloss.Color(lightBlue)
184− Dark: darkBlue,
185− Light: lightBlue,
186− }
187− theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
168+ theme.MarkdownLinkTextColor = lipgloss.Color(lightCyan)
188− Dark: darkCyan,
189− Light: lightCyan,
190− }
191− theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
169+ theme.MarkdownCodeColor = lipgloss.Color(lightGreen)
192− Dark: darkGreen,
193− Light: lightGreen,
194− }
195− theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
170+ theme.MarkdownBlockQuoteColor = lipgloss.Color(lightYellow)
196− Dark: darkYellow,
197− Light: lightYellow,
198− }
199− theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
171+ theme.MarkdownEmphColor = lipgloss.Color(lightYellow)
200− Dark: darkYellow,
201− Light: lightYellow,
202− }
203− theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
172+ theme.MarkdownStrongColor = lipgloss.Color(lightOrange)
204− Dark: darkOrange,
205− Light: lightOrange,
206− }
207− theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
173+ theme.MarkdownHorizontalRuleColor = lipgloss.Color(lightComment)
208− Dark: darkComment,
209− Light: lightComment,
210− }
211− theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
174+ theme.MarkdownListItemColor = lipgloss.Color(lightBlue)
212− Dark: darkBlue,
213− Light: lightBlue,
214− }
215− theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
175+ theme.MarkdownListEnumerationColor = lipgloss.Color(lightCyan)
216− Dark: darkCyan,
217− Light: lightCyan,
218− }
219− theme.MarkdownImageColor = lipgloss.AdaptiveColor{
176+ theme.MarkdownImageColor = lipgloss.Color(lightBlue)
220− Dark: darkBlue,
221− Light: lightBlue,
222− }
223− theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
177+ theme.MarkdownImageTextColor = lipgloss.Color(lightCyan)
224− Dark: darkCyan,
225− Light: lightCyan,
226− }
227− theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
178+ theme.MarkdownCodeBlockColor = lipgloss.Color(lightForeground)
228− Dark: darkForeground,
229− Light: lightForeground,
230− }
231
179
232 // Syntax highlighting colors
180 // Syntax highlighting colors
233− theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
181+ theme.SyntaxCommentColor = lipgloss.Color(lightComment)
234− Dark: darkComment,
235− Light: lightComment,
236− }
237− theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
182+ theme.SyntaxKeywordColor = lipgloss.Color(lightCyan)
238− Dark: darkCyan,
239− Light: lightCyan,
240− }
241− theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
183+ theme.SyntaxFunctionColor = lipgloss.Color(lightGreen)
242− Dark: darkGreen,
243− Light: lightGreen,
244− }
245− theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
184+ theme.SyntaxVariableColor = lipgloss.Color(lightOrange)
246− Dark: darkOrange,
247− Light: lightOrange,
248− }
249− theme.SyntaxStringColor = lipgloss.AdaptiveColor{
185+ theme.SyntaxStringColor = lipgloss.Color(lightYellow)
250− Dark: darkYellow,
251− Light: lightYellow,
252− }
253− theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
186+ theme.SyntaxNumberColor = lipgloss.Color(lightBlue)
254− Dark: darkBlue,
255− Light: lightBlue,
256− }
257− theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
187+ theme.SyntaxTypeColor = lipgloss.Color(lightPurple)
258− Dark: darkPurple,
259− Light: lightPurple,
260− }
261− theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
188+ theme.SyntaxOperatorColor = lipgloss.Color(lightPink)
262− Dark: darkPink,
263− Light: lightPink,
264− }
265− theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
189+ theme.SyntaxPunctuationColor = lipgloss.Color(lightForeground)
266− Dark: darkForeground,
267− Light: lightForeground,
268− }
269
190
270 return theme
191 return theme
271}
192}
272
193
273func init() {
194func init() {
274− // Register the Tron theme with the theme manager
195+ // Register the Tron themes with the theme manager
275 RegisterTheme("tron", NewTronTheme())
196 RegisterTheme("tron", NewTronTheme())
197+ RegisterTheme("tron-light", NewTronLightTheme())
276}
198}
internal/tui/tui.go+16−10
@@ -5,9 +5,9 @@ import (
5 "fmt"
5 "fmt"
6 "strings"
6 "strings"
7
7
8− "github.com/charmbracelet/bubbles/key"
8+ "github.com/charmbracelet/bubbles/v2/key"
9− tea "github.com/charmbracelet/bubbletea"
9+ tea "github.com/charmbracelet/bubbletea/v2"
10− "github.com/charmbracelet/lipgloss"
10+ "github.com/charmbracelet/lipgloss/v2"
11 "github.com/opencode-ai/opencode/internal/app"
11 "github.com/opencode-ai/opencode/internal/app"
12 "github.com/opencode-ai/opencode/internal/config"
12 "github.com/opencode-ai/opencode/internal/config"
13 "github.com/opencode-ai/opencode/internal/llm/agent"
13 "github.com/opencode-ai/opencode/internal/llm/agent"
@@ -99,7 +99,7 @@ type appModel struct {
99 width, height int
99 width, height int
100 currentPage page.PageID
100 currentPage page.PageID
101 previousPage page.PageID
101 previousPage page.PageID
102− pages map[page.PageID]tea.Model
102+ pages map[page.PageID]util.Model
103 loadedPages map[page.PageID]bool
103 loadedPages map[page.PageID]bool
104 status core.StatusCmp
104 status core.StatusCmp
105 app *app.App
105 app *app.App
@@ -143,6 +143,8 @@ type appModel struct {
143func (a appModel) Init() tea.Cmd {
143func (a appModel) Init() tea.Cmd {
144 var cmds []tea.Cmd
144 var cmds []tea.Cmd
145 cmd := a.pages[a.currentPage].Init()
145 cmd := a.pages[a.currentPage].Init()
146+ t := theme.CurrentTheme()
147+ cmds = append(cmds, tea.SetBackgroundColor(t.Background()))
146 a.loadedPages[a.currentPage] = true
148 a.loadedPages[a.currentPage] = true
147 cmds = append(cmds, cmd)
149 cmds = append(cmds, cmd)
148 cmd = a.status.Init()
150 cmd = a.status.Init()
@@ -189,7 +191,8 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
189
191
190 s, _ := a.status.Update(msg)
192 s, _ := a.status.Update(msg)
191 a.status = s.(core.StatusCmp)
193 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)
193 cmds = append(cmds, cmd)
196 cmds = append(cmds, cmd)
194
197
195 prm, permCmd := a.permissions.Update(msg)
198 prm, permCmd := a.permissions.Update(msg)
@@ -348,9 +351,11 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
348 return a, nil
351 return a, nil
349
352
350 case dialog.ThemeChangedMsg:
353 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)
352 a.showThemeDialog = false
356 a.showThemeDialog = false
357+ t := theme.CurrentTheme()
353− return a, tea.Batch(cmd, util.ReportInfo("Theme changed to: "+msg.ThemeName))
358+ return a, tea.Batch(cmd, util.ReportInfo("Theme changed to: "+msg.ThemeName), tea.SetBackgroundColor(t.Background()))
354
359
355 case dialog.CloseModelDialogMsg:
360 case dialog.CloseModelDialogMsg:
356 a.showModelDialog = false
361 a.showModelDialog = false
@@ -427,7 +432,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
427 // If submitted, replace all named arguments and run the command
432 // If submitted, replace all named arguments and run the command
428 if msg.Submit {
433 if msg.Submit {
429 content := msg.Content
434 content := msg.Content
430−
435+
431 // Replace each named argument with its value
436 // Replace each named argument with its value
432 for name, value := range msg.Args {
437 for name, value := range msg.Args {
433 placeholder := "$" + name
438 placeholder := "$" + name
@@ -658,7 +663,8 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
658
663
659 s, _ := a.status.Update(msg)
664 s, _ := a.status.Update(msg)
660 a.status = s.(core.StatusCmp)
665 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)
662 cmds = append(cmds, cmd)
668 cmds = append(cmds, cmd)
663 return a, tea.Batch(cmds...)
669 return a, tea.Batch(cmds...)
664}
670}
@@ -914,7 +920,7 @@ func New(app *app.App) tea.Model {
914 themeDialog: dialog.NewThemeDialogCmp(),
920 themeDialog: dialog.NewThemeDialogCmp(),
915 app: app,
921 app: app,
916 commands: []dialog.Command{},
922 commands: []dialog.Command{},
917− pages: map[page.PageID]tea.Model{
923+ pages: map[page.PageID]util.Model{
918 page.ChatPage: page.NewChatPage(app),
924 page.ChatPage: page.NewChatPage(app),
919 page.LogsPage: page.NewLogsPage(),
925 page.LogsPage: page.NewLogsPage(),
920 },
926 },
internal/tui/util/util.go+6−1
@@ -3,9 +3,14 @@ package util
3import (
3import (
4 "time"
4 "time"
5
5
6− tea "github.com/charmbracelet/bubbletea"
6+ tea "github.com/charmbracelet/bubbletea/v2"
7)
7)
8
8
9+type Model interface {
10+ tea.Model
11+ tea.ViewModel
12+}
13+
9func CmdHandler(msg tea.Msg) tea.Cmd {
14func CmdHandler(msg tea.Msg) tea.Cmd {
10 return func() tea.Msg {
15 return func() tea.Msg {
11 return msg
16 return msg