tags:

views:

207

answers:

2

In emacs, I want to bind a command to C-i. So I put (global-set-key "\C-i" 'forward-word)

in my .emacs file. This works, except now the TAB key is bound to 'forward-word as well.

How do I bind a command to C-i without changing TAB?

+14  A: 

In short, this should solve the problem for you:

(setq local-function-key-map (delq '(kp-tab . [9]) local-function-key-map))
(global-set-key (kbd "C-i") 'forward-word)

Longer version:

From the emacs lisp documentation on function keys:

In ASCII, C-i and are the same character. If the terminal can distinguish between them, Emacs conveys the distinction to Lisp programs by representing the former as the integer 9, and the latter as the symbol tab.

Most of the time, it's not useful to distinguish the two. So normally local-function-key-map (see Translation Keymaps) is set up to map tab into 9. Thus, a key binding for character code 9 (the character C-i) also applies to tab. Likewise for the other symbols in this group. The function read-char likewise converts these events into characters.

So, once you do the following, you can see the difference in the key bindings:

(setq local-function-key-map (delq '(kp-tab . [9]) local-function-key-map))

;; this is C-i
(global-set-key (kbd "C-i") (lambda () (interactive) (message "C-i"))) 
;; this is <tab> key
(global-set-key (kbd "<tab>") (lambda () (interactive) (message "<tab>")))

Note, each mode sets up the various TAB bindings differently, so you may need to do customization per mode that you care about.

Version Dependency:

The above works for Emacs 23.1. From the NEWS file:

Function key sequences are now mapped using `local-function-key-map', a new variable. This inherits from the global variable function-key-map, which is not used directly any more.

Which means, in versions 22 and earlier, you can get the same effect by using the variable function-key-map. I tested this and found it to work with Emacs 21.

(setq local-function-key-map (delq '(kp-tab . [9]) function-key-map))
(global-set-key (kbd "C-i") 'forward-word)
Trey Jackson
When I try this code, I get an error that local-function-key-map is void. Any thoughts on why it would be void?
Steve
@Steve The variable is defined in Emacs 23, I've updated the answer with a version for 22 and earlier.
Trey Jackson
A: 

I found this solution, after much pain, lost in the messages archives. It's simple, avoids conflicts with other modes, and is the only which worked for me:

;; Translate the problematic keys to the function key Hyper:
(keyboard-translate ?\C-i ?\H-i)
(keyboard-translate ?\C-m ?\H-m)
;; Rebind then accordantly: 
(global-set-key [?\H-m] 'delete-backward-char)
(global-set-key [?\H-i] 'iswitchb-buffer)
Caio