mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-09-17 00:29:57 +00:00
245 lines
7.4 KiB
Go
245 lines
7.4 KiB
Go
|
// colorstring provides functions for colorizing strings for terminal
|
||
|
// output.
|
||
|
package colorstring
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"regexp"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// Color colorizes your strings using the default settings.
|
||
|
//
|
||
|
// Strings given to Color should use the syntax `[color]` to specify the
|
||
|
// color for text following. For example: `[blue]Hello` will return "Hello"
|
||
|
// in blue. See DefaultColors for all the supported colors and attributes.
|
||
|
//
|
||
|
// If an unrecognized color is given, it is ignored and assumed to be part
|
||
|
// of the string. For example: `[hi]world` will result in "[hi]world".
|
||
|
//
|
||
|
// A color reset is appended to the end of every string. This will reset
|
||
|
// the color of following strings when you output this text to the same
|
||
|
// terminal session.
|
||
|
//
|
||
|
// If you want to customize any of this behavior, use the Colorize struct.
|
||
|
func Color(v string) string {
|
||
|
return def.Color(v)
|
||
|
}
|
||
|
|
||
|
// ColorPrefix returns the color sequence that prefixes the given text.
|
||
|
//
|
||
|
// This is useful when wrapping text if you want to inherit the color
|
||
|
// of the wrapped text. For example, "[green]foo" will return "[green]".
|
||
|
// If there is no color sequence, then this will return "".
|
||
|
func ColorPrefix(v string) string {
|
||
|
return def.ColorPrefix(v)
|
||
|
}
|
||
|
|
||
|
// Colorize colorizes your strings, giving you the ability to customize
|
||
|
// some of the colorization process.
|
||
|
//
|
||
|
// The options in Colorize can be set to customize colorization. If you're
|
||
|
// only interested in the defaults, just use the top Color function directly,
|
||
|
// which creates a default Colorize.
|
||
|
type Colorize struct {
|
||
|
// Colors maps a color string to the code for that color. The code
|
||
|
// is a string so that you can use more complex colors to set foreground,
|
||
|
// background, attributes, etc. For example, "boldblue" might be
|
||
|
// "1;34"
|
||
|
Colors map[string]string
|
||
|
|
||
|
// If true, color attributes will be ignored. This is useful if you're
|
||
|
// outputting to a location that doesn't support colors and you just
|
||
|
// want the strings returned.
|
||
|
Disable bool
|
||
|
|
||
|
// Reset, if true, will reset the color after each colorization by
|
||
|
// adding a reset code at the end.
|
||
|
Reset bool
|
||
|
}
|
||
|
|
||
|
// Color colorizes a string according to the settings setup in the struct.
|
||
|
//
|
||
|
// For more details on the syntax, see the top-level Color function.
|
||
|
func (c *Colorize) Color(v string) string {
|
||
|
matches := parseRe.FindAllStringIndex(v, -1)
|
||
|
if len(matches) == 0 {
|
||
|
return v
|
||
|
}
|
||
|
|
||
|
result := new(bytes.Buffer)
|
||
|
colored := false
|
||
|
m := []int{0, 0}
|
||
|
for _, nm := range matches {
|
||
|
// Write the text in between this match and the last
|
||
|
result.WriteString(v[m[1]:nm[0]])
|
||
|
m = nm
|
||
|
|
||
|
var replace string
|
||
|
if code, ok := c.Colors[v[m[0]+1:m[1]-1]]; ok {
|
||
|
colored = true
|
||
|
|
||
|
if !c.Disable {
|
||
|
replace = fmt.Sprintf("\033[%sm", code)
|
||
|
}
|
||
|
} else {
|
||
|
replace = v[m[0]:m[1]]
|
||
|
}
|
||
|
|
||
|
result.WriteString(replace)
|
||
|
}
|
||
|
result.WriteString(v[m[1]:])
|
||
|
|
||
|
if colored && c.Reset && !c.Disable {
|
||
|
// Write the clear byte at the end
|
||
|
result.WriteString("\033[0m")
|
||
|
}
|
||
|
|
||
|
return result.String()
|
||
|
}
|
||
|
|
||
|
// ColorPrefix returns the first color sequence that exists in this string.
|
||
|
//
|
||
|
// For example: "[green]foo" would return "[green]". If no color sequence
|
||
|
// exists, then "" is returned. This is especially useful when wrapping
|
||
|
// colored texts to inherit the color of the wrapped text.
|
||
|
func (c *Colorize) ColorPrefix(v string) string {
|
||
|
return prefixRe.FindString(strings.TrimSpace(v))
|
||
|
}
|
||
|
|
||
|
// DefaultColors are the default colors used when colorizing.
|
||
|
//
|
||
|
// If the color is surrounded in underscores, such as "_blue_", then that
|
||
|
// color will be used for the background color.
|
||
|
var DefaultColors map[string]string
|
||
|
|
||
|
func init() {
|
||
|
DefaultColors = map[string]string{
|
||
|
// Default foreground/background colors
|
||
|
"default": "39",
|
||
|
"_default_": "49",
|
||
|
|
||
|
// Foreground colors
|
||
|
"black": "30",
|
||
|
"red": "31",
|
||
|
"green": "32",
|
||
|
"yellow": "33",
|
||
|
"blue": "34",
|
||
|
"magenta": "35",
|
||
|
"cyan": "36",
|
||
|
"light_gray": "37",
|
||
|
"dark_gray": "90",
|
||
|
"light_red": "91",
|
||
|
"light_green": "92",
|
||
|
"light_yellow": "93",
|
||
|
"light_blue": "94",
|
||
|
"light_magenta": "95",
|
||
|
"light_cyan": "96",
|
||
|
"white": "97",
|
||
|
|
||
|
// Background colors
|
||
|
"_black_": "40",
|
||
|
"_red_": "41",
|
||
|
"_green_": "42",
|
||
|
"_yellow_": "43",
|
||
|
"_blue_": "44",
|
||
|
"_magenta_": "45",
|
||
|
"_cyan_": "46",
|
||
|
"_light_gray_": "47",
|
||
|
"_dark_gray_": "100",
|
||
|
"_light_red_": "101",
|
||
|
"_light_green_": "102",
|
||
|
"_light_yellow_": "103",
|
||
|
"_light_blue_": "104",
|
||
|
"_light_magenta_": "105",
|
||
|
"_light_cyan_": "106",
|
||
|
"_white_": "107",
|
||
|
|
||
|
// Attributes
|
||
|
"bold": "1",
|
||
|
"dim": "2",
|
||
|
"underline": "4",
|
||
|
"blink_slow": "5",
|
||
|
"blink_fast": "6",
|
||
|
"invert": "7",
|
||
|
"hidden": "8",
|
||
|
|
||
|
// Reset to reset everything to their defaults
|
||
|
"reset": "0",
|
||
|
"reset_bold": "21",
|
||
|
}
|
||
|
|
||
|
def = Colorize{
|
||
|
Colors: DefaultColors,
|
||
|
Reset: true,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var def Colorize
|
||
|
var parseReRaw = `\[[a-z0-9_-]+\]`
|
||
|
var parseRe = regexp.MustCompile(`(?i)` + parseReRaw)
|
||
|
var prefixRe = regexp.MustCompile(`^(?i)(` + parseReRaw + `)+`)
|
||
|
|
||
|
// Print is a convenience wrapper for fmt.Print with support for color codes.
|
||
|
//
|
||
|
// Print formats using the default formats for its operands and writes to
|
||
|
// standard output with support for color codes. Spaces are added between
|
||
|
// operands when neither is a string. It returns the number of bytes written
|
||
|
// and any write error encountered.
|
||
|
func Print(a string) (n int, err error) {
|
||
|
return fmt.Print(Color(a))
|
||
|
}
|
||
|
|
||
|
// Println is a convenience wrapper for fmt.Println with support for color
|
||
|
// codes.
|
||
|
//
|
||
|
// Println formats using the default formats for its operands and writes to
|
||
|
// standard output with support for color codes. Spaces are always added
|
||
|
// between operands and a newline is appended. It returns the number of bytes
|
||
|
// written and any write error encountered.
|
||
|
func Println(a string) (n int, err error) {
|
||
|
return fmt.Println(Color(a))
|
||
|
}
|
||
|
|
||
|
// Printf is a convenience wrapper for fmt.Printf with support for color codes.
|
||
|
//
|
||
|
// Printf formats according to a format specifier and writes to standard output
|
||
|
// with support for color codes. It returns the number of bytes written and any
|
||
|
// write error encountered.
|
||
|
func Printf(format string, a ...interface{}) (n int, err error) {
|
||
|
return fmt.Printf(Color(format), a...)
|
||
|
}
|
||
|
|
||
|
// Fprint is a convenience wrapper for fmt.Fprint with support for color codes.
|
||
|
//
|
||
|
// Fprint formats using the default formats for its operands and writes to w
|
||
|
// with support for color codes. Spaces are added between operands when neither
|
||
|
// is a string. It returns the number of bytes written and any write error
|
||
|
// encountered.
|
||
|
func Fprint(w io.Writer, a string) (n int, err error) {
|
||
|
return fmt.Fprint(w, Color(a))
|
||
|
}
|
||
|
|
||
|
// Fprintln is a convenience wrapper for fmt.Fprintln with support for color
|
||
|
// codes.
|
||
|
//
|
||
|
// Fprintln formats using the default formats for its operands and writes to w
|
||
|
// with support for color codes. Spaces are always added between operands and a
|
||
|
// newline is appended. It returns the number of bytes written and any write
|
||
|
// error encountered.
|
||
|
func Fprintln(w io.Writer, a string) (n int, err error) {
|
||
|
return fmt.Fprintln(w, Color(a))
|
||
|
}
|
||
|
|
||
|
// Fprintf is a convenience wrapper for fmt.Fprintf with support for color
|
||
|
// codes.
|
||
|
//
|
||
|
// Fprintf formats according to a format specifier and writes to w with support
|
||
|
// for color codes. It returns the number of bytes written and any write error
|
||
|
// encountered.
|
||
|
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||
|
return fmt.Fprintf(w, Color(format), a...)
|
||
|
}
|