.zshrcを設定してみる

zshの設定を見直してみました。
今使っている.zshrcを載せてみたいと思います。
本来、環境変数やパスの設定は.zshenvに記述する方が良いらしいですが、今回は.zshrcにまとめます。

環境
  • OS
    • ProductName: Mac OS X
    • ProductVersion: 10.7.2
    • BuildVersion: 11C74
.zshrc
# (d) is default on

# ------------------------------
# General Settings
# ------------------------------
export EDITOR=vim        # エディタをvimに設定
export LANG=ja_JP.UTF-8  # 文字コードをUTF-8に設定
export KCODE=u           # KCODEにUTF-8を設定
export AUTOFEATURE=true  # autotestでfeatureを動かす

bindkey -e               # キーバインドをemacsモードに設定
#bindkey -v              # キーバインドをviモードに設定

setopt no_beep           # ビープ音を鳴らさないようにする
setopt auto_cd           # ディレクトリ名の入力のみで移動する 
setopt auto_pushd        # cd時にディレクトリスタックにpushdする
setopt correct           # コマンドのスペルを訂正する
setopt magic_equal_subst # =以降も補完する(--prefix=/usrなど)
setopt prompt_subst      # プロンプト定義内で変数置換やコマンド置換を扱う
setopt notify            # バックグラウンドジョブの状態変化を即時報告する
setopt equals            # =commandを`which command`と同じ処理にする

### Complement ###
autoload -U compinit; compinit # 補完機能を有効にする
setopt auto_list               # 補完候補を一覧で表示する(d)
setopt auto_menu               # 補完キー連打で補完候補を順に表示する(d)
setopt list_packed             # 補完候補をできるだけ詰めて表示する
setopt list_types              # 補完候補にファイルの種類も表示する
bindkey "^[[Z" reverse-menu-complete  # Shift-Tabで補完候補を逆順する("\e[Z"でも動作する)
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' # 補完時に大文字小文字を区別しない

### Glob ###
setopt extended_glob # グロブ機能を拡張する
unsetopt caseglob    # ファイルグロブで大文字小文字を区別しない

### History ###
HISTFILE=~/.zsh_history   # ヒストリを保存するファイル
HISTSIZE=10000            # メモリに保存されるヒストリの件数
SAVEHIST=10000            # 保存されるヒストリの件数
setopt bang_hist          # !を使ったヒストリ展開を行う(d)
setopt extended_history   # ヒストリに実行時間も保存する
setopt hist_ignore_dups   # 直前と同じコマンドはヒストリに追加しない
setopt share_history      # 他のシェルのヒストリをリアルタイムで共有する
setopt hist_reduce_blanks # 余分なスペースを削除してヒストリに保存する

# マッチしたコマンドのヒストリを表示できるようにする
autoload history-search-end
zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end
bindkey "^P" history-beginning-search-backward-end
bindkey "^N" history-beginning-search-forward-end

# すべてのヒストリを表示する
function history-all { history -E 1 }


# ------------------------------
# Look And Feel Settings
# ------------------------------
### Ls Color ###
# 色の設定
export LSCOLORS=Exfxcxdxbxegedabagacad
# 補完時の色の設定
export LS_COLORS='di=01;34:ln=01;35:so=01;32:ex=01;31:bd=46;34:cd=43;34:su=41;30:sg=46;30:tw=42;30:ow=43;30'
# ZLS_COLORSとは?
export ZLS_COLORS=$LS_COLORS
# lsコマンド時、自動で色がつく(ls -Gのようなもの?)
export CLICOLOR=true
# 補完候補に色を付ける
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}

### Prompt ###
# プロンプトに色を付ける
autoload -U colors; colors
# 一般ユーザ時
tmp_prompt="%{${fg[cyan]}%}%n%# %{${reset_color}%}"
tmp_prompt2="%{${fg[cyan]}%}%_> %{${reset_color}%}"
tmp_rprompt="%{${fg[green]}%}[%~]%{${reset_color}%}"
tmp_sprompt="%{${fg[yellow]}%}%r is correct? [Yes, No, Abort, Edit]:%{${reset_color}%}"

# rootユーザ時(太字にし、アンダーバーをつける)
if [ ${UID} -eq 0 ]; then
  tmp_prompt="%B%U${tmp_prompt}%u%b"
  tmp_prompt2="%B%U${tmp_prompt2}%u%b"
  tmp_rprompt="%B%U${tmp_rprompt}%u%b"
  tmp_sprompt="%B%U${tmp_sprompt}%u%b"
fi

PROMPT=$tmp_prompt    # 通常のプロンプト
PROMPT2=$tmp_prompt2  # セカンダリのプロンプト(コマンドが2行以上の時に表示される)
RPROMPT=$tmp_rprompt  # 右側のプロンプト
SPROMPT=$tmp_sprompt  # スペル訂正用プロンプト
# SSHログイン時のプロンプト
[ -n "${REMOTEHOST}${SSH_CONNECTION}" ] &&
  PROMPT="%{${fg[white]}%}${HOST%%.*} ${PROMPT}"
;

### Title (user@hostname) ###
case "${TERM}" in
kterm*|xterm*|)
  precmd() {
    echo -ne "\033]0;${USER}@${HOST%%.*}\007"
  }
  ;;
esac


# ------------------------------
# Other Settings
# ------------------------------
### RVM ###
if [[ -s ~/.rvm/scripts/rvm ]] ; then source ~/.rvm/scripts/rvm ; fi

### Macports ###
case "${OSTYPE}" in
  darwin*)
    export PATH=/opt/local/bin:/opt/local/sbin:$PATH
    export MANPATH=/opt/local/share/man:/opt/local/man:$MANPATH
  ;;
esac

### Aliases ###
alias r=rails
alias v=vim

# cdコマンド実行後、lsを実行する
#function cd() {
#  builtin cd $@ && ls;
#}


この中でも特筆できるような設定をピックアップしてみたいと思います。

Shift-Tabで補完候補を逆順する

bindkey "^[[Z" reverse-menu-complete  # Shift-Tabで補完候補を逆順する("\e[Z"でも動作する)

補完機能を有効にしたことで、Tabキーで補完候補が表示される訳ですが、
Tabを連打してお目当ての補完候補を通り過ぎてしまうことがあります。
そこでこの設定をしておくと、Shift-Tabで逆方向に補完してくれるようになります。

ちなみに

設定しているとき、"^[[Z"って何ってなんだ?となったんですが、まあ要するにShift-Tabのことですww
こういったキーコード?を調べる方法があります。
Ctrl-Vを押した後、調べたいキーを押せば、該当のキーコードが表示されます。

Ctrl-V押下後、上矢印キー
> ^[[A
Ctrl-V押下後、Shift-Tabキー
> ^[[Z

ただコメントに括弧して書いているのですが、"\e[Z"でも動作するようです。
どういうことなのかよく分からないな・・・(;´・ω・)ゝ
分かる方がいましたら、是非ご教授ください!

補完時に大文字小文字を区別しない

zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'

例えばDocuments, downloadsというディレクトリがあったとき、
"cd d"までタイプしTabを押すとDocuments, downloads両方を補完してくれる訳です。
ただし、"cd D"でTabを押すとdownloadsは候補にはなりません。
使い勝手としてはまったく問題ないです。

> cd d <Tab>
Documents   downloads

> cd D <Tab>
Documents

マッチしたコマンドのヒストリを表示できるようにする

autoload history-search-end
zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end
bindkey "^P" history-beginning-search-backward-end
bindkey "^N" history-beginning-search-forward-end

この設定をすると、例えば以前にvimコマンドをタイプしたことがあれば、vimのヒストリを遡ることができます。

> history
  1 vim a.txt
  2 cd Documents
  3 vim b.txt
 
> vim <Ctrl-P>
> vim b.txt
> vim b.txt <Ctrl-P>
> vim a.txt

この設定をしない状態(デフォルト)だと、Ctrl-Pはup-line-or-history, Ctrl-Nはdown-line-or-historyなはずなので、
コマンドの履歴を遡るだけです。("cd Documents"とかも表示されます)
要するにこの場合で言えば、vimコマンドに特化して、ヒストリを表示できるということですね。
もちろん、何もタイプしない状態でCtrl-Pを押せば、通常通りのコマンドのヒストリを表示できます。

lsコマンドの結果に色を付ける

### Ls Color ###
# 色の設定
export LSCOLORS=Exfxcxdxbxegedabagacad
# 補完時の色の設定
export LS_COLORS='di=01;34:ln=01;35:so=01;32:ex=01;31:bd=46;34:cd=43;34:su=41;30:sg=46;30:tw=42;30:ow=43;30'
# ZLS_COLORSとは?
export ZLS_COLORS=$LS_COLORS
# lsコマンド時、自動で色がつく(ls -Gのようなもの?)
export CLICOLOR=true
# 補完候補に色を付ける
zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}

lsコマンドの結果に色を付けます。
設定内容はコメントに記述してある通りです。
よく分からなかったのもありますがw
色の設定をしたい場合は、LSCOLORSやLS_COLORSを修正すれば大丈夫です。

プロンプトを変更する・色を付ける

### Prompt ###
# プロンプトに色を付ける
autoload -U colors; colors

# 一般ユーザ時
tmp_prompt="%{${fg[cyan]}%}%n%# %{${reset_color}%}"
tmp_prompt2="%{${fg[cyan]}%}%_> %{${reset_color}%}"
tmp_rprompt="%{${fg[green]}%}[%~]%{${reset_color}%}"
tmp_sprompt="%{${fg[yellow]}%}%r is correct? [Yes, No, Abort, Edit]:%{${reset_color}%}"

# rootユーザ時(太字にし、アンダーバーをつける)
if [ ${UID} -eq 0 ]; then
  tmp_prompt="%B%U${tmp_prompt}%u%b"
  tmp_prompt2="%B%U${tmp_prompt2}%u%b"
  tmp_rprompt="%B%U${tmp_rprompt}%u%b"
  tmp_sprompt="%B%U${tmp_sprompt}%u%b"
fi

PROMPT=$tmp_prompt    # 通常のプロンプト
PROMPT2=$tmp_prompt2  # セカンダリのプロンプト(コマンドが2行以上の時に表示される)
RPROMPT=$tmp_rprompt  # 右側のプロンプト
SPROMPT=$tmp_sprompt  # スペル訂正用プロンプト

まず、"autoload -U colors; colors"でcolors関数をロードし、プロンプトに色を付けます。
次に、通常プロンプト・セカンダリプロンプト・右側のプロンプト・スペル訂正用のプロンプトを設定しています。
色を設定する場合、"%{$fg[red]%}"で開始し、"%{$reset_color%}"でリセットするようにしましょう。
後は、rootユーザであればプロンプトを太字にし、アンダーバーを付けるといったことをやっています。

ターミナルのタイトルを変更する

### Title (user@hostname) ###
case "${TERM}" in
kterm*|xterm*|)
  precmd() {
    echo -ne "\033]0;${USER}@${HOST%%.*}\007"
  }
  ;;  
esac

ターミナルのタイトルを"ユーザ名@ホスト名"に変更します。
組み込み関数のprecmd()を使用し、プロンプト表示前にターミナルにシーケンス文字を送信しています。
うーん、よく分からなかったのですが、"\033]0;"と"\007"で囲めばターミナルのタイトル部分に文字列をechoするということなのかな・・・?


一応、以上の設定である程度満足できています。
もっと改善の余地があると思いますが、余裕があったら掘り下げてやってみようと思います。

githubにもアップしています。
dotfiles/.zshrc at master · tiwakawa/dotfiles · GitHub

以上です。