Problem with Ctrl tab keybinding in Emacs in gnome-terminal

I want to be able to flip back and forwards between two buffers in Emacs in the same way I can flip between tabs in some other editors. The following Ctrl + TAB key binding works nicely in XEmacs:

(defun buffer-shimmy ()
  "Back to the previous buffer"
  (interactive)
  (let ((buff (car (buffer-list))))
    (message "Previous buffer: %s" buff)
    (switch-to-buffer (other-buffer buff))
   )
)
(global-set-key (kbd "<C-tab>") 'buffer-shimmy)
;; or (define-key global-map [(control tab)] 'buffer-shimmy) 

However, it doesn't work when I open Emacs using "emacs -nw" (or if I'm using Emacs in an SSH session).

After finding this link - I think perhaps what I want is not possible?

Apparently, in the terminal (i.e. outside the Windowing system) adding a control modifier to the ASCII character for 'TAB' is nonsensical. Whereas, if going via a windowing system, Emacs can see you pressing Ctrl + TAB as <tab> with a control modifier, which can be represented in the .emacs file as C-<tab> or <C-tab> or [(control tab)].

Is there a workaround that fixes this issue?

Reference software: Emacs version: 22.2.1 on Ubuntu 9.04 using gnome-terminal with the default profile.


Unfortunately, there is no one size fits all solution to this for the emacs client running in a terminal window. The issue comes up because the <TAB> character is defined as CTRL-I, so CTRL-<TAB> would mean CTRL-CTRL-I, and so is not possible.

When emacs is running in windowed mode, it receives its input directly from key presses. When it is run inside a terminal (or if it will make things clearer why it doesn't work - on an ssh connection), the input comes from the terminal I/O. It is the terminal program that reads the hardware key events, and it generates the input stream (not very accurate, but highlights the issue). Emacs reads the input stream and converts to keypress events. Since emacs cannot access the hardware key events, it is bound by the restrictions of the terminal environment.

For some terminal programs, it may be possible to generate a custom input sequence (such as when you press F1) when you press CTRL-<Tab>, which could then be interpreted by Emacs as CTRL-<Tab>. An example snippet to do it for CTRL-<Home> is:

(when (not window-system)
  ; Fixup missing console keys
  (define-key key-translation-map (kbd "M-[ 4 ^") (kbd "C-<end>"))
  (define-key key-translation-map (kbd "M-[ 1 ^") (kbd "C-<home>")))

In this example, M-[ 1 ^ is the input sequence generated when I press CTRL-<Home> in my terminal.

It is not a very portable solution (I mainly use putty to access my linux box from windows, and it doesn't allow it), so your mileage may vary.

In the end, I've decided to use another key binding on my .emacs, and let the muscle memory of CTRL-<TAB> die off.