cmc/cleberg.net

My personal web garden & blog.

clone: git clone https://gitbay.org/cmc/cleberg.net.git

main: content/blog/2024-04-18-mu4e.org · raw

  1#+date:        [2024-04-18 Thu 00:00:00]
  2#+title:       mu4e with Doom Emacs on macOS
  3#+description: Setting up mu4e for email inside Doom Emacs on macOS.
  4#+slug:        mu4e
  5#+filetags:    :emacs:linux:
  6
  7This post was heavily inspired by [[https://macowners.club/posts/email-emacs-mu4e-macos/][Email setup in Emacs with Mu4e on macOS]], but
  8with my own tweaks for a single-account configuration and some Doom-specific
  9configurations.
 10
 11* Overview
 12
 13[[https://github.com/emacsmirror/mu4e][Mu4e]] is an Emacs-based email client based on [[https://www.djcbsoftware.nl/code/mu/][mu]], an indexer that stores email in
 14the Maildir format.
 15
 16This blog post covers the installation of Mu4e in Doom Emacs on macOS. This
 17guide should be very similar to GNU Emacs and Linux-based systems, with a few
 18tweaks required in the various configuration files.
 19
 20* Installation
 21
 22** Prerequisites
 23
 24*** Create the Folder Structure
 25
 26Start by creating the base folder structure:
 27
 28#+begin_src sh
 29mkdir ~/.maildir
 30mkdir ~/.maildir/example      # use whatever name you want to call your email account
 31mkdir ~/.maildir/certificates # used to store system root certificates
 32#+end_src
 33
 34*** Store Email Account Passwords in macOS Keychain
 35
 36Next, I will be using the macOS Keychain to store my email account passwords
 37using the command below.
 38
 39#+begin_src sh
 40security add-generic-password -s mu4e-example -a you@example.com -w
 41#+end_src
 42
 43This will prompt you to input your password twice to confirm. Keep the
 44=mu4e-example= name in mind, as you will need to reference it later in the IMAP
 45and SMTP configuration files.
 46
 47*** Store Root Certificates
 48
 49In order to use IMAP and SMTP, we need to provide certificates to the local
 50services. We will use the macOS defaults for this.
 51
 521. Open =Keychain Access.app=.
 532. Select =System Roots= in the sidebar.
 543. Select all items with =CMD + a=.
 554. Export selected items with =SHIFT + CMD + a= to the file
 56   =~/.maildir/certificates/root-certificates.pem=.
 57
 58*** Install Dependencies
 59
 60Install =mbsync= (via =isync=) to fetch emails via IMAP, =mu= to index emails,
 61and =msmtp= to send emails via SMTP.
 62
 63#+begin_src sh
 64brew install mu isync msmtp
 65#+end_src
 66
 67** Installing Mu4e
 68
 69Within Doom Emacs, we can install Mu4e by enabling the package.
 70
 71#+begin_src sh
 72nano ~/.doom.d/init.el
 73#+end_src
 74
 75In this file, uncomment the =mu4e= line within the =:email= section. You can
 76also enable the =+org= and =+gmail= options if you prefer.
 77
 78#+begin_src lisp
 79(doom! :input
 80       ...
 81       :email
 82       mu4e
 83       ;;(mu4e +org +gmail)
 84       ...
 85       (default +bindings +smartparens))
 86#+end_src
 87
 88* Configuration
 89
 90As an overall suggestion, I create the following configuration files in the
 91=~/.maildir= directory and using symlinks to their proper locations so that I
 92can backup and restore these files easily.
 93
 94#+begin_src sh
 95touch ~/.maildir/.mbsyncrc && \
 96touch ~/.maildir/.msmtprc  && \
 97ln -s /Users/username/.maildir/.mbsyncrc /Users/username/.mbsyncrc && \
 98ln -s /Users/username/.maildir/.msmtprc /Users/username/.msmtprc
 99#+end_src
100
101You can also create these files in your home directory and skip the symlinking
102process above.
103
104** IMAP
105
106Next, let's configure =mbsync= in the file created above. Paste the following
107information and customize it to match your mail provider's information.
108
109#+begin_src sh
110nano ~/.maildir/.mbsyncrc
111#+end_src
112
113#+begin_src conf
114IMAPAccount example
115Host imap.example.com
116User dummy@example.com
117PassCmd "security find-generic-password -s mu4e-example -a dummy@example.com -w"
118Port 993
119SSLType IMAPS
120AuthMechs Login
121CertificateFile ~/.maildir/certificates/root-certificates.pem
122
123IMAPStore example-remote
124Account example
125
126MaildirStore example-local
127SubFolders Verbatim
128Path ~/.maildir/example/
129Inbox ~/.maildir/example/INBOX
130
131Channel example
132Far :example-remote:
133Near :example-local:
134Patterns *
135Create Near
136Sync All
137Expunge Both
138SyncState *
139#+end_src
140
141** SMTP
142
143Next, let's configured =msmtprc= in the file created above. Paste the following
144information and customize it to match your mail provider's information.
145
146#+begin_src sh
147nano ~/.maildir/.msmtprc
148#+end_src
149
150#+begin_src conf
151# Set default values for all the accounts.
152defaults
153logfile ~/.maildir/msmtp.log
154tls_trust_file ~/.maildir/certificates/root-certificates.pem
155
156# ======================================================================
157
158account startmail
159auth on
160host smtp.startmail.com
161port 465
162protocol smtp
163from hello@cleberg.net
164user hello@cleberg.net
165passwordeval security find-generic-password -s startmail -a hello@cleberg.net -w
166tls on
167tls_starttls off
168
169# ======================================================================
170
171account default : startmail
172#+end_src
173
174** Doom Emacs
175
176Finally, we need to configure Doom Emacs to use the proper packages and set some
177variables and functions.
178
179#+begin_src sh
180nano ~/.doom.d/config.el
181#+end_src
182
183#+begin_src lisp
184;; load packages and programs
185(use-package mu4e
186  :load-path  "/Users/username/.emacs.d/modules/email/mu4e/")
187(require 'smtpmail)
188(setq mu4e-mu-binary (executable-find "mu"))
189
190;; set base directory
191(setq mu4e-maildir "~/.maildir")
192
193;; sync imap servers
194(setq mu4e-get-mail-command (concat (executable-find "mbsync") " -a"))
195
196;; how often to sync in seconds
197(setq mu4e-update-interval 300)
198
199;; save attachments to defined directory
200(setq mu4e-attachment-dir "~/Downloads")
201
202;; rename files when moving - needed for mbsync:
203(setq mu4e-change-filenames-when-moving t)
204
205;; list of your email adresses:
206(setq mu4e-user-mail-address-list '("you@example.com"))
207
208;; check your ~/.maildir to see naming of subdirectories
209(setq   mu4e-maildir-shortcuts
210        '(("/example/INBOX" . ?e)
211          ("/example/Sent" . ?E)))
212
213(setq mu4e-contexts
214      `(,(make-mu4e-context
215          :name "example"
216          :enter-func
217          (lambda () (mu4e-message "Enter you@example.com context"))
218          :leave-func
219          (lambda () (mu4e-message "Leave you@example.com context"))
220          :match-func
221          (lambda (msg)
222            (when msg
223              (mu4e-message-contact-field-matches msg
224                                                  :to "you@example.com")))
225          :vars '((user-mail-address . "you@example.com")
226                  (user-full-name . "Christian Cleberg")
227                  ;; check your ~/.maildir to see how the subdirectories are called
228                  ;; e.g `ls ~/.maildir/example'
229                  (mu4e-drafts-folder . "/example/Drafts")
230                  (mu4e-refile-folder . "/example/Archive")
231                  (mu4e-sent-folder . "/example/Sent")
232                  (mu4e-trash-folder . "/example/Trash")))))
233
234(setq mu4e-context-policy 'pick-first) ;; start with the first (default) context;
235(setq mu4e-compose-context-policy 'ask) ;; ask for context if no context matches;
236
237;; gpg encryptiom & decryption:
238;; this can be left alone
239(require 'epa-file)
240(epa-file-enable)
241(setq epa-pinentry-mode 'loopback)
242(auth-source-forget-all-cached)
243
244;; don't keep message compose buffers around after sending:
245(setq message-kill-buffer-on-exit t)
246
247;; send function:
248(setq send-mail-function 'sendmail-send-it
249      message-send-mail-function 'sendmail-send-it)
250
251;; send program:
252(setq sendmail-program (executable-find "msmtp"))
253
254;; select the right sender email from the context.
255(setq message-sendmail-envelope-from 'header)
256
257;; mu4e cc & bcc
258(add-hook 'mu4e-compose-mode-hook
259          (defun timu/add-cc-and-bcc ()
260            "My Function to automatically add Cc & Bcc: headers.
261    This is in the mu4e compose mode."
262            (save-excursion (message-add-header "Cc:\n"))
263            (save-excursion (message-add-header "Bcc:\n"))))
264
265;; mu4e address completion
266(add-hook 'mu4e-compose-mode-hook 'company-mode)
267#+end_src
268
269Be sure to sync Doom to update the current configurations.
270
271#+begin_src sh
272doom sync
273#+end_src
274
275If you have Doom open, execute =SPC h r r= to reload the new configurations.
276
277* Initial Sync
278
279Once you have configured all of the relevant files, you can perform an initial
280sync. Note that you can perform syncing within Mu4e itself after this.
281
282#+begin_src sh
283mbsync -aV
284#+end_src
285
286Once you sync the data, you can index the emails.
287
288#+begin_src sh
289mu init -m ~/.maildir --my-address you@example.com && \
290mu index
291#+end_src
292
293The emails will now to be ready to use!
294
295* Screenshots
296
297You can now launch Doom and open Mu4e with =SPC o m=. You can also explore the
298Mu4e options with =SPC : mu4e=.
299
300The home page shows various options and metadata about the account you've
301opened.
302
303#+caption: Mu4e Home Page
304#+attr_html: :alt The mu4e homepage within iTerm2, showing the basics, bookmarks, maildirs, and misc sections.
305[[https://img.cleberg.net/blog/20240418-mu4e/mu4e.webp]]