5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

シェルのプロンプト何にしてますか?よくあるのは "$ " でしょうか。

$ 

もうちょっとリッチにホストやユーザ名などが載ったプロンプトもよく見ます。

user@host:~/$ 

これは色々な情報が得られて分かりやすい一方、いくつか不満があります。

たとえば現在の作業ディレクトリ(current working directory, CWD)の長さは可変なのでディレクトリを移動するたびに入力するコマンドの開始位置がずれてしまいます。

user@host:~/$ cd tmp
user@host:~/tmp$ cd other
user@host:~/tmp/other$ 

これではあとから何を入力したか分かりづらいですよね。

また、ユーザ名やホスト名はリモートログンする人には重要ですが手元の環境では不要です。プロンプトが無駄に横に伸びてしまって長いコマンドを打つときに不便です。

そこで、私はzshで画像のような以下のようなプロンプトを使っています。

image.png

プロンプトはシンプルに "(" です。"$ " より1文字少ないですね。zshには普通のプロンプトの他に右プロンプトも表示できるので、そちらにCWDを載せています。全体的に実行するコマンドがCommon Lispの関数と引数、キーワード引数のように見えるようになっています。

このキーワード引数部分には条件つきで他の情報も表示しています。例えばCWDがgitのリポジトリ内であればその旨とブランチを出します。
image.png
stageされてないコミットがあればブランチ名は赤になり
image.png
それをstagingすると緑になります
image.png
git以外にもいくつか別のバージョン管理システム(version control systems, VCS)に対応しています。

あとは直前のコミットが失敗するとその終了ステータス ($? 変数の中身)も表示します。
image.png

CWDやVCSの状態、直前のコマンドの結果などは頻繁に参照するので割と気に入っています。

多分以下のコードを ~/.zshrc に貼り付けたら真似できると思います

setopt prompt_subst
setopt transient_rprompt
# {{{ methods for RPROMPT
# fg[color]表記と$reset_colorを使いたい
# @see https://wiki.archlinux.org/index.php/zsh
autoload -U colors; colors

PROMPT="("
RPROMPT='$(check-status $?)$(vcs-stuff)$(colorize red :cwd) %~)'
colorize() {
    echo "%{${fg[$1]}%}$2%{${reset_color}%}"
}

check-status() {
    if [ ! $1 -eq 0 ];then
        echo "$(colorize red :\$\?) $1 "
    else
        echo ""
    fi
}

vcs-stuff() {
    if is-git-repo; then
        echo "$(colorize red :vcs) git $(git-branch-status-check)$(git-stash-count)"
    elif is-hg-repo; then
        echo "$(colorize red :vcs) hg $(hg-branch-status-check)"
    elif is-pijul-repo; then
        echo "$(colorize red :vcs) pijul $(pijul-channel-status-check)"
    fi
}

is-git-repo() {
    git remote >& /dev/null
}

is-hg-repo() {
     hg root >& /dev/null
}

is-pijul-repo() {
    pijul remote >& /dev/null
}


git-stash-count() {
  local COUNT=$(git stash list 2>/dev/null | wc -l | tr -d ' ')
  if [ "$COUNT" -gt 0 ]; then
    echo "$(colorize red :stashes) $COUNT "
  fi
}

git-branch-status-check() {
    local prefix branchname suffix
    branchname="$(git rev-parse --abbrev-ref HEAD 2> /dev/null)"
    # ブランチ名が無いので除外
    if [[ -z $branchname ]]; then
        return
    fi
    prefix=`git-get-branch-status` #色だけ返ってくる
    suffix='%{'${reset_color}'%}'
    echo "$(colorize red :branch) ${prefix}${branchname}${suffix} "
}

git-get-branch-status() {
    local res color workdir index
    git diff --quiet
    workdir=$?
    git diff --cached --quiet
    index=$?
    if [ "$workdir" = 0 ] && [ "$index" = 0 ]; then
        color='%{'${fg[white]}'%}'
    elif [ "$workdir" = 1 ]; then
        color='%{'${fg[red]}'%}'
    else # implies $index = 1 
        color='%{'${fg[green]}'%}'
    fi
    echo ${color} # 色だけ返す
}

hg-branch-status-check() {
    local prefix branchname suffix
    branchname="$(hg branch 2> /dev/null)"
    # ブランチ名が無いので除外
    if [[ -z $branchname ]]; then
        return
    fi
    prefix=`hg-get-branch-status` #色だけ返ってくる
    suffix='%{'${reset_color}'%}'
    echo "$(colorize red :branch) ${prefix}${branchname}${suffix} "
}
hg-get-branch-status() {
    local res color workdir index
    workdir="$(hg status -m -d | wc -l)"
    index="$(hg status -a -r | wc -l)"
    if [ "$workdir" = 0 ] && [ "$index" = 0 ]; then
        color='%{'${fg[white]}'%}'
    elif [ "$workdir" != 0 ]; then
        color='%{'${fg[red]}'%}'
    else # implies $index != 10
        color='%{'${fg[green]}'%}'
    fi
    echo ${color} # 色だけ返す
}

pijul-channel-status-check() {
    local prefix channelname suffix
    channelname="$(pijul channel | sed -n '/^\*/{s/^\* //;p;q}'  2> /dev/null)"
    # ブランチ名が無いので除外
    if [[ -z $channelname ]]; then
        return
    fi
    prefix=`pijul-get-channel-status` #色だけ返ってくる
    suffix='%{'${reset_color}'%}'
    echo "$(colorize red :branch) ${prefix}${channelname}${suffix} "
}
pijul-get-channel-status() {
    local res color workdir index
    workdir="$(pijul diff -s | wc -l)"
    if [ "$workdir" = 0 ] ; then
        color='%{'${fg[white]}'%}'
    else # implies workdir != 0
        color='%{'${fg[red]}'%}'
    fi
    echo ${color} # 色だけ返す
}
5
2
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
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?