*** empty log message ***
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 07:52:01 +0000 (07:52 +0000)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 07:52:01 +0000 (07:52 +0000)
lisp/ChangeLog
lisp/gnus-msg.el
lisp/gnus-salt.el
lisp/gnus-score.el
lisp/gnus-srvr.el
lisp/gnus-vis.el
lisp/gnus.el
lisp/nnmail.el
lisp/nnsoup.el
lisp/nntp.el
texi/gnus.texi

index be5218b..774420e 100644 (file)
@@ -1,5 +1,71 @@
+Tue Feb 27 03:49:45 1996  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * gnus-vis.el (gnus-article-highlight-signature): Use a marker for
+       the signature.
+
+Tue Feb 27 01:29:53 1996  Lars Magne Ingebrigtsen  <larsi@hler.ifi.uio.no>
+
+       * gnus-msg.el (gnus-inews-article): Always check all headers.
+       (gnus-mail-reply): Use the Gnus-Warning Message-ID, if possible.
+       (gnus-news-followup): Ditto.
+
+       * gnus.el (gnus-summary-hide-thread): Would infloop on article
+       with no ":".
+
+       * gnus-msg.el (gnus-mail-send-and-exit): Make sure we're in the
+       right buffer.
+
+Mon Feb 26 01:57:17 1996  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus-srvr.el (gnus-server-prepare): Do more checking for nil
+       methods. 
+
+       * nnsoup.el (nnsoup-request-expire-articles): Better message.
+
+       * gnus-salt.el (gnus-generate-horizontal-tree): Use <> brackets on
+       adopted articles.
+
+       * gnus-msg.el (gnus-inews-news): Don't allow posting when Gnus is
+       dead. 
+
+       * gnus.el (gnus-alive-p): New function.
+
+       * gnus-msg.el (gnus-inews-modify-mail-mode-map): Use new macro;
+       moved `C-c C-k' to `C-c C-q'.
+       (gnus-kill-message-buffer): Return to the buffer from whence we
+       came. 
+
+       * gnus.el (gnus-created-frames): New variable.
+       (gnus-clear-system): Remove created frames.
+       (gnus-local-set-keys): New macro.
+
+       * gnus-msg.el (gnus-inews-cleanup-headers): Remove empty lines.
+       (gnus-inews-check-post): Warn about empty headers.
+       (gnus-check-before-posting): New default.
+
+       * nnmail.el (nnmail-search-unix-mail-delim): New function.
+       (nnmail-process-unix-mail-format): Use it.
+
+       * nntp.el (nntp-open-server): Clear the nntp-server-buffer after
+       opening a connection.
+       (nntp-request-quit): Removed.
+       (nntp-request-group): Change server.
+       (nntp-kill-command): New function.
+       (nntp-send-command): Use it.
+       (nntp-command-timeout): New variable.
+       (nntp-send-command): Retry commands if `C-g'.
+
+       * gnus.el (gnus-summary-mark-read-and-unread-as-read): Changed
+       name. 
+
+       * nntp.el (nntp-open-server-semi-internal): Better messages.
+
+       * gnus-msg.el (gnus-debug): Did `quote' wrong.
+
 Sun Feb 25 01:37:49 1996  Lars Magne Ingebrigtsen  <larsi@ylfing.ifi.uio.no>
 
+       * gnus.el: 0.43 is released.
+
        * gnus-topic.el (gnus-topic-prepare-topic): Would bug out on dead
        groups. 
        (gnus-topic-grok-active): Read the active file if it hasn't been
index cb8952b..11da43e 100644 (file)
@@ -256,7 +256,8 @@ The function will only be called if you have the `Distribution' header in
 (defvar gnus-check-before-posting 
   '(subject-cmsg multiple-headers sendsys message-id from
                 long-lines control-chars size new-text
-                redirected-followup signature approved sender empty)
+                redirected-followup signature approved sender 
+                empty empty-headers)
   "In non-nil, Gnus will attempt to run some checks on outgoing posts.
 If this variable is t, Gnus will check everything it can.  If it is a
 list, then those elements in that list will be checked.")
@@ -644,6 +645,8 @@ function will attempt to use the foreign server to post the article.
 If given an zero prefix, the user will be prompted for a posting
 method to use."
   (interactive "P")
+  (unless (gnus-alive-p)
+    (error "Gnus is dead; you can't post anything."))
   (or gnus-current-select-method
       (setq gnus-current-select-method gnus-select-method))
   (let* ((case-fold-search nil)
@@ -798,14 +801,7 @@ called."
     ;; We narrow to the headers and check them first.
     (save-excursion
       (save-restriction
-       (goto-char (point-min))
-       (narrow-to-region 
-        (point) 
-        (progn
-          (re-search-forward 
-           (concat "^" (regexp-quote mail-header-separator) "$"))
-          (match-beginning 0)))
-       (goto-char (point-min))
+       (gnus-inews-narrow-to-headers)
        (and 
         ;; Check for commands in Subject.
         (or 
@@ -819,8 +815,8 @@ called."
         (or (gnus-check-before-posting 'multiple-headers)
             (save-excursion
               (let (found)
-                (while (and (not found) (re-search-forward "^[^ \t:]+: "
-                                                           nil t))
+                (while (and (not found) 
+                            (re-search-forward "^[^ \t:]+: " nil t))
                   (save-excursion
                     (or (re-search-forward 
                          (concat "^" (setq found
@@ -878,6 +874,20 @@ called."
                      (format 
                       "The Message-ID looks strange: \"%s\". Really post? "
                       message-id))))))
+        ;; Check whether any headers are empty.
+        (or (gnus-check-before-posting 'empty-headers)
+            (save-excursion
+              (let ((post t))
+                (goto-char (point-min))
+                (while (and post (not (eobp)))
+                  (when (looking-at "\\([^ :]+\\):[ \t]\n[^ \t]")
+                    (setq post
+                          (gnus-y-or-n-p
+                           (format
+                            "The %s header is empty.  Really post? "
+                            (match-string 1)))))
+                  (forward-line 1))
+                post)))
         ;; Check the From header.
         (or 
          (gnus-check-before-posting 'from)
@@ -1110,8 +1120,7 @@ This function can be used in `mail-citation-hook', for instance."
       (setq gcc (mail-fetch-field "gcc"))
       (widen))
     ;; Check whether the article is a good Net Citizen.
-    (if (and gnus-article-check-size
-            (not (gnus-inews-check-post)))
+    (if (not (gnus-inews-check-post))
        ;; Aber nein!
        'illegal
       ;; We fudge a hook for nnspool.
@@ -1165,6 +1174,12 @@ This function can be used in `mail-citation-hook', for instance."
       result)))
 
 (defun gnus-inews-cleanup-headers ()
+  ;; Remove empty lines in the header.
+  (save-restriction
+    (gnus-inews-narrow-to-headers)
+    (while (re-search-forward "^[ \t]*\n" nil t)
+      (replace-match "" t t)))
+
   ;; Correct newsgroups field: change sequence of spaces to comma and 
   ;; eliminate spaces around commas.  Eliminate imbedded line breaks.
   (goto-char (point-min))
@@ -1821,7 +1836,7 @@ mailer."
          (winconf (current-window-configuration))
          from subject date reply-to message-of to cc
          references message-id sender follow-to sendto elt new-cc new-to
-         mct mctdo)
+         mct mctdo gnus-warning)
       (set-buffer (get-buffer-create gnus-mail-buffer))
       (mail-mode)
       (if (and (buffer-modified-p)
@@ -1863,6 +1878,9 @@ mailer."
                    (mail-fetch-field "reply-to")))
            (setq references (mail-fetch-field "references"))
            (setq message-id (mail-fetch-field "message-id"))
+           (when (and (setq gnus-warning (mail-fetch-field "gnus-warning"))
+                      (string-match "<[^>]+>" gnus-warning))
+             (setq message-id (match-string 0 gnus-warning)))
            
            (setq mctdo (not (equal mct "never")))
 
@@ -2079,7 +2097,7 @@ If INHIBIT-PROMPT, never prompt for a Subject."
            (winconf (current-window-configuration))
            from subject date reply-to message-of
            references message-id sender follow-to sendto elt 
-           followup-to distribution newsgroups)
+           followup-to distribution newsgroups gnus-warning)
        (set-buffer (get-buffer-create gnus-post-news-buffer))
        (news-reply-mode)
        ;; Associate this buffer with the draft group.
@@ -2111,6 +2129,9 @@ If INHIBIT-PROMPT, never prompt for a Subject."
              (setq subject (concat "Re: " subject))
              (setq references (mail-fetch-field "references"))
              (setq message-id (mail-fetch-field "message-id"))
+             (when (and (setq gnus-warning (mail-fetch-field "gnus-warning"))
+                        (string-match "<[^>]+>" gnus-warning))
+               (setq message-id (match-string 0 gnus-warning)))
              (setq followup-to (mail-fetch-field "followup-to"))
              (setq newsgroups (mail-fetch-field "newsgroups"))
              (setq distribution (mail-fetch-field "distribution"))
@@ -2292,27 +2313,27 @@ If INHIBIT-PROMPT, never prompt for a Subject."
     (let ((buffer-file-name nil))
       (or dont-send (gnus-mail-send)))
     (bury-buffer)
-    ;; This mail group doesn't have a `to-list', so we add one
-    ;; here.  Magic!  
-    (and to-address
-        (gnus-group-add-parameter 
-         address-group (cons 'to-list to-address)))
-    (if (get-buffer gnus-group-buffer)
-       (progn
-         (if (gnus-buffer-exists-p (car-safe reply))
-             (progn
-               (set-buffer (car reply))
-               (and (cdr reply)
-                    (gnus-summary-mark-article-as-replied 
-                     (cdr reply)))))
-         (and winconf (set-window-configuration winconf))))))
+    (when (gnus-alive-p)
+      ;; This mail group doesn't have a `to-list', so we add one
+      ;; here.  Magic!  
+      (when to-address
+       (gnus-group-add-parameter address-group (cons 'to-list to-address)))
+      (when (and (gnus-buffer-exists-p (car reply))
+                (cdr reply))
+       (save-excursion
+         (set-buffer (car reply))
+         (gnus-summary-mark-article-as-replied (cdr reply))))
+      (and winconf (set-window-configuration winconf)))))
 
 (defun gnus-kill-message-buffer ()
   "Kill the current buffer after dissociating it from the draft group."
   (interactive)
   (when (gnus-y-or-n-p "Dissociate and kill the current buffer? ")
     (gnus-dissociate-buffer-from-draft)
-    (kill-buffer (current-buffer))))
+    (let ((winconf gnus-prev-winconf))
+      (kill-buffer (current-buffer))
+      (when winconf 
+       (set-window-configuration winconf)))))
 
 (defun gnus-put-message ()
   "Put the current message in some group and return to Gnus."
@@ -2540,7 +2561,7 @@ The source file has to be in the Emacs load path."
                            (and (symbolp sym)
                                 (not (or (eq sym nil)
                                          (eq sym t)))))
-                       (cons 'quote (symbol-value (car olist)))
+                       (list 'quote (symbol-value (car olist)))
                      (symbol-value (car olist)))
                   "\n")))
        (insert ";; (makeunbound '" (symbol-name (car olist)) ")\n"))
@@ -2631,11 +2652,12 @@ Headers will be generated before sending."
 
 (defun gnus-inews-modify-mail-mode-map ()
   (use-local-map (copy-keymap (current-local-map)))
-  (local-set-key "\C-c\C-c" 'gnus-mail-send-and-exit)
-  (local-set-key "\C-c\M-\C-p" 'gnus-put-message)
-  (local-set-key "\C-c\C-k" 'gnus-kill-message-buffer)
-  (local-set-key "\C-c\M-d" 'gnus-dissociate-buffer-from-draft)
-  (local-set-key "\C-c\C-d" 'gnus-associate-buffer-with-draft))
+  (gnus-local-set-keys
+   "\C-c\C-c" gnus-mail-send-and-exit
+   "\C-c\M-\C-p" gnus-put-message
+   "\C-c\C-q" gnus-kill-message-buffer
+   "\C-c\M-d" gnus-dissociate-buffer-from-draft
+   "\C-c\C-d" gnus-associate-buffer-with-draft))
 
 (defun gnus-mail-setup (type &optional to subject in-reply-to cc
                             replybuffer actions)
@@ -2889,7 +2911,7 @@ Headers will be generated before sending."
       (insert mail-header-separator)
       ;; Configure windows.
       (let ((gnus-draft-buffer (current-buffer)))
-       (gnus-configure-windows 'draft)
+       (gnus-configure-windows 'draft t)
        (goto-char (point))))))
   
 (defun gnus-configure-posting-styles ()
index 1b967f7..1dc2ba9 100644 (file)
@@ -196,7 +196,8 @@ lines.")
 (defvar gnus-selected-tree-face 'modeline
   "*Face used for highlighting selected articles in the thread tree.")
 
-(defvar gnus-tree-brackets '((?\[ . ?\]) (?\( . ?\)) (?\{ . ?\}))
+(defvar gnus-tree-brackets '((?\[ . ?\]) (?\( . ?\))
+                            (?\{ . ?\}) (?< . ?>))
   "Brackets used in tree nodes.")
 
 (defvar gnus-tree-parent-child-edges '(?- ?\\ ?|)
@@ -374,7 +375,7 @@ Two predefined functions are available:
 
 ;;; Generating the tree.
 
-(defun gnus-tree-node-insert (header sparse)
+(defun gnus-tree-node-insert (header sparse &optional adopted)
   (let* ((dummy (stringp header))
         (header (if (vectorp header) header
                   (progn
@@ -404,10 +405,12 @@ Two predefined functions are available:
          (cond ((memq gnus-tmp-number sparse) 
                 (caadr gnus-tree-brackets))
                (dummy (caaddr gnus-tree-brackets))
+               (adopted (car (nth 3 gnus-tree-brackets)))
                (t (caar gnus-tree-brackets))))
         (gnus-tmp-close-bracket
          (cond ((memq gnus-tmp-number sparse)
                 (cdadr gnus-tree-brackets))
+               (adopted (cdr (nth 3 gnus-tree-brackets)))
                (dummy
                 (cdaddr gnus-tree-brackets))
                (t (cdar gnus-tree-brackets))))
@@ -464,7 +467,7 @@ Two predefined functions are available:
          (gnus-horizontal-recenter)
          (select-window selected))))))
 
-(defun gnus-generate-horizontal-tree (thread level &optional dummyp)
+(defun gnus-generate-horizontal-tree (thread level &optional dummyp adopted)
   "Generate a horizontal tree."
   (let* ((dummy (stringp (car thread)))
         (do (or dummy
@@ -491,7 +494,7 @@ Two predefined functions are available:
          (goto-char beg)))
       (setq dummyp nil)
       ;; Insert the article node.
-      (gnus-tree-node-insert (pop thread) gnus-tmp-sparse))
+      (gnus-tree-node-insert (pop thread) gnus-tmp-sparse adopted))
     (if (null thread)
        ;; End of the thread, so we go to the next line.
        (unless (bolp)
@@ -500,7 +503,7 @@ Two predefined functions are available:
       (while thread
        (gnus-generate-horizontal-tree
         (pop thread) (if do (1+ level) level) 
-        (or dummyp dummy))))))
+        (or dummyp dummy) dummy)))))
 
 (defsubst gnus-tree-indent-vertical ()
   (let ((len (- (* (1+ gnus-tree-node-length) gnus-tmp-indent) 
@@ -515,7 +518,7 @@ Two predefined functions are available:
       (insert "\n")))
   (end-of-line))
 
-(defun gnus-generate-vertical-tree (thread level &optional dummyp)
+(defun gnus-generate-vertical-tree (thread level &optional dummyp adopted)
   "Generate a vertical tree."
   (let* ((dummy (stringp (car thread)))
         (do (or dummy
@@ -549,7 +552,7 @@ Two predefined functions are available:
       (setq dummyp nil)
       ;; Insert the article node.
       (gnus-tree-indent-vertical)
-      (gnus-tree-node-insert (pop thread) gnus-tmp-sparse)
+      (gnus-tree-node-insert (pop thread) gnus-tmp-sparse adopted)
       (gnus-tree-forward-line 1))
     (if (null thread)
        ;; End of the thread, so we go to the next line.
@@ -561,7 +564,7 @@ Two predefined functions are available:
       (while thread
        (gnus-generate-vertical-tree
         (pop thread) (if do (1+ level) level) 
-        (or dummyp dummy))))))
+        (or dummyp dummy) dummy)))))
 
 ;;; Interface functions.
 
@@ -629,7 +632,6 @@ Two predefined functions are available:
        (set-window-point 
         (get-buffer-window (current-buffer) t) (cdr region))))))
 
-
 ;;; Allow redefinition of functions.
 (gnus-ems-redefine)
 
index 61fb248..7994e4a 100644 (file)
@@ -1391,8 +1391,10 @@ SCORE is the score to add."
     ;; this function makes will be put into this file.
     (save-excursion
       (set-buffer gnus-summary-buffer)
-      (gnus-score-load-file (gnus-score-file-name 
-                            gnus-newsgroup-name gnus-adaptive-file-suffix)))
+      (gnus-score-load-file
+       (or gnus-newsgroup-adaptive-score-file
+          (gnus-score-file-name 
+           gnus-newsgroup-name gnus-adaptive-file-suffix))))
 
     (setq gnus-scores-articles (sort gnus-scores-articles 'gnus-score-string<)
          articles gnus-scores-articles)
@@ -2089,7 +2091,8 @@ GROUP using BNews sys file syntax."
 
 (defun gnus-score-find-single (group)
   "Return list containing the score file for GROUP."
-  (list (gnus-score-file-name group gnus-adaptive-file-suffix)
+  (list (or gnus-newsgroup-adaptive-score-file
+           (gnus-score-file-name group gnus-adaptive-file-suffix))
        (gnus-score-file-name group)))
 
 (defun gnus-score-find-hierarchical (group)
index d5c3152..e8db063 100644 (file)
@@ -194,7 +194,7 @@ The following commands are available:
     ;; First we do the real list of servers.
     (while alist
       (push (cdr (setq server (pop alist))) done)
-      (when (and server (car server))
+      (when (and server (car server) (cdr server))
        (gnus-server-insert-server-line (car server) (cdr server))))
     ;; Then we insert the list of servers that have been opened in
     ;; this session.
index bcf4975..d5d15e9 100644 (file)
@@ -1323,7 +1323,7 @@ It does this by highlighting everything after
          (widen)
          (re-search-backward gnus-signature-separator nil t)
          (let ((start (match-beginning 0))
-               (end (match-end 0)))
+               (end (set-marker (make-marker) (match-end 0))))
            (gnus-article-add-button start end 'gnus-signature-toggle
                                     end)))))))
 
@@ -1422,25 +1422,18 @@ specified by `gnus-button-alist'."
 (defun gnus-signature-toggle (end)
   (save-excursion
     (set-buffer gnus-article-buffer)
-    (let ((buffer-read-only nil))
+    (let ((buffer-read-only nil)
+         (inhibit-point-motion-hooks t))
       (if (get-text-property end 'invisible)
          (remove-text-properties end (point-max) gnus-hidden-properties)
        (add-text-properties end (point-max) gnus-hidden-properties)))))
 
-;see gnus-cus.el
-;(defun gnus-make-face (color)
-;  ;; Create entry for face with COLOR.
-;  (if gnus-make-foreground
-;      (custom-face-lookup color nil nil nil nil nil)
-;    (custom-face-lookup nil color nil nil nil nil)))
-
 (defun gnus-button-entry ()
   ;; Return the first entry in `gnus-button-alist' matching this place.
   (let ((alist gnus-button-alist)
        (entry nil))
     (while alist
-      (setq entry (car alist)
-           alist (cdr alist))
+      (setq entry (pop alist))
       (if (looking-at (car entry))
          (setq alist nil)
        (setq entry nil)))
index 2aa87c9..80c86c7 100644 (file)
@@ -1523,7 +1523,7 @@ It is called with three parameters -- GROUP, LEVEL and OLDLEVEL.")
            (remove-hook 'gnus-summary-prepare-hook
                         'hilit-rehighlight-buffer-quietly)
            (remove-hook 'gnus-summary-prepare-hook 'hilit-install-line-hooks)
-           (setq gnus-mark-article-hook '(gnus-summary-mark-unread-as-read))
+           (setq gnus-mark-article-hook '(gnus-summary-mark-read-and-unread-as-read))
            (remove-hook 'gnus-article-prepare-hook
                         'hilit-rehighlight-buffer-quietly)))
 
@@ -1557,6 +1557,7 @@ It is called with three parameters -- GROUP, LEVEL and OLDLEVEL.")
 (defvar gnus-inhibit-hiding nil)
 (defvar gnus-group-indentation "")
 (defvar gnus-inhibit-limiting nil)
+(defvar gnus-created-frames nil)
 
 (defvar gnus-article-mode-map nil)
 (defvar gnus-dribble-buffer nil)
@@ -1693,7 +1694,7 @@ variable (string, integer, character, etc).")
   "gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls + Boys)"
   "The mail address of the Gnus maintainers.")
 
-(defconst gnus-version "September Gnus v0.43"
+(defconst gnus-version "September Gnus v0.44"
   "Version number for this version of Gnus.")
 
 (defvar gnus-info-nodes
@@ -2163,6 +2164,11 @@ Thank you for your help in stamping out bugs.
        (point)
       (goto-char p))))
 
+(defun gnus-alive-p ()
+  "Say whether Gnus is running or not."
+  (and gnus-group-buffer
+       (get-buffer gnus-group-buffer)))
+
 ;; Delete the current line (and the next N lines.);
 (defmacro gnus-delete-line (&optional n)
   `(delete-region (progn (beginning-of-line) (point))
@@ -3085,13 +3091,15 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
        gnus-opened-servers nil
        gnus-current-select-method nil)
   ;; Reset any score variables.
-  (and gnus-use-scoring (gnus-score-close))
+  (when gnus-use-scoring 
+    (gnus-score-close))
   ;; Kill the startup file.
   (and gnus-current-startup-file
        (get-file-buffer gnus-current-startup-file)
        (kill-buffer (get-file-buffer gnus-current-startup-file)))
   ;; Save any cache buffers.
-  (and gnus-use-cache (gnus-cache-save-buffers))
+  (when gnus-use-cache 
+    (gnus-cache-save-buffers))
   ;; Clear the dribble buffer.
   (gnus-dribble-clear)
   ;; Close down NoCeM.
@@ -3101,27 +3109,34 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
   (when gnus-use-demon
     (gnus-demon-cancel))
   ;; Kill global KILL file buffer.
-  (if (get-file-buffer (gnus-newsgroup-kill-file nil))
-      (kill-buffer (get-file-buffer (gnus-newsgroup-kill-file nil))))
+  (when (get-file-buffer (gnus-newsgroup-kill-file nil))
+    (kill-buffer (get-file-buffer (gnus-newsgroup-kill-file nil))))
   (gnus-kill-buffer nntp-server-buffer)
   ;; Backlog.
-  (and gnus-keep-backlog (gnus-backlog-shutdown))
+  (when gnus-keep-backlog
+    (gnus-backlog-shutdown))
   ;; Kill Gnus buffers.
   (while gnus-buffer-list
-    (gnus-kill-buffer (car gnus-buffer-list))
-    (setq gnus-buffer-list (cdr gnus-buffer-list))))
+    (gnus-kill-buffer (pop gnus-buffer-list)))
+  ;; Remove Gnus frames.
+  (while gnus-created-frames
+    (when (frame-live-p (car gnus-created-frames))
+      ;; We slap a condition-case around this `delete-frame' to ensure 
+      ;; agains errors if we try do delete the single frame that's left.
+      (condition-case ()
+         (delete-frame (car gnus-created-frames))
+       (error nil)))
+    (pop gnus-created-frames)))
 
 (defun gnus-windows-old-to-new (setting)
   ;; First we take care of the really, really old Gnus 3 actions.
-  (if (symbolp setting)
-      (setq setting
-           (cond ((memq setting '(SelectArticle))
-                  'article)
-                 ((memq setting '(SelectSubject ExpandSubject))
-                  'summary)
-                 ((memq setting '(SelectNewsgroup ExitNewsgroup))
-                  'group)
-                 (t setting))))
+  (when (symbolp setting)
+    (setq setting
+         ;; Take care of ooold GNUS 3.x values.
+         (cond ((eq setting 'SelectArticle) 'article)
+               ((memq setting '(SelectSubject ExpandSubject)) 'summary)
+               ((memq setting '(SelectNewsgroup ExitNewsgroup)) 'group)
+               (t setting))))
   (if (or (listp setting)
          (not (and gnus-window-configuration
                    (memq setting '(group summary article)))))
@@ -3218,6 +3233,7 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
          ;; Create a new frame?
          (unless (setq frame (elt gnus-frame-list i))
            (nconc gnus-frame-list (list (setq frame (make-frame params)))))
+         (push frame gnus-created-frames)
          ;; Is the old frame still alive?
          (unless (frame-live-p frame)
            (setcar (nthcdr i gnus-frame-list)
@@ -3477,10 +3493,19 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
        (and (= (car fdate) (car date))
             (> (nth 1 fdate) (nth 1 date))))))
 
+(defmacro gnus-local-set-keys (&rest plist)
+  "Set the keys in PLIST in the current keymap."
+  `(gnus-define-keys-1 (current-local-map) ',plist))
+
 (defmacro gnus-define-keys (keymap &rest plist)
   "Define all keys in PLIST in KEYMAP."
   `(gnus-define-keys-1 (quote ,keymap) (quote ,plist)))
 
+(put 'gnus-define-keys 'lisp-indent-function 1)
+(put 'gnus-define-keys 'lisp-indent-hook 1)
+(put 'gnus-define-keymap 'lisp-indent-function 1)
+(put 'gnus-define-keymap 'lisp-indent-hook 1)
+
 (defmacro gnus-define-keymap (keymap &rest plist)
   "Define all keys in PLIST in KEYMAP."
   `(gnus-define-keys-1 ,keymap (quote ,plist)))
@@ -3931,149 +3956,140 @@ Note: LIST has to be sorted over `<'."
   (setq gnus-group-mode-map (make-keymap))
   (suppress-keymap gnus-group-mode-map)
 
-  (gnus-define-keys
-   gnus-group-mode-map
-   " " gnus-group-read-group
-   "=" gnus-group-select-group
-   "\M- " gnus-group-unhidden-select-group
-   "\r" gnus-group-select-group
-   "\M-\r" gnus-group-quick-select-group
-   "j" gnus-group-jump-to-group
-   "n" gnus-group-next-unread-group
-   "p" gnus-group-prev-unread-group
-   "\177" gnus-group-prev-unread-group
-   [delete] gnus-group-prev-unread-group
-   "N" gnus-group-next-group
-   "P" gnus-group-prev-group
-   "\M-n" gnus-group-next-unread-group-same-level
-   "\M-p" gnus-group-prev-unread-group-same-level
-   "," gnus-group-best-unread-group
-   "." gnus-group-first-unread-group
-   "u" gnus-group-unsubscribe-current-group
-   "U" gnus-group-unsubscribe-group
-   "c" gnus-group-catchup-current
-   "C" gnus-group-catchup-current-all
-   "l" gnus-group-list-groups
-   "L" gnus-group-list-all-groups
-   "m" gnus-group-mail
-   "g" gnus-group-get-new-news
-   "\M-g" gnus-group-get-new-news-this-group
-   "R" gnus-group-restart
-   "r" gnus-group-read-init-file
-   "B" gnus-group-browse-foreign-server
-   "b" gnus-group-check-bogus-groups
-   "F" gnus-find-new-newsgroups
-   "\C-c\C-d" gnus-group-describe-group
-   "\M-d" gnus-group-describe-all-groups
-   "\C-c\C-a" gnus-group-apropos
-   "\C-c\M-\C-a" gnus-group-description-apropos
-   "a" gnus-group-post-news
-   "\ek" gnus-group-edit-local-kill
-   "\eK" gnus-group-edit-global-kill
-   "\C-k" gnus-group-kill-group
-   "\C-y" gnus-group-yank-group
-   "\C-w" gnus-group-kill-region
-   "\C-x\C-t" gnus-group-transpose-groups
-   "\C-c\C-l" gnus-group-list-killed
-   "\C-c\C-x" gnus-group-expire-articles
-   "\C-c\M-\C-x" gnus-group-expire-all-groups
-   "V" gnus-version
-   "s" gnus-group-save-newsrc
-   "z" gnus-group-suspend
-   "Z" gnus-group-clear-dribble
-   "q" gnus-group-exit
-   "Q" gnus-group-quit
-   "?" gnus-group-describe-briefly
-   "\C-c\C-i" gnus-info-find-node
-   "\M-e" gnus-group-edit-group-method
-   "^" gnus-group-enter-server-mode
-   gnus-mouse-2 gnus-mouse-pick-group
-   "<" beginning-of-buffer
-   ">" end-of-buffer
-   "\C-c\C-b" gnus-bug
-   "\C-c\C-s" gnus-group-sort-groups
-   "t" gnus-topic-mode
-   "\C-c\M-g" gnus-activate-all-groups
-   "\M-&" gnus-group-universal-argument
-   "#" gnus-group-mark-group
-   "\M-#" gnus-group-unmark-group)
-
-  (gnus-define-keys
-   (gnus-group-mark-map "M" gnus-group-mode-map)
-   "m" gnus-group-mark-group
-   "u" gnus-group-unmark-group
-   "w" gnus-group-mark-region
-   "m" gnus-group-mark-buffer
-   "r" gnus-group-mark-regexp
-   "U" gnus-group-unmark-all-groups)
-
-  (gnus-define-keys
-   (gnus-group-group-map "G" gnus-group-mode-map)
-   "d" gnus-group-make-directory-group
-   "h" gnus-group-make-help-group
-   "a" gnus-group-make-archive-group
-   "k" gnus-group-make-kiboze-group
-   "m" gnus-group-make-group
-   "E" gnus-group-edit-group
-   "e" gnus-group-edit-group-method
-   "p" gnus-group-edit-group-parameters
-   "v" gnus-group-add-to-virtual
-   "V" gnus-group-make-empty-virtual
-   "D" gnus-group-enter-directory
-   "f" gnus-group-make-doc-group
-   "r" gnus-group-rename-group
-   "\177" gnus-group-delete-group
-   [delete] gnus-group-delete-group)
-
-   (gnus-define-keys
-    (gnus-group-soup-map "s" gnus-group-group-map)
-    "b" gnus-group-brew-soup
-    "w" gnus-soup-save-areas
-    "s" gnus-soup-send-replies
-    "p" gnus-soup-pack-packet
-    "r" nnsoup-pack-replies)
-
-   (gnus-define-keys
-    (gnus-group-sort-map "S" gnus-group-group-map)
-    "s" gnus-group-sort-groups
-    "a" gnus-group-sort-groups-by-alphabet
-    "u" gnus-group-sort-groups-by-unread
-    "l" gnus-group-sort-groups-by-level
-    "v" gnus-group-sort-groups-by-score
-    "r" gnus-group-sort-groups-by-rank
-    "m" gnus-group-sort-groups-by-method)
-
-   (gnus-define-keys
-    (gnus-group-list-map "A" gnus-group-mode-map)
-    "k" gnus-group-list-killed
-    "z" gnus-group-list-zombies
-    "s" gnus-group-list-groups
-    "u" gnus-group-list-all-groups
-    "A" gnus-group-list-active
-    "a" gnus-group-apropos
-    "d" gnus-group-description-apropos
-    "m" gnus-group-list-matching
-    "M" gnus-group-list-all-matching
-    "l" gnus-group-list-level)
-
-   (gnus-define-keys
-    (gnus-group-score-map "W" gnus-group-mode-map)
-    "f" gnus-score-flush-cache)
-
-   (gnus-define-keys
-    (gnus-group-help-map "H" gnus-group-mode-map)
-    "f" gnus-group-fetch-faq)
-
-   (gnus-define-keys
-    (gnus-group-sub-map "S" gnus-group-mode-map)
-    "l" gnus-group-set-current-level
-    "t" gnus-group-unsubscribe-current-group
-    "s" gnus-group-unsubscribe-group
-    "k" gnus-group-kill-group
-    "y" gnus-group-yank-group
-    "w" gnus-group-kill-region
-    "\C-k" gnus-group-kill-level
-    "z" gnus-group-kill-all-zombies))
+  (gnus-define-keys gnus-group-mode-map
+    " " gnus-group-read-group
+    "=" gnus-group-select-group
+    "\M- " gnus-group-unhidden-select-group
+    "\r" gnus-group-select-group
+    "\M-\r" gnus-group-quick-select-group
+    "j" gnus-group-jump-to-group
+    "n" gnus-group-next-unread-group
+    "p" gnus-group-prev-unread-group
+    "\177" gnus-group-prev-unread-group
+    [delete] gnus-group-prev-unread-group
+    "N" gnus-group-next-group
+    "P" gnus-group-prev-group
+    "\M-n" gnus-group-next-unread-group-same-level
+    "\M-p" gnus-group-prev-unread-group-same-level
+    "," gnus-group-best-unread-group
+    "." gnus-group-first-unread-group
+    "u" gnus-group-unsubscribe-current-group
+    "U" gnus-group-unsubscribe-group
+    "c" gnus-group-catchup-current
+    "C" gnus-group-catchup-current-all
+    "l" gnus-group-list-groups
+    "L" gnus-group-list-all-groups
+    "m" gnus-group-mail
+    "g" gnus-group-get-new-news
+    "\M-g" gnus-group-get-new-news-this-group
+    "R" gnus-group-restart
+    "r" gnus-group-read-init-file
+    "B" gnus-group-browse-foreign-server
+    "b" gnus-group-check-bogus-groups
+    "F" gnus-find-new-newsgroups
+    "\C-c\C-d" gnus-group-describe-group
+    "\M-d" gnus-group-describe-all-groups
+    "\C-c\C-a" gnus-group-apropos
+    "\C-c\M-\C-a" gnus-group-description-apropos
+    "a" gnus-group-post-news
+    "\ek" gnus-group-edit-local-kill
+    "\eK" gnus-group-edit-global-kill
+    "\C-k" gnus-group-kill-group
+    "\C-y" gnus-group-yank-group
+    "\C-w" gnus-group-kill-region
+    "\C-x\C-t" gnus-group-transpose-groups
+    "\C-c\C-l" gnus-group-list-killed
+    "\C-c\C-x" gnus-group-expire-articles
+    "\C-c\M-\C-x" gnus-group-expire-all-groups
+    "V" gnus-version
+    "s" gnus-group-save-newsrc
+    "z" gnus-group-suspend
+    "Z" gnus-group-clear-dribble
+    "q" gnus-group-exit
+    "Q" gnus-group-quit
+    "?" gnus-group-describe-briefly
+    "\C-c\C-i" gnus-info-find-node
+    "\M-e" gnus-group-edit-group-method
+    "^" gnus-group-enter-server-mode
+    gnus-mouse-2 gnus-mouse-pick-group
+    "<" beginning-of-buffer
+    ">" end-of-buffer
+    "\C-c\C-b" gnus-bug
+    "\C-c\C-s" gnus-group-sort-groups
+    "t" gnus-topic-mode
+    "\C-c\M-g" gnus-activate-all-groups
+    "\M-&" gnus-group-universal-argument
+    "#" gnus-group-mark-group
+    "\M-#" gnus-group-unmark-group)
+
+  (gnus-define-keys (gnus-group-mark-map "M" gnus-group-mode-map)
+    "m" gnus-group-mark-group
+    "u" gnus-group-unmark-group
+    "w" gnus-group-mark-region
+    "m" gnus-group-mark-buffer
+    "r" gnus-group-mark-regexp
+    "U" gnus-group-unmark-all-groups)
+
+  (gnus-define-keys (gnus-group-group-map "G" gnus-group-mode-map)
+    "d" gnus-group-make-directory-group
+    "h" gnus-group-make-help-group
+    "a" gnus-group-make-archive-group
+    "k" gnus-group-make-kiboze-group
+    "m" gnus-group-make-group
+    "E" gnus-group-edit-group
+    "e" gnus-group-edit-group-method
+    "p" gnus-group-edit-group-parameters
+    "v" gnus-group-add-to-virtual
+    "V" gnus-group-make-empty-virtual
+    "D" gnus-group-enter-directory
+    "f" gnus-group-make-doc-group
+    "r" gnus-group-rename-group
+    "\177" gnus-group-delete-group
+    [delete] gnus-group-delete-group)
+
+   (gnus-define-keys (gnus-group-soup-map "s" gnus-group-group-map)
+     "b" gnus-group-brew-soup
+     "w" gnus-soup-save-areas
+     "s" gnus-soup-send-replies
+     "p" gnus-soup-pack-packet
+     "r" nnsoup-pack-replies)
+
+   (gnus-define-keys (gnus-group-sort-map "S" gnus-group-group-map)
+     "s" gnus-group-sort-groups
+     "a" gnus-group-sort-groups-by-alphabet
+     "u" gnus-group-sort-groups-by-unread
+     "l" gnus-group-sort-groups-by-level
+     "v" gnus-group-sort-groups-by-score
+     "r" gnus-group-sort-groups-by-rank
+     "m" gnus-group-sort-groups-by-method)
+
+   (gnus-define-keys (gnus-group-list-map "A" gnus-group-mode-map)
+     "k" gnus-group-list-killed
+     "z" gnus-group-list-zombies
+     "s" gnus-group-list-groups
+     "u" gnus-group-list-all-groups
+     "A" gnus-group-list-active
+     "a" gnus-group-apropos
+     "d" gnus-group-description-apropos
+     "m" gnus-group-list-matching
+     "M" gnus-group-list-all-matching
+     "l" gnus-group-list-level)
+
+   (gnus-define-keys (gnus-group-score-map "W" gnus-group-mode-map)
+     "f" gnus-score-flush-cache)
+
+   (gnus-define-keys (gnus-group-help-map "H" gnus-group-mode-map)
+     "f" gnus-group-fetch-faq)
+
+   (gnus-define-keys (gnus-group-sub-map "S" gnus-group-mode-map)
+     "l" gnus-group-set-current-level
+     "t" gnus-group-unsubscribe-current-group
+     "s" gnus-group-unsubscribe-group
+     "k" gnus-group-kill-group
+     "y" gnus-group-yank-group
+     "w" gnus-group-kill-region
+     "\C-k" gnus-group-kill-level
+     "z" gnus-group-kill-all-zombies))
 
 (defun gnus-group-mode ()
   "Major mode for reading news.
@@ -5407,13 +5423,13 @@ of the Earth\".  There is no undo."
 (defun gnus-group-edit-group (group &optional part)
   "Edit the group on the current line."
   (interactive (list (gnus-group-group-name)))
-  (let ((done-func '(lambda ()
-                     "Exit editing mode and update the information."
-                     (interactive)
-                     (gnus-group-edit-group-done 'part 'group)))
-       (part (or part 'info))
-       (winconf (current-window-configuration))
-       info)
+  (let* ((part (or part 'info))
+        (done-func `(lambda ()
+                      "Exit editing mode and update the information."
+                      (interactive)
+                      (gnus-group-edit-group-done ',part ,group)))
+        (winconf (current-window-configuration))
+        info)
     (or group (error "No group on current line"))
     (or (setq info (gnus-get-info group))
        (error "Killed group; can't be edited"))
@@ -5426,9 +5442,6 @@ of the Earth\".    There is no undo."
     (local-set-key "\C-c\C-c" done-func)
     (make-local-variable 'gnus-prev-winconf)
     (setq gnus-prev-winconf winconf)
-    ;; We modify the func to let it know what part it is editing.
-    (setcar (cdr (nth 4 done-func)) (list 'quote part))
-    (setcar (cdr (cdr (nth 4 done-func))) group)
     (erase-buffer)
     (insert
      (cond
@@ -5463,27 +5476,36 @@ of the Earth\".  There is no undo."
   (goto-char (point-min))
   (let* ((form (read (current-buffer)))
         (winconf gnus-prev-winconf)
-        (new-group (when (eq part 'info)
-                     (if (or (not (nth 4 form))
+        (method (cond ((eq part 'info) (nth 4 form))
+                      ((eq part 'method) form)
+                      (t nil)))
+        (info (cond ((eq part 'info) form)
+                    ((eq part 'method) (gnus-get-info group))
+                    (t nil)))
+        (new-group (if info
+                     (if (or (not method)
                              (gnus-server-equal
-                              gnus-select-method (nth 4 form)))
-                         (gnus-group-real-name (car form))
+                              gnus-select-method method))
+                         (gnus-group-real-name (car info))
                        (gnus-group-prefixed-name
-                        (gnus-group-real-name (car form)) (nth 4 form))))))
+                        (gnus-group-real-name (car info)) method))
+                     nil)))
+    (when (and new-group
+              (not (equal new-group group)))
+      (when (gnus-group-goto-group group)
+       (gnus-group-kill-group 1))
+      (gnus-activate-group new-group))
     ;; Set the info.
-    (if (eq part 'info)
+    (if (and info new-group)
        (progn
-         (when new-group (setcar form new-group))
-         (gnus-group-set-info form))
-      (gnus-group-set-info form group part))
+         (setq info (gnus-copy-sequence info))
+         (setcar info new-group)
+         (setcar (cddddr info) method)
+         (gnus-group-set-info info))
+      (gnus-group-set-info form (or new-group group) part))
     (kill-buffer (current-buffer))
     (and winconf (set-window-configuration winconf))
     (set-buffer gnus-group-buffer)
-    (when (and new-group
-            (not (equal new-group group)))
-      (when (gnus-group-goto-group group)
-       (gnus-group-kill-group 1))
-      (gnus-activate-group new-group))
     (gnus-group-update-group (or new-group group))
     (gnus-group-position-point)))
 
@@ -6584,296 +6606,281 @@ and the second element is the address."
 
   ;; Non-orthogonal keys
 
-  (gnus-define-keys
-   gnus-summary-mode-map
-   " " gnus-summary-next-page
-   "\177" gnus-summary-prev-page
-   [delete] gnus-summary-prev-page
-   "\r" gnus-summary-scroll-up
-   "n" gnus-summary-next-unread-article
-   "p" gnus-summary-prev-unread-article
-   "N" gnus-summary-next-article
-   "P" gnus-summary-prev-article
-   "\M-\C-n" gnus-summary-next-same-subject
-   "\M-\C-p" gnus-summary-prev-same-subject
-   "\M-n" gnus-summary-next-unread-subject
-   "\M-p" gnus-summary-prev-unread-subject
-   "." gnus-summary-first-unread-article
-   "," gnus-summary-best-unread-article
-   "\M-s" gnus-summary-search-article-forward
-   "\M-r" gnus-summary-search-article-backward
-   "<" gnus-summary-beginning-of-article
-   ">" gnus-summary-end-of-article
-   "j" gnus-summary-goto-article
-   "^" gnus-summary-refer-parent-article
-   "\M-^" gnus-summary-refer-article
-   "u" gnus-summary-tick-article-forward
-   "!" gnus-summary-tick-article-forward
-   "U" gnus-summary-tick-article-backward
-   "d" gnus-summary-mark-as-read-forward
-   "D" gnus-summary-mark-as-read-backward
-   "E" gnus-summary-mark-as-expirable
-   "\M-u" gnus-summary-clear-mark-forward
-   "\M-U" gnus-summary-clear-mark-backward
-   "k" gnus-summary-kill-same-subject-and-select
-   "\C-k" gnus-summary-kill-same-subject
-   "\M-\C-k" gnus-summary-kill-thread
-   "\M-\C-l" gnus-summary-lower-thread
-   "e" gnus-summary-edit-article
-   "#" gnus-summary-mark-as-processable
-   "\M-#" gnus-summary-unmark-as-processable
-   "\M-\C-t" gnus-summary-toggle-threads
-   "\M-\C-s" gnus-summary-show-thread
-   "\M-\C-h" gnus-summary-hide-thread
-   "\M-\C-f" gnus-summary-next-thread
-   "\M-\C-b" gnus-summary-prev-thread
-   "\M-\C-u" gnus-summary-up-thread
-   "\M-\C-d" gnus-summary-down-thread
-   "&" gnus-summary-execute-command
-   "c" gnus-summary-catchup-and-exit
-   "\C-w" gnus-summary-mark-region-as-read
-   "\C-t" gnus-summary-toggle-truncation
-   "?" gnus-summary-mark-as-dormant
-   "\C-c\M-\C-s" gnus-summary-limit-include-expunged
-   "\C-c\C-s\C-n" gnus-summary-sort-by-number
-   "\C-c\C-s\C-a" gnus-summary-sort-by-author
-   "\C-c\C-s\C-s" gnus-summary-sort-by-subject
-   "\C-c\C-s\C-d" gnus-summary-sort-by-date
-   "\C-c\C-s\C-i" gnus-summary-sort-by-score
-   "=" gnus-summary-expand-window
-   "\C-x\C-s" gnus-summary-reselect-current-group
-   "\M-g" gnus-summary-rescan-group
-   "w" gnus-summary-stop-page-breaking
-   "\C-c\C-r" gnus-summary-caesar-message
-   "\M-t" gnus-summary-toggle-mime
-   "f" gnus-summary-followup
-   "F" gnus-summary-followup-with-original
-   "C" gnus-summary-cancel-article
-   "r" gnus-summary-reply
-   "R" gnus-summary-reply-with-original
-   "\C-c\C-f" gnus-summary-mail-forward
-   "o" gnus-summary-save-article
-   "\C-o" gnus-summary-save-article-mail
-   "|" gnus-summary-pipe-output
-   "\M-k" gnus-summary-edit-local-kill
-   "\M-K" gnus-summary-edit-global-kill
-   "V" gnus-version
-   "\C-c\C-d" gnus-summary-describe-group
-   "q" gnus-summary-exit
-   "Q" gnus-summary-exit-no-update
-   "\C-c\C-i" gnus-info-find-node
-   gnus-mouse-2 gnus-mouse-pick-article
-   "m" gnus-summary-mail-other-window
-   "a" gnus-summary-post-news
-   "x" gnus-summary-limit-to-unread
-   "s" gnus-summary-isearch-article
-   "t" gnus-article-hide-headers
-   "g" gnus-summary-show-article
-   "l" gnus-summary-goto-last-article
-   "\C-c\C-v\C-v" gnus-uu-decode-uu-view
-   "\C-d" gnus-summary-enter-digest-group
-   "\C-c\C-b" gnus-bug
-   "*" gnus-cache-enter-article
-   "\M-*" gnus-cache-remove-article
-   "\M-&" gnus-summary-universal-argument
-   "\C-l" gnus-recenter
-   "I" gnus-summary-increase-score
-   "L" gnus-summary-lower-score
-
-   "V" gnus-summary-score-map
-   "X" gnus-uu-extract-map
-   "S" gnus-summary-send-map)
+  (gnus-define-keys gnus-summary-mode-map
+    " " gnus-summary-next-page
+    "\177" gnus-summary-prev-page
+    [delete] gnus-summary-prev-page
+    "\r" gnus-summary-scroll-up
+    "n" gnus-summary-next-unread-article
+    "p" gnus-summary-prev-unread-article
+    "N" gnus-summary-next-article
+    "P" gnus-summary-prev-article
+    "\M-\C-n" gnus-summary-next-same-subject
+    "\M-\C-p" gnus-summary-prev-same-subject
+    "\M-n" gnus-summary-next-unread-subject
+    "\M-p" gnus-summary-prev-unread-subject
+    "." gnus-summary-first-unread-article
+    "," gnus-summary-best-unread-article
+    "\M-s" gnus-summary-search-article-forward
+    "\M-r" gnus-summary-search-article-backward
+    "<" gnus-summary-beginning-of-article
+    ">" gnus-summary-end-of-article
+    "j" gnus-summary-goto-article
+    "^" gnus-summary-refer-parent-article
+    "\M-^" gnus-summary-refer-article
+    "u" gnus-summary-tick-article-forward
+    "!" gnus-summary-tick-article-forward
+    "U" gnus-summary-tick-article-backward
+    "d" gnus-summary-mark-as-read-forward
+    "D" gnus-summary-mark-as-read-backward
+    "E" gnus-summary-mark-as-expirable
+    "\M-u" gnus-summary-clear-mark-forward
+    "\M-U" gnus-summary-clear-mark-backward
+    "k" gnus-summary-kill-same-subject-and-select
+    "\C-k" gnus-summary-kill-same-subject
+    "\M-\C-k" gnus-summary-kill-thread
+    "\M-\C-l" gnus-summary-lower-thread
+    "e" gnus-summary-edit-article
+    "#" gnus-summary-mark-as-processable
+    "\M-#" gnus-summary-unmark-as-processable
+    "\M-\C-t" gnus-summary-toggle-threads
+    "\M-\C-s" gnus-summary-show-thread
+    "\M-\C-h" gnus-summary-hide-thread
+    "\M-\C-f" gnus-summary-next-thread
+    "\M-\C-b" gnus-summary-prev-thread
+    "\M-\C-u" gnus-summary-up-thread
+    "\M-\C-d" gnus-summary-down-thread
+    "&" gnus-summary-execute-command
+    "c" gnus-summary-catchup-and-exit
+    "\C-w" gnus-summary-mark-region-as-read
+    "\C-t" gnus-summary-toggle-truncation
+    "?" gnus-summary-mark-as-dormant
+    "\C-c\M-\C-s" gnus-summary-limit-include-expunged
+    "\C-c\C-s\C-n" gnus-summary-sort-by-number
+    "\C-c\C-s\C-a" gnus-summary-sort-by-author
+    "\C-c\C-s\C-s" gnus-summary-sort-by-subject
+    "\C-c\C-s\C-d" gnus-summary-sort-by-date
+    "\C-c\C-s\C-i" gnus-summary-sort-by-score
+    "=" gnus-summary-expand-window
+    "\C-x\C-s" gnus-summary-reselect-current-group
+    "\M-g" gnus-summary-rescan-group
+    "w" gnus-summary-stop-page-breaking
+    "\C-c\C-r" gnus-summary-caesar-message
+    "\M-t" gnus-summary-toggle-mime
+    "f" gnus-summary-followup
+    "F" gnus-summary-followup-with-original
+    "C" gnus-summary-cancel-article
+    "r" gnus-summary-reply
+    "R" gnus-summary-reply-with-original
+    "\C-c\C-f" gnus-summary-mail-forward
+    "o" gnus-summary-save-article
+    "\C-o" gnus-summary-save-article-mail
+    "|" gnus-summary-pipe-output
+    "\M-k" gnus-summary-edit-local-kill
+    "\M-K" gnus-summary-edit-global-kill
+    "V" gnus-version
+    "\C-c\C-d" gnus-summary-describe-group
+    "q" gnus-summary-exit
+    "Q" gnus-summary-exit-no-update
+    "\C-c\C-i" gnus-info-find-node
+    gnus-mouse-2 gnus-mouse-pick-article
+    "m" gnus-summary-mail-other-window
+    "a" gnus-summary-post-news
+    "x" gnus-summary-limit-to-unread
+    "s" gnus-summary-isearch-article
+    "t" gnus-article-hide-headers
+    "g" gnus-summary-show-article
+    "l" gnus-summary-goto-last-article
+    "\C-c\C-v\C-v" gnus-uu-decode-uu-view
+    "\C-d" gnus-summary-enter-digest-group
+    "\C-c\C-b" gnus-bug
+    "*" gnus-cache-enter-article
+    "\M-*" gnus-cache-remove-article
+    "\M-&" gnus-summary-universal-argument
+    "\C-l" gnus-recenter
+    "I" gnus-summary-increase-score
+    "L" gnus-summary-lower-score
+
+    "V" gnus-summary-score-map
+    "X" gnus-uu-extract-map
+    "S" gnus-summary-send-map)
 
   ;; Sort of orthogonal keymap
-  (gnus-define-keys
-   (gnus-summary-mark-map "M" gnus-summary-mode-map)
-   "t" gnus-summary-tick-article-forward
-   "!" gnus-summary-tick-article-forward
-   "d" gnus-summary-mark-as-read-forward
-   "r" gnus-summary-mark-as-read-forward
-   "c" gnus-summary-clear-mark-forward
-   " " gnus-summary-clear-mark-forward
-   "e" gnus-summary-mark-as-expirable
-   "x" gnus-summary-mark-as-expirable
-   "?" gnus-summary-mark-as-dormant
-   "b" gnus-summary-set-bookmark
-   "B" gnus-summary-remove-bookmark
-   "#" gnus-summary-mark-as-processable
-   "\M-#" gnus-summary-unmark-as-processable
-   "S" gnus-summary-limit-include-expunged
-   "C" gnus-summary-catchup
-   "H" gnus-summary-catchup-to-here
-   "\C-c" gnus-summary-catchup-all
-   "k" gnus-summary-kill-same-subject-and-select
-   "K" gnus-summary-kill-same-subject
-   "P" gnus-uu-mark-map)
-
-  (gnus-define-keys
-   (gnus-summary-mscore-map "V" gnus-summary-mode-map)
-   "c" gnus-summary-clear-above
-   "u" gnus-summary-tick-above
-   "m" gnus-summary-mark-above
-   "k" gnus-summary-kill-below)
-
-  (gnus-define-keys
-   (gnus-summary-limit-map "/" gnus-summary-mode-map)
-   "/" gnus-summary-limit-to-subject
-   "n" gnus-summary-limit-to-articles
-   "w" gnus-summary-pop-limit
-   "s" gnus-summary-limit-to-subject
-   "a" gnus-summary-limit-to-author
-   "u" gnus-summary-limit-to-unread
-   "m" gnus-summary-limit-to-marks
-   "v" gnus-summary-limit-to-score
-   "D" gnus-summary-limit-include-dormant
-   "d" gnus-summary-limit-exclude-dormant
-;;  "t" gnus-summary-limit-exclude-thread
-   "E" gnus-summary-limit-include-expunged
-   "c" gnus-summary-limit-exclude-childless-dormant
-   "C" gnus-summary-limit-mark-excluded-as-read)
-
-  (gnus-define-keys
-   (gnus-summary-goto-map "G" gnus-summary-mode-map)
-   "n" gnus-summary-next-unread-article
-   "p" gnus-summary-prev-unread-article
-   "N" gnus-summary-next-article
-   "P" gnus-summary-prev-article
-   "\C-n" gnus-summary-next-same-subject
-   "\C-p" gnus-summary-prev-same-subject
-   "\M-n" gnus-summary-next-unread-subject
-   "\M-p" gnus-summary-prev-unread-subject
-   "f" gnus-summary-first-unread-article
-   "b" gnus-summary-best-unread-article
-   "g" gnus-summary-goto-subject
-   "l" gnus-summary-goto-last-article
-   "p" gnus-summary-pop-article)
-
-  (gnus-define-keys
-   (gnus-summary-thread-map "T" gnus-summary-mode-map)
-   "k" gnus-summary-kill-thread
-   "l" gnus-summary-lower-thread
-   "i" gnus-summary-raise-thread
-   "T" gnus-summary-toggle-threads
-   "t" gnus-summary-rethread-current
-   "^" gnus-summary-reparent-thread
-   "s" gnus-summary-show-thread
-   "S" gnus-summary-show-all-threads
-   "h" gnus-summary-hide-thread
-   "H" gnus-summary-hide-all-threads
-   "n" gnus-summary-next-thread
-   "p" gnus-summary-prev-thread
-   "u" gnus-summary-up-thread
-   "o" gnus-summary-top-thread
-   "d" gnus-summary-down-thread
-   "#" gnus-uu-mark-thread
-   "\M-#" gnus-uu-unmark-thread)
-
-  (gnus-define-keys
-   (gnus-summary-exit-map "Z" gnus-summary-mode-map)
-   "c" gnus-summary-catchup-and-exit
-   "C" gnus-summary-catchup-all-and-exit
-   "E" gnus-summary-exit-no-update
-   "Q" gnus-summary-exit
-   "Z" gnus-summary-exit
-   "n" gnus-summary-catchup-and-goto-next-group
-   "R" gnus-summary-reselect-current-group
-   "G" gnus-summary-rescan-group
-   "N" gnus-summary-next-group
-   "P" gnus-summary-prev-group)
-
-  (gnus-define-keys
-   (gnus-summary-article-map "A" gnus-summary-mode-map)
-   " " gnus-summary-next-page
-   "n" gnus-summary-next-page
-   "\177" gnus-summary-prev-page
-   [delete] gnus-summary-prev-page
-   "p" gnus-summary-prev-page
-   "\r" gnus-summary-scroll-up
-   "<" gnus-summary-beginning-of-article
-   ">" gnus-summary-end-of-article
-   "b" gnus-summary-beginning-of-article
-   "e" gnus-summary-end-of-article
-   "^" gnus-summary-refer-parent-article
-   "r" gnus-summary-refer-parent-article
-   "R" gnus-summary-refer-references
-   "g" gnus-summary-show-article
-   "s" gnus-summary-isearch-article)
-
-  (gnus-define-keys
-   (gnus-summary-wash-map "W" gnus-summary-mode-map)
-   "b" gnus-article-add-buttons
-   "B" gnus-article-add-buttons-to-head
-   "o" gnus-article-treat-overstrike
-;;  "w" gnus-article-word-wrap
-   "w" gnus-article-fill-cited-article
-   "c" gnus-article-remove-cr
-   "L" gnus-article-remove-trailing-blank-lines
-   "q" gnus-article-de-quoted-unreadable
-   "f" gnus-article-display-x-face
-   "l" gnus-summary-stop-page-breaking
-   "r" gnus-summary-caesar-message
-   "t" gnus-article-hide-headers
-   "v" gnus-summary-verbose-headers
-   "m" gnus-summary-toggle-mime)
-
-  (gnus-define-keys
-   (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
-   "a" gnus-article-hide
-   "h" gnus-article-hide-headers
-   "b" gnus-article-hide-boring-headers
-   "s" gnus-article-hide-signature
-   "c" gnus-article-hide-citation
-   "p" gnus-article-hide-pgp
-   "\C-c" gnus-article-hide-citation-maybe)
-
-  (gnus-define-keys
-   (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
-   "a" gnus-article-highlight
-   "h" gnus-article-highlight-headers
-   "c" gnus-article-highlight-citation
-   "s" gnus-article-highlight-signature)
-
-  (gnus-define-keys
-   (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
-   "z" gnus-article-date-ut
-   "u" gnus-article-date-ut
-   "l" gnus-article-date-local
-   "e" gnus-article-date-lapsed
-   "o" gnus-article-date-original)
-
-  (gnus-define-keys
-   (gnus-summary-help-map "H" gnus-summary-mode-map)
-   "v" gnus-version
-   "f" gnus-summary-fetch-faq
-   "d" gnus-summary-describe-group
-   "h" gnus-summary-describe-briefly
-   "i" gnus-info-find-node)
-
-  (gnus-define-keys
-   (gnus-summary-backend-map "B" gnus-summary-mode-map)
-   "e" gnus-summary-expire-articles
-   "\M-\C-e" gnus-summary-expire-articles-now
-   "\177" gnus-summary-delete-article
-   [delete] gnus-summary-delete-article
-   "m" gnus-summary-move-article
-   "r" gnus-summary-respool-article
-   "w" gnus-summary-edit-article
-   "c" gnus-summary-copy-article
-   "B" gnus-summary-crosspost-article
-   "q" gnus-summary-respool-query
-   "i" gnus-summary-import-article)
-
-  (gnus-define-keys
-   (gnus-summary-save-map "O" gnus-summary-mode-map)
-   "o" gnus-summary-save-article
-   "m" gnus-summary-save-article-mail
-   "r" gnus-summary-save-article-rmail
-   "f" gnus-summary-save-article-file
-   "b" gnus-summary-save-article-body-file
-   "h" gnus-summary-save-article-folder
-   "v" gnus-summary-save-article-vm
-   "p" gnus-summary-pipe-output
-   "s" gnus-soup-add-article)
+  (gnus-define-keys (gnus-summary-mark-map "M" gnus-summary-mode-map)
+    "t" gnus-summary-tick-article-forward
+    "!" gnus-summary-tick-article-forward
+    "d" gnus-summary-mark-as-read-forward
+    "r" gnus-summary-mark-as-read-forward
+    "c" gnus-summary-clear-mark-forward
+    " " gnus-summary-clear-mark-forward
+    "e" gnus-summary-mark-as-expirable
+    "x" gnus-summary-mark-as-expirable
+    "?" gnus-summary-mark-as-dormant
+    "b" gnus-summary-set-bookmark
+    "B" gnus-summary-remove-bookmark
+    "#" gnus-summary-mark-as-processable
+    "\M-#" gnus-summary-unmark-as-processable
+    "S" gnus-summary-limit-include-expunged
+    "C" gnus-summary-catchup
+    "H" gnus-summary-catchup-to-here
+    "\C-c" gnus-summary-catchup-all
+    "k" gnus-summary-kill-same-subject-and-select
+    "K" gnus-summary-kill-same-subject
+    "P" gnus-uu-mark-map)
+
+  (gnus-define-keys (gnus-summary-mscore-map "V" gnus-summary-mode-map)
+    "c" gnus-summary-clear-above
+    "u" gnus-summary-tick-above
+    "m" gnus-summary-mark-above
+    "k" gnus-summary-kill-below)
+
+  (gnus-define-keys (gnus-summary-limit-map "/" gnus-summary-mode-map)
+    "/" gnus-summary-limit-to-subject
+    "n" gnus-summary-limit-to-articles
+    "w" gnus-summary-pop-limit
+    "s" gnus-summary-limit-to-subject
+    "a" gnus-summary-limit-to-author
+    "u" gnus-summary-limit-to-unread
+    "m" gnus-summary-limit-to-marks
+    "v" gnus-summary-limit-to-score
+    "D" gnus-summary-limit-include-dormant
+    "d" gnus-summary-limit-exclude-dormant
+    ;;  "t" gnus-summary-limit-exclude-thread
+    "E" gnus-summary-limit-include-expunged
+    "c" gnus-summary-limit-exclude-childless-dormant
+    "C" gnus-summary-limit-mark-excluded-as-read)
+
+  (gnus-define-keys (gnus-summary-goto-map "G" gnus-summary-mode-map)
+    "n" gnus-summary-next-unread-article
+    "p" gnus-summary-prev-unread-article
+    "N" gnus-summary-next-article
+    "P" gnus-summary-prev-article
+    "\C-n" gnus-summary-next-same-subject
+    "\C-p" gnus-summary-prev-same-subject
+    "\M-n" gnus-summary-next-unread-subject
+    "\M-p" gnus-summary-prev-unread-subject
+    "f" gnus-summary-first-unread-article
+    "b" gnus-summary-best-unread-article
+    "g" gnus-summary-goto-subject
+    "l" gnus-summary-goto-last-article
+    "p" gnus-summary-pop-article)
+
+  (gnus-define-keys (gnus-summary-thread-map "T" gnus-summary-mode-map)
+    "k" gnus-summary-kill-thread
+    "l" gnus-summary-lower-thread
+    "i" gnus-summary-raise-thread
+    "T" gnus-summary-toggle-threads
+    "t" gnus-summary-rethread-current
+    "^" gnus-summary-reparent-thread
+    "s" gnus-summary-show-thread
+    "S" gnus-summary-show-all-threads
+    "h" gnus-summary-hide-thread
+    "H" gnus-summary-hide-all-threads
+    "n" gnus-summary-next-thread
+    "p" gnus-summary-prev-thread
+    "u" gnus-summary-up-thread
+    "o" gnus-summary-top-thread
+    "d" gnus-summary-down-thread
+    "#" gnus-uu-mark-thread
+    "\M-#" gnus-uu-unmark-thread)
+
+  (gnus-define-keys (gnus-summary-exit-map "Z" gnus-summary-mode-map)
+    "c" gnus-summary-catchup-and-exit
+    "C" gnus-summary-catchup-all-and-exit
+    "E" gnus-summary-exit-no-update
+    "Q" gnus-summary-exit
+    "Z" gnus-summary-exit
+    "n" gnus-summary-catchup-and-goto-next-group
+    "R" gnus-summary-reselect-current-group
+    "G" gnus-summary-rescan-group
+    "N" gnus-summary-next-group
+    "P" gnus-summary-prev-group)
+
+  (gnus-define-keys (gnus-summary-article-map "A" gnus-summary-mode-map)
+    " " gnus-summary-next-page
+    "n" gnus-summary-next-page
+    "\177" gnus-summary-prev-page
+    [delete] gnus-summary-prev-page
+    "p" gnus-summary-prev-page
+    "\r" gnus-summary-scroll-up
+    "<" gnus-summary-beginning-of-article
+    ">" gnus-summary-end-of-article
+    "b" gnus-summary-beginning-of-article
+    "e" gnus-summary-end-of-article
+    "^" gnus-summary-refer-parent-article
+    "r" gnus-summary-refer-parent-article
+    "R" gnus-summary-refer-references
+    "g" gnus-summary-show-article
+    "s" gnus-summary-isearch-article)
+
+  (gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map)
+    "b" gnus-article-add-buttons
+    "B" gnus-article-add-buttons-to-head
+    "o" gnus-article-treat-overstrike
+    ;;  "w" gnus-article-word-wrap
+    "w" gnus-article-fill-cited-article
+    "c" gnus-article-remove-cr
+    "L" gnus-article-remove-trailing-blank-lines
+    "q" gnus-article-de-quoted-unreadable
+    "f" gnus-article-display-x-face
+    "l" gnus-summary-stop-page-breaking
+    "r" gnus-summary-caesar-message
+    "t" gnus-article-hide-headers
+    "v" gnus-summary-verbose-headers
+    "m" gnus-summary-toggle-mime)
+
+  (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
+    "a" gnus-article-hide
+    "h" gnus-article-hide-headers
+    "b" gnus-article-hide-boring-headers
+    "s" gnus-article-hide-signature
+    "c" gnus-article-hide-citation
+    "p" gnus-article-hide-pgp
+    "\C-c" gnus-article-hide-citation-maybe)
+
+  (gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
+    "a" gnus-article-highlight
+    "h" gnus-article-highlight-headers
+    "c" gnus-article-highlight-citation
+    "s" gnus-article-highlight-signature)
+
+  (gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
+    "z" gnus-article-date-ut
+    "u" gnus-article-date-ut
+    "l" gnus-article-date-local
+    "e" gnus-article-date-lapsed
+    "o" gnus-article-date-original)
+
+  (gnus-define-keys (gnus-summary-help-map "H" gnus-summary-mode-map)
+    "v" gnus-version
+    "f" gnus-summary-fetch-faq
+    "d" gnus-summary-describe-group
+    "h" gnus-summary-describe-briefly
+    "i" gnus-info-find-node)
+
+  (gnus-define-keys (gnus-summary-backend-map "B" gnus-summary-mode-map)
+    "e" gnus-summary-expire-articles
+    "\M-\C-e" gnus-summary-expire-articles-now
+    "\177" gnus-summary-delete-article
+    [delete] gnus-summary-delete-article
+    "m" gnus-summary-move-article
+    "r" gnus-summary-respool-article
+    "w" gnus-summary-edit-article
+    "c" gnus-summary-copy-article
+    "B" gnus-summary-crosspost-article
+    "q" gnus-summary-respool-query
+    "i" gnus-summary-import-article)
+
+  (gnus-define-keys (gnus-summary-save-map "O" gnus-summary-mode-map)
+    "o" gnus-summary-save-article
+    "m" gnus-summary-save-article-mail
+    "r" gnus-summary-save-article-rmail
+    "f" gnus-summary-save-article-file
+    "b" gnus-summary-save-article-body-file
+    "h" gnus-summary-save-article-folder
+    "v" gnus-summary-save-article-vm
+    "p" gnus-summary-pipe-output
+    "s" gnus-soup-add-article)
   )
 
 \f
@@ -11916,7 +11923,7 @@ The difference between N and the number of marks cleared is returned."
   (when (memq gnus-current-article gnus-newsgroup-unreads)
     (gnus-summary-mark-article gnus-current-article gnus-read-mark)))
 
-(defun gnus-summary-mark-unread-and-read-as-read ()
+(defun gnus-summary-mark-read-and-unread-as-read ()
   "Intended to be used by `gnus-summary-mark-article-hook'."
   (let ((mark (gnus-summary-article-mark)))
     (when (or (gnus-unread-mark-p mark)
@@ -12272,7 +12279,8 @@ Returns nil if no threads were there to be hidden."
                (gnus-summary-goto-subject article))
            (goto-char start)
            nil)
-       (gnus-summary-position-point)))))
+       ;;(gnus-summary-position-point)
+       ))))
 
 (defun gnus-summary-go-to-next-thread (&optional previous)
   "Go to the same level (or less) next thread.
@@ -12310,7 +12318,8 @@ If SILENT, don't output messages."
                            old (point) 'gnus-intangible nil)))
        (goto-char dum))
       (decf n))
-    (gnus-summary-position-point)
+    (unless silent 
+      (gnus-summary-position-point))
     (when (and (not silent) (/= 0 n))
       (gnus-message 7 "No more threads"))
     n))
@@ -12955,21 +12964,20 @@ is initialized from the SAVEDIR environment variable."
   (setq gnus-article-mode-map (make-keymap))
   (suppress-keymap gnus-article-mode-map)
 
-  (gnus-define-keys
-   gnus-article-mode-map
-   " " gnus-article-goto-next-page
-   "\177" gnus-article-goto-prev-page
-   [delete] gnus-article-goto-prev-page
-   "\C-c^" gnus-article-refer-article
-   "h" gnus-article-show-summary
-   "s" gnus-article-show-summary
-   "\C-c\C-m" gnus-article-mail
-   "?" gnus-article-describe-briefly
-   gnus-mouse-2 gnus-article-push-button
-   "\r" gnus-article-press-button
-   "\t" gnus-article-next-button
-   "\M-\t" gnus-article-prev-button
-   "\C-c\C-b" gnus-bug)
+  (gnus-define-keys gnus-article-mode-map
+    " " gnus-article-goto-next-page
+    "\177" gnus-article-goto-prev-page
+    [delete] gnus-article-goto-prev-page
+    "\C-c^" gnus-article-refer-article
+    "h" gnus-article-show-summary
+    "s" gnus-article-show-summary
+    "\C-c\C-m" gnus-article-mail
+    "?" gnus-article-describe-briefly
+    gnus-mouse-2 gnus-article-push-button
+    "\r" gnus-article-press-button
+    "\t" gnus-article-next-button
+    "\M-\t" gnus-article-prev-button
+    "\C-c\C-b" gnus-bug)
 
   (substitute-key-definition
    'undefined 'gnus-article-read-summary-keys gnus-article-mode-map))
@@ -14779,7 +14787,8 @@ If LEVEL is non-nil, the news will be set up at level LEVEL."
     ;; Read the newsrc file and create `gnus-newsrc-hashtb'.
     (if init (gnus-read-newsrc-file rawfile))
 
-    (unless (assoc "archive" gnus-server-alist)
+    (when (and (not (assoc "archive" gnus-server-alist))
+              gnus-message-archive-method)
       (push (cons "archive" gnus-message-archive-method)
            gnus-server-alist))
 
@@ -14911,8 +14920,9 @@ the server for new groups."
 (defun gnus-ask-server-for-new-groups ()
   (let* ((date (or gnus-newsrc-last-checked-date (current-time-string)))
         (methods (cons gnus-select-method
-                       (cons
-                        "archive"
+                       (nconc
+                        (when gnus-message-archive-method
+                          (list "archive"))
                         (append
                          (and (consp gnus-check-new-newsgroups)
                               gnus-check-new-newsgroups)
@@ -15479,7 +15489,8 @@ Returns whether the updating was successful."
            ;; secondary ones.
            gnus-secondary-select-methods)
          ;; Also read from the archive server.
-         (list "archive")))
+         (when gnus-message-archive-method
+           (list "archive"))))
        list-type)
     (setq gnus-have-read-active-file nil)
     (save-excursion
@@ -16248,8 +16259,10 @@ If FORCE is non-nil, the .newsrc file is read."
 
 (defun gnus-read-all-descriptions-files ()
   (let ((methods (cons gnus-select-method 
-                      (cons "archive"
-                            gnus-secondary-select-methods))))
+                      (nconc
+                       (when gnus-message-archive-method
+                         (list "archive"))
+                       gnus-secondary-select-methods))))
     (while methods
       (gnus-read-descriptions-file (car methods))
       (setq methods (cdr methods)))
index 7635608..49cbd6b 100644 (file)
@@ -522,6 +522,19 @@ nn*-request-list should have been called before calling this function."
          (setq end (point-max))))
       (goto-char end))))
 
+(defun nnmail-search-unix-mail-delim ()
+  "Put point at the beginning of the next message."
+  (let ((case-fold-search t)
+       (delim (concat "^" rmail-unix-mail-delimiter))
+       found)
+    (while (not found)
+      (if (re-search-forward delim nil t)
+         (when (looking-at "[^ :]+:")
+           (forward-line -1)
+           (setq found 'yes))
+       (setq found 'no)))
+    (eq found 'yes)))
+
 (defun nnmail-process-unix-mail-format (func)
   (let ((case-fold-search t)
        (delim (concat "^" rmail-unix-mail-delimiter))
@@ -559,7 +572,8 @@ nn*-request-list should have been called before calling this function."
          (insert "Message-ID: " (setq message-id (nnmail-message-id)) "\n"))
        ;; Look for a Content-Length header.
        (goto-char (point-min))
-       (if (not (re-search-forward "^Content-Length:[ \t]*\\([0-9]+\\)" nil t))
+       (if (not (re-search-forward
+                 "^Content-Length:[ \t]*\\([0-9]+\\)" nil t))
            (setq content-length nil)
          (setq content-length (string-to-int (match-string 1)))
          ;; We destroy the header, since none of the backends ever 
@@ -585,9 +599,8 @@ nn*-request-list should have been called before calling this function."
          ;; No Content-Length, so we find the beginning of the next 
          ;; article or the end of the buffer.
          (goto-char head-end)
-         (if (re-search-forward delim nil t)
-             (goto-char (match-beginning 0))
-           (goto-char (point-max))))
+         (or (nnmail-search-unix-mail-delim)
+             (goto-char (point-max))))
        ;; Allow the backend to save the article.
        (save-excursion
          (save-restriction
index 9b5ca34..cb98ace 100644 (file)
@@ -333,7 +333,7 @@ The SOUP packet file name will be inserted at the %s.")
                    (when (file-exists-p (nnsoup-file prefix))
                      (delete-file (nnsoup-file prefix)))
                    (nnheader-message 
-                    5 "Deleting %s in group..." (nnsoup-file prefix t)
+                    5 "Deleting %s in group %s..." (nnsoup-file prefix t)
                     group)
                    (when (file-exists-p (nnsoup-file prefix t))
                      (delete-file (nnsoup-file prefix t)))
index 19e7308..710b757 100644 (file)
@@ -145,6 +145,10 @@ variable, split the XOVER request into two requests.")
   "*Number of seconds to wait before an nntp connection times out.
 If this variable is nil, which is the default, no timers are set.")
 
+(defvar nntp-command-timeout nil
+  "*Number of seconds to wait for a response when sending a command.
+If this variable is nil, which is the default, no timers are set.")
+
 (defvar nntp-news-default-headers nil
   "*If non-nil, override `mail-default-headers' when posting news.")
 
@@ -382,9 +386,10 @@ servers."
     (setq nntp-current-server server)
     (or (nntp-server-opened server)
        connectionless
-       (progn
-         (run-hooks 'nntp-prepare-server-hook)
-         (nntp-open-server-semi-internal nntp-address nntp-port-number)))))
+       (prog2
+           (run-hooks 'nntp-prepare-server-hook)
+           (nntp-open-server-semi-internal nntp-address nntp-port-number)
+         (nnheader-insert "")))))
 
 (defun nntp-close-server (&optional server)
   "Close connection to SERVER."
@@ -401,26 +406,22 @@ servers."
          (nntp-send-command nil "QUIT")))
     (nntp-close-server-internal server)))
 
-(defalias 'nntp-request-quit (symbol-function 'nntp-close-server))
-
 (defun nntp-request-close ()
   "Close all server connections."
-  (let (proc)
+  (let (proc entry)
      (while nntp-opened-connections
        (when (setq proc (pop nntp-opened-connections))
         (condition-case ()
-            (process-send-string proc "QUIT\n")
+            (process-send-string proc "QUIT\r\n")
           (error nil))
         (delete-process proc)))
      (and nntp-async-buffer
          (get-buffer nntp-async-buffer)
          (kill-buffer nntp-async-buffer))
-    (while nntp-server-alist
-      (and (setq proc (nth 1 (assq 'nntp-async-buffer
-                                  (car nntp-server-alist))))
+    (while (setq entry (pop nntp-server-alist))
+      (and (setq proc (nth 1 (assq 'nntp-async-buffer entry)))
           (buffer-name proc)
-          (kill-buffer proc))
-      (setq nntp-server-alist (cdr nntp-server-alist)))
+          (kill-buffer proc)))
     (setq nntp-current-server nil
          nntp-async-group-alist nil)))
 
@@ -509,11 +510,11 @@ servers."
   "Request head of article ID (Message-ID or number)."
   (nntp-possibly-change-server group server)
   (prog1
-      (and (nntp-send-command 
-           "^\\.\r?\n" "HEAD" (if (numberp id) (int-to-string id) id))
-          (if (numberp id) id
-            ;; We find out what the article number was.
-            (nntp-find-group-and-number)))
+      (when (nntp-send-command 
+            "^\\.\r?\n" "HEAD" (if (numberp id) (int-to-string id) id))
+       (if (numberp id) id
+         ;; We find out what the article number was.
+         (nntp-find-group-and-number)))
     (nntp-decode-text)))
 
 (defun nntp-request-stat (id &optional group server)
@@ -527,6 +528,7 @@ servers."
 
 (defun nntp-request-group (group &optional server dont-check)
   "Select GROUP."
+  (nntp-possibly-change-server nil server)
   (setq nntp-current-group
        (when (nntp-send-command "^2.*\r?\n" "GROUP" group)
          group)))
@@ -751,7 +753,57 @@ It will prompt for a password."
 ;;; Synchronous Communication with NNTP servers.
 ;;;
 
+(defvar nntp-retry-command)
+
 (defun nntp-send-command (response cmd &rest args)
+  "Wait for server RESPONSE after sending CMD and optional ARGS to server."
+  (let ((timer 
+        (and nntp-command-timeout 
+             (cond
+              ((fboundp 'run-at-time)
+               (run-at-time nntp-command-timeout
+                            nil 'nntp-kill-command nntp-current-server))
+              ((fboundp 'start-itimer)
+               ;; Not sure if this will work or not, only one way to
+               ;; find out
+               (eval '(start-itimer "nntp-timeout"
+                                    (lambda ()
+                                      (nntp-kill-command nntp-current-server))
+                                    nntp-command-timeout nil))))))
+       (nntp-retry-command t)
+       result)
+    (unwind-protect
+       (save-excursion
+         (while nntp-retry-command
+           (setq nntp-retry-command nil)
+           ;; Clear communication buffer.
+           (set-buffer nntp-server-buffer)
+           (erase-buffer)
+           (condition-case ()
+               (progn
+                 (apply 'nntp-send-strings-to-server cmd args)
+                 (setq result
+                       (if response
+                           (nntp-wait-for-response response)
+                         t)))
+             (quit (setq nntp-retry-command t))))
+         result)
+      (when timer 
+       (cancel-timer timer)))))
+
+(defun nntp-kill-command (server)
+  "Kill and restart the connection to SERVER."
+  (let ((proc (nth 1 (assq 'nntp-server-process 
+                          (assoc server nntp-server-alist)))))
+    (when proc 
+      (delete-process (process-name proc)))
+    (nntp-close-server server)
+    (nntp-open-server server)
+    (when nntp-current-group
+      (nntp-request-group nntp-current-group))
+    (setq nntp-retry-command t)))
+
+(defun nntp-send-command-old (response cmd &rest args)
   "Wait for server RESPONSE after sending CMD and optional ARGS to server."
   (save-excursion
     ;; Clear communication buffer.
@@ -1054,7 +1106,7 @@ If SERVICE, this this as the port number."
     (save-excursion
       (set-buffer nntp-server-buffer)
       (setq nntp-status-string "")
-      (message "nntp: Connecting to server on %s..." server)
+      (message "nntp: Connecting to server on %s..." nntp-address)
       (cond ((and server (nntp-open-server-internal server service))
             (setq nntp-address server)
             (setq status
@@ -1065,7 +1117,7 @@ If SERVICE, this this as the port number."
             (unless status
               (nntp-close-server-internal server)
               (nnheader-report 
-               'nntp "Couldn't open connection to %s" server))
+               'nntp "Couldn't open connection to %s" nntp-address))
             (when nntp-server-process
               (set-process-sentinel 
                nntp-server-process 'nntp-default-sentinel)
index 5947f2c..f4a249b 100644 (file)
@@ -6823,8 +6823,12 @@ Check whether the article has an @code{Approved} header, which is
 something only moderators should include.
 @item empty
 Check whether the article is empty.
+@item empty-headers
+Check whether any of the headers are empty.
 @end table
 
+All these conditions are checked by default.
+
 @end table
 
 
@@ -7750,6 +7754,22 @@ that says how many seconds the @code{nntp} backend should wait for a
 connection before giving up.  If it is @code{nil}, which is the default,
 no timeouts are done.
 
+@item nntp-command-timeout
+@vindex nntp-command-timeout
+@cindex PPP connections
+@cindex dynamic IP addresses
+If you're running Gnus on a machine that has a dynamically assigned
+address, Gnus may become confused.  If the address of your machine
+changes after connecting to the @sc{nntp} server, Gnus will simply sit
+waiting forever for replies from the server.  To help with this
+unfortunate problem, you can set this command to a number.  Gnus will
+then, if it sits waiting longer than that number of seconds for a reply
+from the server, shut down the connection, start a new one, and resend
+the command.  This should hopefully be transparent to the user.  A
+likely number is 30 seconds.  (You can also @kbd{C-g} if Gnus hangs in
+this manner.  The same thing will hopefully happen, but it can be
+somewhat unsafe.)
+
 @item nntp-server-hook
 @vindex nntp-server-hook
 This hook is run as the last step when connecting to an @sc{nntp}