<!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>

