LJ Archive

Tech Tips

Mutt macros make e-mail sorting and navigation a breeze, and a handy script to help you find other scripts.

An Easy Way for Mutt Users to Move Mail into Designated Folders

You'd think with all the wonderful GUI IMAP e-mail clients available, the character-based Mutt wouldn't have much appeal. Yet, a number of us at Linux Journal are still hooked on Mutt for at least part of our e-mail usage. One reason is that you can configure Mutt to behave just about any way you like.

Ideally, you can write server-side filters to sort your mail into the appropriate folders, and I have a number of filters to do just that. However, the filters aren't perfect, and many news alerts, press releases and the like end up in my inbox. I can spot them from the subject lines. So, I have created a long list of macros for Mutt to file away mail into specific folders from the inbox index. I can tuck away mail with a single Ctrl-keystroke, which beats the heck out of dragging and dropping mail to a sidebar with a folder tree (or worse, a cascading “move” menu). Here's a short sample of my list of macro keystrokes. You can put your own set in the .muttrc configuration file in your home directory.

The following list of macros lets me press Ctrl-R to send the currently highlighted message to my Read folder (that's Read as in past tense), Ctrl-P to send it to my Press-Releases folder (which is a subfolder of Folders), Ctrl-N to send it to News-Alerts, and so on. As you can see, I've tried to associate the letter with the action to make the keystrokes easy to remember (Ctrl-K kills the message to the SPAM bin):

macro index \Cr "s=Read\r"
macro index \Cp "s=Folders/Press-Releases\r"
macro index \Cn "s=Folders/News-Alerts\r"
macro index \Ch "s=Folders/Humor\r"
macro index \Ck "s=SPAM\r"

I also spend a lot of time stepping through messages with the preview pane open though. The above list of macros won't work in preview mode. If you want to be able to do the same operations while previewing mail with the pager, add a duplicate list like this:

macro pager \Cr "s=Read\r"
macro pager \Cp "s=Folders/Press-Releases\r"
macro pager \Cn "s=Folders/News-Alerts\r"
macro pager \Ch "s=Folders/Humor\r"
macro pager \Ck "s=SPAM\r"

Mutt gives you a way to navigate through your folders, but this is one case when it's not as easy as GUI clients that provide a sidebar folder tree where you can click on the folder you want to open. Here are some macros to navigate to your most commonly used folders to read the messages you've filed away:

macro index ",r"  "c=Read\nOd="
macro index ",p"  "c=Folders/Press-Releases\nOd="
macro index ",n"  "c=Folders/News-Alerts\nOd="
macro index ",h"  "c=Folders/Humor\nOd="
macro index ",k"  "c=SPAM\nOd="

I've gotten used to thinking of the comma key as my “go-to” key, so I can go to the Press-Releases subfolder by typing the keys , and then p. The combination ,n takes me to News-Alerts, and so on. If the comma isn't intuitive for you, pick another keystroke and modify the macros accordingly.

Naturally, you'll want to be able to get back to the inbox easily. So, I do that with the ,i combination. Once again, you may want to create a duplicate that works if you are using the preview pager. Simply substitute the address of your IMAP server for <yourmailserver>, and it should work for you:

macro index ",i"  "cimap://<yourmailserver>/INBOX\nOd="
macro pager ",i"  "cimap://<yourmailserver>/INBOX\nOd="

One final note: you may be wondering why each of the navigation macros ends with \n and then Od=. The \n executes the move to the new folder, and the 0d= tells Mutt to sort the messages by date. That way, if you have changed the sort order of messages while reading your mail, Mutt always will use the date sort when you change folders with the macro command.

You can find all the info you need to customize your copy of Mutt in the Mutt manual on-line at www.mutt.org/doc/manual. It may take a bit of work getting Mutt to perform just the way you like, but once you've got it customized to your tastes, you may find it very difficult to go back to using a GUI e-mail client.

—Nicholas Petreley

Finding a Needle in a Haystack of Scripts

This script is the combined effort of Linux Journal Webmaster Keith Daniels, whose work was modified by a reader named Karl, who gave us this submission. It lets you find a script based on a keyword you might recall that occurs in the script.


  1. Don't force the four-line restriction on the length of each script's header.

  2. Allow multiple search paths (not only ~/bin/).

  3. Support display of the script's path/name without hard-coding it into the header.


#- NAME:    ~/bin/scriptsearch
#- PURPOSE: grep for patterns in all scripts
#  under preset search
#  paths; output header lines in each matching script
#- NOTES:   all lines beginning with '#-' are assumed
#  to be header lines
#- USAGE:   scriptsearch <grep pattern>

# paths in which all scripts will be searched
SEARCH_PATHS="${HOME}/bin /usr/local/bin"

if [ ${1} ]; then
    for PATH in ${SEARCH_PATHS}; do
        echo -e "\n...searching ${PATH}...\n"
        # find list of matching files for current
        # search path
        MATCHES="`/bin/grep -li $1 ${PATH}/*`"

        for MATCH in ${MATCHES}; do
            # print summary for each matching file
            echo "#====<script> ${MATCH}"
            /bin/grep -i '^#-' ${MATCH}
            echo -e "#====</script>\n"

Note that a side effect of the way I handled the first objective is that my Perl scripts, which often have a print_usage() function with a print qq{...} spanning multiple lines can be searched as well without duplicating the print_usage() function. Simply prefix each line in the qq{...} with #-.

I added the -i option to the grep command for ${MATCHES}. It's a very simple change but quite important, as I don't want to lose relevant results simply because my search keywords are lowercase but the script contains matches with uppercase characters (var names and comments might be our memory cues for finding the script, and they commonly contain uppercase).

—Karl Erisman and Keith Daniels

LJ Archive