mirror of https://github.com/Hilbis/Hilbish
Merge 2eb1ea398f
into 8a1614ab59
commit
6508fcfba2
|
@ -10,10 +10,11 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: ${{ matrix.goos }}-${{ matrix.goarch }}
|
name: ${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.midnight == 'true' && ' (Midnight Edition)' || ''}}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
midnight: [false, true]
|
||||||
goos: [linux, windows, darwin]
|
goos: [linux, windows, darwin]
|
||||||
goarch: ["386", amd64, arm64]
|
goarch: ["386", amd64, arm64]
|
||||||
exclude:
|
exclude:
|
||||||
|
@ -33,11 +34,11 @@ jobs:
|
||||||
- name: Download Task
|
- name: Download Task
|
||||||
run: 'sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d'
|
run: 'sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d'
|
||||||
- name: Build
|
- 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
|
- uses: actions/upload-artifact@v4
|
||||||
if: matrix.goos == 'windows'
|
if: matrix.goos == 'windows'
|
||||||
with:
|
with:
|
||||||
name: hilbish-${{ matrix.goos }}-${{ matrix.goarch }}
|
name: hilbish${{ matrix.midnight == 'true' && '-midnight-edition' || ''}}-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||||
path: |
|
path: |
|
||||||
hilbish.exe
|
hilbish.exe
|
||||||
LICENSE
|
LICENSE
|
||||||
|
@ -51,7 +52,7 @@ jobs:
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
if: matrix.goos != 'windows'
|
if: matrix.goos != 'windows'
|
||||||
with:
|
with:
|
||||||
name: hilbish-${{ matrix.goos }}-${{ matrix.goarch }}
|
name: hilbish${{ matrix.midnight == 'true' && '-midnight-edition' || ''}}-${{ matrix.goos }}-${{ matrix.goarch }}
|
||||||
path: |
|
path: |
|
||||||
hilbish
|
hilbish
|
||||||
LICENSE
|
LICENSE
|
||||||
|
|
30
README.md
30
README.md
|
@ -1,7 +1,4 @@
|
||||||
> [!TIP]
|
<img src="./assets/hilbish-logo-and-text-midnight-edition.png" width=512><br>
|
||||||
> Check out [Hilbish: Midnight Edition](https://github.com/Rosettea/Hilbish/tree/midnight-edition) if you want to use C Lua, LuaJIT or anything related!
|
|
||||||
|
|
||||||
<img src="./assets/hilbish-logo-and-text.png" width=512><br>
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
🌓 The Moon-powered shell! A comfy and extensible shell for Lua fans! 🌺 ✨
|
🌓 The Moon-powered shell! A comfy and extensible shell for Lua fans! 🌺 ✨
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
@ -12,6 +9,27 @@
|
||||||
<a href="https://discord.gg/3PDdcQz"><img alt="Discord" src="https://img.shields.io/discord/732357621503229962?color=blue&style=flat-square"></a>
|
<a href="https://discord.gg/3PDdcQz"><img alt="Discord" src="https://img.shields.io/discord/732357621503229962?color=blue&style=flat-square"></a>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
# Midnight Edition
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> This is a **HEAVILY** WORK IN PROGRESS branch which makes a lot of internal changes.
|
||||||
|
Functionality **will** be missing if you use this branch,
|
||||||
|
and you may see crashes too. Tread lightly.
|
||||||
|
|
||||||
|
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
|
||||||
|
is to offer Midnight Edition as a separate, "not as supported" build for users
|
||||||
|
that *really* want to access a certain library made for C Lua or want the
|
||||||
|
most performance with their Lua code.
|
||||||
|
|
||||||
|
**The standard edition, which is all native Go,
|
||||||
|
will always be more supported than Midnight Edition.**
|
||||||
|
|
||||||
|
# Back the original README
|
||||||
|
|
||||||
Hilbish is an extensible shell designed to be highly customizable.
|
Hilbish is an extensible shell designed to be highly customizable.
|
||||||
It is configured in Lua and provides a good range of features.
|
It is configured in Lua and provides a good range of features.
|
||||||
It aims to be easy to use for anyone but powerful enough for
|
It aims to be easy to use for anyone but powerful enough for
|
||||||
|
@ -53,13 +71,13 @@ go get -d ./...
|
||||||
|
|
||||||
To build, run:
|
To build, run:
|
||||||
```
|
```
|
||||||
task
|
go-task
|
||||||
```
|
```
|
||||||
|
|
||||||
Or, if you want a stable branch, run these commands:
|
Or, if you want a stable branch, run these commands:
|
||||||
```
|
```
|
||||||
git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
|
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.
|
After you did all that, run `sudo task install` to install Hilbish globally.
|
||||||
|
|
|
@ -10,6 +10,8 @@ vars:
|
||||||
LIBDIR: '{{default .libdir__ .LIBDIR}}'
|
LIBDIR: '{{default .libdir__ .LIBDIR}}'
|
||||||
goflags__: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}}"'
|
goflags__: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}}"'
|
||||||
GOFLAGS: '{{default .goflags__ .GOFLAGS}}'
|
GOFLAGS: '{{default .goflags__ .GOFLAGS}}'
|
||||||
|
lua__: 'lua'
|
||||||
|
LUA: '{{default .lua__ .LUA}}'
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
default:
|
default:
|
||||||
|
@ -24,6 +26,12 @@ tasks:
|
||||||
vars:
|
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)"'
|
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:
|
build:
|
||||||
cmds:
|
cmds:
|
||||||
- go build {{.GOFLAGS}}
|
- go build {{.GOFLAGS}}
|
||||||
|
|
|
@ -97,10 +97,12 @@ func (a *aliasModule) Resolve(cmdstr string) string {
|
||||||
func (a *aliasModule) Loader(rtm *rt.Runtime) *rt.Table {
|
func (a *aliasModule) Loader(rtm *rt.Runtime) *rt.Table {
|
||||||
// create a lua module with our functions
|
// create a lua module with our functions
|
||||||
hshaliasesLua := map[string]util.LuaExport{
|
hshaliasesLua := map[string]util.LuaExport{
|
||||||
|
/*
|
||||||
"add": util.LuaExport{hlalias, 2, false},
|
"add": util.LuaExport{hlalias, 2, false},
|
||||||
"list": util.LuaExport{a.luaList, 0, false},
|
"list": util.LuaExport{a.luaList, 0, false},
|
||||||
"del": util.LuaExport{a.luaDelete, 1, false},
|
"del": util.LuaExport{a.luaDelete, 1, false},
|
||||||
"resolve": util.LuaExport{a.luaResolve, 1, false},
|
"resolve": util.LuaExport{a.luaResolve, 1, false},
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
mod := rt.NewTable()
|
mod := rt.NewTable()
|
||||||
|
|
183
api.go
183
api.go
|
@ -15,56 +15,58 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
//"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
//"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
//"syscall"
|
||||||
"time"
|
//"time"
|
||||||
|
|
||||||
"hilbish/util"
|
//"hilbish/util"
|
||||||
|
"hilbish/moonlight"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
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/arnodel/golua/lib/iolib"
|
||||||
"github.com/maxlandon/readline"
|
"github.com/maxlandon/readline"
|
||||||
"mvdan.cc/sh/v3/interp"
|
"mvdan.cc/sh/v3/interp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var exports = map[string]util.LuaExport{
|
var hshMod *moonlight.Table
|
||||||
|
|
||||||
|
func hilbishLoader(mlr *moonlight.Runtime) moonlight.Value {
|
||||||
|
var exports = map[string]moonlight.Export{
|
||||||
"alias": {hlalias, 2, false},
|
"alias": {hlalias, 2, false},
|
||||||
"appendPath": {hlappendPath, 1, false},
|
"appendPath": {hlappendPath, 1, false},
|
||||||
|
/*
|
||||||
"complete": {hlcomplete, 2, false},
|
"complete": {hlcomplete, 2, false},
|
||||||
|
*/
|
||||||
"cwd": {hlcwd, 0, false},
|
"cwd": {hlcwd, 0, false},
|
||||||
|
/*
|
||||||
"exec": {hlexec, 1, false},
|
"exec": {hlexec, 1, false},
|
||||||
|
*/
|
||||||
"runnerMode": {hlrunnerMode, 1, false},
|
"runnerMode": {hlrunnerMode, 1, false},
|
||||||
|
/*
|
||||||
"goro": {hlgoro, 1, true},
|
"goro": {hlgoro, 1, true},
|
||||||
"highlighter": {hlhighlighter, 1, false},
|
"highlighter": {hlhighlighter, 1, false},
|
||||||
"hinter": {hlhinter, 1, false},
|
"hinter": {hlhinter, 1, false},
|
||||||
"multiprompt": {hlmultiprompt, 1, false},
|
"multiprompt": {hlmultiprompt, 1, false},
|
||||||
"prependPath": {hlprependPath, 1, false},
|
"prependPath": {hlprependPath, 1, false},
|
||||||
|
*/
|
||||||
"prompt": {hlprompt, 1, true},
|
"prompt": {hlprompt, 1, true},
|
||||||
|
/*
|
||||||
"inputMode": {hlinputMode, 1, false},
|
"inputMode": {hlinputMode, 1, false},
|
||||||
"interval": {hlinterval, 2, false},
|
"interval": {hlinterval, 2, false},
|
||||||
"read": {hlread, 1, false},
|
"read": {hlread, 1, false},
|
||||||
"run": {hlrun, 1, true},
|
"run": {hlrun, 1, true},
|
||||||
"timeout": {hltimeout, 2, false},
|
"timeout": {hltimeout, 2, false},
|
||||||
"which": {hlwhich, 1, false},
|
"which": {hlwhich, 1, false},
|
||||||
}
|
*/
|
||||||
|
}
|
||||||
var hshMod *rt.Table
|
hshMod = moonlight.NewTable()
|
||||||
var hilbishLoader = packagelib.Loader{
|
mlr.SetExports(hshMod, exports)
|
||||||
Load: hilbishLoad,
|
|
||||||
Name: "hilbish",
|
|
||||||
}
|
|
||||||
|
|
||||||
func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) {
|
|
||||||
mod := rt.NewTable()
|
|
||||||
|
|
||||||
util.SetExports(rtm, mod, exports)
|
|
||||||
hshMod = mod
|
|
||||||
|
|
||||||
host, _ := os.Hostname()
|
host, _ := os.Hostname()
|
||||||
username := curuser.Username
|
username := curuser.Username
|
||||||
|
@ -73,68 +75,69 @@ func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) {
|
||||||
username = strings.Split(username, "\\")[1] // for some reason Username includes the hostname on windows
|
username = strings.Split(username, "\\")[1] // for some reason Username includes the hostname on windows
|
||||||
}
|
}
|
||||||
|
|
||||||
util.SetField(rtm, mod, "ver", rt.StringValue(getVersion()))
|
hshMod.SetField("ver", moonlight.StringValue(getVersion()))
|
||||||
util.SetField(rtm, mod, "goVersion", rt.StringValue(runtime.Version()))
|
hshMod.SetField("goVersion", moonlight.StringValue(runtime.Version()))
|
||||||
util.SetField(rtm, mod, "user", rt.StringValue(username))
|
hshMod.SetField("user", moonlight.StringValue(username))
|
||||||
util.SetField(rtm, mod, "host", rt.StringValue(host))
|
hshMod.SetField("host", moonlight.StringValue(host))
|
||||||
util.SetField(rtm, mod, "home", rt.StringValue(curuser.HomeDir))
|
hshMod.SetField("home", moonlight.StringValue(curuser.HomeDir))
|
||||||
util.SetField(rtm, mod, "dataDir", rt.StringValue(dataDir))
|
hshMod.SetField("dataDir", moonlight.StringValue(dataDir))
|
||||||
util.SetField(rtm, mod, "interactive", rt.BoolValue(interactive))
|
hshMod.SetField("interactive", moonlight.BoolValue(interactive))
|
||||||
util.SetField(rtm, mod, "login", rt.BoolValue(login))
|
hshMod.SetField("login", moonlight.BoolValue(login))
|
||||||
util.SetField(rtm, mod, "vimMode", rt.NilValue)
|
hshMod.SetField("exitCode", moonlight.IntValue(0))
|
||||||
util.SetField(rtm, mod, "exitCode", rt.IntValue(0))
|
//util.SetField(rtm, mod, "vimMode", rt.NilValue)
|
||||||
|
|
||||||
// hilbish.userDir table
|
// hilbish.userDir table
|
||||||
hshuser := userDirLoader(rtm)
|
hshuser := userDirLoader()
|
||||||
mod.Set(rt.StringValue("userDir"), rt.TableValue(hshuser))
|
hshMod.SetField("userDir", moonlight.TableValue(hshuser))
|
||||||
|
|
||||||
// hilbish.os table
|
// hilbish.os table
|
||||||
hshos := hshosLoader(rtm)
|
//hshos := hshosLoader(rtm)
|
||||||
mod.Set(rt.StringValue("os"), rt.TableValue(hshos))
|
//mod.Set(rt.StringValue("os"), rt.TableValue(hshos))
|
||||||
|
|
||||||
// hilbish.aliases table
|
// hilbish.aliases table
|
||||||
aliases = newAliases()
|
aliases = newAliases()
|
||||||
aliasesModule := aliases.Loader(rtm)
|
//aliasesModule := aliases.Loader(rtm)
|
||||||
mod.Set(rt.StringValue("aliases"), rt.TableValue(aliasesModule))
|
//mod.Set(rt.StringValue("aliases"), rt.TableValue(aliasesModule))
|
||||||
|
|
||||||
// hilbish.history table
|
// hilbish.history table
|
||||||
historyModule := lr.Loader(rtm)
|
//historyModule := lr.Loader(rtm)
|
||||||
mod.Set(rt.StringValue("history"), rt.TableValue(historyModule))
|
//mod.Set(rt.StringValue("history"), rt.TableValue(historyModule))
|
||||||
|
|
||||||
// hilbish.completion table
|
// hilbish.completion table
|
||||||
hshcomp := completionLoader(rtm)
|
//hshcomp := completionLoader(rtm)
|
||||||
// TODO: REMOVE "completion" AND ONLY USE "completions" WITH AN S
|
// TODO: REMOVE "completion" AND ONLY USE "completions" WITH AN S
|
||||||
mod.Set(rt.StringValue("completion"), rt.TableValue(hshcomp))
|
//mod.Set(rt.StringValue("completion"), rt.TableValue(hshcomp))
|
||||||
mod.Set(rt.StringValue("completions"), rt.TableValue(hshcomp))
|
//mod.Set(rt.StringValue("completions"), rt.TableValue(hshcomp))
|
||||||
|
|
||||||
// hilbish.runner table
|
// hilbish.runner table
|
||||||
runnerModule := runnerModeLoader(rtm)
|
runnerModule := runnerModeLoader(mlr)
|
||||||
mod.Set(rt.StringValue("runner"), rt.TableValue(runnerModule))
|
hshMod.SetField("runner", moonlight.TableValue(runnerModule))
|
||||||
|
|
||||||
// hilbish.jobs table
|
// hilbish.jobs table
|
||||||
jobs = newJobHandler()
|
jobs = newJobHandler()
|
||||||
jobModule := jobs.loader(rtm)
|
//jobModule := jobs.loader(rtm)
|
||||||
mod.Set(rt.StringValue("jobs"), rt.TableValue(jobModule))
|
//mod.Set(rt.StringValue("jobs"), rt.TableValue(jobModule))
|
||||||
|
|
||||||
// hilbish.timers table
|
// hilbish.timers table
|
||||||
timers = newTimersModule()
|
timers = newTimersModule()
|
||||||
timersModule := timers.loader(rtm)
|
//timersModule := timers.loader(rtm)
|
||||||
mod.Set(rt.StringValue("timers"), rt.TableValue(timersModule))
|
//mod.Set(rt.StringValue("timers"), rt.TableValue(timersModule))
|
||||||
|
|
||||||
editorModule := editorLoader(rtm)
|
//editorModule := editorLoader(rtm)
|
||||||
mod.Set(rt.StringValue("editor"), rt.TableValue(editorModule))
|
//mod.Set(rt.StringValue("editor"), rt.TableValue(editorModule))
|
||||||
|
|
||||||
versionModule := rt.NewTable()
|
//versionModule := rt.NewTable()
|
||||||
util.SetField(rtm, versionModule, "branch", rt.StringValue(gitBranch))
|
//util.SetField(rtm, versionModule, "branch", rt.StringValue(gitBranch))
|
||||||
util.SetField(rtm, versionModule, "full", rt.StringValue(getVersion()))
|
//util.SetField(rtm, versionModule, "full", rt.StringValue(getVersion()))
|
||||||
util.SetField(rtm, versionModule, "commit", rt.StringValue(gitCommit))
|
//util.SetField(rtm, versionModule, "commit", rt.StringValue(gitCommit))
|
||||||
util.SetField(rtm, versionModule, "release", rt.StringValue(releaseName))
|
//util.SetField(rtm, versionModule, "release", rt.StringValue(releaseName))
|
||||||
mod.Set(rt.StringValue("version"), rt.TableValue(versionModule))
|
//mod.Set(rt.StringValue("version"), rt.TableValue(versionModule))
|
||||||
|
|
||||||
pluginModule := moduleLoader(rtm)
|
// very meta
|
||||||
mod.Set(rt.StringValue("module"), rt.TableValue(pluginModule))
|
moduleModule := moduleLoader(mlr)
|
||||||
|
hshMod.SetField("module", moonlight.TableValue(moduleModule))
|
||||||
|
|
||||||
return rt.TableValue(mod), nil
|
return moonlight.TableValue(hshMod)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getenv(key, fallback string) string {
|
func getenv(key, fallback string) string {
|
||||||
|
@ -146,12 +149,12 @@ func getenv(key, fallback string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setVimMode(mode string) {
|
func setVimMode(mode string) {
|
||||||
util.SetField(l, hshMod, "vimMode", rt.StringValue(mode))
|
hshMod.SetField("vimMode", moonlight.StringValue(mode))
|
||||||
hooks.Emit("hilbish.vimMode", mode)
|
hooks.Emit("hilbish.vimMode", mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unsetVimMode() {
|
func unsetVimMode() {
|
||||||
util.SetField(l, hshMod, "vimMode", rt.NilValue)
|
hshMod.SetField("vimMode", moonlight.NilValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleStream(v rt.Value, strms *streams, errStream bool) error {
|
func handleStream(v rt.Value, strms *streams, errStream bool) error {
|
||||||
|
@ -292,10 +295,10 @@ func hlrun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
// cwd() -> string
|
// cwd() -> string
|
||||||
// Returns the current directory of the shell.
|
// Returns the current directory of the shell.
|
||||||
// #returns string
|
// #returns string
|
||||||
func hlcwd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func hlcwd(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
cwd, _ := os.Getwd()
|
cwd, _ := os.Getwd()
|
||||||
|
|
||||||
return c.PushingNext1(t.Runtime, rt.StringValue(cwd)), nil
|
return mlr.PushNext1(c, moonlight.StringValue(cwd)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -348,17 +351,18 @@ hilbish.prompt '%u@%h :%d $'
|
||||||
-- prompt: user@hostname: ~/directory $
|
-- prompt: user@hostname: ~/directory $
|
||||||
#example
|
#example
|
||||||
*/
|
*/
|
||||||
func hlprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func hlprompt(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
err := c.Check1Arg()
|
err := mlr.Check1Arg(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
p, err := c.StringArg(0)
|
p, err := mlr.StringArg(c, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
typ := "left"
|
typ := "left"
|
||||||
// optional 2nd arg
|
// optional 2nd arg
|
||||||
|
/*
|
||||||
if len(c.Etc()) != 0 {
|
if len(c.Etc()) != 0 {
|
||||||
ltyp := c.Etc()[0]
|
ltyp := c.Etc()[0]
|
||||||
var ok bool
|
var ok bool
|
||||||
|
@ -367,6 +371,7 @@ func hlprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
return nil, errors.New("bad argument to run (expected string, got " + ltyp.TypeName() + ")")
|
return nil, errors.New("bad argument to run (expected string, got " + ltyp.TypeName() + ")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
switch typ {
|
switch typ {
|
||||||
case "left":
|
case "left":
|
||||||
|
@ -429,15 +434,17 @@ hilbish.alias('dircount', 'ls %1 | wc -l')
|
||||||
-- "dircount ~" would count how many files are in ~ (home directory).
|
-- "dircount ~" would count how many files are in ~ (home directory).
|
||||||
#example
|
#example
|
||||||
*/
|
*/
|
||||||
func hlalias(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
//func hlalias(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
if err := c.CheckNArgs(2); err != nil {
|
func hlalias(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
|
if err := mlr.CheckNArgs(c, 2); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cmd, err := c.StringArg(0)
|
|
||||||
|
cmd, err := mlr.StringArg(c, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
orig, err := c.StringArg(1)
|
orig, err := mlr.StringArg(c, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -462,20 +469,20 @@ hilbish.appendPath {
|
||||||
}
|
}
|
||||||
#example
|
#example
|
||||||
*/
|
*/
|
||||||
func hlappendPath(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func hlappendPath(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
if err := c.Check1Arg(); err != nil {
|
if err := mlr.Check1Arg(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
arg := c.Arg(0)
|
arg := mlr.Arg(c, 0)
|
||||||
|
|
||||||
// check if dir is a table or a string
|
// check if dir is a table or a string
|
||||||
if arg.Type() == rt.TableType {
|
if moonlight.Type(arg) == moonlight.TableType {
|
||||||
util.ForEach(arg.AsTable(), func(k rt.Value, v rt.Value) {
|
moonlight.ForEach(moonlight.ToTable(arg), func(_ moonlight.Value, v moonlight.Value) {
|
||||||
if v.Type() == rt.StringType {
|
if moonlight.Type(v) == moonlight.StringType {
|
||||||
appendPath(v.AsString())
|
appendPath(moonlight.ToString(v))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else if arg.Type() == rt.StringType {
|
} else if moonlight.Type(arg) == moonlight.StringType {
|
||||||
appendPath(arg.AsString())
|
appendPath(arg.AsString())
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.New("bad argument to appendPath (expected string or table, got " + arg.TypeName() + ")")
|
return nil, errors.New("bad argument to appendPath (expected string or table, got " + arg.TypeName() + ")")
|
||||||
|
@ -494,6 +501,7 @@ func appendPath(dir string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// exec(cmd)
|
// exec(cmd)
|
||||||
// Replaces the currently running Hilbish instance with the supplied command.
|
// Replaces the currently running Hilbish instance with the supplied command.
|
||||||
// This can be used to do an in-place restart.
|
// This can be used to do an in-place restart.
|
||||||
|
@ -529,7 +537,9 @@ func hlexec(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
// goro(fn)
|
// goro(fn)
|
||||||
// Puts `fn` in a Goroutine.
|
// Puts `fn` in a Goroutine.
|
||||||
// This can be used to run any function in another thread at the same time as other Lua code.
|
// This can be used to run any function in another thread at the same time as other Lua code.
|
||||||
|
@ -613,6 +623,7 @@ func hlinterval(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
return c.PushingNext1(t.Runtime, rt.UserDataValue(timer.ud)), nil
|
return c.PushingNext1(t.Runtime, rt.UserDataValue(timer.ud)), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// complete(scope, cb)
|
// complete(scope, cb)
|
||||||
// Registers a completion handler for the specified scope.
|
// Registers a completion handler for the specified scope.
|
||||||
|
@ -648,7 +659,6 @@ hilbish.complete('command.sudo', function(query, ctx, fields)
|
||||||
return {compGroup}, pfx
|
return {compGroup}, pfx
|
||||||
end)
|
end)
|
||||||
#example
|
#example
|
||||||
*/
|
|
||||||
func hlcomplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func hlcomplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
scope, cb, err := util.HandleStrCallback(t, c)
|
scope, cb, err := util.HandleStrCallback(t, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -658,7 +668,9 @@ func hlcomplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
// prependPath(dir)
|
// prependPath(dir)
|
||||||
// Prepends `dir` to $PATH.
|
// Prepends `dir` to $PATH.
|
||||||
// #param dir string
|
// #param dir string
|
||||||
|
@ -741,6 +753,7 @@ func hlinputMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// runnerMode(mode)
|
// runnerMode(mode)
|
||||||
// Sets the execution/runner mode for interactive Hilbish.
|
// Sets the execution/runner mode for interactive Hilbish.
|
||||||
|
@ -751,19 +764,19 @@ func hlinputMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
// will call it to execute user input instead.
|
// will call it to execute user input instead.
|
||||||
// Read [about runner mode](../features/runner-mode) for more information.
|
// Read [about runner mode](../features/runner-mode) for more information.
|
||||||
// #param mode string|function
|
// #param mode string|function
|
||||||
func hlrunnerMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func hlrunnerMode(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
if err := c.Check1Arg(); err != nil {
|
if err := mlr.Check1Arg(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
mode := c.Arg(0)
|
mode := mlr.Arg(c, 0)
|
||||||
|
|
||||||
switch mode.Type() {
|
switch moonlight.Type(mode) {
|
||||||
case rt.StringType:
|
case moonlight.StringType:
|
||||||
switch mode.AsString() {
|
switch mode.AsString() {
|
||||||
case "hybrid", "hybridRev", "lua", "sh": runnerMode = mode
|
case "hybrid", "hybridRev", "lua", "sh": runnerMode = mode
|
||||||
default: return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.AsString())
|
default: return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.AsString())
|
||||||
}
|
}
|
||||||
case rt.FunctionType: runnerMode = mode
|
case moonlight.FunctionType: runnerMode = mode
|
||||||
default: return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.TypeName())
|
default: return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.TypeName())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,6 +799,7 @@ function hilbish.hinter(line, pos)
|
||||||
end
|
end
|
||||||
#example
|
#example
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
func hlhinter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func hlhinter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
}
|
}
|
||||||
|
@ -815,3 +829,4 @@ func hlhighlighter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
return c.PushingNext1(t.Runtime, rt.StringValue(line)), nil
|
return c.PushingNext1(t.Runtime, rt.StringValue(line)), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
27
complete.go
27
complete.go
|
@ -1,14 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
//"errors"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hilbish/util"
|
"hilbish/util"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
//rt "github.com/arnodel/golua/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var charEscapeMap = []string{
|
var charEscapeMap = []string{
|
||||||
|
@ -191,6 +191,7 @@ func escapeFilename(fname string) string {
|
||||||
// #interface completion
|
// #interface completion
|
||||||
// tab completions
|
// tab completions
|
||||||
// The completions interface deals with tab completions.
|
// The completions interface deals with tab completions.
|
||||||
|
/*
|
||||||
func completionLoader(rtm *rt.Runtime) *rt.Table {
|
func completionLoader(rtm *rt.Runtime) *rt.Table {
|
||||||
exports := map[string]util.LuaExport{
|
exports := map[string]util.LuaExport{
|
||||||
"bins": {hcmpBins, 3, false},
|
"bins": {hcmpBins, 3, false},
|
||||||
|
@ -204,6 +205,7 @@ func completionLoader(rtm *rt.Runtime) *rt.Table {
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// #interface completion
|
// #interface completion
|
||||||
// bins(query, ctx, fields) -> entries (table), prefix (string)
|
// bins(query, ctx, fields) -> entries (table), prefix (string)
|
||||||
|
@ -231,6 +233,7 @@ hilbish.complete('command.sudo', function(query, ctx, fields)
|
||||||
end)
|
end)
|
||||||
#example
|
#example
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
func hcmpBins(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func hcmpBins(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
query, ctx, fds, err := getCompleteParams(t, c)
|
query, ctx, fds, err := getCompleteParams(t, c)
|
||||||
if err != nil {
|
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
|
return c.PushingNext(t.Runtime, rt.TableValue(luaComps), rt.StringValue(pfx)), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// #interface completion
|
// #interface completion
|
||||||
// call(name, query, ctx, fields) -> completionGroups (table), prefix (string)
|
// 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 query string
|
||||||
// #param ctx string
|
// #param ctx string
|
||||||
// #param fields table
|
// #param fields table
|
||||||
|
/*
|
||||||
func hcmpCall(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func hcmpCall(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
if err := c.CheckNArgs(4); err != nil {
|
if err := c.CheckNArgs(4); err != nil {
|
||||||
return nil, err
|
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")
|
return nil, errors.New("completer " + completer + " does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
// we must keep the holy 80 cols
|
|
||||||
cont := c.Next()
|
cont := c.Next()
|
||||||
err = rt.Call(l.MainThread(), rt.FunctionValue(completecb),
|
err = l.Call(moonlight.FunctionValue(completecb), []moonlight.Value{
|
||||||
[]rt.Value{rt.StringValue(query), rt.StringValue(ctx), rt.TableValue(fields)},
|
moonlight.StringValue(query),
|
||||||
cont)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -295,6 +304,7 @@ func hcmpCall(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
return cont, nil
|
return cont, nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// #interface completion
|
// #interface completion
|
||||||
// files(query, ctx, fields) -> entries (table), prefix (string)
|
// 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 query string
|
||||||
// #param ctx string
|
// #param ctx string
|
||||||
// #param fields table
|
// #param fields table
|
||||||
|
/*
|
||||||
func hcmpFiles(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func hcmpFiles(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
query, ctx, fds, err := getCompleteParams(t, c)
|
query, ctx, fds, err := getCompleteParams(t, c)
|
||||||
if err != nil {
|
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
|
return c.PushingNext(t.Runtime, rt.TableValue(luaComps), rt.StringValue(pfx)), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// #interface completion
|
// #interface completion
|
||||||
// handler(line, pos)
|
// handler(line, pos)
|
||||||
|
@ -340,11 +352,11 @@ function hilbish.completion.handler(line, pos)
|
||||||
end
|
end
|
||||||
#example
|
#example
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
func hcmpHandler(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func hcmpHandler(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func getCompleteParams(t *rt.Thread, c *rt.GoCont) (string, string, []string, error) {
|
func getCompleteParams(t *rt.Thread, c *rt.GoCont) (string, string, []string, error) {
|
||||||
if err := c.CheckNArgs(3); err != nil {
|
if err := c.CheckNArgs(3); err != nil {
|
||||||
return "", "", []string{}, err
|
return "", "", []string{}, err
|
||||||
|
@ -371,3 +383,4 @@ func getCompleteParams(t *rt.Thread, c *rt.GoCont) (string, string, []string, er
|
||||||
|
|
||||||
return query, ctx, fds, err
|
return query, ctx, fds, err
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -12,11 +12,13 @@ import (
|
||||||
// directly interact with the line editor in use.
|
// directly interact with the line editor in use.
|
||||||
func editorLoader(rtm *rt.Runtime) *rt.Table {
|
func editorLoader(rtm *rt.Runtime) *rt.Table {
|
||||||
exports := map[string]util.LuaExport{
|
exports := map[string]util.LuaExport{
|
||||||
|
/*
|
||||||
"insert": {editorInsert, 1, false},
|
"insert": {editorInsert, 1, false},
|
||||||
"setVimRegister": {editorSetRegister, 1, false},
|
"setVimRegister": {editorSetRegister, 1, false},
|
||||||
"getVimRegister": {editorGetRegister, 2, false},
|
"getVimRegister": {editorGetRegister, 2, false},
|
||||||
"getLine": {editorGetLine, 0, false},
|
"getLine": {editorGetLine, 0, false},
|
||||||
"readChar": {editorReadChar, 0, false},
|
"readChar": {editorReadChar, 0, false},
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
mod := rt.NewTable()
|
mod := rt.NewTable()
|
||||||
|
|
65
exec.go
65
exec.go
|
@ -15,7 +15,8 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hilbish/util"
|
"hilbish/moonlight"
|
||||||
|
//"hilbish/util"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
"mvdan.cc/sh/v3/shell"
|
"mvdan.cc/sh/v3/shell"
|
||||||
|
@ -27,7 +28,7 @@ import (
|
||||||
|
|
||||||
var errNotExec = errors.New("not executable")
|
var errNotExec = errors.New("not executable")
|
||||||
var errNotFound = errors.New("not found")
|
var errNotFound = errors.New("not found")
|
||||||
var runnerMode rt.Value = rt.StringValue("hybrid")
|
var runnerMode moonlight.Value = moonlight.StringValue("hybrid")
|
||||||
|
|
||||||
type streams struct {
|
type streams struct {
|
||||||
stdout io.Writer
|
stdout io.Writer
|
||||||
|
@ -100,7 +101,7 @@ func runInput(input string, priv bool) {
|
||||||
var cont bool
|
var cont bool
|
||||||
// save incase it changes while prompting (For some reason)
|
// save incase it changes while prompting (For some reason)
|
||||||
currentRunner := runnerMode
|
currentRunner := runnerMode
|
||||||
if currentRunner.Type() == rt.StringType {
|
if currentRunner.Type() == moonlight.StringType {
|
||||||
switch currentRunner.AsString() {
|
switch currentRunner.AsString() {
|
||||||
case "hybrid":
|
case "hybrid":
|
||||||
_, _, err = handleLua(input)
|
_, _, err = handleLua(input)
|
||||||
|
@ -170,70 +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) {
|
||||||
term := rt.NewTerminationWith(l.MainThread().CurrentCont(), 3, false)
|
runnerRet, err := l.Call1(runr, moonlight.StringValue(userInput))
|
||||||
err = rt.Call(l.MainThread(), runr, []rt.Value{rt.StringValue(userInput)}, term)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 124, false, nil, err
|
return "", 124, false, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var runner *rt.Table
|
var runner *moonlight.Table
|
||||||
var ok bool
|
var ok bool
|
||||||
runnerRet := term.Get(0)
|
if runner, ok = moonlight.TryTable(runnerRet); !ok {
|
||||||
if runner, ok = runnerRet.TryTable(); !ok {
|
|
||||||
fmt.Fprintln(os.Stderr, "runner did not return a table")
|
fmt.Fprintln(os.Stderr, "runner did not return a table")
|
||||||
exitCode = 125
|
exitCode = 125
|
||||||
input = userInput
|
input = userInput
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if code, ok := runner.Get(rt.StringValue("exitCode")).TryInt(); ok {
|
if code, ok := runner.Get(moonlight.StringValue("exitCode")).TryInt(); ok {
|
||||||
exitCode = uint8(code)
|
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
|
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)
|
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
|
continued = c
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
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()))
|
|
||||||
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 = rt.Call1(l.MainThread(), 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) {
|
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
|
var err error
|
||||||
input, exitCode, cont, runErr, err = runLuaRunner(shRunner, cmdString)
|
input, exitCode, cont, runErr, err = runLuaRunner(shRunner, cmdString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -352,7 +324,7 @@ func execHandle(bg bool) interp.ExecHandlerFunc {
|
||||||
sinks.Set(rt.StringValue("out"), rt.UserDataValue(stdout.ud))
|
sinks.Set(rt.StringValue("out"), rt.UserDataValue(stdout.ud))
|
||||||
sinks.Set(rt.StringValue("err"), rt.UserDataValue(stderr.ud))
|
sinks.Set(rt.StringValue("err"), rt.UserDataValue(stderr.ud))
|
||||||
|
|
||||||
t := rt.NewThread(l)
|
//t := rt.NewThread(l)
|
||||||
sig := make(chan os.Signal)
|
sig := make(chan os.Signal)
|
||||||
exit := make(chan bool)
|
exit := make(chan bool)
|
||||||
|
|
||||||
|
@ -368,14 +340,15 @@ func execHandle(bg bool) interp.ExecHandlerFunc {
|
||||||
signal.Notify(sig, os.Interrupt)
|
signal.Notify(sig, os.Interrupt)
|
||||||
select {
|
select {
|
||||||
case <-sig:
|
case <-sig:
|
||||||
t.KillContext()
|
//t.KillContext()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
luaexitcode, err = rt.Call1(t, rt.FunctionValue(cmd), rt.TableValue(luacmdArgs), rt.TableValue(sinks))
|
// TODO: call in thread function?
|
||||||
|
//luaexitcode, err = l.CallInThread1(t, rt.FunctionValue(cmd), rt.TableValue(luacmdArgs), rt.TableValue(sinks))
|
||||||
exit <- true
|
exit <- true
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -606,9 +579,9 @@ func splitInput(input string) ([]string, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdFinish(code uint8, cmdstr string, private bool) {
|
func cmdFinish(code uint8, cmdstr string, private bool) {
|
||||||
util.SetField(l, hshMod, "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
|
// using AsValue (to convert to lua type) on an interface which is an int
|
||||||
// results in it being unknown in lua .... ????
|
// results in it being unknown in lua .... ????
|
||||||
// so we allow the hook handler to take lua runtime Values
|
// 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
|
toolchain go1.22.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/aarzilli/golua v0.0.0-20210507130708-11106aa57765
|
||||||
github.com/arnodel/golua v0.0.0-20230215163904-e0b5347eaaa1
|
github.com/arnodel/golua v0.0.0-20230215163904-e0b5347eaaa1
|
||||||
github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504
|
github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504
|
||||||
github.com/blackfireio/osinfo v1.0.5
|
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/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 h1:THNle0FR2g7DMO1y3Bx1Zr7rYeiLXt3st3UkxEsMzL4=
|
||||||
github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240720131751-805c301321fd/go.mod h1:YZalN5H7WNQw3DGij6IvHsEhn5YMW7M2FCwG6gnfKy4=
|
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 h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
|
||||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
|
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=
|
github.com/arnodel/strftime v0.1.6 h1:0hc0pUvk8KhEMXE+htyaOUV42zNcf/csIbjzEFCJqsw=
|
||||||
|
|
|
@ -26,12 +26,12 @@ this function will set the user prompt.
|
||||||
package bait
|
package bait
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
//"errors"
|
||||||
|
|
||||||
|
"hilbish/moonlight"
|
||||||
"hilbish/util"
|
"hilbish/util"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
"github.com/arnodel/golua/lib/packagelib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type listenerType int
|
type listenerType int
|
||||||
|
@ -48,26 +48,21 @@ type Listener struct{
|
||||||
typ listenerType
|
typ listenerType
|
||||||
once bool
|
once bool
|
||||||
caller func(...interface{})
|
caller func(...interface{})
|
||||||
luaCaller *rt.Closure
|
luaCaller *moonlight.Closure
|
||||||
}
|
}
|
||||||
|
|
||||||
type Bait struct{
|
type Bait struct{
|
||||||
Loader packagelib.Loader
|
|
||||||
recoverer Recoverer
|
recoverer Recoverer
|
||||||
handlers map[string][]*Listener
|
handlers map[string][]*Listener
|
||||||
rtm *rt.Runtime
|
rtm *moonlight.Runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Bait instance.
|
// New creates a new Bait instance.
|
||||||
func New(rtm *rt.Runtime) *Bait {
|
func New(rtm *moonlight.Runtime) *Bait {
|
||||||
b := &Bait{
|
b := &Bait{
|
||||||
handlers: make(map[string][]*Listener),
|
handlers: make(map[string][]*Listener),
|
||||||
rtm: rtm,
|
rtm: rtm,
|
||||||
}
|
}
|
||||||
b.Loader = packagelib.Loader{
|
|
||||||
Load: b.loaderFunc,
|
|
||||||
Name: "bait",
|
|
||||||
}
|
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
@ -87,17 +82,18 @@ func (b *Bait) Emit(event string, args ...interface{}) {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if handle.typ == luaListener {
|
if handle.typ == luaListener {
|
||||||
funcVal := rt.FunctionValue(handle.luaCaller)
|
//funcVal := moonlight.FunctionValue(handle.luaCaller)
|
||||||
var luaArgs []rt.Value
|
var luaArgs []moonlight.Value
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
var luarg rt.Value
|
var luarg moonlight.Value
|
||||||
switch arg.(type) {
|
switch arg.(type) {
|
||||||
case rt.Value: luarg = arg.(rt.Value)
|
case moonlight.Value: luarg = arg.(moonlight.Value)
|
||||||
default: luarg = rt.AsValue(arg)
|
default: luarg = moonlight.AsValue(arg)
|
||||||
}
|
}
|
||||||
luaArgs = append(luaArgs, luarg)
|
luaArgs = append(luaArgs, luarg)
|
||||||
}
|
}
|
||||||
_, err := rt.Call1(b.rtm.MainThread(), funcVal, luaArgs...)
|
/*
|
||||||
|
_, err := b.rtm.Call1(funcVal, luaArgs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if event != "error" {
|
if event != "error" {
|
||||||
b.Emit("error", event, handle.luaCaller, err.Error())
|
b.Emit("error", event, handle.luaCaller, err.Error())
|
||||||
|
@ -107,6 +103,7 @@ func (b *Bait) Emit(event string, args ...interface{}) {
|
||||||
// (calls the go recoverer function)
|
// (calls the go recoverer function)
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
} else {
|
} else {
|
||||||
handle.caller(args...)
|
handle.caller(args...)
|
||||||
}
|
}
|
||||||
|
@ -129,8 +126,8 @@ func (b *Bait) On(event string, handler func(...interface{})) *Listener {
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnLua adds a Lua function handler for an event.
|
// OnLua adds a Lua function handler for an event.
|
||||||
func (b *Bait) OnLua(event string, handler *rt.Closure) *Listener {
|
func (b *Bait) OnLua(event string, handler *moonlight.Closure) *Listener {
|
||||||
listener :=&Listener{
|
listener := &Listener{
|
||||||
typ: luaListener,
|
typ: luaListener,
|
||||||
luaCaller: handler,
|
luaCaller: handler,
|
||||||
}
|
}
|
||||||
|
@ -151,7 +148,7 @@ func (b *Bait) Off(event string, listener *Listener) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// OffLua removes a Lua function handler for an event.
|
// 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]
|
handles := b.handlers[event]
|
||||||
|
|
||||||
for i, handle := range handles {
|
for i, handle := range handles {
|
||||||
|
@ -174,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.
|
// 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{
|
listener := &Listener{
|
||||||
typ: luaListener,
|
typ: luaListener,
|
||||||
once: true,
|
once: true,
|
||||||
|
@ -212,18 +209,20 @@ func (b *Bait) callRecoverer(event string, handler *Listener, err interface{}) {
|
||||||
b.recoverer(event, handler, err)
|
b.recoverer(event, handler, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bait) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
func (b *Bait) Loader(rtm *moonlight.Runtime) moonlight.Value {
|
||||||
exports := map[string]util.LuaExport{
|
exports := map[string]moonlight.Export{
|
||||||
"catch": util.LuaExport{b.bcatch, 2, false},
|
"catch": {b.bcatch, 2, false},
|
||||||
|
/*
|
||||||
"catchOnce": util.LuaExport{b.bcatchOnce, 2, false},
|
"catchOnce": util.LuaExport{b.bcatchOnce, 2, false},
|
||||||
"throw": util.LuaExport{b.bthrow, 1, true},
|
"throw": util.LuaExport{b.bthrow, 1, true},
|
||||||
"release": util.LuaExport{b.brelease, 2, false},
|
"release": util.LuaExport{b.brelease, 2, false},
|
||||||
"hooks": util.LuaExport{b.bhooks, 1, false},
|
"hooks": util.LuaExport{b.bhooks, 1, false},
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
mod := rt.NewTable()
|
mod := moonlight.NewTable()
|
||||||
util.SetExports(rtm, mod, exports)
|
rtm.SetExports(mod, exports)
|
||||||
|
|
||||||
return rt.TableValue(mod), nil
|
return moonlight.TableValue(mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleHook(t *rt.Thread, c *rt.GoCont, name string, catcher *rt.Closure, args ...interface{}) {
|
func handleHook(t *rt.Thread, c *rt.GoCont, name string, catcher *rt.Closure, args ...interface{}) {
|
||||||
|
@ -258,8 +257,8 @@ bait.catch('hilbish.exit', function()
|
||||||
end)
|
end)
|
||||||
#example
|
#example
|
||||||
*/
|
*/
|
||||||
func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func (b *Bait) bcatch(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
name, catcher, err := util.HandleStrCallback(t, c)
|
name, catcher, err := util.HandleStrCallback(mlr, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -269,6 +268,7 @@ func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// catchOnce(name, cb)
|
// catchOnce(name, cb)
|
||||||
// Catches an event, but only once. This will remove the hook immediately after it runs for the first time.
|
// Catches an event, but only once. This will remove the hook immediately after it runs for the first time.
|
||||||
// #param name string The name of the event
|
// #param name string The name of the event
|
||||||
|
@ -315,6 +315,7 @@ func (b *Bait) bhooks(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
return c.PushingNext1(t.Runtime, rt.TableValue(luaHandlers)), nil
|
return c.PushingNext1(t.Runtime, rt.TableValue(luaHandlers)), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// release(name, catcher)
|
// release(name, catcher)
|
||||||
// Removes the `catcher` for the event with `name`.
|
// Removes the `catcher` for the event with `name`.
|
||||||
|
@ -333,6 +334,7 @@ bait.release('event', hookCallback)
|
||||||
-- and now hookCallback will no longer be ran for the event.
|
-- and now hookCallback will no longer be ran for the event.
|
||||||
#example
|
#example
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
name, catcher, err := util.HandleStrCallback(t, c)
|
name, catcher, err := util.HandleStrCallback(t, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -343,6 +345,7 @@ func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// throw(name, ...args)
|
// throw(name, ...args)
|
||||||
// #param name string The name of the hook.
|
// #param name string The name of the hook.
|
||||||
|
@ -358,6 +361,7 @@ bait.catch('gretting', function(greetTo)
|
||||||
end)
|
end)
|
||||||
#example
|
#example
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
if err := c.Check1Arg(); err != nil {
|
if err := c.Check1Arg(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -374,3 +378,4 @@ func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -33,42 +33,35 @@ This sink is for writing errors, as the name would suggest.
|
||||||
package commander
|
package commander
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hilbish/moonlight"
|
||||||
"hilbish/util"
|
"hilbish/util"
|
||||||
"hilbish/golibs/bait"
|
"hilbish/golibs/bait"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
|
||||||
"github.com/arnodel/golua/lib/packagelib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Commander struct{
|
type Commander struct{
|
||||||
Events *bait.Bait
|
Events *bait.Bait
|
||||||
Loader packagelib.Loader
|
Commands map[string]*moonlight.Closure
|
||||||
Commands map[string]*rt.Closure
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(rtm *rt.Runtime) *Commander {
|
func New(rtm *moonlight.Runtime) *Commander {
|
||||||
c := &Commander{
|
c := &Commander{
|
||||||
Events: bait.New(rtm),
|
Events: bait.New(rtm),
|
||||||
Commands: make(map[string]*rt.Closure),
|
Commands: make(map[string]*moonlight.Closure),
|
||||||
}
|
|
||||||
c.Loader = packagelib.Loader{
|
|
||||||
Load: c.loaderFunc,
|
|
||||||
Name: "commander",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commander) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
func (c *Commander) Loader(rtm *moonlight.Runtime) moonlight.Value {
|
||||||
exports := map[string]util.LuaExport{
|
exports := map[string]moonlight.Export{
|
||||||
"register": util.LuaExport{c.cregister, 2, false},
|
"register": {c.cregister, 2, false},
|
||||||
"deregister": util.LuaExport{c.cderegister, 1, false},
|
"deregister": {c.cderegister, 1, false},
|
||||||
"registry": util.LuaExport{c.cregistry, 0, false},
|
"registry": {c.cregistry, 0, false},
|
||||||
}
|
}
|
||||||
mod := rt.NewTable()
|
mod := moonlight.NewTable()
|
||||||
util.SetExports(rtm, mod, exports)
|
rtm.SetExports(mod, exports)
|
||||||
|
|
||||||
return rt.TableValue(mod), nil
|
return moonlight.TableValue(mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
// register(name, cb)
|
// register(name, cb)
|
||||||
|
@ -88,8 +81,8 @@ commander.register('hello', function(args, sinks)
|
||||||
end)
|
end)
|
||||||
#example
|
#example
|
||||||
*/
|
*/
|
||||||
func (c *Commander) cregister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
|
func (c *Commander) cregister(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
cmdName, cmd, err := util.HandleStrCallback(t, ct)
|
cmdName, cmd, err := util.HandleStrCallback(mlr, ct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -102,11 +95,11 @@ func (c *Commander) cregister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
|
||||||
// deregister(name)
|
// deregister(name)
|
||||||
// Removes the named command. Note that this will only remove Commander-registered commands.
|
// Removes the named command. Note that this will only remove Commander-registered commands.
|
||||||
// #param name string Name of the command to remove.
|
// #param name string Name of the command to remove.
|
||||||
func (c *Commander) cderegister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
|
func (c *Commander) cderegister(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
if err := ct.Check1Arg(); err != nil {
|
if err := mlr.Check1Arg(ct); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cmdName, err := ct.StringArg(0)
|
cmdName, err := mlr.StringArg(ct, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -120,14 +113,16 @@ func (c *Commander) cderegister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
|
||||||
// Returns all registered commanders. Returns a list of tables with the following keys:
|
// Returns all registered commanders. Returns a list of tables with the following keys:
|
||||||
// - `exec`: The function used to run the commander. Commanders require args and sinks to be passed.
|
// - `exec`: The function used to run the commander. Commanders require args and sinks to be passed.
|
||||||
// #returns table
|
// #returns table
|
||||||
func (c *Commander) cregistry(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
|
func (c *Commander) cregistry(mlr *moonlight.Runtime, ct *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
registryLua := rt.NewTable()
|
registryLua := moonlight.NewTable()
|
||||||
for cmdName, cmd := range c.Commands {
|
for cmdName, cmd := range c.Commands {
|
||||||
cmdTbl := rt.NewTable()
|
cmdTbl := moonlight.NewTable()
|
||||||
cmdTbl.Set(rt.StringValue("exec"), rt.FunctionValue(cmd))
|
//cmdTbl.SetField("exec", moonlight.FunctionValue(cmd))
|
||||||
|
print(cmd)
|
||||||
|
cmdTbl.SetField("exec", moonlight.StringValue("placeholder"))
|
||||||
|
|
||||||
registryLua.Set(rt.StringValue(cmdName), rt.TableValue(cmdTbl))
|
registryLua.SetField(cmdName, moonlight.TableValue(cmdTbl))
|
||||||
}
|
}
|
||||||
|
|
||||||
return ct.PushingNext1(t.Runtime, rt.TableValue(registryLua)), nil
|
return mlr.PushNext1(ct, moonlight.TableValue(registryLua)), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,50 +14,51 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"hilbish/moonlight"
|
||||||
"hilbish/util"
|
"hilbish/util"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
"github.com/arnodel/golua/lib/packagelib"
|
|
||||||
"github.com/arnodel/golua/lib/iolib"
|
"github.com/arnodel/golua/lib/iolib"
|
||||||
"mvdan.cc/sh/v3/interp"
|
"mvdan.cc/sh/v3/interp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fs struct{
|
type fs struct{
|
||||||
runner *interp.Runner
|
runner *interp.Runner
|
||||||
Loader packagelib.Loader
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(runner *interp.Runner) *fs {
|
func New(runner *interp.Runner) *fs {
|
||||||
f := &fs{
|
return &fs{
|
||||||
runner: runner,
|
runner: runner,
|
||||||
}
|
}
|
||||||
f.Loader = packagelib.Loader{
|
|
||||||
Load: f.loaderFunc,
|
|
||||||
Name: "fs",
|
|
||||||
}
|
|
||||||
|
|
||||||
return f
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fs) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
func (f *fs) Loader(rtm *moonlight.Runtime) moonlight.Value {
|
||||||
exports := map[string]util.LuaExport{
|
exports := map[string]moonlight.Export{
|
||||||
|
/*
|
||||||
"cd": util.LuaExport{f.fcd, 1, false},
|
"cd": util.LuaExport{f.fcd, 1, false},
|
||||||
"mkdir": util.LuaExport{f.fmkdir, 2, false},
|
"mkdir": util.LuaExport{f.fmkdir, 2, false},
|
||||||
"stat": util.LuaExport{f.fstat, 1, false},
|
"stat": util.LuaExport{f.fstat, 1, false},
|
||||||
"readdir": util.LuaExport{f.freaddir, 1, false},
|
*/
|
||||||
|
"readdir": {f.freaddir, 1, false},
|
||||||
|
/*
|
||||||
"abs": util.LuaExport{f.fabs, 1, false},
|
"abs": util.LuaExport{f.fabs, 1, false},
|
||||||
"basename": util.LuaExport{f.fbasename, 1, false},
|
"basename": util.LuaExport{f.fbasename, 1, false},
|
||||||
"dir": util.LuaExport{f.fdir, 1, false},
|
*/
|
||||||
|
"dir": {f.fdir, 1, false},
|
||||||
|
/*
|
||||||
"glob": util.LuaExport{f.fglob, 1, false},
|
"glob": util.LuaExport{f.fglob, 1, false},
|
||||||
"join": util.LuaExport{f.fjoin, 0, true},
|
"join": util.LuaExport{f.fjoin, 0, true},
|
||||||
"pipe": util.LuaExport{f.fpipe, 0, false},
|
"pipe": util.LuaExport{f.fpipe, 0, false},
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
mod := rt.NewTable()
|
|
||||||
util.SetExports(rtm, mod, exports)
|
|
||||||
mod.Set(rt.StringValue("pathSep"), rt.StringValue(string(os.PathSeparator)))
|
|
||||||
mod.Set(rt.StringValue("pathListSep"), rt.StringValue(string(os.PathListSeparator)))
|
|
||||||
|
|
||||||
return rt.TableValue(mod), nil
|
mod := moonlight.NewTable()
|
||||||
|
rtm.SetExports(mod, exports)
|
||||||
|
|
||||||
|
mod.SetField("pathSep", moonlight.StringValue(string(os.PathSeparator)))
|
||||||
|
mod.SetField("pathListSep", moonlight.StringValue(string(os.PathListSeparator)))
|
||||||
|
|
||||||
|
return moonlight.TableValue(mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
// abs(path) -> string
|
// abs(path) -> string
|
||||||
|
@ -124,16 +125,17 @@ func (f *fs) fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
// `~/Documents/doc.txt` then this function will return `~/Documents`.
|
// `~/Documents/doc.txt` then this function will return `~/Documents`.
|
||||||
// #param path string Path to get the directory for.
|
// #param path string Path to get the directory for.
|
||||||
// #returns string
|
// #returns string
|
||||||
func (f *fs) fdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func (f *fs) fdir(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
if err := c.Check1Arg(); err != nil {
|
if err := mlr.Check1Arg(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
path, err := c.StringArg(0)
|
path, err := mlr.StringArg(c, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.PushingNext(t.Runtime, rt.StringValue(filepath.Dir(path))), nil
|
next := mlr.PushNext1(c, moonlight.StringValue(filepath.Dir(path)))
|
||||||
|
return next, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// glob(pattern) -> matches (table)
|
// glob(pattern) -> matches (table)
|
||||||
|
@ -262,26 +264,26 @@ func (f *fs) fpipe(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
// Returns a list of all files and directories in the provided path.
|
// Returns a list of all files and directories in the provided path.
|
||||||
// #param dir string
|
// #param dir string
|
||||||
// #returns table
|
// #returns table
|
||||||
func (f *fs) freaddir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func (f *fs) freaddir(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
if err := c.Check1Arg(); err != nil {
|
if err := mlr.Check1Arg(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dir, err := c.StringArg(0)
|
dir, err := mlr.StringArg(c, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dir = util.ExpandHome(dir)
|
dir = util.ExpandHome(dir)
|
||||||
names := rt.NewTable()
|
names := moonlight.NewTable()
|
||||||
|
|
||||||
dirEntries, err := os.ReadDir(dir)
|
dirEntries, err := os.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for i, entry := range dirEntries {
|
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 c.PushingNext1(t.Runtime, rt.TableValue(names)), nil
|
return mlr.PushNext1(c, moonlight.TableValue(names)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// stat(path) -> {}
|
// stat(path) -> {}
|
||||||
|
|
|
@ -5,52 +5,46 @@ package terminal
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hilbish/util"
|
"hilbish/moonlight"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
|
||||||
"github.com/arnodel/golua/lib/packagelib"
|
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
var termState *term.State
|
var termState *term.State
|
||||||
var Loader = packagelib.Loader{
|
|
||||||
Load: loaderFunc,
|
|
||||||
Name: "terminal",
|
|
||||||
}
|
|
||||||
|
|
||||||
func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
func Loader(rtm *moonlight.Runtime) moonlight.Value {
|
||||||
exports := map[string]util.LuaExport{
|
exports := map[string]moonlight.Export{
|
||||||
"setRaw": util.LuaExport{termsetRaw, 0, false},
|
"setRaw": {termsetRaw, 0, false},
|
||||||
"restoreState": util.LuaExport{termrestoreState, 0, false},
|
"restoreState": {termrestoreState, 0, false},
|
||||||
"size": util.LuaExport{termsize, 0, false},
|
"size": {termsize, 0, false},
|
||||||
"saveState": util.LuaExport{termsaveState, 0, false},
|
"saveState": {termsaveState, 0, false},
|
||||||
}
|
}
|
||||||
|
|
||||||
mod := rt.NewTable()
|
mod := moonlight.NewTable()
|
||||||
util.SetExports(rtm, mod, exports)
|
rtm.SetExports(mod, exports)
|
||||||
|
|
||||||
return rt.TableValue(mod), nil
|
return moonlight.TableValue(mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
// size()
|
// size()
|
||||||
// Gets the dimensions of the terminal. Returns a table with `width` and `height`
|
// Gets the dimensions of the terminal. Returns a table with `width` and `height`
|
||||||
// NOTE: The size refers to the amount of columns and rows of text that can fit in the terminal.
|
// NOTE: The size refers to the amount of columns and rows of text that can fit in the terminal.
|
||||||
func termsize(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func termsize(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
w, h, err := term.GetSize(int(os.Stdin.Fd()))
|
w, h, err := term.GetSize(int(os.Stdin.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dimensions := rt.NewTable()
|
dimensions := moonlight.NewTable()
|
||||||
dimensions.Set(rt.StringValue("width"), rt.IntValue(int64(w)))
|
dimensions.SetField("width", moonlight.IntValue(int64(w)))
|
||||||
dimensions.Set(rt.StringValue("height"), rt.IntValue(int64(h)))
|
dimensions.SetField("height", moonlight.IntValue(int64(h)))
|
||||||
|
|
||||||
return c.PushingNext1(t.Runtime, rt.TableValue(dimensions)), nil
|
return mlr.PushNext1(c, moonlight.TableValue(dimensions)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// saveState()
|
// saveState()
|
||||||
// Saves the current state of the terminal.
|
// Saves the current state of the terminal.
|
||||||
func termsaveState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func termsaveState(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
state, err := term.GetState(int(os.Stdin.Fd()))
|
state, err := term.GetState(int(os.Stdin.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -62,7 +56,7 @@ func termsaveState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
// restoreState()
|
// restoreState()
|
||||||
// Restores the last saved state of the terminal
|
// Restores the last saved state of the terminal
|
||||||
func termrestoreState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func termrestoreState(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
err := term.Restore(int(os.Stdin.Fd()), termState)
|
err := term.Restore(int(os.Stdin.Fd()), termState)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -73,7 +67,7 @@ func termrestoreState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
|
||||||
// setRaw()
|
// setRaw()
|
||||||
// Puts the terminal into raw mode.
|
// Puts the terminal into raw mode.
|
||||||
func termsetRaw(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func termsetRaw(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
_, err := term.MakeRaw(int(os.Stdin.Fd()))
|
_, err := term.MakeRaw(int(os.Stdin.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
20
history.go
20
history.go
|
@ -7,17 +7,17 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
"hilbish/moonlight"
|
||||||
)
|
)
|
||||||
|
|
||||||
type luaHistory struct {}
|
type luaHistory struct {}
|
||||||
|
|
||||||
func (h *luaHistory) Write(line string) (int, error) {
|
func (h *luaHistory) Write(line string) (int, error) {
|
||||||
histWrite := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("add"))
|
histWrite := hshMod.Get(moonlight.StringValue("history")).AsTable().Get(moonlight.StringValue("add"))
|
||||||
ln, err := rt.Call1(l.MainThread(), histWrite, rt.StringValue(line))
|
ln, err := l.Call1(histWrite, moonlight.StringValue(line))
|
||||||
|
|
||||||
var num int64
|
var num int64
|
||||||
if ln.Type() == rt.IntType {
|
if ln.Type() == moonlight.IntType {
|
||||||
num = ln.AsInt()
|
num = ln.AsInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,11 +25,11 @@ func (h *luaHistory) Write(line string) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *luaHistory) GetLine(idx int) (string, error) {
|
func (h *luaHistory) GetLine(idx int) (string, error) {
|
||||||
histGet := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("get"))
|
histGet := hshMod.Get(moonlight.StringValue("history")).AsTable().Get(moonlight.StringValue("get"))
|
||||||
lcmd, err := rt.Call1(l.MainThread(), histGet, rt.IntValue(int64(idx)))
|
lcmd, err := l.Call1(histGet, moonlight.IntValue(int64(idx)))
|
||||||
|
|
||||||
var cmd string
|
var cmd string
|
||||||
if lcmd.Type() == rt.StringType {
|
if lcmd.Type() == moonlight.StringType {
|
||||||
cmd = lcmd.AsString()
|
cmd = lcmd.AsString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,11 +37,11 @@ func (h *luaHistory) GetLine(idx int) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *luaHistory) Len() int {
|
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, _ := rt.Call1(l.MainThread(), histSize)
|
ln, _ := l.Call1(histSize)
|
||||||
|
|
||||||
var num int64
|
var num int64
|
||||||
if ln.Type() == rt.IntType {
|
if ln.Type() == moonlight.IntType {
|
||||||
num = ln.AsInt()
|
num = ln.AsInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
job.go
21
job.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"hilbish/moonlight"
|
||||||
"hilbish/util"
|
"hilbish/util"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
|
@ -260,7 +261,7 @@ func (j *jobHandler) add(cmd string, args []string, path string) *job {
|
||||||
stdout: &bytes.Buffer{},
|
stdout: &bytes.Buffer{},
|
||||||
stderr: &bytes.Buffer{},
|
stderr: &bytes.Buffer{},
|
||||||
}
|
}
|
||||||
jb.ud = jobUserData(jb)
|
//jb.ud = jobUserData(jb)
|
||||||
|
|
||||||
j.jobs[j.latestID] = jb
|
j.jobs[j.latestID] = jb
|
||||||
hooks.Emit("job.add", rt.UserDataValue(jb.ud))
|
hooks.Emit("job.add", rt.UserDataValue(jb.ud))
|
||||||
|
@ -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
|
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. */
|
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()
|
jobMethods := rt.NewTable()
|
||||||
jFuncs := map[string]util.LuaExport{
|
jFuncs := map[string]util.LuaExport{
|
||||||
"stop": {luaStopJob, 1, false},
|
"stop": {luaStopJob, 1, false},
|
||||||
|
@ -319,7 +321,9 @@ func (j *jobHandler) loader(rtm *rt.Runtime) *rt.Table {
|
||||||
"background": {luaBackgroundJob, 1, false},
|
"background": {luaBackgroundJob, 1, false},
|
||||||
}
|
}
|
||||||
util.SetExports(l, jobMethods, jFuncs)
|
util.SetExports(l, jobMethods, jFuncs)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
jobMeta := rt.NewTable()
|
jobMeta := rt.NewTable()
|
||||||
jobIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
jobIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
j, _ := jobArg(c, 0)
|
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)))
|
jobMeta.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(jobIndex, "__index", 2, false)))
|
||||||
l.SetRegistry(jobMetaKey, rt.TableValue(jobMeta))
|
l.SetRegistry(jobMetaKey, rt.TableValue(jobMeta))
|
||||||
|
*/
|
||||||
|
|
||||||
jobFuncs := map[string]util.LuaExport{
|
jobFuncs := map[string]moonlight.Export{
|
||||||
|
/*
|
||||||
"all": {j.luaAllJobs, 0, false},
|
"all": {j.luaAllJobs, 0, false},
|
||||||
"last": {j.luaLastJob, 0, false},
|
"last": {j.luaLastJob, 0, false},
|
||||||
"get": {j.luaGetJob, 1, false},
|
"get": {j.luaGetJob, 1, false},
|
||||||
"add": {j.luaAddJob, 3, false},
|
"add": {j.luaAddJob, 3, false},
|
||||||
"disown": {j.luaDisownJob, 1, false},
|
"disown": {j.luaDisownJob, 1, false},
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
luaJob := rt.NewTable()
|
luaJob := moonlight.NewTable()
|
||||||
util.SetExports(rtm, luaJob, jobFuncs)
|
l.SetExports(luaJob, jobFuncs)
|
||||||
|
|
||||||
return luaJob
|
return luaJob
|
||||||
}
|
}
|
||||||
|
@ -382,10 +389,12 @@ func valueToJob(val rt.Value) (*job, bool) {
|
||||||
return j, ok
|
return j, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func jobUserData(j *job) *rt.UserData {
|
func jobUserData(j *job) *rt.UserData {
|
||||||
jobMeta := l.Registry(jobMetaKey)
|
jobMeta := l.UnderlyingRuntime().Registry(jobMetaKey)
|
||||||
return rt.NewUserData(j, jobMeta.AsTable())
|
return rt.NewUserData(j, jobMeta.AsTable())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// #interface jobs
|
// #interface jobs
|
||||||
// get(id) -> @Job
|
// get(id) -> @Job
|
||||||
|
|
42
lua.go
42
lua.go
|
@ -4,47 +4,41 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hilbish/util"
|
//"hilbish/util"
|
||||||
"hilbish/golibs/bait"
|
"hilbish/golibs/bait"
|
||||||
"hilbish/golibs/commander"
|
"hilbish/golibs/commander"
|
||||||
"hilbish/golibs/fs"
|
"hilbish/golibs/fs"
|
||||||
"hilbish/golibs/terminal"
|
"hilbish/golibs/terminal"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
"hilbish/moonlight"
|
||||||
"github.com/arnodel/golua/lib"
|
|
||||||
"github.com/arnodel/golua/lib/debuglib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var minimalconf = `hilbish.prompt '& '`
|
var minimalconf = `hilbish.prompt '& '`
|
||||||
|
|
||||||
func luaInit() {
|
func luaInit() {
|
||||||
l = rt.New(os.Stdout)
|
l = moonlight.NewRuntime()
|
||||||
l.PushContext(rt.RuntimeContextDef{
|
setupSinkType()
|
||||||
MessageHandler: debuglib.Traceback,
|
|
||||||
})
|
|
||||||
lib.LoadAll(l)
|
|
||||||
setupSinkType(l)
|
|
||||||
|
|
||||||
lib.LoadLibs(l, hilbishLoader)
|
l.LoadLibrary(hilbishLoader, "hilbish")
|
||||||
// yes this is stupid, i know
|
// 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
|
// Add fs and terminal module module to Lua
|
||||||
f := fs.New(runner)
|
f := fs.New(runner)
|
||||||
lib.LoadLibs(l, f.Loader)
|
l.LoadLibrary(f.Loader, "fs")
|
||||||
lib.LoadLibs(l, terminal.Loader)
|
|
||||||
|
l.LoadLibrary(terminal.Loader, "terminal")
|
||||||
|
|
||||||
cmds = commander.New(l)
|
cmds = commander.New(l)
|
||||||
lib.LoadLibs(l, cmds.Loader)
|
l.LoadLibrary(cmds.Loader, "commander")
|
||||||
|
|
||||||
hooks = bait.New(l)
|
hooks = bait.New(l)
|
||||||
hooks.SetRecoverer(func(event string, handler *bait.Listener, err interface{}) {
|
hooks.SetRecoverer(func(event string, handler *bait.Listener, err interface{}) {
|
||||||
fmt.Println("Error in `error` hook handler:", err)
|
fmt.Println("Error in `error` hook handler:", err)
|
||||||
hooks.Off(event, handler)
|
hooks.Off(event, handler)
|
||||||
})
|
})
|
||||||
|
l.LoadLibrary(hooks.Loader, "bait")
|
||||||
lib.LoadLibs(l, hooks.Loader)
|
/*
|
||||||
|
|
||||||
// Add Ctrl-C handler
|
// Add Ctrl-C handler
|
||||||
hooks.On("signal.sigint", func(...interface{}) {
|
hooks.On("signal.sigint", func(...interface{}) {
|
||||||
if !interactive {
|
if !interactive {
|
||||||
|
@ -55,16 +49,18 @@ func luaInit() {
|
||||||
lr.rl.RawInputCallback = func(r []rune) {
|
lr.rl.RawInputCallback = func(r []rune) {
|
||||||
hooks.Emit("hilbish.rawInput", string(r))
|
hooks.Emit("hilbish.rawInput", string(r))
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Add more paths that Lua can require from
|
// 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 {
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
fmt.Fprintln(os.Stderr, "Could not add Hilbish require paths! Libraries will be missing. This shouldn't happen.")
|
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 {
|
if err1 != nil {
|
||||||
err2 := util.DoFile(l, preloadPath)
|
err2 := l.DoFile(preloadPath)
|
||||||
if err2 != nil {
|
if err2 != nil {
|
||||||
fmt.Fprintln(os.Stderr, "Missing nature module, some functionality and builtins will be missing.")
|
fmt.Fprintln(os.Stderr, "Missing nature module, some functionality and builtins will be missing.")
|
||||||
fmt.Fprintln(os.Stderr, "local error:", err1)
|
fmt.Fprintln(os.Stderr, "local error:", err1)
|
||||||
|
@ -77,9 +73,9 @@ func runConfig(confpath string) {
|
||||||
if !interactive {
|
if !interactive {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err := util.DoFile(l, confpath)
|
err := l.DoFile(confpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err, "\nAn error has occured while loading your config! Falling back to minimal default config.")
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
//go:build !midnight
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"hilbish/moonlight"
|
||||||
|
rt "github.com/arnodel/golua/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
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")
|
||||||
|
}
|
11
main.go
11
main.go
|
@ -16,6 +16,7 @@ import (
|
||||||
"hilbish/util"
|
"hilbish/util"
|
||||||
"hilbish/golibs/bait"
|
"hilbish/golibs/bait"
|
||||||
"hilbish/golibs/commander"
|
"hilbish/golibs/commander"
|
||||||
|
"hilbish/moonlight"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
"github.com/pborman/getopt"
|
"github.com/pborman/getopt"
|
||||||
|
@ -25,7 +26,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
l *rt.Runtime
|
l *moonlight.Runtime
|
||||||
lr *lineReader
|
lr *lineReader
|
||||||
|
|
||||||
luaCompletions = map[string]*rt.Closure{}
|
luaCompletions = map[string]*rt.Closure{}
|
||||||
|
@ -169,13 +170,13 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if getopt.NArgs() > 0 {
|
if getopt.NArgs() > 0 {
|
||||||
luaArgs := rt.NewTable()
|
luaArgs := moonlight.NewTable()
|
||||||
for i, arg := range getopt.Args() {
|
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.GlobalEnv().Set(rt.StringValue("args"), rt.TableValue(luaArgs))
|
l.GlobalTable().SetField("args", moonlight.TableValue(luaArgs))
|
||||||
err := util.DoFile(l, getopt.Arg(0))
|
err := l.DoFile(getopt.Arg(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
24
module.go
24
module.go
|
@ -3,9 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"plugin"
|
"plugin"
|
||||||
|
|
||||||
"hilbish/util"
|
"hilbish/moonlight"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// #interface module
|
// #interface module
|
||||||
|
@ -46,13 +44,13 @@ func Loader(rtm *rt.Runtime) rt.Value {
|
||||||
This can be compiled with `go build -buildmode=plugin plugin.go`.
|
This can be compiled with `go build -buildmode=plugin plugin.go`.
|
||||||
If you attempt to require and print the result (`print(require 'plugin')`), it will show "hello world!"
|
If you attempt to require and print the result (`print(require 'plugin')`), it will show "hello world!"
|
||||||
*/
|
*/
|
||||||
func moduleLoader(rtm *rt.Runtime) *rt.Table {
|
func moduleLoader(mlr *moonlight.Runtime) *moonlight.Table {
|
||||||
exports := map[string]util.LuaExport{
|
exports := map[string]moonlight.Export{
|
||||||
"load": {moduleLoad, 2, false},
|
"load": {moduleLoad, 2, false},
|
||||||
}
|
}
|
||||||
|
|
||||||
mod := rt.NewTable()
|
mod := moonlight.NewTable()
|
||||||
util.SetExports(rtm, mod, exports)
|
mlr.SetExports(mod, exports)
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
}
|
}
|
||||||
|
@ -62,12 +60,12 @@ func moduleLoader(rtm *rt.Runtime) *rt.Table {
|
||||||
// Loads a module at the designated `path`.
|
// Loads a module at the designated `path`.
|
||||||
// It will throw if any error occurs.
|
// It will throw if any error occurs.
|
||||||
// #param path string
|
// #param path string
|
||||||
func moduleLoad(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func moduleLoad(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
if err := c.CheckNArgs(1); err != nil {
|
if err := mlr.Check1Arg(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
path, err := c.StringArg(0)
|
path, err := mlr.StringArg(c, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -82,12 +80,12 @@ func moduleLoad(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
loader, ok := value.(func(*rt.Runtime) rt.Value)
|
loader, ok := value.(func(*moonlight.Runtime) moonlight.Value)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
val := loader(t.Runtime)
|
val := loader(mlr)
|
||||||
|
|
||||||
return c.PushingNext1(t.Runtime, val), nil
|
return mlr.PushNext1(c, val), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
//go:build !midnight
|
||||||
|
package moonlight
|
||||||
|
|
||||||
|
import (
|
||||||
|
rt "github.com/arnodel/golua/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GoCont struct{
|
||||||
|
cont *rt.GoCont
|
||||||
|
thread *rt.Thread
|
||||||
|
}
|
||||||
|
|
||||||
|
type Cont = rt.Cont
|
||||||
|
type Closure = rt.Closure
|
||||||
|
|
||||||
|
func (gc *GoCont) Next() Cont {
|
||||||
|
return gc.cont.Next()
|
||||||
|
}
|
|
@ -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)))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build !midnight
|
||||||
|
package moonlight
|
||||||
|
|
||||||
|
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,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)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
//go:build !midnight
|
||||||
|
package moonlight
|
||||||
|
|
||||||
|
import (
|
||||||
|
rt "github.com/arnodel/golua/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GoFunctionFunc = rt.GoFunctionFunc
|
||||||
|
|
||||||
|
func (mlr *Runtime) CheckNArgs(c *GoCont, num int) error {
|
||||||
|
return c.cont.CheckNArgs(num)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlr *Runtime) Check1Arg(c *GoCont) error {
|
||||||
|
return c.cont.CheckNArgs(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlr *Runtime) StringArg(c *GoCont, num int) (string, error) {
|
||||||
|
return c.cont.StringArg(num)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlr *Runtime) ClosureArg(c *GoCont, num int) (*Closure, error) {
|
||||||
|
return c.cont.ClosureArg(num)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlr *Runtime) Arg(c *GoCont, num int) Value {
|
||||||
|
return c.cont.Arg(num)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlr *Runtime) GoFunction(fun GoToLuaFunc) GoFunctionFunc {
|
||||||
|
return func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
gocont := GoCont{
|
||||||
|
cont: c,
|
||||||
|
thread: t,
|
||||||
|
}
|
||||||
|
return fun(mlr, &gocont)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
//go:build !midnight
|
||||||
|
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,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())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
//go:build !midnight
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push will push a Lua value onto the stack.
|
||||||
|
func (mlr *Runtime) Push(c *GoCont, v Value) {
|
||||||
|
c.cont.Push(c.thread.Runtime, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
//go:build !midnight
|
||||||
|
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 (t *Table) Set(key Value, value Value) {
|
||||||
|
t.lt.Set(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ForEach(tbl *Table, cb func(key Value, val Value)) {
|
||||||
|
nextVal := rt.NilValue
|
||||||
|
for {
|
||||||
|
key, val, _ := tbl.lt.Next(nextVal)
|
||||||
|
if key == rt.NilValue {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
nextVal = key
|
||||||
|
|
||||||
|
cb(Value(key), Value(val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mlr *Runtime) GlobalTable() *Table {
|
||||||
|
return &Table{
|
||||||
|
lt: mlr.rt.GlobalEnv(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertToMoonlightTable(t *rt.Table) *Table {
|
||||||
|
return &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)
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
//go:build !midnight
|
||||||
|
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) (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,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
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
//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)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IntValue(i int64) Value {
|
||||||
|
return rt.IntValue(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BoolValue(b bool) Value {
|
||||||
|
return rt.BoolValue(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TableValue(t *Table) Value {
|
||||||
|
return rt.TableValue(t.lt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToString(v Value) string {
|
||||||
|
return v.AsString()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToTable(v Value) *Table {
|
||||||
|
return convertToMoonlightTable(v.AsTable())
|
||||||
|
}
|
||||||
|
|
||||||
|
func AsValue(v interface{}) Value {
|
||||||
|
return rt.AsValue(v)
|
||||||
|
}
|
14
os.go
14
os.go
|
@ -1,9 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"hilbish/util"
|
"hilbish/moonlight"
|
||||||
|
//"hilbish/util"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
|
||||||
"github.com/blackfireio/osinfo"
|
"github.com/blackfireio/osinfo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -14,13 +14,13 @@ import (
|
||||||
// #field family Family name of the current OS
|
// #field family Family name of the current OS
|
||||||
// #field name Pretty name of the current OS
|
// #field name Pretty name of the current OS
|
||||||
// #field version Version 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()
|
info, _ := osinfo.GetOSInfo()
|
||||||
mod := rt.NewTable()
|
mod := moonlight.NewTable()
|
||||||
|
|
||||||
util.SetField(rtm, mod, "family", rt.StringValue(info.Family))
|
mod.SetField("family", moonlight.StringValue(info.Family))
|
||||||
util.SetField(rtm, mod, "name", rt.StringValue(info.Name))
|
mod.SetField("name", moonlight.StringValue(info.Name))
|
||||||
util.SetField(rtm, mod, "version", rt.StringValue(info.Version))
|
mod.SetField("version", moonlight.StringValue(info.Version))
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
}
|
}
|
||||||
|
|
103
rl.go
103
rl.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"hilbish/moonlight"
|
||||||
"hilbish/util"
|
"hilbish/util"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
|
@ -27,7 +28,7 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
||||||
|
|
||||||
regexSearcher := rl.Searcher
|
regexSearcher := rl.Searcher
|
||||||
rl.Searcher = func(needle string, haystack []string) []string {
|
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()
|
fuzz, ok := fz.TryBool()
|
||||||
if !fuzz || !ok {
|
if !fuzz || !ok {
|
||||||
return regexSearcher(needle, haystack)
|
return regexSearcher(needle, haystack)
|
||||||
|
@ -70,9 +71,8 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
||||||
hooks.Emit("hilbish.vimAction", actionStr, args)
|
hooks.Emit("hilbish.vimAction", actionStr, args)
|
||||||
}
|
}
|
||||||
rl.HintText = func(line []rune, pos int) []rune {
|
rl.HintText = func(line []rune, pos int) []rune {
|
||||||
hinter := hshMod.Get(rt.StringValue("hinter"))
|
hinter := hshMod.Get(moonlight.StringValue("hinter"))
|
||||||
retVal, err := rt.Call1(l.MainThread(), hinter,
|
retVal, err := l.Call1(hinter, moonlight.StringValue(string(line)), moonlight.IntValue(int64(pos)))
|
||||||
rt.StringValue(string(line)), rt.IntValue(int64(pos)))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return []rune{}
|
return []rune{}
|
||||||
|
@ -86,9 +86,8 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
||||||
return []rune(hintText)
|
return []rune(hintText)
|
||||||
}
|
}
|
||||||
rl.SyntaxHighlighter = func(line []rune) string {
|
rl.SyntaxHighlighter = func(line []rune) string {
|
||||||
highlighter := hshMod.Get(rt.StringValue("highlighter"))
|
highlighter := hshMod.Get(moonlight.StringValue("highlighter"))
|
||||||
retVal, err := rt.Call1(l.MainThread(), highlighter,
|
retVal, err := l.Call1(highlighter, moonlight.StringValue(string(line)))
|
||||||
rt.StringValue(string(line)))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return string(line)
|
return string(line)
|
||||||
|
@ -101,93 +100,7 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
||||||
|
|
||||||
return highlighted
|
return highlighted
|
||||||
}
|
}
|
||||||
rl.TabCompleter = func(line []rune, pos int, _ readline.DelayedTabContext) (string, []*readline.CompletionGroup) {
|
setupTabCompleter(rl)
|
||||||
term := rt.NewTerminationWith(l.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)),
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
return lr
|
return lr
|
||||||
}
|
}
|
||||||
|
@ -246,11 +159,13 @@ func (lr *lineReader) Resize() {
|
||||||
// method of saving history.
|
// method of saving history.
|
||||||
func (lr *lineReader) Loader(rtm *rt.Runtime) *rt.Table {
|
func (lr *lineReader) Loader(rtm *rt.Runtime) *rt.Table {
|
||||||
lrLua := map[string]util.LuaExport{
|
lrLua := map[string]util.LuaExport{
|
||||||
|
/*
|
||||||
"add": {lr.luaAddHistory, 1, false},
|
"add": {lr.luaAddHistory, 1, false},
|
||||||
"all": {lr.luaAllHistory, 0, false},
|
"all": {lr.luaAllHistory, 0, false},
|
||||||
"clear": {lr.luaClearHistory, 0, false},
|
"clear": {lr.luaClearHistory, 0, false},
|
||||||
"get": {lr.luaGetHistory, 1, false},
|
"get": {lr.luaGetHistory, 1, false},
|
||||||
"size": {lr.luaSize, 0, false},
|
"size": {lr.luaSize, 0, false},
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
mod := rt.NewTable()
|
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,99 @@
|
||||||
|
//go:build !midnight
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hilbish/util"
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"hilbish/util"
|
"hilbish/moonlight"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// #interface runner
|
// #interface runner
|
||||||
|
@ -49,15 +47,15 @@ hilbish.runnerMode(function(input)
|
||||||
end)
|
end)
|
||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
func runnerModeLoader(rtm *rt.Runtime) *rt.Table {
|
func runnerModeLoader(rtm *moonlight.Runtime) *moonlight.Table {
|
||||||
exports := map[string]util.LuaExport{
|
exports := map[string]moonlight.Export{
|
||||||
"sh": {shRunner, 1, false},
|
"sh": {shRunner, 1, false},
|
||||||
"lua": {luaRunner, 1, false},
|
"lua": {luaRunner, 1, false},
|
||||||
"setMode": {hlrunnerMode, 1, false},
|
"setMode": {hlrunnerMode, 1, false},
|
||||||
}
|
}
|
||||||
|
|
||||||
mod := rt.NewTable()
|
mod := moonlight.NewTable()
|
||||||
util.SetExports(rtm, mod, exports)
|
rtm.SetExports(mod, exports)
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
}
|
}
|
||||||
|
@ -76,27 +74,27 @@ func _runnerMode() {}
|
||||||
// Runs a command in Hilbish's shell script interpreter.
|
// Runs a command in Hilbish's shell script interpreter.
|
||||||
// This is the equivalent of using `source`.
|
// This is the equivalent of using `source`.
|
||||||
// #param cmd string
|
// #param cmd string
|
||||||
func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func shRunner(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
if err := c.Check1Arg(); err != nil {
|
if err := mlr.Check1Arg(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cmd, err := c.StringArg(0)
|
cmd, err := mlr.StringArg(c, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, exitCode, cont, err := execSh(aliases.Resolve(cmd))
|
_, exitCode, cont, err := execSh(aliases.Resolve(cmd))
|
||||||
var luaErr rt.Value = rt.NilValue
|
var luaErr moonlight.Value = moonlight.NilValue
|
||||||
if err != nil {
|
if err != nil {
|
||||||
luaErr = rt.StringValue(err.Error())
|
luaErr = moonlight.StringValue(err.Error())
|
||||||
}
|
}
|
||||||
runnerRet := rt.NewTable()
|
runnerRet := moonlight.NewTable()
|
||||||
runnerRet.Set(rt.StringValue("input"), rt.StringValue(cmd))
|
runnerRet.SetField("input", moonlight.StringValue(cmd))
|
||||||
runnerRet.Set(rt.StringValue("exitCode"), rt.IntValue(int64(exitCode)))
|
runnerRet.SetField("exitCode", moonlight.IntValue(int64(exitCode)))
|
||||||
runnerRet.Set(rt.StringValue("continue"), rt.BoolValue(cont))
|
runnerRet.SetField("continue", moonlight.BoolValue(cont))
|
||||||
runnerRet.Set(rt.StringValue("err"), luaErr)
|
runnerRet.SetField("err", luaErr)
|
||||||
|
|
||||||
return c.PushingNext(t.Runtime, rt.TableValue(runnerRet)), nil
|
return mlr.PushNext1(c, moonlight.TableValue(runnerRet)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// #interface runner
|
// #interface runner
|
||||||
|
@ -104,24 +102,25 @@ func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
// Evaluates `cmd` as Lua input. This is the same as using `dofile`
|
// Evaluates `cmd` as Lua input. This is the same as using `dofile`
|
||||||
// or `load`, but is appropriated for the runner interface.
|
// or `load`, but is appropriated for the runner interface.
|
||||||
// #param cmd string
|
// #param cmd string
|
||||||
func luaRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
func luaRunner(mlr *moonlight.Runtime, c *moonlight.GoCont) (moonlight.Cont, error) {
|
||||||
if err := c.Check1Arg(); err != nil {
|
if err := mlr.Check1Arg(c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cmd, err := c.StringArg(0)
|
cmd, err := mlr.StringArg(c, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
input, exitCode, err := handleLua(cmd)
|
input, exitCode, err := handleLua(cmd)
|
||||||
var luaErr rt.Value = rt.NilValue
|
var luaErr moonlight.Value = moonlight.NilValue
|
||||||
if err != nil {
|
if err != nil {
|
||||||
luaErr = rt.StringValue(err.Error())
|
luaErr = moonlight.StringValue(err.Error())
|
||||||
}
|
}
|
||||||
runnerRet := rt.NewTable()
|
runnerRet := moonlight.NewTable()
|
||||||
runnerRet.Set(rt.StringValue("input"), rt.StringValue(input))
|
runnerRet.SetField("input", moonlight.StringValue(input))
|
||||||
runnerRet.Set(rt.StringValue("exitCode"), rt.IntValue(int64(exitCode)))
|
runnerRet.SetField("exitCode", moonlight.IntValue(int64(exitCode)))
|
||||||
runnerRet.Set(rt.StringValue("err"), luaErr)
|
runnerRet.SetField("err", luaErr)
|
||||||
|
|
||||||
return c.PushingNext(t.Runtime, rt.TableValue(runnerRet)), nil
|
|
||||||
|
return mlr.PushNext1(c, moonlight.TableValue(runnerRet)), nil
|
||||||
}
|
}
|
||||||
|
|
26
sink.go
26
sink.go
|
@ -7,7 +7,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"hilbish/util"
|
//"hilbish/util"
|
||||||
|
"hilbish/moonlight"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
)
|
)
|
||||||
|
@ -25,20 +26,22 @@ type sink struct{
|
||||||
autoFlush bool
|
autoFlush bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupSinkType(rtm *rt.Runtime) {
|
func setupSinkType() {
|
||||||
sinkMeta := rt.NewTable()
|
//sinkMeta := moonlight.NewTable()
|
||||||
|
|
||||||
sinkMethods := rt.NewTable()
|
sinkMethods := moonlight.NewTable()
|
||||||
sinkFuncs := map[string]util.LuaExport{
|
sinkFuncs := map[string]moonlight.Export{
|
||||||
|
/*
|
||||||
"flush": {luaSinkFlush, 1, false},
|
"flush": {luaSinkFlush, 1, false},
|
||||||
"read": {luaSinkRead, 1, false},
|
"read": {luaSinkRead, 1, false},
|
||||||
"readAll": {luaSinkReadAll, 1, false},
|
"readAll": {luaSinkReadAll, 1, false},
|
||||||
"autoFlush": {luaSinkAutoFlush, 2, false},
|
"autoFlush": {luaSinkAutoFlush, 2, false},
|
||||||
"write": {luaSinkWrite, 2, false},
|
"write": {luaSinkWrite, 2, false},
|
||||||
"writeln": {luaSinkWriteln, 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) {
|
sinkIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
s, _ := sinkArg(c, 0)
|
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)))
|
sinkMeta.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(sinkIndex, "__index", 2, false)))
|
||||||
l.SetRegistry(sinkMetaKey, rt.TableValue(sinkMeta))
|
l.SetRegistry(sinkMetaKey, rt.TableValue(sinkMeta))
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,7 +220,7 @@ func newSinkInput(r io.Reader) *sink {
|
||||||
s := &sink{
|
s := &sink{
|
||||||
reader: bufio.NewReader(r),
|
reader: bufio.NewReader(r),
|
||||||
}
|
}
|
||||||
s.ud = sinkUserData(s)
|
//s.ud = sinkUserData(s)
|
||||||
|
|
||||||
if f, ok := r.(*os.File); ok {
|
if f, ok := r.(*os.File); ok {
|
||||||
s.file = f
|
s.file = f
|
||||||
|
@ -230,7 +234,7 @@ func newSinkOutput(w io.Writer) *sink {
|
||||||
writer: bufio.NewWriter(w),
|
writer: bufio.NewWriter(w),
|
||||||
autoFlush: true,
|
autoFlush: true,
|
||||||
}
|
}
|
||||||
s.ud = sinkUserData(s)
|
//s.ud = sinkUserData(s)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
@ -254,7 +258,9 @@ func valueToSink(val rt.Value) (*sink, bool) {
|
||||||
return s, ok
|
return s, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func sinkUserData(s *sink) *rt.UserData {
|
func sinkUserData(s *sink) *rt.UserData {
|
||||||
sinkMeta := l.Registry(sinkMetaKey)
|
sinkMeta := l.UnderlyingRuntime().Registry(sinkMetaKey)
|
||||||
return rt.NewUserData(s, sinkMeta.AsTable())
|
return rt.NewUserData(s, sinkMeta.AsTable())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
10
timer.go
10
timer.go
|
@ -2,10 +2,12 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
// "fmt"
|
||||||
"os"
|
// "os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
// "hilbish/moonlight"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,7 +49,8 @@ func (t *timer) start() error {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-t.ticker.C:
|
case <-t.ticker.C:
|
||||||
_, err := rt.Call1(l.MainThread(), rt.FunctionValue(t.fun))
|
/*
|
||||||
|
_, err := l.Call1(moonlight.FunctionValue(t.fun))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "Error in function:\n", err)
|
fmt.Fprintln(os.Stderr, "Error in function:\n", err)
|
||||||
t.stop()
|
t.stop()
|
||||||
|
@ -56,6 +59,7 @@ func (t *timer) start() error {
|
||||||
if t.typ == timerTimeout {
|
if t.typ == timerTimeout {
|
||||||
t.stop()
|
t.stop()
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
case <-t.channel:
|
case <-t.channel:
|
||||||
t.ticker.Stop()
|
t.ticker.Stop()
|
||||||
return
|
return
|
||||||
|
|
|
@ -5,7 +5,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hilbish/util"
|
"hilbish/moonlight"
|
||||||
|
//"hilbish/util"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
)
|
)
|
||||||
|
@ -47,7 +48,7 @@ func (th *timersModule) create(typ timerType, dur time.Duration, fun *rt.Closure
|
||||||
th: th,
|
th: th,
|
||||||
id: th.latestID,
|
id: th.latestID,
|
||||||
}
|
}
|
||||||
t.ud = timerUserData(t)
|
//t.ud = timerUserData(t)
|
||||||
|
|
||||||
th.timers[th.latestID] = t
|
th.timers[th.latestID] = t
|
||||||
|
|
||||||
|
@ -133,14 +134,17 @@ t:start()
|
||||||
print(t.running) // true
|
print(t.running) // true
|
||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
func (th *timersModule) loader(rtm *rt.Runtime) *rt.Table {
|
func (th *timersModule) loader() *moonlight.Table {
|
||||||
timerMethods := rt.NewTable()
|
timerMethods := moonlight.NewTable()
|
||||||
timerFuncs := map[string]util.LuaExport{
|
timerFuncs := map[string]moonlight.Export{
|
||||||
|
/*
|
||||||
"start": {timerStart, 1, false},
|
"start": {timerStart, 1, false},
|
||||||
"stop": {timerStop, 1, false},
|
"stop": {timerStop, 1, false},
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
util.SetExports(rtm, timerMethods, timerFuncs)
|
l.SetExports(timerMethods, timerFuncs)
|
||||||
|
|
||||||
|
/*
|
||||||
timerMeta := rt.NewTable()
|
timerMeta := rt.NewTable()
|
||||||
timerIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
timerIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
ti, _ := timerArg(c, 0)
|
ti, _ := timerArg(c, 0)
|
||||||
|
@ -164,18 +168,21 @@ func (th *timersModule) loader(rtm *rt.Runtime) *rt.Table {
|
||||||
}
|
}
|
||||||
|
|
||||||
timerMeta.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(timerIndex, "__index", 2, false)))
|
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},
|
"create": {th.luaCreate, 3, false},
|
||||||
"get": {th.luaGet, 1, false},
|
"get": {th.luaGet, 1, false},
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
luaTh := rt.NewTable()
|
luaTh := moonlight.NewTable()
|
||||||
util.SetExports(rtm, luaTh, thExports)
|
l.SetExports(luaTh, thExports)
|
||||||
|
|
||||||
util.SetField(rtm, luaTh, "INTERVAL", rt.IntValue(0))
|
luaTh.SetField("INTERVAL", moonlight.IntValue(0))
|
||||||
util.SetField(rtm, luaTh, "TIMEOUT", rt.IntValue(1))
|
luaTh.SetField("TIMEOUT", moonlight.IntValue(1))
|
||||||
|
|
||||||
return luaTh
|
return luaTh
|
||||||
}
|
}
|
||||||
|
@ -199,7 +206,9 @@ func valueToTimer(val rt.Value) (*timer, bool) {
|
||||||
return j, ok
|
return j, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func timerUserData(j *timer) *rt.UserData {
|
func timerUserData(j *timer) *rt.UserData {
|
||||||
timerMeta := l.Registry(timerMetaKey)
|
timerMeta := l.UnderlyingRuntime().Registry(timerMetaKey)
|
||||||
return rt.NewUserData(j, timerMeta.AsTable())
|
return rt.NewUserData(j, timerMeta.AsTable())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
12
userdir.go
12
userdir.go
|
@ -1,9 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"hilbish/util"
|
"hilbish/moonlight"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// #interface userDir
|
// #interface userDir
|
||||||
|
@ -13,11 +11,11 @@ import (
|
||||||
// for configs and data.
|
// for configs and data.
|
||||||
// #field config The user's config directory
|
// #field config The user's config directory
|
||||||
// #field data The user's directory for program data
|
// #field data The user's directory for program data
|
||||||
func userDirLoader(rtm *rt.Runtime) *rt.Table {
|
func userDirLoader() *moonlight.Table {
|
||||||
mod := rt.NewTable()
|
mod := moonlight.NewTable()
|
||||||
|
|
||||||
util.SetField(rtm, mod, "config", rt.StringValue(confDir))
|
mod.SetField("config", moonlight.StringValue(confDir))
|
||||||
util.SetField(rtm, mod, "data", rt.StringValue(userDataDir))
|
mod.SetField("data", moonlight.StringValue(userDataDir))
|
||||||
|
|
||||||
return mod
|
return mod
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hilbish/moonlight"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LuaExport represents a Go function which can be exported to Lua.
|
// LuaExport represents a Go function which can be exported to Lua.
|
||||||
type LuaExport struct {
|
type LuaExport struct {
|
||||||
Function rt.GoFunctionFunc
|
Function moonlight.GoFunctionFunc
|
||||||
ArgNum int
|
ArgNum int
|
||||||
Variadic bool
|
Variadic bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetExports puts the Lua function exports in the table.
|
// SetExports puts the Lua function exports in the table.
|
||||||
func SetExports(rtm *rt.Runtime, tbl *rt.Table, exports map[string]LuaExport) {
|
func SetExports(rtm *rt.Runtime, tbl *rt.Table, exports map[string]LuaExport) {
|
||||||
|
/*
|
||||||
for name, export := range exports {
|
for name, export := range exports {
|
||||||
rtm.SetEnvGoFunc(tbl, name, export.Function, export.ArgNum, export.Variadic)
|
rtm.SetEnvGoFunc(tbl, name, export.Function, export.ArgNum, export.Variadic)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
86
util/util.go
86
util/util.go
|
@ -1,103 +1,31 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"io"
|
|
||||||
"strings"
|
"strings"
|
||||||
"os"
|
|
||||||
"os/user"
|
"os/user"
|
||||||
|
|
||||||
|
"hilbish/moonlight"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
rt "github.com/arnodel/golua/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetField sets a field in a table, adding docs for it.
|
// 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.
|
// 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) {
|
func SetField(module *rt.Table, field string, value rt.Value) {
|
||||||
// TODO: ^ rtm isnt needed, i should remove it
|
|
||||||
module.Set(rt.StringValue(field), 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
|
// HandleStrCallback handles function parameters for Go functions which take
|
||||||
// a string and a closure.
|
// a string and a closure.
|
||||||
func HandleStrCallback(t *rt.Thread, c *rt.GoCont) (string, *rt.Closure, error) {
|
func HandleStrCallback(mlr *moonlight.Runtime, c *moonlight.GoCont) (string, *moonlight.Closure, error) {
|
||||||
if err := c.CheckNArgs(2); err != nil {
|
if err := mlr.CheckNArgs(c, 2); err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
name, err := c.StringArg(0)
|
name, err := mlr.StringArg(c, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
cb, err := c.ClosureArg(1)
|
cb, err := mlr.ClosureArg(c, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue