[Pkg-zsh-devel] [PATCH 1/6] Rewrite keyboard handling in zshrc

Frank Terbeck ft at bewatermyfriend.org
Mon Mar 5 23:02:07 UTC 2012


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 at bewatermyfriend.org>
---
 debian/zshrc |   94 +++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 67 insertions(+), 27 deletions(-)

diff --git a/debian/zshrc b/debian/zshrc
index 9aed934..16ff26d 100644
--- a/debian/zshrc
+++ b/debian/zshrc
@@ -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
-- 
1.7.9.188.g12766




More information about the Pkg-zsh-devel mailing list