Subject: bug#18367: 24.4.50; [PATCH] Text property `font-lock-ignore', to protect from font-lock

From: Drew Adams <[email-masked]>
Date: Sun, 31 Aug 2014 08:30:54 -0700 (PDT)

> > Bug or missing feature: Prevent font-lock from changing text
> > properties on text that has property `font-lock-ignore'.  See
> > http://lists.gnu.org/archive/html/emacs-devel/2014-08/msg00540.html
> 
> Could you add a short explanation for why font-lock-face is
> not sufficient?

Sorry, but I don't know why it might be imagined sufficient.  Can
you hint how?  IOW, so far, I don't see how it is relevant at all.

If you could please hint how one might use `font-lock-face' to
protect ad hoc highlighting that uses `face', then I can perhaps
try to add a short explanation about that, if you think the bug
report is still relevant in that case.

But if you really think that `font-lock-face' is sufficient, then
why not just close the bug?  In that case, however, I would still
appreciate knowing how.

Trying to see what you might have in mind...

I see this in (elisp) `Font Lock Basics' about `font-lock-face':

 If your mode fontifies text explicitly by adding `font-lock-face'
 properties, it can specify `(nil t)' for `font-lock-defaults' to turn
 off all automatic fontification.  However, this is not required; it is
 possible to fontify some things using `font-lock-face' properties and
 set up automatic fontification for other parts of the text.

The last sentence sounds vaguely related (the first sentence seems
irrelevant).  But it says nothing about how you would do it, so I
don't really understand it.  And it presumably is, like the first
sentence, talking about some mode, whereas there is nothing about
any mode in the feature I described (ad hoc highlighting, whether
or not the buffer is font-locked).

I see this in (elisp) `Search-based Fontification':

 If it is `prepend', the face specified by FACESPEC is
 added to the beginning of the `font-lock-face' property.  If it is
 `append', the face is added to the end of the `font-lock-face'
 property.

That too tells me nothing about what the resulting behavior is, or
what `font-lock-face' is for.

(elisp) `Other Font Lock Variables' says this about it:

 Variable: font-lock-extra-managed-props
 This variable specifies additional properties (other than
 `font-lock-face') that are being managed by Font Lock mode.  It is
 used by `font-lock-default-unfontify-region', which normally only
 manages the `font-lock-face' property.  If you want Font Lock to
 manage other properties as well, you must specify them in a
 FACESPEC in `font-lock-keywords' as well as add them to this list.
 *Note Search-based Fontification::.

Again, I'm afraid that tells me nothing about what `font-lock-face'
is for or how to use it.  It seems to be saying only that
`font-lock-face' is removed by `font-lock-default-unfontify-region'
and you can change the var to have it also remove other properties.
(But the code of that function does not refer to `font-lock-face'
at all AFAICT (?).)  And it makes the vague statement that
`font-lock-face' is "managed by Font Lock mode", whatever that might
mean.

(elisp) `Precalculated Fontification' says this:

 Some major modes such as `list-buffers' and `occur' construct the
 buffer text programmatically.  The easiest way for them to support Font
 Lock mode is to specify the faces of text when they insert the text in
 the buffer.

 The way to do this is to specify the faces in the text with the
 special text property `font-lock-face' (*note Special Properties::).
 When Font Lock mode is enabled, this property controls the display,
 just like the `face' property.  When Font Lock mode is disabled,
 `font-lock-face' has no effect on the display.

 It is ok for a mode to use `font-lock-face' for some text and also
 use the normal Font Lock machinery.  But if the mode does not use the
 normal Font Lock machinery, it should not set the variable
 `font-lock-defaults'.

That says only (AFAICT) that if some text has property
`font-lock-face' then that property "controls the display, just
like the `face' property".  But it does not say what that means.
And it says that when font-lock is disabled, highlighting with
`font-lock-face' is also disabled, which is hardly the aim of the
feature I proposed.

That passage seems to correspond to what I have understood in the
past about `font-lock-face': It lets you use font-lock to highlight
text, i.e., to have some given highlighting handled by font-lock -
to let a major mode "support Font Lock mode".  That is opposite to
the feature I proposed, AFAICT.

Finally, we get to what is presumably the main place (e.g. indexed)
that `font-lock-face' is described, (elisp) `Special Properties':

 `font-lock-face'
 This property specifies a value for the `face' property that Font
 Lock mode should apply to the underlying text.  It is one of the
 fontification methods used by Font Lock mode, and is useful for
 special modes that implement their own highlighting.  *Note
 Precalculated Fontification::.  When Font Lock mode is disabled,
 `font-lock-face' has no effect.

That doesn't help me understand, I'm afraid.  AFAICT, all it says
is that `font-lock-face' is used like `face' by font-lock.  I don't
see how that text distinguishes it from `face', except in name.
(I know that it is distinguished, but that passage does not speak
to that.)

Coming to the code: Each occurrence of `font-lock-face' in
`font-lock.el' simply pairs it with `face', treating the two the
same way.  These are the only occurrences there:

font-lock.el:1378:      (and (memq prop '(face font-lock-face))
font-lock.el:1398:      (and (memq prop '(face font-lock-face))

If I look at how `font-lock-face' is used elsewhere in the code,
e.g. in `occur' (as suggested by (elisp) `Precalculated
Fontification'), it seems that the use case for it is to apply
a face to text in an ad hoc way (good), i.e., other than by using
`font-lock-keywords', and yet to have font-lock effect/control
that highlighting (bad, er, not the feature I have in mind).

And that is exactly what I have understood for `font-lock-face'
in the past:

You can apply it to text any way you like, without bothering
with `font-lock-keywords', and yet font-lock will "control" it:
turning font-lock on shows the highlighting; turning font-lock
off hides it.

IOW, AFAICT, it is a way to get font-lock to control additional
(e.g. ad hoc) highlighting, beyond the control provided by
`font-lock-keywords'.

Presumably the reason for using a different property from
`face' for this is so that font-lock does not turn on/off all
`face'-propertied text, in particular, so that `font-lock-mode'
need not be on for some `face'-propertied text to be highlighted.
Of course, that does not prevent font-lock from turning OFF
other highlighting, which is the point of the feature I proposed.

If I have understood correctly, giving font-lock control over
additional (e.g. non `font-lock-keywords') highlighting is what
`font-lock-face' is for.  And in that case it is opposite to the
feature I propose, which is to remove font-lock control over
given ad hoc highlighting.

Please let me know what I am missing or misunderstand.