]> code.delx.au - gnu-emacs/blobdiff - lisp/mh-e.el
Comment changes.
[gnu-emacs] / lisp / mh-e.el
index 83ad28509046829535106dfc660991d04634eaaf..619556d260feb483e50d7b999a893db2cc4c67fd 100644 (file)
@@ -1,15 +1,12 @@
-;;; mh-e.el --- GNU Emacs interface to the MH mailer
+;;; mh-e.el --- GNU Emacs interface to the MH mail system
 
 
-;;; (Version: 3.7 for GNU Emacs Version 18 and MH.5 and MH.6)
+;;; Copyright (C) 1985, 86, 87, 88, 90, 92, 93 Free Software Foundation
 
 
-(defvar mh-e-RCS-id)
-(setq mh-e-RCS-id "$Header: /var/home/larus/lib/emacs/RCS/mh-e.el,v 3.1 90/09/28 15:47:58 larus Exp Locker: larus $")
-;;;  Copyright (C) 1985-89 Free Software Foundation
-;;;     Author:  James Larus (larus@ginger.Berkeley.EDU or ucbvax!larus)
-;;;    Please send suggestions and corrections to the above address.
-;;;
-;;;  This file contains mh-e, a GNU Emacs front end to the MH mail system.
+(defconst mh-e-time-stamp "Time-stamp: <93/05/30 18:37:43 gildea>")
 
 
+;; Maintainer: Stephen Gildea <gildea@lcs.mit.edu>
+;; Version: 3.8.2
+;; Keywords: mail
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but without any warranty.  No author or distributor
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but without any warranty.  No author or distributor
 ;; It should be in a file named COPYING.  Among other things, the
 ;; copyright notice and this notice must be preserved on all copies.
 
 ;; It should be in a file named COPYING.  Among other things, the
 ;; copyright notice and this notice must be preserved on all copies.
 
+;;; Commentary:
 
 
-;;;  Original version for Gosling emacs by Brian Reid, Stanford, 1982.
-;;;  Modified by James Larus, BBN, July 1984 and UCB, 1984 & 1985.
-;;;  Rewritten for GNU Emacs, James Larus 1985.  larus@ginger.berkeley.edu
-;;;  Modified by Stephen Gildea 1988.  gildea@bbn.com
+;;; mh-e works with Emacs 18 or 19, and MH 5 or 6.
 
 
+;;; HOW TO USE:
+;;; M-x mh-rmail to read mail.  Type C-h m there for a list of commands.
+;;; C-u M-x mh-rmail to visit any folder.
+;;; M-x mh-smail to send mail.  From within the mail reader, "m" works, too.
+;;; Your .emacs might benefit from these bindings:
+;;; (global-set-key "\C-xm" 'mh-smail)
+;;; (global-set-key "\C-x4m" 'mh-smail-other-window)
+;;; (global-set-key "\C-cr" 'mh-rmail)
 
 
-;;;  NB.  MH must have been compiled with the MHE compiler flag or several
-;;;  features necessary mh-e will be missing from MH commands, specifically
-;;;  the -build switch to repl and forw.
+;;; MH (Message Handler) is a powerful mail reader.  The MH newsgroup
+;;; is comp.mail.mh; the mailing list is mh-users@ics.uci.edu (send to
+;;; mh-users-request to be added).  See the monthly Frequently Asked
+;;; Questions posting there for information on getting MH.
+
+;;; NB.  MH must have been compiled with the MHE compiler flag or several
+;;; features necessary mh-e will be missing from MH commands, specifically
+;;; the -build switch to repl and forw.
+
+;;; Original version for Gosling emacs by Brian Reid, Stanford, 1982.
+;;; Modified by James Larus, BBN, July 1984 and UCB, 1984 & 1985.
+;;; Rewritten for GNU Emacs, James Larus 1985.  larus@ginger.berkeley.edu
+;;; Modified by Stephen Gildea 1988.  gildea@bbn.com
+(defconst mh-e-RCS-id "$Header: /home/fsf/rms/e19/lisp/RCS/mh-e.el,v 1.15 1993/07/20 04:35:00 rms Exp rms $")
+
+;;; Code:
 
 \f
 
 
 \f
 
@@ -45,7 +61,7 @@
 ;;;(defvar mh-progs "/usr/new/mh/" "Directory containing MH commands.")
 ;;;(defvar mh-lib "/usr/new/lib/mh/" "Directory of MH library.")
 
 ;;;(defvar mh-progs "/usr/new/mh/" "Directory containing MH commands.")
 ;;;(defvar mh-lib "/usr/new/lib/mh/" "Directory of MH library.")
 
-(defvar mh-redist-full-contents t
+(defvar mh-redist-full-contents nil
   "Non-nil if the `dist' command needs whole letter for redistribution.
 This is the case when `send' is compiled with the BERK option.")
 
   "Non-nil if the `dist' command needs whole letter for redistribution.
 This is the case when `send' is compiled with the BERK option.")
 
@@ -68,8 +84,11 @@ It is passed three arguments: TO recipients, SUBJECT, and CC recipients.")
 (defvar mh-inc-folder-hook nil
   "Invoked after incorporating mail into a folder with \\[mh-inc-folder].")
 
 (defvar mh-inc-folder-hook nil
   "Invoked after incorporating mail into a folder with \\[mh-inc-folder].")
 
+(defvar mh-before-quit-hook nil
+  "Invoked by \\[mh-quit] before quitting mh-e.  See also  mh-quit-hook")
+
 (defvar mh-quit-hook nil
 (defvar mh-quit-hook nil
-  "Invoked after quitting mh-e with \\[mh-quit].")
+  "Invoked after quitting mh-e by \\[mh-quit].  See also  mh-before-quit-hook")
 
 
 (defvar mh-ins-string nil
 
 
 (defvar mh-ins-string nil
@@ -80,7 +99,7 @@ It is passed three arguments: TO recipients, SUBJECT, and CC recipients.")
     (save-excursion
       (goto-char (point))
       (or (bolp) (forward-line 1))
     (save-excursion
       (goto-char (point))
       (or (bolp) (forward-line 1))
-      (while (< (point) (mark))
+      (while (< (point) (mark t))
        (insert mh-ins-string)
        (forward-line 1))))
   "Hook to run citation function.
        (insert mh-ins-string)
        (forward-line 1))))
   "Hook to run citation function.
@@ -116,12 +135,12 @@ WARNING: do not delete the messages until printing is finished;
 otherwise, your output may be truncated.")
 
 (defvar mh-summary-height 4
 otherwise, your output may be truncated.")
 
 (defvar mh-summary-height 4
-  "*Number of lines in summary window.")
+  "*Number of lines in summary window (including the mode line).")
 
 (defvar mh-recenter-summary-p nil
   "*Recenter summary window when the show window is toggled off if non-nil.")
 
 
 (defvar mh-recenter-summary-p nil
   "*Recenter summary window when the show window is toggled off if non-nil.")
 
-(defvar mh-ins-buf-prefix ">> "
+(defvar mh-ins-buf-prefix "> "
   "*String to put before each non-blank line of a yanked or inserted message.
 Used when the message is inserted in an outgoing letter.")
 
   "*String to put before each non-blank line of a yanked or inserted message.
 Used when the message is inserted in an outgoing letter.")
 
@@ -139,7 +158,7 @@ windows displaying the message.")
 
 (defvar mh-yank-from-start-of-msg t
   "*Controls which part of a message is yanked by \\[mh-yank-cur-msg].
 
 (defvar mh-yank-from-start-of-msg t
   "*Controls which part of a message is yanked by \\[mh-yank-cur-msg].
-If non-nil, include the entire message.  If the symbol `body, then yank the
+If non-nil, include the entire message.  If the symbol `body', then yank the
 message minus the header.  If nil, yank only the portion of the message
 following the point.  If the show buffer has a region, this variable is
 ignored.")
 message minus the header.  If nil, yank only the portion of the message
 following the point.  If the show buffer has a region, this variable is
 ignored.")
@@ -152,9 +171,16 @@ value and it should be one of \"from\", \"to\", or \"cc\".")
 (defvar mh-recursive-folders nil
   "*If non-nil, then commands which operate on folders do so recursively.")
 
 (defvar mh-recursive-folders nil
   "*If non-nil, then commands which operate on folders do so recursively.")
 
+(defvar mh-unshar-default-directory ""
+  "*Default for directory name prompted for by mh-unshar-msg.")
+
+(defvar mh-signature-file-name "~/.signature"
+  "*Name of file containing the user's signature.
+Inserted into message by \\<mh-letter-mode-map>\\[mh-insert-signature].")
+
 
 ;;; Parameterize mh-e to work with different scan formats.  The defaults work
 
 ;;; Parameterize mh-e to work with different scan formats.  The defaults work
-;;; the standard MH scan listings.
+;;; with the standard MH scan listings.
 
 (defvar mh-cmd-note 4
   "Offset to insert notation.")
 
 (defvar mh-cmd-note 4
   "Offset to insert notation.")
@@ -169,7 +195,7 @@ value and it should be one of \"from\", \"to\", or \"cc\".")
   "String whose first character is used to notate redistributed messages.")
 
 (defvar mh-good-msg-regexp  "^....[^D^]"
   "String whose first character is used to notate redistributed messages.")
 
 (defvar mh-good-msg-regexp  "^....[^D^]"
-  "Regexp specifiying the scan lines that are 'good' messages.")
+  "Regexp specifying the scan lines that are 'good' messages.")
 
 (defvar mh-deleted-msg-regexp "^....D"
   "Regexp matching scan lines of deleted messages.")
 
 (defvar mh-deleted-msg-regexp "^....D"
   "Regexp matching scan lines of deleted messages.")
@@ -212,7 +238,10 @@ The string is displayed after the folder's name.  NIL for no annotation.")
 If `mh-visible-headers' is non-nil, it is used instead to specify what
 to keep.")
 
 If `mh-visible-headers' is non-nil, it is used instead to specify what
 to keep.")
 
-(defvar mh-rejected-letter-start "^   ----- Unsent message follows -----$"
+(defvar mh-rejected-letter-start
+  (concat "^   ----- Unsent message follows -----$" ;from mail system
+         "\\|^------- Unsent Draft$"   ;from MH itself
+         "\\|^  --- The unsent message follows ---$") ;from AIX mail system
   "Regexp specifying the beginning of the wrapper around a returned letter.
 This wrapper is generated by the mail system when rejecting a letter.")
 
   "Regexp specifying the beginning of the wrapper around a returned letter.
 This wrapper is generated by the mail system when rejecting a letter.")
 
@@ -238,6 +267,9 @@ This wrapper is generated by the mail system when rejecting a letter.")
 (defvar mh-pick-mode-map (make-sparse-keymap)
   "Keymap for searching folder.")
 
 (defvar mh-pick-mode-map (make-sparse-keymap)
   "Keymap for searching folder.")
 
+(defvar mh-searching-folder nil
+  "Folder this pick is searching.")
+
 (defvar mh-letter-mode-syntax-table nil
   "Syntax table used while in mh-e letter mode.")
 
 (defvar mh-letter-mode-syntax-table nil
   "Syntax table used while in mh-e letter mode.")
 
@@ -264,9 +296,6 @@ NIL means do not use draft folder.")
 (defvar mh-previous-seq nil
   "Name of the sequence to which a message was last added.")
 
 (defvar mh-previous-seq nil
   "Name of the sequence to which a message was last added.")
 
-(defvar mh-signature-file-name "~/.signature"
-  "Name of file containing the user's signature.")
-
 
 ;;; Macros and generic functions:
 
 
 ;;; Macros and generic functions:
 
@@ -411,13 +440,13 @@ from a sequence."
         (config (current-window-configuration))
         (draft
          (cond ((and mh-draft-folder (equal from-folder mh-draft-folder))
         (config (current-window-configuration))
         (draft
          (cond ((and mh-draft-folder (equal from-folder mh-draft-folder))
-                (find-file (mh-msg-filename msg))
+                (pop-to-buffer (find-file-noselect (mh-msg-filename msg)) t)
                 (rename-buffer (format "draft-%d" msg))
                 (buffer-name))
                (t
                 (mh-read-draft "clean-up" (mh-msg-filename msg) nil)))))
     (mh-clean-msg-header (point-min)
                 (rename-buffer (format "draft-%d" msg))
                 (buffer-name))
                (t
                 (mh-read-draft "clean-up" (mh-msg-filename msg) nil)))))
     (mh-clean-msg-header (point-min)
-                        "^Date:\\|^Received:\\|^Message-Id:\\|^From:"
+                        "^Date:\\|^Received:\\|^Message-Id:\\|^From:\\|^Delivery-Date:"
                         nil)
     (goto-char (point-min))
     (set-buffer-modified-p nil)
                         nil)
     (goto-char (point-min))
     (set-buffer-modified-p nil)
@@ -448,7 +477,7 @@ Default is the displayed message."
           (forward-char 1)
           (delete-region (point-min) (point))
           (mh-clean-msg-header (point-min)
           (forward-char 1)
           (delete-region (point-min) (point))
           (mh-clean-msg-header (point-min)
-                               "^Date:\\|^Received:\\|^Message-Id:\\|^From:\\|^Sender:"
+                               "^Date:\\|^Received:\\|^Message-Id:\\|^From:\\|^Sender:\\|^Return-Path:"
                                nil))
          (t
           (message "Does not appear to be a rejected letter.")))
                                nil))
          (t
           (message "Does not appear to be a rejected letter.")))
@@ -515,7 +544,7 @@ If optional prefix argument provided, then prompt for the message sequence."
 Non-nil second argument means do not signal an error if message does not exist.
 Non-nil third argument means not to show the message.
 Return non-nil if cursor is at message."
 Non-nil second argument means do not signal an error if message does not exist.
 Non-nil third argument means not to show the message.
 Return non-nil if cursor is at message."
-  (interactive "NMessage number? ")
+  (interactive "NGoto message: ")
   (let ((cur-msg (mh-get-msg-num nil))
        (starting-place (point))
        (msg-pattern (mh-msg-search-pat number)))
   (let ((cur-msg (mh-get-msg-num nil))
        (starting-place (point))
        (msg-pattern (mh-msg-search-pat number)))
@@ -542,7 +571,7 @@ Return non-nil if cursor is at message."
 (defun mh-inc-folder (&optional maildrop-name)
   "Inc(orporate) new mail into +inbox.
 Optional prefix argument specifies an alternate maildrop from the default.
 (defun mh-inc-folder (&optional maildrop-name)
   "Inc(orporate) new mail into +inbox.
 Optional prefix argument specifies an alternate maildrop from the default.
-If this is given, mail is incorporated into the current folder, rather
+If this is given, incorporate mail into the current folder, rather
 than +inbox.  Run `mh-inc-folder-hook' after incorporating new mail."
   (interactive (list (if current-prefix-arg
                         (expand-file-name
 than +inbox.  Run `mh-inc-folder-hook' after incorporating new mail."
   (interactive (list (if current-prefix-arg
                         (expand-file-name
@@ -571,7 +600,8 @@ than +inbox.  Run `mh-inc-folder-hook' after incorporating new mail."
        (mh-remove-folder-from-folder-list folder)
        (message "Folder %s removed" folder)
        (mh-set-folder-modified-p nil)  ; so kill-buffer doesn't complain
        (mh-remove-folder-from-folder-list folder)
        (message "Folder %s removed" folder)
        (mh-set-folder-modified-p nil)  ; so kill-buffer doesn't complain
-       (kill-buffer mh-show-buffer)
+       (if (get-buffer mh-show-buffer)
+           (kill-buffer mh-show-buffer))
        (kill-buffer folder))
       (message "Folder not removed")))
 
        (kill-buffer folder))
       (message "Folder not removed")))
 
@@ -592,7 +622,9 @@ than +inbox.  Run `mh-inc-folder-hook' after incorporating new mail."
       (switch-to-buffer " *mh-temp*")
       (erase-buffer)
       (message "Listing folders...")
       (switch-to-buffer " *mh-temp*")
       (erase-buffer)
       (message "Listing folders...")
-      (mh-exec-cmd-output "folders" t)
+      (mh-exec-cmd-output "folders" t (if mh-recursive-folders
+                                         "-recurse"
+                                         "-norecurse"))
       (goto-char (point-min))
       (message "Listing folders...done"))))
 
       (goto-char (point-min))
       (message "Listing folders...done"))))
 
@@ -658,7 +690,7 @@ Otherwise just send the message's body."
   (interactive
    (list current-prefix-arg (read-string "Shell command on message: ")))
   (save-excursion
   (interactive
    (list current-prefix-arg (read-string "Shell command on message: ")))
   (save-excursion
-    (set-buffer mh-show-buffer)
+    (mh-display-msg (mh-get-msg-num t) mh-current-folder) ;update show buffer
     (goto-char (point-min))
     (if (not prefix-provided) (search-forward "\n\n"))
     (shell-command-on-region (point) (point-max) command nil)))
     (goto-char (point-min))
     (if (not prefix-provided) (search-forward "\n\n"))
     (shell-command-on-region (point) (point-max) command nil)))
@@ -719,7 +751,7 @@ using filter mhl.reply in your MH directory."
       (message "Composing a reply...")
       (cond ((or (equal reply-to "from") (equal reply-to ""))
             (apply 'mh-exec-cmd
       (message "Composing a reply...")
       (cond ((or (equal reply-to "from") (equal reply-to ""))
             (apply 'mh-exec-cmd
-                   "repl" "-build"
+                   "repl" "-build" "-noquery"
                    "-nodraftfolder" mh-current-folder
                    msg
                    "-nocc" "all"
                    "-nodraftfolder" mh-current-folder
                    msg
                    "-nocc" "all"
@@ -727,7 +759,7 @@ using filter mhl.reply in your MH directory."
                        (list "-filter" "mhl.reply"))))
            ((equal reply-to "to")
             (apply 'mh-exec-cmd
                        (list "-filter" "mhl.reply"))))
            ((equal reply-to "to")
             (apply 'mh-exec-cmd
-                   "repl" "-build"
+                   "repl" "-build" "-noquery"
                    "-nodraftfolder" mh-current-folder
                    msg
                    "-cc" "to"
                    "-nodraftfolder" mh-current-folder
                    msg
                    "-cc" "to"
@@ -735,7 +767,7 @@ using filter mhl.reply in your MH directory."
                        (list "-filter" "mhl.reply"))))
            ((or (equal reply-to "cc") (equal reply-to "all"))
             (apply 'mh-exec-cmd
                        (list "-filter" "mhl.reply"))))
            ((or (equal reply-to "cc") (equal reply-to "all"))
             (apply 'mh-exec-cmd
-                   "repl" "-build"
+                   "repl" "-build" "-noquery"
                    "-nodraftfolder" mh-current-folder
                    msg
                    "-cc" "all" "-nocc" "me"
                    "-nodraftfolder" mh-current-folder
                    msg
                    "-cc" "all" "-nocc" "me"
@@ -762,9 +794,11 @@ using filter mhl.reply in your MH directory."
 
 
 (defun mh-quit ()
 
 
 (defun mh-quit ()
-  "Restore the previous window configuration, if one exists.
-Finish by running mh-quit-hook."
+  "Quit mh-e.
+Start by running mh-before-quit-hook.  Restore the previous window
+configuration, if one exists.  Finish by running mh-quit-hook."
   (interactive)
   (interactive)
+  (run-hooks 'mh-before-quit-hook)
   (if mh-previous-window-config
       (set-window-configuration mh-previous-window-config))
   (run-hooks 'mh-quit-hook))
   (if mh-previous-window-config
       (set-window-configuration mh-previous-window-config))
   (run-hooks 'mh-quit-hook))
@@ -901,7 +935,7 @@ If optional prefix argument provided, then prompt for the message sequence."
   (mh-add-msgs-to-seq from to))
 
 
   (mh-add-msgs-to-seq from to))
 
 
-(defun mh-rescan-folder (range)
+(defun mh-rescan-folder (&optional range)
   "Rescan a folder after optionally processing the outstanding commands.
 If optional prefix argument is provided, prompt for the range of
 messages to display.  Otherwise show the entire folder."
   "Rescan a folder after optionally processing the outstanding commands.
 If optional prefix argument is provided, prompt for the range of
 messages to display.  Otherwise show the entire folder."
@@ -985,7 +1019,10 @@ setting of the variable mh-redist-full-contents.  See its documentation."
 
 
 (defun mh-send (to cc subject)
 
 
 (defun mh-send (to cc subject)
-  "Compose and send a letter."
+  "Compose and send a letter.
+The letter is composed in mh-letter-mode; see its documentation for more
+details.  If `mh-compose-letter-function' is defined, it is called on the
+draft and passed three arguments: to, subject, and cc."
   (interactive "sTo: \nsCc: \nsSubject: ")
   (let ((config (current-window-configuration)))
     (delete-other-windows)
   (interactive "sTo: \nsCc: \nsSubject: ")
   (let ((config (current-window-configuration)))
     (delete-other-windows)
@@ -1040,14 +1077,15 @@ mh-summary-height) and the show buffer below it."
     (mh-show-message-in-other-window)
     (mh-display-msg msg folder))
   (other-window -1)
     (mh-show-message-in-other-window)
     (mh-display-msg msg folder))
   (other-window -1)
-  (shrink-window (- (window-height) mh-summary-height))
+  (if (not (= (1+ (window-height)) (screen-height))) ;not horizontally split
+      (shrink-window (- (window-height) mh-summary-height)))
   (mh-recenter nil)
   (if (not (memq msg mh-seen-list)) (mh-push msg mh-seen-list)))
 
 
 (defun mh-sort-folder ()
   "Sort the messages in the current folder by date."
   (mh-recenter nil)
   (if (not (memq msg mh-seen-list)) (mh-push msg mh-seen-list)))
 
 
 (defun mh-sort-folder ()
   "Sort the messages in the current folder by date."
-  (interactive "")
+  (interactive)
   (mh-process-or-undo-commands mh-current-folder)
   (setq mh-next-direction 'forward)
   (mh-set-folder-modified-p t)         ; lock folder while sorting
   (mh-process-or-undo-commands mh-current-folder)
   (setq mh-next-direction 'forward)
   (mh-set-folder-modified-p t)         ; lock folder while sorting
@@ -1073,21 +1111,30 @@ provided, then prompt for the message sequence."
                     (if current-prefix-arg
                         (mh-read-seq-default "Undo" t)
                         (mh-get-msg-num t))))
                     (if current-prefix-arg
                         (mh-read-seq-default "Undo" t)
                         (mh-get-msg-num t))))
-
   (cond (prefix-provided
         (mh-mapc (function mh-undo-msg) (mh-seq-to-msgs msg-or-seq)))
   (cond (prefix-provided
         (mh-mapc (function mh-undo-msg) (mh-seq-to-msgs msg-or-seq)))
-       ((or (looking-at mh-deleted-msg-regexp)
-            (looking-at mh-refiled-msg-regexp))
-        (mh-undo-msg (mh-get-msg-num t)))
        (t
        (t
-        (error "Nothing to undo")))
+        (let ((original-position (point)))
+          (beginning-of-line)
+          (while (not (or (looking-at mh-deleted-msg-regexp)
+                          (looking-at mh-refiled-msg-regexp)
+                          (and (eq mh-next-direction 'forward) (bobp))
+                          (and (eq mh-next-direction 'backward)
+                               (save-excursion (forward-line) (eobp)))))
+            (forward-line (if (eq mh-next-direction 'forward) -1 1)))
+          (if (or (looking-at mh-deleted-msg-regexp)
+                  (looking-at mh-refiled-msg-regexp))
+              (progn
+                (mh-undo-msg (mh-get-msg-num t))
+                (mh-maybe-show))
+              (goto-char original-position)
+              (error "Nothing to undo")))))
   ;; update the mh-refile-list so mh-outstanding-commands-p will work
   (mh-mapc (function
            (lambda (elt)
              (if (not (mh-seq-to-msgs elt))
                  (setq mh-refile-list (delq elt mh-refile-list)))))
           mh-refile-list)
   ;; update the mh-refile-list so mh-outstanding-commands-p will work
   (mh-mapc (function
            (lambda (elt)
              (if (not (mh-seq-to-msgs elt))
                  (setq mh-refile-list (delq elt mh-refile-list)))))
           mh-refile-list)
-
   (if (not (mh-outstanding-commands-p))
       (mh-set-folder-modified-p nil)))
 
   (if (not (mh-outstanding-commands-p))
       (mh-set-folder-modified-p nil)))
 
@@ -1096,18 +1143,17 @@ provided, then prompt for the message sequence."
   ;; Undo the deletion or refile of one MESSAGE.
   (cond ((memq msg mh-delete-list)
         (setq mh-delete-list (delq msg mh-delete-list))
   ;; Undo the deletion or refile of one MESSAGE.
   (cond ((memq msg mh-delete-list)
         (setq mh-delete-list (delq msg mh-delete-list))
-        (mh-remove-msg-from-seq msg 'deleted t)
-        (mh-notate msg ?  mh-cmd-note))
+        (mh-remove-msg-from-seq msg 'deleted t))
        (t
         (mh-mapc (function (lambda (dest)
                              (mh-remove-msg-from-seq msg dest t)))
        (t
         (mh-mapc (function (lambda (dest)
                              (mh-remove-msg-from-seq msg dest t)))
-                 mh-refile-list)
-        (mh-notate msg ?  mh-cmd-note))))
+                 mh-refile-list)))
+  (mh-notate msg ?  mh-cmd-note))
 
 
 (defun mh-undo-folder (&rest ignore)
   "Undo all commands in current folder."
 
 
 (defun mh-undo-folder (&rest ignore)
   "Undo all commands in current folder."
-  (interactive "")
+  (interactive)
   (cond ((or mh-do-not-confirm
             (yes-or-no-p "Undo all commands in folder? "))
         (setq mh-delete-list nil
   (cond ((or mh-do-not-confirm
             (yes-or-no-p "Undo all commands in folder? "))
         (setq mh-delete-list nil
@@ -1121,22 +1167,57 @@ provided, then prompt for the message sequence."
         (sit-for 2))))
 
 
         (sit-for 2))))
 
 
+(defun mh-unshar-msg (dir)
+  "Unpack the shar file contained in the current message into directory DIR."
+  (interactive (list (read-file-name "Unshar message in directory: "
+                                    mh-unshar-default-directory
+                                    mh-unshar-default-directory nil)))
+  (mh-display-msg (mh-get-msg-num t) mh-current-folder) ;update show buffer
+  (mh-unshar-buffer dir))
+
+(defun mh-unshar-buffer (dir)
+  ;; Unpack the shar file contained in the current buffer into directory DIR.
+  (goto-char (point-min))
+  (if (or (re-search-forward "^#![ \t]*/bin/sh" nil t)
+         (and (re-search-forward "^[^a-z0-9\"]*cut here\b" nil t)
+              (forward-line 1))
+         (re-search-forward "^#" nil t)
+         (re-search-forward "^: " nil t))
+      (let ((default-directory (expand-file-name dir))
+           (start (progn (beginning-of-line) (point)))
+           (log-buffer (get-buffer-create "*Unshar Output*")))
+       (save-excursion
+         (set-buffer log-buffer)
+         (setq default-directory (expand-file-name dir))
+         (erase-buffer)
+         (if (file-directory-p default-directory)
+             (insert "cd " dir "\n")
+           (insert "mkdir " dir "\n")
+           (call-process "mkdir" nil log-buffer t default-directory)))
+       (set-window-start (display-buffer log-buffer) 0) ;so can watch progress
+       (call-process-region start (point-max) "sh" nil log-buffer t))
+    (error "Cannot find start of shar.")))
+       
+
 (defun mh-visit-folder (folder &optional range)
 (defun mh-visit-folder (folder &optional range)
-  "Visit FOLDER and display RANGE of messages."
+  "Visit FOLDER and display RANGE of messages.
+Assumes mh-e has already been initialized."
   (interactive (list (mh-prompt-for-folder "Visit" "+inbox" t)
                     (mh-read-msg-range "Range [all]? ")))
   (let ((config (current-window-configuration)))
     (mh-scan-folder folder (or range "all"))
   (interactive (list (mh-prompt-for-folder "Visit" "+inbox" t)
                     (mh-read-msg-range "Range [all]? ")))
   (let ((config (current-window-configuration)))
     (mh-scan-folder folder (or range "all"))
-    (setq mh-previous-window-config config)))
+    (setq mh-previous-window-config config))
+  nil)
 
 
 (defun mh-widen ()
   "Remove restrictions from the current folder, thereby showing all messages."
 
 
 (defun mh-widen ()
   "Remove restrictions from the current folder, thereby showing all messages."
-  (interactive "")
-  (with-mh-folder-updating (t)
-    (delete-region (point-min) (point-max))
-    (widen)
-    (mh-make-folder-mode-line))
+  (interactive)
+  (if mh-narrowed-to-seq
+      (with-mh-folder-updating (t)
+       (delete-region (point-min) (point-max))
+       (widen)
+       (mh-make-folder-mode-line)))
   (setq mh-narrowed-to-seq nil))
 
 \f
   (setq mh-narrowed-to-seq nil))
 
 \f
@@ -1158,7 +1239,7 @@ provided, then prompt for the message sequence."
 
 
 (defun mh-refile-a-msg (msg destination)
 
 
 (defun mh-refile-a-msg (msg destination)
-  ;; Refile MESSAGE in FOLDER.
+  ;; Refile MESSAGE in FOLDER.  FOLDER is a symbol, not a string.
   (save-excursion
     (mh-goto-msg msg nil t)
     (cond ((looking-at mh-deleted-msg-regexp)
   (save-excursion
     (mh-goto-msg msg nil t)
     (cond ((looking-at mh-deleted-msg-regexp)
@@ -1182,6 +1263,7 @@ provided, then prompt for the message sequence."
 
 (defun mh-display-msg (msg-num folder)
   ;; Display message NUMBER of FOLDER.
 
 (defun mh-display-msg (msg-num folder)
   ;; Display message NUMBER of FOLDER.
+  ;; Sets the current buffer to the show buffer.
   (set-buffer folder)
   ;; Bind variables in folder buffer in case they are local
   (let ((formfile mhl-formfile)
   (set-buffer folder)
   ;; Bind variables in folder buffer in case they are local
   (let ((formfile mhl-formfile)
@@ -1251,7 +1333,7 @@ provided, then prompt for the message sequence."
     (save-restriction
       (goto-char start)
       (if (search-forward "\n\n" nil t)
     (save-restriction
       (goto-char start)
       (if (search-forward "\n\n" nil t)
-         (backward-char 2))
+         (backward-char 1))
       (narrow-to-region start (point))
       (goto-char (point-min))
       (if visible-headers
       (narrow-to-region start (point))
       (goto-char (point-min))
       (if visible-headers
@@ -1291,7 +1373,7 @@ provided, then prompt for the message sequence."
   ;; reused.
   (cond (mh-draft-folder
         (let ((orig-default-dir default-directory))
   ;; reused.
   (cond (mh-draft-folder
         (let ((orig-default-dir default-directory))
-          (pop-to-buffer (find-file-noselect (mh-new-draft-name) t))
+          (pop-to-buffer (find-file-noselect (mh-new-draft-name)) t)
           (rename-buffer (format "draft-%s" (buffer-name)))
           (setq default-directory orig-default-dir)))
        (t
           (rename-buffer (format "draft-%s" (buffer-name)))
           (setq default-directory orig-default-dir)))
        (t
@@ -1327,7 +1409,7 @@ provided, then prompt for the message sequence."
     (set-buffer (get-buffer-create " *mh-temp*"))
     (erase-buffer)
     (mh-exec-cmd-output "mhpath" nil mh-draft-folder "new")
     (set-buffer (get-buffer-create " *mh-temp*"))
     (erase-buffer)
     (mh-exec-cmd-output "mhpath" nil mh-draft-folder "new")
-    (buffer-substring (point) (1- (mark)))))
+    (buffer-substring (point) (1- (mark t)))))
 
 
 (defun mh-next-msg ()
 
 
 (defun mh-next-msg ()
@@ -1364,7 +1446,7 @@ provided, then prompt for the message sequence."
 ;;; The folder data abstraction.
 
 (defvar mh-current-folder nil "Name of current folder, a string.")
 ;;; The folder data abstraction.
 
 (defvar mh-current-folder nil "Name of current folder, a string.")
-(defvar mh-show-buffer nil "Buffer that displays mesage for this folder.")
+(defvar mh-show-buffer nil "Buffer that displays message for this folder.")
 (defvar mh-folder-filename nil "Full path of directory for this folder.")
 (defvar mh-showing nil "If non-nil, show the message in a separate window.")
 (defvar mh-next-seq-num nil "Index of free sequence id.")
 (defvar mh-folder-filename nil "Full path of directory for this folder.")
 (defvar mh-showing nil "If non-nil, show the message in a separate window.")
 (defvar mh-next-seq-num nil "Index of free sequence id.")
@@ -1434,9 +1516,9 @@ Variables controlling mh-e operation are (defaults in parentheses):
     a messages is toggled off.
 
  mh-summary-height (4)
     a messages is toggled off.
 
  mh-summary-height (4)
-    Number of lines in the summary window.
+    Number of lines in the summary window including the mode line.
 
 
- mh-ins-buf-prefix (\">> \")
+ mh-ins-buf-prefix (\"> \")
     String to insert before each non-blank line of a message as it is
     inserted in a draft letter.
 
     String to insert before each non-blank line of a message as it is
     inserted in a draft letter.
 
@@ -1462,6 +1544,7 @@ The value of mh-folder-mode-hook is called when a new folder is set up."
    'mh-first-msg-num nil               ; Number of first msg in buffer
    'mh-last-msg-num nil                        ; Number of last msg in buffer
    'mh-previous-window-config nil)     ; Previous window configuration
    'mh-first-msg-num nil               ; Number of first msg in buffer
    'mh-last-msg-num nil                        ; Number of last msg in buffer
    'mh-previous-window-config nil)     ; Previous window configuration
+  (setq truncate-lines t)
   (auto-save-mode -1)
   (setq buffer-offer-save t)
   (make-local-variable 'write-file-hooks)
   (auto-save-mode -1)
   (setq buffer-offer-save t)
   (make-local-variable 'write-file-hooks)
@@ -1694,7 +1777,7 @@ The value of mh-folder-mode-hook is called when a new folder is set up."
   (save-excursion
     (mh-first-msg)
     (while (and msgs (< (point) (point-max)))
   (save-excursion
     (mh-first-msg)
     (while (and msgs (< (point) (point-max)))
-      (cond ((= (mh-get-msg-num nil) (car msgs))
+      (cond ((equal (mh-get-msg-num nil) (car msgs))
             (delete-region (point) (save-excursion (forward-line) (point)))
             (setq msgs (cdr msgs)))
            (t
             (delete-region (point) (save-excursion (forward-line) (point)))
             (setq msgs (cdr msgs)))
            (t
@@ -1745,6 +1828,9 @@ Variables controlling this mode (defaults in parentheses):
     If nil, only the portion of the message following the point will be yanked.
     If there is a region, this variable is ignored.
 
     If nil, only the portion of the message following the point will be yanked.
     If there is a region, this variable is ignored.
 
+ mh-signature-file-name (\"~/.signature\")
+    File to be inserted into message by \\[mh-insert-signature].
+
 Upon invoking mh-letter-mode, text-mode-hook and mh-letter-mode-hook are
 invoked with no args, if those values are non-nil.
 
 Upon invoking mh-letter-mode, text-mode-hook and mh-letter-mode-hook are
 invoked with no args, if those values are non-nil.
 
@@ -1767,7 +1853,10 @@ invoked with no args, if those values are non-nil.
   (mh-set-mode-name "mh-e letter")
   (set-syntax-table mh-letter-mode-syntax-table)
   (run-hooks 'text-mode-hook 'mh-letter-mode-hook)
   (mh-set-mode-name "mh-e letter")
   (set-syntax-table mh-letter-mode-syntax-table)
   (run-hooks 'text-mode-hook 'mh-letter-mode-hook)
-  (mh-when auto-fill-function
+  (mh-when (and (boundp 'auto-fill-hook) auto-fill-hook) ;emacs 18
+    (make-local-variable 'auto-fill-hook)
+    (setq auto-fill-hook 'mh-auto-fill-for-letter))
+  (mh-when (and (boundp 'auto-fill-function) auto-fill-function) ;emacs 19
     (make-local-variable 'auto-fill-function)
     (setq auto-fill-function 'mh-auto-fill-for-letter)))
 
     (make-local-variable 'auto-fill-function)
     (setq auto-fill-function 'mh-auto-fill-for-letter)))
 
@@ -1795,7 +1884,7 @@ invoked with no args, if those values are non-nil.
   "Move point to the end of a specified header field.
 The field is indicated by the previous keystroke.  Create the field if
 it does not exist.  Set the mark to point before moving."
   "Move point to the end of a specified header field.
 The field is indicated by the previous keystroke.  Create the field if
 it does not exist.  Set the mark to point before moving."
-  (interactive "")
+  (interactive)
   (expand-abbrev)
   (let ((target (cdr (assoc (logior last-input-char ?`) mh-to-field-choices)))
        (case-fold-search t))
   (expand-abbrev)
   (let ((target (cdr (assoc (logior last-input-char ?`) mh-to-field-choices)))
        (case-fold-search t))
@@ -1803,9 +1892,10 @@ it does not exist.  Set the mark to point before moving."
           (let ((eol (point)))
             (skip-chars-backward " \t")
             (delete-region (point) eol))
           (let ((eol (point)))
             (skip-chars-backward " \t")
             (delete-region (point) eol))
-          (if (save-excursion
-                (backward-char 1)
-                (not (looking-at "[:,]")))
+          (if (and (not (eq (logior last-input-char ?`) ?s))
+                   (save-excursion
+                     (backward-char 1)
+                     (not (looking-at "[:,]"))))
               (insert ", ")
               (insert " ")))
          (t
               (insert ", ")
               (insert " ")))
          (t
@@ -1830,8 +1920,8 @@ Prompt for the field name with a completion list of the current folders."
 
 
 (defun mh-insert-signature ()
 
 
 (defun mh-insert-signature ()
-  "Insert the file ~/.signature at the current point."
-  (interactive "")
+  "Insert the file named by mh-signature-file-name at the current point."
+  (interactive)
   (insert-file-contents mh-signature-file-name)
   (set-buffer-modified-p (buffer-modified-p))) ; force mode line update
 
   (insert-file-contents mh-signature-file-name)
   (set-buffer-modified-p (buffer-modified-p))) ; force mode line update
 
@@ -1881,7 +1971,7 @@ Put messages found in a sequence named `search'."
   (interactive)
   (let ((pattern-buffer (buffer-name))
        (searching-buffer mh-searching-folder)
   (interactive)
   (let ((pattern-buffer (buffer-name))
        (searching-buffer mh-searching-folder)
-       (range)
+       range msgs
        (pattern nil)
        (new-buffer nil))
     (save-excursion
        (pattern nil)
        (new-buffer nil))
     (save-excursion
@@ -1995,7 +2085,7 @@ Run mh-before-send-letter-hook before doing anything."
                                   "-nodraftfolder" mh-send-args file-name)
               (mh-exec-cmd-output "send" t "-watch" "-nopush"
                                   "-nodraftfolder" file-name))
                                   "-nodraftfolder" mh-send-args file-name)
               (mh-exec-cmd-output "send" t "-watch" "-nopush"
                                   "-nodraftfolder" file-name))
-          (goto-char (point-max))
+          (goto-char (point-max))      ; show the interesting part
           (recenter -1)
           (set-buffer draft-buffer))   ; for annotation below
          (mh-send-args
           (recenter -1)
           (set-buffer draft-buffer))   ; for annotation below
          (mh-send-args
@@ -2065,8 +2155,9 @@ yanked message will be deleted."
        (if mh-delete-yanked-msg-window
            (delete-windows-on mh-show-buffer))
        (set-buffer mh-show-buffer)     ; Find displayed message
        (if mh-delete-yanked-msg-window
            (delete-windows-on mh-show-buffer))
        (set-buffer mh-show-buffer)     ; Find displayed message
-       (let ((mh-ins-str (cond ((mark)
-                                (buffer-substring (point) (mark)))
+       (let ((mh-ins-str (cond (mark-active
+                                (buffer-substring (region-beginning)
+                                                  (region-end)))
                                ((eq 'body mh-yank-from-start-of-msg)
                                 (buffer-substring
                                  (save-excursion
                                ((eq 'body mh-yank-from-start-of-msg)
                                 (buffer-substring
                                  (save-excursion
@@ -2100,7 +2191,7 @@ yanked message will be deleted."
 (defun mh-fully-kill-draft ()
   "Kill the draft message file and the draft message buffer.
 Use \\[kill-buffer] if you don't want to delete the draft message file."
 (defun mh-fully-kill-draft ()
   "Kill the draft message file and the draft message buffer.
 Use \\[kill-buffer] if you don't want to delete the draft message file."
-  (interactive "")
+  (interactive)
   (if (y-or-n-p "Kill draft message? ")
       (let ((config mh-previous-window-config))
        (if (file-exists-p (buffer-file-name))
   (if (y-or-n-p "Kill draft message? ")
       (let ((config mh-previous-window-config))
        (if (file-exists-p (buffer-file-name))
@@ -2196,7 +2287,8 @@ Use \\[kill-buffer] if you don't want to delete the draft message file."
     (save-excursion
       (mh-exec-cmd-quiet " *mh-temp*" "mark" folder "-list")
       (goto-char (point-min))
     (save-excursion
       (mh-exec-cmd-quiet " *mh-temp*" "mark" folder "-list")
       (goto-char (point-min))
-      (while (re-search-forward "^[^:]+" nil t)
+      ;; look for name in line of form "cur: 4" or "myseq (private): 23"
+      (while (re-search-forward "^[^: ]+" nil t)
        (mh-push (mh-make-seq (intern (buffer-substring (match-beginning 0)
                                                        (match-end 0)))
                              (mh-read-msg-list))
        (mh-push (mh-make-seq (intern (buffer-substring (match-beginning 0)
                                                        (match-end 0)))
                              (mh-read-msg-list))
@@ -2322,7 +2414,7 @@ Use \\[kill-buffer] if you don't want to delete the draft message file."
 
 (defun mh-folder-name-p (name)
   ;; Return non-NIL if NAME is possibly the name of a folder.
 
 (defun mh-folder-name-p (name)
   ;; Return non-NIL if NAME is possibly the name of a folder.
-  ;; A name can be a folder name if it begins with "+".
+  ;; A name (a string or symbol) can be a folder name if it begins with "+".
   (if (symbolp name)
       (eql (aref (symbol-name name) 0) ?+)
       (eql (aref name 0) ?+)))
   (if (symbolp name)
       (eql (aref (symbol-name name) 0) ?+)
       (eql (aref name 0) ?+)))
@@ -2456,10 +2548,11 @@ Use \\[kill-buffer] if you don't want to delete the draft message file."
   (save-excursion
     (set-buffer (get-buffer-create " *mh-temp*"))
     (erase-buffer))
   (save-excursion
     (set-buffer (get-buffer-create " *mh-temp*"))
     (erase-buffer))
-  (let ((process (apply 'start-process
-                       command nil
-                       (expand-file-name command mh-progs)
-                       (mh-list-to-string args))))
+  (let* ((process-connection-type nil)
+        (process (apply 'start-process
+                        command nil
+                        (expand-file-name command mh-progs)
+                        (mh-list-to-string args))))
     (set-process-filter process 'mh-process-daemon)))
 
 
     (set-process-filter process 'mh-process-daemon)))
 
 
@@ -2529,16 +2622,16 @@ Use \\[kill-buffer] if you don't want to delete the draft message file."
 ;;; User prompting commands.
 
 (defun mh-prompt-for-folder (prompt default can-create)
 ;;; User prompting commands.
 
 (defun mh-prompt-for-folder (prompt default can-create)
-  ;; Prompt for a folder name with PROMPT.  Returns the folder's name.
-  ;; DEFAULT is used if the folder exists and the user types return.
-  ;; If the CAN-CREATE flag is t, then a non-existant folder is made.
+  ;; Prompt for a folder name with PROMPT.  Returns the folder's name as a
+  ;; string.  DEFAULT is used if the folder exists and the user types return.
+  ;; If the CAN-CREATE flag is t, then a non-existent folder is made.
   (let* ((prompt (format "%s folder%s" prompt
                         (if (equal "" default)
                             "? "
                             (format " [%s]? " default))))
         name)
     (if (null mh-folder-list)
   (let* ((prompt (format "%s folder%s" prompt
                         (if (equal "" default)
                             "? "
                             (format " [%s]? " default))))
         name)
     (if (null mh-folder-list)
-       (setq mh-folder-list (mh-make-folder-list)))
+       (mh-set-folder-list))
     (while (and (setq name (completing-read prompt mh-folder-list
                                            nil nil "+"))
                (equal name "")
     (while (and (setq name (completing-read prompt mh-folder-list
                                            nil nil "+"))
                (equal name "")
@@ -2554,17 +2647,21 @@ Use \\[kill-buffer] if you don't want to delete the draft message file."
             (message "Creating %s" name)
             (call-process "mkdir" nil nil nil (mh-expand-file-name name))
             (message "Creating %s...done" name)
             (message "Creating %s" name)
             (call-process "mkdir" nil nil nil (mh-expand-file-name name))
             (message "Creating %s...done" name)
-            (mh-push (list name) mh-folder-list)
-            (mh-push (list (substring name 1 nil)) mh-folder-list))
+            (mh-push (list name) mh-folder-list))
            (new-file-p
             (error "Folder %s is not created" name))
            (t
             (mh-when (null (assoc name mh-folder-list))
            (new-file-p
             (error "Folder %s is not created" name))
            (t
             (mh-when (null (assoc name mh-folder-list))
-              (mh-push (list name) mh-folder-list)
-              (mh-push (list (substring name 1 nil)) mh-folder-list)))))
+              (mh-push (list name) mh-folder-list)))))
     name))
 
 
     name))
 
 
+(defun mh-set-folder-list ()
+  "Sets mh-folder-list correctly.
+A useful function for the command line or for when you need to sync by hand."
+  (setq mh-folder-list (mh-make-folder-list)))
+
+
 (defun mh-make-folder-list ()
   "Return a list of the user's folders.
 Result is in a form suitable for completing read."
 (defun mh-make-folder-list ()
   "Return a list of the user's folders.
 Result is in a form suitable for completing read."
@@ -2685,21 +2782,15 @@ Assumes that any filename that starts with '+' is a folder name."
   ;; Returns the empty string if the field is not in the message.
   (let ((case-fold-search t))
     (goto-char (point-min))
   ;; Returns the empty string if the field is not in the message.
   (let ((case-fold-search t))
     (goto-char (point-min))
-    (cond ((not (search-forward field nil t)) "")
+    (cond ((not (re-search-forward (format "^%s" field) nil t)) "")
          ((looking-at "[\t ]*$") "")
          (t
           (re-search-forward "[\t ]*\\([^\t \n].*\\)$" nil t)
          ((looking-at "[\t ]*$") "")
          (t
           (re-search-forward "[\t ]*\\([^\t \n].*\\)$" nil t)
-          (let ((field (buffer-substring (match-beginning 1)
-                                         (match-end 1)))
-                (end-of-match (point)))
-            (forward-line)
-            (while (looking-at "[ \t]") (forward-line 1))
-            (backward-char 1)
-            (if (<= (point) end-of-match)
-                field
-                (format "%s%s"
-                        field
-                        (buffer-substring end-of-match (point)))))))))
+          (let ((start (match-beginning 1)))
+            (forward-line 1)
+            (while (looking-at "[ \t]")
+              (forward-line 1))
+            (buffer-substring start (1- (point))))))))
 
 
 (defun mh-insert-fields (&rest name-values)
 
 
 (defun mh-insert-fields (&rest name-values)
@@ -2723,6 +2814,7 @@ Assumes that any filename that starts with '+' is a folder name."
 (defun mh-position-on-field (field set-mark)
   ;; Set point to the end of the line beginning with FIELD.
   ;; Set the mark to the old value of point, if SET-MARK is non-nil.
 (defun mh-position-on-field (field set-mark)
   ;; Set point to the end of the line beginning with FIELD.
   ;; Set the mark to the old value of point, if SET-MARK is non-nil.
+  ;; Returns non-nil iff the field was found.
   (let ((case-fold-search t))
     (if set-mark (push-mark))
     (goto-char (point-min))
   (let ((case-fold-search t))
     (if set-mark (push-mark))
     (goto-char (point-min))
@@ -2760,6 +2852,7 @@ Assumes that any filename that starts with '+' is a folder name."
 (define-key mh-folder-mode-map "\ef" 'mh-visit-folder)
 (define-key mh-folder-mode-map "\ek" 'mh-kill-folder)
 (define-key mh-folder-mode-map "\el" 'mh-list-folders)
 (define-key mh-folder-mode-map "\ef" 'mh-visit-folder)
 (define-key mh-folder-mode-map "\ek" 'mh-kill-folder)
 (define-key mh-folder-mode-map "\el" 'mh-list-folders)
+(define-key mh-folder-mode-map "\en" 'mh-unshar-msg)
 (define-key mh-folder-mode-map "\eo" 'mh-write-msg-to-file)
 (define-key mh-folder-mode-map "\ep" 'mh-pack-folder)
 (define-key mh-folder-mode-map "\es" 'mh-search-folder)
 (define-key mh-folder-mode-map "\eo" 'mh-write-msg-to-file)
 (define-key mh-folder-mode-map "\ep" 'mh-pack-folder)
 (define-key mh-folder-mode-map "\es" 'mh-search-folder)
@@ -2777,6 +2870,7 @@ Assumes that any filename that starts with '+' is a folder name."
 (define-key mh-folder-mode-map "m" 'mh-send)
 (define-key mh-folder-mode-map "a" 'mh-reply)
 (define-key mh-folder-mode-map "j" 'mh-goto-msg)
 (define-key mh-folder-mode-map "m" 'mh-send)
 (define-key mh-folder-mode-map "a" 'mh-reply)
 (define-key mh-folder-mode-map "j" 'mh-goto-msg)
+(define-key mh-folder-mode-map "<" 'mh-first-msg)
 (define-key mh-folder-mode-map "g" 'mh-goto-msg)
 (define-key mh-folder-mode-map "\177" 'mh-previous-page)
 (define-key mh-folder-mode-map " " 'mh-page-msg)
 (define-key mh-folder-mode-map "g" 'mh-goto-msg)
 (define-key mh-folder-mode-map "\177" 'mh-previous-page)
 (define-key mh-folder-mode-map " " 'mh-page-msg)
@@ -2830,8 +2924,8 @@ Assumes that any filename that starts with '+' is a folder name."
 
 ;;; For Gnu Emacs.
 ;;; Local Variables: ***
 
 ;;; For Gnu Emacs.
 ;;; Local Variables: ***
-;;; eval: (put 'mh-when 'lisp-indent-function 1) ***
-;;; eval: (put 'with-mh-folder-updating 'lisp-indent-function 1) ***
+;;; eval: (put 'mh-when 'lisp-indent-hook 1) ***
+;;; eval: (put 'with-mh-folder-updating 'lisp-indent-hook 1) ***
 ;;; End: ***
 
 (provide 'mh-e)
 ;;; End: ***
 
 (provide 'mh-e)