-
Notifications
You must be signed in to change notification settings - Fork 11
/
colorscheme.go
241 lines (216 loc) · 8.85 KB
/
colorscheme.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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
package femto
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/gdamore/tcell/v2"
)
// Colorscheme is a map from string to style -- it represents a colorscheme
type Colorscheme map[string]tcell.Style
// The current default colorscheme
var colorscheme Colorscheme
// The default cell style
var defStyle tcell.Style
// GetColor takes in a syntax group and returns the colorscheme's style for that group
func GetColor(color string) tcell.Style {
return colorscheme.GetColor(color)
}
// GetColor takes in a syntax group and returns the colorscheme's style for that group
func (colorscheme Colorscheme) GetColor(color string) tcell.Style {
st := defStyle
if color == "" {
return st
}
groups := strings.Split(color, ".")
if len(groups) > 1 {
curGroup := ""
for i, g := range groups {
if i != 0 {
curGroup += "."
}
curGroup += g
if style, ok := colorscheme[curGroup]; ok {
st = style
}
}
} else if style, ok := colorscheme[color]; ok {
st = style
} else {
st = StringToStyle(color)
}
return st
}
// init picks and initializes the colorscheme when micro starts
func init() {
colorscheme = make(Colorscheme)
defStyle = tcell.StyleDefault.
Foreground(tcell.ColorDefault).
Background(tcell.ColorDefault)
}
// SetDefaultColorscheme sets the current default colorscheme for new Views.
func SetDefaultColorscheme(scheme Colorscheme) {
colorscheme = scheme
}
// ParseColorscheme parses the text definition for a colorscheme and returns the corresponding object
// Colorschemes are made up of color-link statements linking a color group to a list of colors
// For example, color-link keyword (blue,red) makes all keywords have a blue foreground and
// red background
func ParseColorscheme(text string) Colorscheme {
parser := regexp.MustCompile(`color-link\s+(\S*)\s+"(.*)"`)
lines := strings.Split(text, "\n")
c := make(Colorscheme)
for _, line := range lines {
if strings.TrimSpace(line) == "" ||
strings.TrimSpace(line)[0] == '#' {
// Ignore this line
continue
}
matches := parser.FindSubmatch([]byte(line))
if len(matches) == 3 {
link := string(matches[1])
colors := string(matches[2])
style := StringToStyle(colors)
c[link] = style
if link == "default" {
defStyle = style
}
} else {
fmt.Println("Color-link statement is not valid:", line)
}
}
return c
}
// StringToStyle returns a style from a string
// The strings must be in the format "extra foregroundcolor,backgroundcolor"
// The 'extra' can be bold, reverse, or underline
func StringToStyle(str string) tcell.Style {
var fg, bg string
spaceSplit := strings.Split(str, " ")
var split []string
if len(spaceSplit) > 1 {
split = strings.Split(spaceSplit[1], ",")
} else {
split = strings.Split(str, ",")
}
if len(split) > 1 {
fg, bg = split[0], split[1]
} else {
fg = split[0]
}
fg = strings.TrimSpace(fg)
bg = strings.TrimSpace(bg)
var fgColor, bgColor tcell.Color
if fg == "" {
fgColor, _, _ = defStyle.Decompose()
} else {
fgColor = StringToColor(fg)
}
if bg == "" {
_, bgColor, _ = defStyle.Decompose()
} else {
bgColor = StringToColor(bg)
}
style := defStyle.Foreground(fgColor).Background(bgColor)
if strings.Contains(str, "bold") {
style = style.Bold(true)
}
if strings.Contains(str, "reverse") {
style = style.Reverse(true)
}
if strings.Contains(str, "underline") {
style = style.Underline(true)
}
return style
}
// StringToColor returns a tcell color from a string representation of a color
// We accept either bright... or light... to mean the brighter version of a color
func StringToColor(str string) tcell.Color {
switch str {
case "black":
return tcell.ColorBlack
case "red":
return tcell.ColorMaroon
case "green":
return tcell.ColorGreen
case "yellow":
return tcell.ColorOlive
case "blue":
return tcell.ColorNavy
case "magenta":
return tcell.ColorPurple
case "cyan":
return tcell.ColorTeal
case "white":
return tcell.ColorSilver
case "brightblack", "lightblack":
return tcell.ColorGray
case "brightred", "lightred":
return tcell.ColorRed
case "brightgreen", "lightgreen":
return tcell.ColorLime
case "brightyellow", "lightyellow":
return tcell.ColorYellow
case "brightblue", "lightblue":
return tcell.ColorBlue
case "brightmagenta", "lightmagenta":
return tcell.ColorFuchsia
case "brightcyan", "lightcyan":
return tcell.ColorAqua
case "brightwhite", "lightwhite":
return tcell.ColorWhite
case "default":
return tcell.ColorDefault
default:
// Check if this is a 256 color
if num, err := strconv.Atoi(str); err == nil {
return GetColor256(num)
}
// Probably a truecolor hex value
return tcell.GetColor(str)
}
}
// GetColor256 returns the tcell color for a number between 0 and 255
func GetColor256(color int) tcell.Color {
colors := []tcell.Color{tcell.ColorBlack, tcell.ColorMaroon, tcell.ColorGreen,
tcell.ColorOlive, tcell.ColorNavy, tcell.ColorPurple,
tcell.ColorTeal, tcell.ColorSilver, tcell.ColorGray,
tcell.ColorRed, tcell.ColorLime, tcell.ColorYellow,
tcell.ColorBlue, tcell.ColorFuchsia, tcell.ColorAqua,
tcell.ColorWhite, tcell.Color16, tcell.Color17, tcell.Color18, tcell.Color19, tcell.Color20,
tcell.Color21, tcell.Color22, tcell.Color23, tcell.Color24, tcell.Color25, tcell.Color26, tcell.Color27, tcell.Color28,
tcell.Color29, tcell.Color30, tcell.Color31, tcell.Color32, tcell.Color33, tcell.Color34, tcell.Color35, tcell.Color36,
tcell.Color37, tcell.Color38, tcell.Color39, tcell.Color40, tcell.Color41, tcell.Color42, tcell.Color43, tcell.Color44,
tcell.Color45, tcell.Color46, tcell.Color47, tcell.Color48, tcell.Color49, tcell.Color50, tcell.Color51, tcell.Color52,
tcell.Color53, tcell.Color54, tcell.Color55, tcell.Color56, tcell.Color57, tcell.Color58, tcell.Color59, tcell.Color60,
tcell.Color61, tcell.Color62, tcell.Color63, tcell.Color64, tcell.Color65, tcell.Color66, tcell.Color67, tcell.Color68,
tcell.Color69, tcell.Color70, tcell.Color71, tcell.Color72, tcell.Color73, tcell.Color74, tcell.Color75, tcell.Color76,
tcell.Color77, tcell.Color78, tcell.Color79, tcell.Color80, tcell.Color81, tcell.Color82, tcell.Color83, tcell.Color84,
tcell.Color85, tcell.Color86, tcell.Color87, tcell.Color88, tcell.Color89, tcell.Color90, tcell.Color91, tcell.Color92,
tcell.Color93, tcell.Color94, tcell.Color95, tcell.Color96, tcell.Color97, tcell.Color98, tcell.Color99, tcell.Color100,
tcell.Color101, tcell.Color102, tcell.Color103, tcell.Color104, tcell.Color105, tcell.Color106, tcell.Color107, tcell.Color108,
tcell.Color109, tcell.Color110, tcell.Color111, tcell.Color112, tcell.Color113, tcell.Color114, tcell.Color115, tcell.Color116,
tcell.Color117, tcell.Color118, tcell.Color119, tcell.Color120, tcell.Color121, tcell.Color122, tcell.Color123, tcell.Color124,
tcell.Color125, tcell.Color126, tcell.Color127, tcell.Color128, tcell.Color129, tcell.Color130, tcell.Color131, tcell.Color132,
tcell.Color133, tcell.Color134, tcell.Color135, tcell.Color136, tcell.Color137, tcell.Color138, tcell.Color139, tcell.Color140,
tcell.Color141, tcell.Color142, tcell.Color143, tcell.Color144, tcell.Color145, tcell.Color146, tcell.Color147, tcell.Color148,
tcell.Color149, tcell.Color150, tcell.Color151, tcell.Color152, tcell.Color153, tcell.Color154, tcell.Color155, tcell.Color156,
tcell.Color157, tcell.Color158, tcell.Color159, tcell.Color160, tcell.Color161, tcell.Color162, tcell.Color163, tcell.Color164,
tcell.Color165, tcell.Color166, tcell.Color167, tcell.Color168, tcell.Color169, tcell.Color170, tcell.Color171, tcell.Color172,
tcell.Color173, tcell.Color174, tcell.Color175, tcell.Color176, tcell.Color177, tcell.Color178, tcell.Color179, tcell.Color180,
tcell.Color181, tcell.Color182, tcell.Color183, tcell.Color184, tcell.Color185, tcell.Color186, tcell.Color187, tcell.Color188,
tcell.Color189, tcell.Color190, tcell.Color191, tcell.Color192, tcell.Color193, tcell.Color194, tcell.Color195, tcell.Color196,
tcell.Color197, tcell.Color198, tcell.Color199, tcell.Color200, tcell.Color201, tcell.Color202, tcell.Color203, tcell.Color204,
tcell.Color205, tcell.Color206, tcell.Color207, tcell.Color208, tcell.Color209, tcell.Color210, tcell.Color211, tcell.Color212,
tcell.Color213, tcell.Color214, tcell.Color215, tcell.Color216, tcell.Color217, tcell.Color218, tcell.Color219, tcell.Color220,
tcell.Color221, tcell.Color222, tcell.Color223, tcell.Color224, tcell.Color225, tcell.Color226, tcell.Color227, tcell.Color228,
tcell.Color229, tcell.Color230, tcell.Color231, tcell.Color232, tcell.Color233, tcell.Color234, tcell.Color235, tcell.Color236,
tcell.Color237, tcell.Color238, tcell.Color239, tcell.Color240, tcell.Color241, tcell.Color242, tcell.Color243, tcell.Color244,
tcell.Color245, tcell.Color246, tcell.Color247, tcell.Color248, tcell.Color249, tcell.Color250, tcell.Color251, tcell.Color252,
tcell.Color253, tcell.Color254, tcell.Color255,
}
if color >= 0 && color < len(colors) {
return colors[color]
}
return tcell.ColorDefault
}