]> git.lizzy.rs Git - micro.git/blobdiff - pkg/highlight/highlighter.go
More style improvements
[micro.git] / pkg / highlight / highlighter.go
index e736abdbfab486d55793e39fd8c6b92dff01a4da..50545f04da5278f99e8f9d6a791337befa99c2f9 100644 (file)
@@ -3,7 +3,6 @@ package highlight
 import (
        "regexp"
        "strings"
-       "unicode/utf8"
 )
 
 func sliceStart(slc []byte, index int) []byte {
@@ -15,7 +14,7 @@ func sliceStart(slc []byte, index int) []byte {
                        return slc[totalSize:]
                }
 
-               _, size := utf8.DecodeRune(slc[totalSize:])
+               _, _, size := DecodeCharacter(slc[totalSize:])
                totalSize += size
                i++
        }
@@ -32,7 +31,7 @@ func sliceEnd(slc []byte, index int) []byte {
                        return slc[:totalSize]
                }
 
-               _, size := utf8.DecodeRune(slc[totalSize:])
+               _, _, size := DecodeCharacter(slc[totalSize:])
                totalSize += size
                i++
        }
@@ -47,9 +46,9 @@ func runePos(p int, str []byte) int {
                return 0
        }
        if p >= len(str) {
-               return utf8.RuneCount(str)
+               return CharacterCount(str)
        }
-       return utf8.RuneCount(str[:p])
+       return CharacterCount(str[:p])
 }
 
 func combineLineMatch(src, dst LineMatch) LineMatch {
@@ -68,6 +67,9 @@ func combineLineMatch(src, dst LineMatch) LineMatch {
 // A State represents the region at the end of a line
 type State *region
 
+// EmptyDef is an empty definition.
+var EmptyDef = Def{nil, &rules{}}
+
 // LineStates is an interface for a buffer-like object which can also store the states and matches for every line
 type LineStates interface {
        LineBytes(n int) []byte
@@ -110,7 +112,7 @@ func findIndex(regex *regexp.Regexp, skip *regexp.Regexp, str []byte, canMatchSt
        var strbytes []byte
        if skip != nil {
                strbytes = skip.ReplaceAllFunc(str, func(match []byte) []byte {
-                       res := make([]byte, utf8.RuneCount(match))
+                       res := make([]byte, CharacterCount(match))
                        return res
                })
        } else {
@@ -146,7 +148,7 @@ func findAllIndex(regex *regexp.Regexp, str []byte, canMatchStart, canMatchEnd b
 }
 
 func (h *Highlighter) highlightRegion(highlights LineMatch, start int, canMatchEnd bool, lineNum int, line []byte, curRegion *region, statesOnly bool) LineMatch {
-       lineLen := utf8.RuneCount(line)
+       lineLen := CharacterCount(line)
        if start == 0 {
                if !statesOnly {
                        if _, ok := highlights[0]; !ok {
@@ -176,7 +178,7 @@ func (h *Highlighter) highlightRegion(highlights LineMatch, start int, canMatchE
                return highlights
        }
 
-       if lineLen == 0 || statesOnly {
+       if lineLen == 0 {
                if canMatchEnd {
                        h.lastRegion = curRegion
                }
@@ -197,28 +199,32 @@ func (h *Highlighter) highlightRegion(highlights LineMatch, start int, canMatchE
                }
        }
        if firstLoc[0] != lineLen {
-               highlights[start+firstLoc[0]] = firstRegion.limitGroup
+               if !statesOnly {
+                       highlights[start+firstLoc[0]] = firstRegion.limitGroup
+               }
                h.highlightRegion(highlights, start, false, lineNum, sliceEnd(line, firstLoc[0]), curRegion, statesOnly)
                h.highlightRegion(highlights, start+firstLoc[1], canMatchEnd, lineNum, sliceStart(line, firstLoc[1]), firstRegion, statesOnly)
                return highlights
        }
 
-       fullHighlights := make([]Group, lineLen)
-       for i := 0; i < len(fullHighlights); i++ {
-               fullHighlights[i] = curRegion.group
-       }
+       if !statesOnly {
+               fullHighlights := make([]Group, lineLen)
+               for i := 0; i < len(fullHighlights); i++ {
+                       fullHighlights[i] = curRegion.group
+               }
 
-       for _, p := range curRegion.rules.patterns {
-               matches := findAllIndex(p.regex, line, start == 0, canMatchEnd)
-               for _, m := range matches {
-                       for i := m[0]; i < m[1]; i++ {
-                               fullHighlights[i] = p.group
+               for _, p := range curRegion.rules.patterns {
+                       matches := findAllIndex(p.regex, line, start == 0, canMatchEnd)
+                       for _, m := range matches {
+                               for i := m[0]; i < m[1]; i++ {
+                                       fullHighlights[i] = p.group
+                               }
                        }
                }
-       }
-       for i, h := range fullHighlights {
-               if i == 0 || h != fullHighlights[i-1] {
-                       highlights[start+i] = h
+               for i, h := range fullHighlights {
+                       if i == 0 || h != fullHighlights[i-1] {
+                               highlights[start+i] = h
+                       }
                }
        }
 
@@ -230,7 +236,7 @@ func (h *Highlighter) highlightRegion(highlights LineMatch, start int, canMatchE
 }
 
 func (h *Highlighter) highlightEmptyRegion(highlights LineMatch, start int, canMatchEnd bool, lineNum int, line []byte, statesOnly bool) LineMatch {
-       lineLen := utf8.RuneCount(line)
+       lineLen := CharacterCount(line)
        if lineLen == 0 {
                if canMatchEnd {
                        h.lastRegion = nil
@@ -330,11 +336,11 @@ func (h *Highlighter) HighlightStates(input LineStates) {
        }
 }
 
-// HighlightMatches sets the matches for each line in between startline and endline
+// HighlightMatches sets the matches for each line from startline to endline
 // It sets all other matches in the buffer to nil to conserve memory
 // This assumes that all the states are set correctly
 func (h *Highlighter) HighlightMatches(input LineStates, startline, endline int) {
-       for i := startline; i < endline; i++ {
+       for i := startline; i <= endline; i++ {
                if i >= input.LinesNum() {
                        break
                }
@@ -354,8 +360,9 @@ func (h *Highlighter) HighlightMatches(input LineStates, startline, endline int)
 }
 
 // ReHighlightStates will scan down from `startline` and set the appropriate end of line state
-// for each line until it comes across the same state in two consecutive lines
-func (h *Highlighter) ReHighlightStates(input LineStates, startline int) {
+// for each line until it comes across a line whose state does not change
+// returns the number of the final line
+func (h *Highlighter) ReHighlightStates(input LineStates, startline int) int {
        // lines := input.LineData()
 
        h.lastRegion = nil
@@ -378,9 +385,11 @@ func (h *Highlighter) ReHighlightStates(input LineStates, startline int) {
                input.SetState(i, curState)
 
                if curState == lastState {
-                       break
+                       return i
                }
        }
+
+       return input.LinesNum() - 1
 }
 
 // ReHighlightLine will rehighlight the state and match for a single line