]> git.lizzy.rs Git - micro.git/blob - cmd/micro/settings.go
Add filetype as an option
[micro.git] / cmd / micro / settings.go
1 package main
2
3 import (
4         "encoding/json"
5         "errors"
6         "io/ioutil"
7         "os"
8         "reflect"
9         "strconv"
10 )
11
12 // The options that the user can set
13 var globalSettings map[string]interface{}
14
15 // InitSettings initializes the options map and sets all options to their default values
16 func InitSettings() {
17         defaults := DefaultSettings()
18         var parsed map[string]interface{}
19
20         filename := configDir + "/settings.json"
21         if _, e := os.Stat(filename); e == nil {
22                 input, err := ioutil.ReadFile(filename)
23                 if err != nil {
24                         TermMessage("Error reading settings.json file: " + err.Error())
25                         return
26                 }
27
28                 err = json.Unmarshal(input, &parsed)
29                 if err != nil {
30                         TermMessage("Error reading settings.json:", err.Error())
31                 }
32         }
33
34         globalSettings = make(map[string]interface{})
35         for k, v := range defaults {
36                 globalSettings[k] = v
37         }
38         for k, v := range parsed {
39                 globalSettings[k] = v
40         }
41
42         err := WriteSettings(filename)
43         if err != nil {
44                 TermMessage("Error writing settings.json file: " + err.Error())
45         }
46 }
47
48 // WriteSettings writes the settings to the specified filename as JSON
49 func WriteSettings(filename string) error {
50         var err error
51         if _, e := os.Stat(configDir); e == nil {
52                 txt, _ := json.MarshalIndent(globalSettings, "", "    ")
53                 err = ioutil.WriteFile(filename, txt, 0644)
54         }
55         return err
56 }
57
58 // AddOption creates a new option. This is meant to be called by plugins to add options.
59 func AddOption(name string, value interface{}) {
60         globalSettings[name] = value
61         err := WriteSettings(configDir + "/settings.json")
62         if err != nil {
63                 TermMessage("Error writing settings.json file: " + err.Error())
64         }
65 }
66
67 // GetOption returns the specified option. This is meant to be called by plugins to add options.
68 func GetGlobalOption(name string) interface{} {
69         return globalSettings[name]
70 }
71
72 func GetLocalOption(name string, buf *Buffer) interface{} {
73         return buf.Settings[name]
74 }
75
76 func GetOption(name string) interface{} {
77         if GetLocalOption(name, CurView().Buf) != nil {
78                 return GetLocalOption(name, CurView().Buf)
79         }
80         return GetGlobalOption(name)
81 }
82
83 // DefaultSettings returns the default settings for micro
84 func DefaultSettings() map[string]interface{} {
85         return map[string]interface{}{
86                 "autoindent":   true,
87                 "colorscheme":  "monokai",
88                 "cursorline":   false,
89                 "filetype":     "Unknown",
90                 "ignorecase":   false,
91                 "indentchar":   " ",
92                 "ruler":        true,
93                 "savecursor":   false,
94                 "saveundo":     false,
95                 "scrollspeed":  float64(2),
96                 "scrollmargin": float64(3),
97                 "statusline":   true,
98                 "syntax":       true,
99                 "tabsize":      float64(4),
100                 "tabstospaces": false,
101         }
102 }
103
104 // SetOption attempts to set the given option to the value
105 func SetGlobalOption(option, value string) error {
106         if _, ok := globalSettings[option]; !ok {
107                 return errors.New("Invalid option")
108         }
109
110         kind := reflect.TypeOf(globalSettings[option]).Kind()
111         if kind == reflect.Bool {
112                 b, err := ParseBool(value)
113                 if err != nil {
114                         return errors.New("Invalid value")
115                 }
116                 globalSettings[option] = b
117         } else if kind == reflect.String {
118                 globalSettings[option] = value
119         } else if kind == reflect.Float64 {
120                 i, err := strconv.Atoi(value)
121                 if err != nil {
122                         return errors.New("Invalid value")
123                 }
124                 globalSettings[option] = float64(i)
125         }
126
127         for _, tab := range tabs {
128                 for _, view := range tab.views {
129                         SetLocalOption(option, value, view)
130                 }
131         }
132
133         return nil
134 }
135
136 func SetLocalOption(option, value string, view *View) error {
137         buf := view.Buf
138         if _, ok := buf.Settings[option]; !ok {
139                 return errors.New("Invalid option")
140         }
141
142         kind := reflect.TypeOf(buf.Settings[option]).Kind()
143         if kind == reflect.Bool {
144                 b, err := ParseBool(value)
145                 if err != nil {
146                         return errors.New("Invalid value")
147                 }
148                 buf.Settings[option] = b
149         } else if kind == reflect.String {
150                 buf.Settings[option] = value
151         } else if kind == reflect.Float64 {
152                 i, err := strconv.Atoi(value)
153                 if err != nil {
154                         return errors.New("Invalid value")
155                 }
156                 buf.Settings[option] = float64(i)
157         }
158
159         if option == "colorscheme" {
160                 LoadSyntaxFiles()
161                 buf.UpdateRules()
162                 if buf.Settings["syntax"].(bool) {
163                         view.matches = Match(view)
164                 }
165         }
166
167         if option == "statusline" {
168                 view.ToggleStatusLine()
169                 if buf.Settings["syntax"].(bool) {
170                         view.matches = Match(view)
171                 }
172         }
173
174         return nil
175 }
176
177 // SetOptionAndSettings sets the given option and saves the option setting to the settings config file
178 func SetOptionAndSettings(option, value string) {
179         filename := configDir + "/settings.json"
180
181         err := SetGlobalOption(option, value)
182
183         if err != nil {
184                 messenger.Message(err.Error())
185                 return
186         }
187
188         err = WriteSettings(filename)
189         if err != nil {
190                 messenger.Error("Error writing to settings.json: " + err.Error())
191                 return
192         }
193 }