package config
import (
+ "errors"
"io/ioutil"
+ "log"
"os"
"path"
"path/filepath"
+ "regexp"
"strings"
)
const (
- RTColorscheme = 0
- RTSyntax = 1
- RTHelp = 2
- RTPlugin = 3
- NumTypes = 4 // How many filetypes are there
+ RTColorscheme = 0
+ RTSyntax = 1
+ RTHelp = 2
+ RTPlugin = 3
+ RTSyntaxHeader = 4
)
-type RTFiletype byte
+var (
+ NumTypes = 5 // How many filetypes are there
+)
+
+type RTFiletype int
// RuntimeFile allows the program to read runtime data like colorschemes or syntax files
type RuntimeFile interface {
}
// allFiles contains all available files, mapped by filetype
-var allFiles [NumTypes][]RuntimeFile
+var allFiles [][]RuntimeFile
+var realFiles [][]RuntimeFile
+
+func init() {
+ allFiles = make([][]RuntimeFile, NumTypes)
+ realFiles = make([][]RuntimeFile, NumTypes)
+}
+
+// NewRTFiletype creates a new RTFiletype
+func NewRTFiletype() int {
+ NumTypes++
+ allFiles = append(allFiles, []RuntimeFile{})
+ realFiles = append(realFiles, []RuntimeFile{})
+ return NumTypes - 1
+}
// some file on filesystem
type realFile string
allFiles[fileType] = append(allFiles[fileType], file)
}
+// AddRealRuntimeFile registers a file for the given filetype
+func AddRealRuntimeFile(fileType RTFiletype, file RuntimeFile) {
+ allFiles[fileType] = append(allFiles[fileType], file)
+ realFiles[fileType] = append(realFiles[fileType], file)
+}
+
// AddRuntimeFilesFromDirectory registers each file from the given directory for
// the filetype which matches the file-pattern
func AddRuntimeFilesFromDirectory(fileType RTFiletype, directory, pattern string) {
for _, f := range files {
if ok, _ := filepath.Match(pattern, f.Name()); !f.IsDir() && ok {
fullPath := filepath.Join(directory, f.Name())
- AddRuntimeFile(fileType, realFile(fullPath))
+ AddRealRuntimeFile(fileType, realFile(fullPath))
}
}
}
return allFiles[fileType]
}
+// ListRealRuntimeFiles lists all real runtime files (on disk) for a filetype
+// these runtime files will be ones defined by the user and loaded from the config directory
+func ListRealRuntimeFiles(fileType RTFiletype) []RuntimeFile {
+ return realFiles[fileType]
+}
+
// InitRuntimeFiles initializes all assets file and the config directory
func InitRuntimeFiles() {
add := func(fileType RTFiletype, dir, pattern string) {
add(RTColorscheme, "colorschemes", "*.micro")
add(RTSyntax, "syntax", "*.yaml")
+ add(RTSyntaxHeader, "syntax", "*.hdr")
add(RTHelp, "help", "*.md")
+ initlua := filepath.Join(ConfigDir, "init.lua")
+ if _, err := os.Stat(initlua); !os.IsNotExist(err) {
+ p := new(Plugin)
+ p.Name = "initlua"
+ p.DirName = "initlua"
+ p.Srcs = append(p.Srcs, realFile(initlua))
+ Plugins = append(Plugins, p)
+ }
+
// Search ConfigDir for plugin-scripts
- plugdir := filepath.Join(ConfigDir, "plugins")
+ plugdir := filepath.Join(ConfigDir, "plug")
files, _ := ioutil.ReadDir(plugdir)
+
+ isID := regexp.MustCompile(`^[_A-Za-z0-9]+$`).MatchString
+
for _, d := range files {
if d.IsDir() {
srcs, _ := ioutil.ReadDir(filepath.Join(plugdir, d.Name()))
p := new(Plugin)
p.Name = d.Name()
+ p.DirName = 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"))
+ } else if strings.HasSuffix(f.Name(), ".json") {
+ data, err := ioutil.ReadFile(filepath.Join(plugdir, d.Name(), f.Name()))
+ if err != nil {
+ continue
+ }
+ p.Info, err = NewPluginInfo(data)
+ if err != nil {
+ log.Println(err)
+ continue
+ }
+ p.Name = p.Info.Name
}
}
+
+ if !isID(p.Name) || len(p.Srcs) <= 0 {
+ log.Println(p.Name, "is not a plugin")
+ continue
+ }
Plugins = append(Plugins, p)
}
}
if srcs, err := AssetDir(filepath.Join(plugdir, d)); err == nil {
p := new(Plugin)
p.Name = d
+ p.DirName = 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"))
+ } else if strings.HasSuffix(f, ".json") {
+ data, err := Asset(filepath.Join(plugdir, d, f))
+ if err != nil {
+ continue
+ }
+ p.Info, err = NewPluginInfo(data)
+ if err != nil {
+ log.Println(err)
+ continue
+ }
+ p.Name = p.Info.Name
}
}
+ if !isID(p.Name) || len(p.Srcs) <= 0 {
+ log.Println(p.Name, "is not a plugin")
+ continue
+ }
Plugins = append(Plugins, p)
}
}
}
// PluginAddRuntimeFile adds a file to the runtime files for a plugin
-func PluginAddRuntimeFile(plugin string, filetype RTFiletype, filePath string) {
- fullpath := filepath.Join(ConfigDir, "plugins", plugin, filePath)
+func PluginAddRuntimeFile(plugin string, filetype RTFiletype, filePath string) error {
+ pl := FindPlugin(plugin)
+ if pl == nil {
+ return errors.New("Plugin " + plugin + " does not exist")
+ }
+ pldir := pl.DirName
+ fullpath := filepath.Join(ConfigDir, "plug", pldir, filePath)
if _, err := os.Stat(fullpath); err == nil {
- AddRuntimeFile(filetype, realFile(fullpath))
+ AddRealRuntimeFile(filetype, realFile(fullpath))
} else {
- fullpath = path.Join("runtime", "plugins", plugin, filePath)
+ fullpath = path.Join("runtime", "plugins", pldir, filePath)
AddRuntimeFile(filetype, assetFile(fullpath))
}
+ return nil
}
// PluginAddRuntimeFilesFromDirectory adds files from a directory to the runtime files for a plugin
-func PluginAddRuntimeFilesFromDirectory(plugin string, filetype RTFiletype, directory, pattern string) {
- fullpath := filepath.Join(ConfigDir, "plugins", plugin, directory)
+func PluginAddRuntimeFilesFromDirectory(plugin string, filetype RTFiletype, directory, pattern string) error {
+ pl := FindPlugin(plugin)
+ if pl == nil {
+ return errors.New("Plugin " + plugin + " does not exist")
+ }
+ pldir := pl.DirName
+ fullpath := filepath.Join(ConfigDir, "plug", pldir, directory)
if _, err := os.Stat(fullpath); err == nil {
AddRuntimeFilesFromDirectory(filetype, fullpath, pattern)
} else {
- fullpath = path.Join("runtime", "plugins", plugin, directory)
+ fullpath = path.Join("runtime", "plugins", pldir, directory)
AddRuntimeFilesFromAssets(filetype, fullpath, pattern)
}
+ return nil
}
// PluginAddRuntimeFileFromMemory adds a file to the runtime files for a plugin from a given string
-func PluginAddRuntimeFileFromMemory(plugin string, filetype RTFiletype, filename, data string) {
- AddRuntimeFile(filetype, memoryFile{filename, []byte(data)})
+func PluginAddRuntimeFileFromMemory(filetype RTFiletype, filename, data string) {
+ AddRealRuntimeFile(filetype, memoryFile{filename, []byte(data)})
}