mirror of
https://github.com/felixangell/phi.git
synced 2024-09-11 07:45:30 +03:00
syntax highlighting configs are back... make it work again!
This commit is contained in:
parent
68c3a94c12
commit
88696f37c9
@ -15,6 +15,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -1205,12 +1206,15 @@ type syntaxRuneInfo struct {
|
|||||||
// dimensions of the last character we rendered
|
// dimensions of the last character we rendered
|
||||||
var lastCharW, lastCharH int
|
var lastCharW, lastCharH int
|
||||||
|
|
||||||
func lexFindMatches(matches *map[int]syntaxRuneInfo, currLine string, toMatch map[string]bool, bg uint32, fg uint32) {
|
func lexFindMatches(matches *map[int]syntaxRuneInfo, currLine string, toMatch []string, bg uint32, fg uint32) {
|
||||||
lexer := lex.New(currLine)
|
lexer := lex.New(currLine)
|
||||||
tokenStream := lexer.Tokenize()
|
tokenStream := lexer.Tokenize()
|
||||||
for _, tok := range tokenStream {
|
for _, tok := range tokenStream {
|
||||||
if _, ok := toMatch[tok.Lexeme]; ok {
|
// hashset for match.
|
||||||
(*matches)[tok.Start] = syntaxRuneInfo{bg, fg, len(tok.Lexeme)}
|
for _, ms := range toMatch {
|
||||||
|
if strings.Compare(ms, tok.Lexeme) == 0 {
|
||||||
|
(*matches)[tok.Start] = syntaxRuneInfo{bg, fg, len(tok.Lexeme)}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1267,9 +1271,11 @@ func (b *Buffer) syntaxHighlightLine(currLine string) map[int]syntaxRuneInfo {
|
|||||||
for syntaxIndex, syntax := range subjects {
|
for syntaxIndex, syntax := range subjects {
|
||||||
if syntax.Pattern != "" {
|
if syntax.Pattern != "" {
|
||||||
for charIndex := 0; charIndex < len(currLine); charIndex++ {
|
for charIndex := 0; charIndex < len(currLine); charIndex++ {
|
||||||
a := string(currLine[charIndex:])
|
a := currLine[charIndex:]
|
||||||
|
|
||||||
matched := syntax.CompiledPattern.FindStringIndex(a)
|
patt := lazyCompileRegExPattern(syntax.Pattern)
|
||||||
|
|
||||||
|
matched := patt.FindStringIndex(a)
|
||||||
if matched != nil {
|
if matched != nil {
|
||||||
if _, ok := matches[charIndex]; !ok {
|
if _, ok := matches[charIndex]; !ok {
|
||||||
matchedStrLen := matched[1] - matched[0]
|
matchedStrLen := matched[1] - matched[0]
|
||||||
@ -1288,7 +1294,7 @@ func (b *Buffer) syntaxHighlightLine(currLine string) map[int]syntaxRuneInfo {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
colouring := colours[syntaxIndex]
|
colouring := colours[syntaxIndex]
|
||||||
lexFindMatches(&matches, currLine, syntax.MatchList, colouring.bg, colouring.fg)
|
lexFindMatches(&matches, currLine, syntax.Match, colouring.bg, colouring.fg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1300,6 +1306,21 @@ func (b *Buffer) syntaxHighlightLine(currLine string) map[int]syntaxRuneInfo {
|
|||||||
return matches
|
return matches
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var patts = map[string]*regexp.Regexp{}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
func lazyCompileRegExPattern(pattern string) *regexp.Regexp {
|
||||||
|
if cachedPattern, ok := patts[pattern]; ok {
|
||||||
|
return cachedPattern
|
||||||
|
}
|
||||||
|
compiledPattern, err := regexp.Compile(pattern)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
patts[pattern] = compiledPattern
|
||||||
|
return compiledPattern
|
||||||
|
}
|
||||||
|
|
||||||
func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
|
func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
|
||||||
x, y := b.GetPos()
|
x, y := b.GetPos()
|
||||||
w, h := b.GetSize()
|
w, h := b.GetSize()
|
||||||
|
@ -3,26 +3,36 @@ package cfg
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PhiEditorConfig struct {
|
type PhiEditorConfig struct {
|
||||||
Editor *EditorConfig `toml:"editor"`
|
Editor *EditorConfig `toml:"editor"`
|
||||||
Cursor *CursorConfig `toml:"cursor"`
|
Cursor *CursorConfig `toml:"cursor"`
|
||||||
Render *RenderConfig `toml:"render"`
|
Render *RenderConfig `toml:"render"`
|
||||||
Theme *ThemeConfig `toml:"theme"`
|
Theme *ThemeConfig `toml:"theme"`
|
||||||
Associations map[string]FileAssociations `toml:"file_associations"`
|
Associations map[string]FileAssociations `toml:"file_associations"`
|
||||||
Commands map[string]Command `toml:"commands"`
|
Commands map[string]Command `toml:"commands"`
|
||||||
|
LanguageAssociations map[string]*LanguageSyntaxConfig
|
||||||
associations map[string]*LanguageSyntaxConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSyntaxConfig returns a pointer to the parsed
|
// GetSyntaxConfig returns a pointer to the parsed
|
||||||
// syntax language file for the given file extension
|
// syntax language file for the given file extension
|
||||||
// e.g. what syntax def we need for a .cpp file or a .h file
|
// e.g. what syntax def we need for a .cpp file or a .h file
|
||||||
func (p *PhiEditorConfig) GetSyntaxConfig(ext string) (*LanguageSyntaxConfig, error) {
|
func (p *PhiEditorConfig) GetSyntaxConfig(ext string) (*LanguageSyntaxConfig, error) {
|
||||||
if val, ok := p.associations[ext]; ok {
|
// fixme relationship is wrong way round so for now we have to iterate over keys.. very st upid
|
||||||
|
|
||||||
|
var theKey string
|
||||||
|
for key, assoc := range p.Associations {
|
||||||
|
for _, assocExt := range assoc.Extensions {
|
||||||
|
if strings.Compare(ext, assocExt) == 0 {
|
||||||
|
theKey = key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, ok := p.LanguageAssociations[theKey]; ok {
|
||||||
return val, nil
|
return val, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("no language for extension '" + ext + "'")
|
return nil, errors.New("no language for extension '" + ext + "'")
|
||||||
@ -37,9 +47,6 @@ type SyntaxCriteria struct {
|
|||||||
Background uint32 `toml:"background"`
|
Background uint32 `toml:"background"`
|
||||||
Match []string `toml:"match"`
|
Match []string `toml:"match"`
|
||||||
Pattern string `toml:"pattern"`
|
Pattern string `toml:"pattern"`
|
||||||
|
|
||||||
CompiledPattern *regexp.Regexp
|
|
||||||
MatchList map[string]bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Command struct {
|
type Command struct {
|
||||||
@ -196,8 +203,11 @@ func NewDefaultConfig() *PhiEditorConfig {
|
|||||||
"md": {Extensions: []string{".md", ".markdown"}},
|
"md": {Extensions: []string{".md", ".markdown"}},
|
||||||
"toml": {Extensions: []string{".toml"}},
|
"toml": {Extensions: []string{".toml"}},
|
||||||
},
|
},
|
||||||
|
LanguageAssociations: map[string]*LanguageSyntaxConfig{
|
||||||
// TODO syntax defaults
|
"go": GoConfig(),
|
||||||
associations: map[string]*LanguageSyntaxConfig{},
|
"c": CConfig(),
|
||||||
|
"md": MarkdownConfig(),
|
||||||
|
"toml": TOMLConfig(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,119 +4,114 @@ type LanguageSyntaxConfig struct {
|
|||||||
Syntax map[string]*SyntaxCriteria `toml:"syntax"`
|
Syntax map[string]*SyntaxCriteria `toml:"syntax"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLanguageSyntaxConfig() *LanguageSyntaxConfig {
|
func MarkdownConfig() *LanguageSyntaxConfig {
|
||||||
return &LanguageSyntaxConfig{Syntax: map[string]*SyntaxCriteria{}}
|
return &LanguageSyntaxConfig{Syntax: map[string]*SyntaxCriteria{
|
||||||
|
"header": {
|
||||||
|
Foreground: 0xff00ff,
|
||||||
|
Pattern: "(?m)^#{1,6}.*",
|
||||||
|
},
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
var DefaultSyntaxSet = map[string]string{}
|
func TOMLConfig() *LanguageSyntaxConfig {
|
||||||
|
return &LanguageSyntaxConfig{Syntax: map[string]*SyntaxCriteria{
|
||||||
func RegisterSyntax(name string, syntaxTomlDef string) {
|
"declaration": {
|
||||||
DefaultSyntaxSet[name] = syntaxTomlDef
|
Foreground: 0xf8f273,
|
||||||
|
Pattern: `(\[)(.*)(\])`,
|
||||||
|
},
|
||||||
|
"identifier": {
|
||||||
|
Foreground: 0xf0a400,
|
||||||
|
Pattern: `\b([a-z]|[A-Z])+(_|([a-z]|[A-Z])+)*\b`,
|
||||||
|
},
|
||||||
|
"symbol": {
|
||||||
|
Match: []string{"="},
|
||||||
|
Foreground: 0xf8f273,
|
||||||
|
},
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func CConfig() *LanguageSyntaxConfig {
|
||||||
// TOML
|
return &LanguageSyntaxConfig{Syntax: map[string]*SyntaxCriteria{
|
||||||
RegisterSyntax("toml", `[syntax.toml]
|
"type": {
|
||||||
[syntax.declaration]
|
Foreground: 0xf8f273,
|
||||||
foreground = 0xf8f273
|
Match: []string{
|
||||||
pattern = '(\[)(.*)(\])'
|
"int", "char", "bool", "float", "double", "void",
|
||||||
|
"uint8_t", "uint16_t", "uint32_t", "uint64_t",
|
||||||
[syntax.identifier]
|
"int8_t", "int16_t", "int32_t", "int64_t", "const",
|
||||||
foreground = 0xf0a400
|
},
|
||||||
pattern = '\b([a-z]|[A-Z])+(_|([a-z]|[A-Z])+)*\b'
|
},
|
||||||
|
"keyword": {
|
||||||
[syntax.symbol]
|
Foreground: 0xf0a400,
|
||||||
match = ["="]
|
Match: []string{
|
||||||
foreground = 0xf8f273
|
"for", "break", "if", "else", "continue", "return",
|
||||||
`)
|
"goto", "extern", "const", "typedef",
|
||||||
|
"struct", "union", "register", "enum",
|
||||||
// C LANGUAGE SYNTAX HIGHLIGHTING
|
"do", "static", "sizeof", "volatile", "unsigned",
|
||||||
|
"switch", "case", "default",
|
||||||
RegisterSyntax("c", `[syntax.c]
|
},
|
||||||
[syntax.type]
|
},
|
||||||
foreground = 0xf8f273
|
"string_literal": {
|
||||||
match = [
|
Foreground: 0x4b79fc,
|
||||||
"int", "char", "bool", "float", "double", "void",
|
Pattern: `\"([^\\\"]|\\.)*\"`,
|
||||||
"uint8_t", "uint16_t", "uint32_t", "uint64_t",
|
},
|
||||||
"int8_t", "int16_t", "int32_t", "int64_t", "const"
|
"directive": {
|
||||||
]
|
Foreground: 0xf0a400,
|
||||||
|
Pattern: `^\\s*#\\s*include\\s+(?:<[^>]*>|\"[^\"]*\")\\s*`,
|
||||||
[syntax.keyword]
|
},
|
||||||
foreground = 0xf0a400
|
"symbol": {
|
||||||
match = [
|
Foreground: 0xf0a400,
|
||||||
"for", "break", "if", "else", "continue", "return",
|
Match: []string{
|
||||||
"goto", "extern", "const", "typedef",
|
"+=", "-=", "*=", "/=", ">>", "<<", "==", "!=",
|
||||||
"struct", "union", "register", "enum",
|
">=", "<=", "||", "&&",
|
||||||
"do", "static", "sizeof", "volatile", "unsigned",
|
"=", ":", ";", "*", "&", "+", "-", "/", "%",
|
||||||
"switch", "case", "default"
|
"^", "#", "!", "@", "<", ">", ".", ",",
|
||||||
]
|
},
|
||||||
|
},
|
||||||
[syntax.string_literal]
|
"comment": {
|
||||||
foreground = 0x4b79fc
|
Foreground: 0x4b79fc,
|
||||||
pattern = "\"([^\\\"]|\\.)*\""
|
Pattern: `//.*`,
|
||||||
|
},
|
||||||
[syntax.directive]
|
}}
|
||||||
foreground = 0xf0a400
|
}
|
||||||
pattern = "^\\s*#\\s*include\\s+(?:<[^>]*>|\"[^\"]*\")\\s*"
|
|
||||||
|
func GoConfig() *LanguageSyntaxConfig {
|
||||||
[syntax.symbol]
|
return &LanguageSyntaxConfig{Syntax: map[string]*SyntaxCriteria{
|
||||||
foreground = 0xf0a400
|
"keyword": {
|
||||||
match = [
|
Foreground: 0xf0a400,
|
||||||
"+=", "-=", "*=", "/=", ">>", "<<", "==", "!=",
|
Match: []string{
|
||||||
">=", "<=", "||", "&&",
|
"break", "default", "func", "interface", "select",
|
||||||
"=", ":", ";", "*", "&", "+", "-", "/", "%",
|
"case", "defer", "go", "map", "struct",
|
||||||
"^", "#", "!", "@", "<", ">", ".", ","
|
"chan", "else", "goto", "package", "switch",
|
||||||
]
|
"const", "fallthrough", "if", "range", "type",
|
||||||
|
"continue", "for", "import", "return", "var",
|
||||||
[syntax.comment]
|
},
|
||||||
foreground = 0x4b79fc
|
},
|
||||||
pattern = '//.*'`)
|
"type": {
|
||||||
|
Foreground: 0xf8f273,
|
||||||
// GO LANGUAGE SYNTAX HIGHLIGHTING
|
Match: []string{
|
||||||
|
"int", "string", "uint", "rune",
|
||||||
RegisterSyntax("go", `[syntax.go]
|
"int8", "int16", "int32", "int64",
|
||||||
[syntax.keyword]
|
"uint8", "uint16", "uint32", "uint64",
|
||||||
foreground = 0xf0a400
|
"byte", "float32", "float64", "complex64",
|
||||||
match = [
|
"complex128", "uintptr",
|
||||||
"break", "default", "func", "interface", "select",
|
},
|
||||||
"case", "defer", "go", "map", "struct",
|
},
|
||||||
"chan", "else", "goto", "package", "switch",
|
"comment": {
|
||||||
"const", "fallthrough", "if", "range", "type",
|
Foreground: 0x4b79fc,
|
||||||
"continue", "for", "import", "return", "var",
|
Pattern: `//.*`,
|
||||||
]
|
},
|
||||||
|
"string_literal": {
|
||||||
[syntax.type]
|
Foreground: 0x4b79fc,
|
||||||
foreground = 0xf8f273
|
Pattern: `\"([^\\\"]|\\.)*\"`,
|
||||||
match = [
|
},
|
||||||
"int", "string", "uint", "rune",
|
"symbol": {
|
||||||
"int8", "int16", "int32", "int64",
|
Foreground: 0xf0a400,
|
||||||
"uint8", "uint16", "uint32", "uint64",
|
Match: []string{
|
||||||
"byte", "float32", "float64", "complex64",
|
"+=", "-=", "*=", "/=", ">>", "<<", "==", "!=", ":=",
|
||||||
"complex128", "uintptr",
|
">=", "<=", "||", "&&",
|
||||||
]
|
"=", ":", ";", "*", "&", "+", "-", "/", "%",
|
||||||
|
"^", "#", "!", "@", "<", ">", ".", ",",
|
||||||
[syntax.comment]
|
},
|
||||||
foreground = 0x4b79fc
|
},
|
||||||
pattern = '//.*'
|
}}
|
||||||
|
|
||||||
[syntax.string_literal]
|
|
||||||
foreground = 0x4b79fc
|
|
||||||
pattern = "\"([^\\\"]|\\.)*\""
|
|
||||||
|
|
||||||
[syntax.symbol]
|
|
||||||
foreground = 0xf0a400
|
|
||||||
match = [
|
|
||||||
"+=", "-=", "*=", "/=", ">>", "<<", "==", "!=", ":=",
|
|
||||||
">=", "<=", "||", "&&",
|
|
||||||
"=", ":", ";", "*", "&", "+", "-", "/", "%",
|
|
||||||
"^", "#", "!", "@", "<", ">", ".", ","
|
|
||||||
]`)
|
|
||||||
|
|
||||||
RegisterSyntax("md", `[syntax.md]
|
|
||||||
[syntax.header]
|
|
||||||
foreground = 0xff00ff
|
|
||||||
pattern = '(?m)^#{1,6}.*'
|
|
||||||
`)
|
|
||||||
|
|
||||||
// your syntax here!
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user