[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: mailcap viewers in dired; gnus-dired.el, mailcap.el

From: Reiner Steib
Subject: Re: mailcap viewers in dired; gnus-dired.el, mailcap.el
Date: Wed, 10 Oct 2007 23:20:44 +0200
User-agent: Gnus/5.110007 (No Gnus v0.7) Emacs/22.1.50 (gnu/linux)

On Wed, Oct 10 2007, Juri Linkov wrote:

>>> There is already a file lisp/gnus/gnus-dired.el that binds `C-c C-m C-l'
>>> in Dired to the command that runs the program found in the mailcap file.

[ FWIW: It only binds the key if the users calls
  `gnus-dired-minor-mode' or `turn-on-gnus-dired-mode'. ]

>> The current versions of `mailcap.el' and `gnus-dired.el' have some
>> dependencies on Gnus.  I'm working on reducing these dependencies so
>> that it should possible to use them in other parts of Emacs without
>> loading significant parts of Gnus

In Emacs 22 (branch), ...
emacs22 -Q -l mailcap -l gnus-dired -f dired -f turn-on-gnus-dired-mode
... loads more than 50 gnusy packages...

ELISP> (length '(gnus-dired gnus-msg gnus-art mm-uu mml2015 pgg
  pgg-parse pgg-def mm-view gnus-sum nnoo gnus-group gnus-undo nnmail
  mail-source format-spec gnus-start gnus-spec gnus-int gnus-range
  gnus-win message rfc822 mml mml-sec mml-smime smime dig mm-decode
  mm-bodies mm-encode mailabbrev gmm-utils mailheader canlock sha1
  hex-util gnus nnheader gnus-util netrc mail-utils gnus-ems dired
  regexp-opt mailcap mail-parse rfc2231 rfc2047 rfc2045 qp ietf-drums
  mm-util mule-util time-date mail-prsvr))
==> 56

With these changes, only mailcap and gnus-dired are loaded.

> Thanks.  Do you see any problems with this?

I did only very limited testing.  I tested that
`gnus-dired-find-file-mailcap' still works without loading unnecessary
gnusy packages.  See the preliminary patches (against Gnus trunk)

Not a problem, but a TODO: `mailcap-mime-data' should be splitted.
IMHO, it should be composed of...

(a) entries from a customizable variable

(b) the data from MAILCAPS (`mailcap-parse-mailcaps')

(c) Emacs-wide fallback entries for external viewers (e.g. for
    Windows), cf. `mailcap-poor-system-types'.

Of course, mailcap.el should prefer (a) over (b), and (b) over (c).

>> (probably `gnus-dired.el' should be renamed, e.g. to `dired-mime.el').
> gnus-dired.el has a function `gnus-dired-attach' that is Gnus-specific.

I think it could work with any message composition package that
supports using MML (Emacs MIME).  I don't know if any other exists
beside (Gnus) Message mode.  But it's MML-specific, yes.

> So I think it would be better to leave gnus-dired.el alone, and implement
> new commands in dired.el or dired-aux.el 

I don't use dired often, so I don't have a strong opinion how to
integrate mailcap functionality there.

I think the other functions `gnus-dired-attach' and `gnus-dired-print'
could be useful as well (cf. (info "(gnus)Other modes")).  But they
surely need to be modified for if no other Gnus features should be

> (and maybe take into account the command guessing behaviour of ! in
> dired-x.el).

`!' (`dired-do-shell-command') is not exactly what
`gnus-dired-find-file-mailcap' does.  In mailcap.el you can also
specify Emacs-internal handling, IIRC.

Bye, Reiner.

--8<---------------cut here---------------start------------->8---
--- mailcap.el  4 Oct 2007 18:51:28 -0000       7.11
+++ mailcap.el  10 Oct 2007 20:59:53 -0000
@@ -33,8 +33,18 @@
 ;;; Code:
 (eval-when-compile (require 'cl))
-(require 'mail-parse)
-(require 'mm-util)
+;; (require 'mail-parse)
+(autoload 'mail-header-parse-content-type "mail-parse")
+;; (require 'mm-util)
+(autoload 'mm-delete-duplicates "mm-util")
+;; `mm-delete-duplicates' is an alias for `delete-dups' in Emacs 22.
+(defalias 'mailcap-delete-duplicates
+  (if (fboundp 'delete-dups)
+      'delete-dups
+    (autoload 'mm-delete-duplicates "mm-util")
+    'mm-delete-duplicates))
 (defgroup mailcap nil
   "Definition of viewers for MIME types."
@@ -722,7 +732,7 @@
      (t nil))))
-(defun mailcap-mime-info (string &optional request)
+(defun mailcap-mime-info (string &optional request no-decode)
   "Get the MIME viewer command for STRING, return nil if none found.
 Expects a complete content-type header line as its argument.
@@ -732,7 +742,9 @@
 corresponding to that string will be returned (print, description,
 whatever).  If a number, then all the information for this specific
 viewer is returned.  If `all', then all possible viewers for
-this type is returned."
+this type is returned.
+If NO-DECODE is non-nil, don't decode STRING."
   (let (
        major                           ; Major encoding (text, etc)
        minor                           ; Minor encoding (html, etc)
@@ -746,7 +758,10 @@
        viewer                          ; The one and only viewer
-      (setq ctl (mail-header-parse-content-type (or string "text/plain")))
+      (setq ctl
+           (if no-decode
+               (list (or string "text/plain"))
+             (mail-header-parse-content-type (or string "text/plain"))))
       (setq major (split-string (car ctl) "/"))
       (setq minor (cadr major)
            major (car major))
@@ -766,7 +781,7 @@
        (setq viewer (car passed)))
        ((and (null viewer) (not (equal major "default")) request)
-       (mailcap-mime-info "default" request))
+       (mailcap-mime-info "default" request no-decode))
        ((or (null request) (equal request ""))
        (mailcap-unescape-mime-test (cdr (assq 'viewer viewer)) info))
        ((stringp request)
@@ -976,7 +991,7 @@
 (defun mailcap-mime-types ()
   "Return a list of MIME media types."
-  (mm-delete-duplicates
+  (mailcap-delete-duplicates
     (mapcar 'cdr mailcap-mime-extensions)
--8<---------------cut here---------------end--------------->8---

--8<---------------cut here---------------start------------->8---
--- gnus-dired.el       4 Oct 2007 18:51:27 -0000       7.8
+++ gnus-dired.el       10 Oct 2007 20:57:48 -0000
@@ -42,25 +42,42 @@
 ;;; Code:
 (require 'dired)
-(require 'gnus-ems)
-(require 'gnus-msg)
-(require 'gnus-util)
-(require 'message)
-(require 'mm-encode)
-(require 'mml)
+;; (require 'mm-encode)
+;; (require 'mml)
+(autoload 'mml-attach-file "mml")
+;; Maybe shift this function to `mailcap.el'?
+(autoload 'mm-default-file-encoding "mm-decode")
+(autoload 'mailcap-extension-to-mime "mailcap")
+(autoload 'mailcap-mime-info "mailcap")
+;; Maybe shift this function to `mailcap.el'?
+(autoload 'mm-mailcap-command "mm-decode")
+(autoload 'ps-print-preprint "ps-print")
+;; Autoloads to avoid byte-compiler warnings.  These are used only if
+;; the user customizes `gnus-dired-mail-mode' to use Message and/or
+;; Gnus.
+(autoload 'message-buffers "message")
+(autoload 'gnus-setup-message "gnus-msg")
+(autoload 'gnus-print-buffer "gnus-sum")
+(defvar gnus-dired-mail-mode 'message) ;; 'gnus 'mail
+;; FIXME: Make it customizable, change the default to `mail' when this
+;; file if renamed to `dired-mime.el'.
 (defvar gnus-dired-mode nil
-  "Minor mode for intersections of gnus and dired.")
+  "Minor mode for intersections of MIME mail composition and dired.")
 (defvar gnus-dired-mode-map nil)
 (unless gnus-dired-mode-map
   (setq gnus-dired-mode-map (make-sparse-keymap))
-  (gnus-define-keys gnus-dired-mode-map
-    "\C-c\C-m\C-a" gnus-dired-attach
-    "\C-c\C-m\C-l" gnus-dired-find-file-mailcap
-    "\C-c\C-m\C-p" gnus-dired-print))
+  (define-key gnus-dired-mode-map "\C-c\C-m\C-a" 'gnus-dired-attach)
+  (define-key gnus-dired-mode-map "\C-c\C-m\C-l" 'gnus-dired-find-file-mailcap)
+  (define-key gnus-dired-mode-map "\C-c\C-m\C-p" 'gnus-dired-print))
 (defun gnus-dired-mode (&optional arg)
   "Minor mode for intersections of gnus and dired.
@@ -73,14 +90,31 @@
           (> (prefix-numeric-value arg) 0)))
     (when gnus-dired-mode
       (add-minor-mode 'gnus-dired-mode "" gnus-dired-mode-map)
-      (gnus-run-hooks 'gnus-dired-mode-hook))))
+      (save-current-buffer
+       (run-hooks 'gnus-dired-mode-hook)))))
 (defun turn-on-gnus-dired-mode ()
   "Convenience method to turn on gnus-dired-mode."
+  (interactive)
   (gnus-dired-mode 1))
-;; Method to attach files to a gnus composition.
+(defun gnus-dired-mail-buffers ()
+  "Return a list of active mail composition buffers."
+  (if (and (memq gnus-dired-mail-mode '(message gnus))
+          (require 'message)
+          (fboundp 'message-buffers))
+      (message-buffers)
+    ;; Cf. `message-buffers' in `message.el':
+    (let (buffers)
+      (save-excursion
+       (dolist (buffer (buffer-list t))
+         (set-buffer buffer)
+         (when (eq major-mode 'mail-mode)
+           (push (buffer-name buffer) buffers))))
+      (nreverse buffers))))
+;; Method to attach files to a mail composition.
 (defun gnus-dired-attach (files-to-attach)
   "Attach dired's marked files to a gnus message composition.
 If called non-interactively, FILES-TO-ATTACH should be a list of
@@ -102,22 +136,25 @@
             (lambda (f) (file-name-nondirectory f))
             files-to-attach ", "))
-      (setq bufs (message-buffers))
+      (setq bufs (gnus-dired-mail-buffers))
-      ;; set up destination message buffer
+      ;; set up destination mail composition buffer
       (if (and bufs
-              (y-or-n-p "Attach files to existing message buffer? "))
+              (y-or-n-p "Attach files to existing mail composition buffer? "))
          (setq destination
                (if (= (length bufs) 1)
                    (get-buffer (car bufs))
-                 (completing-read "Attach to which message buffer: "
+                 (completing-read "Attach to which mail composition buffer: "
                                    (lambda (b)
                                      (cons b (get-buffer b)))
                                   nil t)))
-       ;; setup a new gnus message buffer
-       (gnus-setup-message 'message (message-mail))
+       ;; setup a new mail composition buffer
+       (if (eq gnus-dired-mail-mode 'gnus)
+           (gnus-setup-message 'message (message-mail))
+         ;; FIXME: Is this the right thing?
+         (compose-mail))
        (setq destination (current-buffer)))
       ;; set buffer to destination buffer, and attach files
@@ -151,7 +188,8 @@
                  (setq method
                        (cdr (assoc 'viewer
                                    (car (mailcap-mime-info mime-type
-                                                           'all)))))))
+                                                           'all 
+                                                           'no-decode)))))))
            (let ((view-command (mm-mailcap-command method file-name nil)))
              (message "viewing via %s" view-command)
              (start-process "*display*"
@@ -186,7 +224,8 @@
                      (match-string 0 file-name)))
-               (setq method (mailcap-mime-info mime-type "print"))))
+               (setq method (mailcap-mime-info mime-type "print"
+                                               'no-decode))))
          (call-process shell-file-name nil
                        (generate-new-buffer " *mm*")
@@ -194,7 +233,10 @@
                        (mm-mailcap-command method file-name mime-type))
          (insert-file-contents file-name)
-         (gnus-print-buffer))
+         (if (eq gnus-dired-mail-mode 'gnus)
+             (gnus-print-buffer)
+           ;; FIXME:
+           (error "MIME print only implemeted via Gnus")))
        (ps-despool print-to))))
    ((file-symlink-p file-name)
      (error "File is a symlink to a nonexistent target"))
--8<---------------cut here---------------end--------------->8---
      (o o)
---ooO-(_)-Ooo---  |  PGP key available  |  http://rsteib.home.pages.de/

reply via email to

[Prev in Thread] Current Thread [Next in Thread]