mirror of https://github.com/Hilbis/Hilbish
refactor: use custom event emitter
parent
387d7d2243
commit
307589df9e
|
@ -13,6 +13,7 @@ doPrompt()
|
|||
|
||||
bait.catch('command.exit', function(code)
|
||||
doPrompt(code ~= 0)
|
||||
print(code:lol())
|
||||
end)
|
||||
|
||||
bait.catch('hilbish.vimMode', function(mode)
|
||||
|
|
2
api.go
2
api.go
|
@ -189,7 +189,7 @@ func getenv(key, fallback string) string {
|
|||
|
||||
func setVimMode(mode string) {
|
||||
util.SetField(l, hshMod, "vimMode", rt.StringValue(mode), "Current Vim mode of Hilbish (nil if not in Vim mode)")
|
||||
hooks.Em.Emit("hilbish.vimMode", mode)
|
||||
hooks.Emit("hilbish.vimMode", mode)
|
||||
}
|
||||
|
||||
func unsetVimMode() {
|
||||
|
|
6
exec.go
6
exec.go
|
@ -85,7 +85,7 @@ func isExecError(err error) (execError, bool) {
|
|||
func runInput(input string, priv bool) {
|
||||
running = true
|
||||
cmdString := aliases.Resolve(input)
|
||||
hooks.Em.Emit("command.preexec", input, cmdString)
|
||||
hooks.Emit("command.preexec", input, cmdString)
|
||||
|
||||
rerun:
|
||||
var exitCode uint8
|
||||
|
@ -140,7 +140,7 @@ func runInput(input string, priv bool) {
|
|||
|
||||
if err != nil {
|
||||
if exErr, ok := isExecError(err); ok {
|
||||
hooks.Em.Emit("command." + exErr.typ, exErr.cmd)
|
||||
hooks.Emit("command." + exErr.typ, exErr.cmd)
|
||||
err = exErr.sprint()
|
||||
}
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
|
@ -544,5 +544,5 @@ func cmdFinish(code uint8, cmdstr string, private bool) {
|
|||
// using AsValue (to convert to lua type) on an interface which is an int
|
||||
// results in it being unknown in lua .... ????
|
||||
// so we allow the hook handler to take lua runtime Values
|
||||
hooks.Em.Emit("command.exit", rt.IntValue(int64(code)), cmdstr, private)
|
||||
hooks.Emit("command.exit", rt.IntValue(int64(code)), cmdstr, private)
|
||||
}
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
package bait
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hilbish/util"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
"github.com/arnodel/golua/lib/packagelib"
|
||||
"github.com/chuckpreslar/emission"
|
||||
)
|
||||
|
||||
type Recoverer func(event string, handler, err interface{})
|
||||
|
||||
type Bait struct{
|
||||
Em *emission.Emitter
|
||||
Loader packagelib.Loader
|
||||
recoverer Recoverer
|
||||
luaHandlers map[string][]*rt.Closure
|
||||
handlers map[string][]func(...interface{})
|
||||
rtm *rt.Runtime
|
||||
}
|
||||
|
||||
func New() Bait {
|
||||
emitter := emission.NewEmitter()
|
||||
emitter.RecoverWith(func(hookname, hookfunc interface{}, err error) {
|
||||
emitter.Off(hookname, hookfunc)
|
||||
fmt.Println(err)
|
||||
})
|
||||
func New(rtm *rt.Runtime) Bait {
|
||||
b := Bait{
|
||||
Em: emitter,
|
||||
luaHandlers: make(map[string][]*rt.Closure),
|
||||
handlers: make(map[string][]func(...interface{})),
|
||||
rtm: rtm,
|
||||
}
|
||||
b.Loader = packagelib.Loader{
|
||||
Load: b.loaderFunc,
|
||||
|
@ -31,6 +31,73 @@ func New() Bait {
|
|||
return b
|
||||
}
|
||||
|
||||
func (b *Bait) Emit(event string, args ...interface{}) {
|
||||
handles := b.handlers[event]
|
||||
luaHandles := b.luaHandlers[event]
|
||||
|
||||
if handles == nil && luaHandles == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if handles != nil {
|
||||
for _, handle := range handles {
|
||||
handle(args...)
|
||||
}
|
||||
}
|
||||
|
||||
if luaHandles != nil {
|
||||
for _, handle := range luaHandles {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
b.callRecoverer(event, handle, err)
|
||||
}
|
||||
}()
|
||||
|
||||
funcVal := rt.FunctionValue(handle)
|
||||
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(b.rtm.MainThread(), funcVal, luaArgs...)
|
||||
if err != nil {
|
||||
// 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(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bait) On(event string, handler func(...interface{})) {
|
||||
if b.handlers[event] == nil {
|
||||
b.handlers[event] = []func(...interface{}){}
|
||||
}
|
||||
b.handlers[event] = append(b.handlers[event], handler)
|
||||
}
|
||||
|
||||
func (b *Bait) OnLua(event string, handler *rt.Closure) {
|
||||
if b.luaHandlers[event] == nil {
|
||||
b.luaHandlers[event] = []*rt.Closure{}
|
||||
}
|
||||
b.luaHandlers[event] = append(b.luaHandlers[event], handler)
|
||||
}
|
||||
|
||||
func (b *Bait) SetRecoverer(recoverer Recoverer) {
|
||||
b.recoverer = recoverer
|
||||
}
|
||||
|
||||
func (b *Bait) callRecoverer(event string, handler, err interface{}) {
|
||||
if b.recoverer == nil {
|
||||
panic(err)
|
||||
}
|
||||
b.recoverer(event, handler, err)
|
||||
}
|
||||
|
||||
func (b *Bait) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
||||
exports := map[string]util.LuaExport{
|
||||
"catch": util.LuaExport{b.bcatch, 2, false},
|
||||
|
@ -89,7 +156,7 @@ func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
for i, v := range c.Etc() {
|
||||
ifaceSlice[i] = v
|
||||
}
|
||||
b.Em.Emit(name, ifaceSlice...)
|
||||
b.Emit(name, ifaceSlice...)
|
||||
|
||||
return c.Next(), nil
|
||||
}
|
||||
|
@ -104,9 +171,7 @@ func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
b.Em.On(name, func(args ...interface{}) {
|
||||
handleHook(t, c, name, catcher, args...)
|
||||
})
|
||||
b.OnLua(name, catcher)
|
||||
|
||||
return c.Next(), nil
|
||||
}
|
||||
|
@ -121,7 +186,8 @@ func (b *Bait) bcatchOnce(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
b.Em.Once(name, func(args ...interface{}) {
|
||||
// todo: add once
|
||||
b.On(name, func(args ...interface{}) {
|
||||
handleHook(t, c, name, catcher, args...)
|
||||
})
|
||||
|
||||
|
|
6
job.go
6
job.go
|
@ -67,7 +67,7 @@ func (j *job) start() error {
|
|||
j.pid = proc.Pid
|
||||
j.running = true
|
||||
|
||||
hooks.Em.Emit("job.start", rt.UserDataValue(j.ud))
|
||||
hooks.Emit("job.start", rt.UserDataValue(j.ud))
|
||||
|
||||
return err
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ func (j *job) stop() {
|
|||
|
||||
func (j *job) finish() {
|
||||
j.running = false
|
||||
hooks.Em.Emit("job.done", rt.UserDataValue(j.ud))
|
||||
hooks.Emit("job.done", rt.UserDataValue(j.ud))
|
||||
}
|
||||
|
||||
func (j *job) wait() {
|
||||
|
@ -236,7 +236,7 @@ func (j *jobHandler) add(cmd string, args []string, path string) *job {
|
|||
jb.ud = jobUserData(jb)
|
||||
|
||||
j.jobs[j.latestID] = jb
|
||||
hooks.Em.Emit("job.add", rt.UserDataValue(jb.ud))
|
||||
hooks.Emit("job.add", rt.UserDataValue(jb.ud))
|
||||
|
||||
return jb
|
||||
}
|
||||
|
|
10
lua.go
10
lua.go
|
@ -42,18 +42,22 @@ func luaInit() {
|
|||
})
|
||||
lib.LoadLibs(l, cmds.Loader)
|
||||
|
||||
hooks = bait.New()
|
||||
hooks = bait.New(l)
|
||||
hooks.SetRecoverer(func(event string, handler, err interface{}) {
|
||||
fmt.Println("Error in", event, "event:", err)
|
||||
})
|
||||
|
||||
lib.LoadLibs(l, hooks.Loader)
|
||||
|
||||
// Add Ctrl-C handler
|
||||
hooks.Em.On("signal.sigint", func() {
|
||||
hooks.On("signal.sigint", func(...interface{}) {
|
||||
if !interactive {
|
||||
os.Exit(0)
|
||||
}
|
||||
})
|
||||
|
||||
lr.rl.RawInputCallback = func(r []rune) {
|
||||
hooks.Em.Emit("hilbish.rawInput", string(r))
|
||||
hooks.Emit("hilbish.rawInput", string(r))
|
||||
}
|
||||
|
||||
// Add more paths that Lua can require from
|
||||
|
|
8
main.go
8
main.go
|
@ -138,7 +138,7 @@ func main() {
|
|||
} else {
|
||||
runConfig(*configflag)
|
||||
}
|
||||
hooks.Em.Emit("hilbish.init")
|
||||
hooks.Emit("hilbish.init")
|
||||
|
||||
if fileInfo, _ := os.Stdin.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 {
|
||||
scanner := bufio.NewScanner(bufio.NewReader(os.Stdin))
|
||||
|
@ -177,7 +177,7 @@ input:
|
|||
|
||||
if err == io.EOF {
|
||||
// Exit if user presses ^D (ctrl + d)
|
||||
hooks.Em.Emit("hilbish.exit")
|
||||
hooks.Emit("hilbish.exit")
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -196,7 +196,7 @@ input:
|
|||
input = strings.TrimSpace(input)
|
||||
if len(input) == 0 {
|
||||
running = true
|
||||
hooks.Em.Emit("command.exit", 0)
|
||||
hooks.Emit("command.exit", 0)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ input:
|
|||
}
|
||||
|
||||
func continuePrompt(prev string) (string, error) {
|
||||
hooks.Em.Emit("multiline", nil)
|
||||
hooks.Emit("multiline", nil)
|
||||
lr.SetPrompt(multilinePrompt)
|
||||
cont, err := lr.Read()
|
||||
if err != nil {
|
||||
|
|
4
rl.go
4
rl.go
|
@ -48,7 +48,7 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
|||
case readline.VimActionPaste: actionStr = "paste"
|
||||
case readline.VimActionYank: actionStr = "yank"
|
||||
}
|
||||
hooks.Em.Emit("hilbish.vimAction", actionStr, args)
|
||||
hooks.Emit("hilbish.vimAction", actionStr, args)
|
||||
}
|
||||
rl.HintText = func(line []rune, pos int) []rune {
|
||||
if hinter == nil {
|
||||
|
@ -179,7 +179,7 @@ func newLineReader(prompt string, noHist bool) *lineReader {
|
|||
}
|
||||
|
||||
func (lr *lineReader) Read() (string, error) {
|
||||
hooks.Em.Emit("command.precmd", nil)
|
||||
hooks.Emit("command.precmd", nil)
|
||||
s, err := lr.rl.Readline()
|
||||
// this is so dumb
|
||||
if err == readline.EOF {
|
||||
|
|
|
@ -15,11 +15,11 @@ func handleSignals() {
|
|||
|
||||
for s := range c {
|
||||
switch s {
|
||||
case os.Interrupt: hooks.Em.Emit("signal.sigint")
|
||||
case os.Interrupt: hooks.Emit("signal.sigint")
|
||||
case syscall.SIGTERM: exit(0)
|
||||
case syscall.SIGWINCH: hooks.Em.Emit("signal.resize")
|
||||
case syscall.SIGUSR1: hooks.Em.Emit("signal.sigusr1")
|
||||
case syscall.SIGUSR2: hooks.Em.Emit("signal.sigusr2")
|
||||
case syscall.SIGWINCH: hooks.Emit("signal.resize")
|
||||
case syscall.SIGUSR1: hooks.Emit("signal.sigusr1")
|
||||
case syscall.SIGUSR2: hooks.Emit("signal.sigusr2")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue