* elmo2.el (elmo-move-msgs, elmo-msgdb-load, elmo-msgdb-save,
[elisp/wanderlust.git] / elmo / elmo-cache.el
index f0ea53c..8e447a0 100644 (file)
@@ -6,7 +6,6 @@
 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
 ;;         Kenichi OKADA <okada@opaopa.org>
 ;; Keywords: mail, net news
-;; Time-stamp: <00/03/01 09:57:55 teranisi>
 
 ;; 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)
-    (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))
        nil ;; Don't delete caches with mark (or locked message).
-      (if (and path 
+      (if (and path
               (file-directory-p path))
          (progn
            (mapcar 'delete-file (directory-files path t "^[^\\.]"))
   (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))
-               (when (file-exists-p (setq path2 
+               (when (file-exists-p (setq path2
                                           (expand-file-name
-                                           (format "%s@%s" 
+                                           (format "%s@%s"
                                                    number
                                                    (elmo-safe-filename
                                                     folder))
 
 (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)
      (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
@@ -134,17 +133,17 @@ If KBYTES is kilo bytes (This value must be float)."
                    (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)
-         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)))
        (if (file-directory-p cur-file)
            (setq cur-size (elmo-disk-usage cur-file))
-         (setq cur-size 
+         (setq cur-size
                (/ (float (nth 7 (file-attributes cur-file)))
                   Kbytes)))
        (when (elmo-cache-force-delete cur-file locked)
@@ -152,7 +151,7 @@ If KBYTES is kilo bytes (This value must be float)."
          (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)
@@ -163,8 +162,8 @@ If KBYTES is kilo bytes (This value must be float)."
        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)))
 ;    (prin1 firsts)
@@ -183,8 +182,8 @@ If KBYTES is kilo bytes (This value must be float)."
     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
@@ -192,33 +191,35 @@ If KBYTES is kilo bytes (This value must be float)."
     (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)
-                                  (sort 
+                                  (sort
                                    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)))
+    (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)
-                     (read-from-minibuffer 
+                     (read-from-minibuffer
                       (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)
@@ -227,7 +228,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 curtime (+ (* (nth 0 curtime) 
+    (setq curtime (+ (* (nth 0 curtime)
                        (float 65536)) (nth 1 curtime)))
     (while dirs
       (let ((files (directory-files (car dirs) t "^[^\\.]"))
@@ -249,7 +250,7 @@ If KBYTES is kilo bytes (This value must be float)."
                     (elmo-cache-get-path msgid folder number)
                   (elmo-cache-get-path msgid)))
           dir tmp-buf)
-      (when path 
+      (when path
        (setq dir (directory-file-name (file-name-directory path)))
        (if (not (file-exists-p dir))
            (elmo-make-directory dir))
@@ -269,8 +270,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
-                                                (format "%s@%s" 
-                                                        (or number "") 
+                                                (format "%s@%s"
+                                                        (or number "")
                                                         (elmo-safe-filename
                                                          folder))
                                                 path)))
@@ -282,30 +283,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)))
-        (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)
-    (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)
   "Collect subdirectories under 'dir'"
-  (let ((dirs 
+  (let ((dirs
         (delete (expand-file-name elmo-cache-dirname
                                   elmo-msgdb-dir)
                 (directory-files dir t "^[^\\.]")))
@@ -314,14 +321,14 @@ If KBYTES is kilo bytes (This value must be float)."
     (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)
-  (when (and msgid 
+  (when (and msgid
             (string-match "<\\(.+\\)>$" msgid))
     (elmo-replace-msgid-as-filename (elmo-match-string 1 msgid))))
 
@@ -331,12 +338,12 @@ If KBYTES is kilo bytes (This value must be float)."
       (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))
-         (format "%s/%s" 
+         (format "%s/%s"
                  (elmo-cache-get-path-subr msgid)
                  msgid))
        (expand-file-name elmo-cache-dirname
@@ -399,6 +406,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))
+    (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))
@@ -457,8 +467,8 @@ Returning its cache buffer."
       (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)))))
@@ -526,17 +536,18 @@ Returning its cache buffer."
                                  nil
                                new-mark)))
              (setq mark-alist
-                   (elmo-msgdb-mark-append 
-                    mark-alist 
+                   (elmo-msgdb-mark-append
+                    mark-alist
                     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)))
-      (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)
@@ -577,10 +588,10 @@ Returning its cache buffer."
   (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)))
-        (number-alist (or (elmo-msgdb-number-load 
+        (number-alist (or (elmo-msgdb-number-load
                            (elmo-msgdb-expand-path folder))
                           (list nil)))
         nlist)
@@ -634,7 +645,7 @@ Returning its cache buffer."
 (defun elmo-cache-read-msg (spec number outbuf &optional set-mark)
   (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)
@@ -649,7 +660,12 @@ Returning its cache buffer."
                       msgs)))))
 
 (defun elmo-cache-list-folder (spec); called by elmo-cache-search()
-  (elmo-cache-list-folder-subr spec))
+  (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))
@@ -676,16 +692,19 @@ Returning its cache buffer."
         (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))
-                                           condition)
+          condition
+          (car msgs)
+          msgs)
          (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)))
 
@@ -697,7 +716,7 @@ Returning its cache buffer."
        (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
@@ -724,14 +743,16 @@ Returning its cache buffer."
    (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)
-(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)
+(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