summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--commands/account/compose.go4
-rw-r--r--commands/msg/forward.go4
-rw-r--r--commands/msg/reply.go6
-rw-r--r--commands/msg/unsubscribe.go1
-rw-r--r--config/config.go2
-rw-r--r--doc/aerc-config.5.scd8
-rw-r--r--widgets/aerc.go2
-rw-r--r--widgets/compose.go66
8 files changed, 84 insertions, 9 deletions
diff --git a/commands/account/compose.go b/commands/account/compose.go
index ad48fe6..039eb92 100644
--- a/commands/account/compose.go
+++ b/commands/account/compose.go
@@ -29,7 +29,7 @@ func (Compose) Execute(aerc *widgets.Aerc, args []string) error {
 		return err
 	}
 	acct := aerc.SelectedAccount()
-	composer := widgets.NewComposer(
+	composer := widgets.NewComposer(aerc,
 		aerc.Config(), acct.AccountConfig(), acct.Worker(), nil)
 	tab := aerc.NewTab(composer, "New email")
 	composer.OnHeaderChange("Subject", func(subject string) {
@@ -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..494072d 100644
--- a/commands/msg/forward.go
+++ b/commands/msg/forward.go
@@ -69,7 +69,7 @@ func (forward) Execute(aerc *widgets.Aerc, args []string) error {
 		"To":      to,
 		"Subject": subject,
 	}
-	composer := widgets.NewComposer(aerc.Config(), acct.AccountConfig(),
+	composer := widgets.NewComposer(aerc, aerc.Config(), acct.AccountConfig(),
 		acct.Worker(), defaults)
 
 	addTab := func() {
@@ -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 7c40e97..9ef7a3b 100644
--- a/commands/msg/reply.go
+++ b/commands/msg/reply.go
@@ -116,8 +116,8 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {
 		"In-Reply-To": msg.Envelope.MessageId,
 	}
 
-	composer := widgets.NewComposer(
-		aerc.Config(), acct.AccountConfig(), acct.Worker(), defaults)
+	composer := widgets.NewComposer(aerc, aerc.Config(),
+		acct.AccountConfig(), acct.Worker(), defaults)
 
 	if args[0] == "reply" {
 		composer.FocusTerminal()
@@ -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/commands/msg/unsubscribe.go b/commands/msg/unsubscribe.go
index f18da07..15a9411 100644
--- a/commands/msg/unsubscribe.go
+++ b/commands/msg/unsubscribe.go
@@ -88,6 +88,7 @@ func unsubscribeMailto(aerc *widgets.Aerc, u *url.URL) error {
 		"Subject": u.Query().Get("subject"),
 	}
 	composer := widgets.NewComposer(
+		aerc,
 		aerc.Config(),
 		acct.AccountConfig(),
 		acct.Worker(),
diff --git a/config/config.go b/config/config.go
index 738fd1d..eeaf937 100644
--- a/config/config.go
+++ b/config/config.go
@@ -55,6 +55,8 @@ type AccountConfig struct {
 	Params          map[string]string
 	Outgoing        string
 	OutgoingCredCmd string
+	SignatureFile   string
+	SignatureCmd    string
 }
 
 type BindingConfig struct {
diff --git a/doc/aerc-config.5.scd b/doc/aerc-config.5.scd
index d422e5d..91b444a 100644
--- a/doc/aerc-config.5.scd
+++ b/doc/aerc-config.5.scd
@@ -297,6 +297,14 @@ 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-file*
+	Specifies the file to read in order to obtain the signature to be added
+	to emails sent from this account.
+
+*signature-cmd*
+	Specifies the command to execute in *sh* in order to obtain the
+	signature to be added to emails sent from this account. If the command
+	fails then *signature-file* is used instead.
 
 # BINDS.CONF
 
diff --git a/widgets/aerc.go b/widgets/aerc.go
index fe3c1e2..8671c87 100644
--- a/widgets/aerc.go
+++ b/widgets/aerc.go
@@ -430,7 +430,7 @@ func (aerc *Aerc) Mailto(addr *url.URL) error {
 			defaults[header] = strings.Join(vals, ",")
 		}
 	}
-	composer := NewComposer(aerc.Config(),
+	composer := NewComposer(aerc, aerc.Config(),
 		acct.AccountConfig(), acct.Worker(), defaults)
 	composer.FocusSubject()
 	title := "New email"
diff --git a/widgets/compose.go b/widgets/compose.go
index 0e7f09e..22c58da 100644
--- a/widgets/compose.go
+++ b/widgets/compose.go
@@ -2,6 +2,8 @@ package widgets
 
 import (
 	"bufio"
+	"bytes"
+	"fmt"
 	"io"
 	"io/ioutil"
 	"mime"
@@ -17,6 +19,7 @@ import (
 	"github.com/emersion/go-message/mail"
 	"github.com/gdamore/tcell"
 	"github.com/mattn/go-runewidth"
+	"github.com/mitchellh/go-homedir"
 	"github.com/pkg/errors"
 
 	"git.sr.ht/~sircmpwn/aerc/config"
@@ -29,6 +32,7 @@ type Composer struct {
 
 	acct   *config.AccountConfig
 	config *config.AercConfig
+	aerc   *Aerc
 
 	defaults    map[string]string
 	editor      *Terminal
@@ -48,7 +52,7 @@ type Composer struct {
 	width int
 }
 
-func NewComposer(conf *config.AercConfig,
+func NewComposer(aerc *Aerc, conf *config.AercConfig,
 	acct *config.AccountConfig, worker *types.Worker, defaults map[string]string) *Composer {
 
 	if defaults == nil {
@@ -68,6 +72,7 @@ func NewComposer(conf *config.AercConfig,
 	}
 
 	c := &Composer{
+		aerc:     aerc,
 		editors:  editors,
 		acct:     acct,
 		config:   conf,
@@ -80,6 +85,8 @@ func NewComposer(conf *config.AercConfig,
 		focusable: focusable,
 	}
 
+	c.AddSignature()
+
 	c.updateGrid()
 	c.ShowTerminal()
 
@@ -140,6 +147,63 @@ 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() {
+	var signature []byte
+	if c.acct.SignatureCmd != "" {
+		var err error
+		signature, err = c.readSignatureFromCmd()
+		if err != nil {
+			signature = c.readSignatureFromFile()
+		}
+	} else {
+		signature = c.readSignatureFromFile()
+	}
+	c.AppendContents(bytes.NewReader(signature))
+}
+
+func (c *Composer) readSignatureFromCmd() ([]byte, error) {
+	sigCmd := c.acct.SignatureCmd
+	cmd := exec.Command("sh", "-c", sigCmd)
+	signature, err := cmd.Output()
+	if err != nil {
+		return nil, err
+	}
+	return signature, nil
+}
+
+func (c *Composer) readSignatureFromFile() []byte {
+	sigFile := c.acct.SignatureFile
+	if sigFile == "" {
+		return nil
+	}
+	sigFile, err := homedir.Expand(sigFile)
+	if err != nil {
+		return nil
+	}
+	signature, err := ioutil.ReadFile(sigFile)
+	if err != nil {
+		c.aerc.PushError(fmt.Sprintf(" Error loading signature from file: %v", sigFile))
+		return nil
+	}
+	return signature
+}
+
 func (c *Composer) FocusTerminal() *Composer {
 	if c.editor == nil {
 		return c