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
/*
luacmdArgs := l.NewTable()
for _, str := range args[1:] {
luacmdArgs.Append(lua.LString(str))
luacmdArgs := rt.NewTable()
for i, str := range args[1:] {
luacmdArgs.Set(rt.IntValue(int64(i + 1)), rt.StringValue(str))
}
if commands[args[0]] != nil {
err := l.CallByParam(lua.P{
Fn: commands[args[0]],
NRet: 1,
Protect: true,
}, luacmdArgs)
luaexitcode, err := rt.Call1(l.MainThread(), rt.FunctionValue(commands[args[0]]), rt.TableValue(luacmdArgs))
if err != nil {
fmt.Fprintln(os.Stderr,
"Error in command:\n\n" + err.Error())
return interp.NewExitStatus(1)
}
luaexitcode := l.Get(-1)
var exitcode uint8
l.Pop(1)
if code, ok := luaexitcode.(lua.LNumber); luaexitcode != lua.LNil && ok {
if code, ok := luaexitcode.TryInt(); ok {
exitcode = uint8(code)
}
} // TODO: deregister commander if return isnt number
return interp.NewExitStatus(exitcode)
}
*/
err := lookpath(args[0])
if err == errNotExec {
@ -447,6 +437,8 @@ func cmdFinish(code uint8, cmdstr string, private bool) {
handleHistory(cmdstr)
}
// 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)
}

View File

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

8
lua.go
View File

@ -6,8 +6,8 @@ import (
"hilbish/util"
"hilbish/golibs/bait"
/*
"hilbish/golibs/commander"
/*
"hilbish/golibs/fs"
"hilbish/golibs/terminal"
*/
@ -28,17 +28,17 @@ func luaInit() {
// Add fs and terminal module module to Lua
/* l.PreloadModule("fs", fs.Loader)
l.PreloadModule("terminal", terminal.Loader)
*/
cmds := commander.New()
// 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
})
cmds.Events.On("commandDeregister", func(cmdName string) {
delete(commands, cmdName)
})
l.PreloadModule("commander", cmds.Loader)
*/
lib.LoadLibs(l, cmds.Loader)
hooks = bait.New()
lib.LoadLibs(l, hooks.Loader)

View File

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