From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.devel Subject: Re: Local face remapping Date: Fri, 06 Oct 2023 08:41:03 +0300 Message-ID: <837co02tqo.fsf@gnu.org> References: <1AB6E9C8-1BCB-4C0A-A4AF-45F5C64D9B4C@gmail.com> <838r8i5nwe.fsf@gnu.org> <5E16BC09-3063-4509-9DF6-7C8EC25E1285@gmail.com> <83y1gh4os9.fsf@gnu.org> <8EA60CCA-70A7-40FC-86E7-649EB10AE6E7@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="10082"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: JD Smith Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Oct 06 07:41:50 2023 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qodav-0002R2-T7 for ged-emacs-devel@m.gmane-mx.org; Fri, 06 Oct 2023 07:41:49 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qoda8-0006pp-2v; Fri, 06 Oct 2023 01:41:00 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qoda6-0006lP-Cu for emacs-devel@gnu.org; Fri, 06 Oct 2023 01:40:58 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qoda6-0002we-27; Fri, 06 Oct 2023 01:40:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-version:References:Subject:In-Reply-To:To:From: Date; bh=t6DCz9PYbjvm7yYpqiRc7APJIkvmHsNrT1P5OXfEqNM=; b=JiuuuAtXxem3Ogbb6eoK LBlNlPwW8Tmq4dcHy5xlOKzmCOBcOg7stwllmBbjyrvytNWBRL1skYQWSZgwDl3s4fZ681IQT+wCn 4XZIc/dbjhZR7Tx24HX6R9TJvTi/tvxcKdNpJ0VHOHMHiOZ2mlUpUXN+R4rsE/dqeEgMCNGRE6D3d dWi/KrRsV9dpTsYY6objZyI8mzOnxVexBaLqabwBygSmjO17chSxWRgxT8NUjyd+NFykNKXWbNZLq 4I6RjukFlvA2XeoALHK946p51vEmY1NNUNPkaNY1lJWawMJk7M/WMHSWJ6zU3b6aciit/mxiRIbPo QAXUUbcfWIhLOg==; In-Reply-To: <8EA60CCA-70A7-40FC-86E7-649EB10AE6E7@gmail.com> (message from JD Smith on Thu, 5 Oct 2023 09:12:58 -0400) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:311319 Archived-At: > From: JD Smith > 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.