Synch with Oort Gnus.
[elisp/gnus.git-] / lisp / mm-decode.el
index 2a02fab..b6fb1c4 100644 (file)
@@ -35,7 +35,8 @@
 (require 'mail-parse)
 (require 'gnus-mailcap)
 (require 'mm-bodies)
-(eval-when-compile (require 'cl))
+(eval-when-compile (require 'cl)
+                   (require 'term))
 
 (eval-and-compile
   (autoload 'mm-inline-partial "mm-partial")
     ("application/pkcs7-signature" ignore identity)
     ("multipart/alternative" ignore identity)
     ("multipart/mixed" ignore identity)
-    ("multipart/related" ignore identity))
+    ("multipart/related" ignore identity)
+    ;; Default to displaying as text
+    (".*" mm-inline-text identity))
   "Alist of media types/tests saying whether types can be displayed inline."
   :type '(repeat (list (string :tag "MIME type")
                       (function :tag "Display function")
     "application/pkcs7-signature")
   "List of media types that are to be displayed inline.
 See also `mm-inline-media-tests', which says how to display a media
-type inline.  If no media test is defined, the default is to treat the
-type as plain text."
+type inline."
   :type '(repeat string)
   :group 'mime-display)
 
@@ -277,6 +279,11 @@ If not set, `default-directory' will be used."
   :type 'directory
   :group 'mime-display)
 
+(defcustom mm-external-terminal-program "xterm"
+  "The program to start an external terminal."
+  :type 'string
+  :group 'mime-display)
+
 ;;; Internal variables.
 
 (defvar mm-dissection-list nil)
@@ -545,7 +552,8 @@ external if displayed external."
        (mm-remove-part handle)
       (let* ((type (mm-handle-media-type handle))
             (method (mailcap-mime-info type)))
-       (if (mm-inlined-p handle)
+       (if (and (mm-inlinable-p handle)
+                (mm-inlined-p handle))
            (progn
              (forward-line 1)
              (mm-display-inline handle)
@@ -615,12 +623,33 @@ external if displayed external."
          (message "Viewing with %s" method)
          (cond (needsterm
                 (unwind-protect
-                    (start-process "*display*" nil
-                                   "xterm"
-                                   "-e" shell-file-name
-                                   shell-command-switch
-                                   (mm-mailcap-command
-                                    method file (mm-handle-type handle)))
+                     (if window-system
+                         (start-process "*display*" nil
+                                        mm-external-terminal-program
+                                        "-e" shell-file-name
+                                        shell-command-switch
+                                        (mm-mailcap-command
+                                         method file (mm-handle-type handle)))
+                       (require 'term)
+                       (require 'gnus-win)
+                       (set-buffer
+                        (setq buffer
+                              (make-term "display"
+                                         shell-file-name
+                                         nil
+                                         shell-command-switch
+                                         (mm-mailcap-command
+                                          method file 
+                                          (mm-handle-type handle)))))
+                       (term-mode)
+                       (term-char-mode)
+                       (set-process-sentinel 
+                        (get-buffer-process buffer)
+                        `(lambda (process state)
+                           (if (eq 'exit (process-status process))
+                               (gnus-configure-windows 
+                                ',gnus-current-window-configuration))))
+                       (gnus-configure-windows 'display-term))
                   (mm-handle-set-external-undisplayer handle (cons file buffer)))
                 (message "Displaying %s..." (format method file))
                 'external)
@@ -739,7 +768,7 @@ external if displayed external."
         ((consp object)
          (ignore-errors (delete-file (car object)))
          (ignore-errors (delete-directory (file-name-directory (car object))))
-         (ignore-errors (kill-buffer (cdr object))))
+         (ignore-errors (and (cdr object) (kill-buffer (cdr object)))))
         ((bufferp object)
          (when (buffer-live-p object)
            (kill-buffer object)))))
@@ -748,7 +777,7 @@ external if displayed external."
 (defun mm-display-inline (handle)
   (let* ((type (mm-handle-media-type handle))
         (function (cadr (mm-assoc-string-match mm-inline-media-tests type))))
-    (funcall (or function #'mm-inline-text) handle)
+    (funcall function handle)
     (goto-char (point-min))))
 
 (defun mm-assoc-string-match (alist type)
@@ -768,8 +797,21 @@ external if displayed external."
              methods nil)))
     result))
 
+(defun mm-inlinable-p (handle)
+  "Say whether HANDLE can be displayed inline."
+  (let ((alist mm-inline-media-tests)
+       (type (mm-handle-media-type handle))
+       test)
+    (while alist
+      (when (string-match (caar alist) type)
+       (setq test (caddar alist)
+             alist nil)
+       (setq test (funcall test handle)))
+      (pop alist))
+    test))
+
 (defun mm-inlined-p (handle)
-  "Say whether the user wants HANDLE to be displayed automatically."
+  "Say whether the user wants HANDLE to be displayed inline."
   (let ((methods mm-inlined-types)
        (type (mm-handle-media-type handle))
        method result)
@@ -787,7 +829,8 @@ external if displayed external."
        ty)
     (catch 'found
       (while (setq ty (pop types))
-       (when (string-match ty type)
+       (when (and (string-match ty type)
+                  (mm-inlinable-p handle))
          (throw 'found t))))))
 
 (defun mm-inline-override-p (handle)