import (
"regexp"
"strings"
- "unicode/utf8"
)
func sliceStart(slc []byte, index int) []byte {
return slc[totalSize:]
}
- _, size := utf8.DecodeRune(slc[totalSize:])
+ _, _, size := DecodeCharacter(slc[totalSize:])
totalSize += size
i++
}
return slc[:totalSize]
}
- _, size := utf8.DecodeRune(slc[totalSize:])
+ _, _, size := DecodeCharacter(slc[totalSize:])
totalSize += size
i++
}
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 {
// 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
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 {
}
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 {
return highlights
}
- if lineLen == 0 || statesOnly {
+ if lineLen == 0 {
if canMatchEnd {
h.lastRegion = curRegion
}
}
}
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
+ }
}
}
}
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
}
}
-// 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
}
}
// 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
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