"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 return false
} }
type syntaxRuneInfo struct {
background int
foreground int
length int
}
// dimensions of the last character we rendered // dimensions of the last character we rendered
var last_w, last_h int 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()) currLine := []rune(rope.String())
// char index => colour // char index => colour
matches := map[int]int{} matches := map[int]syntaxRuneInfo{}
subjects := []cfg.SyntaxCriteria{} subjects := []cfg.SyntaxCriteria{}
colours := []int{} colours := []int{}
@ -803,34 +809,49 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
// HOLY SLOW BATMAN // HOLY SLOW BATMAN
for idx, _ := range currLine { for idx, _ := range currLine {
for syntaxIndex, syntax := range subjects { for syntaxIndex, syntax := range subjects {
// we have a regex pattern
if syntax.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 { if match {
for i := 0; i < len(string(a)); i++ { // for some reason this affects the whole line
matches[i] = colours[syntaxIndex] if _, ok := matches[idx]; !ok {
} matches[idx] = syntaxRuneInfo{colours[syntaxIndex], -1, len(a)}
}
} else {
for _, subject := range syntax.Match {
if idx+len(subject) > len(currLine) {
continue continue
} }
a := currLine[idx : idx+len(subject)] }
if strings.Compare(string(a), subject) == 0 {
for i := 0; i < len(subject); i++ { } else {
if _, ok := matches[i+idx]; ok {
break for _, subject := range syntax.Match {
} if idx+len(subject)+1 > len(currLine) {
matches[i+idx] = colours[syntaxIndex] 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) idx += len(subject)
} }
} }
} }
} }
} }
colorStack := []int{}
var x_col int var x_col int
for idx, char := range currLine { for idx, char := range currLine {
switch char { 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 { 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)) 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))) 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 package gui
// FIXME make this better!
// behaviour is a little off at the moment.
func DeleteLine(b *Buffer) bool { 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) { if b.curs.y >= len(b.contents) {
return false return false
} }
prevLineLen := b.contents[b.curs.y].Len()
b.contents = remove(b.contents[:], b.curs.y) 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 return true
} }