forked from u-root/u-root
-
Notifications
You must be signed in to change notification settings - Fork 0
/
emitter.go
80 lines (72 loc) · 1.78 KB
/
emitter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package highlight
import (
"strings"
"github.com/u-root/u-root/cmds/core/elvish/edit/ui"
"github.com/u-root/u-root/cmds/core/elvish/eval"
"github.com/u-root/u-root/cmds/core/elvish/parse"
)
type Emitter struct {
GoodFormHead func(string) bool
AddStyling func(begin, end int, style string)
}
func (e *Emitter) EmitAll(n parse.Node) {
switch n := n.(type) {
case *parse.Form:
e.form(n)
case *parse.Primary:
e.primary(n)
case *parse.Sep:
e.sep(n)
}
for _, child := range n.Children() {
e.EmitAll(child)
}
}
func (e *Emitter) form(n *parse.Form) {
for _, an := range n.Assignments {
if an.Left != nil && an.Left.Head != nil {
v := an.Left.Head
e.AddStyling(v.Begin(), v.End(), styleForGoodVariable.String())
}
}
for _, cn := range n.Vars {
if len(cn.Indexings) > 0 && cn.Indexings[0].Head != nil {
v := cn.Indexings[0].Head
e.AddStyling(v.Begin(), v.End(), styleForGoodVariable.String())
}
}
if n.Head != nil {
e.formHead(n.Head)
}
}
func (e *Emitter) formHead(n *parse.Compound) {
head, err := eval.PurelyEvalCompound(n)
st := ui.Styles{}
if err == nil {
if e.GoodFormHead(head) {
st = styleForGoodCommand
} else {
st = styleForBadCommand
}
} else if err != eval.ErrImpure {
st = styleForBadCommand
}
if len(st) > 0 {
e.AddStyling(n.Begin(), n.End(), st.String())
}
}
func (e *Emitter) primary(n *parse.Primary) {
e.AddStyling(n.Begin(), n.End(), styleForPrimary[n.Type].String())
}
func (e *Emitter) sep(n *parse.Sep) {
septext := n.SourceText()
switch {
case strings.TrimSpace(septext) == "":
// Don't do anything. Whitespaces don't get any styling.
case strings.HasPrefix(septext, "#"):
// Comment.
e.AddStyling(n.Begin(), n.End(), styleForComment.String())
default:
e.AddStyling(n.Begin(), n.End(), styleForSep[septext])
}
}