From 264ec81fd666b3f4247c15f6ba79c38d1e98af52 Mon Sep 17 00:00:00 2001 From: Felix Angell Date: Tue, 17 Apr 2018 21:38:52 +0100 Subject: [PATCH] dont seg fault when there is no highlighting info --- cfg/config.go | 9 +-- cfg/config_any.go | 1 + cfg/config_linux.go | 1 + cfg/config_mac.go | 1 + gui/buffer.go | 141 +++++++++++++++++++++++--------------------- 5 files changed, 83 insertions(+), 70 deletions(-) diff --git a/cfg/config.go b/cfg/config.go index 610d24b..8e5bfa4 100644 --- a/cfg/config.go +++ b/cfg/config.go @@ -65,10 +65,11 @@ func (c CursorConfig) GetCaretWidth() int { } type RenderConfig struct { - Aliased bool - Accelerated bool - Throttle_Cpu_Usage bool - Always_Render bool + Aliased bool + Accelerated bool + Throttle_Cpu_Usage bool + Always_Render bool + Syntax_Highlighting bool } // todo make this more extendable... diff --git a/cfg/config_any.go b/cfg/config_any.go index a674cda..5e6da42 100644 --- a/cfg/config_any.go +++ b/cfg/config_any.go @@ -18,6 +18,7 @@ aliased = true accelerated = true throttle_cpu_usage = true always_render = true +syntax_highlighting = true [file_associations] [file_associations.c] diff --git a/cfg/config_linux.go b/cfg/config_linux.go index cc3ad65..57dc326 100644 --- a/cfg/config_linux.go +++ b/cfg/config_linux.go @@ -18,6 +18,7 @@ aliased = true accelerated = true throttle_cpu_usage = true always_render = true +syntax_highlighting = true [file_associations] [file_associations.c] diff --git a/cfg/config_mac.go b/cfg/config_mac.go index 8340651..a660ede 100644 --- a/cfg/config_mac.go +++ b/cfg/config_mac.go @@ -18,6 +18,7 @@ aliased = true accelerated = true throttle_cpu_usage = true always_render = true +syntax_highlighting = true [file_associations] [file_associations.c] diff --git a/gui/buffer.go b/gui/buffer.go index 81b0567..d0a3fde 100644 --- a/gui/buffer.go +++ b/gui/buffer.go @@ -755,6 +755,78 @@ var ex, ey = 0, 0 var compiledRegex = map[string]*regexp.Regexp{} +func (b *Buffer) syntaxHighlightLine(currLine string) map[int]syntaxRuneInfo { + matches := map[int]syntaxRuneInfo{} + + subjects := make([]cfg.SyntaxCriteria, len(b.languageInfo.Syntax)) + colours := make([]int, len(b.languageInfo.Syntax)) + + idx := 0 + for _, criteria := range b.languageInfo.Syntax { + colours[idx] = criteria.Colour + subjects[idx] = criteria + idx++ + } + + // HOLY SLOW BATMAN + for charIndex := 0; charIndex < len(currLine); charIndex++ { + for syntaxIndex, syntax := range subjects { + + if syntax.Pattern != "" { + // we have a regex pattern + + // FIXME this is also very slow! + // we could easily compile all of these + // regular expressions when we load the + // syntax highlighter. + a := string(currLine[charIndex:]) + + // no need to compile the same regex + // pattern multiple times. + regex, ok := compiledRegex[syntax.Pattern] + if !ok { + var err error + regex, err = regexp.Compile(syntax.Pattern) + if err != nil { + log.Println(err.Error()) + } + } + + matched := regex.FindStringIndex(a) + if matched != nil { + if _, ok := matches[charIndex]; !ok { + matchedStrLen := (matched[1] - matched[0]) + matches[charIndex+matched[0]] = syntaxRuneInfo{colours[syntaxIndex], -1, matchedStrLen} + charIndex = charIndex + matchedStrLen + } + } + + } else { + + for _, subject := range syntax.Match { + if charIndex+len(subject)+1 > len(currLine) { + continue + } + a := currLine[charIndex : charIndex+len(subject)+1] + + // we only want to match words. so we check that it has a space + // before or after the subject word. + if strings.Compare(string(a), subject+" ") == 0 || strings.Compare(string(a), " "+subject) == 0 { + if _, ok := matches[charIndex]; !ok { + matches[charIndex] = syntaxRuneInfo{colours[syntaxIndex], -1, len(string(a))} + break + } + charIndex += len(subject) + } + } + + } + } + } + + return matches +} + func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) { // BACKGROUND ctx.SetColor(strife.HexRGB(b.cfg.Theme.Background)) @@ -803,72 +875,9 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) { currLine := []rune(rope.String()) // char index => colour - matches := map[int]syntaxRuneInfo{} - - subjects := make([]cfg.SyntaxCriteria, len(b.languageInfo.Syntax)) - colours := make([]int, len(b.languageInfo.Syntax)) - - idx := 0 - for _, criteria := range b.languageInfo.Syntax { - colours[idx] = criteria.Colour - subjects[idx] = criteria - idx++ - } - - // HOLY SLOW BATMAN - for charIndex := 0; charIndex < len(currLine); charIndex++ { - for syntaxIndex, syntax := range subjects { - - if syntax.Pattern != "" { - // we have a regex pattern - - // FIXME this is also very slow! - // we could easily compile all of these - // regular expressions when we load the - // syntax highlighter. - a := string(currLine[charIndex:]) - - // no need to compile the same regex - // pattern multiple times. - regex, ok := compiledRegex[syntax.Pattern] - if !ok { - var err error - regex, err = regexp.Compile(syntax.Pattern) - if err != nil { - log.Println(err.Error()) - } - } - - matched := regex.FindStringIndex(a) - if matched != nil { - if _, ok := matches[charIndex]; !ok { - matchedStrLen := (matched[1] - matched[0]) - matches[charIndex+matched[0]] = syntaxRuneInfo{colours[syntaxIndex], -1, matchedStrLen} - charIndex = charIndex + matchedStrLen - } - } - - } else { - - for _, subject := range syntax.Match { - if charIndex+len(subject)+1 > len(currLine) { - continue - } - a := currLine[charIndex : charIndex+len(subject)+1] - - // we only want to match words. so we check that it has a space - // before or after the subject word. - if strings.Compare(string(a), subject+" ") == 0 || strings.Compare(string(a), " "+subject) == 0 { - if _, ok := matches[charIndex]; !ok { - matches[charIndex] = syntaxRuneInfo{colours[syntaxIndex], -1, len(string(a))} - break - } - charIndex += len(subject) - } - } - - } - } + var matches map[int]syntaxRuneInfo + if b.languageInfo != nil { + matches = b.syntaxHighlightLine(string(currLine)) } colorStack := []int{}