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