[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
本章では、Emacsの動作を(あまり大幅でなく)カスタマイズする方法に ついて説明します。 もっと大幅な変更を行いたい場合には
カスタマイズは、Emacsの1つのセッションの中だけで効果を持ちます。 Emacsを終了するとカスタマイズの効果は失われますし、 同時にあるいはあとで別のEmacsを立ち上げた場合にも何の影響も及ぼしません。 あるEmacsのセッションがセッションを超えて影響するためには、 ファイルに書くしかありません。 特に、カスタマイズを『恒久化』したい場合には、 個人の`.emacs'ファイルや その他の関連するファイルに適切な内容を書き込んでおき、 セッションごとにカスタマイズが行われるようにします。 See 節 AE.6 初期化ファイル`~/.emacs'。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
マイナモードは、個別にオン/オフ可能な機能です。 たとえば、マイナモードである自動詰め込み(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 節 Y. 略語の利用法 (2004/01/12)。
自動詰め込み(auto-fill)モードでは、いちいち改行で行分けしなくても テキストを詰め込んで入力できます。 行が長くなりすぎないようにEmacsが適宜改行を挿入します。 See 節 U.5 テキストの詰め込み。
自動保存(auto-save)モードはバッファの内容を定期的に保存することで、 システムクラッシュが起きたとき紛失してしまう作業の量を少なくします。 See 節 N.5 自動保存、不慮の事故に対する備え。
エンリッチ(enriched)モードは、整形済みテキストの編集を可能にします。 See 節 U.11 整形済みテキストの編集。
フライスペル(flyspell)モードは、 綴りに誤りのある単語を自動的に強調表示します。
フォントロック(font-lock)モードは、コメント、文字列、定義中の関数名などの プログラム中の決まった単位を自動的に強調表示します。 これには、複数のフォントを表示できるウィンドウシステムが必要です。 See 節 Q.13 複数タイプフェイスの利用。
水平スクロール(hscroll)モードは、ポイントが画面内に留まるように、 自動的に水平スクロールを行います。 See 節 J.2 水平スクロール。
ISOアクセント(iso-accents)モードは、``'、`''、 `"'、 `^'、`/'、`~'とこれらに続くつぎの文字を結合して、 ISO Latin-1文字集合のアクセント付き文字を作り出します。 See 節 R.12 1バイトヨーロッパ文字の使い方。
アウトラインマイナ(outline-minor)モードは、メジャーモードである アウトライン(outline)モードと同じ機能を提供します。 しかし、マイナモードなので任意のメジャーモードと一緒に使えます。 See 節 U.8 アウトラインモード(outlineモード)。
上書き(overwrite)モードでは、入力された図形文字は既存の文字を右に押しやる かわりにその文字を置き換えます。 たとえば、ポイントが`FOOBAR'の`B'のまえにあるときに Gを打つと`FOOGAR'となります。 通常のモードであれば`FOOGBAR'となります。 上書き(overwrite)モードでコマンドC-qを打つと、 そのつぎの文字が何であっても(数字であっても)その文字を挿入します。 つまり、上書き(overwrite)モードの中で文字を挿入するには この方法を使います。
バイナリ上書き(binary-overwrite)モードは上書き(overwrite)モードの変形で、 バイナリファイル編集用です。 このモードでは、改行やタブも他の文字と同じに扱われるので、 他の文字をこれらの文字で上書きすることも、 これらの文字を他の文字で上書きすることもできます。
以下で説明するマイナモードは、すべてのバッファに一斉に適用されます。 ただし、これらは変数の値に応じてオン/オフされますから、 その変数をバッファにローカルな変数にすれば、 バッファごとに独立にオン/オフすることも可能です。 See 節 AE.2.4 ローカル変数。
補完示唆(icomplete)モードは、ミニバッファで入力中に補完機能が働いているとき、 どのような補完候補があるかを表示します。 See 節 E.3.4 補完のオプション (2005/03/24)。
行番号(line-number)モードは、 ポイントのある行の行番号を絶えずモード行に表示します。 See 節 B.3 モード行。
ミニバッファリサイズ(resize-minibuffer)モードは、 打ち込んだテキスト量に応じて自動的にミニバッファを広げます。 See 節 E.2 ミニバッファでの編集 (2005/03/24)。
スクロールバー(scroll-bar)モードは、各ウィンドウにスクロールバーを付けます (see 節 Q.11 スクロールバー)。 メニューバー(menu-bar)モードは、各フレームにメニューバーを付けます (see 節 Q.12 メニューバー)。 どちらのモードも、Xウィンドウシステムを使っているときは デフォルトでオンになっています。
暫定マーク(transient-mark)モードでは、 バッファの内容を変更するとマークは『不活性』になるので、 そのあとでリージョンを対象とするコマンドを使うとエラーになります。 つまり、リージョンを対象とするコマンドを使うまえに、 改めてマークを設定するか、不活性になったマークを『再度活性』にします。 暫定マーク(transient-mark)モードの利点は、 (今のところXウィンドウシステムを使っているときのみ) Emacsがリージョンを強調表示することです。 See 節 H.1 マークを設定する (2005/03/20)。
ほとんどのマイナモードには、コマンド名と同じ名前の変数があり、 その変数でモードを直接制御しています。 つまり、その変数の値がnil
以外ならモードはオンであり、 各マイナモードコマンドは変数の値を設定する動作をします。 たとえば、コマンドoutline-minor-mode
は、 変数outline-minor-mode
の値を設定する動作を行います。 つまり、この変数が、直接、上書き(overwrite)モードをオン/オフしているのです。 あるマイナモードがこのように動作するかどうかは、 C-h vを使ってその変数の説明文字列を参照してください。
これらのマイナモード変数は、Lispプログラムからモードを オン/オフするのに有用です。 また、ファイルのローカル変数リストとして指定するのも便利です。 ただし、ローカル変数リストで設定する場合には、よく考えてください。 というのは、ほとんどのマイナモードはユーザーの好みの問題であり、 同じファイルを編集する別のユーザーは好みが違うかもしれません。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
変数は値を持つLispシンボル(記号)です。 そのシンボルの名前のことを、変数名とも呼びます。 変数名はファイルに入れられるどのような文字でも含むことができますが、 習慣的には、変数名は英単語をハイフンでつなげたものです。 変数には、その変数がどのような値を持ち、 どのように使われるかを記述した説明文字列を持たせることができます。
Lispではどの変数にどのような値でも格納できますが、 Emacsの中ではほとんどの変数はどのような値を持つかが決まっています。 たとえば、ある変数はつねに文字列である、別の変数は数値であるといった具合です。 また、「これこれの機能はこの変数がnil
以外のときにオンになる」 といういい方もします。 その場合は、その変数にnil
が格納されているときはその機能はオフですが、 それ以外のどんな値が格納されているときでもその機能はオンになります。 ですが、ある機能をオンにするために使う値として 何か選ばなければなりませんから、t
という値を使うのが習慣です。
Emacsは一般のLispプログラムと同様、 内部で情報を保持するために数多くの変数を使いますが、 ユーザーにとって特に興味深い変数というのは、 もっぱらカスタマイズ向けに用意された変数だといえます。 Emacsは(通常は)そのような変数の値を変更しません。 かわりに、ユーザーが値を設定すると、 その値に応じてさまざまなEmacsコマンドのふるまいを 変更したり制御したりできるのです。 これらの変数のことをユーザーオプションといいます。 ほとんどのユーザーオプションはこのマニュアルに記載してありますし、 変数索引(see 節 変数索引)にも記載してあります。
ユーザーオプションであるような変数の例としてfill-column
があります。 この変数は、詰め込みコマンド(see 節 U.5 テキストの詰め込み)が使う 右端の桁位置を(左端から何文字右かを表す数値として)保持します。
AE.2.1 変数の設定と参照 Examining or setting one variable's value. AE.2.2 簡便なカスタマイズ方法 Convenient and easy customization of variables. AE.2.3 フック Hook variables let you specify programs for parts of Emacs to run on particular occasions. AE.2.4 ローカル変数 Per-buffer values of variables. AE.2.5 ファイルにローカルな変数 How files can specify variable values.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
describe-variable
)。特定の変数の値を見るには、C-h v(describe-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 節 W.9 lisp対話バッファ (2004/08/16)。
変数を設定することは、特記していない限り、 他のカスタマイズ方法と同様に、現在のEmacsセッションだけに影響します。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
変更したいユーザーオプション変数をみつけて値を変更する便利な方法は、 M-x customizeを使うことです。 このコマンドはカスタマイズバッファを作成し、 そのバッファ内では論理的な順序に並べたEmacsのユーザーオプションを 眺めてまわることができますし、さらに値を編集して設定できます。 また、カスタマイズバッファを使えば設定を恒久的なものとして 保存もできます。 (まだこの機能で扱えないユーザーオプションもあるが、 それらも扱えるように現在作業中。)
AE.2.2.1 カスタマイズグループ How options are classified in a structure. AE.2.2.2 オプションの変更 How to edit a value and set an option. AE.2.2.3 フェイスのカスタマイズ How to edit the attributes of a face. AE.2.2.4 特定項目のカスタマイズ Making a customization buffer for specific options, faces, or groups.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
カスタマイズのために、ユーザーオプションをグループに まとめてみつけやすくしてあります。 グループはさらに大きなグループにまとめられていて、 いちばん大きな(すべてのグループを含む)グループは 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]'と記されたアクティブフィールドがあります。 それらを起動すると、そのグループ/オプション/フェイスのみを表示した 通常のカスタマイズバッファが作成されます。 そのバッファで値を設定します。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
カスタマイズバッファでユーザーオプションがどのように見えるか、 例をあげましょう。
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-1かRETで起動するとさまざまな操作を 示すメニューが表示されます。 これらの操作は変数をカスタマイズするうえでとても重要です。
`[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-TAB(widget-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つの特別なコマンド、TABとS-TABは、 カスタマイズバッファ内での移動に役立ちます。 TAB(widget-forward
)はつぎの アクティブ/編集可能フィールドへ移動します。 S-TAB(widget-backward
)は、 1つまえのアクティブ/編集可能フィールドへ移動します。
編集可能フィールドでRETを打つと、 TABと同様につぎのフィールドへ進みます。 なぜそうなっているかというと、編集可能フィールドを 編集し終えると最後にRETを打つ人が多いからです。 編集可能フィールドに改行文字を入るには、 C-oかC-q C-jと打ちます。
オプションを設定すると、その値は現在のEmacsセッションだけに有効です。 その値を保存すると、将来のセッションでも有効になります。 保存を行うと、個人の`~/.emacs'ファイルにコードが追加されて、 つぎにEmacsを起動したときにオプション変数の値を設定するようになります。 オプションを保存するには、`[State]'を起動して `Save for Future Sessions'を選びます。
オプションを標準値に戻したければ、`[State]'を起動して `Reset to Standard Settings'を選びます。 実際にはつぎの3種類のリセット操作があります。
グループの`[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]'を起動すると、カスタマイズバッファを消します。 他のフィールドは、そのバッファに含まれている項目それぞれについてそれぞれ、 設定、保存、リセットを(それらの操作が適用可能なら)実行します。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
いくつかのカスタマイズグループは、 ユーザーオプションに加えてフェイスも含みます。 グループの内容を表示したとき、 オプションとフェイスの両方がカスタマイズバッファに現れます。 フェイスの見え方は、たとえばつぎのようになります。
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 節 AE.2.2.2 オプションの変更)。
フェイスでは、ディスプレイの種別ごとに異なる見え方を指定できます。 たとえば、あるフェイスをカラーディスプレイでは赤で表示し、 白黒ディスプレイではかわりにボールド体で表示するようにできます。 あるフェイスに複数の見え方を指定するには、 `[State]'メニューを表示させて`Show Display Types'を選びます。
フェイスの属性を設定するもっと基本的な方法は、 M-x modify-faceを使うことです。 このコマンドは、まずフェイスの名前を聞いてきて、 続いて属性を1つずつ順に聞いてきます。 表示色やパターンの属性では、その属性の現在の値がデフォルトになっています。 これらを変更したくなければ、単に、RETを打てばよいのです。 属性を空にしたければ`none'と打ちます。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
グループ構造を1段ずつ降りていって目指すオプションを探すかわりに、 カスタマイズしたいオプション/フェイス/グループの名前を 直接に指定することもできます。
名前のわかっているオプション変数をカスタマイズバッファで変更したい場合は、 コマンド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を使います。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
フックとはある特定の状況で既存のプログラムから呼び出される 関数/関数群を格納しておく変数をいいます。 Emacsには、カスタマイズ用のフックが数多くあります。
Emacs中のほとんどのフックはノーマルフックです。 これらの変数は、引数なしで呼び出される関数のリストを保持します。 ほとんどのフックがノーマルフックなのは、それらを統一的に扱えるからです。 Emacsでは、`-hook'で終わる名前の変数はすべてノーマルフックです。
ほとんどのメジャーモードは初期設定の最終段階でフックを実行します。 モードが設定したローカル変数をフックで変更すればよいので、 モードのふるまいをユーザーがカスタマイズすることが容易になります。 しかし、フックはそれ以外の場面でも使われます。 たとえば、suspend-hook
は、Emacsが休止する直前に実行されます (see 節 C.1 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)))) |
どの順番で実行されても大丈夫なようにフック関数を設計するのが最良です。 実行順序に依存するのは、『事故を呼び込む』ようなものです。 しかし、順番は予測できます。 もっとも最近に追加したフック関数ほど先に実行されます。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
ほとんどの変数はEmacsバッファに対してローカルにできます。 つまり、その変数のバッファ中での値は他のバッファでの値とは 独立になります。 いくつかの変数はつねにすべてのバッファにおいてローカルです。 それ以外の変数はすべて、グローバルな値、 つまりその変数をローカルにしていないすべてのバッファにおいて 共有される値を持ちます。
M-x make-local-variableは変数名を受け取り、 その変数をカレントバッファにおいてローカルにします。 それ以降、このバッファ内でその変数を変更しても 他のバッファには影響しませんし、 その変数のグローバルな値を変更してもこのバッファ内での値には影響しません。
M-x make-variable-buffer-localは、変数名を受け取り、 値が設定されるとその変数が自動的にローカルになるようにします。 もっと正確にいえば、このように特別な印を変数に付けておくと、 通常の方法で変数に値を設定するときにはつねにまず make-local-variable
が実行されるようになるのです。 このような変数をバッファごとの変数と呼びます。
メジャーモード(see 節 S. メジャーモード (2005/03/20))では、 変数を設定するまえにつねにローカルにします。 このため、あるバッファでメジャーモードを変更しても 他のバッファには影響が及びません。 マイナモード(see 節 AE.1 マイナモード(minor mode))も同様で、通常、 マイナモードごとにオン/オフを制御する変数があり、 その変数がnil
以外のときにそのマイナモードはオンになります。 ほとんどのマイナモードでは、その制御用変数はバッファごとの変数です。
Emacsには、つねにバッファごとの変数であるような変数が数多くあります。 abbrev-mode
、auto-fill-function
、case-fold-search
、 comment-column
、ctl-arrow
、fill-column
、 fill-prefix
、indent-tabs-mode
、left-margin
、 mode-line-format
、overwrite-mode
、 selective-display-ellipses
、selective-display
、 tab-width
、truncate-lines
がそのような変数です。 これ以外にもつねに各バッファでローカルな変数はありますが、 それらは内部作業用の変数です。
いくつかの変数はディスプレイに対してローカルになっているため、 バッファに対してローカルにはできません (see 節 Q.8 複数ディスプレイ)。 これらの変数をバッファにローカルにしようとすると、 エラーメッセージが表示されます。
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) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
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 節 R.7 コーディングシステム。
一方、ローカル変数リストはファイルの末尾(最後のページ)に置きます。 (最後のページにはローカル変数リストだけを置くというのを勧めます。) ローカル変数リストは`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-start
とcomment-end
のローカルな値で、 このような変な構文に対処するようにEmacsをカスタマイズするのです。 必要ないのであれば、接頭辞(と接尾辞)は使わないでください。
ローカル変数リストにおいては、2つの変数名が特別な意味を持ちます。 変数mode
に対する値は、実際にはメジャーモードを設定します。 変数eval
に対する値は、式として評価されますが、 その結果は捨てられます。 mode
とeval
は本当の変数ではなく、他の状況で これらの名前の変数に値を設定してもなんら特別な意味を持ちません。 メジャーモードを設定するためにmode
を指定する場合は、 ローカル変数リストの先頭に書く必要があります。
仮想的な『変数』mode
は、メジャーモードだけでなくマイナモードを 設定するのにも使えます。 実は、この指定は2回以上使うことができて、 最初はメジャーモードを設定し、 それ以降は(それぞれ)マイナモードを設定します。 しかし、マイナモードはユーザーの好みに応じて選ぶものですから、 普通はファイルでマイナモードを指定するべきではないでしょう。
たとえば、ローカル変数リストで自動詰め込み(auto-fill)モードをオンにしたいと 思うかもしれませんが、それはまちがいです。 自動詰め込みにするかどうかは、個人の好みの問題であり、 ファイルの中身によって決まるものではないからです。 ある種別のファイルでいつも自動詰め込みにしたければ、 個人の`.emacs'ファイルで(状況に応じて)自動詰め込み(auto-fill)モードを オンにするようなメジャーモードのフックを設定してください (see 節 AE.6 初期化ファイル`~/.emacs')。 ローカル変数リストで他人に好みを押し付けてはいけません。
ローカル変数リストは、ファイルの末尾から3000文字以内にある必要があり、 ファイルがページに分かれている場合には最後のページにある必要があります。 これらが守られていないと、 Emacsはローカル変数リストがあることを認識しません。 これらの規則の目的は、最後ではないページに偶然 `Local Variables:'があってもEmacsが誤認しないようにすることと、 全体が1ページでローカル変数リストを持たない長いファイルを訪問するときでも ファイル全体を探さなくてもすむようにするためです。
バッファのローカル変数やメジャーモードを、 ローカル変数リストがあるときにはそれによる指定も含めて、 ファイル名とファイルの内容に基づいたものにリセットしたければ、 normal-mode
コマンドを使ってください。 See 節 S.1 メジャーモードの選択方式 (2005/03/20)。
変数enable-local-variables
は、 ファイル中のローカル変数指定を処理するか否かを制御します。 つまり、ローカル変数指定を無視するようにもできます。 デフォルトはt
で、ファイル中のローカル変数指定を処理します。 値をnil
にすると、ファイル中のローカル変数指定を無視します。 これら以外の値の場合は、ファイル中にローカル変数指定があると、 その内容を表示して処理するかどうか問い合わせます。
仮想的な『変数』eval
といくつかの(実在する)変数に対する指定は、 ある種の危険性をもたらします。 他人のファイルを訪問したとき、そこに書かれているローカル変数指定に よってあなたが使っているEmacsのふるまいがどのようにでも変更できるからです。 このため、オプションenable-local-eval
により、 変数eval
、さらに、`-hook'、`-hooks'、`-function'、 `-functions'という名前で終る変数、および、他のいくつかの変数に 対するローカル変数指定を処理するかどうか制御できるようになっています。 enable-local-variables
と同じように指定できる値は3種類あって、 t
、nil
、これら以外です。 デフォルトはmaybe
で、これはt
でもnil
でもありませんから、 Emacsはこれらのローカル変数指定があるときは確認を求めてきます。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
本節では、コマンドをキーに対応付けるキーバインディングと、 キーバインディングを記録するキーマップについて説明します。 また、キーバインディングをカスタマイズする方法についても説明します。
コマンドとは、対話利用向けに定義されたLisp関数で あることを思い出してください。 コマンドには、他のLisp関数と同様、通常、英小文字とハイフンから成る 関数名前が付いています。
AE.3.1 キーマップ Generalities. The global keymap. AE.3.2 プレフィックスキーマップ Keymaps for prefix keys. AE.3.3 ローカルキーマップ Major and minor modes have their own keymaps. AE.3.4 ミニバッファのキーマップ The minibuffer uses its own local keymaps. AE.3.5 キーバインディングの対話的な変更 How to redefine one key's meaning conveniently. AE.3.6 初期化ファイルでのキーの変更 Rebinding keys with your init file, `.emacs'. AE.3.7 ファンクションキーの再定義 Rebinding terminal function keys. AE.3.8 名前の付いたASCIIコントロール文字 Distinguishing TAB from C-i, and so on. AE.3.9 キーボード上の非ASCII文字 Rebinding non-ASCII characters such as Latin-1. AE.3.10 マウスボタンの再定義 Rebinding mouse buttons in Emacs. AE.3.11 使用禁止コマンド Disabling a command means confirmation is required before it can be executed. This is done to protect beginners from surprises.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
キー列とコマンド関数との対応はキーマップと呼ばれる データ構造に保持されています。 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までのファンクションキーも ユーザー定義のために予約してあります。 これ以外のキー列を再定義すると、 同じキーを再定義する拡張やメジャーモードによって あなたの定義が上書きされてしまう可能性があります。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
C-xやESCのようなプレフィックスキーは それぞれ専用のキーマップを持っていて、 そこにはそのプレフィックスキーに続くイベントの定義が保持されています。
プレフィックスキーの定義は、通常、それに続くイベントの定義を検索するための キーマップです。 あるいは、プレフィックスキーの定義がLispシンボルであって、 その関数の定義がキーマップというのもあります。 どちらでも効果は同じですが、 後者では、プレフィックスキーにコマンド名を与えてその用途を示すことができます。 このため、C-xにバインドされているのは シンボルCtl-X-Prefix
であり、 その関数定義はC-xコマンド群に対応するキーマップです。 C-c、C-x、C-h、ESCは グローバルマップでプレフィックスキーとして定義されていますから、 これらはつねにプレフィックスキーとして使用できます。
通常のプレフィックスキーに加えて、 メニューバーを表す『仮想的なプレフィックスキー』があります。 メニューバーのキーバインディングに関する特別な点については Emacs Lisp リファレンスマニュアルを参照してください。 ポップアップメニューを表示させるマウスボタンイベントもまた、 プレフィックスキーです。 こちらの詳細については Emacs Lisp リファレンスマニュアルを参照してください。
決まった変数に格納されているプレフィックスキーマップもあります。
ctl-x-map
はC-xに続くキーを探すためのマップを納めた変数名。help-map
はC-hに続くキーを探すためのマップを納めた変数名。esc-map
はESCに続くキーを探すためのマップを納めた変数名。 つまり、すべてのメタ文字は実際にはこのマップで定義されている。ctl-x-4-map
はC-x 4に続くキーを探すためのマップを納めた変数名。mode-specific-map
はC-cに続くキーを探すためのマップを納めた変数名。[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
これまではグローバルキーマップの諸側面について説明しました。 メジャーモード固有のキーバインディングを ローカルキーマップに定義することで、 各メジャーモードは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 nとC-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 節 AE.2.3 フック。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
ミニバッファも一群の専用ローカルキーマップを持っています。 それらには各種の補完や脱出コマンドが定義されています。
minibuffer-local-map
は通常の入力に使われる(補完なし)。minibuffer-local-ns-map
も同様。 ただし、SPCは、RETと同様に、脱出動作である。 これは主にMocklispとの互換性のために使われる。minibuffer-local-completion-map
は弱い補完に使われる。minibuffer-local-must-match-map
は強い補完と慎重な補完に使われる。[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsのキーを再定義するには、キーマップの対応する項目を 変更すればよいのです。 グローバルキーマップを変更すると、その変更は (同じキーに対して独自のローカルな定義をしているメジャーモードを除く) すべてのメジャーモードに影響します。 あるいは、カレントバッファのローカルマップを変更すると、 同じメジャーモードを使っているすべてバッファに影響が及びます。
たとえば、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を使います。 本書のキーの説明にもコマンド名を掲載してあります。
まちがって、あるコマンドを実行することを防ぎたければ、 キーを未定義にするのでなく、コマンドを使用禁止にするのがよいでしょう。 必要になったときに使用禁止コマンドを起動するのは造作もありません。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
いつでもあるキーバインディングを設定しておきたければ、 その指定を個人の`.emacs'ファイルにLispのコードとして書いておきます。
これを行うもっとも簡単な方法は、 ASCII文字とメタ修飾付きのASCII文字に対してのみ使えます。 たとえば、C-zをshell
にバインドするにはつぎのようにします。
(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) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
キー列には通常の文字以外にもファンクションキーを含めることができます。 キーボードの文字が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
これらの名前は習慣的なものですが、システムによっては (とりわけXウィンドウシステムを使っている場合は)、 別の名前になっている場合があります。 あるファンクションキーにどのシンボルが対応しているか調べるには、 C-h cに続いてそのキーを打鍵してください。
ファンクションキーのシンボルを含むキー列(あるいは、 ASCII以外の文字を含むもの)は文字列ではなくベクタで指定してください。 ベクタの構文では要素と要素のあいだは空白で区切り、 全体を中括弧``[...]''で囲みます。 たとえば、ファンクションキー`f1'をコマンドrmail
にバインドするには、 つぎのようにします。
(global-set-key [f1] 'rmail) |
右矢印キーをコマンドfowared-char
にバインドするには、 つぎのようにします。
(global-set-key [right] 'forward-char) |
これは、シンボルright
を要素とするベクタのLisp構文です。 (このバインディングはEmacsのデフォルト設定に入っている。)
ベクタを用いたキーの再定義ついてより詳しくは、See 節 AE.3.6 初期化ファイルでのキーの変更。
キー列の中でファンクションキーと文字を混ぜることができます。 以下の例は、 C-x NEXTをコマンドforward-page
にバインドしています。
(global-set-key [?\C-x next] 'forward-page) |
ここで、?\C-x
はLispの文字定数で、文字C-xを表します。 ベクタのもう1つの要素であるnext
は、シンボルですから`?'は不要です。
ファンクションキーに対して、修飾キーCTRL、META、HYPER、 SUPER、ALT、SHIFTを指定できます。 これらの修飾キーを指定するには、シンボル名のまえに`C-'、 `M-'、`H-'、`s-'、`A-'、`S-'を付けてください。 たとえば、Hyper-Meta-RIGHTで 1語先へ移動するにはつぎのように指定します。
(global-set-key [H-M-right] 'forward-word) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
TAB、RET、BS、LFD、ESC、DELは もともとASCIIの特定のコントロール文字に対応していたのですが、 よく使われるため別にそれ専用のキーを持つようになりました。 のちに人々はEmacsでこれらのキーとそれらと『同じ』文字を CTRLキーと組み合わせて打鍵した場合とを区別できると 便利だと気がつきました。
EmacsではXウィンドウシステムを使っている場合、 これら2種類の入力を区別します。 つまり、キーボード上の特殊キーの方はtab
、return
、 backspace
、linefeed
、escape
、 delete
という名前のファンクションキーとして扱うのです。 これらのファンクションキーは、もしそれ固有のバインディングが 指定されていなければ、自動的に対応するASCII文字に変換されます。 その結果、特にこの2種類を区別したいと思わない限りは、 ユーザーもLispプログラムもこれらの区分について気にする必要はありません。
(たとえば)TABとC-iを区別したくないなら、 ASCII文字TAB(8進コード011)に対応するバインディング1つだけを 指定してください。 区別したいのなら、このASCII文字に対するバインディングに加えて、 『ファンクションキー』tab
に対するバインディングも指定します。
通常のASCII端末では、TABとC-i (および上記の対応する組のそれぞれ)を区別する方法はありません。 というのは、端末はどちらが押されても同じ文字を送出するからです。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
アクセント付き文字などの非ASCII文字を送出するキーがあるキーボードでは、 それらのキーの再定義には、少々トリックが必要です。 2つの解決方法があります。 1つめは、set-keyboard-coding-system
(see 節 R.9 コーディングシステムの指定)を 使って、キーボードのコーディングシステムを指定することです。 そうすれば、つぎのように書いて、 通常の方法でそれらのキーを再定義できます。
(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) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
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
1つのキー列の中に2つ以上のマウスボタンイベントを含めることもできますが、 普通はあまりしないでしょう。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
コマンドを使用禁止にすると、コマンドの実行にはユーザーの確認が必要になります。 コマンドを使用禁止にする目的は、 初心者がそのコマンドをまちがって実行してしまい、混乱するのを防ぐためです。
Emacs上で使用禁止コマンドを対話的に実行しようとすると、 コマンド名、説明文、とりあえずどうすべきかの指示を 表示したウィンドウが現れます。 つぎにEmacsはコマンドを実行するか、使用禁止を解除してから実行するか、 実行を取り消すかを問い合わせてきます。 コマンドの使用禁止を解除することを選ぶと、 Emacsさらに、以後恒久的にそうするのか、 または現在のセッション内だけそうするのかも問い合わせてきます。 恒久的に使えるようにすると、 自動的に個人の`.emacs'ファイルを編集します。
コマンドを使用禁止にする機構は、 コマンドに対応するLispシンボルの属性disabled
に nil
以外の値を設定することです。 これを行う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 節 AE.6 初期化ファイル`~/.emacs'。
コマンドが使用禁止であるかどうかは、 そのコマンドを起動するキー列には無関係です。 したがって、M-xでそのコマンドを起動しても Emacsはその可否を問い合わせてきます。 Lispプログラムからコマンドを関数として呼び出す場合には 使用禁止にしても何の効果もありません。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
キーボードの機種によっては、Emacsが使用するすべての特殊文字を 送ってくれないものがあります。 もっともよくある問題は、DEL文字に関するものです。 いくつかのキーボードでは、 このきわめて重要な文字を簡単に打ち込む手段がありません。 それは、削除にはC-hを使うことを前提としているからです。 そのようなキーボードで削除のためのキーを打つと、 Emacsはそれをプレフィックス文字C-hとして解釈し、 どのヘルプ機能を使うか問い合わせてきてしまいます。 それはユーザーがしたかったことではありません。
Emacs内でこの問題を回避するには、C-hをDELに、 DELをC-hに変換するキーボード変換を 以下のように 設定することで回避できます。
;; C-hをDELに変換する。 (keyboard-translate ?\C-h ?\C-?) ;; DELをC-hに変換する。 (keyboard-translate ?\C-? ?\C-h) |
キーボード変換はキーマップによるキーバインディング(see 節 AE.3.1 キーマップ)と 同じではありません。 Emacsには状況ごとに使い分けられる多数のキーマップがあるのに対し、 キーボード変換は一式だけしかなく、 Emacsが端末から読むすべての文字に対してその変換が適用されます。 キーボード変換は入力処理のいちばん下位のレベルで行われ、 キーマップ上の検索はキーボード変換を施した結果に対して行われます。
XウィンドウシステムではDELETEというキーはファンクションキーであり、 ASCII文字DELとは別ものです。 See 節 AE.3.8 名前の付いたASCIIコントロール文字。 キーボード変換はASCII文字入力だけに適用され、 ファンクションキーとは無関係ですから、 Xウィンドウシステムでは上の例はDELETEキーに対して効果をもたらしません。 しかし、Xウィンドウシステムでは上のようなキーボード変換そのものが不要です。 というのは、EmacsはXウィンドウシステムでは BACKSPACEキーとC-hも区別でき、 通常、BAKSPACEをDELとして扱うからです。
キーボード変換の使い方に関する詳しい情報は、 Emacs Lisp リファレンスマニュアルを 参照してください。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
単語や対応した括弧の対を認識するEmacsコマンドはすべて、 構文テーブル(syntax table)によって制御されます。 構文テーブルは、どの文字が開き括弧で、どの文字が単語の中身で、 どの文字がシングルクォートかといったことを記述しています。 各メジャーモードにはそれぞれ専用の構文テーブルがあり (ただし、互いに関係のあるメジャーモードが 1つの構文テーブルを共用することはある)、 各バッファごとにそのときのメジャーモードの構文テーブルが使われます。 カレントバッファに設定されている構文テーブルはすべてのコマンドが使うので、 以下ではこれを『現在の』構文テーブルと呼びます。 構文テーブルは文字テーブル(char-table)型のLispオブジェクトであり、 その要素は数値です。
現在の構文テーブルの内容に関する記述を表示するには、 C-h s(descirbe-syntax
)を使います。 記述の表示には各文字ごとに、 その文字の現在の構文を設定するためにmodify-syntax-entry
に 渡すべき文字列、および、その文字列の英語での説明が含まれます。
構文テーブルに関する詳しい情報については、 Emacs Lisp リファレンスマニュアルを 参照してください。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsが実行を開始するとき、通常はユーザーのホームディレクトリにある ファイル`.emacs'や`.emacs.el'からLispプログラムをロードします。 このファイルがEmacsの初期化の仕方を指定するので、 このファイルのことを初期化ファイル(init file)と呼びます。 コマンド行オプション`-q'で、 Emacsに初期化ファイルを読まないことを指示したり、 `-u'(あるいは`--user')で、 別のユーザーの初期化ファイルを指定できます (see 節 C. Emacsの起動と終了)。
デフォルトの初期化ファイルもあります。 これは`default.el'という名前のライブラリファイルで、 Emacsはライブラリ探索パスをとおしてその場所を探します。 Emacsの配布には`default.el'は含まれていません。 ローカルなカスタマイズのためにサイトで`default.el'を 用意することもあります。 このファイルがあれば(`-q'を指定したときを除いて) Emacsを開始するときつねにロードされます。 しかし、あるならば個人の初期化ファイルが最初にロードされます。 その中でinhibit-default-init
にnil
以外の値を設定すると、 `default.el'はロードされません。
各サイトにはサイトスタートアップファイルがあるかもしれません。 あるならば、このファイルの名前は`site-start.el'です。 Emacsはユーザーの初期化ファイルを読むまえにこのファイルもロードします。 このファイルのロードを抑止するには、 オプション`-no-site-file'を指定します。
`.emacs'に大量のコードがある場合には、 `~/.emacs.el'と改名してバイトコンパイルしておくべきです。 Emacs Lispプログラムのコンパイルについてより詳しくは、 See Emacs Lisp リファレンスマニュアル。
単なるカスタマイズを超えるような実際のEmacsプログラムを書くのであれば、
AE.6.1 初期化ファイルの構文 Syntax of constants in Emacs Lisp. AE.6.2 初期化ファイルの例 How to do some things with an init file. AE.6.3 端末に固有の初期化 Each terminal type can have an init file. AE.6.4 個人の初期化ファイルの探し方 How Emacs finds the init file.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
ファイル`.emacs'にはLispの関数呼び出し式を書きます。 関数呼び出しは、関数名に続けて引数リストを並べ、全体を括弧で囲みます。 たとえば、(setq fill-column 60)
は、 関数setq
によって、変数fill-column
(see 節 U.5 テキストの詰め込み)に 60を設定します。
setq
の2番目の引数は変数の新しい値を表す式です。 これは、定数でも、変数でも、関数呼び出し式でもかまいません。 `.emacs'ファイルでは定数を使うことがもっとも多いでしょう。 定数にはつぎのものがあります。
文字列の中には、改行や特殊文字をそのまま入れることができる。 しかし、バックスラッシュで始まる形式、つまり、 改行は`\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を表す。
?x
、?\n
、?\)
などは文字定数。 Lispでは文字と文字列は別ものなので注意すること。 ある場面では文字列が必要であり、別の場面では文字が必要である。
t
は「真」を表す。
nil
は「偽」を表す。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
以下にはよく使われるLispの式の例をあげておきます。
(setq c-tab-always-indent nil) |
変数の値を「真」にするにはt
を設定し、 逆に「偽」にするにはnil
を設定する。
(setq-default case-fold-search nil) |
ここではsetq-default
で変数のデフォルト値を設定し、 その変数に対してローカルな値を設定していないすべてのバッファで有効である。 setq
でcase-fold-search
に値を設定すると、 カレントバッファのローカルな値だけに影響し、 初期化ファイルで記述したいこととは異なるだろう。
(setq user-mail-address "[email protected]") |
メイルアドレスを必要とする多くのEmacsパッケージは、 user-mail-address
の値を使う。
(setq default-major-mode 'text-mode) |
text-mode
を指定しているのは、 これがテキストモードに入るためのコマンドだから。 コマンド名のまえのシングルクォートは、シンボルを定数として扱うため。 さもないとtext-mode
という変数を参照することになってしまう。
(set-language-environment "Latin-1") |
(add-hook 'text-mode-hook '(lambda () (auto-fill-mode 1))) |
これはノーマルフック変数(see 節 AE.2.3 フック)にフック関数を追加する例。 ここでは関数としてlambda
で始まるリストを指定し、 シングルクォートを前置して式ではなく定数として扱わせる。
Lispの関数について説明するのは本書の範囲外だが、 この例を理解するには、テキストモードに入るときに (auto-fill-mode 1)
が実行されるのだと考えておけば十分。 この式を別の式に変えたり、式を複数並べてもかまわない。
Emacsにはturn-on-auto-fill
という関数が用意されており、 その定義は(lambda () (auto-fill-mode 1))
になっている。 したがって、上の例をもっと簡単に書くとつぎのようになる。
(add-hook 'text-mode-hook 'turn-on-auto-fill) |
(load "foo") |
load
に渡す引数が相対ファイル名、つまり、 `/'や`~'で始まらない場合には、 load
はload-path
(see 節 W.7 Emacs用のLispコードのライブラリ (2004/08/16))の ディレクトリ群を順に探索する。
(load "~/foo.elc") |
ここでは絶対ファイル名が使われているので、探索は行わない。
make-symbolic-link
が実行されるように バインディングを設定する。
(global-set-key "\C-xl" 'make-symbolic-link) |
または
(define-key global-map "\C-xl" 'make-symbolic-link) |
ここでもシンボルmake-symbolic-link
を変数としての値ではなく 定数とするためにシングルクォートが使われていることに注意。
(define-key lisp-mode-map "\C-xl" 'make-symbolic-link) |
next-line
を 実行するようになっているすべてのキーを、 かわりにforward-line
を実行するように直す。
(substitute-key-definition 'next-line 'forward-line global-map) |
(global-unset-key "\C-x\C-v") |
キーを未定義にする必要のある場合の1つとして、 そのキーをプレフィックスにしたい場合がある。 たとえば、C-x C-v anythingを定義すると、 C-x C-vは自動的プレフィックスになるが、 しかしそのまえにC-x C-vの通常の(プレフィックスではない)定義を 未定義に戻しておく必要がある。
(modify-syntax-entry ?\$ "." text-mode-syntax-table) |
narrow-to-region
を確認なしに使えるようにする。
(put 'narrow-to-region 'disabled nil) |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
各端末種別ごとに、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-prefix
を nil
に設定すると端末ライブラリのロードを抑止できます。
Emacsは`.emacs'と端末ライブラリを読んだあと、 初期化の最後にフックterm-setup-hook
を実行します。 端末ライブラリによる指定を一部変更したり、 端末ライブラリがない端末の初期設定を行いたければ、 このフックにフック関数を追加してください。 See 節 AE.2.3 フック。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
通常、Emacsは環境変数HOME
に基づいて`.emacs'を探し、 ファイル名の`~'の意味を定めます。 しかし、su
を実行したあとでは、Emacsは(su実行前の) もとのユーザーの`.emacs'を読もうとし、 suした先のユーザーのではありません。 これは、たとえスーパーユーザーになっているとしても、 本来のユーザー独自のエディタのカスタマイズを使うべきだと考えるからです。
より正確には、Emacsはまずどのユーザーの初期化ファイルを使うかを決めます。 それにはまず環境変数LOGNAME
およびUSER
からユーザー名を取得します。 これらの環境変数がみつからなければ、Emacsは実効ユーザーIDを参照します。 ユーザー名と実ユーザーIDが一致すれば、EmacsはHOME
を利用します。 一致しない場合は、システムのユーザーデータベースから そのユーザー名に対応するホームディレクトリを探して使用します。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
abort-recursive-edit
)。keyboard-escape-quit
)。undo
)。実行を完了していないコマンドを取り消すには、2つの方法があります。 1つはC-gで中断すること、 もう1つはC-]やM-x top-levelで アボートすることです。 中断とは、打鍵途中のコマンドや動作中のコマンドを取り消すことをいいます。 アボートとは、再帰編集レベルから抜け出し、かつ、 その再帰編集レベルを起動したコマンドを取り消すことをいいます (see 節 AD.24 再帰編集レベル (2005/05/07))。
C-gでの中断は、打鍵途中のコマンドや 不要な数引数を打ってしまったときにとりやめるのに使います。 また、実行途中のコマンドを比較的安全な方法で止めますから、 長時間かかるコマンドをうっかり始めてしまったときにも使えます。 特に、キル操作を中断しても安全です。 テキストは、まだすべてバッファ内にあるか、 または、すべてキルリングに入っている (あるいは、その両方に入っている)からです。 なお、インクリメンタルサーチを中断する場合には、 文字列探索のところで説明してあるように、特別な動作を行います。 一般には、サーチから抜け出すにはC-gを2回連打する必要があります (see 節 K.1 インクリメンタルサーチ (2004/03/26))。
MS-DOSでは、C-BREAKはC-gと同様に中断として働きます。 MS-DOSでは、コマンドの実行中にユーザーとのやりとりを行う状態にないときには、 C-gを検出できないからです。 これに対して、C-BREAKはつねに認識できます。 See 節 AJ.1 MS-DOSのキーボードとマウス (2005/05/08)。
C-gはつぎのように動作します。 C-gが打鍵されると変数quit-flag
にt
が設定されます。 Emacs Lispはこの変数を頻繁に調べ、値がnil
以外だと中断処理を行います。 C-gが実際にコマンドとして実行されるのは、 Emacsが入力待ち状態にあるときにC-gを打った場合だけです。この場合, keyboard-quit
が実行されます.
最初のC-gが認識されないうちに2つめのC-gを打って中断すると、 『緊急脱出』機能を発動したことになりシェルに戻ります。 See 節 AE.8.8 緊急脱出。
中断できない場合もありえます。 Emacsがオペレーティングシステムに何かを頼んで待っているときには、 待ち状態を起こしたシステムコールを使ったEmacs側で特別な手当てをしない限り 中断できません。 Emacsでは、ユーザーが中断しそうなシステムコールには 手当てを施してありますが、手当てしていない場所を叩く可能性はあります。 よくあるのは、NFS経由の入出力を待っているときです。 Emacs側ではこれを中断する方法はわかっているのですが、 多くのNFSの実装では、NFSサーバーが固まったときにユーザープログラムが NFSの待ちを中断することを許していないのです。
C-]によるアボート(abort-recursive-edit
)は、 再帰編集レベルから脱出し、かつ、その再帰編集レベルを 起動したコマンドを取り消すのに使います。 C-gによる中断はこのような目的には使えませんし、 このようなことはできません。 というのは、C-gは、ある再帰編集レベルの中で 打ちかけたコマンドを取り消すのに使うからです。 どちらの操作も必要なものです。 たとえば、再帰編集中に数引数を入力しようとしてC-u 8と打鍵した場合、 C-gで数引数を取り消しても再帰編集に留まったままです。
コマンドESC ESC ESC (keyboard-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 節 AD.24 再帰編集レベル (2005/05/07)。
C-x u(undo
)は、正確にいえばコマンドを 取り消すわけではありませんが、 動作を完了してしまったコマンドを取り消すものと考えることができます。 詳しくは See 節 D.4 変更をアンドゥする(もとに戻す) (2004/03/28) を参照してください。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
本節では、Emacsが正常に動作し損なうさまざまな条件と、それらの見分け方、 直し方について説明します。発生しうる問題についてはEmacsに付属している GNU Emacs FAQ やファイル `etc/PROBLEMS' を参照し てください.FAQはC-h F,`PROBLEMS'ファイルはC-h P で読むことが できます.
AE.8.1 DELで削除できない (2004/03/29) What to do if DEL doesn't delete. AE.8.2 再帰編集レベル `[...]' in mode line around the parentheses. AE.8.3 画面上のゴミ (2004/03/29) Garbage on the screen. AE.8.4 テキスト内のゴミ Garbage in the text. AE.8.5 自発的なインクリメンタルサーチの開始 Spontaneous entry to incremental search. AE.8.6 メモリ不足 (2004/03/29) How to cope when you run out of memory. AE.8.7 クラッシュからの回復 Recovering editing in an Emacs session that crashed. AE.8.8 緊急脱出 Emergency escape--- What to do if Emacs stops responding. AE.8.9 いらいらしたら… When you are at your wits' end.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
大抵のキーボードにはEmacs外で最後に入力した文字を消すためのキーとしてRET や ENTER キーの上あたりにあるキーがあります.このキーを本書では 通常 削除キー(the usual erasure key) と呼びます.端末上のEmacsはそのキーをDEL キーと同じものとみなし,DELに変換します.
Emacs が起動する時にウィンドウシステムを利用していると,自動的にDELとして 扱うべきキーを決定します.しかし,ある環境ではシステムから誤った情報を受け取って しまいます.通常削除キーが後ではなく前の文字を消すようであれば,DELETE キー を DEL として扱うように設定しなければなりません.
ウィンドウシステムでは通常削除キーはBACKSPACEと印字されており,他に DELETEキーもあります.しかし,DELETEキーは前ではなく後の文字を削除し ます.もし逆の動作になっているようであれば,Emacsが判断を誤っています. BACKSPACE キーを DELキーとして扱うようにしなければなりません.
テキスト端末で,通常削除キーが文字を削除するかわりに,Control-hのようにヘ ルプを表示するようであれば,そのキーは実際にはBSを送っていることになります. つまり,EmacsはBSをDELとして扱うべきなのです.
こういった場合,当面の問題は同じです.そのため,M-x normal-erase-is-backspace-mode が利用できます.このコマンドは2つのモードを切り 替えることができます.もしEmacsが誤ったモードで起動していれば,DELを扱うモー ドにすることで,正しいモードに切り替えることができます.テキスト端末で,BS が DEL として扱われているかどうかを確認したければ, F1 (C-? も 動作するかもしれません)を利用して,127 になっていることを確認します. sends character code 127.
Emacsを起動時に自動的に問題を修正するためには,以下の行を `.emacs'ファイル (see 節 AE.6 初期化ファイル`~/.emacs') に追加します.最初の例ではDELETEが後ではなく前の文字を 消す場合にDELETE を DEL として扱うようにします (Emacs20以前と同じ動 作になります).
(normal-erase-is-backspace-mode 0) |
他の2例では,BACKSPACEをDELとして扱うべきなため,以下を利用します.
(normal-erase-is-backspace-mode 1) |
Emacsを起動時に問題を修正する他の方法として,変数 normal-erase-is-backspace
をカスタマイズする方法があります.t
であ れば,BS や BACKSPACE を DELとみなし, nil
であれば逆に なります.See 節 AE.2.2 簡便なカスタマイズ方法.
ウィンドウシステムではBACKSPACEと印字されたキーが通常削除キーであり,他に DELETE キーも存在し,両方ともが前の文字を削除するということも起こります. これがおそらく誰(何)かが BACKSPACE キーを DELETE としちぇ再定義した ためです.Xウィンドウシステムではサーバを起動したりログインしたりすると, xmodmap
によってなされます.この現象を引き起こしているのは古いバージョン のEmacsをサポートすることです.だから,古いバージョンは削除することをお勧めしま す.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
再帰編集レベルはEmacsの重要で有用な機能ですが、 それについて理解していない人にとっては、誤動作に見える可能性があります。
モード行のメジャー/マイナモード名を囲む丸括弧の周囲に中括弧 `[...]'が表示されているときは、再帰編集レベルに入っています。 意図してそうしたのでなかったり、 再帰編集レベルの意味を理解していないのであれば、 再帰編集レベルから抜け出すべきです。 それにはM-x top-levelと打ちます。 これをトップレベルへの抜け出しと呼びます。 See 節 AD.24 再帰編集レベル (2005/05/07)。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
画面上のデータがまちがっているように見えたら、まず最初にすべきことは、 テキストが本当にまちがっているのかどうか調べることです。 C-lと打って画面全体を再描画します。 これで画面が正しそうになるのなら、問題は画面更新にあったのです。 (そうでない場合は、後の章を参照してください)。
画面更新の問題は、 使っている端末に対応するtermcapの定義がまちがっている場合が多いです。 Emacsの配布に含まれるファイル`etc/TERMS'には、 この種の問題で既知のものに対する修正が入っています。 ファイル`INSTALL'には、 この種の問題に対する一般的なアドバイスの節があります。 いちばんありがちなのは、 ある種の画面操作に対するパディング (59) が不足している場合です。 この種の問題があるかどうか調べるには、 他のメーカ製の別の端末でEmacsを動かしてみてください。 ある機種の端末では頻繁に問題が起きるのに別の機種の端末では問題がないなら、 termcapの定義がまちがっている可能性があります。 しかし、ある種の機能を有するか欠如している端末で現れる Emacsのバグである可能性もあります。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
C-lを実行してもテキストが変ならば、 正しいと思われる状態になるまで、 C-x uを使って変更をもとに戻してみてください。 また、どのコマンドで変になったのか調べるために、 C-h lを試してみてください。
バッファの先頭や末尾で大量のテキストが失われているようなら、 モード行に単語`Narrow'が表示されていないか確認してください。 もしそうなら、おそらくテキストは失われているのではなく、 一時的に見えなくなっているのでしょう。 見えるようにするには、C-x n wと打ってください。 See 節 AD.20 ナロイング (2005/05/07)。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsが画面の最下行に自発的に`I-search:'と表示するようなら、 劣悪なxon/xoffの『フロー制御プロトコル』に従って 端末がC-sとC-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 節 AE.4 キーボード変換。)
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
`Virtual memory exceeded'というエラーメッセージが出たら、 変更したバッファをC-x sで保存してください。 この方法で保存する場合、必要なメモリは最小限ですみます。 Emacsは上記のエラーが起きたときでも使える予備のメモリを確保していますから、 C-x sを完了するのには十分なはずです。
変更済みのバッファを保存したら、 Emacsを終了して別のEmacsを起動してもよいですし、 M-x kill-some-bufferを使って 現在動いているEmacsのメモリを解放してもよいです。 大量のテキストが入っているバッファを消せば、 安全に編集を続行できます。 空きメモリが十分な量になると予備のメモリを自動的に確保し直し、 再度メモリ不足になったときに備えます。
メモリ不足になったときには、M-x buffer-menuを使って バッファを保存したり消したりしないでください。 このコマンドはけっこうメモリを必要とするので、 確保した予備のメモリだけでは十分でない可能性があるからです。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsやコンピュータがクラッシュしても、 クラッシュ時に編集していたファイルは自動保存ファイルから回復できます。 それには、Emacsを再度起動してから、コマンドM-x recover-sessionを 入力してください。
このコマンドは、まず、中断されたセッションファイルの一覧を日付とともに バッファに表示します。 その中からどのセッションを回復するか選んでください。 通常は、最新のセッションを選べばよいでしょう。 望みのセッションの行にポイントを動かして、C-c C-cと打ちます。
すると、recover-session
は、そのセッションで編集中だった 各ファイルについて回復するかどうか問い合わせてきます。 yと答えると、そのファイルと自動保存ファイルの日付を表示してから、 回復するかどうか再度問い合わせてきます。 再問い合わせに対してはyesで答える必要があります。 そうすると、Emacsはそのファイルを訪れますが、 テキストは自動保存ファイルから持ってきます。
recover-session
が完了すると、 回復を指定したファイルはEmacsバッファに入っています。 そうしたらこれらのバッファを保存してください。 保存して始めてもとのファイルが更新されます。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
バグのために、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) |
それぞれの質問に対し、yかnに続けて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回打っても緊急脱出の機能を使えない場合があります。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsを使うこと(や、その他のこと)がきわめて不愉快になったり、 ここまでにあげたどの方法でも問題が解決しない場合でも、 Emacsはまだ手助けができます。
まず、Emacsがコマンドに応答しないようなら、 C-g C-gと打ってEmacsから抜け出し、 新たに別のEmacsを起動してください。
doctorプログラムがあなたのいらいらを鎮めてくれるでしょう。 doctorに何かを話すときには、RET RETと打っていい終える 必要があります。 こうすると、doctorは患者が話し終えたことを認識します。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsのバグに出会うこともあるでしょう。 バグを修正する/できるとは約束できませんし、 そもそもバグだと認めないかもしれませんが、 読者が遭遇した問題については知らせてほしいと考えています。 たしかにそれをバグだと認めて修正しようということになる場合も多いのです。
バグを修正するには、まず、報告してもらう必要があります。 効果的に報告してもらうためには、報告の仕方を知っていただく必要があります。
バグを報告する前にすでに報告されているかを確認することはいい考えです.Emacs に付 属している `etc/PROBLEMS'ファイルに既知のバグのリストがあります.これは, C-h P で読むことができます.ユーザレベルでのバグの追加情報は GNU Emacs FAQにあります.この2つの文書でバ グを調べれば,解決策が見つかるかもしれません.あるいは関連問題の情報が得られるか もしれません.
AE.9.1 バグの発生時期 (2004/03/29) Have you really found a bug? AE.9.2 バグの報告とは How to report a bug effectively. AE.9.3 バグレポートのチェックリスト (2004/03/29) Steps to follow for a good bug report. AE.9.4 GNU Emacsに対する修正を送る How to send a patch for GNU Emacs.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsが不正命令を実行したり、 (『ディスクが満杯』などの外部の問題ではなく)プログラムに問題が あるというオペレーティングシステムのメッセージを表示して止まった場合には、 たしかにバグがあるといえます。
Emacsの画面の更新結果がバッファの内容に対応していないなら、 それもたしかにバグです。 コマンドの実行が思わしくなくてもC-lで再表示させると正しくなる場合には、 画面更新がまちがっているのです。
あるコマンドを実行するのに無限に時間がかかるというのはバグの可能性が ありますが、たしかにEmacsの責任かどうかを確認する必要があります。 コマンドによってはとても時間がかかるものもあります。 C-g(MS-DOSではC-BREAK)を打ってから C-h lを打つことで、Emacsが受け付けた入力がたしかに 読者が意図したものだったかどうか確認できます。 すぐに処理されるコマンドだという確信があるなら、 バグを報告してください。 そのコマンドがすごく時間のかかるものかどうかわからないなら、 マニュアルで調べるか知っている人に聞いてください。
よく知っているコマンドであって、普通なら問題なく結果が得られるはずなのに、 かわりにEmacsがエラーメッセージを出すようなら、恐らくそれはバグでしょう。
コマンドが正しくない動作をするのなら、それはバグです。 ただし、コマンドが本当は何をするのが正しいか確認してください。 そのコマンドに馴染みがないとか、 そのコマンドがどう動作するはずなのか確信が持てない場合は、 コマンドは実際には正しく動作しているのかもしれません。 バグという結論に飛びつくまえに、よく知っている人に見てもらってください。
最後に、コマンドの意図された定義が編集操作に対して最良でない可能性があります。 これは重要な問題ではありますが、ユーザーがどう判断するかの問題でもあります。 既存の機能について無知なために、 まちがっていると結論を出してしまうのも簡単です。 まずドキュメントをひととおり調べて、十分に納得し、 それでもなお自分にとって必要な機能がない、と断言できるまでは、 コマンドの定義が悪いなどとはいわないほうがよいでしょう。 マニュアルを熟読してもコマンドが何をするのかよくわからなければ、 索引や用語集を活用してよくわからない単語について調べましょう。
十分熟読しても、なおコマンドが何をするのかわからないなら、 それは「マニュアルのバグ」として報告すべきでしょう。 マニュアルは、読者を含めて、Emacsの専門家でない人が読んでも すべてのことが明らかになるようなものであるべきです。 ドキュメントのバグを報告することも、 プログラムのバグを報告することと同じくらい重要なことです。
関数や変数のオンラインの説明文がマニュアルと一致しない場合は、 どちらかがまちがっていますから、これもバグです。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
バグがあると確信したら、それを報告すること、 しかも、役立つ形で報告することが重要です。 もっとも有用なのは、どのようなコマンドを打ち込んだかを、 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と打ち込んだあとで」のように、 あなたがテキストを入れたやり方そのものを報告してください。
このように、バグを報告するときには、いかなる説明も推測しないでください。 問題を実際にデバッグして憶測ではない説明を報告してもらえるなら、 それは有益ですが、事実も含めてください。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
バグレポートを送る最良の方法は、電子メイルでEmacs保守チーム `[email protected]'かベータ版をテスト中であれば に送ることです。 (重要な改良の提案などもここに送ってください)。
他から出されたバグレポートが読みたければ、 ニュースグループ`gnu.emacs.bug'で読めます。 ただし、傍観者として見る場合には、見たものについて批判するべきではない、 ということを承知しておいてください。 バグレポートの目的はEmacs保守チームに情報を提供することです。 傍観者は、この目的に干渉しない限りは、歓迎します。 特に、大量のデータが添付されているバグレポートもありますので、 傍観者はそのことを非難すべきではありません。
ネットニュース経由でバグレポートを投稿しないでください。 ネットニュースよりもメイルのほうが送り手のメイルアドレスが確実にわかり 信頼できます。 もっと情報が必要なときには、メイルで問い合わせる必要があるかも知れません。もし, データが500,000バイト以上ある場合には,バグレポートにそのデータは含めないように してください.かわりに,必要があれば送付する旨を付記したり,ftpなどで利用できる ようにしてください.
電子メイルを送れない場合には、 紙や他の機械可読な媒体で下記へ送ってください。
GNU Emacs Bugs Free Software Foundation 59 Temple Place, Suite 330 Boston, MA 02111-1307 USA |
バグを修正するとは約束できません。 しかし、重大なバグや、醜いバグや、簡単に直せるバグなら、直したいと思います。
Emacsのバグレポートを送るのに便利な方法の1つは、 コマンドM-x report-emacs-bugsを使うことです。 このコマンドはメイルバッファ(see 節 AA. メイルの送信)を開いて、 自動的に重要な情報の一部を書き込みます。 しかし、必要な情報をすべて入れられるわけではありませんから、 以下の指針を読んでそれに従い、 メッセージを送るまえに重要な情報を自分で打ち込んでください。
保守チームがバグの調査を開始するためには、 以下のすべてがバグレポートに含まれている必要があります。
バージョン番号を調べるには、M-x emacs-version RETと打つ。 このコマンドが動作しないようなら、 GNU Emacsではないエディタを使っているようなので、 どこか別のところへバグを報告する。
configure
コマンドの引数。
これらの変更については正確に記してほしい。 英語での説明では不十分。 ソースのコンテキストdiffを送ること。
独自のファイルを追加したり、別のマシンに移植するのも、 ソースの変更にあたる。
ファイルをまったく訪問せずに問題が再現可能なら、ぜひ教えてほしい。 そのほうがデバッグがずっと楽になる。 どうしてもファイルが必要なら、必ずその内容が正確にわかるようにすること。 たとえば、行末に空白文字が付いているかどうかとか、 バッファの最終行に改行文字があるかどうかが 問題になることは頻繁にある (最終行に改行があるかどうかで何か違いがあるべきではないのだが、 もし違いが生じるようならそれもバグといえる)。
Emacsへの入力を正確に記録する簡単な方法は、 ドリブルファイルに書くことである。 ドリブルファイルを開始するには、 Emacsを実行開始した直後に、M-:か バッファ`*scratch*'でつぎのLisp式を実行する。
(open-dribble-file "~/dribble") |
それ以降はEmacsプロセスが終了するまで、 Emacsはすべての入力をドリブルファイルにコピーする。
TERM
の値)、 (すべてのマシンで同じとは限らないので) `/etc/termcap'ファイル中の当該端末のtermcapの定義すべて、 および、Emacsが実際に端末に送った出力。
端末への出力を収集するには、Emacsを実行開始した直後に、M-:か バッファ`*scratch*'でつぎのLisp式を実行する。
(open-termscript "~/termscript") |
それ以降、Emacsはプロセスが終了するまでのすべての端末出力の写しを 指定されたtermscriptファイルに書き出す。 Emacsが起動するときに問題が起きるのなら、 上の式を`.emacs'ファイルに入れて、 Emacsが最初に画面を開くときに一緒にtermscriptファイルも 書き始めるようにする。
ただし、端末に依存したバグは、 そのバグの出る端末なしで直すことは難しいことが多く、 ときとして不可能であることも承知しておいてほしい。
もちろん、Emacsが致命的なシグナルを受け取るのなら、それは誰にでもわかる。 しかし、バグが正しくないテキストだとすると、 保守チームにはどこが正しくないのかわからない可能性がある。 そういう可能性のある書き方はやめてほしい。
遭遇する問題が致命的なシグナルだとしても、はっきりとそう書くべきである。 たとえば、Emacsのソースが一部違っている版だったとか、 システムのCライブラリのバグに遭遇したといった 奇妙なことに出会ったとしよう(実話!)。 あなたが使っているEmacsはクラッシュするが、保守チームのほうでは何ともない。 クラッシュするといってもらえれば、 保守チームのほうで実行してクラッシュしなければバグが再現しないとわかる。 しかしそういってもらえないと、 バグが再現したのかどうかさえわからずに、 試してみた結果からは何の結論も得られない。
エラーメッセージの文面を正確に報告するには、 `*Message*'バッファからメッセージをバグレポートにコピーする。 一部ではなく、全体をコピーしてほしい。
エラーのバックトレースを取得するには、エラーが発生するよりまえにLisp式 (setq debug-on-error t)
を評価する (つまり、まずこのLisp式を実行して、それからエラーを再現させる)。 すると、エラーが起きたときにLispデバッガが実行され、 デバッガがバックトレースを表示する。 このデバッガのバックトレース出力を、バグレポートにコピーする。
このやり方は、バグを再現できるときだけ使える。 再現できない場合は、最低限、エラーメッセージだけでもすべてコピーする。
-q
を指定して初期化ファイルのロードを抑制して) 個人のファイル`.emacs'をロードせずに起動したEmacsでも エラーが再現するかどうか調べる。 これでエラーが再現しないなら、 エラーの再現に必要なので、ロードしたすべてのプログラムの内容を正確に報告する。
開発中のソースの行番号とユーザーが入手するソースの行番号とは同じではない。 あなたが使っているバージョンのソースの何行目が、 開発中のソースの何行目に対応しているか調べるのは余分な手間であり、 正確にはわからないかもしれない。
ただし、バグの原因を示すために追加情報を集める場合には、 追加情報をいつ集めるかをよく考える必要がある。
たとえば、多くの人はバックトレースだけを送ってくるが、 それ単体ではあまり役に立たない。 引数の記録つきの単純なバックトレースでは、 GNU Emacsの内部で何が起きているかについての情報はほとんどない。 というのは、バックトレースに表示される引数のほとんどは Lispオブジェクトへのポインタだから。 それらのポインタの値そのものは、なんら重要ではない。 重要なのは、ポインタが指している先のオブジェクトの内容 (そしてその内容もまたポインタであることが多い)。
役に立つ情報を提供するには、 Lispオブジェクトの値をLispの記法で示す必要がある。 スタックの底付近にある数個のフレームについて、 Lispオブジェクトであるような各変数に対してこれを行ってほしい。 デバッガは単なる整数だと思うので、 どの変数がLispオブジェクトであるかはソースを見てほしい。
変数の値をLispの記法で示すには、まず、その値をプリントしてから、 GDBのユーザー定義コマンドpr
を使ってLispオブジェクトをLispの記法で 表示させる。 (別のデバッガを使わなければならない場合は、 オブジェクトを引数として関数debug_print
を呼び出す)。 コマンドpr
は、ファイル`.gdbinit'で定義されており、 (コアダンプではなく)実行中のプロセスをデバッグするときだけ使える。
Lispでエラーが発生したときにEmacsを中断してGDBに戻るようにするには、 Fsignal
にブレークポイントを設定する。
実行中のLisp関数の簡素な一覧を表示するには、 GDBのコマンドxbacktrace
を打つ。
Lisp関数の引数を調べたい場合には、 スタック上を上に移動していき関数Ffuncall
のフレームに到達するごとに、 つぎのようなGDBコマンドを打つ。
p *args pr |
関数が受け取った最初の引数を出力するには、つぎのようにする。
p args[1] pr |
2番目以降の引数でも同様に出力できる。 Ffuncall
の引数nargs
は、 Ffuncall
が受け取った引数の個数を表す。 この個数は、Lisp関数自身とその関数に対する引数とを合わせた数。
ファイル`.gdbinit'は、 データタイプやLispオブジェクトの中身を調べるのに役立つコマンド類を定義する。 それらのコマンドの名前は`x'で始まる。 これらのコマンドはpr
より下位のレベルで動作し使い難いが、 コアダンプをデバックしたり、 Emacsが致命的なシグナルを受理したときのように pr
がうまく動かないときでも使える。
こうして調べた結果、Emacsがシステムコールの中で固まっているとわかったら、 Emacsを再度止めて、システムコールの引数を調べる。 そしてバグレポートには、ソース中でのシステムコールの正確な位置と、 引数が何だったかを正確に記入する。
Emacsが無限ループしているのなら、ループの始まりと終りを調べる。 もっとも簡単にこれを調べるには、GDBのコマンド`finish'を使う。 このコマンドを使うたびに、1つのスタックフレームから抜けるまで Emacsは実行を継続する。 戻ってこなくなるまで、繰り返し`finish'を打つ。 戻ってこないのは、そのフレームで無限ループが起こっているからである。
ここでEmacsを再度停止し、 戻ってこなくなったフレームにちょうど戻るまで、 繰り返し`finish'を使う。 つぎに、`next'を使ってそのフレーム内で1ステップずつ実行する。 こうすれば、ループがどこで始まりどこで終るかわかる。 さらに、ループ内で使われているデータを調べて、 ループが終るべきところでなぜ終らないかを追求してみてほしい。 これらの情報すべてを、バグレポートに含める。
以下には、バグレポートに必要ないものをあげておきます。
バグに出会った人はしばしば、入力をどう変えるとバグが出なくなるとか、 あるいは、相変わらず出るといったことを探求するのに時間をかける。
これは時間がかかるわりには、役に立たない。 というのは、保守チームがデバッグを行うときには、 デバッガのもとでブレークポイントを設定しながらバグの出る1つの例を 実行するのであって、何通りもの例から帰納的に推論するわけではない。 だから、別の例を探すのに時間をかけたりしないでほしい。
もちろん、もとの例のかわりに使えるもっと簡単な例がみつかれば、 それは役に立つ。 簡単な例なら、出力中のエラーもみつけやすくなり、 デバッガを使って実行するにも短い時間ですむ。
ただし、単純化は必須ではない。 もし単純化できなかったり、単純化する時間がなければ、 もとの例のままでよいので、バグレポートを出してほしい。
ある特別な種類のバグについては、システムコールトレースは非常に役立つが、 多くの場合はほとんど有用な情報は得られない。 したがって、多くの人がシステムコールのトレースこそクラッシュに 関する情報を報告するのに欠かせないものだと思っているらしいのは、 不思議である。 これはたぶん、ソースコードやデバッグ用シンボルのないプログラムを デバッグした経験から生まれた習慣だろう。
ほとんどのプログラムでは、システムコールのトレースより、 バックトレースのほうがずっとずっと役に立つ。 Emacsでさえ、単純なバックトレースのほうが有用である。 しかし、十分な情報を提供するには、バックトレースの補記として、 変数の値を表示しpr
でLispオブジェクトとしても表示する(上記参照)。
バグに対する修正は、よい品質のものなら有用である。 しかし、修正が正しいことを示すテスト例などの バグレポートに必要な情報を省かないでほしい。 修正に問題があるとわかって別のやり方でバグをつぶすかもしれないし、 報告された修正がまったく理解できないこともありえる。 そして、どんなバグを修正しようとしているのかわからない、あるいは、 その修正がなぜ改良になるのかわからなければ、 その修正を採用するわけにいかない。
我々にとって、読者のパッチが理解しやすく、 インストールしやすくするための指針については、 see 節 AE.9.4 GNU Emacsに対する修正を送る。
こういう予想は、たいていはまちがっている。 専門家でさえ、まずデバッガで事実を調べない限り、正しい予想はできない。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
GNU Emacsに対する改良や虫取りのための修正を送ろうということであれば、 おおいに助かります。 修正を送るにあたっては、保守チームがそれを役立てやすいように、 以下の指針に従ってください。 さもないと、送られた情報は有用であっても、 役立てるには余分な作業が必要になります。 GNU Emacsの保守は最善の環境でやっても手間のかかる仕事ですから、 手助けしていただくにしても十分な配慮が必要なのです。
(バグレポートへのポインタを示すよりも、 バグレポートのコピーを含めるほうが望ましい。 というのは、ポインタだとバグレポートを探す必要があるし、 そのバグを直し終えていると、バグレポートを消してしまっているかもしれない。)
異なる理由に基づいて2つの変更を行った場合、 その両方を採用することはないだろう。 どちらか一方だけを採用するかもしれない。 もしそれらをいっしょくたに1つのdiffにしてしまうと、 それを分離するために余計な作業が必要になる。 どの部分の変更がどちらの目的に対応しているのか調べる必要がある。 その時間を割けないと、その変更をまったく 採用しないということにもなりかねない。
それぞれの変更を行ってすぐに、別個に、説明を付けて送ってもらえれば、 2つの変更が一緒になるなどということはないし、 それぞれの変更を分離するなどの余計な作業をせずに適切に考慮できる。
それぞれの変更は別個に送るべきなので、変更を行ったらすぐに送れるはず。 そうすれば、保守チームのほうでその変更が重要なものだと 判断したらすぐ取り入れることができる。
もしGNU diffを使っているのなら、Cのコードのdiffを作るときには `diff -c -F'^[_a-zA-Z0-9$]+ *(''を使う。 こうすると、変更される各関数の名前が一緒に表示される。
変更記録の目的は、人が読んでどこが変わったかわかるようにすること。 だから、どの関数を変更したか具体的に書く。 大きい関数の場合は、関数の中のどの箇所を変更したかも書いてあると助かる。
その反面、どこが変更されたかわかるようにさえなっていれば、 変更の目的は変更記録で説明する必要はない。 たとえば、新しい関数を追加したのであれば、 その関数が新しいということだけを書けば十分。 目的を説明したほうがよいと感じるなら、たぶんそのとおりだろう。 しかし、説明はコード中のコメントに書く。 そのほうが役に立つ。
ディレクトリ`src'とディレクトリ`lisp'の ファイル`ChangeLog'を眺めて、どのような情報を入れるかとか、 どのようなスタイルで書くかの参考にしてほしい。 誰が変更したかわかるように自分の名前をヘッダの行に記録したいなら、 ヘッダ行も送ること。
ときどき、おおむね改良になるかもしれないが、 はっきり改良だとはいいがたいような変更を送ってくる人がいる。 そのような変更は、きわめて慎重に検討しなければならないので、 採用するのは難しい。 もちろん、あなたがどのような理由でその変更が正しいのかよい説明を 書いてくれれば、保守チームがそれを理解する助けになる。
もっとも安全な変更は、特定のマシンの構成ファイルに対する変更。 それが安全だという理由は、 その変更が他のマシンにおいて問題を引き起こすことはありえないから。
修正を採用しても安全だとはっきりわかる形に設計することで、 保守チームの労力を軽減できる。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
Emacsのプレテスト版が正しく動作することの確認を手助けしたかったり、 Emacsの改良作業に加わりたければ、 [email protected]
の保守チームに連絡してください。 プレテスト参加者は、バグを報告するだけでなく、バグを探すことも要求されます。 Emacsの改良に加わりたければ、保守チームにプロジェクトの示唆を求めるか、 あなたのアイデアを提案してください。
すでに改良したコードを書いてしまったのなら、それについて教えてください。 まだ作業を始めていないのなら、始めるまえに [email protected]
に連絡したほうがよいです。 そうすれば、Emacsの残りの部分とよく適合する形で 拡張を行うにはどうしたらよいかのヒントがもらえるでしょう。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |
GNU Emacsをインストールしたり、使ったり、変更したりするうえで手助けが必要なら、 2つの方法があります。
[email protected]
にメッセージを送るか、 ニュースグループgnu.emacs.help
に投稿する。 (これらのメイリングリストとニュースグループは相互乗り入れしているので、 どちらを使ってもかまわない。)
[ << ] | [ >> ] | [表紙] | [目次] | [索引] | [検索] [上端 / 下端] [?] |