Synch up with main trunk, and prepare the release 2.12.0.
[elisp/wanderlust.git] / wl / wl-summary.el
index afedf62..8cee114 100644 (file)
 (defvar wl-summary-buffer-mode-line-formatter nil)
 (defvar wl-summary-buffer-mode-line nil)
 (defvar wl-summary-buffer-display-mime-mode 'mime)
-(defvar wl-summary-buffer-display-all-header nil)
+(defvar wl-summary-buffer-display-header-mode 'partial)
 (defvar wl-summary-buffer-event-handler nil)
 
 (defvar wl-thread-indent-level-internal nil)
 (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-mime-mode)
-(make-variable-buffer-local 'wl-summary-buffer-display-all-header)
+(make-variable-buffer-local 'wl-summary-buffer-display-header-mode)
 (make-variable-buffer-local 'wl-summary-buffer-event-handler)
 
 (defvar wl-datevec)
@@ -398,6 +398,11 @@ See also variable `wl-use-petname'."
     ()
   (setq wl-summary-mode-map (make-keymap))
   (suppress-keymap wl-summary-mode-map)
+  (substitute-key-definition 'kill-buffer
+                            'wl-summary-mimic-kill-buffer
+                            wl-summary-mode-map
+                            global-map)
+  ;; 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-top)
@@ -580,6 +585,15 @@ See also variable `wl-use-petname'."
    "Menu used in Summary mode."
    wl-summary-mode-menu-spec))
 
+(defun wl-summary-mimic-kill-buffer (buffer)
+  "Kill the current (Summary) buffer with query."
+  (interactive "bKill buffer: ")
+  (if (or (not buffer)
+         (string-equal buffer "")
+         (string-equal buffer (buffer-name)))
+      (wl-summary-exit 'force-exit)
+    (kill-buffer buffer)))
+
 (defsubst wl-summary-message-visible-p (number)
   "Return non-nil if the message with NUMBER is visible."
   (or (eq wl-summary-buffer-view 'sequence)
@@ -620,6 +634,19 @@ See also variable `wl-use-petname'."
        (wl-summary-lazy-update-mark
         (list 'wl-summary-update-mark-window))))
 
+(defun wl-summary-after-resize-function (frame)
+  "Called from `window-size-change-functions'."
+  (save-excursion
+    (save-selected-window
+      (select-frame frame)
+      (walk-windows
+       (lambda (window)
+        (set-buffer (window-buffer window))
+        (when (eq major-mode 'wl-summary-mode)
+          (run-hook-with-args 'wl-summary-buffer-window-scroll-functions
+                              window)))
+       'nomini frame))))
+
 ;; Handler of event from elmo-folder
 (eval-and-compile
   (luna-define-class wl-summary-event-handler (elmo-event-handler)
@@ -629,12 +656,19 @@ See also variable `wl-use-petname'."
 (luna-define-method elmo-event-handler-flag-changed ((handler
                                                      wl-summary-event-handler)
                                                     numbers)
-  (with-current-buffer (wl-summary-event-handler-buffer-internal handler)
-    (save-excursion
-      (dolist (number numbers)
-       (when (and (wl-summary-message-visible-p number)
-                  (wl-summary-jump-to-msg number))
-         (wl-summary-update-persistent-mark number))))))
+  (save-excursion
+    (set-buffer (wl-summary-event-handler-buffer-internal handler))
+    (dolist (number numbers)
+      (when (and (wl-summary-message-visible-p number)
+                (wl-summary-jump-to-msg number))
+       (wl-summary-update-persistent-mark number)))))
+
+(defun wl-summary-buffer-detach ()
+  (when (and (eq major-mode 'wl-summary-mode)
+            wl-summary-buffer-elmo-folder
+            wl-summary-buffer-event-handler)
+    (elmo-folder-remove-handler wl-summary-buffer-elmo-folder
+                               wl-summary-buffer-event-handler)))
 
 (defun wl-status-update ()
   (interactive)
@@ -783,6 +817,7 @@ you."
          wl-summary-buffer-persistent-mark-column persistent)))
 
 (defun wl-summary-buffer-set-folder (folder)
+  (wl-summary-buffer-detach)
   (if (stringp folder)
       (setq folder (wl-folder-get-elmo-folder folder)))
   (setq wl-summary-buffer-elmo-folder folder)
@@ -866,7 +901,8 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
 ;;;(setq default-directory (or wl-tmp-dir (expand-file-name "~/")))
   (setq buffer-read-only t)
   (setq truncate-lines t)
-  (setq show-trailing-whitespace nil)
+  (when (boundp 'show-trailing-whitespace)
+    (setq show-trailing-whitespace nil))
 ;;;(make-local-variable 'tab-width)
 ;;;(setq tab-width 1)
   (buffer-disable-undo (current-buffer))
@@ -880,7 +916,12 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
     (let ((hook (if wl-on-xemacs 'pre-idle-hook 'window-scroll-functions)))
       (make-local-hook hook)
       (dolist (function wl-summary-buffer-window-scroll-functions)
-       (add-hook hook function nil t))))
+       (add-hook hook function nil t)))
+    (add-hook 'window-size-change-functions
+             #'wl-summary-after-resize-function))
+  (dolist (hook '(change-major-mode-hook kill-buffer-hook))
+    (make-local-hook hook)
+    (add-hook hook #'wl-summary-buffer-detach nil t))
   ;; This hook may contain the function `wl-setup-summary' for reasons
   ;; of system internal to accord facilities for the Emacs variants.
   (run-hooks 'wl-summary-mode-hook))
@@ -1196,10 +1237,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
          (progn
            (wl-summary-save-view)
            (if (or force-exit (not sticky))
-               (progn
-                 (elmo-folder-close wl-summary-buffer-elmo-folder)
-                 (elmo-folder-remove-handler wl-summary-buffer-elmo-folder
-                                             wl-summary-buffer-event-handler))
+               (elmo-folder-close wl-summary-buffer-elmo-folder)
              (elmo-folder-commit wl-summary-buffer-elmo-folder)
              (elmo-folder-check wl-summary-buffer-elmo-folder))
            (if wl-use-scoring (wl-score-save)))
@@ -2320,9 +2358,6 @@ If ARG, without confirm."
          (if other-window
              (delete-other-windows))
          (set-buffer buf)
-         (when wl-summary-buffer-event-handler
-           (elmo-folder-remove-handler wl-summary-buffer-elmo-folder
-                                       wl-summary-buffer-event-handler))
          (unless (eq major-mode 'wl-summary-mode)
            (wl-summary-mode))
          (wl-summary-buffer-set-folder folder)
@@ -2540,7 +2575,7 @@ If ARG, without confirm."
 (defun wl-summary-default-subject-filter (subject)
   (setq subject (elmo-replace-in-string subject "[ \t]*\\(re\\|was\\)[:>]" ""))
   (setq subject (elmo-replace-in-string subject "[ \t]" ""))
-  (elmo-replace-in-string subject "^\\[.*\\]" ""))
+  (elmo-replace-in-string subject "^\\[[^]]*\\]" ""))
 
 (defun wl-summary-subject-equal (subject1 subject2)
   (string= (funcall wl-summary-subject-filter-function subject1)
@@ -4110,9 +4145,7 @@ Reply to author if invoked with ARG."
     (when number
       (save-excursion
        (wl-summary-set-message-buffer-or-redisplay))
-      (setq mes-buf wl-message-buffer)
       (wl-message-select-buffer wl-message-buffer)
-      (set-buffer mes-buf)
       (condition-case err
          (when (setq mes-buf (wl-message-get-original-buffer))
            (wl-draft-reply mes-buf arg summary-buf number)
@@ -4175,7 +4208,6 @@ Use function list is `wl-summary-write-current-folder-functions'."
        (number (wl-summary-message-number))
        (summary-buf (current-buffer))
        (wl-draft-forward t)
-       mes-buf
        entity subject num)
     (if (null number)
        (message "No message.")
@@ -4187,17 +4219,10 @@ Use function list is `wl-summary-write-current-folder-functions'."
          ;; Reload.
          (wl-summary-redisplay-internal nil nil 'force-reload)
        (wl-summary-redisplay-internal folder number))
-      (setq mes-buf wl-message-buffer)
-      (wl-message-select-buffer mes-buf)
-      ;; get original subject.
-      (if summary-buf
-         (save-excursion
-           (set-buffer summary-buf)
-           (setq subject
-                 (or (elmo-message-entity-field
-                      (elmo-message-entity folder number) 'subject 'decode)
-                     ""))))
-      (set-buffer mes-buf)
+      (wl-message-select-buffer wl-message-buffer)
+      (setq subject (with-current-buffer
+                       wl-message-buffer-original-buffer
+                     (std11-field-body "Subject")))
       (wl-draft-forward subject summary-buf number)
       (with-current-buffer summary-buf (run-hooks 'wl-summary-forward-hook))
       (unless without-setup-hook
@@ -4370,6 +4395,24 @@ Use function list is `wl-summary-write-current-folder-functions'."
            (wl-summary-redisplay)))
     (message "No last message.")))
 
+(defun wl-summary-message-display-type ()
+  (when (and wl-summary-buffer-disp-msg
+            (buffer-live-p wl-message-buffer)
+            wl-summary-buffer-current-msg
+            (wl-summary-message-number)
+            (= (wl-summary-message-number) wl-summary-buffer-current-msg))
+    (wl-message-buffer-display-type wl-message-buffer)))
+
+(defun wl-summary-buffer-display-mime-mode ()
+  (or (wl-message-display-type-property (wl-summary-message-display-type)
+                                       :mime)
+      wl-summary-buffer-display-mime-mode))
+
+(defun wl-summary-buffer-display-header-mode ()
+  (or (wl-message-display-type-property (wl-summary-message-display-type)
+                                       :header)
+      wl-summary-buffer-display-header-mode))
+
 (defun wl-summary-toggle-mime (&optional arg)
   "Toggle MIME decoding.
 If ARG is non-nil, ask coding-system to display the message in the current
@@ -4380,37 +4423,39 @@ If ARG is numeric number, decode message as following:
 2: Enable MIME analysis only for headers.
 3: Disable MIME analysis."
   (interactive "P")
-  (let ((rest (memq wl-summary-buffer-display-mime-mode
-                   wl-summary-display-mime-mode-list))
+  (let ((mime-mode (wl-summary-buffer-display-mime-mode))
        (elmo-mime-display-as-is-coding-system
         elmo-mime-display-as-is-coding-system))
-    (if (numberp arg)
-       (setq wl-summary-buffer-display-mime-mode
-             (case arg
-               (1 'mime)
-               (2 'header-only)
-               (3 'as-is)))
-      (if arg
-         ;; Specify coding-system (doesn't change the MIME mode).
-         (setq elmo-mime-display-as-is-coding-system
-               (if (and arg (not (eq wl-summary-buffer-display-mime-mode
-                                     'mime)))
-                   (or (read-coding-system "Coding system: ")
-                       elmo-mime-display-as-is-coding-system)
-                 elmo-mime-display-as-is-coding-system))
+    (if (and (consp arg) (> (prefix-numeric-value arg) 4))
+       (progn
+         (setq wl-summary-buffer-display-mime-mode mime-mode)
+         (wl-summary-update-modeline))
+      (cond
+       ((numberp arg)
+       (setq mime-mode (case arg
+                         (1 'mime)
+                         (2 'header-only)
+                         (3 'as-is))))
+       (arg
+       ;; Specify coding-system (doesn't change the MIME mode).
+       (setq elmo-mime-display-as-is-coding-system
+             (if (and arg
+                      (not (wl-message-mime-analysis-p
+                            (wl-summary-message-display-type))))
+                 (or (read-coding-system "Coding system: ")
+                     elmo-mime-display-as-is-coding-system)
+               elmo-mime-display-as-is-coding-system)))
+       (t
        ;; Change the MIME mode.
-       (if (cadr rest)
-           (setq wl-summary-buffer-display-mime-mode (cadr rest))
-         (setq wl-summary-buffer-display-mime-mode
-               (car wl-summary-display-mime-mode-list)))))
-    (wl-summary-redisplay arg)
-    (wl-summary-update-modeline)
+       (setq mime-mode (or (cadr (memq mime-mode
+                                       wl-summary-display-mime-mode-list))
+                           (car wl-summary-display-mime-mode-list)))))
+      (wl-summary-redisplay-internal nil nil arg mime-mode))
     (message "MIME decoding: %s%s"
-            (upcase (symbol-name wl-summary-buffer-display-mime-mode))
-            (if (and arg
-                     (not (numberp arg))
-                     (not (eq wl-summary-buffer-display-mime-mode
-                              'mime)))
+            (upcase (symbol-name mime-mode))
+            (if (and (not (eq mime-mode 'mime))
+                     (not (eq elmo-mime-display-as-is-coding-system
+                              wl-cs-autoconv)))
                 (concat " ("
                         (symbol-name elmo-mime-display-as-is-coding-system)
                         ")")
@@ -4419,20 +4464,24 @@ If ARG is numeric number, decode message as following:
 (defun wl-summary-redisplay (&optional arg)
   "Redisplay message."
   (interactive "P")
-  (wl-summary-redisplay-internal nil nil arg))
+  (apply #'wl-summary-redisplay-internal nil nil arg
+        (unless (and (consp arg) (> (prefix-numeric-value arg) 4))
+          (list wl-summary-buffer-display-mime-mode
+                wl-summary-buffer-display-header-mode))))
 
 (defun wl-summary-toggle-all-header (&optional arg)
   "Toggle displaying message with all header."
   (interactive "P")
-  (setq wl-summary-buffer-display-all-header
-       (not wl-summary-buffer-display-all-header))
-  (wl-summary-redisplay-internal nil nil arg))
+  (let ((header-mode (wl-summary-buffer-display-header-mode)))
+    (if (and (consp arg) (> (prefix-numeric-value arg) 4))
+       (setq wl-summary-buffer-display-header-mode header-mode)
+      (wl-summary-redisplay-internal
+       nil nil arg nil
+       (if (eq header-mode 'all) 'partial 'all)))))
 
 (defun wl-summary-redisplay-internal (&optional folder number force-reload
-                                               mode all-header)
+                                               mime-mode header-mode)
   (let* ((folder (or folder wl-summary-buffer-elmo-folder))
-        (mode (or mode wl-summary-buffer-display-mime-mode))
-        (all-header (or all-header wl-summary-buffer-display-all-header))
         (num (or number (wl-summary-message-number)))
         (wl-mime-charset      wl-summary-buffer-mime-charset)
         (default-mime-charset wl-summary-buffer-mime-charset)
@@ -4460,13 +4509,16 @@ If ARG is numeric number, decode message as following:
          (setq wl-current-summary-buffer (current-buffer))
          (setq no-folder-mark
                ;; If cache is used, change folder-mark.
-               (if (wl-message-redisplay folder num
-                                         mode all-header
-                                         (or
-                                          force-reload
-                                          (string= (elmo-folder-name-internal
-                                                    folder)
-                                                   wl-draft-folder)))
+               (if (wl-message-redisplay
+                    folder num
+                    (wl-message-make-display-type
+                     (or mime-mode
+                         (wl-summary-buffer-display-mime-mode))
+                     (or header-mode
+                         (wl-summary-buffer-display-header-mode)))
+                    (or force-reload
+                        (string= (elmo-folder-name-internal folder)
+                                 wl-draft-folder)))
                    nil
                  ;; plugged, then leave folder-mark.
                  (if (and (not (elmo-folder-local-p