colorprofile

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2025 License: MIT Imports: 13 Imported by: 10

README

Colorprofile

Latest Release GoDoc Build Status

A simple, powerful—and at times magical—package for detecting terminal color profiles and performing color (and CSI) degradation.

Detecting the terminal’s color profile

Detecting the terminal’s color profile is easy.

import "github.com/charmbracelet/colorprofile"

// Detect the color profile. If you’re planning on writing to stderr you'd want
// to use os.Stderr instead.
p := colorprofile.Detect(os.Stdout, os.Environ())

// Comment on the profile.
fmt.Printf("You know, your colors are quite %s.", func() string {
    switch p {
    case colorprofile.TrueColor:
        return "fancy"
    case colorprofile.ANSI256:
        return "1990s fancy"
    case colorprofile.ANSI:
        return "normcore"
    case colorprofile.Ascii:
        return "ancient"
    case colorprofile.NoTTY:
        return "naughty!"
    }
    return "...IDK" // this should never happen
}())

Downsampling colors

When necessary, colors can be downsampled to a given profile, or manually downsampled to a specific profile.

p := colorprofile.Detect(os.Stdout, os.Environ())
c := color.RGBA{0x6b, 0x50, 0xff, 0xff} // #6b50ff

// Downsample to the detected profile, when necessary.
convertedColor := p.Convert(c)

// Or manually convert to a given profile.
ansi256Color := colorprofile.ANSI256.Convert(c)
ansiColor := colorprofile.ANSI.Convert(c)
noColor := colorprofile.Ascii.Convert(c)
noANSI := colorprofile.NoTTY.Convert(c)

Automatic downsampling with a Writer

You can also magically downsample colors in ANSI output, when necessary. If output is not a TTY ANSI will be dropped entirely.

myFancyANSI := "\x1b[38;2;107;80;255mCute \x1b[1;3mpuppy!!\x1b[m"

// Automatically downsample for the terminal at stdout.
w := colorprofile.NewWriter(os.Stdout, os.Environ())
fmt.Fprintf(w, myFancyANSI)

// Downsample to 4-bit ANSI.
w.Profile = colorprofile.ANSI
fmt.Fprintf(w, myFancyANSI)

// Ascii-fy, no colors.
w.Profile = colorprofile.Ascii
fmt.Fprintf(w, myFancyANSI)

// Strip ANSI altogether.
w.Profile = colorprofile.NoTTY
fmt.Fprintf(w, myFancyANSI) // not as fancy

Feedback

We’d love to hear your thoughts on this project. Feel free to drop us a note!

License

MIT


Part of Charm.

The Charm logo

Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Profile

type Profile byte

Profile is a color profile: NoTTY, Ascii, ANSI, ANSI256, or TrueColor.

const (
	// NoTTY, not a terminal profile.
	NoTTY Profile = iota
	// Ascii, uncolored profile.
	Ascii //nolint:revive
	// ANSI, 4-bit color profile.
	ANSI
	// ANSI256, 8-bit color profile.
	ANSI256
	// TrueColor, 24-bit color profile.
	TrueColor
)

func Detect

func Detect(output io.Writer, env []string) Profile

Detect returns the color profile based on the terminal output, and environment variables. This respects NO_COLOR, CLICOLOR, and CLICOLOR_FORCE environment variables.

The rules as follows:

  • TERM=dumb is always treated as NoTTY unless CLICOLOR_FORCE=1 is set.
  • If COLORTERM=truecolor, and the profile is not NoTTY, it gest upgraded to TrueColor.
  • Using any 256 color terminal (e.g. TERM=xterm-256color) will set the profile to ANSI256.
  • Using any color terminal (e.g. TERM=xterm-color) will set the profile to ANSI.
  • Using CLICOLOR=1 without TERM defined should be treated as ANSI if the output is a terminal.
  • NO_COLOR takes precedence over CLICOLOR/CLICOLOR_FORCE, and will disable colors but not text decoration, i.e. bold, italic, faint, etc.

See https://no-color.org/ and https://bixense.com/clicolors/ for more information.

func Env

func Env(env []string) (p Profile)

Env returns the color profile based on the terminal environment variables. This respects NO_COLOR, CLICOLOR, and CLICOLOR_FORCE environment variables.

The rules as follows:

  • TERM=dumb is always treated as NoTTY unless CLICOLOR_FORCE=1 is set.
  • If COLORTERM=truecolor, and the profile is not NoTTY, it gest upgraded to TrueColor.
  • Using any 256 color terminal (e.g. TERM=xterm-256color) will set the profile to ANSI256.
  • Using any color terminal (e.g. TERM=xterm-color) will set the profile to ANSI.
  • Using CLICOLOR=1 without TERM defined should be treated as ANSI if the output is a terminal.
  • NO_COLOR takes precedence over CLICOLOR/CLICOLOR_FORCE, and will disable colors but not text decoration, i.e. bold, italic, faint, etc.

See https://no-color.org/ and https://bixense.com/clicolors/ for more information.

func Terminfo added in v0.1.10

func Terminfo(term string) (p Profile)

Terminfo returns the color profile based on the terminal's terminfo database. This relies on the Tc and RGB capabilities to determine if the terminal supports TrueColor. If term is empty or "dumb", it returns NoTTY.

func Tmux added in v0.1.10

func Tmux(env []string) Profile

Tmux returns the color profile based on `tmux info` output. Tmux supports overriding the terminal's color capabilities, so this function will return the color profile based on the tmux configuration.

func (Profile) Convert

func (p Profile) Convert(c color.Color) color.Color

Convert transforms a given Color to a Color supported within the Profile.

func (Profile) String

func (p Profile) String() string

String returns the string representation of a Profile.

type Writer

type Writer struct {
	Forward io.Writer
	Profile Profile
}

Writer represents a color profile writer that writes ANSI sequences to the underlying writer.

func NewWriter

func NewWriter(w io.Writer, environ []string) *Writer

NewWriter creates a new color profile writer that downgrades color sequences based on the detected color profile.

If environ is nil, it will use os.Environ() to get the environment variables.

It queries the given writer to determine if it supports ANSI escape codes. If it does, along with the given environment variables, it will determine the appropriate color profile to use for color formatting.

This respects the NO_COLOR, CLICOLOR, and CLICOLOR_FORCE environment variables.

func (*Writer) Write

func (w *Writer) Write(p []byte) (int, error)

Write writes the given text to the underlying writer.

func (*Writer) WriteString

func (w *Writer) WriteString(s string) (n int, err error)

WriteString writes the given text to the underlying writer.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL