X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=internal%2Fconfig%2Fsettings.go;h=55aed63ed851995c72238982832be0e2110dcdf7;hb=660d345880fc32c8403f0bd2d82f2ed907f54621;hp=e8f37e012cb55ef6aa06464e34aa425eebd02aa0;hpb=2f45644d14e7c96b7dbd70bd21eeebca185a6035;p=micro.git diff --git a/internal/config/settings.go b/internal/config/settings.go index e8f37e01..55aed63e 100644 --- a/internal/config/settings.go +++ b/internal/config/settings.go @@ -3,6 +3,7 @@ package config import ( "encoding/json" "errors" + "fmt" "io/ioutil" "os" "path/filepath" @@ -12,7 +13,7 @@ import ( "github.com/zyedidia/glob" "github.com/zyedidia/json5" - "github.com/zyedidia/micro/internal/util" + "github.com/zyedidia/micro/v2/internal/util" "golang.org/x/text/encoding/htmlindex" ) @@ -27,9 +28,14 @@ var ( // This is the raw parsed json parsedSettings map[string]interface{} + + // ModifiedSettings is a map of settings which should be written to disk + // because they have been modified by the user in this session + ModifiedSettings map[string]bool ) func init() { + ModifiedSettings = make(map[string]bool) parsedSettings = make(map[string]interface{}) } @@ -75,16 +81,33 @@ func ReadSettings() error { return nil } +func verifySetting(option string, value reflect.Type, def reflect.Type) bool { + var interfaceArr []interface{} + switch option { + case "pluginrepos", "pluginchannels": + return value.AssignableTo(reflect.TypeOf(interfaceArr)) + default: + return def.AssignableTo(value) + } +} + // InitGlobalSettings initializes the options map and sets all options to their default values // Must be called after ReadSettings -func InitGlobalSettings() { +func InitGlobalSettings() error { + var err error GlobalSettings = DefaultGlobalSettings() for k, v := range parsedSettings { if !strings.HasPrefix(reflect.TypeOf(v).String(), "map") { + if _, ok := GlobalSettings[k]; ok && !verifySetting(k, reflect.TypeOf(v), reflect.TypeOf(GlobalSettings[k])) { + err = errors.New(fmt.Sprintf("Global Error: setting '%s' has incorrect type (%s), using default value: %v (%s)", k, reflect.TypeOf(v), GlobalSettings[k], reflect.TypeOf(GlobalSettings[k]))) + continue + } + GlobalSettings[k] = v } } + return err } // InitLocalSettings scans the json in settings.json and sets the options locally based @@ -97,6 +120,10 @@ func InitLocalSettings(settings map[string]interface{}, path string) error { if strings.HasPrefix(k, "ft:") { if settings["filetype"].(string) == k[3:] { for k1, v1 := range v.(map[string]interface{}) { + if _, ok := settings[k1]; ok && !verifySetting(k1, reflect.TypeOf(v1), reflect.TypeOf(settings[k1])) { + parseError = errors.New(fmt.Sprintf("Error: setting '%s' has incorrect type (%s), using default value: %v (%s)", k, reflect.TypeOf(v1), settings[k1], reflect.TypeOf(settings[k1]))) + continue + } settings[k1] = v1 } } @@ -109,6 +136,10 @@ func InitLocalSettings(settings map[string]interface{}, path string) error { if g.MatchString(path) { for k1, v1 := range v.(map[string]interface{}) { + if _, ok := settings[k1]; ok && !verifySetting(k1, reflect.TypeOf(v1), reflect.TypeOf(settings[k1])) { + parseError = errors.New(fmt.Sprintf("Error: setting '%s' has incorrect type (%s), using default value: %v (%s)", k, reflect.TypeOf(v1), settings[k1], reflect.TypeOf(settings[k1]))) + continue + } settings[k1] = v1 } } @@ -122,8 +153,25 @@ func InitLocalSettings(settings map[string]interface{}, path string) error { func WriteSettings(filename string) error { var err error if _, e := os.Stat(ConfigDir); e == nil { + defaults := DefaultGlobalSettings() + + // remove any options froms parsedSettings that have since been marked as default + for k, v := range parsedSettings { + if !strings.HasPrefix(reflect.TypeOf(v).String(), "map") { + cur, okcur := GlobalSettings[k] + if def, ok := defaults[k]; ok && okcur && reflect.DeepEqual(cur, def) { + delete(parsedSettings, k) + } + } + } + + // add any options to parsedSettings that have since been marked as non-default for k, v := range GlobalSettings { - parsedSettings[k] = v + if def, ok := defaults[k]; !ok || !reflect.DeepEqual(v, def) { + if _, wr := ModifiedSettings[k]; wr { + parsedSettings[k] = v + } + } } txt, _ := json.MarshalIndent(parsedSettings, "", " ") @@ -132,10 +180,23 @@ func WriteSettings(filename string) error { return err } +// OverwriteSettings writes the current settings to settings.json and +// resets any user configuration of local settings present in settings.json func OverwriteSettings(filename string) error { + settings := make(map[string]interface{}) + var err error if _, e := os.Stat(ConfigDir); e == nil { - txt, _ := json.MarshalIndent(GlobalSettings, "", " ") + defaults := DefaultGlobalSettings() + for k, v := range GlobalSettings { + if def, ok := defaults[k]; !ok || !reflect.DeepEqual(v, def) { + if _, wr := ModifiedSettings[k]; wr { + settings[k] = v + } + } + } + + txt, _ := json.MarshalIndent(settings, "", " ") err = ioutil.WriteFile(filename, append(txt, '\n'), 0644) } return err @@ -147,7 +208,7 @@ func RegisterCommonOptionPlug(pl string, name string, defaultvalue interface{}) if v, ok := GlobalSettings[name]; !ok { defaultCommonSettings[name] = defaultvalue GlobalSettings[name] = defaultvalue - err := WriteSettings(filepath.Join(ConfigDir, "/settings.json")) + err := WriteSettings(filepath.Join(ConfigDir, "settings.json")) if err != nil { return errors.New("Error writing settings.json file: " + err.Error()) } @@ -165,14 +226,14 @@ func RegisterGlobalOptionPlug(pl string, name string, defaultvalue interface{}) // RegisterGlobalOption creates a new global-only option func RegisterGlobalOption(name string, defaultvalue interface{}) error { if v, ok := GlobalSettings[name]; !ok { - defaultGlobalSettings[name] = defaultvalue + DefaultGlobalOnlySettings[name] = defaultvalue GlobalSettings[name] = defaultvalue err := WriteSettings(filepath.Join(ConfigDir, "settings.json")) if err != nil { return errors.New("Error writing settings.json file: " + err.Error()) } } else { - defaultGlobalSettings[name] = v + DefaultGlobalOnlySettings[name] = v } return nil } @@ -184,13 +245,15 @@ func GetGlobalOption(name string) interface{} { var defaultCommonSettings = map[string]interface{}{ "autoindent": true, + "autosu": false, "backup": true, "basename": false, "colorcolumn": float64(0), "cursorline": true, + "diffgutter": false, "encoding": "utf-8", - "eofnewline": false, - "fastdirty": true, + "eofnewline": true, + "fastdirty": false, "fileformat": "unix", "filetype": "unknown", "ignorecase": false, @@ -201,6 +264,7 @@ var defaultCommonSettings = map[string]interface{}{ "readonly": false, "rmtrailingws": false, "ruler": true, + "relativeruler": false, "savecursor": false, "saveundo": false, "scrollbar": false, @@ -243,17 +307,21 @@ func DefaultCommonSettings() map[string]interface{} { // a list of settings that should only be globally modified and their // default values -var defaultGlobalSettings = map[string]interface{}{ +var DefaultGlobalOnlySettings = map[string]interface{}{ "autosave": float64(0), "colorscheme": "default", + "divchars": "|-", + "divreverse": true, "infobar": true, "keymenu": false, "mouse": true, + "parsecursor": false, "paste": false, "savehistory": true, "sucmd": "sudo", "pluginchannels": []string{"https://raw.githubusercontent.com/micro-editor/plugin-channel/master/channel.json"}, "pluginrepos": []string{}, + "xterm": false, } // a list of settings that should never be globally modified @@ -269,7 +337,7 @@ func DefaultGlobalSettings() map[string]interface{} { for k, v := range defaultCommonSettings { globalsettings[k] = v } - for k, v := range defaultGlobalSettings { + for k, v := range DefaultGlobalOnlySettings { globalsettings[k] = v } return globalsettings @@ -282,7 +350,7 @@ func DefaultAllSettings() map[string]interface{} { for k, v := range defaultCommonSettings { allsettings[k] = v } - for k, v := range defaultGlobalSettings { + for k, v := range DefaultGlobalOnlySettings { allsettings[k] = v } return allsettings