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 -- Default Hilbish config
local lunacolors = require 'lunacolors' local lunacolors = require 'lunacolors'
local bait = require 'bait' --local bait = require 'bait'
local ansikit = require 'ansikit' local ansikit = require 'ansikit'
local function doPrompt(fail) local function doPrompt(fail)
@ -13,6 +13,7 @@ print(lunacolors.format(hilbish.greeting))
doPrompt() doPrompt()
--[[
bait.catch('command.exit', function(code) bait.catch('command.exit', function(code)
doPrompt(code ~= 0) doPrompt(code ~= 0)
end) end)
@ -24,3 +25,4 @@ bait.catch('hilbish.vimMode', function(mode)
ansikit.cursorStyle(ansikit.lineCursor) ansikit.cursorStyle(ansikit.lineCursor)
end end
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)) lr.SetPrompt(fmtPrompt(prompt))
return c.Next(), nil return nil, nil
} }
// multiprompt(str) // 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 // And if there's no syntax errors and -n isnt provided, run
if !noexecute { if !noexecute {
if chunk != nil {
_, err = rt.Call1(l.MainThread(), rt.FunctionValue(chunk)) _, err = rt.Call1(l.MainThread(), rt.FunctionValue(chunk))
} }
}
if err == nil { if err == nil {
return 0, nil return 0, nil
} }
@ -447,6 +445,5 @@ func cmdFinish(code uint8, cmdstr string, private bool) {
handleHistory(cmdstr) handleHistory(cmdstr)
} }
// util.SetField(l, hshMod, "exitCode", lua.LNumber(code), "Exit code of last exected command") // 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", code, cmdstr)
hooks.Em.Emit("command.exit", rt.IntValue(int64(code)), cmdstr)
} }

View File

@ -5,13 +5,12 @@ import (
"hilbish/util" "hilbish/util"
"github.com/chuckpreslar/emission" "github.com/chuckpreslar/emission"
rt "github.com/arnodel/golua/runtime" "github.com/yuin/gopher-lua"
"github.com/arnodel/golua/lib/packagelib" "layeh.com/gopher-luar"
) )
type Bait struct{ type Bait struct{
Em *emission.Emitter Em *emission.Emitter
Loader packagelib.Loader
} }
func New() Bait { func New() Bait {
@ -20,27 +19,14 @@ func New() Bait {
emitter.Off(hookname, hookfunc) emitter.Off(hookname, hookfunc)
fmt.Println(err) fmt.Println(err)
}) })
b := Bait{ return Bait{
Em: emitter, Em: emitter,
} }
b.Loader = packagelib.Loader{
Load: b.LoaderFunc,
Name: "bait",
}
return b
} }
func (b *Bait) LoaderFunc(rtm *rt.Runtime) (rt.Value, func()) { func (b *Bait) Loader(L *lua.LState) int {
exports := map[string]util.LuaExport{ mod := L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{})
"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, util.Document(L, mod,
`Bait is the event emitter for Hilbish. Why name it bait? `Bait is the event emitter for Hilbish. Why name it bait?
Because it throws hooks that you can catch (emits events 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, in on hooks to know when certain things have happened,
like when you've changed directory, a command has like when you've changed directory, a command has
failed, etc. To find all available hooks, see doc hooks.`) 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) { L.Push(mod)
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
}
return name, catcher, err return 1
}
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)
}
} }
// throw(name, ...args) // throw(name, ...args)
// Throws a hook with `name` with the provided `args` // Throws a hook with `name` with the provided `args`
// --- @param name string // --- @param name string
// --- @vararg any // --- @vararg any
func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (b *Bait) bthrow(name string, args ...interface{}) {
if err := c.Check1Arg(); err != nil { b.Em.Emit(name, args...)
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
} }
// catch(name, cb) // catch(name, cb)
// Catches a hook with `name`. Runs the `cb` when it is thrown // Catches a hook with `name`. Runs the `cb` when it is thrown
// --- @param name string // --- @param name string
// --- @param cb function // --- @param cb function
func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (b *Bait) bcatch(name string, catcher func(...interface{})) {
name, catcher, err := handleArgs(t, c) b.Em.On(name, catcher)
if err != nil {
return nil, err
}
b.Em.On(name, func(args ...interface{}) {
handleHook(t, c, name, catcher, args...)
})
return c.Next(), nil
} }
// catchOnce(name, cb) // catchOnce(name, cb)
// Same as catch, but only runs the `cb` once and then removes the hook // Same as catch, but only runs the `cb` once and then removes the hook
// --- @param name string // --- @param name string
// --- @param cb function // --- @param cb function
func (b *Bait) bcatchOnce(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (b *Bait) bcatchOnce(name string, catcher func(...interface{})) {
name, catcher, err := handleArgs(t, c) b.Em.Once(name, catcher)
if err != nil {
return nil, err
}
b.Em.Once(name, func(args ...interface{}) {
handleHook(t, c, name, catcher, args...)
})
return c.Next(), nil
} }

13
lua.go
View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"os" "os"
"hilbish/util"
"hilbish/golibs/bait" "hilbish/golibs/bait"
/* /*
"hilbish/golibs/commander" "hilbish/golibs/commander"
@ -43,8 +42,7 @@ func luaInit() {
*/ */
hooks = bait.New() hooks = bait.New()
lib.LoadLibs(l, hooks.Loader) // l.PreloadModule("bait", hooks.Loader)
// Add Ctrl-C handler // Add Ctrl-C handler
hooks.Em.On("signal.sigint", func() { hooks.Em.On("signal.sigint", func() {
if !interactive { if !interactive {
@ -73,9 +71,14 @@ func runConfig(confpath string) {
if !interactive { if !interactive {
return return
} }
err := util.DoFile(l, confpath) data, err := os.ReadFile(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) 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 package util
import ( import (
"os"
"github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
rt "github.com/arnodel/golua/runtime" 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) 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))
}