【コラム】

漢のzsh

5 「あーっ!」というそのときのために - 備えあれば憂いなしの設定集

    後藤大地  [2007/03/08]

    今回は、前回までの設定も含めて、zshの基本的なオプションをまとめよう。

    超基本にして最重要 - compinitで補完機能

    第1回目で簡単に説明したが、リスト1.1の設定は絶対必要。zshの実力を発揮するための第1歩だ。

    リスト1.1 補完設定をロードして設定

    autoload -U compinit
    compinit

    プロンプト1.2 補完設定を読み込む前はコマンドに関係なくファイルが補完候補として表示されるが

    % tar [ここでタブキーを押す]
    dir01/ dir02/ file01 file02 file03

    プロンプト1.3 補完設定を読み込んだあとはコマンドに応じてオプションが補完される

    % autoload -U compinit
    % compinit
    %
    % tar [ここでタブキーを押す]
    A -- append to an archive
    c -- create a new archive
    f -- specify archive file or device
    t -- list archive contents
    u -- update archive
    v -- verbose output
    x -- extract files from an archive

    補完設定を読み込む前は入力されているコマンドに関係なくファイルやディレクトリが補完候補として展開されるが、補完設定を読み込んだあとはコマンドに応じてオプションや引数の補完候補が表示されるようになる。

    困ったらタブを押せばなんとかなる便利な機能だ。

    急いても事をし損じない - 空気を読むぞauto_cd

    "cd"なんて押してられるか、と思うことはないだろうか? 怠惰はハッカーの美徳なり。リスト2.1を設定すると、ディレクトリ名を入力するだけでカレントディレクトリを変更できる。

    リスト2.1 auto_cdを設定

    setopt auto_cd

    プロンプト2.2 ディレクトリ名をコマンドのように入力する - 当然: command not found

    % ls -F
    dir01/ dir02/ file01 file02 file03
    % dir01
    zsh: command not found: dir01
    %

    プロンプト2.3 setopt auto_cdを設定しておくと、ディレクトリ名でcdできる。結構便利な機能

    % ls -F
    dir01/ dir02/ file01 file02 file03
    %
    % setopt auto_cd
    %
    % pwd
    /home/test
    % dir01
    % pwd
    /home/test/dir01
    %

    急いでいるとcdを省略して入力してしまうこともままある。しかし、かえってくるのは"command not found:"という冷たい表示。そのくらい空気読めよとおもうわけだが、zshなら大丈夫。

    cdあーっ、というときも安心 - auto_pushdで備えあれば憂い無し

    そもそも深いディレクトリ作らない方が扱いやすい。しかし、何年も同じホームディレクトリを使いまわしていると、そのうちウィザード的な深いディレクトリ階層が生まれる。

    そんなダンジョンの最下層で勢いよく"cd"なんて押してしまうと……

    「あ、らめー」

    一気にホームディレクトリへ戻ってしまうことになる。リスト3.2を設定しておけばこんなときも安心。

    リスト3.2 移動したディレクトリを記録しておくと、いざというときに便利

    autoload -U compinit
    compinit

    setopt auto_pushd

    早速効果をチェック。

    プロンプト3.3 -タブキーとしても当然なにもおこらないわけだが

    % cd /usr/local
    % cd jdk1.5.0
    % cd bin
    %
    % cd -[ここでタブキーを押す]

    プロンプト3.4 auto_pushd設定をしておくと、-[タブキー]でこれまでに移動したディレクトリが一覧表示されるようになる

    % autoload -U compinit
    % compinit
    % setopt auto_pushd
    %
    % cd /usr/local
    % cd jdk1.5.0
    % cd bin
    %
    % cd -[ここでタブキーを押す]
    0 -- /home/test
    1 -- /usr/local
    2 -- /usr/local/jdk1.5.0

    補完設定をしておく必要があるが、setopt auto_pushdを設定しておくと"cd -[タブ]"で、これまでに移動したディレクトリ一覧が表示され、表示されている番号を押してリターンキーで、そのディレクトリへ移動できる。

    いくつかのディレクトリをまたいで作業する場合にもこの機能はかなり役に立つ。ぜひとも設定して使ってみてほしい。

    間違っても安心 - やさしく修正してくれるcorrect

    ヒトの入力ほど当てにならないものはない。コマンド名を間違えるなどしょっちゅうだ。そこでリスト4.1。これはbashやtcshとそれほど変わらないかも。

    リスト4.1 入力したコマンド名が間違っている場合には修正

    setopt correct

    設定前はコマンド名が間違っていればそのまま"command not found"だが、設定したあとは間違いを指摘してくれる。

    プロンプト4.2 存在しないコマンド名を入力すれば当然ながらcommand not foundなわけだが

    % lls
    zsh: command not found: lls
    %

    プロンプト4.3 自動修正機能を有効にしておくと、近いコマンド名を探して、お前間違えてるんじゃないかとやさしく諭してくれる

    % setopt correct
    %
    % lls
    zsh: correct 'lls' to 'ls' [nyae]? y [ここでyと入力]
    dir01 dir02 file01 file02 file03
    %

    いちどにたくさん観たいから - list_packedで詰めて表示

    結構便利な設定にlist_packedがあるので紹介しておく。タブキーをおせばいろいろと補完候補が表示されるわけだが、リスト5.1を設定しておくと補完候補がつめて表示されるようになる。

    リスト5.1 補完候補を詰めて表示する設定

    setopt list_packed

    早速効果を確認。

    プロンプト5.2 タブキーで補完候補が表示されるわけだが

    % cd /usr/local 
    % ls [ここでタブキーを押す]
    bin                     lib                     openoffice.org-2.1.0
    etc                     libdata                 sbin
    gcc-ooo                 libexec                 share
    include                 linux-sun-jdk1.4.2      src
    info                    live                    var
    jdk1.4.2                man                     www
    jdk1.5.0                modules

    プロンプト5.3 list_packedを設定しておくとつめて表示される

    % setopt list_packed

    % cd /usr/local 
    % ls [ここでタブキーを押す]
    bin/      info/      libdata/             man/                   share/
    etc/      jdk1.4.2/  libexec/             modules/               src/
    gcc-ooo/  jdk1.5.0/  linux-sun-jdk1.4.2/  openoffice.org-2.1.0/  var/
    include/  lib/       live/                sbin/                  www/

    補完候補が画面を越えると少々あつかいずらい。できれば1画面に納めたいものだ。list_packedで詰めて表示させるこの設定は小さいけどなかなか使える。

    漢は黙ってもくもくと作業 - nolistbeep

    補完機能を多様するzshだが、いちいちピッピピッピとビープ音がなっていてはいただけない。なんというか、仕事をミスっているようで示しがつかない。そこでリスト6.1を設定だ。これで補完するごとにピッピ鳴るということはなくなる。

    リスト6.1 補完候補表示時などにピッピとビープ音をならないように設定

    setopt nolistbeep

    逆に、音を鳴らして、zshマスターのヘルプに期待するのもありかも?

    というわけで基本設定ファイルのまとめ

    これまで説明していた基本中の基本となる設定をまとめたものを掲載しておく。自分の設定ファイルの参考にしてほしい。ちなみに^[はエスケープだから、ここからコピペしただけではおもったようにはならない。コピペして使う場合は、第2回を参考に^[をエスケープに変更してから使ってほしい。

    リスト7.1 ~/.zshrc - 基本中の基本を設定

    ## Environment variable configuration
    #
    # LANG
    #
    export LANG=ja_JP.UTF-8

    ## Default shell configuration
    #
    # set prompt
    #
    case ${UID} in
    0)
        PROMPT="%B%{^[[31m%}%/#%{^[[m%}%b "
        PROMPT2="%B%{^[[31m%}%_#%{^[[m%}%b "
        SPROMPT="%B%{^[[31m%}%r is correct? [n,y,a,e]:%{^[[m%}%b "
        [ -n "${REMOTEHOST}${SSH_CONNECTION}" ] && 
            PROMPT="%{^[[37m%}${HOST%%.*} ${PROMPT}"
        ;;
    *)
        PROMPT="%{^[[31m%}%/%%%{^[[m%} "
        PROMPT2="%{^[[31m%}%_%%%{^[[m%} "
        SPROMPT="%{^[[31m%}%r is correct? [n,y,a,e]:%{^[[m%} "
        [ -n "${REMOTEHOST}${SSH_CONNECTION}" ] && 
            PROMPT="%{^[[37m%}${HOST%%.*} ${PROMPT}"
        ;;
    esac

    # 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 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
    #
    autoload -U compinit
    compinit

    # set terminal title including current directory
    #
    case "${TERM}" in
    kterm*|xterm)
        precmd() {
            echo -ne "\033]0;${USER}@${HOST%%.*}:${PWD}\007"
        }
        ;;
    esac

    参考までにbashで似たような設定をした場合の例を次に掲載しておく。bashの場合、~/.bashrcだけではなく~/.inputrcのほうにも設定が必要だ。

    リスト7.2 ~/.bashrc - .zshrcと似たような設定をした場合

    ## Environment variable configuration
    #
    # LANG
    #
    export LANG=ja_JP.UTF-8

    ## Default shell configuration
    #
    # set prompt
    #
    case ${UID} in
    0)
        PS1='\[\033[1;31m\]${PWD}\$\[\033[0m\] '
        PS2='\[\033[1;31m\]>\[\033[0m\] '
        [ -n "${REMOTEHOST}${SSH_CONNECTION}" ] && PS1='\[\033[1;30m\]\h'" ${PS1}"
        ;;
    *)
        PS1='\[\033[31m\]${PWD}\$\[\033[0m\] '
        PS2='\[\033[31m\]>\[\033[0m\] '
        [ -n "${REMOTEHOST}${SSH_CONNECTION}" ] && PS1='\[\033[37m\]\h'" ${PS1}"
        ;;
    esac

    # set terminal title including current directory
    #
    case "${TERM}" in
    kterm*|xterm)
        PROMPT_COMMAND='echo -e "\033]0;'"${USER}@${HOSTNAME%%.*}:"'${PWD}\007\c"'
        ;;
    esac

    リスト7.3 bashの場合~/.bashrcだけではなく~/.inputrcにも設定が必要

    # list the possibilities after an ambiguous completion
    #
    set show-all-if-ambiguous on

    # stop the beep
    #
    set bell-style none

    # historical backward search with linehead string binded to up-key
    #
    "\e[A": history-search-backward

    # historical forward search with linehead string binded to down-key
    #
    "\e[B": history-search-forward

    tcshの場合なら次のようになる。ここでも^[はエスケープだし、^GはCtrl-gそのものが入力されているので、第2回を参考に置き換えてから使ってほしい。

    リスト7.4 ~/.tcshrc - .zshrcと似たような設定をした場合

    ## Environment variable configuration
    #
    # LANG
    #
    setenv LANG ja_JP.UTF-8

    ## Default shell configuration
    #
    # set prompt
    #
    if ( 0 == ${uid} ) then
        set prompt="%B%{\033[31m%}%/%#%{\033[m%}%b "
        set prompt2="%B%{\033[31m%}%R%#%{\033[m%}%b "
        set prompt3="%B%{\033[31m%}%R is correct? [y,n]:%{\033[m%}%b "
        if (${?REMOTEHOST} || ${?SSH_CONNECTION}) then
            set prompt="%{\033[37m%}${HOST:ar:au} ${prompt}"
        endif
    else
        set prompt="%{\033[31m%}%/%%%{\033[m%} "
        set prompt2="%{\033[31m%}%R%%%{\033[m%} "
        set prompt3="%{\033[31m%}%R is correct? [y,n]:%{\033[m%} "
        if (${?REMOTEHOST} || ${?SSH_CONNECTION}) then
            set prompt="%{\033[37m%}${HOST:ar:au} ${prompt}"
        endif
    endif

    # do spell-word editor command before each completion attempt
    #
    set autocorrect

    # do expand-history editor command before each completion attempt
    #
    set autoexpand

    # list the possibilities after an ambiguous completion
    #
    set autolist

    # enable color display for ls-F and ls
    #
    set color

    # enable color escape sequence for NLS message files
    #
    set colorcat

    # do spelling-correcte of command automatically
    #
    set correct=cmd

    # enable display and editing Japanese(UTF-8) code
    #
    set dspmbyte=utf8

    # list the all jobs (long format) when a job is suspended 
    #
    set listjobs=long

    # never beep when complete
    #
    set matchbeep=never

    # stop the beep
    #
    set nobeep

    # disable the ding in the prompt
    #
    set noding

    # do not error when filename or directory completion gets fail
    #
    set nonomatch

    # notify as soon as possible when backgroup jobs get change
    #
    set notify

    # ask before `rm *' command
    #
    set rmstar

    # treat symlinks as normal status
    #
    set symlinks=ignore

    ## Keybind configuration
    #
    # backward delete word binded to Ctrl-W
    #
    bindkey ^W backward-delete-word

    # historical backward search with linehead string binded to up-key
    #
    bindkey -k up history-search-backward

    # historical forward search with linehead string binded to down-key
    #
    bindkey -k down history-search-forward

    ## Command history configuration
    #
    set histfile=~/.history-"${tty:as|/|-|}"
    set history=1000
    set savehist=1000
    set histdup=erase

    # merge history files
    #
    if ( -d /usr/bin/ ) then
        touch ~/.tcshhistory$$ "${histfile}"
        chmod 600 ~/.tcshhistory$$ "${histfile}"
        cat ~/.history* | paste - - | sort | uniq -f 1 | \
            awk '{print $1 "\n" substr($0, 14, length($0) - 13)}' | \
            tail -${history} \
            > ~/.tcshhistory$$
        mv ~/.tcshhistory$$ "${histfile}"
    endif

    ## terminal configuration
    #
    if ( ${?TERM} ) then
        switch ( "${TERM}" )
        case xterm:
            # set terminal title
            alias postcmd echo -n '"^[]2;${TERM:s/-/./:r} ${HOST:ar}:${cwd}^G"'

            breaksw
        endsw
    endif

    と、いうわけで、今回で基本設定は終了。なんですが……次回からはまだ考えてなかったりします。でも、乞うご期待。

    新着記事

    特設サイトの情報

      人気記事

      一覧

        イチオシ記事

        新着記事

        特別企画

        マイナビニュースマガジン