]> git.lizzy.rs Git - micro.git/commitdiff
Add option to clean unused settings and other parts of config
authorZachary Yedidia <zyedidia@gmail.com>
Sun, 2 Feb 2020 20:30:06 +0000 (15:30 -0500)
committerZachary Yedidia <zyedidia@gmail.com>
Sun, 2 Feb 2020 20:30:06 +0000 (15:30 -0500)
cmd/micro/clean.go [new file with mode: 0644]
cmd/micro/micro.go
internal/buffer/serialize.go
internal/config/settings.go

diff --git a/cmd/micro/clean.go b/cmd/micro/clean.go
new file mode 100644 (file)
index 0000000..c0a8766
--- /dev/null
@@ -0,0 +1,140 @@
+package main
+
+import (
+       "bufio"
+       "encoding/gob"
+       "fmt"
+       "io/ioutil"
+       "os"
+       "path/filepath"
+       "sort"
+       "strings"
+
+       "github.com/zyedidia/micro/internal/buffer"
+       "github.com/zyedidia/micro/internal/config"
+)
+
+func shouldContinue() bool {
+       reader := bufio.NewReader(os.Stdin)
+       fmt.Print("Continue [Y/n]: ")
+       text, err := reader.ReadString('\n')
+       if err != nil {
+               fmt.Println(err)
+               return false
+       }
+
+       if len(text) <= 1 {
+               // default continue
+               return true
+       }
+
+       return strings.ToLower(text)[0] == 'y'
+}
+
+// CleanConfig performs cleanup in the user's configuration directory
+func CleanConfig() {
+       fmt.Println("Cleaning your configuration directory at", config.ConfigDir)
+       fmt.Printf("Please consider backing up %s before continuing\n", config.ConfigDir)
+
+       if !shouldContinue() {
+               fmt.Println("Stopping early")
+               return
+       }
+
+       // detect unused options
+       var unusedOptions []string
+       defaultSettings := config.DefaultAllSettings()
+       for k := range config.GlobalSettings {
+               if _, ok := defaultSettings[k]; !ok {
+                       valid := false
+                       for _, p := range config.Plugins {
+                               if strings.HasPrefix(k, p.Name+".") || k == p.Name {
+                                       valid = true
+                               }
+                       }
+                       if !valid {
+                               unusedOptions = append(unusedOptions, k)
+                       }
+               }
+       }
+
+       if len(unusedOptions) > 0 {
+               fmt.Println("The following options are unused:")
+
+               sort.Strings(unusedOptions)
+
+               for _, s := range unusedOptions {
+                       fmt.Printf("%s (value: %v)\n", s, config.GlobalSettings[s])
+               }
+
+               fmt.Printf("These options will be removed from %s\n", filepath.Join(config.ConfigDir, "settings.json"))
+
+               if shouldContinue() {
+                       for _, s := range unusedOptions {
+                               delete(config.GlobalSettings, s)
+                       }
+
+                       err := config.OverwriteSettings(filepath.Join(config.ConfigDir, "settings.json"))
+                       if err != nil {
+                               fmt.Println("Error writing settings.json file: " + err.Error())
+                       }
+
+                       fmt.Println("Removed unused options")
+                       fmt.Print("\n\n")
+               }
+       }
+
+       // detect incorrectly formatted buffer/ files
+       files, err := ioutil.ReadDir(filepath.Join(config.ConfigDir, "buffers"))
+       if err == nil {
+               var badFiles []string
+               var buffer buffer.SerializedBuffer
+               for _, f := range files {
+                       fname := filepath.Join(config.ConfigDir, "buffers", f.Name())
+                       file, err := os.Open(fname)
+                       defer file.Close()
+
+                       decoder := gob.NewDecoder(file)
+                       err = decoder.Decode(&buffer)
+
+                       if err != nil {
+                               badFiles = append(badFiles, fname)
+                       }
+               }
+
+               if len(badFiles) > 0 {
+                       fmt.Printf("Detected %d files with an invalid format in %s\n", len(badFiles), filepath.Join(config.ConfigDir, "buffers"))
+                       fmt.Println("These files store cursor and undo history.")
+                       fmt.Printf("Removing badly formatted files in %s\n", filepath.Join(config.ConfigDir, "buffers"))
+
+                       if shouldContinue() {
+                               for _, f := range badFiles {
+                                       err := os.Remove(f)
+                                       if err != nil {
+                                               fmt.Println(err)
+                                               continue
+                                       }
+                               }
+
+                               fmt.Println("Removed badly formatted files")
+                               fmt.Print("\n\n")
+                       }
+               }
+       }
+
+       // detect plugins/ directory
+       plugins := filepath.Join(config.ConfigDir, "plugins")
+       if stat, err := os.Stat(plugins); err == nil && stat.IsDir() {
+               fmt.Printf("Found directory %s\n", plugins)
+               fmt.Printf("Plugins should now be stored in %s\n", filepath.Join(config.ConfigDir, "plug"))
+               fmt.Printf("Removing %s\n", plugins)
+
+               if shouldContinue() {
+                       os.RemoveAll(plugins)
+               }
+
+               fmt.Print("\n\n")
+       }
+
+       fmt.Println("Done cleaning")
+}
index 4bcf99cbfe6ac6dd05b141bf5dbaff9a05c90009..f6360255fa46d9f91c90895a20db5a343ee94363 100644 (file)
@@ -31,12 +31,15 @@ var (
        flagOptions   = flag.Bool("options", false, "Show all option help")
        flagDebug     = flag.Bool("debug", false, "Enable debug mode (prints debug info to ./log.txt)")
        flagPlugin    = flag.String("plugin", "", "Plugin command")
+       flagClean     = flag.Bool("clean", false, "Clean configuration directory")
        optionFlags   map[string]*string
 )
 
 func InitFlags() {
        flag.Usage = func() {
                fmt.Println("Usage: micro [OPTIONS] [FILE]...")
+               fmt.Println("-clean")
+               fmt.Println("    \tCleans the configuration directory")
                fmt.Println("-config-dir dir")
                fmt.Println("    \tSpecify a custom location for the configuration directory")
                fmt.Println("[FILE]:LINE:COL")
@@ -106,14 +109,18 @@ func InitFlags() {
        }
 }
 
-// DoPluginFlags parses and executes any -plugin flags
+// DoPluginFlags parses and executes any flags that require LoadAllPlugins (-plugin and -clean)
 func DoPluginFlags() {
-       if *flagPlugin != "" {
+       if *flagClean || *flagPlugin != "" {
                config.LoadAllPlugins()
 
-               args := flag.Args()
+               if *flagPlugin != "" {
+                       args := flag.Args()
 
-               config.PluginCommand(os.Stdout, *flagPlugin, args)
+                       config.PluginCommand(os.Stdout, *flagPlugin, args)
+               } else if *flagClean {
+                       CleanConfig()
+               }
 
                os.Exit(0)
        }
index ae1d411faa8d306c33d8f87c96bcc3eafeaa620e..b11b7322ce9aa1c0d4392b891ecb84f4fae8f4ef 100644 (file)
@@ -5,6 +5,7 @@ import (
        "errors"
        "io"
        "os"
+       "path/filepath"
        "time"
 
        "golang.org/x/text/encoding"
@@ -49,7 +50,7 @@ func (b *Buffer) Unserialize() error {
        if b.Path == "" {
                return nil
        }
-       file, err := os.Open(config.ConfigDir + "/buffers/" + util.EscapePath(b.AbsPath))
+       file, err := os.Open(filepath.Join(config.ConfigDir, "buffers", util.EscapePath(b.AbsPath)))
        defer file.Close()
        if err == nil {
                var buffer SerializedBuffer
index 76f11771297619343a330ce11ed898ff144cd7e4..c5e3f011b0c287f5602fc3bdde74da4ee78a4db3 100644 (file)
@@ -5,6 +5,7 @@ import (
        "errors"
        "io/ioutil"
        "os"
+       "path/filepath"
        "reflect"
        "strconv"
        "strings"
@@ -45,7 +46,7 @@ var optionValidators = map[string]optionValidator{
 }
 
 func ReadSettings() error {
-       filename := ConfigDir + "/settings.json"
+       filename := filepath.Join(ConfigDir, "settings.json")
        if _, e := os.Stat(filename); e == nil {
                input, err := ioutil.ReadFile(filename)
                if err != nil {
@@ -119,13 +120,22 @@ func WriteSettings(filename string) error {
        return err
 }
 
+func OverwriteSettings(filename string) error {
+       var err error
+       if _, e := os.Stat(ConfigDir); e == nil {
+               txt, _ := json.MarshalIndent(GlobalSettings, "", "    ")
+               err = ioutil.WriteFile(filename, append(txt, '\n'), 0644)
+       }
+       return err
+}
+
 // RegisterCommonOptionPlug creates a new option (called pl.name). This is meant to be called by plugins to add options.
 func RegisterCommonOptionPlug(pl string, name string, defaultvalue interface{}) error {
        name = pl + "." + name
        if v, ok := GlobalSettings[name]; !ok {
                defaultCommonSettings[name] = defaultvalue
                GlobalSettings[name] = defaultvalue
-               err := WriteSettings(ConfigDir + "/settings.json")
+               err := WriteSettings(filepath.Join(ConfigDir, "/settings.json"))
                if err != nil {
                        return errors.New("Error writing settings.json file: " + err.Error())
                }
@@ -145,7 +155,7 @@ func RegisterGlobalOption(name string, defaultvalue interface{}) error {
        if v, ok := GlobalSettings[name]; !ok {
                defaultGlobalSettings[name] = defaultvalue
                GlobalSettings[name] = defaultvalue
-               err := WriteSettings(ConfigDir + "/settings.json")
+               err := WriteSettings(filepath.Join(ConfigDir, "settings.json"))
                if err != nil {
                        return errors.New("Error writing settings.json file: " + err.Error())
                }