diff --git a/internal/config/colorscheme.go b/internal/config/colorscheme.go index 703a1d69..d03c64b9 100644 --- a/internal/config/colorscheme.go +++ b/internal/config/colorscheme.go @@ -52,43 +52,55 @@ func InitColorscheme() error { Colorscheme = make(map[string]tcell.Style) DefStyle = tcell.StyleDefault - return LoadDefaultColorscheme() + c, err := LoadDefaultColorscheme() + if err == nil { + Colorscheme = c + } + + return err } // LoadDefaultColorscheme loads the default colorscheme from $(ConfigDir)/colorschemes -func LoadDefaultColorscheme() error { - return LoadColorscheme(GlobalSettings["colorscheme"].(string)) +func LoadDefaultColorscheme() (map[string]tcell.Style, error) { + var parsedColorschemes []string + return LoadColorscheme(GlobalSettings["colorscheme"].(string), &parsedColorschemes) } // LoadColorscheme loads the given colorscheme from a directory -func LoadColorscheme(colorschemeName string) error { +func LoadColorscheme(colorschemeName string, parsedColorschemes *[]string) (map[string]tcell.Style, error) { + c := make(map[string]tcell.Style) file := FindRuntimeFile(RTColorscheme, colorschemeName) if file == nil { - return errors.New(colorschemeName + " is not a valid colorscheme") + return c, errors.New(colorschemeName + " is not a valid colorscheme") } if data, err := file.Data(); err != nil { - return errors.New("Error loading colorscheme: " + err.Error()) + return c, errors.New("Error loading colorscheme: " + err.Error()) } else { - Colorscheme, err = ParseColorscheme(string(data)) + var err error + c, err = ParseColorscheme(file.Name(), string(data), parsedColorschemes) if err != nil { - return err + return c, err } } - return nil + return c, nil } // ParseColorscheme parses the text definition for a colorscheme and returns the corresponding object // Colorschemes are made up of color-link statements linking a color group to a list of colors // For example, color-link keyword (blue,red) makes all keywords have a blue foreground and // red background -func ParseColorscheme(text string) (map[string]tcell.Style, error) { +func ParseColorscheme(name string, text string, parsedColorschemes *[]string) (map[string]tcell.Style, error) { var err error - parser := regexp.MustCompile(`color-link\s+(\S*)\s+"(.*)"`) - + colorParser := regexp.MustCompile(`color-link\s+(\S*)\s+"(.*)"`) + includeParser := regexp.MustCompile(`include\s+"(.*)"`) lines := strings.Split(text, "\n") - c := make(map[string]tcell.Style) + if parsedColorschemes != nil { + *parsedColorschemes = append(*parsedColorschemes, name) + } + +lineLoop: for _, line := range lines { if strings.TrimSpace(line) == "" || strings.TrimSpace(line)[0] == '#' { @@ -96,7 +108,30 @@ func ParseColorscheme(text string) (map[string]tcell.Style, error) { continue } - matches := parser.FindSubmatch([]byte(line)) + matches := includeParser.FindSubmatch([]byte(line)) + if len(matches) == 2 { + // support includes only in case parsedColorschemes are given + if parsedColorschemes != nil { + include := string(matches[1]) + for _, name := range *parsedColorschemes { + // check for circular includes... + if name == include { + // ...and prevent them + continue lineLoop + } + } + includeScheme, err := LoadColorscheme(include, parsedColorschemes) + if err != nil { + return c, err + } + for k, v := range includeScheme { + c[k] = v + } + } + continue + } + + matches = colorParser.FindSubmatch([]byte(line)) if len(matches) == 3 { link := string(matches[1]) colors := string(matches[2]) diff --git a/internal/config/colorscheme_test.go b/internal/config/colorscheme_test.go index 2785c581..bcd4016a 100644 --- a/internal/config/colorscheme_test.go +++ b/internal/config/colorscheme_test.go @@ -65,7 +65,7 @@ color-link constant "#AE81FF,#282828" color-link constant.string "#E6DB74,#282828" color-link constant.string.char "#BDE6AD,#282828"` - c, err := ParseColorscheme(testColorscheme) + c, err := ParseColorscheme("testColorscheme", testColorscheme, nil) assert.Nil(t, err) fg, bg, _ := c["comment"].Decompose() diff --git a/runtime/colorschemes/default.micro b/runtime/colorschemes/default.micro index 9ae5bfd6..2f7fdfcc 100644 --- a/runtime/colorschemes/default.micro +++ b/runtime/colorschemes/default.micro @@ -1,34 +1 @@ -color-link default "#F8F8F2,#282828" -color-link comment "#75715E,#282828" -color-link identifier "#66D9EF,#282828" -color-link constant "#AE81FF,#282828" -color-link constant.string "#E6DB74,#282828" -color-link constant.string.char "#BDE6AD,#282828" -color-link statement "#F92672,#282828" -color-link symbol.operator "#F92671,#282828" -color-link preproc "#CB4B16,#282828" -color-link type "#66D9EF,#282828" -color-link special "#A6E22E,#282828" -color-link underlined "#D33682,#282828" -color-link error "bold #CB4B16,#282828" -color-link todo "bold #D33682,#282828" -color-link hlsearch "#282828,#E6DB74" -color-link statusline "#282828,#F8F8F2" -color-link tabbar "#282828,#F8F8F2" -color-link indent-char "#505050,#282828" -color-link line-number "#AAAAAA,#323232" -color-link current-line-number "#AAAAAA,#282828" -color-link diff-added "#00AF00" -color-link diff-modified "#FFAF00" -color-link diff-deleted "#D70000" -color-link gutter-error "#CB4B16,#282828" -color-link gutter-warning "#E6DB74,#282828" -color-link cursor-line "#323232" -color-link color-column "#323232" -#No extended types; Plain brackets. -color-link type.extended "default" -#color-link symbol.brackets "default" -color-link symbol.tag "#AE81FF,#282828" -color-link match-brace "#282828,#AE81FF" -color-link tab-error "#D75F5F" -color-link trailingws "#D75F5F" +include "monokai" diff --git a/runtime/help/colors.md b/runtime/help/colors.md index a6970d15..59b4f045 100644 --- a/runtime/help/colors.md +++ b/runtime/help/colors.md @@ -236,7 +236,10 @@ Here's a list of subgroups used in micro's built-in syntax files. * type.keyword (If you want a special highlight for keywords like `private`) In the future, plugins may also be able to use color groups for styling. - +Last but not least it's even possible to use `include` followed by the +colorscheme name as string to include a different colorscheme within a new one. +Additionally the groups can then be extended or overwritten. The `default.micro` +theme can be seen as an example, which links to the chosen default colorscheme. ## Syntax files