GNU bug report logs - #69578
30.0.50; tab-bar-mode binding of (control tab) not always useful

Previous Next

Package: emacs;

Reported by: Gerd Möllmann <gerd.moellmann <at> gmail.com>

Date: Wed, 6 Mar 2024 07:58:02 UTC

Severity: normal

Fixed in version 30.0.50

Done: Juri Linkov <juri <at> linkov.net>

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 69578 in the body.
You can then email your comments to 69578 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#69578; Package emacs. (Wed, 06 Mar 2024 07:58:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Gerd Möllmann <gerd.moellmann <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 06 Mar 2024 07:58:02 GMT) Full text and rfc822 format available.

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

From: Gerd Möllmann <gerd.moellmann <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.0.50; tab-bar-mode binding of (control tab) not always useful
Date: Wed, 06 Mar 2024 08:56:56 +0100
tab-bar--define-keys makes bindings for TAG like this:

  (unless (global-key-binding [(control tab)])
    (global-set-key [(control tab)] #'tab-next))
  (unless (global-key-binding [(control shift tab)])
    (global-set-key [(control shift tab)] #'tab-previous))
  (unless (global-key-binding [(control shift iso-lefttab)])
    (global-set-key [(control shift iso-lefttab)] #'tab-previous))

These bindings stop taking effect if a mode has its own bindings for
control tab, for instance. A prominent example is Magit.

So, maybe these bindings should not be done?

In GNU Emacs 30.0.50 (build 1, x86_64-apple-darwin23.3.0, NS
 appkit-2487.40 Version 14.3.1 (Build 23D60)) of 2024-03-05 built on
 Pro.fritz.box
Repository revision: a3d7092114db09fee392ccc8187fde03376f2089
Repository branch: HEAD
Windowing system distributor 'Apple', version 10.3.2487
System Description:  macOS 14.3.1





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Wed, 06 Mar 2024 17:50:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: Gerd Möllmann <gerd.moellmann <at> gmail.com>
Cc: 69578 <at> debbugs.gnu.org
Subject: Re: bug#69578: 30.0.50; tab-bar-mode binding of (control tab) not
 always useful
Date: Wed, 06 Mar 2024 19:45:46 +0200
> tab-bar--define-keys makes bindings for TAG like this:
>
>   (unless (global-key-binding [(control tab)])
>     (global-set-key [(control tab)] #'tab-next))
>   (unless (global-key-binding [(control shift tab)])
>     (global-set-key [(control shift tab)] #'tab-previous))
>   (unless (global-key-binding [(control shift iso-lefttab)])
>     (global-set-key [(control shift iso-lefttab)] #'tab-previous))
>
> These bindings stop taking effect if a mode has its own bindings for
> control tab, for instance. A prominent example is Magit.

The developers of Org mode took courage and
replaced their C-TAB bindings with C-c C-TAB:
https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-09/msg00341.html
The developers of Magit could do the same.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Sun, 10 Mar 2024 05:34:01 GMT) Full text and rfc822 format available.

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

From: Gerd Möllmann <gerd.moellmann <at> gmail.com>
To: Juri Linkov <juri <at> linkov.net>
Cc: 69578 <at> debbugs.gnu.org
Subject: Re: bug#69578: 30.0.50; tab-bar-mode binding of (control tab) not
 always useful
Date: Sun, 10 Mar 2024 06:31:48 +0100
Juri Linkov <juri <at> linkov.net> writes:

>> tab-bar--define-keys makes bindings for TAG like this:
>>
>>   (unless (global-key-binding [(control tab)])
>>     (global-set-key [(control tab)] #'tab-next))
>>   (unless (global-key-binding [(control shift tab)])
>>     (global-set-key [(control shift tab)] #'tab-previous))
>>   (unless (global-key-binding [(control shift iso-lefttab)])
>>     (global-set-key [(control shift iso-lefttab)] #'tab-previous))
>>
>> These bindings stop taking effect if a mode has its own bindings for
>> control tab, for instance. A prominent example is Magit.
>
> The developers of Org mode took courage and
> replaced their C-TAB bindings with C-c C-TAB:
> https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-09/msg00341.html
> The developers of Magit could do the same.

I've submitted https://github.com/magit/magit/issues/5106 to the Magit
project.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Sun, 10 Mar 2024 06:29:01 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Gerd Möllmann <gerd.moellmann <at> gmail.com>
Cc: 69578 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#69578: 30.0.50;
 tab-bar-mode binding of (control tab) not always useful
Date: Sun, 10 Mar 2024 08:28:14 +0200
> Cc: 69578 <at> debbugs.gnu.org
> From: Gerd Möllmann <gerd.moellmann <at> gmail.com>
> Date: Sun, 10 Mar 2024 06:31:48 +0100
> 
> Juri Linkov <juri <at> linkov.net> writes:
> 
> >> tab-bar--define-keys makes bindings for TAG like this:
> >>
> >>   (unless (global-key-binding [(control tab)])
> >>     (global-set-key [(control tab)] #'tab-next))
> >>   (unless (global-key-binding [(control shift tab)])
> >>     (global-set-key [(control shift tab)] #'tab-previous))
> >>   (unless (global-key-binding [(control shift iso-lefttab)])
> >>     (global-set-key [(control shift iso-lefttab)] #'tab-previous))
> >>
> >> These bindings stop taking effect if a mode has its own bindings for
> >> control tab, for instance. A prominent example is Magit.
> >
> > The developers of Org mode took courage and
> > replaced their C-TAB bindings with C-c C-TAB:
> > https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-09/msg00341.html
> > The developers of Magit could do the same.
> 
> I've submitted https://github.com/magit/magit/issues/5106 to the Magit
> project.

Thanks, should we therefore close this bug?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Sun, 10 Mar 2024 06:39:02 GMT) Full text and rfc822 format available.

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

From: Gerd Möllmann <gerd.moellmann <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 69578 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#69578: 30.0.50; tab-bar-mode binding of (control tab) not
 always useful
Date: Sun, 10 Mar 2024 07:36:25 +0100
Eli Zaretskii <eliz <at> gnu.org> writes:

> Thanks, should we therefore close this bug?

I'll close it in a second, thanks.




bug marked as fixed in version 30.1, send any further explanations to 69578 <at> debbugs.gnu.org and Gerd Möllmann <gerd.moellmann <at> gmail.com> Request was from Gerd Möllmann <gerd.moellmann <at> gmail.com> to control <at> debbugs.gnu.org. (Sun, 10 Mar 2024 06:39:03 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Mon, 11 Mar 2024 14:25:01 GMT) Full text and rfc822 format available.

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

From: Jonas Bernoulli <jonas <at> bernoul.li>
To: 69578 <at> debbugs.gnu.org
Subject: bug#69578: 30.0.50; tab-bar-mode binding of (control tab) not
 always useful
Date: Mon, 11 Mar 2024 15:23:51 +0100
> The developers of Org mode took courage and replaced their C-TAB
> bindings with C-c C-TAB:

It indeed takes courage to change key bindings; there will always be
a few users who get very upset by such a change.

> These bindings stop taking effect if a mode has its own bindings for
> control tab, for instance. A prominent example is Magit.

I have addressed this in Magit as described in this commit message:

magit-section-cycle: Pivot to tab-next if there is a binding conflict

If `tab-bar-mode' is enable, then "C-<tab>" is bound to `tab-next'
in the global map.  That conflicts with our local (and much older)
binding for `magit-section-cycle'.

Address this conflict by teaching `magit-section-cycle' to pivot to
`tab-next', but only if `tab-bar-mode' is enabled.  That way, users
who do not use `tab-bar-mode' (i.e., the majority), are not affected
by this unfortunate conflict.

`tab-bar-mode' users will have to get used to the much less convenient
"C-c TAB" binding to cycle section visibility.  Alternatively they can
advice `tab-bar--define-keys' to bind another key to `tab-next'.  It
would be nice if `tab-bar-mode', instead of modifying the global map,
used a mode map, and thus didn't make it so very hard to change its
key bindings.

> So, maybe these bindings should not be done?

Too late for that now, but they should definitely be done in a way that
users can customize, without having to advice tab-bar--define-keys (and
tab-bar--undefine-keys).  Maybe by using a mode map?  If there is some
reason this cannot be done, then maybe a "dummy keymap" could be used?
(User could then manipulate the fake tab-bar-mode-map like any keymap,
but the bindings it contains would then somehow be "transplanted" into
the global map by tab-bar--define-keys.)

>> Thanks, should we therefore close this bug?
>
> I'll close it in a second, thanks.

This seems premature, making it so hard for users to change the tab-bar
bindings seems like something that needs to be fixed.




bug No longer marked as fixed in versions 30.1 and reopened. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Mon, 11 Mar 2024 14:53:01 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Mon, 11 Mar 2024 14:55:02 GMT) Full text and rfc822 format available.

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

From: Gerd Möllmann <gerd.moellmann <at> gmail.com>
To: Jonas Bernoulli <jonas <at> bernoul.li>
Cc: 69578 <at> debbugs.gnu.org
Subject: Re: bug#69578: 30.0.50; tab-bar-mode binding of (control tab) not
 always useful
Date: Mon, 11 Mar 2024 15:52:32 +0100
Jonas Bernoulli <jonas <at> bernoul.li> writes:

>>> Thanks, should we therefore close this bug?
>>
>> I'll close it in a second, thanks.
>
> This seems premature, making it so hard for users to change the tab-bar
> bindings seems like something that needs to be fixed.

No problem, I've re-opened it. Thanks, Jonas!




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Mon, 11 Mar 2024 15:05:01 GMT) Full text and rfc822 format available.

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

From: Gerd Möllmann <gerd.moellmann <at> gmail.com>
To: Jonas Bernoulli <jonas <at> bernoul.li>
Cc: 69578 <at> debbugs.gnu.org
Subject: Re: bug#69578: 30.0.50; tab-bar-mode binding of (control tab) not
 always useful
Date: Mon, 11 Mar 2024 16:02:26 +0100
Gerd Möllmann <gerd.moellmann <at> gmail.com> writes:

> No problem, I've re-opened it. Thanks, Jonas!

At least I tried, but reopen doesn't seem to take effect.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Mon, 11 Mar 2024 16:46:02 GMT) Full text and rfc822 format available.

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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Gerd Möllmann <gerd.moellmann <at> gmail.com>
Cc: jonas <at> bernoul.li, 69578 <at> debbugs.gnu.org
Subject: Re: bug#69578: 30.0.50;
 tab-bar-mode binding of (control tab) not always useful
Date: Mon, 11 Mar 2024 18:44:51 +0200
> Cc: 69578 <at> debbugs.gnu.org
> From: Gerd Möllmann <gerd.moellmann <at> gmail.com>
> Date: Mon, 11 Mar 2024 16:02:26 +0100
> 
> Gerd Möllmann <gerd.moellmann <at> gmail.com> writes:
> 
> > No problem, I've re-opened it. Thanks, Jonas!
> 
> At least I tried, but reopen doesn't seem to take effect.

It did.  The bug is now open.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Mon, 11 Mar 2024 18:03:01 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: Jonas Bernoulli <jonas <at> bernoul.li>
Cc: 69578 <at> debbugs.gnu.org
Subject: Re: bug#69578: 30.0.50; tab-bar-mode binding of (control tab) not
 always useful
Date: Mon, 11 Mar 2024 19:50:20 +0200
[Message part 1 (text/plain, inline)]
>> So, maybe these bindings should not be done?
>
> Too late for that now, but they should definitely be done in a way that
> users can customize, without having to advice tab-bar--define-keys (and
> tab-bar--undefine-keys).

Thanks for bringing up this issue.  Customization of keys was not supported
since no once asked for it, I guess because tab-bar--define-keys
respected the existing global keybindings before defining own.
But indeed this doesn't work for local keymaps.

> Maybe by using a mode map?  If there is some reason this cannot be
> done, then maybe a "dummy keymap" could be used?  (User could then
> manipulate the fake tab-bar-mode-map like any keymap, but the bindings
> it contains would then somehow be "transplanted" into the global map
> by tab-bar--define-keys.)

Just adding a simple mode map completely makes it customizable
since 'define-minor-mode' is able to pick it by naming convention:

  (defvar tab-bar-mode-map
    (let ((map (make-sparse-keymap)))
      (define-key map [(control tab)] #'tab-next)
      (define-key map [(control shift tab)] #'tab-previous)
      (define-key map [(control shift iso-lefttab)] #'tab-previous)
      map)
    "Tab Bar mode map.")

The rest of complexity in the following patch comes
from the need to address the customization of
'tab-bar-select-tab-modifiers'.

There is a slight backward incompatibility for users who have own
global keybindings for C-TAB.  They will need to unbind these keys
in the new map.  Then this change should be announced in NEWS:
[tab-bar-mode-map.patch (text/x-diff, inline)]
diff --git a/etc/NEWS b/etc/NEWS
index 19cd170e5c7..0aab2d04ca2 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -285,6 +285,11 @@ selected or deselected at the end of executing the current command.
 
 ** Tab Bars and Tab Lines
 
+---
+*** New keymap 'tab-bar-mode-map'.
+If you have global keybinding for 'C-TAB', then you might want
+to unbind the same keybinding in 'tab-bar-mode-map'.
+
 ---
 *** New user option 'tab-bar-tab-name-format-functions'.
 It can be used to add, remove and reorder functions that change
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 61efa332e0b..07470f072e1 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -104,10 +104,11 @@ tab-bar-select-tab-modifiers
               (const alt))
   :initialize #'custom-initialize-default
   :set (lambda (sym val)
+         (when tab-bar-mode
+           (tab-bar--undefine-keys))
          (set-default sym val)
          ;; Reenable the tab-bar with new keybindings
          (when tab-bar-mode
-           (tab-bar--undefine-keys)
            (tab-bar--define-keys)))
   :group 'tab-bar
   :version "27.1")
@@ -115,21 +116,17 @@ tab-bar-select-tab-modifiers
 (defun tab-bar--define-keys ()
   "Install key bindings to switch between tabs if so configured."
   (when tab-bar-select-tab-modifiers
-    (global-set-key (vector (append tab-bar-select-tab-modifiers (list ?0)))
-                    #'tab-recent)
+    (define-key tab-bar-mode-map
+                (vector (append tab-bar-select-tab-modifiers (list ?0)))
+                #'tab-recent)
     (dotimes (i 8)
-      (global-set-key (vector (append tab-bar-select-tab-modifiers
-                                      (list (+ i 1 ?0))))
-                      #'tab-bar-select-tab))
-    (global-set-key (vector (append tab-bar-select-tab-modifiers (list ?9)))
-                    #'tab-last))
-  ;; Don't override user customized key bindings
-  (unless (global-key-binding [(control tab)])
-    (global-set-key [(control tab)] #'tab-next))
-  (unless (global-key-binding [(control shift tab)])
-    (global-set-key [(control shift tab)] #'tab-previous))
-  (unless (global-key-binding [(control shift iso-lefttab)])
-    (global-set-key [(control shift iso-lefttab)] #'tab-previous))
+      (define-key tab-bar-mode-map
+                  (vector (append tab-bar-select-tab-modifiers
+                                  (list (+ i 1 ?0))))
+                  #'tab-bar-select-tab))
+    (define-key tab-bar-mode-map
+                (vector (append tab-bar-select-tab-modifiers (list ?9)))
+                #'tab-last))
 
   ;; Replace default value with a condition that supports displaying
   ;; global-mode-string in the tab bar instead of the mode line.
@@ -144,12 +141,18 @@ tab-bar--define-keys
 
 (defun tab-bar--undefine-keys ()
   "Uninstall key bindings previously bound by `tab-bar--define-keys'."
-  (when (eq (global-key-binding [(control tab)]) 'tab-next)
-    (global-unset-key [(control tab)]))
-  (when (eq (global-key-binding [(control shift tab)]) 'tab-previous)
-    (global-unset-key [(control shift tab)]))
-  (when (eq (global-key-binding [(control shift iso-lefttab)]) 'tab-previous)
-    (global-unset-key [(control shift iso-lefttab)])))
+  (when tab-bar-select-tab-modifiers
+    (define-key tab-bar-mode-map
+                (vector (append tab-bar-select-tab-modifiers (list ?0)))
+                nil)
+    (dotimes (i 8)
+      (define-key tab-bar-mode-map
+                  (vector (append tab-bar-select-tab-modifiers
+                                  (list (+ i 1 ?0))))
+                  nil))
+    (define-key tab-bar-mode-map
+                (vector (append tab-bar-select-tab-modifiers (list ?9)))
+                nil)))
 
 (defun tab-bar--load-buttons ()
   "Load the icons for the tab buttons."
@@ -239,6 +242,14 @@ tab-bar--update-tab-bar-lines
                       (if (and tab-bar-mode (eq tab-bar-show t)) 1 0))
                 (assq-delete-all 'tab-bar-lines default-frame-alist)))))
 
+(defvar tab-bar-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [(control tab)] #'tab-next)
+    (define-key map [(control shift tab)] #'tab-previous)
+    (define-key map [(control shift iso-lefttab)] #'tab-previous)
+    map)
+  "Tab Bar mode map.")
+
 (define-minor-mode tab-bar-mode
   "Toggle the tab bar in all graphical frames (Tab Bar mode)."
   :global t

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Wed, 20 Mar 2024 17:56:02 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: Jonas Bernoulli <jonas <at> bernoul.li>
Cc: 69578 <at> debbugs.gnu.org
Subject: Re: bug#69578: 30.0.50; tab-bar-mode binding of (control tab) not
 always useful
Date: Wed, 20 Mar 2024 19:40:40 +0200
> There is a slight backward incompatibility for users who have own
> global keybindings for C-TAB.  They will need to unbind these keys
> in the new map.  Then this change should be announced in NEWS:
>
> diff --git a/etc/NEWS b/etc/NEWS
> +---
> +*** New keymap 'tab-bar-mode-map'.
> +If you have global keybinding for 'C-TAB', then you might want
> +to unbind the same keybinding in 'tab-bar-mode-map'.

I still feel uneasy about this backward incompatibility
since users will suddenly get tab-switching on C-TAB
when they use another global keybinding for C-TAB.
So we need to rethink this change.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#69578; Package emacs. (Fri, 05 Apr 2024 16:28:01 GMT) Full text and rfc822 format available.

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

From: Juri Linkov <juri <at> linkov.net>
To: Jonas Bernoulli <jonas <at> bernoul.li>
Cc: 69578 <at> debbugs.gnu.org
Subject: Re: bug#69578: 30.0.50; tab-bar-mode binding of (control tab) not
 always useful
Date: Fri, 05 Apr 2024 19:23:23 +0300
close 69578 30.0.50
thanks

>> There is a slight backward incompatibility for users who have own
>> global keybindings for C-TAB.  They will need to unbind these keys
>> in the new map.  Then this change should be announced in NEWS:
>>
>> diff --git a/etc/NEWS b/etc/NEWS
>> +---
>> +*** New keymap 'tab-bar-mode-map'.
>> +If you have global keybinding for 'C-TAB', then you might want
>> +to unbind the same keybinding in 'tab-bar-mode-map'.
>
> I still feel uneasy about this backward incompatibility
> since users will suddenly get tab-switching on C-TAB
> when they use another global keybinding for C-TAB.
> So we need to rethink this change.

Ok, now pushed a backward-compatibile fix.
So can close now.




bug marked as fixed in version 30.0.50, send any further explanations to 69578 <at> debbugs.gnu.org and Gerd Möllmann <gerd.moellmann <at> gmail.com> Request was from Juri Linkov <juri <at> linkov.net> to control <at> debbugs.gnu.org. (Fri, 05 Apr 2024 16:28:02 GMT) Full text and rfc822 format available.

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

This bug report was last modified today.

Previous Next


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