Highlight in parallel

This commit is contained in:
Zachary Yedidia
2020-01-28 20:54:14 -05:00
parent 477bdb3dc8
commit 953f5a0eff
3 changed files with 65 additions and 9 deletions

View File

@@ -7,6 +7,7 @@ import (
"os"
"runtime"
"sort"
"time"
"github.com/go-errors/errors"
isatty "github.com/mattn/go-isatty"
@@ -240,6 +241,22 @@ func main() {
}
}()
// clear the drawchan so we don't redraw excessively
// if someone requested a redraw before we started displaying
for len(screen.DrawChan) > 0 {
<-screen.DrawChan
}
var event tcell.Event
// wait for initial resize event
select {
case event = <-events:
action.Tabs.HandleEvent(event)
case <-time.After(20 * time.Millisecond):
// time out after 10ms
}
for {
// Display everything
screen.Screen.Fill(' ', config.DefStyle)
@@ -252,8 +269,6 @@ func main() {
action.InfoBar.Display()
screen.Screen.Show()
var event tcell.Event
// Check for new events
select {
case f := <-shell.Jobs:

View File

@@ -10,6 +10,7 @@ import (
"path/filepath"
"strconv"
"strings"
"sync"
"time"
"unicode/utf8"
@@ -117,6 +118,7 @@ type Buffer struct {
Highlighter *highlight.Highlighter
// Modifications is the list of modified regions for syntax highlighting
Modifications []Loc
HighlightLock sync.Mutex
// Hash of the original buffer -- empty if fastdirty is on
origHash [md5.Size]byte
@@ -610,7 +612,9 @@ func (b *Buffer) UpdateRules() {
}
if b.Highlighter == nil || syntaxFile != "" {
b.Settings["filetype"] = b.SyntaxDef.FileType
if b.SyntaxDef != nil {
b.Settings["filetype"] = b.SyntaxDef.FileType
}
} else {
b.SyntaxDef = &highlight.EmptyDef
}
@@ -618,8 +622,11 @@ func (b *Buffer) UpdateRules() {
if b.SyntaxDef != nil {
b.Highlighter = highlight.NewHighlighter(b.SyntaxDef)
if b.Settings["syntax"].(bool) {
b.Highlighter.HighlightStates(b)
b.Highlighter.HighlightMatches(b, 0, b.End().Y)
go func() {
b.Highlighter.HighlightStates(b)
b.Highlighter.HighlightMatches(b, 0, b.End().Y)
screen.DrawChan <- true
}()
}
}
}

View File

@@ -3,6 +3,7 @@ package buffer
import (
"bufio"
"io"
"sync"
"unicode/utf8"
"github.com/zyedidia/micro/pkg/highlight"
@@ -38,6 +39,7 @@ type Line struct {
state highlight.State
match highlight.LineMatch
rehighlight bool
lock sync.Mutex
}
const (
@@ -124,12 +126,22 @@ func NewLineArray(size uint64, endings FileFormat, reader io.Reader) *LineArray
if err != nil {
if err == io.EOF {
la.lines = Append(la.lines, Line{data[:], nil, nil, false})
la.lines = Append(la.lines, Line{
data: data[:],
state: nil,
match: nil,
rehighlight: false,
})
}
// Last line was read
break
} else {
la.lines = Append(la.lines, Line{data[:dlen-1], nil, nil, false})
la.lines = Append(la.lines, Line{
data: data[:dlen-1],
state: nil,
match: nil,
rehighlight: false,
})
}
n++
}
@@ -155,9 +167,19 @@ func (la *LineArray) Bytes() []byte {
// newlineBelow adds a newline below the given line number
func (la *LineArray) newlineBelow(y int) {
la.lines = append(la.lines, Line{[]byte{' '}, nil, nil, false})
la.lines = append(la.lines, Line{
data: []byte{' '},
state: nil,
match: nil,
rehighlight: false,
})
copy(la.lines[y+2:], la.lines[y+1:])
la.lines[y+1] = Line{[]byte{}, la.lines[y].state, nil, false}
la.lines[y+1] = Line{
data: []byte{},
state: la.lines[y].state,
match: nil,
rehighlight: false,
}
}
// Inserts a byte array at a given location
@@ -285,28 +307,40 @@ func (la *LineArray) LineBytes(n int) []byte {
// State gets the highlight state for the given line number
func (la *LineArray) State(lineN int) highlight.State {
la.lines[lineN].lock.Lock()
defer la.lines[lineN].lock.Unlock()
return la.lines[lineN].state
}
// SetState sets the highlight state at the given line number
func (la *LineArray) SetState(lineN int, s highlight.State) {
la.lines[lineN].lock.Lock()
defer la.lines[lineN].lock.Unlock()
la.lines[lineN].state = s
}
// SetMatch sets the match at the given line number
func (la *LineArray) SetMatch(lineN int, m highlight.LineMatch) {
la.lines[lineN].lock.Lock()
defer la.lines[lineN].lock.Unlock()
la.lines[lineN].match = m
}
// Match retrieves the match for the given line number
func (la *LineArray) Match(lineN int) highlight.LineMatch {
la.lines[lineN].lock.Lock()
defer la.lines[lineN].lock.Unlock()
return la.lines[lineN].match
}
func (la *LineArray) Rehighlight(lineN int) bool {
la.lines[lineN].lock.Lock()
defer la.lines[lineN].lock.Unlock()
return la.lines[lineN].rehighlight
}
func (la *LineArray) SetRehighlight(lineN int, on bool) {
la.lines[lineN].lock.Lock()
defer la.lines[lineN].lock.Unlock()
la.lines[lineN].rehighlight = on
}