1package termenv 2 3import ( 4 "errors" 5 "os" 6 7 "github.com/mattn/go-isatty" 8) 9 10var ( 11 ErrStatusReport = errors.New("unable to retrieve status report") 12) 13 14type Profile int 15 16const ( 17 CSI = "\x1b[" 18 19 Ascii = Profile(iota) 20 ANSI 21 ANSI256 22 TrueColor 23) 24 25// ColorProfile returns the supported color profile: 26// Ascii, ANSI, ANSI256, or TrueColor. 27func ColorProfile() Profile { 28 if !isatty.IsTerminal(os.Stdout.Fd()) { 29 return Ascii 30 } 31 32 return colorProfile() 33} 34 35// ForegroundColor returns the terminal's default foreground color. 36func ForegroundColor() Color { 37 if !isatty.IsTerminal(os.Stdout.Fd()) { 38 return NoColor{} 39 } 40 41 return foregroundColor() 42} 43 44// BackgroundColor returns the terminal's default background color. 45func BackgroundColor() Color { 46 if !isatty.IsTerminal(os.Stdout.Fd()) { 47 return NoColor{} 48 } 49 50 return backgroundColor() 51} 52 53// HasDarkBackground returns whether terminal uses a dark-ish background. 54func HasDarkBackground() bool { 55 c := ConvertToRGB(BackgroundColor()) 56 _, _, l := c.Hsl() 57 return l < 0.5 58} 59 60// EnvNoColor returns true if the environment variables explicitly disable color output 61// by setting NO_COLOR (https://no-color.org/) 62// or CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/) 63// If NO_COLOR is set, this will return true, ignoring CLICOLOR/CLICOLOR_FORCE 64// If CLICOLOR=="0", it will be true only if CLICOLOR_FORCE is also "0" or is unset. 65func EnvNoColor() bool { 66 return os.Getenv("NO_COLOR") != "" || (os.Getenv("CLICOLOR") == "0" && !cliColorForced()) 67} 68 69// EnvColorProfile returns the color profile based on environment variables set 70// Supports NO_COLOR (https://no-color.org/) 71// and CLICOLOR/CLICOLOR_FORCE (https://bixense.com/clicolors/) 72// If none of these environment variables are set, this behaves the same as ColorProfile() 73// It will return the Ascii color profile if EnvNoColor() returns true 74// If the terminal does not support any colors, but CLICOLOR_FORCE is set and not "0" 75// then the ANSI color profile will be returned. 76func EnvColorProfile() Profile { 77 if EnvNoColor() { 78 return Ascii 79 } 80 p := ColorProfile() 81 if cliColorForced() && p == Ascii { 82 return ANSI 83 } 84 return p 85} 86 87func cliColorForced() bool { 88 if forced := os.Getenv("CLICOLOR_FORCE"); forced != "" { 89 return forced != "0" 90 } 91 return false 92} 93