#zdep __begin__
### vim:ft=zsh:foldmethod=marker
#
# The journey towards "the perfect key definitions"[tm].
#
# We'll go about it like this:
# - if there's zsh/terminfo and $terminfo[] "looks good", use it.
# - if there's zsh/termcap and $termcap[] "looks good", use it.
# - if neither is there, fall back to zkbd.
# - if zkbd fails for some reason, create a setup-file-skeleton
# for the terminal-OS combination in question.
#
# Slight deviation from the rules, we just established:
# If the user marks a database entry as broken, directly fall back
# to zkbd:
# % zstyle ':keyboard:$VENDOR:$OSTYPE:$TERM:*:*' broken (terminfo|termcap|both)
#
# Also, allow for overwriting key definitions:
# % zstyle ':keyboard:$VENDOR:$OSTYPE:$TERM:terminfo:Home' overwrite $'\e[1~'
#
# Styles *have* to be set *before* sourcing this file.
# Also, this files expects pretty much zsh-mode default options. So,
# set your crazy options *after* sourcing this file.
#
# Note, that this file does *NOT* bind anything for you. It merely
# populates the $key[] hash, which you can later use to bind your keys,
# like this:
# [[ -n ${key[Home]} ]] && bindkey ${key[Home]} beginning-of-line
#
# Also, this file uses a function called zprintf(), which I use in the
# rest of my setup. zsh doesn't know about it by default, so you'd need
# uncomment the following in order to avoid errors:
#
#ZSHRC_VERBOSE=0
#function zprintf() {
# local -i level; local format
# level=$1 ; format=$2; shift; shift
# (( ZSHRC_VERBOSE < level )) && return 0
# printf '[%2d] '${format} ${level} "$@"
#}
#
if [[ ${builtins[zmodload]} != 'defined' ]]; then
printf 'keyboard: zmodload builtin not found, cannot go on.\n'
return 0
fi
# zrclistkeys() show a list of keysyms strings
function zrclistkeys() {
for i in ${(kon)key}; do
printf '%13s: '\''%s'\''\n' ${i} ${(V)${key[$i]}}
done
}
[[ ${modules[zsh/parameter]} != 'loaded' ]] && zmodload zsh/parameter
typeset -A key
typeset -A kbd_terminfo_map
typeset -A kbd_termcap_map
kbd_terminfo_map=(
Home khome
End kend
Insert kich1
Delete kdch1
Up kcuu1
Down kcud1
Left kcub1
Right kcuf1
PageUp kpp
PageDown knp
)
kbd_termcap_map=(
Home kh
End @7
Insert kI
Delete dc
Up ku
Down kd
Left kl
Right kr
PageUp kP
PageDown kN
)
mode='(-nothing-)'
if [[ ${modules[zsh/terminfo]} == 'loaded' ]] && [[ ${(t)terminfo} == association-*-special ]]; then
mode='terminfo'
elif zmodload zsh/terminfo 2> /dev/null && [[ ${modules[zsh/terminfo]} == 'loaded' ]] \
&& [[ ${(t)terminfo} == association-*-special ]]; then
mode='terminfo'
elif [[ ${modules[zsh/termcap]} == 'loaded' ]] && [[ ${(t)termcap} == association-*-special ]]; then
mode='termcap'
elif zmodload zsh/termcap 2> /dev/null && [[ ${modules[zsh/termcap]} == 'loaded' ]] \
&& [[ ${(t)termcap} == association-*-special ]]; then
mode='termcap'
else
mode='zkbd'
fi
zstyle -s ':keyboard:*' zkbddir zkbddir || zkbddir="${ZDOTDIR:-$HOME}/.zkbd"
kcontext=":keyboard:${VENDOR}:${OSTYPE}:${TERM}:*:*"
zstyle -s ${kcontext} broken broken || broken=''
if [[ ${broken} == 'both' ]] || [[ ${broken} == ${mode} ]]; then
mode='zkbd'
fi
if [[ ${mode} == 'zkbd' ]]; then
function Printf_file() {
[[ -f "$2" ]] && printf "$1" "$2" && return 0
return 1
}
function zrc_printf_termfile() {
Printf_file '%s' ~/.${zkbddir}/${TERM}-${VENDOR}-${OSTYPE} && return 0
Printf_file '%s' ~/.${zkbddir}/${TERM}-${DISPLAY} && return 0
return 1
}
termfile="$(zrc_printf_termfile)"
if [[ -z "${termfile}" ]] ; then
zrcautoload zkbd && zkbd
termfile=$(zrc_printf_termfile)
fi
if [[ -f "${termfile}" ]] ; then
zprintf 1 ' zle: loading %s\n' "${termfile}"
source "${termfile}"
else
zprintf 0 'termfile (%s) not found. zkbd failed.\n' "${termfile}"
mode='need-manual-skeleton'
fi
unfunction Printf_file zrc_printf_termfile
elif [[ ${mode} == 'terminfo' ]]; then
typeset -A key
for k in ${(k)kbd_terminfo_map}; do
key[$k]=${terminfo[${kbd_terminfo_map[$k]}]}
done
if [[ -n ${terminfo[smkx]} ]] && [[ -n ${terminfo[rmkx]} ]]; then
function zle-line-init () {
echoti smkx
}
function zle-line-finish () {
echoti rmkx
}
zle -N zle-line-init
zle -N zle-line-finish
fi
else # termcap
typeset -A key
for k in ${(k)kbd_termcap_map}; do
key[$k]=${termcap[${kbd_termcap_map[$k]}]}
done
if [[ -n ${termcap[ks]} ]] && [[ -n ${termcap[ke]} ]]; then
function zle-line-init () {
echotc ks
}
function zle-line-finish () {
echotc ke
}
zle -N zle-line-init
zle -N zle-line-finish
fi
fi
if [[ ${mode} == 'need-manual-skeleton' ]]; then
termfile="${zkbddir}/MANUAL_${TERM}-${VENDOR}-${OSTYPE}"
if [[ ! -e ${termfile} ]]; then
printf '%s\n' "echo \"zkbd failed for terminal: ${TERM}-${VENDOR}-${OSTYPE}\"" > ${termfile}
printf '%s\n' "echo \"This is ${termfile}\";echo" >> ${termfile}
printf '%s\n' "echo \"Feel free to edit this file and manually insert the right\"" >> ${termfile}
printf '%s\n\n' "echo \"sequences for the keys you want.\"" >> ${termfile}
for k in ${(k)kbd_terminfo_map}; do
printf '#key[%s]=$'\'''\''\n' $k >> ${termfile}
done
fi
source ${termfile}
fi
key[Tab]='^I'
for k in ${(k)key} ; do
key[Alt-${k}]='^['${key[$k]}
done
function kbd_expand() {
emulate -L zsh
setopt braceccl
for k in {0..9} {a-z} {A-Z} ; do
for i in Ctrl- Alt- ; do
case ${i} in
(Ctrl-)
[[ ${k} == [A-Z0-9] ]] && continue
key[${i}${k}]='^'${k}
;;
(Alt-)
# This might not work everywhere. Oh well...
key[${i}${k}]='^['${k}
;;
esac
done
done
}
kbd_expand
key[Alt-Enter]='^[^M'
#for k in ${(k)key}; do
# printf '"%s": "%s"\n' $k "${(V)key[$k]}"
#done
unset mode kcontext broken kbd_terminfo_map kbd_termcap_map termfile k sequence
unfunction kbd_expand
true