aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTassilo Horn2016-04-10 09:39:51 +0200
committerTassilo Horn2016-04-10 18:15:45 +0200
commitb4b83fa2ba52cd5398e3b9d085b4afea679d1515 (patch)
treeab4cf32e906b9924792461331a4f35b5b896416c
parent7172ba7f7f5b1a91357ea727ab188db3ccc99a77 (diff)
downloademacs-b4b83fa2ba52cd5398e3b9d085b4afea679d1515.tar.gz
emacs-b4b83fa2ba52cd5398e3b9d085b4afea679d1515.zip
New custom option for overriding mailcap choices
* lisp/net/mailcap.el (mailcap--get-user-mime-data): New function. (mailcap--set-user-mime-data): New function. (mailcap-user-mime-data): New customization option. (mailcap-select-preferred-viewer): New function. (mailcap-mime-info): Use it. * doc/misc/emacs-mime.texi (mailcap): Document `mailcap-user-mime-data'.
-rw-r--r--doc/misc/emacs-mime.texi5
-rw-r--r--lisp/net/mailcap.el131
2 files changed, 107 insertions, 29 deletions
diff --git a/doc/misc/emacs-mime.texi b/doc/misc/emacs-mime.texi
index c9c4b7c2a2f..2b3bba39ad9 100644
--- a/doc/misc/emacs-mime.texi
+++ b/doc/misc/emacs-mime.texi
@@ -1826,6 +1826,11 @@ matching types.
1826@vindex mailcap-mime-data 1826@vindex mailcap-mime-data
1827This variable is an alist of alists containing backup viewing rules. 1827This variable is an alist of alists containing backup viewing rules.
1828 1828
1829@item mailcap-user-mime-data
1830@vindex mailcap-user-mime-data
1831A customizable list of viewers that take preference over
1832@code{mailcap-mime-data}.
1833
1829@end table 1834@end table
1830 1835
1831Interface functions: 1836Interface functions:
diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el
index 609a8f4d64b..ae49972f5bf 100644
--- a/lisp/net/mailcap.el
+++ b/lisp/net/mailcap.el
@@ -58,6 +58,59 @@
58 " ") 58 " ")
59 "Shell command (including switches) used to print PostScript files.") 59 "Shell command (including switches) used to print PostScript files.")
60 60
61(defun mailcap--get-user-mime-data (sym)
62 (let ((val (default-value sym))
63 res)
64 (dolist (entry val)
65 (setq res (cons (list (cdr (assq 'viewer entry))
66 (cdr (assq 'type entry))
67 (cdr (assq 'test entry)))
68 res)))
69 (nreverse res)))
70
71(defun mailcap--set-user-mime-data (sym val)
72 (let (res)
73 (dolist (entry val)
74 (setq res (cons `((viewer . ,(car entry))
75 (type . ,(cadr entry))
76 ,@(when (caddr entry)
77 `((test . ,(caddr entry)))))
78 res)))
79 (set-default sym (nreverse res))))
80
81(defcustom mailcap-user-mime-data nil
82 "A list of viewers preferred for different MIME types.
83The elements of the list are alists of the following structure
84
85 ((viewer . VIEWER)
86 (type . MIME-TYPE)
87 (test . TEST))
88
89where VIEWER is either a lisp command, e.g., a major-mode, or a
90string containing a shell command for viewing files of the
91defined MIME-TYPE. In case of a shell command, %s will be
92replaced with the file.
93
94MIME-TYPE is a regular expression being matched against the
95actual MIME type. It is implicitly surrounded with ^ and $.
96
97TEST is an lisp form which is evaluated in order to test if the
98entry should be chosen. The `test' entry is optional.
99
100When selecting a viewer for a given MIME type, the first viewer
101in this list with a matching MIME-TYPE and successful TEST is
102selected. Only if none matches, the standard `mailcap-mime-data'
103is consulted."
104 :type '(repeat
105 (list
106 (choice (function :tag "Function or mode")
107 (string :tag "Shell command"))
108 (regexp :tag "MIME Type")
109 (sexp :tag "Test (optional)")))
110 :get #'mailcap--get-user-mime-data
111 :set #'mailcap--set-user-mime-data
112 :group 'mailcap)
113
61;; Postpone using defcustom for this as it's so big and we essentially 114;; Postpone using defcustom for this as it's so big and we essentially
62;; have to have two copies of the data around then. Perhaps just 115;; have to have two copies of the data around then. Perhaps just
63;; customize the Lisp viewers and rely on the normal configuration 116;; customize the Lisp viewers and rely on the normal configuration
@@ -700,6 +753,20 @@ If TEST is not given, it defaults to t."
700 t) 753 t)
701 (t nil)))) 754 (t nil))))
702 755
756(defun mailcap-select-preferred-viewer (type-info)
757 "Return an applicable viewer entry from `mailcap-user-mime-data'."
758 (let ((info (mapcar (lambda (a) (cons (symbol-name (car a))
759 (cdr a)))
760 (cdr type-info)))
761 viewer)
762 (dolist (entry mailcap-user-mime-data)
763 (when (and (null viewer)
764 (string-match (concat "^" (cdr (assq 'type entry)) "$")
765 (car type-info))
766 (mailcap-viewer-passes-test entry info))
767 (setq viewer entry)))
768 viewer))
769
703(defun mailcap-mime-info (string &optional request no-decode) 770(defun mailcap-mime-info (string &optional request no-decode)
704 "Get the MIME viewer command for STRING, return nil if none found. 771 "Get the MIME viewer command for STRING, return nil if none found.
705Expects a complete content-type header line as its argument. 772Expects a complete content-type header line as its argument.
@@ -732,41 +799,47 @@ If NO-DECODE is non-nil, don't decode STRING."
732 (if no-decode 799 (if no-decode
733 (list (or string "text/plain")) 800 (list (or string "text/plain"))
734 (mail-header-parse-content-type (or string "text/plain")))) 801 (mail-header-parse-content-type (or string "text/plain"))))
735 (setq major (split-string (car ctl) "/")) 802 ;; Check if there's a user-defined viewer from `mailcap-user-mime-data'.
736 (setq minor (cadr major) 803 (setq viewer (mailcap-select-preferred-viewer ctl))
737 major (car major)) 804 (if viewer
738 (when (setq major-info (cdr (assoc major mailcap-mime-data))) 805 (setq passed (list viewer))
739 (when (setq viewers (mailcap-possible-viewers major-info minor)) 806 ;; None found, so heuristically select some applicable viewer
740 (setq info (mapcar (lambda (a) (cons (symbol-name (car a)) 807 ;; from `mailcap-mime-data'.
741 (cdr a))) 808 (setq major (split-string (car ctl) "/"))
742 (cdr ctl))) 809 (setq minor (cadr major)
743 (while viewers 810 major (car major))
744 (if (mailcap-viewer-passes-test (car viewers) info) 811 (when (setq major-info (cdr (assoc major mailcap-mime-data)))
745 (setq passed (cons (car viewers) passed))) 812 (when (setq viewers (mailcap-possible-viewers major-info minor))
746 (setq viewers (cdr viewers))) 813 (setq info (mapcar (lambda (a) (cons (symbol-name (car a))
747 (setq passed (sort passed 'mailcap-viewer-lessp)) 814 (cdr a)))
748 (setq viewer (car passed)))) 815 (cdr ctl)))
749 (when (and (stringp (cdr (assq 'viewer viewer))) 816 (while viewers
750 passed) 817 (if (mailcap-viewer-passes-test (car viewers) info)
751 (setq viewer (car passed))) 818 (setq passed (cons (car viewers) passed)))
819 (setq viewers (cdr viewers)))
820 (setq passed (sort passed 'mailcap-viewer-lessp))
821 (setq viewer (car passed))))
822 (when (and (stringp (cdr (assq 'viewer viewer)))
823 passed)
824 (setq viewer (car passed))))
752 (cond 825 (cond
753 ((and (null viewer) (not (equal major "default")) request) 826 ((and (null viewer) (not (equal major "default")) request)
754 (mailcap-mime-info "default" request no-decode)) 827 (mailcap-mime-info "default" request no-decode))
755 ((or (null request) (equal request "")) 828 ((or (null request) (equal request ""))
756 (mailcap-unescape-mime-test (cdr (assq 'viewer viewer)) info)) 829 (mailcap-unescape-mime-test (cdr (assq 'viewer viewer)) info))
757 ((stringp request) 830 ((stringp request)
758 (mailcap-unescape-mime-test 831 (mailcap-unescape-mime-test
759 (cdr-safe (assoc request viewer)) info)) 832 (cdr-safe (assoc request viewer)) info))
760 ((eq request 'all) 833 ((eq request 'all)
761 passed) 834 passed)
762 (t 835 (t
763 ;; MUST make a copy *sigh*, else we modify mailcap-mime-data 836 ;; MUST make a copy *sigh*, else we modify mailcap-mime-data
764 (setq viewer (copy-sequence viewer)) 837 (setq viewer (copy-sequence viewer))
765 (let ((view (assq 'viewer viewer)) 838 (let ((view (assq 'viewer viewer))
766 (test (assq 'test viewer))) 839 (test (assq 'test viewer)))
767 (if view (setcdr view (mailcap-unescape-mime-test (cdr view) info))) 840 (if view (setcdr view (mailcap-unescape-mime-test (cdr view) info)))
768 (if test (setcdr test (mailcap-unescape-mime-test (cdr test) info)))) 841 (if test (setcdr test (mailcap-unescape-mime-test (cdr test) info))))
769 viewer))))) 842 viewer)))))
770 843
771;;; 844;;;
772;;; Experimental MIME-types parsing 845;;; Experimental MIME-types parsing