Add support for skipping and remove need for lookbehind

This commit is contained in:
Zachary Yedidia 2017-03-27 20:53:08 -04:00
parent c24f75999a
commit 299712ead3
53 changed files with 195 additions and 153 deletions

View file

@ -4,8 +4,6 @@ import (
"regexp"
"strings"
"unicode/utf8"
"github.com/dlclark/regexp2"
)
// RunePos returns the rune index of a given byte index
@ -62,7 +60,7 @@ func NewHighlighter(def *Def) *Highlighter {
// color's group (represented as one byte)
type LineMatch map[int]Group
func findIndex(regex *regexp2.Regexp, str []rune, canMatchStart, canMatchEnd bool) []int {
func findIndex(regex *regexp.Regexp, skip []*regexp.Regexp, str []rune, canMatchStart, canMatchEnd bool) []int {
regexStr := regex.String()
if strings.Contains(regexStr, "^") {
if !canMatchStart {
@ -74,12 +72,30 @@ func findIndex(regex *regexp2.Regexp, str []rune, canMatchStart, canMatchEnd boo
return nil
}
}
match, _ := regex.FindStringMatch(string(str))
var strbytes []byte
if skip != nil && len(skip) > 0 {
for _, r := range skip {
if r != nil {
strbytes = r.ReplaceAllFunc([]byte(string(str)), func(match []byte) []byte {
res := make([]byte, len(match))
// for i := 0; i < len(match); i++ {
//
// }
return res
})
}
}
} else {
strbytes = []byte(string(str))
}
match := regex.FindIndex(strbytes)
if match == nil {
return nil
}
return []int{match.Index, match.Index + match.Length}
// return []int{runePos(match.Index, string(str)), runePos(match.Index+match.Length, string(str))}
// return []int{match.Index, match.Index + match.Length}
return []int{runePos(match[0], string(str)), runePos(match[1], string(str))}
}
func findAllIndex(regex *regexp.Regexp, str []rune, canMatchStart, canMatchEnd bool) [][]int {
@ -111,7 +127,15 @@ func (h *Highlighter) highlightRegion(highlights LineMatch, start int, canMatchE
}
}
loc := findIndex(curRegion.end, line, start == 0, canMatchEnd)
skips := make([]*regexp.Regexp, len(curRegion.rules.patterns)+1)
for i := range skips {
if i != len(skips)-1 {
skips[i] = curRegion.rules.patterns[i].regex
} else {
skips[i] = curRegion.skip
}
}
loc := findIndex(curRegion.end, skips, line, start == 0, canMatchEnd)
if loc != nil {
if !statesOnly {
highlights[start+loc[1]-1] = curRegion.group
@ -144,7 +168,7 @@ func (h *Highlighter) highlightRegion(highlights LineMatch, start int, canMatchE
var firstRegion *region
for _, r := range curRegion.rules.regions {
loc := findIndex(r.start, line, start == 0, canMatchEnd)
loc := findIndex(r.start, nil, line, start == 0, canMatchEnd)
if loc != nil {
if loc[0] < firstLoc[0] {
firstLoc = loc
@ -198,7 +222,7 @@ func (h *Highlighter) highlightEmptyRegion(highlights LineMatch, start int, canM
firstLoc := []int{len(line), 0}
var firstRegion *region
for _, r := range h.Def.rules.regions {
loc := findIndex(r.start, line, start == 0, canMatchEnd)
loc := findIndex(r.start, nil, line, start == 0, canMatchEnd)
if loc != nil {
if loc[0] < firstLoc[0] {
firstLoc = loc

View file

@ -4,8 +4,6 @@ import (
"fmt"
"regexp"
"github.com/dlclark/regexp2"
"gopkg.in/yaml.v2"
)
@ -61,8 +59,9 @@ type rules struct {
type region struct {
group Group
parent *region
start *regexp2.Regexp
end *regexp2.Regexp
start *regexp.Regexp
end *regexp.Regexp
skip *regexp.Regexp
rules *rules
}
@ -217,18 +216,27 @@ func parseRegion(group string, regionInfo map[interface{}]interface{}, prevRegio
region.group = groupNum
region.parent = prevRegion
region.start, err = regexp2.Compile(regionInfo["start"].(string), 0)
region.start, err = regexp.Compile(regionInfo["start"].(string))
if err != nil {
return nil, err
}
region.end, err = regexp2.Compile(regionInfo["end"].(string), 0)
region.end, err = regexp.Compile(regionInfo["end"].(string))
if err != nil {
return nil, err
}
// skip is optional
if _, ok := regionInfo["skip"]; ok {
region.skip, err = regexp.Compile(regionInfo["skip"].(string))
if err != nil {
return nil, err
}
}
region.rules, err = parseRules(regionInfo["rules"].([]interface{}), region)
if err != nil {

File diff suppressed because one or more lines are too long

View file

@ -250,7 +250,7 @@ And here are some example regions for Go:
```
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "%."
- constant.specialChar: "\\\\[abfnrtv'\\\"\\\\]"
@ -269,10 +269,20 @@ And here are some example regions for Go:
- todo: "(TODO|XXX|FIXME):?"
```
Notice how the regions may contain rules inside of them.
Notice how the regions may contain rules inside of them. Any inner rules that are matched are then skipped when searching
for the end of the region. For example, when highlighting `"foo \" bar"`, since `\"` is matched by an inner rule in the
region, it is skipped. Likewise for `"foo \\" bar`, since `\\` is matched by an inner rule, it is skipped, and then the `"`
is found and the string ends at the correct place.
Also the regexes for region start and end may contain more complex regexes with lookahead and lookbehind,
but this is not supported for pattern regexes.
You may also explicitly mark skip regexes if you don't want them to be highlighted. For example:
```
- constant.string:
start: "\""
end: "\""
skip: "\\."
rules: []
```
#### Includes

View file

@ -46,7 +46,7 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."

View file

@ -74,13 +74,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- preproc: "..+"
- constant.specialChar: "\\\\."

View file

@ -90,13 +90,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -24,13 +24,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -27,13 +27,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- preproc: "..+"
- constant.specialChar: "\\\\."

View file

@ -10,7 +10,7 @@ rules:
- constant.specialChar: "^\\s*}$"
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."

View file

@ -24,7 +24,7 @@ rules:
# String highlighting
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "(\\\\u[0-9A-fa-f]{4,4}|\\\\newline|\\\\space|\\\\tab|\\\\formfeed|\\\\backspace|\\\\return|\\\\.)"

View file

@ -15,13 +15,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -16,7 +16,7 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."

View file

@ -6,7 +6,7 @@ detect:
rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules: []
- comment:

View file

@ -28,13 +28,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- preproc: "..+"
- constant.specialChar: "\\\\."

View file

@ -32,14 +32,14 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialchar: "\\\\."
- special: "#\\{[^}]*\\}"
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules: []
- comment:

View file

@ -23,14 +23,14 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\([btnfr]|'|\\\"|\\\\)"
- constant.specialChar: "\\\\u[A-Fa-f0-9]{4}"
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\([btnfr]|'|\\\"|\\\\)"
- constant.specialChar: "\\\\u[A-Fa-f0-9]{4}"

View file

@ -24,12 +24,12 @@ rules:
# Strings
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."
- special: "\"|'"

View file

@ -32,13 +32,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -26,7 +26,7 @@ rules:
# Character literals
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."
# Keywords
@ -52,13 +52,13 @@ rules:
# DoubleQuotedString
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
# WysiwygString
- constant.string:
start: "r\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
@ -69,7 +69,7 @@ rules:
# HexString
- constant.string:
start: "x\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
# DelimitedString

View file

@ -32,13 +32,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -22,13 +22,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -10,7 +10,7 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."

View file

@ -29,13 +29,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules: []
- comment:

View file

@ -43,13 +43,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -46,13 +46,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\([0-7]{3}|x[A-Fa-f0-9]{2}|u[A-Fa-f0-9]{4}|U[A-Fa-f0-9]{8})"
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\([0-7]{3}|x[A-Fa-f0-9]{2}|u[A-Fa-f0-9]{4}|U[A-Fa-f0-9]{8})"

View file

@ -28,13 +28,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -29,7 +29,7 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "%."
- constant.specialChar: "\\\\[abfnrtv'\\\"\\\\]"
@ -37,7 +37,7 @@ rules:
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- error: "..+"
- constant.specialChar: "%."

View file

@ -47,13 +47,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -29,7 +29,7 @@ rules:
# Strings
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."

View file

@ -10,7 +10,7 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules: []
- default:

View file

@ -12,13 +12,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- preproc: "..+"
- constant.specialChar: "\\\\."

View file

@ -21,13 +21,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -12,12 +12,12 @@ rules:
- constant: "\\b(true|false)\\b"
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."
- statement: "\\\"(\\\\\"|[^\"])*\\\"[[:space:]]*:\" \"'(\\'|[^'])*'[[:space:]]*:"

View file

@ -10,12 +10,12 @@ rules:
- special: "="
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."
- comment:

View file

@ -11,7 +11,7 @@ rules:
- special: "[(){}<>]|\\[|\\]"
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- comment:

View file

@ -26,13 +26,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -23,7 +23,7 @@ rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."
- identifier: "\\$+(\\{[^} ]+\\}|\\([^) ]+\\))"

View file

@ -15,7 +15,7 @@ rules:
rules: []
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.number: "#[0-9 A-F a-f]+"

View file

@ -34,13 +34,13 @@ rules:
- constant.string:
start: "@\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."

View file

@ -22,7 +22,7 @@ rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."
- preproc:

View file

@ -41,13 +41,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -40,13 +40,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -19,7 +19,7 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."

View file

@ -9,7 +9,7 @@ rules:
- statement: "\\b(def|object|case|trait|lazy|implicit|abstract|class|extends|final|implements|import|instanceof|interface|native|package|private|protected|public|static|strictfp|super|synchronized|throws|volatile|sealed)\\b"
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant: "\\b(true|false|null)\\b"

View file

@ -25,13 +25,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules: []
- comment:

View file

@ -28,12 +28,12 @@ rules:
- todo: "TODO:?"
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -26,7 +26,7 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."

View file

@ -16,13 +16,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -31,12 +31,12 @@ rules:
- todo: "TODO:?"
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -12,13 +12,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -16,13 +16,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules:
- constant.specialChar: "\\\\."

View file

@ -35,13 +35,13 @@ rules:
- constant.string:
start: "\""
end: "(?<!\\\\)\""
end: "\""
rules:
- constant.specialChar: "\\\\."
- constant.string:
start: "'"
end: "(?<!\\\\)'"
end: "'"
rules: []
- comment: