mirror of
https://github.com/felixangell/phi.git
synced 2024-08-16 19:20:21 +03:00
languages are now written to and loaded from "PHI_CONFIG_DIR/syntax/language_name.toml"
This commit is contained in:
parent
8ece431fc4
commit
c085e4e66e
@ -9,28 +9,24 @@ import (
|
||||
)
|
||||
|
||||
type TomlConfig struct {
|
||||
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"`
|
||||
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"`
|
||||
|
||||
// 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
|
||||
associations map[string]*LanguageSyntaxConfig
|
||||
}
|
||||
|
||||
func (t *TomlConfig) GetLanguageFromExt(ext string) (string, error) {
|
||||
// GetSyntaxConfig returns a pointer to the parsed
|
||||
// syntax language file for the given file extension
|
||||
// e.g. what syntax def we need for a .cpp file or a .h file
|
||||
func (t *TomlConfig) GetSyntaxConfig(ext string) (*LanguageSyntaxConfig, error) {
|
||||
if val, ok := t.associations[ext]; ok {
|
||||
return val, nil
|
||||
}
|
||||
return "", errors.New("no language for extension '" + ext + "'")
|
||||
return nil, errors.New("no language for extension '" + ext + "'")
|
||||
}
|
||||
|
||||
type FileAssociations struct {
|
||||
|
@ -24,69 +24,6 @@ extensions = [".c", ".h", ".cc"]
|
||||
[file_associations.go]
|
||||
extensions = [".go"]
|
||||
|
||||
[syntax.go]
|
||||
[syntax.go.keyword]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"type", "import", "package", "func", "struct",
|
||||
"append", "delete", "make", "for", "if", "while",
|
||||
"switch", "select", "chan", "else", "var", "const",
|
||||
"iota", "case"
|
||||
]
|
||||
|
||||
[syntax.go.type]
|
||||
colouring = 0xf8f273
|
||||
match = [
|
||||
"int", "string", "uint",
|
||||
"int8", "int16", "int32", "int64",
|
||||
"uint8", "uint16", "uint32", "uint64",
|
||||
"rune", "byte", "float32", "float64"
|
||||
]
|
||||
|
||||
[syntax.go.string_literal]
|
||||
colouring = 0x4b79fc
|
||||
pattern = "\"([^\\\"]|\\.)*\""
|
||||
|
||||
[syntax.go.comment]
|
||||
colouring = 0x4b79fc
|
||||
pattern = '//.*'
|
||||
|
||||
[syntax.go.symbol]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"=", ":", ";", "*", "&", "+", "-", "/", "%",
|
||||
"^", "#", "!", "@", "<", ">", ".", ","
|
||||
]
|
||||
|
||||
[syntax.c]
|
||||
|
||||
[syntax.c.type]
|
||||
colouring = 0xf8f273
|
||||
match = [
|
||||
"int", "char", "bool", "float", "double", "void",
|
||||
"uint8_t", "uint16_t", "uint32_t", "uint64_t",
|
||||
"int8_t", "int16_t", "int32_t", "int64_t"
|
||||
]
|
||||
|
||||
[syntax.c.keyword]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"for", "break", "if", "else", "continue", "return",
|
||||
"goto", "static", "extern", "const", "typedef",
|
||||
]
|
||||
|
||||
[syntax.c.string_literal]
|
||||
colouring = 0x4b79fc
|
||||
pattern = "\"([^\\\"]|\\.)*\""
|
||||
|
||||
[syntax.c.directive]
|
||||
colouring = 0xf0a400
|
||||
pattern = "^\\s*#\\s*include\\s+(?:<[^>]*>|\"[^\"]*\")\\s*"
|
||||
|
||||
[syntax.c.comment]
|
||||
colouring = 0x4b79fc
|
||||
pattern = '//.*'
|
||||
|
||||
[theme]
|
||||
background = 0x002649
|
||||
foreground = 0xf2f4f6
|
||||
|
@ -23,8 +23,14 @@ const (
|
||||
CONFIG_TOML_FILE = "config.toml"
|
||||
)
|
||||
|
||||
// this is the absolute path to the
|
||||
// config.toml file. todo rename/refactor
|
||||
var CONFIG_FULL_PATH string = ""
|
||||
|
||||
// the absolute path to the config directory
|
||||
// rename/refactor due here too!
|
||||
var configDirAbsPath string = ""
|
||||
|
||||
// TODO we only had double key combos
|
||||
// e.g. cmd+s. we want to handle things
|
||||
// like cmd+alt+s
|
||||
@ -38,6 +44,23 @@ var Shortcuts = &shortcutRegister{
|
||||
Controls: map[string]string{},
|
||||
}
|
||||
|
||||
func loadSyntaxDef(lang string) *LanguageSyntaxConfig {
|
||||
languagePath := filepath.Join(configDirAbsPath, "syntax", lang+".toml")
|
||||
syntaxTomlData, err := ioutil.ReadFile(languagePath)
|
||||
if err != nil {
|
||||
log.Println("Failed to load highlighting for language '"+lang+"' from path: ", languagePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
var conf = &LanguageSyntaxConfig{}
|
||||
if _, err := toml.Decode(string(syntaxTomlData), conf); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
log.Println("Loaded syntax definition for language", lang)
|
||||
return conf
|
||||
}
|
||||
|
||||
func configureAndValidate(conf *TomlConfig) {
|
||||
// config & validate the keyboard shortcuts
|
||||
log.Println("Configuring keyboard shortcuts")
|
||||
@ -60,21 +83,15 @@ func configureAndValidate(conf *TomlConfig) {
|
||||
|
||||
log.Println("Syntax Highlighting")
|
||||
{
|
||||
conf.associations = map[string]string{}
|
||||
conf.associations = map[string]*LanguageSyntaxConfig{}
|
||||
|
||||
for lang, extSet := range conf.Associations {
|
||||
log.Println(lang, "=>", extSet.Extensions)
|
||||
languageConfig := loadSyntaxDef(lang)
|
||||
|
||||
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)
|
||||
conf.associations[ext] = languageConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,8 +104,15 @@ func Setup() TomlConfig {
|
||||
if runtime.GOOS == "windows" {
|
||||
home = os.Getenv("USERPROFILE")
|
||||
}
|
||||
|
||||
CONFIG_DIR := filepath.Join(home, CONFIG_DIR_PATH)
|
||||
configDirAbsPath = CONFIG_DIR
|
||||
|
||||
CONFIG_PATH := filepath.Join(CONFIG_DIR, CONFIG_TOML_FILE)
|
||||
|
||||
// this folder is where we store all of the language syntax
|
||||
SYNTAX_CONFIG_DIR := filepath.Join(CONFIG_DIR, "syntax")
|
||||
|
||||
CONFIG_FULL_PATH = CONFIG_PATH
|
||||
|
||||
// if the user doesn't have a /.phi-editor
|
||||
@ -99,6 +123,30 @@ func Setup() TomlConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// try make the syntax config folder.
|
||||
if _, err := os.Stat(SYNTAX_CONFIG_DIR); os.IsNotExist(err) {
|
||||
if err := os.Mkdir(SYNTAX_CONFIG_DIR, 0775); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// load all of the default language syntax
|
||||
for name, syntaxDef := range DefaultSyntaxSet {
|
||||
languagePath := filepath.Join(SYNTAX_CONFIG_DIR, name+".toml")
|
||||
if _, err := os.Stat(languagePath); os.IsNotExist(err) {
|
||||
file, err := os.Create(languagePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if _, err := file.Write([]byte(syntaxDef)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
log.Println("Wrote syntax for language '" + name + "'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure a config.toml file exists in the
|
||||
// phi-editor directory.
|
||||
if _, err := os.Stat(CONFIG_PATH); os.IsNotExist(err) {
|
||||
|
@ -24,69 +24,6 @@ extensions = [".c", ".h", ".cc"]
|
||||
[file_associations.go]
|
||||
extensions = [".go"]
|
||||
|
||||
[syntax.go]
|
||||
[syntax.go.keyword]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"type", "import", "package", "func", "struct",
|
||||
"append", "delete", "make", "for", "if", "while",
|
||||
"switch", "select", "chan", "else", "var", "const",
|
||||
"iota", "case"
|
||||
]
|
||||
|
||||
[syntax.go.type]
|
||||
colouring = 0xf8f273
|
||||
match = [
|
||||
"int", "string", "uint",
|
||||
"int8", "int16", "int32", "int64",
|
||||
"uint8", "uint16", "uint32", "uint64",
|
||||
"rune", "byte", "float32", "float64"
|
||||
]
|
||||
|
||||
[syntax.go.comment]
|
||||
colouring = 0x4b79fc
|
||||
pattern = '//.*'
|
||||
|
||||
[syntax.go.string_literal]
|
||||
colouring = 0x4b79fc
|
||||
pattern = "\"([^\\\"]|\\.)*\""
|
||||
|
||||
[syntax.go.symbol]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"=", ":", ";", "*", "&", "+", "-", "/", "%",
|
||||
"^", "#", "!", "@", "<", ">", ".", ","
|
||||
]
|
||||
|
||||
[syntax.c]
|
||||
|
||||
[syntax.c.type]
|
||||
colouring = 0xf8f273
|
||||
match = [
|
||||
"int", "char", "bool", "float", "double", "void",
|
||||
"uint8_t", "uint16_t", "uint32_t", "uint64_t",
|
||||
"int8_t", "int16_t", "int32_t", "int64_t"
|
||||
]
|
||||
|
||||
[syntax.c.keyword]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"for", "break", "if", "else", "continue", "return",
|
||||
"goto", "static", "extern", "const", "typedef",
|
||||
]
|
||||
|
||||
[syntax.c.string_literal]
|
||||
colouring = 0x4b79fc
|
||||
pattern = "\"([^\\\"]|\\.)*\""
|
||||
|
||||
[syntax.c.directive]
|
||||
colouring = 0xf0a400
|
||||
pattern = "^\\s*#\\s*include\\s+(?:<[^>]*>|\"[^\"]*\")\\s*"
|
||||
|
||||
[syntax.c.comment]
|
||||
colouring = 0x4b79fc
|
||||
pattern = '//.*'
|
||||
|
||||
[theme]
|
||||
background = 0x002649
|
||||
foreground = 0xf2f4f6
|
||||
|
77
cfg/syntax.go
Normal file
77
cfg/syntax.go
Normal file
@ -0,0 +1,77 @@
|
||||
package cfg
|
||||
|
||||
type LanguageSyntaxConfig struct {
|
||||
Syntax map[string]SyntaxCriteria `toml:"syntax"`
|
||||
}
|
||||
|
||||
type DefaultSyntax map[string]string
|
||||
|
||||
var DefaultSyntaxSet = DefaultSyntax{}
|
||||
|
||||
func RegisterSyntax(name string, s string) {
|
||||
DefaultSyntaxSet[name] = s
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterSyntax("c", `[syntax.c]
|
||||
[syntax.type]
|
||||
colouring = 0xf8f273
|
||||
match = [
|
||||
"int", "char", "bool", "float", "double", "void",
|
||||
"uint8_t", "uint16_t", "uint32_t", "uint64_t",
|
||||
"int8_t", "int16_t", "int32_t", "int64_t"
|
||||
]
|
||||
|
||||
[syntax.keyword]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"for", "break", "if", "else", "continue", "return",
|
||||
"goto", "static", "extern", "const", "typedef",
|
||||
]
|
||||
|
||||
[syntax.string_literal]
|
||||
colouring = 0x4b79fc
|
||||
pattern = "\"([^\\\"]|\\.)*\""
|
||||
|
||||
[syntax.directive]
|
||||
colouring = 0xf0a400
|
||||
pattern = "^\\s*#\\s*include\\s+(?:<[^>]*>|\"[^\"]*\")\\s*"
|
||||
|
||||
[syntax.comment]
|
||||
colouring = 0x4b79fc
|
||||
pattern = '//.*'`)
|
||||
|
||||
RegisterSyntax("go", `[syntax.go]
|
||||
[syntax.go.keyword]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"type", "import", "package", "func", "struct",
|
||||
"append", "delete", "make", "for", "if", "while",
|
||||
"switch", "select", "chan", "else", "var", "const",
|
||||
"iota", "case"
|
||||
]
|
||||
|
||||
[syntax.go.type]
|
||||
colouring = 0xf8f273
|
||||
match = [
|
||||
"int", "string", "uint",
|
||||
"int8", "int16", "int32", "int64",
|
||||
"uint8", "uint16", "uint32", "uint64",
|
||||
"rune", "byte", "float32", "float64"
|
||||
]
|
||||
|
||||
[syntax.go.comment]
|
||||
colouring = 0x4b79fc
|
||||
pattern = '//.*'
|
||||
|
||||
[syntax.go.string_literal]
|
||||
colouring = 0x4b79fc
|
||||
pattern = "\"([^\\\"]|\\.)*\""
|
||||
|
||||
[syntax.go.symbol]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"=", ":", ";", "*", "&", "+", "-", "/", "%",
|
||||
"^", "#", "!", "@", "<", ">", ".", ","
|
||||
]`)
|
||||
}
|
@ -24,69 +24,6 @@ extensions = [".c", ".h", ".cc"]
|
||||
[file_associations.go]
|
||||
extensions = [".go"]
|
||||
|
||||
[syntax.go]
|
||||
[syntax.go.keyword]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"type", "import", "package", "func", "struct",
|
||||
"append", "delete", "make", "for", "if", "while",
|
||||
"switch", "select", "chan", "else", "var", "const",
|
||||
"iota", "case"
|
||||
]
|
||||
|
||||
[syntax.go.type]
|
||||
colouring = 0xf8f273
|
||||
match = [
|
||||
"int", "string", "uint",
|
||||
"int8", "int16", "int32", "int64",
|
||||
"uint8", "uint16", "uint32", "uint64",
|
||||
"rune", "byte", "float32", "float64"
|
||||
]
|
||||
|
||||
[syntax.go.string_literal]
|
||||
colouring = 0x4b79fc
|
||||
pattern = "\"([^\\\"]|\\.)*\""
|
||||
|
||||
[syntax.go.comment]
|
||||
colouring = 0x4b79fc
|
||||
pattern = '//.*'
|
||||
|
||||
[syntax.go.symbol]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"=", ":", ";", "*", "&", "+", "-", "/", "%",
|
||||
"^", "#", "!", "@", "<", ">", ".", ","
|
||||
]
|
||||
|
||||
[syntax.c]
|
||||
|
||||
[syntax.c.type]
|
||||
colouring = 0xf8f273
|
||||
match = [
|
||||
"int", "char", "bool", "float", "double", "void",
|
||||
"uint8_t", "uint16_t", "uint32_t", "uint64_t",
|
||||
"int8_t", "int16_t", "int32_t", "int64_t"
|
||||
]
|
||||
|
||||
[syntax.c.keyword]
|
||||
colouring = 0xf0a400
|
||||
match = [
|
||||
"for", "break", "if", "else", "continue", "return",
|
||||
"goto", "static", "extern", "const", "typedef",
|
||||
]
|
||||
|
||||
[syntax.c.string_literal]
|
||||
colouring = 0x4b79fc
|
||||
pattern = "\"([^\\\"]|\\.)*\""
|
||||
|
||||
[syntax.c.directive]
|
||||
colouring = 0xf0a400
|
||||
pattern = "^\\s*#\\s*include\\s+(?:<[^>]*>|\"[^\"]*\")\\s*"
|
||||
|
||||
[syntax.c.comment]
|
||||
colouring = 0x4b79fc
|
||||
pattern = '//.*'
|
||||
|
||||
[theme]
|
||||
background = 0x002649
|
||||
foreground = 0xf2f4f6
|
||||
|
@ -34,17 +34,16 @@ type camera struct {
|
||||
|
||||
type Buffer struct {
|
||||
BaseComponent
|
||||
HasFocus bool
|
||||
index int
|
||||
parent *View
|
||||
font *strife.Font
|
||||
contents []*rope.Rope
|
||||
curs *Cursor
|
||||
cfg *cfg.TomlConfig
|
||||
cam *camera
|
||||
filePath string
|
||||
|
||||
languageInfo string
|
||||
HasFocus bool
|
||||
index int
|
||||
parent *View
|
||||
font *strife.Font
|
||||
contents []*rope.Rope
|
||||
curs *Cursor
|
||||
cfg *cfg.TomlConfig
|
||||
cam *camera
|
||||
filePath string
|
||||
languageInfo *cfg.LanguageSyntaxConfig
|
||||
}
|
||||
|
||||
func NewBuffer(conf *cfg.TomlConfig, parent *View, index int) *Buffer {
|
||||
@ -73,12 +72,11 @@ func (b *Buffer) OpenFile(filePath string) {
|
||||
log.Println("Opening file ", filePath)
|
||||
|
||||
ext := path.Ext(filePath)
|
||||
lang, err := b.cfg.GetLanguageFromExt(ext)
|
||||
|
||||
var err error
|
||||
b.languageInfo, err = b.cfg.GetSyntaxConfig(ext)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
} else {
|
||||
log.Println("- this file is a ", lang, " language program")
|
||||
b.languageInfo = lang
|
||||
}
|
||||
|
||||
// if the file doesn't exist, try to create it before reading it
|
||||
@ -807,13 +805,11 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
|
||||
// char index => colour
|
||||
matches := map[int]syntaxRuneInfo{}
|
||||
|
||||
stuff := b.cfg.Syntax[b.languageInfo]
|
||||
|
||||
subjects := make([]cfg.SyntaxCriteria, len(stuff))
|
||||
colours := make([]int, len(stuff))
|
||||
subjects := make([]cfg.SyntaxCriteria, len(b.languageInfo.Syntax))
|
||||
colours := make([]int, len(b.languageInfo.Syntax))
|
||||
|
||||
idx := 0
|
||||
for _, criteria := range stuff {
|
||||
for _, criteria := range b.languageInfo.Syntax {
|
||||
colours[idx] = criteria.Colour
|
||||
subjects[idx] = criteria
|
||||
idx++
|
||||
|
Loading…
Reference in New Issue
Block a user