unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* face-attribute and face-remapping-alist
@ 2021-03-30 18:53 gliao.tw
  2021-03-30 19:05 ` Eli Zaretskii
  0 siblings, 1 reply; 10+ messages in thread
From: gliao.tw @ 2021-03-30 18:53 UTC (permalink / raw)
  To: emacs-devel@gnu.org

The `face-attribute' function defined in `faces.el' is the foundation of many face property inquiry functions such as `face-background'. However, `face-attribute' is not aware of buffer-local variable 'face-remapping-alist' which is used for buffer-specific theming.

Since there are many modes, such as `term-mode', rely on `face-attribute' to obtain face information while `face-attribute' is only capabale of obtaining frame-specific, rather than buffer-specific face infomation, these modes cannot display faces sufficiently well while a buffer-local theme is applied via `face-remap-add-relative' or `face-remap-set-base' (both functions, defined in `face-remap.el', add items to buffer-specific variable `face-remapping-alist').

Therefore, I propose the following prototype of an enhanced version of `face-attribute' function that is aware of the existence of `face-remapping-alist' in current buffer and return face property from `face-remapping-alist' instead of  frame-specific (single frame also means global) face property.

Any comments are greatly appreciated, thanks.

Kiong-Gē.

---------------------------


;;
(defun face-attribute (face attribute &optional frame inherit)
  "Return the value of FACE's ATTRIBUTE on FRAME or current buffer.
If the optional argument FRAME is given, report on face FACE in that frame.
If FRAME is t, report on the defaults for face FACE (for new frames).
If FRAME is omitted or nil, use the selected frame.

If INHERIT is nil, only attributes directly defined by FACE are considered,
  so the return value may be `unspecified', or a relative value.
If INHERIT is non-nil, FACE's definition of ATTRIBUTE is merged with the
  faces specified by its `:inherit' attribute; however the return value
  may still be `unspecified' or relative.
If INHERIT is a face or a list of faces, then the result is further merged
  with that face (or faces), until it becomes specified and absolute.

To ensure that the return value is always specified and absolute, use a
value of `default' for INHERIT; this will resolve any unspecified or
relative values by merging with the `default' face (which is always
completely specified)."
  ;; check if `face-remapping-alist' exist as a buffer-local variable
  ;; in current buffer
  (let* ((local-faces (if (local-variable-p 'face-remapping-alist
					    (current-buffer))
			  ;; if so, take faces information from it
			  (buffer-local-value 'face-remapping-alist
					      (current-buffer))))
	 ;; try to fetch buffer-local face proprety from face-remapping-alist
	 (local-face-prop (if local-faces
			      (plist-get (car (alist-get face local-faces))
					 attribute))))
    ;; if there is no inquired face informatio available in
    ;; face-remapping-alist, fallback to frame-specific values
    (or local-face-prop
	(let ((value (internal-get-lisp-face-attribute face attribute frame)))
	  (when (and inherit (face-attribute-relative-p attribute value))
	    ;; VALUE is relative, so merge with inherited faces
	    (let ((inh-from (face-attribute face :inherit frame)))
	      (unless (or (null inh-from) (eq inh-from 'unspecified))
		(condition-case nil
		    (setq value
			  (face-attribute-merged-with attribute value inh-from frame))
		  ;; The `inherit' attribute may point to non existent faces.
		  (error nil)))))
	  (when (and inherit
		     (not (eq inherit t))
		     (face-attribute-relative-p attribute value))
	    ;; We should merge with INHERIT as well
	    (setq value (face-attribute-merged-with attribute value inherit frame)))
	  value))))


----------------------------------------







^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-04-01  7:08 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
2021-04-01  7:08           ` Eli Zaretskii

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).