Skip to content

Commit

Permalink
highlighter: Fix regions and patterns inside regions (#2840)
Browse files Browse the repository at this point in the history
* highlighter: Fix regions and patterns inside regions

* highlighting: Remove 2nd recursive highlightRegion() call

...and add limitGroup checks to pattern search.

* yaml: Add TODO type highlighting

* highlighting: Don't stop in highlightRegion() at empty lines

...because possible region line end pattern must be detected.

* syntax/sh: Correct string handling due to additional pattern handling

* syntax/sh: Remove slash in variables

* highlighter: Accept nested region only in case it's within the current reagion

* highlighter: Accept nested patterns only in case it's within the current reagion

* highlighter: Don't search for nesting in case the region end was found at start
  • Loading branch information
JoeKar authored Jul 11, 2023
1 parent cb260bf commit ceaa143
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 50 deletions.
95 changes: 51 additions & 44 deletions pkg/highlight/highlighter.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,51 +134,33 @@ func (h *Highlighter) highlightRegion(highlights LineMatch, start int, canMatchE
}
}

loc := findIndex(curRegion.end, curRegion.skip, line)
if loc != nil {
if !statesOnly {
highlights[start+loc[0]] = curRegion.limitGroup
}
if curRegion.parent == nil {
if !statesOnly {
highlights[start+loc[1]] = 0
}
h.highlightEmptyRegion(highlights, start+loc[1], canMatchEnd, lineNum, sliceStart(line, loc[1]), statesOnly)
return highlights
}
if !statesOnly {
highlights[start+loc[1]] = curRegion.parent.group
h.highlightRegion(highlights, start, false, lineNum, sliceEnd(line, loc[0]), curRegion, statesOnly)
}
h.highlightRegion(highlights, start+loc[1], canMatchEnd, lineNum, sliceStart(line, loc[1]), curRegion.parent, statesOnly)
return highlights
}

if lineLen == 0 {
if canMatchEnd {
h.lastRegion = curRegion
var firstRegion *region
firstLoc := []int{lineLen, 0}
searchNesting := true
endLoc := findIndex(curRegion.end, curRegion.skip, line)
if endLoc != nil {
if start == endLoc[0] {
searchNesting = false
} else {
firstLoc = endLoc
}

return highlights
}

firstLoc := []int{lineLen, 0}

var firstRegion *region
for _, r := range curRegion.rules.regions {
loc := findIndex(r.start, r.skip, line)
if loc != nil {
if loc[0] < firstLoc[0] {
firstLoc = loc
firstRegion = r
if searchNesting {
for _, r := range curRegion.rules.regions {
loc := findIndex(r.start, r.skip, line)
if loc != nil {
if loc[0] < firstLoc[0] {
firstLoc = loc
firstRegion = r
}
}
}
}
if firstLoc[0] != lineLen {
if firstRegion != nil && firstLoc[0] != lineLen {
if !statesOnly {
highlights[start+firstLoc[0]] = firstRegion.limitGroup
}
h.highlightRegion(highlights, start, false, lineNum, sliceEnd(line, firstLoc[0]), curRegion, statesOnly)
h.highlightEmptyRegion(highlights, start+firstLoc[1], canMatchEnd, lineNum, sliceStart(line, firstLoc[1]), statesOnly)
h.highlightRegion(highlights, start+firstLoc[1], canMatchEnd, lineNum, sliceStart(line, firstLoc[1]), firstRegion, statesOnly)
return highlights
}
Expand All @@ -189,11 +171,17 @@ func (h *Highlighter) highlightRegion(highlights LineMatch, start int, canMatchE
fullHighlights[i] = curRegion.group
}

for _, p := range curRegion.rules.patterns {
matches := findAllIndex(p.regex, line)
for _, m := range matches {
for i := m[0]; i < m[1]; i++ {
fullHighlights[i] = p.group
if searchNesting {
for _, p := range curRegion.rules.patterns {
if curRegion.group == curRegion.limitGroup || p.group == curRegion.limitGroup {
matches := findAllIndex(p.regex, line)
for _, m := range matches {
if ((endLoc == nil) || (m[0] < endLoc[0])) {
for i := m[0]; i < m[1]; i++ {
fullHighlights[i] = p.group
}
}
}
}
}
}
Expand All @@ -204,6 +192,25 @@ func (h *Highlighter) highlightRegion(highlights LineMatch, start int, canMatchE
}
}

loc := endLoc
if loc != nil {
if !statesOnly {
highlights[start+loc[0]] = curRegion.limitGroup
}
if curRegion.parent == nil {
if !statesOnly {
highlights[start+loc[1]] = 0
}
h.highlightEmptyRegion(highlights, start+loc[1], canMatchEnd, lineNum, sliceStart(line, loc[1]), statesOnly)
return highlights
}
if !statesOnly {
highlights[start+loc[1]] = curRegion.parent.group
}
h.highlightRegion(highlights, start+loc[1], canMatchEnd, lineNum, sliceStart(line, loc[1]), curRegion.parent, statesOnly)
return highlights
}

if canMatchEnd {
h.lastRegion = curRegion
}
Expand All @@ -220,8 +227,8 @@ func (h *Highlighter) highlightEmptyRegion(highlights LineMatch, start int, canM
return highlights
}

firstLoc := []int{lineLen, 0}
var firstRegion *region
firstLoc := []int{lineLen, 0}
for _, r := range h.Def.rules.regions {
loc := findIndex(r.start, r.skip, line)
if loc != nil {
Expand All @@ -231,7 +238,7 @@ func (h *Highlighter) highlightEmptyRegion(highlights LineMatch, start int, canM
}
}
}
if firstLoc[0] != lineLen {
if firstRegion != nil && firstLoc[0] != lineLen {
if !statesOnly {
highlights[start+firstLoc[0]] = firstRegion.limitGroup
}
Expand Down
6 changes: 3 additions & 3 deletions runtime/syntax/sh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@ rules:
- statement: " (-[A-Za-z]+|--[a-z]+)"

- identifier: "\\$\\{[0-9A-Za-z_:!%&=+#~@*^$?, .\\-\\/\\[\\]]+\\}"
- identifier: "\\$[0-9A-Za-z_:!%&=+#~@*^$?,\\-\\/\\[\\]]+"
- identifier: "\\$[0-9A-Za-z_:!%&=+#~@*^$?,\\-\\[\\]]+"

- constant.string:
start: "\""
end: "\""
skip: "\\\\."
rules:
- constant.specialChar: "\\\\."
rules: []

- constant.string:
start: "'"
end: "'"
skip: "\\\\."
rules: []

- comment:
Expand Down
5 changes: 2 additions & 3 deletions runtime/syntax/yaml.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,5 @@ rules:
- comment:
start: "#"
end: "$"
rules: []


rules:
- todo: "(TODO|XXX|FIXME):?"

0 comments on commit ceaa143

Please sign in to comment.