forked from u-root/u-root
/
complete_variable.go
62 lines (52 loc) · 1.55 KB
/
complete_variable.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
package completion
import (
"strings"
"github.com/u-root/u-root/cmds/elvish/eval"
"github.com/u-root/u-root/cmds/elvish/parse"
)
type variableComplContext struct {
complContextCommon
ns, nsPart string
}
func (*variableComplContext) name() string { return "variable" }
func findVariableComplContext(n parse.Node, _ pureEvaler) complContext {
primary := parse.GetPrimary(n)
if primary != nil && primary.Type == parse.Variable {
explode, nsPart, nameSeed := eval.SplitIncompleteVariableRef(primary.Value)
// Move past "$", "@" and "<ns>:".
begin := primary.Begin() + 1 + len(explode) + len(nsPart)
ns := nsPart
if len(ns) > 0 {
ns = ns[:len(ns)-1]
}
return &variableComplContext{
complContextCommon{nameSeed, parse.Bareword, begin, primary.End()},
ns, nsPart,
}
}
return nil
}
type evalerScopes interface {
EachVariableInTop(string, func(string))
EachNsInTop(func(string))
}
func (ctx *variableComplContext) generate(env *complEnv, ch chan<- rawCandidate) error {
complVariable(ctx.ns, ctx.nsPart, env.evaler, ch)
return nil
}
func complVariable(ctxNs, ctxNsPart string, ev evalerScopes, ch chan<- rawCandidate) {
ev.EachVariableInTop(ctxNs, func(varname string) {
ch <- noQuoteCandidate(varname)
})
ev.EachNsInTop(func(ns string) {
nsPart := ns + ":"
// This is to match namespaces that are "nested" under the current
// namespace.
if hasProperPrefix(nsPart, ctxNsPart) {
ch <- noQuoteCandidate(nsPart[len(ctxNsPart):])
}
})
}
func hasProperPrefix(s, p string) bool {
return len(s) > len(p) && strings.HasPrefix(s, p)
}