~sircmpwn/aerc

Add Templates v2 PROPOSED

Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/aerc/%3C20191008160704.231376-1-sri%40vathsan.com%3E/mbox | git am -3
Learn more about email & git

[PATCH v2] Add Templates Export this patch

This adds the ability to load templates into the body of the
email. When compose is called with '-T' flag, the default template
or the template with the name passed as value is used to populate
the body of the email.

There are two new configs options for accounts.conf: TemplateDir
and DefaultTemplate. Template Dir specifies the directory containing
the templates.DefaultTemplate specifies the template that is loaded
if no template name is provided.
---
Fixes the formatting issues pointed out by Jeffas in the first patch.
Also moved the logic to a lib file. This would help in the future
if we would like to implement template for the reply and forward
commands.

 commands/account/compose.go | 28 +++++++++++++++++++++++-----
 config/config.go            |  2 ++
 doc/aerc-config.5.scd       |  7 +++++++
 doc/aerc.1.scd              |  6 +++++-
 lib/template.go             | 24 ++++++++++++++++++++++++
 5 files changed, 61 insertions(+), 6 deletions(-)
 create mode 100644 lib/template.go

diff --git a/commands/account/compose.go b/commands/account/compose.go
index 039eb92363c6..a1c7d4e4c17f 100644
--- a/commands/account/compose.go
+++ b/commands/account/compose.go
@@ -5,6 +5,8 @@ import (
 	"regexp"
 	"strings"
 
+	"git.sr.ht/~sircmpwn/aerc/config"
+	"git.sr.ht/~sircmpwn/aerc/lib"
 	"git.sr.ht/~sircmpwn/aerc/widgets"
 	"git.sr.ht/~sircmpwn/getopt"
 )
@@ -24,11 +26,11 @@ func (Compose) Complete(aerc *widgets.Aerc, args []string) []string {
 }
 
 func (Compose) Execute(aerc *widgets.Aerc, args []string) error {
-	body, err := buildBody(args)
+	acct := aerc.SelectedAccount()
+	body, err := buildBody(args, acct.AccountConfig())
 	if err != nil {
 		return err
 	}
-	acct := aerc.SelectedAccount()
 	composer := widgets.NewComposer(aerc,
 		aerc.Config(), acct.AccountConfig(), acct.Worker(), nil)
 	tab := aerc.NewTab(composer, "New email")
@@ -44,9 +46,9 @@ func (Compose) Execute(aerc *widgets.Aerc, args []string) error {
 	return nil
 }
 
-func buildBody(args []string) (string, error) {
+func buildBody(args []string, acct *config.AccountConfig) (string, error) {
 	var body, headers string
-	opts, optind, err := getopt.Getopts(args, "H:")
+	opts, optind, err := getopt.Getopts(args, ":T:H:")
 	if err != nil {
 		return "", err
 	}
@@ -60,11 +62,27 @@ func buildBody(args []string) (string, error) {
 			} else {
 				headers += opt.Value + ":\n"
 			}
+		case 'T':
+			template, err := lib.ReadTemplateFromFile(opt.Value, acct.TemplateDir)
+			if err != nil {
+				return "", err
+			}
+			body = template
+		case ':':
+			if opt.Value == "T" {
+				template, err := lib.ReadTemplateFromFile(acct.DefaultTemplate, acct.TemplateDir)
+				if err != nil {
+					return "", err
+				}
+				body = template
+			} else {
+				return "", errors.New("Usage: compose [-H] [-T [template]] [body]")
+			}
 		}
 	}
 	posargs := args[optind:]
 	if len(posargs) > 1 {
-		return "", errors.New("Usage: compose [-H] [body]")
+		return "", errors.New("Usage: compose [-H] [-T [template]] [body]")
 	}
 	if len(posargs) == 1 {
 		body = posargs[0]
diff --git a/config/config.go b/config/config.go
index 133a7f4ed5ca..a7ca2f27aed2 100644
--- a/config/config.go
+++ b/config/config.go
@@ -59,6 +59,8 @@ type AccountConfig struct {
 	OutgoingCredCmd string
 	SignatureFile   string
 	SignatureCmd    string
+	TemplateDir     string
+	DefaultTemplate string
 }
 
 type BindingConfig struct {
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index f4f02f2cb0f3..2be0c425a5c1 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -320,6 +320,13 @@ Note that many of these configuration options are written for you, such as
 	signature to be added to emails sent from this account. If the command
 	fails then *signature-file* is used instead.
 
+*template-dir*
+	Specifies the location of the folder containing email templates.
+
+*default-template*
+	Specifies the name of the default template used when no template
+	is given as part of the compose command.
+
 # BINDS.CONF
 
 This file is used for configuring keybindings used in the aerc interactive
diff --git a/doc/aerc.1.scd b/doc/aerc.1.scd
index e76b5199162c..a697f05648f1 100644
--- a/doc/aerc.1.scd
+++ b/doc/aerc.1.scd
@@ -155,7 +155,7 @@ message list, the message in the message viewer, etc).
 *cf* <folder>
 	Change the folder shown in the message list.
 
-*compose* [-H] [<body>]
+*compose* [-H] [-T [template]] [<body>]
 	Open the compose window to send a new email. The new email will be sent with
 	the current account's outgoing transport configuration. For details on
 	configuring outgoing mail delivery consult *aerc-config*(5).
@@ -164,6 +164,10 @@ message list, the message in the message viewer, etc).
 		Add the specified header to the message, e.g. 'compose -H "X-Custom: custom
 		value"'
 
+	*-T* [template]
+		Use the email template to populate the email body, e.g. 'compose -T template1'
+		If a template name is not provided, the default template is used.
+
 *filter* [options] <terms...>
 	Similar to *search*, but filters the displayed messages to only the search
 	results. See the documentation for *search* for more details.
diff --git a/lib/template.go b/lib/template.go
new file mode 100644
index 000000000000..4f1593624af0
--- /dev/null
+++ b/lib/template.go
@@ -0,0 +1,24 @@
+package lib
+
+import (
+	"errors"
+	"io/ioutil"
+	"path"
+
+	"github.com/mitchellh/go-homedir"
+)
+
+func ReadTemplateFromFile(templateName string, templateDir string)  (string, error) {
+	if templateDir == "" {
+		return "", errors.New("Template Directory is not set.")
+	}
+	templateFile, err := homedir.Expand(path.Join(templateDir, templateName))
+	if err != nil {
+		return "", errors.New("Error while expanding template path.")
+	}
+	template, err := ioutil.ReadFile(templateFile)
+	if err != nil {
+		return "", errors.New("Error while reading template.")
+	}
+	return string(template), nil
+}
-- 
2.23.0
View this thread in the archives