1 <h1>NOTMUCH-SEXP-QUERIES(7)</h1>
5 notmuch-sexp-queries - s-expression syntax for notmuch queries
10 <b>notmuch</b> <u>subcommand</u> <b>--query=sexp</b> [option ...] <b>--</b> '(and (to santa) (date
16 Notmuch supports an alternative query syntax based on <u>S-expressions</u> .
17 It can be selected with the command line <b>--query=sexp</b> or with the ap‐
18 propriate option to the library function <b>notmuch</b>_<b>query</b>_<b>create</b>_<b>with</b>_<b>syn-</b>
19 <b>tax()</b>. Support for this syntax is currently optional, you can test if
20 your build of notmuch supports it with
22 $ notmuch config get built_with.sexpr_query
25 <h3> S-EXPRESSIONS</h3>
27 An <u>s-expression</u> is either an atom, or list of whitespace delimited
28 s-expressions inside parentheses. Atoms are either
30 <u>basic</u> <u>value</u>
31 A basic value is an unquoted string containing no whitespace,
32 double quotes, or parentheses.
34 <u>quoted</u> <u>string</u>
35 Double quotes (") delimit strings possibly containing whitespace
36 or parentheses. These can contain double quote characters by es‐
37 caping with backslash. E.g. <b>"this</b> <b>is</b> <b>a</b> <b>quote</b> <b>\""</b>.
40 <h3> S-EXPRESSION QUERIES</h3>
42 An s-expression query is either an atom, the empty list, or a <u>compound</u>
43 <u>query</u> consisting of a prefix atom (first element) defining a <u>field</u>,
44 <u>logical</u> <u>operation</u>, or <u>modifier</u>, and 0 or more subqueries.
46 <b>*</b> "*" matches any non-empty string in the current field.
48 <b>()</b> The empty list matches all messages
51 Match all messages containing <u>term</u>, possibly after stemming or
52 phrase splitting. For discussion of stemming in notmuch see <a href='../notmuch-search-terms-7/'>not‐</a>
53 <a href='../notmuch-search-terms-7/'>much-search-terms</a>(7). Stemming only applies to unquoted terms (basic
54 values) in s-expression queries. For information on phrase split‐
55 ting see <u>FIELDS</u>.
57 <b>(</b> <u>field</u> <b>q</b>_<b>1</b> <b>q</b>_<b>2</b> <b>...</b> <b>q</b>_<b>n</b> <b>)</b>
58 Restrict the queries q_1 to q_n to <u>field</u>, and combine with <u>and</u>
59 (for most fields) or <u>or</u>. See <u>FIELDS</u> for more information.
61 <b>(</b> <u>operator</u> <b>q</b>_<b>1</b> <b>q</b>_<b>2</b> <b>...</b> <b>q</b>_<b>n</b> <b>)</b>
62 Combine queries q_1 to q_n. Currently supported operators are
63 <b>and</b>, <b>or</b>, and <b>not</b>. <b>(not</b> q_1 ... q_n <b>)</b> is equivalent to <b>(and</b> <b>(not</b>
64 q_1 <b>)</b> <b>...</b> <b>(not</b> q_n <b>))</b>.
66 <b>(</b> <u>modifier</u> <b>q</b>_<b>1</b> <b>q</b>_<b>2</b> <b>...</b> <b>q</b>_<b>n</b> <b>)</b>
67 Combine queries q_1 to q_n, and reinterpret the result (e.g. as
68 a regular expression). See <u>MODIFIERS</u> for more information.
70 <b>(macro</b> <b>(</b> <b>p</b>_<b>1</b> <b>...</b> <b>p</b>_<b>n</b> <b>)</b> <b>body)</b>
71 Define saved query with parameter substitution. The syntax is
72 recognized only in saved s-expression queries (see <b>squery.*</b> in
73 <a href='../notmuch-config-1/'>notmuch-config</a>(1)). Parameter names in <b>body</b> must be prefixed
74 with <b>,</b> to be expanded (see <u>MACRO</u> <u>EXAMPLES</u>). Macros may refer to
75 other macros, but only to their own parameters [1].
78 <h3> FIELDS</h3>
80 <u>Fields</u> [2] correspond to attributes of mail messages. Some are inherent
81 (and immutable) like <b>subject</b>, while others <b>tag</b> and <b>property</b> are set‐
82 table by the user. Each concrete field in <u>the</u> <u>table</u> <u>below</u> is discussed
83 further under "Search prefixes" in <a href='../notmuch-search-terms-7/'>notmuch-search-terms</a>(7). The row
84 <u>user</u> refers to user defined fields, described in <a href='../notmuch-config-1/'>notmuch-config</a>(1).
86 Most fields are either <u>phrase</u> <u>fields</u> [3] (which match sequences of
87 words), or <u>term</u> <u>fields</u> [4] (which match exact strings). <u>Phrase</u> <u>split‐</u>
88 <u>ting</u> breaks the term (basic value or quoted string) into words, ignore
89 punctuation. Phrase splitting is applied to terms in phrase (proba‐
90 bilistic) fields. Both phrase splitting and stemming apply only in
93 Each term or phrase field has an associated combining operator (<b>and</b> or
94 <b>or</b>) used to combine the queries from each element of the tail of the
95 list. This is generally <b>or</b> for those fields where a message has one
96 such attribute, and <b>and</b> otherwise.
98 Term or phrase fields can contain arbitrarily complex queries made up
99 from terms, operators, and modifiers, but not other fields.
102 <h3> Fields with supported modifiers</h3>
104 ┌───────────┬─────────┬────────┬────────┬──────────┬───────┐
105 │field │ combine │ type │ expand │ wildcard │ regex │
106 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
107 │<u>none</u> │ and │ │ no │ yes │ no │
108 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
109 │<u>user</u> │ and │ phrase │ no │ yes │ no │
110 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
111 │attachment │ and │ phrase │ yes │ yes │ no │
112 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
113 │body │ and │ phrase │ no │ no │ no │
114 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
115 │date │ │ range │ no │ no │ no │
116 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
117 │folder │ or │ phrase │ yes │ yes │ yes │
118 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
119 │from │ and │ phrase │ yes │ yes │ yes │
120 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
121 │id │ or │ term │ no │ yes │ yes │
122 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
123 │is │ and │ term │ yes │ yes │ yes │
124 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
125 │lastmod │ │ range │ no │ no │ no │
126 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
127 │mid │ or │ term │ no │ yes │ yes │
128 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
129 │mimetype │ or │ phrase │ yes │ yes │ no │
130 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
131 │path │ or │ term │ no │ yes │ yes │
132 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
133 │property │ and │ term │ yes │ yes │ yes │
134 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
135 │subject │ and │ phrase │ yes │ yes │ yes │
136 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
137 │tag │ and │ term │ yes │ yes │ yes │
138 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
139 │thread │ or │ term │ yes │ yes │ yes │
140 ├───────────┼─────────┼────────┼────────┼──────────┼───────┤
141 │to │ and │ phrase │ yes │ yes │ no │
142 └───────────┴─────────┴────────┴────────┴──────────┴───────┘
145 <h3> MODIFIERS</h3>
147 <u>Modifiers</u> refer to any prefixes (first elements of compound queries)
148 that are neither operators nor fields.
150 <b>(infix</b> <u>atom</u> <b>)</b>
151 Interpret <u>atom</u> as an infix notmuch query (see <a href='../notmuch-search-terms-7/'>not‐</a>
152 <a href='../notmuch-search-terms-7/'>much-search-terms</a>(7)). Not supported inside fields.
154 <b>(matching</b> <b>q</b>_<b>1</b> <b>q</b>_<b>2</b> <b>...</b> <b>q</b>_<b>n</b> <b>)</b> <b>(of</b> <b>q</b>_<b>1</b> <b>q</b>_<b>2</b> <b>...</b> <b>q</b>_<b>n</b> <b>)</b>
155 Match all messages have the same values of the current field as
156 those matching all of q_1 ... q_n. Supported in most term [7] or
157 phrase fields. Most commonly used in the <b>thread</b> field.
159 <b>(query</b> <u>atom</u> <b>)</b>
160 Expand to the saved query named by <u>atom</u>. See <a href='../notmuch-config-1/'>notmuch-config</a>(1)
161 for more. Note that the saved query must be in infix syntax
162 (<a href='../notmuch-search-terms-7/'>notmuch-search-terms</a>(7)). Not supported inside fields.
164 <b>(regex</b> <u>atom</u> <b>)</b> <b>(rx</b> <u>atom</u> <b>)</b>
165 Interpret <u>atom</u> as a POSIX.2 regular expression (see <b>regex</b>(7)).
166 This applies in term fields and a subset [5] of phrase fields
167 (see <u>Fields</u> <u>with</u> <u>supported</u> <u>modifiers</u>).
169 <b>(starts-with</b> <u>subword</u> <b>)</b>
170 Matches any term starting with <u>subword</u>. This applies in either
171 phrase or term <u>fields</u>, or outside of fields [6]. Note that a
172 <b>starts-with</b> query cannot be part of a phrase. The atom <b>*</b> is a
173 synonym for <b>(starts-with</b> <b>"")</b>.
178 <b>Wizard</b> Match all messages containing the word "wizard", ignoring case.
180 <b>added</b> Match all messages containing "added", but also those containing
181 "add", "additional", "Additional", "adds", etc... via stemming.
183 <b>(and</b> <b>Bob</b> <b>Marley)</b>
184 Match messages containing words "Bob" and "Marley", or their
185 stems The words need not be adjacent.
187 <b>(not</b> <b>Bob</b> <b>Marley)</b>
188 Match messages containing neither "Bob" nor "Marley", nor their
191 <b>"quick</b> <b>fox"</b> <b>quick-fox</b> <b>quick@fox</b>
192 Match the <u>phrase</u> "quick" followed by "fox" in phrase fields (or
193 outside a field). Match the literal string in a term field.
195 <b>(folder</b> <b>(of</b> <b>(id</b> <b>1234@invalid)))</b>
196 Match any message in the same folder as the one with Message-Id
197 "<u>1234@invalid</u>"
199 <b>(id</b> <b>1234@invalid</b> <b>blah@test)</b>
200 Matches Message-Id "<u>1234@invalid</u>" <u>or</u> Message-Id "<u>blah@test</u>"
202 <b>(and</b> <b>(infix</b> <b>date:2009-11-18..2009-11-18</b> <b>)</b> <b>(tag</b> <b>unread))</b>
203 Match messages in the given date range with tag unread.
205 <b>(starts-with</b> <b>prelim)</b>
206 Match any words starting with "prelim".
208 <b>(subject</b> <b>quick</b> <b>brown</b> <b>fox</b> <b>)</b>
209 Match messages whose subject contains "quick" (anywhere,
210 stemmed) and the phrase "brown fox".
212 <b>(subject</b> <b>(starts-with</b> <b>prelim))</b>
213 Matches any word starting with "prelim", inside a message sub‐
216 <b>(subject</b> <b>(starts-wih</b> <b>quick)</b> <b>brown</b> <b>fox</b> <b>)</b>
217 Match messages whose subject contains "quick brown fox", but
218 also "brown fox quicksand".
220 <b>(thread</b> <b>(of</b> <b>(id</b> <b>1234@invalid)))</b>
221 Match any message in the same thread as the one with Message-Id
222 "<u>1234@invalid</u>"
224 <b>(thread</b> <b>(matching</b> <b>(from</b> <b>bob@example.com)</b> <b>(to</b> <b>bob@example.com)))</b>
225 Match any (messages in) a thread containing a message from "‐
226 <u>bob@example.com</u>" and a (possibly distinct) message to "bob at
229 <b>(to</b> <b>(or</b> <b>bob@example.com</b> <b>mallory@example.org))</b> <b>(or</b> <b>(to</b> <b>bob@example.com)</b>
230 <b>(to</b> <b>mallory@example.org))</b>
231 Match in the "To" or "Cc" headers, "<u>bob@example.com</u>", "‐
232 <u>mallory@example.org</u>", and also "<u>bob@example.com.au</u>" since it
233 contains the adjacent triple "bob", "example", "com".
235 <b>(not</b> <b>(to</b> <b>*))</b>
236 Match messages with an empty or invalid 'To' and 'Cc' field.
238 <b>(List</b> <b>*)</b>
239 Match messages with a non-empty List-Id header, assuming config‐
240 uration <b>index.header.List=List-Id</b>
243 <h3> MACRO EXAMPLES</h3>
245 A macro that takes two parameters and applies different fields to them.
247 $ notmuch config set squery.TagSubject '(macro (tagname subj) (and (tag ,tagname) (subject ,subj)))'
248 $ notmuch search --query=sexp '(TagSubject inbox maildir)'
250 Nested macros are allowed.
252 $ notmuch config set squery.Inner '(macro (x) (subject ,x))'
253 $ notmuch config set squery.Outer '(macro (x y) (and (tag ,x) (Inner ,y)))'
254 $ notmuch search --query=sexp '(Outer inbox maildir)'
256 Parameters can be re-used to reduce boilerplate. Any field, including
257 user defined fields is permitted within a macro.
259 $ notmuch config set squery.About '(macro (name) (or (subject ,name) (List ,name)))'
260 $ notmuch search --query=sexp '(About notmuch)'
265 [1] Technically macros impliment lazy evaluation and lexical scope.
266 There is one top level scope containing all macro definitions, but
267 all parameter definitions are local to a given macro.
271 [3] a.k.a. probabilistic prefixes
273 [4] a.k.a. boolean prefixes
275 [5] Due to the implemention of phrase fields in Xapian, regex queries
276 could only match individual words.
278 [6] Due the the way <b>body</b> is implemented in notmuch, this modifier is
279 not supported in the <b>body</b> field.
281 [7] Due to the way recursive <b>path</b> queries are implemented in notmuch,
282 this modifier is not supported in the <b>path</b> field.
287 Carl Worth and many others
292 2009-2021, Carl Worth and many others