X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/9b7bc07699051b2ef7461f378f4aa7b8f90e1f80..ca05be61ac6d9b527df14f667c447224b69a955d:/lisp/mail/mh-e.el diff --git a/lisp/mail/mh-e.el b/lisp/mail/mh-e.el index 5acb71dbdf..386a9acf99 100644 --- a/lisp/mail/mh-e.el +++ b/lisp/mail/mh-e.el @@ -1,13 +1,9 @@ ;;; mh-e.el --- GNU Emacs interface to the MH mail system -;;; Copyright (C) 1985,86,87,88,90,92,93,94,95 Free Software Foundation, Inc. +;; Copyright (C) 1985,86,87,88,90,92,93,94,95,97,2000 Free Software Foundation, Inc. -(defconst mh-e-time-stamp "Time-stamp: <95/03/05 23:39:29 gildea>") -(defconst mh-e-version "5.0" - "Version numbers of this version of mh-e.") - -;; Maintainer: Stephen Gildea -;; Version: 5.0 +;; Maintainer: Bill Wohler +;; Version: 5.0.2 ;; Keywords: mail ;; Bug-reports: include `M-x mh-version' output in any correspondence @@ -24,46 +20,47 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. ;;; Commentary: -;;; HOW TO USE: -;;; M-x mh-rmail to read mail. Type C-h m there for a list of commands. -;;; C-u M-x mh-rmail to visit any folder. -;;; M-x mh-smail to send mail. From within the mail reader, "m" works, too. +;; HOW TO USE: +;; M-x mh-rmail to read mail. Type C-h m there for a list of commands. +;; C-u M-x mh-rmail to visit any folder. +;; M-x mh-smail to send mail. From within the mail reader, "m" works, too. -;;; MH (Message Handler) is a powerful mail reader. The MH newsgroup -;;; is comp.mail.mh; the mailing list is mh-users@ics.uci.edu (send to -;;; mh-users-request to be added). See the monthly Frequently Asked -;;; Questions posting there for information on getting MH and mh-e. +;; MH (Message Handler) is a powerful mail reader. The MH newsgroup +;; is comp.mail.mh; the mailing list is mh-users@ics.uci.edu (send to +;; mh-users-request to be added). See the monthly Frequently Asked +;; Questions posting there for information on getting MH and mh-e. -;;; mh-e is an Emacs interface to the MH mail system. -;;; The mailing list mh-e@x.org is for discussion of mh-e and -;;; announcements of new versions. Send a "subscribe" message to -;;; mh-e-request@x.org to be added. Do not report bugs here; mail -;;; them directly to the author (see top of mh-e.el source). -;;; Include the output of M-x mh-version in any bug report. +;; mh-e is an Emacs interface to the MH mail system. +;; There is a mailing list for discussion of mh-e and +;; announcements of new versions. Send a "subscribe" message to +;; mh-e-request@gnu.org to be added. Do not report bugs here; mail +;; them directly to the maintainer (see top of mh-e.el source). +;; Include the output of M-x mh-version in any bug report. -;;; mh-e works with GNU Emacs 18 or 19, and MH 6. +;; mh-e works with GNU Emacs 18 or 19, and MH 6. -;;; NB. MH must have been compiled with the MHE compiler flag or several -;;; features necessary for mh-e will be missing from MH commands, specifically -;;; the -build switch to repl and forw. +;; NB. MH must have been compiled with the MHE compiler flag or several +;; features necessary for mh-e will be missing from MH commands, specifically +;; the -build switch to repl and forw. -;;; Your .emacs might benefit from these bindings: -;;; (global-set-key "\C-cr" 'mh-rmail) -;;; (global-set-key "\C-xm" 'mh-smail) -;;; (global-set-key "\C-x4m" 'mh-smail-other-window) +;; Your .emacs might benefit from these bindings: +;; (global-set-key "\C-cr" 'mh-rmail) +;; (global-set-key "\C-xm" 'mh-smail) +;; (global-set-key "\C-x4m" 'mh-smail-other-window) ;;; Change Log: -;;; Original version for Gosling emacs by Brian Reid, Stanford, 1982. -;;; Modified by James Larus, BBN, July 1984 and UCB, 1984 & 1985. -;;; Rewritten for GNU Emacs, James Larus 1985. larus@ginger.berkeley.edu -;;; Modified by Stephen Gildea 1988. gildea@lcs.mit.edu -(defconst mh-e-RCS-id "$Id: mh-e.el,v 1.5 1995/04/09 22:28:32 kwzh Exp kwzh $") +;; Original version for Gosling emacs by Brian Reid, Stanford, 1982. +;; Modified by James Larus, BBN, July 1984 and UCB, 1984 & 1985. +;; Rewritten for GNU Emacs, James Larus 1985. larus@ginger.berkeley.edu +;; Modified by Stephen Gildea 1988. gildea@stop.mail-abuse.org +(defconst mh-e-RCS-id "$Id: mh-e.el,v 1.30 2001/09/23 17:38:22 eliz Exp $") ;;; Code: @@ -73,74 +70,115 @@ ;;; Hooks: -(defvar mh-folder-mode-hook nil - "Invoked in MH-Folder mode on a new folder.") +(defgroup mh nil + "Emacs interface to the MH mail system" + :group 'mail) + +(defgroup mh-hook nil + "Hooks to mh-e mode" + :prefix "mh-" + :group 'mh) + -(defvar mh-inc-folder-hook nil - "Invoked by \\`\\[mh-inc-folder]' after incorporating mail into a folder.") +(defcustom mh-folder-mode-hook nil + "Invoked in MH-Folder mode on a new folder." + :type 'hook + :group 'mh-hook) -(defvar mh-show-hook nil - "Invoked after \\`\\[mh-show]' shows a message.") +(defcustom mh-inc-folder-hook nil + "Invoked by \\`\\[mh-inc-folder]' after incorporating mail into a folder." + :type 'hook + :group 'mh-hook) -(defvar mh-show-mode-hook nil - "Invoked in MH-Show mode on each message.") +(defcustom mh-show-hook nil + "Invoked after \\`\\[mh-show]' shows a message." + :type 'hook + :group 'mh-hook) -(defvar mh-delete-msg-hook nil - "Invoked after marking each message for deletion.") +(defcustom mh-show-mode-hook nil + "Invoked in MH-Show mode on each message." + :type 'hook + :group 'mh-hook) -(defvar mh-refile-msg-hook nil - "Invoked after marking each message for refiling.") +(defcustom mh-delete-msg-hook nil + "Invoked after marking each message for deletion." + :type 'hook + :group 'mh-hook) -(defvar mh-before-quit-hook nil - "Invoked by \\`\\[mh-quit]' before quitting mh-e. See also mh-quit-hook.") +(defcustom mh-refile-msg-hook nil + "Invoked after marking each message for refiling." + :type 'hook + :group 'mh-hook) -(defvar mh-quit-hook nil - "Invoked after \\`\\[mh-quit]' quits mh-e. See also mh-before-quit-hook.") +(defcustom mh-before-quit-hook nil + "Invoked by \\`\\[mh-quit]' before quitting mh-e. See also mh-quit-hook." + :type 'hook + :group 'mh-hook) + +(defcustom mh-quit-hook nil + "Invoked after \\`\\[mh-quit]' quits mh-e. See also mh-before-quit-hook." + :type 'hook + :group 'mh-hook) ;;; Personal preferences: -(defvar mh-lpr-command-format "lpr -J '%s'" +(defcustom mh-lpr-command-format "lpr -J '%s'" "*Format for Unix command that prints a message. The string should be a Unix command line, with the string '%s' where the job's name (folder and message number) should appear. The formatted -message text is piped to this command when you type \\`\\[mh-print-msg]'.") +message text is piped to this command when you type \\`\\[mh-print-msg]'." + :type 'string + :group 'mh) -(defvar mh-scan-prog "scan" +(defcustom mh-scan-prog "scan" "*Program to run to generate one-line-per-message listing of a folder. Normally \"scan\" or a file name linked to scan. This file is searched for relative to the mh-progs directory unless it is an absolute pathname. -Automatically becomes buffer-local when set in any fashion.") +Automatically becomes buffer-local when set in any fashion." + :type 'string + :group 'mh) (make-variable-buffer-local 'mh-scan-prog) -(defvar mh-inc-prog "inc" +(defcustom mh-inc-prog "inc" "*Program to run to incorporate new mail into a folder. Normally \"inc\". This file is searched for relative to -the mh-progs directory unless it is an absolute pathname.") +the mh-progs directory unless it is an absolute pathname." + :type 'string + :group 'mh) -(defvar mh-print-background nil +(defcustom mh-print-background nil "*Print messages in the background if non-nil. WARNING: do not delete the messages until printing is finished; -otherwise, your output may be truncated.") +otherwise, your output may be truncated." + :type 'boolean + :group 'mh) -(defvar mh-recenter-summary-p nil - "*Recenter summary window when the show window is toggled off if non-nil.") +(defcustom mh-recenter-summary-p nil + "*Recenter summary window when the show window is toggled off if non-nil." + :type 'boolean + :group 'mh) -(defvar mh-do-not-confirm nil +(defcustom mh-do-not-confirm nil "*Non-nil means do not prompt for confirmation before some mh-e commands. -Affects non-recoverable commands such as mh-kill-folder and mh-undo-folder.") +Affects non-recoverable commands such as `mh-kill-folder' and `mh-undo-folder'." + :type 'boolean + :group 'mh) -(defvar mh-store-default-directory nil +(defcustom mh-store-default-directory nil "*Last directory used by \\[mh-store-msg]; default for next store. -A directory name string, or nil to use current directory.") +A directory name string, or nil to use current directory." + :type '(choice (const :tag "Current" nil) + directory) + :group 'mh) ;;; Parameterize mh-e to work with different scan formats. The defaults work ;;; with the standard MH scan listings, in which the first 4 characters on ;;; the line are the message number, followed by two places for notations. (defvar mh-good-msg-regexp "^....[^D^]" - "Regexp specifiying the scan lines that are 'good' messages.") + "Regexp specifying the scan lines that are 'good' messages.") (defvar mh-deleted-msg-regexp "^....D" "Regexp matching scan lines of deleted messages.") @@ -165,7 +203,7 @@ A directory name string, or nil to use current directory.") (defvar mh-partial-folder-mode-line-annotation "select" "Annotation when displaying part of a folder. -The string is displayed after the folder's name. NIL for no annotation.") +The string is displayed after the folder's name. nil for no annotation.") ;;; Internal variables: @@ -390,7 +428,6 @@ previous refile or write command." (message "Destination: %s" (cdr mh-last-destination)))) (mh-next-msg)) - (defun mh-quit () "Quit the current mh-e folder. Start by running mh-before-quit-hook. Restore the previous window @@ -522,7 +559,7 @@ provided, then prompt for the message sequence." (mh-find-progs) (set-buffer (get-buffer-create mh-temp-buffer)) (erase-buffer) - (insert " mh-e info:\n\nversion: " mh-e-version "\n" mh-e-time-stamp + (insert " mh-e info:\n\nversion: " mh-e-RCS-id "\nEmacs: " emacs-version " on " (symbol-name system-type) " ") (condition-case () (call-process "uname" nil t nil "-a") @@ -592,7 +629,7 @@ Flush mh-e's state out to MH. The message at the cursor becomes current." (save-excursion (mh-goto-msg msg nil t) (if (looking-at mh-refiled-msg-regexp) - (error "Message %d is refiled. Undo refile before deleting." msg)) + (error "Message %d is refiled. Undo refile before deleting" msg)) (if (looking-at mh-deleted-msg-regexp) nil (mh-set-folder-modified-p t) @@ -606,7 +643,7 @@ Flush mh-e's state out to MH. The message at the cursor becomes current." (save-excursion (mh-goto-msg msg nil t) (cond ((looking-at mh-deleted-msg-regexp) - (error "Message %d is deleted. Undo delete before moving." msg)) + (error "Message %d is deleted. Undo delete before moving" msg)) ((looking-at mh-refiled-msg-regexp) (if (y-or-n-p (format "Message %d already refiled. Copy to %s as well? " @@ -637,7 +674,7 @@ Flush mh-e's state out to MH. The message at the cursor becomes current." (if (get-buffer mh-show-buffer) (delete-windows-on mh-show-buffer)) (setq mh-showing nil) - (set-buffer-modified-p (buffer-modified-p)) ;force mode line update + (force-mode-line-update) (if mh-recenter-summary-p (mh-recenter nil))) @@ -720,50 +757,50 @@ Here are all the commands with their current binding, listed in key order: Variables controlling mh-e operation are (defaults in parentheses): - mh-recursive-folders (nil) + `mh-recursive-folders' (nil) Non-nil means commands which operate on folders do so recursively. - mh-bury-show-buffer (t) + `mh-bury-show-buffer' (t) Non-nil means that the buffer used to display message is buried. It will never be offered as the default other buffer. - mh-clean-message-header (nil) + `mh-clean-message-header' (nil) Non-nil means remove header lines matching the regular expression specified in mh-invisible-headers from messages. - mh-visible-headers (nil) + `mh-visible-headers' (nil) If non-nil, it contains a regexp specifying the headers that are shown in a message if mh-clean-message-header is non-nil. Setting this variable - overrides mh-invisible-headers. + overrides `mh-invisible-headers'. - mh-do-not-confirm (nil) + `mh-do-not-confirm' (nil) Non-nil means do not prompt for confirmation before executing some - non-recoverable commands such as mh-kill-folder and mh-undo-folder. + non-recoverable commands such as `mh-kill-folder' and `mh-undo-folder'. - mhl-formfile (nil) + `mhl-formfile' (nil) Name of format file to be used by mhl to show messages. - A value of T means use the default format file. - Nil means don't use mhl to format messages. + A value of t means use the default format file. + nil means don't use mhl to format messages. - mh-lpr-command-format (\"lpr -p -J '%s'\") + `mh-lpr-command-format' (\"lpr -p -J '%s'\") Format for command used to print a message on a system printer. - mh-scan-prog (\"scan\") + `mh-scan-prog' (\"scan\") Program to run to generate one-line-per-message listing of a folder. Normally \"scan\" or a file name linked to scan. This file is searched for relative to the mh-progs directory unless it is an absolute pathname. Automatically becomes buffer-local when set in any fashion. - mh-print-background (nil) + `mh-print-background' (nil) Print messages in the background if non-nil. WARNING: do not delete the messages until printing is finished; otherwise, your output may be truncated. - mh-recenter-summary-p (nil) + `mh-recenter-summary-p' (nil) If non-nil, then the scan listing is recentered when the window displaying a messages is toggled off. - mh-summary-height (4) + `mh-summary-height' (4) Number of lines in the summary window including the mode line. The value of mh-folder-mode-hook is called when a new folder is set up." @@ -786,6 +823,7 @@ The value of mh-folder-mode-hook is called when a new folder is set up." 'mh-narrowed-to-seq nil ; Sequence display is narrowed to 'mh-first-msg-num nil ; Number of first msg in buffer 'mh-last-msg-num nil ; Number of last msg in buffer + 'mh-msg-count nil ; Number of msgs in buffer 'mh-mode-line-annotation nil ; Indiction this is not the full folder 'mh-previous-window-config nil) ; Previous window configuration (setq truncate-lines t) @@ -807,8 +845,7 @@ The value of mh-folder-mode-hook is called when a new folder is set up." ;; Take VARIABLE-VALUE pairs and make local variables initialized to the ;; value. (while pairs - (make-variable-buffer-local (car pairs)) - (set (car pairs) (car (cdr pairs))) + (set (make-local-variable (car pairs)) (car (cdr pairs))) (setq pairs (cdr (cdr pairs))))) @@ -867,9 +904,9 @@ The value of mh-folder-mode-hook is called when a new folder is set up." (folder mh-current-folder) (new-mail-p nil)) (with-mh-folder-updating (t) - (message (if maildrop-name - (format "inc %s -file %s..." folder maildrop-name) - (format "inc %s..." folder))) + (if maildrop-name + (message "inc %s -file %s..." folder maildrop-name) + (message "inc %s..." folder)) (setq mh-next-direction 'forward) (goto-char (point-max)) (let ((start-of-inc (point))) @@ -882,10 +919,9 @@ The value of mh-folder-mode-hook is called when a new folder is set up." "-truncate") (mh-exec-cmd-output mh-inc-prog nil "-width" (window-width))) - (message - (if maildrop-name - (format "inc %s -file %s...done" folder maildrop-name) - (format "inc %s...done" folder))) + (if maildrop-name + (message "inc %s -file %s...done" folder maildrop-name) + (message "inc %s...done" folder)) (goto-char start-of-inc) (cond ((save-excursion (re-search-forward "^inc: no mail" nil t)) @@ -901,8 +937,8 @@ The value of mh-folder-mode-hook is called when a new folder is set up." (mh-notate-user-sequences) (if new-mail-p (progn - (mh-goto-cur-msg) - (mh-make-folder-mode-line)) + (mh-make-folder-mode-line) + (mh-goto-cur-msg)) (goto-char point-before-inc)))))) @@ -916,19 +952,19 @@ The value of mh-folder-mode-hook is called when a new folder is set up." (setq mh-first-msg-num (mh-get-msg-num nil)) (mh-last-msg) (setq mh-last-msg-num (mh-get-msg-num nil)) - (let ((lines (count-lines (point-min) (point-max)))) - (setq mode-line-buffer-identification - (list (format "{%%b%s} %d msg%s" - (if mh-mode-line-annotation - (format "/%s" mh-mode-line-annotation) - "") - lines - (if (zerop lines) - "s" - (if (> lines 1) - (format "s (%d-%d)" mh-first-msg-num - mh-last-msg-num) - (format " (%d)" mh-first-msg-num))))))))) + (setq mh-msg-count (count-lines (point-min) (point-max))) + (setq mode-line-buffer-identification + (list (format "{%%b%s} %d msg%s" + (if mh-mode-line-annotation + (format "/%s" mh-mode-line-annotation) + "") + mh-msg-count + (if (zerop mh-msg-count) + "s" + (if (> mh-msg-count 1) + (format "s (%d-%d)" mh-first-msg-num + mh-last-msg-num) + (format " (%d)" mh-first-msg-num)))))))) (defun mh-unmark-all-headers (remove-all-flags) @@ -944,16 +980,16 @@ The value of mh-folder-mode-hook is called when a new folder is set up." (forward-char mh-cmd-note) (setq char (following-char)) (if (or (and remove-all-flags - (or (eql char (aref mh-note-deleted 0)) - (eql char (aref mh-note-refiled 0)))) - (eql char (aref mh-note-cur 0))) + (or (= char (aref mh-note-deleted 0)) + (= char (aref mh-note-refiled 0)))) + (= char (aref mh-note-cur 0))) (progn (delete-char 1) (insert " "))) (if remove-all-flags (progn (forward-char 1) - (if (eql (following-char) (aref mh-note-seq 0)) + (if (= (following-char) (aref mh-note-seq 0)) (progn (delete-char 1) (insert " "))))) @@ -1044,7 +1080,7 @@ The value of mh-folder-mode-hook is called when a new folder is set up." (defun mh-update-unseen () ;; Flush updates to the Unseen sequence out to MH. - ;; Return non-NIL iff set the MH folder. + ;; Return non-nil iff set the MH folder. (if mh-seen-list (let* ((unseen-seq (mh-find-seq mh-unseen-seq)) (unseen-msgs (mh-seq-msgs unseen-seq))) @@ -1061,16 +1097,11 @@ The value of mh-folder-mode-hook is called when a new folder is set up." (defun mh-delete-scan-msgs (msgs) ;; Delete the scan listing lines for each of the msgs in the LIST. - ;; Optimized for speed (i.e., no regular expressions). - (setq msgs (sort msgs '<)) ;okay to clobber msgs (save-excursion - (mh-first-msg) - (while (and msgs (< (point) (point-max))) - (cond ((equal (mh-get-msg-num nil) (car msgs)) - (delete-region (point) (save-excursion (forward-line) (point))) - (setq msgs (cdr msgs))) - (t - (forward-line)))))) + (while msgs + (if (mh-goto-msg (car msgs) t t) + (mh-delete-line 1)) + (setq msgs (cdr msgs))))) (defun mh-outstanding-commands-p () @@ -1090,9 +1121,9 @@ The value of mh-folder-mode-hook is called when a new folder is set up." (while prev (if range-high (if (or (not (numberp prev)) - (not (eql (car msgs) (1- prev)))) + (not (equal (car msgs) (1- prev)))) (progn ;non-sequential, flush old range - (if (eql prev range-high) + (if (eq prev range-high) (setq ranges (cons range-high ranges)) (setq ranges (cons (format "%s-%s" prev range-high) ranges))) (setq range-high nil)))) @@ -1180,7 +1211,7 @@ The value of mh-folder-mode-hook is called when a new folder is set up." (defun mh-internal-seq (name) - ;; Return non-NIL if NAME is the name of an internal mh-e sequence. + ;; Return non-nil if NAME is the name of an internal mh-e sequence. (or (memq name '(answered cur deleted forwarded printed)) (eq name mh-unseen-seq) (eq name mh-previous-seq) @@ -1329,6 +1360,8 @@ inform MH of the change." (define-key mh-folder-mode-map ">" 'mh-write-msg-to-file) (define-key mh-folder-mode-map "!" 'mh-refile-or-write-again) +;; "C-c /" prefix is used in mh-folder-mode by pgp.el and mailcrypt + ;;;autoload the other mh-e parts @@ -1487,4 +1520,8 @@ If optional prefix argument provided, then prompt for the message sequence." t) (autoload 'mh-rename-seq "mh-seq" "Rename SEQUENCE to have NEW-NAME." t) +(dolist (mess '("^Cursor not pointing to message$" + "^There is no other window$")) + (add-to-list 'debug-ignored-errors mess)) + ;;; mh-e.el ends here