Consistent BackSpace and Delete Configuration

an alternative approach

http://www.ibb.net/~anne/keyboardprev.html

version 1.15


Main Page|The Alternative Way|Troubleshooting

Index

Introduction
 Introduction 
Configuration of environments...
 VT 
 terminfo 
 Xterm 
 X 
 Bash 
 Tcsh 
... and applications
 Apps-list 
athena-apps emacs joe jove kvt less login minicom mutt nedit netscape pico pine vi other

Introduction

This page includes all modifications needed to get the keys to work in all applications, except those that need to use ^H (jed, emacs...). This method was described and recommended in the Linux Journal (see the references). Personally, I don't think this method is recommendable anymore, although I do use it on some of my systems. It will break applications that need ^H for something other than [<---], and if you want to get everything right, you will have to edit terminfo entries anyway (dirty work arounds aside), so it's more work (well, actually, the terminfo entries are likely to be consistent with this approach, but it will be more work anyhow).

Many of the workarounds described below circumvent terminfo, presumably because a lot of them are broken and can't be relied upon. While this works well on your own system, it may cause others problems when they connect to your system (i.e. when they use a different keymapping), the reason why the terminfo database was made in the first place. Oh well... I am not sure what caused all this trouble, on the other hand, I am quite sure that many people disagree whatever you say or do. Anyway, this is listed as an alternative, and because it contains lots of hints that I don't mention on the other page.


The Virtual Terminal (kernel-level configuration)

1. find and edit custom.map

The first step is to change the kernel's keyboard translation table. If you load a keymap at boot time, read on, if not, apply the kernelpatch in the login section. Let's begin with finding the installed keymap. Different Linux-distributions put the system files in different places. Here are some suggestions for finding the keymap on your system. Type at the command line:

[localhost]> find /etc -type f | xargs grep loadkeys

If you see something like:

/etc/init.d/boot: loadkeys /usr/lib/kbd/keytables/us.map

You have actually found the keymap you were looking for. If not, you can also search for us.map with locate (provided it's installed and up-to-date):


[localhost]> locate us.map

On a RedHat system, type:

[localhost]> cat /etc/sysconfig/keyboard

and you'll probably find something like:

KEYTABLE="/usr/lib/kbd/keytables/us.map"

On a Debian system, copy /etc/kbd/default.map to custom.map. If it isn't there, there may be some maps in /usr/share/keytables, or you can copy /usr/src/linux/drivers/char/defkeymap.map to costum.map, and edit this file (provided you have installed the kernel-sources). Also check /usr/doc/kbd/. Alternatively, sit back, relax and fetch one of the following files: customus.map.tar.gz which is a modified us.map or a modified version of dk-latin1.map: customdk.map.tar.gz.

Be careful, it's possible to leave the keyboard in an unusable state if the instructions are not closely followed. Since you have copied the system keymap it's no problem, just reboot and the original keymap will be loaded. If you have edited the system keymap (without copying it) you will have to reboot using a boot flop. However, if you carefully follow the instructions you shouldn't worry. Find the following lines:



keycode 14 = Delete               Delete
        alt     keycode 14 = Meta_Delete
and replace them with:

keycode 14 = BackSpace            BackSpace
        alt     keycode 14 = Meta_BackSpace 

You also need a delete key, so find the line:

keycode 111 = Remove

and replace it with the lines:


keycode 111 = Delete          Delete
        alt     keycode 111 = Meta_Delete

2. optional editing of custom.map (recommended)

If you want to be able to generate characters such as àéáë in a very convenient way, you can add a compose key to your custom.map. To use the right control-key, add the line:


keycode  97 = Compose

Set the following environment variable (in /etc/profile, or /etc/csh.cshrc) for bash and tcsh:

for bash:   export LC_CTYPE=iso-8859-1

for tcsh:   set LC_CTYPE=iso-8859-1

Now you can generate (after loading custom.map) e.g. ø by pressing the right control key, slash (/), and o.

Also very nice: if you want CTRL-ALT-END to shut down linux (halting the system instead of rebooting) you can add the following to your custom.map:


# Numeric Keypad End
control alt        keycode 79 = KeyboardSignal
control altgr      keycode 79 = KeyboardSignal
# Editing keypad End
control alt        keycode 107 = KeyboardSignal
control altgr      keycode 107 = KeyboardSignal

Save the file, and edit /etc/inittab. Add or edit the following lines as shown:

# Action on special keypress (CTRL-ALT-END)
kb::kbrequest:/sbin/shutdown -h now

3. testing and installing custom.map

Now, type (as root):

[localhost]> loadkeys custom.map

If the new keytable works, install it permanently by putting it's location in /etc/sysconfig/keyboard for RedHat, or, on a Slackware system, copy the new keymap to /etc/rc.d/rc.keymap. On a Debian system, add the line loadkeys /etc/kbd/default.map to the /etc/init.d/boot boot script (provided the file you edited is placed in /etc/kbd/default.map of course). On other systems, by editing the boot script containing the loadkeys command. Well, that's it. Almost. You still need some shell specific modifications for bash and tcsh, and fiddle with xterm settings to get the keys right.


Terminfo

This can be a problem. If you find that the keys in e.g. vi are ok on the console but not in xterm, it means that the terminfo entry of xterm is not consistent with the keysettings. I am not really comfortable with telling you to fiddle with terminfo, please be careful, make backups! First find out wheter the terminfo entry for xterm is conform your xterm settings or not:
infocmp | grep kbs
should return a line which includes kbs=^H. This means DEL is mapped to the backspace key, which is what we want.
infocmp | grep kdch1
should return a line with kdch1=\177~. This means that \177 (or ^?) is mapped to the delete key. You may find kbs=\177 and/or kdch1=\E[3~, or there will be no kdch1 at all. You can either edit the terminfo entry as described on the Troubleshooting-page (simply setting or adding kdch1=\177 and kbs=^H, but make a backup first!)


Xterm

The xterm (and friends) only needs little configuration. In the /etc/X11/Xresources or ~/.Xdefaults add the line:


*ttyModes: erase ^H

Rxvt only uses Xresources if it is compiled with this option. Luckily, the key bindings are correct by default (however, since rxvt uses readline, to get home and end to work you will have to edit .inputrc, see the Bash section).

While you're at it, let's get the Home and End keys to work:


*vt100.translations: #override \
        <Key>Home:      string("\033[1~") \n\
        <Key>End:       string("\033[4~")

Putting xterm or nxterm in front of *vt100.translations makes the settings specific for xterm or nxterm.

BTW, have I told you that Ctrl-V <key> will tell you what sequence is sent to the shell? Try Ctrl-V <Delete>, it should give a ^? in your xterm or console.

Some notes:
1. Emacs resets the numeric keypad. In the emacs section you will find how this behavior can be corrected.
2. People have reported that the keypad-entry doesn't work with nxterm.
3. The syntax of the Xresources files is very strict, make sure you don't leave blank spaces after the backslash on each line. Also watch the newline (\n\) sequences, there shouldn't be one at the last line of an entry.
4. The sections are named, if you only use *VT100.Translations it will work for all xterm and friends.
5. For info about Xresources and other X related stuff try see 'man X'.


X

Ideally, it should not be necessary to change or use xmodmap at all. However, it can be useful to create an Xmodmap if you want the keyboard to generate special characters in X, xmodmap can also be used to configure the function-keys. This is adequately described in the 'man xmodmap'. Make sure that the following lines are included in your Xmodmap:

keycode 22 = BackSpace
keycode 107 = Delete

Note that the keycodes in X are not the same as in a VT. Use showkey to see the keycodes generated by the keyboard in a VT, and xev in X. There is a graphical front end for X-keyboard configuration: xkeycaps. Get the .rpm at RedHat Powertools, or get the Debian-package (or plain tarball).

Another way of generating special characters in X (without using xmodmap) is by defining a Compose-key (for use as a "dead key") in XF86Config in the Keyboard section:


  RightCtl        Compose

Now you have a compose-key with the same properties as the one described in the VT section. Remember to set the environment variable LC_CTYPE=iso-8859-1 (see VT optional...). Consult 'man XF86Config' if you want to know more. Note: this doesn't seem to work with nxterm... suggestions anyone?
Alternatively, owners of a windows keyboard (one with extra buttons, it need not be a M$ natural keyboard) can enable the XKEYBOARD extension (enabled per default) in XF86Config and uncomment the line (follow the instructions in the file):

  XkbModel    "microsoft" 

Now you can use the button with the windows flag on it to produce a great number of exotic characters, just press it in combination with e.g. a, producing á (a clear disadvantage is that there is no logic in the location of the special characters at all...).

Yet another way to use "dead keys" in X is by installing a modified version of libX11 which includes support for dead keys (transparent for all apps). First, get the modified version of libX11 (make sure you get the right version, if you use glibc replace both libX11, ELF-libc5 and ELF-libc6). Now, deactivate the XKB extension of XFree86 (edit XF86Config and run xmodmap on a Xmodmap file with dead keys like dead_acute, dead_grave, dead_cedilla, dead_ogonek and a Multi_keys one too.

A special case is if you use xdm, you need to deactivate XKB from the /etc/X11/xdm/Xservers file, passing a -kb parameter to the server like this:


:0 local /usr/X11R6/bin/X -kb
then in /etc/X11/xdm/Xsetup_0 file add a line to load the Xmodmap, like this:

if [ -r /etc/X11/xinit/.Xmodmap ]; then
        /usr/X11R6/bin/xmodmap /etc/X11/xinit/.Xmodmap
fi
Now chars accesible by AltGr, dead keys or compose are usable in xdm too.

Bash

Create a file, /etc/inputrc for system wide use and set the INPUTRC variable to point to it, or ~/.inputrc for personal use. Actually, this is the readline initialization file, readline is a library that some programs (bash, kvt) use to read input (try bind -v to see a list of readline key and function bindings). Cut and paste the following in the file to make the Delete key delete characters under the cursor, and make Home and End work as well. DEL works only if you've created and installed custom.map, if not you need "\e[3~": delete-char. However, kvt needs this no matter what you do with your keymap, so just throw them both in (if you try bind -v you'll see that some keys or functions can be found on 5 different sequences, this is perfectly ok...):


DEL: delete-char
# this is actally equivalent to "\C-?": delete-char
# VT
"\e[1~": beginning-of-line
"\e[4~": end-of-line
# kvt
"\e[3~": delete-char
"\e[H":beginning-of-line
"\e[F":end-of-line
# rxvt
"\e[7~":beginning-of-line
"\e[8~":end-of-line

If a system-wide /etc/inputrc was created, add the following line to /etc/profile:

export INPUTRC=/etc/inputrc

I wonder what's easier, cutting and pasting the above (and the international bit below) or (right/shift) clicking on inputrc to download the file...

Make sure that the stty erase character is set to ^H. Type

stty -a | grep erase

and check if it says

erase = ^H;

If it is set to something else (e.g. ^?) then put the following line in both .bashrc and in either .bash_profile or /etc/profile:


  if tty --quiet ; then
    stty erase '^H'
  fi

and for xterm and rxvt add this:

if [ "$TERM" = "xterm" -o "$TERM" = "xterm-color" -o "$TERM" = "rxvt" ];
then
   # activate keypad
   echo -en '\033>'
   # BackSpace sends ^H
   echo -en '\033[36h'
fi
            

If you create /etc/inputrc, note that Bash will ignore ~/.inputrc (currently this happens in all distributions except Debian, however, this might change in the future). As an alternative, you can edit ~/.inputrc, and copy this to /etc/skel/, so it's in the home directories of all new users.
Push the key-combination 'Ctrl-x-r' (push the control-key, the x-key. release it, push the r-key, release it, and then release the control-key) to see if the changes in inputrc take effect. Or just login again, and it will work. If it doesn't work, note the following:

if you leave alone the line

	keycode 111 = Remove
in your custom.map, the Delete key will return the ^[[3~ sequence, so you need to put
"\e[3~": delete-char
in your inputrc. If you change the "Remove" above to "Delete" as suggested, the Delete key will return \177, and you need to put
	DEL:	delete-char
in your inputrc (with readline, DEL is simply a shortcut for \177, which is the same as ^?). Make sure your custom.map works as intended by pressing Ctrl+v and <Delete>.

You can also change the keybindings on the fly with the bind command, e.g:

[localhost]> bind "\C-?": delete-char
This is useful to test different keybindings, if they work you can put them in ~/.inputrc. Read all about it in the readline manpage.

People using keymaps with e.g. Scandinavian characters who would like bash to display these characters (øl;-) have to add the following lines in .inputrc:
set convert-meta off
set output-meta on
set input-meta on

For more info, check the Danish-HOWTO.


Tcsh

If you use the tcsh shell, put the following lines in your /etc/cshrc or your personal ~/.cshrc file:

  if ($term == "xterm" || $term == "vt100" \
            || $term == "vt102" || $term !~ "con*") then
        # bind keypad keys for console, vt100, vt102, xterm
          bindkey "\e[2~" overwrite-mode    # Ins
          bindkey ^? delete-char            # Delete
          bindkey "\e[1~" beginning-of-line # Home
          bindkey "\e[4~" end-of-line       # End
      endif 

To see whether it works or not, type:

[localhost]> source .cshrc



Applications

athena-apps emacs joe jove kvt less
login minicom mutt nedit netscape pico pine

Athena Applications

For programs using the Athena widgets (xpaint, xbmbrowser, xman, xmh, xedit, pixmap, bitmap, editres...) put the following in .Xdefaults to get Delete to work:

*Text.translations:    #override \
        ~Shift ~Meta <Key>Delete: delete-next-character()


Emacs

There seem to be two ways, the first is to create a ~/.emacs file with keybindings, the other is to define the keys from within emacs. Both methods are described in the Key-Setup Mini-Howto. Either way, you will have to choose between losing the ``<Ctr-h> = help'' mapping and Backspace.

Emacs resets the numeric keypad when exiting, which means that the numeric keypad will no longer transmit escape sequences. However, this behavior can be corrected by removing the "rmkx" capability from the terminfo database (be careful, make a backup first and only attempt this if it bothers you...):

[localhost]> cd /usr/lib/terminfo/x (note: on some systems /etc/terminfo/x)
[localhost]> infocmp xterm > xterm.txt
[localhost]> emacs xterm.txt

Remove the "rmkx" entry, save the file and exit. Then:

[localhost]> tic xterm.txt
[localhost]> rm xterm.txt

Joe

First find the file joerc. It is most likely /usr/lib/joe/joerc, but sometimes /etc/joerc, or maybe even /usr/local/lib/joerc. Try 'locate joerc' if you can't find the file. Make a backup for safety, or copy it to .joerc in your home directory, and change the following lines in de section "Standard JOE user interface":

backs           ^?              Backspace
backs           ^H 

to:

 backs           ^?              Backspace
backs           ^H 
and add:

delch           ^?              # Del = Delete in default.map
delch           ^[ [ 3 ~        # Del = Remove in default.map
Note: the space in front of 'backs' disables this line.

Add the following lines to in the same section to enable the Home en End keys:


bol              ^[ [ H          # Standard xterm escape seq.
bol              ^[ [ 1 ~        # Standard VT escape seq.
bol              ^[ [ 7 ~        # rxvt
eol              ^[ [ F          # Standard xterm escape seq.
eol              ^[ [ 4 ~        # Standard VT escape seq.
eol              ^[ [ 8 ~        # rxvt

Note that you first have to make sure that Home and End work in an xterm. Check out 'man joe'. BTW, these modifications apply to jpicorc, jstarrc and jmacsrc as well.

Jove

To get the emacs-clone jove to get the key-thing right, add the following to joverc (/usr/lib/jove/ or /usr/local/lib/jove/):

bind-to-key delete-previous-character ^H
bind-to-key delete-next-character ^?

Thanks to James Murray.

Kvt

Kvt, KDE's rxvt-based xterminal, turned out to be a special case. Since it uses the readline library (see the Bash section) it can be easily configured. Add this (yes, regardless of what is already there...) to your ~/.inputrc (tcsh users too!):
"\e[3~":delete-char

It turns out kvt receives the "\e[3~" sequence regardless of the system keymap. Oh, don't forget to check that the following lines are present to make the Home and End keys do their job:
"\e[H":beginning-of-line
"\e[F":end-of-line

Less

Create a file, /etc/lesskey, for system-wide use. This will be a lesskey input file. Put the following lines in the file:

#line-edit
\177           delete
\e[1~          home
\e[4~          end

You can also add (may not be necessary since it is the default):

^H              BackSpace

Some people report using \e[3~ instead of \177 for delete. These people haven't modified the system keymap, and should do either that or look at the main page.
Save the file, and compile it as follows:

[localhost]> lesskey -o /etc/less /etc/lesskey

Add the following line to /etc/profile:

export LESS="-MM -k/etc/less"

Now type:

[localhost]> . /etc/profile

And the next time you use less Delete will delete, and BackSpace will backspace! In an ideal world, anyway. Actually, my system needed some additional modifications. To get it to work in a VT, I had to make sure that the stty erase character was set to ^H, please refer to the Bash section.

By fiddling with these settings you should be able to get less to accept (all of) the holy keycodes, at least, it works on my computer. For some exciting reading, check 'man lesskey'.

Login

Finally... the beast... our nemesis... the one that lurks from the dark, independent of any keymapping... or is it? No, but it takes a kernel patch to get this one to behave. Download this (right button...) kbdkrnlpatch and patch the kernel: cp and cd to /usr/src/ (yes, you have to have the source installed) and type: patch < kbdkrnlpatch (if you want to undo the patch, type patch -R < kbdkrnlpatch, which reverses the patch). Compile the kernel, and voila. This patch switches BS and DEL, in the same way as the edited keymap (custom.map) does. This actually means that you do not have to load a keymap at all, provided you are satisfied with the other keys of course:-) In addition to all this, the default erase character is changed to BS instead of DEL. NOTE: this patch is i386 specific, it will not work on other platforms. Thanks to Dick Streefland for the patch.

Minicom

Start minicom as root, entering the command:

[localhost]> minicom -s

Select "Screen and Keyboard" from the menu. Type "A", then press the space bar. Use "B" to determine what BackSpace should transmit. Since most remote systems will use Delete to erase to the left, "DEL" is probably the best choice here. If this creates a problem, change it to "BS". Press ESC when done. At the configuration menu, select "Save setup as dfl", then "Exit from Minicom".

Mutt

Mutt let's you use your favourite editor, however, you enter email addresses in mutt's editor, and you may like to delete characters every once in a while. Add the following to your ~/.muttrc:

bind editor      delete         delete-char

Nedit

Put the following in ~/.Xdefaults:

 nedit.remapDeleteKey: False

Save the file, and the next time you start nedit the Delete key will do what we want it to: delete under the cursor. Note: you can also put the line in ~/.nedit, but every time you save the default settings, the .nedit file will be overwritten, and you'll have to (n)edit it again.

Netscape

The keybindings of Motif-applications such as Netscape are configured correctly by default, so they should work after the VT-fix is applied. At least, if the XKeysymDB is installed (usually the case, although Slackware users may want to check this). Netscape looks for this file in /usr/X11R6/lib/X11/ or /usr/lib/X11/XKeysymDB (and some other places). If netscape still can't find the file set the XKEYSYMDB environment variable. Check the other page if you want more suggestions. If you use xmodmap, see X for more about xmodmap. Note: on LST Linux 2.2, uncomment the Xmotif Defaults section, in /usr/X11R6/x11/xinit/.Xresources. They make BackSpace and Delete do the same thing, so you'd better get rid of them.

Pico

Just use 'pico -d' instead of 'pico'. Add an alias to /etc/bashrc, /etc/cshrc, ~/.bashrc or ~/.cshrc.

Pine

In pine, go to 'Setup' and choose the 'Configure' option, and enable the compose-maps-delete-key-to-ctrl-d option. You can also use an alternate editor. Edit .pinerc and find the following lines:

# Specifies the program invoked by ^_ in the Composer,
# or the "enable-alternate-editor-implicitly" feature.
editor=

You can enter the command for any editor here, e.g. joe or vi.

If you want the editor to be started right away, start pine, enter SETUP and Config and select the enable-alternate-editor-implicitly option. Now the editor of choice will be started automagically when you start writing a message.
Another way to deal with pine is to switch to mutt, it's six times as small, and can do a lot more (colors, threadsupport, pgp... you name it). Sorry, just had to mention that.

Vi

Vi and derivatives (like vim, elvis, nvi) look at terminfo, so either you can fix the terminfo entry, on the console this will be the "linux" terminfo entry. Alternatively, you can try a dirty work around.

#!/bin/sh
$if TERM=linux
export TERM=vt100
endif
exec vi "$@"
Now you can make an alias pointing to the wrapper. If you have problems in xterms, you can try to change linux to xterm.

Other

Whatever method you use to map the keys, you can run into trouble when somebody decides to do it differently on his system, and you want to connect with it. Luckily this is easily worked around. Create the following script, let's call it kbdfiks and make it executable (make sure you have expect installed on your system).
#!/usr/bin/expect

eval spawn -noecho $argv

interact {
 \010        {send "\177"}
 \177        {send "\033\[3~"}
}
Now type kbdfiks telnet brokenhost and the keys will work. Thanks to Philip Hands for this clever workaround.

This page is maintained by Anne Baretta (anne@ibb.net).