*** empty log message ***
authorLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 02:15:55 +0000 (02:15 +0000)
committerLars Magne Ingebrigtsen <larsi@gnus.org>
Tue, 4 Mar 1997 02:15:55 +0000 (02:15 +0000)
17 files changed:
Makefile
lisp/ChangeLog
lisp/Makefile
lisp/gnus-mh.el
lisp/gnus-msg.el
lisp/gnus-score.el
lisp/gnus-uu.el
lisp/gnus-vis.el
lisp/gnus-vm.el
lisp/gnus.el
lisp/nnbabyl.el
lisp/nnfolder.el
lisp/nnheader.el
lisp/nnmail.el
lisp/nnmbox.el
lisp/nnmh.el
lisp/nnml.el

index 6811b9d..336fb88 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,16 @@
-EMACS=emacs
+.PHONY: lisp texi elc info
+
+all: elc texi
+
+lisp:
+       cd lisp; $(MAKE) all
+
+texi:
+       cd texi; $(MAKE) all
 
-all: elc info
 
 elc:
-       cd lisp; $(MAKE) EMACS=$(EMACS) elc
+       cd lisp; $(MAKE) elc
 
 info:
-       cd texi; makeinfo -o gnus gnus.texi
-
+       cd lisp; $(MAKE) info
index cc1f983..7d8ca65 100644 (file)
@@ -1,5 +1,90 @@
+Wed May 24 02:35:49 1995  Lars Magne Ingebrigtsen  <larsi@gymir.ifi.uio.no>
+
+       * nnfolder.el (nnfolder-close-group): New version. Don't close if
+       already closed.
+
+       * gnus-msg.el (gnus-inews-news): Wouldn't restore winconf.
+
+       * gnus.el (gnus-summary-delete-article): Would make all expirable
+       articles disappear.
+
+       * gnus-msg.el (gnus-summary-cancel-article): Don't mark as
+       cancelled before it actually is cancelled.
+       (gnus-mail-reply-using-mail): Did not narrow to headers. 
+       (gnus-group-mail): Use the mail-other-window method.
+
+       * gnus.el (gnus-signature-separator): Moved to gnus.el.
+       (gnus-debug): Ignore nils in load-path.
+       (gnus-score-score-files): Did not find adapt files when using
+       short file names. 
+       (gnus-score-score-files): Changing from short to long file names
+       would bug out.
+       (gnus-get-newsgroup-headers): Would bug out on empty articles.
+
+       * nnheader.el (nnheader-insert-head): Would stop before getting
+       the entire head.
+
+       * gnus-msg.el (gnus-mail-reply-using-mail): Would unmark process
+       marks in the wrong buffer.
+       (gnus-post-news): Ditto.
+       (gnus-inews-do-fcc): Would make a directory out of the file name. 
+
+Tue May 23 07:24:52 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.el (gnus-group-real-name): Get the word after the last
+       colon, not after the first colon.
+
+       * nnmail.el (nnmail-split-incoming): When "splitting" for just a
+       single group, narrow the split method to just the single group. 
+
+       * gnus-uu.el (gnus-uu-unpack-files): Expunge generated files on
+       group exit.
+
+       * gnus-score.el (gnus-score-load-file): Added the `local' atom.
+
+       * gnus.el (gnus-group-make-empty-virtual): New function and
+       keystroke. 
+       (gnus-dummy-mark): New variable.
+       (gnus-summary-remove-lines-marked-with): Remove dummy roots that
+       have no children.
+       (gnus-articles-to-read): Allow the user to specify how many
+       articles to read with a numerical prefix.
+       (gnus-browse-read-group): New command and keystroke.
+       (gnus-summary-insert-line): Go back to using normal plists for
+       article info. Changes all over in the summary code.
+       (gnus-summary-first-subject): New implementation.
+
+Tue May 23 02:54:05 1995  Lars Magne Ingebrigtsen  <larsi@bera.ifi.uio.no>
+
+       * nnmail.el (nnmail-move-inbox): tofile fix.
+
+       * gnus-msg.el (gnus-group-mail): Moved here.
+       (gnus-group-mail): Run gnus-mail-hook.
+
+       * gnus.el (gnus-article-prepare): Let buffer-read-only to nil.
+
+       * nnfolder.el (nnfolder-possibly-activate-groups): Don't use
+       gnus-group-real-name. 
+
+       * gnus.el (gnus-active-to-gnus-format): Add more error control.
+
+       * gnus-score.el (gnus-summary-increase-score): Would bug out on
+       certain keystrokes.
+
+       * gnus.el (gnus-group-sort-groups): Would rescan.
+       (gnus-group-sort-groups): Added keystroke.
+       (gnus-article-setup-buffer): Always set article mode.
+       (gnus-group-add-to-virtual): Prompt with nnvirtual:.
+
+Sun May 21 07:33:20 1995  Lars Ingebrigtsen  <lars@eyesore.no>
+
+       * gnus.el (gnus-offer-save-summaries): Save any still-existing
+       summary buffer on exit from Gnus.
+
 Sun May 21 00:11:00 1995  Lars Magne Ingebrigtsen  <larsi@hymir.ifi.uio.no>
 
+       * gnus.el: 0.75 is released.
+
        * gnus-cache.el (gnus-cache-retrieve-headers): Don't bug out on
        changed source groups. 
 
index ff0a0ff..a2898c5 100644 (file)
-EMACS=emacs
+include ../Makefile.conf
 
-#This is Jack's additions to reduce amount of stuff compiled
-#do "make X Y.." where X Y... are the gnus packages being used.
-#i.e.  "make nntp" will make gnus for nntp access only.
-# virtual - adds stuff for virtual groups
-# nnmbox - adds back end for mbox mail groups
-# nnml - adds back end for nnml mail groups
-# nnmh - adds back end for nnmh mail groups
-# nnspool - adds back ends for local news spool
-# mh - adds functions for using MH interface for mail and mail output
+.SUFFIXES:     .el .elc
+.el.elc:;       $(ELC) $<
 
-syntax:
-       @echo "" ;\
-       echo "*** make one or more of: nntp virtual nnmbox nnml nnmh nnspool mh all gnus" ;\
-       echo "" ;\
-       exit 1
+# virtual      adds stuff for virtual groups
+# nnmbox       adds back end for mbox mail groups
+# nnml         adds back end for nnml mail groups
+# nnmh         adds back end for nnmh mail groups
+# nnspool      adds back ends for local news spool
+# mh           adds functions for using MH interface for mail and mail output
+
+SUBSETS                =gnus nntp virtual nnmbox nnml nnmh nnspool mh
 
-nnheader.elc: nnheader.el
-       $(EMACS) -batch -f batch-byte-compile $(@:.elc=.el)
-gnus.elc: gnus.el
-       $(EMACS) -batch -l ./nnheader.elc -f batch-byte-compile $(@:.elc=.el)
-gnus-visual.elc: gnus-visual.el
-       $(EMACS) -batch -f batch-byte-compile $(@:.elc=.el)
-gnus-uu.elc: gnus-uu.el
-       $(EMACS) -batch -l ./nnheader.elc -l ./gnus-visual.elc -l ./gnus.elc -f batch-byte-compile $(@:.elc=.el)
-nntp.elc: nntp.el
-       $(EMACS) -batch -l ./nnheader.elc -f batch-byte-compile $(@:.elc=.el)
-nnvirtual.elc: nnvirtual.el
-       $(EMACS) -batch -l ./nnheader.elc -l ./gnus-visual.elc -l ./gnus.elc -l ./nntp.elc -f batch-byte-compile $(@:.elc=.el)
-nnmbox.elc: nnmbox.el
-       $(EMACS) -batch -l ./nnheader.elc -l ./nnmail.elc -f batch-byte-compile $(@:.elc=.el)
-nnml.elc: nnml.el
-       $(EMACS) -batch -l ./nnheader.elc -l ./nnmail.elc -l ./nnheader.elc -f batch-byte-compile $(@:.elc=.el)
-nnmh.elc: nnmh.el
-       $(EMACS) -batch -l ./nnheader.elc -l ./gnus-visual.elc -l ./nnmail.elc -l ./gnus.elc -f batch-byte-compile $(@:.elc=.el)
-nnspool.elc: nnspool.el
-       $(EMACS) -batch -l ./nnheader.elc -l ./nntp.elc -f batch-byte-compile $(@:.elc=.el)
-gnus-mh.elc: gnus-mh.el
-       $(EMACS) -batch -l ./nnheader.elc -l ./gnus.elc -f batch-byte-compile $(@:.elc=.el)
-nnmail.elc: nnmail.el
-       $(EMACS) -batch -l ./nnheader.elc -f batch-byte-compile $(@:.elc=.el)
-mhspool.elc: mhspool.el
-       $(EMACS) -batch -l ./nnheader.elc -l ./nntp.elc -f batch-byte-compile $(@:.elc=.el)
+DGNUS.el       =gnus-cache.el gnus-cite.el gnus-ems.el \
+               gnus-kill.el gnus-mh.el gnus-msg.el gnus-score.el gnus-uu.el \
+               gnus-vis.el gnus-vm.el gnus.el nnbabyl.el nndigest.el nndir.el \
+               nndoc.el nnfolder.el nnheader.el nnkiboze.el nnmail.el nnmbox.el \
+               nnmh.el nnml.el nnspool.el nntp.el nnvirtual.el
 
+DGNUS.elc      =$(DGNUS.el:.el=.elc)
 
-gnus:   nnheader.elc gnus.elc gnus-visual.elc gnus-uu.elc
-nntp:  gnus nntp.elc 
-virtual: nntp nnvirtual.elc
-nnmbox: gnus nnmail.elc  nnmbox.elc
-nnml:  gnus nnmail.elc nnml.elc
-nnmh:  gnus nnmail.elc nnmh.elc mhspool.elc 
-nnspool: nntp nnspool.elc
-mh:    gnus gnus-mh.elc
-all:   nntp virtual nnmbox nnml nnmh nnspool mh
+.PHONY:                syntax all elc $(SUBSETS)
 
-# This is what Lars wrote
-# all: elc info
+syntax:
+       @echo "make one or more of: all elc $(SUBSETS)"
+       @exit 1
 
-elc:
-       $(EMACS) -batch -l ./dgnushack.el -f batch-byte-compile *.el
+all:           $(DGNUS.elc)
 
-info:
-       cd ../texi; makeinfo gnus.texi
+elc:           $(DGNUS.el)
+        $(ELC) $(DGNUS.el)
 
+install::      $(DGNUS.elc) $(DESTELC)
+       $(INSTALL) $(INSTDFLAGS) $(DGNUS.elc) $(DESTELC)
 
+install::      $(DGNUS.el) $(DESTEL)
+       case "$(DESTEL)" in \
+       ?*) $(INSTALL) $(INSTDFLAGS) $(DGNUS.el) $(DESTEL);; \
+       esac
 
+$(DESTEL):;    $(MKDIRS) $? && chmod $(MODEDIR) $?
+$(DESTELC):;   $(MKDIRS) $? && chmod $(MODEDIR) $?
 
+gnus:          nnheader.elc gnus.elc gnus-vis.elc gnus-uu.elc
+mh:            gnus gnus-mh.elc
+nnmbox:                gnus nnmail.elc  nnmbox.elc
+nnmh:          gnus nnmail.elc nnmh.elc
+nnml:          gnus nnmail.elc nnml.elc
+nntp:          gnus nntp.elc 
+nnspool:       nntp nnspool.elc
+virtual:       nntp nnvirtual.elc
 
+gnus-cache.elc:        gnus.el
+gnus-cite.elc: gnus-msg.el
+gnus-cite.elc: gnus.el
+gnus-kill.elc: gnus.el
+gnus-mh.elc:   gnus-msg.el
+gnus-mh.elc:   gnus.el
+gnus-msg.elc:  gnus.el
+gnus-score.elc:        gnus.el
+gnus-uu.elc:   gnus-msg.el
+gnus-uu.elc:   gnus.el
+#gnus-vis.elc: gnus-easymenu.el
+gnus-vis.elc:  gnus.el
+gnus-vm.elc:   gnus-msg.el
+gnus-vm.elc:   gnus.el
+gnus.elc:      gnus-ems.el
+gnus.elc:      nnheader.el
+gnus.elc:      nnmh.el
+gnus.elc:      nnspool.el
+gnus.elc:      nntp.el
+nnbabyl.elc:   nnheader.el
+nnbabyl.elc:   nnmail.el
+nndigest.elc:  nnheader.el
+nndir.elc:     nnheader.el
+nndir.elc:     nnmh.el
+nndir.elc:     nnml.el
+nndoc.elc:     nnheader.el
+nndoc.elc:     nnmail.el
+nnfolder.elc:  gnus.el
+nnfolder.elc:  nnheader.el
+nnfolder.elc:  nnmail.el
+nnkiboze.elc:  gnus-score.el
+nnkiboze.elc:  gnus.el
+nnkiboze.elc:  nnheader.el
+nnkiboze.elc:  nntp.el
+nnmail.elc:    nnheader.el
+nnmbox.elc:    nnheader.el
+nnmbox.elc:    nnmail.el
+nnmh.elc:      gnus.el
+nnmh.elc:      nnheader.el
+nnmh.elc:      nnmail.el
+nnml.elc:      nnheader.el
+nnml.elc:      nnmail.el
+nnspool.elc:   nnheader.el
+nnspool.elc:   nntp.el
+nntp.elc:      nnheader.el
+nnvirtual.elc: gnus.el
+nnvirtual.elc: nnheader.el
+nnvirtual.elc: nntp.el
index 8de37b2..9f2ab55 100644 (file)
 (require 'gnus)
 (require 'gnus-msg)
 
+(defun gnus-summary-save-article-folder (arg)
+  "Append the current article to an mh folder.
+If N is a positive number, save the N next articles.
+If N is a negative number, save the N previous articles.
+If N is nil and any articles have been marked with the process mark,
+save those articles instead."
+  (interactive "P")
+  (let ((gnus-default-article-saver 'gnus-summary-save-in-folder))
+    (gnus-summary-save-article arg)))
+
 (defun gnus-summary-save-in-folder (&optional folder)
   "Save this article to MH folder (using `rcvstore' in MH library).
 Optional argument FOLDER specifies folder name."
index a719f43..3422c1c 100644 (file)
@@ -136,9 +136,6 @@ string itself is inserted.
 If the function returns nil, the `gnus-signature-file' variable will
 be used instead.")
 
-(defvar gnus-signature-separator "^-- *$"
-  "Regexp matching signature separator.")
-
 (defvar gnus-required-headers
   '(From Date Newsgroups Subject Message-ID Organization Lines X-Newsreader)
   "*Headers to be generated or prompted for when posting an article.
@@ -243,6 +240,13 @@ headers.")
 
 ;;; Post news commands of Gnus group mode and summary mode
 
+(defun gnus-group-mail ()
+  "Start composing a mail."
+  (interactive)
+  (funcall gnus-mail-other-window-method)
+  (gnus-configure-windows 'group-mail)
+  (run-hooks 'gnus-mail-hook))
+
 (defun gnus-group-post-news ()
   "Post an article."
   (interactive)
@@ -288,6 +292,7 @@ If prefix argument YANK is non-nil, original article is yanked automatically."
 (defun gnus-summary-followup-and-reply (yank &optional yank-articles)
   "Compose a followup and do an auto mail to author."
   (interactive "P")
+  (gnus-set-global-variables)
   (let ((gnus-auto-mail-to-author t))
     (gnus-summary-followup yank yank-articles)))
 
@@ -303,9 +308,9 @@ If prefix argument YANK is non-nil, original article is yanked automatically."
   (let ((articles (gnus-summary-work-articles n)))
     (while articles
       (gnus-summary-select-article t nil nil (car articles))
+      (gnus-eval-in-buffer-window gnus-article-buffer (gnus-cancel-news))
       (gnus-summary-remove-process-mark (car articles))
       (gnus-summary-mark-as-read (car articles) gnus-canceled-mark)
-      (gnus-eval-in-buffer-window gnus-article-buffer (gnus-cancel-news))
       (gnus-article-hide-headers-if-wanted)
       (setq articles (cdr articles)))))
 
@@ -344,10 +349,10 @@ header line with the old Message-ID."
 
 \f
 ;;;###autoload
-(fset 'sendnews 'gnus-post-news)
+(defalias 'sendnews 'gnus-post-news)
 
 ;;;###autoload
-(fset 'postnews 'gnus-post-news)
+(defalias 'postnews 'gnus-post-news)
 
 (defun gnus-copy-article-buffer (&optional article-buffer)
   ;; make a copy of the article buffer with all text properties removed
@@ -475,6 +480,7 @@ Type \\[describe-mode] in the buffer to get a list of commands."
                    (news-reply-yank-original nil)
                  (while yank
                    (save-window-excursion
+                     (set-buffer gnus-summary-buffer)
                      (gnus-summary-select-article nil nil nil (car yank))
                      (gnus-summary-remove-process-mark (car yank)))
                    (let ((mail-reply-buffer gnus-article-copy))
@@ -656,9 +662,10 @@ will attempt to use the foreign server to post the article."
     ;; If NNTP server is opened by gnus-inews-news, close it by myself.
     (or server-running
        (gnus-close-server (gnus-find-method-for-group gnus-newsgroup-name)))
-    (bury-buffer)
-    ;; Restore last window configuration.
-    (and gnus-prev-winconf (set-window-configuration gnus-prev-winconf))))
+    (let ((conf gnus-prev-winconf))
+      (bury-buffer)
+      ;; Restore last window configuration.
+      (and conf (set-window-configuration conf)))))
 
 (defun gnus-inews-check-post ()
   "Check whether the post looks ok."
@@ -1089,7 +1096,7 @@ a program specified by the rest of the value."
                (t
                 ;; Suggested by hyoko@flab.fujitsu.junet.
                 ;; Save article in Unix mail format by default.
-                (gnus-make-directory fcc-file)
+                (gnus-make-directory (file-name-directory fcc-file))
                 (if (and gnus-author-copy-saver
                          (not (eq gnus-author-copy-saver 'rmail-output)))
                     (funcall gnus-author-copy-saver fcc-file)
@@ -1286,6 +1293,7 @@ Customize the variable gnus-mail-reply-method to use another mailer."
   "Forward the current message to another user.
 Customize the variable gnus-mail-forward-method to use another mailer."
   (interactive "P")
+  (gnus-set-global-variables)
   (gnus-summary-select-article t)
   (gnus-copy-article-buffer)
   (let ((gnus-newsgroup-name gnus-newsgroup-name))
@@ -1304,6 +1312,7 @@ Customize the variable gnus-mail-forward-method to use another mailer."
 Customize the variable `gnus-mail-other-window-method' to use another
 mailer."
   (interactive)
+  (gnus-set-global-variables)
   (let ((gnus-newsgroup-name gnus-newsgroup-name))
     (funcall gnus-mail-other-window-method)))
 
@@ -1332,32 +1341,31 @@ mailer."
        (erase-buffer)
        (save-excursion
          (gnus-copy-article-buffer)
-         (set-buffer gnus-article-copy)
-         (if (and (boundp 'gnus-reply-to-function)
-                  gnus-reply-to-function)
-             (save-excursion
-               (save-restriction
-                 (gnus-narrow-to-headers)
-                 (setq follow-to (funcall gnus-reply-to-function group)))))
-         (setq from (mail-fetch-field "from"))
-         (setq date (or (mail-fetch-field "date") 
-                        (header-date gnus-current-headers)))
-         (and from
-              (let ((stop-pos 
-                     (string-match "  *at \\|  *@ \\| *(\\| *<" from)))
-                (setq message-of
-                      (concat (if stop-pos (substring from 0 stop-pos) from)
-                              "'s message of " date))))
-         (setq sender (mail-fetch-field "sender"))
-         (setq subject (or (mail-fetch-field "subject")
-                           "Re: none"))
-         (or (string-match "^[Rr][Ee]:" subject)
-             (setq subject (concat "Re: " subject)))
-         (setq cc (mail-fetch-field "cc"))
-         (setq reply-to (mail-fetch-field "reply-to"))
-         (setq references (mail-fetch-field "references"))
-         (setq message-id (mail-fetch-field "message-id")))
-       (setq news-reply-yank-from (or from "(nobody)"))
+         (save-restriction
+           (set-buffer gnus-article-copy)
+           (gnus-narrow-to-headers)
+           (if (and (boundp 'gnus-reply-to-function)
+                    gnus-reply-to-function)
+               (setq follow-to (funcall gnus-reply-to-function group)))
+           (setq from (mail-fetch-field "from"))
+           (setq date (or (mail-fetch-field "date") 
+                          (header-date gnus-current-headers)))
+           (and from
+                (let ((stop-pos 
+                       (string-match "  *at \\|  *@ \\| *(\\| *<" from)))
+                  (setq message-of
+                        (concat (if stop-pos (substring from 0 stop-pos) from)
+                                "'s message of " date))))
+           (setq sender (mail-fetch-field "sender"))
+           (setq subject (or (mail-fetch-field "subject")
+                             "Re: none"))
+           (or (string-match "^[Rr][Ee]:" subject)
+               (setq subject (concat "Re: " subject)))
+           (setq cc (mail-fetch-field "cc"))
+           (setq reply-to (mail-fetch-field "reply-to"))
+           (setq references (mail-fetch-field "references"))
+           (setq message-id (mail-fetch-field "message-id")))
+         (setq news-reply-yank-from (or from "(nobody)")))
        (setq news-reply-yank-message-id
              (or message-id "(unknown Message-ID)"))
 
@@ -1408,6 +1416,7 @@ mailer."
                  (run-hooks 'news-reply-header-hook))
              (while yank
                (save-window-excursion
+                 (set-buffer gnus-summary-buffer)
                  (gnus-summary-select-article nil nil nil (car yank))
                  (gnus-summary-remove-process-mark (car yank)))
                (save-excursion
@@ -1484,7 +1493,8 @@ mailer."
     (re-search-forward "^To: " nil t)
     (gnus-configure-windows 'mail-forward)
     ;; You have a chance to arrange the message.
-    (run-hooks 'gnus-mail-forward-hook)))
+    (run-hooks 'gnus-mail-forward-hook)
+    (run-hooks 'gnus-mail-hook)))
 
 (defun gnus-forward-using-post (&optional buffer)
   (let* ((forward-buffer (or buffer (current-buffer))) 
@@ -1502,7 +1512,8 @@ mailer."
     (use-local-map (copy-keymap (current-local-map)))
     (local-set-key "\C-c\C-c" 'gnus-mail-send-and-exit)
     (make-local-variable 'gnus-prev-winconf)
-    (setq gnus-prev-winconf winconf)))
+    (setq gnus-prev-winconf winconf)
+    (run-hooks 'gnus-mail-hook)))
 
 (defun gnus-article-mail (yank)
   "Send a reply to the address near point.
index 588dc63..9355ecb 100644 (file)
 
 (require 'gnus)
 
-(defvar gnus-score-find-score-files-function 'gnus-score-find-bnews
-  "*Function used to find SCORE files.
-The function will be called with the group name as the argument, and
-should return a list of score files to apply to that group.  The score
-files do not actually have to exist.
-
-Predefined values are:
-
-gnus-score-find-single: Only apply the group's own SCORE file.
-gnus-score-find-hierarchical: Also apply SCORE files from parent groups.
-gnus-score-find-bnews: Apply SCORE files whose names matches.
-
-See the documentation to these functions for more information.
-
-This variable can also be a list of functions to be called.  Each
-function should either return a list of score files, or a list of
-score alists.")
-
-(defvar gnus-adaptive-file-suffix "ADAPT"
-  "*Suffix of the adaptive score files.")
-
 (defvar gnus-score-expiry-days 7
   "*Number of days before unused score file entries are expired.")
 
@@ -83,8 +62,6 @@ always be used.")
 
 ;; Internal variables.
 
-(defvar gnus-internal-global-score-files nil)
-(defvar gnus-score-file-list nil)
 (defvar gnus-adaptive-score-alist gnus-default-adaptive-score-alist)
 
 (defvar gnus-score-trace nil)
@@ -157,10 +134,10 @@ of the last succesful match.")
            (?d "date")
            (?f "followup")))
         (char-to-type
-         '((?e e) (?f f) (?s nil) (?r r) (?b before)
+         '((?e e) (?f f) (?s s) (?r r) (?b before)
            (?a at) (?n now) (?< <) (?> >) (?= =)))
         (char-to-perm
-         (list (list ?t (current-time-string)) '(?p nil) '(?i now)))
+         (list (list ?t (current-time-string)) '(?p perm) '(?i now)))
         (mimic gnus-score-mimic-keymap)
         hchar entry temporary tchar pchar end type)
     ;; First we read the header to score.
@@ -224,8 +201,10 @@ of the last succesful match.")
        (nth 1 entry)                   ; Header
        (gnus-summary-header (or (nth 2 entry) (nth 1 entry))) ; Match
        type                            ; Type
-       score                           ; Score
-       temporary                        ; Temp
+       (if (eq 's score) nil score)     ; Score
+       (if (eq 'perm temporary)         ; Temp
+           nil
+         temporary)
        (not (nth 3 entry)))            ; Prompt
       )))
 
@@ -495,6 +474,7 @@ SCORE is the score to add."
          (exclude-files (gnus-score-get 'exclude-files alist))
           (orphan (car (gnus-score-get 'orphan alist)))
          (adapt (gnus-score-get 'adapt alist))
+         (local (gnus-score-get 'local alist))
          (eval (car (gnus-score-get 'eval alist))))
       ;; We do not respect eval and files atoms from global score
       ;; files. 
@@ -505,6 +485,17 @@ SCORE is the score to add."
                                      files))))
       (and eval (not global) (eval eval))
       (setq gnus-scores-exclude-files exclude-files)
+      (if (not local)
+         ()
+       (save-excursion
+         (set-buffer gnus-summary-buffer)
+         (while local
+           (and (consp (car local))
+                (symbolp (car (car local)))
+                (progn
+                  (make-local-variable (car (car local)))
+                  (set (car (car local)) (nth 1 (car local)))))
+           (setq local (cdr local)))))
       (if orphan (setq gnus-orphan-score orphan))
       (setq gnus-adaptive-score-alist
            (cond ((equal adapt '(t))
@@ -1454,203 +1445,6 @@ This mode is an extended emacs-lisp mode.
     (gnus-score-load-file bufnam)
     (and winconf (set-window-configuration winconf))))
 
-;;; Finding score files. 
-
-(defvar gnus-global-score-files nil
-  "*List of global score files and directories.
-Set this variable if you want to use people's score files.  One entry
-for each score file or each score file directory.  Gnus will decide
-by itself what score files are applicable to which group.
-
-Say you want to use the single score file
-\"/ftp.ifi.uio.no@ftp:/pub/larsi/ding/score/soc.motss.SCORE\" and all
-score files in the \"/ftp.some-where:/pub/score\" directory.
-
- (setq gnus-global-score-files
-       '(\"/ftp.ifi.uio.no:/pub/larsi/ding/score/soc.motss.SCORE\"
-         \"/ftp.some-where:/pub/score\"))")
-
-(defun gnus-score-score-files (group)
-  "Return a list of all possible score files."
-  ;; Search and set any global score files.
-  (and gnus-global-score-files 
-       (or gnus-internal-global-score-files
-          (gnus-score-search-global-directories gnus-global-score-files)))
-  ;; Fix the kill-file dir variable.
-  (setq gnus-kill-files-directory 
-       (file-name-as-directory
-        (or gnus-kill-files-directory "~/News/")))
-  ;; If er can't read it, there's no score files.
-  (if (not (file-readable-p (expand-file-name gnus-kill-files-directory)))
-      (setq gnus-score-file-list nil)
-    (if (gnus-use-long-file-name 'not-score)
-       ;; We want long file names.
-       (if (or (not gnus-score-file-list)
-               (gnus-file-newer-than gnus-kill-files-directory
-                                     (car gnus-score-file-list)))
-             (setq gnus-score-file-list 
-                   (cons (nth 5 (file-attributes gnus-kill-files-directory))
-                         (nreverse 
-                          (directory-files 
-                           gnus-kill-files-directory t 
-                           (gnus-score-file-regexp))))))
-      ;; We do not use long file names, so we have to do some
-      ;; directory traversing.  
-      (let ((dir (expand-file-name
-                 (concat gnus-kill-files-directory
-                         (gnus-replace-chars-in-string group ?. ?/))))
-           (mdir (length (expand-file-name gnus-kill-files-directory)))
-           (suffixes (list gnus-score-file-suffix gnus-adaptive-file-suffix))
-           files suffix)
-       (while suffixes
-         (setq suffix (car suffixes)
-               suffixes (cdr suffixes))
-         (if (file-exists-p (concat dir "/" suffix))
-             (setq files (list (concat dir "/" suffix))))
-         (while (>= (1+ (length dir)) mdir)
-           (and (file-exists-p (concat dir "/all/" suffix))
-                (setq files (cons (concat dir "/all/" suffix) files)))
-           (string-match "/[^/]*$" dir)
-           (setq dir (substring dir 0 (match-beginning 0)))))
-       (setq gnus-score-file-list 
-             (cons nil (nreverse files)))))
-    (cdr gnus-score-file-list)))
-
-(defun gnus-score-file-regexp ()
-  (concat "\\(" gnus-score-file-suffix 
-         "\\|" gnus-adaptive-file-suffix "\\)$"))
-       
-(defun gnus-score-find-bnews (group)
-  "Return a list of score files for GROUP.
-The score files are those files in the ~/News directory which matches
-GROUP using BNews sys file syntax."
-  (let* ((sfiles (append (gnus-score-score-files group)
-                        gnus-internal-global-score-files))
-        (kill-dir (file-name-as-directory 
-                   (expand-file-name gnus-kill-files-directory)))
-        (klen (length kill-dir))
-        ofiles not-match regexp)
-    (save-excursion
-      (set-buffer (get-buffer-create "*gnus score files*"))
-      (buffer-disable-undo (current-buffer))
-      ;; Go through all score file names and create regexp with them
-      ;; as the source.  
-      (while sfiles
-       (erase-buffer)
-       (insert (car sfiles))
-       (goto-char (point-min))
-       ;; First remove the suffix itself.
-       (re-search-forward (concat "." (gnus-score-file-regexp)))
-       (replace-match "" t t) 
-       (goto-char (point-min))
-       (if (looking-at (regexp-quote kill-dir))
-           ;; If the file name was just "SCORE", `klen' is one character
-           ;; too much.
-           (delete-char (min (1- (point-max)) klen))
-         (goto-char (point-max))
-         (search-backward "/")
-         (delete-region (1+ (point)) (point-min)))
-       ;; Translate "all" to ".*".
-       (while (search-forward "all" nil t)
-         (replace-match ".*" t t))
-       (goto-char (point-min))
-       ;; Deal with "not."s.
-       (if (looking-at "not.")
-           (progn
-             (setq not-match t)
-             (setq regexp (buffer-substring 5 (point-max))))
-         (setq regexp (buffer-substring 1 (point-max)))
-         (setq not-match nil))
-       ;; Finally - if this resulting regexp matches the group name,
-       ;; we add this score file to the list of score files
-       ;; applicable to this group.
-       (if (or (and not-match
-                    (not (string-match regexp group)))
-               (and (not not-match)
-                    (string-match regexp group)))
-           (setq ofiles (cons (car sfiles) ofiles)))
-       (setq sfiles (cdr sfiles)))
-      (kill-buffer (current-buffer))
-      ;; Slight kludge here - the last score file returned should be
-      ;; the local score file, whether it exists or not. This is so
-      ;; that any score commands the user enters will go to the right
-      ;; file, and not end up in some global score file.
-      (let ((localscore
-            (expand-file-name
-             (if (gnus-use-long-file-name 'not-score)
-                 (concat gnus-kill-files-directory group "." 
-                         gnus-score-file-suffix)
-               (concat gnus-kill-files-directory
-                       (gnus-replace-chars-in-string group ?. ?/)
-                       "/" gnus-score-file-suffix)))))
-       (and (member localscore ofiles)
-            (delete localscore ofiles))
-       (setq ofiles (cons localscore ofiles)))
-      (nreverse ofiles))))
-
-(defun gnus-score-find-single (group)
-  "Return list containing the score file for GROUP."
-  (list (gnus-score-file-name group)))
-
-(defun gnus-score-find-hierarchical (group)
-  "Return list of score files for GROUP.
-This includes the score file for the group and all its parents."
-  (let ((all (copy-sequence '(nil)))
-       (start 0))
-    (while (string-match "\\." group (1+ start))
-      (setq start (match-beginning 0))
-      (setq all (cons (substring group 0 start) all)))
-    (setq all (cons group all))
-    (mapcar 'gnus-score-file-name (nreverse all))))
-
-(defun gnus-possibly-score-headers (&optional trace)
-  (let ((func gnus-score-find-score-files-function)
-       score-files scores)
-    (and func (not (listp func))
-        (setq func (list func)))
-    ;; Go through all the functions for finding score files (or actual
-    ;; scores) and add them to a list.
-    (while func
-      (and (symbolp (car func))
-          (fboundp (car func))
-          (setq score-files 
-                (nconc score-files (funcall (car func) gnus-newsgroup-name))))
-      (setq func (cdr func)))
-    (if score-files (gnus-score-headers score-files trace))))
-
-(defun gnus-score-file-name (newsgroup &optional suffix)
-  "Return the name of a score file for NEWSGROUP."
-  (let ((suffix (or suffix gnus-score-file-suffix)))
-    (cond  ((or (null newsgroup)
-               (string-equal newsgroup ""))
-           ;; The global score file is placed at top of the directory.
-           (expand-file-name 
-            suffix (or gnus-kill-files-directory "~/News")))
-          ((gnus-use-long-file-name 'not-score)
-           ;; Append ".SCORE" to newsgroup name.
-           (expand-file-name (concat newsgroup "." suffix)
-                             (or gnus-kill-files-directory "~/News")))
-          (t
-           ;; Place "SCORE" under the hierarchical directory.
-           (expand-file-name (concat (gnus-newsgroup-directory-form newsgroup)
-                                     "/" suffix)
-                             (or gnus-kill-files-directory "~/News"))))))
-
-(defun gnus-score-search-global-directories (files)
-  "Scan all global score directories for score files."
-  ;; Set the variable `gnus-internal-global-score-files' to all
-  ;; available global score files.
-  (interactive (list gnus-global-score-files))
-  (let (out)
-    (while files
-      (if (string-match "/$" (car files))
-         (setq out (nconc (directory-files 
-                           (car files) t
-                           (concat (gnus-score-file-regexp) "$"))))
-       (setq out (cons (car files) out)))
-      (setq files (cdr files)))
-    (setq gnus-internal-global-score-files out)))
-
 (defun gnus-score-find-trace ()
   "Find all score rules applied to this article."
   (interactive)
index f2660fd..a67e132 100644 (file)
@@ -1357,6 +1357,7 @@ The headers will be included in the sequence they are matched.")
   (let* ((totfiles (gnus-uu-ls-r gnus-uu-work-dir))
         (ofiles files)
         file did-unpack)
+    (gnus-uu-add-file totfiles)
     (while files
       (setq file (cdr (assq 'name (car files))))
       (if (and (not (member file ignore))
@@ -1368,6 +1369,7 @@ The headers will be included in the sequence they are matched.")
                (message "Error during unpacking of %s" file))
            (let* ((newfiles (gnus-uu-ls-r gnus-uu-work-dir))
                   (nfiles newfiles))
+             (gnus-uu-add-file newfiles)
              (while nfiles
                (or (member (car nfiles) totfiles)
                    (setq ofiles (cons (list (cons 'name (car nfiles))
@@ -1541,7 +1543,7 @@ uuencode and adds MIME headers.")
 (defvar gnus-uu-post-include-before-composing nil
   "Non-nil means that gnus-uu will ask for a file to encode before you compose the article.
 If this variable is t, you can either include an encoded file with
-\\<gnus-uu-post-reply-mode-map>\\[gnus-uu-post-insert-binary-in-article] or have one included for you when you post the article.")
+\\[gnus-uu-post-insert-binary-in-article] or have one included for you when you post the article.")
 
 (defvar gnus-uu-post-length 990
   "Maximum length of an article.
@@ -1577,7 +1579,6 @@ is t.")
 
   (use-local-map (copy-keymap (current-local-map)))
   (local-set-key "\C-c\C-c" 'gnus-summary-edit-article-done)
-  (local-set-key "\C-c\C-f\C-a" 'gnus-uu-post-reply-summary)
   (local-set-key "\C-c\C-c" 'gnus-uu-post-news-inews)
   (local-set-key "\C-c\C-s" 'gnus-uu-post-news-inews)
   (local-set-key "\C-c\C-i" 'gnus-uu-post-insert-binary-in-article)
index 99c65c9..3541b77 100644 (file)
@@ -177,7 +177,9 @@ highlight-headers-follow-url-netscape:
       ["Add a directory group" gnus-group-make-directory-group t]
       ["Add the help group" gnus-group-make-help-group t]
       ["Add the archive group" gnus-group-make-archive-group t]
-      ["Make a kiboze group" gnus-group-make-kiboze-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])
      ["Jump to group" gnus-group-jump-to-group t]
      ["Best unread group" gnus-group-best-unread-group t]
      ))
@@ -244,6 +246,7 @@ highlight-headers-follow-url-netscape:
    ""
    '("Browse"
      ["Subscribe" gnus-browse-unsubscribe-current-group t]
+     ["Read" gnus-group-read-group t]
      ["Exit" gnus-browse-exit t]
      )))
 
@@ -478,34 +481,34 @@ highlight-headers-follow-url-netscape:
 ;;;
 
 (defun gnus-highlight-selected-summary ()
-    ;; Added by Per Abrahamsen <amanda@iesd.auc.dk>.
-    ;; Highlight selected article in summary buffer
-    (if gnus-summary-selected-face
-       (save-excursion
-         (let* ((beg (progn (beginning-of-line) (point)))
-                (end (progn (end-of-line) (point)))
-                ;; Fix by Mike Dugan <dugan@bucrf16.bu.edu>.
-                (from (if (get-text-property beg 'mouse-face) 
-                          beg
-                        (1+ (or (next-single-property-change 
-                                 beg 'mouse-face nil end) 
-                                end))))
-                (to (1- (or (next-single-property-change
-                             from 'mouse-face nil end)
-                            end))))
-            ;; If no mouse-face prop on line (e.g. xemacs) we 
-            ;; will have to = from = end, so we highlight the
-            ;; entire line instead.
-           (if (= to from)
-               (progn
-                 (setq from beg)
-                 (setq to end)))
-           (if gnus-newsgroup-selected-overlay
-               (move-overlay gnus-newsgroup-selected-overlay 
-                             from to (current-buffer))
-             (setq gnus-newsgroup-selected-overlay (make-overlay from to))
-             (overlay-put gnus-newsgroup-selected-overlay 'face 
-                          gnus-summary-selected-face))))))
+  ;; Added by Per Abrahamsen <amanda@iesd.auc.dk>.
+  ;; Highlight selected article in summary buffer
+  (if gnus-summary-selected-face
+      (save-excursion
+       (let* ((beg (progn (beginning-of-line) (point)))
+              (end (progn (end-of-line) (point)))
+              ;; Fix by Mike Dugan <dugan@bucrf16.bu.edu>.
+              (from (if (get-text-property beg 'mouse-face) 
+                        beg
+                      (1+ (or (next-single-property-change 
+                               beg 'mouse-face nil end) 
+                              beg))))
+              (to (1- (or (next-single-property-change
+                           from 'mouse-face nil end)
+                          end))))
+         ;; If no mouse-face prop on line (e.g. xemacs) we 
+         ;; will have to = from = end, so we highlight the
+         ;; entire line instead.
+         (if (= to from)
+             (progn
+               (setq from beg)
+               (setq to end)))
+         (if gnus-newsgroup-selected-overlay
+             (move-overlay gnus-newsgroup-selected-overlay 
+                           from to (current-buffer))
+           (setq gnus-newsgroup-selected-overlay (make-overlay from to))
+           (overlay-put gnus-newsgroup-selected-overlay 'face 
+                        gnus-summary-selected-face))))))
 
 
 ;; New implementation by Christian Limpach <Christian.Limpach@nice.ch>.
@@ -516,12 +519,12 @@ highlight-headers-follow-url-netscape:
         (end (progn (end-of-line) (point)))
         ;; now find out where the line starts and leave point there.
         (beg (progn (beginning-of-line) (point)))
-        (score (or (cdr (assq (or (car (get-text-property beg 'gnus))
+        (score (or (cdr (assq (or (get-text-property beg 'gnus-number)
                                   gnus-current-article)
                               gnus-newsgroup-scored))
                    gnus-summary-default-score 0))
         (default gnus-summary-default-score)
-        (mark (car (cdr (get-text-property beg 'gnus))))
+        (mark (get-text-property beg 'gnus-mark))
         (inhibit-read-only t))
     (while (and list (not (eval (car (car list)))))
       (setq list (cdr list)))
@@ -633,7 +636,7 @@ highlight-headers-follow-url-netscape:
   (suppress-keymap gnus-carpal-mode-map)
   (define-key gnus-carpal-mode-map " " 'gnus-carpal-select)
   (define-key gnus-carpal-mode-map "\r" 'gnus-carpal-select)
-  (define-key gnus-carpal-mode-map [mouse-2] 'gnus-carpal-mouse-select))
+  (define-key gnus-carpal-mode-map gnus-mouse-2 'gnus-carpal-mouse-select))
 
 (defun gnus-carpal-mode ()
   "Major mode clicking buttons.
index a50d2ac..842cee9 100644 (file)
@@ -73,6 +73,16 @@ Has to be set before gnus-vm is loaded.")
     (vm-mode)
     tmp-folder))
   
+(defun gnus-summary-save-article-vm (arg)
+  "Append the current article to a vm folder.
+If N is a positive number, save the N next articles.
+If N is a negative number, save the N previous articles.
+If N is nil and any articles have been marked with the process mark,
+save those articles instead."
+  (interactive "P")
+  (let ((gnus-default-article-saver 'gnus-summary-save-in-vm))
+    (gnus-summary-save-article arg)))
+
 (defun gnus-summary-save-in-vm (&optional folder)
   (interactive)
   (let ((default-name
index 3bcac69..c5b6de4 100644 (file)
@@ -111,7 +111,7 @@ see the manual for details.")
   "*Preferred method for posting USENET news.
 If this variable is nil, Gnus will use the current method to decide
 which method to use when posting.  If it is non-nil, it will override
-the current method. This method will not be used in mail groups and
+the current method.  This method will not be used in mail groups and
 the like, only in \"real\" newsgroups.
 
 The value must be a valid method as discussed in the documentation of
@@ -199,6 +199,27 @@ information can be restored from the dribble file.")
 (defvar gnus-score-file-suffix "SCORE"
   "*Suffix of the score files.")
 
+(defvar gnus-adaptive-file-suffix "ADAPT"
+  "*Suffix of the adaptive score files.")
+
+(defvar gnus-score-find-score-files-function 'gnus-score-find-bnews
+  "*Function used to find SCORE files.
+The function will be called with the group name as the argument, and
+should return a list of score files to apply to that group.  The score
+files do not actually have to exist.
+
+Predefined values are:
+
+gnus-score-find-single: Only apply the group's own SCORE file.
+gnus-score-find-hierarchical: Also apply SCORE files from parent groups.
+gnus-score-find-bnews: Apply SCORE files whose names matches.
+
+See the documentation to these functions for more information.
+
+This variable can also be a list of functions to be called.  Each
+function should either return a list of score files, or a list of
+score alists.")
+
 (defvar gnus-score-interactive-default-score 1000
   "*Scoring commands will raise/lower the score with this number as the default.")
 
@@ -556,6 +577,9 @@ this list.")
 (defvar gnus-inhibit-startup-message nil
   "*If non-nil, the startup message will not be displayed.")
 
+(defvar gnus-signature-separator "^-- *$"
+  "Regexp matching signature separator.")
+
 (defvar gnus-auto-extend-newsgroup t
   "*If non-nil, extend newsgroup forward and backward when requested.")
 
@@ -744,6 +768,8 @@ for the groups to be sorted.  Pre-made functions include
   "*There is no thread under the article.")
 (defvar gnus-not-empty-thread-mark ?=
   "*There is a thread under the article.")
+(defvar gnus-dummy-mark ?Z
+  "*This is a dummy article.")
 
 (defvar gnus-view-pseudo-asynchronously nil
   "*If non-nil, Gnus will view pseudo-articles asynchronously.")
@@ -1114,6 +1140,10 @@ automatically when it is selected.")
 (defvar gnus-article-check-size nil)
 
 (defvar gnus-current-score-file nil)
+(defvar gnus-internal-global-score-files nil)
+(defvar gnus-score-file-list nil)
+
+
 (defvar gnus-current-move-group nil)
 
 (defvar gnus-newsgroup-dependencies nil)
@@ -1213,7 +1243,7 @@ variable (string, integer, character, etc).")
 (defconst gnus-maintainer "gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls & Boys)"
   "The mail address of the Gnus maintainer.")
 
-(defconst gnus-version "(ding) Gnus v0.75"
+(defconst gnus-version "(ding) Gnus v0.76"
   "Version number for this version of Gnus.")
 
 (defvar gnus-info-nodes
@@ -1415,8 +1445,8 @@ Please do not delete those.  They will tell the Bug People what your
 environment is, so that it will be easier to locate the bugs.
 
 If you have found a bug that makes Emacs go \"beep\", set
-debug-on-error to t (`M-ESC (setq debug-on-error t)') and include the
-backtrace in your bug report.
+debug-on-error to t (`M-x set-variable RET debug-on-error RET t RET') 
+and include the backtrace in your bug report.
 
 Please describe the bug in annoying, painstaking detail.
 
@@ -1461,6 +1491,7 @@ Thank you for your help in stamping out bugs.
   (autoload 'gnus-mail-forward-using-mhe "gnus-mh")
   (autoload 'gnus-mail-other-window-using-mhe "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")
   (autoload 'gnus-folder-save-name "gnus-mh")
 
@@ -1537,10 +1568,17 @@ Thank you for your help in stamping out bugs.
   (autoload 'gnus-uu-decode-unshar-and-save "gnus-uu" nil t)
   (autoload 'gnus-uu-decode-save "gnus-uu" nil t)
   (autoload 'gnus-uu-decode-binhex "gnus-uu" nil t)
+  (autoload 'gnus-uu-decode-uu-view "gnus-uu" nil t)
+  (autoload 'gnus-uu-decode-uu-and-save-view "gnus-uu" nil t)
+  (autoload 'gnus-uu-decode-unshar-view "gnus-uu" nil t)
+  (autoload 'gnus-uu-decode-unshar-and-save-view "gnus-uu" nil t)
+  (autoload 'gnus-uu-decode-save-view "gnus-uu" nil t)
+  (autoload 'gnus-uu-decode-binhex-view "gnus-uu" nil t)
 
   ;; gnus-msg
   (autoload 'gnus-summary-send-map "gnus-msg" nil nil 'keymap)
   (autoload 'gnus-group-post-news "gnus-msg" nil t)
+  (autoload 'gnus-group-mail "gnus-msg" nil t)
   (autoload 'gnus-summary-post-news "gnus-msg" nil t)
   (autoload 'gnus-summary-followup "gnus-msg" nil t)
   (autoload 'gnus-summary-followup-with-original "gnus-msg" nil t)
@@ -1565,6 +1603,7 @@ Thank you for your help in stamping out bugs.
 
   ;; gnus-vm
   (autoload 'gnus-summary-save-in-vm "gnus-vm" nil t)
+  (autoload 'gnus-summary-save-article-vm "gnus-vm" nil t)
   (autoload 'gnus-mail-forward-using-vm "gnus-vm")
   (autoload 'gnus-mail-reply-using-vm "gnus-vm")
   (autoload 'gnus-mail-other-window-using-vm "gnus-vm" nil t)
@@ -1641,6 +1680,11 @@ Thank you for your help in stamping out bugs.
        (point)
       (goto-char p))))
 
+;; Delete the current line (and the next N lines.);
+(defmacro gnus-delete-line (&optional n)
+  (` (delete-region (progn (beginning-of-line) (point))
+                   (progn (forward-line (, (or n 1))) (point)))))
+
 ;;; Load the compatability functions. 
 
 (require 'gnus-ems)
@@ -2409,9 +2453,11 @@ The source file has to be in the Emacs load path."
        (erase-buffer)
        (setq dirs load-path)
        (while dirs
-         (if (not (file-exists-p 
-                   (setq file (concat (file-name-as-directory 
-                                       (car dirs)) (car files)))))
+         (if (or (not (car dirs))
+                 (not (stringp (car dirs)))
+                 (not (file-exists-p 
+                       (setq file (concat (file-name-as-directory 
+                                           (car dirs)) (car files))))))
              (setq dirs (cdr dirs))
            (setq dirs nil)
            (insert-file-contents file)
@@ -2549,12 +2595,6 @@ If nothing is specified, use the variable gnus-overload-functions."
       (setq i (* 2 i)))
     (1- i)))
 
-;; Delete the current line (and the next N lines.);
-(defun gnus-delete-line (&optional n)
-  (let ((n (or n 1)))
-    (delete-region (progn (beginning-of-line) (point))
-                  (progn (forward-line n) (point)))))
-
 ;; Show message if message has a lower level than `gnus-verbose'. 
 ;; Guide-line for numbers:
 ;; 1 - error messages, 3 - non-serious error messages, 5 - messages
@@ -2867,6 +2907,7 @@ Note: LIST has to be sorted over `<'."
   (define-key gnus-group-mode-map "<" 'beginning-of-buffer)
   (define-key gnus-group-mode-map ">" 'end-of-buffer)
   (define-key gnus-group-mode-map "\C-c\C-b" 'gnus-bug)
+  (define-key gnus-group-mode-map "\C-c\C-s" 'gnus-group-sort-groups)
 
   (define-key gnus-group-mode-map "#" 'gnus-group-mark-group)
   (define-key gnus-group-mode-map "\M-#" 'gnus-group-unmark-group)
@@ -2887,6 +2928,7 @@ Note: LIST has to be sorted over `<'."
   (define-key gnus-group-group-map "e" 'gnus-group-edit-group-method)
   (define-key gnus-group-group-map "p" 'gnus-group-edit-group-parameters)
   (define-key gnus-group-group-map "v" 'gnus-group-add-to-virtual)
+  (define-key gnus-group-group-map "V" 'gnus-group-make-empty-virtual)
 
   (define-prefix-command 'gnus-group-list-map)
   (define-key gnus-group-mode-map "A" 'gnus-group-list-map)
@@ -3145,8 +3187,8 @@ If REGEXP, only list groups matching REGEXP."
 
 (defun gnus-group-real-name (group)
   "Find the real name of a foreign newsgroup."
-  (if (string-match "^[^:]+:" group)
-      (substring group (match-end 0))
+  (if (string-match ":[^:]+$" group)
+      (substring group (1+ (match-beginning 0)))
     group))
 
 (defun gnus-group-prefixed-name (group method)
@@ -3379,7 +3421,8 @@ If VISIBLE-ONLY is non-nil, the group won't be displayed if it isn't already."
                               (point-min) (point-max) 
                               'gnus-group (intern (car (car entry)))))))
                  (setq entry (cdr entry)))
-               (or entry (goto-char (point-max)))))))
+               (if entry (forward-line 1)
+                 (goto-char (point-max)))))))
       (if (or visible (not visible-only))
          (gnus-group-insert-group-line-info group))
       (gnus-group-set-mode-line))))
@@ -3526,8 +3569,6 @@ If UNMARK, remove the mark instead."
         (let ((group (gnus-group-group-name)))
           (and group (list group))))))
 
-
-
 ;; Selecting groups.
 
 (defun gnus-group-read-group (all &optional no-article group)
@@ -3875,7 +3916,8 @@ score file entries for articles to include in the group."
   "Add the current group to a virtual group."
   (interactive
    (list current-prefix-arg
-        (completing-read "Add to virtual group: " gnus-newsrc-hashtb nil t)))
+        (completing-read "Add to virtual group: " gnus-newsrc-hashtb nil t
+                         "nnvirtual:")))
   (or (eq (car (gnus-find-method-for-group vgroup)) 'nnvirtual)
       (error "%s is not an nnvirtual group" vgroup))
   (let* ((groups (gnus-group-process-prefix n))
@@ -3887,7 +3929,22 @@ score file entries for articles to include in the group."
              (lambda (s) 
                (gnus-group-remove-mark s)
                (concat "\\(^" (regexp-quote s) "$\\)"))
-             groups "\\|")))))
+             groups "\\|"))))
+  (gnus-group-position-cursor))
+
+(defun gnus-group-make-empty-virtual (group)
+  "Create a new, fresh, empty virtual group."
+  (interactive "sCreate new, empty virtual group: ")
+  (let* ((method (list 'nnvirtual ""))
+        (pgroup (gnus-group-prefixed-name group method)))
+    ;; Check whether it exists already.
+    (and (gnus-gethash pgroup gnus-newsrc-hashtb)
+        (error "Group %s already exists." pgroup))
+    ;; Subscribe the new group after the group on the current line.
+    (gnus-subscribe-group pgroup (gnus-group-group-name) method)
+    (gnus-group-update-group pgroup)
+    (forward-line -1)
+    (gnus-group-position-cursor)))
 
 ;; Group sorting commands
 ;; Suggested by Joe Hildebrand <hildjj@idaho.fuentez.com>.
@@ -3898,7 +3955,6 @@ score file entries for articles to include in the group."
   (setq gnus-newsrc-alist 
        (sort (cdr gnus-newsrc-alist) gnus-group-sort-function))
   (gnus-make-hashtable-from-newsrc-alist)
-  (gnus-get-unread-articles (1+ gnus-level-subscribed))
   (gnus-group-list-groups nil))
 
 (defun gnus-group-sort-by-alphabet (info1 info2)
@@ -4383,11 +4439,6 @@ If LOWEST, don't list groups with level lower than LOWEST."
   (gnus-check-bogus-newsgroups (not gnus-expert-user)) ;Require confirmation.
   (gnus-group-list-groups nil gnus-have-all-newsgroups))
 
-(defun gnus-group-mail ()
-  "Start composing a mail."
-  (interactive)
-  (mail))
-
 (defun gnus-group-edit-global-kill (article &optional group)
   "Edit the global kill file.
 If GROUP, edit that local kill file instead."
@@ -4475,9 +4526,28 @@ The hook `gnus-exit-gnus-hook' is called before actually exiting."
       (progn
        (run-hooks 'gnus-exit-gnus-hook)
        (gnus-dribble-save)
+       (gnus-offer-save-summaries)
        (gnus-close-backends)
        (gnus-clear-system))))
 
+(defun gnus-offer-save-summaries ()
+  (let ((buffers (buffer-list)))
+    (save-excursion
+      (while buffers
+       (and 
+        ;; We look for buffers with "Summary" in the name.
+        (string-match "Summary" (or (buffer-name (car buffers)) ""))
+        (progn
+          (set-buffer (car buffers))
+          ;; We check that this is, indeed, a summary buffer.
+          (eq 'major-mode 'gnus-summary-mode)) 
+        ;; We ask the user whether she wants to save the info.
+        (not (gnus-y-or-n-p
+              (format "Discard summary buffer %s? " (buffer-name))))
+        ;; We do it by simply exiting.
+        (gnus-summary-exit))
+       (setq buffers (cdr buffers))))))
+
 (defun gnus-group-describe-briefly ()
   "Give a one line description of the group mode commands."
   (interactive)
@@ -4522,7 +4592,7 @@ and the second element is the address."
   (setq gnus-browse-mode-map (make-keymap))
   (suppress-keymap gnus-browse-mode-map)
   (define-key gnus-browse-mode-map " " 'gnus-browse-read-group)
-  (define-key gnus-browse-mode-map "=" 'gnus-browse-read-group)
+  (define-key gnus-browse-mode-map "=" 'gnus-browse-select-group)
   (define-key gnus-browse-mode-map "n" 'gnus-browse-next-group)
   (define-key gnus-browse-mode-map "p" 'gnus-browse-prev-group)
   (define-key gnus-browse-mode-map "\177" 'gnus-browse-prev-group)
@@ -4530,7 +4600,7 @@ and the second element is the address."
   (define-key gnus-browse-mode-map "P" 'gnus-browse-prev-group)
   (define-key gnus-browse-mode-map "\M-n" 'gnus-browse-next-group)
   (define-key gnus-browse-mode-map "\M-p" 'gnus-browse-prev-group)
-  (define-key gnus-browse-mode-map "\r" 'gnus-browse-read-group)
+  (define-key gnus-browse-mode-map "\r" 'gnus-browse-select-group)
   (define-key gnus-browse-mode-map "u" 'gnus-browse-unsubscribe-current-group)
   (define-key gnus-browse-mode-map "l" 'gnus-browse-exit)
   (define-key gnus-browse-mode-map "L" 'gnus-browse-exit)
@@ -4613,10 +4683,32 @@ and the second element is the address."
   (setq buffer-read-only t)
   (run-hooks 'gnus-browse-mode-hook))
 
-(defun gnus-browse-read-group ()
-  "Not implemented, and will probably never be."
+(defun gnus-browse-read-group (&optional no-article)
+  "Enter the group at the current line."
   (interactive)
-  (error "You can't read while browsing"))
+  (let ((group (gnus-browse-group-name))
+       (buf (current-buffer)))
+    (set-buffer gnus-group-buffer)
+    (gnus-sethash 
+     group
+     (list t nil 
+          (list group gnus-level-default-subscribed nil nil 
+                (cons (cons 'quit-config (current-window-configuration)) 
+                      gnus-browse-current-method)))
+     gnus-newsrc-hashtb)
+    (condition-case ()
+       (gnus-group-read-group t no-article group)
+      (error nil)
+      (quit nil))
+    (if (not (equal major-mode 'gnus-group-mode))
+       ()
+      (switch-to-buffer buf)
+      (gnus-configure-windows 'browse)
+      (gnus-message 3 "Article not a digest?"))))
+
+(defun gnus-browse-select-group ()
+  "Select the current group."
+  (gnus-browse-read-group 'no))
 
 (defun gnus-browse-next-group (n)
   "Go to the next group."
@@ -4645,6 +4737,14 @@ and the second element is the address."
     (gnus-group-position-cursor)
     (if (/= 0 arg) (gnus-message 7 "No more newsgroups"))
     arg))
+
+(defun gnus-browse-group-name ()
+  (save-excursion
+    (if (not (re-search-forward ": \\(.*\\)$" (gnus-point-at-eol) t))
+       ()
+      (gnus-group-prefixed-name 
+       (buffer-substring (match-beginning 1) (match-end 1))
+       gnus-browse-current-method))))
   
 (defun gnus-browse-unsubscribe-group ()
   (let ((sub nil)
@@ -4653,10 +4753,7 @@ and the second element is the address."
     (save-excursion
       (beginning-of-line)
       (if (= (following-char) ?K) (setq sub t))
-      (re-search-forward ": \\(.*\\)$" nil t)
-      (setq group (gnus-group-prefixed-name 
-                  (buffer-substring (match-beginning 1) (match-end 1))
-                  gnus-browse-current-method))
+      (setq group (gnus-browse-group-name))
       (beginning-of-line)
       (delete-char 1)
       (if sub
@@ -5129,7 +5226,9 @@ The following commands are available:
     (insert (eval sformat))
     (add-text-properties
      b (1+ b)
-     (list 'gnus (list number ?Z 0)))))
+     (list 'gnus-number number 
+          'gnus-mark gnus-dummy-mark
+          'gnus-level 0))))
 
 (defvar gnus-thread-indent-array nil)
 (defvar gnus-thread-indent-array-level gnus-thread-indent-level)
@@ -5170,7 +5269,9 @@ The following commands are available:
     (or (numberp lines) (setq lines 0))
     (insert (eval sformat))
     (add-text-properties
-     b (1+ b) (list 'gnus (list number (or unread gnus-unread-mark) level)))))
+     b (1+ b) (list 'gnus-number number 
+                   'gnus-mark (or unread gnus-unread-mark)
+                   'gnus-level level))))
 
 (defun gnus-summary-update-line (&optional dont-update)
   ;; Update summary line after change.
@@ -5334,6 +5435,21 @@ If NO-ARTICLE is non-nil, no article is selected initially."
     (goto-char (point-min))
     (run-hooks 'gnus-summary-prepare-hook)))
 
+(defun gnus-subject-equal (s1 s2)
+  (cond 
+   ((numberp gnus-summary-gather-subject-limit)
+    (string= (if (> (length s1) gnus-summary-gather-subject-limit)
+                (substring s1 0 gnus-summary-gather-subject-limit)
+              s1)
+            (if (> (length s2) gnus-summary-gather-subject-limit)
+                (substring s2 0 gnus-summary-gather-subject-limit)
+              s2)))
+   ((eq 'fuzzy gnus-summary-gather-subject-limit)
+    (string= (gnus-simplify-subject-fuzzy s1)
+            (gnus-simplify-subject-fuzzy s2)))
+   (t
+    (string= s1 s2))))
+
 (defun gnus-gather-threads (threads)
   "Gather threads that have lost their roots."
   (if (not gnus-summary-make-false-root)
@@ -5673,7 +5789,7 @@ Unscored articles will be counted as havin a score of zero."
   (> (gnus-thread-total-score h1) (gnus-thread-total-score h2)))
 
 (defun gnus-thread-total-score (thread)
-  ;;  This function find the total score of  THREAD.
+  ;;  This function find the total score of THREAD.
   (if (consp thread)
       (if (stringp (car thread))
          (apply gnus-thread-score-function 0
@@ -5891,7 +6007,7 @@ If READ-ALL is non-nil, all articles in the group are selected."
   (let* ((articles
          ;; Select all articles if `read-all' is non-nil, or if all the
          ;; unread articles are dormant articles.
-         (if (or read-all
+         (if (or (and read-all (not (numberp read-all)))
                  (= (length gnus-newsgroup-unreads) 
                     (length gnus-newsgroup-dormant)))
              (gnus-uncompress-range 
@@ -5903,29 +6019,33 @@ If READ-ALL is non-nil, all articles in the group are selected."
         (marked (+ (length gnus-newsgroup-marked)
                    (length gnus-newsgroup-dormant)))
         (select
-         (condition-case ()
-             (cond ((and (or (<= scored marked)
-                             (= scored number))
-                         (numberp gnus-large-newsgroup)
-                         (> number gnus-large-newsgroup))
-                    (let ((input
-                           (read-string
-                            (format
-                             "How many articles from %s (default %d): "
-                             gnus-newsgroup-name number))))
-                      (if (string-equal input "")
-                          number input)))
-                   ((and (> scored marked) (< scored number))
-                    (let ((input
-                           (read-string
-                            (format 
-                             "%s %s (%d scored, %d total): "
-                             "How many articles from"
-                             group scored number))))
-                      (if (string-equal input "")
-                          number input)))
-                   (t number))
-           (quit nil)))
+         (cond 
+          ((numberp read-all)
+           read-all)
+          (t
+           (condition-case ()
+               (cond ((and (or (<= scored marked)
+                               (= scored number))
+                           (numberp gnus-large-newsgroup)
+                           (> number gnus-large-newsgroup))
+                      (let ((input
+                             (read-string
+                              (format
+                               "How many articles from %s (default %d): "
+                               gnus-newsgroup-name number))))
+                        (if (string-equal input "")
+                            number input)))
+                     ((and (> scored marked) (< scored number))
+                      (let ((input
+                             (read-string
+                              (format 
+                               "%s %s (%d scored, %d total): "
+                               "How many articles from"
+                               group scored number))))
+                        (if (string-equal input "")
+                            number input)))
+                     (t number))
+             (quit nil)))))
         total-articles)
     (setq select (if (stringp select) (string-to-number select) select))
     (if (or (null select) (zerop select))
@@ -6287,8 +6407,9 @@ The resulting hash table is returned, or nil if no Xrefs were found."
          ;; can't have everything, I guess. Speed and elegance
          ;; doesn't always come hand in hand.
          (save-restriction
-           (narrow-to-region (point) (save-excursion 
-                                       (search-forward "\n.\n" nil t)))
+           (narrow-to-region (point) (or (save-excursion 
+                                           (search-forward "\n.\n" nil t))
+                                         (point)))
            (if (search-forward "\nfrom: " nil t)
                (header-set-from header (gnus-header-value))
              (header-set-from header "(nobody)"))
@@ -6633,19 +6754,19 @@ searched for."
        pos)
     (beginning-of-line)
     (and gnus-summary-check-current unread
-        (eq (nth 1 (get-text-property (point) 'gnus)) gnus-unread-mark)
+        (eq (get-text-property (point) 'gnus-mark) gnus-unread-mark)
         (setq did nil))
     (if (not did)
        ()
       (forward-char (if backward (if (bobp) 0 -1) (if (eobp) 0 1)))
       (while
          (and 
-          (setq pos (funcall func (point) 'gnus))
+          (setq pos (funcall func (point) 'gnus-number))
           (goto-char (if backward (1- pos) pos))
           (setq did
                 (not (and
                       (or (not unread)
-                          (eq (nth 1 (get-text-property (point) 'gnus))
+                          (eq (get-text-property (point) 'gnus-mark)
                               gnus-unread-mark))
                       (or (not subject)
                           (equal (gnus-simplify-subject-re subject)
@@ -6656,7 +6777,7 @@ searched for."
     (if did
        (progn (goto-char beg) nil)
       (prog1
-         (car (get-text-property (point) 'gnus))
+         (get-text-property (point) 'gnus-number)
        (gnus-summary-position-cursor)))))
 
 (defun gnus-summary-search-forward (&optional unread subject backward)
@@ -6678,16 +6799,12 @@ the same subject will be searched for."
   "The article number of the article on the current line.
 If there isn's an article number here, then we return the current
 article number."
-  (let* ((p (point))
-        (number (car (get-text-property 
-                      (progn (beginning-of-line) 
-                             (prog1 (point) (goto-char p)))
-                      'gnus))))
+  (let* ((number (get-text-property (gnus-point-at-bol) 'gnus-number)))
     (if number-or-nil number (or number gnus-current-article))))
 
 (defun gnus-summary-thread-level ()
   "The thread level of the article on the current line."
-  (or (nth 2 (get-text-property (gnus-point-at-bol) 'gnus))
+  (or (get-text-property (gnus-point-at-bol) 'gnus-level)
       0))
 
 (defun gnus-summary-pseudo-article ()
@@ -6696,7 +6813,7 @@ article number."
 
 (defun gnus-summary-article-mark ()
   "The mark on the current line."
-  (nth 1 (get-text-property (gnus-point-at-bol) 'gnus)))
+  (get-text-property (gnus-point-at-bol) 'gnus-mark))
 
 (defun gnus-summary-subject-string ()
   "Return current subject string or nil if nothing."
@@ -6922,7 +7039,7 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
   (gnus-set-global-variables)
   (gnus-kill-save-kill-buffer)
   (let* ((group gnus-newsgroup-name)
-        (quit-buffer (cdr (assoc 'quit-buffer (gnus-find-method-for-group
+        (quit-config (cdr (assoc 'quit-config (gnus-find-method-for-group
                                                gnus-newsgroup-name))))
         (mode major-mode)
         (method (car (gnus-find-method-for-group group)))
@@ -6956,18 +7073,18 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
          ()
        (gnus-group-jump-to-group group)
        (gnus-group-next-unread-group 1))
-      (if (gnus-buffer-exists-p quit-buffer)
+      (if (gnus-buffer-exists-p quit-config)
          (progn
-           (switch-to-buffer quit-buffer)
-           (gnus-set-global-variables)
-           (gnus-configure-windows 'summary))))))
+           (set-window-configuration quit-config)
+           (and (eq major-mode 'gnus-summary-mode)
+                (gnus-set-global-variables)))))))
 
 (defalias 'gnus-summary-quit 'gnus-summary-exit-no-update)
 (defun gnus-summary-exit-no-update (&optional no-questions)
   "Quit reading current newsgroup without updating read article info."
   (interactive)
   (let* ((group gnus-newsgroup-name)
-        (quit-buffer (cdr (assoc 'quit-buffer 
+        (quit-config (cdr (assoc 'quit-config 
                                  (gnus-find-method-for-group group)))))
     (if (or no-questions
            gnus-expert-user
@@ -6985,10 +7102,11 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
              (bury-buffer gnus-article-buffer))
          (if (equal (gnus-group-group-name) group)
              (gnus-group-next-unread-group 1))
-         (if (gnus-buffer-exists-p quit-buffer)
+         (if (gnus-buffer-exists-p quit-config)
              (progn
-               (switch-to-buffer quit-buffer)
-               (gnus-configure-windows 'summary)))))))
+               (set-window-configuration quit-config)
+               (and (eq major-mode 'gnus-summary-mode)
+                    (gnus-set-global-variables))))))))
 
 ;; Suggested by Andrew Eskilsson <pi92ae@pt.hk-r.se>.
 (defun gnus-summary-fetch-faq (group)
@@ -7077,21 +7195,16 @@ If prefix argument NO-ARTICLE is non-nil, no article is selected initially."
 If UNREAD is non-nil, go to the first unread article.
 Returns nil if there are no unread articles."
   (interactive "P")
-  (let ((begin (point)))
-    (goto-char (point-min))
-    (if (not unread)
-       t
-      (while (and (not (eq (nth 1 (get-text-property (point) 'gnus))
-                          gnus-unread-mark))
-                 (zerop (forward-line 1))))
-      (prog1
-         (if (not (eobp))
-             t
-           ;; If there is no unread articles, stay where you are.
-           (goto-char begin)
-           (gnus-message 3 "No more unread articles")
-           nil)
-       (gnus-summary-position-cursor)))))
+  (prog1
+      (if (or (not unread)
+             (gnus-goto-char 
+              (text-property-any 
+               (point-min) (point-max) 'gnus-mark gnus-unread-mark)))
+         t 
+       ;; If there are no unread articles.
+       (gnus-message 3 "No more unread articles")
+       nil)
+    (gnus-summary-position-cursor)))
 
 (defun gnus-summary-next-subject (n &optional unread dont-display)
   "Go to next N'th summary line.
@@ -7143,12 +7256,11 @@ If optional argument UNREAD is non-nil, only unread article is selected."
                      nil 'require-match))))
   (or article (error "No article number"))
   (let ((b (point)))
-    (goto-char (point-min))
-    (while (and (not (eq (car (get-text-property (point) 'gnus)) article))
-               (zerop (forward-line 1))))
+    (gnus-goto-char (text-property-any (point-min) (point-max)
+                                      'gnus-number article))
     (gnus-summary-show-thread)
     ;; Skip dummy articles. 
-    (if (eq (gnus-summary-article-mark) ?Z)
+    (if (eq (gnus-summary-article-mark) gnus-dummy-mark)
        (forward-line 1))
     (prog1
        (if (not (eobp))
@@ -7172,7 +7284,7 @@ If optional argument UNREAD is non-nil, only unread article is selected."
       nil
     (gnus-article-prepare article all-header)
     (gnus-summary-show-thread)
-    (if (eq (gnus-summary-article-mark) ?Z)
+    (if (eq (gnus-summary-article-mark) gnus-dummy-mark)
        (progn
          (forward-line 1)
          (gnus-summary-position-cursor)))
@@ -7560,7 +7672,8 @@ NOTE: This command only works with newsgroup that use NNTP."
      name 
      (list t nil (list name gnus-level-default-subscribed nil nil 
                       (list 'nndigest gnus-article-buffer
-                            (cons 'quit-buffer buf))))
+                            (cons 'quit-config 
+                                  (current-window-configuration)))))
      gnus-newsrc-hashtb)
     (condition-case ()
        (gnus-group-read-group t nil name)
@@ -7686,7 +7799,7 @@ article. If BACKWARD (the prefix) is non-nil, search backward instead."
                    (` (lambda ()
                         (call-interactively '(, (key-binding command)))))
                    backward)
-      (gnus-message 6 "Executing %s... done" (key-description command)))))
+      (gnus-message 6 "Executing %s...done" (key-description command)))))
 
 (defun gnus-summary-beginning-of-article ()
   "Scroll the article back to the beginning."
@@ -8030,7 +8143,8 @@ delete these instead."
                                   gnus-newsgroup-name)
       (error "The current newsgroup does not support article deletion."))
   ;; Compute the list of articles to delete.
-  (let ((articles (gnus-summary-work-articles n)))
+  (let ((articles (gnus-summary-work-articles n))
+       not-deleted)
     (if (and gnus-novice-user
             (not (gnus-y-or-n-p 
                   (format "Do you really want to delete %s forever? "
@@ -8038,17 +8152,17 @@ delete these instead."
                             "this article")))))
        ()
       ;; Delete the articles.
-      (setq gnus-newsgroup-expirable 
-           (gnus-request-expire-articles 
-            articles gnus-newsgroup-name 'force))
+      (setq not-deleted (gnus-request-expire-articles 
+                        articles gnus-newsgroup-name 'force))
       (while articles
        (gnus-summary-remove-process-mark (car articles))       
        ;; The backend might not have been able to delete the article
        ;; after all.  
-       (or (memq (car articles) gnus-newsgroup-expirable)
+       (or (memq (car articles) not-deleted)
            (gnus-summary-mark-as-read (car articles) gnus-canceled-mark))
-       (setq articles (cdr articles)))))
-  (gnus-summary-position-cursor))
+       (setq articles (cdr articles))))
+    (gnus-summary-position-cursor)
+    not-deleted))
 
 (defun gnus-summary-edit-article ()
   "Enter into a buffer and edit the current article.
@@ -8111,7 +8225,7 @@ This will have permanent effect only in mail groups."
   ;; Skip dummy header line.
   (save-excursion
     (gnus-summary-show-thread)
-    (if (eq (gnus-summary-article-mark) ?Z)
+    (if (eq (gnus-summary-article-mark) gnus-dummy-mark)
        (forward-line 1))
     (let ((buffer-read-only nil))
       ;; Set score.
@@ -8358,7 +8472,7 @@ the actual number of articles marked is returned."
     (if (gnus-summary-goto-subject article)
        (progn
          (gnus-summary-show-thread)
-         (and (eq (gnus-summary-article-mark) ?Z)
+         (and (eq (gnus-summary-article-mark) gnus-dummy-mark)
               (forward-line 1))
          (gnus-summary-update-mark gnus-process-mark 'replied)
          t))))
@@ -8370,7 +8484,7 @@ the actual number of articles marked is returned."
     (if (gnus-summary-goto-subject article)
        (progn
          (gnus-summary-show-thread)
-         (and (eq (gnus-summary-article-mark) ?Z)
+         (and (eq (gnus-summary-article-mark) gnus-dummy-mark)
               (forward-line 1))
          (gnus-summary-update-mark ?  'replied)
          (if (memq article gnus-newsgroup-replied) 
@@ -8438,7 +8552,7 @@ marked."
     (if (gnus-summary-goto-subject article)
        (let ((buffer-read-only nil))
          (gnus-summary-show-thread)
-         (and (eq (gnus-summary-article-mark) ?Z)
+         (and (eq (gnus-summary-article-mark) gnus-dummy-mark)
               (forward-line 1))
          ;; Fix the mark.
          (gnus-summary-update-mark mark 'unread)
@@ -8453,10 +8567,9 @@ marked."
       (forward-char forward)
       (setq plist (text-properties-at (point)))
       (delete-char 1)
-      (and (memq 'gnus plist) 
-          (setcar (cdr (car (cdr (memq 'gnus plist)))) mark))
       (insert mark)
       (and plist (add-text-properties (1- (point)) (point) plist))
+      (add-text-properties (1- (point)) (point) (list 'gnus-mark mark))
       (gnus-summary-update-line (eq mark gnus-unread-mark)))))
   
 (defun gnus-mark-article-as-read (article &optional mark)
@@ -8467,34 +8580,25 @@ marked."
        (setq gnus-newsgroup-expirable (cons article gnus-newsgroup-expirable))
       (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable)))
     ;; Remove from unread and marked lists.
-    (setq gnus-newsgroup-unreads
-         (delq article gnus-newsgroup-unreads))
-    (setq gnus-newsgroup-marked
-         (delq article gnus-newsgroup-marked))
-    (setq gnus-newsgroup-dormant
-         (delq article gnus-newsgroup-dormant))))
+    (setq gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads))
+    (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
+    (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))))
 
 (defun gnus-mark-article-as-unread (article &optional mark)
   "Enter ARTICLE in the pertinent lists and remove it from others."
   (let ((mark (or (and (stringp mark) (aref mark 0)) mark gnus-ticked-mark)))
     ;; Add to unread list.
     (or (memq article gnus-newsgroup-unreads)
-       (setq gnus-newsgroup-unreads
-             (cons article gnus-newsgroup-unreads)))
-    ;; If CLEAR-MARK is non-nil, the article must be removed from marked
-    ;; list.  Otherwise, it must be added to the list.
-    (setq gnus-newsgroup-marked
-         (delq article gnus-newsgroup-marked))
-    (setq gnus-newsgroup-dormant
-         (delq article gnus-newsgroup-dormant))
-    (setq gnus-newsgroup-expirable 
-         (delq article gnus-newsgroup-expirable))
+       (setq gnus-newsgroup-unreads (cons article gnus-newsgroup-unreads)))
+    ;; If CLEAR-MARK is non-nil, the article must be removed from mark
+    ;; lists.  Otherwise, it must be added to the list.
+    (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
+    (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))
+    (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))
     (if (= mark gnus-ticked-mark)
-       (setq gnus-newsgroup-marked 
-             (cons article gnus-newsgroup-marked)))
+       (setq gnus-newsgroup-marked (cons article gnus-newsgroup-marked)))
     (if (= mark gnus-dormant-mark)
-       (setq gnus-newsgroup-dormant 
-             (cons article gnus-newsgroup-dormant)))))
+       (setq gnus-newsgroup-dormant (cons article gnus-newsgroup-dormant)))))
 
 (defalias 'gnus-summary-mark-as-unread-forward 
   'gnus-summary-tick-article-forward)
@@ -8615,6 +8719,7 @@ even ticked and dormant ones."
   "Remove lines that are marked with MARKS (e.g. \"DK\")."
   (interactive "sMarks: ")
   ;; Fix by Sudish Joseph <joseph@cis.ohio-state.edu>.
+  (gnus-set-global-variables)
   (save-excursion
     (set-buffer gnus-summary-buffer)
     (let ((buffer-read-only nil)
@@ -8622,18 +8727,32 @@ even ticked and dormant ones."
       (goto-char (point-min))
       (if gnus-newsgroup-adaptive
          (gnus-score-remove-lines-adaptive marks)
-       (while (re-search-forward marks (point-max) t)
-         (beginning-of-line)
-         (delete-region (point)
-                        (progn (forward-line 1) (point))))))
-    (or (zerop (buffer-size))
-       (if (eobp)
-           (gnus-summary-prev-subject 1)
-         (gnus-summary-position-cursor)))))
+       (while (re-search-forward marks nil t)
+         (gnus-delete-line)))
+      ;; If we use dummy roots, we have to do an additional sweep over
+      ;; the buffer.
+      (if (not (eq gnus-summary-make-false-root 'dummy))
+         ()
+       (goto-char (point-min))
+       (setq marks (concat "^[" (char-to-string gnus-dummy-mark) "]"))
+       (while (re-search-forward marks nil t)
+         (if (gnus-subject-equal
+              (gnus-summary-subject-string)
+              (progn
+                (forward-line 1)
+                (gnus-summary-subject-string)))
+             ()
+           (forward-line -1)
+           (gnus-delete-line))))))
+  (or (zerop (buffer-size))
+      (if (eobp)
+         (gnus-summary-prev-subject 1)
+       (gnus-summary-position-cursor))))
 
 (defun gnus-summary-expunge-below (score)
   "Remove articles with score less than SCORE."
   (interactive "P")
+  (gnus-set-global-variables)
   (setq score (if score
                  (prefix-numeric-value score)
                (or gnus-summary-default-score 0)))
@@ -8658,6 +8777,7 @@ even ticked and dormant ones."
 (defun gnus-summary-mark-below (score mark)
   "Mark articles with score less than SCORE with MARK."
   (interactive "P\ncMark: ")
+  (gnus-set-global-variables)
   (setq score (if score
                  (prefix-numeric-value score)
                (or gnus-summary-default-score 0)))
@@ -9179,26 +9299,6 @@ save those articles instead."
   (let ((gnus-default-article-saver 'gnus-summary-save-in-file))
     (gnus-summary-save-article arg)))
 
-(defun gnus-summary-save-article-folder (arg)
-  "Append the current article to an mh folder.
-If N is a positive number, save the N next articles.
-If N is a negative number, save the N previous articles.
-If N is nil and any articles have been marked with the process mark,
-save those articles instead."
-  (interactive "P")
-  (let ((gnus-default-article-saver 'gnus-summary-save-in-folder))
-    (gnus-summary-save-article arg)))
-
-(defun gnus-summary-save-article-vm (arg)
-  "Append the current article to a vm folder.
-If N is a positive number, save the N next articles.
-If N is a negative number, save the N previous articles.
-If N is nil and any articles have been marked with the process mark,
-save those articles instead."
-  (interactive "P")
-  (let ((gnus-default-article-saver 'gnus-summary-save-in-vm))
-    (gnus-summary-save-article arg)))
-
 (defun gnus-read-save-file-name (prompt default-name)
   (let ((methods gnus-split-methods)
        split-name)
@@ -9376,8 +9476,9 @@ is initialized from the SAVEDIR environment variable."
                                (cdr (assq 'name (car pslist))))
                  ": " (or (cdr (assq 'execute (car pslist))) "") "\n")
          (add-text-properties 
-          b (1+ b) (list 'gnus (list gnus-reffed-article-number
-                                     gnus-unread-mark 0)
+          b (1+ b) (list 'gnus-number gnus-reffed-article-number
+                         'gnus-mark gnus-unread-mark 
+                         'gnus-level 0
                          'gnus-pseudo (car pslist)))
          (forward-line -1)
          (gnus-sethash (int-to-string gnus-reffed-article-number)
@@ -9521,11 +9622,15 @@ The following commands are available:
 
 (defun gnus-article-setup-buffer ()
   "Initialize article mode buffer."
-  (or (get-buffer gnus-article-buffer)
+  (if (get-buffer gnus-article-buffer)
       (save-excursion
-       (set-buffer (get-buffer-create gnus-article-buffer))
-       (gnus-add-current-to-buffer-list)
-       (gnus-article-mode))))
+       (set-buffer gnus-article-buffer)
+       (or (eq major-mode 'gnus-article-mode)
+           (gnus-article-mode)))
+    (save-excursion
+      (set-buffer (get-buffer-create gnus-article-buffer))
+      (gnus-add-current-to-buffer-list)
+      (gnus-article-mode))))
 
 ;; Set article window start at LINE, where LINE is the number of lines
 ;; from the head of the article.
@@ -9707,13 +9812,12 @@ If ALL-HEADERS is non-nil, no headers are hidden."
            ;; This hook must be called before being narrowed.
            (let (buffer-read-only)
              (run-hooks 'internal-hook)
-             (run-hooks 'gnus-article-prepare-hook))
-           ;; Decode MIME message.
-           (if (and gnus-show-mime
-                    (gnus-fetch-field "Mime-Version"))
-               (funcall gnus-show-mime-method))
-           ;; Perform the article display hooks.
-           (let (buffer-read-only)
+             (run-hooks 'gnus-article-prepare-hook)
+             ;; Decode MIME message.
+             (if (and gnus-show-mime
+                      (gnus-fetch-field "Mime-Version"))
+                 (funcall gnus-show-mime-method))
+             ;; Perform the article display hooks.
              (run-hooks 'gnus-article-display-hook))
            ;; Do page break.
            (goto-char (point-min))
@@ -10262,7 +10366,7 @@ ROT47 will be performed for Japanese text in any case."
                          (if (<= v t1) (if (< v t2) v (+ v 47))
                            (if (<= v t3) (- v 47) v))))
                  (setq i (1+ i))))
-             (gnus-message 9 "Building caesar-translate-table... done")))
+             (gnus-message 9 "Building caesar-translate-table...done")))
        (let ((from (region-beginning))
              (to (region-end))
              (i 0) str len)
@@ -11080,6 +11184,13 @@ The `-n' option line from .newsrc is respected."
        (and gnus-novice-user
             (gnus-message 7 "`A k' to list killed groups"))))))
 
+(defun gnus-subscribe-group (group previous &optional method)
+  (gnus-group-change-level 
+   (if method
+       (list t group gnus-level-default-subscribed nil nil method)
+     group) 
+   gnus-level-default-subscribed gnus-level-killed previous t))
+
 ;; `gnus-group-change-level' is the fundamental function for changing
 ;; subscription levels of newsgroups. This might mean just changing
 ;; from level 1 to 2, which is pretty trivial, from 2 to 6 or back
@@ -11142,10 +11253,14 @@ The `-n' option line from .newsrc is respected."
     ;; go, and change the subscription level. If it is to be killed,
     ;; we enter it into the killed or zombie list.
     (cond ((>= level gnus-level-zombie)
-          (and (string= group (gnus-group-real-name group))
-               (if (= level gnus-level-zombie)
-                   (setq gnus-zombie-list (cons group gnus-zombie-list))
-                 (setq gnus-killed-list (cons group gnus-killed-list)))))
+          ;; Remove from the hash table.
+          (gnus-sethash group nil gnus-newsrc-hashtb)
+          (or (gnus-group-foreign-p group)
+              ;; We do not enter foreign groups into the list of dead
+              ;; groups.  
+              (if (= level gnus-level-zombie)
+                  (setq gnus-zombie-list (cons group gnus-zombie-list))
+                (setq gnus-killed-list (cons group gnus-killed-list)))))
          (t
           ;; If the list is to be entered into the newsrc assoc, and
           ;; it was killed, we have to create an entry in the newsrc
@@ -11236,7 +11351,7 @@ newsgroup."
                   (delete group (symbol-value (car dead-lists)))))
          (setq killed (cdr killed)))
        (setq dead-lists (cdr dead-lists))))
-    (gnus-message 5 "Checking bogus newsgroups... done")))
+    (gnus-message 5 "Checking bogus newsgroups...done")))
 
 (defun gnus-check-duplicate-killed-groups ()
   "Remove duplicates from the list of killed groups."
@@ -11300,7 +11415,7 @@ newsgroup."
           (gnus-get-unread-articles-in-group (car virtuals) active))
       (setq virtuals (cdr virtuals)))
 
-    (gnus-message 5 "Checking new news... done")))
+    (gnus-message 5 "Checking new news...done")))
 
 ;; Create a hash table out of the newsrc alist. The `car's of the
 ;; alist elements are used as keys.
@@ -11633,8 +11748,8 @@ Returns whether the updating was successful."
                ;; group gets set to a symbol interned in the hash table
                ;; (what a hack!!)
                (setq group (let ((obarray hashtb)) (read cur)))
-               (setq max (read cur))
-               (set group (cons (read cur) max)))
+               (and (numberp (setq max (read cur)))
+                    (set group (cons (read cur) max))))
            (error 
             (progn (ding) 
                    (gnus-message 3 "Illegal active: %s"
@@ -11721,7 +11836,7 @@ If FORCE is non-nil, the .newsrc file is read."
            (buffer-disable-undo (current-buffer))
            (gnus-newsrc-to-gnus-format)
            (kill-buffer (current-buffer))
-           (gnus-message 5 "Reading %s... done" newsrc-file))))))
+           (gnus-message 5 "Reading %s...done" newsrc-file))))))
 
 (defun gnus-read-newsrc-el-file (file)
   (let ((ding-file (concat file "d")))
@@ -12086,7 +12201,7 @@ If FORCE is non-nil, the .newsrc file is read."
                   (gnus-message 5 "Saving %s..." gnus-current-startup-file)
                   ;; Make backup file of master newsrc.
                   (gnus-gnus-to-newsrc-format)
-                  (gnus-message 5 "Saving %s... done"
+                  (gnus-message 5 "Saving %s...done"
                                 gnus-current-startup-file)))
             ;; Quickly loadable .newsrc.
             (set-buffer (get-buffer-create " *Gnus-newsrc*"))
@@ -12099,7 +12214,7 @@ If FORCE is non-nil, the .newsrc file is read."
                           (concat gnus-current-startup-file ".eld") 
                           nil 'nomesg)
             (kill-buffer (current-buffer))
-            (gnus-message 5 "Saving %s.eld... done" gnus-current-startup-file)
+            (gnus-message 5 "Saving %s.eld...done" gnus-current-startup-file)
             (gnus-dribble-delete-file))))))
 
 (defun gnus-gnus-to-quick-newsrc-format ()
@@ -12183,8 +12298,6 @@ If FORCE is non-nil, the .newsrc file is read."
        (save-restriction
          (set-buffer nntp-server-buffer)
          (goto-char (point-min))
-         (delete-non-matching-lines "^[-\\._+A-Za-z0-9]+[ \t]")
-         (goto-char (point-min))
          (if (or (search-forward "\n.\n" nil t)
                  (goto-char (point-max)))
              (progn
@@ -12192,11 +12305,20 @@ If FORCE is non-nil, the .newsrc file is read."
                (narrow-to-region (point-min) (point))))
          (goto-char (point-min))
          (while (not (eobp))
-           (setq group (let ((obarray gnus-description-hashtb))
-                         (read (current-buffer))))
+           ;; If we get an error, we set group to 0, which is not a
+           ;; symbol... 
+           (setq group 
+                 (condition-case ()
+                     (let ((obarray gnus-description-hashtb))
+                       ;; Group is set to a symbol interned in this
+                       ;; hash table.
+                       (read nntp-server-buffer))
+                   (error 0)))
            (skip-chars-forward " \t")
+           ;; ... which leads to this line being effectively ignored.
            (and (symbolp group)
-                (set group (buffer-substring (point) (gnus-point-at-eol))))
+                (set group (buffer-substring 
+                            (point) (progn (end-of-line) (point)))))
            (forward-line 1))))
       (gnus-message 5 "Reading descriptions file...done")
       t))))
@@ -12540,6 +12662,208 @@ The following commands are available:
   (mouse-set-point e)
   (gnus-server-read-server (gnus-server-server-name)))
 
+;;;
+;;; entry points into gnus-score.el
+;;;
+
+;;; Finding score files. 
+
+(defvar gnus-global-score-files nil
+  "*List of global score files and directories.
+Set this variable if you want to use people's score files.  One entry
+for each score file or each score file directory.  Gnus will decide
+by itself what score files are applicable to which group.
+
+Say you want to use the single score file
+\"/ftp.ifi.uio.no@ftp:/pub/larsi/ding/score/soc.motss.SCORE\" and all
+score files in the \"/ftp.some-where:/pub/score\" directory.
+
+ (setq gnus-global-score-files
+       '(\"/ftp.ifi.uio.no:/pub/larsi/ding/score/soc.motss.SCORE\"
+         \"/ftp.some-where:/pub/score\"))")
+
+(defun gnus-score-score-files (group)
+  "Return a list of all possible score files."
+  ;; Search and set any global score files.
+  (and gnus-global-score-files 
+       (or gnus-internal-global-score-files
+          (gnus-score-search-global-directories gnus-global-score-files)))
+  ;; Fix the kill-file dir variable.
+  (setq gnus-kill-files-directory 
+       (file-name-as-directory
+        (or gnus-kill-files-directory "~/News/")))
+  ;; If er can't read it, there's no score files.
+  (if (not (file-readable-p (expand-file-name gnus-kill-files-directory)))
+      (setq gnus-score-file-list nil)
+    (if (gnus-use-long-file-name 'not-score)
+       ;; We want long file names.
+       (if (or (not gnus-score-file-list)
+               (not (car gnus-score-file-list))
+               (gnus-file-newer-than gnus-kill-files-directory
+                                     (car gnus-score-file-list)))
+             (setq gnus-score-file-list 
+                   (cons (nth 5 (file-attributes gnus-kill-files-directory))
+                         (nreverse 
+                          (directory-files 
+                           gnus-kill-files-directory t 
+                           (gnus-score-file-regexp))))))
+      ;; We do not use long file names, so we have to do some
+      ;; directory traversing.  
+      (let ((mdir (length (expand-file-name gnus-kill-files-directory)))
+           (suffixes (list gnus-score-file-suffix gnus-adaptive-file-suffix))
+           dir files suffix)
+       (while suffixes
+         (setq dir (expand-file-name
+                    (concat gnus-kill-files-directory
+                            (gnus-replace-chars-in-string group ?. ?/))))
+         (setq suffix (car suffixes)
+               suffixes (cdr suffixes))
+         (if (file-exists-p (concat dir "/" suffix))
+             (setq files (list (concat dir "/" suffix))))
+         (while (>= (1+ (length dir)) mdir)
+           (and (file-exists-p (concat dir "/all/" suffix))
+                (setq files (cons (concat dir "/all/" suffix) files)))
+           (string-match "/[^/]*$" dir)
+           (setq dir (substring dir 0 (match-beginning 0)))))
+       (setq gnus-score-file-list 
+             (cons nil (nreverse files)))))
+    (cdr gnus-score-file-list)))
+
+(defun gnus-score-file-regexp ()
+  (concat "\\(" gnus-score-file-suffix 
+         "\\|" gnus-adaptive-file-suffix "\\)$"))
+       
+(defun gnus-score-find-bnews (group)
+  "Return a list of score files for GROUP.
+The score files are those files in the ~/News directory which matches
+GROUP using BNews sys file syntax."
+  (let* ((sfiles (append (gnus-score-score-files group)
+                        gnus-internal-global-score-files))
+        (kill-dir (file-name-as-directory 
+                   (expand-file-name gnus-kill-files-directory)))
+        (klen (length kill-dir))
+        ofiles not-match regexp)
+    (save-excursion
+      (set-buffer (get-buffer-create "*gnus score files*"))
+      (buffer-disable-undo (current-buffer))
+      ;; Go through all score file names and create regexp with them
+      ;; as the source.  
+      (while sfiles
+       (erase-buffer)
+       (insert (car sfiles))
+       (goto-char (point-min))
+       ;; First remove the suffix itself.
+       (re-search-forward (concat "." (gnus-score-file-regexp)))
+       (replace-match "" t t) 
+       (goto-char (point-min))
+       (if (looking-at (regexp-quote kill-dir))
+           ;; If the file name was just "SCORE", `klen' is one character
+           ;; too much.
+           (delete-char (min (1- (point-max)) klen))
+         (goto-char (point-max))
+         (search-backward "/")
+         (delete-region (1+ (point)) (point-min)))
+       ;; Translate "all" to ".*".
+       (while (search-forward "all" nil t)
+         (replace-match ".*" t t))
+       (goto-char (point-min))
+       ;; Deal with "not."s.
+       (if (looking-at "not.")
+           (progn
+             (setq not-match t)
+             (setq regexp (buffer-substring 5 (point-max))))
+         (setq regexp (buffer-substring 1 (point-max)))
+         (setq not-match nil))
+       ;; Finally - if this resulting regexp matches the group name,
+       ;; we add this score file to the list of score files
+       ;; applicable to this group.
+       (if (or (and not-match
+                    (not (string-match regexp group)))
+               (and (not not-match)
+                    (string-match regexp group)))
+           (setq ofiles (cons (car sfiles) ofiles)))
+       (setq sfiles (cdr sfiles)))
+      (kill-buffer (current-buffer))
+      ;; Slight kludge here - the last score file returned should be
+      ;; the local score file, whether it exists or not. This is so
+      ;; that any score commands the user enters will go to the right
+      ;; file, and not end up in some global score file.
+      (let ((localscore
+            (expand-file-name
+             (if (gnus-use-long-file-name 'not-score)
+                 (concat gnus-kill-files-directory group "." 
+                         gnus-score-file-suffix)
+               (concat gnus-kill-files-directory
+                       (gnus-replace-chars-in-string group ?. ?/)
+                       "/" gnus-score-file-suffix)))))
+       (and (member localscore ofiles)
+            (delete localscore ofiles))
+       (setq ofiles (cons localscore ofiles)))
+      (nreverse ofiles))))
+
+(defun gnus-score-find-single (group)
+  "Return list containing the score file for GROUP."
+  (list (gnus-score-file-name group)))
+
+(defun gnus-score-find-hierarchical (group)
+  "Return list of score files for GROUP.
+This includes the score file for the group and all its parents."
+  (let ((all (copy-sequence '(nil)))
+       (start 0))
+    (while (string-match "\\." group (1+ start))
+      (setq start (match-beginning 0))
+      (setq all (cons (substring group 0 start) all)))
+    (setq all (cons group all))
+    (mapcar 'gnus-score-file-name (nreverse all))))
+
+(defun gnus-possibly-score-headers (&optional trace)
+  (let ((func gnus-score-find-score-files-function)
+       score-files scores)
+    (and func (not (listp func))
+        (setq func (list func)))
+    ;; Go through all the functions for finding score files (or actual
+    ;; scores) and add them to a list.
+    (while func
+      (and (symbolp (car func))
+          (fboundp (car func))
+          (setq score-files 
+                (nconc score-files (funcall (car func) gnus-newsgroup-name))))
+      (setq func (cdr func)))
+    (if score-files (gnus-score-headers score-files trace))))
+
+(defun gnus-score-file-name (newsgroup &optional suffix)
+  "Return the name of a score file for NEWSGROUP."
+  (let ((suffix (or suffix gnus-score-file-suffix)))
+    (cond  ((or (null newsgroup)
+               (string-equal newsgroup ""))
+           ;; The global score file is placed at top of the directory.
+           (expand-file-name 
+            suffix (or gnus-kill-files-directory "~/News")))
+          ((gnus-use-long-file-name 'not-score)
+           ;; Append ".SCORE" to newsgroup name.
+           (expand-file-name (concat newsgroup "." suffix)
+                             (or gnus-kill-files-directory "~/News")))
+          (t
+           ;; Place "SCORE" under the hierarchical directory.
+           (expand-file-name (concat (gnus-newsgroup-directory-form newsgroup)
+                                     "/" suffix)
+                             (or gnus-kill-files-directory "~/News"))))))
+
+(defun gnus-score-search-global-directories (files)
+  "Scan all global score directories for score files."
+  ;; Set the variable `gnus-internal-global-score-files' to all
+  ;; available global score files.
+  (interactive (list gnus-global-score-files))
+  (let (out)
+    (while files
+      (if (string-match "/$" (car files))
+         (setq out (nconc (directory-files 
+                           (car files) t
+                           (concat (gnus-score-file-regexp) "$"))))
+       (setq out (cons (car files) out)))
+      (setq files (cdr files)))
+    (setq gnus-internal-global-score-files out)))
+
 ;; Allow redefinition of Gnus functions.
 
 (gnus-ems-redefine)
index 4a6c2dc..6797e83 100644 (file)
           (setq incomings (cons incoming incomings))
           (save-excursion
             (let ((in-buf (nnmail-split-incoming 
-                           incoming 'nnbabyl-save-mail t)))
+                           incoming 'nnbabyl-save-mail t group)))
               (set-buffer in-buf)
               (goto-char (point-min))
               (while (search-forward "\n\^_\n" nil t)
index 316bda3..fb2a5e5 100644 (file)
@@ -239,22 +239,27 @@ such things as moving mail.  All buffers always get killed upon server close.")
 ;; way.
 
 (defun nnfolder-close-group (group &optional server force)
-  (nnfolder-possibly-change-group group)
-  (save-excursion
-    (set-buffer nnfolder-current-buffer)
-    ;; If the buffer was modified, write the file out now.
-    (and (buffer-modified-p) (save-buffer))
-    (if (or force
-           nnfolder-always-close)
-       ;; If we're shutting the server down, we need to kill the buffer and
-       ;; remove it from the open buffer list.  Or, of course, if we're
-       ;; trying to minimize our space impact.
-       (progn
-         (kill-buffer (current-buffer))
-         (setq nnfolder-buffer-alist (delq (assoc group nnfolder-buffer-alist)
-                                           nnfolder-buffer-alist))))
-    (setq nnfolder-current-group nil
-         nnfolder-current-buffer nil))
+  ;; Make sure we _had_ the group open.
+  (if (or (assoc group nnfolder-buffer-alist)
+         (equal group nnfolder-current-group))
+      (progn
+       (nnfolder-possibly-change-group group)
+       (save-excursion
+         (set-buffer nnfolder-current-buffer)
+         ;; If the buffer was modified, write the file out now.
+         (and (buffer-modified-p) (save-buffer))
+         (if (or force
+                 nnfolder-always-close)
+             ;; If we're shutting the server down, we need to kill the
+             ;; buffer and remove it from the open buffer list.  Or, of
+             ;; course, if we're trying to minimize our space impact.
+             (progn
+               (kill-buffer (current-buffer))
+               (setq nnfolder-buffer-alist (delq (assoc group 
+                                                        nnfolder-buffer-alist)
+                                                 nnfolder-buffer-alist)))))))
+  (setq nnfolder-current-group nil
+       nnfolder-current-buffer nil)
   t)
 
 (defun nnfolder-request-list (&optional server)
@@ -508,7 +513,7 @@ such things as moving mail.  All buffers always get killed upon server close.")
   (save-excursion
     ;; If we're looking for the activation of a specific group, find out
     ;; it's real name and switch to it.
-    (if group (nnfolder-possibly-change-group (gnus-group-real-name group)))
+    (if group (nnfolder-possibly-change-group group))
     ;; If the group alist isn't active, activate it now.
     (if (not nnfolder-group-alist)
        (progn
@@ -625,7 +630,7 @@ such things as moving mail.  All buffers always get killed upon server close.")
                 (nnmail-move-inbox 
                  (car spools) (concat nnfolder-directory "Incoming")))
           (setq incomings (cons incoming incomings))
-          (nnmail-split-incoming incoming 'nnfolder-save-mail)))
+          (nnmail-split-incoming incoming 'nnfolder-save-mail nil group)))
        (setq spools (cdr spools)))
       ;; If we did indeed read any incoming spools, we save all info. 
       (if incoming 
index 340b115..2be32fa 100644 (file)
 ;; Read the head of an article.
 (defun nnheader-insert-head (file)
   (let ((beg 0)
+       (chop 1024)
        found)
-    (while (and (eq 1024 (nth 1 (insert-file-contents 
-                                file nil beg (setq beg (+ 1024 beg)))))
-               (search-backward "\n\n" nil t)))))
+    (while (and (eq chop (nth 1 (insert-file-contents 
+                                file nil beg (setq beg (+ chop beg)))))
+               (prog1 (not (search-backward "\n\n" nil t)) 
+                 (goto-char (point-max)))))))
     
 
 (provide 'nnheader)
index ad81655..e332bf7 100644 (file)
@@ -312,12 +312,13 @@ Example:
 (defun nnmail-move-inbox (inbox tofile)
   (let ((inbox (file-truename
                (expand-file-name (substitute-in-file-name inbox))))
-       (tofile (nnmail-make-complex-temp-name (expand-file-name tofile)))
        movemail popmail errors)
     ;; Check whether the inbox is to be moved to the special tmp dir. 
     (if nnmail-tmp-directory
        (setq tofile (concat (file-name-as-directory nnmail-tmp-directory)
                             (file-name-nondirectory tofile))))
+    ;; Make the filename unique.
+    (setq tofile (nnmail-make-complex-temp-name (expand-file-name tofile)))
     ;; If getting from mail spool directory,
     ;; use movemail to move rather than just renaming,
     ;; so as to interlock with the mailer.
@@ -433,10 +434,15 @@ nn*-request-list should have been called before calling this function."
       (write-region 1 (point-max) (expand-file-name file-name) nil 'nomesg)
       (kill-buffer (current-buffer)))))
 
-(defun nnmail-split-incoming (incoming func &optional dont-kill)
+(defun nnmail-split-incoming (incoming func &optional dont-kill group)
   "Go through the entire INCOMING file and pick out each individual mail.
 FUNC will be called with the buffer narrowed to each mail."
   (let ((delim (concat "^" rmail-unix-mail-delimiter))
+       ;; If this is a group-specific split, we bind the split
+       ;; methods to just this group.
+       (nnmail-split-methods (if (and group (eq nnmail-spool-file 'procmail))
+                                 (list (list group ""))
+                               nnmail-split-methods))
        start end content-length do-search)
     (save-excursion
       (set-buffer (get-buffer-create " *nnmail incoming*"))
@@ -457,7 +463,7 @@ FUNC will be called with the buffer narrowed to each mail."
            ;; Look for a Content-Length header.
            (if (not (save-excursion
                       (and (re-search-backward 
-                            "^Content-Length: \\([0-9]+\\)" nil t)
+                            "^Content-Length: \\([0-9]+\\)" start t)
                            (setq content-length (string-to-int
                                                  (buffer-substring 
                                                   (match-beginning 1)
@@ -500,51 +506,58 @@ FUNC will be called with the group name to determine the article number."
        (obuf (current-buffer))
        (beg (point-min))
        end found group-art)
-    (save-excursion
-      ;; Find headers.
-      (goto-char beg)
-      (setq end (if (search-forward "\n\n" nil t) (point) (point-max)))
-      (set-buffer (get-buffer-create " *nnmail work*"))
-      (buffer-disable-undo (current-buffer))
-      (erase-buffer)
-      ;; Copy the headers into the work buffer.
-      (insert-buffer-substring obuf beg end)
-      ;; Fold continuation lines.
-      (goto-char (point-min))
-      (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
-       (replace-match " " t t))
-      (if (and (symbolp nnmail-split-methods)
-              (fboundp nnmail-split-methods))
-         (setq group-art
-               (mapcar
-                (lambda (group) (cons group (funcall func group)))
-                (funcall nnmail-split-methods)))
-       ;; Go throught the split methods to find a match.
-       (while (and methods (or nnmail-crosspost (not group-art)))
-         (goto-char (point-max))
-         (if (or (cdr methods)
-                 (not (equal "" (nth 1 (car methods)))))
-             (if (and (condition-case () 
-                          (if (stringp (nth 1 (car methods)))
-                              (re-search-backward
-                               (car (cdr (car methods))) nil t)
-                            ;; Suggested by Brian Edmonds <edmonds@cs.ubc.ca>.
-                            (funcall (nth 1 (car methods)) 
-                                     (car (car methods))))
-                        (error nil))
-                      ;; Don't enter the article into the same group twice.
-                      (not (assoc (car (car methods)) group-art)))
-                 (setq group-art
-                       (cons (cons (car (car methods))
-                                   (funcall func (car (car methods)))) 
-                             group-art)))
-           (or group-art
-               (setq group-art 
-                     (list (cons (car (car methods)) 
-                                 (funcall func (car (car methods))))))))
-         (setq methods (cdr methods))))
-      (kill-buffer (current-buffer))
-      group-art)))
+    (if (= (length methods) 1)
+       ;; If there is only just one group to put everything in, we
+       ;; just return a list with just this one method in.
+       (setq group-art
+             (list (cons (car (car methods))
+                         (funcall func (car (car methods))))))
+      ;; We do actual comparison.
+      (save-excursion
+       ;; Find headers.
+       (goto-char beg)
+       (setq end (if (search-forward "\n\n" nil t) (point) (point-max)))
+       (set-buffer (get-buffer-create " *nnmail work*"))
+       (buffer-disable-undo (current-buffer))
+       (erase-buffer)
+       ;; Copy the headers into the work buffer.
+       (insert-buffer-substring obuf beg end)
+       ;; Fold continuation lines.
+       (goto-char (point-min))
+       (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
+         (replace-match " " t t))
+       (if (and (symbolp nnmail-split-methods)
+                (fboundp nnmail-split-methods))
+           (setq group-art
+                 (mapcar
+                  (lambda (group) (cons group (funcall func group)))
+                  (funcall nnmail-split-methods)))
+         ;; Go throught the split methods to find a match.
+         (while (and methods (or nnmail-crosspost (not group-art)))
+           (goto-char (point-max))
+           (if (or (cdr methods)
+                   (not (equal "" (nth 1 (car methods)))))
+               (if (and (condition-case () 
+                            (if (stringp (nth 1 (car methods)))
+                                (re-search-backward
+                                 (car (cdr (car methods))) nil t)
+                              ;; Suggested by Brian Edmonds <edmonds@cs.ubc.ca>.
+                              (funcall (nth 1 (car methods)) 
+                                       (car (car methods))))
+                          (error nil))
+                        ;; Don't enter the article into the same group twice.
+                        (not (assoc (car (car methods)) group-art)))
+                   (setq group-art
+                         (cons (cons (car (car methods))
+                                     (funcall func (car (car methods)))) 
+                               group-art)))
+             (or group-art
+                 (setq group-art 
+                       (list (cons (car (car methods)) 
+                                   (funcall func (car (car methods))))))))
+           (setq methods (cdr methods))))
+       (kill-buffer (current-buffer))
+       group-art))))
 
 (defun nnmail-insert-lines ()
   "Insert how many lines and chars there are in the body of the mail."
index 958fe0b..7e159a2 100644 (file)
                  (car spools) (concat nnmbox-mbox-file "-Incoming")))
           (save-excursion
             (let ((in-buf (nnmail-split-incoming 
-                           incoming 'nnmbox-save-mail t)))
+                           incoming 'nnmbox-save-mail t group)))
               (set-buffer nnmbox-mbox-buffer)
               (goto-char (point-max))
               (insert-buffer-substring in-buf)
index 13b07bb..0205711 100644 (file)
                 (nnmail-move-inbox 
                  (car spools) (concat nnmh-directory "Incoming")))
           (setq incomings (cons incoming incomings))
-          (nnmail-split-incoming incoming 'nnmh-save-mail)))
+          (nnmail-split-incoming incoming 'nnmh-save-mail nil group)))
        (setq spools (cdr spools)))
       ;; If we did indeed read any incoming spools, we save all info. 
       (if incoming 
index dc4e8e8..cd960e3 100644 (file)
@@ -495,7 +495,7 @@ all. This may very well take some time.")
           (setq incoming 
                 (nnmail-move-inbox 
                  (car spools) (concat nnml-directory "Incoming")))
-          (nnmail-split-incoming incoming 'nnml-save-mail)
+          (nnmail-split-incoming incoming 'nnml-save-mail nil group)
           (setq incomings (cons incoming incomings))
           ;; The following has been commented away, just to make sure
           ;; that nobody ever loses any mail. If you feel safe that