9 "github.com/zyedidia/tcell/v2"
12 // DefStyle is Micro's default style
13 var DefStyle tcell.Style = tcell.StyleDefault
15 // Colorscheme is 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 {
43 // ColorschemeExists checks if a given colorscheme exists
44 func ColorschemeExists(colorschemeName string) bool {
45 return FindRuntimeFile(RTColorscheme, colorschemeName) != nil
48 // InitColorscheme picks and initializes the colorscheme when micro starts
49 func InitColorscheme() error {
50 Colorscheme = make(map[string]tcell.Style)
51 DefStyle = tcell.StyleDefault
53 return LoadDefaultColorscheme()
56 // LoadDefaultColorscheme loads the default colorscheme from $(ConfigDir)/colorschemes
57 func LoadDefaultColorscheme() error {
58 return LoadColorscheme(GlobalSettings["colorscheme"].(string))
61 // LoadColorscheme loads the given colorscheme from a directory
62 func LoadColorscheme(colorschemeName string) error {
63 file := FindRuntimeFile(RTColorscheme, colorschemeName)
65 return errors.New(colorschemeName + " is not a valid colorscheme")
67 if data, err := file.Data(); err != nil {
68 return errors.New("Error loading colorscheme: " + err.Error())
70 Colorscheme, err = ParseColorscheme(string(data))
78 // ParseColorscheme parses the text definition for a colorscheme and returns the corresponding object
79 // Colorschemes are made up of color-link statements linking a color group to a list of colors
80 // For example, color-link keyword (blue,red) makes all keywords have a blue foreground and
82 func ParseColorscheme(text string) (map[string]tcell.Style, error) {
84 parser := regexp.MustCompile(`color-link\s+(\S*)\s+"(.*)"`)
86 lines := strings.Split(text, "\n")
88 c := make(map[string]tcell.Style)
90 for _, line := range lines {
91 if strings.TrimSpace(line) == "" ||
92 strings.TrimSpace(line)[0] == '#' {
97 matches := parser.FindSubmatch([]byte(line))
98 if len(matches) == 3 {
99 link := string(matches[1])
100 colors := string(matches[2])
102 style := StringToStyle(colors)
105 if link == "default" {
109 err = errors.New("Color-link statement is not valid: " + line)
116 // StringToStyle returns a style from a string
117 // The strings must be in the format "extra foregroundcolor,backgroundcolor"
118 // The 'extra' can be bold, reverse, italic or underline
119 func StringToStyle(str string) tcell.Style {
121 spaceSplit := strings.Split(str, " ")
122 split := strings.Split(spaceSplit[len(spaceSplit)-1], ",")
124 fg, bg = split[0], split[1]
128 fg = strings.TrimSpace(fg)
129 bg = strings.TrimSpace(bg)
131 var fgColor, bgColor tcell.Color
132 if fg == "" || fg == "default" {
133 fgColor, _, _ = DefStyle.Decompose()
135 fgColor = StringToColor(fg)
137 if bg == "" || bg == "default" {
138 _, bgColor, _ = DefStyle.Decompose()
140 bgColor = StringToColor(bg)
143 style := DefStyle.Foreground(fgColor).Background(bgColor)
144 if strings.Contains(str, "bold") {
145 style = style.Bold(true)
147 if strings.Contains(str, "italic") {
148 style = style.Italic(true)
150 if strings.Contains(str, "reverse") {
151 style = style.Reverse(true)
153 if strings.Contains(str, "underline") {
154 style = style.Underline(true)
159 // StringToColor returns a tcell color from a string representation of a color
160 // We accept either bright... or light... to mean the brighter version of a color
161 func StringToColor(str string) tcell.Color {
164 return tcell.ColorBlack
166 return tcell.ColorMaroon
168 return tcell.ColorGreen
170 return tcell.ColorOlive
172 return tcell.ColorNavy
174 return tcell.ColorPurple
176 return tcell.ColorTeal
178 return tcell.ColorSilver
179 case "brightblack", "lightblack":
180 return tcell.ColorGray
181 case "brightred", "lightred":
182 return tcell.ColorRed
183 case "brightgreen", "lightgreen":
184 return tcell.ColorLime
185 case "brightyellow", "lightyellow":
186 return tcell.ColorYellow
187 case "brightblue", "lightblue":
188 return tcell.ColorBlue
189 case "brightmagenta", "lightmagenta":
190 return tcell.ColorFuchsia
191 case "brightcyan", "lightcyan":
192 return tcell.ColorAqua
193 case "brightwhite", "lightwhite":
194 return tcell.ColorWhite
196 return tcell.ColorDefault
198 // Check if this is a 256 color
199 if num, err := strconv.Atoi(str); err == nil {
200 return GetColor256(num)
202 // Probably a truecolor hex value
203 return tcell.GetColor(str)
207 // GetColor256 returns the tcell color for a number between 0 and 255
208 func GetColor256(color int) tcell.Color {
210 return tcell.ColorDefault
212 return tcell.PaletteColor(color)