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  }