Reading Your Mail

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

Note: HTML conversion may not be complete.

I'll start out by including a function that I use as a front end to mh-e. (By the way, Stephen Gildea's favorite binding is (global-set-key "\C-cr" 'mh-rmail).) The function toggles between your working window configuration, which may be quite involved -- windows filled with source, compilation output, man pages, and other documentation --and your mh-e window configuration. Like the rest of the customization described in this chapter, simply add the following code to ~/.emacs.

Example: Starting mh-e

(defvar my-mh-screen-saved nil
  "Set to non-nil when mh-e window configuration shown.")
(defvar my-normal-screen nil "Normal window configuration.")
(defvar my-mh-screen nil "mh-e window configuration.")

(defun my-mh-rmail (&optional arg)
  "Toggle between mh-e and normal screen configurations.
With non-nil or prefix argument, inc mailbox as well when going into mail."
  (interactive "P")                           ; user callable function, P=prefix arg
  (setq my-mh-screen-saved                    ; save state
         ;; Bring up mh-e screen if arg or normal window configuration.
         ;; If arg or +inbox buffer doesn't exist, run mh-rmail.
         ((or arg (null my-mh-screen-saved))
          (setq my-normal-screen (current-window-configuration))
          (if (or arg (null (get-buffer "+inbox")))
            (set-window-configuration my-mh-screen))
          t)                                  ; set my-mh-screen-saved to t
         ;; Otherwise, save mh-e screen and restore normal screen.
          (setq my-mh-screen (current-window-configuration))
          (set-window-configuration my-normal-screen)
          nil))))                             ; set my-mh-screen-saved to nil

(global-set-key "\C-x\r" 'my-mh-rmail)      ; call with C-x RET
If you type an argument (C-u) or if screen-saved-mh is nil (meaning a non-mh-e window configuration), the current window configuration is saved, either +inbox is displayed or mh-rmail is run, and the mh-e window configuration is shown. Otherwise, the mh-e window configuration is saved and the original configuration is displayed.

Now to configure mh-e. The following table lists general mh-e variables and variables that are used while reading mail.

Variable               |       Default     |  Description
mh-progs               |       dynamic     |  Directory containing
                       |                   |  MH programs
mh-lib                 |       dynamic     |  Directory containing
                       |                   |  MH support files and
                       |                   |  programs
mh-do-not-confirm      |         nil       |  Don't   confirm   on
                       |                   |  non-reversible  com-
                       |                   |  mands
mh-summary-height      |          4        |  Number of scan lines
                       |                   |  to   show  (includes
                       |                   |  mode line)
mh-folder-mode-hook    |         nil       |  Functions to run  in
                       |                   |  MH-Folder mode
mh-clean-message-header|         nil       |  Remove    extraneous
                       |                   |  header fields
mh-invisible-headers   |  "^Received: \\|  |  Header   fields   to
                       |  ^Message-Id: \\| |  hide
                       |  ^Remailed-\\|    |
                       |  ^Via: \\|        |
                       |  ^Mail-from: \\|  |
                       |  ^Return-Path: \\||
                       |  ^In-Reply-To: \\||
                       |  ^Resent-"        |
mh-visible-headers     |         nil       |  Header   fields   to
                       |                   |  display
mhl-formfile           |         nil       |  Format file for mhl
mh-show-hook           |         nil       |  Functions   to   run
                       |                   |  when showing message
mh-show-mode-hook      |         nil       |  Functions   to   run
                       |                   |  when showing message
mh-bury-show-buffer    |          t        |
                       |                   |  Leave show buffer at
                       |                   |  end of stack
mh-show-buffer-mode-   |   "{show-%s} %d"  |  Name of show buffer
line-buffer-id         |                   |
The two variables mh-progs and mh-lib are used to tell mh-e where the MH programs and supporting files are kept, respectively. mh-e does try to figure out where they are kept for itself by looking in common places and in the user's PATH environment variable, but if it cannot find the directories, or finds the wrong ones, you should set these variables. The name of the directory should be placed in double quotes, and there should be a trailing slash (/). See the example in the Section Getting Started.

If you never make mistakes, and you do not like confirmations for your actions, you can set mh-do-not-confirm to a non-nil value to disable confirmation for unrecoverable commands such as M-k (mh-kill-folder) and M-u (mh-undo-folder). Here's how you set boolean values:

(setq mh-do-not-confirm t)

The variable mh-summary-height controls the number of scan lines displayed in the MH-Folder window, including the mode line. The default value of 4 means that 3 scan lines are displayed. Here's how you set numerical values:

(setq mh-summary-height 2)            ; only show the current scan line

Normally the buffer for displaying messages is buried at the bottom at the buffer stack. You may wish to disable this feature by setting mh-bury-show-buffer to nil. One advantage of not burying the show buffer is that one can delete the show buffer more easily in an electric buffer list because of its proximity to its associated MH-Folder buffer. Try running M-x electric-buffer-list to see what I mean.

The hook mh-folder-mode-hook is called when a new folder is created with MH-Folder mode. This could be used to set your own key bindings, for example:

Example: Create additional key bindings via mh-folder-mode-hook

(defvar my-mh-init-done nil "Non-nil when one-time mh-e settings have made.")

(defun my-mh-folder-mode-hook ()
  "Hook to set key bindings in MH-Folder mode."
  (if (not my-mh-init-done)                       ; only need to bind the keys once 
        (local-set-key "/" 'search-msg)
        (local-set-key "b" 'mh-burst-digest)      ; better use of b
        (setq my-mh-init-done t))))

;;; Emacs 19
(add-hook 'mh-folder-mode-hook 'my-mh-folder-mode-hook)
;;; Emacs 18
;;;   (setq mh-folder-mode-hook (cons 'my-mh-folder-mode-hook mh-folder-mode-hook))

(defun search-msg ()
  "Search for a regexp in the current message."
  (interactive)                                   ; user function
  (other-window 1)                                ; go to next window
  (isearch-forward-regexp)                        ; string search; hit return (ESC in
                                                  ;   Emacs 18) when done
  (other-window -1))                              ; go back to folder
Remove the triple semicolons (;;;) from the line that applies to your version of Emacs.

Viewing Your Mail

Several variables control what displayed messages look like. Normally messages are delivered with a handful of uninteresting header fields. You can make them go away by setting mh-clean-message-header to a non-nil value. The header can then be cleaned up in two ways. By default, the header fields in mh-invisible-headers are removed. On the other hand, you could set mh-visible-headers to the fields that you would like to see. If this variable is set, mh-invisible-headers is ignored. It is suggested not to set mh-visible-headers since if you use this variable, you might miss a lot of header fields that you'd rather not miss. As an example of how to set a string variable, mh-visible-headers can be set to show a minimum set of header fields:

(setq mh-visible-headers "^From: \\|^Subject: \\|^Date: ")

Normally mh-e takes care of displaying messages itself (rather than calling an MH program to do the work). If you'd rather have mhl display the message (within mh-e), set the variable mhl-formfile to a non-nil value. You can set this variable either to t to use the default format file or to a filename if you have your own format file (the Section mhl tells you how to write one). When writing your own format file, use a nonzero value for overflowoffset to insure the header is RFC 822 compliant and parseable by mh-e. mhl is always used for printing and forwarding; in this case, the value of mhl-formfile is consulted if it is a filename.

Two hooks can be used to control how messages are displayed. The first hook, mh-show-mode-hook, is called early on in the process of displaying of messages. It is used to perform some actions on the contents of messages, such as highlighting the header fields. If you're running Emacs 19 under the X Window System, the Example Emphasize header fields in different fonts via mh-show-mode-hook will highlight the From: and Subject: header fields. This is a very nice feature indeed.

Example: Emphasize header fields in different fonts via mh-show-mode-hook

(defvar my-mh-keywords
   '(("^From: \\(.*\\)" 1 'bold t)
     ("^Subject: \\(.*\\)" 1 'highlight t))
  "mh-e additions for font-lock-keywords.")

(defun my-mh-show-mode-hook ()
  "Hook to turn on and customize fonts."
  (require 'font-lock)                                ; for font-lock-keywords below
  (make-local-variable 'font-lock-mode-hook)          ; don't affect other buffers
  (add-hook 'font-lock-mode-hook                      ; set a hook with inline function
            (function                                 ; modifies font-lock-keywords when
             (lambda ()                               ; font-lock-mode run
               (setq font-lock-keywords 
                     (append my-mh-keywords font-lock-keywords)))))
  (font-lock-mode 1))                                 ; change the typefaces

(if window-system                                     ; can't do this on ASCII terminal
    (add-hook 'mh-show-mode-hook 'my-mh-show-mode-hook))
The second hook, mh-show-hook, is the last thing called after messages are displayed. It's used to affect the behavior of mh-e in general or when mh-show-mode-hook is too early. For example, if you wanted to keep mh-e in sync with MH, you could use mh-show-hook as follows:
(add-hook 'mh-show-hook 'mh-update-sequences)
The function mh-update-sequences is documented in the Section Finishing Up. For those who like to modify their mode lines, use mh-show-buffer-mode-line-buffer-id to modify the mode line in the MH-Show buffers. Place the two escape strings %s and %d, which will display the folder name and the message number, respectively, somewhere in the string in that order. The default value of "{show-%s} %d" yields a mode line of
-----{show-+inbox} 4      (MH-Show) -- Bot------------------------------

Moving Around

When you use t (mh-toggle-showing) to toggle between show mode and scan mode, the MH-Show buffer is hidden and the MH-Folder buffer is left alone. Setting mh-recenter-summary-p to a non-nil value causes the toggle to display as many scan lines as possible, with the cursor at the middle. The effect of mh-recenter-summary-p is rather useful, but it can be annoying on a slow network connection.

[Table of Contents] [Index] [Previous: Miscellaneous Commands] [Next: Sending Mail]

(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 <>