;; Use find-buffer-visiting, not get-file-buffer, for those users
;; who have find-file-visit-truename set to t.
(existed (find-buffer-visiting file-name))
- run-mail-hook msg-shown)
- ;; Like find-file, but in the case where a buffer existed
- ;; and the file was reverted, recompute the message-data.
- ;; We used to bind enable-local-variables to nil here,
- ;; but that should not be needed now that pmail-mode
- ;; sets it locally to nil.
- ;; (Binding a variable locally with let is not safe if it has
- ;; buffer-local bindings.)
+ run-mail-hook mail-buf msg-shown)
+ ;; Determine if an existing mail file has been changed behind the
+ ;; scene...
(if (and existed (not (verify-visited-file-modtime existed)))
+ ;; The mail file has been changed. Revisit it and reset the
+ ;; message state variables when in pmail mode.
(progn
(find-file file-name)
(when (and (verify-visited-file-modtime existed)
(eq major-mode 'pmail-mode))
- (pmail-forget-messages)
(pmail-set-message-counters)))
+ ;; The mail file is either unchanged or not visited. Visit it.
(switch-to-buffer
(let ((enable-local-variables nil))
(find-file-noselect file-name))))
+ ;; Insure that the collection and view buffers are in sync and
+ ;; insure that a message is not being edited.
(setq pmail-buffers-swapped-p nil)
(if (eq major-mode 'pmail-edit-mode)
(error "Exit Pmail Edit mode before getting new mail"))
- (if (and existed (> (buffer-size) 0))
- ;; Buffer not new and not empty; ensure in proper mode, but that's all.
- (or (eq major-mode 'pmail-mode)
- (progn (pmail-mode-2)
- (setq run-mail-hook t)))
- (setq run-mail-hook t)
- (pmail-mode-2)
- (pmail-convert-file-maybe)
- (goto-char (point-max)))
- ;; As we have read a file by raw-text, the buffer is set to
- ;; unibyte. We must make it multibyte if necessary.
- (if (and pmail-enable-multibyte
- (not enable-multibyte-characters))
- (set-buffer-multibyte t))
- ;; If necessary, scan to find all the messages.
+ ;; Insure that the Rmail file is in mbox format, the buffer is in
+ ;; Pmail mode and has been scanned to find all the messages
+ ;; (setting the global message variables in the process).
+ (pmail-convert-file-maybe)
+ (unless (eq major-mode 'pmail-mode)
+ (pmail-mode-2))
+ (goto-char (point-max))
(pmail-maybe-set-message-counters)
+ (setq mail-buf pmail-buffer)
+ ;; Show the first unread message and process summary mode.
(unwind-protect
- (unless (and (not file-name-arg) (pmail-get-new-mail))
- (pmail-show-message-maybe (pmail-first-unseen-message)))
+ ;; Only get new mail when there is not a file name argument.
+ (unless file-name-arg
+ (pmail-get-new-mail))
(progn
+ (set-buffer mail-buf)
+ (pmail-show-message-maybe (pmail-first-unseen-message))
(if pmail-display-summary (pmail-summary))
(pmail-construct-io-menu)
(if run-mail-hook
(message "Replacing BABYL format with mbox format...")
(let ((inhibit-read-only t))
(erase-buffer)
- (insert-file-contents-literally new-file))
+ (insert-file-contents-literally new-file)
+ (goto-char (point-max))
+ (pmail-set-message-counters))
(message "Replacing BABYL format with mbox format...done"))
(delete-file old-file)
(delete-file new-file))))
;; Pmail toolbar
(defvar pmail-tool-bar-map
- (if (display-graphic-p)
- (let ((map (make-sparse-keymap)))
- (tool-bar-local-item-from-menu 'pmail-get-new-mail "mail/inbox"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-next-undeleted-message "right-arrow"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-previous-undeleted-message "left-arrow"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-search "search"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-input "open"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-mail "mail/compose"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-reply "mail/reply-all"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-forward "mail/forward"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-delete-forward "close"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-output "mail/move"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-output-body-to-file "mail/save"
- map pmail-mode-map)
- (tool-bar-local-item-from-menu 'pmail-expunge "delete"
- map pmail-mode-map)
- map)))
+ (let ((map (make-sparse-keymap)))
+ (tool-bar-local-item-from-menu 'pmail-get-new-mail "mail/inbox"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-next-undeleted-message "right-arrow"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-previous-undeleted-message "left-arrow"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-search "search"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-input "open"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-mail "mail/compose"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-reply "mail/reply-all"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-forward "mail/forward"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-delete-forward "close"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-output "mail/move"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-output-body-to-file "mail/save"
+ map pmail-mode-map)
+ (tool-bar-local-item-from-menu 'pmail-expunge "delete"
+ map pmail-mode-map)
+ map))
\f
(setq mode-line-modified "--")
(use-local-map pmail-mode-map)
(set-syntax-table text-mode-syntax-table)
- (setq local-abbrev-table text-mode-abbrev-table))
+ (setq local-abbrev-table text-mode-abbrev-table)
+ ;; First attempt at adding hook functions to support buffer swapping...
+ (add-hook 'write-region-annotate-functions 'pmail-write-region-annotate nil t)
+ (add-hook 'kill-buffer-hook 'pmail-mode-kill-buffer-hook nil t)
+ (add-hook 'change-major-mode-hook 'pmail-change-major-mode-hook nil t))
(defun pmail-generate-viewer-buffer ()
- "Return a newly created buffer suitable for viewing messages."
- (let ((suffix (file-name-nondirectory (or buffer-file-name (buffer-name)))))
- (generate-new-buffer (format " *message-viewer %s*" suffix))))
+ "Return a reusable buffer suitable for viewing messages.
+Create the buffer if necessary."
+ (let* ((suffix (file-name-nondirectory (or buffer-file-name (buffer-name))))
+ (name (format " *message-viewer %s*" suffix))
+ (buf (get-buffer name)))
+ (unless buf
+ (generate-new-buffer name))))
+
+;; Used in write-region-annotate-functions to write Pmail files out
+;; correctly.
+(defun pmail-write-region-annotate (start end)
+ ;; When called from write-file (and auto-save), `start' is nil.
+ ;; When called from M-x write-region, we assume the user wants to save
+ ;; (part of) the inbox, not the message display data.
+ (unless (or start (not pmail-buffers-swapped-p))
+ ;;(tar-clear-modification-flags)
+ (set-buffer pmail-view-buffer)
+ (widen)
+ nil))
+
+(defun pmail-change-major-mode-hook ()
+ ;; Bring the actual Pmail messages back into the main buffer.
+ (when (pmail-buffers-swapped-p)
+ (current-buffer)
+ (buffer-swap-text pmail-view-buffer)))
+ ;; Throw away the summary.
+ ;;(when (buffer-live-p pmail-view-buffer) (kill-buffer pmail-view-buffer)))
+
+(defun pmail-buffers-swapped-p ()
+ "Return non-nil if the message collection is in `pmail-view-buffer'."
+ ;; We need to be careful to keep track of which buffer holds the
+ ;; message collection, since we swap the collection the view of the
+ ;; current message back and forth. This model is based on Stefan
+ ;; Monnier's solution for tar-mode.
+ (and (buffer-live-p pmail-view-buffer)
+ (> (buffer-size pmail-view-buffer) (buffer-size))))
+
+(defun pmail-mode-kill-buffer-hook ()
+ (if (buffer-live-p pmail-view-buffer) (kill-buffer pmail-view-buffer)))
;; Set up the permanent locals associated with an Pmail file.
(defun pmail-perm-variables ()
(make-local-variable 'pmail-summary-vector)
(make-local-variable 'pmail-current-message)
(make-local-variable 'pmail-total-messages)
+ (setq pmail-total-messages 0)
(make-local-variable 'pmail-overlay-list)
(setq pmail-overlay-list nil)
(make-local-variable 'pmail-message-vector)
(save-restriction
(let ((new-messages 0)
(spam-filter-p (and (featurep 'pmail-spam-filter) pmail-use-spam-filter))
- blurb success suffix)
+ blurb result success suffix)
(narrow-to-region (point) (point))
;; Read in the contents of the inbox files, renaming them as
;; necessary, and adding to the list of files to delete
(if rsf-beep (beep t))
(sleep-for rsf-sleep-after-message))
- ;; Move to the first new message
- ;; unless we have other unseen messages before it.
- (pmail-show-message-maybe (pmail-first-unseen-message))
+ ;; Establish the return value and move to the first new
+ ;; message unless we have other unseen messages before it.
+ (setq result (> new-messages 0))
+ (when result
+ (pmail-show-message-maybe (pmail-first-unseen-message)))
(run-hooks 'pmail-after-get-new-mail-hook)
- (> new-messages 0)))))
+ result))))
(defun pmail-get-new-mail-filter-spam (new-message-count)
"Process new messages for spam."
(pmail-swap-buffers-maybe)
(pmail-maybe-set-message-counters)
(widen)
- (let (blurb)
+ (let ((msgnum (or n pmail-current-message))
+ blurb)
(if (zerop pmail-total-messages)
(save-excursion
(with-current-buffer pmail-view-buffer
(erase-buffer)
(setq blurb "No mail.")))
- (setq blurb (pmail-show-message n))
+ (setq blurb (pmail-show-message msgnum))
(when mail-mailing-lists
(pmail-unknown-mail-followup-to))
(if transient-mark-mode (deactivate-mark))