LDP/LDP/howto/docbook/BackspaceDelete.sgml

739 lines
34 KiB
Plaintext

<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
<article class="TECHREPORT" id="index" lang="en">
<artheader>
<title>Linux <keycap>Backspace</keycap>/<keycap>Delete</keycap> mini-HOWTO</title>
<author>
<firstname>Sebastiano</firstname>
<surname>Vigna</surname>
<affiliation>
<address><email>vigna@acm.org</email></address>
</affiliation>
</author>
<revhistory>
<revision>
<revnumber>v1.6</revnumber>
<date>19 Jan 2002</date>
<revremark>Included many comments from Alex Boldt and Chung-Rui Kao.</revremark>
</revision>
<revision>
<revnumber>v1.5</revnumber>
<date>3 May 2000</date>
<revremark>Updated for new distros and the tput trick.</revremark>
</revision>
<revision>
<revnumber>v1.4</revnumber>
<date>7 December 2000</date>
<revremark>Updated for Red Hat 7.0 and Helix Gnome conflicts.</revremark>
</revision>
<revision>
<revnumber>v1.3</revnumber>
<date>18 October 2000</date>
<revremark>Name change.</revremark>
</revision>
<revision>
<revnumber>v1.2</revnumber> <date>15 October 2000</date>
<revremark>
Updated. Added "What If Nothing Works" section.
</revremark>
</revision>
<revision>
<revnumber>v1.1</revnumber> <date>13 September 2000</date>
<revremark>
Added tcsh fixes
</revremark>
</revision>
<revision>
<revnumber>v1.0</revnumber> <date>5 September 2000</date>
<revremark>
First release
</revremark>
</revision>
</revhistory>
</artheader>
<sect1 id="intro">
<title>Introduction</title>
<para>Every Linux user has been sooner or later trapped in a situation in
which having working <keycap>Backspace</keycap> and <keycap>Delete</keycap>
keys on the console and on X seemed impossible. This paper explains why
this happens and suggests solutions. The notions given here are essentially
distribution-independent: due to the widely different content of system
configuration files in each distribution, I will try to give the reader
enough knowledge to think up his/her own fixes, if necessary.</para>
<para>I assume that the <keycap>Backspace</keycap> key should go back one
character and then erase the character under the cursor. On the other hand,
the <keycap>Delete</keycap> key should delete the character under the
cursor, without moving it. If you think that the function of the two keys
should be exchanged, in spite of the fact that most keyboards feature an
arrow pointing to the <emphasis>left</emphasis> (<keycap>&larr;</keycap>)
on the <keycap>Backspace</keycap> key, then this paper will not give you
immediate solutions, but certainly you may find the explanations given here
useful.</para>
<para>Another assumption is that the fixes should alter only local (user)
files. No standard part of the distribution should be altered. Finally,
this document discusses how to set up your system so that applications get
the right events. If an application decides to interpret such events in an
idiosyncratic way, the only possible fix is to reconfigure the
application.</para>
<note>
<para>Since the first release of this Mini-HOWTO things have become even
more entangled. Different distributions of the same terminal emulator
(e.g., <application>gnome-terminal</application> as provided by Red Hat
7.0, Helix Code/Ximian or even Red Hat&ge;7.1) generate different
<ACRONYM>ASCII</ACRONYM> sequences. Due to this mismatch, now the terminal
databases correspond even less to the terminal emulators they are supposed
to describe. To set a firm ground for the following discussion, we assume
basically as correct settings the ones proposed in the <ulink
url="http://www.debian.org/doc/debian-policy/">Debian keyboard
policy</ulink>.</para>
</note>
</sect1>
<sect1 id="actions">
<title>How Keys Are Turned Into Actions</title>
<para>When a key is pressed on the keyboard, a number of hardware and
software components cooperate so as to guarantee that the intended meaning
of the key (e.g., emitting a certain character) matches the actual
behaviour of the key. I will concentrate on the software side (as our
control on the hardware part is nonexistent), and in particular, for the
time being, on the events related to console output.</para>
<orderedlist>
<listitem>
<para>Hitting a key causes raw keyboard <firstterm>scancodes</firstterm>
to be generated; these scancodes are then transformed in a
<firstterm>keycode</firstterm>. On an i386 system, usually the key
<keycap>Backspace</keycap> emits <keycode>14</keycode> and the key
<keycap>Delete</keycap> emits <keycode>111</keycode>.</para>
</listitem>
<listitem>
<para>The keycodes are translated by the keyboard library into a
<firstterm>keyboard symbol (keysym)</firstterm> using the keyboard
definition loaded by the user. If you look into your keyboard database
(e.g., in <filename>/lib/kbd/</filename>), you'll discover several
definitions for different computers, different layouts and possibly
different interpretations of the same keys (e.g., one could desire that
the two <keycap>Alt</keycap> keys really behave as distinct
modifiers). The Linux console keyboard layout assigns keysym
<keysym>Delete</keysym> to keycode 14 and keysym
<keysym>Remove</keysym> to keycode 111. This may seem strange, but the
Linux console emulates a VT100 terminal, and this is the way things
work in that realm.<footnote><para>This claim has been
asserted/disputed several times commenting this document. If you have
any definitive information on this subject, please write me.</para></footnote></para>
</listitem>
<listitem>
<para>Our journey has still to come to an end. Console applications
read <acronym>ASCII</acronym> sequences, not keysyms. So the console
must read keysyms and translate them into <acronym>ASCII</acronym>
sequences that suitably encode the keys. Of course, this operation must
be performed in a way that is understandable by applications. For
instance, on the Linux console the <keysym>Delete</keysym> keysym is
mapped to the <acronym>ASCII</acronym> code 127 (<symbol>DEL</symbol>),
the <keysym>Remove</keysym> keysym on a suitable escape sequence, and
the <keysym>BackSpace</keysym> keysym to <acronym>ASCII</acronym> code
8 (<symbol>BS</symbol>).</para>
</listitem>
<listitem>
<para>Finally, we must in a sense roll back to what we had before and
translate the <acronym>ASCII</acronym> sequences generated by each key
into a <firstterm>key capability</firstterm>. This goal is reached by a
<firstterm>terminal database</firstterm>, which contains, for each kind
of terminal, a reverse mapping from sequences of characters to key
capabilities (which are essentially a subset of the keysyms).<footnote>
<para>Some programs rely on the terminal driver for input line editing,
such as deleting characters or words. With <command>stty</command>, you
can tell the terminal driver what character it should use to delete the
character to the left of the cursor (the <firstterm>erase</firstterm>
character). You can check your current settings with <command>stty
-a</command> and set them with <command>stty erase
<replaceable>character</replaceable></command>.</para></footnote></para>
<note>
<para>Unfortunately, there are two <quote>standard</quote> terminal
databases, <application>termcap</application> and
<application>terminfo</application>. Depending on your distribution,
you could be using either one of them, or the database could even
depend on the application. Our discussion will concentrate on the
more modern <application>terminfo</application> database, but the
suggested fixes take both into consideration. </para>
</note>
<para>For instance, on the Linux console <keycap>F1</keycap> generates
an escape followed by <literal>[[A</literal>, which can be translated
to the capability <literal>key_f1</literal> by looking into the
terminal-database entry of the console (try <command>infocmp
linux</command> if you want to have a look at the entry). A very good
and thorough discussion of terminal databases can be found in
<acronym>GNU</acronym>'s <application>termcap</application>
manual. Usually Linux applications use the newer
<application>terminfo</application> database, contained in the
<application>ncurses</application> package.</para>
<para>Maybe at this point not surprisingly, the Linux console terminfo
entry maps <symbol>DEL</symbol> to the <literal>kbs</literal>
(backspace key) capability, and escape followed by
<literal>[3~</literal> to the <literal>kdch1</literal>
(<quote>delete-one-char</quote> key) capability. Even if you could
find strange that the <keycap>Backspace</keycap> key emits a <symbol>DEL</symbol>,
the terminal database puts everything back into its right place, and correctly
behaving applications will interpret <symbol>DEL</symbol> as the capability
<literal>kbs</literal>, thus deleting the character to the left of the cursor.</para>
</listitem>
</orderedlist>
</sect1>
<sect1 id="why">
<title>Why It Doesn't (Always) Work</title>
<para>I hope the basic problem is clear at this point: there is a
bottleneck between the keyboard and console applications, that is, the fact
that they can only communicate by <acronym>ASCII</acronym> sequences. So
special keys must be first translated from keysyms to sequences, and then
from sequences to key capabilities. Since different consoles have different
ideas about what this translation can look like, we need a terminal
database. The system would work flawlessly, except for a small problem: it
is not always set up correctly, and not everyone uses it.
</para>
<para>Applications must have a way to know which database entry to use:
this is accomplished by suitably setting the <envar>TERM</envar>
environment variable. In some cases, there is a mismatch between the
terminal emulator and the content of the database entry suggested by
<envar>TERM</envar>.</para>
<para>Moreover, many applications <emphasis>do not use</emphasis> the
terminal database (or at least not all of it), and consider
<symbol>BS</symbol> and <symbol>DEL</symbol> <acronym>ASCII</acronym> codes
with an intended meaning: thus, without looking at the database, they
assign them semantics (usually, of course, the semantics is removing the
character before or under the cursor). So now our beautiful scheme is
completely broken (as every Linux user is bitterly aware). For instance,
the <application>bash</application> assumes that <symbol>DEL</symbol>
should do a <action>backward-delete-char</action>, that is,
backspace. Hence, on a fresh install the <keycap>Backspace</keycap>
key works on the console as expected, but just because of two twists in a
row! Of course, the <keycap>Delete</keycap> key does not work. This happens
because the <application>bash</application> does not look into the terminal
database for the <literal>kdch1</literal> capability.</para>
<para>Just to illustrate how things have become entangled, consider the
<command>fix_bs_and_del</command> script provided with the Red Hat
distribution (and maybe others). It assigns on-the-fly the
<keysym>BackSpace</keysym> keysym to the <keycap>Backspace</keycap> key,
and the <keysym>Delete</keysym> keysym to the <keycap>Delete</keycap>
key. Now the shell works! Unfortunately, all programs relying on the
correct coupling of keysym generation and terminal database mappings are
now not working at all, as the <keysym>Delete</keysym> keysym is mapped to
<symbol>DEL</symbol>, and the latter to the <literal>kbs</literal> key
capability by the terminfo database, so in such programs both keys produce
backspacing.</para>
</sect1>
<sect1 id="X">
<title>X</title>
<para>The situation under X is not really different. There is just a
different layer, that is, the X window system translates the scancodes into
its own keysyms, which are much more varied and precise than the console
ones, and feeds them into applications (by the way, this is the reason why
<application>XEmacs</application> is not plagued by the problem: X
translates keycode 22 to keysym <keysym>BackSpace</keysym> and keycode 107
to keysym <keysym>Delete</keysym>, and then the user can easily assign to
those keysyms the desired behaviour). Of course, a terminal emulator
program (usually a VT100 emulator in the X world) must translate the
X keysyms into ASCII sequences, so we are again in our sore
business.</para>
<para>More in detail, usually <application>xterm</application> behaves
exactly like the console (i.e., it emits the same <acronym>ASCII</acronym>
sequences), but, for instance, <application>gnome-terminal</application> in
Red Hat <7.0 or &ge;7.1 emits <symbol>BS</symbol> for
<keycap>Backspace</keycap> and <symbol>DEL</symbol> for
<keycap>Delete</keycap>. The real fun starts when you realise that by
default they use the <emphasis>same</emphasis> terminal-database entry, so
the fact that the <literal>kbs</literal> capability is associated to an
<acronym>ASCII</acronym> <symbol>DEL</symbol> makes all correctly behaving
applications produce the same behaviour for the <keycap>Backspace</keycap>
and <keycap>Delete</keycap> keys in
<application>gnome-terminal</application>. The simple statement
<screen>
bash$ export TERM=gnome
</screen> can solve the problem in this case for
correctly behaving applications. Well, not always, because your system
could lack an entry in the terminal database named
<literal>gnome</literal>, in particular if it is not very up-to-date.</para>
<para>In any case, this is not always a solution: if, for instance, you
have a Red Hat 7.0 distribution, your
<application>gnome-terminal</application> behaves like a console. But
beware: if you upgraded your desktop using the Helix distribution, then
your <application>gnome-terminal</application> behaves like a pre-7.0 Red
Hat.</para>
<para>Just to make easier the following discussion, let us define
<firstterm>standard</firstterm> a VT100 emulator behaving like the console,
and <firstterm>deviant</firstterm> one that emits <symbol>BS</symbol> for
<keycap>Backspace</keycap> and <symbol>DEL</symbol> for
<keycap>Delete</keycap>.<footnote><para>Also these definitions have been
asserted/disputed several times commenting this document. If you have any
definitive information on this subject, please write me.</para></footnote>
Thus, for instance, <application>xterm</application> has always been
standard in the Debian distribution, while it switched a couple of times
from standard to deviant and viceversa in Red Hat; the behaviour of
<application>gnome-terminal</application> is even more erratic. See <xref
linkend="morehack"> for some information on how to turn a deviant terminal
into a standard one.</para>
</sect1>
<sect1 id="writing">
<title>What You Should Do When Writing Applications</title>
<para>When you write a console application, be kind to the user and try to
understand what comes from the standard input using the following fallback
chain:</para>
<orderedlist>
<listitem>
<para>open the right <application>terminfo</application> entry, and try
to process the sequence so as to discover whether it has a particular
meaning on the current terminal; if so, use the
<application>terminfo</application> semantics;</para>
</listitem>
<listitem>
<para>use the <acronym>ASCII</acronym> intended meaning on line feeds,
newlines, tab characters and, of course, <symbol>BS</symbol> and
<symbol>DEL</symbol>. Crossing your finger could also be useful.</para>
</listitem>
</orderedlist>
</sect1>
<sect1 id="system">
<title>What You Should Do On Your System</title>
<para>Note again that the main issue that confuses people trying to fix
their system is that usually they are fixing thing in the wrong
place. Since the parts that work often just work by chance, trying to fix
the system assuming something is broken will often lead to change correct
settings into incorrect settings.</para>
<sect2>
<title>What Needs to Be Done</title>
<sect3 id="deviance">
<title>Detecting Deviance</title>
<para>The first step towards a clean solution is to know exactly which
terminals are deviant and which not. Usually they all behave like the
console, and in this case the modifications to get everything working
are minimal. If, however, you have some deviant terminal (e.g., a
deviant version of <application>gnome-terminal</application>), you will
have to treat it in a special way.</para>
<para>The following C one-liner
<programlisting width=70>
void main(void) {int c; while(c = getchar()) printf("%d 0x%02X\n", c, c);}
</programlisting>
may help you. Put the line into a file named <filename>ascii.c</filename>,
compile it with <command>gcc ascii.c -o ascii</command>, type
<command>./ascii</command> and press a key followed by <keycap>RETURN</keycap>.
The program will display the decimal and hexadecimal codes of the
<acronym>ASCII</acronym> sequence produced (you may want to do a <command>stty
erase ^-</command> first to get really all the codes). Now you can easily see
what <keycap>Backspace</keycap> key does: if it emits a <symbol>DEL</symbol>
(127), you have a standard emulator, if it emits a <symbol>BS</symbol> (8) you have
a deviant one.
</para>
</sect3>
<sect3>
<title>Distinguishing Between Emulators</title>
<para>If you have some deviant terminal emulator, you must distinguish
it from the standard ones. Theoretically, this should not be a problem
because there are different entries in the terminal database for
terminals with different sequences (the entry used depends on the value
of the <envar>TERM</envar> variable).</para>
<para>Here we take the approach that the <literal>gnome</literal> entry
should be used for all deviant VT100 emulators, and the
<literal>xterm</literal> entry for the standard ones. This is in line
with several distributions (except a few cases like RedHat &le;5.0,
where the <literal>xterm</literal> entry is deviant).</para>
<para>However, <application>gnome-terminal</application> uses by
default the same entry as <application>xterm</application>, so if one
is deviant and the other one is not you will need to find a way to tell
them apart. The option <literal>termname</literal> of
<application>gnome-terminal</application> allows the user to set the
<envar>TERM</envar> variable to a more sensible name. However, in older
versions of <application>gnome-terminal</application> the option does
not work. Moreover, sometimes it is not easy to modify the way
<application>gnome-terminal</application> is started.</para>
<para>A good idea here is to exploit the fact that
<application>gnome-terminal</application> sets the
<envar>COLORTERM</envar> variable to
<literal>gnome-terminal</literal>. Thus, by adding a simple test to the
shell configuration files we can fix the <envar>TERM</envar>
variable.</para>
</sect3>
<sect3>
<title>Fixing the Terminal Database</title>
<para>Our problem now is that the terminal database could lack a
<literal>gnome</literal> entry for deviant terminals (this happens on a
number of <application>termcap</application> and
<application>terminfo</application> versions). Recent
<application>terminfo</application> databases have an entry
<literal>gnome</literal>, but, in any case, since
<application>gnome-terminal</application> behaves essentially like
<application>xterm</application> modulo our famous two keys, it is
possible to automagically generate a brand new correct entry.</para>
</sect3>
<sect3>
<title>Fixing the Shell Behaviour</title>
<para>The <application>readline</application> library used by the
<application>bash</application> and by many other programs to read the
input line can be customized so to recognize specific sequences of
characters. The customization can also depend on the
<envar>TERM</envar> variable, so once we can distinguish terminals we
can do fine tuning of the keyboard.</para>
<para>Moreover, if you want <application>less</application> and other
application that do raw line input to work correctly, you must convince
the shell that under a deviant terminal emulator the erase character is
<symbol>BS</symbol>, and not <symbol>DEL</symbol> (in the other case
the <keycap>Backspace</keycap> key is already emitting
<symbol>DEL</symbol>, so we do not have to do anything). This can be
done using the command <command>stty</command>.</para>
</sect3>
</sect2>
<sect2>
<title>How to Do It</title>
<caution>
<para>These fixes have some drawbacks. First, they work only for the
specified terminals. Second, in theory (but this is unlikely to happen)
they could confuse the <application>readline</application> library on
other terminals. Both limitations are however mostly harmless.</para>
</caution>
<para>First of all, check with <command>infocmp gnome</command>
whether you already have a <literal>gnome</literal> entry in your
<application>terminfo</application> database (we will fix
<application>termcap</application> later). If the entry does not exist,
the following command
<programlisting>
bash$ tic <(infocmp xterm |\
sed 's/xterm|/gnome|/' |\
sed 's/kbs=\\177,/kbs=^H,/' |\
sed 's/kdch1=\\E\[3~,/kdch1=\\177,/')
</programlisting>
will create a correct one in <filename>~/.terminfo</filename>. If the same
command is launched by the root, it will generate the entry in the global
database (you can override this behaviour by setting <envar>TERMINFO</envar> to
<filename>~/.terminfo</filename>). Note that if your <literal>xterm</literal>
entry is already deviant (e.g., you have a Red Hat &le;5.0) the script will copy it unchanged, which is
exactly what we want.</para>
<para>Now, add the following snippet to
<filename>~/.inputrc</filename><footnote id=addinputrc><para>On older
version of the <application>bash</application>, you must remember to set
<envar>INPUTRC</envar> suitably, for instance adding
<programlisting>
export INPUTRC=~/.inputrc
</programlisting> to your
<filename>~/.profile</filename> (or whichever file is read just by login
shells).</para></footnote>:
<programlisting>
"\e[3~": delete-char
</programlisting>
This line teaches the <application>readline</application> library how to
manage your standard <keycap>Delete</keycap> key for standard emulators,
and with a bit of luck it should not interfere with other
terminals. However, now we must also explain to the library the meaning
of the <symbol>DEL</symbol> character on deviant terminals, for instance
by adding
<programlisting>
$if term=gnome
DEL: delete-char
Meta-DEL: kill-word
"\M-\C-?": kill-word
$endif
</programlisting>
to <filename>~/.inputrc</filename>. If <application>xterm</application>
is deviant, too, you must add other three lines for it. On the other
hand, if no terminal emulator is deviant this part is not needed. All
these changes can be made global by altering the
<filename>/etc/inputrc</filename> file.</para>
<para>Note that the conditional assignments make deviant terminal
emulators work <emphasis>given that the <envar>TERM</envar> variable is
set correctly</emphasis>. To guarantee this, there are a number of
techniques. First of all, since the default value of the
<envar>TERM</envar> variable for
<application>gnome-terminal</application> is <literal>xterm</literal>, if
all terminals are not deviant then we do nothing. If, however, a terminal
that by default uses the <literal>xterm</literal> entry is deviant you
must find a way to set the <envar>TERM</envar> variable correctly; assume
for instance this is true of
<application>gnome-terminal</application>.</para>
<para>The simplest way to obtain this effect is to start
<application>gnome-terminal</application> with the argument
<literal>--termname=gnome</literal>, for instance by suitably setting the
command line in the launcher on the <acronym>GNOME</acronym> panel. If
however you have an old version, and this method does not work, you can
add the lines
<programlisting>
if [ "$COLORTERM" = "gnome-terminal" ]
then
export TERM=gnome
fi
</programlisting>
to your <filename>~/.bashrc</filename> configuration file<footnote><para>More
precisely, to the shell configuration file that is read in every shell, not
only in login shells. The right file depend on startup sequence of your
<application>bash</application>.</para></footnote>. The assignment is executed
only under <application>gnome-terminal</application>, and sets correctly the
<envar>TERM</envar> variable.</para>
<note><para>Setting the terminal to <literal>gnome</literal> could prevent
<command>ls</command> from using colours, as many versions of
<command>ls</command> do not know that
<application>gnome-terminal</application> is colour capable. To avoid this
problem, create a configuration file <filename>~/.dircolors</filename> with
<command>dircolors --print-database &gt;~/.dircolors</command>, and add a line
<userinput>TERM=gnome</userinput> to the configuration file.</para></note>
<para>We will now generate on-the-fly a suitable
<application>termcap</application> entry for deviant terminal emulators; this
can be done as follows, always in <filename>~/.bashrc</filename>:
<programlisting>
if [ "$TERM" = "gnome" ]
then
export TERMCAP=$(infocmp -C gnome | grep -v '^#' | \
tr '\n\t' ' ' | sed 's/\\ //g' | sed s/::/:/g)
fi
</programlisting></para>
<para>Finally, we must explain to the terminal device which character is
generated by the erase key. Since usually the erase key is expected to
backspace, there is a nice trick taken from the Red Hat
<filename>/etc/bashrc</filename> that works: add this to
<filename>~/.bashrc</filename>:
<programlisting>
KBS=$(tput kbs)
if [ ${#KBS} -eq 1 ]; then stty erase $KBS; fi
</programlisting>
It's a simple idea: we read from the terminal database the capability
<literal>kbs</literal>, and set the erase character to its value if it is a
single character (which happens in both standard and deviant terminals).</para>
<note>
<para>Certain distributions could have fixes already in place in the
system-wide <filename>/etc/inputrc</filename> configuration file. In
this case you can eliminate redundant lines from your
<filename>~/.inputrc</filename>.</para>
</note>
</sect2>
<sect2>
<title>Fixing for <application>tcsh</application></title>
<para>In the case of the <application>tcsh</application>, the fixes go
all in <filename>~/.tcshrc</filename>, and follow the same rationale as the ones for the
<application>bash</application>:
<programlisting width=80>
bindkey "^[[3~" delete-char
if ($?COLORTERM) then
if ($COLORTERM == "gnome-terminal") then
setenv TERM gnome
endif
endif
if ($?TERM) then
if ($TERM == "gnome") then
setenv TERMCAP \
"`infocmp -C gnome | grep -v '^#' | tr '\n\t' ' ' | sed 's/\\ //g' | sed s/::/:/g`"
bindkey "^?" delete-char
bindkey "^[^?" delete-word
bindkey "\377" delete-word
endif
endif
set KBS=`tput kbs`
if (${%KBS} == 1) then
stty erase $KBS
endif
</programlisting>
The second part must be replicated for every deviant terminal. Of course, if a
<application>termcap</application> entry already exists it is not necessary to
generate it.
</para>
</sect2>
</sect1>
<sect1 id="notwork">
<title>What If Nothing Works</title>
<para>The first thing to do is understanding which <acronym>ASCII</acronym>
codes are produced by a certain key using the <link linkend="deviance">C
one-liner</link>.</para>
<para>Once you know which sequences are produced, you must check the
current <application>terminfo</application> entry with
<command>infocmp</command> (don't be scared by the amount of information
printed!) and be sure that the <literal>kbs</literal> and
<literal>kdch1</literal> capabilities correspond to the right sequences
(that is, the one produced by the respective keys). Moreover, you must
check with <command>stty -a</command> that the erase character is the one
emitted by the <keycap>Backspace</keycap> key (note that
<literal>^H</literal> represent <symbol>BS</symbol> whereas
<literal>^?</literal> represents <symbol>DEL</symbol>).</para>
<para>If there is a mismatch, there can be several different reason: wrong
content of the <envar>TERM</envar> variable, wrong entry of the terminal
database, wrong terminal emulation under X. I hope at this point you have
enough information to dig the solution autonomously.</para>
<note>
<para>If different applications behave in different ways, it is likely
that some of them are using the terminal database correctly, and some are
not. Remember that the fact that the keys produce the right behaviour in
a certain application does not mean that the application is using
correctly the terminal database&mdash;they could work just by chance. If you
want to have an independent check, you can try whether the
<ulink url="http://ne.dsi.unimi.it/"><command>ne</command></ulink>
editor works. <command>ne</command> uses all terminal capabilities,
including <literal>kbs</literal> and <literal>kdch1</literal>, and uses
intended meaning only as a last resource.</para>
</note>
</sect1>
<sect1 id="morehack">
<title>More Hacking</title>
<para>So, you're not happy with the information you got. In this case,
there is even more hacking you can do on the Backspace/Delete issue, using
suitable commands that get or set the way X and the console handle
keys.</para>
<para>It could happen that, for some reason, what I said talking about
<link linkend="x">X</link> is not true, that is, X does
<emphasis>not</emphasis> translate keycode 22 to keysym
<keysym>BackSpace</keysym> and keycode 107 to keysym
<keysym>Delete</keysym> (or even that, on your particular keyboard, the
keycodes associated to <keycap>Backspace</keycap>/<keycap>Delete</keycap>
are not 22 and 107). To be sure of that, you need to use
<command>xev</command>, a simple X application that will display the
keycode and keysym associated to the key you press. If anything goes wrong,
there are several ways you can fix the problem: the easy, temporary way is
to use <command>xmodmap</command>, a command that lets you change many
settings related to X keyboard handling. For instance,
<screen>
xmodmap -e "keycode 22 = BackSpace"
xmodmap -e "keycode 107 = Delete"
</screen>
will set correctly the keysyms (assuming that 22 and 107 are the correct
keycodes for you). In case you want to do some changes permanently, you can
play with the resources <varname>vt100.backArrowKey</varname>,
<varname>vt100.translations</varname> and <varname>ttyModes</varname> of
<application>xterm</application> (and similar terminal applications) in the
configuration file <filename>~/.Xdefaults</filename>. One
possibility, for instance, is
<programlisting>
XTerm.VT100.Translations: \
&lt;Key>BackSpace: string(0x7F)\n\
&lt;Key>Delete: string("\033[3~")
</programlisting>
You should take a look at the <application>xterm</application> man page for
more information.</para>
<para>The program that does for the console what <command>xev</command>
does for X is <command>showkeys</command>: it will dump the console
keycodes of the keys you press. Combining <command>showkeys</command> with
<command>dumpkeys</command>, which will print on standard output the
console keymap, you can easily fix mismatches between keycodes and
keysyms. Analogously to <command>xmodmap</command>,
<command>loadkeys</command> can then fix single associations, or load
entirely new console keymaps. With it, you can even change the string
associated to a given keysym. If you want to record these changes, you will
have to define a new keymap for the console (you should have a look at the
system keymaps, usually located in <filename>/lib/kbd</filename>).</para>
</sect1>
<sect1 id="concl">
<title>Conclusions</title>
<para>The fixes suggested here should solve to a large extent the problem
of deleting text you wrote (however, they do not help in creating other
text <literal>:)</literal>).</para>
<para>There is a small bug in the whole setting: if you're using the
<envar>COLORTERM</envar> trick and you start
<application>xterm</application> from
<application>gnome-terminal</application>, the former will get
<envar>TERM</envar> set to <literal>gnome</literal>. This inconvenience is,
of course, mostly harmless, and does not occur if you simply started
<application>gnome-terminal</application> with <envar>TERM</envar> suitably
set.</para>
<para>Another nontrivial problem that essentially has no solution is the
one concerning remote connections: if you connect to a host whose terminal
database is incoherent with yours, you will have to set up things
manually.</para>
<para>Finally, it should be noted that the fixes will not work for broken
applications (for instance, applications ignoring the
<literal>kbs</literal> key capability). There is little to do in this case,
as fixing for one broken application will likely break all well-behaving
ones.</para>
</sect1>
</article>