最強のシェル zsh
今までシェルはbash一筋だったのですが、最強のシェルと聞いてzshを使ってみました。
Macには標準でもzshが入っていましたが、せっかくなので最新版をインストール。
インストールはHomebrewで
brew install zsh
で一発で出来ます。
デフォルトシェルの変え方はこちら(http://tukaikta.blog135.fc2.com/blog-entry-195.html)とか参照。
zshは.zshrcをいじることでカスタマイズできます。oh-my-zsh(https://github.com/robbyrussell/oh-my-zsh)が簡単で使いやすいらしいです。ただ僕はあまり好みではなかったので自作。下記の参考サイトを見て良さそうな機能をかき集めて作りました。
一番悩んだのがインクリメンタル補完機能。是非欲しい機能だけど、標準搭載のincremental-complete-wordやauto-fu.zsh(https://github.com/hchbaw/auto-fu.zsh)はちょっとイメージと違う。うーんどうしようと思っていたらしっくり来るのを発見!y.fujiiさんの「Incremental completion on zsh」です。すごい!!
http://mimosa-pudica.net/zsh-incremental.html
ちょっと使ってみた感じでは、zshの強力な補完機能はかなりいい感じです。また、過去に訪れたディレクトリに移動出来る「cd -」もかなり便利。
また、zshの勉強の過程で知ったのですが、シェルのコマンドラインってemacsのキーバインド使えたんですね・・・(参照 : http://qiita.com/items/08792b7188b5c11e0f21)。
zshどころかbashでも「Ctrl-w」(単語削除)とか「Ctrl-u」(行削除)、「Ctrl-a」(行頭移動)が出来たなんて・・・。今まで人生を無駄にしていた・・・。
最後に僕の今の.zshrcを書いておきます。コピーするとすぐ使えるので良ければどうぞー。
#read Aliases source ~/.aliases #from http://news.mynavi.jp/column/zsh/index.html case ${UID} in 0) #for super user RPROMPT='(%~)' PROMPT=$'%B%m%b:%?:%# ' ;; *) RPROMPT='(%~)' PROMPT=$'%m: %n %D{%T} %{%F{cyan}%}%#%{%f%} ' esac #SPROMPT="%r is correct? [n,y,a,e]:] " # auto change directory setopt auto_cd # auto directory pushd that you can get dirs list by cd -[tab] setopt auto_pushd # command correct edition before each completion attempt setopt correct # compacked complete list display setopt list_packed # no remove postfix slash of command line setopt noautoremoveslash # no beep sound when complete list displayed # #setopt nolistbeep ## Keybind configuration # emacs like keybind (e.x. Ctrl-a goes to head of a line and Ctrl-e goes # to end of it) bindkey -e # historical backward/forward search with linehead string binded to ^P/^N 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 ## Command history configuration # HISTFILE=~/.zsh_history HISTSIZE=10000 SAVEHIST=10000 setopt hist_ignore_dups # ignore duplication command history list setopt share_history # share command history data ## Completion configuration #http://qiita.com/items/f2971728c845c75e9967 autoload -U compinit && compinit compinit #autoload predict-on #predict-on setopt complete_aliases # aliased ls needs if file/dir completions work #from http://qiita.com/items/ed2d36698a5cc314557d zstyle ':completion:*:default' menu select=2 zstyle ':completion:*' verbose yes zstyle ':completion:*' completer _expand _complete _match _prefix _approximate _list _history zstyle ':completion:*:messages' format '%F{YELLOW}%d'$DEFAULT zstyle ':completion:*:warnings' format '%F{RED}No matches for:''%F{YELLOW} %d'$DEFAULT zstyle ':completion:*:descriptions' format '%F{YELLOW}completing %B%d%b'$DEFAULT zstyle ':completion:*:options' description 'yes' zstyle ':completion:*:descriptions' format '%F{yellow}Completing %B%d%b%f'$DEFAULT # マッチ種別を別々に表示 zstyle ':completion:*' group-name '' # セパレータを設定する zstyle ':completion:*' list-separator '-->' zstyle ':completion:*:manuals' separate-sections true # 名前で色を付けるようにする autoload colors colors # LS_COLORSを設定しておく export LS_COLORS='di=34:ln=35:so=32:pi=33:ex=31:bd=46;34:cd=43;34:su=41;30:sg=46;30:tw=42;30:ow=43;30' # ファイル補完候補に色を付ける zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS} # 補完に関するオプション # http://voidy21.hatenablog.jp/entry/20090902/1251918174 setopt auto_param_slash # ディレクトリ名の補完で末尾の / を自動的に付加し、次の補完に備える setopt mark_dirs # ファイル名の展開でディレクトリにマッチした場合 末尾に / を付加 setopt list_types # 補完候補一覧でファイルの種別を識別マーク表示 (訳注:ls -F の記号) setopt auto_menu # 補完キー連打で順に補完候補を自動で補完 setopt auto_param_keys # カッコの対応などを自動的に補完 setopt interactive_comments # コマンドラインでも # 以降をコメントと見なす setopt magic_equal_subst # コマンドラインの引数で --prefix=/usr などの = 以降でも補完できる setopt complete_in_word # 語の途中でもカーソル位置で補完 setopt always_last_prompt # カーソル位置は保持したままファイル名一覧を順次その場で表示 setopt print_eight_bit #日本語ファイル名等8ビットを通す setopt extended_glob # 拡張グロブで補完(~とか^とか。例えばless *.txt~memo.txt ならmemo.txt 以外の *.txt にマッチ) setopt globdots # 明確なドットの指定なしで.から始まるファイルをマッチ bindkey "^I" menu-complete # 展開する前に補完候補を出させる(Ctrl-iで補完するようにする) # 範囲指定できるようにする # 例 : mkdir {1-3} で フォルダ1, 2, 3を作れる setopt brace_ccl # manの補完をセクション番号別に表示させる zstyle ':completion:*:manuals' separate-sections true # 変数の添字を補完する zstyle ':completion:*:*:-subscript-:*' tag-order indexes parameters #cdは親ディレクトリからカレントディレクトリを選択しないので表示させないようにする (例: cd ../<TAB>): zstyle ':completion:*:cd:*' ignore-parents parent pwd # オブジェクトファイルとか中間ファイルとかはfileとして補完させない zstyle ':completion:*:*files' ignored-patterns '*?.o' '*?~' '*\#' # http://qiita.com/items/55651f44f91123f1881c # url: $1, delimiter: $2, prefix: $3, words: $4.. function web_search { local url=$1 && shift local delimiter=$1 && shift local prefix=$1 && shift local query while [ -n "$1" ]; do if [ -n "$query" ]; then query="${query}${delimiter}${prefix}$1" else query="${prefix}$1" fi shift done open "${url}${query}" } function google () { web_search "https://www.google.co.jp/search?&q=" "+" "" $* } #http://qiita.com/items/156464de9caf64338b17 #bindkey "^[u" undo #bindkey "^[r" redo #incremental-complete #autoload incremental-complete-word #zle -N incremental-complete-word #bindkey '\C-xI' incremental-complete-word # Incremental completion for zsh # by y.fujii <y-fujii at mimosa-pudica.net>, public domain #autoload -U compinit zle -N self-insert self-insert-incr zle -N vi-cmd-mode-incr zle -N vi-backward-delete-char-incr zle -N backward-delete-char-incr zle -N expand-or-complete-prefix-incr #compinit bindkey -M viins '^[' vi-cmd-mode-incr bindkey -M viins '^h' vi-backward-delete-char-incr bindkey -M viins '^?' vi-backward-delete-char-incr bindkey -M viins '^i' expand-or-complete-prefix-incr bindkey -M emacs '^h' backward-delete-char-incr bindkey -M emacs '^?' backward-delete-char-incr bindkey -M emacs '^i' expand-or-complete-prefix-incr setopt automenu now_predict=0 function limit-completion { if ((compstate[nmatches] <= 1)); then zle -M "" elif ((compstate[list_lines] > 6)); then compstate[list]="" zle -M "too many matches." fi } function correct-prediction { if ((now_predict == 1)); then if [[ "$BUFFER" != "$buffer_prd" ]] || ((CURSOR != cursor_org)); then now_predict=0 fi fi } function remove-prediction { if ((now_predict == 1)); then BUFFER="$buffer_org" now_predict=0 fi } function show-prediction { # assert(now_predict == 0) if ((PENDING == 0)) && ((CURSOR > 1)) && [[ "$PREBUFFER" == "" ]] && [[ "$BUFFER[CURSOR]" != " " ]] then cursor_org="$CURSOR" buffer_org="$BUFFER" comppostfuncs=(limit-completion) zle complete-word cursor_prd="$CURSOR" buffer_prd="$BUFFER" if [[ "$buffer_org[1,cursor_org]" == "$buffer_prd[1,cursor_org]" ]]; then CURSOR="$cursor_org" if [[ "$buffer_org" != "$buffer_prd" ]] || ((cursor_org != cursor_prd)); then now_predict=1 fi else BUFFER="$buffer_org" CURSOR="$cursor_org" fi echo -n "\e[32m" else zle -M "" fi } function preexec { echo -n "\e[39m" } function vi-cmd-mode-incr { correct-prediction remove-prediction zle vi-cmd-mode } function self-insert-incr { correct-prediction remove-prediction if zle .self-insert; then show-prediction fi } function vi-backward-delete-char-incr { correct-prediction remove-prediction if zle vi-backward-delete-char; then show-prediction fi } function backward-delete-char-incr { correct-prediction remove-prediction if zle backward-delete-char; then show-prediction fi } function expand-or-complete-prefix-incr { correct-prediction if ((now_predict == 1)); then CURSOR="$cursor_prd" now_predict=0 comppostfuncs=(limit-completion) zle list-choices else remove-prediction zle expand-or-complete-prefix fi }
参考 :
漢のzsh http://news.mynavi.jp/column/zsh/index.html
zsh Advent Calendar 2012 http://qiita.com/advent-calendar/2012/zsh
http://qiita.com/items/ed2d36698a5cc314557d
http://d.hatena.ne.jp/Naruhodius/20110520/1305872622
http://d.hatena.ne.jp/seiunsky/20110519/1305764493