Subject: Re: An old unix Issue the Delete key how do you fix it
To: None <netbsd-help@netbsd.org>
From: Valeriy E. Ushakov <uwe@stderr.spb.ru>
List: netbsd-help
Date: 05/04/2007 04:38:41
On Thu, May 03, 2007 at 10:56:07 -0400, Greg Troxel wrote:

> "Valeriy E. Ushakov" <uwe@stderr.spb.ru> writes:
> 
> > mowestusa <mowestusa@yahoo.com> wrote:
> >
> > IIRC, default wscons keymap maps both the "<-" key in the upper right
> > corner of the main block (scancode 14) and the "Delete" key in the 2x3
> > editing block (scancode 211) to produce ASCII character DEL (127).  So
> > programs just cannot distinguish the two keys with the default keymap.
> 
> Default seems to be <- is BS and Delete DEL.

Hmm, not according to sys/dev/pckbport/wskbdmap_mfii.c or wsconctl -k
map on my laptop.  Both 14 and 211 are mapped as KS_Delete.

I guess you are using USB keyboard [and indeed I can see your reply
further down the thread].


> >> On those keyboards you had no "backspace" but instead had a "delete"
> >> key in that location that carried out the function of
> >> "delete-left". You had no way to "delete-right" on those old
> >> terminals.
> >
> > I think you are confused.  "delete-right" or "delete-left" are actions
> > that program performs in response to certain key presses (in the case
> > of terminal - bytes coming from the tty).  Of course you was able to
> > "delete-right", it all about how your programs are configured.
> 
> Sure, but I think the point is that the behavior of DEL was wired into
> the cooked-mode tty processing, and most programs used cooked mode.

Wired?  Even in V7 you certainly could control it, and defaults still
were '#' for erase and '@' for kill (I've just verified that with simh
and, my, it took me some time to remember how to boot it :).


> Programs that used raw mode behaved this way too, in order not to be
> confusing and gratuitously different.  So that usage was universal.
> 
> While you could certainly delete the character at the cursor in vi or
> emacs, that was about those programs interpreting some key sequence that
> way, as opposed to now where nearly all X11 programs interpret the
> "Delete" key as delete right.

And just what is "delete-right" in the cooked (aka "canonical") mode? ;)

As there's no real editing in the canonical mode, you can only KILL
the whole line or ERASE the last character (which is obviously "to the
left").  There's no movement possible, so there's never any "to the
right" character to apply "delete-right" to.


The keyboard situation is somewhat eclectic, so I'm sorry if the
following sounds confusing.  Someone please correct me where I'm
wrong.


Terminals used to be independent devices that sent bytes to the host,
usually using serial line.  That's reflected in the tty(4) model.
There are no "key presses" (or key releases) in that model.

Terminal emulators (xterm or kernel console driver) usually receive
key presses/releases and emulate terminal "send sequence of bytes"
behaviour to support tty(4) model.  As emulators are configurable, you
can make them send whatever you want, emulating different terminals.

You can use stty(1) to set tty(4) VERASE to the char that the driver
will treat as "delete-left" (and as explained above, there's no
"delete-right" in this model).

Smart programs that provide advanced editing usually use TERM
environment variable to look up terminal description in the termcap
(or terminfo) database.  Thus they can recognize sequences of bytes
sent by the terminal and convert them back to "key presses" (though
there are no key releases in this model).  Thus a program can see
three bytes \E[D and recognize them as "left arrow key".  Often such
programs use curses library instead of messing with termcap themselves
or readline that messes with termcap for them.

Termcap has "kb" capability for the sequence of bytes sent by the <-
aka <X] aka BackSpace key and "kD" for the sequence sent by Del.  Most
programs also check the VERASE setting and use it to mean <- as well.

Emacs is a notable exception that doesn't rely on curses for
converting sequences of bytes into keypresses.  Emacs uses its own
database (in form of lisp files in its lisp/term directory with
keybindings for different terminals).

In principle, you shouldn't care about what character your <- send,
b/c programs should pick it up from VERASE and termcap.  But I guess
it's emacs ruins this idyllic picture (no offense, I'm a long time
emacs user myself).  Having originated in the DEC-orieneted world
(where <X] sends DEL), emacs uses BS (^H) for help.  Of course on a
terminal that sends BS for <- that causes a lot of grief.  Thus emacs
users tend to stick with DEC ways and make their <- keys send DEL.

On the other side there are various programs (e.g. various kinds of
firmware) that hardcode ^H as their "delete-left" character.  In rare
cases when I need to deal with them, I don't mind using <Ctrl>+<H>
chord, but I guess people that deal with them often (and don't use
emacs :) think otherwise and like their <- to send BS.


To make the matter more confusing different keyboards had different
sets of backspace/delete keys.  To mention few popular ones:

vt220 lk keyboard has <X] key (sending DEL) and <Remove> key (sending
\E[3~).  I'm not sure about original vt220 (and I'm not turning mine
on to check ;), but e.g. vt420 provided an option for <X] key to
generate BS.  vt220 termcap entry sets kD=\E[3~ and kb=^H (!).  I'm
not sure why it does the former, but I think that's done so that
programs that pick up VERASE (which would be DEL) will still handle
<X] correctly, and they will also handle ^H correctly.  They can get
^H either entered as <Ctrl>+<h> chord, or they can be run under an
emulator that is mostly vt220 but still sends ^H for <-, e.g. xterm
with default settings(!).

pc'ish keyboards (including e.g. Sun Type 5 and up) has <- key
(sometimes also labeled "Back Space"), <Del> key in the 3x2 editing
block and <Del> key on the keypad block that is conventionally treated
as the <Del> key from the 3x2 editing block if yout are not in the
NumLock mode.  Note that X11 distinguishes all three as XK_BackSpace,
XK_Delete and XK_KP_Delete respecively.  Most vt'ish terminal
emulators map <- (XK_BackSpace) to either BS or DEL and send \E[3~ for
XK_Delete and XK_KP_Delete.  But OTOH default X translations (check
e.g. what xev(1) shows you) map XK_BackSpace to BS and XK_Delete to
DEL and have no translation for XK_KP_Delete.

vt100 had backspace and delete keys sending corresponding ASCII chars.
vt100 termcap entry has kb=^H (same logic as with vt220 applies) but
no kD entry.

Sun Type 4 keyboard has an interesting quirk.  [I haven't used it for
quite some time, so my memory is a bit hazy.  Someone please correct
me where I'm wrong].  Type 4 has no middle "editing" block.  It has
<BackSpace> and <Delete> keys in the main block (Delete above
BackSpace) and it has <Del> key in the keypad block.  IIRC, sun
console sends BS and DEL for <BackSpace> and <Delete> and \E[249z for
<Del>.  That's what our old, non-wscons, sun console code does anyway
as far as i can tell from reading the code (but our wsemul_sun seems
to send DEL for KS_KP_Delete!)  Note that unlike the pc'ish keyboard
convention, the <Delete> and <Del> are treated differently in the sun
scheme.  You cannot describe this fully in termcap (3 keys vs. 2
capabilities).  Termcap entry for sun has kb=^H and kD=\177, and
leaves <Del> out completely - so, iirc, you cannot use the keypad
<Del> in programs unless you can add key-binding for it (e.g. in
.emacs or .inputrc).  Of course under X11 each key has its own keysym
and xterm will use <Delete> == <Del> logic, and when you are back in
console your xterm habits might bite you.  I loved the typing feeling
of Type 4 keyboard, it was very smooth, but the BackSpace/Delete/Del
issue was always a bit annoying.

All this boils down to:

. what does your terminal sends

. what is your stty setting for VERASE (for programs that rely on tty
  driver canonical input processing)

. what is your TERM (for "smart" programs)

and you want the three to be in sync.


Since wscons "vt100" emulation really emulates vt220'ish terminal, it
makes sense to keep 14 (<- or <X] or BackSpace) mapped to Delete
(generating DEL) and 211 to KP_Delete (generating \033[3~).

The first one matches default VERASE 0177, so default mapping matches
default stty settings.  The latter is already described by kD=\E[3~ in
termcap descriptions of vt220 &co, so it should do the right thing and
provide working "delete-right" out of the box.

There's still consistency issue - USB keyboards generate BS for <- and
xterm defaults favor BS too.  I'm not sure how to deal with this
sanely (I whacked xterm into never ever giving me ^H unless I press
^H, and I rarely use USB keyboards for console) but it's been like
that for ages and the above proposal doesn't change it, so we can
probably ignore it for now or spin that off into a separate
discussion.


PS: FreeBSD made an interesing hack, they've added VERASE2 char and
they set it to BS by default.  Thus tty(4) "just works" with either BS
or DEL.  On the other hand you need to teach every program that deals
with tty(4) that VERASE2 exists.

PPS: Sorry if the above sounds like rambling.  It's kinda hard to
squeeze the long story into a few paragraphs, especially since I
haven't used some of the systems/terminals for quite some time, so my
memory is patchy.

SY, Uwe
-- 
uwe@stderr.spb.ru                       |       Zu Grunde kommen
http://snark.ptc.spbu.ru/~uwe/          |       Ist zu Grunde gehen