diff options
Diffstat (limited to 'Functions')
-rw-r--r-- | Functions/Misc/.distfiles | 2 | ||||
-rw-r--r-- | Functions/Misc/zkbd | 248 |
2 files changed, 249 insertions, 1 deletions
diff --git a/Functions/Misc/.distfiles b/Functions/Misc/.distfiles index eba35794c..5ed84ece7 100644 --- a/Functions/Misc/.distfiles +++ b/Functions/Misc/.distfiles @@ -2,5 +2,5 @@ DISTFILES_SRC=' .distfiles acx allopt cat cdmatch cdmatch2 checkmail colors cx harden is-at-least mere multicomp nslookup proto pushd randline - run-help yp yu zed zless zls zmv zrecompile zstyle+ + run-help yp yu zed zkbd zless zls zmv zrecompile zstyle+ ' diff --git a/Functions/Misc/zkbd b/Functions/Misc/zkbd new file mode 100644 index 000000000..30cb4a248 --- /dev/null +++ b/Functions/Misc/zkbd @@ -0,0 +1,248 @@ +#! /bin/zsh -f + +[[ -o interactive ]] && { + local -i ARGC + (ARGC=0) 2>/dev/null || { + print -u2 ${0}: must be run as a function or shell script, not sourced + return 1 + } +} + +emulate -RL zsh +local zkbd term key seq + +zkbd=${ZDOTDIR:-$HOME}/.zkbd +[[ -d $zkbd ]] || mkdir $zkbd || return 1 + +print 'typeset -g -A key\n' > $zkbd/$TERM.tmp || return 1 +trap "unfunction getkey getseq; command rm -f $zkbd/$TERM.tmp" 0 +trap "return 1" 1 2 15 + +getkey () { + local k='' i + for ((i=10; i>0; --i)) + do + read -t -k 1 k && break + sleep 1 + done + [[ -n $k ]] || return 1 + [[ $k = $'\012' || $k = $'\015' || $k = ' ' ]] && return 0 + print -Rn $k +} + +getseq () { + trap "stty ${$(stty -g 2>/dev/null):-echo -raw}" 0 1 2 15 + stty raw -echo + local k='' seq='' i + for ((i=10; i>0; --i)) + do + read -t -k 1 k && break + sleep 1 + done + [[ -n $k ]] || return 1 + [[ $k = $'\012' || $k = $'\015' || $k = ' ' ]] && return 0 + seq=$k + while read -t -k 1 k + do + seq=$seq$k + done + print -Rn ${(V)seq} +} + +read term"?Enter current terminal type: [$TERM] " +[[ -n $term ]] && TERM=$term + +cat <<\EOF + +We will now test some features of your keyboard and terminal. + +If you do not press the requested keys within 10 seconds, key reading will +abort. If your keyboard does not have a requested key, press Space to +skip to the next key. + +EOF + +local ctrl alt meta + +print -n "Hold down Ctrl and press X: " +ctrl=$(getkey) || return 1 +print + +if [[ $ctrl != $'\030' ]] +then + print "Your keyboard does not have a working Ctrl key?" + print "Giving up ..." + return 1 +else + print +fi + +print "Your Meta key may have a Microsoft Windows logo on the cap." +print -n "Hold down Meta and press X: " +meta=$(getkey) || return 1 +print + +if [[ $meta == x ]] +then + print "Your keyboard or terminal does not recognize the Meta key." + unset meta +elif [[ $meta > $'\177' ]] +then + print "Your keyboard uses the Meta key to send high-order characters." +else + unset meta +fi +print + +print -n "Hold down Alt and press X: " +alt=$(getkey) || return 1 +print + +if [[ $alt == x ]] +then + print "Your keyboard or terminal does not recognize the Alt key." + unset alt +elif [[ $alt == $meta ]] +then + print "Your keyboard does not distinguish Alt from Meta." +elif [[ $alt > $'\177' ]] +then + print "Your keyboard uses the Alt key to send high-order characters." +else + unset alt +fi + +(( $+alt + $+meta == 0 )) && cat <<EOF + +--------- + +Your current terminal and keyboard configuration does not appear to use +high-order characters. You may be able to enable the Meta or Alt keys +with a command such as + + stty pass8 + +If you want to use these extra keys with zsh, try adding the above command +to your ${ZDOTDIR:-$HOME}/.zshrc file. + +See also "man stty" or the documentation for your terminal or emulator. +EOF + +(( $+alt || $+meta )) && cat <<EOF + +--------- + +You may enable keybindings that use the \ +${meta:+Meta}${meta:+${alt:+ and }}${alt:+Alt} key${meta:+${alt:+s}} \ +by adding + + bindkey -m + +to your ${ZDOTDIR:-$HOME}/.zshrc file. +EOF + +cat <<\EOF + +--------- + +You will now be asked to press in turn each of the 12 function keys, then +the Backspace key, the 6 common keypad keys found on typical PC keyboards, +plus the 4 arrow keys, and finally the Menu key (near Ctrl on the right). +If your keyboard does not have the requested key, press Space to skip to +the next key. + +Do not type ahead! Wait at least one second after pressing each key for +zsh to read the entire sequence and prompt for the next key. If a key +sequence does not echo within 2 seconds after you press it, that key may +not be sending any sequence at all. In this case zsh is not able to make +use of that key. Press Space to skip to the next key. + +EOF + +read -k 1 key"?Press any key when ready to begin: " +[[ $key != $'\n' ]] && print + +cat <<\EOF + +If you do not press a key within 10 seconds, key reading will abort. +If you make a mistake, stop typing and wait, then run this program again. + +EOF + +# There are 509 combinations of the following three arrays that represent +# possible keystrokes. (Actually, Sun keyboards don't have Meta or Menu, +# though some have R{1..12} keys as well, so really there are either 433 +# or 517 combinations; but some X11 apps map Shift-F{1..11} to emulate the +# unmodified Sun keys, so really only the 345 PC combinations are usable. +# Let's not even get into distinguishing Left and Right Shift/Alt/Meta.) +# No one would ever want to type them all into this program (would they?), +# so by default ask for the 23 unmodified PC keys. If you uncomment more, +# you should fix the introductory text above. + +local -a pckeys sunkeys modifiers +pckeys=(F{1..12} + Backspace Insert Home PageUp + Delete End PageDown + Up + Left Down Right + Menu + ) +sunkeys=(Stop Again + Props Undo + Front Copy + Open Paste + Find Cut + Help + ) +modifiers=(Shift- # Control- Alt- Meta- + # Control-Shift- Alt-Shift- Meta-Shift- + # Control-Alt- Control-Meta- Alt-Meta- + # Control-Alt-Shift- Control-Meta-Shift- + # Alt-Meta-Shift- Control-Alt-Meta-Shift- + ) + +exec 3>/dev/tty + +for key in $pckeys # $^modifiers$^pckeys $sunkeys $^modifiers$^sunkeys +do + print -u3 -Rn "Press $key: " + seq="$(getseq)" || return 1 + print "key[$key]='${(q)seq}'" + print -u3 -R $seq +done >> $zkbd/$TERM.tmp + +source $zkbd/$TERM.tmp || return 1 +if [[ "${key[Delete]}" == "${key[Backspace]}" ]] +then + print + print Warning: Backspace and Delete key both send "${(q)key[Delete]}" +else + if [[ "${key[Delete]}" != "^?" ]] + then + print + print Warning: Delete key sends "${(q)key[Delete]}" '(not ^?)' + fi + if [[ "${key[Backspace]}" != "^H" ]] + then + print + print Warning: Backspace sends "${(q)key[Backspace]}" + fi +fi + +command mv $zkbd/$TERM.tmp $zkbd/$TERM-$VENDOR-$OSTYPE + +cat <<EOF + +Parameter assignments for the keys you typed have been written to the file: +$zkbd/$TERM-$VENDOR-$OSTYPE + +You may read this file into ${ZDOTDIR:-$HOME}/.zshrc or another startup +file with the "source" or "." commands, then reference the \$key parameter +in bindkey commands, like this: + + source ${zkbd/$HOME/~}/\$TERM-\$VENDOR-\$OSTYPE + [[ -n \${key[Left]} ]] && bindkey "\${key[Left]}" backward-char + [[ -n \${key[Right]} ]] && bindkey "\${key[Right]}" forward-char + # etc. + +EOF |