@@ -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