102 lines
2.0 KiB
Go
102 lines
2.0 KiB
Go
package color
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
// ANSI color codes
|
|
const (
|
|
resetCode = "\033[0m"
|
|
redCode = "\033[31m"
|
|
greenCode = "\033[32m"
|
|
yellowCode = "\033[33m"
|
|
blueCode = "\033[34m"
|
|
purpleCode = "\033[35m"
|
|
cyanCode = "\033[36m"
|
|
whiteCode = "\033[37m"
|
|
grayCode = "\033[90m"
|
|
)
|
|
|
|
var (
|
|
useColors bool
|
|
colorMu sync.RWMutex
|
|
)
|
|
|
|
// Color function; makes a call to makeColorFunc with the associated color code
|
|
var (
|
|
Reset = makeColorFunc(resetCode)
|
|
Red = makeColorFunc(redCode)
|
|
Green = makeColorFunc(greenCode)
|
|
Yellow = makeColorFunc(yellowCode)
|
|
Blue = makeColorFunc(blueCode)
|
|
Purple = makeColorFunc(purpleCode)
|
|
Cyan = makeColorFunc(cyanCode)
|
|
White = makeColorFunc(whiteCode)
|
|
Gray = makeColorFunc(grayCode)
|
|
)
|
|
|
|
func init() {
|
|
useColors = DetectShellColors()
|
|
}
|
|
|
|
func makeColorFunc(code string) func(string) string {
|
|
return func(text string) string {
|
|
colorMu.RLock()
|
|
enabled := useColors
|
|
colorMu.RUnlock()
|
|
|
|
if enabled {
|
|
return code + text + resetCode
|
|
}
|
|
return text
|
|
}
|
|
}
|
|
|
|
// DetectShellColors checks if the current shell supports colors
|
|
func DetectShellColors() bool {
|
|
// Check NO_COLOR environment variable (standard)
|
|
if os.Getenv("NO_COLOR") != "" {
|
|
return false
|
|
}
|
|
|
|
// Check FORCE_COLOR environment variable
|
|
if os.Getenv("FORCE_COLOR") != "" {
|
|
return true
|
|
}
|
|
|
|
// Check if stdout is a terminal
|
|
if !isTerminal(os.Stdout) {
|
|
return false
|
|
}
|
|
|
|
// Check TERM environment variable
|
|
term := os.Getenv("TERM")
|
|
if term == "" || term == "dumb" {
|
|
return false
|
|
}
|
|
|
|
// Common color-supporting terminals
|
|
return strings.Contains(term, "color") ||
|
|
strings.Contains(term, "xterm") ||
|
|
strings.Contains(term, "screen") ||
|
|
strings.Contains(term, "tmux") ||
|
|
term == "linux" ||
|
|
isWindowsTerminal()
|
|
}
|
|
|
|
// SetColors enables or disables colors globally
|
|
func SetColors(enabled bool) {
|
|
colorMu.Lock()
|
|
useColors = enabled
|
|
colorMu.Unlock()
|
|
}
|
|
|
|
// ColorsEnabled returns current global color setting
|
|
func ColorsEnabled() bool {
|
|
colorMu.RLock()
|
|
defer colorMu.RUnlock()
|
|
return useColors
|
|
}
|