bug#81534: [PATCH] elisp-scope: Improve support for :inherit face specs
zach shaftel via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <[email protected]> Sun, 02 Aug 2026 20:03:09 -0400
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <[email protected]> |
--=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Eshel Yaron <[email protected]> writes: > Hi, > > zach shaftel <[email protected]> writes: > >> Tags: patch >> >> This patches elisp-scope--match-spec-to-arg to recursively process >> :inherit face specs, so now even complicated face specs like >> (:inherit (:inherit (bold (:inherit underline)))) are correctly parsed. > > Sounds good, although in (info "(elisp) Face Attributes") I see: > > =E2=80=98:inherit=E2=80=99 > The name of a face from which to inherit attributes, or a list of > face names. [...] > > This says that the value of :inherit is always expressed in face names, > not as a list of face attributes. And I couldn't find an example of > such a nested attributes list. Moreover, evaluating the following form > indeed yields an "Invalid face inheritance" error: > > (defface f '((t :inherit (bold (:inherit success)))) "") > > So I think we should support a list of face names like (bold success), > but not nested attribute lists. Makes sense? Ah I didn't realize that, makes sense. I had tested my example spec as a face text property and it does render correctly, but I don't think any sane person would (or should) write that. This patch changes all :inherit specs to (or (symbol . face) (repeat . (symbol . face))). > >> I noticed this after defface forms inheriting from a list of faces >> weren't being fontified the same as with a single inherited face name. >> I changed a couple uses of (symbol . face) output specs to just `face' >> so they utilize this. > > Nice. Could you please also add a test or two? > See test/lisp/progmodes/elisp-mode-resources/semantic-highlighting.el Added in this patch. > > > Best regards, > > Eshel --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-elisp-scope-Improve-support-for-inherit-face-specs.patch From 048ce64a75dacfc2b255612519c5f373e2f5400c Mon Sep 17 00:00:00 2001 From: Zach Shaftel <[email protected]> Date: Sat, 1 Aug 2026 21:33:40 -0400 Subject: [PATCH] elisp-scope: Improve support for :inherit face specs * lisp/emacs-lisp/elisp-scope.el (elisp-scope--match-spec-to-arg): Update to support lists of faces in :inherit. Update analyzers for a few functions to use it. * test/lisp/progmodes/elisp-mode-resources/semantic-highlighting.el: Extra testing for lists of faces. --- lisp/emacs-lisp/elisp-scope.el | 11 +++++++---- .../semantic-highlighting.el | 18 +++++++++++++++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lisp/emacs-lisp/elisp-scope.el b/lisp/emacs-lisp/elisp-scope.el index a81a7dfacaf..cee483043d0 100644 --- a/lisp/emacs-lisp/elisp-scope.el +++ b/lisp/emacs-lisp/elisp-scope.el @@ -1818,7 +1818,8 @@ custom-declare-group (elisp-scope-define-function-analyzer custom-declare-face (face spec doc &rest args) (elisp-scope-1 face '(symbol . defface)) - (elisp-scope-1 spec '(repeat . (cons t . (plist (:inherit . (symbol . face)))))) + (elisp-scope-1 spec '(repeat . (cons t . (plist (:inherit . (or (symbol . face) + (repeat . (symbol . face)))))))) (elisp-scope-1 doc) (while-let ((kw (car-safe args)) (bkw (elisp-scope--sym-bare kw)) @@ -1831,7 +1832,7 @@ custom-declare-face (elisp-scope-define-function-spec cl-typep (nil cl-type)) (elisp-scope-define-function-spec pulse-momentary-highlight-region - (nil nil (symbol . face))) + (nil nil face)) (elisp-scope--define-function-analyzer throw (&optional tag val) non-local-exit (elisp-scope-1 tag '(symbol . throw-tag)) @@ -2495,10 +2496,12 @@ elisp-scope--match-spec-to-arg (if (consp arg) (if (keywordp (elisp-scope--sym-bare (car arg))) ;; One face, given as a plist of face attributes. - '(plist (:inherit . (symbol . face))) + '(plist (:inherit . (or (symbol . face) + (repeat . (symbol . face))))) ;; Multiple faces. '(repeat . (or (symbol . face) - (plist (:inherit . (symbol . face)))))) + (plist (:inherit . (or (symbol . face) + (repeat . (symbol . face)))))))) '(symbol . face)) arg)) diff --git a/test/lisp/progmodes/elisp-mode-resources/semantic-highlighting.el b/test/lisp/progmodes/elisp-mode-resources/semantic-highlighting.el index 307ca49cc85..43aefb050a7 100644 --- a/test/lisp/progmodes/elisp-mode-resources/semantic-highlighting.el +++ b/test/lisp/progmodes/elisp-mode-resources/semantic-highlighting.el @@ -15,6 +15,16 @@ foo ;; ^ elisp-bound-variable ) +(pulse-momentary-highlight-region (point) (point-max) +;; ^ elisp-function +;; ^ elisp-function +;; ^ elisp-function + (or (and t '(bold success)) +;; ^ elisp-face +;; ^ elisp-face + 'warning)) +;; ^ elisp-face + (add-face-text-property ;; ^ elisp-function (point) (mark) @@ -163,10 +173,12 @@ baz-opt ;; ^ elisp-function (defface foobar - '((default :inherit font-lock-function-call-face) + '((default :inherit (font-lock-function-call-face error)) ;; ^ (elisp-constant font-lock-builtin-face) -;; ^ elisp-face - (((background light)) :foreground "#00008b") +;; ^ elisp-face +;; ^ elisp-face + (((background light)) :foreground "#00008b" :inherit bold) +;; ^ elisp-face (((background dark)) :foreground "#5c9cff")) "Face for highlighting symbol role names in Emacs Lisp code." :version "31.1") -- 2.55.0 --=-=-=--