■■■ Emacsをもっと快適にするElisp集
Emacsは単独でも強力なテキストエディタですが,Elispによるカスタマイズでエディタの枠を越えた強力な作業環境になり得ます.とはいえ,Elispのコードを書くのはなかなか敷居の高いもの.そこで今回は,Web上で公開されている様々なElispをご紹介します.「Emacsって興味はあるけど何ができるの?」「Emacs使ってるけどもっと便利にしたい!」とお考えの方のヒントになれば,と思います.
なお、Elispのご紹介にあたり、Emacsは23.1.1、OSはWindows7とMandrivaLinux2010.0で確認しています。環境によっては動きが異なったり、動作しない可能性がありますのでご了承ください。

■■ newsticker.el
Emacsに標準で入っているフィードリーダです.
“M-x newsticker-show-news”で起動します.一般的なメーラやフィードリーダと似た3ペインのツリー表示になっていて,マウスだけでも操作できるので,ライトユーザにも優しい作りになっています.

■ フィードの登録
フィードの登録は”M-x newsticker-add-url”からも可能ですが,数が多いと面倒なので.emacsに直接書く方が楽かもしれません.書き方は簡単で,リスト1のようにフィードの名前とURLを並べて書きます.

———————————————————————–
☆リスト1 フィードの登録
(setq newsticker-url-list
‘((“Slashdot” “http://rss.slashdot.org/Slashdot/slashdot”)
(“TechCrunch” “http://feeds.feedburner.com/TechCrunch”)))
———————————————————————–

■ フィードをw3mで表示する
これでEmacsでフィードを読めるようになりました.しかしこれだけだと,フィードを開くとHTMLのタグがそのまま表示されてしまいます.そこで,フィードの表示にはemacs-w3mを使用します.emacs-w3mが動作する環境であれば,.emacsにリスト2のように書いておくとフィードをemacs-w3mで表示できます.

———————————————————————–
☆リスト2 emacs-w3mでフィードを表示する
(autoload ‘w3m-region “w3m” nil t)
(setq newsticker-html-renderer ‘w3m-region)
———————————————————————–

Emacs23の場合,emacs-w3mの安定版は動かないので,CVSから最新ソースを取ってきてビルドする必要があります.若干面倒ですが一度環境さえ作ってしまえば,これとmewとemacs-w3mと,人によりnavi2chとかtwittering-modeあたりがあれば,一日中Emacs上で生活できそうですね.

[図1 newsticker.png]

■■ wdired.el
diredバッファを編集できるようになるモードです.この連載を読んでいる方なら皆様使っているのではないかと思うくらい有名なものらしく,改めて紹介するまでもないかもしれません.・・・と偉そうに書いている筆者は知らなかったので,このwdiredに出会えただけでも今回この原稿を書いた元は取れた気分です.
標準で入っているので,とくに何も設定しなくても使えます.”C-x d”で通常のdiredバッファを開いて,”C-x C-q”とタイプするとバッファ内のファイル名を編集できるようになります.編集が終わったら”C-c C-c”とタイプすると変更が反映されます.間違えたら”C-c ESC”で取り消せます.
何が嬉しいかというと,ファイル名の一括変更が非常に楽になることです.普段仕事をしていて,複数のファイルの末尾に日付やSubversionのリビジョン番号を付ける作業が時々発生します.これまではKDEのKrenameを使っていましたが,wdiredがあれば環境を問わず,Emacsの文字列置換の機能を使って簡単にリネームできます.
たとえば,あるディレクトリにテキストファイルがたくさん入っていて,ファイル名の末尾(拡張子の直前)にリビジョン番号”-r12345″を付けたいとします.”M-% .txt RET -r12345.txt RET”とタイプすると、バッファの先頭からひとつずつ確認しながらファイル名を変更していくことができます.SPCキーをタイプすると置換され,”n”をタイプするとスキップされます.全てを置換しても問題ないことが分かっていれば,”M-x replace-string RET .txt RET -r12345.txt RET”とタイプすれば確認なして一括置換できます.”M-x query-replace-regexp”を使えば,正規表現を使った置換も可能です.
.emacsにリスト3のように書いておくと,ファイル名だけでなくファイルのパーミッションも編集できるようになります.

———————————————————————–
☆リスト3 wdiredでファイルのパーミッションを編集可能にする
(setq wdired-allow-to-change-permissions t)
———————————————————————–

[図2 wdired.png]

■■ keywiz.el
Emacsのキーバインド,いくつ覚えてますか?
keywiz.elは,画面に表示されるEmacsのコマンドに対応するキーをタイプしていくことでEmacsジャンキー度を計るゲームです.”find-file”と表示されたら”C-x C-f”とタイプする,といった具合です.
“M-x keywiz”でゲームがスタートします.制限時間内にいくつ答えられるかを競います.
筆者ごときでは全く歯が立たなかったので,隣の席の若きEmacs使いにもチャレンジしてもらいました.が,見事惨敗.今のところ社内最高得点は11点です.難しいにも程があります.
動かしているEmacsで使用できる全てのコマンドから出題されるので,カスタマイズしているほどコマンド数が増えて難しくなるのがちょっと不公平な感じはします.ゲームなら”emacs -q”の方がいいよ,という声もありました.

[図3 keywiz.png]

■■ tld.el
国名とトップレベルドメインの相互参照ができる誰得感満載のツールです.
“M-x tld”とタイプすると,ミニバッファで検索文字列を聞いてきます.たとえば”jp”と入力すると,ミニバッファに”JP is Japan”と表示されます.逆に”Japan”と入力しても,”JP is Japan”と表示されます.ドメイン取りたいけど自国のトップレベルドメインを忘れてしまったそこの貴方に!怪しげなメールの送信元アドレスがどこの国か調べたいそこの貴女にも!

[図4 tld.png]

■■ table.el
テキストベースのテーブルエディタです.Emacsに標準で入っているので設定不要で使えます.非常に多機能で,およそテーブルに対して実行したいと思う操作はほぼ揃っています.慣れればWordやExcelより使いやすくなるでしょう.
まずは最も基本的な,空のテーブルを作成する方法からご紹介しましょう.”M-x table-insert”とタイプすると,ミニバッファでテーブルの列数や行数などのパラメータを聞かれます.これらを入力していくと,指定した大きさのテーブルが作成されます.
セルのサイズ変更も簡単です.変更したいセルにカーソルを置いて,”C-< “で幅を縮め,”C->”で幅を広げられます.また,”C-{“で高さを縮め,”C-}”で高さを広げられます.セルの分割や結合,行や列の追加や削除もお手のもの.セル間はTABキーで移動できるので入力も快適です.
テキストでできたテーブルなので,一見するとセル内に文字を入力すると形が崩れてしまいそうに見えます.ところがそんなことはなく,文字を入力してもセルの幅は変わりません.セルの幅を越えて文字を入力していくと,セルの横幅が自動的に広がります.同様に,改行していくとセルの縦幅が広がります.横幅を広げたくない場合は,”M-x table-fixed-width-mode”とタイプすると固定幅モードになります.このモードではセルの横幅は広がらず,次の行に折り返すようになります.テキストエディタであることを忘れてしまいそうな快適さです.
さらにHTMLのソース生成機能まであります.”C-^”とタイプすると,作成したテーブルをHTMLのtableタグに変換して新しいバッファに入力することができます.キーボードから手を離さずにWYSIWYGでテーブルが作れるので,複雑なWebの画面の作成や,Seleniumのテストケースを書くのにも便利そうですね.機能が豊富すぎて全ては紹介しきれませんが,”M-x table-“とタイプしてTABキーで補完候補を表示させると,一通りのコマンドを見ることができます.

[図5 table.png]

■■ all.el
Emacsの標準機能にoccurがあります.”M-x occur”とタイプして正規表現を入力すると,バッファの中からマッチする行だけを抽出して*occur*バッファに表示する機能です.all.elを使うと,occurと同様にして抽出した行を編集できるようになります.
“M-x all”とタイプして正規表現を入力すると,マッチする行が*All*バッファに表示されます.この*All*バッファを編集すると,元のバッファにも編集内容が反映されます.occurと異なり行番号は表示されませんが,*All*バッファで”C-c C-c”とタイプすると,元のバッファの対応する行にジャンプできます.ファイルの中身を検索しながら編集していく作業はよくありますが,all.elを使うと検索する作業と編集する作業を切り離せるので,一度に考えることが1つになって効率がよくなります.ソースコードの軽いリファクタリングにも便利そうです.

[図6 all.png]

■■ lcomp.el
アリエルが誇るEmacsハッカーの書いたElisp,ついにDebianに取り込まれる.この連載にも寄稿している菅原さんの作で,Debian/GNU Linuxのemacs-goodies-elパッケージに入っています.コマンドやファイル名などの補完時に開く*Completions*バッファを,使用後に消してくれます.バッファがたくさん開くのを気にしない人にとってはあまり意味のないものかもしれませんが,筆者のように必要最低限のバッファ以外が開いているのが我慢ならない神経質な人間にはもってこいです.
.emacsにリスト4のように書いておくだけで自動的に動いてくれます.このため,操作は普段と全く変わりません.

———————————————————————–
☆リスト4 lcompを動作させる
(require ‘lcomp)
(lcomp-install)
———————————————————————–

■■ tail.el
プログラマの必需品,tailをemacs上で実行するものです.
“M-x tail-file”とタイプするとファイルを,”M-x tail-command”とタイプするとコマンドの出力を監視できます.あくまでもtailコマンドの実行結果を表示するものなので,tail自体は別に用意する必要があります.Linux環境では何の問題もありませんが,Windows環境ではCygwinなどを用意することになるでしょう.
ログ監視などで頻繁に使用するtailがEmacs内で動いてくれると,ログを見ながらコードを書いたりできるので非常に便利です.筆者はこのtail.elの存在を知る以前,Shellバッファで”tail -f”を実行してログ監視をしていました.一応それでも用は足りていたのですが,tail.elを使うとウインドウの高さを邪魔にならないように設定できたり,対象に変化があった時だけ表示したり,と更に便利になります.

[図7 tail.png]

■■ ibuffer.el
“C-x C-b”で表示されるバッファリストの機能強化版です.
“M-x ibuffer”とタイプするとibufferによるバッファリストが開きます.この状態だと,見た目はバッファ名が色分けされている以外は通常のバッファリストとあまり違いはありません.通常のバッファリストと比べて便利なのは,バッファのソートや絞り込みが簡単にできることです.たとえば”s m”とタイプするとメジャーモードで,”s s”だとバッファサイズでソートされます.”,”とタイプするとソート条件を次々に切り替えていくことができます.絞り込みも,たとえば”/ m”とタイプするとメジャーモードで,”/ n”とタイプするとバッファ名で絞り込みができます.
カスタマイズも豊富です.ソート順や絞り込み条件のデフォルト値を設定できる他,バッファリストに表示したくないバッファ名を正規表現で指定できたり,ディレクトリ名のエイリアスのようなものを定義できたりします.
便利そうなのは確かですが,個人的にはあまりありがたみを感じません.筆者は普段から使い終わったバッファはすぐ閉じる習慣が付いているので,そもそもバッファリストを表示すること自体が少ないのです.とはいえ,入れておいて損はないと思いますし,バッファをたくさん開いて作業する必要があるときにはやはり便利でしょう.
気に入った方は,.emacsにリスト5のように書いて,標準のバッファリストと置き換えてしまうと幸せになれるかもしれません.

———————————————————————–
☆リスト5 標準のバッファリストをibufferで置き換える
(global-set-key “\C-x\C-b” ‘ibuffer)
———————————————————————–

[図8 ibuffer.png]

■■ tabbar.el
バッファ一覧をタブで表示して,「次のタブ」「前のタブ」というようにバッファを切り替えられるようになります.
“M-x tabbar-mode”とタイプするとタブが表示されます.”M-x tabbar-forward”で1つ右のタブへ,”M-x tabbar-backward”で1つ左のタブへ切り替えられます.

[図9 tabbar.png]

■ タブのグループ化の設定
デフォルトの状態では,タブはバッファのメジャーモードごとにグループ化されて表示されます.このグループ化の方法は,listを返す関数を定義することで変更できます.
.emacsにリスト6のように書くと,”*”で始まるバッファ(*scratch*や*Messages*など)を”Emacs Buffer”,dired-modeのバッファを”Dired”,それ以外を”User Buffer”にグループ化できます.

———————————————————————–
☆リスト6 タブのグループ化の例
(defun my-tabbar-buffer-groups (buffer)
(with-current-buffer (get-buffer buffer)
(cond
((string-match “^\\*.*” (buffer-name))
‘(“Emacs Buffer”)
)
((eq major-mode ‘dired-mode)
‘(“Dired”)
)
(t
(list “User Buffer”)
))))
(setq tabbar-buffer-groups-function ‘my-tabbar-buffer-groups)
———————————————————————–

これを利用して,グループ化しない設定も可能です.リスト7のように書くことで,全てのタブが”All”にグループ化され,実質的にグループ化なしとして使うことができます.

———————————————————————–
☆リスト7 タブをグループ化しない例
(defun tabbar-buffer-groups-all (buffer)
(list “All”))
(setq tabbar-buffer-groups-function ‘tabbar-buffer-groups-all)
———————————————————————–

■ 表示するバッファの設定
グループ化なしで使っていると,*scratch*や*Messages*がタブとして表示されるのが邪魔になるかもしれません.タブとして表示する条件も,関数を定義することで変更できます.リスト8のように書くと,” *”で始まるバッファはタブとして表示されなくなります.

———————————————————————–
☆リスト8 ” *”で始まるバッファをタブとして表示しない例
(defun my-tabbar-buffer-list ()
(remove-if
(lambda (buffer)
(find (aref (buffer-name buffer) 0) ” *”))
(buffer-list)))
(setq tabbar-buffer-list-function ‘my-tabbar-buffer-list)
———————————————————————–

いちいち”C-x C-b”でバッファリストを開かなくても,現在開いているバッファを把握できるのでなかなか快適です.tabbar-forwardとtabbar-backwardに適当なキーを割り当てておくと,バッファ間の移動も直感的になります.バッファの切り替えは,普段はtabbar.elでタブ化しておいて,バッファ数が増えてきたらibufferで探す,という合わせ技が良いかもしれません.

■■ おわりに
今回ご紹介したElispの入手元を表1に示しました。これ以外にも,便利なElispは多数公開されています.普段の作業を楽にするものがないか,ぜひ探してみてください.また,既存のElispのコードを読みながら改造してみるのも,Elispを学ぶ近道になると思います.

———————————————————————–
☆表1 今回紹介したElisp一覧

名称 入手元
newsticker.el 標準添付
wdired.el 標準添付
keywiz.el http://purl.org/harder/keywiz.el
tld.el http://www.davep.org/emacs/tld.el
table.el 標準添付
all.el ftp://ftp.dina.kvl.dk/pub/Staff/Per.Abrahamsen/auctex/all.el
lcomp.el http://www.geocities.co.jp/SiliconValley-Oakland/7673/lisp/lcomp.el
tail.el http://www.drieu.org/code/sources/tail.el
ibuffer.el http://www.shootybangbang.com/software/ibuffer.el
tabbar.el http://sourceforge.net/projects/emhacks/files/
———————————————————————–