Major optimization for syntax highlighting

This commit is contained in:
Zachary Yedidia
2016-03-21 12:07:48 -04:00
parent e61048154b
commit d429dc3df2
3 changed files with 37 additions and 15 deletions

View File

@@ -121,18 +121,25 @@ func GetRules(buf *Buffer) (string, string) {
// Match takes a buffer and returns a map specifying how it should be syntax highlighted
// The map is from character numbers to styles, so map[3] represents the style change
// at the third character in the buffer
func Match(rules string, buf *Buffer) map[int]tcell.Style {
// rules := strings.TrimSpace(GetRules(buf))
str := buf.text
// Note that this map only stores changes in styles, not each character's style
func Match(rules string, buf *Buffer, v *View) map[int]tcell.Style {
start := v.topline - synLinesUp
end := v.topline + v.height + synLinesDown
if start < 0 {
start = 0
}
if end > len(buf.lines) {
end = len(buf.lines)
}
str := strings.Join(buf.lines[start:end], "\n")
startNum := v.cursor.loc + v.cursor.Distance(0, start)
toplineNum := v.cursor.loc + v.cursor.Distance(0, v.topline)
lines := strings.Split(rules, "\n")
m := make(map[int]tcell.Style)
parser := regexp.MustCompile(`color (.*?)\s+"(.*)"`)
for _, line := range lines {
if strings.TrimSpace(line) == "" ||
strings.TrimSpace(line)[0] == '#' ||
strings.HasPrefix(line, "syntax") ||
strings.HasPrefix(line, "header") {
if strings.TrimSpace(line) == "" {
// Ignore this line
continue
}
@@ -148,14 +155,25 @@ func Match(rules string, buf *Buffer) map[int]tcell.Style {
if regex.MatchString(str) {
indicies := regex.FindAllStringIndex(str, -1)
for _, value := range indicies {
value[0] += startNum
value[1] += startNum
for i := value[0] + 1; i < value[1]; i++ {
if _, exists := m[i]; exists {
delete(m, i)
}
}
m[value[0]] = st
if _, exists := m[value[1]]; !exists {
m[value[1]] = tcell.StyleDefault
if value[0] < toplineNum && value[1] > toplineNum {
m[toplineNum] = st
}
if value[0] >= toplineNum {
m[value[0]] = st
}
if value[1] >= toplineNum {
if _, exists := m[value[1]]; !exists {
m[value[1]] = tcell.StyleDefault
}
}
}
}

View File

@@ -10,7 +10,9 @@ import (
)
const (
tabSize = 4
tabSize = 4
synLinesUp = 100
synLinesDown = 100
)
func main() {
@@ -71,6 +73,7 @@ func main() {
redraw := 2
for {
if redraw == 2 {
v.matches = Match(v.buf.rules, v.buf, v)
s.Clear()
v.Display()
v.cursor.Display()

View File

@@ -23,6 +23,9 @@ type View struct {
mouseReleased bool
// Syntax highlighting matches
matches map[int]tcell.Style
s tcell.Screen
}
@@ -301,8 +304,6 @@ func (v *View) Display() {
charNum := v.cursor.loc + v.cursor.Distance(0, v.topline)
matches := Match(v.buf.rules, v.buf)
// Convert the length of buffer to a string, and get the length of the string
// We are going to have to offset by that amount
maxLineLength := len(strconv.Itoa(len(v.buf.lines)))
@@ -338,7 +339,7 @@ func (v *View) Display() {
tabchars := 0
for _, ch := range line {
var lineStyle tcell.Style
st, ok := matches[charNum]
st, ok := v.matches[charNum]
if ok {
highlightStyle = st
}
@@ -365,7 +366,7 @@ func (v *View) Display() {
x++
}
x = 0
st, ok := matches[charNum]
st, ok := v.matches[charNum]
if ok {
highlightStyle = st
}