From 5ab6c9795fb004fa25d6ffd5a26b6f19c17e74cf Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Mon, 18 Mar 2019 18:40:53 -0400 Subject: [PATCH] Load plugins --- Makefile | 3 ++ cmd/micro/micro.go | 2 ++ internal/config/plugin.go | 57 ++++++++++++++++++++++++++++++++ internal/config/rtfiles.go | 42 ++++++++++++++++-------- internal/lua/plugin.go | 67 -------------------------------------- 5 files changed, 91 insertions(+), 80 deletions(-) create mode 100644 internal/config/plugin.go delete mode 100644 internal/lua/plugin.go diff --git a/Makefile b/Makefile index 72547cd0..c423ac01 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,9 @@ GOVARS := -X github.com/zyedidia/micro/internal/util.Version=$(VERSION) -X githu build: go build -ldflags "-s -w $(GOVARS) $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro +build-dbg: + go build -ldflags "-s -w $(ADDITIONAL_GO_LINKER_FLAGS)" ./cmd/micro + # Builds micro after building the runtime and checking dependencies build-all: runtime build diff --git a/cmd/micro/micro.go b/cmd/micro/micro.go index e2a961f7..fc89f3bc 100644 --- a/cmd/micro/micro.go +++ b/cmd/micro/micro.go @@ -173,6 +173,8 @@ func main() { screen.TermMessage(err) } + config.LoadAllPlugins() + screen.Init() // If we have an error, we can exit cleanly and not completely diff --git a/internal/config/plugin.go b/internal/config/plugin.go new file mode 100644 index 00000000..ffb24e94 --- /dev/null +++ b/internal/config/plugin.go @@ -0,0 +1,57 @@ +package config + +import ( + "errors" + + lua "github.com/yuin/gopher-lua" + ulua "github.com/zyedidia/micro/internal/lua" +) + +var ErrNoSuchFunction = errors.New("No such function exists") + +func LoadAllPlugins() { + for _, p := range Plugins { + p.Load() + } +} + +type Plugin struct { + Name string // name of plugin + Info RuntimeFile // json file containing info + Srcs []RuntimeFile // lua files +} + +var Plugins []*Plugin + +func (p *Plugin) Load() error { + for _, f := range p.Srcs { + dat, err := f.Data() + if err != nil { + return err + } + err = ulua.LoadFile(p.Name, f.Name(), dat) + if err != nil { + return err + } + } + return nil +} + +func (p *Plugin) Call(fn string, args ...lua.LValue) (lua.LValue, error) { + plug := ulua.L.GetGlobal(p.Name) + luafn := ulua.L.GetField(plug, fn) + if luafn == lua.LNil { + return nil, ErrNoSuchFunction + } + err := ulua.L.CallByParam(lua.P{ + Fn: luafn, + NRet: 1, + Protect: true, + }, args...) + if err != nil { + return nil, err + } + ret := ulua.L.Get(-1) + ulua.L.Pop(1) + return ret, nil +} diff --git a/internal/config/rtfiles.go b/internal/config/rtfiles.go index 5db052ee..d31b4123 100644 --- a/internal/config/rtfiles.go +++ b/internal/config/rtfiles.go @@ -5,6 +5,7 @@ import ( "os" "path" "path/filepath" + "strings" ) const ( @@ -134,23 +135,38 @@ func InitRuntimeFiles() { add(RTHelp, "help", "*.md") // Search ConfigDir for plugin-scripts - files, _ := ioutil.ReadDir(filepath.Join(ConfigDir, "plugins")) - for _, f := range files { - realpath, _ := filepath.EvalSymlinks(filepath.Join(ConfigDir, "plugins", f.Name())) - realpathStat, _ := os.Stat(realpath) - if realpathStat.IsDir() { - scriptPath := filepath.Join(ConfigDir, "plugins", f.Name(), f.Name()+".lua") - if _, err := os.Stat(scriptPath); err == nil { - AddRuntimeFile(RTPlugin, realFile(scriptPath)) + plugdir := filepath.Join(ConfigDir, "plugins") + files, _ := ioutil.ReadDir(plugdir) + for _, d := range files { + if d.IsDir() { + srcs, _ := ioutil.ReadDir(filepath.Join(plugdir, d.Name())) + p := new(Plugin) + p.Name = d.Name() + for _, f := range srcs { + if strings.HasSuffix(f.Name(), ".lua") { + p.Srcs = append(p.Srcs, realFile(filepath.Join(plugdir, d.Name(), f.Name()))) + } else if f.Name() == "info.json" { + p.Info = realFile(filepath.Join(plugdir, d.Name(), "info.json")) + } } + Plugins = append(Plugins, p) } } - if files, err := AssetDir("runtime/plugins"); err == nil { - for _, f := range files { - scriptPath := path.Join("runtime/plugins", f, f+".lua") - if _, err := AssetInfo(scriptPath); err == nil { - AddRuntimeFile(RTPlugin, assetFile(scriptPath)) + plugdir = filepath.Join("runtime", "plugins") + if files, err := AssetDir(plugdir); err == nil { + for _, d := range files { + if srcs, err := AssetDir(filepath.Join(plugdir, d)); err == nil { + p := new(Plugin) + p.Name = d + for _, f := range srcs { + if strings.HasSuffix(f, ".lua") { + p.Srcs = append(p.Srcs, assetFile(filepath.Join(plugdir, d, f))) + } else if f == "info.json" { + p.Info = assetFile(filepath.Join(plugdir, d, "info.json")) + } + } + Plugins = append(Plugins, p) } } } diff --git a/internal/lua/plugin.go b/internal/lua/plugin.go deleted file mode 100644 index d68003c4..00000000 --- a/internal/lua/plugin.go +++ /dev/null @@ -1,67 +0,0 @@ -package lua - -import ( - "errors" - "io/ioutil" - "strings" - - lua "github.com/yuin/gopher-lua" -) - -var ErrNoSuchFunction = errors.New("No such function exists") - -type Plugin struct { - name string - files []string -} - -func NewPluginFromDir(name string, dir string) (*Plugin, error) { - files, err := ioutil.ReadDir(dir) - if err != nil { - return nil, err - } - - p := new(Plugin) - p.name = name - - for _, f := range files { - if strings.HasSuffix(f.Name(), ".lua") { - p.files = append(p.files, dir+f.Name()) - } - } - - return p, nil -} - -func (p *Plugin) Load() error { - for _, f := range p.files { - dat, err := ioutil.ReadFile(f) - if err != nil { - return err - } - err = LoadFile(p.name, f, dat) - if err != nil { - return err - } - } - return nil -} - -func (p *Plugin) Call(fn string, args ...lua.LValue) (lua.LValue, error) { - plug := L.GetGlobal(p.name) - luafn := L.GetField(plug, fn) - if luafn == lua.LNil { - return nil, ErrNoSuchFunction - } - err := L.CallByParam(lua.P{ - Fn: luafn, - NRet: 1, - Protect: true, - }, args...) - if err != nil { - return nil, err - } - ret := L.Get(-1) - L.Pop(1) - return ret, nil -}