Skip to content

Commit b6dcbfa

Browse files
JoeKardmaluka
andcommitted
highlighter: Fix race between the async highlighter and the main routine
This is achieved by the usage of the new `LineArray` locking machanism, which prevents the interruption in the moment of modifications like insertion or removal of lines. Co-authored-by: Dmytro Maluka <[email protected]>
1 parent 6e71e37 commit b6dcbfa

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

pkg/highlight/highlighter.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ type LineStates interface {
7777
State(lineN int) State
7878
SetState(lineN int, s State)
7979
SetMatch(lineN int, m LineMatch)
80+
Lock()
81+
Unlock()
8082
}
8183

8284
// A Highlighter contains the information needed to highlight a string
@@ -303,7 +305,13 @@ func (h *Highlighter) HighlightString(input string) []LineMatch {
303305

304306
// HighlightStates correctly sets all states for the buffer
305307
func (h *Highlighter) HighlightStates(input LineStates) {
306-
for i := 0; i < input.LinesNum(); i++ {
308+
for i := 0; ; i++ {
309+
input.Lock()
310+
if i >= input.LinesNum() {
311+
input.Unlock()
312+
break
313+
}
314+
307315
line := input.LineBytes(i)
308316
// highlights := make(LineMatch)
309317

@@ -316,6 +324,7 @@ func (h *Highlighter) HighlightStates(input LineStates) {
316324
curState := h.lastRegion
317325

318326
input.SetState(i, curState)
327+
input.Unlock()
319328
}
320329
}
321330

@@ -324,7 +333,9 @@ func (h *Highlighter) HighlightStates(input LineStates) {
324333
// This assumes that all the states are set correctly
325334
func (h *Highlighter) HighlightMatches(input LineStates, startline, endline int) {
326335
for i := startline; i <= endline; i++ {
336+
input.Lock()
327337
if i >= input.LinesNum() {
338+
input.Unlock()
328339
break
329340
}
330341

@@ -339,6 +350,7 @@ func (h *Highlighter) HighlightMatches(input LineStates, startline, endline int)
339350
}
340351

341352
input.SetMatch(i, match)
353+
input.Unlock()
342354
}
343355
}
344356

@@ -350,9 +362,17 @@ func (h *Highlighter) ReHighlightStates(input LineStates, startline int) int {
350362

351363
h.lastRegion = nil
352364
if startline > 0 {
365+
input.Lock()
353366
h.lastRegion = input.State(startline - 1)
367+
input.Unlock()
354368
}
355-
for i := startline; i < input.LinesNum(); i++ {
369+
for i := startline; ; i++ {
370+
input.Lock()
371+
if i >= input.LinesNum() {
372+
input.Unlock()
373+
break
374+
}
375+
356376
line := input.LineBytes(i)
357377
// highlights := make(LineMatch)
358378

@@ -366,6 +386,7 @@ func (h *Highlighter) ReHighlightStates(input LineStates, startline int) int {
366386
lastState := input.State(i)
367387

368388
input.SetState(i, curState)
389+
input.Unlock()
369390

370391
if curState == lastState {
371392
return i
@@ -377,6 +398,9 @@ func (h *Highlighter) ReHighlightStates(input LineStates, startline int) int {
377398

378399
// ReHighlightLine will rehighlight the state and match for a single line
379400
func (h *Highlighter) ReHighlightLine(input LineStates, lineN int) {
401+
input.Lock()
402+
defer input.Unlock()
403+
380404
line := input.LineBytes(lineN)
381405
highlights := make(LineMatch)
382406

0 commit comments

Comments
 (0)