1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Zshの複数行プロンプトでコマンド実行後は1行だけ残す

Posted at

やりたいこと

Zshの複数行プロンプトで、例えばGitのワーキングツリー状態などを出している場合、コマンド実行後は画面に残したくないんです。
スクリーンショット 2020-06-13 8.29.03.png
Git情報は入力受付中のプロンプトにだけ出ていればよくて、コマンド実行後はGit情報を消して1行だけのプロンプトを画面に残したいわけです。

やりかた

複数行プロンプトを設定する際、あらかじめ1行版のプロンプトを変数に入れておき、それ以外の行と連結する形で$PROMPTを設定しておきます。下記の例では、普段は1行のプロンプトですが、Gitリポジトリ内部にいるときのみ1行目がGit情報・2行目が通常のプロンプトとなるようにしています。

# 1行版のプロンプトの中身を $BASE_PROMPT 変数に入れる
case $TERM in
    xterm*)
        BASE_PROMPT=$'%{\e]0;[%n@%m:%~]\a%}'$'[%n@%m%{\e[00m%}]%(5~,%-1~/.../%1~,%~)%# '
        ;;
    *)
        BASE_PROMPT=$'[%n@%m%{\e[00m%}]%(5~,%-2~/.../%2~,%~)%# '
        ;;
esac

# Gitが公式に配布している git-prompt.sh を利用
source ~/.zsh/git-prompt.sh

# プロンプト表示前にGitの状態を検知してプロンプトを書き換える
precmd () {
    local git_prompt="$(__git_ps1 '%s')"
    if [[ -n "$git_prompt" ]]; then
        # Gitリポジトリの内部にいるとき、ワーキングツリーの状態によって色を切り替える
        local color=34 # blue
        if [[ $git_prompt == *'*'* ]]; then
            color=31 # red
        elif [[ $git_prompt == *'%'* ]]; then
            color=33 # yellow
        elif [[ $git_prompt == *'+'* ]]; then
            color=32 # green
        elif [[ $git_prompt == *'$'* ]]; then
            color=35 # magenta
        fi
        PROMPT=$'\e['"$color"$'m(\ue0a0 '"$git_prompt"$')\e[0m\n'"$BASE_PROMPT"
    else
        PROMPT="$BASE_PROMPT"
    fi
}

# git-prompt.sh 用のオプション設定
GIT_PS1_SHOWDIRTYSTATE=1
GIT_PS1_SHOWSTASHSTATE=1
GIT_PS1_SHOWUNTRACKEDFILES=1
GIT_PS1_SHOWUPSTREAM=""
GIT_PS1_DESCRIBE_STYLE="branch"
GIT_PS1_SHOWCOLORHINTS=0

ここまでだけなら、ただの複数行プロンプトです。次が本記事のポイントで、コマンド実行後にプロンプトを1行だけ残す部分です。

# Enter を打った時に実行する関数
function my_accept_line() {
    # プロンプトにgit状態も表示されている場合、git状態の表示を消す
    if [[ ${#PROMPT} -ne ${#BASE_PROMPT} ]]; then
        local saved_prompt=$PROMPT
        PROMPT=$BASE_PROMPT
        zle reset-prompt
        PROMPT=$saved_prompt
    fi
    zle accept-line
}
zle -N my_accept_line
bindkey '^M' my_accept_line

ZLEの機能を使って、Enterを打った際にプロンプトを書き換えます。一時的にプロンプトを1行版プロンプトにし、 zle reset-prompt によってプロンプトおよび入力されたコマンドを再描画するのがミソです。なお、再描画後はプロンプトを元の複数行版に戻しています。

結果

画面から不要な情報が消えてスッキリしました。
スクリーンショット 2020-06-13 8.32.40.png

1
0
0

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
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?