mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-21 01:34:22 +01:00
wip: refactoring tui
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
zone "github.com/lrstanley/bubblezone"
|
zone "github.com/lrstanley/bubblezone"
|
||||||
"github.com/sst/opencode/internal/app"
|
"github.com/sst/opencode/internal/app"
|
||||||
"github.com/sst/opencode/internal/pubsub"
|
"github.com/sst/opencode/internal/pubsub"
|
||||||
@@ -65,6 +65,8 @@ func main() {
|
|||||||
zone.NewGlobal()
|
zone.NewGlobal()
|
||||||
program := tea.NewProgram(
|
program := tea.NewProgram(
|
||||||
tui.NewModel(app_),
|
tui.NewModel(app_),
|
||||||
|
// tea.WithMouseCellMotion(),
|
||||||
|
tea.WithKeyboardEnhancements(),
|
||||||
tea.WithAltScreen(),
|
tea.WithAltScreen(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,12 @@ go 1.24.0
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.5.0
|
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/bmatcuk/doublestar/v4 v4.8.1
|
||||||
github.com/catppuccin/go v0.3.0
|
github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1
|
||||||
github.com/charmbracelet/bubbles v0.21.0
|
github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.3
|
||||||
github.com/charmbracelet/bubbletea v1.3.4
|
github.com/charmbracelet/glamour v0.10.0
|
||||||
github.com/charmbracelet/glamour v0.9.1
|
github.com/charmbracelet/lipgloss/v2 v2.0.0-beta1
|
||||||
github.com/charmbracelet/lipgloss v1.1.0
|
|
||||||
github.com/charmbracelet/x/ansi v0.8.0
|
github.com/charmbracelet/x/ansi v0.8.0
|
||||||
github.com/lithammer/fuzzysearch v1.1.8
|
github.com/lithammer/fuzzysearch v1.1.8
|
||||||
github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231
|
github.com/lrstanley/bubblezone v0.0.0-20250315020633-c249a3fe1231
|
||||||
@@ -28,6 +27,11 @@ require (
|
|||||||
dario.cat/mergo v1.0.2 // indirect
|
dario.cat/mergo v1.0.2 // indirect
|
||||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||||
github.com/atombender/go-jsonschema v0.20.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/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||||
github.com/getkin/kin-openapi v0.127.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/atotto/clipboard v0.1.4
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
|
github.com/charmbracelet/colorprofile v0.3.1 // indirect
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
|
github.com/charmbracelet/x/cellbuf v0.0.14-0.20250501183327-ad3bc78c6a81 // indirect
|
||||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
github.com/charmbracelet/x/term v0.2.1 // indirect
|
||||||
github.com/disintegration/imaging v1.6.2
|
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/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||||
github.com/google/go-cmp v0.7.0 // indirect
|
github.com/google/go-cmp v0.7.0 // indirect
|
||||||
github.com/gorilla/css v1.0.1 // indirect
|
github.com/gorilla/css v1.0.1 // indirect
|
||||||
|
|||||||
@@ -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/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 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
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.18.0 h1:6h53Q4hW83SuF+jcsp7CVhLsMozzvQvO8HBbKQW+gn4=
|
||||||
github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio=
|
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 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
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=
|
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 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 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
|
||||||
github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
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/charmbracelet/bubbles/v2 v2.0.0-beta.1 h1:swACzss0FjnyPz1enfX56GKkLiuKg5FlyVmOLIlU2kE=
|
||||||
github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
|
github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1/go.mod h1:6HamsBKWqEC/FVHuQMHgQL+knPyvHH55HwJDHl/adMw=
|
||||||
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/bubbletea v1.3.4 h1:kCg7B+jSCFPLYRA52SDZjr51kG/fMUEoPoZrkaDHyoI=
|
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/bubbletea v1.3.4/go.mod h1:dtcUCyCGEX3g9tosuYiut3MXgY/Jsv9nKVdibKKRRXo=
|
||||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
|
github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.3 h1:5A2e3myxXMpCES+kjEWgGsaf9VgZXjZbLi5iMTH7j40=
|
||||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
|
github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.3/go.mod h1:ZFDg5oPjyRYrPAa3iFrtP1DO8xy+LUQxd9JFHEcuwJY=
|
||||||
github.com/charmbracelet/glamour v0.9.1 h1:11dEfiGP8q1BEqvGoIjivuc2rBk+5qEXdPtaQ2WoiCM=
|
github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40=
|
||||||
github.com/charmbracelet/glamour v0.9.1/go.mod h1:+SHvIS8qnwhgTpVMiXwn7OfGomSqff1cHBCI8jLOetk=
|
github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0=
|
||||||
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
github.com/charmbracelet/glamour v0.10.0 h1:MtZvfwsYCx8jEPFJm3rIBFIMZUfUJ765oX8V6kXldcY=
|
||||||
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
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 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
|
||||||
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
|
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.14-0.20250501183327-ad3bc78c6a81 h1:iGrflaL5jQW6crML+pZx/ulWAVZQR3CQoRGvFsr2Tyg=
|
||||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
|
github.com/charmbracelet/x/cellbuf v0.0.14-0.20250501183327-ad3bc78c6a81/go.mod h1:poPFOXFTsJsnLbkV3H2KxAAXT7pdjxxLujLocWjkyzM=
|
||||||
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
|
github.com/charmbracelet/x/exp/golden v0.0.0-20250207160936-21c02780d27a h1:FsHEJ52OC4VuTzU8t+n5frMjLvpYWEznSr/u8tnkCYw=
|
||||||
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
|
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 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
|
||||||
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
|
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/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/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
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/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 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
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.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
|
||||||
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
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-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 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w=
|
||||||
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q=
|
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q=
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/sst/opencode/internal/config"
|
"github.com/sst/opencode/internal/config"
|
||||||
"github.com/sst/opencode/internal/fileutil"
|
"github.com/sst/opencode/internal/fileutil"
|
||||||
"github.com/sst/opencode/internal/state"
|
"github.com/sst/opencode/internal/state"
|
||||||
|
|||||||
@@ -5,15 +5,13 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"slices"
|
|
||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
"github.com/charmbracelet/bubbles/spinner"
|
"github.com/charmbracelet/bubbles/v2/spinner"
|
||||||
"github.com/charmbracelet/bubbles/textarea"
|
"github.com/charmbracelet/bubbles/v2/textarea"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/app"
|
"github.com/sst/opencode/internal/app"
|
||||||
"github.com/sst/opencode/internal/components/dialog"
|
"github.com/sst/opencode/internal/components/dialog"
|
||||||
"github.com/sst/opencode/internal/image"
|
"github.com/sst/opencode/internal/image"
|
||||||
@@ -129,18 +127,18 @@ func (m *editorComponent) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
m.attachments = nil
|
m.attachments = nil
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
if m.deleteMode && len(msg.Runes) > 0 && unicode.IsDigit(msg.Runes[0]) {
|
// if m.deleteMode && len(msg.Runes) > 0 && unicode.IsDigit(msg.Runes[0]) {
|
||||||
num := int(msg.Runes[0] - '0')
|
// num := int(msg.Runes[0] - '0')
|
||||||
m.deleteMode = false
|
// m.deleteMode = false
|
||||||
if num < 10 && len(m.attachments) > num {
|
// if num < 10 && len(m.attachments) > num {
|
||||||
if num == 0 {
|
// if num == 0 {
|
||||||
m.attachments = m.attachments[num+1:]
|
// m.attachments = m.attachments[num+1:]
|
||||||
} else {
|
// } else {
|
||||||
m.attachments = slices.Delete(m.attachments, num, num+1)
|
// m.attachments = slices.Delete(m.attachments, num, num+1)
|
||||||
}
|
// }
|
||||||
return m, nil
|
// return m, nil
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
if key.Matches(msg, messageKeys.PageUp) || key.Matches(msg, messageKeys.PageDown) ||
|
if key.Matches(msg, messageKeys.PageUp) || key.Matches(msg, messageKeys.PageDown) ||
|
||||||
key.Matches(msg, messageKeys.HalfPageUp) || key.Matches(msg, messageKeys.HalfPageDown) {
|
key.Matches(msg, messageKeys.HalfPageUp) || key.Matches(msg, messageKeys.HalfPageDown) {
|
||||||
return m, nil
|
return m, nil
|
||||||
@@ -258,7 +256,7 @@ func (m *editorComponent) View() string {
|
|||||||
m.textarea.View(),
|
m.textarea.View(),
|
||||||
)
|
)
|
||||||
textarea = styles.BaseStyle().
|
textarea = styles.BaseStyle().
|
||||||
Width(m.width-2).
|
Width(m.width). // -2).
|
||||||
Border(lipgloss.NormalBorder(), true, true).
|
Border(lipgloss.NormalBorder(), true, true).
|
||||||
BorderForeground(t.Border()).
|
BorderForeground(t.Border()).
|
||||||
Render(textarea)
|
Render(textarea)
|
||||||
@@ -286,10 +284,7 @@ func (m *editorComponent) View() string {
|
|||||||
info,
|
info,
|
||||||
)
|
)
|
||||||
|
|
||||||
return styles.ForceReplaceBackgroundWithLipgloss(
|
return content
|
||||||
content,
|
|
||||||
t.Background(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *editorComponent) SetSize(width, height int) tea.Cmd {
|
func (m *editorComponent) SetSize(width, height int) tea.Cmd {
|
||||||
@@ -414,14 +409,14 @@ func createTextArea(existing *textarea.Model) textarea.Model {
|
|||||||
ta := textarea.New()
|
ta := textarea.New()
|
||||||
ta.Placeholder = "It's prompting time..."
|
ta.Placeholder = "It's prompting time..."
|
||||||
|
|
||||||
ta.BlurredStyle.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
|
ta.Styles.Blurred.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
|
||||||
ta.BlurredStyle.CursorLine = styles.BaseStyle().Background(bgColor)
|
ta.Styles.Blurred.CursorLine = styles.BaseStyle().Background(bgColor)
|
||||||
ta.BlurredStyle.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
|
ta.Styles.Blurred.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
|
||||||
ta.BlurredStyle.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
|
ta.Styles.Blurred.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
|
||||||
ta.FocusedStyle.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
|
ta.Styles.Focused.Base = styles.BaseStyle().Background(bgColor).Foreground(textColor)
|
||||||
ta.FocusedStyle.CursorLine = styles.BaseStyle().Background(bgColor)
|
ta.Styles.Focused.CursorLine = styles.BaseStyle().Background(bgColor)
|
||||||
ta.FocusedStyle.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
|
ta.Styles.Focused.Placeholder = styles.BaseStyle().Background(bgColor).Foreground(textMutedColor)
|
||||||
ta.FocusedStyle.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
|
ta.Styles.Focused.Text = styles.BaseStyle().Background(bgColor).Foreground(textColor)
|
||||||
|
|
||||||
ta.Prompt = " "
|
ta.Prompt = " "
|
||||||
ta.ShowLineNumbers = false
|
ta.ShowLineNumbers = false
|
||||||
@@ -437,7 +432,7 @@ func createTextArea(existing *textarea.Model) textarea.Model {
|
|||||||
return ta
|
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)))
|
s := spinner.New(spinner.WithSpinner(spinner.Ellipsis), spinner.WithStyle(styles.Muted().Width(3)))
|
||||||
ta := createTextArea(nil)
|
ta := createTextArea(nil)
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
|
"github.com/charmbracelet/lipgloss/v2/compat"
|
||||||
"github.com/charmbracelet/x/ansi"
|
"github.com/charmbracelet/x/ansi"
|
||||||
"github.com/sst/opencode/internal/app"
|
"github.com/sst/opencode/internal/app"
|
||||||
"github.com/sst/opencode/internal/components/diff"
|
"github.com/sst/opencode/internal/components/diff"
|
||||||
@@ -21,8 +22,8 @@ import (
|
|||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
)
|
)
|
||||||
|
|
||||||
func toMarkdown(content string, width int) string {
|
func toMarkdown(content string, width int, backgroundColor compat.AdaptiveColor) string {
|
||||||
r := styles.GetMarkdownRenderer(width)
|
r := styles.GetMarkdownRenderer(width, backgroundColor)
|
||||||
content = strings.ReplaceAll(content, app.Info.Path.Root+"/", "")
|
content = strings.ReplaceAll(content, app.Info.Path.Root+"/", "")
|
||||||
rendered, _ := r.Render(content)
|
rendered, _ := r.Render(content)
|
||||||
lines := strings.Split(rendered, "\n")
|
lines := strings.Split(rendered, "\n")
|
||||||
@@ -50,7 +51,7 @@ func toMarkdown(content string, width int) string {
|
|||||||
|
|
||||||
type blockRenderer struct {
|
type blockRenderer struct {
|
||||||
align *lipgloss.Position
|
align *lipgloss.Position
|
||||||
borderColor *lipgloss.AdaptiveColor
|
borderColor *compat.AdaptiveColor
|
||||||
fullWidth bool
|
fullWidth bool
|
||||||
paddingTop int
|
paddingTop int
|
||||||
paddingBottom 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) {
|
return func(c *blockRenderer) {
|
||||||
c.borderColor = &color
|
c.borderColor = &color
|
||||||
}
|
}
|
||||||
@@ -137,9 +138,8 @@ func renderContentBlock(content string, options ...renderingOption) string {
|
|||||||
BorderLeftBackground(t.Background())
|
BorderLeftBackground(t.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
content = styles.ForceReplaceBackgroundWithLipgloss(content, t.BackgroundSubtle())
|
|
||||||
if renderer.fullWidth {
|
if renderer.fullWidth {
|
||||||
style = style.Width(layout.Current.Container.Width - 2)
|
style = style.Width(layout.Current.Container.Width)
|
||||||
}
|
}
|
||||||
content = style.Render(content)
|
content = style.Render(content)
|
||||||
if renderer.paddingTop > 0 {
|
if renderer.paddingTop > 0 {
|
||||||
@@ -152,13 +152,11 @@ func renderContentBlock(content string, options ...renderingOption) string {
|
|||||||
layout.Current.Container.Width,
|
layout.Current.Container.Width,
|
||||||
align,
|
align,
|
||||||
content,
|
content,
|
||||||
lipgloss.WithWhitespaceBackground(t.Background()),
|
|
||||||
)
|
)
|
||||||
content = lipgloss.PlaceHorizontal(
|
content = lipgloss.PlaceHorizontal(
|
||||||
layout.Current.Viewport.Width,
|
layout.Current.Viewport.Width,
|
||||||
lipgloss.Center,
|
lipgloss.Center,
|
||||||
content,
|
content,
|
||||||
lipgloss.WithWhitespaceBackground(t.Background()),
|
|
||||||
)
|
)
|
||||||
return content
|
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
|
// don't show the date if it's today
|
||||||
timestamp = timestamp[12:]
|
timestamp = timestamp[12:]
|
||||||
}
|
}
|
||||||
info := styles.BaseStyle().
|
info := fmt.Sprintf("%s (%s)", author, timestamp)
|
||||||
Foreground(t.TextMuted()).
|
|
||||||
Render(fmt.Sprintf("%s (%s)", author, timestamp))
|
|
||||||
|
|
||||||
align := lipgloss.Left
|
align := lipgloss.Left
|
||||||
switch message.Role {
|
switch message.Role {
|
||||||
@@ -195,7 +191,7 @@ func renderText(message client.MessageInfo, text string, author string) string {
|
|||||||
|
|
||||||
textWidth := lipgloss.Width(text)
|
textWidth := lipgloss.Width(text)
|
||||||
markdownWidth := min(textWidth, width-padding-4) // -4 for the border and padding
|
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)
|
content = lipgloss.JoinVertical(align, content, info)
|
||||||
|
|
||||||
switch message.Role {
|
switch message.Role {
|
||||||
@@ -313,7 +309,7 @@ func renderToolInvocation(
|
|||||||
lipgloss.Center,
|
lipgloss.Center,
|
||||||
lipgloss.Center,
|
lipgloss.Center,
|
||||||
body,
|
body,
|
||||||
lipgloss.WithWhitespaceBackground(t.Background()),
|
lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().Background(t.Background())),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case "opencode_write":
|
case "opencode_write":
|
||||||
@@ -328,7 +324,7 @@ func renderToolInvocation(
|
|||||||
command := toolArgsMap["command"].(string)
|
command := toolArgsMap["command"].(string)
|
||||||
stdout := metadata["stdout"].(string)
|
stdout := metadata["stdout"].(string)
|
||||||
body = fmt.Sprintf("```console\n> %s\n%s```", command, stdout)
|
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))
|
body = renderContentBlock(body, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
|
||||||
}
|
}
|
||||||
case "opencode_webfetch":
|
case "opencode_webfetch":
|
||||||
@@ -336,7 +332,7 @@ func renderToolInvocation(
|
|||||||
format := toolArgsMap["format"].(string)
|
format := toolArgsMap["format"].(string)
|
||||||
body = truncateHeight(body, 10)
|
body = truncateHeight(body, 10)
|
||||||
if format == "html" || format == "markdown" {
|
if format == "html" || format == "markdown" {
|
||||||
body = toMarkdown(body, innerWidth)
|
body = toMarkdown(body, innerWidth, t.BackgroundSubtle())
|
||||||
}
|
}
|
||||||
body = renderContentBlock(body, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
|
body = renderContentBlock(body, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
|
||||||
case "opencode_todowrite":
|
case "opencode_todowrite":
|
||||||
@@ -356,7 +352,7 @@ func renderToolInvocation(
|
|||||||
body += fmt.Sprintf("- [ ] %s\n", content)
|
body += fmt.Sprintf("- [ ] %s\n", content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
body = toMarkdown(body, innerWidth)
|
body = toMarkdown(body, innerWidth, t.BackgroundSubtle())
|
||||||
body = renderContentBlock(body, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
|
body = renderContentBlock(body, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -368,7 +364,7 @@ func renderToolInvocation(
|
|||||||
|
|
||||||
content := style.Render(title)
|
content := style.Render(title)
|
||||||
content = lipgloss.PlaceHorizontal(layout.Current.Viewport.Width, lipgloss.Center, content)
|
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 != "" {
|
if showResult && body != "" {
|
||||||
content += "\n" + body
|
content += "\n" + body
|
||||||
}
|
}
|
||||||
@@ -411,6 +407,7 @@ func WithTruncate(height int) fileRenderingOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func renderFile(filename string, content string, options ...fileRenderingOption) string {
|
func renderFile(filename string, content string, options ...fileRenderingOption) string {
|
||||||
|
t := theme.CurrentTheme()
|
||||||
renderer := &fileRenderer{
|
renderer := &fileRenderer{
|
||||||
filename: filename,
|
filename: filename,
|
||||||
content: content,
|
content: content,
|
||||||
@@ -419,7 +416,6 @@ func renderFile(filename string, content string, options ...fileRenderingOption)
|
|||||||
option(renderer)
|
option(renderer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: is this even needed?
|
|
||||||
lines := []string{}
|
lines := []string{}
|
||||||
for line := range strings.SplitSeq(content, "\n") {
|
for line := range strings.SplitSeq(content, "\n") {
|
||||||
line = strings.TrimRightFunc(line, unicode.IsSpace)
|
line = strings.TrimRightFunc(line, unicode.IsSpace)
|
||||||
@@ -428,23 +424,12 @@ func renderFile(filename string, content string, options ...fileRenderingOption)
|
|||||||
}
|
}
|
||||||
content = strings.Join(lines, "\n")
|
content = strings.Join(lines, "\n")
|
||||||
|
|
||||||
width := layout.Current.Container.Width - 6
|
width := layout.Current.Container.Width - 8
|
||||||
if renderer.height > 0 {
|
if renderer.height > 0 {
|
||||||
content = truncateHeight(content, renderer.height)
|
content = truncateHeight(content, renderer.height)
|
||||||
}
|
}
|
||||||
content = fmt.Sprintf("```%s\n%s\n```", extension(renderer.filename), content)
|
content = fmt.Sprintf("```%s\n%s\n```", extension(renderer.filename), content)
|
||||||
content = toMarkdown(content, width)
|
content = toMarkdown(content, width, t.BackgroundSubtle())
|
||||||
|
|
||||||
// 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")
|
|
||||||
|
|
||||||
return renderContentBlock(content, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
|
return renderContentBlock(content, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
"github.com/charmbracelet/bubbles/spinner"
|
"github.com/charmbracelet/bubbles/v2/spinner"
|
||||||
"github.com/charmbracelet/bubbles/viewport"
|
"github.com/charmbracelet/bubbles/v2/viewport"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/app"
|
"github.com/sst/opencode/internal/app"
|
||||||
"github.com/sst/opencode/internal/components/dialog"
|
"github.com/sst/opencode/internal/components/dialog"
|
||||||
"github.com/sst/opencode/internal/layout"
|
"github.com/sst/opencode/internal/layout"
|
||||||
@@ -220,11 +220,11 @@ func (m *messagesComponent) renderView() {
|
|||||||
m.width,
|
m.width,
|
||||||
lipgloss.Center,
|
lipgloss.Center,
|
||||||
block,
|
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"))
|
m.viewport.SetContent(strings.Join(centered, "\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ func (m *messagesComponent) header() string {
|
|||||||
base := styles.BaseStyle().Render
|
base := styles.BaseStyle().Render
|
||||||
muted := styles.Muted().Render
|
muted := styles.Muted().Render
|
||||||
headerLines := []string{}
|
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 != "" {
|
if m.app.Session.Share != nil && m.app.Session.Share.Url != "" {
|
||||||
headerLines = append(headerLines, muted(m.app.Session.Share.Url))
|
headerLines = append(headerLines, muted(m.app.Session.Share.Url))
|
||||||
} else {
|
} else {
|
||||||
@@ -255,7 +255,7 @@ func (m *messagesComponent) header() string {
|
|||||||
Background(t.Background()).
|
Background(t.Background()).
|
||||||
Render(header)
|
Render(header)
|
||||||
|
|
||||||
return styles.ForceReplaceBackgroundWithLipgloss(header, t.Background())
|
return header
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *messagesComponent) View() string {
|
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 {
|
func (m *messagesComponent) home() string {
|
||||||
t := theme.CurrentTheme()
|
// t := theme.CurrentTheme()
|
||||||
baseStyle := styles.BaseStyle()
|
baseStyle := styles.BaseStyle()
|
||||||
base := baseStyle.Render
|
base := baseStyle.Render
|
||||||
muted := styles.Muted().Render
|
muted := styles.Muted().Render
|
||||||
@@ -398,16 +333,13 @@ func (m *messagesComponent) home() string {
|
|||||||
lines = append(lines, "")
|
lines = append(lines, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
return styles.ForceReplaceBackgroundWithLipgloss(
|
return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center,
|
||||||
lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center,
|
baseStyle.Width(lipgloss.Width(logoAndVersion)).Render(
|
||||||
baseStyle.Width(lipgloss.Width(logoAndVersion)).Render(
|
lipgloss.JoinVertical(
|
||||||
lipgloss.JoinVertical(
|
lipgloss.Top,
|
||||||
lipgloss.Top,
|
lines...,
|
||||||
lines...,
|
),
|
||||||
),
|
))
|
||||||
)),
|
|
||||||
t.Background(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *messagesComponent) SetSize(width, height int) tea.Cmd {
|
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.width = width
|
||||||
m.height = height
|
m.height = height
|
||||||
m.viewport.Width = width
|
m.viewport.SetWidth(width)
|
||||||
m.viewport.Height = height - lipgloss.Height(m.header())
|
m.viewport.SetHeight(height - lipgloss.Height(m.header()))
|
||||||
m.attachments.Width = width + 40
|
m.attachments.SetWidth(width + 40)
|
||||||
m.attachments.Height = 3
|
m.attachments.SetHeight(3)
|
||||||
m.renderView()
|
m.renderView()
|
||||||
return nil
|
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{
|
customSpinner := spinner.Spinner{
|
||||||
Frames: []string{" ", "┃", "┃"},
|
Frames: []string{" ", "┃", "┃"},
|
||||||
FPS: time.Second / 3,
|
FPS: time.Second / 3,
|
||||||
}
|
}
|
||||||
s := spinner.New(spinner.WithSpinner(customSpinner))
|
s := spinner.New(spinner.WithSpinner(customSpinner))
|
||||||
|
|
||||||
vp := viewport.New(0, 0)
|
vp := viewport.New() //(0, 0)
|
||||||
attachments := viewport.New(0, 0)
|
attachments := viewport.New() //(0, 0)
|
||||||
vp.KeyMap.PageUp = messageKeys.PageUp
|
vp.KeyMap.PageUp = messageKeys.PageUp
|
||||||
vp.KeyMap.PageDown = messageKeys.PageDown
|
vp.KeyMap.PageDown = messageKeys.PageDown
|
||||||
vp.KeyMap.HalfPageUp = messageKeys.HalfPageUp
|
vp.KeyMap.HalfPageUp = messageKeys.HalfPageUp
|
||||||
|
|||||||
@@ -5,20 +5,21 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/app"
|
"github.com/sst/opencode/internal/app"
|
||||||
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/pubsub"
|
"github.com/sst/opencode/internal/pubsub"
|
||||||
"github.com/sst/opencode/internal/status"
|
"github.com/sst/opencode/internal/status"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StatusCmp interface {
|
type StatusComponent interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
}
|
}
|
||||||
|
|
||||||
type statusCmp struct {
|
type statusComponent struct {
|
||||||
app *app.App
|
app *app.App
|
||||||
queue []status.StatusMessage
|
queue []status.StatusMessage
|
||||||
width int
|
width int
|
||||||
@@ -27,7 +28,7 @@ type statusCmp struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clearMessageCmd is a command that clears status messages after a timeout
|
// 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 tea.Tick(time.Second, func(t time.Time) tea.Msg {
|
||||||
return statusCleanupMsg{time: t}
|
return statusCleanupMsg{time: t}
|
||||||
})
|
})
|
||||||
@@ -38,11 +39,11 @@ type statusCleanupMsg struct {
|
|||||||
time time.Time
|
time time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m statusCmp) Init() tea.Cmd {
|
func (m statusComponent) Init() tea.Cmd {
|
||||||
return m.clearMessageCmd()
|
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) {
|
switch msg := msg.(type) {
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
m.width = msg.Width
|
m.width = msg.Width
|
||||||
@@ -104,10 +105,9 @@ func logo() string {
|
|||||||
open := styles.Muted().Render("open")
|
open := styles.Muted().Render("open")
|
||||||
code := styles.BaseStyle().Bold(true).Render("code")
|
code := styles.BaseStyle().Bold(true).Render("code")
|
||||||
version := styles.Muted().Render(app.Info.Version)
|
version := styles.Muted().Render(app.Info.Version)
|
||||||
return styles.ForceReplaceBackgroundWithLipgloss(
|
return styles.Padded().
|
||||||
styles.Padded().Render(mark+open+code+" "+version),
|
Background(t.BackgroundElement()).
|
||||||
t.BackgroundElement(),
|
Render(mark + open + code + " " + version)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatTokensAndCost(tokens float32, contextWindow float32, cost float32) string {
|
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)
|
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 == "" {
|
if m.app.Session.Id == "" {
|
||||||
return styles.BaseStyle().
|
return styles.BaseStyle().
|
||||||
Width(m.width).
|
Width(m.width).
|
||||||
@@ -250,107 +250,8 @@ func (m statusCmp) View() string {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *statusCmp) projectDiagnostics() string {
|
func NewStatusCmp(app *app.App) StatusComponent {
|
||||||
t := theme.CurrentTheme()
|
statusComponent := &statusComponent{
|
||||||
|
|
||||||
// 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{
|
|
||||||
app: app,
|
app: app,
|
||||||
queue: []status.StatusMessage{},
|
queue: []status.StatusMessage{},
|
||||||
messageTTL: 4 * time.Second,
|
messageTTL: 4 * time.Second,
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package dialog
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
"github.com/charmbracelet/bubbles/textinput"
|
"github.com/charmbracelet/bubbles/v2/textinput"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
|
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
@@ -70,17 +70,24 @@ func NewMultiArgumentsDialogCmp(commandID, content string, argNames []string) Mu
|
|||||||
for i, name := range argNames {
|
for i, name := range argNames {
|
||||||
ti := textinput.New()
|
ti := textinput.New()
|
||||||
ti.Placeholder = fmt.Sprintf("Enter value for %s...", name)
|
ti.Placeholder = fmt.Sprintf("Enter value for %s...", name)
|
||||||
ti.Width = 40
|
ti.SetWidth(40)
|
||||||
ti.Prompt = ""
|
ti.Prompt = ""
|
||||||
ti.PlaceholderStyle = ti.PlaceholderStyle.Background(t.Background())
|
ti.Styles.Blurred.Placeholder = ti.Styles.Blurred.Placeholder.Background(t.Background())
|
||||||
ti.PromptStyle = ti.PromptStyle.Background(t.Background())
|
ti.Styles.Blurred.Text = ti.Styles.Blurred.Text.Background(t.Background())
|
||||||
ti.TextStyle = ti.TextStyle.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
|
// Only focus the first input initially
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
ti.Focus()
|
ti.Focus()
|
||||||
ti.PromptStyle = ti.PromptStyle.Foreground(t.Primary())
|
// ti.PromptStyle = ti.PromptStyle.Foreground(t.Primary())
|
||||||
ti.TextStyle = ti.TextStyle.Foreground(t.Primary())
|
// ti.TextStyle = ti.TextStyle.Foreground(t.Primary())
|
||||||
} else {
|
} else {
|
||||||
ti.Blur()
|
ti.Blur()
|
||||||
}
|
}
|
||||||
@@ -115,7 +122,7 @@ func (m MultiArgumentsDialogCmp) Init() tea.Cmd {
|
|||||||
// Update implements tea.Model.
|
// Update implements tea.Model.
|
||||||
func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
var cmds []tea.Cmd
|
var cmds []tea.Cmd
|
||||||
t := theme.CurrentTheme()
|
// t := theme.CurrentTheme()
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
@@ -145,22 +152,22 @@ func (m MultiArgumentsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
m.inputs[m.focusIndex].Blur()
|
m.inputs[m.focusIndex].Blur()
|
||||||
m.focusIndex++
|
m.focusIndex++
|
||||||
m.inputs[m.focusIndex].Focus()
|
m.inputs[m.focusIndex].Focus()
|
||||||
m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.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())
|
// m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
|
||||||
case key.Matches(msg, key.NewBinding(key.WithKeys("tab"))):
|
case key.Matches(msg, key.NewBinding(key.WithKeys("tab"))):
|
||||||
// Move to the next input
|
// Move to the next input
|
||||||
m.inputs[m.focusIndex].Blur()
|
m.inputs[m.focusIndex].Blur()
|
||||||
m.focusIndex = (m.focusIndex + 1) % len(m.inputs)
|
m.focusIndex = (m.focusIndex + 1) % len(m.inputs)
|
||||||
m.inputs[m.focusIndex].Focus()
|
m.inputs[m.focusIndex].Focus()
|
||||||
m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.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())
|
// m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
|
||||||
case key.Matches(msg, key.NewBinding(key.WithKeys("shift+tab"))):
|
case key.Matches(msg, key.NewBinding(key.WithKeys("shift+tab"))):
|
||||||
// Move to the previous input
|
// Move to the previous input
|
||||||
m.inputs[m.focusIndex].Blur()
|
m.inputs[m.focusIndex].Blur()
|
||||||
m.focusIndex = (m.focusIndex - 1 + len(m.inputs)) % len(m.inputs)
|
m.focusIndex = (m.focusIndex - 1 + len(m.inputs)) % len(m.inputs)
|
||||||
m.inputs[m.focusIndex].Focus()
|
m.inputs[m.focusIndex].Focus()
|
||||||
m.inputs[m.focusIndex].PromptStyle = m.inputs[m.focusIndex].PromptStyle.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())
|
// m.inputs[m.focusIndex].TextStyle = m.inputs[m.focusIndex].TextStyle.Foreground(t.Primary())
|
||||||
}
|
}
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
m.width = msg.Width
|
m.width = msg.Width
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package dialog
|
package dialog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
utilComponents "github.com/sst/opencode/internal/components/util"
|
utilComponents "github.com/sst/opencode/internal/components/util"
|
||||||
"github.com/sst/opencode/internal/layout"
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
@@ -56,12 +56,12 @@ type CloseCommandDialogMsg struct{}
|
|||||||
|
|
||||||
// CommandDialog interface for the command selection dialog
|
// CommandDialog interface for the command selection dialog
|
||||||
type CommandDialog interface {
|
type CommandDialog interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
layout.Bindings
|
layout.Bindings
|
||||||
SetCommands(commands []Command)
|
SetCommands(commands []Command)
|
||||||
}
|
}
|
||||||
|
|
||||||
type commandDialogCmp struct {
|
type commandDialogComponent struct {
|
||||||
listView utilComponents.SimpleList[Command]
|
listView utilComponents.SimpleList[Command]
|
||||||
width int
|
width int
|
||||||
height 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()
|
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
|
var cmds []tea.Cmd
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
@@ -114,7 +114,7 @@ func (c *commandDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return c, tea.Batch(cmds...)
|
return c, tea.Batch(cmds...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *commandDialogCmp) View() string {
|
func (c *commandDialogComponent) View() string {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
baseStyle := styles.BaseStyle()
|
baseStyle := styles.BaseStyle()
|
||||||
|
|
||||||
@@ -158,11 +158,11 @@ func (c *commandDialogCmp) View() string {
|
|||||||
Render(content)
|
Render(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *commandDialogCmp) BindingKeys() []key.Binding {
|
func (c *commandDialogComponent) BindingKeys() []key.Binding {
|
||||||
return layout.KeyMapToSlice(commandKeys)
|
return layout.KeyMapToSlice(commandKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *commandDialogCmp) SetCommands(commands []Command) {
|
func (c *commandDialogComponent) SetCommands(commands []Command) {
|
||||||
c.listView.SetItems(commands)
|
c.listView.SetItems(commands)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ func NewCommandDialogCmp() CommandDialog {
|
|||||||
"No commands available",
|
"No commands available",
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
return &commandDialogCmp{
|
return &commandDialogComponent{
|
||||||
listView: listView,
|
listView: listView,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package dialog
|
package dialog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
"github.com/charmbracelet/bubbles/textarea"
|
"github.com/charmbracelet/bubbles/v2/textarea"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/status"
|
|
||||||
utilComponents "github.com/sst/opencode/internal/components/util"
|
utilComponents "github.com/sst/opencode/internal/components/util"
|
||||||
"github.com/sst/opencode/internal/layout"
|
"github.com/sst/opencode/internal/layout"
|
||||||
|
"github.com/sst/opencode/internal/status"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
"github.com/sst/opencode/internal/util"
|
"github.com/sst/opencode/internal/util"
|
||||||
@@ -77,7 +77,7 @@ type CompletionDialogCompleteItemMsg struct {
|
|||||||
type CompletionDialogCloseMsg struct{}
|
type CompletionDialogCloseMsg struct{}
|
||||||
|
|
||||||
type CompletionDialog interface {
|
type CompletionDialog interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
layout.Bindings
|
layout.Bindings
|
||||||
SetWidth(width int)
|
SetWidth(width int)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/sst/opencode/internal/app"
|
"github.com/sst/opencode/internal/app"
|
||||||
"github.com/sst/opencode/internal/util"
|
"github.com/sst/opencode/internal/util"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,13 +12,14 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"github.com/atotto/clipboard"
|
"github.com/atotto/clipboard"
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
"github.com/charmbracelet/bubbles/textinput"
|
"github.com/charmbracelet/bubbles/v2/textinput"
|
||||||
"github.com/charmbracelet/bubbles/viewport"
|
"github.com/charmbracelet/bubbles/v2/viewport"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/app"
|
"github.com/sst/opencode/internal/app"
|
||||||
"github.com/sst/opencode/internal/image"
|
"github.com/sst/opencode/internal/image"
|
||||||
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/status"
|
"github.com/sst/opencode/internal/status"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
@@ -82,7 +83,7 @@ var filePickerKeyMap = FilePrickerKeyMap{
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
type filepickerCmp struct {
|
type filepickerComponent struct {
|
||||||
basePath string
|
basePath string
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
@@ -118,18 +119,18 @@ type AttachmentAddedMsg struct {
|
|||||||
Attachment app.Attachment
|
Attachment app.Attachment
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *filepickerCmp) Init() tea.Cmd {
|
func (f *filepickerComponent) Init() tea.Cmd {
|
||||||
return nil
|
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
|
var cmd tea.Cmd
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
f.width = 60
|
f.width = 60
|
||||||
f.height = 20
|
f.height = 20
|
||||||
f.viewport.Width = 80
|
f.viewport.SetWidth(80)
|
||||||
f.viewport.Height = 22
|
f.viewport.SetHeight(22)
|
||||||
f.cursor = 0
|
f.cursor = 0
|
||||||
f.getCurrentFileBelowCursor()
|
f.getCurrentFileBelowCursor()
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
@@ -236,7 +237,7 @@ func (f *filepickerCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return f, cmd
|
return f, cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *filepickerCmp) addAttachmentToMessage() (tea.Model, tea.Cmd) {
|
func (f *filepickerComponent) addAttachmentToMessage() (tea.Model, tea.Cmd) {
|
||||||
// modeInfo := GetSelectedModel(config.Get())
|
// modeInfo := GetSelectedModel(config.Get())
|
||||||
// if !modeInfo.SupportsAttachments {
|
// if !modeInfo.SupportsAttachments {
|
||||||
// status.Error(fmt.Sprintf("Model %s doesn't support attachments", modeInfo.Name))
|
// 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})
|
return f, util.CmdHandler(AttachmentAddedMsg{attachment})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *filepickerCmp) View() string {
|
func (f *filepickerComponent) View() string {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
const maxVisibleDirs = 20
|
const maxVisibleDirs = 20
|
||||||
const maxWidth = 80
|
const maxWidth = 80
|
||||||
@@ -333,7 +334,7 @@ func (f *filepickerCmp) View() string {
|
|||||||
Render(f.cwd.View())
|
Render(f.cwd.View())
|
||||||
|
|
||||||
viewportstyle := lipgloss.NewStyle().
|
viewportstyle := lipgloss.NewStyle().
|
||||||
Width(f.viewport.Width).
|
Width(f.viewport.Width()).
|
||||||
Background(t.Background()).
|
Background(t.Background()).
|
||||||
Border(lipgloss.RoundedBorder()).
|
Border(lipgloss.RoundedBorder()).
|
||||||
BorderForeground(t.TextMuted()).
|
BorderForeground(t.TextMuted()).
|
||||||
@@ -366,21 +367,21 @@ func (f *filepickerCmp) View() string {
|
|||||||
return lipgloss.JoinHorizontal(lipgloss.Center, contentStyle.Render(content), viewportstyle)
|
return lipgloss.JoinHorizontal(lipgloss.Center, contentStyle.Render(content), viewportstyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
type FilepickerCmp interface {
|
type FilepickerComponent interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
ToggleFilepicker(showFilepicker bool)
|
ToggleFilepicker(showFilepicker bool)
|
||||||
IsCWDFocused() bool
|
IsCWDFocused() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *filepickerCmp) ToggleFilepicker(showFilepicker bool) {
|
func (f *filepickerComponent) ToggleFilepicker(showFilepicker bool) {
|
||||||
f.ShowFilePicker = showFilepicker
|
f.ShowFilePicker = showFilepicker
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *filepickerCmp) IsCWDFocused() bool {
|
func (f *filepickerComponent) IsCWDFocused() bool {
|
||||||
return f.cwd.Focused()
|
return f.cwd.Focused()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFilepickerCmp(app *app.App) FilepickerCmp {
|
func NewFilepickerCmp(app *app.App) FilepickerComponent {
|
||||||
homepath, err := os.UserHomeDir()
|
homepath, err := os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error("error loading user files")
|
slog.Error("error loading user files")
|
||||||
@@ -388,16 +389,16 @@ func NewFilepickerCmp(app *app.App) FilepickerCmp {
|
|||||||
}
|
}
|
||||||
baseDir := DirNode{parent: nil, directory: homepath}
|
baseDir := DirNode{parent: nil, directory: homepath}
|
||||||
dirs := readDir(homepath, false)
|
dirs := readDir(homepath, false)
|
||||||
viewport := viewport.New(0, 0)
|
viewport := viewport.New() // viewport.New(0, 0)
|
||||||
currentDirectory := textinput.New()
|
currentDirectory := textinput.New()
|
||||||
currentDirectory.CharLimit = 200
|
currentDirectory.CharLimit = 200
|
||||||
currentDirectory.Width = 44
|
currentDirectory.SetWidth(44)
|
||||||
currentDirectory.Cursor.Blink = true
|
// currentDirectory.Cursor.Blink = true
|
||||||
currentDirectory.SetValue(baseDir.directory)
|
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) {
|
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))
|
slog.Error(fmt.Sprintf("Invalid cursor position. Dirs length: %d, Cursor: %d", len(f.dirs), f.cursor))
|
||||||
f.viewport.SetContent("Preview unavailable")
|
f.viewport.SetContent("Preview unavailable")
|
||||||
@@ -410,7 +411,7 @@ func (f *filepickerCmp) getCurrentFileBelowCursor() {
|
|||||||
fullPath := f.cwdDetails.directory + "/" + dir.Name()
|
fullPath := f.cwdDetails.directory + "/" + dir.Name()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
imageString, err := image.ImagePreview(f.viewport.Width-4, fullPath)
|
imageString, err := image.ImagePreview(f.viewport.Width()-4, fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error(err.Error())
|
slog.Error(err.Error())
|
||||||
f.viewport.SetContent("Preview unavailable")
|
f.viewport.SetContent("Preview unavailable")
|
||||||
|
|||||||
@@ -3,28 +3,29 @@ package dialog
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
)
|
)
|
||||||
|
|
||||||
type helpCmp struct {
|
type helpComponent struct {
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
keys []key.Binding
|
keys []key.Binding
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *helpCmp) Init() tea.Cmd {
|
func (h *helpComponent) Init() tea.Cmd {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *helpCmp) SetBindings(k []key.Binding) {
|
func (h *helpComponent) SetBindings(k []key.Binding) {
|
||||||
h.keys = k
|
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) {
|
switch msg := msg.(type) {
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
h.width = 90
|
h.width = 90
|
||||||
@@ -53,7 +54,7 @@ func removeDuplicateBindings(bindings []key.Binding) []key.Binding {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *helpCmp) render() string {
|
func (h *helpComponent) render() string {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
baseStyle := styles.BaseStyle()
|
baseStyle := styles.BaseStyle()
|
||||||
|
|
||||||
@@ -134,7 +135,7 @@ func (h *helpCmp) render() string {
|
|||||||
pairs = append(pairs, pair)
|
pairs = append(pairs, pair)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/charmbracelet/lipgloss/issues/209
|
// https://github.com/charmbracelet/lipgloss/v2/issues/209
|
||||||
if len(pairs) > 1 {
|
if len(pairs) > 1 {
|
||||||
prefix := pairs[:len(pairs)-1]
|
prefix := pairs[:len(pairs)-1]
|
||||||
lastPair := pairs[len(pairs)-1]
|
lastPair := pairs[len(pairs)-1]
|
||||||
@@ -144,7 +145,7 @@ func (h *helpCmp) render() string {
|
|||||||
lipgloss.Left, // x
|
lipgloss.Left, // x
|
||||||
lipgloss.Top, // y
|
lipgloss.Top, // y
|
||||||
lastPair, // content
|
lastPair, // content
|
||||||
lipgloss.WithWhitespaceBackground(t.Background()),
|
// lipgloss.WithWhitespaceBackground(t.Background()),
|
||||||
))
|
))
|
||||||
content := baseStyle.Width(h.width).Render(
|
content := baseStyle.Width(h.width).Render(
|
||||||
lipgloss.JoinHorizontal(
|
lipgloss.JoinHorizontal(
|
||||||
@@ -165,7 +166,7 @@ func (h *helpCmp) render() string {
|
|||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *helpCmp) View() string {
|
func (h *helpComponent) View() string {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
baseStyle := styles.BaseStyle()
|
baseStyle := styles.BaseStyle()
|
||||||
|
|
||||||
@@ -190,11 +191,11 @@ func (h *helpCmp) View() string {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
type HelpCmp interface {
|
type HelpComponent interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
SetBindings([]key.Binding)
|
SetBindings([]key.Binding)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHelpCmp() HelpCmp {
|
func NewHelpCmp() HelpComponent {
|
||||||
return &helpCmp{}
|
return &helpComponent{}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package dialog
|
package dialog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
|
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/app"
|
"github.com/sst/opencode/internal/app"
|
||||||
"github.com/sst/opencode/internal/layout"
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
@@ -31,13 +31,13 @@ type CloseModelDialogMsg struct {
|
|||||||
|
|
||||||
// ModelDialog interface for the model selection dialog
|
// ModelDialog interface for the model selection dialog
|
||||||
type ModelDialog interface {
|
type ModelDialog interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
layout.Bindings
|
layout.Bindings
|
||||||
|
|
||||||
SetProviders(providers []client.ProviderInfo)
|
SetProviders(providers []client.ProviderInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
type modelDialogCmp struct {
|
type modelDialogComponent struct {
|
||||||
app *app.App
|
app *app.App
|
||||||
availableProviders []client.ProviderInfo
|
availableProviders []client.ProviderInfo
|
||||||
provider 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()
|
// cfg := config.Get()
|
||||||
// modelInfo := GetSelectedModel(cfg)
|
// modelInfo := GetSelectedModel(cfg)
|
||||||
// m.availableProviders = getEnabledProviders(cfg)
|
// m.availableProviders = getEnabledProviders(cfg)
|
||||||
@@ -125,11 +125,11 @@ func (m *modelDialogCmp) Init() tea.Cmd {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *modelDialogCmp) SetProviders(providers []client.ProviderInfo) {
|
func (m *modelDialogComponent) SetProviders(providers []client.ProviderInfo) {
|
||||||
m.availableProviders = providers
|
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) {
|
switch msg := msg.(type) {
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
switch {
|
switch {
|
||||||
@@ -159,7 +159,7 @@ func (m *modelDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return m, nil
|
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 {
|
models := slices.SortedFunc(maps.Values(m.provider.Models), func(a, b client.ProviderModel) int {
|
||||||
return strings.Compare(*a.Name, *b.Name)
|
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
|
// moveSelectionUp moves the selection up or wraps to bottom
|
||||||
func (m *modelDialogCmp) moveSelectionUp() {
|
func (m *modelDialogComponent) moveSelectionUp() {
|
||||||
if m.selectedIdx > 0 {
|
if m.selectedIdx > 0 {
|
||||||
m.selectedIdx--
|
m.selectedIdx--
|
||||||
} else {
|
} else {
|
||||||
@@ -182,7 +182,7 @@ func (m *modelDialogCmp) moveSelectionUp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// moveSelectionDown moves the selection down or wraps to top
|
// 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 {
|
if m.selectedIdx < len(m.provider.Models)-1 {
|
||||||
m.selectedIdx++
|
m.selectedIdx++
|
||||||
} else {
|
} 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
|
newOffset := m.hScrollOffset + offset
|
||||||
|
|
||||||
// Ensure we stay within bounds
|
// Ensure we stay within bounds
|
||||||
@@ -212,7 +212,7 @@ func (m *modelDialogCmp) switchProvider(offset int) {
|
|||||||
m.setupModelsForProvider(m.provider.Id)
|
m.setupModelsForProvider(m.provider.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *modelDialogCmp) View() string {
|
func (m *modelDialogComponent) View() string {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
baseStyle := styles.BaseStyle()
|
baseStyle := styles.BaseStyle()
|
||||||
|
|
||||||
@@ -255,7 +255,7 @@ func (m *modelDialogCmp) View() string {
|
|||||||
Render(content)
|
Render(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *modelDialogCmp) getScrollIndicators(maxWidth int) string {
|
func (m *modelDialogComponent) getScrollIndicators(maxWidth int) string {
|
||||||
var indicator string
|
var indicator string
|
||||||
|
|
||||||
if len(m.provider.Models) > numVisibleModels {
|
if len(m.provider.Models) > numVisibleModels {
|
||||||
@@ -291,7 +291,7 @@ func (m *modelDialogCmp) getScrollIndicators(maxWidth int) string {
|
|||||||
Render(indicator)
|
Render(indicator)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *modelDialogCmp) BindingKeys() []key.Binding {
|
func (m *modelDialogComponent) BindingKeys() []key.Binding {
|
||||||
return layout.KeyMapToSlice(modelKeys)
|
return layout.KeyMapToSlice(modelKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +305,7 @@ func (m *modelDialogCmp) BindingKeys() []key.Binding {
|
|||||||
// return -1
|
// return -1
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func (m *modelDialogCmp) setupModelsForProvider(_ string) {
|
func (m *modelDialogComponent) setupModelsForProvider(_ string) {
|
||||||
m.selectedIdx = 0
|
m.selectedIdx = 0
|
||||||
m.scrollOffset = 0
|
m.scrollOffset = 0
|
||||||
|
|
||||||
@@ -332,7 +332,7 @@ func (m *modelDialogCmp) setupModelsForProvider(_ string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewModelDialogCmp(app *app.App) ModelDialog {
|
func NewModelDialogCmp(app *app.App) ModelDialog {
|
||||||
return &modelDialogCmp{
|
return &modelDialogComponent{
|
||||||
app: app,
|
app: app,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ package dialog
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
"github.com/charmbracelet/bubbles/viewport"
|
"github.com/charmbracelet/bubbles/v2/viewport"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/layout"
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
@@ -28,9 +28,9 @@ type PermissionResponseMsg struct {
|
|||||||
Action PermissionAction
|
Action PermissionAction
|
||||||
}
|
}
|
||||||
|
|
||||||
// PermissionDialogCmp interface for permission dialog component
|
// PermissionDialogComponent interface for permission dialog component
|
||||||
type PermissionDialogCmp interface {
|
type PermissionDialogComponent interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
layout.Bindings
|
layout.Bindings
|
||||||
// SetPermissions(permission permission.PermissionRequest) tea.Cmd
|
// SetPermissions(permission permission.PermissionRequest) tea.Cmd
|
||||||
}
|
}
|
||||||
@@ -76,8 +76,8 @@ var permissionsKeys = permissionsMapping{
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
// permissionDialogCmp is the implementation of PermissionDialog
|
// permissionDialogComponent is the implementation of PermissionDialog
|
||||||
type permissionDialogCmp struct {
|
type permissionDialogComponent struct {
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
// permission permission.PermissionRequest
|
// permission permission.PermissionRequest
|
||||||
@@ -89,11 +89,11 @@ type permissionDialogCmp struct {
|
|||||||
markdownCache map[string]string
|
markdownCache map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) Init() tea.Cmd {
|
func (p *permissionDialogComponent) Init() tea.Cmd {
|
||||||
return p.contentViewPort.Init()
|
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
|
var cmds []tea.Cmd
|
||||||
|
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
@@ -129,7 +129,7 @@ func (p *permissionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return p, tea.Batch(cmds...)
|
return p, tea.Batch(cmds...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) selectCurrentOption() tea.Cmd {
|
func (p *permissionDialogComponent) selectCurrentOption() tea.Cmd {
|
||||||
var action PermissionAction
|
var action PermissionAction
|
||||||
|
|
||||||
switch p.selectedOption {
|
switch p.selectedOption {
|
||||||
@@ -144,7 +144,7 @@ func (p *permissionDialogCmp) selectCurrentOption() tea.Cmd {
|
|||||||
return util.CmdHandler(PermissionResponseMsg{Action: action}) // , Permission: p.permission})
|
return util.CmdHandler(PermissionResponseMsg{Action: action}) // , Permission: p.permission})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) renderButtons() string {
|
func (p *permissionDialogComponent) renderButtons() string {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
baseStyle := styles.BaseStyle()
|
baseStyle := styles.BaseStyle()
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ func (p *permissionDialogCmp) renderButtons() string {
|
|||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) renderHeader() string {
|
func (p *permissionDialogComponent) renderHeader() string {
|
||||||
return "NOT IMPLEMENTED"
|
return "NOT IMPLEMENTED"
|
||||||
// t := theme.CurrentTheme()
|
// t := theme.CurrentTheme()
|
||||||
// baseStyle := styles.BaseStyle()
|
// baseStyle := styles.BaseStyle()
|
||||||
@@ -246,7 +246,7 @@ func (p *permissionDialogCmp) renderHeader() string {
|
|||||||
// return lipgloss.NewStyle().Background(t.Background()).Render(lipgloss.JoinVertical(lipgloss.Left, headerParts...))
|
// 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()
|
// t := theme.CurrentTheme()
|
||||||
// baseStyle := styles.BaseStyle()
|
// baseStyle := styles.BaseStyle()
|
||||||
//
|
//
|
||||||
@@ -269,7 +269,7 @@ func (p *permissionDialogCmp) renderBashContent() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) renderEditContent() string {
|
func (p *permissionDialogComponent) renderEditContent() string {
|
||||||
// if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
|
// if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
|
||||||
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
||||||
// return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
|
// return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
|
||||||
@@ -281,7 +281,7 @@ func (p *permissionDialogCmp) renderEditContent() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) renderPatchContent() string {
|
func (p *permissionDialogComponent) renderPatchContent() string {
|
||||||
// if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
|
// if pr, ok := p.permission.Params.(tools.EditPermissionsParams); ok {
|
||||||
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
||||||
// return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
|
// return diff.FormatDiff(pr.Diff, diff.WithTotalWidth(p.contentViewPort.Width))
|
||||||
@@ -293,7 +293,7 @@ func (p *permissionDialogCmp) renderPatchContent() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) renderWriteContent() string {
|
func (p *permissionDialogComponent) renderWriteContent() string {
|
||||||
// if pr, ok := p.permission.Params.(tools.WritePermissionsParams); ok {
|
// if pr, ok := p.permission.Params.(tools.WritePermissionsParams); ok {
|
||||||
// // Use the cache for diff rendering
|
// // Use the cache for diff rendering
|
||||||
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
// diff := p.GetOrSetDiff(p.permission.ID, func() (string, error) {
|
||||||
@@ -306,7 +306,7 @@ func (p *permissionDialogCmp) renderWriteContent() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) renderFetchContent() string {
|
func (p *permissionDialogComponent) renderFetchContent() string {
|
||||||
// t := theme.CurrentTheme()
|
// t := theme.CurrentTheme()
|
||||||
// baseStyle := styles.BaseStyle()
|
// baseStyle := styles.BaseStyle()
|
||||||
//
|
//
|
||||||
@@ -329,7 +329,7 @@ func (p *permissionDialogCmp) renderFetchContent() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) renderDefaultContent() string {
|
func (p *permissionDialogComponent) renderDefaultContent() string {
|
||||||
// t := theme.CurrentTheme()
|
// t := theme.CurrentTheme()
|
||||||
// baseStyle := styles.BaseStyle()
|
// baseStyle := styles.BaseStyle()
|
||||||
//
|
//
|
||||||
@@ -354,7 +354,7 @@ func (p *permissionDialogCmp) renderDefaultContent() string {
|
|||||||
return p.styleViewport()
|
return p.styleViewport()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) styleViewport() string {
|
func (p *permissionDialogComponent) styleViewport() string {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
contentStyle := lipgloss.NewStyle().
|
contentStyle := lipgloss.NewStyle().
|
||||||
Background(t.Background())
|
Background(t.Background())
|
||||||
@@ -362,7 +362,7 @@ func (p *permissionDialogCmp) styleViewport() string {
|
|||||||
return contentStyle.Render(p.contentViewPort.View())
|
return contentStyle.Render(p.contentViewPort.View())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) render() string {
|
func (p *permissionDialogComponent) render() string {
|
||||||
return "NOT IMPLEMENTED"
|
return "NOT IMPLEMENTED"
|
||||||
// t := theme.CurrentTheme()
|
// t := theme.CurrentTheme()
|
||||||
// baseStyle := styles.BaseStyle()
|
// 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()
|
return p.render()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) BindingKeys() []key.Binding {
|
func (p *permissionDialogComponent) BindingKeys() []key.Binding {
|
||||||
return layout.KeyMapToSlice(permissionsKeys)
|
return layout.KeyMapToSlice(permissionsKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *permissionDialogCmp) SetSize() tea.Cmd {
|
func (p *permissionDialogComponent) SetSize() tea.Cmd {
|
||||||
// if p.permission.ID == "" {
|
// if p.permission.ID == "" {
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
@@ -458,7 +458,7 @@ func (p *permissionDialogCmp) SetSize() tea.Cmd {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// Helper to get or set cached diff content
|
// 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 {
|
if cached, ok := c.diffCache[key]; ok {
|
||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
@@ -474,7 +474,7 @@ func (c *permissionDialogCmp) GetOrSetDiff(key string, generator func() (string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper to get or set cached markdown content
|
// 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 {
|
if cached, ok := c.markdownCache[key]; ok {
|
||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
@@ -489,11 +489,11 @@ func (c *permissionDialogCmp) GetOrSetMarkdown(key string, generator func() (str
|
|||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPermissionDialogCmp() PermissionDialogCmp {
|
func NewPermissionDialogCmp() PermissionDialogComponent {
|
||||||
// Create viewport for content
|
// Create viewport for content
|
||||||
contentViewport := viewport.New(0, 0)
|
contentViewport := viewport.New() // (0, 0)
|
||||||
|
|
||||||
return &permissionDialogCmp{
|
return &permissionDialogComponent{
|
||||||
contentViewPort: contentViewport,
|
contentViewPort: contentViewport,
|
||||||
selectedOption: 0, // Default to "Allow"
|
selectedOption: 0, // Default to "Allow"
|
||||||
diffCache: make(map[string]string),
|
diffCache: make(map[string]string),
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package dialog
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/layout"
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
@@ -17,11 +17,11 @@ const question = "Are you sure you want to quit?"
|
|||||||
type CloseQuitMsg struct{}
|
type CloseQuitMsg struct{}
|
||||||
|
|
||||||
type QuitDialog interface {
|
type QuitDialog interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
layout.Bindings
|
layout.Bindings
|
||||||
}
|
}
|
||||||
|
|
||||||
type quitDialogCmp struct {
|
type quitDialogComponent struct {
|
||||||
selectedNo bool
|
selectedNo bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,11 +56,11 @@ var helpKeys = helpMapping{
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *quitDialogCmp) Init() tea.Cmd {
|
func (q *quitDialogComponent) Init() tea.Cmd {
|
||||||
return nil
|
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) {
|
switch msg := msg.(type) {
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
switch {
|
switch {
|
||||||
@@ -81,7 +81,7 @@ func (q *quitDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *quitDialogCmp) View() string {
|
func (q *quitDialogComponent) View() string {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
baseStyle := styles.BaseStyle()
|
baseStyle := styles.BaseStyle()
|
||||||
|
|
||||||
@@ -125,12 +125,12 @@ func (q *quitDialogCmp) View() string {
|
|||||||
Render(content)
|
Render(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *quitDialogCmp) BindingKeys() []key.Binding {
|
func (q *quitDialogComponent) BindingKeys() []key.Binding {
|
||||||
return layout.KeyMapToSlice(helpKeys)
|
return layout.KeyMapToSlice(helpKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewQuitCmp() QuitDialog {
|
func NewQuitCmp() QuitDialog {
|
||||||
return &quitDialogCmp{
|
return &quitDialogComponent{
|
||||||
selectedNo: true,
|
selectedNo: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package dialog
|
package dialog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/layout"
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
@@ -18,13 +18,13 @@ type CloseSessionDialogMsg struct {
|
|||||||
|
|
||||||
// SessionDialog interface for the session switching dialog
|
// SessionDialog interface for the session switching dialog
|
||||||
type SessionDialog interface {
|
type SessionDialog interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
layout.Bindings
|
layout.Bindings
|
||||||
SetSessions(sessions []client.SessionInfo)
|
SetSessions(sessions []client.SessionInfo)
|
||||||
SetSelectedSession(sessionID string)
|
SetSelectedSession(sessionID string)
|
||||||
}
|
}
|
||||||
|
|
||||||
type sessionDialogCmp struct {
|
type sessionDialogComponent struct {
|
||||||
sessions []client.SessionInfo
|
sessions []client.SessionInfo
|
||||||
selectedIdx int
|
selectedIdx int
|
||||||
width int
|
width int
|
||||||
@@ -68,11 +68,11 @@ var sessionKeys = sessionKeyMap{
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sessionDialogCmp) Init() tea.Cmd {
|
func (s *sessionDialogComponent) Init() tea.Cmd {
|
||||||
return nil
|
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) {
|
switch msg := msg.(type) {
|
||||||
case tea.WindowSizeMsg:
|
case tea.WindowSizeMsg:
|
||||||
s.width = msg.Width
|
s.width = msg.Width
|
||||||
@@ -105,7 +105,7 @@ func (s *sessionDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sessionDialogCmp) View() string {
|
func (s *sessionDialogComponent) View() string {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
baseStyle := styles.BaseStyle()
|
baseStyle := styles.BaseStyle()
|
||||||
|
|
||||||
@@ -185,11 +185,11 @@ func (s *sessionDialogCmp) View() string {
|
|||||||
Render(content)
|
Render(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sessionDialogCmp) BindingKeys() []key.Binding {
|
func (s *sessionDialogComponent) BindingKeys() []key.Binding {
|
||||||
return layout.KeyMapToSlice(sessionKeys)
|
return layout.KeyMapToSlice(sessionKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sessionDialogCmp) SetSessions(sessions []client.SessionInfo) {
|
func (s *sessionDialogComponent) SetSessions(sessions []client.SessionInfo) {
|
||||||
s.sessions = sessions
|
s.sessions = sessions
|
||||||
|
|
||||||
// If we have a selected session ID, find its index
|
// If we have a selected session ID, find its index
|
||||||
@@ -206,7 +206,7 @@ func (s *sessionDialogCmp) SetSessions(sessions []client.SessionInfo) {
|
|||||||
s.selectedIdx = 0
|
s.selectedIdx = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *sessionDialogCmp) SetSelectedSession(sessionID string) {
|
func (s *sessionDialogComponent) SetSelectedSession(sessionID string) {
|
||||||
s.selectedSessionID = sessionID
|
s.selectedSessionID = sessionID
|
||||||
|
|
||||||
// Update the selected index if sessions are already loaded
|
// 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
|
// NewSessionDialogCmp creates a new session switching dialog
|
||||||
func NewSessionDialogCmp() SessionDialog {
|
func NewSessionDialogCmp() SessionDialog {
|
||||||
return &sessionDialogCmp{
|
return &sessionDialogComponent{
|
||||||
sessions: []client.SessionInfo{},
|
sessions: []client.SessionInfo{},
|
||||||
selectedIdx: 0,
|
selectedIdx: 0,
|
||||||
selectedSessionID: "",
|
selectedSessionID: "",
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package dialog
|
package dialog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/layout"
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/status"
|
"github.com/sst/opencode/internal/status"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
@@ -21,11 +21,11 @@ type CloseThemeDialogMsg struct{}
|
|||||||
|
|
||||||
// ThemeDialog interface for the theme switching dialog
|
// ThemeDialog interface for the theme switching dialog
|
||||||
type ThemeDialog interface {
|
type ThemeDialog interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
layout.Bindings
|
layout.Bindings
|
||||||
}
|
}
|
||||||
|
|
||||||
type themeDialogCmp struct {
|
type themeDialogComponent struct {
|
||||||
themes []string
|
themes []string
|
||||||
selectedIdx int
|
selectedIdx int
|
||||||
width 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
|
// Load available themes and update selectedIdx based on current theme
|
||||||
t.themes = theme.AvailableThemes()
|
t.themes = theme.AvailableThemes()
|
||||||
t.currentTheme = theme.CurrentThemeName()
|
t.currentTheme = theme.CurrentThemeName()
|
||||||
@@ -85,7 +85,7 @@ func (t *themeDialogCmp) Init() tea.Cmd {
|
|||||||
return nil
|
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) {
|
switch msg := msg.(type) {
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
switch {
|
switch {
|
||||||
@@ -124,7 +124,7 @@ func (t *themeDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *themeDialogCmp) View() string {
|
func (t *themeDialogComponent) View() string {
|
||||||
currentTheme := theme.CurrentTheme()
|
currentTheme := theme.CurrentTheme()
|
||||||
baseStyle := styles.BaseStyle()
|
baseStyle := styles.BaseStyle()
|
||||||
|
|
||||||
@@ -185,13 +185,13 @@ func (t *themeDialogCmp) View() string {
|
|||||||
Render(content)
|
Render(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *themeDialogCmp) BindingKeys() []key.Binding {
|
func (t *themeDialogComponent) BindingKeys() []key.Binding {
|
||||||
return layout.KeyMapToSlice(themeKeys)
|
return layout.KeyMapToSlice(themeKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewThemeDialogCmp creates a new theme switching dialog
|
// NewThemeDialogCmp creates a new theme switching dialog
|
||||||
func NewThemeDialogCmp() ThemeDialog {
|
func NewThemeDialogCmp() ThemeDialog {
|
||||||
return &themeDialogCmp{
|
return &themeDialogComponent{
|
||||||
themes: []string{},
|
themes: []string{},
|
||||||
selectedIdx: 0,
|
selectedIdx: 0,
|
||||||
currentTheme: "",
|
currentTheme: "",
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package dialog
|
package dialog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
utilComponents "github.com/sst/opencode/internal/components/util"
|
utilComponents "github.com/sst/opencode/internal/components/util"
|
||||||
"github.com/sst/opencode/internal/layout"
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
@@ -17,7 +17,7 @@ const (
|
|||||||
|
|
||||||
// ToolsDialog interface for the tools list dialog
|
// ToolsDialog interface for the tools list dialog
|
||||||
type ToolsDialog interface {
|
type ToolsDialog interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
layout.Bindings
|
layout.Bindings
|
||||||
SetTools(tools []string)
|
SetTools(tools []string)
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ func (t toolItem) Render(selected bool, width int) string {
|
|||||||
baseStyle := styles.BaseStyle().
|
baseStyle := styles.BaseStyle().
|
||||||
Width(width).
|
Width(width).
|
||||||
Background(th.Background())
|
Background(th.Background())
|
||||||
|
|
||||||
if selected {
|
if selected {
|
||||||
baseStyle = baseStyle.
|
baseStyle = baseStyle.
|
||||||
Background(th.Primary()).
|
Background(th.Primary()).
|
||||||
@@ -49,15 +49,15 @@ func (t toolItem) Render(selected bool, width int) string {
|
|||||||
baseStyle = baseStyle.
|
baseStyle = baseStyle.
|
||||||
Foreground(th.Text())
|
Foreground(th.Text())
|
||||||
}
|
}
|
||||||
|
|
||||||
return baseStyle.Render(t.name)
|
return baseStyle.Render(t.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
type toolsDialogCmp struct {
|
type toolsDialogComponent struct {
|
||||||
tools []toolItem
|
tools []toolItem
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
list utilComponents.SimpleList[toolItem]
|
list utilComponents.SimpleList[toolItem]
|
||||||
}
|
}
|
||||||
|
|
||||||
type toolsKeyMap struct {
|
type toolsKeyMap struct {
|
||||||
@@ -91,21 +91,21 @@ var toolsKeys = toolsKeyMap{
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *toolsDialogCmp) Init() tea.Cmd {
|
func (m *toolsDialogComponent) Init() tea.Cmd {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *toolsDialogCmp) SetTools(tools []string) {
|
func (m *toolsDialogComponent) SetTools(tools []string) {
|
||||||
var toolItems []toolItem
|
var toolItems []toolItem
|
||||||
for _, name := range tools {
|
for _, name := range tools {
|
||||||
toolItems = append(toolItems, toolItem{name: name})
|
toolItems = append(toolItems, toolItem{name: name})
|
||||||
}
|
}
|
||||||
|
|
||||||
m.tools = toolItems
|
m.tools = toolItems
|
||||||
m.list.SetItems(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) {
|
switch msg := msg.(type) {
|
||||||
case tea.KeyMsg:
|
case tea.KeyMsg:
|
||||||
switch {
|
switch {
|
||||||
@@ -130,7 +130,7 @@ func (m *toolsDialogCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
return m, cmd
|
return m, cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *toolsDialogCmp) View() string {
|
func (m *toolsDialogComponent) View() string {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
baseStyle := styles.BaseStyle().Background(t.Background())
|
baseStyle := styles.BaseStyle().Background(t.Background())
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ func (m *toolsDialogCmp) View() string {
|
|||||||
// Calculate dialog width based on content
|
// Calculate dialog width based on content
|
||||||
dialogWidth := min(maxToolsDialogWidth, m.width/2)
|
dialogWidth := min(maxToolsDialogWidth, m.width/2)
|
||||||
m.list.SetMaxWidth(dialogWidth)
|
m.list.SetMaxWidth(dialogWidth)
|
||||||
|
|
||||||
content := lipgloss.JoinVertical(
|
content := lipgloss.JoinVertical(
|
||||||
lipgloss.Left,
|
lipgloss.Left,
|
||||||
title,
|
title,
|
||||||
@@ -160,7 +160,7 @@ func (m *toolsDialogCmp) View() string {
|
|||||||
Render(content)
|
Render(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *toolsDialogCmp) BindingKeys() []key.Binding {
|
func (m *toolsDialogComponent) BindingKeys() []key.Binding {
|
||||||
return layout.KeyMapToSlice(toolsKeys)
|
return layout.KeyMapToSlice(toolsKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,8 +171,8 @@ func NewToolsDialogCmp() ToolsDialog {
|
|||||||
"No tools available",
|
"No tools available",
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
|
|
||||||
return &toolsDialogCmp{
|
return &toolsDialogComponent{
|
||||||
list: list,
|
list: list,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package diff
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image/color"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -12,9 +13,11 @@ import (
|
|||||||
"github.com/alecthomas/chroma/v2/formatters"
|
"github.com/alecthomas/chroma/v2/formatters"
|
||||||
"github.com/alecthomas/chroma/v2/lexers"
|
"github.com/alecthomas/chroma/v2/lexers"
|
||||||
"github.com/alecthomas/chroma/v2/styles"
|
"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/charmbracelet/x/ansi"
|
||||||
"github.com/sergi/go-diff/diffmatchpatch"
|
"github.com/sergi/go-diff/diffmatchpatch"
|
||||||
|
stylesi "github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"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
|
// 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()
|
t := theme.CurrentTheme()
|
||||||
|
|
||||||
// Determine the language lexer to use
|
// 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
|
// getColor returns the appropriate hex color string based on terminal background
|
||||||
func getColor(adaptiveColor lipgloss.AdaptiveColor) string {
|
func getColor(adaptiveColor compat.AdaptiveColor) string {
|
||||||
if lipgloss.HasDarkBackground() {
|
return stylesi.AdaptiveColorToString(adaptiveColor)
|
||||||
return adaptiveColor.Dark
|
|
||||||
}
|
|
||||||
return adaptiveColor.Light
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// highlightLine applies syntax highlighting to a single line
|
// 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
|
var buf bytes.Buffer
|
||||||
err := SyntaxHighlight(&buf, line, fileName, "terminal16m", bg)
|
err := SyntaxHighlight(&buf, line, fileName, "terminal16m", bg)
|
||||||
if err != nil {
|
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
|
// 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
|
// Find all ANSI sequences in the content
|
||||||
ansiRegex := regexp.MustCompile(`\x1b(?:[@-Z\\-_]|\[[0-9?]*(?:;[0-9?]*)*[@-~])`)
|
ansiRegex := regexp.MustCompile(`\x1b(?:[@-Z\\-_]|\[[0-9?]*(?:;[0-9?]*)*[@-~])`)
|
||||||
ansiMatches := ansiRegex.FindAllStringIndex(content, -1)
|
ansiMatches := ansiRegex.FindAllStringIndex(content, -1)
|
||||||
@@ -662,7 +662,7 @@ func renderDiffColumnLine(
|
|||||||
var bgStyle lipgloss.Style
|
var bgStyle lipgloss.Style
|
||||||
var lineNum string
|
var lineNum string
|
||||||
var highlightType LineType
|
var highlightType LineType
|
||||||
var highlightColor lipgloss.AdaptiveColor
|
var highlightColor compat.AdaptiveColor
|
||||||
|
|
||||||
if isLeftColumn {
|
if isLeftColumn {
|
||||||
// Left column logic
|
// Left column logic
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package qr
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
"rsc.io/qr"
|
"rsc.io/qr"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package utilComponents
|
package utilComponents
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/layout"
|
"github.com/sst/opencode/internal/layout"
|
||||||
"github.com/sst/opencode/internal/styles"
|
"github.com/sst/opencode/internal/styles"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
@@ -14,7 +14,7 @@ type SimpleListItem interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SimpleList[T SimpleListItem] interface {
|
type SimpleList[T SimpleListItem] interface {
|
||||||
tea.Model
|
layout.ModelWithView
|
||||||
layout.Bindings
|
layout.Bindings
|
||||||
SetMaxWidth(maxWidth int)
|
SetMaxWidth(maxWidth int)
|
||||||
GetSelectedItem() (item T, idx int)
|
GetSelectedItem() (item T, idx int)
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
"image/png"
|
"image/png"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/disintegration/imaging"
|
"github.com/disintegration/imaging"
|
||||||
"github.com/lucasb-eyer/go-colorful"
|
"github.com/lucasb-eyer/go-colorful"
|
||||||
_ "golang.org/x/image/webp"
|
_ "golang.org/x/image/webp"
|
||||||
@@ -39,7 +40,7 @@ func ToString(width int, img image.Image) string {
|
|||||||
c1, _ := colorful.MakeColor(img.At(x, heightCounter))
|
c1, _ := colorful.MakeColor(img.At(x, heightCounter))
|
||||||
color1 := lipgloss.Color(c1.Hex())
|
color1 := lipgloss.Color(c1.Hex())
|
||||||
|
|
||||||
var color2 lipgloss.Color
|
var color2 color.Color
|
||||||
if heightCounter+1 < h {
|
if heightCounter+1 < h {
|
||||||
c2, _ := colorful.MakeColor(img.At(x, heightCounter+1))
|
c2, _ := colorful.MakeColor(img.At(x, heightCounter+1))
|
||||||
color2 = lipgloss.Color(c2.Hex())
|
color2 = lipgloss.Color(c2.Hex())
|
||||||
@@ -76,10 +77,10 @@ func ImagePreview(width int, filename string) (string, error) {
|
|||||||
|
|
||||||
func ImageToBytes(image image.Image) ([]byte, error) {
|
func ImageToBytes(image image.Image) ([]byte, error) {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err := png.Encode(buf, image)
|
err := png.Encode(buf, image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf.Bytes(), nil
|
return buf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
package layout
|
package layout
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Container interface {
|
type ModelWithView interface {
|
||||||
tea.Model
|
tea.Model
|
||||||
|
tea.ViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
type Container interface {
|
||||||
|
ModelWithView
|
||||||
Sizeable
|
Sizeable
|
||||||
Bindings
|
Bindings
|
||||||
Focus()
|
Focus()
|
||||||
@@ -21,7 +26,7 @@ type container struct {
|
|||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
|
|
||||||
content tea.Model
|
content ModelWithView
|
||||||
|
|
||||||
paddingTop int
|
paddingTop int
|
||||||
paddingRight int
|
paddingRight int
|
||||||
@@ -46,7 +51,7 @@ func (c *container) Init() tea.Cmd {
|
|||||||
|
|
||||||
func (c *container) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
func (c *container) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||||
u, cmd := c.content.Update(msg)
|
u, cmd := c.content.Update(msg)
|
||||||
c.content = u
|
c.content = u.(ModelWithView)
|
||||||
return c, cmd
|
return c, cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +180,7 @@ func (c *container) Blur() {
|
|||||||
|
|
||||||
type ContainerOption func(*container)
|
type ContainerOption func(*container)
|
||||||
|
|
||||||
func NewContainer(content tea.Model, options ...ContainerOption) Container {
|
func NewContainer(content ModelWithView, options ...ContainerOption) Container {
|
||||||
c := &container{
|
c := &container{
|
||||||
content: content,
|
content: content,
|
||||||
borderStyle: lipgloss.NormalBorder(),
|
borderStyle: lipgloss.NormalBorder(),
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package layout
|
package layout
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/theme"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type FlexDirection int
|
type FlexDirection int
|
||||||
@@ -26,7 +25,7 @@ func FlexPaneSizeFixed(size int) FlexPaneSize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type FlexLayout interface {
|
type FlexLayout interface {
|
||||||
tea.Model
|
ModelWithView
|
||||||
Sizeable
|
Sizeable
|
||||||
Bindings
|
Bindings
|
||||||
SetPanes(panes []Container) tea.Cmd
|
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 {
|
func (f *flexLayout) View() string {
|
||||||
t := theme.CurrentTheme()
|
|
||||||
|
|
||||||
if len(f.panes) == 0 {
|
if len(f.panes) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -94,7 +91,6 @@ func (f *flexLayout) View() string {
|
|||||||
paneWidth,
|
paneWidth,
|
||||||
pane.Alignment(),
|
pane.Alignment(),
|
||||||
pane.View(),
|
pane.View(),
|
||||||
lipgloss.WithWhitespaceBackground(t.Background()),
|
|
||||||
)
|
)
|
||||||
views = append(views, view)
|
views = append(views, view)
|
||||||
} else {
|
} else {
|
||||||
@@ -105,7 +101,6 @@ func (f *flexLayout) View() string {
|
|||||||
lipgloss.Center,
|
lipgloss.Center,
|
||||||
pane.Alignment(),
|
pane.Alignment(),
|
||||||
pane.View(),
|
pane.View(),
|
||||||
lipgloss.WithWhitespaceBackground(t.Background()),
|
|
||||||
)
|
)
|
||||||
views = append(views, view)
|
views = append(views, view)
|
||||||
}
|
}
|
||||||
@@ -245,4 +240,3 @@ func WithPaneSizes(sizes ...FlexPaneSize) FlexLayoutOption {
|
|||||||
f.sizes = sizes
|
f.sizes = sizes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package layout
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Current *LayoutInfo
|
var Current *LayoutInfo
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package layout
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
chAnsi "github.com/charmbracelet/x/ansi"
|
chAnsi "github.com/charmbracelet/x/ansi"
|
||||||
"github.com/muesli/ansi"
|
"github.com/muesli/ansi"
|
||||||
"github.com/muesli/reflow/truncate"
|
"github.com/muesli/reflow/truncate"
|
||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Most of this code is borrowed from
|
// 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.
|
// 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.
|
// Split a string into lines, additionally returning the size of the widest line.
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
"github.com/sst/opencode/internal/app"
|
"github.com/sst/opencode/internal/app"
|
||||||
"github.com/sst/opencode/internal/completions"
|
"github.com/sst/opencode/internal/completions"
|
||||||
"github.com/sst/opencode/internal/components/chat"
|
"github.com/sst/opencode/internal/components/chat"
|
||||||
@@ -187,7 +187,7 @@ func (p *chatPage) BindingKeys() []key.Binding {
|
|||||||
return bindings
|
return bindings
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChatPage(app *app.App) tea.Model {
|
func NewChatPage(app *app.App) layout.ModelWithView {
|
||||||
cg := completions.NewFileAndFolderContextGroup()
|
cg := completions.NewFileAndFolderContextGroup()
|
||||||
completionDialog := dialog.NewCompletionDialogCmp(cg)
|
completionDialog := dialog.NewCompletionDialogCmp(cg)
|
||||||
messagesContainer := layout.NewContainer(
|
messagesContainer := layout.NewContainer(
|
||||||
|
|||||||
@@ -1,123 +1,13 @@
|
|||||||
package styles
|
package styles
|
||||||
|
|
||||||
import (
|
type TerminalInfo struct {
|
||||||
"fmt"
|
BackgroundIsDark bool
|
||||||
"regexp"
|
}
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
var Terminal *TerminalInfo
|
||||||
)
|
|
||||||
|
|
||||||
var ansiEscape = regexp.MustCompile("\x1b\\[[0-9;]*m")
|
func init() {
|
||||||
|
Terminal = &TerminalInfo{
|
||||||
func getColorRGB(c lipgloss.TerminalColor) (uint8, uint8, uint8) {
|
BackgroundIsDark: false,
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 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"
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ package styles
|
|||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/glamour"
|
"github.com/charmbracelet/glamour"
|
||||||
"github.com/charmbracelet/glamour/ansi"
|
"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"
|
"github.com/sst/opencode/internal/theme"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,117 +16,120 @@ func stringPtr(s string) *string { return &s }
|
|||||||
func uintPtr(u uint) *uint { return &u }
|
func uintPtr(u uint) *uint { return &u }
|
||||||
|
|
||||||
// returns a glamour TermRenderer configured with the current theme
|
// 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(
|
r, _ := glamour.NewTermRenderer(
|
||||||
glamour.WithStyles(generateMarkdownStyleConfig()),
|
glamour.WithStyles(generateMarkdownStyleConfig(backgroundColor)),
|
||||||
glamour.WithWordWrap(width),
|
glamour.WithWordWrap(width),
|
||||||
|
glamour.WithChromaFormatter("terminal16m"),
|
||||||
)
|
)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates an ansi.StyleConfig for markdown rendering
|
// creates an ansi.StyleConfig for markdown rendering
|
||||||
// using adaptive colors from the provided theme.
|
// using adaptive colors from the provided theme.
|
||||||
func generateMarkdownStyleConfig() ansi.StyleConfig {
|
func generateMarkdownStyleConfig(backgroundColor compat.AdaptiveColor) ansi.StyleConfig {
|
||||||
t := theme.CurrentTheme()
|
t := theme.CurrentTheme()
|
||||||
|
background := stringPtr(AdaptiveColorToString(backgroundColor))
|
||||||
|
|
||||||
return ansi.StyleConfig{
|
return ansi.StyleConfig{
|
||||||
Document: ansi.StyleBlock{
|
Document: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
BlockPrefix: "",
|
BlockPrefix: "",
|
||||||
BlockSuffix: "",
|
BlockSuffix: "",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
BlockQuote: ansi.StyleBlock{
|
BlockQuote: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownBlockQuote())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownBlockQuote())),
|
||||||
Italic: boolPtr(true),
|
Italic: boolPtr(true),
|
||||||
Prefix: "┃ ",
|
Prefix: "┃ ",
|
||||||
},
|
},
|
||||||
Indent: uintPtr(1),
|
Indent: uintPtr(1),
|
||||||
IndentToken: stringPtr(BaseStyle().Render(" ")),
|
IndentToken: stringPtr(" "),
|
||||||
},
|
},
|
||||||
List: ansi.StyleList{
|
List: ansi.StyleList{
|
||||||
LevelIndent: defaultMargin,
|
LevelIndent: defaultMargin,
|
||||||
StyleBlock: ansi.StyleBlock{
|
StyleBlock: ansi.StyleBlock{
|
||||||
IndentToken: stringPtr(BaseStyle().Render(" ")),
|
IndentToken: stringPtr(" "),
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Heading: ansi.StyleBlock{
|
Heading: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
BlockSuffix: "\n",
|
BlockSuffix: "\n",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
|
||||||
Bold: boolPtr(true),
|
Bold: boolPtr(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
H1: ansi.StyleBlock{
|
H1: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
Prefix: "# ",
|
Prefix: "# ",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
|
||||||
Bold: boolPtr(true),
|
Bold: boolPtr(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
H2: ansi.StyleBlock{
|
H2: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
Prefix: "## ",
|
Prefix: "## ",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
|
||||||
Bold: boolPtr(true),
|
Bold: boolPtr(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
H3: ansi.StyleBlock{
|
H3: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
Prefix: "### ",
|
Prefix: "### ",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
|
||||||
Bold: boolPtr(true),
|
Bold: boolPtr(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
H4: ansi.StyleBlock{
|
H4: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
Prefix: "#### ",
|
Prefix: "#### ",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
|
||||||
Bold: boolPtr(true),
|
Bold: boolPtr(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
H5: ansi.StyleBlock{
|
H5: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
Prefix: "##### ",
|
Prefix: "##### ",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
|
||||||
Bold: boolPtr(true),
|
Bold: boolPtr(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
H6: ansi.StyleBlock{
|
H6: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
Prefix: "###### ",
|
Prefix: "###### ",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownHeading())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownHeading())),
|
||||||
Bold: boolPtr(true),
|
Bold: boolPtr(true),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Strikethrough: ansi.StylePrimitive{
|
Strikethrough: ansi.StylePrimitive{
|
||||||
CrossedOut: boolPtr(true),
|
CrossedOut: boolPtr(true),
|
||||||
Color: stringPtr(adaptiveColorToString(t.TextMuted())),
|
Color: stringPtr(AdaptiveColorToString(t.TextMuted())),
|
||||||
},
|
},
|
||||||
Emph: ansi.StylePrimitive{
|
Emph: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownEmph())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownEmph())),
|
||||||
Italic: boolPtr(true),
|
Italic: boolPtr(true),
|
||||||
},
|
},
|
||||||
Strong: ansi.StylePrimitive{
|
Strong: ansi.StylePrimitive{
|
||||||
Bold: boolPtr(true),
|
Bold: boolPtr(true),
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownStrong())),
|
||||||
},
|
},
|
||||||
HorizontalRule: ansi.StylePrimitive{
|
HorizontalRule: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownHorizontalRule())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownHorizontalRule())),
|
||||||
Format: "\n─────────────────────────────────────────\n",
|
Format: "\n─────────────────────────────────────────\n",
|
||||||
},
|
},
|
||||||
Item: ansi.StylePrimitive{
|
Item: ansi.StylePrimitive{
|
||||||
BlockPrefix: "• ",
|
BlockPrefix: "• ",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownListItem())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownListItem())),
|
||||||
},
|
},
|
||||||
Enumeration: ansi.StylePrimitive{
|
Enumeration: ansi.StylePrimitive{
|
||||||
BlockPrefix: ". ",
|
BlockPrefix: ". ",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownListEnumeration())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownListEnumeration())),
|
||||||
},
|
},
|
||||||
Task: ansi.StyleTask{
|
Task: ansi.StyleTask{
|
||||||
StylePrimitive: ansi.StylePrimitive{},
|
StylePrimitive: ansi.StylePrimitive{},
|
||||||
@@ -133,116 +137,147 @@ func generateMarkdownStyleConfig() ansi.StyleConfig {
|
|||||||
Unticked: "[ ] ",
|
Unticked: "[ ] ",
|
||||||
},
|
},
|
||||||
Link: ansi.StylePrimitive{
|
Link: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownLink())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownLink())),
|
||||||
Underline: boolPtr(true),
|
Underline: boolPtr(true),
|
||||||
},
|
},
|
||||||
LinkText: ansi.StylePrimitive{
|
LinkText: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownLinkText())),
|
||||||
Bold: boolPtr(true),
|
Bold: boolPtr(true),
|
||||||
},
|
},
|
||||||
Image: ansi.StylePrimitive{
|
Image: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownImage())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownImage())),
|
||||||
Underline: boolPtr(true),
|
Underline: boolPtr(true),
|
||||||
Format: "🖼 {{.text}}",
|
Format: "🖼 {{.text}}",
|
||||||
},
|
},
|
||||||
ImageText: ansi.StylePrimitive{
|
ImageText: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownImageText())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownImageText())),
|
||||||
Format: "{{.text}}",
|
Format: "{{.text}}",
|
||||||
},
|
},
|
||||||
Code: ansi.StyleBlock{
|
Code: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownCode())),
|
BackgroundColor: background,
|
||||||
Prefix: "",
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownCode())),
|
||||||
Suffix: "",
|
Prefix: "",
|
||||||
|
Suffix: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
CodeBlock: ansi.StyleCodeBlock{
|
CodeBlock: ansi.StyleCodeBlock{
|
||||||
StyleBlock: ansi.StyleBlock{
|
StyleBlock: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
StylePrimitive: ansi.StylePrimitive{
|
||||||
Prefix: " ",
|
BackgroundColor: background,
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownCodeBlock())),
|
Prefix: " ",
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownCodeBlock())),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Chroma: &ansi.Chroma{
|
Chroma: &ansi.Chroma{
|
||||||
|
Background: ansi.StylePrimitive{
|
||||||
|
BackgroundColor: background,
|
||||||
|
},
|
||||||
Text: ansi.StylePrimitive{
|
Text: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
|
||||||
},
|
},
|
||||||
Error: ansi.StylePrimitive{
|
Error: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.Error())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.Error())),
|
||||||
},
|
},
|
||||||
Comment: ansi.StylePrimitive{
|
Comment: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxComment())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxComment())),
|
||||||
},
|
},
|
||||||
CommentPreproc: ansi.StylePrimitive{
|
CommentPreproc: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
|
||||||
},
|
},
|
||||||
Keyword: ansi.StylePrimitive{
|
Keyword: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
|
||||||
},
|
},
|
||||||
KeywordReserved: ansi.StylePrimitive{
|
KeywordReserved: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
|
||||||
},
|
},
|
||||||
KeywordNamespace: ansi.StylePrimitive{
|
KeywordNamespace: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
|
||||||
},
|
},
|
||||||
KeywordType: ansi.StylePrimitive{
|
KeywordType: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxType())),
|
||||||
},
|
},
|
||||||
Operator: ansi.StylePrimitive{
|
Operator: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxOperator())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxOperator())),
|
||||||
},
|
},
|
||||||
Punctuation: ansi.StylePrimitive{
|
Punctuation: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxPunctuation())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxPunctuation())),
|
||||||
},
|
},
|
||||||
Name: ansi.StylePrimitive{
|
Name: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxVariable())),
|
||||||
},
|
},
|
||||||
NameBuiltin: ansi.StylePrimitive{
|
NameBuiltin: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxVariable())),
|
||||||
},
|
},
|
||||||
NameTag: ansi.StylePrimitive{
|
NameTag: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
|
||||||
},
|
},
|
||||||
NameAttribute: ansi.StylePrimitive{
|
NameAttribute: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxFunction())),
|
||||||
},
|
},
|
||||||
NameClass: ansi.StylePrimitive{
|
NameClass: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxType())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxType())),
|
||||||
},
|
},
|
||||||
NameConstant: ansi.StylePrimitive{
|
NameConstant: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxVariable())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxVariable())),
|
||||||
},
|
},
|
||||||
NameDecorator: ansi.StylePrimitive{
|
NameDecorator: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxFunction())),
|
||||||
},
|
},
|
||||||
NameFunction: ansi.StylePrimitive{
|
NameFunction: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxFunction())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxFunction())),
|
||||||
},
|
},
|
||||||
LiteralNumber: ansi.StylePrimitive{
|
LiteralNumber: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxNumber())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxNumber())),
|
||||||
},
|
},
|
||||||
LiteralString: ansi.StylePrimitive{
|
LiteralString: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxString())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxString())),
|
||||||
},
|
},
|
||||||
LiteralStringEscape: ansi.StylePrimitive{
|
LiteralStringEscape: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.SyntaxKeyword())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.SyntaxKeyword())),
|
||||||
},
|
},
|
||||||
GenericDeleted: ansi.StylePrimitive{
|
GenericDeleted: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.DiffRemoved())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.DiffRemoved())),
|
||||||
},
|
},
|
||||||
GenericEmph: ansi.StylePrimitive{
|
GenericEmph: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownEmph())),
|
BackgroundColor: background,
|
||||||
Italic: boolPtr(true),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownEmph())),
|
||||||
|
Italic: boolPtr(true),
|
||||||
},
|
},
|
||||||
GenericInserted: ansi.StylePrimitive{
|
GenericInserted: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.DiffAdded())),
|
BackgroundColor: background,
|
||||||
|
Color: stringPtr(AdaptiveColorToString(t.DiffAdded())),
|
||||||
},
|
},
|
||||||
GenericStrong: ansi.StylePrimitive{
|
GenericStrong: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownStrong())),
|
BackgroundColor: background,
|
||||||
Bold: boolPtr(true),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownStrong())),
|
||||||
|
Bold: boolPtr(true),
|
||||||
},
|
},
|
||||||
GenericSubheading: ansi.StylePrimitive{
|
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{
|
DefinitionDescription: ansi.StylePrimitive{
|
||||||
BlockPrefix: "\n ❯ ",
|
BlockPrefix: "\n ❯ ",
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownLinkText())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownLinkText())),
|
||||||
},
|
},
|
||||||
Text: ansi.StylePrimitive{
|
Text: ansi.StylePrimitive{
|
||||||
Color: stringPtr(adaptiveColorToString(t.MarkdownText())),
|
Color: stringPtr(AdaptiveColorToString(t.MarkdownText())),
|
||||||
},
|
},
|
||||||
Paragraph: ansi.StyleBlock{
|
Paragraph: ansi.StyleBlock{
|
||||||
StylePrimitive: ansi.StylePrimitive{
|
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
|
// hex color string based on the current terminal background
|
||||||
func adaptiveColorToString(color lipgloss.AdaptiveColor) string {
|
func AdaptiveColorToString(color compat.AdaptiveColor) string {
|
||||||
if lipgloss.HasDarkBackground() {
|
if Terminal.BackgroundIsDark {
|
||||||
return color.Dark
|
c1, _ := colorful.MakeColor(color.Dark)
|
||||||
|
return c1.Hex()
|
||||||
}
|
}
|
||||||
return color.Light
|
c1, _ := colorful.MakeColor(color.Light)
|
||||||
|
return c1.Hex()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package styles
|
package styles
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
|
"github.com/charmbracelet/lipgloss/v2/compat"
|
||||||
"github.com/sst/opencode/internal/theme"
|
"github.com/sst/opencode/internal/theme"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -83,76 +84,76 @@ func DimBorder() lipgloss.Style {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PrimaryColor returns the primary color from the current theme
|
// PrimaryColor returns the primary color from the current theme
|
||||||
func PrimaryColor() lipgloss.AdaptiveColor {
|
func PrimaryColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().Primary()
|
return theme.CurrentTheme().Primary()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SecondaryColor returns the secondary color from the current theme
|
// SecondaryColor returns the secondary color from the current theme
|
||||||
func SecondaryColor() lipgloss.AdaptiveColor {
|
func SecondaryColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().Secondary()
|
return theme.CurrentTheme().Secondary()
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccentColor returns the accent color from the current theme
|
// AccentColor returns the accent color from the current theme
|
||||||
func AccentColor() lipgloss.AdaptiveColor {
|
func AccentColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().Accent()
|
return theme.CurrentTheme().Accent()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrorColor returns the error color from the current theme
|
// ErrorColor returns the error color from the current theme
|
||||||
func ErrorColor() lipgloss.AdaptiveColor {
|
func ErrorColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().Error()
|
return theme.CurrentTheme().Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// WarningColor returns the warning color from the current theme
|
// WarningColor returns the warning color from the current theme
|
||||||
func WarningColor() lipgloss.AdaptiveColor {
|
func WarningColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().Warning()
|
return theme.CurrentTheme().Warning()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuccessColor returns the success color from the current theme
|
// SuccessColor returns the success color from the current theme
|
||||||
func SuccessColor() lipgloss.AdaptiveColor {
|
func SuccessColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().Success()
|
return theme.CurrentTheme().Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
// InfoColor returns the info color from the current theme
|
// InfoColor returns the info color from the current theme
|
||||||
func InfoColor() lipgloss.AdaptiveColor {
|
func InfoColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().Info()
|
return theme.CurrentTheme().Info()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TextColor returns the text color from the current theme
|
// TextColor returns the text color from the current theme
|
||||||
func TextColor() lipgloss.AdaptiveColor {
|
func TextColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().Text()
|
return theme.CurrentTheme().Text()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TextMutedColor returns the muted text color from the current theme
|
// TextMutedColor returns the muted text color from the current theme
|
||||||
func TextMutedColor() lipgloss.AdaptiveColor {
|
func TextMutedColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().TextMuted()
|
return theme.CurrentTheme().TextMuted()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BackgroundColor returns the background color from the current theme
|
// BackgroundColor returns the background color from the current theme
|
||||||
func BackgroundColor() lipgloss.AdaptiveColor {
|
func BackgroundColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().Background()
|
return theme.CurrentTheme().Background()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BackgroundSubtleColor returns the subtle background color from the current theme
|
// BackgroundSubtleColor returns the subtle background color from the current theme
|
||||||
func BackgroundSubtleColor() lipgloss.AdaptiveColor {
|
func BackgroundSubtleColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().BackgroundSubtle()
|
return theme.CurrentTheme().BackgroundSubtle()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BackgroundElementColor returns the darker background color from the current theme
|
// BackgroundElementColor returns the darker background color from the current theme
|
||||||
func BackgroundElementColor() lipgloss.AdaptiveColor {
|
func BackgroundElementColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().BackgroundElement()
|
return theme.CurrentTheme().BackgroundElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BorderColor returns the border color from the current theme
|
// BorderColor returns the border color from the current theme
|
||||||
func BorderColor() lipgloss.AdaptiveColor {
|
func BorderColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().Border()
|
return theme.CurrentTheme().Border()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BorderActiveColor returns the active border color from the current theme
|
// BorderActiveColor returns the active border color from the current theme
|
||||||
func BorderActiveColor() lipgloss.AdaptiveColor {
|
func BorderActiveColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().BorderActive()
|
return theme.CurrentTheme().BorderActive()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BorderSubtleColor returns the subtle border color from the current theme
|
// BorderSubtleColor returns the subtle border color from the current theme
|
||||||
func BorderSubtleColor() lipgloss.AdaptiveColor {
|
func BorderSubtleColor() compat.AdaptiveColor {
|
||||||
return theme.CurrentTheme().BorderSubtle()
|
return theme.CurrentTheme().BorderSubtle()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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())
|
|
||||||
}
|
|
||||||
@@ -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())
|
|
||||||
}
|
|
||||||
@@ -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())
|
|
||||||
}
|
|
||||||
@@ -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())
|
|
||||||
}
|
|
||||||
@@ -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())
|
|
||||||
}
|
|
||||||
@@ -6,8 +6,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
// "github.com/alecthomas/chroma/v2/styles"
|
||||||
"github.com/alecthomas/chroma/v2/styles"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Manager handles theme registration, selection, and retrieval.
|
// Manager handles theme registration, selection, and retrieval.
|
||||||
@@ -46,7 +45,7 @@ func RegisterTheme(name string, theme Theme) {
|
|||||||
func SetTheme(name string) error {
|
func SetTheme(name string) error {
|
||||||
globalManager.mu.Lock()
|
globalManager.mu.Lock()
|
||||||
defer globalManager.mu.Unlock()
|
defer globalManager.mu.Unlock()
|
||||||
delete(styles.Registry, "charm")
|
// delete(styles.Registry, "charm")
|
||||||
|
|
||||||
// Handle custom theme
|
// Handle custom theme
|
||||||
// if name == "custom" {
|
// if name == "custom" {
|
||||||
|
|||||||
@@ -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())
|
|
||||||
}
|
|
||||||
@@ -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())
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
package theme
|
package theme
|
||||||
|
|
||||||
import (
|
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.
|
// OpenCodeTheme implements the Theme interface with OpenCode brand colors.
|
||||||
@@ -72,219 +73,219 @@ func NewOpenCodeTheme() *OpenCodeTheme {
|
|||||||
theme := &OpenCodeTheme{}
|
theme := &OpenCodeTheme{}
|
||||||
|
|
||||||
// Base colors
|
// Base colors
|
||||||
theme.PrimaryColor = lipgloss.AdaptiveColor{
|
theme.PrimaryColor = compat.AdaptiveColor{
|
||||||
Dark: darkPrimary,
|
Dark: lipgloss.Color(darkPrimary),
|
||||||
Light: lightPrimary,
|
Light: lipgloss.Color(lightPrimary),
|
||||||
}
|
}
|
||||||
theme.SecondaryColor = lipgloss.AdaptiveColor{
|
theme.SecondaryColor = compat.AdaptiveColor{
|
||||||
Dark: darkSecondary,
|
Dark: lipgloss.Color(darkSecondary),
|
||||||
Light: lightSecondary,
|
Light: lipgloss.Color(lightSecondary),
|
||||||
}
|
}
|
||||||
theme.AccentColor = lipgloss.AdaptiveColor{
|
theme.AccentColor = compat.AdaptiveColor{
|
||||||
Dark: darkAccent,
|
Dark: lipgloss.Color(darkAccent),
|
||||||
Light: lightAccent,
|
Light: lipgloss.Color(lightAccent),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status colors
|
// Status colors
|
||||||
theme.ErrorColor = lipgloss.AdaptiveColor{
|
theme.ErrorColor = compat.AdaptiveColor{
|
||||||
Dark: darkRed,
|
Dark: lipgloss.Color(darkRed),
|
||||||
Light: lightRed,
|
Light: lipgloss.Color(lightRed),
|
||||||
}
|
}
|
||||||
theme.WarningColor = lipgloss.AdaptiveColor{
|
theme.WarningColor = compat.AdaptiveColor{
|
||||||
Dark: darkOrange,
|
Dark: lipgloss.Color(darkOrange),
|
||||||
Light: lightOrange,
|
Light: lipgloss.Color(lightOrange),
|
||||||
}
|
}
|
||||||
theme.SuccessColor = lipgloss.AdaptiveColor{
|
theme.SuccessColor = compat.AdaptiveColor{
|
||||||
Dark: darkGreen,
|
Dark: lipgloss.Color(darkGreen),
|
||||||
Light: lightGreen,
|
Light: lipgloss.Color(lightGreen),
|
||||||
}
|
}
|
||||||
theme.InfoColor = lipgloss.AdaptiveColor{
|
theme.InfoColor = compat.AdaptiveColor{
|
||||||
Dark: darkCyan,
|
Dark: lipgloss.Color(darkCyan),
|
||||||
Light: lightCyan,
|
Light: lipgloss.Color(lightCyan),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text colors
|
// Text colors
|
||||||
theme.TextColor = lipgloss.AdaptiveColor{
|
theme.TextColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep12,
|
Dark: lipgloss.Color(darkStep12),
|
||||||
Light: lightStep12,
|
Light: lipgloss.Color(lightStep12),
|
||||||
}
|
}
|
||||||
theme.TextMutedColor = lipgloss.AdaptiveColor{
|
theme.TextMutedColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep11,
|
Dark: lipgloss.Color(darkStep11),
|
||||||
Light: lightStep11,
|
Light: lipgloss.Color(lightStep11),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Background colors
|
// Background colors
|
||||||
theme.BackgroundColor = lipgloss.AdaptiveColor{
|
theme.BackgroundColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep1,
|
Dark: lipgloss.Color(darkStep1),
|
||||||
Light: lightStep1,
|
Light: lipgloss.Color(lightStep1),
|
||||||
}
|
}
|
||||||
theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
|
theme.BackgroundSubtleColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep2,
|
Dark: lipgloss.Color(darkStep2),
|
||||||
Light: lightStep2,
|
Light: lipgloss.Color(lightStep2),
|
||||||
}
|
}
|
||||||
theme.BackgroundElementColor = lipgloss.AdaptiveColor{
|
theme.BackgroundElementColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep3,
|
Dark: lipgloss.Color(darkStep3),
|
||||||
Light: lightStep3,
|
Light: lipgloss.Color(lightStep3),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Border colors
|
// Border colors
|
||||||
theme.BorderColor = lipgloss.AdaptiveColor{
|
theme.BorderColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep7,
|
Dark: lipgloss.Color(darkStep7),
|
||||||
Light: lightStep7,
|
Light: lipgloss.Color(lightStep7),
|
||||||
}
|
}
|
||||||
theme.BorderActiveColor = lipgloss.AdaptiveColor{
|
theme.BorderActiveColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep8,
|
Dark: lipgloss.Color(darkStep8),
|
||||||
Light: lightStep8,
|
Light: lipgloss.Color(lightStep8),
|
||||||
}
|
}
|
||||||
theme.BorderSubtleColor = lipgloss.AdaptiveColor{
|
theme.BorderSubtleColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep6,
|
Dark: lipgloss.Color(darkStep6),
|
||||||
Light: lightStep6,
|
Light: lipgloss.Color(lightStep6),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diff view colors
|
// Diff view colors
|
||||||
theme.DiffAddedColor = lipgloss.AdaptiveColor{
|
theme.DiffAddedColor = compat.AdaptiveColor{
|
||||||
Dark: "#478247",
|
Dark: lipgloss.Color("#478247"),
|
||||||
Light: "#2E7D32",
|
Light: lipgloss.Color("#2E7D32"),
|
||||||
}
|
}
|
||||||
theme.DiffRemovedColor = lipgloss.AdaptiveColor{
|
theme.DiffRemovedColor = compat.AdaptiveColor{
|
||||||
Dark: "#7C4444",
|
Dark: lipgloss.Color("#7C4444"),
|
||||||
Light: "#C62828",
|
Light: lipgloss.Color("#C62828"),
|
||||||
}
|
}
|
||||||
theme.DiffContextColor = lipgloss.AdaptiveColor{
|
theme.DiffContextColor = compat.AdaptiveColor{
|
||||||
Dark: "#a0a0a0",
|
Dark: lipgloss.Color("#a0a0a0"),
|
||||||
Light: "#757575",
|
Light: lipgloss.Color("#757575"),
|
||||||
}
|
}
|
||||||
theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
|
theme.DiffHunkHeaderColor = compat.AdaptiveColor{
|
||||||
Dark: "#a0a0a0",
|
Dark: lipgloss.Color("#a0a0a0"),
|
||||||
Light: "#757575",
|
Light: lipgloss.Color("#757575"),
|
||||||
}
|
}
|
||||||
theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
|
theme.DiffHighlightAddedColor = compat.AdaptiveColor{
|
||||||
Dark: "#DAFADA",
|
Dark: lipgloss.Color("#DAFADA"),
|
||||||
Light: "#A5D6A7",
|
Light: lipgloss.Color("#A5D6A7"),
|
||||||
}
|
}
|
||||||
theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
|
theme.DiffHighlightRemovedColor = compat.AdaptiveColor{
|
||||||
Dark: "#FADADD",
|
Dark: lipgloss.Color("#FADADD"),
|
||||||
Light: "#EF9A9A",
|
Light: lipgloss.Color("#EF9A9A"),
|
||||||
}
|
}
|
||||||
theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
|
theme.DiffAddedBgColor = compat.AdaptiveColor{
|
||||||
Dark: "#303A30",
|
Dark: lipgloss.Color("#303A30"),
|
||||||
Light: "#E8F5E9",
|
Light: lipgloss.Color("#E8F5E9"),
|
||||||
}
|
}
|
||||||
theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
|
theme.DiffRemovedBgColor = compat.AdaptiveColor{
|
||||||
Dark: "#3A3030",
|
Dark: lipgloss.Color("#3A3030"),
|
||||||
Light: "#FFEBEE",
|
Light: lipgloss.Color("#FFEBEE"),
|
||||||
}
|
}
|
||||||
theme.DiffContextBgColor = lipgloss.AdaptiveColor{
|
theme.DiffContextBgColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep2,
|
Dark: lipgloss.Color(darkStep2),
|
||||||
Light: lightStep2,
|
Light: lipgloss.Color(lightStep2),
|
||||||
}
|
}
|
||||||
theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
|
theme.DiffLineNumberColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep3,
|
Dark: lipgloss.Color(darkStep3),
|
||||||
Light: lightStep3,
|
Light: lipgloss.Color(lightStep3),
|
||||||
}
|
}
|
||||||
theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
|
theme.DiffAddedLineNumberBgColor = compat.AdaptiveColor{
|
||||||
Dark: "#293229",
|
Dark: lipgloss.Color("#293229"),
|
||||||
Light: "#C8E6C9",
|
Light: lipgloss.Color("#C8E6C9"),
|
||||||
}
|
}
|
||||||
theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
|
theme.DiffRemovedLineNumberBgColor = compat.AdaptiveColor{
|
||||||
Dark: "#332929",
|
Dark: lipgloss.Color("#332929"),
|
||||||
Light: "#FFCDD2",
|
Light: lipgloss.Color("#FFCDD2"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Markdown colors
|
// Markdown colors
|
||||||
theme.MarkdownTextColor = lipgloss.AdaptiveColor{
|
theme.MarkdownTextColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep12,
|
Dark: lipgloss.Color(darkStep12),
|
||||||
Light: lightStep12,
|
Light: lipgloss.Color(lightStep12),
|
||||||
}
|
}
|
||||||
theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
|
theme.MarkdownHeadingColor = compat.AdaptiveColor{
|
||||||
Dark: darkSecondary,
|
Dark: lipgloss.Color(darkSecondary),
|
||||||
Light: lightSecondary,
|
Light: lipgloss.Color(lightSecondary),
|
||||||
}
|
}
|
||||||
theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
|
theme.MarkdownLinkColor = compat.AdaptiveColor{
|
||||||
Dark: darkPrimary,
|
Dark: lipgloss.Color(darkPrimary),
|
||||||
Light: lightPrimary,
|
Light: lipgloss.Color(lightPrimary),
|
||||||
}
|
}
|
||||||
theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
|
theme.MarkdownLinkTextColor = compat.AdaptiveColor{
|
||||||
Dark: darkCyan,
|
Dark: lipgloss.Color(darkCyan),
|
||||||
Light: lightCyan,
|
Light: lipgloss.Color(lightCyan),
|
||||||
}
|
}
|
||||||
theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
|
theme.MarkdownCodeColor = compat.AdaptiveColor{
|
||||||
Dark: darkGreen,
|
Dark: lipgloss.Color(darkGreen),
|
||||||
Light: lightGreen,
|
Light: lipgloss.Color(lightGreen),
|
||||||
}
|
}
|
||||||
theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
|
theme.MarkdownBlockQuoteColor = compat.AdaptiveColor{
|
||||||
Dark: darkYellow,
|
Dark: lipgloss.Color(darkYellow),
|
||||||
Light: lightYellow,
|
Light: lipgloss.Color(lightYellow),
|
||||||
}
|
}
|
||||||
theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
|
theme.MarkdownEmphColor = compat.AdaptiveColor{
|
||||||
Dark: darkYellow,
|
Dark: lipgloss.Color(darkYellow),
|
||||||
Light: lightYellow,
|
Light: lipgloss.Color(lightYellow),
|
||||||
}
|
}
|
||||||
theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
|
theme.MarkdownStrongColor = compat.AdaptiveColor{
|
||||||
Dark: darkAccent,
|
Dark: lipgloss.Color(darkAccent),
|
||||||
Light: lightAccent,
|
Light: lipgloss.Color(lightAccent),
|
||||||
}
|
}
|
||||||
theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
|
theme.MarkdownHorizontalRuleColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep11,
|
Dark: lipgloss.Color(darkStep11),
|
||||||
Light: lightStep11,
|
Light: lipgloss.Color(lightStep11),
|
||||||
}
|
}
|
||||||
theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
|
theme.MarkdownListItemColor = compat.AdaptiveColor{
|
||||||
Dark: darkPrimary,
|
Dark: lipgloss.Color(darkPrimary),
|
||||||
Light: lightPrimary,
|
Light: lipgloss.Color(lightPrimary),
|
||||||
}
|
}
|
||||||
theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
|
theme.MarkdownListEnumerationColor = compat.AdaptiveColor{
|
||||||
Dark: darkCyan,
|
Dark: lipgloss.Color(darkCyan),
|
||||||
Light: lightCyan,
|
Light: lipgloss.Color(lightCyan),
|
||||||
}
|
}
|
||||||
theme.MarkdownImageColor = lipgloss.AdaptiveColor{
|
theme.MarkdownImageColor = compat.AdaptiveColor{
|
||||||
Dark: darkPrimary,
|
Dark: lipgloss.Color(darkPrimary),
|
||||||
Light: lightPrimary,
|
Light: lipgloss.Color(lightPrimary),
|
||||||
}
|
}
|
||||||
theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
|
theme.MarkdownImageTextColor = compat.AdaptiveColor{
|
||||||
Dark: darkCyan,
|
Dark: lipgloss.Color(darkCyan),
|
||||||
Light: lightCyan,
|
Light: lipgloss.Color(lightCyan),
|
||||||
}
|
}
|
||||||
theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
|
theme.MarkdownCodeBlockColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep12,
|
Dark: lipgloss.Color(darkStep12),
|
||||||
Light: lightStep12,
|
Light: lipgloss.Color(lightStep12),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Syntax highlighting colors
|
// Syntax highlighting colors
|
||||||
theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
|
theme.SyntaxCommentColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep11,
|
Dark: lipgloss.Color(darkStep11),
|
||||||
Light: lightStep11,
|
Light: lipgloss.Color(lightStep11),
|
||||||
}
|
}
|
||||||
theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
|
theme.SyntaxKeywordColor = compat.AdaptiveColor{
|
||||||
Dark: darkSecondary,
|
Dark: lipgloss.Color(darkPrimary),
|
||||||
Light: lightSecondary,
|
Light: lipgloss.Color(lightPrimary),
|
||||||
}
|
}
|
||||||
theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
|
theme.SyntaxFunctionColor = compat.AdaptiveColor{
|
||||||
Dark: darkPrimary,
|
Dark: lipgloss.Color(darkPrimary),
|
||||||
Light: lightPrimary,
|
Light: lipgloss.Color(lightPrimary),
|
||||||
}
|
}
|
||||||
theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
|
theme.SyntaxVariableColor = compat.AdaptiveColor{
|
||||||
Dark: darkRed,
|
Dark: lipgloss.Color(darkRed),
|
||||||
Light: lightRed,
|
Light: lipgloss.Color(lightRed),
|
||||||
}
|
}
|
||||||
theme.SyntaxStringColor = lipgloss.AdaptiveColor{
|
theme.SyntaxStringColor = compat.AdaptiveColor{
|
||||||
Dark: darkGreen,
|
Dark: lipgloss.Color(darkGreen),
|
||||||
Light: lightGreen,
|
Light: lipgloss.Color(lightGreen),
|
||||||
}
|
}
|
||||||
theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
|
theme.SyntaxNumberColor = compat.AdaptiveColor{
|
||||||
Dark: darkAccent,
|
Dark: lipgloss.Color(darkAccent),
|
||||||
Light: lightAccent,
|
Light: lipgloss.Color(lightAccent),
|
||||||
}
|
}
|
||||||
theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
|
theme.SyntaxTypeColor = compat.AdaptiveColor{
|
||||||
Dark: darkYellow,
|
Dark: lipgloss.Color(darkYellow),
|
||||||
Light: lightYellow,
|
Light: lipgloss.Color(lightYellow),
|
||||||
}
|
}
|
||||||
theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
|
theme.SyntaxOperatorColor = compat.AdaptiveColor{
|
||||||
Dark: darkCyan,
|
Dark: lipgloss.Color(darkCyan),
|
||||||
Light: lightCyan,
|
Light: lipgloss.Color(lightCyan),
|
||||||
}
|
}
|
||||||
theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
|
theme.SyntaxPunctuationColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep12,
|
Dark: lipgloss.Color(darkStep12),
|
||||||
Light: lightStep12,
|
Light: lipgloss.Color(lightStep12),
|
||||||
}
|
}
|
||||||
|
|
||||||
return theme
|
return theme
|
||||||
|
|||||||
@@ -4,231 +4,232 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"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.
|
// 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.
|
// both light and dark terminal backgrounds.
|
||||||
type Theme interface {
|
type Theme interface {
|
||||||
// Background colors
|
// Background colors
|
||||||
Background() lipgloss.AdaptiveColor // Radix 1
|
Background() compat.AdaptiveColor // Radix 1
|
||||||
BackgroundSubtle() lipgloss.AdaptiveColor // Radix 2
|
BackgroundSubtle() compat.AdaptiveColor // Radix 2
|
||||||
BackgroundElement() lipgloss.AdaptiveColor // Radix 3
|
BackgroundElement() compat.AdaptiveColor // Radix 3
|
||||||
|
|
||||||
// Border colors
|
// Border colors
|
||||||
BorderSubtle() lipgloss.AdaptiveColor // Radix 6
|
BorderSubtle() compat.AdaptiveColor // Radix 6
|
||||||
Border() lipgloss.AdaptiveColor // Radix 7
|
Border() compat.AdaptiveColor // Radix 7
|
||||||
BorderActive() lipgloss.AdaptiveColor // Radix 8
|
BorderActive() compat.AdaptiveColor // Radix 8
|
||||||
|
|
||||||
// Brand colors
|
// Brand colors
|
||||||
Primary() lipgloss.AdaptiveColor // Radix 9
|
Primary() compat.AdaptiveColor // Radix 9
|
||||||
Secondary() lipgloss.AdaptiveColor
|
Secondary() compat.AdaptiveColor
|
||||||
Accent() lipgloss.AdaptiveColor
|
Accent() compat.AdaptiveColor
|
||||||
|
|
||||||
// Text colors
|
// Text colors
|
||||||
TextMuted() lipgloss.AdaptiveColor // Radix 11
|
TextMuted() compat.AdaptiveColor // Radix 11
|
||||||
Text() lipgloss.AdaptiveColor // Radix 12
|
Text() compat.AdaptiveColor // Radix 12
|
||||||
|
|
||||||
// Status colors
|
// Status colors
|
||||||
Error() lipgloss.AdaptiveColor
|
Error() compat.AdaptiveColor
|
||||||
Warning() lipgloss.AdaptiveColor
|
Warning() compat.AdaptiveColor
|
||||||
Success() lipgloss.AdaptiveColor
|
Success() compat.AdaptiveColor
|
||||||
Info() lipgloss.AdaptiveColor
|
Info() compat.AdaptiveColor
|
||||||
|
|
||||||
// Diff view colors
|
// Diff view colors
|
||||||
DiffAdded() lipgloss.AdaptiveColor
|
DiffAdded() compat.AdaptiveColor
|
||||||
DiffRemoved() lipgloss.AdaptiveColor
|
DiffRemoved() compat.AdaptiveColor
|
||||||
DiffContext() lipgloss.AdaptiveColor
|
DiffContext() compat.AdaptiveColor
|
||||||
DiffHunkHeader() lipgloss.AdaptiveColor
|
DiffHunkHeader() compat.AdaptiveColor
|
||||||
DiffHighlightAdded() lipgloss.AdaptiveColor
|
DiffHighlightAdded() compat.AdaptiveColor
|
||||||
DiffHighlightRemoved() lipgloss.AdaptiveColor
|
DiffHighlightRemoved() compat.AdaptiveColor
|
||||||
DiffAddedBg() lipgloss.AdaptiveColor
|
DiffAddedBg() compat.AdaptiveColor
|
||||||
DiffRemovedBg() lipgloss.AdaptiveColor
|
DiffRemovedBg() compat.AdaptiveColor
|
||||||
DiffContextBg() lipgloss.AdaptiveColor
|
DiffContextBg() compat.AdaptiveColor
|
||||||
DiffLineNumber() lipgloss.AdaptiveColor
|
DiffLineNumber() compat.AdaptiveColor
|
||||||
DiffAddedLineNumberBg() lipgloss.AdaptiveColor
|
DiffAddedLineNumberBg() compat.AdaptiveColor
|
||||||
DiffRemovedLineNumberBg() lipgloss.AdaptiveColor
|
DiffRemovedLineNumberBg() compat.AdaptiveColor
|
||||||
|
|
||||||
// Markdown colors
|
// Markdown colors
|
||||||
MarkdownText() lipgloss.AdaptiveColor
|
MarkdownText() compat.AdaptiveColor
|
||||||
MarkdownHeading() lipgloss.AdaptiveColor
|
MarkdownHeading() compat.AdaptiveColor
|
||||||
MarkdownLink() lipgloss.AdaptiveColor
|
MarkdownLink() compat.AdaptiveColor
|
||||||
MarkdownLinkText() lipgloss.AdaptiveColor
|
MarkdownLinkText() compat.AdaptiveColor
|
||||||
MarkdownCode() lipgloss.AdaptiveColor
|
MarkdownCode() compat.AdaptiveColor
|
||||||
MarkdownBlockQuote() lipgloss.AdaptiveColor
|
MarkdownBlockQuote() compat.AdaptiveColor
|
||||||
MarkdownEmph() lipgloss.AdaptiveColor
|
MarkdownEmph() compat.AdaptiveColor
|
||||||
MarkdownStrong() lipgloss.AdaptiveColor
|
MarkdownStrong() compat.AdaptiveColor
|
||||||
MarkdownHorizontalRule() lipgloss.AdaptiveColor
|
MarkdownHorizontalRule() compat.AdaptiveColor
|
||||||
MarkdownListItem() lipgloss.AdaptiveColor
|
MarkdownListItem() compat.AdaptiveColor
|
||||||
MarkdownListEnumeration() lipgloss.AdaptiveColor
|
MarkdownListEnumeration() compat.AdaptiveColor
|
||||||
MarkdownImage() lipgloss.AdaptiveColor
|
MarkdownImage() compat.AdaptiveColor
|
||||||
MarkdownImageText() lipgloss.AdaptiveColor
|
MarkdownImageText() compat.AdaptiveColor
|
||||||
MarkdownCodeBlock() lipgloss.AdaptiveColor
|
MarkdownCodeBlock() compat.AdaptiveColor
|
||||||
|
|
||||||
// Syntax highlighting colors
|
// Syntax highlighting colors
|
||||||
SyntaxComment() lipgloss.AdaptiveColor
|
SyntaxComment() compat.AdaptiveColor
|
||||||
SyntaxKeyword() lipgloss.AdaptiveColor
|
SyntaxKeyword() compat.AdaptiveColor
|
||||||
SyntaxFunction() lipgloss.AdaptiveColor
|
SyntaxFunction() compat.AdaptiveColor
|
||||||
SyntaxVariable() lipgloss.AdaptiveColor
|
SyntaxVariable() compat.AdaptiveColor
|
||||||
SyntaxString() lipgloss.AdaptiveColor
|
SyntaxString() compat.AdaptiveColor
|
||||||
SyntaxNumber() lipgloss.AdaptiveColor
|
SyntaxNumber() compat.AdaptiveColor
|
||||||
SyntaxType() lipgloss.AdaptiveColor
|
SyntaxType() compat.AdaptiveColor
|
||||||
SyntaxOperator() lipgloss.AdaptiveColor
|
SyntaxOperator() compat.AdaptiveColor
|
||||||
SyntaxPunctuation() lipgloss.AdaptiveColor
|
SyntaxPunctuation() compat.AdaptiveColor
|
||||||
}
|
}
|
||||||
|
|
||||||
// BaseTheme provides a default implementation of the Theme interface
|
// BaseTheme provides a default implementation of the Theme interface
|
||||||
// that can be embedded in concrete theme implementations.
|
// that can be embedded in concrete theme implementations.
|
||||||
type BaseTheme struct {
|
type BaseTheme struct {
|
||||||
// Background colors
|
// Background colors
|
||||||
BackgroundColor lipgloss.AdaptiveColor
|
BackgroundColor compat.AdaptiveColor
|
||||||
BackgroundSubtleColor lipgloss.AdaptiveColor
|
BackgroundSubtleColor compat.AdaptiveColor
|
||||||
BackgroundElementColor lipgloss.AdaptiveColor
|
BackgroundElementColor compat.AdaptiveColor
|
||||||
|
|
||||||
// Border colors
|
// Border colors
|
||||||
BorderSubtleColor lipgloss.AdaptiveColor
|
BorderSubtleColor compat.AdaptiveColor
|
||||||
BorderColor lipgloss.AdaptiveColor
|
BorderColor compat.AdaptiveColor
|
||||||
BorderActiveColor lipgloss.AdaptiveColor
|
BorderActiveColor compat.AdaptiveColor
|
||||||
|
|
||||||
// Brand colors
|
// Brand colors
|
||||||
PrimaryColor lipgloss.AdaptiveColor
|
PrimaryColor compat.AdaptiveColor
|
||||||
SecondaryColor lipgloss.AdaptiveColor
|
SecondaryColor compat.AdaptiveColor
|
||||||
AccentColor lipgloss.AdaptiveColor
|
AccentColor compat.AdaptiveColor
|
||||||
|
|
||||||
// Text colors
|
// Text colors
|
||||||
TextMutedColor lipgloss.AdaptiveColor
|
TextMutedColor compat.AdaptiveColor
|
||||||
TextColor lipgloss.AdaptiveColor
|
TextColor compat.AdaptiveColor
|
||||||
|
|
||||||
// Status colors
|
// Status colors
|
||||||
ErrorColor lipgloss.AdaptiveColor
|
ErrorColor compat.AdaptiveColor
|
||||||
WarningColor lipgloss.AdaptiveColor
|
WarningColor compat.AdaptiveColor
|
||||||
SuccessColor lipgloss.AdaptiveColor
|
SuccessColor compat.AdaptiveColor
|
||||||
InfoColor lipgloss.AdaptiveColor
|
InfoColor compat.AdaptiveColor
|
||||||
|
|
||||||
// Diff view colors
|
// Diff view colors
|
||||||
DiffAddedColor lipgloss.AdaptiveColor
|
DiffAddedColor compat.AdaptiveColor
|
||||||
DiffRemovedColor lipgloss.AdaptiveColor
|
DiffRemovedColor compat.AdaptiveColor
|
||||||
DiffContextColor lipgloss.AdaptiveColor
|
DiffContextColor compat.AdaptiveColor
|
||||||
DiffHunkHeaderColor lipgloss.AdaptiveColor
|
DiffHunkHeaderColor compat.AdaptiveColor
|
||||||
DiffHighlightAddedColor lipgloss.AdaptiveColor
|
DiffHighlightAddedColor compat.AdaptiveColor
|
||||||
DiffHighlightRemovedColor lipgloss.AdaptiveColor
|
DiffHighlightRemovedColor compat.AdaptiveColor
|
||||||
DiffAddedBgColor lipgloss.AdaptiveColor
|
DiffAddedBgColor compat.AdaptiveColor
|
||||||
DiffRemovedBgColor lipgloss.AdaptiveColor
|
DiffRemovedBgColor compat.AdaptiveColor
|
||||||
DiffContextBgColor lipgloss.AdaptiveColor
|
DiffContextBgColor compat.AdaptiveColor
|
||||||
DiffLineNumberColor lipgloss.AdaptiveColor
|
DiffLineNumberColor compat.AdaptiveColor
|
||||||
DiffAddedLineNumberBgColor lipgloss.AdaptiveColor
|
DiffAddedLineNumberBgColor compat.AdaptiveColor
|
||||||
DiffRemovedLineNumberBgColor lipgloss.AdaptiveColor
|
DiffRemovedLineNumberBgColor compat.AdaptiveColor
|
||||||
|
|
||||||
// Markdown colors
|
// Markdown colors
|
||||||
MarkdownTextColor lipgloss.AdaptiveColor
|
MarkdownTextColor compat.AdaptiveColor
|
||||||
MarkdownHeadingColor lipgloss.AdaptiveColor
|
MarkdownHeadingColor compat.AdaptiveColor
|
||||||
MarkdownLinkColor lipgloss.AdaptiveColor
|
MarkdownLinkColor compat.AdaptiveColor
|
||||||
MarkdownLinkTextColor lipgloss.AdaptiveColor
|
MarkdownLinkTextColor compat.AdaptiveColor
|
||||||
MarkdownCodeColor lipgloss.AdaptiveColor
|
MarkdownCodeColor compat.AdaptiveColor
|
||||||
MarkdownBlockQuoteColor lipgloss.AdaptiveColor
|
MarkdownBlockQuoteColor compat.AdaptiveColor
|
||||||
MarkdownEmphColor lipgloss.AdaptiveColor
|
MarkdownEmphColor compat.AdaptiveColor
|
||||||
MarkdownStrongColor lipgloss.AdaptiveColor
|
MarkdownStrongColor compat.AdaptiveColor
|
||||||
MarkdownHorizontalRuleColor lipgloss.AdaptiveColor
|
MarkdownHorizontalRuleColor compat.AdaptiveColor
|
||||||
MarkdownListItemColor lipgloss.AdaptiveColor
|
MarkdownListItemColor compat.AdaptiveColor
|
||||||
MarkdownListEnumerationColor lipgloss.AdaptiveColor
|
MarkdownListEnumerationColor compat.AdaptiveColor
|
||||||
MarkdownImageColor lipgloss.AdaptiveColor
|
MarkdownImageColor compat.AdaptiveColor
|
||||||
MarkdownImageTextColor lipgloss.AdaptiveColor
|
MarkdownImageTextColor compat.AdaptiveColor
|
||||||
MarkdownCodeBlockColor lipgloss.AdaptiveColor
|
MarkdownCodeBlockColor compat.AdaptiveColor
|
||||||
|
|
||||||
// Syntax highlighting colors
|
// Syntax highlighting colors
|
||||||
SyntaxCommentColor lipgloss.AdaptiveColor
|
SyntaxCommentColor compat.AdaptiveColor
|
||||||
SyntaxKeywordColor lipgloss.AdaptiveColor
|
SyntaxKeywordColor compat.AdaptiveColor
|
||||||
SyntaxFunctionColor lipgloss.AdaptiveColor
|
SyntaxFunctionColor compat.AdaptiveColor
|
||||||
SyntaxVariableColor lipgloss.AdaptiveColor
|
SyntaxVariableColor compat.AdaptiveColor
|
||||||
SyntaxStringColor lipgloss.AdaptiveColor
|
SyntaxStringColor compat.AdaptiveColor
|
||||||
SyntaxNumberColor lipgloss.AdaptiveColor
|
SyntaxNumberColor compat.AdaptiveColor
|
||||||
SyntaxTypeColor lipgloss.AdaptiveColor
|
SyntaxTypeColor compat.AdaptiveColor
|
||||||
SyntaxOperatorColor lipgloss.AdaptiveColor
|
SyntaxOperatorColor compat.AdaptiveColor
|
||||||
SyntaxPunctuationColor lipgloss.AdaptiveColor
|
SyntaxPunctuationColor compat.AdaptiveColor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implement the Theme interface for BaseTheme
|
// Implement the Theme interface for BaseTheme
|
||||||
func (t *BaseTheme) Primary() lipgloss.AdaptiveColor { return t.PrimaryColor }
|
func (t *BaseTheme) Primary() compat.AdaptiveColor { return t.PrimaryColor }
|
||||||
func (t *BaseTheme) Secondary() lipgloss.AdaptiveColor { return t.SecondaryColor }
|
func (t *BaseTheme) Secondary() compat.AdaptiveColor { return t.SecondaryColor }
|
||||||
func (t *BaseTheme) Accent() lipgloss.AdaptiveColor { return t.AccentColor }
|
func (t *BaseTheme) Accent() compat.AdaptiveColor { return t.AccentColor }
|
||||||
|
|
||||||
func (t *BaseTheme) Error() lipgloss.AdaptiveColor { return t.ErrorColor }
|
func (t *BaseTheme) Error() compat.AdaptiveColor { return t.ErrorColor }
|
||||||
func (t *BaseTheme) Warning() lipgloss.AdaptiveColor { return t.WarningColor }
|
func (t *BaseTheme) Warning() compat.AdaptiveColor { return t.WarningColor }
|
||||||
func (t *BaseTheme) Success() lipgloss.AdaptiveColor { return t.SuccessColor }
|
func (t *BaseTheme) Success() compat.AdaptiveColor { return t.SuccessColor }
|
||||||
func (t *BaseTheme) Info() lipgloss.AdaptiveColor { return t.InfoColor }
|
func (t *BaseTheme) Info() compat.AdaptiveColor { return t.InfoColor }
|
||||||
|
|
||||||
func (t *BaseTheme) Text() lipgloss.AdaptiveColor { return t.TextColor }
|
func (t *BaseTheme) Text() compat.AdaptiveColor { return t.TextColor }
|
||||||
func (t *BaseTheme) TextMuted() lipgloss.AdaptiveColor { return t.TextMutedColor }
|
func (t *BaseTheme) TextMuted() compat.AdaptiveColor { return t.TextMutedColor }
|
||||||
|
|
||||||
func (t *BaseTheme) Background() lipgloss.AdaptiveColor { return t.BackgroundColor }
|
func (t *BaseTheme) Background() compat.AdaptiveColor { return t.BackgroundColor }
|
||||||
func (t *BaseTheme) BackgroundSubtle() lipgloss.AdaptiveColor { return t.BackgroundSubtleColor }
|
func (t *BaseTheme) BackgroundSubtle() compat.AdaptiveColor { return t.BackgroundSubtleColor }
|
||||||
func (t *BaseTheme) BackgroundElement() lipgloss.AdaptiveColor { return t.BackgroundElementColor }
|
func (t *BaseTheme) BackgroundElement() compat.AdaptiveColor { return t.BackgroundElementColor }
|
||||||
|
|
||||||
func (t *BaseTheme) Border() lipgloss.AdaptiveColor { return t.BorderColor }
|
func (t *BaseTheme) Border() compat.AdaptiveColor { return t.BorderColor }
|
||||||
func (t *BaseTheme) BorderActive() lipgloss.AdaptiveColor { return t.BorderActiveColor }
|
func (t *BaseTheme) BorderActive() compat.AdaptiveColor { return t.BorderActiveColor }
|
||||||
func (t *BaseTheme) BorderSubtle() lipgloss.AdaptiveColor { return t.BorderSubtleColor }
|
func (t *BaseTheme) BorderSubtle() compat.AdaptiveColor { return t.BorderSubtleColor }
|
||||||
|
|
||||||
func (t *BaseTheme) DiffAdded() lipgloss.AdaptiveColor { return t.DiffAddedColor }
|
func (t *BaseTheme) DiffAdded() compat.AdaptiveColor { return t.DiffAddedColor }
|
||||||
func (t *BaseTheme) DiffRemoved() lipgloss.AdaptiveColor { return t.DiffRemovedColor }
|
func (t *BaseTheme) DiffRemoved() compat.AdaptiveColor { return t.DiffRemovedColor }
|
||||||
func (t *BaseTheme) DiffContext() lipgloss.AdaptiveColor { return t.DiffContextColor }
|
func (t *BaseTheme) DiffContext() compat.AdaptiveColor { return t.DiffContextColor }
|
||||||
func (t *BaseTheme) DiffHunkHeader() lipgloss.AdaptiveColor { return t.DiffHunkHeaderColor }
|
func (t *BaseTheme) DiffHunkHeader() compat.AdaptiveColor { return t.DiffHunkHeaderColor }
|
||||||
func (t *BaseTheme) DiffHighlightAdded() lipgloss.AdaptiveColor { return t.DiffHighlightAddedColor }
|
func (t *BaseTheme) DiffHighlightAdded() compat.AdaptiveColor { return t.DiffHighlightAddedColor }
|
||||||
func (t *BaseTheme) DiffHighlightRemoved() lipgloss.AdaptiveColor { return t.DiffHighlightRemovedColor }
|
func (t *BaseTheme) DiffHighlightRemoved() compat.AdaptiveColor { return t.DiffHighlightRemovedColor }
|
||||||
func (t *BaseTheme) DiffAddedBg() lipgloss.AdaptiveColor { return t.DiffAddedBgColor }
|
func (t *BaseTheme) DiffAddedBg() compat.AdaptiveColor { return t.DiffAddedBgColor }
|
||||||
func (t *BaseTheme) DiffRemovedBg() lipgloss.AdaptiveColor { return t.DiffRemovedBgColor }
|
func (t *BaseTheme) DiffRemovedBg() compat.AdaptiveColor { return t.DiffRemovedBgColor }
|
||||||
func (t *BaseTheme) DiffContextBg() lipgloss.AdaptiveColor { return t.DiffContextBgColor }
|
func (t *BaseTheme) DiffContextBg() compat.AdaptiveColor { return t.DiffContextBgColor }
|
||||||
func (t *BaseTheme) DiffLineNumber() lipgloss.AdaptiveColor { return t.DiffLineNumberColor }
|
func (t *BaseTheme) DiffLineNumber() compat.AdaptiveColor { return t.DiffLineNumberColor }
|
||||||
func (t *BaseTheme) DiffAddedLineNumberBg() lipgloss.AdaptiveColor {
|
func (t *BaseTheme) DiffAddedLineNumberBg() compat.AdaptiveColor {
|
||||||
return t.DiffAddedLineNumberBgColor
|
return t.DiffAddedLineNumberBgColor
|
||||||
}
|
}
|
||||||
func (t *BaseTheme) DiffRemovedLineNumberBg() lipgloss.AdaptiveColor {
|
func (t *BaseTheme) DiffRemovedLineNumberBg() compat.AdaptiveColor {
|
||||||
return t.DiffRemovedLineNumberBgColor
|
return t.DiffRemovedLineNumberBgColor
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *BaseTheme) MarkdownText() lipgloss.AdaptiveColor { return t.MarkdownTextColor }
|
func (t *BaseTheme) MarkdownText() compat.AdaptiveColor { return t.MarkdownTextColor }
|
||||||
func (t *BaseTheme) MarkdownHeading() lipgloss.AdaptiveColor { return t.MarkdownHeadingColor }
|
func (t *BaseTheme) MarkdownHeading() compat.AdaptiveColor { return t.MarkdownHeadingColor }
|
||||||
func (t *BaseTheme) MarkdownLink() lipgloss.AdaptiveColor { return t.MarkdownLinkColor }
|
func (t *BaseTheme) MarkdownLink() compat.AdaptiveColor { return t.MarkdownLinkColor }
|
||||||
func (t *BaseTheme) MarkdownLinkText() lipgloss.AdaptiveColor { return t.MarkdownLinkTextColor }
|
func (t *BaseTheme) MarkdownLinkText() compat.AdaptiveColor { return t.MarkdownLinkTextColor }
|
||||||
func (t *BaseTheme) MarkdownCode() lipgloss.AdaptiveColor { return t.MarkdownCodeColor }
|
func (t *BaseTheme) MarkdownCode() compat.AdaptiveColor { return t.MarkdownCodeColor }
|
||||||
func (t *BaseTheme) MarkdownBlockQuote() lipgloss.AdaptiveColor { return t.MarkdownBlockQuoteColor }
|
func (t *BaseTheme) MarkdownBlockQuote() compat.AdaptiveColor { return t.MarkdownBlockQuoteColor }
|
||||||
func (t *BaseTheme) MarkdownEmph() lipgloss.AdaptiveColor { return t.MarkdownEmphColor }
|
func (t *BaseTheme) MarkdownEmph() compat.AdaptiveColor { return t.MarkdownEmphColor }
|
||||||
func (t *BaseTheme) MarkdownStrong() lipgloss.AdaptiveColor { return t.MarkdownStrongColor }
|
func (t *BaseTheme) MarkdownStrong() compat.AdaptiveColor { return t.MarkdownStrongColor }
|
||||||
func (t *BaseTheme) MarkdownHorizontalRule() lipgloss.AdaptiveColor {
|
func (t *BaseTheme) MarkdownHorizontalRule() compat.AdaptiveColor {
|
||||||
return t.MarkdownHorizontalRuleColor
|
return t.MarkdownHorizontalRuleColor
|
||||||
}
|
}
|
||||||
func (t *BaseTheme) MarkdownListItem() lipgloss.AdaptiveColor { return t.MarkdownListItemColor }
|
func (t *BaseTheme) MarkdownListItem() compat.AdaptiveColor { return t.MarkdownListItemColor }
|
||||||
func (t *BaseTheme) MarkdownListEnumeration() lipgloss.AdaptiveColor {
|
func (t *BaseTheme) MarkdownListEnumeration() compat.AdaptiveColor {
|
||||||
return t.MarkdownListEnumerationColor
|
return t.MarkdownListEnumerationColor
|
||||||
}
|
}
|
||||||
func (t *BaseTheme) MarkdownImage() lipgloss.AdaptiveColor { return t.MarkdownImageColor }
|
func (t *BaseTheme) MarkdownImage() compat.AdaptiveColor { return t.MarkdownImageColor }
|
||||||
func (t *BaseTheme) MarkdownImageText() lipgloss.AdaptiveColor { return t.MarkdownImageTextColor }
|
func (t *BaseTheme) MarkdownImageText() compat.AdaptiveColor { return t.MarkdownImageTextColor }
|
||||||
func (t *BaseTheme) MarkdownCodeBlock() lipgloss.AdaptiveColor { return t.MarkdownCodeBlockColor }
|
func (t *BaseTheme) MarkdownCodeBlock() compat.AdaptiveColor { return t.MarkdownCodeBlockColor }
|
||||||
|
|
||||||
func (t *BaseTheme) SyntaxComment() lipgloss.AdaptiveColor { return t.SyntaxCommentColor }
|
func (t *BaseTheme) SyntaxComment() compat.AdaptiveColor { return t.SyntaxCommentColor }
|
||||||
func (t *BaseTheme) SyntaxKeyword() lipgloss.AdaptiveColor { return t.SyntaxKeywordColor }
|
func (t *BaseTheme) SyntaxKeyword() compat.AdaptiveColor { return t.SyntaxKeywordColor }
|
||||||
func (t *BaseTheme) SyntaxFunction() lipgloss.AdaptiveColor { return t.SyntaxFunctionColor }
|
func (t *BaseTheme) SyntaxFunction() compat.AdaptiveColor { return t.SyntaxFunctionColor }
|
||||||
func (t *BaseTheme) SyntaxVariable() lipgloss.AdaptiveColor { return t.SyntaxVariableColor }
|
func (t *BaseTheme) SyntaxVariable() compat.AdaptiveColor { return t.SyntaxVariableColor }
|
||||||
func (t *BaseTheme) SyntaxString() lipgloss.AdaptiveColor { return t.SyntaxStringColor }
|
func (t *BaseTheme) SyntaxString() compat.AdaptiveColor { return t.SyntaxStringColor }
|
||||||
func (t *BaseTheme) SyntaxNumber() lipgloss.AdaptiveColor { return t.SyntaxNumberColor }
|
func (t *BaseTheme) SyntaxNumber() compat.AdaptiveColor { return t.SyntaxNumberColor }
|
||||||
func (t *BaseTheme) SyntaxType() lipgloss.AdaptiveColor { return t.SyntaxTypeColor }
|
func (t *BaseTheme) SyntaxType() compat.AdaptiveColor { return t.SyntaxTypeColor }
|
||||||
func (t *BaseTheme) SyntaxOperator() lipgloss.AdaptiveColor { return t.SyntaxOperatorColor }
|
func (t *BaseTheme) SyntaxOperator() compat.AdaptiveColor { return t.SyntaxOperatorColor }
|
||||||
func (t *BaseTheme) SyntaxPunctuation() lipgloss.AdaptiveColor { return t.SyntaxPunctuationColor }
|
func (t *BaseTheme) SyntaxPunctuation() compat.AdaptiveColor { return t.SyntaxPunctuationColor }
|
||||||
|
|
||||||
// ParseAdaptiveColor parses a color value from the config file into a lipgloss.AdaptiveColor.
|
// 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.
|
// 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
|
// Regular expression to validate hex color format
|
||||||
hexColorRegex := regexp.MustCompile(`^#[0-9a-fA-F]{6}$`)
|
hexColorRegex := regexp.MustCompile(`^#[0-9a-fA-F]{6}$`)
|
||||||
|
|
||||||
// Case 1: String value (same color for both dark and light modes)
|
// Case 1: String value (same color for both dark and light modes)
|
||||||
if hexColor, ok := value.(string); ok {
|
if hexColor, ok := value.(string); ok {
|
||||||
if !hexColorRegex.MatchString(hexColor) {
|
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{
|
return compat.AdaptiveColor{
|
||||||
Dark: hexColor,
|
Dark: lipgloss.Color(hexColor),
|
||||||
Light: hexColor,
|
Light: lipgloss.Color(hexColor),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,11 +237,11 @@ func ParseAdaptiveColor(value any) (lipgloss.AdaptiveColor, error) {
|
|||||||
if numericVal, ok := value.(float64); ok {
|
if numericVal, ok := value.(float64); ok {
|
||||||
intVal := int(numericVal)
|
intVal := int(numericVal)
|
||||||
if intVal < 0 || intVal > 255 {
|
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{
|
return compat.AdaptiveColor{
|
||||||
Dark: fmt.Sprintf("%d", intVal),
|
Dark: lipgloss.Color(fmt.Sprintf("%d", intVal)),
|
||||||
Light: fmt.Sprintf("%d", intVal),
|
Light: lipgloss.Color(fmt.Sprintf("%d", intVal)),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +251,7 @@ func ParseAdaptiveColor(value any) (lipgloss.AdaptiveColor, error) {
|
|||||||
lightVal, lightOk := colorMap["light"]
|
lightVal, lightOk := colorMap["light"]
|
||||||
|
|
||||||
if !darkOk || !lightOk {
|
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)
|
darkHex, darkIsString := darkVal.(string)
|
||||||
@@ -261,27 +262,27 @@ func ParseAdaptiveColor(value any) (lipgloss.AdaptiveColor, error) {
|
|||||||
lightVal, lightIsNumber := lightVal.(float64)
|
lightVal, lightIsNumber := lightVal.(float64)
|
||||||
|
|
||||||
if !darkIsNumber || !lightIsNumber {
|
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)
|
darkInt := int(darkVal)
|
||||||
lightInt := int(lightVal)
|
lightInt := int(lightVal)
|
||||||
|
|
||||||
return lipgloss.AdaptiveColor{
|
return compat.AdaptiveColor{
|
||||||
Dark: fmt.Sprintf("%d", darkInt),
|
Dark: lipgloss.Color(fmt.Sprintf("%d", darkInt)),
|
||||||
Light: fmt.Sprintf("%d", lightInt),
|
Light: lipgloss.Color(fmt.Sprintf("%d", lightInt)),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !hexColorRegex.MatchString(darkHex) || !hexColorRegex.MatchString(lightHex) {
|
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{
|
return compat.AdaptiveColor{
|
||||||
Dark: darkHex,
|
Dark: lipgloss.Color(darkHex),
|
||||||
Light: lightHex,
|
Light: lipgloss.Color(lightHex),
|
||||||
}, nil
|
}, 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")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package theme
|
package theme
|
||||||
|
|
||||||
import (
|
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.
|
// TokyoNightTheme implements the Theme interface with Tokyo Night colors.
|
||||||
@@ -70,219 +71,219 @@ func NewTokyoNightTheme() *TokyoNightTheme {
|
|||||||
theme := &TokyoNightTheme{}
|
theme := &TokyoNightTheme{}
|
||||||
|
|
||||||
// Base colors
|
// Base colors
|
||||||
theme.PrimaryColor = lipgloss.AdaptiveColor{
|
theme.PrimaryColor = compat.AdaptiveColor{
|
||||||
Dark: darkBlue,
|
Dark: lipgloss.Color(darkBlue),
|
||||||
Light: lightBlue,
|
Light: lipgloss.Color(lightBlue),
|
||||||
}
|
}
|
||||||
theme.SecondaryColor = lipgloss.AdaptiveColor{
|
theme.SecondaryColor = compat.AdaptiveColor{
|
||||||
Dark: darkPurple,
|
Dark: lipgloss.Color(darkPurple),
|
||||||
Light: lightPurple,
|
Light: lipgloss.Color(lightPurple),
|
||||||
}
|
}
|
||||||
theme.AccentColor = lipgloss.AdaptiveColor{
|
theme.AccentColor = compat.AdaptiveColor{
|
||||||
Dark: darkOrange,
|
Dark: lipgloss.Color(darkOrange),
|
||||||
Light: lightOrange,
|
Light: lipgloss.Color(lightOrange),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status colors
|
// Status colors
|
||||||
theme.ErrorColor = lipgloss.AdaptiveColor{
|
theme.ErrorColor = compat.AdaptiveColor{
|
||||||
Dark: darkRed,
|
Dark: lipgloss.Color(darkRed),
|
||||||
Light: lightRed,
|
Light: lipgloss.Color(lightRed),
|
||||||
}
|
}
|
||||||
theme.WarningColor = lipgloss.AdaptiveColor{
|
theme.WarningColor = compat.AdaptiveColor{
|
||||||
Dark: darkOrange,
|
Dark: lipgloss.Color(darkOrange),
|
||||||
Light: lightOrange,
|
Light: lipgloss.Color(lightOrange),
|
||||||
}
|
}
|
||||||
theme.SuccessColor = lipgloss.AdaptiveColor{
|
theme.SuccessColor = compat.AdaptiveColor{
|
||||||
Dark: darkGreen,
|
Dark: lipgloss.Color(darkGreen),
|
||||||
Light: lightGreen,
|
Light: lipgloss.Color(lightGreen),
|
||||||
}
|
}
|
||||||
theme.InfoColor = lipgloss.AdaptiveColor{
|
theme.InfoColor = compat.AdaptiveColor{
|
||||||
Dark: darkBlue,
|
Dark: lipgloss.Color(darkBlue),
|
||||||
Light: lightBlue,
|
Light: lipgloss.Color(lightBlue),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text colors
|
// Text colors
|
||||||
theme.TextColor = lipgloss.AdaptiveColor{
|
theme.TextColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep12,
|
Dark: lipgloss.Color(darkStep12),
|
||||||
Light: lightStep12,
|
Light: lipgloss.Color(lightStep12),
|
||||||
}
|
}
|
||||||
theme.TextMutedColor = lipgloss.AdaptiveColor{
|
theme.TextMutedColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep11,
|
Dark: lipgloss.Color(darkStep11),
|
||||||
Light: lightStep11,
|
Light: lipgloss.Color(lightStep11),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Background colors
|
// Background colors
|
||||||
theme.BackgroundColor = lipgloss.AdaptiveColor{
|
theme.BackgroundColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep1,
|
Dark: lipgloss.Color(darkStep1),
|
||||||
Light: lightStep1,
|
Light: lipgloss.Color(lightStep1),
|
||||||
}
|
}
|
||||||
theme.BackgroundSubtleColor = lipgloss.AdaptiveColor{
|
theme.BackgroundSubtleColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep2,
|
Dark: lipgloss.Color(darkStep2),
|
||||||
Light: lightStep2,
|
Light: lipgloss.Color(lightStep2),
|
||||||
}
|
}
|
||||||
theme.BackgroundElementColor = lipgloss.AdaptiveColor{
|
theme.BackgroundElementColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep3,
|
Dark: lipgloss.Color(darkStep3),
|
||||||
Light: lightStep3,
|
Light: lipgloss.Color(lightStep3),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Border colors
|
// Border colors
|
||||||
theme.BorderColor = lipgloss.AdaptiveColor{
|
theme.BorderColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep7,
|
Dark: lipgloss.Color(darkStep7),
|
||||||
Light: lightStep7,
|
Light: lipgloss.Color(lightStep7),
|
||||||
}
|
}
|
||||||
theme.BorderActiveColor = lipgloss.AdaptiveColor{
|
theme.BorderActiveColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep8,
|
Dark: lipgloss.Color(darkStep8),
|
||||||
Light: lightStep8,
|
Light: lipgloss.Color(lightStep8),
|
||||||
}
|
}
|
||||||
theme.BorderSubtleColor = lipgloss.AdaptiveColor{
|
theme.BorderSubtleColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep6,
|
Dark: lipgloss.Color(darkStep6),
|
||||||
Light: lightStep6,
|
Light: lipgloss.Color(lightStep6),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diff view colors
|
// Diff view colors
|
||||||
theme.DiffAddedColor = lipgloss.AdaptiveColor{
|
theme.DiffAddedColor = compat.AdaptiveColor{
|
||||||
Dark: "#4fd6be", // teal from palette
|
Dark: lipgloss.Color("#4fd6be"), // teal from palette
|
||||||
Light: "#1e725c",
|
Light: lipgloss.Color("#1e725c"),
|
||||||
}
|
}
|
||||||
theme.DiffRemovedColor = lipgloss.AdaptiveColor{
|
theme.DiffRemovedColor = compat.AdaptiveColor{
|
||||||
Dark: "#c53b53", // red1 from palette
|
Dark: lipgloss.Color("#c53b53"), // red1 from palette
|
||||||
Light: "#c53b53",
|
Light: lipgloss.Color("#c53b53"),
|
||||||
}
|
}
|
||||||
theme.DiffContextColor = lipgloss.AdaptiveColor{
|
theme.DiffContextColor = compat.AdaptiveColor{
|
||||||
Dark: "#828bb8", // fg_dark from palette
|
Dark: lipgloss.Color("#828bb8"), // fg_dark from palette
|
||||||
Light: "#7086b5",
|
Light: lipgloss.Color("#7086b5"),
|
||||||
}
|
}
|
||||||
theme.DiffHunkHeaderColor = lipgloss.AdaptiveColor{
|
theme.DiffHunkHeaderColor = compat.AdaptiveColor{
|
||||||
Dark: "#828bb8", // fg_dark from palette
|
Dark: lipgloss.Color("#828bb8"), // fg_dark from palette
|
||||||
Light: "#7086b5",
|
Light: lipgloss.Color("#7086b5"),
|
||||||
}
|
}
|
||||||
theme.DiffHighlightAddedColor = lipgloss.AdaptiveColor{
|
theme.DiffHighlightAddedColor = compat.AdaptiveColor{
|
||||||
Dark: "#b8db87", // git.add from palette
|
Dark: lipgloss.Color("#b8db87"), // git.add from palette
|
||||||
Light: "#4db380",
|
Light: lipgloss.Color("#4db380"),
|
||||||
}
|
}
|
||||||
theme.DiffHighlightRemovedColor = lipgloss.AdaptiveColor{
|
theme.DiffHighlightRemovedColor = compat.AdaptiveColor{
|
||||||
Dark: "#e26a75", // git.delete from palette
|
Dark: lipgloss.Color("#e26a75"), // git.delete from palette
|
||||||
Light: "#f52a65",
|
Light: lipgloss.Color("#f52a65"),
|
||||||
}
|
}
|
||||||
theme.DiffAddedBgColor = lipgloss.AdaptiveColor{
|
theme.DiffAddedBgColor = compat.AdaptiveColor{
|
||||||
Dark: "#20303b",
|
Dark: lipgloss.Color("#20303b"),
|
||||||
Light: "#d5e5d5",
|
Light: lipgloss.Color("#d5e5d5"),
|
||||||
}
|
}
|
||||||
theme.DiffRemovedBgColor = lipgloss.AdaptiveColor{
|
theme.DiffRemovedBgColor = compat.AdaptiveColor{
|
||||||
Dark: "#37222c",
|
Dark: lipgloss.Color("#37222c"),
|
||||||
Light: "#f7d8db",
|
Light: lipgloss.Color("#f7d8db"),
|
||||||
}
|
}
|
||||||
theme.DiffContextBgColor = lipgloss.AdaptiveColor{
|
theme.DiffContextBgColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep2,
|
Dark: lipgloss.Color(darkStep2),
|
||||||
Light: lightStep2,
|
Light: lipgloss.Color(lightStep2),
|
||||||
}
|
}
|
||||||
theme.DiffLineNumberColor = lipgloss.AdaptiveColor{
|
theme.DiffLineNumberColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep3, // dark3 from palette
|
Dark: lipgloss.Color(darkStep3), // dark3 from palette
|
||||||
Light: lightStep3,
|
Light: lipgloss.Color(lightStep3),
|
||||||
}
|
}
|
||||||
theme.DiffAddedLineNumberBgColor = lipgloss.AdaptiveColor{
|
theme.DiffAddedLineNumberBgColor = compat.AdaptiveColor{
|
||||||
Dark: "#1b2b34",
|
Dark: lipgloss.Color("#1b2b34"),
|
||||||
Light: "#c5d5c5",
|
Light: lipgloss.Color("#c5d5c5"),
|
||||||
}
|
}
|
||||||
theme.DiffRemovedLineNumberBgColor = lipgloss.AdaptiveColor{
|
theme.DiffRemovedLineNumberBgColor = compat.AdaptiveColor{
|
||||||
Dark: "#2d1f26",
|
Dark: lipgloss.Color("#2d1f26"),
|
||||||
Light: "#e7c8cb",
|
Light: lipgloss.Color("#e7c8cb"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Markdown colors
|
// Markdown colors
|
||||||
theme.MarkdownTextColor = lipgloss.AdaptiveColor{
|
theme.MarkdownTextColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep12,
|
Dark: lipgloss.Color(darkStep12),
|
||||||
Light: lightStep12,
|
Light: lipgloss.Color(lightStep12),
|
||||||
}
|
}
|
||||||
theme.MarkdownHeadingColor = lipgloss.AdaptiveColor{
|
theme.MarkdownHeadingColor = compat.AdaptiveColor{
|
||||||
Dark: darkPurple,
|
Dark: lipgloss.Color(darkPurple),
|
||||||
Light: lightPurple,
|
Light: lipgloss.Color(lightPurple),
|
||||||
}
|
}
|
||||||
theme.MarkdownLinkColor = lipgloss.AdaptiveColor{
|
theme.MarkdownLinkColor = compat.AdaptiveColor{
|
||||||
Dark: darkBlue,
|
Dark: lipgloss.Color(darkBlue),
|
||||||
Light: lightBlue,
|
Light: lipgloss.Color(lightBlue),
|
||||||
}
|
}
|
||||||
theme.MarkdownLinkTextColor = lipgloss.AdaptiveColor{
|
theme.MarkdownLinkTextColor = compat.AdaptiveColor{
|
||||||
Dark: darkCyan,
|
Dark: lipgloss.Color(darkCyan),
|
||||||
Light: lightCyan,
|
Light: lipgloss.Color(lightCyan),
|
||||||
}
|
}
|
||||||
theme.MarkdownCodeColor = lipgloss.AdaptiveColor{
|
theme.MarkdownCodeColor = compat.AdaptiveColor{
|
||||||
Dark: darkGreen,
|
Dark: lipgloss.Color(darkGreen),
|
||||||
Light: lightGreen,
|
Light: lipgloss.Color(lightGreen),
|
||||||
}
|
}
|
||||||
theme.MarkdownBlockQuoteColor = lipgloss.AdaptiveColor{
|
theme.MarkdownBlockQuoteColor = compat.AdaptiveColor{
|
||||||
Dark: darkYellow,
|
Dark: lipgloss.Color(darkYellow),
|
||||||
Light: lightYellow,
|
Light: lipgloss.Color(lightYellow),
|
||||||
}
|
}
|
||||||
theme.MarkdownEmphColor = lipgloss.AdaptiveColor{
|
theme.MarkdownEmphColor = compat.AdaptiveColor{
|
||||||
Dark: darkYellow,
|
Dark: lipgloss.Color(darkYellow),
|
||||||
Light: lightYellow,
|
Light: lipgloss.Color(lightYellow),
|
||||||
}
|
}
|
||||||
theme.MarkdownStrongColor = lipgloss.AdaptiveColor{
|
theme.MarkdownStrongColor = compat.AdaptiveColor{
|
||||||
Dark: darkOrange,
|
Dark: lipgloss.Color(darkOrange),
|
||||||
Light: lightOrange,
|
Light: lipgloss.Color(lightOrange),
|
||||||
}
|
}
|
||||||
theme.MarkdownHorizontalRuleColor = lipgloss.AdaptiveColor{
|
theme.MarkdownHorizontalRuleColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep11,
|
Dark: lipgloss.Color(darkStep11),
|
||||||
Light: lightStep11,
|
Light: lipgloss.Color(lightStep11),
|
||||||
}
|
}
|
||||||
theme.MarkdownListItemColor = lipgloss.AdaptiveColor{
|
theme.MarkdownListItemColor = compat.AdaptiveColor{
|
||||||
Dark: darkBlue,
|
Dark: lipgloss.Color(darkBlue),
|
||||||
Light: lightBlue,
|
Light: lipgloss.Color(lightBlue),
|
||||||
}
|
}
|
||||||
theme.MarkdownListEnumerationColor = lipgloss.AdaptiveColor{
|
theme.MarkdownListEnumerationColor = compat.AdaptiveColor{
|
||||||
Dark: darkCyan,
|
Dark: lipgloss.Color(darkCyan),
|
||||||
Light: lightCyan,
|
Light: lipgloss.Color(lightCyan),
|
||||||
}
|
}
|
||||||
theme.MarkdownImageColor = lipgloss.AdaptiveColor{
|
theme.MarkdownImageColor = compat.AdaptiveColor{
|
||||||
Dark: darkBlue,
|
Dark: lipgloss.Color(darkBlue),
|
||||||
Light: lightBlue,
|
Light: lipgloss.Color(lightBlue),
|
||||||
}
|
}
|
||||||
theme.MarkdownImageTextColor = lipgloss.AdaptiveColor{
|
theme.MarkdownImageTextColor = compat.AdaptiveColor{
|
||||||
Dark: darkCyan,
|
Dark: lipgloss.Color(darkCyan),
|
||||||
Light: lightCyan,
|
Light: lipgloss.Color(lightCyan),
|
||||||
}
|
}
|
||||||
theme.MarkdownCodeBlockColor = lipgloss.AdaptiveColor{
|
theme.MarkdownCodeBlockColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep12,
|
Dark: lipgloss.Color(darkStep12),
|
||||||
Light: lightStep12,
|
Light: lipgloss.Color(lightStep12),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Syntax highlighting colors
|
// Syntax highlighting colors
|
||||||
theme.SyntaxCommentColor = lipgloss.AdaptiveColor{
|
theme.SyntaxCommentColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep11,
|
Dark: lipgloss.Color(darkStep11),
|
||||||
Light: lightStep11,
|
Light: lipgloss.Color(lightStep11),
|
||||||
}
|
}
|
||||||
theme.SyntaxKeywordColor = lipgloss.AdaptiveColor{
|
theme.SyntaxKeywordColor = compat.AdaptiveColor{
|
||||||
Dark: darkPurple,
|
Dark: lipgloss.Color(darkPurple),
|
||||||
Light: lightPurple,
|
Light: lipgloss.Color(lightPurple),
|
||||||
}
|
}
|
||||||
theme.SyntaxFunctionColor = lipgloss.AdaptiveColor{
|
theme.SyntaxFunctionColor = compat.AdaptiveColor{
|
||||||
Dark: darkBlue,
|
Dark: lipgloss.Color(darkBlue),
|
||||||
Light: lightBlue,
|
Light: lipgloss.Color(lightBlue),
|
||||||
}
|
}
|
||||||
theme.SyntaxVariableColor = lipgloss.AdaptiveColor{
|
theme.SyntaxVariableColor = compat.AdaptiveColor{
|
||||||
Dark: darkRed,
|
Dark: lipgloss.Color(darkRed),
|
||||||
Light: lightRed,
|
Light: lipgloss.Color(lightRed),
|
||||||
}
|
}
|
||||||
theme.SyntaxStringColor = lipgloss.AdaptiveColor{
|
theme.SyntaxStringColor = compat.AdaptiveColor{
|
||||||
Dark: darkGreen,
|
Dark: lipgloss.Color(darkGreen),
|
||||||
Light: lightGreen,
|
Light: lipgloss.Color(lightGreen),
|
||||||
}
|
}
|
||||||
theme.SyntaxNumberColor = lipgloss.AdaptiveColor{
|
theme.SyntaxNumberColor = compat.AdaptiveColor{
|
||||||
Dark: darkOrange,
|
Dark: lipgloss.Color(darkOrange),
|
||||||
Light: lightOrange,
|
Light: lipgloss.Color(lightOrange),
|
||||||
}
|
}
|
||||||
theme.SyntaxTypeColor = lipgloss.AdaptiveColor{
|
theme.SyntaxTypeColor = compat.AdaptiveColor{
|
||||||
Dark: darkYellow,
|
Dark: lipgloss.Color(darkYellow),
|
||||||
Light: lightYellow,
|
Light: lipgloss.Color(lightYellow),
|
||||||
}
|
}
|
||||||
theme.SyntaxOperatorColor = lipgloss.AdaptiveColor{
|
theme.SyntaxOperatorColor = compat.AdaptiveColor{
|
||||||
Dark: darkCyan,
|
Dark: lipgloss.Color(darkCyan),
|
||||||
Light: lightCyan,
|
Light: lipgloss.Color(lightCyan),
|
||||||
}
|
}
|
||||||
theme.SyntaxPunctuationColor = lipgloss.AdaptiveColor{
|
theme.SyntaxPunctuationColor = compat.AdaptiveColor{
|
||||||
Dark: darkStep12,
|
Dark: lipgloss.Color(darkStep12),
|
||||||
Light: lightStep12,
|
Light: lipgloss.Color(lightStep12),
|
||||||
}
|
}
|
||||||
|
|
||||||
return theme
|
return theme
|
||||||
|
|||||||
@@ -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())
|
|
||||||
}
|
|
||||||
@@ -5,11 +5,11 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/cursor"
|
"github.com/charmbracelet/bubbles/v2/cursor"
|
||||||
"github.com/charmbracelet/bubbles/key"
|
"github.com/charmbracelet/bubbles/v2/key"
|
||||||
"github.com/charmbracelet/bubbles/spinner"
|
"github.com/charmbracelet/bubbles/v2/spinner"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss/v2"
|
||||||
|
|
||||||
"github.com/sst/opencode/internal/app"
|
"github.com/sst/opencode/internal/app"
|
||||||
"github.com/sst/opencode/internal/components/core"
|
"github.com/sst/opencode/internal/components/core"
|
||||||
@@ -18,6 +18,8 @@ import (
|
|||||||
"github.com/sst/opencode/internal/page"
|
"github.com/sst/opencode/internal/page"
|
||||||
"github.com/sst/opencode/internal/state"
|
"github.com/sst/opencode/internal/state"
|
||||||
"github.com/sst/opencode/internal/status"
|
"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/internal/util"
|
||||||
"github.com/sst/opencode/pkg/client"
|
"github.com/sst/opencode/pkg/client"
|
||||||
)
|
)
|
||||||
@@ -90,16 +92,16 @@ type appModel struct {
|
|||||||
width, height int
|
width, height int
|
||||||
currentPage page.PageID
|
currentPage page.PageID
|
||||||
previousPage page.PageID
|
previousPage page.PageID
|
||||||
pages map[page.PageID]tea.Model
|
pages map[page.PageID]layout.ModelWithView
|
||||||
loadedPages map[page.PageID]bool
|
loadedPages map[page.PageID]bool
|
||||||
status core.StatusCmp
|
status core.StatusComponent
|
||||||
app *app.App
|
app *app.App
|
||||||
|
|
||||||
showPermissions bool
|
showPermissions bool
|
||||||
permissions dialog.PermissionDialogCmp
|
permissions dialog.PermissionDialogComponent
|
||||||
|
|
||||||
showHelp bool
|
showHelp bool
|
||||||
help dialog.HelpCmp
|
help dialog.HelpComponent
|
||||||
|
|
||||||
showQuit bool
|
showQuit bool
|
||||||
quit dialog.QuitDialog
|
quit dialog.QuitDialog
|
||||||
@@ -118,7 +120,7 @@ type appModel struct {
|
|||||||
initDialog dialog.InitDialogCmp
|
initDialog dialog.InitDialogCmp
|
||||||
|
|
||||||
showFilepicker bool
|
showFilepicker bool
|
||||||
filepicker dialog.FilepickerCmp
|
filepicker dialog.FilepickerComponent
|
||||||
|
|
||||||
showThemeDialog bool
|
showThemeDialog bool
|
||||||
themeDialog dialog.ThemeDialog
|
themeDialog dialog.ThemeDialog
|
||||||
@@ -131,7 +133,12 @@ type appModel struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a appModel) Init() tea.Cmd {
|
func (a appModel) Init() tea.Cmd {
|
||||||
|
t := theme.CurrentTheme()
|
||||||
var cmds []tea.Cmd
|
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()
|
cmd := a.pages[a.currentPage].Init()
|
||||||
a.loadedPages[a.currentPage] = true
|
a.loadedPages[a.currentPage] = true
|
||||||
cmds = append(cmds, cmd)
|
cmds = append(cmds, cmd)
|
||||||
@@ -170,13 +177,14 @@ func (a appModel) updateAllPages(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
var cmd tea.Cmd
|
var cmd tea.Cmd
|
||||||
|
|
||||||
for id := range a.pages {
|
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)
|
cmds = append(cmds, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
s, cmd := a.status.Update(msg)
|
s, cmd := a.status.Update(msg)
|
||||||
cmds = append(cmds, cmd)
|
cmds = append(cmds, cmd)
|
||||||
a.status = s.(core.StatusCmp)
|
a.status = s.(core.StatusComponent)
|
||||||
|
|
||||||
return a, tea.Batch(cmds...)
|
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 cmds []tea.Cmd
|
||||||
var cmd tea.Cmd
|
var cmd tea.Cmd
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
|
case tea.BackgroundColorMsg:
|
||||||
|
styles.Terminal = &styles.TerminalInfo{
|
||||||
|
BackgroundIsDark: msg.IsDark(),
|
||||||
|
}
|
||||||
case cursor.BlinkMsg:
|
case cursor.BlinkMsg:
|
||||||
return a.updateAllPages(msg)
|
return a.updateAllPages(msg)
|
||||||
case spinner.TickMsg:
|
case spinner.TickMsg:
|
||||||
@@ -234,16 +246,17 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s, _ := a.status.Update(msg)
|
s, _ := a.status.Update(msg)
|
||||||
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)
|
cmds = append(cmds, cmd)
|
||||||
|
|
||||||
prm, permCmd := a.permissions.Update(msg)
|
prm, permCmd := a.permissions.Update(msg)
|
||||||
a.permissions = prm.(dialog.PermissionDialogCmp)
|
a.permissions = prm.(dialog.PermissionDialogComponent)
|
||||||
cmds = append(cmds, permCmd)
|
cmds = append(cmds, permCmd)
|
||||||
|
|
||||||
help, helpCmd := a.help.Update(msg)
|
help, helpCmd := a.help.Update(msg)
|
||||||
a.help = help.(dialog.HelpCmp)
|
a.help = help.(dialog.HelpComponent)
|
||||||
cmds = append(cmds, helpCmd)
|
cmds = append(cmds, helpCmd)
|
||||||
|
|
||||||
session, sessionCmd := a.sessionDialog.Update(msg)
|
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)
|
cmds = append(cmds, commandCmd)
|
||||||
|
|
||||||
filepicker, filepickerCmd := a.filepicker.Update(msg)
|
filepicker, filepickerCmd := a.filepicker.Update(msg)
|
||||||
a.filepicker = filepicker.(dialog.FilepickerCmp)
|
a.filepicker = filepicker.(dialog.FilepickerComponent)
|
||||||
cmds = append(cmds, filepickerCmd)
|
cmds = append(cmds, filepickerCmd)
|
||||||
|
|
||||||
a.initDialog.SetSize(msg.Width, msg.Height)
|
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.Config.Theme = msg.ThemeName
|
||||||
a.app.SaveConfig()
|
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
|
a.showThemeDialog = false
|
||||||
status.Info("Theme changed to: " + msg.ThemeName)
|
status.Info("Theme changed to: " + msg.ThemeName)
|
||||||
return a, cmd
|
return a, tea.Batch(cmds...)
|
||||||
|
|
||||||
case dialog.ShowInitDialogMsg:
|
case dialog.ShowInitDialogMsg:
|
||||||
a.showInitDialog = msg.Show
|
a.showInitDialog = msg.Show
|
||||||
@@ -597,13 +619,13 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
f, filepickerCmd := a.filepicker.Update(msg)
|
f, filepickerCmd := a.filepicker.Update(msg)
|
||||||
a.filepicker = f.(dialog.FilepickerCmp)
|
a.filepicker = f.(dialog.FilepickerComponent)
|
||||||
cmds = append(cmds, filepickerCmd)
|
cmds = append(cmds, filepickerCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.showFilepicker {
|
if a.showFilepicker {
|
||||||
f, filepickerCmd := a.filepicker.Update(msg)
|
f, filepickerCmd := a.filepicker.Update(msg)
|
||||||
a.filepicker = f.(dialog.FilepickerCmp)
|
a.filepicker = f.(dialog.FilepickerComponent)
|
||||||
cmds = append(cmds, filepickerCmd)
|
cmds = append(cmds, filepickerCmd)
|
||||||
// Only block key messages send all other messages down
|
// Only block key messages send all other messages down
|
||||||
if _, ok := msg.(tea.KeyMsg); ok {
|
if _, ok := msg.(tea.KeyMsg); ok {
|
||||||
@@ -623,7 +645,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||||||
|
|
||||||
if a.showPermissions {
|
if a.showPermissions {
|
||||||
d, permissionsCmd := a.permissions.Update(msg)
|
d, permissionsCmd := a.permissions.Update(msg)
|
||||||
a.permissions = d.(dialog.PermissionDialogCmp)
|
a.permissions = d.(dialog.PermissionDialogComponent)
|
||||||
cmds = append(cmds, permissionsCmd)
|
cmds = append(cmds, permissionsCmd)
|
||||||
// Only block key messages send all other messages down
|
// Only block key messages send all other messages down
|
||||||
if _, ok := msg.(tea.KeyMsg); ok {
|
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)
|
s, cmd := a.status.Update(msg)
|
||||||
cmds = append(cmds, cmd)
|
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)
|
cmds = append(cmds, cmd)
|
||||||
return a, tea.Batch(cmds...)
|
return a, tea.Batch(cmds...)
|
||||||
}
|
}
|
||||||
@@ -930,7 +953,7 @@ func NewModel(app *app.App) tea.Model {
|
|||||||
toolsDialog: dialog.NewToolsDialogCmp(),
|
toolsDialog: dialog.NewToolsDialogCmp(),
|
||||||
app: app,
|
app: app,
|
||||||
commands: []dialog.Command{},
|
commands: []dialog.Command{},
|
||||||
pages: map[page.PageID]tea.Model{
|
pages: map[page.PageID]layout.ModelWithView{
|
||||||
page.ChatPage: page.NewChatPage(app),
|
page.ChatPage: page.NewChatPage(app),
|
||||||
},
|
},
|
||||||
filepicker: dialog.NewFilepickerCmp(app),
|
filepicker: dialog.NewFilepickerCmp(app),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CmdHandler(msg tea.Msg) tea.Cmd {
|
func CmdHandler(msg tea.Msg) tea.Cmd {
|
||||||
|
|||||||
Reference in New Issue
Block a user