# HG changeset patch # User Paul Reilly # Date 1045323498 0 # Node ID b621daa96824b8424235fc0fc6b41c0698fd4c91 # Parent 9c783aa2b379f414baa595a70ce965ad9c274e95 Attempt to minimize byte compilation warnings. (rmail-output-to-rmail-file): Eliminate Babyl 5 code by using (rmail-output). (rmail-output): Generalize the use by GNUS; rewrite to reflect mbox as the default format. (rmail-output-body-to-file): Use the rmail message descriptor in setting the "stored" attribute. diff -r 9c783aa2b379 -r b621daa96824 lisp/mail/rmailout.el --- a/lisp/mail/rmailout.el Sat Feb 15 15:12:08 2003 +0000 +++ b/lisp/mail/rmailout.el Sat Feb 15 15:38:18 2003 +0000 @@ -1,4 +1,4 @@ -;;; rmailout.el --- "RMAIL" mail reader for Emacs: output message to a file +;;; rmailout.el --- "RMAIL" mail reader for Emacs: output message to a file. ;; Copyright (C) 1985, 1987, 1993, 1994, 2001 Free Software Foundation, Inc. @@ -26,9 +26,13 @@ ;;; Code: -(require 'rmail) (provide 'rmailout) +(eval-when-compile + (require 'rmail) + (require 'rmaildesc)) + + ;;;###autoload (defcustom rmail-output-file-alist nil "*Alist matching regexps to suggested output Rmail files. @@ -62,7 +66,7 @@ (let ((read-file (expand-file-name (read-file-name - (concat "Output message to Rmail file: (default " + (concat "Output message to Rmail (mbox) file: (default " (file-name-nondirectory default-file) ") ") (file-name-directory default-file) @@ -76,6 +80,7 @@ read-file) read-file))))) +;;; mbox: deprecated (defun rmail-output-read-file-name () "Read the file name to use for `rmail-output'. Set `rmail-default-file' to this name as well as returning it." @@ -108,11 +113,12 @@ (or read-file (file-name-nondirectory default-file)) (file-name-directory default-file))))))) +;;; mbox: ready ;;; There are functions elsewhere in Emacs that use this function; ;;; look at them before you change the calling method. ;;;###autoload (defun rmail-output-to-rmail-file (file-name &optional count stay) - "Append the current message to an Rmail file named FILE-NAME. + "Append the current message to an Rmail (mbox) file named FILE-NAME. If the file does not exist, ask if it should be created. If file is being visited, the message is appended to the Emacs buffer visiting that file. @@ -130,111 +136,23 @@ (interactive (list (rmail-output-read-rmail-file-name) (prefix-numeric-value current-prefix-arg))) - (or count (setq count 1)) - (setq file-name - (expand-file-name file-name - (file-name-directory rmail-default-rmail-file))) - (if (and (file-readable-p file-name) (not (mail-file-babyl-p file-name))) - (rmail-output file-name count) - (rmail-maybe-set-message-counters) - (setq file-name (abbreviate-file-name file-name)) - (or (find-buffer-visiting file-name) - (file-exists-p file-name) - (if (yes-or-no-p - (concat "\"" file-name "\" does not exist, create it? ")) - (let ((file-buffer (create-file-buffer file-name))) - (save-excursion - (set-buffer file-buffer) - (rmail-insert-rmail-file-header) - (let ((require-final-newline nil) - (coding-system-for-write - (or rmail-file-coding-system - 'emacs-mule-unix))) - (write-region (point-min) (point-max) file-name t 1))) - (kill-buffer file-buffer)) - (error "Output file does not exist"))) - (while (> count 0) - (let (redelete) - (unwind-protect - (progn - (set-buffer rmail-buffer) - ;; Temporarily turn off Deleted attribute. - ;; Do this outside the save-restriction, since it would - ;; shift the place in the buffer where the visible text starts. - (if (rmail-message-deleted-p rmail-current-message) - (progn (setq redelete t) - (rmail-set-attribute "deleted" nil))) - (save-restriction - (widen) - ;; Decide whether to append to a file or to an Emacs buffer. - (save-excursion - (let ((buf (find-buffer-visiting file-name)) - (cur (current-buffer)) - (beg (1+ (rmail-msgbeg rmail-current-message))) - (end (1+ (rmail-msgend rmail-current-message))) - (coding-system-for-write - (or rmail-file-coding-system - 'emacs-mule-unix))) - (if (not buf) - ;; Output to a file. - (if rmail-fields-not-to-output - ;; Delete some fields while we output. - (let ((obuf (current-buffer))) - (set-buffer (get-buffer-create " rmail-out-temp")) - (insert-buffer-substring obuf beg end) - (rmail-delete-unwanted-fields) - (append-to-file (point-min) (point-max) file-name) - (set-buffer obuf) - (kill-buffer (get-buffer " rmail-out-temp"))) - (append-to-file beg end file-name)) - (if (eq buf (current-buffer)) - (error "Can't output message to same file it's already in")) - ;; File has been visited, in buffer BUF. - (set-buffer buf) - (let ((buffer-read-only nil) - (msg (and (boundp 'rmail-current-message) - rmail-current-message))) - ;; If MSG is non-nil, buffer is in RMAIL mode. - (if msg - (progn - ;; Turn on auto save mode, if it's off in this - ;; buffer but enabled by default. - (and (not buffer-auto-save-file-name) - auto-save-default - (auto-save-mode t)) - (rmail-maybe-set-message-counters) - (widen) - (narrow-to-region (point-max) (point-max)) - (insert-buffer-substring cur beg end) - (goto-char (point-min)) - (widen) - (search-backward "\n\^_") - (narrow-to-region (point) (point-max)) - (rmail-delete-unwanted-fields) - (rmail-count-new-messages t) - (if (rmail-summary-exists) - (rmail-select-summary - (rmail-update-summary))) - (rmail-show-message msg)) - ;; Output file not in rmail mode => just insert at the end. - (narrow-to-region (point-min) (1+ (buffer-size))) - (goto-char (point-max)) - (insert-buffer-substring cur beg end) - (rmail-delete-unwanted-fields))))))) - (rmail-set-attribute "filed" t)) - (if redelete (rmail-set-attribute "deleted" t)))) - (setq count (1- count)) - (if rmail-delete-after-output - (unless - (if (and (= count 0) stay) - (rmail-delete-message) - (rmail-delete-forward)) - (setq count 0)) - (if (> count 0) - (unless - (if (not stay) (rmail-next-undeleted-message 1)) - (setq count 0))))))) + + ;; Use the 'rmail-output function to perform the output. + (rmail-output file-name count nil nil) + ;; Deal with the next message + (if rmail-delete-after-output + (unless + (if (and (= count 0) stay) + (rmail-delete-message) + (rmail-delete-forward)) + (setq count 0)) + (if (> count 0) + (unless + (if (not stay) (rmail-next-undeleted-message 1)) + (setq count 0))))) + +;;; mbox: deprecated ;;;###autoload (defcustom rmail-fields-not-to-output nil "*Regexp describing fields to exclude when outputting a message to a file." @@ -242,6 +160,7 @@ regexp) :group 'rmail-output) +;;; mbox: deprecated ;; Delete from the buffer header fields we don't want output. ;; NOT-RMAIL if t means this buffer does not have the full header ;; and *** EOOH *** that a message in an Rmail file has. @@ -259,18 +178,15 @@ (delete-region (point) (progn (forward-line 1) (point))))))))) +;;; mbox: ready ;;; There are functions elsewhere in Emacs that use this function; ;;; look at them before you change the calling method. ;;;###autoload -(defun rmail-output (file-name &optional count noattribute from-gnus) - "Append this message to system-inbox-format mail file named FILE-NAME. -A prefix argument N says to output N consecutive messages -starting with the current one. Deleted messages are skipped and don't count. -When called from lisp code, N may be omitted. - -If the pruned message header is shown on the current message, then -messages will be appended with pruned headers; otherwise, messages -will be appended with their original headers. +(defun rmail-output (file-name &optional count noattribute ext) + "Append an mbox formatted message to the mbox formatted file named +FILE-NAME. A prefix argument COUNT says to output COUNT consecutive +messages starting with the current one. Deleted messages are skipped +and don't count. When called from lisp code, COUNT may be omitted. The default file name comes from `rmail-default-file', which is updated to the name you use in this command. @@ -278,7 +194,8 @@ The optional third argument NOATTRIBUTE, if non-nil, says not to set the `filed' attribute, and not to display a message. -The optional fourth argument FROM-GNUS is set when called from GNUS." +The optional fourth argument EXT is set when called from outside of an +Rmail function, for example by GNUS or Sendmail." (interactive (list (rmail-output-read-file-name) (prefix-numeric-value current-prefix-arg))) @@ -287,102 +204,101 @@ (expand-file-name file-name (and rmail-default-file (file-name-directory rmail-default-file)))) - (if (and (file-readable-p file-name) (mail-file-babyl-p file-name)) - (rmail-output-to-rmail-file file-name count) - (set-buffer rmail-buffer) - (let ((orig-count count) - (rmailbuf (current-buffer)) - (case-fold-search t) - (tembuf (get-buffer-create " rmail-output")) - (original-headers-p - (and (not from-gnus) - (save-excursion - (save-restriction - (narrow-to-region (rmail-msgbeg rmail-current-message) (point-max)) - (goto-char (point-min)) - (forward-line 1) - (= (following-char) ?0))))) - header-beginning - mail-from mime-version content-type) - (while (> count 0) - ;; Preserve the Mail-From and MIME-Version fields - ;; even if they have been pruned. - (or from-gnus - (save-excursion - (save-restriction - (widen) - (goto-char (rmail-msgbeg rmail-current-message)) - (setq header-beginning (point)) - (search-forward "\n*** EOOH ***\n") - (narrow-to-region header-beginning (point)) - (setq mail-from (mail-fetch-field "Mail-From")) - (unless rmail-enable-mime - (setq mime-version (mail-fetch-field "MIME-Version") - content-type (mail-fetch-field "Content-type")))))) - (save-excursion - (set-buffer tembuf) - (erase-buffer) - (insert-buffer-substring rmailbuf) - (when rmail-enable-mime - (if original-headers-p - (delete-region (goto-char (point-min)) - (if (search-forward "\n*** EOOH ***\n") - (match-end 0))) - (goto-char (point-min)) - (forward-line 2) - (delete-region (point-min)(point)) - (search-forward "\n*** EOOH ***\n") - (delete-region (match-beginning 0) - (if (search-forward "\n\n") - (1- (match-end 0))))) - (setq buffer-file-coding-system (or rmail-file-coding-system - 'raw-text))) - (rmail-delete-unwanted-fields t) - (or (bolp) (insert "\n")) - (goto-char (point-min)) - (if mail-from - (insert mail-from "\n") - (insert "From " - (mail-strip-quoted-names (or (mail-fetch-field "from") - (mail-fetch-field "really-from") - (mail-fetch-field "sender") - "unknown")) - " " (current-time-string) "\n")) - (if mime-version - (insert "MIME-Version: " mime-version - "\nContent-type: " content-type "\n")) - ;; ``Quote'' "\nFrom " as "\n>From " - ;; (note that this isn't really quoting, as there is no requirement - ;; that "\n[>]+From " be quoted in the same transparent way.) - (let ((case-fold-search nil)) - (while (search-forward "\nFrom " nil t) - (forward-char -5) - (insert ?>))) - (write-region (point-min) (point-max) file-name t - (if noattribute 'nomsg))) - (or noattribute - (if (equal major-mode 'rmail-mode) - (rmail-set-attribute "filed" t))) - (setq count (1- count)) - (or from-gnus - (let ((next-message-p - (if rmail-delete-after-output - (rmail-delete-forward) - (if (> count 0) - (rmail-next-undeleted-message 1)))) - (num-appended (- orig-count count))) - (if (and next-message-p original-headers-p) - (rmail-toggle-header)) - (if (and (> count 0) (not next-message-p)) - (progn - (error - (save-excursion - (set-buffer rmailbuf) - (format "Only %d message%s appended" num-appended - (if (= num-appended 1) "" "s")))) - (setq count 0)))))) - (kill-buffer tembuf)))) + + ;; Use the Rmail buffer, likely narrowed, as the message source + ;; unless being called from an external party, such as GNUS or + ;; Sendmail. + (unless ext + (set-buffer rmail-buffer)) + + (let ((orig-count count) + (src-buf (current-buffer)) + (dst-buf (find-buffer-visiting file-name)) + (current-message rmail-current-message) + (tembuf (get-buffer-create " rmail-output")) + (original-headers-p + (and (not ext) (not (rmail-msg-is-pruned))))) + + ;; Output each message to the destination file. + (while (> count 0) + (save-excursion + + ;; Copy the message, including all headers, to the temporary + ;; buffer. + (set-buffer tembuf) + (erase-buffer) + (insert-buffer-substring src-buf) + + ;; Deal with MIME --- tbd. + ;;(when rmail-enable-mime ... + + ;; Determine whether a buffer is already visiting the output + ;; file. + (if dst-buf + + ;; The destination file is being visited. Update it. + (progn + (set-buffer dst-buf) + + ;; Determine if the destination file is an Rmail file. + (let ((buffer-read-only nil) + (dst-current-message (and (boundp 'rmail-current-message) + rmail-current-message))) + (if dst-current-message + ;; The buffer is an Rmail buffer. Append the message. + (progn + (widen) + (narrow-to-region (point-max) (point-max)) + (insert-buffer-substring src-buf) + (insert "\n") + (rmail-process-new-messages) + (rmail-show-message dst-current-message)) + + ;; The destination file is not an Rmail file, just + ;; insert at the end. + (goto-char (point-max)) + (insert-buffer-substring src-buf)))) + + ;; The destination file is not being visited, just write out + ;; the processed message. + (write-region (point-min) (point-max) file-name t + (if noattribute 'nomsg)))) + + ;; Do housekeeping, such as setting the "Filed" attribute, if + ;; necessary and moving to the next message. + (or noattribute + (if (equal major-mode 'rmail-mode) + (progn + (rmail-set-attribute "filed" t current-message) + (setq current-message (1+ current-message))))) + + ;; Determine if Rmail post output operations need to be handled. + (or ext + + ;; They do. Move to the next non-deleted message. + (let ((next-message-p + (if rmail-delete-after-output + (rmail-delete-forward) + (if (> count 1) + (rmail-next-undeleted-message 1)))) + (num-appended (- orig-count count))) + (if (and (> count 1) (not next-message-p)) + (progn + (error + (save-excursion + (set-buffer src-buf) + (format "Only %d message%s appended" num-appended + (if (= num-appended 1) "" "s")))) + (setq count 0))))) + + ;; Decrement the count for the next iteration. If an error has + ;; occurred, then count will be -1, which is every bit as good + ;; as 0. + (setq count (1- count))) + (kill-buffer tembuf))) + +;;; mbox: ready ;;;###autoload (defun rmail-output-body-to-file (file-name) "Write this message body to the file FILE-NAME. @@ -409,7 +325,7 @@ (error "Operation aborted")) (write-region (point) (point-max) file-name) (if (equal major-mode 'rmail-mode) - (rmail-set-attribute "stored" t))) + (rmail-desc-set-attribute rmail-desc-stored-index t rmail-current-message))) (if rmail-delete-after-output (rmail-delete-forward)))