unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: "gliao.tw@pm.me" <gliao.tw@pm.me>
To: Eli Zaretskii <eliz@gnu.org>
Cc: "emacs-devel@gnu.org" <emacs-devel@gnu.org>
Subject: Re: face-attribute and face-remapping-alist
Date: Wed, 31 Mar 2021 22:41:24 +0000	[thread overview]
Message-ID: <XksHpET9pecTRk9aZLUfE-0UzU1bHPgAQacS23G2qmn_ojqdG4eaqZpo4eTUAjWOid_qARkdKTcxnTtCNnDJ9yUsx047nKVvWQ2ReMfdDbg=@pm.me> (raw)
In-Reply-To: <83sg4bizbr.fsf@gnu.org>



#+begin_src emacs-lisp

  (setq term-current-face
	      (list :foreground
		    (face-foreground
		     (elt ansi-term-color-vector term-ansi-current-color)
		     nil 'default)
		    :background
		    (face-background
		     (elt ansi-term-color-vector term-ansi-current-bg-color)
		     nil 'default)
		    :inverse-video term-ansi-current-reverse))

#+end_src

  And we already know that if an `ansi-term' buffer has its
  `term-color-*' faces have been customized through `face-remap-add-relative',
  `face-foreground' and `face-background' in above code won't
  return correct face information due to `face-attribute' is not
  aware of the `ansi-term' buffer's `face-remapping-alist' local variable.

  Therefore, to make `ansi-term' receive correct face information,
  we need to

  1. change 'face-attribute' to make it aware of `face-remapping-alist'
     in a way that is similar to my earlier proposal; or

  2. do not change any existing face-related functions but define new
     functions to retrieve buffer-local face settings such like

#+begin_src emacs-lisp

  (defun face-attribute-blfa (face attribute &optional frame inherit buffer)
    "Get face attribute with buffer-local faces aware"
    ;; retrieve buffer-local `face-remapping-alist', if it exists
    (or (let ((bl-fra (buffer-local-value
		       'face-remapping-alist
		       (or (and buffer (get-buffer buffer))
			   (current-buffer)))))
	  (and bl-fra
	       (plist-get (car (alist-get face bl-fra)) attribute)))
	(face-attribute face attribute frame inherit)))

  (defun face-foreground-blfa (face &optional frame inherit buffer)
    (face-attribute-blfa face :foreground frame inherit buffer))

  (defun face-background-blfa (face &optional frame inherit buffer)
    (face-attribute-blfa face :background frame inherit buffer))

  (setq term-current-face
	(list :foreground
	      (face-foreground-blfa
	       (elt ansi-term-color-vector term-ansi-current-color)
	       nil 'default)
	      :background
	      (face-background-blfa
	       (elt ansi-term-color-vector term-ansi-current-bg-color)
	       nil 'default)
	      :inverse-video term-ansi-current-reverse))

#+end_src

As mentioned in my previous mails, introducing new APIs (without changing existing
`face-attribute'-based functions) to make buffer-local faces work sufficiently well in
various modes do require library/package developers to adapt the new APIs and change,
potentially considerable, part of their existing code base to accommodate that.

So my question here is that which of the following options

1. make `face-attribute' return buffer-local face attributes if the face has been
   customized (via `face-remapping-alist) in that buffer otherwise return
   frame-local face attributes
2. Introducing new face attribute getting/setting APIs to Emacs code base;
   these new APIs  are `face-remapping-alist' aware and use unchanged
   `face-attribute' as the fallback dispatch option
3.  Do nothing to Emacs code base: let the library/package developer to decide
    whether buffer local face settings should be accommodated or not

is the most economical one?

I personally believe the option #1 is the most favorable one because, ideally,
`face-attribute' should always return face attributes those are consistent with
what have been rendered in any given buffer. Also, this option does not require
changing any existing code base of libraries/packages/modes those manipulate
faces (for example, `term.el'). However, I don't know how much risk of
potential breakage brought by option #1. Therefore, we may treat this option
as a convenient (only need to change `face-attribute') but also a dangerous one.

Option #2 is an acceptable choice to me although it require porting efforts
from the mode/library/package developers to adapt new APIs in Emacs,
but at least we have an official APIs that can be used by all Emacs library/package
developers without re-inventing wheels.

Option #3 is the least favorable option to me, as it requires developers to come
up with lots of solutions just to solve the common problem of retrieving
face information those are consistent with what have been rendered in any
given buffers. This wild west approach seems not helpful in solving the
problem.

Thanks.
Kiong-Gē.





‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Wednesday, March 31, 2021 1:58 AM, Eli Zaretskii <eliz@gnu.org> wrote:

> > Date: Wed, 31 Mar 2021 03:05:42 +0000
>
> > From: "gliao.tw@pm.me" gliao.tw@pm.me
> > Cc: "emacs-devel@gnu.org" emacs-devel@gnu.org
> >
> > > From the above example, we can see that `face-attribute' will return results *incosistent* with what we see in a buffer which has been updated with a theme in buffer-local manner via functions implemented in`face-remap.el'.
>
> Sure, but the only change needed in all the cases you described in
> order to return attributes that are aware of the remapping is to look
> up the face in face-remapping-alist, before calling face-attribute.
> This solution is so easy that I don't understand the need for changing
> the behavior of face-attribute in such fundamental and incompatible
> ways to produce the same effect.
>
> Am I missing something?





  parent reply	other threads:[~2021-03-31 22:41 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-30 18:53 face-attribute and face-remapping-alist gliao.tw
2021-03-30 19:05 ` Eli Zaretskii
2021-03-30 19:13   ` Eli Zaretskii
2021-03-31  3:05     ` gliao.tw
2021-03-31  3:34       ` gliao.tw
2021-03-31  6:58       ` Eli Zaretskii
2021-03-31 13:00         ` Clément Pit-Claudel
2021-03-31 13:27           ` Eli Zaretskii
2021-03-31 22:41         ` gliao.tw [this message]
2021-04-01  7:08           ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='XksHpET9pecTRk9aZLUfE-0UzU1bHPgAQacS23G2qmn_ojqdG4eaqZpo4eTUAjWOid_qARkdKTcxnTtCNnDJ9yUsx047nKVvWQ2ReMfdDbg=@pm.me' \
    --to=gliao.tw@pm.me \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).