How to fix the backspace/ruboff key in Emacs/Xterm
There is a good amount of documentation available on the web regarding backspace/ruboff and delete key issues. Check the References for detailed information. Go to The Best Solution for a quick fix.
The Problem
If Emacs recognizes the key normally above the enter/return key (that produces a delete to the left) as sending the help command rather than the delete to the left command, then you are experiencing this problem. This key is typically called the backspace key, neutrally known as the ruboff key. Throughout the rest of this document it will be referred to as the backspace key. The delete key will refer to the key that says "delete" or "del" on it and is expected to delete the character to the right.
Introduction
It is helpful to note the ASCII codes that will be discussed. ASCII char BS is 08 in decimal, 0x08 in hex, and alternatively '^H'. ASCII char DEL is 127 in decimal, 0x7f in hex, and alternatively '^?'. In Xterm's emulate of the vt100 terminal it sends '^H' (0x08) when the backspace key is hit, "\e[3~" when the delete key is hit, and '^H' (0x08) when ctrl-h is hit. Some programs, such as Emacs, want to use '^H' (0x08) for commands other than delete. To work around this problem the key-map in Emacs either has to be changed to accept '^H' as delete left or Xterm should send '^?' to delete to the left and tty should be told to expect '^?' as meaning delete left. The solutions shown in the next section address changing Emacs key-map, getting Xterm to send the different key codes, and setting stty's variables.
Note that you can type ctrl-v followed by a key on the keyboard to show what key code is being sent for that key. When this is done its representation of "\e[3~" is "^[[3~" for the delete key. The xev command is a X tool to show what keycodes are being sent.
Different Solutions to the Problem
There are several methods of fixing or altering the behavior of the backspace key. The solutions listed here are either partial solutions or less optimal than preferred. They have been included to provide more insight into altering the keycodes are sent and how they are interpreted by the console and applications. Please look at the best solution for the preferred fix.
Changing Xterm's backarrowKey variable
One way to fix the immediate problem of your backspace key sending '^H' (bringing up help in emacs instead of doing a left delete) is to change the backarrowKey variable in Xterm. By default the backarrowKey variable is set to true and Xterm sends '^H', ASCII value 8. When set to false it will send '^?', ASCII value 127.
- To set it to false while running Xterm, hold down the ctrl key and left click with the mouse (Note that middle and right clicking also bring up options). If backarrowKey is set to true there should be a check mark by "Backarrow Key(BS/DEL)". Remove this and see if backspace performs delete left in emacs.
- To set it to false when Xterm starts up add the following lines to .Xdefaults. It can alternatively be added to .Xresources, but .Xresources is normally read when the window manager starts up and .Xdefaults is read for each application that starts up and checks for variables, so it is best to add it to .Xdefaults.
xterm.*backarrowKey: false
|
- Yet another way of changing the value of backarrowKey is to hold ctrl when hitting backspace. This tells Xterm to swap the value of backarrowKey, hence changing backspace's behavior.
These solutions, however, may cause other problems. For example, other applications may suffer from a similar problem that Emacs was having and output the '^?' character to the screen. As for holding down ctrl every time you hit backspace, that is an unnecessary annoyance.
Using stty to view and change the erase variable
stty is a tool for changing and viewing the terminal settings. Many programs use stty's settings so see what keys are mapped to what. In the previous examples where we changed the value of backarrowKey any programs that output '^?' after setting backarrowKey to false did so because they expected '^H' or another key to be delete left. The program may have been looking at stty's erase variable to find out what key is delete left and if so stty's erase was set to something other than '^?', probably '^H'. To see what erase is set to enter the command:
The output will look something like this:
$ stty -a
speed 38400 baud; rows 28; columns 82; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ;
eol2 = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
|
What follows the erase variable is the value that the terminal is expecting backspace to send. If that is different than what backspace sends, any program that gets its information from they stty settings will not recognize backspace as delete left. That is unless the program is specifically coded to delete left with the value that backspace is sending. So if your backspace sends '^?' and stty shows "erase = ^H" then a program that reads the erase value is not going to know what to do with '^?'. Therefore, you will want stty's erase variable to be set to '^?'. You can do this with the command:
tset (used for setting terminal settings) will also work:
Altering mapped keys in Emacs
It is possible to remap what keys execute what command. The following examples do the same thing, interchange Delete and Backspace, but only the very bottom one works in all version of Emacs.
This option only works in Emacs version 21 or greater. While in Emacs type:
M-x normal-erase-is-backspace-mode
|
Or in your .emacs file, which is located in your home directory add:
(normal-erase-is-backspace-mode 1)
|
In versions <= 20 try adding this to your .emacs file (1):
(keyboard-translate ?\C-h ?\C-?)
(keyboard-translate ?\C-? ?\C-h)
|
And in very old versions of Emacs none of the above may work. Add this into your .emacs file (1):
(setq keyboard-translate-table (make-string 128 0))
(let ((i 0))
(while (< i 128)
(aset keyboard-translate-table i i)
(setq i (1+ i))))
(aset keyboard-translate-table ?\b ?\^?)
(aset keyboard-translate-table ?\^? ?\b)
|
The Best Solution
After reading the above it makes sense to set xterm.*backarrowKey: false in your .Xdefaults file and set stty's erase variable to '^?'. This will work, however, overriding key translations is usually chosen over changing the backarrowKey variable. Add these lines to your .Xdefaults:
XTerm*ttyModes: erase ^?
XTerm*VT100.Translations: \
#override <Key>BackSpace: string(0x7f) \n\
<Key>Delete: string(0x1b) string("[3~")
|
If you choose to add the above to your .Xresources instead of .Xdefaults add these lines to .xinitrc:
This ensures that .Xresources is merged into the keycode database. This will only happen when X is started so make sure to restart X before expecting it to work.
If you want these setting to be applied for all programs, not just XTerm, you can leave off the XTerm in front of the *VT100 and *ttyModes. If you are having trouble with your Home and End keys you can also add translations for them. Here is an example of general setting and remapping Home and End:
*ttyModes: erase ^?
*VT100.Translations: \
#override <Key>BackSpace: string(0x7f) \n\
<Key>Delete: string(0x1b) string("[3~") \n\
<Key>Home: string("\033[1~") \n\
<Key>End: string("\033[4~")
|
References
- The Linux keyboard and console HOWTO
- Consistent BackSpace and Delete Configuration
- XTERM - Frequently Asked Questions (FAQ)
- GNU Emacs Manual: AD.9.1 If DEL Fails to Delete
- (emacs)DEL Does Not Delete
- Re: fixing backspace and delete
- man STTY(1)
- man XTERM(1)
- man TERMINFO(5)
- man TSET(1)
Corrections, comments, questions e-mail scott@hypexr.org Last Modified:
April 15 2006.
Top of Page
|