forked from codeskyblue/gobuild
-
Notifications
You must be signed in to change notification settings - Fork 0
/
color.go
102 lines (88 loc) · 2.54 KB
/
color.go
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
package color
const (
pre = "\033["
post = ``
reset = "\033[0m"
)
// Paint is a color to paint, either as a foreground or background paint
type Paint string
// Valid colors for ANSI terminals
const (
BlackPaint Paint = `0;30`
DarkRedPaint Paint = `0;31`
DarkGreenPaint Paint = `0;32`
DarkYellowPaint Paint = `0;33`
DarkBluePaint Paint = `0;34`
DarkPurplePaint Paint = `0;35`
DarkCyanPaint Paint = `0;36`
LightGrayPaint Paint = `0;37`
DarkGrayPaint Paint = `1;30`
RedPaint Paint = `1;31`
GreenPaint Paint = `1;32`
YellowPaint Paint = `1;33`
BluePaint Paint = `1;34`
PurplePaint Paint = `1;35`
CyanPaint Paint = `1;36`
WhitePaint Paint = `1;37`
)
// Brush is a function that let's you colorize strings directly.
type Brush func(string) string
// NewBrush gives you a brush that you can invoke directly to create colorized
// strings
func NewBrush(background, foreground Paint) Brush {
return NewStyle(background, foreground).Brush()
}
// Style will give you colorized strings. Styles are immutable.
type Style struct {
bg Paint
fg Paint
code string
}
// NewStyle gives you a style ready to produce strings with the given
// background and foreground colors
func NewStyle(background, foreground Paint) Style {
bg := background
fg := foreground
return Style{
bg,
fg,
computeColorCode(bg, fg),
}
}
// Brush is a function that can be used to color things directly, i.e:
//
// red := NewStyle(BlackPaint, RedPaint).Brush()
// fmt.Printf("This is %s\n", red("red"))
func (s Style) Brush() Brush {
return func(text string) string {
return s.code + text + reset
}
}
// WithBackground copies the current style and return a new Style that
// has the desired background. The original Style is unchanged and you
// must capture the return value.
func (s Style) WithBackground(color Paint) Style {
newS := s
newS.bg = color
newS.code = computeColorCode(newS.bg, newS.fg)
return newS
}
// WithForeground copies the current style and return a new Style that
// has the desired foreground. The original Style is unchanged and you
// must capture the return value.
func (s Style) WithForeground(color Paint) Style {
newS := s
newS.fg = color
newS.code = computeColorCode(newS.bg, newS.fg)
return newS
}
func computeColorCode(bg, fg Paint) string {
if bg == "" {
return pre + string(fg) + "m" + post
}
// The background code is the last color code prefixed by 4
bgColor := bg[len(bg)-1]
back := pre + "4" + string(bgColor) + "m" + post
front := pre + string(fg) + "m" + post
return back + front
}