Synch with Oort Gnus.
[elisp/gnus.git-] / lisp / message.el
index 0cce8e0..684ebe4 100644 (file)
@@ -200,7 +200,7 @@ Checks include `subject-cmsg', `multiple-headers', `sendsys',
 `new-text', `quoting-style', `redirected-followup', `signature',
 `approved', `sender', `empty', `empty-headers', `message-id', `from',
 `subject', `shorten-followup-to', `existing-newsgroups',
-`buffer-file-name', `unchanged', `newsgroups'."
+`buffer-file-name', `unchanged', `newsgroups', `reply-to'."
   :group 'message-news
   :type '(repeat sexp))                        ; Fixme: improve this
 
@@ -508,7 +508,7 @@ and respond with new To and Cc headers."
   :group 'message-interface
   :type '(choice function (const nil)))
 
-(defcustom message-use-followup-to t
+(defcustom message-use-followup-to 'ask
   "*Specifies what to do with Followup-To header.
 If nil, always ignore the header.  If it is t, use its value, but
 query before using the \"poster\" value.  If it is the symbol `ask',
@@ -533,17 +533,6 @@ the value.  If it is the symbol `use', always use the value."
                 (const :tag "always" use)
                 (const :tag "ask" ask)))
 
-(defcustom message-use-mail-followup-to 'ask
-  "*Specifies what to do with Mail-Followup-To header.
-If nil, always ignore the header.  If it is the symbol `ask', always
-query the user whether to use the value.  If it is t or the symbol
-`use', always use the value."
-  :group 'message-interface
-  :type '(choice (const :tag "ignore" nil)
-                (const :tag "maybe" t)
-                (const :tag "always" use)
-                (const :tag "ask" ask)))
-
 ;;; XXX: 'ask and 'use are not implemented yet.
 (defcustom message-use-mail-reply-to 'ask
   "*Specifies what to do with Mail-Reply-To/Reply-To header.
@@ -557,6 +546,17 @@ is never used."
                 (const :tag "always" use)
                 (const :tag "ask" ask)))
 
+(defcustom message-use-mail-followup-to t
+  "*Specifies what to do with Mail-Followup-To header.
+If nil, always ignore the header.  If it is the symbol `ask', always
+query the user whether to use the value.  If it is t or the symbol
+`use', always use the value."
+  :group 'message-interface
+  :type '(choice (const :tag "ignore" nil)
+                (const :tag "maybe" t)
+                (const :tag "always" use)
+                (const :tag "ask" ask)))
+
 (defcustom message-sendmail-f-is-evil nil
   "*Non-nil means don't add \"-f username\" to the sendmail command line.
 Doing so would be even more evil than leaving it out."
@@ -675,7 +675,8 @@ The function `message-supersede' runs this hook."
 ;;;###autoload
 (defcustom message-yank-prefix "> "
   "*Prefix inserted on the lines of yanked messages.
-Fix `message-cite-prefix-regexp' if it is set to an abnormal value."
+Fix `message-cite-prefix-regexp' if it is set to an abnormal value.
+See also `message-yank-cited-prefix'."
   :type 'string
   :group 'message-insertion)
 
@@ -699,7 +700,8 @@ an article is yanked by the command `message-yank-original' interactively."
 
 (defcustom message-yank-cited-prefix ">"
   "*Prefix inserted on cited lines of yanked messages.
-Fix `message-cite-prefix-regexp' if it is set to an abnormal value."
+Fix `message-cite-prefix-regexp' if it is set to an abnormal value.
+See also `message-yank-prefix'."
   :type 'string
   :group 'message-insertion)
 
@@ -723,6 +725,17 @@ Note that `message-cite-original' uses `mail-citation-hook' if that is non-nil."
   :group 'message-insertion)
 
 ;;;###autoload
+(defcustom message-suspend-font-lock-when-citing nil
+  "Non-nil means suspend font-lock'ing while citing an original message.
+Some lazy demand-driven fontification tools (or Emacs itself) have a
+bug that they often miss a buffer to be fontified.  It will mostly
+occur when Emacs prompts user for any inputs in the minibuffer.
+Setting this option to non-nil may help you to avoid unpleasant errors
+even if it is an add-hoc expedient."
+  :type 'boolean
+  :group 'message-insertion)
+
+;;;###autoload
 (defcustom message-indent-citation-function 'message-indent-citation
   "*Function for modifying a citation just inserted in the mail buffer.
 This can also be a list of functions.  Each function can find the
@@ -2137,7 +2150,7 @@ a string \"never\" is inserted in default."
     (expand-abbrev))
   (goto-char (point-min))
   (or (search-forward (concat "\n" mail-header-separator "\n") nil t)
-      (search-forward "\n\n" nil t)))
+      (search-forward-regexp "[^:]+:\\([^\n]\\|\n[ \t]\\)+\n\n" nil t)))
 
 (defun message-goto-eoh ()
   "Move point to the end of the headers."
@@ -2212,17 +2225,25 @@ With the prefix argument FORCE, insert the header anyway."
 (defun message-delete-not-region (beg end)
   "Delete everything in the body of the current message outside of the region."
   (interactive "r")
-  (save-excursion
-    (goto-char end)
-    (delete-region (point) (if (not (message-goto-signature))
-                              (point)
-                            (forward-line -2)
-                            (point)))
-    (insert "\n")
-    (goto-char beg)
-    (delete-region beg (progn (message-goto-body)
-                             (forward-line 2)
-                             (point))))
+  (let (citeprefix)
+    (save-excursion
+      (goto-char beg)
+      ;; snarf citation prefix, if appropriate
+      (unless (eq (point) (progn (beginning-of-line) (point)))
+       (when (looking-at message-cite-prefix-regexp)
+         (setq citeprefix (match-string 0))))
+      (goto-char end)
+      (delete-region (point) (if (not (message-goto-signature))
+                                (point)
+                              (forward-line -2)
+                              (point)))
+      (insert "\n")
+      (goto-char beg)
+      (delete-region beg (progn (message-goto-body)
+                               (forward-line 2)
+                               (point)))
+      (when citeprefix
+       (insert citeprefix))))
   (when (message-goto-signature)
     (forward-line -2)))
 
@@ -2596,7 +2617,15 @@ be added to \"References\" field.
              (backward-delete-char 1)))))
 
       (unless arg
-       (funcall message-cite-function))
+       (if (and message-suspend-font-lock-when-citing
+                (boundp 'font-lock-mode)
+                (symbol-value 'font-lock-mode))
+           (progn
+             (sit-for 0)
+             (font-lock-mode 0)
+             (funcall message-cite-function)
+             (font-lock-mode 1))
+         (funcall message-cite-function)))
       (message-exchange-point-and-mark)
       (unless (bolp)
        (insert ?\n))
@@ -3294,7 +3323,7 @@ to find out how to use this."
     ;; qmail-inject doesn't say anything on it's stdout/stderr,
     ;; we have to look at the retval instead
     (0 nil)
-    (1   (error "qmail-inject reported permanent failure"))
+    (100 (error "qmail-inject reported permanent failure"))
     (111 (error "qmail-inject reported transient failure"))
     ;; should never happen
     (t   (error "qmail-inject reported unknown failure"))))
@@ -3681,6 +3710,32 @@ This sub function is for exclusive use of `message-send-news'."
           (message
            "Denied posting -- the From looks strange: \"%s\"." from)
           nil)
+         (t t))))
+     ;; Check the Reply-To header.
+     (message-check 'reply-to
+       (let* ((case-fold-search t)
+             (reply-to (message-fetch-field "reply-to"))
+             ad)
+        (cond
+          ((not reply-to)
+           t)
+          ((string-match "," reply-to)
+           (y-or-n-p
+            (format "Multiple Reply-To addresses: \"%s\". Really post? "
+                    reply-to)))
+         ((or (not (string-match
+                    "@[^\\.]*\\."
+                    (setq ad (nth 1 (mail-extract-address-components
+                                     reply-to))))) ;larsi@ifi
+              (string-match "\\.\\." ad) ;larsi@ifi..uio
+              (string-match "@\\." ad) ;larsi@.ifi.uio
+              (string-match "\\.$" ad) ;larsi@ifi.uio.
+              (not (string-match "^[^@]+@[^@]+$" ad)) ;larsi.ifi.uio
+              (string-match "(.*).*(.*)" reply-to)) ;(lars) (lars)
+           (y-or-n-p
+            (format
+             "The Reply-To looks strange: \"%s\". Really post? " 
+             reply-to)))
          (t t))))))
 
 (defun message-check-news-body-syntax ()
@@ -3840,37 +3895,43 @@ This sub function is for exclusive use of `message-send-news'."
        (output-coding-system 'raw-text)
        list file)
     (save-excursion
-      (set-buffer (get-buffer-create " *message temp*"))
-      (erase-buffer)
-      (insert-buffer-substring message-encoding-buffer)
       (save-restriction
        (message-narrow-to-headers)
-       (while (setq file (message-fetch-field "fcc"))
-         (push file list)
-         (message-remove-header "fcc" nil t)))
-      (goto-char (point-min))
-      (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$"))
-      (replace-match "" t t)
-      ;; Process FCC operations.
-      (while list
-       (setq file (pop list))
-       (if (string-match "^[ \t]*|[ \t]*\\(.*\\)[ \t]*$" file)
-           ;; Pipe the article to the program in question.
-           (call-process-region (point-min) (point-max) shell-file-name
-                                nil nil nil shell-command-switch
-                                (match-string 1 file))
-         ;; Save the article.
-         (setq file (expand-file-name file))
-         (unless (file-exists-p (file-name-directory file))
-           (make-directory (file-name-directory file) t))
-         (if (and message-fcc-handler-function
-                  (not (eq message-fcc-handler-function 'rmail-output)))
-             (funcall message-fcc-handler-function file)
-           (if (and (file-readable-p file) (mail-file-babyl-p file))
-               (rmail-output file 1 nil t)
-             (let ((mail-use-rfc822 t))
-               (rmail-output file 1 t t))))))
-      (kill-buffer (current-buffer)))))
+       (setq file (message-fetch-field "fcc" t)))
+      (when file
+       (set-buffer (get-buffer-create " *message temp*"))
+       (erase-buffer)
+       (insert-buffer-substring message-encoding-buffer)
+       (save-restriction
+         (message-narrow-to-headers)
+         (while (setq file (message-fetch-field "fcc"))
+           (push file list)
+           (message-remove-header "fcc" nil t)))
+       (goto-char (point-min))
+       (when (re-search-forward
+              (concat "^" (regexp-quote mail-header-separator) "$")
+              nil t)
+         (replace-match "" t t))
+       ;; Process FCC operations.
+       (while list
+         (setq file (pop list))
+         (if (string-match "^[ \t]*|[ \t]*\\(.*\\)[ \t]*$" file)
+             ;; Pipe the article to the program in question.
+             (call-process-region (point-min) (point-max) shell-file-name
+                                  nil nil nil shell-command-switch
+                                  (match-string 1 file))
+           ;; Save the article.
+           (setq file (expand-file-name file))
+           (unless (file-exists-p (file-name-directory file))
+             (make-directory (file-name-directory file) t))
+           (if (and message-fcc-handler-function
+                    (not (eq message-fcc-handler-function 'rmail-output)))
+               (funcall message-fcc-handler-function file)
+             (if (and (file-readable-p file) (mail-file-babyl-p file))
+                 (rmail-output file 1 nil t)
+               (let ((mail-use-rfc822 t))
+                 (rmail-output file 1 t t))))))
+       (kill-buffer (current-buffer))))))
 
 (defun message-output (filename)
   "Append this article to Unix/babyl mail file FILENAME."
@@ -3921,6 +3982,9 @@ If NOW, use that time instead."
       (setq sign "-")
       (setq zone (- zone)))
     (concat
+     ;; The day name of the %a spec is locale-specific.  Pfff.
+     (format "%s, " (capitalize (car (rassoc (nth 6 (decode-time now))
+                                            parse-time-weekdays))))
      (format-time-string "%d" now)
      ;; The month name of the %b spec is locale-specific.  Pfff.
      (format " %s "
@@ -4586,8 +4650,10 @@ than 988 characters long, and if they are not, trim them until they are."
                     (string-equal name "mail")
                     (string-equal name "news")))
            (setq name (concat "*sent " name "*"))
+         (message-narrow-to-headers)
          (setq to (message-fetch-field "to"))
          (setq group (message-fetch-field "newsgroups"))
+         (widen)
          (setq name
                (cond
                 (to (concat "*sent mail to "
@@ -4794,8 +4860,7 @@ OTHER-HEADERS is an alist of header/value pairs."
          mrt (when message-use-mail-reply-to
                (message-fetch-field "mail-reply-to"))
          mft (when (and (not (or to-address mrt reply-to))
-                        (or message-use-followup-to
-                            message-use-mail-followup-to))
+                        message-use-mail-followup-to)
                (message-fetch-field "mail-followup-to")))
 
     ;; Handle special values of Mail-Copies-To.
@@ -4836,8 +4901,7 @@ sends a copy of your response to " (if (string-match "," mct)
 
     ;; Handle Mail-Followup-To.
     (when (and mft
-              (eq (or message-use-followup-to
-                      message-use-mail-followup-to) 'ask)
+              (eq message-use-mail-followup-to 'ask)
               (not (message-y-or-n-p
                     (concat "Obey Mail-Followup-To: " mft "? ") t "\
 You should normally obey the Mail-Followup-To: header.
@@ -4867,9 +4931,8 @@ that further discussion should take place only in "
        (save-excursion
          (message-set-work-buffer)
          (if (and mft
-                  message-use-followup-to
                   wide
-                  (or (not (eq message-use-followup-to 'ask))
+                  (or (not (eq message-use-mail-followup-to 'ask))
                       (message-y-or-n-p "Obey Mail-Followup-To? " t "\
 You should normally obey the Mail-Followup-To: header.  In this
 article, it has the value of
@@ -4880,8 +4943,12 @@ which directs your response to " (if (string-match "," mft)
                                     "the specified addresses"
                                   "that address only") ".
 
-If a message is posted to several mailing lists, Mail-Followup-To is
-often used to direct the following discussion to one list only,
+Most commonly, Mail-Followup-To is used by a mailing list poster to
+express that responses should be sent to just the list, and not the
+poster as well.
+
+If a message is posted to several mailing lists, Mail-Followup-To may
+also be used to direct the following discussion to one list only,
 because discussions that are spread over several lists tend to be
 fragmented and very difficult to follow.
 
@@ -5029,8 +5096,7 @@ If TO-NEWSGROUPS, use that as the new Newsgroups line."
            distribution (message-fetch-field "distribution")
            mct (when message-use-mail-copies-to
                  (message-fetch-field "mail-copies-to"))
-           mft (when (or message-use-followup-to
-                         message-use-mail-followup-to)
+           mft (when message-use-mail-followup-to
                  (message-fetch-field "mail-followup-to")))
       (when (and (setq gnus-warning (message-fetch-field "gnus-warning"))
                 (string-match "<[^>]+>" gnus-warning))
@@ -5117,8 +5183,7 @@ responses here are directed to other newsgroups."))
            (setq follow-to (list (cons 'Newsgroups newsgroups)))))))
        ;; Handle Mail-Followup-To, followup via e-mail.
        ((and mft
-            (or (not (eq (or message-use-followup-to
-                             message-use-mail-followup-to) 'ask))
+            (or (not (eq message-use-mail-followup-to 'ask))
                 (message-y-or-n-p
                  (concat "Obey Mail-Followup-To: " mft "? ") t "\
 You should normally obey the Mail-Followup-To: header.
@@ -5898,11 +5963,16 @@ regexp varstr."
                         (mail-strip-quoted-names
                          (message-fetch-field "from")))
     (message-options-set 'message-recipients
-                        (mail-strip-quoted-names
-                         (concat
-                          (or (message-fetch-field "to") "") ", "
-                          (or (message-fetch-field "cc") "") ", "
-                          (or (message-fetch-field "bcc") ""))))))
+                        (mail-strip-quoted-names
+                         (let ((to (message-fetch-field "to"))
+                               (cc (message-fetch-field "cc"))
+                               (bcc (message-fetch-field "bcc")))
+                           (concat
+                            (or to "")
+                            (if (and to cc) ", ")
+                            (or cc "")
+                            (if (and (or to cc) bcc) ", ")
+                            (or bcc "")))))))
 
 (when (featurep 'xemacs)
   (require 'messagexmas)