aboutsummaryrefslogblamecommitdiffstats
path: root/config/config.go
blob: 2e45b0c810f36257b74f754284a6a2bdcde7f7a3 (plain) (tree)
1
2
3
4
5
6
7
8
9


              
                
             
             
            
              
                 
                 


                               
                                         

 














                                                                 

                    
                     





                                  
                                   





                                                



                                                   



                                                                               






                                                                        
                                                                  



                                                                   


                                       
                                                                    
                                                                  
                                                              


                                                            

 
                                   
 


                                                       
                                              



                                  
                       
                                        
                                                             



                               


                          
                                                              





                          
                                                             



                                                            
                                                 


                                                                        
                                                                                   
                                                                           
                                  


                 


                                                     
                       
                          

                                 
 

                                                  
         

                                                  
         

                                                  
         

                                                     
         

                                                 
         

                                                     
         

                                                  
         

                                                   
         

                                             
         

                                                    
         

                                                           
         

                                                 
         
 
                  
 
 







                                            
 







                                             







                                                               
package config

import (
	"errors"
	"fmt"
	"log"
	"os"
	"path"
	"strings"
	"unicode"

	"github.com/go-ini/ini"
	"github.com/kyoh86/xdg"
	"github.com/mitchellh/go-homedir"
)

// 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)
}

// Set at build time
var shareDir string
var libexecDir string

func buildDefaultDirs() []string {
	var defaultDirs []string

	prefixes := []string{
		xdg.ConfigHome(),
		"~/.local/libexec",
		xdg.DataHome(),
	}

	// Add XDG_CONFIG_HOME and XDG_DATA_HOME
	for _, v := range prefixes {
		if v != "" {
			v, err := homedir.Expand(v)
			if err != nil {
				log.Println(err)
			}
			defaultDirs = append(defaultDirs, path.Join(v, "aerc"))
		}
	}

	// Add custom buildtime dirs
	if libexecDir != "" && libexecDir != "/usr/local/libexec/aerc" {
		libexecDir, err := homedir.Expand(libexecDir)
		if err == nil {
			defaultDirs = append(defaultDirs, libexecDir)
		}
	}
	if shareDir != "" && shareDir != "/usr/local/share/aerc" {
		shareDir, err := homedir.Expand(shareDir)
		if err == nil {
			defaultDirs = append(defaultDirs, shareDir)
		}
	}

	// Add fixed fallback locations
	defaultDirs = append(defaultDirs, "/usr/local/libexec/aerc")
	defaultDirs = append(defaultDirs, "/usr/local/share/aerc")
	defaultDirs = append(defaultDirs, "/usr/libexec/aerc")
	defaultDirs = append(defaultDirs, "/usr/share/aerc")

	return defaultDirs
}

var SearchDirs = buildDefaultDirs()

func installTemplate(root, name string) error {
	var err error
	if _, err = os.Stat(root); os.IsNotExist(err) {
		err = os.MkdirAll(root, 0o755)
		if err != nil {
			return err
		}
	}
	var data []byte
	for _, dir := range SearchDirs {
		data, err = os.ReadFile(path.Join(dir, name))
		if err == nil {
			break
		}
	}
	if err != nil {
		return err
	}
	err = os.WriteFile(path.Join(root, name), data, 0o644)
	if err != nil {
		return err
	}
	return nil
}

func LoadConfigFromFile(root *string, accts []string) error {
	if root == nil {
		_root := path.Join(xdg.ConfigHome(), "aerc")
		root = &_root
	}
	filename := path.Join(*root, "aerc.conf")

	// if it doesn't exist copy over the template, then load
	if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) {
		fmt.Printf("%s not found, installing the system default", filename)
		if err := installTemplate(*root, "aerc.conf"); err != nil {
			return err
		}
	}

	file, err := ini.LoadSources(ini.LoadOptions{
		KeyValueDelimiters: "=",
	}, filename)
	if err != nil {
		return err
	}
	file.NameMapper = mapName

	if err := parseGeneral(file); err != nil {
		return err
	}
	if err := parseFilters(file); err != nil {
		return err
	}
	if err := parseCompose(file); err != nil {
		return err
	}
	if err := parseConverters(file); err != nil {
		return err
	}
	if err := parseViewer(file); err != nil {
		return err
	}
	if err := parseStatusline(file); err != nil {
		return err
	}
	if err := parseOpeners(file); err != nil {
		return err
	}
	if err := parseTriggers(file); err != nil {
		return err
	}
	if err := parseUi(file); err != nil {
		return err
	}
	if err := parseTemplates(file); err != nil {
		return err
	}
	if err := parseAccounts(*root, accts); err != nil {
		return err
	}
	if err := parseBinds(*root); err != nil {
		return err
	}

	return nil
}

func parseLayout(layout string) [][]string {
	rows := strings.Split(layout, ",")
	l := make([][]string, len(rows))
	for i, r := range rows {
		l[i] = strings.Split(r, "|")
	}
	return l
}

func contains(list []string, v string) bool {
	for _, item := range list {
		if item == v {
			return true
		}
	}
	return false
}

// warning message related to configuration (deprecation, etc.)
type Warning struct {
	Title string
	Body  string
}

var Warnings []Warning