[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

28. カスタマイズ

本章では、Emacsの動作を(あまり大幅でなく)カスタマイズする方法に ついて説明します。 もっと大幅な変更を行いたい場合には The Emacs Lisp Reference Manualを参照してください。

カスタマイズは、Emacsの1つのセッションの中だけで効果を持ちます。 Emacsを終了するとカスタマイズの効果は失われますし、 同時にあるいはあとで別のEmacsを立ち上げた場合にも何の影響も及ぼしません。 あるEmacsのセッションがセッションを超えて影響するためには、 ファイルに書くしかありません。 特に、カスタマイズを『恒久化』したい場合には、 個人の`.emacs'ファイルや その他の関連するファイルに適切な内容を書き込んでおき、 セッションごとにカスタマイズが行われるようにします。 See section 初期化ファイル`~/.emacs'


28.1 マイナモード(minor mode)

マイナモードは、個別にオン/オフ可能な機能です。 たとえば、マイナモードである自動詰め込み(auto-fill)モードをオンにすると、 SPCで自動的に(単語の切れ目で)行分けします。 すべてのマイナモードは互いに独立ですし、 どのメジャーモードとも独立です。 ほとんどのマイナモードは、それがオンであることをモード行に表示します。 たとえば、モード行に`Fill'と表示されていれば、 自動詰め込み(auto-fill)モードがオンであることを意味します。

マイナモード名のうしろに-modeを付け加えると、 そのモードをオン/オフするコマンド関数の名前になります。 したがって、自動詰め込み(auto-fill)モードをオン/オフするコマンドは M-x auto-fill-modeということになります。 これらのコマンドは通常M-xを使って起動しますが、 どれかのキーにバインドすることもできます。 引数を指定しないと、これらのコマンドはモードがオフのときはオンに、 オンのときはオフに切り替えます。 これをトグルすると呼びます。 これに対し、正の引数を指定するとつねにモードをオンにしますし、 明示的に0の引数を指定するか、または負の引数を指定すると つねにモードをオフにします。

いくつかのマイナモードのオン/オフは、カレントバッファに対してのみ適用され、 他のバッファには影響しません。 つまり、あるバッファであるモードをオンにし、 別のバッファではそのモードをオフにできるわけです。 このような、バッファごとにオン/オフできるマイナモードとしては、 略語(abbrev)モード、自動詰め込み(auto-fill)モード、 自動保存(auto-save)モード、フォントロック(font-lock)モード、 ISOアクセント(iso-sccents)モード、アウトライン(outline)マイナモード、 上書き(overwrite)モード、バイナリ上書き(binary-overwrite)モードがあります。

略語(abbrev)モードでは、 略語を打ち込むと自動的に展開されるような略語を定義できます。 たとえば、`amd'を`abbrev mode'と展開させます。 詳しくは、See section 略語の利用法

自動詰め込み(auto-fill)モードでは、いちいち改行で行分けしなくても テキストを詰め込んで入力できます。 行が長くなりすぎないようにEmacsが適宜改行を挿入します。 See section テキストの詰め込み

自動保存(auto-save)モードはバッファの内容を定期的に保存することで、 システムクラッシュが起きたとき紛失してしまう作業の量を少なくします。 See section 自動保存、不慮の事故に対する備え

エンリッチ(enriched)モードは、整形済みテキストの編集を可能にします。 See section 整形済みテキストの編集

フライスペル(flyspell)モードは、 綴りに誤りのある単語を自動的に強調表示します。

フォントロック(font-lock)モードは、コメント、文字列、定義中の関数名などの プログラム中の決まった単位を自動的に強調表示します。 これには、複数のフォントを表示できるウィンドウシステムが必要です。 See section 複数タイプフェイスの利用

水平スクロール(hscroll)モードは、ポイントが画面内に留まるように、 自動的に水平スクロールを行います。 See section 水平スクロール

ISOアクセント(iso-accents)モードは、``'、`''、 `"'、 `^'、`/'、`~'とこれらに続くつぎの文字を結合して、 ISO Latin-1文字集合のアクセント付き文字を作り出します。 See section 1バイトヨーロッパ文字の使い方

アウトラインマイナ(outline-minor)モードは、メジャーモードである アウトライン(outline)モードと同じ機能を提供します。 しかし、マイナモードなので任意のメジャーモードと一緒に使えます。 See section アウトラインモード(outlineモード)

上書き(overwrite)モードでは、入力された図形文字は既存の文字を右に押しやる かわりにその文字を置き換えます。 たとえば、ポイントが`FOOBAR'の`B'のまえにあるときに Gを打つと`FOOGAR'となります。 通常のモードであれば`FOOGBAR'となります。 上書き(overwrite)モードでコマンドC-qを打つと、 そのつぎの文字が何であっても(数字であっても)その文字を挿入します。 つまり、上書き(overwrite)モードの中で文字を挿入するには この方法を使います。

バイナリ上書き(binary-overwrite)モードは上書き(overwrite)モードの変形で、 バイナリファイル編集用です。 このモードでは、改行やタブも他の文字と同じに扱われるので、 他の文字をこれらの文字で上書きすることも、 これらの文字を他の文字で上書きすることもできます。

以下で説明するマイナモードは、すべてのバッファに一斉に適用されます。 ただし、これらは変数の値に応じてオン/オフされますから、 その変数をバッファにローカルな変数にすれば、 バッファごとに独立にオン/オフすることも可能です。 See section ローカル変数

補完示唆(icomplete)モードは、ミニバッファで入力中に補完機能が働いているとき、 どのような補完候補があるかを表示します。 See section 補完のオプション

行番号(line-number)モードは、 ポイントのある行の行番号を絶えずモード行に表示します。 See section モード行

ミニバッファリサイズ(resize-minibuffer)モードは、 打ち込んだテキスト量に応じて自動的にミニバッファを広げます。 See section ミニバッファでの編集

スクロールバー(scroll-bar)モードは、各ウィンドウにスクロールバーを付けます (see section スクロールバー)。 メニューバー(menu-bar)モードは、各フレームにメニューバーを付けます (see section メニューバー)。 どちらのモードも、Xウィンドウシステムを使っているときは デフォルトでオンになっています。

暫定マーク(transient-mark)モードでは、 バッファの内容を変更するとマークは『不活性』になるので、 そのあとでリージョンを対象とするコマンドを使うとエラーになります。 つまり、リージョンを対象とするコマンドを使うまえに、 改めてマークを設定するか、不活性になったマークを『再度活性』にします。 暫定マーク(transient-mark)モードの利点は、 (今のところXウィンドウシステムを使っているときのみ) Emacsがリージョンを強調表示することです。 See section マークを設定する

ほとんどのマイナモードには、コマンド名と同じ名前の変数があり、 その変数でモードを直接制御しています。 つまり、その変数の値がnil以外ならモードはオンであり、 各マイナモードコマンドは変数の値を設定する動作をします。 たとえば、コマンドoutline-minor-modeは、 変数outline-minor-modeの値を設定する動作を行います。 つまり、この変数が、直接、上書き(overwrite)モードをオン/オフしているのです。 あるマイナモードがこのように動作するかどうかは、 C-h vを使ってその変数の説明文字列を参照してください。

これらのマイナモード変数は、Lispプログラムからモードを オン/オフするのに有用です。 また、ファイルのローカル変数リストとして指定するのも便利です。 ただし、ローカル変数リストで設定する場合には、よく考えてください。 というのは、ほとんどのマイナモードはユーザーの好みの問題であり、 同じファイルを編集する別のユーザーは好みが違うかもしれません。


28.2 変数

変数は値を持つLispシンボル(記号)です。 そのシンボルの名前のことを、変数名とも呼びます。 変数名はファイルに入れられるどのような文字でも含むことができますが、 習慣的には、変数名は英単語をハイフンでつなげたものです。 変数には、その変数がどのような値を持ち、 どのように使われるかを記述した説明文字列を持たせることができます。

Lispではどの変数にどのような値でも格納できますが、 Emacsの中ではほとんどの変数はどのような値を持つかが決まっています。 たとえば、ある変数はつねに文字列である、別の変数は数値であるといった具合です。 また、「これこれの機能はこの変数がnil以外のときにオンになる」 といういい方もします。 その場合は、その変数にnilが格納されているときはその機能はオフですが、 それ以外のどんな値が格納されているときでもその機能はオンになります。 ですが、ある機能をオンにするために使う値として 何か選ばなければなりませんから、tという値を使うのが習慣です。

Emacsは一般のLispプログラムと同様、 内部で情報を保持するために数多くの変数を使いますが、 ユーザーにとって特に興味深い変数というのは、 もっぱらカスタマイズ向けに用意された変数だといえます。 Emacsは(通常は)そのような変数の値を変更しません。 かわりに、ユーザーが値を設定すると、 その値に応じてさまざまなEmacsコマンドのふるまいを 変更したり制御したりできるのです。 これらの変数のことをユーザーオプションといいます。 ほとんどのユーザーオプションはこのマニュアルに記載してありますし、 変数索引(see section 変数索引)にも記載してあります。

ユーザーオプションであるような変数の例としてfill-columnがあります。 この変数は、詰め込みコマンド(see section テキストの詰め込み)が使う 右端の桁位置を(左端から何文字右かを表す数値として)保持します。


28.2.1 変数の設定と参照

C-h v var RET

変数varの値と説明文字列を表示する (describe-variable)。

M-x set-variable RET var RET value RET

変数varの値をvalueに変更する。

特定の変数の値を見るには、C-h vdescribe-variables)を使います。 このコマンドは、ミニバッファで補完機能付きで変数名を読み取ります。 変数の値と説明文字列の双方を表示します。 たとえば、

 
C-h v fill-column RET

とすると、つぎのように表示されます。

 
fill-column's value is 75

Documentation:
*Column beyond which automatic line-wrapping should happen.
Automatically becomes buffer-local when set in any fashion.

説明文の先頭にある*は、 この変数がユーザーオプションであることを示します。 C-h vは、ユーザーオプションに限らず任意の変数を扱えます。

ユーザーオプションを設定するいちばん簡単な方法はM-x set-variableを 使うことです。 このコマンドは、まずミニバッファで(補完機能付きで)変数名を読み取り、 つぎにミニバッファで変数に設定するLisp式を読み取ります。 たとえば、

 
M-x set-variable RET fill-column RET 75 RET

とすると、fill-columnに75を設定します。

M-x set-variableはユーザーオプションに対してだけ使えます。 これに対し、setqを使えばどの変数にでも値が設定できます。 たとえば、setqを使ってfill-columnに 設定するにはつぎのようにします。

 
(setq fill-column 75)

このような式を実行するには、`*scratch*'バッファにいき、 式を打ち込んでからC-jを打ちます。 See section lisp対話バッファ

変数を設定することは、特記していない限り、 他のカスタマイズ方法と同様に、現在のEmacsセッションだけに影響します。


28.2.2 簡便なカスタマイズ方法

変更したいユーザーオプション変数をみつけて値を変更する便利な方法は、 M-x customizeを使うことです。 このコマンドはカスタマイズバッファを作成し、 そのバッファ内では論理的な順序に並べたEmacsのユーザーオプションを 眺めてまわることができますし、さらに値を編集して設定できます。 また、カスタマイズバッファを使えば設定を恒久的なものとして 保存もできます。 (まだこの機能で扱えないユーザーオプションもあるが、 それらも扱えるように現在作業中。)


28.2.2.1 カスタマイズグループ

カスタマイズのために、ユーザーオプションをグループに まとめてみつけやすくしてあります。 グループはさらに大きなグループにまとめられていて、 いちばん大きな(すべてのグループを含む)グループは Emacsという名前です。

M-x customizeは、トップレベルのEmacsグループ およびその直下の(第2レベルの)グループを表示した カスタマイズバッファを作成します。 その表示はつぎのようになります。

 
/- Emacs group: ---------------------------------------------------\
      [State]: visible group members are all at standard settings.
   Customization of the One True Editor.
   See also [Manual].

Editing group: [Go to Group] 
Basic text editing facilities.

External group: [Go to Group] 
Interfacing to external utilities.

more second-level groups

\- Emacs group end ------------------------------------------------/

この表示の先頭部分は、 このバッファがEmacsグループの内容を表示していることを記しています。 残りのグループが表示されるのは、 それらがEmacsグループに含まれているからです。 ただし、それらは字下げや「-」なしで表示されていて、 表示にはそれらのグループの内容が含まれてはいないことを示しています。 各グループの表示には1行の説明文字列が付随しています。 また、Emacsグループについては`[State]'行が付随しています。

カスタマイズバッファ内のテキストのほとんどは変更できませんが、 一部分は編集可能フィールドになっていて、変更できます。 また、アクティブフィールドという、 その場所を起動するとなんらかの動作を行うような場所もあります。 アクティブフィールドを起動するには、 Mouse-1でそこをクリックするか、 またはそこにポイントを持っていってRETを打ちます。

たとえば、第2レベルグループ中の`[Go to Group]'と記された部分は アクティブフィールドです。 `[Go to Group]'のフィールドを起動すると、 そのグループとそのグループの内容を表示する 新しいカスタマイズバッファが作られ、 そのグループと中身が表示されます。 このフィールドは他のグループへのハイパーテキストリンクの一種です。

Emacsグループそのものはユーザーオプションを1つも含んでいませんが、 他のグループにはあります。 さまざまなグループを眺めてみると、 興味を持ってカスタマイズしてみようと思うような機能に属する オプションやフェイスをみつけることができるでしょう。

カスタマイズグループ群の構造を概観するには、 M-x customize-browseを使います。 このコマンドは、グループ名(とオプションやフェイス)と それらの構造だけを表示する特別なカスタマイズバッファを作ります。

このバッファ中では、グループの中身を見るには`[+]'のところを起動します。 グループの中身が見えるようになると、このボタンは`[-]'に変わります。 これを起動すると中身を(もとどおり)隠します。

各グループ、オプション、フェイスにはそれぞれ`[Group]'、 `[Option]'、`[Face]'と記されたアクティブフィールドがあります。 それらを起動すると、そのグループ/オプション/フェイスのみを表示した 通常のカスタマイズバッファが作成されます。 そのバッファで値を設定します。


28.2.2.2 オプションの変更

カスタマイズバッファでユーザーオプションがどのように見えるか、 例をあげましょう。

 
Kill Ring Max: [Hide] 30
   [State]: this option is unchanged from its standard setting.
Maximum length of kill ring before oldest elements are thrown away.

`[Hide]'に続くテキスト、つまり、`30'がオプションの現在の値を 示しています。 `[Hide]'ではなく`[Show]'と表示されていれば、 値は隠されています。 カスタマイズバッファでは、複数行にわたるような値は最初は隠されていて、 `[Show]'を起動すると表示されます。

オプション名に続く行はオプションのカスタマイズ状態を示しています。 上の例では、まだ変更していないと表示されています。 行頭の`[State]'のところがアクティブフィールドで、 ここをMouse-1RETで起動するとさまざまな操作を 示すメニューが表示されます。 これらの操作は変数をカスタマイズするうえでとても重要です。

`[State]'のつぎの行には、 そのオプションの説明文字列の先頭部分が表示されます。 1行に収まらない場合には、行末に`[More]'と表示されます。 これを起動すると説明文字列全体が表示されます。

`Kill Ring Max'に新しい値を設定するには、 ポイントを値の位置へ持っていって直接文字列を変更します。 たとえば、M-dで現在の値を削除してから、 設定する数値を打ち込めばよいのです。

文字列を変更し始めると、`[State]'行の表示が変わって、 値が編集されていることを示すようになります。

 
[State]: you have edited the value as text, but not set the option.

文字列を変更しただけでは、まだオプション変数の値は設定されません。 値を設定するには、`[State]'のところを起動して、 `Set for Current Session'を選択します。

値を設定すると、オプションの状態表示も対応して変わります。

 
[State]: you have set this option, but not saved it for future sessions.

正しくない値を設定してしまう心配はありません。 というのは、オプションの設定時には、値の正しさを検査して、 正しくない値は設定できないようになっています。

ディレクトリ名、ファイル名、コマンド名である値やフィールドを編集するとき、 および、その他何であれ補完が定義されているものを編集するときは、 M-TABwidget-complete)を打てば補完できます。

いくつかのオプションでは、正しい値としては決まった少数のものだけを使えます。 そのようなオプションは、テキストとしては編集できません。 かわりに`[Value Menu]'というアクティブフィールドが値のまえに現れます。 『オンかオフ』だけの真偽値を持つオプションでは、 アクティブフィールドは`[Toggle]'と表示されていて、 そこを起動するたびに値を反転できます。 `[Value Menu]'も`[Toggle]'もバッファを変更するだけです。 値が実際に設定されるのは`Set for Current Session'を起動したときです。

いくつかのオプションは、込み入った構造の値を持ちます。 たとえば、load-pathは値としてディレクトリのリストを持ちます。 これをカスタマイズバッファに表示すると、つぎのようになります。

 
Load Path:
[INS] [DEL] [Current dir?]: /usr/local/share/emacs/20.3/site-lisp
[INS] [DEL] [Current dir?]: /usr/local/share/emacs/site-lisp
[INS] [DEL] [Current dir?]: /usr/local/share/emacs/20.3/leim
[INS] [DEL] [Current dir?]: /usr/local/share/emacs/20.3/lisp
[INS] [DEL] [Current dir?]: /build/emacs/e20/lisp
[INS] [DEL] [Current dir?]: /build/emacs/e20/lisp/gnus
[INS]
   [State]: this item has been changed outside the customization buffer.
List of directories to search for files to load....

リスト中の各ディレクトリがそれぞれ別の行に表示され、 各行にはいくつかの編集可能/アクティブフィールドがあります。

どのディレクトリ名も直接編集できます。 リストからディレクトリを削除するには、 その行の`[DEL]'を起動します。 リストに新しいディレクトリを追加するには、 挿入したい箇所の`[INS]'を起動します。

`[Current dir?]'を起動すると、パスに特定のディレクトリを含めるのか、 または、nilを含めるのかを切り替えられます。 (探索パスにおけるnilは、 『カレントディレクトリを探せ』という意味。)

2つの特別なコマンド、TABS-TABは、 カスタマイズバッファ内での移動に役立ちます。 TABwidget-forward)はつぎの アクティブ/編集可能フィールドへ移動します。 S-TABwidget-backward)は、 1つまえのアクティブ/編集可能フィールドへ移動します。

編集可能フィールドでRETを打つと、 TABと同様につぎのフィールドへ進みます。 なぜそうなっているかというと、編集可能フィールドを 編集し終えると最後にRETを打つ人が多いからです。 編集可能フィールドに改行文字を入るには、 C-oC-q C-jと打ちます。

オプションを設定すると、その値は現在のEmacsセッションだけに有効です。 その値を保存すると、将来のセッションでも有効になります。 保存を行うと、個人の`~/.emacs'ファイルにコードが追加されて、 つぎにEmacsを起動したときにオプション変数の値を設定するようになります。 オプションを保存するには、`[State]'を起動して `Save for Future Sessions'を選びます。

オプションを標準値に戻したければ、`[State]'を起動して `Reset to Standard Settings'を選びます。 実際にはつぎの3種類のリセット操作があります。

` Reset'

なんらかの修正を行ったが、まだオプションを設定していなければ、 この操作により、カスタマイズバッファ上のテキストを オプションの現在値と一致させられる。

` Reset to Saved'

この操作では、オプションの値を最後に保存した値に戻し、 カスタマイズバッファ上のテキストもその値に合わせる。

` Reset to Standard Settings'

この操作では、オプションを標準値に設定し、 カスタマイズバッファ上のテキストもその値に合わせる。 さらに、以前にそのオプションについて保存した値もすべてもとに戻されるので、 将来のEmacsセッションでもすべて標準値が使われるようになる。

グループの`[State]'はそのグループに属するもののどれかが 編集された/設定された/保存されたことを示します。 `Set for Current Session'、`Save for Future Sessions'、 および各種の`Reset'をグループ全体に対して適用できます。 これらの操作はグループおよびそのサブグループに属するすべての オプションに対して適用されます。

カスタマイズバッファの先頭付近には、 いくつかのアクティブフィールドを含んだつぎのような行があります。

 
 [Set for Current Session] [Save for Future Sessions]
 [Reset] [Reset to Saved] [Reset to Standard]   [Bury Buffer]

`[Bury Buffer]'を起動すると、カスタマイズバッファを消します。 他のフィールドは、そのバッファに含まれている項目それぞれについてそれぞれ、 設定、保存、リセットを(それらの操作が適用可能なら)実行します。


28.2.2.3 フェイスのカスタマイズ

いくつかのカスタマイズグループは、 ユーザーオプションに加えてフェイスも含みます。 グループの内容を表示したとき、 オプションとフェイスの両方がカスタマイズバッファに現れます。 フェイスの見え方は、たとえばつぎのようになります。

 
Custom Changed Face: (sample)
   [State]: this face is unchanged from its standard setting.
Face used when the customize item has been changed.
Attributes: [ ] Bold: [toggle] off
            [X] Italic: [toggle] on
            [ ] Underline: [toggle] off
            [ ] Inverse-Video: [toggle] on
            [ ] Foreground: black (sample)
            [ ] Background: white (sample)
            [ ] Stipple:  

フェイスの各属性はそれぞれが1行を占めます。 属性のまえの`[x]'というフィールドは、 その属性がオンになっているかどうかを表示しています。 `X'が表示されていればオンになっています。 そのフィールドを起動することでオン/オフを反転できます。 属性がオンになっている場合は、 その属性の値をオプションと同様にして変更できす。

白黒ディスプレイでは、背景に設定可能な表示色は`black'、 `white'、`gray'、`gray1'、`gray3'のいずれかです。 Emacsは表示色のかわりにドットパターンで灰色の階調を表します。

フェイスを設定/保存/リセットするのは、オプションと同様にしてできます (see section オプションの変更)。

フェイスでは、ディスプレイの種別ごとに異なる見え方を指定できます。 たとえば、あるフェイスをカラーディスプレイでは赤で表示し、 白黒ディスプレイではかわりにボールド体で表示するようにできます。 あるフェイスに複数の見え方を指定するには、 `[State]'メニューを表示させて`Show Display Types'を選びます。

フェイスの属性を設定するもっと基本的な方法は、 M-x modify-faceを使うことです。 このコマンドは、まずフェイスの名前を聞いてきて、 続いて属性を1つずつ順に聞いてきます。 表示色やパターンの属性では、その属性の現在の値がデフォルトになっています。 これらを変更したくなければ、単に、RETを打てばよいのです。 属性を空にしたければ`none'と打ちます。


28.2.2.4 特定項目のカスタマイズ

グループ構造を1段ずつ降りていって目指すオプションを探すかわりに、 カスタマイズしたいオプション/フェイス/グループの名前を 直接に指定することもできます。

M-x customize-option RET option RET

指定したオプションoptionだけを含むカスタマイズバッファを開く。

M-x customize-face RET face RET

指定したフェイスfaceだけを含むカスタマイズバッファを開く。

M-x customize-group RET group RET

指定したグループgroupだけを含むカスタマイズバッファを開く。

M-x customize-apropos RET regexp RET

指定した正規表現regexpに一致するすべての オプション/フェイス/グループを含むカスタマイズバッファを開く。

M-x customize-changed-options RET version RET

Emacsのバージョンversion以降に意味が変更されたすべての オプション/フェイス/グループを含むカスタマイズバッファを開く。

M-x customize-saved

カスタマイズバッファで保存したすべてのオプションとフェイスを含む カスタマイズバッファを開く。

M-x customize-customized

カスタマイズしたが、まだ保存していないすべてのオプションとフェイスを含む カスタマイズバッファを開く。

名前のわかっているオプション変数をカスタマイズバッファで変更したい場合は、 コマンドM-x customize-optionで直接名前を指定します。 これにより、そのオプションだけを含むカスタマイズバッファが現れます。 編集/設定/保存はこれまで説明したとおりに行いますが、 設定の対象になるのは指定したオプションだけです。

同様にして、M-x customize-faceではフェイス名を指定して変更できます。

同様に、M-x customize-groupではグループ名を指定して カスタマイズバッファを開くことができます。 そのカスタマイズバッファには、指定したグループに直接含まれているオプション、 フェイス、他の(下位の)グループが現れます。 ただし、サブグループの内容は最初は隠されています。 それらを表示したい場合は、通常どおり`[Show]'を起動します。

M-x customize-aproposを使うと、 カスタマイズするものをもっと細かく制御できます。 このコマンドでは引数として正規表現を指定し、 それに一致するすべてのオプション/フェイス/グループを 含んだカスタマイズバッファが現れます。 空の正規表現を指定すると、すべてのオプション/フェイス/グループを 含むカスタマイズバッファができます (ただしすごく時間がかかる)。

Emacsの新版へ更新したときには、新しいオプション、 意味やデフォルト値が変更されたオプションをカスタマイズしたいはずです。 それには、M-x customize-changed-optionsを使い、 ミニバッファで以前の版のEmacsのバージョン番号を指定します。 すると、指定したバージョン以降に定義が変更された すべてのオプション(とグループ)を含んだカスタマイズバッファを作ります。

オプションを変更したあとでまちがったと気づいたときは、 変更したものを再検討するために2つのコマンドが使えます。 保存してしまったオプションについてはcustomize-savedを、 変更したけれどまだ保存していないオプションについては M-x customize-customizedを使います。


28.2.3 フック

フックとはある特定の状況で既存のプログラムから呼び出される 関数/関数群を格納しておく変数をいいます。 Emacsには、カスタマイズ用のフックが数多くあります。

Emacs中のほとんどのフックはノーマルフックです。 これらの変数は、引数なしで呼び出される関数のリストを保持します。 ほとんどのフックがノーマルフックなのは、それらを統一的に扱えるからです。 Emacsでは、`-hook'で終わる名前の変数はすべてノーマルフックです。

ほとんどのメジャーモードは初期設定の最終段階でフックを実行します。 モードが設定したローカル変数をフックで変更すればよいので、 モードのふるまいをユーザーがカスタマイズすることが容易になります。 しかし、フックはそれ以外の場面でも使われます。 たとえば、suspend-hookは、Emacsが休止する直前に実行されます (see section Emacsの終了)。

ノーマルフックにフック関数を追加するお勧めのやり方は、 add-hookを呼ぶことです。 フック関数としては任意のLisp関数を使えます。 たとえば、テキスト(text)モードやテキスト(text)モードを 基にしているモードにおいて、 自動的に自動詰め込み(auto-fill)モードをオンにするにはつぎのようにします

 
(add-hook 'text-mode-hook 'turn-on-auto-fill)

つぎの例は、Cコードの字下げをカスタマイズするのにフックを 使う方法を示します。 (誰でも字下げには独自の好みがある)。 ここでは、フック関数は名前のないラムダ式です。

 
(setq my-c-style
  '((c-comment-only-line-offset . 4)
    (c-cleanup-list . (scope-operator
		       empty-defun-braces
		       defun-close-semi))
    (c-offsets-alist . ((arglist-close . c-lineup-arglist)
			(substatement-open . 0)))))

(add-hook 'c-mode-common-hook
  (function (lambda ()
    (c-add-style "my-style" my-c-style t))))

どの順番で実行されても大丈夫なようにフック関数を設計するのが最良です。 実行順序に依存するのは、『事故を呼び込む』ようなものです。 しかし、順番は予測できます。 もっとも最近に追加したフック関数ほど先に実行されます。


28.2.4 ローカル変数

M-x make-local-variable RET var RET

変数varがカレントバッファでローカルに値を持つようにする。

M-x kill-local-variable RET var RET

変数varがカレントバッファではグローバル値を使うようにする。

M-x make-variable-buffer-local RET var RET

変数varを、値を設定したときにその時点のカレントバッファでローカル に値を持つようにする。

ほとんどの変数はEmacsバッファに対してローカルにできます。 つまり、その変数のバッファ中での値は他のバッファでの値とは 独立になります。 いくつかの変数はつねにすべてのバッファにおいてローカルです。 それ以外の変数はすべて、グローバルな値、 つまりその変数をローカルにしていないすべてのバッファにおいて 共有される値を持ちます。

M-x make-local-variableは変数名を受け取り、 その変数をカレントバッファにおいてローカルにします。 それ以降、このバッファ内でその変数を変更しても 他のバッファには影響しませんし、 その変数のグローバルな値を変更してもこのバッファ内での値には影響しません。

M-x make-variable-buffer-localは、変数名を受け取り、 値が設定されるとその変数が自動的にローカルになるようにします。 もっと正確にいえば、このように特別な印を変数に付けておくと、 通常の方法で変数に値を設定するときにはつねにまず make-local-variableが実行されるようになるのです。 このような変数をバッファごとの変数と呼びます。

メジャーモード(see section メジャーモード)では、 変数を設定するまえにつねにローカルにします。 このため、あるバッファでメジャーモードを変更しても 他のバッファには影響が及びません。 マイナモード(see section マイナモード(minor mode))も同様で、通常、 マイナモードごとにオン/オフを制御する変数があり、 その変数がnil以外のときにそのマイナモードはオンになります。 ほとんどのマイナモードでは、その制御用変数はバッファごとの変数です。

Emacsには、つねにバッファごとの変数であるような変数が数多くあります。 abbrev-modeauto-fill-functioncase-fold-searchcomment-columnctl-arrowfill-columnfill-prefixindent-tabs-modeleft-marginmode-line-formatoverwrite-modeselective-display-ellipsesselective-displaytab-widthtruncate-linesがそのような変数です。 これ以外にもつねに各バッファでローカルな変数はありますが、 それらは内部作業用の変数です。

いくつかの変数はディスプレイに対してローカルになっているため、 バッファに対してローカルにはできません (see section 複数ディスプレイ)。 これらの変数をバッファにローカルにしようとすると、 エラーメッセージが表示されます。

M-x kill-local-variableは、変数名を受け取り、 その変数をカレントバッファに対してローカルでなくします。 それ以降そのバッファでは、その変数のグローバルな値が使われます。 メジャーモードを設定すると、つねにローカルと印が付いた少数の特別な 変数を除いて、そのバッファにローカルなすべての変数をローカルでなくします。

ある変数がカレントバッファでローカルか否かに係わらず その変数のグローバルな値を設定したければ、setq-defaultを使います。 これはsetqのように使われますが、 (たとえローカルな値があったとしても)つねにグローバルな値のほうを設定します。 その変数がローカルな値を持っている場合、 新たに設定したグローバルな値は別のバッファに切り替えるまでは参照できません。 以下に例をあげます。

 
(setq-default fill-column 75)

setq-defaultは、 make-variable-buffer-localで印を付けた変数の グローバルな値を設定する唯一の方法です。

Lispプログラム中では、変数のデフォルト値を参照するためには default-valueを使えます。 この関数はシンボルを引数とし、その変数のデフォルト値を返します。 引数は評価されるので、普通は引数をクォートします。 たとえば、fill-columnのデフォルト値を取得するにはつぎのようにします。

 
(default-value 'fill-column)

28.2.5 ファイルにローカルな変数

Emacsでファイルを編集する際に、そのファイルに対応したローカル変数と その値を指定することができます。 Emacsはファイルを訪問すると、ローカル変数指定の有無を検査し、 あれば指定された変数を自動的にバッファにローカルにして、 その値をファイルで指定された値に設定します。

ローカル変数とその値を設定するには2つの方法があります。 1つはファイルの先頭行に書くことで、 もう1つはローカル変数リストを書くことです。 先頭行に書く場合は、たとえばつぎのようにします。

 
-*- mode: modename; var: value; … -*-

変数とその値を「:」で区切った対を「;」で区切って並べ、 いくつでも指定できます。 mode: modename;はメジャーモードを指定するもので、 行の最初にある必要があります。 valueは評価されずに書かれているとおりのまま使われます。 以下は、Lispモードで2つの変数に数値を設定する例です。

 
;; -*-mode: Lisp; fill-column: 75; comment-column: 50; -*-

この方法では、ファイルのコーディングシステムも指定できます。 つまり、codingという名前の『変数』に値を指定すればよいのです。 『値』は、Emacsが認識できるコーディングシステム名である必要があります。 See section コーディングシステム

一方、ローカル変数リストはファイルの末尾(最後のページ)に置きます。 (最後のページにはローカル変数リストだけを置くというのを勧めます。) ローカル変数リストは`Local Variables:'という内容を含む行で始まり、 `End:'という内容を含む行で終ります。 これらの行のあいだに、1つの変数につき1行ずつ、 `variable: value'という形で変数の名前と値を指定します。 valueは評価されずにファイルに書かれたとおりにそのまま使われます。 ファイルにローカル変数リストと`-*-'の行が両方含まれていた場合には、 Emacsはまず`-*-'の行をすべて処理してから、 続いてローカル変数リストの内容をすべて処理します。

以下にローカル変数リストの例を示します:

 
;;; Local Variables: ***
;;; mode:lisp ***
;;; comment-column:0 ***
;;; comment-start: ";;; "  ***
;;; comment-end:"***" ***
;;; End: ***

上の例では、各行は`;;;'で始まり`***'で終っています。 Emacsはこれらの接頭辞と接尾辞をリストの最初の内容に基づいて認識します。 つまり、特別な文字列`Local Variables:'の前後の文字列を、 それぞれ、接頭辞、接尾辞とみなし、 それ以降の行についてはこの接頭辞と接尾辞を無視します。

接頭辞と接尾辞を使う主な理由は、 ローカル変数リストをコメントの中に入れることで、 そのファイルを読み込む他のプログラムを困惑させないようにすることです。 上の例では、コメントが`;;;'で始まり`***'で終るような言語を 想定しています。 変数comment-startcomment-endのローカルな値で、 このような変な構文に対処するようにEmacsをカスタマイズするのです。 必要ないのであれば、接頭辞(と接尾辞)は使わないでください。

ローカル変数リストにおいては、2つの変数名が特別な意味を持ちます。 変数modeに対する値は、実際にはメジャーモードを設定します。 変数evalに対する値は、式として評価されますが、 その結果は捨てられます。 modeevalは本当の変数ではなく、他の状況で これらの名前の変数に値を設定してもなんら特別な意味を持ちません。 メジャーモードを設定するためにmodeを指定する場合は、 ローカル変数リストの先頭に書く必要があります。

仮想的な『変数』modeは、メジャーモードだけでなくマイナモードを 設定するのにも使えます。 実は、この指定は2回以上使うことができて、 最初はメジャーモードを設定し、 それ以降は(それぞれ)マイナモードを設定します。 しかし、マイナモードはユーザーの好みに応じて選ぶものですから、 普通はファイルでマイナモードを指定するべきではないでしょう。

たとえば、ローカル変数リストで自動詰め込み(auto-fill)モードをオンにしたいと 思うかもしれませんが、それはまちがいです。 自動詰め込みにするかどうかは、個人の好みの問題であり、 ファイルの中身によって決まるものではないからです。 ある種別のファイルでいつも自動詰め込みにしたければ、 個人の`.emacs'ファイルで(状況に応じて)自動詰め込み(auto-fill)モードを オンにするようなメジャーモードのフックを設定してください (see section 初期化ファイル`~/.emacs')。 ローカル変数リストで他人に好みを押し付けてはいけません。

ローカル変数リストは、ファイルの末尾から3000文字以内にある必要があり、 ファイルがページに分かれている場合には最後のページにある必要があります。 これらが守られていないと、 Emacsはローカル変数リストがあることを認識しません。 これらの規則の目的は、最後ではないページに偶然 `Local Variables:'があってもEmacsが誤認しないようにすることと、 全体が1ページでローカル変数リストを持たない長いファイルを訪問するときでも ファイル全体を探さなくてもすむようにするためです。

バッファのローカル変数やメジャーモードを、 ローカル変数リストがあるときにはそれによる指定も含めて、 ファイル名とファイルの内容に基づいたものにリセットしたければ、 normal-modeコマンドを使ってください。 See section メジャーモードの選択方式

変数enable-local-variablesは、 ファイル中のローカル変数指定を処理するか否かを制御します。 つまり、ローカル変数指定を無視するようにもできます。 デフォルトはtで、ファイル中のローカル変数指定を処理します。 値をnilにすると、ファイル中のローカル変数指定を無視します。 これら以外の値の場合は、ファイル中にローカル変数指定があると、 その内容を表示して処理するかどうか問い合わせます。

仮想的な『変数』evalといくつかの(実在する)変数に対する指定は、 ある種の危険性をもたらします。 他人のファイルを訪問したとき、そこに書かれているローカル変数指定に よってあなたが使っているEmacsのふるまいがどのようにでも変更できるからです。 このため、オプションenable-local-evalにより、 変数eval、さらに、`-hook'、`-hooks'、`-function'、 `-functions'という名前で終る変数、および、他のいくつかの変数に 対するローカル変数指定を処理するかどうか制御できるようになっています。 enable-local-variablesと同じように指定できる値は3種類あって、 tnil、これら以外です。 デフォルトはmaybeで、これはtでもnilでもありませんから、 Emacsはこれらのローカル変数指定があるときは確認を求めてきます。


28.3 キーボードマクロ

キーボードマクロは、 ユーザーが一連のキー操作に基づいて定義したコマンドです。 たとえば、C-n C-dという打鍵を40回繰り返す必要があるとわかったら、 C-n C-dを実行するキーボードマクロを定義し、 それを40回繰り返す指定をして呼び出すと迅速に作業できます。

C-x (

キーボードマクロの定義を開始する (start-kbd-macro)。

C-x )

キーボードマクロの定義を終了する (end-kbd-macro)。

C-x e

もっとも最近のキーボードマクロを実行する (call-last-kbd-macro)。

C-u C-x (

もっとも最近のキーボードマクロを再実行したうえで、 その定義にキーを追加する。

C-x q

キーボードマクロの実行中にこの場所に到達したら、 実行の確認を求める (kbd-macro-query)。

M-x name-last-kbd-macro

もっとも最近に定義したキーボードマクロに(現在のEmacsセッションだけで有効な) コマンド名を与える。

M-x insert-kbd-macro

キーボードマクロの定義をLispコードとしてバッファに挿入する。

C-x C-k

まえに定義したキーボードマクロを編集する (edit-kbd-macro)。

M-x apply-macro-to-region-lines

リージョン内の各行に対して、最後に定義したキーボードマクロを実行する。

キーボードマクロは、それがLispではなくEmacsのコマンド言語で 記述されているという点で、通常のEmacsコマンドとは違っています。 このため、キーボードマクロは初心者でも簡単に作れ、 間に合わせとして定義するのにも向いています。 しかし、Emacsのコマンド言語は、 プログラム言語として知的で汎用的な動作を記述できるほど強力ではありません。 そういう場合には、Lispを使ってください。

キーボードマクロは、定義内容のコマンド列を実際に実行しながら定義できます。 いいかえれば、キーボードマクロを定義しているときに、 その定義の第1回目の実行が行われることになります。 ですから、コマンドがどのように動作するかを目で見ながら確認でき、 頭の中だけで動作を考えるよりも楽に定義できます。 コマンド列の最後まできてキーボードマクロを定義し終ると、 第1回目の実行も終ったことになります。 そのあとは、マクロを呼び出すことで何回でもそのコマンド列全体を実行できます。


28.3.1 基本的な使い方

キーボードマクロの定義を開始するには、C-x (コマンド (start-kbd-macro)を打ってください。 それ以降打鍵するものは通常どおり実行されますが、 それと同時にキーボードマクロの定義として取り込まれます。 モード行にもそのことを表す`Def'という表示が現れます。 定義の終りまできたら、C-x )end-kbd-macro)を打ち込むと キーボードマクロの定義が完了します (C-x )はマクロの内容には含まれません!)。 たとえば、

 
C-x ( M-f foo C-x )

のように打鍵すると、 1単語分ポイントを前進させ文字列`foo'をバッファに挿入する、 キーボードマクロを定義できます。

定義し終えたキーボードマクロは、 コマンドC-x ecall-last-kbd-macro)で再実行できますし、 数引数として反復回数を指定することで多数回実行することもできます。 C-x )にも引数として反復回数を指定でき、 その場合は定義完了とともにただちに指定した回数だけ キーボードマクロを実行しますが、 定義しているとき(実行しているので)を1回目の実行として数えます。 ですから、C-u 4 C-x )と打つと、キーボードマクロをただちに3回実行します。 C-x eC-x )に反復回数0を指定すると、 キーボードマクロを無限回、つまり、エラーが発生するか、 C-g(MS-DOSではC-BREAK)が打鍵されるまで、 繰り返し実行します。

テキスト上の規則的にとびとびの位置に対して操作を行いたい場合には、 キーボードマクロを定義するときに、つぎに適用したい位置までポイントを 移動するコマンドを含めておきます。 たとえば、各行について変更を行いたければ、 ポイントを行頭に置いてからキーボードマクロを定義し始め、 最後にポイントをつぎの行の行頭に置いたところで定義を終えます。 キーボードマクロを繰り返し実行すると、 次々と連続する行に対して操作を実行できます。

キーボードマクロの定義を完了してしまったあとでも、 C-u C-x (を打ち込めば、その定義の末尾に内容を追加できます。 このコマンドは、C-x (に続いて現在のキーボードマクロの 定義内容全体を打鍵したのと同じ効果を持ちます。 その結果、定義されたとおりにマクロを再実行します。

キーボードマクロの中で、通常のキーと同様にファンクションキーを 使うこともできます。 マウスイベントを使うことさえできますが、その場合は注意してください。 キーボードマクロはマウスイベントを再現しますが、 マウス位置としては最初にキーボードマクロを定義したときの位置が そのまま使われます。 その結果は予想し難いものになります。 (現在のマウス位置を使っても、結果はさらに予想し難いものになる。)

キーボードマクロの中で必ずうまくいくとは限らないことの1つに、 C-M-cexit-recursive-edit)コマンドがあります。 このコマンドがマクロの中で開始させた再帰編集を終らせる場合には、 期待どおりに動くでしょう。 しかし、このコマンドがキーボードマクロを起動するまえに入っていた再帰編集を 終らせるとすると、 その終了処理の過程でキーボードマクロの実行も終らせてしまいます。

定義済みのキーボードマクロを編集するには、 C-x C-kedit-kbd-macro)と打ちます。 このコマンドに続けてマクロを起動する打鍵、つまり、 C-x eM-x nameなどのキー列を入れます。 すると、キー列に対応するキーボードマクロの内容が整形されて 特別な編集用メジャーモードのバッファに入ります。 そのバッファ中でC-h mと打つと編集方法が表示されます。 編集し終えたらC-c C-cと打ちます。

コマンドM-x apply-macro-to-region-linesは最後に定義された キーボードマクロを現在のリージョンの各行に対して実行します。 つまり、各行について、行頭にポイントを置いてからキーボードマクロを実行します。


28.3.2 キーボードマクロの命名と保存

新たにつぎのキーボードマクロを定義したあとでも 現在のキーボードマクロを使いたいなら、 M-x name-last-kbd-macroでキーボードマクロに名前を 付けておく必要があります。 このコマンドは、ミニバッファで名前を読み取り、 その名前でキーボードマクロを実行できるように定義します。 マクロ名はLispシンボルであり、このように定義されているので、 M-xで呼び出したりglobal-set-key (see section キーマップ)でキーに対応付けたりできる有効なコマンド名になります。 その名前にキーボードマクロ以外のものがすでに定義されていると、 エラーメッセージが表示され何の変更も起こりません。

キーボードマクロにコマンド名を付けると、その定義をファイルに保存できます。 そうすると、別の編集セッションで使えるようになります。 まず、定義を保存したいファイルを訪問してから、 つぎのコマンドを使ってください。

 
M-x insert-kbd-macro RET macroname RET

このコマンドは、実行するとそのキーボードマクロと 同じ動作を行うLispコードをバッファに挿入します。 (insert-kbd-macroがLispコードの生成を代行するので、 Lispコードを理解する必要はない。) そうしたら、このファイルを保存します。 load-file(see section Emacs用のLispコードのライブラリ)でファイルをロードできます。 保存するファイルとして`~/.emacs'(see section 初期化ファイル`~/.emacs')を使えば、 Emacsを起動するとつねにそのマクロが定義されます。

insert-kbd-macroに数引数を指定すると、 さらに(もしあれば)キーボードマクロに割り当てたキーを 記録するLispコードが追加されるので、 ファイルをロードしたときに同じキーがマクロに割り当てられます。


28.3.3 変化のあるマクロの実行

C-x qkbd-macro-query)を使うと、 query-replaceと同様に変更するかどうか尋ねてくる キーボードマクロを作れます。 キーボードマクロを定義しているときに、問い合わせが起きてほしい箇所で C-x qを打ちます。 マクロの定義中はC-x qは何の動作もしませんが、 あとでマクロを実行させたときにはC-x qの箇所で処理を 続けるかどうか尋ねてくるようになります。

C-x qの問い合わせに対する有効な応答は、SPC(またはy)、 DEL(またはn)、RET(またはq)、C-lC-rです。 これらの意味はquery-replaceと同じですが、 query-replaceのすべての応答が意味を持つとは限りません。

SPCは続行、DELはこの回の反復の残りを飛ばしてただちにつぎの 反復に進むという意味になります。 RETではこの回の反復の残りも以後の反復もすべて取り消します。 C-lは画面を再描画し、再度どうするかを問い合わせてきます。

C-rで再帰編集レベルに入るので、そこでキーボードマクロにはない 編集を行えます。 C-M-cで再帰編集から抜けると、再度どうするかを聞いてきます。 ここでSPCを打つと、キーボードマクロの残りの部分が実行されます。 キーボードマクロの残りの部分が望みどおりの動作をする状態に ポイントやテキストを保っておくのは、ユーザーの責任です。

C-u C-x q、つまり、数引数を指定したC-x qは、 まったく違った動作をします。 キーボードマクロの定義中でも実行中でも、 キーボードから入力を受け付ける再帰編集に入ります。 定義中の場合、再帰編集の中で行った操作はマクロの一部にはなりません。 実行中の場合、再帰編集の中で各反復ごとに個別の編集を行う機会が得られます。 See section 再帰編集レベル


28.4 キーバインディングのカスタマイズ

本節では、コマンドをキーに対応付けるキーバインディングと、 キーバインディングを記録するキーマップについて説明します。 また、キーバインディングをカスタマイズする方法についても説明します。

コマンドとは、対話利用向けに定義されたLisp関数で あることを思い出してください。 コマンドには、他のLisp関数と同様、通常、英小文字とハイフンから成る 関数名前が付いています。


28.4.1 キーマップ

キー列とコマンド関数との対応はキーマップと呼ばれる データ構造に保持されています。 Emacsには数多くのキーマップがあり、それぞれが特定の場面で使われます。

キー列(または単にキー)とは、 ひとまとまりの意味を持つ入力イベントの並びをいいます。 入力イベントは、文字、ファンクションキー、マウスボタン、 つまり、端末から計算機に送ることができるすべての入力から成ります。 キー列の意味付けは、どのコマンドを実行するかを表す バインディングによって決まります。 キーマップの役割は、これらのバインディングを保持することです。

グローバルキーマップはもっとも重要なキーマップですが、 それはグローバルキーマップがつねに有効だからです。 グローバルキーマップは基本(fundamental)モードのキーを定義します。 つまり、そこに含まれる定義の大部分は、ほとんどまたはすべての メジャーモードに共通のものです。 各メジャー/マイナモードは、グローバルキーマップの定義の一部を 置き換えるような独自のキーマップを持つことができます。

たとえば、gのような自己挿入文字を打つとその文字がバッファに 挿入されるのは、グローバルキーマップでこれらのキーが self-insert-commandに対応付けられているからです。 また、C-aのような標準の編集コマンドも、 その意味付けはグローバルキーマップに書かれています。 M-x global-set-keyのようなバインディングを変更するコマンド群は、 グローバルキーマップの適切な箇所に新しいバインディングを書き込みます。

メタ文字はやや違った動作になります。 Emacsでは、メタ文字はESCで始まる文字列に変換されます。 ですから、M-aという入力はつねにEmacsの中では ESC aに置き換えられて処理されます。 つまり、メタ文字は単一の入力イベントですが、 キーバインディングの観点では2つのイベントとして扱われます。 こうなっている理由は歴史的なもので、将来は変わる可能性もあります。

最近のほとんどのキーボードには、 文字キーの他にファンクションキーがあります。 ファンクションキーは文字キーと同様に入力イベントを送出し、 キーマップはそれに対応するバインディングを保持することができます。

多くの端末では、ファンクションキーを打つとコンピュータには 一連の文字列が送られます。 具体的にどのファンクションキーが どんな文字列を送るかは端末によってまちまちです。 (多くの場合、文字列はESC [で始まる。) Emacsが使用中の端末種別を正しく認識していれば、 キー列(の先頭でだけでなく)に現れるファンクションキーに対応した 文字列を正しく判別できます。 ですから、多くの場合、ファンクションキーの打鍵も 1つの入力イベントとして直接Emacsに送られているとみなして、 文字列としての表現形式は無視してかまいません。

マウスボタンも入力イベントを発生させます。 これらのイベントには、追加データ、つまり、 ボタンを押したり放したりしたときのウィンドウとその中での位置、時刻 が付属しています。 ただし、キーバインディングに関しては、 どのボタンが使われたかだけが問題となります。 残りの情報は、コマンドがこれらの情報を参照する場合だけ意味を持ちます。 (通常、マウスから起動できるコマンドは、これらの情報を参照する。)

キーマップは1つのイベントに対する定義のみを保持します。 複数キーの列から成る複数のイベントの解釈には、 キーマップの連鎖が使われます。 最初のキーマップが最初のイベントの定義を保持し、 その定義がつぎのキーマップになっていて、 2番目のイベントの定義を保持し、というようになっています。

キー列にはファンクションキーと文字キーとが混ざっていてもかまいません。 たとえば、C-x SELECTというのも許されます。 SELECTをプレフィックスキーとして定義しておけば、 SELECT C-nというのも許されます。 マウスイベントとキーボードイベントを混ぜることさえ可能ですが、 そうすると打ち込むのが面倒ですからお勧めしません。

ユーザーはどんなキー列でも再定義して利用できますが、 C-cに続けて1文字というキー列だけを使うのが最善です。 このキー列は『ユーザー定義のために予約』されていて、 正しく設計されたEmacsの各種拡張とは衝突しないようになっているからです。 F5からF9までのファンクションキーも ユーザー定義のために予約してあります。 これ以外のキー列を再定義すると、 同じキーを再定義する拡張やメジャーモードによって あなたの定義が上書きされてしまう可能性があります。


28.4.2 プレフィックスキーマップ

C-xESCのようなプレフィックスキーは それぞれ専用のキーマップを持っていて、 そこにはそのプレフィックスキーに続くイベントの定義が保持されています。

プレフィックスキーの定義は、通常、それに続くイベントの定義を検索するための キーマップです。 あるいは、プレフィックスキーの定義がLispシンボルであって、 その関数の定義がキーマップというのもあります。 どちらでも効果は同じですが、 後者では、プレフィックスキーにコマンド名を与えてその用途を示すことができます。 このため、C-xにバインドされているのは シンボルCtl-X-Prefixであり、 その関数定義はC-xコマンド群に対応するキーマップです。 C-cC-xC-hESCは グローバルマップでプレフィックスキーとして定義されていますから、 これらはつねにプレフィックスキーとして使用できます。

通常のプレフィックスキーに加えて、 メニューバーを表す『仮想的なプレフィックスキー』があります。 メニューバーのキーバインディングに関する特別な点については (elisp)Menu Bar section `メニューバー' in Emacs Lisp リファレンスマニュアルを参照してください。 ポップアップメニューを表示させるマウスボタンイベントもまた、 プレフィックスキーです。 こちらの詳細については (elisp)Menu Keymaps section `メニューキーマップ' in Emacs Lisp リファレンスマニュアルを参照してください。

決まった変数に格納されているプレフィックスキーマップもあります。


28.4.3 ローカルキーマップ

これまではグローバルキーマップの諸側面について説明しました。 メジャーモード固有のキーバインディングを ローカルキーマップに定義することで、 各メジャーモードはEmacsの動作を変更します。 たとえば、Cモードでは、 TABをCのコードの現在行を字下げする機能に差し替えます。 バッファ内の一部のテキストで、 そのバッファのメジャーモードのかわりとなる固有のキーマップを 指定することもできます。

マイナモードもローカルキーマップを持てます。 その場合、マイナモードが生きているときには、 そのキーマップがメジャーモードのローカルキーマップ やグローバルキーマップに優先します。

Lispモードおよびその他のいくつかのメジャーモードの ローカルキーマップは、そのモードを使っていないときでもつねに存在します。 これらのキーマップは、lisp-mode-mapなどの変数に格納されています。 さほど頻繁に使われないメジャーモードの場合は、 そのモードがセッションの中で初めて起動されたときに ローカルキーマップが作られます。 これは、メモリを節約するためです。 このようなモードのキーマップを変更したい場合には、 当該メジャーモードのモードフックを使う必要があります(以下を参照)。

すべてのマイナモードのキーマップは、あらかじめ作られています。 マイナモードのキーマップ作成を そのマイナモードが最初に起動されるまで遅延させる方法はありません。

ローカルキーマップでは、その中のあるキーの定義をプレフィックスキーマップと することで、そのキーをローカルなプレフィックスキーとして再定義できます。 そのキーがグローバルにもプレフィックスキーであると定義されているなら、 ローカルキーマップとグローバルキーマップの内容は実質的に統合され、 プレフィックスキーに続くイベントは両方のキーマップで検索されます。 したがって、あるモードのローカルキーマップがC-cを 別のキーマップとして定義し、 そのキーマップではC-zをコマンドとして定義すると、 これらによってC-c C-zのローカルな意味が与えられます。 しかし、これはC-cで始まる他のキー列には影響しません。 あるキー列が独自のローカルなバインディングを持たなければ、 グローバルなバインディングが意味を持つからです。

いいかえれば、Emacsが複数イベントから成るキー列を扱う方法は、 複数のキーマップから1つずつ、キー列全体に一致するバインディングを探すのです。 まず、マイナモードが生きていればそのキーマップを検索し、 つぎにメジャーモードのキーマップを検索し、 最後にグローバルキーマップを検索します。 これは厳密にはキーの検索動作とは違いますが、 通常の状況でどうなるか理解するには十分です。

メジャーモードのローカルバインディングを変更するには、 そのモードのローカルキーマップを変更する必要があります。 通常、そのためにはそのモードが最初に使われるまで待つ必要があります。 というのは、ほどんどのメジャーモードは 使われるまでキーマップを作成しないからです。 ですから、個人の`~/.emacs'ファイルで メジャーモードのバインディングを変更したければ、 そのモードのモードフックを使ってそのモードが最初に使われるまで (変更を)遅らせる必要があります。

たとえば、texinfoモードを選択するtexinfo-modeコマンドは フックtexinfo-mode-hookを実行します。 このフックを使ってC-c nC-c pに対する (有益ではないですが)ローカルバインディングを texinfoモードに追加するには、つぎのようにします。

 
(add-hook 'texinfo-mode-hook
          '(lambda ()
             (define-key texinfo-mode-map
                         "\C-cp"
                         'backward-paragraph)
             (define-key texinfo-mode-map
                         "\C-cn"
                         'forward-paragraph)
             ))

See section フック


28.4.4 ミニバッファのキーマップ

ミニバッファも一群の専用ローカルキーマップを持っています。 それらには各種の補完や脱出コマンドが定義されています。


28.4.5 キーバインディングの対話的な変更

Emacsのキーを再定義するには、キーマップの対応する項目を 変更すればよいのです。 グローバルキーマップを変更すると、その変更は (同じキーに対して独自のローカルな定義をしているメジャーモードを除く) すべてのメジャーモードに影響します。 あるいは、カレントバッファのローカルマップを変更すると、 同じメジャーモードを使っているすべてバッファに影響が及びます。

M-x global-set-key RET key cmd RET

cmdを実行するようにkeyをグローバルに定義する。

M-x local-set-key RET key cmd RET

cmdを実行するようにkeyを(現在のメジャーモードで) ローカルに定義する。

M-x global-unset-key RET key

keyをグローバルマップで未定義にする。

M-x local-unset-key RET key

keyを(現在のメジャーモードで)ローカルに未定義にする。

たとえば、Emacsを休止してログインシェルでコマンドを実行するかわりに、 Emacsバッファ内のサブシェルでコマンドを実行したいとします。 通常、(Xウィンドウシステムを使っていない場合)C-zは 関数suspend-emacsにバインドされていますが、 つぎのようにこのキーをshellにバインドすれば、 このキーでEmacs内の対話的サブシェルを起動するように変更できます。

 
M-x global-set-key RET C-z shell RET

global-set-keyはキー列に続けてコマンド名を読み取ります。 使いたいキーを打鍵すると、どのキーをバインドしたいのかを 確認するつぎのようなメッセージが表示されます。

 
Set key C-z to command: 

同じ手順で、ファンクションキーやマウスイベントを再定義できます。 バインドすべきキーを指定するときに、 キーのかわりにファンクションキーを押したりマウスボタンをクリックしてください。

複数イベントから成るキーも単一イベントのキーと同様にして再定義できます。 Emacsは再定義すべきキー列が完成するまで(つまりプレフィックスキーではない キーが出てくるまで)イベントを読み続けます。 たとえば、keyとしてC-fを打てばそれで終りですから、 ミニバッファはただちにcmdを読む状態になります。 一方、C-xを打つとさらにその先のキーを読みます。 そこで4を打つと、さらにその先のキーが読まれる、というようになります。 たとえば、

 
M-x global-set-key RET C-x 4 $ spell-other-window RET

では、C-x 4 $を(実在しない)コマンドspell-other-windowに バインドします。

C-cに続けて英字という2文字のキー列は、 ユーザーのカスタマイズ用に予約されています。 Lispプログラムはこれらのキー列を定義しないことになっていますから、 これらのキー列のバインディングはどのメジャーモードでも使え、 いかなる機能とも干渉しないはずです。

global-unset-keyでキーのグローバルな定義を取り除けます。 そのキーは未定義になります。 未定義のキーを打つと、Emacsはベルを鳴らします。 同様に、local-unset-keyは現在のメジャーモードでキーを 未定義にしますから、グローバルな定義(あるいはグローバルでの未定義状態)が 現在のメジャーモードでふたたび有効になります。

キーを再定義(または未定義に)して、あとでもとに戻したいと思った場合、 キーを未定義にしてももとには戻りません。 キーの標準定義を設定し直す必要があります。 キーの標準定義を調べるには、基本(fundamental)モードのバッファに いってC-h cを使います。 本書のキーの説明にもコマンド名を掲載してあります。

まちがって、あるコマンドを実行することを防ぎたければ、 キーを未定義にするのでなく、コマンドを使用禁止にするのがよいでしょう。 必要になったときに使用禁止コマンドを起動するのは造作もありません。


28.4.6 初期化ファイルでのキーの変更

いつでもあるキーバインディングを設定しておきたければ、 その指定を個人の`.emacs'ファイルにLispのコードとして書いておきます。

これを行うもっとも簡単な方法は、 ASCII文字とメタ修飾付きのASCII文字に対してのみ使えます。 たとえば、C-zshellにバインドするにはつぎのようにします。

 
(global-set-key "\C-z" 'shell)

この例では1つの文字C-zから成る文字列定数を指定しています。 コマンド名shellのまえのクォート「'」は、 shellを変数ではなく定数シンボルとして扱う印です。 クォートがないと、Emacsはshellを変数として その値をただちに評価しようとします。 すると、望んでいることではなく、エラーになります。

つぎは、2文字のキー列をバインドする例です。

 
(global-set-key "\C-xl" 'make-symbolic-link)

キー列にファンクションキーやマウスボタンイベントが含まれていたり、 C-=H-aなどの非ASCII文字が含まれているなら、 文字列よりもっと一般的な指定方法であるベクタを使った指定を使う必要があります。

Emacs Lispでのベクタの書き方は、その要素を中括弧(`[…]')で 囲みます。 要素は空白で区切ります。 要素がシンボルであれば、単にその名前だけを書けばよく、 区切り記号などは不要です。 要素が文字であれば、Lispの文字定数として、 つまり`?'に続けてその文字が文字列中に現れるのと同じ書き方で、 書いてください。

ベクタを使ってC-=(ASCIIの範囲にないコントロール文字)、 H-a(ハイパー文字。ASCIIにはハイパー文字は含まれない)、 F7(ファンクションキー)、 C-Mouse-1(キーボード修飾付きのマウスボタン)を バインドする例を示します。

 
(global-set-key [?\C-=] 'make-symbolic-link)
(global-set-key [?\H-a] 'make-symbolic-link)
(global-set-key [f7] 'make-symbolic-link)
(global-set-key [C-mouse-1] 'make-symbolic-link)

単純な(文字列ですむ)場合にベクタを使ってもかまいません。 先の2つの例をベクタを使うように書き直すとつぎのようになります。

 
(global-set-key [?\C-z] 'shell)

(global-set-key [?\C-x ?l] 'make-symbolic-link)

28.4.7 ファンクションキーの再定義

キー列には通常の文字以外にもファンクションキーを含めることができます。 キーボードの文字がLispの文字(実は整数です)で表されるのに対し、 ファンクションキーはLispシンボルで表されます。 ファンクションキーに単語のラベルが付いているなら、 その単語が対応するLispシンボルの名前になります。 たとえば普通に見られるファンクションキーとLispシンボルの対応はつぎのとおりです。

left, up, right, down

カーソル矢印キー。

begin, end, home, next, prior

その他のカーソル移動キー。

select, print, execute, backtab
insert, undo, redo, clearline
insertline, deleteline, insertchar, deletechar

その他のファンクションキー。

f1, f2, … f35

(キーボードの上端に並んでいる)番号の付いたファンクションキー。

kp-add, kp-subtract, kp-multiply, kp-divide
kp-backtab, kp-space, kp-tab, kp-enter
kp-separator, kp-decimal, kp-equal

(普通のキーボードの右側にまとまっている)キーパッドのキーで、 名前や句読点が印字されているもの。

kp-0, kp-1, … kp-9

キーパッドの数字キー

kp-f1, kp-f2, kp-f3, kp-f4

キーパッドのPFキー。

これらの名前は習慣的なものですが、システムによっては (とりわけXウィンドウシステムを使っている場合は)、 別の名前になっている場合があります。 あるファンクションキーにどのシンボルが対応しているか調べるには、 C-h cに続いてそのキーを打鍵してください。

ファンクションキーのシンボルを含むキー列(あるいは、 ASCII以外の文字を含むもの)は文字列ではなくベクタで指定してください。 ベクタの構文では要素と要素のあいだは空白で区切り、 全体を中括弧``[…]''で囲みます。 たとえば、ファンクションキー`f1'をコマンドrmailにバインドするには、 つぎのようにします。

 
(global-set-key [f1] 'rmail)

右矢印キーをコマンドfowared-charにバインドするには、 つぎのようにします。

 
(global-set-key [right] 'forward-char)

これは、シンボルrightを要素とするベクタのLisp構文です。 (このバインディングはEmacsのデフォルト設定に入っている。)

ベクタを用いたキーの再定義ついてより詳しくは、See section 初期化ファイルでのキーの変更

キー列の中でファンクションキーと文字を混ぜることができます。 以下の例は、 C-x NEXTをコマンドforward-pageにバインドしています。

 
(global-set-key [?\C-x next] 'forward-page)

ここで、?\C-xはLispの文字定数で、文字C-xを表します。 ベクタのもう1つの要素であるnextは、シンボルですから`?'は不要です。

ファンクションキーに対して、修飾キーCTRLMETAHYPERSUPERALTSHIFTを指定できます。 これらの修飾キーを指定するには、シンボル名のまえに`C-'、 `M-'、`H-'、`s-'、`A-'、`S-'を付けてください。 たとえば、Hyper-Meta-RIGHTで 1語先へ移動するにはつぎのように指定します。

 
(global-set-key [H-M-right] 'forward-word)

28.4.8 名前の付いたASCIIコントロール文字

TABRETBSLFDESCDELは もともとASCIIの特定のコントロール文字に対応していたのですが、 よく使われるため別にそれ専用のキーを持つようになりました。 のちに人々はEmacsでこれらのキーとそれらと『同じ』文字を CTRLキーと組み合わせて打鍵した場合とを区別できると 便利だと気がつきました。

EmacsではXウィンドウシステムを使っている場合、 これら2種類の入力を区別します。 つまり、キーボード上の特殊キーの方はtabreturnbackspacelinefeedescapedeleteという名前のファンクションキーとして扱うのです。 これらのファンクションキーは、もしそれ固有のバインディングが 指定されていなければ、自動的に対応するASCII文字に変換されます。 その結果、特にこの2種類を区別したいと思わない限りは、 ユーザーもLispプログラムもこれらの区分について気にする必要はありません。

(たとえば)TABC-iを区別したくないなら、 ASCII文字TAB(8進コード011)に対応するバインディング1つだけを 指定してください。 区別したいのなら、このASCII文字に対するバインディングに加えて、 『ファンクションキー』tabに対するバインディングも指定します。

通常のASCII端末では、TABC-i (および上記の対応する組のそれぞれ)を区別する方法はありません。 というのは、端末はどちらが押されても同じ文字を送出するからです。


28.4.9 キーボード上の非ASCII文字

アクセント付き文字などの非ASCII文字を送出するキーがあるキーボードでは、 それらのキーの再定義には、少々トリックが必要です。 2つの解決方法があります。 1つめは、set-keyboard-coding-system(see section コーディングシステムの指定)を 使って、キーボードのコーディングシステムを指定することです。 そうすれば、つぎのように書いて、 通常の方法でそれらのキーを再定義できます。

 
(global-set-key [?char] 'some-function)

ただし、charを挿入するには、定義したいキーを打ちます。

キーボードのコーディングシステムを指定しないと、 上のようにはできません。 そのかわりに、端末が実際に送出するコードを調べる必要があります。 Emacsでこれを簡単に行うには、 C-x b temp RETで空バッファを作成し、 M-x toggle-enable-multibyte-characters RETでユニバイトに してから、このバッファに文字を挿入するキーを打ちます。

文字のまえにポイントを移動して、C-b C-x =と打ちます。 8進数、10進数、16進数の3通りで表した文字コードを括弧で括った メッセージがミニバッファに表示されます。 定義するには、3つの数字の2番目、つまり、10進数を ベクタの中に書きます。

 
(global-set-key [decimal-code] 'some-function)

28.4.10 マウスボタンの再定義

Emacsではマウスボタンを表すのにもLispシンボルを使います。 Emacsのもっとも一般的なマウスイベントはクリック(click)イベントです。 これはマウスボタンを押して、マウスを移動せずにボタンを放したときに発生します。 ボタンを押した状態でマウスを移動すると ドラッグ(drag)イベントになります。 そして最後にマウスボタンを放したときにも、 やはりドラッグイベントが発生します。

基本的なクリックイベントに対応するシンボルは、 左ボタンに対してはmouse-1、 左から2番目のボタンに対してはmouse-2、などとなっています。 2番目のボタンをクリックしたときカレントウィンドウを分割するには、 つぎのように設定します。

 
(global-set-key [mouse-2] 'split-window-vertically)

ドラッグイベントについても同様ですが、 イベント名の`mouse'のまえに`drag-'が付きます。 たとえば、第1ボタンを押したままドラッグすると drag-mouse-1イベントが発生します。

マウスボタンが押されたときに発生するイベントに対して バインディングを指定することもできます。 これらのイベントは`drag-'のかわりに`down-'で始まります。 これらのイベントはキーバインディングが定義されているときだけ生成されます。 `down-'イベントのあとには、必ず、 対応するクリック/ドラグッイベントが発生します。

必要ならば、シングルクリック/ダブルクリック/トリプルクリックを 区別することもできます。 ダブルクリックとは、ほぼ同じ位置でマウスボタンを2回クリックすることです。 最初のクリックで通常のクリックイベントが発生します。 最初のクリックから十分短い時間内に2回目のクリックが起こると、 クリックイベントではなくダブルクリックイベントが発生します。 ダブルクリックイベントは、`double-'で始まります。 たとえば、double-mouse-3です。

つまり、同じ場所で2回クリックがあったとき、 2回目のクリックに特別な意味を与えることはできますが、 ただし最初のクリックで発生する通常のシングルクリックに 対して定義された動作も実行されることを前提としなければなりません。

このような制限のため、ダブルクリックで行えることが制約されますが、 ユーザーインターフェイスデザイナは、よいユーザーインターフェイスが つねにそのような制約に従うべきだとの考えを述べています。 つまり、ダブルクリックはシングルクリックと類似した動作をすべきであり、 『それよりいくらか多く』の動作をするのがよい、ということです。 そして、ダブルクリックイベントに対応するコマンドがその 「いくらか多く」のぶんの動作を行うべきだということです。

ダブルクリックイベントに対してバインディングが定義されていなければ、 ダブルクリックは2つのシングルクリックとして扱われます。 その結果、シングルクリックに対応するコマンドが2回実行されることになります。

Emacsではさらにトリプルクリックイベントも使えます (その場合、名前は`triple-'で始まる)。 しかし4重クリックをイベントタイプとして区別しません。 ですから、3回目以降の連続したクリックは、 すべてトリプルクリックイベントとして報告されます。 ただし、連続したクリックの回数はイベントリストに記録されていますから、 本当に4重以上のクリックを区別したければそうすることもできます。 4重以上のクリックに特別な意味を与えるのはお勧めできませんが、 4回だと1回と同じ、5回だと2回と同じというように3つの選択肢のあいだで 巡回できるようにするのは場合によっては有効かもしれません。

Emacsはまた、ドラッグやボタンイベントでも複数回の押し下げを記録します。 たとえば、ボタンを2回押してからそのままマウスを移動した場合、 Emacsは`double-drag-'で始まるイベントを生成します。 ドラッグでなくボタンを押し下げただけの場合は同様に、 `double-down-'で始まるイベントを生成します (ただし、他のボタンイベントと同様に、そのイベントに対する バインディングがなければ無視される)。

変数double-click-timeは、どれくらいの時間間隔内であれば 2つの隣接するクリックをダブルクリックとみなすかを指定します。 単位はミリ秒です。 値がnilであれば、ダブルクリックを検出しません。 値がtであれば、時間間隔の上限はないものとして扱います。

マウスイベントに対応するシンボルにはさらに、 `C-'、`M-'、`H-'、`s-'、`A-'、 `S-'の各プレフィックスで、修飾キーの情報も組み込めます。 順番は、プレフィックスに続いて`double-'や`triple-'があり、 そのあとが`drag-'や`down-'ということになります。

フレームには、モード行やスクロールバーなどの バッファ中のテキストを表示する以外の部分もあります。 マウスイベントがこれらの特別な部分で発生したものかどうかを調べるために、 ダミーの「プレフィックスキー」があります。 たとえば、マウスがモード行でクリックされた場合、 まずmode-lineというプレフィックスキーが送られ、 続いて通常のマウスボタンに対応したイベントが送られます。 ですから、モード行で第1ボタンがクリックされたときに scroll-upを実行するにはつぎのようにします。

 
(global-set-key [mode-line mouse-1] 'scroll-up)

ダミーのプレフィックスキーとその意味はつぎのとおりです。

mode-line

マウスがウィンドウのモード行にある。

vertical-line

マウスが横に隣接するウィンドウ間の境界線上にある。 (スクロールバーを表示させると、 境界線のかわりにスクロールバーが現れる。)

vertical-scroll-bar

マウスが縦スクロールバー上にある。 (Emacsで使えるスクロールバーは、現在のところ縦スクロールバーのみ。)

1つのキー列の中に2つ以上のマウスボタンイベントを含めることもできますが、 普通はあまりしないでしょう。


28.4.11 使用禁止コマンド

コマンドを使用禁止にすると、コマンドの実行にはユーザーの確認が必要になります。 コマンドを使用禁止にする目的は、 初心者がそのコマンドをまちがって実行してしまい、混乱するのを防ぐためです。

Emacs上で使用禁止コマンドを対話的に実行しようとすると、 コマンド名、説明文、とりあえずどうすべきかの指示を 表示したウィンドウが現れます。 つぎにEmacsはコマンドを実行するか、使用禁止を解除してから実行するか、 実行を取り消すかを問い合わせてきます。 コマンドの使用禁止を解除することを選ぶと、 Emacsさらに、以後恒久的にそうするのか、 または現在のセッション内だけそうするのかも問い合わせてきます。 恒久的に使えるようにすると、 自動的に個人の`.emacs'ファイルを編集します。

コマンドを使用禁止にする機構は、 コマンドに対応するLispシンボルの属性disablednil以外の値を設定することです。 これを行うLispプログラムはつぎのようになります。

 
(put 'delete-region 'disabled t)

属性disabledの値が文字列であれば、 コマンドを使用しようとしたときに表示される メッセージにその文字列も含まれるようになります。

 
(put 'delete-region 'disabled
     "It's better to use `kill-region' instead.\n")

コマンドを使用禁止にするには、`.emacs'ファイルを直接編集するか、 かわってこのファイルを編集するコマンドM-x disable-commandを使います。 同様に、コマンドM-x enable-commandは、 `.emacs'ファイルを編集してコマンドを恒久的に使える状態にします。 See section 初期化ファイル`~/.emacs'

コマンドが使用禁止であるかどうかは、 そのコマンドを起動するキー列には無関係です。 したがって、M-xでそのコマンドを起動しても Emacsはその可否を問い合わせてきます。 Lispプログラムからコマンドを関数として呼び出す場合には 使用禁止にしても何の効果もありません。


28.5 キーボード変換

キーボードの機種によっては、Emacsが使用するすべての特殊文字を 送ってくれないものがあります。 もっともよくある問題は、DEL文字に関するものです。 いくつかのキーボードでは、 このきわめて重要な文字を簡単に打ち込む手段がありません。 それは、削除にはC-hを使うことを前提としているからです。 そのようなキーボードで削除のためのキーを打つと、 Emacsはそれをプレフィックス文字C-hとして解釈し、 どのヘルプ機能を使うか問い合わせてきてしまいます。 それはユーザーがしたかったことではありません。

Emacs内でこの問題を回避するには、C-hDELに、 DELC-hに変換するキーボード変換を 以下のように 設定することで回避できます。

 
;; C-hDELに変換する。
(keyboard-translate ?\C-h ?\C-?)

;; DELC-hに変換する。
(keyboard-translate ?\C-? ?\C-h)

キーボード変換はキーマップによるキーバインディング(see section キーマップ)と 同じではありません。 Emacsには状況ごとに使い分けられる多数のキーマップがあるのに対し、 キーボード変換は一式だけしかなく、 Emacsが端末から読むすべての文字に対してその変換が適用されます。 キーボード変換は入力処理のいちばん下位のレベルで行われ、 キーマップ上の検索はキーボード変換を施した結果に対して行われます。

XウィンドウシステムではDELETEというキーはファンクションキーであり、 ASCII文字DELとは別ものです。 See section 名前の付いたASCIIコントロール文字。 キーボード変換はASCII文字入力だけに適用され、 ファンクションキーとは無関係ですから、 Xウィンドウシステムでは上の例はDELETEキーに対して効果をもたらしません。 しかし、Xウィンドウシステムでは上のようなキーボード変換そのものが不要です。 というのは、EmacsはXウィンドウシステムでは BACKSPACEキーとC-hも区別でき、 通常、BAKSPACEDELとして扱うからです。

キーボード変換の使い方に関する詳しい情報は、 (elisp)Translating Input section `入力イベントの変換' in Emacs Lisp リファレンスマニュアルを 参照してください。


28.6 構文テーブル

単語や対応した括弧の対を認識するEmacsコマンドはすべて、 構文テーブル(syntax table)によって制御されます。 構文テーブルは、どの文字が開き括弧で、どの文字が単語の中身で、 どの文字がシングルクォートかといったことを記述しています。 各メジャーモードにはそれぞれ専用の構文テーブルがあり (ただし、互いに関係のあるメジャーモードが 1つの構文テーブルを共用することはある)、 各バッファごとにそのときのメジャーモードの構文テーブルが使われます。 カレントバッファに設定されている構文テーブルはすべてのコマンドが使うので、 以下ではこれを『現在の』構文テーブルと呼びます。 構文テーブルは文字テーブル(char-table)型のLispオブジェクトであり、 その要素は数値です。

現在の構文テーブルの内容に関する記述を表示するには、 C-h sdescirbe-syntax)を使います。 記述の表示には各文字ごとに、 その文字の現在の構文を設定するためにmodify-syntax-entryに 渡すべき文字列、および、その文字列の英語での説明が含まれます。

構文テーブルに関する詳しい情報については、 (elisp)Syntax Tables section `構文テーブル' in Emacs Lisp リファレンスマニュアルを 参照してください。


28.7 初期化ファイル`~/.emacs'

Emacsが実行を開始するとき、通常はユーザーのホームディレクトリにある ファイル`.emacs'や`.emacs.el'からLispプログラムをロードします。 このファイルがEmacsの初期化の仕方を指定するので、 このファイルのことを初期化ファイル(init file)と呼びます。 コマンド行オプション`-q'で、 Emacsに初期化ファイルを読まないことを指示したり、 `-u'(あるいは`--user')で、 別のユーザーの初期化ファイルを指定できます (see section Emacsの起動と終了)。

デフォルトの初期化ファイルもあります。 これは`default.el'という名前のライブラリファイルで、 Emacsはライブラリ探索パスをとおしてその場所を探します。 Emacsの配布には`default.el'は含まれていません。 ローカルなカスタマイズのためにサイトで`default.el'を 用意することもあります。 このファイルがあれば(`-q'を指定したときを除いて) Emacsを開始するときつねにロードされます。 しかし、あるならば個人の初期化ファイルが最初にロードされます。 その中でinhibit-default-initnil以外の値を設定すると、 `default.el'はロードされません。

各サイトにはサイトスタートアップファイルがあるかもしれません。 あるならば、このファイルの名前は`site-start.el'です。 Emacsはユーザーの初期化ファイルを読むまえにこのファイルもロードします。 このファイルのロードを抑止するには、 オプション`-no-site-file'を指定します。

`.emacs'に大量のコードがある場合には、 `~/.emacs.el'と改名してバイトコンパイルしておくべきです。 Emacs Lispプログラムのコンパイルについてより詳しくは、 See (elisp)Byte Compilation section `バイトコンパイル' in Emacs Lisp リファレンスマニュアル

単なるカスタマイズを超えるような実際のEmacsプログラムを書くのであれば、 The Emacs Lisp Reference Manual(57)を読むべきです。


28.7.1 初期化ファイルの構文

ファイル`.emacs'にはLispの関数呼び出し式を書きます。 関数呼び出しは、関数名に続けて引数リストを並べ、全体を括弧で囲みます。 たとえば、(setq fill-column 60)は、 関数setqによって、変数fill-column(see section テキストの詰め込み)に 60を設定します。

setqの2番目の引数は変数の新しい値を表す式です。 これは、定数でも、変数でも、関数呼び出し式でもかまいません。 `.emacs'ファイルでは定数を使うことがもっとも多いでしょう。 定数にはつぎのものがあります。

数値:

数値は10進表記し、先頭にマイナス符号があってもよい。

文字列:

Lispの文字列の構文はCの文字列の構文とほぼ同じだが、多少違うところもある。 文字列定数の始まりと終りにはダブルクォートを使う。

文字列の中には、改行や特殊文字をそのまま入れることができる。 しかし、バックスラッシュで始まる形式、つまり、 改行は`\n'、バックスペースは`\b'、 復帰は`\r'、タブは`\t'、ページ送りは`\f'(コントロールL)、 エスケープは`\e'、バックスラッシュは`\\'、 ダブルクォートは`\"'、8進コードoooの文字は`\ooo'で 表すことができ、そのほうが読みやすい。 バックスラッシュとダブルクォートの2つだけは、 文字列に含めるのに必ずこのような形で書き表す必要がある。

`\C-'はコントロール文字を表すプレフィックスとして使用できる。 たとえば、`\C-s'でASCIIのコントロールSを表す。 同様に、`\M-'はメタ文字を表すプレフィックスとして使用できる。 たとえば、`\M-a'でMeta-A、 `\M-\C-a'でControl-Meta-Aを表す。

文字:

Lispの文字定数は、`?'に続けて文字または`\'で始まる エスケープシーケンスを書いたもの。 たとえば、?x?\n?\)などは文字定数。 Lispでは文字と文字列は別ものなので注意すること。 ある場面では文字列が必要であり、別の場面では文字が必要である。

真:

tは「真」を表す。

偽:

nilは「偽」を表す。

その他のLispオブジェクト:

シングルクォートに続けてそのLispオブジェクトを書く。


28.7.2 初期化ファイルの例

以下にはよく使われるLispの式の例をあげておきます。


28.7.3 端末に固有の初期化

各端末種別ごとに、Emacsがその端末で動くときにロードするライブラリを 指定できます。 つまり、termtypeという名前の端末でEmacsを起動するときには、 `term/termtype'というライブラリがロードされます。 ライブラリの探索は通常どおり load-pathの各ディレクトリに対して行われ、 ファイルの拡張子は`.elc'か`.el'です。 通常、これらのライブラリはほとんどの Emacsライブラリを収めたディレクトリの下の`term'という サブディレクトリに置かれます。

端末固有のライブラリの普通の用途は、端末のファンクションキーによって 送出されるエスケープシーケンスをfunction-key-mapを使って意味の ある名前に対応付けることです。 このような設定を行うファイルの例として、たとえば ファイル`term/kl201.el'を見てみてください。 多くのファンクションキーはtermcapデータベースの情報に 基づいて自動的に対応付けがなされます。 端末固有ライブラリでは、termcapで指定されていないファンクションキー だけを対応付ければよいのです。

端末種別にハイフンが含まれている場合は、 ライブラリ名の選択には最初のハイフンよりまえの部分だけが使われます。 つまり、端末種別`aaa-48'と`aaa-30-rv'では、 どちらも`term/aaa'をロードします。 ライブラリ中のコードでは(getenv "TERM")を 使って必要なら完全な端末種別名を取得できます。

端末ライブラリの名前は、変数term-file-prefixと端末種別とを 連結して作られます。 ファイル`.emacs'中でterm-file-prefixnilに設定すると端末ライブラリのロードを抑止できます。

Emacsは`.emacs'と端末ライブラリを読んだあと、 初期化の最後にフックterm-setup-hookを実行します。 端末ライブラリによる指定を一部変更したり、 端末ライブラリがない端末の初期設定を行いたければ、 このフックにフック関数を追加してください。 See section フック


28.7.4 個人の初期化ファイルの探し方

通常、Emacsは環境変数HOMEに基づいて`.emacs'を探し、 ファイル名の`~'の意味を定めます。 しかし、suを実行したあとでは、Emacsは(su実行前の) もとのユーザーの`.emacs'を読もうとし、 suした先のユーザーのではありません。 これは、たとえスーパーユーザーになっているとしても、 本来のユーザー独自のエディタのカスタマイズを使うべきだと考えるからです。

より正確には、Emacsはまずどのユーザーの初期化ファイルを使うかを決めます。 それにはまず環境変数LOGNAMEおよびUSERからユーザー名を取得します。 これらの環境変数がみつからなければ、Emacsは実効ユーザーIDを参照します。 ユーザー名と実ユーザーIDが一致すれば、EmacsはHOMEを利用します。 一致しない場合は、システムのユーザーデータベースから そのユーザー名に対応するホームディレクトリを探して使用します。


28.8 中断とアボート

C-g
C-BREAK(MS-DOS)

中断する。 動作中のコマンドや打鍵途中のコマンドを取り消す。

C-]

アボートする。 いちばん内側の再帰編集レベルを強制的に終了し、 その再帰編集レベルを起動したコマンドを取り消す (abort-recursive-edit)。

ESC ESC ESC

中断かアボートのいずれか意味のあるほうを実行する (keyboard-escape-quit)。

M-x top-level

現在実行中のすべての再帰編集レベルを強制的に終了する。

C-x u

バッファの内容に対して行った直前の変更を取り消す(undo)。

実行を完了していないコマンドを取り消すには、2つの方法があります。 1つはC-g中断すること、 もう1つはC-]M-x top-levelアボートすることです。 中断とは、打鍵途中のコマンドや動作中のコマンドを取り消すことをいいます。 アボートとは、再帰編集レベルから抜け出し、かつ、 その再帰編集レベルを起動したコマンドを取り消すことをいいます (see section 再帰編集レベル)。

C-gでの中断は、打鍵途中のコマンドや 不要な数引数を打ってしまったときにとりやめるのに使います。 また、実行途中のコマンドを比較的安全な方法で止めますから、 長時間かかるコマンドをうっかり始めてしまったときにも使えます。 特に、キル操作を中断しても安全です。 テキストは、まだすべてバッファ内にあるか、 または、すべてキルリングに入っている (あるいは、その両方に入っている)からです。 なお、インクリメンタルサーチを中断する場合には、 文字列探索のところで説明してあるように、特別な動作を行います。 一般には、サーチから抜け出すにはC-gを2回連打する必要があります (see section インクリメンタルサーチ)。

MS-DOSでは、C-BREAKC-gと同様に中断として働きます。 MS-DOSでは、コマンドの実行中にユーザーとのやりとりを行う状態にないときには、 C-gを検出できないからです。 これに対して、C-BREAKはつねに認識できます。 See section MS-DOSのキーボードとマウス

C-gはつぎのように動作します。 C-gが打鍵されると変数quit-flagtが設定されます。 Emacs Lispはこの変数を頻繁に調べ、値がnil以外だと中断処理を行います。 C-gが実際にコマンドとして実行されるのは、 Emacsが入力待ち状態にあるときにC-gを打った場合だけです。

最初のC-gが認識されないうちに2つめのC-gを打って中断すると、 『緊急脱出』機能を発動したことになりシェルに戻ります。 See section 緊急脱出

中断できない場合もありえます。 Emacsがオペレーティングシステムに何かを頼んで待っているときには、 待ち状態を起こしたシステムコールを使ったEmacs側で特別な手当てをしない限り 中断できません。 Emacsでは、ユーザーが中断しそうなシステムコールには 手当てを施してありますが、手当てしていない場所を叩く可能性はあります。 よくあるのは、NFS経由の入出力を待っているときです。 Emacs側ではこれを中断する方法はわかっているのですが、 多くのNFSの実装では、NFSサーバーが固まったときにユーザープログラムが NFSの待ちを中断することを許していないのです。

C-]によるアボート(abort-recursive-edit)は、 再帰編集レベルから脱出し、かつ、その再帰編集レベルを 起動したコマンドを取り消すのに使います。 C-gによる中断はこのような目的には使えませんし、 このようなことはできません。 というのは、C-gは、ある再帰編集レベルの中で 打ちかけたコマンドを取り消すのに使うからです。 どちらの操作も必要なものです。 たとえば、再帰編集中に数引数を入力しようとしてC-u 8と打鍵した場合、 C-gで数引数を取り消しても再帰編集に留まったままです。

コマンドESC ESC ESCkeyboard-escape-quit)は、中断かアボートのいずれかを行います。 このキーを使うのは、多くのPCのソフトでESCが 『抜け出す』の意味に使われているからです。 C-gと同様に、数引数を取り消したり、 選択したリージョンをクリアしたり、問い合わせ型置換操作から抜け出します。 C-]と同様に、ミニバッファや再帰編集から抜け出します。 また、C-x 1のように、フレームを複数ウィンドウに分割しているのを やめることもできます。 しかしながら、実行中のコマンドを止めることはできません。 なぜなら、このコマンドは普通のコマンドとして実行されるので、 Emacsがコマンドを読み込む状態にならないとこのコマンドを認識しないからです。

コマンドM-x top-levelは、現在入っているすべての再帰編集レベルから 抜け出すのに『十分な』数のC-]と同等です。 C-]は一度に1レベルだけ抜け出すのに対し、 M-x top-levelはすべてのレベルを一気に抜け出します。 C-]M-x top-levelも他のコマンドと同様の普通のコマンドですから、 C-gとは違って、Emacsがコマンドを受け付ける状態のときだけ動作します。 C-]は普通のキーであり、キーマップにそのバインディングがあるので そのように動作するのです。 See section 再帰編集レベル

C-x uundo)は、正確にいえばコマンドを 取り消すわけではありませんが、 動作を完了してしまったコマンドを取り消すものと考えることができます。 See section 変更をアンドゥする(もとに戻す)


28.9 Emacsのトラブルに対する対処

本節では、Emacsが正常に動作し損なうさまざまな条件と、それらの見分け方、 直し方について説明します。


28.9.1 DELで削除できない

DELが文字を削除するかわりにControl-hのように ヘルプに入ってしまう場合には、 使っている端末がDELに対してまちがった文字コードを送出しています。 この問題に対処するには、キーボード変換表を変更します (see section キーボード変換)。


28.9.2 再帰編集レベル

再帰編集レベルはEmacsの重要で有用な機能ですが、 それについて理解していない人にとっては、誤動作に見える可能性があります。

モード行のメジャー/マイナモード名を囲む丸括弧の周囲に中括弧 `[…]'が表示されているときは、再帰編集レベルに入っています。 意図してそうしたのでなかったり、 再帰編集レベルの意味を理解していないのであれば、 再帰編集レベルから抜け出すべきです。 それにはM-x top-levelと打ちます。 これをトップレベルへの抜け出しと呼びます。 See section 再帰編集レベル


28.9.3 画面上のゴミ

画面上のデータがまちがっているように見えたら、まず最初にすべきことは、 テキストが本当にまちがっているのかどうか調べることです。 C-lと打って画面全体を再描画します。 これで画面が正しそうになるのなら、問題は画面更新にあったのです。 (そうでない場合は、see section テキスト内のゴミ)。

画面更新の問題は、 使っている端末に対応するtermcapの定義がまちがっている場合が多いです。 Emacsの配布に含まれるファイル`etc/TERMS'には、 この種の問題で既知のものに対する修正が入っています。 ファイル`INSTALL'には、 この種の問題に対する一般的なアドバイスの節があります。 いちばんありがちなのは、 ある種の画面操作に対するパディング (59) が不足している場合です。 この種の問題があるかどうか調べるには、 他のメーカ製の別の端末でEmacsを動かしてみてください。 ある機種の端末では頻繁に問題が起きるのに別の機種の端末では問題がないなら、 termcapの定義がまちがっている可能性があります。 しかし、ある種の機能を有するか欠如している端末で現れる Emacsのバグである可能性もあります。


28.9.4 テキスト内のゴミ

C-lを実行してもテキストが変ならば、 正しいと思われる状態になるまで、 C-x uを使って変更をもとに戻してみてください。 また、どのコマンドで変になったのか調べるために、 C-h lを試してみてください。

バッファの先頭や末尾で大量のテキストが失われているようなら、 モード行に単語`Narrow'が表示されていないか確認してください。 もしそうなら、おそらくテキストは失われているのではなく、 一時的に見えなくなっているのでしょう。 見えるようにするには、C-x n wと打ってください。 See section ナロイング


28.9.5 自発的なインクリメンタルサーチの開始

Emacsが画面の最下行に自発的に`I-search:'と表示するようなら、 劣悪なxon/xoffの『フロー制御プロトコル』に従って 端末がC-sC-qを送っているためでしょう。

もしこの状態が起きたら、もっともよいのは端末をフロー制御なしに設定するか、 または、パディングを十分に増やして端末がけっしてC-sを 送らないようにすることです。 (パディングを増やす1つの方法は、 より大きい値を変数baud-rateに設定すること。 この値はボーという単位で表した端末の出力速度。)

フロー制御を止められない場合の次善の策は、 Emacsにフロー制御を処理させることです。 それには、関数enable-flow-controlを呼び出してください。

典型的な場合、 ある種の端末タイプに限ってフロー制御を使う必要があります。 enable-flow-control-onを使って、 そのような種類の端末に限ってフロー制御を行うようにできます。 たとえば、VT-100端末とH19端末にはフロー制御を行う必要があるのなら、 ファイル`.emacs'につぎのものを入れます。

 
(enable-flow-control-on "vt100" "h19")

フロー制御を使っている場合には、C-sのかわりにC-\C-qのかわりにC-^を使う必要があります。 (これらの割り当てはキーボード変換によって行われる。 see section キーボード変換。)


28.9.6 メモリ不足

`Virtual memory exceeded'というエラーメッセージが出たら、 変更したバッファをC-x sで保存してください。 この方法で保存する場合、必要なメモリは最小限ですみます。 Emacsは上記のエラーが起きたときでも使える予備のメモリを確保していますから、 C-x sを完了するのには十分なはずです。

変更済みのバッファを保存したら、 Emacsを終了して別のEmacsを起動してもよいですし、 M-x kill-some-bufferを使って 現在動いているEmacsのメモリを解放してもよいです。 大量のテキストが入っているバッファを消せば、 安全に編集を続行できます。 空きメモリが十分な量になると予備のメモリを自動的に確保し直し、 再度メモリ不足になったときに備えます。

メモリ不足になったときには、M-x buffer-menuを使って バッファを保存したり消したりしないでください。 このコマンドはけっこうメモリを必要とするので、 確保した予備のメモリだけでは十分でない可能性があるからです。


28.9.7 クラッシュからの回復

Emacsやコンピュータがクラッシュしても、 クラッシュ時に編集していたファイルは自動保存ファイルから回復できます。 それには、Emacsを再度起動してから、コマンドM-x recover-sessionを 入力してください。

このコマンドは、まず、中断されたセッションファイルの一覧を日付とともに バッファに表示します。 その中からどのセッションを回復するか選んでください。 通常は、最新のセッションを選べばよいでしょう。 望みのセッションの行にポイントを動かして、C-c C-cと打ちます。

すると、recover-sessionは、そのセッションで編集中だった 各ファイルについて回復するかどうか問い合わせてきます。 yと答えると、そのファイルと自動保存ファイルの日付を表示してから、 回復するかどうか再度問い合わせてきます。 再問い合わせに対してはyesで答える必要があります。 そうすると、Emacsはそのファイルを訪れますが、 テキストは自動保存ファイルから持ってきます。

recover-sessionが完了すると、 回復を指定したファイルはEmacsバッファに入っています。 そうしたらこれらのバッファを保存してください。 保存して始めてもとのファイルが更新されます。


28.9.8 緊急脱出

バグのために、Emacsがquit-flagを検査しないループに入ってしまうことも ありえます。 このため、このフラグが設定されている状態で再度C-gが打たれると ただちに実行を休止する特別な機能がEmacsにはあり、 いつでもGNU Emacsから抜け出すことができます。 通常、Emacsはすみやかにquit-flagを認識し(中断し)ますから、 この特別な機能が使われることはまずありません。 (MS-DOSや互換システムでは、C-BREAKを2回連打する。)

C-gの連打によって休止したEmacsを再開すると、 Emacsは休止直前に実行していた動作に戻るまえに、 つぎの2つの質問をしてきます。

 
Auto-save? (y or n)
Abort (and dump core)? (y or n)

それぞれの質問に対し、ynに続けてRETで答えてください。

`Auto-save?'にyと答えると、 自動保存を行う設定になっている変更されたバッファすべてに対して ただちに自動保存を実行します。

`Abort (and dump core)?'にyと答えると、 Emacsは不正命令を実行してコアダンプを作ります。 コアダンプがあると、Emacsが中断できなかった理由をウィザード (60) が追究できます。 コアダンプを作り終えるとEmacsの実行は終了します。 nと答えると実行は継続します。 運がよければ、Emacsが最終的にはquit-flagを検査して 正常に中断できるでしょう。 運が悪ければ、またループに入ったままになりますから、 再度C-gを打ってEmacsをまた休止します。

本当はEmacsが固まったのではなく単に遅いだけの場合には、 意図せずにC-gを連打してしまうことがあります。 その場合には、再開して2つの質問にnと答えればもとの状態に戻れます。 中断要求はすぐに受け付けられるでしょう。

XウィンドウシステムのもとでEmacsが動作している場合には、 C-g連打の機能は切ってあります。 というのは、ウィンドウマネージャを使ってEmacsを終了させたり、 別のウィンドウを開いて別のプログラムを動かせるからです。

MS-DOSや互換システムでは、 (MS-DOSやBIOSの)システムコールが固まっている場合や Emacsが非常にきつい(LispコードではなくCのコードで) 無限ループに入っている場合には、 C-BREAKを2回打っても緊急脱出の機能を使えない場合があります。


28.9.9 いらいらしたら…

Emacsを使うこと(や、その他のこと)がきわめて不愉快になったり、 ここまでにあげたどの方法でも問題が解決しない場合でも、 Emacsはまだ手助けができます。

まず、Emacsがコマンドに応答しないようなら、 C-g C-gと打ってEmacsから抜け出し、 新たに別のEmacsを起動してください。

つぎに、M-x doctor RETと打ってください。

doctorプログラムがあなたのいらいらを鎮めてくれるでしょう。 doctorに何かを話すときには、RET RETと打っていい終える 必要があります。 こうすると、doctorは患者が話し終えたことを認識します。


28.10 バグの報告

Emacsのバグに出会うこともあるでしょう。 バグを修正する/できるとは約束できませんし、 そもそもバグだと認めないかもしれませんが、 読者が遭遇した問題については知らせてほしいと考えています。 たしかにそれをバグだと認めて修正しようということになる場合も多いのです。

バグを修正するには、まず、報告してもらう必要があります。 効果的に報告してもらうためには、報告の仕方を知っていただく必要があります。


28.10.1 バグの発生時期

Emacsが不正命令を実行したり、 (『ディスクが満杯』などの外部の問題ではなく)プログラムに問題が あるというオペレーティングシステムのメッセージを表示して止まった場合には、 たしかにバグがあるといえます。

Emacsの画面の更新結果がバッファの内容に対応していないなら、 それもたしかにバグです。 コマンドの実行が思わしくなくてもC-lで再表示させると正しくなる場合には、 画面更新がまちがっているのです。

あるコマンドを実行するのに無限に時間がかかるというのはバグの可能性が ありますが、たしかにEmacsの責任かどうかを確認する必要があります。 コマンドによってはとても時間がかかるものもあります。 C-g(MS-DOSではC-BREAK)を打ってから C-h lを打つことで、Emacsが受け付けた入力がたしかに 読者が意図したものだったかどうか確認できます。 すぐに処理されるコマンドだという確信があるなら、 バグを報告してください。 そのコマンドがすごく時間のかかるものかどうかわからないなら、 マニュアルで調べるか知っている人に聞いてください。

よく知っているコマンドであって、普通なら問題なく結果が得られるはずなのに、 かわりにEmacsがエラーメッセージを出すようなら、恐らくそれはバグでしょう。

コマンドが正しくない動作をするのなら、それはバグです。 ただし、コマンドが本当は何をするのが正しいか確認してください。 そのコマンドに馴染みがないとか、 そのコマンドがどう動作するはずなのか確信が持てない場合は、 コマンドは実際には正しく動作しているのかもしれません。 バグという結論に飛びつくまえに、よく知っている人に見てもらってください。

最後に、コマンドの意図された定義が編集操作に対して最良でない可能性があります。 これは重要な問題ではありますが、ユーザーがどう判断するかの問題でもあります。 既存の機能について無知なために、 まちがっていると結論を出してしまうのも簡単です。 まずドキュメントをひととおり調べて、十分に納得し、 それでもなお自分にとって必要な機能がない、と断言できるまでは、 コマンドの定義が悪いなどとはいわないほうがよいでしょう。 マニュアルを熟読してもコマンドが何をするのかよくわからなければ、 索引や用語集を活用してよくわからない単語について調べましょう。

十分熟読しても、なおコマンドが何をするのかわからないなら、 それは「マニュアルのバグ」として報告すべきでしょう。 マニュアルは、読者を含めて、Emacsの専門家でない人が読んでも すべてのことが明らかになるようなものであるべきです。 ドキュメントのバグを報告することも、 プログラムのバグを報告することと同じくらい重要なことです。

関数や変数のオンラインの説明文がマニュアルと一致しない場合は、 どちらかがまちがっていますから、これもバグです。


28.10.2 バグの報告とは

バグがあると確信したら、それを報告すること、 しかも、役立つ形で報告することが重要です。 もっとも有用なのは、どのようなコマンドを打ち込んだかを、 Emacsを起動するシェルのコマンドから始めて 問題が起きるところまですべて正確に記述することです。

バグを報告するときもっとも重要なことは事実を報告することです。 仮説や口頭説明は、詳細な生データのかわりにはなりません。 事実を報告することは単純なはずなのに、 多くの人はかわりに説明をでっちあげてそれを報告したがります。 その説明がEmacsの実装方式の想像に基づいたものであるならば、 その説明はまったく役に立たないでしょう。 事実が欠けていたらバグに関する真の情報を得られません。

たとえば、ユーザーがとても大きなファイルを訪れるために C-x C-f /glorp/baz.ugh RETと打ち込んだら、 Emacsが`I feel pretty today'と表示したとしましょう。 もっともよいバグレポートは、まさにこの文のように報告することです。 すべての事実だけを報告できるからです。

問題はファイルの大きさにあると仮定して、 「大きなファイルを訪問したら、Emacsが`I feel pretty today'と表示した」 などと書いてはいけません。 これが『説明をでっちあげた』報告です。 問題はファイル名に`z'が含まれていたために生じたのかもしれないのです。 もしそうだとしたら、報告に基づいて適当な「大きなファイル」を訪問してみても、 そのファイル名に`z'が含まれていなければ何も悪いところが みつからないでしょう。 報告の文面からは、名前に`z'を含んだファイルを 試しに訪問してみるべきだとはわかりません。

あるいは、ファイルがちょうど25個の空白文字で始まっているために 問題が起きたのかもしれません。 ですから、報告に際しては、そのバグを再現させるのに必要なファイルがあれば、 それらのファイルの正確な内容も教えてください。 その問題は、たまたま、C-x C-aと打った直後にのみ 発生するのだとしたらどうでしょう? ですから、Emacsを起動してから問題に遭遇するまでに 打ち込んだものすべてを教えてほしいのです。

どの訪問コマンドを使っても同じように問題が発生すると知っている のでない限り、C-x C-fと打ったと報告するかわりに 「ファイルを訪問した」というのさえいけません。 同様に、「1行に3文字入っているとき」ではなく、 「RET A B C RET C-pと打ち込んだあとで」のように、 あなたがテキストを入れたやり方そのものを報告してください。

このように、バグを報告するときには、いかなる説明も推測しないでください。 問題を実際にデバッグして憶測ではない説明を報告してもらえるなら、 それは有益ですが、事実も含めてください。


28.10.3 バグレポートのチェックリスト

バグレポートを送る最良の方法は、電子メイルでEmacs保守チーム `bug-gnu-emacs@gnu.org'に送ることです。 (重要な改良の提案などもここに送ってください)。

他から出されたバグレポートが読みたければ、 ニュースグループ`gnu.emacs.bug'で読めます。 ただし、傍観者として見る場合には、見たものについて批判するべきではない、 ということを承知しておいてください。 バグレポートの目的はEmacs保守チームに情報を提供することです。 傍観者は、この目的に干渉しない限りは、歓迎します。 特に、大量のデータが添付されているバグレポートもありますので、 傍観者はそのことを非難すべきではありません。

ネットニュース経由でバグレポートを投稿しないでください。 ネットニュースよりもメイルのほうが送り手のメイルアドレスが確実にわかり 信頼できます。 もっと情報が必要なときには、メイルで問い合わせる必要があるかも知れません。

電子メイルを送れない場合には、 紙や他の機械可読な媒体で下記へ送ってください。

 
GNU Emacs Bugs
Free Software Foundation
59 Temple Place, Suite 330
Boston, MA 02111-1307 USA

バグを修正するとは約束できません。 しかし、重大なバグや、醜いバグや、簡単に直せるバグなら、直したいと思います。

Emacsのバグレポートを送るのに便利な方法の1つは、 コマンドM-x report-emacs-bugsを使うことです。 このコマンドはメイルバッファ(see section メイルの送信)を開いて、 自動的に重要な情報の一部を書き込みます。 しかし、必要な情報をすべて入れられるわけではありませんから、 以下の指針を読んでそれに従い、 メッセージを送るまえに重要な情報を自分で打ち込んでください。

保守チームがバグの調査を開始するためには、 以下のすべてがバグレポートに含まれている必要があります。

以下には、バグレポートに必要ないものをあげておきます。


28.10.4 GNU Emacsに対する修正を送る

GNU Emacsに対する改良や虫取りのための修正を送ろうということであれば、 おおいに助かります。 修正を送るにあたっては、保守チームがそれを役立てやすいように、 以下の指針に従ってください。 さもないと、送られた情報は有用であっても、 役立てるには余分な作業が必要になります。 GNU Emacsの保守は最善の環境でやっても手間のかかる仕事ですから、 手助けしていただくにしても十分な配慮が必要なのです。


28.11 Emacsの開発に貢献するには

Emacsのプレテスト版が正しく動作することの確認を手助けしたかったり、 Emacsの改良作業に加わりたければ、 bug-gun-emacs@gnu.orgの保守チームに連絡してください。 プレテスト参加者は、バグを報告するだけでなく、バグを探すことも要求されます。 Emacsの改良に加わりたければ、保守チームにプロジェクトの示唆を求めるか、 あなたのアイデアを提案してください。

すでに改良したコードを書いてしまったのなら、それについて教えてください。 まだ作業を始めていないのなら、始めるまえに bug-gnu-emacs@gnu.orgに連絡したほうがよいです。 そうすれば、Emacsの残りの部分とよく適合する形で 拡張を行うにはどうしたらよいかのヒントがもらえるでしょう。


28.12 GNU Emacsに関する助言を得るには

GNU Emacsをインストールしたり、使ったり、変更したりするうえで手助けが必要なら、 2つの方法があります。


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Akihiro Sagawa on June, 15 2005 using texi2html 1.70.