]> git.lizzy.rs Git - micro.git/blob - cmd/micro/rtfiles.go
change pluginmanager json to json5
[micro.git] / cmd / micro / rtfiles.go
1 package main
2
3 import (
4         "io/ioutil"
5         "os"
6         "path"
7         "path/filepath"
8 )
9
10 const (
11         RTColorscheme = "colorscheme"
12         RTSyntax      = "syntax"
13         RTHelp        = "help"
14         RTPlugin      = "plugin"
15 )
16
17 // RuntimeFile allows the program to read runtime data like colorschemes or syntax files
18 type RuntimeFile interface {
19         // Name returns a name of the file without paths or extensions
20         Name() string
21         // Data returns the content of the file.
22         Data() ([]byte, error)
23 }
24
25 // allFiles contains all available files, mapped by filetype
26 var allFiles map[string][]RuntimeFile
27
28 // some file on filesystem
29 type realFile string
30
31 // some asset file
32 type assetFile string
33
34 // some file on filesystem but with a different name
35 type namedFile struct {
36         realFile
37         name string
38 }
39
40 func (rf realFile) Name() string {
41         fn := filepath.Base(string(rf))
42         return fn[:len(fn)-len(filepath.Ext(fn))]
43 }
44
45 func (rf realFile) Data() ([]byte, error) {
46         return ioutil.ReadFile(string(rf))
47 }
48
49 func (af assetFile) Name() string {
50         fn := path.Base(string(af))
51         return fn[:len(fn)-len(path.Ext(fn))]
52 }
53
54 func (af assetFile) Data() ([]byte, error) {
55         return Asset(string(af))
56 }
57
58 func (nf namedFile) Name() string {
59         return nf.name
60 }
61
62 // AddRuntimeFile registers a file for the given filetype
63 func AddRuntimeFile(fileType string, file RuntimeFile) {
64         if allFiles == nil {
65                 allFiles = make(map[string][]RuntimeFile)
66         }
67         allFiles[fileType] = append(allFiles[fileType], file)
68 }
69
70 // AddRuntimeFilesFromDirectory registers each file from the given directory for
71 // the filetype which matches the file-pattern
72 func AddRuntimeFilesFromDirectory(fileType, directory, pattern string) {
73         files, _ := ioutil.ReadDir(directory)
74         for _, f := range files {
75                 if ok, _ := filepath.Match(pattern, f.Name()); !f.IsDir() && ok {
76                         fullPath := filepath.Join(directory, f.Name())
77                         AddRuntimeFile(fileType, realFile(fullPath))
78                 }
79         }
80 }
81
82 // AddRuntimeFilesFromAssets registers each file from the given asset-directory for
83 // the filetype which matches the file-pattern
84 func AddRuntimeFilesFromAssets(fileType, directory, pattern string) {
85         files, err := AssetDir(directory)
86         if err != nil {
87                 return
88         }
89         for _, f := range files {
90                 if ok, _ := path.Match(pattern, f); ok {
91                         AddRuntimeFile(fileType, assetFile(path.Join(directory, f)))
92                 }
93         }
94 }
95
96 // FindRuntimeFile finds a runtime file of the given filetype and name
97 // will return nil if no file was found
98 func FindRuntimeFile(fileType, name string) RuntimeFile {
99         for _, f := range ListRuntimeFiles(fileType) {
100                 if f.Name() == name {
101                         return f
102                 }
103         }
104         return nil
105 }
106
107 // ListRuntimeFiles lists all known runtime files for the given filetype
108 func ListRuntimeFiles(fileType string) []RuntimeFile {
109         if files, ok := allFiles[fileType]; ok {
110                 return files
111         }
112         return []RuntimeFile{}
113 }
114
115 // InitRuntimeFiles initializes all assets file and the config directory
116 func InitRuntimeFiles() {
117         add := func(fileType, dir, pattern string) {
118                 AddRuntimeFilesFromDirectory(fileType, filepath.Join(configDir, dir), pattern)
119                 AddRuntimeFilesFromAssets(fileType, path.Join("runtime", dir), pattern)
120         }
121
122         add(RTColorscheme, "colorschemes", "*.micro")
123         add(RTSyntax, "syntax", "*.micro")
124         add(RTHelp, "help", "*.md")
125
126         // Search configDir for plugin-scripts
127         files, _ := ioutil.ReadDir(filepath.Join(configDir, "plugins"))
128         for _, f := range files {
129                 if f.IsDir() {
130                         scriptPath := filepath.Join(configDir, "plugins", f.Name(), f.Name()+".lua")
131                         if _, err := os.Stat(scriptPath); err == nil {
132                                 AddRuntimeFile(RTPlugin, realFile(scriptPath))
133                         }
134                 }
135         }
136
137         if files, err := AssetDir("runtime/plugins"); err == nil {
138                 for _, f := range files {
139                         scriptPath := path.Join("runtime/plugins", f, f+".lua")
140                         if _, err := AssetInfo(scriptPath); err == nil {
141                                 AddRuntimeFile(RTPlugin, assetFile(scriptPath))
142                         }
143                 }
144         }
145 }
146
147 // PluginReadRuntimeFile allows plugin scripts to read the content of a runtime file
148 func PluginReadRuntimeFile(fileType, name string) string {
149         if file := FindRuntimeFile(fileType, name); file != nil {
150                 if data, err := file.Data(); err == nil {
151                         return string(data)
152                 }
153         }
154         return ""
155 }
156
157 // PluginListRuntimeFiles allows plugins to lists all runtime files of the given type
158 func PluginListRuntimeFiles(fileType string) []string {
159         files := ListRuntimeFiles(fileType)
160         result := make([]string, len(files))
161         for i, f := range files {
162                 result[i] = f.Name()
163         }
164         return result
165 }
166
167 // PluginAddRuntimeFile adds a file to the runtime files for a plugin
168 func PluginAddRuntimeFile(plugin, filetype, filePath string) {
169         fullpath := filepath.Join(configDir, "plugins", plugin, filePath)
170         if _, err := os.Stat(fullpath); err == nil {
171                 AddRuntimeFile(filetype, realFile(fullpath))
172         } else {
173                 fullpath = path.Join("runtime", "plugins", plugin, filePath)
174                 AddRuntimeFile(filetype, assetFile(fullpath))
175         }
176 }
177
178 // PluginAddRuntimeFilesFromDirectory adds files from a directory to the runtime files for a plugin
179 func PluginAddRuntimeFilesFromDirectory(plugin, filetype, directory, pattern string) {
180         fullpath := filepath.Join(configDir, "plugins", plugin, directory)
181         if _, err := os.Stat(fullpath); err == nil {
182                 AddRuntimeFilesFromDirectory(filetype, fullpath, pattern)
183         } else {
184                 fullpath = path.Join("runtime", "plugins", plugin, directory)
185                 AddRuntimeFilesFromAssets(filetype, fullpath, pattern)
186         }
187 }