Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: The old backspace/delete problem

Boyd Adamson wrote:
> Someone recently mentioned to me a solution to the old "backspace key
> sends ^? or ^H" problem that I hadn't heard of, and I thought we here
> in zsh land might be able to improve on it.
> The solution I saw was for a ksh user:
> alias ^?='stty erase ^?'
> alias ^H='stty erase ^H'
> The idea is that on login, the user types <backspace><enter>. This
> will do one of two things:
> 1. The character sent by the backspace key will match the current tty
>    setting. In this case nothing happens except for a new prompt, or,
> 2. The character sent by the backspace key does not match the current
>    tty setting, the alias is expanded and the tty setting is changed
>    to match the terminal emulator.
> Now this is nice, but it doesn't help those of use who use a superior
> shell, since both ^? and ^H are normally mapped to the same function
> (something like backward-delete-char). This is nice in the shell, but
> potentially leaves us with a broken backspace key in other command
> line programs.
> Any ideas on how we could do this sort of auto-detection in zsh?

It's doable; there's a slight catch, but I think I've managed to make it
almost invisible to the user.  Here's the code first:

backward-delete-char-detect() {
  if (( #KEYS == ##\C-? )); then
    zmodload -i zsh/sched
    sched +00:00 "stty erase '^?'"
  elif (( #KEYS == ##\C-h )); then
    zmodload -i zsh/sched
    sched +00:00 "stty erase '^h'"

  zle .$WIDGET
zle -N backward-delete-char backward-delete-char-detect
zle -N vi-backward-delete-char backward-delete-char-detect

This code will run the function backward-delete-char-detect the first
time you type a key bound to backward-delete-char.  If that's either ^?
or ^h, it will record the fact.  Then it will restore the original
version of backward-delete-char and perform the normal operation.

The unpleasantness is that we can't run stty inside the editor widget,
since the terminal setup is explicitly restored on exit from zle and any
change is lost.  So instead we use "sched" to schedule the stty to run
immediately, which in practice is the next time the command line is
executed.  This does seem to work, but the effect consequently isn't
instantaneous; the first command that runs immediately after you've
deleted a character doesn't yet have the character remapped, because the
"sched" event is only examined when control returns to the shell after
that command.

Alternatively, you could split the stty into the preexec function, but
then it becomes messier.

Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070

This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

This footnote also confirms that this email message has been swept by
MIMEsweeper for the presence of computer viruses.


Messages sorted by: Reverse Date, Date, Thread, Author