diff --git a/.gitignore b/.gitignore index 5d04c97..b4af105 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ /aerc.debug log raw.log -aerc.conf *.1 *.5 *.7 diff --git a/Makefile b/Makefile index a1973d2..9c8b921 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,6 @@ SHAREDIR?=$(PREFIX)/share/aerc MANDIR?=$(PREFIX)/share/man GO?=go GOFLAGS?= -LDFLAGS:=-X main.Prefix=$(PREFIX) -LDFLAGS+=-X main.ShareDir=$(SHAREDIR) LDFLAGS+=-X main.Version=$(VERSION) GOSRC:=$(shell find * -name '*.go') @@ -30,7 +28,7 @@ DOCS := \ aerc-templates.7 \ aerc-stylesets.7 -all: aerc aerc.conf $(DOCS) +all: aerc $(DOCS) aerc: $(GOSRC) $(GO) build $(GOFLAGS) -ldflags "$(LDFLAGS)" -o $@ @@ -47,9 +45,6 @@ checkfmt: exit 1; \ fi -aerc.conf: config/aerc.conf.in - sed -e 's:@SHAREDIR@:$(SHAREDIR):g' > $@ < config/aerc.conf.in - .PHONY: debug debug: aerc.debug @echo 'Run `./aerc.debug` and use this command in another terminal to attach a debugger:' @@ -73,9 +68,9 @@ doc: $(DOCS) RM?=rm -f clean: - $(RM) $(DOCS) aerc.conf aerc + $(RM) $(DOCS) aerc -install: $(DOCS) aerc aerc.conf +install: $(DOCS) aerc mkdir -m755 -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1 $(DESTDIR)$(MANDIR)/man5 $(DESTDIR)$(MANDIR)/man7 \ $(DESTDIR)$(SHAREDIR) $(DESTDIR)$(SHAREDIR)/filters $(DESTDIR)$(SHAREDIR)/templates $(DESTDIR)$(SHAREDIR)/stylesets install -m755 aerc $(DESTDIR)$(BINDIR)/aerc @@ -91,7 +86,7 @@ install: $(DOCS) aerc aerc.conf install -m644 aerc-templates.7 $(DESTDIR)$(MANDIR)/man7/aerc-templates.7 install -m644 aerc-stylesets.7 $(DESTDIR)$(MANDIR)/man7/aerc-stylesets.7 install -m644 config/accounts.conf $(DESTDIR)$(SHAREDIR)/accounts.conf - install -m644 aerc.conf $(DESTDIR)$(SHAREDIR)/aerc.conf + install -m644 config/aerc.conf $(DESTDIR)$(SHAREDIR)/aerc.conf install -m644 config/binds.conf $(DESTDIR)$(SHAREDIR)/binds.conf install -m755 filters/hldiff $(DESTDIR)$(SHAREDIR)/filters/hldiff install -m755 filters/html $(DESTDIR)$(SHAREDIR)/filters/html diff --git a/aerc.go b/aerc.go index 6467c61..555b3a3 100644 --- a/aerc.go +++ b/aerc.go @@ -86,10 +86,8 @@ func getCompletions(aerc *widgets.Aerc, cmd string) []string { return completions } -var ( - ShareDir string - Version string -) +// set at build time +var Version string func usage() { log.Fatal("Usage: aerc [-v] [mailto:...]") @@ -152,7 +150,7 @@ func main() { logger = log.New(logOut, "", log.LstdFlags) logger.Println("Starting up aerc") - conf, err := config.LoadConfigFromFile(nil, ShareDir, logger) + conf, err := config.LoadConfigFromFile(nil, logger) if err != nil { fmt.Fprintf(os.Stderr, "Failed to load config: %v\n", err) os.Exit(1) diff --git a/config/aerc.conf.in b/config/aerc.conf similarity index 90% rename from config/aerc.conf.in rename to config/aerc.conf index 98cd679..2c928f6 100644 --- a/config/aerc.conf.in +++ b/config/aerc.conf @@ -96,10 +96,16 @@ sort= next-message-on-delete=true # The directories where the stylesets are stored. It takes a colon-separated -# list of directories. +# list of directories. If this is unset or if a styleset cannot be found, the +# following paths will be used as a fallback in that order: # -# default: @SHAREDIR@/stylesets/ -stylesets-dirs=@SHAREDIR@/stylesets/ +# ~/.config/aerc/stylesets +# ~/.local/share/aerc/stylesets +# /usr/local/share/aerc/stylesets +# /usr/share/aerc/stylesets +# +# default: "" +stylesets-dirs= # Uncomment to use box-drawing characters for vertical and horizontal borders. # @@ -215,9 +221,8 @@ reply-to-self=true # You can also match on non-mimetypes, by prefixing with the header to match # against (non-case-sensitive) and a comma, e.g. subject,text will match a # subject which contains "text". Use header,~regex to match against a regex. -subject,~^\[PATCH=awk -f @SHAREDIR@/filters/hldiff -#text/html=@SHAREDIR@/filters/html -text/*=awk -f @SHAREDIR@/filters/plaintext +#subject,~^\[PATCH=colordiff +#text/html=pandoc -f html -t plain #image/*=catimg -w $(tput cols) - [triggers] @@ -236,10 +241,16 @@ new-email= # # The directories where the templates are stored. It takes a colon-separated -# list of directories. +# list of directories. If this is unset or if a template cannot be found, the +# following paths will be used as a fallback in that order: # -# default: @SHAREDIR@/templates/ -template-dirs=@SHAREDIR@/templates/ +# ~/.config/aerc/templates +# ~/.local/share/aerc/templates +# /usr/local/share/aerc/templates +# /usr/share/aerc/templates +# +# default: "" +template-dirs= # The default template to be used for new messages. # diff --git a/config/config.go b/config/config.go index 185a14c..f730fe4 100644 --- a/config/config.go +++ b/config/config.go @@ -296,14 +296,28 @@ func parseCredential(cred, command string) (string, error) { return u.String(), nil } -func installTemplate(root, sharedir, name string) error { - if _, err := os.Stat(root); os.IsNotExist(err) { - err := os.MkdirAll(root, 0755) +var defaultDirs []string = []string{ + path.Join(xdg.ConfigHome(), "aerc"), + path.Join(xdg.DataHome(), "aerc"), + "/usr/local/share/aerc", + "/usr/share/aerc", +} + +func installTemplate(root, name string) error { + var err error + if _, err = os.Stat(root); os.IsNotExist(err) { + err = os.MkdirAll(root, 0755) if err != nil { return err } } - data, err := ioutil.ReadFile(path.Join(sharedir, name)) + var data []byte + for _, dir := range defaultDirs { + data, err = ioutil.ReadFile(path.Join(dir, name)) + if err == nil { + break + } + } if err != nil { return err } @@ -446,20 +460,30 @@ func (config *AercConfig) LoadConfig(file *ini.File) error { if templateDirs != "" { config.Templates.TemplateDirs = strings.Split(templateDirs, ":") } - for key, val := range templatesSec.KeysHash() { - if key == "template-dirs" { - continue - } - // we want to fail during startup if the templates are not ok - // hence we do a dummy execute here - _, err := templates.ParseTemplateFromFile( - val, config.Templates.TemplateDirs, templates.DummyData()) - if err != nil { - return err - } - } } + // append default paths to template-dirs and styleset-dirs + for _, dir := range defaultDirs { + config.Ui.StyleSetDirs = append( + config.Ui.StyleSetDirs, path.Join(dir, "stylesets"), + ) + config.Templates.TemplateDirs = append( + config.Templates.TemplateDirs, path.Join(dir, "templates"), + ) + } + + // we want to fail during startup if the templates are not ok + // hence we do dummy executes here + t := config.Templates + if err := templates.CheckTemplate(t.NewMessage, t.TemplateDirs); err != nil { + return err + } + if err := templates.CheckTemplate(t.QuotedReply, t.TemplateDirs); err != nil { + return err + } + if err := templates.CheckTemplate(t.Forwards, t.TemplateDirs); err != nil { + return err + } if err := config.Ui.loadStyleSet( config.Ui.StyleSetDirs); err != nil { return err @@ -506,7 +530,7 @@ func validateBorderChars(section *ini.Section, config *UIConfig) error { return nil } -func LoadConfigFromFile(root *string, sharedir string, logger *log.Logger) (*AercConfig, error) { +func LoadConfigFromFile(root *string, logger *log.Logger) (*AercConfig, error) { if root == nil { _root := path.Join(xdg.ConfigHome(), "aerc") root = &_root @@ -519,7 +543,7 @@ func LoadConfigFromFile(root *string, sharedir string, logger *log.Logger) (*Aer // if it doesn't exist copy over the template, then load if _, err := os.Stat(filename); errors.Is(err, os.ErrNotExist) { - if err := installTemplate(*root, sharedir, "aerc.conf"); err != nil { + if err := installTemplate(*root, "aerc.conf"); err != nil { return nil, err } } @@ -572,7 +596,7 @@ func LoadConfigFromFile(root *string, sharedir string, logger *log.Logger) (*Aer NextMessageOnDelete: true, CompletionDelay: 250 * time.Millisecond, CompletionPopovers: true, - StyleSetDirs: []string{path.Join(sharedir, "stylesets")}, + StyleSetDirs: []string{}, StyleSetName: "default", // border defaults BorderCharVertical: ' ', @@ -602,7 +626,7 @@ func LoadConfigFromFile(root *string, sharedir string, logger *log.Logger) (*Aer }, Templates: TemplateConfig{ - TemplateDirs: []string{path.Join(sharedir, "templates")}, + TemplateDirs: []string{}, NewMessage: "new_message", QuotedReply: "quoted_reply", Forwards: "forward_as_body", @@ -636,7 +660,7 @@ func LoadConfigFromFile(root *string, sharedir string, logger *log.Logger) (*Aer filename = path.Join(*root, "binds.conf") binds, err := ini.Load(filename) if err != nil { - if err := installTemplate(*root, sharedir, "binds.conf"); err != nil { + if err := installTemplate(*root, "binds.conf"); err != nil { return nil, err } if binds, err = ini.Load(filename); err != nil { diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd index ce53f9b..1992b59 100644 --- a/doc/aerc-config.5.scd +++ b/doc/aerc-config.5.scd @@ -208,10 +208,18 @@ These options are configured in the *[ui]* section of aerc.conf. Default: spaces *stylesets-dirs* - The directories where the stylesets are stored. The config takes a - colon-separated list of dirs. + The directories where the stylesets are stored. The config takes + a colon-separated list of dirs. If this is unset or if a styleset cannot + be found, the following paths will be used as a fallback in that order: - Default: "/usr/share/aerc/stylesets" + ``` + ~/.config/aerc/stylesets + ~/.local/share/aerc/stylesets + /usr/local/share/aerc/stylesets + /usr/share/aerc/stylesets + ``` + + Default: "" *styleset-name* The name of the styleset to be used to style the ui elements. The @@ -398,10 +406,18 @@ _/usr/share/aerc/templates_). These options are configured in the *[templates]* section of aerc.conf. *template-dirs* - The directory where the templates are stored. The config takes a - colon-separated list of dirs. + The directory where the templates are stored. The config takes + a colon-separated list of dirs. If this is unset or if a template cannot + be found, the following paths will be used as a fallback in that order: - Default: "/usr/share/aerc/templates" + ``` + ~/.config/aerc/templates + ~/.local/share/aerc/templates + /usr/local/share/aerc/templates + /usr/share/aerc/templates + ``` + + Default: "" *new-message* The default template to be used for new messages. diff --git a/lib/templates/template.go b/lib/templates/template.go index 6d66d8e..9c71c46 100644 --- a/lib/templates/template.go +++ b/lib/templates/template.go @@ -227,3 +227,11 @@ func ParseTemplateFromFile(templateName string, templateDirs []string, data inte } return &body, nil } + +func CheckTemplate(templateName string, templateDirs []string) error { + if templateName != "" { + _, err := ParseTemplateFromFile(templateName, templateDirs, DummyData()) + return err + } + return nil +}