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