help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Mixing named and anonymous faces in text properties


From: Kévin Le Gouguec
Subject: Re: Mixing named and anonymous faces in text properties
Date: Fri, 26 Apr 2019 19:21:47 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

(Replying to my own mail since I haven't received Stefan's answer, maybe
because I'm not subscribed to the list)

> > - M-: (add-text-properties 1 3 '(face '(italic :weight bold))) RET
> This is wrong.  It should be
> 
>     (add-text-properties 1 3 '(face '(italic (:weight bold))))
> 
> I.e. a face property ca hold either a "face" or a list of "face"s,
> where "face" can be either a symbol or a plist of face attributes.
> So you can set the `face` property to
> 
>     italic
>     
>     (:weight bold)
> 
>     (italic (:weight bold))
>     
>     ((:weight bold) italic)
> 
>     (italic)
>     
>     ...
>     
> but if the value you used above did what you intended, it's just
> a lucky accident.

Yes, I eventually did figure out that this only works incidentally.  The
only reason I tested this specific invokation is because the problematic
text in Org buffers had

    (:strike-through t org-level-1)

So I replaced the call to font-lock-prepend-text-property with
font-lock-append-text-property as a silly workaround.

I since took a look at font-lock-prepend-text-property and cooked up the
attached patch; if it is correct, I guess font-lock-append-text-property
could use something similar.

>From 7ddfe61225eaa2409589e61cc3333484fe000492 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= <kevin.legouguec@gmail.com>
Date: Fri, 26 Apr 2019 18:50:48 +0200
Subject: [PATCH] Refrain from splicing anonymous faces in text properties
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Otherwise named faces that follow are not displayed anymore.  E.g. in
an Org buffer with this content:

    * /foo/ *bar* _baz_ +quux+

Before this commit, the 'face property on quux was:

    (:strike-through t org-level-1)

… and the org-level-1 foreground was not displayed.  This commit makes
the 'face property become:

    ((:strike-through t) org-level-1)

… which lets quux display both the strike-through decoration and the
org-level-1 foreground.

* lisp/font-lock.el (font-lock-prepend-text-property):
Wrap anonymous faces in a single-elemnt list so that `append' does not
splice them.
---
 lisp/font-lock.el | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index 1475911195..23135e6445 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -1392,16 +1392,23 @@ font-lock-prepend-text-property
 Arguments PROP and VALUE specify the property and value to prepend to the value
 already in place.  The resulting property values are always lists.
 Optional argument OBJECT is the string or buffer containing the text."
-  (let ((val (if (listp value) value (list value))) next prev)
+  (let ((val (if (listp value) value (list value)))
+        (is-face-prop (memq prop '(face font-lock-face)))
+        next prev)
     (while (/= start end)
       (setq next (next-single-property-change start prop object end)
            prev (get-text-property start prop object))
       ;; Canonicalize old forms of face property.
-      (and (memq prop '(face font-lock-face))
+      (and is-face-prop
           (listp prev)
           (or (keywordp (car prev))
               (memq (car prev) '(foreground-color background-color)))
           (setq prev (list prev)))
+      ;; Wrap an anonymous face into a single-element list, so that
+      ;; `append' does not splice it.
+      (and is-face-prop
+           (keywordp (car val))
+           (setq val (list val)))
       (put-text-property start next prop
                         (append val (if (listp prev) prev (list prev)))
                         object)
-- 
2.20.1

(I was about to send this patch with report-emacs-bug when I saw your
reply; should I go ahead with this report?)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]