Synch with the semi-1_14 branch.
[elisp/semi.git] / mime-play.el
index f412dd9..187cfb6 100644 (file)
 (require 'mime-view)
 (require 'alist)
 (require 'filename)
+(require 'eword-decode)
 
 (eval-when-compile
   (condition-case nil
       (require 'bbdb)
-    (error (defvar bbdb-buffer-name nil)))
-  )
+    (error (defvar bbdb-buffer-name nil))))
+
+(defcustom mime-save-directory "~/"
+  "*Name of the directory where MIME entity will be saved in.
+If t, it means current directory."
+  :group 'mime-view
+  :type '(choice (const :tag "Current directory" t)
+                (directory)))
 
 (defvar mime-acting-situation-example-list nil)
 
 (add-hook 'kill-emacs-hook 'mime-save-acting-situation-examples)
 
 (defun mime-reduce-acting-situation-examples ()
-  (let* ((rest mime-acting-situation-example-list)
-        (min-example (car rest))
-        (min-score (cdr min-example)))
-    (while rest
-      (let* ((example (car rest))
-            (score (cdr example)))
-       (cond ((< score min-score)
-              (setq min-score score
-                    min-example example)
-              )
-             ((= score min-score)
-              (if (<= (length (car example))(length (car min-example)))
-                  (setq min-example example)
-                ))
-             ))
-      (setq rest (cdr rest)))
-    (setq mime-acting-situation-example-list
-         (delq min-example mime-acting-situation-example-list))
-    (setq min-example (car min-example))
-    (let ((examples mime-acting-situation-example-list)
-         (max-score 0)
-         max-examples)
-      (while examples
-       (let* ((ret (mime-compare-situation-with-example min-example
-                                                        (caar examples)))
-              (ret-score (car ret)))
-         (cond ((> ret-score max-score)
-                (setq max-score ret-score
-                      max-examples (list (cdr ret)))
-                )
-               ((= ret-score max-score)
-                (setq max-examples (cons (cdr ret) max-examples))
-                )))
-       (setq examples (cdr examples)))
-      (while max-examples
-       (let* ((example (car max-examples))
-              (cell (assoc example mime-acting-situation-example-list)))
-         (if cell
-             (setcdr cell (1+ (cdr cell)))
-           (setq mime-acting-situation-example-list
-                 (cons (cons example 0)
-                       mime-acting-situation-example-list))
-           ))
-       (setq max-examples (cdr max-examples))
-       ))))
+  (let ((len (length mime-acting-situation-example-list))
+       i ir ic j jr jc ret
+       dest d-i d-j
+       (max-sim 0) sim
+       min-det-ret det-ret
+       min-det-org det-org
+       min-freq freq)
+    (setq i 0
+         ir mime-acting-situation-example-list)
+    (while (< i len)
+      (setq ic (car ir)
+           j 0
+           jr mime-acting-situation-example-list)
+      (while (< j len)
+       (unless (= i j)
+         (setq jc (car jr))
+         (setq ret (mime-compare-situation-with-example (car ic)(car jc))
+               sim (car ret)
+               det-ret (+ (length (car ic))(length (car jc)))
+               det-org (length (cdr ret))
+               freq (+ (cdr ic)(cdr jc)))
+         (cond ((< max-sim sim)
+                (setq max-sim sim
+                      min-det-ret det-ret
+                      min-det-org det-org
+                      min-freq freq
+                      d-i i
+                      d-j j
+                      dest (cons (cdr ret) freq)))
+               ((= max-sim sim)
+                (cond ((> min-det-ret det-ret)
+                       (setq min-det-ret det-ret
+                             min-det-org det-org
+                             min-freq freq
+                             d-i i
+                             d-j j
+                             dest (cons (cdr ret) freq)))
+                      ((= min-det-ret det-ret)
+                       (cond ((> min-det-org det-org)
+                              (setq min-det-org det-org
+                                    min-freq freq
+                                    d-i i
+                                    d-j j
+                                    dest (cons (cdr ret) freq)))
+                             ((= min-det-org det-org)
+                              (cond ((> min-freq freq)
+                                     (setq min-freq freq
+                                           d-i i
+                                           d-j j
+                                           dest (cons (cdr ret) freq)))))))))))
+       (setq jr (cdr jr)
+             j (1+ j)))
+      (setq ir (cdr ir)
+           i (1+ i)))
+    (if (> d-i d-j)
+       (setq i d-i
+             d-i d-j
+             d-j i))
+    (setq jr (nthcdr (1- d-j) mime-acting-situation-example-list))
+    (setcdr jr (cddr jr))
+    (if (= d-i 0)
+       (setq mime-acting-situation-example-list
+             (cdr mime-acting-situation-example-list))
+      (setq ir (nthcdr (1- d-i) mime-acting-situation-example-list))
+      (setcdr ir (cddr ir)))
+    (if (setq ir (assoc (car dest) mime-acting-situation-example-list))
+       (setcdr ir (+ (cdr ir)(cdr dest)))
+      (setq mime-acting-situation-example-list
+           (cons dest mime-acting-situation-example-list)))))
 
 
 ;;; @ content decoder
 ;;;
 
+;;;###autoload
 (defun mime-preview-play-current-entity (&optional ignore-examples mode)
   "Play current entity.
 It decodes current entity to call internal or external method.  The
@@ -124,8 +156,20 @@ If MODE is specified, play as it.  Default MODE is \"play\"."
   (interactive "P")
   (let ((entity (get-text-property (point) 'mime-view-entity)))
     (if entity
-       (mime-play-entity entity nil (or mode "play") ignore-examples)
-      )))
+       (let ((situation
+              (get-text-property (point) 'mime-view-situation)))
+         (or mode
+             (setq mode "play"))
+         (setq situation 
+               (if (assq 'mode situation)
+                   (put-alist 'mode mode (copy-alist situation))
+                 (cons (cons 'mode mode)
+                       situation)))
+         (if ignore-examples
+             (setq situation
+                   (cons (cons 'ignore-examples ignore-examples)
+                         situation)))
+         (mime-play-entity entity situation)))))
 
 (defun mime-sort-situation (situation)
   (sort situation
@@ -137,30 +181,23 @@ If MODE is specified, play as it.  Default MODE is \"play\"."
                           (mode . 3)
                           (method . 4)
                           (major-mode . 5)
-                          (disposition-type . 6)
-                          ))
+                          (disposition-type . 6)))
                  a-order b-order)
              (if (symbolp a-t)
                  (let ((ret (assq a-t order)))
                    (if ret
                        (setq a-order (cdr ret))
-                     (setq a-order 7)
-                     ))
-               (setq a-order 8)
-               )
+                     (setq a-order 7)))
+               (setq a-order 8))
              (if (symbolp b-t)
                  (let ((ret (assq b-t order)))
                    (if ret
                        (setq b-order (cdr ret))
-                     (setq b-order 7)
-                     ))
-               (setq b-order 8)
-               )
+                     (setq b-order 7)))
+               (setq b-order 8))
              (if (= a-order b-order)
                  (string< (format "%s" a-t)(format "%s" b-t))
-               (< a-order b-order))
-             )))
-  )
+               (< a-order b-order))))))
 
 (defsubst mime-delq-null-situation (situations field
                                               &optional ignored-value)
@@ -170,8 +207,7 @@ If MODE is specified, play as it.  Default MODE is \"play\"."
             (cell (assq field situation)))
        (if cell
            (or (eq (cdr cell) ignored-value)
-               (setq dest (cons situation dest))
-               )))
+               (setq dest (cons situation dest)))))
       (setq situations (cdr situations)))
     dest))
 
@@ -185,37 +221,25 @@ If MODE is specified, play as it.  Default MODE is \"play\"."
        (when ecell
          (if (equal cell ecell)
              (setq match (1+ match))
-           (setq example (delq ecell example))
-           ))
-       )
-      (setq situation (cdr situation))
-      )
-    (cons match example)
-    ))
-
-(defun mime-play-entity (entity &optional situation mode
-                               ignore-examples ignored-method)
+           (setq example (delq ecell example)))))
+      (setq situation (cdr situation)))
+    (cons match example)))
+
+;;;###autoload
+(defun mime-play-entity (entity &optional situation ignored-method)
   "Play entity specified by ENTITY.
 It decodes the entity to call internal or external method.  The method
 is selected from variable `mime-acting-condition'.  If MODE is
 specified, play as it.  Default MODE is \"play\"."
   (let (method ret)
-    (or situation
-       (setq situation (mime-entity-situation entity)))
-    (if mode
-       (setq situation (cons (cons 'mode mode) situation))
-      )
-    (if ignore-examples
-       (or (assq 'ignore-examples situation)
-           (setq situation
-                 (cons (cons 'ignore-examples ignore-examples) situation)))
-      )
+    (in-calist-package 'mime-view)
     (setq ret
          (mime-delq-null-situation
-          (ctree-find-calist mime-acting-condition situation
+          (ctree-find-calist mime-acting-condition
+                             (mime-entity-situation entity situation)
                              mime-view-find-every-acting-situation)
           'method ignored-method))
-    (or ignore-examples
+    (or (assq 'ignore-examples situation)
        (if (cdr ret)
            (let ((rest ret)
                  (max-score 0)
@@ -234,21 +258,18 @@ specified, play as it.  Default MODE is \"play\"."
                             (setq max-score ret-score
                                   max-escore (cdar examples)
                                   max-examples (list (cdr ret))
-                                  max-situations (list situation))
-                            )
+                                  max-situations (list situation)))
                            ((= ret-score max-score)
                             (cond ((> (cdar examples) max-escore)
                                    (setq max-escore (cdar examples)
                                          max-examples (list (cdr ret))
-                                         max-situations (list situation))
-                                   )
+                                         max-situations (list situation)))
                                   ((= (cdar examples) max-escore)
                                    (setq max-examples
                                          (cons (cdr ret) max-examples))
                                    (or (member situation max-situations)
                                        (setq max-situations
-                                             (cons situation max-situations)))
-                                   )))))
+                                             (cons situation max-situations))))))))
                    (setq examples (cdr examples))))
                (setq rest (cdr rest)))
              (when max-situations
@@ -261,10 +282,8 @@ specified, play as it.  Default MODE is \"play\"."
                        (setcdr cell (1+ (cdr cell)))
                      (setq mime-acting-situation-example-list
                            (cons (cons example 0)
-                                 mime-acting-situation-example-list))
-                     ))
-                 (setq max-examples (cdr max-examples))
-                 )))))
+                                 mime-acting-situation-example-list))))
+                 (setq max-examples (cdr max-examples)))))))
     (cond ((cdr ret)
           (setq ret (select-menu-alist
                      "Methods"
@@ -276,27 +295,25 @@ specified, play as it.  Default MODE is \"play\"."
                                  situation)))
                              ret)))
           (setq ret (mime-sort-situation ret))
-          (add-to-list 'mime-acting-situation-example-list (cons ret 0))
-          )
+          (add-to-list 'mime-acting-situation-example-list (cons ret 0)))
          (t
-          (setq ret (car ret))
-          ))
+          (setq ret (car ret))))
     (setq method (cdr (assq 'method ret)))
     (cond ((and (symbolp method)
                (fboundp method))
-          (funcall method entity ret)
-          )
+          (funcall method entity ret))
          ((stringp method)
-          (mime-activate-mailcap-method entity ret)
-          )
+          (mime-activate-mailcap-method entity ret))
           ;; ((and (listp method)(stringp (car method)))
           ;;  (mime-activate-external-method entity ret)
           ;;  )
          (t
           (mime-show-echo-buffer "No method are specified for %s\n"
-                                 (mime-entity-type/subtype entity))
-          ))
-    ))
+                                 (mime-type/subtype-string
+                                  (cdr (assq 'type situation))
+                                  (cdr (assq 'subtype situation))))
+          (if (y-or-n-p "Do you want to save current entity to disk?")
+              (mime-save-content entity situation))))))
 
 
 ;;; @ external decoder
@@ -311,8 +328,7 @@ specified, play as it.  Default MODE is \"play\"."
          (if (and name (not (string= name "")))
              (expand-file-name name temporary-file-directory)
            (make-temp-name
-            (expand-file-name "EMI" temporary-file-directory))
-           ))
+            (expand-file-name "EMI" temporary-file-directory))))
     (mime-write-entity-content entity name)
     (message "External method is starting...")
     (let ((process
@@ -321,18 +337,14 @@ specified, play as it.  Default MODE is \"play\"."
                   method
                   (cons (cons 'filename name) situation))))
             (start-process command mime-echo-buffer-name
-                           shell-file-name shell-command-switch command)
-            )))
+                           shell-file-name shell-command-switch command))))
       (set-alist 'mime-mailcap-method-filename-alist process name)
-      (set-process-sentinel process 'mime-mailcap-method-sentinel)
-      )
-    ))
+      (set-process-sentinel process 'mime-mailcap-method-sentinel))))
 
 (defun mime-mailcap-method-sentinel (process event)
   (let ((file (cdr (assq process mime-mailcap-method-filename-alist))))
     (if (file-exists-p file)
-       (delete-file file)
-      ))
+       (delete-file file)))
   (remove-alist 'mime-mailcap-method-filename-alist process)
   (message (format "%s %s" process event)))
 
@@ -343,8 +355,7 @@ specified, play as it.  Default MODE is \"play\"."
 (defvar mime-echo-window-height
   (function
    (lambda ()
-     (/ (window-height) 5)
-     ))
+     (/ (window-height) 5)))
   "*Size of mime-echo window.
 It allows function or integer.  If it is function,
 `mime-show-echo-buffer' calls it to get height of mime-echo window.
@@ -367,18 +378,14 @@ window.")
                   (- (window-height)
                      (if (functionp mime-echo-window-height)
                          (funcall mime-echo-window-height)
-                       mime-echo-window-height)
-                     )))
-       )
-      (set-window-buffer win mime-echo-buffer-name)
-      )
+                       mime-echo-window-height)))))
+      (set-window-buffer win mime-echo-buffer-name))
     (select-window win)
     (goto-char (point-max))
     (if forms
-       (insert (apply (function format) forms))
-      )
-    (select-window the-win)
-    ))
+       (let ((buffer-read-only nil))
+         (insert (apply (function format) forms))))
+    (select-window the-win)))
 
 
 ;;; @ file name
@@ -398,44 +405,62 @@ window.")
   (let ((filename
         (or (mime-entity-filename entity)
             (let ((subj
-                   (or (mime-read-field 'Content-Description entity)
-                       (mime-read-field 'Subject entity))))
+                   (or (mime-entity-read-field entity 'Content-Description)
+                       (mime-entity-read-field entity 'Subject))))
               (if (and subj
                        (or (string-match mime-view-file-name-regexp-1 subj)
                            (string-match mime-view-file-name-regexp-2 subj)))
-                  (substring subj (match-beginning 0)(match-end 0))
-                )))))
+                  (substring subj (match-beginning 0)(match-end 0)))))))
     (if filename
-       (replace-as-filename filename)
-      )))
+       (replace-as-filename filename))))
 
 
 ;;; @ file extraction
 ;;;
 
 (defun mime-save-content (entity situation)
-  (let* ((name (mime-entity-safe-filename entity))
-        (filename (if (and name (not (string-equal name "")))
-                      (expand-file-name name
-                                        (save-window-excursion
-                                          (call-interactively
-                                           (function
-                                            (lambda (dir)
-                                              (interactive "DDirectory: ")
-                                              dir)))))
-                    (save-window-excursion
-                      (call-interactively
-                       (function
-                        (lambda (file)
-                          (interactive "FFilename: ")
-                          (expand-file-name file)))))))
-        )
+  (let ((name (or (mime-entity-safe-filename entity)
+                 (format "%s" (mime-entity-media-type entity))))
+       (dir (if (eq t mime-save-directory)
+                default-directory
+              mime-save-directory))
+       filename)
+    (setq filename (read-file-name
+                   (concat "File name: (default "
+                           (file-name-nondirectory name) ") ")
+                   dir
+                   (concat (file-name-as-directory dir)
+                           (file-name-nondirectory name))))
+    (if (file-directory-p filename)
+       (setq filename (concat (file-name-as-directory filename)
+                              (file-name-nondirectory name))))
     (if (file-exists-p filename)
        (or (yes-or-no-p (format "File %s exists. Save anyway? " filename))
            (error "")))
-    (mime-write-entity-content entity filename)
-    ))
-
+    (mime-write-entity-content entity (expand-file-name filename))))
+
+(defun mime-save-content-for-broken-message (entity situation)
+  (let ((name (or (and (mime-entity-filename entity)
+                      (eword-decode-string
+                       (mime-entity-filename entity)))
+                 (format "%s" (mime-entity-media-type entity))))
+       (dir (if (eq t mime-save-directory)
+                default-directory
+              mime-save-directory))
+       filename)
+    (setq filename (read-file-name
+                   (concat "File name: (default "
+                           (file-name-nondirectory name) ") ")
+                   dir
+                   (concat (file-name-as-directory dir)
+                           (file-name-nondirectory name))))
+    (if (file-directory-p filename)
+       (setq filename (concat (file-name-as-directory filename)
+                              (file-name-nondirectory name))))
+    (if (file-exists-p filename)
+       (or (yes-or-no-p (format "File %s exists. Save anyway? " filename))
+           (error "")))
+    (mime-write-entity-content entity (expand-file-name filename))))
 
 ;;; @ file detection
 ;;;
@@ -447,8 +472,7 @@ window.")
     ("^II\\*\000"                      image tiff)
     ("^MM\000\\*"                      image tiff)
     ("^MThd"                           audio midi)
-    ("^\000\000\001\263"               video mpeg)
-    )
+    ("^\000\000\001\263"               video mpeg))
   "*Alist of regexp about magic-number vs. corresponding media-types.
 Each element looks like (REGEXP TYPE SUBTYPE).
 REGEXP is a regular expression to match against the beginning of the
@@ -464,22 +488,17 @@ SUBTYPE is symbol to indicate subtype of media-type.")
                    (if cell
                        (if (string-match (car cell) mdata)
                            (setq type (nth 1 cell)
-                                 subtype (nth 2 cell))
-                         )
+                                 subtype (nth 2 cell)))
                      t)))
        (setq rest (cdr rest))))
-    (if type
-       (mime-play-entity
-        entity
-        (put-alist 'type type
-                   (put-alist 'subtype subtype
-                              (del-alist 'method
-                                         (copy-alist situation))))
-        nil
-        (cdr (assq 'ignore-examples situation))
-        'mime-detect-content)
-      ))
-  )
+    (setq situation (del-alist 'method (copy-alist situation)))
+    (mime-play-entity entity
+                     (if type
+                         (put-alist 'type type
+                                    (put-alist 'subtype subtype
+                                               situation))
+                       situation)
+                     'mime-detect-content)))
 
 
 ;;; @ mail/news message
@@ -489,36 +508,35 @@ SUBTYPE is symbol to indicate subtype of media-type.")
   "Quitting method for mime-view.
 It is registered to variable `mime-preview-quitting-method-alist'."
   (let ((mother mime-mother-buffer)
-       (win-conf mime-preview-original-window-configuration)
-       )
-    (kill-buffer mime-raw-buffer)
+       (win-conf mime-preview-original-window-configuration))
+    (if (and (boundp 'mime-view-temp-message-buffer)
+            (buffer-live-p mime-view-temp-message-buffer))
+       (kill-buffer mime-view-temp-message-buffer))
     (mime-preview-kill-buffer)
     (set-window-configuration win-conf)
-    (pop-to-buffer mother)
-    ))
+    (pop-to-buffer mother)))
 
 (defun mime-view-message/rfc822 (entity situation)
   (let* ((new-name
          (format "%s-%s" (buffer-name) (mime-entity-number entity)))
-        (mother mime-preview-buffer)
-        (children (car (mime-entity-children entity))))
-    (set-buffer (get-buffer-create new-name))
-    (erase-buffer)
-    (insert-buffer-substring (mime-entity-buffer children)
-                            (mime-entity-point-min children)
-                            (mime-entity-point-max children))
-    (setq mime-message-structure children)
-    (setq major-mode 'mime-show-message-mode)
-    (mime-view-buffer (current-buffer) nil mother
-                     nil (if (mime-entity-cooked-p entity) 'cooked))
-    ))
+        (mother (current-buffer))
+        (children (car (mime-entity-children entity)))
+        (preview-buffer
+         (mime-display-message
+          children new-name mother nil
+          (cdr (assq 'major-mode
+                     (get-text-property (point) 'mime-view-situation))))))
+    (or (get-buffer-window preview-buffer)
+       (let ((m-win (get-buffer-window mother)))
+         (if m-win
+             (set-window-buffer m-win preview-buffer)
+           (switch-to-buffer preview-buffer))))))
 
 
 ;;; @ message/partial
 ;;;
 
 (defun mime-store-message/partial-piece (entity cal)
-  (goto-char (mime-entity-point-min entity))
   (let* ((root-dir
          (expand-file-name
           (concat "m-prts-" (user-login-name)) temporary-file-directory))
@@ -526,35 +544,30 @@ It is registered to variable `mime-preview-quitting-method-alist'."
         (number (cdr (assoc "number" cal)))
         (total (cdr (assoc "total" cal)))
         file
-        (mother mime-preview-buffer)
-        )
+        (mother (current-buffer)))
     (or (file-exists-p root-dir)
-       (make-directory root-dir)
-       )
+       (make-directory root-dir))
     (setq id (replace-as-filename id))
     (setq root-dir (concat root-dir "/" id))
     (or (file-exists-p root-dir)
-       (make-directory root-dir)
-       )
+       (make-directory root-dir))
     (setq file (concat root-dir "/FULL"))
     (if (file-exists-p file)
        (let ((full-buf (get-buffer-create "FULL"))
              (pwin (or (get-buffer-window mother)
                        (get-largest-window)))
-             )
+             pbuf)
          (save-window-excursion
            (set-buffer full-buf)
            (erase-buffer)
-           (as-binary-input-file (insert-file-contents file))
+           (insert-file-contents-as-binary file)
            (setq major-mode 'mime-show-message-mode)
            (mime-view-buffer (current-buffer) nil mother)
-           )
-         (set-window-buffer pwin
-                            (save-excursion
-                              (set-buffer full-buf)
-                              mime-preview-buffer))
-         (select-window pwin)
-         )
+           (setq pbuf (current-buffer))
+           (make-local-variable 'mime-view-temp-message-buffer)
+           (setq mime-view-temp-message-buffer full-buf))
+         (set-window-buffer pwin pbuf)
+         (select-window pwin))
       (setq file (concat root-dir "/" number))
       (mime-write-entity-body entity file)
       (let ((total-file (concat root-dir "/CT")))
@@ -568,10 +581,8 @@ It is registered to variable `mime-preview-quitting-method-alist'."
                          (erase-buffer)
                          (insert total)
                          (write-region (point-min)(point-max) total-file)
-                         (kill-buffer (current-buffer))
-                         ))
-                   (string-to-number total)
-                   )
+                         (kill-buffer (current-buffer))))
+                   (string-to-number total))
                (and (file-exists-p total-file)
                     (save-excursion
                       (set-buffer (find-file-noselect total-file))
@@ -579,12 +590,11 @@ It is registered to variable `mime-preview-quitting-method-alist'."
                           (and (re-search-forward "[0-9]+" nil t)
                                (string-to-number
                                 (buffer-substring (match-beginning 0)
-                                                  (match-end 0)))
-                               )
-                        (kill-buffer (current-buffer))
-                        )))
-               )))
-      (if (and total (> total 0))
+                                                  (match-end 0))))
+                        (kill-buffer (current-buffer))))))))
+      (if (and total (> total 0)
+              (>= (length (directory-files root-dir nil "^[0-9]+$" t))
+                  total))
          (catch 'tag
            (save-excursion
              (set-buffer (get-buffer-create mime-temp-buffer-name))
@@ -594,40 +604,32 @@ It is registered to variable `mime-preview-quitting-method-alist'."
                  (while (<= i total)
                    (setq file (concat root-dir "/" (int-to-string i)))
                    (or (file-exists-p file)
-                       (throw 'tag nil)
-                       )
+                       (throw 'tag nil))
                    (as-binary-input-file (insert-file-contents file))
                    (goto-char (point-max))
-                   (setq i (1+ i))
-                   ))
-               (as-binary-output-file
-                (write-region (point-min)(point-max)
-                              (expand-file-name "FULL" root-dir)))
+                   (setq i (1+ i))))
+               (write-region-as-binary (point-min)(point-max)
+                                       (expand-file-name "FULL" root-dir))
                (let ((i 1))
                  (while (<= i total)
                    (let ((file (format "%s/%d" root-dir i)))
                      (and (file-exists-p file)
-                          (delete-file file)
-                          ))
-                   (setq i (1+ i))
-                   ))
+                          (delete-file file)))
+                   (setq i (1+ i))))
                (let ((file (expand-file-name "CT" root-dir)))
                  (and (file-exists-p file)
-                      (delete-file file)
-                      ))
-               (save-window-excursion
-                 (setq major-mode 'mime-show-message-mode)
-                 (mime-view-buffer (current-buffer) nil mother)
-                 )
-               (let ((pwin (or (get-buffer-window mother)
+                      (delete-file file)))
+               (let ((buf (current-buffer))
+                     (pwin (or (get-buffer-window mother)
                                (get-largest-window)))
-                     (pbuf (save-excursion
-                             (set-buffer full-buf)
-                             mime-preview-buffer)))
+                     (pbuf (mime-display-message
+                            (mime-open-entity 'buffer (current-buffer))
+                            nil mother nil 'mime-show-message-mode)))
+                 (with-current-buffer pbuf
+                   (make-local-variable 'mime-view-temp-message-buffer)
+                   (setq mime-view-temp-message-buffer buf))
                  (set-window-buffer pwin pbuf)
-                 (select-window pwin)
-                 )))))
-      )))
+                 (select-window pwin)))))))))
 
 
 ;;; @ message/external-body
@@ -636,32 +638,29 @@ It is registered to variable `mime-preview-quitting-method-alist'."
 (defvar mime-raw-dired-function
   (if (and (>= emacs-major-version 19) window-system)
       (function dired-other-frame)
-    (function mime-raw-dired-function-for-one-frame)
-    ))
+    (function mime-raw-dired-function-for-one-frame)))
 
 (defun mime-raw-dired-function-for-one-frame (dir)
   (let ((win (or (get-buffer-window mime-preview-buffer)
                 (get-largest-window))))
     (select-window win)
-    (dired dir)
-    ))
+    (dired dir)))
 
 (defun mime-view-message/external-anon-ftp (entity cal)
   (let* ((site (cdr (assoc "site" cal)))
         (directory (cdr (assoc "directory" cal)))
         (name (cdr (assoc "name" cal)))
         (pathname (concat "/anonymous@" site ":" directory)))
-    (message (concat "Accessing " (expand-file-name name pathname) " ..."))
+    (message (concat "Accessing " (expand-file-name name pathname) "..."))
     (funcall mime-raw-dired-function pathname)
     (goto-char (point-min))
-    (search-forward name)
-    ))
+    (search-forward name)))
 
 (defvar mime-raw-browse-url-function mime-browse-url-function)
 
 (defun mime-view-message/external-url (entity cal)
   (let ((url (cdr (assoc "url" cal))))
-    (message (concat "Accessing " url " ..."))
+    (message (concat "Accessing " url "..."))
     (funcall mime-raw-browse-url-function url)))
 
 
@@ -670,24 +669,19 @@ It is registered to variable `mime-preview-quitting-method-alist'."
 
 (defun mime-view-caesar (entity situation)
   "Internal method for mime-view to display ROT13-47-48 message."
-  (let* ((new-name (format "%s-%s" (buffer-name)
-                          (mime-entity-number entity)))
-        (mother mime-preview-buffer))
-    (let ((pwin (or (get-buffer-window mother)
-                   (get-largest-window)))
-         (buf (get-buffer-create new-name)))
-      (set-window-buffer pwin buf)
-      (set-buffer buf)
-      (select-window pwin)
-      )
-    (setq buffer-read-only nil)
-    (erase-buffer)
-    (mime-insert-text-content entity)
-    (mule-caesar-region (point-min) (point-max))
-    (set-buffer-modified-p nil)
-    (set-buffer mother)
-    (view-buffer new-name)
-    ))
+  (let ((buf (get-buffer-create
+             (format "%s-%s" (buffer-name) (mime-entity-number entity)))))
+    (with-current-buffer buf
+      (setq buffer-read-only nil)
+      (erase-buffer)
+      (mime-insert-text-content entity)
+      (mule-caesar-region (point-min) (point-max))
+      (set-buffer-modified-p nil))
+    (let ((win (get-buffer-window (current-buffer))))
+      (or (eq (selected-window) win)
+         (select-window (or win (get-largest-window)))))
+    (view-buffer buf)
+    (goto-char (point-min))))
 
 
 ;;; @ end
@@ -711,10 +705,8 @@ It is registered to variable `mime-preview-quitting-method-alist'."
                                 mime-acting-situation-example-list-max-size)
                              (< i 16))
                    (mime-reduce-acting-situation-examples)
-                   (setq i (1+ i))
-                   ))
-             (error (setq mime-acting-situation-example-list nil)))
-           )
+                   (setq i (1+ i))))
+             (error (setq mime-acting-situation-example-list nil))))
        (kill-buffer buffer))))
 
 ;;; mime-play.el ends here