* elmo-imap4.el (elmo-imap4-prefetch-msg): Set `msgdb'
[elisp/wanderlust.git] / elmo / elmo-cache.el
index f0ea53c..993b7d7 100644 (file)
@@ -1,12 +1,11 @@
 ;;; elmo-cache.el -- Cache modules for Elmo.
 
 ;;; elmo-cache.el -- Cache modules for Elmo.
 
-;; Copyright 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
-;; Copyright 2000 Kenichi OKADA <okada@opaopa.org>
+;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
+;; Copyright (C) 2000 Kenichi OKADA <okada@opaopa.org>
 
 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
 
 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
-;;         Kenichi OKADA <okada@opaopa.org>
+;;     Kenichi OKADA <okada@opaopa.org>
 ;; Keywords: mail, net news
 ;; Keywords: mail, net news
-;; Time-stamp: <00/03/01 09:57:55 teranisi>
 
 ;; This file is part of ELMO (Elisp Library for Message Orchestration).
 
 
 ;; This file is part of ELMO (Elisp Library for Message Orchestration).
 
   (unless (string-match elmo-cache-dirname path)
     (error "%s is not cache file!" path))
   (let (message-id)
   (unless (string-match elmo-cache-dirname path)
     (error "%s is not cache file!" path))
   (let (message-id)
-    (if (or (elmo-msgdb-global-mark-get 
+    (if (or (elmo-msgdb-global-mark-get
             (setq message-id
                   (elmo-cache-to-msgid (file-name-nondirectory path))))
            (member message-id locked))
             (setq message-id
                   (elmo-cache-to-msgid (file-name-nondirectory path))))
            (member message-id locked))
-       nil ;; Don't delete caches with mark (or locked message).
-      (if (and path 
+       nil;; Don't delete caches with mark (or locked message).
+      (if (and path
               (file-directory-p path))
          (progn
            (mapcar 'delete-file (directory-files path t "^[^\\.]"))
               (file-directory-p path))
          (progn
            (mapcar 'delete-file (directory-files path t "^[^\\.]"))
   (if msgid
       (let ((path1 (elmo-cache-get-path msgid))
            path2)
   (if msgid
       (let ((path1 (elmo-cache-get-path msgid))
            path2)
-       (if (and path1 
+       (if (and path1
                 (file-exists-p path1))
            (if (and folder
                     (file-directory-p path1))
                 (file-exists-p path1))
            (if (and folder
                     (file-directory-p path1))
-               (when (file-exists-p (setq path2 
+               (when (file-exists-p (setq path2
                                           (expand-file-name
                                           (expand-file-name
-                                           (format "%s@%s" 
+                                           (format "%s@%s"
                                                    number
                                                    (elmo-safe-filename
                                                     folder))
                                                    number
                                                    (elmo-safe-filename
                                                     folder))
@@ -82,7 +81,7 @@
                    (delete-directory path1))))))))
 
 (defun elmo-cache-read (msgid &optional folder number outbuf)
                    (delete-directory path1))))))))
 
 (defun elmo-cache-read (msgid &optional folder number outbuf)
-  "Read cache contents to outbuf"
+  "Read cache contents to OUTBUF."
   (save-excursion
     (let ((path (elmo-cache-exists-p msgid folder number)))
       (when path
   (save-excursion
     (let ((path (elmo-cache-exists-p msgid folder number)))
       (when path
 
 (defun elmo-read-float-value-from-minibuffer (prompt &optional initial)
   (let ((str (read-from-minibuffer prompt initial)))
 
 (defun elmo-read-float-value-from-minibuffer (prompt &optional initial)
   (let ((str (read-from-minibuffer prompt initial)))
-    (cond 
+    (cond
      ((string-match "[0-9]*\\.[0-9]+" str)
       (string-to-number str))
      ((string-match "[0-9]+" str)
      ((string-match "[0-9]*\\.[0-9]+" str)
       (string-to-number str))
      ((string-match "[0-9]+" str)
      (t (error "%s is not number" str)))))
 
 (defun elmo-cache-expire-by-size (&optional kbytes)
      (t (error "%s is not number" str)))))
 
 (defun elmo-cache-expire-by-size (&optional kbytes)
-  "Expire cache file by size. 
+  "Expire cache file by size.
 If KBYTES is kilo bytes (This value must be float)."
   (interactive)
   (let ((size (or kbytes
 If KBYTES is kilo bytes (This value must be float)."
   (interactive)
   (let ((size (or kbytes
@@ -134,25 +133,21 @@ If KBYTES is kilo bytes (This value must be float)."
                    (expand-file-name
                     elmo-cache-dirname elmo-msgdb-dir)) Kbytes))
     (setq beginning total)
                    (expand-file-name
                     elmo-cache-dirname elmo-msgdb-dir)) Kbytes))
     (setq beginning total)
-    (message "Checking disk usage...done.")
+    (message "Checking disk usage...done")
     (let ((cfl (elmo-cache-get-sorted-cache-file-list))
          (deleted 0)
     (let ((cfl (elmo-cache-get-sorted-cache-file-list))
          (deleted 0)
-         oldest 
+         oldest
          cur-size cur-file)
       (while (and (<= size total)
                  (setq oldest (elmo-cache-get-oldest-cache-file-entity cfl)))
        (setq cur-file (expand-file-name (car (cdr oldest)) (car oldest)))
          cur-size cur-file)
       (while (and (<= size total)
                  (setq oldest (elmo-cache-get-oldest-cache-file-entity cfl)))
        (setq cur-file (expand-file-name (car (cdr oldest)) (car oldest)))
-       (if (file-directory-p cur-file)
-           (setq cur-size (elmo-disk-usage cur-file))
-         (setq cur-size 
-               (/ (float (nth 7 (file-attributes cur-file)))
-                  Kbytes)))
+       (setq cur-size (/ (elmo-disk-usage cur-file) Kbytes))
        (when (elmo-cache-force-delete cur-file locked)
          (setq count (+ count 1))
          (message "%d cache(s) are expired." count))
        (setq deleted (+ deleted cur-size))
        (setq total (- total cur-size)))
        (when (elmo-cache-force-delete cur-file locked)
          (setq count (+ count 1))
          (message "%d cache(s) are expired." count))
        (setq deleted (+ deleted cur-size))
        (setq total (- total cur-size)))
-      (message "%d cache(s) are expired from disk (%d Kbytes/%d Kbytes)." 
+      (message "%d cache(s) are expired from disk (%d Kbytes/%d Kbytes)."
               count deleted beginning))))
 
 (defun elmo-cache-make-file-entity (filename path)
               count deleted beginning))))
 
 (defun elmo-cache-make-file-entity (filename path)
@@ -163,11 +158,11 @@ If KBYTES is kilo bytes (This value must be float)."
        flist firsts oldest-entity wonlist)
     (while cfl
       (setq flist (cdr (car cfl)))
        flist firsts oldest-entity wonlist)
     (while cfl
       (setq flist (cdr (car cfl)))
-      (setq firsts (append firsts (list 
-                                  (cons (car (car cfl)) 
+      (setq firsts (append firsts (list
+                                  (cons (car (car cfl))
                                         (car flist)))))
       (setq cfl (cdr cfl)))
                                         (car flist)))))
       (setq cfl (cdr cfl)))
-;    (prin1 firsts)
+;;; (prin1 firsts)
     (while firsts
       (if (and (not oldest-entity)
               (cdr (cdr (car firsts))))
     (while firsts
       (if (and (not oldest-entity)
               (cdr (cdr (car firsts))))
@@ -183,8 +178,8 @@ If KBYTES is kilo bytes (This value must be float)."
     oldest-entity))
 
 (defun elmo-cache-get-sorted-cache-file-list ()
     oldest-entity))
 
 (defun elmo-cache-get-sorted-cache-file-list ()
-  (let ((dirs (directory-files 
-              (expand-file-name elmo-cache-dirname elmo-msgdb-dir) 
+  (let ((dirs (directory-files
+              (expand-file-name elmo-cache-dirname elmo-msgdb-dir)
               t "^[^\\.]"))
        (i 0) num
        elist
               t "^[^\\.]"))
        (i 0) num
        elist
@@ -192,33 +187,35 @@ If KBYTES is kilo bytes (This value must be float)."
     (setq num (length dirs))
     (message "Collecting cache info...")
     (while dirs
     (setq num (length dirs))
     (message "Collecting cache info...")
     (while dirs
-      (setq elist (mapcar (lambda (x) 
+      (setq elist (mapcar (lambda (x)
                            (elmo-cache-make-file-entity x (car dirs)))
                          (directory-files (car dirs) nil "^[^\\.]")))
       (setq ret-val (append ret-val
                            (list (cons
                                   (car dirs)
                            (elmo-cache-make-file-entity x (car dirs)))
                          (directory-files (car dirs) nil "^[^\\.]")))
       (setq ret-val (append ret-val
                            (list (cons
                                   (car dirs)
-                                  (sort 
+                                  (sort
                                    elist
                                    (lambda (x y)
                                      (< (cdr x)
                                         (cdr y))))))))
                                    elist
                                    (lambda (x y)
                                      (< (cdr x)
                                         (cdr y))))))))
-      (setq i (+ i 1))
-      (elmo-display-progress
-       'elmo-cache-get-sorted-cache-file-list "Collecting cache info..."
-       (/ (* i 100) num))
+      (when (> num elmo-display-progress-threshold)
+       (setq i (+ i 1))
+       (elmo-display-progress
+        'elmo-cache-get-sorted-cache-file-list "Collecting cache info..."
+        (/ (* i 100) num)))
       (setq dirs (cdr dirs)))
       (setq dirs (cdr dirs)))
+    (message "Collecting cache info...done")
     ret-val))
 
 (defun elmo-cache-expire-by-age (&optional days)
   (let ((age (or (and days (int-to-string days))
                 (and (interactive-p)
     ret-val))
 
 (defun elmo-cache-expire-by-age (&optional days)
   (let ((age (or (and days (int-to-string days))
                 (and (interactive-p)
-                     (read-from-minibuffer 
+                     (read-from-minibuffer
                       (format "Enter days (%s): "
                               elmo-cache-expire-default-age)))
                 (int-to-string elmo-cache-expire-default-age)))
                       (format "Enter days (%s): "
                               elmo-cache-expire-default-age)))
                 (int-to-string elmo-cache-expire-default-age)))
-       (dirs (directory-files 
-              (expand-file-name elmo-cache-dirname elmo-msgdb-dir) 
+       (dirs (directory-files
+              (expand-file-name elmo-cache-dirname elmo-msgdb-dir)
               t "^[^\\.]"))
        (locked (elmo-dop-lock-list-load))
        (count 0)
               t "^[^\\.]"))
        (locked (elmo-dop-lock-list-load))
        (count 0)
@@ -227,7 +224,7 @@ If KBYTES is kilo bytes (This value must be float)."
        (setq age elmo-cache-expire-default-age)
       (setq age (string-to-int age)))
     (setq curtime (current-time))
        (setq age elmo-cache-expire-default-age)
       (setq age (string-to-int age)))
     (setq curtime (current-time))
-    (setq curtime (+ (* (nth 0 curtime) 
+    (setq curtime (+ (* (nth 0 curtime)
                        (float 65536)) (nth 1 curtime)))
     (while dirs
       (let ((files (directory-files (car dirs) t "^[^\\.]"))
                        (float 65536)) (nth 1 curtime)))
     (while dirs
       (let ((files (directory-files (car dirs) t "^[^\\.]"))
@@ -242,22 +239,22 @@ If KBYTES is kilo bytes (This value must be float)."
       (setq dirs (cdr dirs)))))
 
 (defun elmo-cache-save (msgid partial folder number &optional inbuf)
       (setq dirs (cdr dirs)))))
 
 (defun elmo-cache-save (msgid partial folder number &optional inbuf)
-  "If partial is non-nil, save current buffer (or INBUF) as partial cache."
+  "If PARTIAL is non-nil, save current buffer (or INBUF) as partial cache."
   (condition-case nil
   (condition-case nil
-  (save-excursion
-    (let* ((path (if partial
-                    (elmo-cache-get-path msgid folder number)
-                  (elmo-cache-get-path msgid)))
-          dir tmp-buf)
-      (when path 
-       (setq dir (directory-file-name (file-name-directory path)))
-       (if (not (file-exists-p dir))
-           (elmo-make-directory dir))
-       (if inbuf (set-buffer inbuf))
-       (goto-char (point-min))
-       (as-binary-output-file (write-region (point-min) (point-max)
-                                            path nil 'no-msg)))))
-  (error)))
+      (save-excursion
+       (let* ((path (if partial
+                        (elmo-cache-get-path msgid folder number)
+                      (elmo-cache-get-path msgid)))
+              dir tmp-buf)
+         (when path
+           (setq dir (directory-file-name (file-name-directory path)))
+           (if (not (file-exists-p dir))
+               (elmo-make-directory dir))
+           (if inbuf (set-buffer inbuf))
+           (goto-char (point-min))
+           (as-binary-output-file (write-region (point-min) (point-max)
+                                                path nil 'no-msg)))))
+    (error)))
 
 (defun elmo-cache-exists-p (msgid &optional folder number)
   "Returns the path if the cache exists."
 
 (defun elmo-cache-exists-p (msgid &optional folder number)
   "Returns the path if the cache exists."
@@ -269,8 +266,8 @@ If KBYTES is kilo bytes (This value must be float)."
              (if (and folder
                       (file-directory-p path))
                  (if (file-exists-p (setq path (expand-file-name
              (if (and folder
                       (file-directory-p path))
                  (if (file-exists-p (setq path (expand-file-name
-                                                (format "%s@%s" 
-                                                        (or number "") 
+                                                (format "%s@%s"
+                                                        (or number "")
                                                         (elmo-safe-filename
                                                          folder))
                                                 path)))
                                                         (elmo-safe-filename
                                                          folder))
                                                 path)))
@@ -282,30 +279,36 @@ If KBYTES is kilo bytes (This value must be float)."
 (defun elmo-cache-search-all (folder condition from-msgs)
   (let* ((number-alist (elmo-msgdb-number-load
                        (elmo-msgdb-expand-path folder)))
 (defun elmo-cache-search-all (folder condition from-msgs)
   (let* ((number-alist (elmo-msgdb-number-load
                        (elmo-msgdb-expand-path folder)))
-        (nalist number-alist)
+        (number-list (or from-msgs (mapcar 'car number-alist)))
         (num (length number-alist))
         cache-file
         ret-val
         case-fold-search msg
         percent i)
         (num (length number-alist))
         cache-file
         ret-val
         case-fold-search msg
         percent i)
-    (setq i 0)    
-    (while nalist
-      (if (and (setq cache-file (elmo-cache-exists-p (cdr (car nalist))
-                                                    folder 
-                                                    (car (car nalist))))
-              (elmo-file-field-condition-match cache-file condition))
-         (setq ret-val (append ret-val (list (caar nalist)))))
-      (setq i (1+ i))
-      (setq percent (/ (* i 100) num))
-      (elmo-display-progress
-       'elmo-cache-search-all "Searching..."
-       percent)
-      (setq nalist (cdr nalist)))
+    (setq i 0)
+    (while number-alist
+      (if (and (memq (car (car number-alist)) number-list)
+              (setq cache-file (elmo-cache-exists-p (cdr (car
+                                                          number-alist))
+                                                    folder
+                                                    (car (car
+                                                          number-alist))))
+              (elmo-file-field-condition-match cache-file condition
+                                               (car (car number-alist))
+                                               number-list))
+         (setq ret-val (append ret-val (list (caar number-alist)))))
+      (when (> num elmo-display-progress-threshold)
+       (setq i (1+ i))
+       (setq percent (/ (* i 100) num))
+       (elmo-display-progress
+        'elmo-cache-search-all "Searching..."
+        percent))
+      (setq number-alist (cdr number-alist)))
     ret-val))
 
 (defun elmo-cache-collect-sub-directories (init dir &optional recursively)
     ret-val))
 
 (defun elmo-cache-collect-sub-directories (init dir &optional recursively)
-  "Collect subdirectories under 'dir'"
-  (let ((dirs 
+  "Collect subdirectories under DIR."
+  (let ((dirs
         (delete (expand-file-name elmo-cache-dirname
                                   elmo-msgdb-dir)
                 (directory-files dir t "^[^\\.]")))
         (delete (expand-file-name elmo-cache-dirname
                                   elmo-msgdb-dir)
                 (directory-files dir t "^[^\\.]")))
@@ -314,14 +317,14 @@ If KBYTES is kilo bytes (This value must be float)."
     (setq ret-val (append init dirs))
     (while (and recursively dirs)
       (setq ret-val
     (setq ret-val (append init dirs))
     (while (and recursively dirs)
       (setq ret-val
-           (elmo-cache-collect-sub-directories 
+           (elmo-cache-collect-sub-directories
             ret-val
             (car dirs) recursively))
       (setq dirs (cdr dirs)))
     ret-val))
 
 (defun elmo-msgid-to-cache (msgid)
             ret-val
             (car dirs) recursively))
       (setq dirs (cdr dirs)))
     ret-val))
 
 (defun elmo-msgid-to-cache (msgid)
-  (when (and msgid 
+  (when (and msgid
             (string-match "<\\(.+\\)>$" msgid))
     (elmo-replace-msgid-as-filename (elmo-match-string 1 msgid))))
 
             (string-match "<\\(.+\\)>$" msgid))
     (elmo-replace-msgid-as-filename (elmo-match-string 1 msgid))))
 
@@ -331,12 +334,12 @@ If KBYTES is kilo bytes (This value must be float)."
       (expand-file-name
        (expand-file-name
        (if folder
       (expand-file-name
        (expand-file-name
        (if folder
-           (format "%s/%s/%s@%s" 
+           (format "%s/%s/%s@%s"
                    (elmo-cache-get-path-subr msgid)
                    msgid
                    (or number "")
                    (elmo-safe-filename folder))
                    (elmo-cache-get-path-subr msgid)
                    msgid
                    (or number "")
                    (elmo-safe-filename folder))
-         (format "%s/%s" 
+         (format "%s/%s"
                  (elmo-cache-get-path-subr msgid)
                  msgid))
        (expand-file-name elmo-cache-dirname
                  (elmo-cache-get-path-subr msgid)
                  msgid))
        (expand-file-name elmo-cache-dirname
@@ -355,13 +358,13 @@ If KBYTES is kilo bytes (This value must be float)."
   
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; buffer cache module
+;; buffer cache module
 
 (defconst elmo-buffer-cache-name " *elmo cache*")
 
 (defvar elmo-buffer-cache nil
 
 (defconst elmo-buffer-cache-name " *elmo cache*")
 
 (defvar elmo-buffer-cache nil
-  "Message cache. (old ... new) order alist with association
- ((\"folder\" message \"message-id\") . cache-buffer)")
+  "Message cache.  (old ... new) order alist.
+With association ((\"folder\" message \"message-id\") . cache-buffer).")
 
 (defmacro elmo-buffer-cache-buffer-get (entry)
   (` (cdr (, entry))))
 
 (defmacro elmo-buffer-cache-buffer-get (entry)
   (` (cdr (, entry))))
@@ -391,7 +394,7 @@ If KBYTES is kilo bytes (This value must be float)."
     (setq elmo-buffer-cache (cdr top))))
 
 (defun elmo-buffer-cache-add (fld-msg-id)
     (setq elmo-buffer-cache (cdr top))))
 
 (defun elmo-buffer-cache-add (fld-msg-id)
-  "Adding (fld-msg-id . buf) to the top of \"elmo-buffer-cache\".
+  "Adding (FLD-MSG-ID . buf) to the top of `elmo-buffer-cache'.
 Returning its cache buffer."
   (let ((len (length elmo-buffer-cache))
        (buf nil))
 Returning its cache buffer."
   (let ((len (length elmo-buffer-cache))
        (buf nil))
@@ -399,6 +402,9 @@ Returning its cache buffer."
        (setq buf (get-buffer-create (format "%s%d" elmo-buffer-cache-name len)))
       (setq buf (elmo-buffer-cache-buffer-get (nth (1- len) elmo-buffer-cache)))
       (setcdr (nthcdr (- len 2) elmo-buffer-cache) nil))
        (setq buf (get-buffer-create (format "%s%d" elmo-buffer-cache-name len)))
       (setq buf (elmo-buffer-cache-buffer-get (nth (1- len) elmo-buffer-cache)))
       (setcdr (nthcdr (- len 2) elmo-buffer-cache) nil))
+    (save-excursion
+      (set-buffer buf)
+      (elmo-set-buffer-multibyte nil))
     (setq elmo-buffer-cache
          (cons (elmo-buffer-cache-entry-make fld-msg-id buf)
                elmo-buffer-cache))
     (setq elmo-buffer-cache
          (cons (elmo-buffer-cache-entry-make fld-msg-id buf)
                elmo-buffer-cache))
@@ -421,9 +427,9 @@ Returning its cache buffer."
       (setq n (1+ n))))
   (setq elmo-buffer-cache nil))
 
       (setq n (1+ n))))
   (setq elmo-buffer-cache nil))
 
-;;;
-;;; cache backend by Kenichi OKADA <okada@opaopa.org>
-;;;
+;;
+;; cache backend by Kenichi OKADA <okada@opaopa.org>
+;;
 
 (defsubst elmo-cache-get-folder-directory (spec)
   (if (file-name-absolute-p (nth 1 spec))
 
 (defsubst elmo-cache-get-folder-directory (spec)
   (if (file-name-absolute-p (nth 1 spec))
@@ -451,14 +457,14 @@ Returning its cache buffer."
   (defsubst elmo-cache-insert-header (file)
     "Insert the header of the article."
     (let ((beg 0)
   (defsubst elmo-cache-insert-header (file)
     "Insert the header of the article."
     (let ((beg 0)
-         insert-file-contents-pre-hook   ; To avoid autoconv-xmas...
+         insert-file-contents-pre-hook ; To avoid autoconv-xmas...
          insert-file-contents-post-hook
          format-alist)
       (when (file-exists-p file)
        ;; Read until header separator is found.
        (while (and (eq elmo-localdir-header-chop-length
          insert-file-contents-post-hook
          format-alist)
       (when (file-exists-p file)
        ;; Read until header separator is found.
        (while (and (eq elmo-localdir-header-chop-length
-                       (nth 1 
-                            (as-binary-input-file 
+                       (nth 1
+                            (as-binary-input-file
                              (insert-file-contents
                               file nil beg
                               (incf beg elmo-localdir-header-chop-length)))))
                              (insert-file-contents
                               file nil beg
                               (incf beg elmo-localdir-header-chop-length)))))
@@ -526,17 +532,18 @@ Returning its cache buffer."
                                  nil
                                new-mark)))
              (setq mark-alist
                                  nil
                                new-mark)))
              (setq mark-alist
-                   (elmo-msgdb-mark-append 
-                    mark-alist 
+                   (elmo-msgdb-mark-append
+                    mark-alist
                     num
                     gmark))))
                     num
                     gmark))))
-       (setq i (1+ i))
-       (setq percent (/ (* i 100) len))
-       (elmo-display-progress
-        'elmo-cache-msgdb-create-as-numlist "Creating msgdb..."
-        percent)
+       (when (> len elmo-display-progress-threshold)
+         (setq i (1+ i))
+         (setq percent (/ (* i 100) len))
+         (elmo-display-progress
+          'elmo-cache-msgdb-create-as-numlist "Creating msgdb..."
+          percent))
        (setq numlist (cdr numlist)))
        (setq numlist (cdr numlist)))
-      (message "Creating msgdb...done.")
+      (message "Creating msgdb...done")
       (list overview number-alist mark-alist))))
 
 (defalias 'elmo-cache-msgdb-create 'elmo-cache-msgdb-create-as-numlist)
       (list overview number-alist mark-alist))))
 
 (defalias 'elmo-cache-msgdb-create 'elmo-cache-msgdb-create-as-numlist)
@@ -555,7 +562,7 @@ Returning its cache buffer."
                (expand-file-name
                 (nth 1 (elmo-folder-get-spec folder))
                 (expand-file-name elmo-cache-dirname elmo-msgdb-dir)))
                (expand-file-name
                 (nth 1 (elmo-folder-get-spec folder))
                 (expand-file-name elmo-cache-dirname elmo-msgdb-dir)))
-         (if (string-match "^[+=$!]$" folder) ;; localdir, archive, localnews
+         (if (string-match "^[+=$!]$" folder) ; localdir, archive, localnews
              (setq subprefix folder)
            (setq subprefix (concat folder elmo-path-sep)))
            ;; include parent
              (setq subprefix folder)
            (setq subprefix (concat folder elmo-path-sep)))
            ;; include parent
@@ -577,10 +584,10 @@ Returning its cache buffer."
   (let* ((dir (elmo-cache-get-folder-directory spec))
         (flist (mapcar 'file-name-nondirectory
                        (elmo-delete-if 'file-directory-p
   (let* ((dir (elmo-cache-get-folder-directory spec))
         (flist (mapcar 'file-name-nondirectory
                        (elmo-delete-if 'file-directory-p
-                                       (directory-files 
+                                       (directory-files
                                         dir t "^[^@]+@[^@]+$" t))))
         (folder (concat "'cache/" (nth 1 spec)))
                                         dir t "^[^@]+@[^@]+$" t))))
         (folder (concat "'cache/" (nth 1 spec)))
-        (number-alist (or (elmo-msgdb-number-load 
+        (number-alist (or (elmo-msgdb-number-load
                            (elmo-msgdb-expand-path folder))
                           (list nil)))
         nlist)
                            (elmo-msgdb-expand-path folder))
                           (list nil)))
         nlist)
@@ -631,10 +638,10 @@ Returning its cache buffer."
     ;; return nil if failed.
     (elmo-cache-force-delete file locked)))
 
     ;; return nil if failed.
     (elmo-cache-force-delete file locked)))
 
-(defun elmo-cache-read-msg (spec number outbuf &optional set-mark)
+(defun elmo-cache-read-msg (spec number outbuf &optional msgdb unread)
   (save-excursion
     (let* ((dir (elmo-cache-get-folder-directory spec))
   (save-excursion
     (let* ((dir (elmo-cache-get-folder-directory spec))
-          (file (expand-file-name 
+          (file (expand-file-name
                  (elmo-cache-number-to-filename spec number) dir)))
       (set-buffer outbuf)
       (erase-buffer)
                  (elmo-cache-number-to-filename spec number) dir)))
       (set-buffer outbuf)
       (erase-buffer)
@@ -648,8 +655,13 @@ Returning its cache buffer."
               (mapcar '(lambda (msg) (elmo-cache-delete-msg spec msg locked))
                       msgs)))))
 
               (mapcar '(lambda (msg) (elmo-cache-delete-msg spec msg locked))
                       msgs)))))
 
-(defun elmo-cache-list-folder (spec); called by elmo-cache-search()
-  (elmo-cache-list-folder-subr spec))
+(defun elmo-cache-list-folder (spec)   ; called by elmo-cache-search()
+  (let ((killed (and elmo-use-killed-list
+                    (elmo-msgdb-killed-list-load
+                     (elmo-msgdb-expand-path spec))))
+       numbers)
+    (setq numbers (elmo-cache-list-folder-subr spec))
+    (elmo-living-messages numbers killed)))
 
 (defun elmo-cache-max-of-folder (spec)
   (elmo-cache-list-folder-subr spec t))
 
 (defun elmo-cache-max-of-folder (spec)
   (elmo-cache-list-folder-subr spec t))
@@ -676,16 +688,19 @@ Returning its cache buffer."
         (i 0) case-fold-search ret-val)
     (while msgs
       (if (elmo-file-field-condition-match
         (i 0) case-fold-search ret-val)
     (while msgs
       (if (elmo-file-field-condition-match
-          (expand-file-name 
+          (expand-file-name
            (elmo-msgid-to-cache
             (cdr (assq (car msgs) number-alist)))
            (elmo-cache-get-folder-directory spec))
            (elmo-msgid-to-cache
             (cdr (assq (car msgs) number-alist)))
            (elmo-cache-get-folder-directory spec))
-                                           condition)
+          condition
+          (car msgs)
+          msgs)
          (setq ret-val (cons (car msgs) ret-val)))
          (setq ret-val (cons (car msgs) ret-val)))
-      (setq i (1+ i))
-      (elmo-display-progress
-       'elmo-cache-search "Searching..."
-       (/ (* i 100) num))
+      (when (> num elmo-display-progress-threshold)
+       (setq i (1+ i))
+       (elmo-display-progress
+        'elmo-cache-search "Searching..."
+        (/ (* i 100) num)))
       (setq msgs (cdr msgs)))
     (nreverse ret-val)))
 
       (setq msgs (cdr msgs)))
     (nreverse ret-val)))
 
@@ -697,7 +712,7 @@ Returning its cache buffer."
        (next-num (1+ (car (elmo-cache-list-folder-subr dst-spec t))))
        (number-alist
         (elmo-msgdb-number-load
        (next-num (1+ (car (elmo-cache-list-folder-subr dst-spec t))))
        (number-alist
         (elmo-msgdb-number-load
-         (elmo-msgdb-expand-path nil src-spec))))
+         (elmo-msgdb-expand-path src-spec))))
     (if same-number (error "Not implemented"))
     (while msgs
       (elmo-copy-file
     (if same-number (error "Not implemented"))
     (while msgs
       (elmo-copy-file
@@ -707,7 +722,7 @@ Returning its cache buffer."
        (expand-file-name
        (elmo-msgid-to-cache
         (cdr (assq (if same-number (car msgs) next-num) number-alist)))
        (expand-file-name
        (elmo-msgid-to-cache
         (cdr (assq (if same-number (car msgs) next-num) number-alist)))
-        dst-dir))
+       dst-dir))
       (if (and (setq msgs (cdr msgs))
               (not same-number))
          (setq next-num (1+ next-num))))
       (if (and (setq msgs (cdr msgs))
               (not same-number))
          (setq next-num (1+ next-num))))
@@ -724,14 +739,16 @@ Returning its cache buffer."
    (elmo-cache-number-to-filename spec number)
    (elmo-cache-get-folder-directory spec)))
 
    (elmo-cache-number-to-filename spec number)
    (elmo-cache-get-folder-directory spec)))
 
-(defalias 'elmo-cache-sync-number-alist 
+(defalias 'elmo-cache-sync-number-alist
   'elmo-generic-sync-number-alist)
   'elmo-generic-sync-number-alist)
-(defalias 'elmo-cache-list-folder-unread 
+(defalias 'elmo-cache-list-folder-unread
   'elmo-generic-list-folder-unread)
 (defalias 'elmo-cache-list-folder-important
   'elmo-generic-list-folder-important)
 (defalias 'elmo-cache-commit 'elmo-generic-commit)
   'elmo-generic-list-folder-unread)
 (defalias 'elmo-cache-list-folder-important
   'elmo-generic-list-folder-important)
 (defalias 'elmo-cache-commit 'elmo-generic-commit)
+(defalias 'elmo-cache-folder-diff 'elmo-generic-folder-diff)
 
 
-(provide 'elmo-cache)
+(require 'product)
+(product-provide (provide 'elmo-cache) (require 'elmo-version))
 
 ;;; elmo-cache.el ends here
 
 ;;; elmo-cache.el ends here