update wl-draft-reply-*-argument-list
[elisp/wanderlust.git] / wl / wl-summary.el
index 2319076..ba42408 100644 (file)
@@ -86,7 +86,7 @@
 (defvar wl-summary-buffer-mime-charset  nil)
 (defvar wl-summary-buffer-weekday-name-lang  nil)
 (defvar wl-summary-buffer-thread-indent-set-alist  nil)
 (defvar wl-summary-buffer-mime-charset  nil)
 (defvar wl-summary-buffer-weekday-name-lang  nil)
 (defvar wl-summary-buffer-thread-indent-set-alist  nil)
-(defvar wl-summary-buffer-view 'thread)
+(defvar wl-summary-buffer-view nil)
 (defvar wl-summary-buffer-message-modified nil)
 (defvar wl-summary-buffer-mark-modified nil)
 (defvar wl-summary-buffer-thread-modified nil)
 (defvar wl-summary-buffer-message-modified nil)
 (defvar wl-summary-buffer-mark-modified nil)
 (defvar wl-summary-buffer-thread-modified nil)
     subject-string))
 
 (defun wl-summary-default-from (from)
     subject-string))
 
 (defun wl-summary-default-from (from)
+  "Instance of `wl-summary-from-function'.
+Ordinarily returns the sender name. Returns recipient names if (1)
+summary's folder name matches with `wl-summary-showto-folder-regexp'
+and (2) sender address is yours.
+
+See also variable `wl-use-petname'."
   (let (retval tos ng)
     (unless
        (and (eq major-mode 'wl-summary-mode)
   (let (retval tos ng)
     (unless
        (and (eq major-mode 'wl-summary-mode)
                                 (eword-decode-string
                                  (if wl-use-petname
                                      (or
                                 (eword-decode-string
                                  (if wl-use-petname
                                      (or
-                                      (funcall wl-summary-get-petname-function to)
+                                      (funcall
+                                       wl-summary-get-petname-function to)
                                       (car
                                        (std11-extract-address-components to))
                                       to)
                                       (car
                                        (std11-extract-address-components to))
                                       to)
          string)
     string))
 
          string)
     string))
 
+(defvar wl-summary-sort-specs '(number date subject from list-info))
+(defvar wl-summary-default-sort-spec 'date)
+
 (defvar wl-summary-mode-menu-spec
   '("Summary"
     ["Read" wl-summary-read t]
 (defvar wl-summary-mode-menu-spec
   '("Summary"
     ["Read" wl-summary-read t]
      ["By Number" wl-summary-sort-by-number t]
      ["By Date" wl-summary-sort-by-date t]
      ["By From" wl-summary-sort-by-from t]
      ["By Number" wl-summary-sort-by-number t]
      ["By Date" wl-summary-sort-by-date t]
      ["By From" wl-summary-sort-by-from t]
-     ["By Subject" wl-summary-sort-by-subject t])
+     ["By Subject" wl-summary-sort-by-subject t]
+     ["By List Info" wl-summary-sort-by-list-info t])
     "----"
     ("Message Operation"
      ["Mark as read"    wl-summary-mark-as-read t]
     "----"
     ("Message Operation"
      ["Mark as read"    wl-summary-mark-as-read t]
   (define-key wl-summary-mode-map "g"    'wl-summary-goto-folder)
   (define-key wl-summary-mode-map "G"    'wl-summary-goto-folder-sticky)
   (define-key wl-summary-mode-map "c"    'wl-summary-mark-as-read-all)
   (define-key wl-summary-mode-map "g"    'wl-summary-goto-folder)
   (define-key wl-summary-mode-map "G"    'wl-summary-goto-folder-sticky)
   (define-key wl-summary-mode-map "c"    'wl-summary-mark-as-read-all)
-;  (define-key wl-summary-mode-map "D"    'wl-summary-drop-unsync)
 
   (define-key wl-summary-mode-map "a"    'wl-summary-reply)
   (define-key wl-summary-mode-map "A"    'wl-summary-reply-with-citation)
 
   (define-key wl-summary-mode-map "a"    'wl-summary-reply)
   (define-key wl-summary-mode-map "A"    'wl-summary-reply-with-citation)
   (define-key wl-summary-mode-map "p"    'wl-summary-prev)
   (define-key wl-summary-mode-map "N"    'wl-summary-down)
   (define-key wl-summary-mode-map "P"    'wl-summary-up)
   (define-key wl-summary-mode-map "p"    'wl-summary-prev)
   (define-key wl-summary-mode-map "N"    'wl-summary-down)
   (define-key wl-summary-mode-map "P"    'wl-summary-up)
-;;;(define-key wl-summary-mode-map "w"    'wl-draft)
   (define-key wl-summary-mode-map "w"    'wl-summary-write)
   (define-key wl-summary-mode-map "W"    'wl-summary-write-current-folder)
   (define-key wl-summary-mode-map "w"    'wl-summary-write)
   (define-key wl-summary-mode-map "W"    'wl-summary-write-current-folder)
-;;;(define-key wl-summary-mode-map "e"     'wl-draft-open-file)
   (define-key wl-summary-mode-map "e"     'wl-summary-save)
   (define-key wl-summary-mode-map "\C-c\C-o" 'wl-jump-to-draft-buffer)
   (define-key wl-summary-mode-map "\C-c\C-a" 'wl-addrmgr)
   (define-key wl-summary-mode-map "e"     'wl-summary-save)
   (define-key wl-summary-mode-map "\C-c\C-o" 'wl-jump-to-draft-buffer)
   (define-key wl-summary-mode-map "\C-c\C-a" 'wl-addrmgr)
   (define-key wl-summary-mode-map "d"    'wl-summary-delete)
   (define-key wl-summary-mode-map "u"    'wl-summary-unmark)
   (define-key wl-summary-mode-map "U"    'wl-summary-unmark-all)
   (define-key wl-summary-mode-map "d"    'wl-summary-delete)
   (define-key wl-summary-mode-map "u"    'wl-summary-unmark)
   (define-key wl-summary-mode-map "U"    'wl-summary-unmark-all)
+  (define-key wl-summary-mode-map "D"    'wl-summary-erase)
 
   ;; thread commands
   (define-key wl-summary-mode-map "t"  (make-sparse-keymap))
 
   ;; thread commands
   (define-key wl-summary-mode-map "t"  (make-sparse-keymap))
   (define-key wl-summary-mode-map "m?"   'wl-summary-target-mark-pick)
   (define-key wl-summary-mode-map "m#"   'wl-summary-target-mark-print)
   (define-key wl-summary-mode-map "m|"   'wl-summary-target-mark-pipe)
   (define-key wl-summary-mode-map "m?"   'wl-summary-target-mark-pick)
   (define-key wl-summary-mode-map "m#"   'wl-summary-target-mark-print)
   (define-key wl-summary-mode-map "m|"   'wl-summary-target-mark-pipe)
+  (define-key wl-summary-mode-map "mD"   'wl-summary-target-mark-erase)
 
   ;; region commands
   (define-key wl-summary-mode-map "r"    (make-sparse-keymap))
 
   ;; region commands
   (define-key wl-summary-mode-map "r"    (make-sparse-keymap))
 (defun wl-summary-display-top ()
   (interactive)
   (goto-char (point-min))
 (defun wl-summary-display-top ()
   (interactive)
   (goto-char (point-min))
+  (when wl-summary-lazy-highlight
+    (wl-highlight-summary-window))
   (if wl-summary-buffer-disp-msg
       (wl-summary-redisplay)))
 
   (if wl-summary-buffer-disp-msg
       (wl-summary-redisplay)))
 
   (interactive)
   (goto-char (point-max))
   (forward-line -1)
   (interactive)
   (goto-char (point-max))
   (forward-line -1)
+  (when wl-summary-lazy-highlight
+    (wl-highlight-summary-window))
   (if wl-summary-buffer-disp-msg
       (wl-summary-redisplay)))
 
   (if wl-summary-buffer-disp-msg
       (wl-summary-redisplay)))
 
@@ -596,16 +610,15 @@ If optional USE-CACHE is non-nil, use cache if exists."
   "Re-edit current message.
 If ARG is non-nil, Supersedes message"
   (interactive "P")
   "Re-edit current message.
 If ARG is non-nil, Supersedes message"
   (interactive "P")
+  (wl-summary-toggle-disp-msg 'off)
   (if arg
       (wl-summary-supersedes-message)
     (if (string= (wl-summary-buffer-folder-name) wl-draft-folder)
   (if arg
       (wl-summary-supersedes-message)
     (if (string= (wl-summary-buffer-folder-name) wl-draft-folder)
-       (if (wl-summary-message-number)
-           (progn
-             (wl-draft-reedit (wl-summary-message-number))
-             (if (wl-message-news-p)
-                 (mail-position-on-field "Newsgroups")
-               (mail-position-on-field "To"))
-             (delete-other-windows)))
+       (when (wl-summary-message-number)
+         (wl-draft-reedit (wl-summary-message-number))
+         (if (wl-message-news-p)
+             (mail-position-on-field "Newsgroups")
+           (mail-position-on-field "To")))
       (wl-draft-edit-string (wl-summary-message-string)))))
 
 (defun wl-summary-resend-bounced-mail ()
       (wl-draft-edit-string (wl-summary-message-string)))))
 
 (defun wl-summary-resend-bounced-mail ()
@@ -614,6 +627,7 @@ This only makes sense if the current message is a bounce message which
 contains some mail you have written but has been bounced back to
 you."
   (interactive)
 contains some mail you have written but has been bounced back to
 you."
   (interactive)
+  (wl-summary-toggle-disp-msg 'off)
   (save-excursion
     (wl-summary-set-message-buffer-or-redisplay)
     (set-buffer (wl-message-get-original-buffer))
   (save-excursion
     (wl-summary-set-message-buffer-or-redisplay)
     (set-buffer (wl-message-get-original-buffer))
@@ -632,7 +646,7 @@ you."
                              (concat "^--" boundary "\n"
                                      "\\([Cc]ontent-[Dd]escription:.*\n\\)?"
                                      "[Cc]ontent-[Tt]ype:[ \t]+"
                              (concat "^--" boundary "\n"
                                      "\\([Cc]ontent-[Dd]escription:.*\n\\)?"
                                      "[Cc]ontent-[Tt]ype:[ \t]+"
-                                     "\\(message/rfc822\\|text/rfc822-headers\\)\n"
+                                     "\\(message/rfc822\\|text/rfc822-headers\\).*\n"
                                      "\\(.+\n\\)*\n") nil t))
                 (re-search-forward
                  (concat "\n\\(--" boundary "\\)--\n") nil t))
                                      "\\(.+\n\\)*\n") nil t))
                 (re-search-forward
                  (concat "\n\\(--" boundary "\\)--\n") nil t))
@@ -786,13 +800,6 @@ you."
    wl-thread-space-str-internal
    (or (nth 5 wl-summary-buffer-thread-indent-set)
        wl-thread-space-str))
    wl-thread-space-str-internal
    (or (nth 5 wl-summary-buffer-thread-indent-set)
        wl-thread-space-str))
-  (setq wl-thread-indent-regexp
-       (concat
-        (regexp-quote wl-thread-have-younger-brother-str-internal) "\\|"
-        (regexp-quote wl-thread-youngest-child-str-internal) "\\|"
-        (regexp-quote wl-thread-vertical-str-internal) "\\|"
-        (regexp-quote wl-thread-horizontal-str-internal) "\\|"
-        (regexp-quote wl-thread-space-str-internal)))
   (run-hooks 'wl-summary-buffer-set-folder-hook))
 
 (defun wl-summary-mode ()
   (run-hooks 'wl-summary-buffer-set-folder-hook))
 
 (defun wl-summary-mode ()
@@ -860,6 +867,60 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
   (string< (elmo-msgdb-overview-entity-get-subject-no-decode x)
           (elmo-msgdb-overview-entity-get-subject-no-decode y)))
 
   (string< (elmo-msgdb-overview-entity-get-subject-no-decode x)
           (elmo-msgdb-overview-entity-get-subject-no-decode y)))
 
+(defun wl-summary-get-list-info (entity)
+  "Returns (\"ML-name\" . ML-count) of ENTITY."
+  (let (sequence ml-name ml-count subject return-path delivered-to mailing-list)
+    (setq sequence (elmo-msgdb-overview-entity-get-extra-field
+                   entity "x-sequence")
+         ml-name (or (elmo-msgdb-overview-entity-get-extra-field
+                      entity "x-ml-name")
+                     (and sequence
+                          (car (split-string sequence " "))))
+         ml-count (or (elmo-msgdb-overview-entity-get-extra-field
+                       entity "x-mail-count")
+                      (elmo-msgdb-overview-entity-get-extra-field
+                       entity "x-ml-count")
+                      (and sequence
+                           (cadr (split-string sequence " ")))))
+    (and (setq subject (elmo-msgdb-overview-entity-get-subject
+                       entity))
+        (setq subject (elmo-delete-char ?\n subject))
+        (string-match "^\\s(\\(\\S)+\\)[ :]\\([0-9]+\\)\\s)[ \t]*" subject)
+        (progn
+          (or ml-name (setq ml-name (match-string 1 subject)))
+          (or ml-count (setq ml-count (match-string 2 subject)))))
+    (and (setq return-path
+              (elmo-msgdb-overview-entity-get-extra-field
+               entity "return-path"))
+        (string-match "^<\\([^@>]+\\)-return-\\([0-9]+\\)-" return-path)
+        (progn
+          (or ml-name (setq ml-name (match-string 1 return-path)))
+          (or ml-count (setq ml-count (match-string 2 return-path)))))
+    (and (setq delivered-to
+              (elmo-msgdb-overview-entity-get-extra-field
+               entity "delivered-to"))
+        (string-match "^mailing list \\([^@]+\\)@" delivered-to)
+        (or ml-name (setq ml-name (match-string 1 delivered-to))))
+    (and (setq mailing-list
+              (elmo-msgdb-overview-entity-get-extra-field
+               entity "mailing-list"))
+        (string-match "\\(^\\|; \\)contact \\([^@]+\\)-[^-@]+@" mailing-list)  ; *-help@, *-owner@, etc.
+        (or ml-name (setq ml-name (match-string 2 mailing-list))))
+    (cons (and ml-name (car (split-string ml-name " ")))
+         (and ml-count (string-to-int ml-count)))))
+
+(defun wl-summary-overview-entity-compare-by-list-info (x y)
+  "Compare entity X and Y by mailing-list info."
+  (let* ((list-info-x (wl-summary-get-list-info x))
+        (list-info-y (wl-summary-get-list-info y)))
+    (if (equal (car list-info-x) (car list-info-y))
+       (if (equal (cdr list-info-x) (cdr list-info-y))
+           (wl-summary-overview-entity-compare-by-date x y)
+         (< (or (cdr list-info-x) 0)
+            (or (cdr list-info-y) 0)))
+      (string< (or (car list-info-x) "")
+              (or (car list-info-y) "")))))
+
 (defun wl-summary-sort-by-date ()
   (interactive)
   (wl-summary-rescan "date"))
 (defun wl-summary-sort-by-date ()
   (interactive)
   (wl-summary-rescan "date"))
@@ -872,6 +933,9 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
 (defun wl-summary-sort-by-from ()
   (interactive)
   (wl-summary-rescan "from"))
 (defun wl-summary-sort-by-from ()
   (interactive)
   (wl-summary-rescan "from"))
+(defun wl-summary-sort-by-list-info ()
+  (interactive)
+  (wl-summary-rescan "list-info"))
 
 (defun wl-summary-rescan (&optional sort-by)
   "Rescan current folder without updating."
 
 (defun wl-summary-rescan (&optional sort-by)
   "Rescan current folder without updating."
@@ -913,7 +977,6 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
     (setq wl-summary-buffer-delete-list nil)
     (setq wl-summary-delayed-update nil)
     (elmo-kill-buffer wl-summary-search-buf-name)
     (setq wl-summary-buffer-delete-list nil)
     (setq wl-summary-delayed-update nil)
     (elmo-kill-buffer wl-summary-search-buf-name)
-    (message "Constructing summary structure...")
     (while curp
       (setq entity (car curp))
       (wl-summary-append-message-func-internal entity msgdb nil)
     (while curp
       (setq entity (car curp))
       (wl-summary-append-message-func-internal entity msgdb nil)
@@ -1020,7 +1083,8 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
   (if (or wl-summary-buffer-refile-list
          wl-summary-buffer-copy-list
          wl-summary-buffer-delete-list)
   (if (or wl-summary-buffer-refile-list
          wl-summary-buffer-copy-list
          wl-summary-buffer-delete-list)
-      (if (y-or-n-p "Marks remain to be executed.  Execute them? ")
+      (if (y-or-n-p (format "Execute remaining marks in %s? "
+                           (wl-summary-buffer-folder-name)))
          (progn
            (wl-summary-exec)
            (if (or wl-summary-buffer-refile-list
          (progn
            (wl-summary-exec)
            (if (or wl-summary-buffer-refile-list
@@ -1059,7 +1123,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
   (elmo-folder-commit wl-summary-buffer-elmo-folder)
   (elmo-folder-check wl-summary-buffer-elmo-folder)
   (if wl-use-scoring (wl-score-save))
   (elmo-folder-commit wl-summary-buffer-elmo-folder)
   (elmo-folder-check wl-summary-buffer-elmo-folder)
   (if wl-use-scoring (wl-score-save))
-  (if (interactive-p) (message "Saving summary status...done.")))
+  (if (interactive-p) (message "Saving summary status...done")))
 
 (defun wl-summary-force-exit ()
   "Exit current summary.  Buffer is deleted even the buffer is sticky."
 
 (defun wl-summary-force-exit ()
   "Exit current summary.  Buffer is deleted even the buffer is sticky."
@@ -1326,13 +1390,15 @@ If ARG is non-nil, checking is omitted."
           (number-alist (elmo-msgdb-get-number-alist msgdb))
           (message-id (cdr (assq number number-alist)))
           (ov (elmo-msgdb-overview-get-entity message-id msgdb))
           (number-alist (elmo-msgdb-get-number-alist msgdb))
           (message-id (cdr (assq number number-alist)))
           (ov (elmo-msgdb-overview-get-entity message-id msgdb))
-          (entity ov)
+          (wl-message-entity ov)
+          (entity ov)                  ; backward compatibility.
           (size (elmo-msgdb-overview-entity-get-size ov))
           (inhibit-read-only t)
           (buffer-read-only nil)
           (file-cached (elmo-file-cache-exists-p message-id))
           (force-read (and size
           (size (elmo-msgdb-overview-entity-get-size ov))
           (inhibit-read-only t)
           (buffer-read-only nil)
           (file-cached (elmo-file-cache-exists-p message-id))
           (force-read (and size
-                           (or (null wl-prefetch-threshold)
+                           (or (and (null wl-prefetch-confirm) arg)
+                               (null wl-prefetch-threshold)
                                (< size wl-prefetch-threshold))))
           mark new-mark)
       (unwind-protect
                                (< size wl-prefetch-threshold))))
           mark new-mark)
       (unwind-protect
@@ -1510,15 +1576,11 @@ If ARG is non-nil, checking is omitted."
          (insert " "))
        (forward-line 1)))))
 
          (insert " "))
        (forward-line 1)))))
 
-;; Does not work correctly...
 (defun wl-summary-mark-as-read-region (beg end)
   (interactive "r")
   (save-excursion
     (save-restriction
       (narrow-to-region beg end)
 (defun wl-summary-mark-as-read-region (beg end)
   (interactive "r")
   (save-excursion
     (save-restriction
       (narrow-to-region beg end)
-;;; use narrowing.
-;;;   (save-excursion (goto-char end)
-;;;                  (end-of-line) (point)))
       (goto-char (point-min))
       (if (eq wl-summary-buffer-view 'thread)
          (progn
       (goto-char (point-min))
       (if (eq wl-summary-buffer-view 'thread)
          (progn
@@ -1528,17 +1590,16 @@ If ARG is non-nil, checking is omitted."
                     children)
                (if (wl-thread-entity-get-opened entity)
                    ;; opened...mark line.
                     children)
                (if (wl-thread-entity-get-opened entity)
                    ;; opened...mark line.
-                   ;; Crossposts are not processed
-                   (wl-summary-mark-as-read t)
+                   (wl-summary-mark-as-read number)
                  ;; closed
                  ;; closed
-                 (wl-summary-mark-as-read t) ; mark itself.
+                 (wl-summary-mark-as-read number) ; mark itself.
                  (setq children (wl-thread-get-children-msgs number))
                  (while children
                  (setq children (wl-thread-get-children-msgs number))
                  (while children
-                   (wl-summary-mark-as-read t nil nil (car children))
+                   (wl-summary-mark-as-read (car children))
                    (setq children (cdr children))))
                (forward-line 1))))
        (while (not (eobp))
                    (setq children (cdr children))))
                (forward-line 1))))
        (while (not (eobp))
-         (wl-summary-mark-as-read t)
+         (wl-summary-mark-as-read (wl-summary-message-number))
          (forward-line 1)))))
   (wl-summary-count-unread)
   (wl-summary-update-modeline))
          (forward-line 1)))))
   (wl-summary-count-unread)
   (wl-summary-update-modeline))
@@ -1829,21 +1890,13 @@ If ARG is non-nil, checking is omitted."
 
 (defun wl-summary-sort ()
   (interactive)
 
 (defun wl-summary-sort ()
   (interactive)
-  (let ((sort-by (let ((input-range-list '("number" "date" "subject" "from"))
-                      (default "date")
-                      in)
-                  (setq in
-                        (completing-read
-                         (format "Sort by (%s): " default)
-                         (mapcar
-                          (function (lambda (x) (cons x x)))
-                          input-range-list)))
-                  (if (string= in "")
-                      default
-                    in))))
-    (if (not (member sort-by '("number" "date" "subject" "from")))
-       (error "Sort by %s is not implemented"  sort-by))
-    (wl-summary-rescan sort-by)))
+  (wl-summary-rescan
+   (completing-read
+    (format "Sort by (%s): " (symbol-name wl-summary-default-sort-spec))
+    (mapcar (lambda (spec)
+             (list (symbol-name spec)))
+           wl-summary-sort-specs)
+    nil t nil nil (symbol-name wl-summary-default-sort-spec))))
 
 (defun wl-summary-sync-marks ()
   "Update marks in summary."
 
 (defun wl-summary-sync-marks ()
   "Update marks in summary."
@@ -1890,7 +1943,7 @@ If ARG is non-nil, checking is omitted."
       (setq diffs (cadr diff))
       (setq mes (concat mes (format "(-%d" (length diffs))))
       (while diffs
       (setq diffs (cadr diff))
       (setq mes (concat mes (format "(-%d" (length diffs))))
       (while diffs
-       (wl-summary-mark-as-read t 'no-server nil (car diffs))
+       (wl-summary-mark-as-read (car diffs) 'no-folder)
        (setq diffs (cdr diffs)))
       (setq diffs (car diff)) ; unread-appends
       (setq mes (concat mes (format "/+%d) unread mark(s)." (length diffs))))
        (setq diffs (cdr diffs)))
       (setq diffs (car diff)) ; unread-appends
       (setq mes (concat mes (format "/+%d) unread mark(s)." (length diffs))))
@@ -2012,7 +2065,6 @@ If ARG is non-nil, checking is omitted."
                (when (and sync-all (eq wl-summary-buffer-view 'thread))
                  (elmo-kill-buffer wl-summary-search-buf-name)
                  (message "Inserting thread...")
                (when (and sync-all (eq wl-summary-buffer-view 'thread))
                  (elmo-kill-buffer wl-summary-search-buf-name)
                  (message "Inserting thread...")
-                 (setq wl-thread-entity-cur 0)
                  (wl-thread-insert-top)
                  (message "Inserting thread...done"))
                (if elmo-use-database
                  (wl-thread-insert-top)
                  (message "Inserting thread...done"))
                (if elmo-use-database
@@ -2417,9 +2469,14 @@ If ARG, without confirm."
                    (decode-mime-charset-region
                     (point-min)(point-max)
                     wl-summary-buffer-mime-charset 'LF))
                    (decode-mime-charset-region
                     (point-min)(point-max)
                     wl-summary-buffer-mime-charset 'LF))
-                 (when (file-exists-p view)
+                 (if (file-exists-p view)
+                     (setq wl-summary-buffer-view
+                           (wl-summary-load-file-object view))
                    (setq wl-summary-buffer-view
                    (setq wl-summary-buffer-view
-                         (wl-summary-load-file-object view)))
+                         (or (wl-get-assoc-list-value
+                              wl-summary-default-view-alist
+                              (elmo-folder-name-internal folder))
+                             wl-summary-default-view)))
                  (wl-thread-resume-entity folder)
                  (wl-summary-open-folder folder))
              (setq wl-summary-buffer-view
                  (wl-thread-resume-entity folder)
                  (wl-summary-open-folder folder))
              (setq wl-summary-buffer-view
@@ -2432,9 +2489,10 @@ If ARG, without confirm."
            (wl-summary-update-modeline)))
       (unless (eq wl-summary-buffer-view 'thread)
        (wl-summary-make-number-list))
            (wl-summary-update-modeline)))
       (unless (eq wl-summary-buffer-view 'thread)
        (wl-summary-make-number-list))
-      (when (or (and wl-summary-check-line-format
-                    (wl-summary-line-format-changed-p))
-               (wl-summary-view-old-p))
+      (when (and wl-summary-cache-use
+                (or (and wl-summary-check-line-format
+                         (wl-summary-line-format-changed-p))
+                    (wl-summary-view-old-p)))
        (wl-summary-rescan))
       (wl-summary-toggle-disp-msg (if wl-summary-buffer-disp-msg 'on 'off))
       (unless (and reuse-buf keep-cursor)
        (wl-summary-rescan))
       (wl-summary-toggle-disp-msg (if wl-summary-buffer-disp-msg 'on 'off))
       (unless (and reuse-buf keep-cursor)
@@ -2614,7 +2672,7 @@ If ARG, without confirm."
       (setq this (funcall func ov))
       (and this (setq this (std11-unfold-string this)))
       (if (equal last this)
       (setq this (funcall func ov))
       (and this (setq this (std11-unfold-string this)))
       (if (equal last this)
-         (wl-append alike (list ov))
+         (setq alike (cons ov alike))
        (when last
          (wl-summary-put-alike alike)
          (insert last ?\n))
        (when last
          (wl-summary-put-alike alike)
          (insert last ?\n))
@@ -2634,47 +2692,53 @@ If ARG, without confirm."
   (let ((summary-buf (current-buffer))
        (buf (get-buffer-create wl-summary-search-buf-name))
        (folder-name (wl-summary-buffer-folder-name))
   (let ((summary-buf (current-buffer))
        (buf (get-buffer-create wl-summary-search-buf-name))
        (folder-name (wl-summary-buffer-folder-name))
-       match founds found-entity)
+       match founds cur result)
     (with-current-buffer buf
       (let ((case-fold-search t))
        (when (or (not (string= wl-summary-search-buf-folder-name folder-name))
                  (zerop (buffer-size)))
          (setq wl-summary-search-buf-folder-name folder-name)
     (with-current-buffer buf
       (let ((case-fold-search t))
        (when (or (not (string= wl-summary-search-buf-folder-name folder-name))
                  (zerop (buffer-size)))
          (setq wl-summary-search-buf-folder-name folder-name)
+         (message "Creating subject cache...")
          (wl-summary-insert-headers
           overview
           (function
            (lambda (x)
              (funcall wl-summary-subject-filter-function
          (wl-summary-insert-headers
           overview
           (function
            (lambda (x)
              (funcall wl-summary-subject-filter-function
-              (elmo-msgdb-overview-entity-get-subject-no-decode x))))
-          t))
+                      (elmo-msgdb-overview-entity-get-subject-no-decode x))))
+          t)
+         (message "Creating subject cache...done"))
        (setq match (funcall wl-summary-subject-filter-function
                             (elmo-msgdb-overview-entity-get-subject entity)))
        (if (string= match "")
            (setq match "\n"))
        (setq match (funcall wl-summary-subject-filter-function
                             (elmo-msgdb-overview-entity-get-subject entity)))
        (if (string= match "")
            (setq match "\n"))
-       (goto-char (point-min))
-       (while (and (not founds)
-                   (not (= (point) (point-max)))
-                   (search-forward match nil t))
+       (goto-char (point-max))
+       (while (and (null result)
+                   (not (= (point) (point-min)))
+                   (search-backward match nil t))
          ;; check exactly match
          ;; check exactly match
-         (when (and (eolp)
-                    (= (point-at-bol)
-                       (match-beginning 0)))
-           (setq found-entity (wl-summary-get-alike))
-           (if (and found-entity
-                    ;; Is founded entity myself or children?
-                    (not (string=
-                          (elmo-msgdb-overview-entity-get-id entity)
-                          (elmo-msgdb-overview-entity-get-id
-                           (car found-entity))))
-                    (with-current-buffer summary-buf
+         (when (and (bolp) (= (point-at-eol)(match-end 0)))
+           (setq founds (wl-summary-get-alike))
+           (with-current-buffer summary-buf
+             (while founds
+               (when (and
+                      ;; the first element of found-entity list exists on
+                      ;; thread tree.
+                      (wl-thread-get-entity
+                       (elmo-msgdb-overview-entity-get-number
+                        (car founds)))
+                      ;; message id is not same as myself.
+                      (not (string=
+                            (elmo-msgdb-overview-entity-get-id entity)
+                            (elmo-msgdb-overview-entity-get-id (car founds))))
+                      ;; not a descendant.
                       (not (wl-thread-descendant-p
                             (elmo-msgdb-overview-entity-get-number entity)
                             (elmo-msgdb-overview-entity-get-number
                       (not (wl-thread-descendant-p
                             (elmo-msgdb-overview-entity-get-number entity)
                             (elmo-msgdb-overview-entity-get-number
-                             (car found-entity))))))
-               ;; return matching entity
-               (setq founds found-entity))))
-       (if founds
-           (car founds))))))
+                             (car founds)))))
+                 (setq result (car founds)
+                       founds nil))
+               (setq founds (cdr founds))))))
+       result))))
 
 (defun wl-summary-insert-thread-entity (entity msgdb update
                                               &optional force-insert)
 
 (defun wl-summary-insert-thread-entity (entity msgdb update
                                               &optional force-insert)
@@ -2683,6 +2747,7 @@ If ARG, without confirm."
         parent-entity
         parent-number
         (case-fold-search t)
         parent-entity
         parent-number
         (case-fold-search t)
+        (depth 0) relatives anumber
         cur number overview2 cur-entity linked retval delayed-entity
         update-list entity-stack)
     (while entity
         cur number overview2 cur-entity linked retval delayed-entity
         update-list entity-stack)
     (while entity
@@ -2692,14 +2757,18 @@ If ARG, without confirm."
            parent-number (elmo-msgdb-overview-entity-get-number
                           parent-entity))
       (setq number (elmo-msgdb-overview-entity-get-number entity))
            parent-number (elmo-msgdb-overview-entity-get-number
                           parent-entity))
       (setq number (elmo-msgdb-overview-entity-get-number entity))
-      ;; If thread loop detected, set parent as nil.
       (setq cur entity)
       (setq cur entity)
+      ;; If thread loop detected, set parent as nil.
       (while cur
       (while cur
-       (if (eq number (elmo-msgdb-overview-entity-get-number
-                       (setq cur
-                             (elmo-msgdb-get-parent-entity cur msgdb))))
+       (setq anumber
+             (elmo-msgdb-overview-entity-get-number
+              (setq cur (elmo-msgdb-get-parent-entity cur msgdb))))
+       (if (memq anumber relatives)
            (setq parent-number nil
            (setq parent-number nil
-                 cur nil)))
+                 cur nil))
+       (setq relatives (cons
+                        (elmo-msgdb-overview-entity-get-number cur)
+                        relatives)))
       (if (and parent-number
               (not (wl-thread-get-entity parent-number))
               (not force-insert))
       (if (and parent-number
               (not (wl-thread-get-entity parent-number))
               (not force-insert))
@@ -2753,26 +2822,29 @@ If ARG, without confirm."
         (overview-entity entity)
         (parent-id (elmo-msgdb-overview-entity-get-id parent-entity))
         (number (elmo-msgdb-overview-entity-get-number entity))
         (overview-entity entity)
         (parent-id (elmo-msgdb-overview-entity-get-id parent-entity))
         (number (elmo-msgdb-overview-entity-get-number entity))
-        (parent-number (elmo-msgdb-overview-entity-get-number parent-entity)))
+        (parent-number (elmo-msgdb-overview-entity-get-number parent-entity))
+        insert-line)
     (cond
      ((or (not parent-id)
          (string= this-id parent-id))
       (goto-char (point-max))
     (cond
      ((or (not parent-id)
          (string= this-id parent-id))
       (goto-char (point-max))
-      (beginning-of-line))
+      (beginning-of-line)
+      (setq insert-line t))
      ;; parent already exists in buffer.
      ((wl-summary-jump-to-msg parent-number)
      ;; parent already exists in buffer.
      ((wl-summary-jump-to-msg parent-number)
-      (wl-thread-goto-bottom-of-sub-thread)))
-    (let ((inhibit-read-only t)
-         (buffer-read-only nil))
-      (wl-summary-insert-line
-       (wl-summary-create-line
-       entity
-       parent-entity
-       nil
-       (elmo-msgdb-get-mark (wl-summary-buffer-msgdb) number)
-       (wl-thread-maybe-get-children-num number)
-       (wl-thread-make-indent-string thr-entity)
-       (wl-thread-entity-get-linked thr-entity))))))
+      (wl-thread-goto-bottom-of-sub-thread)
+      (setq insert-line t)))
+    (when insert-line
+      (let (buffer-read-only)
+       (wl-summary-insert-line
+        (wl-summary-create-line
+         entity
+         parent-entity
+         nil
+         (elmo-msgdb-get-mark (wl-summary-buffer-msgdb) number)
+         (wl-thread-maybe-get-children-num number)
+         (wl-thread-make-indent-string thr-entity)
+         (wl-thread-entity-get-linked thr-entity)))))))
 
 (defun wl-summary-mark-as-unread (&optional number
                                            no-server-update
 
 (defun wl-summary-mark-as-unread (&optional number
                                            no-server-update
@@ -2928,7 +3000,8 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
          (while (not (eobp))
            (when (string= (wl-summary-temp-mark) mark)
              (setq msglist (cons (wl-summary-message-number) msglist)))
          (while (not (eobp))
            (when (string= (wl-summary-temp-mark) mark)
              (setq msglist (cons (wl-summary-message-number) msglist)))
-           (forward-line 1)))))))
+           (forward-line 1))
+         (nreverse msglist))))))
 
 (defun wl-summary-exec ()
   (interactive)
 
 (defun wl-summary-exec ()
   (interactive)
@@ -2938,7 +3011,7 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
 
 (defun wl-summary-exec-region (beg end)
   (interactive "r")
 
 (defun wl-summary-exec-region (beg end)
   (interactive "r")
-  (message "Collecting marks ...")
+  (message "Collecting marks...")
   (save-excursion
     (goto-char beg)
     (beginning-of-line)
   (save-excursion
     (goto-char beg)
     (beginning-of-line)
@@ -2967,7 +3040,7 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
            refile-len
            dst-msgs                    ; loop counter
            result)
            refile-len
            dst-msgs                    ; loop counter
            result)
-       (message "Executing ...")
+       (message "Executing...")
        (while dels
          (when (not (assq (car dels) wl-summary-buffer-refile-list))
            (wl-append wl-summary-buffer-refile-list
        (while dels
          (when (not (assq (car dels) wl-summary-buffer-refile-list))
            (wl-append wl-summary-buffer-refile-list
@@ -3058,7 +3131,7 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
                           wl-message-buffer-cur-number)))
          (wl-summary-toggle-disp-msg 'off))
        (set-buffer-modified-p nil)
                           wl-message-buffer-cur-number)))
          (wl-summary-toggle-disp-msg 'off))
        (set-buffer-modified-p nil)
-       (message (concat "Executing ... done"
+       (message (concat "Executing...done"
                         (if (> refile-failures 0)
                             (format " (%d refiling failed)" refile-failures)
                           "")
                         (if (> refile-failures 0)
                             (format " (%d refiling failed)" refile-failures)
                           "")
@@ -3067,6 +3140,45 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
                           "")
                         "."))))))
 
                           "")
                         "."))))))
 
+(defun wl-summary-erase (&optional number)
+  "Erase message actually, without moving it to trash."
+  (interactive)
+  (if (elmo-folder-writable-p wl-summary-buffer-elmo-folder)
+      (let* ((buffer-num (wl-summary-message-number))
+            (msg-num (or number buffer-num)))
+       (if (null msg-num)
+           (message "No message.")
+         (let* ((msgdb (wl-summary-buffer-msgdb))
+                (entity (elmo-msgdb-overview-get-entity msg-num msgdb))
+                (subject (elmo-delete-char
+                          ?\n (or (elmo-msgdb-overview-entity-get-subject
+                                   entity)
+                                  wl-summary-no-subject-message))))
+           (when (yes-or-no-p
+                  (format "Erase \"%s\" without moving it to trash? "
+                          (truncate-string subject 30)))
+             (wl-summary-unmark msg-num)
+             (elmo-folder-delete-messages wl-summary-buffer-elmo-folder
+                                          (list msg-num))
+             (wl-summary-delete-messages-on-buffer (list msg-num))
+             (save-excursion (wl-summary-sync nil "update"))))))
+    (message "Read-only folder.")))
+
+(defun wl-summary-target-mark-erase ()
+  (interactive)
+  (if (elmo-folder-writable-p wl-summary-buffer-elmo-folder)
+      (if (null wl-summary-buffer-target-mark-list)
+         (message "No marked message.")
+       (when (yes-or-no-p
+              "Erase all marked messages without moving them to trash? ")
+         (elmo-folder-delete-messages wl-summary-buffer-elmo-folder
+                                      wl-summary-buffer-target-mark-list)
+         (wl-summary-delete-messages-on-buffer
+          wl-summary-buffer-target-mark-list)
+         (setq wl-summary-buffer-target-mark-list nil)
+         (save-excursion (wl-summary-sync nil "update"))))
+    (message "Read-only folder.")))
+
 (defun wl-summary-read-folder (default &optional purpose ignore-error
                                no-create init)
   (let ((fld (completing-read
 (defun wl-summary-read-folder (default &optional purpose ignore-error
                                no-create init)
   (let ((fld (completing-read
@@ -3115,7 +3227,8 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
        (setq c (+ c (char-width (following-char)))))
       (and (> c len) (setq folder (concat " " folder)))
       (setq rs (point))
        (setq c (+ c (char-width (following-char)))))
       (and (> c len) (setq folder (concat " " folder)))
       (setq rs (point))
-      (put-text-property rs re 'invisible t)
+      (when wl-summary-width
+         (put-text-property rs re 'invisible t))
       (put-text-property rs re 'wl-summary-destination t)
       (goto-char re)
       (wl-highlight-refile-destination-string folder)
       (put-text-property rs re 'wl-summary-destination t)
       (goto-char re)
       (wl-highlight-refile-destination-string folder)
@@ -3384,7 +3497,7 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
 
 
 (defun wl-summary-refile-region (beg end)
 
 
 (defun wl-summary-refile-region (beg end)
-  "Put copy mark on messages in the region specified by BEG and END."
+  "Put refile mark on messages in the region specified by BEG and END."
   (interactive "r")
   (wl-summary-refile-region-subr "refile" beg end))
 
   (interactive "r")
   (wl-summary-refile-region-subr "refile" beg end))
 
@@ -3698,7 +3811,7 @@ If ARG, exit virtual folder."
          (setq skipped (cons (car mlist) skipped)))
        (setq mlist (cdr mlist)))
       (setq wl-summary-buffer-target-mark-list skipped)
          (setq skipped (cons (car mlist) skipped)))
        (setq mlist (cdr mlist)))
       (setq wl-summary-buffer-target-mark-list skipped)
-      (message "Prefetching... %d/%d message(s)." count length)
+      (message "Prefetching... %d/%d message(s)" count length)
       (set-buffer-modified-p nil))))
 
 (defun wl-summary-target-mark-refile-subr (copy-or-refile)
       (set-buffer-modified-p nil))))
 
 (defun wl-summary-target-mark-refile-subr (copy-or-refile)
@@ -3722,11 +3835,9 @@ If ARG, exit virtual folder."
                      number (wl-summary-buffer-msgdb)))
        (if (null entity)
            (error "Cannot %s" copy-or-refile))
                      number (wl-summary-buffer-msgdb)))
        (if (null entity)
            (error "Cannot %s" copy-or-refile))
-       (funcall function
-                (setq folder (wl-summary-read-folder
-                              (wl-refile-guess entity)
-                              (format "for %s" copy-or-refile)))
-                number)
+       (setq folder (wl-summary-read-folder
+                     (wl-refile-guess entity)
+                     (format "for %s" copy-or-refile)))
        (goto-char (point-min))
        (while (not (eobp))
          (when (string= (wl-summary-temp-mark) "*")
        (goto-char (point-min))
        (while (not (eobp))
          (when (string= (wl-summary-temp-mark) "*")
@@ -3789,15 +3900,17 @@ If ARG, exit virtual folder."
          ;; delete target-mark from buffer.
          (delete-backward-char 1)
          (insert " ")
          ;; delete target-mark from buffer.
          (delete-backward-char 1)
          (insert " ")
-         (setq number (wl-summary-mark-as-read t))
+         (setq number (wl-summary-message-number))
+         (wl-summary-mark-as-read number)
          (if wl-summary-highlight
              (wl-highlight-summary-current-line))
          (if number
              (setq wl-summary-buffer-target-mark-list
          (if wl-summary-highlight
              (wl-highlight-summary-current-line))
          (if number
              (setq wl-summary-buffer-target-mark-list
-                   (delq number wl-summary-buffer-target-mark-list)))))
+                   (delq number wl-summary-buffer-target-mark-list))))
+       (forward-line 1))
       (setq mlist wl-summary-buffer-target-mark-list)
       (while mlist
       (setq mlist wl-summary-buffer-target-mark-list)
       (while mlist
-       (wl-summary-mark-as-read t nil nil (car mlist))
+       (wl-summary-mark-as-read (car mlist))
        (setq wl-summary-buffer-target-mark-list
              (delq (car mlist) wl-summary-buffer-target-mark-list))
        (setq mlist (cdr mlist)))
        (setq wl-summary-buffer-target-mark-list
              (delq (car mlist) wl-summary-buffer-target-mark-list))
        (setq mlist (cdr mlist)))
@@ -3880,87 +3993,67 @@ If ARG, exit virtual folder."
   (interactive)
   (wl-summary-pick wl-summary-buffer-target-mark-list 'delete))
 
   (interactive)
   (wl-summary-pick wl-summary-buffer-target-mark-list 'delete))
 
-(defun wl-summary-mark-as-read (&optional notcrosses
-                                         leave-server-side-mark-untouched
-                                         displayed
-                                         number
-                                         cached)
+(defun wl-summary-mark-as-read (&optional number no-folder-mark)
   (interactive)
   (save-excursion
   (interactive)
   (save-excursion
-    (let* (eol
-          (inhibit-read-only t)
-          (buffer-read-only nil)
-          (folder wl-summary-buffer-elmo-folder)
-          (msgdb (wl-summary-buffer-msgdb))
-;;;       (number-alist (elmo-msgdb-get-number-alist msgdb))
-          (case-fold-search nil)
-          cur-mark mark stat visible uncached new-mark marked)
-      (if number
-         (progn
-           (setq visible (wl-summary-jump-to-msg number))
-           (setq mark (elmo-msgdb-get-mark msgdb number)))
-       ;; interactive
-       (setq visible t))
-      (beginning-of-line)
-      (if (or (not visible)
-             (progn
-               (setq cur-mark (wl-summary-persistent-mark))
-               (or (string= cur-mark wl-summary-read-uncached-mark)
-                   (string= cur-mark wl-summary-unread-uncached-mark)
-                   (string= cur-mark wl-summary-unread-cached-mark)
-                   (string= cur-mark wl-summary-new-mark))))
-         (progn
-           (setq mark (or mark cur-mark))
-           (when mark
-             (cond
-              ((string= mark wl-summary-new-mark) ; N
-               (setq stat 'new)
-               (setq uncached t))
-              ((string= mark wl-summary-unread-uncached-mark) ; U
-               (setq stat 'unread)
-               (setq uncached t))
-              ((string= mark wl-summary-unread-cached-mark)  ; !
-               (setq stat 'unread))
-              (t
-               ;; no need to mark server.
-               (setq leave-server-side-mark-untouched t))))
-           (setq number (or number (wl-summary-message-number)))
-           ;; set server side mark...
-           (setq new-mark
-                 (if (and uncached
-                          (if (elmo-message-use-cache-p folder number)
-                              (not (elmo-folder-local-p folder)))
-                          (not cached))
-                     wl-summary-read-uncached-mark
-                   nil))
-           (if (not leave-server-side-mark-untouched)
-               (save-match-data
-                 (setq marked (elmo-folder-mark-as-read
-                               folder
-                               (list number)))))
-           (if (or leave-server-side-mark-untouched
-                   marked)
-               (progn
-                 (cond ((eq stat 'unread)
-                        (setq wl-summary-buffer-unread-count
-                              (1- wl-summary-buffer-unread-count)))
-                       ((eq stat 'new)
-                        (setq wl-summary-buffer-new-count
-                              (1- wl-summary-buffer-new-count))))
-                 (wl-summary-update-modeline)
-                 (wl-folder-update-unread
-                  (wl-summary-buffer-folder-name)
-                  (+ wl-summary-buffer-unread-count
-                     wl-summary-buffer-new-count))
-                 (when (or stat cached)
-                   (when visible
-                     (delete-backward-char 1)
-                     (insert (or new-mark " ")))
-                   (elmo-msgdb-set-mark msgdb number new-mark)
-                   (wl-summary-set-mark-modified))
-                 (if (and visible wl-summary-highlight)
-                     (wl-highlight-summary-current-line nil nil t)))
-             (if mark (message "Warning: Changing mark failed.")))))
+    (let ((buffer-read-only nil)
+         (folder wl-summary-buffer-elmo-folder)
+         (msgdb (wl-summary-buffer-msgdb))
+         (case-fold-search nil)
+         cur-mark mark stat visible uncached new-mark marked)
+      (setq number (or number (wl-summary-message-number))
+           visible (if number
+                       (wl-summary-jump-to-msg number)
+                     ;; interactive
+                     t)
+           mark (elmo-msgdb-get-mark msgdb number))
+      (cond
+       ((string= mark wl-summary-new-mark) ; N
+       (setq stat 'new))
+       ((string= mark wl-summary-unread-uncached-mark) ; U
+       (setq stat 'unread))
+       ((string= mark wl-summary-unread-cached-mark)  ; !
+       (setq stat 'unread))
+       ((string= mark wl-summary-read-uncached-mark)  ; u
+       (setq stat 'read))
+       (t
+       ;; no need to mark server.
+       (setq no-folder-mark t)))
+      (setq new-mark
+           (if (and (if (elmo-message-use-cache-p folder number)
+                        (not (elmo-folder-local-p folder)))
+                    (not (elmo-file-cache-exists-p
+                          (elmo-message-field wl-summary-buffer-elmo-folder
+                                              number 'message-id))))
+               wl-summary-read-uncached-mark
+             nil))
+      ;; folder mark.
+      (unless no-folder-mark
+       (setq marked (elmo-folder-mark-as-read folder (list number))))
+      (when (or no-folder-mark marked)
+       (cond ((eq stat 'unread)
+              (setq wl-summary-buffer-unread-count
+                    (1- wl-summary-buffer-unread-count)))
+             ((eq stat 'new)
+              (setq wl-summary-buffer-new-count
+                    (1- wl-summary-buffer-new-count))))
+       (wl-summary-update-modeline)
+       (wl-folder-update-unread
+        (wl-summary-buffer-folder-name)
+        (+ wl-summary-buffer-unread-count
+           wl-summary-buffer-new-count))
+       (when stat
+         ;; set mark on buffer
+         (when visible
+           (unless (string= (wl-summary-persistent-mark) new-mark)
+             (delete-backward-char 1)
+             (insert (or new-mark " "))))
+         ;; set msgdb mark.
+         (unless (string= mark new-mark)
+           (elmo-msgdb-set-mark msgdb number new-mark))
+         (wl-summary-set-mark-modified))
+       (if (and visible wl-summary-highlight)
+           (wl-highlight-summary-current-line nil nil t)))
       (set-buffer-modified-p nil)
       (if stat
          (run-hooks 'wl-summary-unread-message-hook))
       (set-buffer-modified-p nil)
       (if stat
          (run-hooks 'wl-summary-unread-message-hook))
@@ -4109,7 +4202,6 @@ If ARG, exit virtual folder."
         (t (format "%dB" size)))
       "")))
 
         (t (format "%dB" size)))
       "")))
 
-(defvar wl-summary-line-subject-minimum-length nil)
 (defun wl-summary-line-subject ()
   (let (no-parent subject parent-raw-subject parent-subject)
     (if (string= wl-thr-indent-string "")
 (defun wl-summary-line-subject ()
   (let (no-parent subject parent-raw-subject parent-subject)
     (if (string= wl-thr-indent-string "")
@@ -4124,24 +4216,12 @@ If ARG, exit virtual folder."
     (setq parent-subject
          (if parent-raw-subject
              (elmo-delete-char ?\n parent-raw-subject)))
     (setq parent-subject
          (if parent-raw-subject
              (elmo-delete-char ?\n parent-raw-subject)))
-    (setq subject
-         (if (or no-parent
-                 (null parent-subject)
-                 (not (wl-summary-subject-equal
-                       subject parent-subject)))
-             (funcall wl-summary-subject-function subject)
-           ""))
-    (when (and wl-summary-line-subject-minimum-length
-              (< (string-width subject)
-                 wl-summary-line-subject-minimum-length))
-      (while (< (string-width subject)
-               wl-summary-line-subject-minimum-length)
-       (setq subject (concat subject " "))))
-    (if (and (not wl-summary-width)
-            wl-summary-subject-length-limit)
-       (truncate-string subject
-                        wl-summary-subject-length-limit)
-      subject)))
+    (if (or no-parent
+           (null parent-subject)
+           (not (wl-summary-subject-equal
+                 subject parent-subject)))
+       (funcall wl-summary-subject-function subject)
+      "")))
 
 (defun wl-summary-line-from ()
   (elmo-delete-char ?\n
 
 (defun wl-summary-line-from ()
   (elmo-delete-char ?\n
@@ -4150,66 +4230,22 @@ If ARG, exit virtual folder."
                              wl-message-entity))))
 
 (defun wl-summary-line-list-info ()
                              wl-message-entity))))
 
 (defun wl-summary-line-list-info ()
-  (let ((folder wl-summary-buffer-folder-name)
-       (sequence) (ml-name) (ml-count) (subject-string))
-    (setq sequence (elmo-msgdb-overview-entity-get-extra-field
-                   wl-message-entity "x-sequence")
-         ml-name (or (elmo-msgdb-overview-entity-get-extra-field
-                      wl-message-entity "x-ml-name")
-                     (and sequence
-                          (car (split-string sequence " "))))
-         ml-count (or (elmo-msgdb-overview-entity-get-extra-field
-                       wl-message-entity "x-mail-count")
-                      (elmo-msgdb-overview-entity-get-extra-field
-                       wl-message-entity "x-ml-count")
-                      (and sequence
-                           (cadr (split-string sequence " "))))
-         subject-string
-         (elmo-delete-char ?\n
-                           (or (elmo-msgdb-overview-entity-get-subject
-                                wl-message-entity)
-                               wl-summary-no-subject-message)))
-    (if (string-match
-        "^\\s(\\(\\S)+\\)[ :]\\([0-9]+\\)\\s)[ \t]*"
-        subject-string)
-       (progn
-         (if (not ml-name) (setq ml-name (match-string 1 subject-string)))
-         (if (not ml-count) (setq ml-count (match-string 2 subject-string)))))
-    (condition-case nil
-       (if (and ml-name ml-count)
-           (format "(%s %05d)"
-                   (car (split-string ml-name " "))
-                   (string-to-int ml-count))
-         "")
-      (error ""))))
+  (let ((list-info (wl-summary-get-list-info wl-message-entity)))
+    (if (car list-info)
+       (format (if (cdr list-info) "(%s %05.0f)" "(%s)")
+               (car list-info) (cdr list-info))
+      "")))
 
 (defun wl-summary-line-list-count ()
 
 (defun wl-summary-line-list-count ()
-  (let ((folder wl-summary-buffer-folder-name)
-       (sequence) (ml-count) (subject-string))
-    (setq sequence (elmo-msgdb-overview-entity-get-extra-field
-                   wl-message-entity "x-sequence")
-         ml-count (or (elmo-msgdb-overview-entity-get-extra-field
-                       wl-message-entity "x-mail-count")
-                      (elmo-msgdb-overview-entity-get-extra-field
-                       wl-message-entity "x-ml-count")
-                      (and sequence
-                           (cadr (split-string sequence " ")))))
+  (let ((ml-count (cdr (wl-summary-get-list-info wl-message-entity))))
     (if ml-count
     (if ml-count
-       (format "%d" (string-to-int ml-count))
-      (setq subject-string
-           (elmo-delete-char ?\n
-                             (or (elmo-msgdb-overview-entity-get-subject
-                                  wl-message-entity)
-                                 "")))
-      (if (string-match
-          "^\\s(\\(\\S)+\\)[ :]\\([0-9]+\\)\\s)[ \t]*"
-          subject-string)
-         (match-string 2 subject-string)
-       ""))))
+       (format "%.0f" ml-count)
+      "")))
 
 (defun wl-summary-line-attached ()
   (let ((content-type (elmo-msgdb-overview-entity-get-extra-field
 
 (defun wl-summary-line-attached ()
   (let ((content-type (elmo-msgdb-overview-entity-get-extra-field
-                      wl-message-entity "content-type")))
+                      wl-message-entity "content-type"))
+       (case-fold-search t))
     (if (and content-type
             (string-match "multipart/mixed" content-type))
        "@"
     (if (and content-type
             (string-match "multipart/mixed" content-type))
        "@"
@@ -4245,7 +4281,8 @@ If ARG, exit virtual folder."
     (setq line (funcall wl-summary-buffer-line-formatter))
     (if wl-summary-width (setq line
                               (wl-set-string-width
     (setq line (funcall wl-summary-buffer-line-formatter))
     (if wl-summary-width (setq line
                               (wl-set-string-width
-                               (- wl-summary-width 1) line)))
+                               (- wl-summary-width 1) line nil
+                               'ignore-invalid)))
     (setq line (concat line
                       "\r"
                       (number-to-string
     (setq line (concat line
                       "\r"
                       (number-to-string
@@ -4373,7 +4410,9 @@ If ARG, exit virtual folder."
              (copy-to-buffer tmp-buffer (point-min) (point-max))
              (with-current-buffer tmp-buffer
                (widen)
              (copy-to-buffer tmp-buffer (point-min) (point-max))
              (with-current-buffer tmp-buffer
                (widen)
-               (setq wl-summary-buffer-target-mark-list mark-list
+               (make-local-variable 'wl-summary-highlight)
+               (setq wl-summary-highlight nil
+                     wl-summary-buffer-target-mark-list mark-list
                      wl-summary-buffer-refile-list refile-list
                      wl-summary-buffer-copy-list copy-list
                      wl-summary-buffer-delete-list delete-list
                      wl-summary-buffer-refile-list refile-list
                      wl-summary-buffer-copy-list copy-list
                      wl-summary-buffer-delete-list delete-list
@@ -4381,7 +4420,8 @@ If ARG, exit virtual folder."
                (wl-summary-delete-all-temp-marks)
                (encode-coding-region
                 (point-min) (point-max)
                (wl-summary-delete-all-temp-marks)
                (encode-coding-region
                 (point-min) (point-max)
-                (or (mime-charset-to-coding-system charset 'LF)
+                (or (and wl-on-mule ; one in mcs-ltn1(apel<10.4) cannot take 2 arg.
+                         (mime-charset-to-coding-system charset 'LF))
                     ;; Mule 2 doesn't have `*ctext*unix'.
                     (mime-charset-to-coding-system charset)))
                (write-region-as-binary (point-min)(point-max)
                     ;; Mule 2 doesn't have `*ctext*unix'.
                     (mime-charset-to-coding-system charset)))
                (write-region-as-binary (point-min)(point-max)
@@ -4673,6 +4713,7 @@ Return t if message exists."
       (save-excursion
        (set-buffer summary-buf)
        (wl-summary-delete-all-temp-marks)))
       (save-excursion
        (set-buffer summary-buf)
        (wl-summary-delete-all-temp-marks)))
+    (wl-draft-reply-position wl-draft-reply-default-position)
     (run-hooks 'wl-mail-setup-hook)))
 
 (defun wl-summary-reply-with-citation (&optional arg)
     (run-hooks 'wl-mail-setup-hook)))
 
 (defun wl-summary-reply-with-citation (&optional arg)
@@ -4680,6 +4721,7 @@ Return t if message exists."
   (when (wl-summary-reply arg t)
     (goto-char (point-max))
     (wl-draft-yank-original)
   (when (wl-summary-reply arg t)
     (goto-char (point-max))
     (wl-draft-yank-original)
+    (wl-draft-reply-position wl-draft-reply-default-position)
     (run-hooks 'wl-mail-setup-hook)))
 
 (defun wl-summary-jump-to-msg-by-message-id (&optional id)
     (run-hooks 'wl-mail-setup-hook)))
 
 (defun wl-summary-jump-to-msg-by-message-id (&optional id)
@@ -4795,6 +4837,7 @@ Return t if message exists."
 (defun wl-summary-jump-to-parent-message (arg)
   (interactive "P")
   (let ((cur-buf (current-buffer))
 (defun wl-summary-jump-to-parent-message (arg)
   (interactive "P")
   (let ((cur-buf (current-buffer))
+       (disp-msg wl-summary-buffer-disp-msg)
        (number (wl-summary-message-number))
        (regexp "\\(<[^<>]*>\\)[ \t]*$")
        (i -1) ;; xxx
        (number (wl-summary-message-number))
        (regexp "\\(<[^<>]*>\\)[ \t]*$")
        (i -1) ;; xxx
@@ -4848,17 +4891,18 @@ Return t if message exists."
          (setq msg-id
                (if (null arg) (nth 0 ref-list) ;; previous
                  (if (<= arg i) (nth (1- arg) ref-list)
          (setq msg-id
                (if (null arg) (nth 0 ref-list) ;; previous
                  (if (<= arg i) (nth (1- arg) ref-list)
-                   (nth i ref-list)))))))
-      (set-buffer cur-buf)
+                   (nth i ref-list))))))
+       (set-buffer cur-buf)
+       (or disp-msg (wl-summary-toggle-disp-msg 'off)))
       (cond ((and (null msg-id) (null msg-num))
             (message "No parent message!")
             nil)
            ((and msg-id (wl-summary-jump-to-msg-by-message-id msg-id))
       (cond ((and (null msg-id) (null msg-num))
             (message "No parent message!")
             nil)
            ((and msg-id (wl-summary-jump-to-msg-by-message-id msg-id))
-            (wl-summary-redisplay)
+            (if wl-summary-buffer-disp-msg (wl-summary-redisplay))
             (message "Searching parent message...done")
             t)
            ((and msg-num (wl-summary-jump-to-msg msg-num))
             (message "Searching parent message...done")
             t)
            ((and msg-num (wl-summary-jump-to-msg msg-num))
-            (wl-summary-redisplay)
+            (if wl-summary-buffer-disp-msg (wl-summary-redisplay))
             (message "Searching parent message...done")
             t)
            (t ; failed.
             (message "Searching parent message...done")
             t)
            (t ; failed.
@@ -4880,11 +4924,9 @@ Reply to author if invoked with ARG."
       (wl-message-select-buffer wl-message-buffer)
       (set-buffer mes-buf)
       (goto-char (point-min))
       (wl-message-select-buffer wl-message-buffer)
       (set-buffer mes-buf)
       (goto-char (point-min))
-      (unless wl-draft-use-frame
-       (split-window-vertically)
-       (other-window 1))
       (when (setq mes-buf (wl-message-get-original-buffer))
        (wl-draft-reply mes-buf arg summary-buf)
       (when (setq mes-buf (wl-message-get-original-buffer))
        (wl-draft-reply mes-buf arg summary-buf)
+       (wl-draft-reply-position wl-draft-reply-default-position)
        (unless without-setup-hook
          (run-hooks 'wl-mail-setup-hook)))
       t)))
        (unless without-setup-hook
          (run-hooks 'wl-mail-setup-hook)))
       t)))
@@ -4954,9 +4996,6 @@ Use function list is `wl-summary-write-current-folder-functions'."
        (wl-summary-redisplay-internal folder number))
       (setq mes-buf wl-message-buffer)
       (wl-message-select-buffer mes-buf)
        (wl-summary-redisplay-internal folder number))
       (setq mes-buf wl-message-buffer)
       (wl-message-select-buffer mes-buf)
-      (unless wl-draft-use-frame
-       (split-window-vertically)
-       (other-window 1))
       ;; get original subject.
       (if summary-buf
          (save-excursion
       ;; get original subject.
       (if summary-buf
          (save-excursion
@@ -5001,7 +5040,7 @@ Use function list is `wl-summary-write-current-folder-functions'."
       (if downward
          (forward-line 1)
        (forward-line -1))
       (if downward
          (forward-line 1)
        (forward-line -1))
-      (setq skip (or (string-match skip-tmark-regexp 
+      (setq skip (or (string-match skip-tmark-regexp
                                   (save-excursion
                                     (wl-summary-temp-mark)))
                     (and skip-pmark-regexp
                                   (save-excursion
                                     (wl-summary-temp-mark)))
                     (and skip-pmark-regexp
@@ -5020,8 +5059,12 @@ Use function list is `wl-summary-write-current-folder-functions'."
        (if wl-summary-buffer-disp-msg
            (wl-summary-redisplay))
       (if interactive
        (if wl-summary-buffer-disp-msg
            (wl-summary-redisplay))
       (if interactive
-         (if wl-summary-buffer-next-folder-function
-             (funcall wl-summary-buffer-next-folder-function)
+         (cond
+          ((and (not downward) wl-summary-buffer-prev-folder-function)
+           (funcall wl-summary-buffer-prev-folder-function))
+          ((and downward wl-summary-buffer-next-folder-function)
+           (funcall wl-summary-buffer-next-folder-function))
+          (t
            (when wl-auto-select-next
              (setq next-entity
                    (if downward
            (when wl-auto-select-next
              (setq next-entity
                    (if downward
@@ -5033,7 +5076,7 @@ Use function list is `wl-summary-write-current-folder-functions'."
             '(lambda () (wl-summary-next-folder-or-exit next-entity))
             (format
              "No more messages. Type SPC to go to %s."
             '(lambda () (wl-summary-next-folder-or-exit next-entity))
             (format
              "No more messages. Type SPC to go to %s."
-             (wl-summary-entity-info-msg next-entity finfo))))))))
+             (wl-summary-entity-info-msg next-entity finfo)))))))))
 
 (defun wl-summary-prev (&optional interactive)
   (interactive)
 
 (defun wl-summary-prev (&optional interactive)
   (interactive)
@@ -5173,7 +5216,7 @@ Use function list is `wl-summary-write-current-folder-functions'."
                  (delete-window fld-win)))
          (setq wl-current-summary-buffer (current-buffer))
          (wl-summary-mark-as-read
                  (delete-window fld-win)))
          (setq wl-current-summary-buffer (current-buffer))
          (wl-summary-mark-as-read
-          nil
+          num
           ;; not fetched, then change server-mark.
           (if (wl-message-redisplay folder num 'mime
                                     (or force-reload
           ;; not fetched, then change server-mark.
           (if (wl-message-redisplay folder num 'mime
                                     (or force-reload
@@ -5188,11 +5231,7 @@ Use function list is `wl-summary-write-current-folder-functions'."
                    wl-summary-buffer-elmo-folder))
                  (elmo-folder-plugged-p
                   wl-summary-buffer-elmo-folder))
                    wl-summary-buffer-elmo-folder))
                  (elmo-folder-plugged-p
                   wl-summary-buffer-elmo-folder))
-                'leave))
-          t ; displayed
-          nil
-          'cached ; cached by reading.
-          )
+                'leave)))
          (setq wl-summary-buffer-current-msg num)
          (when wl-summary-recenter
            (recenter (/ (- (window-height) 2) 2))
          (setq wl-summary-buffer-current-msg num)
          (when wl-summary-recenter
            (recenter (/ (- (window-height) 2) 2))
@@ -5230,7 +5269,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
          (wl-message-redisplay fld num 'as-is
                                (string= (elmo-folder-name-internal fld)
                                         wl-draft-folder))
          (wl-message-redisplay fld num 'as-is
                                (string= (elmo-folder-name-internal fld)
                                         wl-draft-folder))
-         (wl-summary-mark-as-read nil nil t)
+         (wl-summary-mark-as-read num)
          (setq wl-summary-buffer-current-msg num)
          (when wl-summary-recenter
            (recenter (/ (- (window-height) 2) 2))
          (setq wl-summary-buffer-current-msg num)
          (when wl-summary-recenter
            (recenter (/ (- (window-height) 2) 2))
@@ -5257,7 +5296,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
          (if (wl-message-redisplay fld num 'all-header
                                    (string= (elmo-folder-name-internal fld)
                                             wl-draft-folder))
          (if (wl-message-redisplay fld num 'all-header
                                    (string= (elmo-folder-name-internal fld)
                                             wl-draft-folder))
-             (wl-summary-mark-as-read nil nil t))
+             (wl-summary-mark-as-read num))
          (setq wl-summary-buffer-current-msg num)
          (when wl-summary-recenter
            (recenter (/ (- (window-height) 2) 2))
          (setq wl-summary-buffer-current-msg num)
          (when wl-summary-recenter
            (recenter (/ (- (window-height) 2) 2))
@@ -5331,6 +5370,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
 (defun wl-summary-supersedes-message ()
   "Supersede current message."
   (interactive)
 (defun wl-summary-supersedes-message ()
   "Supersede current message."
   (interactive)
+  (wl-summary-toggle-disp-msg 'off)
   (let ((summary-buf (current-buffer))
        message-buf from)
     (wl-summary-set-message-buffer-or-redisplay)
   (let ((summary-buf (current-buffer))
        message-buf from)
     (wl-summary-set-message-buffer-or-redisplay)