search
LoginSignup
12

More than 5 years have passed since last update.

posted at

precmdを明示的に呼ぶ方法

zshでprecmdpreexecchpwdなどを定義する場合、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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
12