File: color.go

package info (click to toggle)
elvish 0.21.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,372 kB
  • sloc: javascript: 236; sh: 130; python: 104; makefile: 88; xml: 9
file content (117 lines) | stat: -rw-r--r-- 3,242 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package ui

import (
	"fmt"
	"strconv"
	"strings"
)

// Color represents a color.
type Color interface {
	fgSGR() string
	bgSGR() string
	String() string
}

// Builtin ANSI colors.
var (
	Black   Color = ansiColor(0)
	Red     Color = ansiColor(1)
	Green   Color = ansiColor(2)
	Yellow  Color = ansiColor(3)
	Blue    Color = ansiColor(4)
	Magenta Color = ansiColor(5)
	Cyan    Color = ansiColor(6)
	White   Color = ansiColor(7)

	BrightBlack   Color = ansiBrightColor(0)
	BrightRed     Color = ansiBrightColor(1)
	BrightGreen   Color = ansiBrightColor(2)
	BrightYellow  Color = ansiBrightColor(3)
	BrightBlue    Color = ansiBrightColor(4)
	BrightMagenta Color = ansiBrightColor(5)
	BrightCyan    Color = ansiBrightColor(6)
	BrightWhite   Color = ansiBrightColor(7)
)

// XTerm256Color returns a color from the xterm 256-color palette.
func XTerm256Color(i uint8) Color { return xterm256Color(i) }

// TrueColor returns a 24-bit true color.
func TrueColor(r, g, b uint8) Color { return trueColor{r, g, b} }

var colorNames = []string{
	"black", "red", "green", "yellow",
	"blue", "magenta", "cyan", "white",
}

var colorByName = map[string]Color{
	"black":   Black,
	"red":     Red,
	"green":   Green,
	"yellow":  Yellow,
	"blue":    Blue,
	"magenta": Magenta,
	"cyan":    Cyan,
	"white":   White,

	"bright-black":   BrightBlack,
	"bright-red":     BrightRed,
	"bright-green":   BrightGreen,
	"bright-yellow":  BrightYellow,
	"bright-blue":    BrightBlue,
	"bright-magenta": BrightMagenta,
	"bright-cyan":    BrightCyan,
	"bright-white":   BrightWhite,
}

type ansiColor uint8

func (c ansiColor) fgSGR() string  { return strconv.Itoa(30 + int(c)) }
func (c ansiColor) bgSGR() string  { return strconv.Itoa(40 + int(c)) }
func (c ansiColor) String() string { return colorNames[c] }

type ansiBrightColor uint8

func (c ansiBrightColor) fgSGR() string  { return strconv.Itoa(90 + int(c)) }
func (c ansiBrightColor) bgSGR() string  { return strconv.Itoa(100 + int(c)) }
func (c ansiBrightColor) String() string { return "bright-" + colorNames[c] }

type xterm256Color uint8

func (c xterm256Color) fgSGR() string  { return "38;5;" + strconv.Itoa(int(c)) }
func (c xterm256Color) bgSGR() string  { return "48;5;" + strconv.Itoa(int(c)) }
func (c xterm256Color) String() string { return "color" + strconv.Itoa(int(c)) }

type trueColor struct{ R, G, B uint8 }

func (c trueColor) fgSGR() string { return "38;2;" + c.rgbSGR() }
func (c trueColor) bgSGR() string { return "48;2;" + c.rgbSGR() }

func (c trueColor) String() string {
	return fmt.Sprintf("#%02x%02x%02x", c.R, c.G, c.B)
}

func (c trueColor) rgbSGR() string {
	return fmt.Sprintf("%d;%d;%d", c.R, c.G, c.B)
}

func parseColor(name string) Color {
	if color, ok := colorByName[name]; ok {
		return color
	}
	if strings.HasPrefix(name, "color") {
		i, err := strconv.Atoi(name[5:])
		if err == nil && 0 <= i && i < 256 {
			return XTerm256Color(uint8(i))
		}
	} else if strings.HasPrefix(name, "#") && len(name) == 7 {
		r, rErr := strconv.ParseUint(name[1:3], 16, 8)
		g, gErr := strconv.ParseUint(name[3:5], 16, 8)
		b, bErr := strconv.ParseUint(name[5:7], 16, 8)
		if rErr == nil && gErr == nil && bErr == nil {
			return TrueColor(uint8(r), uint8(g), uint8(b))
		}
	}
	return nil
}