Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Rewrite keyboard handling in zshrc
This change makes proper use of `$terminfo[]', because it makes sure
that zle (zsh's line editor) puts the terminal into application mode
while it is running. Then - and ONLY then - are the values from the
`$terminfo[]' array valid.

While doing that this also does this:

  a) Refactor the actual binding code
  b) Do not bind non-default vi-* widgets to Up and Down.

The change in "b)" may be controversial because it reverts long standing
debian-zshrc behaviour. However, the #zsh channel on freenode gets a
*lot* of people complaining about this from debian and ubuntu systems.
There even was a bug report about this: #383737. Clint commented like
this:

> Unfortunately this boils down to a binary division in a fundamental
> belief, and either way people are unhappy.

I agree.

But I disagree, that the solution is to keep the non-default behaviour
in that case. The package should keep the default zsh behaviour with
things that boil down to "fundamental belief" and leave it to the user
to decide.

The bindings that were the most controversial were `Up' and `Down' bound
to vi-up/down-line-or-history in viins and vicmd. This patch binds both
keys to the less surprising up/down-line-or-history bindings.

Signed-off-by: Frank Terbeck <ft@bewatermyfriend.org>
  • Loading branch information
ft committed Mar 4, 2012
1 parent c5dfca6 commit cb9eb75
Showing 1 changed file with 67 additions and 27 deletions.
94 changes: 67 additions & 27 deletions debian/zshrc
Expand Up @@ -8,33 +8,73 @@

READNULLCMD=${PAGER:-/usr/bin/pager}

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
if [[ -z "$DEBIAN_PREVENT_KEYBOARD_CHANGES" ]] &&
[[ "$TERM" != 'emacs' ]]
then

typeset -A key
key=(
Home "${terminfo[khome]}"
End "${terminfo[kend]}"
Insert "${terminfo[kich1]}"
Delete "${terminfo[kdch1]}"
Up "${terminfo[kcuu1]}"
Down "${terminfo[kcud1]}"
Left "${terminfo[kcub1]}"
Right "${terminfo[kcuf1]}"
PageUp "${terminfo[kpp]}"
PageDown "${terminfo[knp]}"
)

function bind2maps () {
local i sequence widget
local -a maps

while [[ "$1" != "--" ]]; do
maps+=( "$1" )
shift
done
shift

sequence="${key[$1]}"
widget="$2"

[[ -z "$sequence" ]] && return 1

for i in "${maps[@]}"; do
bindkey -M "$i" "$sequence" "$widget"
done
}

bind2maps emacs -- Home beginning-of-line
bind2maps viins vicmd -- Home vi-beginning-of-line
bind2maps emacs -- End end-of-line
bind2maps viins vicmd -- End vi-end-of-line
bind2maps emacs viins -- Insert overwrite-mode
bind2maps vicmd -- Insert vi-insert
bind2maps emacs -- Delete delete-char
bind2maps viins vicmd -- Delete vi-delete-char
bind2maps emacs viins vicmd -- Up up-line-or-history
bind2maps emacs viins vicmd -- Down down-line-or-history
bind2maps emacs -- Left backward-char
bind2maps viins vicmd -- Left vi-backward-char
bind2maps emacs -- Right forward-char
bind2maps viins vicmd -- Right vi-forward-char

# Make sure the terminal is in application mode, when zle is
# active. Only then are the values from $terminfo valid.
function zle-line-init () {
echoti smkx
}
function zle-line-finish () {
echoti rmkx
}
zle -N zle-line-init
zle -N zle-line-finish

unfunction bind2maps

fi # [[ -z "$DEBIAN_PREVENT_KEYBOARD_CHANGES" ]] && [[ "$TERM" != 'emacs' ]]

zstyle ':completion:*:sudo:*' command-path /usr/local/sbin /usr/local/bin \
/usr/sbin /usr/bin /sbin /bin /usr/X11R6/bin
Expand Down

0 comments on commit cb9eb75

Please sign in to comment.