diff --git a/api.go b/api.go index 6f8f517..43e361a 100644 --- a/api.go +++ b/api.go @@ -701,7 +701,7 @@ func hlwhich(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { cmd := strings.Split(alias, " ")[0] // check for commander - if commands[cmd] != nil { + if cmds.Commands[cmd] != nil { // they dont resolve to a path, so just send the cmd return c.PushingNext1(t.Runtime, rt.StringValue(cmd)), nil } diff --git a/complete.go b/complete.go index 71d92fb..1c40b20 100644 --- a/complete.go +++ b/complete.go @@ -128,7 +128,7 @@ func binaryComplete(query, ctx string, fields []string) ([]string, string) { } // add lua registered commands to completions - for cmdName := range commands { + for cmdName := range cmds.Commands { if strings.HasPrefix(cmdName, query) { completions = append(completions, cmdName) } diff --git a/exec.go b/exec.go index 355fa3d..cf1b299 100644 --- a/exec.go +++ b/exec.go @@ -342,7 +342,7 @@ func execHandle(bg bool) interp.ExecHandlerFunc { } hc := interp.HandlerCtx(ctx) - if commands[args[0]] != nil { + if cmd := cmds.Commands[args[0]]; cmd != nil { stdin := newSinkInput(hc.Stdin) stdout := newSinkOutput(hc.Stdout) stderr := newSinkOutput(hc.Stderr) @@ -353,7 +353,7 @@ func execHandle(bg bool) interp.ExecHandlerFunc { sinks.Set(rt.StringValue("out"), rt.UserDataValue(stdout.ud)) sinks.Set(rt.StringValue("err"), rt.UserDataValue(stderr.ud)) - luaexitcode, err := rt.Call1(l.MainThread(), rt.FunctionValue(commands[args[0]]), rt.TableValue(luacmdArgs), rt.TableValue(sinks)) + luaexitcode, err := rt.Call1(l.MainThread(), rt.FunctionValue(cmd), rt.TableValue(luacmdArgs), rt.TableValue(sinks)) if err != nil { fmt.Fprintln(os.Stderr, "Error in command:\n" + err.Error()) return interp.NewExitStatus(1) @@ -365,7 +365,7 @@ func execHandle(bg bool) interp.ExecHandlerFunc { exitcode = uint8(code) } else if luaexitcode != rt.NilValue { // deregister commander - delete(commands, args[0]) + delete(cmds.Commands, args[0]) fmt.Fprintf(os.Stderr, "Commander did not return number for exit code. %s, you're fired.\n", args[0]) } diff --git a/golibs/commander/commander.go b/golibs/commander/commander.go index f4d588d..840aaa1 100644 --- a/golibs/commander/commander.go +++ b/golibs/commander/commander.go @@ -43,11 +43,13 @@ import ( type Commander struct{ Events *bait.Bait Loader packagelib.Loader + Commands map[string]*rt.Closure } -func New(rtm *rt.Runtime) Commander { - c := Commander{ +func New(rtm *rt.Runtime) *Commander { + c := &Commander{ Events: bait.New(rtm), + Commands: make(map[string]*rt.Closure), } c.Loader = packagelib.Loader{ Load: c.loaderFunc, @@ -61,6 +63,7 @@ func (c *Commander) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) { exports := map[string]util.LuaExport{ "register": util.LuaExport{c.cregister, 2, false}, "deregister": util.LuaExport{c.cderegister, 1, false}, + "registry": util.LuaExport{c.cregistry, 0, false}, } mod := rt.NewTable() util.SetExports(rtm, mod, exports) @@ -91,7 +94,7 @@ func (c *Commander) cregister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) { return nil, err } - c.Events.Emit("commandRegister", cmdName, cmd) + c.Commands[cmdName] = cmd return ct.Next(), err } @@ -108,7 +111,23 @@ func (c *Commander) cderegister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) { return nil, err } - c.Events.Emit("commandDeregister", cmdName) + delete(c.Commands, cmdName) return ct.Next(), err } + +// registry() -> table +// Returns all registered commanders. Returns a list of tables with the following keys: +// - `exec`: The function used to run the commander. Commanders require args and sinks to be passed. +// #returns table +func (c *Commander) cregistry(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) { + registryLua := rt.NewTable() + for cmdName, cmd := range c.Commands { + cmdTbl := rt.NewTable() + cmdTbl.Set(rt.StringValue("exec"), rt.FunctionValue(cmd)) + + registryLua.Set(rt.StringValue(cmdName), rt.TableValue(cmdTbl)) + } + + return ct.PushingNext1(t.Runtime, rt.TableValue(registryLua)), nil +} diff --git a/lua.go b/lua.go index e46d27b..94b7910 100644 --- a/lua.go +++ b/lua.go @@ -33,19 +33,7 @@ func luaInit() { lib.LoadLibs(l, fs.Loader) lib.LoadLibs(l, terminal.Loader) - cmds := commander.New(l) - // When a command from Lua is added, register it for use - cmds.Events.On("commandRegister", func(args ...interface{}) { - cmdName := args[0].(string) - cmd := args[1].(*rt.Closure) - - commands[cmdName] = cmd - }) - cmds.Events.On("commandDeregister", func(args ...interface{}) { - cmdName := args[0].(string) - - delete(commands, cmdName) - }) + cmds = commander.New(l) lib.LoadLibs(l, cmds.Loader) hooks = bait.New(l) diff --git a/main.go b/main.go index 4b756c0..4bdfdac 100644 --- a/main.go +++ b/main.go @@ -14,6 +14,7 @@ import ( "hilbish/util" "hilbish/golibs/bait" + "hilbish/golibs/commander" rt "github.com/arnodel/golua/runtime" "github.com/pborman/getopt" @@ -25,7 +26,6 @@ var ( l *rt.Runtime lr *lineReader - commands = map[string]*rt.Closure{} luaCompletions = map[string]*rt.Closure{} confDir string @@ -33,6 +33,7 @@ var ( curuser *user.User hooks *bait.Bait + cmds *commander.Commander defaultConfPath string defaultHistPath string )