eval: BuiltinFn -> GoFn.

This commit is contained in:
Qi Xiao 2019-04-18 22:57:14 +01:00
parent c8e767b2fd
commit a0c53d4c40
33 changed files with 105 additions and 109 deletions

View File

@ -8,14 +8,14 @@ import (
)
func TestRawFilterCandidates(t *testing.T) {
passAll := eval.NewBuiltinFn("test:passAll",
passAll := eval.NewGoFn("test:passAll",
func(fm *eval.Frame, pattern string, inputs eval.Inputs) {
out := fm.OutputChan()
inputs(func(v interface{}) {
out <- vals.Bool(true)
})
})
blockAll := eval.NewBuiltinFn("test:blockAll",
blockAll := eval.NewGoFn("test:blockAll",
func(fm *eval.Frame, pattern string, inputs eval.Inputs) {
out := fm.OutputChan()
inputs(func(v interface{}) {
@ -43,7 +43,7 @@ func TestRawFilterCandidates(t *testing.T) {
func TestComplexCandidate(t *testing.T) {
setup := func(ev *eval.Evaler) {
ev.Builtin.AddNs("edit", eval.NewNs().AddBuiltinFn(
ev.Builtin.AddNs("edit", eval.NewNs().AddGoFn(
"edit:", "complex-candidate", makeComplexCandidate))
}
That := eval.That

View File

@ -51,7 +51,7 @@ func Init(ed eddefs.Editor, ns eval.Ns) {
"binding": vars.FromPtr(&c.binding),
"matcher": vars.FromPtr(&c.matcher),
"arg-completer": vars.FromPtr(&c.argCompleter),
}.AddBuiltinFns("edit:completion:", map[string]interface{}{
}.AddGoFns("edit:completion:", map[string]interface{}{
"start": func() { c.start(ed, false) },
"smart-start": func() { c.start(ed, true) },
"up": func() { c.prev(false) },
@ -77,7 +77,7 @@ func Init(ed eddefs.Editor, ns eval.Ns) {
ns.AddFn("match-subseq", matchSubseq)
// Other functions.
ns.AddBuiltinFns("edit:", map[string]interface{}{
ns.AddGoFns("edit:", map[string]interface{}{
"complete-getopt": complGetopt,
"complex-candidate": makeComplexCandidate,
})

View File

@ -17,11 +17,11 @@ var (
)
var (
matchPrefix = eval.NewBuiltinFn(
matchPrefix = eval.NewGoFn(
"edit:match-prefix", wrapMatcher(strings.HasPrefix))
matchSubstr = eval.NewBuiltinFn(
matchSubstr = eval.NewGoFn(
"edit:match-substr", wrapMatcher(strings.Contains))
matchSubseq = eval.NewBuiltinFn(
matchSubseq = eval.NewGoFn(
"edit:match-subseq", wrapMatcher(util.HasSubseq))
)

View File

@ -98,7 +98,7 @@ func makeNs(ed *editor) eval.Ns {
"wordify": wordifyBuiltin,
"-dump-buf": ed.dumpBuf,
}
ns.AddBuiltinFns("edit:", fns)
ns.AddGoFns("edit:", fns)
return ns
}

View File

@ -22,7 +22,7 @@ func init() {
}
func initCoreFns(ed *editor, ns eval.Ns) {
ns.AddBuiltinFns("edit:", map[string]interface{}{
ns.AddGoFns("edit:", map[string]interface{}{
"kill-line-left": ed.applyKill(moveDotSOL),
"kill-line-right": ed.applyKill(moveDotEOL),
"kill-word-left": ed.applyKill(moveDotLeftWord),
@ -80,7 +80,7 @@ func initInsert(ed *editor, ns eval.Ns) {
insertNs := eval.Ns{
"binding": vars.FromPtr(&insert.binding),
}
insertNs.AddBuiltinFns("edit:insert:", map[string]interface{}{
insertNs.AddGoFns("edit:insert:", map[string]interface{}{
"start": ed.SetModeInsert,
"default": ed.insertDefault,
})
@ -115,7 +115,7 @@ func initCommand(ed *editor, ns eval.Ns) {
commandNs := eval.Ns{
"binding": vars.FromPtr(&command.binding),
}
commandNs.AddBuiltinFns("edit:command:", map[string]interface{}{
commandNs.AddGoFns("edit:command:", map[string]interface{}{
"start": ed.commandStart,
"default": ed.commandDefault,
})

View File

@ -38,7 +38,7 @@ func initListing(ed *editor, ns eval.Ns) {
subns := eval.Ns{
"binding": vars.FromPtr(&l.commonBinding),
}
subns.AddBuiltinFns("edit:listing:", map[string]interface{}{
subns.AddGoFns("edit:listing:", map[string]interface{}{
"up": func() { l.up(false) },
"up-cycle": func() { l.up(true) },
"page-up": func() { l.pageUp() },

View File

@ -28,7 +28,7 @@ func initNarrow(ed *editor, ns eval.Ns) {
subns := eval.Ns{
"binding": vars.FromPtr(&n.binding),
}
subns.AddBuiltinFns("edit:narrow:", map[string]interface{}{
subns.AddGoFns("edit:narrow:", map[string]interface{}{
"up": func() { n.up(false) },
"up-cycle": func() { n.up(true) },
"page-up": func() { n.pageUp() },
@ -52,7 +52,7 @@ func initNarrow(ed *editor, ns eval.Ns) {
"default": func() { n.defaultBinding(ed) },
})
ns.AddNs("narrow", subns)
ns.AddBuiltinFn("edit:", "-narrow-read", n.NarrowRead)
ns.AddGoFn("edit:", "-narrow-read", n.NarrowRead)
}
type narrowState struct {

View File

@ -48,7 +48,7 @@ func initNavigation(ed *editor, ns eval.Ns) {
subns := eval.Ns{
"binding": vars.FromPtr(&n.binding),
}
subns.AddBuiltinFns("edit:navigation:", map[string]interface{}{
subns.AddGoFns("edit:navigation:", map[string]interface{}{
"start": func() { n.start(ed) },
"up": n.prev,
"down": n.next,

View File

@ -50,7 +50,7 @@ func Init(ed eddefs.Editor, ns eval.Ns) {
"binding": vars.FromPtr(&hist.binding),
"list": vars.NewReadOnly(List{&hist.mutex, ed.Daemon()}),
}
historyNs.AddBuiltinFns("edit:history:", map[string]interface{}{
historyNs.AddGoFns("edit:history:", map[string]interface{}{
"start": hist.start,
"up": hist.up,
"down": hist.down,
@ -63,7 +63,7 @@ func Init(ed eddefs.Editor, ns eval.Ns) {
histlistNs := eval.Ns{
"binding": vars.FromPtr(&histlistBinding),
}
histlistNs.AddBuiltinFns("edit:histlist:", map[string]interface{}{
histlistNs.AddGoFns("edit:histlist:", map[string]interface{}{
"start": func() {
hl.start(ed, hist.fuser, histlistBinding)
},
@ -74,7 +74,7 @@ func Init(ed eddefs.Editor, ns eval.Ns) {
ns.AddNs("history", historyNs)
ns.AddNs("histlist", histlistNs)
// TODO(xiaq): Rename and put in edit:history
ns.AddBuiltinFn("edit:", "command-history", hist.commandHistory)
ns.AddGoFn("edit:", "command-history", hist.commandHistory)
}
func (h *hist) Teardown() {

View File

@ -32,7 +32,7 @@ func Init(ed eddefs.Editor, ns eval.Ns) {
subns := eval.Ns{
"binding": vars.FromPtr(&binding),
}
subns.AddBuiltinFns("edit:lastcmd:", map[string]interface{}{
subns.AddGoFns("edit:lastcmd:", map[string]interface{}{
"start": func() { lc.start(ed, binding) },
"accept-line": func() { lc.acceptLine(ed) },
})

View File

@ -37,7 +37,7 @@ type mode struct {
matcher eval.Callable
}
var matchDirPatternBuiltin = eval.NewBuiltinFn("edit:location:match-dir-pattern", matchDirPattern)
var matchDirPatternBuiltin = eval.NewGoFn("edit:location:match-dir-pattern", matchDirPattern)
// Init initializes the location mode for an Editor.
func Init(ed eddefs.Editor, ns eval.Ns) {
@ -51,7 +51,7 @@ func Init(ed eddefs.Editor, ns eval.Ns) {
"pinned": vars.FromPtr(&m.pinned),
"matcher": vars.FromPtr(&m.matcher),
"workspaces": vars.FromPtr(&m.workspaces),
}.AddBuiltinFn("edit:location:", "start", m.start).
}.AddGoFn("edit:location:", "start", m.start).
AddFn("match-dir-pattern", matchDirPatternBuiltin))
ed.Evaler().AddAfterChdir(func(string) {

View File

@ -59,7 +59,7 @@ var (
"/home",
nil,
eval.NewEvaler(),
eval.NewBuiltinFn("edit:location:test:match-prefix", matchPrefix))
eval.NewGoFn("edit:location:test:match-prefix", matchPrefix))
locationWithPrefixMatcherTests = []eddefs.ListingProviderFilterTest{
{"", []eddefs.ListingShown{

View File

@ -24,7 +24,7 @@ func init() {
out <- &ui.Styled{"> ", ui.Styles{}}
}
}
defaultPrompt = eval.NewBuiltinFn("default prompt", prompt)
defaultPrompt = eval.NewGoFn("default prompt", prompt)
}
func init() {
@ -42,7 +42,7 @@ func init() {
out := fm.OutputChan()
out <- &ui.Styled{rpromptStr, ui.Styles{"inverse"}}
}
defaultRPrompt = eval.NewBuiltinFn("default rprompt", rprompt)
defaultRPrompt = eval.NewGoFn("default rprompt", rprompt)
}
func init() {
@ -53,5 +53,5 @@ func init() {
out <- &ui.Styled{s.Text, ui.Styles{"inverse"}}
})
}
defaultStaleTransform = eval.NewBuiltinFn("default stale transform", staleTransform)
defaultStaleTransform = eval.NewGoFn("default stale transform", staleTransform)
}

View File

@ -1,6 +1,6 @@
package eval
// Builtin functions.
// Misc builtin functions.
import (
"fmt"
@ -51,7 +51,7 @@ func kindOf(fm *Frame, args ...interface{}) {
func constantly(args ...interface{}) Callable {
// XXX Repr of this fn is not right
return NewBuiltinFn(
return NewGoFn(
"created by constantly",
func(fm *Frame) {
out := fm.ports[1].Chan

View File

@ -21,5 +21,5 @@ var builtinNs = Ns{
}
func addBuiltinFns(fns map[string]interface{}) {
builtinNs.AddBuiltinFns("", fns)
builtinNs.AddGoFns("", fns)
}

View File

@ -194,7 +194,7 @@ func (op fnOp) invoke(fm *Frame) error {
// Initialize the function variable with the builtin nop function. This step
// allows the definition of recursive functions; the actual function will
// never be called.
fm.local[op.varName] = vars.FromInit(NewBuiltinFn("<shouldn't be called>", nop))
fm.local[op.varName] = vars.FromInit(NewGoFn("<shouldn't be called>", nop))
values, err := op.lambdaOp.invoke(fm)
if err != nil {
return err

View File

@ -41,7 +41,7 @@ func Ns(daemon *daemon.Client, spawner *daemonp.Daemon) eval.Ns {
return eval.Ns{
"pid": vars.FromGet(getPidVar),
"sock": vars.NewReadOnly(string(daemon.SockPath())),
}.AddBuiltinFns("daemon:", map[string]interface{}{
}.AddGoFns("daemon:", map[string]interface{}{
"pid": getPid,
"spawn": spawn,
})

View File

@ -11,18 +11,17 @@ import (
)
var (
// ErrArgs is thrown when a builtin function gets erroneous arguments.
// ErrArgs is thrown when a Go function gets erroneous arguments.
//
// TODO(xiaq): Replace this single error type with multiple types that carry
// richer error information.
ErrArgs = errors.New("args error")
// ErrNoOptAccepted is thrown when a builtin function that does not accept
// any options gets passed options.
// ErrNoOptAccepted is thrown when a Go function that does not accept any
// options gets passed options.
ErrNoOptAccepted = errors.New("function does not accept any options")
)
// BuiltinFn uses reflection to wrap arbitrary Go functions into Elvish
// functions.
// GoFn uses reflection to wrap arbitrary Go functions into Elvish functions.
//
// Parameters are passed following these rules:
//
@ -49,9 +48,7 @@ var (
// converted using goToElv. If the last return value has type error and is not
// nil, it is turned into an exception and no ouputting happens. If the last
// return value is a nil error, it is ignored.
//
// TODO(xiaq): Rename this to NativeFn.
type BuiltinFn struct {
type GoFn struct {
name string
impl interface{}
@ -71,7 +68,7 @@ type BuiltinFn struct {
variadicArg reflect.Type
}
var _ Callable = &BuiltinFn{}
var _ Callable = &GoFn{}
// An interface to be implemented by pointers to structs that should hold
// scanned options.
@ -79,9 +76,9 @@ type optionsPtr interface {
SetDefaultOptions()
}
// Inputs is the type that the last parameter of a builtin function can take.
// When that is the case, it is a callback to get inputs. See the doc of
// BuiltinFn for details.
// Inputs is the type that the last parameter of a Go-native function can take.
// When that is the case, it is a callback to get inputs. See the doc of GoFn
// for details.
type Inputs func(func(interface{}))
var (
@ -91,10 +88,10 @@ var (
inputsType = reflect.TypeOf(Inputs(nil))
)
// NewBuiltinFn creates a new ReflectBuiltinFn instance.
func NewBuiltinFn(name string, impl interface{}) *BuiltinFn {
// NewGoFn creates a new GoFn instance.
func NewGoFn(name string, impl interface{}) *GoFn {
implType := reflect.TypeOf(impl)
b := &BuiltinFn{name: name, impl: impl}
b := &GoFn{name: name, impl: impl}
i := 0
if i < implType.NumIn() && implType.In(i) == frameType {
@ -129,22 +126,22 @@ func NewBuiltinFn(name string, impl interface{}) *BuiltinFn {
}
// Kind returns "fn".
func (*BuiltinFn) Kind() string {
func (*GoFn) Kind() string {
return "fn"
}
// Equal compares identity.
func (b *BuiltinFn) Equal(rhs interface{}) bool {
func (b *GoFn) Equal(rhs interface{}) bool {
return b == rhs
}
// Hash hashes the address.
func (b *BuiltinFn) Hash() uint32 {
func (b *GoFn) Hash() uint32 {
return hash.Pointer(unsafe.Pointer(b))
}
// Repr returns an opaque representation "<builtin $name>".
func (b *BuiltinFn) Repr(int) string {
func (b *GoFn) Repr(int) string {
return "<builtin " + b.name + ">"
}
@ -155,7 +152,7 @@ var errorType = reflect.TypeOf((*error)(nil)).Elem()
var errNoOptions = errors.New("function does not accept any options")
// Call calls the implementation using reflection.
func (b *BuiltinFn) Call(f *Frame, args []interface{}, opts map[string]interface{}) error {
func (b *GoFn) Call(f *Frame, args []interface{}, opts map[string]interface{}) error {
if b.variadicArg != nil {
if len(args) < len(b.normalArgs) {
return fmt.Errorf("want %d or more arguments, got %d",

View File

@ -14,7 +14,7 @@ type testOptions struct {
func (o *testOptions) SetDefaultOptions() { o.Bar = "default" }
func TestReflectBuiltinFnCall(t *testing.T) {
func TestGoFnCall(t *testing.T) {
theFrame := new(Frame)
theOptions := map[string]interface{}{}
@ -33,7 +33,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
}
// *Frame parameter gets the Frame.
f = NewBuiltinFn("f", func(f *Frame) {
f = NewGoFn("f", func(f *Frame) {
if f != theFrame {
t.Errorf("*Frame parameter doesn't get current frame")
}
@ -41,7 +41,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
callGood(theFrame, nil, theOptions)
// RawOptions parameter gets options.
f = NewBuiltinFn("f", func(opts RawOptions) {
f = NewGoFn("f", func(opts RawOptions) {
if opts["foo"] != "bar" {
t.Errorf("RawOptions parameter doesn't get options")
}
@ -49,7 +49,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
callGood(theFrame, nil, RawOptions{"foo": "bar"})
// ScanOptions parameters gets scanned options.
f = NewBuiltinFn("f", func(opts testOptions) {
f = NewGoFn("f", func(opts testOptions) {
if opts.Foo != "bar" {
t.Errorf("ScanOptions parameter doesn't get options")
}
@ -60,7 +60,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
callGood(theFrame, nil, RawOptions{"foo": "bar"})
// Combination of Frame and RawOptions.
f = NewBuiltinFn("f", func(f *Frame, opts RawOptions) {
f = NewGoFn("f", func(f *Frame, opts RawOptions) {
if f != theFrame {
t.Errorf("*Frame parameter doesn't get current frame")
}
@ -71,7 +71,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
callGood(theFrame, nil, RawOptions{"foo": "bar"})
// Argument passing.
f = NewBuiltinFn("f", func(x, y string) {
f = NewGoFn("f", func(x, y string) {
if x != "lorem" {
t.Errorf("Argument x not passed")
}
@ -82,7 +82,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
callGood(theFrame, []interface{}{"lorem", "ipsum"}, theOptions)
// Variadic arguments.
f = NewBuiltinFn("f", func(x ...string) {
f = NewGoFn("f", func(x ...string) {
if len(x) != 2 || x[0] != "lorem" || x[1] != "ipsum" {
t.Errorf("Variadic argument not passed")
}
@ -90,7 +90,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
callGood(theFrame, []interface{}{"lorem", "ipsum"}, theOptions)
// Conversion into int and float64.
f = NewBuiltinFn("f", func(i int, f float64) {
f = NewGoFn("f", func(i int, f float64) {
if i != 314 {
t.Errorf("Integer argument i not passed")
}
@ -101,7 +101,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
callGood(theFrame, []interface{}{"314", "1.25"}, theOptions)
// Conversion of supplied inputs.
f = NewBuiltinFn("f", func(i Inputs) {
f = NewGoFn("f", func(i Inputs) {
var values []interface{}
i(func(x interface{}) {
values = append(values, x)
@ -119,7 +119,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
ch <- "bar"
close(ch)
inFrame.ports[0] = &Port{Chan: ch}
f = NewBuiltinFn("f", func(i Inputs) {
f = NewGoFn("f", func(i Inputs) {
var values []interface{}
i(func(x interface{}) {
values = append(values, x)
@ -134,7 +134,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
outFrame := &Frame{ports: make([]*Port, 3)}
ch = make(chan interface{}, 10)
outFrame.ports[1] = &Port{Chan: ch}
f = NewBuiltinFn("f", func() string { return "ret" })
f = NewGoFn("f", func() string { return "ret" })
callGood(outFrame, nil, theOptions)
select {
case ret := <-ch:
@ -146,7 +146,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
}
// Conversion of return values.
f = NewBuiltinFn("f", func() int { return 314 })
f = NewGoFn("f", func() int { return 314 })
callGood(outFrame, nil, theOptions)
select {
case ret := <-ch:
@ -159,7 +159,7 @@ func TestReflectBuiltinFnCall(t *testing.T) {
// Passing of error return value.
theError := errors.New("the error")
f = NewBuiltinFn("f", func() (string, error) {
f = NewGoFn("f", func() (string, error) {
return "x", theError
})
if f.Call(outFrame, nil, theOptions) != theError {
@ -172,41 +172,41 @@ func TestReflectBuiltinFnCall(t *testing.T) {
}
// Too many arguments.
f = NewBuiltinFn("f", func() {
f = NewGoFn("f", func() {
t.Errorf("Function called when there are too many arguments")
})
callBad(theFrame, []interface{}{"x"}, theOptions)
// Too few arguments.
f = NewBuiltinFn("f", func(x string) {
f = NewGoFn("f", func(x string) {
t.Errorf("Function called when there are too few arguments")
})
callBad(theFrame, nil, theOptions)
f = NewBuiltinFn("f", func(x string, y ...string) {
f = NewGoFn("f", func(x string, y ...string) {
t.Errorf("Function called when there are too few arguments")
})
callBad(theFrame, nil, theOptions)
// Options when the function does not accept options.
f = NewBuiltinFn("f", func() {
f = NewGoFn("f", func() {
t.Errorf("Function called when there are extra options")
})
callBad(theFrame, nil, RawOptions{"foo": "bar"})
// Wrong argument type.
f = NewBuiltinFn("f", func(x string) {
f = NewGoFn("f", func(x string) {
t.Errorf("Function called when arguments have wrong type")
})
callBad(theFrame, []interface{}{1}, theOptions)
// Wrong argument type: cannot convert to int.
f = NewBuiltinFn("f", func(x int) {
f = NewGoFn("f", func(x int) {
t.Errorf("Function called when arguments have wrong type")
})
callBad(theFrame, []interface{}{"x"}, theOptions)
// Wrong argument type: cannot convert to float64.
f = NewBuiltinFn("f", func(x float64) {
f = NewGoFn("f", func(x float64) {
t.Errorf("Function called when arguments have wrong type")
})
callBad(theFrame, []interface{}{"x"}, theOptions)

View File

@ -92,17 +92,15 @@ func (ns Ns) AddNs(name string, v Ns) Ns {
return ns.Add(name+NsSuffix, vars.FromPtr(&v))
}
// AddBuiltinFn adds a builtin function to a namespace. It returns the namespace
// itself.
func (ns Ns) AddBuiltinFn(nsName, name string, impl interface{}) Ns {
return ns.AddFn(name, NewBuiltinFn(nsName+name, impl))
// AddGoFn adds a Go function to a namespace. It returns the namespace itself.
func (ns Ns) AddGoFn(nsName, name string, impl interface{}) Ns {
return ns.AddFn(name, NewGoFn(nsName+name, impl))
}
// AddBuiltinFns adds builtin functions to a namespace. It returns the namespace
// itself.
func (ns Ns) AddBuiltinFns(nsName string, fns map[string]interface{}) Ns {
// AddGoFns adds Go functions to a namespace. It returns the namespace itself.
func (ns Ns) AddGoFns(nsName string, fns map[string]interface{}) Ns {
for name, impl := range fns {
ns.AddBuiltinFn(nsName, name, impl)
ns.AddGoFn(nsName, name, impl)
}
return ns
}

View File

@ -9,8 +9,9 @@ import (
"github.com/elves/elvish/util"
)
// RawOptions is the type of an argument a builtin function can take to declare
// that it wants to parse options itself. See the doc of BuiltinFn for details.
// RawOptions is the type of an argument a Go-native function can take to
// declare that it wants to parse options itself. See the doc of GoFn for
// details.
type RawOptions map[string]interface{}
// Takes a raw option map and a pointer to a struct, and populate the struct

View File

@ -11,7 +11,7 @@ import (
)
// Ns is the namespace for the re: module.
var Ns = eval.NewNs().AddBuiltinFns("re:", fns)
var Ns = eval.NewNs().AddGoFns("re:", fns)
var fns = map[string]interface{}{
"quote": regexp.QuoteMeta,

View File

@ -6,7 +6,7 @@ import (
)
func Ns(s storedefs.Store) eval.Ns {
return eval.NewNs().AddBuiltinFns("store:", map[string]interface{}{
return eval.NewNs().AddGoFns("store:", map[string]interface{}{
"del-dir": s.DelDir,
"del-cmd": s.DelCmd,
})

View File

@ -8,7 +8,7 @@ import (
"github.com/elves/elvish/eval"
)
var Ns = eval.NewNs().AddBuiltinFns("str:", fns)
var Ns = eval.NewNs().AddGoFns("str:", fns)
var fns = map[string]interface{}{
"compare": strings.Compare,

View File

@ -14,7 +14,7 @@ import (
func TestKeyHandlerFromBinding_CallsBinding(t *testing.T) {
called := 0
binding := buildBinding(
"a", eval.NewBuiltinFn("[test]", func() { called++ }))
"a", eval.NewGoFn("[test]", func() { called++ }))
handler := keyHandlerFromBindings(&fakeEditor{}, eval.NewEvaler(), &binding)
action := handler(ui.Key{Rune: 'a'})
@ -31,7 +31,7 @@ func TestKeyHandlerFromBinding_SetsBindingKey(t *testing.T) {
ed := &fakeEditor{}
var gotKey ui.Key
binding := buildBinding(
"a", eval.NewBuiltinFn("[test]", func() { gotKey = ed.State().BindingKey() }))
"a", eval.NewGoFn("[test]", func() { gotKey = ed.State().BindingKey() }))
handler := keyHandlerFromBindings(ed, eval.NewEvaler(), &binding)
key := ui.Key{Rune: 'a'}
@ -65,10 +65,10 @@ func TestIndexLayeredBindings(t *testing.T) {
// 3. Key
called := 0
binding1 := buildBinding(
"a", eval.NewBuiltinFn("[a1]", func() { called = 1 }))
"a", eval.NewGoFn("[a1]", func() { called = 1 }))
binding2 := buildBinding(
"a", eval.NewBuiltinFn("[a2]", func() { called = 2 }),
"b", eval.NewBuiltinFn("[b2]", func() { called = 2 }))
"a", eval.NewGoFn("[a2]", func() { called = 2 }),
"b", eval.NewGoFn("[b2]", func() { called = 2 }))
handler := keyHandlerFromBindings(&fakeEditor{}, eval.NewEvaler(),
&binding1, &binding2)
@ -88,7 +88,7 @@ func TestIndexLayeredBindings(t *testing.T) {
// Use lower layer default when upper layer does not have default
b, _ := binding2.Assoc(
ui.Default, eval.NewBuiltinFn("[d2]", func() { called = 2 }))
ui.Default, eval.NewGoFn("[d2]", func() { called = 2 }))
binding2 = b.(BindingMap)
called = 0
@ -99,7 +99,7 @@ func TestIndexLayeredBindings(t *testing.T) {
// Prefer upper layer default
b, _ = binding1.Assoc(
ui.Default, eval.NewBuiltinFn("[d1]", func() { called = 1 }))
ui.Default, eval.NewGoFn("[d1]", func() { called = 1 }))
binding1 = b.(BindingMap)
called = 0
@ -110,7 +110,7 @@ func TestIndexLayeredBindings(t *testing.T) {
// Exact matches in all layers are tried before falling back to default
b, _ = binding2.Assoc(
"c", eval.NewBuiltinFn("[c2]", func() { called = 2 }))
"c", eval.NewGoFn("[c2]", func() { called = 2 }))
binding2 = b.(BindingMap)
called = 0
@ -137,7 +137,7 @@ func TestCallBinding_CallsFunction(t *testing.T) {
nt := &fakeNotifier{}
called := 0
callBinding(nt, ev, eval.NewBuiltinFn("test binding", func() {
callBinding(nt, ev, eval.NewGoFn("test binding", func() {
called++
}))
if called != 1 {
@ -149,7 +149,7 @@ func TestCallBinding_CapturesAction(t *testing.T) {
ev := eval.NewEvaler()
nt := &fakeNotifier{}
action := callBinding(nt, ev, eval.NewBuiltinFn("test", func() error {
action := callBinding(nt, ev, eval.NewGoFn("test", func() error {
return editutil.ActionError(types.CommitCode)
}))
if action != types.CommitCode {
@ -161,7 +161,7 @@ func TestCallBinding_NotifyOnValueOutput(t *testing.T) {
ev := eval.NewEvaler()
nt := &fakeNotifier{}
callBinding(nt, ev, eval.NewBuiltinFn("test binding", func(fm *eval.Frame) {
callBinding(nt, ev, eval.NewGoFn("test binding", func(fm *eval.Frame) {
fm.OutputChan() <- "VALUE"
}))
wantNotes := []string{"[value out] VALUE"}
@ -174,7 +174,7 @@ func TestCallBinding_NotifyOnByteOutput(t *testing.T) {
ev := eval.NewEvaler()
nt := &fakeNotifier{}
callBinding(nt, ev, eval.NewBuiltinFn("test binding", func(fm *eval.Frame) {
callBinding(nt, ev, eval.NewGoFn("test binding", func(fm *eval.Frame) {
fm.OutputFile().WriteString("BYTES")
}))
wantNotes := []string{"[bytes out] BYTES"}
@ -187,7 +187,7 @@ func TestCallBinding_StripsNewlinesFromByteOutput(t *testing.T) {
ev := eval.NewEvaler()
nt := &fakeNotifier{}
callBinding(nt, ev, eval.NewBuiltinFn("test binding", func(fm *eval.Frame) {
callBinding(nt, ev, eval.NewGoFn("test binding", func(fm *eval.Frame) {
fm.OutputFile().WriteString("line 1\nline 2\n")
}))
wantNotes := []string{"[bytes out] line 1", "[bytes out] line 2"}
@ -200,7 +200,7 @@ func TestCallBinding_NotifyOnError(t *testing.T) {
ev := eval.NewEvaler()
nt := &fakeNotifier{}
callBinding(nt, ev, eval.NewBuiltinFn("test binding", func() error {
callBinding(nt, ev, eval.NewGoFn("test binding", func() error {
return errors.New("ERROR")
}))
wantNotes := []string{"[binding error] ERROR"}

View File

@ -32,14 +32,14 @@ func NewEditor(in, out *os.File, ev *eval.Evaler, st storedefs.Store) *Editor {
ns := eval.NewNs().
Add("max-height",
vars.FromPtrWithMutex(&ed.Config.Raw.MaxHeight, &ed.Config.Mutex)).
AddBuiltinFns("<edit>", map[string]interface{}{
AddGoFns("<edit>", map[string]interface{}{
"binding-map": makeBindingMap,
"exit-binding": exitBinding,
"commit-code": commitCode,
"commit-eof": commitEOF,
"reset-mode": makeResetMode(ed.State()),
}).
AddBuiltinFns("<edit>", bufferBuiltins(ed.State()))
AddGoFns("<edit>", bufferBuiltins(ed.State()))
// Hooks
ns["before-readline"], ed.BeforeReadline = initBeforeReadline(ev)

View File

@ -46,7 +46,7 @@ func TestMakeHasCommand(t *testing.T) {
hasCommand := makeHasCommand(ev)
// Set up global functions and modules in the evaler.
goodFn := eval.NewBuiltinFn("good", func() {})
goodFn := eval.NewGoFn("good", func() {})
ev.Global.AddFn("good", goodFn)
aNs := eval.Ns{}.AddFn("good", goodFn)
bNs := eval.Ns{}.AddFn("good", goodFn)

View File

@ -10,7 +10,7 @@ import (
func TestInitBeforeReadline(t *testing.T) {
variable, cb := initBeforeReadline(eval.NewEvaler())
called := 0
variable.Set(vals.EmptyList.Cons(eval.NewBuiltinFn("[test]", func() {
variable.Set(vals.EmptyList.Cons(eval.NewGoFn("[test]", func() {
called++
})))
cb()
@ -24,7 +24,7 @@ func TestInitAfterReadline(t *testing.T) {
variable, cb := initAfterReadline(eval.NewEvaler())
called := 0
calledWith := ""
variable.Set(vals.EmptyList.Cons(eval.NewBuiltinFn("[test]", func(s string) {
variable.Set(vals.EmptyList.Cons(eval.NewGoFn("[test]", func(s string) {
called++
calledWith = s
})))

View File

@ -29,7 +29,7 @@ func initInsert(ed editor, ev *eval.Evaler) (*insert.Mode, eval.Ns) {
"abbr": vars.FromPtr(&abbr),
"quote-paste": vars.FromPtrWithMutex(
&m.Config.Raw.QuotePaste, &m.Config.Mutex),
}.AddBuiltinFns("<edit:insert>:", map[string]interface{}{
}.AddGoFns("<edit:insert>:", map[string]interface{}{
"start": func() { st.SetMode(m) },
"default-handler": func() error {
action := editutil.BasicHandler(tty.KeyEvent(st.BindingKey()), st)

View File

@ -36,7 +36,7 @@ func TestInitInsert_Binding(t *testing.T) {
m, ns := initInsert(&fakeEditor{}, eval.NewEvaler())
called := 0
binding, err := EmptyBindingMap.Assoc("a",
eval.NewBuiltinFn("test binding", func() { called++ }))
eval.NewGoFn("test binding", func() { called++ }))
if err != nil {
panic(err)
}

View File

@ -16,7 +16,7 @@ func initLastcmd(ed editor, ev *eval.Evaler, st storedefs.Store, lsMode *listing
KeyHandler: keyHandlerFromBindings(ed, ev, &binding, lsBinding),
}
ns := eval.Ns{}.
AddBuiltinFn("<edit:lastcmd>:", "start", func() {
AddGoFn("<edit:lastcmd>:", "start", func() {
startLastcmd(ed, st, &mode)
})
return ns

View File

@ -11,7 +11,7 @@ func initListing(ed editor) (*listing.Mode, *BindingMap, eval.Ns) {
binding := EmptyBindingMap
ns := eval.Ns{
"binding": vars.FromPtr(&binding),
}.AddBuiltinFns("<edit:listing>:", map[string]interface{}{
}.AddGoFns("<edit:listing>:", map[string]interface{}{
"up": func() { mode.MutateStates((*listing.State).Up) },
"down": func() { mode.MutateStates((*listing.State).Down) },
"up-cycle": func() { mode.MutateStates((*listing.State).UpCycle) },

View File

@ -49,7 +49,7 @@ func getDefaultPrompt(isRoot bool) eval.Callable {
if isRoot {
p = styled.Transform(styled.Unstyled("# "), "red")
}
return eval.NewBuiltinFn("default prompt", func(fm *eval.Frame) {
return eval.NewGoFn("default prompt", func(fm *eval.Frame) {
out := fm.OutputChan()
out <- string(util.Getwd())
out <- p
@ -58,7 +58,7 @@ func getDefaultPrompt(isRoot bool) eval.Callable {
func getDefaultRPrompt(username, hostname string) eval.Callable {
rp := styled.Transform(styled.Unstyled(username+"@"+hostname), "inverse")
return eval.NewBuiltinFn("default rprompt", func(fm *eval.Frame) {
return eval.NewGoFn("default rprompt", func(fm *eval.Frame) {
fm.OutputChan() <- rp
})
}