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-") { if strings.Contains(k, "Alt-") {
split := strings.Split(k, "-") split := strings.Split(k, "-")
var key Key
if len(split[1]) > 1 { if len(split[1]) > 1 {
key = Key{keys[split[1]].keyCode, keys[k].modifiers | tcell.ModAlt, 0} key = Key{keys[split[1]].keyCode, keys[k].modifiers | tcell.ModAlt, 0}
} else { } else {
key = Key{tcell.KeyRune, tcell.ModAlt, rune(k[len(k)-1])} key = Key{tcell.KeyRune, tcell.ModAlt, rune(k[len(k)-1])}
} }
bindings[key] = actions[v]
} else { } else {
bindings[keys[k]] = actions[v] key = keys[k]
} }
if v == "ToggleHelp" {
helpBinding = k action := actions[v]
} if _, ok := actions[v]; !ok {
} // If the user seems to be binding a function that doesn't exist
for k, v := range parsed { // We hope that it's a lua function that exists and bind it to that
if strings.Contains(k, "Alt-") { action = LuaFunctionBinding(v)
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]
} }
bindings[key] = action
if v == "ToggleHelp" { if v == "ToggleHelp" {
helpBinding = k helpBinding = k
} }

View File

@@ -1,8 +1,10 @@
package main package main
import ( import (
"github.com/yuin/gopher-lua" "errors"
"io/ioutil" "io/ioutil"
"github.com/yuin/gopher-lua"
) )
var loadedPlugins []string var loadedPlugins []string
@@ -18,7 +20,7 @@ var preInstalledPlugins = []string{
func Call(function string) error { func Call(function string) error {
luaFunc := L.GetGlobal(function) luaFunc := L.GetGlobal(function)
if luaFunc.String() == "nil" { if luaFunc.String() == "nil" {
return nil return errors.New("function does not exist: " + function)
} }
err := L.CallByParam(lua.P{ err := L.CallByParam(lua.P{
Fn: luaFunc, Fn: luaFunc,
@@ -28,6 +30,31 @@ func Call(function string) error {
return err 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 // LoadPlugins loads the pre-installed plugins and the plugins located in ~/.config/micro/plugins
func LoadPlugins() { func LoadPlugins() {
files, _ := ioutil.ReadDir(configDir + "/plugins") files, _ := ioutil.ReadDir(configDir + "/plugins")

View File

@@ -275,7 +275,7 @@ func runtimePluginsGoGoLua() (*asset, error) {
return nil, err 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} a := &asset{bytes: bytes, info: info}
return a, nil return a, nil
} }

View File

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