Better URL management in NeoMutt with urlscan | Hund


Better URL management in NeoMutt with urlscan

Saturday, May 22, 2021

There’s one thing that doesn’t work ideal in Mutt or NeoMutt; URLs in messages. While my terminal emulator URxvt supports URLs and I can copy and open URLs, it’s not an ideal workflow when there’s a bunch of URLs in a single message.

Thankfully, this is where urlscan comes in the picture and saves the day. urlscan is a piece of software that extract URLs from any message (or any text file) and then allow the user to select and open any URL in the default web browser.

I use the text based web browser Lynx to render HTML messages. It usually looks like this:

As you can see, there’s no visible URLs. They’re all grouped down at the bottom of the message, without any context. This can make it hard to figure out which URL I’m interested in, especially when they’re all annoying obfuscated tracking links.

This is where urlscan comes in. When I press Ctrl+B, it opens urlscan and presents me the URLs with some context:

If the environment variable $BROWSER is set to a browser command, then that specified browser is used. The $BROWSER environment variable is only honored if the rc-file doesn’t contain the COMMAND option.


In Gentoo, it’s available as the package net-mail/urlscan:

# emerge --ask net-mail/urlscan


I have simply added these two macros to NeoMutt:

macro index,pager \cb "<pipe-message> urlscan<Enter>" "call urlscan to extract URLs out of a message"
macro attach,compose \cb "<pipe-entry> urlscan<Enter>" "call urlscan to extract URLs out of a message"

And don’t forget to set your $BROWSER variable. I have this in my ~/.zshrc file:

export BROWSER=""

The script contains this:


qutebrowser-tmp $1 >/dev/null 2>&1 & disown -a

And the script qutebrowser-tmp is script that creates a temporary session with qutebrowser for me. That script looks like this:


PROFILEDIR=`mktemp -p /tmp -d tmp-qb-profile.XXXXXX.d`
mkdir $PROFILEDIR/config
cp ~/.config/qutebrowser/{user-stylecheet.css,autoconfig.yml} $PROFILEDIR/config/
mkdir $PROFILEDIR/data/userscripts/
cp ~/.local/share/qutebrowser/userscripts $PROFILEDIR/data/userscripts/
qutebrowser --basedir $PROFILEDIR $1