Skip to content

Commit

Permalink
feat: add adaptive color package
Browse files Browse the repository at this point in the history
This introduces a helper type `LightDark` that takes a boolean to
determine which `Color(light, dark)` to choose from. The `adaptive`
package is a helper package that uses the `lipgloss.LightDark` along
with querying the terminal when the module is imported to choose the
appropriate light-dark color.

Example:

```go
var (
  light = "#0000ff"
  dark = "#ff0000"
)

colorToUse := adaptive.Color(light, dark) // the terminal is queried before choosing the color
fmt.Println(colorToUse)
```
  • Loading branch information
aymanbagabas committed Aug 30, 2024
1 parent b89f1a3 commit 3014273
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 16 deletions.
47 changes: 47 additions & 0 deletions adaptive/adaptive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package adaptive

import (
"os"

"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/x/term"
)

// Stdin, Stdout, and HasDarkBackground are the standard input, output, and
// default background color value to use. They can be overridden by the
// importing program.
var (
Stdin = os.Stdin
Stdout = os.Stdout
HasDarkBackground = true
)

// colorFn is the light-dark Lip Gloss color function to use to determine the
// appropriate color based on the terminal's background color.
// When a program imports this package, it will query the terminal's background
// color and use it to determine whether to use the light or dark color.
var colorFn lipgloss.LightDark

func init() {
Query()
}

// Query queries the terminal's background color and updates the color function
// accordingly.
func Query() {
colorFn = lipgloss.LightDark(func() bool {
state, err := term.MakeRaw(Stdin.Fd())
if err != nil {
return HasDarkBackground
}

defer term.Restore(Stdin.Fd(), state) //nolint:errcheck

bg, err := queryBackgroundColor(Stdin, Stdout)
if err == nil {
return lipgloss.IsDarkColor(bg)
}

return HasDarkBackground
}())
}
11 changes: 11 additions & 0 deletions adaptive/color.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package adaptive

import (
"image/color"
)

// Color returns the color that should be used based on the terminal's
// background color.
func Color(light, dark any) color.Color {
return colorFn.Color(light, dark)
}
95 changes: 95 additions & 0 deletions adaptive/terminal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package adaptive

import (
"image/color"
"io"
"time"

"github.com/charmbracelet/x/ansi"
"github.com/charmbracelet/x/input"
)

// queryBackgroundColor queries the terminal for the background color.
// If the terminal does not support querying the background color, nil is
// returned.
//
// Note: you will need to set the input to raw mode before calling this
// function.
//
// state, _ := term.MakeRaw(in.Fd())
// defer term.Restore(in.Fd(), state)
//
// copied from x/[email protected].
func queryBackgroundColor(in io.Reader, out io.Writer) (c color.Color, err error) {
// nolint: errcheck

Check failure on line 24 in adaptive/terminal.go

View workflow job for this annotation

GitHub Actions / lint-soft

directive `// nolint: errcheck` should be written without leading space as `//nolint: errcheck` (nolintlint)
err = queryTerminal(in, out, defaultQueryTimeout,
func(events []input.Event) bool {
for _, e := range events {
switch e := e.(type) {
case input.BackgroundColorEvent:
c = e.Color
continue // we need to consume the next DA1 event
case input.PrimaryDeviceAttributesEvent:
return false
}
}
return true
}, ansi.RequestBackgroundColor+ansi.RequestPrimaryDeviceAttributes)
return
}

const defaultQueryTimeout = time.Second * 2

// queryTerminalFilter is a function that filters input events using a type
// switch. If false is returned, the QueryTerminal function will stop reading
// input.
type queryTerminalFilter func(events []input.Event) bool

// queryTerminal queries the terminal for support of various features and
// returns a list of response events.
// Most of the time, you will need to set stdin to raw mode before calling this
// function.
// Note: This function will block until the terminal responds or the timeout
// is reached.
// copied from x/[email protected].
func queryTerminal(
in io.Reader,
out io.Writer,
timeout time.Duration,
filter queryTerminalFilter,
query string,
) error {
rd, err := input.NewDriver(in, "", 0)
if err != nil {
return err

Check failure on line 64 in adaptive/terminal.go

View workflow job for this annotation

GitHub Actions / lint-soft

error returned from external package is unwrapped: sig: func github.com/charmbracelet/x/input.NewDriver(r io.Reader, term string, flags int) (*github.com/charmbracelet/x/input.Driver, error) (wrapcheck)

Check failure on line 64 in adaptive/terminal.go

View workflow job for this annotation

GitHub Actions / lint-soft

error returned from external package is unwrapped: sig: func github.com/charmbracelet/x/input.NewDriver(r io.Reader, term string, flags int) (*github.com/charmbracelet/x/input.Driver, error) (wrapcheck)
}

defer rd.Close() // nolint: errcheck

Check failure on line 67 in adaptive/terminal.go

View workflow job for this annotation

GitHub Actions / lint-soft

directive `// nolint: errcheck` should be written without leading space as `//nolint: errcheck` (nolintlint)

done := make(chan struct{}, 1)
defer close(done)
go func() {
select {
case <-done:
case <-time.After(timeout):
rd.Cancel()
}
}()

if _, err := io.WriteString(out, query); err != nil {
return err

Check failure on line 80 in adaptive/terminal.go

View workflow job for this annotation

GitHub Actions / lint-soft

error returned from external package is unwrapped: sig: func io.WriteString(w io.Writer, s string) (n int, err error) (wrapcheck)

Check failure on line 80 in adaptive/terminal.go

View workflow job for this annotation

GitHub Actions / lint-soft

error returned from external package is unwrapped: sig: func io.WriteString(w io.Writer, s string) (n int, err error) (wrapcheck)
}

for {
events, err := rd.ReadEvents()
if err != nil {
return err

Check failure on line 86 in adaptive/terminal.go

View workflow job for this annotation

GitHub Actions / lint-soft

error returned from external package is unwrapped: sig: func (*github.com/charmbracelet/x/input.Driver).ReadEvents() ([]github.com/charmbracelet/x/input.Event, error) (wrapcheck)
}

if !filter(events) {
break
}
}

return nil
}
36 changes: 31 additions & 5 deletions color.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package lipgloss

import (
"fmt"
"image/color"
"strconv"

Expand Down Expand Up @@ -54,12 +55,13 @@ func (n NoColor) RGBA() (r, g, b, a uint32) {
// ansiColor := lipgloss.Color(21)
// hexColor := lipgloss.Color("#0000ff")
// uint32Color := lipgloss.Color(0xff0000)
func Color[T string | int](c T) color.Color {
var col color.Color = noColor
switch c := any(c).(type) {
func Color(c any) color.Color {
switch c := c.(type) {
case nil:
return noColor
case string:
if len(c) == 0 {
return col
return noColor
}
if h, err := colorful.Hex(c); err == nil {
return h
Expand All @@ -71,15 +73,18 @@ func Color[T string | int](c T) color.Color {
}
return ansi.TrueColor(i)

Check failure on line 74 in color.go

View workflow job for this annotation

GitHub Actions / lint

G115: integer overflow conversion int -> uint32 (gosec)
}
return noColor
case int:
if c < 16 {

Check failure on line 78 in color.go

View workflow job for this annotation

GitHub Actions / lint-soft

Magic number: 16, in <condition> detected (gomnd)
return ansi.BasicColor(c)

Check failure on line 79 in color.go

View workflow job for this annotation

GitHub Actions / lint

G115: integer overflow conversion int -> uint8 (gosec)
} else if c < 256 {

Check failure on line 80 in color.go

View workflow job for this annotation

GitHub Actions / lint-soft

Magic number: 256, in <condition> detected (gomnd)
return ansi.ExtendedColor(c)

Check failure on line 81 in color.go

View workflow job for this annotation

GitHub Actions / lint

G115: integer overflow conversion int -> uint8 (gosec)
}
return ansi.TrueColor(c)

Check failure on line 83 in color.go

View workflow job for this annotation

GitHub Actions / lint

G115: integer overflow conversion int -> uint32 (gosec)
case color.Color:
return c
}
return col
return Color(fmt.Sprint(c))
}

// RGBColor is a color specified by red, green, and blue values.
Expand Down Expand Up @@ -107,6 +112,27 @@ func (c RGBColor) RGBA() (r, g, b, a uint32) {
// colorB := lipgloss.ANSIColor(134)
type ANSIColor = ansi.ExtendedColor

// LightDark is a helper type that can be used to specify colors that should be
// used based on the terminal's background color.
//
// Example usage:
//
// useDark := lipgloss.LightDark(true)
// light := "#0000ff"
// dark := "#ff0000"
// colorToUse := useDark.Color(light, dark)
// fmt.Println(colorToUse)
type LightDark bool

// Color returns the color that should be used based on the terminal's
// background color.
func (a LightDark) Color(light, dark any) color.Color {
if bool(a) {
return Color(dark)
}
return Color(light)
}

// IsDarkColor returns whether the given color is dark.
//
// Example usage:
Expand Down
14 changes: 10 additions & 4 deletions examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ replace github.com/charmbracelet/lipgloss => ../

replace github.com/charmbracelet/lipgloss/list => ../list

replace github.com/charmbracelet/lipgloss/adaptive => ../adaptive

require (
github.com/charmbracelet/lipgloss v0.11.0
github.com/charmbracelet/ssh v0.0.0-20240401141849-854cddfa2917
github.com/charmbracelet/wish v1.4.0
github.com/creack/pty v1.1.21
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/muesli/termenv v0.15.2
golang.org/x/term v0.21.0
)

Expand All @@ -22,21 +22,27 @@ require (
github.com/charmbracelet/bubbletea v0.25.0 // indirect
github.com/charmbracelet/keygen v0.5.0 // indirect
github.com/charmbracelet/log v0.4.0 // indirect
github.com/charmbracelet/x/ansi v0.1.4 // indirect
github.com/charmbracelet/x/ansi v0.2.3 // indirect
github.com/charmbracelet/x/errors v0.0.0-20240117030013-d31dba354651 // indirect
github.com/charmbracelet/x/exp/term v0.0.0-20240328150354-ab9afc214dfd // indirect
github.com/charmbracelet/x/input v0.2.0 // indirect
github.com/charmbracelet/x/term v0.2.0 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/creack/pty v1.1.21 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/text v0.14.0 // indirect
)
18 changes: 14 additions & 4 deletions examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,24 @@ github.com/charmbracelet/ssh v0.0.0-20240401141849-854cddfa2917 h1:NZKjJ7d/pzk/A
github.com/charmbracelet/ssh v0.0.0-20240401141849-854cddfa2917/go.mod h1:8/Ve8iGRRIGFM1kepYfRF2pEOF5Y3TEZYoJaA54228U=
github.com/charmbracelet/wish v1.4.0 h1:pL1uVP/YuYgJheHEj98teZ/n6pMYnmlZq/fcHvomrfc=
github.com/charmbracelet/wish v1.4.0/go.mod h1:ew4/MjJVfW/akEO9KmrQHQv1F7bQRGscRMrA+KtovTk=
github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM=
github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY=
github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/errors v0.0.0-20240117030013-d31dba354651 h1:3RXpZWGWTOeVXCTv0Dnzxdv/MhNUkBfEcbaTY0zrTQI=
github.com/charmbracelet/x/errors v0.0.0-20240117030013-d31dba354651/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0=
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30=
github.com/charmbracelet/x/exp/term v0.0.0-20240328150354-ab9afc214dfd h1:HqBjkSFXXfW4IgX3TMKipWoPEN08T3Pi4SA/3DLss/U=
github.com/charmbracelet/x/exp/term v0.0.0-20240328150354-ab9afc214dfd/go.mod h1:6GZ13FjIP6eOCqWU4lqgveGnYxQo9c3qBzHPeFu4HBE=
github.com/charmbracelet/x/input v0.2.0 h1:1Sv+y/flcqUfUH2PXNIDKDIdT2G8smOnGOgawqhwy8A=
github.com/charmbracelet/x/input v0.2.0/go.mod h1:KUSFIS6uQymtnr5lHVSOK9j8RvwTD4YHnWnzJUYnd/M=
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
Expand All @@ -49,16 +56,19 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
Expand Down
7 changes: 6 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,19 @@ require (
github.com/aymanbagabas/go-udiff v0.2.0
github.com/charmbracelet/x/ansi v0.2.3
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a
github.com/charmbracelet/x/input v0.2.0
github.com/charmbracelet/x/term v0.2.0
github.com/lucasb-eyer/go-colorful v1.2.0
github.com/muesli/termenv v0.15.2
github.com/rivo/uniseg v0.4.7
golang.org/x/sys v0.19.0
golang.org/x/sys v0.24.0
)

require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
)
16 changes: 14 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,29 @@ github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqo
github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a h1:G99klV19u0QnhiizODirwVksQB91TJKV/UaTnACcG30=
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/input v0.2.0 h1:1Sv+y/flcqUfUH2PXNIDKDIdT2G8smOnGOgawqhwy8A=
github.com/charmbracelet/x/input v0.2.0/go.mod h1:KUSFIS6uQymtnr5lHVSOK9j8RvwTD4YHnWnzJUYnd/M=
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
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.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/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=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=

0 comments on commit 3014273

Please sign in to comment.