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