1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
|
AERC-TEMPLATES(7)
# NAME
aerc-templates - template file specification for *aerc*(1)
# SYNOPSIS
aerc uses the go text/template package for the template parsing.
Refer to the go text/template documentation for the general syntax.
The template syntax described below can be used for message template files and
for dynamic formatting of some UI app.
Template files are composed of headers, followed by a newline, followed by the
body text.
Example:
```
X-Clacks-Overhead: GNU Terry Pratchett
Hello,
Greetings,
Chuck
```
If you have a template that doesn't add any header, it *must* be preceded by a
newline, to avoid parsing parts of the body as header text.
All headers defined in the template will have precedence over any headers that
are initialized by aerc (e.g. Subject, To, From, Cc) when composing a new
message, forwarding or replying.
# MESSAGE DATA
The following data can be used in templates. Though they are not all
available always.
*Addresses*
An array of mail.Address. That can be used to add sender or recipient
names to the template.
- _{{.From}}_: List of senders.
- _{{.Peer}}_: List of senders or To recipients if the message is from
you.
- _{{.To}}_: List of To recipients. Not always Available.
- _{{.ReplyTo}}_: List of ReplyTo recipients. Not always Available.
- _{{.Cc}}_: List of Cc recipients. Not always Available.
- _{{.Bcc}}_: List of Cc recipients. Not always Available.
- _{{.OriginalFrom}}_: List of senders of the original message.
Available for quoted reply and forward.
Example:
Get the name of the first sender.
```
{{(index .From 0).Name}}
{{index (.From | names) 0}}
```
Get the email address of the first sender.
```
{{(index .From 0).Address}}
```
*Date and Time*
The date and time information is always available and can be easily
formatted.
- _{{.Date}}_: Date and time information when the compose window is opened.
- _{{.OriginalDate}}_: Date and time when the original message was received.
Available for quoted reply and forward.
To format the date fields, _dateFormat_ and _.Local_ are provided.
Refer to the *TEMPLATE FUNCTIONS* section for details.
*Subject*
The subject of the email (_ThreadPrefix_ will be empty unless threading
is enabled).
```
{{.ThreadPrefix}}{{if .ThreadFolded}}{{printf "{%d}" .ThreadCount}}{{end}}{{.Subject}}
```
The subject of the email stripped of any _Re:_ and _Fwd:_ prefixes.
```
{{.SubjectBase}}
```
*Threading*
When threading is enabled, these attributes are available in the message
list:
_ThreadPrefix_
If the message is part of a thread, this will contain arrows
that represent the message tree based on _In-Reply-To_ and
_References_ headers.
_ThreadFolded_
Will be _true_ if the message has thread children which are
hidden by *:fold*.
_ThreadCount_
The number of messages in the thread.
_ThreadUnread_
The number of unread messages in the thread.
*Flags*
List of message flags, not available when composing, replying nor
forwarding. This is a list of strings that may be converted to a single
string with *join*.
```
{{.Flags | join ""}}
```
*IsReplied*, *HasAttachment*, *IsFlagged*, *IsRecent*, *IsUnread*, *IsMarked*,
*IsDraft*
Individual boolean flags. not available when composing, replying nor
forwarding.
```
{{if .IsFlagged}}★{{end}}
```
*Labels*
Message labels (for example notmuch tags). Not available when composing,
replying nor forwarding. This is a list of strings that may be converted
to a single string with *join*.
```
{{.Labels | join " "}}
```
*Size*
The size of the message in bytes. Not available when composing, replying
nor forwarding. It can be formatted with *humanReadable*.
```
{{.Size | humanReadable}}
```
*Filename*
The full path of the message file. Not available when composing,
replying nor forwarding. For the notmuch backend, it returns a random
filename if there are multiple files associated with the message.
*Filenames*
A list of the full paths of the files associated with the message. For
maildir this is always a list with a single element. Not available when
composing, replying nor forwarding.
*Any header value*
Any header value of the email.
```
{{.Header "x-foo-bar"}}
```
Any header values of the original forwared or replied message:
```
{{.OriginalHeader "x-foo-bar"}}
```
*Message-ID*
The message-ID of the message.
```
:term b4 am {{.MessageId}}
```
*MIME Type*
MIME type is available for quoted reply and forward.
- _{{.OriginalMIMEType}}_: MIME type info of quoted mail part. Usually
_text/plain_ or _text/html_.
*Original Message*
When using quoted reply or forward, the original message is available in a
field called _OriginalText_.
```
{{.OriginalText}}
```
*Signature*
The signature of the currently selected account obtained from
*signature-file* or *signature-cmd*.
```
{{.Signature}}
```
*Account info*
The current account name:
```
{{.Account}}
```
The current account's backend:
```
{{.AccountBackend}}
```
The current account's from address:
```
{{.AccountFrom}}
{{.AccountFrom.Address}}
```
Currently selected mailbox folder:
```
{{.Folder}}
```
Current message counts for all folders:
```
{{.Recent}} {{.Unread}} {{.Exists}}
{{.RUE}}
```
IANA role of the mailbox, converted to lowercase:
```
{{.Role}}
```
*aerc* implements two additional custom roles: A 'query' role is given
to folders from a notmuch query-map
and 'virtual' indicates a virtual node in the directory tree listing:
```
{{if eq .Role "query"}}{{...}}{{else}}{{...}}{{end}}
```
Current message counts for specific folders:
```
{{.Recent "inbox"}}
{{.Unread "inbox" "aerc/pending"}}
{{.Exists "archive" "spam" "foo/baz" "foo/bar"}}
{{.RUE "inbox"}}
```
*Status line*
The following data will only be available in the status line templates:
Connection state.
```
{{.Connected}}
{{.ConnectionInfo}}
```
General status information (e.g. filter, search) separated with
*[statusline].separator*.
```
{{.ContentInfo}}
```
Combination of *{{.ConnectionInfo}}* and *{{.StatusInfo}}* separated
with *[statusline].separator*.
```
{{.StatusInfo}}
```
General on/off information (e.g. passthrough, threading, sorting, visual
mode), separated with *[statusline].separator*.
```
{{.TrayInfo}}
```
Currently pressed key sequence that does not match any key binding
and/or is incomplete.
```
{{.PendingKeys}}
```
# TEMPLATE FUNCTIONS
Besides the standard functions described in go's text/template documentation,
aerc provides the following additional functions:
*wrap*
Wrap the original text to the specified number of characters per line.
```
{{wrap 72 .OriginalText}}
```
*quote*
Prepends each line with _"> "_.
```
{{quote .OriginalText}}
```
*trimSignature*
Removes the signature froma passed in mail. Quoted signatures are kept
as they are.
```
{{trimSignature .OriginalText}}
```
*join*
Join the provided list of strings with a separator:
```
{{.To | names | join ", "}}
```
*split*
Split a string into a string slice with a separator:
```
{{.To | names | join ", " | split ", "}}
```
*names*
Extracts the names part from a mail.Address list. If there is no name
available, the mbox (email address without @domain) is returned instead.
```
{{.To | names | join ", "}}
{{index (.To | names) 0}}
```
*firstnames*
Extracts the first names part from a mail.Address list. If there is no
name available, the short mbox (start of email address without @domain)
is returned instead.
```
{{.To | firstnames | join ", "}}
{{index (.To | firstnames) 0}}
```
*initials*
Extracts the initials from the names part from a mail.Address list. If
there is no name available, the first letter of the email address is
returned instead.
```
{{.To | initials | join ", "}}
{{index (.To | initials) 0}}
```
*emails*
Extracts the addresses part from a mail.Address list.
```
{{.To | emails | join ", "}}
{{index (.To | emails) 0}}
```
*mboxes*
Extracts the mbox part from a mail.Address list (i.e. _smith_ from
_smith@example.com_).
```
{{.To | mboxes | join ", "}}
{{index (.To | mboxes) 0}}
```
*shortmboxes*
Extracts the short mbox part from a mail.Address list (i.e. _smith_ from
_smith.and.wesson@example.com_).
```
{{.To | shortmboxes | join ", "}}
{{index (.To | shortmboxes) 0}}
```
*persons*
Formats a list of mail.Address into a list of strings containing the
human readable form of RFC5322 (e.g. _Firstname Lastname
<email@address.tld>_).
```
{{.To | persons | join ", "}}
{{index (.To | persons) 0}}
```
*.Attach*
Attaches a file to the message being composed.
```
{{.Attach '/usr/libexec/aerc/filters/html'}}
```
*exec*
Execute external command, provide the second argument to its stdin.
```
{{exec `/usr/libexec/aerc/filters/html` .OriginalText}}
```
*.Local*
Convert the date to the local timezone as specified by the locale.
```
{{.Date.Local}}
```
*dateFormat*
Format date and time according to the format passed as the second argument.
The format must be specified according to go's time package format.
```
{{dateFormat .Date "Mon Jan 2 15:04:05 -0700 MST 2006"}}
```
You can also use the _.DateAutoFormat_ method to format the date
according to *\*-time\*format* settings:
```
{{.DateAutoFormat .OriginalDate.Local}}
```
*now*
Return the current date as a golang time.Time object that can be
formatted with *dateFormat*.
```
{{dateFormat now "Mon Jan 2 15:04:05 -0700 MST 2006"}}
```
*humanReadable*
Return the human readable form of an integer value.
```
{{humanReadable 3217653721}}
```
*cwd*
Return the current working directory with the user home dir replaced by
_~_.
```
{{cwd}}
```
*compactDir*
Reduce a directory path into a compact form. The directory name will be
split with _/_ and each part will be reduced to the first letter in its
name: _INBOX/01_WORK/PROJECT_ will become _I/W/PROJECT_.
```
{{compactDir .Folder}}
```
*contains*
Checks if a string contains a substring.
```
{{contains "<!DOCTYPE html>" .OriginalText}}
```
*hasPrefix*
Checks if a string has a prefix.
```
{{hasPrefix "Business" .Folder}}
```
*toLower*
Convert a string to lowercase.
```
{{toLower "SPECIAL OFFER!"}}
```
*toUpper*
Convert a string to uppercase.
```
{{toUpper "important"}}
```
*replace*
Perform a regular expression substitution on the passed string.
```
{{replace `(.+) - .+ at .+\..+` `$1` ((index .OriginalFrom 0).Name)}}
```
*head*
Return first n characters from string.
```
{{"hello" | head 2}}
```
*tail*
Return last n characters from string.
```
{{"hello" | tail 2}}
```
*.Style*
Apply a user-defined style (see *aerc-stylesets*(7)) to a string.
```
{{.Style .Account "red"}}
{{.Style .ThreadPrefix "thread"}}{{.Subject}}
```
*.StyleSwitch*
Apply a user-defined style (see *aerc-stylesets*(7)) to a string if it
matches one of the associated regular expressions. If the string does
not match any of the expressions, leave it unstyled.
```
{{.StyleSwitch .Subject (`^(\[[\w-]+\]\s*)?\[(RFC )?PATCH` "cyan")}}
{{.StyleSwitch (.From | names | join ", ") (case `Tim` "cyan") (case `Robin` "pink-blink") (default "blue")}}
```
*.StyleMap*
Apply user-defined styles (see *aerc-stylesets*(7)) to elements of
a string list. The logic is the same than *.StyleSwitch* but works on
a list of elements. An additional *exclude* option is available to
remove the matching elements from the list.
```
{{.StyleMap .Labels (exclude .Folder) (exclude `^spam$`) (case `^inbox$` "red") (case `^Archive/.*` "green") (default "blue") | join " "}}
```
*version*
Returns the version of aerc, which can be useful for things like X-Mailer.
```
X-Mailer: aerc {{version}}
```
*match*
Check if a string matches a regular expression. This is intended for
use in conditional control flow:
```
{{if match .Folder `.*/Archive-[0-9]+`}}{{humanReadable .Unread}}{{end}}
```
*switch*
Do swich/case/default control flows. The switch value is compared with
regular expressions. If none of the case/default arms match, an empty
string is returned.
```
{{switch .Folder (case `^INBOX$` "📥") (case `^Archive/.*` "🗃") (default "📁")}}
```
*map*
Transform a string list into another one. The logic is the same than
*switch* but works on a list of elements. An additional *exclude* option
is available to remove the matching elements from the list.
```
{{map .Labels (exclude .Folder) (exclude `^spam$`) (case `^inbox$` "📥") (case `^Archive/.*` "🗃") | join " "}}
```
*Function chaining*
All of the template functions can be chained together if needed.
Example: Automatic HTML parsing for text/html mime type messages
```
{{if eq .OriginalMIMEType "text/html"}}
{{exec `/usr/libexec/aerc/filters/html` .OriginalText | wrap 72 | quote}}
{{else}}
{{wrap 72 .OriginalText | trimSignature | quote}}
{{end}}
```
# SEE ALSO
*aerc*(1) *aerc-config*(5)
# AUTHORS
Originally created by Drew DeVault and maintained by Robin Jarry who is assisted
by other open source contributors. For more information about aerc development,
see _https://sr.ht/~rjarry/aerc/_.
|