summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authoradamdottv <[email protected]>2025-06-12 05:35:40 -0500
committeradamdottv <[email protected]>2025-06-12 16:00:24 -0500
commitcce2e4ad754479917fc8f6f24c1421cf19c04573 (patch)
tree62c0ec32358932a468af73b44fd28e7de7859bbe
parenta1ce35c208bf9ebca37f722e845035bd7fd5e801 (diff)
downloadopencode-cce2e4ad754479917fc8f6f24c1421cf19c04573.tar.gz
opencode-cce2e4ad754479917fc8f6f24c1421cf19c04573.zip
wip: refactoring tui
-rw-r--r--packages/tui/cmd/opencode/main.go4
-rw-r--r--packages/tui/go.mod22
-rw-r--r--packages/tui/go.sum44
-rw-r--r--packages/tui/internal/app/app.go2
-rw-r--r--packages/tui/internal/components/chat/editor.go61
-rw-r--r--packages/tui/internal/components/chat/message.go49
-rw-r--r--packages/tui/internal/components/chat/messages.go116
-rw-r--r--packages/tui/internal/components/core/status.go129
-rw-r--r--packages/tui/internal/components/dialog/arguments.go41
-rw-r--r--packages/tui/internal/components/dialog/commands.go22
-rw-r--r--packages/tui/internal/components/dialog/complete.go12
-rw-r--r--packages/tui/internal/components/dialog/custom_commands.go2
-rw-r--r--packages/tui/internal/components/dialog/filepicker.go49
-rw-r--r--packages/tui/internal/components/dialog/help.go31
-rw-r--r--packages/tui/internal/components/dialog/init.go6
-rw-r--r--packages/tui/internal/components/dialog/models.go34
-rw-r--r--packages/tui/internal/components/dialog/permission.go60
-rw-r--r--packages/tui/internal/components/dialog/quit.go20
-rw-r--r--packages/tui/internal/components/dialog/session.go24
-rw-r--r--packages/tui/internal/components/dialog/theme.go20
-rw-r--r--packages/tui/internal/components/dialog/tools.go40
-rw-r--r--packages/tui/internal/components/diff/diff.go20
-rw-r--r--packages/tui/internal/components/qr/qr.go2
-rw-r--r--packages/tui/internal/components/util/simple-list.go8
-rw-r--r--packages/tui/internal/image/images.go17
-rw-r--r--packages/tui/internal/layout/container.go19
-rw-r--r--packages/tui/internal/layout/flex.go14
-rw-r--r--packages/tui/internal/layout/layout.go4
-rw-r--r--packages/tui/internal/layout/overlay.go4
-rw-r--r--packages/tui/internal/page/chat.go8
-rw-r--r--packages/tui/internal/styles/background.go124
-rw-r--r--packages/tui/internal/styles/markdown.go175
-rw-r--r--packages/tui/internal/styles/styles.go33
-rw-r--r--packages/tui/internal/theme/ayu.go276
-rw-r--r--packages/tui/internal/theme/catppuccin.go244
-rw-r--r--packages/tui/internal/theme/dracula.go270
-rw-r--r--packages/tui/internal/theme/flexoki.go278
-rw-r--r--packages/tui/internal/theme/gruvbox.go298
-rw-r--r--packages/tui/internal/theme/manager.go5
-rw-r--r--packages/tui/internal/theme/monokai.go269
-rw-r--r--packages/tui/internal/theme/onedark.go270
-rw-r--r--packages/tui/internal/theme/opencode.go303
-rw-r--r--packages/tui/internal/theme/theme.go359
-rw-r--r--packages/tui/internal/theme/tokyonight.go303
-rw-r--r--packages/tui/internal/theme/tron.go272
-rw-r--r--packages/tui/internal/tui/tui.go73
-rw-r--r--packages/tui/internal/util/util.go2
47 files changed, 1025 insertions, 3413 deletions
diff --git a/packages/tui/cmd/opencode/main.go b/packages/tui/cmd/opencode/main.go
index 27e797e8b..06c4554a3 100644
--- a/packages/tui/cmd/opencode/main.go
+++ b/packages/tui/cmd/opencode/main.go
@@ -9,7 +9,7 @@ import (
"sync"
"time"
- tea "github.com/charmbracelet/bubbletea"
+ tea "github.com/charmbracelet/bubbletea/v2"
zone "github.com/lrstanley/bubblezone"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/pubsub"
@@ -65,6 +65,8 @@ func main() {
zone.NewGlobal()
program := tea.NewProgram(
tui.NewModel(app_),
+ // tea.WithMouseCellMotion(),
+ tea.WithKeyboardEnhancements(),
tea.WithAltScreen(),
)
diff --git a/packages/tui/go.mod b/packages/tui/go.mod
index 76d2d7bd5..6dddd8094 100644
--- a/packages/tui/go.mod
+++ b/packages/tui/go.mod
@@ -4,13 +4,12 @@ go 1.24.0
require (
github.com/BurntSushi/toml v1.5.0
- github.com/alecthomas/chroma/v2 v2.15.0
+ github.com/alecthomas/chroma/v2 v2.18.0
github.com/bmatcuk/doublestar/v4 v4.8.1
- github.com/catppuccin/go v0.3.0
- github.com/charmbracelet/bubbles v0.21.0
- github.com/charmbracelet/bubbletea v1.3.4
- github.com/charmbracelet/glamour v0.9.1
- github.com/charmbracelet/lipgloss v1.1.0
+ github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1
+ github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.3
+ github.com/charmbracelet/glamour v0.10.0
+ github.com/charmbracelet/lipgloss/v2 v2.0.0-beta1
github.com/charmbracelet/x/ansi v0.8.0
github.com/lithammer/fuzzysearch v1.1.8
github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231
@@ -28,6 +27,11 @@ require (
dario.cat/mergo v1.0.2 // indirect
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/atombender/go-jsonschema v0.20.0 // indirect
+ github.com/charmbracelet/bubbletea v1.3.4 // indirect
+ github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 // indirect
+ github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf // indirect
+ github.com/charmbracelet/x/input v0.3.5-0.20250424101541-abb4d9a9b197 // indirect
+ github.com/charmbracelet/x/windows v0.2.1 // indirect
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/getkin/kin-openapi v0.127.0 // indirect
@@ -57,11 +61,11 @@ require (
github.com/atotto/clipboard v0.1.4
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
- github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
- github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
+ github.com/charmbracelet/colorprofile v0.3.1 // indirect
+ github.com/charmbracelet/x/cellbuf v0.0.14-0.20250501183327-ad3bc78c6a81 // indirect
github.com/charmbracelet/x/term v0.2.1 // indirect
github.com/disintegration/imaging v1.6.2
- github.com/dlclark/regexp2 v1.11.4 // indirect
+ github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/gorilla/css v1.0.1 // indirect
diff --git a/packages/tui/go.sum b/packages/tui/go.sum
index 03689fe8c..4021e9bf4 100644
--- a/packages/tui/go.sum
+++ b/packages/tui/go.sum
@@ -7,8 +7,8 @@ github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
-github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc=
-github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio=
+github.com/alecthomas/chroma/v2 v2.18.0 h1:6h53Q4hW83SuF+jcsp7CVhLsMozzvQvO8HBbKQW+gn4=
+github.com/alecthomas/chroma/v2 v2.18.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
@@ -26,26 +26,34 @@ github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd3
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
-github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY=
-github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
-github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
-github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
+github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1 h1:swACzss0FjnyPz1enfX56GKkLiuKg5FlyVmOLIlU2kE=
+github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1/go.mod h1:6HamsBKWqEC/FVHuQMHgQL+knPyvHH55HwJDHl/adMw=
github.com/charmbracelet/bubbletea v1.3.4 h1:kCg7B+jSCFPLYRA52SDZjr51kG/fMUEoPoZrkaDHyoI=
github.com/charmbracelet/bubbletea v1.3.4/go.mod h1:dtcUCyCGEX3g9tosuYiut3MXgY/Jsv9nKVdibKKRRXo=
-github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
-github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
-github.com/charmbracelet/glamour v0.9.1 h1:11dEfiGP8q1BEqvGoIjivuc2rBk+5qEXdPtaQ2WoiCM=
-github.com/charmbracelet/glamour v0.9.1/go.mod h1:+SHvIS8qnwhgTpVMiXwn7OfGomSqff1cHBCI8jLOetk=
-github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
-github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
+github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.3 h1:5A2e3myxXMpCES+kjEWgGsaf9VgZXjZbLi5iMTH7j40=
+github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.3/go.mod h1:ZFDg5oPjyRYrPAa3iFrtP1DO8xy+LUQxd9JFHEcuwJY=
+github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40=
+github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0=
+github.com/charmbracelet/glamour v0.10.0 h1:MtZvfwsYCx8jEPFJm3rIBFIMZUfUJ765oX8V6kXldcY=
+github.com/charmbracelet/glamour v0.10.0/go.mod h1:f+uf+I/ChNmqo087elLnVdCiVgjSKWuXa/l6NU2ndYk=
+github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 h1:ZR7e0ro+SZZiIZD7msJyA+NjkCNNavuiPBLgerbOziE=
+github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834/go.mod h1:aKC/t2arECF6rNOnaKaVU6y4t4ZeHQzqfxedE/VkVhA=
+github.com/charmbracelet/lipgloss/v2 v2.0.0-beta1 h1:SOylT6+BQzPHEjn15TIzawBPVD0QmhKXbcb3jY0ZIKU=
+github.com/charmbracelet/lipgloss/v2 v2.0.0-beta1/go.mod h1:tRlx/Hu0lo/j9viunCN2H+Ze6JrmdjQlXUQvvArgaOc=
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
-github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
-github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
-github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
-github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
+github.com/charmbracelet/x/cellbuf v0.0.14-0.20250501183327-ad3bc78c6a81 h1:iGrflaL5jQW6crML+pZx/ulWAVZQR3CQoRGvFsr2Tyg=
+github.com/charmbracelet/x/cellbuf v0.0.14-0.20250501183327-ad3bc78c6a81/go.mod h1:poPFOXFTsJsnLbkV3H2KxAAXT7pdjxxLujLocWjkyzM=
+github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a h1:FsHEJ52OC4VuTzU8t+n5frMjLvpYWEznSr/u8tnkCYw=
+github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
+github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf h1:rLG0Yb6MQSDKdB52aGX55JT1oi0P0Kuaj7wi1bLUpnI=
+github.com/charmbracelet/x/exp/slice v0.0.0-20250327172914-2fdc97757edf/go.mod h1:B3UgsnsBZS/eX42BlaNiJkD1pPOUa+oF1IYC6Yd2CEU=
+github.com/charmbracelet/x/input v0.3.5-0.20250424101541-abb4d9a9b197 h1:fsWj8NF5njyMVzELc7++HsvRDvgz3VcgGAUgWBDWWWM=
+github.com/charmbracelet/x/input v0.3.5-0.20250424101541-abb4d9a9b197/go.mod h1:xseGeVftoP9rVI+/8WKYrJFH6ior6iERGvklwwHz5+s=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
+github.com/charmbracelet/x/windows v0.2.1 h1:3x7vnbpQrjpuq/4L+I4gNsG5htYoCiA5oe9hLjAij5I=
+github.com/charmbracelet/x/windows v0.2.1/go.mod h1:ptZp16h40gDYqs5TSawSVW+yiLB13j4kSMA0lSCHL0M=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -56,8 +64,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
-github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
-github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
+github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58=
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w=
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q=
diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go
index cffc4b1cf..3917330e3 100644
--- a/packages/tui/internal/app/app.go
+++ b/packages/tui/internal/app/app.go
@@ -8,7 +8,7 @@ import (
"log/slog"
- tea "github.com/charmbracelet/bubbletea"
+ tea "github.com/charmbracelet/bubbletea/v2"
"github.com/sst/opencode/internal/config"
"github.com/sst/opencode/internal/fileutil"
"github.com/sst/opencode/internal/state"
diff --git a/packages/tui/internal/components/chat/editor.go b/packages/tui/internal/components/chat/editor.go
index 52f198492..198958b09 100644
--- a/packages/tui/internal/components/chat/editor.go
+++ b/packages/tui/internal/components/chat/editor.go
@@ -5,15 +5,13 @@ import (
"log/slog"
"os"
"os/exec"
- "slices"
"strings"
- "unicode"
- "github.com/charmbracelet/bubbles/key"
- "github.com/charmbracelet/bubbles/spinner"
- "github.com/charmbracelet/bubbles/textarea"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ "github.com/charmbracelet/bubbles/v2/spinner"
+ "github.com/charmbracelet/bubbles/v2/textarea"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/components/dialog"
"github.com/sst/opencode/internal/image"
@@ -129,18 +127,18 @@ func (m *editorComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.attachments = nil
return m, nil
}
- if m.deleteMode && len(msg.Runes) > 0 && unicode.IsDigit(msg.Runes[0]) {
- num := int(msg.Runes[0] - '0')
- m.deleteMode = false
- if num < 10 && len(m.attachments) > num {
- if num == 0 {
- m.attachments = m.attachments[num+1:]
- } else {
- m.attachments = slices.Delete(m.attachments, num, num+1)
- }
- return m, nil
- }
- }
+ // if m.deleteMode && len(msg.Runes) > 0 && unicode.IsDigit(msg.Runes[0]) {
+ // num := int(msg.Runes[0] - '0')
+ // m.deleteMode = false
+ // if num < 10 && len(m.attachments) > num {
+ // if num == 0 {
+ // m.attachments = m.attachments[num+1:]
+ // } else {
+ // m.attachments = slices.Delete(m.attachments, num, num+1)
+ // }
+ // return m, nil
+ // }
+ // }
if key.Matches(msg, messageKeys.PageUp) || key.Matches(msg, messageKeys.PageDown) ||
key.Matches(msg, messageKeys.HalfPageUp) || key.Matches(msg, messageKeys.HalfPageDown) {
return m, nil
@@ -258,7 +256,7 @@ func (m *editorComponent) View() string {
m.textarea.View(),
)
textarea = styles.BaseStyle().
- Width(m.width-2).
+ Width(m.width). // -2).
Border(lipgloss.NormalBorder(), true, true).
BorderForeground(t.Border()).
Render(textarea)
@@ -286,10 +284,7 @@ func (m *editorComponent) View() string {
info,
)
- return styles.ForceReplaceBackgroundWithLipgloss(
- content,
- t.Background(),
- )
+ return content
}
func (m *editorComponent) SetSize(width, height int) tea.Cmd {
@@ -414,14 +409,14 @@ func createTextArea(existing *textarea.Model) textarea.Model {
ta := textarea.New()
ta.Placeholder = "It's prompting time..."
- ta.BlurredStyle.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
- ta.BlurredStyle.CursorLine = styles.BaseStyle().Background(bgColor)
- ta.BlurredStyle.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
- ta.BlurredStyle.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
- ta.FocusedStyle.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
- ta.FocusedStyle.CursorLine = styles.BaseStyle().Background(bgColor)
- ta.FocusedStyle.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
- ta.FocusedStyle.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
+ ta.Styles.Blurred.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
+ ta.Styles.Blurred.CursorLine = styles.BaseStyle().Background(bgColor)
+ ta.Styles.Blurred.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
+ ta.Styles.Blurred.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
+ ta.Styles.Focused.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
+ ta.Styles.Focused.CursorLine = styles.BaseStyle().Background(bgColor)
+ ta.Styles.Focused.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
+ ta.Styles.Focused.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
ta.Prompt = " "
ta.ShowLineNumbers = false
@@ -437,7 +432,7 @@ func createTextArea(existing *textarea.Model) textarea.Model {
return ta
}
-func NewEditorComponent(app *app.App) tea.Model {
+func NewEditorComponent(app *app.App) layout.ModelWithView {
s := spinner.New(spinner.WithSpinner(spinner.Ellipsis), spinner.WithStyle(styles.Muted().Width(3)))
ta := createTextArea(nil)
diff --git a/packages/tui/internal/components/chat/message.go b/packages/tui/internal/components/chat/message.go
index 131898c84..199b4a070 100644
--- a/packages/tui/internal/components/chat/message.go
+++ b/packages/tui/internal/components/chat/message.go
@@ -9,7 +9,8 @@ import (
"time"
"unicode"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/lipgloss/v2"
+ "github.com/charmbracelet/lipgloss/v2/compat"
"github.com/charmbracelet/x/ansi"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/components/diff"
@@ -21,8 +22,8 @@ import (
"golang.org/x/text/language"
)
-func toMarkdown(content string, width int) string {
- r := styles.GetMarkdownRenderer(width)
+func toMarkdown(content string, width int, backgroundColor compat.AdaptiveColor) string {
+ r := styles.GetMarkdownRenderer(width, backgroundColor)
content = strings.ReplaceAll(content, app.Info.Path.Root+"/", "")
rendered, _ := r.Render(content)
lines := strings.Split(rendered, "\n")
@@ -50,7 +51,7 @@ func toMarkdown(content string, width int) string {
type blockRenderer struct {
align *lipgloss.Position
- borderColor *lipgloss.AdaptiveColor
+ borderColor *compat.AdaptiveColor
fullWidth bool
paddingTop int
paddingBottom int
@@ -70,7 +71,7 @@ func WithAlign(align lipgloss.Position) renderingOption {
}
}
-func WithBorderColor(color lipgloss.AdaptiveColor) renderingOption {
+func WithBorderColor(color compat.AdaptiveColor) renderingOption {
return func(c *blockRenderer) {
c.borderColor = &color
}
@@ -137,9 +138,8 @@ func renderContentBlock(content string, options ...renderingOption) string {
BorderLeftBackground(t.Background())
}
- content = styles.ForceReplaceBackgroundWithLipgloss(content, t.BackgroundSubtle())
if renderer.fullWidth {
- style = style.Width(layout.Current.Container.Width - 2)
+ style = style.Width(layout.Current.Container.Width)
}
content = style.Render(content)
if renderer.paddingTop > 0 {
@@ -152,13 +152,11 @@ func renderContentBlock(content string, options ...renderingOption) string {
layout.Current.Container.Width,
align,
content,
- lipgloss.WithWhitespaceBackground(t.Background()),
)
content = lipgloss.PlaceHorizontal(
layout.Current.Viewport.Width,
lipgloss.Center,
content,
- lipgloss.WithWhitespaceBackground(t.Background()),
)
return content
}
@@ -181,9 +179,7 @@ func renderText(message client.MessageInfo, text string, author string) string {
// don't show the date if it's today
timestamp = timestamp[12:]
}
- info := styles.BaseStyle().
- Foreground(t.TextMuted()).
- Render(fmt.Sprintf("%s (%s)", author, timestamp))
+ info := fmt.Sprintf("%s (%s)", author, timestamp)
align := lipgloss.Left
switch message.Role {
@@ -195,7 +191,7 @@ func renderText(message client.MessageInfo, text string, author string) string {
textWidth := lipgloss.Width(text)
markdownWidth := min(textWidth, width-padding-4) // -4 for the border and padding
- content := toMarkdown(text, markdownWidth)
+ content := toMarkdown(text, markdownWidth, t.BackgroundSubtle())
content = lipgloss.JoinVertical(align, content, info)
switch message.Role {
@@ -313,7 +309,7 @@ func renderToolInvocation(
lipgloss.Center,
lipgloss.Center,
body,
- lipgloss.WithWhitespaceBackground(t.Background()),
+ lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
)
}
case "opencode_write":
@@ -328,7 +324,7 @@ func renderToolInvocation(
command := toolArgsMap["command"].(string)
stdout := metadata["stdout"].(string)
body = fmt.Sprintf("```console\n> %s\n%s```", command, stdout)
- body = toMarkdown(body, innerWidth)
+ body = toMarkdown(body, innerWidth, t.BackgroundSubtle())
body = renderContentBlock(body, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
}
case "opencode_webfetch":
@@ -336,7 +332,7 @@ func renderToolInvocation(
format := toolArgsMap["format"].(string)
body = truncateHeight(body, 10)
if format == "html" || format == "markdown" {
- body = toMarkdown(body, innerWidth)
+ body = toMarkdown(body, innerWidth, t.BackgroundSubtle())
}
body = renderContentBlock(body, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
case "opencode_todowrite":
@@ -356,7 +352,7 @@ func renderToolInvocation(
body += fmt.Sprintf("- [ ] %s\n", content)
}
}
- body = toMarkdown(body, innerWidth)
+ body = toMarkdown(body, innerWidth, t.BackgroundSubtle())
body = renderContentBlock(body, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
}
default:
@@ -368,7 +364,7 @@ func renderToolInvocation(
content := style.Render(title)
content = lipgloss.PlaceHorizontal(layout.Current.Viewport.Width, lipgloss.Center, content)
- content = styles.ForceReplaceBackgroundWithLipgloss(content, t.Background())
+ // content = styles.ForceReplaceBackgroundWithLipgloss(content, t.Background())
if showResult && body != "" {
content += "\n" + body
}
@@ -411,6 +407,7 @@ func WithTruncate(height int) fileRenderingOption {
}
func renderFile(filename string, content string, options ...fileRenderingOption) string {
+ t := theme.CurrentTheme()
renderer := &fileRenderer{
filename: filename,
content: content,
@@ -419,7 +416,6 @@ func renderFile(filename string, content string, options ...fileRenderingOption)
option(renderer)
}
- // TODO: is this even needed?
lines := []string{}
for line := range strings.SplitSeq(content, "\n") {
line = strings.TrimRightFunc(line, unicode.IsSpace)
@@ -428,23 +424,12 @@ func renderFile(filename string, content string, options ...fileRenderingOption)
}
content = strings.Join(lines, "\n")
- width := layout.Current.Container.Width - 6
+ width := layout.Current.Container.Width - 8
if renderer.height > 0 {
content = truncateHeight(content, renderer.height)
}
content = fmt.Sprintf("```%s\n%s\n```", extension(renderer.filename), content)
- content = toMarkdown(content, width)
-
- // ensure no line is wider than the width
- // truncated := []string{}
- // for line := range strings.SplitSeq(content, "\n") {
- // line = strings.TrimRightFunc(line, unicode.IsSpace)
- // // if lipgloss.Width(line) > width-3 {
- // line = ansi.Truncate(line, width-3, "")
- // // }
- // truncated = append(truncated, line)
- // }
- // content = strings.Join(truncated, "\n")
+ content = toMarkdown(content, width, t.BackgroundSubtle())
return renderContentBlock(content, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
}
diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go
index 093c8cf94..0036d0669 100644
--- a/packages/tui/internal/components/chat/messages.go
+++ b/packages/tui/internal/components/chat/messages.go
@@ -4,11 +4,11 @@ import (
"strings"
"time"
- "github.com/charmbracelet/bubbles/key"
- "github.com/charmbracelet/bubbles/spinner"
- "github.com/charmbracelet/bubbles/viewport"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ "github.com/charmbracelet/bubbles/v2/spinner"
+ "github.com/charmbracelet/bubbles/v2/viewport"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/components/dialog"
"github.com/sst/opencode/internal/layout"
@@ -220,11 +220,11 @@ func (m *messagesComponent) renderView() {
m.width,
lipgloss.Center,
block,
- lipgloss.WithWhitespaceBackground(t.Background()),
+ lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
))
}
- m.viewport.Height = m.height - lipgloss.Height(m.header())
+ m.viewport.SetHeight(m.height - lipgloss.Height(m.header()))
m.viewport.SetContent(strings.Join(centered, "\n"))
}
@@ -238,7 +238,7 @@ func (m *messagesComponent) header() string {
base := styles.BaseStyle().Render
muted := styles.Muted().Render
headerLines := []string{}
- headerLines = append(headerLines, toMarkdown("# "+m.app.Session.Title, width))
+ headerLines = append(headerLines, toMarkdown("# "+m.app.Session.Title, width, t.Background()))
if m.app.Session.Share != nil && m.app.Session.Share.Url != "" {
headerLines = append(headerLines, muted(m.app.Session.Share.Url))
} else {
@@ -255,7 +255,7 @@ func (m *messagesComponent) header() string {
Background(t.Background()).
Render(header)
- return styles.ForceReplaceBackgroundWithLipgloss(header, t.Background())
+ return header
}
func (m *messagesComponent) View() string {
@@ -269,73 +269,8 @@ func (m *messagesComponent) View() string {
)
}
-// func hasToolsWithoutResponse(messages []message.Message) bool {
-// toolCalls := make([]message.ToolCall, 0)
-// toolResults := make([]message.ToolResult, 0)
-// for _, m := range messages {
-// toolCalls = append(toolCalls, m.ToolCalls()...)
-// toolResults = append(toolResults, m.ToolResults()...)
-// }
-//
-// for _, v := range toolCalls {
-// found := false
-// for _, r := range toolResults {
-// if v.ID == r.ToolCallID {
-// found = true
-// break
-// }
-// }
-// if !found && v.Finished {
-// return true
-// }
-// }
-// return false
-// }
-
-// func hasUnfinishedToolCalls(messages []message.Message) bool {
-// toolCalls := make([]message.ToolCall, 0)
-// for _, m := range messages {
-// toolCalls = append(toolCalls, m.ToolCalls()...)
-// }
-// for _, v := range toolCalls {
-// if !v.Finished {
-// return true
-// }
-// }
-// return false
-// }
-
-func (m *messagesComponent) help() string {
- t := theme.CurrentTheme()
- baseStyle := styles.BaseStyle()
-
- text := ""
-
- if m.app.IsBusy() {
- text += lipgloss.JoinHorizontal(
- lipgloss.Left,
- baseStyle.Foreground(t.TextMuted()).Bold(true).Render("press "),
- baseStyle.Foreground(t.Text()).Bold(true).Render("esc"),
- baseStyle.Foreground(t.TextMuted()).Bold(true).Render(" to interrupt"),
- )
- } else {
- text += lipgloss.JoinHorizontal(
- lipgloss.Left,
- baseStyle.Foreground(t.Text()).Bold(true).Render("enter"),
- baseStyle.Foreground(t.TextMuted()).Bold(true).Render(" to send,"),
- baseStyle.Foreground(t.Text()).Bold(true).Render(" \\"),
- baseStyle.Foreground(t.TextMuted()).Bold(true).Render("+"),
- baseStyle.Foreground(t.Text()).Bold(true).Render("enter"),
- baseStyle.Foreground(t.TextMuted()).Bold(true).Render(" for newline"),
- )
- }
- return baseStyle.
- Width(m.width).
- Render(text)
-}
-
func (m *messagesComponent) home() string {
- t := theme.CurrentTheme()
+ // t := theme.CurrentTheme()
baseStyle := styles.BaseStyle()
base := baseStyle.Render
muted := styles.Muted().Render
@@ -398,16 +333,13 @@ func (m *messagesComponent) home() string {
lines = append(lines, "")
}
- return styles.ForceReplaceBackgroundWithLipgloss(
- lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center,
- baseStyle.Width(lipgloss.Width(logoAndVersion)).Render(
- lipgloss.JoinVertical(
- lipgloss.Top,
- lines...,
- ),
- )),
- t.Background(),
- )
+ return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center,
+ baseStyle.Width(lipgloss.Width(logoAndVersion)).Render(
+ lipgloss.JoinVertical(
+ lipgloss.Top,
+ lines...,
+ ),
+ ))
}
func (m *messagesComponent) SetSize(width, height int) tea.Cmd {
@@ -420,10 +352,10 @@ func (m *messagesComponent) SetSize(width, height int) tea.Cmd {
}
m.width = width
m.height = height
- m.viewport.Width = width
- m.viewport.Height = height - lipgloss.Height(m.header())
- m.attachments.Width = width + 40
- m.attachments.Height = 3
+ m.viewport.SetWidth(width)
+ m.viewport.SetHeight(height - lipgloss.Height(m.header()))
+ m.attachments.SetWidth(width + 40)
+ m.attachments.SetHeight(3)
m.renderView()
return nil
}
@@ -449,15 +381,15 @@ func (m *messagesComponent) BindingKeys() []key.Binding {
}
}
-func NewMessagesComponent(app *app.App) tea.Model {
+func NewMessagesComponent(app *app.App) layout.ModelWithView {
customSpinner := spinner.Spinner{
Frames: []string{" ", "┃", "┃"},
FPS: time.Second / 3,
}
s := spinner.New(spinner.WithSpinner(customSpinner))
- vp := viewport.New(0, 0)
- attachments := viewport.New(0, 0)
+ vp := viewport.New() //(0, 0)
+ attachments := viewport.New() //(0, 0)
vp.KeyMap.PageUp = messageKeys.PageUp
vp.KeyMap.PageDown = messageKeys.PageDown
vp.KeyMap.HalfPageUp = messageKeys.HalfPageUp
diff --git a/packages/tui/internal/components/core/status.go b/packages/tui/internal/components/core/status.go
index 10a123f02..2b9929222 100644
--- a/packages/tui/internal/components/core/status.go
+++ b/packages/tui/internal/components/core/status.go
@@ -5,20 +5,21 @@ import (
"strings"
"time"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/app"
+ "github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/pubsub"
"github.com/sst/opencode/internal/status"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
)
-type StatusCmp interface {
- tea.Model
+type StatusComponent interface {
+ layout.ModelWithView
}
-type statusCmp struct {
+type statusComponent struct {
app *app.App
queue []status.StatusMessage
width int
@@ -27,7 +28,7 @@ type statusCmp struct {
}
// clearMessageCmd is a command that clears status messages after a timeout
-func (m statusCmp) clearMessageCmd() tea.Cmd {
+func (m statusComponent) clearMessageCmd() tea.Cmd {
return tea.Tick(time.Second, func(t time.Time) tea.Msg {
return statusCleanupMsg{time: t}
})
@@ -38,11 +39,11 @@ type statusCleanupMsg struct {
time time.Time
}
-func (m statusCmp) Init() tea.Cmd {
+func (m statusComponent) Init() tea.Cmd {
return m.clearMessageCmd()
}
-func (m statusCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+func (m statusComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.width = msg.Width
@@ -104,10 +105,9 @@ func logo() string {
open := styles.Muted().Render("open")
code := styles.BaseStyle().Bold(true).Render("code")
version := styles.Muted().Render(app.Info.Version)
- return styles.ForceReplaceBackgroundWithLipgloss(
- styles.Padded().Render(mark+open+code+" "+version),
- t.BackgroundElement(),
- )
+ return styles.Padded().
+ Background(t.BackgroundElement()).
+ Render(mark + open + code + " " + version)
}
func formatTokensAndCost(tokens float32, contextWindow float32, cost float32) string {
@@ -137,7 +137,7 @@ func formatTokensAndCost(tokens float32, contextWindow float32, cost float32) st
return fmt.Sprintf("Tokens: %s (%d%%), Cost: %s", formattedTokens, int(percentage), formattedCost)
}
-func (m statusCmp) View() string {
+func (m statusComponent) View() string {
if m.app.Session.Id == "" {
return styles.BaseStyle().
Width(m.width).
@@ -250,107 +250,8 @@ func (m statusCmp) View() string {
// }
}
-func (m *statusCmp) projectDiagnostics() string {
- t := theme.CurrentTheme()
-
- // Check if any LSP server is still initializing
- initializing := false
- // for _, client := range m.app.LSPClients {
- // if client.GetServerState() == lsp.StateStarting {
- // initializing = true
- // break
- // }
- // }
-
- // If any server is initializing, show that status
- if initializing {
- return lipgloss.NewStyle().
- Foreground(t.Warning()).
- Render(fmt.Sprintf("%s Initializing LSP...", styles.SpinnerIcon))
- }
-
- // errorDiagnostics := []protocol.Diagnostic{}
- // warnDiagnostics := []protocol.Diagnostic{}
- // hintDiagnostics := []protocol.Diagnostic{}
- // infoDiagnostics := []protocol.Diagnostic{}
- // for _, client := range m.app.LSPClients {
- // for _, d := range client.GetDiagnostics() {
- // for _, diag := range d {
- // switch diag.Severity {
- // case protocol.SeverityError:
- // errorDiagnostics = append(errorDiagnostics, diag)
- // case protocol.SeverityWarning:
- // warnDiagnostics = append(warnDiagnostics, diag)
- // case protocol.SeverityHint:
- // hintDiagnostics = append(hintDiagnostics, diag)
- // case protocol.SeverityInformation:
- // infoDiagnostics = append(infoDiagnostics, diag)
- // }
- // }
- // }
- // }
- return styles.ForceReplaceBackgroundWithLipgloss(
- styles.Padded().Render("No diagnostics"),
- t.BackgroundElement(),
- )
-
- // if len(errorDiagnostics) == 0 &&
- // len(warnDiagnostics) == 0 &&
- // len(infoDiagnostics) == 0 &&
- // len(hintDiagnostics) == 0 {
- // return styles.ForceReplaceBackgroundWithLipgloss(
- // styles.Padded().Render("No diagnostics"),
- // t.BackgroundDarker(),
- // )
- // }
-
- // diagnostics := []string{}
- //
- // errStr := lipgloss.NewStyle().
- // Background(t.BackgroundDarker()).
- // Foreground(t.Error()).
- // Render(fmt.Sprintf("%s %d", styles.ErrorIcon, len(errorDiagnostics)))
- // diagnostics = append(diagnostics, errStr)
- //
- // warnStr := lipgloss.NewStyle().
- // Background(t.BackgroundDarker()).
- // Foreground(t.Warning()).
- // Render(fmt.Sprintf("%s %d", styles.WarningIcon, len(warnDiagnostics)))
- // diagnostics = append(diagnostics, warnStr)
- //
- // infoStr := lipgloss.NewStyle().
- // Background(t.BackgroundDarker()).
- // Foreground(t.Info()).
- // Render(fmt.Sprintf("%s %d", styles.InfoIcon, len(infoDiagnostics)))
- // diagnostics = append(diagnostics, infoStr)
- //
- // hintStr := lipgloss.NewStyle().
- // Background(t.BackgroundDarker()).
- // Foreground(t.Text()).
- // Render(fmt.Sprintf("%s %d", styles.HintIcon, len(hintDiagnostics)))
- // diagnostics = append(diagnostics, hintStr)
- //
- // return styles.ForceReplaceBackgroundWithLipgloss(
- // styles.Padded().Render(strings.Join(diagnostics, " ")),
- // t.BackgroundDarker(),
- // )
-}
-
-func (m statusCmp) model() string {
- t := theme.CurrentTheme()
- model := "None"
- if m.app.Model != nil {
- model = *m.app.Model.Name
- }
-
- return styles.Padded().
- Background(t.Secondary()).
- Foreground(t.Background()).
- Render(model)
-}
-
-func NewStatusCmp(app *app.App) StatusCmp {
- statusComponent := &statusCmp{
+func NewStatusCmp(app *app.App) StatusComponent {
+ statusComponent := &statusComponent{
app: app,
queue: []status.StatusMessage{},
messageTTL: 4 * time.Second,
diff --git a/packages/tui/internal/components/dialog/arguments.go b/packages/tui/internal/components/dialog/arguments.go
index 2faa36070..4ef21fcf4 100644
--- a/packages/tui/internal/components/dialog/arguments.go
+++ b/packages/tui/internal/components/dialog/arguments.go
@@ -2,10 +2,10 @@ package dialog
import (
"fmt"
- "github.com/charmbracelet/bubbles/key"
- "github.com/charmbracelet/bubbles/textinput"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ "github.com/charmbracelet/bubbles/v2/textinput"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
@@ -70,17 +70,24 @@ func NewMultiArgumentsDialogCmp(commandID, content string, argNames []string) Mu
for i, name := range argNames {
ti := textinput.New()
ti.Placeholder = fmt.Sprintf("Enter value for %s...", name)
- ti.Width = 40
+ ti.SetWidth(40)
ti.Prompt = ""
- ti.PlaceholderStyle = ti.PlaceholderStyle.Background(t.Background())
- ti.PromptStyle = ti.PromptStyle.Background(t.Background())
- ti.TextStyle = ti.TextStyle.Background(t.Background())
+ ti.Styles.Blurred.Placeholder = ti.Styles.Blurred.Placeholder.Background(t.Background())
+ ti.Styles.Blurred.Text = ti.Styles.Blurred.Text.Background(t.Background())
+ ti.Styles.Blurred.Prompt = ti.Styles.Blurred.Prompt.Foreground(t.Primary())
+
+ ti.Styles.Focused.Placeholder = ti.Styles.Focused.Placeholder.Background(t.Background())
+ ti.Styles.Focused.Text = ti.Styles.Focused.Text.Background(t.Background())
+ ti.Styles.Focused.Prompt = ti.Styles.Focused.Prompt.Foreground(t.Primary())
+
+ // ti.PromptStyle = ti.PromptStyle.Background(t.Background())
+ // ti.TextStyle = ti.TextStyle.Background(t.Background())
// Only focus the first input initially
if i == 0 {
ti.Focus()
- ti.PromptStyle = ti.PromptStyle.Foreground(t.Primary())
- ti.TextStyle = ti.TextStyle.Foreground(t.Primary())
+ // ti.PromptStyle = ti.PromptStyle.Foreground(t.Primary())
+ // ti.TextStyle = ti.TextStyle.Foreground(t.Primary())
} else {
ti.Blur()
}
@@ -115,7 +122,7 @@ func (m MultiArgumentsDialogCmp) Init() tea.Cmd {
// Update implements tea.Model.
func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
- t := theme.CurrentTheme()
+ // t := theme.CurrentTheme()
switch msg := msg.(type) {
case tea.KeyMsg:
@@ -145,22 +152,22 @@ func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.inputs[m.focusIndex].Blur()
m.focusIndex++
m.inputs[m.focusIndex].Focus()
- m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
- m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
+ // m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
+ // m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
case key.Matches(msg, key.NewBinding(key.WithKeys("tab"))):
// Move to the next input
m.inputs[m.focusIndex].Blur()
m.focusIndex = (m.focusIndex + 1) % len(m.inputs)
m.inputs[m.focusIndex].Focus()
- m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
- m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
+ // m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
+ // m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
case key.Matches(msg, key.NewBinding(key.WithKeys("shift+tab"))):
// Move to the previous input
m.inputs[m.focusIndex].Blur()
m.focusIndex = (m.focusIndex - 1 + len(m.inputs)) % len(m.inputs)
m.inputs[m.focusIndex].Focus()
- m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
- m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
+ // m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.Foreground(t.Primary())
+ // m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
}
case tea.WindowSizeMsg:
m.width = msg.Width
diff --git a/packages/tui/internal/components/dialog/commands.go b/packages/tui/internal/components/dialog/commands.go
index 1e99c09e0..39fe793d7 100644
--- a/packages/tui/internal/components/dialog/commands.go
+++ b/packages/tui/internal/components/dialog/commands.go
@@ -1,9 +1,9 @@
package dialog
import (
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
utilComponents "github.com/sst/opencode/internal/components/util"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
@@ -56,12 +56,12 @@ type CloseCommandDialogMsg struct{}
// CommandDialog interface for the command selection dialog
type CommandDialog interface {
- tea.Model
+ layout.ModelWithView
layout.Bindings
SetCommands(commands []Command)
}
-type commandDialogCmp struct {
+type commandDialogComponent struct {
listView utilComponents.SimpleList[Command]
width int
height int
@@ -83,11 +83,11 @@ var commandKeys = commandKeyMap{
),
}
-func (c *commandDialogCmp) Init() tea.Cmd {
+func (c *commandDialogComponent) Init() tea.Cmd {
return c.listView.Init()
}
-func (c *commandDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+func (c *commandDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
case tea.KeyMsg:
@@ -114,7 +114,7 @@ func (c *commandDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return c, tea.Batch(cmds...)
}
-func (c *commandDialogCmp) View() string {
+func (c *commandDialogComponent) View() string {
t := theme.CurrentTheme()
baseStyle := styles.BaseStyle()
@@ -158,11 +158,11 @@ func (c *commandDialogCmp) View() string {
Render(content)
}
-func (c *commandDialogCmp) BindingKeys() []key.Binding {
+func (c *commandDialogComponent) BindingKeys() []key.Binding {
return layout.KeyMapToSlice(commandKeys)
}
-func (c *commandDialogCmp) SetCommands(commands []Command) {
+func (c *commandDialogComponent) SetCommands(commands []Command) {
c.listView.SetItems(commands)
}
@@ -174,7 +174,7 @@ func NewCommandDialogCmp() CommandDialog {
"No commands available",
true,
)
- return &commandDialogCmp{
+ return &commandDialogComponent{
listView: listView,
}
}
diff --git a/packages/tui/internal/components/dialog/complete.go b/packages/tui/internal/components/dialog/complete.go
index ca209014e..91ac8f7b8 100644
--- a/packages/tui/internal/components/dialog/complete.go
+++ b/packages/tui/internal/components/dialog/complete.go
@@ -1,13 +1,13 @@
package dialog
import (
- "github.com/charmbracelet/bubbles/key"
- "github.com/charmbracelet/bubbles/textarea"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
- "github.com/sst/opencode/internal/status"
+ "github.com/charmbracelet/bubbles/v2/key"
+ "github.com/charmbracelet/bubbles/v2/textarea"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
utilComponents "github.com/sst/opencode/internal/components/util"
"github.com/sst/opencode/internal/layout"
+ "github.com/sst/opencode/internal/status"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
"github.com/sst/opencode/internal/util"
@@ -77,7 +77,7 @@ type CompletionDialogCompleteItemMsg struct {
type CompletionDialogCloseMsg struct{}
type CompletionDialog interface {
- tea.Model
+ layout.ModelWithView
layout.Bindings
SetWidth(width int)
}
diff --git a/packages/tui/internal/components/dialog/custom_commands.go b/packages/tui/internal/components/dialog/custom_commands.go
index c0115ad7a..5e0671b80 100644
--- a/packages/tui/internal/components/dialog/custom_commands.go
+++ b/packages/tui/internal/components/dialog/custom_commands.go
@@ -7,7 +7,7 @@ import (
"regexp"
"strings"
- tea "github.com/charmbracelet/bubbletea"
+ tea "github.com/charmbracelet/bubbletea/v2"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/util"
)
diff --git a/packages/tui/internal/components/dialog/filepicker.go b/packages/tui/internal/components/dialog/filepicker.go
index 3fad90e3f..408b9cc00 100644
--- a/packages/tui/internal/components/dialog/filepicker.go
+++ b/packages/tui/internal/components/dialog/filepicker.go
@@ -12,13 +12,14 @@ import (
"log/slog"
"github.com/atotto/clipboard"
- "github.com/charmbracelet/bubbles/key"
- "github.com/charmbracelet/bubbles/textinput"
- "github.com/charmbracelet/bubbles/viewport"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ "github.com/charmbracelet/bubbles/v2/textinput"
+ "github.com/charmbracelet/bubbles/v2/viewport"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/image"
+ "github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/status"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
@@ -82,7 +83,7 @@ var filePickerKeyMap = FilePrickerKeyMap{
),
}
-type filepickerCmp struct {
+type filepickerComponent struct {
basePath string
width int
height int
@@ -118,18 +119,18 @@ type AttachmentAddedMsg struct {
Attachment app.Attachment
}
-func (f *filepickerCmp) Init() tea.Cmd {
+func (f *filepickerComponent) Init() tea.Cmd {
return nil
}
-func (f *filepickerCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+func (f *filepickerComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case tea.WindowSizeMsg:
f.width = 60
f.height = 20
- f.viewport.Width = 80
- f.viewport.Height = 22
+ f.viewport.SetWidth(80)
+ f.viewport.SetHeight(22)
f.cursor = 0
f.getCurrentFileBelowCursor()
case tea.KeyMsg:
@@ -236,7 +237,7 @@ func (f *filepickerCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return f, cmd
}
-func (f *filepickerCmp) addAttachmentToMessage() (tea.Model, tea.Cmd) {
+func (f *filepickerComponent) addAttachmentToMessage() (tea.Model, tea.Cmd) {
// modeInfo := GetSelectedModel(config.Get())
// if !modeInfo.SupportsAttachments {
// status.Error(fmt.Sprintf("Model %s doesn't support attachments", modeInfo.Name))
@@ -273,7 +274,7 @@ func (f *filepickerCmp) addAttachmentToMessage() (tea.Model, tea.Cmd) {
return f, util.CmdHandler(AttachmentAddedMsg{attachment})
}
-func (f *filepickerCmp) View() string {
+func (f *filepickerComponent) View() string {
t := theme.CurrentTheme()
const maxVisibleDirs = 20
const maxWidth = 80
@@ -333,7 +334,7 @@ func (f *filepickerCmp) View() string {
Render(f.cwd.View())
viewportstyle := lipgloss.NewStyle().
- Width(f.viewport.Width).
+ Width(f.viewport.Width()).
Background(t.Background()).
Border(lipgloss.RoundedBorder()).
BorderForeground(t.TextMuted()).
@@ -366,21 +367,21 @@ func (f *filepickerCmp) View() string {
return lipgloss.JoinHorizontal(lipgloss.Center, contentStyle.Render(content), viewportstyle)
}
-type FilepickerCmp interface {
- tea.Model
+type FilepickerComponent interface {
+ layout.ModelWithView
ToggleFilepicker(showFilepicker bool)
IsCWDFocused() bool
}
-func (f *filepickerCmp) ToggleFilepicker(showFilepicker bool) {
+func (f *filepickerComponent) ToggleFilepicker(showFilepicker bool) {
f.ShowFilePicker = showFilepicker
}
-func (f *filepickerCmp) IsCWDFocused() bool {
+func (f *filepickerComponent) IsCWDFocused() bool {
return f.cwd.Focused()
}
-func NewFilepickerCmp(app *app.App) FilepickerCmp {
+func NewFilepickerCmp(app *app.App) FilepickerComponent {
homepath, err := os.UserHomeDir()
if err != nil {
slog.Error("error loading user files")
@@ -388,16 +389,16 @@ func NewFilepickerCmp(app *app.App) FilepickerCmp {
}
baseDir := DirNode{parent: nil, directory: homepath}
dirs := readDir(homepath, false)
- viewport := viewport.New(0, 0)
+ viewport := viewport.New() // viewport.New(0, 0)
currentDirectory := textinput.New()
currentDirectory.CharLimit = 200
- currentDirectory.Width = 44
- currentDirectory.Cursor.Blink = true
+ currentDirectory.SetWidth(44)
+ // currentDirectory.Cursor.Blink = true
currentDirectory.SetValue(baseDir.directory)
- return &filepickerCmp{cwdDetails: &baseDir, dirs: dirs, cursorChain: make(stack, 0), viewport: viewport, cwd: currentDirectory, app: app}
+ return &filepickerComponent{cwdDetails: &baseDir, dirs: dirs, cursorChain: make(stack, 0), viewport: viewport, cwd: currentDirectory, app: app}
}
-func (f *filepickerCmp) getCurrentFileBelowCursor() {
+func (f *filepickerComponent) getCurrentFileBelowCursor() {
if len(f.dirs) == 0 || f.cursor < 0 || f.cursor >= len(f.dirs) {
slog.Error(fmt.Sprintf("Invalid cursor position. Dirs length: %d, Cursor: %d", len(f.dirs), f.cursor))
f.viewport.SetContent("Preview unavailable")
@@ -410,7 +411,7 @@ func (f *filepickerCmp) getCurrentFileBelowCursor() {
fullPath := f.cwdDetails.directory + "/" + dir.Name()
go func() {
- imageString, err := image.ImagePreview(f.viewport.Width-4, fullPath)
+ imageString, err := image.ImagePreview(f.viewport.Width()-4, fullPath)
if err != nil {
slog.Error(err.Error())
f.viewport.SetContent("Preview unavailable")
diff --git a/packages/tui/internal/components/dialog/help.go b/packages/tui/internal/components/dialog/help.go
index a55e39e72..6ceeb40b2 100644
--- a/packages/tui/internal/components/dialog/help.go
+++ b/packages/tui/internal/components/dialog/help.go
@@ -3,28 +3,29 @@ package dialog
import (
"strings"
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
+ "github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
)
-type helpCmp struct {
+type helpComponent struct {
width int
height int
keys []key.Binding
}
-func (h *helpCmp) Init() tea.Cmd {
+func (h *helpComponent) Init() tea.Cmd {
return nil
}
-func (h *helpCmp) SetBindings(k []key.Binding) {
+func (h *helpComponent) SetBindings(k []key.Binding) {
h.keys = k
}
-func (h *helpCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+func (h *helpComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
h.width = 90
@@ -53,7 +54,7 @@ func removeDuplicateBindings(bindings []key.Binding) []key.Binding {
return result
}
-func (h *helpCmp) render() string {
+func (h *helpComponent) render() string {
t := theme.CurrentTheme()
baseStyle := styles.BaseStyle()
@@ -134,7 +135,7 @@ func (h *helpCmp) render() string {
pairs = append(pairs, pair)
}
- // https://github.com/charmbracelet/lipgloss/issues/209
+ // https://github.com/charmbracelet/lipgloss/v2/issues/209
if len(pairs) > 1 {
prefix := pairs[:len(pairs)-1]
lastPair := pairs[len(pairs)-1]
@@ -144,7 +145,7 @@ func (h *helpCmp) render() string {
lipgloss.Left, // x
lipgloss.Top, // y
lastPair, // content
- lipgloss.WithWhitespaceBackground(t.Background()),
+ // lipgloss.WithWhitespaceBackground(t.Background()),
))
content := baseStyle.Width(h.width).Render(
lipgloss.JoinHorizontal(
@@ -165,7 +166,7 @@ func (h *helpCmp) render() string {
return content
}
-func (h *helpCmp) View() string {
+func (h *helpComponent) View() string {
t := theme.CurrentTheme()
baseStyle := styles.BaseStyle()
@@ -190,11 +191,11 @@ func (h *helpCmp) View() string {
)
}
-type HelpCmp interface {
- tea.Model
+type HelpComponent interface {
+ layout.ModelWithView
SetBindings([]key.Binding)
}
-func NewHelpCmp() HelpCmp {
- return &helpCmp{}
+func NewHelpCmp() HelpComponent {
+ return &helpComponent{}
}
diff --git a/packages/tui/internal/components/dialog/init.go b/packages/tui/internal/components/dialog/init.go
index 01bdbe577..d939427c1 100644
--- a/packages/tui/internal/components/dialog/init.go
+++ b/packages/tui/internal/components/dialog/init.go
@@ -1,9 +1,9 @@
package dialog
import (
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
diff --git a/packages/tui/internal/components/dialog/models.go b/packages/tui/internal/components/dialog/models.go
index 5d0ee772b..50d1791cd 100644
--- a/packages/tui/internal/components/dialog/models.go
+++ b/packages/tui/internal/components/dialog/models.go
@@ -7,9 +7,9 @@ import (
"slices"
"strings"
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
@@ -31,13 +31,13 @@ type CloseModelDialogMsg struct {
// ModelDialog interface for the model selection dialog
type ModelDialog interface {
- tea.Model
+ layout.ModelWithView
layout.Bindings
SetProviders(providers []client.ProviderInfo)
}
-type modelDialogCmp struct {
+type modelDialogComponent struct {
app *app.App
availableProviders []client.ProviderInfo
provider client.ProviderInfo
@@ -106,7 +106,7 @@ var modelKeys = modelKeyMap{
),
}
-func (m *modelDialogCmp) Init() tea.Cmd {
+func (m *modelDialogComponent) Init() tea.Cmd {
// cfg := config.Get()
// modelInfo := GetSelectedModel(cfg)
// m.availableProviders = getEnabledProviders(cfg)
@@ -125,11 +125,11 @@ func (m *modelDialogCmp) Init() tea.Cmd {
return nil
}
-func (m *modelDialogCmp) SetProviders(providers []client.ProviderInfo) {
+func (m *modelDialogComponent) SetProviders(providers []client.ProviderInfo) {
m.availableProviders = providers
}
-func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+func (m *modelDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch {
@@ -159,7 +159,7 @@ func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, nil
}
-func (m *modelDialogCmp) models() []client.ProviderModel {
+func (m *modelDialogComponent) models() []client.ProviderModel {
models := slices.SortedFunc(maps.Values(m.provider.Models), func(a, b client.ProviderModel) int {
return strings.Compare(*a.Name, *b.Name)
})
@@ -167,7 +167,7 @@ func (m *modelDialogCmp) models() []client.ProviderModel {
}
// moveSelectionUp moves the selection up or wraps to bottom
-func (m *modelDialogCmp) moveSelectionUp() {
+func (m *modelDialogComponent) moveSelectionUp() {
if m.selectedIdx > 0 {
m.selectedIdx--
} else {
@@ -182,7 +182,7 @@ func (m *modelDialogCmp) moveSelectionUp() {
}
// moveSelectionDown moves the selection down or wraps to top
-func (m *modelDialogCmp) moveSelectionDown() {
+func (m *modelDialogComponent) moveSelectionDown() {
if m.selectedIdx < len(m.provider.Models)-1 {
m.selectedIdx++
} else {
@@ -196,7 +196,7 @@ func (m *modelDialogCmp) moveSelectionDown() {
}
}
-func (m *modelDialogCmp) switchProvider(offset int) {
+func (m *modelDialogComponent) switchProvider(offset int) {
newOffset := m.hScrollOffset + offset
// Ensure we stay within bounds
@@ -212,7 +212,7 @@ func (m *modelDialogCmp) switchProvider(offset int) {
m.setupModelsForProvider(m.provider.Id)
}
-func (m *modelDialogCmp) View() string {
+func (m *modelDialogComponent) View() string {
t := theme.CurrentTheme()
baseStyle := styles.BaseStyle()
@@ -255,7 +255,7 @@ func (m *modelDialogCmp) View() string {
Render(content)
}
-func (m *modelDialogCmp) getScrollIndicators(maxWidth int) string {
+func (m *modelDialogComponent) getScrollIndicators(maxWidth int) string {
var indicator string
if len(m.provider.Models) > numVisibleModels {
@@ -291,7 +291,7 @@ func (m *modelDialogCmp) getScrollIndicators(maxWidth int) string {
Render(indicator)
}
-func (m *modelDialogCmp) BindingKeys() []key.Binding {
+func (m *modelDialogComponent) BindingKeys() []key.Binding {
return layout.KeyMapToSlice(modelKeys)
}
@@ -305,7 +305,7 @@ func (m *modelDialogCmp) BindingKeys() []key.Binding {
// return -1
// }
-func (m *modelDialogCmp) setupModelsForProvider(_ string) {
+func (m *modelDialogComponent) setupModelsForProvider(_ string) {
m.selectedIdx = 0
m.scrollOffset = 0
@@ -332,7 +332,7 @@ func (m *modelDialogCmp) setupModelsForProvider(_ string) {
}
func NewModelDialogCmp(app *app.App) ModelDialog {
- return &modelDialogCmp{
+ return &modelDialogComponent{
app: app,
}
}
diff --git a/packages/tui/internal/components/dialog/permission.go b/packages/tui/internal/components/dialog/permission.go
index bb71fc35d..526e03483 100644
--- a/packages/tui/internal/components/dialog/permission.go
+++ b/packages/tui/internal/components/dialog/permission.go
@@ -2,10 +2,10 @@ package dialog
import (
"fmt"
- "github.com/charmbracelet/bubbles/key"
- "github.com/charmbracelet/bubbles/viewport"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ "github.com/charmbracelet/bubbles/v2/viewport"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
@@ -28,9 +28,9 @@ type PermissionResponseMsg struct {
Action PermissionAction
}
-// PermissionDialogCmp interface for permission dialog component
-type PermissionDialogCmp interface {
- tea.Model
+// PermissionDialogComponent interface for permission dialog component
+type PermissionDialogComponent interface {
+ layout.ModelWithView
layout.Bindings
// SetPermissions(permission permission.PermissionRequest) tea.Cmd
}
@@ -76,8 +76,8 @@ var permissionsKeys = permissionsMapping{
),
}
-// permissionDialogCmp is the implementation of PermissionDialog
-type permissionDialogCmp struct {
+// permissionDialogComponent is the implementation of PermissionDialog
+type permissionDialogComponent struct {
width int
height int
// permission permission.PermissionRequest
@@ -89,11 +89,11 @@ type permissionDialogCmp struct {
markdownCache map[string]string
}
-func (p *permissionDialogCmp) Init() tea.Cmd {
+func (p *permissionDialogComponent) Init() tea.Cmd {
return p.contentViewPort.Init()
}
-func (p *permissionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+func (p *permissionDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
@@ -129,7 +129,7 @@ func (p *permissionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return p, tea.Batch(cmds...)
}
-func (p *permissionDialogCmp) selectCurrentOption() tea.Cmd {
+func (p *permissionDialogComponent) selectCurrentOption() tea.Cmd {
var action PermissionAction
switch p.selectedOption {
@@ -144,7 +144,7 @@ func (p *permissionDialogCmp) selectCurrentOption() tea.Cmd {
return util.CmdHandler(PermissionResponseMsg{Action: action}) // , Permission: p.permission})
}
-func (p *permissionDialogCmp) renderButtons() string {
+func (p *permissionDialogComponent) renderButtons() string {
t := theme.CurrentTheme()
baseStyle := styles.BaseStyle()
@@ -190,7 +190,7 @@ func (p *permissionDialogCmp) renderButtons() string {
return content
}
-func (p *permissionDialogCmp) renderHeader() string {
+func (p *permissionDialogComponent) renderHeader() string {
return "NOT IMPLEMENTED"
// t := theme.CurrentTheme()
// baseStyle := styles.BaseStyle()
@@ -246,7 +246,7 @@ func (p *permissionDialogCmp) renderHeader() string {
// return lipgloss.NewStyle().Background(t.Background()).Render(lipgloss.JoinVertical(lipgloss.Left, headerParts...))
}
-func (p *permissionDialogCmp) renderBashContent() string {
+func (p *permissionDialogComponent) renderBashContent() string {
// t := theme.CurrentTheme()
// baseStyle := styles.BaseStyle()
//
@@ -269,7 +269,7 @@ func (p *permissionDialogCmp) renderBashContent() string {
return ""
}
-func (p *permissionDialogCmp) renderEditContent() string {
+func (p *permissionDialogComponent) renderEditContent() string {
// if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
// return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
@@ -281,7 +281,7 @@ func (p *permissionDialogCmp) renderEditContent() string {
return ""
}
-func (p *permissionDialogCmp) renderPatchContent() string {
+func (p *permissionDialogComponent) renderPatchContent() string {
// if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
// return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
@@ -293,7 +293,7 @@ func (p *permissionDialogCmp) renderPatchContent() string {
return ""
}
-func (p *permissionDialogCmp) renderWriteContent() string {
+func (p *permissionDialogComponent) renderWriteContent() string {
// if pr, ok := p.permission.Params.(tools.WritePermissionsParams); ok {
// // Use the cache for diff rendering
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
@@ -306,7 +306,7 @@ func (p *permissionDialogCmp) renderWriteContent() string {
return ""
}
-func (p *permissionDialogCmp) renderFetchContent() string {
+func (p *permissionDialogComponent) renderFetchContent() string {
// t := theme.CurrentTheme()
// baseStyle := styles.BaseStyle()
//
@@ -329,7 +329,7 @@ func (p *permissionDialogCmp) renderFetchContent() string {
return ""
}
-func (p *permissionDialogCmp) renderDefaultContent() string {
+func (p *permissionDialogComponent) renderDefaultContent() string {
// t := theme.CurrentTheme()
// baseStyle := styles.BaseStyle()
//
@@ -354,7 +354,7 @@ func (p *permissionDialogCmp) renderDefaultContent() string {
return p.styleViewport()
}
-func (p *permissionDialogCmp) styleViewport() string {
+func (p *permissionDialogComponent) styleViewport() string {
t := theme.CurrentTheme()
contentStyle := lipgloss.NewStyle().
Background(t.Background())
@@ -362,7 +362,7 @@ func (p *permissionDialogCmp) styleViewport() string {
return contentStyle.Render(p.contentViewPort.View())
}
-func (p *permissionDialogCmp) render() string {
+func (p *permissionDialogComponent) render() string {
return "NOT IMPLEMENTED"
// t := theme.CurrentTheme()
// baseStyle := styles.BaseStyle()
@@ -420,15 +420,15 @@ func (p *permissionDialogCmp) render() string {
// )
}
-func (p *permissionDialogCmp) View() string {
+func (p *permissionDialogComponent) View() string {
return p.render()
}
-func (p *permissionDialogCmp) BindingKeys() []key.Binding {
+func (p *permissionDialogComponent) BindingKeys() []key.Binding {
return layout.KeyMapToSlice(permissionsKeys)
}
-func (p *permissionDialogCmp) SetSize() tea.Cmd {
+func (p *permissionDialogComponent) SetSize() tea.Cmd {
// if p.permission.ID == "" {
// return nil
// }
@@ -458,7 +458,7 @@ func (p *permissionDialogCmp) SetSize() tea.Cmd {
// }
// Helper to get or set cached diff content
-func (c *permissionDialogCmp) GetOrSetDiff(key string, generator func() (string, error)) string {
+func (c *permissionDialogComponent) GetOrSetDiff(key string, generator func() (string, error)) string {
if cached, ok := c.diffCache[key]; ok {
return cached
}
@@ -474,7 +474,7 @@ func (c *permissionDialogCmp) GetOrSetDiff(key string, generator func() (string,
}
// Helper to get or set cached markdown content
-func (c *permissionDialogCmp) GetOrSetMarkdown(key string, generator func() (string, error)) string {
+func (c *permissionDialogComponent) GetOrSetMarkdown(key string, generator func() (string, error)) string {
if cached, ok := c.markdownCache[key]; ok {
return cached
}
@@ -489,11 +489,11 @@ func (c *permissionDialogCmp) GetOrSetMarkdown(key string, generator func() (str
return content
}
-func NewPermissionDialogCmp() PermissionDialogCmp {
+func NewPermissionDialogCmp() PermissionDialogComponent {
// Create viewport for content
- contentViewport := viewport.New(0, 0)
+ contentViewport := viewport.New() // (0, 0)
- return &permissionDialogCmp{
+ return &permissionDialogComponent{
contentViewPort: contentViewport,
selectedOption: 0, // Default to "Allow"
diffCache: make(map[string]string),
diff --git a/packages/tui/internal/components/dialog/quit.go b/packages/tui/internal/components/dialog/quit.go
index 78034c714..8362e7672 100644
--- a/packages/tui/internal/components/dialog/quit.go
+++ b/packages/tui/internal/components/dialog/quit.go
@@ -3,9 +3,9 @@ package dialog
import (
"strings"
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
@@ -17,11 +17,11 @@ const question = "Are you sure you want to quit?"
type CloseQuitMsg struct{}
type QuitDialog interface {
- tea.Model
+ layout.ModelWithView
layout.Bindings
}
-type quitDialogCmp struct {
+type quitDialogComponent struct {
selectedNo bool
}
@@ -56,11 +56,11 @@ var helpKeys = helpMapping{
),
}
-func (q *quitDialogCmp) Init() tea.Cmd {
+func (q *quitDialogComponent) Init() tea.Cmd {
return nil
}
-func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+func (q *quitDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch {
@@ -81,7 +81,7 @@ func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return q, nil
}
-func (q *quitDialogCmp) View() string {
+func (q *quitDialogComponent) View() string {
t := theme.CurrentTheme()
baseStyle := styles.BaseStyle()
@@ -125,12 +125,12 @@ func (q *quitDialogCmp) View() string {
Render(content)
}
-func (q *quitDialogCmp) BindingKeys() []key.Binding {
+func (q *quitDialogComponent) BindingKeys() []key.Binding {
return layout.KeyMapToSlice(helpKeys)
}
func NewQuitCmp() QuitDialog {
- return &quitDialogCmp{
+ return &quitDialogComponent{
selectedNo: true,
}
}
diff --git a/packages/tui/internal/components/dialog/session.go b/packages/tui/internal/components/dialog/session.go
index 2d234529e..8ef9a701f 100644
--- a/packages/tui/internal/components/dialog/session.go
+++ b/packages/tui/internal/components/dialog/session.go
@@ -1,9 +1,9 @@
package dialog
import (
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
@@ -18,13 +18,13 @@ type CloseSessionDialogMsg struct {
// SessionDialog interface for the session switching dialog
type SessionDialog interface {
- tea.Model
+ layout.ModelWithView
layout.Bindings
SetSessions(sessions []client.SessionInfo)
SetSelectedSession(sessionID string)
}
-type sessionDialogCmp struct {
+type sessionDialogComponent struct {
sessions []client.SessionInfo
selectedIdx int
width int
@@ -68,11 +68,11 @@ var sessionKeys = sessionKeyMap{
),
}
-func (s *sessionDialogCmp) Init() tea.Cmd {
+func (s *sessionDialogComponent) Init() tea.Cmd {
return nil
}
-func (s *sessionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+func (s *sessionDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
s.width = msg.Width
@@ -105,7 +105,7 @@ func (s *sessionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return s, nil
}
-func (s *sessionDialogCmp) View() string {
+func (s *sessionDialogComponent) View() string {
t := theme.CurrentTheme()
baseStyle := styles.BaseStyle()
@@ -185,11 +185,11 @@ func (s *sessionDialogCmp) View() string {
Render(content)
}
-func (s *sessionDialogCmp) BindingKeys() []key.Binding {
+func (s *sessionDialogComponent) BindingKeys() []key.Binding {
return layout.KeyMapToSlice(sessionKeys)
}
-func (s *sessionDialogCmp) SetSessions(sessions []client.SessionInfo) {
+func (s *sessionDialogComponent) SetSessions(sessions []client.SessionInfo) {
s.sessions = sessions
// If we have a selected session ID, find its index
@@ -206,7 +206,7 @@ func (s *sessionDialogCmp) SetSessions(sessions []client.SessionInfo) {
s.selectedIdx = 0
}
-func (s *sessionDialogCmp) SetSelectedSession(sessionID string) {
+func (s *sessionDialogComponent) SetSelectedSession(sessionID string) {
s.selectedSessionID = sessionID
// Update the selected index if sessions are already loaded
@@ -222,7 +222,7 @@ func (s *sessionDialogCmp) SetSelectedSession(sessionID string) {
// NewSessionDialogCmp creates a new session switching dialog
func NewSessionDialogCmp() SessionDialog {
- return &sessionDialogCmp{
+ return &sessionDialogComponent{
sessions: []client.SessionInfo{},
selectedIdx: 0,
selectedSessionID: "",
diff --git a/packages/tui/internal/components/dialog/theme.go b/packages/tui/internal/components/dialog/theme.go
index 42c777c41..4704cb42e 100644
--- a/packages/tui/internal/components/dialog/theme.go
+++ b/packages/tui/internal/components/dialog/theme.go
@@ -1,9 +1,9 @@
package dialog
import (
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/status"
"github.com/sst/opencode/internal/styles"
@@ -21,11 +21,11 @@ type CloseThemeDialogMsg struct{}
// ThemeDialog interface for the theme switching dialog
type ThemeDialog interface {
- tea.Model
+ layout.ModelWithView
layout.Bindings
}
-type themeDialogCmp struct {
+type themeDialogComponent struct {
themes []string
selectedIdx int
width int
@@ -69,7 +69,7 @@ var themeKeys = themeKeyMap{
),
}
-func (t *themeDialogCmp) Init() tea.Cmd {
+func (t *themeDialogComponent) Init() tea.Cmd {
// Load available themes and update selectedIdx based on current theme
t.themes = theme.AvailableThemes()
t.currentTheme = theme.CurrentThemeName()
@@ -85,7 +85,7 @@ func (t *themeDialogCmp) Init() tea.Cmd {
return nil
}
-func (t *themeDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+func (t *themeDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch {
@@ -124,7 +124,7 @@ func (t *themeDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return t, nil
}
-func (t *themeDialogCmp) View() string {
+func (t *themeDialogComponent) View() string {
currentTheme := theme.CurrentTheme()
baseStyle := styles.BaseStyle()
@@ -185,13 +185,13 @@ func (t *themeDialogCmp) View() string {
Render(content)
}
-func (t *themeDialogCmp) BindingKeys() []key.Binding {
+func (t *themeDialogComponent) BindingKeys() []key.Binding {
return layout.KeyMapToSlice(themeKeys)
}
// NewThemeDialogCmp creates a new theme switching dialog
func NewThemeDialogCmp() ThemeDialog {
- return &themeDialogCmp{
+ return &themeDialogComponent{
themes: []string{},
selectedIdx: 0,
currentTheme: "",
diff --git a/packages/tui/internal/components/dialog/tools.go b/packages/tui/internal/components/dialog/tools.go
index a01d1911b..c91dfef9a 100644
--- a/packages/tui/internal/components/dialog/tools.go
+++ b/packages/tui/internal/components/dialog/tools.go
@@ -1,9 +1,9 @@
package dialog
import (
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
utilComponents "github.com/sst/opencode/internal/components/util"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
@@ -17,7 +17,7 @@ const (
// ToolsDialog interface for the tools list dialog
type ToolsDialog interface {
- tea.Model
+ layout.ModelWithView
layout.Bindings
SetTools(tools []string)
}
@@ -39,7 +39,7 @@ func (t toolItem) Render(selected bool, width int) string {
baseStyle := styles.BaseStyle().
Width(width).
Background(th.Background())
-
+
if selected {
baseStyle = baseStyle.
Background(th.Primary()).
@@ -49,15 +49,15 @@ func (t toolItem) Render(selected bool, width int) string {
baseStyle = baseStyle.
Foreground(th.Text())
}
-
+
return baseStyle.Render(t.name)
}
-type toolsDialogCmp struct {
- tools []toolItem
- width int
- height int
- list utilComponents.SimpleList[toolItem]
+type toolsDialogComponent struct {
+ tools []toolItem
+ width int
+ height int
+ list utilComponents.SimpleList[toolItem]
}
type toolsKeyMap struct {
@@ -91,21 +91,21 @@ var toolsKeys = toolsKeyMap{
),
}
-func (m *toolsDialogCmp) Init() tea.Cmd {
+func (m *toolsDialogComponent) Init() tea.Cmd {
return nil
}
-func (m *toolsDialogCmp) SetTools(tools []string) {
+func (m *toolsDialogComponent) SetTools(tools []string) {
var toolItems []toolItem
for _, name := range tools {
toolItems = append(toolItems, toolItem{name: name})
}
-
+
m.tools = toolItems
m.list.SetItems(toolItems)
}
-func (m *toolsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+func (m *toolsDialogComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch {
@@ -130,7 +130,7 @@ func (m *toolsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, cmd
}
-func (m *toolsDialogCmp) View() string {
+func (m *toolsDialogComponent) View() string {
t := theme.CurrentTheme()
baseStyle := styles.BaseStyle().Background(t.Background())
@@ -144,7 +144,7 @@ func (m *toolsDialogCmp) View() string {
// Calculate dialog width based on content
dialogWidth := min(maxToolsDialogWidth, m.width/2)
m.list.SetMaxWidth(dialogWidth)
-
+
content := lipgloss.JoinVertical(
lipgloss.Left,
title,
@@ -160,7 +160,7 @@ func (m *toolsDialogCmp) View() string {
Render(content)
}
-func (m *toolsDialogCmp) BindingKeys() []key.Binding {
+func (m *toolsDialogComponent) BindingKeys() []key.Binding {
return layout.KeyMapToSlice(toolsKeys)
}
@@ -171,8 +171,8 @@ func NewToolsDialogCmp() ToolsDialog {
"No tools available",
true,
)
-
- return &toolsDialogCmp{
+
+ return &toolsDialogComponent{
list: list,
}
}
diff --git a/packages/tui/internal/components/diff/diff.go b/packages/tui/internal/components/diff/diff.go
index 65874ebb4..4551cf736 100644
--- a/packages/tui/internal/components/diff/diff.go
+++ b/packages/tui/internal/components/diff/diff.go
@@ -3,6 +3,7 @@ package diff
import (
"bytes"
"fmt"
+ "image/color"
"io"
"regexp"
"strconv"
@@ -12,9 +13,11 @@ import (
"github.com/alecthomas/chroma/v2/formatters"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/styles"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/lipgloss/v2"
+ "github.com/charmbracelet/lipgloss/v2/compat"
"github.com/charmbracelet/x/ansi"
"github.com/sergi/go-diff/diffmatchpatch"
+ stylesi "github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
)
@@ -300,7 +303,7 @@ func pairLines(lines []DiffLine) []linePair {
// -------------------------------------------------------------------------
// SyntaxHighlight applies syntax highlighting to text based on file extension
-func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg lipgloss.TerminalColor) error {
+func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg color.Color) error {
t := theme.CurrentTheme()
// Determine the language lexer to use
@@ -509,15 +512,12 @@ func SyntaxHighlight(w io.Writer, source, fileName, formatter string, bg lipglos
}
// getColor returns the appropriate hex color string based on terminal background
-func getColor(adaptiveColor lipgloss.AdaptiveColor) string {
- if lipgloss.HasDarkBackground() {
- return adaptiveColor.Dark
- }
- return adaptiveColor.Light
+func getColor(adaptiveColor compat.AdaptiveColor) string {
+ return stylesi.AdaptiveColorToString(adaptiveColor)
}
// highlightLine applies syntax highlighting to a single line
-func highlightLine(fileName string, line string, bg lipgloss.TerminalColor) string {
+func highlightLine(fileName string, line string, bg color.Color) string {
var buf bytes.Buffer
err := SyntaxHighlight(&buf, line, fileName, "terminal16m", bg)
if err != nil {
@@ -540,7 +540,7 @@ func createStyles(t theme.Theme) (removedLineStyle, addedLineStyle, contextLineS
// -------------------------------------------------------------------------
// applyHighlighting applies intra-line highlighting to a piece of text
-func applyHighlighting(content string, segments []Segment, segmentType LineType, highlightBg lipgloss.AdaptiveColor) string {
+func applyHighlighting(content string, segments []Segment, segmentType LineType, highlightBg compat.AdaptiveColor) string {
// Find all ANSI sequences in the content
ansiRegex := regexp.MustCompile(`\x1b(?:[@-Z\\-_]|\[[0-9?]*(?:;[0-9?]*)*[@-~])`)
ansiMatches := ansiRegex.FindAllStringIndex(content, -1)
@@ -662,7 +662,7 @@ func renderDiffColumnLine(
var bgStyle lipgloss.Style
var lineNum string
var highlightType LineType
- var highlightColor lipgloss.AdaptiveColor
+ var highlightColor compat.AdaptiveColor
if isLeftColumn {
// Left column logic
diff --git a/packages/tui/internal/components/qr/qr.go b/packages/tui/internal/components/qr/qr.go
index df51a644d..82d597a3f 100644
--- a/packages/tui/internal/components/qr/qr.go
+++ b/packages/tui/internal/components/qr/qr.go
@@ -3,7 +3,7 @@ package qr
import (
"strings"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/theme"
"rsc.io/qr"
)
diff --git a/packages/tui/internal/components/util/simple-list.go b/packages/tui/internal/components/util/simple-list.go
index 0c0bb6556..d6e27db14 100644
--- a/packages/tui/internal/components/util/simple-list.go
+++ b/packages/tui/internal/components/util/simple-list.go
@@ -1,9 +1,9 @@
package utilComponents
import (
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/layout"
"github.com/sst/opencode/internal/styles"
"github.com/sst/opencode/internal/theme"
@@ -14,7 +14,7 @@ type SimpleListItem interface {
}
type SimpleList[T SimpleListItem] interface {
- tea.Model
+ layout.ModelWithView
layout.Bindings
SetMaxWidth(maxWidth int)
GetSelectedItem() (item T, idx int)
diff --git a/packages/tui/internal/image/images.go b/packages/tui/internal/image/images.go
index f476b201c..742eb30a8 100644
--- a/packages/tui/internal/image/images.go
+++ b/packages/tui/internal/image/images.go
@@ -4,11 +4,12 @@ import (
"bytes"
"fmt"
"image"
+ "image/color"
"image/png"
"os"
"strings"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/disintegration/imaging"
"github.com/lucasb-eyer/go-colorful"
_ "golang.org/x/image/webp"
@@ -39,7 +40,7 @@ func ToString(width int, img image.Image) string {
c1, _ := colorful.MakeColor(img.At(x, heightCounter))
color1 := lipgloss.Color(c1.Hex())
- var color2 lipgloss.Color
+ var color2 color.Color
if heightCounter+1 < h {
c2, _ := colorful.MakeColor(img.At(x, heightCounter+1))
color2 = lipgloss.Color(c2.Hex())
@@ -76,10 +77,10 @@ func ImagePreview(width int, filename string) (string, error) {
func ImageToBytes(image image.Image) ([]byte, error) {
buf := new(bytes.Buffer)
- err := png.Encode(buf, image)
- if err != nil {
- return nil, err
- }
-
- return buf.Bytes(), nil
+ err := png.Encode(buf, image)
+ if err != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
}
diff --git a/packages/tui/internal/layout/container.go b/packages/tui/internal/layout/container.go
index 1c12ef6a1..2bed6708f 100644
--- a/packages/tui/internal/layout/container.go
+++ b/packages/tui/internal/layout/container.go
@@ -1,14 +1,19 @@
package layout
import (
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/theme"
)
-type Container interface {
+type ModelWithView interface {
tea.Model
+ tea.ViewModel
+}
+
+type Container interface {
+ ModelWithView
Sizeable
Bindings
Focus()
@@ -21,7 +26,7 @@ type container struct {
width int
height int
- content tea.Model
+ content ModelWithView
paddingTop int
paddingRight int
@@ -46,7 +51,7 @@ func (c *container) Init() tea.Cmd {
func (c *container) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
u, cmd := c.content.Update(msg)
- c.content = u
+ c.content = u.(ModelWithView)
return c, cmd
}
@@ -175,7 +180,7 @@ func (c *container) Blur() {
type ContainerOption func(*container)
-func NewContainer(content tea.Model, options ...ContainerOption) Container {
+func NewContainer(content ModelWithView, options ...ContainerOption) Container {
c := &container{
content: content,
borderStyle: lipgloss.NormalBorder(),
diff --git a/packages/tui/internal/layout/flex.go b/packages/tui/internal/layout/flex.go
index a0882196e..292cfcb0f 100644
--- a/packages/tui/internal/layout/flex.go
+++ b/packages/tui/internal/layout/flex.go
@@ -1,10 +1,9 @@
package layout
import (
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
- "github.com/sst/opencode/internal/theme"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
)
type FlexDirection int
@@ -26,7 +25,7 @@ func FlexPaneSizeFixed(size int) FlexPaneSize {
}
type FlexLayout interface {
- tea.Model
+ ModelWithView
Sizeable
Bindings
SetPanes(panes []Container) tea.Cmd
@@ -75,8 +74,6 @@ func (f *flexLayout) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
func (f *flexLayout) View() string {
- t := theme.CurrentTheme()
-
if len(f.panes) == 0 {
return ""
}
@@ -94,7 +91,6 @@ func (f *flexLayout) View() string {
paneWidth,
pane.Alignment(),
pane.View(),
- lipgloss.WithWhitespaceBackground(t.Background()),
)
views = append(views, view)
} else {
@@ -105,7 +101,6 @@ func (f *flexLayout) View() string {
lipgloss.Center,
pane.Alignment(),
pane.View(),
- lipgloss.WithWhitespaceBackground(t.Background()),
)
views = append(views, view)
}
@@ -245,4 +240,3 @@ func WithPaneSizes(sizes ...FlexPaneSize) FlexLayoutOption {
f.sizes = sizes
}
}
-
diff --git a/packages/tui/internal/layout/layout.go b/packages/tui/internal/layout/layout.go
index 05f07f1a2..9a7fefcad 100644
--- a/packages/tui/internal/layout/layout.go
+++ b/packages/tui/internal/layout/layout.go
@@ -3,8 +3,8 @@ package layout
import (
"reflect"
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
)
var Current *LayoutInfo
diff --git a/packages/tui/internal/layout/overlay.go b/packages/tui/internal/layout/overlay.go
index bc349096a..c2cd54b1a 100644
--- a/packages/tui/internal/layout/overlay.go
+++ b/packages/tui/internal/layout/overlay.go
@@ -3,7 +3,7 @@ package layout
import (
"strings"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/lipgloss/v2"
chAnsi "github.com/charmbracelet/x/ansi"
"github.com/muesli/ansi"
"github.com/muesli/reflow/truncate"
@@ -14,7 +14,7 @@ import (
)
// Most of this code is borrowed from
-// https://github.com/charmbracelet/lipgloss/pull/102
+// https://github.com/charmbracelet/lipgloss/v2/pull/102
// as well as the lipgloss library, with some modification for what I needed.
// Split a string into lines, additionally returning the size of the widest line.
diff --git a/packages/tui/internal/page/chat.go b/packages/tui/internal/page/chat.go
index 6c4227674..906dc70ae 100644
--- a/packages/tui/internal/page/chat.go
+++ b/packages/tui/internal/page/chat.go
@@ -4,9 +4,9 @@ import (
"context"
"strings"
- "github.com/charmbracelet/bubbles/key"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/key"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/completions"
"github.com/sst/opencode/internal/components/chat"
@@ -187,7 +187,7 @@ func (p *chatPage) BindingKeys() []key.Binding {
return bindings
}
-func NewChatPage(app *app.App) tea.Model {
+func NewChatPage(app *app.App) layout.ModelWithView {
cg := completions.NewFileAndFolderContextGroup()
completionDialog := dialog.NewCompletionDialogCmp(cg)
messagesContainer := layout.NewContainer(
diff --git a/packages/tui/internal/styles/background.go b/packages/tui/internal/styles/background.go
index 2fbb34efb..6db130c0e 100644
--- a/packages/tui/internal/styles/background.go
+++ b/packages/tui/internal/styles/background.go
@@ -1,123 +1,13 @@
package styles
-import (
- "fmt"
- "regexp"
- "strings"
-
- "github.com/charmbracelet/lipgloss"
-)
-
-var ansiEscape = regexp.MustCompile("\x1b\\[[0-9;]*m")
-
-func getColorRGB(c lipgloss.TerminalColor) (uint8, uint8, uint8) {
- r, g, b, a := c.RGBA()
-
- // Un-premultiply alpha if needed
- if a > 0 && a < 0xffff {
- r = (r * 0xffff) / a
- g = (g * 0xffff) / a
- b = (b * 0xffff) / a
- }
-
- // Convert from 16-bit to 8-bit color
- return uint8(r >> 8), uint8(g >> 8), uint8(b >> 8)
+type TerminalInfo struct {
+ BackgroundIsDark bool
}
-// ForceReplaceBackgroundWithLipgloss replaces any ANSI background color codes
-// in `input` with a single 24‑bit background (48;2;R;G;B).
-func ForceReplaceBackgroundWithLipgloss(input string, newBgColor lipgloss.TerminalColor) string {
- // Precompute our new-bg sequence once
- r, g, b := getColorRGB(newBgColor)
- newBg := fmt.Sprintf("48;2;%d;%d;%d", r, g, b)
-
- return ansiEscape.ReplaceAllStringFunc(input, func(seq string) string {
- const (
- escPrefixLen = 2 // "\x1b["
- escSuffixLen = 1 // "m"
- )
-
- raw := seq
- start := escPrefixLen
- end := len(raw) - escSuffixLen
+var Terminal *TerminalInfo
- var sb strings.Builder
- // reserve enough space: original content minus bg codes + our newBg
- sb.Grow((end - start) + len(newBg) + 2)
-
- // scan from start..end, token by token
- for i := start; i < end; {
- // find the next ';' or end
- j := i
- for j < end && raw[j] != ';' {
- j++
- }
- token := raw[i:j]
-
- // fast‑path: skip "48;5;N" or "48;2;R;G;B"
- if len(token) == 2 && token[0] == '4' && token[1] == '8' {
- k := j + 1
- if k < end {
- // find next token
- l := k
- for l < end && raw[l] != ';' {
- l++
- }
- next := raw[k:l]
- if next == "5" {
- // skip "48;5;N"
- m := l + 1
- for m < end && raw[m] != ';' {
- m++
- }
- i = m + 1
- continue
- } else if next == "2" {
- // skip "48;2;R;G;B"
- m := l + 1
- for count := 0; count < 3 && m < end; count++ {
- for m < end && raw[m] != ';' {
- m++
- }
- m++
- }
- i = m
- continue
- }
- }
- }
-
- // decide whether to keep this token
- // manually parse ASCII digits to int
- isNum := true
- val := 0
- for p := i; p < j; p++ {
- c := raw[p]
- if c < '0' || c > '9' {
- isNum = false
- break
- }
- val = val*10 + int(c-'0')
- }
- keep := !isNum ||
- ((val < 40 || val > 47) && (val < 100 || val > 107) && val != 49)
-
- if keep {
- if sb.Len() > 0 {
- sb.WriteByte(';')
- }
- sb.WriteString(token)
- }
- // advance past this token (and the semicolon)
- i = j + 1
- }
-
- // append our new background
- if sb.Len() > 0 {
- sb.WriteByte(';')
- }
- sb.WriteString(newBg)
-
- return "\x1b[" + sb.String() + "m"
- })
+func init() {
+ Terminal = &TerminalInfo{
+ BackgroundIsDark: false,
+ }
}
diff --git a/packages/tui/internal/styles/markdown.go b/packages/tui/internal/styles/markdown.go
index bacd063cc..a8681e191 100644
--- a/packages/tui/internal/styles/markdown.go
+++ b/packages/tui/internal/styles/markdown.go
@@ -3,7 +3,8 @@ package styles
import (
"github.com/charmbracelet/glamour"
"github.com/charmbracelet/glamour/ansi"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/lipgloss/v2/compat"
+ "github.com/lucasb-eyer/go-colorful"
"github.com/sst/opencode/internal/theme"
)
@@ -15,117 +16,120 @@ func stringPtr(s string) *string { return &s }
func uintPtr(u uint) *uint { return &u }
// returns a glamour TermRenderer configured with the current theme
-func GetMarkdownRenderer(width int) *glamour.TermRenderer {
+func GetMarkdownRenderer(width int, backgroundColor compat.AdaptiveColor) *glamour.TermRenderer {
r, _ := glamour.NewTermRenderer(
- glamour.WithStyles(generateMarkdownStyleConfig()),
+ glamour.WithStyles(generateMarkdownStyleConfig(backgroundColor)),
glamour.WithWordWrap(width),
+ glamour.WithChromaFormatter("terminal16m"),
)
return r
}
// creates an ansi.StyleConfig for markdown rendering
// using adaptive colors from the provided theme.
-func generateMarkdownStyleConfig() ansi.StyleConfig {
+func generateMarkdownStyleConfig(backgroundColor compat.AdaptiveColor) ansi.StyleConfig {
t := theme.CurrentTheme()
+ background := stringPtr(AdaptiveColorToString(backgroundColor))
return ansi.StyleConfig{
Document: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
- BlockPrefix: "",
- BlockSuffix: "",
- Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
+ BlockPrefix: "",
+ BlockSuffix: "",
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
},
},
BlockQuote: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownBlockQuote())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownBlockQuote())),
Italic: boolPtr(true),
Prefix: "┃ ",
},
Indent: uintPtr(1),
- IndentToken: stringPtr(BaseStyle().Render(" ")),
+ IndentToken: stringPtr(" "),
},
List: ansi.StyleList{
LevelIndent: defaultMargin,
StyleBlock: ansi.StyleBlock{
- IndentToken: stringPtr(BaseStyle().Render(" ")),
+ IndentToken: stringPtr(" "),
StylePrimitive: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
},
},
},
Heading: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
BlockSuffix: "\n",
- Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H1: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "# ",
- Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H2: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "## ",
- Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H3: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "### ",
- Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H4: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "#### ",
- Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H5: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "##### ",
- Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
H6: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
Prefix: "###### ",
- Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
Bold: boolPtr(true),
},
},
Strikethrough: ansi.StylePrimitive{
CrossedOut: boolPtr(true),
- Color: stringPtr(adaptiveColorToString(t.TextMuted())),
+ Color: stringPtr(AdaptiveColorToString(t.TextMuted())),
},
Emph: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownEmph())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownEmph())),
Italic: boolPtr(true),
},
Strong: ansi.StylePrimitive{
Bold: boolPtr(true),
- Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownStrong())),
},
HorizontalRule: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownHorizontalRule())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownHorizontalRule())),
Format: "\n─────────────────────────────────────────\n",
},
Item: ansi.StylePrimitive{
BlockPrefix: "• ",
- Color: stringPtr(adaptiveColorToString(t.MarkdownListItem())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownListItem())),
},
Enumeration: ansi.StylePrimitive{
BlockPrefix: ". ",
- Color: stringPtr(adaptiveColorToString(t.MarkdownListEnumeration())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownListEnumeration())),
},
Task: ansi.StyleTask{
StylePrimitive: ansi.StylePrimitive{},
@@ -133,116 +137,147 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
Unticked: "[ ] ",
},
Link: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownLink())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownLink())),
Underline: boolPtr(true),
},
LinkText: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownLinkText())),
Bold: boolPtr(true),
},
Image: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownImage())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownImage())),
Underline: boolPtr(true),
Format: "🖼 {{.text}}",
},
ImageText: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownImageText())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownImageText())),
Format: "{{.text}}",
},
Code: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownCode())),
- Prefix: "",
- Suffix: "",
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownCode())),
+ Prefix: "",
+ Suffix: "",
},
},
CodeBlock: ansi.StyleCodeBlock{
StyleBlock: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
- Prefix: " ",
- Color: stringPtr(adaptiveColorToString(t.MarkdownCodeBlock())),
+ BackgroundColor: background,
+ Prefix: " ",
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownCodeBlock())),
},
},
Chroma: &ansi.Chroma{
+ Background: ansi.StylePrimitive{
+ BackgroundColor: background,
+ },
Text: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
},
Error: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.Error())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.Error())),
},
Comment: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxComment())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxComment())),
},
CommentPreproc: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
Keyword: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
KeywordReserved: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
KeywordNamespace: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
KeywordType: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxType())),
},
Operator: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxOperator())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxOperator())),
},
Punctuation: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxPunctuation())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxPunctuation())),
},
Name: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxVariable())),
},
NameBuiltin: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxVariable())),
},
NameTag: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
NameAttribute: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxFunction())),
},
NameClass: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxType())),
},
NameConstant: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxVariable())),
},
NameDecorator: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxFunction())),
},
NameFunction: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxFunction())),
},
LiteralNumber: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxNumber())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxNumber())),
},
LiteralString: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxString())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxString())),
},
LiteralStringEscape: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
},
GenericDeleted: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.DiffRemoved())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.DiffRemoved())),
},
GenericEmph: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownEmph())),
- Italic: boolPtr(true),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownEmph())),
+ Italic: boolPtr(true),
},
GenericInserted: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.DiffAdded())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.DiffAdded())),
},
GenericStrong: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
- Bold: boolPtr(true),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownStrong())),
+ Bold: boolPtr(true),
},
GenericSubheading: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
+ BackgroundColor: background,
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
},
},
},
@@ -259,24 +294,26 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
},
DefinitionDescription: ansi.StylePrimitive{
BlockPrefix: "\n ❯ ",
- Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownLinkText())),
},
Text: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
},
Paragraph: ansi.StyleBlock{
StylePrimitive: ansi.StylePrimitive{
- Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
+ Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
},
},
}
}
-// adaptiveColorToString converts a lipgloss.AdaptiveColor to the appropriate
+// AdaptiveColorToString converts a compat.AdaptiveColor to the appropriate
// hex color string based on the current terminal background
-func adaptiveColorToString(color lipgloss.AdaptiveColor) string {
- if lipgloss.HasDarkBackground() {
- return color.Dark
+func AdaptiveColorToString(color compat.AdaptiveColor) string {
+ if Terminal.BackgroundIsDark {
+ c1, _ := colorful.MakeColor(color.Dark)
+ return c1.Hex()
}
- return color.Light
+ c1, _ := colorful.MakeColor(color.Light)
+ return c1.Hex()
}
diff --git a/packages/tui/internal/styles/styles.go b/packages/tui/internal/styles/styles.go
index 3916ea12c..4b29091c3 100644
--- a/packages/tui/internal/styles/styles.go
+++ b/packages/tui/internal/styles/styles.go
@@ -1,7 +1,8 @@
package styles
import (
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/lipgloss/v2"
+ "github.com/charmbracelet/lipgloss/v2/compat"
"github.com/sst/opencode/internal/theme"
)
@@ -83,76 +84,76 @@ func DimBorder() lipgloss.Style {
}
// PrimaryColor returns the primary color from the current theme
-func PrimaryColor() lipgloss.AdaptiveColor {
+func PrimaryColor() compat.AdaptiveColor {
return theme.CurrentTheme().Primary()
}
// SecondaryColor returns the secondary color from the current theme
-func SecondaryColor() lipgloss.AdaptiveColor {
+func SecondaryColor() compat.AdaptiveColor {
return theme.CurrentTheme().Secondary()
}
// AccentColor returns the accent color from the current theme
-func AccentColor() lipgloss.AdaptiveColor {
+func AccentColor() compat.AdaptiveColor {
return theme.CurrentTheme().Accent()
}
// ErrorColor returns the error color from the current theme
-func ErrorColor() lipgloss.AdaptiveColor {
+func ErrorColor() compat.AdaptiveColor {
return theme.CurrentTheme().Error()
}
// WarningColor returns the warning color from the current theme
-func WarningColor() lipgloss.AdaptiveColor {
+func WarningColor() compat.AdaptiveColor {
return theme.CurrentTheme().Warning()
}
// SuccessColor returns the success color from the current theme
-func SuccessColor() lipgloss.AdaptiveColor {
+func SuccessColor() compat.AdaptiveColor {
return theme.CurrentTheme().Success()
}
// InfoColor returns the info color from the current theme
-func InfoColor() lipgloss.AdaptiveColor {
+func InfoColor() compat.AdaptiveColor {
return theme.CurrentTheme().Info()
}
// TextColor returns the text color from the current theme
-func TextColor() lipgloss.AdaptiveColor {
+func TextColor() compat.AdaptiveColor {
return theme.CurrentTheme().Text()
}
// TextMutedColor returns the muted text color from the current theme
-func TextMutedColor() lipgloss.AdaptiveColor {
+func TextMutedColor() compat.AdaptiveColor {
return theme.CurrentTheme().TextMuted()
}
// BackgroundColor returns the background color from the current theme
-func BackgroundColor() lipgloss.AdaptiveColor {
+func BackgroundColor() compat.AdaptiveColor {
return theme.CurrentTheme().Background()
}
// BackgroundSubtleColor returns the subtle background color from the current theme
-func BackgroundSubtleColor() lipgloss.AdaptiveColor {
+func BackgroundSubtleColor() compat.AdaptiveColor {
return theme.CurrentTheme().BackgroundSubtle()
}
// BackgroundElementColor returns the darker background color from the current theme
-func BackgroundElementColor() lipgloss.AdaptiveColor {
+func BackgroundElementColor() compat.AdaptiveColor {
return theme.CurrentTheme().BackgroundElement()
}
// BorderColor returns the border color from the current theme
-func BorderColor() lipgloss.AdaptiveColor {
+func BorderColor() compat.AdaptiveColor {
return theme.CurrentTheme().Border()
}
// BorderActiveColor returns the active border color from the current theme
-func BorderActiveColor() lipgloss.AdaptiveColor {
+func BorderActiveColor() compat.AdaptiveColor {
return theme.CurrentTheme().BorderActive()
}
// BorderSubtleColor returns the subtle border color from the current theme
-func BorderSubtleColor() lipgloss.AdaptiveColor {
+func BorderSubtleColor() compat.AdaptiveColor {
return theme.CurrentTheme().BorderSubtle()
}
diff --git a/packages/tui/internal/theme/ayu.go b/packages/tui/internal/theme/ayu.go
deleted file mode 100644
index 947e41e5b..000000000
--- a/packages/tui/internal/theme/ayu.go
+++ /dev/null
@@ -1,276 +0,0 @@
-package theme
-
-import (
- "github.com/charmbracelet/lipgloss"
-)
-
-// AyuDarkTheme implements the Theme interface with Ayu Dark colors.
-type AyuDarkTheme struct {
- BaseTheme
-}
-
-// AyuLightTheme implements the Theme interface with Ayu Light colors.
-type AyuLightTheme struct {
- BaseTheme
-}
-
-// AyuMirageTheme implements the Theme interface with Ayu Mirage colors.
-type AyuMirageTheme struct {
- BaseTheme
-}
-
-// NewAyuDarkTheme creates a new instance of the Ayu Dark theme.
-func NewAyuDarkTheme() *AyuDarkTheme {
- // Ayu Dark color palette
- darkBackground := "#0f1419"
- darkCurrentLine := "#191f26"
- darkSelection := "#253340"
- darkForeground := "#b3b1ad"
- darkComment := "#5c6773"
- darkBlue := "#53bdfa"
- darkCyan := "#90e1c6"
- darkGreen := "#91b362"
- darkOrange := "#f9af4f"
- darkPurple := "#fae994"
- darkRed := "#ea6c73"
- darkBorder := "#253340"
-
- // Light mode approximation for terminal compatibility
- lightBackground := "#fafafa"
- lightCurrentLine := "#f0f0f0"
- lightSelection := "#d1d1d1"
- lightForeground := "#5c6773"
- lightComment := "#828c99"
- lightBlue := "#3199e1"
- lightCyan := "#46ba94"
- lightGreen := "#7c9f32"
- lightOrange := "#f29718"
- lightPurple := "#9e75c7"
- lightRed := "#f07171"
- lightBorder := "#d1d1d1"
-
- theme := &AyuDarkTheme{}
-
- // Base colors
- theme.PrimaryColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.SecondaryColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.AccentColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
-
- // Status colors
- theme.ErrorColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
- }
- theme.WarningColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.SuccessColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.InfoColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
-
- // Text colors
- theme.TextColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.TextMutedColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
-
- // Background colors
- theme.BackgroundColor = lipgloss.AdaptiveColor{
- Dark: darkBackground,
- Light: lightBackground,
- }
- theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkCurrentLine,
- Light: lightCurrentLine,
- }
- theme.BackgroundElementColor = lipgloss.AdaptiveColor{
- Dark: "#0b0e14", // Darker than background
- Light: "#ffffff", // Lighter than background
- }
-
- // Border colors
- theme.BorderColor = lipgloss.AdaptiveColor{
- Dark: darkBorder,
- Light: lightBorder,
- }
- theme.BorderActiveColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.BorderSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkSelection,
- Light: lightSelection,
- }
-
- // Diff view colors
- theme.DiffAddedColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.DiffRemovedColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
- }
- theme.DiffContextColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
- Dark: "#91b362",
- Light: "#a5d6a7",
- }
- theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#ea6c73",
- Light: "#ef9a9a",
- }
- theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
- Dark: "#1f2c1f",
- Light: "#e8f5e9",
- }
- theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
- Dark: "#2c1f1f",
- Light: "#ffebee",
- }
- theme.DiffContextBgColor = lipgloss.AdaptiveColor{
- Dark: darkBackground,
- Light: lightBackground,
- }
- theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#1a261a",
- Light: "#c8e6c9",
- }
- theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#261a1a",
- Light: "#ffcdd2",
- }
-
- // Markdown colors
- theme.MarkdownTextColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownImageColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
-
- // Syntax highlighting colors
- theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.SyntaxStringColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
-
- return theme
-}
-
-func init() {
- // Register all three Ayu theme variants with the theme manager
- RegisterTheme("ayu", NewAyuDarkTheme())
-}
diff --git a/packages/tui/internal/theme/catppuccin.go b/packages/tui/internal/theme/catppuccin.go
deleted file mode 100644
index 976eb7fbd..000000000
--- a/packages/tui/internal/theme/catppuccin.go
+++ /dev/null
@@ -1,244 +0,0 @@
-package theme
-
-import (
- catppuccin "github.com/catppuccin/go"
- "github.com/charmbracelet/lipgloss"
-)
-
-// CatppuccinTheme implements the Theme interface with Catppuccin colors.
-// It provides both dark (Mocha) and light (Latte) variants.
-type CatppuccinTheme struct {
- BaseTheme
-}
-
-// NewCatppuccinTheme creates a new instance of the Catppuccin theme.
-func NewCatppuccinTheme() *CatppuccinTheme {
- // Get the Catppuccin palettes
- mocha := catppuccin.Mocha
- latte := catppuccin.Latte
-
- theme := &CatppuccinTheme{}
-
- // Base colors
- theme.PrimaryColor = lipgloss.AdaptiveColor{
- Dark: mocha.Blue().Hex,
- Light: latte.Blue().Hex,
- }
- theme.SecondaryColor = lipgloss.AdaptiveColor{
- Dark: mocha.Mauve().Hex,
- Light: latte.Mauve().Hex,
- }
- theme.AccentColor = lipgloss.AdaptiveColor{
- Dark: mocha.Peach().Hex,
- Light: latte.Peach().Hex,
- }
-
- // Status colors
- theme.ErrorColor = lipgloss.AdaptiveColor{
- Dark: mocha.Red().Hex,
- Light: latte.Red().Hex,
- }
- theme.WarningColor = lipgloss.AdaptiveColor{
- Dark: mocha.Peach().Hex,
- Light: latte.Peach().Hex,
- }
- theme.SuccessColor = lipgloss.AdaptiveColor{
- Dark: mocha.Green().Hex,
- Light: latte.Green().Hex,
- }
- theme.InfoColor = lipgloss.AdaptiveColor{
- Dark: mocha.Blue().Hex,
- Light: latte.Blue().Hex,
- }
-
- // Text colors
- theme.TextColor = lipgloss.AdaptiveColor{
- Dark: mocha.Text().Hex,
- Light: latte.Text().Hex,
- }
- theme.TextMutedColor = lipgloss.AdaptiveColor{
- Dark: mocha.Subtext0().Hex,
- Light: latte.Subtext0().Hex,
- }
-
- // Background colors
- theme.BackgroundColor = lipgloss.AdaptiveColor{
- Dark: "#212121", // From existing styles
- Light: "#EEEEEE", // Light equivalent
- }
- theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
- Dark: "#2c2c2c", // From existing styles
- Light: "#E0E0E0", // Light equivalent
- }
- theme.BackgroundElementColor = lipgloss.AdaptiveColor{
- Dark: "#181818", // From existing styles
- Light: "#F5F5F5", // Light equivalent
- }
-
- // Border colors
- theme.BorderColor = lipgloss.AdaptiveColor{
- Dark: "#4b4c5c", // From existing styles
- Light: "#BDBDBD", // Light equivalent
- }
- theme.BorderActiveColor = lipgloss.AdaptiveColor{
- Dark: mocha.Blue().Hex,
- Light: latte.Blue().Hex,
- }
- theme.BorderSubtleColor = lipgloss.AdaptiveColor{
- Dark: mocha.Surface0().Hex,
- Light: latte.Surface0().Hex,
- }
-
- // Diff view colors
- theme.DiffAddedColor = lipgloss.AdaptiveColor{
- Dark: "#478247", // From existing diff.go
- Light: "#2E7D32", // Light equivalent
- }
- theme.DiffRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#7C4444", // From existing diff.go
- Light: "#C62828", // Light equivalent
- }
- theme.DiffContextColor = lipgloss.AdaptiveColor{
- Dark: "#a0a0a0", // From existing diff.go
- Light: "#757575", // Light equivalent
- }
- theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
- Dark: "#a0a0a0", // From existing diff.go
- Light: "#757575", // Light equivalent
- }
- theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
- Dark: "#DAFADA", // From existing diff.go
- Light: "#A5D6A7", // Light equivalent
- }
- theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#FADADD", // From existing diff.go
- Light: "#EF9A9A", // Light equivalent
- }
- theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
- Dark: "#303A30", // From existing diff.go
- Light: "#E8F5E9", // Light equivalent
- }
- theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
- Dark: "#3A3030", // From existing diff.go
- Light: "#FFEBEE", // Light equivalent
- }
- theme.DiffContextBgColor = lipgloss.AdaptiveColor{
- Dark: "#212121", // From existing diff.go
- Light: "#F5F5F5", // Light equivalent
- }
- theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
- Dark: "#888888", // From existing diff.go
- Light: "#9E9E9E", // Light equivalent
- }
- theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#293229", // From existing diff.go
- Light: "#C8E6C9", // Light equivalent
- }
- theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#332929", // From existing diff.go
- Light: "#FFCDD2", // Light equivalent
- }
-
- // Markdown colors
- theme.MarkdownTextColor = lipgloss.AdaptiveColor{
- Dark: mocha.Text().Hex,
- Light: latte.Text().Hex,
- }
- theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
- Dark: mocha.Mauve().Hex,
- Light: latte.Mauve().Hex,
- }
- theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
- Dark: mocha.Sky().Hex,
- Light: latte.Sky().Hex,
- }
- theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
- Dark: mocha.Pink().Hex,
- Light: latte.Pink().Hex,
- }
- theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
- Dark: mocha.Green().Hex,
- Light: latte.Green().Hex,
- }
- theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
- Dark: mocha.Yellow().Hex,
- Light: latte.Yellow().Hex,
- }
- theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
- Dark: mocha.Yellow().Hex,
- Light: latte.Yellow().Hex,
- }
- theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
- Dark: mocha.Peach().Hex,
- Light: latte.Peach().Hex,
- }
- theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
- Dark: mocha.Overlay0().Hex,
- Light: latte.Overlay0().Hex,
- }
- theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
- Dark: mocha.Blue().Hex,
- Light: latte.Blue().Hex,
- }
- theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
- Dark: mocha.Sky().Hex,
- Light: latte.Sky().Hex,
- }
- theme.MarkdownImageColor = lipgloss.AdaptiveColor{
- Dark: mocha.Sapphire().Hex,
- Light: latte.Sapphire().Hex,
- }
- theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
- Dark: mocha.Pink().Hex,
- Light: latte.Pink().Hex,
- }
- theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
- Dark: mocha.Text().Hex,
- Light: latte.Text().Hex,
- }
-
- // Syntax highlighting colors
- theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
- Dark: mocha.Overlay1().Hex,
- Light: latte.Overlay1().Hex,
- }
- theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
- Dark: mocha.Pink().Hex,
- Light: latte.Pink().Hex,
- }
- theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
- Dark: mocha.Green().Hex,
- Light: latte.Green().Hex,
- }
- theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
- Dark: mocha.Sky().Hex,
- Light: latte.Sky().Hex,
- }
- theme.SyntaxStringColor = lipgloss.AdaptiveColor{
- Dark: mocha.Yellow().Hex,
- Light: latte.Yellow().Hex,
- }
- theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
- Dark: mocha.Teal().Hex,
- Light: latte.Teal().Hex,
- }
- theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
- Dark: mocha.Sky().Hex,
- Light: latte.Sky().Hex,
- }
- theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
- Dark: mocha.Pink().Hex,
- Light: latte.Pink().Hex,
- }
- theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
- Dark: mocha.Text().Hex,
- Light: latte.Text().Hex,
- }
-
- return theme
-}
-
-func init() {
- // Register the Catppuccin theme with the theme manager
- RegisterTheme("catppuccin", NewCatppuccinTheme())
-}
diff --git a/packages/tui/internal/theme/dracula.go b/packages/tui/internal/theme/dracula.go
deleted file mode 100644
index 7f14d6290..000000000
--- a/packages/tui/internal/theme/dracula.go
+++ /dev/null
@@ -1,270 +0,0 @@
-package theme
-
-import (
- "github.com/charmbracelet/lipgloss"
-)
-
-// DraculaTheme implements the Theme interface with Dracula colors.
-// It provides both dark and light variants, though Dracula is primarily a dark theme.
-type DraculaTheme struct {
- BaseTheme
-}
-
-// NewDraculaTheme creates a new instance of the Dracula theme.
-func NewDraculaTheme() *DraculaTheme {
- // Dracula color palette
- // Official colors from https://draculatheme.com/
- darkBackground := "#282a36"
- darkCurrentLine := "#44475a"
- darkSelection := "#44475a"
- darkForeground := "#f8f8f2"
- darkComment := "#6272a4"
- darkCyan := "#8be9fd"
- darkGreen := "#50fa7b"
- darkOrange := "#ffb86c"
- darkPink := "#ff79c6"
- darkPurple := "#bd93f9"
- darkRed := "#ff5555"
- darkYellow := "#f1fa8c"
- darkBorder := "#44475a"
-
- // Light mode approximation (Dracula is primarily a dark theme)
- lightBackground := "#f8f8f2"
- lightCurrentLine := "#e6e6e6"
- lightSelection := "#d8d8d8"
- lightForeground := "#282a36"
- lightComment := "#6272a4"
- lightCyan := "#0097a7"
- lightGreen := "#388e3c"
- lightOrange := "#f57c00"
- lightPink := "#d81b60"
- lightPurple := "#7e57c2"
- lightRed := "#e53935"
- lightYellow := "#fbc02d"
- lightBorder := "#d8d8d8"
-
- theme := &DraculaTheme{}
-
- // Base colors
- theme.PrimaryColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.SecondaryColor = lipgloss.AdaptiveColor{
- Dark: darkPink,
- Light: lightPink,
- }
- theme.AccentColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
-
- // Status colors
- theme.ErrorColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
- }
- theme.WarningColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.SuccessColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.InfoColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
-
- // Text colors
- theme.TextColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.TextMutedColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
-
- // Background colors
- theme.BackgroundElementColor = lipgloss.AdaptiveColor{
- Dark: darkBackground,
- Light: lightBackground,
- }
- theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkCurrentLine,
- Light: lightCurrentLine,
- }
- theme.BackgroundColor = lipgloss.AdaptiveColor{
- Dark: "#21222c", // Slightly darker than background
- Light: "#ffffff", // Slightly lighter than background
- }
-
- // Border colors
- theme.BorderColor = lipgloss.AdaptiveColor{
- Dark: darkBorder,
- Light: lightBorder,
- }
- theme.BorderActiveColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.BorderSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkSelection,
- Light: lightSelection,
- }
-
- // Diff view colors
- theme.DiffAddedColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.DiffRemovedColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
- }
- theme.DiffContextColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
- Dark: darkCurrentLine,
- Light: lightCurrentLine,
- }
- theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
- Dark: "#50fa7b",
- Light: "#a5d6a7",
- }
- theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#ff5555",
- Light: "#ef9a9a",
- }
- theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
- Dark: "#2c3b2c",
- Light: "#e8f5e9",
- }
- theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
- Dark: "#3b2c2c",
- Light: "#ffebee",
- }
- theme.DiffContextBgColor = lipgloss.AdaptiveColor{
- Dark: darkBackground,
- Light: lightBackground,
- }
- theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#253025",
- Light: "#c8e6c9",
- }
- theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#302525",
- Light: "#ffcdd2",
- }
-
- // Markdown colors
- theme.MarkdownTextColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
- Dark: darkPink,
- Light: lightPink,
- }
- theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownImageColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
-
- // Syntax highlighting colors
- theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
- Dark: darkPink,
- Light: lightPink,
- }
- theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.SyntaxStringColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
- Dark: darkPink,
- Light: lightPink,
- }
- theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
-
- return theme
-}
-
-func init() {
- // Register the Dracula theme with the theme manager
- RegisterTheme("dracula", NewDraculaTheme())
-}
diff --git a/packages/tui/internal/theme/flexoki.go b/packages/tui/internal/theme/flexoki.go
deleted file mode 100644
index ad5443869..000000000
--- a/packages/tui/internal/theme/flexoki.go
+++ /dev/null
@@ -1,278 +0,0 @@
-package theme
-
-import (
- "github.com/charmbracelet/lipgloss"
-)
-
-// Flexoki color palette constants
-const (
- // Base colors
- flexokiPaper = "#FFFCF0" // Paper (lightest)
- flexokiBase50 = "#F2F0E5" // bg-2 (light)
- flexokiBase100 = "#E6E4D9" // ui (light)
- flexokiBase150 = "#DAD8CE" // ui-2 (light)
- flexokiBase200 = "#CECDC3" // ui-3 (light)
- flexokiBase300 = "#B7B5AC" // tx-3 (light)
- flexokiBase500 = "#878580" // tx-2 (light)
- flexokiBase600 = "#6F6E69" // tx (light)
- flexokiBase700 = "#575653" // tx-3 (dark)
- flexokiBase800 = "#403E3C" // ui-3 (dark)
- flexokiBase850 = "#343331" // ui-2 (dark)
- flexokiBase900 = "#282726" // ui (dark)
- flexokiBase950 = "#1C1B1A" // bg-2 (dark)
- flexokiBlack = "#100F0F" // bg (darkest)
-
- // Accent colors - Light theme (600)
- flexokiRed600 = "#AF3029"
- flexokiOrange600 = "#BC5215"
- flexokiYellow600 = "#AD8301"
- flexokiGreen600 = "#66800B"
- flexokiCyan600 = "#24837B"
- flexokiBlue600 = "#205EA6"
- flexokiPurple600 = "#5E409D"
- flexokiMagenta600 = "#A02F6F"
-
- // Accent colors - Dark theme (400)
- flexokiRed400 = "#D14D41"
- flexokiOrange400 = "#DA702C"
- flexokiYellow400 = "#D0A215"
- flexokiGreen400 = "#879A39"
- flexokiCyan400 = "#3AA99F"
- flexokiBlue400 = "#4385BE"
- flexokiPurple400 = "#8B7EC8"
- flexokiMagenta400 = "#CE5D97"
-)
-
-// FlexokiTheme implements the Theme interface with Flexoki colors.
-// It provides both dark and light variants.
-type FlexokiTheme struct {
- BaseTheme
-}
-
-// NewFlexokiTheme creates a new instance of the Flexoki theme.
-func NewFlexokiTheme() *FlexokiTheme {
- theme := &FlexokiTheme{}
-
- // Base colors
- theme.PrimaryColor = lipgloss.AdaptiveColor{
- Dark: flexokiBlue400,
- Light: flexokiBlue600,
- }
- theme.SecondaryColor = lipgloss.AdaptiveColor{
- Dark: flexokiPurple400,
- Light: flexokiPurple600,
- }
- theme.AccentColor = lipgloss.AdaptiveColor{
- Dark: flexokiOrange400,
- Light: flexokiOrange600,
- }
-
- // Status colors
- theme.ErrorColor = lipgloss.AdaptiveColor{
- Dark: flexokiRed400,
- Light: flexokiRed600,
- }
- theme.WarningColor = lipgloss.AdaptiveColor{
- Dark: flexokiYellow400,
- Light: flexokiYellow600,
- }
- theme.SuccessColor = lipgloss.AdaptiveColor{
- Dark: flexokiGreen400,
- Light: flexokiGreen600,
- }
- theme.InfoColor = lipgloss.AdaptiveColor{
- Dark: flexokiCyan400,
- Light: flexokiCyan600,
- }
-
- // Text colors
- theme.TextColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase300,
- Light: flexokiBase600,
- }
- theme.TextMutedColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase700,
- Light: flexokiBase500,
- }
-
- // Background colors
- theme.BackgroundColor = lipgloss.AdaptiveColor{
- Dark: flexokiBlack,
- Light: flexokiPaper,
- }
- theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase950,
- Light: flexokiBase50,
- }
- theme.BackgroundElementColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase900,
- Light: flexokiBase100,
- }
-
- // Border colors
- theme.BorderColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase900,
- Light: flexokiBase100,
- }
- theme.BorderActiveColor = lipgloss.AdaptiveColor{
- Dark: flexokiBlue400,
- Light: flexokiBlue600,
- }
- theme.BorderSubtleColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase850,
- Light: flexokiBase150,
- }
-
- // Diff view colors
- theme.DiffAddedColor = lipgloss.AdaptiveColor{
- Dark: flexokiGreen400,
- Light: flexokiGreen600,
- }
- theme.DiffRemovedColor = lipgloss.AdaptiveColor{
- Dark: flexokiRed400,
- Light: flexokiRed600,
- }
- theme.DiffContextColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase700,
- Light: flexokiBase500,
- }
- theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase700,
- Light: flexokiBase500,
- }
- theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
- Dark: flexokiGreen400,
- Light: flexokiGreen600,
- }
- theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
- Dark: flexokiRed400,
- Light: flexokiRed600,
- }
- theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
- Dark: "#1D2419", // Darker green background
- Light: "#EFF2E2", // Light green background
- }
- theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
- Dark: "#241919", // Darker red background
- Light: "#F2E2E2", // Light red background
- }
- theme.DiffContextBgColor = lipgloss.AdaptiveColor{
- Dark: flexokiBlack,
- Light: flexokiPaper,
- }
- theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase700,
- Light: flexokiBase500,
- }
- theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#1A2017", // Slightly darker green
- Light: "#E5EBD9", // Light green
- }
- theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#201717", // Slightly darker red
- Light: "#EBD9D9", // Light red
- }
-
- // Markdown colors
- theme.MarkdownTextColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase300,
- Light: flexokiBase600,
- }
- theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
- Dark: flexokiYellow400,
- Light: flexokiYellow600,
- }
- theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
- Dark: flexokiCyan400,
- Light: flexokiCyan600,
- }
- theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
- Dark: flexokiMagenta400,
- Light: flexokiMagenta600,
- }
- theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
- Dark: flexokiGreen400,
- Light: flexokiGreen600,
- }
- theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
- Dark: flexokiCyan400,
- Light: flexokiCyan600,
- }
- theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
- Dark: flexokiYellow400,
- Light: flexokiYellow600,
- }
- theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
- Dark: flexokiOrange400,
- Light: flexokiOrange600,
- }
- theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase800,
- Light: flexokiBase200,
- }
- theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
- Dark: flexokiBlue400,
- Light: flexokiBlue600,
- }
- theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
- Dark: flexokiBlue400,
- Light: flexokiBlue600,
- }
- theme.MarkdownImageColor = lipgloss.AdaptiveColor{
- Dark: flexokiPurple400,
- Light: flexokiPurple600,
- }
- theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
- Dark: flexokiMagenta400,
- Light: flexokiMagenta600,
- }
- theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase300,
- Light: flexokiBase600,
- }
-
- // Syntax highlighting colors (based on Flexoki's mappings)
- theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase700, // tx-3
- Light: flexokiBase300, // tx-3
- }
- theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
- Dark: flexokiGreen400, // gr
- Light: flexokiGreen600, // gr
- }
- theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
- Dark: flexokiOrange400, // or
- Light: flexokiOrange600, // or
- }
- theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
- Dark: flexokiBlue400, // bl
- Light: flexokiBlue600, // bl
- }
- theme.SyntaxStringColor = lipgloss.AdaptiveColor{
- Dark: flexokiCyan400, // cy
- Light: flexokiCyan600, // cy
- }
- theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
- Dark: flexokiPurple400, // pu
- Light: flexokiPurple600, // pu
- }
- theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
- Dark: flexokiYellow400, // ye
- Light: flexokiYellow600, // ye
- }
- theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase500, // tx-2
- Light: flexokiBase500, // tx-2
- }
- theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
- Dark: flexokiBase500, // tx-2
- Light: flexokiBase500, // tx-2
- }
-
- return theme
-}
-
-func init() {
- // Register the Flexoki theme with the theme manager
- RegisterTheme("flexoki", NewFlexokiTheme())
-}
diff --git a/packages/tui/internal/theme/gruvbox.go b/packages/tui/internal/theme/gruvbox.go
deleted file mode 100644
index da9aab50e..000000000
--- a/packages/tui/internal/theme/gruvbox.go
+++ /dev/null
@@ -1,298 +0,0 @@
-package theme
-
-import (
- "github.com/charmbracelet/lipgloss"
-)
-
-// Gruvbox color palette constants
-const (
- // Dark theme colors
- gruvboxDarkBg0 = "#282828"
- gruvboxDarkBg0Soft = "#32302f"
- gruvboxDarkBg1 = "#3c3836"
- gruvboxDarkBg2 = "#504945"
- gruvboxDarkBg3 = "#665c54"
- gruvboxDarkBg4 = "#7c6f64"
- gruvboxDarkFg0 = "#fbf1c7"
- gruvboxDarkFg1 = "#ebdbb2"
- gruvboxDarkFg2 = "#d5c4a1"
- gruvboxDarkFg3 = "#bdae93"
- gruvboxDarkFg4 = "#a89984"
- gruvboxDarkGray = "#928374"
- gruvboxDarkRed = "#cc241d"
- gruvboxDarkRedBright = "#fb4934"
- gruvboxDarkGreen = "#98971a"
- gruvboxDarkGreenBright = "#b8bb26"
- gruvboxDarkYellow = "#d79921"
- gruvboxDarkYellowBright = "#fabd2f"
- gruvboxDarkBlue = "#458588"
- gruvboxDarkBlueBright = "#83a598"
- gruvboxDarkPurple = "#b16286"
- gruvboxDarkPurpleBright = "#d3869b"
- gruvboxDarkAqua = "#689d6a"
- gruvboxDarkAquaBright = "#8ec07c"
- gruvboxDarkOrange = "#d65d0e"
- gruvboxDarkOrangeBright = "#fe8019"
-
- // Light theme colors
- gruvboxLightBg0 = "#fbf1c7"
- gruvboxLightBg0Soft = "#f2e5bc"
- gruvboxLightBg1 = "#ebdbb2"
- gruvboxLightBg2 = "#d5c4a1"
- gruvboxLightBg3 = "#bdae93"
- gruvboxLightBg4 = "#a89984"
- gruvboxLightFg0 = "#282828"
- gruvboxLightFg1 = "#3c3836"
- gruvboxLightFg2 = "#504945"
- gruvboxLightFg3 = "#665c54"
- gruvboxLightFg4 = "#7c6f64"
- gruvboxLightGray = "#928374"
- gruvboxLightRed = "#9d0006"
- gruvboxLightRedBright = "#cc241d"
- gruvboxLightGreen = "#79740e"
- gruvboxLightGreenBright = "#98971a"
- gruvboxLightYellow = "#b57614"
- gruvboxLightYellowBright = "#d79921"
- gruvboxLightBlue = "#076678"
- gruvboxLightBlueBright = "#458588"
- gruvboxLightPurple = "#8f3f71"
- gruvboxLightPurpleBright = "#b16286"
- gruvboxLightAqua = "#427b58"
- gruvboxLightAquaBright = "#689d6a"
- gruvboxLightOrange = "#af3a03"
- gruvboxLightOrangeBright = "#d65d0e"
-)
-
-// GruvboxTheme implements the Theme interface with Gruvbox colors.
-// It provides both dark and light variants.
-type GruvboxTheme struct {
- BaseTheme
-}
-
-// NewGruvboxTheme creates a new instance of the Gruvbox theme.
-func NewGruvboxTheme() *GruvboxTheme {
- theme := &GruvboxTheme{}
-
- // Base colors
- theme.PrimaryColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBlueBright,
- Light: gruvboxLightBlueBright,
- }
- theme.SecondaryColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkPurpleBright,
- Light: gruvboxLightPurpleBright,
- }
- theme.AccentColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkOrangeBright,
- Light: gruvboxLightOrangeBright,
- }
-
- // Status colors
- theme.ErrorColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkRedBright,
- Light: gruvboxLightRedBright,
- }
- theme.WarningColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkYellowBright,
- Light: gruvboxLightYellowBright,
- }
- theme.SuccessColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkGreenBright,
- Light: gruvboxLightGreenBright,
- }
- theme.InfoColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBlueBright,
- Light: gruvboxLightBlueBright,
- }
-
- // Text colors
- theme.TextColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkFg1,
- Light: gruvboxLightFg1,
- }
- theme.TextMutedColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkFg4,
- Light: gruvboxLightFg4,
- }
-
- // Background colors
- theme.BackgroundColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBg0,
- Light: gruvboxLightBg0,
- }
- theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBg1,
- Light: gruvboxLightBg1,
- }
- theme.BackgroundElementColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBg0Soft,
- Light: gruvboxLightBg0Soft,
- }
-
- // Border colors
- theme.BorderColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBg2,
- Light: gruvboxLightBg2,
- }
- theme.BorderActiveColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBlueBright,
- Light: gruvboxLightBlueBright,
- }
- theme.BorderSubtleColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBg1,
- Light: gruvboxLightBg1,
- }
-
- // Diff view colors
- theme.DiffAddedColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkGreenBright,
- Light: gruvboxLightGreenBright,
- }
- theme.DiffRemovedColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkRedBright,
- Light: gruvboxLightRedBright,
- }
- theme.DiffContextColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkFg4,
- Light: gruvboxLightFg4,
- }
- theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkFg3,
- Light: gruvboxLightFg3,
- }
- theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkGreenBright,
- Light: gruvboxLightGreenBright,
- }
- theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkRedBright,
- Light: gruvboxLightRedBright,
- }
- theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
- Dark: "#3C4C3C", // Darker green background
- Light: "#E8F5E9", // Light green background
- }
- theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
- Dark: "#4C3C3C", // Darker red background
- Light: "#FFEBEE", // Light red background
- }
- theme.DiffContextBgColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBg0,
- Light: gruvboxLightBg0,
- }
- theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkFg4,
- Light: gruvboxLightFg4,
- }
- theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#32432F", // Slightly darker green
- Light: "#C8E6C9", // Light green
- }
- theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#43322F", // Slightly darker red
- Light: "#FFCDD2", // Light red
- }
-
- // Markdown colors
- theme.MarkdownTextColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkFg1,
- Light: gruvboxLightFg1,
- }
- theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkYellowBright,
- Light: gruvboxLightYellowBright,
- }
- theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBlueBright,
- Light: gruvboxLightBlueBright,
- }
- theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkAquaBright,
- Light: gruvboxLightAquaBright,
- }
- theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkGreenBright,
- Light: gruvboxLightGreenBright,
- }
- theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkAquaBright,
- Light: gruvboxLightAquaBright,
- }
- theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkYellowBright,
- Light: gruvboxLightYellowBright,
- }
- theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkOrangeBright,
- Light: gruvboxLightOrangeBright,
- }
- theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBg3,
- Light: gruvboxLightBg3,
- }
- theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBlueBright,
- Light: gruvboxLightBlueBright,
- }
- theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBlueBright,
- Light: gruvboxLightBlueBright,
- }
- theme.MarkdownImageColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkPurpleBright,
- Light: gruvboxLightPurpleBright,
- }
- theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkAquaBright,
- Light: gruvboxLightAquaBright,
- }
- theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkFg1,
- Light: gruvboxLightFg1,
- }
-
- // Syntax highlighting colors
- theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkGray,
- Light: gruvboxLightGray,
- }
- theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkRedBright,
- Light: gruvboxLightRedBright,
- }
- theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkGreenBright,
- Light: gruvboxLightGreenBright,
- }
- theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkBlueBright,
- Light: gruvboxLightBlueBright,
- }
- theme.SyntaxStringColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkYellowBright,
- Light: gruvboxLightYellowBright,
- }
- theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkPurpleBright,
- Light: gruvboxLightPurpleBright,
- }
- theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkYellow,
- Light: gruvboxLightYellow,
- }
- theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkAquaBright,
- Light: gruvboxLightAquaBright,
- }
- theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
- Dark: gruvboxDarkFg1,
- Light: gruvboxLightFg1,
- }
-
- return theme
-}
-
-func init() {
- // Register the Gruvbox theme with the theme manager
- RegisterTheme("gruvbox", NewGruvboxTheme())
-}
diff --git a/packages/tui/internal/theme/manager.go b/packages/tui/internal/theme/manager.go
index 020e3e193..3e351f7f1 100644
--- a/packages/tui/internal/theme/manager.go
+++ b/packages/tui/internal/theme/manager.go
@@ -6,8 +6,7 @@ import (
"slices"
"strings"
"sync"
-
- "github.com/alecthomas/chroma/v2/styles"
+ // "github.com/alecthomas/chroma/v2/styles"
)
// Manager handles theme registration, selection, and retrieval.
@@ -46,7 +45,7 @@ func RegisterTheme(name string, theme Theme) {
func SetTheme(name string) error {
globalManager.mu.Lock()
defer globalManager.mu.Unlock()
- delete(styles.Registry, "charm")
+ // delete(styles.Registry, "charm")
// Handle custom theme
// if name == "custom" {
diff --git a/packages/tui/internal/theme/monokai.go b/packages/tui/internal/theme/monokai.go
deleted file mode 100644
index 71234d025..000000000
--- a/packages/tui/internal/theme/monokai.go
+++ /dev/null
@@ -1,269 +0,0 @@
-package theme
-
-import (
- "github.com/charmbracelet/lipgloss"
-)
-
-// MonokaiProTheme implements the Theme interface with Monokai Pro colors.
-// It provides both dark and light variants.
-type MonokaiProTheme struct {
- BaseTheme
-}
-
-// NewMonokaiProTheme creates a new instance of the Monokai Pro theme.
-func NewMonokaiProTheme() *MonokaiProTheme {
- // Monokai Pro color palette (dark mode)
- darkBackground := "#2d2a2e"
- darkCurrentLine := "#403e41"
- darkSelection := "#5b595c"
- darkForeground := "#fcfcfa"
- darkComment := "#727072"
- darkRed := "#ff6188"
- darkOrange := "#fc9867"
- darkYellow := "#ffd866"
- darkGreen := "#a9dc76"
- darkCyan := "#78dce8"
- darkBlue := "#ab9df2"
- darkPurple := "#ab9df2"
- darkBorder := "#403e41"
-
- // Light mode colors (adapted from dark)
- lightBackground := "#fafafa"
- lightCurrentLine := "#f0f0f0"
- lightSelection := "#e5e5e6"
- lightForeground := "#2d2a2e"
- lightComment := "#939293"
- lightRed := "#f92672"
- lightOrange := "#fd971f"
- lightYellow := "#e6db74"
- lightGreen := "#9bca65"
- lightCyan := "#66d9ef"
- lightBlue := "#7e75db"
- lightPurple := "#ae81ff"
- lightBorder := "#d3d3d3"
-
- theme := &MonokaiProTheme{}
-
- // Base colors
- theme.PrimaryColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.SecondaryColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.AccentColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
-
- // Status colors
- theme.ErrorColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
- }
- theme.WarningColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.SuccessColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.InfoColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
-
- // Text colors
- theme.TextColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.TextMutedColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
-
- // Background colors
- theme.BackgroundColor = lipgloss.AdaptiveColor{
- Dark: darkBackground,
- Light: lightBackground,
- }
- theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkCurrentLine,
- Light: lightCurrentLine,
- }
- theme.BackgroundElementColor = lipgloss.AdaptiveColor{
- Dark: "#221f22", // Slightly darker than background
- Light: "#ffffff", // Slightly lighter than background
- }
-
- // Border colors
- theme.BorderColor = lipgloss.AdaptiveColor{
- Dark: darkBorder,
- Light: lightBorder,
- }
- theme.BorderActiveColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.BorderSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkSelection,
- Light: lightSelection,
- }
-
- // Diff view colors
- theme.DiffAddedColor = lipgloss.AdaptiveColor{
- Dark: "#a9dc76",
- Light: "#9bca65",
- }
- theme.DiffRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#ff6188",
- Light: "#f92672",
- }
- theme.DiffContextColor = lipgloss.AdaptiveColor{
- Dark: "#a0a0a0",
- Light: "#757575",
- }
- theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
- Dark: "#a0a0a0",
- Light: "#757575",
- }
- theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
- Dark: "#c2e7a9",
- Light: "#c5e0b4",
- }
- theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#ff8ca6",
- Light: "#ffb3c8",
- }
- theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
- Dark: "#3a4a35",
- Light: "#e8f5e9",
- }
- theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
- Dark: "#4a3439",
- Light: "#ffebee",
- }
- theme.DiffContextBgColor = lipgloss.AdaptiveColor{
- Dark: darkBackground,
- Light: lightBackground,
- }
- theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
- Dark: "#888888",
- Light: "#9e9e9e",
- }
- theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#2d3a28",
- Light: "#c8e6c9",
- }
- theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#3d2a2e",
- Light: "#ffcdd2",
- }
-
- // Markdown colors
- theme.MarkdownTextColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownImageColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
-
- // Syntax highlighting colors
- theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
- }
- theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.SyntaxStringColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
-
- return theme
-}
-
-func init() {
- // Register the Monokai Pro theme with the theme manager
- RegisterTheme("monokai", NewMonokaiProTheme())
-}
diff --git a/packages/tui/internal/theme/onedark.go b/packages/tui/internal/theme/onedark.go
deleted file mode 100644
index 21953c10d..000000000
--- a/packages/tui/internal/theme/onedark.go
+++ /dev/null
@@ -1,270 +0,0 @@
-package theme
-
-import (
- "github.com/charmbracelet/lipgloss"
-)
-
-// OneDarkTheme implements the Theme interface with Atom's One Dark colors.
-// It provides both dark and light variants.
-type OneDarkTheme struct {
- BaseTheme
-}
-
-// NewOneDarkTheme creates a new instance of the One Dark theme.
-func NewOneDarkTheme() *OneDarkTheme {
- // One Dark color palette
- // Dark mode colors from Atom One Dark
- darkBackground := "#282c34"
- darkCurrentLine := "#2c313c"
- darkSelection := "#3e4451"
- darkForeground := "#abb2bf"
- darkComment := "#5c6370"
- darkRed := "#e06c75"
- darkOrange := "#d19a66"
- darkYellow := "#e5c07b"
- darkGreen := "#98c379"
- darkCyan := "#56b6c2"
- darkBlue := "#61afef"
- darkPurple := "#c678dd"
- darkBorder := "#3b4048"
-
- // Light mode colors from Atom One Light
- lightBackground := "#fafafa"
- lightCurrentLine := "#f0f0f0"
- lightSelection := "#e5e5e6"
- lightForeground := "#383a42"
- lightComment := "#a0a1a7"
- lightRed := "#e45649"
- lightOrange := "#da8548"
- lightYellow := "#c18401"
- lightGreen := "#50a14f"
- lightCyan := "#0184bc"
- lightBlue := "#4078f2"
- lightPurple := "#a626a4"
- lightBorder := "#d3d3d3"
-
- theme := &OneDarkTheme{}
-
- // Base colors
- theme.PrimaryColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.SecondaryColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.AccentColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
-
- // Status colors
- theme.ErrorColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
- }
- theme.WarningColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.SuccessColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.InfoColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
-
- // Text colors
- theme.TextColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.TextMutedColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
-
- // Background colors
- theme.BackgroundColor = lipgloss.AdaptiveColor{
- Dark: darkBackground,
- Light: lightBackground,
- }
- theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkCurrentLine,
- Light: lightCurrentLine,
- }
- theme.BackgroundElementColor = lipgloss.AdaptiveColor{
- Dark: "#21252b", // Slightly darker than background
- Light: "#ffffff", // Slightly lighter than background
- }
-
- // Border colors
- theme.BorderColor = lipgloss.AdaptiveColor{
- Dark: darkBorder,
- Light: lightBorder,
- }
- theme.BorderActiveColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.BorderSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkSelection,
- Light: lightSelection,
- }
-
- // Diff view colors
- theme.DiffAddedColor = lipgloss.AdaptiveColor{
- Dark: "#478247",
- Light: "#2E7D32",
- }
- theme.DiffRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#7C4444",
- Light: "#C62828",
- }
- theme.DiffContextColor = lipgloss.AdaptiveColor{
- Dark: "#a0a0a0",
- Light: "#757575",
- }
- theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
- Dark: "#a0a0a0",
- Light: "#757575",
- }
- theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
- Dark: "#DAFADA",
- Light: "#A5D6A7",
- }
- theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#FADADD",
- Light: "#EF9A9A",
- }
- theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
- Dark: "#303A30",
- Light: "#E8F5E9",
- }
- theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
- Dark: "#3A3030",
- Light: "#FFEBEE",
- }
- theme.DiffContextBgColor = lipgloss.AdaptiveColor{
- Dark: darkBackground,
- Light: lightBackground,
- }
- theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
- Dark: "#888888",
- Light: "#9E9E9E",
- }
- theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#293229",
- Light: "#C8E6C9",
- }
- theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#332929",
- Light: "#FFCDD2",
- }
-
- // Markdown colors
- theme.MarkdownTextColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownImageColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
-
- // Syntax highlighting colors
- theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
- }
- theme.SyntaxStringColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
-
- return theme
-}
-
-func init() {
- // Register the One Dark theme with the theme manager
- RegisterTheme("onedark", NewOneDarkTheme())
-}
diff --git a/packages/tui/internal/theme/opencode.go b/packages/tui/internal/theme/opencode.go
index 4de88ae4e..8f188be3c 100644
--- a/packages/tui/internal/theme/opencode.go
+++ b/packages/tui/internal/theme/opencode.go
@@ -1,7 +1,8 @@
package theme
import (
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/lipgloss/v2"
+ "github.com/charmbracelet/lipgloss/v2/compat"
)
// OpenCodeTheme implements the Theme interface with OpenCode brand colors.
@@ -72,219 +73,219 @@ func NewOpenCodeTheme() *OpenCodeTheme {
theme := &OpenCodeTheme{}
// Base colors
- theme.PrimaryColor = lipgloss.AdaptiveColor{
- Dark: darkPrimary,
- Light: lightPrimary,
+ theme.PrimaryColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkPrimary),
+ Light: lipgloss.Color(lightPrimary),
}
- theme.SecondaryColor = lipgloss.AdaptiveColor{
- Dark: darkSecondary,
- Light: lightSecondary,
+ theme.SecondaryColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkSecondary),
+ Light: lipgloss.Color(lightSecondary),
}
- theme.AccentColor = lipgloss.AdaptiveColor{
- Dark: darkAccent,
- Light: lightAccent,
+ theme.AccentColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkAccent),
+ Light: lipgloss.Color(lightAccent),
}
// Status colors
- theme.ErrorColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
+ theme.ErrorColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkRed),
+ Light: lipgloss.Color(lightRed),
}
- theme.WarningColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
+ theme.WarningColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkOrange),
+ Light: lipgloss.Color(lightOrange),
}
- theme.SuccessColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
+ theme.SuccessColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkGreen),
+ Light: lipgloss.Color(lightGreen),
}
- theme.InfoColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
+ theme.InfoColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkCyan),
+ Light: lipgloss.Color(lightCyan),
}
// Text colors
- theme.TextColor = lipgloss.AdaptiveColor{
- Dark: darkStep12,
- Light: lightStep12,
+ theme.TextColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep12),
+ Light: lipgloss.Color(lightStep12),
}
- theme.TextMutedColor = lipgloss.AdaptiveColor{
- Dark: darkStep11,
- Light: lightStep11,
+ theme.TextMutedColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep11),
+ Light: lipgloss.Color(lightStep11),
}
// Background colors
- theme.BackgroundColor = lipgloss.AdaptiveColor{
- Dark: darkStep1,
- Light: lightStep1,
+ theme.BackgroundColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep1),
+ Light: lipgloss.Color(lightStep1),
}
- theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkStep2,
- Light: lightStep2,
+ theme.BackgroundSubtleColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep2),
+ Light: lipgloss.Color(lightStep2),
}
- theme.BackgroundElementColor = lipgloss.AdaptiveColor{
- Dark: darkStep3,
- Light: lightStep3,
+ theme.BackgroundElementColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep3),
+ Light: lipgloss.Color(lightStep3),
}
// Border colors
- theme.BorderColor = lipgloss.AdaptiveColor{
- Dark: darkStep7,
- Light: lightStep7,
+ theme.BorderColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep7),
+ Light: lipgloss.Color(lightStep7),
}
- theme.BorderActiveColor = lipgloss.AdaptiveColor{
- Dark: darkStep8,
- Light: lightStep8,
+ theme.BorderActiveColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep8),
+ Light: lipgloss.Color(lightStep8),
}
- theme.BorderSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkStep6,
- Light: lightStep6,
+ theme.BorderSubtleColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep6),
+ Light: lipgloss.Color(lightStep6),
}
// Diff view colors
- theme.DiffAddedColor = lipgloss.AdaptiveColor{
- Dark: "#478247",
- Light: "#2E7D32",
+ theme.DiffAddedColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#478247"),
+ Light: lipgloss.Color("#2E7D32"),
}
- theme.DiffRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#7C4444",
- Light: "#C62828",
+ theme.DiffRemovedColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#7C4444"),
+ Light: lipgloss.Color("#C62828"),
}
- theme.DiffContextColor = lipgloss.AdaptiveColor{
- Dark: "#a0a0a0",
- Light: "#757575",
+ theme.DiffContextColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#a0a0a0"),
+ Light: lipgloss.Color("#757575"),
}
- theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
- Dark: "#a0a0a0",
- Light: "#757575",
+ theme.DiffHunkHeaderColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#a0a0a0"),
+ Light: lipgloss.Color("#757575"),
}
- theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
- Dark: "#DAFADA",
- Light: "#A5D6A7",
+ theme.DiffHighlightAddedColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#DAFADA"),
+ Light: lipgloss.Color("#A5D6A7"),
}
- theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#FADADD",
- Light: "#EF9A9A",
+ theme.DiffHighlightRemovedColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#FADADD"),
+ Light: lipgloss.Color("#EF9A9A"),
}
- theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
- Dark: "#303A30",
- Light: "#E8F5E9",
+ theme.DiffAddedBgColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#303A30"),
+ Light: lipgloss.Color("#E8F5E9"),
}
- theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
- Dark: "#3A3030",
- Light: "#FFEBEE",
+ theme.DiffRemovedBgColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#3A3030"),
+ Light: lipgloss.Color("#FFEBEE"),
}
- theme.DiffContextBgColor = lipgloss.AdaptiveColor{
- Dark: darkStep2,
- Light: lightStep2,
+ theme.DiffContextBgColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep2),
+ Light: lipgloss.Color(lightStep2),
}
- theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
- Dark: darkStep3,
- Light: lightStep3,
+ theme.DiffLineNumberColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep3),
+ Light: lipgloss.Color(lightStep3),
}
- theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#293229",
- Light: "#C8E6C9",
+ theme.DiffAddedLineNumberBgColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#293229"),
+ Light: lipgloss.Color("#C8E6C9"),
}
- theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#332929",
- Light: "#FFCDD2",
+ theme.DiffRemovedLineNumberBgColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#332929"),
+ Light: lipgloss.Color("#FFCDD2"),
}
// Markdown colors
- theme.MarkdownTextColor = lipgloss.AdaptiveColor{
- Dark: darkStep12,
- Light: lightStep12,
+ theme.MarkdownTextColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep12),
+ Light: lipgloss.Color(lightStep12),
}
- theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
- Dark: darkSecondary,
- Light: lightSecondary,
+ theme.MarkdownHeadingColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkSecondary),
+ Light: lipgloss.Color(lightSecondary),
}
- theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
- Dark: darkPrimary,
- Light: lightPrimary,
+ theme.MarkdownLinkColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkPrimary),
+ Light: lipgloss.Color(lightPrimary),
}
- theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
+ theme.MarkdownLinkTextColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkCyan),
+ Light: lipgloss.Color(lightCyan),
}
- theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
+ theme.MarkdownCodeColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkGreen),
+ Light: lipgloss.Color(lightGreen),
}
- theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
+ theme.MarkdownBlockQuoteColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkYellow),
+ Light: lipgloss.Color(lightYellow),
}
- theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
+ theme.MarkdownEmphColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkYellow),
+ Light: lipgloss.Color(lightYellow),
}
- theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
- Dark: darkAccent,
- Light: lightAccent,
+ theme.MarkdownStrongColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkAccent),
+ Light: lipgloss.Color(lightAccent),
}
- theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
- Dark: darkStep11,
- Light: lightStep11,
+ theme.MarkdownHorizontalRuleColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep11),
+ Light: lipgloss.Color(lightStep11),
}
- theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
- Dark: darkPrimary,
- Light: lightPrimary,
+ theme.MarkdownListItemColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkPrimary),
+ Light: lipgloss.Color(lightPrimary),
}
- theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
+ theme.MarkdownListEnumerationColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkCyan),
+ Light: lipgloss.Color(lightCyan),
}
- theme.MarkdownImageColor = lipgloss.AdaptiveColor{
- Dark: darkPrimary,
- Light: lightPrimary,
+ theme.MarkdownImageColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkPrimary),
+ Light: lipgloss.Color(lightPrimary),
}
- theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
+ theme.MarkdownImageTextColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkCyan),
+ Light: lipgloss.Color(lightCyan),
}
- theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
- Dark: darkStep12,
- Light: lightStep12,
+ theme.MarkdownCodeBlockColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep12),
+ Light: lipgloss.Color(lightStep12),
}
// Syntax highlighting colors
- theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
- Dark: darkStep11,
- Light: lightStep11,
+ theme.SyntaxCommentColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep11),
+ Light: lipgloss.Color(lightStep11),
}
- theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
- Dark: darkSecondary,
- Light: lightSecondary,
+ theme.SyntaxKeywordColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkPrimary),
+ Light: lipgloss.Color(lightPrimary),
}
- theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
- Dark: darkPrimary,
- Light: lightPrimary,
+ theme.SyntaxFunctionColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkPrimary),
+ Light: lipgloss.Color(lightPrimary),
}
- theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
+ theme.SyntaxVariableColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkRed),
+ Light: lipgloss.Color(lightRed),
}
- theme.SyntaxStringColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
+ theme.SyntaxStringColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkGreen),
+ Light: lipgloss.Color(lightGreen),
}
- theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
- Dark: darkAccent,
- Light: lightAccent,
+ theme.SyntaxNumberColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkAccent),
+ Light: lipgloss.Color(lightAccent),
}
- theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
+ theme.SyntaxTypeColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkYellow),
+ Light: lipgloss.Color(lightYellow),
}
- theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
+ theme.SyntaxOperatorColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkCyan),
+ Light: lipgloss.Color(lightCyan),
}
- theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
- Dark: darkStep12,
- Light: lightStep12,
+ theme.SyntaxPunctuationColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep12),
+ Light: lipgloss.Color(lightStep12),
}
return theme
diff --git a/packages/tui/internal/theme/theme.go b/packages/tui/internal/theme/theme.go
index 8b2d926b1..2769a1720 100644
--- a/packages/tui/internal/theme/theme.go
+++ b/packages/tui/internal/theme/theme.go
@@ -4,231 +4,232 @@ import (
"fmt"
"regexp"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/lipgloss/v2"
+ "github.com/charmbracelet/lipgloss/v2/compat"
)
// Theme defines the interface for all UI themes in the application.
-// All colors must be defined as lipgloss.AdaptiveColor to support
+// All colors must be defined as compat.AdaptiveColor to support
// both light and dark terminal backgrounds.
type Theme interface {
// Background colors
- Background() lipgloss.AdaptiveColor // Radix 1
- BackgroundSubtle() lipgloss.AdaptiveColor // Radix 2
- BackgroundElement() lipgloss.AdaptiveColor // Radix 3
+ Background() compat.AdaptiveColor // Radix 1
+ BackgroundSubtle() compat.AdaptiveColor // Radix 2
+ BackgroundElement() compat.AdaptiveColor // Radix 3
// Border colors
- BorderSubtle() lipgloss.AdaptiveColor // Radix 6
- Border() lipgloss.AdaptiveColor // Radix 7
- BorderActive() lipgloss.AdaptiveColor // Radix 8
+ BorderSubtle() compat.AdaptiveColor // Radix 6
+ Border() compat.AdaptiveColor // Radix 7
+ BorderActive() compat.AdaptiveColor // Radix 8
// Brand colors
- Primary() lipgloss.AdaptiveColor // Radix 9
- Secondary() lipgloss.AdaptiveColor
- Accent() lipgloss.AdaptiveColor
+ Primary() compat.AdaptiveColor // Radix 9
+ Secondary() compat.AdaptiveColor
+ Accent() compat.AdaptiveColor
// Text colors
- TextMuted() lipgloss.AdaptiveColor // Radix 11
- Text() lipgloss.AdaptiveColor // Radix 12
+ TextMuted() compat.AdaptiveColor // Radix 11
+ Text() compat.AdaptiveColor // Radix 12
// Status colors
- Error() lipgloss.AdaptiveColor
- Warning() lipgloss.AdaptiveColor
- Success() lipgloss.AdaptiveColor
- Info() lipgloss.AdaptiveColor
+ Error() compat.AdaptiveColor
+ Warning() compat.AdaptiveColor
+ Success() compat.AdaptiveColor
+ Info() compat.AdaptiveColor
// Diff view colors
- DiffAdded() lipgloss.AdaptiveColor
- DiffRemoved() lipgloss.AdaptiveColor
- DiffContext() lipgloss.AdaptiveColor
- DiffHunkHeader() lipgloss.AdaptiveColor
- DiffHighlightAdded() lipgloss.AdaptiveColor
- DiffHighlightRemoved() lipgloss.AdaptiveColor
- DiffAddedBg() lipgloss.AdaptiveColor
- DiffRemovedBg() lipgloss.AdaptiveColor
- DiffContextBg() lipgloss.AdaptiveColor
- DiffLineNumber() lipgloss.AdaptiveColor
- DiffAddedLineNumberBg() lipgloss.AdaptiveColor
- DiffRemovedLineNumberBg() lipgloss.AdaptiveColor
+ DiffAdded() compat.AdaptiveColor
+ DiffRemoved() compat.AdaptiveColor
+ DiffContext() compat.AdaptiveColor
+ DiffHunkHeader() compat.AdaptiveColor
+ DiffHighlightAdded() compat.AdaptiveColor
+ DiffHighlightRemoved() compat.AdaptiveColor
+ DiffAddedBg() compat.AdaptiveColor
+ DiffRemovedBg() compat.AdaptiveColor
+ DiffContextBg() compat.AdaptiveColor
+ DiffLineNumber() compat.AdaptiveColor
+ DiffAddedLineNumberBg() compat.AdaptiveColor
+ DiffRemovedLineNumberBg() compat.AdaptiveColor
// Markdown colors
- MarkdownText() lipgloss.AdaptiveColor
- MarkdownHeading() lipgloss.AdaptiveColor
- MarkdownLink() lipgloss.AdaptiveColor
- MarkdownLinkText() lipgloss.AdaptiveColor
- MarkdownCode() lipgloss.AdaptiveColor
- MarkdownBlockQuote() lipgloss.AdaptiveColor
- MarkdownEmph() lipgloss.AdaptiveColor
- MarkdownStrong() lipgloss.AdaptiveColor
- MarkdownHorizontalRule() lipgloss.AdaptiveColor
- MarkdownListItem() lipgloss.AdaptiveColor
- MarkdownListEnumeration() lipgloss.AdaptiveColor
- MarkdownImage() lipgloss.AdaptiveColor
- MarkdownImageText() lipgloss.AdaptiveColor
- MarkdownCodeBlock() lipgloss.AdaptiveColor
+ MarkdownText() compat.AdaptiveColor
+ MarkdownHeading() compat.AdaptiveColor
+ MarkdownLink() compat.AdaptiveColor
+ MarkdownLinkText() compat.AdaptiveColor
+ MarkdownCode() compat.AdaptiveColor
+ MarkdownBlockQuote() compat.AdaptiveColor
+ MarkdownEmph() compat.AdaptiveColor
+ MarkdownStrong() compat.AdaptiveColor
+ MarkdownHorizontalRule() compat.AdaptiveColor
+ MarkdownListItem() compat.AdaptiveColor
+ MarkdownListEnumeration() compat.AdaptiveColor
+ MarkdownImage() compat.AdaptiveColor
+ MarkdownImageText() compat.AdaptiveColor
+ MarkdownCodeBlock() compat.AdaptiveColor
// Syntax highlighting colors
- SyntaxComment() lipgloss.AdaptiveColor
- SyntaxKeyword() lipgloss.AdaptiveColor
- SyntaxFunction() lipgloss.AdaptiveColor
- SyntaxVariable() lipgloss.AdaptiveColor
- SyntaxString() lipgloss.AdaptiveColor
- SyntaxNumber() lipgloss.AdaptiveColor
- SyntaxType() lipgloss.AdaptiveColor
- SyntaxOperator() lipgloss.AdaptiveColor
- SyntaxPunctuation() lipgloss.AdaptiveColor
+ SyntaxComment() compat.AdaptiveColor
+ SyntaxKeyword() compat.AdaptiveColor
+ SyntaxFunction() compat.AdaptiveColor
+ SyntaxVariable() compat.AdaptiveColor
+ SyntaxString() compat.AdaptiveColor
+ SyntaxNumber() compat.AdaptiveColor
+ SyntaxType() compat.AdaptiveColor
+ SyntaxOperator() compat.AdaptiveColor
+ SyntaxPunctuation() compat.AdaptiveColor
}
// BaseTheme provides a default implementation of the Theme interface
// that can be embedded in concrete theme implementations.
type BaseTheme struct {
// Background colors
- BackgroundColor lipgloss.AdaptiveColor
- BackgroundSubtleColor lipgloss.AdaptiveColor
- BackgroundElementColor lipgloss.AdaptiveColor
+ BackgroundColor compat.AdaptiveColor
+ BackgroundSubtleColor compat.AdaptiveColor
+ BackgroundElementColor compat.AdaptiveColor
// Border colors
- BorderSubtleColor lipgloss.AdaptiveColor
- BorderColor lipgloss.AdaptiveColor
- BorderActiveColor lipgloss.AdaptiveColor
+ BorderSubtleColor compat.AdaptiveColor
+ BorderColor compat.AdaptiveColor
+ BorderActiveColor compat.AdaptiveColor
// Brand colors
- PrimaryColor lipgloss.AdaptiveColor
- SecondaryColor lipgloss.AdaptiveColor
- AccentColor lipgloss.AdaptiveColor
+ PrimaryColor compat.AdaptiveColor
+ SecondaryColor compat.AdaptiveColor
+ AccentColor compat.AdaptiveColor
// Text colors
- TextMutedColor lipgloss.AdaptiveColor
- TextColor lipgloss.AdaptiveColor
+ TextMutedColor compat.AdaptiveColor
+ TextColor compat.AdaptiveColor
// Status colors
- ErrorColor lipgloss.AdaptiveColor
- WarningColor lipgloss.AdaptiveColor
- SuccessColor lipgloss.AdaptiveColor
- InfoColor lipgloss.AdaptiveColor
+ ErrorColor compat.AdaptiveColor
+ WarningColor compat.AdaptiveColor
+ SuccessColor compat.AdaptiveColor
+ InfoColor compat.AdaptiveColor
// Diff view colors
- DiffAddedColor lipgloss.AdaptiveColor
- DiffRemovedColor lipgloss.AdaptiveColor
- DiffContextColor lipgloss.AdaptiveColor
- DiffHunkHeaderColor lipgloss.AdaptiveColor
- DiffHighlightAddedColor lipgloss.AdaptiveColor
- DiffHighlightRemovedColor lipgloss.AdaptiveColor
- DiffAddedBgColor lipgloss.AdaptiveColor
- DiffRemovedBgColor lipgloss.AdaptiveColor
- DiffContextBgColor lipgloss.AdaptiveColor
- DiffLineNumberColor lipgloss.AdaptiveColor
- DiffAddedLineNumberBgColor lipgloss.AdaptiveColor
- DiffRemovedLineNumberBgColor lipgloss.AdaptiveColor
+ DiffAddedColor compat.AdaptiveColor
+ DiffRemovedColor compat.AdaptiveColor
+ DiffContextColor compat.AdaptiveColor
+ DiffHunkHeaderColor compat.AdaptiveColor
+ DiffHighlightAddedColor compat.AdaptiveColor
+ DiffHighlightRemovedColor compat.AdaptiveColor
+ DiffAddedBgColor compat.AdaptiveColor
+ DiffRemovedBgColor compat.AdaptiveColor
+ DiffContextBgColor compat.AdaptiveColor
+ DiffLineNumberColor compat.AdaptiveColor
+ DiffAddedLineNumberBgColor compat.AdaptiveColor
+ DiffRemovedLineNumberBgColor compat.AdaptiveColor
// Markdown colors
- MarkdownTextColor lipgloss.AdaptiveColor
- MarkdownHeadingColor lipgloss.AdaptiveColor
- MarkdownLinkColor lipgloss.AdaptiveColor
- MarkdownLinkTextColor lipgloss.AdaptiveColor
- MarkdownCodeColor lipgloss.AdaptiveColor
- MarkdownBlockQuoteColor lipgloss.AdaptiveColor
- MarkdownEmphColor lipgloss.AdaptiveColor
- MarkdownStrongColor lipgloss.AdaptiveColor
- MarkdownHorizontalRuleColor lipgloss.AdaptiveColor
- MarkdownListItemColor lipgloss.AdaptiveColor
- MarkdownListEnumerationColor lipgloss.AdaptiveColor
- MarkdownImageColor lipgloss.AdaptiveColor
- MarkdownImageTextColor lipgloss.AdaptiveColor
- MarkdownCodeBlockColor lipgloss.AdaptiveColor
+ MarkdownTextColor compat.AdaptiveColor
+ MarkdownHeadingColor compat.AdaptiveColor
+ MarkdownLinkColor compat.AdaptiveColor
+ MarkdownLinkTextColor compat.AdaptiveColor
+ MarkdownCodeColor compat.AdaptiveColor
+ MarkdownBlockQuoteColor compat.AdaptiveColor
+ MarkdownEmphColor compat.AdaptiveColor
+ MarkdownStrongColor compat.AdaptiveColor
+ MarkdownHorizontalRuleColor compat.AdaptiveColor
+ MarkdownListItemColor compat.AdaptiveColor
+ MarkdownListEnumerationColor compat.AdaptiveColor
+ MarkdownImageColor compat.AdaptiveColor
+ MarkdownImageTextColor compat.AdaptiveColor
+ MarkdownCodeBlockColor compat.AdaptiveColor
// Syntax highlighting colors
- SyntaxCommentColor lipgloss.AdaptiveColor
- SyntaxKeywordColor lipgloss.AdaptiveColor
- SyntaxFunctionColor lipgloss.AdaptiveColor
- SyntaxVariableColor lipgloss.AdaptiveColor
- SyntaxStringColor lipgloss.AdaptiveColor
- SyntaxNumberColor lipgloss.AdaptiveColor
- SyntaxTypeColor lipgloss.AdaptiveColor
- SyntaxOperatorColor lipgloss.AdaptiveColor
- SyntaxPunctuationColor lipgloss.AdaptiveColor
+ SyntaxCommentColor compat.AdaptiveColor
+ SyntaxKeywordColor compat.AdaptiveColor
+ SyntaxFunctionColor compat.AdaptiveColor
+ SyntaxVariableColor compat.AdaptiveColor
+ SyntaxStringColor compat.AdaptiveColor
+ SyntaxNumberColor compat.AdaptiveColor
+ SyntaxTypeColor compat.AdaptiveColor
+ SyntaxOperatorColor compat.AdaptiveColor
+ SyntaxPunctuationColor compat.AdaptiveColor
}
// Implement the Theme interface for BaseTheme
-func (t *BaseTheme) Primary() lipgloss.AdaptiveColor { return t.PrimaryColor }
-func (t *BaseTheme) Secondary() lipgloss.AdaptiveColor { return t.SecondaryColor }
-func (t *BaseTheme) Accent() lipgloss.AdaptiveColor { return t.AccentColor }
-
-func (t *BaseTheme) Error() lipgloss.AdaptiveColor { return t.ErrorColor }
-func (t *BaseTheme) Warning() lipgloss.AdaptiveColor { return t.WarningColor }
-func (t *BaseTheme) Success() lipgloss.AdaptiveColor { return t.SuccessColor }
-func (t *BaseTheme) Info() lipgloss.AdaptiveColor { return t.InfoColor }
-
-func (t *BaseTheme) Text() lipgloss.AdaptiveColor { return t.TextColor }
-func (t *BaseTheme) TextMuted() lipgloss.AdaptiveColor { return t.TextMutedColor }
-
-func (t *BaseTheme) Background() lipgloss.AdaptiveColor { return t.BackgroundColor }
-func (t *BaseTheme) BackgroundSubtle() lipgloss.AdaptiveColor { return t.BackgroundSubtleColor }
-func (t *BaseTheme) BackgroundElement() lipgloss.AdaptiveColor { return t.BackgroundElementColor }
-
-func (t *BaseTheme) Border() lipgloss.AdaptiveColor { return t.BorderColor }
-func (t *BaseTheme) BorderActive() lipgloss.AdaptiveColor { return t.BorderActiveColor }
-func (t *BaseTheme) BorderSubtle() lipgloss.AdaptiveColor { return t.BorderSubtleColor }
-
-func (t *BaseTheme) DiffAdded() lipgloss.AdaptiveColor { return t.DiffAddedColor }
-func (t *BaseTheme) DiffRemoved() lipgloss.AdaptiveColor { return t.DiffRemovedColor }
-func (t *BaseTheme) DiffContext() lipgloss.AdaptiveColor { return t.DiffContextColor }
-func (t *BaseTheme) DiffHunkHeader() lipgloss.AdaptiveColor { return t.DiffHunkHeaderColor }
-func (t *BaseTheme) DiffHighlightAdded() lipgloss.AdaptiveColor { return t.DiffHighlightAddedColor }
-func (t *BaseTheme) DiffHighlightRemoved() lipgloss.AdaptiveColor { return t.DiffHighlightRemovedColor }
-func (t *BaseTheme) DiffAddedBg() lipgloss.AdaptiveColor { return t.DiffAddedBgColor }
-func (t *BaseTheme) DiffRemovedBg() lipgloss.AdaptiveColor { return t.DiffRemovedBgColor }
-func (t *BaseTheme) DiffContextBg() lipgloss.AdaptiveColor { return t.DiffContextBgColor }
-func (t *BaseTheme) DiffLineNumber() lipgloss.AdaptiveColor { return t.DiffLineNumberColor }
-func (t *BaseTheme) DiffAddedLineNumberBg() lipgloss.AdaptiveColor {
+func (t *BaseTheme) Primary() compat.AdaptiveColor { return t.PrimaryColor }
+func (t *BaseTheme) Secondary() compat.AdaptiveColor { return t.SecondaryColor }
+func (t *BaseTheme) Accent() compat.AdaptiveColor { return t.AccentColor }
+
+func (t *BaseTheme) Error() compat.AdaptiveColor { return t.ErrorColor }
+func (t *BaseTheme) Warning() compat.AdaptiveColor { return t.WarningColor }
+func (t *BaseTheme) Success() compat.AdaptiveColor { return t.SuccessColor }
+func (t *BaseTheme) Info() compat.AdaptiveColor { return t.InfoColor }
+
+func (t *BaseTheme) Text() compat.AdaptiveColor { return t.TextColor }
+func (t *BaseTheme) TextMuted() compat.AdaptiveColor { return t.TextMutedColor }
+
+func (t *BaseTheme) Background() compat.AdaptiveColor { return t.BackgroundColor }
+func (t *BaseTheme) BackgroundSubtle() compat.AdaptiveColor { return t.BackgroundSubtleColor }
+func (t *BaseTheme) BackgroundElement() compat.AdaptiveColor { return t.BackgroundElementColor }
+
+func (t *BaseTheme) Border() compat.AdaptiveColor { return t.BorderColor }
+func (t *BaseTheme) BorderActive() compat.AdaptiveColor { return t.BorderActiveColor }
+func (t *BaseTheme) BorderSubtle() compat.AdaptiveColor { return t.BorderSubtleColor }
+
+func (t *BaseTheme) DiffAdded() compat.AdaptiveColor { return t.DiffAddedColor }
+func (t *BaseTheme) DiffRemoved() compat.AdaptiveColor { return t.DiffRemovedColor }
+func (t *BaseTheme) DiffContext() compat.AdaptiveColor { return t.DiffContextColor }
+func (t *BaseTheme) DiffHunkHeader() compat.AdaptiveColor { return t.DiffHunkHeaderColor }
+func (t *BaseTheme) DiffHighlightAdded() compat.AdaptiveColor { return t.DiffHighlightAddedColor }
+func (t *BaseTheme) DiffHighlightRemoved() compat.AdaptiveColor { return t.DiffHighlightRemovedColor }
+func (t *BaseTheme) DiffAddedBg() compat.AdaptiveColor { return t.DiffAddedBgColor }
+func (t *BaseTheme) DiffRemovedBg() compat.AdaptiveColor { return t.DiffRemovedBgColor }
+func (t *BaseTheme) DiffContextBg() compat.AdaptiveColor { return t.DiffContextBgColor }
+func (t *BaseTheme) DiffLineNumber() compat.AdaptiveColor { return t.DiffLineNumberColor }
+func (t *BaseTheme) DiffAddedLineNumberBg() compat.AdaptiveColor {
return t.DiffAddedLineNumberBgColor
}
-func (t *BaseTheme) DiffRemovedLineNumberBg() lipgloss.AdaptiveColor {
+func (t *BaseTheme) DiffRemovedLineNumberBg() compat.AdaptiveColor {
return t.DiffRemovedLineNumberBgColor
}
-func (t *BaseTheme) MarkdownText() lipgloss.AdaptiveColor { return t.MarkdownTextColor }
-func (t *BaseTheme) MarkdownHeading() lipgloss.AdaptiveColor { return t.MarkdownHeadingColor }
-func (t *BaseTheme) MarkdownLink() lipgloss.AdaptiveColor { return t.MarkdownLinkColor }
-func (t *BaseTheme) MarkdownLinkText() lipgloss.AdaptiveColor { return t.MarkdownLinkTextColor }
-func (t *BaseTheme) MarkdownCode() lipgloss.AdaptiveColor { return t.MarkdownCodeColor }
-func (t *BaseTheme) MarkdownBlockQuote() lipgloss.AdaptiveColor { return t.MarkdownBlockQuoteColor }
-func (t *BaseTheme) MarkdownEmph() lipgloss.AdaptiveColor { return t.MarkdownEmphColor }
-func (t *BaseTheme) MarkdownStrong() lipgloss.AdaptiveColor { return t.MarkdownStrongColor }
-func (t *BaseTheme) MarkdownHorizontalRule() lipgloss.AdaptiveColor {
+func (t *BaseTheme) MarkdownText() compat.AdaptiveColor { return t.MarkdownTextColor }
+func (t *BaseTheme) MarkdownHeading() compat.AdaptiveColor { return t.MarkdownHeadingColor }
+func (t *BaseTheme) MarkdownLink() compat.AdaptiveColor { return t.MarkdownLinkColor }
+func (t *BaseTheme) MarkdownLinkText() compat.AdaptiveColor { return t.MarkdownLinkTextColor }
+func (t *BaseTheme) MarkdownCode() compat.AdaptiveColor { return t.MarkdownCodeColor }
+func (t *BaseTheme) MarkdownBlockQuote() compat.AdaptiveColor { return t.MarkdownBlockQuoteColor }
+func (t *BaseTheme) MarkdownEmph() compat.AdaptiveColor { return t.MarkdownEmphColor }
+func (t *BaseTheme) MarkdownStrong() compat.AdaptiveColor { return t.MarkdownStrongColor }
+func (t *BaseTheme) MarkdownHorizontalRule() compat.AdaptiveColor {
return t.MarkdownHorizontalRuleColor
}
-func (t *BaseTheme) MarkdownListItem() lipgloss.AdaptiveColor { return t.MarkdownListItemColor }
-func (t *BaseTheme) MarkdownListEnumeration() lipgloss.AdaptiveColor {
+func (t *BaseTheme) MarkdownListItem() compat.AdaptiveColor { return t.MarkdownListItemColor }
+func (t *BaseTheme) MarkdownListEnumeration() compat.AdaptiveColor {
return t.MarkdownListEnumerationColor
}
-func (t *BaseTheme) MarkdownImage() lipgloss.AdaptiveColor { return t.MarkdownImageColor }
-func (t *BaseTheme) MarkdownImageText() lipgloss.AdaptiveColor { return t.MarkdownImageTextColor }
-func (t *BaseTheme) MarkdownCodeBlock() lipgloss.AdaptiveColor { return t.MarkdownCodeBlockColor }
-
-func (t *BaseTheme) SyntaxComment() lipgloss.AdaptiveColor { return t.SyntaxCommentColor }
-func (t *BaseTheme) SyntaxKeyword() lipgloss.AdaptiveColor { return t.SyntaxKeywordColor }
-func (t *BaseTheme) SyntaxFunction() lipgloss.AdaptiveColor { return t.SyntaxFunctionColor }
-func (t *BaseTheme) SyntaxVariable() lipgloss.AdaptiveColor { return t.SyntaxVariableColor }
-func (t *BaseTheme) SyntaxString() lipgloss.AdaptiveColor { return t.SyntaxStringColor }
-func (t *BaseTheme) SyntaxNumber() lipgloss.AdaptiveColor { return t.SyntaxNumberColor }
-func (t *BaseTheme) SyntaxType() lipgloss.AdaptiveColor { return t.SyntaxTypeColor }
-func (t *BaseTheme) SyntaxOperator() lipgloss.AdaptiveColor { return t.SyntaxOperatorColor }
-func (t *BaseTheme) SyntaxPunctuation() lipgloss.AdaptiveColor { return t.SyntaxPunctuationColor }
-
-// ParseAdaptiveColor parses a color value from the config file into a lipgloss.AdaptiveColor.
+func (t *BaseTheme) MarkdownImage() compat.AdaptiveColor { return t.MarkdownImageColor }
+func (t *BaseTheme) MarkdownImageText() compat.AdaptiveColor { return t.MarkdownImageTextColor }
+func (t *BaseTheme) MarkdownCodeBlock() compat.AdaptiveColor { return t.MarkdownCodeBlockColor }
+
+func (t *BaseTheme) SyntaxComment() compat.AdaptiveColor { return t.SyntaxCommentColor }
+func (t *BaseTheme) SyntaxKeyword() compat.AdaptiveColor { return t.SyntaxKeywordColor }
+func (t *BaseTheme) SyntaxFunction() compat.AdaptiveColor { return t.SyntaxFunctionColor }
+func (t *BaseTheme) SyntaxVariable() compat.AdaptiveColor { return t.SyntaxVariableColor }
+func (t *BaseTheme) SyntaxString() compat.AdaptiveColor { return t.SyntaxStringColor }
+func (t *BaseTheme) SyntaxNumber() compat.AdaptiveColor { return t.SyntaxNumberColor }
+func (t *BaseTheme) SyntaxType() compat.AdaptiveColor { return t.SyntaxTypeColor }
+func (t *BaseTheme) SyntaxOperator() compat.AdaptiveColor { return t.SyntaxOperatorColor }
+func (t *BaseTheme) SyntaxPunctuation() compat.AdaptiveColor { return t.SyntaxPunctuationColor }
+
+// ParseAdaptiveColor parses a color value from the config file into a compat.AdaptiveColor.
// It accepts either a string (hex color) or a map with "dark" and "light" keys.
-func ParseAdaptiveColor(value any) (lipgloss.AdaptiveColor, error) {
+func ParseAdaptiveColor(value any) (compat.AdaptiveColor, error) {
// Regular expression to validate hex color format
hexColorRegex := regexp.MustCompile(`^#[0-9a-fA-F]{6}$`)
// Case 1: String value (same color for both dark and light modes)
if hexColor, ok := value.(string); ok {
if !hexColorRegex.MatchString(hexColor) {
- return lipgloss.AdaptiveColor{}, fmt.Errorf("invalid hex color format: %s", hexColor)
+ return compat.AdaptiveColor{}, fmt.Errorf("invalid hex color format: %s", hexColor)
}
- return lipgloss.AdaptiveColor{
- Dark: hexColor,
- Light: hexColor,
+ return compat.AdaptiveColor{
+ Dark: lipgloss.Color(hexColor),
+ Light: lipgloss.Color(hexColor),
}, nil
}
@@ -236,11 +237,11 @@ func ParseAdaptiveColor(value any) (lipgloss.AdaptiveColor, error) {
if numericVal, ok := value.(float64); ok {
intVal := int(numericVal)
if intVal < 0 || intVal > 255 {
- return lipgloss.AdaptiveColor{}, fmt.Errorf("invalid int color value (must be between 0 and 255): %d", intVal)
+ return compat.AdaptiveColor{}, fmt.Errorf("invalid int color value (must be between 0 and 255): %d", intVal)
}
- return lipgloss.AdaptiveColor{
- Dark: fmt.Sprintf("%d", intVal),
- Light: fmt.Sprintf("%d", intVal),
+ return compat.AdaptiveColor{
+ Dark: lipgloss.Color(fmt.Sprintf("%d", intVal)),
+ Light: lipgloss.Color(fmt.Sprintf("%d", intVal)),
}, nil
}
@@ -250,7 +251,7 @@ func ParseAdaptiveColor(value any) (lipgloss.AdaptiveColor, error) {
lightVal, lightOk := colorMap["light"]
if !darkOk || !lightOk {
- return lipgloss.AdaptiveColor{}, fmt.Errorf("color map must contain both 'dark' and 'light' keys")
+ return compat.AdaptiveColor{}, fmt.Errorf("color map must contain both 'dark' and 'light' keys")
}
darkHex, darkIsString := darkVal.(string)
@@ -261,27 +262,27 @@ func ParseAdaptiveColor(value any) (lipgloss.AdaptiveColor, error) {
lightVal, lightIsNumber := lightVal.(float64)
if !darkIsNumber || !lightIsNumber {
- return lipgloss.AdaptiveColor{}, fmt.Errorf("color map values must be strings or ints")
+ return compat.AdaptiveColor{}, fmt.Errorf("color map values must be strings or ints")
}
darkInt := int(darkVal)
lightInt := int(lightVal)
- return lipgloss.AdaptiveColor{
- Dark: fmt.Sprintf("%d", darkInt),
- Light: fmt.Sprintf("%d", lightInt),
+ return compat.AdaptiveColor{
+ Dark: lipgloss.Color(fmt.Sprintf("%d", darkInt)),
+ Light: lipgloss.Color(fmt.Sprintf("%d", lightInt)),
}, nil
}
if !hexColorRegex.MatchString(darkHex) || !hexColorRegex.MatchString(lightHex) {
- return lipgloss.AdaptiveColor{}, fmt.Errorf("invalid hex color format")
+ return compat.AdaptiveColor{}, fmt.Errorf("invalid hex color format")
}
- return lipgloss.AdaptiveColor{
- Dark: darkHex,
- Light: lightHex,
+ return compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkHex),
+ Light: lipgloss.Color(lightHex),
}, nil
}
- return lipgloss.AdaptiveColor{}, fmt.Errorf("color must be either a hex string or an object with dark/light keys")
+ return compat.AdaptiveColor{}, fmt.Errorf("color must be either a hex string or an object with dark/light keys")
}
diff --git a/packages/tui/internal/theme/tokyonight.go b/packages/tui/internal/theme/tokyonight.go
index 7ae53abc5..8bb32dced 100644
--- a/packages/tui/internal/theme/tokyonight.go
+++ b/packages/tui/internal/theme/tokyonight.go
@@ -1,7 +1,8 @@
package theme
import (
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/lipgloss/v2"
+ "github.com/charmbracelet/lipgloss/v2/compat"
)
// TokyoNightTheme implements the Theme interface with Tokyo Night colors.
@@ -70,219 +71,219 @@ func NewTokyoNightTheme() *TokyoNightTheme {
theme := &TokyoNightTheme{}
// Base colors
- theme.PrimaryColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
+ theme.PrimaryColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkBlue),
+ Light: lipgloss.Color(lightBlue),
}
- theme.SecondaryColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
+ theme.SecondaryColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkPurple),
+ Light: lipgloss.Color(lightPurple),
}
- theme.AccentColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
+ theme.AccentColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkOrange),
+ Light: lipgloss.Color(lightOrange),
}
// Status colors
- theme.ErrorColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
+ theme.ErrorColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkRed),
+ Light: lipgloss.Color(lightRed),
}
- theme.WarningColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
+ theme.WarningColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkOrange),
+ Light: lipgloss.Color(lightOrange),
}
- theme.SuccessColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
+ theme.SuccessColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkGreen),
+ Light: lipgloss.Color(lightGreen),
}
- theme.InfoColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
+ theme.InfoColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkBlue),
+ Light: lipgloss.Color(lightBlue),
}
// Text colors
- theme.TextColor = lipgloss.AdaptiveColor{
- Dark: darkStep12,
- Light: lightStep12,
+ theme.TextColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep12),
+ Light: lipgloss.Color(lightStep12),
}
- theme.TextMutedColor = lipgloss.AdaptiveColor{
- Dark: darkStep11,
- Light: lightStep11,
+ theme.TextMutedColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep11),
+ Light: lipgloss.Color(lightStep11),
}
// Background colors
- theme.BackgroundColor = lipgloss.AdaptiveColor{
- Dark: darkStep1,
- Light: lightStep1,
+ theme.BackgroundColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep1),
+ Light: lipgloss.Color(lightStep1),
}
- theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkStep2,
- Light: lightStep2,
+ theme.BackgroundSubtleColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep2),
+ Light: lipgloss.Color(lightStep2),
}
- theme.BackgroundElementColor = lipgloss.AdaptiveColor{
- Dark: darkStep3,
- Light: lightStep3,
+ theme.BackgroundElementColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep3),
+ Light: lipgloss.Color(lightStep3),
}
// Border colors
- theme.BorderColor = lipgloss.AdaptiveColor{
- Dark: darkStep7,
- Light: lightStep7,
+ theme.BorderColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep7),
+ Light: lipgloss.Color(lightStep7),
}
- theme.BorderActiveColor = lipgloss.AdaptiveColor{
- Dark: darkStep8,
- Light: lightStep8,
+ theme.BorderActiveColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep8),
+ Light: lipgloss.Color(lightStep8),
}
- theme.BorderSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkStep6,
- Light: lightStep6,
+ theme.BorderSubtleColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep6),
+ Light: lipgloss.Color(lightStep6),
}
// Diff view colors
- theme.DiffAddedColor = lipgloss.AdaptiveColor{
- Dark: "#4fd6be", // teal from palette
- Light: "#1e725c",
+ theme.DiffAddedColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#4fd6be"), // teal from palette
+ Light: lipgloss.Color("#1e725c"),
}
- theme.DiffRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#c53b53", // red1 from palette
- Light: "#c53b53",
+ theme.DiffRemovedColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#c53b53"), // red1 from palette
+ Light: lipgloss.Color("#c53b53"),
}
- theme.DiffContextColor = lipgloss.AdaptiveColor{
- Dark: "#828bb8", // fg_dark from palette
- Light: "#7086b5",
+ theme.DiffContextColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#828bb8"), // fg_dark from palette
+ Light: lipgloss.Color("#7086b5"),
}
- theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
- Dark: "#828bb8", // fg_dark from palette
- Light: "#7086b5",
+ theme.DiffHunkHeaderColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#828bb8"), // fg_dark from palette
+ Light: lipgloss.Color("#7086b5"),
}
- theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
- Dark: "#b8db87", // git.add from palette
- Light: "#4db380",
+ theme.DiffHighlightAddedColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#b8db87"), // git.add from palette
+ Light: lipgloss.Color("#4db380"),
}
- theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#e26a75", // git.delete from palette
- Light: "#f52a65",
+ theme.DiffHighlightRemovedColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#e26a75"), // git.delete from palette
+ Light: lipgloss.Color("#f52a65"),
}
- theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
- Dark: "#20303b",
- Light: "#d5e5d5",
+ theme.DiffAddedBgColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#20303b"),
+ Light: lipgloss.Color("#d5e5d5"),
}
- theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
- Dark: "#37222c",
- Light: "#f7d8db",
+ theme.DiffRemovedBgColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#37222c"),
+ Light: lipgloss.Color("#f7d8db"),
}
- theme.DiffContextBgColor = lipgloss.AdaptiveColor{
- Dark: darkStep2,
- Light: lightStep2,
+ theme.DiffContextBgColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep2),
+ Light: lipgloss.Color(lightStep2),
}
- theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
- Dark: darkStep3, // dark3 from palette
- Light: lightStep3,
+ theme.DiffLineNumberColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep3), // dark3 from palette
+ Light: lipgloss.Color(lightStep3),
}
- theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#1b2b34",
- Light: "#c5d5c5",
+ theme.DiffAddedLineNumberBgColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#1b2b34"),
+ Light: lipgloss.Color("#c5d5c5"),
}
- theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#2d1f26",
- Light: "#e7c8cb",
+ theme.DiffRemovedLineNumberBgColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color("#2d1f26"),
+ Light: lipgloss.Color("#e7c8cb"),
}
// Markdown colors
- theme.MarkdownTextColor = lipgloss.AdaptiveColor{
- Dark: darkStep12,
- Light: lightStep12,
+ theme.MarkdownTextColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep12),
+ Light: lipgloss.Color(lightStep12),
}
- theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
+ theme.MarkdownHeadingColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkPurple),
+ Light: lipgloss.Color(lightPurple),
}
- theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
+ theme.MarkdownLinkColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkBlue),
+ Light: lipgloss.Color(lightBlue),
}
- theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
+ theme.MarkdownLinkTextColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkCyan),
+ Light: lipgloss.Color(lightCyan),
}
- theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
+ theme.MarkdownCodeColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkGreen),
+ Light: lipgloss.Color(lightGreen),
}
- theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
+ theme.MarkdownBlockQuoteColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkYellow),
+ Light: lipgloss.Color(lightYellow),
}
- theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
+ theme.MarkdownEmphColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkYellow),
+ Light: lipgloss.Color(lightYellow),
}
- theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
+ theme.MarkdownStrongColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkOrange),
+ Light: lipgloss.Color(lightOrange),
}
- theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
- Dark: darkStep11,
- Light: lightStep11,
+ theme.MarkdownHorizontalRuleColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep11),
+ Light: lipgloss.Color(lightStep11),
}
- theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
+ theme.MarkdownListItemColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkBlue),
+ Light: lipgloss.Color(lightBlue),
}
- theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
+ theme.MarkdownListEnumerationColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkCyan),
+ Light: lipgloss.Color(lightCyan),
}
- theme.MarkdownImageColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
+ theme.MarkdownImageColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkBlue),
+ Light: lipgloss.Color(lightBlue),
}
- theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
+ theme.MarkdownImageTextColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkCyan),
+ Light: lipgloss.Color(lightCyan),
}
- theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
- Dark: darkStep12,
- Light: lightStep12,
+ theme.MarkdownCodeBlockColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep12),
+ Light: lipgloss.Color(lightStep12),
}
// Syntax highlighting colors
- theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
- Dark: darkStep11,
- Light: lightStep11,
+ theme.SyntaxCommentColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep11),
+ Light: lipgloss.Color(lightStep11),
}
- theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
+ theme.SyntaxKeywordColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkPurple),
+ Light: lipgloss.Color(lightPurple),
}
- theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
+ theme.SyntaxFunctionColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkBlue),
+ Light: lipgloss.Color(lightBlue),
}
- theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
+ theme.SyntaxVariableColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkRed),
+ Light: lipgloss.Color(lightRed),
}
- theme.SyntaxStringColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
+ theme.SyntaxStringColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkGreen),
+ Light: lipgloss.Color(lightGreen),
}
- theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
+ theme.SyntaxNumberColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkOrange),
+ Light: lipgloss.Color(lightOrange),
}
- theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
+ theme.SyntaxTypeColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkYellow),
+ Light: lipgloss.Color(lightYellow),
}
- theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
+ theme.SyntaxOperatorColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkCyan),
+ Light: lipgloss.Color(lightCyan),
}
- theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
- Dark: darkStep12,
- Light: lightStep12,
+ theme.SyntaxPunctuationColor = compat.AdaptiveColor{
+ Dark: lipgloss.Color(darkStep12),
+ Light: lipgloss.Color(lightStep12),
}
return theme
diff --git a/packages/tui/internal/theme/tron.go b/packages/tui/internal/theme/tron.go
deleted file mode 100644
index ea9756753..000000000
--- a/packages/tui/internal/theme/tron.go
+++ /dev/null
@@ -1,272 +0,0 @@
-package theme
-
-import (
- "github.com/charmbracelet/lipgloss"
-)
-
-// TronTheme implements the Theme interface with Tron-inspired colors.
-// It provides both dark and light variants, though Tron is primarily a dark theme.
-type TronTheme struct {
- BaseTheme
-}
-
-// NewTronTheme creates a new instance of the Tron theme.
-func NewTronTheme() *TronTheme {
- // Tron color palette
- // Inspired by the Tron movie's neon aesthetic
- darkBackground := "#0c141f"
- darkCurrentLine := "#1a2633"
- darkSelection := "#1a2633"
- darkForeground := "#caf0ff"
- darkComment := "#4d6b87"
- darkCyan := "#00d9ff"
- darkBlue := "#007fff"
- darkOrange := "#ff9000"
- darkPink := "#ff00a0"
- darkPurple := "#b73fff"
- darkRed := "#ff3333"
- darkYellow := "#ffcc00"
- darkGreen := "#00ff8f"
- darkBorder := "#1a2633"
-
- // Light mode approximation
- lightBackground := "#f0f8ff"
- lightCurrentLine := "#e0f0ff"
- lightSelection := "#d0e8ff"
- lightForeground := "#0c141f"
- lightComment := "#4d6b87"
- lightCyan := "#0097b3"
- lightBlue := "#0066cc"
- lightOrange := "#cc7300"
- lightPink := "#cc0080"
- lightPurple := "#9932cc"
- lightRed := "#cc2929"
- lightYellow := "#cc9900"
- lightGreen := "#00cc72"
- lightBorder := "#d0e8ff"
-
- theme := &TronTheme{}
-
- // Base colors
- theme.PrimaryColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.SecondaryColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.AccentColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
-
- // Status colors
- theme.ErrorColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
- }
- theme.WarningColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.SuccessColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.InfoColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
-
- // Text colors
- theme.TextColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.TextMutedColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
-
- // Background colors
- theme.BackgroundColor = lipgloss.AdaptiveColor{
- Dark: darkBackground,
- Light: lightBackground,
- }
- theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkCurrentLine,
- Light: lightCurrentLine,
- }
- theme.BackgroundElementColor = lipgloss.AdaptiveColor{
- Dark: "#070d14", // Slightly darker than background
- Light: "#ffffff", // Slightly lighter than background
- }
-
- // Border colors
- theme.BorderColor = lipgloss.AdaptiveColor{
- Dark: darkBorder,
- Light: lightBorder,
- }
- theme.BorderActiveColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.BorderSubtleColor = lipgloss.AdaptiveColor{
- Dark: darkSelection,
- Light: lightSelection,
- }
-
- // Diff view colors
- theme.DiffAddedColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.DiffRemovedColor = lipgloss.AdaptiveColor{
- Dark: darkRed,
- Light: lightRed,
- }
- theme.DiffContextColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
- Dark: "#00ff8f",
- Light: "#a5d6a7",
- }
- theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
- Dark: "#ff3333",
- Light: "#ef9a9a",
- }
- theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
- Dark: "#0a2a1a",
- Light: "#e8f5e9",
- }
- theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
- Dark: "#2a0a0a",
- Light: "#ffebee",
- }
- theme.DiffContextBgColor = lipgloss.AdaptiveColor{
- Dark: darkBackground,
- Light: lightBackground,
- }
- theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#082015",
- Light: "#c8e6c9",
- }
- theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
- Dark: "#200808",
- Light: "#ffcdd2",
- }
-
- // Markdown colors
- theme.MarkdownTextColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
- theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownImageColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
-
- // Syntax highlighting colors
- theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
- Dark: darkComment,
- Light: lightComment,
- }
- theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
- Dark: darkCyan,
- Light: lightCyan,
- }
- theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
- Dark: darkGreen,
- Light: lightGreen,
- }
- theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
- Dark: darkOrange,
- Light: lightOrange,
- }
- theme.SyntaxStringColor = lipgloss.AdaptiveColor{
- Dark: darkYellow,
- Light: lightYellow,
- }
- theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
- Dark: darkBlue,
- Light: lightBlue,
- }
- theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
- Dark: darkPurple,
- Light: lightPurple,
- }
- theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
- Dark: darkPink,
- Light: lightPink,
- }
- theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
- Dark: darkForeground,
- Light: lightForeground,
- }
-
- return theme
-}
-
-func init() {
- // Register the Tron theme with the theme manager
- RegisterTheme("tron", NewTronTheme())
-}
diff --git a/packages/tui/internal/tui/tui.go b/packages/tui/internal/tui/tui.go
index e4fdb4ae2..29ce635d6 100644
--- a/packages/tui/internal/tui/tui.go
+++ b/packages/tui/internal/tui/tui.go
@@ -5,11 +5,11 @@ import (
"log/slog"
"strings"
- "github.com/charmbracelet/bubbles/cursor"
- "github.com/charmbracelet/bubbles/key"
- "github.com/charmbracelet/bubbles/spinner"
- tea "github.com/charmbracelet/bubbletea"
- "github.com/charmbracelet/lipgloss"
+ "github.com/charmbracelet/bubbles/v2/cursor"
+ "github.com/charmbracelet/bubbles/v2/key"
+ "github.com/charmbracelet/bubbles/v2/spinner"
+ tea "github.com/charmbracelet/bubbletea/v2"
+ "github.com/charmbracelet/lipgloss/v2"
"github.com/sst/opencode/internal/app"
"github.com/sst/opencode/internal/components/core"
@@ -18,6 +18,8 @@ import (
"github.com/sst/opencode/internal/page"
"github.com/sst/opencode/internal/state"
"github.com/sst/opencode/internal/status"
+ "github.com/sst/opencode/internal/styles"
+ "github.com/sst/opencode/internal/theme"
"github.com/sst/opencode/internal/util"
"github.com/sst/opencode/pkg/client"
)
@@ -90,16 +92,16 @@ type appModel struct {
width, height int
currentPage page.PageID
previousPage page.PageID
- pages map[page.PageID]tea.Model
+ pages map[page.PageID]layout.ModelWithView
loadedPages map[page.PageID]bool
- status core.StatusCmp
+ status core.StatusComponent
app *app.App
showPermissions bool
- permissions dialog.PermissionDialogCmp
+ permissions dialog.PermissionDialogComponent
showHelp bool
- help dialog.HelpCmp
+ help dialog.HelpComponent
showQuit bool
quit dialog.QuitDialog
@@ -118,7 +120,7 @@ type appModel struct {
initDialog dialog.InitDialogCmp
showFilepicker bool
- filepicker dialog.FilepickerCmp
+ filepicker dialog.FilepickerComponent
showThemeDialog bool
themeDialog dialog.ThemeDialog
@@ -131,7 +133,12 @@ type appModel struct {
}
func (a appModel) Init() tea.Cmd {
+ t := theme.CurrentTheme()
var cmds []tea.Cmd
+ cmds = append(cmds, tea.SetBackgroundColor(t.Background()))
+ // cmds = append(cmds, tea.SetForegroundColor(t.Background()))
+ cmds = append(cmds, tea.RequestBackgroundColor)
+
cmd := a.pages[a.currentPage].Init()
a.loadedPages[a.currentPage] = true
cmds = append(cmds, cmd)
@@ -170,13 +177,14 @@ func (a appModel) updateAllPages(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
for id := range a.pages {
- a.pages[id], cmd = a.pages[id].Update(msg)
+ updated, cmd := a.pages[id].Update(msg)
+ a.pages[id] = updated.(layout.ModelWithView)
cmds = append(cmds, cmd)
}
s, cmd := a.status.Update(msg)
cmds = append(cmds, cmd)
- a.status = s.(core.StatusCmp)
+ a.status = s.(core.StatusComponent)
return a, tea.Batch(cmds...)
}
@@ -185,6 +193,10 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
var cmd tea.Cmd
switch msg := msg.(type) {
+ case tea.BackgroundColorMsg:
+ styles.Terminal = &styles.TerminalInfo{
+ BackgroundIsDark: msg.IsDark(),
+ }
case cursor.BlinkMsg:
return a.updateAllPages(msg)
case spinner.TickMsg:
@@ -234,16 +246,17 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
s, _ := a.status.Update(msg)
- a.status = s.(core.StatusCmp)
- a.pages[a.currentPage], cmd = a.pages[a.currentPage].Update(msg)
+ a.status = s.(core.StatusComponent)
+ updated, cmd := a.pages[a.currentPage].Update(msg)
+ a.pages[a.currentPage] = updated.(layout.ModelWithView)
cmds = append(cmds, cmd)
prm, permCmd := a.permissions.Update(msg)
- a.permissions = prm.(dialog.PermissionDialogCmp)
+ a.permissions = prm.(dialog.PermissionDialogComponent)
cmds = append(cmds, permCmd)
help, helpCmd := a.help.Update(msg)
- a.help = help.(dialog.HelpCmp)
+ a.help = help.(dialog.HelpComponent)
cmds = append(cmds, helpCmd)
session, sessionCmd := a.sessionDialog.Update(msg)
@@ -255,7 +268,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
cmds = append(cmds, commandCmd)
filepicker, filepickerCmd := a.filepicker.Update(msg)
- a.filepicker = filepicker.(dialog.FilepickerCmp)
+ a.filepicker = filepicker.(dialog.FilepickerComponent)
cmds = append(cmds, filepickerCmd)
a.initDialog.SetSize(msg.Width, msg.Height)
@@ -342,10 +355,19 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
a.app.Config.Theme = msg.ThemeName
a.app.SaveConfig()
- a.pages[a.currentPage], cmd = a.pages[a.currentPage].Update(msg)
+ updated, cmd := a.pages[a.currentPage].Update(msg)
+ if cmd != nil {
+ cmds = append(cmds, cmd)
+ }
+
+ t := theme.CurrentTheme()
+ cmds = append(cmds, tea.SetBackgroundColor(t.Background()))
+ // cmds = append(cmds, tea.RequestBackgroundColor)
+
+ a.pages[a.currentPage] = updated.(layout.ModelWithView)
a.showThemeDialog = false
status.Info("Theme changed to: " + msg.ThemeName)
- return a, cmd
+ return a, tea.Batch(cmds...)
case dialog.ShowInitDialogMsg:
a.showInitDialog = msg.Show
@@ -597,13 +619,13 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
default:
f, filepickerCmd := a.filepicker.Update(msg)
- a.filepicker = f.(dialog.FilepickerCmp)
+ a.filepicker = f.(dialog.FilepickerComponent)
cmds = append(cmds, filepickerCmd)
}
if a.showFilepicker {
f, filepickerCmd := a.filepicker.Update(msg)
- a.filepicker = f.(dialog.FilepickerCmp)
+ a.filepicker = f.(dialog.FilepickerComponent)
cmds = append(cmds, filepickerCmd)
// Only block key messages send all other messages down
if _, ok := msg.(tea.KeyMsg); ok {
@@ -623,7 +645,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if a.showPermissions {
d, permissionsCmd := a.permissions.Update(msg)
- a.permissions = d.(dialog.PermissionDialogCmp)
+ a.permissions = d.(dialog.PermissionDialogComponent)
cmds = append(cmds, permissionsCmd)
// Only block key messages send all other messages down
if _, ok := msg.(tea.KeyMsg); ok {
@@ -693,9 +715,10 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
s, cmd := a.status.Update(msg)
cmds = append(cmds, cmd)
- a.status = s.(core.StatusCmp)
+ a.status = s.(core.StatusComponent)
- a.pages[a.currentPage], cmd = a.pages[a.currentPage].Update(msg)
+ updated, cmd := a.pages[a.currentPage].Update(msg)
+ a.pages[a.currentPage] = updated.(layout.ModelWithView)
cmds = append(cmds, cmd)
return a, tea.Batch(cmds...)
}
@@ -930,7 +953,7 @@ func NewModel(app *app.App) tea.Model {
toolsDialog: dialog.NewToolsDialogCmp(),
app: app,
commands: []dialog.Command{},
- pages: map[page.PageID]tea.Model{
+ pages: map[page.PageID]layout.ModelWithView{
page.ChatPage: page.NewChatPage(app),
},
filepicker: dialog.NewFilepickerCmp(app),
diff --git a/packages/tui/internal/util/util.go b/packages/tui/internal/util/util.go
index fe2cf71e5..537d852d6 100644
--- a/packages/tui/internal/util/util.go
+++ b/packages/tui/internal/util/util.go
@@ -1,7 +1,7 @@
package util
import (
- tea "github.com/charmbracelet/bubbletea"
+ tea "github.com/charmbracelet/bubbletea/v2"
)
func CmdHandler(msg tea.Msg) tea.Cmd {