Subject: bug#71345: Feature: unleash font-lock's secret weapon; handle Qfontified = non-nil

From: JD Smith <[email-masked]>
Date: Wed, 5 Jun 2024 11:52:37 -0400

> On Jun 5, 2024, at 10:53 AM, Eli Zaretskii <[email-masked]> wrote:
> 
>> From: JD Smith <[email-masked]>
>> Cc: [email-masked], [email-masked]
>> Date: Wed, 5 Jun 2024 10:02:23 -0400
>> 
>> In general, yes.  In my case having the scope be per-buffer not per window makes the most sense in
>> terms of
>> 
>> the functionality.
>> 
>> Given the feature of redisplay I just mentioned, you will actually get
>> 
>> a per-window functionality, at least as far as the position of point
>> 
>> is concerned.
>> 
>> Not in my case, since I am discriminating between point in the selected window and other windows showing the
>> same buffer, such that switching windows = changing point. Since much of the work in my mode is not
>> position-dependent but depends on text content, updating face is the natural thing.  
> 
> Sorry, I don't think I understand you.  But if the fact that redisplay
> moves point to window-point doesn't bother me, we can drop this issue.

I use treesitter to identify nodes of interest, and do that in a PCH.  So there is one buffer-local record of where that node of interest is.  Thus different windows showing the same buffer is immaterial; the window where the last PCH ran controls.

>> Thinking more about what makes font-lock “special” as a jit-lock backend, it is exactly this: font-lock claims
>> exclusive ownership of `face'.  Solutions I can see:
>> 
>> 1 Make font-lock a good citizen by using its own alias for face. 
>> 2 Give other jit-lock backends which may alter face and potentially conflict with font-lock the ability to specify
>> to jit-lock “if you re-run font lock on a region, re-run me too after that.”
> 
> I don't understand.  The solution to this dilemma is well known: Lisp
> programs that want to control faces without turning off font-lock mode
> should set font-lock-face property, instead of the face property.  Why
> do you need to find another solution?

Because such programs may need to override locations where font-lock has already applied 'face.  In contrast to the documentation[1], font-lock does not itself use font-lock-face, but only configures it for other programs to use.  The issue is that 'face, where applied, always outranks any alias to 'face placed on the same text:

;; TEST (1st disable font-lock-mode)
(push 'my-face-prop (alist-get 'face char-property-alias-alist))
(put-text-property 1 8 'face 'error)
(put-text-property 1 8 'my-face-prop 'success) ; outranked by 'face
(remove-text-properties 1 8 '(face nil)) ; now we can see my-face-prop
<<<<<<<

It would be wonderful if font-lock cleared and applied a suitable face alias (perhaps 'font-lock-face itself).  This is what I mean by making font-lock a "good citizen": let other backends be able to override the faces it sets.  Currently, if font-lock-mode is enabled, it has effectively exclusive rights to the use of 'face on the locations it matches.  The only hope then is to arrange to run after font-lock, and use the "heavy hammer" of overwriting 'face yourself.

[1] From `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.
But I believe all font-lock keywords actually just set the 'face property.