Add flag based search options
Provide search and filter with the option to specify more flag based conditions. Use '-x <flag>' to search for messages with a flag (seen, answered, flagged) and '-X <flag>' to search for messages without a flag.
This commit is contained in:
parent
126c9437e8
commit
494bd674a9
3 changed files with 76 additions and 4 deletions
|
@ -2,7 +2,7 @@ aerc-search(1)
|
||||||
|
|
||||||
# IMAP
|
# IMAP
|
||||||
|
|
||||||
*search* [-ruba] [-f <from>] [-t <to>] [-c <cc>] [terms...]
|
*search* [-ruba] [-x <flag>] [-X <flag>] [-f <from>] [-t <to>] [-c <cc>] [terms...]
|
||||||
Searches the current folder for messages matching the given set of
|
Searches the current folder for messages matching the given set of
|
||||||
conditions.
|
conditions.
|
||||||
|
|
||||||
|
@ -14,6 +14,22 @@ aerc-search(1)
|
||||||
|
|
||||||
*-u*: Search for unread messages
|
*-u*: Search for unread messages
|
||||||
|
|
||||||
|
*-x <flag>*, *-X <flag>*: Restrict search to messages with or without <flag>
|
||||||
|
|
||||||
|
Use *-x* to search for messages with the flag set.
|
||||||
|
Use *-X* to search for messages without the flag set.
|
||||||
|
|
||||||
|
Possible values are:
|
||||||
|
|
||||||
|
Seen
|
||||||
|
Read messages
|
||||||
|
|
||||||
|
Answered
|
||||||
|
Replied messages
|
||||||
|
|
||||||
|
Flagged
|
||||||
|
Flagged messages
|
||||||
|
|
||||||
*-b*: Search in the body of the messages
|
*-b*: Search in the body of the messages
|
||||||
|
|
||||||
*-a*: Search in the entire text of the messages
|
*-a*: Search in the entire text of the messages
|
||||||
|
@ -26,7 +42,7 @@ aerc-search(1)
|
||||||
|
|
||||||
# MAILDIR
|
# MAILDIR
|
||||||
|
|
||||||
*search* [-ruba] [-f <from>] [-t <to>] [-c <cc>] [terms...]
|
*search* [-ruba] [-x <flag>] [-X <flag>] [-f <from>] [-t <to>] [-c <cc>] [terms...]
|
||||||
Searches the current folder for messages matching the given set of
|
Searches the current folder for messages matching the given set of
|
||||||
conditions.
|
conditions.
|
||||||
|
|
||||||
|
@ -38,6 +54,22 @@ aerc-search(1)
|
||||||
|
|
||||||
*-u*: Search for unread messages
|
*-u*: Search for unread messages
|
||||||
|
|
||||||
|
*-x <flag>*, *-X <flag>*: Restrict search to messages with or without <flag>
|
||||||
|
|
||||||
|
Use *-x* to search for messages with the flag set.
|
||||||
|
Use *-X* to search for messages without the flag set.
|
||||||
|
|
||||||
|
Possible values are:
|
||||||
|
|
||||||
|
Seen
|
||||||
|
Read messages
|
||||||
|
|
||||||
|
Answered
|
||||||
|
Replied messages
|
||||||
|
|
||||||
|
Flagged
|
||||||
|
Flagged messages
|
||||||
|
|
||||||
*-b*: Search in the body of the messages
|
*-b*: Search in the body of the messages
|
||||||
|
|
||||||
*-a*: Search in the entire text of the messages
|
*-a*: Search in the entire text of the messages
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package imap
|
package imap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/emersion/go-imap"
|
"github.com/emersion/go-imap"
|
||||||
|
|
||||||
"git.sr.ht/~sircmpwn/getopt"
|
"git.sr.ht/~sircmpwn/getopt"
|
||||||
|
@ -9,7 +12,7 @@ import (
|
||||||
func parseSearch(args []string) (*imap.SearchCriteria, error) {
|
func parseSearch(args []string) (*imap.SearchCriteria, error) {
|
||||||
criteria := imap.NewSearchCriteria()
|
criteria := imap.NewSearchCriteria()
|
||||||
|
|
||||||
opts, optind, err := getopt.Getopts(args, "rubat:H:f:c:")
|
opts, optind, err := getopt.Getopts(args, "rubax:X:t:H:f:c:")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -21,6 +24,14 @@ func parseSearch(args []string) (*imap.SearchCriteria, error) {
|
||||||
criteria.WithFlags = append(criteria.WithFlags, imap.SeenFlag)
|
criteria.WithFlags = append(criteria.WithFlags, imap.SeenFlag)
|
||||||
case 'u':
|
case 'u':
|
||||||
criteria.WithoutFlags = append(criteria.WithoutFlags, imap.SeenFlag)
|
criteria.WithoutFlags = append(criteria.WithoutFlags, imap.SeenFlag)
|
||||||
|
case 'x':
|
||||||
|
if f, err := getParsedFlag(opt.Value); err == nil {
|
||||||
|
criteria.WithFlags = append(criteria.WithFlags, f)
|
||||||
|
}
|
||||||
|
case 'X':
|
||||||
|
if f, err := getParsedFlag(opt.Value); err == nil {
|
||||||
|
criteria.WithoutFlags = append(criteria.WithoutFlags, f)
|
||||||
|
}
|
||||||
case 'H':
|
case 'H':
|
||||||
// TODO
|
// TODO
|
||||||
case 'f':
|
case 'f':
|
||||||
|
@ -46,3 +57,15 @@ func parseSearch(args []string) (*imap.SearchCriteria, error) {
|
||||||
}
|
}
|
||||||
return criteria, nil
|
return criteria, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getParsedFlag(name string) (string, error) {
|
||||||
|
switch strings.ToLower(name) {
|
||||||
|
case "seen":
|
||||||
|
return imap.SeenFlag, nil
|
||||||
|
case "flagged":
|
||||||
|
return imap.FlaggedFlag, nil
|
||||||
|
case "answered":
|
||||||
|
return imap.AnsweredFlag, nil
|
||||||
|
}
|
||||||
|
return imap.FlaggedFlag, errors.New("Flag not suppored")
|
||||||
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ func newSearchCriteria() *searchCriteria {
|
||||||
func parseSearch(args []string) (*searchCriteria, error) {
|
func parseSearch(args []string) (*searchCriteria, error) {
|
||||||
criteria := newSearchCriteria()
|
criteria := newSearchCriteria()
|
||||||
|
|
||||||
opts, optind, err := getopt.Getopts(args, "rubat:H:f:c:")
|
opts, optind, err := getopt.Getopts(args, "rux:X:bat:H:f:c:")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,10 @@ func parseSearch(args []string) (*searchCriteria, error) {
|
||||||
criteria.WithFlags = append(criteria.WithFlags, maildir.FlagSeen)
|
criteria.WithFlags = append(criteria.WithFlags, maildir.FlagSeen)
|
||||||
case 'u':
|
case 'u':
|
||||||
criteria.WithoutFlags = append(criteria.WithoutFlags, maildir.FlagSeen)
|
criteria.WithoutFlags = append(criteria.WithoutFlags, maildir.FlagSeen)
|
||||||
|
case 'x':
|
||||||
|
criteria.WithFlags = append(criteria.WithFlags, getParsedFlag(opt.Value))
|
||||||
|
case 'X':
|
||||||
|
criteria.WithoutFlags = append(criteria.WithoutFlags, getParsedFlag(opt.Value))
|
||||||
case 'H':
|
case 'H':
|
||||||
// TODO
|
// TODO
|
||||||
case 'f':
|
case 'f':
|
||||||
|
@ -67,6 +71,19 @@ func parseSearch(args []string) (*searchCriteria, error) {
|
||||||
return criteria, nil
|
return criteria, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getParsedFlag(name string) maildir.Flag {
|
||||||
|
var f maildir.Flag
|
||||||
|
switch strings.ToLower(name) {
|
||||||
|
case "seen":
|
||||||
|
f = maildir.FlagSeen
|
||||||
|
case "answered":
|
||||||
|
f = maildir.FlagReplied
|
||||||
|
case "flagged":
|
||||||
|
f = maildir.FlagFlagged
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Worker) search(criteria *searchCriteria) ([]uint32, error) {
|
func (w *Worker) search(criteria *searchCriteria) ([]uint32, error) {
|
||||||
requiredParts := getRequiredParts(criteria)
|
requiredParts := getRequiredParts(criteria)
|
||||||
w.worker.Logger.Printf("Required parts bitmask for search: %b", requiredParts)
|
w.worker.Logger.Printf("Required parts bitmask for search: %b", requiredParts)
|
||||||
|
|
Loading…
Reference in a new issue