]> code.delx.au - gnu-emacs/blobdiff - lisp/mail/rmailedit.el
Merge from origin/emacs-25
[gnu-emacs] / lisp / mail / rmailedit.el
index 868ca15923f1c858f8d5280ee6737674624f1343..46e5e17a2e8f72b35da47958b02694406a217ad2 100644 (file)
@@ -1,8 +1,8 @@
 ;;; rmailedit.el --- "RMAIL edit mode"  Edit the current message
 
-;; Copyright (C) 1985, 1994, 2001-201 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1994, 2001-2016 Free Software Foundation, Inc.
 
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: mail
 ;; Package: rmail
 
@@ -44,6 +44,8 @@
 
 (declare-function rmail-summary-disable "rmailsum" ())
 
+;; We can't straightforwardly make this derive from text-mode, because
+;; we need to bind (rmail-buffer-swapped) around the text-mode call.  :(
 (defun rmail-edit-mode ()
   "Major mode for editing the contents of an Rmail message.
 The editing commands are the same as in Text mode, together with
@@ -78,6 +80,7 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
 \f
 
 (defvar rmail-old-text)
+(defvar rmail-old-mime-state)
 (defvar rmail-old-pruned nil
   "Non-nil means the message being edited originally had pruned headers.")
 (put 'rmail-old-pruned 'permanent-local t)
@@ -86,6 +89,10 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
   "Holds the headers of this message before editing started.")
 (put 'rmail-old-headers 'permanent-local t)
 
+;; Everything we use from here is a defsubst.
+(eval-when-compile
+  (require 'rmailmm))
+
 ;;;###autoload
 (defun rmail-edit-current-message ()
   "Edit the contents of this message."
@@ -96,6 +103,30 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
   (make-local-variable 'rmail-old-pruned)
   (setq rmail-old-pruned (rmail-msg-is-pruned))
   (rmail-edit-mode)
+  (set (make-local-variable 'rmail-old-mime-state)
+       (and rmail-enable-mime
+           ;; If you use something else, you are on your own.
+           (eq rmail-mime-feature 'rmailmm)
+           (rmail-mime-message-p)
+           (let ((entity (get-text-property (point-min) 'rmail-mime-entity)))
+             ;; rmailmm has got its hands on the message.
+             ;; Even if the message is in `raw' state, boundaries etc
+             ;; are still missing.  All we can do is insert the real
+             ;; raw message.  (Bug#9840)
+             ;; FIXME?  Since the 2012-09-17 changes to rmail-mime,
+             ;; can we just use that function now?
+             (when (and entity
+                        (not (equal "text/plain"
+                                    (car (rmail-mime-entity-type entity)))))
+               (let ((inhibit-read-only t))
+                 (erase-buffer)
+                 (insert-buffer-substring
+                  rmail-view-buffer
+                  (aref (rmail-mime-entity-header entity) 0)
+                  (aref (rmail-mime-entity-body entity) 1)))
+               (goto-char (point-min))
+               ;; t = decoded; raw = raw.
+               (aref (aref (rmail-mime-entity-display entity) 0) 0)))))
   (make-local-variable 'rmail-old-text)
   (setq rmail-old-text
        (save-restriction
@@ -134,17 +165,36 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
       (error "There must be a blank line at the end of the headers"))
   ;; Disguise any "From " lines so they don't start a new message.
   (goto-char (point-min))
-  (or rmail-old-pruned (forward-line 1))
-  (while (re-search-forward "^>*From " nil t)
-    (beginning-of-line)
-    (insert ">")
-    (forward-line))
+  ;; This tries to skip the mbox From.  FIXME less fragile to go to EOH?
+  (if (or rmail-old-mime-state
+         (not rmail-old-pruned))
+      (forward-line 1))
+  ;; When editing a non-MIME message, rmail-show-message-1 has unescaped
+  ;; ^>*From lines according to rmail-mbox-format.  We are editing
+  ;; the message as it was displayed, and need to put the escapes when done.
+  ;; When editing a MIME message, we are editing the "raw" message.
+  ;; ^>*From lines have not been escaped, but we still need to ensure
+  ;; a "^From " line is escaped so as not to break later parsing (?).
+  ;; With ^>+From lines, we have no way of knowing whether the person
+  ;; doing the editing escaped them or not, so it seems best to leave
+  ;; them alone.  (This all assumes you are using rmailmm rather than
+  ;; something else that behaves differently.)
+  (let ((fromline (if (or (eq 'mboxo rmail-mbox-format)
+                         rmail-mime-decoded)
+                     "^From "
+                   "^>*From "))
+       case-fold-search)
+    (while (re-search-forward fromline nil t)
+      (beginning-of-line)
+      (insert ">")
+      (forward-line)))
   ;; Make sure buffer ends with a blank line so as not to run this
   ;; message together with the following one.
   (goto-char (point-max))
   (rmail-ensure-blank-line)
   (let ((old rmail-old-text)
        (pruned rmail-old-pruned)
+       (mime-state rmail-old-mime-state)
        ;; People who know what they are doing might have modified the
        ;; buffer's encoding if editing the message included inserting
        ;; characters that were unencodable by the original message's
@@ -168,6 +218,7 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
       (setq buffer-undo-list t)
       (rmail-variables))
     ;; If text has really changed, mark message as edited.
+    ;; FIXME we should do the comparison before escaping From lines.
     (unless (and (= (length old) (- (point-max) (point-min)))
                 (string= old (buffer-substring (point-min) (point-max))))
       (setq old nil)
@@ -256,7 +307,9 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
 ;;;    (if (boundp 'rmail-summary-vector)
 ;;;    (aset rmail-summary-vector (1- rmail-current-message) nil))
     (rmail-show-message)
-    (rmail-toggle-header (if pruned 1 0)))
+    (rmail-toggle-header (if pruned 1 0))
+    ;; Restore mime display state.
+    (and mime-state (rmail-mime nil mime-state)))
   (run-hooks 'rmail-mode-hook))
 
 (defun rmail-abort-edit ()
@@ -395,7 +448,7 @@ HEADER-DIFF should be a return value from `rmail-edit-diff-headers'."
 (provide 'rmailedit)
 
 ;; Local Variables:
-;; generated-autoload-file: "rmail.el"
+;; generated-autoload-file: "rmail-loaddefs.el"
 ;; End:
 
 ;;; rmailedit.el ends here