Virtual Folders in mutt

by Kyle Rankin

Related link: http://larve.net/people/hugo/2003/scratchpad/VirtualFoldersInMutt.html



My email is generally well-organized. I have a lot of different folders and procmail rules that automatically move email to the various categories of email I've set up. Sometimes, though, I can't exactly remember which category a message is in. While mutt, my preferred email client, is great at searching for a term within a folder, it isn't as easy to search all of your email folders at once. I found a few possible solutions to this problem, and ended up rolling my own solution.



I was first inspired by this post that described using mairix to create a virtual folder in mutt. Mairix indexes all of your email folders, and allows you to search through this index with basic keyword searches. It then outputs the results into a maildir (or mbox if you want) so you can treat it like a virtual folder.



I set up mairix for a bit and tried it out, however I realized that most of my searches aren't simple "what emails contain these single words in them" much of the time. Some times I want to search for two words next to each other, but that's something mairix doesn't seem to be able to do. Sometimes I even want to use regular expressions in my searches, which mairix doesn't support.



My solution is a script called "maildirsearch" and looks like this:




#!/bin/sh

MAILDIRS="$HOME/mail"
VFOLDER="search"
VFOLDERPATH="$MAILDIRS/$VFOLDER/cur/"
FOLDERS=`awk '{print $2}' $HOME/.mutt/mailboxes | sed 's/^"\=\(.*\)\"$/\1 /' \
| xargs echo`

rm $VFOLDERPATH/*

for i in $FOLDERS
do
for j in `egrep -lR "$@" $MAILDIRS/$i`
do
ln -s $j $VFOLDERPATH/.;
done;
done;


I store my mail in a series of maildirs on my laptop in ~/mail/. The FOLDERS environment variable is populated with a one-liner that turns my .mutt/mailboxes file from this:




. . .
mailboxes "=oreilly"
mailboxes "=blog"
mailboxes "=nblug"
mailboxes "=google_alerts"
mailboxes "=debian"
mailboxes "=sent-mail"


into a list of folders separated by spaces. Then I egrep through each folder for my search term, finally symlinking any results into my virtual folder that I called "search" and put with the rest of my maildirs.



I realized that when I ran this search in mutt, what would be nice is for mutt to automatically change to this new folder while it was being populated with email. So I created a wrapper script that runs this script in the background, and then runs an extra instance of mutt inside itself, open to my virtual folder. It's a bit of a hack, but I can't seem to find a way yet to send commands to a running mutt process from outside mutt. I called this script "muttsearch":




#!/bin/sh

VFOLDER="search"
$HOME/bin/maildirsearch "$@" &
sleep 1;
mutt -f "=$VFOLDER";


Basically, since it runs mutt -f "=search", I can watch my search results as they appear, so I can go ahead and read through them without having to wait for the search to finish. Plus I can use all of the standard mutt filtering techniques at that point to refine the search. All that was left is to add a macro to my mutt config:




# search macro
macro index \eM "$HOME/bin/muttsearch "
macro browser \eM "$HOME/bin/muttsearch "


Now I can just type Esc-M from within mutt and type in my search term. I think for the future I'm going to extend this idea to provide other types of virtual folders from within mutt, possibly to create a folder of flagged messages on the fly.





How do you manage virtual folders in mutt? In your preferred email client?


2 Comments

moil
2005-02-03 14:36:34
A small change to avoid double-linking
I noticed when I ran the script that it tried to link the messages to themselves in $VFOLDER and gave me the following error message:



ln: Maildir/.Search/cur/1107194183.21186_45.panix3:2,S: File exists


so in maildirsearch I changed



for i in $FOLDERS


to



for i in ${FOLDERS/$VFOLDER/}


and it seems to work. Note that this is a bash solution. I don't know if it will work in other shells.


I also put an -f flag on rm so it won't send me an error message when $VFOLDER is empty.

moil
2005-02-09 14:43:25
A small change to avoid double-linking
Um, great script, by the way. It's small and elegant.


I've also been trying out nmzmail, another possible mutt-search solution.


And sorry about the ugly spacing in my previous post.