Preprocessing of muttrc with m4/cpp

See also my list of hacks for Mutt.

What it does

I use Mutt in a lot of different contexts: at work, on my laptop while connected to a network, on my laptop while in a plane, to read my private email, to read my work email, etc.

I ended up, even though I modularized my muttrc when I started using Mutt in 1997 (one file for key binding, another one for the UI look, etc), with lots of different configuration files to maintain, and often having to do a modification in 4 different muttrcs.

I saw somebody wanting to add some conditional processing of muttrc, but I thought: This won't make it in Mutt 1.4, and there's got to be a way to do this now.

cpp (the GNU C-Compatible Compiler Preprocessor) uses directives starting with # which is muttrc's comment character. It is therefore perfect for doing conditional preprocessing of muttrc.

Update (2003-02-06): actually, m4 is better suited than cpp for this job, so I ended up converting my muttrc cpp format into a muttrc m4. It works exactly the same, with a slightly different syntax.

Configuration file: muttrc.cpp or muttrc.m4

I have a master muttrc.cpp which contains the configuration for all my profiles.

The file looks like a standard muttrc configuration file, with cpp directives added.

For example, here is how I declare where my folders are depending on how I invoke Mutt:

# Folders

#ifdef WORK_CONF
  #ifdef USE_IMAP
    #define FOLDER "{localhost:1430}mail"
  #else
    #define FOLDER "~/mail"
  #endif
#else
  #ifdef USE_IMAP
    #define FOLDER "{localhost:1430}private-mail"
  #else
    #define FOLDER "~/private-mail"
  #endif
#endif

set folder=FOLDER

The m4 version looks as follows:

changequote([[[, ]]])

# Folders

ifdef([[[WORK_CONF]]], [[[
  ifdef([[[USE_IMAP]]], [[[
    define([[[LOCALFOLDER]]], [[["{localhost:1430}mail"]]])
  ]]], [[[
    define([[[LOCALFOLDER]]], [[["~/mail"]]])
  ]]])
]]], [[[
  ifdef([[[USE_IMAP]]], [[[
    define([[[LOCALFOLDER]]], [[["{localhost:1430}private-mail"]]])
  ]]], [[[
    define([[[LOCALFOLDER]]], [[["~/private-mail"]]])
  ]]])
]]])

set folder=LOCALFOLDER

Invoking Mutt: my_mutt

I invoke Mutt with a script which preprocess my muttrc.cpp and then configures Mutt with the result.

This shell script is called my_mutt, and it accepts arguments for cpp (before --) and for Mutt (after --). For example, I can run my_mutt -DWORK_CONF -DON_LAPTOP -- foo@example.com.

Comments, contributions

Please send them to hugo@larve.net.

I know that my_mutt, if run more than once at a time, leads to a race condition for the generation of the muttrc. I have been to lazy to fix this. I want to run exec mutt at the end of the script but it seems that fighting against the race condition will make me keep the shell to delete the specfic muttrc I use once I close Mutt, which I was trying to avoid.


Hugo Haas
$Id: mutt-cpp.html 2081 2003-04-16 12:54:58Z hugo $