mirror of https://github.com/Hilbis/Hilbish
feat: add moonlight lua abstraction library
future plans: add the ability to use c lua (or luajit) with hilbish benefits? speed, i guess?pull/314/merge^2
parent
bfa3b55542
commit
4524c1451a
|
@ -97,7 +97,7 @@ func (a *aliasModule) Resolve(cmdstr string) string {
|
|||
func (a *aliasModule) Loader(rtm *rt.Runtime) *rt.Table {
|
||||
// create a lua module with our functions
|
||||
hshaliasesLua := map[string]util.LuaExport{
|
||||
"add": util.LuaExport{hlalias, 2, false},
|
||||
//"add": util.LuaExport{hlalias, 2, false},
|
||||
"list": util.LuaExport{a.luaList, 0, false},
|
||||
"del": util.LuaExport{a.luaDelete, 1, false},
|
||||
"resolve": util.LuaExport{a.luaResolve, 1, false},
|
||||
|
|
176
api.go
176
api.go
|
@ -15,56 +15,52 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
//"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
//"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
//"syscall"
|
||||
//"time"
|
||||
|
||||
"hilbish/util"
|
||||
//"hilbish/util"
|
||||
"hilbish/moonlight"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/arnodel/golua/lib/packagelib"
|
||||
//"github.com/arnodel/golua/lib/packagelib"
|
||||
"github.com/arnodel/golua/lib/iolib"
|
||||
"github.com/maxlandon/readline"
|
||||
"mvdan.cc/sh/v3/interp"
|
||||
)
|
||||
|
||||
var exports = map[string]util.LuaExport{
|
||||
"alias": {hlalias, 2, false},
|
||||
"appendPath": {hlappendPath, 1, false},
|
||||
"complete": {hlcomplete, 2, false},
|
||||
"cwd": {hlcwd, 0, false},
|
||||
"exec": {hlexec, 1, false},
|
||||
"runnerMode": {hlrunnerMode, 1, false},
|
||||
"goro": {hlgoro, 1, true},
|
||||
"highlighter": {hlhighlighter, 1, false},
|
||||
"hinter": {hlhinter, 1, false},
|
||||
"multiprompt": {hlmultiprompt, 1, false},
|
||||
"prependPath": {hlprependPath, 1, false},
|
||||
"prompt": {hlprompt, 1, true},
|
||||
"inputMode": {hlinputMode, 1, false},
|
||||
"interval": {hlinterval, 2, false},
|
||||
"read": {hlread, 1, false},
|
||||
"run": {hlrun, 1, true},
|
||||
"timeout": {hltimeout, 2, false},
|
||||
"which": {hlwhich, 1, false},
|
||||
}
|
||||
var hshMod *moonlight.Table
|
||||
|
||||
var hshMod *rt.Table
|
||||
var hilbishLoader = packagelib.Loader{
|
||||
Load: hilbishLoad,
|
||||
Name: "hilbish",
|
||||
}
|
||||
|
||||
func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) {
|
||||
mod := rt.NewTable()
|
||||
|
||||
util.SetExports(rtm, mod, exports)
|
||||
hshMod = mod
|
||||
func hilbishLoader(mlr *moonlight.Runtime) moonlight.Value {
|
||||
var exports = map[string]moonlight.Export{
|
||||
"alias": {hlalias, 2, false},
|
||||
/*
|
||||
"appendPath": {hlappendPath, 1, false},
|
||||
"complete": {hlcomplete, 2, false},
|
||||
"cwd": {hlcwd, 0, false},
|
||||
"exec": {hlexec, 1, false},
|
||||
"runnerMode": {hlrunnerMode, 1, false},
|
||||
"goro": {hlgoro, 1, true},
|
||||
"highlighter": {hlhighlighter, 1, false},
|
||||
"hinter": {hlhinter, 1, false},
|
||||
"multiprompt": {hlmultiprompt, 1, false},
|
||||
"prependPath": {hlprependPath, 1, false},
|
||||
"prompt": {hlprompt, 1, true},
|
||||
"inputMode": {hlinputMode, 1, false},
|
||||
"interval": {hlinterval, 2, false},
|
||||
"read": {hlread, 1, false},
|
||||
"run": {hlrun, 1, true},
|
||||
"timeout": {hltimeout, 2, false},
|
||||
"which": {hlwhich, 1, false},
|
||||
*/
|
||||
}
|
||||
hshMod = moonlight.NewTable()
|
||||
mlr.SetExports(hshMod, exports)
|
||||
|
||||
host, _ := os.Hostname()
|
||||
username := curuser.Username
|
||||
|
@ -73,68 +69,68 @@ func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) {
|
|||
username = strings.Split(username, "\\")[1] // for some reason Username includes the hostname on windows
|
||||
}
|
||||
|
||||
util.SetField(rtm, mod, "ver", rt.StringValue(getVersion()))
|
||||
util.SetField(rtm, mod, "goVersion", rt.StringValue(runtime.Version()))
|
||||
util.SetField(rtm, mod, "user", rt.StringValue(username))
|
||||
util.SetField(rtm, mod, "host", rt.StringValue(host))
|
||||
util.SetField(rtm, mod, "home", rt.StringValue(curuser.HomeDir))
|
||||
util.SetField(rtm, mod, "dataDir", rt.StringValue(dataDir))
|
||||
util.SetField(rtm, mod, "interactive", rt.BoolValue(interactive))
|
||||
util.SetField(rtm, mod, "login", rt.BoolValue(login))
|
||||
util.SetField(rtm, mod, "vimMode", rt.NilValue)
|
||||
util.SetField(rtm, mod, "exitCode", rt.IntValue(0))
|
||||
hshMod.SetField("ver", moonlight.StringValue(getVersion()))
|
||||
hshMod.SetField("goVersion", moonlight.StringValue(runtime.Version()))
|
||||
hshMod.SetField("user", moonlight.StringValue(username))
|
||||
hshMod.SetField("host", moonlight.StringValue(host))
|
||||
hshMod.SetField("home", moonlight.StringValue(curuser.HomeDir))
|
||||
hshMod.SetField("dataDir", moonlight.StringValue(dataDir))
|
||||
hshMod.SetField("interactive", moonlight.BoolValue(interactive))
|
||||
hshMod.SetField("login", moonlight.BoolValue(login))
|
||||
hshMod.SetField("exitCode", moonlight.IntValue(0))
|
||||
//util.SetField(rtm, mod, "vimMode", rt.NilValue)
|
||||
|
||||
// hilbish.userDir table
|
||||
hshuser := userDirLoader(rtm)
|
||||
mod.Set(rt.StringValue("userDir"), rt.TableValue(hshuser))
|
||||
//hshuser := userDirLoader(rtm)
|
||||
//mod.Set(rt.StringValue("userDir"), rt.TableValue(hshuser))
|
||||
|
||||
// hilbish.os table
|
||||
hshos := hshosLoader(rtm)
|
||||
mod.Set(rt.StringValue("os"), rt.TableValue(hshos))
|
||||
//hshos := hshosLoader(rtm)
|
||||
//mod.Set(rt.StringValue("os"), rt.TableValue(hshos))
|
||||
|
||||
// hilbish.aliases table
|
||||
aliases = newAliases()
|
||||
aliasesModule := aliases.Loader(rtm)
|
||||
mod.Set(rt.StringValue("aliases"), rt.TableValue(aliasesModule))
|
||||
//aliases = newAliases()
|
||||
//aliasesModule := aliases.Loader(rtm)
|
||||
//mod.Set(rt.StringValue("aliases"), rt.TableValue(aliasesModule))
|
||||
|
||||
// hilbish.history table
|
||||
historyModule := lr.Loader(rtm)
|
||||
mod.Set(rt.StringValue("history"), rt.TableValue(historyModule))
|
||||
//historyModule := lr.Loader(rtm)
|
||||
//mod.Set(rt.StringValue("history"), rt.TableValue(historyModule))
|
||||
|
||||
// hilbish.completion table
|
||||
hshcomp := completionLoader(rtm)
|
||||
//hshcomp := completionLoader(rtm)
|
||||
// TODO: REMOVE "completion" AND ONLY USE "completions" WITH AN S
|
||||
mod.Set(rt.StringValue("completion"), rt.TableValue(hshcomp))
|
||||
mod.Set(rt.StringValue("completions"), rt.TableValue(hshcomp))
|
||||
//mod.Set(rt.StringValue("completion"), rt.TableValue(hshcomp))
|
||||
//mod.Set(rt.StringValue("completions"), rt.TableValue(hshcomp))
|
||||
|
||||
// hilbish.runner table
|
||||
runnerModule := runnerModeLoader(rtm)
|
||||
mod.Set(rt.StringValue("runner"), rt.TableValue(runnerModule))
|
||||
//runnerModule := runnerModeLoader(rtm)
|
||||
//mod.Set(rt.StringValue("runner"), rt.TableValue(runnerModule))
|
||||
|
||||
// hilbish.jobs table
|
||||
jobs = newJobHandler()
|
||||
jobModule := jobs.loader(rtm)
|
||||
mod.Set(rt.StringValue("jobs"), rt.TableValue(jobModule))
|
||||
//jobs = newJobHandler()
|
||||
//jobModule := jobs.loader(rtm)
|
||||
//mod.Set(rt.StringValue("jobs"), rt.TableValue(jobModule))
|
||||
|
||||
// hilbish.timers table
|
||||
timers = newTimersModule()
|
||||
timersModule := timers.loader(rtm)
|
||||
mod.Set(rt.StringValue("timers"), rt.TableValue(timersModule))
|
||||
//timers = newTimersModule()
|
||||
//timersModule := timers.loader(rtm)
|
||||
//mod.Set(rt.StringValue("timers"), rt.TableValue(timersModule))
|
||||
|
||||
editorModule := editorLoader(rtm)
|
||||
mod.Set(rt.StringValue("editor"), rt.TableValue(editorModule))
|
||||
//editorModule := editorLoader(rtm)
|
||||
//mod.Set(rt.StringValue("editor"), rt.TableValue(editorModule))
|
||||
|
||||
versionModule := rt.NewTable()
|
||||
util.SetField(rtm, versionModule, "branch", rt.StringValue(gitBranch))
|
||||
util.SetField(rtm, versionModule, "full", rt.StringValue(getVersion()))
|
||||
util.SetField(rtm, versionModule, "commit", rt.StringValue(gitCommit))
|
||||
util.SetField(rtm, versionModule, "release", rt.StringValue(releaseName))
|
||||
mod.Set(rt.StringValue("version"), rt.TableValue(versionModule))
|
||||
//versionModule := rt.NewTable()
|
||||
//util.SetField(rtm, versionModule, "branch", rt.StringValue(gitBranch))
|
||||
//util.SetField(rtm, versionModule, "full", rt.StringValue(getVersion()))
|
||||
//util.SetField(rtm, versionModule, "commit", rt.StringValue(gitCommit))
|
||||
//util.SetField(rtm, versionModule, "release", rt.StringValue(releaseName))
|
||||
//mod.Set(rt.StringValue("version"), rt.TableValue(versionModule))
|
||||
|
||||
pluginModule := moduleLoader(rtm)
|
||||
mod.Set(rt.StringValue("module"), rt.TableValue(pluginModule))
|
||||
//pluginModule := moduleLoader(rtm)
|
||||
//mod.Set(rt.StringValue("module"), rt.TableValue(pluginModule))
|
||||
|
||||
return rt.TableValue(mod), nil
|
||||
return moonlight.TableValue(hshMod)
|
||||
}
|
||||
|
||||
func getenv(key, fallback string) string {
|
||||
|
@ -146,12 +142,12 @@ func getenv(key, fallback string) string {
|
|||
}
|
||||
|
||||
func setVimMode(mode string) {
|
||||
util.SetField(l, hshMod, "vimMode", rt.StringValue(mode))
|
||||
hshMod.SetField("vimMode", rt.StringValue(mode))
|
||||
hooks.Emit("hilbish.vimMode", mode)
|
||||
}
|
||||
|
||||
func unsetVimMode() {
|
||||
util.SetField(l, hshMod, "vimMode", rt.NilValue)
|
||||
hshMod.SetField("vimMode", rt.NilValue)
|
||||
}
|
||||
|
||||
func handleStream(v rt.Value, strms *streams, errStream bool) error {
|
||||
|
@ -429,15 +425,17 @@ hilbish.alias('dircount', 'ls %1 | wc -l')
|
|||
-- "dircount ~" would count how many files are in ~ (home directory).
|
||||
#example
|
||||
*/
|
||||
func hlalias(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.CheckNArgs(2); err != nil {
|
||||
//func hlalias(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
func hlalias(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||
if err := mlr.CheckNArgs(c, 2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd, err := c.StringArg(0)
|
||||
|
||||
cmd, err := mlr.StringArg(c, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orig, err := c.StringArg(1)
|
||||
orig, err := mlr.StringArg(c, 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -461,7 +459,6 @@ hilbish.appendPath {
|
|||
'~/.local/bin'
|
||||
}
|
||||
#example
|
||||
*/
|
||||
func hlappendPath(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
return nil, err
|
||||
|
@ -529,7 +526,9 @@ func hlexec(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.Next(), nil
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// goro(fn)
|
||||
// Puts `fn` in a Goroutine.
|
||||
// This can be used to run any function in another thread at the same time as other Lua code.
|
||||
|
@ -613,6 +612,7 @@ func hlinterval(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.PushingNext1(t.Runtime, rt.UserDataValue(timer.ud)), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// complete(scope, cb)
|
||||
// Registers a completion handler for the specified scope.
|
||||
|
@ -648,7 +648,6 @@ hilbish.complete('command.sudo', function(query, ctx, fields)
|
|||
return {compGroup}, pfx
|
||||
end)
|
||||
#example
|
||||
*/
|
||||
func hlcomplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
scope, cb, err := util.HandleStrCallback(t, c)
|
||||
if err != nil {
|
||||
|
@ -658,7 +657,9 @@ func hlcomplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.Next(), nil
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// prependPath(dir)
|
||||
// Prepends `dir` to $PATH.
|
||||
// #param dir string
|
||||
|
@ -769,6 +770,7 @@ func hlrunnerMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.Next(), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// hinter(line, pos)
|
||||
// The command line hint handler. It gets called on every key insert to
|
||||
|
@ -786,6 +788,7 @@ function hilbish.hinter(line, pos)
|
|||
end
|
||||
#example
|
||||
*/
|
||||
/*
|
||||
func hlhinter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
return c.Next(), nil
|
||||
}
|
||||
|
@ -815,3 +818,4 @@ func hlhighlighter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.PushingNext1(t.Runtime, rt.StringValue(line)), nil
|
||||
}
|
||||
*/
|
||||
|
|
27
complete.go
27
complete.go
|
@ -1,14 +1,14 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
//"errors"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"os"
|
||||
|
||||
"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
//rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
var charEscapeMap = []string{
|
||||
|
@ -191,6 +191,7 @@ func escapeFilename(fname string) string {
|
|||
// #interface completion
|
||||
// tab completions
|
||||
// The completions interface deals with tab completions.
|
||||
/*
|
||||
func completionLoader(rtm *rt.Runtime) *rt.Table {
|
||||
exports := map[string]util.LuaExport{
|
||||
"bins": {hcmpBins, 3, false},
|
||||
|
@ -204,6 +205,7 @@ func completionLoader(rtm *rt.Runtime) *rt.Table {
|
|||
|
||||
return mod
|
||||
}
|
||||
*/
|
||||
|
||||
// #interface completion
|
||||
// bins(query, ctx, fields) -> entries (table), prefix (string)
|
||||
|
@ -231,6 +233,7 @@ hilbish.complete('command.sudo', function(query, ctx, fields)
|
|||
end)
|
||||
#example
|
||||
*/
|
||||
/*
|
||||
func hcmpBins(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
query, ctx, fds, err := getCompleteParams(t, c)
|
||||
if err != nil {
|
||||
|
@ -246,6 +249,7 @@ func hcmpBins(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.PushingNext(t.Runtime, rt.TableValue(luaComps), rt.StringValue(pfx)), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// #interface completion
|
||||
// call(name, query, ctx, fields) -> completionGroups (table), prefix (string)
|
||||
|
@ -256,6 +260,7 @@ func hcmpBins(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
// #param query string
|
||||
// #param ctx string
|
||||
// #param fields table
|
||||
/*
|
||||
func hcmpCall(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.CheckNArgs(4); err != nil {
|
||||
return nil, err
|
||||
|
@ -283,11 +288,15 @@ func hcmpCall(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
return nil, errors.New("completer " + completer + " does not exist")
|
||||
}
|
||||
|
||||
// we must keep the holy 80 cols
|
||||
cont := c.Next()
|
||||
err = rt.Call(l.MainThread(), rt.FunctionValue(completecb),
|
||||
[]rt.Value{rt.StringValue(query), rt.StringValue(ctx), rt.TableValue(fields)},
|
||||
cont)
|
||||
err = l.Call(moonlight.FunctionValue(completecb), []moonlight.Value{
|
||||
moonlight.StringValue(query),
|
||||
moonlight.StringValue(ctx),
|
||||
moonlight.TableValue(fields)
|
||||
}, cont)
|
||||
err = rt.Call(l.MainThread(), rt.FunctionValue(completecb), []rt.Value{
|
||||
rt.StringValue(query), rt.StringValue(ctx), rt.TableValue(fields)
|
||||
}, cont)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -295,6 +304,7 @@ func hcmpCall(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return cont, nil
|
||||
}
|
||||
*/
|
||||
|
||||
// #interface completion
|
||||
// files(query, ctx, fields) -> entries (table), prefix (string)
|
||||
|
@ -303,6 +313,7 @@ func hcmpCall(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
// #param query string
|
||||
// #param ctx string
|
||||
// #param fields table
|
||||
/*
|
||||
func hcmpFiles(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
query, ctx, fds, err := getCompleteParams(t, c)
|
||||
if err != nil {
|
||||
|
@ -318,6 +329,7 @@ func hcmpFiles(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
|
||||
return c.PushingNext(t.Runtime, rt.TableValue(luaComps), rt.StringValue(pfx)), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// #interface completion
|
||||
// handler(line, pos)
|
||||
|
@ -340,11 +352,11 @@ function hilbish.completion.handler(line, pos)
|
|||
end
|
||||
#example
|
||||
*/
|
||||
/*
|
||||
func hcmpHandler(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
return c.Next(), nil
|
||||
}
|
||||
|
||||
|
||||
func getCompleteParams(t *rt.Thread, c *rt.GoCont) (string, string, []string, error) {
|
||||
if err := c.CheckNArgs(3); err != nil {
|
||||
return "", "", []string{}, err
|
||||
|
@ -371,3 +383,4 @@ func getCompleteParams(t *rt.Thread, c *rt.GoCont) (string, string, []string, er
|
|||
|
||||
return query, ctx, fds, err
|
||||
}
|
||||
*/
|
||||
|
|
16
exec.go
16
exec.go
|
@ -14,7 +14,8 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
"hilbish/util"
|
||||
"hilbish/moonlight"
|
||||
//"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"mvdan.cc/sh/v3/shell"
|
||||
|
@ -170,15 +171,13 @@ func reprompt(input string) (string, error) {
|
|||
}
|
||||
|
||||
func runLuaRunner(runr rt.Value, userInput string) (input string, exitCode uint8, continued bool, runnerErr, err error) {
|
||||
term := rt.NewTerminationWith(l.MainThread().CurrentCont(), 3, false)
|
||||
err = rt.Call(l.MainThread(), runr, []rt.Value{rt.StringValue(userInput)}, term)
|
||||
runnerRet, err := l.Call1(runr, moonlight.StringValue(userInput))
|
||||
if err != nil {
|
||||
return "", 124, false, nil, err
|
||||
}
|
||||
|
||||
var runner *rt.Table
|
||||
var ok bool
|
||||
runnerRet := term.Get(0)
|
||||
if runner, ok = runnerRet.TryTable(); !ok {
|
||||
fmt.Fprintln(os.Stderr, "runner did not return a table")
|
||||
exitCode = 125
|
||||
|
@ -207,7 +206,8 @@ func runLuaRunner(runr rt.Value, userInput string) (input string, exitCode uint8
|
|||
func handleLua(input string) (string, uint8, error) {
|
||||
cmdString := aliases.Resolve(input)
|
||||
// First try to load input, essentially compiling to bytecode
|
||||
chunk, err := l.CompileAndLoadLuaChunk("", []byte(cmdString), rt.TableValue(l.GlobalEnv()))
|
||||
rtm := l.UnderlyingRuntime()
|
||||
chunk, err := rtm.CompileAndLoadLuaChunk("", []byte(cmdString), moonlight.TableValue(l.GlobalTable()))
|
||||
if err != nil && noexecute {
|
||||
fmt.Println(err)
|
||||
/* if lerr, ok := err.(*lua.ApiError); ok {
|
||||
|
@ -221,7 +221,7 @@ func handleLua(input string) (string, uint8, error) {
|
|||
// And if there's no syntax errors and -n isnt provided, run
|
||||
if !noexecute {
|
||||
if chunk != nil {
|
||||
_, err = rt.Call1(l.MainThread(), rt.FunctionValue(chunk))
|
||||
_, err = l.Call1(rt.FunctionValue(chunk))
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
|
@ -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(cmd), rt.TableValue(luacmdArgs), rt.TableValue(sinks))
|
||||
luaexitcode, err := l.Call1(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)
|
||||
|
@ -580,7 +580,7 @@ func splitInput(input string) ([]string, string) {
|
|||
}
|
||||
|
||||
func cmdFinish(code uint8, cmdstr string, private bool) {
|
||||
util.SetField(l, hshMod, "exitCode", rt.IntValue(int64(code)))
|
||||
hshMod.SetField("exitCode", rt.IntValue(int64(code)))
|
||||
// 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
|
||||
|
|
|
@ -14,7 +14,7 @@ type luaHistory struct {}
|
|||
|
||||
func (h *luaHistory) Write(line string) (int, error) {
|
||||
histWrite := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("add"))
|
||||
ln, err := rt.Call1(l.MainThread(), histWrite, rt.StringValue(line))
|
||||
ln, err := l.Call1(histWrite, rt.StringValue(line))
|
||||
|
||||
var num int64
|
||||
if ln.Type() == rt.IntType {
|
||||
|
@ -26,7 +26,7 @@ func (h *luaHistory) Write(line string) (int, error) {
|
|||
|
||||
func (h *luaHistory) GetLine(idx int) (string, error) {
|
||||
histGet := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("get"))
|
||||
lcmd, err := rt.Call1(l.MainThread(), histGet, rt.IntValue(int64(idx)))
|
||||
lcmd, err := l.Call1(histGet, rt.IntValue(int64(idx)))
|
||||
|
||||
var cmd string
|
||||
if lcmd.Type() == rt.StringType {
|
||||
|
@ -38,7 +38,7 @@ func (h *luaHistory) GetLine(idx int) (string, error) {
|
|||
|
||||
func (h *luaHistory) Len() int {
|
||||
histSize := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("size"))
|
||||
ln, _ := rt.Call1(l.MainThread(), histSize)
|
||||
ln, _ := l.Call1(histSize)
|
||||
|
||||
var num int64
|
||||
if ln.Type() == rt.IntType {
|
||||
|
|
17
job.go
17
job.go
|
@ -10,6 +10,7 @@ import (
|
|||
"sync"
|
||||
"syscall"
|
||||
|
||||
"hilbish/moonlight"
|
||||
"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
|
@ -310,7 +311,8 @@ Manage interactive jobs in Hilbish via Lua.
|
|||
|
||||
Jobs are the name of background tasks/commands. A job can be started via
|
||||
interactive usage or with the functions defined below for use in external runners. */
|
||||
func (j *jobHandler) loader(rtm *rt.Runtime) *rt.Table {
|
||||
func (j *jobHandler) loader() *moonlight.Table {
|
||||
/*
|
||||
jobMethods := rt.NewTable()
|
||||
jFuncs := map[string]util.LuaExport{
|
||||
"stop": {luaStopJob, 1, false},
|
||||
|
@ -319,7 +321,9 @@ func (j *jobHandler) loader(rtm *rt.Runtime) *rt.Table {
|
|||
"background": {luaBackgroundJob, 1, false},
|
||||
}
|
||||
util.SetExports(l, jobMethods, jFuncs)
|
||||
*/
|
||||
|
||||
/*
|
||||
jobMeta := rt.NewTable()
|
||||
jobIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
j, _ := jobArg(c, 0)
|
||||
|
@ -348,17 +352,20 @@ func (j *jobHandler) loader(rtm *rt.Runtime) *rt.Table {
|
|||
|
||||
jobMeta.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(jobIndex, "__index", 2, false)))
|
||||
l.SetRegistry(jobMetaKey, rt.TableValue(jobMeta))
|
||||
*/
|
||||
|
||||
jobFuncs := map[string]util.LuaExport{
|
||||
jobFuncs := map[string]moonlight.Export{
|
||||
/*
|
||||
"all": {j.luaAllJobs, 0, false},
|
||||
"last": {j.luaLastJob, 0, false},
|
||||
"get": {j.luaGetJob, 1, false},
|
||||
"add": {j.luaAddJob, 3, false},
|
||||
"disown": {j.luaDisownJob, 1, false},
|
||||
*/
|
||||
}
|
||||
|
||||
luaJob := rt.NewTable()
|
||||
util.SetExports(rtm, luaJob, jobFuncs)
|
||||
luaJob := moonlight.NewTable()
|
||||
l.SetExports(luaJob, jobFuncs)
|
||||
|
||||
return luaJob
|
||||
}
|
||||
|
@ -383,7 +390,7 @@ func valueToJob(val rt.Value) (*job, bool) {
|
|||
}
|
||||
|
||||
func jobUserData(j *job) *rt.UserData {
|
||||
jobMeta := l.Registry(jobMetaKey)
|
||||
jobMeta := l.UnderlyingRuntime().Registry(jobMetaKey)
|
||||
return rt.NewUserData(j, jobMeta.AsTable())
|
||||
}
|
||||
|
||||
|
|
38
lua.go
38
lua.go
|
@ -4,32 +4,27 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"hilbish/util"
|
||||
"hilbish/golibs/bait"
|
||||
"hilbish/golibs/commander"
|
||||
"hilbish/golibs/fs"
|
||||
"hilbish/golibs/terminal"
|
||||
//"hilbish/util"
|
||||
//"hilbish/golibs/bait"
|
||||
//"hilbish/golibs/commander"
|
||||
//"hilbish/golibs/fs"
|
||||
//"hilbish/golibs/terminal"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/arnodel/golua/lib"
|
||||
"github.com/arnodel/golua/lib/debuglib"
|
||||
"hilbish/moonlight"
|
||||
)
|
||||
|
||||
var minimalconf = `hilbish.prompt '& '`
|
||||
|
||||
func luaInit() {
|
||||
l = rt.New(os.Stdout)
|
||||
l.PushContext(rt.RuntimeContextDef{
|
||||
MessageHandler: debuglib.Traceback,
|
||||
})
|
||||
lib.LoadAll(l)
|
||||
setupSinkType(l)
|
||||
l = moonlight.NewRuntime()
|
||||
setupSinkType()
|
||||
|
||||
lib.LoadLibs(l, hilbishLoader)
|
||||
l.LoadLibrary(hilbishLoader, "hilbish")
|
||||
// yes this is stupid, i know
|
||||
util.DoString(l, "hilbish = require 'hilbish'")
|
||||
l.DoString("hilbish = require 'hilbish'")
|
||||
|
||||
// Add fs and terminal module module to Lua
|
||||
/*
|
||||
lib.LoadLibs(l, fs.Loader)
|
||||
lib.LoadLibs(l, terminal.Loader)
|
||||
|
||||
|
@ -54,16 +49,17 @@ func luaInit() {
|
|||
lr.rl.RawInputCallback = func(r []rune) {
|
||||
hooks.Emit("hilbish.rawInput", string(r))
|
||||
}
|
||||
*/
|
||||
|
||||
// Add more paths that Lua can require from
|
||||
_, err := util.DoString(l, "package.path = package.path .. " + requirePaths)
|
||||
_, err := l.DoString("package.path = package.path .. " + requirePaths)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Could not add Hilbish require paths! Libraries will be missing. This shouldn't happen.")
|
||||
}
|
||||
|
||||
err1 := util.DoFile(l, "nature/init.lua")
|
||||
err1 := l.DoFile("nature/init.lua")
|
||||
if err1 != nil {
|
||||
err2 := util.DoFile(l, preloadPath)
|
||||
err2 := l.DoFile(preloadPath)
|
||||
if err2 != nil {
|
||||
fmt.Fprintln(os.Stderr, "Missing nature module, some functionality and builtins will be missing.")
|
||||
fmt.Fprintln(os.Stderr, "local error:", err1)
|
||||
|
@ -76,9 +72,9 @@ func runConfig(confpath string) {
|
|||
if !interactive {
|
||||
return
|
||||
}
|
||||
err := util.DoFile(l, confpath)
|
||||
err := l.DoFile(confpath)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err, "\nAn error has occured while loading your config! Falling back to minimal default config.")
|
||||
util.DoString(l, minimalconf)
|
||||
l.DoString(minimalconf)
|
||||
}
|
||||
}
|
||||
|
|
7
main.go
7
main.go
|
@ -16,6 +16,7 @@ import (
|
|||
"hilbish/util"
|
||||
"hilbish/golibs/bait"
|
||||
"hilbish/golibs/commander"
|
||||
"hilbish/moonlight"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/pborman/getopt"
|
||||
|
@ -24,7 +25,7 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
l *rt.Runtime
|
||||
l *moonlight.Runtime
|
||||
lr *lineReader
|
||||
|
||||
luaCompletions = map[string]*rt.Closure{}
|
||||
|
@ -171,8 +172,8 @@ func main() {
|
|||
luaArgs.Set(rt.IntValue(int64(i)), rt.StringValue(arg))
|
||||
}
|
||||
|
||||
l.GlobalEnv().Set(rt.StringValue("args"), rt.TableValue(luaArgs))
|
||||
err := util.DoFile(l, getopt.Arg(0))
|
||||
l.GlobalTable().SetField("args", rt.TableValue(luaArgs))
|
||||
err := l.DoFile(getopt.Arg(0))
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
exit(1)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package moonlight
|
||||
|
||||
type Export struct{
|
||||
Function GoToLuaFunc
|
||||
ArgNum int
|
||||
Variadic bool
|
||||
}
|
||||
|
||||
func (mlr *Runtime) SetExports(tbl *Table, exports map[string]Export) {
|
||||
for name, export := range exports {
|
||||
mlr.rt.SetEnvGoFunc(tbl.lt, name, mlr.GoFunction(export.Function), export.ArgNum, export.Variadic)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package moonlight
|
||||
|
||||
type GoToLuaFunc func(mlr *Runtime, c *GoCont) (Cont, error)
|
|
@ -0,0 +1,29 @@
|
|||
package moonlight
|
||||
|
||||
import (
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
type GoFunctionFunc = rt.GoFunctionFunc
|
||||
|
||||
type GoCont = rt.GoCont
|
||||
type Cont = rt.Cont
|
||||
|
||||
func (mlr *Runtime) CheckNArgs(c *GoCont, num int) error {
|
||||
return c.CheckNArgs(num)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) StringArg(c *GoCont, num int) (string, error) {
|
||||
return c.StringArg(num)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) GoFunction(fun GoToLuaFunc) rt.GoFunctionFunc {
|
||||
return func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
gocont := GoCont(*c)
|
||||
return fun(mlr, &gocont)
|
||||
}
|
||||
}
|
||||
|
||||
func (mlr *Runtime) Call1(val Value, args ...Value) (Value, error) {
|
||||
return rt.Call1(mlr.rt.MainThread(), val, args...)
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package moonlight
|
||||
|
||||
import (
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/arnodel/golua/lib"
|
||||
"github.com/arnodel/golua/lib/packagelib"
|
||||
)
|
||||
|
||||
type Loader func(*Runtime) Value
|
||||
|
||||
func (mlr *Runtime) LoadLibrary(ldr Loader, name string) {
|
||||
goluaLoader := packagelib.Loader{
|
||||
Load: func(rt *rt.Runtime) (rt.Value, func()) {
|
||||
val := ldr(specificRuntimeToGeneric(rt))
|
||||
|
||||
return val, nil
|
||||
},
|
||||
Name: name,
|
||||
}
|
||||
|
||||
lib.LoadLibs(mlr.rt, goluaLoader)
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package moonlight
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/arnodel/golua/lib"
|
||||
"github.com/arnodel/golua/lib/debuglib"
|
||||
)
|
||||
|
||||
type Runtime struct{
|
||||
rt *rt.Runtime
|
||||
}
|
||||
|
||||
func NewRuntime() *Runtime {
|
||||
r := rt.New(os.Stdout)
|
||||
r.PushContext(rt.RuntimeContextDef{
|
||||
MessageHandler: debuglib.Traceback,
|
||||
})
|
||||
lib.LoadAll(r)
|
||||
|
||||
return specificRuntimeToGeneric(r)
|
||||
}
|
||||
|
||||
func specificRuntimeToGeneric(rtm *rt.Runtime) *Runtime {
|
||||
rr := Runtime{
|
||||
rt: rtm,
|
||||
}
|
||||
|
||||
return &rr
|
||||
}
|
||||
|
||||
func (mlr *Runtime) UnderlyingRuntime() *rt.Runtime {
|
||||
return mlr.rt
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package moonlight
|
||||
|
||||
import (
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
type Table struct{
|
||||
lt *rt.Table
|
||||
}
|
||||
|
||||
func NewTable() *Table {
|
||||
return &Table{
|
||||
lt: rt.NewTable(),
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Table) Get(val Value) Value {
|
||||
return t.lt.Get(val)
|
||||
}
|
||||
|
||||
func (t *Table) SetField(key string, value Value) {
|
||||
t.lt.Set(rt.StringValue(key), value)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) GlobalTable() *Table {
|
||||
return &Table{
|
||||
lt: mlr.rt.GlobalEnv(),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package moonlight
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
// DoString runs the code string in the Lua runtime.
|
||||
func (mlr *Runtime) DoString(code string) (rt.Value, error) {
|
||||
chunk, err := mlr.rt.CompileAndLoadLuaChunk("<string>", []byte(code), rt.TableValue(mlr.rt.GlobalEnv()))
|
||||
var ret rt.Value
|
||||
if chunk != nil {
|
||||
ret, err = rt.Call1(mlr.rt.MainThread(), rt.FunctionValue(chunk))
|
||||
}
|
||||
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// DoFile runs the contents of the file in the Lua runtime.
|
||||
func (mlr *Runtime) DoFile(path string) error {
|
||||
f, err := os.Open(path)
|
||||
defer f.Close()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(f)
|
||||
c, err := reader.ReadByte()
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
// unread so a char won't be missing
|
||||
err = reader.UnreadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if c == byte('#') {
|
||||
// shebang - skip that line
|
||||
_, err := reader.ReadBytes('\n')
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
buf = []byte{'\n'}
|
||||
}
|
||||
|
||||
for {
|
||||
line, err := reader.ReadBytes('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
buf = append(buf, line...)
|
||||
}
|
||||
|
||||
clos, err := mlr.rt.LoadFromSourceOrCode(path, buf, "bt", rt.TableValue(mlr.rt.GlobalEnv()), false)
|
||||
if clos != nil {
|
||||
_, err = rt.Call1(mlr.rt.MainThread(), rt.FunctionValue(clos))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package moonlight
|
||||
|
||||
import (
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
type Value = rt.Value
|
||||
|
||||
func StringValue(str string) Value {
|
||||
return rt.StringValue(str)
|
||||
}
|
||||
|
||||
func IntValue(i int) Value {
|
||||
return rt.IntValue(int64(i))
|
||||
}
|
||||
|
||||
func BoolValue(b bool) Value {
|
||||
return rt.BoolValue(b)
|
||||
}
|
||||
|
||||
func TableValue(t *Table) Value {
|
||||
return rt.TableValue(t.lt)
|
||||
}
|
13
os.go
13
os.go
|
@ -1,7 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"hilbish/util"
|
||||
"hilbish/moonlight"
|
||||
//"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/blackfireio/osinfo"
|
||||
|
@ -14,13 +15,13 @@ import (
|
|||
// #field family Family name of the current OS
|
||||
// #field name Pretty name of the current OS
|
||||
// #field version Version of the current OS
|
||||
func hshosLoader(rtm *rt.Runtime) *rt.Table {
|
||||
func hshosLoader() *moonlight.Table {
|
||||
info, _ := osinfo.GetOSInfo()
|
||||
mod := rt.NewTable()
|
||||
mod := moonlight.NewTable()
|
||||
|
||||
util.SetField(rtm, mod, "family", rt.StringValue(info.Family))
|
||||
util.SetField(rtm, mod, "name", rt.StringValue(info.Name))
|
||||
util.SetField(rtm, mod, "version", rt.StringValue(info.Version))
|
||||
mod.SetField("family", rt.StringValue(info.Family))
|
||||
mod.SetField("name", rt.StringValue(info.Name))
|
||||
mod.SetField("version", rt.StringValue(info.Version))
|
||||
|
||||
return mod
|
||||
}
|
||||
|
|
12
rl.go
12
rl.go
|
@ -27,7 +27,7 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
|||
|
||||
regexSearcher := rl.Searcher
|
||||
rl.Searcher = func(needle string, haystack []string) []string {
|
||||
fz, _ := util.DoString(l, "return hilbish.opts.fuzzy")
|
||||
fz, _ := l.DoString("return hilbish.opts.fuzzy")
|
||||
fuzz, ok := fz.TryBool()
|
||||
if !fuzz || !ok {
|
||||
return regexSearcher(needle, haystack)
|
||||
|
@ -71,8 +71,7 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
|||
}
|
||||
rl.HintText = func(line []rune, pos int) []rune {
|
||||
hinter := hshMod.Get(rt.StringValue("hinter"))
|
||||
retVal, err := rt.Call1(l.MainThread(), hinter,
|
||||
rt.StringValue(string(line)), rt.IntValue(int64(pos)))
|
||||
retVal, err := l.Call1(hinter, rt.StringValue(string(line)), rt.IntValue(int64(pos)))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return []rune{}
|
||||
|
@ -87,8 +86,7 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
|||
}
|
||||
rl.SyntaxHighlighter = func(line []rune) string {
|
||||
highlighter := hshMod.Get(rt.StringValue("highlighter"))
|
||||
retVal, err := rt.Call1(l.MainThread(), highlighter,
|
||||
rt.StringValue(string(line)))
|
||||
retVal, err := l.Call1(highlighter, rt.StringValue(string(line)))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return string(line)
|
||||
|
@ -102,9 +100,9 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
|||
return highlighted
|
||||
}
|
||||
rl.TabCompleter = func(line []rune, pos int, _ readline.DelayedTabContext) (string, []*readline.CompletionGroup) {
|
||||
term := rt.NewTerminationWith(l.MainThread().CurrentCont(), 2, false)
|
||||
term := rt.NewTerminationWith(l.UnderlyingRuntime().MainThread().CurrentCont(), 2, false)
|
||||
compHandle := hshMod.Get(rt.StringValue("completion")).AsTable().Get(rt.StringValue("handler"))
|
||||
err := rt.Call(l.MainThread(), compHandle, []rt.Value{rt.StringValue(string(line)),
|
||||
err := rt.Call(l.UnderlyingRuntime().MainThread(), compHandle, []rt.Value{rt.StringValue(string(line)),
|
||||
rt.IntValue(int64(pos))}, term)
|
||||
|
||||
var compGroups []*readline.CompletionGroup
|
||||
|
|
|
@ -51,9 +51,11 @@ end)
|
|||
*/
|
||||
func runnerModeLoader(rtm *rt.Runtime) *rt.Table {
|
||||
exports := map[string]util.LuaExport{
|
||||
/*
|
||||
"sh": {shRunner, 1, false},
|
||||
"lua": {luaRunner, 1, false},
|
||||
"setMode": {hlrunnerMode, 1, false},
|
||||
*/
|
||||
}
|
||||
|
||||
mod := rt.NewTable()
|
||||
|
|
20
sink.go
20
sink.go
|
@ -7,7 +7,8 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"hilbish/util"
|
||||
//"hilbish/util"
|
||||
"hilbish/moonlight"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
@ -25,20 +26,22 @@ type sink struct{
|
|||
autoFlush bool
|
||||
}
|
||||
|
||||
func setupSinkType(rtm *rt.Runtime) {
|
||||
sinkMeta := rt.NewTable()
|
||||
func setupSinkType() {
|
||||
//sinkMeta := moonlight.NewTable()
|
||||
|
||||
sinkMethods := rt.NewTable()
|
||||
sinkFuncs := map[string]util.LuaExport{
|
||||
sinkMethods := moonlight.NewTable()
|
||||
sinkFuncs := map[string]moonlight.Export{
|
||||
/*
|
||||
"flush": {luaSinkFlush, 1, false},
|
||||
"read": {luaSinkRead, 1, false},
|
||||
"readAll": {luaSinkReadAll, 1, false},
|
||||
"autoFlush": {luaSinkAutoFlush, 2, false},
|
||||
"write": {luaSinkWrite, 2, false},
|
||||
"writeln": {luaSinkWriteln, 2, false},
|
||||
*/
|
||||
}
|
||||
util.SetExports(l, sinkMethods, sinkFuncs)
|
||||
|
||||
l.SetExports(sinkMethods, sinkFuncs)
|
||||
/*
|
||||
sinkIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
s, _ := sinkArg(c, 0)
|
||||
|
||||
|
@ -65,6 +68,7 @@ func setupSinkType(rtm *rt.Runtime) {
|
|||
|
||||
sinkMeta.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(sinkIndex, "__index", 2, false)))
|
||||
l.SetRegistry(sinkMetaKey, rt.TableValue(sinkMeta))
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -255,6 +259,6 @@ func valueToSink(val rt.Value) (*sink, bool) {
|
|||
}
|
||||
|
||||
func sinkUserData(s *sink) *rt.UserData {
|
||||
sinkMeta := l.Registry(sinkMetaKey)
|
||||
sinkMeta := l.UnderlyingRuntime().Registry(sinkMetaKey)
|
||||
return rt.NewUserData(s, sinkMeta.AsTable())
|
||||
}
|
||||
|
|
2
timer.go
2
timer.go
|
@ -47,7 +47,7 @@ func (t *timer) start() error {
|
|||
for {
|
||||
select {
|
||||
case <-t.ticker.C:
|
||||
_, err := rt.Call1(l.MainThread(), rt.FunctionValue(t.fun))
|
||||
_, err := l.Call1(rt.FunctionValue(t.fun))
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error in function:\n", err)
|
||||
t.stop()
|
||||
|
|
|
@ -5,7 +5,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"hilbish/util"
|
||||
"hilbish/moonlight"
|
||||
//"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
@ -133,13 +134,15 @@ t:start()
|
|||
print(t.running) // true
|
||||
```
|
||||
*/
|
||||
func (th *timersModule) loader(rtm *rt.Runtime) *rt.Table {
|
||||
timerMethods := rt.NewTable()
|
||||
timerFuncs := map[string]util.LuaExport{
|
||||
func (th *timersModule) loader() *moonlight.Table {
|
||||
timerMethods := moonlight.NewTable()
|
||||
timerFuncs := map[string]moonlight.Export{
|
||||
/*
|
||||
"start": {timerStart, 1, false},
|
||||
"stop": {timerStop, 1, false},
|
||||
*/
|
||||
}
|
||||
util.SetExports(rtm, timerMethods, timerFuncs)
|
||||
l.SetExports(timerMethods, timerFuncs)
|
||||
|
||||
timerMeta := rt.NewTable()
|
||||
timerIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
|
@ -164,18 +167,20 @@ func (th *timersModule) loader(rtm *rt.Runtime) *rt.Table {
|
|||
}
|
||||
|
||||
timerMeta.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(timerIndex, "__index", 2, false)))
|
||||
l.SetRegistry(timerMetaKey, rt.TableValue(timerMeta))
|
||||
l.UnderlyingRuntime().SetRegistry(timerMetaKey, rt.TableValue(timerMeta))
|
||||
|
||||
thExports := map[string]util.LuaExport{
|
||||
thExports := map[string]moonlight.Export{
|
||||
/*
|
||||
"create": {th.luaCreate, 3, false},
|
||||
"get": {th.luaGet, 1, false},
|
||||
*/
|
||||
}
|
||||
|
||||
luaTh := rt.NewTable()
|
||||
util.SetExports(rtm, luaTh, thExports)
|
||||
luaTh := moonlight.NewTable()
|
||||
l.SetExports(luaTh, thExports)
|
||||
|
||||
util.SetField(rtm, luaTh, "INTERVAL", rt.IntValue(0))
|
||||
util.SetField(rtm, luaTh, "TIMEOUT", rt.IntValue(1))
|
||||
luaTh.SetField("INTERVAL", rt.IntValue(0))
|
||||
luaTh.SetField("TIMEOUT", rt.IntValue(1))
|
||||
|
||||
return luaTh
|
||||
}
|
||||
|
@ -200,6 +205,6 @@ func valueToTimer(val rt.Value) (*timer, bool) {
|
|||
}
|
||||
|
||||
func timerUserData(j *timer) *rt.UserData {
|
||||
timerMeta := l.Registry(timerMetaKey)
|
||||
timerMeta := l.UnderlyingRuntime().Registry(timerMetaKey)
|
||||
return rt.NewUserData(j, timerMeta.AsTable())
|
||||
}
|
||||
|
|
11
userdir.go
11
userdir.go
|
@ -1,7 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"hilbish/util"
|
||||
"hilbish/moonlight"
|
||||
//"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
@ -13,11 +14,11 @@ import (
|
|||
// for configs and data.
|
||||
// #field config The user's config directory
|
||||
// #field data The user's directory for program data
|
||||
func userDirLoader(rtm *rt.Runtime) *rt.Table {
|
||||
mod := rt.NewTable()
|
||||
func userDirLoader() *moonlight.Table {
|
||||
mod := moonlight.NewTable()
|
||||
|
||||
util.SetField(rtm, mod, "config", rt.StringValue(confDir))
|
||||
util.SetField(rtm, mod, "data", rt.StringValue(userDataDir))
|
||||
mod.SetField("config", rt.StringValue(confDir))
|
||||
mod.SetField("data", rt.StringValue(userDataDir))
|
||||
|
||||
return mod
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"hilbish/moonlight"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
// LuaExport represents a Go function which can be exported to Lua.
|
||||
type LuaExport struct {
|
||||
Function rt.GoFunctionFunc
|
||||
Function moonlight.GoFunctionFunc
|
||||
ArgNum int
|
||||
Variadic bool
|
||||
}
|
||||
|
|
76
util/util.go
76
util/util.go
|
@ -1,10 +1,7 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"strings"
|
||||
"os"
|
||||
"os/user"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
|
@ -12,81 +9,10 @@ import (
|
|||
|
||||
// SetField sets a field in a table, adding docs for it.
|
||||
// It is accessible via the __docProp metatable. It is a table of the names of the fields.
|
||||
func SetField(rtm *rt.Runtime, module *rt.Table, field string, value rt.Value) {
|
||||
// TODO: ^ rtm isnt needed, i should remove it
|
||||
func SetField(module *rt.Table, field string, value rt.Value) {
|
||||
module.Set(rt.StringValue(field), value)
|
||||
}
|
||||
|
||||
// SetFieldProtected sets a field in a protected table. A protected table
|
||||
// is one which has a metatable proxy to ensure no overrides happen to it.
|
||||
// It sets the field in the table and sets the __docProp metatable on the
|
||||
// user facing table.
|
||||
func SetFieldProtected(module, realModule *rt.Table, field string, value rt.Value) {
|
||||
realModule.Set(rt.StringValue(field), value)
|
||||
}
|
||||
|
||||
// DoString runs the code string in the Lua runtime.
|
||||
func DoString(rtm *rt.Runtime, code string) (rt.Value, error) {
|
||||
chunk, err := rtm.CompileAndLoadLuaChunk("<string>", []byte(code), rt.TableValue(rtm.GlobalEnv()))
|
||||
var ret rt.Value
|
||||
if chunk != nil {
|
||||
ret, err = rt.Call1(rtm.MainThread(), rt.FunctionValue(chunk))
|
||||
}
|
||||
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// DoFile runs the contents of the file in the Lua runtime.
|
||||
func DoFile(rtm *rt.Runtime, path string) error {
|
||||
f, err := os.Open(path)
|
||||
defer f.Close()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
reader := bufio.NewReader(f)
|
||||
c, err := reader.ReadByte()
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
// unread so a char won't be missing
|
||||
err = reader.UnreadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
if c == byte('#') {
|
||||
// shebang - skip that line
|
||||
_, err := reader.ReadBytes('\n')
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
buf = []byte{'\n'}
|
||||
}
|
||||
|
||||
for {
|
||||
line, err := reader.ReadBytes('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
buf = append(buf, line...)
|
||||
}
|
||||
|
||||
clos, err := rtm.LoadFromSourceOrCode(path, buf, "bt", rt.TableValue(rtm.GlobalEnv()), false)
|
||||
if clos != nil {
|
||||
_, err = rt.Call1(rtm.MainThread(), rt.FunctionValue(clos))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// HandleStrCallback handles function parameters for Go functions which take
|
||||
// a string and a closure.
|
||||
func HandleStrCallback(t *rt.Thread, c *rt.GoCont) (string, *rt.Closure, error) {
|
||||
|
|
Loading…
Reference in New Issue