*** empty log message ***
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 04:27:53 +0000 (04:27 +0000)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 04:27:53 +0000 (04:27 +0000)
20 files changed:
lisp/ChangeLog
lisp/gnus-cache.el
lisp/gnus-ems.el
lisp/gnus-mh.el
lisp/gnus-msg.el
lisp/gnus-score.el
lisp/gnus-topic.el [new file with mode: 0644]
lisp/gnus-uu.el
lisp/gnus-vis.el
lisp/gnus-vm.el
lisp/gnus.el
lisp/nnbabyl.el
lisp/nndoc.el
lisp/nnfolder.el
lisp/nnmbox.el
lisp/nnmh.el
lisp/nnml.el
lisp/nnsoup.el
texi/ChangeLog
texi/gnus.texi

index ddbc1b0..63524e2 100644 (file)
@@ -1,3 +1,111 @@
+Mon Sep 25 22:43:22 1995  Lars Magne Ingebrigtsen  <larsi@gjalp.ifi.uio.no>
+
+       * gnus-msg.el (gnus-inews-insert-headers): Heed
+               check-before-posting. 
+               (gnus-mail-reply): Allow specification of In-Reply-To.
+               (gnus-inews-in-reply-to): New function.
+
+Mon Sep 25 00:03:03 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.el (gnus-get-unread-articles): Don't treat nnvirtual groups
+       specially. 
+       (gnus-get-unread-articles): Allow updating of info.
+       (gnus-request-update-info): New function.
+       (gnus-group-sort-function): Can now be a list.
+       (gnus-group-sort-groups): Use it.
+       (gnus-group-sort-by-method): New function.
+       (gnus-group-topic-p): New function.
+
+       * gnus-topic.el: Finally included Ilja Weis' gnus-topic.
+
+Sun Sep 24 02:18:12 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus-vis.el (gnus-header-button-alist): New variable.
+       (gnus-button-mailto): New function.
+       (gnus-button-reply): New function.
+       (gnus-article-add-buttons-to-head): New command and keystroke.
+
+       * gnus.el (gnus-group-add-parameter): New function.
+       (gnus-fetch-group): New autoloaded command.
+       (gnus-summary-articles-in-thread): New function.
+       (gnus-summary-kill-thread): Use it.
+       (gnus-summary-raise-thread): Ditto.
+       (gnus-thread-operation-ignore-subject): New variable.
+
+       * gnus-msg.el (gnus-post-news): When posting to a mail group that
+       has no to-address, add the To in the mail to the group
+       parameters. 
+
+       * gnus.el (gnus-create-xref-hashtb): Mark ticked and dormant
+       articles as read when Xreffing.
+       (gnus-dribble-directory): New variable.
+       (gnus-dribble-file-name): Use it.
+       (gnus-auto-select-next): Additional value: `almost-quietly'.
+       (gnus-summary-next-article): Use it.
+       (gnus-summary-last-article-p): New function.
+       (gnus-summary-save-article-body-file): New command and keystroke.
+       (gnus-summary-save-body-in-file): New function.
+       (gnus-prompt-before-saving): New variable.
+       (gnus-summary-save-article): Use it.
+       (gnus-request-article-this-buffer): Fetch the article from
+       `gnus-article-original-buffer' if it is there.
+       (gnus-summary-mode-line-format-alist): New specs for ticked,
+       dormant, read and expunged articles.
+
+       * gnus-cache.el (gnus-uncacheable-groups): New variable.
+       (gnus-cache-possibly-enter-article): Use it.
+
+       * gnus-score.el (gnus-score-uncacheable-files): New variable.
+       (gnus-score-save): Use it.
+
+       * gnus.el (gnus-auto-subscribed-groups): New variable.
+
+       * nnfolder.el (nnfolder-request-delete-group): New function.
+       (nnfolder-request-rename-group): New function.
+
+       * nnbabyl.el (nnbabyl-request-delete-group): New function.
+       (nnbabyl-request-rename-group): New function.
+
+       * nnmbox.el (nnmbox-save-mail): Ran wrong hook.
+       (nnmbox-request-delete-group): New function.
+       (nnmbox-request-rename-group): New function.
+
+       * nnmh.el (nnmh-request-delete-group): New function.
+       (nnmh-request-rename-group): New function.
+
+Sat Sep 23 02:33:29 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.el (gnus-summary-next-article): Use `read-char-exclusive'
+       instead of read-char.
+
+       * nnbabyl.el (nnbabyl-retrieve-headers): Wrong number of arguments.
+
+       * gnus.el (gnus-save-quick-newsrc-hook): New hook.
+       (gnus-save-quick-newsrc-hook): New hook.
+
+       * gnus-msg.el (gnus-news-followup): Used news-mode instead of
+       news-reply-mode. 
+
+       * gnus-uu.el (gnus-uu-digest-mail-forward): Would call wrong
+       forward function.
+
+       * gnus-msg.el (gnus-mail-reply): Would add _-_ to all
+       message-ids. 
+
+       * gnus.el (gnus-request-delete-group): New function.
+       (gnus-request-rename-group): New function.
+       (gnus-group-delete-group): New command and keystroke.
+       (gnus-group-rename-group): New command and keystroke.
+
+       * nnml.el (nnml-request-delete-group): New function.
+       (nnml-request-rename-group): New function.
+
+       * nnsoup.el (nnsoup-request-scan): New function.
+
+Fri Sep 22 22:35:37 1995  Lars Magne Ingebrigtsen  <larsi@mimir.ifi.uio.no>
+
+       * gnus.el: 0.2 is released.
+
 Thu Sep 21 14:19:41 1995  Sudish Joseph <joseph@cis.ohio-state.edu>
 
        * gnus.el (gnus-article-display-x-face): Use start-process instead
index 8358d81..ce12205 100644 (file)
 (defvar gnus-cache-remove-articles '(read)
   "*Classes of articles to remove from the cache.")
 
+(defvar gnus-uncacheable-groups "^nnvirtual"
+  "*Groups that match this regexp will not be cached.
+
+If you want to avoid caching on your nnml groups, you could set this 
+variable to \"^nnml\".")
+
 \f
 
 (defvar gnus-cache-buffer nil)
   (let ((number (mail-header-number headers))
        file dir)
     (if (or (not (vectorp headers))    ; This might be a dummy article.
+           (< number 0)                ; Reffed article.
+           (and gnus-uncacheable-groups
+                (string-match gnus-uncacheable-groups group))
            (not (gnus-cache-member-of-class
                  gnus-cache-enter-articles ticked dormant unread))
            (file-exists-p (setq file (gnus-cache-file-name group article))))
          (gnus-make-directory dir))
       ;; Save the article in the cache.
       (if (file-exists-p file)
-         t                             ; The article already is saved, so we end here.
+         t                             ; The article already is saved.
        (let ((gnus-use-cache nil))
          (gnus-summary-select-article))
        (save-excursion
index a0b429b..1bb9852 100644 (file)
@@ -45,7 +45,6 @@
 (defvar gnus-level-zombie)
 (defvar gnus-newsgroup-bookmarks)
 (defvar gnus-newsgroup-dependencies)
-(defvar gnus-newsgroup-headers-hashtb-by-number)
 (defvar gnus-newsgroup-selected-overlay)
 (defvar gnus-newsrc-hashtb)
 (defvar gnus-read-mark)
@@ -362,8 +361,6 @@ NOTE: This command only works with newsgroups that use real or simulated NNTP."
        b)
     (or (gnus-summary-goto-subject article)
        (error (format "No such article: %d" article)))
-    (or gnus-newsgroup-headers-hashtb-by-number
-       (gnus-make-headers-hashtable-by-number))
     (gnus-summary-position-cursor)
     ;; If all commands are to be bunched up on one line, we collect
     ;; them here.  
index ccb0e64..1474b6f 100644 (file)
@@ -53,12 +53,15 @@ Optional argument FOLDER specifies folder name."
   ;; Thanks to yuki@flab.Fujitsu.JUNET and ohm@kaba.junet.
   (mh-find-path)
   (let ((folder
-        (or folder
-            (mh-prompt-for-folder 
-             "Save article in"
-             (funcall gnus-folder-save-name gnus-newsgroup-name
-                      gnus-current-headers gnus-newsgroup-last-folder)
-             t)))
+        (cond ((and (eq folder 'default)
+                    gnus-newsgroup-last-folder)
+               gnus-newsgroup-last-folder)
+              (folder folder)
+              (t (mh-prompt-for-folder 
+                  "Save article in"
+                  (funcall gnus-folder-save-name gnus-newsgroup-name
+                           gnus-current-headers gnus-newsgroup-last-folder)
+                  t))))
        (errbuf (get-buffer-create " *Gnus rcvstore*")))
     (gnus-eval-in-buffer-window 
      gnus-article-buffer
index ce6ce84..8bbfe3f 100644 (file)
@@ -169,11 +169,12 @@ be used instead.")
   '(From Date Newsgroups Subject Message-ID Organization Lines X-Newsreader)
   "*Headers to be generated or prompted for when posting an article.
 RFC977 and RFC1036 require From, Date, Newsgroups, Subject,
-Message-ID.  Organization, Lines and X-Newsreader are optional.  If
-you want Gnus not to insert some header, remove it from this list.")
+Message-ID.  Organization, Lines, In-Reply-To and X-Newsreader are
+optional.  If you want Gnus not to insert some header, remove it from
+this list.")
 
 (defvar gnus-required-mail-headers 
-  '(From Date To Subject Message-ID Organization Lines)
+  '(From Date To Subject In-Reply-To Message-ID Organization Lines)
   "*Headers to be generated or prompted for when mailing a message.
 RFC822 required that From, Date, To, Subject and Message-ID be
 included.  Organization, Lines and X-Mailer are optional.")
@@ -187,7 +188,7 @@ included.  Organization, Lines and X-Mailer are optional.")
 (defvar gnus-check-before-posting 
   '(subject-cmsg multiple-headers sendsys message-id from
                 long-lines control-chars size new-text
-                signature approved)
+                signature approved sender)
   "In non-nil, Gnus will attempt to run some checks on outgoing posts.
 If this variable is t, Gnus will check everything it can.  If it is a
 list, then those elements in that list will be checked.")
@@ -263,11 +264,13 @@ headers.")
 (defvar gnus-summary-send-map nil)
 (defvar gnus-article-copy nil)
 (defvar gnus-reply-subject nil)
+(defvar gnus-add-to-address nil)
+(defvar gnus-in-reply-to nil)
 
 (eval-and-compile
   (autoload 'gnus-uu-post-news "gnus-uu" nil t)
   (autoload 'news-setup "rnewspost")
-  (autoload 'news-mode "rnewspost"))
+  (autoload 'news-reply-mode "rnewspost"))
 
 \f
 ;;;
@@ -456,7 +459,14 @@ Type \\[describe-mode] in the buffer to get a list of commands."
            (gnus-new-news group)
          (gnus-news-followup yank group))
       (if post
-         (gnus-new-mail)
+         (progn
+           (gnus-new-mail)
+           ;; Arrange for mail groups that have no `to-address' to
+           ;; get that when the user sends off the mail.
+           (or to-address
+               (progn
+                 (make-local-variable 'gnus-add-to-address)
+                 (setq gnus-add-to-address group))))
        (gnus-mail-reply yank (and to-address (cdr to-address)) 'followup)))))
 
 (defun gnus-inews-news (&optional use-group-method)
@@ -966,6 +976,7 @@ Headers in `gnus-required-headers' will be generated."
        (Path (gnus-inews-path))
        (Subject nil)
        (Newsgroups nil)
+       (In-Reply-To (gnus-inews-in-reply-yo))
        (To nil)
        (Distribution nil)
        (Lines (gnus-inews-lines))
@@ -1052,6 +1063,7 @@ Headers in `gnus-required-headers' will be generated."
     (let ((from (mail-fetch-field "from"))
          (sender (mail-fetch-field "sender")))
       (if (and from 
+              (not (gnus-check-before-posting 'sender))
               (not (string=
                     (downcase (car (gnus-extract-address-components from)))
                     (downcase (gnus-inews-real-user-address))))
@@ -1341,6 +1353,10 @@ organization."
       (forward-line 1)
       (int-to-string (count-lines (point) (point-max))))))
 
+(defun gnus-inews-in-reply-to ()
+  "Return the In-Reply-To header for this message."
+  gnus-in-reply-to)
+
 \f
 ;;;
 ;;; Gnus Mail Functions 
@@ -1408,10 +1424,10 @@ mailer."
   (gnus-set-global-variables)
   (gnus-new-mail))
 
-(defun gnus-new-mail ()
+(defun gnus-new-mail (&optional to)
   (pop-to-buffer gnus-mail-buffer)
   (erase-buffer)
-  (gnus-mail-setup nil nil nil nil nil nil))
+  (gnus-mail-setup to nil nil nil nil nil))
 
 (defun gnus-mail-reply (&optional yank to-address followup)
   (save-excursion
@@ -1495,7 +1511,7 @@ mailer."
         (or to-address 
             (if (and follow-to (not (stringp follow-to))) sendto
               (or follow-to reply-to from sender "")))
-        subject message-of 
+        subject nil
         (if (zerop (length new-cc)) nil new-cc)
         gnus-article-copy nil)
 
@@ -1503,6 +1519,10 @@ mailer."
        (setq gnus-article-reply cur)
        (make-local-variable 'gnus-prev-winconf)
        (setq gnus-prev-winconf winconf)
+       (make-local-variable 'gnus-reply-subject)
+       (setq gnus-reply-subject subject)
+       (make-local-variable 'gnus-in-reply-to)
+       (setq gnus-in-reply-to message-of)
 
        (auto-save-mode auto-save-default)
        (gnus-inews-modify-mail-mode-map)
@@ -1574,14 +1594,14 @@ mailer."
                 (gnus-y-or-n-p
                  "Are you sure you want to post to all of USENET? ")))
        ()
-      (let ((group (or group (gnus-group-real-name gnus-newsgroup-name)))
+      (let ((group (gnus-group-real-name (or group gnus-newsgroup-name)))
            (cur (cons (current-buffer) (cdr gnus-article-current)))
            (winconf (current-window-configuration))
            from subject date reply-to message-of
            references message-id sender follow-to sendto elt 
            followup-to distribution)
        (set-buffer (get-buffer-create gnus-mail-buffer))
-       (news-mode)
+       (news-reply-mode)
        (if (and (buffer-modified-p)
                 (> (buffer-size) 0)
                 (not (gnus-y-or-n-p 
@@ -1635,7 +1655,7 @@ mailer."
                (setq sendto (concat sendto (and sendto ", ") (cdr elt)))
                (setq follow-to (delq elt follow-to))))
 
-         (news-setup nil subject message-of 
+         (news-setup nil subject nil 
                      (or group sendto 
                          (and follow-to
                               gnus-use-followup-to
@@ -1652,6 +1672,9 @@ mailer."
          (setq gnus-prev-winconf winconf)
          (make-local-variable 'gnus-reply-subject)
          (setq gnus-reply-subject (mail-header-subject gnus-current-headers))
+         (make-local-variable 'gnus-in-reply-to)
+         (setq gnus-in-reply-to message-of)
+
 
          (auto-save-mode auto-save-default)
          (gnus-inews-modify-mail-mode-map)
@@ -1752,10 +1775,19 @@ mailer."
 (defun gnus-mail-send-and-exit (&optional dont-send)
   "Send the current mail and return to Gnus."
   (interactive)
-  (let ((reply gnus-article-reply)
-       (winconf gnus-prev-winconf))
+  (let* ((reply gnus-article-reply)
+        (winconf gnus-prev-winconf)
+        (address-group gnus-add-to-address)
+        (to-address (and address-group
+                         (mail-fetch-field "to"))))
+    (setq gnus-add-to-address nil)
     (or dont-send (gnus-mail-send))
     (bury-buffer)
+    ;; This mail group doesn't have a `to-address', so we add one
+    ;; here.  Magic!  
+    (and to-address
+        (gnus-group-add-parameter 
+         address-group (cons 'to-address to-address)))
     (if (get-buffer gnus-group-buffer)
        (progn
          (if (gnus-buffer-exists-p (car-safe reply))
@@ -1990,7 +2022,7 @@ contains some mail you have written which has been bounced back to
 you.
 If FETCH, try to fetch the article that this is a reply to, if indeed
 this is a reply."
-  (interactive)
+  (interactive "P")
   (gnus-summary-select-article t)
   ;; Create a mail buffer.
   (gnus-new-mail)
@@ -2033,7 +2065,6 @@ Headers will be generated before sending."
     (save-restriction
       (widen)
       (gnus-inews-narrow-to-headers)
-      (gnus-inews-remove-headers)
       (gnus-inews-insert-headers gnus-required-mail-headers)))
   (widen)
   ;; Remove the header separator.
@@ -2086,6 +2117,7 @@ Headers will be generated before sending."
    to subject in-reply-to cc replybuffer actions))
 
 (defun gnus-sendmail-mail-setup (to subject in-reply-to cc replybuffer actions)
+  (mail-mode)
   (mail-setup to subject in-reply-to cc replybuffer actions))
   
 ;;; Gcc handling.
index 9224805..76f413f 100644 (file)
@@ -54,6 +54,9 @@ than this variable, exact matching will be used.
 
 If this variable is nil, exact matching will always be used.")
 
+(defvar gnus-score-uncacheable-files "ADAPT$"
+  "*All score files that match this regexp will not be cached.")
+
 \f
 
 ;; Internal variables.
@@ -588,7 +591,6 @@ SCORE is the score to add."
       (and global
           (not (assq 'read-only alist))
           (setq alist (cons (list 'read-only t) alist)))
-      ;; Update cache.
       (setq gnus-score-cache
            (cons (cons file alist) gnus-score-cache)))
     ;; If there are actual scores in the alist, we add it to the
@@ -776,7 +778,10 @@ SCORE is the score to add."
                ;; There are scores, so we write the file. 
                (and (file-writable-p file)
                     (write-region (point-min) (point-max) 
-                                  file nil 'silent)))))))
+                                  file nil 'silent))))
+           (and gnus-score-uncacheable-files
+                (string-match gnus-score-uncacheable-files file)
+                (gnus-score-remove-from-cache file)))))
       (kill-buffer (current-buffer)))))
   
 (defun gnus-score-headers (score-files &optional trace)
@@ -1651,7 +1656,8 @@ This mode is an extended emacs-lisp mode.
 (defun gnus-score-flush-cache ()
   "Flush the cache of score files."
   (interactive)
-  (setq gnus-score-cache nil))
+  (setq gnus-score-cache nil)
+  (gnus-message 6 "The score cache is now flushed"))
 
 (provide 'gnus-score)
 
diff --git a/lisp/gnus-topic.el b/lisp/gnus-topic.el
new file mode 100644 (file)
index 0000000..c10a055
--- /dev/null
@@ -0,0 +1,161 @@
+;;; gnus-topic.el --- a folding group mode for Gnus
+;; Copyright (C) 1995 Free Software Foundation, Inc.
+
+;; Author: Ilja Weis <kult@uni-paderborn.de>
+;;     Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Keywords: news
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'gnus)
+
+(defvar gnus-group-topic-face 'underline
+  "*Face used to highlight topic headers.")
+
+(defvar gnus-group-topics '(("misc" "." nil))
+  "*Alist of newsgroup topics.
+This alist has entries of the form
+
+   (TOPIC REGEXP SHOW)
+
+where TOPIC is the name of the topic a group is put in if it matches
+REGEXP.  A group can only be in one topic at a time.
+
+If SHOW is nil, newsgroups will be inserted according to
+`gnus-group-topic-topics-only', otherwise that variable is ignored and
+the groups are always shown if SHOW is true or never if SHOW is a
+number.")
+
+(defvar gnus-group-topic-topics-only nil
+  "*If non-nil, only the topics will be shown when typing `l' or `L'.")
+
+;; Internal variables.
+
+(defvar gnus-topics-not-listed nil)
+
+;; Functions.
+
+(defun gnus-group-topic-name ()
+  (get-text-property (gnus-point-at-bol) 'gnus-topic))
+
+(defun gnus-group-prepare-topics (level &optional all lowest regexp)
+  "List all newsgroups with unread articles of level LEVEL or lower, and
+use the `gnus-group-topics' to sort the groups.
+If ALL is non-nil, list groups that have no unread articles.
+If LOWEST is non-nil, list all newsgroups of level LOWEST or higher."
+  (set-buffer gnus-group-buffer)
+  (let ((buffer-read-only nil)
+        (lowest (or lowest 1)))
+    
+    (erase-buffer)
+    
+    ;; List dead groups?
+    (and (>= level 8) (<= lowest 8)
+         (gnus-group-prepare-flat-list-dead 
+          (setq gnus-zombie-list (sort gnus-zombie-list 'string<)) 8 ?Z
+          regexp))
+    
+    (and (>= level 9) (<= lowest 9)
+         (gnus-group-prepare-flat-list-dead 
+          (setq gnus-killed-list (sort gnus-killed-list 'string<)) 9 ?K
+          regexp))
+    
+    ;; Use topics
+    (if (< lowest 8)
+        (let ((topics gnus-group-topics)
+              topic how)
+          (erase-buffer)
+          (while topics
+            (setq topic (car (car topics))
+                  how (nth 2 (car topics))
+                  topics (cdr topics))
+
+            (add-text-properties 
+            (point)
+            (progn
+              (insert topic "\n")
+              (point))
+            (list 'mouse-face gnus-mouse-face
+                  'face gnus-group-topic-face
+                  'gnus-topic topic))
+
+            (if (and (or (and (not how) (not gnus-group-topic-topics-only))
+                        (and how (not (numberp how))))
+                    (not (member topic gnus-topics-not-listed)))
+               (gnus-topic-insert-topic topic level all lowest t)
+             (setq gnus-topics-not-listed
+                   (cons topic gnus-topics-not-listed)))))))
+
+  (gnus-group-set-mode-line)
+  (setq gnus-group-list-mode (cons level all))
+  (run-hooks 'gnus-group-prepare-hook))
+
+(defun gnus-topic-insert-topic (topic level &optional all lowest m)
+  "Insert all groups matching TOPIC with unread articles of level LEVEL or lower.
+If ALL is non-nil, list groups that have no unread articles.  If
+LOWEST is non-nil, list all newsgroups of level LOWEST or higher.  If
+M is non-nil, nothing will be inserted, but only
+`gnus-group-listed-topics' will be changed."
+  (let ((buffer-read-only nil)
+        (regexp (car (cdr (assoc topic gnus-group-topics))))
+        (newsrc (cdr gnus-newsrc-alist))
+        info clevel unread group w)
+    (setq lowest (or lowest 1))
+    (while newsrc
+      (setq info (car newsrc)
+            group (car info)
+            newsrc (cdr newsrc)
+            unread (car (gnus-gethash group gnus-newsrc-hashtb)))
+      (and unread
+           (string-match regexp group)
+           (<= (setq clevel (car (cdr info))) level)
+           (>= clevel lowest)
+           (or all
+               (eq unread t)
+               (> unread 0)
+               (cdr (assq 'tick (nth 3 info))))
+           (progn
+            (gnus-group-insert-group-line 
+             nil group (car (cdr info)) (nth 3 info) unread 
+             (nth 4 info))
+            (setq gnus-topics-not-listed
+                  (delete topic gnus-topics-not-listed)))))))
+
+(defun gnus-topic-remove-topic ()
+  (let ((topic (gnus-group-topic-name))
+       buffer-read-only)
+    (setq gnus-topics-not-listed (cons topic gnus-topics-not-listed))
+    (forward-line 1)
+    (delete-region (point) 
+                  (or (next-single-property-change (point) 'gnus-topic)
+                      (point-max)))))
+  
+(defun gnus-topic-fold ()
+  (let ((topic (gnus-group-topic-name))) 
+    (save-excursion
+      (if (not (member topic gnus-topics-not-listed))
+         (gnus-topic-remove-topic)
+       (forward-line 1)
+       (gnus-topic-insert-topic
+        topic (gnus-group-default-level) 
+        (cdr gnus-group-list-mode))))))
+
+;;; gnus-topic.el ends here
index 7460a51..273ecbf 100644 (file)
@@ -474,7 +474,7 @@ The headers will be included in the sequence they are matched.")
           (insert from)))
     (if post
        (gnus-forward-using-post)
-      (funcall gnus-mail-forward-method))
+      (gnus-mail-forward))
     (delete-file file)
     (kill-buffer buf)
     (setq gnus-uu-digest-from-subject nil)))
index 6bc553e..1984cb4 100644 (file)
@@ -27,7 +27,7 @@
 
 (require 'gnus)
 (require 'gnus-ems)
-(require gnus-easymenu)
+(require 'easymenu)
 (require 'custom)
 
 (defvar gnus-group-menu-hook nil
     ;; Next regexp stolen from highlight-headers.el.
     ;; Modified by Vladimir Alexiev.
     ("\\b\\(s?https?\\|ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?[-a-zA-Z0-9_=?#$@~`%&*+|\\/.,]*[-a-zA-Z0-9_=#$@~`%&*+|\\/]" 0 t gnus-button-url 0))
-  "Alist of regexps matching buttons in an article.
+  "Alist of regexps matching buttons in article bodies.
 
 Each entry has the form (REGEXP BUTTON FORM CALLBACK PAR...), where
 REGEXP: is the string matching text around the button,
@@ -233,6 +233,20 @@ PAR: is a number of a regexp grouping whose text will be passed to CALLBACK.
 CALLBACK can also be a variable, in that case the value of that
 variable it the real callback function.")
 
+(defvar gnus-header-button-alist 
+  '(("^\\(References\\|Message-ID\\):" "<[^>]+>" 0 t gnus-button-message-id 0)
+    ("^\\(From\\|Reply-To\\): " ".*" 0 t gnus-button-reply 0)
+    ("^\\(Cc\\|To\\):" "[^ \t]+@[^ \t]+\\|<[^>]+>" 0 t gnus-button-mailto 0))
+  "Alist of headers and regexps to match buttons in article heads.
+
+This alist is very similar to `gnus-button-alist', except that each
+alist has an additional HEADER element first in each entry:
+
+(HEADER REGEXP BUTTON FORM CALLBACK PAR)
+
+HEADER is a regexp to match a header.  For a fuller explanation, see
+`gnus-button-alist'.")
+
 ;see gnus-cus.el
 ;(eval-when-compile
 ;  (defvar browse-url-browser-function))
@@ -328,7 +342,9 @@ variable it the real callback function.")
         ["Make a doc group" gnus-group-make-doc-group t]
         ["Make a kiboze group" gnus-group-make-kiboze-group t]
         ["Make a virtual group" gnus-group-make-empty-virtual t]
-        ["Add a group to a virtual" gnus-group-add-to-virtual t])
+        ["Add a group to a virtual" gnus-group-add-to-virtual t]
+        ["Rename group" gnus-group-rename-group t]
+        ["Delete group" gnus-group-delete-group t])
        ("Editing groups"
         ["Parameters" gnus-group-edit-group-parameters t]
         ["Select method" gnus-group-edit-group-method t]
@@ -658,6 +674,7 @@ variable it the real callback function.")
         ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
         ["Rot 13" gnus-summary-caesar-message t]
         ["Add buttons" gnus-article-add-buttons t]
+        ["Add buttons to head" gnus-article-add-buttons-to-head t]
         ["Stop page breaking" gnus-summary-stop-page-breaking t]
         ["Toggle MIME" gnus-summary-toggle-mime t]
         ["Toggle header" gnus-summary-toggle-header t])
@@ -668,6 +685,7 @@ variable it the real callback function.")
         ["Save in MH folder" gnus-summary-save-article-folder t]
         ["Save in VM folder" gnus-summary-save-article-vm t]
         ["Save in RMAIL mbox" gnus-summary-save-article-rmail t]
+        ["Save body in file" gnus-summary-save-article-body-file t]
         ["Pipe through a filter" gnus-summary-pipe-output t])
        ("Backend"
         ["Respool article" gnus-summary-respool-article t]
@@ -1202,7 +1220,8 @@ do the highlighting.  See the documentation for those functions."
   (gnus-article-highlight-headers)
   (gnus-article-highlight-citation force)
   (gnus-article-highlight-signature)
-  (gnus-article-add-buttons force))
+  (gnus-article-add-buttons force)
+  (gnus-article-add-buttons-to-head))
 
 (defun gnus-article-highlight-some (&optional force)
   "Highlight current article.
@@ -1300,10 +1319,9 @@ It does this by making everything after `gnus-signature-separator' invisible."
                                gnus-hidden-properties)))))
 
 (defun gnus-article-add-buttons (&optional force)
-  "Find external references in article and make them to buttons.
-
-External references are things like message-ids and URLs, as specified by 
-`gnus-button-alist'."
+  "Find external references in the article and make buttons of them.
+\"External references\" are things like Message-IDs and URLs, as
+specified by `gnus-button-alist'."
   (interactive (list 'force))
   (if (eq gnus-button-last gnus-button-alist)
       ()
@@ -1329,16 +1347,53 @@ External references are things like message-ids and URLs, as specified by
              ()
            (goto-char (match-end 0))
            (if (eval form)
-               (gnus-article-add-button start end 'gnus-button-push
-                                        (set-marker (make-marker)
-                                                    from)))))))))
+               (gnus-article-add-button 
+                start end 'gnus-button-push
+                (set-marker (make-marker) from)))))))))
+
+;; Add buttons to the head of an article.
+(defun gnus-article-add-buttons-to-head ()
+  "Add buttons to the head of the article."
+  (interactive)
+  (save-excursion
+    (set-buffer gnus-article-buffer)
+    (let ((buffer-read-only nil)
+         (inhibit-point-motion-hooks t)
+         (case-fold-search t)
+         (alist gnus-header-button-alist)
+         entry beg end)
+      (gnus-narrow-to-headers)
+      (while alist
+       (goto-char (point-min))
+       (if (not (re-search-forward (car (setq entry (car alist))) nil t))
+           ()                          ; That header isn't here.
+         (setq beg (match-beginning 0))
+         (setq end (or (and (re-search-forward "^[^ \t]" nil t)
+                            (match-beginning 0))
+                       (point-max)))
+         (goto-char beg)
+         (while (re-search-forward (nth 1 entry) end t)
+           (let* ((from (match-beginning 0))
+                  (entry (cdr entry))
+                  (start (match-beginning (nth 1 entry)))
+                  (end (match-end (nth 1 entry)))
+                  (form (nth 2 entry)))
+             (goto-char (match-end 0))
+             (and (eval form)
+                  (gnus-article-add-button 
+                   start end (nth 3 entry)
+                   (buffer-substring (match-beginning (nth 4 entry))
+                                     (match-end (nth 4 entry))))))))
+       (goto-char end)
+       (setq alist (cdr alist))))
+    (widen)))
+
 (defun gnus-netscape-open-url (url)
   "Open URL in netscape, or start new scape with URL."
-  (let ((process (start-process (concat "netscape " url)
-                               nil
-                               "netscape"
-                               "-remote" 
-                               (concat "openUrl(" url ")'"))))
+  (let ((process
+        (start-process 
+         (concat "netscape " url) nil
+         "netscape" "-remote"  (concat "openUrl(" url ")'"))))
     (set-process-sentinel process 
                          (` (lambda (process change)
                               (or (eq (process-exit-status process) 0)
@@ -1355,11 +1410,12 @@ External references are things like message-ids and URLs, as specified by
   (and gnus-article-button-face
        (gnus-overlay-put (gnus-make-overlay from to)
                         'face gnus-article-button-face))
-  (add-text-properties from to
-                      (append (and gnus-article-mouse-face
-                                   (list 'mouse-face gnus-article-mouse-face))
-                              (list 'gnus-callback fun)
-                              (and data (list 'gnus-data data)))))
+  (add-text-properties 
+   from to
+   (append (and gnus-article-mouse-face
+               (list 'mouse-face gnus-article-mouse-face))
+          (list 'gnus-callback fun)
+          (and data (list 'gnus-data data)))))
 
 ;;; Internal functions:
 
@@ -1415,11 +1471,19 @@ External references are things like message-ids and URLs, as specified by
                      (cons fun args)))))))
 
 (defun gnus-button-message-id (message-id)
-  ;; Push on MESSAGE-ID.
+  ;; Fetch MESSAGE-ID.
   (save-excursion
     (set-buffer gnus-summary-buffer)
     (gnus-summary-refer-article message-id)))
 
+(defun gnus-button-mailto (address)
+  ;; Mail to ADDRESS.
+  (gnus-new-mail address))
+
+(defun gnus-button-reply (address)
+  ;; Reply to ADDRESS.
+  (gnus-mail-reply t address))
+
 ;;; Compatibility Functions:
 
 (or (fboundp 'rassoc)
index d549de0..003095a 100644 (file)
@@ -88,13 +88,15 @@ save those articles instead."
   (let ((default-name
          (funcall gnus-mail-save-name gnus-newsgroup-name
                   gnus-current-headers gnus-newsgroup-last-mail)))
-    (or folder
-       (setq folder
-             (read-file-name
-              (concat "Save article in VM folder: (default "
-                      (file-name-nondirectory default-name) ") ")
-              (file-name-directory default-name)
-              default-name)))
+    (setq filename
+         (cond ((eq filename 'default)
+                default-name)
+               (filename filename)
+               (t (read-file-name 
+                   (concat "Save article in VM folder: (default "
+                           (file-name-nondirectory default-name) ") ")
+                   (file-name-directory default-name)
+                   default-name))))
     (setq folder
          (expand-file-name folder
                            (and default-name
index bcd92b0..9d48c40 100644 (file)
@@ -254,6 +254,11 @@ newsgroups.")
 If Emacs should crash without saving the .newsrc files, complete
 information can be restored from the dribble file.")
 
+(defvar gnus-dribble-directory nil
+  "*The directory where dribble files will be saved.
+If this variable is nil, the directory where the .newsrc files are
+saved will be used.")
+
 (defvar gnus-asynchronous nil
   "*If non-nil, Gnus will supply backends with data needed for async article fetching.")
 
@@ -351,6 +356,15 @@ Gnus provides the following functions:
 * gnus-summary-save-in-file (article format).
 * gnus-summary-save-in-vm (use VM's folder format).")
 
+(defvar gnus-prompt-before-saving 'always
+  "*This variable says how much prompting is to be done when saving articles.
+If it is nil, no prompting will be done, and the articles will be
+saved to the default files.  If this variable is `always', each and
+every article that is saved will be preceded by a prompt, even when
+saving large batches of articles.  If this variable is neither nil not
+`always', there the user will be prompted once for a file name for
+each invocation of the saving commands.")
+
 (defvar gnus-rmail-save-name (function gnus-plain-save-name)
   "*A function generating a file name to save articles in Rmail format.
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE.")
@@ -651,6 +665,16 @@ to expose hidden threads.")
 If nil, which is the default, articles that have different subjects
 from their parents will start separate threads.")
 
+(defvar gnus-thread-operation-ignore-subject t
+  "*If non-nil, subjects will be ignored when doing thread commands.
+This affects commands like `gnus-summary-kill-thread' and
+`gnus-summary-lower-thread'.  
+
+If this variable is nil, articles in the same thread with different
+subjects will not be included in the operation in question.  If this
+variable is `fuzzy', only articles that have subjects that are fuzzily
+equal will be included.")
+
 (defvar gnus-thread-indent-level 4
   "*Number that says how much each sub-thread should be indented.")
 
@@ -710,7 +734,9 @@ If the value is t and the next newsgroup is empty, Gnus will exit
 summary mode and go back to group mode.  If the value is neither nil
 nor t, Gnus will select the following unread newsgroup.  In
 particular, if the value is the symbol `quietly', the next unread
-newsgroup will be selected without any confirmations.")
+newsgroup will be selected without any confirmation, and if it is
+`almost-quietly', the next group will be selected without any
+confirmation if you are located on the last article in the group.")
 
 (defvar gnus-auto-select-same nil
   "*If non-nil, select the next article with the same subject.")
@@ -851,7 +877,11 @@ hierarchy in its entirety.")
 This function will be called with group info entries as the arguments
 for the groups to be sorted.  Pre-made functions include
 `gnus-group-sort-by-alphabet', `gnus-group-sort-by-unread' and
-`gnus-group-sort-by-level'")
+`gnus-group-sort-by-level'.
+
+This variable can also be a list of sorting functions.  In that case,
+the most significant sort function should be the last function in the
+list.")
 
 ;; Mark variables suggested by Thomas Michanek
 ;; <Thomas.Michanek@telelogic.se>. 
@@ -1092,6 +1122,12 @@ subthread and should then return the score of the thread.
 
 Some functions you can use are `+', `max', or `min'.")
 
+(defvar gnus-auto-subscribed-groups 
+  "^nnml\\|^nnfolder\\|^nnmbox\\|^nnmh\\|^nnbabyl"
+  "*All new groups that match this regexp will be subscribed automatically.
+Note that this variable only deals with new groups.  It has no effect
+whatsoever on old groups.")
+
 (defvar gnus-options-subscribe nil
   "*All new groups matching this regexp will be subscribed unconditionally.
 Note that this variable deals only with new newsgroups.  This variable
@@ -1162,7 +1198,10 @@ if the second is non-nil, empty groups should also be displayed. If
 the third is non-nil, it is a number. No groups with a level lower
 than this number should be displayed.
 
-The only current function implemented is `gnus-group-prepare-flat'.")
+The only current function implemented are `gnus-group-prepare-flat'
+(which does the normal boring group display) and
+`gnus-group-prepare-topics' (which does a folding display accoring to
+topics).")
 
 (defvar gnus-group-prepare-hook nil
   "*A hook called after the group buffer has been generated.
@@ -1254,7 +1293,15 @@ is not run if `gnus-visual' is nil.")
   "*A hook called when exiting Gnus.")
 
 (defvar gnus-save-newsrc-hook nil
-  "*A hook called when saving the newsrc file.")
+  "*A hook called before saving any of the newsrc files.")
+
+(defvar gnus-save-quick-newsrc-hook nil
+  "*A hook called just before saving the quick newsrc file.
+Can be used to turn version control on or off.")
+
+(defvar gnus-save-standard-newsrc-hook nil
+  "*A hook called just before saving the standard newsrc file.
+Can be used to turn version control on or off.")
 
 (defvar gnus-summary-update-hook 
   (list 'gnus-summary-highlight-line)
@@ -1386,6 +1433,10 @@ variable (string, integer, character, etc).")
        (list ?S 'subject ?s)
        (list ?e 'unselected ?d)
        (list ?u 'user-defined ?s)
+       (list ?d '(length gnus-newsgroup-dormant) ?d)
+       (list ?t '(length gnus-newsgroup-marked) ?d)
+       (list ?r '(length gnus-newsgroup-reads) ?d)
+       (list ?E 'gnus-newsgroup-expunged-tally ?d)
        (list ?s '(gnus-current-score-file-nondirectory) ?s)))
 
 (defconst gnus-group-mode-line-format-alist 
@@ -1399,7 +1450,7 @@ variable (string, integer, character, etc).")
   "gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls + Boys)"
   "The mail address of the Gnus maintainers.")
 
-(defconst gnus-version "September Gnus v0.02"
+(defconst gnus-version "September Gnus v0.3"
   "Version number for this version of Gnus.")
 
 (defvar gnus-info-nodes
@@ -1419,6 +1470,7 @@ variable (string, integer, character, etc).")
 (defvar gnus-work-buffer " *gnus work*")
 
 (defvar gnus-original-article-buffer " *Original Article*")
+(defvar gnus-original-article nil)
 
 (defvar gnus-buffer-list nil
   "Gnus buffers that should be killed on exit.")
@@ -1515,6 +1567,8 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
 (defvar gnus-newsgroup-reads nil
   "Alist of read articles and article marks in the current newsgroup.")
 
+(defvar gnus-newsgroup-expunged-tally nil)
+
 (defvar gnus-newsgroup-marked nil
   "List of ticked articles in the current newsgroup (a subset of unread art).")
 
@@ -1597,6 +1651,7 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
     gnus-summary-mark-below gnus-newsgroup-active gnus-scores-exclude-files
     gnus-newsgroup-history gnus-newsgroup-ancient
     (gnus-newsgroup-adaptive . gnus-use-adaptive-scoring)
+    (gnus-newsgroup-expunged-tally . 0)
     gnus-cache-removeable-articles
     gnus-newsgroup-data gnus-newsgroup-data-reverse
     gnus-newsgroup-limit gnus-newsgroup-limits)
@@ -1667,9 +1722,7 @@ Thank you for your help in stamping out bugs.
   (autoload 'nnsoup-pack-replies "nnsoup" nil t)
 
   ;; gnus-mh
-  (autoload 'gnus-mail-reply-using-mhe "gnus-mh")
-  (autoload 'gnus-mail-forward-using-mhe "gnus-mh")
-  (autoload 'gnus-mail-other-window-using-mhe "gnus-mh")
+  (autoload 'gnus-mh-mail-setup "gnus-mh")
   (autoload 'gnus-summary-save-in-folder "gnus-mh")
   (autoload 'gnus-summary-save-article-folder "gnus-mh")
   (autoload 'gnus-Folder-save-name "gnus-mh")
@@ -1695,6 +1748,7 @@ Thank you for your help in stamping out bugs.
   (autoload 'gnus-article-highlight-headers "gnus-vis" nil t)
   (autoload 'gnus-article-highlight-signature "gnus-vis" nil t)
   (autoload 'gnus-article-add-buttons "gnus-vis" nil t)
+  (autoload 'gnus-article-add-buttons-to-head "gnus-vis" nil t)
   (autoload 'gnus-article-next-button "gnus-vis" nil t)
   (autoload 'gnus-article-add-button "gnus-vis")
 
@@ -1736,6 +1790,9 @@ Thank you for your help in stamping out bugs.
   ;; gnus-edit
   (autoload 'gnus-score-customize "gnus-edit" nil t)
 
+  ;; gnus-topic
+  (autoload 'gnus-topic-fold "gnus-topic")
+
   ;; gnus-uu
   (autoload 'gnus-uu-extract-map "gnus-uu" nil nil 'keymap)
   (autoload 'gnus-uu-mark-map "gnus-uu" nil nil 'keymap)
@@ -1778,11 +1835,9 @@ Thank you for your help in stamping out bugs.
   (autoload 'gnus-summary-reply-with-original "gnus-msg" nil t)
   (autoload 'gnus-summary-mail-forward "gnus-msg" nil t)
   (autoload 'gnus-summary-mail-other-window "gnus-msg" nil t)
-  (autoload 'gnus-mail-reply-using-mail "gnus-msg")
   (autoload 'gnus-mail-yank-original "gnus-msg")
   (autoload 'gnus-mail-send-and-exit "gnus-msg")
-  (autoload 'gnus-mail-forward-using-mail "gnus-msg")
-  (autoload 'gnus-mail-other-window-using-mail "gnus-msg")
+  (autoload 'gnus-sendmail-setup-mail "gnus-msg")
   (autoload 'gnus-article-mail "gnus-msg")
   (autoload 'gnus-bug "gnus-msg" nil t)
   (autoload 'gnus-inews-message-id "gnus-msg")
@@ -3270,6 +3325,8 @@ Note: LIST has to be sorted over `<'."
   (define-key gnus-group-group-map "V" 'gnus-group-make-empty-virtual)
   (define-key gnus-group-group-map "D" 'gnus-group-enter-directory)
   (define-key gnus-group-group-map "f" 'gnus-group-make-doc-group)
+  (define-key gnus-group-group-map "r" 'gnus-group-rename-group)
+  (define-key gnus-group-group-map "\177" 'gnus-group-delete-group)
   (define-key gnus-group-group-map "sb" 'gnus-group-brew-soup)
   (define-key gnus-group-group-map "sw" 'gnus-soup-save-areas)
   (define-key gnus-group-group-map "ss" 'gnus-soup-send-replies)
@@ -3671,6 +3728,18 @@ If REGEXP, only list groups matching REGEXP."
   "Return nil if GROUP is native, non-nil if it is foreign."
   (string-match ":" group))
 
+(defun gnus-group-topic-p ()
+  "Return non-nil if the current line is a topic."
+  (get-text-property (gnus-point-at-bol) 'gnus-topic))
+
+(defun gnus-group-add-parameter (group param)
+  "Add parameter PARAM to GROUP."
+  (let ((info (nth 2 (gnus-gethash group gnus-newsrc-hashtb))))
+    (if (not info)
+       () ; This is a dead group. We just ignore it.
+      ;; Cons the new param to the old one and update.
+      (gnus-group-set-info (cons param (nth 5 info)) group 'params))))
+
 (defun gnus-group-set-info (info &optional method-only-group part)
   (let* ((entry (gnus-gethash
                 (or method-only-group (car info)) gnus-newsrc-hashtb))
@@ -4032,22 +4101,26 @@ If the prefix argument ALL is non-nil, already read articles become
 readable. If the optional argument NO-ARTICLE is non-nil, no article
 will be auto-selected upon group entry."
   (interactive "P")
-  (let ((group (or group (gnus-group-group-name)))
-       number active marked entry)
-    (or group (error "No group on current line"))
-    (setq marked 
-         (nth 3 (nth 2 (setq entry (gnus-gethash group gnus-newsrc-hashtb)))))
-    ;; This group might be a dead group. In that case we have to get
-    ;; the number of unread articles from `gnus-active-hashtb'.
-    (if entry
-       (setq number (car entry))
-      (if (setq active (gnus-gethash group gnus-active-hashtb))
-         (setq number (- (1+ (cdr active)) (car active)))))
-    (gnus-summary-read-group 
-     group (or all (and (numberp number) 
-                       (zerop (+ number (length (cdr (assq 'tick marked)))
-                                 (length (cdr (assq 'dormant marked)))))))
-     no-article)))
+  (if (gnus-group-topic-p)
+      (gnus-topic-fold) ; This is a topic line.
+    ;; And this is a real group.
+    (let ((group (or group (gnus-group-group-name)))
+         number active marked entry)
+      (or group (error "No group on current line"))
+      (setq marked 
+           (nth 3 (nth 2 (setq entry (gnus-gethash
+                                      group gnus-newsrc-hashtb)))))
+      ;; This group might be a dead group. In that case we have to get
+      ;; the number of unread articles from `gnus-active-hashtb'.
+      (if entry
+         (setq number (car entry))
+       (if (setq active (gnus-gethash group gnus-active-hashtb))
+           (setq number (- (1+ (cdr active)) (car active)))))
+      (gnus-summary-read-group 
+       group (or all (and (numberp number) 
+                         (zerop (+ number (length (cdr (assq 'tick marked)))
+                                   (length (cdr (assq 'dormant marked)))))))
+       no-article))))
 
 (defun gnus-group-select-group (&optional all)
   "Select this newsgroup.
@@ -4058,7 +4131,7 @@ If argument ALL is non-nil, already read articles become readable."
 
 (defun gnus-group-quick-select-group (&optional all)
   "Select the current group \"quickly\". 
-This means that no highlights or scoring will be performed."
+This means that no highlighting or scoring will be performed."
   (interactive "P")
   (let (gnus-visual
        gnus-score-find-score-files-function
@@ -4066,6 +4139,15 @@ This means that no highlights or scoring will be performed."
        gnus-summary-expunge-below)
     (gnus-group-read-group all t)))
 
+;;;###autoload
+(defun gnus-fetch-group (group)
+  "Start Gnus if necessary and enter GROUP.
+Returns whether the fetching was successful or not."
+  (interactive "sGroup name: ")
+  (or (get-buffer gnus-group-buffer)
+      (gnus))
+  (gnus-group-select-group))
+
 (defun gnus-group-select-group-all ()
   "Select the current group and display all articles in it."
   (interactive)
@@ -4276,6 +4358,76 @@ ADDRESS."
       (and (gnus-check-backend-function 'request-create-group nname)
           (gnus-request-create-group nname)))))
 
+(defun gnus-group-delete-group (group &optional force)
+  "Delete the current group.
+If FORCE (the prefix) is non-nil, all the articles in the group will
+be deleted.  This is \"deleted\" as in \"removed forever from the face
+of the Earth\".  There is no undo."
+  (interactive 
+   (list (gnus-group-group-name)
+        current-prefix-arg))
+  (or group (error "No group to rename"))
+  (or (gnus-check-backend-function 'request-delete-group group)
+      (error "This backend does not support group deletion"))
+  (prog1
+      (if (not (gnus-yes-or-no-p
+               (format
+                "Do you really want to delete %s%s? " 
+                group (if force " and all its contents" ""))))
+         () ; Whew!
+       (gnus-message 6 "Deleting group %s..." group)
+       (if (not (gnus-request-delete-group group force))
+           (progn
+             (gnus-message 3 "Couldn't delete group %s" group)
+             (ding))
+         (gnus-message 6 "Deleting group %s...done" group)
+         (gnus-group-goto-group group)
+         (gnus-group-kill-group 1 t)
+         t))
+    (gnus-group-position-point)))
+
+(defun gnus-group-rename-group (group new-name)
+  (interactive
+   (list
+    (gnus-group-group-name)
+    (progn
+      (or (gnus-check-backend-function 
+          'request-rename-group (gnus-group-group-name))
+         (error "This backend does not support renaming groups"))
+      (read-string "New group name: "))))
+
+  (or (gnus-check-backend-function 'request-rename-group group)
+      (error "This backend does not support renaming groups"))
+
+  (or group (error "No group to rename"))
+  (and (string-match "^[ \t]*$" new-name) 
+       (error "Not a valid group name"))
+
+  ;; We find the proper prefixed name.
+  (setq new-name
+       (gnus-group-prefixed-name 
+        (gnus-group-real-name new-name)
+        (nth 4 (nth 2 (gnus-gethash group gnus-newsrc-hashtb)))))
+
+  (gnus-message 6 "Renaming group %s to %s..." group new-name)
+  (prog1
+      (if (not (gnus-request-rename-group group new-name))
+         (progn
+           (gnus-message 3 "Couldn't rename group %s to %s" group new-name)
+           (ding))
+       ;; We rename the group internally by killing it...
+       (gnus-group-goto-group group)
+       (gnus-group-kill-group)
+       ;; ... changing its name ...
+       (setcar (cdr (car gnus-list-of-killed-groups))
+               new-name)
+       ;; ... and then yanking it.  Magic!
+       (gnus-group-yank-group) 
+       (gnus-message 6 "Renaming group %s to %s...done" group new-name)
+       new-name)
+    (gnus-group-position-point)))
+
+
 (defun gnus-group-edit-group (group &optional part)
   "Edit the group on the current line."
   (interactive (list (gnus-group-group-name)))
@@ -4514,10 +4666,18 @@ score file entries for articles to include in the group."
 ;; Suggested by Joe Hildebrand <hildjj@idaho.fuentez.com>.
 
 (defun gnus-group-sort-groups ()
-  "Sort the group buffer using `gnus-group-sort-function'."
+  "Sort the group buffer according to `gnus-group-sort-function'."
   (interactive)
-  (setq gnus-newsrc-alist 
-       (sort (cdr gnus-newsrc-alist) gnus-group-sort-function))
+  (let ((funcs (if (listp gnus-group-sort-function) gnus-group-sort-function
+                (list gnus-group-sort-function))))
+    ;; We peel off the dummy group off the alist.
+    (and (equal (car (car gnus-newsrc-alist)) "dummy.group")
+        (setq gnus-newsrc-alist (cdr gnus-newsrc-alist)))
+    ;; Do the sorting.
+    (while funcs
+      (setq gnus-newsrc-alist 
+           (sort (cdr gnus-newsrc-alist) (car funcs)))
+      (setq funcs (cdr funcs))))
   (gnus-make-hashtable-from-newsrc-alist)
   (gnus-group-list-groups))
 
@@ -4533,6 +4693,10 @@ score file entries for articles to include in the group."
 (defun gnus-group-sort-by-level (info1 info2)
   (< (nth 1 info1) (nth 1 info2)))
 
+(defun gnus-group-sort-by-method (info1 info2)
+  (string< (symbol-name (car (gnus-find-method-for-group (car info1))))
+          (symbol-name (car (gnus-find-method-for-group (car info2))))))
+
 ;; Group catching up.
 
 (defun gnus-group-catchup-current (&optional n all)
@@ -4745,7 +4909,7 @@ The killed newsgroups can be yanked by using \\[gnus-group-yank-group]."
     (beginning-of-line)                        ;Important when LINES < 1
     (gnus-group-kill-group lines)))
 
-(defun gnus-group-kill-group (&optional n)
+(defun gnus-group-kill-group (&optional n discard)
   "The the next N groups.
 The killed newsgroups can be yanked by using \\[gnus-group-yank-group].
 However, only groups that were alive can be yanked; already killed 
@@ -4763,7 +4927,8 @@ The return value is the name of the (last) group that was killed."
          (gnus-group-remove-mark group)
          (setq level (gnus-group-group-level))
          (gnus-delete-line)
-         (if (setq entry (gnus-gethash group gnus-newsrc-hashtb))
+         (if (and (not discard)
+                  (setq entry (gnus-gethash group gnus-newsrc-hashtb)))
              (setq gnus-list-of-killed-groups 
                    (cons (cons (car entry) (nth 2 entry)) 
                          gnus-list-of-killed-groups)))
@@ -5711,6 +5876,7 @@ buffer.
   (define-key gnus-summary-wash-time-map "o" 'gnus-article-date-original)
 
   (define-key gnus-summary-wash-map "b" 'gnus-article-add-buttons)
+  (define-key gnus-summary-wash-map "B" 'gnus-article-add-buttons-to-head)
   (define-key gnus-summary-wash-map "o" 'gnus-article-treat-overstrike)
   (define-key gnus-summary-wash-map "w" 'gnus-article-word-wrap)
   (define-key gnus-summary-wash-map "c" 'gnus-article-remove-cr)
@@ -5751,6 +5917,7 @@ buffer.
   (define-key gnus-summary-save-map "m" 'gnus-summary-save-article-mail)
   (define-key gnus-summary-save-map "r" 'gnus-summary-save-article-rmail)
   (define-key gnus-summary-save-map "f" 'gnus-summary-save-article-file)
+  (define-key gnus-summary-save-map "b" 'gnus-summary-save-article-body-file)
   (define-key gnus-summary-save-map "h" 'gnus-summary-save-article-folder)
   (define-key gnus-summary-save-map "v" 'gnus-summary-save-article-vm)
   (define-key gnus-summary-save-map "p" 'gnus-summary-pipe-output)
@@ -6051,6 +6218,12 @@ article number."
            (setq gnus-newsgroup-data data)
            (setq gnus-current-score-file score-file))))))
 
+(defun gnus-summary-last-article-p (&optional article)
+  "Return whether ARTICLE is the last article in the buffer."
+  (if (not (setq article (or article (gnus-summary-article-number))))
+      t ; All non-existant numbers are the last article. :-)
+    (cdr (gnus-data-find-list article))))
+    
 (defun gnus-summary-insert-dummy-line (sformat subject number)
   (if (not sformat) 
       (setq sformat gnus-summary-dummy-line-format-spec))
@@ -6410,6 +6583,8 @@ If NO-DISPLAY, don't generate a summary buffer."
                          (setq gnus-newsgroup-reads
                                (cons (cons number gnus-low-score-mark)
                                      gnus-newsgroup-reads))
+                         (setq gnus-newsgroup-expunged-tally 
+                               (1+ gnus-newsgroup-expunged-tally))
                          t)))))
        nil
       (list (cons head tail)))))
@@ -6729,6 +6904,8 @@ or a straight list of headers."
                        gnus-summary-default-score 0)
                    gnus-summary-expunge-below))
            (setq header nil
+                 gnus-newsgroup-expunged-tally 
+                 (1+ gnus-newsgroup-expunged-tally)
                  gnus-newsgroup-unreads 
                  (delq number gnus-newsgroup-unreads)
                  gnus-newsgroup-reads
@@ -6804,7 +6981,9 @@ or a straight list of headers."
              (delq number gnus-newsgroup-unreads))
        (setq gnus-newsgroup-reads
              (cons (cons number gnus-low-score-mark)
-                   gnus-newsgroup-reads)))
+                   gnus-newsgroup-reads))
+       (setq gnus-newsgroup-expunged-tally 
+             (1+ gnus-newsgroup-expunged-tally)))
        ((and gnus-newsgroup-limit
             (not (memq number gnus-newsgroup-limit)))
        ;; Don't print this article - it's not in the limit.
@@ -7154,7 +7333,7 @@ If WHERE is `summary', the summary mode line format will be used."
        (setq mode-line-buffer-identification mode-string)
        (set-buffer-modified-p t))))
 
-(defun gnus-create-xref-hashtb (from-newsgroup headers unreads)
+(defun gnus-create-xref-hashtb (from-newsgroup headers unreads ticked dormant)
   "Go through the HEADERS list and add all Xrefs to a hash table.
 The resulting hash table is returned, or nil if no Xrefs were found."
   (let* ((from-method (gnus-find-method-for-group from-newsgroup))
@@ -7169,7 +7348,9 @@ The resulting hash table is returned, or nil if no Xrefs were found."
     (while headers
       (setq header (car headers))
       (if (and (setq xrefs (mail-header-xref header))
-              (not (memq (mail-header-number header) unreads)))
+              (not (memq (setq number (mail-header-number header)) unreads))
+              (not (memq number ticked))
+              (not (memq number dormant)))
          (progn
            (setq start 0)
            (while (string-match "\\([^ ]+\\)[:/]\\([0-9]+\\)" xrefs start)
@@ -7185,7 +7366,8 @@ The resulting hash table is returned, or nil if no Xrefs were found."
       (setq headers (cdr headers)))
     (if start xref-hashtb nil)))
 
-(defun gnus-mark-xrefs-as-read (from-newsgroup headers unreads expirable)
+(defun gnus-mark-xrefs-as-read (from-newsgroup headers unreads expirable
+                                              ticked dormant)
   "Look through all the headers and mark the Xrefs as read."
   (let ((virtual (memq 'virtual 
                       (assoc (symbol-name (car (gnus-find-method-for-group 
@@ -7196,7 +7378,8 @@ The resulting hash table is returned, or nil if no Xrefs were found."
     (save-excursion
       (set-buffer gnus-group-buffer)
       (if (setq xref-hashtb 
-               (gnus-create-xref-hashtb from-newsgroup headers unreads))
+               (gnus-create-xref-hashtb 
+                from-newsgroup headers unreads ticked dormant))
          (mapatoms 
           (lambda (group)
             (if (string= from-newsgroup (setq name (symbol-name group)))
@@ -7908,7 +8091,8 @@ The prefix argument ALL means to select all articles."
        (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))
+           group headers gnus-newsgroup-unreads gnus-newsgroup-expirable
+           gnus-newsgroup-marked gnus-newsgroup-dormant))
       ;; Do adaptive scoring, and possibly save score files.
       (and gnus-newsgroup-adaptive
           (gnus-score-adaptive))
@@ -8079,67 +8263,6 @@ previous group instead."
            (setq current-group target-group
                  target-group nil)))))))
 
-(defun gnus-summary-next-group-old (&optional no-article group backward)
-  "Exit current newsgroup and then select next unread newsgroup.
-If prefix argument NO-ARTICLE is non-nil, no article is selected initially.
-If BACKWARD, go to previous group instead."
-  (interactive "P")
-  (gnus-set-global-variables)
-  (let ((ingroup gnus-newsgroup-name)
-       (sumbuf (current-buffer))
-       num)
-    (set-buffer gnus-group-buffer)
-    (if (and group
-            (or (and (numberp (setq num (car (gnus-gethash
-                                              group gnus-newsrc-hashtb))))
-                     (< num 1))
-                (null num)))
-       (progn
-         (gnus-group-jump-to-group group)
-         (setq group nil))
-      (gnus-group-jump-to-group ingroup))
-    (gnus-summary-search-group backward)
-    (let ((group (or group (gnus-summary-search-group backward))))
-      (set-buffer sumbuf)
-      (gnus-summary-exit t)            ;Update all information.
-      (if (null group)
-         (gnus-summary-exit-no-update t)
-       (gnus-group-jump-to-group ingroup)
-       (setq group (gnus-summary-search-group backward))
-       (gnus-message 5 "Selecting %s..." group)
-       (set-buffer gnus-group-buffer)
-       ;; We are now in group mode buffer.
-       ;; Make sure group mode buffer point is on GROUP.
-       (gnus-group-jump-to-group group)
-       (if (not (eq gnus-auto-select-next 'quietly))
-           (progn
-             (gnus-summary-read-group group nil no-article sumbuf)
-             (and (string= gnus-newsgroup-name ingroup)
-                  (bufferp sumbuf) (buffer-name sumbuf)
-                  (progn
-                    (set-buffer (setq gnus-summary-buffer sumbuf))
-                    (gnus-summary-exit-no-update t))))
-         (let ((prevgroup group))
-           (gnus-group-jump-to-group ingroup)
-           (setq group (gnus-summary-search-group backward))
-           (gnus-summary-read-group group nil no-article sumbuf)
-           (while (and (string= gnus-newsgroup-name ingroup)
-                       (bufferp sumbuf) 
-                       (buffer-name sumbuf)
-                       (not (string= prevgroup (gnus-group-group-name))))
-             (set-buffer gnus-group-buffer)
-             (gnus-summary-read-group 
-              (setq prevgroup (gnus-group-group-name)) 
-              nil no-article sumbuf))
-           (and (string= prevgroup (gnus-group-group-name))
-                ;; We have reached the final group in the group
-                ;; buffer.
-                (progn
-                  (if (buffer-name sumbuf)
-                      (progn
-                        (set-buffer sumbuf)
-                        (gnus-summary-exit)))))))))))
-
 (defun gnus-summary-prev-group (&optional no-article)
   "Exit current newsgroup and then select previous unread newsgroup.
 If prefix argument NO-ARTICLE is non-nil, no article is selected initially."
@@ -8361,7 +8484,9 @@ If BACKWARD, the previous article is selected instead of the next."
        (cond 
         ((not gnus-auto-select-next)
          (gnus-message 7 "No more%s articles" (if unread " unread" "")))
-        ((eq gnus-auto-select-next 'quietly)
+        ((or (eq gnus-auto-select-next 'quietly)
+             (and (eq gnus-auto-select-next 'almost-quietly)
+                  (gnus-summary-last-article-p)))
          ;; Select quietly.
          (if (assoc 'quit-config (gnus-find-method-for-group 
                                   gnus-newsgroup-name))
@@ -8387,7 +8512,7 @@ If BACKWARD, the previous article is selected instead of the next."
                         (single-key-description cmd)
                         gnus-newsgroup-name)))
              ;; Confirm auto selection.
-             (let* ((event (read-char)))
+             (let* ((event (read-char-exclusive)))
                (setq key (if (listp event) (car event) event))
                (if (memq key keystrokes)
                    (let ((obuf (current-buffer)))
@@ -9574,12 +9699,12 @@ groups."
   (setq score (gnus-score-default score))
   (let (e)
     (save-excursion
-      (let ((level (gnus-summary-thread-level)))
-       (gnus-summary-raise-score score)
-       (while (and (zerop (gnus-summary-next-subject 1 nil t))
-                   (> (gnus-summary-thread-level) level))
-         (gnus-summary-raise-score score))
-       (setq e (point))))
+      (let ((articles (gnus-summary-articles-in-thread)))
+       (while articles
+         (gnus-summary-goto-subject (car articles))
+         (gnus-summary-raise-score score)
+         (setq articles (cdr articles))))
+      (setq e (point)))
     (let ((gnus-summary-check-current t))
       (or (zerop (gnus-summary-next-subject 1 t))
          (goto-char e))))
@@ -10235,6 +10360,42 @@ read."
 
 ;; Thread-based commands.
 
+(defun gnus-summary-articles-in-thread (&optional article)
+  "Return a list of all articles in the current thread.
+If ARTICLE is non-nil, return all articles in the thread that starts
+with that article."
+  (let* ((article (or article (gnus-summary-article-number)))
+        (data (gnus-data-find-list article))
+        (top-level (gnus-data-level (car data)))
+        (top-subject 
+         (cond ((null gnus-thread-operation-ignore-subject)
+                (gnus-simplify-subject-re
+                 (mail-header-subject (gnus-data-header (car data)))))
+               ((eq gnus-thread-operation-ignore-subject 'fuzzy)
+                (gnus-simplify-subject-fuzzy
+                 (mail-header-subject (gnus-data-header (car data)))))
+               (t nil)))
+        articles)
+    (if (not data)
+       ()                              ; This article doesn't exist.
+      (while data
+       (and (or (not top-subject)
+                (string= top-subject
+                         (if (eq gnus-thread-operation-ignore-subject 'fuzzy)
+                             (gnus-simplify-subject-fuzzy
+                              (mail-header-subject 
+                               (gnus-data-header (car data))))
+                           (gnus-simplify-subject-re
+                            (mail-header-subject 
+                             (gnus-data-header (car data)))))))
+            (setq articles (cons (gnus-data-number (car data)) articles)))
+       (if (and (setq data (cdr data))
+                (> (gnus-data-level (car data)) top-level))
+           ()
+         (setq data nil)))
+      ;; Return the list of articles.
+      (nreverse articles))))
+
 (defun gnus-summary-toggle-threads (&optional arg)
   "Toggle showing conversation threads.
 If ARG is positive number, turn showing conversation threads on."
@@ -10396,23 +10557,20 @@ If the prefix argument is negative, tick articles instead."
   (gnus-set-global-variables)
   (if unmark
       (setq unmark (prefix-numeric-value unmark)))
-  (let ((killing t)
-       (level (gnus-summary-thread-level)))
+  (let ((articles (gnus-summary-articles-in-thread)))
     (save-excursion
       ;; Expand the thread.
       (gnus-summary-show-thread)
-      (while killing
-       ;; Mark the article...
-       (cond ((null unmark) (gnus-summary-mark-article-as-read
-                             gnus-killed-mark))
-             ((> unmark 0) (gnus-summary-mark-article-as-unread 
-                            gnus-unread-mark))
-             (t (gnus-summary-mark-article-as-unread gnus-ticked-mark)))
-       ;; ...and go forward until either the buffer ends or the subtree
-       ;; ends. 
-       (if (not (and (gnus-summary-find-next)
-                     (> (gnus-summary-thread-level) level)))
-           (setq killing nil))))
+      ;; Mark all the articles.
+      (while articles
+       (gnus-summary-goto-subject (car articles))
+       (cond ((null unmark) 
+              (gnus-summary-mark-article-as-read gnus-killed-mark))
+             ((> unmark 0) 
+              (gnus-summary-mark-article-as-unread gnus-unread-mark))
+             (t 
+              (gnus-summary-mark-article-as-unread gnus-ticked-mark)))
+       (setq articles (cdr articles))))
     ;; Hide killed subtrees.
     (and (null unmark)
         gnus-thread-hide-killed
@@ -10546,7 +10704,8 @@ save those articles instead.
 The variable `gnus-default-article-saver' specifies the saver function."
   (interactive "P")
   (gnus-set-global-variables)
-  (let ((articles (gnus-summary-work-articles n)))
+  (let ((articles (gnus-summary-work-articles n))
+       file)
     (while articles
       (let ((header (gnus-summary-article-header (car articles))))
        (if (vectorp header)
@@ -10570,7 +10729,14 @@ The variable `gnus-default-article-saver' specifies the saver function."
                    (widen))))
              (save-window-excursion
                (if gnus-default-article-saver
-                   (funcall gnus-default-article-saver)
+                   (setq file (funcall
+                               gnus-default-article-saver
+                               (cond
+                                ((not gnus-prompt-before-saving)
+                                 'default)
+                                ((eq gnus-prompt-before-saving 'always)
+                                 nil)
+                                (t file))))
                  (error "No default saver is defined."))))
          (if (assq 'name header)
              (gnus-copy-file (cdr (assq 'name header)))
@@ -10624,6 +10790,17 @@ save those articles instead."
   (let ((gnus-default-article-saver 'gnus-summary-save-in-file))
     (gnus-summary-save-article arg)))
 
+(defun gnus-summary-save-article-body-file (&optional arg)
+  "Append the current article body 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")
+  (gnus-set-global-variables)
+  (let ((gnus-default-article-saver 'gnus-summary-save-body-in-file))
+    (gnus-summary-save-article arg)))
+
 (defun gnus-read-save-file-name (prompt default-name)
   (let ((methods gnus-split-methods)
        split-name)
@@ -10672,9 +10849,12 @@ is initialized from the SAVEDIR environment variable."
   (let ((default-name
          (funcall gnus-rmail-save-name gnus-newsgroup-name
                   gnus-current-headers gnus-newsgroup-last-rmail)))
-    (or filename
-       (setq filename (gnus-read-save-file-name 
-                       "Save in rmail file:" default-name)))
+    (setq filename
+         (cond ((eq filename 'default)
+                default-name)
+               (filename filename)
+               (t (gnus-read-save-file-name 
+                   "Save in rmail file:" default-name))))
     (gnus-make-directory (file-name-directory filename))
     (gnus-eval-in-buffer-window 
      gnus-article-buffer
@@ -10695,9 +10875,12 @@ is initialized from the SAVEDIR environment variable."
   (let ((default-name
          (funcall gnus-mail-save-name gnus-newsgroup-name
                   gnus-current-headers gnus-newsgroup-last-mail)))
-    (or filename
-       (setq filename (gnus-read-save-file-name 
-                       "Save in Unix mail file:" default-name)))
+    (setq filename
+         (cond ((eq filename 'default)
+                default-name)
+               (filename filename)
+               (t (gnus-read-save-file-name 
+                   "Save in Unix mail file:" default-name))))
     (setq filename
          (expand-file-name filename
                            (and default-name
@@ -10724,9 +10907,12 @@ is initialized from the SAVEDIR environment variable."
   (let ((default-name
          (funcall gnus-file-save-name gnus-newsgroup-name
                   gnus-current-headers gnus-newsgroup-last-file)))
-    (or filename
-       (setq filename (gnus-read-save-file-name 
-                       "Save in file:" default-name)))
+    (setq filename
+         (cond ((eq filename 'default)
+                default-name)
+               (filename filename)
+               (t (gnus-read-save-file-name 
+                   "Save in file:" default-name))))
     (gnus-make-directory (file-name-directory filename))
     (gnus-eval-in-buffer-window 
      gnus-article-buffer
@@ -10737,20 +10923,53 @@ is initialized from the SAVEDIR environment variable."
     ;; Remember the directory name to save articles.
     (setq gnus-newsgroup-last-file filename)))
 
-(defun gnus-summary-save-in-pipe (&optional command)
-  "Pipe this article to subprocess."
+(defun gnus-summary-save-body-in-file (&optional filename)
+  "Append this article body to a file.
+Optional argument FILENAME specifies file name.
+The directory to save in defaults to `gnus-article-save-directory' which
+is initialized from the SAVEDIR environment variable."
   (interactive)
   (gnus-set-global-variables)
-  (let ((command (read-string "Shell command on article: "
-                             gnus-last-shell-command)))
-    (if (string-equal command "")
-       (setq command gnus-last-shell-command))
+  (let ((default-name
+         (funcall gnus-file-save-name gnus-newsgroup-name
+                  gnus-current-headers gnus-newsgroup-last-file)))
+    (setq filename
+         (cond ((eq filename 'default)
+                default-name)
+               (filename filename)
+               (t (gnus-read-save-file-name 
+                   "Save body in file:" default-name))))
+    (gnus-make-directory (file-name-directory filename))
     (gnus-eval-in-buffer-window 
      gnus-article-buffer
-     (save-restriction
-       (widen)
-       (shell-command-on-region (point-min) (point-max) command nil)))
-    (setq gnus-last-shell-command command)))
+     (save-excursion
+       (save-restriction
+        (widen)
+        (goto-char (point-min))
+        (and (search-forward "\n\n" nil t)
+             (narrow-to-region (point) (point-max)))
+        (gnus-output-to-file filename))))
+    ;; Remember the directory name to save articles.
+    (setq gnus-newsgroup-last-file filename)))
+
+(defun gnus-summary-save-in-pipe (&optional command)
+  "Pipe this article to subprocess."
+  (interactive)
+  (gnus-set-global-variables)
+  (setq command
+       (cond ((eq command 'default)
+              gnus-last-shell-command)
+             (command command)
+             (t (read-string "Shell command on article: "
+                             gnus-last-shell-command))))
+  (if (string-equal command "")
+      (setq command gnus-last-shell-command))
+  (gnus-eval-in-buffer-window 
+   gnus-article-buffer
+   (save-restriction
+     (widen)
+     (shell-command-on-region (point-min) (point-max) command nil)))
+  (setq gnus-last-shell-command command))
 
 ;; Summary extract commands
 
@@ -11012,8 +11231,8 @@ The following commands are available:
            (set-buffer (get-buffer gnus-original-article-buffer))
          (set-buffer (get-buffer-create gnus-original-article-buffer))
          (buffer-disable-undo (current-buffer))
+         (setq major-mode 'gnus-original-article-mode)
          (gnus-add-current-to-buffer-list))
-       (erase-buffer)
 
        (setq group (or group gnus-newsgroup-name))
 
@@ -11056,20 +11275,26 @@ The following commands are available:
                          (setq article 'nneething)
                          (gnus-group-enter-directory dir)))))))))
 
-       ;; Check the cache.
-       (if (and gnus-use-cache
-                (numberp article)
-                (gnus-cache-request-article article group))
-           'article
-         ;; Get the article and into the article buffer.
-         (if (or (stringp article) (numberp article))
-             (progn
-               (erase-buffer)
-               (let ((gnus-override-method 
-                      (and (stringp article) gnus-refer-article-method)))
-                 (and (gnus-request-article article group (current-buffer))
-                      'article)))
-           article)))
+       (cond 
+        ;; We first check `gnus-original-article-buffer'.
+        ((and (equal (car gnus-original-article) group)
+              (eq (cdr gnus-original-article) article))
+         'article)
+        ;; Check the cache.
+        ((and gnus-use-cache
+              (numberp article)
+              (gnus-cache-request-article article group))
+         'article)
+        ;; Get the article from the backend.
+        ((or (stringp article) (numberp article))
+         (erase-buffer)
+         (let ((gnus-override-method 
+                (and (stringp article) gnus-refer-article-method)))
+           (and (gnus-request-article article group (current-buffer))
+                'article)))
+        ;; It was a pseudo.
+        (t article)))
+    (setq gnus-original-article (cons group article))
     (erase-buffer)
     (insert-buffer gnus-original-article-buffer)))
 
@@ -11862,7 +12087,12 @@ If NEWSGROUP is nil, return the global kill file name instead."
 (defvar gnus-dribble-eval-file nil)
 
 (defun gnus-dribble-file-name ()
-  (concat gnus-current-startup-file "-dribble"))
+  (concat 
+   (if gnus-dribble-directory
+       (concat (file-name-as-directory gnus-dribble-directory)
+              (file-name-nondirectory gnus-current-startup-file))
+     gnus-current-startup-file)
+   "-dribble"))
 
 (defun gnus-dribble-enter (string)
   (if (and (not gnus-dribble-ignore)
@@ -12159,6 +12389,10 @@ is returned insted of the status string."
     (funcall (gnus-get-function method 'request-scan) 
             (and group (gnus-group-real-name group)) (nth 1 method))))
 
+(defun gnus-request-update-info (info method)
+  (funcall (gnus-get-function method 'request-update-info) 
+          (gnus-group-real-name (car info)) info (nth 1 method)))
+
 (defun gnus-request-expire-articles (articles group &optional force)
   (let ((method (gnus-find-method-for-group group)))
     (funcall (gnus-get-function method 'request-expire-articles) 
@@ -12189,6 +12423,17 @@ is returned insted of the status string."
     (funcall (gnus-get-function method 'request-create-group) 
             (gnus-group-real-name group) (nth 1 method))))
 
+(defun gnus-request-delete-group (group &optional force)
+  (let ((method (gnus-find-method-for-group group)))
+    (funcall (gnus-get-function method 'request-delete-group) 
+            (gnus-group-real-name group) force (nth 1 method))))
+
+(defun gnus-request-rename-group (group new-name)
+  (let ((method (gnus-find-method-for-group group)))
+    (funcall (gnus-get-function method 'request-rename-group) 
+            (gnus-group-real-name group) 
+            (gnus-group-real-name new-name) (nth 1 method))))
+
 (defun gnus-member-of-valid (symbol group)
   "Find out if GROUP has SYMBOL as part of its \"valid\" spec."
   (memq symbol (assoc
@@ -12196,6 +12441,7 @@ is returned insted of the status string."
                gnus-valid-select-methods)))
 
 (defun gnus-secondary-method-p (method)
+  "Return whether METHOD is a secondary select method."
   (let ((methods gnus-secondary-select-methods)
        (gmethod (gnus-server-get-method nil method)))
     (while (and methods
@@ -12205,6 +12451,7 @@ is returned insted of the status string."
     methods))
 
 (defun gnus-find-method-for-group (group &optional info)
+  "Find the select method that GROUP uses."
   (or gnus-override-method
       (and (not group)
           gnus-select-method)
@@ -12223,15 +12470,17 @@ is returned insted of the status string."
        (gnus-server-add-address method))))
 
 (defun gnus-check-backend-function (func group)
+  "Check whether GROUP supports function FUNC."
   (let ((method (if (stringp group) (car (gnus-find-method-for-group group))
                  group)))
     (fboundp (intern (format "%s-%s" method func)))))
 
-(defun gnus-methods-using (method)
+(defun gnus-methods-using (feature)
+  "Find all methods that have FEATURE."
   (let ((valids gnus-valid-select-methods)
        outs)
     (while valids
-      (if (memq method (car valids)) 
+      (if (memq feature (car valids)) 
          (setq outs (cons (car valids) outs)))
       (setq valids (cdr valids)))
     outs))
@@ -12376,6 +12625,9 @@ The `-n' option line from .newsrc is respected."
    ((and gnus-options-subscribe
         (string-match gnus-options-subscribe group))
     'subscribe)
+   ((and gnus-auto-subscribed-groups 
+        (string-match gnus-auto-subscribed-groups group))
+    'subscribe)
    ((and gnus-options-not-subscribe
         (string-match gnus-options-not-subscribe group))
     'ignore)
@@ -12686,7 +12938,10 @@ newsgroup."
                  gnus-activate-foreign-newsgroups)
                 (t 0))
           level))
-        info group active virtuals method)
+        (update
+         (fboundp (intern (format "%s-request-update-info"
+                                  (car gnus-select-method)))))
+        info group active virtuals method fmethod)
     (gnus-message 5 "Checking new news...")
 
     (while newsrc
@@ -12700,28 +12955,34 @@ newsgroup."
       ;; newsgroup to t. This means that Gnus thinks that there are
       ;; unread articles, but it has no idea how many.
       (if (and (setq method (nth 4 info))
-              (not (gnus-server-equal gnus-select-method
-                                      (gnus-server-get-method nil method)))
+              (not (gnus-server-equal
+                    gnus-select-method
+                    (prog1
+                        (setq fmethod (gnus-server-get-method nil method))
+                      ;; We do this here because it would be awkward
+                      ;; to do it anywhere else.  Hell, it's pretty
+                      ;; awkward here as well, but at least it's
+                      ;; reasonable efficient. 
+                      (and (fboundp (intern (format "%s-request-update-info"
+                                                    (car fmethod))))
+                           (<= (nth 1 info) foreign-level)
+                           (gnus-request-update-info info method)))))
               (not (gnus-secondary-method-p method)))
          ;; These groups are foreign. Check the level.
          (if (<= (nth 1 info) foreign-level)
-             (if (eq (car (if (stringp method) 
-                              (gnus-server-to-method method)
-                            (nth 4 info))) 'nnvirtual)
-                 ;; We have to activate the virtual groups after all
-                 ;; the others, so we just pop them on a list for
-                 ;; now. 
-                 (setq virtuals (cons info virtuals))
-               (and (setq active (gnus-activate-group (car info) 'scan))
-                    ;; Close the groups as we look at them!
-                    (gnus-close-group group))))
+             (setq active (gnus-activate-group (car info) 'scan)))
 
        ;; These groups are native or secondary. 
-       (if (and (not gnus-read-active-file)
-                (<= (nth 1 info) level))
+       (if (<= (nth 1 info) level)
            (progn
-             (or gnus-read-active-file (gnus-check-server method))
-             (setq active (gnus-activate-group (car info) 'scan)))))
+             (if (and update (not method))
+                 (progn
+                   ;; Allow updating of native groups as well, even
+                   ;; though that's pretty unlikely.
+                   (gnus-request-update-info info gnus-select-method)
+                   (setq active (gnus-activate-group (car info) 'scan)))
+               (or gnus-read-active-file
+                   (setq active (gnus-activate-group (car info) 'scan)))))))
       
       (if active
          (gnus-get-unread-articles-in-group info active)
@@ -12732,15 +12993,6 @@ newsgroup."
 
       (setq newsrc (cdr newsrc)))
 
-    ;; Activate the virtual groups. This has to be done after all the
-    ;; other groups. 
-    ;; !!! If one virtual group contains another virtual group, even
-    ;; doing it this way might cause problems.
-    (while virtuals
-      (and (setq active (gnus-activate-group (car (car virtuals)) 'scan))
-          (gnus-get-unread-articles-in-group (car virtuals) active))
-      (setq virtuals (cdr virtuals)))
-
     (gnus-message 5 "Checking new news...done")))
 
 ;; Create a hash table out of the newsrc alist. The `car's of the
@@ -13624,7 +13876,6 @@ If FORCE is non-nil, the .newsrc file is read."
   (and (or gnus-newsrc-alist gnus-killed-list)
        gnus-current-startup-file
        (progn
-        (run-hooks 'gnus-save-newsrc-hook)
         (save-excursion
           (if (and (or gnus-use-dribble-file gnus-slave)
                    (or (not gnus-dribble-buffer)
@@ -13633,6 +13884,7 @@ If FORCE is non-nil, the .newsrc file is read."
                                 (set-buffer gnus-dribble-buffer)
                                 (buffer-size)))))
               (gnus-message 4 "(No changes need to be saved)")
+            (run-hooks 'gnus-save-newsrc-hook)
             (if gnus-slave
                 (gnus-slave-save-newsrc)
               (if gnus-save-newsrc-file
@@ -13651,6 +13903,7 @@ If FORCE is non-nil, the .newsrc file is read."
               (erase-buffer)
               (gnus-message 5 "Saving %s.eld..." gnus-current-startup-file)
               (gnus-gnus-to-quick-newsrc-format)
+              (run-hooks 'gnus-save-quick-newsrc-hook)
               (save-buffer)
               (kill-buffer (current-buffer))
               (gnus-message 
@@ -13729,6 +13982,7 @@ If FORCE is non-nil, the .newsrc file is read."
       (if gnus-modtime-botch
          (delete-file gnus-startup-file)
        (clear-visited-file-modtime))
+      (run-hooks 'gnus-save-standard-newsrc-hook)
       (save-buffer)
       (kill-buffer (current-buffer)))))
 
index 41d6684..d4b5c6b 100644 (file)
@@ -74,7 +74,7 @@
 
 ;;; Interface functions
 
-(defun nnbabyl-retrieve-headers (sequence &optional newsgroup server)
+(defun nnbabyl-retrieve-headers (sequence &optional newsgroup server fetch-old)
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
       (save-buffer)
       t)))
 
+(defun nnbabyl-request-delete-group (group &optional force server)
+  (nnbabyl-possibly-change-newsgroup group)
+  ;; Delete all articles in GROUP.
+  (if (not force)
+      ()                               ; Don't delete the articles.
+    (save-excursion
+      (set-buffer nnbabyl-mbox-buffer)
+      (goto-char (point-min))
+      ;; Delete all articles in this group.
+      (let ((ident (concat "\nX-Gnus-Newsgroup: " nnbabyl-current-group ":"))
+           found)
+       (while (search-forward ident nil t)
+         (setq found t)
+         (nnbabyl-delete-mail))
+       (and found (save-buffer)))))
+  ;; Remove the group from all structures.
+  (setq nnbabyl-group-alist 
+       (delq (assoc group nnbabyl-group-alist) nnbabyl-group-alist)
+       nnbabyl-current-group nil)
+  ;; Save the active file.
+  (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file)
+  t)
+
+(defun nnbabyl-request-rename-group (group new-name &optional server)
+  (nnbabyl-possibly-change-newsgroup group)
+  (save-excursion
+    (set-buffer nnbabyl-mbox-buffer)
+    (goto-char (point-min))
+    (let ((ident (concat "\nX-Gnus-Newsgroup: " nnbabyl-current-group ":"))
+         (new-ident (concat "\nX-Gnus-Newsgroup: " new-name ":"))
+         found)
+      (while (search-forward ident nil t)
+       (replace-match new-ident t t)
+       (setq found t))
+      (and found (save-buffer))))
+  (let ((entry (assoc group nnbabyl-group-alist)))
+    (and entry (setcar entry new-name))
+    (setq nnbabyl-current-group nil)
+    ;; Save the new group alist.
+    (nnmail-save-active nnbabyl-group-alist nnbabyl-active-file)
+    t))
+
 \f
-;;; Low-Level Interface
+;;; 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
index c7fad19..22c3ccc 100644 (file)
@@ -96,7 +96,7 @@ Possible values:
 
 ;;; Interface functions
 
-(defun nndoc-retrieve-headers (sequence &optional newsgroup server)
+(defun nndoc-retrieve-headers (sequence &optional newsgroup server fetch-old)
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
index 5247924..4d2aaad 100644 (file)
@@ -107,7 +107,7 @@ such things as moving mail.  All buffers always get killed upon server close.")
 
 ;;; Interface functions
 
-(defun nnfolder-retrieve-headers (sequence &optional newsgroup server)
+(defun nnfolder-retrieve-headers (sequence &optional newsgroup server fetch-old)
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
@@ -426,6 +426,51 @@ such things as moving mail.  All buffers always get killed upon server close.")
       (and (buffer-modified-p) (save-buffer))
       t)))
 
+(defun nnfolder-request-delete-group (group &optional force server)
+  (nnfolder-possibly-change-group group)
+  ;; Delete all articles in GROUP.
+  (if (not force)
+      ()                               ; Don't delete the articles.
+    ;; Delete the file that holds the group and kill the buffer as
+    ;; well.  
+    (save-excursion
+      (and (set-buffer nnfolder-current-buffer)
+          (progn
+            (and (file-writable-p buffer-file-name)
+                 (delete-file buffer-file-name))
+            (kill-buffer (current-buffer))))))
+  ;; Remove the group from all structures.
+  (setq nnfolder-group-alist 
+       (delq (assoc group nnfolder-group-alist) nnfolder-group-alist)
+       nnfolder-current-group nil
+       nnfolder-current-buffer nil)
+  ;; Save the active file.
+  (nnmail-save-active nnfolder-group-alist nnfolder-active-file)
+  t)
+
+(defun nnfolder-request-rename-group (group new-name &optional server)
+  (nnfolder-possibly-change-group group)
+  (save-excursion
+    (set-buffer nnfolder-current-buffer)
+    (and (file-writable-p buffer-file-name)
+        (condition-case ()
+            (progn
+              (rename-file buffer-file-name
+                           (concat (file-name-as-directory nnfolder-directory)
+                                   new-name))
+              t)
+          (error nil))
+        ;; That went ok, so we change the internal structures.
+        (let ((entry (assoc group nnfolder-group-alist)))
+          (and entry (setcar entry new-name))
+          (setq nnfolder-current-buffer nil
+                nnfolder-current-group nil)
+          ;; Save the new group alist.
+          (nnmail-save-active nnfolder-group-alist nnfolder-active-file)
+          ;; We kill the buffer instead of renaming it and stuff.
+          (kill-buffer (current-buffer))
+          t))))
+
 \f
 ;;; Internal functions.
 
index 7ad97b0..e555e3c 100644 (file)
@@ -76,7 +76,7 @@
 
 ;;; Interface functions
 
-(defun nnmbox-retrieve-headers (sequence &optional newsgroup server)
+(defun nnmbox-retrieve-headers (sequence &optional newsgroup server fetch-old)
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
       (save-buffer)
       t)))
 
+(defun nnmbox-request-delete-group (group &optional force server)
+  (nnmbox-possibly-change-newsgroup group)
+  ;; Delete all articles in GROUP.
+  (if (not force)
+      ()                               ; Don't delete the articles.
+    (save-excursion
+      (set-buffer nnmbox-mbox-buffer)
+      (goto-char (point-min))
+      ;; Delete all articles in this group.
+      (let ((ident (concat "\nX-Gnus-Newsgroup: " nnmbox-current-group ":"))
+           found)
+       (while (search-forward ident nil t)
+         (setq found t)
+         (nnmbox-delete-mail))
+       (and found (save-buffer)))))
+  ;; Remove the group from all structures.
+  (setq nnmbox-group-alist 
+       (delq (assoc group nnmbox-group-alist) nnmbox-group-alist)
+       nnmbox-current-group nil)
+  ;; Save the active file.
+  (nnmail-save-active nnmbox-group-alist nnmbox-active-file)
+  t)
+
+(defun nnmbox-request-rename-group (group new-name &optional server)
+  (nnmbox-possibly-change-newsgroup group)
+  (save-excursion
+    (set-buffer nnmbox-mbox-buffer)
+    (goto-char (point-min))
+    (let ((ident (concat "\nX-Gnus-Newsgroup: " nnmbox-current-group ":"))
+         (new-ident (concat "\nX-Gnus-Newsgroup: " new-name ":"))
+         found)
+      (while (search-forward ident nil t)
+       (replace-match new-ident t t)
+       (setq found t))
+      (and found (save-buffer))))
+  (let ((entry (assoc group nnmbox-group-alist)))
+    (and entry (setcar entry new-name))
+    (setq nnmbox-current-group nil)
+    ;; Save the new group alist.
+    (nnmail-save-active nnmbox-group-alist nnmbox-active-file)
+    t))
+
 \f
 ;;; Internal functions.
 
     (nnmail-insert-lines)
     (nnmail-insert-xref group-art)
     (nnmbox-insert-newsgroup-line group-art)
-    (run-hooks 'nnml-prepare-save-mail-hook)
+    (run-hooks 'nnmbox-prepare-save-mail-hook)
     group-art))
 
 (defun nnmbox-insert-newsgroup-line (group-art)
index 076a054..1ae2ff5 100644 (file)
@@ -73,7 +73,7 @@
 
 ;;; Interface functions.
 
-(defun nnmh-retrieve-headers (sequence &optional newsgroup server)
+(defun nnmh-retrieve-headers (sequence &optional newsgroup server fetch-old)
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
                 (setcdr active (apply 'max articles)))))))
   t)
 
+(defun nnmh-request-delete-group (group &optional force server)
+  (nnmh-possibly-change-directory group)
+  ;; Delete all articles in GROUP.
+  (if (not force)
+      ()                               ; Don't delete the articles.
+    (let ((articles (directory-files nnmh-current-directory t "^[0-9]+$")))
+      (while articles 
+       (and (file-writable-p (car articles))
+            (progn
+              (and gnus-verbose-backends
+                   (message (message "Deleting article %s in %s..."
+                                     (car articles) group)))
+              (funcall nnmail-delete-file-function (car articles))))
+       (setq articles (cdr articles))))
+    ;; Try to delete the directory itself.
+    (condition-case ()
+       (delete-directory nnmh-current-directory)
+      (error nil)))
+  ;; Remove the group from all structures.
+  (setq nnmh-group-alist 
+       (delq (assoc group nnmh-group-alist) nnmh-group-alist)
+       nnmh-current-directory nil)
+  t)
+
+(defun nnmh-request-rename-group (group new-name &optional server)
+  (nnmh-possibly-change-directory group)
+  ;; Rename directory.
+  (and (file-writable-p nnmh-current-directory)
+       (condition-case ()
+          (progn
+            (rename-file 
+             (directory-file-name nnmh-current-directory)
+             (directory-file-name 
+              (nnmail-article-pathname new-name nnmh-directory)))
+            t)
+        (error nil))
+       ;; That went ok, so we change the internal structures.
+       (let ((entry (assoc group nnmh-group-alist)))
+        (and entry (setcar entry new-name))
+        (setq nnmh-current-directory nil)
+        t)))
+
 \f
 ;;; Internal functions.
 
index b4f7ef6..f68f643 100644 (file)
@@ -392,9 +392,59 @@ all. This may very well take some time.")
          (nnml-save-nov)
          t)))))
 
+(defun nnml-request-delete-group (group &optional force server)
+  (nnml-possibly-change-directory group)
+  ;; Delete all articles in GROUP.
+  (if (not force)
+      ()                               ; Don't delete the articles.
+    (let ((articles 
+          (directory-files 
+           nnml-current-directory t
+           (concat "^[0-9]+$\\|" (regexp-quote nnml-nov-file-name) "$"))))
+      (while articles 
+       (and (file-writable-p (car articles))
+            (progn
+              (and gnus-verbose-backends
+                   (message (message "Deleting article %s in %s..."
+                                     (car articles) group)))
+              (funcall nnmail-delete-file-function (car articles))))
+       (setq articles (cdr articles))))
+    ;; Try to delete the directory itself.
+    (condition-case ()
+       (delete-directory nnml-current-directory)
+      (error nil)))
+  ;; Remove the group from all structures.
+  (setq nnml-group-alist 
+       (delq (assoc group nnml-group-alist) nnml-group-alist)
+       nnml-current-group nil
+       nnml-current-directory nil)
+  ;; Save the active file.
+  (nnmail-save-active nnml-group-alist nnml-active-file)
+  t)
+
+(defun nnml-request-rename-group (group new-name &optional server)
+  (nnml-possibly-change-directory group)
+  ;; Rename directory.
+  (and (file-writable-p nnml-current-directory)
+       (condition-case ()
+          (progn
+            (rename-file 
+             (directory-file-name nnml-current-directory)
+             (directory-file-name 
+              (nnmail-article-pathname new-name nnml-directory)))
+            t)
+        (error nil))
+       ;; That went ok, so we change the internal structures.
+       (let ((entry (assoc group nnml-group-alist)))
+        (and entry (setcar entry new-name))
+        (setq nnml-current-directory nil
+              nnml-current-group nil)
+        ;; Save the new group alist.
+        (nnmail-save-active nnml-group-alist nnml-active-file)
+        t)))
 
 \f
-;;; Internal functions
+;;; Internal functions.
 
 ;; Find an article number in the current group given the Message-ID. 
 (defun nnml-find-group-number (id)
index d4ea1d0..bf7dfdc 100644 (file)
@@ -251,8 +251,6 @@ The SOUP packet file name will be inserted at the %s.")
   t)
 
 (defun nnsoup-request-list (&optional server)
-  (or nnsoup-group-alist (nnsoup-read-areas))
-  (nnsoup-unpack-packets)
   (save-excursion
     (set-buffer nntp-server-buffer)
     (erase-buffer)
@@ -268,6 +266,10 @@ The SOUP packet file name will be inserted at the %s.")
        (setq alist (cdr alist)))
       t)))
 
+(defun nnsoup-request-scan (group &optional server)
+  (or nnsoup-group-alist (nnsoup-read-areas))
+  (nnsoup-unpack-packets))
+
 (defun nnsoup-request-newgroups (date &optional server)
   (nnsoup-request-list))
 
index 9872513..6271a36 100644 (file)
@@ -1,3 +1,28 @@
+Mon Sep 25 00:28:32 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.texi (Group Maintenance): Change.
+       (Group Topics): New.
+
+Sun Sep 24 02:48:58 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.texi (New Groups): Addition.
+       (Score Variables): Addition.
+       (Auto Save): Addition.
+       (Saving Articles): Addition.
+       (Saving Articles): Addition.
+       (Saving Articles): Addition.
+       (Summary Buffer Mode Line): Addition.
+       (Fetching a Group): New.
+       (Thread Commands): Addition.
+       (Article Buttons): New.
+       (Article Washing): Addition.
+
+Sat Sep 23 02:53:11 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.texi (Optional Backend Functions): Addition.
+       (Foreign Groups): Addition.
+       (Startup Files): Addition.
+
 Fri Sep 22 14:44:26 1995  Lars Ingebrigtsen  <lars@eyesore.no>
 
        * gnus.texi (Various Various): Addition.
index 7394265..1a92688 100644 (file)
@@ -342,6 +342,8 @@ highlighting (as well as the soon-to-come @sc{soup} support) was written
 by Per Abrahamsen.
 @item
 Innumerable bug fixes were written by Sudish Joseph.
+@item 
+@code{gnus-topic} was written by Ilja Weis.
 @item
 The refcard was written by Vladimir Alexiev.
 @item
@@ -363,9 +365,9 @@ Ricardo Nassif did the proof-reading.
 @item
 Kevin Davidson came up with the name @dfn{ding}, so blame him.
 @item 
-Stainless Steel Rat, Ulrik Dickow, Jack Vinson, Daniel Quinlan, Ilja
-Weis, Frank D. Cringle, Geoffrey T. Dairiki and Andrew Eskilsson have
-all contributed code and suggestions.
+Stainless Steel Rat, Ulrik Dickow, Jack Vinson, Daniel Quinlan, Frank
+D. Cringle, Geoffrey T. Dairiki and Andrew Eskilsson have all
+contributed code and suggestions.
 @end itemize
 
 
@@ -670,6 +672,7 @@ variables.
 * The First Time::      What does Gnus do the first time you start it?
 * The Server is Down::  How can I read my mail then?
 * Slave Gnusii::        You can have more than one Gnus active at a time.
+* Fetching a Group::    Starting Gnus just to read a group.
 * New Groups::          What is Gnus supposed to do with new groups?
 * Startup Files::       Those pesky startup files - @file{.newsrc}.
 * Auto Save::           Recovering from a crash.
@@ -833,6 +836,17 @@ Information from the slave files has, of course, presedence over the
 information in the normal (i. e., master) @code{.newsrc} file.
 
 
+@node Fetching a Group
+@section Fetching a Group
+
+@findex gnus-fetch-group
+It it sometime convenient to be able to just say "I want to read this
+group and I don't care whether Gnus has been started or not".  This is
+perhaps more useful for people who write code than for users, but the
+command @code{gnus-fetch-group} provides this functionality in any
+case.  It takes the group name as a paramenter.
+
+
 @node New Groups
 @section New Groups
 @cindex new groups
@@ -900,6 +914,17 @@ same as the @file{.newsrc} options -n trick.  Both are regexps, and if
 the the new group matches the first, it will be unconditionally
 subscribed, and if it matches the latter, it will be ignored.
 
+@vindex gnus-auto-subscribed-groups
+Yet another variable that meddles here is
+@code{gnus-auto-subscribed-groups}.  It works exactly like
+@code{gnus-options-subscribe}, and is therefore really superfluos, but I
+thought it would be nice to have two of these.  This variable is more
+meant for setting some ground rules, while the other variable is used
+more for user fiddling.  By default this variable makes all new groups
+that come from mail backends (@code{nnml}, @code{nnbabyl},
+@code{nnfolder}, @code{nnmbox}, and @code{nnmh}) subscribed.  If you
+don't like that, just set this variable to @code{nil}.
+
 @vindex gnus-check-new-newsgroups
 If you are satisfied that you really never want to see any new groups,
 you could set @code{gnus-check-new-newsgroups} to @code{nil}.  This will
@@ -968,8 +993,14 @@ 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}
-file.
+@vindex gnus-save-quick-newsrc-hook
+@vindex gnus-save-standard-newsrc-hook
+@code{gnus-save-newsrc-hook} is called before saving any of the newsrc
+files, while @code{gnus-save-quick-newsrc-hook} is called just before
+saving the @file{.newsrc.eld} file, and
+@code{gnus-save-standard-newsrc-hook} is called just before saving the
+@file{.newsrc} file.  The latter two are commonly used to tern version
+control on or off.
 
 @node Auto Save
 @section Auto Save
@@ -991,6 +1022,12 @@ saved.
 If @code{gnus-use-dribble-file} is @code{nil}, Gnus won't create and
 maintain a dribble buffer.
 
+@vindex gnus-dribble-directory
+Gnus will put the dribble file(s) in @code{gnus-dribble-directory}.  If
+this variable is @code{nil}, which it is by default, Gnus will dribble
+into the same directory as the @file{.newsrc} file is located.  (This is
+normally the user's home directory.)
+
 @node The Active File
 @section The Active File
 @cindex active file
@@ -1094,6 +1131,7 @@ long as Gnus is active.
 * Group Maintenance::      Maintaining a tidy @file{.newsrc} file.
 * Browse Foreign Server::  You can browse a server.  See what if has to offer.
 * Exiting Gnus::           Stop reading news and get some work done.
+* Group Topics::           A folding group mode divided into topics.
 * Misc Group Stuff::       Other stuff that you can to do.
 @end menu
 
@@ -1558,6 +1596,14 @@ Make a new group (@code{gnus-group-make-group}).  Gnus will prompt you
 for a name, a method and possibly an @dfn{address}.  For an easier way
 to subscribe to @sc{nntp} groups, @xref{Browse Foreign Server}.
 
+@item G r
+@kindex G m (Group)
+@findex gnus-group-rename-group
+Rename the current group to something else
+(@code{gnus-group-rename-group}).  This is legal only on some groups --
+mail groups mostly.  This command might very well be quite slow on some
+backends. 
+
 @item G e
 @kindex G e (Group)
 @findex gnus-group-edit-group-method
@@ -1618,6 +1664,15 @@ Make a group based on some file or other
 name and a file type.  Currently supported types are @code{babyl},
 @code{mbox} and @code{digest}.
 
+@item G DEL
+@kindex G DEL (Group)
+@findex gnus-group-delete-group
+This function will delete the current group
+(@code{gnus-group-delete-group}).  If given a prefix, this function will
+actuallt delete all the articles in the group, and forcibly remove the
+group itself from the face of the Earth.  Use a prefix only if you are
+sure of what you are doing.  
+
 @item G V
 @kindex G V (Group)
 @findex gnus-group-make-empty-virtual
@@ -2787,23 +2842,44 @@ Find new groups and process them (@code{gnus-find-new-newsgroups}).
 @findex gnus-group-expire-articles
 Run all expirable articles in the current group through the expiry
 process (if any) (@code{gnus-group-expire-articles}).
+
 @item C-c M-C-x
 @kindex C-c M-C-x (Group)
 @findex gnus-group-expire-all-groups
 Run all articles in all groups through the expiry process
 (@code{gnus-group-expire-all-groups}).
+
 @item C-c C-s
 @kindex C-c C-s (Group)
 @findex gnus-group-sort-groups
-@findex gnus-group-sort-by-level
-@findex gnus-group-sort-by-unread
-@findex gnus-group-sort-by-alphabet
 @vindex gnus-group-sort-function
 Sort the groups according to the function given by the
 @code{gnus-group-sort-function} variable
-(@code{gnus-group-sort-groups}).  Available sorting functions include
-@code{gnus-group-sort-by-alphabet} (the default),
-@code{gnus-group-sort-by-unread} and @code{gnus-group-sort-by-level}. 
+(@code{gnus-group-sort-groups}).  Available sorting functions include:
+
+@table 
+
+@item gnus-group-sort-by-level
+@findex gnus-group-sort-by-level
+Sort by group level.
+
+@item gnus-group-sort-by-unread
+@findex gnus-group-sort-by-unread
+Sort by number of unread articles.
+
+@item gnus-group-sort-by-alphabet
+@findex gnus-group-sort-by-alphabet
+Sort the group names alphabetically.  This is the default.
+
+@item gnus-group-sort-by-method
+@findex gnus-group-sort-by-method
+Sort by alphabetically on the select method.
+
+@end table
+
+@code{gnus-group-sort-function} can also be a list of sorting
+functions.  In that case, the most significant sort key function must be
+the last one.
 @end table
 
 @node Browse Foreign Server
@@ -2920,6 +2996,64 @@ behind her drew repeated lines with his pencil across the back of her
 plastic chair.
 @end quotation
 
+
+@node Group Topics
+@section Group Topics
+@cindex topics
+
+If you read lots and lots of groups, it might be convenient to group
+them according to topics.  You put your Emacs groups over here, your sex
+groups over there, and the rest (what, two groups or so?) you put in
+some misc section that you never bother with anyway.
+
+To get this @emph{fab} functionality, you set
+@code{gnus-group-prepare-function} to @code{gnus-group-prepare-topics}.
+Go ahead, just try it.  I'll still be here when you get back.  La de
+dum...  Nice tune, that... la la la...  What, you're back? Yes, and now
+press @kbd{l}.  There.  All your groups are now listed under
+@samp{misc}.  Doesn't that make you feel all warm and fuzzy?  Hot and
+bothered?
+
+@vindex gnus-group-topics
+To get an even more exciting division, you have to fiddle with
+@code{gnus-group-topics}.  That is an alist where each entry looks like
+this: 
+
+@lisp
+(TOPIC REGEXP SHOW)
+@end lisp
+
+As you've already guessed (only geniouses read manuals anyway), all
+groups that match @var{regexp} gets put into a section called
+@var{topic}.  If @var{show} is non-@code{nil}, it overrides
+@code{gnus-group-topic-topics-only}.  In specific, if @var{show} is
+@code{t}, all groups with this topic are always shown, and if it is a
+number, these groups are never shown.
+
+@vindex gnus-group-topic-topics-only
+Whoo, this is complicated.  If @code{gnus-group-topic-topics-only} is
+@code{nil}, all groups and topics will be listed, as you would expect.
+If this variable is non-@code{nil}, only the topics will be listed, and
+the groups will not be listed. This makes the group buffer much shorter,
+I'm sure you'll agree.  This is all modified on a topic-by-topic basis
+by the @var{show} parameter.   It makes perfect sense, really.
+
+@vindex gnus-group-topic-face
+Topics are shown with @code{gnus-group-topic-face}.
+
+Now, if you select a topic, if will fold/unfold that topic, which is
+really neat, I think.
+
+Here's an example @code{gnus-group-topics}:
+
+@lisp
+(("Emacs - the Spice of Life" "^gnu.emacs\\|comp.emacs" t)
+ ("Alternativeness" "^alt" 0)
+ ("Hard Stuff" "^comp" nil)
+ ("The Rest" "." nil))
+@end lisp
+
+
 @node Misc Group Stuff
 @section Misc Group Stuff
 
@@ -3214,6 +3348,14 @@ Subject of the current article.
 Used-defined spec.
 @item s
 Name of the current score file.
+@item d
+Number of dormant articles.
+@item t
+Number of ticked articles.
+@item r
+Number of articles that have been marked as read in this session. 
+@item E
+Number of articles expunged by the score files.
 @end table
 
 
@@ -3258,7 +3400,9 @@ Gnus will exit summary mode and return to the group buffer.  If this
 variable is neither @code{t} nor @code{nil}, Gnus will select the next
 group, no matter whether it has any unread articles or not.  As a
 special case, if this variable is @code{quietly}, Gnus will select the
-next group without asking for confirmation.  Also @xref{Group Levels}.
+next group without asking for confirmation.  If this variable is
+@code{almost-quietly}, the same will happen only if you are located on
+the last article in the group.  Also @xref{Group Levels}.
 
 If Gnus asks you to press a key to confirm going to the next group, you
 can use the @kbd{C-n} and @kbd{C-p} keys to move around the group
@@ -3891,6 +4035,8 @@ list.  Legal elemetents are:
 @table @code
 @item subject-cmsg 
 Check the subject for commands.
+@item sender
+Insert a new @code{Sender} header if the @code{From} header looks odd. 
 @item multiple-headers 
 Check for the existence of multiple equal headers.
 @item sendsys 
@@ -4661,16 +4807,19 @@ Don't gather loose threads.
 @vindex gnus-thread-hide-subtree
 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
 will be hidden.
+
 @item gnus-thread-ignore-subject
 @vindex gnus-thread-ignore-subject
 Sometimes somebody changes the subject in the middle of a thread.  If
 this variable is non-@code{nil}, the subject change is ignored.  If 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 says how much each sub-thread should be indented.
@@ -4682,6 +4831,7 @@ The default is @samp{4}.
 @cindex thread commands
 
 @table @kbd
+
 @item T k
 @itemx M-C-k
 @kindex T k (Summary)
@@ -4691,6 +4841,7 @@ Mark all articles in the current sub-thread as read
 (@code{gnus-summary-kill-thread}).  If the prefix argument is positive,
 remove all marks instead.  If the prefix argument is negative, tick
 articles instead.
+
 @item T l
 @itemx M-C-l
 @kindex T l (Summary)
@@ -4698,38 +4849,46 @@ articles instead.
 @findex gnus-summary-lower-thread
 Lower the score of the current thread
 (@code{gnus-summary-lower-thread}). 
+
 @item T i
 @kindex T i (Summary)
 @findex gnus-summary-raise-thread
 Increase the score of the current thread
 (@code{gnus-summary-raise-thread}).
+
 @item T #
 @kindex T # (Summary)
 @findex gnus-uu-mark-thread
 Set the process mark on the current thread
 (@code{gnus-uu-mark-thread}).
+
 @item T M-#
 @kindex T M-# (Summary)
 @findex gnus-uu-unmark-thread
 Remove the process mark from the current thread
 (@code{gnus-uu-unmark-thread}).
+
 @item T T
 @kindex T T (Summary)
 @findex gnus-summary-toggle-threads
 Toggle threading (@code{gnus-summary-toggle-threads}).
+
 @item T s
 @kindex T s (Summary)
 @findex 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
 Hide the current (sub)thread (@code{gnus-summary-hide-thread}).
+
 @item T S
 @kindex T S (Summary)
 @findex 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
@@ -4758,6 +4917,20 @@ Descend the thread (@code{gnus-summary-down-thread}).
 Ascend the thread (@code{gnus-summary-up-thread}).
 @end table
 
+@vindex gnus-thread-operation-ignore-subject 
+If you ignore subject while threading, you'll naturally end up with
+threads that have several different subjects in them.  If you then issue
+a command like `T k' (@code{gnus-summary-kill-thread}) you might not
+wish to kill the entire thread, but just those parts of the thread that
+have the same subject as the current article.  If you like this idea,
+you can fiddle with @code{gnus-thread-operation-ignore-subject}.  If is
+is non-@code{nil} (which it is by default), subjects will be ignored
+when doing thread commands.  If this variable is @code{nil}, articles in
+the same thread with different subjects will not be included in the
+operation in question.  If this variable is @code{fuzzy}, only articles
+that have subjects that are fuzzily equal will be included.
+
+
 @node Asynchronous Fetching
 @section Asynchronous Article Fetching
 @cindex asynchronous article fetching
@@ -4862,6 +5035,16 @@ the cache.  You should only ever, ever ever ever, use this command if 1)
 your connection to the @sc{nntp} server is really, really, really slow
 and 2) you have a really, really, really huge disk.  Seriously.
 
+@vindex gnus-uncacheable-groups
+It is likely that you do not want caching on some groups.  For instance,
+if your @code{nnml} mail is located under your home directory, it makes no
+sense to cache it somewhere else under your home directory.  Unless you
+feel that it's neat to use twice as much space.  To limit the caching,
+you could set the @code{gnus-uncacheable-groups} regexp to
+@samp{"^nnml"}, for instance.  This variable is @samp{"^nnvirtual"} by
+default, since caching doesn't really work in @code{nnvirtual} groups,
+since @code{nnvirtual} assigns random article numbers to its articles.
+
 
 @node Exiting the Summary Buffer
 @section Exiting the Summary Buffer
@@ -5018,6 +5201,7 @@ If @code{gnus-save-all-headers} is non-@code{nil}, Gnus will not delete
 unwanted headers before saving the article.
 
 @table @kbd
+
 @item O o
 @itemx o
 @kindex O o (Summary)
@@ -5025,26 +5209,37 @@ unwanted headers before saving the article.
 @findex gnus-summary-save-article
 Save the current article using the default article saver
 (@code{gnus-summary-save-article}). 
+
 @item O m
 @kindex O m (Summary)
 @findex gnus-summary-save-article-mail
 Save the current article in mail format
 (@code{gnus-summary-save-article-mail}). 
+
 @item O r
 @kindex O r (Summary)
 @findex gnus-summary-save-article-mail
 Save the current article in rmail format
 (@code{gnus-summary-save-article-rmail}). 
+
 @item O f
 @kindex O f (Summary)
 @findex gnus-summary-save-article-file
 Save the current article in plain file format
 (@code{gnus-summary-save-article-file}). 
+
+@item O b
+@kindex O b (Summary)
+@findex gnus-summary-save-article-body-file
+Save the current article body in plain file format
+(@code{gnus-summary-save-article-body-file}). 
+
 @item O h
 @kindex O h (Summary)
 @findex gnus-summary-save-article-folder
 Save the current article in mh folder format
 (@code{gnus-summary-save-article-folder}). 
+
 @item O p
 @kindex O p (Summary)
 @findex gnus-summary-pipe-output
@@ -5052,8 +5247,20 @@ 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
 
+@vindex gnus-prompt-before-saving
 All these commands use the process/prefix convention
-(@pxref{Process/Prefix}).
+(@pxref{Process/Prefix}).  If you save bunches of articles using these
+functions, you might get tired of being prompted for files to save each
+and every article in.  The prompting action is controlled by
+the @code{gnus-prompt-before-saving} variable, which is @code{always} by
+default, giving you that excessive prompting action you know and
+loathe.  If you set this variable to @code{t} instead, you'll be promted
+just once for each series of articles you save.  If you like to really
+have Gnus do all your thinking for you, you can even set this variable
+to @code{nil}, which means that you will never be prompted for files to
+save articles in.  Gnus will simply save all the articles in the default
+files. 
+
 
 @vindex gnus-default-article-saver
 You can customize the @code{gnus-default-article-saver} variable to make
@@ -5061,27 +5268,38 @@ Gnus do what you want it to.  You can use any of the four ready-made
 functions below, or you can create your own.
 
 @table @code
+
 @item gnus-summary-save-in-rmail
-@vindex gnus-summary-save-in-rmail
+@findex gnus-summary-save-in-rmail
 This is the default format, @dfn{babyl}.  Uses the function in the
 @code{gnus-rmail-save-name} variable to get a file name to save the
 article in.  The default is @code{gnus-plain-save-name}.
+
 @item gnus-summary-save-in-mail
-@vindex gnus-summary-save-in-mail
+@findex gnus-summary-save-in-mail
 Save in a Unix mail (mbox) file.  Uses the function in the
 @code{gnus-mail-save-name} variable to get a file name to save the
 article in.  The default is @code{gnus-plain-save-name}.
+
 @item gnus-summary-save-in-file
-@vindex gnus-summary-save-in-file
+@findex gnus-summary-save-in-file
 Append the article straight to an ordinary file.  Uses the function in
 the @code{gnus-file-save-name} variable to get a file name to save the
 article in.  The default is @code{gnus-numeric-save-name}.
+
+@item gnus-summary-save-body-in-file
+@findex gnus-summary-save-body-in-file
+Append the article body to an ordinary file.  Uses the function in the
+@code{gnus-file-save-name} variable to get a file name to save the
+article in.  The default is @code{gnus-numeric-save-name}.
+
 @item gnus-summary-save-in-folder
-@vindex gnus-summary-save-in-folder
+@findex gnus-summary-save-in-folder
 Save the article to an MH folder using @code{rcvstore} from the MH
 library.
+
 @item gnus-summary-save-in-vm
-@vindex gnus-summary-save-in-vm
+@findex gnus-summary-save-in-vm
 Save the article in a VM folder.  You have to have the VM mail
 reader to use this setting.
 @end table
@@ -5471,6 +5689,7 @@ these articles easier.
 * Article Highlighting::    You want to make the article look like fruit salad.
 * Article Hiding::          You also want to make certain info go away.
 * Article Washing::         Lots of way-neat functions to make life better.
+* Article Buttons::         Clcik on URLs, Message-IDs, addresses and the like.
 * Article Date::            Grumble, UT!
 @end menu
 
@@ -5694,8 +5913,96 @@ If it is a function, this function will be called with the face as the
 argument. If the @code{gnus-article-x-face-too-ugly} (which is a regexp)
 matches the @code{From} header, the face will not be shown.
 
+@item W b
+@kindex W b (Summary)
+@findex gnus-article-add-buttons
+Add clickable buttons to the article (@code{gnus-article-add-buttons}). 
+
+@item W B
+@kindex W B (Summary)
+@findex gnus-article-add-buttons-to-head
+Add clickable buttons to the article headers
+(@code{gnus-article-add-buttons-to-head}).  
+
+@end table
+
+
+@node Article Buttons
+@subsection Article Buttons
+@cindex buttons
+
+People often include references to other stuff in articles, and it would
+be nice if Gnus could just fetch whatever it is that people talk about
+with the minimum of fuzz.
+
+Gnus adds @dfn{buttons} to certain standard references by default:
+Well-formed URLs, mail addresses and Message-IDs.  This is controlled by
+two variables, one that handles article bodies and one that handles
+article heads:
+
+@table @code
+
+@item gnus-button-alist
+@vindex gnus-header-button-alist
+This is an alist where each entry has this form:
+
+@lisp
+(REGEXP BUTTON-PAR USE-P FUNCTION DATA-PAR)
+@end lisp
+
+@table @var
+
+@item regexp
+All text that match this regular expression will be considered an
+external reference.  Here's a typical regexp that match embedded URLs:
+@samp{"<URL:\\([^\n\r>]*\\)>"}. 
+
+@item button-par
+Gnus has to know which parts of the match is to be highlighted.  This is
+a number that says what sub-expression of the regexp that is to be
+highlighted.  If you want it all highlighted, you use @samp{0} here.
+
+@item use-p
+This form will be @code{eval}ed, and if the result is non-@code{nil},
+this is considered a match.  This is useful if you want extra sifting to
+avoid false matches.
+
+@item function
+This function will be called when you click on this button.
+
+@item data-par
+As with @var{button-par}, this is a sub-expression number, but this one
+says which part of the match is to be sent as data to @var{function}. 
+
 @end table
 
+So the full entry for buttonizing URLs is then
+
+@lisp
+("<URL:\\([^\n\r>]*\\)>" 0 t gnus-button-url 1)
+@end lisp
+
+@item gnus-header-button-alist
+@vindex gnus-header-button-alist
+This is just like the other alist, except that it is applied to the
+article head only, and that each entry has an additional element that is
+used to say what headers to apply the buttonize coding to:
+
+@lisp
+(HEADER REGEXP BUTTON-PAR USE-P FUNCTION DATA-PAR)
+@end lisp
+
+@var{header} is a regular expression.
+
+@end table
+
+@vindex gnus-article-button-face
+@vindex gnus-article-mouse-face
+Buttons are highlighted with @code{gnus-article-button-face}, while
+@code{gnus-article-mouse-face} is used when the mouse cursor is over the
+button.
+
+
 @node Article Date
 @subsection Article Date
 
@@ -6128,20 +6435,30 @@ treatment of the article before it is displayed.  By default it contains
 Other useful functions you might add to this hook is:
 
 @table @code
+
 @item gnus-article-hide-citation
 Hide all cited text.
+
 @item gnus-article-hide-signature
 Umn, hides the signature.
+
 @item gnus-article-treat-overstrike
 Treat @samp{^H_} in a reasonable manner.
+
 @item gnus-article-maybe-highlight
-Do fancy article highlighting.
+Do some fancy article highlighting.
+
+@item gnus-article-highlight
+Do lots of article highlighting.
+
 @item gnus-article-remove-cr
 Removes trailing carriage returns.
+
 @item gnus-article-de-quoted-unreadable
 Do naive decoding of articles encoded with Quoted-Printable.
+
 @item gnus-article-display-x-face
-Displays any X-Face headers.
+Displays any @code{X-Face} headers.
 @end table
 
 You can, of course, write your own functions.  The functions are called
@@ -6610,6 +6927,7 @@ all the time.  This command will flush the cache
 @vindex gnus-use-scoring
 If @code{nil}, Gnus will not check for score files, and will not, in
 general, do any score-related work.
+
 @item gnus-kill-killed
 @vindex gnus-kill-killed
 If this variable is @code{nil}, Gnus will never apply score files to
@@ -6618,14 +6936,29 @@ may save you lots of time, it also means that if you apply a kill file
 to a group, and then change the kill file and want to run it over you
 group again to kill more articles, it won't work.  You have to set this
 variable to @code{t} to do that.
+
 @item gnus-kill-files-directory
 @vindex gnus-kill-files-directory
 All kill and score files will be stored in this directory, which is
 initialized from the @samp{SAVEDIR} environment variable by default.
+
 @item gnus-score-file-suffix
 @vindex gnus-score-file-suffix
 Suffix to add to the group name to arrive at the score file name
 (@samp{SCORE} by default.)
+
+@item gnus-score-uncacheable-files
+@vindex gnus-score-uncacheable-files
+@cindex score cache
+All score files are normally cached to avoid excessive re-loading of
+score files.  However, if this might make you Emacs grow big and
+bloated, so this regexp can be used to weed out score files that are
+unlikely to be needed again.  It would be a bad idea to deny caching of
+@file{all.SCORE}, while it might be a good idea to not cache
+@file{comp.infosystems.www.authoring.misc.ADAPT}.  In fact, this
+variable is @samp{"ADAPT$"} by default, so no adaptive score files will
+be cached.
+
 @item gnus-score-interactive-default-score
 @vindex gnus-score-interactive-default-score
 Score used by all the interactive raise/lower commands to raise/lower
@@ -6633,17 +6966,21 @@ score with.  Default is 1000, which may seem excessive, but this is to
 ensure that the adaptive scoring scheme gets enough room to play with.
 We don't want the small changes from the adaptive scoring to overwrite
 manually entered data.
+
 @item gnus-summary-default-score
 @vindex gnus-summary-default-score
 Default score of an article, which is 0 by default.
+
 @item gnus-score-over-mark
 @vindex gnus-score-over-mark
 Mark (in the third column) used for articles with a score over the
 default.  Default is @samp{+}.
+
 @item gnus-score-below-mark
 @vindex gnus-score-below-mark
 Mark (in the third column) used for articles with a score below the
 default.  Default is @samp{-}.
+
 @item gnus-score-find-score-files-function
 @vindex gnus-score-find-score-files-function
 Function used to find score files for the current group.  This function
@@ -7929,7 +8266,7 @@ non-@code{nil}, this is not a followup, but a totally new article.
 the subject of the message.  @var{article-buffer} is the buffer being
 followed up, if that is the case.  @var{info} is the group info.
 @var{follow-to} is the group that one is supposed to re-direct the
-article to.  If @var{respect-poster} is non-@code{nil}, the special
+article ot.  If @var{respect-poster} is non-@code{nil}, the special
 @samp{"poster"} value of a @code{Followup-To} header is to be respected.
 
 There should be no result data returned.
@@ -8082,6 +8419,24 @@ This function should remove @var{article} (which is a number) from
 
 There should be no data returned.
 
+
+@item (nnchoke-request-delete-group GROUP FORCE &optional SERVER)
+
+This function should delete @var{group}.  If @var{force}, it should
+really delete all the articles in the group, and then delete the group
+itself.  (If there is such a thing as "the group itself".)
+
+There should be no data returned.
+
+
+@item (nnchoke-request-rename-group GROUP NEW-NAME &optional SERVER)
+
+This function should rename @var{group} into @var{new-name}.  All
+articles that are in @var{group} should move to @var{new-name}.
+
+There should be no data returned.
+
+
 @end table