1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package config
import (
"github.com/go-ini/ini"
"github.com/kyoh86/xdg"
"fmt"
"path"
"strings"
"unicode"
)
type UIConfig struct {
IndexFormat string
TimestampFormat string
ShowHeaders []string `delim:","`
LoadingFrames []string `delim:","`
RenderAccountTabs string
SidebarWidth int
PreviewHeight int
EmptyMessage string
}
type AccountConfig struct {
Name string
Source string
Folders []string
Params map[string]string
}
type AercConfig struct {
Ini *ini.File `ini:"-"`
Accounts []AccountConfig `ini:"-"`
Ui UIConfig
}
// Input: TimestampFormat
// Output: timestamp-format
func mapName(raw string) string {
newstr := make([]rune, 0, len(raw))
for i, chr := range raw {
if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
if i > 0 {
newstr = append(newstr, '-')
}
}
newstr = append(newstr, unicode.ToLower(chr))
}
return string(newstr)
}
func loadAccountConfig(path string) ([]AccountConfig, error) {
var (
file *ini.File
err error
accounts []AccountConfig
)
accounts = make([]AccountConfig, 0)
if file, err = ini.Load(path); err != nil {
return nil, err
}
file.NameMapper = mapName
for _, _sec := range file.SectionStrings() {
if _sec == "DEFAULT" {
continue
}
sec := file.Section(_sec)
account := AccountConfig{Name: _sec}
if err = sec.MapTo(&account); err != nil {
return nil, err
}
for key, val := range sec.KeysHash() {
if key == "source" {
account.Source = val
} else if key == "folders" {
account.Folders = strings.Split(val, ",")
} else if key != "name" {
account.Params[key] = val
}
}
if account.Source == "" {
return nil, fmt.Errorf("Expected source for account %s", _sec)
}
accounts = append(accounts, account)
}
return accounts, nil
}
func LoadConfig(root *string) (*AercConfig, error) {
var (
err error
file *ini.File
)
if root == nil {
_root := path.Join(xdg.ConfigHome(), "aerc")
root = &_root
}
if file, err = ini.Load(path.Join(*root, "aerc.conf")); err != nil {
return nil, err
}
file.NameMapper = mapName
config := &AercConfig{
Ini: file,
Ui: UIConfig{
IndexFormat: "%4C %Z %D %-17.17n %s",
TimestampFormat: "%F %l:%M %p",
ShowHeaders: []string{
"From", "To", "Cc", "Bcc", "Subject", "Date",
},
LoadingFrames: []string{
"[..] ", " [..] ", " [..]", " [..] ",
},
RenderAccountTabs: "auto",
SidebarWidth: 20,
PreviewHeight: 12,
EmptyMessage: "(no messages)",
},
}
if ui, err := file.GetSection("ui"); err != nil {
ui.MapTo(config.Ui)
}
accountsPath := path.Join(*root, "accounts.conf")
if accounts, err := loadAccountConfig(accountsPath); err != nil {
return nil, err
} else {
config.Accounts = accounts
}
return config, nil
}
|