prototype syntax highlighter semi works!

This commit is contained in:
Felix Angell 2018-04-13 21:08:26 +01:00
parent aa656e6b7a
commit 55a48faa71
4 changed files with 109 additions and 10 deletions

View File

@ -1,6 +1,7 @@
package cfg package cfg
import ( import (
"errors"
"log" "log"
"runtime" "runtime"
"strconv" "strconv"
@ -8,11 +9,32 @@ import (
) )
type TomlConfig struct { type TomlConfig struct {
Editor EditorConfig Editor EditorConfig `toml:"editor"`
Cursor CursorConfig Cursor CursorConfig `toml:"cursor"`
Render RenderConfig Render RenderConfig `toml:"render"`
Theme ThemeConfig Theme ThemeConfig `toml:"theme"`
Commands map[string]Command Associations map[string]FileAssociations `toml:"file_associations"`
Commands map[string]Command `toml:"commands"`
Syntax map[string]map[string]SyntaxCriteria `toml:"syntax"`
// this maps ext => language
// when we have file associations from
// the Associations field we take
// each extension and put them here
// pointing it to the language.
// basically the reverse/opposite
associations map[string]string
}
func (t *TomlConfig) GetLanguageFromExt(ext string) (string, error) {
if val, ok := t.associations[ext]; ok {
return val, nil
}
return "", errors.New("no language for extension '" + ext + "'")
}
type FileAssociations struct {
Extensions []string
} }
var DEFUALT_TOML_CONFIG string = getDefaultConfig() var DEFUALT_TOML_CONFIG string = getDefaultConfig()
@ -31,6 +53,11 @@ func getDefaultConfig() string {
return DEFAULT_WINDOWS_TOML_CONFIG return DEFAULT_WINDOWS_TOML_CONFIG
} }
type SyntaxCriteria struct {
Colour int `toml:"colouring"`
Match []string `toml:"match"`
}
type Command struct { type Command struct {
Shortcut string Shortcut string
} }

View File

@ -36,10 +36,10 @@ var Shortcuts = &shortcutRegister{
Controls: map[string]string{}, Controls: map[string]string{},
} }
func configureAndValidate(conf TomlConfig) { func configureAndValidate(conf *TomlConfig) {
// config & validate the keyboard shortcuts
log.Println("Configuring keyboard shortcuts")
{ {
log.Println("Configuring keyboard shortcuts")
// keyboard commands // keyboard commands
for commandName, cmd := range conf.Commands { for commandName, cmd := range conf.Commands {
shortcut := cmd.Shortcut shortcut := cmd.Shortcut
@ -55,6 +55,27 @@ func configureAndValidate(conf TomlConfig) {
} }
} }
} }
log.Println("Syntax Highlighting")
{
conf.associations = map[string]string{}
for lang, extSet := range conf.Associations {
log.Println(lang, "=>", extSet.Extensions)
for _, ext := range extSet.Extensions {
log.Println("registering", ext, "as", lang)
conf.associations[ext] = lang
}
}
for name, conf := range conf.Syntax {
log.Println(name + ":")
for name, val := range conf {
log.Println(name, val)
}
}
}
} }
func Setup() TomlConfig { func Setup() TomlConfig {
@ -103,6 +124,6 @@ func Setup() TomlConfig {
panic(err) panic(err)
} }
configureAndValidate(conf) configureAndValidate(&conf)
return conf return conf
} }

View File

@ -3,6 +3,7 @@ package gui
import ( import (
"io/ioutil" "io/ioutil"
"log" "log"
"path"
"strings" "strings"
"time" "time"
"unicode" "unicode"
@ -38,6 +39,8 @@ type Buffer struct {
cfg *cfg.TomlConfig cfg *cfg.TomlConfig
cam *camera cam *camera
filePath string filePath string
languageInfo string
} }
func NewBuffer(conf *cfg.TomlConfig, parent *View, index int) *Buffer { func NewBuffer(conf *cfg.TomlConfig, parent *View, index int) *Buffer {
@ -63,6 +66,17 @@ func NewBuffer(conf *cfg.TomlConfig, parent *View, index int) *Buffer {
func (b *Buffer) OpenFile(filePath string) { func (b *Buffer) OpenFile(filePath string) {
b.filePath = filePath b.filePath = filePath
log.Println("Opening file ", filePath)
ext := path.Ext(filePath)
lang, err := b.cfg.GetLanguageFromExt(ext)
if err != nil {
log.Println(err.Error())
} else {
log.Println("- this file is a ", lang, " language program")
b.languageInfo = lang
}
contents, err := ioutil.ReadFile(filePath) contents, err := ioutil.ReadFile(filePath)
if err != nil { if err != nil {
panic(err) panic(err)
@ -717,8 +731,42 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
continue continue
} }
source := []rune(rope.String())
// char index => colour
matches := map[int]int{}
subjects := [][]string{}
colours := []int{}
stuff := b.cfg.Syntax[b.languageInfo]
for _, criteria := range stuff {
colours = append(colours, criteria.Colour)
subj := criteria.Match
subjects = append(subjects, subj)
}
// HOLY SLOW BATMAN
for idx, _ := range source {
for syntaxIndex, syntax := range subjects {
for _, subject := range syntax {
if idx+len(subject) > len(source) {
continue
}
a := source[idx : idx+len(subject)]
if strings.Compare(string(a), subject) == 0 {
for i := 0; i < len(subject); i++ {
matches[i+idx] = colours[syntaxIndex]
}
idx += len(subject)
}
}
}
}
var x_col int var x_col int
for _, char := range rope.String() { for idx, char := range source {
switch char { switch char {
case '\n': case '\n':
x_col = 0 x_col = 0
@ -739,6 +787,9 @@ 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)))
}
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)))
} }

Binary file not shown.