71: Allow user to change config options at runtime

There is a LoadConf and a LoadConfFromFile.
LoadConfFromFile reads the iniFile into memory and and calls
LoadConf, which executes the old parsing commands from
LoadConf (old func).

The remaining of the LoadConfFromFile is the same as the old OldConf.
This commit is contained in:
Pedro L. Ramos 2019-07-13 18:42:22 +01:00 committed by Drew DeVault
parent 9bf1a0418b
commit d85f671bdf
3 changed files with 129 additions and 51 deletions

View file

@ -121,7 +121,7 @@ func main() {
logger = log.New(logOut, "", log.LstdFlags)
logger.Println("Starting up aerc")
conf, err := config.LoadConfig(nil, ShareDir)
conf, err := config.LoadConfigFromFile(nil, ShareDir)
if err != nil {
fmt.Printf("Failed to load config: %v\n", err)
os.Exit(1)

69
commands/set.go Normal file
View file

@ -0,0 +1,69 @@
package commands
import (
"errors"
"strings"
"git.sr.ht/~sircmpwn/aerc/widgets"
"github.com/go-ini/ini"
)
type Set struct{}
func setUsage() string {
return "set <category>.<option> <value>"
}
func init() {
register(Set{})
}
func (_ Set) Aliases() []string {
return []string{"set"}
}
func (_ Set) Complete(aerc *widgets.Aerc, args []string) []string {
return nil
}
func SetCore(aerc *widgets.Aerc, args []string) error {
if len(args) != 3 {
return errors.New("Usage: " + setUsage())
}
config := aerc.Config()
parameters := strings.Split(args[1], ".")
if len(parameters) != 2 {
return errors.New("Usage: " + setUsage())
}
category := parameters[0]
option := parameters[1]
value := args[2]
new_file := ini.Empty()
section, err := new_file.NewSection(category)
if err != nil {
return nil
}
if _, err := section.NewKey(option, value); err != nil {
return err
}
if err := config.LoadConfig(new_file); err != nil {
return err
}
return nil
}
func (_ Set) Execute(aerc *widgets.Aerc, args []string) error {
return SetCore(aerc, args)
}

View file

@ -222,7 +222,61 @@ func installTemplate(root, sharedir, name string) error {
return nil
}
func LoadConfig(root *string, sharedir string) (*AercConfig, error) {
func (config *AercConfig) LoadConfig(file *ini.File) error {
if filters, err := file.GetSection("filters"); err == nil {
// TODO: Parse the filter more finely, e.g. parse the regex
for _, match := range filters.KeyStrings() {
cmd := filters.KeysHash()[match]
filter := FilterConfig{
Command: cmd,
Filter: match,
}
if strings.Contains(match, ",~") {
filter.FilterType = FILTER_HEADER
header := filter.Filter[:strings.Index(filter.Filter, ",")]
regex := filter.Filter[strings.Index(filter.Filter, "~")+1:]
filter.Header = strings.ToLower(header)
filter.Regex, err = regexp.Compile(regex)
if err != nil {
panic(err)
}
} else if strings.ContainsRune(match, ',') {
filter.FilterType = FILTER_HEADER
header := filter.Filter[:strings.Index(filter.Filter, ",")]
value := filter.Filter[strings.Index(filter.Filter, ",")+1:]
filter.Header = strings.ToLower(header)
filter.Regex, err = regexp.Compile(regexp.QuoteMeta(value))
} else {
filter.FilterType = FILTER_MIMETYPE
}
config.Filters = append(config.Filters, filter)
}
}
if viewer, err := file.GetSection("viewer"); err == nil {
if err := viewer.MapTo(&config.Viewer); err != nil {
return err
}
for key, val := range viewer.KeysHash() {
switch key {
case "alternatives":
config.Viewer.Alternatives = strings.Split(val, ",")
}
}
}
if compose, err := file.GetSection("compose"); err == nil {
if err := compose.MapTo(&config.Compose); err != nil {
return err
}
}
if ui, err := file.GetSection("ui"); err == nil {
if err := ui.MapTo(&config.Ui); err != nil {
return err
}
}
return nil
}
func LoadConfigFromFile(root *string, sharedir string) (*AercConfig, error) {
if root == nil {
_root := path.Join(xdg.ConfigHome(), "aerc")
root = &_root
@ -274,61 +328,16 @@ func LoadConfig(root *string, sharedir string) (*AercConfig, error) {
}
quit, _ := ParseBinding("<C-q>", ":quit<Enter>")
config.Bindings.AccountWizard.Add(quit)
if filters, err := file.GetSection("filters"); err == nil {
// TODO: Parse the filter more finely, e.g. parse the regex
for _, match := range filters.KeyStrings() {
cmd := filters.KeysHash()[match]
filter := FilterConfig{
Command: cmd,
Filter: match,
}
if strings.Contains(match, ",~") {
filter.FilterType = FILTER_HEADER
header := filter.Filter[:strings.Index(filter.Filter, ",")]
regex := filter.Filter[strings.Index(filter.Filter, "~")+1:]
filter.Header = strings.ToLower(header)
filter.Regex, err = regexp.Compile(regex)
if err != nil {
panic(err)
}
} else if strings.ContainsRune(match, ',') {
filter.FilterType = FILTER_HEADER
header := filter.Filter[:strings.Index(filter.Filter, ",")]
value := filter.Filter[strings.Index(filter.Filter, ",")+1:]
filter.Header = strings.ToLower(header)
filter.Regex, err = regexp.Compile(regexp.QuoteMeta(value))
} else {
filter.FilterType = FILTER_MIMETYPE
}
config.Filters = append(config.Filters, filter)
}
}
if viewer, err := file.GetSection("viewer"); err == nil {
if err := viewer.MapTo(&config.Viewer); err != nil {
return nil, err
}
for key, val := range viewer.KeysHash() {
switch key {
case "alternatives":
config.Viewer.Alternatives = strings.Split(val, ",")
}
}
}
if compose, err := file.GetSection("compose"); err == nil {
if err := compose.MapTo(&config.Compose); err != nil {
return nil, err
}
}
if ui, err := file.GetSection("ui"); err == nil {
if err := ui.MapTo(&config.Ui); err != nil {
return nil, err
}
if err = config.LoadConfig(file); err != nil {
return nil, err
}
if ui, err := file.GetSection("general"); err == nil {
if err := ui.MapTo(&config.General); err != nil {
return nil, err
}
}
accountsPath := path.Join(*root, "accounts.conf")
if accounts, err := loadAccountConfig(accountsPath); err != nil {
return nil, err