github.com/hoop33/elvish@v0.0.0-20160801152013-6d25485beab4/edit/stylists.go (about) 1 package edit 2 3 import ( 4 "os" 5 6 "github.com/elves/elvish/eval" 7 "github.com/elves/elvish/parse" 8 "github.com/elves/elvish/util" 9 ) 10 11 // stylist takes a Node and Editor, and returns a style string. The Node is 12 // always a leaf in the parsed AST. 13 // NOTE: Not all stylings are now done with stylists. 14 type stylist func(parse.Node, *Editor) string 15 16 var stylists = []stylist{ 17 colorFormHead, 18 } 19 20 func colorFormHead(n parse.Node, ed *Editor) string { 21 // BUG doesn't work when the form head is compound 22 n, head := formHead(n) 23 if n == nil { 24 return "" 25 } 26 if goodFormHead(head, ed) { 27 return styleForGoodCommand 28 } 29 return styleForBadCommand 30 } 31 32 func goodFormHead(head string, ed *Editor) bool { 33 if isBuiltinSpecial[head] { 34 return true 35 } else if util.DontSearch(head) { 36 // XXX don't stat twice 37 return util.IsExecutable(head) || isDir(head) 38 } else { 39 _, ns, head := eval.ParseVariable(head) 40 if ns == "" { 41 return ed.isExternal[head] || 42 eval.Builtin()[eval.FnPrefix+head] != nil || 43 ed.evaler.Global[eval.FnPrefix+head] != nil 44 } else { 45 return ed.evaler.Modules[ns] != nil && 46 ed.evaler.Modules[ns][eval.FnPrefix+head] != nil 47 } 48 } 49 } 50 51 var isBuiltinSpecial = map[string]bool{} 52 53 func init() { 54 for _, name := range eval.BuiltinSpecialNames { 55 isBuiltinSpecial[name] = true 56 } 57 } 58 59 func isDir(fname string) bool { 60 stat, err := os.Stat(fname) 61 return err == nil && stat.IsDir() 62 }