【コラム】

漢のzsh

4 コマンド履歴の検索~EmacsとVi、どっちも設定できるぜzsh

    後藤大地  [2007/03/01]

    今回は、少し話がそれるが最初にEmacsの話だ。

    Emacsキーバインド

    朝起きると、既に床の横で起動している端末にログイン、おもむろにcvs update -Pdし、Emacsをビルドする。当然、シェルスクリプトで自動化されているのはいうまでもない。しかし、cronに登録しないのは彼の良心である。ギークにとっては日常茶飯事だ。

    Emacsでは多くの一種独特なショートカットキーを使う。こうしたキーは普段の作業で体に染み付いてしまうもので、シェルを操作するときでもついつい同じキーを叩いてしまいがち。

    ここで期待しない動作になるとストレスである。

    そんなユーザのために、zshにはEmacs風ショートカットキー設定が用意されている。なにはともあれ~/.zshrcにリスト1.1の設定を追加だ。何の設定もしていなければだいたいEmacs風設定が最初から有効になっている。

    リスト1.1 Emacsライクキーバインド設定

    bindkey -e

    代表的なショートカットキーを表1.2に掲載しておく。どのようなショートカットキーが設定されているかはbindkey -Lを実行すれば一覧表示されるので、すべて把握しておきたいユーザは調べてみるといいだろう。

    表1.2 bindkey -eで設定されるEmacs風の代表的なショートカットキー

    ショートカットキー操作内容
    Ctrl-A行頭へジャンプ
    Ctrl-E行末へジャンプ
    Ctrl-Yヤンク
    Ctrl-X Uアンドゥ
    Ctrl-@マークセット
    Ctrl-Kカーソルから行末までを削除
    Ctrl-Wカーソルから行頭までを削除
    Ctrl-U一行削除
    Ctrl-Gコマンド入力を実行せずに無視して次の行へ
    Ctrl-B←キー
    Ctrl-F→キー
    Ctrl-P↑キー
    Ctrl-N↓キー
    Ctrl-DDeleteキー
    Ctrl-HBackSpaceキー
    Ctrl-I展開または補完
    Ctrl-Lクリアスクリーン

    表1.3 いくつかVi的な設定も用意されている

    ショートカットキー操作内容
    Ctrl-X Ctrl-Fvi風文字一致検索
    Ctrl-X Ctrl-Vviコマンドモード
    Ctrl-X Ctrl-Uアンドゥ

    特にCtrl-A、Ctrl-E、Ctrl-K、Ctrl-Lあたりはよく使うショートカットだ。これが使えないとなるとかなりストレスを覚える。

    なにも設定していないにもかかわらず、Ctrl-AやCtrl-Eが動作しない場合、環境変数EDITORがviやvimに設定されていると思う。EDITORにvi系エディタが設定されていると、自動的にVi風のショートカット設定が有効になるのである。

    このあたり、気が利いていると思う。

    Viキーバインド

    Emacsに対抗できる変態度を備えたエディタといえばVi。

    編集モードとコマンドモードという二面性を備えたViエディタは一度慣れてしまうとヤミツキになる。インタラクティブシェルで行をクリアしようとしてESC ddと入力してしまうようなら、もはやVi症候群におかされているとみていい。

    zshは、当然こうしたViギークの心をも捉えてはなさない。むしろViユーザこそ、シェルとしてはzshを採用するべきだ。zshは当然のごとくViモードのキーバンド設定を提供している。Viギークはなにはともあれリスト2.1を追加だ。

    リスト2.1 Viライクキーバインド設定

    bindkey -v

    表2.2 bindkey -vで設定されるVi風の代表的なショートカットキー

    ショートカットキー操作内容
    (編集モード)ESCコマンドモードへ移行
    (コマンドモード)I編集モードへ移行(行頭から入力)
    (コマンドモード)A編集モードへ移行(行末から入力)
    (コマンドモード)i編集モードへ移行(カーソルから挿入)
    (コマンドモード)a編集モードへ移行(カーソルの次の文字から挿入)
    (コマンドモード)o編集モードへ移行(次の行から入力)
    (コマンドモード)O編集モードへ移行(前の行から入力)
    (コマンドモード)dd一行削除
    (コマンドモード)Dカーソルから行末まで削除
    (コマンドモード)xDeleteキー
    (コマンドモード)XBackSpaceキー
    (コマンドモード)yyコピー
    (コマンドモード)pペースト

    Vi風のキーバインドが有効になると、入力部分はまるでViエディタそのもののようになる。

    ESCキーでコマンドモードにはいるし、I, A, i, aで編集モードへ移行だ。当然のごとくViで活用される代表的なコマンドが提供されている。bindkey -Lで確認するとわかるが、bindkey -vを実行した場合は表1.2のEmacsショートカットは使えない。そこに広がるのはあのViワールドである。

    えらいよ、Vi、いやzsh。

    履歴検索機能のショートカット設定

    ショートカットキーの話をしたところで、前回の話の続きにはいりたい。コマンド履歴の検索機能をどう設定するかだ。

    tcshの便利な機能のひとつとして、コマンド履歴の検索機能がある。これはたとえば"ls -"のように入力してからCtrl-Pを押すと、コマンド履歴の中から"ls -"ではじまるコマンドを順次表示するというものだ。

    そして当然、zshでも同じような機能が用意されている。ただしzshの場合、複数行を複数行のまま扱えるという特徴があるので、うっかり設定すると他のショートカットキーと設定がぶつかって別のシーンで扱いずらくなる。ということでリスト3.1の設定を追加だ。

    リスト3.1 履歴検索機能のショートカット設定

    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

    リスト3.1のように設定しておけば、コマンド履歴の検索機能はCtrl-PとCtrl-Nに割り当てられ、複数行の編集には↓↑←→を使うといった風にすみわけができる。Ctrl-PとCtrl-Nを別の機能として使っているなら、bindkey "^P"やbindkey "^N"を適当な扱いやすいものに変更すればいい。コマンド履歴が10万行あったとしても、このコマンド履歴検索機能を使えばさくっと過去のコマンドを表示できるというわけだ。

    おまけ - コマンド履歴検索機能でゴー

    今回説明した設定内容を設定ファイルにまとめたものを掲載しておく。設定例はEmacsキーバインドのものだ。Vi風を好むならbindkey -eをbindkey -vに変更すればいい。

    リスト4.1 今回の設定ファイルまとめ ~/.zshrc

    ## 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

    bashで同じような設定をする場合、~/.bashrcではなく~/.inputrcにリスト4.2のような設定を追加する。tcshならリスト4.3だ。bash/tcshでは複数行の編集はしないので、Ctrl-P, Ctrl-Nではなく↑↓にショートカットキーを設定してある。zshが使えない環境での参考にしてみてほしい。

    リスト4.2 bashで同じような設定をした場合 ~/.bashrc

    # 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

    リスト4.3 tcshで同じような設定をした場合 ~/.tcshrc

    ## Keybind configuration
    #
    # 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

    新着記事

    特設サイトの情報

      求人情報

      人気記事

      一覧

      イチオシ記事

      新着記事

      特別企画

      転職ノウハウ

      あなたの仕事適性診断

      4つの診断で、自分の適性を見つめなおそう!

      Heroes File ~挑戦者たち~

      働くこと・挑戦し続けることへの思いを綴ったインタビュー

      はじめての転職診断

      あなたにピッタリのアドバイスを読むことができます。

      転職Q&A

      転職に必要な情報が収集できます

      スカウト転職する

      企業からアプローチのメッセージが届きます。

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