Skip to content

Commit e9effe8

Browse files
committed
highlighter: Reintroduction of statesOnly to fix bottom up changes
This regression was introduced by accident in the moment the highlighting interfaces have been combined. The MarkModified() method of the buffer wasn't able to highlight bottom up changes lines in the backward direction.
1 parent 7f6733a commit e9effe8

File tree

2 files changed

+57
-29
lines changed

2 files changed

+57
-29
lines changed

internal/buffer/buffer.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,11 @@ func (b *SharedBuffer) MarkModified(start, end int) {
150150
end = util.Clamp(end, 0, len(b.lines)-1)
151151

152152
if b.Settings["syntax"].(bool) && b.SyntaxDef != nil {
153+
l := start
153154
for i := start; i <= end; i++ {
154-
b.Highlighter.Highlight(b, start, end)
155+
l = util.Max(b.Highlighter.Highlight(b, i, end, true), l)
155156
}
157+
b.Highlighter.Highlight(b, start, l, false)
156158
}
157159

158160
for i := start; i <= end; i++ {
@@ -817,7 +819,7 @@ func (b *Buffer) UpdateRules() {
817819
b.Highlighter = highlight.NewHighlighter(b.SyntaxDef)
818820
if b.Settings["syntax"].(bool) {
819821
go func() {
820-
b.Highlighter.Highlight(b, 0, b.End().Y)
822+
b.Highlighter.Highlight(b, 0, b.End().Y, false)
821823
screen.Redraw()
822824
}()
823825
}

pkg/highlight/highlighter.go

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,11 @@ func findAllIndex(regex *regexp.Regexp, skip *regexp.Regexp, str []byte) [][]int
9191
return matches
9292
}
9393

94-
func (h *Highlighter) highlightRange(fullHighlights []Group, start int, end int, group Group) {
94+
func (h *Highlighter) highlightRange(fullHighlights []Group, start int, end int, group Group, statesOnly bool) {
95+
if statesOnly {
96+
return
97+
}
98+
9599
if start <= end && end <= len(fullHighlights) {
96100
for i := start; i < end; i++ {
97101
fullHighlights[i] = group
@@ -100,10 +104,10 @@ func (h *Highlighter) highlightRange(fullHighlights []Group, start int, end int,
100104
}
101105
}
102106

103-
func (h *Highlighter) highlightPatterns(fullHighlights []Group, start int, lineNum int, line []byte, curRegion *region) {
107+
func (h *Highlighter) highlightPatterns(fullHighlights []Group, start int, lineNum int, line []byte, curRegion *region, statesOnly bool) {
104108
lineLen := util.CharacterCount(line)
105109
// log.Println("highlightPatterns: lineNum:", lineNum, "start:", start, "line:", string(line))
106-
if lineLen == 0 {
110+
if lineLen == 0 || statesOnly {
107111
return
108112
}
109113

@@ -118,20 +122,20 @@ func (h *Highlighter) highlightPatterns(fullHighlights []Group, start int, lineN
118122
if curRegion == nil || curRegion.group == curRegion.limitGroup || p.group == curRegion.limitGroup {
119123
matches := findAllIndex(p.regex, nil, line)
120124
for _, m := range matches {
121-
h.highlightRange(fullHighlights, start+m[0], start+m[1], p.group)
125+
h.highlightRange(fullHighlights, start+m[0], start+m[1], p.group, statesOnly)
122126
}
123127
}
124128
}
125129
}
126130

127-
func (h *Highlighter) highlightRegions(fullHighlights []Group, start int, lineNum int, line []byte, curRegion *region, regions []*region, nestedRegion bool) {
131+
func (h *Highlighter) highlightRegions(fullHighlights []Group, start int, lineNum int, line []byte, curRegion *region, regions []*region, nestedRegion bool, statesOnly bool) {
128132
lineLen := util.CharacterCount(line)
129133
// log.Println("highlightRegions: lineNum:", lineNum, "start:", start, "line:", string(line))
130134
if lineLen == 0 {
131135
return
132136
}
133137

134-
h.highlightPatterns(fullHighlights, start, lineNum, line, curRegion)
138+
h.highlightPatterns(fullHighlights, start, lineNum, line, curRegion, statesOnly)
135139

136140
lastStart := 0
137141
regionStart := 0
@@ -176,8 +180,8 @@ func (h *Highlighter) highlightRegions(fullHighlights []Group, start int, lineNu
176180
// log.Println("start < end")
177181
regionStart = startMatches[startIdx][0]
178182
regionEnd = endMatches[endIdx][1]
179-
h.highlightRange(fullHighlights, start+startMatches[startIdx][0], start+endMatches[endIdx][1], r.limitGroup)
180-
h.highlightRegions(fullHighlights, start+startMatches[startIdx][1], lineNum, util.SliceStartEnd(line, startMatches[startIdx][1], endMatches[endIdx][0]), r, r.rules.regions, true)
183+
h.highlightRange(fullHighlights, start+startMatches[startIdx][0], start+endMatches[endIdx][1], r.limitGroup, statesOnly)
184+
h.highlightRegions(fullHighlights, start+startMatches[startIdx][1], lineNum, util.SliceStartEnd(line, startMatches[startIdx][1], endMatches[endIdx][0]), r, r.rules.regions, true, statesOnly)
181185
if samePattern {
182186
startIdx += 1
183187
}
@@ -196,9 +200,9 @@ func (h *Highlighter) highlightRegions(fullHighlights []Group, start int, lineNu
196200
}
197201
// start and end at the current line, but switched
198202
// log.Println("end < start")
199-
h.highlightRange(fullHighlights, start, start+endMatches[endIdx][1], r.limitGroup)
200-
h.highlightRegions(fullHighlights, start, lineNum, util.SliceStart(line, endMatches[endIdx][0]), r, r.rules.regions, true)
201-
h.highlightPatterns(fullHighlights, start+endMatches[endIdx][1], lineNum, util.SliceStartEnd(line, endMatches[endIdx][1], startMatches[startIdx][0]), nil)
203+
h.highlightRange(fullHighlights, start, start+endMatches[endIdx][1], r.limitGroup, statesOnly)
204+
h.highlightRegions(fullHighlights, start, lineNum, util.SliceStart(line, endMatches[endIdx][0]), r, r.rules.regions, true, statesOnly)
205+
h.highlightPatterns(fullHighlights, start+endMatches[endIdx][1], lineNum, util.SliceStartEnd(line, endMatches[endIdx][1], startMatches[startIdx][0]), nil, statesOnly)
202206
if curRegion != nil {
203207
h.lastRegion = curRegion.parent
204208
} else {
@@ -212,8 +216,8 @@ func (h *Highlighter) highlightRegions(fullHighlights []Group, start int, lineNu
212216
// log.Println("start ...")
213217
regionStart = startMatches[startIdx][0]
214218
regionEnd = 0
215-
h.highlightRange(fullHighlights, start+startMatches[startIdx][0], lineLen, r.limitGroup)
216-
h.highlightRegions(fullHighlights, start+startMatches[startIdx][1], lineNum, util.SliceEnd(line, startMatches[startIdx][1]), r, r.rules.regions, true)
219+
h.highlightRange(fullHighlights, start+startMatches[startIdx][0], lineLen, r.limitGroup, statesOnly)
220+
h.highlightRegions(fullHighlights, start+startMatches[startIdx][1], lineNum, util.SliceEnd(line, startMatches[startIdx][1]), r, r.rules.regions, true, statesOnly)
217221
if lastStart <= startMatches[startIdx][0] {
218222
lastStart = startMatches[startIdx][0]
219223
h.lastRegion = r
@@ -226,8 +230,8 @@ func (h *Highlighter) highlightRegions(fullHighlights []Group, start int, lineNu
226230
for _, endMatch := range endMatches {
227231
// end at the current, but start at the previous line
228232
// log.Println("... end")
229-
h.highlightRange(fullHighlights, start, start+endMatch[1], r.limitGroup)
230-
h.highlightRegions(fullHighlights, start, lineNum, util.SliceStart(line, endMatch[0]), r, r.rules.regions, true)
233+
h.highlightRange(fullHighlights, start, start+endMatch[1], r.limitGroup, statesOnly)
234+
h.highlightRegions(fullHighlights, start, lineNum, util.SliceStart(line, endMatch[0]), r, r.rules.regions, true, statesOnly)
231235
if curRegion != nil {
232236
h.lastRegion = curRegion.parent
233237
} else {
@@ -238,25 +242,27 @@ func (h *Highlighter) highlightRegions(fullHighlights []Group, start int, lineNu
238242
}
239243
} else if len(startMatches) == 0 && len(endMatches) == 0 {
240244
// no start and end found in this region
241-
h.highlightRange(fullHighlights, start, lineLen, curRegion.group)
245+
h.highlightRange(fullHighlights, start, lineLen, curRegion.group, statesOnly)
242246
}
243247
}
244248
}
245249
}
246250

247-
func (h *Highlighter) highlight(highlights LineMatch, start int, lineNum int, line []byte, curRegion *region) LineMatch {
251+
func (h *Highlighter) highlight(highlights LineMatch, start int, lineNum int, line []byte, curRegion *region, statesOnly bool) LineMatch {
248252
lineLen := util.CharacterCount(line)
249253
// log.Println("highlight: lineNum:", lineNum, "start:", start, "line:", string(line))
250254
if lineLen == 0 {
251255
return highlights
252256
}
253257

254258
fullHighlights := make([]Group, lineLen)
255-
h.highlightRegions(fullHighlights, start, lineNum, line, curRegion, h.Def.rules.regions, false)
259+
h.highlightRegions(fullHighlights, start, lineNum, line, curRegion, h.Def.rules.regions, false, statesOnly)
256260

257-
for i, h := range fullHighlights {
258-
if i == 0 || h != fullHighlights[i-1] {
259-
highlights[i] = h
261+
if !statesOnly {
262+
for i, h := range fullHighlights {
263+
if i == 0 || h != fullHighlights[i-1] {
264+
highlights[i] = h
265+
}
260266
}
261267
}
262268

@@ -274,20 +280,28 @@ func (h *Highlighter) HighlightString(input string) []LineMatch {
274280
for i := 0; i < len(lines); i++ {
275281
line := []byte(lines[i])
276282
highlights := make(LineMatch)
277-
lineMatches = append(lineMatches, h.highlight(highlights, 0, i, line, nil))
283+
lineMatches = append(lineMatches, h.highlight(highlights, 0, i, line, nil, false))
278284
}
279285

280286
return lineMatches
281287
}
282288

283289
// Highlight sets the state and matches for each line from startline to endline
284290
// It sets all other matches in the buffer to nil to conserve memory
285-
func (h *Highlighter) Highlight(input LineStates, startline, endline int) {
291+
// In the moment it is called with statesOnly set it will scan down from
292+
// `startline` and set the appropriate end of line state for each line
293+
// until it comes across a line whose state does not change
294+
// returns the number of the final line
295+
func (h *Highlighter) Highlight(input LineStates, startline, endline int, statesOnly bool) int {
286296
h.lastRegion = nil
287297
if startline > 0 {
288298
h.lastRegion = input.State(startline - 1)
289299
}
290300

301+
if statesOnly {
302+
endline = input.LinesNum() - 1
303+
}
304+
291305
for i := startline; i <= endline; i++ {
292306
if i >= input.LinesNum() {
293307
break
@@ -297,11 +311,23 @@ func (h *Highlighter) Highlight(input LineStates, startline, endline int) {
297311
highlights := make(LineMatch)
298312

299313
var match LineMatch
300-
match = h.highlight(highlights, 0, i, line, h.lastRegion)
314+
match = h.highlight(highlights, 0, i, line, h.lastRegion, statesOnly)
301315

302-
input.SetState(i, h.lastRegion)
303-
input.SetMatch(i, match)
316+
curState := h.lastRegion
317+
lastState := input.State(i)
318+
319+
input.SetState(i, curState)
320+
321+
if !statesOnly {
322+
input.SetMatch(i, match)
323+
} else {
324+
if curState == lastState {
325+
return i
326+
}
327+
}
304328
}
329+
330+
return input.LinesNum() - 1
305331
}
306332

307333
// ReHighlightLine will rehighlight the state and match for a single line
@@ -315,7 +341,7 @@ func (h *Highlighter) ReHighlightLine(input LineStates, lineN int) {
315341
}
316342

317343
var match LineMatch
318-
match = h.highlight(highlights, 0, lineN, line, h.lastRegion)
344+
match = h.highlight(highlights, 0, lineN, line, h.lastRegion, false)
319345

320346
input.SetState(lineN, h.lastRegion)
321347
input.SetMatch(lineN, match)

0 commit comments

Comments
 (0)