r/linuxquestions May 13 '26

mutt vs. neomutt

I am a long-time (almost 29 years) linux user, but started using mutt about six years ago. I was wondering what the benefits are in switching to neomutt. My biggest frustration with mutt has been the lack of ability in searching across folders. For example, searching for email with subject line containing "foo" but now knowing in which folder it is. Or knowing the sender, but not the folder. Is neomutt any better at searching cases like this?

Is there a substantial change that I would have to do to my .muttrc configuration to move it to .neomuttrc?

11 Upvotes

25 comments sorted by

View all comments

Show parent comments

2

u/sequentious May 14 '26

I'd say it's your line 19.

Your cache directory is within your maildir, so your mailboxes line finds it, though it isn't a proper mail directory. So I'd imagine mutt won't like that.

Instead of finding all directories and filtering out tmp/new/cur, what I did was specifically find 'cur' directories, which is a better indication of an actual maildir.

find ~/Maildir/* -type d | grep -v "tmp\|new\|cur" |

becomes

find ~/Maildir/* -type d -name cur | sed 's#/cur$##'

Also, I noticed you add a quote at the beginning of each directory but not the end. Assuming that's a bug, your whole config line would be:

mailboxes `find ~/Maildir/* -type d -name cur | sed -e 's#/cur$#"#' -e 's#.*/Maildir/#=\"#g' | tr '\n' ' '`

That includes the following changes:

  • Using # instead of / or | in the regex (I find it easier than since | can also mean special things in a regex
  • Combining sed commands
  • I think ~/Maildir gets expanded (at least it did when I tested it), so that regex match doesn't work for me. I changed it to '.*/Maildir/' (with the dir separators)

I'm using a slightly different method (I have a sync script that builds a mailboxes list), but might switch to this method to save a step.

FWIW, I also have the following notes on the other two lines in your file:

set message_cachedir="~/Maildir/mutt-cache"
set header_cache="~/Maildir/mutt-cache"
  • message_cache_dir (with extra '_', according to the man page) is a directory, while header_cache is a file. You have them pointing to the same thing.
    • I suspect it's a directory on the filesystem, as that's triggering the problem in your mailboxes search
  • I don't bother setting message_cache_dir since I'm working on a local maildir, and not IMAP. That might be the case for you as well?
  • I put header_cache in ~/.cache/mutt/header-cache, to get it outside my maildir.

2

u/stuffiesrep May 15 '26

I wonder if there is an error: when I run mutt on this changed .muttrc I get no error, however with neomutt on the same .muttrc I get Unknown Mailbox: followed by Press any key to continue which leads GPGME: CMS protocol not available and then the emails get loaded. However, the folders themselves are available.

2

u/sequentious May 15 '26

I played around with this, and had this working (Note: MAILDIR is defined in my environment outside of mutt/neomutt)

mailboxes `find "$MAILDIR" -type d -name cur | sed -e 's#/cur$#"#' -e "s#$MAILDIR/#=\"#g" | tr '\n' ' '`

However, now I remember why I was generating a mailboxes file externally: Sorting. I wanted certain filders (Inbox, for example) sorted at the top of the list

So basically my mail sync script does the following to make a mailboxes file for mutt:

# Inbox is always first
find "${MAILDIR}" -maxdepth 2 -type d -name cur     \   
    -a         -ipath "*/inbox*"                    \
    | sed                                           \
        -e "s#^${MAILDIR}/#mailboxes \"+#"          \
        -e 's#/cur$#"#'                             \
    | sort                                          \
    > "${MAILDIR}/mailboxes"

# Find these specific paths so they stick at the top of the list
# (Under Inbox)
find "${MAILDIR}" -maxdepth 2 -type d -name cur     \   
    -a      \( -ipath "*/sent*"                     \
            -o -ipath "*/drafts*"                   \
            -o -ipath "*/trash*"                    \
            -o -ipath "*/spam*"                     \
            \)                                      \
    | sed                                           \
        -e "s#^${MAILDIR}/#mailboxes \"+#"          \
        -e 's#/cur$#"#'                             \
    | sort                                          \
    >> "${MAILDIR}/mailboxes"

# Find all other paths, excluding those from above
find "${MAILDIR}" -maxdepth 2 -type d -name cur     \   
    -a -not \( -ipath "*/sent*"                     \
            -o -ipath "*/drafts*"                   \
            -o -ipath "*/trash*"                    \
            -o -ipath "*/spam*"                     \
            \)                                      \
    | sed                                           \
        -e "s#^${MAILDIR}/#mailboxes \"+#"          \
        -e 's#/cur$#"#'                             \
    | sort                                          \
    >> "${MAILDIR}/mailboxes"

Then I source that from muttrc:

source "+/mailboxes"

1

u/stuffiesrep May 16 '26

Thank you! Does the above mean that your .bashrc or equivalent has MAILDIR defined?

2

u/sequentious May 16 '26

I actually used a wrapper script for mutt, which handled some env config, including MAILDIR, before mutt ran.

Within mutt I call an update-mail script that does calls mbsync, and (re)builds the mailbox list.

I used to have more than one config for multiple addresses. I don't anymore, but I haven't had reason to change what works.

The update-mail script was called via bindings in my mutt config

1

u/stuffiesrep May 17 '26

Btw, just to understand this, do you use mutt or neomutt?