compose: use a proper header instead of a string map

Prior to this commit, the composer was based on a map[string]string.
While this approach was very versatile, it lead to a constant encoding / decoding
of addresses and other headers.

This commit switches to a different model, where the composer is based on a header.
Commands which want to interact with it can simply set some defaults they would
like to have. Users can overwrite them however they like.

In order to get access to the functions generating / getting the msgid go-message
was upgraded.
This commit is contained in:
Reto Brunner 2020-11-10 20:27:30 +01:00
parent 3ad3a5ede0
commit 20ec2c8eeb
14 changed files with 318 additions and 217 deletions

View file

@ -15,6 +15,7 @@ import (
"git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/widgets"
"git.sr.ht/~sircmpwn/aerc/worker/types"
"github.com/emersion/go-message/mail"
"git.sr.ht/~sircmpwn/getopt"
)
@ -49,11 +50,6 @@ func (forward) Execute(aerc *widgets.Aerc, args []string) error {
}
}
to := ""
if len(args) != 1 {
to = strings.Join(args[optind:], ", ")
}
widget := aerc.SelectedTab().(widgets.ProvidesMessage)
acct := widget.SelectedAccount()
if acct == nil {
@ -69,11 +65,19 @@ func (forward) Execute(aerc *widgets.Aerc, args []string) error {
}
acct.Logger().Println("Forwarding email " + msg.Envelope.MessageId)
h := &mail.Header{}
subject := "Fwd: " + msg.Envelope.Subject
defaults := map[string]string{
"To": to,
"Subject": subject,
h.SetSubject(subject)
if len(args) != 1 {
to := strings.Join(args[optind:], ", ")
tolist, err := mail.ParseAddressList(to)
if err != nil {
return fmt.Errorf("invalid to address(es): %v", err)
}
h.SetAddressList("to", tolist)
}
original := models.OriginalMail{
From: format.FormatAddresses(msg.Envelope.From),
Date: msg.Envelope.Date,
@ -81,15 +85,15 @@ func (forward) Execute(aerc *widgets.Aerc, args []string) error {
}
addTab := func() (*widgets.Composer, error) {
composer, err := widgets.NewComposer(aerc, acct, aerc.Config(), acct.AccountConfig(),
acct.Worker(), template, defaults, original)
composer, err := widgets.NewComposer(aerc, acct, aerc.Config(),
acct.AccountConfig(), acct.Worker(), template, h, original)
if err != nil {
aerc.PushError("Error: " + err.Error())
return nil, err
}
tab := aerc.NewTab(composer, subject)
if to == "" {
if !h.Has("to") {
composer.FocusRecipient()
} else {
composer.FocusTerminal()

View file

@ -53,15 +53,9 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error {
}
acct.Logger().Println("Recalling message " + msgInfo.Envelope.MessageId)
// copy the headers to the defaults map for addition to the composition
defaults := make(map[string]string)
headerFields := msgInfo.RFC822Headers.Fields()
for headerFields.Next() {
defaults[headerFields.Key()] = headerFields.Value()
}
composer, err := widgets.NewComposer(aerc, acct, aerc.Config(),
acct.AccountConfig(), acct.Worker(), "", defaults, models.OriginalMail{})
acct.AccountConfig(), acct.Worker(), "", msgInfo.RFC822Headers,
models.OriginalMail{})
if err != nil {
return errors.Wrap(err, "Cannot open a new composer")
}

View file

@ -145,22 +145,22 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {
subject = msg.Envelope.Subject
}
defaults := map[string]string{
"To": format.FormatAddresses(to),
"Cc": format.FormatAddresses(cc),
"From": format.AddressForHumans(from),
"Subject": subject,
"In-Reply-To": msg.Envelope.MessageId,
}
h := &mail.Header{}
h.SetAddressList("to", to)
h.SetAddressList("cc", cc)
h.SetAddressList("from", []*mail.Address{from})
h.SetSubject(subject)
h.SetMsgIDList("in-reply-to", []string{msg.Envelope.MessageId})
//TODO: references header
original := models.OriginalMail{
From: format.FormatAddresses(msg.Envelope.From),
Date: msg.Envelope.Date,
From: format.FormatAddresses(msg.Envelope.From),
Date: msg.Envelope.Date,
RFC822Headers: msg.RFC822Headers,
}
addTab := func() error {
composer, err := widgets.NewComposer(aerc, acct, aerc.Config(),
acct.AccountConfig(), acct.Worker(), template, defaults, original)
acct.AccountConfig(), acct.Worker(), template, h, original)
if err != nil {
aerc.PushError("Error: " + err.Error())
return err

View file

@ -9,6 +9,7 @@ import (
"git.sr.ht/~sircmpwn/aerc/lib"
"git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/widgets"
"github.com/emersion/go-message/mail"
)
// Unsubscribe helps people unsubscribe from mailing lists by way of the
@ -84,10 +85,13 @@ func parseUnsubscribeMethods(header string) (methods []*url.URL) {
func unsubscribeMailto(aerc *widgets.Aerc, u *url.URL) error {
widget := aerc.SelectedTab().(widgets.ProvidesMessage)
acct := widget.SelectedAccount()
defaults := map[string]string{
"To": u.Opaque,
"Subject": u.Query().Get("subject"),
h := &mail.Header{}
h.SetSubject(u.Query().Get("subject"))
if to, err := mail.ParseAddressList(u.Opaque); err == nil {
h.SetAddressList("to", to)
}
composer, err := widgets.NewComposer(
aerc,
acct,
@ -95,7 +99,7 @@ func unsubscribeMailto(aerc *widgets.Aerc, u *url.URL) error {
acct.AccountConfig(),
acct.Worker(),
"",
defaults,
h,
models.OriginalMail{},
)
if err != nil {