* utils/bbdb-wl.el (bbdb-wl-get-update-record): Use `with-current-buffer'.
[elisp/wanderlust.git] / wl / wl-refile.el
index 7bdb661..8155e93 100644 (file)
@@ -1,10 +1,9 @@
 ;;; wl-refile.el -- Refile modules for Wanderlust.
 
-;; Copyright 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
+;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
 
 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
 ;; Keywords: mail, net news
-;; Time-stamp: <2000-04-04 11:38:57 teranisi>
 
 ;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
 
 
 (require 'wl-vars)
 (require 'wl-util)
-(provide 'wl-refile)
-
 
 (defvar wl-refile-alist nil)
 (defvar wl-refile-alist-file-name "refile-alist")
 ;; should be renamed to "refile-from-alist"
 (defvar wl-refile-msgid-alist nil)
 (defvar wl-refile-msgid-alist-file-name "refile-msgid-alist")
+(defvar wl-refile-subject-alist nil)
+(defvar wl-refile-subject-alist-file-name "refile-subject-alist")
 
 (defvar wl-refile-alist-max-length 1000)
 
 (defun wl-refile-alist-setup ()
-  (setq wl-refile-alist
-       (elmo-object-load
-        (expand-file-name wl-refile-alist-file-name
-                          elmo-msgdb-dir)))
-  (setq wl-refile-msgid-alist
-       (elmo-object-load
-        (expand-file-name wl-refile-msgid-alist-file-name
-                          elmo-msgdb-dir))))
+  (let ((flist wl-refile-guess-functions))
+    (while flist
+      (cond
+       ((eq (car flist) 'wl-refile-guess-by-history)
+       (setq wl-refile-alist
+             (elmo-object-load
+              (expand-file-name wl-refile-alist-file-name
+                                elmo-msgdb-dir) elmo-mime-charset)))
+       ((eq (car flist) 'wl-refile-guess-by-msgid)
+       (setq wl-refile-msgid-alist
+             (elmo-object-load
+              (expand-file-name wl-refile-msgid-alist-file-name
+                                elmo-msgdb-dir) elmo-mime-charset)))
+       ((eq (car flist) 'wl-refile-guess-by-subject)
+       (setq wl-refile-subject-alist
+             (elmo-object-load
+              (expand-file-name wl-refile-subject-alist-file-name
+                                elmo-msgdb-dir) elmo-mime-charset))))
+      (setq flist (cdr flist)))))
 
-(defun wl-refile-alist-save (file-name alist)
-  (save-excursion
-    (let ((filename (expand-file-name file-name
-                                     elmo-msgdb-dir))
-         (tmp-buffer (get-buffer-create " *wl-refile-alist-tmp*")))
-      (set-buffer tmp-buffer)
-      (erase-buffer)
-      (if (> (length alist) wl-refile-alist-max-length)
-         (setcdr (nthcdr (1- wl-refile-alist-max-length) alist) nil))
-      (prin1 alist tmp-buffer)
-      (princ "\n" tmp-buffer)
-      (if (file-writable-p filename)
-         (write-region (point-min) (point-max) 
-                       filename nil 'no-msg)
-       (message (format "%s is not writable." filename)))
-      (kill-buffer tmp-buffer))))
+(defun wl-refile-alist-save ()
+  (if wl-refile-alist
+      (wl-refile-alist-save-file
+       wl-refile-alist-file-name wl-refile-alist))
+  (if wl-refile-msgid-alist
+      (wl-refile-alist-save-file
+       wl-refile-msgid-alist-file-name wl-refile-msgid-alist))
+  (if wl-refile-subject-alist
+      (wl-refile-alist-save-file
+       wl-refile-subject-alist-file-name wl-refile-subject-alist)))
+
+(defun wl-refile-alist-save-file (file-name alist)
+  (if (> (length alist) wl-refile-alist-max-length)
+      (setcdr (nthcdr (1- wl-refile-alist-max-length) alist) nil))
+  (elmo-object-save (expand-file-name file-name elmo-msgdb-dir)
+                   alist elmo-mime-charset))
 
 (defun wl-refile-learn (entity dst)
   (let (tocc-list from key hit ml)
     (setq dst (elmo-string dst))
-    (setq tocc-list 
+    (setq tocc-list
          (mapcar (function
-                  (lambda (entity) 
+                  (lambda (entity)
                     (downcase (wl-address-header-extract-address entity))))
-                 (wl-parse-addresses 
+                 (wl-parse-addresses
                   (concat
                    (elmo-msgdb-overview-entity-get-to entity) ","
                    (elmo-msgdb-overview-entity-get-cc entity)))))
     (while tocc-list
-      (if (wl-string-member 
-          (car tocc-list) 
+      (if (wl-string-member
+          (car tocc-list)
           (mapcar (function downcase) wl-subscribed-mailing-list))
          (setq ml (car tocc-list)
                tocc-list nil)
     (if ml
        (setq key ml) ; subscribed entity!!
       (or (wl-address-user-mail-address-p
-          (setq from 
-                (downcase 
+          (setq from
+                (downcase
                  (wl-address-header-extract-address
-                  (elmo-msgdb-overview-entity-get-from 
+                  (elmo-msgdb-overview-entity-get-from
                    entity)))))
-         (setq key from)))
-    (if (not ml)
-       (wl-refile-msgid-learn entity dst))
-    (if key
-       (if (setq hit (assoc key wl-refile-alist))
-           (setcdr hit dst)
-         (setq wl-refile-alist
-               (nconc wl-refile-alist (list (cons key dst))))))))
+         (setq key from))
+      (if (or wl-refile-msgid-alist
+             (memq 'wl-refile-guess-by-msgid
+                   wl-refile-guess-functions))
+         (wl-refile-msgid-learn entity dst))
+      (if (or wl-refile-subject-alist
+             (memq 'wl-refile-guess-by-subject
+                   wl-refile-guess-functions))
+         (wl-refile-subject-learn entity dst)))
+    (when key
+      (if (setq hit (assoc key wl-refile-alist))
+          (setq wl-refile-alist (delq hit wl-refile-alist)))
+      (setq wl-refile-alist (cons (cons key dst)
+                                 wl-refile-alist)))))
 
 (defun wl-refile-msgid-learn (entity dst)
   (let ((key (elmo-msgdb-overview-entity-get-id entity))
          (setq wl-refile-msgid-alist (cons (cons key dst)
                                            wl-refile-msgid-alist))))))
 
+(defun wl-refile-subject-learn (entity dst)
+  (let ((subject (wl-summary-subject-filter-func-internal
+                 (elmo-msgdb-overview-entity-get-subject entity)))
+       hit)
+    (setq dst (elmo-string dst))
+    (if (and subject (not (string= subject "")))
+       (if (setq hit (assoc subject wl-refile-subject-alist))
+           (setcdr hit dst)
+         (setq wl-refile-subject-alist (cons (cons subject dst)
+                                           wl-refile-subject-alist))))))
+
 ;;
 ;; refile guess
 ;;
-(defvar wl-refile-guess-func-list
+(defvar wl-refile-guess-functions
   '(wl-refile-guess-by-rule
     wl-refile-guess-by-msgid
+    wl-refile-guess-by-subject
     wl-refile-guess-by-history)
   "*Functions in this list are used for guessing refile destination folder.")
 
+(defvar wl-refile-guess-func-list wl-refile-guess-functions)
+(make-obsolete-variable 'wl-refile-guess-func-list 'wl-refile-guess-functions)
+
 (defun wl-refile-guess (entity)
-  (let ((flist wl-refile-guess-func-list) guess)
+  (let ((flist wl-refile-guess-functions) guess)
     (while flist
       (if (setq guess (funcall (car flist) entity))
          (setq flist nil)
     guess))
 
 (defun wl-refile-evaluate-rule (rule entity)
-  "Returns folder string if RULE is matched to ENTITY.
+  "Return folder string if RULE is matched to ENTITY.
 If RULE does not match ENTITY, returns nil."
   (let ((case-fold-search t)
        fields guess pairs value)
-    (cond 
+    (cond
      ((stringp rule) rule)
      ((listp (car rule))
       (setq fields (car rule))
@@ -156,9 +187,10 @@ If RULE does not match ENTITY, returns nil."
                 (string-match
                  (car (car pairs))
                  value)
-                (setq guess (wl-refile-expand-newtext
+                (setq guess (wl-expand-newtext
                              (wl-refile-evaluate-rule (cdr (car pairs))
-                                                      entity))))
+                                                      entity)
+                             value)))
            (setq pairs nil)
          (setq pairs (cdr pairs))))
       guess)
@@ -176,39 +208,6 @@ If RULE does not match ENTITY, returns nil."
                 entity)
       (elmo-msgdb-overview-entity-get-extra-field entity field))))
 
-(defun wl-refile-expand-newtext (newtext)
-  (let ((len (length newtext))
-       (pos 0)
-       c expanded beg N did-expand)
-    (while (< pos len)
-      (setq beg pos)
-      (while (and (< pos len)
-                 (not (= (aref newtext pos) ?\\)))
-       (setq pos (1+ pos)))
-      (unless (= beg pos)
-       (push (substring newtext beg pos) expanded))
-      (when (< pos len)
-       ;; We hit a \; expand it.
-       (setq did-expand t
-             pos (1+ pos)
-             c (aref newtext pos))
-       (if (not (or (= c ?\&)
-                    (and (>= c ?1)
-                         (<= c ?9))))
-           ;; \ followed by some character we don't expand.
-           (push (char-to-string c) expanded)
-         ;; \& or \N
-         (if (= c ?\&)
-             (setq N 0)
-           (setq N (- c ?0)))
-         (when (match-beginning N)
-           (push (buffer-substring (match-beginning N) (match-end N))
-                 expanded))))
-      (setq pos (1+ pos)))
-    (if did-expand
-       (apply (function concat) (nreverse expanded))
-      newtext)))
-
 (defun wl-refile-guess-by-rule (entity)
   (let ((rules wl-refile-rule-alist)
        guess)
@@ -219,11 +218,11 @@ If RULE does not match ENTITY, returns nil."
     guess))
 
 (defun wl-refile-guess-by-history (entity)
-  (let ((tocc-list 
+  (let ((tocc-list
         (mapcar (function
                  (lambda (entity)
                    (downcase (wl-address-header-extract-address entity))))
-                (wl-parse-addresses 
+                (wl-parse-addresses
                  (concat
                   (elmo-msgdb-overview-entity-get-to entity) ","
                   (elmo-msgdb-overview-entity-get-cc entity)))))
@@ -250,11 +249,19 @@ If RULE does not match ENTITY, returns nil."
                    (elmo-msgdb-overview-entity-get-from entity)))))
     ;; search from alist
     (or (cdr (assoc from wl-refile-alist))
-       (format "%s/%s" wl-refile-default-from-folder 
+       (format "%s/%s" wl-refile-default-from-folder
                (wl-refile-get-account-part-from-address from)))))
   
 (defun wl-refile-guess-by-msgid (entity)
   (cdr (assoc (elmo-msgdb-overview-entity-get-references entity)
              wl-refile-msgid-alist)))
 
+(defun wl-refile-guess-by-subject (entity)
+  (cdr (assoc (wl-summary-subject-filter-func-internal
+              (elmo-msgdb-overview-entity-get-subject entity))
+             wl-refile-subject-alist)))
+
+(require 'product)
+(product-provide (provide 'wl-refile) (require 'wl-version))
+
 ;;; wl-refile.el ends here