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
mu
queriesFull support for all flags and fields, including shorthands and aliases
Range queries (for
date
andsize
) are also supportedSeveral helper forms that simplify query building, including
(rx ...)
for Emacsy regex generationand
(one-of ...)
and(all-of ...)
forms that generate logicalor
orand
queries 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\")"