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 <dmitrymaluka@gmail.com>
This commit is contained in:
parent
6e71e37568
commit
b6dcbfa846
1 changed files with 26 additions and 2 deletions
|
@ -77,6 +77,8 @@ type LineStates interface {
|
||||||
State(lineN int) State
|
State(lineN int) State
|
||||||
SetState(lineN int, s State)
|
SetState(lineN int, s State)
|
||||||
SetMatch(lineN int, m LineMatch)
|
SetMatch(lineN int, m LineMatch)
|
||||||
|
Lock()
|
||||||
|
Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// A Highlighter contains the information needed to highlight a string
|
// A Highlighter contains the information needed to highlight a string
|
||||||
|
@ -303,7 +305,13 @@ func (h *Highlighter) HighlightString(input string) []LineMatch {
|
||||||
|
|
||||||
// HighlightStates correctly sets all states for the buffer
|
// HighlightStates correctly sets all states for the buffer
|
||||||
func (h *Highlighter) HighlightStates(input LineStates) {
|
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)
|
line := input.LineBytes(i)
|
||||||
// highlights := make(LineMatch)
|
// highlights := make(LineMatch)
|
||||||
|
|
||||||
|
@ -316,6 +324,7 @@ func (h *Highlighter) HighlightStates(input LineStates) {
|
||||||
curState := h.lastRegion
|
curState := h.lastRegion
|
||||||
|
|
||||||
input.SetState(i, curState)
|
input.SetState(i, curState)
|
||||||
|
input.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +333,9 @@ func (h *Highlighter) HighlightStates(input LineStates) {
|
||||||
// This assumes that all the states are set correctly
|
// This assumes that all the states are set correctly
|
||||||
func (h *Highlighter) HighlightMatches(input LineStates, startline, endline int) {
|
func (h *Highlighter) HighlightMatches(input LineStates, startline, endline int) {
|
||||||
for i := startline; i <= endline; i++ {
|
for i := startline; i <= endline; i++ {
|
||||||
|
input.Lock()
|
||||||
if i >= input.LinesNum() {
|
if i >= input.LinesNum() {
|
||||||
|
input.Unlock()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,6 +350,7 @@ func (h *Highlighter) HighlightMatches(input LineStates, startline, endline int)
|
||||||
}
|
}
|
||||||
|
|
||||||
input.SetMatch(i, match)
|
input.SetMatch(i, match)
|
||||||
|
input.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,9 +362,17 @@ func (h *Highlighter) ReHighlightStates(input LineStates, startline int) int {
|
||||||
|
|
||||||
h.lastRegion = nil
|
h.lastRegion = nil
|
||||||
if startline > 0 {
|
if startline > 0 {
|
||||||
|
input.Lock()
|
||||||
h.lastRegion = input.State(startline - 1)
|
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)
|
line := input.LineBytes(i)
|
||||||
// highlights := make(LineMatch)
|
// highlights := make(LineMatch)
|
||||||
|
|
||||||
|
@ -366,6 +386,7 @@ func (h *Highlighter) ReHighlightStates(input LineStates, startline int) int {
|
||||||
lastState := input.State(i)
|
lastState := input.State(i)
|
||||||
|
|
||||||
input.SetState(i, curState)
|
input.SetState(i, curState)
|
||||||
|
input.Unlock()
|
||||||
|
|
||||||
if curState == lastState {
|
if curState == lastState {
|
||||||
return i
|
return i
|
||||||
|
@ -377,6 +398,9 @@ func (h *Highlighter) ReHighlightStates(input LineStates, startline int) int {
|
||||||
|
|
||||||
// ReHighlightLine will rehighlight the state and match for a single line
|
// ReHighlightLine will rehighlight the state and match for a single line
|
||||||
func (h *Highlighter) ReHighlightLine(input LineStates, lineN int) {
|
func (h *Highlighter) ReHighlightLine(input LineStates, lineN int) {
|
||||||
|
input.Lock()
|
||||||
|
defer input.Unlock()
|
||||||
|
|
||||||
line := input.LineBytes(lineN)
|
line := input.LineBytes(lineN)
|
||||||
highlights := make(LineMatch)
|
highlights := make(LineMatch)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue