Skip to content

Commit

Permalink
highlighter: Fix race between the async highlighter and the main routine
Browse files Browse the repository at this point in the history
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 <dmitrymaluka@gmail.com>
  • Loading branch information
JoeKar and dmaluka committed Apr 5, 2024
1 parent 10fa1f4 commit 7c141ac
Showing 1 changed file with 26 additions and 2 deletions.
28 changes: 26 additions & 2 deletions pkg/highlight/highlighter.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ type LineStates interface {
State(lineN int) State
SetState(lineN int, s State)
SetMatch(lineN int, m LineMatch)
Lock()
Unlock()
}

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

// HighlightStates correctly sets all states for the buffer
func (h *Highlighter) HighlightStates(input LineStates) {
for i := 0; i < input.LinesNum(); i++ {
for i := 0; ; i++ {
input.Lock()
if i >= input.LinesNum() {
input.Unlock()
break
}

line := input.LineBytes(i)
// highlights := make(LineMatch)

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

input.SetState(i, curState)
input.Unlock()
}
}

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

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

input.SetMatch(i, match)
input.Unlock()
}
}

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

h.lastRegion = nil
if startline > 0 {
input.Lock()
h.lastRegion = input.State(startline - 1)
input.Unlock()
}
for i := startline; i < input.LinesNum(); i++ {
for i := startline; ; i++ {
input.Lock()
if i >= input.LinesNum() {
input.Unlock()
break
}

line := input.LineBytes(i)
// highlights := make(LineMatch)

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

input.SetState(i, curState)
input.Unlock()

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

// ReHighlightLine will rehighlight the state and match for a single line
func (h *Highlighter) ReHighlightLine(input LineStates, lineN int) {
input.Lock()
defer input.Unlock()

line := input.LineBytes(lineN)
highlights := make(LineMatch)

Expand Down

0 comments on commit 7c141ac

Please sign in to comment.