# Prefer the plain text part of multipart emails, followed by any enriched text
# part (?), followed by the HTML part, followed by any other parts. Decode the
# text/html part with .mailcap's chosen program (I favour Lynx).
#
alternative_order text/plain text/enriched text/html *
auto_view text/html
# If an outgoing message looks like I meant to attach something, and there
# isn't an attachment, prompt me to make sure I haven't forgotten it.
# I normally don't like this sort of nagging, but I'm making an exception in
# this case, as I really do trip up on this a lot. The default pattern of just
# 'attach' is a bit too aggressive, so I write a slightly softer one that
# reflects the usual way I refer to attachments.
#
set abort_noattach = ask-no
set abort_noattach_regexp = "attached is|(find|i've|see) attached"
# Don't assume I don't want to continue editing a message if I didn't change
# anything to it; if I want to send a message with just my signature, that's my
# right.
#
unset abort_unmodified
# Put the alias file in a nice XDG location, distinct from the muttrc, so that
# we don't end up losing them each time the dotfiles are reinstalled; `man
# 5 muttrc` points out that this file needs to be explicitly sourced, too.
#
set alias_file \
= ~/.config/mutt/aliases
source $alias_file
# Don't send terminal bells on errors, but do send them when new mail arrives,
# because that should light up my tmux window label and/or urxvt window.
#
unset beep
set beep_new
# Don't prompt me for confirmation if I move messages into an existing mailbox;
# just do it.
#
unset confirmappend
# Switch to a subject format for forwarded messages that's more familiar to
# most mail users.
#
set forward_format = 'Fw: %s'
# Cache message headers for speed; this really helps.
#
set header_cache \
= ~/.cache/mutt/headers
# Save command history; this saves other kinds of history as well, but all
# I really want is to be able to run the same commands again even after I quit
# Mutt. We can afford to keep 2^8 of these, since it's the future and all.
#
set history_file = \
~/.cache/mutt/history
set history = 256
set save_history = $history
# Always put a quoted copy of the whole message in a reply text for me to chop
# up and respond to in Vim--no need to prompt me (the default does that).
#
set include
# Tweak the index format to include spam tagging information, if any, with the
# %H format string
#
set index_format = '%4C %Z %{%b %d %Y} %-15.15L (%?l?%4l&%4c?) %?H?[%H] ?%s'
# Don't show any nasty little markers at the start of wrapped lines. That's
# the sort of thing Vim cares about, if need be.
#
unset markers
# Created mailboxes are in Maildir format everywhere I deploy this, so may as
# well set it in here rather than get annoyed when Mutt starts dropping mboxes
# everywhere if I leave it out of muttrc.d/*.rc.
#
set mbox_type = Maildir
# Show a few messages of the index when in pager mode to give a little context
# around the message. I should have been doing this years ago. Oh well.
#
set pager_index_lines = 6
# Don't move on to the next message if we're at the end of the current one just
# because I executed <next-page>.
#
set pager_stop
# Use the abook program for finding and completing addresses with ^T. I do use
# the aliases system for regular correspondents, too.
#
set query_command = 'abook --mutt-query %s'
# Check with me whether I really want to quit, just in case I've hit "q" too
# many times trying to get out of e.g. the aliases menu.
#
set quit = ask-yes
# I prefer a slightly stricter pattern to match what is and isn't a quote; this
# avoids flagging things like closing braces on new lines in code blocks as
# quotes.
#
set quote_regexp = '^(>[ \t]*)+'
# Don't offer to resume a postponed message when I hit <mail>; I'll use
# <recall-message> for that.
#
set recall = no
# Don't delay on switching or altering mailboxes so that I see the messages;
# just do it straight away.
#
set sleep_time = 0
# Only use the headers with proper references to link messages in a thread;
# don't try to use pattern matches on subjects, which might be rubbish like
# "hi". If I need to link a thread together because it's been broken somehow,
# I'll do that manually.
#
set strict_threads
# Use format=flowed, continuing paragraphs for lines that end with a single
# space, and use that wrapping information to use the full width of the
# terminal for the wrapping display.
#
set text_flowed
set reflow_wrap = 0
# When passing mail to the sendmail binary, use the "From" address I set as the
# envelope sender, in case the local mailserver needs to do any switching or
# filtering based on that.
#
set use_envelope_from
# Don't wait for me to press a key after running a command if it exited
# successfully; this still warns me if something failed, though.
#
unset wait_key
# Use the GPGME library for PGP; sign replies to messages that are themselves
# signed (whether encrypted or not), and encrypt when we have a key for every
# recipient (opportunistic).
#
set crypt_use_gpgme
set crypt_opportunistic_encrypt
set crypt_replysign
set crypt_replysignencrypted
# Use a default key for self-encrypting both sent and draft messages so that
# they're protected but legible. This defaults to the GPG_KEYID environment
# variable, so be careful to set that lest you send useless OpenPGP headers!
# My kingdom for muttrc(5) conditionals...
#
set pgp_default_key = $GPG_KEYID
set pgp_self_encrypt
set postpone_encrypt
# Always include OpenPGP header with the selected default key, regardless of
# whether the message is protected or not:
#
# <https://datatracker.ietf.org/doc/draft-josefsson-openpgp-mailnews-header/>
#
# This RFC has expired and doesn't seem to have seen widespread adoption, but
# it looks like Thunderbird's Enigmail extension is still sending key IDs with
# it, and it doesn't do any harm.
#
my_hdr OpenPGP: id=$pgp_default_key\; \
preference=signencrypt\; \
url=https://keys.openpgp.org/vks/v1/by-fingerprint/$pgp_default_key
# Because I (personally) never want to encrypt mail without signing it, add in
# a hook for sending or changing a message that forces a signature if it's
# encrypted but not signed. This may not suit anyone else reading.
#
send-hook '~G !~g' 'push <pgp-menu>s'
send2-hook '~G !~g' 'push <pgp-menu>s'
# Because of the order in which opportunistic encryption is applied, we queue
# up a no-op change by opening the PGP menu and then doing nothing (pressing
# Enter), to trigger send2-hooks to run and turn signatures on if opportunistic
# encryption happens to have decided to switch encryption on.
#
send-hook '!~G !~g' 'push <pgp-menu><enter>'
# Failing all of the above, maybe autocrypt will passively give us a key to
# use, but don't store its keys in our primary keyring.
#
set autocrypt
set autocrypt_dir \
= ~/.local/share/mutt/autocrypt
# Set custom filter to generate an HTML part for plain-text messages in
# Markdown style; defaults to off, per God's will and common decency.
#
set send_multipart_alternative_filter \
= ~/.local/libexec/mutt/filters/markdown-to-html
# Toggle multipart sending option manually and display the new setting
macro generic,index,browser,pager \\h '\
<enter-command>toggle send_multipart_alternative<enter>\
<enter-command>set ?send_multipart_alternative<enter>' \
'Toggle multipart/alternative sending'
# Shortcuts to jump to mailboxes
macro generic,index,browser,pager \\b \
'<change-folder>-<enter>' \
'Change to previous'
macro generic,index,browser,pager \\i \
'<change-folder>!<enter>' \
'Change to inbox'
macro generic,index,browser,pager \\r \
'<change-folder><<enter>' \
'Change to sent'
# Shortcuts to save to mailboxes
macro generic,index,browser,pager \\\Cb \
'<save-message>-<enter>' \
'Move message to previous'
macro generic,index,browser,pager \\\Ci \
'<save-message>!<enter>' \
'Move message to inbox'
macro generic,index,browser,pager \\\Cr \
'<save-message><<enter>' \
'Move message to sent'
# Shortcut to add addresses to abook
macro index,pager \\a \
'<pipe-message>abook --add-email-quiet<enter>' \
'Add sender address to abook'
# Shortcut to reload configuration
set my_muttrc \
= ~/.config/mutt/muttrc
macro generic,index,browser,pager \\R '\
<enter-command>unhook *<enter>\
<enter-command>source $my_muttrc<enter>\
<enter-command>echo "Reloaded $my_muttrc"<enter>' \
"Clear hooks and reload"
# Shortcut to toggle thread display
set my_sort_alt = threads
macro index \\t '\
<enter-command>set my_sort_cur = $sort<enter>\
<enter-command>set sort = $my_sort_alt<enter>\
<enter-command>set my_sort_alt = $my_sort_cur<enter>' \
"Toggle thread display"
# Set a few simple colors just for a quick visual cue of which tool I'm looking
# at and for some visual distinction between text, signature, and quote. The
# navigation bar is a nice dark green.
#
color attachment \
brightyellow default
color hdrdefault \
brightcyan default
color quoted \
brightgreen default
color signature \
cyan default
color status \
default color22
# Load machine-specific or account-specific settings from the helper script in
# muttrc.d, and w're done.
#
source ~/.config/mutt/muttrc.d/src|