]> git.lizzy.rs Git - micro.git/blob - cmd/micro/colorscheme.go
Merge pull request #570 from yursan9/yaml
[micro.git] / cmd / micro / colorscheme.go
1 package main
2
3 import (
4         "fmt"
5         "regexp"
6         "strconv"
7         "strings"
8
9         "github.com/zyedidia/tcell"
10 )
11
12 // Colorscheme is a map from string to style -- it represents a colorscheme
13 type Colorscheme map[string]tcell.Style
14
15 // The current colorscheme
16 var colorscheme Colorscheme
17
18 // ColorschemeExists checks if a given colorscheme exists
19 func ColorschemeExists(colorschemeName string) bool {
20         return FindRuntimeFile(RTColorscheme, colorschemeName) != nil
21 }
22
23 // InitColorscheme picks and initializes the colorscheme when micro starts
24 func InitColorscheme() {
25         colorscheme = make(Colorscheme)
26         if screen != nil {
27                 screen.SetStyle(tcell.StyleDefault.
28                         Foreground(tcell.ColorDefault).
29                         Background(tcell.ColorDefault))
30         }
31
32         LoadDefaultColorscheme()
33 }
34
35 // LoadDefaultColorscheme loads the default colorscheme from $(configDir)/colorschemes
36 func LoadDefaultColorscheme() {
37         LoadColorscheme(globalSettings["colorscheme"].(string))
38 }
39
40 // LoadColorscheme loads the given colorscheme from a directory
41 func LoadColorscheme(colorschemeName string) {
42         file := FindRuntimeFile(RTColorscheme, colorschemeName)
43         if file == nil {
44                 TermMessage(colorschemeName, "is not a valid colorscheme")
45         } else {
46                 if data, err := file.Data(); err != nil {
47                         TermMessage("Error loading colorscheme:", err)
48                 } else {
49                         colorscheme = ParseColorscheme(string(data))
50
51                         // Default style
52                         defStyle = tcell.StyleDefault.
53                                 Foreground(tcell.ColorDefault).
54                                 Background(tcell.ColorDefault)
55
56                         // There may be another default style defined in the colorscheme
57                         // In that case we should use that one
58                         if style, ok := colorscheme["default"]; ok {
59                                 defStyle = style
60                         }
61                         if screen != nil {
62                                 screen.SetStyle(defStyle)
63                         }
64                 }
65         }
66 }
67
68 // ParseColorscheme parses the text definition for a colorscheme and returns the corresponding object
69 // Colorschemes are made up of color-link statements linking a color group to a list of colors
70 // For example, color-link keyword (blue,red) makes all keywords have a blue foreground and
71 // red background
72 func ParseColorscheme(text string) Colorscheme {
73         parser := regexp.MustCompile(`color-link\s+(\S*)\s+"(.*)"`)
74
75         lines := strings.Split(text, "\n")
76
77         c := make(Colorscheme)
78
79         for _, line := range lines {
80                 if strings.TrimSpace(line) == "" ||
81                         strings.TrimSpace(line)[0] == '#' {
82                         // Ignore this line
83                         continue
84                 }
85
86                 matches := parser.FindSubmatch([]byte(line))
87                 if len(matches) == 3 {
88                         link := string(matches[1])
89                         colors := string(matches[2])
90
91                         style := StringToStyle(colors)
92                         c[link] = style
93
94                         if link == "default" {
95                                 defStyle = style
96                         }
97                 } else {
98                         fmt.Println("Color-link statement is not valid:", line)
99                 }
100         }
101
102         return c
103 }
104
105 // StringToStyle returns a style from a string
106 // The strings must be in the format "extra foregroundcolor,backgroundcolor"
107 // The 'extra' can be bold, reverse, or underline
108 func StringToStyle(str string) tcell.Style {
109         var fg, bg string
110         spaceSplit := strings.Split(str, " ")
111         var split []string
112         if len(spaceSplit) > 1 {
113                 split = strings.Split(spaceSplit[1], ",")
114         } else {
115                 split = strings.Split(str, ",")
116         }
117         if len(split) > 1 {
118                 fg, bg = split[0], split[1]
119         } else {
120                 fg = split[0]
121         }
122         fg = strings.TrimSpace(fg)
123         bg = strings.TrimSpace(bg)
124
125         var fgColor, bgColor tcell.Color
126         if fg == "" {
127                 fgColor, _, _ = defStyle.Decompose()
128         } else {
129                 fgColor = StringToColor(fg)
130         }
131         if bg == "" {
132                 _, bgColor, _ = defStyle.Decompose()
133         } else {
134                 bgColor = StringToColor(bg)
135         }
136
137         style := defStyle.Foreground(fgColor).Background(bgColor)
138         if strings.Contains(str, "bold") {
139                 style = style.Bold(true)
140         }
141         if strings.Contains(str, "reverse") {
142                 style = style.Reverse(true)
143         }
144         if strings.Contains(str, "underline") {
145                 style = style.Underline(true)
146         }
147         return style
148 }
149
150 // StringToColor returns a tcell color from a string representation of a color
151 // We accept either bright... or light... to mean the brighter version of a color
152 func StringToColor(str string) tcell.Color {
153         switch str {
154         case "black":
155                 return tcell.ColorBlack
156         case "red":
157                 return tcell.ColorMaroon
158         case "green":
159                 return tcell.ColorGreen
160         case "yellow":
161                 return tcell.ColorOlive
162         case "blue":
163                 return tcell.ColorNavy
164         case "magenta":
165                 return tcell.ColorPurple
166         case "cyan":
167                 return tcell.ColorTeal
168         case "white":
169                 return tcell.ColorSilver
170         case "brightblack", "lightblack":
171                 return tcell.ColorGray
172         case "brightred", "lightred":
173                 return tcell.ColorRed
174         case "brightgreen", "lightgreen":
175                 return tcell.ColorLime
176         case "brightyellow", "lightyellow":
177                 return tcell.ColorYellow
178         case "brightblue", "lightblue":
179                 return tcell.ColorBlue
180         case "brightmagenta", "lightmagenta":
181                 return tcell.ColorFuchsia
182         case "brightcyan", "lightcyan":
183                 return tcell.ColorAqua
184         case "brightwhite", "lightwhite":
185                 return tcell.ColorWhite
186         case "default":
187                 return tcell.ColorDefault
188         default:
189                 // Check if this is a 256 color
190                 if num, err := strconv.Atoi(str); err == nil {
191                         return GetColor256(num)
192                 }
193                 // Probably a truecolor hex value
194                 return tcell.GetColor(str)
195         }
196 }
197
198 // GetColor256 returns the tcell color for a number between 0 and 255
199 func GetColor256(color int) tcell.Color {
200         colors := []tcell.Color{tcell.ColorBlack, tcell.ColorMaroon, tcell.ColorGreen,
201                 tcell.ColorOlive, tcell.ColorNavy, tcell.ColorPurple,
202                 tcell.ColorTeal, tcell.ColorSilver, tcell.ColorGray,
203                 tcell.ColorRed, tcell.ColorLime, tcell.ColorYellow,
204                 tcell.ColorBlue, tcell.ColorFuchsia, tcell.ColorAqua,
205                 tcell.ColorWhite, tcell.Color16, tcell.Color17, tcell.Color18, tcell.Color19, tcell.Color20,
206                 tcell.Color21, tcell.Color22, tcell.Color23, tcell.Color24, tcell.Color25, tcell.Color26, tcell.Color27, tcell.Color28,
207                 tcell.Color29, tcell.Color30, tcell.Color31, tcell.Color32, tcell.Color33, tcell.Color34, tcell.Color35, tcell.Color36,
208                 tcell.Color37, tcell.Color38, tcell.Color39, tcell.Color40, tcell.Color41, tcell.Color42, tcell.Color43, tcell.Color44,
209                 tcell.Color45, tcell.Color46, tcell.Color47, tcell.Color48, tcell.Color49, tcell.Color50, tcell.Color51, tcell.Color52,
210                 tcell.Color53, tcell.Color54, tcell.Color55, tcell.Color56, tcell.Color57, tcell.Color58, tcell.Color59, tcell.Color60,
211                 tcell.Color61, tcell.Color62, tcell.Color63, tcell.Color64, tcell.Color65, tcell.Color66, tcell.Color67, tcell.Color68,
212                 tcell.Color69, tcell.Color70, tcell.Color71, tcell.Color72, tcell.Color73, tcell.Color74, tcell.Color75, tcell.Color76,
213                 tcell.Color77, tcell.Color78, tcell.Color79, tcell.Color80, tcell.Color81, tcell.Color82, tcell.Color83, tcell.Color84,
214                 tcell.Color85, tcell.Color86, tcell.Color87, tcell.Color88, tcell.Color89, tcell.Color90, tcell.Color91, tcell.Color92,
215                 tcell.Color93, tcell.Color94, tcell.Color95, tcell.Color96, tcell.Color97, tcell.Color98, tcell.Color99, tcell.Color100,
216                 tcell.Color101, tcell.Color102, tcell.Color103, tcell.Color104, tcell.Color105, tcell.Color106, tcell.Color107, tcell.Color108,
217                 tcell.Color109, tcell.Color110, tcell.Color111, tcell.Color112, tcell.Color113, tcell.Color114, tcell.Color115, tcell.Color116,
218                 tcell.Color117, tcell.Color118, tcell.Color119, tcell.Color120, tcell.Color121, tcell.Color122, tcell.Color123, tcell.Color124,
219                 tcell.Color125, tcell.Color126, tcell.Color127, tcell.Color128, tcell.Color129, tcell.Color130, tcell.Color131, tcell.Color132,
220                 tcell.Color133, tcell.Color134, tcell.Color135, tcell.Color136, tcell.Color137, tcell.Color138, tcell.Color139, tcell.Color140,
221                 tcell.Color141, tcell.Color142, tcell.Color143, tcell.Color144, tcell.Color145, tcell.Color146, tcell.Color147, tcell.Color148,
222                 tcell.Color149, tcell.Color150, tcell.Color151, tcell.Color152, tcell.Color153, tcell.Color154, tcell.Color155, tcell.Color156,
223                 tcell.Color157, tcell.Color158, tcell.Color159, tcell.Color160, tcell.Color161, tcell.Color162, tcell.Color163, tcell.Color164,
224                 tcell.Color165, tcell.Color166, tcell.Color167, tcell.Color168, tcell.Color169, tcell.Color170, tcell.Color171, tcell.Color172,
225                 tcell.Color173, tcell.Color174, tcell.Color175, tcell.Color176, tcell.Color177, tcell.Color178, tcell.Color179, tcell.Color180,
226                 tcell.Color181, tcell.Color182, tcell.Color183, tcell.Color184, tcell.Color185, tcell.Color186, tcell.Color187, tcell.Color188,
227                 tcell.Color189, tcell.Color190, tcell.Color191, tcell.Color192, tcell.Color193, tcell.Color194, tcell.Color195, tcell.Color196,
228                 tcell.Color197, tcell.Color198, tcell.Color199, tcell.Color200, tcell.Color201, tcell.Color202, tcell.Color203, tcell.Color204,
229                 tcell.Color205, tcell.Color206, tcell.Color207, tcell.Color208, tcell.Color209, tcell.Color210, tcell.Color211, tcell.Color212,
230                 tcell.Color213, tcell.Color214, tcell.Color215, tcell.Color216, tcell.Color217, tcell.Color218, tcell.Color219, tcell.Color220,
231                 tcell.Color221, tcell.Color222, tcell.Color223, tcell.Color224, tcell.Color225, tcell.Color226, tcell.Color227, tcell.Color228,
232                 tcell.Color229, tcell.Color230, tcell.Color231, tcell.Color232, tcell.Color233, tcell.Color234, tcell.Color235, tcell.Color236,
233                 tcell.Color237, tcell.Color238, tcell.Color239, tcell.Color240, tcell.Color241, tcell.Color242, tcell.Color243, tcell.Color244,
234                 tcell.Color245, tcell.Color246, tcell.Color247, tcell.Color248, tcell.Color249, tcell.Color250, tcell.Color251, tcell.Color252,
235                 tcell.Color253, tcell.Color254, tcell.Color255,
236         }
237
238         return colors[color]
239 }