*** empty log message ***
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 04:43:22 +0000 (04:43 +0000)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 04:43:22 +0000 (04:43 +0000)
lisp/ChangeLog
lisp/gnus-cus.el
lisp/gnus-ems.el
lisp/gnus-msg.el
lisp/gnus-vis.el
lisp/gnus-xmas.el
lisp/gnus.el
lisp/nnheader.el
lisp/nntp.el

index 9553784..1f83df5 100644 (file)
@@ -1,5 +1,39 @@
+Fri Nov 17 03:35:58 1995  Lars Magne Ingebrigtsen  <larsi@narfi.ifi.uio.no>
+
+       * gnus-vis.el ((require 'cl)): Require cl.
+
+       * gnus.el (gnus-active): New macro.
+       (gnus-intern-safe): Ditto.
+       (gnus-set-active): Ditto.
+
+Fri Nov 17 01:33:26 1995  Lars Magne Ingebrigtsen  <larsi@ifi.uio.no>
+
+       * gnus.el (gnus-max-width-function): Totally bugged out.
+
+       * gnus-msg.el (gnus-new-news): Set point on Subject.
+       (gnus-inews-insert-bfcc): Don't narrow to headers.
+
+       * gnus.el (gnus-articles-to-read): `C-u SPC' would have no real
+       effect. 
+       (gnus-article-date-ut): Would chop up lines.
+
+       * nnheader.el: Require cl.
+
+Fri Nov 17 00:11:10 1995  Lars Magne Ingebrigtsen  <larsi@narfi.ifi.uio.no>
+
+       * gnus.el (gnus-select-newsgroup): Expiry marks would disappear.
+       (gnus-headers-decode-quoted-printable): Use subst-char instead of
+       search/replace. 
+       (gnus-remove-thread): Didn't remove properly.
+
+Thu Nov 16 06:28:17 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.el: Intern group in active hashtb throughout.
+
 Wed Nov 15 06:13:48 1995  Lars Ingebrigtsen  <lars@eyesore.no>
 
+       * gnus.el: 0.13 is released.
+
        * gnus-score.el (gnus-score-get): Turned into a defsubst.
        (gnus-score-find-bnews): Slightly less funcalling.
 
index 6c472b7..2ad1c0b 100644 (file)
@@ -27,6 +27,7 @@
 
 (require 'custom)
 (require 'gnus-ems)
+(require 'browse-url)
 
 ;; The following is just helper functions and data, not ment to be set
 ;; by the user.
index 975ddf7..5163c2f 100644 (file)
@@ -84,6 +84,9 @@
  '(progn
     (if (string-match "XEmacs\\|Lucid" emacs-version)
        ()
+
+      (defvar gnus-mouse-face-prop 'mouse-face)
+
       ;; Added by Per Abrahamsen <amanda@iesd.auc.dk>.
       (defvar gnus-display-type 
        (condition-case nil
index 8d08c9c..f61075e 100644 (file)
@@ -464,6 +464,7 @@ header line with the old Message-ID."
 Type \\[describe-mode] in the buffer to get a list of commands."
   (interactive (list t))
   (let* ((group (or group gnus-newsgroup-name))
+        (pgroup group)
         (to-address 
          (when group
            (gnus-group-get-parameter group 'to-address)))
@@ -476,7 +477,7 @@ Type \\[describe-mode] in the buffer to get a list of commands."
     (when group
       (setq group (gnus-group-real-name group)))
     (if (or to-group
-           (and (gnus-member-of-valid 'post (or group gnus-newsgroup-name))
+           (and (gnus-member-of-valid 'post (or pgroup gnus-newsgroup-name))
                 (not mailing-list)
                 (not to-address)))
        ;; This is news.
@@ -1676,10 +1677,9 @@ If INHIBIT-PROMPT, never prompt for a Subject."
         (fboundp gnus-post-prepare-function)
         (funcall gnus-post-prepare-function group))
     (goto-char (point-min))
-    (if (re-search-forward 
-        (concat "^" (regexp-quote mail-header-separator) "$") nil t)
-       (forward-line 1)
-      (goto-char (point-max)))
+    (if group
+       (re-search-forward "^Subject: " nil t)
+      (re-search-forward "^Newsgroups: " nil t))
     (run-hooks 'gnus-post-prepare-hook)
     (make-local-variable 'gnus-prev-winconf)
     (setq gnus-prev-winconf winconf)
@@ -2279,21 +2279,17 @@ Headers will be generated before sending."
 (defun gnus-inews-insert-bfcc ()
   "Insert Bcc and Fcc headers."
   (save-excursion
-    (save-restriction
-      (gnus-inews-narrow-to-headers)
-      ;; Handle author copy using BCC field.
-      (if (and gnus-mail-self-blind
+    ;; Handle author copy using BCC field.
+    (when (and gnus-mail-self-blind
               (not (mail-fetch-field "bcc")))
-         (progn
-           (mail-position-on-field "Bcc")
-           (insert (if (stringp gnus-mail-self-blind)
-                       gnus-mail-self-blind
-                     (user-login-name)))))
-      ;; Handle author copy using FCC field.
-      (if gnus-author-copy
-         (progn
-           (mail-position-on-field "Fcc")
-           (insert gnus-author-copy))))))
+      (mail-position-on-field "Bcc")
+      (insert (if (stringp gnus-mail-self-blind)
+                 gnus-mail-self-blind
+               (user-login-name))))
+    ;; Handle author copy using FCC field.
+    (when gnus-author-copy
+      (mail-position-on-field "Fcc")
+      (insert gnus-author-copy))))
 
 (defun gnus-inews-insert-gcc ()
   (let* ((group gnus-outgoing-message-group)
index e575d0b..4685d62 100644 (file)
@@ -29,6 +29,8 @@
 (require 'gnus-ems)
 (require 'easymenu)
 (require 'custom)
+(require 'browse-url)
+(eval-when-compile (require 'cl))
 
 (defvar gnus-group-menu-hook nil
   "*Hook run after the creation of the group mode menu.")
           (assq (1+ lines) gnus-cite-attribution-alist)))
      gnus-button-message-id 3)
     ;; This is how URLs _should_ be embedded in text...
-    ("<URL:\\([^\n\r>]*\\)>" 0 t gnus-button-url 1)
+    ("<URL:\\([^\n\r>]*\\)>" 0 t browse-url-browser-function 1)
     ;; Next regexp stolen from highlight-headers.el.
     ;; Modified by Vladimir Alexiev.
-    (,gnus-button-url-regexp 0 t gnus-button-url 0))
+    (,gnus-button-url-regexp 0 t browse-url-browser-function 0))
   "Alist of regexps matching buttons in article bodies.
 
 Each entry has the form (REGEXP BUTTON FORM CALLBACK PAR...), where
@@ -242,7 +244,7 @@ variable it the real callback function.")
     ("^\\(From\\|Reply-To\\): " ": *\\(.+\\)$" 1 t gnus-button-reply 0)
     ("^\\(Cc\\|To\\):" "[^ \t\n<>,()\"]+@[^ \t\n<>,()\"]+" 
      0 t gnus-button-mailto 0)
-    ("^X-[Uu][Rr][Ll]:" ,gnus-button-url-regexp 0 t gnus-button-url 0))
+    ("^X-[Uu][Rr][Ll]:" ,gnus-button-url-regexp 0 t browse-url-browser-function 0))
   "Alist of headers and regexps to match buttons in article heads.
 
 This alist is very similar to `gnus-button-alist', except that each
@@ -257,22 +259,6 @@ HEADER is a regexp to match a header.  For a fuller explanation, see
 ;(eval-when-compile
 ;  (defvar browse-url-browser-function))
 
-;see gnus-cus.el
-;(defvar gnus-button-url
-;  (cond ((boundp 'browse-url-browser-function) browse-url-browser-function)
-;      ((fboundp 'w3-fetch) 'w3-fetch)
-;      ((eq window-system 'x) 'gnus-netscape-open-url))
-;  "*Function to fetch URL.
-;The function will be called with one argument, the URL to fetch.
-;Useful values of this function are:
-
-;w3-fetch: 
-;   defined in the w3 emacs package by William M. Perry.
-;gnus-netscape-open-url:
-;   open url in existing netscape, start netscape if none found.
-;gnus-netscape-start-url:
-;   start new netscape with url.")
-
 \f
 
 (eval-and-compile
@@ -935,13 +921,13 @@ If nil, the user will be asked for a duration.")
        (let* ((beg (progn (beginning-of-line) (point)))
               (end (progn (end-of-line) (point)))
               ;; Fix by Mike Dugan <dugan@bucrf16.bu.edu>.
-              (from (if (get-text-property beg 'mouse-face
+              (from (if (get-text-property beg gnus-mouse-face-prop
                         beg
                       (1+ (or (next-single-property-change 
-                               beg 'mouse-face nil end) 
+                               beg gnus-mouse-face-prop nil end) 
                               beg))))
               (to (1- (or (next-single-property-change
-                           from 'mouse-face nil end)
+                           from gnus-mouse-face-prop nil end)
                           end))))
          ;; If no mouse-face prop on line (e.g. xemacs) we 
          ;; will have to = from = end, so we highlight the
@@ -1131,7 +1117,7 @@ The following commands are available:
               (prog2 (insert (car button)) (point) (insert " "))
               (list 'gnus-callback (cdr button)
                     'face gnus-carpal-button-face
-                    'mouse-face 'highlight))))
+                    gnus-mouse-face-prop 'highlight))))
          (let ((fill-column (- (window-width) 2)))
            (fill-region (point-min) (point-max)))
          (set-window-point (get-buffer-window (current-buffer)) 
@@ -1414,7 +1400,7 @@ specified by `gnus-button-alist'."
   (add-text-properties 
    from to
    (nconc (and gnus-article-mouse-face
-              (list 'mouse-face gnus-article-mouse-face))
+              (list gnus-mouse-face-prop gnus-article-mouse-face))
          (list 'gnus-callback fun)
          (and data (list 'gnus-data data)))))
 
index cf172f6..90442ef 100644 (file)
@@ -135,7 +135,7 @@ It is provided only to ease porting of broken FSF Emacs programs."
        (progn
          (setq info (nth 2 entry))
          (gnus-group-insert-group-line 
-          nil group (gnus-info-group info) (gnus-info-marks info)
+          nil group (gnus-info-level info) (gnus-info-marks info)
           (car entry) (gnus-info-method info)))
       (setq active (gnus-gethash group gnus-active-hashtb))
          
@@ -258,6 +258,8 @@ call it with the value of the `gnus-data' text property."
   (or (boundp 'standard-display-table) (setq standard-display-table nil))
   (or (boundp 'read-event) (fset 'read-event 'next-command-event))
 
+  (defvar gnus-mouse-face-prop 'highlight)
+      
   ;; Fix by "jeff (j.d.) sparkes" <jsparkes@bnr.ca>.
   (defvar gnus-display-type (device-class)
     "A symbol indicating the display Emacs is running under.
index 514bac7..f96d8f2 100644 (file)
@@ -1433,7 +1433,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.13"
+(defconst gnus-version "September Gnus v0.14"
   "Version number for this version of Gnus.")
 
 (defvar gnus-info-nodes
@@ -1647,7 +1647,7 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
                      gnus-tmp-name))
            gnus-tmp-closing-bracket
            " " gnus-tmp-subject-or-nil "\n")
-    (put-text-property b (+ b 28) 'mouse-face gnus-mouse-face)))
+    (put-text-property b (+ b 28) gnus-mouse-face-prop gnus-mouse-face)))
 (defvar gnus-summary-line-format-spec 
   (gnus-byte-code 'gnus-summary-line-format-spec))
 
@@ -1662,7 +1662,7 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
    (format "%5s: " gnus-tmp-number-of-unread-unticked))
   (let ((b (point)))
     (insert gnus-tmp-group "\n")
-    (put-text-property b (1- (point)) 'mouse-face gnus-mouse-face)))
+    (put-text-property b (1- (point)) gnus-mouse-face-prop gnus-mouse-face)))
 (defvar gnus-group-line-format-spec 
   (gnus-byte-code 'gnus-group-line-format-spec))
 
@@ -1890,16 +1890,27 @@ Thank you for your help in stamping out bugs.
 
 (defmacro gnus-gethash (string hashtable)
   "Get hash value of STRING in HASHTABLE."
-  ;;(` (symbol-value (abbrev-symbol (, string) (, hashtable))))
-  ;;(` (abbrev-expansion (, string) (, hashtable)))
   (` (symbol-value (intern-soft (, string) (, hashtable)))))
 
 (defmacro gnus-sethash (string value hashtable)
   "Set hash value.  Arguments are STRING, VALUE, and HASHTABLE."
-  ;; We cannot use define-abbrev since it only accepts string as value.
-  ;; (set (intern string hashtable) value))
   (` (set (intern (, string) (, hashtable)) (, value))))
 
+(defmacro gnus-intern-safe (string hashtable)
+  "Set hash value.  Arguments are STRING, VALUE, and HASHTABLE."
+  `(let ((symbol (intern ,string ,hashtable)))
+     (or (boundp symbol)
+        (setq symbol nil))
+     symbol))
+
+(defmacro gnus-active (group)
+  "Get active info on GROUP."
+  `(gnus-gethash ,group gnus-active-hashtb))
+
+(defmacro gnus-set-active (group active)
+  "Set GROUP's active info."
+  `(gnus-sethash ,group ,active gnus-active-hashtb))
+
 ;; modified by MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;;   function `substring' might cut on a middle of multi-octet
 ;;   character.
@@ -2142,7 +2153,7 @@ Thank you for your help in stamping out bugs.
   (save-excursion
     (let ((gnus-process-mark 128)
          (gnus-group-marked '("dummy.group")))
-      (gnus-sethash "dummy.group" '(0 . 0) gnus-active-hashtb)
+      (gnus-set-active "dummy.group" '(0 . 0))
       (gnus-set-work-buffer)
       (gnus-group-insert-group-line nil "dummy.group" 0 nil 0 nil)
       (goto-char (point-min))
@@ -2153,13 +2164,13 @@ Thank you for your help in stamping out bugs.
 (defun gnus-mouse-face-function (form)
   (` (put-text-property
       (point) (progn (insert (, form)) (point))
-      'mouse-face gnus-mouse-face)))
+      ,gnus-mouse-face-prop gnus-mouse-face)))
 
 (defun gnus-max-width-function (el max-width)
   (or (numberp max-width) (signal 'wrong-type-argument '(numberp max-width)))
   (` (let ((val (eval (, el))))
        (if (numberp val)
-          (setq val (int-to-string val) val))
+          (setq val (int-to-string val)))
        (if (> (length val) (, max-width))
           (substring val 0 (, max-width))
         val))))
@@ -2640,6 +2651,7 @@ If optional argument RE-ONLY is non-nil, strip `Re:' only."
        gnus-newsgroup-headers nil
        gnus-newsgroup-name nil
        gnus-server-alist nil
+       gnus-opened-servers nil
        gnus-current-select-method nil)
   ;; Reset any score variables.
   (and gnus-use-scoring (gnus-score-close))
@@ -3818,14 +3830,16 @@ listed."
        ;; one.  If no next one can be found, just leave point at the
        ;; first newsgroup in the buffer.
        (if (not (gnus-goto-char
-                 (text-property-any (point-min) (point-max) 
-                                    'gnus-group (intern group))))
+                 (text-property-any
+                  (point-min) (point-max) 
+                  'gnus-group (gnus-intern-safe group gnus-active-hashtb))))
            (let ((newsrc (nthcdr 3 (gnus-gethash group gnus-newsrc-hashtb))))
              (while (and newsrc
                          (not (gnus-goto-char 
                                (text-property-any 
                                 (point-min) (point-max) 'gnus-group 
-                                (intern (car (car newsrc)))))))
+                                (gnus-intern-safe 
+                                 (car (car newsrc)) gnus-active-hashtb)))))
                (setq newsrc (cdr newsrc)))
              (or newsrc (progn (goto-char (point-max))
                                (forward-line -1))))))
@@ -3893,7 +3907,7 @@ If REGEXP, only list groups matching REGEXP."
            (add-text-properties 
             (point) (prog1 (1+ (point))
                       (insert " " mark "     *: " group "\n"))
-            (list 'gnus-group (intern group)
+            (list 'gnus-group (gnus-intern-safe group gnus-active-hashtb)
                   'gnus-unread t
                   'gnus-level level))))
       ;; This loop is used when listing all groups.
@@ -3902,7 +3916,7 @@ If REGEXP, only list groups matching REGEXP."
         (point) (prog1 (1+ (point))
                   (insert " " mark "     *: " 
                           (setq group (pop groups)) "\n"))
-        (list 'gnus-group (intern group)
+        (list 'gnus-group (gnus-intern-safe group gnus-active-hashtb)
               'gnus-unread t
               'gnus-level level))))))
 
@@ -4079,7 +4093,7 @@ increase the score of each group you read."
        (progn
          (setcar (nthcdr 2 entry) info)
          (if (and (not (eq (car entry) t)) 
-                  (gnus-gethash (gnus-info-group info) gnus-active-hashtb))
+                  (gnus-active (gnus-info-group info)))
              (let ((marked (gnus-info-marks info)))
                (setcar entry (length (gnus-list-of-unread-articles 
                                       (car info)))))))
@@ -4112,21 +4126,25 @@ increase the score of each group you read."
        active info)
     (if entry
        (progn
+         ;; (Un)subscribed group.
          (setq info (nth 2 entry))
          (gnus-group-insert-group-line 
           nil group (gnus-info-level info) (gnus-info-marks info)
           (car entry) (gnus-info-method info)))
-      (setq active (gnus-gethash group gnus-active-hashtb))
+      ;; This group is dead.
       (gnus-group-insert-group-line 
        nil group 
        (if (member group gnus-zombie-list) gnus-level-zombie gnus-level-killed)
-       nil (if active (- (1+ (cdr active)) (car active)) 0) nil))))
+       nil 
+       (if (setq active (gnus-active group))
+          (- (1+ (cdr active)) (car active)) 0) 
+       nil))))
 
 (defun gnus-group-insert-group-line 
   (gformat gnus-tmp-group gnus-tmp-level gnus-tmp-marked gnus-tmp-number
           gnus-tmp-method)
   (let* ((gformat (or gformat gnus-group-line-format-spec))
-        (gnus-tmp-active (gnus-gethash gnus-tmp-group gnus-active-hashtb))
+        (gnus-tmp-active (gnus-active gnus-tmp-group))
         (gnus-tmp-number-total 
          (if gnus-tmp-active 
              (1+ (- (cdr gnus-tmp-active) (car gnus-tmp-active)))
@@ -4187,7 +4205,8 @@ increase the score of each group you read."
     (eval gformat)
 
     (add-text-properties 
-     b (1+ b) (list 'gnus-group (intern gnus-tmp-group)
+     b (1+ b) (list 'gnus-group (gnus-intern-safe
+                                gnus-tmp-group gnus-active-hashtb)
                    'gnus-unread (if (numberp gnus-tmp-number)
                                     (string-to-int 
                                      gnus-tmp-number-of-unread-unticked)
@@ -4204,7 +4223,7 @@ already."
     ;; The buffer may be narrowed.
     (save-restriction
       (widen)
-      (let ((ident (intern group))
+      (let ((ident (gnus-intern-safe group gnus-active-hashtb))
            (loc (point-min))
            found buffer-read-only visible)
        ;; Enter the current status into the dribble buffer.
@@ -4233,7 +4252,9 @@ already."
                         (gnus-goto-char
                          (text-property-any
                           (point-min) (point-max) 
-                          'gnus-group (intern (car (car entry)))))))
+                          'gnus-group (gnus-intern-safe 
+                                       (car (car entry)) 
+                                       gnus-active-hashtb)))))
              (setq entry (cdr entry)))
            (or entry (goto-char (point-max))))
          ;; Finally insert the line.
@@ -4412,7 +4433,7 @@ group."
       (setq number
            (cond ((numberp all) all)
                  (entry (car entry))
-                 ((setq active (gnus-gethash group gnus-active-hashtb))
+                 ((setq active (gnus-active group))
                   (- (1+ (cdr active)) (car active)))))
       (gnus-summary-read-group 
        group (or all (and (numberp number) 
@@ -4484,26 +4505,29 @@ Returns whether the fetching was successful or not."
       (error "Empty group name"))
 
   (let ((b (text-property-any 
-           (point-min) (point-max) 'gnus-group (intern group))))
+           (point-min) (point-max) 
+           'gnus-group (gnus-intern-safe group gnus-active-hashtb))))
     (if b
        ;; Either go to the line in the group buffer...
        (goto-char b)
       ;; ... or insert the line.
       (or
-       (gnus-gethash group gnus-active-hashtb)
+       (gnus-active group)
        (gnus-activate-group group)
        (error "%s error: %s" group (gnus-status-message group)))
 
       (gnus-group-update-group group)
       (goto-char (text-property-any 
-                 (point-min) (point-max) 'gnus-group (intern group)))))
+                 (point-min) (point-max)
+                 'gnus-group (gnus-intern-safe group gnus-active-hashtb)))))
   ;; Adjust cursor point.
   (gnus-group-position-point))
 
 (defun gnus-group-goto-group (group)
   "Goto to newsgroup GROUP."
   (let ((b (text-property-any (point-min) (point-max) 
-                             'gnus-group (intern group))))
+                             'gnus-group (gnus-intern-safe
+                                          group gnus-active-hashtb))))
     (and b (goto-char b))))
 
 (defun gnus-group-next-group (n)
@@ -4640,7 +4664,7 @@ ADDRESS."
            (gnus-gethash (gnus-group-group-name)
                          gnus-newsrc-hashtb))
        t)
-      (gnus-sethash nname (cons 1 0) gnus-active-hashtb)
+      (gnus-set-active nname (cons 1 0))
       (or (gnus-ephemeral-group-p name)
          (gnus-dribble-enter 
           (concat "(gnus-group-set-info '" (prin1-to-string (cdr info)) ")")))
@@ -5218,7 +5242,7 @@ New newsgroup is added to .newsrc automatically."
       (gnus-group-update-group group))
      ((and (stringp group)
           (or (not (memq gnus-select-method gnus-have-read-active-file))
-              (gnus-gethash group gnus-active-hashtb)))
+              (gnus-active group)))
       ;; Add new newsgroup.
       (gnus-group-change-level 
        group 
@@ -5462,7 +5486,7 @@ If N is negative, this group and the N-1 previous groups will be checked."
 (defun gnus-get-new-news-in-group (group)
   (when (and group (gnus-activate-group group 'scan))
     (gnus-get-unread-articles-in-group 
-     (gnus-get-info group) (gnus-gethash group gnus-active-hashtb))
+     (gnus-get-info group) (gnus-active group))
     (gnus-group-update-group-line)
     t))
 
@@ -5548,7 +5572,7 @@ If N is negative, this group and the N-1 previous groups will be checked."
        (mapatoms 
         (lambda (group)
           (and (string-match regexp (symbol-value group))
-               (gnus-gethash (symbol-name group) gnus-active-hashtb)
+               (gnus-active (symbol-name group))
                (setq groups (cons (symbol-name group) groups))))
         gnus-description-hashtb))
     (if (not groups)
@@ -6543,7 +6567,9 @@ article number."
   '(progn
      (gnus-summary-skip-intangible)
      (or (get-text-property (point) 'gnus-number) 
-        gnus-newsgroup-end)))
+        (progn
+          (forward-line -1)
+          gnus-newsgroup-end))))
 
 (defmacro gnus-summary-article-header (&optional number)
   (` (gnus-data-header (gnus-data-find
@@ -6876,7 +6902,7 @@ If NO-DISPLAY, don't generate a summary buffer."
       ;; Save the active value in effect when the group was entered.
       (setq gnus-newsgroup-active 
            (gnus-copy-sequence
-            (gnus-gethash gnus-newsgroup-name gnus-active-hashtb)))
+            (gnus-active gnus-newsgroup-name)))
       ;; You can change the summary buffer in some way with this hook.
       (run-hooks 'gnus-select-group-hook)
       ;; Set any local variables in the group parameters.
@@ -7147,7 +7173,7 @@ If NO-DISPLAY, don't generate a summary buffer."
                        sub nil))
                (setq sub (cdr sub))))
          ;; It's an ordinary thread, so we check it.
-         (when (member (car sub) headers)
+         (when (eq (car sub) (car headers))
            (setq thread sub
                  threads nil)))
        (setq threads (cdr threads)))
@@ -7530,7 +7556,7 @@ If READ-ALL is non-nil, all articles in the group are selected."
           (let ((name (intern (format "gnus-newsgroup-%s" (car thing)))))
             (set name (copy-sequence (cdr (assq (cdr thing) marked))))))
         '((marked . tick) (replied . reply) 
-          (exirable . expire) (killed . killed)
+          (expirable . expire) (killed . killed)
           (bookmarks . bookmark) (dormant . dormant)
           (scored . score)))))
 
@@ -7601,11 +7627,9 @@ If READ-ALL is non-nil, all articles in the group are selected."
          ;; Select all articles if `read-all' is non-nil, or if there
          ;; are no unread articles.
          (if (or read-all
-                 (zerop (length gnus-newsgroup-unreads)))
-             (if (zerop (length gnus-newsgroup-marked))
-                 (gnus-uncompress-range 
-                  (gnus-gethash group gnus-active-hashtb))
-               gnus-newsgroup-marked)
+                 (and (zerop (length gnus-newsgroup-marked))
+                      (zerop (length gnus-newsgroup-unreads))))
+             (gnus-uncompress-range (gnus-active group))
            (sort (append gnus-newsgroup-dormant gnus-newsgroup-marked 
                          (copy-sequence gnus-newsgroup-unreads))
                  '<)))
@@ -7620,27 +7644,25 @@ If READ-ALL is non-nil, all articles in the group are selected."
            read-all)
           (t
            (condition-case ()
-               (cond ((and (or (<= scored marked)
-                               (= scored number))
-                           (numberp gnus-large-newsgroup)
-                           (> number gnus-large-newsgroup))
-                      (let ((input
-                             (read-string
-                              (format
-                               "How many articles from %s (default %d): "
-                               gnus-newsgroup-name number))))
-                        (if (string-match "^[ \t]*$" input)
-                            number input)))
-                     ((and (> scored marked) (< scored number))
-                      (let ((input
-                             (read-string
-                              (format 
-                               "%s %s (%d scored, %d total): "
-                               "How many articles from"
-                               group scored number))))
-                        (if (string-match "^[ \t]*$" input)
-                            number input)))
-                     (t number))
+               (cond 
+                ((and (or (<= scored marked) (= scored number))
+                      (numberp gnus-large-newsgroup)
+                      (> number gnus-large-newsgroup))
+                 (let ((input
+                        (read-string
+                         (format
+                          "How many articles from %s (default %d): "
+                          gnus-newsgroup-name number))))
+                   (if (string-match "^[ \t]*$" input) number input)))
+                ((and (> scored marked) (< scored number))
+                 (let ((input
+                        (read-string
+                         (format "%s %s (%d scored, %d total): "
+                                 "How many articles from"
+                                 group scored number))))
+                   (if (string-match "^[ \t]*$" input)
+                       number input)))
+                (t number))
              (quit nil))))))
     (setq select (if (stringp select) (string-to-number select) select))
     (if (or (null select) (zerop select))
@@ -7674,8 +7696,7 @@ If READ-ALL is non-nil, all articles in the group are selected."
 (defun gnus-adjust-marked-articles (info &optional active)
   "Remove all marked articles that are no longer legal."
   (let* ((marked-lists (gnus-info-marks info))
-        (active (or active (gnus-gethash (gnus-info-group info)
-                                         gnus-active-hashtb)))
+        (active (or active (gnus-active (gnus-info-group info))))
         (min (car active))
         m prev)
     ;; There are many types of marked articles.
@@ -7915,7 +7936,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
   (let* ((num 0)
         (entry (gnus-gethash group gnus-newsrc-hashtb))
         (info (nth 2 entry))
-        (active (gnus-gethash group gnus-active-hashtb))
+        (active (gnus-active group))
         exps expirable range)
     ;; First peel off all illegal article numbers.
     (if active
@@ -8250,8 +8271,7 @@ list of headers that match SEQUENCE (see `nntp-retrieve-headers')."
             (set id-dep (list header)))))
     (if header
        (progn
-         (if (boundp (setq ref-dep (intern (or ref "none") 
-                                           dependencies)))
+         (if (boundp (setq ref-dep (intern (or ref "none") dependencies)))
              (setcdr (symbol-value ref-dep) 
                      (nconc (cdr (symbol-value ref-dep))
                             (list (symbol-value id-dep))))
@@ -8285,21 +8305,19 @@ This is meant to be called in `gnus-article-internal-prepare-hook'."
   "Find article ID and insert the summary line for that article."
   (let ((header (gnus-read-header id))
        number)
-    (if (not header)
-       () ; We couldn't fetch ID.
+    (when header
       ;; Rebuild the thread that this article is part of and go to the
       ;; article we have fetched.
       (gnus-rebuild-thread (mail-header-id header))
       (gnus-summary-goto-subject (setq number (mail-header-number header)))
-      (and (> number 0)
-          (progn
-            ;; We have to update the boundaries, possibly.
-            (and (> number gnus-newsgroup-end)
-                 (setq gnus-newsgroup-end number))
-            (and (< number gnus-newsgroup-begin)
-                 (setq gnus-newsgroup-begin number))
-            (setq gnus-newsgroup-unselected
-                  (delq number gnus-newsgroup-unselected))))
+      (when (> number 0)
+       ;; We have to update the boundaries, possibly.
+       (and (> number gnus-newsgroup-end)
+            (setq gnus-newsgroup-end number))
+       (and (< number gnus-newsgroup-begin)
+            (setq gnus-newsgroup-begin number))
+       (setq gnus-newsgroup-unselected
+             (delq number gnus-newsgroup-unselected)))
       ;; Report back a success.
       number)))
 
@@ -8479,7 +8497,7 @@ displayed, no centering will be performed."
 ;; the range of active articles.
 (defun gnus-list-of-unread-articles (group)
   (let* ((read (gnus-info-read (gnus-get-info group)))
-        (active (gnus-gethash group gnus-active-hashtb))
+        (active (gnus-active group))
         (last (cdr active))
         first nlast unread)
     ;; If none are read, then all are unread. 
@@ -8514,7 +8532,7 @@ displayed, no centering will be performed."
 (defun gnus-list-of-read-articles (group)
   (let* ((info (gnus-get-info group))
         (marked (gnus-info-marks info))
-        (active (gnus-gethash group gnus-active-hashtb)))
+        (active (gnus-active group)))
     (and info active
         (gnus-set-difference
          (gnus-sorted-complement 
@@ -9500,15 +9518,14 @@ Return how many articles were fetched."
 (defun gnus-summary-refer-article (message-id)
   "Fetch an article specified by MESSAGE-ID."
   (interactive "sMessage-ID: ")
-  (if (or (not (stringp message-id))
-         (zerop (length message-id)))
-      ()
+  (when (and (stringp message-id)
+            (not (zerop (length message-id))))
     ;; Construct the correct Message-ID if necessary.
     ;; Suggested by tale@pawl.rpi.edu.
-    (or (string-match "^<" message-id)
-       (setq message-id (concat "<" message-id)))
-    (or (string-match ">$" message-id)
-       (setq message-id (concat message-id ">")))
+    (unless (string-match "^<" message-id)
+      (setq message-id (concat "<" message-id)))
+    (unless (string-match ">$" message-id)
+      (setq message-id (concat message-id ">")))
     (let ((header (car (gnus-gethash (downcase message-id)
                                     gnus-newsgroup-dependencies))))
       (if header
@@ -9516,12 +9533,11 @@ Return how many articles were fetched."
          (gnus-summary-goto-article (mail-header-number header) nil t)
        ;; We fetch the article
        (let ((gnus-override-method gnus-refer-article-method)
-             (gnus-ancient-mark gnus-read-mark)
-             (tmp-point (window-start
-                         (get-buffer-window gnus-article-buffer)))
-             number tmp-buf)
-         (and gnus-refer-article-method
-              (gnus-check-server gnus-refer-article-method))
+             number)
+         ;; Start the special refer-article method, if necessary.
+         (when gnus-refer-article-method
+           (gnus-check-server gnus-refer-article-method))
+         ;; Fetch the header, and display the article.
          (when (setq number (gnus-summary-insert-subject message-id))
            (gnus-summary-select-article nil nil nil number)))))))
 
@@ -9851,7 +9867,7 @@ and `request-accept' functions. (Ie. mail newsgroups at present.)"
         (progn
           (if (or (string= to-newsgroup "") (string= to-newsgroup prefix))
               (setq to-newsgroup (or gnus-current-move-group "")))
-          (or (gnus-gethash to-newsgroup gnus-active-hashtb)
+          (or (gnus-active to-newsgroup)
              (gnus-activate-group to-newsgroup)
               (error "No such group: %s" to-newsgroup))
           (setq gnus-current-move-group to-newsgroup)))
@@ -10003,7 +10019,7 @@ functions. (Ie. mail newsgroups at present.)"
         (progn
           (if (or (string= to-newsgroup "") (string= to-newsgroup prefix))
               (setq to-newsgroup (or gnus-current-move-group "")))
-          (or (gnus-gethash to-newsgroup gnus-active-hashtb)
+          (or (gnus-active to-newsgroup)
              (gnus-activate-group to-newsgroup)
               (error "No such group: %s" to-newsgroup))
           (setq gnus-current-move-group to-newsgroup)))
@@ -10625,18 +10641,16 @@ marked."
   (let ((forward (cdr (assq type gnus-summary-mark-positions)))
        (buffer-read-only nil)
        plist)
-    (if (not forward)
-       ()
+    (when forward
       ;; Go to the right position on the line.
       (forward-char forward)
       ;; Replace the old mark with the new mark.
       (subst-char-in-region (point) (1+ (point)) (following-char) mark)
       ;; Optionally update the marks by some user rule.
-      (and (eq type 'unread)
-          (progn
-            (gnus-data-set-mark (gnus-data-find (gnus-summary-article-number))
-                                mark)
-            (gnus-summary-update-line (eq mark gnus-unread-mark)))))))
+      (when (eq type 'unread)
+       (gnus-data-set-mark 
+        (gnus-data-find (gnus-summary-article-number)) mark)
+       (gnus-summary-update-line (eq mark gnus-unread-mark))))))
   
 (defun gnus-mark-article-as-read (article &optional mark)
   "Enter ARTICLE in the pertinent lists and remove it from others."
@@ -11868,7 +11882,8 @@ The following commands are available:
            (erase-buffer)
            ;; There may be some overlays that we have to kill...
            (insert "i")
-           (let ((overlays (overlays-at (point-min))))
+           (let ((overlays (and (fboundp 'overlays-at)
+                                (overlays-at (point-min)))))
              (while overlays
                (delete-overlay (car overlays))
                (setq overlays (cdr overlays))))
@@ -12249,17 +12264,18 @@ Provided for backwards compatability."
 (defun gnus-headers-decode-quoted-printable ()
   "Hack to remove QP encoding from headers."
   (let ((case-fold-search t)
+       (inhibit-point-motion-hooks t)
        string)
     (goto-char (point-min))
-    (while (re-search-forward "=?iso-8859-1?q?\\([^ \t\n]*\\)?=" nil t)
-      (replace-match (setq string (match-string 1)) t t)
-      (narrow-to-region 
-       (match-beginning 0) (+ (match-beginning 0) (length string)))
-      (goto-char (point-min))
-      (while (search-forward "_" nil t)
-       (replace-match " "))
-      (gnus-mime-decode-quoted-printable (point-min) (point-max))
-      (widen))))
+    (while (re-search-forward "=\\?iso-8859-1\\?q\\?\\([^?\t\n]*\\)\\?=" nil t)
+      (setq string (match-string 1))
+      (narrow-to-region (match-beginning 0) (match-end 0))
+      (delete-region (point-min) (point-max))
+      (insert string)
+      (gnus-mime-decode-quoted-printable (goto-char (point-min)) (point-max))
+      (subst-char-in-region (point-min) (point-max) ?_ ? )
+      (widen)
+      (goto-char (point-min)))))
        
 (defun gnus-article-de-quoted-unreadable (&optional force)
   "Do a naive translation of a quoted-printable-encoded article.
@@ -12282,7 +12298,7 @@ or not."
        (gnus-headers-decode-quoted-printable)))))
 
 (defun gnus-mime-decode-quoted-printable (from to)
-  ;; Decode quoted-printable from region between FROM and TO.
+  "Decode Quoted-Printable in the region between FROM and TO."
   (goto-char from)
   (while (search-forward "=" to t)
     (cond ((eq (following-char) ?\n)
@@ -12353,7 +12369,8 @@ how much time has lapsed since DATE."
          (gnus-narrow-to-headers)
          (let ((buffer-read-only nil))
            ;; Delete any old Date headers.
-           (when (zerop (nnheader-remove-header date-regexp t))
+           (if (zerop (nnheader-remove-header date-regexp t))
+               (beginning-of-line)
              (goto-char (point-max)))
            (insert
             (cond 
@@ -12959,9 +12976,9 @@ is returned insted of the status string."
             (funcall (gnus-get-function method 'open-server)
                      (nth 1 method) (nthcdr 2 method))))
        ;; If this hasn't been opened before, we add it to the list.
-       (or elem 
-           (setq elem (list method nil)
-                 gnus-opened-servers (cons elem gnus-opened-servers)))
+       (unless elem 
+         (setq elem (list method nil)
+               gnus-opened-servers (cons elem gnus-opened-servers)))
        ;; Set the status of this server.
        (setcar (cdr elem) (if result 'ok 'denied))
        ;; Return the result from the "open" call.
@@ -13378,7 +13395,7 @@ The `-n' option line from .newsrc is respected."
           ;; The group is already known.
           ()
         (and (symbol-value group-sym)
-             (gnus-sethash group (symbol-value group-sym) gnus-active-hashtb))
+             (gnus-set-active group (symbol-value group-sym)))
         (let ((do-sub (gnus-matches-options-n group)))
           (cond ((eq do-sub 'subscribe)
                  (setq groups (1+ groups))
@@ -13431,7 +13448,7 @@ The `-n' option line from .newsrc is respected."
                 (setq gnus-killed-list (cons group gnus-killed-list)))))))
         gnus-active-hashtb)
        (while groups
-         (if (gnus-gethash (car groups) gnus-active-hashtb)
+         (if (gnus-active (car groups))
              (gnus-group-change-level 
               (car groups) gnus-level-default-subscribed gnus-level-killed))
          (setq groups (cdr groups)))
@@ -13532,7 +13549,7 @@ The `-n' option line from .newsrc is respected."
                       (progn
                         (setq info (cdr entry))
                         (setq num (car entry)))
-                    (setq active (gnus-gethash group gnus-active-hashtb))
+                    (setq active (gnus-active group))
                     (setq num 
                           (if active (- (1+ (cdr active)) (car active)) t))
                     ;; Check whether the group is foreign.  If so, the
@@ -13582,7 +13599,7 @@ newsgroup."
     ;; Find all bogus newsgroup that are subscribed.
     (while newsrc
       (setq group (car (car newsrc)))
-      (if (or (gnus-gethash group gnus-active-hashtb) ; Active
+      (if (or (gnus-active group) ; Active
              (nth 4 (car newsrc))      ; Foreign
              (and confirm
                   (not (gnus-y-or-n-p
@@ -13608,7 +13625,7 @@ newsgroup."
        (setq killed (symbol-value (car dead-lists)))
        (while killed
          (setq group (car killed))
-         (or (gnus-gethash group gnus-active-hashtb)
+         (or (gnus-active group)
              ;; The group is bogus.
              (set (car dead-lists)
                   (delete group (symbol-value (car dead-lists)))))
@@ -13648,7 +13665,7 @@ newsgroup."
     (while newsrc
       (setq info (car newsrc)
            group (gnus-info-group info)
-           active (gnus-gethash group gnus-active-hashtb))
+           active (gnus-active group))
 
       ;; Check newsgroups.  If the user doesn't want to check them, or
       ;; they can't be checked (for instance, if the news server can't
@@ -13691,7 +13708,7 @@ newsgroup."
          (gnus-get-unread-articles-in-group info active)
        ;; The group couldn't be reached, so we nix out the number of
        ;; unread articles and stuff.
-       (gnus-sethash group nil gnus-active-hashtb)
+       (gnus-set-active group nil)
        (setcar (gnus-gethash group gnus-newsrc-hashtb) t))
 
       (setq newsrc (cdr newsrc)))
@@ -13833,10 +13850,9 @@ newsgroup."
           (and (looking-at "[0-9]+ [0-9]+ \\([0-9]+\\) [0-9]+")
                (progn
                  (goto-char (match-beginning 1))
-                 (gnus-sethash 
+                 (gnus-set-active 
                   group (setq active (cons (read (current-buffer))
-                                           (read (current-buffer))))
-                  gnus-active-hashtb)
+                                           (read (current-buffer)))))
                  ;; Return the new active info.
                  active))))))
 
@@ -13847,8 +13863,7 @@ newsgroup."
 UNREAD and TICKED lists.
 Note: UNSELECTED has to be sorted over `<'.
 Returns whether the updating was successful."
-  (let* ((active (or gnus-newsgroup-active 
-                    (gnus-gethash group gnus-active-hashtb)))
+  (let* ((active (or gnus-newsgroup-active (gnus-active group)))
         (entry (gnus-gethash group gnus-newsrc-hashtb))
         (info (nth 2 entry))
         (marked (gnus-info-marks info))
@@ -13896,8 +13911,7 @@ Returns whether the updating was successful."
        (if domarks bookmark (cdr (assq 'bookmark marked)))
        (if domarks score (cdr (assq 'score marked))))
       ;; Set the number of unread articles in gnus-newsrc-hashtb.
-      (gnus-get-unread-articles-in-group 
-       info (gnus-gethash group gnus-active-hashtb))
+      (gnus-get-unread-articles-in-group info (gnus-active group))
       t)))
 
 (defun gnus-make-articles-unread (group articles)
@@ -14802,6 +14816,7 @@ If FORCE is non-nil, the .newsrc file is read."
 
 (defvar gnus-backlog-buffer " *Gnus Backlog*")
 (defvar gnus-backlog-articles nil)
+(defvar gnus-backlog-hashtb nil)
 
 (defun gnus-backlog-buffer ()
   (or (get-buffer gnus-backlog-buffer)
@@ -14811,8 +14826,15 @@ If FORCE is non-nil, the .newsrc file is read."
        (setq buffer-read-only t)
        (gnus-add-current-to-buffer-list))))
 
+(defun gnus-backlog-setup ()
+  "Initialize backlog variables."
+  (unless gnus-backlog-hashtb
+    (setq gnus-backlog-hashtb (make-vector 1023 0))))
+
 (defun gnus-backlog-enter-article (group number buffer)
-  (let ((ident (intern (concat group ":" (int-to-string number))))
+  (gnus-backlog-setup)
+  (let ((ident (intern (concat group ":" (int-to-string number))
+                      gnus-backlog-hashtb))
        b)
     (if (memq ident gnus-backlog-articles)
        () ; It's already kept.
@@ -14849,7 +14871,9 @@ If FORCE is non-nil, the .newsrc file is read."
                  (1+ (point)) 'gnus-backlog nil (point-max)))))))
 
 (defun gnus-backlog-request-article (group number buffer)
-  (let ((ident (intern (concat group ":" (int-to-string number))))
+  (gnus-backlog-setup)
+  (let ((ident (intern (concat group ":" (int-to-string number))
+                      gnus-backlog-hashtb))
        beg end)
     (if (not (memq ident gnus-backlog-articles))
        () ; It wasn't in the backlog.
index aa87f54..ed873be 100644 (file)
@@ -37,6 +37,7 @@
 ;;; Code:
 
 (require 'mail-utils)
+(eval-when-compile (require 'cl))
 
 (defvar nnheader-max-head-length 4096
   "*Max length of the head of articles.")
index ddd9de7..702e255 100644 (file)
@@ -180,159 +180,161 @@ instead call function `nntp-status-message' to get status message.")
 (defvar nntp-current-server nil)
 (defvar nntp-server-alist nil)
 (defvar nntp-server-variables 
-  (list
-   (list 'nntp-server-hook nntp-server-hook)
-   (list 'nntp-server-opened-hook nntp-server-opened-hook)
-   (list 'nntp-port-number nntp-port-number)
-   (list 'nntp-address nntp-address)
-   (list 'nntp-large-newsgroup nntp-large-newsgroup)
-   (list 'nntp-buggy-select nntp-buggy-select)
-   (list 'nntp-maximum-request nntp-maximum-request)
-   (list 'nntp-debug-read nntp-debug-read)
-   (list 'nntp-nov-is-evil nntp-nov-is-evil)
-   (list 'nntp-xover-commands nntp-xover-commands)
-   (list 'nntp-connection-timeout nntp-connection-timeout)
-   (list 'nntp-news-default-headers nntp-news-default-headers)
-   (list 'nntp-prepare-server-hook nntp-prepare-server-hook) 
-   (list 'nntp-async-number nntp-async-number)
-   '(nntp-async-process nil)
-   '(nntp-async-buffer nil)
-   '(nntp-async-articles nil)
-   '(nntp-async-fetched nil)
-   '(nntp-async-group-alist nil)
-   '(nntp-server-process nil)
-   '(nntp-status-string nil)
-   '(nntp-server-xover try)
-   '(nntp-server-list-active-group try)
-   '(nntp-current-group "")))
+  `((nntp-server-hook ,nntp-server-hook)
+    (nntp-server-opened-hook ,nntp-server-opened-hook)
+    (nntp-port-number ,nntp-port-number)
+    (nntp-address ,nntp-address)
+    (nntp-large-newsgroup ,nntp-large-newsgroup)
+    (nntp-buggy-select ,nntp-buggy-select)
+    (nntp-maximum-request ,nntp-maximum-request)
+    (nntp-debug-read ,nntp-debug-read)
+    (nntp-nov-is-evil ,nntp-nov-is-evil)
+    (nntp-xover-commands ,nntp-xover-commands)
+    (nntp-connection-timeout ,nntp-connection-timeout)
+    (nntp-news-default-headers ,nntp-news-default-headers)
+    (nntp-prepare-server-hook ,nntp-prepare-server-hook) 
+    (nntp-async-number ,nntp-async-number)
+    (nntp-async-process nil)
+    (nntp-async-buffer nil)
+    (nntp-async-articles nil)
+    (nntp-async-fetched nil)
+    (nntp-async-group-alist nil)
+    (nntp-server-process nil)
+    (nntp-status-string nil)
+    (nntp-server-xover try)
+    (nntp-server-list-active-group try)
+    (nntp-current-group "")))
 
 \f
 ;;; Interface functions.
 
-(defun nntp-retrieve-headers (sequence &optional newsgroup server fetch-old)
-  "Retrieve the headers to the articles in SEQUENCE."
-  (nntp-possibly-change-server newsgroup server)
+(defun nntp-retrieve-headers (articles &optional group server fetch-old)
+  "Retrieve the headers of ARTICLES."
+  (nntp-possibly-change-server group server)
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
     (if (and (not gnus-nov-is-evil) 
             (not nntp-nov-is-evil)
-            (nntp-retrieve-headers-with-xover sequence fetch-old))
+            (nntp-retrieve-headers-with-xover articles fetch-old))
+       ;; We successfully retrieved the headers via XOVER.
         'nov
-      (let ((number (length sequence))
+      ;; XOVER didn't work, so we do it the hard, slow and inefficient
+      ;; way.  
+      (let ((number (length articles))
            (count 0)
            (received 0)
            (last-point (point-min)))
        ;; Send HEAD command.
-       (while sequence
+       (while articles
          (nntp-send-strings-to-server 
-          "HEAD" (if (numberp (car sequence)) (int-to-string (car sequence))
-                   (car sequence)))
-         (setq sequence (cdr sequence)
+          "HEAD" (if (numberp (car articles)) 
+                     (int-to-string (car articles))
+                   ;; `articles' is either a list of article numbers
+                   ;; or a list of article IDs.
+                   (car articles)))
+         (setq articles (cdr articles)
                count (1+ count))
-         ;; Every 400 header requests we have to read stream in order
-         ;;  to avoid deadlock.
-         (if (or (null sequence)       ;All requests have been sent.
-                 (zerop (% count nntp-maximum-request)))
-             (progn
-               (nntp-accept-response)
-               (while (progn
-                        (goto-char last-point)
-                        ;; Count replies.
-                        (while (re-search-forward "^[0-9]" nil t)
-                          (setq received (1+ received)))
-                        (setq last-point (point))
-                        (< received count))
-                 ;; If number of headers is greater than 100, give
-                 ;;  informative messages.
-                 (and (numberp nntp-large-newsgroup)
-                      (> number nntp-large-newsgroup)
-                      (zerop (% received 20))
-                      (message "NNTP: Receiving headers... %d%%"
-                               (/ (* received 100) number)))
-                 (nntp-accept-response)))))
+         ;; Every 400 header requests we have to read the stream in
+         ;; order to avoid deadlocks.
+         (when (or (null articles)     ;All requests have been sent.
+                   (zerop (% count nntp-maximum-request)))
+           (nntp-accept-response)
+           (while (progn
+                    (goto-char last-point)
+                    ;; Count replies.
+                    (while (re-search-forward "^[0-9]" nil t)
+                      (setq received (1+ received)))
+                    (setq last-point (point))
+                    (< received count))
+             ;; If number of headers is greater than 100, give
+             ;;  informative messages.
+             (and (numberp nntp-large-newsgroup)
+                  (> number nntp-large-newsgroup)
+                  (zerop (% received 20))
+                  (message "NNTP: Receiving headers... %d%%"
+                           (/ (* received 100) number)))
+             (nntp-accept-response))))
        ;; Wait for text of last command.
        (goto-char (point-max))
        (re-search-backward "^[0-9]" nil t)
-       (if (looking-at "^[23]")
-           (while (progn
-                    (goto-char (- (point-max) 3))
-                    (not (looking-at "^\\.\r?\n")))
-             (nntp-accept-response)))
+       (when (looking-at "^[23]")
+         (while (progn
+                  (goto-char (- (point-max) 3))
+                  (not (looking-at "^\\.\r?\n")))
+           (nntp-accept-response)))
        (and (numberp nntp-large-newsgroup)
             (> number nntp-large-newsgroup)
             (message "NNTP: Receiving headers...done"))
 
-       ;; Now all of replies are received.
-       (setq received number)
-       ;; First, fold continuation lines.
+       ;; Now all of replies are received.  Fold continuation lines.
        (goto-char (point-min))
        (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
-         (replace-match " "))
-       ;; Remove all "\r"'s
+         (replace-match " " t t))
+       ;; Remove all "\r"'s.
        (goto-char (point-min))
        (while (search-forward "\r" nil t)
-         (replace-match ""))
+         (replace-match "" t t))
        'headers))))
 
 
 (defun nntp-retrieve-groups (groups &optional server)
+  "Retrieve group info on GROUPS."
   (nntp-possibly-change-server nil server)
   (save-excursion
     (set-buffer nntp-server-buffer)
-    (and (eq nntp-server-list-active-group 'try)
-        (nntp-try-list-active (car groups)))
+    ;; The first time this is run, this variable is `try'.  So we
+    ;; try.   
+    (when (eq nntp-server-list-active-group 'try)
+      (nntp-try-list-active (car groups)))
     (erase-buffer)
     (let ((count 0)
          (received 0)
          (last-point (point-min))
-         (command (if nntp-server-list-active-group
-                      "LIST ACTIVE" "GROUP")))
+         (command (if nntp-server-list-active-group "LIST ACTIVE" "GROUP")))
       (while groups
+       ;; Send the command to the server.
        (nntp-send-strings-to-server command (car groups))
        (setq groups (cdr groups))
        (setq count (1+ count))
        ;; Every 400 requests we have to read the stream in
        ;; order to avoid deadlocks.
-       (if (or (null groups)           ;All requests have been sent.
-               (zerop (% count nntp-maximum-request)))
-           (progn
-             (nntp-accept-response)
-             (while (progn
-                      (goto-char last-point)
-                      ;; Count replies.
-                      (while (re-search-forward "^[0-9]" nil t)
-                        (setq received (1+ received)))
-                      (setq last-point (point))
-                      (< received count))
-               (nntp-accept-response)))))
+       (when (or (null groups)         ;All requests have been sent.
+                 (zerop (% count nntp-maximum-request)))
+         (nntp-accept-response)
+         (while (progn
+                  (goto-char last-point)
+                  ;; Count replies.
+                  (while (re-search-forward "^[0-9]" nil t)
+                    (setq received (1+ received)))
+                  (setq last-point (point))
+                  (< received count))
+           (nntp-accept-response))))
 
       ;; Wait for the reply from the final command.
-      (if nntp-server-list-active-group
-         (progn
-           (goto-char (point-max))
-           (re-search-backward "^[0-9]" nil t)
-           (if (looking-at "^[23]")
-               (while (progn
-                        (goto-char (- (point-max) 3))
-                        (not (looking-at "^\\.\r?\n")))
-                 (nntp-accept-response)))))
+      (when nntp-server-list-active-group
+       (goto-char (point-max))
+       (re-search-backward "^[0-9]" nil t)
+       (when (looking-at "^[23]")
+         (while (progn
+                  (goto-char (- (point-max) 3))
+                  (not (looking-at "^\\.\r?\n")))
+           (nntp-accept-response))))
 
       ;; Now all replies are received. We remove CRs.
       (goto-char (point-min))
       (while (search-forward "\r" nil t)
        (replace-match "" t t))
 
-      (if nntp-server-list-active-group
-         (progn
-           ;; We have read active entries, so we just delete the
-           ;; superfluos gunk.
-           (goto-char (point-min))
-           (while (re-search-forward "^[.2-5]" nil t)
-             (delete-region (match-beginning 0) 
-                            (progn (forward-line 1) (point))))
-           'active)
-       'group))))
+      (if (not nntp-server-list-active-group)
+         'group
+       ;; We have read active entries, so we just delete the
+       ;; superfluos gunk.
+       (goto-char (point-min))
+       (while (re-search-forward "^[.2-5]" nil t)
+         (delete-region (match-beginning 0) 
+                        (progn (forward-line 1) (point))))
+       'active))))
 
 (defun nntp-open-server (server &optional defs)
   (nnheader-init-server-buffer)
@@ -417,22 +419,22 @@ instead call function `nntp-status-message' to get status message.")
     ;; Empty message if nothing.
     (or nntp-status-string "")))
 
-(defun nntp-request-article (id &optional newsgroup server buffer)
-  "Request article ID (message-id or number)."
-  (nntp-possibly-change-server newsgroup server)
+(defun nntp-request-article (id &optional group server buffer)
+  "Request article ID (Message-ID or number)."
+  (nntp-possibly-change-server group server)
 
   (let (found)
 
     ;; First we see whether we can get the article from the async buffer. 
-    (if (and (numberp id)
-            nntp-async-articles
-            (memq id nntp-async-fetched))
-       (save-excursion
-         (set-buffer nntp-async-buffer)
-         (let ((opoint (point))
-               (art (if (numberp id) (int-to-string id) id))
-               beg end)
-           (if (and (or (re-search-forward (concat "^2.. +" art) nil t)
+    (when (and (numberp id)
+              nntp-async-articles
+              (memq id nntp-async-fetched))
+      (save-excursion
+       (set-buffer nntp-async-buffer)
+       (let ((opoint (point))
+             (art (if (numberp id) (int-to-string id) id))
+             beg end)
+         (when (and (or (re-search-forward (concat "^2.. +" art) nil t)
                         (progn
                           (goto-char (point-min))
                           (re-search-forward (concat "^2.. +" art) opoint t)))
@@ -440,17 +442,16 @@ instead call function `nntp-status-message' to get status message.")
                       (beginning-of-line)
                       (setq beg (point)
                             end (re-search-forward "^\\.\r?\n" nil t))))
-               (progn
-                 (setq found t)
-                 (save-excursion
-                   (set-buffer (or buffer nntp-server-buffer))
-                   (erase-buffer)
-                   (insert-buffer-substring nntp-async-buffer beg end)
-                   (let ((nntp-server-buffer (current-buffer)))
-                     (nntp-decode-text)))
-                 (delete-region beg end)
-                 (and nntp-async-articles
-                      (nntp-async-fetch-articles id)))))))
+           (setq found t)
+           (save-excursion
+             (set-buffer (or buffer nntp-server-buffer))
+             (erase-buffer)
+             (insert-buffer-substring nntp-async-buffer beg end)
+             (let ((nntp-server-buffer (current-buffer)))
+               (nntp-decode-text)))
+           (delete-region beg end)
+           (when nntp-async-articles
+             (nntp-async-fetch-articles id))))))
 
     (if found 
        id
@@ -468,21 +469,21 @@ instead call function `nntp-status-message' to get status message.")
                         (nntp-find-group-and-number)))
                (nntp-decode-text)
                (and nntp-async-articles (nntp-async-fetch-articles id)))))
-       (if buffer (set-process-buffer 
-                   nntp-server-process nntp-server-buffer))))))
+       (when buffer 
+         (set-process-buffer nntp-server-process nntp-server-buffer))))))
 
-(defun nntp-request-body (id &optional newsgroup server)
-  "Request body of article ID (message-id or number)."
-  (nntp-possibly-change-server newsgroup server)
+(defun nntp-request-body (id &optional group server)
+  "Request body of article ID (Message-ID or number)."
+  (nntp-possibly-change-server group server)
   (prog1
       ;; If NEmacs, end of message may look like: "\256\215" (".^M")
       (nntp-send-command
        "^\\.\r?\n" "BODY" (or (and (numberp id) (int-to-string id)) id))
     (nntp-decode-text)))
 
-(defun nntp-request-head (id &optional newsgroup server)
-  "Request head of article ID (message-id or number)."
-  (nntp-possibly-change-server newsgroup server)
+(defun nntp-request-head (id &optional group server)
+  "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))
@@ -491,70 +492,75 @@ instead call function `nntp-status-message' to get status message.")
             (nntp-find-group-and-number)))
     (nntp-decode-text)))
 
-(defun nntp-request-stat (id &optional newsgroup server)
-  "Request STAT of article ID (message-id or number)."
-  (nntp-possibly-change-server newsgroup server)
+(defun nntp-request-stat (id &optional group server)
+  "Request STAT of article ID (Message-ID or number)."
+  (nntp-possibly-change-server group server)
   (nntp-send-command 
    "^[23].*\r?\n" "STAT" (or (and (numberp id) (int-to-string id)) id)))
 
 (defun nntp-request-group (group &optional server dont-check)
   "Select GROUP."
-  (nntp-send-command "^.*\r?\n" "GROUP" group)
-  (setq nntp-current-group group)
-  (save-excursion
-    (set-buffer nntp-server-buffer)
-    (goto-char (point-min))
-    (looking-at "[23]")))
+  (setq nntp-current-group
+       (when (nntp-send-command "^2.*\r?\n" "GROUP" group)
+         group)))
 
 (defun nntp-request-asynchronous (group &optional server articles)
-  (and nntp-async-articles (nntp-async-request-group group))
-  (and 
-   nntp-async-number
-   (if (not (or (nntp-async-server-opened)
-               (nntp-async-open-server)))
-       (progn
-        (message "Can't open second connection to %s" nntp-address)
-        (ding)
-        (setq nntp-async-articles nil)
-        (sit-for 2))
-     (setq nntp-async-articles articles)
-     (setq nntp-async-fetched nil)
-     (save-excursion
-       (set-buffer nntp-async-buffer)
-       (erase-buffer))
-     (nntp-async-send-strings "GROUP" group)
-     t)))
+  "Enable pre-fetch in GROUP."
+  (when nntp-async-articles
+    (nntp-async-request-group group))
+  (when nntp-async-number
+    (if (not (or (nntp-async-server-opened)
+                (nntp-async-open-server)))
+       ;; Couldn't open the second connection
+       (progn
+         (message "Can't open second connection to %s" nntp-address)
+         (ding)
+         (setq nntp-async-articles nil)
+         (sit-for 2))
+      ;; We opened the second connection (or it was opened already).  
+      (setq nntp-async-articles articles)
+      (setq nntp-async-fetched nil)
+      ;; Clear any old data.
+      (save-excursion
+       (set-buffer nntp-async-buffer)
+       (erase-buffer))
+      ;; Select the correct current group on this server.
+      (nntp-async-send-strings "GROUP" group)
+      t)))
 
 (defun nntp-list-active-group (group &optional server)
+  "Return the active info on GROUP (which can be a regexp."
+  (nntp-possibly-change-server group server)
   (nntp-send-command "^.*\r?\n" "LIST ACTIVE" group))
 
 (defun nntp-request-group-description (group &optional server)
-  "Get description of GROUP."
-  (if (nntp-possibly-change-server nil server)
-      (prog1
-         (nntp-send-command "^.*\r?\n" "XGTITLE" group)
-       (nntp-decode-text))))
+  "Get the description of GROUP."
+  (nntp-possibly-change-server nil server)
+  (prog1
+      (nntp-send-command "^.*\r?\n" "XGTITLE" group)
+    (nntp-decode-text)))
 
 (defun nntp-close-group (group &optional server)
+  "Close GROUP."
   (setq nntp-current-group nil)
   t)
 
 (defun nntp-request-list (&optional server)
-  "List active groups."
+  "List all active groups."
   (nntp-possibly-change-server nil server)
   (prog1
       (nntp-send-command "^\\.\r?\n" "LIST")
     (nntp-decode-text)))
 
 (defun nntp-request-list-newsgroups (&optional server)
-  "List groups."
+  "Get descriptions on all groups on SERVER."
   (nntp-possibly-change-server nil server)
   (prog1
       (nntp-send-command "^\\.\r?\n" "LIST NEWSGROUPS")
     (nntp-decode-text)))
 
 (defun nntp-request-newgroups (date &optional server)
-  "List new groups."
+  "List groups that have arrived since DATE."
   (nntp-possibly-change-server nil server)
   (let* ((date (timezone-parse-date date))
         (time-string
@@ -574,26 +580,25 @@ instead call function `nntp-status-message' to get status message.")
       (nntp-send-command "^\\.\r?\n" "LIST DISTRIBUTIONS")
     (nntp-decode-text)))
 
-(defun nntp-request-last (&optional newsgroup server)
+(defun nntp-request-last (&optional group server)
   "Decrease the current article pointer."
-  (nntp-possibly-change-server newsgroup server)
+  (nntp-possibly-change-server group server)
   (nntp-send-command "^[23].*\r?\n" "LAST"))
 
-(defun nntp-request-next (&optional newsgroup server)
+(defun nntp-request-next (&optional group server)
   "Advance the current article pointer."
-  (nntp-possibly-change-server newsgroup server)
+  (nntp-possibly-change-server group server)
   (nntp-send-command "^[23].*\r?\n" "NEXT"))
 
 (defun nntp-request-post (&optional server)
   "Post the current buffer."
   (nntp-possibly-change-server nil server)
-  (if (nntp-send-command "^[23].*\r?\n" "POST")
-      (progn
-       (nntp-encode-text)
-       (nntp-send-region-to-server (point-min) (point-max))
-       ;; 1.2a NNTP's post command is buggy. "^M" (\r) is not
-       ;;  appended to end of the status message.
-       (nntp-wait-for-response "^[23].*\n"))))
+  (when (nntp-send-command "^[23].*\r?\n" "POST")
+    (nntp-encode-text)
+    (nntp-send-region-to-server (point-min) (point-max))
+    ;; 1.2a NNTP's post command is buggy. "^M" (\r) is not
+    ;;  appended to end of the status message.
+    (nntp-wait-for-response "^[23].*\n")))
 
 ;;; Internal functions.
 
@@ -616,16 +621,18 @@ It will prompt for a password."
   "Send the AUTHINFO to the nntp server.
 This function is supposed to be called from `nntp-server-opened-hook'.
 It will prompt for a password."
-  (and (file-exists-p "~/.nntp-authinfo")
-       (save-excursion
-        (set-buffer (get-buffer-create " *tull*"))
-        (insert-file-contents "~/.nntp-authinfo")
-        (goto-char (point-min))
-        (nntp-send-command "^.*\r?\n" "AUTHINFO USER" (user-login-name))
-        (nntp-send-command "^.*\r?\n" "AUTHINFO PASS" 
-                           (buffer-substring (point)
-                                             (progn (end-of-line) (point))))
-        (kill-buffer (current-buffer)))))
+  (when (file-exists-p "~/.nntp-authinfo")
+    (save-excursion
+      (set-buffer (get-buffer-create " *authinfo*"))
+      (buffer-disable-undo)
+      (erase-buffer)
+      (insert-file-contents "~/.nntp-authinfo")
+      (goto-char (point-min))
+      (nntp-send-command "^.*\r?\n" "AUTHINFO USER" (user-login-name))
+      (nntp-send-command 
+       "^.*\r?\n" "AUTHINFO PASS" 
+       (buffer-substring (point) (progn (end-of-line) (point))))
+      (kill-buffer (current-buffer)))))
 
 (defun nntp-default-sentinel (proc status)
   "Default sentinel function for NNTP server process."
@@ -641,16 +648,17 @@ It will prompt for a password."
                                                (car servers))))))
        (setq servers (cdr servers)))
       (setq server (car (car servers))))
-    (and server
-        nntp-warn-about-losing-connection
-        (progn
-          (message "nntp: Connection closed to server %s" server)
-          (ding)))))
+    (when (and server
+              nntp-warn-about-losing-connection)
+      (message "nntp: Connection closed to server %s" server)
+      (ding))))
 
 (defun nntp-kill-connection (server)
+  "Choke the connection to SERVER."
   (let ((proc (nth 1 (assq 'nntp-server-process 
                           (assoc server nntp-server-alist)))))
-    (and proc (delete-process (process-name proc)))
+    (when proc 
+      (delete-process (process-name proc)))
     (nntp-close-server server)
     (setq nntp-status-string 
          (message "Connection timed out to server %s." server))
@@ -671,19 +679,15 @@ It will prompt for a password."
     (goto-char (point-max))
     (or (bolp) (insert "\n"))
     ;; Delete status line.
-    (goto-char (point-min))
-    (delete-region (point) (progn (forward-line 1) (point)))
-    ;; Delete `^M' at the end of lines.
-    (while (not (eobp))
-      (end-of-line)
-      (and (= (preceding-char) ?\r)
-          (delete-char -1))
-      (forward-line 1))
+    (delete-region (goto-char (point-min)) (progn (forward-line 1) (point)))
+    ;; Delete `^M's.
+    (while (search-forward "\r" nil t)
+      (replace-match "" t t))
     ;; Delete `.' at end of the buffer (end of text mark).
     (goto-char (point-max))
     (forward-line -1)
-    (if (looking-at "^\\.\n")
-       (delete-region (point) (progn (forward-line 1) (point))))
+    (when (looking-at "^\\.\n")
+      (delete-region (point) (progn (forward-line 1) (point))))
     ;; Replace `..' at beginning of line with `.'.
     (goto-char (point-min))
     ;; (replace-regexp "^\\.\\." ".")
@@ -695,21 +699,19 @@ It will prompt for a password."
 1. Insert `.' at beginning of line.
 2. Insert `.' at end of buffer (end of text mark)."
   (save-excursion
-    ;; Insert newline at end of buffer.
-    (goto-char (point-max))
-    (or (bolp) (insert "\n"))
     ;; Replace `.' at beginning of line with `..'.
     (goto-char (point-min))
-    ;; (replace-regexp "^\\." "..")
     (while (search-forward "\n." nil t)
       (insert "."))
-    ;; Insert `.' at end of buffer (end of text mark).
     (goto-char (point-max))
+    ;; Insert newline at end of buffer.
+    (or (bolp) (insert "\n"))
+    ;; Insert `.' at end of buffer (end of text mark).
     (insert ".\r\n")))
 
 \f
 ;;;
-;;; Synchronous Communication with NNTP Server.
+;;; Synchronous Communication with NNTP servers.
 ;;;
 
 (defun nntp-send-command (response cmd &rest args)
@@ -764,30 +766,26 @@ It will prompt for a password."
       (end-of-line)
       (setq nntp-status-string
            (buffer-substring (point-min) (point)))
-      (if status
-         (progn
-           (setq wait t)
-           (while wait
-             (goto-char (point-max))
-             (forward-line -1)         ;(beginning-of-line)
-             ;;(message (buffer-substring
-             ;;         (point)
-             ;;         (save-excursion (end-of-line) (point))))
-             (if (looking-at regexp)
-                 (setq wait nil)
-               (if nntp-debug-read
-                   (let ((newnum (/ (buffer-size) dotsize)))
-                     (if (not (= dotnum newnum))
-                         (progn
-                           (setq dotnum newnum)
-                           (message "NNTP: Reading %s"
-                                    (make-string dotnum ?.))))))
-               (nntp-accept-response)))
-           ;; Remove "...".
-           (if (and nntp-debug-read (> dotnum 0))
-               (message ""))
-           ;; Successfully received server response.
-           t)))))
+      (when status
+       (setq wait t)
+       (while wait
+         (goto-char (point-max))
+         (forward-line -1)
+         (if (looking-at regexp)
+             (setq wait nil)
+           (when nntp-debug-read
+             (let ((newnum (/ (buffer-size) dotsize)))
+               (if (not (= dotnum newnum))
+                   (progn
+                     (setq dotnum newnum)
+                     (message "NNTP: Reading %s"
+                              (make-string dotnum ?.))))))
+           (nntp-accept-response)))
+       ;; Remove "...".
+       (when (and nntp-debug-read (> dotnum 0))
+         (message ""))
+       ;; Successfully received server response.
+       t))))
 
 \f
 
@@ -830,11 +828,11 @@ It will prompt for a password."
                     (string-match (format "\\([^ :]+\\):%d" number) xref))
                (substring xref (match-beginning 1) (match-end 1)))
               (t "")))
-       (and (string-match "\r" group) 
-            (setq group (substring group 0 (match-beginning 0))))
+       (when (string-match "\r" group) 
+         (setq group (substring group 0 (match-beginning 0))))
        (cons group number)))))
 
-(defun nntp-retrieve-headers-with-xover (sequence &optional fetch-old)
+(defun nntp-retrieve-headers-with-xover (articles &optional fetch-old)
   (erase-buffer)
   (cond 
 
@@ -848,20 +846,20 @@ It will prompt for a password."
     (nntp-send-xover-command 
      (if fetch-old
         (if (numberp fetch-old) 
-            (max 1 (- (car sequence) fetch-old)) 
+            (max 1 (- (car articles) fetch-old)) 
           1)
-       (car sequence))
-     (nntp-last-element sequence) 'wait)
+       (car articles))
+     (nntp-last-element articles) 'wait)
 
     (goto-char (point-min))
-    (if (looking-at "[1-5][0-9][0-9] ")
-       (delete-region (point) (progn (forward-line 1) (point))))
+    (when (looking-at "[1-5][0-9][0-9] ")
+      (delete-region (point) (progn (forward-line 1) (point))))
     (while (search-forward "\r" nil t)
       (replace-match "" t t))
     (goto-char (point-max))
     (forward-line -1)
-    (if (looking-at "\\.")
-       (delete-region (point) (progn (forward-line 1) (point)))))
+    (when (looking-at "\\.")
+      (delete-region (point) (progn (forward-line 1) (point)))))
 
    ;; We do it the hard way.  For each gap, an XOVER command is sent
    ;; to the server.  We do not wait for a reply from the server, we
@@ -877,51 +875,48 @@ It will prompt for a password."
       ;; We have to check `nntp-server-xover'.  If it gets set to nil,
       ;; that means that the server does not understand XOVER, but we
       ;; won't know that until we try.
-      (while (and nntp-server-xover sequence)
-       (setq first (car sequence))
+      (while (and nntp-server-xover articles)
+       (setq first (car articles))
        ;; Search forward until we find a gap, or until we run out of
        ;; articles. 
-       (while (and (cdr sequence
-                   (< (- (nth 1 sequence) (car sequence)) nntp-nov-gap))
-         (setq sequence (cdr sequence)))
+       (while (and (cdr articles
+                   (< (- (nth 1 articles) (car articles)) nntp-nov-gap))
+         (setq articles (cdr articles)))
 
-       (if (not (nntp-send-xover-command first (car sequence)))
-           ()
-         (setq sequence (cdr sequence)
+       (when (nntp-send-xover-command first (car articles))
+         (setq articles (cdr articles)
                count (1+ count))
 
          ;; Every 400 requests we have to read the stream in
          ;; order to avoid deadlocks.
-         (if (or (null sequence)       ;All requests have been sent.
-                 (zerop (% count nntp-maximum-request)))
-             (progn
-               (accept-process-output)
-               ;; On some Emacs versions the preceding function has
-               ;; a tendency to change the buffer. Perhaps. It's
-               ;; quite difficult to reporduce, because it only
-               ;; seems to happen once in a blue moon. 
-               (set-buffer buf) 
-               (while (progn
-                        (goto-char last-point)
-                        ;; Count replies.
-                        (while (re-search-forward "^[0-9][0-9][0-9] " nil t)
-                          (setq received (1+ received)))
-                        (setq last-point (point))
-                        (< received count))
-                 (accept-process-output)
-                 (set-buffer buf))))))
-
-      (if (not nntp-server-xover)
-         ()
+         (when (or (null articles)     ;All requests have been sent.
+                   (zerop (% count nntp-maximum-request)))
+           (accept-process-output)
+           ;; On some Emacs versions the preceding function has
+           ;; a tendency to change the buffer. Perhaps. It's
+           ;; quite difficult to reporduce, because it only
+           ;; seems to happen once in a blue moon. 
+           (set-buffer buf) 
+           (while (progn
+                    (goto-char last-point)
+                    ;; Count replies.
+                    (while (re-search-forward "^[0-9][0-9][0-9] " nil t)
+                      (setq received (1+ received)))
+                    (setq last-point (point))
+                    (< received count))
+             (accept-process-output)
+             (set-buffer buf)))))
+
+      (when nntp-server-xover
        ;; Wait for the reply from the final command.
        (goto-char (point-max))
        (re-search-backward "^[0-9][0-9][0-9] " nil t)
-       (if (looking-at "^[23]")
-           (while (progn
-                    (goto-char (point-max))
-                    (forward-line -1)
-                    (not (looking-at "^\\.\r?\n")))
-             (nntp-accept-response)))
+       (when (looking-at "^[23]")
+         (while (progn
+                  (goto-char (point-max))
+                  (forward-line -1)
+                  (not (looking-at "^\\.\r?\n")))
+           (nntp-accept-response)))
        
        ;; We remove any "." lines and status lines.
        (goto-char (point-min))
@@ -933,6 +928,7 @@ It will prompt for a password."
   nntp-server-xover)
 
 (defun nntp-send-xover-command (beg end &optional wait-for-reply)
+  "Send the XOVER command to the server."
   (let ((range (format "%d-%d" beg end)))
     (if (stringp nntp-server-xover)
        ;; If `nntp-server-xover' is a string, then we just send this
@@ -940,9 +936,7 @@ It will prompt for a password."
        (if wait-for-reply
            (nntp-send-command "^\\.\r?\n" nntp-server-xover range)
          ;; We do not wait for the reply.
-         (progn
-           (nntp-send-strings-to-server nntp-server-xover range)
-           t))
+         (nntp-send-strings-to-server nntp-server-xover range))
       (let ((commands nntp-xover-commands))
        ;; `nntp-xover-commands' is a list of possible XOVER commands.
        ;; We try them all until we get at positive response. 
@@ -961,54 +955,48 @@ It will prompt for a password."
                 (setq nntp-server-xover (car commands))))
          (setq commands (cdr commands)))
        ;; If none of the commands worked, we disable XOVER.
-       (if (eq nntp-server-xover 'try)
-           (save-excursion
-             (set-buffer nntp-server-buffer)
-             (erase-buffer)
-             (setq nntp-server-xover nil)))
+       (when (eq nntp-server-xover 'try)
+         (save-excursion
+           (set-buffer nntp-server-buffer)
+           (erase-buffer)
+           (setq nntp-server-xover nil)))
        nntp-server-xover))))
 
 (defun nntp-send-strings-to-server (&rest strings)
-  "Send list of STRINGS to news server as command and its arguments."
+  "Send STRINGS to the server."
   (let ((cmd (concat (mapconcat 'identity strings " ") "\r\n")))
     ;; We open the nntp server if it is down.
     (or (nntp-server-opened nntp-current-server)
        (nntp-open-server nntp-current-server)
        (error (nntp-status-message)))
     ;; Send the strings.
-    (process-send-string nntp-server-process cmd)))
+    (process-send-string nntp-server-process cmd)
+    t))
 
 (defun nntp-send-region-to-server (begin end)
-  "Send current buffer region (from BEGIN to END) to news server."
+  "Send the current buffer region (from BEGIN to END) to the server."
   (save-excursion
-    ;; We have to work in the buffer associated with NNTP server
-    ;;  process because of NEmacs hack.
-    (copy-to-buffer nntp-server-buffer begin end)
-    (set-buffer nntp-server-buffer)
-    (setq begin (point-min))
-    (setq end (point-max))
-    ;; `process-send-region' does not work if text to be sent is very
-    ;;  large. I don't know maximum size of text sent correctly.
-    (let ((last nil)
+    ;; If we're not the the nntp server buffer, we copy the region
+    ;; over to that buffer.  
+    (if (eq (get-buffer nntp-server-buffer) (current-buffer))
+       (let ((orig (current-buffer)))
+         (set-buffer nntp-server-buffer)
+         (erase-buffer)
+         (insert-buffer-substring orig begin end))
+      ;; We are in the nntp buffer, so we just narrow it.
+      (narrow-to-region begin end))
+    ;; `process-send-region' does not work if the text to be sent is very
+    ;; large, so we send it piecemeal.
+    (let ((last (point-min))
          (size 100))                   ;Size of text sent at once.
-      (save-restriction
-       (narrow-to-region begin end)
-       (goto-char begin)
-       (while (not (eobp))
-         ;;(setq last (min end (+ (point) size)))
-         ;; NEmacs gets confused if character at `last' is Kanji.
-         (setq last (save-excursion
-                      (goto-char (min end (+ (point) size)))
-                      (or (eobp) (forward-char 1)) ;Adjust point
-                      (point)))
-         (process-send-region nntp-server-process (point) last)
-         ;; I don't know whether the next codes solve the known
-         ;;  problem of communication error of GNU Emacs.
-         (accept-process-output)
-         ;;(sit-for 0)
-         (goto-char last))))
-    ;; We cannot erase buffer, because reply may be received.
-    (delete-region begin end)))
+      (while (/= last (point-max))
+       (process-send-region 
+        nntp-server-process last (setq last (min (+ last size) (point-max))))
+       ;; Read any output from the server.  May be unnecessary.
+       (accept-process-output)))
+    ;; Delete the area we sent.
+    (delete-region (point-min) (point-max))
+    (widen)))
 
 (defun nntp-open-server-semi-internal (server &optional service)
   "Open SERVER.
@@ -1158,12 +1146,12 @@ defining this function as macro."
     (setq list (cdr list)))
   (car list))
 
-(defun nntp-possibly-change-server (newsgroup server)
-  ;; We see whether it is necessary to change the newsgroup.
-  (and newsgroup
+(defun nntp-possibly-change-server (group server)
+  ;; We see whether it is necessary to change the group.
+  (and group
        (progn
-        (not (equal newsgroup nntp-current-group))
-        (nntp-request-group newsgroup server)))
+        (not (equal group nntp-current-group))
+        (nntp-request-group group server)))
   (and server
        (or (nntp-server-opened server)
           (nntp-open-server server))))