mirror of
				https://github.com/sammy-ette/Hilbish
				synced 2025-08-10 02:52:03 +00:00 
			
		
		
		
	refactor: use custom event emitter (#193)
* refactor: use custom event emitter * fix: sigint hook emit on windows * fix: restore correct hilbish conf file * fix: call recoverer for go listeners * refactor(golibs/bait): use 1 map for listeners * feat: add once listeners, ability to remove listeners and remove listener on error * perf: reslice listener slice instead of trying to do ordered move with append * feat(bait): add release function to remove event listener * perf: remove listener directly from once emit instead of using off function * refactor: use bait event emitter on commander * docs(golibs/bait): add doc strings for functions * docs: set changelog * docs(golibs/bait): add docs for lua release function
This commit is contained in:
		
							parent
							
								
									6ce4fb3973
								
							
						
					
					
						commit
						2337f9ab60
					
				@ -70,6 +70,11 @@ set `hilbish.opts.motd` to false.
 | 
				
			|||||||
disables commands being added to history.
 | 
					disables commands being added to history.
 | 
				
			||||||
- `hilbish.rawInput` hook for input from the readline library
 | 
					- `hilbish.rawInput` hook for input from the readline library
 | 
				
			||||||
- Completion of files in quotes
 | 
					- Completion of files in quotes
 | 
				
			||||||
 | 
					- A new and "safer" event emitter has been added. This causes a performance deficit, but avoids a lot of
 | 
				
			||||||
 | 
					random errors introduced with the new Lua runtime (see [#197])
 | 
				
			||||||
 | 
					- `bait.release(name, catcher)` removes `handler` for the named `event`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[#197]: https://github.com/Rosettea/Hilbish/issues/197
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Changed
 | 
					### Changed
 | 
				
			||||||
- **Breaking Change:** Upgraded to Lua 5.4.
 | 
					- **Breaking Change:** Upgraded to Lua 5.4.
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								api.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								api.go
									
									
									
									
									
								
							@ -189,7 +189,7 @@ func getenv(key, fallback string) string {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func setVimMode(mode string) {
 | 
					func setVimMode(mode string) {
 | 
				
			||||||
	util.SetField(l, hshMod, "vimMode", rt.StringValue(mode), "Current Vim mode of Hilbish (nil if not in Vim mode)")
 | 
						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() {
 | 
					func unsetVimMode() {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								exec.go
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								exec.go
									
									
									
									
									
								
							@ -85,7 +85,7 @@ func isExecError(err error) (execError, bool) {
 | 
				
			|||||||
func runInput(input string, priv bool) {
 | 
					func runInput(input string, priv bool) {
 | 
				
			||||||
	running = true
 | 
						running = true
 | 
				
			||||||
	cmdString := aliases.Resolve(input)
 | 
						cmdString := aliases.Resolve(input)
 | 
				
			||||||
	hooks.Em.Emit("command.preexec", input, cmdString)
 | 
						hooks.Emit("command.preexec", input, cmdString)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rerun:
 | 
						rerun:
 | 
				
			||||||
	var exitCode uint8
 | 
						var exitCode uint8
 | 
				
			||||||
@ -140,7 +140,7 @@ func runInput(input string, priv bool) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if exErr, ok := isExecError(err); ok {
 | 
							if exErr, ok := isExecError(err); ok {
 | 
				
			||||||
			hooks.Em.Emit("command." + exErr.typ, exErr.cmd)
 | 
								hooks.Emit("command." + exErr.typ, exErr.cmd)
 | 
				
			||||||
			err = exErr.sprint()
 | 
								err = exErr.sprint()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fmt.Fprintln(os.Stderr, err)
 | 
							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
 | 
						// 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.Em.Emit("command.exit", rt.IntValue(int64(code)), cmdstr, private)
 | 
						hooks.Emit("command.exit", rt.IntValue(int64(code)), cmdstr, private)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,27 +1,41 @@
 | 
				
			|||||||
package bait
 | 
					package bait
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"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/packagelib"
 | 
				
			||||||
	"github.com/chuckpreslar/emission"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Bait struct{
 | 
					type listenerType int
 | 
				
			||||||
	Em *emission.Emitter
 | 
					const (
 | 
				
			||||||
	Loader packagelib.Loader
 | 
						goListener listenerType = iota
 | 
				
			||||||
 | 
						luaListener
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Recoverer is a function which is called when a panic occurs in an event.
 | 
				
			||||||
 | 
					type Recoverer func(event string, handler *Listener, err interface{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Listener is a struct that holds the handler for an event.
 | 
				
			||||||
 | 
					type Listener struct{
 | 
				
			||||||
 | 
						typ listenerType
 | 
				
			||||||
 | 
						once bool
 | 
				
			||||||
 | 
						caller func(...interface{})
 | 
				
			||||||
 | 
						luaCaller *rt.Closure
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func New() Bait {
 | 
					type Bait struct{
 | 
				
			||||||
	emitter := emission.NewEmitter()
 | 
						Loader packagelib.Loader
 | 
				
			||||||
	emitter.RecoverWith(func(hookname, hookfunc interface{}, err error) {
 | 
						recoverer Recoverer
 | 
				
			||||||
		emitter.Off(hookname, hookfunc)
 | 
						handlers map[string][]*Listener
 | 
				
			||||||
		fmt.Println(err)
 | 
						rtm *rt.Runtime
 | 
				
			||||||
	})
 | 
					}
 | 
				
			||||||
	b := Bait{
 | 
					
 | 
				
			||||||
		Em: emitter,
 | 
					// New creates a new Bait instance.
 | 
				
			||||||
 | 
					func New(rtm *rt.Runtime) *Bait {
 | 
				
			||||||
 | 
						b := &Bait{
 | 
				
			||||||
 | 
							handlers: make(map[string][]*Listener),
 | 
				
			||||||
 | 
							rtm: rtm,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	b.Loader = packagelib.Loader{
 | 
						b.Loader = packagelib.Loader{
 | 
				
			||||||
		Load: b.loaderFunc,
 | 
							Load: b.loaderFunc,
 | 
				
			||||||
@ -31,11 +45,148 @@ func New() Bait {
 | 
				
			|||||||
	return b
 | 
						return b
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Emit throws an event.
 | 
				
			||||||
 | 
					func (b *Bait) Emit(event string, args ...interface{}) {
 | 
				
			||||||
 | 
						handles := b.handlers[event]
 | 
				
			||||||
 | 
						if handles == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for idx, handle := range handles {
 | 
				
			||||||
 | 
							defer func() {
 | 
				
			||||||
 | 
								if err := recover(); err != nil {
 | 
				
			||||||
 | 
									b.callRecoverer(event, handle, err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if handle.typ == luaListener {
 | 
				
			||||||
 | 
								funcVal := rt.FunctionValue(handle.luaCaller)
 | 
				
			||||||
 | 
								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. reference the recoverer function in lua.go
 | 
				
			||||||
 | 
									panic(err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								handle.caller(args...)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if handle.once {
 | 
				
			||||||
 | 
								b.removeListener(event, idx)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// On adds a Go function handler for an event.
 | 
				
			||||||
 | 
					func (b *Bait) On(event string, handler func(...interface{})) *Listener {
 | 
				
			||||||
 | 
						listener := &Listener{
 | 
				
			||||||
 | 
							typ: goListener,
 | 
				
			||||||
 | 
							caller: handler,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b.addListener(event, listener)
 | 
				
			||||||
 | 
						return listener
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OnLua adds a Lua function handler for an event.
 | 
				
			||||||
 | 
					func (b *Bait) OnLua(event string, handler *rt.Closure) *Listener {
 | 
				
			||||||
 | 
						listener :=&Listener{
 | 
				
			||||||
 | 
							typ: luaListener,
 | 
				
			||||||
 | 
							luaCaller: handler,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						b.addListener(event, listener)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return listener
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Off removes a Go function handler for an event.
 | 
				
			||||||
 | 
					func (b *Bait) Off(event string, listener *Listener) {
 | 
				
			||||||
 | 
						handles := b.handlers[event]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, handle := range handles {
 | 
				
			||||||
 | 
							if handle == listener {
 | 
				
			||||||
 | 
								b.removeListener(event, i)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OffLua removes a Lua function handler for an event.
 | 
				
			||||||
 | 
					func (b *Bait) OffLua(event string, handler *rt.Closure) {
 | 
				
			||||||
 | 
						handles := b.handlers[event]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, handle := range handles {
 | 
				
			||||||
 | 
							if handle.luaCaller == handler {
 | 
				
			||||||
 | 
								b.removeListener(event, i)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Once adds a Go function listener for an event that only runs once.
 | 
				
			||||||
 | 
					func (b *Bait) Once(event string, handler func(...interface{})) *Listener {
 | 
				
			||||||
 | 
						listener := &Listener{
 | 
				
			||||||
 | 
							typ: goListener,
 | 
				
			||||||
 | 
							once: true,
 | 
				
			||||||
 | 
							caller: handler,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						b.addListener(event, listener)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return listener
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// OnceLua adds a Lua function listener for an event that only runs once.
 | 
				
			||||||
 | 
					func (b *Bait) OnceLua(event string, handler *rt.Closure) *Listener {
 | 
				
			||||||
 | 
						listener := &Listener{
 | 
				
			||||||
 | 
							typ: luaListener,
 | 
				
			||||||
 | 
							once: true,
 | 
				
			||||||
 | 
							luaCaller: handler,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						b.addListener(event, listener)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return listener
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetRecoverer sets the function to be executed when a panic occurs in an event.
 | 
				
			||||||
 | 
					func (b *Bait) SetRecoverer(recoverer Recoverer) {
 | 
				
			||||||
 | 
						b.recoverer = recoverer
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b *Bait) addListener(event string, listener *Listener) {
 | 
				
			||||||
 | 
						if b.handlers[event] == nil {
 | 
				
			||||||
 | 
							b.handlers[event] = []*Listener{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b.handlers[event] = append(b.handlers[event], listener)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b *Bait) removeListener(event string, idx int) {
 | 
				
			||||||
 | 
						b.handlers[event][idx] = b.handlers[event][len(b.handlers[event]) - 1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b.handlers[event] = b.handlers[event][:len(b.handlers[event]) - 1]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b *Bait) callRecoverer(event string, handler *Listener, err interface{}) {
 | 
				
			||||||
 | 
						if b.recoverer == nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						b.recoverer(event, handler, err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (b *Bait) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
 | 
					func (b *Bait) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
 | 
				
			||||||
	exports := map[string]util.LuaExport{
 | 
						exports := map[string]util.LuaExport{
 | 
				
			||||||
		"catch": util.LuaExport{b.bcatch, 2, false},
 | 
							"catch": util.LuaExport{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},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mod := rt.NewTable()
 | 
						mod := rt.NewTable()
 | 
				
			||||||
	util.SetExports(rtm, mod, exports)
 | 
						util.SetExports(rtm, mod, exports)
 | 
				
			||||||
@ -89,7 +240,7 @@ func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
 | 
				
			|||||||
	for i, v := range c.Etc() {
 | 
						for i, v := range c.Etc() {
 | 
				
			||||||
		ifaceSlice[i] = v
 | 
							ifaceSlice[i] = v
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	b.Em.Emit(name, ifaceSlice...)
 | 
						b.Emit(name, ifaceSlice...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return c.Next(), nil
 | 
						return c.Next(), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -104,9 +255,7 @@ func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b.Em.On(name, func(args ...interface{}) {
 | 
						b.OnLua(name, catcher)
 | 
				
			||||||
		handleHook(t, c, name, catcher, args...)
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return c.Next(), nil
 | 
						return c.Next(), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -121,9 +270,22 @@ func (b *Bait) bcatchOnce(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b.Em.Once(name, func(args ...interface{}) {
 | 
						b.OnceLua(name, catcher)
 | 
				
			||||||
		handleHook(t, c, name, catcher, args...)
 | 
					
 | 
				
			||||||
	})
 | 
						return c.Next(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// release(name, catcher)
 | 
				
			||||||
 | 
					// Removes the `catcher` for the event with `name`
 | 
				
			||||||
 | 
					// For this to work, `catcher` has to be the same function used to catch
 | 
				
			||||||
 | 
					// an event, like one saved to a variable.
 | 
				
			||||||
 | 
					func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
 | 
				
			||||||
 | 
						name, catcher, err := util.HandleStrCallback(t, c)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b.OffLua(name, catcher)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return c.Next(), nil
 | 
						return c.Next(), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,20 +2,20 @@ package commander
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"hilbish/util"
 | 
						"hilbish/util"
 | 
				
			||||||
 | 
						"hilbish/golibs/bait"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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/chuckpreslar/emission"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Commander struct{
 | 
					type Commander struct{
 | 
				
			||||||
	Events *emission.Emitter
 | 
						Events *bait.Bait
 | 
				
			||||||
	Loader packagelib.Loader
 | 
						Loader packagelib.Loader
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func New() Commander {
 | 
					func New(rtm *rt.Runtime) Commander {
 | 
				
			||||||
	c := Commander{
 | 
						c := Commander{
 | 
				
			||||||
		Events: emission.NewEmitter(),
 | 
							Events: bait.New(rtm),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	c.Loader = packagelib.Loader{
 | 
						c.Loader = packagelib.Loader{
 | 
				
			||||||
		Load: c.loaderFunc,
 | 
							Load: c.loaderFunc,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								job.go
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								job.go
									
									
									
									
									
								
							@ -67,7 +67,7 @@ func (j *job) start() error {
 | 
				
			|||||||
	j.pid = proc.Pid
 | 
						j.pid = proc.Pid
 | 
				
			||||||
	j.running = true
 | 
						j.running = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hooks.Em.Emit("job.start", rt.UserDataValue(j.ud))
 | 
						hooks.Emit("job.start", rt.UserDataValue(j.ud))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -82,7 +82,7 @@ func (j *job) stop() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (j *job) finish() {
 | 
					func (j *job) finish() {
 | 
				
			||||||
	j.running = false
 | 
						j.running = false
 | 
				
			||||||
	hooks.Em.Emit("job.done", rt.UserDataValue(j.ud))
 | 
						hooks.Emit("job.done", rt.UserDataValue(j.ud))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (j *job) wait() {
 | 
					func (j *job) wait() {
 | 
				
			||||||
@ -236,7 +236,7 @@ func (j *jobHandler) add(cmd string, args []string, path string) *job {
 | 
				
			|||||||
	jb.ud = jobUserData(jb)
 | 
						jb.ud = jobUserData(jb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	j.jobs[j.latestID] = 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
 | 
						return jb
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										22
									
								
								lua.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								lua.go
									
									
									
									
									
								
							@ -32,28 +32,38 @@ func luaInit() {
 | 
				
			|||||||
	lib.LoadLibs(l, fs.Loader)
 | 
						lib.LoadLibs(l, fs.Loader)
 | 
				
			||||||
	lib.LoadLibs(l, terminal.Loader)
 | 
						lib.LoadLibs(l, terminal.Loader)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmds := commander.New()
 | 
						cmds := commander.New(l)
 | 
				
			||||||
	// When a command from Lua is added, register it for use
 | 
						// When a command from Lua is added, register it for use
 | 
				
			||||||
	cmds.Events.On("commandRegister", func(cmdName string, cmd *rt.Closure) {
 | 
						cmds.Events.On("commandRegister", func(args ...interface{}) {
 | 
				
			||||||
 | 
							cmdName := args[0].(string)
 | 
				
			||||||
 | 
							cmd := args[1].(*rt.Closure)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		commands[cmdName] = cmd
 | 
							commands[cmdName] = cmd
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	cmds.Events.On("commandDeregister", func(cmdName string) {
 | 
						cmds.Events.On("commandDeregister", func(args ...interface{}) {
 | 
				
			||||||
 | 
							cmdName := args[0].(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		delete(commands, cmdName)
 | 
							delete(commands, cmdName)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	lib.LoadLibs(l, cmds.Loader)
 | 
						lib.LoadLibs(l, cmds.Loader)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hooks = bait.New()
 | 
						hooks = bait.New(l)
 | 
				
			||||||
 | 
						hooks.SetRecoverer(func(event string, handler *bait.Listener, err interface{}) {
 | 
				
			||||||
 | 
							fmt.Println("Error in", event, "event:", err)
 | 
				
			||||||
 | 
							hooks.Off(event, handler)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lib.LoadLibs(l, hooks.Loader)
 | 
						lib.LoadLibs(l, hooks.Loader)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add Ctrl-C handler
 | 
						// Add Ctrl-C handler
 | 
				
			||||||
	hooks.Em.On("signal.sigint", func() {
 | 
						hooks.On("signal.sigint", func(...interface{}) {
 | 
				
			||||||
		if !interactive {
 | 
							if !interactive {
 | 
				
			||||||
			os.Exit(0)
 | 
								os.Exit(0)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lr.rl.RawInputCallback = func(r []rune) {
 | 
						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
 | 
						// Add more paths that Lua can require from
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								main.go
									
									
									
									
									
								
							@ -30,7 +30,7 @@ var (
 | 
				
			|||||||
	userDataDir string
 | 
						userDataDir string
 | 
				
			||||||
	curuser *user.User
 | 
						curuser *user.User
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	hooks bait.Bait
 | 
						hooks *bait.Bait
 | 
				
			||||||
	defaultConfPath string
 | 
						defaultConfPath string
 | 
				
			||||||
	defaultHistPath string
 | 
						defaultHistPath string
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -138,7 +138,7 @@ func main() {
 | 
				
			|||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		runConfig(*configflag)
 | 
							runConfig(*configflag)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	hooks.Em.Emit("hilbish.init")
 | 
						hooks.Emit("hilbish.init")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if fileInfo, _ := os.Stdin.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 {
 | 
						if fileInfo, _ := os.Stdin.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 {
 | 
				
			||||||
		scanner := bufio.NewScanner(bufio.NewReader(os.Stdin))
 | 
							scanner := bufio.NewScanner(bufio.NewReader(os.Stdin))
 | 
				
			||||||
@ -177,7 +177,7 @@ input:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if err == io.EOF {
 | 
							if err == io.EOF {
 | 
				
			||||||
			// Exit if user presses ^D (ctrl + d)
 | 
								// Exit if user presses ^D (ctrl + d)
 | 
				
			||||||
			hooks.Em.Emit("hilbish.exit")
 | 
								hooks.Emit("hilbish.exit")
 | 
				
			||||||
			break
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@ -196,7 +196,7 @@ input:
 | 
				
			|||||||
		input = strings.TrimSpace(input)
 | 
							input = strings.TrimSpace(input)
 | 
				
			||||||
		if len(input) == 0 {
 | 
							if len(input) == 0 {
 | 
				
			||||||
			running = true
 | 
								running = true
 | 
				
			||||||
			hooks.Em.Emit("command.exit", 0)
 | 
								hooks.Emit("command.exit", 0)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -227,7 +227,7 @@ input:
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func continuePrompt(prev string) (string, error) {
 | 
					func continuePrompt(prev string) (string, error) {
 | 
				
			||||||
	hooks.Em.Emit("multiline", nil)
 | 
						hooks.Emit("multiline", nil)
 | 
				
			||||||
	lr.SetPrompt(multilinePrompt)
 | 
						lr.SetPrompt(multilinePrompt)
 | 
				
			||||||
	cont, err := lr.Read()
 | 
						cont, err := lr.Read()
 | 
				
			||||||
	if err != nil {
 | 
						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.VimActionPaste: actionStr = "paste"
 | 
				
			||||||
			case readline.VimActionYank: actionStr = "yank"
 | 
								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 {
 | 
						rl.HintText = func(line []rune, pos int) []rune {
 | 
				
			||||||
		if hinter == nil {
 | 
							if hinter == nil {
 | 
				
			||||||
@ -179,7 +179,7 @@ func newLineReader(prompt string, noHist bool) *lineReader {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (lr *lineReader) Read() (string, error) {
 | 
					func (lr *lineReader) Read() (string, error) {
 | 
				
			||||||
	hooks.Em.Emit("command.precmd", nil)
 | 
						hooks.Emit("command.precmd", nil)
 | 
				
			||||||
	s, err := lr.rl.Readline()
 | 
						s, err := lr.rl.Readline()
 | 
				
			||||||
	// this is so dumb
 | 
						// this is so dumb
 | 
				
			||||||
	if err == readline.EOF {
 | 
						if err == readline.EOF {
 | 
				
			||||||
 | 
				
			|||||||
@ -15,11 +15,11 @@ func handleSignals() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	for s := range c {
 | 
						for s := range c {
 | 
				
			||||||
		switch s {
 | 
							switch s {
 | 
				
			||||||
		case os.Interrupt: hooks.Em.Emit("signal.sigint")
 | 
							case os.Interrupt: hooks.Emit("signal.sigint")
 | 
				
			||||||
		case syscall.SIGTERM: exit(0)
 | 
							case syscall.SIGTERM: exit(0)
 | 
				
			||||||
		case syscall.SIGWINCH: hooks.Em.Emit("signal.resize")
 | 
							case syscall.SIGWINCH: hooks.Emit("signal.resize")
 | 
				
			||||||
		case syscall.SIGUSR1: hooks.Em.Emit("signal.sigusr1")
 | 
							case syscall.SIGUSR1: hooks.Emit("signal.sigusr1")
 | 
				
			||||||
		case syscall.SIGUSR2: hooks.Em.Emit("signal.sigusr2")
 | 
							case syscall.SIGUSR2: hooks.Emit("signal.sigusr2")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,7 @@ func handleSignals() {
 | 
				
			|||||||
	for s := range c {
 | 
						for s := range c {
 | 
				
			||||||
		switch s {
 | 
							switch s {
 | 
				
			||||||
		case os.Interrupt:
 | 
							case os.Interrupt:
 | 
				
			||||||
			hooks.Em.Emit("signal.sigint")
 | 
								hooks.Emit("signal.sigint")
 | 
				
			||||||
			if !running && interactive {
 | 
								if !running && interactive {
 | 
				
			||||||
				lr.ClearInput()
 | 
									lr.ClearInput()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user