[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
remapping).
> > 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
mouse-highlight.