"optimized" syntax colouring algorithm slightly; improved delete line behaviour

This commit is contained in:
Felix Angell 2018-04-16 00:50:30 +01:00
parent 0395a358b4
commit 49e7bce3ea
2 changed files with 59 additions and 28 deletions

View File

@ -727,6 +727,12 @@ func (b *Buffer) OnUpdate() bool {
return false
}
type syntaxRuneInfo struct {
background int
foreground int
length int
}
// dimensions of the last character we rendered
var last_w, last_h int
@ -789,7 +795,7 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
currLine := []rune(rope.String())
// char index => colour
matches := map[int]int{}
matches := map[int]syntaxRuneInfo{}
subjects := []cfg.SyntaxCriteria{}
colours := []int{}
@ -803,34 +809,49 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
// HOLY SLOW BATMAN
for idx, _ := range currLine {
for syntaxIndex, syntax := range subjects {
// we have a regex pattern
if syntax.Pattern != "" {
a := currLine[idx:]
match, _ := regexp.MatchString(syntax.Pattern, string(a))
// FIXME this is also very slow!
// we could easily compile all of these
// regular expressions when we load the
// syntax highlighter.
a := string(currLine[idx:])
match, _ := regexp.MatchString(syntax.Pattern, a)
if match {
for i := 0; i < len(string(a)); i++ {
matches[i] = colours[syntaxIndex]
}
}
} else {
for _, subject := range syntax.Match {
if idx+len(subject) > len(currLine) {
// for some reason this affects the whole line
if _, ok := matches[idx]; !ok {
matches[idx] = syntaxRuneInfo{colours[syntaxIndex], -1, len(a)}
continue
}
a := currLine[idx : idx+len(subject)]
if strings.Compare(string(a), subject) == 0 {
for i := 0; i < len(subject); i++ {
if _, ok := matches[i+idx]; ok {
break
}
matches[i+idx] = colours[syntaxIndex]
}
} else {
for _, subject := range syntax.Match {
if idx+len(subject)+1 > len(currLine) {
continue
}
a := currLine[idx : idx+len(subject)+1]
// we only want to match words. so we check that it has a space
// before or after the subject word.
if strings.Compare(string(a), subject+" ") == 0 || strings.Compare(string(a), " "+subject) == 0 {
if _, ok := matches[idx]; !ok {
matches[idx] = syntaxRuneInfo{colours[syntaxIndex], -1, len(string(a))}
break
}
idx += len(subject)
}
}
}
}
}
colorStack := []int{}
var x_col int
for idx, char := range currLine {
switch char {
@ -853,10 +874,18 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
if b.HasFocus && b.curs.x+1 == x_col && b.curs.y == y_col && should_draw {
ctx.SetColor(strife.HexRGB(b.cfg.Theme.Cursor_Invert))
}
if col, ok := matches[idx]; ok {
ctx.SetColor(strife.HexRGB(int32(col)))
if info, ok := matches[idx]; ok {
for i := 0; i < info.length; i++ {
colorStack = append(colorStack, info.background)
}
}
if len(colorStack) > 0 {
var a int32
a, colorStack = int32(colorStack[len(colorStack)-1]), colorStack[:len(colorStack)-1]
ctx.SetColor(strife.HexRGB(a))
}
last_w, last_h = ctx.String(string(char), (rx + ((x_col - 1) * last_w)), (ry + (y_col * last_h)))
}

View File

@ -1,18 +1,20 @@
package gui
// FIXME make this better!
// behaviour is a little off at the moment.
func DeleteLine(b *Buffer) bool {
if b.curs.y == 0 {
for b.curs.x < b.contents[b.curs.y].Len() {
b.curs.move(1, 0)
}
b.deleteBeforeCursor()
return true
}
if b.curs.y >= len(b.contents) {
return false
}
prevLineLen := b.contents[b.curs.y].Len()
b.contents = remove(b.contents[:], b.curs.y)
currLineLen := b.contents[b.curs.y].Len()
if b.curs.x > currLineLen {
amountToMove := prevLineLen - currLineLen
for i := 0; i < amountToMove; i++ {
b.moveLeft()
}
}
return true
}