Update copyright year to 2016
[gnus] / lisp / gnus.el
index 19b19aa..19807fc 100644 (file)
@@ -1,7 +1,7 @@
 ;;; gnus.el --- a newsreader for GNU Emacs
 
 ;;; gnus.el --- a newsreader for GNU Emacs
 
-;; Copyright (C) 1987-1990, 1993-1998, 2000-2012
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1987-1990, 1993-1998, 2000-2016 Free Software
+;; Foundation, Inc.
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;;     Lars Magne Ingebrigtsen <larsi@gnus.org>
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;;     Lars Magne Ingebrigtsen <larsi@gnus.org>
 
 (eval '(run-hooks 'gnus-load-hook))
 
 
 (eval '(run-hooks 'gnus-load-hook))
 
-;; For Emacs <22.2 and XEmacs.
-(eval-and-compile
-  (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
-
 (eval-when-compile (require 'cl))
 (require 'wid-edit)
 (require 'mm-util)
 (eval-when-compile (require 'cl))
 (require 'wid-edit)
 (require 'mm-util)
@@ -294,7 +290,7 @@ is restarted, and sometimes reloaded."
   :link '(custom-manual "(gnus)Exiting Gnus")
   :group 'gnus)
 
   :link '(custom-manual "(gnus)Exiting Gnus")
   :group 'gnus)
 
-(defconst gnus-version-number "0.2"
+(defconst gnus-version-number "0.14"
   "Version number for this version of Gnus.")
 
 (defconst gnus-version (format "Ma Gnus v%s" gnus-version-number)
   "Version number for this version of Gnus.")
 
 (defconst gnus-version (format "Ma Gnus v%s" gnus-version-number)
@@ -308,15 +304,6 @@ be set in `.emacs' instead."
   :type 'boolean)
 
 (unless (featurep 'gnus-xmas)
   :type 'boolean)
 
 (unless (featurep 'gnus-xmas)
-  (defalias 'gnus-make-overlay 'make-overlay)
-  (defalias 'gnus-delete-overlay 'delete-overlay)
-  (defalias 'gnus-overlay-get 'overlay-get)
-  (defalias 'gnus-overlay-put 'overlay-put)
-  (defalias 'gnus-move-overlay 'move-overlay)
-  (defalias 'gnus-overlay-buffer 'overlay-buffer)
-  (defalias 'gnus-overlay-start 'overlay-start)
-  (defalias 'gnus-overlay-end 'overlay-end)
-  (defalias 'gnus-overlays-in 'overlays-in)
   (defalias 'gnus-extent-detached-p 'ignore)
   (defalias 'gnus-extent-start-open 'ignore)
   (defalias 'gnus-mail-strip-quoted-names 'mail-strip-quoted-names)
   (defalias 'gnus-extent-detached-p 'ignore)
   (defalias 'gnus-extent-start-open 'ignore)
   (defalias 'gnus-mail-strip-quoted-names 'mail-strip-quoted-names)
@@ -328,8 +315,9 @@ be set in `.emacs' instead."
   (if (fboundp 'find-image)
       (defun gnus-mode-line-buffer-identification (line)
        (let ((str (car-safe line))
   (if (fboundp 'find-image)
       (defun gnus-mode-line-buffer-identification (line)
        (let ((str (car-safe line))
-             (load-path (mm-image-load-path)))
-         (if (and (stringp str)
+             (load-path (append (mm-image-load-path) load-path)))
+         (if (and (display-graphic-p)
+                  (stringp str)
                   (string-match "^Gnus:" str))
              (progn (add-text-properties
                      0 5
                   (string-match "^Gnus:" str))
              (progn (add-text-properties
                      0 5
@@ -1272,15 +1260,18 @@ Set this variable in `.emacs' instead."
   :type '(choice (const :tag "current" nil)
                 directory))
 
   :type '(choice (const :tag "current" nil)
                 directory))
 
-;; Site dependent variables.  These variables should be defined in
-;; paths.el.
+;; Site dependent variables.
 
 
-(defvar gnus-default-nntp-server nil
-  "Specify a default NNTP server.
-This variable should be defined in paths.el, and should never be set
-by the user.
-If you want to change servers, you should use `gnus-select-method'.
-See the documentation to that variable.")
+;; Should this be obsolete?
+(defcustom gnus-default-nntp-server nil
+  "The hostname of the default NNTP server.
+The empty string, or nil, means to use the local host.
+You may wish to set this on a site-wide basis.
+
+If you want to change servers, you should use `gnus-select-method'."
+  :group 'gnus-server
+  :type '(choice (const :tag "local host" nil)
+                 (string :tag "host name")))
 
 (defcustom gnus-nntpserver-file "/etc/nntpserver"
   "A file with only the name of the nntp server in it."
 
 (defcustom gnus-nntpserver-file "/etc/nntpserver"
   "A file with only the name of the nntp server in it."
@@ -1317,16 +1308,18 @@ news is to be fetched, the second is the address.
 For instance, if you want to get your news via \"flab.flab.edu\" using
 NNTP, you could say:
 
 For instance, if you want to get your news via \"flab.flab.edu\" using
 NNTP, you could say:
 
-\(setq gnus-select-method '(nntp \"flab.flab.edu\"))
+\(setq gnus-select-method \\='(nntp \"flab.flab.edu\"))
 
 If you want to use your local spool, say:
 
 
 If you want to use your local spool, say:
 
-\(setq gnus-select-method (list 'nnspool (system-name)))
+\(setq gnus-select-method (list \\='nnspool (system-name)))
 
 If you use this variable, you must set `gnus-nntp-server' to nil.
 
 There is a lot more to know about select methods and virtual servers -
 see the manual for details."
 
 If you use this variable, you must set `gnus-nntp-server' to nil.
 
 There is a lot more to know about select methods and virtual servers -
 see the manual for details."
+  ;; Emacs has set-after since 22.1.
+  ;set-after '(gnus-default-nntp-server)
   :group 'gnus-server
   :group 'gnus-start
   :initialize 'custom-initialize-default
   :group 'gnus-server
   :group 'gnus-start
   :initialize 'custom-initialize-default
@@ -1368,8 +1361,8 @@ group (or nil) as a parameter.
 If you want to save your mail in one group and the news articles you
 write in another group, you could say something like:
 
 If you want to save your mail in one group and the news articles you
 write in another group, you could say something like:
 
\(setq gnus-message-archive-group
-       '((if (message-news-p)
 (setq gnus-message-archive-group
+       \\='((if (message-news-p)
              \"misc-news\"
            \"misc-mail\")))
 
              \"misc-news\"
            \"misc-mail\")))
 
@@ -1404,7 +1397,7 @@ This is a list where each element is a complete select method (see
 If, for instance, you want to read your mail with the nnml back end,
 you could set this variable:
 
 If, for instance, you want to read your mail with the nnml back end,
 you could set this variable:
 
-\(setq gnus-secondary-select-methods '((nnml \"\")))"
+\(setq gnus-secondary-select-methods \\='((nnml \"\")))"
   :group 'gnus-server
   :type '(repeat gnus-select-method))
 
   :group 'gnus-server
   :type '(repeat gnus-select-method))
 
@@ -1609,7 +1602,7 @@ slower."
   :type 'string)
 
 (defcustom gnus-valid-select-methods
   :type 'string)
 
 (defcustom gnus-valid-select-methods
-  '(("nntp" post address prompt-address physical-address)
+  '(("nntp" post address prompt-address physical-address cloud)
     ("nnspool" post address)
     ("nnvirtual" post-mail virtual prompt-address)
     ("nnmbox" mail respool address)
     ("nnspool" post address)
     ("nnvirtual" post-mail virtual prompt-address)
     ("nnmbox" mail respool address)
@@ -1623,10 +1616,10 @@ slower."
     ("nnfolder" mail respool address)
     ("nngateway" post-mail address prompt-address physical-address)
     ("nnweb" none)
     ("nnfolder" mail respool address)
     ("nngateway" post-mail address prompt-address physical-address)
     ("nnweb" none)
-    ("nnrss" none)
+    ("nnrss" none global)
     ("nnagent" post-mail)
     ("nnimap" post-mail address prompt-address physical-address respool
     ("nnagent" post-mail)
     ("nnimap" post-mail address prompt-address physical-address respool
-     server-marks)
+     server-marks cloud)
     ("nnmaildir" mail respool address server-marks)
     ("nnnil" none))
   "*An alist of valid select methods.
     ("nnmaildir" mail respool address server-marks)
     ("nnnil" none))
   "*An alist of valid select methods.
@@ -1642,12 +1635,14 @@ this variable.  I think."
                                             (const :format "%v " mail)
                                             (const :format "%v " none)
                                             (const post-mail))
                                             (const :format "%v " mail)
                                             (const :format "%v " none)
                                             (const post-mail))
-                       (checklist :inline t
+                       (checklist :inline t :greedy t
                                   (const :format "%v " address)
                                   (const :format "%v " address)
+                                  (const global)
                                   (const :format "%v " prompt-address)
                                   (const :format "%v " physical-address)
                                   (const :format "%v " prompt-address)
                                   (const :format "%v " physical-address)
-                                  (const :format "%v " virtual)
-                                  (const respool))))
+                                  (const virtual)
+                                  (const :format "%v " respool)
+                                  (const server-marks))))
   :version "24.1")
 
 (defun gnus-redefine-select-method-widget ()
   :version "24.1")
 
 (defun gnus-redefine-select-method-widget ()
@@ -2401,7 +2396,7 @@ less space and be faster as a result.
 This variable can also be a list of visual elements to switch on.  For
 instance, to switch off all visual things except menus, you can say:
 
 This variable can also be a list of visual elements to switch on.  For
 instance, to switch off all visual things except menus, you can say:
 
-   (setq gnus-visual '(menu))
+   (setq gnus-visual \\='(menu))
 
 Valid elements include `summary-highlight', `group-highlight',
 `article-highlight', `mouse-face', `summary-menu', `group-menu',
 
 Valid elements include `summary-highlight', `group-highlight',
 `article-highlight', `mouse-face', `summary-menu', `group-menu',
@@ -2489,9 +2484,19 @@ Disabling the agent may result in noticeable loss of performance."
   :type 'boolean)
 
 (defcustom gnus-other-frame-function 'gnus
   :type 'boolean)
 
 (defcustom gnus-other-frame-function 'gnus
-  "Function called by the command `gnus-other-frame'."
+  "Function called by the command `gnus-other-frame' when starting Gnus."
+  :group 'gnus-start
+  :type '(choice (function-item gnus)
+                (function-item gnus-no-server)
+                (function-item gnus-slave)
+                (function-item gnus-slave-no-server)))
+
+(defcustom gnus-other-frame-resume-function 'gnus-group-get-new-news
+  "Function called by the command `gnus-other-frame' when resuming Gnus."
+  :version "24.4"
   :group 'gnus-start
   :type '(choice (function-item gnus)
   :group 'gnus-start
   :type '(choice (function-item gnus)
+                (function-item gnus-group-get-new-news)
                 (function-item gnus-no-server)
                 (function-item gnus-slave)
                 (function-item gnus-slave-no-server)))
                 (function-item gnus-no-server)
                 (function-item gnus-slave)
                 (function-item gnus-slave-no-server)))
@@ -2512,10 +2517,10 @@ This should be an alist for Emacs, or a plist for XEmacs."
   "Which information should be exposed in the User-Agent header.
 
 Can be a list of symbols or a string.  Valid symbols are `gnus'
   "Which information should be exposed in the User-Agent header.
 
 Can be a list of symbols or a string.  Valid symbols are `gnus'
-\(show Gnus version\) and `emacs' \(show Emacs version\).  In
+\(show Gnus version) and `emacs' \(show Emacs version).  In
 addition to the Emacs version, you can add `codename' \(show
 addition to the Emacs version, you can add `codename' \(show
-\(S\)XEmacs codename\) or either `config' \(show system
-configuration\) or `type' \(show system type\).  If you set it to
+\(S)XEmacs codename) or either `config' \(show system
+configuration) or `type' \(show system type).  If you set it to
 a string, be sure to use a valid format, see RFC 2616."
 
   :version "22.1"
 a string, be sure to use a valid format, see RFC 2616."
 
   :version "22.1"
@@ -2620,10 +2625,11 @@ a string, be sure to use a valid format, see RFC 2616."
     (scored . score) (saved . save)
     (cached . cache) (downloadable . download)
     (unsendable . unsend) (forwarded . forward)
     (scored . score) (saved . save)
     (cached . cache) (downloadable . download)
     (unsendable . unsend) (forwarded . forward)
-    (seen . seen)))
+    (seen . seen) (unexist . unexist)))
 
 (defconst gnus-article-special-mark-lists
   '((seen range)
 
 (defconst gnus-article-special-mark-lists
   '((seen range)
+    (unexist range)
     (killed range)
     (bookmark tuple)
     (uid tuple)
     (killed range)
     (bookmark tuple)
     (uid tuple)
@@ -2638,7 +2644,7 @@ a string, be sure to use a valid format, see RFC 2616."
 ;; `score' is not a proper mark
 ;; `bookmark': don't propagated it, or fix the bug in update-mark.
 (defconst gnus-article-unpropagated-mark-lists
 ;; `score' is not a proper mark
 ;; `bookmark': don't propagated it, or fix the bug in update-mark.
 (defconst gnus-article-unpropagated-mark-lists
-  '(seen cache download unsend score bookmark)
+  '(seen cache download unsend score bookmark unexist)
   "Marks that shouldn't be propagated to back ends.
 Typical marks are those that make no sense in a standalone back end,
 such as a mark that says whether an article is stored in the cache
   "Marks that shouldn't be propagated to back ends.
 Typical marks are those that make no sense in a standalone back end,
 such as a mark that says whether an article is stored in the cache
@@ -2670,7 +2676,6 @@ such as a mark that says whether an article is stored in the cache
     (gnus-tree-mode "(gnus)Tree Display"))
   "Alist of major modes and related Info nodes.")
 
     (gnus-tree-mode "(gnus)Tree Display"))
   "Alist of major modes and related Info nodes.")
 
-(defvar gnus-group-buffer "*Group*")
 (defvar gnus-summary-buffer "*Summary*")
 (defvar gnus-article-buffer "*Article*")
 (defvar gnus-server-buffer "*Server*")
 (defvar gnus-summary-buffer "*Summary*")
 (defvar gnus-article-buffer "*Article*")
 (defvar gnus-server-buffer "*Server*")
@@ -2686,7 +2691,10 @@ such as a mark that says whether an article is stored in the cache
                        gnus-newsrc-last-checked-date
                        gnus-newsrc-alist gnus-server-alist
                        gnus-killed-list gnus-zombie-list
                        gnus-newsrc-last-checked-date
                        gnus-newsrc-alist gnus-server-alist
                        gnus-killed-list gnus-zombie-list
-                       gnus-topic-topology gnus-topic-alist)
+                       gnus-topic-topology gnus-topic-alist
+                       gnus-cloud-sequence
+                       gnus-cloud-covered-servers
+                       gnus-cloud-file-timestamps)
   "Gnus variables saved in the quick startup file.")
 
 (defvar gnus-newsrc-alist nil
   "Gnus variables saved in the quick startup file.")
 
 (defvar gnus-newsrc-alist nil
@@ -2799,6 +2807,8 @@ gnus-registry.el will populate this if it's loaded.")
      ("gnus-kill" gnus-kill gnus-apply-kill-file-internal
       gnus-kill-file-edit-file gnus-kill-file-raise-followups-to-author
       gnus-execute gnus-expunge gnus-batch-kill gnus-batch-score)
      ("gnus-kill" gnus-kill gnus-apply-kill-file-internal
       gnus-kill-file-edit-file gnus-kill-file-raise-followups-to-author
       gnus-execute gnus-expunge gnus-batch-kill gnus-batch-score)
+     ("gnus-registry" gnus-try-warping-via-registry
+      gnus-registry-handle-action)
      ("gnus-cache" gnus-cache-possibly-enter-article gnus-cache-save-buffers
       gnus-cache-possibly-remove-articles gnus-cache-request-article
       gnus-cache-retrieve-headers gnus-cache-possibly-alter-active
      ("gnus-cache" gnus-cache-possibly-enter-article gnus-cache-save-buffers
       gnus-cache-possibly-remove-articles gnus-cache-request-article
       gnus-cache-retrieve-headers gnus-cache-possibly-alter-active
@@ -2988,7 +2998,7 @@ with some simple extensions.
             summary just like information from any other summary
             specifier.
 &user-date; Age sensitive date format. Various date format is
             summary just like information from any other summary
             specifier.
 &user-date; Age sensitive date format. Various date format is
-            defined in `gnus-summary-user-date-format-alist'.
+            defined in `gnus-user-date-format-alist'.
 
 
 The %U (status), %R (replied) and %z (zcore) specs have to be handled
 
 
 The %U (status), %R (replied) and %z (zcore) specs have to be handled
@@ -3015,7 +3025,7 @@ See Info node `(gnus)Formatting Variables'."
 
 (defun gnus-suppress-keymap (keymap)
   (suppress-keymap keymap)
 
 (defun gnus-suppress-keymap (keymap)
   (suppress-keymap keymap)
-  (let ((keys `([backspace] [delete] "\177" "\M-u"))) ;gnus-mouse-2
+  (let ((keys `([delete] "\177" "\M-u"))) ;gnus-mouse-2
     (while keys
       (define-key keymap (pop keys) 'undefined))))
 
     (while keys
       (define-key keymap (pop keys) 'undefined))))
 
@@ -3227,9 +3237,9 @@ If ARG, insert string at point."
                    0))
       (string-to-number
        (if (zerop major)
                    0))
       (string-to-number
        (if (zerop major)
-            (format "%s00%02d%02d"
+            (format "%1.2f00%02d%02d"
                     (if (member alpha '("(ding)" "d"))
                     (if (member alpha '("(ding)" "d"))
-                        "4.99"
+                        4.99
                       (+ 5 (* 0.02
                               (abs
                                (- (mm-char-int (aref (downcase alpha) 0))
                       (+ 5 (* 0.02
                               (abs
                                (- (mm-char-int (aref (downcase alpha) 0))
@@ -3405,15 +3415,6 @@ that that variable is buffer-local to the summary buffers."
        (t                              ;Has positive number
         (eq (gnus-request-type group article) 'news)))) ;use it.
 
        (t                              ;Has positive number
         (eq (gnus-request-type group article) 'news)))) ;use it.
 
-;; Returns a list of writable groups.
-(defun gnus-writable-groups ()
-  (let ((alist gnus-newsrc-alist)
-       groups group)
-    (while (setq group (car (pop alist)))
-      (unless (gnus-group-read-only-p group)
-       (push group groups)))
-    (nreverse groups)))
-
 ;; Check whether to use long file names.
 (defun gnus-use-long-file-name (symbol)
   ;; The variable has to be set...
 ;; Check whether to use long file names.
 (defun gnus-use-long-file-name (symbol)
   ;; The variable has to be set...
@@ -3582,13 +3583,6 @@ that that variable is buffer-local to the summary buffers."
                                            gnus-valid-select-methods)))
                 (equal (nth 1 m1) (nth 1 m2)))))))
 
                                            gnus-valid-select-methods)))
                 (equal (nth 1 m1) (nth 1 m2)))))))
 
-(defun gnus-method-ephemeral-p (method)
-  (let ((equal nil))
-    (dolist (ephemeral gnus-ephemeral-servers)
-      (when (gnus-sloppily-equal-method-parameters method ephemeral)
-       (setq equal t)))
-    equal))
-
 (defsubst gnus-sloppily-equal-method-parameters (m1 m2)
   ;; Check parameters for sloppy equality.
   (let ((p1 (copy-sequence (cddr m1)))
 (defsubst gnus-sloppily-equal-method-parameters (m1 m2)
   ;; Check parameters for sloppy equality.
   (let ((p1 (copy-sequence (cddr m1)))
@@ -3617,6 +3611,13 @@ that that variable is buffer-local to the summary buffers."
       ;; If p2 now is empty, they were equal.
       (null p2))))
 
       ;; If p2 now is empty, they were equal.
       (null p2))))
 
+(defun gnus-method-ephemeral-p (method)
+  (let ((equal nil))
+    (dolist (ephemeral gnus-ephemeral-servers)
+      (when (gnus-sloppily-equal-method-parameters method ephemeral)
+       (setq equal t)))
+    equal))
+
 (defun gnus-methods-sloppily-equal (m1 m2)
   ;; Same method.
   (or
 (defun gnus-methods-sloppily-equal (m1 m2)
   ;; Same method.
   (or
@@ -3689,21 +3690,10 @@ server is native)."
       group
     (concat (gnus-method-to-server-name method) ":" group)))
 
       group
     (concat (gnus-method-to-server-name method) ":" group)))
 
-(defun gnus-group-guess-prefixed-name (group)
-  "Guess the whole name from GROUP and METHOD."
-  (gnus-group-prefixed-name group (gnus-find-method-for-group
-                              group)))
-
 (defun gnus-group-full-name (group method)
   "Return the full name from GROUP and METHOD, even if the method is native."
   (gnus-group-prefixed-name group method t))
 
 (defun gnus-group-full-name (group method)
   "Return the full name from GROUP and METHOD, even if the method is native."
   (gnus-group-prefixed-name group method t))
 
-(defun gnus-group-guess-full-name (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-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)
 (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)
@@ -3836,12 +3826,28 @@ You should probably use `gnus-find-method-for-group' instead."
   "Go through PARAMETERS and expand them according to the match data."
   (let (new)
     (dolist (elem parameters)
   "Go through PARAMETERS and expand them according to the match data."
   (let (new)
     (dolist (elem parameters)
-      (if (and (stringp (cdr elem))
-              (string-match "\\\\[0-9&]" (cdr elem)))
-         (push (cons (car elem)
-                     (gnus-expand-group-parameter match (cdr elem) group))
-               new)
-       (push elem new)))
+      (cond
+       ((and (stringp (cdr elem))
+             (string-match "\\\\[0-9&]" (cdr elem)))
+        (push (cons (car elem)
+                    (gnus-expand-group-parameter match (cdr elem) group))
+              new))
+       ;; For `sieve' group parameters, perform substitutions for every
+       ;; string within the match rule.  This allows for parameters such
+       ;; as:
+       ;;  ("list\\.\\(.*\\)"
+       ;;   (sieve header :is "list-id" "<\\1.domain.org>"))
+       ((eq 'sieve (car elem))
+        (push (mapcar (lambda (sieve-elem)
+                        (if (and (stringp sieve-elem)
+                                 (string-match "\\\\[0-9&]" sieve-elem))
+                            (gnus-expand-group-parameter match sieve-elem
+                                                         group)
+                          sieve-elem))
+                      (cdr elem))
+              new))
+       (t
+       (push elem new))))
     new))
 
 (defun gnus-group-fast-parameter (group symbol &optional allow-list)
     new))
 
 (defun gnus-group-fast-parameter (group symbol &optional allow-list)
@@ -3873,9 +3879,20 @@ The function `gnus-group-find-parameter' will do that for you."
              (when this-result
                (setq result (car this-result))
                ;; Expand if necessary.
              (when this-result
                (setq result (car this-result))
                ;; Expand if necessary.
-               (if (and (stringp result) (string-match "\\\\[0-9&]" result))
-                   (setq result (gnus-expand-group-parameter
-                                 (car head) result group)))))))
+               (cond
+                 ((and (stringp result) (string-match "\\\\[0-9&]" result))
+                  (setq result (gnus-expand-group-parameter
+                                (car head) result group)))
+                 ;; For `sieve' group parameters, perform substitutions
+                 ;; for every string within the match rule (see above).
+                 ((eq symbol 'sieve)
+                  (setq result
+                        (mapcar (lambda (elem)
+                                  (if (stringp elem)
+                                      (gnus-expand-group-parameter (car head)
+                                                                   elem group)
+                                    elem))
+                                result))))))))
        ;; Done.
        result))))
 
        ;; Done.
        result))))
 
@@ -4124,12 +4141,17 @@ parameters."
   (if (or (not (inline (gnus-similar-server-opened method)))
          (not (cddr method)))
       method
   (if (or (not (inline (gnus-similar-server-opened method)))
          (not (cddr method)))
       method
-    (setq method
-         `(,(car method) ,(concat (cadr method) "+" group)
-           (,(intern (format "%s-address" (car method))) ,(cadr method))
-           ,@(cddr method)))
-    (push method gnus-extended-servers)
-    method))
+    (let ((address-slot
+          (intern (format "%s-address" (car method)))))
+      (setq method
+           (if (assq address-slot (cddr method))
+               `(,(car method) ,(concat (cadr method) "+" group)
+                 ,@(cddr method))
+             `(,(car method) ,(concat (cadr method) "+" group)
+               (,address-slot ,(cadr method))
+               ,@(cddr method))))
+      (push method gnus-extended-servers)
+      method)))
 
 (defun gnus-server-status (method)
   "Return the status of METHOD."
 
 (defun gnus-server-status (method)
   "Return the status of METHOD."
@@ -4213,8 +4235,7 @@ parameters."
       (setq valids (cdr valids)))
     outs))
 
       (setq valids (cdr valids)))
     outs))
 
-(eval-and-compile
-  (autoload 'message-y-or-n-p "message" nil nil 'macro))
+(autoload 'message-y-or-n-p "message" nil nil 'macro)
 
 (defun gnus-read-group (prompt &optional default)
   "Prompt the user for a group name.
 
 (defun gnus-read-group (prompt &optional default)
   "Prompt the user for a group name.
@@ -4328,13 +4349,22 @@ server."
   (interactive "P")
   (gnus arg nil 'slave))
 
   (interactive "P")
   (gnus arg nil 'slave))
 
+(defun gnus-delete-gnus-frame ()
+  "Delete gnus frame unless it is the only one.
+Used for `gnus-exit-gnus-hook' in `gnus-other-frame'."
+  (when (and (frame-live-p gnus-other-frame-object)
+             (cdr (frame-list)))
+    (delete-frame gnus-other-frame-object))
+  (setq gnus-other-frame-object nil))
+
 ;;;###autoload
 (defun gnus-other-frame (&optional arg display)
   "Pop up a frame to read news.
 This will call one of the Gnus commands which is specified by the user
 option `gnus-other-frame-function' (default `gnus') with the argument
 ;;;###autoload
 (defun gnus-other-frame (&optional arg display)
   "Pop up a frame to read news.
 This will call one of the Gnus commands which is specified by the user
 option `gnus-other-frame-function' (default `gnus') with the argument
-ARG if Gnus is not running, otherwise just pop up a Gnus frame.  The
-optional second argument DISPLAY should be a standard display string
+ARG if Gnus is not running, otherwise pop up a Gnus frame and run the
+command specified by `gnus-other-frame-resume-function'.
+The optional second argument DISPLAY should be a standard display string
 such as \"unix:0\" to specify where to pop up a frame.  If DISPLAY is
 omitted or the function `make-frame-on-display' is not available, the
 current display is used."
 such as \"unix:0\" to specify where to pop up a frame.  If DISPLAY is
 omitted or the function `make-frame-on-display' is not available, the
 current display is used."
@@ -4366,14 +4396,16 @@ current display is used."
                 (make-frame-on-display display gnus-other-frame-parameters)
               (make-frame gnus-other-frame-parameters))))
       (if alive
                 (make-frame-on-display display gnus-other-frame-parameters)
               (make-frame gnus-other-frame-parameters))))
       (if alive
-         (switch-to-buffer gnus-group-buffer)
+         (progn (switch-to-buffer gnus-group-buffer)
+                (funcall gnus-other-frame-resume-function arg))
        (funcall gnus-other-frame-function arg)
        (funcall gnus-other-frame-function arg)
-       (add-hook 'gnus-exit-gnus-hook
-                 (lambda nil
-                    (when (and (frame-live-p gnus-other-frame-object)
-                               (cdr (frame-list)))
-                      (delete-frame gnus-other-frame-object))
-                    (setq gnus-other-frame-object nil)))))))
+       (add-hook 'gnus-exit-gnus-hook 'gnus-delete-gnus-frame)
+  ;; One might argue that `gnus-delete-gnus-frame' should not be called
+  ;; from `gnus-suspend-gnus-hook', but, on the other hand, one might
+  ;; argue that it should.  No matter what you think, for the sake of
+  ;; those who want it to be called from it, please keep (defun
+  ;; gnus-delete-gnus-frame) even if you remove the next `add-hook'.
+  (add-hook 'gnus-suspend-gnus-hook 'gnus-delete-gnus-frame)))))
 
 ;;;###autoload
 (defun gnus (&optional arg dont-connect slave)
 
 ;;;###autoload
 (defun gnus (&optional arg dont-connect slave)
@@ -4393,10 +4425,13 @@ prompt the user for the name of an NNTP server to use."
     (gnus-1 arg dont-connect slave)
     (gnus-final-warning)))
 
     (gnus-1 arg dont-connect slave)
     (gnus-final-warning)))
 
-(autoload 'debbugs-gnu "debbugs-gnu")
+(declare-function debbugs-gnu "ext:debbugs-gnu"
+                 (severities &optional packages archivedp suppress tags))
+
 (defun gnus-list-debbugs ()
   "List all open Gnus bug reports."
   (interactive)
 (defun gnus-list-debbugs ()
   "List all open Gnus bug reports."
   (interactive)
+  (require 'debbugs-gnu)
   (debbugs-gnu nil "gnus"))
 
 ;; Allow redefinition of Gnus functions.
   (debbugs-gnu nil "gnus"))
 
 ;; Allow redefinition of Gnus functions.