Annotation of 43BSDReno/contrib/emacs-18.55/lisp/mh-e.el, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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