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