Skip to content

Commit

Permalink
feat: add impure package
Browse files Browse the repository at this point in the history
This adds a compatibility layer for Lip Gloss that provides a way to
continue using `AdaptiveColor` and `CompleteColor`. It's impure because
it uses global variables, is not thread-safe, and only works with the
default standard I/O streams.

Users are encouraged to use the pure API when possible.
  • Loading branch information
aymanbagabas committed Oct 31, 2024
1 parent 0208749 commit 94fe7b7
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 5 deletions.
81 changes: 81 additions & 0 deletions impure/color.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package impure

import (
"image/color"
"os"

"github.com/charmbracelet/colorprofile"
"github.com/charmbracelet/lipgloss/v2"
)

var (
// HasDarkBackground is true if the terminal has a dark background.
HasDarkBackground = func() bool {
hdb, _ := lipgloss.HasDarkBackground(os.Stdin, os.Stdout)
return hdb
}()

// Writer is the default writer that prints to stdout, automatically
// downsampling colors when necessary.
Writer = colorprofile.NewWriter(os.Stdout, os.Environ())
)

// AdaptiveColor provides color options for light and dark backgrounds. The
// appropriate color will be returned at runtime based on the darkness of the
// terminal background color.
//
// Example usage:
//
// color := lipgloss.AdaptiveColor{Light: "#0000ff", Dark: "#000099"}
type AdaptiveColor struct {
Light color.Color
Dark color.Color
}

// RGBA returns the RGBA value of this color. This satisfies the Go Color
// interface.
func (c AdaptiveColor) RGBA() (uint32, uint32, uint32, uint32) {
if HasDarkBackground {
return c.Dark.RGBA()
}
return c.Light.RGBA()
}

// CompleteColor specifies exact values for truecolor, ANSI256, and ANSI color
// profiles. Automatic color degradation will not be performed.
type CompleteColor struct {
TrueColor color.Color
ANSI256 color.Color
ANSI color.Color
}

// RGBA returns the RGBA value of this color. This satisfies the Go Color
// interface.
func (c CompleteColor) RGBA() (uint32, uint32, uint32, uint32) {
switch Writer.Profile {
case colorprofile.TrueColor:
return c.TrueColor.RGBA()
case colorprofile.ANSI256:
return c.ANSI256.RGBA()
case colorprofile.ANSI:
return c.ANSI.RGBA()
}
return lipgloss.NoColor{}.RGBA()
}

// CompleteAdaptiveColor specifies exact values for truecolor, ANSI256, and ANSI color
// profiles, with separate options for light and dark backgrounds. Automatic
// color degradation will not be performed.
type CompleteAdaptiveColor struct {
Light CompleteColor
Dark CompleteColor
}

// RGBA returns the RGBA value of this color. This satisfies the Go Color
// interface.
func (c CompleteAdaptiveColor) RGBA() (uint32, uint32, uint32, uint32) {
if HasDarkBackground {
return c.Dark.RGBA()
}
return c.Light.RGBA()
}
5 changes: 5 additions & 0 deletions impure/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Package impure is a compatibility layer for Lip Gloss that provides a way to
// deal with the hassle of setting up a writer. It's impure because it uses
// global variables, is not thread-safe, and only works with the default
// standard I/O streams.
package impure
6 changes: 1 addition & 5 deletions writer.go → impure/writer.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package lipgloss
package impure

import (
"fmt"
Expand All @@ -8,10 +8,6 @@ import (
"github.com/charmbracelet/colorprofile"
)

// Writer is the default writer that prints to stdout, automatically
// downsampling colors when necessary.
var Writer = colorprofile.NewWriter(os.Stdout, os.Environ())

// Println to stdout, automatically downsampling colors when necessary, ending
// with a trailing newline.
//
Expand Down

0 comments on commit 94fe7b7

Please sign in to comment.