2004-01-16 Steve Youngs <sryoungs@bigpond.net.au>
[gnus] / lisp / gnus.el
index 0005ed3..df42d5d 100644 (file)
@@ -1,7 +1,7 @@
 ;;; gnus.el --- a newsreader for GNU Emacs
 
 ;; Copyright (C) 1987, 1988, 1989, 1990, 1993, 1994, 1995, 1996, 1997,
-;; 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+;; 1998, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;;     Lars Magne Ingebrigtsen <larsi@gnus.org>
@@ -282,10 +282,10 @@ is restarted, and sometimes reloaded."
   :link '(custom-manual "(gnus)Exiting Gnus")
   :group 'gnus)
 
-(defconst gnus-version-number "5.10.3"
+(defconst gnus-version-number "0.2"
   "Version number for this version of Gnus.")
 
-(defconst gnus-version (format "Gnus v%s" gnus-version-number)
+(defconst gnus-version (format "No Gnus v%s" gnus-version-number)
   "Version string for this version of Gnus.")
 
 (defcustom gnus-inhibit-startup-message nil
@@ -303,9 +303,6 @@ be set in `.emacs' instead."
 (unless (fboundp 'gnus-group-remove-excess-properties)
   (defalias 'gnus-group-remove-excess-properties 'ignore))
 
-(unless (fboundp 'gnus-set-text-properties)
-  (defalias 'gnus-set-text-properties 'set-text-properties))
-
 (unless (featurep 'gnus-xmas)
   (defalias 'gnus-make-overlay 'make-overlay)
   (defalias 'gnus-delete-overlay 'delete-overlay)
@@ -339,7 +336,9 @@ be set in `.emacs' instead."
                                         (:type xbm :file "gnus-pointer.xbm"
                                                :ascent center))))
                              gnus-mode-line-image-cache)
-                           'help-echo "This is Gnus")
+                           'help-echo (format
+                                       "This is %s, %s."
+                                       gnus-version (gnus-emacs-version)))
                      str)
                     (list str))
            line)))
@@ -849,12 +848,12 @@ be set in `.emacs' instead."
     (storm "#666699" "#99ccff")
     (pdino "#9999cc" "#99ccff")
     (purp "#9999cc" "#666699")
-    (no "#000000" "#ff0000")
+    (no "#ff0000" "#ffff00")
     (neutral "#b4b4b4" "#878787")
     (september "#bf9900" "#ffcc00"))
   "Color alist used for the Gnus logo.")
 
-(defcustom gnus-logo-color-style 'oort
+(defcustom gnus-logo-color-style 'no
   "*Color styles used for the Gnus logo."
   :type `(choice ,@(mapcar (lambda (elem) (list 'const (car elem)))
                           gnus-logo-color-alist))
@@ -938,10 +937,10 @@ be set in `.emacs' instead."
 
 (eval-when (load)
   (let ((command (format "%s" this-command)))
-    (if (and (string-match "gnus" command)
-            (not (string-match "gnus-other-frame" command)))
-       (gnus-splash)
-      (gnus-get-buffer-create gnus-group-buffer))))
+    (when (string-match "gnus" command)
+      (if (string-match "gnus-other-frame" command)
+         (gnus-get-buffer-create gnus-group-buffer)
+       (gnus-splash)))))
 
 ;;; Do the rest.
 
@@ -1093,21 +1092,17 @@ used to 899, you would say something along these lines:
   :group 'gnus-server
   :type 'file)
 
-;; This function is used to check both the environment variable
-;; NNTPSERVER and the /etc/nntpserver file to see whether one can find
-;; an nntp server name default.
 (defun gnus-getenv-nntpserver ()
+  "Find default nntp server.
+Check the NNTPSERVER environment variable and the
+`gnus-nntpserver-file' file."
   (or (getenv "NNTPSERVER")
       (and (file-readable-p gnus-nntpserver-file)
-          (save-excursion
-            (set-buffer (gnus-get-buffer-create " *gnus nntp*"))
+          (with-temp-buffer
             (insert-file-contents gnus-nntpserver-file)
             (let ((name (buffer-string)))
-              (prog1
-                  (if (string-match "\\'[ \t\n]*$" name)
-                      nil
-                    name)
-                (kill-buffer (current-buffer))))))))
+              (unless (string-match "\\`[ \t\n]*$" name)
+                name))))))
 
 (defcustom gnus-select-method
   (condition-case nil
@@ -1149,7 +1144,8 @@ see the manual for details."
 This should be a mail method."
   :group 'gnus-server
   :group 'gnus-message
-  :type 'gnus-select-method)
+  :type '(choice (const :tag "Default archive method" "archive")
+                gnus-select-method))
 
 (defcustom gnus-message-archive-group nil
   "*Name of the group in which to save the messages you've written.
@@ -1238,6 +1234,7 @@ It can also be a list of select methods, as well as the special symbol
 list, Gnus will try all the methods in the list until it finds a match."
   :group 'gnus-server
   :type '(choice (const :tag "default" nil)
+                (const current)
                 (const :tag "Google" (nnweb "refer" (nnweb-type google)))
                 gnus-select-method
                 (repeat :menu-tag "Try multiple"
@@ -1258,7 +1255,7 @@ list, Gnus will try all the methods in the list until it finds a match."
     "/ftp@rtfm.mit.edu:/pub/usenet/"
     "/ftp@ftp.uni-paderborn.de:/pub/FAQ/"
     "/ftp@ftp.sunet.se:/pub/usenet/"
-    "/ftp@nctuccca.edu.tw:/USENET/FAQ/"
+    "/ftp@nctuccca.nctu.edu.tw:/pub/Documents/rtfm/usenet-by-group/"
     "/ftp@hwarang.postech.ac.kr:/pub/usenet/"
     "/ftp@ftp.hk.super.net:/mirror/faqs/")
   "*Directory where the group FAQs are stored.
@@ -1282,7 +1279,7 @@ If the default site is too slow, try one of these:
                  src.doc.ic.ac.uk               /usenet/news-FAQS
                  ftp.sunet.se                   /pub/usenet
                  ftp.pasteur.fr                 /pub/FAQ
-   Asia:         nctuccca.edu.tw                /USENET/FAQ
+   Asia:         nctuccca.nctu.edu.tw           /pub/Documents/rtfm/usenet-by-group/
                  hwarang.postech.ac.kr          /pub/usenet
                  ftp.hk.super.net               /mirror/faqs"
   :group 'gnus-group-various
@@ -1298,12 +1295,11 @@ If the default site is too slow, try one of these:
     ("europa" . (concat "http://www.europa.usenet.eu.org/chartas/charta-en-"
                        (gnus-replace-in-string name "europa\\." "") ".html"))
     ("nl" . (concat "http://www.xs4all.nl/~sister/usenet/charters/" name))
-    ("aus" . (concat "http://aus.news-admin.org/groupinfo.php/" name))
+    ("aus" . (concat "http://aus.news-admin.org/groupinfo.cgi/" name))
     ("pl" . (concat "http://www.usenet.pl/opisy/" name))
     ("ch" . (concat "http://www.use-net.ch/Usenet/charter.html#" name))
     ("at" . (concat "http://www.usenet.at/chartas/" name "/charta"))
     ("uk" . (concat "http://www.usenet.org.uk/" name ".html"))
-    ("wales" . (concat "http://www.wales-usenet.org/english/groups/" name ".html"))
     ("dfw" . (concat "http://www.cirr.com/dfw/charters/" name ".html"))
     ("se" . (concat "http://www.usenet-se.net/Reglementen/"
                    (gnus-replace-in-string name "\\." "_") ".html"))
@@ -1835,74 +1831,89 @@ This only makes sense for mail groups."
 When a spam group is entered, all unread articles are marked as spam.")
 
   (defvar gnus-group-spam-exit-processor-ifile "ifile"
-    "The ifile summary exit spam processor.")
+    "OBSOLETE: The ifile summary exit spam processor.")
 
   (defvar gnus-group-spam-exit-processor-stat "stat"
-    "The spam-stat summary exit spam processor.")
+    "OBSOLETE: The spam-stat summary exit spam processor.")
 
   (defvar gnus-group-spam-exit-processor-bogofilter "bogofilter"
-    "The Bogofilter summary exit spam processor.")
+    "OBSOLETE: The Bogofilter summary exit spam processor.")
 
   (defvar gnus-group-spam-exit-processor-blacklist "blacklist"
-    "The Blacklist summary exit spam processor.")
+    "OBSOLETE: The Blacklist summary exit spam processor.")
 
   (defvar gnus-group-spam-exit-processor-report-gmane "report-gmane"
-    "The Gmane reporting summary exit spam processor.
+    "OBSOLETE: The Gmane reporting summary exit spam processor.
 Only applicable to NNTP groups with articles from Gmane.  See spam-report.el")
 
   (defvar gnus-group-spam-exit-processor-spamoracle "spamoracle-spam"
-    "The spamoracle summary exit spam processor.")
+    "OBSOLETE: The spamoracle summary exit spam processor.")
 
   (defvar gnus-group-ham-exit-processor-ifile "ifile-ham"
-    "The ifile summary exit ham processor.
+    "OBSOLETE: The ifile summary exit ham processor.
 Only applicable to non-spam (unclassified and ham) groups.")
 
   (defvar gnus-group-ham-exit-processor-bogofilter "bogofilter-ham"
-    "The Bogofilter summary exit ham processor.
+    "OBSOLETE: The Bogofilter summary exit ham processor.
 Only applicable to non-spam (unclassified and ham) groups.")
 
   (defvar gnus-group-ham-exit-processor-stat "stat-ham"
-    "The spam-stat summary exit ham processor.
+    "OBSOLETE: The spam-stat summary exit ham processor.
 Only applicable to non-spam (unclassified and ham) groups.")
 
   (defvar gnus-group-ham-exit-processor-whitelist "whitelist"
-    "The whitelist summary exit ham processor.
+    "OBSOLETE: The whitelist summary exit ham processor.
 Only applicable to non-spam (unclassified and ham) groups.")
 
   (defvar gnus-group-ham-exit-processor-BBDB "bbdb"
-    "The BBDB summary exit ham processor.
+    "OBSOLETE: The BBDB summary exit ham processor.
 Only applicable to non-spam (unclassified and ham) groups.")
 
   (defvar gnus-group-ham-exit-processor-copy "copy"
-    "The ham copy exit ham processor.
+    "OBSOLETE: The ham copy exit ham processor.
 Only applicable to non-spam (unclassified and ham) groups.")
 
   (defvar gnus-group-ham-exit-processor-spamoracle "spamoracle-ham"
-    "The spamoracle summary exit ham processor.
+    "OBSOLETE: The spamoracle summary exit ham processor.
 Only applicable to non-spam (unclassified and ham) groups.")
 
   (gnus-define-group-parameter
    spam-process
    :type list
-   :parameter-type '(choice :tag "Spam Summary Exit Processor"
-                           :value nil
-                           (list :tag "Spam Summary Exit Processor Choices"
-                                 (set
-                                  (variable-item gnus-group-spam-exit-processor-ifile)
-                                  (variable-item gnus-group-spam-exit-processor-stat)
-                                  (variable-item gnus-group-spam-exit-processor-bogofilter)
-                                  (variable-item gnus-group-spam-exit-processor-blacklist)
-                                  (variable-item gnus-group-spam-exit-processor-report-gmane)
-                                  (variable-item gnus-group-spam-exit-processor-spamoracle)
-                                  (variable-item gnus-group-ham-exit-processor-bogofilter)
-                                  (variable-item gnus-group-ham-exit-processor-ifile)
-                                  (variable-item gnus-group-ham-exit-processor-stat)
-                                  (variable-item gnus-group-ham-exit-processor-whitelist)
-                                  (variable-item gnus-group-ham-exit-processor-BBDB)
-                                  (variable-item gnus-group-ham-exit-processor-copy)
-                                  (variable-item gnus-group-ham-exit-processor-spamoracle))))
+   :parameter-type 
+   '(choice 
+     :tag "Spam Summary Exit Processor"
+     :value nil
+     (list :tag "Spam Summary Exit Processor Choices"
+          (set
+           (variable-item gnus-group-spam-exit-processor-ifile)
+           (variable-item gnus-group-spam-exit-processor-stat)
+           (variable-item gnus-group-spam-exit-processor-bogofilter)
+           (variable-item gnus-group-spam-exit-processor-blacklist)
+           (variable-item gnus-group-spam-exit-processor-spamoracle)
+           (variable-item gnus-group-spam-exit-processor-report-gmane)
+           (variable-item gnus-group-ham-exit-processor-bogofilter)
+           (variable-item gnus-group-ham-exit-processor-ifile)
+           (variable-item gnus-group-ham-exit-processor-stat)
+           (variable-item gnus-group-ham-exit-processor-whitelist)
+           (variable-item gnus-group-ham-exit-processor-BBDB)
+           (variable-item gnus-group-ham-exit-processor-spamoracle)
+           (variable-item gnus-group-ham-exit-processor-copy)
+           (const :tag "Spam: Gmane Report"  (spam spam-use-gmane))
+           (const :tag "Spam: Bogofilter"    (spam spam-use-bogofilter))
+           (const :tag "Spam: Blacklist"     (spam spam-use-blacklist))
+           (const :tag "Spam: ifile"         (spam spam-use-ifile))
+           (const :tag "Spam: Spam-stat"     (spam spam-use-stat))
+           (const :tag "Spam: Spam Oracle"   (spam spam-use-spamoracle))
+           (const :tag "Ham: ifile"          (ham spam-use-ifile))
+           (const :tag "Ham: Bogofilter"     (ham spam-use-bogofilter))
+           (const :tag "Ham: Spam-stat"      (ham spam-use-stat))
+           (const :tag "Ham: Whitelist"      (ham spam-use-whitelist))
+           (const :tag "Ham: BBDB"           (ham spam-use-BBDB))
+           (const :tag "Ham: Copy"           (ham spam-use-ham-copy))
+           (const :tag "Ham: Spam Oracle"    (ham spam-use-spamoracle)))))
    :function-document
-   "Which spam or ham processors will be applied to the GROUP articles at summary exit."
+   "Which spam or ham processors will be applied when the summary is exited."
    :variable gnus-spam-process-newsgroups
    :variable-default nil
    :variable-document
@@ -1911,29 +1922,133 @@ a backend on summary exit.  If non-nil, this should be a list of group
 name regexps that should match all groups in which to do automatic
 spam processing, associated with the appropriate processor."
    :variable-group spam
-   :variable-type '(repeat :tag "Spam/Ham Processors"
-                          (list :tag "Spam Summary Exit Processor Choices"
-                                (regexp :tag "Group Regexp")
-                                (set :tag "Spam/Ham Summary Exit Processor"
-                                     (variable-item gnus-group-spam-exit-processor-ifile)
-                                     (variable-item gnus-group-spam-exit-processor-stat)
-                                     (variable-item gnus-group-spam-exit-processor-bogofilter)
-                                     (variable-item gnus-group-spam-exit-processor-blacklist)
-                                     (variable-item gnus-group-spam-exit-processor-report-gmane)
-                                     (variable-item gnus-group-ham-exit-processor-bogofilter)
-                                     (variable-item gnus-group-ham-exit-processor-ifile)
-                                     (variable-item gnus-group-ham-exit-processor-stat)
-                                     (variable-item gnus-group-ham-exit-processor-whitelist)
-                                     (variable-item gnus-group-ham-exit-processor-BBDB)
-                                     (variable-item gnus-group-ham-exit-processor-copy))))
+   :variable-type 
+   '(repeat :tag "Spam/Ham Processors"
+           (list :tag "Spam Summary Exit Processor Choices"
+                 (regexp :tag "Group Regexp")
+                 (set 
+                  :tag "Spam/Ham Summary Exit Processor"
+                  (variable-item gnus-group-spam-exit-processor-ifile)
+                  (variable-item gnus-group-spam-exit-processor-stat)
+                  (variable-item gnus-group-spam-exit-processor-bogofilter)
+                  (variable-item gnus-group-spam-exit-processor-blacklist)
+                  (variable-item gnus-group-spam-exit-processor-spamoracle)
+                  (variable-item gnus-group-spam-exit-processor-report-gmane)
+                  (variable-item gnus-group-ham-exit-processor-bogofilter)
+                  (variable-item gnus-group-ham-exit-processor-ifile)
+                  (variable-item gnus-group-ham-exit-processor-stat)
+                  (variable-item gnus-group-ham-exit-processor-whitelist)
+                  (variable-item gnus-group-ham-exit-processor-BBDB)
+                  (variable-item gnus-group-ham-exit-processor-spamoracle)
+                  (variable-item gnus-group-ham-exit-processor-copy)
+                  (const :tag "Spam: Gmane Report"  (spam spam-use-gmane))
+                  (const :tag "Spam: Bogofilter"    (spam spam-use-bogofilter))
+                  (const :tag "Spam: Blacklist"     (spam spam-use-blacklist))
+                  (const :tag "Spam: ifile"         (spam spam-use-ifile))
+                  (const :tag "Spam: Spam-stat"     (spam spam-use-stat))
+                  (const :tag "Spam: Spam Oracle"   (spam spam-use-spamoracle))
+                  (const :tag "Ham: ifile"          (ham spam-use-ifile))
+                  (const :tag "Ham: Bogofilter"     (ham spam-use-bogofilter))
+                  (const :tag "Ham: Spam-stat"      (ham spam-use-stat))
+                  (const :tag "Ham: Whitelist"      (ham spam-use-whitelist))
+                  (const :tag "Ham: BBDB"           (ham spam-use-BBDB))
+                  (const :tag "Ham: Copy"           (ham spam-use-ham-copy))
+                  (const :tag "Ham: Spam Oracle"    (ham spam-use-spamoracle)))))
+
    :parameter-document
-   "Which spam processors will be applied to the spam or ham GROUP articles at summary exit.")
+   "Which spam or ham processors will be applied when the summary is exited.")
+
+  (gnus-define-group-parameter
+   spam-autodetect
+   :type list
+   :parameter-type 
+   '(boolean :tag "Spam autodetection")
+   :function-document
+   "Should spam be autodetected (with spam-split) in this group?"
+   :variable gnus-spam-autodetect
+   :variable-default nil
+   :variable-document
+   "*Groups in which spam should be autodetected when they are entered.
+   Only unseen articles will be examined, unless
+   spam-autodetect-recheck-messages is set."
+   :variable-group spam
+   :variable-type 
+   '(repeat
+     :tag "Autodetection setting"
+     (list
+      (regexp :tag "Group Regexp")
+      boolean))
+   :parameter-document
+   "Spam autodetection.
+Only unseen articles will be examined, unless
+spam-autodetect-recheck-messages is set.")
+
+  (gnus-define-group-parameter
+   spam-autodetect-methods
+   :type list
+   :parameter-type 
+   '(choice :tag "Spam autodetection-specific methods"
+     (const none)
+     (const default)
+     (set :tag "Use specific methods"
+         (variable-item spam-use-blacklist)
+         (variable-item spam-use-regex-headers)
+         (variable-item spam-use-regex-body)
+         (variable-item spam-use-whitelist)
+         (variable-item spam-use-BBDB)
+         (variable-item spam-use-ifile)
+         (variable-item spam-use-spamoracle)
+         (variable-item spam-use-stat)
+         (variable-item spam-use-blackholes)
+         (variable-item spam-use-hashcash)
+         (variable-item spam-use-bogofilter-headers)
+         (variable-item spam-use-bogofilter)))
+   :function-document
+   "Methods to be used for autodetection in each group"
+   :variable gnus-spam-autodetect-methods
+   :variable-default nil
+   :variable-document
+   "*Methods for autodetecting spam per group.
+Requires the spam-autodetect parameter.  Only unseen articles
+will be examined, unless spam-autodetect-recheck-messages is
+set."
+   :variable-group spam
+   :variable-type 
+   '(repeat
+     :tag "Autodetection methods"
+     (list
+      (regexp :tag "Group Regexp")
+      (choice
+       (const none)
+       (const default)
+       (set :tag "Use specific methods"
+       (variable-item spam-use-blacklist)
+       (variable-item spam-use-regex-headers)
+       (variable-item spam-use-regex-body)
+       (variable-item spam-use-whitelist)
+       (variable-item spam-use-BBDB)
+       (variable-item spam-use-ifile)
+       (variable-item spam-use-spamoracle)
+       (variable-item spam-use-stat)
+       (variable-item spam-use-blackholes)
+       (variable-item spam-use-hashcash)
+       (variable-item spam-use-bogofilter-headers)
+       (variable-item spam-use-bogofilter)))))
+     :parameter-document
+   "Spam autodetection methods.  
+Requires the spam-autodetect parameter.  Only unseen articles
+will be examined, unless spam-autodetect-recheck-messages is
+set.")
 
   (gnus-define-group-parameter
    spam-process-destination
-   :parameter-type '(choice :tag "Destination for spam-processed articles at summary exit"
-                           (string :tag "Move to a group")
-                           (const :tag "Expire" nil))
+   :type list
+   :parameter-type 
+   '(choice :tag "Destination for spam-processed articles at summary exit"
+           (string :tag "Move to a group")
+           (repeat :tag "Move to multiple groups"
+                   (string :tag "Destination group"))
+           (const :tag "Expire" nil))
    :function-document
    "Where spam-processed articles will go at summary exit."
    :variable gnus-spam-process-destinations
@@ -1946,23 +2061,31 @@ to do spam-processed article moving, associated with the destination
 group or nil for explicit expiration.  This only makes sense for
 mail groups."
    :variable-group spam
-   :variable-type '(repeat
-                   :tag "Spam-processed articles destination"
-                   (list
-                    (regexp :tag "Group Regexp")
-                    (choice
-                     :tag "Destination for spam-processed articles at summary exit"
-                     (string :tag "Move to a group")
-                     (const :tag "Expire" nil))))
+   :variable-type 
+   '(repeat
+     :tag "Spam-processed articles destination"
+     (list
+      (regexp :tag "Group Regexp")
+      (choice
+       :tag "Destination for spam-processed articles at summary exit"
+       (string :tag "Move to a group")
+       (repeat :tag "Move to multiple groups"
+              (string :tag "Destination group"))
+       (const :tag "Expire" nil))))
    :parameter-document
    "Where spam-processed articles will go at summary exit.")
-
+  
   (gnus-define-group-parameter
    ham-process-destination
-   :parameter-type '(choice
-                    :tag "Destination for ham articles at summary exit from a spam group"
-                    (string :tag "Move to a group")
-                    (const :tag "Do nothing" nil))
+   :type list
+   :parameter-type 
+   '(choice
+     :tag "Destination for ham articles at summary exit from a spam group"
+     (string :tag "Move to a group")
+     (repeat :tag "Move to multiple groups"
+            (string :tag "Destination group"))
+     (const :tag "Respool" respool)
+     (const :tag "Do nothing" nil))
    :function-document
    "Where ham articles will go at summary exit from a spam group."
    :variable gnus-ham-process-destinations
@@ -1975,14 +2098,18 @@ to do ham article moving, associated with the destination
 group or nil for explicit ignoring.  This only makes sense for
 mail groups, and only works in spam groups."
    :variable-group spam
-   :variable-type '(repeat
-                   :tag "Ham articles destination"
-                   (list
-                    (regexp :tag "Group Regexp")
-                    (choice
-                     :tag "Destination for ham articles at summary exit from spam group"
-                     (string :tag "Move to a group")
-                     (const :tag "Expire" nil))))
+   :variable-type 
+   '(repeat
+     :tag "Ham articles destination"
+     (list
+      (regexp :tag "Group Regexp")
+      (choice
+       :tag "Destination for ham articles at summary exit from spam group"
+       (string :tag "Move to a group")
+       (repeat :tag "Move to multiple groups"
+               (string :tag "Destination group"))
+       (const :tag "Respool" respool)
+       (const :tag "Expire" nil))))
    :parameter-document
    "Where ham articles will go at summary exit from a spam group.")
 
@@ -2201,11 +2328,33 @@ This should be an alist for Emacs, or a plist for XEmacs."
                         (symbol :tag "Parameter")
                         (sexp :tag "Value")))))
 
+(defcustom gnus-user-agent 'emacs-gnus-type
+  "Which information should be exposed in the User-Agent header.
+
+It can be one of the symbols `gnus' \(show only Gnus version\), `emacs-gnus'
+\(show only Emacs and Gnus versions\), `emacs-gnus-config' \(same as
+`emacs-gnus' plus system configuration\), `emacs-gnus-type' \(same as
+`emacs-gnus' plus system type\) or a custom string.  If you set it to a
+string, be sure to use a valid format, see RFC 2616."
+  :group 'gnus-message
+  :type '(choice
+         (item :tag "Show Gnus and Emacs versions and system type"
+               emacs-gnus-type)
+         (item :tag "Show Gnus and Emacs versions and system configuration"
+               emacs-gnus-config)
+         (item :tag "Show Gnus and Emacs versions" emacs-gnus)
+         (item :tag "Show only Gnus version" gnus)
+         (string :tag "Other")))
+
 \f
 ;;; Internal variables
 
 (defvar gnus-agent-gcc-header "X-Gnus-Agent-Gcc")
 (defvar gnus-agent-meta-information-header "X-Gnus-Agent-Meta-Information")
+(defvar gnus-agent-method-p-cache nil
+  ; Reset each time gnus-agent-covered-methods is changed else
+  ; gnus-agent-method-p may mis-report a methods status.
+  )
 (defvar gnus-agent-target-move-group-header "X-Gnus-Agent-Move-To")
 (defvar gnus-draft-meta-information-header "X-Draft-From")
 (defvar gnus-group-get-parameter-function 'gnus-group-get-parameter)
@@ -2217,7 +2366,8 @@ This should be an alist for Emacs, or a plist for XEmacs."
 (defvar gnus-agent-fetching nil
   "Whether Gnus agent is in fetching mode.")
 
-(defvar gnus-agent-covered-methods nil)
+(defvar gnus-agent-covered-methods nil
+  "A list of servers, NOT methods, showing which servers are covered by the agent.")
 
 (defvar gnus-command-method nil
   "Dynamically bound variable that says what the current back end is.")
@@ -2329,7 +2479,7 @@ such as a mark that says whether an article is stored in the cache
                        gnus-newsrc-alist gnus-server-alist
                        gnus-killed-list gnus-zombie-list
                        gnus-topic-topology gnus-topic-alist
-                       gnus-agent-covered-methods gnus-format-specs)
+                       gnus-format-specs)
   "Gnus variables saved in the quick startup file.")
 
 (defvar gnus-newsrc-alist nil
@@ -3066,7 +3216,7 @@ that that variable is buffer-local to the summary buffers."
 (defun gnus-generate-new-group-name (leaf)
   (let ((name leaf)
        (num 0))
-    (while (gnus-gethash name gnus-newsrc-hashtb)
+    (while (gnus-group-entry name)
       (setq name (concat leaf "<" (int-to-string (setq num (1+ num))) ">")))
     name))
 
@@ -3129,10 +3279,59 @@ that that variable is buffer-local to the summary buffers."
                            (not (equal server (format "%s:%s" (caar servers)
                                                       (cadar servers)))))
                  (pop servers))
-               (car servers)))))
-       (push (cons server result) gnus-server-method-cache)
+               (car servers))
+              ;; This could be some sort of foreign server that I
+              ;; simply haven't opened (yet).  Do a brute-force scan
+              ;; of the entire gnus-newsrc-alist for the server name
+              ;; of every method.  As a side-effect, loads the
+              ;; gnus-server-method-cache so this only happens once,
+              ;; if at all.
+              (let (match)
+                (mapcar 
+                 (lambda (info)
+                   (let ((info-method (gnus-info-method info)))
+                     (unless (stringp info-method)
+                       (let ((info-server (gnus-method-to-server info-method)))
+                         (when (equal server info-server)
+                           (setq match info-method))))))
+                 (cdr gnus-newsrc-alist))
+                match))))
+        (when result
+          (push (cons server result) gnus-server-method-cache))
        result)))
 
+(defsubst gnus-method-to-server (method)
+  (catch 'server-name
+    (setq method (or method gnus-select-method))
+
+    ;; Perhaps it is already in the cache.
+    (mapc (lambda (name-method)
+            (if (equal (cdr name-method) method)
+                (throw 'server-name (car name-method))))
+          gnus-server-method-cache)
+
+    (mapc
+     (lambda (server-alist)
+       (mapc (lambda (name-method)
+               (when (gnus-methods-equal-p (cdr name-method) method)
+                 (unless (member name-method gnus-server-method-cache)
+                   (push name-method gnus-server-method-cache))
+                 (throw 'server-name (car name-method))))
+             server-alist))
+     (let ((alists (list gnus-server-alist
+                         gnus-predefined-server-alist)))
+       (if gnus-select-method
+           (push (list (cons "native" gnus-select-method)) alists))
+       alists))
+
+    (let* ((name (if (member (cadr method) '(nil ""))
+                     (format "%s" (car method))
+                   (format "%s:%s" (car method) (cadr method))))
+           (name-method (cons name method)))
+      (unless (member name-method gnus-server-method-cache)
+        (push name-method gnus-server-method-cache))
+      name)))
+
 (defsubst gnus-server-get-method (group method)
   ;; Input either a server name, and extended server name, or a
   ;; select method, and return a select method.
@@ -3247,11 +3446,19 @@ server is native)."
       group
     (gnus-group-full-name group (gnus-find-method-for-group group))))
 
+(defun gnus-group-guess-full-name-from-command-method (group)
+  "Guess the full name from GROUP, even if the method is native."
+  (if (gnus-group-prefixed-p group)
+      group
+    (gnus-group-full-name group gnus-command-method)))
+
 (defun gnus-group-real-prefix (group)
   "Return the prefix of the current group name."
-  (if (string-match "^[^:]+:" group)
-      (substring group 0 (match-end 0))
-    ""))
+  (if (stringp group)
+      (if (string-match "^[^:]+:" group)
+         (substring group 0 (match-end 0))
+       "")
+    nil))
 
 (defun gnus-group-short-name (group)
   "Return the short group name."
@@ -3300,10 +3507,10 @@ You should probably use `gnus-find-method-for-group' instead."
 (defsubst gnus-secondary-method-p (method)
   "Return whether METHOD is a secondary select method."
   (let ((methods gnus-secondary-select-methods)
-       (gmethod (gnus-server-get-method nil method)))
+       (gmethod (inline (gnus-server-get-method nil method))))
     (while (and methods
                (not (gnus-method-equal
-                     (gnus-server-get-method nil (car methods))
+                     (inline (gnus-server-get-method nil (car methods)))
                      gmethod)))
       (setq methods (cdr methods)))
     methods))
@@ -3702,6 +3909,9 @@ If NEWSGROUP is nil, return the global kill file name instead."
       (setq valids (cdr valids)))
     outs))
 
+(eval-when-compile
+  (autoload 'message-y-or-n-p "message" nil nil 'macro))
+
 (defun gnus-read-group (prompt &optional default)
   "Prompt the user for a group name.
 Disallow invalid group names."
@@ -3713,8 +3923,22 @@ Disallow invalid group names."
             (setq group (read-string (concat prefix prompt)
                                      (cons (or default "") 0)
                                      'gnus-group-history)))
-       (setq prefix (format "Invalid group name: \"%s\".  " group)
-             group nil)))
+       (let ((match (match-string 0 group)))
+         ;; Might be okay (e.g. for nnimap), so ask the user:
+         (unless (and (not (string-match "^$\\|:" match))
+                      (message-y-or-n-p
+                       "Proceed and create group anyway? " t
+"The group name \"" group "\" contains a forbidden character: \"" match "\".
+
+Usually, it's dangerous to create a group with this name, because it's not
+supported by all back ends and servers.  On IMAP servers it should work,
+though.  If you are really sure, you can proceed anyway and create the group.
+
+You may customize the variable `gnus-invalid-group-regexp', which currently is
+set to \"" gnus-invalid-group-regexp
+"\", if you want to get rid of this query permanently."))
+           (setq prefix (format "Invalid group name: \"%s\".  " group)
+                 group nil)))))
     group))
 
 (defun gnus-read-method (prompt)
@@ -3758,7 +3982,13 @@ Allow completion over sensible values."
 
 (defun gnus-agent-method-p (method)
   "Say whether METHOD is covered by the agent."
-  (member method gnus-agent-covered-methods))
+  (or (eq (car gnus-agent-method-p-cache) method)
+      (setq gnus-agent-method-p-cache 
+            (cons method
+                  (member (if (stringp method) 
+                              method 
+                            (gnus-method-to-server method)) gnus-agent-covered-methods))))
+  (cdr gnus-agent-method-p-cache))
 
 (defun gnus-online (method)
   (not
@@ -3846,7 +4076,7 @@ current display is used."
 (defun gnus (&optional arg dont-connect slave)
   "Read network news.
 If ARG is non-nil and a positive number, Gnus will use that as the
-startup level. If ARG is non-nil and not a positive number, Gnus will
+startup level.  If ARG is non-nil and not a positive number, Gnus will
 prompt the user for the name of an NNTP server to use."
   (interactive "P")
   (unless (byte-code-function-p (symbol-function 'gnus))