I found it's a combination:
One
The ZSH developers do not think that ZSH should define the actions of the Home, End, Del, ... keys.
Debian and Ubuntu fix this by defining the normal actions the average user would expect in the global /etc/zsh/zshrc
file. Following the relevant code (it is the same on Debian and Ubuntu):
if [[ "$TERM" != emacs ]]; then
[[ -z "$terminfo[kdch1]" ]] || bindkey -M emacs "$terminfo[kdch1]" delete-char
[[ -z "$terminfo[khome]" ]] || bindkey -M emacs "$terminfo[khome]" beginning-of-line
[[ -z "$terminfo[kend]" ]] || bindkey -M emacs "$terminfo[kend]" end-of-line
[[ -z "$terminfo[kich1]" ]] || bindkey -M emacs "$terminfo[kich1]" overwrite-mode
[[ -z "$terminfo[kdch1]" ]] || bindkey -M vicmd "$terminfo[kdch1]" vi-delete-char
[[ -z "$terminfo[khome]" ]] || bindkey -M vicmd "$terminfo[khome]" vi-beginning-of-line
[[ -z "$terminfo[kend]" ]] || bindkey -M vicmd "$terminfo[kend]" vi-end-of-line
[[ -z "$terminfo[kich1]" ]] || bindkey -M vicmd "$terminfo[kich1]" overwrite-mode
[[ -z "$terminfo[cuu1]" ]] || bindkey -M viins "$terminfo[cuu1]" vi-up-line-or-history
[[ -z "$terminfo[cuf1]" ]] || bindkey -M viins "$terminfo[cuf1]" vi-forward-char
[[ -z "$terminfo[kcuu1]" ]] || bindkey -M viins "$terminfo[kcuu1]" vi-up-line-or-history
[[ -z "$terminfo[kcud1]" ]] || bindkey -M viins "$terminfo[kcud1]" vi-down-line-or-history
[[ -z "$terminfo[kcuf1]" ]] || bindkey -M viins "$terminfo[kcuf1]" vi-forward-char
[[ -z "$terminfo[kcub1]" ]] || bindkey -M viins "$terminfo[kcub1]" vi-backward-char
# ncurses fogyatekos
[[ "$terminfo[kcuu1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcuu1]/O/[}" vi-up-line-or-history
[[ "$terminfo[kcud1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcud1]/O/[}" vi-down-line-or-history
[[ "$terminfo[kcuf1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcuf1]/O/[}" vi-forward-char
[[ "$terminfo[kcub1]" == "^[O"* ]] && bindkey -M viins "${terminfo[kcub1]/O/[}" vi-backward-char
[[ "$terminfo[khome]" == "^[O"* ]] && bindkey -M viins "${terminfo[khome]/O/[}" beginning-of-line
[[ "$terminfo[kend]" == "^[O"* ]] && bindkey -M viins "${terminfo[kend]/O/[}" end-of-line
[[ "$terminfo[khome]" == "^[O"* ]] && bindkey -M emacs "${terminfo[khome]/O/[}" beginning-of-line
[[ "$terminfo[kend]" == "^[O"* ]] && bindkey -M emacs "${terminfo[kend]/O/[}" end-of-line
fi
So, if you are connecting to a Debian or Ubuntu box, you don't have to do anything. Everything should work automagically (if not, see below).
But... if you are connecting to another box (e.g. FreeBSD), there might be no user friendly default zshrc
. The solution is of course to add the lines from the Debian/Ubuntu zshrc
to your own .zshrc
.
Two
Putty sends xterm
as terminal type to the remote host. But messes up somewhere and doesn't send the correct control codes for Home, End, ... that one would expect from an xterm
. Or an xterm
terminal isn't expected to send those or whatever... (Del key does work in xterm
however, if you configure it in ZSH). Also notice that your Numpad-keys act funny in Vim for example with xterm
terminal.
The solution is to configure Putty to send another terminal type. I've tried xterm-color
and linux
. xterm-color
fixed the Home/End problem, but the Numpad was still funny. Setting it to linux
fixed both problems.
You can set terminal type in Putty under Connection -> Data. Do not be tempted to set your terminal type in your .zshrc
with export TERM=linux
, that is just wrong. The terminal type should be specified by your terminal app. So that if, for example, you connect from a Mac box with a Mac SSH client it can set it's own terminal type.
Notice that TERM specifies your terminal type and has nothing to do with the host you are connecting to. I can set my terminal type to linux
in Putty and connect to FreeBSD servers without problems.
So, fix both these things and you should be fine :)