Background fetch (or any command) in mutt
published:
signed with 0x683A22F9469CA4EBBy default, mutt runs external commands in the foreground of your mutt window. For long running tasks this can get kind of annoying.
I wrote a quick shell script to detect whether or not I’m in a tmux session, and if so, spawn an auto-closing background window to run offlineimap
:
#!/usr/bin/sh
# Are we in tmux?
if [ -z "${TMUX}" ]; then
# Did we pass in an account?
if [ -z "${1}" ]; then
offlineimap
else
offlineimap -a "$1"
fi
else
# Did we pass in an account?
if [ -z "${1}" ]; then
j
####################################################
# The -d flag tells tmux to create the new window,
# but not switch focus to it
####################################################
tmux new-window -d -n "fetching mail..." offlineimap
else
tmux new-window -d -n "fetching mail..." offlineimap -a "$1"
fi
fi
Then I updated the macro in my muttrc
to make use of the new handler:
macro index 0 "<enter-command>unset wait_key<enter><shell-escape>/path/to/syncmail.sh myaccountid<enter>" "run offlineimap to sync all mail"
macro index 0
triggers whenever the0
key is pressed in the mutt index view. There’s nothing special about this key or this view. You could bind it to any key in any view, this is just how mine is set up.<enter-command>unset wait_key<enter>
prevents having to pressenter
to return to the mutt index after kicking off the background sync.<shell-escape>
runs the script
Obviously this pattern isn’t limited to mail sync. You could use this to run any background task from within mutt, or from any other application running within tmux.
I considered making a generic tmux backgrounder script that would exec whatever args. This is definitely more composable, but I’ll cross that bridge if I ever have another use case.
Notes
There’s some repetition in the script, but it seems like that’s unavoidable. I’d preffer to encapsulate the offlineimap argument check in a function, but there doesn’t seem to be a way to have tmux evaluate shell functions.
I use multiple email accounts with offlineimap and opt to only sync the current one. If you only have one (or always want to sync all accounts), you can simplify the script to:
#!/usr/bin/sh
# Are we in tmux?
if [ -z "${TMUX}" ]; then
offlineimap
else
tmux new-window -d -n "fetching mail..." offlineimap
fi
and the macro to:
macro index 0 "<enter-command>unset wait_key<enter><shell-escape>/path/to/syncmail.sh<enter>" "run offlineimap to sync all mail"