Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(v2) feat: add adaptive color package #359

Open
wants to merge 1 commit into
base: v2-exp
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,32 +55,36 @@
// 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
} else if i, err := strconv.Atoi(c); err == nil {
if i < 16 {

Check failure on line 69 in color.go

View workflow job for this annotation

GitHub Actions / lint-soft

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

Check failure on line 70 in color.go

View workflow job for this annotation

GitHub Actions / lint

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

Check failure on line 71 in color.go

View workflow job for this annotation

GitHub Actions / lint-soft

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

Check failure on line 72 in color.go

View workflow job for this annotation

GitHub Actions / lint

G115: integer overflow conversion int -> uint8 (gosec)
}
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 All @@ -92,9 +97,9 @@
// RGBA returns the RGBA value of this color. This satisfies the Go Color
// interface.
func (c RGBColor) RGBA() (r, g, b, a uint32) {
r |= uint32(c.R) << 8

Check failure on line 100 in color.go

View workflow job for this annotation

GitHub Actions / lint-soft

Magic number: 8, in <operation> detected (gomnd)
g |= uint32(c.G) << 8

Check failure on line 101 in color.go

View workflow job for this annotation

GitHub Actions / lint-soft

Magic number: 8, in <operation> detected (gomnd)
b |= uint32(c.B) << 8

Check failure on line 102 in color.go

View workflow job for this annotation

GitHub Actions / lint-soft

Magic number: 8, in <operation> detected (gomnd)
a = 0xFFFF //nolint:gomnd
return
}
Expand All @@ -107,6 +112,27 @@
// 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 All @@ -124,5 +150,5 @@
}

_, _, l := col.Hsl()
return l < 0.5

Check failure on line 153 in color.go

View workflow job for this annotation

GitHub Actions / lint-soft

Magic number: 0.5, in <return> detected (gomnd)
}
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=
Loading