aboutsummaryrefslogtreecommitdiff
path: root/content/blog/2025-11-02-aerc-macos.org
blob: 320f7a9783c04220093a18ac16a523e19d3e3e21 (plain) (blame)
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
#+date:        [2025-11-02 Sun 10:07:14]
#+title:       Using aerc on macOS
#+description: How I use aerc, a TUI email client, on macOS.
#+slug: aerc-macos
#+filetags:    :linux:

#+caption: aerc-mail
#+attr_html: :alt An image of aerc with an email opened in the reader window.
https://img.cleberg.net/blog/20251102-aerc-macos/read.webp

Shout-out to [[https://baty.net/posts/2025/10/using-aerc-for-email/][Jack Baty]] for inspiring me to write about my =aerc-mail= client
after chatting about it over email recently!

* Overview

[[https://aerc-mail.org/][aerc]] is a text user interface (TUI) email client with intuitive defaults, easy
setup, and hassle-free operations. This post will walk through my personal
configuration for aerc on macOS.

* Installation

Since I am on macOS, I opted to install aerc from Homebrew. There are build
options for additional modules if you build from source, but I am okay with the
default options.

You can view the information about the package prior to installing it, if you
wish:

#+begin_src sh
brew info aerc
#+end_src

#+begin_src sh
==> aerc: stable 0.21.0 (bottled), HEAD
Email client that runs in your terminal
https://aerc-mail.org/
Installed
/opt/homebrew/Cellar/aerc/0.21.0 (48 files, 23MB) *
  Poured from bottle using the formulae.brew.sh API on 2025-10-05 at 19:51:31
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/a/aerc.rb
License: MIT
==> Dependencies
Build: go ✘, scdoc ✘
Required: notmuch ✔
==> Options
--HEAD
	Install HEAD version
==> Downloading https://formulae.brew.sh/api/formula/aerc.json
==> Analytics
install: 136 (30 days), 560 (90 days), 1,772 (365 days)
install-on-request: 136 (30 days), 560 (90 days), 1,772 (365 days)
build-error: 3 (30 days)
#+end_src

Once you confirm you want to install this package, run the following:

#+begin_src sh
brew install aerc
#+end_src

* First-Time Wizard

When you run aerc for the first time, an IMAP & SMTP wizard will walk you
through a basic setup for your email account(s).

On macOS, aerc will save your configuration files in the following location:
=~/Library/Preferences/aerc=.

I tried to create a =~/.config/aerc= directory, but the Library directory above
took precedence. If you truly need to keep your files in =~/.config=, you could
probably symlink that to the Library location. However, I accepted my fate and
will just edit the files within the Library directory.

* Configuration

Once you have installed and setup aerc for the first time, you can configure the
client and account settings.

As noted above, I will be working within the Library directory that aerc
defaults to when installed via brew.

#+begin_src sh
cd ~/Library/Preferences/aerc
#+end_src

This directory should contain the following files. You can open the
=accounts.conf= file to confirm it contains the information you input during the
wizard process.

| File            | Purpose                                                     |
|-----------------+-------------------------------------------------------------|
| =accounts.conf= | Contains account-specific settings for IMAP & SMTP accounts |
| =aerc.conf=     | Contains program-wide settings                              |
| =binds.conf=    | Contains key bindings for aerc                              |

I'll share my personal configuration, which is close to the defaults that
existed at the time of writing this post.

=accounts.conf=

This is the information from the wizard. The only further customization I
provided is the default signature file to be appended to each message I compose.

#+begin_src conf
[Personal]
source         = imaps://hello%40cleberg.net:[email protected]
outgoing       = smtps://hello%40cleberg.net:[email protected]
default        = INBOX
from           = Christian Cleberg <[email protected]>
copy-to        = Sent
cache-headers  = true
signature-file = /Users/cmc/Library/Preferences/aerc/sigs/default
#+end_src

=sigs/default=

Any content within this file will be appended to my messages, as noted above.

#+begin_src text
Christian Cleberg <[email protected]>
GPG: 3917 973F B159 BBB8 6194 5385 69451A51 7AC0 CB37
#+end_src

=aerc.conf=

This contains quite a few customizations for my preferences related to
downloads, encryption, mouse controls, editor, and message composition.

#+begin_src conf
[general]
# Prefer downloads to be saved to the Downloads folder
default-save-path=~/Downloads
# Use GPG for PGP encryption
pgp-provider=gpg

[ui]
# Enable mouse controls for scrolling, paging, etc.
mouse-enabled=true

[statusline]
[viewer]
# Use emacs instead of vi
pager=/usr/local/bin/emacs_viewer

[compose]
# Use emacs instead of vi
editor=emacs
# Add Cc as a default field to view each time I compose a message
header-layout=To|From,Cc,Subject
# Allow me to edit headers when composing (so I can customize From address)
edit-headers=true
# Warn me if I mentioned these words but don't attach a file
empty-subject-warning=true
no-attachment-warning=^[^>]*attach(ed|ment)

[multipart-converters]

[filters]
text/plain=colorize
text/calendar=calendar
message/delivery-status=colorize
message/rfc822=colorize
text/html=! html
.headers=colorize

[openers]
[hooks]
[templates]
#+end_src

#+begin_quote
*IMPORTANT*: If you use the =pager= option above that I'm using, you will need
 to create the =emacs_viewer= file as well.
#+end_quote

You can create the file following my process below, which will create an
executable in the location specified in my =aerc.conf= file. I put it in
=/usr/local/bin=, but you can put it anywhere as long as it exists in the file
path specific within your configuration file.

#+begin_src sh
sudo nano /usr/local/bin/emacs_viewer
#+end_src

Paste this inside the file:

#+begin_src sh
#!/bin/bash
emacs -nw - < "$1"
#+end_src

#+begin_src sh
sudo chmod +x /usr/local/bin/emacs_viewer
#+end_src

=binds.conf=

Finally, here are the key bindings. I did not change these, but I'm showing them
here in case you have an issue and want to see the defaults.

#+begin_src conf
# Binds are of the form <key sequence> = <command to run>
# To use '=' in a key sequence, substitute it with "Eq": "<Ctrl+Eq>"
# If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit
<C-p> = :prev-tab<Enter>
<C-PgUp> = :prev-tab<Enter>
<C-n> = :next-tab<Enter>
<C-PgDn> = :next-tab<Enter>
\[t = :prev-tab<Enter>
\]t = :next-tab<Enter>
<C-t> = :term<Enter>
? = :help keys<Enter>
<C-c> = :prompt 'Quit?' quit<Enter>
<C-q> = :prompt 'Quit?' quit<Enter>
<C-z> = :suspend<Enter>

[messages]
q = :prompt 'Quit?' quit<Enter>

j = :next<Enter>
<Down> = :next<Enter>
<C-d> = :next 50%<Enter>
<C-f> = :next 100%<Enter>
<PgDn> = :next 100%<Enter>

k = :prev<Enter>
<Up> = :prev<Enter>
<C-u> = :prev 50%<Enter>
<C-b> = :prev 100%<Enter>
<PgUp> = :prev 100%<Enter>
g = :select 0<Enter>
G = :select -1<Enter>

J = :next-folder<Enter>
<C-Down> = :next-folder<Enter>
K = :prev-folder<Enter>
<C-Up> = :prev-folder<Enter>
H = :collapse-folder<Enter>
<C-Left> = :collapse-folder<Enter>
L = :expand-folder<Enter>
<C-Right> = :expand-folder<Enter>

v = :mark -t<Enter>
<Space> = :mark -t<Enter>:next<Enter>
V = :mark -v<Enter>

T = :toggle-threads<Enter>
zc = :fold<Enter>
zo = :unfold<Enter>
za = :fold -t<Enter>
zM = :fold -a<Enter>
zR = :unfold -a<Enter>
<tab> = :fold -t<Enter>

zz = :align center<Enter>
zt = :align top<Enter>
zb = :align bottom<Enter>

<Enter> = :view<Enter>
d = :choose -o y 'Really delete this message' delete-message<Enter>
D = :delete<Enter>
a = :archive flat<Enter>
A = :unmark -a<Enter>:mark -T<Enter>:archive flat<Enter>

C = :compose<Enter>
m = :compose<Enter>

b = :bounce<space>

rr = :reply -a<Enter>
rq = :reply -aq<Enter>
Rr = :reply<Enter>
Rq = :reply -q<Enter>

c = :cf<space>
$ = :term<space>
! = :term<space>
| = :pipe<space>

/ = :search<space>
\ = :filter<space>
n = :next-result<Enter>
N = :prev-result<Enter>
<Esc> = :clear<Enter>

s = :split<Enter>
S = :vsplit<Enter>

pl = :patch list<Enter>
pa = :patch apply <Tab>
pd = :patch drop <Tab>
pb = :patch rebase<Enter>
pt = :patch term<Enter>
ps = :patch switch <Tab>

[messages:folder=Drafts]
<Enter> = :recall<Enter>

[view]
/ = :toggle-key-passthrough<Enter>/
q = :close<Enter>
O = :open<Enter>
o = :open<Enter>
S = :save<space>
| = :pipe<space>
D = :delete<Enter>
A = :archive flat<Enter>

<C-y> = :copy-link <space>
<C-l> = :open-link <space>

f = :forward<Enter>
rr = :reply -a<Enter>
rq = :reply -aq<Enter>
Rr = :reply<Enter>
Rq = :reply -q<Enter>

H = :toggle-headers<Enter>
<C-k> = :prev-part<Enter>
<C-Up> = :prev-part<Enter>
<C-j> = :next-part<Enter>
<C-Down> = :next-part<Enter>
J = :next<Enter>
<C-Right> = :next<Enter>
K = :prev<Enter>
<C-Left> = :prev<Enter>

[view::passthrough]
$noinherit = true
$ex = <C-x>
<Esc> = :toggle-key-passthrough<Enter>

[compose]
# Keybindings used when the embedded terminal is not selected in the compose
# view
$noinherit = true
$ex = <C-x>
$complete = <C-o>
<C-k> = :prev-field<Enter>
<C-Up> = :prev-field<Enter>
<C-j> = :next-field<Enter>
<C-Down> = :next-field<Enter>
<A-p> = :switch-account -p<Enter>
<C-Left> = :switch-account -p<Enter>
<A-n> = :switch-account -n<Enter>
<C-Right> = :switch-account -n<Enter>
<tab> = :next-field<Enter>
<backtab> = :prev-field<Enter>
<C-p> = :prev-tab<Enter>
<C-PgUp> = :prev-tab<Enter>
<C-n> = :next-tab<Enter>
<C-PgDn> = :next-tab<Enter>

[compose::editor]
# Keybindings used when the embedded terminal is selected in the compose view
$noinherit = true
$ex = <C-x>
<C-k> = :prev-field<Enter>
<C-Up> = :prev-field<Enter>
<C-j> = :next-field<Enter>
<C-Down> = :next-field<Enter>
<C-p> = :prev-tab<Enter>
<C-PgUp> = :prev-tab<Enter>
<C-n> = :next-tab<Enter>
<C-PgDn> = :next-tab<Enter>

[compose::review]
# Keybindings used when reviewing a message to be sent
# Inline comments are used as descriptions on the review screen
y = :send<Enter> # Send
n = :abort<Enter> # Abort (discard message, no confirmation)
s = :sign<Enter> # Toggle signing
x = :encrypt<Enter> # Toggle encryption to all recipients
v = :preview<Enter> # Preview message
p = :postpone<Enter> # Postpone
q = :choose -o d discard abort -o p postpone postpone<Enter> # Abort or postpone
e = :edit<Enter> # Edit (body and headers)
a = :attach<space> # Add attachment
d = :detach<space> # Remove attachment

[terminal]
$noinherit = true
$ex = <C-x>

<C-p> = :prev-tab<Enter>
<C-n> = :next-tab<Enter>
<C-PgUp> = :prev-tab<Enter>
<C-PgDn> = :next-tab<Enter>
#+end_src

* Operation

Now that I have configured the program to my liking, I can run =aerc= in my
terminal and see my changes reflected!

Personally, I keep aerc running in a terminal at all times, since it has the
operation to ring a bell when a new message arrives.

#+caption: Notification
#+attr_html: :alt An image of the bell notification on macOS from aerc.
[[https://img.cleberg.net/blog/20251102-aerc-macos/notification.webp]]

The mailbox views and composition screens are fairly standard, but it does a
great job at displaying information effectively.

#+caption: Inbox
#+attr_html: :alt An image of the aerc inbox view.
[[https://img.cleberg.net/blog/20251102-aerc-macos/inbox.webp]]

#+caption: Compose Message
#+attr_html: :alt An image of Emacs being used as the composition window for aerc.
[[https://img.cleberg.net/blog/20251102-aerc-macos/compose.webp]]

#+caption: Send Message
#+attr_html: :alt An image of the aerc commands to send an email.
[[https://img.cleberg.net/blog/20251102-aerc-macos/send.webp]]

#+caption: Read Message
#+attr_html: :alt An image of an email opened in aerc's reading window.
[[https://img.cleberg.net/blog/20251102-aerc-macos/read.webp]]

All in all, I love aerc and far prefer it to my previous client (neomutt). In
certain cases, Thunderbird is more convenient, but I don't find myself opening
it at all lately. I will definitely update this post in the future if I find
anything extraordinary to add about aerc.