-KEYTIMEOUT=1
-# xorg
-bindkey "^[[7~" beginning-of-line #Home
-bindkey -a "^[[7~" beginning-of-line
-bindkey "^[[8~" end-of-line #End
-bindkey -a "^[[8~" end-of-line
-bindkey "^[[3~" delete-char #Del
-bindkey -a "^[[3~" delete-char
-# bsd vt
-bindkey "^[[H" beginning-of-line #Home
-bindkey -a "^[[H" beginning-of-line
-bindkey "^[[F" end-of-line #End
-bindkey -a "^[[F" end-of-line
+KEYTIMEOUT=10
+## populate key array
+if (( $#terminfo == 0 )) {
+ # terminfo is not set or empty
+ function find_keymap {
+ for f in ${ZDOTDIR:-$HOME}/.zkbd/${TERM}{-${DISPLAY:-${VENDOR}-${OSTYPE}},}
+ [[ -f $f ]] && keymap=$f && break
+ }
+ find_keymap
+ if [[ -z $keymap ]] {
+ if read -q "?Can't read terminfo. Add new zkbd keymap? [y/N]"; then
+ echo
+ autoload -Uz zkbd && zkbd
+ unfunction zkbd
+ find_keymap
+ fi
+ echo
+ }
+ if [[ -n $keymap ]] {
+ source $keymap
+ } else {
+ echo "Failed to source keymap file $keymap" >&2
+ }
+ unfunction find_keymap; unset keymap
+} else {
+ # activate application mode for zle so terminfo keys work
+ # NOTE: don't do this for zkbd since application mode shouldn't have been
+ # enabled by zkbd when the keymap file was generated
+ if [[ -v terminfo[smkx] && -v terminfo[rmkx] ]] {
+ autoload -Uz add-zle-hook-widget
+ function _enter-application-mode { echoti smkx }
+ add-zle-hook-widget line-init _enter-application-mode
+ function _exit-application-mode { echoti rmkx }
+ add-zle-hook-widget line-finish _exit-application-mode
+ trap _exit-application-mode EXIT
+ }
+ # match zkbd hash as best we can to terminfo
+ typeset -gA key
+ key[F1]=$terminfo[kf1]
+ key[F2]=$terminfo[kf2]
+ key[F3]=$terminfo[kf3]
+ key[F4]=$terminfo[kf4]
+ key[F5]=$terminfo[kf5]
+ key[F6]=$terminfo[kf6]
+ key[F7]=$terminfo[kf7]
+ key[F8]=$terminfo[kf8]
+ key[F9]=$terminfo[kf9]
+ key[F10]=$terminfo[kf10]
+ key[F11]=$terminfo[kf11]
+ key[F12]=$terminfo[kf12]
+ key[Backspace]=$terminfo[kbs]
+ key[Insert]=$terminfo[kich1]
+ key[Home]=$terminfo[khome]
+ key[PageUp]=$terminfo[kpp]
+ key[Delete]=$terminfo[kdch1]
+ key[End]=$terminfo[kend]
+ key[PageDown]=$terminfo[knp]
+ key[Up]=$terminfo[kcuu1]
+ key[Down]=$terminfo[kcud1]
+ key[Left]=$terminfo[kcub1]
+ key[Right]=$terminfo[kcuf1]
+ #key[Menu]=$terminfo[] #TODO: not in termcap?
+}