extract search criteria parsing into the backends

This commit is contained in:
Reto Brunner 2019-08-28 06:39:07 +02:00 committed by Drew DeVault
parent ac99d9ed62
commit 94b9d557de
8 changed files with 70 additions and 48 deletions

View file

@ -28,6 +28,7 @@ aerc.conf: config/aerc.conf.in
DOCS := \ DOCS := \
aerc.1 \ aerc.1 \
aerc-search.1 \
aerc-config.5 \ aerc-config.5 \
aerc-imap.5 \ aerc-imap.5 \
aerc-maildir.5 \ aerc-maildir.5 \
@ -60,6 +61,7 @@ install: all
$(SHAREDIR) $(SHAREDIR)/filters $(SHAREDIR) $(SHAREDIR)/filters
install -m755 aerc $(BINDIR)/aerc install -m755 aerc $(BINDIR)/aerc
install -m644 aerc.1 $(MANDIR)/man1/aerc.1 install -m644 aerc.1 $(MANDIR)/man1/aerc.1
install -m644 aerc-search.1 $(MANDIR)/man1/aerc-search.1
install -m644 aerc-config.5 $(MANDIR)/man5/aerc-config.5 install -m644 aerc-config.5 $(MANDIR)/man5/aerc-config.5
install -m644 aerc-imap.5 $(MANDIR)/man5/aerc-imap.5 install -m644 aerc-imap.5 $(MANDIR)/man5/aerc-imap.5
install -m644 aerc-maildir.5 $(MANDIR)/man5/aerc-maildir.5 install -m644 aerc-maildir.5 $(MANDIR)/man5/aerc-maildir.5

View file

@ -3,9 +3,6 @@ package account
import ( import (
"errors" "errors"
"git.sr.ht/~sircmpwn/getopt"
"github.com/emersion/go-imap"
"git.sr.ht/~sircmpwn/aerc/widgets" "git.sr.ht/~sircmpwn/aerc/widgets"
) )
@ -24,28 +21,6 @@ func (_ SearchFilter) Complete(aerc *widgets.Aerc, args []string) []string {
} }
func (_ SearchFilter) Execute(aerc *widgets.Aerc, args []string) error { func (_ SearchFilter) Execute(aerc *widgets.Aerc, args []string) error {
var (
criteria *imap.SearchCriteria = imap.NewSearchCriteria()
)
opts, optind, err := getopt.Getopts(args, "ruH:")
if err != nil {
return err
}
for _, opt := range opts {
switch opt.Option {
case 'r':
criteria.WithFlags = append(criteria.WithFlags, imap.SeenFlag)
case 'u':
criteria.WithoutFlags = append(criteria.WithoutFlags, imap.SeenFlag)
case 'H':
// TODO
}
}
for _, arg := range args[optind:] {
criteria.Header.Add("Subject", arg)
}
acct := aerc.SelectedAccount() acct := aerc.SelectedAccount()
if acct == nil { if acct == nil {
return errors.New("No account selected") return errors.New("No account selected")
@ -73,6 +48,6 @@ func (_ SearchFilter) Execute(aerc *widgets.Aerc, args []string) error {
acct.Messages().Scroll() acct.Messages().Scroll()
} }
} }
store.Search(criteria, cb) store.Search(args, cb)
return nil return nil
} }

11
doc/aerc-search.1.scd Normal file
View file

@ -0,0 +1,11 @@
aerc-search(1)
# IMAP
*search* [-ru] <terms...>
Searches the current folder for <terms>. Each separate term is searched
case-insensitively among subject lines.
*-r*: Search for read messages
*-u*: Search for unread messages

View file

@ -175,13 +175,10 @@ message list, the message in the message viewer, etc).
*next-result*, *prev-result* *next-result*, *prev-result*
Selects the next or previous search result. Selects the next or previous search result.
*search* [-ru] <terms...> *search*
Searches the current folder for <terms>. Each separate term is searched Searches the current folder.
case-insensitively among subject lines. The search syntax is dependant on the underlying backend.
Refer to *aerc-search*(1) for details
*-r*: Search for read messages
*-u*: Search for unread messages
*select* <n> *select* <n>
Selects the nth message in the message list (and scrolls it into view if Selects the nth message in the message list (and scrolls it into view if

View file

@ -4,8 +4,6 @@ import (
"io" "io"
"time" "time"
"github.com/emersion/go-imap"
"git.sr.ht/~sircmpwn/aerc/models" "git.sr.ht/~sircmpwn/aerc/models"
"git.sr.ht/~sircmpwn/aerc/worker/types" "git.sr.ht/~sircmpwn/aerc/worker/types"
) )
@ -368,9 +366,9 @@ func (store *MessageStore) Prev() {
store.NextPrev(-1) store.NextPrev(-1)
} }
func (store *MessageStore) Search(c *imap.SearchCriteria, cb func([]uint32)) { func (store *MessageStore) Search(args []string, cb func([]uint32)) {
store.worker.PostAction(&types.SearchDirectory{ store.worker.PostAction(&types.SearchDirectory{
Criteria: c, Argv: args,
}, func(msg types.WorkerMessage) { }, func(msg types.WorkerMessage) {
switch msg := msg.(type) { switch msg := msg.(type) {
case *types.SearchResults: case *types.SearchResults:

View file

@ -52,17 +52,29 @@ func canOpen(mbox *imap.MailboxInfo) bool {
} }
func (imapw *IMAPWorker) handleSearchDirectory(msg *types.SearchDirectory) { func (imapw *IMAPWorker) handleSearchDirectory(msg *types.SearchDirectory) {
imapw.worker.Logger.Println("Executing search") emitError := func(err error) {
if uids, err := imapw.client.UidSearch(msg.Criteria); err != nil {
imapw.worker.PostMessage(&types.Error{ imapw.worker.PostMessage(&types.Error{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
Error: err, Error: err,
}, nil) }, nil)
} else { }
imapw.worker.Logger.Println("Executing search")
criteria, err := parseSearch(msg.Argv)
if err != nil {
emitError(err)
return
}
uids, err := imapw.client.UidSearch(criteria)
if err != nil {
emitError(err)
return
}
imapw.worker.PostMessage(&types.SearchResults{ imapw.worker.PostMessage(&types.SearchResults{
Message: types.RespondTo(msg), Message: types.RespondTo(msg),
Uids: uids, Uids: uids,
}, nil) }, nil)
}
} }

29
worker/imap/search.go Normal file
View file

@ -0,0 +1,29 @@
package imap
import (
"git.sr.ht/~sircmpwn/getopt"
"github.com/emersion/go-imap"
)
func parseSearch(args []string) (*imap.SearchCriteria, error) {
criteria := imap.NewSearchCriteria()
opts, optind, err := getopt.Getopts(args, "ruH:")
if err != nil {
return nil, err
}
for _, opt := range opts {
switch opt.Option {
case 'r':
criteria.WithFlags = append(criteria.WithFlags, imap.SeenFlag)
case 'u':
criteria.WithoutFlags = append(criteria.WithoutFlags, imap.SeenFlag)
case 'H':
// TODO
}
}
for _, arg := range args[optind:] {
criteria.Header.Add("Subject", arg)
}
return criteria, nil
}

View file

@ -4,8 +4,6 @@ import (
"io" "io"
"time" "time"
"github.com/emersion/go-imap"
"git.sr.ht/~sircmpwn/aerc/config" "git.sr.ht/~sircmpwn/aerc/config"
"git.sr.ht/~sircmpwn/aerc/models" "git.sr.ht/~sircmpwn/aerc/models"
) )
@ -84,7 +82,7 @@ type FetchDirectoryContents struct {
type SearchDirectory struct { type SearchDirectory struct {
Message Message
Criteria *imap.SearchCriteria Argv []string
} }
type CreateDirectory struct { type CreateDirectory struct {