Software Design連載記事を掲載します。

株式会社技術評論社の許可を得て掲載しています。
草稿なので細かい部分は実際の記事とは異なることがあります。

他の記事は左下にある「■雑誌連載中(全文公開)」から見られます。

今こそ基本に立ち帰ろう

 ども、るびきちです。本連載も先月で1年になり、まさに一周したような感じです。最初の数回はEmacsを使ったことのない人を対象に、Emacsの基礎概念をゆっくりと紹介しました。その後はddskkによるOS非依存の日本語入力を紹介したことで、複数のOSを使う人でもEmacsは有用だと示しました。その後は、様々なカーソル移動、入力支援、検索・置換というテキストエディタとしてのEmacsの使い方を紹介しました。dired、eshellというOS非依存のファイラーとシェルもありました。Emacs上のワープロ・スーパー電子手帳であるorg-modeについても軽く触れました。

 そして、先々月と先月は2回に分けて、それらを統合するhelmという超強力なパッケージを紹介しました。helmを使いこなすことで、あなたのEmacsはかなり使いやすくなったことでしょう。

 ですが、今回はあえて初心に帰って、キーに割り当てられた標準コマンドに焦点を当ててみます。今回が初めての読者はもちろんのこと、ベテランユーザも今一度標準機能を見直しててはいかがでしょうか。最近導入された機能は意外と知られていないものです。

キーに割り当てられたコマンドを見てみよう

 Emacsはデフォルトの状態で無数のコマンドがキーに割り当てられています。<f1> bを実行すれば、キーに割り当てられたすべてのコマンドがわかります。しかし、それはカスタマイズされた状態での表示なので、デフォルトの設定ではありません。

 そこで、emacs -Qで立ち上げた後で<f1> bを実行すればデフォルトの状態が分かります。あるいはeshellで

emacs -batch -f describe-bindings -eval '(with-current-buffer "*Help*" (princ (buffer-string)))'

を実行してもいいです。このコマンドは、デフォルトの状態Emacsをバッチモードで起動し、<f1> b (describe-bindings)を実行し、表示された内容を標準出力に出力して終了します。

 出力は約1000行にも及びます。これだけ多くのコマンドが標準状態で割り当てられているのは驚きです。Emacsを使って20年になる筆者も、すべてのコマンドを使いこなせているわけではありません。

1ストロークのキー

 Emacsで頻繁に使われるコマンドは1ストロークのキーに割り当てられています。

 とくにCtrl+英字は基本的なコマンドばかりなのでしっかりおさえておきましょう。とはいえ一部は使用頻度が低いです。C-tは文字の順序を入れ替えるタイプミスを修正してくれるのですが、日本語のローマ字入力では使えないので無理に使う必要はないです。C-qは制御文字や改行文字を入力するときに使いますが、めったに使いません。C-zはEmacsのフレームをサスペンドしますが、Emacsひきこもり生活をしていれば全く使いません。

 困ったらC-gやC-/を押すことは絶対に覚えてください。Emacsユーザはパニックになってはいけません。C-gでコマンドを取り消し、C-/でバッファへの変更を取り消します。たまにC-gで取り消せずEmacsが固まってしまうこともありますが、それはEmacs本体かLispレベルのバグなのであきらめて再起動しましょう。

 特殊キーの代わりにCtrlを使うと指を動かす距離が短くなります。TABの代わりにC-i、RETの代わりにC-m、ESCの代わりにC-[が使えます。

 Meta(Alt)+英字は、だいたいCtrl+英字の補助的なコマンドが多いです。作用対象が文字→単語、行→センテンスに変わったりします。面白いことに、M-pとM-nには何もキーが割り当てられていません。それらはメジャーモードが自由に割り当てられるようにわざと空けています。名前を指定してコマンドを実行するM-xが重要なのは言うまでもないです。

 Meta+記号文字には多くのコマンドが割り当てられています。たとえば、M-!でシェルコマンド実行、M-% で置換などがあります。特にM-/のdabbrevはタイプミス撲滅・タイプ数節約のためには多用しておきたいです。中には使用頻度の低いコマンドも含まれていますが、そういうのは無理に覚える必要はありません。

プレフィクスキー

 それでは、もっと深く見ていきましょう。Emacsにはプレフィクスキーが用意されており、2ストローク以上のキーにコマンドが割り当てられます。そのおかげでこれだけ多くのコマンドをキーに割り当てられます。出力から抜き取り吟味した結果、これだけ多くのプレフィクスキーが見付かりました。

C-c 汎用プレフィクスキー
ESC Meta/C-[と同じ
C-x 標準プレフィクスキー
C-x C-k キーボードマクロ関係
C-x RET エンコーディング関係
C-x ESC C-x ESC ESC(repeat-complex-command)のみ
C-x 4 other-window関係
C-x 5 other-frame関係
C-x 6 2C(two-columns)関係
C-x 8 アクセント文字などを入力する
C-x a abbrev関係
C-x a i abbrev関係
C-x n ナローイング関係
C-x r レジスタ・矩形関係
C-x v VC(バージョン管理)関係
C-h ヘルプ
C-h 4 C-h 4 i (info-other-window)のみ
M-s 検索関係
M-s h ハイライト関係
M-o facemenu関係
M-g カーソル移動関係
M-ESC ESC ESC ESC(keyboard-escape-quit)のみ
<f1> C-hと同じ
<f1> 4 C-h 4と同じ
<f2> C-x 6と同じ

各プレフィクスキー

 それでは主なプレフィクスキーを見てみましょう。

標準コマンドへの入口のC-x

 C-x は常に使える標準コマンドのためのプレフィクスキーです。

 C-x+1文字にも重要なコマンドが勢ぞろいしています。たとえばC-x C-s(保存)やC-x C-f(ファイルオープン)やC-x b(バッファ切り替え)などは真っ先に覚える必要があります。

 Emacsにはデフォルトで1000ものコマンドが割り当ててあるため、C-x から始まる2〜3ストロークのプレフィクスキーもあったりします。それらにはおおむね同じカテゴリのコマンドが割り当てられています。

 たとえばC-x 4をプレフィクスキーとするコマンドは、other-window系列のコマンドであり、隣のウィンドウに表示するものばかりです。しかも普通のC-x 系のコマンドから類推できるキーなので覚えやすいです。C-x 4 bはC-x bの、C-x 4 C-fはC-x C-fのother-window版です。ウィンドウが分割されていないときは分割します。

 プレフィクスキーC-x 5はother-frame系列のコマンドで、別フレームで表示するものばかりです。C-x 4と同じくC-x 5 bはC-x b、C-x 5 C-fはC-x C-fに対応しています。

 プレフィクスキーC-x nはナローイング(narrowing)関連のコマンド担当です。ナローイングとは、編集領域をバッファの一部に制限し、範囲外を一時的に見えなくする機能です。C-x n nでregionをナローイングし、C-x n wでナローイングを解除します。他のナローイングのコマンドも用意されています。

 プレフィクスキーC-x rはレジスタ(register)、矩形(rectangle)関連のコマンド担当です。それぞれ働きは異なりますが、どちらも頭文字がRなので共通のプレフィクスキーになっています。どちらも説明すると長くなるので割愛します。他に置き場所がないのか、なぜかブックマーク関連のコマンドもC-x rをプレフィクスキーにしています。

 プレフィクスキーC-x vはバージョン管理システム関連のコマンド担当です。C-x v vでファイル登録・コミット、C-x v =でdiff、C-x v lでログを表示します。他にもたくさんのコマンドがありますが、通常使用ではこの3つがあれば事足ります。

 プレフィクスキーC-x RET(C-x C-m)はバッファやファイルのエンコーディング(coding system)関連のコマンド担当です。バッファのエンコーディングを変更して保存するにはC-x C-m fで設定します。Emacsがエンコーディングを誤認識したときはC-x C-m rで明示的に指定してファイルを開き直します。この2つを知っていれば十分です。

モードコマンド・ユーザ割り当てのC-c

 C-c は汎用的なプレフィクスキーです。C-c をプレフィクスキーとする割り当て方はキーバインドの規約で決まっています。

 まず、C-c+英文字はユーザが自由に割り当てられる領域になっています。elispプログラムではそれらにコマンドを割り当ててはいけないという厳密な決まりがあります。メジャーモードで使うのは論外ですが、実際には一部の外部パッケージによるマイナーモードでは使われていることもあります。よって、規約に違反しているマイナーモードがなければ、安心して好きなコマンドをC-c+英文字に割り当てられます。

 C-c+コントロール文字、C-c+数字、C-c {、C-c }、C-c <、C-c >、C-c :、C-c ;はメジャーモードが使うように予約されています。ほとんどのメジャーモードはC-c+C-英文字に割り当てれば間に合っています。

 プレフィクスキーの後でもEmacsのキーの意味が継承されています。たとえばC-c C-pやC-c C-bで前、C-c C-nやC-c C-fで次の要素に移動するコマンドが割り当てられていることがしばしば見られます。

 特定のメジャーモードに付随するマイナーモード…たとえばorg-modeに対するorg-capture-mode…はorg-modeの元のキーバインドを上書きするために、わざとC-c C-cなどにコマンドを割り当てていたりします。なぜなら、マイナーモードはメジャーモードより優先するからです。

 C-c の後に上記以外の記号文字はマイナーモードのために用意されています。とはいえ、メジャーモードで使うことは禁じられていません。実際org-modeのような巨大メジャーモードではC-c 'などにコマンドが割り当てられています。

ヘルプの<f1> (C-h)

 <f1>とC-hは、ヘルプのためのプレフィクスキーになっています。関数や変数の説明を見たりinfoを読んだりEmacsの変更履歴を見たりできます。ヘルプコマンドはとても多いので、これらのキーを2度押すことでヘルプメニューが出てきます。

 コマンドを正確に覚えていれば<f1>は1回で構いません。たとえば<f1> <f1>の後にaを押すとaproposが起動しますが、<f1> aでもできます。aproposとは、スペース区切りの正規表現にマッチするシンボル(コマンド、関数、変数、フェイス)を探すコマンドです。

 実用の観点ではC-hはヘルプではなく1文字後退にするとよいです。delete-backward-charに割り当てるか、OSレベルで<backspace>のキーコードを発行させるとよいです。とくに後者はEmacsの外でもC-hで1文字後退してくれるようになってとても快適です。

(global-set-key (kbd "C-h") 'delete-backward-char)

カーソル移動補助のM-g

 M-g はEmacs22から導入されたカーソル移動系プレフィクスキーです。M-g M-gで指定した行番号に移動(goto-line)します。Emacs24.3からはM-g C-iで指定した桁に移動(move-to-column)し、M-g cで指定した位置に移動(goto-char)するコマンドも追加されました。

 外部プログラムとの橋渡しをするのもEmacsの重要な役割です。M-x compile、M-x grep、M-x executable-interpretはそれぞれ外部プログラムをEmacsのバッファで実行します。外部プログラム実行後にM-g M-n (next-error)とM-g M-p (previous-error)を使うと、ウィンドウを選択することなく実行結果が指し示す行にジャンプします。M-g M-nは大昔からC-x `にも割り当てられています。また、これらのコマンドはelispによるバッファ内検索であるM-s o (occur)にも対応しています。

 M-gにはこれくらいしかコマンドが割り当てられていないので、余っている部分にはユーザが好きなように割り当てればよいです。

検索、そして新天地のM-s

 M-s はEmacs23から導入された検索系プレフィクスキーです。比較的新しいので知名度はあまり高くないかもしれません。M-x occurはM-s oに割り当てられています。

 M-s w(isearch-forward-word)で単語のisearchができます。旧来ではC-u C-s \bと正規表現を使う必要がありました。

 Emacs24.4からはシンボルisearchができるようになりました。特にコーディングの際には現在位置のシンボルを検索することが多いです。従来のisearchの欠点は短い文字列をisearchしたとき、その文字列を含む長い文字列にもマッチする点です。そこでシンボルisearchを使うと、そのシンボルそのものに対してのみマッチします。たとえばsetqに対してシンボルisearchを使うと、setqにはマッチしますが、setq-localにはマッチしません。シンボルisearchはM-s . (isearch-forward-symbol-at-point)でできます。旧来ではC-u C-s \_< C-wと操作する必要があり、とても面倒でした。

 M-s hはバッファ自動色付け(hi-lock)機能のためのプレフィクスキーです。M-s h . (highlight-symbol-at-point)は現在のシンボルをすべて色付けします。M-s h l (highlight-lines-matching-regexp)は正規表現にマッチする行をすべて色付けします。M-s h u (unhighlight-regexp) は、色付けを解除します。

 M-sも割り当てられているコマンドが少ないので、ユーザは安全にコマンドを割り当てられます。特にM-s M-■には一切割り当てられていないのは、押しやすいキーを求めている人には絶好のチャンスです。

数引数・前置引数

 数引数・前置引数は地味ながらも基本的なEmacsの機能ですが、まだ話していませんでした。数引数・前置引数とは一言で言えばコマンドの前に指定するC-uのことです。

数引数

 一部のコマンドにC-uを前置したとき、そのコマンドの挙動が変わります。C-uが「数引数」と言われるのは、多くの編集コマンドや文字をその数だけ繰り返すからです。たとえばC-fの代わりにC-u 4 C-fを実行すると、4文字進みます。C-bやC-pやC-nに対しても同様です。負の数を指定した場合は逆の挙動をします。たとえばC-u - 3 C-fで3文字戻ります。

 ただ、このように数字や負号を指定するためにCtrlキーを離すと操作しづらいですね。そこで、Ctrlを押しながらでも数を指定できるようになっています。C-u 4 C-fはC-u C-4 C-fと操作できます。

 実はCtrlやMetaあるいは両方を押しながら数を指定したときは、直前のC-uを省略できます。C-u C-4 C-fはC-4 C-fと、C-u 4 M-fはM-4 M-f となります。

 数引数を取るコマンドで数を指定せずにC-uのみを指定した場合、4が指定されたことになります。よって、C-u 4 C-fなんて操作する必要はなく、C-u C-fでいいのです。「4」は絶妙な数で、C-fを3回押すのはともかく、4回押すのはだるいと感じる人間の心理を表しているようです。かといってC-4 C-fは左手人差指を上下する必要があり、打ちづらいです。そこでちょっと前に行きたいと思ったときに、サッとC-u C-fを打つのです。筆者は3回押すのも面倒なのでC-3 C-fやC-3 C-bも多用しています。

 C-uを何度も押すと4の累乗が指定されます。C-u C-u C-fで16文字進みますし、C-u C-u C-u C-fで64文字です。筆者は特定の文字のみの行を作成するのに、しばしばC-u C-u C-u =やC-u C-u C-u #を使っています。

 数やハイフンをたくさん入力するには「C-u 繰り返す数 C-u 文字」のように操作します。Ctrlを押しっぱなしでC-5 C-u 5で5が5つ入力できます。このようにC-uには数引数の終わりも意味します。

前置引数

 C-uは数を指定するのではなく、コマンドの挙動を変更する場合にも用いられます。たとえば、M-! はシェルコマンドを実行するコマンドですが、何も付けずに実行すると別ウィンドウに結果が表示されます。C-u M-!とした場合、実行結果がカーソル位置に貼り付けられます。

 亜種であるM-|はregionを標準入力としてシェルコマンドを実行します。C-u M-|とした場合、regionの内容をシェルコマンドの出力に置き換えます。たとえば各行を逆順にする場合、M-x reverse-regionというコマンドを知らなくて、tacシェルコマンドを知っているならば、C-u M-| tacと実行できます。行のソートもEmacsのコマンドよりもC-u M-|でsortシェルコマンドを使う方がより細かな指定ができます。

 M-!やM-|でのC-uは挙動の変更程度の違いですが、C-SPCの前にC-uを置くと、まるっきり別の挙動をします。カーソル位置をマークするのではなくて、過去のマークへジャンプします。

 これらのケースではC-uに数という意味はなくなり、ただ置かれたかどうかがチェックされます。その場合は数引数ではなく「前置引数」と言われます。数引数は前置引数の特別な場合ともいえます。

 中にはC-uが押された数によって挙動が変化するコマンドも存在します。

 このように、C-uを使うことで複数の機能を1つのコマンドにまとめられます。普段C-uを使わないコマンドに対してC-uを付けたときの挙動を追加したりすれば、限られたキーバインド資源を有効活用できます。それを行うパッケージがmykie.elで、筆者のサイトで紹介しています。http://emacs.rubikitch.com/mykie

終わりに

 いかがだったでしょうか?パッケージ全盛時代でつい外部パッケージに目が行ってしまいがちな今日この頃ですが、あえて標準コマンドに立ち帰ってみました。意外な発見がありましたでしょうか?

 筆者は「日刊Emacs」以外にもEmacs病院兼メルマガのサービスを運営しています。Emacsに関すること関しないこと、わかる範囲でなんでも御答えします。「こんなパッケージ知らない?」「挙動がおかしいからなんとかしてよ!」はもちろんのこと、自作elispプログラムの添削もします。集中力を上げるなどのライフハック・マインド系も得意としています。登録はこちら→http://rubikitch.com/juku/

本日もお読みいただき、ありがとうございました。参考になれば嬉しいです。