#!/bin/zsh -f [[ -o interactive ]] && { local -hi ARGC # local is a no-op outside of a function (ARGC=0) 2>/dev/null || { # so ARGC remains read-only for "source" 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 trap 'unfunction getmbkey getseq; command rm -f $zkbd/$TERM.tmp' 0 trap "return 1" 1 2 15 getmbkey () { 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 # We might not be done yet, thanks to multibyte characters local mbk=$k while read -t -k 1 k do mbk=$mbk$k done print -Rn $mbk } 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 print 'typeset -g -A key\n' > $zkbd/$TERM.tmp || return 1 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=$(getmbkey) || 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=$(getmbkey) || 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=$(getmbkey) || 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 if (( $+alt + $+meta == 0 )) then print $'\n---------\n' if [[ -o multibyte ]] then 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 local termID=${${DISPLAY:t}:-$VENDOR-$OSTYPE} termFile=$zkbd/$TERM.tmp command mv $termFile $zkbd/$TERM-$termID && termFile=$zkbd/$TERM-$termID cat <