diff options
| author | Lars Ingebrigtsen | 2020-08-02 09:04:31 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2020-08-02 09:04:31 +0200 |
| commit | eab636c7eb25c4e1cbfeb0fc48cc1274e1c55222 (patch) | |
| tree | 3803a79716966e2a1109290bae5069408b1fb5ac | |
| parent | 8f181124dfc84b9a7fcadb895af6ce2978d8a40e (diff) | |
| download | emacs-eab636c7eb25c4e1cbfeb0fc48cc1274e1c55222.tar.gz emacs-eab636c7eb25c4e1cbfeb0fc48cc1274e1c55222.zip | |
Try to fix mailcap parsing again to respect Emacs defaults
* lisp/net/mailcap.el (mailcap--computed-mime-data): New variable.
(mailcap-parse-mailcaps): Don't delete Emacs-distributed fallback
values (bug#40247).
(mailcap-add-mailcap-entry): Extend to allow working on different
variables.
(mailcap-add): Store data in mailcap-user-mime-data, since it
should be heeded first.
| -rw-r--r-- | lisp/net/mailcap.el | 60 |
1 files changed, 39 insertions, 21 deletions
diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el index 5fe5b4d3a54..86f9d2bf07c 100644 --- a/lisp/net/mailcap.el +++ b/lisp/net/mailcap.el | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | 29 | ||
| 30 | ;;; Code: | 30 | ;;; Code: |
| 31 | 31 | ||
| 32 | (require 'cl-lib) | ||
| 32 | (autoload 'mail-header-parse-content-type "mail-parse") | 33 | (autoload 'mail-header-parse-content-type "mail-parse") |
| 33 | 34 | ||
| 34 | (defgroup mailcap nil | 35 | (defgroup mailcap nil |
| @@ -337,6 +338,10 @@ is a string or list of strings, it represents a shell command to run | |||
| 337 | to return a true or false shell value for the validity.") | 338 | to return a true or false shell value for the validity.") |
| 338 | (put 'mailcap-mime-data 'risky-local-variable t) | 339 | (put 'mailcap-mime-data 'risky-local-variable t) |
| 339 | 340 | ||
| 341 | (defvar mailcap--computed-mime-data nil | ||
| 342 | "Computed version of the mailcap data incorporating all sources. | ||
| 343 | Same format as `mailcap-mime-data'.") | ||
| 344 | |||
| 340 | (defcustom mailcap-download-directory nil | 345 | (defcustom mailcap-download-directory nil |
| 341 | "Directory to which `mailcap-save-binary-file' downloads files by default. | 346 | "Directory to which `mailcap-save-binary-file' downloads files by default. |
| 342 | nil means your home directory." | 347 | nil means your home directory." |
| @@ -422,7 +427,13 @@ MAILCAPS if set; otherwise (on Unix) use the path from RFC 1524, plus | |||
| 422 | (when (or (not mailcap-parsed-p) | 427 | (when (or (not mailcap-parsed-p) |
| 423 | force) | 428 | force) |
| 424 | ;; Clear out all old data. | 429 | ;; Clear out all old data. |
| 425 | (setq mailcap-mime-data nil) | 430 | (setq mailcap--computed-mime-data nil) |
| 431 | ;; Add the Emacs-distributed defaults (which will be used as | ||
| 432 | ;; fallbacks). Do it this way instead of just copying the list, | ||
| 433 | ;; since entries are destructively modified. | ||
| 434 | (cl-loop for (major . minors) in mailcap-mime-data | ||
| 435 | do (cl-loop for (minor . entry) in minors | ||
| 436 | do (mailcap-add-mailcap-entry major minor entry))) | ||
| 426 | (cond | 437 | (cond |
| 427 | (path nil) | 438 | (path nil) |
| 428 | ((getenv "MAILCAPS") | 439 | ((getenv "MAILCAPS") |
| @@ -709,10 +720,13 @@ to supply to the test." | |||
| 709 | (push (list otest result) mailcap-viewer-test-cache) | 720 | (push (list otest result) mailcap-viewer-test-cache) |
| 710 | result)))) | 721 | result)))) |
| 711 | 722 | ||
| 712 | (defun mailcap-add-mailcap-entry (major minor info) | 723 | (defun mailcap-add-mailcap-entry (major minor info &optional storage) |
| 713 | (let ((old-major (assoc major mailcap-mime-data))) | 724 | (let* ((storage (or storage 'mailcap--computed-mime-data)) |
| 725 | (old-major (assoc major (symbol-value storage)))) | ||
| 714 | (if (null old-major) ; New major area | 726 | (if (null old-major) ; New major area |
| 715 | (push (cons major (list (cons minor info))) mailcap-mime-data) | 727 | (set storage |
| 728 | (cons (cons major (list (cons minor info))) | ||
| 729 | (symbol-value storage))) | ||
| 716 | (let ((cur-minor (assoc minor old-major))) | 730 | (let ((cur-minor (assoc minor old-major))) |
| 717 | (cond | 731 | (cond |
| 718 | ((or (null cur-minor) ; New minor area, or | 732 | ((or (null cur-minor) ; New minor area, or |
| @@ -736,11 +750,15 @@ If TEST is not given, it defaults to t." | |||
| 736 | (when (or (not (car tl)) | 750 | (when (or (not (car tl)) |
| 737 | (not (cadr tl))) | 751 | (not (cadr tl))) |
| 738 | (error "%s is not a valid MIME type" type)) | 752 | (error "%s is not a valid MIME type" type)) |
| 739 | (mailcap-add-mailcap-entry | 753 | (let ((entry |
| 740 | (car tl) (cadr tl) | 754 | `((viewer . ,viewer) |
| 741 | `((viewer . ,viewer) | 755 | (test . ,(if test test t)) |
| 742 | (test . ,(if test test t)) | 756 | (type . ,type)))) |
| 743 | (type . ,type))))) | 757 | ;; Store it. |
| 758 | (mailcap-add-mailcap-entry (car tl) (cadr tl) entry | ||
| 759 | 'mailcap-user-mime-data) | ||
| 760 | ;; Make it available for usage. | ||
| 761 | (mailcap-add-mailcap-entry (car tl) (cadr tl) entry)))) | ||
| 744 | 762 | ||
| 745 | ;;; | 763 | ;;; |
| 746 | ;;; The main whabbo | 764 | ;;; The main whabbo |
| @@ -791,13 +809,13 @@ If NO-DECODE is non-nil, don't decode STRING." | |||
| 791 | ;; NO-DECODE avoids calling `mail-header-parse-content-type' from | 809 | ;; NO-DECODE avoids calling `mail-header-parse-content-type' from |
| 792 | ;; `mail-parse.el' | 810 | ;; `mail-parse.el' |
| 793 | (let ( | 811 | (let ( |
| 794 | major ; Major encoding (text, etc) | 812 | major ; Major encoding (text, etc) |
| 795 | minor ; Minor encoding (html, etc) | 813 | minor ; Minor encoding (html, etc) |
| 796 | info ; Other info | 814 | info ; Other info |
| 797 | major-info ; (assoc major mailcap-mime-data) | 815 | major-info ; (assoc major mailcap--computed-mime-data) |
| 798 | viewers ; Possible viewers | 816 | viewers ; Possible viewers |
| 799 | passed ; Viewers that passed the test | 817 | passed ; Viewers that passed the test |
| 800 | viewer ; The one and only viewer | 818 | viewer ; The one and only viewer |
| 801 | ctl) | 819 | ctl) |
| 802 | (save-excursion | 820 | (save-excursion |
| 803 | (setq ctl | 821 | (setq ctl |
| @@ -809,12 +827,12 @@ If NO-DECODE is non-nil, don't decode STRING." | |||
| 809 | (if viewer | 827 | (if viewer |
| 810 | (setq passed (list viewer)) | 828 | (setq passed (list viewer)) |
| 811 | ;; None found, so heuristically select some applicable viewer | 829 | ;; None found, so heuristically select some applicable viewer |
| 812 | ;; from `mailcap-mime-data'. | 830 | ;; from `mailcap--computed-mime-data'. |
| 813 | (mailcap-parse-mailcaps nil t) | 831 | (mailcap-parse-mailcaps nil t) |
| 814 | (setq major (split-string (car ctl) "/")) | 832 | (setq major (split-string (car ctl) "/")) |
| 815 | (setq minor (cadr major) | 833 | (setq minor (cadr major) |
| 816 | major (car major)) | 834 | major (car major)) |
| 817 | (when (setq major-info (cdr (assoc major mailcap-mime-data))) | 835 | (when (setq major-info (cdr (assoc major mailcap--computed-mime-data))) |
| 818 | (when (setq viewers (mailcap-possible-viewers major-info minor)) | 836 | (when (setq viewers (mailcap-possible-viewers major-info minor)) |
| 819 | (setq info (mapcar (lambda (a) | 837 | (setq info (mapcar (lambda (a) |
| 820 | (cons (symbol-name (car a)) (cdr a))) | 838 | (cons (symbol-name (car a)) (cdr a))) |
| @@ -847,7 +865,7 @@ If NO-DECODE is non-nil, don't decode STRING." | |||
| 847 | ((eq request 'all) | 865 | ((eq request 'all) |
| 848 | passed) | 866 | passed) |
| 849 | (t | 867 | (t |
| 850 | ;; MUST make a copy *sigh*, else we modify mailcap-mime-data | 868 | ;; MUST make a copy *sigh*, else we modify mailcap--computed-mime-data |
| 851 | (setq viewer (copy-sequence viewer)) | 869 | (setq viewer (copy-sequence viewer)) |
| 852 | (let ((view (assq 'viewer viewer)) | 870 | (let ((view (assq 'viewer viewer)) |
| 853 | (test (assq 'test viewer))) | 871 | (test (assq 'test viewer))) |
| @@ -1057,7 +1075,7 @@ For instance, \"foo.png\" will result in \"image/png\"." | |||
| 1057 | (nconc | 1075 | (nconc |
| 1058 | (mapcar 'cdr mailcap-mime-extensions) | 1076 | (mapcar 'cdr mailcap-mime-extensions) |
| 1059 | (let (res type) | 1077 | (let (res type) |
| 1060 | (dolist (data mailcap-mime-data) | 1078 | (dolist (data mailcap--computed-mime-data) |
| 1061 | (dolist (info (cdr data)) | 1079 | (dolist (info (cdr data)) |
| 1062 | (setq type (cdr (assq 'type (cdr info)))) | 1080 | (setq type (cdr (assq 'type (cdr info)))) |
| 1063 | (unless (string-match-p "\\*" type) | 1081 | (unless (string-match-p "\\*" type) |
| @@ -1117,7 +1135,7 @@ For instance, \"foo.png\" will result in \"image/png\"." | |||
| 1117 | 1135 | ||
| 1118 | (defun mailcap-view-mime (type) | 1136 | (defun mailcap-view-mime (type) |
| 1119 | "View the data in the current buffer that has MIME type TYPE. | 1137 | "View the data in the current buffer that has MIME type TYPE. |
| 1120 | `mailcap-mime-data' determines the method to use." | 1138 | `mailcap--computed-mime-data' determines the method to use." |
| 1121 | (let ((method (mailcap-mime-info type))) | 1139 | (let ((method (mailcap-mime-info type))) |
| 1122 | (if (stringp method) | 1140 | (if (stringp method) |
| 1123 | (shell-command-on-region (point-min) (point-max) | 1141 | (shell-command-on-region (point-min) (point-max) |