I recently changed my terminal emulator; after several years with the “good old” xterm, I switched to the Unicode-enabled variant of rxvt, urxvt (or rxvt-unicode). Although I am now pleased with urxvt, I ran into a few minor problems when I started to use that emulator, and I would like to expose them here, along with the workarounds I found.
The <Home>
and <End>
keys,
which are supposed to move the cursor to the beginning and the end of
line, respectively, didn’t work. The reason was that the escape
sequences emitted by urxvt when those keys are pressed were not
the escape sequences expected by readline.
By default, urxvt emits <Esc>[7~
for
<Home>
and <Esc>[8~
for
<End>
(this can by verified by typing
<Control>-V
followed by the desired key, at the
terminal prompt). And here are the relevant lines of the default
readline configuration file on my Slackware system,
/etc/inputrc
:
# for linux console "\e[1~": beginning-of-line "\e[4~": end-of-line # for xterm "\eOH": beginning-of-line "\eOF": end-of-line # for freebsd console "\e[H": beginning-of-line "\e[F": end-of-line
So, readline maps several escape sequences from several terminal emulators to the beginning-of-line and end-of-line functions, but the sequences from urxvt are not included.
There are (at least) two solutions. The first is to modify the
configuration of readline (either in the system-wide
/etc/inputrc
file, or in my own ~/.inputrc
file) to add the missing mapping:
# for urxvt "\e[7~": beginning-of-line "\e[8~": end-of-line
The second solution is quite the opposite: modify the configuration
of urxvt so that it sends control sequences already recognized
by readline. That’s what I did, by adding the following lines
to my ~/.Xdefaults
file:
urxvt.keysym.Home: \033[1~ urxvt.keysym.End: \033[4~
The <Control>-L
combination is supposed to clear
the terminal screen. There again, in urxvt it didn’t work:
pressing <Control>-L
only resulted in a new line, as
if <Return>
has been pressed instead.
I have still not understood the reason for that behavior. Here are the tests I conducted and the conclusions I can draw.
First, the <Control>-L
combination is correctly
associated to readline’s clear-screen function:
$ bind -P | grep clear clear-screen can be found on "\C-l".
I can bind another combination to the clear-screen function:
$ bind ‘"\C-g": clear-screen’ $ bind -P | grep clear clear-screen can be found on "\C-g", "\C-l".
but the new combination <Control>-G
produces
exactly the same (incorrect) behavior as the default
<Control>-L
. So I assume the clear-screen
is called, but somehow fails to clear the screen as it should.
To clear the screen, readline must send to the terminal an
appropriate escape sequence. According to urxvt’s man page,
that sequence is <Esc>[H<Esc>[2J
. A lookup
into the terminfo(5) database confirms:
$ infocmp rxvt-unicode | grep clear clear=\E[H\E[2J, cnorm=\E[?25h, cr=^M
Manually emitting that sequence clears the screen as expected:
$ echo -ne "\033[H\033[2J" (The screen is cleared.)
So the terminfo entry for rxvt-unicode is correct.
Why then readline cannot clear the screen? I don’t know. I guess I’m missing something here, but that’s as far as my understanding of the problem goes.
The workaround I found is quite ugly, I admit: I instructed
urxvt (through the ~/.Xdefaults
file) to intercept
the <Control>-L
sequence and to call the
clear command:
urxvt.keysym.Control-l: clear\n
Then, I added clear to the HISTIGNORE environment
variable, so that my shell history does not get polluted by dozens of
clear calls (I use the <Control>-L
quite a
lot):
HISTIGNORE="clear:$HISTIGNORE" export HISTIGNORE
UPDATE: I finally found out what the problem was. As I suspected, I was missing something, and the fault is entirely mine.
I had assumed from the beginning that readline retrieves
the appropriate escape sequence through terminfo(5), while it
really uses termcap(5)! And when I compiled and installed
rxvt-unicode (which is not provided by Slackware), I did make
sure to update the terminfo database, but I completely
neglected the /etc/termcap
file. That’s why
readline was unable to obtain the escape sequence it needed
to clear the screen—while the clear(1) command, which uses
terminfo, had no problem. Adding to
/etc/termcap
the contents of the
rxvt-unicode.termcap
file (provided in
rxvt-unicode’s archive) solved the problem.