github.com/oweisse/u-root@v0.0.0-20181109060735-d005ad25fef1/cmds/elvish/edit/completion/complete_variable.go (about) 1 package completion 2 3 import ( 4 "strings" 5 6 "github.com/u-root/u-root/cmds/elvish/eval" 7 "github.com/u-root/u-root/cmds/elvish/parse" 8 ) 9 10 type variableComplContext struct { 11 complContextCommon 12 ns, nsPart string 13 } 14 15 func (*variableComplContext) name() string { return "variable" } 16 17 func findVariableComplContext(n parse.Node, _ pureEvaler) complContext { 18 primary := parse.GetPrimary(n) 19 if primary != nil && primary.Type == parse.Variable { 20 explode, nsPart, nameSeed := eval.SplitIncompleteVariableRef(primary.Value) 21 // Move past "$", "@" and "<ns>:". 22 begin := primary.Begin() + 1 + len(explode) + len(nsPart) 23 ns := nsPart 24 if len(ns) > 0 { 25 ns = ns[:len(ns)-1] 26 } 27 return &variableComplContext{ 28 complContextCommon{nameSeed, parse.Bareword, begin, primary.End()}, 29 ns, nsPart, 30 } 31 } 32 return nil 33 } 34 35 type evalerScopes interface { 36 EachVariableInTop(string, func(string)) 37 EachNsInTop(func(string)) 38 } 39 40 func (ctx *variableComplContext) generate(env *complEnv, ch chan<- rawCandidate) error { 41 complVariable(ctx.ns, ctx.nsPart, env.evaler, ch) 42 return nil 43 } 44 45 func complVariable(ctxNs, ctxNsPart string, ev evalerScopes, ch chan<- rawCandidate) { 46 ev.EachVariableInTop(ctxNs, func(varname string) { 47 ch <- noQuoteCandidate(varname) 48 }) 49 50 ev.EachNsInTop(func(ns string) { 51 nsPart := ns + ":" 52 // This is to match namespaces that are "nested" under the current 53 // namespace. 54 if hasProperPrefix(nsPart, ctxNsPart) { 55 ch <- noQuoteCandidate(nsPart[len(ctxNsPart):]) 56 } 57 }) 58 } 59 60 func hasProperPrefix(s, p string) bool { 61 return len(s) > len(p) && strings.HasPrefix(s, p) 62 }