Subject: bug#42184: 27.0.91; org-fontify-whole-heading-line does not work in emacs 27

From: Kévin Le Gouguec <[email-masked]>
Date: Thu, 06 Aug 2020 11:32:18 +0200

Kyle Meyer <[email-masked]> writes:

> Kévin Le Gouguec writes:
>
>> Here is a variant of the previous patch, which correctly resets :extend
>> to nil if the user disables the relevant options (after reverting the
>> current buffer, or for newly opened ones).
>>
>> This ends up looking similar to what Org does for org-hide; IMO this
>> seems like the most straightforward short-term fix.  In the long run,
>> these user options would probably deserve :set functions.
>
> Thanks for working on this fix.  I of course can't speak for Bastien or
> Nicolas, but this patch looks fine to me.  Assuming it's okay with Eli,
> I'd suggest applying it to the emacs-27 branch.  (Once applied, I'd port
> it to the Org repo, as I do with other changes in the Emacs repo that
> touch Org files.)

Thank you for the review.  I hope this can make it into 27.1 since this
bug seems to be getting some attention[1][2], but the (tentative?)
etc/HISTORY file on the emacs-27 branch makes me wonder if we aren't too
close to the release day…

> Upstream in the thread you wrote:
>
>> Relatedly (but not crucial to solving this bug), should org-block and
>> org-block-background also have :extend t?  It would make sense to me
>> since they delimit visual "blocks".
>
> That would make sense to me as well.

OK, here's a patch to do that for org-block:

>From e489b09d27a36fdf0366a2fecba31eda475bc14d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= <[email-masked]>
Date: Thu, 6 Aug 2020 10:59:38 +0200
Subject: [PATCH] * lisp/org/org-faces.el (org-block): Set face extension
 beyond EOL

---
 lisp/org/org-faces.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lisp/org/org-faces.el b/lisp/org/org-faces.el
index 30eab9bc6b..eba5a484ac 100644
--- a/lisp/org/org-faces.el
+++ b/lisp/org/org-faces.el
@@ -393,7 +393,7 @@ org-document-info-keyword
   "Face for #+TITLE:, #+AUTHOR:, #+EMAIL: and #+DATE: keywords."
   :group 'org-faces)
 
-(defface org-block '((t :inherit shadow))
+(defface org-block '((t (:extend t :inherit shadow)))
   "Face text in #+begin ... #+end blocks.
 For source-blocks `org-src-block-faces' takes precedence."
   :group 'org-faces
-- 
2.28.0

>                                       (org-block-background hasn't
> existed since v8.3, though.)

Huh!  I guess that calls for a further patch:

>From 9b303ca5b717f5ed1ef48cb3a7d40693ec2dc8e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= <[email-masked]>
Date: Thu, 6 Aug 2020 10:45:39 +0200
Subject: [PATCH] * etc/themes/leuven-theme.el (class): Remove obsolete face

---
 etc/themes/leuven-theme.el | 1 -
 1 file changed, 1 deletion(-)

diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el
index 4d8568b7d8..4d8cf0f869 100644
--- a/etc/themes/leuven-theme.el
+++ b/etc/themes/leuven-theme.el
@@ -515,7 +515,6 @@ leuven
    `(org-archived ((,class (:foreground "gray70"))))
    `(org-beamer-tag ((,class (:box (:line-width 1 :color "#FABC18") :foreground "#2C2C2C" :background "#FFF8D0"))))
    `(org-block ((,class ,code-block)))
-   `(org-block-background ((,class (:background "#FFFFE0"))))
    `(org-block-begin-line ((,class (:underline "#A7A6AA" :foreground "#555555" :background "#E2E1D5"))))
    `(org-block-end-line ((,class (:overline "#A7A6AA" :foreground "#555555" :background "#E2E1D5"))))
    `(org-checkbox ((,class (:weight bold :box (:line-width 1 :style pressed-button) :foreground "white" :background "#777777"))))
-- 
2.28.0

(AFAICT this was the only reference to org-block-background in all Elisp
files.)

All three patches squashed together:

>From 4328455c2d99ae118fa36401ea89d0e7cbb8c815 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= <[email-masked]>
Date: Thu, 9 Jul 2020 16:02:49 +0200
Subject: [PATCH] Fix org-fontify-whole-*-line by setting face extension
 (bug#42184)

* lisp/org/org-compat.el (org--set-faces-extend): New function to set
face extension, for Emacs versions where this attribute exists.
* lisp/org/org.el (org-mode): Call it to set the extend attribute of
relevant faces to the correct value.

* lisp/org/org-faces.el (org-block): Set face extension beyond EOL.
* etc/themes/leuven-theme.el (class): Remove obsolete face.
---
 etc/themes/leuven-theme.el | 1 -
 lisp/org/org-compat.el     | 4 ++++
 lisp/org/org-faces.el      | 2 +-
 lisp/org/org.el            | 6 +++++-
 4 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el
index 4d8568b7d8..4d8cf0f869 100644
--- a/etc/themes/leuven-theme.el
+++ b/etc/themes/leuven-theme.el
@@ -515,7 +515,6 @@ leuven
    `(org-archived ((,class (:foreground "gray70"))))
    `(org-beamer-tag ((,class (:box (:line-width 1 :color "#FABC18") :foreground "#2C2C2C" :background "#FFF8D0"))))
    `(org-block ((,class ,code-block)))
-   `(org-block-background ((,class (:background "#FFFFE0"))))
    `(org-block-begin-line ((,class (:underline "#A7A6AA" :foreground "#555555" :background "#E2E1D5"))))
    `(org-block-end-line ((,class (:overline "#A7A6AA" :foreground "#555555" :background "#E2E1D5"))))
    `(org-checkbox ((,class (:weight bold :box (:line-width 1 :style pressed-button) :foreground "white" :background "#777777"))))
diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el
index c1aaf17ca2..fcc325e475 100644
--- a/lisp/org/org-compat.el
+++ b/lisp/org/org-compat.el
@@ -101,6 +101,10 @@ org-table1-hline-regexp
   (defun org-time-convert-to-list (time)
     (seconds-to-time (float-time time))))
 
+(defun org--set-faces-extend (faces extend-p)
+  (when (fboundp 'set-face-extend)
+    (mapc (lambda (f) (set-face-extend f extend-p)) faces)))
+
 
 ;;; Emacs < 26.1 compatibility
 
diff --git a/lisp/org/org-faces.el b/lisp/org/org-faces.el
index 30eab9bc6b..eba5a484ac 100644
--- a/lisp/org/org-faces.el
+++ b/lisp/org/org-faces.el
@@ -393,7 +393,7 @@ org-document-info-keyword
   "Face for #+TITLE:, #+AUTHOR:, #+EMAIL: and #+DATE: keywords."
   :group 'org-faces)
 
-(defface org-block '((t :inherit shadow))
+(defface org-block '((t (:extend t :inherit shadow)))
   "Face text in #+begin ... #+end blocks.
 For source-blocks `org-src-block-faces' takes precedence."
   :group 'org-faces
diff --git a/lisp/org/org.el b/lisp/org/org.el
index 568f5b9b87..fb31336ea4 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -4944,7 +4944,11 @@ org-mode
   ;; Try to set `org-hide' face correctly.
   (let ((foreground (org-find-invisible-foreground)))
     (when foreground
-      (set-face-foreground 'org-hide foreground))))
+      (set-face-foreground 'org-hide foreground)))
+  ;; Set face extension as requested.
+  (org--set-faces-extend '(org-block-begin-line org-block-end-line)
+                         org-fontify-whole-block-delimiter-line)
+  (org--set-faces-extend org-level-faces org-fontify-whole-heading-line))
 
 ;; Update `customize-package-emacs-version-alist'
 (add-to-list 'customize-package-emacs-version-alist
-- 
2.28.0

[1] https://orgmode.org/list/[email-masked]/t/#mac68a8ca95f64cb3fe7161bb44454253aad39fd6
[2] https://old.reddit.com/r/emacs/comments/i26n46/why_does_my_orgmode_look_different_to_leuven/