💾 Archived View for laniakea.rodoste.de › tui › mutt.gmi captured on 2023-12-28 at 15:27:48. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-11-04)

-=-=-=-=-=-=-

🏠 home

mutt: mail client

2023-05-26

Mutt is a mail client that claims to suck less than many others. I believe that to be true, simply because it can be configured till the cows come home to work _precisely_ as you want it.

Of course, the downside is that personally, I found it pretty much unavoidable to configure it a lot until it becomes usable.

I cannot possibly include a full setup explanation here, but I'll try to cover the things I found necessary to make mutt superior to many other CLI mail clients for my own usecase.

As you might have guessed already, I want vim-keys for navigation. Also, I want the option to GPG-sign and -encrypt messages, work with different mail accounts and some of them being gmail, work with gmail labels efficiently.

config file structure

Mutt allows for a very flexible config file structure within ~/.config/mutt/ and I'm using that to keep track of things. Here is a rough outline:

~/.config/mutt/ 
 ↳ muttrc               the main config file, this is what mutt actually loads
 ↳ account-abc.rc       config file for account 'abc'
 ↳ account-abc.gpg      gpg-encrypted mail account password for 'abc'
 ↳ account-def.rc       config file for account 'def'
 ↳ account-def.gpg      gpg-encrypted mail account password for 'def'
 ↳ appearance.rc        global look and feel config
 ↳ colors-tokyonight    my theme, contains color declarations
 ↳ common.rc            global config options. to be fair this could be inside muttrc
 ↳ gpg.rc               GPG commands. GPG _behaviour_ is in the account.rcs
 ↳ keybinds.rc          keybind changes

mutt itself will load the `muttrc` file. Its basic structure looks like this:

# this is the main script
#
# it loads all common .rc files,
# configures folder hooks and useful macros to switch accounts
# and then sources the default account

# general settings are included
source ~/.config/mutt/common.rc
source ~/.config/mutt/gpg.rc
source ~/.config/mutt/appearance.rc
source ~/.config/mutt/keybinds.rc

# configure folder hooks and macros for all accounts
folder-hook 'account-abc' 'source ~/.config/mutt/account-abc.rc'
folder-hook 'account-def' 'source ~/.config/mutt/account-def.rc'

# load default account
source '~/.config/mutt/account-abc.rc'

# account switching macros
macro index <f2> '<sync-mailbox><enter-command>source ~/.config/mutt/account-abc.rc<enter><change-folder>!<enter>'
macro index <f3> '<sync-mailbox><enter-command>source ~/.config/mutt/account-def.rc<enter><change-folder>!<enter>'

# styling
source ~/.config/mutt/colors-tokyonight

As you might have spotted, I can switch between accounts by pressing F2 / F3.

account config

There really isn't anything special here: The `account-xyz.rc` files source the GPG-encrypted passwords, set all parameters and folders for the mail account and configure the GPG setup. The GPG setup isn't centralized because I want only my main account to automatically sign my messages. All others are GPG capable but completely passive.

There is a separate section on GPG further down.

What the main `account.rc` file also does is activate the sidebar and configure the relevant GMail mailboxes to show up in the sidebar. More on that in the sidebar section.

GPG

The main `gpg.rc` file only configures the mutt command to call the right GPG commands in turn.

set crypt_use_gpgme=yes
set pgp_decode_command="gpg --status-fd=2 %?p?--passphrase-fd 0 --pinentry-mode=loopback? --no-verbose --quiet --batch --output - %f"
set pgp_verify_command="gpg --status-fd=2 --no-verbose --quiet --batch --output - --verify %s %f"
set pgp_decrypt_command="gpg --status-fd=2 %?p?--passphrase-fd 0 --pinentry-mode=loopback? --no-verbose --quiet --batch --output - %f"
set pgp_sign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0 --pinentry-mode=loopback? --armor --detach-sign --textmode %?a?-u %a? %f"
set pgp_clearsign_command="gpg --no-verbose --batch --quiet --output - %?p?--passphrase-fd 0 --pinentry-mode=loopback? --armor --textmode --clearsign %?a?-u %a? %f"
set pgp_encrypt_only_command="/usr/lib/mutt/pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust -- -r %r -- %f"
set pgp_encrypt_sign_command="/usr/lib/mutt/pgpewrap gpg %?p?--passphrase-fd 0 --pinentry-mode=loopback? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust -- -r %r -- %f"
set pgp_import_command="gpg --no-verbose --import %f"
set pgp_export_command="gpg --no-verbose --export --armor %r"
set pgp_verify_key_command="gpg --verbose --batch --fingerprint --check-sigs %r"
set pgp_list_pubring_command="gpg --no-verbose --batch --quiet --with-colons --with-fingerprint --list-keys %r"
set pgp_list_secring_command="gpg --no-verbose --batch --quiet --with-colons --with-fingerprint --list-secret-keys %r"
set pgp_good_sign="^\\[GNUPG:\\] Good signature from"
set pgp_check_gpg_decrypt_status_fd

This is a mixup of several sources, including an old mutt-gnupg-howto:

codesorcery.net mutt-gnupg-howto

How a mail account handles GPG is configured in the respective `account.rc` file.

For example the config below activates pgp for my respective key and will automatically sign all outgoing mails, including replies.

It will also automatically encrypt mails from people I have a key for.

set pgp_use_gpg_agent = yes
set crypt_autopgp = yes
set pgp_default_key="..."
# automatically sign all mails, even unsigned / unencrypted ones
set crypt_autosign = yes
# DO sign / encrypt replies to mails which are themselves signed / encrypted
set crypt_replysign = yes
set crypt_replyencrypt = yes
set crypt_replysignencrypted = yes
#-- automatically encrypts mails to recipients we have a key of
set crypt_opportunistic_encrypt = yes

For accounts that don't use GPG at all, I need to `set crypt_autopgp = no` to deactivate.

the sidebar

For the longest time I didn't know that the sidebar exists in mutt. I now use it to show the different mail folders and quickly navigate between them.

To activate the sidebar and display a bunch of existing mail folders:

set sidebar_visible = yes
mailboxes =INBOX =done =done/amazon =done/paypal =done/gemini =family 

To have the mailboxes appear exactly in the order I configure them, my `common.rc` sets the sorting:

set sidebar_sort_method = "unsorted"

To quickly navigate between sidebar folders I've chosen to use Ctrl plus j/k for vim-key like up and down, also Ctrl-l to go to the active mailbox. My `keybinds.rc` therefore contains:

bind index,pager  \Cj  sidebar-next
bind index,pager  \Ck  sidebar-prev
bind index,pager  \Cl  sidebar-open

For a bit of neatness my `appearance.rc` tweaks the vertical divider between sidebar and mail index / pager:

set sidebar_divider_char = "║"

To quickly send mails to a specific mailbox I have setup macros in `keybinds.rc`. For example:

bind index,pager \Ce noop
macro index,pager \Ce ":set confirmappend=no delete=yes\n<save-message>=done\n<sync-mailbox>:set confirmappend=yes delete=ask-yes\n"

This causes Ctrl-e to send the active mail (selected in the index or displayed in the pager) to be sent to my done folder.

Two gotchas here: Firstly: if the mailbox name contains a space I found mutt to behave randomly, mostly assigning other keyboard commands to the macro than what I configured. I couldn't find an escape sequence to mitigate this. Secondly: The built-in help sometimes didn't display that a keyboard shortcut was already used, so I find it wise to unbind the shortcut before assigning the macro.

keyboard shortcuts

I find that most default keybinds make a lot of sense. Nonetheless switching to vim-keys took some care, also the sidebar navigation above. There isn't much else to be honest.

# common keybinds

# by default IMAP mail fetching isn't bound, G is used for POP3
bind index G imap-fetch-mail

# scrolling in mail-view
## scroll with mouse-wheel
bind pager <up> previous-line
bind pager <down> next-line

## scroll with vim-keys
bind pager j next-line
bind pager k previous-line
bind pager h previous-entry
bind pager l next-entry
bind pager \Cf next-page
bind pager \Cb previous-page
bind pager \Cd half-down
bind pager \Cu half-up
bind pager b exit
bind index l display-message

# clear up some keybinds
bind pager i noop # seems bound to 'exit'
bind pager q noop # seems bound to 'exit'
bind pager x noop # seems bound to 'exit'

# move within sidebar
bind index,pager  \Cj  sidebar-next
bind index,pager  \Ck  sidebar-prev
bind index,pager  \Cl  sidebar-open

theming

I did only minor visual tweaking. One is to slightly change the colums in the index as well as introducing vertical dividers between the columns. The sidebar divider was already mentioned above. My `appearance.rc` file looks like this:

set date_format = "!%d %b %R"
set index_format = "%4C │ %Z │ (%?l?%4l&%4c?) │ %D │ %-30.30L │ %s"
set sidebar_divider_char = "║"

The other change was my theme. I like tokyonight although it is overdone. Also I couldn't actually find a tokyonight theme for mutt so I made my own. It isn't complete but it works for me:

# colors-tokyonight

# general ------------ foreground ---- background -----------------------------
color indicator        black           cyan
color status           brightblack     magenta
color error            red             black
# unchanged below
color markers          color210        default
color message          default         default
color normal           default         default
color prompt           default         default
color search           color84         default
color tilde            color231        default
color tree             color141        default

# message index ------ foreground ---- background -----------------------------
color index            brightgreen     default  ~N # new unread messages
color index            brightgreen     default  ~O # old unread messages
color index            default         default  ~R # read messages
color index            green           default  ~U # unread messages
color index            cyan            default  ~Q # messages which have been replied to
color index            red             default  ~D # deleted messages
# unchanged below
color index            color84         default  ~F # flagged messages
color index            color215        default  ~T # tagged messages
color index            color141        default  ~v # messages part of a collapsed thread

# message headers ---- foreground ---- background -----------------------------
color header           color231        default  ^Subject:.*
color header           color231        default  ^From:.*
color header           color231        default  ^To:.*
color header           color231        default  ^Date:.*
color hdrdefault       cyan            default

# message body ------- foreground ---- background -----------------------------
color quoted           blue            default
color quoted1          brightblue      default
color quoted2          cyan            default
color quoted3          brightcyan      default
color quoted4          green           default
color body             color231        default  [\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+               # email addresses
color body             color228        default  (https?|ftp|gemini)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+        # URLs
color body             brightyellow    default  " [:;][-o][)/(|D]" # emoticons with nose
color body             brightyellow    default  " [:;][/)(|D]"     # emoticons without nose
color body             brightyellow    default  (o.O|O.o)         # emoticon: confused look
color body             color231        default  (^|[[:space:][:punct:]])\\*[^*]+\\*([[:space:][:punct:]]|$) # *bold* text
color body             color231        default  (^|[[:space:][:punct:]])_[^_]+_([[:space:][:punct:]]|$)     # _underlined_ text
color body             color231        default  (^|[[:space:]])/[^/]+/([[:space:][:punct:]]|$)     # /italic/ text
# unchanged below
color attachment       color228        default
color signature        color212        default

conclusion and links

I know this has been a long cheat sheet. It certainly took me quite a while to piece it all together. I am very certain that a lot of mutt goodness still evades me but with the setup above mutt has replaced my gmail webclient and Thunderbird. It is perfectly usable. Anything from here on out is optimization.

There are a lot of helpful links for mutt without I wouldn't have been able to get here. Also the man page is fantastic.

Some of the most important web resources:

an old mutt & gnupg howto. It is a very good source to understand GPG.

the official mutt manual

The mutt command reference. Anything that can be `set` in the .rc files.

Sadly, getting mail encryption going isn't trivial, even today. I recommend these two sources to get started:

email self-defense

generating secure and easy-to-remember passphrases with diceware

---

see all articles on command-line tools