6

I defined a function like this:

(defun switch-to-prev-window ()
  (interactive)
  (other-window -1))

and it appears to work if I call it with M-x. But I've added the binding

(global-set-key [(control shift tab)] 'switch-to-prev-window)

and that does NOT seem to work. In fact when I use M-x to run it, it reports you can run the command 'switch-to-prev-window' with <C-S-tab>. But when I type ctrl-shit-tab I see <C-S-iso-lefttab> is undefined. And yet

(global-set-key [(control tab)] 'other-window)

seems to work fine. Based on the error message I tried

(global-set-key [(control shift iso-lefttab)] 'switch-to-prev-window)

and that works fine too.

So I'm left wondering: is control tab aliased to control iso-lefttab, but there's no corresponding control shift tab alias? And yet if that were the case, why the reminder that <C-S-tab> is available?

  • 2
    The reminder about C-S-tab is because your (global-set-key [(control shift tab)] 'switch-to-prev-window) setup a binding for C-S-tab. The problem is that hitting control+shift+tab doesn't send events which Emacs interprets as C-S-tab but as C-S-iso-lefttab instead. – Stefan Oct 30 '19 at 2:15
  • then how does the (control tab) binding work? I'm not required to type (control iso-lefttab) to bind it... – Swiss Frank Oct 30 '19 at 2:16
  • 1
    I deleted my answer of (global-set-key [C-S-tab] 'switch-to-prev-window) and will defer to @Stefan to provide additional assistance ... he is an expert / Emacs guru .... :) – lawlist Oct 30 '19 at 2:27
6

Key naming is messier than it ought to be. When you press the Tab key while the Shift modifier is held down, your operating system tells Emacs that you've pressed the ISO_Left_Tab key. I guess that you're using an X11-based system (I think that's the only platform with this particular key name) and you're using a standard XKB layout which specifies (e.g. through /usr/share/X11/xkb/symbols/pc):

    key  <TAB> {  [ Tab,  ISO_Left_Tab    ]      };

This means: when the user presses the physical key TAB, it's the logical key Tab if unshifted but ISO_Left_Tab if shifted.

The reason to have a separate key is that there (used to) exist terminals with a both a “left tab” and a “right tab” key. Most terminals only have a single tab key which is a right tab key, and the convention to indent or move to the left is to use this key with the Shift modifier. That's why Shift+Tab is translated to a “left tab” keyboard event.

Emacs has its own name for the logical key “tab towards the left”, which is backtab. In local-function-key-map on an X11 frame, there's a translation from iso-lefttab and S-iso-lefttab to backtab. There's no corresponding translation for C-iso-lefttab or C-S-iso-lefttab.

Add these translations to function-key-map. (That's not the absolute cleanest place to put them, because function-key-map applies to all terminals and not just X11 frames. But since this translation doesn't hurt elsewhere, you might as well apply it systematically.) Add any other similar translation if you want to use other modifiers.

(define-key function-key-map [(control shift iso-lefttab)] [(control shift tab)])
(define-key function-key-map [(meta shift iso-lefttab)] [(meta shift tab)])
(define-key function-key-map [(meta control shift iso-lefttab)] [(meta control shift tab)])

Alternatively, make your key binding for C-S-iso-lefttab rather than C-S-tab. Some modes do set up bindings for S-iso-lefttab rather than rely on the translation. If you use the function-key-map approach and a mode defines a binding for C-S-iso-lefttab, the mode's binding takes precedence over the translation in function-key-map.

For completeness, the canonical place for a key translation that should only take place in an X11 frame is in x-alternatives-map, which is used as the local-function-key-map on X11 frame (each terminal has its own value of local-function-key-map).

| improve this answer | |
  • I actually worked for the X Consortium (internationalization in X11R6) and didn't know of this stage of mapping: "This means: when the user presses the physical key TAB, it's the logical key Tab if unshifted but ISO_Left_Tab if shifted." That more or less is necessary and sufficient to answer the direct question but the extra completeness is as enjoyable as a glass of congac, thanks so much. – Swiss Frank Oct 31 '19 at 0:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.