sendmail.el trivia.
[bpt/emacs.git] / lisp / mail / rmailedit.el
index 7d75779..868ca15 100644 (file)
@@ -1,10 +1,10 @@
 ;;; rmailedit.el --- "RMAIL edit mode"  Edit the current message
 
-;; Copyright (C) 1985, 1994, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-;;   2008, 2009  Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1994, 2001-2011  Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: mail
+;; Package: rmail
 
 ;; This file is part of GNU Emacs.
 
@@ -64,6 +64,13 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
     (if (boundp 'mode-line-modified)
        (setq mode-line-modified (default-value 'mode-line-modified))
       (setq mode-line-format (default-value 'mode-line-format)))
+    ;; Don't turn off auto-saving based on the size of the buffer
+    ;; because that code does not understand buffer-swapping.
+    (make-local-variable 'auto-save-include-big-deletions)
+    (setq auto-save-include-big-deletions t)
+    ;; If someone uses C-x C-s, don't clobber the rmail file (bug#2625).
+    (add-hook 'write-region-annotate-functions
+             'rmail-write-region-annotate nil t)
     (run-mode-hooks 'rmail-edit-mode-hook)))
 
 ;; Rmail Edit mode is suitable only for specially formatted data.
@@ -85,6 +92,7 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
   (interactive)
   (if (zerop rmail-total-messages)
       (error "No messages in this buffer"))
+  (rmail-modify-format)
   (make-local-variable 'rmail-old-pruned)
   (setq rmail-old-pruned (rmail-msg-is-pruned))
   (rmail-edit-mode)
@@ -97,9 +105,10 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
   (setq rmail-old-headers (rmail-edit-headers-alist t))
   (setq buffer-read-only nil)
   (setq buffer-undo-list nil)
-  ;; FIXME whether the buffer is initially marked as modified or not
+  ;; Whether the buffer is initially marked as modified or not
   ;; depends on whether or not the underlying rmail buffer was so marked.
-  ;; Seems poor.
+  ;; Given the way this works, it has to.
+  ;; If you kill the edit buffer, you've killed your rmail buffer.
   (force-mode-line-update)
   (if (and (eq (key-binding "\C-c\C-c") 'rmail-cease-edit)
           (eq (key-binding "\C-c\C-]") 'rmail-abort-edit))
@@ -117,22 +126,23 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
       (with-current-buffer rmail-summary-buffer
        (rmail-summary-enable)))
   (widen)
+  (goto-char (point-min))
+  ;; This is far from ideal.  The edit may have inadvertently
+  ;; removed the blank line at the end of the headers, but there
+  ;; are almost certainly other blank lines.
+  (or (search-forward "\n\n" nil t)
+      (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.
-  (save-excursion
-    (goto-char (point-min))
-    (or rmail-old-pruned (forward-line 1))
-    (while (re-search-forward "^>*From " 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.
-  (save-excursion
-    (goto-char (point-max))
-    (if (/= (preceding-char) ?\n)
-       (insert "\n"))
-    (unless (looking-back "\n\n")
-      (insert "\n")))
+  (goto-char (point-min))
+  (or rmail-old-pruned (forward-line 1))
+  (while (re-search-forward "^>*From " 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)
        ;; People who know what they are doing might have modified the
@@ -162,47 +172,51 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
                 (string= old (buffer-substring (point-min) (point-max))))
       (setq old nil)
       (goto-char (point-min))
-      ;; If they changed the message's encoding, rewrite the charset=
-      ;; header for them, so that subsequent rmail-show-message
-      ;; decodes it correctly.
-      (let ((buffer-read-only nil)
-           (new-coding (coding-system-base edited-coding))
-           old-coding mime-charset mime-beg mime-end)
-       (when (re-search-forward rmail-mime-charset-pattern
-                                (1- (save-excursion (search-forward "\n\n")))
-                                'move)
-           (setq mime-beg (match-beginning 1)
-                 mime-end (match-end 1)
-                 old-coding (coding-system-from-name (match-string 1))))
-       (setq mime-charset
-             (symbol-name
-              (or (coding-system-get new-coding :mime-charset)
-                  (if (coding-system-equal new-coding 'undecided)
-                      'us-ascii
-                    new-coding))))
-       (cond
-        ((null old-coding)
-         ;; If there was no charset= spec, insert one.
-         (insert "Content-type: text/plain; charset=" mime-charset "\n"))
-        ((not (coding-system-equal (coding-system-base old-coding)
-                                   new-coding))
-         (delete-region mime-beg mime-end)
-         (insert mime-charset))))
-      (goto-char (point-min))
       (search-forward "\n\n")
-      (setq headers-end (point))
+      (setq headers-end (point-marker))
+      (goto-char (point-min))
+      (save-restriction
+       (narrow-to-region (point) headers-end)
+       ;; If they changed the message's encoding, rewrite the charset=
+       ;; header for them, so that subsequent rmail-show-message
+       ;; decodes it correctly.
+       (let* ((buffer-read-only nil)
+              (new-coding (coding-system-base edited-coding))
+              (mime-charset (symbol-name
+                             (or (coding-system-get new-coding :mime-charset)
+                                 (if (coding-system-equal new-coding
+                                                          'undecided)
+                                     'us-ascii
+                                   new-coding))))
+              old-coding mime-beg mime-end content-type)
+         (if (re-search-forward rmail-mime-charset-pattern nil 'move)
+             (setq mime-beg (match-beginning 1)
+                   mime-end (match-end 1)
+                   old-coding (coding-system-from-name (match-string 1)))
+           (setq content-type (mail-fetch-field "Content-Type")))
+         (cond
+          ;; No match for rmail-mime-charset-pattern, but there was some
+          ;; other Content-Type.  We should not insert another.  (Bug#4624)
+          (content-type)
+          ((null old-coding)
+           ;; If there was no charset= spec, insert one.
+           (backward-char 1)
+           (insert "Content-type: text/plain; charset=" mime-charset "\n"))
+          ((not (coding-system-equal (coding-system-base old-coding)
+                                     new-coding))
+           (goto-char mime-end)
+           (delete-region mime-beg mime-end)
+           (insert mime-charset)))))
       (setq new-headers (rmail-edit-headers-alist t))
       (rmail-swap-buffers-maybe)
       (narrow-to-region (rmail-msgbeg rmail-current-message)
                        (rmail-msgend rmail-current-message))
+      (goto-char (point-min))
+      (setq limit (search-forward "\n\n"))
       (save-restriction
-       (setq limit
-             (save-excursion
-               (goto-char (point-min))
-               (search-forward "\n\n" nil t)))
        ;; All 3 of the functions we call below assume the buffer was
        ;; narrowed to just the headers of the message.
-       (narrow-to-region (rmail-msgbeg rmail-current-message) limit)
+       (narrow-to-region (point-min) limit)
        (setq character-coding
              (mail-fetch-field "content-transfer-encoding")
              is-text-message (rmail-is-text-p)
@@ -241,9 +255,8 @@ This function runs the hooks `text-mode-hook' and `rmail-edit-mode-hook'.
     ;;??? BROKEN perhaps.
 ;;;    (if (boundp 'rmail-summary-vector)
 ;;;    (aset rmail-summary-vector (1- rmail-current-message) nil))
-    (save-excursion
-      (rmail-show-message)
-      (rmail-toggle-header (if pruned 1 0))))
+    (rmail-show-message)
+    (rmail-toggle-header (if pruned 1 0)))
   (run-hooks 'rmail-mode-hook))
 
 (defun rmail-abort-edit ()
@@ -381,5 +394,8 @@ HEADER-DIFF should be a return value from `rmail-edit-diff-headers'."
 
 (provide 'rmailedit)
 
-;; arch-tag: 9524f335-12cc-4e95-9e9b-3208dc30550b
+;; Local Variables:
+;; generated-autoload-file: "rmail.el"
+;; End:
+
 ;;; rmailedit.el ends here