mirror of
https://github.com/zyedidia/micro.git
synced 2026-02-07 23:50:18 +09:00
allow plugins to list / read runtime files
also renamed most of the new functions to be more specific about what kind of files this is for.
This commit is contained in:
@@ -84,7 +84,7 @@ func CommandComplete(input string) (string, []string) {
|
||||
func HelpComplete(input string) (string, []string) {
|
||||
var suggestions []string
|
||||
|
||||
for _, file := range ListExtensionFiles(FILE_Help) {
|
||||
for _, file := range ListRuntimeFiles(FILE_Help) {
|
||||
topic := file.Name()
|
||||
if strings.HasPrefix(topic, input) {
|
||||
suggestions = append(suggestions, topic)
|
||||
|
||||
@@ -17,7 +17,7 @@ var colorscheme Colorscheme
|
||||
|
||||
// ColorschemeExists checks if a given colorscheme exists
|
||||
func ColorschemeExists(colorschemeName string) bool {
|
||||
return FindExtensionFile(FILE_ColorScheme, colorschemeName) != nil
|
||||
return FindRuntimeFile(FILE_ColorScheme, colorschemeName) != nil
|
||||
}
|
||||
|
||||
// InitColorscheme picks and initializes the colorscheme when micro starts
|
||||
@@ -39,7 +39,7 @@ func LoadDefaultColorscheme() {
|
||||
|
||||
// LoadColorscheme loads the given colorscheme from a directory
|
||||
func LoadColorscheme(colorschemeName string) {
|
||||
file := FindExtensionFile(FILE_ColorScheme, colorschemeName)
|
||||
file := FindRuntimeFile(FILE_ColorScheme, colorschemeName)
|
||||
if file == nil {
|
||||
TermMessage(colorschemeName, "is not a valid colorscheme")
|
||||
} else {
|
||||
|
||||
@@ -94,7 +94,7 @@ func Help(args []string) {
|
||||
CurView().openHelp("help")
|
||||
} else {
|
||||
helpPage := args[0]
|
||||
if FindExtensionFile(FILE_Help, helpPage) != nil {
|
||||
if FindRuntimeFile(FILE_Help, helpPage) != nil {
|
||||
CurView().openHelp(helpPage)
|
||||
} else {
|
||||
messenger.Error("Sorry, no help for ", helpPage)
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const (
|
||||
FILE_ColorScheme = "colorscheme"
|
||||
FILE_Syntax = "syntax"
|
||||
FILE_Help = "help"
|
||||
)
|
||||
|
||||
// ExtensionFile allows the program to read runtime data like colorschemes or syntax files
|
||||
type ExtensionFile interface {
|
||||
// Name returns a name of the file without paths or extensions
|
||||
Name() string
|
||||
// Data returns the content of the file.
|
||||
Data() ([]byte, error)
|
||||
}
|
||||
|
||||
// allFiles contains all available files, mapped by filetype
|
||||
var allFiles map[string][]ExtensionFile
|
||||
|
||||
// some file on filesystem
|
||||
type realFile string
|
||||
|
||||
// some asset file
|
||||
type assetFile string
|
||||
|
||||
// some file on filesystem but with a different name
|
||||
type namedFile struct {
|
||||
realFile
|
||||
name string
|
||||
}
|
||||
|
||||
func (rf realFile) Name() string {
|
||||
fn := filepath.Base(string(rf))
|
||||
return fn[:len(fn)-len(filepath.Ext(fn))]
|
||||
}
|
||||
|
||||
func (rf realFile) Data() ([]byte, error) {
|
||||
return ioutil.ReadFile(string(rf))
|
||||
}
|
||||
|
||||
func (af assetFile) Name() string {
|
||||
fn := path.Base(string(af))
|
||||
return fn[:len(fn)-len(path.Ext(fn))]
|
||||
}
|
||||
|
||||
func (af assetFile) Data() ([]byte, error) {
|
||||
return Asset(string(af))
|
||||
}
|
||||
|
||||
func (nf namedFile) Name() string {
|
||||
return nf.name
|
||||
}
|
||||
|
||||
func AddFile(fileType string, file ExtensionFile) {
|
||||
if allFiles == nil {
|
||||
allFiles = make(map[string][]ExtensionFile)
|
||||
}
|
||||
allFiles[fileType] = append(allFiles[fileType], file)
|
||||
}
|
||||
|
||||
func AddFilesFromDirectory(fileType, directory, pattern string) {
|
||||
files, _ := ioutil.ReadDir(directory)
|
||||
for _, f := range files {
|
||||
if ok, _ := filepath.Match(pattern, f.Name()); !f.IsDir() && ok {
|
||||
fullPath := filepath.Join(directory, f.Name())
|
||||
AddFile(fileType, realFile(fullPath))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func AddFilesFromAssets(fileType, directory, pattern string) {
|
||||
files, err := AssetDir(directory)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, f := range files {
|
||||
if ok, _ := path.Match(pattern, f); ok {
|
||||
AddFile(fileType, assetFile(path.Join(directory, f)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func FindExtensionFile(fileType, name string) ExtensionFile {
|
||||
for _, f := range ListExtensionFiles(fileType) {
|
||||
if f.Name() == name {
|
||||
return f
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ListExtensionFiles(fileType string) []ExtensionFile {
|
||||
if files, ok := allFiles[fileType]; ok {
|
||||
return files
|
||||
} else {
|
||||
return []ExtensionFile{}
|
||||
}
|
||||
}
|
||||
|
||||
func InitExtensionFiles() {
|
||||
add := func(fileType, dir, pattern string) {
|
||||
AddFilesFromDirectory(fileType, filepath.Join(configDir, dir), pattern)
|
||||
AddFilesFromAssets(fileType, path.Join("runtime", dir), pattern)
|
||||
}
|
||||
|
||||
add(FILE_ColorScheme, "colorschemes", "*.micro")
|
||||
add(FILE_Syntax, "syntax", "*.micro")
|
||||
add(FILE_Help, "help", "*.md")
|
||||
}
|
||||
@@ -32,7 +32,7 @@ var syntaxFiles map[[2]*regexp.Regexp]FileTypeRules
|
||||
func LoadSyntaxFiles() {
|
||||
InitColorscheme()
|
||||
syntaxFiles = make(map[[2]*regexp.Regexp]FileTypeRules)
|
||||
for _, f := range ListExtensionFiles(FILE_Syntax) {
|
||||
for _, f := range ListRuntimeFiles(FILE_Syntax) {
|
||||
data, err := f.Data()
|
||||
if err != nil {
|
||||
TermMessage("Error loading syntax file " + f.Name() + ": " + err.Error())
|
||||
|
||||
@@ -234,7 +234,7 @@ func main() {
|
||||
InitConfigDir()
|
||||
|
||||
// Build a list of available Extensions (Syntax, Colorscheme etc.)
|
||||
InitExtensionFiles()
|
||||
InitRuntimeFiles()
|
||||
|
||||
// Load the user's settings
|
||||
InitGlobalSettings()
|
||||
@@ -316,6 +316,10 @@ func main() {
|
||||
L.SetGlobal("JobSend", luar.New(L, JobSend))
|
||||
L.SetGlobal("JobStop", luar.New(L, JobStop))
|
||||
|
||||
// Extension Files
|
||||
L.SetGlobal("ReadRuntimeFile", luar.New(L, PluginReadRuntimeFile))
|
||||
L.SetGlobal("ListRuntimeFiles", luar.New(L, PluginListRuntimeFiles))
|
||||
|
||||
LoadPlugins()
|
||||
|
||||
jobs = make(chan JobFunction, 100)
|
||||
|
||||
@@ -138,7 +138,7 @@ func LoadPlugins() {
|
||||
}
|
||||
loadedPlugins = append(loadedPlugins, pluginName)
|
||||
} else if f.Name() == "help.md" {
|
||||
AddFile(FILE_Help, namedFile{realFile(fullPath), pluginName})
|
||||
AddRuntimeFile(FILE_Help, namedFile{realFile(fullPath), pluginName})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
144
cmd/micro/rtfiles.go
Normal file
144
cmd/micro/rtfiles.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const (
|
||||
FILE_ColorScheme = "colorscheme"
|
||||
FILE_Syntax = "syntax"
|
||||
FILE_Help = "help"
|
||||
)
|
||||
|
||||
// RuntimeFile allows the program to read runtime data like colorschemes or syntax files
|
||||
type RuntimeFile interface {
|
||||
// Name returns a name of the file without paths or extensions
|
||||
Name() string
|
||||
// Data returns the content of the file.
|
||||
Data() ([]byte, error)
|
||||
}
|
||||
|
||||
// allFiles contains all available files, mapped by filetype
|
||||
var allFiles map[string][]RuntimeFile
|
||||
|
||||
// some file on filesystem
|
||||
type realFile string
|
||||
|
||||
// some asset file
|
||||
type assetFile string
|
||||
|
||||
// some file on filesystem but with a different name
|
||||
type namedFile struct {
|
||||
realFile
|
||||
name string
|
||||
}
|
||||
|
||||
func (rf realFile) Name() string {
|
||||
fn := filepath.Base(string(rf))
|
||||
return fn[:len(fn)-len(filepath.Ext(fn))]
|
||||
}
|
||||
|
||||
func (rf realFile) Data() ([]byte, error) {
|
||||
return ioutil.ReadFile(string(rf))
|
||||
}
|
||||
|
||||
func (af assetFile) Name() string {
|
||||
fn := path.Base(string(af))
|
||||
return fn[:len(fn)-len(path.Ext(fn))]
|
||||
}
|
||||
|
||||
func (af assetFile) Data() ([]byte, error) {
|
||||
return Asset(string(af))
|
||||
}
|
||||
|
||||
func (nf namedFile) Name() string {
|
||||
return nf.name
|
||||
}
|
||||
|
||||
// AddRuntimeFile registers a file for the given filetype
|
||||
func AddRuntimeFile(fileType string, file RuntimeFile) {
|
||||
if allFiles == nil {
|
||||
allFiles = make(map[string][]RuntimeFile)
|
||||
}
|
||||
allFiles[fileType] = append(allFiles[fileType], file)
|
||||
}
|
||||
|
||||
// AddRuntimeFilesFromDirectory registers each file from the given directory for
|
||||
// the filetype which matches the file-pattern
|
||||
func AddRuntimeFilesFromDirectory(fileType, directory, pattern string) {
|
||||
files, _ := ioutil.ReadDir(directory)
|
||||
for _, f := range files {
|
||||
if ok, _ := filepath.Match(pattern, f.Name()); !f.IsDir() && ok {
|
||||
fullPath := filepath.Join(directory, f.Name())
|
||||
AddRuntimeFile(fileType, realFile(fullPath))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddRuntimeFilesFromDirectory registers each file from the given asset-directory for
|
||||
// the filetype which matches the file-pattern
|
||||
func AddRuntimeFilesFromAssets(fileType, directory, pattern string) {
|
||||
files, err := AssetDir(directory)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, f := range files {
|
||||
if ok, _ := path.Match(pattern, f); ok {
|
||||
AddRuntimeFile(fileType, assetFile(path.Join(directory, f)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FindRuntimeFile finds a runtime file of the given filetype and name
|
||||
// will return nil if no file was found
|
||||
func FindRuntimeFile(fileType, name string) RuntimeFile {
|
||||
for _, f := range ListRuntimeFiles(fileType) {
|
||||
if f.Name() == name {
|
||||
return f
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Lists all known runtime files for the given filetype
|
||||
func ListRuntimeFiles(fileType string) []RuntimeFile {
|
||||
if files, ok := allFiles[fileType]; ok {
|
||||
return files
|
||||
} else {
|
||||
return []RuntimeFile{}
|
||||
}
|
||||
}
|
||||
|
||||
// Initializes all assets file and the config directory
|
||||
func InitRuntimeFiles() {
|
||||
add := func(fileType, dir, pattern string) {
|
||||
AddRuntimeFilesFromDirectory(fileType, filepath.Join(configDir, dir), pattern)
|
||||
AddRuntimeFilesFromAssets(fileType, path.Join("runtime", dir), pattern)
|
||||
}
|
||||
|
||||
add(FILE_ColorScheme, "colorschemes", "*.micro")
|
||||
add(FILE_Syntax, "syntax", "*.micro")
|
||||
add(FILE_Help, "help", "*.md")
|
||||
}
|
||||
|
||||
// Allows plugin scripts to read the content of a runtime file
|
||||
func PluginReadRuntimeFile(fileType, name string) string {
|
||||
if file := FindRuntimeFile(fileType, name); file != nil {
|
||||
if data, err := file.Data(); err == nil {
|
||||
return string(data)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Allows plugins to lists all runtime files of the given type
|
||||
func PluginListRuntimeFiles(fileType string) []string {
|
||||
files := ListRuntimeFiles(fileType)
|
||||
result := make([]string, len(files))
|
||||
for i, f := range files {
|
||||
result[i] = f.Name()
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -529,7 +529,7 @@ func (v *View) ClearAllGutterMessages() {
|
||||
|
||||
// Opens the given help page in a new horizontal split
|
||||
func (v *View) openHelp(helpPage string) {
|
||||
if data, err := FindExtensionFile(FILE_Help, helpPage).Data(); err != nil {
|
||||
if data, err := FindRuntimeFile(FILE_Help, helpPage).Data(); err != nil {
|
||||
TermMessage("Unable to load help text", helpPage, "\n", err)
|
||||
} else {
|
||||
helpBuffer := NewBuffer(data, helpPage+".md")
|
||||
|
||||
Reference in New Issue
Block a user