~sircmpwn/aerc

Add signatures v1 PROPOSED

I would rather use a signature file than a literal string in the config.
I'd love if this feature could not only read from a file, but also allow
dynamic signatures via a callable script, and potentially allow for
different signature "files" for different accounts, or to different
users.  I have something like this in Mutt.

I understand this wouldn't be a simple patch though, but using a file
would lend a few more options at least.
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/%3C20190907213340.872-1-dev%40jeffas.io%3E/mbox | git am -3
Learn more about email & git

[PATCH] Add signatures Export this patch

This adds the ability for a per-account signature in the accounts.conf
config file. The signature is added to emails in the editor at the
bottom of the email. This includes when forwarding, replying to, and
composing emails.

There is a config option and this has parsing associated when set. This
ensures newlines and some other escape sequences work as expected.

The option is also documented in the man page.
---
 commands/account/compose.go |  2 +-
 commands/msg/forward.go     |  2 +-
 commands/msg/reply.go       |  2 +-
 config/config.go            | 15 +++++++++++++++
 doc/aerc-config.5.scd       |  3 +++
 widgets/compose.go          | 23 +++++++++++++++++++++++
 6 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/commands/account/compose.go b/commands/account/compose.go
index ad48fe6..c8358a7 100644
--- a/commands/account/compose.go
+++ b/commands/account/compose.go
@@ -40,7 +40,7 @@ func (Compose) Execute(aerc *widgets.Aerc, args []string) error {
 		}
 		tab.Content.Invalidate()
 	})
-	go composer.SetContents(strings.NewReader(body))
+	go composer.PrependContents(strings.NewReader(body))
 	return nil
 }

diff --git a/commands/msg/forward.go b/commands/msg/forward.go
index b925a49..c443213 100644
--- a/commands/msg/forward.go
+++ b/commands/msg/forward.go
@@ -154,7 +154,7 @@ func forwardBodyPart(store *lib.MessageStore, composer *widgets.Composer,

 		pipeout, pipein := io.Pipe()
 		scanner := bufio.NewScanner(part.Body)
-		go composer.SetContents(pipeout)
+		go composer.PrependContents(pipeout)
 		// TODO: Let user customize the date format used here
 		io.WriteString(pipein, fmt.Sprintf("Forwarded message from %s on %s:\n\n",
 			msg.Envelope.From[0].Name,
diff --git a/commands/msg/reply.go b/commands/msg/reply.go
index 34d03d5..ade4bdc 100644
--- a/commands/msg/reply.go
+++ b/commands/msg/reply.go
@@ -170,7 +170,7 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {

 			pipeout, pipein := io.Pipe()
 			scanner := bufio.NewScanner(part.Body)
-			go composer.SetContents(pipeout)
+			go composer.PrependContents(pipeout)
 			// TODO: Let user customize the date format used here
 			io.WriteString(pipein, fmt.Sprintf("On %s %s wrote:\n",
 				msg.Envelope.Date.Format("Mon Jan 2, 2006 at 3:04 PM"),
diff --git a/config/config.go b/config/config.go
index 06caec1..f555dd6 100644
--- a/config/config.go
+++ b/config/config.go
@@ -54,6 +54,7 @@ type AccountConfig struct {
 	Params          map[string]string
 	Outgoing        string
 	OutgoingCredCmd string
+	Signature       string
 }

 type BindingConfig struct {
@@ -180,6 +181,20 @@ func loadAccountConfig(path string) ([]AccountConfig, error) {
 		}
 		account.Outgoing = outgoing

+		if account.Signature != "" {
+			type conversion struct {
+				o string
+				n string
+			}
+			conversions := []conversion{
+				conversion{o: "\\n", n: "\n"},
+				conversion{o: "\\r", n: "\r"},
+				conversion{o: "\\t", n: "\t"}}
+			for _, conversion := range conversions {
+				account.Signature = strings.ReplaceAll(account.Signature, conversion.o, conversion.n)
+			}
+		}
+
 		accounts = append(accounts, account)
 	}
 	return accounts, nil
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index 9257bde..51c5c2f 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -281,6 +281,9 @@ Note that many of these configuration options are written for you, such as
 	Specifies an optional command that is run to get the source account's
 	password. See each protocol's man page for more details.

+*signature*
+	Specifies the signature to be added to emails sent from this account.
+

 # BINDS.CONF

diff --git a/widgets/compose.go b/widgets/compose.go
index bd4301a..fa9e544 100644
--- a/widgets/compose.go
+++ b/widgets/compose.go
@@ -2,6 +2,7 @@ package widgets

 import (
 	"bufio"
+	"bytes"
 	"io"
 	"io/ioutil"
 	"mime"
@@ -78,6 +79,8 @@ func NewComposer(conf *config.AercConfig,
 		focusable: focusable,
 	}

+	c.AddSignature()
+
 	c.updateGrid()
 	c.ShowTerminal()

@@ -138,6 +141,26 @@ func (c *Composer) SetContents(reader io.Reader) *Composer {
 	return c
 }

+func (c *Composer) PrependContents(reader io.Reader) {
+	buf := bytes.NewBuffer(nil)
+	c.email.Seek(0, io.SeekStart)
+	io.Copy(buf, c.email)
+	c.email.Seek(0, io.SeekStart)
+	io.Copy(c.email, reader)
+	io.Copy(c.email, buf)
+	c.email.Sync()
+}
+
+func (c *Composer) AppendContents(reader io.Reader) {
+	c.email.Seek(0, io.SeekEnd)
+	io.Copy(c.email, reader)
+	c.email.Sync()
+}
+
+func (c *Composer) AddSignature() {
+	c.AppendContents(strings.NewReader(c.acct.Signature))
+}
+
 func (c *Composer) FocusTerminal() *Composer {
 	if c.editor == nil {
 		return c
--
2.23.0
I would rather use a signature file than a literal string in the config.
View this thread in the archives