全部博文(168)
分类: IT业界
2007-11-13 22:00:11
version 0.6
Index |
||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
|||||||||
|
|
|
||||||||
Configuration of environments...
|
||||||||||
|
|
|
|
|
||||||
... and applications
|
||||||||||
The keymapping problem can be traced back to the time when computers used punched tapes. The only way to correct a wrongly punched character was to punch additional bits in the tape (or rather, punch additional bits _out_ of the tape). Characters with all the bits punched were treated as deleted characters. See 'man ascii' for a list of the ASCII characterset, you'll see that DEL, (octal 177, decimal 127 and hexadecimal 7F) is the one with all the bits punched in (the ASCII code with the highest value). To be able to overwrite a character it is necessary to undo the feed between the characters first. For this the ASCII BS (octal 010, decimal 8, hexadecimal 08) was used. So to erase the last-typed character, you would have to press first BS to move back one character, and then DEL to delete the character. In newer computers either BS or DEL was chosen to move back and delete in one press.
The question to use BS or DEL was (and is...) just a matter of choice, just as different operating systems chose different ways to represent newlines, which was done by first issuing a carriage return (CR) and then a line-feed (LF). UNIX chose ASCII LF (hexadecimal 0A) to do both at the same time, Macintosh chose CR and MS-DOS both. Unfortunately, in the BS-DEL case, Linux ended up with two possibilities.
The essential point in this issue is to go for one way consistently. This page describes a way to consistently use DEL to erase the previous character, the page called describes a way to consistently use BS. On the latter page there are some tips which may be useful regardless of what approach you take.
At this point the best way to fix the keys on your machine is to install from version 2 (Hamm) and up, or , or any later Redhat/Fedora distribution, and I would bet that the issue has been addressed in other recent distributions as well. In fact, I find it surprising that so many people still refer to this page after 9 years, especially since nothing new has been added to it for at least 6 years.
If you miss an application on this page, it's either because the keys are ok in the application ("If it ain't broken, don't fix it"), or because I don't know about it. In either case, don't hesitate to mail me about it.
Note: |
---|
ASCII BS == 0x08 == ^H |
ASCII DEL == 0x7f == 0177 == ^? |
The linux console emulates a vt220 terminal which has the following key-mapping:
Linux console/VT220 Key KeySymName Console characters -------------------------------------------------- Ctrl+H ---> Control_H ---> ASCII BS (0x08) [<---] ---> Backspace ---> ASCII DEL (0x7f) [Delete] ---> Delete ---> "\e[3~"Note 1: BS (0x08) is equivalent to ^H, which is left to be used by applications (e.g. for help menus in emacs, but it could be anything). DEL is equivalent to ^?, or 0177 (octal) and 0x7f (hex) and "\e[3~" will show up in your xterm (using the ) as ^[[3~. Xterms on the other hand, emulate the vt100 terminal, which didn't have a [Delete]. It did have a [<---] which generated ASCII BS (but it was in an awkward position and did not serve as rubout).
VT100 -- Key KeySymName Console characters -------------------------------------------------- Ctrl+H ---> Control_H ---> ASCII BS (0x08) [<---] ---> Backspace ---> ASCII DEL (0x7F)Now here's how xterm emulates the VT100 terminal:
Xterm's emulation of VT100 Key KeySymName Console characters -------------------------------------------------- Ctrl+H ---> Control_H ---> ASCII BS (0x08) [<---] ---> Backspace ---> ASCII BS (0x08) [Delete] ---> Delete ---> ASCII DEL (0x7F)It may be clear that by default the keys are mapped differently on the console and in xterm. This would be ok if it weren't for the fact that while on the console ^H is free to be used by applications, in an xterm it is not (instead it's mapped to the [<---] key). Differences between terminal types are generally dealt with by the terminfo database (see below), mapping terminal specific strings to the correct key. However, in this case, the ^H should not be mapped. Terminfo is not enough, the settings of the terminal (xterm) have to be modified such that ^H is not used.
In at working around the problem, I put most of my effort in trying to map all keys to suit xterm's vt100 emulation. However, I now propose another way to deal with the problem. This basically means getting xterm to work with the consoles' default settings: [<---] will do ASCII DEL (0x7F, or ^?), and [Delete] will do "\e[3~". This way ^H is not used for any terminal specific functions, it can be used by applications.
When you change the keymapping on your own system, you may have problems when accessing other systems. Luckily, this can be worked-around by a script which changes the input it receives to the output that is expected by the application (telnet, rlogin). See the section.
Environment
|
Configuration files
|
Configuration
|
|
user
|
systemwide
|
||
- | terminfo | infocmp/tic | |
~/.Xdefaults (*) | /etc/X11/Xresources | xrdb ~/.Xdefaults (*) | |
- | /etc/X11/xinit/.Xmodmap (**) | xmodmap .Xmodmap | |
~/.inputrc | /etc/inputrc | export INPUTRC=/etc/inputrc | |
~/.cshrc | /etc/cshrc | bindkey (shellcommand) |
infocmp | grep kbsshould return a line which includes kbs=\177. This means DEL (or ^?) is mapped to the backspace key, which is what we want.
infocmp | grep kdch1should return a line with kdch1=\E[3~. This means that \E[3~ is mapped to the delete key. Often you will find kbs=^H and/or kdch1=\177, or there will be no kdch1 at all. You can either edit the terminfo entry as described on the (simply setting or adding kdch1=\E[3~ and kbs=\177, but make a backup first!). Put the file in ~/.terminfo/x/xterm (for testing purposes) and do for bash:
export TERMINFO=~/.terminfoand/or for tcsh:
setenv TERMINFO ~/.terminfoMake sure that the TERM variable is set to xterm:
echo $TERMshould return "xterm". If it works as intended (do 'toe' to check whether the terminfo dir you specified is indeed used, toe will return a list of available terminfo types, only xterm in this case), you can run tic as root, which will copy the file to
/etc/terminfo/x/xterm() or
/usr/lib/terminfo/x/xterm(, ). Make backups first, and test it before you replace any files!
*VT100.Translations: #override \BackSpace: string(0x7F)\n\ Delete: string("\033[3~")\n\ Home: string("\033[1~")\n\ End: string("\033[4~") *ttyModes: erase ^?
Rxvt only uses Xresources if it is compiled with this option. Since rxvt uses readline, to get home and end to work you will have to edit .inputrc, see the section). users can pick up the SRPM (source) and compile rxvt themselves with this , ensuring the right keybindings.
Putting xterm or nxterm in front of *vt100.translations makes the settings specific for xterm or nxterm. Sometimes this does not seem to work properly, in that case try using both nxterm*VT100.Translations and xterm*VT100.Translations.
BTW, have I told you that Ctrl-v
1. 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.
2. The sections are named, if you only use *VT100.Translations it will work for all xterm and friends.
3. For info about Xresources and other X related stuff refer to .
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 an excellent graphical front end for X-keyboard configuration: xkeycaps. Refer to the .
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 ComposeNow you have a compose-key with the same properties as the one described in the section. Remember to set the environment variable LC_CTYPE=iso-8859-1 (see ). Consult if you want to know more. Note: this doesn't seem work rxvt.
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 -kbthen 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 fiNow chars accesible by AltGr, dead keys or compose are usable in xdm too.
? ? ? ¤ ? ? § ¨ © ? ? ? ? ? ° ± ? ? ? ? ? · ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? × ? ? ? ? ? ? ? ? à á ? ? ? ? ? ? è é ê ? ì í ? ? ? ? ò ó ? ? ? ÷ ? ù ú ? ü ? ? ?Now you need a way to display them (millions of options here, I bet you can do all kinds of crazy things with fonts, colors, pixmaps, borders...). The script assumes the file with the characters is in /usr/local/lib.
#!/bin/bash export LESSCHARSET=latin1 exec xterm -T Iso_8859_1-TABLE -geometry 77x4 +sb -bg SteelBlue -fg white \ -fn lucidasanstypewriter-bold-12 -e less /usr/local/lib/iso_8859_1Refer to the manual page of iso_8859_1. If you do 'man iso_8859_1' but you don't see any special characters, edit /etc/man.config, and change the following line:
NROFF /usr/bin/groff -Tascii -mandocto:
NROFF /usr/bin/groff -Tlatin1 -mandocNow try 'man -c iso_8859_1' (the -c option is to make sure man does not use an old cat file).
Create a file, /etc/inputrc for system wide use 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:
"\e[3~": delete-char # this is actually equivalent to "\C-?": delete-char # VT "\e[1~": beginning-of-line "\e[4~": end-of-line # kvt "\e[H":beginning-of-line "\e[F":end-of-line # rxvt and konsole (i.e. the KDE-app...) "\e[7~":beginning-of-line "\e[8~":end-of-lineIf a system-wide /etc/inputrc was created, add the following line to /etc/profile:
export INPUTRC=/etc/inputrc
Make sure that the stty erase character is set to ^?. Type
stty -a | grep erase
and check if it says
erase = ^?;
If it is set to something else (e.g. ^H) then put the following line in both .bashrc and in either .bash_profile or /etc/profile:
if tty --quiet ; then stty erase '^?' fiand for xterm and rxvt add this to .Xdefaults:
*ttyModes: erase ^?
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.
You can also change the keybindings on the fly with the bind command, e.g:
[localhost]> bind "\C-?": backward-delete-charThis 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 .
#.cshrc if ($term == "xterm" || $term == "vt100" \ || $term == "vt102" || $term !~ "con*") then # bind keypad keys for console, vt100, vt102, xterm bindkey "\e[1~" beginning-of-line # Home bindkey "\e[7~" beginning-of-line # Home rxvt bindkey "\e[2~" overwrite-mode # Ins bindkey "\e[3~" delete-char # Delete bindkey "\e[4~" end-of-line # End bindkey "\e[8~" end-of-line # End rxvt endifTo see whether it works or not, type:
[localhost]> source .cshrc
*Text.translations: #override \ ~Shift ~MetaDelete: delete-next-character()
;; Map certain keypad keys into ASCII characters ;; that people usually expect. (define-key function-key-map [backspace] [127]) (define-key function-key-map [delete] [127])and change the last line to
(define-key function-key-map [delete] [deletechar])Alternatively you can add
(define-key function-key-map [delete] [deletechar])to your ~/.emacs file. On a related note, by default in emacs the HOME key brings you to the beginning of the buffer (i.e. top of the document). Likewise the END key brings you to the end of the buffer. Adding the lines
(define-key global-map [home] `beginning-of-line) (define-key global-map [end] `end-of-line)to your ~/.emacs make these keys move you to the beginning and end of the current line. Note that the M-< and M-> keybindings remain untouched and can still be used to go to the beginning and end of the buffer.
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 ~ # rxvtNote that you first have to make sure that Home and End work in an . Check out . BTW, these modifications apply to jpicorc, jstarrc and jmacsrc as well.
"\e[H":beginning-of-line "\e[F":end-of-linein .inputrc. Additionally, make sure that you have checked the 'BS sends DEL' checkbox (right mouse click, or through the 'Options' pulldown menu). In kvt, home and end can be configured by editing ~/.inputrc (tcsh users too, it uses readline):
"\e[H":beginning-of-line "\e[F":end-of-line
#line-edit \e[3~ delete \e[1~ home \e[4~ end
[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
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 .
nedit.remapDeleteKey: False
Save the file, and the next time you start 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.
Note the nedit, as e.g. netscape, is a motif application. This means that it uses the XKeysymDB, see thet netscape section.
If you use xmodmap, you may want to check out the graphical front end for X-keyboard configuration: xkeycaps. Get the .rpm at , or get the (or plain tarball). It's a nice tool. You can also look for a default Xmodmap file on your system. At any rate, make sure that the following is in the file:
keycode 22 = BackSpace
keycode 107 = Delete
alternatively, you can put it in e.g. your .Xclients file, or in /etc/X11/xdm/Xsetup_0):
# map the [<---] key to the [BackSpace] keysym. xmodmap -e "keycode 22 = BackSpace" # map the [Delete] key to the [Delete] keysym. xmodmap -e "keycode 107 = Delete"
#!/usr/bin/expect eval spawn -noecho $argv interact { \177 {send "\010"} "\033\[3~" {send "\004"} }Make picofix executable, and start the editor (or pine) with
picofix picoand it will work (then you can make an alias or a wrapper). Thanks to Philip Hands for this ingenious (and powerful!) workaround. 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.
Pico fans may want to try jpico, which is basically joe with pico keybindings (and all the extra's joe offers). Others my be even smarter and switch to and . Note that the first can be taught to do the Ctrl-j-trick, the latter can use pine keybindings.
bind editorThis will make [Delete] do its job in internal pager.delete-char
#!/usr/bin/expect eval spawn -noecho $argv interact { \177 {send "\010"} "\033\[3~" {send "\177"} }If you press [<---], expect will receive \177 (equivalent to 0x7F and ^?, see the ) and it will send \010 (equivalent to ^H) along to telnet, which will result in [<---] at the other end. Make it executable and use kbdfix telnet brokenhost. Thanks to Philip Hands for this clever workaround.
The logical next step is to automate the trick. Create a file, /etc/broken-backspace-hosts (or a shorter name...). In this file, list the hosts which expect ^H and ^? instead of ^? and ^[[3~. Now you can make a wrapper for telnet as shown below. This particular script assumes that the telnet binary has been renamed telnet.orig, and that the kbdfix script described in the previous section is somewhere in your path):
#!/bin/sh if grep -wq "$@" /etc/broken-backspace-hosts ; then exec kbdfix telnet.orig "$@" else exec telnet.orig "$@" fiFrom now on, when you use telnet, the script will check whether the host you are telnetting to is considered broken (listed in the /etc/broken-backspace-hosts file). If it is, the expect script (kbdfix) will be used, if not, telnet will be started directly. You can do the same for rlogin, although rlogin can't be moved (i.e. won't work when it isn't called rlogin).
This document was put together by (anne@ibb.net). Please mail me if you find mistakes, tY-pO's, alternative or plain better solutions. A few people have already pointed out many mistakes (there simply cannot be that many left...), which improved the document a lot. I would like to thank all the people who contributed to the page, and Thomas Telkamp for hosting the site.