mirror of https://github.com/Hilbis/Hilbish
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 functionpull/207/head
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…
Reference in New Issue