-
Notifications
You must be signed in to change notification settings - Fork 1
/
color.go
155 lines (134 loc) · 2.56 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Package color can be used to add color to your terminal using ANSI escape code (or sequences).
//
// See https://en.wikipedia.org/wiki/ANSI_escape_code
// Copy modified from https://github.com/fatih/color
// Copyright 2013 Fatih Arslan
package color
import (
"fmt"
"strconv"
"strings"
)
// Attribute defines a single SGR (Select Graphic Rendition) code.
type Attribute int
// Base attributes
const (
Reset Attribute = iota
Bold
Faint
Italic
Underline
BlinkSlow
BlinkRapid
ReverseVideo
Concealed
CrossedOut
)
// Foreground text colors
const (
FgBlack Attribute = iota + 30
FgRed
FgGreen
FgYellow
FgBlue
FgMagenta
FgCyan
FgWhite
)
// Foreground Hi-Intensity text colors
const (
FgHiBlack Attribute = iota + 90
FgHiRed
FgHiGreen
FgHiYellow
FgHiBlue
FgHiMagenta
FgHiCyan
FgHiWhite
)
// Background text colors
const (
BgBlack Attribute = iota + 40
BgRed
BgGreen
BgYellow
BgBlue
BgMagenta
BgCyan
BgWhite
)
// Background Hi-Intensity text colors
const (
BgHiBlack Attribute = iota + 100
BgHiRed
BgHiGreen
BgHiYellow
BgHiBlue
BgHiMagenta
BgHiCyan
BgHiWhite
)
const (
escape = "\x1b"
unescape = "\\x1b"
)
// Format text for terminal.
func Format(s ...interface{}) string {
if len(s) == 0 {
return ""
}
out := make([]interface{}, 0)
params := []Attribute{}
in := -1
for i, v := range s {
switch vt := v.(type) {
case []Attribute:
params = append(params, vt...)
case Attribute:
params = append(params, vt)
default:
in = i
goto over
}
}
over:
if in != -1 {
out = s[in:]
}
if len(out) == 0 {
return ""
}
return wrap(params, sprintf(out...))
}
// StripAttributes from input arguments and return unformatted text.
func StripAttributes(s ...interface{}) (raw string) {
for k, v := range s {
switch v.(type) {
case []Attribute, Attribute:
default:
return sprintf(s[k:]...)
}
}
return
}
// Escape text for terminal.
func Escape(s string) string {
return strings.Replace(s, escape, unescape, -1)
}
func sprintf(s ...interface{}) string {
format := s[0]
return fmt.Sprintf(fmt.Sprintf("%v", format), s[1:]...)
}
// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m"
// an example output might be: "1;36" -> bold cyan.
func sequence(params []Attribute) string {
format := make([]string, len(params))
for i, v := range params {
format[i] = strconv.Itoa(int(v))
}
return strings.Join(format, ";")
}
// wrap the s string with the colors attributes.
func wrap(params []Attribute, s string) string {
return fmt.Sprintf("%s[%sm%s%s[%dm", escape, sequence(params), s, escape, Reset)
}