github.com/elves/elvish@v0.15.0/pkg/ui/color.go (about)

     1  package ui
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  )
     8  
     9  // Color represents a color.
    10  type Color interface {
    11  	fgSGR() string
    12  	bgSGR() string
    13  	String() string
    14  }
    15  
    16  // Builtin ANSI colors.
    17  var (
    18  	Black   Color = ansiColor(0)
    19  	Red     Color = ansiColor(1)
    20  	Green   Color = ansiColor(2)
    21  	Yellow  Color = ansiColor(3)
    22  	Blue    Color = ansiColor(4)
    23  	Magenta Color = ansiColor(5)
    24  	Cyan    Color = ansiColor(6)
    25  	White   Color = ansiColor(7)
    26  
    27  	BrightBlack   Color = ansiBrightColor(0)
    28  	BrightRed     Color = ansiBrightColor(1)
    29  	BrightGreen   Color = ansiBrightColor(2)
    30  	BrightYellow  Color = ansiBrightColor(3)
    31  	BrightBlue    Color = ansiBrightColor(4)
    32  	BrightMagenta Color = ansiBrightColor(5)
    33  	BrightCyan    Color = ansiBrightColor(6)
    34  	BrightWhite   Color = ansiBrightColor(7)
    35  )
    36  
    37  // XTerm256Color returns a color from the xterm 256-color palette.
    38  func XTerm256Color(i uint8) Color { return xterm256Color(i) }
    39  
    40  // TrueColor returns a 24-bit true color.
    41  func TrueColor(r, g, b uint8) Color { return trueColor{r, g, b} }
    42  
    43  var colorNames = []string{
    44  	"black", "red", "green", "yellow",
    45  	"blue", "magenta", "cyan", "white",
    46  }
    47  
    48  var colorByName = map[string]Color{
    49  	"black":   Black,
    50  	"red":     Red,
    51  	"green":   Green,
    52  	"yellow":  Yellow,
    53  	"blue":    Blue,
    54  	"magenta": Magenta,
    55  	"cyan":    Cyan,
    56  	"white":   White,
    57  
    58  	"bright-black":   BrightBlack,
    59  	"bright-red":     BrightRed,
    60  	"bright-green":   BrightGreen,
    61  	"bright-yellow":  BrightYellow,
    62  	"bright-blue":    BrightBlue,
    63  	"bright-magenta": BrightMagenta,
    64  	"bright-cyan":    BrightCyan,
    65  	"bright-white":   BrightWhite,
    66  }
    67  
    68  type ansiColor uint8
    69  
    70  func (c ansiColor) fgSGR() string  { return strconv.Itoa(30 + int(c)) }
    71  func (c ansiColor) bgSGR() string  { return strconv.Itoa(40 + int(c)) }
    72  func (c ansiColor) String() string { return colorNames[c] }
    73  
    74  type ansiBrightColor uint8
    75  
    76  func (c ansiBrightColor) fgSGR() string  { return strconv.Itoa(90 + int(c)) }
    77  func (c ansiBrightColor) bgSGR() string  { return strconv.Itoa(100 + int(c)) }
    78  func (c ansiBrightColor) String() string { return "bright-" + colorNames[c] }
    79  
    80  type xterm256Color uint8
    81  
    82  func (c xterm256Color) fgSGR() string  { return "38;5;" + strconv.Itoa(int(c)) }
    83  func (c xterm256Color) bgSGR() string  { return "48;5;" + strconv.Itoa(int(c)) }
    84  func (c xterm256Color) String() string { return "color" + strconv.Itoa(int(c)) }
    85  
    86  type trueColor struct{ r, g, b uint8 }
    87  
    88  func (c trueColor) fgSGR() string { return "38;2;" + c.rgbSGR() }
    89  func (c trueColor) bgSGR() string { return "48;2;" + c.rgbSGR() }
    90  
    91  func (c trueColor) String() string {
    92  	return fmt.Sprintf("#%02x%02x%02x", c.r, c.g, c.b)
    93  }
    94  
    95  func (c trueColor) rgbSGR() string {
    96  	return fmt.Sprintf("%d;%d;%d", c.r, c.g, c.b)
    97  }
    98  
    99  func parseColor(name string) Color {
   100  	if color, ok := colorByName[name]; ok {
   101  		return color
   102  	}
   103  	if strings.HasPrefix(name, "color") {
   104  		i, err := strconv.Atoi(name[5:])
   105  		if err == nil && 0 <= i && i < 256 {
   106  			return XTerm256Color(uint8(i))
   107  		}
   108  	} else if strings.HasPrefix(name, "#") && len(name) == 7 {
   109  		r, rErr := strconv.ParseUint(name[1:3], 16, 8)
   110  		g, gErr := strconv.ParseUint(name[3:5], 16, 8)
   111  		b, bErr := strconv.ParseUint(name[5:7], 16, 8)
   112  		if rErr == nil && gErr == nil && bErr == nil {
   113  			return TrueColor(uint8(r), uint8(g), uint8(b))
   114  		}
   115  	}
   116  	return nil
   117  }