* wl-fldmgr.el (wl-fldmgr-make-indent): Change from macro to function.
[elisp/wanderlust.git] / wl / wl-summary.el
index 73a0bae..d1c6670 100644 (file)
@@ -37,6 +37,7 @@
 
 (require 'elmo)
 (require 'elmo-multi)
+(eval-when-compile (require 'elmo-filter))
 (require 'wl-message)
 (require 'wl-vars)
 (require 'wl-highlight)
@@ -69,8 +70,8 @@
 (defvar wl-summary-buffer-elmo-folder nil)
 
 (defmacro wl-summary-buffer-folder-name ()
-  (` (and wl-summary-buffer-elmo-folder
-         (elmo-folder-name-internal wl-summary-buffer-elmo-folder))))
+  `(and wl-summary-buffer-elmo-folder
+       (elmo-folder-name-internal wl-summary-buffer-elmo-folder)))
 
 (defvar wl-summary-buffer-disp-msg    nil)
 (defvar wl-summary-buffer-disp-folder nil)
 (defvar wl-persistent-mark)
 
 (defmacro wl-summary-sticky-buffer-name (name)
-  (` (concat wl-summary-buffer-name ":" (, name))))
+  `(concat wl-summary-buffer-name ":" ,name))
 
 (defun wl-summary-default-subject (subject-string)
   (if (string-match "^[ \t]*\\[[^:]+[,: ][0-9]+\\][ \t]*" subject-string)
@@ -290,7 +291,8 @@ See also variable `wl-use-petname'."
      ["Resend bounced mail" wl-summary-resend-bounced-mail t]
      ["Enter the message" wl-summary-jump-to-current-message t]
      ["Pipe message" wl-summary-pipe-message t]
-     ["Print message" wl-summary-print-message t])
+     ["Print message" wl-summary-print-message t]
+     ["View raw message" wl-summary-display-raw t])
     ("Thread Operation"
      ["Open or Close" wl-thread-open-close (eq wl-summary-buffer-view 'thread)]
      ["Open all"     wl-thread-open-all (eq wl-summary-buffer-view 'thread)]
@@ -386,6 +388,7 @@ See also variable `wl-use-petname'."
   ;; basic commands
   (define-key wl-summary-mode-map " "    'wl-summary-read)
   (define-key wl-summary-mode-map "."    'wl-summary-redisplay)
+  (define-key wl-summary-mode-map ","    'wl-summary-display-raw)
   (define-key wl-summary-mode-map "<"    'wl-summary-display-top)
   (define-key wl-summary-mode-map ">"    'wl-summary-display-bottom)
   (define-key wl-summary-mode-map "\177" 'wl-summary-prev-page)
@@ -825,6 +828,7 @@ you."
        wl-summary-highlight
        temp persistent)
     (with-temp-buffer
+      (set-buffer-multibyte t)
       (setq wl-summary-buffer-number-column column
            wl-summary-buffer-line-formatter formatter
            wl-summary-buffer-weekday-name-lang lang)
@@ -1003,7 +1007,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
               (count (elmo-find-list-match-value
                       elmo-mailing-list-count-spec-list
                       getter)))
-         (cons name (and count (string-to-int count)))))))
+         (cons name (and count (string-to-number count)))))))
 
 (defun wl-summary-overview-entity-compare-by-list-info (x y)
   "Compare entity X and Y by mailing-list info."
@@ -1032,15 +1036,15 @@ This function is defined by `wl-summary-define-sort-command'." sort-by)
             (wl-summary-rescan ,(symbol-name sort-by) reverse)))))
 
 (defun wl-summary-sort-function-from-spec (spec reverse)
-  (let (funtion)
+  (let (function)
     (when (string-match "^!\\(.+\\)$" spec)
       (setq spec (match-string 1 spec)
            reverse (not reverse)))
-    (setq funtion
+    (setq function
          (intern (format "wl-summary-overview-entity-compare-by-%s" spec)))
     (if reverse
-       `(lambda (x y) (not (,funtion x y)))
-      funtion)))
+       `(lambda (x y) (not (,function x y)))
+      function)))
 
 (defun wl-summary-sort-messages (numbers sort-by reverse)
   (let* ((functions (mapcar
@@ -1829,7 +1833,7 @@ If ARG is non-nil, checking is omitted."
       (wl-summary-update-modeline)
       (message "Resuming cache status...done"))))
 
-(defun wl-summary-delete-messages-on-buffer (msgs &optional deleting-info)
+(defun wl-summary-delete-messages-on-buffer (msgs)
   (interactive)
   (save-excursion
     (let ((inhibit-read-only t)
@@ -1837,7 +1841,6 @@ If ARG is non-nil, checking is omitted."
          (msgs2 msgs)
          (len (length msgs))
          (i 0)
-         ;(deleting-info (or deleting-info "Deleting..."))
          update-list)
       (elmo-kill-buffer wl-summary-search-buf-name)
       (while msgs
@@ -1862,7 +1865,6 @@ If ARG is non-nil, checking is omitted."
              "Updating deleted thread"
            (wl-thread-update-line-msgs updates)
            (wl-thread-cleanup-symbols msgs2))))
-      ;;(message (concat deleting-info "done"))
       (wl-summary-count-unread)
       (wl-summary-update-modeline)
       (wl-summary-folder-info-update))))
@@ -2155,7 +2157,7 @@ This function is defined for `window-scroll-functions'"
     (beginning-of-line)
     (if (or (re-search-forward "\r\\(-?[0-9]+\\)" (point-at-eol) t)
            (re-search-forward "^ *\\(-?[0-9]+\\)" (point-at-eol) t))
-       (string-to-int (wl-match-buffer 1))
+       (string-to-number (wl-match-buffer 1))
       nil)))
 
 (defun wl-summary-delete-all-msgs ()
@@ -2299,7 +2301,7 @@ If ARG, without confirm."
     (wl-summary-mode)
     (wl-summary-buffer-set-folder folder)
     (let ((buffer-read-only nil))
-      (insert-buffer cur-buf))
+      (insert-buffer-substring cur-buf))
     (set-buffer-modified-p nil)
     (while copy-variables
       (set (car copy-variables)
@@ -2380,10 +2382,13 @@ If ARG, without confirm."
               (eq major-mode 'wl-summary-mode)) ; called in summary.
       (setq wl-summary-last-visited-folder (wl-summary-buffer-folder-name))
       (run-hooks 'wl-summary-exit-pre-hook)
-      (if (or force-exit (not (wl-summary-sticky-p)))
+      (let ((discard-contents (or force-exit (not (wl-summary-sticky-p)))))
+       (when discard-contents
          (wl-summary-cleanup-temp-marks))
-      (wl-summary-save-view)
-      (elmo-folder-commit wl-summary-buffer-elmo-folder)
+       (wl-summary-save-view)
+       (if discard-contents
+           (elmo-folder-close wl-summary-buffer-elmo-folder)
+         (elmo-folder-commit wl-summary-buffer-elmo-folder)))
       (if (and (wl-summary-sticky-p) force-exit)
          (kill-buffer (current-buffer))))
     (setq buf (wl-summary-get-buffer-create (elmo-folder-name-internal folder)
@@ -2627,13 +2632,13 @@ If ARG, without confirm."
           (funcall wl-summary-subject-filter-function subject2)))
 
 (defmacro wl-summary-put-alike (alike)
-  (` (elmo-set-hash-val (format "#%d" (wl-count-lines))
-                       (, alike)
-                       wl-summary-alike-hashtb)))
+  `(elmo-set-hash-val (format "#%d" (wl-count-lines))
+                     ,alike
+                     wl-summary-alike-hashtb))
 
 (defmacro wl-summary-get-alike ()
-  (` (elmo-get-hash-val (format "#%d" (wl-count-lines))
-                       wl-summary-alike-hashtb)))
+  `(elmo-get-hash-val (format "#%d" (wl-count-lines))
+                     wl-summary-alike-hashtb))
 
 (defun wl-summary-insert-headers (folder func &optional mime-decode)
   (let ((numbers (elmo-folder-list-messages folder 'visible t))
@@ -4219,8 +4224,7 @@ Return t if message exists."
             nil)))))
 
 (defun wl-summary-reply (&optional arg without-setup-hook)
-  "Reply to current message. Default is \"wide\" reply.
-Reply to author if invoked with ARG."
+  "Reply to current message. See also `wl-draft-reply'."
   (interactive "P")
   (let ((folder wl-summary-buffer-elmo-folder)
        (number (wl-summary-message-number))
@@ -4409,36 +4413,34 @@ Use function list is `wl-summary-write-current-folder-functions'."
                (wl-summary-entity-info-msg next-entity finfo)))))))))
 
 (defun wl-summary-get-prev-folder ()
-  (let ((folder-buf (get-buffer wl-folder-buffer-name))
-       last-entity cur-id)
+  (let ((folder-buf (get-buffer wl-folder-buffer-name)))
     (when folder-buf
-      (setq cur-id (save-excursion (set-buffer folder-buf)
-                                  wl-folder-buffer-cur-entity-id))
-      (wl-folder-get-prev-folder cur-id))))
+      (wl-folder-get-prev-folder
+       (with-current-buffer folder-buf
+        wl-folder-buffer-cur-entity-id)))))
 
 (defun wl-summary-get-next-folder ()
-  (let ((folder-buf (get-buffer wl-folder-buffer-name))
-       cur-id)
+  (let ((folder-buf (get-buffer wl-folder-buffer-name)))
     (when folder-buf
-      (setq cur-id (save-excursion (set-buffer folder-buf)
-                                  wl-folder-buffer-cur-entity-id))
-      (wl-folder-get-next-folder cur-id))))
+      (wl-folder-get-next-folder
+       (with-current-buffer folder-buf
+        wl-folder-buffer-cur-entity-id)))))
 
 (defun wl-summary-get-next-unread-folder ()
-  (let ((folder-buf (get-buffer wl-folder-buffer-name))
-       cur-id)
+  (let ((folder-buf (get-buffer wl-folder-buffer-name)))
     (when folder-buf
-      (setq cur-id (save-excursion (set-buffer folder-buf)
-                                  wl-folder-buffer-cur-entity-id))
-      (wl-folder-get-next-folder cur-id 'unread))))
+      (wl-folder-get-next-folder
+       (with-current-buffer folder-buf
+        wl-folder-buffer-cur-entity-id)
+       'unread))))
 
 (defun wl-summary-get-prev-unread-folder ()
-  (let ((folder-buf (get-buffer wl-folder-buffer-name))
-       cur-id)
+  (let ((folder-buf (get-buffer wl-folder-buffer-name)))
     (when folder-buf
-      (setq cur-id (save-excursion (set-buffer folder-buf)
-                                  wl-folder-buffer-cur-entity-id))
-      (wl-folder-get-prev-folder cur-id 'unread))))
+      (wl-folder-get-prev-folder
+       (with-current-buffer folder-buf
+        wl-folder-buffer-cur-entity-id)
+       'unread))))
 
 (defun wl-summary-down (&optional interactive skip-no-unread)
   (interactive)
@@ -4742,6 +4744,31 @@ If ARG is numeric number, decode message as following:
        (if message-buf (set-buffer message-buf))
        (wl-draft-edit-string (buffer-substring (point-min) (point-max)))))))
 
+(defun wl-summary-display-raw (&optional arg)
+  "Display current message in raw format."
+  (interactive)
+  (let ((number (wl-summary-message-number))
+       (folder wl-summary-buffer-elmo-folder))
+    (if number
+       (let ((raw (elmo-message-fetch-string 
+                   folder number
+                   (elmo-find-fetch-strategy folder number)))
+             (raw-buffer (get-buffer-create "*wl:raw message*"))
+             (raw-mode-map (make-sparse-keymap)))
+         (with-current-buffer raw-buffer
+           (toggle-read-only -1)
+           (erase-buffer)
+           (princ raw raw-buffer)
+           (toggle-read-only t)
+           (goto-char (point-min))
+           (switch-to-buffer-other-window raw-buffer)
+           (define-key raw-mode-map "l" 'toggle-truncate-lines)
+           (define-key raw-mode-map "q" 'kill-buffer-and-window)
+           (define-key raw-mode-map "," 'kill-buffer-and-window)
+           (use-local-map raw-mode-map)))
+      (message "No message to display."))
+    number))
+
 (defun wl-summary-save (&optional arg wl-save-dir)
   "Save current message to disk."
   (interactive)
@@ -4798,8 +4825,8 @@ If ARG is numeric number, decode message as following:
   (interactive (list current-prefix-arg nil))
   (if (null (wl-summary-message-number))
       (message "No message.")
-    (setq command (read-string "Shell command on message: "
-                              wl-summary-shell-command-last))
+    (setq command (wl-read-shell-command "Shell command on message: "
+                                        wl-summary-shell-command-last))
     (if (y-or-n-p "Send this message to pipe? ")
        (wl-summary-pipe-message-subr prefix command))))
 
@@ -4808,8 +4835,9 @@ If ARG is numeric number, decode message as following:
   (interactive (list current-prefix-arg nil))
   (if (null wl-summary-buffer-target-mark-list)
       (message "No marked message.")
-    (setq command (read-string "Shell command on each marked message: "
-                              wl-summary-shell-command-last))
+    (setq command (wl-read-shell-command
+                  "Shell command on each marked message: "
+                  wl-summary-shell-command-last))
     (when (y-or-n-p "Send each marked message to pipe? ")
       (while (car wl-summary-buffer-target-mark-list)
        (let ((num (car wl-summary-buffer-target-mark-list)))
@@ -5026,14 +5054,27 @@ If ARG is numeric number, decode message as following:
 ;;                                         sum))
 ;;     (message "Dropping...done"))))
 
+(defun wl-summary-previous-message-number (msg)
+  "Return a message number previous to the message specified by MSG."
+  (let ((list wl-summary-buffer-number-list)
+       previous)
+    (while (and list (not (eq msg (car list))))
+      (setq previous (car list))
+      (setq list (cdr list)))
+    previous))
+
+(defun wl-summary-next-message-number (msg)
+  "Return a message number next to the message specified by MSG."
+  (cadr (memq msg wl-summary-buffer-number-list)))
+
 (defun wl-summary-default-get-next-msg (msg)
   (or (wl-summary-next-message msg
                               (if wl-summary-move-direction-downward 'down
                                 'up)
                               nil)
-      (cadr (memq msg (if wl-summary-move-direction-downward
-                         wl-summary-buffer-number-list
-                       (reverse wl-summary-buffer-number-list))))))
+      (if wl-summary-move-direction-downward
+         (wl-summary-next-message-number msg)
+       (wl-summary-previous-message-number msg))))
 
 (defun wl-summary-save-current-message ()
   "Save current message for `wl-summary-yank-saved-message'."