2001-07-27 12:00:00 ShengHuo ZHU <zsh@cs.rochester.edu>
[gnus] / lisp / nnfolder.el
index 5f399d8..ceedda3 100644 (file)
@@ -1,7 +1,9 @@
 ;;; nnfolder.el --- mail folder access for Gnus
-;; Copyright (C) 1995,96,97,98 Free Software Foundation, Inc.
+;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000
+;;        Free Software Foundation, Inc.
 
-;; Author: Scott Byer <byer@mv.us.adobe.com>
+;; Author: ShengHuo Zhu <zsh@cs.rochester.edu> (adding NOV)
+;;      Scott Byer <byer@mv.us.adobe.com>
 ;;     Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;; Keywords: mail
 (require 'nnoo)
 (eval-when-compile (require 'cl))
 (require 'gnus-util)
+(require 'gnus-range)
+
+(eval-and-compile
+  (autoload 'gnus-intersection "gnus-range"))
 
 (nnoo-declare nnfolder)
 
 (defvoo nnfolder-directory (expand-file-name message-directory)
   "The name of the nnfolder directory.")
 
+(defvoo nnfolder-nov-directory nil
+  "The name of the nnfolder NOV directory.
+If nil, `nnfolder-directory' is used.")
+
 (defvoo nnfolder-active-file
-  (nnheader-concat nnfolder-directory "active")
+    (nnheader-concat nnfolder-directory "active")
   "The name of the active file.")
 
 ;; I renamed this variable to something more in keeping with the general GNU
 ;; style. -SLB
 
 (defvoo nnfolder-ignore-active-file nil
-  "If non-nil, causes nnfolder to do some extra work in order to determine
-the true active ranges of an mbox file.  Note that the active file is still
-saved, but it's values are not used.  This costs some extra time when
-scanning an mbox when opening it.")
+  "If non-nil, the active file is ignored.
+This causes nnfolder to do some extra work in order to determine the
+true active ranges of an mbox file.  Note that the active file is
+still saved, but its values are not used.  This costs some extra time
+when scanning an mbox when opening it.")
 
 (defvoo nnfolder-distrust-mbox nil
-  "If non-nil, causes nnfolder to not trust the user with respect to
-inserting unaccounted for mail in the middle of an mbox file.  This can greatly
-slow down scans, which now must scan the entire file for unmarked messages.
-When nil, scans occur forward from the last marked message, a huge
-time saver for large mailboxes.")
+  "If non-nil, the folder will be distrusted.
+This means that nnfolder will not trust the user with respect to
+inserting unaccounted for mail in the middle of an mbox file.  This
+can greatly slow down scans, which now must scan the entire file for
+unmarked messages.  When nil, scans occur forward from the last marked
+message, a huge time saver for large mailboxes.")
 
 (defvoo nnfolder-newsgroups-file
-  (concat (file-name-as-directory nnfolder-directory) "newsgroups")
+    (concat (file-name-as-directory nnfolder-directory) "newsgroups")
   "Mail newsgroups description file.")
 
 (defvoo nnfolder-get-new-mail t
@@ -77,7 +89,7 @@ time saver for large mailboxes.")
 
 \f
 
-(defconst nnfolder-version "nnfolder 1.0"
+(defconst nnfolder-version "nnfolder 2.0"
   "nnfolder version.")
 
 (defconst nnfolder-article-marker "X-Gnus-Article-Number: "
@@ -90,6 +102,28 @@ time saver for large mailboxes.")
 (defvoo nnfolder-buffer-alist nil)
 (defvoo nnfolder-scantime-alist nil)
 (defvoo nnfolder-active-timestamp nil)
+(defvoo nnfolder-active-file-coding-system mm-text-coding-system)
+(defvoo nnfolder-active-file-coding-system-for-write
+    nnmail-active-file-coding-system)
+(defvoo nnfolder-file-coding-system mm-text-coding-system)
+(defvoo nnfolder-file-coding-system-for-write nnheader-file-coding-system
+  "Coding system for save nnfolder file.
+If NIL, NNFOLDER-FILE-CODING-SYSTEM is used.")
+
+(defvoo nnfolder-nov-is-evil nil
+  "If non-nil, Gnus will never generate and use nov databases for mail groups.
+Using nov databases will speed up header fetching considerably.
+This variable shouldn't be flipped much.  If you have, for some reason,
+set this to t, and want to set it to nil again, you should always run
+the `nnfolder-generate-active-file' command.  The function will go
+through all nnfolder directories and generate nov databases for them
+all.  This may very well take some time.")
+
+(defvoo nnfolder-nov-file-suffix ".nov")
+
+(defvoo nnfolder-nov-buffer-alist nil)
+
+(defvar nnfolder-nov-buffer-file-name nil)
 
 \f
 
@@ -108,26 +142,35 @@ time saver for large mailboxes.")
        (goto-char (point-min))
        (if (stringp (car articles))
            'headers
-         (while (setq article (pop articles))
-           (set-buffer nnfolder-current-buffer)
-           (when (nnfolder-goto-article article)
-             (setq start (point))
-             (search-forward "\n\n" nil t)
-             (setq stop (1- (point)))
-             (set-buffer nntp-server-buffer)
-             (insert (format "221 %d Article retrieved.\n" article))
-             (insert-buffer-substring nnfolder-current-buffer start stop)
-             (goto-char (point-max))
-             (insert ".\n")))
-
-         (set-buffer nntp-server-buffer)
-         (nnheader-fold-continuation-lines)
-         'headers)))))
+         (if (nnfolder-retrieve-headers-with-nov articles fetch-old)
+             'nov
+           (setq articles (gnus-sorted-intersection
+                           ;; Is ARTICLES sorted?
+                           (sort articles '<)
+                           (nnfolder-existing-articles)))
+           (while (setq article (pop articles))
+             (set-buffer nnfolder-current-buffer)
+             (when (nnfolder-goto-article article)
+               (setq start (point))
+               (setq stop (if (search-forward "\n\n" nil t)
+                              (1- (point))
+                            (point-max)))
+               (set-buffer nntp-server-buffer)
+               (insert (format "221 %d Article retrieved.\n" article))
+               (insert-buffer-substring nnfolder-current-buffer start stop)
+               (goto-char (point-max))
+               (insert ".\n")))
+           (set-buffer nntp-server-buffer)
+           (nnheader-fold-continuation-lines)
+           'headers))))))
 
 (deffoo nnfolder-open-server (server &optional defs)
   (nnoo-change-server 'nnfolder server defs)
   (nnmail-activate 'nnfolder t)
   (gnus-make-directory nnfolder-directory)
+  (unless (or gnus-nov-is-evil nnfolder-nov-is-evil)
+    (and nnfolder-nov-directory
+        (gnus-make-directory nnfolder-nov-directory)))
   (cond
    ((not (file-exists-p nnfolder-directory))
     (nnfolder-close-server)
@@ -176,11 +219,13 @@ time saver for large mailboxes.")
          (if (numberp article)
              (cons nnfolder-current-group article)
            (goto-char (point-min))
-           (search-forward (concat "\n" nnfolder-article-marker))
            (cons nnfolder-current-group
-                 (string-to-int
-                  (buffer-substring
-                   (point) (progn (end-of-line) (point)))))))))))
+                 (if (search-forward (concat "\n" nnfolder-article-marker)
+                                     nil t)
+                     (string-to-int
+