[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Local face remapping

From: Eli Zaretskii
Subject: Re: Local face remapping
Date: Fri, 06 Oct 2023 08:41:03 +0300

> From: JD Smith <jdtsmith@gmail.com>
> Date: Thu, 5 Oct 2023 09:12:58 -0400
> Cc: emacs-devel@gnu.org
> > In Emacs, faces are defined per-frame.  That is, each frame can have a
> > different definition of the same face symbol.
> > 
> > face-remapping-alist doesn't (and cannot) change that simple fact, so
> > it is a trick: it creates new faces based on default faces, in a way
> > that is buffer-local.  This works (btw, not in all places) because the
> > display engine consults the buffer-local value of face-remapping-alist
> > each time it needs to realize a face for display.  If that variable is
> > non-nil, and the face to be realized is mentioned in the alist, then
> > the display engine generates a new face on the fly and uses that new
> > face for display.
> Interesting.  I presume with caching?

Yes, each frame has its own face cache (that is orthogonal to face

> > So, if you want face-remapping that depends on buffer positions, you
> > will need to change the implementation of face-remapping: instead of a
> > simple alist, we will probably need to also allow a function returning
> > such an alist, and the C code will need to be taught to deal with
> > the situation where face-remapping-alist's value is a function.
> That’s an interesting idea, more flexible than hard-coding a simple function 
> that considers START…END.  You wouldn’t want to call such a function for each 
> FACE character, and if the region divides a FACE interval, that adds 
> complexity. But maybe tractable.

Emacs only computes the faces when the face changes, so this is not a
significant complication, IMO.

> > My suggestion to use different faces just does explicitly what
> > face-remapping-alist does implicitly.
> But much less efficiently, if the faces to be altered appear in many 
> non-contiguous intervals, and within ‘display strings in that (potentially 
> large) region.  The advantage of the “just in time” face substitution you 
> describe is it operates from the top down and is thus suitable for rapid 
> updates via, e.g., post-command-hooks. It also plays nicely with font-lock, 
> etc.

Maybe.  My idea was that the same code which decides that colors
should change can place the new faces on the text in the region, and
how heavy could that be?

> A perhaps related concept would be allowing code (including font-lock) to 
> apply secondary face(s) to text, via an alist, perhaps.  Secondary faces 
> would lie dormant, unless and until an overlay or text property explicitly 
> enables one of them (`use-secondary-face ‘foo', or similar).  In this way it 
> would be similar to mouse-face, but explicitly under programmatic control 
> instead of implicit mouse position control. An overlay or text property could 
> then be applied to an entire region enabling specific secondary faces within 
> it to “come alive”, quite similar to how mouse position causes mouse-face to 
> activate.

Actually, mouse-face is also under Lisp program control: see

reply via email to

[Prev in Thread] Current Thread [Next in Thread]