もた日記

くだらないことを真面目にやる

Oh My Zshの処理を見てみる(3) : テーマの設定


~/.zshrc


テーマについては~/.zshrcZSH_THEMEで好きなテーマ名を設定する。コメントに書いてあるようにZSH_THEME="random"と設定すれば起動時にランダムでテーマが選択される。どのテーマも有効にしたくない場合はZSH_THEME=""のようにする。

# Set name of the theme to load. Optionally, if you set this to "random"
# it'll load a random theme each time that oh-my-zsh is loaded.
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
ZSH_THEME="robbyrussell"


oh-my-zsh.sh


実際にどのようにテーマを選択しているかはoh-my-zsh.shで確認できる。"random"を指定した場合は、$ZSH/themes以下にあるテーマをランダムで選択している。
テーマ名を指定した場合は$ZSH_CUSTOM$ZSH_CUSTOM/themes$ZSH/themesの順番でテーマファイルを探す。コードを見てわかるようにテーマファイルの拡張子は.zsh-themeとなっている必要がある。

# Load the theme
if [ "$ZSH_THEME" = "random" ]; then
  themes=($ZSH/themes/*zsh-theme)
  N=${#themes[@]}
  ((N=(RANDOM%N)+1))
  RANDOM_THEME=${themes[$N]}
  source "$RANDOM_THEME"
  echo "[oh-my-zsh] Random theme '$RANDOM_THEME' loaded..."
else
  if [ ! "$ZSH_THEME" = ""  ]; then
    if [ -f "$ZSH_CUSTOM/$ZSH_THEME.zsh-theme" ]; then
      source "$ZSH_CUSTOM/$ZSH_THEME.zsh-theme"
    elif [ -f "$ZSH_CUSTOM/themes/$ZSH_THEME.zsh-theme" ]; then
      source "$ZSH_CUSTOM/themes/$ZSH_THEME.zsh-theme"
    else
      source "$ZSH/themes/$ZSH_THEME.zsh-theme"
    fi
  fi
fi


使用可能なテーマの一覧


デフォルトで使用可能なテーマの見た目の一部は下記ページで確認できる。

Themes · robbyrussell/oh-my-zsh Wiki · GitHub

また、下記ページでview all zsh themesをクリックすれば色々なテーマが確認できる(数が多いのでロードに時間がかかる)。

zsh themes - all about z shell and oh-my-zsh themes

テーマ名だけを確認したいのであれば$ZSH/themesディレクトリ以下にあるファイル名を見ればよい。


Externalテーマ


Oh My Zshでは新しいテーマはもう受け付けていないらしく、デフォルトのテーマ以外は下記ページで確認できる。
External themes · robbyrussell/oh-my-zsh Wiki · GitHub

これらのテーマを追加したい場合は$ZSH_CUSTOM/themesディレクトリにテーマファイルを追加して~/.zshrcでテーマ名を指定すればよい。


themeプラグインでテーマを確認


自分の環境でどのような見た目になるかはthemeプラグインを使用して確認するのがよい。~/.zshrcで以下のようにプラグインを追加してsource ~/.zshrcを実行する。

plugins=(git theme)

plugins/themes/themes.plugin.zshは以下のようになっており、themelstheme関数が使えるようになる。

function theme
{
    if [ -z "$1" ] || [ "$1" = "random" ]; then
	themes=($ZSH/themes/*zsh-theme)
	N=${#themes[@]}
	((N=(RANDOM%N)+1))
	RANDOM_THEME=${themes[$N]}
	source "$RANDOM_THEME"
	echo "[oh-my-zsh] Random theme '$RANDOM_THEME' loaded..."
    else
	if [ -f "$ZSH_CUSTOM/$1.zsh-theme" ]
	then
	    source "$ZSH_CUSTOM/$1.zsh-theme"
	else
	    source "$ZSH/themes/$1.zsh-theme"
	fi
    fi
}

function lstheme
{
    cd $ZSH/themes
    ls *zsh-theme | sed 's,\.zsh-theme$,,'
}

lsthemeを実行すれば、現在使用可能なテーマの一覧が確認できる。

$ lstheme
3den
Soliah
adben
af-magic
afowler
 …

テーマを変更したい場合は、theme <テーマ名>と実行すればすぐに変更される。もちろんtheme randomのようにランダムで選択することも可能。ただし、前のテーマの$RPROMPTの設定を引き継ぐなどバグがある模様。

$ theme robbyrussell


tools/theme_chooser.shでテーマを確認


プラグインではなくtools/theme_chooser.shスクリプトを使う方法もある。使い方は以下の通りで、

$ ~/.oh-my-zsh/tools/theme_chooser.sh -h
Usage: usage [options] [theme]

Options
  -l   List available themes
  -s   Show all themes
  -h   Get this help message

-lオプションを指定すれば使用可能なテーマ一覧が確認できる。

$ ~/.oh-my-zsh/tools/theme_chooser.sh -l
3den
Soliah
adben
af-magic
afowler
 …

-sオプションを指定すれば全てのテーマを適用した結果が一覧で確認できるが、前のテーマの$RPROMPTの設定を引き継いだり、表示位置がずれるバグがある模様。

$ ~/.oh-my-zsh/tools/theme_chooser.sh -s


テーマファイルの設定例


$ZSH/themes/robbyrussell.zsh-themeテーマの内容は下記の通りであるが、何が設定されているかを見てみる。

local ret_status="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ )"
PROMPT='${ret_status} %{$fg[cyan]%}%c%{$reset_color%} $(git_prompt_info)'

ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[blue]%}git:(%{$fg[red]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}) %{$fg[yellow]%}✗"
ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%})"

基本となるのはPROMPTでプロンプトの見た目を設定している。色設定を除外すると表示内容は${ret_status}%c$(git_prompt_info)%cはカレントディレクトリを表示する。プロンプトで利用できるエスケープ文字は下記ページが参考になる。

てげてげきばる日記: zsh 設定 - プロンプト -

色設定については、変更したい所を%{$fg[cyan]%}%{$reset_color%}など色を指定して囲む。%{$fg[cyan]%}で色指定を開始して、%{$reset_color%}で色指定を戻す。使える色については下記ページが参考になる。

zshでプロンプトをカラー表示する - Qiita

${ret_status}はコマンドの終了ステータスによりを色分けして表示している。%?がコマンドの終了ステータスを意味し、%(?:<正常終了>:<異常終了>という条件分岐をしているようだ。

$(git_prompt_info)はGitで管理している場合に表示される内容で、$ZSH/lib/git.zshに詳細が記述されている。${ref#refs/heads/}$(parse_git_dirty)$$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_SUFFIXで囲んでおり、リポジトリの変更の有無により$ZSH_THEME_GIT_PROMPT_DIRTY$ZSH_THEME_GIT_PROMPT_CLEANを選択している。

# Outputs current branch info in prompt format
function git_prompt_info() {
  local ref
  if [[ "$(command git config --get oh-my-zsh.hide-status 2>/dev/null)" != "1" ]]; then
    ref=$(command git symbolic-ref HEAD 2> /dev/null) || \
    ref=$(command git rev-parse --short HEAD 2> /dev/null) || return 0
    echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_SUFFIX"
  fi
}

# Checks if working tree is dirty
function parse_git_dirty() {
  local STATUS=''
  local FLAGS
  FLAGS=('--porcelain')
  if [[ "$(command git config --get oh-my-zsh.hide-dirty)" != "1" ]]; then
    if [[ $POST_1_7_2_GIT -gt 0 ]]; then
      FLAGS+='--ignore-submodules=dirty'
    fi
    if [[ "$DISABLE_UNTRACKED_FILES_DIRTY" == "true" ]]; then
      FLAGS+='--untracked-files=no'
    fi
    STATUS=$(command git status ${FLAGS} 2> /dev/null | tail -n1)
  fi
  if [[ -n $STATUS ]]; then
    echo "$ZSH_THEME_GIT_PROMPT_DIRTY"
  else
    echo "$ZSH_THEME_GIT_PROMPT_CLEAN"
  fi
}

その他、このテーマには設定されていないがRPROMPTでプロンプトの右端に表示する内容を設定できる。


オリジナルテーマの作成


例えばmy_awesome_themeというオリジナルテーマを作成したい場合は、$ZSH_CUSTOM/themesmy_awesome_theme.zsh-themeというファイルを作成しPROMPTなどを記述する。その後、~/.zshrcZSH_THEME="my_awesome_theme"と設定すればオリジナルテーマが有効になる。