feat: implement commander

lua5.4
TorchedSammy 2022-03-28 19:12:58 -04:00
parent e466085d24
commit b887ad4fa9
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
4 changed files with 47 additions and 39 deletions

26
exec.go
View File

@ -183,37 +183,27 @@ func execCommand(cmd string) error {
} }
// If command is defined in Lua then run it // If command is defined in Lua then run it
/* luacmdArgs := rt.NewTable()
luacmdArgs := l.NewTable() for i, str := range args[1:] {
for _, str := range args[1:] { luacmdArgs.Set(rt.IntValue(int64(i + 1)), rt.StringValue(str))
luacmdArgs.Append(lua.LString(str))
} }
if commands[args[0]] != nil { if commands[args[0]] != nil {
err := l.CallByParam(lua.P{ luaexitcode, err := rt.Call1(l.MainThread(), rt.FunctionValue(commands[args[0]]), rt.TableValue(luacmdArgs))
Fn: commands[args[0]],
NRet: 1,
Protect: true,
}, luacmdArgs)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, fmt.Fprintln(os.Stderr,
"Error in command:\n\n" + err.Error()) "Error in command:\n\n" + err.Error())
return interp.NewExitStatus(1) return interp.NewExitStatus(1)
} }
luaexitcode := l.Get(-1)
var exitcode uint8 var exitcode uint8
l.Pop(1) if code, ok := luaexitcode.TryInt(); ok {
if code, ok := luaexitcode.(lua.LNumber); luaexitcode != lua.LNil && ok {
exitcode = uint8(code) exitcode = uint8(code)
} } // TODO: deregister commander if return isnt number
return interp.NewExitStatus(exitcode) return interp.NewExitStatus(exitcode)
} }
*/
err := lookpath(args[0]) err := lookpath(args[0])
if err == errNotExec { if err == errNotExec {
@ -447,6 +437,8 @@ func cmdFinish(code uint8, cmdstr string, private bool) {
handleHistory(cmdstr) handleHistory(cmdstr)
} }
// util.SetField(l, hshMod, "exitCode", lua.LNumber(code), "Exit code of last exected command") // util.SetField(l, hshMod, "exitCode", lua.LNumber(code), "Exit code of last exected command")
// using AsValue on an interface which is an int results in it being unknown .... ???? // using AsValue (to convert to lua type) on an interface which is an int
// results in it being unknown in lua .... ????
// so we allow the hook handler to take lua runtime Values
hooks.Em.Emit("command.exit", rt.IntValue(int64(code)), cmdstr) hooks.Em.Emit("command.exit", rt.IntValue(int64(code)), cmdstr)
} }

View File

@ -3,52 +3,68 @@ package commander
import ( import (
"hilbish/util" "hilbish/util"
rt "github.com/arnodel/golua/runtime"
"github.com/arnodel/golua/lib/packagelib"
"github.com/chuckpreslar/emission" "github.com/chuckpreslar/emission"
"github.com/yuin/gopher-lua"
) )
type Commander struct{ type Commander struct{
Events *emission.Emitter Events *emission.Emitter
Loader packagelib.Loader
} }
func New() Commander { func New() Commander {
return Commander{ c := Commander{
Events: emission.NewEmitter(), Events: emission.NewEmitter(),
} }
c.Loader = packagelib.Loader{
Load: c.LoaderFunc,
Name: "commander",
}
return c
} }
func (c *Commander) Loader(L *lua.LState) int { func (c *Commander) LoaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
exports := map[string]lua.LGFunction{ exports := map[string]util.LuaExport{
"register": c.cregister, "register": util.LuaExport{c.cregister, 2, false},
"deregister": c.cderegister, "deregister": util.LuaExport{c.cderegister, 1, false},
} }
mod := L.SetFuncs(L.NewTable(), exports) mod := rt.NewTable()
util.Document(L, mod, "Commander is Hilbish's custom command library, a way to write commands in Lua.") util.SetExports(rtm, mod, exports)
L.Push(mod) // util.Document(L, mod, "Commander is Hilbish's custom command library, a way to write commands in Lua.")
return 1 return rt.TableValue(mod), nil
} }
// register(name, cb) // register(name, cb)
// Register a command with `name` that runs `cb` when ran // Register a command with `name` that runs `cb` when ran
// --- @param name string // --- @param name string
// --- @param cb function // --- @param cb function
func (c *Commander) cregister(L *lua.LState) int { func (c *Commander) cregister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
cmdName := L.CheckString(1) cmdName, cmd, err := util.HandleStrCallback(t, ct)
cmd := L.CheckFunction(2) if err != nil {
return nil, err
}
c.Events.Emit("commandRegister", cmdName, cmd) c.Events.Emit("commandRegister", cmdName, cmd)
return 0 return ct.Next(), err
} }
// deregister(name) // deregister(name)
// Deregisters any command registered with `name` // Deregisters any command registered with `name`
// --- @param name string // --- @param name string
func (c *Commander) cderegister(L *lua.LState) int { func (c *Commander) cderegister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
cmdName := L.CheckString(1) if err := ct.Check1Arg(); err != nil {
return nil, err
}
cmdName, err := ct.StringArg(0)
if err != nil {
return nil, err
}
c.Events.Emit("commandDeregister", cmdName) c.Events.Emit("commandDeregister", cmdName)
return 0 return ct.Next(), err
} }

8
lua.go
View File

@ -6,8 +6,8 @@ import (
"hilbish/util" "hilbish/util"
"hilbish/golibs/bait" "hilbish/golibs/bait"
/*
"hilbish/golibs/commander" "hilbish/golibs/commander"
/*
"hilbish/golibs/fs" "hilbish/golibs/fs"
"hilbish/golibs/terminal" "hilbish/golibs/terminal"
*/ */
@ -28,17 +28,17 @@ func luaInit() {
// Add fs and terminal module module to Lua // Add fs and terminal module module to Lua
/* l.PreloadModule("fs", fs.Loader) /* l.PreloadModule("fs", fs.Loader)
l.PreloadModule("terminal", terminal.Loader) l.PreloadModule("terminal", terminal.Loader)
*/
cmds := commander.New() cmds := commander.New()
// When a command from Lua is added, register it for use // When a command from Lua is added, register it for use
cmds.Events.On("commandRegister", func(cmdName string, cmd *lua.LFunction) { cmds.Events.On("commandRegister", func(cmdName string, cmd *rt.Closure) {
commands[cmdName] = cmd commands[cmdName] = cmd
}) })
cmds.Events.On("commandDeregister", func(cmdName string) { cmds.Events.On("commandDeregister", func(cmdName string) {
delete(commands, cmdName) delete(commands, cmdName)
}) })
l.PreloadModule("commander", cmds.Loader) lib.LoadLibs(l, cmds.Loader)
*/
hooks = bait.New() hooks = bait.New()
lib.LoadLibs(l, hooks.Loader) lib.LoadLibs(l, hooks.Loader)

View File

@ -23,7 +23,7 @@ var (
l *rt.Runtime l *rt.Runtime
lr *lineReader lr *lineReader
commands = map[string]*lua.LFunction{} commands = map[string]*rt.Closure{}
luaCompletions = map[string]*lua.LFunction{} luaCompletions = map[string]*lua.LFunction{}
confDir string confDir string