Add automatic settings to ~/.micro/settings.json

This commit is contained in:
Zachary Yedidia
2016-03-28 21:10:10 -04:00
parent 77164fd08c
commit 62967c7935
9 changed files with 128 additions and 56 deletions

View File

@@ -28,7 +28,7 @@ func LoadDefaultColorscheme() {
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

View File

@@ -257,7 +257,7 @@ func (c *Cursor) Start() {
// 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) {
@@ -273,7 +273,7 @@ func (c *Cursor) GetCharPosInLine(lineNum, visualPos int) int {
// 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)
}

View File

@@ -31,12 +31,12 @@ var syntaxFiles map[[2]*regexp.Regexp]FileTypeRules
// 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)

View File

@@ -64,7 +64,7 @@ func main() {
os.Exit(1)
}
InitOptions()
InitSettings()
// Should we enable true color?
truecolor := os.Getenv("MICRO_TRUECOLOR") == "1"

View File

@@ -1,47 +0,0 @@
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")
}
}
}

110
src/settings.go Normal file
View File

@@ -0,0 +1,110 @@
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")
}
}
}

View File

@@ -60,3 +60,13 @@ func IsWordChar(str string) bool {
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
}

View File

@@ -626,7 +626,7 @@ func (v *View) DisplayView() {
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)