Skip to content

Commit

Permalink
chore(progress)!: migrate progress to lipgloss
Browse files Browse the repository at this point in the history
This removes the dependency on termenv and replaces it with lipgloss. This
change also removes the WithColorProfile option, as it is no longer needed.
The new API uses `color.Color` types for colors, which are more flexible and
allow for more advanced color manipulation.
  • Loading branch information
aymanbagabas committed Nov 21, 2024
1 parent bd415b4 commit 04626c8
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 48 deletions.
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ require (
github.com/dustin/go-humanize v1.0.1
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/mattn/go-runewidth v0.0.16
github.com/muesli/termenv v0.15.2
github.com/rivo/uniseg v0.4.7
github.com/sahilm/fuzzy v0.1.1
)

require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/aymanbagabas/go-udiff v0.2.0 // indirect
github.com/charmbracelet/colorprofile v0.1.8 // indirect
github.com/charmbracelet/x/cellbuf v0.0.6 // indirect
Expand All @@ -28,7 +26,6 @@ require (
github.com/charmbracelet/x/wcwidth v0.0.0-20241113152101-0af7d04e9f32 // indirect
github.com/charmbracelet/x/windows v0.2.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/sync v0.9.0 // indirect
Expand Down
7 changes: 0 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/charmbracelet/bubbletea/v2 v2.0.0-alpha.2.0.20241121171714-fbd5423ea935 h1:S+hhEwWnJxDeZMtHqIHgGVilNWsez3xmFOpwSc9GbcE=
Expand Down Expand Up @@ -34,14 +32,10 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
Expand All @@ -52,7 +46,6 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJu
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
Expand Down
45 changes: 14 additions & 31 deletions progress/progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package progress

import (
"fmt"
"image/color"
"math"
"strings"
"sync/atomic"
Expand All @@ -12,7 +13,6 @@ import (
"github.com/charmbracelet/lipgloss/v2"
"github.com/charmbracelet/x/ansi"
"github.com/lucasb-eyer/go-colorful"
"github.com/muesli/termenv"
)

// Internal ID management. Used during animating to assure that frame messages
Expand Down Expand Up @@ -65,7 +65,7 @@ func WithScaledGradient(colorA, colorB string) Option {
}

// WithSolidFill sets the progress to use a solid fill with the given color.
func WithSolidFill(color string) Option {
func WithSolidFill(color color.Color) Option {
return func(m *Model) {
m.FullColor = color
m.useRamp = false
Expand Down Expand Up @@ -108,13 +108,6 @@ func WithSpringOptions(frequency, damping float64) Option {
}
}

// WithColorProfile sets the color profile to use for the progress bar.
func WithColorProfile(p termenv.Profile) Option {
return func(m *Model) {
m.colorProfile = p
}
}

// FrameMsg indicates that an animation step should occur.
type FrameMsg struct {
id int
Expand All @@ -135,11 +128,11 @@ type Model struct {

// "Filled" sections of the progress bar.
Full rune
FullColor string
FullColor color.Color

// "Empty" sections of the progress bar.
Empty rune
EmptyColor string
EmptyColor color.Color

// Settings for rendering the numeric percentage.
ShowPercentage bool
Expand All @@ -162,9 +155,6 @@ type Model struct {
// of the progress bar. When false, the width of the gradient will be set
// to the full width of the progress bar.
scaleRamp bool

// Color profile for the progress bar.
colorProfile termenv.Profile
}

// New returns a model with default values.
Expand All @@ -173,12 +163,11 @@ func New(opts ...Option) Model {
id: nextID(),
width: defaultWidth,
Full: '█',
FullColor: "#7571F9",
FullColor: lipgloss.Color("#7571F9"),
Empty: '░',
EmptyColor: "#606060",
EmptyColor: lipgloss.Color("#606060"),
ShowPercentage: true,
PercentFormat: " %3.0f%%",
colorProfile: termenv.ColorProfile(),
}

for _, opt := range opts {
Expand Down Expand Up @@ -316,23 +305,21 @@ func (m Model) barView(b *strings.Builder, percent float64, textWidth int) {
} else {
p = float64(i) / float64(tw-1)
}
c := m.rampColorA.BlendLuv(m.rampColorB, p).Hex()
b.WriteString(termenv.
String(string(m.Full)).
Foreground(m.color(c)).
String(),
)
c := m.rampColorA.BlendLuv(m.rampColorB, p)
b.WriteString(lipgloss.NewStyle().Foreground(c).Render(string(m.Full)))
}
} else {
// Solid fill
s := termenv.String(string(m.Full)).Foreground(m.color(m.FullColor)).String()
b.WriteString(strings.Repeat(s, fw))
b.WriteString(lipgloss.NewStyle().
Foreground(m.FullColor).
Render(strings.Repeat(string(m.Full), fw)))
}

// Empty fill
e := termenv.String(string(m.Empty)).Foreground(m.color(m.EmptyColor)).String()
n := max(0, tw-fw)
b.WriteString(strings.Repeat(e, n))
b.WriteString(lipgloss.NewStyle().
Foreground(m.EmptyColor).
Render(strings.Repeat(string(m.Empty), n)))
}

func (m Model) percentageView(percent float64) string {
Expand All @@ -358,10 +345,6 @@ func (m *Model) setRamp(colorA, colorB string, scaled bool) {
m.rampColorB = b
}

func (m Model) color(c string) termenv.Color {
return m.colorProfile.Color(c)
}

func max(a, b int) int {
if a > b {
return a
Expand Down
14 changes: 7 additions & 7 deletions progress/progress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import (
"strings"
"testing"

"github.com/muesli/termenv"
"github.com/charmbracelet/lipgloss/v2"
)

const (
AnsiReset = "\x1b[0m"
AnsiReset = "\x1b[m"
)

func TestGradient(t *testing.T) {

colA := "#FF0000"
colB := "#00FF00"

Expand All @@ -21,7 +20,7 @@ func TestGradient(t *testing.T) {

for _, scale := range []bool{false, true} {
opts := []Option{
WithColorProfile(termenv.TrueColor), WithoutPercentage(),
WithoutPercentage(),
}
if scale {
descr = "progress bar with scaled gradient"
Expand All @@ -36,10 +35,12 @@ func TestGradient(t *testing.T) {

// build the expected colors by colorizing an empty string and then cutting off the following reset sequence
sb := strings.Builder{}
sb.WriteString(termenv.String("").Foreground(p.color(colA)).String())
// sb.WriteString(termenv.String("").Foreground(p.color(colA)).String())
sb.WriteString(lipgloss.NewStyle().Foreground(lipgloss.Color(colA)).String())
expFirst := strings.Split(sb.String(), AnsiReset)[0]
sb.Reset()
sb.WriteString(termenv.String("").Foreground(p.color(colB)).String())
// sb.WriteString(termenv.String("").Foreground(p.color(colB)).String())
sb.WriteString(lipgloss.NewStyle().Foreground(lipgloss.Color(colB)).String())
expLast := strings.Split(sb.String(), AnsiReset)[0]

for _, width := range []int{3, 5, 50} {
Expand All @@ -62,5 +63,4 @@ func TestGradient(t *testing.T) {
}
})
}

}

0 comments on commit 04626c8

Please sign in to comment.