]> git.lizzy.rs Git - micro.git/commitdiff
Add plugin info.json support
authorZachary Yedidia <zyedidia@gmail.com>
Wed, 7 Aug 2019 05:24:03 +0000 (22:24 -0700)
committerZachary Yedidia <zyedidia@gmail.com>
Wed, 25 Dec 2019 22:05:11 +0000 (17:05 -0500)
internal/action/command.go
internal/action/infocomplete.go
internal/config/plugin.go
internal/config/plugin_manager.go [new file with mode: 0644]
internal/config/rtfiles.go
internal/config/runtime.go
runtime/plugins/autoclose/info.json [new file with mode: 0644]
runtime/plugins/comment/info.json [new file with mode: 0644]
runtime/plugins/ftoptions/info.json [new file with mode: 0644]
runtime/plugins/linter/info.json [new file with mode: 0644]
runtime/plugins/literate/info.json [new file with mode: 0644]

index 03949b0ff4c84ed911aed1457264893619280ac0..39dc2c2a709a169c780530ca77d24365ec54ebc4 100644 (file)
@@ -1,6 +1,7 @@
 package action
 
 import (
+       "bytes"
        "errors"
        "fmt"
        "os"
@@ -52,7 +53,7 @@ func InitCommands() {
                "help":       Command{(*BufPane).HelpCmd, HelpComplete},
                "eval":       Command{(*BufPane).EvalCmd, nil},
                "log":        Command{(*BufPane).ToggleLogCmd, nil},
-               "plugin":     Command{(*BufPane).PluginCmd, nil},
+               "plugin":     Command{(*BufPane).PluginCmd, PluginComplete},
                "reload":     Command{(*BufPane).ReloadCmd, nil},
                "reopen":     Command{(*BufPane).ReopenCmd, nil},
                "cd":         Command{(*BufPane).CdCmd, buffer.FileComplete},
@@ -115,6 +116,8 @@ func CommandAction(cmd string) BufKeyAction {
        }
 }
 
+var PluginCmds = []string{"list", "info", "version"}
+
 // PluginCmd installs, removes, updates, lists, or searches for given plugins
 func (h *BufPane) PluginCmd(args []string) {
        if len(args) <= 0 {
@@ -132,10 +135,82 @@ func (h *BufPane) PluginCmd(args []string) {
                        } else {
                                en = "disabled"
                        }
-                       WriteLog(fmt.Sprintf("%s: %s\n", pl.Name, en))
+                       WriteLog(fmt.Sprintf("%s: %s", pl.Name, en))
+                       if pl.Default {
+                               WriteLog(" (default)\n")
+                       } else {
+                               WriteLog("\n")
+                       }
+               }
+               WriteLog("Default plugins come pre-installed with micro.")
+       case "version":
+               if len(args) <= 1 {
+                       InfoBar.Error("No plugin provided to give info for")
+                       return
+               }
+               found := false
+               for _, pl := range config.Plugins {
+                       if pl.Name == args[1] {
+                               found = true
+                               if pl.Info == nil {
+                                       InfoBar.Message("Sorry no version for", pl.Name)
+                                       return
+                               }
+
+                               WriteLog("Version: " + pl.Info.Vstr + "\n")
+                       }
+               }
+               if !found {
+                       InfoBar.Message(args[1], "is not installed")
+               }
+       case "info":
+               if len(args) <= 1 {
+                       InfoBar.Error("No plugin provided to give info for")
+                       return
+               }
+               found := false
+               for _, pl := range config.Plugins {
+                       if pl.Name == args[1] {
+                               found = true
+                               if pl.Info == nil {
+                                       InfoBar.Message("Sorry no info for ", pl.Name)
+                                       return
+                               }
+
+                               var buffer bytes.Buffer
+                               buffer.WriteString("Name: ")
+                               buffer.WriteString(pl.Info.Name)
+                               buffer.WriteString("\n")
+                               buffer.WriteString("Description: ")
+                               buffer.WriteString(pl.Info.Desc)
+                               buffer.WriteString("\n")
+                               buffer.WriteString("Website: ")
+                               buffer.WriteString(pl.Info.Site)
+                               buffer.WriteString("\n")
+                               buffer.WriteString("Installation link: ")
+                               buffer.WriteString(pl.Info.Install)
+                               buffer.WriteString("\n")
+                               buffer.WriteString("Version: ")
+                               buffer.WriteString(pl.Info.Vstr)
+                               buffer.WriteString("\n")
+                               buffer.WriteString("Requirements:")
+                               buffer.WriteString("\n")
+                               for _, r := range pl.Info.Require {
+                                       buffer.WriteString("    - ")
+                                       buffer.WriteString(r)
+                                       buffer.WriteString("\n")
+                               }
+
+                               WriteLog(buffer.String())
+                       }
+               }
+               if !found {
+                       InfoBar.Message(args[1], "is not installed")
+                       return
                }
        default:
-               valid = false
+               InfoBar.Error("Not a valid plugin command")
+               return
        }
 
        if valid && h.Buf.Type != buffer.BTLog {
index 15a175dad04d306ce663aecbe0255aa026177c39..598f387363573dac6483710cc42e429930b32658 100644 (file)
@@ -197,6 +197,62 @@ func OptionValueComplete(b *buffer.Buffer) ([]string, []string) {
        return completions, suggestions
 }
 
+// OptionComplete autocompletes options
+func PluginCmdComplete(b *buffer.Buffer) ([]string, []string) {
+       c := b.GetActiveCursor()
+       input, argstart := buffer.GetArg(b)
+
+       var suggestions []string
+       for _, cmd := range PluginCmds {
+               if strings.HasPrefix(cmd, input) {
+                       suggestions = append(suggestions, cmd)
+               }
+       }
+
+       sort.Strings(suggestions)
+       completions := make([]string, len(suggestions))
+       for i := range suggestions {
+               completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
+       }
+       return completions, suggestions
+}
+
+// PluginComplete completes values for the plugin command
+func PluginComplete(b *buffer.Buffer) ([]string, []string) {
+       c := b.GetActiveCursor()
+       l := b.LineBytes(c.Y)
+       l = util.SliceStart(l, c.X)
+       input, argstart := buffer.GetArg(b)
+
+       completeValue := false
+       args := bytes.Split(l, []byte{' '})
+       if len(args) >= 2 {
+               for _, cmd := range PluginCmds {
+                       if cmd == string(args[len(args)-2]) {
+                               completeValue = true
+                               break
+                       }
+               }
+       }
+       if !completeValue {
+               return PluginCmdComplete(b)
+       }
+
+       var suggestions []string
+       for _, pl := range config.Plugins {
+               if strings.HasPrefix(pl.Name, input) {
+                       suggestions = append(suggestions, pl.Name)
+               }
+       }
+       sort.Strings(suggestions)
+
+       completions := make([]string, len(suggestions))
+       for i := range suggestions {
+               completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
+       }
+       return completions, suggestions
+}
+
 // // MakeCompletion registers a function from a plugin for autocomplete commands
 // func MakeCompletion(function string) Completion {
 //     pluginCompletions = append(pluginCompletions, LuaFunctionComplete(function))
index 40a526e9fa1347d3cde1448d89b421cbda546967..f659961990d08c4974696990ffa0f0a6785b75c7 100644 (file)
@@ -65,10 +65,11 @@ func RunPluginFnBool(fn string, args ...lua.LValue) (bool, error) {
 }
 
 type Plugin struct {
-       Name   string        // name of plugin
-       Info   RuntimeFile   // json file containing info
-       Srcs   []RuntimeFile // lua files
-       Loaded bool
+       Name    string        // name of plugin
+       Info    *PluginInfo   // json file containing info
+       Srcs    []RuntimeFile // lua files
+       Loaded  bool
+       Default bool // pre-installed plugin
 }
 
 func (p *Plugin) IsEnabled() bool {
diff --git a/internal/config/plugin_manager.go b/internal/config/plugin_manager.go
new file mode 100644 (file)
index 0000000..19f53cd
--- /dev/null
@@ -0,0 +1,66 @@
+package config
+
+import (
+       "bytes"
+       "encoding/json"
+       "errors"
+)
+
+var (
+       ErrMissingName    = errors.New("Missing or empty name field")
+       ErrMissingDesc    = errors.New("Missing or empty description field")
+       ErrMissingSite    = errors.New("Missing or empty website field")
+       ErrMissingInstall = errors.New("Missing or empty install field")
+       ErrMissingVstr    = errors.New("Missing or empty versions field")
+       ErrMissingRequire = errors.New("Missing or empty require field")
+)
+
+// PluginInfo contains all the needed info about a plugin
+// The info is just strings and are not used beyond that (except
+// the Site and Install fields should be valid URLs). This means
+// that the requirements for example can be formatted however the
+// plugin maker decides, the fields will only be parsed by humans
+// Name: name of plugin
+// Desc: description of plugin
+// Site: home website of plugin
+// Install: install link for plugin (can be link to repo or zip file)
+// Vstr: version
+// Require: list of dependencies and requirements
+type PluginInfo struct {
+       Name    string   `json:"name"`
+       Desc    string   `json:"description"`
+       Site    string   `json:"website"`
+       Install string   `json:"install"`
+       Vstr    string   `json:"version"`
+       Require []string `json:"require"`
+}
+
+// NewPluginInfo parses a JSON input into a valid PluginInfo struct
+// Returns an error if there are any missing fields or any invalid fields
+// There are no optional fields in a plugin info json file
+func NewPluginInfo(data []byte) (*PluginInfo, error) {
+       var info PluginInfo
+
+       dec := json.NewDecoder(bytes.NewReader(data))
+       // dec.DisallowUnknownFields() // Force errors
+
+       if err := dec.Decode(&info); err != nil {
+               return nil, err
+       }
+
+       // if len(info.Name) == 0 {
+       //      return nil, ErrMissingName
+       // } else if len(info.Desc) == 0 {
+       //      return nil, ErrMissingDesc
+       // } else if len(info.Site) == 0 {
+       //      return nil, ErrMissingSite
+       // } else if len(info.Install) == 0 {
+       //      return nil, ErrMissingInstall
+       // } else if len(info.Vstr) == 0 {
+       //      return nil, ErrMissingVstr
+       // } else if len(info.Require) == 0 {
+       //      return nil, ErrMissingRequire
+       // }
+
+       return &info, nil
+}
index 16cc04d148b739315cc546a06a53fd7c13f972b8..fdc3388984f454e02a88285252df891e51e7e9b7 100644 (file)
@@ -154,7 +154,11 @@ func InitRuntimeFiles() {
                                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"))
+                                       data, err := ioutil.ReadFile(filepath.Join(plugdir, d.Name(), "info.json"))
+                                       if err != nil {
+                                               continue
+                                       }
+                                       p.Info, _ = NewPluginInfo(data)
                                }
                        }
                        Plugins = append(Plugins, p)
@@ -167,11 +171,16 @@ func InitRuntimeFiles() {
                        if srcs, err := AssetDir(filepath.Join(plugdir, d)); err == nil {
                                p := new(Plugin)
                                p.Name = d
+                               p.Default = true
                                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"))
+                                               data, err := Asset(filepath.Join(plugdir, d, "info.json"))
+                                               if err != nil {
+                                                       continue
+                                               }
+                                               p.Info, _ = NewPluginInfo(data)
                                        }
                                }
                                Plugins = append(Plugins, p)
index 0fa2f4e353ee2275d022cdb4203989b8a1eedae0..4764f31186a5128c8ba0ac8340b374ed987c308f 100644 (file)
 // runtime/help/plugins.md
 // runtime/help/tutorial.md
 // runtime/plugins/autoclose/autoclose.lua
+// runtime/plugins/autoclose/info.json
 // runtime/plugins/comment/comment.lua
+// runtime/plugins/comment/info.json
 // runtime/plugins/ftoptions/ftoptions.lua
+// runtime/plugins/ftoptions/info.json
+// runtime/plugins/linter/info.json
 // runtime/plugins/linter/linter.lua
 // runtime/plugins/literate/README.md
+// runtime/plugins/literate/info.json
 // runtime/plugins/literate/literate.lua
 // runtime/syntax/LICENSE
 // runtime/syntax/PowerShell.yaml
@@ -1052,6 +1057,26 @@ func runtimePluginsAutocloseAutocloseLua() (*asset, error) {
        return a, nil
 }
 
+var _runtimePluginsAutocloseInfoJson = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x8f\xc1\x4e\xc3\x30\x0c\x86\xcf\xf4\x29\xac\x9c\xab\x74\x70\x9c\x04\x12\xcf\x81\x38\xb8\xae\x59\x2d\xd2\x24\xb3\x1d\xd0\x40\xbc\x3b\x6a\x60\xf7\x1d\xfd\xfd\xfe\xf5\xd9\xdf\x03\x00\x40\xc8\xb8\x71\x38\x42\x48\x92\x9d\x35\x8c\x7f\x74\x61\x23\x95\xea\x52\xf2\x1e\x3e\x37\x2f\x1b\xba\x10\xa6\x74\x81\x9a\x90\xd8\x80\x52\x31\xc9\x27\xa0\x15\x15\xc9\x59\x0d\xde\x8a\xc2\xb9\x15\x67\x1b\xa1\xa2\x72\xf6\x95\x6d\x1f\x66\x45\x7a\x67\xb7\x11\xd8\x29\xc6\x78\xf5\x7c\xf2\x6c\xe2\xfd\x80\xd5\xbd\xda\x71\x9a\x4e\xe2\x6b\x9b\x23\x95\x6d\xfa\xba\xf0\x22\x8b\xe0\xb4\x09\x69\x09\xe3\x70\x17\x24\x9b\x63\x4a\xb7\x16\xba\xe4\x83\xd5\xfe\x1f\xb9\x8f\x87\x78\xb8\x72\xe5\x73\x13\xdd\xe5\x2f\x1d\x74\xd8\x9b\xf0\xf4\x08\x0f\x7d\xb5\x07\xaf\xc3\xcf\xf0\x1b\x00\x00\xff\xff\xb5\xd0\x75\x6b\x2f\x01\x00\x00"
+
+func runtimePluginsAutocloseInfoJsonBytes() ([]byte, error) {
+       return bindataRead(
+               _runtimePluginsAutocloseInfoJson,
+               "runtime/plugins/autoclose/info.json",
+       )
+}
+
+func runtimePluginsAutocloseInfoJson() (*asset, error) {
+       bytes, err := runtimePluginsAutocloseInfoJsonBytes()
+       if err != nil {
+               return nil, err
+       }
+
+       info := bindataFileInfo{name: "runtime/plugins/autoclose/info.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
+       a := &asset{bytes: bytes, info: info}
+       return a, nil
+}
+
 var _runtimePluginsCommentCommentLua = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x57\x5b\x6f\x2b\x35\x10\x7e\xcf\xaf\x30\x7b\x88\x64\xb7\xd9\xed\x49\x79\x8b\x08\x12\xed\x43\x91\x08\x07\xa9\xad\x20\x55\x14\xa4\xbd\xcc\x26\x3e\x78\xbd\x2b\xdb\x0b\x44\x08\x7e\x3b\xf2\x65\xaf\xde\x84\x1c\x21\xc1\x0b\x95\xda\x6c\x3e\xcf\x37\x63\xcf\x7c\xe3\xd9\xb2\x32\x8d\x19\xaa\x15\x65\x68\x8d\x68\x51\x95\x42\xe1\xa0\xa0\xa9\x28\xef\x34\x18\x90\x99\xb5\x48\x4b\x9e\xd3\x83\x67\x63\xe1\xd6\x2a\xa9\xf3\x1c\x84\x67\x65\xe1\x80\xcc\x9c\x59\xae\xd0\x1a\xfd\xfe\xc7\x6c\x96\xab\x5d\x90\x06\x7b\xb4\x46\xc1\xdd\x1d\x9a\xcb\xc0\x22\xb7\xb7\x1e\x76\x28\x3d\xa8\x3a\xa9\x63\xc9\x2d\xfc\x6e\x84\x7e\x31\x86\x8f\xaa\x60\x16\xfb\xf2\xb3\x30\x44\x73\x89\xc2\xf0\x2b\xbb\xf4\x31\xfe\x25\xf6\x9c\x7f\xac\x19\x8d\x3d\xdf\x20\x98\x87\x1d\x2b\x8f\x2c\x6a\xa9\x3c\x50\x1e\x81\x79\x6c\x56\xbb\x20\x66\x4f\xdd\x7e\x64\x2a\x68\xe5\xfb\x10\x75\x72\x1a\xbb\xc8\xfc\x48\xbf\xd2\x7c\xc8\x9d\xe5\x35\x4f\x15\x2d\x39\x2a\xf9\x83\x29\xc6\xf7\x15\x70\x9c\xd4\x39\x99\x21\x84\x10\xcd\x75\xe9\xa2\x17\x50\x8a\xf2\x83\xdc\x05\x69\x59\x14\xc0\x95\x3a\x55\xa0\x1d\xad\x11\xa7\x0c\xa9\x23\x70\x63\xee\x28\xb9\xda\x0d\x59\x39\x65\x60\x29\x7b\xf4\xe7\x04\x47\xff\x5c\x8c\x73\xd1\x65\xeb\x06\x98\x84\x4f\xf0\xe9\x72\xd5\xb2\x79\x36\x6b\x3e\xf5\x6f\x97\x1b\x47\xdc\x50\x0e\x38\xa9\x16\x88\x51\x0e\x1f\x6c\x82\xac\x6e\x35\x80\xd6\x28\xa9\xa2\x87\x3a\x5f\x19\x3b\xcf\xc6\x39\x79\x3d\x55\x9d\xe9\xb9\xcd\xf9\xb4\x67\x38\xc0\x6f\x7a\xcf\x3f\xcd\xe5\x4d\x80\xa2\xa8\xef\x6f\x75\x90\x75\x82\x83\xf9\x4d\xb0\x40\xfa\x2f\x69\x80\xd0\x00\x61\x07\x44\x06\x88\x3a\xe0\xd6\x00\xb7\x1d\xb0\x37\xc0\xbe\x03\x76\x06\xd8\x75\xc0\x5c\x6a\x04\x47\x37\x24\xe8\x9f\x4f\x82\xbe\x29\xc2\xa4\x8a\x1e\x6b\x21\x4b\xa1\x3f\x5e\x80\x81\x49\x61\xff\x40\xb5\xa8\x4a\x39\x34\xdd\x94\x69\xcf\x82\xf2\xcc\x9c\x55\x2a\x41\xf9\x21\xca\x29\xcf\x70\xef\xb4\x7a\x3b\x73\x19\x10\x14\xa2\x65\x23\x52\x67\x5a\xc4\x2a\x3d\x9a\xd4\x2f\x06\x89\x23\x43\xb9\xd5\xdc\x2d\x42\xb6\xb1\x95\xfb\x3b\x7e\x4b\x75\x25\x7e\x86\x8a\xc5\x29\x60\x7b\x81\xe9\xfd\xe3\xf7\x8d\x2e\x16\xa8\x87\xbe\xb3\xce\x9a\x15\x7d\x75\x46\x4f\xa0\x36\x10\x67\x94\x1f\x7e\x3c\x52\x05\xb2\xd2\x9e\xb4\x05\xd1\x75\x1d\x6d\x8e\xf4\x1b\xab\xcd\xd8\xea\x9b\x58\xb6\xc9\xc5\x64\xa2\x9b\x26\xcb\xb0\x5b\xee\xa3\x37\x7d\x5c\x60\xe6\xf1\x1a\xca\x7d\x47\xb9\xbf\x92\xb2\xdc\x47\xdb\x2e\xca\xf6\xca\x28\xdb\x2e\xca\xf6\x42\x4b\xb7\x7c\x6d\x6f\xc5\x14\x6d\x51\x68\x55\x73\xc6\xf4\xad\x33\x7d\xf3\xfb\xbd\x1f\x62\xd0\x74\xad\x3c\x26\x7a\xcd\x74\x81\x12\xb4\xb0\x95\xfb\x37\x15\xf2\xbf\x3e\x3e\x5d\x1f\xb7\xff\x40\x1f\xee\xb3\x4b\xee\x33\x68\x99\x28\xc0\x64\xb8\x10\x6d\x62\xa9\x7e\xa0\xb2\x8e\xd9\xd6\xde\xf1\x8e\xf0\x04\x0d\x8c\xc9\xf4\x6c\xe9\x8a\xa5\x07\x8c\x54\xb1\x30\xe3\x66\xa1\xa3\x77\x65\xce\x4b\xd1\xcc\x1a\xdf\x04\x65\x65\xbb\xf7\xa9\x89\x45\x2e\x4f\x37\x9c\x54\xdd\xcc\xbf\x4a\x47\x7d\xc3\x71\x81\x57\x4f\x02\x62\x05\xe2\xf5\x18\x73\x7c\x66\x28\xec\xee\xf7\x13\xca\xb4\x1d\xd8\x9c\x69\x7d\x49\xa9\x03\xde\xa5\xdd\x68\x2d\xac\xd1\x7b\x3f\x98\xcb\x88\x0b\xd5\x3c\x35\x83\x65\xac\x84\x51\x76\x87\x35\xbb\xd0\x1e\xa3\x2a\x4e\xea\xf6\xca\x63\x7b\x2d\x76\xfe\xd8\xf7\xff\xe5\xb1\x97\x67\x8e\x3d\x75\xe7\x8e\xc5\xda\xeb\xcb\x73\x9a\x35\x17\xaf\xb4\xab\x02\x54\x2d\x38\xc2\xd2\x5d\xcd\xfa\x0d\x09\x47\x21\x99\xcb\x9b\xcf\xcd\xbb\xcb\x32\x20\xe3\xae\x73\xf3\xde\x34\x91\xc4\x2f\xe6\xdb\xe2\x45\x7f\x1b\xf8\x6c\xcc\xea\xa4\xb1\x59\x2e\x1c\xc6\x80\x63\x4b\x20\xeb\xb5\x79\xb0\x21\xec\x3f\x3e\xd1\x77\xf1\xcf\xf0\x58\x16\x45\xcc\x33\xdc\xbc\xdb\xe9\xcd\xb8\xc7\xa8\x83\x1c\xe1\x43\xf9\x58\x16\x15\x03\x05\xa4\xf1\xf1\x2a\x4e\x0f\x94\x67\xdf\xc2\x09\x07\x5f\x33\x15\xde\x69\x07\xac\x8e\x57\xbe\x93\x3c\x66\x12\xc8\xec\xaf\x00\x00\x00\xff\xff\x93\xd1\x8d\x0e\xb5\x0d\x00\x00"
 
 func runtimePluginsCommentCommentLuaBytes() ([]byte, error) {
@@ -1072,6 +1097,26 @@ func runtimePluginsCommentCommentLua() (*asset, error) {
        return a, nil
 }
 
+var _runtimePluginsCommentInfoJson = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x8f\xb1\x4e\x43\x31\x0c\x45\x67\xde\x57\x5c\x65\xae\xf2\x0a\x63\x25\xd8\xf8\x02\x46\xc4\x90\x97\xb8\xaf\x16\x49\x1c\x12\x07\x28\x88\x7f\x47\x4d\xdb\xbd\xeb\xb9\xbe\x3e\xf6\xef\x04\x00\x26\xbb\x44\x66\x07\xe3\x25\x25\xca\x6a\x36\x67\x1c\xa8\xf9\xca\x45\x59\xf2\x29\x7d\xe9\xa5\x48\x55\xec\xa5\xc2\x75\x95\xe4\x94\xbd\x8b\xf1\x88\x4b\x8f\xf3\x8a\x25\x8a\x7f\x6f\x90\x3d\xbc\x04\xb2\x78\xfe\x56\xca\x8d\x97\x48\x70\x39\x20\xf5\xa8\x5c\x22\x21\xba\xbc\x76\xb7\x52\x43\x3b\xaf\xa5\x60\xaf\xde\x2f\x5a\x1a\xeb\xb8\xe8\xa0\x5a\xda\x6e\x9e\x57\xd6\x43\x5f\xac\x97\x34\xff\x1c\x29\x70\x60\x37\x27\xf6\x55\xcc\x66\xba\x33\x9c\x9b\xba\x18\x6f\x2d\x0c\xc9\x27\xd5\x76\x79\xec\xde\x6e\xed\xf6\xca\x2b\x7d\x74\xae\x27\xf9\xeb\x00\x03\x8e\x26\x9e\x1e\xf1\x30\x46\x47\xf0\x36\xfd\x4d\xff\x01\x00\x00\xff\xff\x56\x49\x72\x08\x40\x01\x00\x00"
+
+func runtimePluginsCommentInfoJsonBytes() ([]byte, error) {
+       return bindataRead(
+               _runtimePluginsCommentInfoJson,
+               "runtime/plugins/comment/info.json",
+       )
+}
+
+func runtimePluginsCommentInfoJson() (*asset, error) {
+       bytes, err := runtimePluginsCommentInfoJsonBytes()
+       if err != nil {
+               return nil, err
+       }
+
+       info := bindataFileInfo{name: "runtime/plugins/comment/info.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
+       a := &asset{bytes: bytes, info: info}
+       return a, nil
+}
+
 var _runtimePluginsFtoptionsFtoptionsLua = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\xcf\xb1\x0e\x82\x40\x0c\x06\xe0\x9d\xa7\x68\x6e\x82\xc4\x49\x37\x12\x16\x07\x57\x06\x7d\x81\x3b\x6c\xe5\xe2\xd1\x5e\xb8\x32\xf0\xf6\x86\x13\x75\x82\xc4\x26\x5d\xfa\x25\xfd\xf3\xd3\xc4\x9d\x7a\x61\x10\x3e\x4f\x44\x38\xb6\x11\xb9\x74\x55\x01\x00\x10\xa4\xb3\x01\x48\xa1\x01\x57\x5f\x7c\xc0\xdb\x1c\xb1\xac\x8a\x8c\x9e\xb2\x34\x60\x1e\x62\x40\xc6\x7c\x5c\x2f\x83\x7d\x22\xf9\x80\x06\xb4\x47\xce\xb2\x8c\xab\xaf\xa8\x6d\x5c\xf2\x4a\xa3\xd6\x25\x95\x14\x6d\x87\xc9\x1c\xc0\x08\x91\x79\xc7\x62\x48\xf8\xfb\x4e\x3e\xf5\xdf\xff\xeb\xac\x14\x67\xed\x85\x77\xf1\xb8\xab\xa7\x0d\x9d\xed\x10\x36\x88\xfd\xf0\x57\x2b\xfe\x94\xe2\x7b\xb1\xec\x2b\x00\x00\xff\xff\x55\x1f\xb6\x5b\x71\x01\x00\x00"
 
 func runtimePluginsFtoptionsFtoptionsLuaBytes() ([]byte, error) {
@@ -1092,6 +1137,46 @@ func runtimePluginsFtoptionsFtoptionsLua() (*asset, error) {
        return a, nil
 }
 
+var _runtimePluginsFtoptionsInfoJson = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x8f\xbd\x4e\xc4\x30\x10\x84\x6b\xf2\x14\x23\x57\x20\x9d\x92\x83\x32\x12\xbc\x01\x15\x25\xa2\x70\x92\x0d\x59\xe1\x3f\xbc\x7b\xc0\x81\x78\x77\x94\x25\xe9\xaf\xf4\xf7\xed\x68\xc6\x3f\x0d\x00\xb8\xe4\x23\xb9\x1e\x6e\xd6\x5c\x94\x73\x12\x77\xf8\x17\x13\xc9\x58\xd9\xd8\xea\x9f\x48\x05\x83\x17\x1e\xb1\x1d\xae\x2f\x9a\x90\x13\x74\x21\xcc\x1c\x48\xcf\x85\x70\x3d\xe7\x0a\xfa\xf2\xb1\x04\xc2\xa3\x7f\xa3\xd5\x08\x2a\xbd\x9f\xb8\x12\xd4\x0f\x72\xd3\xee\x25\x9f\x34\x08\xab\x0d\x58\x54\x8b\xf4\x5d\xf7\xca\xba\x9c\x86\x76\xcc\xb1\xfb\x3e\xd3\xc4\x13\xfb\x2e\xf2\x58\xb3\x3b\x34\x57\x8e\x93\xa8\x0f\xe1\xd2\x80\x95\x7c\x50\x95\xed\x17\xb7\xed\xb1\x3d\xee\x7c\x9b\xe4\x7a\x3c\x1b\x30\x68\x49\x3c\xdc\xe3\xce\x4e\x4d\xbc\x34\xbf\xcd\x5f\x00\x00\x00\xff\xff\xa1\xba\x02\x21\x2f\x01\x00\x00"
+
+func runtimePluginsFtoptionsInfoJsonBytes() ([]byte, error) {
+       return bindataRead(
+               _runtimePluginsFtoptionsInfoJson,
+               "runtime/plugins/ftoptions/info.json",
+       )
+}
+
+func runtimePluginsFtoptionsInfoJson() (*asset, error) {
+       bytes, err := runtimePluginsFtoptionsInfoJsonBytes()
+       if err != nil {
+               return nil, err
+       }
+
+       info := bindataFileInfo{name: "runtime/plugins/ftoptions/info.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
+       a := &asset{bytes: bytes, info: info}
+       return a, nil
+}
+
+var _runtimePluginsLinterInfoJson = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x8e\x4d\x4e\x03\x31\x0c\x85\xd7\xe4\x14\x56\xd6\x55\x52\x58\x56\x02\x89\x73\x20\x16\x6e\xe2\xa6\x96\xf2\x53\x1c\x67\xd0\x80\xb8\x3b\x9a\xc0\xec\xbb\xfd\xde\x7b\xfe\xfc\x6d\x00\x00\x6c\xc5\x42\xf6\x04\x36\x73\x55\x12\x7b\xf8\xa3\x91\x7a\x10\xbe\x29\xb7\xba\x85\xaf\x43\x5b\x41\xe5\x00\xa1\x45\x82\xad\xcb\x35\xc1\xa5\x09\x20\x2c\x28\x4c\xba\x42\xbb\x40\xc6\x9a\x06\x26\xea\x6e\x3f\xf4\x49\xe7\xce\x3a\x0d\x57\xd5\x5b\x3f\x79\x9f\x58\xaf\xe3\xec\x42\x2b\xfe\x6b\xa5\xc8\x91\xd1\x17\x0e\xd2\xec\xc1\x3c\x58\xae\x5d\x31\xe7\x7b\x07\x53\xb2\x90\xf4\xff\x4f\x1f\xdd\xd1\x1d\x77\x2e\xf4\x31\x58\x36\xf9\xdb\x04\x13\xce\x25\xbc\x3c\xc3\xd3\xac\xce\xe0\xdd\xfc\x98\xdf\x00\x00\x00\xff\xff\x66\xe8\x97\x46\x10\x01\x00\x00"
+
+func runtimePluginsLinterInfoJsonBytes() ([]byte, error) {
+       return bindataRead(
+               _runtimePluginsLinterInfoJson,
+               "runtime/plugins/linter/info.json",
+       )
+}
+
+func runtimePluginsLinterInfoJson() (*asset, error) {
+       bytes, err := runtimePluginsLinterInfoJsonBytes()
+       if err != nil {
+               return nil, err
+       }
+
+       info := bindataFileInfo{name: "runtime/plugins/linter/info.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
+       a := &asset{bytes: bytes, info: info}
+       return a, nil
+}
+
 var _runtimePluginsLinterLinterLua = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x59\x5f\x8f\xa4\xb8\x11\x7f\x9f\x4f\x61\xa1\x20\xd1\x3b\xc0\xec\x46\x79\x42\x6a\x45\x97\xcd\x5d\xa4\x68\xff\x44\x9a\x8d\xf2\xb0\xbb\x17\xb9\x4d\xd1\xed\x1b\x63\x13\xdb\x74\x4f\x67\xb4\xdf\x3d\x2a\xdb\xd0\x86\x86\xd9\xc9\xdd\xb5\x34\x60\x4c\xb9\xea\x57\x7f\x5d\x66\x84\x62\x54\x10\xdd\x4b\xcb\x5b\x20\x5b\xc2\xdb\x4e\x69\x9b\x25\x61\x26\xd9\xdc\x78\x8a\x86\x0b\xe8\xa8\x3d\x44\x24\xf8\x78\x37\xcc\x8f\x84\xe6\x00\x42\x44\x54\x2d\x67\x5a\xdd\xb9\xd9\x91\x66\xd7\x37\x0d\xe8\x2b\x22\x3f\x3d\x52\x31\x25\x1b\xbe\xbf\xa2\xf2\xd3\xc9\xe6\x26\x90\x09\x2e\x2d\x68\x43\xb6\xe4\xe9\xdb\xcd\x4d\x51\x10\xa6\x81\x5a\x30\x84\x86\x57\x04\xa4\xd5\xe7\x9c\x30\x2a\x04\x69\xb4\x6a\xc9\x89\xdb\x03\x97\x84\x4a\xc2\x25\xb7\x9c\x0a\xfe\x5f\x6a\xb9\x92\xa4\xe9\x25\xc3\x41\x4e\xa4\xb2\xc8\xab\xe6\x1a\x98\x15\x67\x42\xed\x40\x4b\x84\xa2\x35\x41\xe3\xdc\x14\x05\xd2\x48\xda\x42\xe5\xae\x44\x35\xc4\x1e\x20\xc8\xc5\x77\x68\x1e\x7b\xee\xa0\x1a\x47\xc4\x2a\xc2\x0e\xc0\x1e\x48\xa3\x34\x3e\xf4\x26\x5e\xc0\xda\xba\x22\x2d\xe5\x72\x00\xdf\x69\xc5\xc0\x18\x62\x0f\x08\xc1\x10\x78\x04\xd6\x5b\xa8\x91\x98\xea\xbd\xa9\xf0\xda\xb7\x20\xad\x41\x6e\x1d\x35\xee\x7e\x81\x31\x70\xc0\x05\xf8\x43\x79\x69\x83\x34\x1a\xd0\x0b\x81\x98\xf5\x5a\x83\xb4\x0e\xa7\x53\x66\x42\x5f\xaf\xd2\x7b\x0b\x29\x7d\x1e\x17\x81\xd6\x4a\x37\x4a\xb7\xd4\x56\xe4\xa0\x4e\x1e\x96\x36\x10\x81\xba\x63\xaa\xed\xb8\x88\xf4\x53\xbd\xed\x7a\x3b\x08\x4d\x1b\x6f\xb1\x9c\xa4\xa2\xc2\x35\x40\x64\xdf\xee\x40\xe7\x24\x6d\x2b\x2f\xe2\xee\x44\xb5\xe4\x72\x4f\x5a\x30\x86\xee\x9d\x6c\x65\x90\xda\x58\xf4\xc4\xc7\x7b\xb4\x1a\x37\x83\x1d\xb8\x21\xa6\xef\x30\x94\xa0\x26\x4a\x93\x5e\x46\x8f\x72\x90\xac\x3a\x0c\x00\x2a\x10\x32\x6d\x73\x52\x43\x43\x7b\x61\x2b\x8c\xae\xa2\x20\xa7\x03\xb7\x80\x12\x2a\x62\x0e\xaa\x17\xb5\x53\xea\xe3\xbd\x97\xba\x03\x42\xc9\x4e\x50\xf6\xe0\x1e\xb3\x5a\x61\x20\x61\x7a\xc5\x0e\x71\x8e\x3f\x80\xc1\x75\x66\x33\x08\x0e\x3f\xa5\x09\xbd\x48\x21\x99\x92\xe2\xfc\x32\x06\xab\xc8\x1b\x2a\x0c\x90\x2c\xe0\x1d\xe1\xb9\x85\xb5\x6a\xa9\x65\x87\x89\x36\x63\xa8\xee\x80\x38\x81\x9d\x06\x34\x12\x75\x39\xd5\x53\xd2\x51\x6b\x41\x4b\x74\xac\x5b\xed\x12\x6a\xa2\x07\xb2\xa1\xcc\xf6\xa1\x72\x20\xb7\x1c\x55\x8b\xa4\x04\x5d\x9c\x7e\x94\x59\x7e\xa4\x16\x88\x72\x59\x09\x8f\x94\x59\xcf\xfa\xa5\xca\x69\xf8\x4f\xcf\x35\xc4\x4b\x9d\x7e\x42\x35\x8d\x01\x1b\x62\xc8\x3f\x90\x13\x17\xc2\xf9\xaa\xae\xa1\x8e\xb2\x65\x08\x32\xa2\xc1\xf6\x5a\x42\x4d\x76\xe7\x59\x42\x8f\xbf\xde\x40\xd3\x0b\xc2\xe3\x8c\x0f\xeb\x0c\x79\x5d\x70\x59\xc3\x23\xd4\x8e\xab\xf9\xae\x12\xaf\x5d\xea\x0f\x50\x99\x12\x7d\x2b\x9f\x05\xcb\x94\xf8\xfd\xb1\x7a\xb9\x2f\x41\x3b\xd4\x49\xd2\xd2\x07\x78\xe7\xf8\x65\x98\xfe\x79\xe4\x6d\xd6\xd6\xb9\xab\x50\x79\x5c\x11\x72\xa2\x4c\x7e\x89\xef\x7c\x08\xc0\x7c\xf0\x54\x3e\xd8\x61\x73\x83\x20\x78\x33\x14\xf8\xcf\x28\xe0\x2b\xd9\x6e\x89\xe4\x02\x15\x91\x37\x83\x7e\x33\x0a\x4c\xd5\xc5\x57\xe5\x18\xd9\xdb\x11\xe8\x0a\x25\x6b\x6b\xb2\x45\x1d\x56\xde\xa3\x62\x64\xeb\xf4\x5b\xa1\x88\x94\x26\xdb\xd8\x04\x2b\xf4\x0a\xf9\x29\x83\x59\xb2\x8a\xff\x52\x17\xb6\x51\x8d\x50\xda\x67\xc1\xca\xa2\x60\x61\xb2\x1d\x6c\xfd\xbd\x05\xc1\x13\x64\x3b\xf8\x04\x17\xbc\x5e\x33\xd4\x48\xcc\xe6\xc4\x20\xeb\x1b\xfc\xbb\x84\x8b\x86\x56\x1d\xe3\x80\xf1\x4e\x9e\xfb\x4f\x72\x31\x5b\x88\x7b\x6f\x16\x88\xdd\xae\x5f\xc3\x51\xf6\xae\xd1\x48\xee\x6a\x38\xde\xe1\x43\x32\x44\x4c\x68\x5e\xca\xbf\x7d\xfc\x78\x8f\x01\x93\x9c\xb8\xac\xd5\xc9\x24\xd3\xb0\x89\x78\x7c\xf8\xe7\xbb\x64\xc4\xec\x06\x51\x64\x27\x7b\xc6\x92\x9c\x24\xee\xe2\xc7\x4f\x49\xd1\x98\xb3\xb4\xf4\xb1\xc0\x02\x86\x2f\x8a\x7f\x51\x21\xfc\x00\x1e\xad\xa6\x38\x4c\x9b\xe4\x9b\xbb\x55\xa9\xa8\x52\x56\x95\xb7\x15\x49\xdb\x64\xb3\x2a\xe1\xf6\xf6\x19\x19\x49\x61\x6c\xbd\x65\xb7\xb7\x6f\xfe\xf4\x9b\x05\xd6\x6d\x8d\xf4\xfe\xe2\xc6\x4f\x49\xc1\x94\x50\x7a\xab\x9a\xc6\x71\x55\x85\xbb\x9d\xfc\x95\xbb\x1b\x9b\x08\x49\xb3\x54\xa4\x9b\x67\xb4\x52\xbb\x9e\x0b\x27\x63\xaf\xc6\xeb\x53\x32\xce\x16\xf8\x1c\xdc\x70\xc1\xbd\xc6\x0c\xc3\x24\xe6\x15\x9e\x9f\xae\xb4\x5e\x66\xf0\x0b\x3d\x52\x87\x1f\x07\xc3\x3d\x18\xda\xa1\x49\xeb\x2b\x13\xfa\xbc\x5d\x63\x68\x0e\x01\x11\x72\x32\x4c\xf3\xce\x3f\x0d\xf3\x31\x32\xbf\xbf\xa4\x22\x2f\x6f\xf3\x65\x76\x82\x5b\xd0\xd4\x02\xb2\x98\x8d\x83\x7b\xae\x3d\xdc\xe2\x9b\x6f\xb9\x4f\xe7\x9c\x58\xdd\xc3\x02\xe3\x9e\xba\x8e\xd3\x31\xeb\x69\xb8\x0d\x53\x4f\x49\x51\x48\xe5\x7d\xbf\x14\x42\xcb\x60\x25\x47\xd1\xd3\xdb\x53\x32\x8a\x29\x0a\xac\x4c\x3f\xf5\x42\xfc\x83\xda\x83\xf1\x53\xc6\xd6\xaa\xb7\x7e\x8c\x16\x32\x55\x08\xb5\x51\x64\x99\x8a\x9c\xa4\xac\x5c\x96\xc9\x04\x95\x7b\xa4\x57\xbb\x5f\x00\x3b\x06\xf0\x26\x79\x64\xba\x97\x5e\xfe\x40\xf1\xfb\x66\x67\x77\x6e\x04\x7d\x00\xa7\x46\x77\xb6\x07\x25\xfd\x68\x9c\x9d\x85\x60\x59\x54\x7f\x5e\xe6\xd4\x9e\xbb\xf3\x94\x4b\x98\x99\x71\x58\xc3\x31\xa4\x40\x8c\x62\x4c\x83\xa2\xf0\x4d\x74\xe1\xf7\x99\xad\x6b\xba\xe9\x4e\x80\x37\xb9\x06\x6c\x76\xcd\x56\xaa\xeb\x30\x5f\x14\x67\x0e\x4d\xeb\xa4\xf9\xd3\x9b\x1b\xf8\x99\x97\xa6\x9c\x39\xf1\xc6\x3a\x1f\xb9\xd1\xd4\x59\x97\x97\x2b\x8e\x40\xa2\x9a\xea\x13\x97\xf8\x7a\x39\xb6\x67\x12\xd8\x22\xb8\x88\x9f\xe0\xb2\x7f\x5c\x67\x77\xa6\xad\x53\x34\xbe\x47\xf6\xf5\x86\x75\x66\xa7\xda\x0c\xa6\xbd\x16\xe7\xad\xe1\xb8\xfb\xe3\x6a\xf9\x9e\x3e\xc0\x5b\xd5\xb6\x54\xd6\x98\xe9\xde\x8b\x7e\xdf\x2b\xf1\xf6\xd6\xd5\xe0\x40\xfc\x41\xbd\x55\x6d\x27\xc0\xc2\x66\xb6\x0f\x06\xd2\x6c\xd7\x79\xec\xbb\xae\xba\xa7\x47\x08\x5b\xa3\xee\x65\x50\x64\xd7\x95\x7f\xe9\x9b\xf9\x6a\xa6\xa4\xa5\x5c\x9a\xcc\xb7\x5e\x20\x00\xcf\x8d\x7e\x2d\x9e\x29\x1e\x72\x72\x24\x5c\x92\x8e\x72\xed\x89\x36\xa4\x56\xe3\x7e\xc9\x1b\x72\xc4\xed\x34\xac\x9b\x6e\xa6\x4e\xbe\x6b\x29\x9d\x69\xc7\x79\x44\x10\xdf\x03\x8d\xef\x3f\x66\xdd\xc1\x05\x3e\x62\xbf\x6c\xf6\x0d\xb6\x17\xbb\xbe\xa9\x7e\xe2\x02\x3e\x9d\x3b\x98\xb4\x02\xee\xc4\xea\xde\x97\x58\x6c\xe2\x26\x81\xeb\xd0\xe9\x75\xd4\x1e\xca\xbf\x72\x9d\xe1\x43\xf0\xcc\x92\xc6\xae\x0f\x99\x28\x3d\x20\x18\x7a\x28\xc4\xb2\x25\xc7\xf2\xaa\x7f\x44\xeb\x8c\xbd\xd6\x95\x69\x2e\x0c\x8c\xd5\x5c\xee\x4b\xf7\x98\x35\x36\x8f\x78\x6d\x26\x56\x9b\x41\x38\x50\x83\xdd\xcc\xc5\x89\xc7\x12\x5b\xe9\xb8\xd7\xd9\xc4\x60\xf0\xe0\xe9\xd7\x50\x59\x93\x63\xd4\x3b\x3e\x03\x6e\xda\x16\x0e\x3e\x0b\x1c\x2f\xdc\x90\xf7\xaf\xe6\x38\xd3\x2b\x74\xd2\x51\xcf\x1b\x1c\x43\xf5\xfe\xe2\x9a\xa3\xeb\xb8\x27\x9e\xc1\x1f\x4e\x7e\x7e\xf8\xea\x3b\xf1\x6a\x6f\xfa\x5d\x96\xa4\x29\x6e\x2a\xce\xd1\xe3\x0c\x26\x57\xcd\xf5\x8a\x81\x79\x33\x02\xbe\xd2\x04\x63\x02\xe3\x31\x77\xb1\x52\x46\xa7\x9a\x63\x39\x39\xd7\x1c\xcb\xf1\x04\x73\x2c\x27\x67\x98\x79\x1a\x4c\xa3\x5e\x49\x97\xc1\x43\x46\x5f\xe7\xf0\x77\xb2\xe6\x02\xd0\x87\xef\xfa\xc9\x0b\xf1\xf9\xe3\x55\x28\x1e\x7d\x53\xbd\x15\x40\xf5\x7b\xff\x01\xc5\x64\xa1\x22\x0d\xb5\xcb\xd5\xfd\xf2\xef\x6a\x77\xdf\xd1\x93\xcc\x22\xbe\x49\x12\xfe\x42\x09\x53\xf2\xc7\x47\xd7\xa6\x4c\x80\xac\x4a\x9f\x5b\x00\x17\x67\x7e\xf3\x7a\x29\x8b\x4b\x00\xb9\x23\x36\x26\x56\x27\x22\x2e\xc9\x17\x39\xa8\x11\xbe\x71\xc2\x1e\x1e\xa7\x27\xb1\x49\xc0\x24\x59\x59\x16\x9b\xe4\x12\x33\x6e\x03\xc8\xd2\xfa\x36\x9e\x64\x4b\x93\xad\x5f\x8e\x73\x63\x65\xf9\x77\xee\x1a\x3e\x2e\x09\x1f\x8b\x0b\x4c\x03\xb8\x28\xc8\x27\xcd\x5b\x7f\x92\x33\x1d\x65\x93\x03\x19\xd6\x34\xbc\x55\xbe\x52\x24\x3f\xa7\xe6\x15\xca\x48\xcd\xab\x3f\x24\x93\x4c\x0f\x15\xa5\xe1\xb2\x76\x52\x72\xaf\xeb\x66\x21\x98\xc7\x82\xe9\x2c\x8c\xa7\x74\x25\x72\xd2\x9a\xfd\xbc\x30\xc5\x7c\x16\x58\x1c\xa8\x61\x0a\x4f\x4e\x93\x5a\x1f\x55\x9e\x18\xd3\xc4\x87\xce\x86\x0b\xd0\xf0\x37\x72\x9d\x16\x8d\xe1\xe7\x61\x32\x25\x26\x6f\xe2\x22\x15\x00\xec\xa8\x01\x3c\x4b\x66\xc3\x9e\xb0\xc1\x9a\x3d\xce\xba\xd2\xb0\x8c\x20\x7c\x9f\xf6\x92\xf0\x18\x3a\x27\xf0\x65\x10\x51\x2e\xae\xbf\xf0\x68\x8d\xa5\x3a\xec\x5b\x0d\xe8\xf2\x9d\x62\x99\x55\xfe\x9b\x4d\xc6\x94\x28\xde\xdc\xba\x40\xce\xc9\x38\x8b\x36\x2f\xde\xdc\x62\x94\x6f\x36\xcf\xb1\x06\x59\xaf\x33\xfe\x15\x6c\x83\xbe\x81\xe1\x07\x38\x85\x82\x30\xd6\x03\x17\x22\x79\xd0\x29\x77\x00\xf2\x81\xfc\xfd\xa7\x1f\xd1\xbf\xd7\x9c\x61\xc9\x87\xcf\x89\xfb\xc1\xbe\xe3\xf2\x4a\xe8\x44\x0f\xaf\xc5\x0b\x64\xcf\x82\x82\x84\x72\xf7\x43\x5d\x0f\xba\x21\x8a\xcd\x6a\x24\xad\xd7\x6b\x5f\x66\x8c\xd5\x39\x31\xd0\x6d\x26\x15\xc6\xf4\xc2\x5e\xf6\xb2\x69\xdd\xc9\x92\xec\xf3\xcf\xa9\xf9\xea\x2a\x87\xcf\x86\x6c\x64\x80\x15\x03\x28\x3b\x60\xbd\x30\x56\x57\x7b\x9f\x85\x21\x8f\xa3\x9a\x61\xb1\xe9\x2c\xb9\x34\xa0\x6d\xe6\x05\xe6\x6e\xe5\x66\xa9\xcb\xf2\x04\x33\x05\xa6\x79\x10\x21\x35\xd0\xb9\xef\x29\xff\xef\x77\x94\xb0\xee\xcb\x97\x64\x82\xc1\x33\x75\xff\x17\x19\x8b\x8b\xab\x98\xbe\xfe\x24\x59\xf9\x2a\x21\x65\xe9\x96\x97\x25\x49\x36\x59\xf9\x6a\xe3\xfa\xe9\x3f\x26\x93\x5d\xcf\xfd\x63\x01\xb9\xfe\x2f\x00\x00\xff\xff\xe6\x74\x28\x8b\xad\x1a\x00\x00"
 
 func runtimePluginsLinterLinterLuaBytes() ([]byte, error) {
@@ -1132,6 +1217,26 @@ func runtimePluginsLiterateReadmeMd() (*asset, error) {
        return a, nil
 }
 
+var _runtimePluginsLiterateInfoJson = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x8e\xb1\x4e\xc5\x30\x0c\x45\x67\xfa\x15\x56\xe6\xa7\xf6\xc1\xf8\x24\x98\x19\xf8\x03\xc4\xe0\xb6\x26\xb1\x94\xc4\xc1\x71\x40\x80\xf8\x77\xd4\x40\xe6\xb7\x9e\xeb\x7b\x8f\xbf\x27\x00\x00\x97\x31\x91\xbb\x80\x8b\x9c\x8d\xd4\x9d\xfe\xe8\x4e\x75\x53\x2e\xc6\x92\x8f\xf0\x91\x7d\x88\xec\x83\x71\xf6\x80\x79\x87\x88\xd9\x37\xf4\x04\xb5\x95\x22\x6a\xf0\x2a\x0a\x16\x08\x9e\xd8\x48\xd1\x08\x8a\x8a\x57\x4c\xe9\x68\x98\x48\x9c\xc7\xf4\x07\xad\x95\xad\x3b\x83\x59\xa9\x97\x65\xf1\x6c\xa1\xad\xf3\x26\x69\xf9\xfa\xa4\x9d\x77\xc6\x65\x0c\xb9\xd3\x74\xe3\x38\x57\xc3\x18\xaf\x75\x12\x6f\x2a\xc3\xf3\x4e\x5a\xff\xdf\xbf\x9d\xcf\xf3\x79\x70\xa5\xb7\xc6\x7a\xf8\x9f\x3b\xe8\xb0\x37\xe1\xe1\x1e\xee\xfa\x69\x0f\x5e\xa6\x9f\xe9\x37\x00\x00\xff\xff\x4e\x6f\x8e\x85\x25\x01\x00\x00"
+
+func runtimePluginsLiterateInfoJsonBytes() ([]byte, error) {
+       return bindataRead(
+               _runtimePluginsLiterateInfoJson,
+               "runtime/plugins/literate/info.json",
+       )
+}
+
+func runtimePluginsLiterateInfoJson() (*asset, error) {
+       bytes, err := runtimePluginsLiterateInfoJsonBytes()
+       if err != nil {
+               return nil, err
+       }
+
+       info := bindataFileInfo{name: "runtime/plugins/literate/info.json", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
+       a := &asset{bytes: bytes, info: info}
+       return a, nil
+}
+
 var _runtimePluginsLiterateLiterateLua = "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x55\x4d\x8f\xe2\x38\x10\xbd\xf3\x2b\x4a\xde\x5d\x75\xb2\x9d\x64\xc5\x1e\x91\x22\x65\xf7\xd0\xa7\xfd\x12\xbd\x73\x02\x1a\x99\xb8\x02\x16\x8e\x1d\xd9\x95\x61\x50\xd3\xff\x7d\xe4\x38\x84\x34\x6a\x69\xa0\x73\x89\xab\xfc\xea\xbd\x2a\x97\x3f\x94\x29\xb9\x82\xd2\xe8\x4a\x6e\x21\x07\x59\x37\xc6\x52\xc4\x6a\x59\x5a\xf3\x5b\x70\xb3\x78\x32\xa9\x5a\x5d\x92\x34\x1a\x1c\x71\x4b\xee\x20\x69\x17\x39\xb2\x49\xb0\xe3\x09\x00\x58\xa4\xd6\x7a\x80\x95\x7a\x9b\xb9\x76\xd3\x01\xa6\x49\xef\x50\xa8\xa3\x00\x8e\xf3\xbc\x1b\x4c\x50\x8b\x11\x33\x6a\x31\xe2\x45\x2d\x9e\xc9\x8e\x89\x83\x27\xcf\x1f\x1e\xc0\xd8\x6b\x99\x74\xa4\xd2\x87\xc6\x79\x1e\x46\x57\x3a\xae\x51\x92\xa2\x80\x4f\xc0\x61\xd3\x89\x40\x58\x08\x87\x4d\x02\x95\x44\x25\x1c\xe4\xde\xf2\x5a\x6c\xc6\x12\x78\x7d\x1b\xc1\x1a\x4e\x84\x56\x7b\x48\xd0\xad\x8c\xad\x39\x45\x2c\x5a\xbc\xfc\xe2\x56\x8f\x31\x1b\x31\x07\xc8\x6c\xeb\x73\xed\x03\x13\x38\xa7\x13\x95\x71\xaf\xb7\xf8\x29\xfc\x1f\xa7\x2b\xc8\xa1\xf4\xf5\x86\xf8\xbe\xfe\x30\x7b\x55\x8c\xd1\x7f\xb6\x55\x85\xf6\xdf\x06\x75\xb4\x69\xab\x10\x21\x2b\xd0\x86\x2e\x2b\xba\x69\xab\xec\x3f\x4e\xbb\x04\x58\xa6\x24\xb1\x18\x68\x87\xba\x83\x5e\x04\x3a\xb3\x63\xbf\xd4\x59\x1a\x81\x74\x6c\x10\x72\x60\xad\xde\x6b\x73\xd0\xac\x9b\xae\x8c\x05\x99\x4f\x93\x4d\x5b\xcd\xfe\x92\x1a\xdd\x3f\x6d\x1d\xc5\x20\xcc\x40\x1a\x08\x94\xd4\x3e\xf8\x0c\x8b\x64\x3a\x8d\x07\x88\xac\xc6\xdb\xc9\x43\x13\x60\x85\xd7\x5c\x7b\xd1\xeb\x34\xfd\x37\x4a\x28\xf4\xb1\x8f\x02\x16\x2f\x7e\x5f\xbd\x83\x6e\x2c\xf2\xfd\xe0\xf1\x85\x7d\x50\xa0\x3b\x6a\xe2\xdf\x9e\xa4\xea\x4a\x0c\xb5\xbd\xf3\x8d\x8c\x2c\x03\x56\x49\xd5\xe9\xcf\x40\x49\x42\xcb\x09\x53\xe6\x27\x86\xbc\x3c\x68\xa9\x7f\x4c\x24\x90\xb0\xa4\xd9\x2d\xd0\x6e\xbd\xa5\x42\xcd\x6b\x9c\xc1\x92\x2d\x97\xcb\xa5\x6f\xe3\xcf\xcb\x9b\x94\x6c\xab\xd0\xdd\x2c\x94\x82\xd4\xa5\x6a\x45\xa7\x54\x73\xbb\x17\xe6\xa0\x6f\x13\x0a\xe1\xae\xc1\x52\x72\xe5\xc3\x5f\xa2\xc2\x9d\x0a\x92\xa4\xf0\x74\x69\xab\x1f\xd6\x35\x6a\xea\xad\x5e\xef\x54\x94\x3b\xae\xb7\xc3\x7f\xed\xf7\xff\x27\x85\xa3\x82\x0b\xb1\x2e\x9d\x3b\x15\xe6\x2b\xda\x83\x95\x84\xc1\x2c\x8d\x32\xd6\x95\x3b\xac\x43\x1e\x8d\x54\x68\x4f\x05\x5a\x6b\xec\x3a\x1c\xe2\x53\xb1\x31\x66\x7f\x97\xb4\xc0\x8a\xb7\xea\xf6\x6e\x86\x5b\x81\x5b\xf2\xc9\xa6\x69\x9a\xfd\x7a\x63\x2f\x47\xbb\xb9\x0f\xbd\x33\x50\xc9\x5a\x52\xba\xb5\xa6\x6d\x3c\x81\x14\xa8\x49\x56\x12\xed\x7d\x34\xf7\xed\xa9\xf3\x77\xe9\xd1\xbd\x91\xef\x16\xac\xf0\x07\xe0\xf5\xbe\x84\xaf\x16\xce\x33\xbc\x7d\x8e\x21\x94\x0e\x8b\xd5\xfd\xd5\x0f\x27\xeb\xe3\x2b\x63\x12\x2e\x38\xff\xe4\x66\x7f\x08\x31\x6f\x35\xc9\x1a\x3d\xd7\x93\x35\xf5\xdf\x58\x1b\x7b\x8c\xd8\xf9\xde\x61\xc9\x19\x3b\xff\xff\xb9\x53\x4d\x60\x98\xcc\x8e\xbc\x56\xfe\x0d\x1a\xd2\x89\xc7\xec\x73\x54\x86\x8b\x28\xf8\xfc\xdd\xfc\xa5\x11\x9c\x70\xee\x4b\x8b\xe2\xee\x89\xf9\x1e\x00\x00\xff\xff\x27\x3a\xf6\x67\x18\x08\x00\x00"
 
 func runtimePluginsLiterateLiterateLuaBytes() ([]byte, error) {
@@ -3625,10 +3730,15 @@ var _bindata = map[string]func() (*asset, error){
        "runtime/help/plugins.md":                                 runtimeHelpPluginsMd,
        "runtime/help/tutorial.md":                                runtimeHelpTutorialMd,
        "runtime/plugins/autoclose/autoclose.lua":                 runtimePluginsAutocloseAutocloseLua,
+       "runtime/plugins/autoclose/info.json":                     runtimePluginsAutocloseInfoJson,
        "runtime/plugins/comment/comment.lua":                     runtimePluginsCommentCommentLua,
+       "runtime/plugins/comment/info.json":                       runtimePluginsCommentInfoJson,
        "runtime/plugins/ftoptions/ftoptions.lua":                 runtimePluginsFtoptionsFtoptionsLua,
+       "runtime/plugins/ftoptions/info.json":                     runtimePluginsFtoptionsInfoJson,
+       "runtime/plugins/linter/info.json":                        runtimePluginsLinterInfoJson,
        "runtime/plugins/linter/linter.lua":                       runtimePluginsLinterLinterLua,
        "runtime/plugins/literate/README.md":                      runtimePluginsLiterateReadmeMd,
+       "runtime/plugins/literate/info.json":                      runtimePluginsLiterateInfoJson,
        "runtime/plugins/literate/literate.lua":                   runtimePluginsLiterateLiterateLua,
        "runtime/syntax/LICENSE":                                  runtimeSyntaxLicense,
        "runtime/syntax/PowerShell.yaml":                          runtimeSyntaxPowershellYaml,
@@ -3842,18 +3952,23 @@ var _bintree = &bintree{nil, map[string]*bintree{
                "plugins": &bintree{nil, map[string]*bintree{
                        "autoclose": &bintree{nil, map[string]*bintree{
                                "autoclose.lua": &bintree{runtimePluginsAutocloseAutocloseLua, map[string]*bintree{}},
+                               "info.json":     &bintree{runtimePluginsAutocloseInfoJson, map[string]*bintree{}},
                        }},
                        "comment": &bintree{nil, map[string]*bintree{
                                "comment.lua": &bintree{runtimePluginsCommentCommentLua, map[string]*bintree{}},
+                               "info.json":   &bintree{runtimePluginsCommentInfoJson, map[string]*bintree{}},
                        }},
                        "ftoptions": &bintree{nil, map[string]*bintree{
                                "ftoptions.lua": &bintree{runtimePluginsFtoptionsFtoptionsLua, map[string]*bintree{}},
+                               "info.json":     &bintree{runtimePluginsFtoptionsInfoJson, map[string]*bintree{}},
                        }},
                        "linter": &bintree{nil, map[string]*bintree{
+                               "info.json":  &bintree{runtimePluginsLinterInfoJson, map[string]*bintree{}},
                                "linter.lua": &bintree{runtimePluginsLinterLinterLua, map[string]*bintree{}},
                        }},
                        "literate": &bintree{nil, map[string]*bintree{
                                "README.md":    &bintree{runtimePluginsLiterateReadmeMd, map[string]*bintree{}},
+                               "info.json":    &bintree{runtimePluginsLiterateInfoJson, map[string]*bintree{}},
                                "literate.lua": &bintree{runtimePluginsLiterateLiterateLua, map[string]*bintree{}},
                        }},
                }},
diff --git a/runtime/plugins/autoclose/info.json b/runtime/plugins/autoclose/info.json
new file mode 100644 (file)
index 0000000..ddcd926
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "name": "linter",
+    "description": "Automatically places closing characters for quotes, parentheses, brackets, etc...",
+    "website": "https://github.com/zyedidia/micro",
+       "install": "https://github.com/zyedidia/micro",
+    "version": "1.0.0",
+    "require": [
+        "micro >= 2.0.0"
+    ]
+}
diff --git a/runtime/plugins/comment/info.json b/runtime/plugins/comment/info.json
new file mode 100644 (file)
index 0000000..ec79adf
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "name": "comment",
+    "description": "Support for automatically commenting blocks of code. Extensible and multiple languages supported.",
+    "website": "https://github.com/zyedidia/micro",
+       "install": "https://github.com/zyedidia/micro",
+    "version": "1.0.0",
+    "require": [
+        "micro >= 2.0.0"
+    ]
+}
diff --git a/runtime/plugins/ftoptions/info.json b/runtime/plugins/ftoptions/info.json
new file mode 100644 (file)
index 0000000..8419cc1
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "name": "ftoptions",
+    "description": "Sets basic options based on the filetype (for example Makefiles require tabs).",
+    "website": "https://github.com/zyedidia/micro",
+       "install": "https://github.com/zyedidia/micro",
+    "version": "1.0.0",
+    "require": [
+        "micro >= 2.0.0"
+    ]
+}
diff --git a/runtime/plugins/linter/info.json b/runtime/plugins/linter/info.json
new file mode 100644 (file)
index 0000000..3756739
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "name": "linter",
+    "description": "Automatic code linting for a variety of languages.",
+    "website": "https://github.com/zyedidia/micro",
+       "install": "https://github.com/zyedidia/micro",
+    "version": "1.0.0",
+    "require": [
+        "micro >= 2.0.0"
+    ]
+}
diff --git a/runtime/plugins/literate/info.json b/runtime/plugins/literate/info.json
new file mode 100644 (file)
index 0000000..fa13392
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "name": "linter",
+    "description": "Highlighting and language support for the Literate programming tool.",
+    "website": "https://github.com/zyedidia/Literate",
+       "install": "https://github.com/zyedidia/micro",
+    "version": "1.0.0",
+    "require": [
+        "micro >= 2.0.0"
+    ]
+}