www-gem words

The power of emails in the terminal: Neomutt

Published on

cli

If you’ve ever opened your email in a web browser and felt that creeping frustration: the endless tabs, the sluggish loading, the feeling that your messages are trapped in some glossy corporate interface, then today’s story is for you.
I’ll talk about a way that’s been quietly thriving for decades among developers, system administrators, and people who simply love the feeling of control: Neomutt

This has been my way to make my inbox becoming a text interface where every action feels immediate, powerful, and minimal. Also, we’re no longer living in the 50s, and a terminal interface doesn’t have to be boring.

In this post, I assume you have Neomutt installed and your accounts configured. I’ll focus on sharing some post config info I found crucial in my workflow, but rarely mentioned online.

Some sections are lengthy because of config files descriptions. Here is a table of content to jump faster:

╭── The .mailcap file

This is the configuration file that tells NeoMutt how to handle different MIME types in your emails.

Let’s go through mine line by line:

╭── The muttrc file

STOP !!! I will list here all the lines of my own file along with their meanings when not obvious. I experimented extensively with customizations, but a functional file typically requires only a few of these lines.
Once again, the purpose of this blog is to share information that is not readily available elsewhere online. This list aims to provide insights into lesser-known topics.

Format of the index (see options here ):

If you want to use a sidebar with folders tree:

Start programs at launch. Davmail is needed for my work emails:

startup-hook '`davmail & \  
		mbsync -aqq & \  
		`'`

Execute some commads on close:

shutdown-hook '`kill $(pidof java) & \ # to kill Davmail  
		notmuch compact --quiet`'

Accounts specific config (see the accounts section ):

╭── Accounts-specific config

Stored in the [account_name] file in the mutt folder. Make sure it matches the name used in your .muttrc file.

╭── Neomutt is not boring

Neomutt can use icons as shown in the muttrc file, but you can also make it looks pretty. This is done by defining your colors in the colors file located in the mutt folder.
The basic structure for each color definition is color <element> <foreground> <background>

Here are few examples:

color	 indicator	    bold	    white	default
color	 index_author	cyan	    default	 "~f john.doe@gmail.com | ~C john.doe@gmail.com"
color	 body		    red 	    default	 "(^|[[:space:][:punct:]])\\~\\~[^*]+\\~\\~([[:space:][:punct:]]|$)" # strikethrough

There are also some colorschemes available out there, like on the official website .

╭── Keybindings

Stored in the bind file in the mutt folder.
I will not list all my keybindings, but share the ones that may be less obvious:

╭── Notmuch, is it?

Beyond its unassuming name, it revolutionizes email searching. This tool perfectly integrates into your workflow and will help you retrieve any email instantly due to its lightning-fast speed and comprehensive filtering system.

Using the vfolder-from-query command (see the keybindings section ), you can perfom any Notmuch search you like. For example:

╭── Davmail

If, like me, you are forced to use Outlook services Davmail could be a life saver. It’s a POP/IMAP/SMTP/Caldav/Carddav/LDAP gateway allowing users to use any mail client with Exchange, even from the internet through Outlook Web Access.
I let you check the link above to see how to configure it. Don’t worry, it’s a GUI and it’s pretty straightforward. Jut make sure to use localhost and the right ports for your imap and smtp in your config files.

╭── Use the evil HTML

People can’t save themselves from using poor formatting, and many large companies’ email services default to HTML. As a result, you - the email recipient - have to deal with that.

We’ve seen earlier how to show HTML email in Neomutt, but you may need to send some as well. After lots of experimentation, I’ve settle on using a script developped by Daring Fireball .

This script is part of several commands I execute when sending my emails. All commands are stored in a html_send bash script located in my .mutt folder, and called with a keybinding .
This script itself is called with perl ~/.mutt//Markdown.pl --html4tags "$1" > /tmp/conv.html in my global bash script.

╭── Conclusion

This concludes my journey writing this post, and may mark the beginning of your journey with Neomutt. If you’re already using this email client, I will be happy if this post brings you more ideas of customization.
I will be extremely happy to hear about your use of Neomutt. You may have a better approach with HTML emails for example.

As a final note, I’d say that Tom Robinson (@TomRobinsonIO@fosstodon.org) picked my interest with Aerc - especially its asynchronous approach - but my Outlook work email was not working. Aerc is unable to handle “malformed header”, which happens with some email providers. This issue is known for at least 10 years (1 , 2 , 3 )


SCRIPTS

The mutt_bgrun script:

#!/usr/bin/bash
# @(#) mutt_bgrun $Revision: 1.4 $

#   mutt_bgrun - run an attachment viewer from mutt in the background
#   Copyright (C) 1999-2002 Gary A. Johnson
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

# SYNOPSIS
#	mutt_bgrun viewer [viewer options] file
#
# DESCRIPTION
#	Mutt invokes external attachment viewers by writing the
#	attachment to a temporary file, executing the pipeline specified
#	for that attachment type in the mailcap file, waiting for the
#	pipeline to terminate, writing nulls over the temporary file,
#	then deleting it.  This causes problems when using graphical
#	viewers such as qvpview and acroread to view attachments. 
#
#	If qvpview, for example, is executed in the foreground, the mutt
#	user interface is hung until qvpview exits, so the user can't do
#	anything else with mutt until he or she finishes reading the
#	attachment and exits qvpview.  This is especially annoying when
#	a message contains several MS Office attachments--one would like
#	to have them all open at once. 
#
#	If qvpview is executed in the background, it must be given
#	enough time to completely read the file before returning control
#	to mutt, since mutt will then obliterate the file.  Qvpview is
#	so slow that this time can exceed 20 seconds, and the bound is
#	unknown.  So this is again annoying. 
#
#	The solution provided here is to invoke the specified viewer
#	from this script after first copying mutt's temporary file to
#	another temporary file.  This script can then quickly return
#	control to mutt while the viewer can take as much time as it
#	needs to read and render the attachment. 
#
# EXAMPLE
#	To use qvpview to view MS Office attachments from mutt, add the
#	following lines to mutt's mailcap file.
#
#	application/msword;             mutt_bgrun qvpview %s
#	application/vnd.ms-excel;       mutt_bgrun qvpview %s
#	application/vnd.ms-powerpoint;  mutt_bgrun qvpview %s
#
# AUTHOR
#	Gary A. Johnson
#	<garyjohn@spk.agilent.com>
#
# ACKNOWLEDGEMENTS
#	My thanks to the people who have commented on this script and
#	offered solutions to shortcomings and bugs, especially Edmund
#	GRIMLEY EVANS <edmundo@rano.org> and Andreas Somogyi
#	<aso@somogyi.nu>.

prog=${0##*/}

# Check the arguments first.

if [ "$#" -lt "2" ]
then
    echo "usage: $prog viewer [viewer options] file" >&2
    exit 1
fi

# Separate the arguments.  Assume the first is the viewer, the last is
# the file, and all in between are options to the viewer.

viewer="$1"
shift

while [ "$#" -gt "1" ]
do
    options="$options $1"
    shift
done

file=$1

# Create a temporary directory for our copy of the temporary file.
#
# This is more secure than creating a temporary file in an existing
# directory.

tmpdir=/tmp/$LOGNAME$$
umask 077
mkdir "$tmpdir" || exit 1
tmpfile="$tmpdir/${file##*/}"

# Copy mutt's temporary file to our temporary directory so that we can
# let mutt overwrite and delete it when we exit.

cp "$file" "$tmpfile"

# Run the viewer in the background and delete the temporary files when done. 

    "$viewer" $options "$tmpfile" >/dev/null 2>&1 &
    sleep 1 &&
    rm -f "$tmpfile"
    rmdir "$tmpdir"

The mutt-notif script:

Make sure to replace [Account] with your account name.

#!/usr/bin/bash

number=$(fd . ~/.mail/[Account]/Inbox/new | wc -l)

if [ "$number" -eq 1 ]; then
	notify-send -a [Account] "1 new email [Account]"
elif [ "$number" -gt 0 ]; then
	notify-send -a [Account] "$number new emails [Account]"
fi
exit 0

More food for thoughts? Check other posts about: #Cli


Thanks for your read. Hope it's been useful to you.


Interact with this post using Mastodon or

Comment on wwwgem's post

Copy and paste this URL into the search field of your favourite Fediverse app or the web interface of your Mastodon server.

✄ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈ ┈