#! /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 </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 <