(message-required-headers): New variable.
[gnus] / lisp / message.el
index daa32a2..079783f 100644 (file)
@@ -192,9 +192,17 @@ Checks include `subject-cmsg', `multiple-headers', `sendsys',
   :group 'message-news
   :type '(repeat sexp))                        ; Fixme: improve this
 
+(defcustom message-required-headers '((optional . References))
+  "*Headers to be generated or promted for when sending a message.
+Also see `message-required-news-headers' and
+1message-required-mail-headers'."
+  :group 'message-news
+  :group 'message-headers
+  :type '(repeat sexp))
+
 (defcustom message-required-news-headers
   '(From Newsgroups Subject Date Message-ID
-        (optional . Organization) Lines
+        (optional . Organization)
         (optional . User-Agent))
   "*Headers to be generated or prompted for when posting an article.
 RFC977 and RFC1036 require From, Date, Newsgroups, Subject,
@@ -1481,14 +1489,21 @@ is used by default."
            (insert (car headers) ?\n)))))
     (setq headers (cdr headers))))
 
+(defmacro message-with-reply-buffer (&rest forms)
+  "Evaluate FORMS in the reply buffer, if it exists."
+  `(when (and message-reply-buffer
+             (buffer-name message-reply-buffer))
+     (save-excursion
+       (set-buffer message-reply-buffer)
+       ,@forms)))
+
+(put 'message-with-reply-buffer 'lisp-indent-function 0)
+(put 'message-with-reply-buffer 'edebug-form-spec '(body))
 
 (defun message-fetch-reply-field (header)
   "Fetch field HEADER from the message we're replying to."
-  (when (and message-reply-buffer
-            (buffer-name message-reply-buffer))
-    (save-excursion
-      (set-buffer message-reply-buffer)
-      (message-fetch-field header))))
+  (message-with-reply-buffer
+    (message-fetch-field header)))
 
 (defun message-set-work-buffer ()
   (if (get-buffer " *message work*")
@@ -1971,6 +1986,7 @@ Point is left at the beginning of the narrowed-to region."
   (define-key message-mode-map "\C-c\C-i" 'message-goto-signature)
 
   (define-key message-mode-map "\C-c\C-t" 'message-insert-to)
+  (define-key message-mode-map "\C-c\C-p" 'message-insert-wide-reply)
   (define-key message-mode-map "\C-c\C-n" 'message-insert-newsgroups)
   (define-key message-mode-map "\C-c\C-l" 'message-to-list-only)
 
@@ -2035,7 +2051,7 @@ Point is left at the beginning of the narrowed-to region."
     ["Insert Region Marked" message-mark-inserted-region 
      ,@(if (featurep 'xemacs) '(t)
         '(:help "Mark region with enclosing tags"))]
-    ["Insert File Marked" message-mark-insert-file 
+    ["Insert File Marked..." message-mark-insert-file 
      ,@(if (featurep 'xemacs) '(t)
         '(:help "Insert file at point marked with enclosing tags"))]
     "----"
@@ -2045,7 +2061,7 @@ Point is left at the beginning of the narrowed-to region."
     ["Postpone Message" message-dont-send
      ,@(if (featurep 'xemacs) '(t)
         '(:help "File this draft message and exit"))]
-    ["Send at Specific Time" gnus-delay-article
+    ["Send at Specific Time..." gnus-delay-article
      ,@(if (featurep 'xemacs) '(t)
         '(:help "Ask, then arrange to send message at that time"))]
     ["Kill Message" message-kill-buffer
@@ -2061,7 +2077,7 @@ Point is left at the beginning of the narrowed-to region."
     ["To" message-goto-to t]
     ["From" message-goto-from t]
     ["Subject" message-goto-subject t]
-    ["Change subject" message-change-subject t]
+    ["Change subject..." message-change-subject t]
     ["Cc" message-goto-cc t]
     ["Bcc" message-goto-bcc t]
     ["Fcc" message-goto-fcc t]
@@ -2073,7 +2089,7 @@ Point is left at the beginning of the narrowed-to region."
     ["Newsgroups" message-goto-newsgroups t]
     ["Followup-To" message-goto-followup-to t]
     ;; ["Followup-To (with note in body)" message-xpost-fup2 t]
-    ["Crosspost / Followup-To" message-xpost-fup2 t]
+    ["Crosspost / Followup-To..." message-xpost-fup2 t]
     ["Distribution" message-goto-distribution t]
     ["X-No-Archive:" message-add-archive-header t ]
     "----"
@@ -2414,13 +2430,29 @@ With the prefix argument FORCE, insert the header anyway."
               (or (equal (downcase co) "never")
                   (equal (downcase co) "nobody")))
       (error "The user has requested not to have copies sent via mail")))
-  (when (and (message-position-on-field "To")
-            (mail-fetch-field "to")
-            (not (string-match "\\` *\\'" (mail-fetch-field "to"))))
-    (insert ", "))
-  (insert (or (message-fetch-reply-field "mail-reply-to")
-             (message-fetch-reply-field "reply-to")
-             (message-fetch-reply-field "from") "")))
+  (message-carefully-insert-headers
+   (list (cons 'To
+              (or (message-fetch-reply-field "mail-reply-to")
+                  (message-fetch-reply-field "reply-to")
+                  (message-fetch-reply-field "from")
+                  "")))))
+
+(defun message-insert-wide-reply ()
+  "Insert To and Cc headers as if you were doing a wide reply."
+  (interactive)
+  (let ((headers (message-with-reply-buffer
+                  (message-get-reply-headers t))))
+    (message-carefully-insert-headers headers)))
+
+(defun message-carefully-insert-headers (headers)
+  (dolist (header headers)
+    (let ((header-name (symbol-name (car header))))
+      (when (and (message-position-on-field header-name)
+                (mail-fetch-field header-name)
+                (not (string-match "\\` *\\'"
+                                   (mail-fetch-field header-name))))
+       (insert ", "))
+      (insert (cdr header)))))
 
 (defun message-widen-reply ()
   "Widen the reply to include maximum recipients."
@@ -4247,6 +4279,17 @@ If NOW, use that time instead."
       (message-goto-body)
       (int-to-string (count-lines (point) (point-max))))))
 
+(defun message-make-references ()
+  "Return the References header for this message."
+  (when message-reply-headers
+    (let ((message-id (mail-header-message-id message-reply-headers))
+         (references (mail-header-references message-reply-headers))
+         new-references)
+      (if (or references message-id)
+         (concat (or references "") (and references " ")
+                 (or message-id ""))
+       nil))))
+
 (defun message-make-in-reply-to ()
   "Return the In-Reply-To header for this message."
   (when message-reply-headers
@@ -4451,6 +4494,7 @@ not the additional To and Cc header contents)."
 (defun message-generate-headers (headers)
   "Prepare article HEADERS.
 Headers already prepared in the buffer are not modified."
+  (setq headers (append headers message-required-headers))
   (save-restriction
     (message-narrow-to-headers)
     (let* ((Date (message-make-date))
@@ -4461,6 +4505,7 @@ Headers already prepared in the buffer are not modified."
           (Subject nil)
           (Newsgroups nil)
           (In-Reply-To (message-make-in-reply-to))
+          (References (message-make-references))
           (To nil)
           (Distribution (message-make-distribution))
           (Lines (message-make-lines))
@@ -5020,7 +5065,7 @@ OTHER-HEADERS is an alist of header/value pairs."
     (message-setup `((Newsgroups . ,(or newsgroups ""))
                     (Subject . ,(or subject ""))))))
 
-(defun message-get-reply-headers (wide &optional to-address)
+(defun message-get-reply-headers (wide &optional to-address address-headers)
   (let (follow-to mct never-mct to cc author mft recipients)
     ;; Find all relevant headers we need.
     (setq to (message-fetch-field "to")
@@ -5048,6 +5093,11 @@ OTHER-HEADERS is an alist of header/value pairs."
       (cond
        ((not wide)
        (setq recipients (concat ", " author)))
+       (address-headers
+       (dolist (header address-headers)
+         (let ((value (message-fetch-field header)))
+           (when value
+             (setq recipients (concat recipients ", " value))))))
        ((and mft
             (string-match "[^ \t,]" mft)
             (or (not (eq message-use-mail-followup-to 'ask))
@@ -5188,11 +5238,7 @@ responses here are directed to other addresses.")))
 
     (message-setup
      `((Subject . ,subject)
-       ,@follow-to
-       ,@(if (or references message-id)
-            `((References . ,(concat (or references "") (and references " ")
-                                     (or message-id ""))))
-          nil))
+       ,@follow-to)
      cur)))
 
 ;;;###autoload
@@ -5251,6 +5297,9 @@ If TO-NEWSGROUPS, use that as the new Newsgroups line."
 
     (message-pop-to-buffer (message-buffer-name "followup" from newsgroups))
 
+    (setq message-reply-headers
+         (vector 0 subject from date message-id references 0 0 ""))
+    
     (message-setup
      `((Subject . ,subject)
        ,@(cond
@@ -5299,9 +5348,6 @@ responses here are directed to other newsgroups."))
          (t
           `((Newsgroups . ,newsgroups))))
        ,@(and distribution (list (cons 'Distribution distribution)))
-       ,@(if (or references message-id)
-            `((References . ,(concat (or references "") (and references " ")
-                                     (or message-id "")))))
        ,@(when (and mct
                    (not (or (equal (downcase mct) "never")
                             (equal (downcase mct) "nobody"))))
@@ -5310,10 +5356,7 @@ responses here are directed to other newsgroups."))
                               (or mrt reply-to from "")
                             mct)))))
 
-     cur)
-
-    (setq message-reply-headers
-         (vector 0 subject from date message-id references 0 0 ""))))
+     cur)))
 
 
 ;;;###autoload