Documentation
¶
Overview ¶
Package palette provides stable, hash-based color selection from ordered color palettes, plus curated palettes tuned for light and dark terminal backgrounds.
The mapping from string to color is deterministic: the same text always resolves to the same color for a given palette, across processes and platforms. This makes it suitable for colorizing entities such as environments, hostnames, or identifiers so they stay visually consistent.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Assigner ¶ added in v0.5.1
type Assigner struct {
// contains filtered or unexported fields
}
Assigner hands out colors from a Palette so distinct keys receive distinct colors in palette order, repeating only after the palette is exhausted. Assignments are remembered, so a key always resolves to the same color for the Assigner's lifetime. Assign keys in a stable order, such as sorted order, to reproduce the same mapping across runs.
An Assigner is safe for concurrent use.
func NewAssigner ¶ added in v0.5.1
NewAssigner returns an Assigner that draws from the given colors. When no colors are given, it defaults to Auto, selecting a palette that matches the terminal background and true-color support. Pass an explicit palette by spreading it, e.g. NewAssigner(TrueColorDark()...). Spreading an empty palette also triggers the Auto fallback; use Palette.Assigner for a palette that must stay empty, such as the result of Palette.Avoiding.
Example ¶
package main
import (
"fmt"
"github.com/gechr/x/palette"
)
func main() {
// An Assigner gives distinct keys distinct colors (no duplicates until the
// palette is exhausted) while keeping each key stable. With no colors it
// defaults to Auto for the current terminal.
a := palette.NewAssigner()
fmt.Println(a.Assign("web") == a.Assign("web"))
}
Output: true
type Option ¶
type Option func(*config)
Option configures Auto.
func WithDark ¶ added in v0.5.14
WithDark tells Auto whether the terminal background is dark, skipping its background detection entirely. Use it when the background was already detected, for example once at startup.
func WithReserved ¶ added in v0.5.14
WithReserved keeps the returned palette perceptually clear of the reserved colors, as if the selected palette were passed to Palette.Avoiding: any palette color that could be mistaken for a reserved one is removed. Use it when entity colors render alongside colors that carry meaning of their own, such as a theme's semantic red or a Semantic set. On the non-true-color path, colors are measured as ANSI-256 renders them.
func WithTrueColor ¶
func WithTrueColor() Option
WithTrueColor forces Auto to return the true-color palette, overriding its automatic terminal-capability detection. The caller is responsible for ensuring the terminal supports true color.
type Palette ¶
Palette is an ordered list of colors from which a stable color is chosen for a given string.
func Auto ¶
Auto returns a palette matching the terminal, defaulting to the dark palette when background detection is unavailable. By default it selects the true-color palette when the terminal supports true color and the ANSI-256 palette otherwise; pass WithTrueColor to force the true-color palette.
Background detection queries the terminal, waiting up to 10 milliseconds for a response on the first call; the result is cached for the process. Pass WithDark to skip detection entirely, for example when the background was already detected at startup.
Example ¶
package main
import (
"fmt"
"github.com/gechr/x/palette"
)
func main() {
// Auto detects the terminal background and true-color support, then colors
// entities so identical strings share a stable color.
p := palette.Auto()
for _, entity := range []string{"alpha", "beta", "alpha"} {
_ = p.Color(entity)
}
// Force the true-color palette regardless of detection.
p = palette.Auto(palette.WithTrueColor())
fmt.Println(len(p))
}
Output: 23
func DefaultDark ¶
func DefaultDark() Palette
DefaultDark returns the default ANSI-256 palette tuned for dark backgrounds, ordered so that colors close together in the list stay perceptually distinct.
func DefaultLight ¶
func DefaultLight() Palette
DefaultLight returns the default palette tuned for light backgrounds: the DefaultDark palette darkened for contrast against a light background.
func TrueColorDark ¶
func TrueColorDark() Palette
TrueColorDark returns the 24-bit palette tuned for dark backgrounds. Every color clears 4.5:1 contrast against #1e1e1e and sits at least 0.08 CIEDE2000 from every other, and colors are ordered so that consecutive entries stay distinct from one another as well. Each call returns a fresh palette the caller owns.
func TrueColorLight ¶
func TrueColorLight() Palette
TrueColorLight returns the 24-bit palette tuned for light backgrounds, ordered like TrueColorDark but measured against #fafafa.
func (Palette) Assigner ¶ added in v0.5.14
Assigner returns an Assigner that draws from exactly this palette, even when it is empty - unlike NewAssigner, which treats no colors as a request for Auto. An empty palette assigns nil to every key.
func (Palette) Avoiding ¶ added in v0.5.14
Avoiding returns a new palette without the colors that sit perceptually close to any reserved color, so entity colors cannot be mistaken for a reserved one - a theme's semantic red, say. Closeness is measured with the CIEDE2000 color-difference formula. The remaining colors keep their original order, so a most-separable-first palette stays that way.
Distances are measured on the colors' own RGBA values, so the guarantee is for opaque colors rendered in true color. Rendering in a reduced color profile quantizes colors and can narrow their distances; Auto accounts for this on its non-true-color path by measuring colors as ANSI-256 renders them. Nil and fully transparent reserved colors are ignored; palette colors that cannot be measured are kept.
The mapping from string to color differs between the filtered and unfiltered palettes, since Palette.Color hashes over the palette length. A reserved set that blankets the palette can leave it empty, in which case Palette.Color returns nil; use Palette.Assigner rather than NewAssigner to keep such a palette empty.
Example ¶
package main
import (
"fmt"
"charm.land/lipgloss/v2"
"github.com/gechr/x/palette"
)
func main() {
// A theme that renders dangerous entities in its own semantic red can keep
// entity colors perceptually clear of it, so the red stays unmistakable.
themeRed := lipgloss.Color("#f38ba8")
p := palette.TrueColorDark().Avoiding(themeRed)
fmt.Println(len(p))
}
Output: 20
func (Palette) Color ¶
Color returns a stable color for text, or nil when the palette is empty. The same text always yields the same color for a given palette.
Example ¶
package main
import (
"fmt"
"github.com/gechr/x/palette"
)
func main() {
p := palette.DefaultDark()
// The same entity always resolves to the same color.
fmt.Println(p.Color("alpha") == p.Color("alpha"))
}
Output: true
Example (Empty) ¶
package main
import (
"fmt"
"github.com/gechr/x/palette"
)
func main() {
// An empty palette resolves every input to nil, leaving text uncolored.
fmt.Println(palette.Palette(nil).Color("alpha"))
}
Output: <nil>
type Semantic ¶ added in v0.5.14
type Semantic struct {
Danger color.Color
Warning color.Color
Success color.Color
Info color.Color
}
Semantic holds measured colors for conventional message meanings. Like the entity palettes, every color clears 4.5:1 contrast against its target background, and the colors are mutually distinguishable. Which strings warrant a semantic color is the caller's policy; the set only guarantees the colors themselves are legible and distinct.
To keep entity colors perceptually clear of the set, reserve it: pass the Semantic.Colors slice to WithReserved or Palette.Avoiding.
func SemanticDark ¶ added in v0.5.14
func SemanticDark() Semantic
SemanticDark returns the semantic set tuned for dark backgrounds, measured against #1e1e1e like TrueColorDark.
Example ¶
package main
import (
"fmt"
"github.com/gechr/x/palette"
)
func main() {
// A measured semantic set: every color clears 4.5:1 against a dark
// background, and reserving it keeps entity colors clear of the set.
sem := palette.SemanticDark()
p := palette.Auto(
palette.WithTrueColor(),
palette.WithDark(true),
palette.WithReserved(sem.Colors()...),
)
fmt.Println(len(p) < len(palette.TrueColorDark()))
}
Output: true
func SemanticLight ¶ added in v0.5.14
func SemanticLight() Semantic
SemanticLight returns the semantic set tuned for light backgrounds, measured against #fafafa like TrueColorLight.
func (Semantic) Colors ¶ added in v0.5.14
Colors returns the set as a slice, in Danger, Warning, Success, Info order - convenient for Palette.Avoiding and WithReserved.