"encoding/json"
"io/ioutil"
"os"
+ "reflect"
"strconv"
- "strings"
)
// The options that the user can set
-var settings Settings
-
-// All the possible settings
-var possibleSettings = []string{"colorscheme", "tabsize", "autoindent", "syntax", "tabsToSpaces", "ruler"}
-
-// The Settings struct contains the settings for micro
-type Settings struct {
- Colorscheme string `json:"colorscheme"`
- TabSize int `json:"tabsize"`
- AutoIndent bool `json:"autoindent"`
- Syntax bool `json:"syntax"`
- TabsToSpaces bool `json:"tabsToSpaces"`
- Ruler bool `json:"ruler"`
-}
+var settings map[string]interface{}
// InitSettings initializes the options map and sets all options to their default values
func InitSettings() {
+ defaults := DefaultSettings()
+ var parsed map[string]interface{}
+
filename := configDir + "/settings.json"
if _, e := os.Stat(filename); e == nil {
input, err := ioutil.ReadFile(filename)
return
}
- json.Unmarshal(input, &settings)
- } else {
- settings = DefaultSettings()
- err := WriteSettings(filename)
+ err = json.Unmarshal(input, &parsed)
if err != nil {
- TermMessage("Error writing settings.json file: " + err.Error())
+ TermMessage("Error reading settings.json:", err.Error())
}
}
+
+ settings = make(map[string]interface{})
+ for k, v := range defaults {
+ settings[k] = v
+ }
+ for k, v := range parsed {
+ settings[k] = v
+ }
+
+ err := WriteSettings(filename)
+ if err != nil {
+ TermMessage("Error writing settings.json file: " + err.Error())
+ }
}
// WriteSettings writes the settings to the specified filename as JSON
return err
}
+// AddOption creates a new option. This is meant to be called by plugins to add options.
+func AddOption(name string, value interface{}) {
+ settings[name] = value
+ err := WriteSettings(configDir + "/settings.json")
+ if err != nil {
+ TermMessage("Error writing settings.json file: " + err.Error())
+ }
+}
+
+// GetOption returns the specified option. This is meant to be called by plugins to add options.
+func GetOption(name string) interface{} {
+ return settings[name]
+}
+
// DefaultSettings returns the default settings for micro
-func DefaultSettings() Settings {
- return Settings{
- Colorscheme: "default",
- TabSize: 4,
- AutoIndent: true,
- Syntax: true,
- TabsToSpaces: false,
- Ruler: true,
+func DefaultSettings() map[string]interface{} {
+ return map[string]interface{}{
+ "autoindent": true,
+ "colorscheme": "monokai",
+ "cursorline": false,
+ "ignorecase": false,
+ "indentchar": " ",
+ "ruler": true,
+ "savecursor": false,
+ "saveundo": false,
+ "scrollspeed": float64(2),
+ "scrollmargin": float64(3),
+ "statusline": true,
+ "syntax": true,
+ "tabsize": float64(4),
+ "tabstospaces": false,
}
}
// SetOption prompts the user to set an option and checks that the response is valid
-func SetOption(view *View, args []string) {
+func SetOption(option, value string) {
filename := configDir + "/settings.json"
- if len(args) == 2 {
- option := strings.TrimSpace(args[0])
- value := strings.TrimSpace(args[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()
- } else if option == "syntax" {
- if value == "on" {
- settings.Syntax = true
- } else if value == "off" {
- settings.Syntax = false
- } else {
- messenger.Error("Invalid value for " + option)
- return
- }
- LoadSyntaxFiles()
- view.buf.UpdateRules()
- } else if option == "tabsToSpaces" {
- if value == "on" {
- settings.TabsToSpaces = true
- } else if value == "off" {
- settings.TabsToSpaces = false
- } else {
- messenger.Error("Invalid value for " + option)
- return
- }
- } else if option == "autoindent" {
- if value == "on" {
- settings.AutoIndent = true
- } else if value == "off" {
- settings.AutoIndent = false
- } else {
- messenger.Error("Invalid value for " + option)
- return
- }
- } else if option == "ruler" {
- if value == "on" {
- settings.Ruler = true
- } else if value == "off" {
- settings.Ruler = false
- } else {
- messenger.Error("Invalid value for " + option)
- return
+ if _, ok := settings[option]; !ok {
+ messenger.Error(option + " is not a valid option")
+ return
+ }
+
+ kind := reflect.TypeOf(settings[option]).Kind()
+ if kind == reflect.Bool {
+ b, err := ParseBool(value)
+ if err != nil {
+ messenger.Error("Invalid value for " + option)
+ return
+ }
+ settings[option] = b
+ } else if kind == reflect.String {
+ settings[option] = value
+ } else if kind == reflect.Float64 {
+ i, err := strconv.Atoi(value)
+ if err != nil {
+ messenger.Error("Invalid value for " + option)
+ return
+ }
+ settings[option] = float64(i)
+ }
+
+ if option == "colorscheme" {
+ LoadSyntaxFiles()
+ for _, tab := range tabs {
+ for _, view := range tab.views {
+ view.Buf.UpdateRules()
+ if settings["syntax"].(bool) {
+ view.matches = Match(view)
}
}
+ }
+ }
- err := WriteSettings(filename)
- if err != nil {
- messenger.Error("Error writing to settings.json: " + err.Error())
- return
+ if option == "statusline" {
+ for _, tab := range tabs {
+ for _, view := range tab.views {
+ view.ToggleStatusLine()
+ if settings["syntax"].(bool) {
+ view.matches = Match(view)
+ }
}
- } else {
- messenger.Error("Option " + option + " does not exist")
}
- } else {
- messenger.Error("Invalid option, please use option value")
+ }
+
+ err := WriteSettings(filename)
+ if err != nil {
+ messenger.Error("Error writing to settings.json: " + err.Error())
+ return
}
}