*** empty log message ***
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 01:45:02 +0000 (01:45 +0000)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 01:45:02 +0000 (01:45 +0000)
16 files changed:
lisp/ChangeLog
lisp/gnus-visual.el
lisp/gnus.el
lisp/nnbabyl.el
lisp/nndigest.el
lisp/nndoc.el
lisp/nnfolder.el
lisp/nnheader.el
lisp/nnmail.el
lisp/nnmbox.el
lisp/nnmh.el
lisp/nnml.el
lisp/nntp.el
lisp/nnvirtual.el
readme
texi/gnus.texi

index ed798d2..6bad614 100644 (file)
@@ -1,3 +1,86 @@
+Sat Mar 25 05:05:26 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.el (gnus-compress-newsrc-assoc,
+       gnus-uncompress-newsrc-assoc): Compress lists of marked articles
+       before writing them to the .newsrc.eld file.
+       (gnus-select-newsgroup): auto-expire match on full name.
+       (gnus-select-newsgroup): New element in select methods:
+       auto-expire. 
+       (gnus-save-scores): New variable. 
+       (gnus-summary-exit): Use it.
+       (gnus-newsrc-to-gnus-format): If .newsrc was newer than
+       .newsrc.eld, all foreign groups would be hosed.
+
+       * gnus.el: All range functions have changed to allow an extended
+       syntax.
+
+Fri Mar 24 07:17:20 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.el (gnus-summary-move-article): Copy marks when moving
+       articles. 
+       (gnus-set-sorted-intersection): Would compute incorrect
+       intersection. 
+
+       * nndoc.el (nndoc-retrieve-headers): Insert Lines header.
+       * nnmh.el (nnmh-retrieve-headers): Ditto.
+       (nndigest-retrieve-headers): Ditto.
+
+       * nndigest.el (nndigest-narrow-to-article): Don't include the
+       closing digest separator in an article. 
+
+       * gnus.el (gnus-group-change-level): When subscribing to
+       non-existant groups, would claim that there was one unread article
+       in the group.
+       (gnus-summary-delete-article): Remove process mark after deleting
+       articles. 
+       (gnus-score-load-file): 'files was not properly handled, and edits
+       would end up with the wrong alist as the current one. 
+       (gnus-score-edit-alist): Name change from -file. 
+       (gnus-score-edit-file): New function and keystroke.
+
+       * nntp.el (nntp-request-newgroups): Would bug out due to a `let'
+       instead of a `let*'.
+
+       * gnus.el (gnus-score-save): Score files would not be saved. 
+       (gnus-summary-update-line): Would mark as read-below even when
+       attempting to remove the mark.
+
+Thu Mar 23 08:29:56 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.el (gnus-summary-save-article-file,
+       gnus-summary-save-article-folder,
+       gnus-summary-save-article-rmail): New commands and keystrokes.
+       (gnus-summary-sort): All sort commands now also work when
+       threading is used.
+       (gnus-summary-mode-map): Several key changes.
+
+       * nnml.el (nnml-request-expire-articles): Update active file as
+       well. 
+       * nnbabyl.el (nnbabyl-request-expire-articles): Ditto.
+       * nnfolder.el (nnfolder-request-expire-articles): Ditto.
+       * nnmbox.el (nnmbox-request-expire-articles): Ditto.
+
+       * nnmail.el (nnmail-tmp-directory): New variable.
+       (nnmail-move-inbox): Use it.
+
+       * nnvirtual.el (nnvirtual-update-marked): Would insert non-visible
+       component groups into the group buffer.
+
+       * nnmh.el (nnmh-get-new-mail): Don't create directories unless
+       mail reading is wanted.
+
+       * nnfolder.el (nnfolder-read-folder): Insert number of lines in
+       the article.
+
+       * gnus.el (gnus-group-unsubscribe-group): Would refuse to
+       subscribe to groups not in active file. 
+
+Thu Mar 23 13:23:45 1995  Lars Magne Ingebrigtsen  <larsi@menja.ifi.uio.no>
+
+       * gnus.el: Remove two calls to `debug'.
+
+       * gnus.el: 0.40 is released.
+
 Thu Mar 23 06:29:03 1995  Lars Magne Ingebrigtsen  <larsi@menja.ifi.uio.no>
 
        * gnus.el: 0.39 is released.
index 72d27f9..7e53af0 100644 (file)
@@ -276,6 +276,8 @@ The `.' will match any character.")
      ["Describe group" gnus-summary-describe-group t]
      ["Exit group" gnus-summary-exit t]
      ["Exit group without updating" gnus-summary-quit t]
+     ["Edit local kill file" gnus-summary-edit-local-kill t]
+     ["Edit global kill file" gnus-summary-edit-global-kill t]
      ))
 
   (easy-menu-define
@@ -302,11 +304,13 @@ The `.' will match any character.")
    gnus-summary-kill-menu
    gnus-summary-mode-map
    ""
-   '("Kill"
-     ["Edit local kill file" gnus-summary-edit-local-kill t]
-     ["Edit global kill file" gnus-summary-edit-global-kill t]
-     ["Expunge with score below..." gnus-score-set-expunge-below t]
-     ["Set mark with score below..." gnus-score-set-mark-below t]
+   '("Score"
+     ("Score file"
+      ["Switch current score file" gnus-score-change-score-file t]
+      ["Set mark below" gnus-score-set-mark-below t]
+      ["Set expunge below" gnus-score-set-expunge-below t]
+      ["Edit current score file" gnus-score-edit-alist t]
+      ["Edit score file" gnus-score-edit-file t])
      ["Raise score with current subject" 
       gnus-summary-temporarily-raise-by-subject t]
      ["Raise score with current author" 
index 601a320..db471b7 100644 (file)
@@ -268,9 +268,6 @@ The function is called with NEWSGROUP, HEADERS, and optional LAST-FOLDER.")
   "A function generating a file name to save articles in article format.
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE.")
 
-(defvar gnus-kill-file-name "KILL"
-  "Suffix of the kill files.")
-
 (defvar gnus-score-file-suffix "SCORE"
   "Suffix of the score files.")
 
@@ -434,6 +431,9 @@ slower.")
 (defvar gnus-score-interactive-default-score 1000
   "Scoring commands will raise/lower the score with this number as the default.")
 
+(defvar gnus-save-score nil
+  "If non-nil, save group scoring info.")
+
 (defvar gnus-global-score-files nil
   "List of global score files and directories.
 Set this variable if you want to use people's score files.  One entry
@@ -913,9 +913,6 @@ which to perform auto-expiry. This only makes sense for mail groups.")
 (defvar gnus-article-mode-hook nil
   "A hook for Gnus article mode.")
 
-(defvar gnus-kill-file-mode-hook nil
-  "A hook for Gnus kill file mode.")
-
 (defvar gnus-open-server-hook nil
   "A hook called just before opening connection to the news server.")
 
@@ -1203,7 +1200,7 @@ variable (string, integer, character, etc).")
 (defconst gnus-maintainer "Lars Magne Ingebrigtsen <larsi@ifi.uio.no>"
   "The mail address of the Gnus maintainer.")
 
-(defconst gnus-version "(ding) Gnus v0.40"
+(defconst gnus-version "(ding) Gnus v0.41"
   "Version number for this version of Gnus.")
 
 (defvar gnus-info-nodes
@@ -1348,7 +1345,6 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
 (defvar gnus-current-kill-article nil)
 
 ;; Save window configuration.
-(defvar gnus-winconf-kill-file nil)
 (defvar gnus-winconf-edit-group nil)
 (defvar gnus-winconf-edit-score nil)
 
@@ -1383,7 +1379,7 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
     gnus-newsgroup-dependencies gnus-newsgroup-selected-overlay
     gnus-newsgroup-scored gnus-newsgroup-kill-headers
     gnus-score-alist gnus-current-score-file gnus-summary-expunge-below 
-    (gnus-summary-mark-below . gnus-summary-default-score)
+    gnus-summary-mark-below
     gnus-newsgroup-history gnus-newsgroup-ancient)
   "Variables that are buffer-local to the summary buffers.")
 
@@ -1439,6 +1435,12 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
   (autoload 'gnus-uu-decode-save-view "gnus-uu")
   (autoload 'gnus-uu-decode-binhex-view "gnus-uu")
 
+  (autoload 'gnus-kill "gnus-kill")
+  (autoload 'gnus-apply-kill-file-internal "gnus-kill")
+  (autoload 'gnus-kill-file-edit-file "gnus-kill")
+  (autoload 'gnus-kill-file-raise-followups-to-author "gnus-kill")
+  (autoload 'gnus-execute "gnus-kill")
+
   (autoload 'pp "pp")
   (autoload 'pp-to-string "pp")
   (autoload 'mail-extract-address-components "mail-extr")
@@ -2344,8 +2346,8 @@ Both lists have to be sorted over <."
           (setcdr prev (cdr list1))
           (setq list1 (cdr list1)))
          (t
-          (setcdr prev (cdr list1))
           (setq list2 (cdr list2)))))
+  (setcdr prev nil)
   (cdr top)))
 
 (defun gnus-compress-sequence (numbers &optional always-list)
@@ -2362,39 +2364,111 @@ ranges."
              ((= (1+ last) (car numbers)) ;Still in sequence
               (setq last (car numbers)))
              (t                                ;End of one sequence
-              (setq result (cons (cons first last) result))
+              (setq result 
+                    (cons (if (= first last) first (cons first last)) result))
               (setq first (car numbers))
               (setq last  (car numbers))))
        (setq numbers (cdr numbers)))
       (if (and (not always-list) (null result))
-         (cons first last)
-       (nreverse (cons (cons first last) result))))))
+         (if (= first last) first (cons first last))
+       (nreverse (cons (if (= first last) first (cons first last))
+                       result))))))
 
-(defun gnus-uncompress-sequence (ranges)
+(defalias 'gnus-uncompress-sequence 'gnus-uncompress-range)
+(defun gnus-uncompress-range (ranges)
   "Expand a list of ranges into a list of numbers.
 RANGES is either a single range on the form `(num . num)' or a list of
 these ranges."
   (let (first last result)
-    (if (null ranges)
-       nil
-      (if (atom (car ranges))
-         (progn
-           (setq first (car ranges))
-           (setq last (cdr ranges))
-           (while (<= first last)
-             (setq result (cons first result))
-             (setq first (1+ first))))
-       (while ranges
+    (cond 
+     ((null ranges)
+      nil)
+     ((not (listp (cdr ranges)))
+      (setq first (car ranges))
+      (setq last (cdr ranges))
+      (while (<= first last)
+       (setq result (cons first result))
+       (setq first (1+ first)))
+      (nreverse result))
+     (t
+      (while ranges
+       (if (atom (car ranges))
+           (if (numberp (car ranges))
+               (setq result (cons (car ranges) result)))
          (setq first (car (car ranges)))
          (setq last  (cdr (car ranges)))
          (while (<= first last)
            (setq result (cons first result))
-           (setq first (1+ first)))
-         (setq ranges (cdr ranges))))
-      (nreverse result))))
+           (setq first (1+ first))))
+       (setq ranges (cdr ranges)))
+      (nreverse result)))))
 
 (defun gnus-add-to-range (ranges list)
   "Return a list of ranges that has all articles from both RANGES and LIST.
+Note: LIST has to be sorted over `<'."
+  (if (not ranges)
+      (gnus-compress-sequence list t)
+    (setq list (copy-sequence list))
+    (or (listp (cdr ranges))
+       (setq ranges (list ranges)))
+    (let ((out ranges)
+         ilist lowest highest temp)
+      (while (and ranges list)
+       (setq ilist list)
+       (setq lowest (or (and (atom (car ranges)) (car ranges))
+                        (car (car ranges))))
+       (while (and list (cdr list) (< (car (cdr list)) lowest))
+         (setq list (cdr list)))
+       (if (< (car ilist) lowest)
+           (progn
+             (setq temp list)
+             (setq list (cdr list))
+             (setcdr temp nil)
+             (setq out (nconc (gnus-compress-sequence ilist t) out))))
+       (setq highest (or (and (atom (car ranges)) (car ranges))
+                         (cdr (car ranges))))
+       (while (and list (<= (car list) highest))
+         (setq list (cdr list)))
+       (setq ranges (cdr ranges)))
+      (if list
+         (setq out (nconc (gnus-compress-sequence list t) out)))
+      (setq out (sort out (lambda (r1 r2) 
+                           (< (or (and (atom r1) r1) (car r1))
+                              (or (and (atom r2) r2) (car r2))))))
+      (setq ranges out)
+      (while ranges
+       (if (atom (car ranges))
+           (if (cdr ranges)
+               (if (atom (car (cdr ranges)))
+                   (if (= (1+ (car ranges)) (car (cdr ranges)))
+                       (progn
+                         (setcar ranges (cons (car ranges) 
+                                              (car (cdr ranges))))
+                         (setcdr ranges (cdr (cdr ranges)))))
+                 (if (= (1+ (car ranges)) (car (car (cdr ranges))))
+                     (progn
+                       (setcar (car (cdr ranges)) (car ranges))
+                       (setcar ranges (car (cdr ranges)))
+                       (setcdr ranges (cdr (cdr ranges)))))))
+         (if (cdr ranges)
+             (if (atom (car (cdr ranges)))
+                 (if (= (1+ (cdr (car ranges))) (car (cdr ranges)))
+                     (progn
+                       (setcdr (car ranges) (car (cdr ranges)))
+                       (setcdr ranges (cdr (cdr ranges)))))
+               (if (= (1+ (cdr (car ranges))) (car (car (cdr ranges))))
+                   (progn
+                     (setcdr (car ranges) (cdr (car (cdr ranges))))
+                     (setcdr ranges (cdr (cdr ranges))))))))
+       (setq ranges (cdr ranges)))
+      out)))
+
+(defun gnus-add-to-range-new (ranges list)
+  (gnus-compress-sequence 
+   (sort (nconc (gnus-uncompress-range ranges) list) '<)))     
+
+(defun gnus-add-to-range-old (ranges list)
+  "Return a list of ranges that has all articles from both RANGES and LIST.
 Note: LIST has to be sorted over `<'."
   (let* ((ranges (if (and ranges (atom (car ranges))) (list ranges) ranges))
         (inrange ranges)
@@ -2446,16 +2520,22 @@ Note: LIST has to be sorted over `<'."
   ;; !!! This function shouldn't look like this, but I've got a headache.
   (gnus-compress-sequence 
    (gnus-sorted-complement
-    (gnus-uncompress-sequence ranges) list)))
+    (gnus-uncompress-range ranges) list)))
 
 (defun gnus-member-of-range (number ranges)
-  (if (not (listp (car ranges)))
+  (if (not (listp (cdr ranges)))
       (and (>= number (car ranges)) 
           (<= number (cdr ranges)))
     (let ((not-stop t))
-      (while (and ranges (>= number (car (car ranges))) not-stop)
-       (if (and (>= number (car (car ranges)))
-                (<= number (cdr (car ranges))))
+      (while (and ranges 
+                 (if (numberp (car ranges))
+                     (>= number (car ranges))
+                   (>= number (car (car ranges))))
+                 not-stop)
+       (if (if (numberp (car ranges))
+               (= number (car ranges))
+             (and (>= number (car (car ranges)))
+                  (<= number (cdr (car ranges)))))
            (setq not-stop nil))
        (setq ranges (cdr ranges)))
       (not not-stop))))
@@ -2549,7 +2629,18 @@ Note: LIST has to be sorted over `<'."
 
 (defun gnus-group-mode ()
   "Major mode for reading news.
+
 All normal editing commands are switched off.
+\\<gnus-group-mode-map>
+The group buffer lists (some of) the groups available.  For instance,
+`\\[gnus-group-list-groups]' will list all subscribed groups with unread articles, while `\\[gnus-group-list-zombies]'
+lists all zombie groups. 
+
+Groups that are displayed can be entered with `\\[gnus-group-read-group]'.  To subscribe 
+to a group not displayed, type `\\[gnus-group-unsubscribe-group]'. 
+
+For more in-depth information on this mode, read the manual (`\\[gnus-info-find-node]'). 
+
 The following commands are available:
 
 \\{gnus-group-mode-map}"
@@ -2794,6 +2885,16 @@ If REGEXP, only list groups matching REGEXP."
 
 (defun gnus-group-set-info (info)
   (let ((entry (gnus-gethash (car info) gnus-newsrc-hashtb)))
+    (let (marked)
+      (if (not (setq marked (nth 3 info)))
+         ()
+       (while marked
+         (or (eq 'score (car (car marked)))
+             (not (or (atom (cdr (cdr (car marked))))
+                      (not (atom (car (cdr (car marked)))))))
+             (setcdr (car marked) 
+                     (gnus-uncompress-range (cdr (car marked)))))
+         (setq marked (cdr marked)))))
     (if entry
        ()
       (save-excursion
@@ -2853,7 +2954,7 @@ moves the point to the colon."
       (setq active (gnus-gethash group gnus-active-hashtb))
       (gnus-group-insert-group-line 
        nil group (if (member group gnus-zombie-list) 8 9)
-       nil (- (1+ (cdr active)) (car active)) nil))))
+       nil (if active (- (1+ (cdr active)) (car active)) 0) nil))))
 
 (defun gnus-group-insert-group-line (gformat group level marked number method)
   (let* ((gformat (or gformat gnus-group-line-format-spec))
@@ -3169,10 +3270,9 @@ ADDRESS."
      (concat "(gnus-group-set-info '" (prin1-to-string (cdr info)) ")"))
     (gnus-group-insert-group-line-info nname)))
 
-(defun gnus-group-edit-group ()
-  (interactive)
-  (let ((group (gnus-group-group-name))
-       info)
+(defun gnus-group-edit-group (group)
+  (interactive (list (gnus-group-group-name)))
+  (let (info)
     (if group (setq info (nth 2 (gnus-gethash group gnus-newsrc-hashtb)))
       (error "No group on current line"))
     (setq gnus-winconf-edit-group (current-window-configuration))
@@ -3184,7 +3284,17 @@ ADDRESS."
     (local-set-key "\C-c\C-c" 'gnus-group-edit-group-done)
     (erase-buffer)
     (insert ";; Type `C-c C-c' after you have edited the newsgroup entry.\n\n")
-    (insert (pp-to-string (list 'gnus-group-set-info (list 'quote info))))))
+    (let ((cinfo (gnus-copy-sequence info))
+         marked)
+      (if (not (setq marked (nth 3 cinfo)))
+         ()
+       (while marked
+         (or (eq 'score (car (car marked)))
+             (setcdr (car marked) 
+                     (gnus-compress-sequence (sort (cdr (car marked)) '<) t)))
+         (setq marked (cdr marked))))
+      (insert (pp-to-string (list 'gnus-group-set-info
+                                 (list 'quote cinfo)))))))
 
 (defun gnus-group-edit-group-done ()
   (interactive)
@@ -3404,14 +3514,13 @@ New newsgroup is added to .newsrc automatically."
            newsrc (if level level (if (< (nth 1 (nth 2 newsrc)) 6) 6 4)))
           (gnus-group-update-group group))
          ((and (stringp group)
-               (gnus-gethash group gnus-active-hashtb))
+               (or (not gnus-have-read-active-file)
+                   (gnus-gethash group gnus-active-hashtb)))
           ;; Add new newsgroup.
           (gnus-group-change-level 
            group 
            (if level level 3) 
-           (or (nth 2 (nth 2 (gnus-gethash group gnus-newsrc-hashtb)))
-               (and (member group gnus-zombie-list) 8)
-               9)
+           (or (and (member group gnus-zombie-list) 8) 9)
            (or (and (gnus-group-group-name)
                     (gnus-gethash (gnus-group-group-name) gnus-newsrc-hashtb))
                (gnus-gethash (car (car gnus-newsrc-assoc)) 
@@ -4038,7 +4147,7 @@ and the second element is the address."
 (defvar gnus-summary-score-map nil)
 (defvar gnus-summary-sort-map nil)
 (defvar gnus-summary-mgroup-map nil)
-(defvar gnus-summary-vkill-map nil)
+(defvar gnus-summary-vsave-map nil)
 (defvar gnus-summary-increase-map nil)
 (defvar gnus-summary-inc-subject-map nil)
 (defvar gnus-summary-inc-author-map nil)
@@ -4133,7 +4242,7 @@ and the second element is the address."
   (define-key gnus-summary-mode-map "V" 'gnus-version)
   (define-key gnus-summary-mode-map "\C-c\C-d" 'gnus-summary-describe-group)
   (define-key gnus-summary-mode-map "q" 'gnus-summary-exit)
-  (define-key gnus-summary-mode-map "Q" 'gnus-summary-quit)
+  (define-key gnus-summary-mode-map "Q" 'gnus-summary-exit-no-update)
   (define-key gnus-summary-mode-map "\C-c\C-i" 'gnus-info-find-node)
   (define-key gnus-summary-mode-map [mouse-2] 'gnus-mouse-pick-article)
   (define-key gnus-summary-mode-map "m" 'gnus-summary-mail-other-window)
@@ -4146,6 +4255,7 @@ and the second element is the address."
 ;  (define-key gnus-summary-mode-map "?" 'gnus-summary-describe-briefly)
   (define-key gnus-summary-mode-map "l" 'gnus-summary-goto-last-article)
   (define-key gnus-summary-mode-map "\C-c\C-v\C-v" 'gnus-uu-decode-uu)
+  (define-key gnus-summary-mode-map "\C-d" 'gnus-summary-enter-digest-group)
 
 
   ;; Sort of orthogonal keymap
@@ -4172,6 +4282,8 @@ and the second element is the address."
   (define-key gnus-summary-mark-map "C" 'gnus-summary-catchup)
   (define-key gnus-summary-mark-map "H" 'gnus-summary-catchup-to-here)
   (define-key gnus-summary-mark-map "\C-c" 'gnus-summary-catchup-all)
+  (define-key gnus-summary-mark-map "k" 'gnus-summary-kill-same-subject-and-select)
+  (define-key gnus-summary-mark-map "K" 'gnus-summary-kill-same-subject)
 
   (define-prefix-command 'gnus-summary-mscore-map)
   (define-key gnus-summary-mark-map "s" 'gnus-summary-mscore-map)
@@ -4245,13 +4357,12 @@ and the second element is the address."
 
   
   (define-prefix-command 'gnus-summary-exit-map)
-  (define-key gnus-summary-mode-map "\M-e" 'gnus-summary-exit-map)
+  (define-key gnus-summary-mode-map "Z" 'gnus-summary-exit-map)
   (define-key gnus-summary-exit-map "c" 'gnus-summary-catchup-and-exit)
-  (define-key gnus-summary-exit-map "\C-c" 'gnus-summary-catchup-all-and-exit)
-  (define-key gnus-summary-exit-map "q" 'gnus-summary-exit)
-  (define-key gnus-summary-exit-map "e" 'gnus-summary-exit)
-  (define-key gnus-summary-exit-map "Q" 'gnus-summary-quit)
-  (define-key gnus-summary-exit-map "E" 'gnus-summary-quit)
+  (define-key gnus-summary-exit-map "C" 'gnus-summary-catchup-all-and-exit)
+  (define-key gnus-summary-exit-map "E" 'gnus-summary-exit-no-update)
+  (define-key gnus-summary-exit-map "Q" 'gnus-summary-exit)
+  (define-key gnus-summary-exit-map "Z" 'gnus-summary-exit)
 
 
   (define-prefix-command 'gnus-summary-article-map)
@@ -4318,23 +4429,32 @@ and the second element is the address."
   (define-key gnus-summary-various-map "e" 'gnus-summary-expand-window)
   (define-key gnus-summary-various-map "S" 'gnus-summary-reselect-current-group)
   (define-key gnus-summary-various-map "g" 'gnus-summary-rescan-group)
-  (define-key gnus-summary-various-map "o" 'gnus-summary-save-article)
-  (define-key gnus-summary-various-map "\C-o" 'gnus-summary-save-article-mail)
-  (define-key gnus-summary-various-map "|" 'gnus-summary-pipe-output)
   (define-key gnus-summary-various-map "V" 'gnus-version)
   (define-key gnus-summary-various-map "f" 'gnus-summary-fetch-faq)
   (define-key gnus-summary-various-map "d" 'gnus-summary-describe-group)
   (define-key gnus-summary-various-map "?" 'gnus-summary-describe-briefly)
   (define-key gnus-summary-various-map "i" 'gnus-info-find-node)
   (define-key gnus-summary-various-map "D" 'gnus-summary-enter-digest-group)
+  (define-key gnus-summary-various-map "k" 'gnus-summary-edit-local-kill)
+  (define-key gnus-summary-various-map "K" 'gnus-summary-edit-global-kill)
+
+  (define-prefix-command 'gnus-summary-vsave-map)
+  (define-key gnus-summary-various-map "o" 'gnus-summary-vsave-map)
+  (define-key gnus-summary-vsave-map "o" 'gnus-summary-save-article)
+  (define-key gnus-summary-vsave-map "m" 'gnus-summary-save-article-mail)
+  (define-key gnus-summary-vsave-map "r" 'gnus-summary-save-article-rmail)
+  (define-key gnus-summary-vsave-map "f" 'gnus-summary-save-article-file)
+  (define-key gnus-summary-vsave-map "h" 'gnus-summary-save-article-folder)
+  (define-key gnus-summary-vsave-map "p" 'gnus-summary-pipe-output)
 
   (define-prefix-command 'gnus-summary-score-map)
   (define-key gnus-summary-various-map "S" 'gnus-summary-score-map)
   (define-key gnus-summary-score-map "s" 'gnus-summary-set-score)
   (define-key gnus-summary-score-map "c" 'gnus-score-change-score-file)
   (define-key gnus-summary-score-map "m" 'gnus-score-set-mark-below)
-  (define-key gnus-summary-score-map "E" 'gnus-score-set-expunge-below)
-  (define-key gnus-summary-score-map "e" 'gnus-score-edit-file)
+  (define-key gnus-summary-score-map "x" 'gnus-score-set-expunge-below)
+  (define-key gnus-summary-score-map "e" 'gnus-score-edit-alist)
+  (define-key gnus-summary-score-map "f" 'gnus-score-edit-file)
 
   (define-prefix-command 'gnus-summary-sort-map)
   (define-key gnus-summary-various-map "s" 'gnus-summary-sort-map)
@@ -4353,13 +4473,6 @@ and the second element is the address."
   (define-key gnus-summary-mgroup-map "w" 'gnus-summary-edit-article)
   (define-key gnus-summary-mgroup-map "c" 'gnus-summary-copy-article)
 
-  (define-prefix-command 'gnus-summary-vkill-map)
-  (define-key gnus-summary-various-map "k" 'gnus-summary-vkill-map)
-  (define-key gnus-summary-vkill-map "k" 'gnus-summary-kill-same-subject-and-select)
-  (define-key gnus-summary-vkill-map "K" 'gnus-summary-kill-same-subject)
-  (define-key gnus-summary-vkill-map "\M-k" 'gnus-summary-edit-local-kill)
-  (define-key gnus-summary-vkill-map "\M-K" 'gnus-summary-edit-global-kill)
-
 
   (define-prefix-command 'gnus-summary-increase-map)
   (define-key gnus-summary-mode-map "I" 'gnus-summary-increase-map)
@@ -4475,7 +4588,21 @@ and the second element is the address."
 
 (defun gnus-summary-mode ()
   "Major mode for reading articles.
+
 All normal editing commands are switched off.
+\\<gnus-summary-mode-map>
+Each line in this buffer represents one article.  To read an
+article, you can, for instance, type `\\[gnus-summary-next-page]'.  To move forwards
+and backwards while displaying articles, type `\\[gnus-summary-next-unread-article]' and `\\[gnus-summary-prev-unread-article]', 
+respectively.
+
+You can also post articles and send mail from this buffer.  To 
+follow up an article, type `\\[gnus-summary-followup]'.  To mail a reply to the author 
+of an article, type `\\[gnus-summary-reply]'.
+
+There are approx. one gazillion commands you can execute in this 
+buffer; read the info pages for more information (`\\[gnus-info-find-node]'). 
+
 The following commands are available:
 
 \\{gnus-summary-mode-map}"
@@ -4605,9 +4732,10 @@ The following commands are available:
        (progn
          (or dont-update
              (if (and gnus-summary-mark-below
-                      (< (gnus-summary-article-score) gnus-summary-mark-below))
-                 (and (not (memq (gnus-summary-article-mark)
-                                 gnus-newsgroup-unreads))
+                      (< (gnus-summary-article-score)
+                         gnus-summary-mark-below))
+                 (and (not (memq (gnus-summary-article-number)
+                                 gnus-newsgroup-marked))
                       (gnus-summary-mark-article nil gnus-low-score-mark))
                (and (eq (gnus-summary-article-mark) gnus-low-score-mark)
                     (gnus-summary-mark-article nil gnus-unread-mark))))
@@ -5143,7 +5271,7 @@ If READ-ALL is non-nil, all articles in the group are selected."
        nil
       ;; Init the dependencies hash table.
       (setq gnus-newsgroup-dependencies 
-           (gnus-make-hashtable (length gnus-newsgroup-unreads)))
+           (gnus-make-hashtable (length articles)))
       ;; Retrieve the headers and read them in.
       (setq gnus-newsgroup-headers 
            (if (eq 'nov (setq gnus-headers-retrieved-by
@@ -5171,9 +5299,9 @@ If READ-ALL is non-nil, all articles in the group are selected."
                     gnus-newsgroup-headers)))
       ;; Check whether auto-expire is to be done in this group.
       (setq gnus-newsgroup-auto-expire
-           (and (stringp gnus-auto-expirable-newsgroups)
-                (string-match gnus-auto-expirable-newsgroups 
-                              (gnus-group-real-name group))))
+           (or (and (stringp gnus-auto-expirable-newsgroups)
+                    (string-match gnus-auto-expirable-newsgroups group))
+               (memq 'auto-expire gnus-current-select-method)))
       ;; First and last article in this newsgroup.
       (and gnus-newsgroup-headers
           (setq gnus-newsgroup-begin 
@@ -5192,7 +5320,7 @@ If READ-ALL is non-nil, all articles in the group are selected."
          (if (or read-all
                  (= (length gnus-newsgroup-unreads) 
                     (length gnus-newsgroup-dormant)))
-             (gnus-uncompress-sequenc
+             (gnus-uncompress-rang
               (gnus-gethash group gnus-active-hashtb))
            gnus-newsgroup-unreads))
         (scored-list (gnus-killed-articles gnus-newsgroup-killed articles))
@@ -5352,7 +5480,7 @@ If READ-ALL is non-nil, all articles in the group are selected."
 (defun gnus-add-marked-articles (group type articles &optional info force)
   ;; Add ARTICLES of TYPE to the info of GROUP.
   ;; If INFO is non-nil, use that info. If FORCE is non-nil, don't
-  ;; add, but replace this marked articles of TYPE with ARTICLES.
+  ;; add, but replace marked articles of TYPE with ARTICLES.
   (let ((info (or info (nth 2 (gnus-gethash group gnus-newsrc-hashtb))))
        marked m)
     (or (not info)
@@ -5503,15 +5631,15 @@ The resulting hash table is returned, or nil if no Xrefs were found."
                     ;; articles there are in this group.
                     (if active
                         (progn
-                          (if (atom (car range))
+                          (if (atom (cdr range))
                               (if (not range)
                                   (setq num (- (1+ (cdr active)) 
                                                (car active)))
                                 (setq num (- (cdr active) (- (1+ (cdr range)) 
                                                              (car range)))))
                             (while range
-                              (setq num (+ num (- (1+ (cdr (car range))) 
-                                                  (car (car range)))))
+                              (setq num (+ num (- (1+ (or (and (numberp (car range)) (car range)) (cdr (car range))))
+                                                  (or (and (numberp (car range)) (car range)) (car (car range))))))
                               (setq range (cdr range)))
                             (setq num (- (cdr active) num)))
                           ;; Update the number of unread articles.
@@ -6037,8 +6165,10 @@ displayed, no centering will be performed."
              (while (< first nlast)
                (setq unread (cons first unread))
                (setq first (1+ first))))
-         (setq first (1+ (cdr (car read))))
-         (setq nlast (car (car (cdr read))))
+         (setq first (1+ (if (atom (car read)) (car read) (cdr (car read)))))
+         (setq nlast (if (atom (car (cdr read))) 
+                         (car (cdr read))
+                       (car (car (cdr read)))))
          (setq read (cdr read)))))
     ;; And add the last unread articles.
     (while (<= first last)
@@ -6119,7 +6249,7 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
              (gnus-compress-sequence
               (nconc
                (gnus-set-sorted-intersection
-                (gnus-uncompress-sequence gnus-newsgroup-killed)
+                (gnus-uncompress-range gnus-newsgroup-killed)
                 (setq gnus-newsgroup-unselected
                       (sort gnus-newsgroup-unselected '<)))
                (setq gnus-newsgroup-unreads
@@ -6136,7 +6266,8 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
        gnus-newsgroup-marked
        t gnus-newsgroup-replied gnus-newsgroup-expirable
        gnus-newsgroup-killed gnus-newsgroup-dormant
-       gnus-newsgroup-bookmarks gnus-newsgroup-scored)
+       gnus-newsgroup-bookmarks 
+       (and gnus-save-score gnus-newsgroup-scored))
       (and gnus-use-cross-reference
           (gnus-mark-xrefs-as-read 
            group headers gnus-newsgroup-unreads gnus-newsgroup-expirable))
@@ -6178,7 +6309,8 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
            (gnus-set-global-variables)
            (gnus-configure-windows 'summary))))))
 
-(defun gnus-summary-quit (&optional no-questions)
+(defalias 'gnus-summary-quit 'gnus-summary-exit-no-update)
+(defun gnus-summary-exit-no-update (&optional no-questions)
   "Quit reading current newsgroup without updating read article info."
   (interactive)
   (let* ((group gnus-newsgroup-name)
@@ -6250,7 +6382,7 @@ If BACKWARD, go to previous group instead."
     (let ((group (or group (gnus-summary-search-group backward)))
          (buf gnus-summary-buffer))
       (if (null group)
-         (gnus-summary-quit t)
+         (gnus-summary-exit-no-update t)
        (message "Selecting %s..." group)
        ;; We are now in group mode buffer.
        ;; Make sure group mode buffer point is on GROUP.
@@ -6260,7 +6392,7 @@ If BACKWARD, go to previous group instead."
          (and (string= gnus-newsgroup-name ingroup)
               (progn
                 (set-buffer sumbuf)
-                (gnus-summary-quit t))))))))
+                (gnus-summary-exit-no-update t))))))))
 
 (defun gnus-summary-prev-group (no-article)
   "Exit current newsgroup and then select previous unread newsgroup.
@@ -6794,28 +6926,29 @@ gnus-select-article-hook is not called during the search."
     ;; Return T if found such article.
     found))
 
-(defun gnus-summary-execute-command (field regexp command &optional backward)
-  "If FIELD of article header matches REGEXP, execute a COMMAND string.
-If FIELD is an empty string (or nil), entire article body is searched for.
-If optional (prefix) argument BACKWARD is non-nil, do backward instead."
+(defun gnus-summary-execute-command (header regexp command &optional backward)
+  "Search forward for an article whose HEADER matches REGEXP and execute COMMAND.
+If HEADER is an empty string (or nil), the match is done on the entire
+article. If BACKWARD (the prefix) is non-nil, search backward instead."
   (interactive
    (list (let ((completion-ignore-case t))
-          (completing-read "Field name: "
-                           '(("Number")("Subject")("From")
-                             ("Lines")("Date")("Message-ID")
-                             ("Xref")("References"))
-                           nil 'require-match))
+          (completing-read 
+           "Header name: "
+           (mapcar (string) (list string)
+                   '("Number" "Subject" "From" "Lines" "Date"
+                     "Message-ID" "Xref" "References")
+                   nil 'require-match)))
         (read-string "Regexp: ")
         (read-key-sequence "Command: ")
         current-prefix-arg))
-  ;; Hidden thread subtrees must be searched for ,too.
+  ;; Hidden thread subtrees must be searched as well.
   (gnus-summary-show-all-threads)
   ;; We don't want to change current point nor window configuration.
   (save-excursion
     (save-window-excursion
       (message "Executing %s..." (key-description command))
       ;; We'd like to execute COMMAND interactively so as to give arguments.
-      (gnus-execute field regexp
+      (gnus-execute header regexp
                    (` (lambda ()
                         (call-interactively '(, (key-binding command)))))
                    backward)
@@ -6969,9 +7102,19 @@ and `request-accept' functions. (Ie. mail newsgroups at present.)"
                (setcar (cdr (cdr info))
                        (gnus-add-to-range (nth 2 info) 
                                           (list (cdr art-group)))))
-           ;; !!! Here one should copy all the marks over to the new
-           ;; newsgroup, but I couldn't be bothered. nth on that!
-           )
+           ;; Copy any marks over to the new group.
+           (let ((marks '((tick . gnus-newsgroup-marked)
+                          (dormant . gnus-newsgroup-dormant)
+                          (expire . gnus-newsgroup-expirable)
+                          (bookmark . gnus-newsgroup-bookmarks)
+                       ;   (score . gnus-newsgroup-scored)
+                          (reply . gnus-newsgroup-replied)))
+                 (to-article (cdr art-group)))
+             (while marks
+               (if (memq article (symbol-value (cdr (car marks))))
+                   (gnus-add-marked-articles 
+                    (car info) (car (car marks)) (list to-article) info))
+               (setq marks (cdr marks)))))
        (message "Couldn't move article %s" (car articles)))
       (gnus-summary-remove-process-mark (car articles))
       (setq articles (cdr articles)))))
@@ -7054,14 +7197,103 @@ functions. (Ie. mail newsgroups at present.)"
                (setcar (cdr (cdr info))
                        (gnus-add-to-range (nth 2 info) 
                                           (list (cdr art-group)))))
-           ;; !!! Here one should copy all the marks over to the new
-           ;; newsgroup, but I couldn't be bothered. nth on that!
-           )
+           ;; Copy any marks over to the new group.
+           (let ((marks '((tick . gnus-newsgroup-marked)
+                          (dormant . gnus-newsgroup-dormant)
+                          (expire . gnus-newsgroup-expirable)
+                          (bookmark . gnus-newsgroup-bookmarks)
+                       ;   (score . gnus-newsgroup-scored)
+                          (reply . gnus-newsgroup-replied)))
+                 (to-article (cdr art-group)))
+             (while marks
+               (if (memq article (symbol-value (cdr (car marks))))
+                   (gnus-add-marked-articles 
+                    (car info) (car (car marks)) (list to-article) info))
+               (setq marks (cdr marks)))))
        (message "Couldn't copy article %s" (car articles)))
       (gnus-summary-remove-process-mark (car articles))
       (setq articles (cdr articles)))
     (kill-buffer copy-buf)))
-      
+
+(defun gnus-summary-expire-articles ()
+  "Expire all articles that are marked as expirable in the current group."
+  (interactive)
+  (if (and gnus-newsgroup-expirable
+          (gnus-check-backend-function 
+           'request-expire-articles gnus-newsgroup-name))
+      (let ((expirable gnus-newsgroup-expirable))
+       ;; The list of articles that weren't expired is returned.
+       (setq gnus-newsgroup-expirable 
+             (gnus-request-expire-articles gnus-newsgroup-expirable
+                                           gnus-newsgroup-name))
+       ;; We go through the old list of expirable, and mark all
+       ;; really expired articles as non-existant.
+       (while expirable
+         (or (memq (car expirable) gnus-newsgroup-expirable)
+             (gnus-summary-mark-as-read (car expirable) "%"))
+         (setq expirable (cdr expirable))))))
+
+;; Suggested by Jack Vinson <vinson@unagi.cis.upenn.edu>.
+(defun gnus-summary-delete-article (n)
+  "Delete the N next (mail) articles.
+This command actually deletes articles. This is not a marking
+command. The article will disappear forever from you life, never to
+return. 
+If N is negative, delete backwards.
+If N is nil and articles have been marked with the process mark,
+delete these instead."
+  (interactive "P")
+  (or (gnus-check-backend-function 'request-expire-articles 
+                                  gnus-newsgroup-name)
+      (error "The current newsgroup does not support article deletion."))
+  ;; Compute the list of articles to delete.
+  (let ((articles (gnus-summary-work-articles n)))
+    (if (and gnus-novice-user
+            (not (gnus-y-or-n-p 
+                  (format "Do you really want to delete %s forever? "
+                          (if (> (length articles) 1) "these articles"
+                            "this article")))))
+       ()
+      ;; Delete the articles.
+      (setq gnus-newsgroup-expirable 
+           (gnus-request-expire-articles 
+            articles gnus-newsgroup-name 'force))
+      (while articles
+       (gnus-summary-remove-process-mark (car articles))       
+       ;; The backend might not have been able to delete the article
+       ;; after all.  
+       (or (memq (car articles) gnus-newsgroup-expirable)
+           (gnus-summary-mark-as-read (car articles) gnus-canceled-mark))
+       (setq articles (cdr articles))))))
+
+(defun gnus-summary-edit-article ()
+  "Enter into a buffer and edit the current article.
+This will have permanent effect only in mail groups."
+  (interactive)
+  (or (gnus-check-backend-function 
+       'request-replace-article gnus-newsgroup-name)
+      (error "The current newsgroup does not support article editing."))
+  (gnus-summary-select-article t)
+  (other-window 1)
+  (message "C-c C-c to end edits")
+  (setq buffer-read-only nil)
+  (text-mode)
+  (use-local-map (copy-keymap (current-local-map)))
+  (local-set-key "\C-c\C-c" 'gnus-summary-edit-article-done)
+  (goto-char 1)
+  (search-forward "\n\n" nil t))
+
+(defun gnus-summary-edit-article-done ()
+  "Make edits to the current article permanent."
+  (interactive)
+  (if (not (gnus-request-replace-article 
+           (cdr gnus-article-current) (car gnus-article-current) 
+           (current-buffer)))
+      (error "Couldn't replace article.")
+    (gnus-article-mode)
+    (use-local-map gnus-article-mode-map)
+    (setq buffer-read-only t)
+    (pop-to-buffer gnus-summary-buffer)))      
 
 ;; Summary score commands.
 
@@ -7096,14 +7328,6 @@ functions. (Ie. mail newsgroups at present.)"
              (cons (cons article n) gnus-newsgroup-scored))))
     (gnus-summary-update-line)))
 
-(defmacro gnus-raise (field expression level)
-  (` (gnus-kill (, field) (, expression)
-               (function (gnus-summary-raise-score (, level))) t)))
-
-(defmacro gnus-lower (field expression level)
-  (` (gnus-kill (, field) (, expression)
-               (function (gnus-summary-raise-score (- (, level)))) t)))
-
 ;; Summary marking commands.
 
 (defun gnus-summary-raise-same-subject-and-select (score)
@@ -7257,95 +7481,6 @@ the actual number of articles marked is returned."
   (interactive "p")
   (gnus-summary-mark-forward n gnus-expirable-mark))
 
-(defun gnus-summary-expire-articles ()
-  "Expire all articles that are marked as expirable in the current group."
-  (interactive)
-  (if (and gnus-newsgroup-expirable
-          (gnus-check-backend-function 
-           'request-expire-articles gnus-newsgroup-name))
-      (let ((expirable gnus-newsgroup-expirable))
-       ;; The list of articles that weren't expired is returned.
-       (setq gnus-newsgroup-expirable 
-             (gnus-request-expire-articles gnus-newsgroup-expirable
-                                           gnus-newsgroup-name))
-       ;; We go through the old list of expirable, and mark all
-       ;; really expired articles as non-existant.
-       (while expirable
-         (or (memq (car expirable) gnus-newsgroup-expirable)
-             (gnus-summary-mark-as-read (car expirable) "%"))
-         (setq expirable (cdr expirable))))))
-
-;; Suggested by Jack Vinson <vinson@unagi.cis.upenn.edu>.
-(defun gnus-summary-delete-article (n)
-  "Delete the N next (mail) articles.
-This command actually deletes articles. This is not a marking
-command. The article will disappear forever from you life, never to
-return. 
-If N is negative, delete backwards.
-If N is nil and articles have been marked with the process mark,
-delete these instead."
-  (interactive "P")
-  (or (gnus-check-backend-function 'request-expire-articles 
-                                  gnus-newsgroup-name)
-      (error "The current newsgroup does not support article deletion."))
-  ;; Compute the list of articles to delete.
-  (let (articles)
-    (if (and n (numberp n))
-       (let ((backward (< n 0))
-             (n (abs n)))
-         (save-excursion
-           (while (and (> n 0)
-                       (setq articles (cons (gnus-summary-article-number) 
-                                            articles))
-                       (gnus-summary-search-forward nil nil backward))
-             (setq n (1- n))))
-         (setq articles (sort articles (function <))))
-      (setq articles (or (setq gnus-newsgroup-processable
-                              (sort gnus-newsgroup-processable (function <)))
-                        (list (gnus-summary-article-number)))))
-    (if (and gnus-novice-user
-            (not (gnus-y-or-n-p 
-                  (format "Do you really want to delete %s forever? "
-                          (if (> (length articles) 1) "these articles"
-                            "this article")))))
-       ()
-      ;; Delete the articles.
-      (setq gnus-newsgroup-expirable 
-           (gnus-request-expire-articles 
-            articles gnus-newsgroup-name 'force))
-      (while articles
-       (gnus-summary-mark-as-read (car articles) gnus-canceled-mark)
-       (setq articles (cdr articles))))))
-
-(defun gnus-summary-edit-article ()
-  "Enter into a buffer and edit the current article.
-This will have permanent effect only in mail groups."
-  (interactive)
-  (or (gnus-check-backend-function 
-       'request-replace-article gnus-newsgroup-name)
-      (error "The current newsgroup does not support article editing."))
-  (gnus-summary-select-article t)
-  (other-window 1)
-  (message "C-c C-c to end edits")
-  (setq buffer-read-only nil)
-  (text-mode)
-  (use-local-map (copy-keymap (current-local-map)))
-  (local-set-key "\C-c\C-c" 'gnus-summary-edit-article-done)
-  (goto-char 1)
-  (search-forward "\n\n" nil t))
-
-(defun gnus-summary-edit-article-done ()
-  "Make edits to the current article permanent."
-  (interactive)
-  (if (not (gnus-request-replace-article 
-           (cdr gnus-article-current) (car gnus-article-current) 
-           (current-buffer)))
-      (error "Couldn't replace article.")
-    (gnus-article-mode)
-    (use-local-map gnus-article-mode-map)
-    (setq buffer-read-only t)
-    (pop-to-buffer gnus-summary-buffer)))
-
 (defun gnus-summary-mark-article-as-replied (article)
   "Mark ARTICLE replied and update the summary line."
   (setq gnus-newsgroup-replied (cons article gnus-newsgroup-replied))
@@ -7995,7 +8130,8 @@ If the prefix argument is negative, tick articles instead."
   "Sort summary buffer by article number.
 Argument REVERSE means reverse order."
   (interactive "P")
-  (gnus-summary-sort 'gnus-summary-article-number reverse))
+  (gnus-summary-sort 
+   (cons 'gnus-summary-article-number 'gnus-thread-sort-by-number) reverse))
 
 (defun gnus-summary-sort-by-author (reverse)
   "Sort summary buffer by author name alphabetically.
@@ -8003,12 +8139,14 @@ If case-fold-search is non-nil, case of letters is ignored.
 Argument REVERSE means reverse order."
   (interactive "P")
   (gnus-summary-sort
-   (lambda ()
-     (let ((extract (funcall
-                    gnus-extract-address-components
-                    (header-from (gnus-get-header-by-number
-                                  (gnus-summary-article-number))))))
-       (or (car extract) (cdr extract))))
+   (cons
+    (lambda ()
+      (let ((extract (funcall
+                     gnus-extract-address-components
+                     (header-from (gnus-get-header-by-number
+                                   (gnus-summary-article-number))))))
+       (or (car extract) (cdr extract))))
+    'gnus-thread-sort-by-author)
    reverse))
 
 (defun gnus-summary-sort-by-subject (reverse)
@@ -8017,8 +8155,10 @@ If case-fold-search is non-nil, case of letters is ignored.
 Argument REVERSE means reverse order."
   (interactive "P")
   (gnus-summary-sort
-   (lambda ()
-     (downcase (gnus-simplify-subject (gnus-summary-subject-string))))
+   (cons
+    (lambda ()
+      (downcase (gnus-simplify-subject (gnus-summary-subject-string))))
+    'gnus-thread-sort-by-subject)
    reverse))
 
 (defun gnus-summary-sort-by-date (reverse)
@@ -8026,22 +8166,31 @@ Argument REVERSE means reverse order."
 Argument REVERSE means reverse order."
   (interactive "P")
   (gnus-summary-sort
-   (lambda ()
-     (gnus-sortable-date
-      (header-date (gnus-get-header-by-number (gnus-summary-article-number)))))
+   (cons
+    (lambda ()
+      (gnus-sortable-date
+       (header-date 
+       (gnus-get-header-by-number (gnus-summary-article-number)))))
+    'gnus-thread-sort-by-date)
    reverse))
 
 (defun gnus-summary-sort-by-score (reverse)
   "Sort summary buffer by score.
 Argument REVERSE means reverse order."
   (interactive "P")
-  (gnus-summary-sort 'gnus-summary-article-score (not reverse)))
+  (gnus-summary-sort 
+   (cons 'gnus-summary-article-score 'gnus-thread-sort-by-score)
+   (not reverse)))
 
 (defun gnus-summary-sort (predicate reverse)
   ;; Sort summary buffer by PREDICATE.  REVERSE means reverse order. 
   (let (buffer-read-only)
-    (goto-char (point-min))
-    (sort-subr reverse 'forward-line 'end-of-line predicate)))
+    (if (not gnus-show-threads)
+       (progn
+         (goto-char (point-min))
+         (sort-subr reverse 'forward-line 'end-of-line (car predicate)))
+      (let ((gnus-thread-sort-functions (list (cdr predicate))))
+       (gnus-summary-prepare)))))
 
 (defun gnus-sortable-date (date)
   "Make sortable string by string-lessp from DATE.
@@ -8125,6 +8274,36 @@ save those articles instead."
   (let ((gnus-default-article-saver 'gnus-summary-save-in-mail))
     (gnus-summary-save-article arg)))
 
+(defun gnus-summary-save-article-rmail (arg)
+  "Append the current article to an rmail file.
+If N is a positive number, save the N next articles.
+If N is a negative number, save the N previous articles.
+If N is nil and any articles have been marked with the process mark,
+save those articles instead."
+  (interactive "P")
+  (let ((gnus-default-article-saver 'gnus-summary-save-in-rmail))
+    (gnus-summary-save-article arg)))
+
+(defun gnus-summary-save-article-file (arg)
+  "Append the current article to a file.
+If N is a positive number, save the N next articles.
+If N is a negative number, save the N previous articles.
+If N is nil and any articles have been marked with the process mark,
+save those articles instead."
+  (interactive "P")
+  (let ((gnus-default-article-saver 'gnus-summary-save-in-file))
+    (gnus-summary-save-article arg)))
+
+(defun gnus-summary-save-article-folder (arg)
+  "Append the current article to an mh folder.
+If N is a positive number, save the N next articles.
+If N is a negative number, save the N previous articles.
+If N is nil and any articles have been marked with the process mark,
+save those articles instead."
+  (interactive "P")
+  (let ((gnus-default-article-saver 'gnus-summary-save-in-folder))
+    (gnus-summary-save-article arg)))
+
 (defun gnus-summary-save-in-rmail (&optional filename)
   "Append this article to Rmail file.
 Optional argument FILENAME specifies file name.
@@ -8579,8 +8758,10 @@ See `gnus-score-expiry-days'."
 
 
 (defun gnus-article-mode ()
-  "Major mode for reading an article.
+  "Major mode for displaying an article.
+
 All normal editing commands are switched off.
+
 The following commands are available:
 
 \\<gnus-article-mode-map>
@@ -9268,268 +9449,6 @@ ROT47 will be performed for Japanese text in any case."
          (insert str)))))
 
 \f
-;;;
-;;; Gnus Kill File Mode
-;;;
-
-(defvar gnus-kill-file-mode-map nil)
-
-(if gnus-kill-file-mode-map
-    nil
-  (setq gnus-kill-file-mode-map (copy-keymap emacs-lisp-mode-map))
-  (define-key gnus-kill-file-mode-map 
-    "\C-c\C-k\C-s" 'gnus-kill-file-kill-by-subject)
-  (define-key gnus-kill-file-mode-map
-    "\C-c\C-k\C-a" 'gnus-kill-file-kill-by-author)
-  (define-key gnus-kill-file-mode-map
-    "\C-c\C-k\C-a" 'gnus-kill-file-kill-by-thread)
-  (define-key gnus-kill-file-mode-map 
-    "\C-c\C-k\C-a" 'gnus-kill-file-kill-by-xref)
-  (define-key gnus-kill-file-mode-map
-    "\C-c\C-a" 'gnus-kill-file-apply-buffer)
-  (define-key gnus-kill-file-mode-map
-    "\C-c\C-e" 'gnus-kill-file-apply-last-sexp)
-  (define-key gnus-kill-file-mode-map 
-    "\C-c\C-c" 'gnus-kill-file-exit))
-
-(defun gnus-kill-file-mode ()
-  "Major mode for editing kill files.
-
-If you are using this mode - you probably shouldn't.  Kill files
-perform badly and paint with a pretty broad brush.  Score files, on
-the other hand, are vastly faster (40x speedup) and give you more
-control over what to do.
-
-In addition to Emacs-Lisp Mode, the following commands are available:
-
-\\{gnus-kill-file-mode-map}
-
-  A kill file contains Lisp expressions to be applied to a selected
-newsgroup.  The purpose is to mark articles as read on the basis of
-some set of regexps.  A global kill file is applied to every newsgroup,
-and a local kill file is applied to a specified newsgroup.  Since a
-global kill file is applied to every newsgroup, for better performance
-use a local one.
-
-  A kill file can contain any kind of Emacs Lisp expressions expected
-to be evaluated in the Summary buffer.  Writing Lisp programs for this
-purpose is not so easy because the internal working of Gnus must be
-well-known.  For this reason, Gnus provides a general function which
-does this easily for non-Lisp programmers.
-
-  The `gnus-kill' function executes commands available in Summary Mode
-by their key sequences. `gnus-kill' should be called with FIELD,
-REGEXP and optional COMMAND and ALL.  FIELD is a string representing
-the header field or an empty string.  If FIELD is an empty string, the
-entire article body is searched for.  REGEXP is a string which is
-compared with FIELD value. COMMAND is a string representing a valid
-key sequence in Summary mode or Lisp expression. COMMAND defaults to
-'(gnus-summary-mark-as-read nil \"X\").  Make sure that COMMAND is
-executed in the Summary buffer.  If the second optional argument ALL
-is non-nil, the COMMAND is applied to articles which are already
-marked as read or unread.  Articles which are marked are skipped over
-by default.
-
-  For example, if you want to mark articles of which subjects contain
-the string `AI' as read, a possible kill file may look like:
-
-       (gnus-kill \"Subject\" \"AI\")
-
-  If you want to mark articles with `D' instead of `X', you can use
-the following expression:
-
-       (gnus-kill \"Subject\" \"AI\" \"d\")
-
-In this example it is assumed that the command
-`gnus-summary-mark-as-read-forward' is assigned to `d' in Summary Mode.
-
-  It is possible to delete unnecessary headers which are marked with
-`X' in a kill file as follows:
-
-       (gnus-expunge \"X\")
-
-  If the Summary buffer is empty after applying kill files, Gnus will
-exit the selected newsgroup normally.  If headers which are marked
-with `D' are deleted in a kill file, it is impossible to read articles
-which are marked as read in the previous Gnus sessions.  Marks other
-than `D' should be used for articles which should really be deleted.
-
-Entry to this mode calls emacs-lisp-mode-hook and
-gnus-kill-file-mode-hook with no arguments, if that value is non-nil."
-  (interactive)
-  (kill-all-local-variables)
-  (use-local-map gnus-kill-file-mode-map)
-  (set-syntax-table emacs-lisp-mode-syntax-table)
-  (setq major-mode 'gnus-kill-file-mode)
-  (setq mode-name "Kill")
-  (lisp-mode-variables nil)
-  (run-hooks 'emacs-lisp-mode-hook 'gnus-kill-file-mode-hook))
-
-(defun gnus-kill-file-edit-file (newsgroup)
-  "Begin editing a kill file for NEWSGROUP.
-If NEWSGROUP is nil, the global kill file is selected."
-  (interactive "sNewsgroup: ")
-  (let ((file (gnus-newsgroup-kill-file newsgroup)))
-    (gnus-make-directory (file-name-directory file))
-    ;; Save current window configuration if this is first invocation.
-    (or (and (get-file-buffer file)
-            (get-buffer-window (get-file-buffer file)))
-       (setq gnus-winconf-kill-file (current-window-configuration)))
-    ;; Hack windows.
-    (let ((buffer (find-file-noselect file)))
-      (cond ((get-buffer-window buffer)
-            (pop-to-buffer buffer))
-           ((eq major-mode 'gnus-group-mode)
-            (gnus-configure-windows '(1 0 0)) ;Take all windows.
-            (pop-to-buffer gnus-group-buffer)
-            ;; Fix by sachs@SLINKY.CS.NYU.EDU (Jay Sachs).
-            (let ((gnus-summary-buffer buffer))
-              (gnus-configure-windows '(1 1 0))) ;Split into two.
-            (pop-to-buffer buffer))
-           ((eq major-mode 'gnus-summary-mode)
-            (gnus-configure-windows 'article)
-            (pop-to-buffer gnus-article-buffer)
-            (bury-buffer gnus-article-buffer)
-            (switch-to-buffer buffer))
-           (t                          ;No good rules.
-            (find-file-other-window file))))
-    (gnus-kill-file-mode)))
-
-;; Fix by Sudish Joseph <joseph@cis.ohio-state.edu>.
-(defun gnus-kill-set-kill-buffer ()
-  (let* ((file (gnus-newsgroup-kill-file gnus-newsgroup-name))
-        (buffer (find-file-noselect file)))
-    (set-buffer buffer)
-    (gnus-kill-file-mode)
-    (bury-buffer buffer)))
-
-(defun gnus-kill-save-kill-buffer ()
-  (save-excursion
-    (let ((file (gnus-newsgroup-kill-file gnus-newsgroup-name)))
-      (if (get-file-buffer file)
-         (progn
-           (set-buffer (get-file-buffer file))
-           (and (buffer-modified-p) (save-buffer))
-           (kill-buffer (current-buffer)))))))
-
-(defun gnus-kill-file-enter-kill (field regexp)
-  ;; Enter kill file entry.
-  ;; FIELD: String containing the name of the header field to kill.
-  ;; REGEXP: The string to kill.
-  (save-excursion
-    (let (string)
-      (gnus-kill-set-kill-buffer)
-      (goto-char (point-max))
-      (insert (setq string (format "(gnus-kill %S %S)\n" field regexp)))
-      (gnus-kill-file-apply-string string))))
-    
-(defun gnus-kill-file-kill-by-subject ()
-  "Kill by subject."
-  (interactive)
-  (gnus-kill-file-enter-kill
-   "Subject" 
-   (regexp-quote 
-    (gnus-simplify-subject (header-subject gnus-current-headers)))))
-  
-(defun gnus-kill-file-kill-by-author ()
-  "Kill by author."
-  (interactive)
-  (gnus-kill-file-enter-kill
-   "From" (regexp-quote (header-from gnus-current-headers))))
-(defun gnus-kill-file-kill-by-thread ()
-  "Kill by author."
-  (interactive "p")
-  (gnus-kill-file-enter-kill
-   "References" (regexp-quote (header-id gnus-current-headers))))
-(defun gnus-kill-file-kill-by-xref ()
-  "Kill by Xref."
-  (interactive)
-  (let ((xref (header-xref gnus-current-headers))
-       (start 0)
-       group)
-    (if xref
-       (while (string-match " \\([^ \t]+\\):" xref start)
-         (setq start (match-end 0))
-         (if (not (string= 
-                   (setq group 
-                         (substring xref (match-beginning 1) (match-end 1)))
-                   gnus-newsgroup-name))
-             (gnus-kill-file-enter-kill 
-              "Xref" (concat " " (regexp-quote group) ":"))))
-      (gnus-kill-file-enter-kill "Xref" ""))))
-
-(defun gnus-kill-file-raise-followups-to-author (level)
-  "Raise score for all followups to the current author."
-  (interactive "p")
-  (let ((name (header-from gnus-current-headers))
-       string)
-    (save-excursion
-      (gnus-kill-set-kill-buffer)
-      (goto-char (point-min))
-      (setq name (read-string (concat "Add " level
-                                     " to followup articles to: ")
-                             (regexp-quote name)))
-      (setq 
-       string
-       (format
-       "(gnus-kill %S %S '(gnus-summary-temporarily-raise-by-thread %S))\n"
-       "From" name level))
-      (insert string)
-      (gnus-kill-file-apply-string string))
-    (message "Added permanent score file entry for followups to %s." name)))
-
-(defun gnus-kill-file-apply-buffer ()
-  "Apply current buffer to current newsgroup."
-  (interactive)
-  (if (and gnus-current-kill-article
-          (get-buffer gnus-summary-buffer))
-      ;; Assume newsgroup is selected.
-      (gnus-kill-file-apply-string (buffer-string))
-    (ding) (message "No newsgroup is selected.")))
-
-(defun gnus-kill-file-apply-string (string)
-  "Apply STRING to current newsgroup."
-  (interactive)
-  (let ((string (concat "(progn \n" string "\n)")))
-    (save-excursion
-      (save-window-excursion
-       (pop-to-buffer gnus-summary-buffer)
-       (eval (car (read-from-string string)))))))
-
-(defun gnus-kill-file-apply-last-sexp ()
-  "Apply sexp before point in current buffer to current newsgroup."
-  (interactive)
-  (if (and gnus-current-kill-article
-          (get-buffer gnus-summary-buffer))
-      ;; Assume newsgroup is selected.
-      (let ((string
-            (buffer-substring
-             (save-excursion (forward-sexp -1) (point)) (point))))
-       (save-excursion
-         (save-window-excursion
-           (pop-to-buffer gnus-summary-buffer)
-           (eval (car (read-from-string string))))))
-    (ding) (message "No newsgroup is selected.")))
-
-(defun gnus-kill-file-exit ()
-  "Save a kill file, then return to the previous buffer."
-  (interactive)
-  (save-buffer)
-  (let ((killbuf (current-buffer)))
-    ;; We don't want to return to article buffer.
-    (and (get-buffer gnus-article-buffer)
-        (bury-buffer gnus-article-buffer))
-    ;; Delete the KILL file windows.
-    (delete-windows-on killbuf)
-    ;; Restore last window configuration if available.
-    (and gnus-winconf-kill-file
-        (set-window-configuration gnus-winconf-kill-file))
-    (setq gnus-winconf-kill-file nil)
-    ;; Kill the KILL file buffer.  Suggested by tale@pawl.rpi.edu.
-    (kill-buffer killbuf)))
-
 ;; Basic ideas by emv@math.lsa.umich.edu (Edward Vielmetti)
 
 ;;;###autoload
@@ -9579,26 +9498,25 @@ score the alt hierarchy, you'd say \"!alt.all\"."
     (switch-to-buffer gnus-group-buffer)
     (gnus-group-save-newsrc)))
 
-;; For kill files
+(defun gnus-apply-kill-file ()
+  "Apply a kill file to the current newsgroup.
+Returns the number of articles marked as read."
+  (if (or (file-exists-p (gnus-newsgroup-kill-file nil))
+         (file-exists-p (gnus-newsgroup-kill-file gnus-newsgroup-name)))
+      (gnus-apply-kill-file-internal)
+    0))
 
-(defun gnus-Newsgroup-kill-file (newsgroup)
-  "Return the name of a kill file for NEWSGROUP.
-If NEWSGROUP is nil, return the global kill file instead."
-  (cond ((or (null newsgroup)
-            (string-equal newsgroup ""))
-        ;; The global kill file is placed at top of the directory.
-        (expand-file-name gnus-kill-file-name
-                          (or gnus-kill-files-directory "~/News")))
-       (gnus-use-long-file-name
-        ;; Append ".KILL" to capitalized newsgroup name.
-        (expand-file-name (concat (gnus-capitalize-newsgroup newsgroup)
-                                  "." gnus-kill-file-name)
-                          (or gnus-kill-files-directory "~/News")))
-       (t
-        ;; Place "KILL" under the hierarchical directory.
-        (expand-file-name (concat (gnus-newsgroup-directory-form newsgroup)
-                                  "/" gnus-kill-file-name)
-                          (or gnus-kill-files-directory "~/News")))))
+(defun gnus-kill-save-kill-buffer ()
+  (save-excursion
+    (let ((file (gnus-newsgroup-kill-file gnus-newsgroup-name)))
+      (if (get-file-buffer file)
+         (progn
+           (set-buffer (get-file-buffer file))
+           (and (buffer-modified-p) (save-buffer))
+           (kill-buffer (current-buffer)))))))
+
+(defvar gnus-kill-file-name "KILL"
+  "Suffix of the kill files.")
 
 (defun gnus-newsgroup-kill-file (newsgroup)
   "Return the name of a kill file name for NEWSGROUP.
@@ -9618,234 +9536,6 @@ If NEWSGROUP is nil, return the global kill file name instead."
                                   "/" gnus-kill-file-name)
                           (or gnus-kill-files-directory "~/News")))))
 
-(defalias 'gnus-expunge 'gnus-summary-remove-lines-marked-with)
-
-(defun gnus-apply-kill-file ()
-  "Apply a kill file to the current newsgroup.
-Returns the number of articles marked as read."
-  (let* ((kill-files (list (gnus-newsgroup-kill-file nil)
-                          (gnus-newsgroup-kill-file gnus-newsgroup-name)))
-        (unreads (length gnus-newsgroup-unreads))
-        (gnus-summary-inhibit-highlight t)
-        (mark-below (or gnus-summary-mark-below gnus-summary-default-score 0))
-        (expunge-below gnus-summary-expunge-below)
-        form beg)
-    (setq gnus-newsgroup-kill-headers nil)
-    (or gnus-newsgroup-headers-hashtb-by-number
-       (gnus-make-headers-hashtable-by-number))
-    ;; If there are any previously scored articles, we remove these
-    ;; from the `gnus-newsgroup-headers' list that the score functions
-    ;; will see. This is probably pretty wasteful when it comes to
-    ;; conses, but is, I think, faster than having to assq in every
-    ;; single score funtion.
-    (let ((files kill-files))
-      (while files
-       (if (file-exists-p (car files))
-           (let ((headers gnus-newsgroup-headers))
-             (if gnus-kill-killed
-                 (setq gnus-newsgroup-kill-headers
-                       (mapcar (lambda (header) (header-number header))
-                               headers))
-               (while headers
-                 (or (gnus-member-of-range 
-                      (header-number (car headers)) 
-                      gnus-newsgroup-killed)
-                     (setq gnus-newsgroup-kill-headers 
-                           (cons (header-number (car headers))
-                                 gnus-newsgroup-kill-headers)))
-                 (setq headers (cdr headers))))
-             (setq files nil))
-         (setq files (cdr files)))))
-    (if gnus-newsgroup-kill-headers
-       (save-excursion
-         (while kill-files
-           (if (file-exists-p (car kill-files))
-               (progn
-                 (message "Processing kill file %s..." (car kill-files))
-                 (find-file (car kill-files))
-                 (goto-char (point-min))
-                 (while (progn
-                          (setq beg (point))
-                          (setq form (condition-case nil 
-                                         (read (current-buffer)) 
-                                       (error nil))))
-                   (if (or (eq (car form) 'gnus-kill)
-                           (eq (car form) 'gnus-raise)
-                           (eq (car form) 'gnus-lower))
-                       (progn
-                         (delete-region beg (point))
-                         (insert (or (eval form) "")))
-                     (condition-case ()
-                         (eval form)
-                       (error nil))))
-                 (and (buffer-modified-p) (save-buffer))
-                 (message "Processing kill file %s...done" (car kill-files))))
-           (setq kill-files (cdr kill-files)))))
-    (if beg
-       (let ((nunreads (- unreads (length gnus-newsgroup-unreads))))
-         (or (eq nunreads 0)
-             (message "Marked %d articles as read" nunreads))
-         nunreads)
-      0)))
-
-;; Kill changes and new format by suggested by JWZ and Sudish Joseph
-;; <joseph@cis.ohio-state.edu>.  
-(defun gnus-kill (field regexp &optional exe-command all)
-  "If FIELD of an article matches REGEXP, execute COMMAND.
-Optional 1st argument COMMAND is default to
-       (gnus-summary-mark-as-read nil \"X\").
-If optional 2nd argument ALL is non-nil, articles marked are also applied to.
-If FIELD is an empty string (or nil), entire article body is searched for.
-COMMAND must be a lisp expression or a string representing a key sequence."
-  ;; We don't want to change current point nor window configuration.
-  (save-excursion
-    (save-window-excursion
-      ;; Selected window must be summary buffer to execute keyboard
-      ;; macros correctly. See command_loop_1.
-      (switch-to-buffer gnus-summary-buffer 'norecord)
-      (goto-char (point-min))          ;From the beginning.
-      (let ((kill-list regexp)
-           (date (current-time-string))
-           (command (or exe-command '(gnus-summary-mark-as-read 
-                                      nil gnus-kill-file-mark)))
-           kill kdate prev)
-       (if (listp kill-list)
-           ;; It is a list.
-           (if (not (consp (cdr kill-list)))
-               ;; It's on the form (regexp . date).
-               (if (zerop (gnus-execute field (car kill-list) 
-                                        command nil (not all)))
-                   (if (> (gnus-days-between date (cdr kill-list))
-                          gnus-score-expiry-days)
-                       (setq regexp nil))
-                 (setcdr kill-list date))
-             (while (setq kill (car kill-list))
-               (if (consp kill)
-                   ;; It's a temporary kill.
-                   (progn
-                     (setq kdate (cdr kill))
-                     (if (zerop (gnus-execute 
-                                 field (car kill) command nil (not all)))
-                         (if (> (gnus-days-between date kdate)
-                                gnus-score-expiry-days)
-                             ;; Time limit has been exceeded, so we
-                             ;; remove the match.
-                             (if prev
-                                 (setcdr prev (cdr kill-list))
-                               (setq regexp (cdr regexp))))
-                       ;; Successful kill. Set the date to today.
-                       (setcdr kill date)))
-                 ;; It's a permanent kill.
-                 (gnus-execute field kill command nil (not all)))
-               (setq prev kill-list)
-               (setq kill-list (cdr kill-list))))
-         (gnus-execute field kill-list command nil (not all))))))
-  (if (and (eq major-mode 'gnus-kill-file-mode) regexp)
-      (gnus-pp-gnus-kill
-       (nconc (list 'gnus-kill field 
-                   (if (consp regexp) (list 'quote regexp) regexp))
-             (if (or exe-command all) (list (list 'quote exe-command)))
-             (if all (list t) nil)))))
-
-(defun gnus-pp-gnus-kill (object)
-  (if (or (not (consp (nth 2 object)))
-         (not (consp (cdr (nth 2 object))))
-         (and (eq 'quote (car (nth 2 object)))
-              (not (consp (cdr (car (cdr (nth 2 object))))))))
-      (concat "\n" (prin1-to-string object))
-    (save-excursion
-      (set-buffer (get-buffer-create "*Gnus PP*"))
-      (buffer-disable-undo (current-buffer))
-      (erase-buffer)
-      (insert (format "\n(%S %S\n  '(" (nth 0 object) (nth 1 object)))
-      (let ((klist (car (cdr (nth 2 object))))
-           (first t))
-       (while klist
-         (insert (if first (progn (setq first nil) "")  "\n    ")
-                 (prin1-to-string (car klist)))
-         (setq klist (cdr klist))))
-      (insert ")")
-      (and (nth 3 object)
-          (insert "\n  " 
-                  (if (and (consp (nth 3 object))
-                           (not (eq 'quote (car (nth 3 object))))) 
-                      "'" "")
-                  (prin1-to-string (nth 3 object))))
-      (and (nth 4 object)
-          (insert "\n  t"))
-      (insert ")")
-      (prog1
-         (buffer-substring (point-min) (point-max))
-       (kill-buffer (current-buffer))))))
-
-(defun gnus-execute-1 (function regexp form header)
-  (save-excursion
-    (let (did-kill)
-      (if (null header)
-         nil                           ;Nothing to do.
-       (if function
-           ;; Compare with header field.
-           (let (value)
-             (and header
-                  (progn
-                    (setq value (funcall function header))
-                    ;; Number (Lines:) or symbol must be converted to string.
-                    (or (stringp value)
-                        (setq value (prin1-to-string value)))
-                    (setq did-kill (string-match regexp value)))
-                  (if (stringp form)   ;Keyboard macro.
-                      (execute-kbd-macro form)
-                    (funcall form))))
-         ;; Search article body.
-         (let ((gnus-current-article nil) ;Save article pointer.
-               (gnus-last-article nil)
-               (gnus-break-pages nil)  ;No need to break pages.
-               (gnus-mark-article-hook nil)) ;Inhibit marking as read.
-           (message "Searching for article: %d..." (header-number header))
-           (gnus-article-setup-buffer)
-           (gnus-article-prepare (header-number header) t)
-           (if (save-excursion
-                 (set-buffer gnus-article-buffer)
-                 (goto-char (point-min))
-                 (setq did-kill (re-search-forward regexp nil t)))
-               (if (stringp form)      ;Keyboard macro.
-                   (execute-kbd-macro form)
-                 (eval form))))))
-      did-kill)))
-
-(defun gnus-execute (field regexp form &optional backward ignore-marked)
-  "If FIELD of article header matches REGEXP, execute lisp FORM (or a string).
-If FIELD is an empty string (or nil), entire article body is searched for.
-If optional 1st argument BACKWARD is non-nil, do backward instead.
-If optional 2nd argument IGNORE-MARKED is non-nil, articles which are
-marked as read or ticked are ignored."
-  (save-excursion
-    (let ((killed-no 0)
-         function header article)
-      (if (or (null field) (string-equal field ""))
-         (setq function nil)
-       ;; Get access function of header filed.
-       (setq function (intern-soft (concat "gnus-header-" (downcase field))))
-       (if (and function (fboundp function))
-           (setq function (symbol-function function))
-         (error "Unknown header field: \"%s\"" field))
-       ;; Make FORM funcallable.
-       (if (and (listp form) (not (eq (car form) 'lambda)))
-           (setq form (list 'lambda nil form))))
-      ;; Starting from the current article.
-      (while (or (and (not article)
-                     (setq article (gnus-summary-article-number))
-                     t)
-                (setq article 
-                      (gnus-summary-search-subject 
-                       backward (not ignore-marked))))
-       (and (or (null gnus-newsgroup-kill-headers)
-                (memq article gnus-newsgroup-kill-headers))
-            (gnus-execute-1 function regexp form 
-                            (gnus-get-header-by-number article))
-            (setq killed-no (1+ killed-no))))
-      killed-no)))
-
 \f
 ;;;
 ;;; Gnus Score Files
@@ -9869,7 +9559,7 @@ marked as read or ticked are ignored."
   "Automatically expunge articles with score below SCORE."
   (interactive 
    (list (or (and current-prefix-arg (prefix-numeric-value current-prefix-arg))
-            (string-to-int (read-string "Mark below: ")))))
+            (string-to-int (read-string "Expunge below: ")))))
   (setq score (or score gnus-summary-default-score 0))
   (gnus-score-set 'expunge (list score))
   (gnus-score-set 'touched '(t)))
@@ -9915,8 +9605,8 @@ marked as read or ticked are ignored."
   (setq gnus-current-score-file file)
   (gnus-score-load-file file))
 
-(defun gnus-score-edit-file (file)
-  "Edit score file."
+(defun gnus-score-edit-alist (file)
+  "Edit the current score alist."
   (interactive (list gnus-current-score-file))
   (and (buffer-name gnus-summary-buffer) (gnus-score-save))
   (setq gnus-winconf-edit-score (current-window-configuration))
@@ -9926,17 +9616,31 @@ marked as read or ticked are ignored."
            "\\<gnus-score-mode-map>\\[gnus-score-edit-done] to save edits"))
   (gnus-score-mode))
   
+(defun gnus-score-edit-file (file)
+  "Edit a score file."
+  (interactive 
+   (list (read-file-name "Edit score file: " gnus-kill-files-directory)))
+  (and (buffer-name gnus-summary-buffer) (gnus-score-save))
+  (setq gnus-winconf-edit-score (current-window-configuration))
+  (gnus-configure-windows 'article)
+  (pop-to-buffer (find-file-noselect file))
+  (message (substitute-command-keys 
+           "\\<gnus-score-mode-map>\\[gnus-score-edit-done] to save edits"))
+  (gnus-score-mode))
+  
 (defun gnus-score-load-file (file)
   ;; Load score file FILE.  Returns a list a retrieved score-alists.
-  (let ((cached (assoc file gnus-score-cache))
-       (global (member file gnus-internal-global-score-files))
-       lists)
+  (let* ((file (expand-file-name (or (and (string-match "^/" file) file)
+                                    (concat gnus-kill-files-directory file))))
+        (cached (assoc file gnus-score-cache))
+        (global (member file gnus-internal-global-score-files))
+        lists alist)
     (if cached
        ;; The score file was already loaded.
        (setq gnus-score-alist (cdr cached))
       ;; We load the score file.
       (setq gnus-score-alist nil)
-      (gnus-score-load-score-alist file)
+      (setq alist (gnus-score-load-score-alist file))
       ;; We add '(touched) to the alist to signify that it hasn't been
       ;; touched (yet). 
       (if (not (assq 'touched gnus-score-alist))
@@ -9970,10 +9674,10 @@ marked as read or ticked are ignored."
                                        (gnus-score-load-file file)) 
                                      files))))
       (and eval (not global) (eval eval))
-      (setq gnus-summary-mark-below (or mark mark-and-expunge 
-                                       gnus-summary-default-score))
+      (setq gnus-summary-mark-below (or mark mark-and-expunge))
       (setq gnus-summary-expunge-below (or expunge mark-and-expunge)))
     (setq gnus-current-score-file file)
+    (setq gnus-score-alist alist)
     lists))
 
 (defun gnus-score-load (file)
@@ -10053,7 +9757,7 @@ marked as read or ticked are ignored."
                cache (cdr cache)
                file (car entry)
                score (cdr entry))
-         (if (or (not (eq (gnus-score-get 'touched score) '(t)))
+         (if (or (not (equal (gnus-score-get 'touched score) '(t)))
                  (gnus-score-get 'read-only score)
                  (not (file-writable-p file)))
              ()
@@ -12196,9 +11900,8 @@ The `-n' option line from .newsrc is respected."
                     (progn
                       (setq info (cdr entry))
                       (setq num (car entry)))
-                  (setq active (or (gnus-gethash group gnus-active-hashtb)
-                                   '(0 . 0)))
-                  (setq num (- (1+ (cdr active)) (car active)))
+                  (setq active (gnus-gethash group gnus-active-hashtb))
+                  (setq num (if active (- (1+ (cdr active)) (car active)) t))
                   ;; Check whether the group is foreign. If so, the
                   ;; foreign select method has to be entered into the
                   ;; info. 
@@ -12376,26 +12079,41 @@ newsgroup."
          (t
           ;; The read list is a list of ranges. Fix them according to
           ;; the active hash table.
-          (while (and (cdr range) (>= (car active) (car (car (cdr range)))))
+          ;; First peel off any elements that are below the lower
+          ;; active limit. 
+          (while (and (cdr range) 
+                      (>= (car active) 
+                          (or (and (atom (car (cdr range))) (car (cdr range)))
+                              (car (car (cdr range))))))
             (setcdr (car range) (cdr (car (cdr range))))
             (setcdr range (cdr (cdr range))))
-          (if (< (cdr (car range)) (car active)) 
+          ;; Adjust the first element to be the same as the lower limit. 
+          (if (and (not (atom (car range))) 
+                   (< (cdr (car range)) (car active)))
               (setcdr (car range) (car active)))
+          ;; Then we want to peel off any elements that are higher
+          ;; than the upper active limit.  
           (let ((srange range))
+            ;; Go past all legal elements.
             (while (and (cdr srange) 
-                        (<= (car (car (cdr srange))) (cdr active)))
+                        (<= (or (and (atom (car (cdr srange)))
+                                     (car (cdr srange)))
+                                (car (car (cdr srange)))) (cdr active)))
               (setq srange (cdr srange)))
             (if (cdr srange)
-                (progn
-                  (setcdr srange nil)
-                  (if (> (cdr (car srange)) (cdr active))
-                      (setcdr (car srange) (cdr active)))))
-            (if (and srange (> (cdr (car srange)) (cdr active)))
+                ;; Nuke all remaining illegal elements.
+                (setcdr srange nil))
+
+            ;; Adjust the final element.
+            (if (and (not (atom (car srange)))
+                     (> (cdr (car srange)) (cdr active)))
                 (setcdr (car srange) (cdr active))))
           ;; Compute the number of unread articles.
           (while range
-            (setq num (+ num (- (1+ (cdr (car range))) 
-                                (car (car range)))))
+            (setq num (+ num (- (1+ (or (and (atom (car range)) (car range))
+                                        (cdr (car range))))
+                                (or (and (atom (car range)) (car range))
+                                    (car (car range))))))
             (setq range (cdr range)))
           (setq num (max 0 (- (cdr active) num)))))
     (and info
@@ -12472,7 +12190,8 @@ Returns whether the updating was successful."
       ;; unread articles.  
       (while unread
        (if (/= (car unread) prev)
-           (setq read (cons (cons prev (1- (car unread))) read)))
+           (setq read (cons (if (= prev (1- (car unread))) prev
+                              (cons prev (1- (car unread)))) read)))
        (setq prev (1+ (car unread)))
        (setq unread (cdr unread)))
       (if (<= prev (cdr active))
@@ -12634,6 +12353,7 @@ If FORCE is non-nil, the .newsrc file is read."
     (condition-case nil
        (load ding-file t t t)
       (error nil))
+    (gnus-uncompress-newsrc-assoc)
     (gnus-make-hashtable-from-newsrc-alist)
     (if (not (file-newer-than-file-p file ding-file))
        ()
@@ -12688,12 +12408,40 @@ If FORCE is non-nil, the .newsrc file is read."
     (if (file-exists-p real-file)
        real-file file)))
 
-;; jwz: rewrote this function to be much more efficient, and not be subject
-;; to regexp overflow errors when it encounters very long lines -- the old
-;; behavior was to blow off the rest of the *file* when a line was encountered
-;; that was too long to match!!  Now it uses only simple looking-at calls, and
-;; doesn't create as many temporary strings.  It also now handles multiple
-;; consecutive options lines (before it only handled the first.)
+(defun gnus-uncompress-newsrc-assoc ()
+  ;; Uncompress all lists of marked articles in the newsrc assoc.
+  (let ((newsrc gnus-newsrc-assoc)
+       marked)
+    (while newsrc
+      (if (not (setq marked (nth 3 (car newsrc))))
+         ()
+       (while marked
+         (or (eq 'score (car (car marked)))
+             (setcdr (car marked) (gnus-uncompress-range (cdr (car marked)))))
+         (setq marked (cdr marked))))
+      (setq newsrc (cdr newsrc)))))
+
+(defun gnus-compress-newsrc-assoc ()
+  ;; Compress all lists of marked articles in the newsrc assoc.
+  (let ((newsrc gnus-newsrc-assoc)
+       marked)
+    (while newsrc
+      (if (not (setq marked (nth 3 (car newsrc))))
+         ()
+       (while marked
+         (or (eq 'score (car (car marked)))
+             (setcdr (car marked) 
+                     (gnus-compress-sequence (sort (cdr (car marked)) '<) t)))
+         (setq marked (cdr marked))))
+      (setq newsrc (cdr newsrc)))))
+
+;; jwz: rewrote this function to be much more efficient, and not be
+;; subject to regexp overflow errors when it encounters very long
+;; lines -- the old behavior was to blow off the rest of the *file*
+;; when a line was encountered that was too long to match!!  Now it
+;; uses only simple looking-at calls, and doesn't create as many
+;; temporary strings.  It also now handles multiple consecutive
+;; options lines (before it only handled the first.)
 ;; Tiny rewrite by lmi. 
 (defun gnus-newsrc-to-gnus-format ()
   "Parse current buffer as .newsrc file."
@@ -12703,7 +12451,6 @@ If FORCE is non-nil, the .newsrc file is read."
   (setq gnus-newsrc-options nil)
   (setq gnus-newsrc-options-n-yes nil)
   (setq gnus-newsrc-options-n-no nil)
-  (setq gnus-newsrc-assoc nil)
   (gnus-parse-options-lines)
   (gnus-parse-newsrc-body))
 
@@ -12855,15 +12602,14 @@ If FORCE is non-nil, the .newsrc file is read."
            (if info
                (progn
                  (setcar (nthcdr 2 info) (nreverse read-list))
-                 (setcar (cdr info) (if subscribe 3 (if read-list 6 7)))
-                 (setq gnus-newsrc-assoc (cons info gnus-newsrc-assoc)))
+                 (setcar (cdr info) (if subscribe 3 (if read-list 6 7))))
              (setq gnus-newsrc-assoc
                    (cons (list newsgroup (if subscribe 3 (if read-list 6 7))
                                (nreverse read-list))
                          gnus-newsrc-assoc))))))
        (setq line (1+ line))
        (forward-line 1))))
-  (setq gnus-newsrc-assoc (nreverse gnus-newsrc-assoc))
+  (setq gnus-newsrc-assoc (cdr gnus-newsrc-assoc))
   (gnus-make-hashtable-from-newsrc-alist)
   nil)
 
@@ -12969,6 +12715,7 @@ If FORCE is non-nil, the .newsrc file is read."
        (gnus-newsrc-assoc (cdr gnus-newsrc-assoc))
        variable)
     ;; insert lisp expressions.
+    (gnus-compress-newsrc-assoc)
     (while variables
       (setq variable (car variables))
       (and (boundp variable)
@@ -12977,7 +12724,9 @@ If FORCE is non-nil, the .newsrc file is read."
           (insert "(setq " (symbol-name variable) " '"
                   (prin1-to-string (symbol-value variable))
                   ")\n"))
-      (setq variables (cdr variables)))))
+      (setq variables (cdr variables)))
+    (gnus-uncompress-newsrc-assoc)))
+
 
 (defun gnus-gnus-to-newsrc-format ()
   ;; Generate and save the .newsrc file.
@@ -12998,7 +12747,7 @@ If FORCE is non-nil, the .newsrc file is read."
              (if (setq ranges (nth 2 info))
                  (progn
                    (insert " ")
-                   (if (atom (car ranges))
+                   (if (not (listp (cdr ranges)))
                        (if (= (car ranges) (cdr ranges))
                            (insert (int-to-string (car ranges)))
                          (insert (int-to-string (car ranges)) "-" 
@@ -13006,8 +12755,10 @@ If FORCE is non-nil, the .newsrc file is read."
                      (while ranges
                        (setq range (car ranges)
                              ranges (cdr ranges))
-                       (if (= (car range) (cdr range))
-                           (insert (int-to-string (car range)))
+                       (if (or (atom range) (= (car range) (cdr range)))
+                           (insert (int-to-string 
+                                    (or (and (atom range) range) 
+                                        (car range))))
                          (insert (int-to-string (car range)) "-"
                                  (int-to-string (cdr range))))
                        (if ranges (insert ","))))))
index 2dd41ac..9c1903d 100644 (file)
@@ -23,6 +23,9 @@
 
 ;;; Commentary:
 
+;; For an overview of what the interface functions do, please see the
+;; Gnus sources.  
+
 ;;; Code:
 
 (require 'nnheader)
@@ -57,8 +60,6 @@
 ;;; Interface functions
 
 (defun nnbabyl-retrieve-headers (sequence &optional newsgroup server)
-  "Retrieve the headers for the articles in SEQUENCE.
-Newsgroup must be selected before calling this function."
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
@@ -111,27 +112,21 @@ Newsgroup must be selected before calling this function."
       'headers)))
 
 (defun nnbabyl-open-server (host &optional service)
-  "Open mbox backend."
   (setq nnbabyl-status-string "")
   (setq nnbabyl-group-alist nil)
   (nnheader-init-server-buffer))
 
 (defun nnbabyl-close-server (&optional server)
-  "Close news server."
   t)
 
 (defun nnbabyl-server-opened (&optional server)
-  "Return server process status, T or NIL.
-If the stream is opened, return T, otherwise return NIL."
   (and nntp-server-buffer
        (get-buffer nntp-server-buffer)))
 
 (defun nnbabyl-status-message (&optional server)
-  "Return server status response as string."
   nnbabyl-status-string)
 
 (defun nnbabyl-request-article (article &optional newsgroup server buffer)
-  "Select ARTICLE by number."
   (nnbabyl-possibly-change-newsgroup newsgroup)
   (if (stringp article)
       nil
@@ -162,7 +157,6 @@ If the stream is opened, return T, otherwise return NIL."
              t))))))
 
 (defun nnbabyl-request-group (group &optional server dont-check)
-  "Select news GROUP."
   (save-excursion
     (if (nnbabyl-possibly-change-newsgroup group)
        (if dont-check
@@ -184,31 +178,22 @@ If the stream is opened, return T, otherwise return NIL."
   t)
 
 (defun nnbabyl-request-list (&optional server)
-  "List active newsgoups."
   (if server (nnbabyl-get-new-mail))
   (nnmail-find-file nnbabyl-active-file))
 
 (defun nnbabyl-request-newgroups (date &optional server)
-  "List groups created after DATE."
   (nnbabyl-request-list server))
 
 (defun nnbabyl-request-list-newsgroups (&optional server)
-  "List newsgroups (defined in NNTP2)."
   (setq nnbabyl-status-string "nnbabyl: LIST NEWSGROUPS is not implemented.")
   nil)
 
 (defun nnbabyl-request-post (&optional server)
-  "Post a new news in current buffer."
   (mail-send-and-exit nil))
 
 (fset 'nnbabyl-request-post-buffer 'nnmail-request-post-buffer)
 
 (defun nnbabyl-request-expire-articles (articles newsgroup &optional server force)
-  "Expire all articles in the ARTICLES list in group GROUP.
-The list of unexpired articles will be returned (ie. all articles that
-were too fresh to be expired).
-If FORCE is non-nil, the ARTICLES will be deleted without looking at
-the date."
   (nnbabyl-possibly-change-newsgroup newsgroup)
   (let* ((days (or (and nnmail-expiry-wait-function
                        (funcall nnmail-expiry-wait-function newsgroup))
@@ -232,6 +217,14 @@ the date."
              (setq rest (cons (car articles) rest))))
        (setq articles (cdr articles)))
       (save-buffer)
+      ;; Find the lowest active article in this group.
+      (let ((active (nth 1 (assoc newsgroup nnbabyl-group-alist))))
+       (goto-char (point-min))
+       (while (not (search-forward
+                    (nnbabyl-article-string (car active)) nil t))
+         (setcar (car active) (1+ (car active)))
+         (goto-char (point-min))))
+      (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file)
       rest)))
 
 (defun nnbabyl-request-move-article 
@@ -300,10 +293,10 @@ the date."
 \f
 ;;; Low-Level Interface
 
+;; If FORCE, delete article no matter how many X-Gnus-Newsgroup
+;; headers there are. If LEAVE-DELIM, don't delete the Unix mbox
+;; delimeter line.
 (defun nnbabyl-delete-mail (&optional force leave-delim)
-  "If FORCE, delete article no matter how many X-Gnus-Newsgroup
-headers there are. If LEAVE-DELIM, don't delete the Unix mbox
-delimeter line."
   ;; Delete the current X-Gnus-Newsgroup line.
   (or force
       (delete-region
@@ -348,7 +341,7 @@ delimeter line."
          (int-to-string article)))
 
 (defun nnbabyl-save-mail ()
-  "Called narrowed to an article."
+  ;; Called narrowed to an article.
   (let ((group-art (nreverse (nnmail-article-group 'nnbabyl-active-number))))
     (nnmail-insert-lines)
     (nnmail-insert-xref group-art)
@@ -372,7 +365,7 @@ delimeter line."
            (setq group-art (cdr group-art)))))))
 
 (defun nnbabyl-active-number (group)
-  "Find the next article number in GROUP."
+  ;; Find the next article number in GROUP.
   (let ((active (car (cdr (assoc group nnbabyl-group-alist)))))
     (setcdr active (1+ (cdr active)))
     (cdr active)))
index 5fcae1c..a77b391 100644 (file)
@@ -69,6 +69,7 @@ Newsgroup must be selected before calling this function."
                  (forward-char -1)
                (goto-char (point-max))
                (insert "\n\n"))
+             (insert (format "Lines: %d\n" (count-lines (point) (point-max))))
              (insert ".\n")
              (delete-region (point) (point-max))))
        (setq sequence (cdr sequence)))
@@ -194,9 +195,7 @@ Newsgroup must be selected before calling this function."
          (narrow-to-region 
           (point)
           (or (and (re-search-forward nndigest-separator nil t)
-                   (progn
-                     (beginning-of-line)
-                     (point)))
+                   (match-beginning 0))
               (point-max)))
          (cons (point-min) (point-max)))
       nil)))
index b7700bd..c6198f5 100644 (file)
@@ -52,7 +52,7 @@ Newsgroup must be selected before calling this function."
     (let ((file nil)
          (number (length sequence))
          (count 0)
-         beg article art-string start stop)
+         beg article art-string start stop lines)
       (nndoc-possibly-change-buffer newsgroup server)
       (while sequence
        (setq article (car sequence))
@@ -66,12 +66,20 @@ Newsgroup must be selected before calling this function."
                        (concat "^" rmail-unix-mail-delimiter) nil t)
                       (point-min))))
              (search-forward "\n\n" nil t)
+             (setq lines (count-lines 
+                          (point)
+                          (or
+                           (save-excursion
+                             (re-search-forward 
+                              (concat "^" rmail-unix-mail-delimiter) nil t))
+                           (point-max))))
              (setq stop (1- (point)))
              (set-buffer nntp-server-buffer)
              (insert (format "221 %d Article retrieved.\n" article))
              (setq beg (point))
              (insert-buffer-substring nndoc-current-buffer start stop)
              (goto-char (point-max))
+             (insert (format "Lines: %d\n" lines))
              (insert ".\n")))
        (setq sequence (cdr sequence)))
 
index 998db04..9422f3a 100644 (file)
@@ -23,6 +23,9 @@
 
 ;;; Commentary:
 
+;; For an overview of what the interface functions do, please see the
+;; Gnus sources.  
+
 ;;; Code:
 
 (require 'nnheader)
@@ -55,8 +58,6 @@
 ;;; Interface functions
 
 (defun nnfolder-retrieve-headers (sequence &optional newsgroup server)
-  "Retrieve the headers for the articles in SEQUENCE.
-Newsgroup must be selected before calling this function."
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
@@ -94,27 +95,21 @@ Newsgroup must be selected before calling this function."
       'headers)))
 
 (defun nnfolder-open-server (host &optional service)
-  "Open mbox backend."
   (setq nnfolder-status-string "")
   (setq nnfolder-group-alist nil)
   (nnheader-init-server-buffer))
 
 (defun nnfolder-close-server (&optional server)
-  "Close news server."
   t)
 
 (defun nnfolder-server-opened (&optional server)
-  "Return server process status, T or NIL.
-If the stream is opened, return T, otherwise return NIL."
   (and nntp-server-buffer
        (buffer-name nntp-server-buffer)))
 
 (defun nnfolder-status-message (&optional server)
-  "Return server status response as string."
   nnfolder-status-string)
 
 (defun nnfolder-request-article (article &optional newsgroup server buffer)
-  "Select ARTICLE by number."
   (nnfolder-possibly-change-group newsgroup)
   (if (stringp article)
       nil
@@ -143,7 +138,6 @@ If the stream is opened, return T, otherwise return NIL."
              t))))))
 
 (defun nnfolder-request-group (group &optional server dont-check)
-  "Select news GROUP."
   (save-excursion
     (nnfolder-possibly-change-group group)
     (and (assoc group nnfolder-group-alist)
@@ -166,7 +160,6 @@ If the stream is opened, return T, otherwise return NIL."
   t)
 
 (defun nnfolder-request-list (&optional server)
-  "List active newsgoups."
   (if server (nnfolder-get-new-mail))
   (or (nnmail-find-file nnfolder-active-file)
       (progn
@@ -175,25 +168,17 @@ If the stream is opened, return T, otherwise return NIL."
        (nnmail-find-file nnfolder-active-file))))
 
 (defun nnfolder-request-newgroups (date &optional server)
-  "List groups created after DATE."
   (nnfolder-request-list server))
 
 (defun nnfolder-request-list-newsgroups (&optional server)
-  "List newsgroups (defined in NNTP2)."
   (nnmail-find-file nnfolder-newsgroups-file))
 
 (defun nnfolder-request-post (&optional server)
-  "Post a new news in current buffer."
   (mail-send-and-exit nil))
 
 (fset 'nnfolder-request-post-buffer 'nnmail-request-post-buffer)
 
 (defun nnfolder-request-expire-articles (articles newsgroup &optional server force)
-  "Expire all articles in the ARTICLES list in group GROUP.
-The list of unexpired articles will be returned (ie. all articles that
-were too fresh to be expired).
-If FORCE is non-nil, the ARTICLES will be deleted without looking at
-the date."
   (nnfolder-possibly-change-group newsgroup)
   (let* ((days (or (and nnmail-expiry-wait-function
                        (funcall nnmail-expiry-wait-function newsgroup))
@@ -217,6 +202,14 @@ the date."
              (setq rest (cons (car articles) rest))))
        (setq articles (cdr articles)))
       (save-buffer)
+      ;; Find the lowest active article in this group.
+      (let ((active (nth 1 (assoc newsgroup nnfolder-group-alist))))
+       (goto-char (point-min))
+       (while (not (search-forward
+                    (nnfolder-article-string (car active)) nil t))
+         (setcar (car active) (1+ (car active)))
+         (goto-char (point-min))))
+      (nnmail-save-active nnfolder-group-alist nnfolder-active-file)
       rest)))
 
 (defun nnfolder-request-move-article
@@ -253,7 +246,6 @@ the date."
   (nnfolder-possibly-change-group group)
   (let ((buf (current-buffer))
        result beg)
-    (debug (current-buffer))
     (goto-char (point-min))
     (if (looking-at "X-From-Line: ")
        (replace-match "From ")
@@ -293,9 +285,6 @@ the date."
 ;;; Internal functions.
 
 (defun nnfolder-delete-mail (&optional force leave-delim)
-  "If FORCE, delete article no matter how many X-Gnus-Newsgroup
-headers there are. If LEAVE-DELIM, don't delete the Unix mbox
-delimeter line."
   ;; Beginning of the article.
   (save-excursion
     (save-restriction
@@ -388,7 +377,6 @@ delimeter line."
                          (cdr group-art) (current-time-string)))))))
 
 (defun nnfolder-active-number (group)
-  "Find the next article number in GROUP."
   (let ((active (car (cdr (assoc group nnfolder-group-alist)))))
     (setcdr active (1+ (cdr active)))
     (cdr active)))
@@ -418,6 +406,7 @@ delimeter line."
            (save-excursion
              (save-restriction
                (narrow-to-region start end)
+               (nnmail-insert-lines)
                (nnfolder-insert-newsgroup-line 
                 (cons nil (nnfolder-active-number nnfolder-current-group))))))
        (goto-char end)))
index 52ed8e6..31a15a8 100644 (file)
 (defvar news-reply-yank-from nil)
 (defvar news-reply-yank-message-id nil)
 
+;; All backends use this function, so I moved it to this file.
+
 (defun nnheader-init-server-buffer ()
   (save-excursion
     (setq nntp-server-buffer (get-buffer-create " *nntpd*"))
index f534862..34e4175 100644 (file)
@@ -78,16 +78,16 @@ says how many days an article can be stored before it is considered
 Eg.:
 
 (setq nnmail-expiry-wait-function
-  (function
-    (lambda (newsgroup)
-      (cond ((string-match \"private\" newsgroup) 31)
-            ((string-match \"junk\" newsgroup) 1)
-           (t 7)))))")
+      (lambda (newsgroup)
+        (cond ((string-match \"private\" newsgroup) 31)
+              ((string-match \"junk\" newsgroup) 1)
+             (t 7))))")
 
 (defvar nnmail-spool-file 
   (or (getenv "MAIL")
       (concat "/usr/spool/mail/" (user-login-name)))
   "Where the mail backends will look for incoming mail.
+This variable is \"/usr/spool/mail/$user\" by default.
 If this variable is nil, no mail backends will read incoming mail.")
 
 (defvar nnmail-read-incoming-hook nil
@@ -101,16 +101,19 @@ running (\"xwatch\", etc.)
 Eg.
 
 (add-hook 'nnmail-read-incoming-hook 
-         (function
           (lambda () 
             (start-process \"mailsend\" nil 
-                           \"/local/bin/mailsend\" \"read\" \"mbox\"))))")
+                           \"/local/bin/mailsend\" \"read\" \"mbox\")))")
 
 ;; Suggested by Erik Selberg <speed@cs.washington.edu>.
 (defvar nnmail-prepare-incoming-hook nil
   "Hook called before treating incoming mail.
 The hook is run in a buffer with all the new, incoming mail.")
 
+;; Suggested by Mejia Pablo J <pjm9806@usl.edu>.
+(defvar nnmail-tmp-directory nil
+  "If non-nil, use this directory for temporary storage when reading incoming mail.")
+
 (defvar nnmail-large-newsgroup 50
   "The number of the articles which indicates a large newsgroup.
 If the number of the articles is greater than the value, verbose
@@ -229,6 +232,10 @@ messages will be shown to indicate the current status.")
                (expand-file-name (substitute-in-file-name inbox))))
        (tofile (make-temp-name (expand-file-name tofile)))
        movemail popmail errors)
+    ;; Check whether the inbox is to be moved to the special tmp dir. 
+    (if nnmail-tmp-directory
+       (setq tofile (concat (file-name-as-directory nnmail-tmp-directory)
+                            (file-name-nondirectory tofile))))
     ;; If getting from mail spool directory,
     ;; use movemail to move rather than just renaming,
     ;; so as to interlock with the mailer.
index 175af1d..800c8bb 100644 (file)
@@ -23,6 +23,9 @@
 
 ;;; Commentary:
 
+;; For an overview of what the interface functions do, please see the
+;; Gnus sources.  
+
 ;;; Code:
 
 (require 'nnheader)
@@ -55,8 +58,6 @@
 ;;; Interface functions
 
 (defun nnmbox-retrieve-headers (sequence &optional newsgroup server)
-  "Retrieve the headers for the articles in SEQUENCE.
-Newsgroup must be selected before calling this function."
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
@@ -107,27 +108,21 @@ Newsgroup must be selected before calling this function."
       'headers)))
 
 (defun nnmbox-open-server (host &optional service)
-  "Open mbox backend."
   (setq nnmbox-status-string "")
   (setq nnmbox-group-alist nil)
   (nnheader-init-server-buffer))
 
 (defun nnmbox-close-server (&optional server)
-  "Close news server."
   t)
 
 (defun nnmbox-server-opened (&optional server)
-  "Return server process status, T or NIL.
-If the stream is opened, return T, otherwise return NIL."
   (and nntp-server-buffer
        (get-buffer nntp-server-buffer)))
 
 (defun nnmbox-status-message (&optional server)
-  "Return server status response as string."
   nnmbox-status-string)
 
 (defun nnmbox-request-article (article &optional newsgroup server buffer)
-  "Select ARTICLE by number."
   (nnmbox-possibly-change-newsgroup newsgroup)
   (if (stringp article)
       nil
@@ -156,7 +151,6 @@ If the stream is opened, return T, otherwise return NIL."
              t))))))
 
 (defun nnmbox-request-group (group &optional server dont-check)
-  "Select news GROUP."
   (save-excursion
     (if (nnmbox-possibly-change-newsgroup group)
        (if dont-check
@@ -178,7 +172,6 @@ If the stream is opened, return T, otherwise return NIL."
   t)
 
 (defun nnmbox-request-list (&optional server)
-  "List active newsgoups."
   (if server (nnmbox-get-new-mail))
   (or (nnmail-find-file nnmbox-active-file)
       (progn
@@ -187,26 +180,19 @@ If the stream is opened, return T, otherwise return NIL."
        (nnmail-find-file nnmbox-active-file))))
 
 (defun nnmbox-request-newgroups (date &optional server)
-  "List groups created after DATE."
   (nnmbox-request-list server))
 
 (defun nnmbox-request-list-newsgroups (&optional server)
-  "List newsgroups (defined in NNTP2)."
   (setq nnmbox-status-string "nnmbox: LIST NEWSGROUPS is not implemented.")
   nil)
 
 (defun nnmbox-request-post (&optional server)
-  "Post a new news in current buffer."
   (mail-send-and-exit nil))
 
 (fset 'nnmbox-request-post-buffer 'nnmail-request-post-buffer)
 
-(defun nnmbox-request-expire-articles (articles newsgroup &optional server force)
-  "Expire all articles in the ARTICLES list in group GROUP.
-The list of unexpired articles will be returned (ie. all articles that
-were too fresh to be expired).
-If FORCE is non-nil, the ARTICLES will be deleted without looking at
-the date."
+(defun nnmbox-request-expire-articles 
+  (articles newsgroup &optional server force)
   (nnmbox-possibly-change-newsgroup newsgroup)
   (let* ((days (or (and nnmail-expiry-wait-function
                        (funcall nnmail-expiry-wait-function newsgroup))
@@ -230,6 +216,14 @@ the date."
              (setq rest (cons (car articles) rest))))
        (setq articles (cdr articles)))
       (save-buffer)
+      ;; Find the lowest active article in this group.
+      (let ((active (nth 1 (assoc newsgroup nnmbox-group-alist))))
+       (goto-char (point-min))
+       (while (not (search-forward
+                    (nnmbox-article-string (car active)) nil t))
+         (setcar (car active) (1+ (car active)))
+         (goto-char (point-min))))
+      (nnmail-save-active nnmbox-group-alist nnmbox-active-file)
       rest)))
 
 (defun nnmbox-request-move-article
@@ -264,7 +258,6 @@ the date."
 (defun nnmbox-request-accept-article (group &optional last)
   (let ((buf (current-buffer))
        result beg)
-    (debug (current-buffer))
     (goto-char (point-min))
     (if (looking-at "X-From-Line: ")
        (replace-match "From ")
@@ -303,10 +296,10 @@ the date."
 \f
 ;;; Internal functions.
 
+;; If FORCE, delete article no matter how many X-Gnus-Newsgroup
+;; headers there are. If LEAVE-DELIM, don't delete the Unix mbox
+;; delimeter line.
 (defun nnmbox-delete-mail (&optional force leave-delim)
-  "If FORCE, delete article no matter how many X-Gnus-Newsgroup
-headers there are. If LEAVE-DELIM, don't delete the Unix mbox
-delimeter line."
   ;; Delete the current X-Gnus-Newsgroup line.
   (or force
       (delete-region
index 0ba5266..895268e 100644 (file)
@@ -24,6 +24,8 @@
 ;;; Commentary:
 
 ;; Based on nnspool.el by Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>.
+;; For an overview of what the interface functions do, please see the
+;; Gnus sources.  
 
 ;;; Code:
 
@@ -55,8 +57,6 @@
 ;;; Interface functions.
 
 (defun nnmh-retrieve-headers (sequence &optional newsgroup server)
-  "Retrieve the headers for the articles in SEQUENCE.
-Newsgroup must be selected before calling this function."
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
@@ -80,6 +80,7 @@ Newsgroup must be selected before calling this function."
                  (forward-char -1)
                (goto-char (point-max))
                (insert "\n\n"))
+             (insert (format "Lines: %d\n" (count-lines (point) (point-max))))
              (insert ".\n")
              (delete-region (point) (point-max))))
        (setq sequence (cdr sequence))
@@ -101,26 +102,20 @@ Newsgroup must be selected before calling this function."
       'headers)))
 
 (defun nnmh-open-server (host &optional service)
-  "Open nnmh mail backend."
   (setq nnmh-status-string "")
   (nnheader-init-server-buffer))
 
 (defun nnmh-close-server (&optional server)
-  "Close news server."
   t)
 
 (defun nnmh-server-opened (&optional server)
-  "Return server process status, T or NIL.
-If the stream is opened, return T, otherwise return NIL."
   (and nntp-server-buffer
        (get-buffer nntp-server-buffer)))
 
 (defun nnmh-status-message (&optional server)
-  "Return server status response as string."
   nnmh-status-string)
 
 (defun nnmh-request-article (id &optional newsgroup server buffer)
-  "Select article by message ID (or number)."
   (nnmh-possibly-change-directory newsgroup)
   (let ((file (if (stringp id)
                  nil
@@ -133,7 +128,6 @@ If the stream is opened, return T, otherwise return NIL."
          (nnmail-find-file file)))))
 
 (defun nnmh-request-group (group &optional server dont-check)
-  "Select news GROUP."
   (and nnmh-get-new-mail (or dont-check (nnmh-get-new-mail)))
   (let ((pathname (nnmail-article-pathname group nnmh-directory))
        dir)
@@ -165,7 +159,6 @@ If the stream is opened, return T, otherwise return NIL."
          t))))
 
 (defun nnmh-request-list (&optional server dir)
-  "Get list of active articles in all newsgroups."
   (and server nnmh-get-new-mail (nnmh-get-new-mail))
   (or dir
       (save-excursion
@@ -200,20 +193,14 @@ If the stream is opened, return T, otherwise return NIL."
   t)
 
 (defun nnmh-request-newgroups (date &optional server)
-  "List groups created after DATE."
   (nnmh-request-list server))
 
 (defun nnmh-request-post (&optional server)
-  "Post a new news in current buffer."
   (mail-send-and-exit nil))
 
 (fset 'nnmh-request-post-buffer 'nnmail-request-post-buffer)
 
 (defun nnmh-request-expire-articles (articles newsgroup &optional server force)
-  "Expire all articles in the ARTICLES list in group GROUP.
-The list of unexpired articles will be returned (ie. all articles that
-were too fresh to be expired).
-If FORCE is non-nil, ARTICLES will be deleted whether they are old or not."
   (nnmh-possibly-change-directory newsgroup)
   (let* ((days (or (and nnmail-expiry-wait-function
                        (funcall nnmail-expiry-wait-function newsgroup))
@@ -355,12 +342,12 @@ If FORCE is non-nil, ARTICLES will be deleted whether they are old or not."
 (defun nnmh-get-new-mail ()
   "Read new incoming mail."
   (let (incoming)
-    (nnmh-create-directories)
     (if (and nnmh-get-new-mail nnmail-spool-file
             (file-exists-p nnmail-spool-file)
             (> (nth 7 (file-attributes nnmail-spool-file)) 0))
        (progn
          (message "nnmh: Reading incoming mail...")
+         (nnmh-create-directories)
          (setq incoming 
                (nnmail-move-inbox nnmail-spool-file
                                   (concat nnmh-directory "Incoming")))
index 7ade6d8..f591ff3 100644 (file)
@@ -24,6 +24,8 @@
 ;;; Commentary:
 
 ;; Based on nnspool.el by Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>.
+;; For an overview of what the interface functions do, please see the
+;; Gnus sources.  
 
 ;;; Code:
 
@@ -71,8 +73,6 @@ all. This may very well take some time.")
 ;;; Interface functions.
 
 (defun nnml-retrieve-headers (sequence &optional newsgroup server)
-  "Retrieve the headers for the articles in SEQUENCE.
-Newsgroup must be selected before calling this function."
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
@@ -125,21 +125,16 @@ Newsgroup must be selected before calling this function."
   (nnheader-init-server-buffer))
 
 (defun nnml-close-server (&optional server)
-  "Close news server."
   t)
 
 (defun nnml-server-opened (&optional server)
-  "Return server process status, T or NIL.
-If the stream is opened, return T, otherwise return NIL."
   (and nntp-server-buffer
        (get-buffer nntp-server-buffer)))
 
 (defun nnml-status-message (&optional server)
-  "Return server status response as string."
   nnml-status-string)
 
 (defun nnml-request-article (id &optional newsgroup server buffer)
-  "Select article by message ID (or number)."
   (nnml-possibly-change-directory newsgroup)
   (let ((file (if (stringp id)
                  nil
@@ -152,7 +147,6 @@ If the stream is opened, return T, otherwise return NIL."
          (nnmail-find-file file)))))
 
 (defun nnml-request-group (group &optional server dont-check)
-  "Select news GROUP."
   (if (not (nnml-possibly-change-directory group))
       (progn
        (setq nnml-status-string "Invalid group (no such directory)")
@@ -183,58 +177,58 @@ If the stream is opened, return T, otherwise return NIL."
   t)
 
 (defun nnml-request-list (&optional server)
-  "List active newsgoups."
   (if server (nnml-get-new-mail))
   (save-excursion
     (nnmail-find-file nnml-active-file)))
 
 (defun nnml-request-newgroups (date &optional server)
-  "List groups created after DATE."
   (nnml-request-list server))
 
 (defun nnml-request-list-newsgroups (&optional server)
-  "List newsgroups (defined in NNTP2)."
   (save-excursion
     (nnmail-find-file nnml-newsgroups-file)))
 
 (defun nnml-request-post (&optional server)
-  "Post a new news in current buffer."
   (mail-send-and-exit nil))
 
 (fset 'nnml-request-post-buffer 'nnmail-request-post-buffer)
 
 (defun nnml-request-expire-articles (articles newsgroup &optional server force)
-  "Expire all articles in the ARTICLES list in group GROUP.
-The list of unexpired articles will be returned (ie. all articles that
-were too fresh to be expired).
-If FORCE is non-nil, ARTICLES will be deleted whether they are old or not."
   (nnml-possibly-change-directory newsgroup)
   (let* ((days (or (and nnmail-expiry-wait-function
                        (funcall nnmail-expiry-wait-function newsgroup))
                   nnmail-expiry-wait))
+        (active-articles 
+         (mapcar
+          (function
+           (lambda (name)
+             (string-to-int name)))
+          (directory-files nnml-current-directory nil "^[0-9]+$" t)))
+        (max-article (max active-articles))
         article rest mod-time)
-    (if nnmail-keep-last-article
-       (progn
-         (setq articles (sort articles '>))
-         (setq rest (cons (car articles) rest))
-         (setq articles (cdr articles))))
     (while articles
       (setq article (concat nnml-current-directory (int-to-string
                                                      (car articles))))
       (if (setq mod-time (nth 5 (file-attributes article)))
-         (if (or force
-                 (> (nnmail-days-between
-                     (current-time-string)
-                     (current-time-string mod-time))
-                    days))
+         (if (and (or (not nnmail-keep-last-article)
+                      (not (= (car articles) max-article)))
+                  (or force
+                      (> (nnmail-days-between
+                          (current-time-string)
+                          (current-time-string mod-time))
+                         days)))
              (progn
                (and gnus-verbose-backends (message "Deleting %s..." article))
                (condition-case ()
                    (delete-file article)
                  (file-error nil))
+               (setq active-articles (delq (car articles) active-articles))
                (nnml-nov-delete-article newsgroup (car articles)))
            (setq rest (cons (car articles) rest))))
       (setq articles (cdr articles)))
+    (let ((active (nth 1 (assoc newsgroup nnml-group-alist))))
+      (setcar active (min active-articles))
+      (nnmail-save-active nnml-group-alist nnml-active-file))
     (nnml-save-nov)
     rest))
 
index b4ed194..81de65f 100644 (file)
@@ -185,9 +185,9 @@ instead call function `nntp-status-message' to get status message.")
        'headers))))
 
 (defun nntp-open-server (server &optional service)
-  "Open news server on SERVER.
+  "Open SERVER.
 If SERVER is nil, use value of environment variable `NNTPSERVER'.
-If optional argument SERVICE is non-nil, open by the service name."
+If SERVICE, this this as the port number."
   (let ((server (or server (getenv "NNTPSERVER")))
        (status nil)
        (timer 
@@ -215,7 +215,7 @@ If optional argument SERVICE is non-nil, open by the service name."
     status))
 
 (defun nntp-close-server (&optional server)
-  "Close news server."
+  "Close connection to SERVER."
   (nntp-possibly-change-server nil server)
   (unwind-protect
       (progn
@@ -232,8 +232,7 @@ If optional argument SERVICE is non-nil, open by the service name."
 (fset 'nntp-request-quit (symbol-function 'nntp-close-server))
 
 (defun nntp-server-opened (&optional server)
-  "Return server process status.
-If the stream is opened, return non-nil, otherwise return nil."
+  "Say whether a connection to SERVER has been opened."
   (if (or server nntp-current-server)
       (let ((process (nth 1 (assoc (or server nntp-current-server)
                                   nntp-server-alist))))
@@ -241,7 +240,7 @@ If the stream is opened, return non-nil, otherwise return nil."
             (memq (process-status process) '(open run))))))
 
 (defun nntp-status-message (&optional server)
-  "Return server status response as string."
+  "Return server status as a string."
   (if (and nntp-status-string
           ;; NNN MESSAGE
           (string-match "[0-9][0-9][0-9][ \t]+\\([^\r]*\\).*$"
@@ -251,7 +250,7 @@ If the stream is opened, return non-nil, otherwise return nil."
     nntp-status-string))
 
 (defun nntp-request-article (id &optional newsgroup server buffer)
-  "Select article by message ID (or number)."
+  "Request article ID (message-id or number)."
   (nntp-possibly-change-server newsgroup server)
   (unwind-protect
       (progn
@@ -264,7 +263,7 @@ If the stream is opened, return non-nil, otherwise return nil."
     (if buffer (set-process-buffer nntp-server-process nntp-server-buffer))))
 
 (defun nntp-request-body (id &optional newsgroup server)
-  "Select article body by message ID (or number)."
+  "Request body of article ID (message-id or number)."
   (nntp-possibly-change-server newsgroup server)
   (prog1
       ;; If NEmacs, end of message may look like: "\256\215" (".^M")
@@ -272,77 +271,79 @@ If the stream is opened, return non-nil, otherwise return nil."
     (nntp-decode-text)))
 
 (defun nntp-request-head (id &optional newsgroup server)
-  "Select article head by message ID (or number)."
+  "Request head of article ID (message-id or number)."
   (nntp-possibly-change-server newsgroup server)
   (prog1
       (nntp-send-command "^\\.\r$" "HEAD" id)
     (nntp-decode-text)))
 
 (defun nntp-request-stat (id &optional newsgroup server)
-  "Select article by message ID (or number)."
+  "Request STAT of article ID (message-id or number)."
   (nntp-possibly-change-server newsgroup server)
   (nntp-send-command "^[23].*\r$" "STAT" id))
 
 (defun nntp-request-group (group &optional server dont-check)
-  "Select news GROUP."
+  "Select GROUP."
   (if (nntp-possibly-change-server nil server)
       (nntp-send-command "^.*\r$" "GROUP" group)))
 
 (defun nntp-request-group-description (group &optional server)
-  "Select news GROUP."
+  "Get description of GROUP."
   (if (nntp-possibly-change-server nil server)
-      (nntp-send-command "^.*\r$" "XGTITLE" group)))
+      (prog1
+         (nntp-send-command "^.*\r$" "XGTITLE" group)
+       (nntp-decode-text))))
 
 (defun nntp-close-group (group &optional server)
   t)
 
 (defun nntp-request-list (&optional server)
-  "List active newsgroups."
+  "List active groups."
   (nntp-possibly-change-server nil server)
   (prog1
       (nntp-send-command "^\\.\r$" "LIST")
     (nntp-decode-text)))
 
 (defun nntp-request-list-newsgroups (&optional server)
-  "List newsgroups (defined in NNTP2)."
+  "List groups."
   (nntp-possibly-change-server nil server)
   (prog1
       (nntp-send-command "^\\.\r$" "LIST NEWSGROUPS")
     (nntp-decode-text)))
 
 (defun nntp-request-newgroups (date &optional server)
-  "List new groups (defined in NNTP2)."
+  "List new groups."
   (nntp-possibly-change-server nil server)
-  (let ((date (timezone-parse-date date))
-       (time-string
-        (format "%s%02d%02d %s%s%s"
-                (substring (aref date 0) 2) (string-to-int (aref date 1)) 
-                (string-to-int (aref date 2)) (substring (aref date 3) 0 2)
-                (substring (aref date 3) 3 5) (substring (aref date 3) 6 8))))
+  (let* ((date (timezone-parse-date date))
+        (time-string
+         (format "%s%02d%02d %s%s%s"
+                 (substring (aref date 0) 2) (string-to-int (aref date 1)) 
+                 (string-to-int (aref date 2)) (substring (aref date 3) 0 2)
+                 (substring 
+                  (aref date 3) 3 5) (substring (aref date 3) 6 8))))
     (prog1
        (nntp-send-command "^\\.\r$" "NEWGROUPS" time-string)
       (nntp-decode-text))))
 
 (defun nntp-request-list-distributions (&optional server)
-  "List distributions (defined in NNTP2)."
+  "List distributions."
   (nntp-possibly-change-server nil server)
   (prog1
       (nntp-send-command "^\\.\r$" "LIST DISTRIBUTIONS")
     (nntp-decode-text)))
 
 (defun nntp-request-last (&optional newsgroup server)
-  "Set current article pointer to the previous article
-in the current news group."
+  "Decrease the current article pointer."
   (nntp-possibly-change-server newsgroup server)
   (nntp-send-command "^[23].*\r$" "LAST"))
 
 (defun nntp-request-next (&optional newsgroup server)
-  "Advance current article pointer."
+  "Advance the current article pointer."
   (nntp-possibly-change-server newsgroup server)
   (nntp-send-command "^[23].*\r$" "NEXT"))
 
 (defun nntp-request-post (&optional server)
-  "Post a new news in current buffer."
+  "Post the current buffer."
   (nntp-possibly-change-server nil server)
   (if (nntp-send-command "^[23].*\r$" "POST")
       (progn
@@ -353,8 +354,14 @@ in the current news group."
        (nntp-wait-for-response "^[23].*$"))))
 
 (defun nntp-request-post-buffer 
-  (post group subject header article-buffer info follow-to
-       respect-poster)
+  (post group subject header article-buffer info follow-to respect-poster)
+  "Request a buffer suitable for composing an article.
+If POST, this is an original article; otherwise it's a followup.
+GROUP is the group to be posted to, the article should have subject
+SUBJECT.  HEADER is a Gnus header vector.  ARTICLE-BUFFER contains the
+article being followed up.  INFO is a Gnus info list.  If FOLLOW-TO,
+post to this group instead.  If RESPECT-POSTER, heed the special
+\"poster\" value of the Followup-to header."
   (if (assq 'to-address (nth 4 info))
       (nnmail-request-post-buffer 
        post group subject header article-buffer info follow-to respect-poster)
@@ -427,7 +434,7 @@ in the current news group."
 (defun nntp-send-mode-reader ()
   "Send the MODE READER command to the nntp server.
 This function is supposed to be called from `nntp-server-opened-hook'.
-It will make innd servers enter nnrpd mode to allow actual article
+It will make innd servers spawn an nnrpd process to allow actual article
 reading."
   (nntp-send-command "^.*\r$" "MODE READER"))
 
@@ -471,21 +478,19 @@ It will prompt for a password."
     (set-buffer nntp-server-buffer)
     ;; Insert newline at end of buffer.
     (goto-char (point-max))
-    (if (not (bolp))
-       (insert "\n"))
+    (or (bolp) (insert "\n"))
     ;; Delete status line.
     (goto-char (point-min))
     (delete-region (point) (progn (forward-line 1) (point)))
-    ;; Delete `^M' at end of line.
-    ;; (replace-regexp "\r$" "")
+    ;; Delete `^M' at the end of lines.
     (while (not (eobp))
       (end-of-line)
-      (if (= (preceding-char) ?\r)
-         (delete-char -1))
+      (and (= (preceding-char) ?\r)
+          (delete-char -1))
       (forward-line 1))
-    ;; Delete `.' at end of buffer (end of text mark).
+    ;; Delete `.' at end of the buffer (end of text mark).
     (goto-char (point-max))
-    (forward-line -1)                  ;(beginning-of-line)
+    (forward-line -1)
     (if (looking-at "^\\.$")
        (delete-region (point) (progn (forward-line 1) (point))))
     ;; Replace `..' at beginning of line with `.'.
@@ -501,8 +506,7 @@ It will prompt for a password."
   (save-excursion
     ;; Insert newline at end of buffer.
     (goto-char (point-max))
-    (if (not (bolp))
-       (insert "\n"))
+    (or (bolp) (insert "\n"))
     ;; Replace `.' at beginning of line with `..'.
     (goto-char (point-min))
     ;; (replace-regexp "^\\." "..")
index c7cd266..bc7be82 100644 (file)
@@ -383,7 +383,7 @@ If the stream is opened, return T, otherwise return NIL."
        (gnus-add-marked-articles 
         (car (car group-alist)) (cdr (car mark-lists)) 
         (cdr (car group-alist)) nil t)
-       (gnus-group-update-group (car (car group-alist)))
+       (gnus-group-update-group (car (car group-alist)) t)
        (setq group-alist (cdr group-alist)))
       (setq mark-lists (cdr mark-lists)))))
 
diff --git a/readme b/readme
index 89b1d8c..d4a7902 100644 (file)
--- a/readme
+++ b/readme
@@ -1,67 +1,3 @@
-This package contains a pre-release of (ding) Gnus, version 0.5. The
-lisp directory contains the source lisp files, and the texi directory
-contains an early draft of the Gnus info pages.
-
-IMPORTANT NOTE FOR NNML USERS: If you have used an earlier version of
-this package, you have to do the following:
-
-ESC ESC (load "nnml")
-M-x nnml-generate-nov-databases
-
-nnml will chew on your mail for a while, and then you can use Gnus
-again. Do not attempt to start Gnus before you have done this.
-
-(This note only applies to people who use nnml as a mail backedn.)
-
-
-Gnus is meant to be totally compatible with GNUS. But, alas, it
-probably isn't, which is one of the reasons for this pre-release. 
-
-To use (ding) Gnus you first have to unpack the files, which you've
-obviously done, because you are reading this. 
-
-You should definitely byte-compile the source files. To do that, you
-can simply say "make" in this directory.
-
-Then you have to tell Emacs where Gnus is. You might put something
-like
-
-   (setq load-path (cons (expand-file-name "~/dgnus/lisp") load-path))
-
-in your .emacs file, or wherever you keep such things.
-
-Note that (ding) Gnus and GNUS can not coexist in a single Emacs. They
-both use the same function and variable names. If you have been
-running GNUS in your Emacs, you should probably exit that Emacs and
-start a new one to fire up Gnus.
-
-Then you do a `M-x gnus', and everything should... uhm... it should
-work, but it might not. Set `debug-on-error' to t, and mail me the
-backtraces, or, better yet, find out why Gnus does something wrong,
-fix it, and send me the diffs. :-)
-
-There are three main things I want your help and input on:
-
-1) Startup. Does eveything go smoothly, and why not?
-
-2) Any errors while you read news normally?
-
-3) Any errors if you do anything abnormal?
-
-4) Features you do not like, or do like, but would like to tweak a
-   bit, and features you would like to see.
-
-You do not have to send me typo corrections for the info pages. They
-are a very rough first draft - I haven't even read through it,
-although they should document all of Gnus, I think.
-
-I think I have implemented most of the deep-going changes that I'm
-going to. Things that will probably come in the future, but I haven't
-gotten around to yet is asynchronous posting/pre-fetch of headers and
-articles, better digest handling, a hierarchal Newsgroup buffer,
-allowing the user to provide Newsgroup headers from a function, and a
-few other things that I can't think of at the moment. Oh, and the
-mhspool backend doesn't work at all yet.
-
-Send any comments and all your bug fixes/complaints to
-`larsi@ifi.uio.no'. 
+Ting som ligger under denne katalogen burde du ikke se sÃ¥ veldig mye
+pÃ¥. Den nyeste (pre-)releasen av (ding) Gnus finner du under
+«~larsi/pub/dgnus».
index 2417202..9e888e5 100644 (file)
@@ -1,7 +1,7 @@
 \input texinfo                  @c -*-texinfo-*-
 @comment %**start of header (This is for running Texinfo on a region.)
 @setfilename gnus
-@settitle (ding) Gnus 0.1 Manual
+@settitle (ding) Gnus 0.41 Manual
 @synindex fn cp
 @synindex vr cp
 @synindex pg cp
@@ -89,8 +89,8 @@ push your luck.
 * Key Index::               Key Index.
 @end menu
 
-Note: This is a work of fiction.  Any similarity between this manual and
-real programs is purely coincidental.
+This manual hasn't been prperly proff-read yet, so typos abound, and
+misleading information is sure to exist.  
 
 @node History
 @chapter History
@@ -110,8 +110,8 @@ irritation and/or damage this name may cause you is not the
 responsibility of the author, even though you might like to strangle him
 for the stupid idea.
 
-If you want to take a look at the person responsible for this outrage,
-you can point your (feh!) web browser to
+If you want to investigate the person responsible for this outrage, you
+can point your (feh!) web browser to
 @file{http://www.ifi.uio.no/~larsi/}.  This is also the primary
 distribution point for the new and spiffy versions of Gnus, also know as
 The Site That Destroys Newsrcs And Drives People Mad.
@@ -122,8 +122,9 @@ abbreviation should probably be pronounced "news" as UMEDA intended,
 which makes it a more appropriate name, don't you think?)
 
 @menu
-* Compatibility::          Just how compatible is (ding) Gnus with @sc{GNUS}?
-* New Features::           A short description of all the new stuff in Gnus.
+* Compatibility::       Just how compatible is (ding) Gnus with @sc{GNUS}?
+* New Features::        A short description of all the new stuff in Gnus.
+* Newest Features::     Features so new that they haven't been written yet.
 @end menu
 
 @node Compatibility
@@ -213,11 +214,55 @@ Gnus implements a sliding scale of subscribedness to groups.
 The approach to killing has been changed.  Instead of simply killing or
 not, you can score articles for easier reading.
 
+@node Newest Features
+@section Newest Features
+@cindex todo
+
+Also known as the @dfn{todo list}.  Sure to be implemented before the
+next millennium.
+
+@itemize @bullet
+@item 
+Asynchronous article and header fetching would be very nice.  Pleasant.
+Even useful.  I might even have come up with an idea as to how to
+implement it (two connections, a bit @code{run-at-time}, and lots of
+glue), but this will probably not be implemented within the next few
+months.  In fact, I would put money on it not being implemented before
+(ding) is released, so this is more for Gnus 6.0.  Asynchronous posting,
+however, could possibly be included much sooner, as it is a separate
+issue. 
+@item
+Native @sc{MIME} support is something that should be done.  I was hoping
+I could steal code from @code{Mew}, the @sc{MIME} mail reader for Emacs,
+but I'm not quite sure what the status of that project is.  (ding) might
+support @sc{MIME} quite soon, and it might not.
+@item 
+Some form of caching would come in handy.  Not only for those with
+extremely slow @sc{NNTP} connections, but as a more general way of
+saving articles in a simple fashion.  (You'd basically just mark is as
+@dfn{cached}, Gnus would put it in some local directory, and each time
+you request that article from that group, Gnus would fetch the local
+copy instead.)  Lots of quite interesting stuff to be considered
+(caching @sc{nov} headers or not?) before jumping into it.  It would
+require much twiddling of Gnus internals to make it work transparently.
+@item
+Gnus could detect what articles in a newsgroup you read and which
+articles you kill, and then employ some adaptive scoring scheme.  That
+could potentially be quite interesting, and it's easy enough to
+implement. 
+@item
+When the user references the parent of an article, some sort of
+re-threading should be done to build a proper tree.  The same goes for
+article expunging.  However, as it stands, it's not a trivial issue to
+re-generate parts of the summary buffer.  Generating the entire buffer
+is very easy, but slow.
+@end itemize
+
 @node Terminology
 @chapter Terminology
 
 @cindex terminology
-@table @samp
+@itemize @bullet
 @item news
 This is what you are supposed to use this thing for - reading news.
 News is generally fetched from a nearby NNTP server, and is generally
@@ -248,13 +293,20 @@ are groups that use different backends for getting news.
 A line from the head of an article. 
 @item headers
 A collection of such lines, or a collection of heads.  Or even a
-collection of NOV lines.
-@item NOV
+collection of @sc{NOV} lines.
+@item @sc{NOV}
 When Gnus enters a group, it asks the backend for the headers for all
 the unread articles in the group.  Most servers support the News OverView
 format, which is much smaller and much faster to read than the normal
 HEAD format. 
-@end table
+@item level
+Each group is subscribed at some @dfn{level} or other (1-9).  The ones
+that have a lower level are "more" subscribed than the groups with a
+higher level.  In fact, groups on levels 1-5 are considered
+"subscribed"; 6-7 are "unsubscribed"; 8 are zombies; and 9 are killed.
+Commands for listing groups and scanning for new articles will all use
+the numeric prefix as @dfn{working level}.  
+@end itemize
 
 @node Starting Up
 @chapter Starting Gnus
@@ -363,8 +415,8 @@ groups (ie. @samp{*.newusers}).  (@dfn{Random} is here defined as
 You'll also be subscribed to the Gnus documentation group, which should
 help you with most common problems.  
 
-If @code{gnus-default-subscribed-newsgroups} is @code{t}, Gnus will just use
-the normal functions for handling new groups, and not do anything
+If @code{gnus-default-subscribed-newsgroups} is @code{t}, Gnus will just
+use the normal functions for handling new groups, and not do anything
 special.
 
 @node The Server is Down
@@ -514,8 +566,8 @@ variable to @code{nil}.
 
 @vindex gnus-startup-file
 The @code{gnus-startup-file} variable says where the startup files are.
-The default value is @file{"~/.newsrc"}, with the Gnus (El Dingo)
-startup file being whatever that one is with a @samp{".eld"} appended.
+The default value is @file{~/.newsrc}, with the Gnus (El Dingo) startup
+file being whatever that one is with a @samp{".eld"} appended.
 
 @vindex gnus-save-newsrc-hook
 @code{gnus-save-newsrc-hook} is called before saving the @file{.newsrc}
@@ -998,14 +1050,14 @@ strings to match on headers (@code{gnus-group-make-kiboze-group}).
 The different methods all have their peculiarities, of course.
 
 @menu
-* nntp::           Reading news from a different NNTP server.
-* nnspool::        Reading news from the local spool.
-* nnvirtual::      Combining articles from many groups.
-* nnkiboze::       Looking through parts of the newsfeed for articles.
-* nndir::          You can read a directory as if it was a newsgroup.
-* nndoc::          Single files can be the basis of a group.
-* nndigest::       Digests can be undigested and treated as a group.
-* Mail::           Reading your personal mail with Gnus.
+* nntp::             Reading news from a different NNTP server.
+* nnspool::          Reading news from the local spool.
+* nnvirtual::        Combining articles from many groups.
+* nnkiboze::         Looking through parts of the newsfeed for articles.
+* nndir::            You can read a directory as if it was a newsgroup.
+* nndoc::            Single files can be the basis of a group.
+* nndigest::         Digests can be undigested and treated as a group.
+* Reading Mail::     Reading your personal mail with Gnus.
 @end menu
 
 @vindex gnus-activate-foreign-newsgroups
@@ -1056,7 +1108,7 @@ look like this:
 The two first entries in this method should, of course, be the same as
 @code{gnus-select-method}. 
 
-Quite simple, eh? <duck> *Ouch*.
+Quite simple, eh? <duck> @strong{Ouch}.
 
 Let's take time out for a poem by Reznikoff:
 
@@ -1094,15 +1146,20 @@ The name of the foreign group can be the same as a native group.  In
 fact, you can subscribe to the same group from as many different servers
 you feel like.  There will be no name collisions.
 
+@cindex @sc{MODE READER}
+@cindex authinfo
+@findex nntp-send-authinfo
+@findex nntp-send-mode-reader
 @vindex nntp-server-opened-hook
 @code{nntp-server-opened-hook} is run after a connection has been made.
-It can be used to send initial commands to the NNTP server, like
-@samp{(nntp-send-command "MODE" "READER")} (which is what this hook does
-by default) or to send the @code{AUTHINFO} command, if the server
-requires that.
+It can be used to send commands to the NNTP server after it has been
+contacted.  By default is sends the command @samp{MODE READER} to the
+server with the @code{nntp-send-mode-reader} function.  Another popular
+function for sending the @sc{authinfo} command to the server is
+@code{nntp-send-authinfo}. 
 
 @vindex nntp-maximum-request
-If the NNTP server doesn't support NOV headers, this backend will
+If the NNTP server doesn't support @sc{NOV} headers, this backend will
 collect headers by sending a series of @code{HEAD} commands.  To speed
 things up, the backend sends lots of these commands, without waiting for
 reply, and then reads all the replies.  This is controlled by the
@@ -1140,7 +1197,7 @@ Program used to post an article.
 Where nnspool looks for the articles.  This is normally
 @file{/usr/spool/news/}.
 @item nnspool-nov-directory 
-Where nnspool will look for NOV files.  This is normally 
+Where nnspool will look for @sc{NOV} files.  This is normally
 @file{/usr/spool/news/over.view/}.
 @item nnspool-lib-dir
 Where the news lib dir is (@file{/usr/lib/news/} by default).
@@ -1231,12 +1288,12 @@ and they can be foreign.  No restrictions.
 @vindex nnkiboze-directory
 The generation of an nnkiboze group means writing two files in
 @code{nnkiboze-directory}, which is @file{~/News/} by default.  One
-contains the NOV header lines for all the articles in the group, and the
+contains the @sc{NOV} header lines for all the articles in the group, and the
 other is an additional @file{.newsrc} to store information on what
 groups that have been searched through to find component articles.
 
 Articles that are marked as read in the nnkiboze group will have their
-NOV lines removed from the NOV file.
+@sc{NOV} lines removed from the @sc{NOV} file.
 
 @node nndir
 @subsection nndir
@@ -1256,7 +1313,7 @@ ange-ftp changes that picture dramatically.  For instance, if you enter
 allow you to read this directory over at amanda as a newsgroup.
 Distributed news ahoy!
 
-nndir supports, and will use, NOV files if they are present.
+nndir supports, and will use, @sc{NOV} files if they are present.
 
 @node nndoc
 @subsection nndoc
@@ -1289,8 +1346,8 @@ buffer.
 
 Odd all over, as you can see, but somewhat useful.
 
-@node Mail
-@subsection Mail
+@node Reading Mail
+@subsection Reading Mail
 @cindex reading mail
 @cindex mail
 
@@ -1301,6 +1358,7 @@ course.
 * Creating Mail Groups::         How to create mail groups.
 * Mail & Procmail::              Reading mail groups that procmail create.
 * Expiring Old Mail Articles::   Getting rid of unwanted mail.
+* Not Reading Mail::             Using mail backends for reading other files.
 @end menu
 
 Gnus will read the mail spool when you activate a mail group.  The mail
@@ -1325,14 +1383,20 @@ programs, if you want to.
 variable is @code{nil}, the mail backends will never attempt to fetch
 mail by themselves.
 
-Gnus gives you all the opportunity you want for shooting yourself in
-your foot.  Let's say you create a group that will contain all the mail
-you get from your boss.  And then you accidentally unsubscribe from the
-group.  Gnus will still put all the mail from your boss in the
-unsubscribed group, and so, when your boss mails you "Have that report
-ready by Monday or you're fired!", you'll never see it and, come
-Tuesday, you'll still believe that you're gainfully unemplyed while you
-really should be out collecting empty bottles to save up for next
+@vindex nnmail-tmp-directory
+@code{nnmail-tmp-directory} says where to move the incoming mail to
+while processing it.  This is usually done in the same directory that
+the mail backend habitates (ie. @file{~/Mail/}), but if this variable is
+non-nil, it will be used instead.
+
+Gnus gives you all the opportunity you could possibly want for shooting
+yourself in the foot.  Let's say you create a group that will contain
+all the mail you get from your boss.  And then you accidentally
+unsubscribe from the group.  Gnus will still put all the mail from your
+boss in the unsubscribed group, and so, when your boss mails you "Have
+that report ready by Monday or you're fired!", you'll never see it and,
+come Tuesday, you'll still believe that you're gainfully employed while
+you really should be out collecting empty bottles to save up for next
 month's rent money.
 
 @node Creating Mail Groups
@@ -1371,8 +1435,8 @@ argument.  It should return a non-@code{nil} value if it thinks that the
 mail belongs in that group.
 
 The last of these groups should always be a general one, and the regular
-expression should *always* be @samp{""} so that it matches any mails
-that haven't been matched by any of the other regexps.
+expression should @emph{always} be @samp{""} so that it matches any
+mails that haven't been matched by any of the other regexps.
 
 @vindex nnmail-crosspost
 The mail backends all support cross-posting.  If several regexps match,
@@ -1439,14 +1503,14 @@ disappear right away, however.  In general, a mail article will be
 deleted from your system if, 1) it is marked as expirable, AND 2) it is
 more than one week old.  If you do not mark an article as expirable, it
 will remain on your system until hell freezes over.  This bears
-repeating one more time, with some spurious capitalization: IF you do
+repeating one more time, with some spurious capitalizations: IF you do
 NOT mark articles as EXPIRABLE, Gnus will NEVER delete those ARTICLES.
 
 @vindex gnus-auto-expirable-newsgroups
 You do not have to mark articles as expirable by hand.  Groups that
 match the regular expression @code{gnus-auto-expirable-newsgroups} will
 have all articles that you read marked as expirable automatically.  All
-articles that are marked as expirable have an @samp{X} in the third
+articles that are marked as expirable have an @samp{E} in the first
 column in the summary buffer.
 
 Let's say you subscribe to a couple of mailing lists, and you want the
@@ -1457,6 +1521,9 @@ articles you have read to disappear after a while:
       "^mail.nonsense-list\\|^mail.nice-list")
 @end lisp
 
+Another way to have auto-expiry happen is to have the element
+@code{auto-expire} in the select method of the group. 
+
 @vindex nnmail-expiry-wait
 The @code{nnmail-expiry-wait} variable supplies the default time an
 expirable article has to live.  The default is seven days.
@@ -1469,13 +1536,13 @@ everywhere else:
 
 @lisp
 (setq nnmail-expiry-wait-function
-      '(lambda (group)
-        (cond ((string= group "mail.private")
-                31)
-              ((string= group "mail.junk")
-                1)
-              (t
-                6))))
+      (lambda (group)
+       (cond ((string= group "mail.private")
+               31)
+             ((string= group "mail.junk")
+               1)
+             (t
+               6))))
 @end lisp
 
 @vindex nnmail-keep-last-article
@@ -1483,6 +1550,28 @@ If @code{nnmail-keep-last-article} is non-@code{nil}, Gnus will never
 expire the final article in a mail newsgroup.  This is to make life
 easier for procmail users.
 
+@node Not Reading Mail
+@subsubsection Not Reading Mail
+
+If you start using any of the mail backends, they have the annoying
+habit of assuming that you want to read mail with them.  This might not
+be unreasonable, but it might not be what you want.
+
+If you set @code{nnmail-spool-file} to nil, none of the backends will
+ever attempt to read incoming mail, which should help.
+
+@vindex nnbabyl-get-new-mail
+@vindex nnmbox-get-new-mail
+@vindex nnml-get-new-mail
+@vindex nnmh-get-new-mail
+@vindex nnfolder-get-new-mail
+This might be too much, if, for instance, you are reading mail quite
+happily with @code{nnml} and just want to peek at some old @sc{RMAIL}
+file you have stashed away with @code{nnbabyl}.  All backends have
+variables called backend-@code{get-new-mail}.  If you want to disable
+the @code{nnbabyl} mail reading, you just set
+@code{nnbabyl-get-new-mail} to @code{nil}. 
+
 @node nnmbox
 @subsubsection nnmbox
 @cindex nnmbox
@@ -1518,7 +1607,7 @@ group it belongs in.
 @node nnml
 @subsubsection nnml
 @cindex nnml
-@cindex mail nov spool
+@cindex mail @sc{nov} spool
 
 The spool mail format (@code{nnml}) isn't compatible with any other
 known format.  It should be used with some caution.
@@ -1542,13 +1631,13 @@ know that this is probably the fastest format to use.  You do not have
 to trudge through a big mbox file just to read your new mail.
 
 @code{nnml} is probably the slowest backend when it comes to article
-splitting.  It has to create lots of files, and it also generates NOV
-databases for the incoming mails.  This makes is the fastest backend
-when it comes to reading mail.
+splitting.  It has to create lots of files, and it also generates
+@sc{NOV} databases for the incoming mails.  This makes is the fastest
+backend when it comes to reading mail.
 
 @findex nnml-generate-nov-databases
-If your @code{nnml} groups and nov files get totally out of whack, you
-can do a complete update by typing @kbd{M-x
+If your @code{nnml} groups and @sc{nov} files get totally out of whack,
+you can do a complete update by typing @kbd{M-x
 nnml-generate-nov-databases}.  This command will trawl through the
 entire @code{nnml} hierarchy, looking at each and every article, so it
 might take a while to finish.
@@ -1559,9 +1648,9 @@ might take a while to finish.
 @cindex mh-e mail spool
 
 @code{nnmh} is just like @code{nnml}, except that is doesn't generate
-NOV databases and it doesn't keep an active file.  This makes
-@code{nnmh} a *much* slower backend than @code{nnml}, but it also makes
-it easier to write procmail scripts for.
+@sc{NOV} databases and it doesn't keep an active file.  This makes
+@code{nnmh} a @emph{much} slower backend than @code{nnml}, but it also
+makes it easier to write procmail scripts for.
 
 @node nnfolder
 @subsubsection nnfolder
@@ -1772,7 +1861,9 @@ Check whether new articles have arrived in the current group
 @kindex M-f (Group)
 @findex gnus-group-fetch-faq
 Try to fetch the FAQ for the current group
-(@code{gnus-group-fetch-faq}).
+(@code{gnus-group-fetch-faq}).  Gnus will try to get the FAQ from
+@code{gnus-group-faq-directory}, which is usually a directory on a
+remote machine. ange-ftp will be used for fetching the file.
 @item R
 @kindex R (Group)
 @findex gnus-group-restart
@@ -1961,23 +2052,23 @@ References
 Xref
 @item u
 User defined specifier.  The next character in the format string should
-be a letter.  @sc{GNUS} will call the function gnus-user-format-function-X,
-where X is the letter following %u.  The function will be passed the
-current header as argument.  The function should return a string, which
-will be inserted into the summary just like information from any other
-summary specifier.
+be a letter.  @sc{GNUS} will call the function
+gnus-user-format-function-X, where X is the letter following @samp{%u}.
+The function will be passed the current header as argument.  The
+function should return a string, which will be inserted into the summary
+just like information from any other summary specifier.
 @end table
 
-Text between %( and %) will be highlighted with `gnus-mouse-face'
-when the mouse point is placed inside the area.  There can only be one
-such area.
+Text between @samp{%(} and @samp{%)} will be highlighted with
+@code{gnus-mouse-face} when the mouse point is placed inside the area.
+There can only be one such area.
 
-The %U (status), %R (replied) and %z (zcore) specs have to be handled
-with care.  For reasons of efficiency, Gnus will compute what column
-these characters will end up in, and "hard-code" that.  This means that
-it is illegal to have these specs after a variable-length spec.  Well,
-you might not be arrested, but your summary buffer will look strange,
-which is bad enough.
+The @samp{%U} (status), @samp{%R} (replied) and @samp{%z} (zcore) specs
+have to be handled with care.  For reasons of efficiency, Gnus will
+compute what column these characters will end up in, and "hard-code"
+that.  This means that it is illegal to have these specs after a
+variable-length spec.  Well, you might not be arrested, but your summary
+buffer will look strange, which is bad enough.
 
 The smart choice is to have these specs as far to the left as possible.
 (Isn't that the case with everything, though?  But I digress.)
@@ -2191,15 +2282,15 @@ Scoll the current article back one page (@code{gnus-summary-prev-page}).
 @findex gnus-summary-scroll-up
 Scroll the current article one line forward
 (@code{gnus-summary-scroll-up}).
-@item <
 @item A <
+@item <
 @kindex < (Summary)
 @kindex A < (Summary)
 @findex gnus-summary-beginning-of-article
 Scroll to the beginning of the article
 (@code{gnus-summary-beginning-of-article}).
-@item >
 @item A >
+@item >
 @kindex > (Summary)
 @kindex A > (Summary)
 @findex gnus-summary-end-of-article
@@ -2220,56 +2311,108 @@ and you wish to post the article using the foreign server, you can give
 a prefix to @kbd{C-c C-c} to make Gnus try to post using the foreign
 server. 
 
+@menu 
+* Mail::                 Mailing & replying.
+* Post::                 Posting and following up.
+* Mail & Post::          Mailing and posting at the same time.
+@end menu
+
+@node Mail
+@subsection Mail
+
+Commands for composing a mail message:
+
 @table @kbd
-@item a
-@kindex a (Summary)
-@findex gnus-summary-post-news
-Post an article to the current group
-(@code{gnus-summary-post-news}).
-@item f
-@kindex f (Summary)
-@findex gnus-summary-followup
-Post a followup to the current article (@code{gnus-summary-followup}).
-@item F
-@kindex F (Summary)
-@findex gnus-summary-followup-with-original
-Post a followup to the current article and include the original message
-(@code{gnus-summary-followup-with-original}). 
+@item S r
 @item r
+@kindex S r (Summary)
 @kindex r (Summary)
 @findex gnus-summary-reply
 Mail a reply to the author of the current article
 (@code{gnus-summary-reply}). 
+@item S R
 @item R
 @kindex R (Summary)
+@kindex S R (Summary)
 @findex gnus-summary-reply-with-original
 Mail a reply to the author of the current article and include the
 original message (@code{gnus-summary-reply-with-original}).
-@item b
-@kindex b (Summary)
-@findex gnus-summary-followup-and-reply
-Post a followup and send a reply to the current article
-(@code{gnus-summary-followup-and-reply}).
-@item B
-@kindex N (Summary)
-@findex gnus-summary-followup-and-reply-with-original
-Post a followup and send a reply to the current article and include the
-original message (@code{gnus-summary-followup-and-reply-with-original}).
-@item C-c C-f
-@kindex C-c C-f (Summary)
+@item S C-f
+@kindex S C-f (Summary)
 @findex gnus-summary-mail-forward
 Forward the current article to some other person
 (@code{gnus-summary-mail-forward}). 
+@item S m
 @item m
 @kindex m (Summary)
+@kindex S m (Summary)
 @findex gnus-summary-mail-other-window
 Send a mail to some other person
-(@code{gnus-summary-mail-other-window}). 
+(@code{gnus-summary-mail-other-window}).
 @item S M-f
 @kindex S M-f (Summary)
 @findex gnus-uu-digest-and-forward
 Digest the current series and forward the result using mail
 (@code{gnus-uu-digest-and-forward}). 
+@end table
+
+Variables for customizing outgoing mail:
+
+@table @code
+@item gnus-reply-to-function
+@vindex gnus-reply-to-function
+Gnus uses the normal methods to determine where replies are to go, but
+you can change the behaviour to suit your needs by fiddling with the
+@code{gnus-reply-to-function} variable.
+
+If you want the replies to go to the "sender" instead of the "from" in
+the group "mail.stupid-list", you could do something like this:
+
+@lisp
+(setq gnus-reply-to-function
+      (lambda (group)
+       (cond ((string= group "mail.stupid-list")
+               (mail-fetch-field "sender"))
+             (t
+              nil))))
+@end lisp
+
+This functions will be called from the buffer of the article that is
+being replied to.
+
+@item gnus-mail-send-method
+@vindex gnus-mail-send-method
+This variable says how a mail should be mailed.  It uses the function in
+the @code{send-mail-function} variable as the default.
+@end table
+
+
+@node Post
+@subsection Post
+
+Commands for posting an article:
+
+@table @kbd
+@item S p
+@item a
+@kindex a (Summary)
+@kindex S p (Summary)
+@findex gnus-summary-post-news
+Post an article to the current group
+(@code{gnus-summary-post-news}).
+@item S f
+@item f
+@kindex f (Summary)
+@kindex S f (Summary)
+@findex gnus-summary-followup
+Post a followup to the current article (@code{gnus-summary-followup}).
+@item S F
+@item F
+@kindex S F (Summary)
+@kindex F (Summary)
+@findex gnus-summary-followup-with-original
+Post a followup to the current article and include the original message
+(@code{gnus-summary-followup-with-original}). 
 @item S u
 @kindex S u (Summary)
 @findex gnus-uu-post-news
@@ -2277,6 +2420,8 @@ Uuencode a file, split it up into parts, and post it as a series
 (@code{gnus-uu-post-news}). 
 @end table
 
+Variables for customizing outgoing articles:
+
 @table @code
 @item gnus-required-headers
 @vindex gnus-required-headers
@@ -2284,10 +2429,12 @@ Gnus determines which headers it should generate in outgoing posts by
 consulting the this variable.  All headers mentioned in this list will
 either be generated automatically or prompted for before an article is
 posted. 
+
 @item gnus-post-method
 @vindex gnus-post-method
 If non-@code{nil}, Gnus will use this method instead of the default
 select method when posting.
+
 @item gnus-use-followup-to
 @vindex gnus-use-followup-to
 If @code{nil}, always ignore the Followup-To header.  If it is @code{t},
@@ -2295,30 +2442,28 @@ use its value, but ignore the special value @samp{poster}, which will
 send the followup as a reply mail to the person you are responding to.
 If it is neither @code{nil} nor @code{t}, always use the Followup-To
 value.
+
 @item gnus-followup-to-function
-@item gnus-reply-to-function
-@vindex gnus-reply-to-function
 @vindex gnus-followup-to-function
-Gnus uses the normal methods to determine where replys and follow-ups
-are to go, but you can change the behaviour to suit your need by
-fiddling with the @code{gnus-reply-to-function} and
-@code{gnus-followup-to-function} variables.
+Gnus uses the normal methods to determine where follow-ups are to go,
+but you can change the behaviour to suit your needs by fiddling with
+this variable.
 
-To take "reply" as an example: If you want the replies to go to the
-"sender" instead of the "from" in the group "mail.stupid-list", you
-could do something like this:
+If you want the followups to go to the "sender" instead of the "from" in
+the group "mail.stupid-list", you could do something like this:
 
 @lisp
-(setq gnus-reply-to-function
-      '(lambda (group)
-        (cond ((string= group "mail.stupid-list")
-                (mail-fetch-field "sender"))
-              (t
-               nil))))
+(setq gnus-followup-to-function
+      (lambda (group)
+       (cond ((string= group "mail.stupid-list")
+               (mail-fetch-field "sender"))
+             (t
+              nil))))
 @end lisp
 
-These functions will be called with point in the buffer of the article
-that is being replied to (or followed up).
+This functions will be called from the buffer of the article that is
+being followed up.
+
 @item gnus-signature-function
 @vindex gnus-signature-function
 If non-@code{nil}, this variable should be a function that returns a
@@ -2327,52 +2472,49 @@ group being posted to.  If the function returns a string that doesn't
 correspond to a file, the string itself is inserted.  If the function
 returns @code{nil}, the @code{gnus-signature-file} variable will be used
 instead.
-@item gnus-signature-file
-@item mail-signature
-@vindex mail-signature
-@vindex gnus-signature-file
-If non-@code{nil}, this variable should be the name of a file containing
-a signature (@samp{~/.signature} by default).  This signature will be
-appended to all outgoing post.  Most people find it more convenient to
-use @code{mail-signature}, which does the same, but inserts the
-signature into the buffer before you start editing the post (or mail).
-So - if you have both of these variables set, you will get two
-signatures.
 
-Note that RFC1036 says that a signature should be preceded by the three
-characters @samp{-- } on a line by themselves.  This is to make it
-easier for the recipient to automatically filter the signature away.  So
-don't remove those characters, even though you might feel that they ruin
-you beautiful design, like, totally.
-
-Also note that no signature should be more than four lines long.
-Including ASCII graphics is an efficient way to get everybody to believe
-that you are silly and have nothing important to say.
 @item gnus-post-prepare-function
 @vindex gnus-post-prepare-function
 This function is called with the name of the current group after the
 post buffer has been initialized, and can be used for inserting a
 signature.  Nice if you use different signatures in different groups.
-@item gnus-auto-mail-to-author
-@vindex gnus-auto-mail-to-author
-If non-@code{nil}, Gnus will send a mail with a copy of all follow-ups
-to the authors of the articles you follow up.  It's nice in one way -
-you make sure that the person you are responding to gets your response.
-Other people loathe this method and will hate you dearly for it, because
-it means that they will first get a mail, and then have to read the same
-article later when they read the news.  It is @code{nil} by default.
-@item gnus-mail-send-method
-@vindex gnus-mail-send-method
-This variable says how a mail should be mailed.  It uses the function in
-the @code{send-mail-function} variable as the default.
+
+@item news-reply-header-hook
+@vindex news-reply-header-hook
+A related variable when following up and replying is this variable,
+which inserts the @dfn{quote line}.  The default value is:
+
+@lisp
+(defvar news-reply-header-hook
+  (lambda ()
+    (insert "In article " news-reply-yank-message-id
+            " " news-reply-yank-from " writes:\n\n")))
+@end lisp
+
+This will create lines like:
+
+@example
+In article <larszngay8jrql6a@@eyesore.no> Lars Mars <lars@@eyesore.no> writes:
+@end example
+
+Having the Message-Id in this line is probably overkill, so I would
+suggest this hook instead:
+
+@lisp
+(setq news-reply-header-hook
+  (lambda () (insert news-reply-yank-from " writes:\n\n")))
+@end lisp
+
 @item gnus-prepare-article-hook
 @vindex gnus-prepare-article-hook
 This hook is called before the headers have been prepared.  By default
 it inserts the signature specified by @code{gnus-signature-file}.
+
 @item gnus-inews-article-hook
 @vindex gnus-inews-article-hook
 This hook is called right before the article is posted.  By default it
 handles FCC processing (ie. saving the article to a file.)
+
 @item gnus-inews-article-header-hook
 @vindex gnus-inews-article-header-hook
 This hook is called after inserting the required headers in an article
@@ -2381,6 +2523,87 @@ narrowed to the headers, and is intended for people who would like to
 insert additional headers, or just change headers in some way.
 @end table
 
+
+@node Mail & Post
+@subsection Mail & Post
+
+Commands for sending mail and post at the same time:
+
+@table @kbd
+@item S b
+@kindex S b (Summary)
+@findex gnus-summary-followup-and-reply
+Post a followup and send a reply to the current article
+(@code{gnus-summary-followup-and-reply}).
+@item S B
+@kindex S B (Summary)
+@findex gnus-summary-followup-and-reply-with-original
+Post a followup and send a reply to the current article and include the
+original message (@code{gnus-summary-followup-and-reply-with-original}).
+@end table
+
+Here's a list of variables that are relevant for both mailing and
+posting: 
+
+@table @code
+@item gnus-signature-file
+@item mail-signature
+@vindex mail-signature
+@vindex gnus-signature-file
+If @code{gnus-signature-file} is non-@code{nil}, it should be the name
+of a file containing a signature (@samp{~/.signature} by default).  This
+signature will be appended to all outgoing post.  Most people find it
+more convenient to use @code{mail-signature}, which does the same, but
+inserts the signature into the buffer before you start editing the post
+(or mail).  So - if you have both of these variables set, you will get
+two signatures.
+
+Note that RFC1036 says that a signature should be preceded by the three
+characters @samp{-- } on a line by themselves.  This is to make it
+easier for the recipient to automatically filter the signature away.  So
+don't remove those characters, even though you might feel that they ruin
+you beautiful design, like, totally.
+
+Also note that no signature should be more than four lines long.
+Including ASCII graphics is an efficient way to get everybody to believe
+that you are silly and have nothing important to say.
+
+@item mail-yank-prefix
+@vindex mail-yank-prefix
+@cindex yanking
+@cindex quoting
+When you are replying or following up an article, you normally want to
+quote the person you are replying to.  Inserting quoted text is done by
+@dfn{yanking}, and each quoted line you yank will have
+@code{mail-yank-prefix} prepended to it.  This is @samp{   } by default,
+which isn't very pretty.  Most everybody prefers that lines are
+prepended with @samp{> }, so @code{(setq mail-yank-prefix "> ")} in your
+@file{.emacs} file. 
+
+@item mail-yank-ignored-headers
+@vindex mail-yank-ignored-headers
+When you yank a message, you do not want to include any headers from
+this message, so @code{(setq mail-yank-ignored-headers ":")}.  
+
+@item mail-default-headers
+@vindex mail-default-headers
+This is a string that will be inserted into the heade of all outgoing
+mail messages and news articles.  Convenient to use to insert standard
+headers. 
+
+@item gnus-auto-mail-to-author
+@vindex gnus-auto-mail-to-author
+If @code{ask}, you will be prompted for whether you want to send a mail
+copy to the author of the article you are following up.  If
+non-@code{nil} and not @code{ask}, Gnus will send a mail with a copy of
+all follow-ups to the authors of the articles you follow up.  It's nice
+in one way - you make sure that the person you are responding to gets
+your response.  Other people loathe this method and will hate you dearly
+for it, because it means that they will first get a mail, and then have
+to read the same article later when they read the news.  It is
+@code{nil} by default.
+@end table
+
 @node Cancelling and Superseding
 @section Cancelling Articles
 @cindex cancelling articles
@@ -2394,8 +2617,9 @@ Well, you can't cancel mail, but you can cancel posts.
 @findex gnus-summary-cancel-article
 @kindex C (Summary)
 Find the article you wish to cancel (you can only cancel your own
-articles, so don't try any funny stuff).  Then press @kbd{C}
-(@code{gnus-summary-cancel-article}).  Your article will be cancelled.
+articles, so don't try any funny stuff).  Then press @kbd{C} or @kbd{S
+c} (@code{gnus-summary-cancel-article}).  Your article will be
+cancelled.
 
 Be aware, however, that not all sites honor cancels, so your article may
 live on in some parts of the world, while most sites will delete the
@@ -2407,7 +2631,7 @@ your original article.
 
 @findex gnus-summary-supersede-article
 @kindex S (Summary)
-Go to the original article and press @kbd{S}
+Go to the original article and press @kbd{S s}
 (@code{gnus-summary-supersede-article}).  You will be put in a buffer
 where you can edit the article all you want before sending it off the
 usual way.
@@ -2571,13 +2795,17 @@ Mark the current article as dormant
 @findex gnus-summary-mark-as-read-forward
 Mark the current article as read
 (@code{gnus-summary-mark-as-read-forward}).
+@item M k
 @item k
 @kindex k (Summary)
+@kindex M k (Summary)
 @findex gnus-summary-kill-same-subject-and-select
 Mark all articles that have the same subject as the current one as read,
 and then select the next unread article
 (@code{gnus-summary-kill-same-subject-and-select}).
+@item M K
 @item C-k
+@kindex M K (Summary)
 @kindex C-k (Summary)
 @findex gnus-summary-kill-same-subject
 Mark all articles that have the same subject as the current one as read
@@ -2677,23 +2905,21 @@ one line up or down.
 @cindex setting process marks
 
 @table @kbd
+@item M p p
 @item #
-@item M p
 @kindex # (Summary)
 @kindex M p p (Summary)
 @findex gnus-summary-mark-as-processable
 Mark the current article with the process mark
 (@code{gnus-summary-mark-as-processable}). 
 @findex gnus-summary-unmark-as-processable
-@item M-#
 @item M p u 
-@kindex M-# (Summary)
+@item M-#
 @kindex M p u (Summary)
+@kindex M-# (Summary)
 Remove the process mark from the current article
 (@code{gnus-summary-unmark-as-processable}). 
-@item C-c M-#
 @item M p U
-@kindex C-c M-# (Summary)
 @kindex M p U (Summary)
 @findex gnus-summary-unmark-all-processable
 Remove the process mark from all articles
@@ -2726,12 +2952,6 @@ Mark all series that have already had some articles marked
 Mark all articles in series order (@code{gnus-uu-mark-series}).
 @end table
 
-@findex gnus-summary-universal-argument
-@kindex V u (Summary)
-Finally, we have @kbd{V u} (@code{gnus-summary-universal-argument}) that
-will perform any operation on all articles that have been marked with
-the process mark.
-
 @node Threading
 @section Threading
 @cindex threading
@@ -2760,42 +2980,52 @@ slower and more awkward.
 @item gnus-fetch-old-headers
 @vindex gnus-fetch-old-headers
 If non-@code{nil}, Gnus will attempt to build old threads by fetching
-more old headers - headers to articles that are marked as read.  If it
-has the value `some', only enough headers to connect otherwise loose
-threads will be displayed.  Fetching old headers only works if the
-select method you are using supports XOVER.  Also remember that if the
-root of the thread has been expired by the server, there's not much Gnus
-can do about that.
+more old headers - headers to articles that are marked as read.  If you
+would like to display as few summary lines as possible, but still
+connect as many loose threads as possible, you should set this variable
+to @code{some}.  In either case, fetching old headers only works if the
+select method you are using supports @sc{XOVER}.  Also remember that if
+the root of the thread has been expired by the server, there's not much
+Gnus can do about that.
 @item gnus-gather-loose-threads
 @vindex gnus-gather-loose-threads
 If non-@code{nil}, Gnus will gather all loose subtrees into one big tree
 and create a dummy root at the top.  (Wait a minute.  Root at the top?
 Yup.)  Loose subtrees occur when the real root has expired, or you've
-read it or marked it as read in a previous session.
+read or killed the root in a previous session.
 @item gnus-summary-gather-subject-limit
-If this variable is @code{nil}, the entire subject line will be used to
-gather loose threads.  If you would limit this to the 20 first
-characters of the subjects, set this variable to 20.
+Loose threads are gathered by comparing subjects of articles.  If this
+variable is @code{nil}, Gnus requires an exact match between the
+subjects of the loose threads before gathering them into one big
+super-thread.  This might be too strict a requirement, what with the
+presence of stupid newsreaders that chop off long subjects lines.  If
+you think so, set this variable to, say, 20 to require that only the
+first 20 characters of the subjects have to match.  If you set this
+variable to a real low number, you'll find that Gnus will gather
+everything in sight into one thread, which isn't very helpful.
+
 @item gnus-summary-make-false-root
 @vindex gnus-summary-make-false-root
 When there is no real root of a thread, Gnus will have to fudge
-something.  This variable says what method Gnus should use while
-fudging.  There are four possible value:
+something.  This variable says what fudging method Gnus should use.
+There are four possible values:
 
 @table @code
 @item adopt
 Gnus will make the first of the orphaned articles the parent.  This
 parent will adopt all the other articles.  The adopted articles will be
-marked as such by pointy brackeds instead of square brackets.  This is
-the default value.
+marked as such by pointy brackets instead of the standard square
+brackets.  This is the default method.
 @item dummy
-Gnus will create a dummy that will stand in as the parent.  This dummy
-will be displayed on a line of its own, but it does not correspond to
-any real article.
+Gnus will create a dummy summary line that will pretend to be the
+parent.  This dummy line does not correspond to any real article, so
+selecting it will just select the first real article after the dummy
+article.
 @item empty
 Gnus won't actually make any article the parent, but simply leave the
-subject field of all orphans except the first empty.  (It will use
-@code{gnus-summary-same-subject} as the subject.)
+subject field of all orphans except the first empty.  (Actually, it will
+use @code{gnus-summary-same-subject} as the subject (@pxref{Summary
+Buffer Format}).)
 @item nil
 Don't make any article parent at all.  Just gather the threads and
 display them after one another.
@@ -2803,8 +3033,8 @@ display them after one another.
 
 @item gnus-thread-hide-subtree
 @vindex gnus-thread-hide-subtree
-If non-@code{nil}, all subtrees will be hidden when the summary buffer
-is generated.
+If non-@code{nil}, all threads will be hidden when the summary buffer is
+generated.
 @item gnus-thread-hide-killed
 @vindex gnus-thread-hide-killed
 if you kill a thread and this variable is non-@code{nil}, the subtree
@@ -2817,8 +3047,8 @@ it is @code{nil}, which is the default, a change in the subject will
 result in a new thread.
 @item gnus-thread-indent-level
 @vindex gnus-thread-indent-level
-This is a number that how much each subthread should be indented.  The
-default is @samp{4}.
+This is a number that says how much each subthread should be indented.
+The default is @samp{4}.
 @end table
 
 @node Thread Commands
@@ -2831,9 +3061,10 @@ default is @samp{4}.
 @kindex T k (Summary)
 @kindex M-C-k (Summary)
 @findex gnus-summary-kill-thread
-Mark all articles under the current one as read
+Mark all articles in the current subtread as read
 (@code{gnus-summary-kill-thread}).  If the prefix argument is positive,
-remove all marks.  If the prefix argument is negative, tick articles.
+remove all marks instead.  If the prefix argument is negative, tick
+articles instead.
 @item T l
 @item M-C-l
 @kindex T l (Summary)
@@ -2854,12 +3085,12 @@ Mark the current thread with the process mark
 @item T T
 @kindex T T (Summary)
 @findex gnus-summary-toggle-threads
-Toggle showing threads (@code{gnus-summary-toggle-threads}).
+Toggle threading (@code{gnus-summary-toggle-threads}).
 @item T s
 @kindex T s (Summary)
 @findex gnus-summary-show-thread
-Show the thread hidden under the current article, if any
-(@code{gnus-summary-show-thread}). 
+Expose the thread hidden under the current article, if any
+(@code{gnus-summary-show-thread}).
 @item T h
 @kindex T h (Summary)
 @findex gnus-summary-hide-thread
@@ -2867,14 +3098,14 @@ Hide the current (sub)thread (@code{gnus-summary-hide-thread}).
 @item T S
 @kindex T S (Summary)
 @findex gnus-summary-show-all-threads
-Show all hidden threads (@code{gnus-summary-show-all-threads}).
+Expose all hidden threads (@code{gnus-summary-show-all-threads}).
 @item T H
 @kindex T H (Summary)
 @findex gnus-summary-hide-all-threads
 Hide all threads (@code{gnus-summary-hide-all-threads}).
 @end table
 
-The following commands are all thread movement commands.  They all
+The following commands are thread movement commands.  They all
 understand the numeric prefix.
 
 @table @kbd
@@ -2904,21 +3135,31 @@ Exiting from the summary buffer will normally update all info on the
 group and return you to the group buffer. 
 
 @table @kbd
+@item Z Z
 @item q
 @kindex q (Summary)
 @findex gnus-summary-exit
-Exit the current group and update all the information
-(@code{gnus-summary-exit}). 
+Exit the current group and update all information on the group
+(@code{gnus-summary-exit}).
+@item Z E
 @item Q
+@kindex Z E (Summary)
 @kindex Q (Summary)
-@findex gnus-summary-quit
-Exit the current group without updating any information
-(@code{gnus-summary-quit}). 
+@findex gnus-summary-exit-no-update
+Exit the current group without updating any information on the group
+(@code{gnus-summary-exit-no-update}).
+@item Z c
 @item c
+@kindex Z c (Summary)
 @kindex c (Summary)
 @findex gnus-summary-catchup-and-exit
-Mark all articles in the group as read and exit
-(@code{gnus-summary-catchup-and-exit}). 
+Mark all unticked articles in the group as read and then exit
+(@code{gnus-summary-catchup-and-exit}).
+@item Z C
+@kindex Z C (Summary)
+@findex gnus-summary-catchup-all-and-exit
+Mark all articles, even the ticked ones, as read and then exit
+(@code{gnus-summary-catchup-all-and-exit}).
 @end table
 
 @vindex gnus-exit-group-hook
@@ -2928,12 +3169,12 @@ group.
 @vindex gnus-use-cross-reference
 When you exit the summary buffer, the data on the current group will be
 updated (which articles you have read, which articles you have replied
-to, etc.) If the @code{gnus-use-cross-reference} variable is @code{t}, articles
-that are cross-referenced to this group, and are marked as read, will
-also be marked as read in the other subscribed groups they were
-cross-posted to.   If this variable is neither @code{nil} nor @code{t}, the
-article will be marked as read in both subscribed and unsubscribed
-groups. 
+to, etc.) If the @code{gnus-use-cross-reference} variable is @code{t},
+articles that are cross-referenced to this group, and are marked as
+read, will also be marked as read in the other subscribed groups they
+were cross-posted to.  If this variable is neither @code{nil} nor
+@code{t}, the article will be marked as read in both subscribed and
+unsubscribed groups.
 
 Marking cross-posted articles as read ensures that you'll never have to
 read the same article more than once.  Unless, of course, somebody has
@@ -2946,18 +3187,19 @@ Remember: Cross-posting is kinda ok, but posting the same article
 separately to several groups is not.
 
 One thing that may cause Gnus to not do the cross-posting thing
-correctly is if you use an NNTP server that supports xover (which is
-very nice, because it speeds things up considerably) which does not
-include the Xref header in its NOV lines.  This is Evil, but it's
-common.  Gnus tries to Do The Right Thing even with xover by registering
-the Xref lines of all articles you actually read, but if you kill the
-articles, or just mark them as read without reading them, Gnus will not
-get a chance to snoop the Xref lines out of these articles, and will be
-unable to use the cross reference mechanism.
+correctly is if you use an NNTP server that supports @sc{xover} (which
+is very nice, because it speeds things up considerably) which does not
+include the Xref header in its @sc{NOV} lines.  This is Evil, but it's
+common.  Gnus tries to Do The Right Thing even with @sc{xover} by
+registering the Xref lines of all articles you actually read, but if you
+kill the articles, or just mark them as read without reading them, Gnus
+will not get a chance to snoop the Xref lines out of these articles, and
+will be unable to use the cross reference mechanism.
 
 @vindex gnus-nov-is-evil
 If you want Gnus to get the Xrefs right all the time, you have to set
-@code{gnus-nov-is-evil} to @code{t}, which slows things down considerably. 
+@code{gnus-nov-is-evil} to @code{t}, which slows things down
+considerably.
 
 C'est la vie.
 
@@ -2996,26 +3238,50 @@ are avoided.
 Gnus can save articles in a number of ways.  Below is the documentation
 for saving articles in a fairly straight-forward fashion (ie. little
 processing of the article is done before it is saved).  For a different
-approach (uudecoding, unsharing) see gnus-uu.  @xref{Decoding Articles}.
+approach (uudecoding, unsharing) you should use @code{gnus-uu}
+(@pxref{Decoding Articles}).
 
 @vindex gnus-save-all-headers
 If @code{gnus-save-all-headers} is non-@code{nil}, Gnus will not delete
 unwanted headers before saving the article.
 
 @table @kbd
+@item V o o
 @item o
+@kindex V o o (Summary)
 @kindex o (Summary)
 @findex gnus-summary-save-article
-Save the current article (@code{gnus-summary-save-article}).
-@item C-o
-@kindex C-o (Summary)
+Save the current article using the default article saver
+(@code{gnus-summary-save-article}). 
+@item V o m
+@kindex V o m (Summary)
 @findex gnus-summary-save-article-mail
 Save the current article in mail format
 (@code{gnus-summary-save-article-mail}). 
+@item V o r
+@kindex V o r (Summary)
+@findex gnus-summary-save-article-mail
+Save the current article in rmail format
+(@code{gnus-summary-save-article-rmail}). 
+@item V o f
+@kindex V o f (Summary)
+@findex gnus-summary-save-article-file
+Save the current article in plain file format
+(@code{gnus-summary-save-article-file}). 
+@item V o h
+@kindex V o h (Summary)
+@findex gnus-summary-save-article-folder
+Save the current article in mh folder format
+(@code{gnus-summary-save-article-file}). 
+@item V o p
+@kindex V o p (Summary)
+@findex gnus-summary-pipe-output
+Save the current article in a pipe.  Uhm, like, what I mean is - Pipe
+the current article to a process (@code{gnus-summary-pipe-output}).
 @end table
 
-Both these command use the process/prefix convention
-(@pxref{Process/Prefix}). 
+All these commands use the process/prefix convention
+(@pxref{Process/Prefix}).
 
 @vindex gnus-default-article-saver
 You can customize the @code{gnus-default-article-saver} variable to make
@@ -3141,16 +3407,18 @@ the process mark.  If, for instance, you'd like to uncode and save an
 entire newsgroup, you'd typically do @kbd{M p a}
 (@code{gnus-uu-mark-all}) and then @kbd{X U} (@code{gnus-uu-decode-uu}).
 
-All this is very much different from how gnus-uu worked with @sc{GNUS
-4.1}, where you had explicit keystrokes for everything under the sun.
-This version of gnus-uu generally assumes that you either mark articles
-in some way (@pxref{Setting Process Marks}) and then press @kbd{X u}.
+All this is very much different from how @code{gnus-uu} worked with
+@sc{GNUS 4.1}, where you had explicit keystrokes for everything under
+the sun.  This version of @code{gnus-uu} generally assumes that you
+either mark articles in some way (@pxref{Setting Process Marks}) and
+then press @kbd{X u}.
 
 Note: When trying to decode articles that have names matching
-@samp{[Cc][Ii][Nn][Dd][Yy][0-9]+.\\(gif\\|jpg\\)}
-(@code{gnus-uu-notify-files}), gnus-uu will automatically post an
-article on @samp{comp.unix.wizards} saying that you have just viewed the
-file in question.  This feature can't be turned off.
+@code{gnus-uu-notify-files}, which hard-coded to
+@samp{[Cc][Ii][Nn][Dd][Yy][0-9]+.\\(gif\\|jpg\\)}, @code{gnus-uu} will
+automatically post an article on @samp{comp.unix.wizards} saying that
+you have just viewed the file in question.  This feature can't be turned
+off.
 
 @node Shared Articles
 @subsection Shared Articles
@@ -3191,7 +3459,7 @@ Adjective, not verb.
 @subsubsection Rule Variables
 @cindex rule variables
 
-Gnus uses @dfn{rule} variables to decide how to view a file.  All these
+Gnus uses @dfn{rule variables} to decide how to view a file.  All these
 variables are on the form
   
 @lisp
@@ -3231,17 +3499,17 @@ Files with name matching this regular expression won't be viewed.
 @item gnus-uu-ignore-files-by-type
 @vindex gnus-uu-ignore-files-by-type
 Files with a MIME type matching this variable won't be viewed.  Note
-that Gnus tries to guess what type the file is based on the
-name.  gnus-uu is not a MIME package, so this is slightly kludgy.
+that Gnus tries to guess what type the file is based on the name.
+@code{gnus-uu} is not a MIME package, so this is slightly kludgy.
 
 @item gnus-uu-tmp-dir
 @vindex gnus-uu-tmp-dir
-Where gnus-uu does its work.
+Where @code{gnus-uu} does its work.
 
 @item gnus-uu-do-not-unpack-archives
 @vindex gnus-uu-do-not-unpack-archives
-Non-@code{nil} means that gnus-uu won't peek inside archives looking for
-files to dispay.
+Non-@code{nil} means that @code{gnus-uu} won't peek inside archives
+looking for files to dispay.
 
 @item gnus-uu-view-and-save
 @vindex gnus-uu-view-and-save
@@ -3250,48 +3518,51 @@ after viewing it.
 
 @item gnus-uu-ignore-default-view-rules
 @vindex gnus-uu-ignore-default-view-rules
-Non-@code{nil} means that gnus-uu will ignore the default viewing rules.
+Non-@code{nil} means that @code{gnus-uu} will ignore the default viewing
+rules.
 
 @item gnus-uu-ignore-default-archive-rules
 @vindex gnus-uu-ignore-default-archive-rules
-Non-@code{nil} means that gnus-uu will ignore the default archive
+Non-@code{nil} means that @code{gnus-uu} will ignore the default archive
 unpacking commands.
 
 @item gnus-uu-kill-carriage-return
 @vindex gnus-uu-kill-carriage-return
-Non-@code{nil} means that gnus-uu will strip all carriage returns from
-articles.
+Non-@code{nil} means that @code{gnus-uu} will strip all carriage returns
+from articles.
 
 @item gnus-uu-unmark-articles-not-decoded
 @vindex gnus-uu-unmark-articles-not-decoded
-Non-@code{nil} means that gnus-uu will mark articles that were
+Non-@code{nil} means that @code{gnus-uu} will mark articles that were
 unsuccessfully decoded as unread.
 
 @item gnus-uu-correct-stripped-uucode
 @vindex gnus-uu-correct-stripped-uucode
-Non-@code{nil} means that gnus-uu will *try* to fix uuencoded files that
-have had traling spaces deleted.
+Non-@code{nil} means that @code{gnus-uu} will @emph{try} to fix
+uuencoded files that have had traling spaces deleted.
 
 @item gnus-uu-view-with-metamail
 @vindex gnus-uu-view-with-metamail
-Non-@code{nil} means that gnus-uu will ignore the viewing commands
-defined by the rule variables and just fudge a MIME content type based
-on the file name.  The result will be fed to metamail for viewing.
+Non-@code{nil} means that @code{gnus-uu} will ignore the viewing
+commands defined by the rule variables and just fudge a MIME content
+type based on the file name.  The result will be fed to metamail for
+viewing.
 
 @item gnus-uu-save-in-digest
 @vindex gnus-uu-save-in-digest
-Non-@code{nil} means that gnus-uu, when asked to save without decoding,
-will save in digests.  If this variable is @code{nil}, gnus-uu will just
-save everything in a file without any embellishments.  The digesting
-almost conforms to RFC1153 - no easy way to specify any meaningful
-volume and issue numbers were found, so I simply dropped them.
+Non-@code{nil} means that @code{gnus-uu}, when asked to save without
+decoding, will save in digests.  If this variable is @code{nil},
+@code{gnus-uu} will just save everything in a file without any
+embellishments.  The digesting almost conforms to RFC1153 - no easy way
+to specify any meaningful volume and issue numbers were found, so I
+simply dropped them.
 
 @item gnus-uu-post-include-before-composing
 @vindex gnus-uu-post-include-before-composing
-Non-@code{nil} means that gnus-uu will ask for a file to encode before
-you compose the article.  If this variable is @code{t}, you can either
-include an encoded file with @key{C-c C-i} or have one included for you
-when you post the article.
+Non-@code{nil} means that @code{gnus-uu} will ask for a file to encode
+before you compose the article.  If this variable is @code{t}, you can
+either include an encoded file with @key{C-c C-i} or have one included
+for you when you post the article.
 
 @item gnus-uu-post-length
 @vindex gnus-uu-post-length
@@ -3300,11 +3571,11 @@ many articles it takes to post the entire file.
 
 @item gnus-uu-post-threaded
 @vindex gnus-uu-post-threaded
-Non-@code{nil} means that gnus-uu will post the encoded file in a
+Non-@code{nil} means that @code{gnus-uu} will post the encoded file in a
 thread.  This may not be smart, as no other decoder I have seen are able
 to follow threads when collecting uuencoded articles.  (Well, I have
-seen one package that does that - gnus-uu, but somehow, I don't think
-that counts...) Default is @code{nil}.
+seen one package that does that - @code{gnus-uu}, but somehow, I don't
+think that counts...) Default is @code{nil}.
 
 @item gnus-uu-post-separate-description
 @vindex gnus-uu-post-separate-description
@@ -3378,11 +3649,6 @@ Toggle whether to display all headers in the article buffer
 @findex gnus-summary-toggle-mime
 Toggle whether to run the article through MIME before displaying
 (@code{gnus-summary-toggle-mime}). 
-@item V |
-@kindex V | (Summary)
-@findex gnus-summary-pipe-output
-Pipe the current article to a process
-(@code{gnus-summary-pipe-output}). 
 @end table
 
 There's a battery of commands for washing the article buffer:
@@ -3445,6 +3711,13 @@ Sort by subject (@code{gnus-summary-sort-by-subject}).
 Sort by date (@code{gnus-summary-sort-by-date}).
 @end table
 
+These functions will work both when you use threading and when you don't
+use threading.  In the former case, all summary lines will be sorted,
+line by line.  In the latter case, sorting will be done on a
+root-by-root basis, which might not be what you were looking for.  To
+toggle whether to use threading, type @kbd{T T} (@pxref{Thread
+Commands}).
+
 @node Finding the Parent
 @section Finding the Parent
 @cindex parent articles
@@ -3456,17 +3729,18 @@ If you'd like to read the parent of the current article, and it is not
 displayed in the article buffer, you might still be able to.  That is,
 if the current group is fetched by NNTP, the parent hasn't expired and
 the References in the current article are not mangled, you can just
-press @kbd{^} (@code{gnus-summary-refer-parent-article}).  If everything
-goes well, you'll get the parent.  If the parent is already displayed in
-the summary buffer, point will just move to this article.
+press @kbd{^} or @kbd{A r} (@code{gnus-summary-refer-parent-article}).
+If everything goes well, you'll get the parent.  If the parent is
+already displayed in the summary buffer, point will just move to this
+article.
 
 @findex gnus-summary-refer-article
 @kindex M-^ (Summary)
 You can also ask the NNTP server for an arbitrary article, no matter
-what group it belongs to.  @kbd{M-^} (@code{gnus-summary-refer-article})
+what group it belongs to.  @kbd{V r} (@code{gnus-summary-refer-article})
 will ask you for a message-id, which is one of those long thingies that
 look something like @samp{<38o6up$6f2@@hymir.ifi.uio.no>}.  You have to
-get it all exactly right.
+get it all exactly right.  No fuzzy searches, I'm afraid.
 
 @vindex gnus-refer-article-method
 If the group you are reading is located on a backend that does not
@@ -3517,13 +3791,40 @@ silently to help keep the sizes of the score files down.
 @subsection Summary Score Commands
 @cindex score commands
 
-General score commands don't actually change score files: 
+All score commands that alter score entries do not actually work towards
+a real score file.  That would be to inefficient.  Gnus maintains a
+cache of previously loaded score files, one of which is considered the
+@dfn{current score file alist}.  The score commands simply insert
+entries into this list, and upon group exit, this list is saved.  
+
+The current score file is always the group's local score file, even if
+no such score file actually exists.  To insert score commands into some
+other score file (eg. @file{all.SCORE}), you must first make this score
+file the current one.
+
+General score commands that don't actually change the score file:
 
 @table @kbd
 @item V S s
 @kindex V S s (Summary)
 @findex gnus-summary-set-score
 Set the score of the current article (@code{gnus-summary-set-score}).  
+@item V S c
+@kindex V S c (Summary)
+@findex gnus-score-change-score-file
+Make a different score file the current
+(@code{gnus-score-change-score-file}). 
+@item V S e
+@kindex V S e (Summary)
+@findex gnus-score-edit-alist
+Edit the current score file (@code{gnus-score-edit-alist}).  You will be
+popped into a @code{gnus-score-mode} buffer (@pxref{Score File
+Editing}).
+@item V S f
+@kindex V S f (Summary)
+@findex gnus-score-edit-file
+Edit a score file and make this score file the current one
+(@code{gnus-score-edit-file}).
 @item I C-i
 @kindex I C-i (Summary)
 @findex gnus-summary-raise-score
@@ -3534,17 +3835,6 @@ Increase the score of the current article
 @findex gnus-summary-lower-score
 Lower the score of the current article
 (@code{gnus-summary-lower-score}). 
-@item V S c
-@kindex V S c (Summary)
-@findex gnus-score-change-score-file
-Make a different score file the current
-(@code{gnus-score-change-score-file}). 
-@item V S e
-@kindex V S e (Summary)
-@findex gnus-score-edit-file
-Edit the current score file (@code{gnus-score-edit-file}).  You will be
-popped into a @code{gnus-score-mode} buffer (@pxref{Score File
-Editing}). 
 @end table
 
 The rest of these commands modify the local score file.
@@ -3562,7 +3852,7 @@ Expunge all articles with a score below the default score (or the
 numeric prefix) (@code{gnus-score-set-expunge-below}).
 @end table
 
-Commands for increasing score:
+Commands for increasing the score:
 
 @table @kbd
 @item I s t
@@ -3627,7 +3917,7 @@ Increase followups to the current author permanently
 (@code{gnus-summary-raise-followups-to-author}).
 @end table
 
-Commands for lowering score:
+Commands for lowering the score:
 
 @table @kbd
 @item L s t
@@ -3848,8 +4138,8 @@ You normally enter all scoring commands from the summary buffer, but you
 might feel the urge to edit them by hand as well, so we've supplied you
 with a mode for that.  
 
-It's simply a slightly customized emacs-lisp mode, with these additional
-commands:
+It's simply a slightly customized @code{emacs-lisp} mode, with these
+additional commands:
 
 @table @kbd
 @item C-c C-c
@@ -3869,7 +4159,7 @@ you were wondering.
 @subsection Scoring Tips
 @cindex scoring tips
 
-@table . 
+@itemize @bullet
 @item Crossposts
 If you want to lower the score of crossposts, the line to match on is
 the Xref header.  
@@ -3882,7 +4172,7 @@ more than, say, 3 groups:
 @lisp
 ("xref" (" +[^ ]+:[0-9]+ +[^ ]+:[0-9]+ +[^ ]+:[0-9]+" -1000 nil r))
 @end lisp
-@end table
+@end itemize
 
 @node Global Score Files
 @subsection Global Score Files
@@ -3951,7 +4241,7 @@ old articles for a long time.
 @end itemize
 
 ... I wonder whether other newsreaders will support global score files
-in the future.  *Snicker*.  Yup, any day now, newsreaders like Blue
+in the future.  @emph{Snicker}.  Yup, any day now, newsreaders like Blue
 Wave, xrn and 1stReader are bound to implement scoring.  Should we start
 holding our breath yet?
 
@@ -4005,13 +4295,22 @@ and make the changes permanent.
 @node Various Summary Stuff
 @section Various Summary Stuff
 
+@menu
+* Group Information::                 Information oriented commands.
+* Searching for Articles::            Multiple article commands.
+* Really Various Summary Commands::   Those pesky non-conformant commands.
+@end menu
+
+@vindex gnus-summary-prepare-hook
+@code{gnus-summary-prepare-hook} is called after the summary buffer has
+been generated.  You might use it to, for instance, hilight lines or
+modify the look of the buffer in some other ungodly manner.  I don't
+care.
+
+@node Group Information
+@subsection Group Information
+
 @table @kbd
-@item V D
-@kindex V D (Summary)
-@findex gnus-summary-enter-digest-group
-If the current article is a digest, you might use this command to enter
-you into a group based onthe current digest to ease reading
-(@code{gnus-summary-enter-digest-group}).  @xref{nndigest}.
 @item V f
 @kindex V f (Summary)
 @findex gnus-summary-fetch-faq
@@ -4020,12 +4319,27 @@ Try to fetch the FAQ (list of frequently asked questions) for the
 current group (@code{gnus-summary-fetch-faq}).  Gnus will try to get the
 FAQ from @code{gnus-group-faq-directory}, which is usually a directory
 on a remote machine. ange-ftp will be used for fetching the file.
-@item &
-@kindex & (Summary)
-@findex gnus-summary-expand-window
-This command will prompt you for a header field, a regular expression to
-be matched this field, and a command to be executed if the match is
-made. 
+@item V d
+@kindex V d (Summary)
+@findex gnus-summary-describe-group
+Give a brief description of the current group
+(@code{gnus-summary-describe-group}).  If given a prefix, force reading
+new description from the server. 
+@item V ?
+@kindex V ? (Summary)
+@findex gnus-summary-describe-briefly
+Give a very brief description of the most important summary keystrokes
+(@code{gnus-summary-describe-briefly}). 
+@item V i
+@kindex V i (Summary)
+@findex gnus-info-find-node
+Go to the Gnus info node (@code{gnus-info-find-node}).
+@end table
+
+@node Searching for Articles
+@subsection Searching for Articles
+
+@table @kbd
 @item V C-s
 @kindex V C-s (Summary)
 @findex gnus-summary-search-article-forward
@@ -4036,6 +4350,29 @@ Search through all subsequent articles for a regexp
 @findex gnus-summary-search-article-backward
 Search through all previous articles for a regexp
 (@code{gnus-summary-search-article-backward}). 
+@item V &
+@kindex V & (Summary)
+@findex gnus-summary-execute-command
+This command will prompt you for a header field, a regular expression to
+be matched this field, and a command to be executed if the match is
+made (@code{gnus-summary-execute-command}). 
+@item V u
+@kindex V u (Summary)
+@findex gnus-summary-universal-argument
+Perform any operation on all articles that have been marked with
+the process mark (@code{gnus-summary-universal-argument}).
+@end table
+
+@node Really Various Summary Commands
+@subsection Really Various Summary Commands
+
+@table @kbd
+@item V D
+@kindex V D (Summary)
+@findex gnus-summary-enter-digest-group
+If the current article is a digest, you might use this command to enter
+you into a group based onthe current digest to ease reading
+(@code{gnus-summary-enter-digest-group}).  @xref{nndigest}.
 @item V T
 @kindex V T (Summary)
 @findex gnus-summary-toggle-truncation
@@ -4049,12 +4386,6 @@ Expand the summary buffer window (@code{gnus-summary-expand-window}).
 @findex gnus-summary-reselect-current-group
 Exit this group, and then enter it again
 (@code{gnus-summary-reselect-current-group}).
-@item V d
-@kindex V d (Summary)
-@findex gnus-summary-describe-group
-Give a brief description of the current group
-(@code{gnus-summary-describe-group}).  If given a prefix, force reading
-new description from the server. 
 @item V g
 @item M-g
 @kindex V g (Summary)
@@ -4062,26 +4393,16 @@ new description from the server.
 @findex gnus-summary-rescan-group
 Exit group, check for new articles in the group, and select the group
 (@code{gnus-summary-rescan-group}).
-@item V
-@kindex V (Summary)
-@findex gnus-version
-Display the Gnus version numbers (@code{gnus-version}).
-@item V ?
-@kindex V ? (Summary)
-@findex gnus-summary-describe-briefly
-Give a very brief description of the most important summary keystrokes
-(@code{gnus-summary-describe-briefly}). 
-@item V i
-@kindex V i (Summary)
-@findex gnus-info-find-node
-Go to the Gnus info node (@code{gnus-info-find-node}).
+@item V k
+@kindex V k (Summary)
+@findex gnus-summary-edit-local-kill
+Edit this group's kill file (@code{gnus-summary-edit-local-kill}).
+@item V K
+@kindex V K (Summary)
+@findex gnus-summary-edit-global-kill
+Edit the general kill file (@code{gnus-summary-edit-local-kill}).
 @end table
 
-@vindex gnus-summary-prepare-hook
-@code{gnus-summary-prepare-hook} is called after the summary buffer has
-been generated.  You might use it to, for instance, hilight lines, modify
-the look, or anything else you feel like.  I don't care.
-
 @node The Article Buffer
 @chapter The Article Buffer
 @cindex article buffer
@@ -4184,16 +4505,17 @@ other naughty stuff in innocent-looking articles.
 @vindex gnus-show-mime-method
 Gnus handles MIME by shoving the articles through
 @code{gnus-show-mime-method}, which is @code{metamail-buffer} by
-default.  Set @code{gnus-show-mime} to @code{t} if you want to use MIME all the
-time; it might be best just use the toggling functions from the summary
-buffer to avoid getting nasty surprises (for instance, you enter the
-group @samp{alt.sing-a-long} and, before you know it, MIME has decoded
-the sounds file in the article and some horrible sing-a-long song comes
-streaming out out your speakers, and you can't find the volume button,
-because there isn't one, and people are starting to look at you, and you
-try to stop the program, but you can't, and you can't find the program
-to control the volume, and everybody else in the room suddenly decides
-to look at you disdainfully, and you'll feel rather stupid.)
+default.  Set @code{gnus-show-mime} to @code{t} if you want to use MIME
+all the time; it might be best just use the toggling functions from the
+summary buffer to avoid getting nasty surprises (for instance, you enter
+the group @samp{alt.sing-a-long} and, before you know it, MIME has
+decoded the sounds file in the article and some horrible sing-a-long
+song comes streaming out out your speakers, and you can't find the
+volume button, because there isn't one, and people are starting to look
+at you, and you try to stop the program, but you can't, and you can't
+find the program to control the volume, and everybody else in the room
+suddenly decides to look at you disdainfully, and you'll feel rather
+stupid.)
 
 Any similarity to real events and people is purely coincidental.  Ahem.
 
@@ -4392,10 +4714,10 @@ summary buffer and the article buffer side by side.
 @item gnus-updated-mode-lines
 @vindex gnus-updated-mode-lines
 This is a list of buffers that should keep their mode lines updated.
-The list may contain the symbols `group', `article' and `summary'.  If
-the corresponding symbol is present, Gnus will keep that mode line
-updated with information that may be pertinent.  If this variable is
-@code{nil}, screen refresh may be quicker.
+The list may contain the symbols @code{group}, @code{article} and
+@code{summary}.  If the corresponding symbol is present, Gnus will keep
+that mode line updated with information that may be pertinent.  If this
+variable is @code{nil}, screen refresh may be quicker.
 
 @item gnus-mode-non-string-length
 @vindex gnus-mode-non-string-length
@@ -4458,7 +4780,7 @@ will make it difficult for you to get hold of new groups.
 @item gnus-nov-is-evil
 This one has to be @code{nil}.  If not, grabbing article headers from
 the NNTP server will not be very fast.  Not all NNTP servers support
-XOVER; Gnus will detect this by itself.
+@sc{XOVER}; Gnus will detect this by itself.
 @end table
 
 @node Slow Terminal Connection
@@ -4565,8 +4887,8 @@ gnus-bug} command.  @code{(setq debug-on-error t)}, and send me the
 backtrace.  I will fix bugs, but I can only fix them if you send me a
 precise description as to how to reproduce the bug.
 
-If you just need help, you are better off asking on
-@samp{gnu.emacs.gnus}.
+@c If you just need help, you are better off asking on
+@c @samp{gnu.emacs.gnus}.  
 
 @node Index
 @chapter Index