From: Simon Ruderich Date: Sun, 8 Feb 2009 15:49:57 +0000 (+0100) Subject: Simulate hooks using _functions arrays for older versions. X-Git-Url: https://ruderich.org/simon/gitweb/?a=commitdiff_plain;h=dacacb00aef58048b64f4705923bdb49bc6a8364;p=config%2Fdotfiles.git Simulate hooks using _functions arrays for older versions. This allows the usage of add-zsh-hook also for older version. add-zsh-hook is provided in functions/compatibility and was taken from Zsh 4.3.9. --- diff --git a/zsh/functions/compatibility/add-zsh-hook b/zsh/functions/compatibility/add-zsh-hook new file mode 100644 index 0000000..aedc1e7 --- /dev/null +++ b/zsh/functions/compatibility/add-zsh-hook @@ -0,0 +1,76 @@ +# Add to HOOK the given FUNCTION. +# HOOK is one of chpwd, precmd, preexec, periodic, zshaddhistory, +# zshexit (the _functions subscript is not required). +# +# With -d, remove the function from the hook instead; delete the hook +# variable if it is empty. +# +# -D behaves like -d, but pattern characters are active in the +# function name, so any matching function will be deleted from the hook. +# +# Without -d, the FUNCTION is marked for autoload; -U is passed down to +# autoload if that is given, as are -z and -k. (This is harmless if the +# function is actually defined inline.) + +emulate -L zsh + +local -a hooktypes +hooktypes=(chpwd precmd preexec periodic zshaddhistory zshexit) + +local opt +local -a autoopts +integer del + +while getopts "dDUzk" opt; do + case $opt in + (d) + del=1 + ;; + + (D) + del=2 + ;; + + ([Uzk]) + autoopts+=(-$opt) + ;; + + (*) + return 1 + ;; + esac +done +shift $(( OPTIND - 1 )) + +if (( $# != 2 || ${hooktypes[(I)$1]} == 0 )); then + print "Usage: $0 hook function\nValid hooks are:\n $hooktypes" + return 1 +fi + +local hook="${1}_functions" +local fn="$2" + +if (( del )); then + # delete, if hook is set + if (( ${(P)+hook} )); then + if (( del == 2 )); then + set -A $hook ${(P)hook:#${~fn}} + else + set -A $hook ${(P)hook:#$fn} + fi + # unset if no remaining entries --- this can give better + # performance in some cases + if (( ! ${(P)#hook} )); then + unset $hook + fi + fi +else + if (( ${(P)+hook} )); then + if (( ${${(P)hook}[(I)$fn]} == 0 )); then + set -A $hook ${(P)hook} $fn + fi + else + set -A $hook $fn + fi + autoload $autoopts -- $fn +fi diff --git a/zsh/rc b/zsh/rc index 6348432..0d702b0 100644 --- a/zsh/rc +++ b/zsh/rc @@ -42,6 +42,25 @@ fpath=(~/.zsh/functions $fpath) # to caphuso from the Zsh example files for this idea. autoload ${fpath[1]}/^_*(^/:t) +# Simulate hooks using _functions arrays for Zsh versions older then 4.3.4. At +# the moment only precmd() and preexec() are simulated. +if [[ $ZSH_VERSION != (4.3.<4->|4.<4->*|<5->*) ]]; then + # Provide add-zsh-hook which was added in 4.3.4. + fpath=($fpath ~/.zsh/functions/compatibility) + + # Run all functions defined in the ${precmd,preexec}_functions arrays. + function precmd() { + for function in $precmd_functions; do + $function $@ + done + } + function preexec() { + for function in $preexec_functions; do + $function $@ + done + } +fi + # Autoload add-zsh-hook to add/remove zsh hook functions easily. autoload -Uz add-zsh-hook