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
import (
"errors"
"log"
"runtime"
"strconv"
@ -8,11 +9,32 @@ import (
)
type TomlConfig struct {
Editor EditorConfig
Cursor CursorConfig
Render RenderConfig
Theme ThemeConfig
Commands map[string]Command
Editor EditorConfig `toml:"editor"`
Cursor CursorConfig `toml:"cursor"`
Render RenderConfig `toml:"render"`
Theme ThemeConfig `toml:"theme"`
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()
@ -31,6 +53,11 @@ func getDefaultConfig() string {
return DEFAULT_WINDOWS_TOML_CONFIG
}
type SyntaxCriteria struct {
Colour int `toml:"colouring"`
Match []string `toml:"match"`
}
type Command struct {
Shortcut string
}

View File

@ -36,10 +36,10 @@ var Shortcuts = &shortcutRegister{
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
for commandName, cmd := range conf.Commands {
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 {
@ -103,6 +124,6 @@ func Setup() TomlConfig {
panic(err)
}
configureAndValidate(conf)
configureAndValidate(&conf)
return conf
}

View File

@ -3,6 +3,7 @@ package gui
import (
"io/ioutil"
"log"
"path"
"strings"
"time"
"unicode"
@ -38,6 +39,8 @@ type Buffer struct {
cfg *cfg.TomlConfig
cam *camera
filePath string
languageInfo string
}
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) {
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)
if err != nil {
panic(err)
@ -717,8 +731,42 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
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
for _, char := range rope.String() {
for idx, char := range source {
switch char {
case '\n':
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 {
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)))
}

Binary file not shown.