.zshrcが200行を超えてきたので記事に残したいと思います。
どこかの誰かの役に立てれば幸いです。
実際のファイルはこちらから参照することができます。
reireias/dotfiles/.zshrc
.zshrcのブロックごとに解説していきます。
全体
vimのfoldを使うために次のコメントでセグメントを囲い、折りたたみの範囲を指定しています。
# Comment {{{
settings...
# }}}
Import
このセグメントでは外部ファイルのインポートを記述しています。
# INPORTS {{{
source ~/.bashrc
source ~/.zplug/init.zsh
# }}}
~/.bashrc
はbash用の設定ファイルです。ほとんど設定されていませんが。
~/.zplug/init.zsh
はzplugというプラグインのための設定になります。
Plugin
このセグメントではzplugに関する設定を記述しています。
# PLUGINS {{{
zplug "zsh-users/zsh-syntax-highlighting", defer:2
zplug "b4b4r07/zsh-vimode-visual", defer:3
zplug "zsh-users/zsh-completions"
zplug "b4b4r07/enhancd", use:init.sh
zplug "zsh-users/zsh-autosuggestions"
zplug load
setopt nonomatch
export ZSH_HIGHLIGHT_STYLES[path]='fg=081'
# }}}
以下利用しているpluginの解説です。
zsh-syntax-highlighting
zsh-users/zsh-syntax-highlighting
はコマンドライン自体の色付けを行うプラグインです。
以下のようなシンタックスハイライトが可能です。
- 存在するコマンドはグリーン
- 存在しないコマンドはレッド
- 存在するパスはシアン
- 存在しないパスはホワイト
zsh-completions
zsh-users/zsh-completions
はzshの補完機能をさらに強化するプラグインです。
docker
やgo
等のサブコマンドを持つコマンドに関しても柔軟に補完してくれます。
例としてgo <tab>
と入力した場合の補完候補一覧は次の画像のようになります。
enhancd
b4b4r07/enhancd
はその名の通りcd
コマンドを拡張するプラグインです。
cd -
で直近に利用したディレクトリ一覧から選択して移動したりできます。
私はオプションで下記のように指定し、候補をpecoで絞り込むように設定しています。
# enhancd
export ENHANCD_FILTER=peco
export ENHANCD_DISABLE_DOT=1
export ENHANCD_DISABLE_HOME=1
zsh-autosuggestions
zsh-users/zsh-autosuggestions
はヒストリーから現在入力中のコマンドを探し、補完を表示してくれるプラグインです。
前方一致の中から最新の履歴を表示してくれるので、簡単な補完はこのプラグインで、詳細に検索したい場合は後述のpeco
を使ったインクリメンタルサーチで検索しています。
History
コマンド履歴に関する設定のセグメントです。
検索に関する設定は後述のpecoのセグメントで行っています。
# HISTORY {{{
# history
HISTFILE=$HOME/.zsh-history
HISTSIZE=100000
SAVEHIST=1000000
HISTFILE
はコマンド履歴の保存先ファイル、HISTSIZE
はメモリに保持するコマンド履歴数、SAVEHIST
はファイルに保存するコマンド履歴数になります。大きすぎると動作や検索が遅くなるそうです。
# share .zshhistory
setopt inc_append_history
setopt share_history
inc_append_history
はシェルの終了を待たずにファイルにコマンド履歴を保存します。
share_history
は異なるタブ、ウィンドウ間でのコマンド履歴を共有します。
これらの設定により、tmux等の複数ターミナル環境間でコマンド履歴を共有することができます。
# cdr
if [[ -n $(echo ${^fpath}/chpwd_recent_dirs(N)) && -n $(echo ${^fpath}/cdr(N)) ]]; then
autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
add-zsh-hook chpwd chpwd_recent_dirs
zstyle ':completion:*' recent-dirs-insert both
zstyle ':chpwd:*' recent-dirs-default true
zstyle ':chpwd:*' recent-dirs-max 1000
zstyle ':chpwd:*' recent-dirs-file "$HOME/.cache/chpwd-recent-dirs"
fi
# }}}
cdrと呼ばれるディレクトリ移動の履歴保存の設定です。
検索については後述のpecoのセグメントで設定しています。
Color
色の設定に関するセグメントです。
個人的には補完と一二を争うほど重要だと思ってます。
# COLOR {{{
# LS_COLORS
eval `dircolors -b`
eval `dircolors ${HOME}/.dircolors`
# remove file mark
unsetopt list_types
dircolorsはls
コマンドや補完時のファイルに種類に応じて色付けを行う設定です。
デフォルトの設定とdotfilesで管理している設定を読み込ませています。
list_types
はファイル種別の記号を補完候補の末尾に表示します。(ls -F
での記号と同じ)
邪魔なので無効にしています。
# color at completion
autoload colors
zstyle ':completion:*' verbose yes
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
タブでの補完候補にもシンタックスハイライトが反映される設定です。
これらの設定でvi <tab>
と入力すると、以下のように候補が表示されます。
# less
export LESS='-R'
# man
export MANPAGER='less -R'
man() {
env \
LESS_TERMCAP_mb=$(printf "\e[1;33m") \
LESS_TERMCAP_md=$(printf "\e[1;36m") \
LESS_TERMCAP_me=$(printf "\e[0m") \
LESS_TERMCAP_se=$(printf "\e[0m") \
LESS_TERMCAP_so=$(printf "\e[1;44;33m") \
LESS_TERMCAP_ue=$(printf "\e[0m") \
LESS_TERMCAP_us=$(printf "\e[1;32m") \
man "$@"
}
# }}}
最後はless
とman
の設定です。
less
はgrep
やjq
等で色付きの結果を渡すことが多いため、カラー情報を解釈する設定にしています。
man
に関してもデフォルトの単色/太字混在は見辛いので、適当なシンタックスハイライト設定を施しています。もう少しイケてるシンタックスハイライトにしたいと考えています。
man grep
での表示例
Prompt
続いてPromptの設定です。
# PROMPT {{{
# prompt
PROMPT=" %{[38;5;154m%}%~%{[0m%}
%{[38;5;81m%}%(!.#.$)%{[0m%} "
RPROMPT="%{[38;5;013m%}[%m]%{[0m%}"
# vcs_info
autoload -Uz vcs_info
setopt prompt_subst
zstyle ':vcs_info:git:*' check-for-changes true
zstyle ':vcs_info:git:*' stagedstr "%F{yellow}!"
zstyle ':vcs_info:git:*' unstagedstr "%F{red}+"
zstyle ':vcs_info:*' formats "%F{green}%c%u[ %b]%f"
zstyle ':vcs_info:*' actionformats '[%b|%a]'
precmd () { vcs_info }
RPROMPT='${vcs_info_msg_0_} '$RPROMPT
# }}}
文字化けしている部分は制御文字です。
PROMPT
はターミナルの左側に表示される情報と色を設定します。
1行目には現在のディレクトリ、2行目には通常ユーザーの場合は$
をrootの場合は#
を表示します。
rootかどうかをひと目で判断できるので必須の設定です。
RPROMPT
は右側を設定します。
仕事ではsshで様々なサーバーにログインすることが多いため、%m
でホスト名を表示しています。
vcs_info
の項目では、zshの機能を利用して、カレントディレクトリのgitのステータスやブランチ名を表示しています。
一部文字化けはnerd fontを利用しているためです。
gitのステータスに応じて下記のようにRPROMPT
の色が変わるように設定しています。
Alias
aliasに関する設定をまとめています。
日々増えていきます。
便利なものはコメントで紹介します。
# ALIAS {{{
# general
alias ls='ls -h --color=always'
alias dir='ls --color=auto --format=vertical'
alias vdir='ls --color=auto --format=long'
alias ll='ls -l' # 多用します
alias la='ls -A' # 多用します
alias l='ls -CF'
alias du='du -sh *' # ディレクトリごとにサブディレクトリ含む合計容量を出力します
alias open='gnome-open' # htmlファイルをopenすればブラウザで開くことができます
alias caddy='ruby /opt/caddy/caddy/caddy.rb'
alias terminal='gnome-terminal --hide-menubar'
alias tm='terminal' # tm ./ で現在いるディレクトリでターミナルを複製できます
alias reload='source ~/.zshrc' # .zshrc編集中は多用してます
alias ssh='TERM=xterm ssh'
# cd
alias ..2='cd ../..'
alias ..3='cd ../../..'
alias ..4='cd ../../../..'
# vim
alias vi='nvim'
alias nvi='nvim'
alias vimdiff='nvim -d'
# dotfiles
alias dot='cd ~/dev/src/github.com/reireias/dotfiles'
alias zshconfig='nvim ~/.zshrc'
alias vimconfig='nvim ~/.vimrc'
# grep
alias g='grep --color=always'
alias grep='grep --color=always'
alias jgrep='grep --include="*.java"'
alias jsgrep='grep --include="*.js"'
alias fgrep='find ./ | grep'
alias ngrep='grep --exclude-dir={node_modules,.nuxt}'
# git
# gitはよく使うのでいろいろ設定しています。
# カラー設定込みでaliasに登録しているものもあります
alias g='git'
alias gb='git branch'
alias gl='git log --pretty=format:"%C(yellow)%h%Creset %C(magenta)%ci%Creset%n%C(cyan)%an <%ae>%Creset%n%B"'
alias glp='git log -p'
alias glg='git log --graph --pretty=format:"%C(yellow)%h%Creset %C(magenta)%ci%Creset%n%C(cyan)%an <%ae>%Creset%n%B"'
alias gco='git checkout'
alias gd='git diff'
alias gdh='git diff HEAD'
alias gds='git diff --stat'
alias gdt='git difftool'
alias gst='git status'
alias gp='git pull'
# docker
alias d='docker'
# デフォルトだと見切れるので、表示項目を変更しています。
alias dps='docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}"'
alias dc='docker-compose'
# }}}
aliasはこの記事にいろいろまとめているので、気になる方はどうぞ。
世の中のエンジニアのalias設定
Key
キー設定に関するセグメントです。
HomeキーやEndキーを多用するのでいろいろと設定しています。
また、Ctrl + ← | →
で単語単位のカーソル移動になっています。
# KEY {{{
# key bind
typeset -A key
if [[ -n "${terminfo}" ]]; then
key[Home]="${terminfo[khome]}"
key[End]="${terminfo[kend]}"
key[Insert]="${terminfo[kich1]}"
key[Delete]="${terminfo[kdch1]}"
key[Up]="${terminfo[kcuu1]}"
key[Down]="${terminfo[kcud1]}"
key[Left]="${terminfo[kcub1]}"
key[Right]="${terminfo[kcuf1]}"
key[PageUp]="${terminfo[kpp]}"
key[PageDown]="${terminfo[knp]}"
# setup key accordingly
[[ -n "${key[Home]}" ]] && bindkey "${key[Home]}" beginning-of-line
[[ -n "${key[End]}" ]] && bindkey "${key[End]}" end-of-line
[[ -n "${key[Insert]}" ]] && bindkey "${key[Insert]}" overwrite-mode
[[ -n "${key[Delete]}" ]] && bindkey "${key[Delete]}" delete-char
[[ -n "${key[Up]}" ]] && bindkey "${key[Up]}" up-line-or-history
[[ -n "${key[Down]}" ]] && bindkey "${key[Down]}" down-line-or-history
[[ -n "${key[Left]}" ]] && bindkey "${key[Left]}" backward-char
[[ -n "${key[Right]}" ]] && bindkey "${key[Right]}" forward-char
[[ -n "${key[PageUp]}" ]] && bindkey "${key[PageUp]}" beginning-of-buffer-or-history
[[ -n "${key[PageDown]}" ]] && bindkey "${key[PageDown]}" end-of-buffer-or-history
fi
# word
bindkey "\e[1;5C" forward-word
bindkey "\e[1;5D" backward-word
if (( ${+terminfo[smkx]} )) && (( ${+terminfo[rmkx]} )); then
function zle-line-init () {
printf '%s' "${terminfo[smkx]}"
}
function zle-line-finish () {
printf '%s' "${terminfo[rmkx]}"
}
zle -N zle-line-init
zle -N zle-line-finish
fi
# }}}
peco
インタラクティブフィルタリングツールpecoの設定に関するセグメントです。
pecoは非常に便利なツールですので、個人的にはこれ無しでは生きていけない身体になってしまいました。
# PECO {{{
# peco
function peco-history-selection() {
BUFFER=`history -n 1 | tac | awk '!a[$0]++' | peco`
CURSOR=$#BUFFER
zle reset-prompt
}
zle -N peco-history-selection
bindkey '^R' peco-history-selection
コマンド履歴のインクリメンタルサーチをCtrl + R
に設定しています。
業務はほぼすべてLinuxで行っているので、履歴検索の使用頻度はzsh機能の中では最多だと思います。
function peco-ghq-look () {
local ghq_roots="$(git config --path --get-all ghq.root)"
local selected_dir=$(ghq list --full-path | \
xargs -I{} ls -dl --time-style=+%s {}/.git | sed 's/.*\([0-9]\{10\}\)/\1/' | sort -nr | \
sed "s,.*\(${ghq_roots/$'\n'/\|}\)/,," | \
sed 's/\/.git//' | \
peco --prompt="cd-ghq >" --query "$LBUFFER")
if [ -n "$selected_dir" ]; then
BUFFER="cd $(ghq list --full-path | grep --color=never -E "/$selected_dir$")"
zle accept-line
fi
}
zle -N peco-ghq-look
bindkey '^G' peco-ghq-look
ghqというリポジトリ管理ツールのリポジトリ一覧をCtrl + G
に設定しています。
リポジトリ名でインクリメンタルサーチを行い、選択してEnterキーを押すとそのリポジトリのディレクトリに移動します。
function peco-cdr () {
local selected_dir="$(cdr -l | sed 's/^[0-9]\+ \+//' | peco --prompt="cdr >" --query "$LBUFFER")"
if [ -n "$selected_dir" ]; then
BUFFER="cd ${selected_dir}"
zle accept-line
fi
}
zle -N peco-cdr
bindkey '^E' peco-cdr
# }}}
前述したディレクトリ移動履歴のcdrに関するインクリメンタルサーチです。
Ctrl + E
に割り当てています。
候補には最近移動したディレクトリが表示され、選択しEnterキーを入力するとそのディレクトリに移動します。
Completion
補完の設定です。
この辺は各ツールのREADME.md
を参考に書いています。
# COMPLETION {{{
# pip
function _pip_completion {
local words cword
read -Ac words
read -cn cword
reply=( $( COMP_WORDS="$words[*]" \
COMP_CWORD=$(( cword-1 )) \
PIP_AUTO_COMPLETE=1 $words[1] ) )
}
compctl -K _pip_completion pip3
# npm
if type complete &>/dev/null; then
_npm_completion () {
local words cword
if type _get_comp_words_by_ref &>/dev/null; then
_get_comp_words_by_ref -n = -n @ -n : -w words -i cword
else
cword="$COMP_CWORD"
words=("${COMP_WORDS[@]}")
fi
local si="$IFS"
IFS=$'\n' COMPREPLY=($(COMP_CWORD="$cword" \
COMP_LINE="$COMP_LINE" \
COMP_POINT="$COMP_POINT" \
npm completion -- "${words[@]}" \
2>/dev/null)) || return $?
IFS="$si"
if type __ltrim_colon_completions &>/dev/null; then
__ltrim_colon_completions "${words[cword]}"
fi
}
complete -o default -F _npm_completion npm
elif type compdef &>/dev/null; then
_npm_completion() {
local si=$IFS
compadd -- $(COMP_CWORD=$((CURRENT-1)) \
COMP_LINE=$BUFFER \
COMP_POINT=0 \
npm completion -- "${words[@]}" \
2>/dev/null)
IFS=$si
}
compdef _npm_completion npm
elif type compctl &>/dev/null; then
_npm_completion () {
local cword line point words si
read -Ac words
read -cn cword
let cword-=1
read -l line
read -ln point
si="$IFS"
IFS=$'\n' reply=($(COMP_CWORD="$cword" \
COMP_LINE="$line" \
COMP_POINT="$point" \
npm completion -- "${words[@]}" \
2>/dev/null)) || return $?
IFS="$si"
}
compctl -K _npm_completion npm
fi
# }}}
Other
その他の設定です。
golangやneovim用の環境変数等を定義しています、
pr-open
関数は、現在いるディレクトリのブランチに対応するPRが存在すれば、それをブラウザで開いてくれる神自作関数です。
めっちゃ便利です。
hub
コマンドに依存しています。
# OTHER {{{
# pandoc
pandoc_git () {
pandoc -s --self-contained -t html5 -c ~/.pandoc/github.css $@
}
# neovim
export XDG_CONFIG_HOME=~/.config
# golang
export GOROOT=/usr/lib/go
export GOPATH=$HOME/dev
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
# travis
[ -f /home/fx30079/.travis/travis.sh ] && source /home/fx30079/.travis/travis.sh
# hub
function pr-open {
local url=$(hub pr list -h $(git symbolic-ref --short HEAD) -f "%U")
if [ -z "$url" ]; then
echo "The PR based this branch not found."
return 1
fi
open $url
}
# }}}
Local
環境に依存するような設定は.zshrc_local
というファイルに記述し、gitでの管理外としています。
.zshrc_local
が存在すれば読み込みます。
# LOCAL {{{
# Load local setting
if [ -e ~/.zshrc_local ]; then
source ~/.zshrc_local
fi
# }}}
さいごに
よいzshライフを!