syntax "Go" "\.go$"
-color identifier "[A-Za-z_][A-Za-z0-9_]*[[:space:]]*[()]"
color statement "\b(append|cap|close|complex|copy|delete|imag|len)\b"
color statement "\b(make|new|panic|print|println|protect|real|recover)\b"
color type "\b(u?int(8|16|32|64)?|float(32|64)|complex(64|128))\b"
TermMessage("Error finding your home directory\nCan't load runtime files")
return
}
- LoadColorscheme(options["colorscheme"].(string), dir+"/.micro/colorschemes")
+ LoadColorscheme(settings.Colorscheme, dir+"/.micro/colorschemes")
}
// LoadColorscheme loads the given colorscheme from a directory
// GetCharPosInLine gets the char position of a visual x y coordinate (this is necessary because tabs are 1 char but 4 visual spaces)
func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int {
// Get the tab size
- tabSize := options["tabsize"].(int)
+ tabSize := settings.TabSize
// This is the visual line -- every \t replaced with the correct number of spaces
visualLine := strings.Replace(c.v.buf.lines[lineNum], "\t", "\t"+Spaces(tabSize-1), -1)
if visualPos > Count(visualLine) {
// GetVisualX returns the x value of the cursor in visual spaces
func (c *Cursor) GetVisualX() int {
runes := []rune(c.v.buf.lines[c.y])
- tabSize := options["tabsize"].(int)
+ tabSize := settings.TabSize
return c.x + NumOccurences(string(runes[:c.x]), '\t')*(tabSize-1)
}
// LoadSyntaxFiles loads the syntax files from the default directory ~/.micro
func LoadSyntaxFiles() {
- dir, err := homedir.Dir()
+ home, err := homedir.Dir()
if err != nil {
- TermMessage("Error finding your home directory\nCan't load runtime files")
+ TermMessage("Error finding your home directory\nCan't load syntax files")
return
}
- LoadSyntaxFilesFromDir(dir + "/.micro/syntax")
+ LoadSyntaxFilesFromDir(home + "/.micro/syntax")
}
// JoinRule takes a syntax rule (which can be multiple regular expressions)
os.Exit(1)
}
- InitOptions()
+ InitSettings()
// Should we enable true color?
truecolor := os.Getenv("MICRO_TRUECOLOR") == "1"
+++ /dev/null
-package main
-
-import (
- "strconv"
- "strings"
-)
-
-// The options that the user can set
-var options map[string]interface{}
-
-// InitOptions initializes the options map and sets all options to their default values
-func InitOptions() {
- options = make(map[string]interface{})
- options["tabsize"] = 4
- options["colorscheme"] = "default"
-}
-
-// SetOption prompts the user to set an option and checks that the response is valid
-func SetOption(view *View) {
- choice, canceled := messenger.Prompt("Option: ")
- if !canceled {
- split := strings.Split(choice, "=")
- if len(split) == 2 {
- option := strings.TrimSpace(split[0])
- value := strings.TrimSpace(split[1])
- if _, exists := options[option]; exists {
- if option == "tabsize" {
- tsize, err := strconv.Atoi(value)
- if err != nil {
- messenger.Error("Invalid value for " + option)
- return
- }
- options[option] = tsize
- }
- if option == "colorscheme" {
- options[option] = value
- LoadSyntaxFiles()
- view.buf.UpdateRules()
- }
- } else {
- messenger.Error("Option " + option + " does not exist")
- }
- } else {
- messenger.Error("Invalid option, please use option = value")
- }
- }
-}
--- /dev/null
+package main
+
+import (
+ "encoding/json"
+ "github.com/mitchellh/go-homedir"
+ "io/ioutil"
+ "os"
+ "strconv"
+ "strings"
+)
+
+// The options that the user can set
+var settings Settings
+
+// All the possible settings
+var possibleSettings = []string{"colorscheme", "tabsize", "autoindent"}
+
+// The Settings struct contains the settings for micro
+type Settings struct {
+ Colorscheme string `json:"colorscheme"`
+ TabSize int `json:"tabsize"`
+ AutoIndent bool `json:"autoindent"`
+}
+
+// InitSettings initializes the options map and sets all options to their default values
+func InitSettings() {
+ home, err := homedir.Dir()
+ if err != nil {
+ TermMessage("Error finding your home directory\nCan't load settings file")
+ return
+ }
+
+ filename := home + "/.micro/settings.json"
+ if _, e := os.Stat(filename); e == nil {
+ input, err := ioutil.ReadFile(filename)
+ if err != nil {
+ TermMessage("Error reading settings.json file: " + err.Error())
+ return
+ }
+
+ json.Unmarshal(input, &settings)
+ } else {
+ settings = DefaultSettings()
+ err := WriteSettings(filename)
+ if err != nil {
+ TermMessage("Error writing settings.json file: " + err.Error())
+ }
+ }
+}
+
+// WriteSettings writes the settings to the specified filename as JSON
+func WriteSettings(filename string) error {
+ txt, _ := json.MarshalIndent(settings, "", " ")
+ err := ioutil.WriteFile(filename, txt, 0644)
+ return err
+}
+
+// DefaultSettings returns the default settings for micro
+func DefaultSettings() Settings {
+ return Settings{
+ Colorscheme: "default",
+ TabSize: 4,
+ AutoIndent: true,
+ }
+}
+
+// SetOption prompts the user to set an option and checks that the response is valid
+func SetOption(view *View) {
+ choice, canceled := messenger.Prompt("Option: ")
+
+ home, err := homedir.Dir()
+ if err != nil {
+ messenger.Error("Error finding your home directory\nCan't load settings file")
+ return
+ }
+
+ filename := home + "/.micro/settings.json"
+
+ if !canceled {
+ split := strings.Split(choice, " ")
+ if len(split) == 2 {
+ option := strings.TrimSpace(split[0])
+ value := strings.TrimSpace(split[1])
+
+ if Contains(possibleSettings, option) {
+ if option == "tabsize" {
+ tsize, err := strconv.Atoi(value)
+ if err != nil {
+ messenger.Error("Invalid value for " + option)
+ return
+ }
+ settings.TabSize = tsize
+ } else if option == "colorscheme" {
+ settings.Colorscheme = value
+ LoadSyntaxFiles()
+ view.buf.UpdateRules()
+ }
+ err := WriteSettings(filename)
+ if err != nil {
+ messenger.Error("Error writing to settings.json: " + err.Error())
+ return
+ }
+ } else {
+ messenger.Error("Option " + option + " does not exist")
+ }
+ } else {
+ messenger.Error("Invalid option, please use option value")
+ }
+ }
+}
c := str[0]
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_')
}
+
+// Contains returns whether or not a string array contains a given string
+func Contains(list []string, a string) bool {
+ for _, b := range list {
+ if b == a {
+ return true
+ }
+ }
+ return false
+}
if ch == '\t' {
screen.SetContent(x+tabchars, lineN, ' ', nil, lineStyle)
- tabSize := options["tabsize"].(int)
+ tabSize := settings.TabSize
for i := 0; i < tabSize-1; i++ {
tabchars++
screen.SetContent(x+tabchars, lineN, ' ', nil, lineStyle)