ターミナルのプロンプトをカスタマイズ

更新:2025-02-26
Shell

概要

Gitのブランチ名を表示したり色付けしたりして、ターミナルのプロンプトをカスタマイズする。ここでのシェルはzshを想定している。

基本

ホームディレクトリにある.zshrcファイルに設定を追記してカスタマイズする。具体的には%n%mのようなパラメータを組み合わせる。

~/.zshrc
PROMPT='%n@%m %~ %# '

以下のように出力される。

example
username@hostname ~/path/from/home_directory % ここにコマンドを入力
username@hostname ~/path/from/home_directory % ここにコマンドを入力
...

.zshrcファイルを更新した後は、exec $SHELL -lで新しいログインシェルを起動して反映を確認。

Gitのブランチ名を表示する

git-promptを使う。

ダウンロード

~
curl -o ~/.git-prompt.sh https://raw.githubusercontent.com/git/git/refs/heads/master/contrib/completion/git-prompt.sh

実装

.zshrcファイルに追記。プロンプトを見やすくするために、ユーザー名やパスの表示部分をそれぞれ関数化しておく。

~/.zshrc
# git-promptを読み込む
. ~/.git-prompt.sh
# gitの状態に応じて記号を表示する
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
# gitの情報を表示する
current_git_info() {
if [[ -d .git ]]; then
__git_ps1 "%s"
fi
}
username_and_hostname() {
echo "%n@%m"
}
path_from_home() {
echo "%~"
}
# プロンプトを表示する
setopt PROMPT_SUBST ; PS1='
$(username_and_hostname)
$(path_from_home) $(current_git_info) %# '
example
username@hostname
~/path/from/home_directory main % ここにコマンドを入力
username@hostname
~/path/from/home_directory main % ここにコマンドを入力
...

Gitのユーザー名を表示する

複数のgitユーザーを使い分ける場合に、自分が誰なのか?を調べる手間を省く。

~/.zshrc
...
current_git_user_name() {
if [[ -d .git ]]; then
echo "$(git config user.name)"
fi
}
...
$(path_from_home) $(current_git_info) %# '
$(path_from_home) $(current_git_info) $(current_git_user_name) %# '
example
username@hostname
~/path/from/home_directory main git_username % ここにコマンドを入力
username@hostname
~/path/from/home_directory main git_username % ここにコマンドを入力
...

色をつける

文字色を変更する場合は%F{色番号}%fで囲む。ハイライトする場合は%K{色番号}%kで囲む。色番号について調べるとよく0〜7が出てくるが、それだと良い感じの色を指定できないこともあるので、256色で指定する。

ハイライトは余白が欲しくなるので、半角スペースを入れた。

~/.zshrc
...
adjusted_git_info() {
if [[ -d .git ]]; then
local result="$(current_git_info)"
echo "%K{025} %F{254}${result}%f %k"
fi
}
current_git_user_name() {
if [[ -d .git ]]; then
echo "$(git config user.name)"
echo "%K{044} $(git config user.name) %k"
fi
}
username_and_hostname() {
echo "%n@%m"
echo "%F{244}%n@%m%f"
}
path_from_home() {
echo "%~"
echo "%F{006}%~%f"
}
...
$(path_from_home) $(current_git_info) $(current_git_user_name) %# '
$(path_from_home) $(adjusted_git_info) $(current_git_user_name) %# '

gitの情報を微調整

  • ステージング状態で色分け。
  • gitの情報とユーザー名の間は半角スペースないほうが良い感じ。
~/.zshrc
...
adjusted_git_info() {
if [[ -d .git ]]; then
local result="$(current_git_info)"
echo "%K{025} %F{254}${result}%f %k"
# 未ステージングあり
if echo "$result" | grep -q "*"; then
echo "%K{009} %F{254}${result}%f %k"
# すべてステージング済み
elif echo "$result" | grep -q "+"; then
echo "%K{010} ${result} %k"
# 通常時
else
echo "%K{025} %F{254}${result}%f %k"
fi
fi
}
...
$(path_from_home) $(adjusted_git_info) $(current_git_user_name) %# '
$(path_from_home) $(adjusted_git_info)$(current_git_user_name) %# '

最終版

~/.zshrc
# ▼ プロンプトのカスタマイズ --------
# git-promptを読み込む
. ~/.git-prompt.sh
# gitの状態に応じて記号を表示する
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
# gitの情報を表示する
current_git_info() {
if [[ -d .git ]]; then
__git_ps1 "%s"
fi
}
adjusted_git_info() {
if [[ -d .git ]]; then
local result="$(current_git_info)"
# 未ステージングあり
if echo "$result" | grep -q "*"; then
echo "%K{009} %F{254}${result}%f %k"
# すべてステージング済み
elif echo "$result" | grep -q "+"; then
echo "%K{010} ${result} %k"
# 通常時
else
echo "%K{025} %F{254}${result}%f %k"
fi
fi
}
current_git_user_name() {
if [[ -d .git ]]; then
echo "%K{044} $(git config user.name) %k"
fi
}
username_and_hostname() {
echo "%F{244}%n@%m%f"
}
path_from_home() {
echo "%F{006}%~%f"
}
# プロンプトを表示する
setopt PROMPT_SUBST ; PS1='
$(username_and_hostname)
$(path_from_home) $(adjusted_git_info)$(current_git_user_name) %# '
# ▲ プロンプトのカスタマイズ --------

余談

git-promptで未追跡が%で表示されるのを?に置換したかったが、その後の表示で%fが溢れる?などうまくいかなかったので断念した。

いちおう置換コードを残しておく
# 未追跡は「%」ではなく「?」で表示
result=${result/\%/\?}

続く...かもね