mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-29 22:27:13 +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) {
|
func HelpComplete(input string) (string, []string) {
|
||||||
var suggestions []string
|
var suggestions []string
|
||||||
|
|
||||||
for _, file := range ListExtensionFiles(FILE_Help) {
|
for _, file := range ListRuntimeFiles(FILE_Help) {
|
||||||
topic := file.Name()
|
topic := file.Name()
|
||||||
if strings.HasPrefix(topic, input) {
|
if strings.HasPrefix(topic, input) {
|
||||||
suggestions = append(suggestions, topic)
|
suggestions = append(suggestions, topic)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ var colorscheme Colorscheme
|
|||||||
|
|
||||||
// ColorschemeExists checks if a given colorscheme exists
|
// ColorschemeExists checks if a given colorscheme exists
|
||||||
func ColorschemeExists(colorschemeName string) bool {
|
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
|
// InitColorscheme picks and initializes the colorscheme when micro starts
|
||||||
@@ -39,7 +39,7 @@ func LoadDefaultColorscheme() {
|
|||||||
|
|
||||||
// LoadColorscheme loads the given colorscheme from a directory
|
// LoadColorscheme loads the given colorscheme from a directory
|
||||||
func LoadColorscheme(colorschemeName string) {
|
func LoadColorscheme(colorschemeName string) {
|
||||||
file := FindExtensionFile(FILE_ColorScheme, colorschemeName)
|
file := FindRuntimeFile(FILE_ColorScheme, colorschemeName)
|
||||||
if file == nil {
|
if file == nil {
|
||||||
TermMessage(colorschemeName, "is not a valid colorscheme")
|
TermMessage(colorschemeName, "is not a valid colorscheme")
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ func Help(args []string) {
|
|||||||
CurView().openHelp("help")
|
CurView().openHelp("help")
|
||||||
} else {
|
} else {
|
||||||
helpPage := args[0]
|
helpPage := args[0]
|
||||||
if FindExtensionFile(FILE_Help, helpPage) != nil {
|
if FindRuntimeFile(FILE_Help, helpPage) != nil {
|
||||||
CurView().openHelp(helpPage)
|
CurView().openHelp(helpPage)
|
||||||
} else {
|
} else {
|
||||||
messenger.Error("Sorry, no help for ", helpPage)
|
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() {
|
func LoadSyntaxFiles() {
|
||||||
InitColorscheme()
|
InitColorscheme()
|
||||||
syntaxFiles = make(map[[2]*regexp.Regexp]FileTypeRules)
|
syntaxFiles = make(map[[2]*regexp.Regexp]FileTypeRules)
|
||||||
for _, f := range ListExtensionFiles(FILE_Syntax) {
|
for _, f := range ListRuntimeFiles(FILE_Syntax) {
|
||||||
data, err := f.Data()
|
data, err := f.Data()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
TermMessage("Error loading syntax file " + f.Name() + ": " + err.Error())
|
TermMessage("Error loading syntax file " + f.Name() + ": " + err.Error())
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ func main() {
|
|||||||
InitConfigDir()
|
InitConfigDir()
|
||||||
|
|
||||||
// Build a list of available Extensions (Syntax, Colorscheme etc.)
|
// Build a list of available Extensions (Syntax, Colorscheme etc.)
|
||||||
InitExtensionFiles()
|
InitRuntimeFiles()
|
||||||
|
|
||||||
// Load the user's settings
|
// Load the user's settings
|
||||||
InitGlobalSettings()
|
InitGlobalSettings()
|
||||||
@@ -316,6 +316,10 @@ func main() {
|
|||||||
L.SetGlobal("JobSend", luar.New(L, JobSend))
|
L.SetGlobal("JobSend", luar.New(L, JobSend))
|
||||||
L.SetGlobal("JobStop", luar.New(L, JobStop))
|
L.SetGlobal("JobStop", luar.New(L, JobStop))
|
||||||
|
|
||||||
|
// Extension Files
|
||||||
|
L.SetGlobal("ReadRuntimeFile", luar.New(L, PluginReadRuntimeFile))
|
||||||
|
L.SetGlobal("ListRuntimeFiles", luar.New(L, PluginListRuntimeFiles))
|
||||||
|
|
||||||
LoadPlugins()
|
LoadPlugins()
|
||||||
|
|
||||||
jobs = make(chan JobFunction, 100)
|
jobs = make(chan JobFunction, 100)
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ func LoadPlugins() {
|
|||||||
}
|
}
|
||||||
loadedPlugins = append(loadedPlugins, pluginName)
|
loadedPlugins = append(loadedPlugins, pluginName)
|
||||||
} else if f.Name() == "help.md" {
|
} 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
|
// Opens the given help page in a new horizontal split
|
||||||
func (v *View) openHelp(helpPage string) {
|
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)
|
TermMessage("Unable to load help text", helpPage, "\n", err)
|
||||||
} else {
|
} else {
|
||||||
helpBuffer := NewBuffer(data, helpPage+".md")
|
helpBuffer := NewBuffer(data, helpPage+".md")
|
||||||
|
|||||||
Reference in New Issue
Block a user