This simple library builds valid mu find queries from simple and idiomatic S-expression forms.
For instance:
ELISP> (mu4e-make-query
'(and
(subject "Your Festivus Catalogue is on its way!")
(to "costanza@example.com")))
"(subject:\"Your Festivus Catalogue is on its way!\" and to:costanza@example.com)"Instead of wrangling strings, you can build your queries freely using variables and nested forms to meet your needs.
Here's an example that configures mu4e-bookmarks:
(setq mu4e-bookmarks `((:name "Shared inbox"
:query ,(mp-mu4e-make-query
'(and (not (flag trashed)) (maildir (regex "Inbox$"))))
:key ?i))All known features of mu find are supported, including:
Automatic quoting when white spaces are used
Support for free-form searches
String fallback if you want to mix S-expressions and
muqueriesFull support for all flags and fields, including shorthands and aliases
Range queries (for
dateandsize) are also supportedSeveral helper forms that simplify query building, including
(rx ...)for Emacsy regex generationand
(one-of ...)and(all-of ...)forms that generate logicalororandqueries for a field, to speed up query writing:ELISP> (mu4e-make-query '(contact (one-of "kramer" "costanza" "seinfeld" "benes"))) "(contact:kramer or contact:costanza or contact:seinfeld or contact:benes)"
Install this module somewhere then require it, and call mu4e-make-query. See its docstring (or the commentary in mu4e-query.el) for more information.
Both shorthands -- like f, b, p, etc. -- and their longform field names work.
You can express flags with either their long-form or shorthand names also. Date and size ranges also work.
Fields and flags work the same way. They're specified as (flag ...) or (subject ...). E.g.:
(flag seen)
(maildir "/foo")
(size ("1M" .. "1G"))Range queries work the same way but require a cons to match:
ELISP> (mu4e-make-query '(size (1M .. 1G)))
"size:1M..1G"
ELISP> (mu4e-make-query '(date ( .. 1w)))
"date:..1w"The (regex ...) form generates an ed-style regex:
ELISP> (mu4e-make-query '(from (regex "[FG] Costanza")))
"from:/[FG] Costanza/"But you can also use Emacs's excellent rx package to generate complex regex patterns. Note, though, that mu does not use Emacs's regex engine, so there are differences:
ELISP> (mu4e-make-query '(from (rx (| "George" "Frank"))))
"from:/\\(?:Frank\\|George\\)/"Instead of repeating yourself if you have a range of fields that must match one or -- or all of -- a set of a values, you can use the helper forms (one-of ...) and (all-of ...) instead:
ELISP> (mu4e-make-query '(from (one-of "elaine benez" "cosmo kramer")))
"(from:\"elaine benez\" or from:\"cosmo kramer\")"