>From 4155005861d68e2bc6a4bf7ec21d308e090e8e39 Mon Sep 17 00:00:00 2001 From: Matthias Dahl Date: Wed, 2 Apr 2014 15:30:01 +0200 Subject: [PATCH 2/4] lisp/faces.el: Fix empty face handling Commit 57becb6238dd612e3bf56bef1608bba9486dcec8 inadvertently broke the handling of empty face specs. If face-spec-choose returned an empty spec (which is valid to do), this was mishandled as a no match found condition and as such, the defface default spec was applied. The bug is twofold: * face-spec-choose maps two valid states onto a single return value (no match and empty face both return as nil). * face-spec-recalc does not differentiate between both cases appropriately. This patch fixes the former by introducing a new optional parameter to face-spec-choose which, if given, is returned if no match was found. Thus the function is completely backwards compatible. The latter is fixed by adapting face-spec-recalc to make use of this new functionality and thus reliably detect if no match was found and only then apply the defface default spec. Fixes bug #16378. --- lisp/faces.el | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/lisp/faces.el b/lisp/faces.el index 7d04938..8536c08 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -1532,13 +1532,15 @@ If FRAME is nil, the current FRAME is used." match)) -(defun face-spec-choose (spec &optional frame) - "Choose the proper attributes for FRAME, out of SPEC. -If SPEC is nil, return nil." +(defun face-spec-choose (spec &optional frame no-match-retval) + "Return the proper attributes for FRAME, out of SPEC. + +If no match is found or SPEC is nil, nil is returned unless NO-MATCH-RETVAL +is given which would then be returned instead." (unless frame (setq frame (selected-frame))) (let ((tail spec) - result defaults) + result defaults match-found) (while tail (let* ((entry (pop tail)) (display (car entry)) @@ -1558,9 +1560,18 @@ If SPEC is nil, return nil." (setq defaults thisval) ;; Otherwise, if it matches, use it. (when (face-spec-set-match-display display frame) - (setq result thisval) - (setq tail nil))))) - (if defaults (append result defaults) result))) + (setq result thisval + tail nil + match-found t))))) + ;; If defaults have been found, it's safe to just append those to the result + ;; list (which at this point will be either nil or contain actual specs) and + ;; return it to the caller. Since there will most definitely be something to + ;; return in this case, there's no need to know/check if a match was found. + (if defaults + (append result defaults) + (if match-found + result + no-match-retval)))) (defun face-spec-reset-face (face &optional frame) @@ -1655,11 +1666,12 @@ After the reset, the specs are applied from the following sources in this order: ;; If FACE is customized or themed, set the custom spec from ;; `theme-face' records. (let ((theme-faces (get face 'theme-face)) + (no-match-found 0) spec theme-face-applied) (if theme-faces (dolist (elt (reverse theme-faces)) - (setq spec (face-spec-choose (cadr elt) frame)) - (when spec + (setq spec (face-spec-choose (cadr elt) frame no-match-found)) + (unless (eq spec no-match-found) (face-spec-set-2 face frame spec) (setq theme-face-applied t)))) ;; If there was a spec applicable to FRAME, that overrides the -- 1.9.1