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