Sync up with Pterodactyl Gnus v0.83.
[elisp/gnus.git-] / lisp / gnus-msg.el
index 3a8951b..beb10d7 100644 (file)
@@ -1,9 +1,12 @@
 ;;; gnus-msg.el --- mail and post interface for Semi-gnus
 ;;; gnus-msg.el --- mail and post interface for Semi-gnus
-;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1995,96,97,98,99 Free Software Foundation, Inc.
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
-;;        Lars Magne Ingebrigtsen <larsi@gnus.org>
-;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
+;;     Lars Magne Ingebrigtsen <larsi@gnus.org>
+;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
+;;     Shuhei KOBAYASHI <shuhei-k@jaist.ac.jp>
+;;     Katsumi Yamaoka  <yamaoka@jpl.org>
+;;     Kiyokazu SUTO    <suto@merry.xmath.ous.ac.jp>
 ;; Keywords: mail, news, MIME
 
 ;; This file is part of GNU Emacs.
 ;; Keywords: mail, news, MIME
 
 ;; This file is part of GNU Emacs.
@@ -92,7 +95,7 @@ Thank you.
 The first %s will be replaced by the Newsgroups header;
 the second with the current group name.")
 
 The first %s will be replaced by the Newsgroups header;
 the second with the current group name.")
 
-(defvar gnus-message-setup-hook nil
+(defvar gnus-message-setup-hook '(gnus-maybe-setup-default-charset)
   "Hook run after setting up a message buffer.")
 
 (defvar gnus-bug-create-help-buffer t
   "Hook run after setting up a message buffer.")
 
 (defvar gnus-bug-create-help-buffer t
@@ -109,15 +112,34 @@ the second with the current group name.")
     (name . user-full-name))
   "*Mapping from style parameters to variables.")
 
     (name . user-full-name))
   "*Mapping from style parameters to variables.")
 
+(defcustom gnus-group-posting-charset-alist
+  '(("^no\\." iso-8859-1)
+    (message-this-is-mail nil)
+    (".*" iso-8859-1)
+    (message-this-is-news iso-8859-1))
+  "Alist of regexps (to match group names) and default charsets to be unencoded when posting."
+  :type '(repeat (list (regexp :tag "Group")
+                      (symbol :tag "Charset")))
+  :group 'gnus-charset)
+
 ;;; Internal variables.
 
 ;;; Internal variables.
 
+(defvar gnus-inhibit-posting-styles nil
+  "Inhibit the use of posting styles.")
+
 (defvar gnus-message-buffer "*Mail Gnus*")
 (defvar gnus-article-copy nil)
 (defvar gnus-last-posting-server nil)
 (defvar gnus-message-group-art nil)
 
 (defconst gnus-bug-message
 (defvar gnus-message-buffer "*Mail Gnus*")
 (defvar gnus-article-copy nil)
 (defvar gnus-last-posting-server nil)
 (defvar gnus-message-group-art nil)
 
 (defconst gnus-bug-message
-  "Sending a bug report to the Gnus Towers.
+  (format "Sending a bug report to the Gnus Towers.
+========================================
+
+This gnus is the %s%s.
+If you think the bug is a Semi-gnus bug, send a bug report to Semi-gnus
+Developers. (the addresses below are mailing list addresses)
+
 ========================================
 
 The buffer below is a mail buffer.  When you press `C-c C-c', it will
 ========================================
 
 The buffer below is a mail buffer.  When you press `C-c C-c', it will
@@ -134,7 +156,11 @@ and include the backtrace in your bug report.
 Please describe the bug in annoying, painstaking detail.
 
 Thank you for your help in stamping out bugs.
 Please describe the bug in annoying, painstaking detail.
 
 Thank you for your help in stamping out bugs.
-")
+"
+         gnus-product-name
+         (if (string= gnus-product-name "Semi-gnus")
+             ""
+           ", a modified version of Semi-gnus")))
 
 (eval-and-compile
   (autoload 'gnus-uu-post-news "gnus-uu" nil t)
 
 (eval-and-compile
   (autoload 'gnus-uu-post-news "gnus-uu" nil t)
@@ -165,8 +191,8 @@ Thank you for your help in stamping out bugs.
   "\M-c" gnus-summary-mail-crosspost-complaint
   "om" gnus-summary-mail-forward
   "op" gnus-summary-post-forward
   "\M-c" gnus-summary-mail-crosspost-complaint
   "om" gnus-summary-mail-forward
   "op" gnus-summary-post-forward
-  "Om" gnus-uu-digest-mail-forward
-  "Op" gnus-uu-digest-post-forward)
+  "Om" gnus-summary-mail-digest
+  "Op" gnus-summary-post-digest)
 
 (gnus-define-keys (gnus-send-bounce-map "D" gnus-summary-send-map)
   "b" gnus-summary-resend-bounced-mail
 
 (gnus-define-keys (gnus-send-bounce-map "D" gnus-summary-send-map)
   "b" gnus-summary-resend-bounced-mail
@@ -186,7 +212,12 @@ Thank you for your help in stamping out bugs.
           (,article (and gnus-article-reply (gnus-summary-article-number)))
           (,group gnus-newsgroup-name)
           (message-header-setup-hook
           (,article (and gnus-article-reply (gnus-summary-article-number)))
           (,group gnus-newsgroup-name)
           (message-header-setup-hook
-           (copy-sequence message-header-setup-hook)))
+           (copy-sequence message-header-setup-hook))
+          (message-mode-hook (copy-sequence message-mode-hook))
+          (message-startup-parameter-alist
+           '((reply-buffer . gnus-copy-article-buffer)
+             (original-buffer . gnus-original-article-buffer)
+             (user-agent . Gnus))))
        (add-hook 'message-header-setup-hook 'gnus-inews-insert-gcc)
        (add-hook 'message-header-setup-hook 'gnus-inews-insert-archive-gcc)
        (add-hook 'message-mode-hook 'gnus-configure-posting-styles)
        (add-hook 'message-header-setup-hook 'gnus-inews-insert-gcc)
        (add-hook 'message-header-setup-hook 'gnus-inews-insert-archive-gcc)
        (add-hook 'message-mode-hook 'gnus-configure-posting-styles)
@@ -197,12 +228,28 @@ Thank you for your help in stamping out bugs.
         (setq gnus-message-buffer (current-buffer))
         (set (make-local-variable 'gnus-message-group-art)
              (cons ,group ,article))
         (setq gnus-message-buffer (current-buffer))
         (set (make-local-variable 'gnus-message-group-art)
              (cons ,group ,article))
-        (make-local-variable 'gnus-newsgroup-name)
+        (set (make-local-variable 'gnus-newsgroup-name) ,group)
+        (set (make-local-variable 'message-posting-charset)
+             (gnus-setup-posting-charset ,group))
         (gnus-run-hooks 'gnus-message-setup-hook))
        (gnus-add-buffer)
        (gnus-configure-windows ,config t)
        (set-buffer-modified-p nil))))
 
         (gnus-run-hooks 'gnus-message-setup-hook))
        (gnus-add-buffer)
        (gnus-configure-windows ,config t)
        (set-buffer-modified-p nil))))
 
+(defun gnus-setup-posting-charset (group)
+  (let ((alist gnus-group-posting-charset-alist)
+       elem)
+    (when group
+      (catch 'found
+       (while (setq elem (pop alist))
+         (when (or (and (stringp (car elem))
+                        (string-match (car elem) group))
+                   (and (gnus-functionp (car elem))
+                        (funcall (car elem) group))
+                   (and (symbolp (car elem))
+                        (symbol-value (car elem))))
+           (throw 'found (cadr elem))))))))
+
 (defun gnus-inews-add-send-actions (winconf buffer article)
   (make-local-hook 'message-sent-hook)
   (add-hook 'message-sent-hook 'gnus-inews-do-gcc nil t)
 (defun gnus-inews-add-send-actions (winconf buffer article)
   (make-local-hook 'message-sent-hook)
   (add-hook 'message-sent-hook 'gnus-inews-do-gcc nil t)
@@ -210,8 +257,9 @@ Thank you for your help in stamping out bugs.
        `(lambda (arg)
           (gnus-post-method arg ,gnus-newsgroup-name)))
   (setq message-user-agent (gnus-extended-version))
        `(lambda (arg)
           (gnus-post-method arg ,gnus-newsgroup-name)))
   (setq message-user-agent (gnus-extended-version))
-  (message-add-action
-   `(set-window-configuration ,winconf) 'exit 'postpone 'kill)
+  (when (not message-use-multi-frames)
+    (message-add-action
+     `(set-window-configuration ,winconf) 'exit 'postpone 'kill))
   (message-add-action
    `(when (gnus-buffer-exists-p ,buffer)
       (save-excursion
   (message-add-action
    `(when (gnus-buffer-exists-p ,buffer)
       (save-excursion
@@ -225,11 +273,29 @@ Thank you for your help in stamping out bugs.
 
 ;;; Post news commands of Gnus group mode and summary mode
 
 
 ;;; Post news commands of Gnus group mode and summary mode
 
-(defun gnus-group-mail ()
-  "Start composing a mail."
-  (interactive)
-  (gnus-setup-message 'message
-    (message-mail)))
+(defun gnus-group-mail (&optional arg)
+  "Start composing a mail.
+If ARG, use the group under the point to find a posting style.
+If ARG is 1, prompt for a group name to find the posting style."
+  (interactive "P")
+  ;; We can't `let' gnus-newsgroup-name here, since that leads
+  ;; to local variables leaking.
+  (let ((group gnus-newsgroup-name)
+       (buffer (current-buffer)))
+    (unwind-protect
+       (progn
+         (setq gnus-newsgroup-name
+               (if arg
+                   (if (= 1 (prefix-numeric-value arg))
+                       (completing-read "Use posting style of group: "
+                                        gnus-active-hashtb nil
+                                        (gnus-read-active-file-p))
+                     (gnus-group-group-name))
+                 ""))
+         (gnus-setup-message 'message (message-mail)))
+      (save-excursion
+       (set-buffer buffer)
+       (setq gnus-newsgroup-name group)))))
 
 (defun gnus-group-post-news (&optional arg)
   "Start composing a news message.
 
 (defun gnus-group-post-news (&optional arg)
   "Start composing a news message.
@@ -286,13 +352,26 @@ If prefix argument YANK is non-nil, original article is yanked automatically."
   (gnus-summary-followup (gnus-summary-work-articles arg) t))
 
 (defun gnus-inews-yank-articles (articles)
   (gnus-summary-followup (gnus-summary-work-articles arg) t))
 
 (defun gnus-inews-yank-articles (articles)
-  (let (beg article)
+  (let* ((more-than-one (cdr articles))
+        (frame (when (and message-use-multi-frames more-than-one)
+                 (window-frame (get-buffer-window (current-buffer)))))
+        refs beg article)
     (message-goto-body)
     (while (setq article (pop articles))
       (save-window-excursion
        (set-buffer gnus-summary-buffer)
        (gnus-summary-select-article nil nil nil article)
        (gnus-summary-remove-process-mark article))
     (message-goto-body)
     (while (setq article (pop articles))
       (save-window-excursion
        (set-buffer gnus-summary-buffer)
        (gnus-summary-select-article nil nil nil article)
        (gnus-summary-remove-process-mark article))
+      (when frame
+       (select-frame frame))
+
+      ;; Gathering references.
+      (when more-than-one
+       (setq refs (message-list-references
+                   refs
+                   (mail-header-references gnus-current-headers)
+                   (mail-header-message-id gnus-current-headers))))
+
       (gnus-copy-article-buffer)
       (let ((message-reply-buffer gnus-article-copy)
            (message-reply-headers gnus-current-headers))
       (gnus-copy-article-buffer)
       (let ((message-reply-buffer gnus-article-copy)
            (message-reply-headers gnus-current-headers))
@@ -301,6 +380,25 @@ If prefix argument YANK is non-nil, original article is yanked automatically."
       (when articles
        (insert "\n")))
     (push-mark)
       (when articles
        (insert "\n")))
     (push-mark)
+
+    ;; Replace with the gathered references.
+    (when refs
+      (push-mark beg)
+      (save-restriction
+       (message-narrow-to-headers)
+       (let ((case-fold-search t))
+         (if (re-search-forward "^References:\\([\t ]+.+\n\\)+" nil t)
+             (replace-match "")
+           (goto-char (point-max))))
+       (mail-header-format
+        (list (or (assq 'References message-header-format-alist)
+                  '(References . message-shorten-references)))
+        (list (cons 'References
+                    (mapconcat 'identity (nreverse refs) " "))))
+       (backward-delete-char 1))
+      (setq beg (mark t))
+      (pop-mark))
+
     (goto-char beg)))
 
 (defun gnus-summary-cancel-article (&optional n symp)
     (goto-char beg)))
 
 (defun gnus-summary-cancel-article (&optional n symp)
@@ -330,7 +428,8 @@ post using the current select method."
 This is done simply by taking the old article and adding a Supersedes
 header line with the old Message-ID."
   (interactive)
 This is done simply by taking the old article and adding a Supersedes
 header line with the old Message-ID."
   (interactive)
-  (let ((article (gnus-summary-article-number)))
+  (let ((article (gnus-summary-article-number))
+       (gnus-message-setup-hook '(gnus-maybe-setup-default-charset)))
     (gnus-setup-message 'reply-yank
       (gnus-summary-select-article t)
       (set-buffer gnus-original-article-buffer)
     (gnus-setup-message 'reply-yank
       (gnus-summary-select-article t)
       (set-buffer gnus-original-article-buffer)
@@ -352,9 +451,8 @@ header line with the old Message-ID."
   ;; if ARTICLE-BUFFER is nil, gnus-article-buffer is used
   ;; this buffer should be passed to all mail/news reply/post routines.
   (setq gnus-article-copy (gnus-get-buffer-create " *gnus article copy*"))
   ;; if ARTICLE-BUFFER is nil, gnus-article-buffer is used
   ;; this buffer should be passed to all mail/news reply/post routines.
   (setq gnus-article-copy (gnus-get-buffer-create " *gnus article copy*"))
-  (buffer-disable-undo gnus-article-copy)
   (let ((article-buffer (or article-buffer gnus-article-buffer))
   (let ((article-buffer (or article-buffer gnus-article-buffer))
-       end beg contents)
+       end beg)
     (if (not (and (get-buffer article-buffer)
                  (gnus-buffer-exists-p article-buffer)))
        (error "Can't find any article buffer")
     (if (not (and (get-buffer article-buffer)
                  (gnus-buffer-exists-p article-buffer)))
        (error "Can't find any article buffer")
@@ -383,10 +481,10 @@ header line with the old Message-ID."
          ;; Delete the headers from the displayed articles.
          (set-buffer gnus-article-copy)
          (delete-region (goto-char (point-min))
          ;; Delete the headers from the displayed articles.
          (set-buffer gnus-article-copy)
          (delete-region (goto-char (point-min))
-                        (or (search-forward "\n\n" nil t) (point)))
+                        (or (search-forward "\n\n" nil t) (point-max)))
          ;; Insert the original article headers.
          (insert-buffer-substring gnus-original-article-buffer beg end)
          ;; Insert the original article headers.
          (insert-buffer-substring gnus-original-article-buffer beg end)
-         (gnus-article-decode-rfc1522)))
+         (article-decode-encoded-words)))
       gnus-article-copy)))
 
 (defun gnus-post-news (post &optional group header article-buffer yank subject
       gnus-article-copy)))
 
 (defun gnus-post-news (post &optional group header article-buffer yank subject
@@ -482,14 +580,16 @@ If SILENT, don't prompt the user."
                   (list gnus-post-method)))
               gnus-secondary-select-methods
               (mapcar 'cdr gnus-server-alist)
                   (list gnus-post-method)))
               gnus-secondary-select-methods
               (mapcar 'cdr gnus-server-alist)
+              (mapcar 'car gnus-opened-servers)
               (list gnus-select-method)
               (list group-method)))
             method-alist post-methods method)
        ;; Weed out all mail methods.
        (while methods
          (setq method (gnus-server-get-method "" (pop methods)))
               (list gnus-select-method)
               (list group-method)))
             method-alist post-methods method)
        ;; Weed out all mail methods.
        (while methods
          (setq method (gnus-server-get-method "" (pop methods)))
-         (when (or (gnus-method-option-p method 'post)
-                   (gnus-method-option-p method 'post-mail))
+         (when (and (or (gnus-method-option-p method 'post)
+                        (gnus-method-option-p method 'post-mail))
+                    (not (member method post-methods)))
            (push method post-methods)))
        ;; Create a name-method alist.
        (setq method-alist
            (push method post-methods)))
        ;; Create a name-method alist.
        (setq method-alist
@@ -513,66 +613,60 @@ If SILENT, don't prompt the user."
      ((and (eq gnus-post-method 'current)
           (not (eq (car group-method) 'nndraft))
           (not arg))
      ((and (eq gnus-post-method 'current)
           (not (eq (car group-method) 'nndraft))
           (not arg))
-      group-method) 
-     (gnus-post-method
+      group-method)
+     ((and gnus-post-method
+          (not (eq gnus-post-method 'current)))
       gnus-post-method)
      ;; Use the normal select method.
      (t gnus-select-method))))
 
 \f
 
       gnus-post-method)
      ;; Use the normal select method.
      (t gnus-select-method))))
 
 \f
 
-;; Dummy to avoid byte-compile warning.
-(defvar nnspool-rejected-article-hook)
-(defvar mule-version)
-(defvar xemacs-betaname)
-(defvar xemacs-codename)
-
 (defun gnus-extended-version ()
 (defun gnus-extended-version ()
-  "Stringified Gnus version and Emacs version."
-  (interactive) ; ???
-  (concat
-   ;; Semi-gnus/VERSION
-   gnus-product-name "/" gnus-version-number
-   ;; EMACS/VERSION
-   (if (featurep 'xemacs)
-       ;; XEmacs
-       (concat
-       (format " XEmacs/%d.%d%s" emacs-major-version emacs-minor-version
-               (if (and (boundp 'xemacs-betaname) xemacs-betaname)
-                   (if (string-match "\\`(\\(.*\\))\\'" xemacs-betaname)
-                       (match-string 1 xemacs-betaname)
-                     "")               ; unknown format
-                 ""))                  ; not beta
-       (if (boundp 'xemacs-codename)
-           (concat " (" xemacs-codename ")")
-         "")                           ; no codename
-       )
-     ;; not XEmacs
-     (concat
-      (format " Emacs/%d.%d" emacs-major-version emacs-minor-version)
-      (if (and (boundp 'enable-multibyte-characters)
-              enable-multibyte-characters)
-         ;; Should return " (multibyte)" ?
-         ""
-       " (unibyte)")
-      ))
-   ;; MULE[/VERSION]
-   (if (featurep 'mule)
-       (if (and (boundp 'mule-version) mule-version)
-          (concat " MULE/" mule-version)
-        " MULE")                       ; no mule-version
-     "")                               ; not Mule
-   ;; Meadow/VERSION
-   (if (featurep 'meadow)
-       (let ((version (Meadow-version)))
-        (if (string-match "\\`Meadow.\\([^ ]*\\)\\( (.*)\\)\\'" version)
-            (concat " Meadow/"
-                    (match-string 1 version)
-                    (match-string 2 version)
-                    )
-          "Meadow"))                   ; unknown format
-     "")                               ; not Meadow
-   ))
+  "Stringified gnus version."
+  (concat gnus-product-name "/" gnus-version-number " (based on "
+         gnus-original-product-name " v" gnus-original-version-number ")"))
+
+(defun gnus-message-make-user-agent (&optional include-mime-info max-column)
+  "Return user-agent info.
+INCLUDE-MIME-INFO the optional first argument if it is non-nil and the variable
+  `mime-edit-user-agent-value' exists, the return value will include it.
+MAX-COLUMN the optional second argument if it is specified, the return value
+  will be folded up in the proper way."
+  (let ((user-agent (if (and include-mime-info
+                            (boundp 'mime-edit-user-agent-value))
+                       (concat (gnus-extended-version)
+                               " "
+                               mime-edit-user-agent-value)
+                     (gnus-extended-version))))
+    (if max-column
+       (let (boundary)
+         (unless (natnump max-column) (setq max-column 76))
+         (with-temp-buffer
+           (insert "            " user-agent)
+           (goto-char 13)
+           (while (re-search-forward "[\n\t ]+" nil t)
+             (replace-match " "))
+           (goto-char 13)
+           (while (re-search-forward "[^ ()/]+\\(/[^ ()/]+\\)? ?" nil t)
+             (while (eq ?\( (char-after (point)))
+               (forward-list)
+               (skip-chars-forward " "))
+             (skip-chars-backward " ")
+             (if (> (current-column) max-column)
+                 (progn
+                   (if (or (not boundary) (eq ?\n (char-after boundary)))
+                       (progn
+                         (setq boundary (point))
+                         (unless (eobp)
+                           (delete-char 1)
+                           (insert "\n ")))
+                     (goto-char boundary)
+                     (delete-char 1)
+                     (insert "\n ")))
+               (setq boundary (point))))
+           (buffer-substring 13 (point-max))))
+      user-agent)))
 
 \f
 ;;;
 
 \f
 ;;;
@@ -636,6 +730,37 @@ If FULL-HEADERS (the prefix), include full headers when forwarding."
           (if full-headers "" message-included-forward-headers)))
       (message-forward post))))
 
           (if full-headers "" message-included-forward-headers)))
       (message-forward post))))
 
+;;; XXX: generate Subject and ``Topics''?
+(defun gnus-summary-mail-digest (&optional n post)
+  "Digests and forwards all articles in this series."
+  (interactive "P")
+  (let ((subject "Digested Articles")
+       (articles (gnus-summary-work-articles n))
+       article frame)
+    (gnus-setup-message 'forward
+      (gnus-summary-select-article)
+      (if post (message-news nil subject) (message-mail nil subject))
+      (when (and message-use-multi-frames (cdr articles))
+       (setq frame (window-frame (get-buffer-window (current-buffer)))))
+      (message-goto-body)
+      (while (setq article (pop articles))
+       (save-window-excursion
+         (set-buffer gnus-summary-buffer)
+         (gnus-summary-select-article nil nil nil article)
+         (gnus-summary-remove-process-mark article))
+       (when frame
+         (select-frame frame))
+       (insert (mime-make-tag "message" "rfc822") "\n")
+       (insert-buffer-substring gnus-original-article-buffer))
+      (push-mark)
+      (message-goto-body)
+      (mime-edit-enclose-digest-region (point)(mark t)))))
+
+(defun gnus-summary-post-digest (&optional n)
+  "Digest and forwards all articles in this series to a newsgroup."
+  (interactive "P")
+  (gnus-summary-mail-digest n t))
+
 (defun gnus-summary-resend-message (address n)
   "Resend the current article to ADDRESS."
   (interactive "sResend message(s) to: \nP")
 (defun gnus-summary-resend-message (address n)
   "Resend the current article to ADDRESS."
   (interactive "sResend message(s) to: \nP")
@@ -684,7 +809,8 @@ The current group name will be inserted at \"%s\".")
        (gnus-summary-select-article)
        (set-buffer gnus-original-article-buffer)
        (if (and (<= (length (message-tokenize-header
        (gnus-summary-select-article)
        (set-buffer gnus-original-article-buffer)
        (if (and (<= (length (message-tokenize-header
-                             (setq newsgroups (mail-fetch-field "newsgroups"))
+                             (setq newsgroups
+                                   (mail-fetch-field "newsgroups"))
                              ", "))
                     1)
                 (or (not (setq followup-to (mail-fetch-field "followup-to")))
                              ", "))
                     1)
                 (or (not (setq followup-to (mail-fetch-field "followup-to")))
@@ -811,7 +937,8 @@ If YANK is non-nil, include the original article."
       (insert gnus-bug-message)
       (goto-char (point-min)))
     (message-pop-to-buffer "*Gnus Bug*")
       (insert gnus-bug-message)
       (goto-char (point-min)))
     (message-pop-to-buffer "*Gnus Bug*")
-    (message-setup `((To . ,gnus-maintainer) (Subject . "")))
+    (message-setup
+     `((To . ,gnus-maintainer) (Cc . ,semi-gnus-developers) (Subject . "")))
     (when gnus-bug-create-help-buffer
       (push `(gnus-bug-kill-buffer) message-send-actions))
     (goto-char (point-min))
     (when gnus-bug-create-help-buffer
       (push `(gnus-bug-kill-buffer) message-send-actions))
     (goto-char (point-min))
@@ -823,7 +950,10 @@ If YANK is non-nil, include the original article."
               (stringp nntp-server-type))
       (insert nntp-server-type))
     (insert "\n\n\n\n\n")
               (stringp nntp-server-type))
       (insert nntp-server-type))
     (insert "\n\n\n\n\n")
-    (gnus-debug)
+    (save-excursion
+      (set-buffer (gnus-get-buffer-create " *gnus environment info*"))
+      (gnus-debug))
+    (insert "<#part type=application/x-emacs-lisp buffer=\" *gnus environment info*\" disposition=inline description=\"User settings\"><#/part>")
     (goto-char (point-min))
     (search-forward "Subject: " nil t)
     (message "")))
     (goto-char (point-min))
     (search-forward "Subject: " nil t)
     (message "")))
@@ -847,7 +977,6 @@ The source file has to be in the Emacs load path."
     ;; Go through all the files looking for non-default values for variables.
     (save-excursion
       (set-buffer (gnus-get-buffer-create " *gnus bug info*"))
     ;; Go through all the files looking for non-default values for variables.
     (save-excursion
       (set-buffer (gnus-get-buffer-create " *gnus bug info*"))
-      (buffer-disable-undo (current-buffer))
       (while files
        (erase-buffer)
        (when (and (setq file (locate-library (pop files)))
       (while files
        (erase-buffer)
        (when (and (setq file (locate-library (pop files)))
@@ -906,14 +1035,15 @@ this is a reply."
   (interactive "P")
   (gnus-summary-select-article t)
   (set-buffer gnus-original-article-buffer)
   (interactive "P")
   (gnus-summary-select-article t)
   (set-buffer gnus-original-article-buffer)
-  (gnus-setup-message 'compose-bounce
-    (let* ((references (mail-fetch-field "references"))
-          (parent (and references (gnus-parent-id references))))
-      (message-bounce)
-      ;; If there are references, we fetch the article we answered to.
-      (and fetch parent
-          (gnus-summary-refer-article parent)
-          (gnus-summary-show-all-headers)))))
+  (let ((gnus-message-setup-hook '(gnus-maybe-setup-default-charset)))
+    (gnus-setup-message 'compose-bounce
+      (let* ((references (mail-fetch-field "references"))
+            (parent (and references (gnus-parent-id references))))
+       (message-bounce)
+       ;; If there are references, we fetch the article we answered to.
+       (and fetch parent
+            (gnus-summary-refer-article parent)
+            (gnus-summary-show-all-headers))))))
 
 ;;; Gcc handling.
 
 
 ;;; Gcc handling.
 
@@ -960,7 +1090,7 @@ this is a reply."
                       (concat "^" (regexp-quote mail-header-separator) "$")
                       nil t)
                  (replace-match "" t t ))
                       (concat "^" (regexp-quote mail-header-separator) "$")
                       nil t)
                  (replace-match "" t t ))
-               (unless (gnus-request-accept-article group method t)
+               (unless (gnus-request-accept-article group method t t)
                  (gnus-message 1 "Couldn't store article in group %s: %s"
                                group (gnus-status-message method))
                  (sit-for 2))
                  (gnus-message 1 "Couldn't store article in group %s: %s"
                                group (gnus-status-message method))
                  (sit-for 2))
@@ -991,7 +1121,7 @@ this is a reply."
          (and gnus-newsgroup-name
               (gnus-group-find-parameter
                gnus-newsgroup-name 'gcc-self)))
          (and gnus-newsgroup-name
               (gnus-group-find-parameter
                gnus-newsgroup-name 'gcc-self)))
-        result 
+        result
         (groups
          (cond
           ((null gnus-message-archive-method)
         (groups
          (cond
           ((null gnus-message-archive-method)
@@ -1059,67 +1189,114 @@ this is a reply."
 
 ;;; Posting styles.
 
 
 ;;; Posting styles.
 
+(defvar gnus-message-style-insertions nil)
+
 (defun gnus-configure-posting-styles ()
   "Configure posting styles according to `gnus-posting-styles'."
 (defun gnus-configure-posting-styles ()
   "Configure posting styles according to `gnus-posting-styles'."
-  (let ((styles gnus-posting-styles)
-       (gnus-newsgroup-name (or gnus-newsgroup-name ""))
-       style match variable attribute value value-value)
-    ;; Go through all styles and look for matches.
-    (while styles
-      (setq style (pop styles)
-           match (pop style))
-      (when (cond ((stringp match)
-                  ;; Regexp string match on the group name.
-                  (string-match match gnus-newsgroup-name))
-                 ((or (symbolp match)
-                      (gnus-functionp match))
-                  (cond ((gnus-functionp match)
-                         ;; Function to be called.
-                         (funcall match))
-                        ((boundp match)
-                         ;; Variable to be checked.
-                         (symbol-value match))))
-                 ((listp match)
-                  ;; This is a form to be evaled.
-                  (eval match)))
-       ;; We have a match, so we set the variables.
-       (while style
-         (setq attribute (pop style)
-               value (cadr attribute)
-               variable nil)
-         ;; We find the variable that is to be modified.
-         (if (and (not (stringp (car attribute)))
-                   (not (eq 'body (car attribute)))
-                  (not (setq variable (cdr (assq (car attribute) 
-                                                 gnus-posting-style-alist)))))
-             (message "Couldn't find attribute %s" (car attribute))
-           ;; We get the value.
-           (setq value-value
-                 (cond ((stringp value)
-                        value)
-                       ((or (symbolp value)
-                            (gnus-functionp value))
-                        (cond ((gnus-functionp value)
-                               (funcall value))
-                              ((boundp value)
-                               (symbol-value value))))
-                       ((listp value)
-                        (eval value))))
-           (if variable
-               ;; This is an ordinary variable.
-               (set (make-local-variable variable) value-value)
-              ;; This is either a body or a header to be inserted in the
-              ;; message
-              (when value-value
-                (let ((attr (car attribute)))
-                  (if (eq 'body attr)
-                      (save-excursion
-                        (goto-char (point-max))
-                        (insert value-value))
-                    (save-excursion
-                     (message-goto-eoh)
-                      (insert (if (stringp attr) attr (symbol-name attr))
-                              ": " value-value "\n"))))))))))))
+  (unless gnus-inhibit-posting-styles
+    (let ((styles gnus-posting-styles)
+         (gnus-newsgroup-name (or gnus-newsgroup-name ""))
+         style match variable attribute value value-value)
+      (make-local-variable 'gnus-message-style-insertions)
+      ;; If the group has a posting-style parameter, add it at the end with a
+      ;; regexp matching everything, to be sure it takes precedence over all
+      ;; the others.
+      (unless (zerop (length gnus-newsgroup-name))
+       (let ((tmp-style (gnus-group-find-parameter
+                         gnus-newsgroup-name 'posting-style t)))
+         (when tmp-style
+           (setq styles (append styles (list (cons ".*" tmp-style)))))))
+      ;; Go through all styles and look for matches.
+      (while styles
+       (setq style (pop styles)
+             match (pop style))
+       (when (cond
+              ((stringp match)
+               ;; Regexp string match on the group name.
+               (string-match match gnus-newsgroup-name))
+              ((or (symbolp match)
+                   (gnus-functionp match))
+               (cond
+                ((gnus-functionp match)
+                 ;; Function to be called.
+                 (funcall match))
+                ((boundp match)
+                 ;; Variable to be checked.
+                 (symbol-value match))))
+              ((listp match)
+               ;; This is a form to be evaled.
+               (eval match)))
+         ;; We have a match, so we set the variables.
+         (while style
+           (setq attribute (pop style)
+                 value (cadr attribute)
+                 variable nil)
+           ;; We find the variable that is to be modified.
+           (if (and (not (stringp (car attribute)))
+                    (not (eq 'body (car attribute)))
+                    (not (setq variable
+                               (cdr (assq (car attribute)
+                                          gnus-posting-style-alist)))))
+               (message "Couldn't find attribute %s" (car attribute))
+             ;; We get the value.
+             (setq value-value
+                   (cond
+                    ((stringp value)
+                     value)
+                    ((or (symbolp value)
+                         (gnus-functionp value))
+                     (cond ((gnus-functionp value)
+                            (funcall value))
+                           ((boundp value)
+                            (symbol-value value))))
+                    ((listp value)
+                     (eval value))))
+             (if variable
+                 ;; This is an ordinary variable.
+                 (set (make-local-variable variable) value-value)
+               ;; This is either a body or a header to be inserted in the
+               ;; message.
+               (let ((attr (car attribute)))
+                 (make-local-variable 'message-setup-hook)
+                 (if (eq 'body attr)
+                     (add-hook 'message-setup-hook
+                               `(lambda ()
+                                  (save-excursion
+                                    (message-goto-body)
+                                    (insert ,value-value))))
+                   (add-hook 'message-setup-hook
+                             'gnus-message-insert-stylings)
+                   (push (cons (if (stringp attr) attr
+                                 (symbol-name attr))
+                               value-value)
+                         gnus-message-style-insertions)))))))))))
+
+(defun gnus-message-insert-stylings ()
+  (let (val)
+    (save-excursion
+      (message-goto-eoh)
+      (while (setq val (pop gnus-message-style-insertions))
+       (when (cdr val)
+         (insert (car val) ": " (cdr val) "\n"))
+       (gnus-pull (car val) gnus-message-style-insertions t)))))
+
+
+;;; @ for MIME Edit mode
+;;;
+
+(defun gnus-maybe-setup-default-charset ()
+  (let ((charset
+        (and (boundp 'gnus-summary-buffer)
+              (buffer-live-p gnus-summary-buffer)
+             (save-excursion
+               (set-buffer gnus-summary-buffer)
+               default-mime-charset))))
+    (if charset
+       (progn
+         (make-local-variable 'default-mime-charset)
+         (setq default-mime-charset charset)
+         ))))
+
 
 ;;; Allow redefinition of functions.
 
 
 ;;; Allow redefinition of functions.