summaryrefslogtreecommitdiff
path: root/lisp/faces.el
diff options
context:
space:
mode:
authorChong Yidong <cyd@gnu.org>2012-11-25 12:50:20 +0800
committerChong Yidong <cyd@gnu.org>2012-11-25 12:50:20 +0800
commit1c4f115d4c4eb1aa71c25d21e8bdec2f8da97700 (patch)
tree8fb4e906b3cc5455ab45383267eac3c49da5ef44 /lisp/faces.el
parent61d841dd15f1f9921e23d93e8a0c282fe568aed1 (diff)
downloademacs-1c4f115d4c4eb1aa71c25d21e8bdec2f8da97700.tar.gz
Revamp face-spec-set to be more analogous to setq for faces.
* lisp/faces.el (face-spec-set): Change the third arg to specify whether this function is being called via defface, customize, or a third party. Set the appropriate symbol properties. Clear the override spec if setting via Custom. Initialize face if necessary. (face-spec-recalc): Allow theme faces to completely replace the defface spec, in the same way as custom faces (Bug#8454). * lisp/cus-edit.el (custom-face-set, custom-face-mark-to-save) (custom-face-reset-saved, custom-face-mark-to-reset-standard): Simplify by using the new arg to face-spec-set. * lisp/cus-face.el (custom-declare-face): Move face initialization to face-spec-set. (custom-theme-set-faces): Don't initialize the face name here, as that is now done in face-spec-set. * lisp/emacs-lisp/lisp-mode.el (eval-defun-1): When evaluating defface, reset face-override-spec too, and use custom-declare-face. Fixes: debbugs:4988
Diffstat (limited to 'lisp/faces.el')
-rw-r--r--lisp/faces.el99
1 files changed, 67 insertions, 32 deletions
diff --git a/lisp/faces.el b/lisp/faces.el
index 928174c3954..2a0b77b19c4 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -1587,44 +1587,79 @@ If SPEC is nil, return nil."
(mapcar (lambda (x) (list (car x) 'unspecified))
face-attribute-name-alist)))))
-(defun face-spec-set (face spec &optional for-defface)
- "Set and apply the face spec for FACE.
-If the optional argument FOR-DEFFACE is omitted or nil, set the
-overriding spec to SPEC, recording it in the `face-override-spec'
-property of FACE. See `defface' for the format of SPEC.
-
-If FOR-DEFFACE is non-nil, set the base spec (the one set by
-`defface' and Custom). In this case, SPEC is ignored; the caller
-is responsible for putting the face spec in the `saved-face',
-`customized-face', or `face-defface-spec', as appropriate.
-
-The appearance of FACE is controlled by the base spec, by any
-custom theme specs on top of that, and by the overriding spec on
-top of all the rest."
- (if for-defface
- ;; When we reset the face based on its custom spec, then it is
- ;; unmodified as far as Custom is concerned.
- (put (or (get face 'face-alias) face) 'face-modified nil)
- ;; When we change a face based on a spec from outside custom,
- ;; record it for future frames.
- (put (or (get face 'face-alias) face) 'face-override-spec spec))
- ;; Reset each frame according to the rules implied by all its specs.
- (dolist (frame (frame-list))
- (face-spec-recalc face frame)))
+(defun face-spec-set (face spec &optional spec-type)
+ "Set the face spec SPEC for FACE.
+See `defface' for the format of SPEC.
+
+The appearance of each face is controlled by its spec, and by the
+internal face attributes (which can be frame-specific and can be
+set via `set-face-attribute').
+
+The argument SPEC-TYPE determines which spec to set:
+ nil or `face-override-spec' means the override spec (which is
+ usually what you want if calling this function outside of
+ Custom code);
+ `customized-face' or `saved-face' means the customized spec or
+ the saved custom spec;
+ `face-defface-spec' means the default spec
+ (usually set only via `defface');
+ `reset' means to ignore SPEC, but clear the `customized-face'
+ and `face-override-spec' specs;
+Any other value means not to set any spec, but to run the
+function for its other effects.
+
+In addition to setting the face spec, this function defines FACE
+as a valid face name if it is not already one, and (re)calculates
+the face's attributes on existing frames."
+ (if (get face 'face-alias)
+ (setq face (get face 'face-alias)))
+ ;; Save SPEC to the relevant symbol property.
+ (unless spec-type
+ (setq spec-type 'face-override-spec))
+ (if (memq spec-type '(face-defface-spec face-override-spec
+ customized-face saved-face))
+ (put face spec-type spec))
+ (if (memq spec-type '(reset saved-face))
+ (put face 'customized-face nil))
+ ;; Setting the face spec via Custom empties out any override spec,
+ ;; similar to how setting a variable via Custom changes its valus.
+ (if (memq spec-type '(customized-face saved-face reset))
+ (put face 'face-override-spec nil))
+ ;; If we reset the face based on its custom spec, it is unmodified
+ ;; as far as Custom is concerned.
+ (unless (eq face 'face-override-spec)
+ (put face 'face-modified nil))
+ (if (facep face)
+ ;; If the face already exists, recalculate it.
+ (dolist (frame (frame-list))
+ (face-spec-recalc face frame))
+ ;; Otherwise, initialize it on all frames.
+ (make-empty-face face)
+ (let ((value (face-user-default-spec face))
+ (have-window-system (memq initial-window-system '(x w32 ns))))
+ (dolist (frame (frame-list))
+ (face-spec-set-2 face frame value)
+ (when (memq (window-system frame) '(x w32 ns))
+ (setq have-window-system t)))
+ (if have-window-system
+ (make-face-x-resource-internal face)))))
(defun face-spec-recalc (face frame)
"Reset the face attributes of FACE on FRAME according to its specs.
This applies the defface/custom spec first, then the custom theme specs,
then the override spec."
+ (while (get face 'face-alias)
+ (setq face (get face 'face-alias)))
(face-spec-reset-face face frame)
- (let ((face-sym (or (get face 'face-alias) face)))
- (or (get face 'customized-face)
- (get face 'saved-face)
- (face-spec-set-2 face frame (face-default-spec face)))
- (let ((theme-faces (reverse (get face-sym 'theme-face))))
- (dolist (spec theme-faces)
- (face-spec-set-2 face frame (cadr spec))))
- (face-spec-set-2 face frame (get face-sym 'face-override-spec))))
+ ;; If FACE is customized or themed, set the custom spec from
+ ;; `theme-face' records, which completely replace the defface spec
+ ;; rather than inheriting from it.
+ (let ((theme-faces (get face 'theme-face)))
+ (if theme-faces
+ (dolist (spec (reverse theme-faces))
+ (face-spec-set-2 face frame (cadr spec)))
+ (face-spec-set-2 face frame (face-default-spec face))))
+ (face-spec-set-2 face frame (get face 'face-override-spec)))
(defun face-spec-set-2 (face frame spec)
"Set the face attributes of FACE on FRAME according to SPEC."