termenv.go

  1package termenv
  2
  3import (
  4	"errors"
  5	"os"
  6
  7	"github.com/mattn/go-isatty"
  8)
  9
 10var (
 11	// ErrStatusReport gets returned when the terminal can't be queried.
 12	ErrStatusReport = errors.New("unable to retrieve status report")
 13)
 14
 15const (
 16	// Escape character.
 17	ESC = '\x1b'
 18	// Bell.
 19	BEL = '\a'
 20	// Control Sequence Introducer.
 21	CSI = string(ESC) + "["
 22	// Operating System Command.
 23	OSC = string(ESC) + "]"
 24	// String Terminator.
 25	ST = string(ESC) + `\`
 26)
 27
 28func (o *Output) isTTY() bool {
 29	if o.assumeTTY || o.unsafe {
 30		return true
 31	}
 32	if len(o.environ.Getenv("CI")) > 0 {
 33		return false
 34	}
 35	if f, ok := o.Writer().(*os.File); ok {
 36		return isatty.IsTerminal(f.Fd())
 37	}
 38
 39	return false
 40}
 41
 42// ColorProfile returns the supported color profile:
 43// Ascii, ANSI, ANSI256, or TrueColor.
 44func ColorProfile() Profile {
 45	return output.ColorProfile()
 46}
 47
 48// ForegroundColor returns the terminal's default foreground color.
 49func ForegroundColor() Color {
 50	return output.ForegroundColor()
 51}
 52
 53// BackgroundColor returns the terminal's default background color.
 54func BackgroundColor() Color {
 55	return output.BackgroundColor()
 56}
 57
 58// HasDarkBackground returns whether terminal uses a dark-ish background.
 59func HasDarkBackground() bool {
 60	return output.HasDarkBackground()
 61}
 62
 63// EnvNoColor returns true if the environment variables explicitly disable color output
 64// by setting NO_COLOR (https://no-color.org/)
 65// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
 66// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
 67// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
 68func (o *Output) EnvNoColor() bool {
 69	return o.environ.Getenv("NO_COLOR") != "" || (o.environ.Getenv("CLICOLOR") == "0" && !o.cliColorForced())
 70}
 71
 72// EnvNoColor returns true if the environment variables explicitly disable color output
 73// by setting NO_COLOR (https://no-color.org/)
 74// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
 75// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE
 76// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset.
 77func EnvNoColor() bool {
 78	return output.EnvNoColor()
 79}
 80
 81// EnvColorProfile returns the color profile based on environment variables set
 82// Supports NO_COLOR (https://no-color.org/)
 83// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
 84// If none of these environment variables are set, this behaves the same as ColorProfile()
 85// It will return the Ascii color profile if EnvNoColor() returns true
 86// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
 87// then the ANSI color profile will be returned.
 88func EnvColorProfile() Profile {
 89	return output.EnvColorProfile()
 90}
 91
 92// EnvColorProfile returns the color profile based on environment variables set
 93// Supports NO_COLOR (https://no-color.org/)
 94// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/)
 95// If none of these environment variables are set, this behaves the same as ColorProfile()
 96// It will return the Ascii color profile if EnvNoColor() returns true
 97// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0"
 98// then the ANSI color profile will be returned.
 99func (o *Output) EnvColorProfile() Profile {
100	if o.EnvNoColor() {
101		return Ascii
102	}
103	p := o.ColorProfile()
104	if o.cliColorForced() && p == Ascii {
105		return ANSI
106	}
107	return p
108}
109
110func (o *Output) cliColorForced() bool {
111	if forced := o.environ.Getenv("CLICOLOR_FORCE"); forced != "" {
112		return forced != "0"
113	}
114	return false
115}