Working by-line syntax highlighting
This commit is contained in:
parent
d1d55277f7
commit
ff039df5d0
2 changed files with 61 additions and 39 deletions
|
@ -6,6 +6,7 @@ import (
|
|||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -208,17 +209,24 @@ func GetRules(buf *Buffer) ([]SyntaxRule, string) {
|
|||
|
||||
// SyntaxMatches is an alias to a map from character numbers to styles,
|
||||
// so map[3] represents the style of the third character
|
||||
type SyntaxMatches map[int]tcell.Style
|
||||
type SyntaxMatches [][]tcell.Style
|
||||
|
||||
// Match takes a buffer and returns the syntax matches a map specifying how it should be syntax highlighted
|
||||
func Match(rules []SyntaxRule, buf *Buffer, v *View) SyntaxMatches {
|
||||
m := make(SyntaxMatches)
|
||||
func Match(v *View) SyntaxMatches {
|
||||
buf := v.buf
|
||||
rules := v.buf.rules
|
||||
|
||||
lineStart := v.updateLines[0]
|
||||
lineEnd := v.updateLines[1] + 1
|
||||
if lineStart < 0 {
|
||||
// Don't need to update syntax highlighting
|
||||
return m
|
||||
viewStart := v.topline
|
||||
viewEnd := v.topline + v.height
|
||||
if viewEnd > len(buf.lines) {
|
||||
viewEnd = len(buf.lines)
|
||||
}
|
||||
|
||||
lines := buf.lines[viewStart:viewEnd]
|
||||
matches := make(SyntaxMatches, len(lines))
|
||||
|
||||
for i, line := range lines {
|
||||
matches[i] = make([]tcell.Style, len(line))
|
||||
}
|
||||
|
||||
totalStart := v.topline - synLinesUp
|
||||
|
@ -230,35 +238,35 @@ func Match(rules []SyntaxRule, buf *Buffer, v *View) SyntaxMatches {
|
|||
totalEnd = len(buf.lines)
|
||||
}
|
||||
|
||||
if lineEnd > len(buf.lines) {
|
||||
lineEnd = len(buf.lines)
|
||||
}
|
||||
|
||||
lines := buf.lines[lineStart:lineEnd]
|
||||
str := strings.Join(buf.lines[totalStart:totalEnd], "\n")
|
||||
startNum := v.cursor.loc + v.cursor.Distance(0, totalStart)
|
||||
toplineNum := v.cursor.loc + v.cursor.Distance(0, v.topline)
|
||||
|
||||
for _, rule := range rules {
|
||||
if rule.startend && rule.regex.MatchString(str) {
|
||||
indicies := rule.regex.FindAllStringIndex(str, -1)
|
||||
for _, value := range indicies {
|
||||
value[0] += startNum
|
||||
value[1] += startNum
|
||||
for i := value[0]; i < value[1]; i++ {
|
||||
if i >= toplineNum {
|
||||
m[i] = rule.style
|
||||
if rule.startend {
|
||||
if rule.regex.MatchString(str) {
|
||||
indicies := rule.regex.FindAllStringIndex(str, -1)
|
||||
for _, value := range indicies {
|
||||
value[0] += startNum
|
||||
value[1] += startNum
|
||||
for i := value[0]; i < value[1]; i++ {
|
||||
colNum, lineNum := GetPos(i, buf)
|
||||
v.m.Message(strconv.Itoa(lineNum) + ", " + strconv.Itoa(colNum))
|
||||
if i >= toplineNum {
|
||||
if lineNum != -1 && colNum != -1 {
|
||||
matches[lineNum][colNum] = rule.style
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, line := range lines {
|
||||
for lineN, line := range lines {
|
||||
if rule.regex.MatchString(line) {
|
||||
indicies := rule.regex.FindAllStringIndex(str, -1)
|
||||
indicies := rule.regex.FindAllStringIndex(line, -1)
|
||||
for _, value := range indicies {
|
||||
value[0] += toplineNum
|
||||
value[1] += toplineNum
|
||||
for i := value[0]; i < value[1]; i++ {
|
||||
m[i] = rule.style
|
||||
matches[lineN][i] = rule.style
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -266,5 +274,22 @@ func Match(rules []SyntaxRule, buf *Buffer, v *View) SyntaxMatches {
|
|||
}
|
||||
}
|
||||
|
||||
return m
|
||||
return matches
|
||||
}
|
||||
|
||||
// GetPos returns an x, y position given a character location in the buffer
|
||||
func GetPos(loc int, buf *Buffer) (int, int) {
|
||||
charNum := 0
|
||||
x, y := 0, 0
|
||||
|
||||
for i, line := range buf.lines {
|
||||
if charNum+Count(line) > loc {
|
||||
y = i
|
||||
x = loc - charNum
|
||||
return x, y
|
||||
}
|
||||
charNum += Count(line) + 1
|
||||
}
|
||||
|
||||
return -1, -1
|
||||
}
|
||||
|
|
21
src/view.go
21
src/view.go
|
@ -91,7 +91,7 @@ func NewViewWidthHeight(buf *Buffer, m *Messenger, w, h int) *View {
|
|||
|
||||
// Update the syntax highlighting for the entire buffer at the start
|
||||
v.UpdateLines(v.topline, v.topline+v.height)
|
||||
// v.matches = Match(v.buf.rules, v.buf, v)
|
||||
v.matches = Match(v)
|
||||
|
||||
// Set mouseReleased to true because we assume the mouse is not being pressed when
|
||||
// the editor is opened
|
||||
|
@ -407,12 +407,16 @@ func (v *View) HandleEvent(event tcell.Event) {
|
|||
v.UpdateLines(v.topline, v.topline+v.height)
|
||||
case tcell.KeyPgUp:
|
||||
v.PageUp()
|
||||
relocate = false
|
||||
case tcell.KeyPgDn:
|
||||
v.PageDown()
|
||||
relocate = false
|
||||
case tcell.KeyCtrlU:
|
||||
v.HalfPageUp()
|
||||
relocate = false
|
||||
case tcell.KeyCtrlD:
|
||||
v.HalfPageDown()
|
||||
relocate = false
|
||||
case tcell.KeyRune:
|
||||
// Insert a character
|
||||
if v.cursor.HasSelection() {
|
||||
|
@ -479,12 +483,12 @@ func (v *View) HandleEvent(event tcell.Event) {
|
|||
v.Relocate()
|
||||
}
|
||||
|
||||
// v.matches = Match(v.buf.rules, v.buf, v)
|
||||
v.matches = Match(v)
|
||||
}
|
||||
|
||||
// DisplayView renders the view to the screen
|
||||
func (v *View) DisplayView() {
|
||||
matches := make(SyntaxMatches)
|
||||
matches := make(SyntaxMatches, len(v.matches))
|
||||
|
||||
// The character number of the character in the top left of the screen
|
||||
charNum := v.cursor.loc + v.cursor.Distance(0, v.topline)
|
||||
|
@ -528,17 +532,10 @@ func (v *View) DisplayView() {
|
|||
|
||||
// Write the line
|
||||
tabchars := 0
|
||||
for _, ch := range line {
|
||||
for colN, ch := range line {
|
||||
var lineStyle tcell.Style
|
||||
// Does the current character need to be syntax highlighted?
|
||||
if st, ok := v.matches[charNum]; ok {
|
||||
highlightStyle = st
|
||||
} else if st, ok := v.lastMatches[charNum]; ok {
|
||||
highlightStyle = st
|
||||
} else {
|
||||
highlightStyle = tcell.StyleDefault
|
||||
}
|
||||
matches[charNum] = highlightStyle
|
||||
highlightStyle = v.matches[lineN][colN]
|
||||
|
||||
if v.cursor.HasSelection() &&
|
||||
(charNum >= v.cursor.selectionStart && charNum <= v.cursor.selectionEnd ||
|
||||
|
|
Loading…
Reference in a new issue