Moving Your Mail Around

[previous] [next] [table of contents] [index]

Note: HTML conversion may not be complete.

If you change the name of some of the MH programs or have your own printing programs, the following variables can help you. They are described in detail in the subsequent sections.

Variable                  |       Default      |      Description
mh-inc-prog               |        "inc"       |  Program  to   incor-
                          |                    |  porate mail
mh-inc-folder-hook        |         nil        |  Functions to run
                          |                    |  when incorporating
                          |                    |  mail
mh-delete-msg-hook        |         nil        |  Functions   to   run
                          |                    |  when  deleting  mes-
                          |                    |  sages
mh-print-background       |         nil        |  Print in  foreground
                          |                    |  or background
mh-lpr-command-format     |    "lpr -J '%s'"   |  Command   used    to
                          |                    |  print
mh-default-folder-for-    |         nil        |  Command to  generate
message-function          |                    |  a default folder
mh-auto-folder-collect    |          t         |  Collect folder names
                          |                    |  in   background   at
                          |                    |  startup
mh-recursive-folders      |         nil        |  Collect nested fold-
                          |                    |  ers
mh-refile-msg-hook        |         nil        |  Functions   to   run
                          |                    |  when  refiling  mes-
                          |                    |  sage
mh-store-default-directory|         nil        |  Default    directory
                          |                    |  for storing uuencode
                          |                    |  or shar files
mh-sortm-args             |         nil        |  Additional arguments
                          |                    |  for sortm
mh-scan-prog              |        "scan"      |  Program to scan mes-
                          |                    |  sages
mh-msg-number-regexp      |  "^ *\\([0-9]+\\)" |  Matches      message
                          |                    |  number in scan line
mh-msg-search-regexp      |  "^[^0-9]*%d[^0-9]"|  Matches      message
                          |                    |  number %d
mh-valid-scan-line        |      "^ *[0-9]"    |  Matches a valid scan
                          |                    |  line
mh-cmd-note               |          4         |  Offset for notation
mh-deleted-msg-regexp     |       "^....D"     |  Matches deleted mes-
                          |                    |  sage
mh-refiled-msg-regexp     |      "^....\\^"    |  Matches refiled mes-
                          |                    |  sage
mh-cur-scan-msg-regexp    |      "^....\\+"    |  Matches the  current
                          |                    |  message
mh-good-msg-regexp        |     "^....[^D^]"   |  Matches message that
                          |                    |  can  be  shown by n,
                          |                    |  etc.
mh-note-deleted           |         "D"        |  Notation for deleted
                          |                    |  messages
mh-note-refiled           |         "^"        |  Notation for refiled
                          |                    |  messages
mh-note-copied            |         "C"        |  Notation for  copied
                          |                    |  messages
mh-note-cur               |         "+"        |  Notation   for   the
                          |                    |  current message
mh-note-repl              |         "-"        |  Notation for replied
                          |                    |  to messages
mh-note-forw              |         "F"        |  Notation for for-
                          |                    |  warded messages
mh-note-dist              |         "R"        |  Notation for  redis-
                          |                    |  tributed messages
mh-note-printed           |         "P"        |  Notation for printed
                          |                    |  messages
mh-note-seq               |         "%"        |  Notation  for   mes-
                          |                    |  sages in a sequence
mh-quit-hook              |         nil        |  Functions   to   run
                          |                    |  after quitting

Incorporating Your Mail

The name of the program that incorporates new mail is stored in mh-inc-prog; it is "inc" by default. This program generates a one-line summary for each of the new messages. Unless it is an absolute pathname, the file is assumed to be in the mh-progs directory. You may also link a file to inc, which uses a different format (see the Section Making a New Command Version). You'll then need to modify several variables appropriately; see mh-scan-prog below. You can set the hook mh-inc-folder-hook, which is called after new mail is incorporated by the i (mh-inc-folder) command. A good use of this hook is to rescan the whole folder either after running M-x mh-rmail the first time or when you've changed the message numbers from outside of mh-e.

Example: Rescan folder after incorporating new mail via mh-inc-folder-hook

(defun my-mh-inc-folder-hook ()
  "Hook to rescan folder after incorporating mail."
  (if (buffer-modified-p)         ; if outstanding refiles and deletes,
      (mh-execute-commands))      ; flush them
  (mh-rescan-folder)              ; synchronize with +inbox
  (mh-show))                      ; show the current message

(add-hook 'mh-inc-folder-hook 'my-mh-inc-folder-hook)

Deleting Your Mail

The hook mh-delete-msg-hook is called after you mark a message for deletion. The current maintainer of mh-e used this once when he kept statistics on his mail usage.

Organizing Your Mail with Folders

By default, operations on folders work only one level at a time. Set mh-recursive-folders to non-nil to operate on all folders. This mostly means that you'll be able to see all your folders when you press TAB when prompted for a folder name. The variable mh-auto-folder-collect is normally turned on to generate a list of folder names in the background as soon as mh-e is loaded. Otherwise, the list is generated when you need a folder name the first time (as with o (mh-refile-msg)). If you have a lot of folders and you have mh-recursive-folders set, this could take a while, which is why it's nice to do the folder collection in the background.

The function mh-default-folder-for-message-function is used by o (mh-refile-msg) and C-c C-f C-f (mh-to-fcc) to generate a default folder. The generated folder name should be a string with a "+" before it. For each of my correspondents, I use the same name for both an alias and a folder. So, I wrote a function that takes the address in the From: header field, finds it in my alias file, and returns the alias which is used as a default folder name. This is the most complicated example given here, and it demonstrates several features of Emacs Lisp programming. You should be able to drop this into ~/.emacs, however. If you use this to store messages in a subfolder of your Mail directory, you can modify the line that starts (format "+%s" ... and insert your subfolder after the folder symbol "+".

Example: Default refiling folder via mh-default-folder-for-message-function

(defun my-mh-folder-from-address ()
  "Determine folder name from address.
Takes the address in the From: header field, and returns its corresponding
alias from the user's personal aliases file. Returns nil if the address
was not found."
  (require 'rfc822)                                 ; for the rfc822 functions
  (search-forward-regexp "^From: \\(.*\\)")     ; grab contents of header field
  (setq addr (car (rfc822-addresses                 ; get address from header field
                   (buffer-substring (match-beginning 1)
                                     (match-end 1)))))
  (save-excursion                                   ; save state
    (let ((buffer (get-buffer-create " *temp*"))    ; set local variables
      (set-buffer buffer)                           ; jump to temporary buffer
      (unwind-protect                               ; run kill-buffer when done or on error
          (progn                                    ; function grouping construct
            (insert-file-contents (expand-file-name "aliases" mh-user-path))
            (goto-char (point-min))                 ; grab aliases file and go to beginning
            (setq folder
                  ;; Search for the given address, even commented-out addresses are
                  ;; found!  The function search-forward-regexp sets values that are
                  ;; later used by match-beginning and match-end.
                  (if (search-forward-regexp (format "^;*\\(.*\\):.*%s"
                                                     addr) nil t)
                      ;; NOTE WELL: this is what the return value looks like.  You can
                      ;; modify the format string to match your own Mail hierarchy.
                      (format "+%s" (buffer-substring (match-beginning 1)
                                                      (match-end 1))))))
        (kill-buffer buffer))	; get rid of our temporary buffer
      folder)))	; function's return value

(setq mh-default-folder-for-message-function 'my-mh-folder-from-address)
The hook mh-refile-msg-hook is called after a message is marked to be filed.

The variable mh-sortm-args holds extra arguments to pass on to the sortm(1) command (the Section Sorting Messages: sortm). Note: this variable is only consulted when a prefix argument is given to M-x mh-sort-folder. It is used to override any arguments given in a sortm: entry in your MH profile (~/.mh_profile).

Scan line formatting

The name of the program that generates a listing of one line per message is held in mh-scan-prog (default: "scan"). Unless this variable contains an absolute pathname, it is assumed to be in the mh-progs directory. You may link another program to scan (the Section Making a New Command Version) to produce a different type of listing.

If you change the format of the scan lines you'll need to tell mh-e how to parse the new format. As you see, quite a lot of variables are involved to do that. The first variable has to do with pruning out garbage.

This regular expression describes a valid scan line. This is used to eliminate error messages that are occasionally produced by inc or scan (default: "^ *[0-9]").

Next, two variables control how the message numbers are parsed.

This regular expression is used to extract the message number from a scan line. Note that the message number must be placed in quoted parentheses, (\\(...\\)), as in the default of "^ *\\([0-9]+\\)".
Given a message number (which is inserted in %d ), this regular expression will match the scan line that it represents (default: "^[^0-9]*%d[^0-9]").

Finally, there are a slew of variables that control how mh-e marks up the scan lines.

Number of characters to skip over before inserting notation (default: 4). Note how it relates to the following regular expressions.
This regular expression describes deleted messages (default: "^....D"). See also mh-note-deleted.
This regular expression describes refiled messages (default: "^....\\^"). See also mh-note-refiled.
This regular expression matches the current message (default: "^....\\+"). See also mh-note-cur.
This regular expression describes which messages should be shown when mh-e goes to the next or previous message. Normally, deleted or refiled messages are skipped over (default: "^....[^D^]").
Messages that have been deleted to are marked by this string (default: "D"). See also mh-deleted-msg-regexp.
Messages that have been refiled are marked by this string (default: "^"). See also mh-refiled-msg-regexp.
Messages that have been copied are marked by this string (default: "C").
The current message (in MH, not in mh-e) is marked by this string (default: "+"). See also mh-cur-scan-msg-regexp.
Messages that have been replied to are marked by this string (default: "-").
Messages that have been forwarded are marked by this string (default: "F").
Messages that have been redistributed are marked by this string (default: "R").
Messages that have been printed are marked by this string (default: "P").
Messages in a sequence are marked by this string (default: "%").

Printing Your Mail

Normally messages are printed in the foreground. If this is slow on your system, you may elect to set mh-print-background to non-nil to print in the background. If you do this, do not delete the message until it is printed or else the output may be truncated. The variable mh-lpr-command-format controls how the printing is actually done. The string can contain one escape, %s , which is filled with the name of the folder and the message number and is useful for print job names. As an example, the default is "lpr -J '%s'".

Files and Pipes

The initial directory for the mh-store-msg command is held in mh-store-default-directory. Since I almost always run mh-store-msg on sources, I set it to my personal source directory like this:
(setq mh-store-default-directory (expand-file-name "~/src/"))
Subsequent incarnations of mh-store-msg offer the last directory used as the default. By the way, mh-store-msg calls the Emacs Lisp function mh-store-buffer. I mention this because you can use it directly if you're editing a buffer that contains a file that has been run through uuencode or shar. For example, you can extract the contents of the current buffer in your home directory by typing ESC ESC (mh-store-buffer "~").

Finishing Up

The two variables mh-before-quit-hook and mh-quit-hook are called by q (mh-quit). The former one is called before the quit occurs, so you might use it to perform any mh-e operations; you could perform some query and abort the quit or call mh-execute-commands, for example. The latter is not run in an mh-e context, so you might use it to modify the window setup.

[Table of Contents] [Index] [Previous: Editing a Draft] [Next: Searching Through Messages]

(This section was written by Bill Wohler.)
Last change $Date: 1996/07/14 17:35:00 $

This file is from the third edition of the book MH & xmh: Email for Users & Programmers, ISBN 1-56592-093-7, by Jerry Peek. Copyright © 1991, 1992, 1995 by O'Reilly & Associates, Inc. This file is freely-available; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. For more information, see the file copying.htm.

Suggestions are welcome: Bill Wohler <>