diff --git a/README.md b/README.md index c11fb4b5..f42bdae2 100644 --- a/README.md +++ b/README.md @@ -415,6 +415,30 @@ Flags: Use "yq [command] --help" for more information about a command. ``` + +## Environment Variables + +### Color Customization + +You can customize the colors used in YAML output by setting these environment variables: + +- `YQ_COLOR_BOOL` - Color for boolean values (default: hi-magenta) +- `YQ_COLOR_NUMBER` - Color for numeric values (default: hi-magenta) +- `YQ_COLOR_MAP_KEY` - Color for map keys (default: cyan) +- `YQ_COLOR_ANCHOR` - Color for YAML anchors (default: hi-yellow) +- `YQ_COLOR_ALIAS` - Color for YAML aliases (default: hi-yellow) +- `YQ_COLOR_STRING` - Color for string values (default: green) +- `YQ_COLOR_COMMENT` - Color for comments (default: hi-black) + +Supported color values: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, and their `hi-` prefixed variants (e.g., `hi-red`). Numeric color codes are also supported. + +Example: +```bash +export YQ_COLOR_STRING=red +export YQ_COLOR_MAP_KEY=hi-blue +yq -C '.data' file.yaml +``` + ## Known Issues / Missing Features - `yq` attempts to preserve comment positions and whitespace as much as possible, but it does not handle all scenarios (see https://github.com/go-yaml/yaml/tree/v3 for details) - Powershell has its own...[opinions on quoting yq](https://mikefarah.gitbook.io/yq/usage/tips-and-tricks#quotes-in-windows-powershell) diff --git a/pkg/yqlib/color_config.go b/pkg/yqlib/color_config.go new file mode 100644 index 00000000..73120a15 --- /dev/null +++ b/pkg/yqlib/color_config.go @@ -0,0 +1,117 @@ +package yqlib + +import ( + "fmt" + "os" + "strconv" + + "github.com/fatih/color" +) + +type ColorConfig struct { + BoolColor color.Attribute + NumberColor color.Attribute + MapKeyColor color.Attribute + AnchorColor color.Attribute + AliasColor color.Attribute + StringColor color.Attribute + CommentColor color.Attribute +} + +func NewColorConfig() *ColorConfig { + config := &ColorConfig{ + BoolColor: color.FgHiMagenta, + NumberColor: color.FgHiMagenta, + MapKeyColor: color.FgCyan, + AnchorColor: color.FgHiYellow, + AliasColor: color.FgHiYellow, + StringColor: color.FgGreen, + CommentColor: color.FgHiBlack, + } + + if colorStr := os.Getenv("YQ_COLOR_BOOL"); colorStr != "" { + if attr, err := parseColorAttribute(colorStr); err == nil { + config.BoolColor = attr + } + } + + if colorStr := os.Getenv("YQ_COLOR_NUMBER"); colorStr != "" { + if attr, err := parseColorAttribute(colorStr); err == nil { + config.NumberColor = attr + } + } + + if colorStr := os.Getenv("YQ_COLOR_MAP_KEY"); colorStr != "" { + if attr, err := parseColorAttribute(colorStr); err == nil { + config.MapKeyColor = attr + } + } + + if colorStr := os.Getenv("YQ_COLOR_ANCHOR"); colorStr != "" { + if attr, err := parseColorAttribute(colorStr); err == nil { + config.AnchorColor = attr + } + } + + if colorStr := os.Getenv("YQ_COLOR_ALIAS"); colorStr != "" { + if attr, err := parseColorAttribute(colorStr); err == nil { + config.AliasColor = attr + } + } + + if colorStr := os.Getenv("YQ_COLOR_STRING"); colorStr != "" { + if attr, err := parseColorAttribute(colorStr); err == nil { + config.StringColor = attr + } + } + + if colorStr := os.Getenv("YQ_COLOR_COMMENT"); colorStr != "" { + if attr, err := parseColorAttribute(colorStr); err == nil { + config.CommentColor = attr + } + } + + return config +} + +func parseColorAttribute(colorStr string) (color.Attribute, error) { + switch colorStr { + case "black": + return color.FgBlack, nil + case "red": + return color.FgRed, nil + case "green": + return color.FgGreen, nil + case "yellow": + return color.FgYellow, nil + case "blue": + return color.FgBlue, nil + case "magenta": + return color.FgMagenta, nil + case "cyan": + return color.FgCyan, nil + case "white": + return color.FgWhite, nil + case "hi-black": + return color.FgHiBlack, nil + case "hi-red": + return color.FgHiRed, nil + case "hi-green": + return color.FgHiGreen, nil + case "hi-yellow": + return color.FgHiYellow, nil + case "hi-blue": + return color.FgHiBlue, nil + case "hi-magenta": + return color.FgHiMagenta, nil + case "hi-cyan": + return color.FgHiCyan, nil + case "hi-white": + return color.FgHiWhite, nil + default: + if num, err := strconv.Atoi(colorStr); err == nil { + return color.Attribute(num), nil + } + return color.Reset, fmt.Errorf("unknown color: %s", colorStr) + } +} diff --git a/pkg/yqlib/color_print.go b/pkg/yqlib/color_print.go index 51c0a45d..b0a1d219 100644 --- a/pkg/yqlib/color_print.go +++ b/pkg/yqlib/color_print.go @@ -19,46 +19,47 @@ func format(attr color.Attribute) string { func colorizeAndPrint(yamlBytes []byte, writer io.Writer) error { tokens := lexer.Tokenize(string(yamlBytes)) + config := NewColorConfig() var p printer.Printer p.Bool = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgHiMagenta), + Prefix: format(config.BoolColor), Suffix: format(color.Reset), } } p.Number = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgHiMagenta), + Prefix: format(config.NumberColor), Suffix: format(color.Reset), } } p.MapKey = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgCyan), + Prefix: format(config.MapKeyColor), Suffix: format(color.Reset), } } p.Anchor = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgHiYellow), + Prefix: format(config.AnchorColor), Suffix: format(color.Reset), } } p.Alias = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgHiYellow), + Prefix: format(config.AliasColor), Suffix: format(color.Reset), } } p.String = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgGreen), + Prefix: format(config.StringColor), Suffix: format(color.Reset), } } p.Comment = func() *printer.Property { return &printer.Property{ - Prefix: format(color.FgHiBlack), + Prefix: format(config.CommentColor), Suffix: format(color.Reset), } }