On Jan 5, 2024, at 11:35 AM, Dmitry Gutov <dmitry@gutov.dev> wrote:

On 05/01/2024 10:19, Eli Zaretskii wrote:
I’m sure there could be lots of uses of this type of functionality, but “enhance the focus on one region
of importance” seems like a very common one.  For example, you might imagine dim/gray version of
all the font-lock faces outside the “treesitter region of interest” and bright ones inside.  Whenever that
TS-prescribed region changes, an overlay with a ‘face-remap property gets moved.
The question I suggest to ponder is whether simpler, less general ways
to implement these features are "good enough".  For example, changing
the appearance of a region of text can be handled by moving an overlay
there with a suitable face definition and high priority; changing the
appearance of text around point can be handled by a special variable
which the display engine will consider when working on text around
point;

An overlay with face and higher priority would override most faces in the region, wouldn't it? Unless it just sets the background, in which case we already have this capability.

JD, have you considered it? E.g. set the default face's background to some darker color and use an overlay which sets background to a lighter one.

I’ve definitely considered “re-style all of one particular face attribute” options like this and none I’ve found are suitable in my case (though perhaps for the TS-current-context example I gave this could be a decent option).  The best analogy is the one I just offered in my reply to Eli: changing the class of an HTML element and having subsets of styled text within it automatically updated, thanks to the inheritance capabilities of CSS (not that that’s an explicit model for Emacs to emulate; just conveying the idea). 

But if that's not sufficient, we could use a hook similar to what you (Eli) mentioned in the other subthread. Except instead of having a functions for face properties, it could be a global function that would be called on a "realized" plist of face attributes and return the adjusted one, for the point. The upside is that the display code won't have to look for another text property (and where its intervals start and end).

I see, so that function could look at some properties at point and decide whether to alter or “let stand” the computed faces.  I believe that would work and is obviously rather flexible, but it sounds even more general than the ‘face-remap property approach.

The downside, though, is that the realized plist might no be cache-able (the function can return a different value based on any number of conditions, right?).

Right.   I don’t know how the caching is done, but I’d expect this would be harder.  Imagine for example every other invocation of this “final-face-remap-function” you propose changes from :foreground “blue” to :foreground “red” (ok not a very useful example, but illustrative).  Can the face merge code notice this repetition and keep the cache valid?