Moonshark/utils/color/color.go
2025-05-31 09:11:21 -05:00

98 lines
2.1 KiB
Go

package color
import (
"os"
"strings"
"syscall"
"unsafe"
)
const ioctlReadTermios = 0x5401
// 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 = true
// 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 makeColorFunc(code string) func(string) string {
return func(text string) string {
if useColors {
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"
}
// SetColors enables or disables colors globally
func SetColors(enabled bool) {
useColors = enabled
}
// ColorsEnabled returns current global color setting
func ColorsEnabled() bool {
return useColors
}
// isTerminal checks if the file is a terminal
func isTerminal(f *os.File) bool {
fd := f.Fd()
var termios syscall.Termios
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
return err == 0
}