From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: =?UTF-8?Q?K=C3=A9vin?= Le Gouguec Newsgroups: gmane.emacs.bugs Subject: bug#35476: [PATCH] 27.0.50; font-lock-{append,prepend}-text-property and anonymous faces Date: Sun, 28 Apr 2019 19:11:06 +0200 Message-ID: <87lfzu9hsl.fsf@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="40649"; mail-complaints-to="usenet@blaine.gmane.org" Cc: Stefan Monnier , Nicolas Goaziou To: 35476@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Apr 28 19:12:14 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1hKnLa-000AR5-6C for geb-bug-gnu-emacs@m.gmane.org; Sun, 28 Apr 2019 19:12:14 +0200 Original-Received: from localhost ([127.0.0.1]:46625 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hKnLZ-0000Vv-7f for geb-bug-gnu-emacs@m.gmane.org; Sun, 28 Apr 2019 13:12:13 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:36551) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hKnLQ-0000Vo-SH for bug-gnu-emacs@gnu.org; Sun, 28 Apr 2019 13:12:07 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hKnLO-0007D9-Ns for bug-gnu-emacs@gnu.org; Sun, 28 Apr 2019 13:12:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:52402) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hKnLO-0007Cy-Ir for bug-gnu-emacs@gnu.org; Sun, 28 Apr 2019 13:12:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1hKnLO-0006eZ-AU for bug-gnu-emacs@gnu.org; Sun, 28 Apr 2019 13:12:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: =?UTF-8?Q?K=C3=A9vin?= Le Gouguec Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 28 Apr 2019 17:12:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 35476 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.155647149325534 (code B ref -1); Sun, 28 Apr 2019 17:12:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 28 Apr 2019 17:11:33 +0000 Original-Received: from localhost ([127.0.0.1]:37713 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hKnKt-0006dk-Nd for submit@debbugs.gnu.org; Sun, 28 Apr 2019 13:11:32 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:50288) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1hKnKs-0006dY-9S for submit@debbugs.gnu.org; Sun, 28 Apr 2019 13:11:31 -0400 Original-Received: from lists.gnu.org ([209.51.188.17]:56399) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hKnKj-0006zm-PK for submit@debbugs.gnu.org; Sun, 28 Apr 2019 13:11:23 -0400 Original-Received: from eggs.gnu.org ([209.51.188.92]:36425) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hKnKh-00009F-Ix for bug-gnu-emacs@gnu.org; Sun, 28 Apr 2019 13:11:21 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hKnKd-0006y4-Pt for bug-gnu-emacs@gnu.org; Sun, 28 Apr 2019 13:11:19 -0400 Original-Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:52459) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hKnKb-0006w1-Rl for bug-gnu-emacs@gnu.org; Sun, 28 Apr 2019 13:11:15 -0400 Original-Received: by mail-wm1-x344.google.com with SMTP id j13so10744044wmh.2 for ; Sun, 28 Apr 2019 10:11:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:cc:date:message-id:mime-version; bh=wcC6teh69ge56jScGNhpt8yWafpcB6oiI6oAALOV0Dg=; b=Ou9280v1Ua18CvZ7PcLzqdQckcccQbYrJVSUdUec5LDAgKdW4E9rcOyik69dwtcjwb z4K4b0UMlycswVyvsM9Ro87XEa2u989WRLKqV37DPvIM6Asi2Z235cfGVSS5Ohstavr1 2OE1DztlADbRxr2VWvP53cgwSCQgTQjbMX9vj5YMtuneIv/0N3OFzPJOCOn4D5Zif1Um X+7M+yPRK65GbsPCt8JC0dAE65SmyhOx4XoYkH5DS01oOTU2/suOB0iOm5GppF6GEwwY 9Tk2ml/YnwP6vAMoXmK9SIC4wbksSSOw+6dikiD1ftbq1nRi5uqvxzT/BCig2YlQCtCQ 4ELw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:cc:date:message-id:mime-version; bh=wcC6teh69ge56jScGNhpt8yWafpcB6oiI6oAALOV0Dg=; b=JTgpFWU7VfNzFzORCzJtn4ZzziGTSGOOOTs3bvYjg0rCiLuZMlZ0zfScADbzSCRqAJ xqNSgg7G/3quMhPkn5KIqthUd5LVYjWmB1sGSxWdke8J/W5Ds8VXdtNRcv2fxk4uky36 PuH6nW0f+t238z5GMjTJc7YsEN3WndElDriFASHtb9UMLboTkRoedYCYgvtXMS2NPZAS 7sl9lBg9iFv7M3FgtEPYCFC24id7NeYDKZCWMMVwzvXi8MSwyPJKDKMb/t2doMgovRYD ZkTzlr5aNlbshGgI1X30eKC09Sw7QVueNWpY7Ap1ZOTGE7237lrA8iZ6/F6M0C2Ennsg 2Htg== X-Gm-Message-State: APjAAAWvTPyoe6vxeJOgk3RX5cFzig/kJrpxGVHD3hRq4MjVO+CLKN2i tOdTSyornyPntRQ6ID4fYRg= X-Google-Smtp-Source: APXvYqwsec+QD3d+BgC6XYD9trTdayFsNsqpuWOXaWHgyBlpNnS2LzMeWEQ/G5OgpAMm5Glke/UOfQ== X-Received: by 2002:a1c:1a90:: with SMTP id a138mr8602293wma.81.1556471471381; Sun, 28 Apr 2019 10:11:11 -0700 (PDT) Original-Received: from nc10-laptop ([109.190.253.11]) by smtp.gmail.com with ESMTPSA id x20sm7396198wrg.29.2019.04.28.10.11.09 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sun, 28 Apr 2019 10:11:10 -0700 (PDT) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:158399 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello, This is a follow-up to the mails I sent to emacs-orgmode[1] and help-gnu-emacs[2]. tl;dr I believe font-lock-{append,prepend}-text-property do not handle anonymous faces correctly: they splice their attributes, producing lists mixing keyword attributes and named faces such as this one: (:strike-through t org-level-1) The patch I attach changes this to: ((:strike-through t) org-level-1) To summarize my findings: 1. With org.el from Emacs's master branch (commit 88c91f53df), in an Org buffer with a heading such as this one: * *foo* /bar/ _baz_ +quux+ =20=20 foo (resp. bar and baz) show both the heading face and the bold (resp. italic and underline) decoration, whereas quux only shows the strike-through decoration, without the heading face. 2. C-u C-x =3D on quux says: > face (:strike-through t org-level-1) A hasty look at org.el showed that it used `font-lock-prepend-text-property`. I sent a trivial patch to emacs-orgmode which uses `font-lock-append-text-property` instead, although I wasn't sure that it was sound. With this patch, C-u C-x =3D says instead: =20=20=20 > face (org-level-1 :strike-through t) =E2=80=A6 and quux shows both the org-level-1 foreground and the strike-through decoration. 3. On help-gnu-emacs, Stefan confirmed that my patch relies on undefined behavior. 4. Meanwhile, Nicolas applied it to the org-mode repository (commit 42abf5c69). I have now come to the conclusion that a patch such as the one I attached in this report might be more appropriate. --=-=-= Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=0001-Refrain-from-splicing-anonymous-faces-in-text-proper.patch Content-Transfer-Encoding: quoted-printable >From 7990c65193473784bae6769ae9a2baf233234269 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?K=3DC3=3DA9vin=3D20Le=3D20Gouguec?=3D Date: Sun, 28 Apr 2019 18:48:36 +0200 Subject: [PATCH] Refrain from splicing anonymous faces in text properties MIME-Version: 1.0 Content-Type: text/plain; charset=3DUTF-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) =E2=80=A6 and the org-level-1 foreground was not displayed. This commit ma= kes the 'face property become: ((:strike-through t) org-level-1) =E2=80=A6 which lets quux display both the strike-through decoration and the org-level-1 foreground. * lisp/font-lock.el (font-lock-append-text-property) (font-lock-prepend-text-property): Wrap anonymous faces in a single-elemnt list so that `append' does not splice them. --- lisp/font-lock.el | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 1475911195..e0e55d859d 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 (/=3D 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) @@ -1412,16 +1419,23 @@ font-lock-append-text-property Arguments PROP and VALUE specify the property and value to append to the v= alue 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 (/=3D 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 (if (listp prev) prev (list prev)) val) object) --=20 2.20.1 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable I am not an expert on font-lock though, so this patch might not be correct. Also, since I'm on a laptop running on battery power, I don't intend to run make check right now. I am sharing this patch in case someone well-versed in font-lock finds it "obviously correct". If that is the case, I have two more questions for additional patches: 1. Would it make sense to stuff most of these two functions's code into a third function called e.g. font-lock--add-text-property (start end prop value object append) in order to reduce duplication? 2. I guess some new automated tests would be appreciated? Thank you for your time. K=C3=A9vin [1]: http://lists.gnu.org/archive/html/emacs-orgmode/2019-04/msg00101.html [2]: http://lists.gnu.org/archive/html/help-gnu-emacs/2019-04/msg00240.html In GNU Emacs 27.0.50 (build 1, i686-pc-linux-gnu, GTK+ Version 3.22.11) of 2019-04-18 built on nc10-laptop Repository revision: a18336a8dc754fa1c68e16dd8009466cf409271b Repository branch: master Windowing system distributor 'The X.Org Foundation', version 11.0.11902000 System Description: BunsenLabs GNU/Linux 9.8 (Helium) Recent messages: Saving file /home/peniblec/drafts/font-lock.md... Wrote /home/peniblec/drafts/font-lock.md Saving file /home/peniblec/drafts/font-lock.md... Wrote /home/peniblec/drafts/font-lock.md Mark set Saving file /home/peniblec/drafts/font-lock.md... Wrote /home/peniblec/drafts/font-lock.md next-line: End of buffer [4 times] Mark set [3 times] Undo! Configured using: 'configure --with-xwidgets' Configured features: XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS GSETTINGS GLIB NOTIFY INOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT LIBOTF XFT ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM THREADS XWIDGETS JSON PDUMPER LCMS2 GMP Important settings: value of $LANG: en_US.UTF-8 locale-coding-system: utf-8-unix Major mode: Markdown Minor modes in effect: global-magit-file-mode: t magit-file-mode: t magit-auto-revert-mode: t global-git-commit-mode: t async-bytecomp-package-mode: t shell-dirtrack-mode: t show-paren-mode: t minibuffer-depth-indicate-mode: t icomplete-mode: t global-page-break-lines-mode: t page-break-lines-mode: t electric-pair-mode: t diff-hl-flydiff-mode: t global-diff-hl-mode: t diff-hl-mode: t delete-selection-mode: t tooltip-mode: t global-eldoc-mode: t eldoc-mode: t electric-indent-mode: t mouse-wheel-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t column-number-mode: t line-number-mode: t auto-fill-function: do-auto-fill visual-line-mode: t transient-mark-mode: t Load-path shadows: None found. Features: (shadow emacsbug dired-aux help-fns radix-tree cl-print debug backtrace flyspell ediff-merg ediff-wind ediff-diff ediff-mult ediff-help ediff-init ediff-util ediff vc-mtn vc-hg org-indent org-rmail org-mhe org-irc org-info org-gnus org-docview doc-view jka-compr image-mode org-bibtex bibtex org-bbdb org-w3m org-element avl-tree generator org org-macro org-footnote org-pcomplete org-list org-faces org-entities org-version ob-emacs-lisp ob ob-tangle org-src ob-ref ob-lob ob-table ob-keys ob-exp ob-comint ob-core ob-eval org-compat org-macs org-loaddefs find-func cal-menu calendar cal-loaddefs ispell magit-patch cus-edit whitespace bug-reference diff-hl-dired mailalias smtpmail sendmail nnir markdown-mode rx color thingatpt noutline outline misearch multi-isearch magit-extras executable magit-submodule magit-obsolete magit-blame magit-stash magit-bisect magit-push magit-pull magit-fetch magit-clone magit-remote magit-commit magit-sequence magit-notes magit-worktree magit-tag magit-merge magit-branch magit-reset magit-files magit-refs magit-status magit magit-repos magit-apply magit-wip magit-log which-func imenu magit-diff smerge-mode magit-core magit-autorevert autorevert filenotify magit-margin magit-transient magit-process magit-mode transient git-commit magit-git magit-section magit-utils crm log-edit pcvs-util add-log with-editor async-bytecomp async shell pcomplete server dash sort gnus-cite mail-extr gnus-async gnus-bcklg qp gnus-ml nndraft nnmh nnfolder utf-7 epa-file gnutls network-stream nsm gnus-agent gnus-srvr gnus-score score-mode nnvirtual gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime smime dig mailcap nntp gnus-cache gnus-sum gnus-group gnus-undo gnus-start gnus-cloud nnimap nnmail mail-source utf7 netrc nnoo parse-time gnus-spec gnus-int gnus-range message rmc puny dired dired-loaddefs format-spec rfc822 mml mml-sec epa derived epg mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader gnus-win gnus nnheader gnus-util rmail rmail-loaddefs rfc2047 rfc2045 ietf-drums text-property-search time-date mail-utils mm-util mail-prsvr wid-edit vc-git vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs project delight advice eighters-theme quail cl-extra help-mode rg rg-ibuffer rg-result wgrep-rg wgrep s rg-history rg-header rg-compat ibuf-ext ibuffer ibuffer-loaddefs grep compile comint ansi-color ring edmacro kmacro disp-table paren mb-depth icomplete page-break-lines elec-pair diff-hl-flydiff diff diff-hl vc-dir ewoc vc vc-dispatcher diff-mode easy-mmode delsel cus-start cus-load mule-util tex-site info package easymenu epg-config url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs eieio-loaddefs password-cache json subr-x map url-vars seq byte-opt gv bytecomp byte-compile cconv cl-loaddefs cl-lib tooltip eldoc electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode lisp-mode prog-mode register page menu-bar rfn-eshadow isearch timer select scroll-bar mouse jit-lock font-lock syntax facemenu font-core term/tty-colors frame cl-generic cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite charscript charprop case-table epa-hook jka-cmpr-hook help simple abbrev obarray minibuffer cl-preloaded nadvice loaddefs button faces cus-face macroexp files text-properties overlay sha1 md5 base64 format env code-pages mule custom widget hashtable-print-readable backquote threads dbusbind inotify lcms2 dynamic-setting system-font-setting font-render-setting xwidget-internal move-toolbar gtk x-toolkit x multi-tty make-network-process emacs) Memory information: ((conses 8 340103 79587) (symbols 24 31862 1) (strings 16 105392 12481) (string-bytes 1 3497604) (vectors 8 55552) (vector-slots 4 1313923 80148) (floats 8 495 324) (intervals 28 3532 1391) (buffers 564 52)) --=-=-=--