about summary refs log tree commit diff
path: root/Functions/Misc/add-zsh-hook
diff options
context:
space:
mode:
Diffstat (limited to 'Functions/Misc/add-zsh-hook')
-rw-r--r--Functions/Misc/add-zsh-hook63
1 files changed, 63 insertions, 0 deletions
diff --git a/Functions/Misc/add-zsh-hook b/Functions/Misc/add-zsh-hook
new file mode 100644
index 000000000..fa8015a3d
--- /dev/null
+++ b/Functions/Misc/add-zsh-hook
@@ -0,0 +1,63 @@
+# Add to HOOK the given FUNCTION.
+# HOOK is one of chpwd, precmd, preexec, periodic, zshexit (the
+# _functions subscript is not required).
+#
+# With -d, remove the function from the hook instead; delete the hook
+# variable if it is empty.
+#
+# Without -d, the FUNCTION is marked for autoload; -U is passed down to
+# autoload if that is given.  (This is harmless if the function is actually
+# defined inline.)
+
+emulate -L zsh
+
+local -a hooktypes
+hooktypes=(chpwd precmd preexec periodic zshexit)
+
+local opt
+local -a autoopts
+integer del
+
+while getopts "d" opt; do
+  case $opt in
+    (d)
+    del=1
+    ;;
+
+    (U)
+    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
+    set -A $hook ${(P)hook:#$fn}
+    # unset if no remaining entries --- this can give better
+    # performance in some cases
+    (( ${(P)#hook} )) || unset $hook
+  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