mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-12 17:27:50 +08:00
Add a builtin namespace. Now this is really Pythonic.
The "acme" builtin module finally works.
This commit is contained in:
parent
657448acf3
commit
6fbadd6f31
|
@ -36,6 +36,11 @@ func complVariable(n parse.Node, ed *Editor) []*candidate {
|
|||
|
||||
// Collect matching variables.
|
||||
var varnames []string
|
||||
for varname := range ed.evaler.Builtin() {
|
||||
if strings.HasPrefix(varname, head) {
|
||||
varnames = append(varnames, varname)
|
||||
}
|
||||
}
|
||||
for varname := range ed.evaler.Global() {
|
||||
if strings.HasPrefix(varname, head) {
|
||||
varnames = append(varnames, varname)
|
||||
|
@ -104,6 +109,11 @@ func complFormHeadInner(head string, ed *Editor) []*candidate {
|
|||
for special := range isBuiltinSpecial {
|
||||
foundCommand(special)
|
||||
}
|
||||
for variable := range ed.evaler.Builtin() {
|
||||
if strings.HasPrefix(variable, eval.FnPrefix) {
|
||||
foundCommand(variable[len(eval.FnPrefix):])
|
||||
}
|
||||
}
|
||||
for variable := range ed.evaler.Global() {
|
||||
if strings.HasPrefix(variable, eval.FnPrefix) {
|
||||
foundCommand(variable[len(eval.FnPrefix):])
|
||||
|
|
|
@ -34,8 +34,9 @@ func goodFormHead(head string, ed *Editor) bool {
|
|||
// XXX don't stat twice
|
||||
return util.IsExecutable(head) || isDir(head)
|
||||
} else {
|
||||
return ed.evaler.Global()[eval.FnPrefix+head] != nil ||
|
||||
ed.isExternal[head]
|
||||
return ed.isExternal[head] ||
|
||||
ed.evaler.Builtin()[eval.FnPrefix+head] != nil ||
|
||||
ed.evaler.Global()[eval.FnPrefix+head] != nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
25
eval/eval.go
25
eval/eval.go
|
@ -32,6 +32,7 @@ type Namespace map[string]Variable
|
|||
// Evaler is used to evaluate elvish sources. It maintains runtime context
|
||||
// shared among all evalCtx instances.
|
||||
type Evaler struct {
|
||||
builtin Namespace
|
||||
global Namespace
|
||||
modules map[string]Namespace
|
||||
store *store.Store
|
||||
|
@ -57,11 +58,9 @@ func (ec *EvalCtx) evaling(n parse.Node) {
|
|||
|
||||
// NewEvaler creates a new Evaler.
|
||||
func NewEvaler(st *store.Store) *Evaler {
|
||||
ev := &Evaler{nil, map[string]Namespace{}, st, nil, nil}
|
||||
|
||||
// Construct initial global namespace
|
||||
pid := String(strconv.Itoa(syscall.Getpid()))
|
||||
ev.global = Namespace{
|
||||
builtin := Namespace{
|
||||
"pid": NewRoVariable(pid),
|
||||
"ok": NewRoVariable(OK),
|
||||
"true": NewRoVariable(Bool(true)),
|
||||
|
@ -70,14 +69,14 @@ func NewEvaler(st *store.Store) *Evaler {
|
|||
"pwd": PwdVariable{},
|
||||
}
|
||||
for _, b := range builtinFns {
|
||||
ev.global[FnPrefix+b.Name] = NewRoVariable(b)
|
||||
builtin[FnPrefix+b.Name] = NewRoVariable(b)
|
||||
}
|
||||
|
||||
return ev
|
||||
return &Evaler{builtin, Namespace{}, map[string]Namespace{}, st, nil, nil}
|
||||
}
|
||||
|
||||
func (e *Evaler) searchPaths() []string {
|
||||
return e.global["paths"].(*EnvPathList).get()
|
||||
return e.builtin["paths"].(*EnvPathList).get()
|
||||
}
|
||||
|
||||
func (e *Evaler) AddModule(name string, ns Namespace) {
|
||||
|
@ -326,8 +325,13 @@ func (ev *Evaler) Source(fname string) error {
|
|||
return ev.SourceText(src)
|
||||
}
|
||||
|
||||
// Builtin returns the builtin namespace.
|
||||
func (ev *Evaler) Builtin() Namespace {
|
||||
return map[string]Variable(ev.builtin)
|
||||
}
|
||||
|
||||
// Global returns the global namespace.
|
||||
func (ev *Evaler) Global() map[string]Variable {
|
||||
func (ev *Evaler) Global() Namespace {
|
||||
return map[string]Variable(ev.global)
|
||||
}
|
||||
|
||||
|
@ -339,11 +343,16 @@ func (ec *EvalCtx) ResolveVar(ns, name string) Variable {
|
|||
return ec.local[name]
|
||||
case "up":
|
||||
return ec.up[name]
|
||||
case "builtin":
|
||||
return ec.builtin[name]
|
||||
case "":
|
||||
if v, ok := ec.local[name]; ok {
|
||||
return v
|
||||
}
|
||||
return ec.up[name]
|
||||
if v, ok := ec.up[name]; ok {
|
||||
return v
|
||||
}
|
||||
return ec.builtin[name]
|
||||
case "env", "external", "e", "E":
|
||||
if strings.HasPrefix(name, FnPrefix) {
|
||||
return NewRoVariable(ExternalCmd{name[len(FnPrefix):]})
|
||||
|
|
|
@ -15,8 +15,8 @@ import (
|
|||
func TestNewEvaler(t *testing.T) {
|
||||
ev := NewEvaler(nil)
|
||||
pid := strconv.Itoa(syscall.Getpid())
|
||||
if ToString(ev.global["pid"].Get()) != pid {
|
||||
t.Errorf(`ev.global["pid"] = %v, want %v`, ev.global["pid"], pid)
|
||||
if ToString(ev.builtin["pid"].Get()) != pid {
|
||||
t.Errorf(`ev.builtin["pid"] = %v, want %v`, ev.builtin["pid"], pid)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user