Skip to content

Commit

Permalink
fix(tea): query bg color
Browse files Browse the repository at this point in the history
  • Loading branch information
aymanbagabas committed Aug 21, 2024
1 parent 654e657 commit 94788c7
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 6 deletions.
95 changes: 95 additions & 0 deletions bubbletea/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package bubbletea

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/term@v0.1.3.
func queryBackgroundColor(in io.Reader, out io.Writer) (c color.Color, err error) {
// nolint: errcheck
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/term@v0.1.3.
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
}

defer rd.Close() // nolint: errcheck

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
}

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

if !filter(events) {
break
}
}

return nil
}
11 changes: 5 additions & 6 deletions bubbletea/tea_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/charmbracelet/ssh"
"github.com/charmbracelet/x/ansi"
"github.com/charmbracelet/x/input"
"github.com/charmbracelet/x/term"
"github.com/lucasb-eyer/go-colorful"
"github.com/muesli/termenv"
)
Expand Down Expand Up @@ -46,15 +45,15 @@ func newRenderer(s ssh.Session) *lipgloss.Renderer {
termenv.WithEnvironment(env),
termenv.WithColorCache(true),
)
bg, _ = term.QueryBackgroundColor(pty.Slave, pty.Slave)
bg, _ = queryBackgroundColor(pty.Slave, pty.Slave)
} else {
r = lipgloss.NewRenderer(
s,
termenv.WithEnvironment(env),
termenv.WithUnsafe(),
termenv.WithColorCache(true),
)
bg = queryBackgroundColor(s)
bg = querySessionBackgroundColor(s)
}
if bg != nil {
c, ok := colorful.MakeColor(bg)
Expand All @@ -66,9 +65,9 @@ func newRenderer(s ssh.Session) *lipgloss.Renderer {
return r
}

// copied from x/exp/term.
func queryBackgroundColor(s ssh.Session) (bg color.Color) {
_ = term.QueryTerminal(s, s, time.Second, func(events []input.Event) bool {
// copied from x/term@v0.1.3.
func querySessionBackgroundColor(s ssh.Session) (bg color.Color) {
_ = queryTerminal(s, s, time.Second, func(events []input.Event) bool {
for _, e := range events {
switch e := e.(type) {
case input.BackgroundColorEvent:
Expand Down

0 comments on commit 94788c7

Please sign in to comment.