* wl-summary.el (wl-summary-pick): If call it with prefix
[elisp/wanderlust.git] / wl / wl-summary.el
index ac32be5..2aebd02 100644 (file)
 (defvar wl-summary-buffer-line-format nil)
 (defvar wl-summary-buffer-mode-line-formatter nil)
 (defvar wl-summary-buffer-mode-line nil)
+(defvar wl-summary-buffer-display-as-is nil)
 
 (defvar wl-thread-indent-level-internal nil)
 (defvar wl-thread-have-younger-brother-str-internal nil)
 (make-variable-buffer-local 'wl-summary-buffer-line-format)
 (make-variable-buffer-local 'wl-summary-buffer-mode-line-formatter)
 (make-variable-buffer-local 'wl-summary-buffer-mode-line)
+(make-variable-buffer-local 'wl-summary-buffer-display-as-is)
 
 (defvar wl-datevec)
 (defvar wl-thr-indent-string)
@@ -417,6 +419,7 @@ See also variable `wl-use-petname'."
   (define-key wl-summary-mode-map "f"    'wl-summary-forward)
   (define-key wl-summary-mode-map "$"    'wl-summary-mark-as-important)
   (define-key wl-summary-mode-map "F"    'wl-summary-set-flags)
+  (define-key wl-summary-mode-map "\M-k"  'wl-summary-toggle-persistent-mark)
   (define-key wl-summary-mode-map "&"    'wl-summary-mark-as-answered)
   (define-key wl-summary-mode-map "@"    'wl-summary-edit-addresses)
 
@@ -433,7 +436,7 @@ See also variable `wl-use-petname'."
   (define-key wl-summary-mode-map "\C-c\C-p" 'wl-summary-previous-buffer)
   (define-key wl-summary-mode-map "\C-c\C-n" 'wl-summary-next-buffer)
   (define-key wl-summary-mode-map "H"    'wl-summary-redisplay-all-header)
-  (define-key wl-summary-mode-map "M"    'wl-summary-redisplay-no-mime)
+  (define-key wl-summary-mode-map "M"    'wl-summary-toggle-mime)
   (define-key wl-summary-mode-map "B"    'wl-summary-burst)
   (define-key wl-summary-mode-map "Z"    'wl-status-update)
   (define-key wl-summary-mode-map "#"    'wl-summary-print-message)
@@ -592,9 +595,10 @@ See also variable `wl-use-petname'."
          (goto-char beg)
          (while (and (< (point) end) (not (eobp)))
            (when (null (get-text-property (point) 'face))
-             (setq number (wl-summary-message-number)
-                   flags (elmo-message-flags wl-summary-buffer-elmo-folder
-                                             number))
+             (setq number (wl-summary-message-number))
+             (when number
+               (setq flags (elmo-message-flags wl-summary-buffer-elmo-folder
+                                               number)))
              (let (wl-summary-highlight)
                (wl-summary-update-persistent-mark number flags))
              (wl-highlight-summary-current-line number flags))
@@ -940,26 +944,32 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
       (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-number ()
-  (interactive)
-  (wl-summary-rescan "number"))
-(defun wl-summary-sort-by-subject ()
-  (interactive)
-  (wl-summary-rescan "subject"))
-(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-sort-by-size ()
-  (interactive)
-  (wl-summary-rescan "size"))
+(defun wl-summary-sort-by-date (reverse)
+  "Sort summary lines into the order by message date; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "date" reverse))
+(defun wl-summary-sort-by-number (reverse)
+  "Sort summary lines into the order by message number; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "number" reverse))
+(defun wl-summary-sort-by-subject (reverse)
+  "Sort summary lines into the order by subject; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "subject" reverse))
+(defun wl-summary-sort-by-from (reverse)
+  "Sort summary lines into the order by from; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "from" reverse))
+(defun wl-summary-sort-by-list-info (reverse)
+  "Sort summary lines into the order by mailing list info; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "list-info" reverse))
+(defun wl-summary-sort-by-size (reverse)
+  "Sort summary lines into the order by message size; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "size" reverse))
 
-(defun wl-summary-rescan (&optional sort-by disable-killed disable-thread)
+(defun wl-summary-rescan (&optional sort-by reverse disable-killed disable-thread)
   "Rescan current folder without updating."
   (interactive)
   (let ((elmo-mime-charset wl-summary-buffer-mime-charset)
@@ -977,13 +987,14 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
        (predicate (and sort-by
                        (intern (format "wl-summary-overview-entity-compare-by-%s"
                                        sort-by))))
+       (sort-label (if reverse "Reverse sorting" "Sorting"))
        (i 0)
        num
        expunged)
     (erase-buffer)
     (message "Re-scanning...")
     (when sort-by
-      (message "Sorting by %s..." sort-by)
+      (message "%s by %s..." sort-label sort-by)
       (setq numbers
            (sort numbers
                  (lambda (x y)
@@ -991,7 +1002,8 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
                     predicate
                     (elmo-message-entity wl-summary-buffer-elmo-folder x)
                     (elmo-message-entity wl-summary-buffer-elmo-folder y)))))
-      (message "Sorting by %s...done" sort-by))
+      (if reverse (setq numbers (nreverse numbers)))
+      (message "%s by %s...done" sort-label sort-by))
     (setq num (length numbers))
     (setq wl-thread-entity-hashtb (elmo-make-hash (* num 2))
          wl-thread-entity-list nil
@@ -1248,6 +1260,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
                                     nil
                                   wl-use-scoring)))
             (wl-summary-rescan nil
+                               nil
                                (string-match "noscore" range)
                                (string-match "thread" range))
             (and msg (wl-summary-jump-to-msg msg))))
@@ -1617,7 +1630,8 @@ If ARG is non-nil, checking is omitted."
     (if (null number-list)
        (message "No message.")
       (wl-summary-set-persistent-mark-internal remove 'answered
-                                              number-list)
+                                              number-list
+                                              nil nil (interactive-p))
       (wl-summary-count-unread)
       (wl-summary-update-modeline))))
 
@@ -1632,7 +1646,8 @@ If ARG is non-nil, checking is omitted."
                                            'important))))
     (if (null number-list)
        (message "No message.")
-      (wl-summary-mark-as-important-internal remove number-list)
+      (wl-summary-set-persistent-mark-internal remove 'important number-list
+                                              nil nil (interactive-p))
       (wl-summary-count-unread)
       (wl-summary-update-modeline))))
 
@@ -1765,67 +1780,51 @@ This function is defined for `window-scroll-functions'"
       (apply 'wl-summary-insert-thread args)
     (apply 'wl-summary-insert-sequential args)))
 
-(defun wl-summary-sort ()
-  (interactive)
+(defun wl-summary-sort (reverse)
+  "Sort summary lines into the selected order; argument means descending order."
+  (interactive "P")
   (wl-summary-rescan
    (completing-read
-    (format "Sort by (%s): " (symbol-name wl-summary-default-sort-spec))
+    (format "%s by (%s): "
+           (if reverse "Reverse sort" "Sort")
+           (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))))
+    nil t nil nil (symbol-name wl-summary-default-sort-spec))
+   reverse))
+
+(defun wl-summary-get-available-flags (&optional include-specials)
+  (let ((flags (elmo-uniq-list
+               (append elmo-global-flag-list
+                       (copy-sequence elmo-preserved-flags))
+               #'delq)))
+    (if include-specials
+       flags
+      (delq 'new (delq 'cached flags)))))
 
 (defun wl-summary-sync-marks ()
   "Update persistent marks in summary."
   (interactive)
   (let ((mes "Updated ")
        diff diffs)
-    ;; synchronize marks.
-    (when (not (eq (elmo-folder-type-internal
-                   wl-summary-buffer-elmo-folder)
-                  'internal))
-
-      (message "Updating marks...")
-      (dolist (flag elmo-global-flag-list)
-       (unless (memq flag elmo-preserved-flags)
-         (setq diff (elmo-list-diff (elmo-folder-list-flagged
-                                     wl-summary-buffer-elmo-folder
-                                     flag)
-                                    (elmo-folder-list-flagged
-                                     wl-summary-buffer-elmo-folder
-                                     flag 'in-msgdb)))
-         (setq diffs (cadr diff)) ; deletes
-         (setq mes (concat mes (format "-%d" (length diffs))))
-         (while diffs
-           (wl-summary-remove-flags-internal (car diffs)
-                                            (list flag) 'no-server)
-           (setq diffs (cdr diffs)))
-         (setq diffs (car diff)) ; appends
-         (setq mes (concat mes (format "/+%d %s," (length diffs) flag)))
-         (while diffs
-           (wl-summary-add-flags-internal (car diffs)
-                                         (list flag) 'no-server)
-           (setq diffs (cdr diffs)))))
-
-      (dolist (flag (delete 'new (delete 'cached
-                                        (copy-sequence elmo-preserved-flags))))
-       (setq diff (elmo-list-diff (elmo-folder-list-flagged
-                                   wl-summary-buffer-elmo-folder
-                                   flag)
-                                  (elmo-folder-list-flagged
-                                   wl-summary-buffer-elmo-folder
-                                   flag 'in-msgdb)))
-       (setq diffs (cadr diff))
-       (setq mes (concat mes (format "-%d" (length diffs))))
-       (while diffs
-         (wl-summary-unset-persistent-mark flag (car diffs) 'no-modeline)
-         (setq diffs (cdr diffs)))
-       (setq diffs (car diff)
-             mes (concat mes (format "/+%d %s " (length diffs) flag)))
-       (while diffs
-         (wl-summary-set-persistent-mark flag (car diffs) 'no-modeline)
-         (setq diffs (cdr diffs))))
-      (if (interactive-p) (message "%s" mes)))))
+    (message "Updating marks...")
+    (dolist (flag (wl-summary-get-available-flags))
+      (setq diff (elmo-list-diff (elmo-folder-list-flagged
+                                 wl-summary-buffer-elmo-folder
+                                 flag)
+                                (elmo-folder-list-flagged
+                                 wl-summary-buffer-elmo-folder
+                                 flag 'in-msgdb)))
+      (setq diffs (cadr diff))
+      (setq mes (concat mes (format "-%d" (length diffs))))
+      (when diffs
+       (wl-summary-unset-persistent-mark flag diffs 'no-modeline 'no-server))
+      (setq diffs (car diff)
+           mes (concat mes (format "/+%d %s " (length diffs) flag)))
+      (when diffs
+       (wl-summary-set-persistent-mark flag diffs 'no-modeline 'no-server)))
+    (if (interactive-p) (message "%s" mes))))
 
 (defun wl-summary-sync-update (&optional unset-cursor
                                         disable-killed
@@ -2099,7 +2098,7 @@ If ARG, without confirm."
       (setq wl-summary-buffer-view 'thread))
     (wl-summary-update-modeline)
     (force-mode-line-update)
-    (wl-summary-rescan nil nil t)))
+    (wl-summary-rescan nil nil nil t)))
 
 (defun wl-summary-load-file-object (filename)
   "Load lisp object from dir."
@@ -2302,6 +2301,8 @@ If ARG, without confirm."
          (unless (eq major-mode 'wl-summary-mode)
            (wl-summary-mode))
          (wl-summary-buffer-set-folder folder)
+         (setq wl-summary-buffer-display-as-is
+               (wl-summary-no-mime-p wl-summary-buffer-elmo-folder))
          (setq wl-summary-buffer-disp-msg nil)
          (setq wl-summary-buffer-last-displayed-msg nil)
          (setq wl-summary-buffer-current-msg nil)
@@ -2440,6 +2441,11 @@ If ARG, without confirm."
     (when (and wl-summary-buffer-window-scroll-functions
               wl-on-xemacs)
       (sit-for 0))
+    (when (or (eq t wl-summary-force-prefetch-folder-list)
+             (wl-string-match-member
+              (elmo-folder-name-internal wl-summary-buffer-elmo-folder)
+              wl-summary-force-prefetch-folder-list))
+      (wl-summary-force-prefetch))
     (unwind-protect
        (run-hooks 'wl-summary-prepared-hook)
       (set-buffer-modified-p nil))
@@ -2723,14 +2729,20 @@ If ARG, without confirm."
     i))
 
 (defun wl-summary-pick (&optional from-list delete-marks)
-  (interactive)
+  (interactive "i\nP")
   (save-excursion
-    (let* ((condition (car (elmo-parse-search-condition
+    (let* ((messages (or from-list
+                        (elmo-folder-list-messages
+                         wl-summary-buffer-elmo-folder
+                         'visible
+                         'in-msgdb)
+                        (error "No messages")))
+          (condition (car (elmo-parse-search-condition
                            (elmo-read-search-condition
                             wl-summary-pick-field-default))))
           (result (elmo-folder-search wl-summary-buffer-elmo-folder
                                       condition
-                                      from-list))
+                                      messages))
           num)
       (if delete-marks
          (let ((mlist wl-summary-buffer-target-mark-list))
@@ -2829,7 +2841,8 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
                             "wl-summary-%s-cached-mark" (car priorities))
                          (format
                           "wl-summary-%s-uncached-mark" (car priorities))))))
-                 (if (boundp var)
+                 (if (and (boundp var)
+                          (symbol-value var))
                      (symbol-value var)
                    (if cached
                        (downcase (substring (symbol-name (car priorities))
@@ -2840,7 +2853,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
     (or mark
        (if (or cached (elmo-folder-local-p folder))
            nil
-         wl-summary-read-uncached-mark))))
+         wl-summary-uncached-mark))))
 
 (defsubst wl-summary-message-mark (folder number &optional flags)
   "Return mark of the message."
@@ -2891,8 +2904,13 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
      (or (cadr (memq (current-buffer) buffers))
         (car buffers)))))
 
+(defun wl-summary-check-target-mark ()
+  (when (null wl-summary-buffer-target-mark-list)
+    (error "No marked message")))
+
 (defun wl-summary-target-mark-mark-as-read ()
   (interactive)
+  (wl-summary-check-target-mark)
   (save-excursion
     (goto-char (point-min))
     (let ((inhibit-read-only t)
@@ -2904,6 +2922,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
 
 (defun wl-summary-target-mark-mark-as-unread ()
   (interactive)
+  (wl-summary-check-target-mark)
   (save-excursion
     (goto-char (point-min))
     (let ((inhibit-read-only t)
@@ -2914,6 +2933,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
        (wl-summary-unset-mark number)))))
 
 (defun wl-summary-target-mark-operation (flag &optional inverse)
+  (wl-summary-check-target-mark)
   (save-excursion
     (let ((inhibit-read-only t)
          (buffer-read-only nil)
@@ -2934,6 +2954,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
 
 (defun wl-summary-target-mark-set-flags (&optional remove)
   (interactive "P")
+  (wl-summary-check-target-mark)
   (save-excursion
     (let ((inhibit-read-only t)
          (buffer-read-only nil)
@@ -2946,6 +2967,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
 
 (defun wl-summary-target-mark-save ()
   (interactive)
+  (wl-summary-check-target-mark)
   (let ((wl-save-dir
         (wl-read-directory-name "Save to directory: "
                                 wl-temporary-file-directory))
@@ -2959,6 +2981,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
 
 (defun wl-summary-target-mark-pick ()
   (interactive)
+  (wl-summary-check-target-mark)
   (wl-summary-pick wl-summary-buffer-target-mark-list 'delete))
 
 (defun wl-summary-update-persistent-mark (&optional number flags)
@@ -3011,8 +3034,8 @@ Return non-nil if the mark is updated"
       (if (null number-list)
          (message "No message.")
        (if inverse
-           (elmo-folder-unset-flag folder number-list 'read no-folder-mark)
-         (elmo-folder-set-flag folder number-list 'read no-folder-mark))
+           (elmo-folder-set-flag folder number-list 'unread no-folder-mark)
+         (elmo-folder-unset-flag folder number-list 'unread no-folder-mark))
        (dolist (number number-list)
          (setq visible (wl-summary-jump-to-msg number))
          (unless inverse
@@ -3048,9 +3071,11 @@ Return non-nil if the mark is updated"
                                    no-modeline-update))
 
 (defsubst wl-summary-set-persistent-mark-internal (inverse
-                                                  &optional flag
-                                                  number-or-numbers
-                                                  no-modeline-update)
+                                                  flag
+                                                  &optional number-or-numbers
+                                                  no-modeline-update
+                                                  no-server
+                                                  interactive)
   "Set persistent mark."
   (save-excursion
     (let ((folder wl-summary-buffer-elmo-folder)
@@ -3065,26 +3090,31 @@ Return non-nil if the mark is updated"
                               (list number))))
       (if (null number-list)
          (message "No message.")
-       (if inverse
-           (elmo-folder-unset-flag folder number-list flag)
-         (elmo-folder-set-flag folder number-list flag))
-       (dolist (number number-list)
-         (setq visible (wl-summary-jump-to-msg number))
-         ;; set mark on buffer
-         (when visible
-           (wl-summary-update-persistent-mark)))
-       (unless no-modeline-update
-         ;; Update unread numbers.
-         ;; should elmo-flag-mark-as-read return unread numbers?
-         (wl-summary-count-unread)
-         (wl-summary-update-modeline)
-         (wl-folder-update-unread
-          (wl-summary-buffer-folder-name)
-          wl-summary-buffer-unread-count))))))
+       ;; XXX Only the first element of the list is checked.
+       (if (elmo-message-flag-available-p folder (car number-list) flag)
+           (progn
+             (if inverse
+                 (elmo-folder-unset-flag folder number-list flag no-server)
+               (elmo-folder-set-flag folder number-list flag no-server))
+             (dolist (number number-list)
+               ;; set mark on buffer
+               (when (wl-summary-jump-to-msg number)
+                 (wl-summary-update-persistent-mark)))
+             (unless no-modeline-update
+               ;; Update unread numbers.
+               ;; should elmo-flag-mark-as-read return unread numbers?
+               (wl-summary-count-unread)
+               (wl-summary-update-modeline)
+               (wl-folder-update-unread
+                (wl-summary-buffer-folder-name)
+                wl-summary-buffer-unread-count)))
+         (if interactive
+             (error "Flag `%s' is not available in this folder" flag)))))))
 
 (defun wl-summary-unset-persistent-mark (&optional flag
                                                   number-or-numbers
-                                                  no-modeline-update)
+                                                  no-modeline-update
+                                                  no-server)
   "Unset persistent mark."
   (interactive)
   (when (interactive-p)
@@ -3094,22 +3124,20 @@ Return non-nil if the mark is updated"
                           "Flag: "
                           (mapcar (lambda (flag)
                                     (list (capitalize (symbol-name flag))))
-                                  (delq
-                                   'cached
-                                   (delq 'new
-                                         (elmo-uniq-list
-                                          (append elmo-global-flag-list
-                                                  elmo-preserved-flags)))))
+                                  (wl-summary-get-available-flags))
                           nil
                           'require-match))))))
   (wl-summary-set-persistent-mark-internal 'inverse
                                           flag
                                           number-or-numbers
-                                          no-modeline-update))
+                                          no-modeline-update
+                                          no-server
+                                          (interactive-p)))
 
 (defun wl-summary-set-persistent-mark (&optional flag
                                                 number-or-numbers
-                                                no-modeline-update)
+                                                no-modeline-update
+                                                no-server)
   "Set persistent mark."
   (interactive)
   (when (interactive-p)
@@ -3119,19 +3147,35 @@ Return non-nil if the mark is updated"
                           "Flag: "
                           (mapcar (lambda (flag)
                                     (list (capitalize (symbol-name flag))))
-                                   (delq
-                                    'cached
-                                    (delq 'new
-                                          (elmo-uniq-list
-                                           (append elmo-global-flag-list
-                                                   elmo-preserved-flags)))))
+                                  (wl-summary-get-available-flags))
                           nil
                           'require-match))))))
-  (wl-summary-set-persistent-mark-internal
-   nil
-   flag
-   number-or-numbers
-   no-modeline-update))
+  (wl-summary-set-persistent-mark-internal nil
+                                          flag
+                                          number-or-numbers
+                                          no-modeline-update
+                                          no-server
+                                          (interactive-p)))
+
+(defun wl-summary-toggle-persistent-mark (&optional force)
+  "Toggle persistent mark."
+  (interactive "P")
+  (let ((completion-ignore-case t)
+       flag)
+    (setq flag (intern (downcase
+                       (completing-read
+                        "Flag: "
+                        (mapcar (lambda (flag)
+                                  (list (capitalize (symbol-name flag))))
+                                (wl-summary-get-available-flags))
+                        nil
+                        'require-match))))
+    (if (and (elmo-message-flagged-p wl-summary-buffer-elmo-folder
+                                    (wl-summary-message-number)
+                                    flag)
+            (not force))
+       (wl-summary-unset-persistent-mark flag)
+      (wl-summary-set-persistent-mark flag))))
 
 (defun wl-summary-mark-as-answered (&optional number-or-numbers
                                              no-modeline-update)
@@ -3143,7 +3187,9 @@ Return non-nil if the mark is updated"
                                'answered))
    'answered
    number-or-numbers
-   no-modeline-update))
+   no-modeline-update
+   nil
+   (interactive-p)))
 
 (defun wl-summary-mark-as-unanswered (&optional number-or-numbers
                                                no-modeline-update)
@@ -3213,85 +3259,25 @@ Return non-nil if the mark is updated"
            (wl-summary-update-persistent-mark))))
       flags)))
 
-(defsubst wl-summary-add-flags-internal (&optional
-                                        number-or-numbers
-                                        flags
-                                        local)
-  (save-excursion
-    (let ((folder wl-summary-buffer-elmo-folder)
-         set-flags msg number-list visible)
-      (setq number-list (cond ((numberp number-or-numbers)
-                              (list number-or-numbers))
-                             ((and (not (null number-or-numbers))
-                                   (listp number-or-numbers))
-                              number-or-numbers)
-                             ((setq msg (wl-summary-message-number))
-                              ;; interactive
-                              (list msg))))
-      (if (null number-list)
-         (message "No message.")
-       (dolist (number number-list)
-         (setq set-flags
-               (elmo-get-global-flags
-                (elmo-message-flags folder number)))
-         (setq set-flags (nconc flags set-flags))
-         (elmo-message-set-global-flags folder number set-flags local)
-         (setq visible (wl-summary-jump-to-msg number))
-         ;; set mark on buffer
-         (when visible
-           (wl-summary-update-persistent-mark)))))))
-
-(defsubst wl-summary-remove-flags-internal (&optional
-                                           number-or-numbers
-                                           flags
-                                           local)
-  (save-excursion
-    (let ((folder wl-summary-buffer-elmo-folder)
-         set-flags msg number-list visible)
-      (setq number-list (cond ((numberp number-or-numbers)
-                              (list number-or-numbers))
-                             ((and (not (null number-or-numbers))
-                                   (listp number-or-numbers))
-                              number-or-numbers)
-                             ((setq msg (wl-summary-message-number))
-                              ;; interactive
-                              (list msg))))
-      (if (null number-list)
-         (message "No message.")
-       (dolist (number number-list)
-         (setq set-flags (elmo-get-global-flags
-                          (elmo-message-flags folder number)))
-         (dolist (flag flags)
-           (setq set-flags (delq flag set-flags)))
-         (elmo-message-set-global-flags folder number set-flags local)
-         (setq visible (wl-summary-jump-to-msg number))
-         ;; set mark on buffer
-         (when visible
-           (wl-summary-update-persistent-mark)))))))
-
 (defun wl-summary-set-flags (&optional remove)
   (interactive "P")
   (if (eq 'flag (elmo-folder-type-internal wl-summary-buffer-elmo-folder))
       (error "Cannot process flags in this folder"))
   (wl-summary-set-flags-internal nil nil nil remove))
 
-(defun wl-summary-mark-as-important-internal (inverse
-                                             &optional number-or-numbers)
-  (if inverse
-      (wl-summary-remove-flags-internal number-or-numbers '(important))
-    (wl-summary-add-flags-internal number-or-numbers '(important))))
-
 (defun wl-summary-mark-as-important (&optional prompt)
   (interactive "P")
   (if (eq 'flag (elmo-folder-type-internal wl-summary-buffer-elmo-folder))
       (error "Cannot process flags in this folder"))
   (if prompt
       (wl-summary-set-flags-internal)
-    (wl-summary-mark-as-important-internal
+    (wl-summary-set-persistent-mark-internal
      (and (interactive-p)
          (elmo-message-flagged-p wl-summary-buffer-elmo-folder
                                  (wl-summary-message-number)
-                                 'important)))))
+                                 'important))
+     'important
+     nil nil nil (interactive-p))))
 
 ;;; Summary line.
 (defvar wl-summary-line-formatter nil)
@@ -3772,10 +3758,10 @@ Return non-nil if the mark is updated"
 Basically, it shows next line of the message.
 If optional argument ARG is specified, behave as followed.
 If ARG is number, jump to the message.
-Otherwise it shows previous line of th message."
+Otherwise it shows previous line of the message."
   (interactive "P")
   (cond ((numberp arg)
-        (unless (wl-summary-jump-to-msg arg)
+        (unless (wl-thread-jump-to-msg arg)
           (message "Message (#%d) was not found." arg)))
        (arg
         (wl-summary-prev-line-content))
@@ -3837,15 +3823,15 @@ Return t if message exists."
        (progn
          (set-buffer wl-message-buffer)
          t)
-      (if (wl-summary-no-mime-p folder)
-         (wl-summary-redisplay-no-mime-internal folder number)
-       (wl-summary-redisplay-internal folder number))
+      (wl-summary-redisplay-internal folder number nil
+                                    wl-summary-buffer-display-as-is)
       (when (buffer-live-p wl-message-buffer)
        (set-buffer wl-message-buffer))
       nil)))
 
 (defun wl-summary-target-mark-forward (&optional arg)
   (interactive "P")
+  (wl-summary-check-target-mark)
   (let ((mlist (nreverse (copy-sequence wl-summary-buffer-target-mark-list)))
        (summary-buf (current-buffer))
        (wl-draft-forward t)
@@ -3876,6 +3862,7 @@ Return t if message exists."
 
 (defun wl-summary-target-mark-reply-with-citation (&optional arg)
   (interactive "P")
+  (wl-summary-check-target-mark)
   (let ((mlist (nreverse (copy-sequence wl-summary-buffer-target-mark-list)))
        (summary-buf (current-buffer))
        change-major-mode-hook
@@ -4370,14 +4357,45 @@ Use function list is `wl-summary-write-current-folder-functions'."
            (wl-summary-redisplay)))
     (message "No last message.")))
 
+(defun wl-summary-toggle-mime (&optional no-mime)
+  "Toggle MIME decoding.
+If NO-MIME is non-nil, force displaying the message without MIME decoding
+and ask coding-system for the message."
+  (interactive "P")
+  (if no-mime
+      (wl-summary-redisplay-no-mime 'ask-coding)
+    (setq wl-summary-buffer-display-as-is
+         (not wl-summary-buffer-display-as-is))
+    (wl-summary-redisplay)
+    (wl-summary-update-modeline)
+    (message "MIME decoding: %s"
+            (if wl-summary-buffer-display-as-is "OFF" "ON"))))
+
 (defun wl-summary-redisplay (&optional arg)
+  "Redisplay message."
   (interactive "P")
-  (if (and (not arg)
-          (wl-summary-no-mime-p wl-summary-buffer-elmo-folder))
-      (wl-summary-redisplay-no-mime)
-    (wl-summary-redisplay-internal nil nil arg)))
+  (wl-summary-redisplay-internal nil nil arg
+                                wl-summary-buffer-display-as-is))
+
+(defun wl-summary-redisplay-all-header (&optional arg)
+  "Redisplay message with all header."
+  (interactive "P")
+  (wl-summary-redisplay-internal nil nil arg
+                                wl-summary-buffer-display-as-is 'all-header))
+
+(defun wl-summary-redisplay-no-mime (&optional ask-coding)
+  "Display message without MIME decoding.
+If ASK-CODING is non-nil, coding-system for the message is asked."
+  (interactive "P")
+  (let ((elmo-mime-display-as-is-coding-system
+        (if ask-coding
+            (or (read-coding-system "Coding system: ")
+                elmo-mime-display-as-is-coding-system)
+          elmo-mime-display-as-is-coding-system)))
+    (wl-summary-redisplay-internal nil nil nil 'as-is 'all-header)))
 
-(defun wl-summary-redisplay-internal (&optional folder number force-reload)
+(defun wl-summary-redisplay-internal (&optional folder number force-reload
+                                               as-is all-header)
   (let* ((folder (or folder wl-summary-buffer-elmo-folder))
         (num (or number (wl-summary-message-number)))
         (wl-mime-charset      wl-summary-buffer-mime-charset)
@@ -4407,7 +4425,7 @@ Use function list is `wl-summary-write-current-folder-functions'."
          (setq no-folder-mark
                ;; If cache is used, change folder-mark.
                (if (wl-message-redisplay folder num
-                                         'mime
+                                         as-is all-header
                                          (or
                                           force-reload
                                           (string= (elmo-folder-name-internal
@@ -4441,74 +4459,6 @@ Use function list is `wl-summary-write-current-folder-functions'."
          (run-hooks 'wl-summary-redisplay-hook))
       (message "No message to display."))))
 
-(defun wl-summary-redisplay-no-mime (&optional ask-coding)
-  "Display message without MIME decoding.
-If ASK-CODING is non-nil, coding-system for the message is asked."
-  (interactive "P")
-  (let ((elmo-mime-display-as-is-coding-system
-        (if ask-coding
-            (or (read-coding-system "Coding system: ")
-                elmo-mime-display-as-is-coding-system)
-          elmo-mime-display-as-is-coding-system)))
-    (wl-summary-redisplay-no-mime-internal)))
-
-(defun wl-summary-redisplay-no-mime-internal (&optional folder number)
-  (let* ((fld (or folder wl-summary-buffer-elmo-folder))
-        (num (or number (wl-summary-message-number)))
-        wl-break-pages)
-    (if num
-       (progn
-         (setq wl-summary-buffer-disp-msg t)
-         (setq wl-summary-buffer-last-displayed-msg
-               wl-summary-buffer-current-msg)
-         (setq wl-current-summary-buffer (current-buffer))
-         (wl-message-redisplay fld num 'as-is
-                               (string= (elmo-folder-name-internal fld)
-                                        wl-draft-folder))
-         (when (elmo-message-use-cache-p fld num)
-           (elmo-message-set-cached fld num t))
-         (ignore-errors
-           (if (elmo-message-flagged-p fld num 'unread)
-               (wl-summary-mark-as-read num); no-folder-mark)
-             (wl-summary-update-persistent-mark)))
-         (setq wl-summary-buffer-current-msg num)
-         (when wl-summary-recenter
-           (recenter (/ (- (window-height) 2) 2))
-           (if (not wl-summary-indent-length-limit)
-               (wl-horizontal-recenter)))
-         (wl-highlight-summary-displaying)
-         (run-hooks 'wl-summary-redisplay-hook))
-      (message "No message to display.")
-      (wl-ask-folder 'wl-summary-exit
-                    "No more messages. Type SPC to go to folder mode."))))
-
-(defun wl-summary-redisplay-all-header (&optional folder number)
-  (interactive)
-  (let* ((fld (or folder wl-summary-buffer-elmo-folder))
-        (num (or number (wl-summary-message-number)))
-        (wl-mime-charset      wl-summary-buffer-mime-charset)
-        (default-mime-charset wl-summary-buffer-mime-charset))
-    (if num
-       (progn
-         (setq wl-summary-buffer-disp-msg t)
-         (setq wl-summary-buffer-last-displayed-msg
-               wl-summary-buffer-current-msg)
-         (setq wl-current-summary-buffer (current-buffer))
-         (when (elmo-message-use-cache-p fld num)
-           (elmo-message-set-cached fld num t))
-         (if (wl-message-redisplay fld num 'all-header
-                                   (string= (elmo-folder-name-internal fld)
-                                            wl-draft-folder))
-             (wl-summary-mark-as-read num))
-         (setq wl-summary-buffer-current-msg num)
-         (when wl-summary-recenter
-           (recenter (/ (- (window-height) 2) 2))
-           (if (not wl-summary-indent-length-limit)
-               (wl-horizontal-recenter)))
-         (wl-highlight-summary-displaying)
-         (run-hooks 'wl-summary-redisplay-hook))
-      (message "No message to display."))))
-
 (defun wl-summary-jump-to-current-message ()
   "Jump into Message buffer."
   (interactive)
@@ -4760,14 +4710,13 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
 
 (defun wl-summary-target-mark-print ()
   (interactive)
-  (if (null wl-summary-buffer-target-mark-list)
-      (message "No marked message.")
-    (when (y-or-n-p "Print all marked messages. OK? ")
-      (while (car wl-summary-buffer-target-mark-list)
-       (let ((num (car wl-summary-buffer-target-mark-list)))
-         (wl-thread-jump-to-msg num)
-         (wl-summary-print-message)
-         (wl-summary-unmark))))))
+  (wl-summary-check-target-mark)
+  (when (y-or-n-p "Print all marked messages. OK? ")
+    (while (car wl-summary-buffer-target-mark-list)
+      (let ((num (car wl-summary-buffer-target-mark-list)))
+       (wl-thread-jump-to-msg num)
+       (wl-summary-print-message)
+       (wl-summary-unmark)))))
 
 (defun wl-summary-folder-info-update ()
   (wl-folder-set-folder-updated
@@ -4787,10 +4736,11 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
   (interactive "P")
   (elmo-folder-pack-numbers wl-summary-buffer-elmo-folder)
   (let (wl-use-scoring)
-    (wl-summary-rescan nil nil t)))
+    (wl-summary-rescan nil nil nil t)))
 
 (defun wl-summary-target-mark-uudecode ()
   (interactive)
+  (wl-summary-check-target-mark)
   (let ((mlist (reverse wl-summary-buffer-target-mark-list))
        (summary-buf (current-buffer))
        (tmp-buf (get-buffer-create "*WL UUENCODE*"))