Compare commits

..

No commits in common. "26add6728750b5f793aaf74a59a7ae3cbb76bff1" and "016a3a2ec7a393aed4116bc9fa89c8bab5604f2a" have entirely different histories.

6 changed files with 30 additions and 124 deletions

View File

@ -1,6 +1,6 @@
-- Default Hilbish config
local lunacolors = require 'lunacolors'
local bait = require 'bait'
--local bait = require 'bait'
local ansikit = require 'ansikit'
local function doPrompt(fail)
@ -13,6 +13,7 @@ print(lunacolors.format(hilbish.greeting))
doPrompt()
--[[
bait.catch('command.exit', function(code)
doPrompt(code ~= 0)
end)
@ -24,3 +25,4 @@ bait.catch('hilbish.vimMode', function(mode)
ansikit.cursorStyle(ansikit.lineCursor)
end
end)
]]--

2
api.go
View File

@ -271,7 +271,7 @@ func hlprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
}
lr.SetPrompt(fmtPrompt(prompt))
return c.Next(), nil
return nil, nil
}
// multiprompt(str)

View File

@ -114,10 +114,8 @@ func handleLua(cmdString string) (uint8, error) {
}
// And if there's no syntax errors and -n isnt provided, run
if !noexecute {
if chunk != nil {
_, err = rt.Call1(l.MainThread(), rt.FunctionValue(chunk))
}
}
if err == nil {
return 0, nil
}
@ -447,6 +445,5 @@ func cmdFinish(code uint8, cmdstr string, private bool) {
handleHistory(cmdstr)
}
// util.SetField(l, hshMod, "exitCode", lua.LNumber(code), "Exit code of last exected command")
// using AsValue on an interface which is an int results in it being unknown .... ????
hooks.Em.Emit("command.exit", rt.IntValue(int64(code)), cmdstr)
hooks.Em.Emit("command.exit", code, cmdstr)
}

View File

@ -5,13 +5,12 @@ import (
"hilbish/util"
"github.com/chuckpreslar/emission"
rt "github.com/arnodel/golua/runtime"
"github.com/arnodel/golua/lib/packagelib"
"github.com/yuin/gopher-lua"
"layeh.com/gopher-luar"
)
type Bait struct{
Em *emission.Emitter
Loader packagelib.Loader
}
func New() Bait {
@ -20,27 +19,14 @@ func New() Bait {
emitter.Off(hookname, hookfunc)
fmt.Println(err)
})
b := Bait{
return Bait{
Em: emitter,
}
b.Loader = packagelib.Loader{
Load: b.LoaderFunc,
Name: "bait",
}
return b
}
func (b *Bait) Loader(L *lua.LState) int {
mod := L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{})
func (b *Bait) LoaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
exports := map[string]util.LuaExport{
"catch": util.LuaExport{b.bcatch, 2, false},
"catchOnce": util.LuaExport{b.bcatchOnce, 2, false},
"throw": util.LuaExport{b.bthrow, 1, true},
}
mod := rt.NewTable()
util.SetExports(rtm, mod, exports)
/*
util.Document(L, mod,
`Bait is the event emitter for Hilbish. Why name it bait?
Because it throws hooks that you can catch (emits events
@ -49,99 +35,36 @@ is fun. This is what you will use if you want to listen
in on hooks to know when certain things have happened,
like when you've changed directory, a command has
failed, etc. To find all available hooks, see doc hooks.`)
*/
return rt.TableValue(mod), nil
}
L.SetField(mod, "throw", luar.New(L, b.bthrow))
L.SetField(mod, "catch", luar.New(L, b.bcatch))
L.SetField(mod, "catchOnce", luar.New(L, b.bcatchOnce))
func handleArgs(t *rt.Thread, c *rt.GoCont) (string, *rt.Closure, error) {
if err := c.CheckNArgs(2); err != nil {
return "", nil, err
}
name, err := c.StringArg(0)
if err != nil {
return "", nil, err
}
catcher, err := c.ClosureArg(1)
if err != nil {
return "", nil, err
}
L.Push(mod)
return name, catcher, err
}
func handleHook(t *rt.Thread, c *rt.GoCont, name string, catcher *rt.Closure, args ...interface{}) {
funcVal := rt.FunctionValue(catcher)
var luaArgs []rt.Value
for _, arg := range args {
var luarg rt.Value
switch arg.(type) {
case rt.Value: luarg = arg.(rt.Value)
default: luarg = rt.AsValue(arg)
}
luaArgs = append(luaArgs, luarg)
}
_, err := rt.Call1(t, funcVal, luaArgs...)
if err != nil {
e := rt.NewError(rt.StringValue(err.Error()))
e = e.AddContext(c.Next(), 1)
// panicking here won't actually cause hilbish to panic and instead will
// print the error and remove the hook (look at emission recover from above)
panic(e)
}
return 1
}
// throw(name, ...args)
// Throws a hook with `name` with the provided `args`
// --- @param name string
// --- @vararg any
func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
name, err := c.StringArg(0)
if err != nil {
return nil, err
}
ifaceSlice := make([]interface{}, len(c.Etc()))
for i, v := range c.Etc() {
ifaceSlice[i] = v
}
b.Em.Emit(name, ifaceSlice...)
return c.Next(), nil
func (b *Bait) bthrow(name string, args ...interface{}) {
b.Em.Emit(name, args...)
}
// catch(name, cb)
// Catches a hook with `name`. Runs the `cb` when it is thrown
// --- @param name string
// --- @param cb function
func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
name, catcher, err := handleArgs(t, c)
if err != nil {
return nil, err
}
b.Em.On(name, func(args ...interface{}) {
handleHook(t, c, name, catcher, args...)
})
return c.Next(), nil
func (b *Bait) bcatch(name string, catcher func(...interface{})) {
b.Em.On(name, catcher)
}
// catchOnce(name, cb)
// Same as catch, but only runs the `cb` once and then removes the hook
// --- @param name string
// --- @param cb function
func (b *Bait) bcatchOnce(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
name, catcher, err := handleArgs(t, c)
if err != nil {
return nil, err
}
b.Em.Once(name, func(args ...interface{}) {
handleHook(t, c, name, catcher, args...)
})
return c.Next(), nil
func (b *Bait) bcatchOnce(name string, catcher func(...interface{})) {
b.Em.Once(name, catcher)
}

13
lua.go
View File

@ -4,7 +4,6 @@ import (
"fmt"
"os"
"hilbish/util"
"hilbish/golibs/bait"
/*
"hilbish/golibs/commander"
@ -43,8 +42,7 @@ func luaInit() {
*/
hooks = bait.New()
lib.LoadLibs(l, hooks.Loader)
// l.PreloadModule("bait", hooks.Loader)
// Add Ctrl-C handler
hooks.Em.On("signal.sigint", func() {
if !interactive {
@ -73,9 +71,14 @@ func runConfig(confpath string) {
if !interactive {
return
}
err := util.DoFile(l, confpath)
data, err := os.ReadFile(confpath)
if err != nil {
fmt.Fprintln(os.Stderr, err, "\nAn error has occured while loading your config! Falling back to minimal default config.")
util.DoString(l, minimalconf)
chunk, _ := l.CompileAndLoadLuaChunk("", []byte(minimalconf), rt.TableValue(l.GlobalEnv()))
_, err := rt.Call1(l.MainThread(), rt.FunctionValue(chunk))
fmt.Println(err)
}
chunk, _ := l.CompileAndLoadLuaChunk("", data, rt.TableValue(l.GlobalEnv()))
_, err = rt.Call1(l.MainThread(), rt.FunctionValue(chunk))
fmt.Println("config", err)
}

View File

@ -1,8 +1,6 @@
package util
import (
"os"
"github.com/yuin/gopher-lua"
rt "github.com/arnodel/golua/runtime"
)
@ -38,20 +36,3 @@ func SetField(rtm *rt.Runtime, module *rt.Table, field string, value rt.Value, d
module.Set(rt.StringValue(field), value)
}
func DoString(rtm *rt.Runtime, code string) error {
chunk, err := rtm.CompileAndLoadLuaChunk("", []byte(code), rt.TableValue(rtm.GlobalEnv()))
if chunk != nil {
_, err = rt.Call1(rtm.MainThread(), rt.FunctionValue(chunk))
}
return err
}
func DoFile(rtm *rt.Runtime, filename string) error {
data, err := os.ReadFile(filename)
if err != nil {
return err
}
return DoString(rtm, string(data))
}