aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2023-07-04 12:18:55 +0200
committerRobin Jarry <robin@jarry.cc>2023-07-17 10:23:36 +0200
commit624fb681a8ceeceecb898627503bf6cf73c2c6e8 (patch)
tree68cc73e04e0c2100795b9bfb0720bbc8f28f431f
parent21f14c550a44a4b9207ca27b81976f92a7d26784 (diff)
downloadaerc-624fb681a8ceeceecb898627503bf6cf73c2c6e8.tar.gz
aerc-624fb681a8ceeceecb898627503bf6cf73c2c6e8.zip
compose: only allow setting content at creation
Add a parameter for the initial value of the body to be inserted *before* the signature when composing a message. Make AppendContents and SetContents private methods to ensure there is no other way to change the composer contents from the outside after creation. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Bence Ferdinandy <bence@ferdinandy.com> Tested-by: Koni Marti <koni.marti@gmail.com>
-rw-r--r--commands/account/compose.go8
-rw-r--r--commands/account/recover.go9
-rw-r--r--commands/msg/forward.go2
-rw-r--r--commands/msg/invite.go4
-rw-r--r--commands/msg/recall.go48
-rw-r--r--commands/msg/reply.go2
-rw-r--r--commands/msg/unsubscribe.go2
-rw-r--r--widgets/aerc.go4
-rw-r--r--widgets/compose.go40
9 files changed, 45 insertions, 74 deletions
diff --git a/commands/account/compose.go b/commands/account/compose.go
index a8b16791..3c603f34 100644
--- a/commands/account/compose.go
+++ b/commands/account/compose.go
@@ -11,7 +11,6 @@ import (
"github.com/emersion/go-message/mail"
"git.sr.ht/~rjarry/aerc/config"
- "git.sr.ht/~rjarry/aerc/log"
"git.sr.ht/~rjarry/aerc/widgets"
"git.sr.ht/~sircmpwn/getopt"
)
@@ -53,16 +52,11 @@ func (Compose) Execute(aerc *widgets.Aerc, args []string) error {
composer, err := widgets.NewComposer(aerc, acct,
acct.AccountConfig(), acct.Worker(),
- template, &headers, nil)
+ template, &headers, nil, msg.Body)
if err != nil {
return err
}
composer.Tab = aerc.NewTab(composer, "New email")
- go func() {
- defer log.PanicHandler()
-
- composer.AppendContents(msg.Body)
- }()
return nil
}
diff --git a/commands/account/recover.go b/commands/account/recover.go
index 350daf17..3e4e9136 100644
--- a/commands/account/recover.go
+++ b/commands/account/recover.go
@@ -8,7 +8,6 @@ import (
"path/filepath"
"git.sr.ht/~rjarry/aerc/commands"
- "git.sr.ht/~rjarry/aerc/log"
"git.sr.ht/~rjarry/aerc/widgets"
"git.sr.ht/~sircmpwn/getopt"
)
@@ -85,17 +84,11 @@ func (r Recover) Execute(aerc *widgets.Aerc, args []string) error {
composer, err := widgets.NewComposer(aerc, acct,
acct.AccountConfig(), acct.Worker(),
- "", nil, nil)
+ "", nil, nil, bytes.NewReader(data))
if err != nil {
return err
}
-
composer.Tab = aerc.NewTab(composer, "Recovered")
- go func() {
- defer log.PanicHandler()
-
- composer.AppendContents(bytes.NewReader(data))
- }()
// remove file if force flag is set
if force {
diff --git a/commands/msg/forward.go b/commands/msg/forward.go
index 92575abd..ed0043fe 100644
--- a/commands/msg/forward.go
+++ b/commands/msg/forward.go
@@ -100,7 +100,7 @@ func (forward) Execute(aerc *widgets.Aerc, args []string) error {
addTab := func() (*widgets.Composer, error) {
composer, err := widgets.NewComposer(aerc, acct,
- acct.AccountConfig(), acct.Worker(), template, h, &original)
+ acct.AccountConfig(), acct.Worker(), template, h, &original, nil)
if err != nil {
aerc.PushError("Error: " + err.Error())
return nil, err
diff --git a/commands/msg/invite.go b/commands/msg/invite.go
index 774c4a69..6273d520 100644
--- a/commands/msg/invite.go
+++ b/commands/msg/invite.go
@@ -138,13 +138,11 @@ func (invite) Execute(aerc *widgets.Aerc, args []string) error {
addTab := func(cr *calendar.Reply) error {
composer, err := widgets.NewComposer(aerc, acct,
- acct.AccountConfig(), acct.Worker(), "", h, &original)
+ acct.AccountConfig(), acct.Worker(), "", h, &original, cr.PlainText)
if err != nil {
aerc.PushError("Error: " + err.Error())
return err
}
-
- composer.SetContents(cr.PlainText)
err = composer.AppendPart(cr.MimeType, cr.Params, cr.CalendarText)
if err != nil {
return fmt.Errorf("failed to write invitation: %w", err)
diff --git a/commands/msg/recall.go b/commands/msg/recall.go
index 4eda8339..71f8b8a5 100644
--- a/commands/msg/recall.go
+++ b/commands/msg/recall.go
@@ -7,14 +7,11 @@ import (
"sync"
"time"
- "github.com/emersion/go-message"
_ "github.com/emersion/go-message/charset"
- "github.com/emersion/go-message/mail"
"github.com/pkg/errors"
"git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/log"
- "git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets"
"git.sr.ht/~rjarry/aerc/worker/types"
"git.sr.ht/~sircmpwn/getopt"
@@ -71,17 +68,7 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error {
}
log.Debugf("Recalling message <%s>", msgInfo.Envelope.MessageId)
- composer, err := widgets.NewComposer(aerc, acct,
- acct.AccountConfig(), acct.Worker(), "", msgInfo.RFC822Headers,
- nil)
- if err != nil {
- return errors.Wrap(err, "Cannot open a new composer")
- }
-
- // focus the terminal since the header fields are likely already done
- composer.FocusTerminal()
-
- addTab := func() {
+ addTab := func(composer *widgets.Composer) {
subject := msgInfo.Envelope.Subject
if subject == "" {
subject = "Recalled email"
@@ -136,39 +123,19 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error {
aerc.PushError(err.Error())
return
}
-
- var (
- path []int
- part *models.BodyStructure
- )
+ var path []int
if len(msg.BodyStructure().Parts) != 0 {
path = lib.FindPlaintext(msg.BodyStructure(), path)
}
- part, err = msg.BodyStructure().PartAtIndex(path)
- if part == nil || err != nil {
- part = msg.BodyStructure()
- }
msg.FetchBodyPart(path, func(reader io.Reader) {
- header := message.Header{}
- header.SetText(
- "Content-Transfer-Encoding", part.Encoding)
- header.SetContentType(part.MIMEType, part.Params)
- header.SetText("Content-Description", part.Description)
- entity, err := message.New(header, reader)
+ composer, err := widgets.NewComposer(aerc, acct,
+ acct.AccountConfig(), acct.Worker(),
+ "", msgInfo.RFC822Headers, nil, reader)
if err != nil {
aerc.PushError(err.Error())
- addTab()
return
}
- mreader := mail.NewReader(entity)
- part, err := mreader.NextPart()
- if err != nil {
- aerc.PushError(err.Error())
- addTab()
- return
- }
- composer.SetContents(part.Body)
if md := msg.MessageDetails(); md != nil {
if md.IsEncrypted {
composer.SetEncrypt(md.IsEncrypted)
@@ -180,7 +147,6 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error {
}
}
}
- addTab()
// add attachements if present
var mu sync.Mutex
@@ -210,6 +176,10 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error {
}
})
}
+
+ // focus the terminal since the header fields are likely already done
+ composer.FocusTerminal()
+ addTab(composer)
})
})
diff --git a/commands/msg/reply.go b/commands/msg/reply.go
index 2b9f5d4f..8cdb50d4 100644
--- a/commands/msg/reply.go
+++ b/commands/msg/reply.go
@@ -176,7 +176,7 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {
addTab := func() error {
composer, err := widgets.NewComposer(aerc, acct,
acct.AccountConfig(), acct.Worker(), template, h,
- &original)
+ &original, nil)
if err != nil {
aerc.PushError("Error: " + err.Error())
return err
diff --git a/commands/msg/unsubscribe.go b/commands/msg/unsubscribe.go
index 5fce7ece..cefa69cb 100644
--- a/commands/msg/unsubscribe.go
+++ b/commands/msg/unsubscribe.go
@@ -154,11 +154,11 @@ func unsubscribeMailto(aerc *widgets.Aerc, u *url.URL) error {
"",
h,
nil,
+ strings.NewReader(u.Query().Get("body")),
)
if err != nil {
return err
}
- composer.SetContents(strings.NewReader(u.Query().Get("body")))
composer.Tab = aerc.NewTab(composer, "unsubscribe")
composer.FocusTerminal()
return nil
diff --git a/widgets/aerc.go b/widgets/aerc.go
index 85ce686b..8f744b4c 100644
--- a/widgets/aerc.go
+++ b/widgets/aerc.go
@@ -734,11 +734,11 @@ func (aerc *Aerc) Mailto(addr *url.URL) error {
defer ui.Invalidate()
composer, err := NewComposer(aerc, acct,
- acct.AccountConfig(), acct.Worker(), template, h, nil)
+ acct.AccountConfig(), acct.Worker(), template, h, nil,
+ strings.NewReader(body))
if err != nil {
return err
}
- composer.SetContents(strings.NewReader(body))
composer.FocusEditor("subject")
title := "New email"
if subject != "" {
diff --git a/widgets/compose.go b/widgets/compose.go
index 43657a29..c4a93d83 100644
--- a/widgets/compose.go
+++ b/widgets/compose.go
@@ -71,7 +71,7 @@ type Composer struct {
func NewComposer(
aerc *Aerc, acct *AccountView, acctConfig *config.AccountConfig,
worker *types.Worker, template string,
- h *mail.Header, orig *models.OriginalMail,
+ h *mail.Header, orig *models.OriginalMail, body io.Reader,
) (*Composer, error) {
if h == nil {
h = new(mail.Header)
@@ -100,7 +100,7 @@ func NewComposer(
data.SetAccount(acct.acct)
data.SetFolder(acct.Directories().SelectedDirectory())
data.SetHeaders(h, orig)
- if err := c.AddTemplate(template, data.Data()); err != nil {
+ if err := c.addTemplate(template, data.Data(), body); err != nil {
return nil, err
}
c.AddSignature()
@@ -428,7 +428,7 @@ func (c *Composer) updateCrypto() error {
// Note: this does not reload the editor. You must call this before the first
// Draw() call.
-func (c *Composer) SetContents(reader io.Reader) *Composer {
+func (c *Composer) setContents(reader io.Reader) *Composer {
_, err := c.email.Seek(0, io.SeekStart)
if err != nil {
log.Warnf("failed to seek beginning of mail: %v", err)
@@ -448,7 +448,7 @@ func (c *Composer) SetContents(reader io.Reader) *Composer {
return c
}
-func (c *Composer) AppendContents(reader io.Reader) {
+func (c *Composer) appendContents(reader io.Reader) {
_, err := c.email.Seek(0, io.SeekEnd)
if err != nil {
log.Warnf("failed to seek beginning of mail: %v", err)
@@ -496,20 +496,36 @@ func (c *Composer) RemovePart(mimetype string) error {
return fmt.Errorf("%s part not found", mimetype)
}
-func (c *Composer) AddTemplate(template string, data models.TemplateData) error {
- if template == "" {
+func (c *Composer) addTemplate(
+ template string, data models.TemplateData, body io.Reader,
+) error {
+ var readers []io.Reader
+
+ if template != "" {
+ templateText, err := templates.ParseTemplateFromFile(
+ template, config.Templates.TemplateDirs, data)
+ if err != nil {
+ return err
+ }
+ readers = append(readers, templateText)
+ }
+ if body != nil {
+ readers = append(readers, body)
+ }
+ if len(readers) == 0 {
return nil
}
- templateText, err := templates.ParseTemplateFromFile(
- template, config.Templates.TemplateDirs, data)
+ buf, err := io.ReadAll(io.MultiReader(readers...))
if err != nil {
return err
}
- mr, err := mail.CreateReader(templateText)
+ mr, err := mail.CreateReader(bytes.NewReader(buf))
if err != nil {
- return fmt.Errorf("Template loading failed: %w", err)
+ // no headers in the template nor body
+ c.setContents(bytes.NewReader(buf))
+ return nil
}
// copy the headers contained in the template to the compose headers
@@ -523,7 +539,7 @@ func (c *Composer) AddTemplate(template string, data models.TemplateData) error
return fmt.Errorf("Could not get body of template: %w", err)
}
- c.AppendContents(part.Body)
+ c.setContents(part.Body)
return nil
}
@@ -542,7 +558,7 @@ func (c *Composer) AddSignature() {
return
}
signature = ensureSignatureDelimiter(signature)
- c.AppendContents(bytes.NewReader(signature))
+ c.appendContents(bytes.NewReader(signature))
}
func (c *Composer) readSignatureFromCmd() ([]byte, error) {