GNU bug report logs - #64533
[PATCH] Support displaying function name in the header line

Previous Next

Package: emacs;

Reported by: Spencer Baugh <sbaugh <at> janestreet.com>

Date: Sat, 8 Jul 2023 17:57:01 UTC

Severity: normal

Tags: patch

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 64533 in the body.
You can then email your comments to 64533 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sat, 08 Jul 2023 17:57:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Spencer Baugh <sbaugh <at> janestreet.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sat, 08 Jul 2023 17:57:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: bug-gnu-emacs <at> gnu.org
Subject: [PATCH] Support displaying function name in the header line
Date: Sat, 08 Jul 2023 13:56:23 -0400
[Message part 1 (text/plain, inline)]
Tags: patch


In some languages, the function name as displayed in the mode-line by
which-func-mode can be quite long.  It's useful to be able to display
it in the header-line instead.  Let's support that.

This was my original motivation for Bug#63825, so that the header line
was not displayed when which-func-mode wasn't enabled, but just teaching
which-function-mode to handle this is much easier.

* lisp/progmodes/which-func.el (which-func-use-header-line)
(which-func-use-mode-line): Add.
(which-func-try-to-enable): Support which-func-use-header-line.
(which-func--disable): Add, to support which-func-use-header-line.
(which-func-ff-hook, which-func-update-1): Use which-func--disable.

In GNU Emacs 29.0.92 (build 3, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.15.12, Xaw scroll bars) of 2023-07-05 built on
 igm-qws-u22796a
Repository revision: 4127aa427fc7e2cb5b3dbae9264c2ee628474db4
Repository branch: emacs-29
Windowing system distributor 'The X.Org Foundation', version 11.0.12011000
System Description: CentOS Linux 7 (Core)

Configured using:
 'configure --config-cache --with-x-toolkit=lucid
 --with-gif=ifavailable'

[0001-Support-displaying-function-name-in-the-header-line.patch (text/patch, attachment)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sat, 08 Jul 2023 18:05:01 GMT) Full text and rfc822 format available.

Message #8 received at 64533 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: 64533 <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the header
 line
Date: Sat, 08 Jul 2023 21:04:30 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Date: Sat, 08 Jul 2023 13:56:23 -0400
> 
> +(defcustom which-func-use-header-line nil
> +  "If non-nil, display the function name in the header line."
> +  :type '(choice (const :tag "Display in header line" t)
> +                 (const :tag "Don't display in header line" nil)))
> +
> +(defcustom which-func-use-mode-line t
> +  "If non-nil, display the function name in the mode line."
> +  :type '(choice (const :tag "Display in mode line" t)
> +                 (const :tag "Don't display in mode line" nil)))

Defcustom's should have a :version tag.

And why 2 separate defcustom's instead of just one?  It looks
un-economical, and also allows for situations in which the behavior is
unclear without examining the code.

Also, I think this needs a NEWS entry, and the user manual should be
amended to account for the new optional display.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sat, 08 Jul 2023 18:15:02 GMT) Full text and rfc822 format available.

Message #11 received at 64533 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 64533 <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the header
 line
Date: Sat, 8 Jul 2023 14:14:30 -0400
[Message part 1 (text/plain, inline)]
On Sat, Jul 8, 2023, 14:04 Eli Zaretskii <eliz <at> gnu.org> wrote:

> > From: Spencer Baugh <sbaugh <at> janestreet.com>
> > Date: Sat, 08 Jul 2023 13:56:23 -0400
> >
> > +(defcustom which-func-use-header-line nil
> > +  "If non-nil, display the function name in the header line."
> > +  :type '(choice (const :tag "Display in header line" t)
> > +                 (const :tag "Don't display in header line" nil)))
> > +
> > +(defcustom which-func-use-mode-line t
> > +  "If non-nil, display the function name in the mode line."
> > +  :type '(choice (const :tag "Display in mode line" t)
> > +                 (const :tag "Don't display in mode line" nil)))
>
> Defcustom's should have a :version tag.
>

Will do.

And why 2 separate defcustom's instead of just one?  It looks
> un-economical, and also allows for situations in which the behavior is
> unclear without examining the code.
>

If I had, say, a single defcustom with possible values 'header 'mode and
'both, I would need to add an :eval to mode-line-format to decide whether
to include the function name. I assumed that was undesirable.

Although I could make these current defcustoms into internal variables and
just set them based on a single defcustom, would that be good?

Also, I think this needs a NEWS entry, and the user manual should be
> amended to account for the new optional display.
>

Will do.


> Thanks.
>
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sat, 08 Jul 2023 18:34:01 GMT) Full text and rfc822 format available.

Message #14 received at 64533 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: 64533 <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the header
 line
Date: Sat, 08 Jul 2023 21:33:42 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Date: Sat, 8 Jul 2023 14:14:30 -0400
> Cc: 64533 <at> debbugs.gnu.org
> 
> Although I could make these current defcustoms into internal variables and just set them based on a
> single defcustom, would that be good?

Yes, why not?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sat, 08 Jul 2023 19:27:02 GMT) Full text and rfc822 format available.

Message #17 received at 64533 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 64533 <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the
 header line
Date: Sat, 08 Jul 2023 15:26:23 -0400
[Message part 1 (text/plain, inline)]
Eli Zaretskii <eliz <at> gnu.org> writes:
>> From: Spencer Baugh <sbaugh <at> janestreet.com>
>> Date: Sat, 8 Jul 2023 14:14:30 -0400
>> Cc: 64533 <at> debbugs.gnu.org
>> 
>> Although I could make these current defcustoms into internal variables and just set them based on a
>> single defcustom, would that be good?
>
> Yes, why not?

Fixed, along with your previous comments.

[0001-Support-displaying-function-name-in-the-header-line.patch (text/x-patch, inline)]
From 3086671e447a188b2cdceda779b447d095b3b118 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> janestreet.com>
Date: Sat, 8 Jul 2023 13:54:01 -0400
Subject: [PATCH] Support displaying function name in the header line

In some languages, the function name as displayed in the mode-line by
which-func-mode can be quite long.  It's useful to be able to display
it in the header-line instead.  Let's support that.

* lisp/progmodes/which-func.el (which-func-display)
(which-func--use-header-line, which-func--use-mode-line): Add.
(which-func-try-to-enable): Support which-func--use-header-line.
(which-func--disable): Add, to support which-func--use-header-line.
(which-func-ff-hook, which-func-update-1): Use which-func--disable.
---
 doc/emacs/programs.texi      | 10 +++++++--
 etc/NEWS                     |  9 +++++++++
 lisp/progmodes/which-func.el | 39 ++++++++++++++++++++++++++++++------
 3 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 953de2e4786..c01503ab9f0 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -396,8 +396,8 @@ Which Function
 @cindex current function name in mode line
 
   Which Function mode is a global minor mode (@pxref{Minor Modes})
-which displays the current function name in the mode line, updating it
-as you move around in a buffer.
+which displays the current function name in the mode line or header
+line, updating it as you move around in a buffer.
 
 @findex which-function-mode
 @vindex which-func-modes
@@ -410,6 +410,12 @@ Which Function
 @code{t} (which means to support all available major modes) to a list
 of major mode names.
 
+@vindex which-func-display
+  By default, Which Function mode displays the current function name
+using the mode line.  Customize @code{which-func-display} to
+@code{header}, @code{mode}, or @code{both} to use the header line,
+mode line, or both, respectively.
+
 @node Program Indent
 @section Indentation for Programs
 @cindex indentation for programs
diff --git a/etc/NEWS b/etc/NEWS
index 0556e8be585..9f100d93281 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -243,6 +243,15 @@ docstring, or a comment, or (re)indents the surrounding defun if
 point is not in a comment or a string.  It is by default bound to
 'M-q' in 'prog-mode' and all its descendants.
 
+** Which Function Mode
+
++++
+*** Displaying the function name in the header line is now supported.
+The new user option 'which-func-display' allows choosing where the
+function name is displayed.  The default is 'mode' to display in the
+mode line.  'header' will display in the header line.  'both' displays
+in both the header line and mode line.
+
 ** Tramp
 
 +++
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el
index 09937a60988..0152670bc98 100644
--- a/lisp/progmodes/which-func.el
+++ b/lisp/progmodes/which-func.el
@@ -86,6 +86,16 @@ which-func-non-auto-modes
 activation of Which Function until Imenu is used for the first time."
   :type '(repeat (symbol :tag "Major mode")))
 
+(defcustom which-func-display 'mode
+  "Where to display the function name.
+
+If 'mode, display in the mode line.  If 'header, display in the
+header line.  If 'both, display in both."
+  :type '(choice (const :tag "Display in mode line" mode)
+                 (const :tag "Display in header line" header)
+                 (const :tag "Display in both header and mode line" both))
+  :version "30.1")
+
 (defcustom which-func-maxout 500000
   "Don't automatically compute the Imenu menu if buffer is this big or bigger.
 Zero means compute the Imenu menu regardless of size.
@@ -184,17 +194,33 @@ which-func-current
 ;;;###autoload (put 'which-func-current 'risky-local-variable t)
 
 (defvar-local which-func-mode nil
-  "Non-nil means display current function name in mode line.
+  "Non-nil means display current function name in mode or header line.
 This makes a difference only if variable `which-function-mode' is
 non-nil.")
 
+(defvar-local which-func--use-header-line nil
+  "If non-nil, display the function name in the header line.")
+
+(defvar-local which-func--use-mode-line nil
+  "If non-nil, display the function name in the mode line.")
+
 (add-hook 'after-change-major-mode-hook #'which-func-ff-hook t)
 
 (defun which-func-try-to-enable ()
   (unless (or (not which-function-mode)
               (local-variable-p 'which-func-mode))
     (setq which-func-mode (or (eq which-func-modes t)
-                              (member major-mode which-func-modes)))))
+                              (member major-mode which-func-modes)))
+    (setq which-func--use-mode-line (member which-func-display '(mode both)))
+    (setq which-func--use-header-line (member which-func-display '(header both)))
+    (when (and which-func-mode which-func--use-header-line)
+      (add-to-list 'header-line-format '("" which-func-format " ")))))
+
+(defun which-func--disable ()
+  (when (and which-func-mode which-func--use-header-line)
+    (setq header-line-format
+          (delete '("" which-func-format " ") header-line-format)))
+  (setq which-func-mode nil))
 
 (defun which-func-ff-hook ()
   "`after-change-major-mode-hook' for Which Function mode.
@@ -210,10 +236,10 @@ which-func-ff-hook
 	  (setq imenu--index-alist
                 (save-excursion (funcall imenu-create-index-function))))
     (imenu-unavailable
-     (setq which-func-mode nil))
+     (which-func--disable))
     (error
      (message "which-func-ff-hook error: %S" err)
-     (setq which-func-mode nil))))
+     (which-func--disable))))
 
 (defun which-func-update ()
   "Update the Which-Function mode display in the current window."
@@ -231,7 +257,7 @@ which-func-update-1
 	      (puthash window current which-func-table)
 	      (force-mode-line-update)))
 	(error
-	 (setq which-func-mode nil)
+	 (which-func--disable)
 	 (error "Error in which-func-update: %S" info))))))
 
 (defvar which-func-update-timer nil)
@@ -241,7 +267,8 @@ which-func-update-timer
   (add-to-list 'mode-line-misc-info
                '(which-function-mode    ;Only display if mode is enabled.
                  (which-func-mode       ;Only display if buffer supports it.
-                  ("" which-func-format " ")))))
+                  (which-func--use-mode-line
+                   ("" which-func-format " "))))))
 
 ;; This is the name people would normally expect.
 ;;;###autoload
-- 
2.39.3


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sat, 08 Jul 2023 20:47:02 GMT) Full text and rfc822 format available.

Message #20 received at 64533 <at> debbugs.gnu.org (full text, mbox):

From: Andreas Schwab <schwab <at> linux-m68k.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 64533 <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the
 header line
Date: Sat, 08 Jul 2023 22:46:08 +0200
On Jul 08 2023, Spencer Baugh wrote:

> +@vindex which-func-display
> +  By default, Which Function mode displays the current function name
> +using the mode line.  Customize @code{which-func-display} to
> +@code{header}, @code{mode}, or @code{both} to use the header line,

Or a list of 'header and/or 'mode.

-- 
Andreas Schwab, schwab <at> linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sat, 08 Jul 2023 20:57:01 GMT) Full text and rfc822 format available.

Message #23 received at 64533 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Andreas Schwab <schwab <at> linux-m68k.org>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 64533 <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the
 header line
Date: Sat, 08 Jul 2023 16:56:29 -0400
[Message part 1 (text/plain, inline)]
Andreas Schwab <schwab <at> linux-m68k.org> writes:
> On Jul 08 2023, Spencer Baugh wrote:
>
>> +@vindex which-func-display
>> +  By default, Which Function mode displays the current function name
>> +using the mode line.  Customize @code{which-func-display} to
>> +@code{header}, @code{mode}, or @code{both} to use the header line,
>
> Or a list of 'header and/or 'mode.

Oh much better idea, done:

[0001-Support-displaying-function-name-in-the-header-line.patch (text/x-patch, inline)]
From 8c5acd79f67535703b8c669b25502c6edf141d24 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> janestreet.com>
Date: Sat, 8 Jul 2023 13:54:01 -0400
Subject: [PATCH] Support displaying function name in the header line

In some languages, the function name as displayed in the mode-line by
which-func-mode can be quite long.  It's useful to be able to display
it in the header-line instead.  Let's support that.

* lisp/progmodes/which-func.el (which-func-display)
(which-func--use-header-line, which-func--use-mode-line):
Add. (Bug#64533)
(which-func-try-to-enable): Support which-func--use-header-line.
(which-func--disable): Add, to support which-func--use-header-line.
(which-func-ff-hook, which-func-update-1): Use which-func--disable.
---
 doc/emacs/programs.texi      | 10 +++++++--
 etc/NEWS                     |  8 ++++++++
 lisp/progmodes/which-func.el | 39 ++++++++++++++++++++++++++++++------
 3 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 953de2e4786..705e3dd358e 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -396,8 +396,8 @@ Which Function
 @cindex current function name in mode line
 
   Which Function mode is a global minor mode (@pxref{Minor Modes})
-which displays the current function name in the mode line, updating it
-as you move around in a buffer.
+which displays the current function name in the mode line or header
+line, updating it as you move around in a buffer.
 
 @findex which-function-mode
 @vindex which-func-modes
@@ -410,6 +410,12 @@ Which Function
 @code{t} (which means to support all available major modes) to a list
 of major mode names.
 
+@vindex which-func-display
+  @code{which-func-display} is a list of symbols; if it contains
+@code{mode}, the function name is displayed in the mode line.  If it
+contains @code{header}, the function name is displayed in the header
+line.  By default it contains only @code{mode}.
+
 @node Program Indent
 @section Indentation for Programs
 @cindex indentation for programs
diff --git a/etc/NEWS b/etc/NEWS
index 0556e8be585..f5de6974a46 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -243,6 +243,14 @@ docstring, or a comment, or (re)indents the surrounding defun if
 point is not in a comment or a string.  It is by default bound to
 'M-q' in 'prog-mode' and all its descendants.
 
+** Which Function Mode
+
++++
+*** Displaying the function name in the header line is now supported.
+The new user option 'which-func-display' is a list of places to
+display the function name.  Add 'header' to that list to display in
+the header line.
+
 ** Tramp
 
 +++
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el
index 09937a60988..4c32002e991 100644
--- a/lisp/progmodes/which-func.el
+++ b/lisp/progmodes/which-func.el
@@ -86,6 +86,16 @@ which-func-non-auto-modes
 activation of Which Function until Imenu is used for the first time."
   :type '(repeat (symbol :tag "Major mode")))
 
+(defcustom which-func-display '(mode)
+  "Where to display the function name.
+
+This should be a list of symbols
+If 'mode, display in the mode line.  If 'header, display in the
+header line.  If 'both, display in both."
+  :type '(set (const :tag "Display in mode line" mode)
+              (const :tag "Display in header line" header))
+  :version "30.1")
+
 (defcustom which-func-maxout 500000
   "Don't automatically compute the Imenu menu if buffer is this big or bigger.
 Zero means compute the Imenu menu regardless of size.
@@ -184,17 +194,33 @@ which-func-current
 ;;;###autoload (put 'which-func-current 'risky-local-variable t)
 
 (defvar-local which-func-mode nil
-  "Non-nil means display current function name in mode line.
+  "Non-nil means display current function name in mode or header line.
 This makes a difference only if variable `which-function-mode' is
 non-nil.")
 
+(defvar-local which-func--use-header-line nil
+  "If non-nil, display the function name in the header line.")
+
+(defvar-local which-func--use-mode-line nil
+  "If non-nil, display the function name in the mode line.")
+
 (add-hook 'after-change-major-mode-hook #'which-func-ff-hook t)
 
 (defun which-func-try-to-enable ()
   (unless (or (not which-function-mode)
               (local-variable-p 'which-func-mode))
     (setq which-func-mode (or (eq which-func-modes t)
-                              (member major-mode which-func-modes)))))
+                              (member major-mode which-func-modes)))
+    (setq which-func--use-mode-line (member 'mode which-func-display))
+    (setq which-func--use-header-line (member 'header which-func-display))
+    (when (and which-func-mode which-func--use-header-line)
+      (add-to-list 'header-line-format '("" which-func-format " ")))))
+
+(defun which-func--disable ()
+  (when (and which-func-mode which-func--use-header-line)
+    (setq header-line-format
+          (delete '("" which-func-format " ") header-line-format)))
+  (setq which-func-mode nil))
 
 (defun which-func-ff-hook ()
   "`after-change-major-mode-hook' for Which Function mode.
@@ -210,10 +236,10 @@ which-func-ff-hook
 	  (setq imenu--index-alist
                 (save-excursion (funcall imenu-create-index-function))))
     (imenu-unavailable
-     (setq which-func-mode nil))
+     (which-func--disable))
     (error
      (message "which-func-ff-hook error: %S" err)
-     (setq which-func-mode nil))))
+     (which-func--disable))))
 
 (defun which-func-update ()
   "Update the Which-Function mode display in the current window."
@@ -231,7 +257,7 @@ which-func-update-1
 	      (puthash window current which-func-table)
 	      (force-mode-line-update)))
 	(error
-	 (setq which-func-mode nil)
+	 (which-func--disable)
 	 (error "Error in which-func-update: %S" info))))))
 
 (defvar which-func-update-timer nil)
@@ -241,7 +267,8 @@ which-func-update-timer
   (add-to-list 'mode-line-misc-info
                '(which-function-mode    ;Only display if mode is enabled.
                  (which-func-mode       ;Only display if buffer supports it.
-                  ("" which-func-format " ")))))
+                  (which-func--use-mode-line
+                   ("" which-func-format " "))))))
 
 ;; This is the name people would normally expect.
 ;;;###autoload
-- 
2.39.3


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sat, 08 Jul 2023 21:00:02 GMT) Full text and rfc822 format available.

Message #26 received at 64533 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Andreas Schwab <schwab <at> linux-m68k.org>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 64533 <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the
 header line
Date: Sat, 08 Jul 2023 16:58:50 -0400
[Message part 1 (text/plain, inline)]
Spencer Baugh <sbaugh <at> janestreet.com> writes:
> Andreas Schwab <schwab <at> linux-m68k.org> writes:
>> On Jul 08 2023, Spencer Baugh wrote:
>>
>>> +@vindex which-func-display
>>> +  By default, Which Function mode displays the current function name
>>> +using the mode line.  Customize @code{which-func-display} to
>>> +@code{header}, @code{mode}, or @code{both} to use the header line,
>>
>> Or a list of 'header and/or 'mode.
>
> Oh much better idea, done:

Oops, minor doc fix:

[0001-Support-displaying-function-name-in-the-header-line.patch (text/x-patch, inline)]
From 25be8c9040cdbe2ffe50e399a2d65eaf7759dce9 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> janestreet.com>
Date: Sat, 8 Jul 2023 13:54:01 -0400
Subject: [PATCH] Support displaying function name in the header line

In some languages, the function name as displayed in the mode-line by
which-func-mode can be quite long.  It's useful to be able to display
it in the header-line instead.  Let's support that.

* lisp/progmodes/which-func.el (which-func-display)
(which-func--use-header-line, which-func--use-mode-line):
Add. (Bug#64533)
(which-func-try-to-enable): Support which-func--use-header-line.
(which-func--disable): Add, to support which-func--use-header-line.
(which-func-ff-hook, which-func-update-1): Use which-func--disable.
---
 doc/emacs/programs.texi      | 10 +++++++--
 etc/NEWS                     |  8 ++++++++
 lisp/progmodes/which-func.el | 39 ++++++++++++++++++++++++++++++------
 3 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 953de2e4786..705e3dd358e 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -396,8 +396,8 @@ Which Function
 @cindex current function name in mode line
 
   Which Function mode is a global minor mode (@pxref{Minor Modes})
-which displays the current function name in the mode line, updating it
-as you move around in a buffer.
+which displays the current function name in the mode line or header
+line, updating it as you move around in a buffer.
 
 @findex which-function-mode
 @vindex which-func-modes
@@ -410,6 +410,12 @@ Which Function
 @code{t} (which means to support all available major modes) to a list
 of major mode names.
 
+@vindex which-func-display
+  @code{which-func-display} is a list of symbols; if it contains
+@code{mode}, the function name is displayed in the mode line.  If it
+contains @code{header}, the function name is displayed in the header
+line.  By default it contains only @code{mode}.
+
 @node Program Indent
 @section Indentation for Programs
 @cindex indentation for programs
diff --git a/etc/NEWS b/etc/NEWS
index 0556e8be585..f5de6974a46 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -243,6 +243,14 @@ docstring, or a comment, or (re)indents the surrounding defun if
 point is not in a comment or a string.  It is by default bound to
 'M-q' in 'prog-mode' and all its descendants.
 
+** Which Function Mode
+
++++
+*** Displaying the function name in the header line is now supported.
+The new user option 'which-func-display' is a list of places to
+display the function name.  Add 'header' to that list to display in
+the header line.
+
 ** Tramp
 
 +++
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el
index 09937a60988..4ea6ca1ee6f 100644
--- a/lisp/progmodes/which-func.el
+++ b/lisp/progmodes/which-func.el
@@ -86,6 +86,16 @@ which-func-non-auto-modes
 activation of Which Function until Imenu is used for the first time."
   :type '(repeat (symbol :tag "Major mode")))
 
+(defcustom which-func-display '(mode)
+  "Where to display the function name.
+
+This should be a list of symbols.  If it contains 'mode, display
+in the mode line.  If it contains 'header, display in the header
+line."
+  :type '(set (const :tag "Display in mode line" mode)
+              (const :tag "Display in header line" header))
+  :version "30.1")
+
 (defcustom which-func-maxout 500000
   "Don't automatically compute the Imenu menu if buffer is this big or bigger.
 Zero means compute the Imenu menu regardless of size.
@@ -184,17 +194,33 @@ which-func-current
 ;;;###autoload (put 'which-func-current 'risky-local-variable t)
 
 (defvar-local which-func-mode nil
-  "Non-nil means display current function name in mode line.
+  "Non-nil means display current function name in mode or header line.
 This makes a difference only if variable `which-function-mode' is
 non-nil.")
 
+(defvar-local which-func--use-header-line nil
+  "If non-nil, display the function name in the header line.")
+
+(defvar-local which-func--use-mode-line nil
+  "If non-nil, display the function name in the mode line.")
+
 (add-hook 'after-change-major-mode-hook #'which-func-ff-hook t)
 
 (defun which-func-try-to-enable ()
   (unless (or (not which-function-mode)
               (local-variable-p 'which-func-mode))
     (setq which-func-mode (or (eq which-func-modes t)
-                              (member major-mode which-func-modes)))))
+                              (member major-mode which-func-modes)))
+    (setq which-func--use-mode-line (member 'mode which-func-display))
+    (setq which-func--use-header-line (member 'header which-func-display))
+    (when (and which-func-mode which-func--use-header-line)
+      (add-to-list 'header-line-format '("" which-func-format " ")))))
+
+(defun which-func--disable ()
+  (when (and which-func-mode which-func--use-header-line)
+    (setq header-line-format
+          (delete '("" which-func-format " ") header-line-format)))
+  (setq which-func-mode nil))
 
 (defun which-func-ff-hook ()
   "`after-change-major-mode-hook' for Which Function mode.
@@ -210,10 +236,10 @@ which-func-ff-hook
 	  (setq imenu--index-alist
                 (save-excursion (funcall imenu-create-index-function))))
     (imenu-unavailable
-     (setq which-func-mode nil))
+     (which-func--disable))
     (error
      (message "which-func-ff-hook error: %S" err)
-     (setq which-func-mode nil))))
+     (which-func--disable))))
 
 (defun which-func-update ()
   "Update the Which-Function mode display in the current window."
@@ -231,7 +257,7 @@ which-func-update-1
 	      (puthash window current which-func-table)
 	      (force-mode-line-update)))
 	(error
-	 (setq which-func-mode nil)
+	 (which-func--disable)
 	 (error "Error in which-func-update: %S" info))))))
 
 (defvar which-func-update-timer nil)
@@ -241,7 +267,8 @@ which-func-update-timer
   (add-to-list 'mode-line-misc-info
                '(which-function-mode    ;Only display if mode is enabled.
                  (which-func-mode       ;Only display if buffer supports it.
-                  ("" which-func-format " ")))))
+                  (which-func--use-mode-line
+                   ("" which-func-format " "))))))
 
 ;; This is the name people would normally expect.
 ;;;###autoload
-- 
2.39.3


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sun, 09 Jul 2023 05:30:01 GMT) Full text and rfc822 format available.

Message #29 received at 64533 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: schwab <at> linux-m68k.org, 64533 <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the
 header line
Date: Sun, 09 Jul 2023 08:29:28 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Cc: Eli Zaretskii <eliz <at> gnu.org>,  64533 <at> debbugs.gnu.org
> Date: Sat, 08 Jul 2023 16:56:29 -0400
> 
> >> +@vindex which-func-display
> >> +  By default, Which Function mode displays the current function name
> >> +using the mode line.  Customize @code{which-func-display} to
> >> +@code{header}, @code{mode}, or @code{both} to use the header line,
> >
> > Or a list of 'header and/or 'mode.
> 
> Oh much better idea, done:

I disagree that it is a better idea.  It makes a tad harder to
customize the variable in Lisp if the user is not familiar enough with
Emacs Lisp.  The Custom interface is also more cumbersome.

So my clear preference is for the previous variant, with separate
symbols.  If 'both' is too vague, we could use 'mode-and-header'
instead.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sun, 09 Jul 2023 05:37:02 GMT) Full text and rfc822 format available.

Message #32 received at 64533 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: schwab <at> linux-m68k.org, 64533 <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the
 header line
Date: Sun, 09 Jul 2023 08:36:37 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Cc: Eli Zaretskii <eliz <at> gnu.org>,  64533 <at> debbugs.gnu.org
> Date: Sat, 08 Jul 2023 16:58:50 -0400
> 
> +** Which Function Mode
> +
> ++++
> +*** Displaying the function name in the header line is now supported.

Passive voice alert!  Here's a better wording (also for reasons other
than passive voice);;

  Which Function Mode can now display function names on the header line.

> +(defcustom which-func-display '(mode)
> +  "Where to display the function name.
> +
> +This should be a list of symbols.  If it contains 'mode, display
> +in the mode line.  If it contains 'header, display in the header
> +line."

Which leaves it to the user to deduce that '(mode header) means both:
yet another reason not to prefer this kind of values in user options.

It also doesn't tell how to disable this display: another riddle left
to the user to solve.

Let's always remember that Emacs users are not necessarily experienced
Lispers.  User options should not be "tricky", especially where such
trickery is unjustified.  And the doc strings should not pose riddles,
however logical they seem to us.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#64533; Package emacs. (Sun, 09 Jul 2023 17:27:02 GMT) Full text and rfc822 format available.

Message #35 received at 64533 <at> debbugs.gnu.org (full text, mbox):

From: sbaugh <at> catern.com
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Spencer Baugh <sbaugh <at> janestreet.com>, schwab <at> linux-m68k.org,
 64533 <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the header
 line
Date: Sun, 09 Jul 2023 17:26:09 +0000 (UTC)
[Message part 1 (text/plain, inline)]
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: Spencer Baugh <sbaugh <at> janestreet.com>
>> Cc: Eli Zaretskii <eliz <at> gnu.org>,  64533 <at> debbugs.gnu.org
>> Date: Sat, 08 Jul 2023 16:58:50 -0400
>> 
>> +** Which Function Mode
>> +
>> ++++
>> +*** Displaying the function name in the header line is now supported.
>
> Passive voice alert!  Here's a better wording (also for reasons other
> than passive voice);;
>
>   Which Function Mode can now display function names on the header line.

Fixed.

>> +(defcustom which-func-display '(mode)
>> +  "Where to display the function name.
>> +
>> +This should be a list of symbols.  If it contains 'mode, display
>> +in the mode line.  If it contains 'header, display in the header
>> +line."
>
> Which leaves it to the user to deduce that '(mode header) means both:
> yet another reason not to prefer this kind of values in user options.
>
> It also doesn't tell how to disable this display: another riddle left
> to the user to solve.
>
> Let's always remember that Emacs users are not necessarily experienced
> Lispers.  User options should not be "tricky", especially where such
> trickery is unjustified.  And the doc strings should not pose riddles,
> however logical they seem to us.
>
> Thanks.

Fair point.  Back to the single symbol.

[0001-Support-displaying-function-name-in-the-header-line.patch (text/x-patch, inline)]
From 3f23e559cae5ce864aef2c15e990f6beb5484eb7 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> catern.com>
Date: Sun, 9 Jul 2023 12:16:28 -0400
Subject: [PATCH] Support displaying function name in the header line

In some languages, the function name as displayed in the mode-line by
which-func-mode can be quite long.  It's useful to be able to display
it in the header-line instead.  Let's support that.

* lisp/progmodes/which-func.el (which-func-display)
(which-func--use-header-line, which-func--use-mode-line):
Add. (Bug#64533)
(which-func-try-to-enable): Support which-func--use-header-line.
(which-func--disable): Add, to support which-func--use-header-line.
(which-func-ff-hook, which-func-update-1): Use which-func--disable.
---
 doc/emacs/programs.texi      | 10 +++++++--
 etc/NEWS                     |  9 ++++++++
 lisp/progmodes/which-func.el | 42 ++++++++++++++++++++++++++++++------
 3 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index a0e0fc06385..41780a95489 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -335,8 +335,8 @@ Which Function
 @cindex current function name in mode line
 
   Which Function mode is a global minor mode (@pxref{Minor Modes})
-which displays the current function name in the mode line, updating it
-as you move around in a buffer.
+which displays the current function name in the mode line or header
+line, updating it as you move around in a buffer.
 
 @findex which-function-mode
 @vindex which-func-modes
@@ -349,6 +349,12 @@ Which Function
 @code{t} (which means to support all available major modes) to a list
 of major mode names.
 
+@vindex which-func-display
+  By default, Which Function mode displays the current function name
+using the mode line.  Customize @code{which-func-display} to
+@code{header}, @code{mode}, or @code{mode-and-header} to use the
+header line, mode line, or both, respectively.
+
 @node Program Indent
 @section Indentation for Programs
 @cindex indentation for programs
diff --git a/etc/NEWS b/etc/NEWS
index 9c99cf6c725..efd323cb1da 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2989,6 +2989,15 @@ The newly created buffer will be displayed via 'display-buffer', which
 can be customized through the usual mechanism of 'display-buffer-alist'
 and friends.
 
+** Which Function Mode
+
++++
+*** Which Function Mode can now display function names on the header line.
+The new user option 'which-func-display' allows choosing where the
+function name is displayed.  The default is 'mode' to display in the
+mode line.  'header' will display in the header line.
+'mode-and-header' displays in both the header line and mode line.
+
 ** Tramp
 
 +++
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el
index 09937a60988..631d47bb729 100644
--- a/lisp/progmodes/which-func.el
+++ b/lisp/progmodes/which-func.el
@@ -86,6 +86,17 @@ which-func-non-auto-modes
 activation of Which Function until Imenu is used for the first time."
   :type '(repeat (symbol :tag "Major mode")))
 
+(defcustom which-func-display 'mode
+  "Where to display the function name.
+
+If 'mode, display in the mode line.  If 'header, display in the
+header line.  If 'mode-and-header, display in both."
+  :type '(choice (const :tag "Display in mode line" mode)
+                 (const :tag "Display in header line" header)
+                 (const :tag "Display in both header and mode line"
+                        mode-and-header))
+  :version "30.1")
+
 (defcustom which-func-maxout 500000
   "Don't automatically compute the Imenu menu if buffer is this big or bigger.
 Zero means compute the Imenu menu regardless of size.
@@ -184,17 +195,35 @@ which-func-current
 ;;;###autoload (put 'which-func-current 'risky-local-variable t)
 
 (defvar-local which-func-mode nil
-  "Non-nil means display current function name in mode line.
+  "Non-nil means display current function name in mode or header line.
 This makes a difference only if variable `which-function-mode' is
 non-nil.")
 
+(defvar-local which-func--use-header-line nil
+  "If non-nil, display the function name in the header line.")
+
+(defvar-local which-func--use-mode-line nil
+  "If non-nil, display the function name in the mode line.")
+
 (add-hook 'after-change-major-mode-hook #'which-func-ff-hook t)
 
 (defun which-func-try-to-enable ()
   (unless (or (not which-function-mode)
               (local-variable-p 'which-func-mode))
     (setq which-func-mode (or (eq which-func-modes t)
-                              (member major-mode which-func-modes)))))
+                              (member major-mode which-func-modes)))
+    (setq which-func--use-mode-line
+          (member which-func-display '(mode mode-and-header)))
+    (setq which-func--use-header-line
+          (member which-func-display '(header mode-and-header)))
+    (when (and which-func-mode which-func--use-header-line)
+      (add-to-list 'header-line-format '("" which-func-format " ")))))
+
+(defun which-func--disable ()
+  (when (and which-func-mode which-func--use-header-line)
+    (setq header-line-format
+          (delete '("" which-func-format " ") header-line-format)))
+  (setq which-func-mode nil))
 
 (defun which-func-ff-hook ()
   "`after-change-major-mode-hook' for Which Function mode.
@@ -210,10 +239,10 @@ which-func-ff-hook
 	  (setq imenu--index-alist
                 (save-excursion (funcall imenu-create-index-function))))
     (imenu-unavailable
-     (setq which-func-mode nil))
+     (which-func--disable))
     (error
      (message "which-func-ff-hook error: %S" err)
-     (setq which-func-mode nil))))
+     (which-func--disable))))
 
 (defun which-func-update ()
   "Update the Which-Function mode display in the current window."
@@ -231,7 +260,7 @@ which-func-update-1
 	      (puthash window current which-func-table)
 	      (force-mode-line-update)))
 	(error
-	 (setq which-func-mode nil)
+	 (which-func--disable)
 	 (error "Error in which-func-update: %S" info))))))
 
 (defvar which-func-update-timer nil)
@@ -241,7 +270,8 @@ which-func-update-timer
   (add-to-list 'mode-line-misc-info
                '(which-function-mode    ;Only display if mode is enabled.
                  (which-func-mode       ;Only display if buffer supports it.
-                  ("" which-func-format " ")))))
+                  (which-func--use-mode-line
+                   ("" which-func-format " "))))))
 
 ;; This is the name people would normally expect.
 ;;;###autoload
-- 
2.41.0


Reply sent to Eli Zaretskii <eliz <at> gnu.org>:
You have taken responsibility. (Sat, 15 Jul 2023 08:03:02 GMT) Full text and rfc822 format available.

Notification sent to Spencer Baugh <sbaugh <at> janestreet.com>:
bug acknowledged by developer. (Sat, 15 Jul 2023 08:03:02 GMT) Full text and rfc822 format available.

Message #40 received at 64533-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: sbaugh <at> catern.com
Cc: sbaugh <at> janestreet.com, schwab <at> linux-m68k.org, 64533-done <at> debbugs.gnu.org
Subject: Re: bug#64533: [PATCH] Support displaying function name in the header
 line
Date: Sat, 15 Jul 2023 11:02:50 +0300
> From: sbaugh <at> catern.com
> Date: Sun, 09 Jul 2023 17:26:09 +0000 (UTC)
> Cc: Spencer Baugh <sbaugh <at> janestreet.com>, schwab <at> linux-m68k.org,
> 	64533 <at> debbugs.gnu.org
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> >> +This should be a list of symbols.  If it contains 'mode, display
> >> +in the mode line.  If it contains 'header, display in the header
> >> +line."
> >
> > Which leaves it to the user to deduce that '(mode header) means both:
> > yet another reason not to prefer this kind of values in user options.
> >
> > It also doesn't tell how to disable this display: another riddle left
> > to the user to solve.
> >
> > Let's always remember that Emacs users are not necessarily experienced
> > Lispers.  User options should not be "tricky", especially where such
> > trickery is unjustified.  And the doc strings should not pose riddles,
> > however logical they seem to us.
> >
> > Thanks.
> 
> Fair point.  Back to the single symbol.

Thanks, installed on master, and closing the bug.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sat, 12 Aug 2023 11:24:09 GMT) Full text and rfc822 format available.

This bug report was last modified 1 year and 363 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.