9 "github.com/zyedidia/tcell"
12 // Micro's default style
13 var DefStyle tcell.Style = tcell.StyleDefault
15 // The current colorscheme
16 var Colorscheme map[string]tcell.Style
18 // GetColor takes in a syntax group and returns the colorscheme's style for that group
19 func GetColor(color string) tcell.Style {
24 groups := strings.Split(color, ".")
27 for i, g := range groups {
32 if style, ok := Colorscheme[curGroup]; ok {
36 } else if style, ok := Colorscheme[color]; ok {
39 st = StringToStyle(color)
45 // ColorschemeExists checks if a given colorscheme exists
46 func ColorschemeExists(colorschemeName string) bool {
47 return FindRuntimeFile(RTColorscheme, colorschemeName) != nil
50 // InitColorscheme picks and initializes the colorscheme when micro starts
51 func InitColorscheme() error {
52 Colorscheme = make(map[string]tcell.Style)
53 DefStyle = tcell.StyleDefault
55 return LoadDefaultColorscheme()
58 // LoadDefaultColorscheme loads the default colorscheme from $(ConfigDir)/colorschemes
59 func LoadDefaultColorscheme() error {
60 return LoadColorscheme(GlobalSettings["colorscheme"].(string))
63 // LoadColorscheme loads the given colorscheme from a directory
64 func LoadColorscheme(colorschemeName string) error {
65 file := FindRuntimeFile(RTColorscheme, colorschemeName)
67 return errors.New(colorschemeName + " is not a valid colorscheme")
69 if data, err := file.Data(); err != nil {
70 return errors.New("Error loading colorscheme: " + err.Error())
72 Colorscheme, err = ParseColorscheme(string(data))
80 // ParseColorscheme parses the text definition for a colorscheme and returns the corresponding object
81 // Colorschemes are made up of color-link statements linking a color group to a list of colors
82 // For example, color-link keyword (blue,red) makes all keywords have a blue foreground and
84 func ParseColorscheme(text string) (map[string]tcell.Style, error) {
86 parser := regexp.MustCompile(`color-link\s+(\S*)\s+"(.*)"`)
88 lines := strings.Split(text, "\n")
90 c := make(map[string]tcell.Style)
92 for _, line := range lines {
93 if strings.TrimSpace(line) == "" ||
94 strings.TrimSpace(line)[0] == '#' {
99 matches := parser.FindSubmatch([]byte(line))
100 if len(matches) == 3 {
101 link := string(matches[1])
102 colors := string(matches[2])
104 style := StringToStyle(colors)
107 if link == "default" {
111 err = errors.New("Color-link statement is not valid: " + line)
118 // StringToStyle returns a style from a string
119 // The strings must be in the format "extra foregroundcolor,backgroundcolor"
120 // The 'extra' can be bold, reverse, or underline
121 func StringToStyle(str string) tcell.Style {
123 spaceSplit := strings.Split(str, " ")
125 if len(spaceSplit) > 1 {
126 split = strings.Split(spaceSplit[1], ",")
128 split = strings.Split(str, ",")
131 fg, bg = split[0], split[1]
135 fg = strings.TrimSpace(fg)
136 bg = strings.TrimSpace(bg)
138 var fgColor, bgColor tcell.Color
140 fgColor, _, _ = DefStyle.Decompose()
142 fgColor = StringToColor(fg)
145 _, bgColor, _ = DefStyle.Decompose()
147 bgColor = StringToColor(bg)
150 style := DefStyle.Foreground(fgColor).Background(bgColor)
151 if strings.Contains(str, "bold") {
152 style = style.Bold(true)
154 if strings.Contains(str, "italic") {
155 style = style.Italic(true)
157 if strings.Contains(str, "reverse") {
158 style = style.Reverse(true)
160 if strings.Contains(str, "underline") {
161 style = style.Underline(true)
166 // StringToColor returns a tcell color from a string representation of a color
167 // We accept either bright... or light... to mean the brighter version of a color
168 func StringToColor(str string) tcell.Color {
171 return tcell.ColorBlack
173 return tcell.ColorMaroon
175 return tcell.ColorGreen
177 return tcell.ColorOlive
179 return tcell.ColorNavy
181 return tcell.ColorPurple
183 return tcell.ColorTeal
185 return tcell.ColorSilver
186 case "brightblack", "lightblack":
187 return tcell.ColorGray
188 case "brightred", "lightred":
189 return tcell.ColorRed
190 case "brightgreen", "lightgreen":
191 return tcell.ColorLime
192 case "brightyellow", "lightyellow":
193 return tcell.ColorYellow
194 case "brightblue", "lightblue":
195 return tcell.ColorBlue
196 case "brightmagenta", "lightmagenta":
197 return tcell.ColorFuchsia
198 case "brightcyan", "lightcyan":
199 return tcell.ColorAqua
200 case "brightwhite", "lightwhite":
201 return tcell.ColorWhite
203 return tcell.ColorDefault
205 // Check if this is a 256 color
206 if num, err := strconv.Atoi(str); err == nil {
207 return GetColor256(num)
209 // Probably a truecolor hex value
210 return tcell.GetColor(str)
214 // GetColor256 returns the tcell color for a number between 0 and 255
215 func GetColor256(color int) tcell.Color {
216 colors := []tcell.Color{tcell.ColorBlack, tcell.ColorMaroon, tcell.ColorGreen,
217 tcell.ColorOlive, tcell.ColorNavy, tcell.ColorPurple,
218 tcell.ColorTeal, tcell.ColorSilver, tcell.ColorGray,
219 tcell.ColorRed, tcell.ColorLime, tcell.ColorYellow,
220 tcell.ColorBlue, tcell.ColorFuchsia, tcell.ColorAqua,
221 tcell.ColorWhite, tcell.Color16, tcell.Color17, tcell.Color18, tcell.Color19, tcell.Color20,
222 tcell.Color21, tcell.Color22, tcell.Color23, tcell.Color24, tcell.Color25, tcell.Color26, tcell.Color27, tcell.Color28,
223 tcell.Color29, tcell.Color30, tcell.Color31, tcell.Color32, tcell.Color33, tcell.Color34, tcell.Color35, tcell.Color36,
224 tcell.Color37, tcell.Color38, tcell.Color39, tcell.Color40, tcell.Color41, tcell.Color42, tcell.Color43, tcell.Color44,
225 tcell.Color45, tcell.Color46, tcell.Color47, tcell.Color48, tcell.Color49, tcell.Color50, tcell.Color51, tcell.Color52,
226 tcell.Color53, tcell.Color54, tcell.Color55, tcell.Color56, tcell.Color57, tcell.Color58, tcell.Color59, tcell.Color60,
227 tcell.Color61, tcell.Color62, tcell.Color63, tcell.Color64, tcell.Color65, tcell.Color66, tcell.Color67, tcell.Color68,
228 tcell.Color69, tcell.Color70, tcell.Color71, tcell.Color72, tcell.Color73, tcell.Color74, tcell.Color75, tcell.Color76,
229 tcell.Color77, tcell.Color78, tcell.Color79, tcell.Color80, tcell.Color81, tcell.Color82, tcell.Color83, tcell.Color84,
230 tcell.Color85, tcell.Color86, tcell.Color87, tcell.Color88, tcell.Color89, tcell.Color90, tcell.Color91, tcell.Color92,
231 tcell.Color93, tcell.Color94, tcell.Color95, tcell.Color96, tcell.Color97, tcell.Color98, tcell.Color99, tcell.Color100,
232 tcell.Color101, tcell.Color102, tcell.Color103, tcell.Color104, tcell.Color105, tcell.Color106, tcell.Color107, tcell.Color108,
233 tcell.Color109, tcell.Color110, tcell.Color111, tcell.Color112, tcell.Color113, tcell.Color114, tcell.Color115, tcell.Color116,
234 tcell.Color117, tcell.Color118, tcell.Color119, tcell.Color120, tcell.Color121, tcell.Color122, tcell.Color123, tcell.Color124,
235 tcell.Color125, tcell.Color126, tcell.Color127, tcell.Color128, tcell.Color129, tcell.Color130, tcell.Color131, tcell.Color132,
236 tcell.Color133, tcell.Color134, tcell.Color135, tcell.Color136, tcell.Color137, tcell.Color138, tcell.Color139, tcell.Color140,
237 tcell.Color141, tcell.Color142, tcell.Color143, tcell.Color144, tcell.Color145, tcell.Color146, tcell.Color147, tcell.Color148,
238 tcell.Color149, tcell.Color150, tcell.Color151, tcell.Color152, tcell.Color153, tcell.Color154, tcell.Color155, tcell.Color156,
239 tcell.Color157, tcell.Color158, tcell.Color159, tcell.Color160, tcell.Color161, tcell.Color162, tcell.Color163, tcell.Color164,
240 tcell.Color165, tcell.Color166, tcell.Color167, tcell.Color168, tcell.Color169, tcell.Color170, tcell.Color171, tcell.Color172,
241 tcell.Color173, tcell.Color174, tcell.Color175, tcell.Color176, tcell.Color177, tcell.Color178, tcell.Color179, tcell.Color180,
242 tcell.Color181, tcell.Color182, tcell.Color183, tcell.Color184, tcell.Color185, tcell.Color186, tcell.Color187, tcell.Color188,
243 tcell.Color189, tcell.Color190, tcell.Color191, tcell.Color192, tcell.Color193, tcell.Color194, tcell.Color195, tcell.Color196,
244 tcell.Color197, tcell.Color198, tcell.Color199, tcell.Color200, tcell.Color201, tcell.Color202, tcell.Color203, tcell.Color204,
245 tcell.Color205, tcell.Color206, tcell.Color207, tcell.Color208, tcell.Color209, tcell.Color210, tcell.Color211, tcell.Color212,
246 tcell.Color213, tcell.Color214, tcell.Color215, tcell.Color216, tcell.Color217, tcell.Color218, tcell.Color219, tcell.Color220,
247 tcell.Color221, tcell.Color222, tcell.Color223, tcell.Color224, tcell.Color225, tcell.Color226, tcell.Color227, tcell.Color228,
248 tcell.Color229, tcell.Color230, tcell.Color231, tcell.Color232, tcell.Color233, tcell.Color234, tcell.Color235, tcell.Color236,
249 tcell.Color237, tcell.Color238, tcell.Color239, tcell.Color240, tcell.Color241, tcell.Color242, tcell.Color243, tcell.Color244,
250 tcell.Color245, tcell.Color246, tcell.Color247, tcell.Color248, tcell.Color249, tcell.Color250, tcell.Color251, tcell.Color252,
251 tcell.Color253, tcell.Color254, tcell.Color255,
254 if color >= 0 && color < len(colors) {
258 return tcell.ColorDefault