Annotation of GNUtools/emacs/lisp/mh-e.el, revision 1.1

1.1     ! root        1: ;;;  mh-e.el   (Version: 3.8 for GNU Emacs Version 18 and MH.5 and MH.6)
        !             2: 
        !             3: (defvar mh-e-RCS-id)
        !             4: (setq mh-e-RCS-id "$Header: mh-e.el,v 3.5 92/01/21 11:21:59 gildea Exp $")
        !             5: (setq mh-e-time-stamp "92/01/21 10:59:18 gildea")
        !             6: (provide 'mh-e)
        !             7: 
        !             8: ;;; Copyright (c) 1985,1986,1987,1988,1990,1992 Free Software Foundation
        !             9: ;;;     Maintainer:  Stephen Gildea <[email protected]>
        !            10: ;;;    Please send suggestions and corrections to the above address.
        !            11: ;;;
        !            12: ;;;  This file contains mh-e, a GNU Emacs front end to the MH mail system.
        !            13: 
        !            14: ;; This file is part of GNU Emacs.
        !            15: 
        !            16: ;; GNU Emacs is free software; you can redistribute it and/or modify
        !            17: ;; it under the terms of the GNU General Public License as published by
        !            18: ;; the Free Software Foundation; either version 1, or (at your option)
        !            19: ;; any later version.
        !            20: 
        !            21: ;; GNU Emacs is distributed in the hope that it will be useful,
        !            22: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            23: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            24: ;; GNU General Public License for more details.
        !            25: 
        !            26: ;; You should have received a copy of the GNU General Public License
        !            27: ;; along with GNU Emacs; see the file COPYING.  If not, write to
        !            28: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
        !            29: 
        !            30: 
        !            31: ;;;  Original version for Gosling emacs by Brian Reid, Stanford, 1982.
        !            32: ;;;  Modified by James Larus, BBN, July 1984 and UCB, 1984 & 1985.
        !            33: ;;;  Rewritten for GNU Emacs, James Larus 1985.  [email protected]
        !            34: ;;;  Modified by Stephen Gildea, BBN, 1988, and MIT, 1990.  [email protected]
        !            35: 
        !            36: 
        !            37: ;;;  NB.  MH must have been compiled with the MHE compiler flag or several
        !            38: ;;;  features necessary mh-e will be missing from MH commands, specifically
        !            39: ;;;  the -build switch to repl and forw.
        !            40: 
        !            41: ;;;  HOW TO USE:
        !            42: ;;;  M-x mh-rmail to read mail.  Type C-h m there for a list of commands.
        !            43: ;;;  C-u M-x mh-rmail to visit any folder.
        !            44: ;;;  M-x mh-smail to send mail.  From within the mail reader, "m" works, too.
        !            45: ;;;  Your .emacs might benefit from these bindings:
        !            46: ;;;  (global-set-key "\C-xm" 'mh-smail)
        !            47: ;;;  (global-set-key "\C-x4m" 'mh-smail-other-window)
        !            48: ;;;  (global-set-key "\C-xr" 'mh-rmail)        ;clobbers copy-rectangle-to-register
        !            49: 
        !            50: 
        !            51: 
        !            52: ;;; Constants:
        !            53: 
        !            54: ;;; Set for local environment:
        !            55: ;;;* These are now in paths.el.
        !            56: ;;;(defvar mh-progs "/usr/new/mh/" "Directory containing MH commands.")
        !            57: ;;;(defvar mh-lib "/usr/new/lib/mh/" "Directory of MH library.")
        !            58: 
        !            59: (defvar mh-redist-full-contents nil
        !            60:   "Non-nil if the `dist' command needs whole letter for redistribution.
        !            61: This is the case when `send' is compiled with the BERK option.")
        !            62: 
        !            63: 
        !            64: ;;; Hooks:
        !            65: 
        !            66: (defvar mh-folder-mode-hook nil
        !            67:   "Invoked in `mh-folder mode' on a new folder.")
        !            68: 
        !            69: (defvar mh-letter-mode-hook nil
        !            70:   "Invoked in `mh-letter-mode' on a new letter.")
        !            71: 
        !            72: (defvar mh-compose-letter-function nil
        !            73:   "Invoked in `mh-compose-and-send-mail' on a draft letter.
        !            74: It is passed three arguments: TO recipients, SUBJECT, and CC recipients.")
        !            75: 
        !            76: (defvar mh-before-send-letter-hook nil
        !            77:   "Invoked at the beginning of the \\[mh-send-letter] command.")
        !            78: 
        !            79: (defvar mh-inc-folder-hook nil
        !            80:   "Invoked after incorporating mail into a folder with \\[mh-inc-folder].")
        !            81: 
        !            82: (defvar mh-before-quit-hook nil
        !            83:   "Invoked by \\[mh-quit] before quitting mh-e.  See also  mh-quit-hook")
        !            84: 
        !            85: (defvar mh-quit-hook nil
        !            86:   "Invoked after quitting mh-e by \\[mh-quit].  See also  mh-before-quit-hook")
        !            87: 
        !            88: 
        !            89: (defvar mh-ins-string nil
        !            90:   "Temporarily set by `mh-insert-prefix' prior to running `mh-yank-hooks'.")
        !            91: 
        !            92: (defvar mh-yank-hooks
        !            93:   '(lambda ()
        !            94:     (save-excursion
        !            95:       (goto-char (point))
        !            96:       (or (bolp) (forward-line 1))
        !            97:       (while (< (point) (mark))
        !            98:        (insert mh-ins-string)
        !            99:        (forward-line 1))))
        !           100:   "Hook to run citation function.
        !           101: Expects POINT and MARK to be set to the region to cite.")
        !           102: 
        !           103: 
        !           104: ;;; Personal preferences:
        !           105: 
        !           106: (defvar mh-clean-message-header nil
        !           107:   "*Non-nil means clean headers of messages that are displayed or inserted.
        !           108: The variables `mh-visible-headers' and `mh-invisible-headers' control what
        !           109: is removed.")
        !           110: 
        !           111: (defvar mh-visible-headers nil
        !           112:   "*If non-nil, contains a regexp specifying the headers to keep when cleaning.
        !           113: Only used if `mh-clean-message-header' is non-nil.  Setting this variable
        !           114: overrides `mh-invisible-headers'.")
        !           115: 
        !           116: (defvar mhl-formfile nil
        !           117:   "*Name of format file to be used by mhl to show messages.
        !           118: A value of T means use the default format file.
        !           119: Nil means don't use mhl to format messages.")
        !           120: 
        !           121: (defvar mh-lpr-command-format "lpr -p -J '%s'"
        !           122:   "*Format for Unix command that prints a message.
        !           123: The string should be a Unix command line, with the string '%s' where
        !           124: the job's name (folder and message number) should appear.  The message text
        !           125: is piped to this command.")
        !           126: 
        !           127: (defvar mh-print-background nil
        !           128:   "*Print messages in the background if non-nil.
        !           129: WARNING: do not delete the messages until printing is finished;
        !           130: otherwise, your output may be truncated.")
        !           131: 
        !           132: (defvar mh-summary-height 4
        !           133:   "*Number of lines in summary window (including the mode line).")
        !           134: 
        !           135: (defvar mh-recenter-summary-p nil
        !           136:   "*Recenter summary window when the show window is toggled off if non-nil.")
        !           137: 
        !           138: (defvar mh-ins-buf-prefix "> "
        !           139:   "*String to put before each non-blank line of a yanked or inserted message.
        !           140: Used when the message is inserted in an outgoing letter.")
        !           141: 
        !           142: (defvar mh-do-not-confirm nil
        !           143:   "*Non-nil means do not prompt for confirmation before some commands.
        !           144: Only affects certain innocuous commands.")
        !           145: 
        !           146: (defvar mh-bury-show-buffer t
        !           147:   "*Non-nil means that the displayed show buffer for a folder is buried.")
        !           148: 
        !           149: (defvar mh-delete-yanked-msg-window nil
        !           150:   "*Controls window display when a message is yanked by \\[mh-yank-cur-msg].
        !           151: If non-nil, yanking the current message into a draft letter deletes any
        !           152: windows displaying the message.")
        !           153: 
        !           154: (defvar mh-yank-from-start-of-msg t
        !           155:   "*Controls which part of a message is yanked by \\[mh-yank-cur-msg].
        !           156: If non-nil, include the entire message.  If the symbol `body', then yank the
        !           157: message minus the header.  If nil, yank only the portion of the message
        !           158: following the point.  If the show buffer has a region, this variable is
        !           159: ignored.")
        !           160: 
        !           161: (defvar mh-reply-default-reply-to nil
        !           162:   "*Sets the person or persons to whom a reply will be sent.
        !           163: If nil, prompt for recipient. If non-nil, then \\[mh-reply] will use this
        !           164: value and it should be one of \"from\", \"to\", or \"cc\".")
        !           165: 
        !           166: (defvar mh-recursive-folders nil
        !           167:   "*If non-nil, then commands which operate on folders do so recursively.")
        !           168: 
        !           169: (defvar mh-unshar-default-directory ""
        !           170:   "*Default for directory name prompted for by mh-unshar-msg.")
        !           171: 
        !           172: 
        !           173: ;;; Parameterize mh-e to work with different scan formats.  The defaults work
        !           174: ;;; with the standard MH scan listings.
        !           175: 
        !           176: (defvar mh-cmd-note 4
        !           177:   "Offset to insert notation.")
        !           178: 
        !           179: (defvar mh-note-repl "-"
        !           180:   "String whose first character is used to notate replied to messages.")
        !           181: 
        !           182: (defvar mh-note-forw "F"
        !           183:   "String whose first character is used to notate forwarded messages.")
        !           184: 
        !           185: (defvar mh-note-dist "R"
        !           186:   "String whose first character is used to notate redistributed messages.")
        !           187: 
        !           188: (defvar mh-good-msg-regexp  "^....[^D^]"
        !           189:   "Regexp specifiying the scan lines that are 'good' messages.")
        !           190: 
        !           191: (defvar mh-deleted-msg-regexp "^....D"
        !           192:   "Regexp matching scan lines of deleted messages.")
        !           193: 
        !           194: (defvar mh-refiled-msg-regexp  "^....\\^"
        !           195:   "Regexp matching scan lines of refiled messages.")
        !           196: 
        !           197: (defvar mh-valid-scan-line "^ *[0-9]"
        !           198:   "Regexp matching scan lines for messages (not error messages).")
        !           199: 
        !           200: (defvar mh-msg-number-regexp "^ *\\([0-9]+\\)"
        !           201:   "Regexp to find the number of a message in a scan line.
        !           202: The message's number must be surrounded with \\( \\)")
        !           203: 
        !           204: (defvar mh-msg-search-regexp "^[^0-9]*%d[^0-9]"
        !           205:   "Format string containing a regexp matching the scan listing for a message.
        !           206: The desired message's number will be an argument to format.")
        !           207: 
        !           208: (defvar mh-flagged-scan-msg-regexp "^....\\D\\|^....\\^\\|^....\\+\\|^.....%"
        !           209:   "Regexp matching flagged scan lines.
        !           210: Matches lines marked as deleted, refiled, in a sequence, or the cur message.")
        !           211: 
        !           212: (defvar mh-cur-scan-msg-regexp "^....\\+"
        !           213:   "Regexp matching scan line for the cur message.")
        !           214: 
        !           215: (defvar mh-show-buffer-mode-line-buffer-id "{%%b}  %s/%d"
        !           216:   "Format string to produce `mode-line-buffer-id' for show buffers.
        !           217: First argument is folder name.  Second is message number.")
        !           218: 
        !           219: (defvar mh-partial-folder-mode-line-annotation "select"
        !           220:   "Annotation when displaying part of a folder.
        !           221: The string is displayed after the folder's name.  NIL for no annotation.")
        !           222: 
        !           223: 
        !           224: ;;; Real constants:
        !           225: 
        !           226: (defvar mh-invisible-headers
        !           227:   "^Received: \\|^Message-Id: \\|^Remailed-\\|^Via: \\|^Mail-from: \\|^Return-Path: \\|^In-Reply-To: \\|^Resent-"
        !           228:   "Regexp matching lines in a message header that are not to be shown.
        !           229: If `mh-visible-headers' is non-nil, it is used instead to specify what
        !           230: to keep.")
        !           231: 
        !           232: (defvar mh-rejected-letter-start
        !           233:   (concat "^   ----- Unsent message follows -----$" ;from mail system
        !           234:          "\\|^------- Unsent Draft$"   ;from MH itself
        !           235:          "\\|^  --- The unsent message follows ---$") ;from AIX mail system
        !           236:   "Regexp specifying the beginning of the wrapper around a returned letter.
        !           237: This wrapper is generated by the mail system when rejecting a letter.")
        !           238: 
        !           239: (defvar mh-to-field-choices '((?t . "To:") (?s . "Subject:") (?c . "Cc:")
        !           240:                              (?b . "Bcc:") (?f . "Fcc:"))
        !           241:   "A-list of (character . field name) strings for mh-to-field.")
        !           242: 
        !           243: 
        !           244: ;;; Global variables:
        !           245: 
        !           246: (defvar mh-user-path  ""
        !           247:   "User's mail folder.")
        !           248: 
        !           249: (defvar mh-last-destination nil
        !           250:   "Destination of last refile or write command.")
        !           251: 
        !           252: (defvar mh-folder-mode-map (make-keymap)
        !           253:   "Keymap for MH folders.")
        !           254: 
        !           255: (defvar mh-letter-mode-map (copy-keymap text-mode-map)
        !           256:   "Keymap for composing mail.")
        !           257: 
        !           258: (defvar mh-pick-mode-map (make-sparse-keymap)
        !           259:   "Keymap for searching folder.")
        !           260: 
        !           261: (defvar mh-letter-mode-syntax-table nil
        !           262:   "Syntax table used while in mh-e letter mode.")
        !           263: 
        !           264: (if mh-letter-mode-syntax-table
        !           265:     ()
        !           266:     (setq mh-letter-mode-syntax-table
        !           267:          (make-syntax-table text-mode-syntax-table))
        !           268:     (set-syntax-table mh-letter-mode-syntax-table)
        !           269:     (modify-syntax-entry ?% "." mh-letter-mode-syntax-table))
        !           270: 
        !           271: (defvar mh-folder-list nil
        !           272:   "List of folder names for completion.")
        !           273: 
        !           274: (defvar mh-draft-folder nil
        !           275:   "Name of folder containing draft messages.
        !           276: NIL means do not use draft folder.")
        !           277: 
        !           278: (defvar mh-unseen-seq nil
        !           279:   "Name of the unseen sequence.")
        !           280: 
        !           281: (defvar mh-previous-window-config nil
        !           282:   "Window configuration before mh-e command.")
        !           283: 
        !           284: (defvar mh-previous-seq nil
        !           285:   "Name of the sequence to which a message was last added.")
        !           286: 
        !           287: 
        !           288: ;;; Macros and generic functions:
        !           289: 
        !           290: (defmacro mh-push (v l)
        !           291:   (list 'setq l (list 'cons v l)))
        !           292: 
        !           293: 
        !           294: (defmacro mh-when (pred &rest body)
        !           295:   (list 'cond (cons pred body)))
        !           296: 
        !           297: 
        !           298: (defmacro with-mh-folder-updating (save-modification-flag-p &rest body)
        !           299:   ;; Format is (with-mh-folder-updating (SAVE-MODIFICATION-FLAG-P) &body BODY).
        !           300:   ;; Execute BODY, which can modify the folder buffer without having to
        !           301:   ;; worry about file locking or the read-only flag, and return its result.
        !           302:   ;; If SAVE-MODIFICATION-FLAG-P is non-nil, the buffer's modification
        !           303:   ;; flag is unchanged, otherwise it is cleared.
        !           304:   (setq save-modification-flag-p (car save-modification-flag-p)) ; CL style
        !           305:   (` (let ((folder-updating-mod-flag (buffer-modified-p)))
        !           306:        (prog1
        !           307:           (let ((buffer-read-only nil)
        !           308:                 (buffer-file-name nil)) ; don't let the buffer get locked
        !           309:             (,@ body))
        !           310:         (, (if save-modification-flag-p
        !           311:                '(mh-set-folder-modified-p folder-updating-mod-flag)
        !           312:              '(mh-set-folder-modified-p nil)))))))
        !           313: 
        !           314: 
        !           315: (defun mh-mapc (func list)
        !           316:   (while list
        !           317:     (funcall func (car list))
        !           318:     (setq list (cdr list))))
        !           319: 
        !           320: 
        !           321: 
        !           322: ;;; Entry points:
        !           323: 
        !           324: ;;;###autoload
        !           325: (defun mh-rmail (&optional arg)
        !           326:   "Inc(orporate) new mail (no arg) or scan a MH mail box (arg given).
        !           327: This front end uses the MH mail system, which uses different conventions
        !           328: from the usual mail system."
        !           329:   (interactive "P")
        !           330:   (mh-find-path)
        !           331:   (if arg
        !           332:       (call-interactively 'mh-visit-folder)
        !           333:       (mh-inc-folder)))
        !           334: 
        !           335: 
        !           336: ;;;###autoload
        !           337: (defun mh-smail ()
        !           338:   "Compose and send mail with the MH mail system."
        !           339:   (interactive)
        !           340:   (mh-find-path)
        !           341:   (call-interactively 'mh-send))
        !           342: 
        !           343: 
        !           344: (defun mh-smail-other-window ()
        !           345:   "Compose and send mail in other window with the MH mail system."
        !           346:   (interactive)
        !           347:   (mh-find-path)
        !           348:   (call-interactively 'mh-send-other-window))
        !           349: 
        !           350: 
        !           351: 
        !           352: ;;; User executable mh-e commands:
        !           353: 
        !           354: (defun mh-burst-digest ()
        !           355:   "Burst apart the current message, which should be a digest.
        !           356: The message is replaced by its table of contents and the letters from the
        !           357: digest are inserted into the folder after that message."
        !           358:   (interactive)
        !           359:   (let ((digest (mh-get-msg-num t)))
        !           360:     (mh-process-or-undo-commands mh-current-folder)
        !           361:     (mh-set-folder-modified-p t)               ; lock folder while bursting
        !           362:     (message "Bursting digest...")
        !           363:     (mh-exec-cmd "burst" mh-current-folder digest "-inplace")
        !           364:     (mh-scan-folder mh-current-folder (format "%d-last" mh-first-msg-num))
        !           365:     (message "Bursting digest...done")))
        !           366: 
        !           367: 
        !           368: (defun mh-copy-msg (prefix-provided msg-or-seq dest)
        !           369:   "Copy specified MESSAGE(s) to another FOLDER without deleting them.
        !           370: Default is the displayed message.  If optional prefix argument is
        !           371: provided, then prompt for the message sequence."
        !           372:   (interactive (list current-prefix-arg
        !           373:                     (if current-prefix-arg
        !           374:                         (mh-read-seq-default "Copy" t)
        !           375:                         (mh-get-msg-num t))
        !           376:                     (mh-prompt-for-folder "Copy to" "" t)))
        !           377:   (mh-exec-cmd "refile" msg-or-seq "-link" "-src" mh-current-folder dest)
        !           378:   (if prefix-provided
        !           379:       (mh-notate-seq msg-or-seq ?C mh-cmd-note)
        !           380:       (mh-notate msg-or-seq ?C mh-cmd-note)))
        !           381: 
        !           382: 
        !           383: (defun mh-delete-msg (msg-or-seq)
        !           384:   "Mark the specified MESSAGE(s) for subsequent deletion and move to the next.
        !           385: Default is the displayed message.  If optional prefix argument is
        !           386: given then prompt for the message sequence."
        !           387:   (interactive (list (if current-prefix-arg
        !           388:                         (mh-read-seq-default "Delete" t)
        !           389:                         (mh-get-msg-num t))))
        !           390:   (if (numberp msg-or-seq)
        !           391:       (mh-delete-a-msg msg-or-seq)
        !           392:       (mh-map-to-seq-msgs 'mh-delete-a-msg msg-or-seq))
        !           393:   (mh-next-msg))
        !           394: 
        !           395: 
        !           396: (defun mh-delete-msg-no-motion (msg-or-seq)
        !           397:   "Mark the specified MESSAGE(s) for subsequent deletion.
        !           398: Default is the displayed message.  If optional prefix argument is
        !           399: provided, then prompt for the message sequence."
        !           400:   (interactive (list (if current-prefix-arg
        !           401:                         (mh-read-seq-default "Delete" t)
        !           402:                         (mh-get-msg-num t))))
        !           403:   (if (numberp msg-or-seq)
        !           404:       (mh-delete-a-msg msg-or-seq)
        !           405:       (mh-map-to-seq-msgs 'mh-delete-a-msg msg-or-seq)))
        !           406: 
        !           407: 
        !           408: (defun mh-delete-msg-from-seq (prefix-provided msg-or-seq &optional from-seq)
        !           409:   "Delete MESSAGE (default: displayed message) from SEQUENCE.
        !           410: If optional prefix argument provided, then delete all messages
        !           411: from a sequence."
        !           412:   (interactive (let ((argp current-prefix-arg))
        !           413:                 (list argp
        !           414:                       (if argp
        !           415:                           (mh-read-seq-default "Delete" t)
        !           416:                           (mh-get-msg-num t))
        !           417:                       (if (not argp)
        !           418:                           (mh-read-seq-default "Delete from" t)))))
        !           419:   (if prefix-provided
        !           420:       (mh-remove-seq msg-or-seq)
        !           421:       (mh-remove-msg-from-seq msg-or-seq from-seq)))
        !           422: 
        !           423: 
        !           424: (defun mh-edit-again (msg)
        !           425:   "Clean-up a draft or a message previously sent and make it resendable."
        !           426:   (interactive (list (mh-get-msg-num t)))
        !           427:   (let* ((from-folder mh-current-folder)
        !           428:         (config (current-window-configuration))
        !           429:         (draft
        !           430:          (cond ((and mh-draft-folder (equal from-folder mh-draft-folder))
        !           431:                 (pop-to-buffer (find-file-noselect (mh-msg-filename msg)) t)
        !           432:                 (rename-buffer (format "draft-%d" msg))
        !           433:                 (buffer-name))
        !           434:                (t
        !           435:                 (mh-read-draft "clean-up" (mh-msg-filename msg) nil)))))
        !           436:     (mh-clean-msg-header (point-min)
        !           437:                         "^Date:\\|^Received:\\|^Message-Id:\\|^From:\\|^Delivery-Date:"
        !           438:                         nil)
        !           439:     (goto-char (point-min))
        !           440:     (set-buffer-modified-p nil)
        !           441:     (mh-compose-and-send-mail draft "" from-folder nil nil nil nil nil nil
        !           442:                              config)))
        !           443: 
        !           444: 
        !           445: (defun mh-execute-commands ()
        !           446:   "Process outstanding delete and refile requests."
        !           447:   (interactive)
        !           448:   (if mh-narrowed-to-seq (mh-widen))
        !           449:   (mh-process-commands mh-current-folder)
        !           450:   (mh-set-scan-mode)
        !           451:   (mh-goto-cur-msg)                    ; after mh-set-scan-mode for efficiency
        !           452:   (mh-make-folder-mode-line)
        !           453:   t)                                   ; return t for write-file-hooks
        !           454: 
        !           455: 
        !           456: (defun mh-extract-rejected-mail (msg)
        !           457:   "Extract a letter returned by the mail system and make it resendable.
        !           458: Default is the displayed message."
        !           459:   (interactive (list (mh-get-msg-num t)))
        !           460:   (let ((from-folder mh-current-folder)
        !           461:        (config (current-window-configuration))
        !           462:        (draft (mh-read-draft "extraction" (mh-msg-filename msg) nil)))
        !           463:     (goto-char (point-min))
        !           464:     (cond ((re-search-forward mh-rejected-letter-start nil t)
        !           465:           (forward-char 1)
        !           466:           (delete-region (point-min) (point))
        !           467:           (mh-clean-msg-header (point-min)
        !           468:                                "^Date:\\|^Received:\\|^Message-Id:\\|^From:\\|^Sender:\\|^Return-Path:"
        !           469:                                nil))
        !           470:          (t
        !           471:           (message "Does not appear to be a rejected letter.")))
        !           472:     (goto-char (point-min))
        !           473:     (set-buffer-modified-p nil)
        !           474:     (mh-compose-and-send-mail draft "" from-folder msg (mh-get-field "To")
        !           475:                              (mh-get-field "From") (mh-get-field "cc")
        !           476:                              nil nil config)))
        !           477: 
        !           478: 
        !           479: (defun mh-first-msg ()
        !           480:   "Move to the first message."
        !           481:   (interactive)
        !           482:   (goto-char (point-min)))
        !           483: 
        !           484: 
        !           485: (defun mh-forward (prefix-provided msg-or-seq to cc)
        !           486:   "Forward MESSAGE(s) (default: displayed message).
        !           487: If optional prefix argument provided, then prompt for the message sequence."
        !           488:   (interactive (list current-prefix-arg
        !           489:                     (if current-prefix-arg
        !           490:                         (mh-read-seq-default "Forward" t)
        !           491:                         (mh-get-msg-num t))
        !           492:                     (read-string "To: ")
        !           493:                     (read-string "Cc: ")))
        !           494:   (let* ((folder mh-current-folder)
        !           495:         (config (current-window-configuration))
        !           496:         ;; forw always leaves file in "draft" since it doesn't have -draft
        !           497:         (draft-name (expand-file-name "draft" mh-user-path))
        !           498:         (draft (cond ((or (not (file-exists-p draft-name))
        !           499:                           (y-or-n-p "The file 'draft' exists.  Discard it? "))
        !           500:                       (mh-exec-cmd "forw"
        !           501:                                    "-build" mh-current-folder msg-or-seq)
        !           502:                       (prog1
        !           503:                           (mh-read-draft "" draft-name t)
        !           504:                         (mh-insert-fields "To:" to "Cc:" cc)
        !           505:                         (set-buffer-modified-p nil)))
        !           506:                      (t
        !           507:                       (mh-read-draft "" draft-name nil)))))
        !           508:     (goto-char (point-min))
        !           509:     (re-search-forward "^------- Forwarded Message")
        !           510:     (forward-line -1)
        !           511:     (narrow-to-region (point) (point-max))
        !           512:     (let* ((subject (save-excursion (mh-get-field "From:")))
        !           513:           (trim (string-match "<" subject))
        !           514:           (forw-subject (save-excursion (mh-get-field "Subject:"))))
        !           515:       (if trim
        !           516:          (setq subject (substring subject 0 (1- trim))))
        !           517:       (widen)
        !           518:       (save-excursion
        !           519:        (mh-insert-fields "Subject:" (format "[%s: %s]" subject forw-subject)))
        !           520:       (delete-other-windows)
        !           521:       (if prefix-provided
        !           522:          (mh-add-msgs-to-seq (mh-seq-to-msgs msg-or-seq) 'forwarded t)
        !           523:          (mh-add-msgs-to-seq msg-or-seq 'forwarded t))
        !           524:       (mh-compose-and-send-mail draft "" folder msg-or-seq
        !           525:                                to subject cc
        !           526:                                mh-note-forw "Forwarded:"
        !           527:                                config))))
        !           528: 
        !           529: 
        !           530: (defun mh-goto-msg (number &optional no-error-if-no-message dont-show)
        !           531:   "Position the cursor at message NUMBER.
        !           532: Non-nil second argument means do not signal an error if message does not exist.
        !           533: Non-nil third argument means not to show the message.
        !           534: Return non-nil if cursor is at message."
        !           535:   (interactive "NGoto message: ")
        !           536:   (let ((cur-msg (mh-get-msg-num nil))
        !           537:        (starting-place (point))
        !           538:        (msg-pattern (mh-msg-search-pat number)))
        !           539:     (cond ((cond ((and cur-msg (= cur-msg number)) t)
        !           540:                 ((and cur-msg
        !           541:                       (< cur-msg number)
        !           542:                       (re-search-forward msg-pattern nil t)) t)
        !           543:                 ((and cur-msg
        !           544:                       (> cur-msg number)
        !           545:                       (re-search-backward msg-pattern nil t)) t)
        !           546:                 (t                     ; Do thorough search of buffer
        !           547:                  (goto-char (point-max))
        !           548:                  (re-search-backward msg-pattern nil t)))
        !           549:            (beginning-of-line)
        !           550:            (if (not dont-show) (mh-maybe-show number))
        !           551:            t)
        !           552:          (t
        !           553:           (goto-char starting-place)
        !           554:           (if (not no-error-if-no-message)
        !           555:               (error "No message %d" number))
        !           556:           nil))))
        !           557: 
        !           558: 
        !           559: (defun mh-inc-folder (&optional maildrop-name)
        !           560:   "Inc(orporate) new mail into +inbox.
        !           561: Optional prefix argument specifies an alternate maildrop from the default.
        !           562: If this is given, incorporate mail into the current folder, rather
        !           563: than +inbox.  Run `mh-inc-folder-hook' after incorporating new mail."
        !           564:   (interactive (list (if current-prefix-arg
        !           565:                         (expand-file-name
        !           566:                          (read-file-name "inc mail from file: "
        !           567:                                          mh-user-path)))))
        !           568:   (let ((config (current-window-configuration)))
        !           569:     (if (not maildrop-name)
        !           570:        (cond ((not (get-buffer "+inbox"))
        !           571:               (mh-make-folder "+inbox")
        !           572:               (setq mh-previous-window-config config))
        !           573:              ((not (eq (current-buffer) (get-buffer "+inbox")))
        !           574:               (switch-to-buffer "+inbox")
        !           575:               (setq mh-previous-window-config config)))))
        !           576:   (mh-get-new-mail maildrop-name)
        !           577:   (run-hooks 'mh-inc-folder-hook))
        !           578: 
        !           579: 
        !           580: (defun mh-kill-folder ()
        !           581:   "Remove the current folder."
        !           582:   (interactive)
        !           583:   (if (or mh-do-not-confirm
        !           584:          (yes-or-no-p (format "Remove folder %s? " mh-current-folder)))
        !           585:       (let ((folder mh-current-folder))
        !           586:        (mh-set-folder-modified-p t)    ; lock folder to kill it
        !           587:        (mh-exec-cmd-daemon "rmf" folder)
        !           588:        (mh-remove-folder-from-folder-list folder)
        !           589:        (message "Folder %s removed" folder)
        !           590:        (mh-set-folder-modified-p nil)  ; so kill-buffer doesn't complain
        !           591:        (if (get-buffer mh-show-buffer)
        !           592:            (kill-buffer mh-show-buffer))
        !           593:        (kill-buffer folder))
        !           594:       (message "Folder not removed")))
        !           595: 
        !           596: 
        !           597: (defun mh-last-msg ()
        !           598:   "Move to the last message."
        !           599:   (interactive)
        !           600:   (goto-char (point-max))
        !           601:   (while (and (not (bobp)) (looking-at "^$"))
        !           602:     (forward-line -1)))
        !           603: 
        !           604: 
        !           605: (defun mh-list-folders ()
        !           606:   "List mail folders."
        !           607:   (interactive)
        !           608:   (with-output-to-temp-buffer " *mh-temp*"
        !           609:     (save-excursion
        !           610:       (switch-to-buffer " *mh-temp*")
        !           611:       (erase-buffer)
        !           612:       (message "Listing folders...")
        !           613:       (mh-exec-cmd-output "folders" t (if mh-recursive-folders
        !           614:                                          "-recurse"
        !           615:                                          "-norecurse"))
        !           616:       (goto-char (point-min))
        !           617:       (message "Listing folders...done"))))
        !           618: 
        !           619: 
        !           620: (defun mh-msg-is-in-seq (msg)
        !           621:   "Display the sequences that contain MESSAGE (default: displayed message)."
        !           622:   (interactive (list (mh-get-msg-num t)))
        !           623:   (message "Message %d is in sequences: %s"
        !           624:           msg
        !           625:           (mapconcat 'concat
        !           626:                      (mh-list-to-string (mh-seq-containing-msg msg))
        !           627:                      " ")))
        !           628: 
        !           629: 
        !           630: (defun mh-narrow-to-seq (seq)
        !           631:   "Restrict display of this folder to just messages in a sequence.
        !           632: Reads which sequence.  Use \\[mh-widen] to undo this command."
        !           633:   (interactive (list (mh-read-seq "Narrow to" t)))
        !           634:   (let ((eob (point-max)))
        !           635:     (with-mh-folder-updating (t)
        !           636:       (cond ((mh-seq-to-msgs seq)
        !           637:             (mh-copy-seq-to-point seq eob)
        !           638:             (narrow-to-region eob (point-max))
        !           639:             (mh-make-folder-mode-line (symbol-name seq))
        !           640:             (mh-recenter nil)
        !           641:             (setq mh-narrowed-to-seq seq))
        !           642:            (t
        !           643:             (error "No messages in sequence `%s'" (symbol-name seq)))))))
        !           644: 
        !           645: 
        !           646: (defun mh-next-undeleted-msg (&optional arg)
        !           647:   "Move to next undeleted message in window."
        !           648:   (interactive "P")
        !           649:   (forward-line (prefix-numeric-value arg))
        !           650:   (setq mh-next-direction 'forward)
        !           651:   (cond ((re-search-forward mh-good-msg-regexp nil 0 arg)
        !           652:         (beginning-of-line)
        !           653:         (mh-maybe-show))
        !           654:        (t
        !           655:         (forward-line -1)
        !           656:         (if (get-buffer mh-show-buffer)
        !           657:             (delete-windows-on mh-show-buffer)))))
        !           658: 
        !           659: 
        !           660: (defun mh-pack-folder (range)
        !           661:   "Renumber the messages of a folder to be 1..n.
        !           662: First, offer to execute any outstanding commands for the current folder.
        !           663: If optional prefix argument provided, prompt for the range of messages
        !           664: to display after packing.  Otherwise, show the entire folder."
        !           665:   (interactive (list (if current-prefix-arg
        !           666:                         (mh-read-msg-range
        !           667:                          "Range to scan after packing [all]? ")
        !           668:                         "all")))
        !           669:   (mh-pack-folder-1 range)
        !           670:   (mh-goto-cur-msg)
        !           671:   (message "Packing folder...done"))
        !           672: 
        !           673: 
        !           674: (defun mh-pipe-msg (prefix-provided command)
        !           675:   "Pipe the current message through the given shell COMMAND.
        !           676: If optional prefix argument is provided, send the entire message.
        !           677: Otherwise just send the message's body."
        !           678:   (interactive
        !           679:    (list current-prefix-arg (read-string "Shell command on message: ")))
        !           680:   (save-excursion
        !           681:     (mh-display-msg (mh-get-msg-num t) mh-current-folder) ;update show buffer
        !           682:     (goto-char (point-min))
        !           683:     (if (not prefix-provided) (search-forward "\n\n"))
        !           684:     (shell-command-on-region (point) (point-max) command nil)))
        !           685: 
        !           686: 
        !           687: (defun mh-refile-msg (prefix-provided msg-or-seq dest)
        !           688:   "Refile MESSAGE(s) (default: displayed message) in FOLDER.
        !           689: If optional prefix argument provided, then prompt for message sequence."
        !           690:   (interactive
        !           691:    (list current-prefix-arg
        !           692:         (if current-prefix-arg
        !           693:             (mh-read-seq-default "Refile" t)
        !           694:             (mh-get-msg-num t))
        !           695:         (intern
        !           696:          (mh-prompt-for-folder "Destination"
        !           697:                                (if (eq 'refile (car mh-last-destination))
        !           698:                                    (symbol-name (cdr mh-last-destination))
        !           699:                                    "")
        !           700:                                t))))
        !           701:   (setq mh-last-destination (cons 'refile dest))
        !           702:   (if prefix-provided
        !           703:       (mh-map-to-seq-msgs 'mh-refile-a-msg msg-or-seq dest)
        !           704:       (mh-refile-a-msg msg-or-seq dest))
        !           705:   (mh-next-msg))
        !           706: 
        !           707: 
        !           708: (defun mh-refile-or-write-again (msg)
        !           709:   "Re-execute the last refile or write command on the given MESSAGE.
        !           710: Default is the displayed message.  Use the same folder or file as the
        !           711: previous refile or write command."
        !           712:   (interactive (list (mh-get-msg-num t)))
        !           713:   (if (null mh-last-destination)
        !           714:       (error "No previous refile or write"))
        !           715:   (cond ((eq (car mh-last-destination) 'refile)
        !           716:         (mh-refile-a-msg msg (cdr mh-last-destination))
        !           717:         (message "Destination folder: %s" (cdr mh-last-destination)))
        !           718:        (t
        !           719:         (mh-write-msg-to-file msg (cdr mh-last-destination))
        !           720:         (message "Destination: %s" (cdr mh-last-destination))))
        !           721:   (mh-next-msg))
        !           722: 
        !           723: 
        !           724: (defun mh-reply (prefix-provided msg)
        !           725:   "Reply to a MESSAGE (default: displayed message).
        !           726: If optional prefix argument provided, then include the message in the reply
        !           727: using filter mhl.reply in your MH directory."
        !           728:   (interactive (list current-prefix-arg (mh-get-msg-num t)))
        !           729:   (let ((minibuffer-help-form
        !           730:         "from => Sender only\nto => Sender and primary recipients\ncc or all => Sender and all recipients"))
        !           731:     (let ((reply-to (or mh-reply-default-reply-to
        !           732:                        (completing-read "Reply to whom: "
        !           733:                                         '(("from") ("to") ("cc") ("all"))
        !           734:                                         nil
        !           735:                                         t)))
        !           736:          (folder mh-current-folder)
        !           737:          (show-buffer mh-show-buffer)
        !           738:          (config (current-window-configuration)))
        !           739:       (message "Composing a reply...")
        !           740:       (cond ((or (equal reply-to "from") (equal reply-to ""))
        !           741:             (apply 'mh-exec-cmd
        !           742:                    "repl" "-build" "-noquery"
        !           743:                    "-nodraftfolder" mh-current-folder
        !           744:                    msg
        !           745:                    "-nocc" "all"
        !           746:                    (if prefix-provided
        !           747:                        (list "-filter" "mhl.reply"))))
        !           748:            ((equal reply-to "to")
        !           749:             (apply 'mh-exec-cmd
        !           750:                    "repl" "-build" "-noquery"
        !           751:                    "-nodraftfolder" mh-current-folder
        !           752:                    msg
        !           753:                    "-cc" "to"
        !           754:                    (if prefix-provided
        !           755:                        (list "-filter" "mhl.reply"))))
        !           756:            ((or (equal reply-to "cc") (equal reply-to "all"))
        !           757:             (apply 'mh-exec-cmd
        !           758:                    "repl" "-build" "-noquery"
        !           759:                    "-nodraftfolder" mh-current-folder
        !           760:                    msg
        !           761:                    "-cc" "all" "-nocc" "me"
        !           762:                    (if prefix-provided
        !           763:                        (list "-filter" "mhl.reply")))))
        !           764: 
        !           765:       (let ((draft (mh-read-draft "reply"
        !           766:                                  (expand-file-name "reply" mh-user-path)
        !           767:                                  t)))
        !           768:        (delete-other-windows)
        !           769:        (set-buffer-modified-p nil)
        !           770: 
        !           771:        (let ((to (mh-get-field "To:"))
        !           772:              (subject (mh-get-field "Subject:"))
        !           773:              (cc (mh-get-field "Cc:")))
        !           774:          (goto-char (point-min))
        !           775:          (mh-goto-header-end 1)
        !           776:          (if (not prefix-provided)
        !           777:              (mh-display-msg msg folder))
        !           778:          (mh-add-msgs-to-seq msg 'answered t)
        !           779:          (message "Composing a reply...done")
        !           780:          (mh-compose-and-send-mail draft "" folder msg to subject cc
        !           781:                                    mh-note-repl "Replied:" config))))))
        !           782: 
        !           783: 
        !           784: (defun mh-quit ()
        !           785:   "Quit mh-e.
        !           786: Start by running mh-before-quit-hook.  Restore the previous window
        !           787: configuration, if one exists.  Finish by running mh-quit-hook."
        !           788:   (interactive)
        !           789:   (run-hooks 'mh-before-quit-hook)
        !           790:   (if mh-previous-window-config
        !           791:       (set-window-configuration mh-previous-window-config))
        !           792:   (run-hooks 'mh-quit-hook))
        !           793: 
        !           794: 
        !           795: (defun mh-page-digest ()
        !           796:   "Advance displayed message to next digested message."
        !           797:   (interactive)
        !           798:   (save-excursion
        !           799:     (mh-show-message-in-other-window)
        !           800:     ;; Go to top of screen (in case user moved point).
        !           801:     (move-to-window-line 0)
        !           802:     (let ((case-fold-search nil))
        !           803:       ;; Search for blank line and then for From:
        !           804:       (mh-when (not (and (search-forward "\n\n" nil t)
        !           805:                         (search-forward "From:" nil t)))
        !           806:        (other-window -1)
        !           807:        (error "No more messages")))
        !           808:     ;; Go back to previous blank line, then forward to the first non-blank.
        !           809:     (search-backward "\n\n" nil t)
        !           810:     (forward-line 2)
        !           811:     (mh-recenter 0)
        !           812:     (other-window -1)))
        !           813: 
        !           814: 
        !           815: (defun mh-page-digest-backwards ()
        !           816:   "Back up displayed message to previous digested message."
        !           817:   (interactive)
        !           818:   (save-excursion
        !           819:     (mh-show-message-in-other-window)
        !           820:     ;; Go to top of screen (in case user moved point).
        !           821:     (move-to-window-line 0)
        !           822:     (let ((case-fold-search nil))
        !           823:       (beginning-of-line)
        !           824:       (mh-when (not (and (search-backward "\n\n" nil t)
        !           825:                         (search-backward "From:" nil t)))
        !           826:        (other-window -1)
        !           827:        (error "No more messages")))
        !           828:     ;; Go back to previous blank line, then forward to the first non-blank.
        !           829:     (search-backward "\n\n" nil t)
        !           830:     (forward-line 2)
        !           831:     (mh-recenter 0)
        !           832:     (other-window -1)))
        !           833: 
        !           834: 
        !           835: (defun mh-page-msg (&optional arg)
        !           836:   "Page the displayed message forwards.
        !           837: Scrolls ARG lines or a full screen if no argument is supplied."
        !           838:   (interactive "P")
        !           839:   (scroll-other-window arg))
        !           840: 
        !           841: 
        !           842: (defun mh-previous-page (&optional arg)
        !           843:   "Page the displayed message backwards.
        !           844: Scrolls ARG lines or a full screen if no argument is supplied."
        !           845:   (interactive "P")
        !           846:   (save-excursion
        !           847:     (mh-show-message-in-other-window)
        !           848:     (unwind-protect
        !           849:        (scroll-down arg)
        !           850:       (other-window -1))))
        !           851: 
        !           852: 
        !           853: (defun mh-previous-undeleted-msg (&optional arg)
        !           854:   "Move to previous undeleted message in window."
        !           855:   (interactive "p")
        !           856:   (setq mh-next-direction 'backward)
        !           857:   (beginning-of-line)
        !           858:   (cond ((re-search-backward mh-good-msg-regexp nil 0 arg)
        !           859:         (mh-maybe-show))
        !           860:        (t
        !           861:         (if (get-buffer mh-show-buffer)
        !           862:             (delete-windows-on mh-show-buffer)))))
        !           863: 
        !           864: 
        !           865: (defun mh-print-msg (prefix-provided msg-or-seq)
        !           866:   "Print MESSAGE(s) (default: displayed message) on a line printer.
        !           867: If optional prefix argument provided, then prompt for the message sequence."
        !           868:   (interactive (list current-prefix-arg
        !           869:                     (if current-prefix-arg
        !           870:                         (reverse (mh-seq-to-msgs
        !           871:                                   (mh-read-seq-default "Print" t)))
        !           872:                         (mh-get-msg-num t))))
        !           873:   (if prefix-provided
        !           874:       (message "Printing sequence...")
        !           875:       (message "Printing message..."))
        !           876:   (let ((print-command
        !           877:         (if prefix-provided
        !           878:             (format "(scan -clear %s ; %s -nobell -clear %s %s) | %s"
        !           879:                     (mapconcat (function (lambda (msg) msg)) msg-or-seq " ")
        !           880:                     (expand-file-name "mhl" mh-lib)
        !           881:                     (if (stringp mhl-formfile)
        !           882:                         (format "-form %s" mhl-formfile)
        !           883:                         "")
        !           884:                     (mh-msg-filenames msg-or-seq)
        !           885:                     (format mh-lpr-command-format
        !           886:                             (if prefix-provided
        !           887:                                 (format "Sequence from %s" mh-current-folder)
        !           888:                                 (format "%s/%d" mh-current-folder
        !           889:                                         msg-or-seq))))
        !           890:             (format "%s -nobell -clear %s %s | %s"
        !           891:                     (expand-file-name "mhl" mh-lib)
        !           892:                     (mh-msg-filename msg-or-seq)
        !           893:                     (if (stringp mhl-formfile)
        !           894:                         (format "-form %s" mhl-formfile)
        !           895:                         "")
        !           896:                     (format mh-lpr-command-format
        !           897:                             (if prefix-provided
        !           898:                                 (format "Sequence from %s" mh-current-folder)
        !           899:                                 (format "%s/%d" mh-current-folder
        !           900:                                         msg-or-seq)))))))
        !           901:     (if mh-print-background
        !           902:        (mh-exec-cmd-daemon shell-file-name "-c" print-command)
        !           903:        (call-process shell-file-name nil nil nil "-c" print-command))
        !           904:     (if prefix-provided
        !           905:        (mh-notate-seq msg-or-seq ?P mh-cmd-note)
        !           906:        (mh-notate msg-or-seq ?P mh-cmd-note))
        !           907:     (mh-add-msgs-to-seq msg-or-seq 'printed t)
        !           908:     (if prefix-provided
        !           909:        (message "Printing sequence...done")
        !           910:         (message "Printing message...done"))))
        !           911: 
        !           912: 
        !           913: (defun mh-put-msg-in-seq (prefix-provided from to)
        !           914:   "Add MESSAGE(s) (default: displayed message) to SEQUENCE.
        !           915: If optional prefix argument provided, then prompt for the message sequence."
        !           916:   (interactive (list current-prefix-arg
        !           917:                     (if current-prefix-arg
        !           918:                         (mh-seq-to-msgs
        !           919:                           (mh-read-seq-default "Add messages from" t))
        !           920:                         (mh-get-msg-num t))
        !           921:                     (mh-read-seq-default "Add to" nil)))
        !           922:   (setq mh-previous-seq to)
        !           923:   (mh-add-msgs-to-seq from to))
        !           924: 
        !           925: 
        !           926: (defun mh-rescan-folder (&optional range)
        !           927:   "Rescan a folder after optionally processing the outstanding commands.
        !           928: If optional prefix argument is provided, prompt for the range of
        !           929: messages to display.  Otherwise show the entire folder."
        !           930:   (interactive (list (if current-prefix-arg
        !           931:                         (mh-read-msg-range "Range to scan [all]? ")
        !           932:                         nil)))
        !           933:   (setq mh-next-direction 'forward)
        !           934:   (mh-scan-folder mh-current-folder (or range "all")))
        !           935: 
        !           936: 
        !           937: (defun mh-redistribute (to cc msg)
        !           938:   "Redistribute a letter.
        !           939: Depending on how your copy of MH was compiled, you may need to change the
        !           940: setting of the variable mh-redist-full-contents.  See its documentation."
        !           941:   (interactive (list (read-string "Redist-To: ")
        !           942:                     (read-string "Redist-Cc: ")
        !           943:                     (mh-get-msg-num t)))
        !           944:   (save-window-excursion
        !           945:     (let ((folder mh-current-folder)
        !           946:          (draft (mh-read-draft "redistribution"
        !           947:                                (if mh-redist-full-contents
        !           948:                                    (mh-msg-filename msg)
        !           949:                                    nil)
        !           950:                                nil)))
        !           951:       (mh-goto-header-end 0)
        !           952:       (insert "Resent-To: " to "\n")
        !           953:       (if (not (equal cc "")) (insert "Resent-cc: " cc "\n"))
        !           954:       (mh-clean-msg-header (point-min)
        !           955:                           "^Message-Id:\\|^Received:\\|^Return-Path:\\|^Sender:\\|^Date:\\|^From:"
        !           956:                           nil)
        !           957:       (save-buffer)
        !           958:       (message "Redistributing...")
        !           959:       (if mh-redist-full-contents
        !           960:          (call-process "/bin/sh" nil 0 nil "-c"
        !           961:                        (format "mhdist=1 mhaltmsg=%s %s -push %s"
        !           962:                                (buffer-file-name)
        !           963:                                (expand-file-name "send" mh-progs)
        !           964:                                (buffer-file-name)))
        !           965:          (call-process "/bin/sh" nil 0 nil "-c"
        !           966:                        (format "mhdist=1 mhaltmsg=%s mhannotate=1 %s -push %s"
        !           967:                                (mh-msg-filename msg folder)
        !           968:                                (expand-file-name "send" mh-progs)
        !           969:                                (buffer-file-name))))
        !           970:       (mh-annotate-msg msg folder mh-note-dist
        !           971:                       "-component" "Resent:"
        !           972:                       "-text" (format "\"%s %s\"" to cc))
        !           973:       (kill-buffer draft)
        !           974:       (message "Redistributing...done"))))
        !           975: 
        !           976: 
        !           977: (defun mh-write-msg-to-file (msg file)
        !           978:   "Append MESSAGE to the end of a FILE."
        !           979:   (interactive
        !           980:    (list (mh-get-msg-num t)
        !           981:         (let ((default-dir (if (eq 'write (car mh-last-destination))
        !           982:                                (file-name-directory (cdr mh-last-destination))
        !           983:                                default-directory)))
        !           984:           (read-file-name "Save message in file: " default-dir
        !           985:                           (expand-file-name "mail.out" default-dir)))))
        !           986:   (let ((file-name (mh-msg-filename msg))
        !           987:        (output-file (mh-expand-file-name file)))
        !           988:     (setq mh-last-destination (cons 'write file))
        !           989:     (save-excursion
        !           990:       (set-buffer (get-buffer-create " *mh-temp*"))
        !           991:       (erase-buffer)
        !           992:       (insert-file-contents file-name)
        !           993:       (append-to-file (point-min) (point-max) output-file))))
        !           994: 
        !           995: 
        !           996: (defun mh-search-folder (folder)
        !           997:   "Search FOLDER for messages matching a pattern."
        !           998:   (interactive (list (mh-prompt-for-folder "Search"
        !           999:                                           mh-current-folder
        !          1000:                                           t)))
        !          1001:   (switch-to-buffer-other-window "pick-pattern")
        !          1002:   (if (or (zerop (buffer-size))
        !          1003:          (not (y-or-n-p "Reuse pattern? ")))
        !          1004:       (mh-make-pick-template)
        !          1005:       (message ""))
        !          1006:   (setq mh-searching-folder folder))
        !          1007: 
        !          1008: 
        !          1009: (defun mh-send (to cc subject)
        !          1010:   "Compose and send a letter.
        !          1011: The letter is composed in mh-letter-mode; see its documentation for more
        !          1012: details.  If `mh-compose-letter-function' is defined, it is called on the
        !          1013: draft and passed three arguments: to, subject, and cc."
        !          1014:   (interactive "sTo: \nsCc: \nsSubject: ")
        !          1015:   (let ((config (current-window-configuration)))
        !          1016:     (delete-other-windows)
        !          1017:     (mh-send-sub to cc subject config)))
        !          1018: 
        !          1019: 
        !          1020: (defun mh-send-other-window (to cc subject)
        !          1021:   "Compose and send a letter in another window.."
        !          1022:   (interactive "sTo: \nsCc: \nsSubject: ")
        !          1023:   (let ((pop-up-windows t))
        !          1024:     (mh-send-sub to cc subject (current-window-configuration))))
        !          1025: 
        !          1026: 
        !          1027: (defun mh-send-sub (to cc subject config)
        !          1028:   "Do the real work of composing and sending a letter.
        !          1029: Expects the TO, CC, and SUBJECT fields as arguments.
        !          1030: CONFIG is the window configuration before sending mail."
        !          1031:   (let ((folder mh-current-folder)
        !          1032:        (msg-num (mh-get-msg-num nil)))
        !          1033:     (message "Composing a message...")
        !          1034:     (let ((draft (mh-read-draft
        !          1035:                  "message"
        !          1036:                  (if (file-exists-p
        !          1037:                       (expand-file-name "components" mh-user-path))
        !          1038:                      (expand-file-name "components" mh-user-path)
        !          1039:                      (if (file-exists-p
        !          1040:                           (expand-file-name "components" mh-lib))
        !          1041:                          (expand-file-name "components" mh-lib)
        !          1042:                          (error "Can't find components file")))
        !          1043:                  nil)))
        !          1044:       (mh-insert-fields "To:" to "Subject:" subject "Cc:" cc)
        !          1045:       (set-buffer-modified-p nil)
        !          1046:       (goto-char (point-max))
        !          1047:       (message "Composing a message...done")
        !          1048:       (mh-compose-and-send-mail draft "" folder msg-num
        !          1049:                                to subject cc
        !          1050:                                nil nil config))))
        !          1051: 
        !          1052: 
        !          1053: (defun mh-show (&optional msg)
        !          1054:   "Show MESSAGE (default: displayed message).
        !          1055: Forces a two-window display with the folder window on top (size
        !          1056: mh-summary-height) and the show buffer below it."
        !          1057:   (interactive)
        !          1058:   (if (not msg)
        !          1059:       (setq msg (mh-get-msg-num t)))
        !          1060:   (setq mh-showing t)
        !          1061:   (mh-set-mode-name "mh-e show")
        !          1062:   (if (not (eql (next-window (minibuffer-window)) (selected-window)))
        !          1063:       (delete-other-windows))          ; force ourself to the top window
        !          1064:   (let ((folder mh-current-folder))
        !          1065:     (mh-show-message-in-other-window)
        !          1066:     (mh-display-msg msg folder))
        !          1067:   (other-window -1)
        !          1068:   (if (not (= (1+ (window-height)) (screen-height))) ;not horizontally split
        !          1069:       (shrink-window (- (window-height) mh-summary-height)))
        !          1070:   (mh-recenter nil)
        !          1071:   (if (not (memq msg mh-seen-list)) (mh-push msg mh-seen-list)))
        !          1072: 
        !          1073: 
        !          1074: (defun mh-sort-folder ()
        !          1075:   "Sort the messages in the current folder by date."
        !          1076:   (interactive)
        !          1077:   (mh-process-or-undo-commands mh-current-folder)
        !          1078:   (setq mh-next-direction 'forward)
        !          1079:   (mh-set-folder-modified-p t)         ; lock folder while sorting
        !          1080:   (message "Sorting folder...")
        !          1081:   (mh-exec-cmd "sortm" mh-current-folder)
        !          1082:   (message "Sorting folder...done")
        !          1083:   (mh-scan-folder mh-current-folder "all"))
        !          1084: 
        !          1085: 
        !          1086: (defun mh-toggle-showing ()
        !          1087:   "Toggle the scanning mode/showing mode of displaying messages."
        !          1088:   (interactive)
        !          1089:   (if mh-showing
        !          1090:       (mh-set-scan-mode)
        !          1091:       (mh-show)))
        !          1092: 
        !          1093: 
        !          1094: (defun mh-undo (prefix-provided msg-or-seq)
        !          1095:   "Undo the deletion or refile of the specified MESSAGE(s).
        !          1096: Default is the displayed message.  If optional prefix argument is
        !          1097: provided, then prompt for the message sequence."
        !          1098:   (interactive (list current-prefix-arg
        !          1099:                     (if current-prefix-arg
        !          1100:                         (mh-read-seq-default "Undo" t)
        !          1101:                         (mh-get-msg-num t))))
        !          1102:   (cond (prefix-provided
        !          1103:         (mh-mapc (function mh-undo-msg) (mh-seq-to-msgs msg-or-seq)))
        !          1104:        (t
        !          1105:         (let ((original-position (point)))
        !          1106:           (beginning-of-line)
        !          1107:           (while (not (or (looking-at mh-deleted-msg-regexp)
        !          1108:                           (looking-at mh-refiled-msg-regexp)
        !          1109:                           (and (eq mh-next-direction 'forward) (bobp))
        !          1110:                           (and (eq mh-next-direction 'backward)
        !          1111:                                (save-excursion (forward-line) (eobp)))))
        !          1112:             (forward-line (if (eq mh-next-direction 'forward) -1 1)))
        !          1113:           (if (or (looking-at mh-deleted-msg-regexp)
        !          1114:                   (looking-at mh-refiled-msg-regexp))
        !          1115:               (progn
        !          1116:                 (mh-undo-msg (mh-get-msg-num t))
        !          1117:                 (mh-maybe-show))
        !          1118:               (goto-char original-position)
        !          1119:               (error "Nothing to undo")))))
        !          1120:   ;; update the mh-refile-list so mh-outstanding-commands-p will work
        !          1121:   (mh-mapc (function
        !          1122:            (lambda (elt)
        !          1123:              (if (not (mh-seq-to-msgs elt))
        !          1124:                  (setq mh-refile-list (delq elt mh-refile-list)))))
        !          1125:           mh-refile-list)
        !          1126:   (if (not (mh-outstanding-commands-p))
        !          1127:       (mh-set-folder-modified-p nil)))
        !          1128: 
        !          1129: 
        !          1130: (defun mh-undo-msg (msg)
        !          1131:   ;; Undo the deletion or refile of one MESSAGE.
        !          1132:   (cond ((memq msg mh-delete-list)
        !          1133:         (setq mh-delete-list (delq msg mh-delete-list))
        !          1134:         (mh-remove-msg-from-seq msg 'deleted t))
        !          1135:        (t
        !          1136:         (mh-mapc (function (lambda (dest)
        !          1137:                              (mh-remove-msg-from-seq msg dest t)))
        !          1138:                  mh-refile-list)))
        !          1139:   (mh-notate msg ?  mh-cmd-note))
        !          1140: 
        !          1141: 
        !          1142: (defun mh-undo-folder (&rest ignore)
        !          1143:   "Undo all commands in current folder."
        !          1144:   (interactive)
        !          1145:   (cond ((or mh-do-not-confirm
        !          1146:             (yes-or-no-p "Undo all commands in folder? "))
        !          1147:         (setq mh-delete-list nil
        !          1148:               mh-refile-list nil
        !          1149:               mh-seq-list nil
        !          1150:               mh-next-direction 'forward)
        !          1151:         (with-mh-folder-updating (nil)
        !          1152:           (mh-unmark-all-headers t)))
        !          1153:        (t
        !          1154:         (message "Commands not undone.")
        !          1155:         (sit-for 2))))
        !          1156: 
        !          1157: 
        !          1158: (defun mh-unshar-msg (dir)
        !          1159:   "Unpack the shar file contained in the current message into directory DIR."
        !          1160:   (interactive (list (read-file-name "Unshar message in directory: "
        !          1161:                                     mh-unshar-default-directory
        !          1162:                                     mh-unshar-default-directory nil)))
        !          1163:   (mh-display-msg (mh-get-msg-num t) mh-current-folder) ;update show buffer
        !          1164:   (mh-unshar-buffer dir))
        !          1165: 
        !          1166: (defun mh-unshar-buffer (dir)
        !          1167:   ;; Unpack the shar file contained in the current buffer into directory DIR.
        !          1168:   (goto-char (point-min))
        !          1169:   (if (or (re-search-forward "^#![ \t]*/bin/sh" nil t)
        !          1170:          (and (re-search-forward "^[^a-z0-9\"]*cut here\b" nil t)
        !          1171:               (forward-line 1))
        !          1172:          (re-search-forward "^#" nil t)
        !          1173:          (re-search-forward "^: " nil t))
        !          1174:       (let ((default-directory (expand-file-name dir))
        !          1175:            (start (progn (beginning-of-line) (point)))
        !          1176:            (log-buffer (get-buffer-create "*Unshar Output*")))
        !          1177:        (save-excursion
        !          1178:          (set-buffer log-buffer)
        !          1179:          (setq default-directory (expand-file-name dir))
        !          1180:          (erase-buffer)
        !          1181:          (if (file-directory-p default-directory)
        !          1182:              (insert "cd " dir "\n")
        !          1183:            (insert "mkdir " dir "\n")
        !          1184:            (call-process "mkdir" nil log-buffer t default-directory)))
        !          1185:        (set-window-start (display-buffer log-buffer) 0) ;so can watch progress
        !          1186:        (call-process-region start (point-max) "sh" nil log-buffer t))
        !          1187:     (error "Cannot find start of shar.")))
        !          1188:        
        !          1189: 
        !          1190: (defun mh-visit-folder (folder &optional range)
        !          1191:   "Visit FOLDER and display RANGE of messages.
        !          1192: Assumes mh-e has already been initialized."
        !          1193:   (interactive (list (mh-prompt-for-folder "Visit" "+inbox" t)
        !          1194:                     (mh-read-msg-range "Range [all]? ")))
        !          1195:   (let ((config (current-window-configuration)))
        !          1196:     (mh-scan-folder folder (or range "all"))
        !          1197:     (setq mh-previous-window-config config))
        !          1198:   nil)
        !          1199: 
        !          1200: 
        !          1201: (defun mh-widen ()
        !          1202:   "Remove restrictions from the current folder, thereby showing all messages."
        !          1203:   (interactive)
        !          1204:   (if mh-narrowed-to-seq
        !          1205:       (with-mh-folder-updating (t)
        !          1206:        (delete-region (point-min) (point-max))
        !          1207:        (widen)
        !          1208:        (mh-make-folder-mode-line)))
        !          1209:   (setq mh-narrowed-to-seq nil))
        !          1210: 
        !          1211: 
        !          1212: 
        !          1213: ;;; Support routines.
        !          1214: 
        !          1215: (defun mh-delete-a-msg (msg)
        !          1216:   ;; Delete the MESSAGE.
        !          1217:   (save-excursion
        !          1218:     (mh-goto-msg msg nil t)
        !          1219:     (if (looking-at mh-refiled-msg-regexp)
        !          1220:        (error "Message %d is refiled.  Undo refile before deleting." msg))
        !          1221:     (if (looking-at mh-deleted-msg-regexp)
        !          1222:        nil
        !          1223:        (mh-set-folder-modified-p t)
        !          1224:        (mh-push msg mh-delete-list)
        !          1225:        (mh-add-msgs-to-seq msg 'deleted t)
        !          1226:        (mh-notate msg ?D mh-cmd-note))))
        !          1227: 
        !          1228: 
        !          1229: (defun mh-refile-a-msg (msg destination)
        !          1230:   ;; Refile MESSAGE in FOLDER.  FOLDER is a symbol, not a string.
        !          1231:   (save-excursion
        !          1232:     (mh-goto-msg msg nil t)
        !          1233:     (cond ((looking-at mh-deleted-msg-regexp)
        !          1234:           (error "Message %d is deleted.  Undo delete before moving." msg))
        !          1235:          ((looking-at mh-refiled-msg-regexp)
        !          1236:           (if (y-or-n-p
        !          1237:                (format "Message %d already refiled.  Copy to %s as well? "
        !          1238:                        msg destination))
        !          1239:               (mh-exec-cmd "refile" (mh-get-msg-num t) "-link"
        !          1240:                            "-src" mh-current-folder
        !          1241:                            (symbol-name destination))
        !          1242:               (message "Message not copied.")))
        !          1243:          (t
        !          1244:           (mh-set-folder-modified-p t)
        !          1245:           (if (not (memq destination mh-refile-list))
        !          1246:               (mh-push destination mh-refile-list))
        !          1247:           (if (not (memq msg (mh-seq-to-msgs destination)))
        !          1248:               (mh-add-msgs-to-seq msg destination t))
        !          1249:           (mh-notate msg ?^ mh-cmd-note)))))
        !          1250: 
        !          1251: 
        !          1252: (defun mh-display-msg (msg-num folder)
        !          1253:   ;; Display message NUMBER of FOLDER.
        !          1254:   ;; Sets the current buffer to the show buffer.
        !          1255:   (set-buffer folder)
        !          1256:   ;; Bind variables in folder buffer in case they are local
        !          1257:   (let ((formfile mhl-formfile)
        !          1258:        (clean-message-header mh-clean-message-header)
        !          1259:        (invisible-headers mh-invisible-headers)
        !          1260:        (visible-headers mh-visible-headers)
        !          1261:        (msg-filename (mh-msg-filename msg-num))
        !          1262:        (show-buffer mh-show-buffer)
        !          1263:        (folder mh-current-folder))
        !          1264:     (if (not (file-exists-p msg-filename))
        !          1265:        (error "Message %d does not exist" msg-num))
        !          1266:     (switch-to-buffer show-buffer)
        !          1267:     (if mh-bury-show-buffer (bury-buffer (current-buffer)))
        !          1268:     (mh-when (not (equal msg-filename buffer-file-name))
        !          1269:       ;; Buffer does not yet contain message.
        !          1270:       (clear-visited-file-modtime)
        !          1271:       (unlock-buffer)
        !          1272:       (setq buffer-file-name nil)      ; no locking during setup
        !          1273:       (erase-buffer)
        !          1274:       (if formfile
        !          1275:          (if (stringp formfile)
        !          1276:              (mh-exec-lib-cmd-output "mhl" "-nobell" "-noclear"
        !          1277:                                      "-form" formfile msg-filename)
        !          1278:              (mh-exec-lib-cmd-output "mhl" "-nobell" "-noclear"
        !          1279:                                      msg-filename))
        !          1280:          (insert-file-contents msg-filename))
        !          1281:       (goto-char (point-min))
        !          1282:       (cond (clean-message-header
        !          1283:             (mh-clean-msg-header (point-min)
        !          1284:                                  invisible-headers
        !          1285:                                  visible-headers)
        !          1286:             (goto-char (point-min)))
        !          1287:            (t
        !          1288:             (let ((case-fold-search t))
        !          1289:               (re-search-forward
        !          1290:                "^To:\\|^From:\\|^Subject:\\|^Date:" nil t)
        !          1291:               (beginning-of-line)
        !          1292:               (mh-recenter 0))))
        !          1293:       (set-buffer-modified-p nil)
        !          1294:       (setq buffer-file-name msg-filename)
        !          1295:       (set-mark nil)
        !          1296:       (setq mode-line-buffer-identification
        !          1297:            (list (format mh-show-buffer-mode-line-buffer-id
        !          1298:                          folder msg-num))))))
        !          1299: 
        !          1300: 
        !          1301: (defun mh-invalidate-show-buffer ()
        !          1302:   ;; Invalidate the show buffer so we must update it to use it.
        !          1303:   (if (get-buffer mh-show-buffer)
        !          1304:       (save-excursion
        !          1305:        (set-buffer mh-show-buffer)
        !          1306:        (setq buffer-file-name nil))))
        !          1307: 
        !          1308: 
        !          1309: (defun mh-show-message-in-other-window ()
        !          1310:   (switch-to-buffer-other-window mh-show-buffer)
        !          1311:   (if mh-bury-show-buffer (bury-buffer (current-buffer))))
        !          1312: 
        !          1313: 
        !          1314: (defun mh-clean-msg-header (start invisible-headers visible-headers)
        !          1315:   ;; Flush extraneous lines in a message header, from the given POINT to the
        !          1316:   ;; end of the message header.  If VISIBLE-HEADERS is non-nil, it contains a
        !          1317:   ;; regular expression specifying the lines to display, otherwise
        !          1318:   ;; INVISIBLE-HEADERS contains a regular expression specifying lines to
        !          1319:   ;; delete from the header.
        !          1320:   (let ((case-fold-search t))
        !          1321:     (save-restriction
        !          1322:       (goto-char start)
        !          1323:       (if (search-forward "\n\n" nil t)
        !          1324:          (backward-char 1))
        !          1325:       (narrow-to-region start (point))
        !          1326:       (goto-char (point-min))
        !          1327:       (if visible-headers
        !          1328:          (while (< (point) (point-max))
        !          1329:            (beginning-of-line)
        !          1330:            (cond ((looking-at visible-headers)
        !          1331:                   (forward-line 1)
        !          1332:                   (while (looking-at "^[ \t]+") (forward-line 1)))
        !          1333:                  (t
        !          1334:                    (mh-delete-line 1)
        !          1335:                    (while (looking-at "^[ \t]+")
        !          1336:                      (beginning-of-line)
        !          1337:                      (mh-delete-line 1)))))
        !          1338:          (while (re-search-forward invisible-headers nil t)
        !          1339:            (beginning-of-line)
        !          1340:            (mh-delete-line 1)
        !          1341:            (while (looking-at "^[ \t]+")
        !          1342:              (beginning-of-line)
        !          1343:              (mh-delete-line 1))))
        !          1344:       (unlock-buffer))))
        !          1345: 
        !          1346: 
        !          1347: (defun mh-delete-line (lines)
        !          1348:   ;; Delete version of kill-line.
        !          1349:   (delete-region (point) (save-excursion (forward-line lines) (point))))
        !          1350: 
        !          1351: 
        !          1352: (defun mh-read-draft (use initial-contents delete-contents-file)
        !          1353:   ;; Read draft file into a draft buffer and make that buffer the current one.
        !          1354:   ;; USE is a message used for prompting about the intended use of the message.
        !          1355:   ;; INITIAL-CONTENTS is filename that is read into an empty buffer, or NIL
        !          1356:   ;; if buffer should not be modified.  Delete the initial-contents file if
        !          1357:   ;; DELETE-CONTENTS-FILE flag is set.
        !          1358:   ;; Returns the draft folder's name.
        !          1359:   ;; If the draft folder facility is enabled in ~/.mh_profile, a new buffer is
        !          1360:   ;; used each time and saved in the draft folder.  The draft file can then be
        !          1361:   ;; reused.
        !          1362:   (cond (mh-draft-folder
        !          1363:         (let ((orig-default-dir default-directory))
        !          1364:           (pop-to-buffer (find-file-noselect (mh-new-draft-name)) t)
        !          1365:           (rename-buffer (format "draft-%s" (buffer-name)))
        !          1366:           (setq default-directory orig-default-dir)))
        !          1367:        (t
        !          1368:         (let ((draft-name (expand-file-name "draft" mh-user-path)))
        !          1369:           (pop-to-buffer "draft")      ; Create if necessary
        !          1370:           (if (buffer-modified-p)
        !          1371:               (if (y-or-n-p "Draft has been modified; kill anyway? ")
        !          1372:                   (set-buffer-modified-p nil)
        !          1373:                   (error "Draft preserved")))
        !          1374:           (setq buffer-file-name draft-name)
        !          1375:           (clear-visited-file-modtime)
        !          1376:           (unlock-buffer)
        !          1377:           (mh-when (and (file-exists-p draft-name)
        !          1378:                         (not (equal draft-name initial-contents)))
        !          1379:             (insert-file-contents draft-name)
        !          1380:             (delete-file draft-name)))))
        !          1381:   (mh-when (and initial-contents
        !          1382:                (or (zerop (buffer-size))
        !          1383:                    (not (y-or-n-p
        !          1384:                          (format "A draft exists.  Use for %s? " use)))))
        !          1385:     (erase-buffer)
        !          1386:     (insert-file-contents initial-contents)
        !          1387:     (if delete-contents-file (delete-file initial-contents)))
        !          1388:   (auto-save-mode 1)
        !          1389:   (if mh-draft-folder
        !          1390:       (save-buffer))                   ; Do not reuse draft name
        !          1391:   (buffer-name))
        !          1392: 
        !          1393: 
        !          1394: (defun mh-new-draft-name ()
        !          1395:   ;; Returns the pathname of folder for draft messages.
        !          1396:   (save-excursion
        !          1397:     (set-buffer (get-buffer-create " *mh-temp*"))
        !          1398:     (erase-buffer)
        !          1399:     (mh-exec-cmd-output "mhpath" nil mh-draft-folder "new")
        !          1400:     (buffer-substring (point) (1- (mark)))))
        !          1401: 
        !          1402: 
        !          1403: (defun mh-next-msg ()
        !          1404:   ;; Move backward or forward to the next undeleted message in the buffer.
        !          1405:   (if (eq mh-next-direction 'forward)
        !          1406:       (mh-next-undeleted-msg 1)
        !          1407:       (mh-previous-undeleted-msg 1)))
        !          1408: 
        !          1409: 
        !          1410: (defun mh-set-scan-mode ()
        !          1411:   ;; Display the scan listing buffer, but do not show a message.
        !          1412:   (if (get-buffer mh-show-buffer)
        !          1413:       (delete-windows-on mh-show-buffer))
        !          1414:   (mh-set-mode-name "mh-e scan")
        !          1415:   (setq mh-showing nil)
        !          1416:   (if mh-recenter-summary-p
        !          1417:       (mh-recenter nil)))
        !          1418: 
        !          1419: 
        !          1420: (defun mh-maybe-show (&optional msg)
        !          1421:   ;; If in showing mode, then display the message pointed to by the cursor.
        !          1422:   (if mh-showing (mh-show msg)))
        !          1423: 
        !          1424: 
        !          1425: (defun mh-set-mode-name (mode-name-string)
        !          1426:   ;; Set the mode-name and ensure that the mode line is updated.
        !          1427:   (setq mode-name mode-name-string)
        !          1428:   ;; Force redisplay of all buffers' mode lines to be considered.
        !          1429:   (save-excursion (set-buffer (other-buffer)))
        !          1430:   (set-buffer-modified-p (buffer-modified-p)))
        !          1431: 
        !          1432: 
        !          1433: 
        !          1434: ;;; The folder data abstraction.
        !          1435: 
        !          1436: (defvar mh-current-folder nil "Name of current folder, a string.")
        !          1437: (defvar mh-show-buffer nil "Buffer that displays mesage for this folder.")
        !          1438: (defvar mh-folder-filename nil "Full path of directory for this folder.")
        !          1439: (defvar mh-showing nil "If non-nil, show the message in a separate window.")
        !          1440: (defvar mh-next-seq-num nil "Index of free sequence id.")
        !          1441: (defvar mh-delete-list nil "List of msg numbers to delete.")
        !          1442: (defvar mh-refile-list nil "List of folder names in mh-seq-list.")
        !          1443: (defvar mh-seq-list nil "Alist of (seq . msgs) numbers.")
        !          1444: (defvar mh-seen-list nil "List of displayed messages.")
        !          1445: (defvar mh-next-direction 'forward "Direction to move to next message.")
        !          1446: (defvar mh-narrowed-to-seq nil "Sequence display is narrowed to.")
        !          1447: (defvar mh-first-msg-num nil "Number of first msg in buffer.")
        !          1448: (defvar mh-last-msg-num nil "Number of last msg in buffer.")
        !          1449: 
        !          1450: 
        !          1451: (defun mh-make-folder (name)
        !          1452:   ;; Create and initialize a new mail folder called NAME and make it the
        !          1453:   ;; current folder.
        !          1454:   (switch-to-buffer name)
        !          1455:   (setq buffer-read-only nil)
        !          1456:   (erase-buffer)
        !          1457:   (setq buffer-read-only t)
        !          1458:   (mh-folder-mode)
        !          1459:   (mh-set-folder-modified-p nil)
        !          1460:   (setq buffer-file-name mh-folder-filename)
        !          1461:   (mh-set-mode-name "mh-e scan"))
        !          1462: 
        !          1463: 
        !          1464: ;;; Don't use this mode when creating buffers if default-major-mode is nil.
        !          1465: (put 'mh-folder-mode 'mode-class 'special)
        !          1466: 
        !          1467: (defun mh-folder-mode ()
        !          1468:   "Major mode for \"editing\" an MH folder scan listing.
        !          1469: Messages can be marked for refiling and deletion.  However, both actions
        !          1470: are deferred until you request execution with \\[mh-execute-commands].
        !          1471: \\{mh-folder-mode-map}
        !          1472:   A prefix argument (\\[universal-argument]) to delete, refile, list, or undo
        !          1473: applies the action to a message sequence.
        !          1474: 
        !          1475: Variables controlling mh-e operation are (defaults in parentheses):
        !          1476: 
        !          1477:  mh-bury-show-buffer (t)
        !          1478:     Non-nil means that the buffer used to display message is buried.
        !          1479:     It will never be offered as the default other buffer.
        !          1480: 
        !          1481:  mh-clean-message-header (nil)
        !          1482:     Non-nil means remove header lines matching the regular expression
        !          1483:     specified in mh-invisible-headers from messages.
        !          1484: 
        !          1485:  mh-visible-headers (nil)
        !          1486:     If non-nil, it contains a regexp specifying the headers that are shown in
        !          1487:     a message if mh-clean-message-header is non-nil.  Setting this variable
        !          1488:     overrides mh-invisible-headers.
        !          1489: 
        !          1490:  mh-do-not-confirm (nil)
        !          1491:     Non-nil means do not prompt for confirmation before executing some
        !          1492:     non-recoverable commands such as mh-kill-folder and mh-undo-folder.
        !          1493: 
        !          1494:  mhl-formfile (nil)
        !          1495:     Name of format file to be used by mhl to show messages.
        !          1496:     A value of T means use the default format file.
        !          1497:     Nil means don't use mhl to format messages.
        !          1498: 
        !          1499:  mh-lpr-command-format (\"lpr -p -J '%s'\")
        !          1500:     Format for command used to print a message on a system printer.
        !          1501: 
        !          1502:  mh-recenter-summary-p (nil)
        !          1503:     If non-nil, then the scan listing is recentered when the window displaying
        !          1504:     a messages is toggled off.
        !          1505: 
        !          1506:  mh-summary-height (4)
        !          1507:     Number of lines in the summary window including the mode line.
        !          1508: 
        !          1509:  mh-ins-buf-prefix (\"> \")
        !          1510:     String to insert before each non-blank line of a message as it is
        !          1511:     inserted in a draft letter.
        !          1512: 
        !          1513: The value of mh-folder-mode-hook is called when a new folder is set up."
        !          1514: 
        !          1515:   (kill-all-local-variables)
        !          1516:   (use-local-map mh-folder-mode-map)
        !          1517:   (setq major-mode 'mh-folder-mode)
        !          1518:   (mh-set-mode-name "mh-e folder")
        !          1519:   (make-local-vars
        !          1520:    'mh-current-folder (buffer-name)    ; Name of folder, a string
        !          1521:    'mh-show-buffer (format "show-%s" (buffer-name)) ; Buffer that displays msgs
        !          1522:    'mh-folder-filename                 ; e.g. "/usr/foobar/Mail/inbox/"
        !          1523:    (file-name-as-directory (mh-expand-file-name (buffer-name)))
        !          1524:    'mh-showing nil                     ; Show message also?
        !          1525:    'mh-next-seq-num 0                  ; Index of free sequence id
        !          1526:    'mh-delete-list nil                 ; List of msgs nums to delete
        !          1527:    'mh-refile-list nil                 ; List of folder names in mh-seq-list
        !          1528:    'mh-seq-list nil                    ; Alist of (seq . msgs) nums
        !          1529:    'mh-seen-list nil                   ; List of displayed messages
        !          1530:    'mh-next-direction 'forward         ; Direction to move to next message
        !          1531:    'mh-narrowed-to-seq nil             ; Sequence display is narrowed to
        !          1532:    'mh-first-msg-num nil               ; Number of first msg in buffer
        !          1533:    'mh-last-msg-num nil                        ; Number of last msg in buffer
        !          1534:    'mh-previous-window-config nil)     ; Previous window configuration
        !          1535:   (setq truncate-lines t)
        !          1536:   (auto-save-mode -1)
        !          1537:   (setq buffer-offer-save t)
        !          1538:   (make-local-variable 'write-file-hooks)
        !          1539:   (setq write-file-hooks '(mh-execute-commands))
        !          1540:   (make-local-variable 'revert-buffer-function)
        !          1541:   (setq revert-buffer-function 'mh-undo-folder)
        !          1542:   (run-hooks 'mh-folder-mode-hook))
        !          1543: 
        !          1544: 
        !          1545: (defun make-local-vars (&rest pairs)
        !          1546:   ;; Take VARIABLE-VALUE pairs and makes local variables initialized to the
        !          1547:   ;; value.
        !          1548:   (while pairs
        !          1549:     (make-variable-buffer-local (car pairs))
        !          1550:     (set (car pairs) (car (cdr pairs)))
        !          1551:     (setq pairs (cdr (cdr pairs)))))
        !          1552: 
        !          1553: 
        !          1554: (defun mh-scan-folder (folder range)
        !          1555:   ;; Scan the FOLDER over the RANGE.  Return in the folder's buffer.
        !          1556:   (cond ((null (get-buffer folder))
        !          1557:         (mh-make-folder folder))
        !          1558:        (t
        !          1559:         (mh-process-or-undo-commands folder)
        !          1560:         (switch-to-buffer folder)))
        !          1561:   (mh-regenerate-headers range)
        !          1562:   (mh-when (zerop (buffer-size))
        !          1563:     (if (equal range "all")
        !          1564:        (message "Folder %s is empty" folder)
        !          1565:        (message "No messages in %s, range %s" folder range))
        !          1566:     (sit-for 5))
        !          1567:   (mh-goto-cur-msg))
        !          1568: 
        !          1569: 
        !          1570: (defun mh-regenerate-headers (range)
        !          1571:   ;; Replace buffer with scan of its contents over range RANGE.
        !          1572:   (let ((folder mh-current-folder))
        !          1573:     (message "Scanning %s..." folder)
        !          1574:     (with-mh-folder-updating (nil)
        !          1575:       (erase-buffer)
        !          1576:       (mh-exec-cmd-output "scan" nil
        !          1577:                          "-noclear" "-noheader"
        !          1578:                          "-width" (window-width)
        !          1579:                          folder range)
        !          1580:       (goto-char (point-min))
        !          1581:       (cond ((looking-at "scan: no messages in")
        !          1582:             (keep-lines mh-valid-scan-line)) ; Flush random scan lines
        !          1583:            ((looking-at "scan: "))     ; Keep error messages
        !          1584:            (t
        !          1585:             (keep-lines mh-valid-scan-line))) ; Flush random scan lines
        !          1586:       (mh-delete-seq-locally 'cur)     ; To pick up new one
        !          1587:       (setq mh-seq-list (mh-read-folder-sequences folder nil))
        !          1588:       (mh-notate-user-sequences)
        !          1589:       (mh-make-folder-mode-line (if (equal range "all")
        !          1590:                                    nil
        !          1591:                                    mh-partial-folder-mode-line-annotation)))
        !          1592:     (message "Scanning %s...done" folder)))
        !          1593: 
        !          1594: 
        !          1595: (defun mh-get-new-mail (maildrop-name)
        !          1596:   ;; Read new mail from a maildrop into the current buffer.
        !          1597:   ;; Return T if there was new mail, NIL otherwise.  Return in the current
        !          1598:   ;; buffer.
        !          1599:   (let ((point-before-inc (point))
        !          1600:        (folder mh-current-folder)
        !          1601:        (return-value t))
        !          1602:     (with-mh-folder-updating (t)
        !          1603:       (message (if maildrop-name
        !          1604:                   (format "inc %s -file %s..." folder maildrop-name)
        !          1605:                   (format "inc %s..." folder)))
        !          1606:       (mh-unmark-all-headers nil)
        !          1607:       (setq mh-next-direction 'forward)
        !          1608:       (goto-char (point-max))
        !          1609:       (let ((start-of-inc (point)))
        !          1610:        (if maildrop-name
        !          1611:            (mh-exec-cmd-output "inc" nil folder
        !          1612:                                "-file" (expand-file-name maildrop-name)
        !          1613:                                "-width" (window-width)
        !          1614:                                "-truncate")
        !          1615:            (mh-exec-cmd-output "inc" nil
        !          1616:                                "-width" (window-width)))
        !          1617:        (message
        !          1618:         (if maildrop-name
        !          1619:             (format "inc %s -file %s...done" folder maildrop-name)
        !          1620:             (format "inc %s...done" folder)))
        !          1621:        (goto-char start-of-inc)
        !          1622:        (cond ((looking-at "inc: no mail")
        !          1623:               (keep-lines mh-valid-scan-line) ; Flush random scan lines
        !          1624:               (goto-char point-before-inc)
        !          1625:               (message "No new mail%s%s" (if maildrop-name " in " "")
        !          1626:                        (if maildrop-name maildrop-name "")))
        !          1627:              ((re-search-forward "^inc:" nil t) ; Error messages
        !          1628:               (error "inc error"))
        !          1629:              (t
        !          1630:               (mh-delete-seq-locally 'cur) ; To pick up new one
        !          1631:               (setq mh-seq-list (mh-read-folder-sequences folder t))
        !          1632:               (mh-notate-user-sequences)
        !          1633:               (keep-lines mh-valid-scan-line)
        !          1634:               (mh-make-folder-mode-line)
        !          1635:               (mh-goto-cur-msg)
        !          1636:               (setq return-value t))))
        !          1637:       return-value)))
        !          1638: 
        !          1639: 
        !          1640: (defun mh-make-folder-mode-line (&optional annotation)
        !          1641:   ;; Set the fields of the mode line for a folder buffer.
        !          1642:   ;; The optional ANNOTATION string is displayed after the folder's name.
        !          1643:   (save-excursion
        !          1644:     (mh-first-msg)
        !          1645:     (setq mh-first-msg-num (mh-get-msg-num nil))
        !          1646:     (mh-last-msg)
        !          1647:     (setq mh-last-msg-num (mh-get-msg-num nil))
        !          1648:     (let ((lines (count-lines (point-min) (point-max))))
        !          1649:       (setq mode-line-buffer-identification
        !          1650:            (list (format "{%%b%s}  %d msg%s"
        !          1651:                          (if annotation (format "/%s" annotation) "")
        !          1652:                          lines
        !          1653:                          (if (zerop lines)
        !          1654:                              "s"
        !          1655:                              (if (> lines 1)
        !          1656:                                  (format "s (%d-%d)" mh-first-msg-num
        !          1657:                                          mh-last-msg-num)
        !          1658:                                  (format " (%d)" mh-first-msg-num)))))))))
        !          1659: 
        !          1660: 
        !          1661: (defun mh-unmark-all-headers (remove-all-flags)
        !          1662:   ;; Remove all '+' flags from the headers, and if called with a non-nil
        !          1663:   ;; argument, remove all 'D', '^' and '%' flags too.
        !          1664:   ;; Optimized for speed (i.e., no regular expressions).
        !          1665:   (save-excursion
        !          1666:     (let ((case-fold-search nil)
        !          1667:          (last-line (- (point-max) mh-cmd-note))
        !          1668:          char)
        !          1669:       (mh-first-msg)
        !          1670:       (while (<= (point) last-line)
        !          1671:        (forward-char mh-cmd-note)
        !          1672:        (setq char (following-char))
        !          1673:        (if (or (and remove-all-flags
        !          1674:                     (or (eql char ?D)
        !          1675:                         (eql char ?^)
        !          1676:                         (eql char ?%)))
        !          1677:                (eql char ?+))
        !          1678:            (progn
        !          1679:              (delete-char 1)
        !          1680:              (insert " ")))
        !          1681:        (forward-line)))))
        !          1682: 
        !          1683: 
        !          1684: (defun mh-goto-cur-msg ()
        !          1685:   ;; Position the cursor at the current message.
        !          1686:   (let ((cur-msg (car (mh-seq-to-msgs 'cur))))
        !          1687:     (cond ((and cur-msg
        !          1688:                (mh-goto-msg cur-msg t nil))
        !          1689:           (mh-notate nil ?+ mh-cmd-note)
        !          1690:           (mh-recenter 0)
        !          1691:           (mh-maybe-show cur-msg))
        !          1692:          (t
        !          1693:           (mh-last-msg)
        !          1694:           (message "No current message")))))
        !          1695: 
        !          1696: 
        !          1697: (defun mh-pack-folder-1 (range)
        !          1698:   ;; Close and pack the current folder.
        !          1699:   (mh-process-or-undo-commands mh-current-folder)
        !          1700:   (message "Packing folder...")
        !          1701:   (mh-set-folder-modified-p t)         ; lock folder while packing
        !          1702:   (save-excursion
        !          1703:     (mh-exec-cmd-quiet " *mh-temp*" "folder" mh-current-folder "-pack"))
        !          1704:   (mh-regenerate-headers range))
        !          1705: 
        !          1706: 
        !          1707: (defun mh-process-or-undo-commands (folder)
        !          1708:   ;; If FOLDER has outstanding commands, then either process or discard them.
        !          1709:   (set-buffer folder)
        !          1710:   (if (mh-outstanding-commands-p)
        !          1711:       (if (or mh-do-not-confirm
        !          1712:              (y-or-n-p
        !          1713:                "Process outstanding deletes and refiles (or lose them)? "))
        !          1714:          (mh-process-commands folder)
        !          1715:          (mh-undo-folder))
        !          1716:       (mh-invalidate-show-buffer)))
        !          1717: 
        !          1718: 
        !          1719: (defun mh-process-commands (folder)
        !          1720:   ;; Process outstanding commands for the folder FOLDER.
        !          1721:   (message "Processing deletes and refiles for %s..." folder)
        !          1722:   (set-buffer folder)
        !          1723:   (with-mh-folder-updating (nil)
        !          1724:     ;; Update the unseen sequence if it exists
        !          1725:     (if (and mh-seen-list (mh-seq-to-msgs mh-unseen-seq))
        !          1726:        (mh-undefine-sequence mh-unseen-seq mh-seen-list))
        !          1727: 
        !          1728:     ;; Then refile messages
        !          1729:     (mh-mapc
        !          1730:      (function
        !          1731:       (lambda (dest)
        !          1732:        (let ((msgs (mh-seq-to-msgs dest)))
        !          1733:          (mh-when msgs
        !          1734:            (apply 'mh-exec-cmd "refile"
        !          1735:                   "-src" folder (symbol-name dest) msgs)
        !          1736:            (mh-delete-scan-msgs msgs)))))
        !          1737:      mh-refile-list)
        !          1738: 
        !          1739:     ;; Now delete messages
        !          1740:     (mh-when mh-delete-list
        !          1741:       (apply 'mh-exec-cmd "rmm" folder mh-delete-list)
        !          1742:       (mh-delete-scan-msgs mh-delete-list))
        !          1743: 
        !          1744:     ;; Don't need to remove sequences since delete and refile do so.
        !          1745: 
        !          1746:     ;; Mark cur message
        !          1747:     (if (> (buffer-size) 0)
        !          1748:        (mh-define-sequence 'cur (list (or (mh-get-msg-num nil) "last"))))
        !          1749: 
        !          1750:     (mh-invalidate-show-buffer)
        !          1751: 
        !          1752:     (setq mh-delete-list nil
        !          1753:          mh-refile-list nil
        !          1754:          mh-seq-list (mh-read-folder-sequences mh-current-folder nil)
        !          1755:          mh-seen-list nil)
        !          1756:     (mh-unmark-all-headers t)
        !          1757:     (mh-notate-user-sequences)
        !          1758:     (message "Processing deletes and refiles for %s...done" folder)))
        !          1759: 
        !          1760: 
        !          1761: (defun mh-delete-scan-msgs (msgs)
        !          1762:   ;; Delete the scan listing lines for each of the msgs in the LIST.
        !          1763:   ;; Optimized for speed (i.e., no regular expressions).
        !          1764:   (setq msgs (sort msgs (function <))) ;okay to clobber msgs
        !          1765:   (save-excursion
        !          1766:     (mh-first-msg)
        !          1767:     (while (and msgs (< (point) (point-max)))
        !          1768:       (cond ((equal (mh-get-msg-num nil) (car msgs))
        !          1769:             (delete-region (point) (save-excursion (forward-line) (point)))
        !          1770:             (setq msgs (cdr msgs)))
        !          1771:            (t
        !          1772:             (forward-line))))))
        !          1773: 
        !          1774: 
        !          1775: (defun mh-set-folder-modified-p (flag)
        !          1776:   "Mark current folder as modified or unmodified according to FLAG."
        !          1777:   (set-buffer-modified-p flag))
        !          1778: 
        !          1779: 
        !          1780: (defun mh-outstanding-commands-p ()
        !          1781:   ;; Returns non-nil if there are outstanding deletes or refiles.
        !          1782:   (or mh-delete-list mh-refile-list))
        !          1783: 
        !          1784: 
        !          1785: 
        !          1786: ;;; Mode for composing and sending a draft message.
        !          1787: 
        !          1788: (defvar mh-sent-from-folder nil
        !          1789:   "Folder of msg associated with this letter.")
        !          1790: 
        !          1791: (defvar mh-sent-from-msg nil
        !          1792:   "Number of msg associated with this letter.")
        !          1793: 
        !          1794: (defvar mh-send-args nil
        !          1795:   "Extra arguments to pass to \"send\" command.")
        !          1796: 
        !          1797: (defvar mh-annotate-char nil
        !          1798:   "Character to use to annotate mh-sent-from-msg.")
        !          1799: 
        !          1800: (defvar mh-annotate-field nil
        !          1801:   "Field name for message annotation.")
        !          1802: 
        !          1803: (defun mh-letter-mode ()
        !          1804:   "Mode for composing letters in mh-e.
        !          1805: When you have finished composing, type \\[mh-send-letter] to send the letter.
        !          1806: 
        !          1807: Variables controlling this mode (defaults in parentheses):
        !          1808: 
        !          1809:  mh-delete-yanked-msg-window (nil)
        !          1810:     If non-nil, \\[mh-yank-cur-msg] will delete any windows displaying
        !          1811:     the yanked message.
        !          1812: 
        !          1813:  mh-yank-from-start-of-msg (t)
        !          1814:     If non-nil, \\[mh-yank-cur-msg] will include the entire message.
        !          1815:     If `body', just yank the body (no header).
        !          1816:     If nil, only the portion of the message following the point will be yanked.
        !          1817:     If there is a region, this variable is ignored.
        !          1818: 
        !          1819: Upon invoking mh-letter-mode, text-mode-hook and mh-letter-mode-hook are
        !          1820: invoked with no args, if those values are non-nil.
        !          1821: 
        !          1822: \\{mh-letter-mode-map}"
        !          1823:   (interactive)
        !          1824:   (kill-all-local-variables)
        !          1825:   (make-local-variable 'paragraph-start)
        !          1826:   (setq paragraph-start (concat "^[ \t]*[-_][-_][-_]+$\\|" paragraph-start))
        !          1827:   (make-local-variable 'paragraph-separate)
        !          1828:   (setq paragraph-separate
        !          1829:        (concat "^[ \t]*[-_][-_][-_]+$\\|" paragraph-separate))
        !          1830:   (make-local-variable 'mh-send-args)
        !          1831:   (make-local-variable 'mh-annotate-char)
        !          1832:   (make-local-variable 'mh-annotate-field)
        !          1833:   (make-local-variable 'mh-previous-window-config)
        !          1834:   (make-local-variable 'mh-sent-from-folder)
        !          1835:   (make-local-variable 'mh-sent-from-msg)
        !          1836:   (use-local-map mh-letter-mode-map)
        !          1837:   (setq major-mode 'mh-letter-mode)
        !          1838:   (mh-set-mode-name "mh-e letter")
        !          1839:   (set-syntax-table mh-letter-mode-syntax-table)
        !          1840:   (run-hooks 'text-mode-hook 'mh-letter-mode-hook)
        !          1841:   (mh-when auto-fill-hook
        !          1842:     (make-local-variable 'auto-fill-hook)
        !          1843:     (setq auto-fill-hook 'mh-auto-fill-for-letter)))
        !          1844: 
        !          1845: 
        !          1846: (defun mh-auto-fill-for-letter ()
        !          1847:   ;; Auto-fill in letters treats the header specially by inserting a tab
        !          1848:   ;; before continuation line.
        !          1849:   (do-auto-fill)
        !          1850:   (if (mh-in-header-p)
        !          1851:       (save-excursion
        !          1852:        (beginning-of-line nil)
        !          1853:        (insert-char ?\t 1))))
        !          1854: 
        !          1855: 
        !          1856: (defun mh-in-header-p ()
        !          1857:   ;; Return non-nil if the point is in the header of a draft message.
        !          1858:   (save-excursion
        !          1859:     (let ((cur-point (point)))
        !          1860:       (goto-char (dot-min))
        !          1861:       (re-search-forward "^--------" nil t)
        !          1862:       (< cur-point (point)))))
        !          1863: 
        !          1864: 
        !          1865: (defun mh-to-field ()
        !          1866:   "Move point to the end of a specified header field.
        !          1867: The field is indicated by the previous keystroke.  Create the field if
        !          1868: it does not exist.  Set the mark to point before moving."
        !          1869:   (interactive)
        !          1870:   (expand-abbrev)
        !          1871:   (let ((target (cdr (assoc (logior last-input-char ?`) mh-to-field-choices)))
        !          1872:        (case-fold-search t))
        !          1873:     (cond ((mh-position-on-field target t)
        !          1874:           (let ((eol (point)))
        !          1875:             (skip-chars-backward " \t")
        !          1876:             (delete-region (point) eol))
        !          1877:           (if (and (not (eq (logior last-input-char ?`) ?s))
        !          1878:                    (save-excursion
        !          1879:                      (backward-char 1)
        !          1880:                      (not (looking-at "[:,]"))))
        !          1881:               (insert ", ")
        !          1882:               (insert " ")))
        !          1883:          (t
        !          1884:           (goto-char (dot-min))
        !          1885:           (re-search-forward "^To:")
        !          1886:           (forward-line 1)
        !          1887:           (while (looking-at "^[ \t]") (forward-line 1))
        !          1888:           (insert (format "%s \n" target))
        !          1889:           (backward-char 1)))))
        !          1890: 
        !          1891: 
        !          1892: (defun mh-to-fcc ()
        !          1893:   "Insert an Fcc: field in the current message.
        !          1894: Prompt for the field name with a completion list of the current folders."
        !          1895:   (interactive)
        !          1896:   (let ((last-input-char ?\C-f)
        !          1897:         (folder (mh-prompt-for-folder "Fcc" "" t)))
        !          1898:     (expand-abbrev)
        !          1899:     (save-excursion
        !          1900:       (mh-to-field)
        !          1901:       (insert (substring folder 1 nil)))))
        !          1902: 
        !          1903: 
        !          1904: (defun mh-insert-signature ()
        !          1905:   "Insert the file ~/.signature at the current point."
        !          1906:   (interactive)
        !          1907:   (insert-file-contents "~/.signature")
        !          1908:   (set-buffer-modified-p (buffer-modified-p))) ; force mode line update
        !          1909: 
        !          1910: 
        !          1911: (defun mh-check-whom ()
        !          1912:   "Verify recipients of the current letter."
        !          1913:   (interactive)
        !          1914:   (let ((file-name (buffer-file-name)))
        !          1915:     (set-buffer-modified-p t)          ; Force writing of contents
        !          1916:     (save-buffer)
        !          1917:     (message "Checking recipients...")
        !          1918:     (switch-to-buffer-other-window "*Mail Recipients*")
        !          1919:     (bury-buffer (current-buffer))
        !          1920:     (erase-buffer)
        !          1921:     (mh-exec-cmd-output "whom" t file-name)
        !          1922:     (other-window -1)
        !          1923:     (message "Checking recipients...done")))
        !          1924: 
        !          1925: 
        !          1926: 
        !          1927: ;;; Routines to make a search pattern and search for a message.
        !          1928: 
        !          1929: (defvar mh-searching-folder nil "Folder this pick is searching.")
        !          1930: 
        !          1931: 
        !          1932: (defun mh-make-pick-template ()
        !          1933:   ;; Initialize the current buffer with a template for a pick pattern.
        !          1934:   (erase-buffer)
        !          1935:   (kill-all-local-variables)
        !          1936:   (make-local-variable 'mh-searching-folder)
        !          1937:   (insert "From: \n"
        !          1938:          "To: \n"
        !          1939:          "Cc: \n"
        !          1940:          "Date: \n"
        !          1941:          "Subject: \n"
        !          1942:          "---------\n")
        !          1943:   (mh-letter-mode)
        !          1944:   (use-local-map mh-pick-mode-map)
        !          1945:   (goto-char (point-min))
        !          1946:   (end-of-line))
        !          1947: 
        !          1948: 
        !          1949: (defun mh-do-pick-search ()
        !          1950:   "Find messages that match the qualifications in the current pattern buffer.
        !          1951: Messages are searched for in the folder named in mh-searching-folder.
        !          1952: Put messages found in a sequence named `search'."
        !          1953:   (interactive)
        !          1954:   (let ((pattern-buffer (buffer-name))
        !          1955:        (searching-buffer mh-searching-folder)
        !          1956:        (range)
        !          1957:        (pattern nil)
        !          1958:        (new-buffer nil))
        !          1959:     (save-excursion
        !          1960:       (cond ((get-buffer searching-buffer)
        !          1961:             (set-buffer searching-buffer)
        !          1962:             (setq range (format "%d-%d" mh-first-msg-num mh-last-msg-num)))
        !          1963:            (t
        !          1964:             (mh-make-folder searching-buffer)
        !          1965:             (setq range "all")
        !          1966:             (setq new-buffer t))))
        !          1967:     (message "Searching...")
        !          1968:     (goto-char (point-min))
        !          1969:     (while (setq pattern (mh-next-pick-field pattern-buffer))
        !          1970:       (setq msgs (mh-seq-from-command searching-buffer
        !          1971:                                      'search
        !          1972:                                      (nconc (cons "pick" pattern)
        !          1973:                                             (list searching-buffer
        !          1974:                                                   range
        !          1975:                                                   "-sequence" "search"
        !          1976:                                                   "-list"))))
        !          1977:       (setq range "search"))
        !          1978:     (message "Searching...done")
        !          1979:     (if new-buffer
        !          1980:        (mh-scan-folder searching-buffer msgs)
        !          1981:        (switch-to-buffer searching-buffer))
        !          1982:     (delete-other-windows)
        !          1983:     (mh-notate-seq 'search ?% (1+ mh-cmd-note))))
        !          1984: 
        !          1985: 
        !          1986: (defun mh-next-pick-field (buffer)
        !          1987:   ;; Return the next piece of a pick argument that can be extracted from the
        !          1988:   ;; BUFFER.  Returns nil if no pieces remain.
        !          1989:   (set-buffer buffer)
        !          1990:   (let ((case-fold-search t))
        !          1991:     (cond ((eobp)
        !          1992:           nil)
        !          1993:          ((re-search-forward "^\\([a-z].*\\):[ \t]*\\([a-z0-9].*\\)$" nil t)
        !          1994:           (let* ((component
        !          1995:                   (format "--%s"
        !          1996:                           (downcase (buffer-substring (match-beginning 1)
        !          1997:                                                       (match-end 1)))))
        !          1998:                  (pat (buffer-substring (match-beginning 2) (match-end 2))))
        !          1999:               (forward-line 1)
        !          2000:               (list component pat)))
        !          2001:          ((re-search-forward "^-*$" nil t)
        !          2002:           (forward-char 1)
        !          2003:           (let ((body (buffer-substring (point) (point-max))))
        !          2004:             (if (and (> (length body) 0) (not (equal body "\n")))
        !          2005:                 (list "-search" body)
        !          2006:                 nil)))
        !          2007:          (t
        !          2008:           nil))))
        !          2009: 
        !          2010: 
        !          2011: 
        !          2012: ;;; Routines to compose and send a letter.
        !          2013: 
        !          2014: (defun mh-compose-and-send-mail (draft send-args
        !          2015:                                       sent-from-folder sent-from-msg
        !          2016:                                       to subject cc
        !          2017:                                       annotate-char annotate-field
        !          2018:                                       config)
        !          2019:   ;; Edit and compose a draft message in buffer DRAFT and send or save it.
        !          2020:   ;; SENT-FROM-FOLDER is buffer containing scan listing of current folder, or
        !          2021:   ;; nil if none exists.
        !          2022:   ;; SENT-FROM-MSG is the message number or sequence name or nil.
        !          2023:   ;; SEND-ARGS is an optional argument passed to the send command.
        !          2024:   ;; The TO, SUBJECT, and CC fields are passed to the
        !          2025:   ;; mh-compose-letter-function.
        !          2026:   ;; If ANNOTATE-CHAR is non-null, it is used to notate the scan listing of the
        !          2027:   ;; message.  In that case, the ANNOTATE-FIELD is used to build a string
        !          2028:   ;; for mh-annotate-msg.
        !          2029:   ;; CONFIG is the window configuration to restore after sending the letter.
        !          2030:   (pop-to-buffer draft)
        !          2031:   (mh-letter-mode)
        !          2032:   (setq mh-sent-from-folder sent-from-folder)
        !          2033:   (setq mh-sent-from-msg sent-from-msg)
        !          2034:   (setq mh-send-args send-args)
        !          2035:   (setq mh-annotate-char annotate-char)
        !          2036:   (setq mh-annotate-field annotate-field)
        !          2037:   (setq mh-previous-window-config config)
        !          2038:   (setq mode-line-buffer-identification (list "{%b}"))
        !          2039:   (if (and (boundp 'mh-compose-letter-function)
        !          2040:           (symbol-value 'mh-compose-letter-function))
        !          2041:       ;; run-hooks will not pass arguments.
        !          2042:       (let ((value (symbol-value 'mh-compose-letter-function)))
        !          2043:        (if (and (listp value) (not (eq (car value) 'lambda)))
        !          2044:            (while value
        !          2045:              (funcall (car value) to subject cc)
        !          2046:              (setq value (cdr value)))
        !          2047:            (funcall mh-compose-letter-function to subject cc)))))
        !          2048: 
        !          2049: 
        !          2050: (defun mh-send-letter (&optional arg)
        !          2051:   "Send the draft letter in the current buffer.
        !          2052: If optional prefix argument is provided, monitor delivery.
        !          2053: Run mh-before-send-letter-hook before doing anything."
        !          2054:   (interactive "P")
        !          2055:   (run-hooks 'mh-before-send-letter-hook)
        !          2056:   (set-buffer-modified-p t)            ; Make sure buffer is written
        !          2057:   (save-buffer)
        !          2058:   (message "Sending...")
        !          2059:   (let ((draft-buffer (current-buffer))
        !          2060:        (file-name (buffer-file-name))
        !          2061:        (config mh-previous-window-config))
        !          2062:     (cond (arg
        !          2063:           (pop-to-buffer "MH mail delivery")
        !          2064:           (erase-buffer)
        !          2065:           (if mh-send-args
        !          2066:               (mh-exec-cmd-output "send" t "-watch" "-nopush"
        !          2067:                                   "-nodraftfolder" mh-send-args file-name)
        !          2068:               (mh-exec-cmd-output "send" t "-watch" "-nopush"
        !          2069:                                   "-nodraftfolder" file-name))
        !          2070:           (goto-char (point-max))      ; show the interesting part
        !          2071:           (recenter -1)
        !          2072:           (set-buffer draft-buffer))   ; for annotation below
        !          2073:          (mh-send-args
        !          2074:           (mh-exec-cmd-daemon "send" "-nodraftfolder" "-noverbose"
        !          2075:                               mh-send-args file-name))
        !          2076:          (t
        !          2077:           (mh-exec-cmd-daemon "send" "-nodraftfolder" "-noverbose"
        !          2078:                               file-name)))
        !          2079: 
        !          2080:     (if mh-annotate-char
        !          2081:        (mh-annotate-msg mh-sent-from-msg
        !          2082:                         mh-sent-from-folder
        !          2083:                         mh-annotate-char
        !          2084:                         "-component" mh-annotate-field
        !          2085:                         "-text" (format "\"%s %s\""
        !          2086:                                         (mh-get-field "To:")
        !          2087:                                         (mh-get-field "Cc:"))))
        !          2088: 
        !          2089:     (mh-when (or (not arg)
        !          2090:                 (y-or-n-p "Kill draft buffer? "))
        !          2091:       (kill-buffer draft-buffer)
        !          2092:       (if config
        !          2093:          (set-window-configuration config)))
        !          2094:     (message "Sending...done")))
        !          2095: 
        !          2096: 
        !          2097: (defun mh-insert-letter (prefix-provided folder msg)
        !          2098:   "Insert a message from any folder into the current letter.
        !          2099: Removes the message's headers using mh-invisible-headers.
        !          2100: Prefixes each non-blank line with mh-ins-buf-prefix (default \">> \").
        !          2101: If optional prefix argument provided, do not indent and do not delete
        !          2102: headers.  Leaves the mark before the letter and point after it."
        !          2103:   (interactive
        !          2104:    (list current-prefix-arg
        !          2105:         (mh-prompt-for-folder "Message from" mh-sent-from-folder nil)
        !          2106:         (read-input (format "Message number%s: "
        !          2107:                             (if mh-sent-from-msg
        !          2108:                                 (format " [%d]" mh-sent-from-msg)
        !          2109:                                 "")))))
        !          2110:   (save-restriction
        !          2111:     (narrow-to-region (point) (point))
        !          2112:     (let ((start (point-min)))
        !          2113:       (if (equal msg "") (setq msg (int-to-string mh-sent-from-msg)))
        !          2114:       (mh-exec-lib-cmd-output "mhl" "-nobell" "-noclear"
        !          2115:                              (expand-file-name msg
        !          2116:                                                (mh-expand-file-name folder)))
        !          2117:       (mh-when (not prefix-provided)
        !          2118:        (mh-clean-msg-header start mh-invisible-headers mh-visible-headers)
        !          2119:        (set-mark start)                ; since mh-clean-msg-header moves it
        !          2120:        (mh-insert-prefix-string mh-ins-buf-prefix)))))
        !          2121: 
        !          2122: 
        !          2123: (defun mh-yank-cur-msg ()
        !          2124:   "Insert the current message into the draft buffer.
        !          2125: Prefix each non-blank line in the message with the string in
        !          2126: `mh-ins-buf-prefix'.  If a region is set in the message's buffer, then
        !          2127: only the region will be inserted.  Otherwise, the entire message will
        !          2128: be inserted if `mh-yank-from-start-of-msg' is non-nil.  If this variable
        !          2129: is nil, the portion of the message following the point will be yanked.
        !          2130: If `mh-delete-yanked-msg-window' is non-nil, any window displaying the
        !          2131: yanked message will be deleted."
        !          2132:   (interactive)
        !          2133:   (if (and mh-sent-from-folder mh-sent-from-msg)
        !          2134:       (let ((to-point (point))
        !          2135:            (to-buffer (current-buffer)))
        !          2136:        (set-buffer mh-sent-from-folder)
        !          2137:        (if mh-delete-yanked-msg-window
        !          2138:            (delete-windows-on mh-show-buffer))
        !          2139:        (set-buffer mh-show-buffer)     ; Find displayed message
        !          2140:        (let ((mh-ins-str (cond ((mark)
        !          2141:                                 (buffer-substring (region-beginning)
        !          2142:                                                   (region-end)))
        !          2143:                                ((eq 'body mh-yank-from-start-of-msg)
        !          2144:                                 (buffer-substring
        !          2145:                                  (save-excursion
        !          2146:                                    (goto-char (point-min))
        !          2147:                                    (mh-goto-header-end 1)
        !          2148:                                    (point))
        !          2149:                                  (point-max)))
        !          2150:                                (mh-yank-from-start-of-msg
        !          2151:                                 (buffer-substring (point-min) (point-max)))
        !          2152:                                (t
        !          2153:                                 (buffer-substring (point) (point-max))))))
        !          2154:          (set-buffer to-buffer)
        !          2155:          (narrow-to-region to-point to-point)
        !          2156:          (push-mark)
        !          2157:          (insert mh-ins-str)
        !          2158:          (mh-insert-prefix-string mh-ins-buf-prefix)
        !          2159:          (insert "\n")
        !          2160:          (widen)))
        !          2161:       (error "There is no current message")))
        !          2162: 
        !          2163: 
        !          2164: (defun mh-insert-prefix-string (mh-ins-string)
        !          2165:   ;; Run MH-YANK-HOOK to insert a prefix string before each line in the buffer.
        !          2166:   ;; Generality for supercite users.
        !          2167:   (save-excursion
        !          2168:     (set-mark (point-max))
        !          2169:     (goto-char (point-min))
        !          2170:     (run-hooks 'mh-yank-hooks)))
        !          2171: 
        !          2172: 
        !          2173: (defun mh-fully-kill-draft ()
        !          2174:   "Kill the draft message file and the draft message buffer.
        !          2175: Use \\[kill-buffer] if you don't want to delete the draft message file."
        !          2176:   (interactive)
        !          2177:   (if (y-or-n-p "Kill draft message? ")
        !          2178:       (let ((config mh-previous-window-config))
        !          2179:        (if (file-exists-p (buffer-file-name))
        !          2180:            (delete-file (buffer-file-name)))
        !          2181:        (set-buffer-modified-p nil)
        !          2182:        (kill-buffer (buffer-name))
        !          2183:        (message "")
        !          2184:        (if config
        !          2185:            (set-window-configuration config)))
        !          2186:     (error "Message not killed")))
        !          2187: 
        !          2188: 
        !          2189: (defun mh-recenter (arg)
        !          2190:   ;; Like recenter but with two improvements: nil arg means recenter,
        !          2191:   ;; and only does anything if the current buffer is in the selected
        !          2192:   ;; window.  (Commands like save-some-buffers can make this false.)
        !          2193:   (if (eql (get-buffer-window (current-buffer))
        !          2194:           (selected-window))
        !          2195:       (recenter (if arg arg '(t)))))
        !          2196: 
        !          2197: 
        !          2198: 
        !          2199: ;;; Commands to manipulate sequences.  Sequences are stored in an alist
        !          2200: ;;; of the form:
        !          2201: ;;;    ((seq-name msgs ...) (seq-name msgs ...) ...)
        !          2202: 
        !          2203: (defun mh-make-seq (name msgs) (cons name msgs))
        !          2204: 
        !          2205: (defmacro mh-seq-name (pair) (list 'car pair))
        !          2206: 
        !          2207: (defmacro mh-seq-msgs (pair) (list 'cdr pair))
        !          2208: 
        !          2209: (defun mh-find-seq (name) (assoc name mh-seq-list))
        !          2210: 
        !          2211: 
        !          2212: (defun mh-seq-to-msgs (seq)
        !          2213:   "Return a list of the messages in SEQUENCE."
        !          2214:   (mh-seq-msgs (mh-find-seq seq)))
        !          2215: 
        !          2216: 
        !          2217: (defun mh-seq-containing-msg (msg)
        !          2218:   ;; Return a list of the sequences containing MESSAGE.
        !          2219:   (let ((l mh-seq-list)
        !          2220:        (seqs ()))
        !          2221:     (while l
        !          2222:       (if (memq msg (mh-seq-msgs (car l)))
        !          2223:          (mh-push (mh-seq-name (car l)) seqs))
        !          2224:       (setq l (cdr l)))
        !          2225:     seqs))
        !          2226: 
        !          2227: 
        !          2228: (defun mh-msg-to-seq (msg)
        !          2229:   ;; Given a MESSAGE number, return the first sequence in which it occurs.
        !          2230:   (car (mh-seq-containing-msg msg)))
        !          2231: 
        !          2232: 
        !          2233: (defun mh-read-seq-default (prompt not-empty)
        !          2234:   ;; Read and return sequence name with default narrowed or previous sequence.
        !          2235:   (mh-read-seq prompt not-empty (or mh-narrowed-to-seq mh-previous-seq)))
        !          2236: 
        !          2237: 
        !          2238: (defun mh-read-seq (prompt not-empty &optional default)
        !          2239:   ;; Read and return a sequence name.  Prompt with PROMPT, raise an error
        !          2240:   ;; if the sequence is empty and the NOT-EMPTY flag is non-nil, and supply
        !          2241:   ;; an optional DEFAULT sequence.
        !          2242:   ;; A reply of '%' defaults to the first sequence containing the current
        !          2243:   ;; message.
        !          2244:   (let* ((input (completing-read (format "%s %s %s" prompt "sequence:"
        !          2245:                                         (if default
        !          2246:                                             (format "[%s] " default)
        !          2247:                                             ""))
        !          2248:                                 (mh-seq-names mh-seq-list)))
        !          2249:         (seq (cond ((equal input "%") (mh-msg-to-seq (mh-get-msg-num t)))
        !          2250:                    ((equal input "") default)
        !          2251:                    (t (intern input))))
        !          2252:         (msgs (mh-seq-to-msgs seq)))
        !          2253:     (if (and (null msgs) not-empty)
        !          2254:        (error (format "No messages in sequence `%s'" seq)))
        !          2255:     seq))
        !          2256: 
        !          2257: 
        !          2258: (defun mh-read-folder-sequences (folder define-sequences)
        !          2259:   ;; Read and return the predefined sequences for a FOLDER.  If
        !          2260:   ;; DEFINE-SEQUENCES is non-nil, then define mh-e's sequences before
        !          2261:   ;; reading MH's sequences.
        !          2262:   (let ((seqs ()))
        !          2263:     (mh-when define-sequences
        !          2264:       (mh-define-sequences mh-seq-list)
        !          2265:       (mh-mapc (function (lambda (seq) ; Save the internal sequences
        !          2266:                           (if (mh-folder-name-p (mh-seq-name seq))
        !          2267:                               (mh-push seq seqs))))
        !          2268:               mh-seq-list))
        !          2269:     (save-excursion
        !          2270:       (mh-exec-cmd-quiet " *mh-temp*" "mark" folder "-list")
        !          2271:       (goto-char (point-min))
        !          2272:       ;; look for name in line of form "cur: 4" or "myseq (private): 23"
        !          2273:       (while (re-search-forward "^[^: ]+" nil t)
        !          2274:        (mh-push (mh-make-seq (intern (buffer-substring (match-beginning 0)
        !          2275:                                                        (match-end 0)))
        !          2276:                              (mh-read-msg-list))
        !          2277:                 seqs))
        !          2278:       (delete-region (point-min) (point))) ; avoid race with mh-process-daemon
        !          2279:     seqs))
        !          2280: 
        !          2281: 
        !          2282: (defun mh-seq-names (seq-list)
        !          2283:   ;; Return an alist containing the names of the SEQUENCES.
        !          2284:   (mapcar (function (lambda (entry) (list (symbol-name (mh-seq-name entry)))))
        !          2285:          seq-list))
        !          2286: 
        !          2287: 
        !          2288: (defun mh-seq-from-command (folder seq seq-command)
        !          2289:   ;; In FOLDER, make a sequence named SEQ by executing COMMAND.
        !          2290:   ;; COMMAND is a list.  The first element is a program name
        !          2291:   ;; and the subsequent elements are its arguments, all strings.
        !          2292:   (let ((msg)
        !          2293:        (msgs ())
        !          2294:        (case-fold-search t))
        !          2295:     (save-excursion
        !          2296:       (save-window-excursion
        !          2297:        (apply 'mh-exec-cmd-quiet " *mh-temp*" seq-command)
        !          2298:        (goto-char (point-min))
        !          2299:        (while (setq msg (car (mh-read-msg-list)))
        !          2300:          (mh-push msg msgs)
        !          2301:          (forward-line 1)))
        !          2302:       (set-buffer folder)
        !          2303:       (setq msgs (nreverse msgs))      ; Put in ascending order
        !          2304:       (mh-push (mh-make-seq seq msgs) mh-seq-list)
        !          2305:       msgs)))
        !          2306: 
        !          2307: 
        !          2308: (defun mh-read-msg-list ()
        !          2309:   ;; Return a list of message numbers from the current point to the end of
        !          2310:   ;; the line.
        !          2311:   (let ((msgs ())
        !          2312:        (end-of-line (save-excursion (end-of-line) (point)))
        !          2313:        num)
        !          2314:     (while (re-search-forward "[0-9]+" end-of-line t)
        !          2315:       (setq num (string-to-int (buffer-substring (match-beginning 0)
        !          2316:                                                 (match-end 0))))
        !          2317:       (cond ((looking-at "-")          ; Message range
        !          2318:             (forward-char 1)
        !          2319:             (re-search-forward "[0-9]+" end-of-line t)
        !          2320:             (let ((num2 (string-to-int (buffer-substring (match-beginning 0)
        !          2321:                                                          (match-end 0)))))
        !          2322:               (if (< num2 num)
        !          2323:                   (error "Bad message range: %d-%d" num num2))
        !          2324:               (while (<= num num2)
        !          2325:                 (mh-push num msgs)
        !          2326:                 (setq num (1+ num)))))
        !          2327:            ((not (zerop num)) (mh-push num msgs))))
        !          2328:     msgs))
        !          2329: 
        !          2330: 
        !          2331: (defun mh-remove-seq (seq)
        !          2332:   ;; Delete the SEQUENCE.
        !          2333:   (mh-map-to-seq-msgs 'mh-notate-if-in-one-seq seq ?  (1+ mh-cmd-note) seq)
        !          2334:   (mh-undefine-sequence seq (list "all"))
        !          2335:   (mh-delete-seq-locally seq))
        !          2336: 
        !          2337: 
        !          2338: (defun mh-delete-seq-locally (seq)
        !          2339:   ;; Remove mh-e's record of SEQUENCE.
        !          2340:   (let ((entry (mh-find-seq seq)))
        !          2341:     (setq mh-seq-list (delq entry mh-seq-list))))
        !          2342: 
        !          2343: 
        !          2344: (defun mh-remove-msg-from-seq (msg seq &optional internal-flag)
        !          2345:   ;; Remove MESSAGE from the SEQUENCE.  If optional FLAG is non-nil, do not
        !          2346:   ;; inform MH of the change.
        !          2347:   (let ((entry (mh-find-seq seq)))
        !          2348:     (mh-when entry
        !          2349:       (mh-notate-if-in-one-seq msg ?  (1+ mh-cmd-note) (mh-seq-name entry))
        !          2350:       (if (not internal-flag)
        !          2351:          (mh-undefine-sequence seq (list msg)))
        !          2352:       (setcdr entry (delq msg (mh-seq-msgs entry))))))
        !          2353: 
        !          2354: 
        !          2355: (defun mh-add-msgs-to-seq (msgs seq &optional internal-flag)
        !          2356:   ;; Add MESSAGE(s) to the SEQUENCE.  If optional FLAG is non-nil, do not mark
        !          2357:   ;; the message in the scan listing or inform MH of the addition.
        !          2358:   (let ((entry (mh-find-seq seq)))
        !          2359:     (if (and msgs (atom msgs)) (setq msgs (list msgs)))
        !          2360:     (if (null entry)
        !          2361:        (mh-push (mh-make-seq seq msgs) mh-seq-list)
        !          2362:        (if msgs (setcdr entry (append msgs (cdr entry)))))
        !          2363:     (mh-when (not internal-flag)
        !          2364:       (mh-add-to-sequence seq msgs)
        !          2365:       (mh-notate-seq seq ?% (1+ mh-cmd-note)))))
        !          2366: 
        !          2367: 
        !          2368: (defun mh-rename-seq (seq new-name)
        !          2369:   "Rename a SEQUENCE to have a new NAME."
        !          2370:   (interactive "SOld sequence name: \nSNew name: ")
        !          2371:   (let ((old-seq (mh-find-seq seq)))
        !          2372:     (if old-seq
        !          2373:        (rplaca old-seq new-name)
        !          2374:        (error "Sequence %s does not exists" seq))
        !          2375:     (mh-undefine-sequence seq (mh-seq-msgs old-seq))
        !          2376:     (mh-define-sequence new-name (mh-seq-msgs old-seq))))
        !          2377: 
        !          2378: 
        !          2379: (defun mh-notate-user-sequences ()
        !          2380:   ;; Mark the scan listing of all messages in user-defined sequences.
        !          2381:   (let ((seqs mh-seq-list)
        !          2382:        name)
        !          2383:     (while seqs
        !          2384:       (setq name (mh-seq-name (car seqs)))
        !          2385:       (if (not (mh-internal-seq name))
        !          2386:          (mh-notate-seq name ?% (1+ mh-cmd-note)))
        !          2387:       (setq seqs (cdr seqs)))))
        !          2388: 
        !          2389: 
        !          2390: (defun mh-internal-seq (name)
        !          2391:   ;; Return non-NIL if NAME is the name of an internal mh-e sequence.
        !          2392:   (or (memq name '(answered cur deleted forwarded printed))
        !          2393:       (eq name mh-unseen-seq)
        !          2394:       (mh-folder-name-p name)))
        !          2395: 
        !          2396: 
        !          2397: (defun mh-folder-name-p (name)
        !          2398:   ;; Return non-NIL if NAME is possibly the name of a folder.
        !          2399:   ;; A name (a string or symbol) can be a folder name if it begins with "+".
        !          2400:   (if (symbolp name)
        !          2401:       (eql (aref (symbol-name name) 0) ?+)
        !          2402:       (eql (aref name 0) ?+)))
        !          2403: 
        !          2404: 
        !          2405: (defun mh-notate-seq (seq notation offset)
        !          2406:   ;; Mark the scan listing of all messages in the SEQUENCE with the CHARACTER
        !          2407:   ;; at the given OFFSET from the beginning of the listing line.
        !          2408:   (mh-map-to-seq-msgs 'mh-notate seq notation offset))
        !          2409: 
        !          2410: 
        !          2411: (defun mh-notate-if-in-one-seq (msg notation offset seq)
        !          2412:   ;; If the MESSAGE is in only the SEQUENCE, then mark the scan listing of the
        !          2413:   ;; message with the CHARACTER at the given OFFSET from the beginning of the
        !          2414:   ;; listing line.
        !          2415:   (let ((in-seqs (mh-seq-containing-msg msg)))
        !          2416:     (if (and (eq seq (car in-seqs)) (null (cdr in-seqs)))
        !          2417:        (mh-notate msg notation offset))))
        !          2418: 
        !          2419: 
        !          2420: (defun mh-map-to-seq-msgs (func seq &rest args)
        !          2421:   ;; Invoke the FUNCTION at each message in the SEQUENCE, passing the
        !          2422:   ;; remaining ARGS as arguments.
        !          2423:   (save-excursion
        !          2424:     (let ((msgs (mh-seq-to-msgs seq)))
        !          2425:       (while msgs
        !          2426:        (if (mh-goto-msg (car msgs) t t)
        !          2427:            (apply func (car msgs) args))
        !          2428:        (setq msgs (cdr msgs))))))
        !          2429: 
        !          2430: 
        !          2431: (defun mh-map-over-seqs (func seq-list)
        !          2432:   ;; Apply the FUNCTION to each element in the list of SEQUENCES,
        !          2433:   ;; passing the sequence name and the list of messages as arguments.
        !          2434:   (while seq-list
        !          2435:     (funcall func (mh-seq-name (car seq-list)) (mh-seq-msgs (car seq-list)))
        !          2436:     (setq seq-list (cdr seq-list))))
        !          2437: 
        !          2438: 
        !          2439: (defun mh-define-sequences (seq-list)
        !          2440:   ;; Define the sequences in SEQ-LIST.
        !          2441:   (mh-map-over-seqs 'mh-define-sequence seq-list))
        !          2442: 
        !          2443: 
        !          2444: (defun mh-add-to-sequence (seq msgs)
        !          2445:   ;; Add to a SEQUENCE each message the list of MSGS.
        !          2446:   (if (not (mh-folder-name-p seq))
        !          2447:       (if msgs
        !          2448:          (apply 'mh-exec-cmd "mark" mh-current-folder
        !          2449:                 "-sequence" (symbol-name seq)
        !          2450:                 "-add" msgs))))
        !          2451: 
        !          2452: 
        !          2453: (defun mh-define-sequence (seq msgs)
        !          2454:   ;; Define the SEQUENCE to contain the list of MSGS.  Do not mark
        !          2455:   ;; pseudo-sequences or empty sequences.
        !          2456:   (if (and msgs
        !          2457:           (not (mh-folder-name-p seq)))
        !          2458:       (save-excursion
        !          2459:        (apply 'mh-exec-cmd "mark" mh-current-folder
        !          2460:               "-sequence" (symbol-name seq)
        !          2461:               "-add" "-zero" (mh-list-to-string msgs)))))
        !          2462: 
        !          2463: 
        !          2464: (defun mh-undefine-sequence (seq msgs)
        !          2465:   ;; Remove from the SEQUENCE the list of MSGS.
        !          2466:   (apply 'mh-exec-cmd "mark" mh-current-folder
        !          2467:         "-sequence" (symbol-name seq)
        !          2468:         "-delete" msgs))
        !          2469: 
        !          2470: 
        !          2471: (defun mh-copy-seq-to-point (seq location)
        !          2472:   ;; Copy the scan listing of the messages in SEQUENCE to after the point
        !          2473:   ;; LOCATION in the current buffer.
        !          2474:   (mh-map-to-seq-msgs 'mh-copy-line-to-point seq location))
        !          2475: 
        !          2476: 
        !          2477: (defun mh-copy-line-to-point (msg location)
        !          2478:   ;; Copy the current line to the LOCATION in the current buffer.
        !          2479:   (beginning-of-line)
        !          2480:   (let ((beginning-of-line (point)))
        !          2481:     (forward-line 1)
        !          2482:     (copy-region-as-kill beginning-of-line (point))
        !          2483:     (goto-char location)
        !          2484:     (yank)
        !          2485:     (goto-char beginning-of-line)))
        !          2486: 
        !          2487: 
        !          2488: 
        !          2489: ;;; Issue commands to MH.
        !          2490: 
        !          2491: (defun mh-exec-cmd (command &rest args)
        !          2492:   ;; Execute MH command COMMAND with ARGS.
        !          2493:   ;; Any output is assumed to be an error and is shown to the user.
        !          2494:   (save-excursion
        !          2495:     (set-buffer " *mh-temp*")
        !          2496:     (erase-buffer)
        !          2497:     (apply 'call-process
        !          2498:           (expand-file-name command mh-progs) nil t nil
        !          2499:           (mh-list-to-string args))
        !          2500:     (if (> (buffer-size) 0)
        !          2501:        (save-window-excursion
        !          2502:          (switch-to-buffer-other-window " *mh-temp*")
        !          2503:          (sit-for 5)))))
        !          2504: 
        !          2505: 
        !          2506: (defun mh-exec-cmd-quiet (buffer command &rest args)
        !          2507:   ;; In BUFFER, execute MH command COMMAND with ARGS.
        !          2508:   ;; ARGS is a list of strings.  Return in BUFFER, if one exists.
        !          2509:   (mh-when (stringp buffer)
        !          2510:     (set-buffer buffer)
        !          2511:     (erase-buffer))
        !          2512:   (apply 'call-process
        !          2513:         (expand-file-name command mh-progs) nil buffer nil
        !          2514:         args))
        !          2515: 
        !          2516: 
        !          2517: (defun mh-exec-cmd-output (command display &rest args)
        !          2518:   ;; Execute MH command COMMAND with DISPLAY flag and ARGS putting the output
        !          2519:   ;; into buffer after point.  Set mark after inserted text.
        !          2520:   (push-mark (point) t)
        !          2521:   (apply 'call-process
        !          2522:         (expand-file-name command mh-progs) nil t display
        !          2523:         (mh-list-to-string args))
        !          2524:   (exchange-point-and-mark))
        !          2525: 
        !          2526: 
        !          2527: (defun mh-exec-cmd-daemon (command &rest args)
        !          2528:   ;; Execute MH command COMMAND with ARGS.  Any output from command is
        !          2529:   ;; displayed in an asynchronous pop-up window.
        !          2530:   (save-excursion
        !          2531:     (set-buffer (get-buffer-create " *mh-temp*"))
        !          2532:     (erase-buffer))
        !          2533:   (let* ((process-connection-type nil)
        !          2534:         (process (apply 'start-process
        !          2535:                         command nil
        !          2536:                         (expand-file-name command mh-progs)
        !          2537:                         (mh-list-to-string args))))
        !          2538:     (set-process-filter process 'mh-process-daemon)))
        !          2539: 
        !          2540: 
        !          2541: (defun mh-process-daemon (process output)
        !          2542:   ;; Process daemon that puts output into a temporary buffer.
        !          2543:   (set-buffer (get-buffer-create " *mh-temp*"))
        !          2544:   (insert-before-markers output)
        !          2545:   (display-buffer " *mh-temp*"))
        !          2546: 
        !          2547: 
        !          2548: (defun mh-exec-lib-cmd-output (command &rest args)
        !          2549:   ;; Execute MH library command COMMAND with ARGS.
        !          2550:   ;; Put the output into buffer after point.  Set mark after inserted text.
        !          2551:   (push-mark (point) t)
        !          2552:   (apply 'call-process
        !          2553:         (expand-file-name command mh-lib) nil t nil
        !          2554:         (mh-list-to-string args))
        !          2555:   (exchange-point-and-mark))
        !          2556: 
        !          2557: 
        !          2558: (defun mh-list-to-string (l)
        !          2559:   ;; Flattens the list L and makes every element of the new list into a string.
        !          2560:   (let ((new-list nil))
        !          2561:     (while l
        !          2562:       (cond ((null (car l)))
        !          2563:            ((symbolp (car l)) (mh-push (symbol-name (car l)) new-list))
        !          2564:            ((numberp (car l)) (mh-push (int-to-string (car l)) new-list))
        !          2565:            ((equal (car l) ""))
        !          2566:            ((stringp (car l)) (mh-push (car l) new-list))
        !          2567:            ((listp (car l))
        !          2568:             (setq new-list (nconc (nreverse (mh-list-to-string (car l)))
        !          2569:                                   new-list)))
        !          2570:            (t (error "Bad element in mh-list-to-string: %s" (car l))))
        !          2571:       (setq l (cdr l)))
        !          2572:     (nreverse new-list)))
        !          2573: 
        !          2574: 
        !          2575: 
        !          2576: ;;; Commands to annotate a message.
        !          2577: 
        !          2578: (defun mh-annotate-msg (msg buffer note &rest args)
        !          2579:   ;; Mark the MESSAGE in BUFFER listing with the character NOTE and annotate
        !          2580:   ;; the saved message with ARGS.
        !          2581:   (apply 'mh-exec-cmd "anno" buffer msg args)
        !          2582:   (save-excursion
        !          2583:     (cond ((get-buffer buffer)         ; Buffer may be deleted
        !          2584:           (set-buffer buffer)
        !          2585:           (if (symbolp msg)
        !          2586:               (mh-notate-seq msg note (1+ mh-cmd-note))
        !          2587:               (mh-notate msg note (1+ mh-cmd-note)))))))
        !          2588: 
        !          2589: 
        !          2590: (defun mh-notate (msg notation offset)
        !          2591:   ;; Marks MESSAGE with the character NOTATION at position OFFSET.
        !          2592:   ;; Null MESSAGE means the message that the cursor points to.
        !          2593:   (save-excursion
        !          2594:     (if (or (null msg)
        !          2595:            (mh-goto-msg msg t t))
        !          2596:        (with-mh-folder-updating (t)
        !          2597:          (beginning-of-line)
        !          2598:          (forward-char offset)
        !          2599:          (delete-char 1)
        !          2600:          (insert notation)))))
        !          2601: 
        !          2602: 
        !          2603: 
        !          2604: ;;; User prompting commands.
        !          2605: 
        !          2606: (defun mh-prompt-for-folder (prompt default can-create)
        !          2607:   ;; Prompt for a folder name with PROMPT.  Returns the folder's name as a
        !          2608:   ;; string.  DEFAULT is used if the folder exists and the user types return.
        !          2609:   ;; If the CAN-CREATE flag is t, then a non-existent folder is made.
        !          2610:   (let* ((prompt (format "%s folder%s" prompt
        !          2611:                         (if (equal "" default)
        !          2612:                             "? "
        !          2613:                             (format " [%s]? " default))))
        !          2614:         name)
        !          2615:     (if (null mh-folder-list)
        !          2616:        (mh-set-folder-list))
        !          2617:     (while (and (setq name (completing-read prompt mh-folder-list
        !          2618:                                            nil nil "+"))
        !          2619:                (equal name "")
        !          2620:                (equal default "")))
        !          2621:     (cond ((or (equal name "") (equal name "+"))
        !          2622:           (setq name default))
        !          2623:          ((not (mh-folder-name-p name))
        !          2624:           (setq name (format "+%s" name))))
        !          2625:     (let ((new-file-p (not (file-exists-p (mh-expand-file-name name)))))
        !          2626:       (cond ((and new-file-p
        !          2627:                  (y-or-n-p
        !          2628:                   (format "Folder %s does not exist. Create it? " name)))
        !          2629:             (message "Creating %s" name)
        !          2630:             (call-process "mkdir" nil nil nil (mh-expand-file-name name))
        !          2631:             (message "Creating %s...done" name)
        !          2632:             (mh-push (list name) mh-folder-list))
        !          2633:            (new-file-p
        !          2634:             (error "Folder %s is not created" name))
        !          2635:            (t
        !          2636:             (mh-when (null (assoc name mh-folder-list))
        !          2637:               (mh-push (list name) mh-folder-list)))))
        !          2638:     name))
        !          2639: 
        !          2640: 
        !          2641: (defun mh-set-folder-list ()
        !          2642:   "Sets mh-folder-list correctly.
        !          2643: A useful function for the command line or for when you need to sync by hand."
        !          2644:   (setq mh-folder-list (mh-make-folder-list)))
        !          2645: 
        !          2646: 
        !          2647: (defun mh-make-folder-list ()
        !          2648:   "Return a list of the user's folders.
        !          2649: Result is in a form suitable for completing read."
        !          2650:   (interactive)
        !          2651:   (message "Collecting folder names...")
        !          2652:   (save-window-excursion
        !          2653:     (mh-exec-cmd-quiet " *mh-temp*" "folders" "-fast"
        !          2654:                       (if mh-recursive-folders
        !          2655:                           "-recurse"
        !          2656:                           "-norecurse"))
        !          2657:     (goto-char (point-min))
        !          2658:     (let ((list nil)
        !          2659:          start)
        !          2660:       (while (not (eobp))
        !          2661:        (setq start (point))
        !          2662:        (forward-line 1)
        !          2663:        (mh-push (list (format "+%s" (buffer-substring start (1- (point)))))
        !          2664:                 list))
        !          2665:       (message "Collecting folder names...done")
        !          2666:       list)))
        !          2667: 
        !          2668: 
        !          2669: (defun mh-remove-folder-from-folder-list (folder)
        !          2670:   ;; Remove FOLDER from the list of folders.
        !          2671:   (setq mh-folder-list
        !          2672:        (delq (assoc folder mh-folder-list) mh-folder-list)))
        !          2673: 
        !          2674: 
        !          2675: (defun mh-read-msg-range (prompt)
        !          2676:   ;; Read a list of blank-separated items.
        !          2677:   (let* ((buf (read-string prompt))
        !          2678:         (buf-size (length buf))
        !          2679:         (start 0)
        !          2680:         (input ()))
        !          2681:     (while (< start buf-size)
        !          2682:       (let ((next (read-from-string buf start buf-size)))
        !          2683:        (mh-push (car next) input)
        !          2684:        (setq start (cdr next))))
        !          2685:     (nreverse input)))
        !          2686: 
        !          2687: 
        !          2688: 
        !          2689: ;;; Misc. functions.
        !          2690: 
        !          2691: (defun mh-get-msg-num (error-if-no-message)
        !          2692:   ;; Return the message number of the displayed message.  If the argument
        !          2693:   ;; ERROR-IF-NO-MESSAGE is non-nil, then complain if the cursor is not
        !          2694:   ;; pointing to a message.
        !          2695:   (save-excursion
        !          2696:     (beginning-of-line)
        !          2697:     (cond ((looking-at mh-msg-number-regexp)
        !          2698:           (string-to-int (buffer-substring (match-beginning 1)
        !          2699:                                            (match-end 1))))
        !          2700:          (error-if-no-message
        !          2701:           (error "Cursor not pointing to message"))
        !          2702:          (t nil))))
        !          2703: 
        !          2704: 
        !          2705: (defun mh-msg-search-pat (n)
        !          2706:   ;; Return a search pattern for message N in the scan listing.
        !          2707:   (format mh-msg-search-regexp n))
        !          2708: 
        !          2709: 
        !          2710: (defun mh-msg-filename (msg &optional folder)
        !          2711:   ;; Return the file name of MESSAGE in FOLDER (default current folder).
        !          2712:   (expand-file-name (int-to-string msg)
        !          2713:                    (if folder
        !          2714:                        (mh-expand-file-name folder)
        !          2715:                        mh-folder-filename)))
        !          2716: 
        !          2717: 
        !          2718: (defun mh-msg-filenames (msgs &optional folder)
        !          2719:   ;; Return a list of file names for MSGS in FOLDER (default current folder).
        !          2720:   (mapconcat (function (lambda (msg) (mh-msg-filename msg folder))) msgs " "))
        !          2721: 
        !          2722: 
        !          2723: (defun mh-expand-file-name (filename &optional default)
        !          2724:   "Just like `expand-file-name', but also handles MH folder names.
        !          2725: Assumes that any filename that starts with '+' is a folder name."
        !          2726:    (if (mh-folder-name-p filename)
        !          2727:        (expand-file-name (substring filename 1) mh-user-path)
        !          2728:      (expand-file-name filename default)))
        !          2729: 
        !          2730: 
        !          2731: (defun mh-find-path ()
        !          2732:   ;; Set mh-user-path, mh-draft-folder, and mh-unseen-seq from profile file.
        !          2733:   (save-excursion
        !          2734:     ;; Be sure profile is fully expanded before switching buffers
        !          2735:     (let ((profile (expand-file-name (or (getenv "MH") "~/.mh_profile"))))
        !          2736:       (if (not (file-exists-p profile))
        !          2737:          (error "Cannot find MH profile %s" profile))
        !          2738:       (set-buffer (get-buffer-create " *mh-temp*"))
        !          2739:       (erase-buffer)
        !          2740:       (insert-file-contents profile)
        !          2741:       (setq mh-draft-folder (mh-get-field "Draft-Folder:"))
        !          2742:       (cond ((equal mh-draft-folder "")
        !          2743:             (setq mh-draft-folder nil))
        !          2744:            ((not (mh-folder-name-p mh-draft-folder))
        !          2745:             (setq mh-draft-folder (format "+%s" mh-draft-folder))))
        !          2746:       (setq mh-user-path (mh-get-field "Path:"))
        !          2747:       (if (equal mh-user-path "")
        !          2748:          (setq mh-user-path "Mail"))
        !          2749:       (setq mh-user-path
        !          2750:            (file-name-as-directory
        !          2751:             (expand-file-name mh-user-path (expand-file-name "~"))))
        !          2752:       (if (and mh-draft-folder
        !          2753:               (not (file-exists-p (mh-expand-file-name mh-draft-folder))))
        !          2754:          (error "Draft folder %s does not exist.  Create it and try again."
        !          2755:                 mh-draft-folder))
        !          2756:       (setq mh-unseen-seq (mh-get-field "Unseen-Sequence:"))
        !          2757:       (if (equal mh-unseen-seq "")
        !          2758:          (setq mh-unseen-seq 'unseen)
        !          2759:          (setq mh-unseen-seq (intern mh-unseen-seq))))))
        !          2760: 
        !          2761: 
        !          2762: (defun mh-get-field (field)
        !          2763:   ;; Find and return the value of field FIELD in the current buffer.
        !          2764:   ;; Returns the empty string if the field is not in the message.
        !          2765:   (let ((case-fold-search t))
        !          2766:     (goto-char (point-min))
        !          2767:     (cond ((not (re-search-forward (format "^%s" field) nil t)) "")
        !          2768:          ((looking-at "[\t ]*$") "")
        !          2769:          (t
        !          2770:           (re-search-forward "[\t ]*\\([^\t \n].*\\)$" nil t)
        !          2771:           (let ((start (match-beginning 1)))
        !          2772:             (forward-line 1)
        !          2773:             (while (looking-at "[ \t]")
        !          2774:               (forward-line 1))
        !          2775:             (buffer-substring start (1- (point))))))))
        !          2776: 
        !          2777: 
        !          2778: (defun mh-insert-fields (&rest name-values)
        !          2779:   ;; Insert the NAME-VALUE pairs in the current buffer.
        !          2780:   ;; Do not insert any pairs whose value is the empty string.
        !          2781:   (let ((case-fold-search t))
        !          2782:     (while name-values
        !          2783:       (let ((field-name (car name-values))
        !          2784:            (value (car (cdr name-values))))
        !          2785:        (mh-when (not (equal value ""))
        !          2786:          (goto-char (point-min))
        !          2787:          (cond ((not (re-search-forward (format "^%s" field-name) nil t))
        !          2788:                 (mh-goto-header-end 0)
        !          2789:                 (insert field-name " " value "\n"))
        !          2790:                (t
        !          2791:                 (end-of-line)
        !          2792:                 (insert " " value))))
        !          2793:        (setq name-values (cdr (cdr name-values)))))))
        !          2794: 
        !          2795: 
        !          2796: (defun mh-position-on-field (field set-mark)
        !          2797:   ;; Set point to the end of the line beginning with FIELD.
        !          2798:   ;; Set the mark to the old value of point, if SET-MARK is non-nil.
        !          2799:   ;; Returns non-nil iff the field was found.
        !          2800:   (let ((case-fold-search t))
        !          2801:     (if set-mark (push-mark))
        !          2802:     (goto-char (point-min))
        !          2803:     (mh-goto-header-end 0)
        !          2804:     (if (re-search-backward (format "^%s" field) nil t)
        !          2805:        (progn (end-of-line) t)
        !          2806:        nil)))
        !          2807: 
        !          2808: 
        !          2809: (defun mh-goto-header-end (arg)
        !          2810:   ;; Find the end of the message header in the current buffer and position
        !          2811:   ;; the cursor at the ARG'th newline after the header.
        !          2812:   (if (re-search-forward "^$\\|^-+$" nil nil)
        !          2813:       (forward-line arg)))
        !          2814: 
        !          2815: 
        !          2816: 
        !          2817: ;;; Build the folder-mode keymap:
        !          2818: 
        !          2819: (suppress-keymap mh-folder-mode-map)
        !          2820: (define-key mh-folder-mode-map "q" 'mh-quit)
        !          2821: (define-key mh-folder-mode-map "b" 'mh-quit)
        !          2822: (define-key mh-folder-mode-map "?" 'mh-msg-is-in-seq)
        !          2823: (define-key mh-folder-mode-map "%" 'mh-put-msg-in-seq)
        !          2824: (define-key mh-folder-mode-map "|" 'mh-pipe-msg)
        !          2825: (define-key mh-folder-mode-map "\ea" 'mh-edit-again)
        !          2826: (define-key mh-folder-mode-map "\e%" 'mh-delete-msg-from-seq)
        !          2827: (define-key mh-folder-mode-map "\C-xn" 'mh-narrow-to-seq)
        !          2828: (define-key mh-folder-mode-map "\C-xw" 'mh-widen)
        !          2829: (define-key mh-folder-mode-map "\eb" 'mh-burst-digest)
        !          2830: (define-key mh-folder-mode-map "\eu" 'mh-undo-folder)
        !          2831: (define-key mh-folder-mode-map "\e " 'mh-page-digest)
        !          2832: (define-key mh-folder-mode-map "\e\177" 'mh-page-digest-backwards)
        !          2833: (define-key mh-folder-mode-map "\ee" 'mh-extract-rejected-mail)
        !          2834: (define-key mh-folder-mode-map "\ef" 'mh-visit-folder)
        !          2835: (define-key mh-folder-mode-map "\ek" 'mh-kill-folder)
        !          2836: (define-key mh-folder-mode-map "\el" 'mh-list-folders)
        !          2837: (define-key mh-folder-mode-map "\eo" 'mh-write-msg-to-file)
        !          2838: (define-key mh-folder-mode-map "\ep" 'mh-pack-folder)
        !          2839: (define-key mh-folder-mode-map "\es" 'mh-search-folder)
        !          2840: (define-key mh-folder-mode-map "\er" 'mh-rescan-folder)
        !          2841: (define-key mh-folder-mode-map "l" 'mh-print-msg)
        !          2842: (define-key mh-folder-mode-map "t" 'mh-toggle-showing)
        !          2843: (define-key mh-folder-mode-map "c" 'mh-copy-msg)
        !          2844: (define-key mh-folder-mode-map ">" 'mh-write-msg-to-file)
        !          2845: (define-key mh-folder-mode-map "i" 'mh-inc-folder)
        !          2846: (define-key mh-folder-mode-map "x" 'mh-execute-commands)
        !          2847: (define-key mh-folder-mode-map "e" 'mh-execute-commands)
        !          2848: (define-key mh-folder-mode-map "r" 'mh-redistribute)
        !          2849: (define-key mh-folder-mode-map "f" 'mh-forward)
        !          2850: (define-key mh-folder-mode-map "s" 'mh-send)
        !          2851: (define-key mh-folder-mode-map "m" 'mh-send)
        !          2852: (define-key mh-folder-mode-map "a" 'mh-reply)
        !          2853: (define-key mh-folder-mode-map "j" 'mh-goto-msg)
        !          2854: (define-key mh-folder-mode-map "<" 'mh-first-msg)
        !          2855: (define-key mh-folder-mode-map "g" 'mh-goto-msg)
        !          2856: (define-key mh-folder-mode-map "\177" 'mh-previous-page)
        !          2857: (define-key mh-folder-mode-map " " 'mh-page-msg)
        !          2858: (define-key mh-folder-mode-map "." 'mh-show)
        !          2859: (define-key mh-folder-mode-map "u" 'mh-undo)
        !          2860: (define-key mh-folder-mode-map "!" 'mh-refile-or-write-again)
        !          2861: (define-key mh-folder-mode-map "^" 'mh-refile-msg)
        !          2862: (define-key mh-folder-mode-map "d" 'mh-delete-msg)
        !          2863: (define-key mh-folder-mode-map "\C-d" 'mh-delete-msg-no-motion)
        !          2864: (define-key mh-folder-mode-map "p" 'mh-previous-undeleted-msg)
        !          2865: (define-key mh-folder-mode-map "n" 'mh-next-undeleted-msg)
        !          2866: (define-key mh-folder-mode-map "o" 'mh-refile-msg)
        !          2867: 
        !          2868: 
        !          2869: ;;; Build the letter-mode keymap:
        !          2870: 
        !          2871: (define-key mh-letter-mode-map "\C-c\C-f\C-b" 'mh-to-field)
        !          2872: (define-key mh-letter-mode-map "\C-c\C-f\C-c" 'mh-to-field)
        !          2873: (define-key mh-letter-mode-map "\C-c\C-f\C-f" 'mh-to-fcc)
        !          2874: (define-key mh-letter-mode-map "\C-c\C-f\C-s" 'mh-to-field)
        !          2875: (define-key mh-letter-mode-map "\C-c\C-f\C-t" 'mh-to-field)
        !          2876: (define-key mh-letter-mode-map "\C-c\C-fb" 'mh-to-field)
        !          2877: (define-key mh-letter-mode-map "\C-c\C-fc" 'mh-to-field)
        !          2878: (define-key mh-letter-mode-map "\C-c\C-ff" 'mh-to-fcc)
        !          2879: (define-key mh-letter-mode-map "\C-c\C-fs" 'mh-to-field)
        !          2880: (define-key mh-letter-mode-map "\C-c\C-ft" 'mh-to-field)
        !          2881: (define-key mh-letter-mode-map "\C-c\C-q" 'mh-fully-kill-draft)
        !          2882: (define-key mh-letter-mode-map "\C-c\C-w" 'mh-check-whom)
        !          2883: (define-key mh-letter-mode-map "\C-c\C-i" 'mh-insert-letter)
        !          2884: (define-key mh-letter-mode-map "\C-c\C-y" 'mh-yank-cur-msg)
        !          2885: (define-key mh-letter-mode-map "\C-c\C-s" 'mh-insert-signature)
        !          2886: (define-key mh-letter-mode-map "\C-c\C-c" 'mh-send-letter)
        !          2887: 
        !          2888: 
        !          2889: ;;; Build the pick-mode keymap:
        !          2890: 
        !          2891: (define-key mh-pick-mode-map "\C-c\C-c" 'mh-do-pick-search)
        !          2892: (define-key mh-pick-mode-map "\C-c\C-f\C-b" 'mh-to-field)
        !          2893: (define-key mh-pick-mode-map "\C-c\C-f\C-c" 'mh-to-field)
        !          2894: (define-key mh-pick-mode-map "\C-c\C-f\C-f" 'mh-to-field)
        !          2895: (define-key mh-pick-mode-map "\C-c\C-f\C-s" 'mh-to-field)
        !          2896: (define-key mh-pick-mode-map "\C-c\C-f\C-t" 'mh-to-field)
        !          2897: (define-key mh-pick-mode-map "\C-c\C-fb" 'mh-to-field)
        !          2898: (define-key mh-pick-mode-map "\C-c\C-fc" 'mh-to-field)
        !          2899: (define-key mh-pick-mode-map "\C-c\C-ff" 'mh-to-field)
        !          2900: (define-key mh-pick-mode-map "\C-c\C-fs" 'mh-to-field)
        !          2901: (define-key mh-pick-mode-map "\C-c\C-ft" 'mh-to-field)
        !          2902: (define-key mh-pick-mode-map "\C-c\C-w" 'mh-check-whom)
        !          2903: 
        !          2904: 
        !          2905: 
        !          2906: ;;; For Gnu Emacs.
        !          2907: ;;; Local Variables: ***
        !          2908: ;;; eval: (put 'mh-when 'lisp-indent-hook 1) ***
        !          2909: ;;; eval: (put 'with-mh-folder-updating 'lisp-indent-hook 1) ***
        !          2910: ;;; End: ***

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.