diff options
author | Reto Brunner <reto@labrat.space> | 2020-08-26 08:13:38 +0200 |
---|---|---|
committer | Reto Brunner <reto@labrat.space> | 2020-08-27 08:38:41 +0200 |
commit | 720733bc6e534503bd88d8087ac0446c4c516d4a (patch) | |
tree | cb184706549f1ab888b654af600bf409fba9a7c4 /commands | |
parent | b6ef116c36e1a1de6a2289f392603fd51a2b91da (diff) | |
download | aerc-720733bc6e534503bd88d8087ac0446c4c516d4a.zip |
reply: use set instead of linear search
Diffstat (limited to 'commands')
-rw-r--r-- | commands/msg/reply.go | 115 |
1 files changed, 70 insertions, 45 deletions
diff --git a/commands/msg/reply.go b/commands/msg/reply.go index d4b3be6..3c8016e 100644 --- a/commands/msg/reply.go +++ b/commands/msg/reply.go @@ -64,10 +64,11 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error { if err != nil { return err } - alias_of_us, err := format.ParseAddressList(conf.Aliases) + aliases, err := format.ParseAddressList(conf.Aliases) if err != nil { return err } + store := widget.Store() if store == nil { return errors.New("Cannot perform action. Messages still loading") @@ -77,61 +78,63 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error { return err } + // figure out the sending from address if we have aliases + if len(aliases) != 0 { + rec := newAddrSet() + rec.AddList(msg.Envelope.To) + rec.AddList(msg.Envelope.Cc) + // test the from first, it has priority over any present alias + if rec.Contains(from) { + // do nothing + } else { + for _, a := range aliases { + if rec.Contains(a) { + from = a + break + } + } + } + } + var ( to []*models.Address cc []*models.Address ) - if args[0] == "reply" { - if len(msg.Envelope.ReplyTo) != 0 { - to = msg.Envelope.ReplyTo - } else { - to = msg.Envelope.From - } - // figure out the sending from address if we have aliases - if len(alias_of_us) != 0 { - allRecipients := append(msg.Envelope.To, msg.Envelope.Cc...) - outer: - for _, addr := range allRecipients { - if addr.Address == from.Address { - from = addr - break - } - for _, alias := range alias_of_us { - if addr.Address == alias.Address { - from = addr - break outer - } - } - } + recSet := newAddrSet() // used for de-duping - } + if len(msg.Envelope.ReplyTo) != 0 { + to = msg.Envelope.ReplyTo + } else { + to = msg.Envelope.From + } + recSet.AddList(to) - isMainRecipient := func(a *models.Address) bool { - for _, ta := range to { - if ta.Address == a.Address { - return true - } + if replyAll { + // order matters, due to the deduping + // in order of importance, first parse the To, then the Cc header + + // we add our from address, so that we don't self address ourselves + recSet.Add(from) + + envTos := make([]*models.Address, 0, len(msg.Envelope.To)) + for _, addr := range msg.Envelope.To { + if recSet.Contains(addr) { + continue } - return false + envTos = append(envTos, addr) } - if replyAll { - for _, addr := range msg.Envelope.Cc { - //dedupe stuff from the to/from headers - if isMainRecipient(addr) || addr.Address == from.Address { - continue - } - cc = append(cc, addr) - } - envTos := make([]*models.Address, 0, len(msg.Envelope.To)) - for _, addr := range msg.Envelope.To { - if addr.Address == from.Address { - continue - } - envTos = append(envTos, addr) + recSet.AddList(envTos) + to = append(to, envTos...) + + for _, addr := range msg.Envelope.Cc { + //dedupe stuff from the to/from headers + if recSet.Contains(addr) { + continue } - to = append(to, envTos...) + cc = append(cc, addr) } + recSet.AddList(cc) } var subject string @@ -218,3 +221,25 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error { return addTab() } } + +type addrSet map[string]struct{} + +func newAddrSet() addrSet { + s := make(map[string]struct{}) + return addrSet(s) +} + +func (s addrSet) Add(a *models.Address) { + s[a.Address] = struct{}{} +} + +func (s addrSet) AddList(al []*models.Address) { + for _, a := range al { + s[a.Address] = struct{}{} + } +} + +func (s addrSet) Contains(a *models.Address) bool { + _, ok := s[a.Address] + return ok +} |