mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-11 15:12:47 +09:00
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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user