Add option to clean unused settings and other parts of config

This commit is contained in:
Zachary Yedidia 2020-02-02 15:30:06 -05:00
parent dba8ef2fdd
commit 6a1b8f4a4f
4 changed files with 166 additions and 8 deletions

140
cmd/micro/clean.go Normal file
View file

@ -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")
}

View 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)
}

View 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

View 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())
}