mirror of https://github.com/Hilbis/Hilbish
feat: begin initial port to c lua
parent
17a3e2c0c4
commit
1f9fd80fbb
|
@ -14,6 +14,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
midnight: [false, true]
|
||||
goos: [linux, windows, darwin]
|
||||
goarch: ["386", amd64, arm64]
|
||||
exclude:
|
||||
|
@ -33,7 +34,7 @@ jobs:
|
|||
- name: Download Task
|
||||
run: 'sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d'
|
||||
- name: Build
|
||||
run: GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} ./bin/task
|
||||
run: GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} ./bin/task ${{ matrix.midnight == 'true' && 'midnight' || ''}}
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: matrix.goos == 'windows'
|
||||
with:
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
Functionality **will** be missing if you use this branch,
|
||||
and you may see crashes too. Tread lightly.
|
||||
|
||||
Progress on Midnight Edition is tracked in this PR: [#314](https://github.com/Rosettea/Hilbish/pull/314)
|
||||
Build instructions and progress on Midnight Edition is tracked in this PR:
|
||||
[#314](https://github.com/Rosettea/Hilbish/pull/314)
|
||||
|
||||
Hilbish: Midinight Edition is a version of Hilbish meant to be compatible with
|
||||
the original C implementation of Lua by using a Go library binding. The end goal
|
||||
|
@ -70,13 +71,13 @@ go get -d ./...
|
|||
|
||||
To build, run:
|
||||
```
|
||||
task
|
||||
go-task
|
||||
```
|
||||
|
||||
Or, if you want a stable branch, run these commands:
|
||||
```
|
||||
git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
|
||||
task build
|
||||
go-task build
|
||||
```
|
||||
|
||||
After you did all that, run `sudo task install` to install Hilbish globally.
|
||||
|
|
|
@ -10,6 +10,8 @@ vars:
|
|||
LIBDIR: '{{default .libdir__ .LIBDIR}}'
|
||||
goflags__: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}}"'
|
||||
GOFLAGS: '{{default .goflags__ .GOFLAGS}}'
|
||||
lua__: 'lua'
|
||||
LUA: '{{default .lua__ .LUA}}'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
|
@ -24,6 +26,12 @@ tasks:
|
|||
vars:
|
||||
GOFLAGS: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}} -X main.gitCommit=$(git rev-parse --short HEAD) -X main.gitBranch=$(git rev-parse --abbrev-ref HEAD)"'
|
||||
|
||||
midnight:
|
||||
cmds:
|
||||
- go build -tags midnight,{{.LUA}} {{.GOFLAGS}}
|
||||
vars:
|
||||
GOFLAGS: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}} -X main.gitCommit=$(git rev-parse --short HEAD) -X main.gitBranch=$(git rev-parse --abbrev-ref HEAD)"'
|
||||
|
||||
build:
|
||||
cmds:
|
||||
- go build {{.GOFLAGS}}
|
||||
|
|
|
@ -97,10 +97,12 @@ 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},
|
||||
*/
|
||||
}
|
||||
|
||||
mod := rt.NewTable()
|
||||
|
|
4
api.go
4
api.go
|
@ -149,12 +149,12 @@ func getenv(key, fallback string) string {
|
|||
}
|
||||
|
||||
func setVimMode(mode string) {
|
||||
hshMod.SetField("vimMode", rt.StringValue(mode))
|
||||
hshMod.SetField("vimMode", moonlight.StringValue(mode))
|
||||
hooks.Emit("hilbish.vimMode", mode)
|
||||
}
|
||||
|
||||
func unsetVimMode() {
|
||||
hshMod.SetField("vimMode", rt.NilValue)
|
||||
hshMod.SetField("vimMode", moonlight.NilValue)
|
||||
}
|
||||
|
||||
func handleStream(v rt.Value, strms *streams, errStream bool) error {
|
||||
|
|
|
@ -12,11 +12,13 @@ import (
|
|||
// directly interact with the line editor in use.
|
||||
func editorLoader(rtm *rt.Runtime) *rt.Table {
|
||||
exports := map[string]util.LuaExport{
|
||||
/*
|
||||
"insert": {editorInsert, 1, false},
|
||||
"setVimRegister": {editorSetRegister, 1, false},
|
||||
"getVimRegister": {editorGetRegister, 2, false},
|
||||
"getLine": {editorGetLine, 0, false},
|
||||
"readChar": {editorReadChar, 0, false},
|
||||
*/
|
||||
}
|
||||
|
||||
mod := rt.NewTable()
|
||||
|
|
52
exec.go
52
exec.go
|
@ -28,7 +28,7 @@ import (
|
|||
|
||||
var errNotExec = errors.New("not executable")
|
||||
var errNotFound = errors.New("not found")
|
||||
var runnerMode rt.Value = rt.StringValue("hybrid")
|
||||
var runnerMode moonlight.Value = moonlight.StringValue("hybrid")
|
||||
|
||||
type streams struct {
|
||||
stdout io.Writer
|
||||
|
@ -101,7 +101,7 @@ func runInput(input string, priv bool) {
|
|||
var cont bool
|
||||
// save incase it changes while prompting (For some reason)
|
||||
currentRunner := runnerMode
|
||||
if currentRunner.Type() == rt.StringType {
|
||||
if currentRunner.Type() == moonlight.StringType {
|
||||
switch currentRunner.AsString() {
|
||||
case "hybrid":
|
||||
_, _, err = handleLua(input)
|
||||
|
@ -171,69 +171,41 @@ func reprompt(input string) (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func runLuaRunner(runr rt.Value, userInput string) (input string, exitCode uint8, continued bool, runnerErr, err error) {
|
||||
func runLuaRunner(runr moonlight.Value, userInput string) (input string, exitCode uint8, continued bool, runnerErr, err error) {
|
||||
runnerRet, err := l.Call1(runr, moonlight.StringValue(userInput))
|
||||
if err != nil {
|
||||
return "", 124, false, nil, err
|
||||
}
|
||||
|
||||
var runner *rt.Table
|
||||
var runner *moonlight.Table
|
||||
var ok bool
|
||||
if runner, ok = runnerRet.TryTable(); !ok {
|
||||
if runner, ok = moonlight.TryTable(runnerRet); !ok {
|
||||
fmt.Fprintln(os.Stderr, "runner did not return a table")
|
||||
exitCode = 125
|
||||
input = userInput
|
||||
return
|
||||
}
|
||||
|
||||
if code, ok := runner.Get(rt.StringValue("exitCode")).TryInt(); ok {
|
||||
if code, ok := runner.Get(moonlight.StringValue("exitCode")).TryInt(); ok {
|
||||
exitCode = uint8(code)
|
||||
}
|
||||
|
||||
if inp, ok := runner.Get(rt.StringValue("input")).TryString(); ok {
|
||||
if inp, ok := runner.Get(moonlight.StringValue("input")).TryString(); ok {
|
||||
input = inp
|
||||
}
|
||||
|
||||
if errStr, ok := runner.Get(rt.StringValue("err")).TryString(); ok {
|
||||
if errStr, ok := runner.Get(moonlight.StringValue("err")).TryString(); ok {
|
||||
runnerErr = fmt.Errorf("%s", errStr)
|
||||
}
|
||||
|
||||
if c, ok := runner.Get(rt.StringValue("continue")).TryBool(); ok {
|
||||
if c, ok := runner.Get(moonlight.StringValue("continue")).TryBool(); ok {
|
||||
continued = c
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func handleLua(input string) (string, uint8, error) {
|
||||
cmdString := aliases.Resolve(input)
|
||||
// First try to load input, essentially compiling to bytecode
|
||||
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 {
|
||||
if perr, ok := lerr.Cause.(*parse.Error); ok {
|
||||
print(perr.Pos.Line == parse.EOF)
|
||||
}
|
||||
}
|
||||
*/
|
||||
return cmdString, 125, err
|
||||
}
|
||||
// And if there's no syntax errors and -n isnt provided, run
|
||||
if !noexecute {
|
||||
if chunk != nil {
|
||||
_, err = l.Call1(rt.FunctionValue(chunk))
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
return cmdString, 0, nil
|
||||
}
|
||||
|
||||
return cmdString, 125, err
|
||||
}
|
||||
|
||||
func handleSh(cmdString string) (input string, exitCode uint8, cont bool, runErr error) {
|
||||
shRunner := hshMod.Get(rt.StringValue("runner")).AsTable().Get(rt.StringValue("sh"))
|
||||
shRunner := hshMod.Get(moonlight.StringValue("runner")).AsTable().Get(moonlight.StringValue("sh"))
|
||||
var err error
|
||||
input, exitCode, cont, runErr, err = runLuaRunner(shRunner, cmdString)
|
||||
if err != nil {
|
||||
|
@ -607,9 +579,9 @@ func splitInput(input string) ([]string, string) {
|
|||
}
|
||||
|
||||
func cmdFinish(code uint8, cmdstr string, private bool) {
|
||||
hshMod.SetField("exitCode", rt.IntValue(int64(code)))
|
||||
hshMod.SetField("exitCode", moonlight.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
|
||||
hooks.Emit("command.exit", rt.IntValue(int64(code)), cmdstr, private)
|
||||
hooks.Emit("command.exit", moonlight.IntValue(int64(code)), cmdstr, private)
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -5,6 +5,7 @@ go 1.21
|
|||
toolchain go1.22.2
|
||||
|
||||
require (
|
||||
github.com/aarzilli/golua v0.0.0-20210507130708-11106aa57765
|
||||
github.com/arnodel/golua v0.0.0-20230215163904-e0b5347eaaa1
|
||||
github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504
|
||||
github.com/blackfireio/osinfo v1.0.5
|
||||
|
|
2
go.sum
2
go.sum
|
@ -2,6 +2,8 @@ github.com/Rosettea/golua v0.0.0-20240427174124-d239074c1749 h1:jIFnWBTsYw8s7RX7
|
|||
github.com/Rosettea/golua v0.0.0-20240427174124-d239074c1749/go.mod h1:9jzpYPiU2is0HVGCiuIOBSXdergHUW44IEjmuN1UrIE=
|
||||
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240720131751-805c301321fd h1:THNle0FR2g7DMO1y3Bx1Zr7rYeiLXt3st3UkxEsMzL4=
|
||||
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240720131751-805c301321fd/go.mod h1:YZalN5H7WNQw3DGij6IvHsEhn5YMW7M2FCwG6gnfKy4=
|
||||
github.com/aarzilli/golua v0.0.0-20210507130708-11106aa57765 h1:N6gB4UCRBZz8twlJbMFiCKj0zX5Et2nFU/LRafT4x80=
|
||||
github.com/aarzilli/golua v0.0.0-20210507130708-11106aa57765/go.mod h1:hMjfaJVSqVnxenMlsxrq3Ni+vrm9Hs64tU4M7dhUoO4=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
|
||||
github.com/arnodel/strftime v0.1.6 h1:0hc0pUvk8KhEMXE+htyaOUV42zNcf/csIbjzEFCJqsw=
|
||||
|
|
|
@ -82,16 +82,17 @@ func (b *Bait) Emit(event string, args ...interface{}) {
|
|||
}()
|
||||
|
||||
if handle.typ == luaListener {
|
||||
funcVal := rt.FunctionValue(handle.luaCaller)
|
||||
//funcVal := moonlight.FunctionValue(handle.luaCaller)
|
||||
var luaArgs []moonlight.Value
|
||||
for _, arg := range args {
|
||||
var luarg moonlight.Value
|
||||
switch arg.(type) {
|
||||
case moonlight.Value: luarg = arg.(moonlight.Value)
|
||||
default: luarg = rt.AsValue(arg)
|
||||
default: luarg = moonlight.AsValue(arg)
|
||||
}
|
||||
luaArgs = append(luaArgs, luarg)
|
||||
}
|
||||
/*
|
||||
_, err := b.rtm.Call1(funcVal, luaArgs...)
|
||||
if err != nil {
|
||||
if event != "error" {
|
||||
|
@ -102,6 +103,7 @@ func (b *Bait) Emit(event string, args ...interface{}) {
|
|||
// (calls the go recoverer function)
|
||||
panic(err)
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
handle.caller(args...)
|
||||
}
|
||||
|
@ -146,7 +148,7 @@ func (b *Bait) Off(event string, listener *Listener) {
|
|||
}
|
||||
|
||||
// OffLua removes a Lua function handler for an event.
|
||||
func (b *Bait) OffLua(event string, handler *rt.Closure) {
|
||||
func (b *Bait) OffLua(event string, handler *moonlight.Closure) {
|
||||
handles := b.handlers[event]
|
||||
|
||||
for i, handle := range handles {
|
||||
|
@ -169,7 +171,7 @@ func (b *Bait) Once(event string, handler func(...interface{})) *Listener {
|
|||
}
|
||||
|
||||
// OnceLua adds a Lua function listener for an event that only runs once.
|
||||
func (b *Bait) OnceLua(event string, handler *rt.Closure) *Listener {
|
||||
func (b *Bait) OnceLua(event string, handler *moonlight.Closure) *Listener {
|
||||
listener := &Listener{
|
||||
typ: luaListener,
|
||||
once: true,
|
||||
|
|
|
@ -36,19 +36,17 @@ import (
|
|||
"hilbish/moonlight"
|
||||
"hilbish/util"
|
||||
"hilbish/golibs/bait"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
type Commander struct{
|
||||
Events *bait.Bait
|
||||
Commands map[string]*rt.Closure
|
||||
Commands map[string]*moonlight.Closure
|
||||
}
|
||||
|
||||
func New(rtm *moonlight.Runtime) *Commander {
|
||||
c := &Commander{
|
||||
Events: bait.New(rtm),
|
||||
Commands: make(map[string]*rt.Closure),
|
||||
Commands: make(map[string]*moonlight.Closure),
|
||||
}
|
||||
|
||||
return c
|
||||
|
@ -119,7 +117,9 @@ func (c *Commander) cregistry(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moo
|
|||
registryLua := moonlight.NewTable()
|
||||
for cmdName, cmd := range c.Commands {
|
||||
cmdTbl := moonlight.NewTable()
|
||||
cmdTbl.SetField("exec", rt.FunctionValue(cmd))
|
||||
//cmdTbl.SetField("exec", moonlight.FunctionValue(cmd))
|
||||
print(cmd)
|
||||
cmdTbl.SetField("exec", moonlight.StringValue("placeholder"))
|
||||
|
||||
registryLua.SetField(cmdName, moonlight.TableValue(cmdTbl))
|
||||
}
|
||||
|
|
|
@ -55,8 +55,8 @@ func (f *fs) Loader(rtm *moonlight.Runtime) moonlight.Value {
|
|||
mod := moonlight.NewTable()
|
||||
rtm.SetExports(mod, exports)
|
||||
|
||||
mod.SetField("pathSep", rt.StringValue(string(os.PathSeparator)))
|
||||
mod.SetField("pathListSep", rt.StringValue(string(os.PathListSeparator)))
|
||||
mod.SetField("pathSep", moonlight.StringValue(string(os.PathSeparator)))
|
||||
mod.SetField("pathListSep", moonlight.StringValue(string(os.PathListSeparator)))
|
||||
|
||||
return moonlight.TableValue(mod)
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ func (f *fs) freaddir(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Co
|
|||
return nil, err
|
||||
}
|
||||
for i, entry := range dirEntries {
|
||||
names.Set(rt.IntValue(int64(i + 1)), rt.StringValue(entry.Name()))
|
||||
names.Set(moonlight.IntValue(int64(i + 1)), moonlight.StringValue(entry.Name()))
|
||||
}
|
||||
|
||||
return mlr.PushNext1(c, moonlight.TableValue(names)), nil
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
|
||||
"hilbish/moonlight"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
|
@ -37,8 +36,8 @@ func termsize(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, erro
|
|||
}
|
||||
|
||||
dimensions := moonlight.NewTable()
|
||||
dimensions.Set(rt.StringValue("width"), rt.IntValue(int64(w)))
|
||||
dimensions.Set(rt.StringValue("height"), rt.IntValue(int64(h)))
|
||||
dimensions.SetField("width", moonlight.IntValue(int64(w)))
|
||||
dimensions.SetField("height", moonlight.IntValue(int64(h)))
|
||||
|
||||
return mlr.PushNext1(c, moonlight.TableValue(dimensions)), nil
|
||||
}
|
||||
|
|
18
history.go
18
history.go
|
@ -7,17 +7,17 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"hilbish/moonlight"
|
||||
)
|
||||
|
||||
type luaHistory struct {}
|
||||
|
||||
func (h *luaHistory) Write(line string) (int, error) {
|
||||
histWrite := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("add"))
|
||||
ln, err := l.Call1(histWrite, rt.StringValue(line))
|
||||
histWrite := hshMod.Get(moonlight.StringValue("history")).AsTable().Get(moonlight.StringValue("add"))
|
||||
ln, err := l.Call1(histWrite, moonlight.StringValue(line))
|
||||
|
||||
var num int64
|
||||
if ln.Type() == rt.IntType {
|
||||
if ln.Type() == moonlight.IntType {
|
||||
num = ln.AsInt()
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,11 @@ 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 := l.Call1(histGet, rt.IntValue(int64(idx)))
|
||||
histGet := hshMod.Get(moonlight.StringValue("history")).AsTable().Get(moonlight.StringValue("get"))
|
||||
lcmd, err := l.Call1(histGet, moonlight.IntValue(int64(idx)))
|
||||
|
||||
var cmd string
|
||||
if lcmd.Type() == rt.StringType {
|
||||
if lcmd.Type() == moonlight.StringType {
|
||||
cmd = lcmd.AsString()
|
||||
}
|
||||
|
||||
|
@ -37,11 +37,11 @@ func (h *luaHistory) GetLine(idx int) (string, error) {
|
|||
}
|
||||
|
||||
func (h *luaHistory) Len() int {
|
||||
histSize := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("size"))
|
||||
histSize := hshMod.Get(moonlight.StringValue("history")).AsTable().Get(moonlight.StringValue("size"))
|
||||
ln, _ := l.Call1(histSize)
|
||||
|
||||
var num int64
|
||||
if ln.Type() == rt.IntType {
|
||||
if ln.Type() == moonlight.IntType {
|
||||
num = ln.AsInt()
|
||||
}
|
||||
|
||||
|
|
4
job.go
4
job.go
|
@ -261,7 +261,7 @@ func (j *jobHandler) add(cmd string, args []string, path string) *job {
|
|||
stdout: &bytes.Buffer{},
|
||||
stderr: &bytes.Buffer{},
|
||||
}
|
||||
jb.ud = jobUserData(jb)
|
||||
//jb.ud = jobUserData(jb)
|
||||
|
||||
j.jobs[j.latestID] = jb
|
||||
hooks.Emit("job.add", rt.UserDataValue(jb.ud))
|
||||
|
@ -389,10 +389,12 @@ func valueToJob(val rt.Value) (*job, bool) {
|
|||
return j, ok
|
||||
}
|
||||
|
||||
/*
|
||||
func jobUserData(j *job) *rt.UserData {
|
||||
jobMeta := l.UnderlyingRuntime().Registry(jobMetaKey)
|
||||
return rt.NewUserData(j, jobMeta.AsTable())
|
||||
}
|
||||
*/
|
||||
|
||||
// #interface jobs
|
||||
// get(id) -> @Job
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
//go:build !midnight
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"hilbish/moonlight"
|
||||
)
|
||||
|
||||
func handleLua(input string) (string, uint8, error) {
|
||||
cmdString := aliases.Resolve(input)
|
||||
// First try to load input, essentially compiling to bytecode
|
||||
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 {
|
||||
if perr, ok := lerr.Cause.(*parse.Error); ok {
|
||||
print(perr.Pos.Line == parse.EOF)
|
||||
}
|
||||
}
|
||||
*/
|
||||
return cmdString, 125, err
|
||||
}
|
||||
// And if there's no syntax errors and -n isnt provided, run
|
||||
if !noexecute {
|
||||
if chunk != nil {
|
||||
_, err = l.Call1(rt.FunctionValue(chunk))
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
return cmdString, 0, nil
|
||||
}
|
||||
|
||||
return cmdString, 125, err
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
//go:build midnight
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
func handleLua(input string) (string, uint8, error) {
|
||||
return "", 7, errors.New("lua input in midnight placeholder")
|
||||
}
|
6
main.go
6
main.go
|
@ -170,12 +170,12 @@ func main() {
|
|||
}
|
||||
|
||||
if getopt.NArgs() > 0 {
|
||||
luaArgs := rt.NewTable()
|
||||
luaArgs := moonlight.NewTable()
|
||||
for i, arg := range getopt.Args() {
|
||||
luaArgs.Set(rt.IntValue(int64(i)), rt.StringValue(arg))
|
||||
luaArgs.Set(moonlight.IntValue(int64(i)), moonlight.StringValue(arg))
|
||||
}
|
||||
|
||||
l.GlobalTable().SetField("args", rt.TableValue(luaArgs))
|
||||
l.GlobalTable().SetField("args", moonlight.TableValue(luaArgs))
|
||||
err := l.DoFile(getopt.Arg(0))
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
//go:build midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Callable interface{
|
||||
Continuation(*Runtime, Cont) Cont
|
||||
}
|
||||
|
||||
type Closure struct{
|
||||
refIdx int // so since we cant store the actual lua closure,
|
||||
// we need a index to the ref in the lua registry... or something like that.
|
||||
}
|
||||
|
||||
func (mlr *Runtime) ClosureArg(c *GoCont, num int) (*Closure, error) {
|
||||
fmt.Println("type at ", num, "is", mlr.state.LTypename(num))
|
||||
|
||||
return &Closure{
|
||||
refIdx: -1,
|
||||
}, nil
|
||||
}
|
||||
|
||||
/*
|
||||
func (c *Closure) Continuation(mlr *Runtime, c Cont) Cont {
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,12 @@
|
|||
//go:build midnight
|
||||
package moonlight
|
||||
|
||||
type GoCont struct{
|
||||
vals []Value
|
||||
f GoFunctionFunc
|
||||
}
|
||||
type Cont interface{}
|
||||
|
||||
func (gc *GoCont) Next() Cont {
|
||||
return gc
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
|
@ -8,6 +9,7 @@ type GoCont struct{
|
|||
cont *rt.GoCont
|
||||
thread *rt.Thread
|
||||
}
|
||||
|
||||
type Cont = rt.Cont
|
||||
type Closure = rt.Closure
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package moonlight
|
||||
|
||||
type Export struct{
|
||||
Function GoToLuaFunc
|
||||
ArgNum int
|
||||
Variadic bool
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
//go:build midnight
|
||||
package moonlight
|
||||
|
||||
func (mlr *Runtime) SetExports(tbl *Table, exports map[string]Export) {
|
||||
for name, export := range exports {
|
||||
tbl.SetField(name, FunctionValue(mlr.GoFunction(export.Function)))
|
||||
}
|
||||
}
|
|
@ -1,11 +1,6 @@
|
|||
//go:build !midnight
|
||||
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,61 @@
|
|||
//go:build midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aarzilli/golua/lua"
|
||||
)
|
||||
|
||||
type GoFunctionFunc struct{
|
||||
cf lua.LuaGoFunction
|
||||
}
|
||||
|
||||
func (gf GoFunctionFunc) Continuation(mlr *Runtime, c Cont) Cont {
|
||||
return &GoCont{
|
||||
f: gf,
|
||||
vals: []Value{},
|
||||
}
|
||||
}
|
||||
|
||||
func (mlr *Runtime) CheckNArgs(c *GoCont, num int) error {
|
||||
args := mlr.state.GetTop()
|
||||
if args < num {
|
||||
return fmt.Errorf("%d arguments needed", num)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mlr *Runtime) Check1Arg(c *GoCont) error {
|
||||
return mlr.CheckNArgs(c, 1)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) StringArg(c *GoCont, num int) (string, error) {
|
||||
return mlr.state.CheckString(num + 1), nil
|
||||
}
|
||||
|
||||
func (mlr *Runtime) Arg(c *GoCont, num int) Value {
|
||||
return c.vals[num]
|
||||
}
|
||||
|
||||
func (mlr *Runtime) GoFunction(fun GoToLuaFunc) GoFunctionFunc {
|
||||
return GoFunctionFunc{
|
||||
cf: func(L *lua.State) int {
|
||||
cont, err := fun(mlr, &GoCont{})
|
||||
if err != nil {
|
||||
L.RaiseError(err.Error())
|
||||
return 0
|
||||
}
|
||||
|
||||
for _, val := range cont.(*GoCont).vals {
|
||||
switch Type(val) {
|
||||
case StringType:
|
||||
L.PushString(val.AsString())
|
||||
}
|
||||
}
|
||||
|
||||
return len(cont.(*GoCont).vals)
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
|
@ -26,7 +27,7 @@ func (mlr *Runtime) Arg(c *GoCont, num int) Value {
|
|||
return c.cont.Arg(num)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) GoFunction(fun GoToLuaFunc) rt.GoFunctionFunc {
|
||||
func (mlr *Runtime) GoFunction(fun GoToLuaFunc) GoFunctionFunc {
|
||||
return func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
gocont := GoCont{
|
||||
cont: c,
|
||||
|
@ -35,7 +36,3 @@ func (mlr *Runtime) GoFunction(fun GoToLuaFunc) rt.GoFunctionFunc {
|
|||
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,21 @@
|
|||
//go:build midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
"github.com/aarzilli/golua/lua"
|
||||
)
|
||||
|
||||
type Loader func(*Runtime) Value
|
||||
|
||||
func (mlr *Runtime) LoadLibrary(ldr Loader, name string) {
|
||||
cluaLoader := func (L *lua.State) int {
|
||||
mlr.pushToState(ldr(mlr))
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
mlr.state.GetGlobal("package")
|
||||
mlr.state.GetField(-1, "preload")
|
||||
mlr.state.PushGoFunction(cluaLoader)
|
||||
mlr.state.SetField(-2, name)
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
//go:build midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
"github.com/aarzilli/golua/lua"
|
||||
)
|
||||
|
||||
type Runtime struct{
|
||||
state *lua.State
|
||||
}
|
||||
|
||||
func NewRuntime() *Runtime {
|
||||
L := lua.NewState()
|
||||
L.OpenLibs()
|
||||
|
||||
return &Runtime{
|
||||
state: L,
|
||||
}
|
||||
}
|
||||
|
||||
func (mlr *Runtime) PushNext1(c *GoCont, v Value) Cont {
|
||||
c.vals = []Value{v}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (mlr *Runtime) Call1(f Value, args ...Value) (Value, error) {
|
||||
for _, arg := range args {
|
||||
mlr.pushToState(arg)
|
||||
}
|
||||
|
||||
if f.refIdx > 0 {
|
||||
mlr.state.RawGeti(lua.LUA_REGISTRYINDEX, f.refIdx)
|
||||
mlr.state.Call(len(args), 1)
|
||||
}
|
||||
|
||||
if mlr.state.GetTop() == 0 {
|
||||
return NilValue, nil
|
||||
}
|
||||
|
||||
return NilValue, nil
|
||||
}
|
||||
|
||||
func (mlr *Runtime) pushToState(v Value) {
|
||||
switch v.Type() {
|
||||
case NilType: mlr.state.PushNil()
|
||||
case StringType: mlr.state.PushString(v.AsString())
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
|
@ -42,3 +43,7 @@ func (mlr *Runtime) Push(c *GoCont, v Value) {
|
|||
func (mlr *Runtime) PushNext1(c *GoCont, v Value) Cont {
|
||||
return c.cont.PushingNext1(c.thread.Runtime, v)
|
||||
}
|
||||
|
||||
func (mlr *Runtime) Call1(val Value, args ...Value) (Value, error) {
|
||||
return rt.Call1(mlr.rt.MainThread(), val, args...)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
//go:build midnight
|
||||
package moonlight
|
||||
|
||||
//import "github.com/aarzilli/golua/lua"
|
||||
|
||||
type Table struct{
|
||||
refIdx int
|
||||
}
|
||||
|
||||
func NewTable() *Table {
|
||||
return &Table{
|
||||
refIdx: -1,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Table) Get(val Value) Value {
|
||||
return NilValue
|
||||
}
|
||||
|
||||
func (t *Table) SetField(key string, value Value) {
|
||||
}
|
||||
|
||||
func (t *Table) Set(key Value, value Value) {
|
||||
}
|
||||
|
||||
func ForEach(tbl *Table, cb func(key Value, val Value)) {
|
||||
}
|
||||
|
||||
func (mlr *Runtime) GlobalTable() *Table {
|
||||
return &Table{
|
||||
refIdx: -1,
|
||||
}
|
||||
}
|
||||
|
||||
func ToTable(v Value) *Table {
|
||||
return &Table{
|
||||
refIdx: -1,
|
||||
}
|
||||
}
|
||||
|
||||
func TryTable(v Value) (*Table, bool) {
|
||||
return nil, false
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
|
@ -50,3 +51,9 @@ func convertToMoonlightTable(t *rt.Table) *Table {
|
|||
lt: t,
|
||||
}
|
||||
}
|
||||
|
||||
func TryTable(v Value) (*Table, bool) {
|
||||
t, ok := v.TryTable()
|
||||
|
||||
return convertToMoonlightTable(t), ok
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
//go:build midnight
|
||||
package moonlight
|
||||
|
||||
func (mlr *Runtime) DoString(code string) (Value, error) {
|
||||
err := mlr.state.DoString(code)
|
||||
|
||||
return NilValue, err
|
||||
}
|
||||
|
||||
func (mlr *Runtime) DoFile(filename string) error {
|
||||
return mlr.state.DoFile(filename)
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
//go:build !midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
|
@ -9,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
// DoString runs the code string in the Lua runtime.
|
||||
func (mlr *Runtime) DoString(code string) (rt.Value, error) {
|
||||
func (mlr *Runtime) DoString(code string) (Value, error) {
|
||||
chunk, err := mlr.rt.CompileAndLoadLuaChunk("<string>", []byte(code), rt.TableValue(mlr.rt.GlobalEnv()))
|
||||
var ret rt.Value
|
||||
if chunk != nil {
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
//go:build midnight
|
||||
package moonlight
|
||||
|
||||
type Value struct{
|
||||
iface interface{}
|
||||
relIdx int
|
||||
refIdx int
|
||||
}
|
||||
|
||||
var NilValue = Value{nil, -1, -1}
|
||||
|
||||
type ValueType uint8
|
||||
const (
|
||||
NilType ValueType = iota
|
||||
BoolType
|
||||
IntType
|
||||
StringType
|
||||
TableType
|
||||
FunctionType
|
||||
UnknownType
|
||||
)
|
||||
|
||||
func Type(v Value) ValueType {
|
||||
return v.Type()
|
||||
}
|
||||
|
||||
func BoolValue(b bool) Value {
|
||||
return Value{iface: b}
|
||||
}
|
||||
|
||||
func IntValue(i int64) Value {
|
||||
return Value{iface: i}
|
||||
}
|
||||
|
||||
func StringValue(str string) Value {
|
||||
return Value{iface: str}
|
||||
}
|
||||
|
||||
func TableValue(t *Table) Value {
|
||||
return Value{iface: t}
|
||||
}
|
||||
|
||||
func FunctionValue(f Callable) Value {
|
||||
return NilValue
|
||||
}
|
||||
|
||||
func AsValue(i interface{}) Value {
|
||||
if i == nil {
|
||||
return NilValue
|
||||
}
|
||||
|
||||
switch v := i.(type) {
|
||||
case bool: return BoolValue(v)
|
||||
case int64: return IntValue(v)
|
||||
case string: return StringValue(v)
|
||||
case *Table: return TableValue(v)
|
||||
case Value: return v
|
||||
default:
|
||||
return Value{iface: i}
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) Type() ValueType {
|
||||
if v.iface == nil {
|
||||
return NilType
|
||||
}
|
||||
|
||||
switch v.iface.(type) {
|
||||
case bool: return BoolType
|
||||
case int: return IntType
|
||||
case string: return StringType
|
||||
case *Table: return TableType
|
||||
case *Closure: return FunctionType
|
||||
default: return UnknownType
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) AsInt() int64 {
|
||||
return v.iface.(int64)
|
||||
}
|
||||
|
||||
func (v Value) AsString() string {
|
||||
if v.Type() != StringType {
|
||||
panic("value type was not string")
|
||||
}
|
||||
|
||||
return v.iface.(string)
|
||||
}
|
||||
|
||||
func (v Value) AsTable() *Table {
|
||||
panic("Value.AsTable unimplemented in midnight")
|
||||
}
|
||||
|
||||
func ToString(v Value) string {
|
||||
return v.AsString()
|
||||
}
|
||||
|
||||
func (v Value) TypeName() string {
|
||||
switch v.iface.(type) {
|
||||
case bool: return "bool"
|
||||
case int: return "number"
|
||||
case string: return "string"
|
||||
case *Table: return "table"
|
||||
default: return "<unknown type>"
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) TryBool() (n bool, ok bool) {
|
||||
n, ok = v.iface.(bool)
|
||||
return
|
||||
}
|
||||
|
||||
func (v Value) TryInt() (n int, ok bool) {
|
||||
n, ok = v.iface.(int)
|
||||
return
|
||||
}
|
||||
|
||||
func (v Value) TryString() (n string, ok bool) {
|
||||
n, ok = v.iface.(string)
|
||||
return
|
||||
}
|
|
@ -1,17 +1,25 @@
|
|||
//go:build !midnight
|
||||
package moonlight
|
||||
|
||||
import (
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
var NilValue = rt.NilValue
|
||||
|
||||
type Value = rt.Value
|
||||
type ValueType = rt.ValueType
|
||||
const (
|
||||
IntType = rt.IntType
|
||||
StringType = rt.StringType
|
||||
FunctionType = rt.FunctionType
|
||||
TableType = rt.TableType
|
||||
)
|
||||
|
||||
func Type(v Value) ValueType {
|
||||
return ValueType(v.Type())
|
||||
}
|
||||
|
||||
func StringValue(str string) Value {
|
||||
return rt.StringValue(str)
|
||||
}
|
||||
|
@ -28,10 +36,6 @@ func TableValue(t *Table) Value {
|
|||
return rt.TableValue(t.lt)
|
||||
}
|
||||
|
||||
func Type(v Value) ValueType {
|
||||
return ValueType(v.Type())
|
||||
}
|
||||
|
||||
func ToString(v Value) string {
|
||||
return v.AsString()
|
||||
}
|
||||
|
@ -39,3 +43,7 @@ func ToString(v Value) string {
|
|||
func ToTable(v Value) *Table {
|
||||
return convertToMoonlightTable(v.AsTable())
|
||||
}
|
||||
|
||||
func AsValue(v interface{}) Value {
|
||||
return rt.AsValue(v)
|
||||
}
|
||||
|
|
7
os.go
7
os.go
|
@ -4,7 +4,6 @@ import (
|
|||
"hilbish/moonlight"
|
||||
//"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/blackfireio/osinfo"
|
||||
)
|
||||
|
||||
|
@ -19,9 +18,9 @@ func hshosLoader() *moonlight.Table {
|
|||
info, _ := osinfo.GetOSInfo()
|
||||
mod := moonlight.NewTable()
|
||||
|
||||
mod.SetField("family", rt.StringValue(info.Family))
|
||||
mod.SetField("name", rt.StringValue(info.Name))
|
||||
mod.SetField("version", rt.StringValue(info.Version))
|
||||
mod.SetField("family", moonlight.StringValue(info.Family))
|
||||
mod.SetField("name", moonlight.StringValue(info.Name))
|
||||
mod.SetField("version", moonlight.StringValue(info.Version))
|
||||
|
||||
return mod
|
||||
}
|
||||
|
|
99
rl.go
99
rl.go
|
@ -5,6 +5,7 @@ import (
|
|||
"io"
|
||||
"strings"
|
||||
|
||||
"hilbish/moonlight"
|
||||
"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
|
@ -70,8 +71,8 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
|||
hooks.Emit("hilbish.vimAction", actionStr, args)
|
||||
}
|
||||
rl.HintText = func(line []rune, pos int) []rune {
|
||||
hinter := hshMod.Get(rt.StringValue("hinter"))
|
||||
retVal, err := l.Call1(hinter, rt.StringValue(string(line)), rt.IntValue(int64(pos)))
|
||||
hinter := hshMod.Get(moonlight.StringValue("hinter"))
|
||||
retVal, err := l.Call1(hinter, moonlight.StringValue(string(line)), moonlight.IntValue(int64(pos)))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return []rune{}
|
||||
|
@ -85,8 +86,8 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
|||
return []rune(hintText)
|
||||
}
|
||||
rl.SyntaxHighlighter = func(line []rune) string {
|
||||
highlighter := hshMod.Get(rt.StringValue("highlighter"))
|
||||
retVal, err := l.Call1(highlighter, rt.StringValue(string(line)))
|
||||
highlighter := hshMod.Get(moonlight.StringValue("highlighter"))
|
||||
retVal, err := l.Call1(highlighter, moonlight.StringValue(string(line)))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return string(line)
|
||||
|
@ -99,93 +100,7 @@ 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.UnderlyingRuntime().MainThread().CurrentCont(), 2, false)
|
||||
compHandle := hshMod.Get(rt.StringValue("completion")).AsTable().Get(rt.StringValue("handler"))
|
||||
err := rt.Call(l.UnderlyingRuntime().MainThread(), compHandle, []rt.Value{rt.StringValue(string(line)),
|
||||
rt.IntValue(int64(pos))}, term)
|
||||
|
||||
var compGroups []*readline.CompletionGroup
|
||||
if err != nil {
|
||||
return "", compGroups
|
||||
}
|
||||
|
||||
luaCompGroups := term.Get(0)
|
||||
luaPrefix := term.Get(1)
|
||||
|
||||
if luaCompGroups.Type() != rt.TableType {
|
||||
return "", compGroups
|
||||
}
|
||||
|
||||
groups := luaCompGroups.AsTable()
|
||||
// prefix is optional
|
||||
pfx, _ := luaPrefix.TryString()
|
||||
|
||||
util.ForEach(groups, func(key rt.Value, val rt.Value) {
|
||||
if key.Type() != rt.IntType || val.Type() != rt.TableType {
|
||||
return
|
||||
}
|
||||
|
||||
valTbl := val.AsTable()
|
||||
luaCompType := valTbl.Get(rt.StringValue("type"))
|
||||
luaCompItems := valTbl.Get(rt.StringValue("items"))
|
||||
|
||||
if luaCompType.Type() != rt.StringType || luaCompItems.Type() != rt.TableType {
|
||||
return
|
||||
}
|
||||
|
||||
items := []string{}
|
||||
itemDescriptions := make(map[string]string)
|
||||
|
||||
util.ForEach(luaCompItems.AsTable(), func(lkey rt.Value, lval rt.Value) {
|
||||
if keytyp := lkey.Type(); keytyp == rt.StringType {
|
||||
// ['--flag'] = {'description', '--flag-alias'}
|
||||
itemName, ok := lkey.TryString()
|
||||
vlTbl, okk := lval.TryTable()
|
||||
if !ok && !okk {
|
||||
// TODO: error
|
||||
return
|
||||
}
|
||||
|
||||
items = append(items, itemName)
|
||||
itemDescription, ok := vlTbl.Get(rt.IntValue(1)).TryString()
|
||||
if !ok {
|
||||
// TODO: error
|
||||
return
|
||||
}
|
||||
itemDescriptions[itemName] = itemDescription
|
||||
} else if keytyp == rt.IntType {
|
||||
vlStr, ok := lval.TryString()
|
||||
if !ok {
|
||||
// TODO: error
|
||||
return
|
||||
}
|
||||
items = append(items, vlStr)
|
||||
} else {
|
||||
// TODO: error
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
var dispType readline.TabDisplayType
|
||||
switch luaCompType.AsString() {
|
||||
case "grid": dispType = readline.TabDisplayGrid
|
||||
case "list": dispType = readline.TabDisplayList
|
||||
// need special cases, will implement later
|
||||
//case "map": dispType = readline.TabDisplayMap
|
||||
}
|
||||
|
||||
compGroups = append(compGroups, &readline.CompletionGroup{
|
||||
DisplayType: dispType,
|
||||
Descriptions: itemDescriptions,
|
||||
Suggestions: items,
|
||||
TrimSlash: false,
|
||||
NoSpace: true,
|
||||
})
|
||||
})
|
||||
|
||||
return pfx, compGroups
|
||||
}
|
||||
setupTabCompleter(rl)
|
||||
|
||||
return lr
|
||||
}
|
||||
|
@ -244,11 +159,13 @@ func (lr *lineReader) Resize() {
|
|||
// method of saving history.
|
||||
func (lr *lineReader) Loader(rtm *rt.Runtime) *rt.Table {
|
||||
lrLua := map[string]util.LuaExport{
|
||||
/*
|
||||
"add": {lr.luaAddHistory, 1, false},
|
||||
"all": {lr.luaAllHistory, 0, false},
|
||||
"clear": {lr.luaClearHistory, 0, false},
|
||||
"get": {lr.luaGetHistory, 1, false},
|
||||
"size": {lr.luaSize, 0, false},
|
||||
*/
|
||||
}
|
||||
|
||||
mod := rt.NewTable()
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
//go:build midnight
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/maxlandon/readline"
|
||||
)
|
||||
|
||||
func setupTabCompleter(rl *readline.Instance) {
|
||||
// TODO
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
//go:build !midnight
|
||||
package main
|
||||
|
||||
import (
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/maxlandon/readline"
|
||||
)
|
||||
|
||||
func setupTabCompleter(rl *readline.Instance) {
|
||||
rl.TabCompleter = func(line []rune, pos int, _ readline.DelayedTabContext) (string, []*readline.CompletionGroup) {
|
||||
term := rt.NewTerminationWith(l.UnderlyingRuntime().MainThread().CurrentCont(), 2, false)
|
||||
compHandle := hshMod.Get(rt.StringValue("completion")).AsTable().Get(rt.StringValue("handler"))
|
||||
err := rt.Call(l.UnderlyingRuntime().MainThread(), compHandle, []rt.Value{rt.StringValue(string(line)),
|
||||
rt.IntValue(int64(pos))}, term)
|
||||
|
||||
var compGroups []*readline.CompletionGroup
|
||||
if err != nil {
|
||||
return "", compGroups
|
||||
}
|
||||
|
||||
luaCompGroups := term.Get(0)
|
||||
luaPrefix := term.Get(1)
|
||||
|
||||
if luaCompGroups.Type() != rt.TableType {
|
||||
return "", compGroups
|
||||
}
|
||||
|
||||
groups := luaCompGroups.AsTable()
|
||||
// prefix is optional
|
||||
pfx, _ := luaPrefix.TryString()
|
||||
|
||||
util.ForEach(groups, func(key rt.Value, val rt.Value) {
|
||||
if key.Type() != rt.IntType || val.Type() != rt.TableType {
|
||||
return
|
||||
}
|
||||
|
||||
valTbl := val.AsTable()
|
||||
luaCompType := valTbl.Get(rt.StringValue("type"))
|
||||
luaCompItems := valTbl.Get(rt.StringValue("items"))
|
||||
|
||||
if luaCompType.Type() != rt.StringType || luaCompItems.Type() != rt.TableType {
|
||||
return
|
||||
}
|
||||
|
||||
items := []string{}
|
||||
itemDescriptions := make(map[string]string)
|
||||
|
||||
util.ForEach(luaCompItems.AsTable(), func(lkey rt.Value, lval rt.Value) {
|
||||
if keytyp := lkey.Type(); keytyp == rt.StringType {
|
||||
// ['--flag'] = {'description', '--flag-alias'}
|
||||
itemName, ok := lkey.TryString()
|
||||
vlTbl, okk := lval.TryTable()
|
||||
if !ok && !okk {
|
||||
// TODO: error
|
||||
return
|
||||
}
|
||||
|
||||
items = append(items, itemName)
|
||||
itemDescription, ok := vlTbl.Get(rt.IntValue(1)).TryString()
|
||||
if !ok {
|
||||
// TODO: error
|
||||
return
|
||||
}
|
||||
itemDescriptions[itemName] = itemDescription
|
||||
} else if keytyp == rt.IntType {
|
||||
vlStr, ok := lval.TryString()
|
||||
if !ok {
|
||||
// TODO: error
|
||||
return
|
||||
}
|
||||
items = append(items, vlStr)
|
||||
} else {
|
||||
// TODO: error
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
var dispType readline.TabDisplayType
|
||||
switch luaCompType.AsString() {
|
||||
case "grid": dispType = readline.TabDisplayGrid
|
||||
case "list": dispType = readline.TabDisplayList
|
||||
// need special cases, will implement later
|
||||
//case "map": dispType = readline.TabDisplayMap
|
||||
}
|
||||
|
||||
compGroups = append(compGroups, &readline.CompletionGroup{
|
||||
DisplayType: dispType,
|
||||
Descriptions: itemDescriptions,
|
||||
Suggestions: items,
|
||||
TrimSlash: false,
|
||||
NoSpace: true,
|
||||
})
|
||||
})
|
||||
|
||||
return pfx, compGroups
|
||||
}
|
||||
}
|
|
@ -2,8 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"hilbish/moonlight"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
// #interface runner
|
||||
|
@ -86,13 +84,13 @@ func shRunner(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, erro
|
|||
}
|
||||
|
||||
_, exitCode, cont, err := execSh(aliases.Resolve(cmd))
|
||||
var luaErr moonlight.Value = rt.NilValue
|
||||
var luaErr moonlight.Value = moonlight.NilValue
|
||||
if err != nil {
|
||||
luaErr = moonlight.StringValue(err.Error())
|
||||
}
|
||||
runnerRet := moonlight.NewTable()
|
||||
runnerRet.SetField("input", moonlight.StringValue(cmd))
|
||||
runnerRet.SetField("exitCode", moonlight.IntValue(int(exitCode)))
|
||||
runnerRet.SetField("exitCode", moonlight.IntValue(int64(exitCode)))
|
||||
runnerRet.SetField("continue", moonlight.BoolValue(cont))
|
||||
runnerRet.SetField("err", luaErr)
|
||||
|
||||
|
@ -114,13 +112,13 @@ func luaRunner(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, err
|
|||
}
|
||||
|
||||
input, exitCode, err := handleLua(cmd)
|
||||
var luaErr moonlight.Value = rt.NilValue
|
||||
var luaErr moonlight.Value = moonlight.NilValue
|
||||
if err != nil {
|
||||
luaErr = moonlight.StringValue(err.Error())
|
||||
}
|
||||
runnerRet := moonlight.NewTable()
|
||||
runnerRet.SetField("input", moonlight.StringValue(input))
|
||||
runnerRet.SetField("exitCode", moonlight.IntValue(int(exitCode)))
|
||||
runnerRet.SetField("exitCode", moonlight.IntValue(int64(exitCode)))
|
||||
runnerRet.SetField("err", luaErr)
|
||||
|
||||
|
||||
|
|
6
sink.go
6
sink.go
|
@ -220,7 +220,7 @@ func newSinkInput(r io.Reader) *sink {
|
|||
s := &sink{
|
||||
reader: bufio.NewReader(r),
|
||||
}
|
||||
s.ud = sinkUserData(s)
|
||||
//s.ud = sinkUserData(s)
|
||||
|
||||
if f, ok := r.(*os.File); ok {
|
||||
s.file = f
|
||||
|
@ -234,7 +234,7 @@ func newSinkOutput(w io.Writer) *sink {
|
|||
writer: bufio.NewWriter(w),
|
||||
autoFlush: true,
|
||||
}
|
||||
s.ud = sinkUserData(s)
|
||||
//s.ud = sinkUserData(s)
|
||||
|
||||
return s
|
||||
}
|
||||
|
@ -258,7 +258,9 @@ func valueToSink(val rt.Value) (*sink, bool) {
|
|||
return s, ok
|
||||
}
|
||||
|
||||
/*
|
||||
func sinkUserData(s *sink) *rt.UserData {
|
||||
sinkMeta := l.UnderlyingRuntime().Registry(sinkMetaKey)
|
||||
return rt.NewUserData(s, sinkMeta.AsTable())
|
||||
}
|
||||
*/
|
||||
|
|
10
timer.go
10
timer.go
|
@ -2,10 +2,12 @@ package main
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
// "fmt"
|
||||
// "os"
|
||||
"time"
|
||||
|
||||
// "hilbish/moonlight"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
|
@ -47,7 +49,8 @@ func (t *timer) start() error {
|
|||
for {
|
||||
select {
|
||||
case <-t.ticker.C:
|
||||
_, err := l.Call1(rt.FunctionValue(t.fun))
|
||||
/*
|
||||
_, err := l.Call1(moonlight.FunctionValue(t.fun))
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error in function:\n", err)
|
||||
t.stop()
|
||||
|
@ -56,6 +59,7 @@ func (t *timer) start() error {
|
|||
if t.typ == timerTimeout {
|
||||
t.stop()
|
||||
}
|
||||
*/
|
||||
case <-t.channel:
|
||||
t.ticker.Stop()
|
||||
return
|
||||
|
|
|
@ -48,7 +48,7 @@ func (th *timersModule) create(typ timerType, dur time.Duration, fun *rt.Closure
|
|||
th: th,
|
||||
id: th.latestID,
|
||||
}
|
||||
t.ud = timerUserData(t)
|
||||
//t.ud = timerUserData(t)
|
||||
|
||||
th.timers[th.latestID] = t
|
||||
|
||||
|
@ -144,6 +144,7 @@ func (th *timersModule) loader() *moonlight.Table {
|
|||
}
|
||||
l.SetExports(timerMethods, timerFuncs)
|
||||
|
||||
/*
|
||||
timerMeta := rt.NewTable()
|
||||
timerIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
ti, _ := timerArg(c, 0)
|
||||
|
@ -168,6 +169,7 @@ func (th *timersModule) loader() *moonlight.Table {
|
|||
|
||||
timerMeta.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(timerIndex, "__index", 2, false)))
|
||||
l.UnderlyingRuntime().SetRegistry(timerMetaKey, rt.TableValue(timerMeta))
|
||||
*/
|
||||
|
||||
thExports := map[string]moonlight.Export{
|
||||
/*
|
||||
|
@ -179,8 +181,8 @@ func (th *timersModule) loader() *moonlight.Table {
|
|||
luaTh := moonlight.NewTable()
|
||||
l.SetExports(luaTh, thExports)
|
||||
|
||||
luaTh.SetField("INTERVAL", rt.IntValue(0))
|
||||
luaTh.SetField("TIMEOUT", rt.IntValue(1))
|
||||
luaTh.SetField("INTERVAL", moonlight.IntValue(0))
|
||||
luaTh.SetField("TIMEOUT", moonlight.IntValue(1))
|
||||
|
||||
return luaTh
|
||||
}
|
||||
|
@ -204,7 +206,9 @@ func valueToTimer(val rt.Value) (*timer, bool) {
|
|||
return j, ok
|
||||
}
|
||||
|
||||
/*
|
||||
func timerUserData(j *timer) *rt.UserData {
|
||||
timerMeta := l.UnderlyingRuntime().Registry(timerMetaKey)
|
||||
return rt.NewUserData(j, timerMeta.AsTable())
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -2,9 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"hilbish/moonlight"
|
||||
//"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
)
|
||||
|
||||
// #interface userDir
|
||||
|
@ -17,8 +14,8 @@ import (
|
|||
func userDirLoader() *moonlight.Table {
|
||||
mod := moonlight.NewTable()
|
||||
|
||||
mod.SetField("config", rt.StringValue(confDir))
|
||||
mod.SetField("data", rt.StringValue(userDataDir))
|
||||
mod.SetField("config", moonlight.StringValue(confDir))
|
||||
mod.SetField("data", moonlight.StringValue(userDataDir))
|
||||
|
||||
return mod
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@ type LuaExport struct {
|
|||
|
||||
// SetExports puts the Lua function exports in the table.
|
||||
func SetExports(rtm *rt.Runtime, tbl *rt.Table, exports map[string]LuaExport) {
|
||||
/*
|
||||
for name, export := range exports {
|
||||
rtm.SetEnvGoFunc(tbl, name, export.Function, export.ArgNum, export.Variadic)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue