Chapter 4. Advanced Usage
Prev |  | Next

# Chapter 4. Advanced Usage

## 1. Character Set Handling

A “character set” is basically a mapping between bytes and glyphs and implies a certain character encoding scheme. For example, for the ISO 8859 family of character sets, an encoding of 8bit per character is used. For the Unicode character set, different character encodings may be used, UTF-8 being the most popular. In UTF-8, a character is represented using a variable number of bytes ranging from 1 to 4.

Since NeoMutt is a command-line tool run from a shell, and delegates certain tasks to external tools (such as an editor for composing/editing messages), all of these tools need to agree on a character set and encoding. There exists no way to reliably deduce the character set a plain text file has. Interoperability is gained by the use of well-defined environment variables. The full set can be printed by issuing `locale` on the command line.

Upon startup, NeoMutt determines the character set on its own using routines that inspect locale-specific environment variables. Therefore, it is generally not necessary to set the `$charset` variable in NeoMutt. It may even be counter-productive as NeoMutt uses system and library functions that derive the character set themselves and on which NeoMutt has no influence. It's safest to let NeoMutt work out the locale setup itself.

If you happen to work with several character sets on a regular basis, it's highly advisable to use Unicode and an UTF-8 locale. Unicode can represent nearly all characters in a message at the same time. When not using a Unicode locale, it may happen that you receive messages with characters not representable in your locale. When displaying such a message, or replying to or forwarding it, information may get lost possibly rendering the message unusable (not only for you but also for the recipient, this breakage is not reversible as lost information cannot be guessed).

A Unicode locale makes all conversions superfluous which eliminates the risk of conversion errors. It also eliminates potentially wrong expectations about the character set between NeoMutt and external programs.

The terminal emulator used also must be properly configured for the current locale. Terminal emulators usually do not derive the locale from environment variables, they need to be configured separately. If the terminal is incorrectly configured, NeoMutt may display random and unexpected characters (question marks, octal codes, or just random glyphs), format strings may not work as expected, you may not be abled to enter non-ascii characters, and possible more. Data is always represented using bytes and so a correct setup is very important as to the machine, all character sets “look” the same.

Warning: A mismatch between what system and library functions think the locale is and what NeoMutt was told what the locale is may make it behave badly with non-ascii input: it will fail at seemingly random places. This warning is to be taken seriously since not only local mail handling may suffer: sent messages may carry wrong character set information the receiver has too deal with. The need to set `$charset` directly in most cases points at terminal and environment variable setup problems, not NeoMutt problems.

A list of officially assigned and known character sets can be found at IANA, a list of locally supported locales can be obtained by running `locale -a`.

## 2. Regular Expressions

All string patterns in NeoMutt including those in more complex patterns must be specified using regular expressions (regex) in the “POSIX extended” syntax (which is more or less the syntax used by egrep and GNU awk). For your convenience, we have included below a brief description of this syntax.

The search is case sensitive if the regular expression contains at least one upper case letter, and case insensitive otherwise.

### Note

“\” must be quoted if used for a regular expression in an initialization command: “\\”.

A regular expression is a pattern that describes a set of strings. Regular expressions are constructed analogously to arithmetic expressions, by using various operators to combine smaller expressions.

### Note

The regular expression can be enclosed/delimited by either " or ' which is useful if the regular expression includes a white-space character. See Syntax of Initialization Files for more information on " and ' delimiter processing. To match a literal " or ' you must preface it with \ (backslash).

The fundamental building blocks are the regular expressions that match a single character. Most characters, including all letters and digits, are regular expressions that match themselves. Any metacharacter with special meaning may be quoted by preceding it with a backslash.

The following matches a literal dot “.” in an address:

Example 4.1. Matching a literal dot

    # no quotes
    alternates only\\.dot@example\\.org

    # single quotes
    lists 'only\.dot@example\.org'

    # Double quotes
    subscribe "only\\.dot@example\\.org"

The period “.” matches any single character. The caret “^” and the dollar sign “$” are metacharacters that respectively match the empty string at the beginning and end of a line.

A list of characters enclosed by “[” and “]” matches any single character in that list; if the first character of the list is a caret “^” then it matches any character not in the list. For example, the regular expression [0123456789] matches any single digit. A range of ASCII characters may be specified by giving the first and last characters, separated by a hyphen “-”. Most metacharacters lose their special meaning inside lists. To include a literal “]” place it first in the list. Similarly, to include a literal “^” place it anywhere but first. Finally, to include a literal hyphen “-” place it last.

Certain named classes of characters are predefined. Character classes consist of “[:”, a keyword denoting the class, and “:]”. The following classes are defined by the POSIX standard in Table 4.1, “POSIX regular expression character classes”

Table 4.1. POSIX regular expression character classes

Character class | Description
--- | ---
[:alnum:] | Alphanumeric characters
[:alpha:] | Alphabetic characters
[:blank:] | Space or tab characters
[:cntrl:] | Control characters
[:digit:] | Numeric characters
[:graph:] | Characters that are both printable and visible. (A space is printable, but not visible, while an “a” is both)
[:lower:] | Lower-case alphabetic characters
[:print:] | Printable characters (characters that are not control characters)
[:punct:] | Punctuation characters (characters that are not letter, digits, control characters, or space characters)
[:space:] | Space characters (such as space, tab and formfeed, to name a few)
[:upper:] | Upper-case alphabetic characters
[:xdigit:] | Characters that are hexadecimal digits

A character class is only valid in a regular expression inside the brackets of a character list.

### Note

Note that the brackets in these class names are part of the symbolic names, and must be included in addition to the brackets delimiting the bracket list. For example, [[:digit:]] is equivalent to [0-9].

Two additional special sequences can appear in character lists. These apply to non-ASCII character sets, which can have single symbols (called collating elements) that are represented with more than one character, as well as several characters that are equivalent for collating or sorting purposes:

Collating Symbols

  A collating symbol is a multi-character collating element enclosed in “[.” and “.]”. For example, if “ch” is a collating element, then [[.ch.]] is a regex that matches this collating element, while [ch] is a regex that matches either “c” or “h”.

Equivalence Classes

  An equivalence class is a locale-specific name for a list of characters that are equivalent. The name is enclosed in “[=” and “=]”. For example, the name “e” might be used to represent all of “e” with grave (“è”), “e” with acute (“é”) and “e”. In this case, [[=e=]] is a regex that matches any of: “e” with grave (“è”), “e” with acute (“é”) and “e”.

A regular expression matching a single character may be followed by one of several repetition operators described in Table 4.2, “Regular expression repetition operators”.

Table 4.2. Regular expression repetition operators

Operator | Description
--- | ---
? | The preceding item is optional and matched at most once
* | The preceding item will be matched zero or more times
+ | The preceding item will be matched one or more times
{n} | The preceding item is matched exactly n times
{n,} | The preceding item is matched n or more times
{,m} | The preceding item is matched at most m times
{n,m} | The preceding item is matched at least n times, but no more than m times

Two regular expressions may be concatenated; the resulting regular expression matches any string formed by concatenating two substrings that respectively match the concatenated subexpressions.

Two regular expressions may be joined by the infix operator “|”; the resulting regular expression matches any string matching either subexpression.

Repetition takes precedence over concatenation, which in turn takes precedence over alternation. A whole subexpression may be enclosed in parentheses to override these precedence rules.

### Note

If you compile NeoMutt with the included regular expression engine, the following operators may also be used in regular expressions as described in Table 4.3, “GNU regular expression extensions”.

Table 4.3. GNU regular expression extensions

Expression | Description
--- | ---
\y | Matches the empty string at either the beginning or the end of a word
\B | Matches the empty string within a word
\< | Matches the empty string at the beginning of a word
\> | Matches the empty string at the end of a word
\w | Matches any word-constituent character (letter, digit, or underscore)
\W | Matches any character that is not word-constituent
\` | Matches the empty string at the beginning of a buffer (string)
\' | Matches the empty string at the end of a buffer

Please note however that these operators are not defined by POSIX, so they may or may not be available in stock libraries on various systems.

## 3. Patterns: Searching, Limiting and Tagging

### 3.1. Pattern Modifier

Many of NeoMutt's commands allow you to specify a pattern to match (`limit`, `tag-pattern`, `delete-pattern`, etc.). Table 4.4, “Pattern modifiers” shows several ways to select messages while Table 4.5, “Alias pattern modifiers” shows ways of selecting aliases.

Table 4.4. Pattern modifiers

Pattern modifier | Notes | Description
--- | --- | ---
~A |  | all messages
~b EXPR | d) | messages which contain EXPR in the message body
=b STRING |  | If IMAP is enabled, like ~b but searches for STRING on the server, rather than downloading each message and searching it locally.
~B EXPR | d) | messages which contain EXPR in the whole message
=B STRING |  | If IMAP is enabled, like ~B but searches for STRING on the server, rather than downloading each message and searching it locally.
~c EXPR |  | messages carbon-copied to EXPR
%c GROUP |  | messages carbon-copied to any member of GROUP
~C EXPR |  | messages either to:, cc: or bcc: EXPR
%C GROUP |  | messages either to:, cc: or bcc: to any member of GROUP
~d [MIN]-[MAX] |  | messages with “date-sent” in a Date range
~D |  | deleted messages
~e EXPR |  | messages which contains EXPR in the “Sender” field
%e GROUP |  | messages which contain a member of GROUP in the “Sender” field
~E |  | expired messages
~F |  | flagged messages
~f EXPR |  | messages originating from EXPR
%f GROUP |  | messages originating from any member of GROUP
~g |  | cryptographically signed messages
~G |  | cryptographically encrypted messages
~h EXPR | d) | messages which contain EXPR in the message header
=h STRING |  | If IMAP is enabled, like ~h but searches for STRING on the server, rather than downloading each message and searching it locally; STRING must be of the form “header: substring”(see below).
~H EXPR |  | messages with a spam attribute matching EXPR
~i EXPR |  | messages which match EXPR in the “Message-ID” field
~I QUERY |  | messages whose “Message-ID” field is included in the results returned from an external search program, when the program is run with QUERY as its argument. This is explained in greater detail in the variable reference entry Section 3.94, “external_search_command”,
~k |  | messages which contain PGP key material
~K EXPR |  | messages blind carbon-copied to EXPR
~L EXPR |  | messages either originated or received by EXPR
%L GROUP |  | message either originated or received by any member of GROUP
~l |  | messages addressed to a known mailing list
~m [MIN]-[MAX] | c) | messages with numbers in the range MIN to MAX
~m <[MAX] | c) | messages with numbers less than MAX
~m >[MIN] | c) | messages with numbers greater than MIN
~m [M] | c) | just message number M
~m [MIN],[MAX] | c) | messages with offsets (from selected message) in the range MIN to MAX
~M EXPR | d) | messages which contain a mime Content-Type matching EXPR
~n [MIN]-[MAX] | a) | messages with a score in the range MIN to MAX
~N |  | new messages
~O |  | old messages
~p |  | messages addressed to you (consults $from, alternates, and local account/hostname information)
~P |  | messages from you (consults $from, alternates, and local account/hostname information)
~Q |  | messages which have been replied to
~r [MIN]-[MAX] |  | messages with “date-received” in a Date range
~R |  | read messages
~s EXPR |  | messages having EXPR in the “Subject” field.
~S |  | superseded messages
~t EXPR |  | messages addressed to EXPR
~T |  | tagged messages
~u |  | messages addressed to a subscribed mailing list
~U |  | unread messages
~v |  | messages part of a collapsed thread.
~V |  | cryptographically verified messages
~w EXPR |  | newsgroups matching EXPR
~x EXPR |  | messages which contain EXPR in the “References” or “In-Reply-To” field
~X [MIN]-[MAX] | a), d) | messages with MIN to MAX attachments
~y EXPR |  | messages which contain EXPR in their keywords
~Y EXPR |  | messages whose tags match EXPR
~z [MIN]-[MAX] | a), b) | messages with a size in the range MIN to MAX
=/ STRING |  | IMAP custom server-side search for STRING. Currently only defined for Gmail. See: Gmail Patterns
~= |  | duplicated messages (see $duplicate_threads)
~# |  | broken threads (see $strict_threads)
~$ |  | unreferenced messages (requires threaded view)
~(PATTERN) |  | messages in threads containing messages matching PATTERN, e.g. all threads containing messages from you: ~(~P)
~<(PATTERN) |  | messages whose immediate parent matches PATTERN, e.g. replies to your messages: ~<(~P)
~>(PATTERN) |  | messages having an immediate child matching PATTERN, e.g. messages you replied to: ~>(~P)

Table 4.5. Alias pattern modifiers

Pattern modifier | Notes | Description
--- | --- | ---
~c EXPR |  | aliases which contain EXPR in the alias comment
~f EXPR |  | aliases which contain EXPR in the alias name (From part of alias)
~t EXPR |  | aliases which contain EXPR in the alias address (To part of alias)

Where EXPR is a regular expression, and GROUP is an address group.

a) The forms “<[MAX]”, “>[MIN]”, “[MIN]-” and “-[MAX]” are allowed, too.

b) The suffixes “K” and “M” are allowed to specify kilobyte and megabyte respectively.

c) The message number ranges (introduced by `~m`) are even more general and powerful than the other types of ranges. Read on and see Section 3.1.1, “Message Ranges” below.

d) These patterns read each message in, and can therefore be much slower. Over IMAP this will entail downloading each message. They can not be used for message scoring, and it is recommended to avoid using them for index coloring.

Special attention has to be paid when using regular expressions inside of patterns. Specifically, NeoMutt's parser for these patterns will strip one level of backslash (“\”), which is normally used for quoting. If it is your intention to use a backslash in the regular expression, you will need to use two backslashes instead (“\\”).

Example 4.2. Using `\s` and matching a literal dot in patterns

    # no quotes
    save-hook ~h\ list-id:\\\\s*<only\\\\.dot>    '=archive'
    save-hook ~hlist-id:\\\\s*<only\\\\.dot-here> '=archive'

    # single quotes
    save-hook '~h list-id:\\s<only\\.dot>'        '=archive'
    save-hook ~h'list-id:\\s*<only\\.dot-here>'   '=archive'

    # Double quotes
    save-hook "~h list-id:\\\\s<only\\\\.dot>"    '=archive'
    save-hook ~h"list-id:\\\\s*<only\\\\.dot>"    '=archive'

You can force NeoMutt to treat EXPR as a simple substring instead of a regular expression by using = instead of ~ in the pattern name. For example, `=b *.*` will find all messages that contain the literal string “*.*”. Simple string matches are less powerful than regular expressions but can be considerably faster.

For IMAP folders, string matches `=b`, `=B`, and `=h` will be performed on the server instead of by fetching every message. IMAP treats `=h` specially: it must be of the form “header: substring” and will not partially match header names. The substring part may be omitted if you simply wish to find messages containing a particular header without regard to its value.

Patterns matching lists of addresses (notably c, C, p, P and t) match if there is at least one match in the whole list. If you want to make sure that all elements of that list match, you need to prefix your pattern with “^”. This example matches all mails which only has recipients from Germany.

Example 4.3. Matching all addresses in address lists

    ^~C \.de$

You can restrict address pattern matching to aliases that you have defined with the "@" modifier. This example matches messages whose recipients are all from Germany, and who are known to your alias list.

Example 4.4. Matching restricted to aliases

    ^@~C \.de$

To match any defined alias, use a regular expression that matches any string. This example matches messages whose senders are known aliases.

Example 4.5. Matching any defined alias

    @~f .

#### 3.1.1. Message Ranges

If a message number range (from now on: MNR) contains a comma (`,`), it is a relative MNR. That means the numbers denote offsets from the highlighted message. For example:

Table 4.6. Relative Message Number Ranges

Pattern | Explanation
--- | ---
`~m -2,2` | Previous 2, highlighted and next 2 emails
`~m 0,1` | Highlighted and next email

In addition to numbers, either side of the range can also contain one of the special characters (shortcuts) `.^$`. The meaning is:

Table 4.7. Message Number Shortcuts

Shortcut | Explanation | Example | Meaning
--- | --- | --- | ---
`.` | Current / Highlighted | `~m -3,.` | Previous 3 emails plus the highlighted one
`$` | Last | `~m .,$` | Highlighted email and all the later ones
`^` | First | `~m ^,1` | Highlighted, next and all preceding ones

Lastly, you can also leave either side of the range blank, to make it extend as far as possible. For example, `~m ,1` has the same meaning as the last example in Table 4.7, “Message Number Shortcuts”.

Otherwise, if a MNR doesn't contain a comma, the meaning is similar to other ranges, except that the shortcuts are still available. Examples:

Table 4.8. Absolute Message Number Ranges

Pattern | Explanation
--- | ---
`~m 3-10` | Emails 3 to 10
`~m -10` | Emails 1 to 10
`~m 10-` | Emails 10 to last
`~m <3` | First and second email
`~m ^-2` | First and second email
`~m >1` | Everything but first email
`~m 2-$` | Everything but first email
`~m 2` | Just the second email

### 3.2. Simple Searches

NeoMutt supports two versions of so called “simple searches”. These are issued if the query entered for searching, limiting and similar operations does not seem to contain a valid pattern modifier (i.e. it does not contain one of these characters: “~”, “=” or “%”). If the query is supposed to contain one of these special characters, they must be escaped by prepending a backslash (“\”).

The first type is by checking whether the query string equals a keyword case-insensitively from Table 4.9, “Simple search keywords”: If that is the case, NeoMutt will use the shown pattern modifier instead. If a keyword would conflict with your search keyword, you need to turn it into a regular expression to avoid matching the keyword table. For example, if you want to find all messages matching “flag” (using $simple_search) but don't want to match flagged messages, simply search for “`[f]lag`”.

Table 4.9. Simple search keywords

Keyword | Pattern modifier
--- | ---
all | ~A
. | ~A
^ | ~A
del | ~D
flag | ~F
new | ~N
old | ~O
repl | ~Q
read | ~R
tag | ~T
unread | ~U

The second type of simple search is to build a complex search pattern using $simple_search as a template. NeoMutt will insert your query properly quoted and search for the composed complex query.

### 3.3. Nesting and Boolean Operators

Logical AND is performed by specifying more than one criterion. For example:

    ~t work ~f smith

would select messages which contain the word “work” in the list of recipients and that have the word “smith” in the “From” header field.

NeoMutt also recognizes the following operators to create more complex search patterns:

- ! – logical NOT operator

- | – logical OR operator

- () – logical grouping operator

Here is an example illustrating a complex search pattern. This pattern will select all messages which do not contain “work” in the “To” or “Cc” field and which are from “smith”.

Example 4.6. Using boolean operators in patterns

    !(~t work|~c work) ~f smith

Here is an example using white space in the regular expression (note the “'” and “"” delimiters). For this to match, the mail's subject must match the “^Junk +From +Me$” and it must be from either “Jim +Somebody” or “Ed +SomeoneElse”:

    '~s "^Junk +From +Me$" ~f ("Jim +Somebody"|"Ed +SomeoneElse")'

### Note

If a regular expression contains parenthesis, or a vertical bar ("|"), you must enclose the expression in double or single quotes since those characters are also used to separate different parts of NeoMutt's pattern language. For example: `~f "user@(home\.org|work\.com)"` Without the quotes, the parenthesis wouldn't end. This would be separated to two OR'd patterns: ~f user@(home\.org and work\.com). They are never what you want.

### 3.4. Searching by Date

NeoMutt supports two types of dates, absolute and relative.

#### 3.4.1. Absolute Dates

Dates must be in DD/MM/YY format (month and year are optional, defaulting to the current month and year) or YYYYMMDD. An example of a valid range of dates is:

    Limit to messages matching: ~d 20/1/95-31/10
    Limit to messages matching: ~d 19950120-19951031

If you omit the minimum (first) date, and just specify “-DD/MM/YY” or “-YYYYMMDD”, all messages before the given date will be selected. If you omit the maximum(second) date, and specify “DD/MM/YY-”, all messages after the given date will be selected. If you specify a single date with no dash (“-”), only messages sent on the given date will be selected.

You can add error margins to absolute dates. An error margin is a sign (+ or -), followed by a digit, followed by one of the units in Table 4.10, “Date units”. As a special case, you can replace the sign by a “*” character, which is equivalent to giving identical plus and minus error margins.

Table 4.10. Date units

Unit | Description
--- | ---
y | Years
m | Months
w | Weeks
d | Days

Example: To select any messages two weeks around January 15, 2001, you'd use the following pattern:

    Limit to messages matching: ~d 15/1/2001*2w

#### 3.4.2. Relative Dates

This type of date is relative to the current date, and may be specified as:

- > offset for messages older than offset units

- < offset for messages newer than offset units

- = offset for messages exactly offset units old

offset is specified as a positive number with one of the units from Table 4.11, “Relative date units”.

Table 4.11. Relative date units

Unit | Description
--- | ---
y | Years
m | Months
w | Weeks
d | Days
H | Hours
M | Minutes
S | Seconds

Example: to select messages less than 1 month old, you would use

    Limit to messages matching: ~d <1m

### Note

All dates used when searching are relative to the local time zone, so unless you change the setting of your $index_format to include a `%[...]` format, these are not the dates shown in the main index.

### 3.5. Gmail Patterns

`=/ "search terms"` invokes server-side search, passing along the search terms provided. Search results are constrained by IMAP to be within the current folder. At present this only supports Gmail's search API IMAP extension. The search language is entirely up to the mail provider and changes at their discretion. Using `~/` will silently fail.

For up-to-date information about searching, see: Gmail's Support Page. You will need to (once) use a web-browser to visit Settings/Labels and enable "Show in IMAP" for "All Mail". When searching, visit that folder in NeoMutt to most closely match Gmail search semantics.

Table 4.12. Gmail Example Patterns

Pattern | Matches
--- | ---
`=/ "list:foo.example.org has:attachment is:important"` | the foo.example.org mailing-list per Gmail's definitions, and has an attachment, and has been marked as important
`=/ "{has:purple-star has:yellow-star} older_than:2m"` | is older than two months and has either a purple-star or a yellow-star

## 4. Marking Messages

There are times that it's useful to ask NeoMutt to "remember" which message you're currently looking at, while you move elsewhere in your mailbox. You can do this with the “mark-message” operator, which is bound to the “~” key by default. Press this key to enter an identifier for the marked message. When you want to return to this message, press “'” and the name that you previously entered.

(Message marking is really just a shortcut for defining a macro that returns you to the current message by searching for its Message-ID. You can choose a different prefix by setting the $mark_macro_prefix variable.)

## 5. Using Tags

Sometimes it is desirable to perform an operation on a group of messages all at once rather than one at a time. An example might be to save messages to a mailing list to a separate folder, or to delete all messages with a given subject. To tag all messages matching a pattern, use the `<tag-pattern>` function, which is bound to “shift-T” by default. Patterns are completable in the editor menu. Invoke the `<complete>` function (by default bound to “Tab”) after typing “~” to get a selectable list. Or you can select individual messages by hand using the `<tag-message>` function, which is bound to “t” by default. See patterns for NeoMutt's pattern matching syntax.

Once you have tagged the desired messages, you can use the “tag-prefix” operator, which is the “;” (semicolon) key by default. When the “tag-prefix” operator is used, the next operation will be applied to all tagged messages if that operation can be used in that manner. If the $auto_tag variable is set, the next operation applies to the tagged messages automatically, without requiring the “tag-prefix”.

In macros or push commands, you can use the `<tag-prefix-cond>` operator. If there are no tagged messages, NeoMutt will “eat” the rest of the macro to abort its execution. NeoMutt will stop “eating” the macro when it encounters the `<end-cond>` operator; after this operator the rest of the macro will be executed as normal.

## 6. Using Hooks

A hook is a concept found in many other programs which allows you to execute arbitrary commands before performing some operation. For example, you may wish to tailor your configuration based upon which mailbox you are reading, or to whom you are sending mail. In the NeoMutt world, a hook consists of a regular expression or pattern along with a configuration option/command. See:

- account-hook

- charset-hook

  iconv-hook

- index-format-hook

- crypt-hook

- fcc-save-hook

  fcc-hook

  save-hook

- folder-hook

- mbox-hook

- message-hook

- open-hook

  close-hook

  append-hook

- reply-hook

  send-hook

  send2-hook

- timeout-hook

  startup-hook

  shutdown-hook

- unhook

for specific details on each type of hook available. Also see Message Composition Flow for an overview of the composition process.

### Note

If a hook changes configuration settings, these changes remain effective until the end of the current NeoMutt session. As this is generally not desired, a “default” hook needs to be added before all other hooks of that type to restore configuration defaults.

Example 4.7. Specifying a “default” hook

    send-hook . 'unmy_hdr From:'
    send-hook ~C'^b@b\\.b$' my_hdr from: c@c.c

In Example 4.7, “Specifying a “default” hook”, by default the value of $from and $real_name is not overridden. When sending messages either To: or Cc: to `<b@b.b>`, the From: header is changed to `<c@c.c>`.

### 6.1. Message Matching in Hooks

Hooks that act upon messages (message-hook, reply-hook, send-hook, send2-hook, save-hook, fcc-hook, index-format-hook) are evaluated in a slightly different manner. For the other types of hooks, a regular expression is sufficient. But in dealing with messages a finer grain of control is needed for matching since for different purposes you want to match different criteria.

NeoMutt allows the use of the search pattern language for matching messages in hook commands. This works in exactly the same way as it would when limiting or searching the mailbox, except that you are restricted to those operators which match information NeoMutt extracts from the header of the message (i.e., from, to, cc, date, subject, etc.).

For example, if you wanted to set your return address based upon sending mail to a specific address, you could do something like:

    send-hook '~t ^user@work\\.com$' 'my_hdr From: John Smith <user@host>'

which would execute the given command when sending mail to user@work.com.

However, it is not required that you write the pattern to match using the full searching language. You can still specify a simple regular expression like the other hooks, in which case NeoMutt will translate your pattern into the full language, using the translation specified by the $default_hook variable. The pattern is translated at the time the hook is declared, so the value of $default_hook that is in effect at that time will be used.

### 6.2. Mailbox Matching in Hooks

Hooks that match against mailboxes (folder-hook, mbox-hook) apply both regular expression syntax as well as mailbox shortcut expansion on the regex parameter. There is some overlap between these, so special attention should be paid to the first character of the regex.

    # Here, ^ will expand to "the current mailbox" not "beginning of string":
    folder-hook ^/home/user/Mail/bar "set sort=threads"
    # If you want ^ to be interpreted as "beginning of string", one workaround
    # is to enclose the regex in parenthesis:
    folder-hook (^/home/user/Mail/bar) "set sort=threads"
    # This will expand to the default save folder for the alias "imap.example.com", which
    # is probably not what you want:
    folder-hook @imap\\.example\\.com "set sort=threads"
    # A workaround is to use parenthesis or a backslash:
    folder-hook (@imap\\.example\\.com) "set sort=threads"
    folder-hook '\@imap\.example\.com' "set sort=threads"

Keep in mind that mailbox shortcut expansion on the regex parameter takes place when the hook is initially parsed, not when the hook is matching against a mailbox. When NeoMutt starts up and is reading the .neomuttrc, some mailbox shortcuts may not be usable. For example, the "current mailbox" shortcut, ^, will expand to an empty string because no mailbox has been opened yet. NeoMutt will issue an error for this case or if the mailbox shortcut results in an empty regex.

## 7. Managing the Environment

You can alter the environment that NeoMutt passes on to its child processes using the “setenv” and “unsetenv” commands. You can also query current environment values by adding a “?” character.

### Note

These follow NeoMutt-style syntax, not shell-style!

    setenv TERM vt100
    setenv ORGANIZATION "The NeoMutt Development Team"
    unsetenv DISPLAY
    setenv LESS?

Running setenv with no parameters will show a list of all the environment variables.

## 8. External Address Queries

NeoMutt supports connecting to external directory databases such as LDAP, ph/qi, bbdb, or NIS through a wrapper script which connects to NeoMutt using a simple interface. Using the $query_command variable, you specify the wrapper command to use. For example:

    set query_command = "mutt_ldap_query.pl %s"

The wrapper script should accept the query on the command-line. It should return a one line message, then each matching response on a single line, each line containing a tab separated address then name then some other optional information. On error, or if there are no matching addresses, return a non-zero exit code and a one line error message.

An example multiple response output:

    Searching database ... 70 entries ... 5 matching:
    ji@papaya.com   Jeremy Irons    Emmy, Oscar, Tony
    jc@damson.com   James Cagney    Oscar
    mr@ilama.com    Meg Ryan
    mjf@kumquat.com Michael J Fox
    ma@yew.com      Murray Abraham  Oscar

There are two mechanisms for accessing the query function of NeoMutt. One is to do a query from the index menu using the `<query>` function (default: Q). This will prompt for a query, then bring up the query menu which will list the matching responses. From the query menu, you can select addresses to create aliases, or to mail. You can tag multiple addresses to mail, start a new query, or have a new query appended to the current responses.

The other mechanism for accessing the query function is for address completion, similar to the alias completion. In any prompt for address entry, you can use the `<complete-query>` function (default: ^T) to run a query based on the current address you have typed. Like aliases, NeoMutt will look for what you have typed back to the last space or comma. If there is a single response for that query, NeoMutt will expand the address in place. If there are multiple responses, NeoMutt will activate the query menu. At the query menu, you can select one or more addresses to be added to the prompt.

### Note

The query menu is affected by $sort_alias, thus overruling the order of entries as generated by $query_command.

## 9. Mailbox Formats

NeoMutt supports reading and writing of four different local mailbox formats: mbox, MMDF, MH and Maildir. The mailbox type is auto detected, so there is no need to use a flag for different mailbox types. When creating new mailboxes, NeoMutt uses the default specified with the $mbox_type variable. A short description of the formats follows.

mbox. This is a widely used mailbox format for UNIX. All messages are stored in a single file. Each message has a line of the form:

    From me@ox.ac.uk Fri, 11 Apr 1997 11:44:56 PST

to denote the start of a new message (this is often referred to as the “From_” line). The mbox format requires mailbox locking, is prone to mailbox corruption with concurrently writing clients or misinterpreted From_ lines. Depending on the environment, new mail detection can be unreliable. Mbox folders are fast to open and easy to archive.

MMDF. This is a variant of the mbox format. Each message is surrounded by lines containing “^A^A^A^A” (four times control-A's). The same problems as for mbox apply (also with finding the right message separator as four control-A's may appear in message bodies).

MH. A radical departure from mbox and MMDF, a mailbox consists of a directory and each message is stored in a separate file. The filename indicates the message number (however, this is may not correspond to the message number NeoMutt displays). Deleted messages are renamed with a comma (“,”) prepended to the filename. NeoMutt detects this type of mailbox by looking for either `.mh_sequences` or `.xmhcache` files (needed to distinguish normal directories from MH mailboxes). MH is more robust with concurrent clients writing the mailbox, but still may suffer from lost flags; message corruption is less likely to occur than with mbox/mmdf. It's usually slower to open compared to mbox/mmdf since many small files have to be read (NeoMutt provides Section 8.1, “Header Caching” to greatly speed this process up). Depending on the environment, MH is not very disk-space efficient.

Maildir. The newest of the mailbox formats, used by the Qmail MTA (a replacement for sendmail). Similar to MH, except that it adds three subdirectories of the mailbox: tmp, new and cur. Filenames for the messages are chosen in such a way they are unique, even when two programs are writing the mailbox over NFS, which means that no file locking is needed and corruption is very unlikely. Maildir maybe slower to open without caching in NeoMutt, it too is not very disk-space efficient depending on the environment. Since no additional files are used for metadata (which is embedded in the message filenames) and Maildir is locking-free, it's easy to sync across different machines using file-level synchronization tools.

## 10. Mailbox Shortcuts

There are a number of built in shortcuts which refer to specific mailboxes. These shortcuts can be used anywhere you are prompted for a file or mailbox path or in path-related configuration variables. Note that these only work at the beginning of a string.

Table 4.13. Mailbox shortcuts

Shortcut | Refers to...
--- | ---
`!` | your $spool_file (incoming) mailbox
`>` | your $mbox file
`<` | your $record file
`^` | the current mailbox
`-` or `!!` | the file you've last visited
`~` | your home directory
`=` or `+` | your $folder directory
@alias | to the default save folder as determined by the address of the alias

For example, to store a copy of outgoing messages in the folder they were composed in, a folder-hook can be used to set $record:

    folder-hook . 'set record=^'

Note: the current mailbox shortcut, “`^`”, has no value in some cases. No mailbox is opened when NeoMutt is invoked to send an email from the command-line. In interactive mode, NeoMutt reads the muttrc before opening the mailbox, so immediate expansion won't work as expected either. This can be an issue when trying to directly assign to $record, but also affects the fcc-hook mailbox, which is expanded immediately too. The folder-hook example above works because the command is executed later, when the folder-hook fires.

## 11. Handling Mailing Lists

NeoMutt has a few configuration options that make dealing with large amounts of mail easier. The first thing you must do is to let NeoMutt know what addresses you consider to be mailing lists (technically this does not have to be a mailing list, but that is what it is most often used for), and what lists you are subscribed to. This is accomplished through the use of the lists and subscribe commands in your `.neomuttrc`. Alternatively or additionally, you can set $auto_subscribe to automatically subscribe addresses found in a `List-Post` header.

Now that NeoMutt knows what your mailing lists are, it can do several things, the first of which is the ability to show the name of a list through which you received a message (i.e., of a subscribed list) in the index menu display. This is useful to distinguish between personal and list mail in the same mailbox. In the $index_format variable, the expando “%L” will print the string “To <list>” when “list” appears in the “To” field, and “Cc <list>” when it appears in the “Cc” field (otherwise it prints the name of the author).

Often times the “To” and “Cc” fields in mailing list messages tend to get quite large. Most people do not bother to remove the author of the message they reply to from the list, resulting in two or more copies being sent to that person. The `<list-reply>` function, which by default is bound to “L” in the index menu and pager, helps reduce the clutter by only replying to the known mailing list addresses instead of all recipients (except as specified by `Mail-Followup-To`, see below).

NeoMutt also supports the `Mail-Followup-To` header. When you send a message to a list of recipients which includes one or several known mailing lists, and if the $followup_to option is set, NeoMutt will generate a Mail-Followup-To header. If any of the recipients are subscribed mailing lists, this header will contain all the recipients to whom you send this message, but not your address. This indicates that group-replies or list-replies (also known as “followups”) to this message should only be sent to the original recipients of the message, and not separately to you - you'll receive your copy through one of the mailing lists you are subscribed to. If none of the recipients are subscribed mailing lists, the header will also contain your address, ensuring you receive a copy of replies.

Conversely, when group-replying or list-replying to a message which has a `Mail-Followup-To` header, NeoMutt will respect this header if the $honor_followup_to configuration variable is set. Using list-reply will in this case also make sure that the reply goes to the mailing list, even if it's not specified in the list of recipients in the `Mail-Followup-To`.

### Note

When header editing is enabled, you can create a `Mail-Followup-To` header manually. NeoMutt will only auto-generate this header if it doesn't exist when you send the message.

The other method some mailing list admins use is to generate a “Reply-To” field which points back to the mailing list address rather than the author of the message. This can create problems when trying to reply directly to the author in private, since most mail clients will automatically reply to the address given in the “Reply-To” field. NeoMutt uses the $reply_to variable to help decide which address to use. If set to ask-yes or ask-no, you will be prompted as to whether or not you would like to use the address given in the “Reply-To” field, or reply directly to the address given in the “From” field. When set to yes, the “Reply-To” field will be used when present.

You can change or delete the “X-Label:” field within NeoMutt using the “edit-label” command, bound to the “y” key by default. This works for tagged messages, too. While in the edit-label function, pressing the <complete> binding (TAB, by default) will perform completion against all labels currently in use.

Lastly, NeoMutt has the ability to sort the mailbox into threads. A thread is a group of messages which all relate to the same subject. This is usually organized into a tree-like structure where a message and all of its replies are represented graphically. If you've ever used a threaded news client, this is the same concept. It makes dealing with large volume mailing lists easier because you can easily delete uninteresting threads and quickly find topics of value.

## 12. Display Munging

Working within the confines of a console or terminal window, it is often useful to be able to modify certain information elements in a non-destructive way – to change how they display, without changing the stored value of the information itself. This is especially so of message subjects, which may often be polluted with extraneous metadata that either is reproduced elsewhere, or is of secondary interest.

`subjectrx` `regex` `replacement`
`unsubjectrx` { `*` | `regex` }

`subjectrx` specifies a regular expression which, if detected in a message subject, causes the subject to be replaced with the “replacement” value. The replacement is subject to substitutions in the same way as for the spam command: `%L` for the text to the left of the match, `%R` for text to the right of the match, and `%1` for the first subgroup in the match (etc). If you simply want to erase the match, set it to “%L%R”. Any number of `subjectrx` commands may coexist.

Note this well: the “replacement” value replaces the entire subject, not just the match!

`unsubjectrx` removes a given subjectrx from the substitution list. If `*` is used as the argument, all substitutions will be removed.

Example 4.8. Subject Munging

    # Erase [rt #12345] tags from Request Tracker (RT) e-mails
    subjectrx '\[rt #[0-9]+\] *' '%L%R'
    # Servicedesk is another RT that sends more complex subjects.
    # Keep the ticket number.
    subjectrx '\[servicedesk #([0-9]+)\] ([^.]+)\.([^.]+) - (new|open|pending|update) - ' '%L[#%1] %R'
    # Strip out annoying [listname] prefixes in subjects
    subjectrx '\[[^]]*\]:? *' '%L%R'

## 13. New Mail Detection

NeoMutt supports setups with multiple folders, allowing all of them to be monitored for new mail (see Section 16, “Monitoring Incoming Mail” for details).

### 13.1. How New Mail Detection Works

For Mbox and Mmdf folders, new mail is detected by comparing access and/or modification times of files: NeoMutt assumes a folder has new mail if it wasn't accessed after it was last modified. Utilities like `biff` or `frm` or any other program which accesses the mailbox might cause NeoMutt to never detect new mail for that mailbox if they do not properly reset the access time. Other possible causes of NeoMutt not detecting new mail in these folders are backup tools (updating access times) or filesystems mounted without access time update support (for Linux systems, see the `relatime` option).

### Note

Contrary to older NeoMutt releases, it now maintains the new mail status of a folder by properly resetting the access time if the folder contains at least one message which is neither read, nor deleted, nor marked as old.

In cases where new mail detection for Mbox or Mmdf folders appears to be unreliable, the $check_mbox_size option can be used to make NeoMutt track and consult file sizes for new mail detection instead which won't work for size-neutral changes.

New mail for Maildir is assumed if there is one message in the `new/` subdirectory which is not marked deleted (see $maildir_trash). For MH folders, a mailbox is considered having new mail if there's at least one message in the “unseen” sequence as specified by $mh_seq_unseen. Optionally, $new_mail_command can be configured to execute an external program every time new mail is detected in the current inbox.

NeoMutt does not poll POP3 folders for new mail, it only periodically checks the currently opened folder (if it's a POP3 folder).

For IMAP, by default NeoMutt uses recent message counts provided by the server to detect new mail. If the $imap_idle option is set, it'll use the IMAP IDLE extension if advertised by the server.

The $mail_check_recent option changes whether NeoMutt will notify you of new mail in an already visited mailbox. When set (the default) it will only notify you of new mail received since the last time you opened the mailbox. When unset, NeoMutt will notify you of any new mail in the mailbox.

### 13.2. Polling For New Mail

When in the index menu and being idle (also see $timeout), NeoMutt periodically checks for new mail in all folders which have been configured via the mailboxes command. The interval depends on the folder type: for local/IMAP folders it consults $mail_check and $pop_check_interval for POP folders.

Outside the index menu the directory browser supports checking for new mail using the `<check-new>` function which is unbound by default. Pressing TAB will bring up a menu showing the files specified by the mailboxes command, and indicate which contain new messages. NeoMutt will automatically enter this mode when invoked from the command line with the `-y` option, or from the index/pager via the `<browse-mailboxes>` function.

For the pager, index and directory browser menus, NeoMutt contains the `<mailbox-list>` function (bound to “.” by default) which will print a list of folders with new mail in the command line at the bottom of the screen.

For the index, by default NeoMutt displays the number of mailboxes with new mail in the status bar, please refer to the $status_format variable for details.

When changing folders, NeoMutt fills the prompt with the first folder from the mailboxes list containing new mail (if any), pressing `<Space>` will cycle through folders with new mail. The (by default unbound) function `<next-unread-mailbox>` in the index can be used to immediately open the next folder with unread mail (if any).

### 13.3. Monitoring New Mail

When the Inotify mechanism for monitoring of files is supported (Linux only) and not disabled at compilation time, NeoMutt immediately notifies about new mail for all folders configured via the mailboxes command. Dependent on mailbox format also added old mails are tracked (not for Maildir).

No configuration variables are available. Trace output is given when debugging is enabled via command line option `-d3`. The lower level 2 only shows errors, the higher level 5 all including raw Inotify events.

### Note

Getting events about new mail is limited to the capabilities of the underlying mechanism. inotify only reports local changes, i. e. new mail notification works for mails delivered by an agent on the same machine as NeoMutt, but not when delivered remotely on a network file system as nfs. also the monitoring handles might fail in rare conditions, so you better don't completely rely on this feature.

### Note

When using Maildir, you don't have to manually specify all your mailboxes. You can use this command instead:

    mailboxes `find ~/.mail/ -type d -name cur | sed -e 's:/cur/*$::' -e 's/ /\\ /g' | sort | tr '\n' ' '`

### 13.4. Calculating Mailbox Message Counts

If $mail_check_stats is set, NeoMutt will periodically calculate the unread, flagged, and total message counts for each mailbox watched by the mailboxes command. This calculation takes place at the same time as new mail polling, but is controlled by a separate timer: $mail_check_stats_interval.

The sidebar can display these message counts. See $sidebar_format.

## 14. Editing Threads

NeoMutt has the ability to dynamically restructure threads that are broken either by misconfigured software or bad behavior from some correspondents. This allows to clean your mailboxes from these annoyances which make it hard to follow a discussion.

### 14.1. Linking Threads

Some mailers tend to “forget” to correctly set the “In-Reply-To:” and “References:” headers when replying to a message. This results in broken discussions because NeoMutt has not enough information to guess the correct threading. You can fix this by tagging a number of replies, then moving to the parent message and using the `<link-threads>` function (bound to & by default). The replies will then be connected to this parent message.

### 14.2. Breaking Threads

On mailing lists, some people are in the bad habit of starting a new discussion by hitting “reply” to any message from the list and changing the subject to a totally unrelated one. You can fix such threads by using the `<break-thread>` function (bound by default to #), which will turn the subthread starting from the current message into a whole different thread.

## 15. Delivery Status Notification (DSN) Support

RFC1894 defines a set of MIME content types for relaying information about the status of electronic mail messages. These can be thought of as “return receipts.”

To support DSN, there are two variables. $dsn_notify is used to request receipts for different results (such as failed message, message delivered, etc.). $dsn_return requests how much of your message should be returned with the receipt (headers or full message).

When using $sendmail for mail delivery, you need to use either Berkeley sendmail 8.8.x (or greater) a MTA supporting DSN command line options compatible to Sendmail: The -N and -R options can be used by the mail client to make requests as to what type of status messages should be returned. Please consider your MTA documentation whether DSN is supported.

For SMTP delivery using $smtp_url, it depends on the capabilities announced by the server whether NeoMutt will attempt to request DSN or not.

## 16. Start a WWW Browser on URLs

If a message contains URLs, it is efficient to get a menu with all the URLs and start a WWW browser on one of them. This functionality is provided by the external urlview program which can be retrieved at ftp://ftp.mutt.org/mutt/contrib/ and the configuration commands:

    macro index \cb |urlview\n
    macro pager \cb |urlview\n

## 17. Echoing Text

Usage:

`echo` `message`

You can print messages to the message window using the "echo" command. This might be useful after a macro finishes executing. After printing the message, echo will pause for the number of seconds specified by $sleep_time.

    echo "Sourcing muttrc file"
    unset confirm_append
    macro index ,a "<save-message>=archive<enter><enter-command>echo 'Saved to archive'<enter>"

## 18. Message Composition Flow

This is a brief overview of the steps NeoMutt takes during message composition. It also shows the order and timing of hook execution.

- Reply envelope settings. $reverse_name processing. To, Cc, Subject, References header defaults.

- my_hdr processing for To, Cc, Bcc, Subject headers.

- Prompts for To, Cc, Bcc, Subject headers. See $ask_cc, $ask_bcc, $fast_reply.

- From header setting. Note: this is so send-hooks below can match ~P, but From is re-set further below in case a send-hook changes the value.

- reply-hook

- send-hook

- From header setting.

- my_hdr processing for From, Reply-To, Message-ID and user-defined headers. The To, Cc, Bcc, Subject, and Return-Path headers are ignored at this stage.

- Message body and signature generation.

- send2-hook

- $real_name part of From header setting.

- $editor invocation for the message.

- send2-hook

- Cryptographic settings.

- fcc-hook. Fcc setting.

- Compose menu. Note: send2-hook is evaluated each time the headers are changed.

- Message encryption and signing. Key selection.

- Fcc saving if $fcc_before_send is set. (Note the variable documentation for caveats of Fcc'ing before sending.)

- Message sending.

- Fcc saving if $fcc_before_send is unset (the default). The Fcc used to be saved before sending the message. It is now by default saved afterwards, but if the saving fails, the user is prompted.

## 19. Miscellany

This section documents various features that fit nowhere else.

Address normalization

  NeoMutt normalizes all e-mail addresses to the simplest form possible. If an address contains a real_name, the form Joe User <joe@example.com> is used and the pure e-mail address without angle brackets otherwise, i.e. just joe@example.com.

  This normalization affects all headers NeoMutt generates including aliases.

Initial folder selection

  The folder NeoMutt opens at startup is determined as follows: the folder specified in the `$MAIL` environment variable if present. Otherwise, the value of `$MAILDIR` is taken into account. If that isn't present either, NeoMutt takes the user's mailbox in the mailspool as determined at compile-time (which may also reside in the home directory). The $spool_file setting overrides this selection. Highest priority has the mailbox given with the `-f` command line option.

Prev |  | Next
Chapter 3. Configuration | Home | Chapter 5. NeoMutt's MIME Support