Subject: Re: bug#41852: 27.0.50; text-scale commands don't scale header of tabulated-list-mode

From: Stefan Kangas <[email-masked]>
Date: Mon, 19 Oct 2020 18:21:06 +0000

Eli Zaretskii <[email-masked]> writes:

> It's probably a good feature, but it has at least one caveat: setting
> that variable non-nil will cause not only the header-line face to be
> rescaled, it will also cause any face that inherits from header-line
> to be rescaled.  Not sure if this is a problem, but it should be
> called out in NEWS, at least.
[...]
> This should mention modes that arrange their display in tabular form
> below the header-line, such as tabulated-list-mode and its
> descendants.  Otherwise the last sentence and the goal of the feature
> itself are left on a level that's too abstract.

I've made an attempt to improve this in the attached.

>> -(make-variable-buffer-local 'text-scale-mode-remapping)
>> +(make-obsolete-variable 'text-scale-mode-remapping "no longer used." "28.1")
>> +
>> +(defvar text-scale-mode--remappings nil
>> +  "List of current remapping cookies for `text-scale-mode'.")
>
> Why this change?

This is to give the variable the correct plural form, and to mark it
internal by giving it the double dash.

>> +(defvar text-scale-mode-header-line nil
>
> I suggest to name this text-scale-remap-header-line-face.

Done.

>> +  "If non-nil, also change text height of the header line.")
>
> Not just height, the size.  Also, please say "`header-line' face", and
> mention that all the faces that inherit from it will be affected as
> well.

Done.

>> +(defun face-remap--remap-face (sym)
>> +  (push (face-remap-add-relative sym
>> +                       :height
>> +                       (expt text-scale-mode-step
>> +                             text-scale-mode-amount))
>> +        text-scale-mode--remappings))
>
> I wonder whether this is all there is to it.  The display code doesn't
> automatically use the remapped face in all cases, we need to code that
> "by hand" in each and every case.  So far we've been doing that only
> for the default face; I wonder if we'll have to do something similar
> for header-line on the C level...  Please be sure to test this in
> every possible way, including cursor motion around such rescaled
> header-lines etc.

I've done my best to test it some more, including cursor motion around
the adjusted header line, as well as scrolling the window left and right
and up and down (using mouse and keyboard).  I've not been able to
produce any failures so far.  Please let me know if you have any more
ideas for what I could do to try to break it.
From 04f2037907b8e9335750eafbcaa587e33a92af0c Mon Sep 17 00:00:00 2001
From: Stefan Kangas <[email-masked]>
Date: Mon, 19 Oct 2020 01:03:53 +0200
Subject: [PATCH 1/2] Make text-scale-mode optionally adjust header line face

* lisp/face-remap.el (text-scale-remap-header-line-face): New buffer
local variable.
(text-scale-mode): Also adjust header-line face if above new
variable is non-nil.
(face-remap--clear-remappings, face-remap--remap-face): New
functions.
(text-scale-mode--remappings): New variable.
(text-scale-mode-remapping): Make obsolete.
---
 etc/NEWS           | 15 +++++++++++++++
 lisp/face-remap.el | 42 ++++++++++++++++++++++++++++++++----------
 2 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 390cccbff3..b80bcf397c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1314,6 +1314,21 @@ to 'tab-bar-new-tab-choice' for new tabs to show the bookmark list.
 'gomoku-move-sw' and 'gomoku-move-ne' now work correctly, and
 horizontal movements now stop at the edge of the board.
 
+** text-scale-mode
+
+---
+*** text-scale-mode can now adjust font size of the 'header-line' face.
+When the new buffer local variable 'text-scale-mode-header-line' is
+non-nil, 'text-scale-adjust' (bound to 'C-x C-+' and 'C-x C--' by
+default) will also change the text height of the 'header-line' face.
+This will also affect any face that inherits from it.
+
+This feature is intended for use by Emacs Lisp package authors in
+major modes that arrange their display in tabular form below the
+header-line.  It is enabled in 'tabulated-list-mode' and its derived
+modes (such as the modes used by 'list-packages', 'list-buffers' and
+'bookmark-bmenu-list').
+
 ** xwidget-webkit mode
 
 *** New xwidget commands.
diff --git a/lisp/face-remap.el b/lisp/face-remap.el
index 028269a4b0..4d7be7d65a 100644
--- a/lisp/face-remap.el
+++ b/lisp/face-remap.el
@@ -219,7 +219,10 @@ text-scale-mode-step
 
 ;; current remapping cookie for text-scale-mode
 (defvar text-scale-mode-remapping nil)
-(make-variable-buffer-local 'text-scale-mode-remapping)
+(make-obsolete-variable 'text-scale-mode-remapping "no longer used." "28.1")
+
+(defvar text-scale-mode--remappings nil
+  "List of current remapping cookies for `text-scale-mode'.")
 
 ;; Lighter displayed for text-scale-mode in mode-line minor-mode list
 (defvar text-scale-mode-lighter "+0")
@@ -229,6 +232,24 @@ text-scale-mode-lighter
 (defvar text-scale-mode-amount 0)
 (make-variable-buffer-local 'text-scale-mode-amount)
 
+(defvar text-scale-remap-header-line-face nil
+  "If non-nil, also change font size of the `header-line' face.
+This will also affect any face that inherits from
+`header-line'.")
+(make-variable-buffer-local 'text-scale-header-line)
+
+(defun face-remap--clear-remappings ()
+  (dolist (remapping text-scale-mode--remappings)
+    (face-remap-remove-relative remapping))
+  (setq text-scale-mode--remappings nil))
+
+(defun face-remap--remap-face (sym)
+  (push (face-remap-add-relative sym
+                       :height
+                       (expt text-scale-mode-step
+                             text-scale-mode-amount))
+        text-scale-mode--remappings))
+
 (define-minor-mode text-scale-mode
   "Minor mode for displaying buffer text in a larger/smaller font.
 
@@ -240,19 +261,20 @@ text-scale-mode
 The `text-scale-increase', `text-scale-decrease', and
 `text-scale-set' functions may be used to interactively modify
 the variable `text-scale-mode-amount' (they also enable or
-disable `text-scale-mode' as necessary)."
+disable `text-scale-mode' as necessary).
+
+If `text-scale-remap-header-line-face' is non-nil, also change
+the font size of the `header-line' face (and any face that
+inherits from it)."
   :lighter (" " text-scale-mode-lighter)
-  (when text-scale-mode-remapping
-    (face-remap-remove-relative text-scale-mode-remapping))
+  (face-remap--clear-remappings)
   (setq text-scale-mode-lighter
 	(format (if (>= text-scale-mode-amount 0) "+%d" "%d")
 		text-scale-mode-amount))
-  (setq text-scale-mode-remapping
-	(and text-scale-mode
-	     (face-remap-add-relative 'default
-					  :height
-					  (expt text-scale-mode-step
-						text-scale-mode-amount))))
+  (when text-scale-mode
+    (face-remap--remap-face 'default)
+    (when text-scale-remap-header-line-face
+      (face-remap--remap-face 'header-line)))
   (force-window-update (current-buffer)))
 
 (defun text-scale-min-amount ()
-- 
2.28.0

From deb68fa05b1f7f78168f3516804427cb952d221c Mon Sep 17 00:00:00 2001
From: Stefan Kangas <[email-masked]>
Date: Mon, 19 Oct 2020 01:05:43 +0200
Subject: [PATCH 2/2] Set text-scale-mode-header-line in tabulated-list-mode

* lisp/emacs-lisp/tabulated-list.el (tabulated-list-mode): Set
text-scale-mode-header-line to a non-nil value.  (Bug#41852)
---
 lisp/emacs-lisp/tabulated-list.el | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el
index b13f609f88..2f7899ec51 100644
--- a/lisp/emacs-lisp/tabulated-list.el
+++ b/lisp/emacs-lisp/tabulated-list.el
@@ -761,6 +761,7 @@ tabulated-list-mode
   (setq-local revert-buffer-function #'tabulated-list-revert)
   (setq-local glyphless-char-display
               (tabulated-list-make-glyphless-char-display-table))
+  (setq-local text-scale-mode-header-line t)
   ;; Avoid messing up the entries' display just because the first
   ;; column of the first entry happens to begin with a R2L letter.
   (setq bidi-paragraph-direction 'left-to-right)
-- 
2.28.0