diff options
author | Chong Yidong <cyd@gnu.org> | 2012-11-25 12:50:20 +0800 |
---|---|---|
committer | Chong Yidong <cyd@gnu.org> | 2012-11-25 12:50:20 +0800 |
commit | 1c4f115d4c4eb1aa71c25d21e8bdec2f8da97700 (patch) | |
tree | 8fb4e906b3cc5455ab45383267eac3c49da5ef44 /lisp/faces.el | |
parent | 61d841dd15f1f9921e23d93e8a0c282fe568aed1 (diff) | |
download | emacs-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.el | 99 |
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." |