178 lines
3.8 KiB
Go
178 lines
3.8 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"io/ioutil"
|
||
|
"os"
|
||
|
"reflect"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
//-------------------------------------------------------------------------
|
||
|
// config
|
||
|
//
|
||
|
// Structure represents persistent config storage of the gocode daemon. Usually
|
||
|
// the config is located somewhere in ~/.config/gocode directory.
|
||
|
//-------------------------------------------------------------------------
|
||
|
|
||
|
type config struct {
|
||
|
ProposeBuiltins bool `json:"propose-builtins"`
|
||
|
LibPath string `json:"lib-path"`
|
||
|
CustomPkgPrefix string `json:"custom-pkg-prefix"`
|
||
|
CustomVendorDir string `json:"custom-vendor-dir"`
|
||
|
Autobuild bool `json:"autobuild"`
|
||
|
ForceDebugOutput string `json:"force-debug-output"`
|
||
|
PackageLookupMode string `json:"package-lookup-mode"`
|
||
|
CloseTimeout int `json:"close-timeout"`
|
||
|
UnimportedPackages bool `json:"unimported-packages"`
|
||
|
}
|
||
|
|
||
|
var g_config = config{
|
||
|
ProposeBuiltins: false,
|
||
|
LibPath: "",
|
||
|
CustomPkgPrefix: "",
|
||
|
Autobuild: false,
|
||
|
ForceDebugOutput: "",
|
||
|
PackageLookupMode: "go",
|
||
|
CloseTimeout: 1800,
|
||
|
UnimportedPackages: false,
|
||
|
}
|
||
|
|
||
|
var g_string_to_bool = map[string]bool{
|
||
|
"t": true,
|
||
|
"true": true,
|
||
|
"y": true,
|
||
|
"yes": true,
|
||
|
"on": true,
|
||
|
"1": true,
|
||
|
"f": false,
|
||
|
"false": false,
|
||
|
"n": false,
|
||
|
"no": false,
|
||
|
"off": false,
|
||
|
"0": false,
|
||
|
}
|
||
|
|
||
|
func set_value(v reflect.Value, value string) {
|
||
|
switch t := v; t.Kind() {
|
||
|
case reflect.Bool:
|
||
|
v, ok := g_string_to_bool[value]
|
||
|
if ok {
|
||
|
t.SetBool(v)
|
||
|
}
|
||
|
case reflect.String:
|
||
|
t.SetString(value)
|
||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||
|
v, err := strconv.ParseInt(value, 10, 64)
|
||
|
if err == nil {
|
||
|
t.SetInt(v)
|
||
|
}
|
||
|
case reflect.Float32, reflect.Float64:
|
||
|
v, err := strconv.ParseFloat(value, 64)
|
||
|
if err == nil {
|
||
|
t.SetFloat(v)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func list_value(v reflect.Value, name string, w io.Writer) {
|
||
|
switch t := v; t.Kind() {
|
||
|
case reflect.Bool:
|
||
|
fmt.Fprintf(w, "%s %v\n", name, t.Bool())
|
||
|
case reflect.String:
|
||
|
fmt.Fprintf(w, "%s \"%v\"\n", name, t.String())
|
||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||
|
fmt.Fprintf(w, "%s %v\n", name, t.Int())
|
||
|
case reflect.Float32, reflect.Float64:
|
||
|
fmt.Fprintf(w, "%s %v\n", name, t.Float())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (this *config) list() string {
|
||
|
str, typ := this.value_and_type()
|
||
|
buf := bytes.NewBuffer(make([]byte, 0, 256))
|
||
|
for i := 0; i < str.NumField(); i++ {
|
||
|
v := str.Field(i)
|
||
|
name := typ.Field(i).Tag.Get("json")
|
||
|
list_value(v, name, buf)
|
||
|
}
|
||
|
return buf.String()
|
||
|
}
|
||
|
|
||
|
func (this *config) list_option(name string) string {
|
||
|
str, typ := this.value_and_type()
|
||
|
buf := bytes.NewBuffer(make([]byte, 0, 256))
|
||
|
for i := 0; i < str.NumField(); i++ {
|
||
|
v := str.Field(i)
|
||
|
nm := typ.Field(i).Tag.Get("json")
|
||
|
if nm == name {
|
||
|
list_value(v, name, buf)
|
||
|
}
|
||
|
}
|
||
|
return buf.String()
|
||
|
}
|
||
|
|
||
|
func (this *config) set_option(name, value string) string {
|
||
|
str, typ := this.value_and_type()
|
||
|
buf := bytes.NewBuffer(make([]byte, 0, 256))
|
||
|
for i := 0; i < str.NumField(); i++ {
|
||
|
v := str.Field(i)
|
||
|
nm := typ.Field(i).Tag.Get("json")
|
||
|
if nm == name {
|
||
|
set_value(v, value)
|
||
|
list_value(v, name, buf)
|
||
|
}
|
||
|
}
|
||
|
this.write()
|
||
|
return buf.String()
|
||
|
|
||
|
}
|
||
|
|
||
|
func (this *config) value_and_type() (reflect.Value, reflect.Type) {
|
||
|
v := reflect.ValueOf(this).Elem()
|
||
|
return v, v.Type()
|
||
|
}
|
||
|
|
||
|
func (this *config) write() error {
|
||
|
data, err := json.Marshal(this)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// make sure config dir exists
|
||
|
dir := config_dir()
|
||
|
if !file_exists(dir) {
|
||
|
os.MkdirAll(dir, 0755)
|
||
|
}
|
||
|
|
||
|
f, err := os.Create(config_file())
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
|
||
|
_, err = f.Write(data)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (this *config) read() error {
|
||
|
data, err := ioutil.ReadFile(config_file())
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
err = json.Unmarshal(data, this)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|