Add ability to bind lua functions defined in plugins

This commit is contained in:
Zachary Yedidia
2016-05-30 09:12:04 -04:00
parent e3e50dd6f6
commit 68189fd406
4 changed files with 47 additions and 24 deletions

View File

@@ -247,36 +247,32 @@ func InitBindings() {
}
}
for k, v := range defaults {
parse(defaults, actions, keys)
parse(parsed, actions, keys)
}
func parse(userBindings map[string]string, actions map[string]func(*View) bool, keys map[string]Key) {
for k, v := range userBindings {
var key Key
if strings.Contains(k, "Alt-") {
split := strings.Split(k, "-")
var key Key
if len(split[1]) > 1 {
key = Key{keys[split[1]].keyCode, keys[k].modifiers | tcell.ModAlt, 0}
} else {
key = Key{tcell.KeyRune, tcell.ModAlt, rune(k[len(k)-1])}
}
bindings[key] = actions[v]
} else {
bindings[keys[k]] = actions[v]
key = keys[k]
}
if v == "ToggleHelp" {
helpBinding = k
}
}
for k, v := range parsed {
if strings.Contains(k, "Alt-") {
split := strings.Split(k, "-")
var key Key
if len(split[1]) > 1 {
key = Key{keys[split[1]].keyCode, keys[k].modifiers | tcell.ModAlt, 0}
} else {
key = Key{tcell.KeyRune, tcell.ModAlt, rune(k[len(k)-1])}
}
bindings[key] = actions[v]
} else {
bindings[keys[k]] = actions[v]
action := actions[v]
if _, ok := actions[v]; !ok {
// If the user seems to be binding a function that doesn't exist
// We hope that it's a lua function that exists and bind it to that
action = LuaFunctionBinding(v)
}
bindings[key] = action
if v == "ToggleHelp" {
helpBinding = k
}

View File

@@ -1,8 +1,10 @@
package main
import (
"github.com/yuin/gopher-lua"
"errors"
"io/ioutil"
"github.com/yuin/gopher-lua"
)
var loadedPlugins []string
@@ -18,7 +20,7 @@ var preInstalledPlugins = []string{
func Call(function string) error {
luaFunc := L.GetGlobal(function)
if luaFunc.String() == "nil" {
return nil
return errors.New("function does not exist: " + function)
}
err := L.CallByParam(lua.P{
Fn: luaFunc,
@@ -28,6 +30,31 @@ func Call(function string) error {
return err
}
// LuaFunctionBinding is a function generator which takes the name of a lua function
// and creates a function that will call that lua function
// Specifically it creates a function that can be called as a binding because this is used
// to bind keys to lua functions
func LuaFunctionBinding(function string) func(*View) bool {
return func(v *View) bool {
err := Call(function)
if err != nil {
TermMessage(err)
}
return false
}
}
// LuaFunctionCommand is the same as LuaFunctionBinding except it returns a normal function
// so that a command can be bound to a lua function
func LuaFunctionCommand(function string) func() {
return func() {
err := Call(function)
if err != nil {
TermMessage(err)
}
}
}
// LoadPlugins loads the pre-installed plugins and the plugins located in ~/.config/micro/plugins
func LoadPlugins() {
files, _ := ioutil.ReadDir(configDir + "/plugins")

View File

@@ -275,7 +275,7 @@ func runtimePluginsGoGoLua() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "runtime/plugins/go/go.lua", size: 927, mode: os.FileMode(420), modTime: time.Unix(1464457319, 0)}
info := bindataFileInfo{name: "runtime/plugins/go/go.lua", size: 927, mode: os.FileMode(420), modTime: time.Unix(1464613212, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}

View File

@@ -302,7 +302,7 @@ func (v *View) HandleEvent(event tcell.Event) {
for _, pl := range loadedPlugins {
funcName := strings.Split(runtime.FuncForPC(reflect.ValueOf(action).Pointer()).Name(), ".")
err := Call(pl + "_on" + funcName[len(funcName)-1])
if err != nil {
if err != nil && !strings.HasPrefix(err.Error(), "function does not exist") {
TermMessage(err)
}
}