Initial syntax highlighting

This commit is contained in:
Zachary Yedidia
2016-03-20 11:28:41 -04:00
parent d9856c7c1e
commit 068260157c
4 changed files with 131 additions and 8 deletions

111
highlighter.go Normal file
View File

@@ -0,0 +1,111 @@
package main
import (
"fmt"
"github.com/gdamore/tcell"
"regexp"
"strings"
)
// Match ...
func Match(str string) map[int]tcell.Style {
rules := `color blue "[A-Za-z_][A-Za-z0-9_]*[[:space:]]*[()]"
color blue "\b(append|cap|close|complex|copy|delete|imag|len)\b"
color blue "\b(make|new|panic|print|println|protect|real|recover)\b"
color green "\b(u?int(8|16|32|64)?|float(32|64)|complex(64|128))\b"
color green "\b(uintptr|byte|rune|string|interface|bool|map|chan|error)\b"
color cyan "\b(package|import|const|var|type|struct|func|go|defer|nil|iota)\b"
color cyan "\b(for|range|if|else|case|default|switch|return)\b"
color red "\b(go|goto|break|continue)\b"
color cyan "\b(true|false)\b"
color red "[-+/*=<>!~%&|^]|:="
color blue "\b([0-9]+|0x[0-9a-fA-F]*)\b|'.'"
color magenta "\\([0-7]{3}|x[A-Fa-f0-9]{2}|u[A-Fa-f0-9]{4}|U[A-Fa-f0-9]{8})"
color yellow "` + "`" + `[^` + "`" + `]*` + "`" + `"
color green "(^|[[:space:]])//.*"
color brightwhite,cyan "TODO:?"
color ,green "[[:space:]]+$"
color ,red " + +| + +"`
lines := strings.Split(rules, "\n")
m := make(map[int]tcell.Style)
for _, line := range lines {
split := strings.Split(line, "\"")
color := strings.Split(split[0], " ")[1]
regex, err := regexp.Compile(split[1])
if err != nil {
fmt.Println("\a")
// Error with the regex!
}
st := StringToStyle(color)
if regex.MatchString(str) {
indicies := regex.FindAllStringIndex(str, -1)
for _, value := range indicies {
for i := value[0] + 1; i < value[1]; i++ {
if _, exists := m[i]; exists {
delete(m, i)
}
}
m[value[0]] = st
m[value[1]] = tcell.StyleDefault
}
}
}
return m
}
// StringToStyle returns a style from a string
func StringToStyle(str string) tcell.Style {
var fg string
var bg string
split := strings.Split(str, ",")
if len(split) > 1 {
fg, bg = split[0], split[1]
} else {
fg = split[0]
}
return tcell.StyleDefault.Foreground(StringToColor(fg)).Background(StringToColor(bg))
}
// StringToColor returns a tcell color from a string representation of a color
func StringToColor(str string) tcell.Color {
switch str {
case "black":
return tcell.ColorBlack
case "red":
return tcell.ColorMaroon
case "green":
return tcell.ColorGreen
case "yellow":
return tcell.ColorOlive
case "blue":
return tcell.ColorNavy
case "magenta":
return tcell.ColorPurple
case "cyan":
return tcell.ColorTeal
case "white":
return tcell.ColorSilver
case "brightblack":
return tcell.ColorGray
case "brightred":
return tcell.ColorRed
case "brightgreen":
return tcell.ColorLime
case "brightyellow":
return tcell.ColorYellow
case "brightblue":
return tcell.ColorBlue
case "brightmagenta":
return tcell.ColorFuchsia
case "brightcyan":
return tcell.ColorAqua
case "brightwhite":
return tcell.ColorWhite
default:
return tcell.ColorDefault
}
}

View File

@@ -24,7 +24,7 @@ func (sl *Statusline) Display() {
}
file += " (" + strconv.Itoa(sl.v.cursor.y+1) + "," + strconv.Itoa(sl.v.cursor.GetVisualX()+1) + ")"
statusLineStyle := tcell.StyleDefault.Background(tcell.ColorNavy).Foreground(tcell.ColorBlack)
statusLineStyle := tcell.StyleDefault.Reverse(true)
for x := 0; x < sl.v.width; x++ {
if x < Count(file) {

View File

@@ -14,8 +14,8 @@
- [x] Use pageup and pagedown keys
- [ ] Much more (copy sublime text or standard system applications)
- [ ] Syntax highlighting
- [ ] Use nano-like syntax files (https://github.com/scopatz/nanorc)
- [x] Syntax highlighting
- [x] Use nano-like syntax files (https://github.com/scopatz/nanorc)
- [ ] Colorschemes
- [ ] Support for 256 color and true color

22
view.go
View File

@@ -301,12 +301,16 @@ func (v *View) Display() {
charNum := v.cursor.loc + v.cursor.Distance(0, v.topline)
matches := Match(v.buf.text)
// Convert the length of buffer to a string, and get the length of the string
// We are going to have to offset by that amount
maxLineLength := len(strconv.Itoa(len(v.buf.lines)))
// + 1 for the little space after the line number
v.lineNumOffset = maxLineLength + 1
var lineStyle tcell.Style
for lineN := 0; lineN < v.height; lineN++ {
if lineN+v.topline >= len(v.buf.lines) {
break
@@ -333,26 +337,34 @@ func (v *View) Display() {
// Write the line
tabchars := 0
for _, ch := range line {
st := tcell.StyleDefault
st, ok := matches[charNum]
if ok {
lineStyle = st
}
if v.cursor.HasSelection() &&
(charNum >= v.cursor.selectionStart && charNum <= v.cursor.selectionEnd ||
charNum <= v.cursor.selectionStart && charNum >= v.cursor.selectionEnd) {
st = st.Reverse(true)
lineStyle = lineStyle.Reverse(true)
}
if ch == '\t' {
v.s.SetContent(x+tabchars, lineN, ' ', nil, st)
v.s.SetContent(x+tabchars, lineN, ' ', nil, lineStyle)
for i := 0; i < tabSize-1; i++ {
tabchars++
v.s.SetContent(x+tabchars, lineN, ' ', nil, st)
v.s.SetContent(x+tabchars, lineN, ' ', nil, lineStyle)
}
} else {
v.s.SetContent(x+tabchars, lineN, ch, nil, st)
v.s.SetContent(x+tabchars, lineN, ch, nil, lineStyle)
}
charNum++
x++
}
x = 0
st, ok := matches[charNum]
if ok {
lineStyle = st
}
charNum++
}
}