Discussion:
mailcap MIME type handlers
(too old to reply)
Ben Bacarisse
2018-09-23 02:52:03 UTC
Permalink
Short version:

How can I get Emacs (specifically mailcap.el) to prioritise my system's
or my personal mailcap settings?

Gnus, for example, opens PDF files in doc-view-mode rather than using
the program specified in /etc/mailcap or ~/.mailcap.

In more detail...

From an quick examination of mailcap.el it seems that an initial set of
mailcap data, given an explicit list assigned to mailcap-mime-data, is
augmented by reading the system's mailcap files along with the user's
mailcap. However, the initial data do not simply provide a default
back-stop because many of them use Emacs modes that are, for most
people, to be preferred. This is achieved by sorting the list of
possible matches with a predicate that favours Lisp symbols over strings
(mailcap-viewer-lessp). Thus '(viewer doc-view-mode) will win over
'(viewer "/usr/bin/mupdf %s") or, indeed, over any setting from the
parsed files.

I have a crude solution. If, after mailcap is loaded, I manually
execute

(setq mailcap-mime-data nil)
(mailcap-parse-mailcaps nil t)

only the parsed entries will be seen as the initial value of
mailcap-mime-data is lost. But this is not a good solution not least
because I may want some of these "built-in" handlers -- I haven't
checked them all.

What is the proper way to deal with this?

If there isn't a neat solution, maybe I can hook into the mailcap system
to get the behaviour I want. What's the best way to do that? Do I need
to resort to advice-add?
--
Ben.
Ivan Shmakov
2018-10-06 04:57:33 UTC
Permalink
I've removed news:gnu.emacs.help from Newsgroups: as I seem to
recall the gnu.* hierarchy maintainers requesting for the new
posts to be submitted strictly via the respective mailing lists.

[...]
Post by Ben Bacarisse
From an quick examination of mailcap.el it seems that an initial set
of mailcap data, given an explicit list assigned to mailcap-mime-data,
is augmented by reading the system's mailcap files along with the
user's mailcap. However, the initial data do not simply provide a
default back-stop because many of them use Emacs modes that are, for
most people, to be preferred. This is achieved by sorting the list
of possible matches with a predicate that favours Lisp symbols over
strings (mailcap-viewer-lessp). Thus '(viewer doc-view-mode) will
win over '(viewer "/usr/bin/mupdf %s") or, indeed, over any setting
from the parsed files.
Some sort of a priority value would've helped here, I think.
Post by Ben Bacarisse
I have a crude solution. If, after mailcap is loaded, I manually
execute
(setq mailcap-mime-data nil)
(mailcap-parse-mailcaps nil t)
only the parsed entries will be seen as the initial value of
mailcap-mime-data is lost. But this is not a good solution not least
because I may want some of these "built-in" handlers -- I haven't
checked them all.
You can remove only the offending values (instead of emptying
the list); something along the lines of:

(mapc (lambda (subalist)
(setcdr subalist
(cl-delete-if (lambda (ent)
(let ((v (cdr (assq 'viewer ent))))
;; Alternatively:
; (and v (symbolp v))
(eq 'doc-view-mode v)))
(cdr subalist))))
mailcap-mime-data)
Post by Ben Bacarisse
What is the proper way to deal with this?
If there isn't a neat solution, maybe I can hook into the mailcap
system to get the behaviour I want. What's the best way to do that?
Do I need to resort to advice-add?
I suppose you can alter the behavior of mailcap-viewer-lessp, yes.
--
FSF associate member #7257 np. The Sacred Armour of Antiriad -- Milo Fultz
Ben Bacarisse
2018-10-07 10:22:47 UTC
Permalink
Post by Ivan Shmakov
I've removed news:gnu.emacs.help from Newsgroups: as I seem to
recall the gnu.* hierarchy maintainers requesting for the new
posts to be submitted strictly via the respective mailing lists.
I didn't know about that. Turns out someone has just asked a very
similar question there.
Post by Ivan Shmakov
[...]
Post by Ben Bacarisse
From an quick examination of mailcap.el it seems that an initial set
of mailcap data, given an explicit list assigned to mailcap-mime-data,
is augmented by reading the system's mailcap files along with the
user's mailcap. However, the initial data do not simply provide a
default back-stop because many of them use Emacs modes that are, for
most people, to be preferred. This is achieved by sorting the list
of possible matches with a predicate that favours Lisp symbols over
strings (mailcap-viewer-lessp). Thus '(viewer doc-view-mode) will
win over '(viewer "/usr/bin/mupdf %s") or, indeed, over any setting
from the parsed files.
Some sort of a priority value would've helped here, I think.
Yes. I was wondering how it might best be done because, in the long
run, I'd rather offer a patch to make mailcap.el be more flexible than
simply code a work-around for myself. But it's not trivial to come up
with a simple but flexible arrangement.
Post by Ivan Shmakov
Post by Ben Bacarisse
I have a crude solution. If, after mailcap is loaded, I manually
execute
(setq mailcap-mime-data nil)
(mailcap-parse-mailcaps nil t)
only the parsed entries will be seen as the initial value of
mailcap-mime-data is lost. But this is not a good solution not least
because I may want some of these "built-in" handlers -- I haven't
checked them all.
You can remove only the offending values (instead of emptying
(mapc (lambda (subalist)
(setcdr subalist
(cl-delete-if (lambda (ent)
(let ((v (cdr (assq 'viewer ent))))
; (and v (symbolp v))
(eq 'doc-view-mode v)))
(cdr subalist))))
mailcap-mime-data)
Thanks.
Post by Ivan Shmakov
Post by Ben Bacarisse
What is the proper way to deal with this?
If there isn't a neat solution, maybe I can hook into the mailcap
system to get the behaviour I want. What's the best way to do that?
Do I need to resort to advice-add?
I suppose you can alter the behavior of mailcap-viewer-lessp,
yes.
I tried that as well and I can certainly get what I want by doing that.

What's the right way to hook into a file being loaded? I'd rather not
"(require 'mailcap)" in .emacs just so that I can do some fix-ups after
mailcap.el is loaded. I'm sure this is a trivial question, but I could
not find the hook to do it.
--
Ben.
Michael Heerdegen
2018-10-07 12:23:01 UTC
Permalink
Post by Ben Bacarisse
What's the right way to hook into a file being loaded? I'd rather not
"(require 'mailcap)" in .emacs just so that I can do some fix-ups after
mailcap.el is loaded. I'm sure this is a trivial question, but I could
not find the hook to do it.
`with-eval-after-load'?


Michael.
Ben Bacarisse
2018-10-09 13:37:16 UTC
Permalink
Post by Michael Heerdegen
Post by Ben Bacarisse
What's the right way to hook into a file being loaded? I'd rather not
"(require 'mailcap)" in .emacs just so that I can do some fix-ups after
mailcap.el is loaded. I'm sure this is a trivial question, but I could
not find the hook to do it.
`with-eval-after-load'?
Yes, that's the ticket, thanks. And thanks also to Ivan Shmakov for the
same advice. I don't know why I didn't find it myself.

So, for the record, I am currently using

(with-eval-after-load
'mailcap
(setq mailcap-mime-data nil)
(mailcap-parse-mailcaps nil t))

which is crude but is adequate for the time being.

I will get round to your post (in another group) about filing a bug
report eventually. A lot of real life is happening this week...
--
Ben.
Michael Heerdegen
2018-10-09 15:08:54 UTC
Permalink
Post by Ben Bacarisse
I will get round to your post (in another group) about filing a bug
report eventually. A lot of real life is happening this week...
If you want to do that, please check that the fix of bug#23184, i.e. the
introduction of the `mailcap-user-mime-data' user variable, doesn't fix
your problem (unless your Emacs version doesn't have this fix yet).
Else it's an already fixed issue.


Thanks,

Michael.
Ben Bacarisse
2018-10-09 23:07:44 UTC
Permalink
Post by Michael Heerdegen
Post by Ben Bacarisse
I will get round to your post (in another group) about filing a bug
report eventually. A lot of real life is happening this week...
If you want to do that, please check that the fix of bug#23184, i.e. the
introduction of the `mailcap-user-mime-data' user variable, doesn't fix
your problem (unless your Emacs version doesn't have this fix yet).
Else it's an already fixed issue.
Will do (my Emacs does not yet have mailcap-user-mime-data). Thanks for
the heads-up.
--
Ben.
Ivan Shmakov
2018-10-07 12:24:31 UTC
Permalink
Post by Ben Bacarisse
Post by Ivan Shmakov
I've removed news:gnu.emacs.help from Newsgroups: as I seem to
recall the gnu.* hierarchy maintainers requesting for the new posts
to be submitted strictly via the respective mailing lists.
I didn't know about that. Turns out someone has just asked a very
similar question there.
It was years ago, though; my understanding of this may be
severely out of date.

[...]
Post by Ben Bacarisse
What's the right way to hook into a file being loaded? I'd rather
not "(require 'mailcap)" in .emacs just so that I can do some fix-ups
after mailcap.el is loaded. I'm sure this is a trivial question, but
I could not find the hook to do it.
eval-after-load. E. g.:

;;; eieio: Enhanced Implementation of Emacs Interpreted Objects
;; FIXME: this one loads eieio-opt and thus speedbar, etc.
(eval-after-load 'eieio
'(remove-hook 'help-fns-describe-function-functions 'eieio-help-constructor))

It's a function (IOW, not a special form), so you most likely
will need to quote its second argument.
--
FSF associate member #7257 http://am-1.org/~ivan/
Loading...