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