Personal tools
You are here: Home 原稿・資料 Software Design連載記事「Emacsのトラノマキ」の原稿 Emacs 23.1登場(井上誠一郎)
Document Actions

Emacs 23.1登場(井上誠一郎)

「Emacsのトラノマキ」連載第六回「Emacs 23.1登場」

■■■ 最近のEmacsのリリース
本誌発売時には既に過去の話になっていますが,2009年7月29日にEmacs 23.1のリリースがありました.Emacs 23.1のリリースを記念して,最近のEmacsのリリースからトピックを拾いつつその周辺の話をします.

http://www.gnu.org/software/emacs/からEmacs 21.1以降のリリースを表にまとめます.

============================
バージョン名 日付 トピック
Emacs 23.1 2009/7/29 メジャーリリース
Emacs 22.3 2008/9/5 マイナーリリース
Emacs 22.2 2008/3/26 マイナーリリース(GPL v3)
Emacs 22.1 2007/6/2 メジャーリリース
Emacs 21.4 2005/2/6 movemailのセキュリティパッチ(注1)
Emacs 21.3 2003/3/24 マイナーリリース
Emacs 21.2 2002/3/18 マイナーリリース
Emacs 21.1 2001/10/28 メジャーリリース
============================

注1)http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0100

Emacs 22以降に話を限定します.リリースノート(NEWSファイル)のすべては紹介していません.筆者個人の趣味で選んでいることをあらかじめご了承ください.また22系の話でもスクリーンショット等は23系を使っています.

基本的にUnix系OSとX Window Systemを前提に書いています.他のプラットフォームの話は機会があれば本連載でいつか取り上げます.


■■■ Emacs 22.1

■■ 初期化ファイルの変更
伝統的なEmacsの初期化ファイルは.emacsファイルです.Emacs 20.4は.emacs.elを導入しました.Emacs 22.1で.emacs.dディレクトリの下のinit.elファイルを導入しました.ロードの優先順に並べると次のようになります.

============================
Emacsの初期化ファイル(ロードの優先順)
~/.emacs.elc
~/.emacs.el
~/.emacs
~/.emacs.d/init.elc
~/.emacs.d/init.el
============================


■■ revert-buffer-with-coding-systemコマンド(C-x RET r)
Emacsを使う理由は様々ですが,サポート文字コードの多さも理由のひとつだと思います.ただ,サポート文字コードの多さが災いして文字コード判定を間違える事故もそれなりにあります.文字コード判定の間違い自体は避けられないので諦めがつくのですが,文字コードを明示してファイルを開き直す方法がわかりにくい欠点がありました.今まで次のようなキーストロークが必要でした.

============================
; 文字コードを明示してファイルを開く従来の方法(Emacs 22以降でも使えます)
C-x RET c 文字コード C-x C-f
C-x RET c 文字コード C-x C-v
============================

Emacs 22でrevert-buffer-with-coding-systemコマンドができました.キーアサインは"C-x RET r"です.revertのrで覚えてください.文字コード判定を間違えてファイルが文字化けした場合は,"C-x RET r"とタイプします.文字コードを聞かれるのでutf-8やeuc-jpの文字列を入力します.もちろんタブキーによる補完もできます.指定した文字コードでファイルを開き直してくれます.


■■ lgrep,rgrep,grep-find,multi-occurコマンド
検索用コマンドの細かい改良があります.lgrepとrgrepはgrepコマンドのラッパーコマンドです.lgrepとrgrepは本連載の第1回で紹介したので本誌バックナンバーを参照してください.

grep-findは従来からあるfind-grepコマンドの別名です.コマンドに別名をつけるには次のようにdefaliasで行います..emacsの中でも使えるので気に入らないコマンド名を自分好みにできます.引数の'(シングルクォート)はコマンドを実行せず,コマンド名を取り出す呪文だと考えてください.

============================
; grep.elから抜粋
(defalias 'find-grep 'grep-find)
============================

occurコマンドは名前から動作がイメージしづらいため知らない人もいますが,有用なコマンドです.現在のバッファ内から正規表現での検索結果を一覧できます.先月説明したthingを組み合わせると次のようにカーソル位置の単語を"C-o"キーで探せて便利です.

============================
; カーソル位置の単語をバッファ内から探す設定例
(global-set-key "\C-o" (lambda () (interactive)
(if (thing-at-point 'symbol)
(occur (thing-at-point 'symbol))
(call-interactively 'occur))))
============================

Emacs 22でmulti-occurコマンドができました.複数のバッファ内から検索できるoccurです."M-x multi-occur"を実行すると検索対象のバッファ名を聞かれるので答えます.実際に使ってみると複数のバッファ名の指定が面倒です.そのような場合,"M-x multi-occur-in-matching-buffers"を試してください.検索対象のバッファ名を正規表現で指定できます.たとえばオープン中のJavaのソースコードを検索対象に指定する場合,バッファ名のパターンに"\.java"と入力します.検索したい正規表現を入力するとバッファ内を検索してくれます.


■■ image-dired.elでサムネイル表示
Emacsが画像を表示できるようになったことはEmacs21の驚きでした.バッファ内に画像を表示できる以上,画像ファイルのサムネイル表示ができるのは当然ですが,標準パッケージとして用意されました.

"M-x image-dired"とタイプするとサムネイル表示をするディレクトリを聞かれます.ただ,画像ビューワとして見るとEmacsは特に優れたツールではありません.image-diredコマンドより,diredでファイル一覧を見ている時に"C-t C-t"(image-dired-dired-insert-marked-thumbs)で画像をインサートする機能の方が便利です.複数の画像ファイルを同時に開きたい場合はdired上のファイル名をmキーでマーク後,"C-t C-t"をタイプします.dired内にEmacs22とEmacs23のアイコンを表示した例を示します(図1).

============================
[図1] image-dir.png
============================

Emacs 23ではSVG画像ファイルもサポートしました(librsvg2が必要です).画像表示から画像ファイルのソース表示に切り替えるには"C-c C-c"とタイプします.


■■ マウス関係
Emacsユーザはあまりマウスを使わないかもしれませんが,UI(ユーザインターフェース)の方向性のひとつとして紹介します.

マウスの左クリック(ボタン1)でリンクオープン動作になりました.diredでファイルを左クリックしてファイルオープンになることで確認できます.従来はボタン2(3ボタンの場合は真ん中ボタン,2ボタンの場合は右ボタン)でリンクオープン,ボタン1はポイント(カーソル位置)の指定でした.エディタの枠組で考えると左クリックでカーソル位置指定は自然な動作です.リンクオープン動作はWeb UIの影響です.左クリックを長押しすると従来どおりにカーソル位置指定になります.またマウスをドラッグした場合はテキストのコピーになりリンクオープンの動作にはなりません.このため普通に使う分には直感どおりの動作になります.左クリックを従来動作に戻すには変数mouse-1-click-follows-linkをnilにします.

他のWeb UIの影響としては,Emacs 23のinfoのbreadcrumbs(パンくずリスト)があります.Emacsの世界にもWeb UIの影響が現れています.


■■ GUD(Grand Unified Debugger)のリッチUI
GUDはgdbなどのデバッガの統合フロントエンドパッケージです.gdbを開始する場合,"M-x gdb"とタイプします.gdbの起動プロンプトになるのでgdbのコマンドライン引数を指定します.普通は第1引数に実行ファイルのパスを渡します.起動中のプロセスにアタッチする場合は第2引数にプロセスID,コアファイルを解析する場合は第2引数にコアファイルのパスを渡します.

"M-x gdb-many-windows"とタイプすると次のような多画面モードになります(図2).

============================
[図2] gdb.png
============================

もう一度"M-x gdb-many-windows"とタイプすると2画面モードに戻ります."M-x gdb-restore-windows"はウィンドウの分割状態を復元するコマンドです.

実務で多画面モードを使ってみました.感想は,残念ながらあまり使いやすく感じませんでした.慣れの問題もあるかもしれませんが,ウィンドウ分割が多いとキーボードでの操作が面倒に感じました.機能だけを見ると魅力的です.マウスクリックでブレークポイントの設定やコールスタック上の移動ができます."M-x gud-tooltip-mode"とすることで,マウスポインタを変数の上に重ねた時のツールチップに変数の値を表示できます."M-x gud-tooltip-dereference"でポインタ型変数の参照先オブジェクトの内容表示もできます.マウスだけで使うと割り切ると便利なのかもしれませんが,筆者はマウスとキーボードを行ったり来たりするのが面倒になりました.

変数mouse-autoselect-windowをtにすると,マウスポインタの入ったウィンドウに自動でフォーカスが移ります(Emacs 22からの機能).GUDと相性が良いかもしれません.


■■ M-gとgoto-line
M-gがprefixキーとしてアサインされました.デフォルトで次の組み合わせがアサイン済みです.

============================
キーアサイン コマンド 意味
M-g g と M-g M-g goto-line 指定した行にジャンプ
M-g n と M-g M-n next-error occurやcompileの結果画面で次行を選択("C-x `"と同様)
M-g p と M-g M-p previous-error occurやcompileの結果画面で前行を選択
============================

Emacsは一般にコントロールキーやメタキーを組み合わせたキーストロークを使います.単独のキーとの組み合わせには限度があるので,2ストローク以上の組み合わせがあります."C-x C-f"などです.2ストローク以上の組み合わせに使う"C-c"や"C-x"がprefixキーとして予約されています.今回,新たに"M-g"がprefixキーに加わりました.

ところで,"M-g"は多くの人が次のようにgoto-lineコマンドに割り当てているのではないでしょうか.この記述を.emacsに残せば従来どおり"M-g"でgoto-lineになります.goto-lineは"M-g M-g"にするか"M-g"にこだわるか悩ましいところです.

============================
(global-set-key (kbd "M-g") 'goto-line)
; (global-set-key "\M-g" 'goto-line) ;別の記述
============================


■■ kill-whole-lineコマンド (ページ数オーバーの場合,削除候補)
Emacs使いは"C-k"(kill-lineコマンド)をよく使います.kill-lineコマンドは1行削除して内容をキルリングにいれます.キルリングについては本連載の第4回および第5回を参照してください.kill-lineコマンドは最後の改行を削除しません.このため直感的な1行を削除するには"C-k C-k"のように2回のキー入力が必要です.慣れてしまうと行頭にカーソルを移動する"C-a"と合わせて,"C-a C-k C-k"を無意識に入力するようになります.

この動作,1部の人には違和感があるようで,次の設定を.emacsに書いている人を数人見たことがあります.

============================
; kill-lineコマンドで改行まで含めて削除する設定
(setq kill-whole-line t)
============================

この設定のEmacsを操作するのは苦痛でした(設定を戻しました).単なる慣れの問題ですが操作を身体が覚えているので相容れません.Emacs 22でkill-whole-lineという新しいコマンドができました.デフォルトで"C-S-<backspace>"に割り当てられています.今後,kill-lineの動作が気に入らない人は,"C-k"の動作はそのままにして,kill-whole-lineコマンドを他のキーにアサインして使ってください.


■■ バッファ長と整数長が2倍に(32ビット環境で256Mバイト)
256Mバイトは正確には2の28乗(268435456)です.elispの整数が28ビット長になりました.変更前は27ビット長でした.

28ビット長は32ビット環境で考えると3ビット分の損失を意味しています.この3ビットを理解するには少しEmacsの内部実装を知る必要があります.

elisp実行環境は多数のオブジェクトを生成します.内部的にはオブジェクト(確保したメモリ領域)とオブジェクトを指し示すポインタ型変数を管理します.オブジェクトは文字列やベクタなどの種別があります.専門的にはこのような種別を型と呼びます.ポインタ型変数が指し示す先のオブジェクトの型を知るためにEmacsは少しトリッキーなことをしています.ポインタ型変数の値はアドレス値です.(オブジェクトの)メモリ確保を特定のバイト境界に揃えるとアドレス値の下位ビットはゼロに揃います.たとえば8バイト境界に揃えると下位3ビットがゼロになります.16バイト境界に揃えると下位4ビットがゼロになります.ゼロに揃ったビットは他の用途に使うことができます.なぜなら対象ビットをゼロに戻す変換をすれば,いつでもアドレス値として解釈できるからです.Emacsはアドレス値のうち3ビット分をポインタ型変数が指すオブジェクトの型種別に使います.

整数から3ビット失われている背景にはもうひとつ仕掛けがあります.文字列オブジェクトであれば文字列をメモリに確保して,そこを指すポインタ型変数で特に問題ありません.一方,32ビットの整数オブジェクトを確保して,そこを指す32ビットのポインタ型変数を使うのは無駄に感じます.このため,整数オブジェクトを別途メモリに確保せずポインタ型変数を整数型変数に読み替える工夫をします(C言語の用語を使うと共用体を使います).変数の値がポインタ値か整数値かの区別は,型種別を持つ3ビットの利用で可能です.

これが整数が3ビット分を使えない理由です.Emacs 22より前に27ビット長だったのはなぜかという疑問がわきます.この1ビットの理由を知るにはEmacsのGC(ガベージコレクション)の実装の知識がいります.GCとは不要になったオブジェクトを自動で回収する仕組みのことです.EmacsのGCはマーク&スイープと呼ばれるアルゴリズムを使っています.オブジェクトが不要かどうかを見分けるためにマークをつけて区別します.このマークのためにポインタ型変数の値の1ビット分を使っていました.これが27ビット長だった理由です.マークはGCの最中だけに意味があるので,やや非効率的なビットの流用でした.Emacs 22で基本的にはマークビットをオブジェクト側に持たせる実装になりました(他の手段も組み合わせています).これで1ビット増えました.増えた1ビットをありがたく使ってください.


■■■ Emacs 22.2とEmacs 22.3
Emacs 22.2からひとつトピックを紹介します.

■■ diredのディレクトリ単位のコピーと削除
dired-recursive-deletes変数とdired-recursive-copies変数のデフォルト値がnilから'top'に変わりました.このふたつの変数は従来から存在する変数です.dired上でのディレクトリ単位のコピーと削除を制御する変数です.値がnilの場合,ディレクトリ単位のコピーと削除の禁止を意味していました.不便なので次のように設定することが(知っている人には)推奨でした.

============================
; Emacs 22.2より前に必要だった設定
(setq dired-recursive-deletes 'top)
(setq dired-recursive-copies 'top)
============================

'topを指定すると,ディレクトリのコピーおよび削除時に許可/不許可を聞いてきます.yesまたはnoで答えてください.他に'alwaysとtの指定が可能です.'alwaysを指定するとサブディレクトリごとにコピーおよび削除の許可/不許可を聞くようになります.tを指定するとディレクトリ単位のコピーおよび削除をすぐに実行します.

22.3は特に大きなニュースはありません.


■■■ Emacs 23.1

■■ フォントの改善
筆者は今まで多くのプログラマにEmacsを勧めてきました.最近のEmacsであればメニューを出した状態にして,メニューから操作を始めてもらいます.メニューにはC-x C-fのようにキーアサインが表示されているので,キーアサインを徐々に覚えていけばいいと助言します.プログラマであればどんなエディタを使っても,結局なんらかのショートカット操作を覚える必要があるのでEmacsが特別だとは思っていません.

最近Emacsを使い始めた人が不満を口にすることの多かったのがフォントでした.特にGNOMEなどの統合デスクトップ環境がアンチエイリアスの効いたフォントで見栄えを統一しているので,相対的にEmacsが見劣りすることが多かったのも事実です.

Emacs 23の最も大きな変更がフォント周りの改善です.裏側の話は本連載で別の機会にできたらと思っていますが,GTK+とXftを使える環境(最近の多くのメジャーなフリーUnixは満たしていると思います)であれば特に設定ファイルを書くことなく見栄えの良いフォントを使えます.

シフトキーと左クリックでフォント変更のメニューがでます.メニューを選択するとGTK+のフォント選択ダイアログがでます.直感的にフォントを選択可能です."C-x C-+"と"C-x C--"でフォントサイズを変更できます.元のサイズに戻すには"C-x C-0"とタイプします.


■■ 物理行の移動
"C-n"と"C-p"による行移動が論理行移動から物理行移動になったと聞くと,昔からのEmacs使いは驚くのではないでしょうか.

論理行と物理行の違いを,1行の文字数が200文字でウィンドウの横幅が100文字の時で説明します.行の先頭にカーソルがある状態から"C-n"で次行に移動したとします.Emacs 22以前は論理行の移動なので200文字スキップした次の行に移動します.Emacs 23の物理行移動は100文字スキップして,画面の見た目で1文字下の位置に移動します.

昔の論理行移動が使いやすい人は,次のように変数line-move-visualをnilにしてください.

============================
; 論理行移動モード
(setq line-move-visual nil)
============================


■■ ごみ箱サポート
次の設定をするとdiredからファイルを削除した時に,OSが提供するごみ箱にファイルを移動します.GNOMEとWindowsで動作を確認しました.

============================
; ごみ箱を有効
(setq delete-by-moving-to-trash t)
============================


■■ whitespaceパッケージ
某社に秀丸を使うプログラマがいました.その人に,なぜEmacsではなく秀丸を使うのか聞いたことがあります.その人の回答はEmacsでは空白やタブ文字が可視化されないのが嫌というものでした.その時の感想は,たったそれだけのことでもEmacsを使わない理由になるのかと驚きました.

Emacs 23でwhitespaceパッケージが標準になりました."M-x whitespace-mode"とタイプすると次のような画面になります(図3).スペース文字,タブ文字,改行文字を可視化します.

============================
[図3] whitespace.png
============================

可視化がうるさいと感じる場合,"M-x whitespace-toggle-options"を実行すると部分的に可視化を制御できます.

いわゆる全角スペース文字を可視化する設定を紹介します.

============================
; whitespace-modeで全角スペース文字を可視化
(setq whitespace-space-regexp "\\( +\\|\x3000+\\)")
============================


■■ VC改善
VCはEmacsから各種ソースコード管理システムを統合的に扱えるパッケージです.SCCSとRCSのようなローカルで使うバージョン管理システムもCVSやsubversionのようなクライアントサーバ型のバージョン管理システムも同じUIで統合的に扱えます.22以降もGitなど分散型システムの対応も進んでいます.

============================
Emacsバージョン トピック
Emacs22.1 subversionサポート
Emacs22.2 Git,Mercurial,Monotone,Bazaarサポート
Emacs23.1 複数ファイルのコミット(changeset)サポート
============================

VCの強力さはEmacsの魅力のひとつです.VCについては本連載でいつか取り上げる予定です.


■■ リージョン関係の変更
Emacsのリージョンとは直感的には選択範囲のことです.本連載の第4回で言及したように,Emacs 23でリージョンの可視化(ハイライト表示)がデフォルトになりました.リージョンのハイライト表示が鬱陶しいと感じる人は変数transient-mark-modeをnilに設定してください.

他のエディタで範囲選択を行う時,シフトキーを押しながらカーソル移動,という操作がよく使われます.Emacs 23でシフトキーを押しながらカーソル移動でリージョン選択ができるようになりました.この動作を止めたい場合は変数shift-select-modeをnilにしてください.


■■ D-Busサポート
D-BusとはGNOME由来の汎用プロセス間通信の仕組みです.Unixのプロセス間通信と言うと,シグナル,ソケット,共有メモリ等は低レイヤすぎ,かと言って,少し上位で共通化された仕組みは,いわゆるクリップボードやドラッグ&ドロップなどのウィンドウシステム依存の仕組みしかありませんでした.その間を埋める汎用プロセス間通信の土台がD-Busです.

D-Busサポートの応用例のひとつとしてxesam.elがあります.デスクトップサーチエンジン(Beagle,Strigi,Trackerなど)を呼び出す共通APIのXesam(eXtEnsible Search And Metadata)実装です."M-x xesam-search"で実行できます.Xesamについてはhttp://xesam.orgを参照してください.


■■ procedでプロセス一覧
"M-x proced"とタイプするとプロセス一覧を表示できます.画面例(図4)はプロセスをツリー表示(Tをタイプ)にした画面です.一覧の自動更新も可能です("M-x proced-toggle-auto-update").top(1)コマンドがなくてもEmacsだけでプロセスの監視ができるようになりました.top以上に観測問題が深刻になりそうですが(注2).現在procedが使えるのはGNU/Linux,Solaris,Windowsのみです.

============================
[図4] proced.png
============================

注2)CPUを食っているプロセスを探すためにtopを使うとtopがCPUを食って上位に現れる問題.


■■ UTF-8
内部の文字コードがUTF-8になりました.内部的な話はいずれ本連載でも取り上げたいと思います.ここではdescribe-charコマンド("C-u C-x =")を紹介します.Emacs 22からあるコマンドです.文字のコードポイントやフォント情報を簡単に調べることができます(図5).

============================
[図5] code-point.png
============================


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.