mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-21 08:17:15 +09:00
Initial syntax highlighting
This commit is contained in:
111
highlighter.go
Normal file
111
highlighter.go
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
22
view.go
@@ -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++
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user