Use a map for settings instead of a struct

Using a map for the settings means that plugins will be able to create
their own settings at runtime.
This commit is contained in:
Zachary Yedidia
2016-04-30 11:39:48 -04:00
parent 19d2d20689
commit f6393dd835
5 changed files with 43 additions and 67 deletions

View File

@@ -350,7 +350,7 @@ func (v *View) SelectUp() bool {
return true
}
// SelectUp selects down one line
// SelectDown selects down one line
func (v *View) SelectDown() bool {
loc := v.cursor.Loc()
if !v.cursor.HasSelection() {
@@ -498,7 +498,7 @@ func (v *View) InsertEnter() bool {
ws := GetLeadingWhitespace(v.buf.lines[v.cursor.y])
v.cursor.Right()
if settings.AutoIndent {
if settings["autoindent"].(bool) {
v.eh.Insert(v.cursor.Loc(), ws)
for i := 0; i < len(ws); i++ {
v.cursor.Right()
@@ -525,12 +525,13 @@ func (v *View) Backspace() bool {
// whitespace at the start of the line, we should delete as if its a
// tab (tabSize number of spaces)
lineStart := v.buf.lines[v.cursor.y][:v.cursor.x]
if settings.TabsToSpaces && IsSpaces(lineStart) && len(lineStart) != 0 && len(lineStart)%settings.TabSize == 0 {
tabSize := int(settings["tabsize"].(float64))
if settings["tabsToSpaces"].(bool) && IsSpaces(lineStart) && len(lineStart) != 0 && len(lineStart)%tabSize == 0 {
loc := v.cursor.Loc()
v.cursor.SetLoc(loc - settings.TabSize)
v.cursor.SetLoc(loc - tabSize)
cx, cy := v.cursor.x, v.cursor.y
v.cursor.SetLoc(loc)
v.eh.Remove(loc-settings.TabSize, loc)
v.eh.Remove(loc-tabSize, loc)
v.cursor.x, v.cursor.y = cx, cy
} else {
v.cursor.Left()
@@ -566,9 +567,10 @@ func (v *View) InsertTab() bool {
v.cursor.DeleteSelection()
v.cursor.ResetSelection()
}
if settings.TabsToSpaces {
v.eh.Insert(v.cursor.Loc(), Spaces(settings.TabSize))
for i := 0; i < settings.TabSize; i++ {
if settings["tabsToSpaces"].(bool) {
tabSize := int(settings["tabsize"].(float64))
v.eh.Insert(v.cursor.Loc(), Spaces(tabSize))
for i := 0; i < tabSize; i++ {
v.cursor.Right()
}
} else {
@@ -606,7 +608,7 @@ func (v *View) Save() bool {
// GoSave saves the current file (must be a go file) and runs goimports or gofmt
// depending on the user's configuration
func (v *View) GoSave() {
if settings.GoImports == true {
if settings["goimports"] == true {
messenger.Message("Running goimports...")
err := goimports(v.buf.path)
if err != nil {
@@ -615,7 +617,7 @@ func (v *View) GoSave() {
messenger.Message("Saved " + v.buf.path)
}
v.reOpen()
} else if settings.GoFmt == true {
} else if settings["gofmt"] == true {
messenger.Message("Running gofmt...")
err := gofmt(v.buf.path)
if err != nil {
@@ -824,10 +826,10 @@ func (v *View) HalfPageDown() bool {
// ToggleRuler turns line numbers off and on
func (v *View) ToggleRuler() bool {
if settings.Ruler == false {
settings.Ruler = true
if settings["ruler"] == false {
settings["ruler"] = true
} else {
settings.Ruler = false
settings["ruler"] = false
}
return false
}

View File

@@ -24,7 +24,7 @@ func InitColorscheme() {
// LoadDefaultColorscheme loads the default colorscheme from $(configDir)/colorschemes
func LoadDefaultColorscheme() {
LoadColorscheme(settings.Colorscheme, configDir+"/colorschemes")
LoadColorscheme(settings["colorscheme"].(string), configDir+"/colorschemes")
}
// LoadColorscheme loads the given colorscheme from a directory

View File

@@ -321,7 +321,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 := settings.TabSize
tabSize := int(settings["tabsize"].(float64))
// 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) {
@@ -337,7 +337,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 := settings.TabSize
tabSize := int(settings["tabsize"].(float64))
return c.x + NumOccurences(string(runes[:c.x]), '\t')*(tabSize-1)
}

View File

@@ -10,36 +10,11 @@ import (
)
// The options that the user can set
var settings Settings
// All the possible settings
// This map maps the name of the setting in the Settings struct
// to the name that the user will actually use (the one in the json file)
var possibleSettings = map[string]string{
"colorscheme": "Colorscheme",
"tabsize": "TabSize",
"autoindent": "AutoIndent",
"syntax": "Syntax",
"tabsToSpaces": "TabsToSpaces",
"ruler": "Ruler",
"gofmt": "GoFmt",
"goimports": "GoImports",
}
// 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"`
GoFmt bool `json:"gofmt"`
GoImports bool `json:"goimports"`
}
var settings map[string]interface{}
// InitSettings initializes the options map and sets all options to their default values
func InitSettings() {
settings = make(map[string]interface{})
filename := configDir + "/settings.json"
if _, e := os.Stat(filename); e == nil {
input, err := ioutil.ReadFile(filename)
@@ -72,16 +47,16 @@ func WriteSettings(filename string) error {
}
// DefaultSettings returns the default settings for micro
func DefaultSettings() Settings {
return Settings{
Colorscheme: "default",
TabSize: 4,
AutoIndent: true,
Syntax: true,
TabsToSpaces: false,
Ruler: true,
GoFmt: false,
GoImports: false,
func DefaultSettings() map[string]interface{} {
return map[string]interface{}{
"colorscheme": "default",
"tabsize": 4,
"autoindent": true,
"syntax": true,
"tabsToSpaces": false,
"ruler": true,
"gofmt": false,
"goimports": false,
}
}
@@ -92,29 +67,28 @@ func SetOption(view *View, args []string) {
option := strings.TrimSpace(args[0])
value := strings.TrimSpace(args[1])
mutable := reflect.ValueOf(&settings).Elem()
field := mutable.FieldByName(possibleSettings[option])
if !field.IsValid() {
if _, ok := settings[option]; !ok {
messenger.Error(option + " is not a valid option")
return
}
kind := field.Type().Kind()
kind := reflect.TypeOf(settings[option]).Kind()
if kind == reflect.Bool {
b, err := ParseBool(value)
if err != nil {
messenger.Error("Invalid value for " + option)
return
}
field.SetBool(b)
settings[option] = b
} else if kind == reflect.String {
field.SetString(value)
} else if kind == reflect.Int {
settings[option] = value
} else if kind == reflect.Float64 {
i, err := strconv.Atoi(value)
if err != nil {
messenger.Error("Invalid value for " + option)
return
}
field.SetInt(int64(i))
settings[option] = float64(i)
}
if option == "colorscheme" {

View File

@@ -357,7 +357,7 @@ func (v *View) HandleEvent(event tcell.Event) {
if relocate {
v.Relocate()
}
if settings.Syntax {
if settings["syntax"].(bool) {
v.matches = Match(v)
}
}
@@ -386,7 +386,7 @@ func (v *View) DisplayView() {
// We are going to have to offset by that amount
maxLineLength := len(strconv.Itoa(len(v.buf.lines)))
// + 1 for the little space after the line number
if settings.Ruler == true {
if settings["ruler"] == true {
v.lineNumOffset = maxLineLength + 1
} else {
v.lineNumOffset = 0
@@ -455,7 +455,7 @@ func (v *View) DisplayView() {
}
// Write the spaces before the line number if necessary
var lineNum string
if settings.Ruler == true {
if settings["ruler"] == true {
lineNum = strconv.Itoa(lineN + v.topline + 1)
for i := 0; i < maxLineLength-len(lineNum); i++ {
screen.SetContent(x, lineN, ' ', nil, lineNumStyle)
@@ -467,7 +467,7 @@ func (v *View) DisplayView() {
x++
}
if settings.Ruler == true {
if settings["ruler"] == true {
// Write the extra space
screen.SetContent(x, lineN, ' ', nil, lineNumStyle)
x++
@@ -478,7 +478,7 @@ func (v *View) DisplayView() {
for colN, ch := range line {
var lineStyle tcell.Style
if settings.Syntax {
if settings["syntax"].(bool) {
// Syntax highlighting is enabled
highlightStyle = v.matches[lineN][colN]
}
@@ -498,7 +498,7 @@ func (v *View) DisplayView() {
if ch == '\t' {
screen.SetContent(x+tabchars, lineN, ' ', nil, lineStyle)
tabSize := settings.TabSize
tabSize := int(settings["tabsize"].(float64))
for i := 0; i < tabSize-1; i++ {
tabchars++
if x-v.leftCol+tabchars >= v.lineNumOffset {