hide-ifdef-mode documented; mark some entries as not needed doc updates.
[bpt/emacs.git] / lisp / mail / pmail.el
index 8643666..25fc614 100644 (file)
@@ -854,47 +854,43 @@ If `pmail-display-summary' is non-nil, make a summary for this PMAIL file."
         ;; 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
@@ -959,7 +955,9 @@ MSGNUM, if present, indicates the malformed message."
          (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))))
@@ -1203,33 +1201,32 @@ the region."
 
 ;; 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
@@ -1327,12 +1324,52 @@ Instead, these commands are available:
   (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 ()
@@ -1351,6 +1388,7 @@ Instead, these commands are available:
   (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)
@@ -1679,7 +1717,7 @@ new messages are found, nil otherwise."
     (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
@@ -1738,11 +1776,13 @@ new messages are found, nil otherwise."
          (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."
@@ -2847,13 +2887,14 @@ If summary buffer is currently displayed, update current message there also."
   (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))