]> code.delx.au - gnu-emacs/blobdiff - lisp/mail/rmail.el
Update copyright year to 2016
[gnu-emacs] / lisp / mail / rmail.el
index 643b5f947c7fad8be1014539245313df4d80d00d..2eb19dfef1f2037fcd4cdbe6398ff9771bd33875 100644 (file)
@@ -1,6 +1,6 @@
-;;; rmail.el --- main code of "RMAIL" mail reader for Emacs
+;;; rmail.el --- main code of "RMAIL" mail reader for Emacs  -*- lexical-binding:t -*-
 
 
-;; Copyright (C) 1985-1988, 1993-1998, 2000-2015 Free Software
+;; Copyright (C) 1985-1988, 1993-1998, 2000-2016 Free Software
 ;; Foundation, Inc.
 
 ;; Maintainer: emacs-devel@gnu.org
 ;; Foundation, Inc.
 
 ;; Maintainer: emacs-devel@gnu.org
@@ -98,7 +98,7 @@ its character representation and its display representation.")
 
 (defvar rmail-header-style 'normal
   "The current header display style choice, one of
 
 (defvar rmail-header-style 'normal
   "The current header display style choice, one of
-'normal (selected headers) or 'full (all headers).")
+`normal' (selected headers) or `full' (all headers).")
 
 (defvar rmail-mime-decoded nil
   "Non-nil if message has been processed by `rmail-show-mime-function'.")
 
 (defvar rmail-mime-decoded nil
   "Non-nil if message has been processed by `rmail-show-mime-function'.")
@@ -298,7 +298,7 @@ mail URLs as the source mailbox.")
 ;;;###autoload
 (defun rmail-movemail-variant-p (&rest variants)
   "Return t if the current movemail variant is any of VARIANTS.
 ;;;###autoload
 (defun rmail-movemail-variant-p (&rest variants)
   "Return t if the current movemail variant is any of VARIANTS.
-Currently known variants are 'emacs and 'mailutils."
+Currently known variants are `emacs' and `mailutils'."
   (when (not rmail-movemail-variant-in-use)
     ;; Autodetect
     (setq rmail-movemail-variant-in-use (rmail-autodetect)))
   (when (not rmail-movemail-variant-in-use)
     ;; Autodetect
     (setq rmail-movemail-variant-in-use (rmail-autodetect)))
@@ -316,7 +316,7 @@ Currently known variants are 'emacs and 'mailutils."
 If non-nil, this variable is used to identify the correspondent
 when receiving new mail.  If it matches the address of the sender,
 the recipient is taken as correspondent of a mail.
 If non-nil, this variable is used to identify the correspondent
 when receiving new mail.  If it matches the address of the sender,
 the recipient is taken as correspondent of a mail.
-If nil \(default value\), your `user-login-name' and `user-mail-address'
+If nil \(default value), your `user-login-name' and `user-mail-address'
 are used to exclude yourself as correspondent.
 
 Usually you don't have to set this variable, except if you collect mails
 are used to exclude yourself as correspondent.
 
 Usually you don't have to set this variable, except if you collect mails
@@ -393,7 +393,7 @@ go to that message and type \\[rmail-toggle-header] twice."
   "Regexp to match Header fields that Rmail should display.
 If nil, display all header fields except those matched by
 `rmail-ignored-headers'."
   "Regexp to match Header fields that Rmail should display.
 If nil, display all header fields except those matched by
 `rmail-ignored-headers'."
-  :type '(choice regexp (const :tag "All"))
+  :type '(choice regexp (const :tag "All" nil))
   :group 'rmail-headers)
 
 ;;;###autoload
   :group 'rmail-headers)
 
 ;;;###autoload
@@ -407,7 +407,7 @@ If nil, display all header fields except those matched by
 (defcustom rmail-highlighted-headers (purecopy "^From:\\|^Subject:")
   "Regexp to match Header fields that Rmail should normally highlight.
 A value of nil means don't highlight.  Uses the face `rmail-highlight'."
 (defcustom rmail-highlighted-headers (purecopy "^From:\\|^Subject:")
   "Regexp to match Header fields that Rmail should normally highlight.
 A value of nil means don't highlight.  Uses the face `rmail-highlight'."
-  :type 'regexp
+  :type '(choice regexp (const :tag "None" nil))
   :group 'rmail-headers)
 
 (defface rmail-highlight
   :group 'rmail-headers)
 
 (defface rmail-highlight
@@ -889,12 +889,12 @@ that knows the exact ordering of the \\( \\) subexpressions.")
 Signal an error and set `rmail-mime-feature' to nil if the feature
 isn't provided."
   (when rmail-enable-mime
 Signal an error and set `rmail-mime-feature' to nil if the feature
 isn't provided."
   (when rmail-enable-mime
-    (condition-case err
+    (condition-case nil
        (require rmail-mime-feature)
       (error
        (display-warning
        'rmail
        (require rmail-mime-feature)
       (error
        (display-warning
        'rmail
-       (format "Although MIME support is requested
+       (format-message "Although MIME support is requested
 through `rmail-enable-mime' being non-nil, the required feature
 `%s' (the value of `rmail-mime-feature')
 is not available in the current session.
 through `rmail-enable-mime' being non-nil, the required feature
 `%s' (the value of `rmail-mime-feature')
 is not available in the current session.
@@ -1586,13 +1586,12 @@ Hook `rmail-quit-hook' is run after expunging."
   (interactive)
   ;; This let var was called rmail-buffer, but that interfered
   ;; with the buffer-local var used in summary buffers.
   (interactive)
   ;; This let var was called rmail-buffer, but that interfered
   ;; with the buffer-local var used in summary buffers.
-  (let ((buffer-to-bury (current-buffer)))
-    (if (rmail-summary-exists)
-       (let (window)
-         (while (setq window (get-buffer-window rmail-summary-buffer))
-           (quit-window nil window))
-         (bury-buffer rmail-summary-buffer)))
-    (quit-window)))
+  (if (rmail-summary-exists)
+      (let (window)
+        (while (setq window (get-buffer-window rmail-summary-buffer))
+          (quit-window nil window))
+        (bury-buffer rmail-summary-buffer)))
+  (quit-window))
 \f
 (defun rmail-duplicate-message ()
   "Create a duplicated copy of the current message.
 \f
 (defun rmail-duplicate-message ()
   "Create a duplicated copy of the current message.
@@ -1760,15 +1759,14 @@ not be a new one).  It returns non-nil if it got any new messages."
          ;; This loops if any members of the inbox list have the same
          ;; basename (see "name conflict" below).
          (while all-files
          ;; This loops if any members of the inbox list have the same
          ;; basename (see "name conflict" below).
          (while all-files
-           (let ((opoint (point))
-                 ;; If buffer has not changed yet, and has not been
+           (let (;; If buffer has not changed yet, and has not been
                  ;; saved yet, don't replace the old backup file now.
                  (make-backup-files (and make-backup-files
                                          (buffer-modified-p)))
                  (buffer-read-only nil)
                  ;; Don't make undo records while getting mail.
                  (buffer-undo-list t)
                  ;; saved yet, don't replace the old backup file now.
                  (make-backup-files (and make-backup-files
                                          (buffer-modified-p)))
                  (buffer-read-only nil)
                  ;; Don't make undo records while getting mail.
                  (buffer-undo-list t)
-                 delete-files success files file-last-names)
+                 delete-files files file-last-names)
              ;; Pull files off all-files onto files as long as there is
              ;; no name conflict.  A conflict happens when two inbox
              ;; file names have the same last component.
              ;; Pull files off all-files onto files as long as there is
              ;; no name conflict.  A conflict happens when two inbox
              ;; file names have the same last component.
@@ -1787,7 +1785,7 @@ not be a new one).  It returns non-nil if it got any new messages."
              ;; Make sure we end with a blank line unless there are
              ;; no messages, as required by mbox format (Bug#9974).
              (unless (bobp)
              ;; Make sure we end with a blank line unless there are
              ;; no messages, as required by mbox format (Bug#9974).
              (unless (bobp)
-               (while (not (looking-back "\n\n"))
+               (while (not (looking-back "\n\n" (- (point) 2)))
                  (insert "\n")))
              (setq found (or
                           (rmail-get-new-mail-1 file-name files delete-files)
                  (insert "\n")))
              (setq found (or
                           (rmail-get-new-mail-1 file-name files delete-files)
@@ -1910,9 +1908,10 @@ is non-nil if the user has supplied the password interactively.
 
    ((string-match "^po:\\([^:]+\\)\\(:\\(.*\\)\\)?" file)
     (let (got-password supplied-password
 
    ((string-match "^po:\\([^:]+\\)\\(:\\(.*\\)\\)?" file)
     (let (got-password supplied-password
-          (proto "pop")
-         (user  (match-string 1 file))
-         (host  (match-string 3 file)))
+          ;; (proto "pop")
+         ;; (user  (match-string 1 file))
+         ;; (host  (match-string 3 file))
+          )
 
       (when rmail-remote-password-required
        (setq got-password (not (rmail-have-password)))
 
       (when rmail-remote-password-required
        (setq got-password (not (rmail-have-password)))
@@ -1945,8 +1944,7 @@ SIZE is the original size of the newly read mail.
 Value is the size of the newly read mail after conversion."
   ;; Detect previous Babyl format files.
   (let ((case-fold-search nil)
 Value is the size of the newly read mail after conversion."
   ;; Detect previous Babyl format files.
   (let ((case-fold-search nil)
-       (old-file file)
-       new-file)
+       (old-file file))
     (cond ((looking-at "BABYL OPTIONS:")
           ;; The new mail is in Babyl version 5 format.  Use unrmail
           ;; to convert it.
     (cond ((looking-at "BABYL OPTIONS:")
           ;; The new mail is in Babyl version 5 format.  Use unrmail
           ;; to convert it.
@@ -1972,7 +1970,7 @@ Value is the size of the newly read mail after conversion."
   (or (memq (file-locked-p buffer-file-name) '(nil t))
       (error "RMAIL file %s is locked"
             (file-name-nondirectory buffer-file-name)))
   (or (memq (file-locked-p buffer-file-name) '(nil t))
       (error "RMAIL file %s is locked"
             (file-name-nondirectory buffer-file-name)))
-  (let (file tofile delete-files movemail popmail got-password password)
+  (let (file tofile delete-files popmail got-password password)
     (while files
       ;; Handle remote mailbox names specially; don't expand as filenames
       ;; in case the userid contains a directory separator.
     (while files
       ;; Handle remote mailbox names specially; don't expand as filenames
       ;; in case the userid contains a directory separator.
@@ -2092,7 +2090,7 @@ Value is the size of the newly read mail after conversion."
            ;; Make sure the read-in mbox data properly ends with a
            ;; blank line unless it is of size 0.
            (unless (zerop size)
            ;; Make sure the read-in mbox data properly ends with a
            ;; blank line unless it is of size 0.
            (unless (zerop size)
-             (while (not (looking-back "\n\n"))
+             (while (not (looking-back "\n\n" (- (point) 2)))
                (insert "\n")))
            (if (not (and rmail-preserve-inbox (string= file tofile)))
                (setq delete-files (cons tofile delete-files)))))
                (insert "\n")))
            (if (not (and rmail-preserve-inbox (string= file tofile)))
                (setq delete-files (cons tofile delete-files)))))
@@ -2127,7 +2125,7 @@ Value is the size of the newly read mail after conversion."
 Call with point at the end of the message."
   (unless (bolp)
     (insert "\n"))
 Call with point at the end of the message."
   (unless (bolp)
     (insert "\n"))
-  (unless (looking-back "\n\n")
+  (unless (looking-back "\n\n" (- (point) 2))
     (insert "\n")))
 
 (defun rmail-add-mbox-headers ()
     (insert "\n")))
 
 (defun rmail-add-mbox-headers ()
@@ -2144,7 +2142,7 @@ new messages.  Return the number of new messages."
            (value "------U-")
            (case-fold-search nil)
            (delim (concat "\n\n" rmail-unix-mail-delimiter))
            (value "------U-")
            (case-fold-search nil)
            (delim (concat "\n\n" rmail-unix-mail-delimiter))
-           limit stop)
+           stop)
        ;; Detect an empty inbox file.
        (unless (= start (point-max))
          ;; Scan the new messages to establish a count and to ensure that
        ;; Detect an empty inbox file.
        (unless (= start (point-max))
          ;; Scan the new messages to establish a count and to ensure that
@@ -2664,8 +2662,8 @@ Ask the user whether to add that list name to `mail-mailing-lists'."
                                      "\\>\\)"))
                          addr))
                        (y-or-n-p
                                      "\\>\\)"))
                          addr))
                        (y-or-n-p
-                        (format "Add `%s' to `mail-mailing-lists'? "
-                                addr)))
+                        (format-message "Add `%s' to `mail-mailing-lists'? "
+                                        addr)))
               (customize-save-variable 'mail-mailing-lists
                                        (cons addr mail-mailing-lists)))))))))
 
               (customize-save-variable 'mail-mailing-lists
                                        (cons addr mail-mailing-lists)))))))))
 
@@ -2889,7 +2887,7 @@ The current mail message becomes the message displayed."
          (setq blurb (format "Showing message %d...done" msg)))))
     blurb))
 
          (setq blurb (format "Showing message %d...done" msg)))))
     blurb))
 
-(defun rmail-copy-headers (beg end &optional ignored-headers)
+(defun rmail-copy-headers (beg _end &optional ignored-headers)
   "Copy displayed header fields to the message viewer buffer.
 BEG and END marks the start and end positions of the message in
 the mbox buffer.  If the optional argument IGNORED-HEADERS is
   "Copy displayed header fields to the message viewer buffer.
 BEG and END marks the start and end positions of the message in
 the mbox buffer.  If the optional argument IGNORED-HEADERS is
@@ -2942,7 +2940,8 @@ buffer to the end of the headers."
                              (1+ (match-beginning 0))
                            (point-max))))
              (if (and (looking-at ignored-headers)
                              (1+ (match-beginning 0))
                            (point-max))))
              (if (and (looking-at ignored-headers)
-                      (not (looking-at rmail-nonignored-headers)))
+                      (not (and rmail-nonignored-headers
+                                (looking-at rmail-nonignored-headers))))
                  (goto-char lim)
                (append-to-buffer rmail-view-buffer (point) lim)
                (goto-char lim))))
                  (goto-char lim)
                (append-to-buffer rmail-view-buffer (point) lim)
                (goto-char lim))))
@@ -3152,7 +3151,7 @@ or forward if N is negative."
   (rmail-maybe-set-message-counters)
   (rmail-show-message rmail-total-messages))
 
   (rmail-maybe-set-message-counters)
   (rmail-show-message rmail-total-messages))
 
-(defun rmail-next-error-move (msg-pos bad-marker)
+(defun rmail-next-error-move (msg-pos _bad-marker)
   "Move to an error locus (probably grep hit) in an Rmail buffer.
 MSG-POS is a marker pointing at the error message in the grep buffer.
 BAD-MARKER is a marker that ought to point at where to move to,
   "Move to an error locus (probably grep hit) in an Rmail buffer.
 MSG-POS is a marker pointing at the error message in the grep buffer.
 BAD-MARKER is a marker that ought to point at where to move to,
@@ -3462,21 +3461,20 @@ STATE non-nil means mark as deleted."
   "Back up to deleted message, select it, and undelete it."
   (interactive "p")
   (set-buffer rmail-buffer)
   "Back up to deleted message, select it, and undelete it."
   (interactive "p")
   (set-buffer rmail-buffer)
-  (let (value)
-    (dotimes (i count)
-      (let ((msg rmail-current-message))
-       (while (and (> msg 0)
-                   (not (rmail-message-deleted-p msg)))
-         (setq msg (1- msg)))
-       (if (= msg 0)
-           (error "No previous deleted message")
-         (if (/= msg rmail-current-message)
-             (rmail-show-message msg))
-         (rmail-set-attribute rmail-deleted-attr-index nil)
-         (if (rmail-summary-exists)
-             (with-current-buffer rmail-summary-buffer
-               (rmail-summary-mark-undeleted msg))))))
-    (rmail-maybe-display-summary)))
+  (dotimes (_ count)
+    (let ((msg rmail-current-message))
+      (while (and (> msg 0)
+                  (not (rmail-message-deleted-p msg)))
+        (setq msg (1- msg)))
+      (if (= msg 0)
+          (error "No previous deleted message")
+        (if (/= msg rmail-current-message)
+            (rmail-show-message msg))
+        (rmail-set-attribute rmail-deleted-attr-index nil)
+        (if (rmail-summary-exists)
+            (with-current-buffer rmail-summary-buffer
+              (rmail-summary-mark-undeleted msg))))))
+  (rmail-maybe-display-summary))
 
 (defun rmail-delete-forward (&optional count)
   "Delete this message and move to next nondeleted one.
 
 (defun rmail-delete-forward (&optional count)
   "Delete this message and move to next nondeleted one.
@@ -3490,7 +3488,7 @@ Returns t if a new message is displayed after the delete, or nil otherwise."
   (let (value backward)
     (if (< count 0)
        (setq count (- count) backward t))
   (let (value backward)
     (if (< count 0)
        (setq count (- count) backward t))
-    (dotimes (i count)
+    (dotimes (_ count)
       (rmail-set-attribute rmail-deleted-attr-index t)
       (run-hooks 'rmail-delete-message-hook)
       (let ((del-msg rmail-current-message))
       (rmail-set-attribute rmail-deleted-attr-index t)
       (run-hooks 'rmail-delete-message-hook)
       (let ((del-msg rmail-current-message))
@@ -3787,7 +3785,7 @@ use \\[mail-yank-original] to yank the original message into it."
   (if (zerop rmail-current-message)
       (error "There is no message to reply to"))
   (let (from reply-to cc subject date to message-id references
   (if (zerop rmail-current-message)
       (error "There is no message to reply to"))
   (let (from reply-to cc subject date to message-id references
-            resent-to resent-cc resent-reply-to
+            ;; resent-to resent-cc resent-reply-to
             (msgnum rmail-current-message))
     (rmail-apply-in-message
      rmail-current-message
             (msgnum rmail-current-message))
     (rmail-apply-in-message
      rmail-current-message
@@ -3802,14 +3800,14 @@ use \\[mail-yank-original] to yank the original message into it."
             date (mail-fetch-field "date")
             message-id (mail-fetch-field "message-id")
             references (mail-fetch-field "references" nil nil t)
             date (mail-fetch-field "date")
             message-id (mail-fetch-field "message-id")
             references (mail-fetch-field "references" nil nil t)
-            resent-reply-to (mail-fetch-field "resent-reply-to" nil t)
             ;; Bug#512.  It's inappropriate to reply to these addresses.
             ;; Bug#512.  It's inappropriate to reply to these addresses.
-;;;         resent-cc (and (not just-sender)
-;;;                        (mail-fetch-field "resent-cc" nil t))
-;;;         resent-to (or (mail-fetch-field "resent-to" nil t) "")
-;;;         resent-subject (mail-fetch-field "resent-subject")
-;;;         resent-date (mail-fetch-field "resent-date")
-;;;         resent-message-id (mail-fetch-field "resent-message-id")
+            ;;resent-reply-to (mail-fetch-field "resent-reply-to" nil t)
+            ;;resent-cc (and (not just-sender)
+            ;;             (mail-fetch-field "resent-cc" nil t))
+            ;;resent-to (or (mail-fetch-field "resent-to" nil t) "")
+            ;;resent-subject (mail-fetch-field "resent-subject")
+            ;;resent-date (mail-fetch-field "resent-date")
+            ;;resent-message-id (mail-fetch-field "resent-message-id")
             )
        (unless just-sender
         (if (mail-fetch-field "mail-followup-to" nil t)
             )
        (unless just-sender
         (if (mail-fetch-field "mail-followup-to" nil t)
@@ -3820,17 +3818,18 @@ use \\[mail-yank-original] to yank the original message into it."
                 to (or (mail-fetch-field "to" nil t) ""))))))
     ;; Merge the resent-to and resent-cc into the to and cc.
     ;; Bug#512.  It's inappropriate to reply to these addresses.
                 to (or (mail-fetch-field "to" nil t) ""))))))
     ;; Merge the resent-to and resent-cc into the to and cc.
     ;; Bug#512.  It's inappropriate to reply to these addresses.
-;;;    (if (and resent-to (not (equal resent-to "")))
-;;;    (if (not (equal to ""))
-;;;        (setq to (concat to ", " resent-to))
-;;;      (setq to resent-to)))
-;;;    (if (and resent-cc (not (equal resent-cc "")))
-;;;    (if (not (equal cc ""))
-;;;        (setq cc (concat cc ", " resent-cc))
-;;;      (setq cc resent-cc)))
+    ;;(if (and resent-to (not (equal resent-to "")))
+    ;;    (setq to (if (not (equal to ""))
+    ;;                 (concat to ", " resent-to)
+    ;;               resent-to)))
+    ;;(if (and resent-cc (not (equal resent-cc "")))
+    ;;    (setq cc (if (not (equal cc ""))
+    ;;                 (concat cc ", " resent-cc)
+    ;;               resent-cc)))
     ;; Add `Re: ' to subject if not there already.
     (and (stringp subject)
     ;; Add `Re: ' to subject if not there already.
     (and (stringp subject)
-        (setq subject
+        (setq subject (rfc2047-decode-string subject)
+              subject
               (concat rmail-reply-prefix
                       (if (let ((case-fold-search t))
                             (string-match rmail-reply-regexp subject))
               (concat rmail-reply-prefix
                       (if (let ((case-fold-search t))
                             (string-match rmail-reply-regexp subject))
@@ -4145,6 +4144,9 @@ The message should be narrowed to just the headers."
 
 (declare-function rmail-mime-toggle-raw "rmailmm" (&optional state))
 
 
 (declare-function rmail-mime-toggle-raw "rmailmm" (&optional state))
 
+(defvar rmail-mime-mbox-buffer)
+(defvar rmail-mime-view-buffer)
+
 (defun rmail-retry-failure ()
   "Edit a mail message which is based on the contents of the current message.
 For a message rejected by the mail system, extract the interesting headers and
 (defun rmail-retry-failure ()
   "Edit a mail message which is based on the contents of the current message.
 For a message rejected by the mail system, extract the interesting headers and
@@ -4421,13 +4423,13 @@ current message into that RMAIL folder."
 (declare-function dframe-select-attached-frame "dframe" (&optional frame))
 (declare-function dframe-maybee-jump-to-attached-frame "dframe" ())
 
 (declare-function dframe-select-attached-frame "dframe" (&optional frame))
 (declare-function dframe-maybee-jump-to-attached-frame "dframe" ())
 
-(defun rmail-speedbar-button (text token indent)
+(defun rmail-speedbar-button (_text token _indent)
   "Execute an rmail command specified by TEXT.
 The command used is TOKEN.  INDENT is not used."
   (dframe-with-attached-buffer
    (funcall token t)))
 
   "Execute an rmail command specified by TEXT.
 The command used is TOKEN.  INDENT is not used."
   (dframe-with-attached-buffer
    (funcall token t)))
 
-(defun rmail-speedbar-find-file (text token indent)
+(defun rmail-speedbar-find-file (text _token _indent)
   "Load in the rmail file TEXT.
 TOKEN and INDENT are not used."
   (dframe-with-attached-buffer
   "Load in the rmail file TEXT.
 TOKEN and INDENT are not used."
   (dframe-with-attached-buffer
@@ -4446,7 +4448,7 @@ TOKEN and INDENT are not used."
          (forward-char -2)
          (speedbar-do-function-pointer)))))
 
          (forward-char -2)
          (speedbar-do-function-pointer)))))
 
-(defun rmail-speedbar-move-message (text token indent)
+(defun rmail-speedbar-move-message (_text token _indent)
   "From button TEXT, copy current message to the rmail file specified by TOKEN.
 TEXT and INDENT are not used."
   (dframe-with-attached-buffer
   "From button TEXT, copy current message to the rmail file specified by TOKEN.
 TEXT and INDENT are not used."
   (dframe-with-attached-buffer
@@ -4506,9 +4508,78 @@ encoded string (and the same mask) will decode the string."
      (setq i (1+ i)))
    (concat string-vector)))
 
      (setq i (1+ i)))
    (concat string-vector)))
 
+(defun rmail-epa-decrypt-1 (mime)
+  "Decrypt a single GnuPG encrypted text in a message.
+The starting string of the encrypted text should have just been regexp-matched.
+Argument MIME is non-nil if this is a mime message."
+  (let* ((armor-start (match-beginning 0))
+         (armor-prefix (buffer-substring
+                        (line-beginning-position)
+                        armor-start))
+         (armor-end-regexp)
+         armor-end after-end
+         unquote)
+    (if (string-match "<pre>\\'" armor-prefix)
+        (setq armor-prefix ""))
+
+    (setq armor-end-regexp
+          (concat "^"
+                  armor-prefix
+                  "-----END PGP MESSAGE-----$"))
+    (setq armor-end (re-search-forward armor-end-regexp
+                                       nil t))
+
+    (unless armor-end
+      (error "Encryption armor beginning has no matching end"))
+    (goto-char armor-start)
+
+    ;; Because epa--find-coding-system-for-mime-charset not autoloaded.
+    (require 'epa)
+
+    ;; Advance over this armor.
+    (goto-char armor-end)
+    (setq after-end (- (point-max) armor-end))
+
+    (when mime
+      (save-excursion
+        (goto-char armor-start)
+        (re-search-backward "^--" nil t)
+        (save-restriction
+          (narrow-to-region (point) armor-start)
+
+          ;; Use the charset specified in the armor.
+          (unless coding-system-for-read
+            (if (re-search-forward "^[ \t]*Charset[ \t\n]*:[ \t\n]*\\(.*\\)" nil t)
+                (setq coding-system-for-read
+                      (epa--find-coding-system-for-mime-charset
+                       (intern (downcase (match-string 1)))))))
+
+          (goto-char (point-min))
+          (if (re-search-forward "^[ \t]*Content-transfer-encoding[ \t\n]*:[ \t\n]*quoted-printable[ \t]*$" nil t)
+              (setq unquote t)))))
+
+    (when unquote
+      (let ((inhibit-read-only t))
+        (mail-unquote-printable-region armor-start
+                                       (- (point-max) after-end))))
+
+    ;; Decrypt it, maybe in place, maybe making new buffer.
+    (epa-decrypt-region
+     armor-start (- (point-max) after-end)
+     ;; Call back this function to prepare the output.
+     (lambda ()
+       (let ((inhibit-read-only t))
+         (delete-region armor-start (- (point-max) after-end))
+         (goto-char armor-start)
+         (current-buffer))))
+
+    (list armor-start (- (point-max) after-end) mime
+          armor-end-regexp)))
+
 ;; Should this have a key-binding, or be in a menu?
 ;; There doesn't really seem to be an appropriate menu.
 ;; Eg the edit command is not in a menu either.
 ;; Should this have a key-binding, or be in a menu?
 ;; There doesn't really seem to be an appropriate menu.
 ;; Eg the edit command is not in a menu either.
+
 (defun rmail-epa-decrypt ()
   "Decrypt GnuPG or OpenPGP armors in current message."
   (interactive)
 (defun rmail-epa-decrypt ()
   "Decrypt GnuPG or OpenPGP armors in current message."
   (interactive)
@@ -4517,12 +4588,14 @@ encoded string (and the same mask) will decode the string."
   ;; change it in one of the calls to `epa-decrypt-region'.
 
   (save-excursion
   ;; change it in one of the calls to `epa-decrypt-region'.
 
   (save-excursion
-    (let (decrypts (mime (rmail-mime-message-p)))
+    (let (decrypts (mime (rmail-mime-message-p))
+                   mime-disabled)
       (goto-char (point-min))
 
       ;; Turn off mime processing.
       (when (and mime
                 (not (get-text-property (point-min) 'rmail-mime-hidden)))
       (goto-char (point-min))
 
       ;; Turn off mime processing.
       (when (and mime
                 (not (get-text-property (point-min) 'rmail-mime-hidden)))
+        (setq mime-disabled t)
        (rmail-mime))
 
       ;; Now find all armored messages in the buffer
        (rmail-mime))
 
       ;; Now find all armored messages in the buffer
@@ -4530,68 +4603,12 @@ encoded string (and the same mask) will decode the string."
       (goto-char (point-min))
       (while (re-search-forward "-----BEGIN PGP MESSAGE-----$" nil t)
        (let ((coding-system-for-read coding-system-for-read)
       (goto-char (point-min))
       (while (re-search-forward "-----BEGIN PGP MESSAGE-----$" nil t)
        (let ((coding-system-for-read coding-system-for-read)
-             (case-fold-search t)
-             unquote
-             armor-start armor-prefix armor-end after-end)
-
-         (setq armor-start (match-beginning 0)
-               armor-prefix (buffer-substring
-                             (line-beginning-position)
-                             armor-start)
-               armor-end (re-search-forward
-                          (concat "^"
-                                  armor-prefix
-                                  "-----END PGP MESSAGE-----$")
-                          nil t))
-         (unless armor-end
-           (error "Encryption armor beginning has no matching end"))
-         (goto-char armor-start)
-
-         ;; Because epa--find-coding-system-for-mime-charset not autoloaded.
-         (require 'epa)
-
-         ;; Advance over this armor.
-         (goto-char armor-end)
-         (setq after-end (- (point-max) armor-end))
-
-         (when mime
-           (save-excursion
-             (goto-char armor-start)
-             (re-search-backward "^--" nil t)
-             (save-restriction
-               (narrow-to-region (point) armor-start)
-
-               ;; Use the charset specified in the armor.
-               (unless coding-system-for-read
-                 (if (re-search-forward "^Charset: \\(.*\\)" nil t)
-                     (setq coding-system-for-read
-                           (epa--find-coding-system-for-mime-charset
-                            (intern (downcase (match-string 1)))))))
-
-               (goto-char (point-min))
-               (if (re-search-forward "^[ \t]*Content-transfer-encoding[ \t]*:[ \t]*quoted-printable[ \t]*$" nil t)
-                   (setq unquote t)))))
-
-         (when unquote
-           (let ((inhibit-read-only t))
-             (mail-unquote-printable-region armor-start
-                                            (- (point-max) after-end))))
-
-         ;; Decrypt it, maybe in place, maybe making new buffer.
-         (epa-decrypt-region
-          armor-start (- (point-max) after-end)
-          ;; Call back this function to prepare the output.
-          (lambda ()
-            (let ((inhibit-read-only t))
-              (delete-region armor-start (- (point-max) after-end))
-              (goto-char armor-start)
-              (current-buffer))))
-
-         (push (list armor-start (- (point-max) after-end))
-               decrypts)))
+             (case-fold-search t))
 
 
-      (unless decrypts
-       (error "Nothing to decrypt"))
+          (push (rmail-epa-decrypt-1 mime) decrypts)))
+
+      (when (and decrypts (eq major-mode 'rmail-mode))
+        (rmail-add-label "decrypt"))
 
       (when (and decrypts (rmail-buffers-swapped-p))
        (when (y-or-n-p "Replace the original message? ")
 
       (when (and decrypts (rmail-buffers-swapped-p))
        (when (y-or-n-p "Replace the original message? ")
@@ -4603,25 +4620,69 @@ encoded string (and the same mask) will decode the string."
              (narrow-to-region beg end)
              (goto-char (point-min))
              (dolist (d decrypts)
              (narrow-to-region beg end)
              (goto-char (point-min))
              (dolist (d decrypts)
+               ;; Find, in the real Rmail buffer, the same armors
+               ;; that we found and decrypted in the view buffer.
                (if (re-search-forward "-----BEGIN PGP MESSAGE-----$" nil t)
                (if (re-search-forward "-----BEGIN PGP MESSAGE-----$" nil t)
-                   (let (armor-start armor-end)
+                   (let (armor-start armor-end armor-end-regexp)
                      (setq armor-start (match-beginning 0)
                      (setq armor-start (match-beginning 0)
-                           armor-end (re-search-forward "^-----END PGP MESSAGE-----$"
-                                                        nil t))
+                           armor-end-regexp (nth 3 d)
+                           armor-end (re-search-forward
+                                      armor-end-regexp
+                                      nil t))
+
+                     ;; Found as expected -- now replace it with the decrypt.
                      (when armor-end
                        (delete-region armor-start armor-end)
                      (when armor-end
                        (delete-region armor-start armor-end)
-                       (insert-buffer-substring from-buffer (nth 0 d) (nth 1 d)))))))))))))
+                       (insert-buffer-substring from-buffer (nth 0 d) (nth 1 d)))
+
+                     ;; Change the mime type (if this is in a mime part)
+                     ;; so this part will display by default
+                     ;; when the message is shown later.
+                     (when (nth 2 d)
+                       (goto-char armor-start)
+                       (when (re-search-backward "^--" nil t)
+                         (save-restriction
+                           (narrow-to-region (point) armor-start)
+                           (when (re-search-forward "^content-type[ \t\n]*:[ \t\n]*" nil t)
+                             (when (looking-at "[^\n \t;]+")
+                               (let ((value (match-string 0)))
+                                 (unless (member value '("text/plain" "text/html"))
+                                   (replace-match "text/plain"))))))))
+                     )))))))
+
+      (when (and (null decrypts)
+                 mime mime-disabled)
+        ;; Re-enable mime processing.
+       (rmail-mime)
+        ;; Find each Show button and show that part.
+       (while (search-forward " Show " nil t)
+         (forward-char -2)
+         (let ((rmail-mime-render-html-function nil)
+               (entity (get-text-property (point) 'rmail-mime-entity)))
+            (unless (and (not (stringp entity))
+                         (rmail-mime-entity-truncated entity))
+              (push-button))))
+        (goto-char (point-min))
+        (while (re-search-forward "-----BEGIN PGP MESSAGE-----$" nil t)
+          (let ((coding-system-for-read coding-system-for-read)
+                (case-fold-search t))
+            (push (rmail-epa-decrypt-1 mime) decrypts)))
+
+        )
+
+      (unless decrypts
+       (error "Nothing to decrypt")))))
+
 \f
 ;;;;  Desktop support
 
 \f
 ;;;;  Desktop support
 
-(defun rmail-restore-desktop-buffer (desktop-buffer-file-name
-                                    desktop-buffer-name
-                                    desktop-buffer-misc)
+(defun rmail-restore-desktop-buffer (file-name
+                                    _buffer-name
+                                    _buffer-misc)
   "Restore an rmail buffer specified in a desktop file."
   "Restore an rmail buffer specified in a desktop file."
-  (condition-case error
+  (condition-case nil
       (progn
       (progn
-       (rmail-input desktop-buffer-file-name)
+       (rmail-input file-name)
        (if (eq major-mode 'rmail-mode)
            (current-buffer)
          rmail-buffer))
        (if (eq major-mode 'rmail-mode)
            (current-buffer)
          rmail-buffer))
@@ -4637,7 +4698,7 @@ encoded string (and the same mask) will decode the string."
 (defvar rmail-message-encoding nil)
 
 ;; Used in `write-region-annotate-functions' to write rmail files.
 (defvar rmail-message-encoding nil)
 
 ;; Used in `write-region-annotate-functions' to write rmail files.
-(defun rmail-write-region-annotate (start end)
+(defun rmail-write-region-annotate (start _end)
   (when (and (null start) rmail-buffer-swapped)
     (unless (buffer-live-p rmail-view-buffer)
       (error "Buffer `%s' with real text of `%s' has disappeared"
   (when (and (null start) rmail-buffer-swapped)
     (unless (buffer-live-p rmail-view-buffer)
       (error "Buffer `%s' with real text of `%s' has disappeared"
@@ -4664,7 +4725,7 @@ encoded string (and the same mask) will decode the string."
 \f
 ;;; Start of automatically extracted autoloads.
 \f
 \f
 ;;; Start of automatically extracted autoloads.
 \f
-;;;### (autoloads nil "rmailedit" "rmailedit.el" "f6da7267316d02c90b9d314ce95b3c22")
+;;;### (autoloads nil "rmailedit" "rmailedit.el" "1ed1c211e6e9c254ba3e0dd8d546e745")
 ;;; Generated autoloads from rmailedit.el
 
 (autoload 'rmail-edit-current-message "rmailedit" "\
 ;;; Generated autoloads from rmailedit.el
 
 (autoload 'rmail-edit-current-message "rmailedit" "\
@@ -4717,7 +4778,7 @@ With prefix argument N moves forward N messages with these labels.
 
 ;;;***
 \f
 
 ;;;***
 \f
-;;;### (autoloads nil "rmailmm" "rmailmm.el" "43e0b9f680c4d2581640b286bd4b3107")
+;;;### (autoloads nil "rmailmm" "rmailmm.el" "36f518e036612a33eb436cb267fd39c7")
 ;;; Generated autoloads from rmailmm.el
 
 (autoload 'rmail-mime "rmailmm" "\
 ;;; Generated autoloads from rmailmm.el
 
 (autoload 'rmail-mime "rmailmm" "\
@@ -4814,7 +4875,7 @@ If prefix argument REVERSE is non-nil, sorts in reverse order.
 
 ;;;***
 \f
 
 ;;;***
 \f
-;;;### (autoloads nil "rmailsum" "rmailsum.el" "e3943ef45946f10b9b5cab8097d7f271")
+;;;### (autoloads nil "rmailsum" "rmailsum.el" "4bc0d1a65aede332348200e1937c84d4")
 ;;; Generated autoloads from rmailsum.el
 
 (autoload 'rmail-summary "rmailsum" "\
 ;;; Generated autoloads from rmailsum.el
 
 (autoload 'rmail-summary "rmailsum" "\
@@ -4833,7 +4894,7 @@ Display a summary of all messages with the given RECIPIENTS.
 Normally checks the To, From and Cc fields of headers;
 but if PRIMARY-ONLY is non-nil (prefix arg given),
  only look in the To and From fields.
 Normally checks the To, From and Cc fields of headers;
 but if PRIMARY-ONLY is non-nil (prefix arg given),
  only look in the To and From fields.
-RECIPIENTS is a string of regexps separated by commas.
+RECIPIENTS is a regular expression.
 
 \(fn RECIPIENTS &optional PRIMARY-ONLY)" t nil)
 
 
 \(fn RECIPIENTS &optional PRIMARY-ONLY)" t nil)
 
@@ -4849,19 +4910,19 @@ Emacs will list the message in the summary.
 Display a summary of all messages with the given SUBJECT.
 Normally checks just the Subject field of headers; but with prefix
 argument WHOLE-MESSAGE is non-nil, looks in the whole message.
 Display a summary of all messages with the given SUBJECT.
 Normally checks just the Subject field of headers; but with prefix
 argument WHOLE-MESSAGE is non-nil, looks in the whole message.
-SUBJECT is a string of regexps separated by commas.
+SUBJECT is a regular expression.
 
 \(fn SUBJECT &optional WHOLE-MESSAGE)" t nil)
 
 (autoload 'rmail-summary-by-senders "rmailsum" "\
 Display a summary of all messages whose \"From\" field matches SENDERS.
 
 \(fn SUBJECT &optional WHOLE-MESSAGE)" t nil)
 
 (autoload 'rmail-summary-by-senders "rmailsum" "\
 Display a summary of all messages whose \"From\" field matches SENDERS.
-SENDERS is a string of regexps separated by commas.
+SENDERS is a regular expression.
 
 \(fn SENDERS)" t nil)
 
 ;;;***
 \f
 
 \(fn SENDERS)" t nil)
 
 ;;;***
 \f
-;;;### (autoloads nil "undigest" "undigest.el" "912d4d3bf762991df5d4d02f42358025")
+;;;### (autoloads nil "undigest" "undigest.el" "c0ddfad4fe34ef9c1e790c2cc72b571d")
 ;;; Generated autoloads from undigest.el
 
 (autoload 'undigestify-rmail-message "undigest" "\
 ;;; Generated autoloads from undigest.el
 
 (autoload 'undigestify-rmail-message "undigest" "\