zshでprecmdやpreexec、chpwdなどを定義する場合、precmd(){…}のようにそのまま関数を定義する方法と、add-zsh-hookを使ってフックする関数を登録する方法があります。
前者の方法のみであれば、普通にprecmd関数を呼べば良いが、後者の方法を使用してる場合はどうするかという話。
add-zsh-hookで登録した関数は、precmdであればprecmd_functions変数に配列として登録されています。
よってこの配列を使用して以下のように関数を呼び出します。
for precmd_func in $precmd_functions; do
$precmd_func
done
また、precmd以外では、以下のような変数に対応しています。
-
preexec:preexec_functions -
chpwd:chpwd_functions
どういうときに使用するか
例えば、^キーで親ディレクトリに移動するという設定を行なっている場合。
cdup() {
if [ -z "$BUFFER" ]; then
echo
cd ..
zle reset-prompt
else
zle self-insert '^'
fi
}
zle -N cdup
bindkey '\^' cdup
このとき、関数内でcdを実行してもprecmdが呼ばれません。
そのため、プロンプトの更新やターミナルタイトルの変更をprecmd内で行なっている場合、状態変更が反映されません。
そこで以下のようにしてprecmdを明示的に呼び出します。
cdup() {
if [ -z "$BUFFER" ]; then
echo
cd ..
if type precmd > /dev/null 2>&1; then
precmd
fi
local precmd_func
for precmd_func in $precmd_functions; do
$precmd_func
done
zle reset-prompt
else
zle self-insert '^'
fi
}
zle -N cdup
bindkey '\^' cdup