diff --git a/anko/anko.go b/anko/anko.go index 4932674..e793218 100644 --- a/anko/anko.go +++ b/anko/anko.go @@ -1,12 +1,21 @@ package anko import ( + "errors" + "context" + "reflect" + "fmt" + "github.com/mattn/anko/core" "github.com/mattn/anko/env" "github.com/mattn/anko/vm" _ "github.com/mattn/anko/packages" ) +var ( + ErrNoKeybind = errors.New("no keybinding") + ErrInvalidType = errors.New("invalid type") +) type Anko struct { env *env.Env @@ -85,3 +94,48 @@ func (a *Anko) GetBool(symbol string) bool { func (a *Anko) Execute(src string) (interface{}, error) { return vm.Execute(a.env, nil, src) } + +func (a *Anko) ExecKeybind(panel string, keybind string, cb func(error)) error { + + kb, err := a.Get("keybinds") + if err != nil { + return err + } + + p, ok := kb.(map[interface{}]interface{}) + if !ok { + return fmt.Errorf("%w: require type {} got %T", ErrInvalidType, kb) + } + + k, ok := p[panel] + if !ok { + return ErrNoKeybind + } + + keybinds, ok := k.(map[interface{}]interface{}) + if !ok { + return fmt.Errorf("%w: require type {} got %T", ErrInvalidType, k) + } + + cmd, ok := keybinds[keybind] + if !ok { + return ErrNoKeybind + } + + f, ok := cmd.(func(context.Context) (reflect.Value, reflect.Value)) + if !ok { + return fmt.Errorf("%w: require type func()", ErrInvalidType) + } + + go func() { + _, execErr := f(context.Background()) + if err := execErr.Interface(); !execErr.IsNil() { + if err, ok := err.(error); ok { + cb(err) + } + } + }() + + + return nil +} diff --git a/start.go b/start.go index 9a76aaf..3dddd61 100644 --- a/start.go +++ b/start.go @@ -3,7 +3,6 @@ package main import ( - "context" "errors" "flag" "fmt" @@ -12,9 +11,9 @@ import ( "os/signal" "strings" "syscall" - "reflect" "github.com/gdamore/tcell/v2" + "github.com/issadarkthing/gomu/anko" "github.com/rivo/tview" "github.com/ztrue/tracerr" ) @@ -235,34 +234,15 @@ func start(application *tview.Application, args Args) { } // check for user defined keybindings - kb, err := gomu.anko.Get("keybinds") - if err == nil { - keybinds, ok := kb.(map[interface{}]interface{}) - if !ok { - errorPopup(errors.New("invalid type; require {}")) - return e + err := gomu.anko.ExecKeybind("global", string(e.Rune()), func (err error) { + if err != nil { + errorPopup(tracerr.Wrap(err)) } + }) - cmd, ok := keybinds[string(e.Rune())] - if ok { - - f, ok := cmd.(func(context.Context) (reflect.Value, reflect.Value)) - if !ok { - errorPopup(errors.New("invalid type; require type func()")) - return e - } - - go func() { - _, execErr := f(context.Background()) - if err := execErr.Interface(); !execErr.IsNil() { - if err, ok := err.(error); ok { - errorPopup(err) - } - } - }() - - return e - } + if err != nil && !errors.Is(err, anko.ErrNoKeybind) { + errorPopup(tracerr.Wrap(err)) + return e } cmds := map[rune]string{