GNU Emacs Lisp Reference Manual

For Emacs Version 29.1

by Bil Lewis, Dan LaLiberte, Richard Stallman,
the GNU Manual Group, et al.

This is the GNU Emacs Lisp Reference Manual corresponding to Emacs version 29.1.

Copyright © 1990–1996, 1998–2023 Free Software Foundation, Inc.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with the Invariant Sections being “GNU General Public License,” with the Front-Cover Texts being “A GNU Manual,” and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License.”

(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual. Buying copies from the FSF supports it in developing GNU and promoting software freedom.”



Published by the Free Software Foundation
51 Franklin St, Fifth Floor
Boston, MA 02110-1301
USA
ISBN 1-882114-74-4



Cover art by Etienne Suvasa.


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

Emacs Lisp

This is the GNU Emacs Lisp Reference Manual corresponding to Emacs version 29.1.

Copyright © 1990–1996, 1998–2023 Free Software Foundation, Inc.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with the Invariant Sections being “GNU General Public License,” with the Front-Cover Texts being “A GNU Manual,” and with the Back-Cover Texts as in (a) below. A copy of the license is included in the section entitled “GNU Free Documentation License.”

(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual. Buying copies from the FSF supports it in developing GNU and promoting software freedom.”


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

1 イントロダクション

GNU Emacsテキストエディターのほとんどの部分は、Emacs Lispと呼ばれるプログラミング言語で記述されています。新しいコードをEmacs Lispで記述して、このエディターの拡張としてインストールできます。しかしEmacs Lispは、単なる拡張言語を越える言語であり、それ自体で完全なコンピュータープログラミング言語です。他のプログラミング言語で行なうすべてのことに、この言語を使用できます。

Emacs Lispはエディターの中で使用するようにデザインされているので、テキストのスキャンやパースのための特別な機能をもち、同様にファイル、バッファー、ディスプレイ、サブプロセスを処理する機能をもちます。Emacs Lispは編集機能と密に統合されています。つまり編集コマンドはLispプログラムから簡単に呼び出せる関数で、カスタマイズのためのパラメーターは普通のLisp変数です。

このマニュアルはEmacs Lispの完全な記述を試みます。初心者のためのEmacs Lispのイントロダクションは、Free Software Foundationからも出版されている、Bob ChassellのAn Introduction to Emacs Lisp Programmingを参照してください。このマニュアルは、Emacsを使用した編集に熟知していることを前提としています。これの基本的な情報については、The GNU Emacs Manualを参照してください。

おおまかに言うと、前の方のチャプターでは多くのプログラミング言語の機能にたいして、Emacs Lispでの対応する機能を説明し、後の方のチャプターではEmacs Lispに特異な機能や、編集に特化した関連する機能を説明します。

これは Emacs 29.1に対応したGNU Emacs Lisp Reference Manualです。


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

1.1 注意事項

このマニュアルは幾多のドラフトを経てきました。ほとんど完璧ではありますが、不備がないとも言えません。(ほとんどの特定のモードのように)それらが副次的であるとか、まだ記述されていないという理由により、カバーされていないトピックもあります。わたしたちがそれらを完璧に扱うことはできないので、いくつかの部分は意図的に省略しました。

このマニュアルは、それがカバーしている事柄については完全に正しくあるべきあり、故に特定の説明テキスト、チャプターやセクションの順番にたいしての批判にオープンであるべきです。判りにくかったり、このマニュアルでカバーされていない何かを学ぶためにソースを見たり実地から学ぶ必要があるなら、このマニュアルはおそらく訂正されるべきなのかもしれません。どうかわたしたちにそれを教えてください。

このマニュアルを使用するときは、間違いを見つけたらすぐに訂正を送ってください。関数または関数グループの単純な現実例を考えたときは、ぜひそれを記述して送ってください。それが妥当ならコメントでノード名と関数名や変数名を参照してください。あなたが訂正を求めるエディションのバージョンも示してください。

コメントや訂正の送信には、M-x report-emacs-bugを使用するようお願いします。新たなコード(や問題訂正のパッチ)を寄贈するにはM-x submit-emacs-patchを使用してください。


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

1.2 Lispの歴史

Lisp(LISt Processing language: リスト処理言語)は、MIT(Massachusetts Institute of Technology: マサチューセッツ工科大学)で、AI(artificial intelligence: 人工知能)の研究のために、1950年代末に最初に開発されました。Lisp言語の強力なパワーは、編集コマンドの記述のような、他の目的にも適っています。

長年の間に何ダースものLisp実装が構築されてきて、それらのそれぞれに特異な点があります。これらの多くは、1960年代にMITのProject MACで記述された、Maclispに影響を受けています。最終的に、Maclisp後裔の実装者は共同して、Common Lispと呼ばれる標準のLispシステムを開発しました。その間にMITのGerry SussmanとGuy Steeleにより、簡潔ながらとても強力なLisp方言の、Schemeが開発されました。

GNU Emacs LispはMaclispから多く、Common Lispから少し影響を受けています。Common Lispを知っている場合、多くの類似点に気づくでしょう。しかしCommon Lispの多くの機能は、GNU Emacsが要求するメモリー量を削減するために、省略または単純化されています。ときには劇的に単純化されているために、Common Lispユーザーは混乱するかもしれません。わたしたちは時折GNU Emacs LispがCommon Lispと異なるか示すでしょう。Common Lispを知らない場合、それについて心配する必要はありません。このマニュアルは、それ自体で自己完結しています。

cl-libライブラリーを通じて、Common Lispをかなりエミュレートできます。Overview in Common Lisp Extensionsを参照してください。

Emacs LispはSchemeの影響は受けていません。しかしGNUプロジェクトにはGuileと呼ばれるScheme実装があります。拡張が必要な新しいGNUソフトウェアーでは、Guileを使用します。


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

1.3 Lispの歴史

このセクションでは、このマニュアルで使用する表記規約を説明します。あなたはこのセクションをスキップして、後から参照したいと思うかもしれません。


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

1.3.1 Lispの歴史

このマニュアルでは、“Lispリーダー”および“Lispプリンター”という用語で、Lispのテキスト表現を実際のLispオブジェクトに変換したり、その逆を行なうLispルーチンを参照します。詳細については、プリント表現と読み取り構文を参照してください。あなた、つまりこのマニュアルを読んでいる人のことはプログラマーと考えて“あなた”と呼びます。“ユーザー”とは、あなたの記述したものも含めて、Lispプログラムを使用する人を指します。

Lispコードの例は、(list 1 2 3)のようなフォーマットです。メタ構文変数(metasyntactic variables)を表す名前や、説明されている関数の引数名前は、first-numberのようにフォーマットされています。


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

1.3.2 nilt

Emacs Lispでは、シンボルnilには3つの異なる意味があります。1つ目は‘nil’という名前のシンボル、2つ目は論理値のfalse、3つ目は空リスト — つまり要素が0のリストです。変数として使用した場合、nilは常に値nilをもちます。

Lispリーダーに関する限り、‘()’と‘nil’は同一です。これらは同じオブジェクト、つまりシンボルnilを意味します。このシンボルを異なる方法で記述するのは、完全に人間の読み手を意図したものです。Lispリーダーが‘()’か‘nil’のどちらかを読み取った後は、プログラマーが実際にどちらの表現で記述したかを判断する方法はありません。

このマニュアルでは、空リストを意味することを強調したいときは()と記述し、論理値のfalseを意味することを強調したいときはnilと記述します。この慣習はLispプログラムで使用してもよいでしょう。

(cons 'foo ())                ; 空リストを強調
(setq foo-flag nil)           ; 論理値のfalseを強調

論理値が期待されているコンテキストでは、非niltrueと判断されます。しかし論理値のtrueを表す好ましい方法はtです。trueを表す値を選択する必要があり、他に選択の根拠がない場合はtを使用してください。シンボルtは、常に値tをもちます。

Emacs Lispでのniltは、常に自分自身を評価する特別なシンボルです。そのためプログラムでこれらを定数として使用する場合、クォートする必要はありません。これらの値の変更を試みると、結果はsetting-constantエラーとなります。変更不可な変数を参照してください。

Function: booleanp object

objectが2つの正規のブーリーン値(tnil)のいずれかなら、非nilをリターンする。


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

1.3.3 評価の表記

評価できるLisp式のことをフォーム(form)と呼びます。フォームの評価により、これは結果として常にLispオブジェクトを生成します。このマニュアルの例では、これを‘’で表します:

(car '(1 2))
     ⇒ 1

これは“(car '(1 2))を評価すると、1になる”と読むことができます。

フォームがマクロ呼び出しの場合、それは評価されるための新たなLispフォームに展開されます。展開された結果は‘’で表します。わたしたちは展開されたフォームの評価し結果を示すこともあれば、示さない場合もあります。

(third '(a b c))
     → (car (cdr (cdr '(a b c))))
     ⇒ c

1つのフォームを説明するために、同じ結果を生成する別のフォームを示すこともあります。完全に等価な2つのフォームは、‘’で表します。

(make-sparse-keymap) ≡ (list 'keymap)

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

1.3.4 プリントの表記

このマニュアルの例の多くは、それらが評価されるときにテキストをプリントします。(*scratch*バッファーのような)Lisp Interactionバッファーで閉カッコの後でC-jをタイプすることによりコード例を実行する場合には、プリントされるテキストはそのバッファーに挿入されます。(関数eval-regionでの評価のように)他の方法でコード例を実行する場合、プリントされるテキストはエコーエリアに表示されます。

このマニュアルの例はプリントされるテキストがどこに出力されるかに関わらず、それを‘-|’で表します。フォームを評価することにより戻される値は、‘’とともに後続の行で示します。

(progn (prin1 'foo) (princ "\n") (prin1 'bar))
     -| foo
     -| bar
     ⇒ bar

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

1.3.5 エラーメッセージ

エラーをシグナルする例もあります。これは通常、エコーエリアにエラーメッセージを表示します。エラーメッセージの行は‘error→’で始まります。‘error→’自体は、エコーエリアに表示されないことに注意してください。

(+ 23 'x)
error→ Wrong type argument: number-or-marker-p, x

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

1.3.6 バッファーテキストの表記

バッファー内容の変更を説明する例もあます。それらの例では、そのテキストのbefore(以前)とafter(以後)のバージョンを示します。それらの例では、バッファー内容の該当する部分を、ダッシュを用いた2行の破線(バッファー名を含む)で示します。さらに、‘’はポイントの位置を表します(もちろんポイントのシンボルはバッファーのテキストの一部ではなく、ポイントが現在配されている2つの文字のの位置を表す)。

---------- Buffer: foo ----------
This is the ∗contents of foo.
---------- Buffer: foo ----------

(insert "changed ")
     ⇒ nil
---------- Buffer: foo ----------
This is the changed ∗contents of foo.
---------- Buffer: foo ----------

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

1.3.7 説明のフォーマット

このマニュアルでは関数(function)、変数(variable)、コマンド(command)、ユーザーオプション(user option)、スペシャルフォーム(special form)を、統一されたフォーマットで記述します。記述の最初の行には、そのアイテムの名前と、もしあれば引数(argument)が続きます。 そのアイテムの属するカテゴリー(function、variableなど)は、行の先頭に表示します。 それ以降の行は説明行で、例を含む場合もあります。


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

1.3.7.1 関数の説明例

関数の記述では、関数の名前が最初に記述されます。同じ行に引数の名前のリストが続きます。引数の値を参照するために、引数の名前は記述の本文にも使用されます。

引数リストの中にキーワード&optionalがある場合、その後の引数が省略可能であることを示します(省略された引数のデフォルトはnil)。その関数を呼び出すときは、&optionalを記述しないでください。

キーワード&rest(これの後には1つの引数名を続けなければならない)は、その後に任意の引数を続けることができることを表します。&restの後に記述された引数名の値には、その関数に渡された残りのすべての引数がリストとしてセットされます。この関数を呼び出すときは、&restを記述しないでください。

以下はfooという架空の関数(function)の説明です:

Function: foo integer1 &optional integer2 &rest integers

関数foointeger2からinteger1を減じてから、その結果に残りすべての引数を加える。integer2が与えられなかった場合、デフォルトして数値19が使用される。

(foo 1 5 3 9)
     ⇒ 16
(foo 5)
     ⇒ 14

より一般的には、

(foo w x y…)
≡
(+ (- x w) y…)

慣例として引数の名前には、(たとえばintegerinteger1bufferのような)期待されるタイプ名が含まれます。(buffersのような)複数形のタイプは、しばしばその型のオブジェクトのリストを意味します。objectのような引き数名は、それが任意の型であることを表します(EmacsオブジェクトタイプのリストはLispのデータ型を参照)。他の名前をもつ引数(たとえばnew-file)はその関数に固有の引数で、関数がドキュメント文字列をもつ場合、引数のタイプはその中で説明されるべきです(ドキュメントを参照)。

&optional&restにより修飾される引数のより完全な説明は、ラムダ式を参照してください。

コマンド(command)、マクロ(macro)、スペシャルフォーム(special form)の説明も同じフォーマットですが、‘Function’が‘Command’、‘Macro’、‘Special Form’に置き換えられます。コマンドはとは単に、インタラクティブ(interactive: 対話的)に呼び出すことができる関数です。マクロは関数とは違う方法(引数は評価されない)で引数を処理しますが、同じ方法で記述します。

マクロとスペシャルフォームにたいする説明には、特定のオプション引数や繰り替えされる引数のために、より複雑な表記が使用されます。なぜなら引数リストが、より複雑な方法で別の引数に分離されるからです。‘[optional-arg]’はoptional-argがオプションであることを意味し、‘repeated-args’は0個以上の引数を表します。カッコ(parentheses)は、複数の引数をリスト構造の追加レベルにグループ化するのに使用されます。以下は例です:

Special Form: count-loop (var [from to [inc]]) body…

この架空のスペシャルフォームは、 bodyフォームを実行してから変数varをインクリメントするループを実装します。最初の繰り返しでは変数は値fromをもちます。以降の繰り返しでは、変数は1(incが与えられた場合はinc)増分されます。vartoに等しい場合、bodyを実行する前にループをexitします。以下は例です:

(count-loop (i 0 10)
  (prin1 i) (princ " ")
  (prin1 (aref vector i))
  (terpri))

fromtoが省略された場合、ループを実行する前にvarnilがバインドされ、繰り返しの先頭においてvarが非nilの場合は、ループをexitします。以下は例です:

(count-loop (done)
  (if (pending)
      (fixit)
    (setq done t)))

このスペシャルフォームでは、引数fromtoはオプションですが、両方を指定するか未指定にするかのいずれかでなければなりません。これらの引数が与えられた場合には、オプションでincも同様に指定することができます。これらの引数は、フォームのすべての残りの要素を含むbodyと区別するために、引数varとともにリストにグループ化されます。


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

1.3.7.2 変数の説明例

変数(variable)とは、オブジェクトにバインド(bind)される名前です(セット(set)とも言う)。変数がバインドされたオブジェクトのことを値(value)と呼びます。このような場合には、その変数が値をもつという言い方もします。ほとんどすべての変数はユーザーがセットすることができますが、特にユーザーが変更できる特定の変数も存在し、これらはユーザーオプション(user options)と呼ばれます。通常の変数およびユーザーオプションは、関数と同様のフォーマットを使用して説明されますが、それらには引数がありません。

以下は架空の変数electric-future-mapの説明です。

Variable: electric-future-map

この変数の値はElectric Command Futureモードで使用される完全なキーマップである。このマップ内の関数により、まだ実行を考えていないコマンドの編集が可能になる。

ユーザーオプションも同じフォーマットをもちますが、‘Variable’が‘User Option’に置き換えられます。


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

1.4 バージョンの情報

以下の機能は、使用しているEmacsに関する情報を提供します。

Command: emacs-version &optional here

この関数は実行しているEmacsのバージョンを説明する文字列をreturnすす。これはバグレポートにこの文字列を含めるときに有用である。

(emacs-version)
  ⇒ "GNU Emacs 26.1 (build 1, x86_64-unknown-linux-gnu,
             GTK+ Version 3.16) of 2017-06-01"

hereが非nilならテキストをバッファーのポイントの前に挿入して、nilをリターンする。この関数がインタラクティブに呼び出すと、同じ情報をエコーエリアに出力する。プレフィクス引数を与えると、hereが非nilになる。

Variable: emacs-build-time

この変数の値はEmacsがビルドされた日時を示す。値はcurrent-timeの形式(時刻を参照)、その情報が利用できなければnil

emacs-build-time
     ⇒ (25194 55894 8547 617000)

(Emacsのビルド時にcurrent-time-listnilなら、タイムスタンプは(1651169878008547617 . 1000000000)になる。)

Variable: emacs-version

この変数の値は実行中のEmacsのバージョンであり、"26.1"のような文字列。"26.0.91"のように3つの数値コンポーネントをもつ値はリリース版ではなくテストバージョンであることを示す(Emacs 26.1より前では"25.1.1"のように文字列の最後に余分な整数コンポーネントが含まれていたが、これは現在はemacs-build-numberに格納される)。

Variable: emacs-major-version

Emacsのメジャーバージョン番号を示す整数。Emacs 23.1では値は23。

Variable: emacs-minor-version

Emacsのマイナーバージョン番号を示す整数。Emacs 23.1では値は1。

Variable: emacs-build-number

これは同一のディレクトリーにおいてEmacsが(クリーニングなしで)ビルドされるたびに増分される整数。これはEmacsの開発時だけに関係のある変数。

Variable: emacs-repository-version

Emacsがビルドされたレポジトリのリビジョン番号を与える文字列。Emacsがリビジョンコントロール外部でビルドされた場合の値はnil

Variable: emacs-repository-branch

Emacsがビルドされたレポジトリブランチを与える文字列。ほとんどの場合は"master"。Emacsがリビジョンコントロール外部でビルドされた場合の値はnil


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

1.5 謝辞

このマニュアルは当初、Robert Krawitz、Bil Lewis、Dan LaLiberte、Richard M. Stallman、Chris Welty、およびGNUマニュアルグループのボランティアにより、数年を費やして記述されました。Robert J. Chassellはこのマニュアルのレビューと編集をDefense Advanced Research Projects Agency、ARPA Order 6082のサポートのもとに手助けしてくれ、Computational Logic, IncのWarren A. Hunt, Jr.によりアレンジされました。それ以降も追加のセクションがMiles Bader、Lars Brinkhoff、Chong Yidong、Kenichi Handa、Lute Kamstra、Juri Linkov、Glenn Morris、Thien-Thi Nguyen、Dan Nicolaescu、Martin Rudalics、Kim F. Storm、Luc Teirlinck、Eli Zaretskii、およびその他の人たちにより記述されました。

Drew Adams、Juanma Barranquero、Karl Berry、Jim Blandy、Bard Bloom、Stephane Boucher、David Boyes、Alan Carroll、Richard Davis、Lawrence R. Dodd、Peter Doornbosch、David A. Duff、Chris Eich、Beverly Erlebacher、David Eckelkamp、Ralf Fassel、Eirik Fuller、Stephen Gildea、Bob Glickstein、Eric Hanchrow、Jesper Harder、George Hartzell、Nathan Hess、Masayuki Ida、Dan Jacobson、Jak Kirman、Bob Knighten、Frederick M. Korz、Joe Lammens、Glenn M. Lewis、K. Richard Magill、Brian Marick、Roland McGrath、Stefan Monnier、Skip Montanaro、John Gardiner Myers、Thomas A. Peterson、Francesco Potortì、Friedrich Pukelsheim、Arnold D. Robbins、Raul Rockwell、Jason Rumney、Per Starbäck、Shinichirou Sugou、Kimmo Suominen、Edward Tharp、Bill Trost、Rickard Westman、Jean White、Eduard Wiebe、Matthew Wilding、Carl Witty、Dale Worley、Rusty Wright、David D. Zuhnにより訂正が提供されました。

より完全な貢献者のリストは、Emacsソースレポジトリの関連する変更ログエントリーを参照してください。


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

2 Lispのデータ型

Lispのオブジェクト(object)とは、Lispプログラムから操作されるデータです。型(type)データ型(data type)とは、可能なオブジェクトの集合を意味します。

すべてのオブジェクトは少なくとも1つの型に属します。同じ型のオブジェクトは同様な構造をもち、通常は同じコンテキストで使用されます。型を重複してもつことができ、オブジェクトは複数の型に属することができます。その結果として、あるオブジェクトが特定の型に属するかどうかを尋ねることはできますが、オブジェクトがその型だけに属するかどうかは決定できません。

Emacsにはいくつかの基本オブジェクト型が組み込まれています。これらの型は他のすべての型を構成するもとであり、プリミティブ型(primitive types: 基本型)と呼ばれます。すべてのオブジェクトはただ1つのプリミティブ型に属します。これらの型には整数(integer)浮動小数点数(float)コンス(cons)シンボル(symbol)文字列(string)ベクター(vector)ハッシュテーブル(hash-table)サブルーチン(subr)バイトコード関数(byte-code function)レコード(record)、およびbufferのような編集に関連した特別な型が含まれます(編集用の型を参照)。

プリミティブ型にはそれぞれ、オブジェクトがその型のメンバーかどうかのチェックを行なうために、それぞれ対応するLisp関数があります。

他の多くの言語とは異なり、Lispのオブジェクトは自己記述(self-typing)的です。オブジェクトのプリミティブ型は、オブジェクト自体に暗に含まれます。たとえばオブジェクトがベクターなら、それを数字として扱うことはできません。Lispはベクターが数字でないことを知っているのです。

多くの言語では、プログラマーは各変数にたいしてデータ型を宣言しなければならず、コンパイラーは型を知っていますが、データの中に型はありません。Emacs Lispには、このような型宣言はありません。Lisp変数は任意の型の値をもつことができ、変数に保存した値と型を記憶します(実際には特定の型の値だけをもつことができる少数のEmacs Lisp変数がある。値を制限された変数を参照されたい)。

このチャプターでは、GNU Emacs Lispの各標準型の意味、プリント表現(printed representation)、入力構文(read syntax)を説明します。これらのデータ型を使用する方法についての詳細は、以降のチャプターを参照してください。


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

2.1 プリント表現と読み取り構文

オブジェクトのプリント表現(printed representation)とは、オブジェクトにたいしてLispプリンター(関数prin1)が生成する出力のフォーマットです。すべてのデータ型は一意なプリント表現をもちます。オブジェクトの入力構文(read syntax)とは、オブジェクトにたいしてLispリーダー(関数read)が受け取る入力のフォーマットです。これは一意である必要はありません。多くの種類のオブジェクトが複数の構文をもちます。Lispオブジェクトの読み取りとプリントを参照してください。

ほとんどの場合、オブジェクトのプリント表現が、入力構文としても使用されます。しかしLispプログラム内の定数とすることに意味が無いいくつかの型には、入力構文がありません。これらのオブジェクトはハッシュ表記(hash notation)でプリントされ、‘#<’、説明的な文字列(典型的には型名にオブジェクトの名前を続けたもの)、‘>’で構成される文字列です。たとえば:

(current-buffer)
     ⇒ #<buffer objects-ja.texi>

ハッシュ表記は読み取ることができないので、Lispリーダーは‘#<’に遭遇すると常にエラーinvalid-read-syntaxをシグナルします。

他の言語では式はテキストであり、これ以外の形式はありません。Lispでは式は第一にまずLispオブジェクトであって、オブジェクトの入力構文であるテキストは副次的なものに過ぎません。たいていこの違いを強調する必要はありませんが、このことを心に留めておかないとたまに混乱することがあるでしょう。

インタラクティブに式を評価するとき、Lispインタープリターは最初にそれのテキスト表現を読み取り、Lispオブジェクトを生成してからそのオブジェクトを評価します(評価を参照)。しかし評価と読み取りは別の処理です。読み取りによりテキストにより表現されたLispオブジェクトを読み取り、Lispオブジェクトがリターンされます。後でオブジェクトは評価されるかもしれないし、評価されないかもしれません。オブジェクトを読み取るための基本的な関数readの説明は、入力関数を参照してください。


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

2.2 特別な読み取り構文

Emacs Lispでは特別なハッシュ表記を通じて多くの特別なオブジェクトと構文を表します。

#<…>

入力構文がないオブジェクトはこのように表される(プリント表現と読み取り構文を参照)。

##

名前が空文字列であるようなインターン済みシンボルのプリント表現(シンボル型を参照)。

#'

functionにたいするショートカット。無名関数を参照のこと。

#:

名前がfooであるようなインターンされていないシンボルのプリント表現は‘#:foo’ (シンボル型を参照)。

#N

循環構造のプリント時には構造が自身をループバックすることを表すためにこの構文が使用される。ここで‘N’リストの開始カウント。

(let ((a (list 1)))
  (setcdr a a))
=> (1 . #0)
#N=
#N#

#N=’はオブジェクト名、‘#N#’はそのオブジェクトを表すので、これらはコピーではなく同一オブジェクトになる(循環オブジェクトの読み取り構文を参照)。

#xN

16進表現の‘N’ (‘#x2a’)。

#oN

8進表現の‘N’ (‘#o52’)。

#bN

2進表現の‘N’ (‘#b101010’)。

#(…)

文字列のテキストプロパティ(文字列内のテキストプロパティを参照)。

#^

文字テーブル(文字テーブル型を参照)。

#s(hash-table …)

ハッシュテーブル(ハッシュテーブル型を参照)。

?C

文字(基本的な文字構文を参照)。

#$

バイトコンパイル済みファイルのカレントファイル名(ドキュメント文字列とコンパイルを参照)。これはEmacs Lispソースファイルで使用するためのものではない。

#@N

次の‘N’文字をスキップする(コメントを参照)。バイトコンパイル済みファイル内で使用されるものであって、Emacs Lispソースファイル内で使用するためのものではない。

#f

これに続くフォームがEmacs Lispリーダーで読み取れないことを示す。これは表示されることを意図したテキストだけに出現する読み取り構文(読み取れないフォームを示すための他の選択肢よりも見栄えがよくなると思われる場合)、でありLispファイル中に出現することは決してない。


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

2.3 コメント

コメント(comment)はプログラム中に記述されたテキストであり、そのプログラムを読む人間ためだけに存在するものであって、プログラムの意味には何の影響ももちません。Lispではそれが文字列や文字定数にある場合をのぞき、エスケープされていないセミコロン(‘;’)でコメントが開始されます。行の終端までがコメントになります。Lispリーダーはコメントを破棄します。コメントはLispシステム内でプログラムを表すLispオブジェクトの一部にはなりません。

#@count’構成は、次のcount個の文字をスキップします。これはプログラムにより生成されたバイナリーデータを含むコメントにたいして有用です。Emacs Lispバイトコンパイラーは出力ファイルにこれを使用します(バイトコンパイルを参照)。しかしソースファイル用ではありません。

コメントのフォーマットにたいする慣例は、コメント記述のヒントを参照してください。


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

2.4 プログラミングの型

Emacs Lispには2種類の一般的な型があります。1つはLispプログラミングに関わるもので、もう1つは編集に関わるものです。前者はさまざまな形で多くのLisp実装に存在します。後者はEmacs Lispに固有です。


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

2.4.1 整数型

内部にはfixnumsと呼ばれる小さい整数、およびbignumsという大きい整数という2種類の整数が存在します。

fixnumの値の範囲はマシンに依存します、最小のレンジは-536,870,912から536,870,911(30ビットでは -2**29 から 2**29 - 1) しかし多くのマシンはより広い範囲を提供します。

bignumは任意の精度をもつことができます。fixnumのオーバーフローする処理では、かわりにbignumをリターンされます。

eql=ですべての数値、fixnumならeqで比較することができます。整数がfixnumかbignumをテストするにはmost-negative-fixnummost-positive-fixnumで比較するか、便利な述語fixnumpbignumpを任意のオブジェクトに使用できます。

整数にたいする入力構文は、(10を基数とする)数字のシーケンスで、オプションで先頭に符号、最後にピリオドがつきます。Lispインタープリターにより生成されるプリント表現には、先頭の ‘+’や最後の‘.’はありません。

-1               ; 整数の-1
1                ; 整数の1
1.               ; これも整数の1
+1               ; これも整数の1

詳細は数値を参照してください。


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

2.4.2 浮動小数点数型

浮動小数点数は、コンピューターにおける科学表記に相当するものです。浮動小数点数を10の指数をともなう有理数として考えることができます。正確な有効桁数と可能な指数はマシン固有です。Emacsは値の保存にCデータ型のdoubleを使用し、内部的には10の指数ではなく、2の指数として記録します。

浮動小数点数のプリント表現には、(後に最低1つの数字をともなう)小数点と、指数のどちらか一方、または両方が必要です。たとえば‘1500.0’、‘+15e2’、‘15.0e+2’、‘+1500000e-3’、‘.15e4’は、いずれも浮動小数点数の1500を記述し、これらはすべて等価です。

詳細は数値を参照してください。


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

2.4.3 文字型

Emacs Lispでの文字(character)は、整数以外の何者でもありません。言い換えると、文字は文字コードで表現されます。たとえば文字Aは、整数の65として表現されます。

プログラムで文字を個別に使用するのは稀であり、文字のシーケンスとして構成される文字列(strings)として扱われるのがより一般的です。文字列型を参照してください。

文字列やバッファーの中の文字は、現在のところ0から4194303の範囲 — つまり22ビットに制限されています(文字コードを参照)。0から127のコードはASCIIコードで、残りは非ASCIIです(ASCII文字を参照)。キーボード入力を表す文字はコントロール(Control)、メタ(Meta)、シフト(Shift)などの修飾キーをエンコードするために、より広い範囲をもちます。

文字から可読なテキスト記述を生成する、メッセージ用の特別な関数が存在します。ヘルプメッセージの文字記述を参照してください。


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

2.4.3.1 基本的な文字構文

文字は実際には整数なので、文字のプリント表現は10進数です。文字にたいする入力構文も利用可能ですが、Lispプログラムでこの方法により文字を記述するのは、明解なプログラミングではありません。文字にたいしては、Emacs Lispが提供する、特別な入力構文を常に使用するべきです。これらの構文フォーマットはクエスチョンマークで開始されます。

英数字にたいする通常の入力構文は、クエスチョンマークと、その後にその文字を記述します。したがって文字Aは‘?A’、文字Bは‘?B’、文字aは‘?a’となります。

たとえば:

?Q ⇒ 81     ?q ⇒ 113

区切り文字(punctuation characters)にも同じ構文を使用できますが、区切り文字がLispで特別な意味をもつ場合には‘\’でクォートしなければなりません。たとえば‘?\(’が開カッコを記述する方法であり、同様に文字が‘\’なら、‘?\\’のようにクォートするために2つ目の‘\’を使用しなければなりません。

Ctrl+g(control-g)、バックスペース(backspace)、タブ(tab)、改行(newline)、垂直タブ(vertical tab)、フォームフィード(formfeed)、スペース(space)、キャリッジリターン(return)、デリート(del)、エスケープ(escape)はそれぞれ‘?\a’、‘?\b’、‘?\t’、‘?\n’、‘?\v’、‘?\f’、‘?\s’、‘?\r’、‘?\d’、‘?\e’と表すことができます(後にダッシュのついた‘?\s’は違う意味をもつ — これは後続の文字にたいしてスーパーによる修飾を適用する)。したがって、

?\a ⇒ 7                 ; control-g、C-g
?\b ⇒ 8                 ; バックスペース、BSC-h
?\t ⇒ 9                 ; タブ、TABC-i
?\n ⇒ 10                ; 改行、C-j
?\v ⇒ 11                ; 垂直タブ、C-k
?\f ⇒ 12                ; フォームフィード文字、C-l
?\r ⇒ 13                ; キャリッジリターン、RETC-m
?\e ⇒ 27                ; エスケープ文字、ESCC-[
?\s ⇒ 32                ; スペース文字、SPC
?\\ ⇒ 92                ; バックスラッシュ文字、\
?\d ⇒ 127               ; デリート文字、DEL

バックスラッシュがエスケープ文字の役割を果たすので、これらのバックスラッシュで始まるシーケンスはエスケープシーケンス(escape sequences)とも呼ばれます。この用語法は文字ESCとは関係ありません。‘\s’は文字定数としての使用を意図しており、文字定数の内部では単にスペースを記述します。

エスケープという特別な意味を与えずに、任意の文字の前にバックスラッシュの使用することは許されていて害もありません。したがって‘?\+’は‘?+’と等価です。ほとんどの文字の前にバックスラッシュを追加することに理由はありません。しかし文字‘()[]\;"’の前にはバックスラッシュを追加しなければならず、Lispコードを編集するEmacsコマンドが混乱するのを避けるために‘|'`#.,’の前にもバックスラッシュを追加するべきです。コードを読む人の混乱を避けるために、前に言及したASCII文字と類似したUnicode文字の前にもバックスラッシュを追加する必要があります。これを奨励するために、‘’のような一般的には混乱を招くエスケープされていない文字をハイライトします。スペース、タブ、改行、フォームフィードのような空白文字の前にもバックスラッシュを追加できます。しかしタブやスペースspaceのような実際の空白文字のかわりに、‘\t’や‘\s’のような可読性のあるエスケープシーケンスを使用するほうが明解です(スペースを後にともなうバックスラッシュを記述する場合、後続のテキストと区別するために、文字定数の後に余分なスペースを記述すること)。


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

2.4.3.2 一般的なエスケープ構文

特に重要なコントロール文字にたいする特別なエスケープシーケンスに加えて、Emacsは非ASCIIテキスト文字の指定に使用できる、何種類かのエスケープ構文を提供します。

  1. もしあればUnicode名で文字を指定できる。?\N{NAME}NAMEという名前のUnicode文字を表す。したがって‘?\N{LATIN SMALL LETTER A WITH GRAVE}’はと等価でありUnicode文字のU+00E0を意味する。名前中のスペースを空白文字(改行)の非空のシーケンスにして複数行文字列の入力を簡略化できる。
  2. Unicode値で文字を指定できる。?\N{U+X}はUnicodeコードポイントX (16進数値)を表す。また?\uxxxx?\Uxxxxxxxxはそれぞれコードポイントxxxxxxxxxxxxを表すxは(1つの16進数字)。たとえば?\N{U+E0}?\u00e0?\U000000E0と‘?\N{LATIN SMALL LETTER A WITH GRAVE}’に等しい。Unicode標準は‘U+10ffff’以下のコードポイントだけを定義するので、これより大きいコードポイントではEmacsはエラーをシグナルする。
  3. 文字を16進の文字コードで指定できる。16進エスケープシーケンスはバックスラッシュ、‘x’、および16進の文字コードにより構成される。したがって‘?\x41’は文字A、‘?\x1’は文字C-a?\xe0は文字à (グレイブアクセントつきのa)になる。‘x’の後に1つ以上の16進数を使用できるので、この方法で任意の文字を表すことができる。
  4. 8進の文字コードにより文字を指定できる。8進エスケープシーケンスは3桁までの8進数字をともなうバックスラッシュにより形成される。したがって‘?\101’は文字A、‘?\001’は文字C-a?\002は文字C-bを表す。この方法で指定できるのは8進コード777までの文字のみ。

これらのエスケープシーケンスは文字列内でも使用されます。文字列内の非ASCII文字を参照してください。


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

2.4.3.3 コントロール文字構文

他の入力構文を使用してコントロール文字を表すことができます。これは後にバックスラッシュ、カレット、対応する非コントロール文字(大文字か小文字)をともなうクエスチョンマークから構成されます。たとえば‘?\^I’と‘?\^i’はどちらも、値が9である文字C-iの有効な入力構文です。

^’のかわりに‘C-’を使用することもできます。したがって‘?\C-i’は‘?\^I’や‘?\^i’と等価です。

?\^I ⇒ 9     ?\C-I ⇒ 9

文字列やバッファーの中ではASCIIのコントロール文字だけが許されますが、キーボード入力にたいしては‘C-’により任意の文字をコントロール文字にすることができます。これらの非ASCIIのコントロール文字にたいするコントロール文字には 非コントロール文字にたいするコードと同様に、2**26 ビットが含まれます。すべてのテキスト端末が非ASCIIコントロール文字を生成できる訳ではありませんが、Xやその他のウィンドウシステムを使用すれば直接生成することができます。

歴史的な理由により、EmacsはDEL文字を?のコントロール文字として扱います:

?\^? ⇒ 127     ?\C-? ⇒ 127

結果として、Xでは有意な入力文字であるControl-?文字を、‘\C-’を使用して表現することは今のところできません。さまざまなLispファイルがこの方法でDELを参照するので、これを変更するのは簡単ではないのです。

コントロール文字の表現はファイルや文字列内で見ることができますが、わたしたちは‘^’構文を推奨します。キーボード入力にたいするコントロール文字に好ましいのは、‘C-’構文です。どちらを使用するかはプログラムの意味に影響しませんが、プログラムを読む人の理解を助けるでしょう。


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

2.4.3.4 メタ文字構文

メタ文字(meta character)とは、META修飾キーとともにタイプされた文字です。そのような文字を表す整数には 2**27 のビットがセットされています。基本的な文字コードの広い範囲を利用可能にするために、メタやその他の修飾にたいしては上位ビットを使用します。

文字列では、メタ文字を示すASCII文字に、 2**7 ビットが付加されます。したがって文字列に含めることができるメタ文字のコードは128から255の範囲となり、メタ文字は通常のASCII文字のメタ修飾されたバージョンとなります。文字列内でのMETA処理の詳細については、文字列内へのキーボードイベントの配置を参照してください。

メタ文字の入力構文には‘\M-’を使用します。たとえば‘?\M-A’はM-Aを意味します。8進文字コード(以下参照)や、‘\C-’、その他の文字にたいする他の構文とともに‘\M-’を使用できます。したがって、M-Aは‘?\M-A’や‘?\M-\101’と記述できます。同様にC-M-bは‘?\M-\C-b’、‘?\C-\M-b’、‘?\M-\002’と記述することができます。


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

2.4.3.5 その他の文字修飾ビット

グラフィック文字(graphic character)のcaseは文字コードで示されます。たとえばASCIIでは、文字‘a’と文字‘A’は区別されます。しかしASCIIにはコントロール文字が大文字なのか小文字なのかを表現する方法がありません。コントロール文字がタイプされたときシフトキーが使用されたかを示すために、Emacsは 2**25 のビットを使用します。この区別はX上でのGUIディスプレイのようなグラフィカルディスプレイでのみ利用できます。通常のテキスト端末はこれらの違いを報告しません。シフトをあらわすビットのためのLisp構文は‘\S-’です。したがって‘?\C-\S-o’や‘?\C-\S-O’は、Shift+Ctrl+o文字を表します。

Xウィンドウシステムは文字にセットするために、他にも3つ修飾ビット — ハイパー(hyper)スーパー(super)アルト(alt)を定義します。これらのビットにたいする構文は、‘\H-’、‘\s-’、‘\A-’です(これらのプレフィクスでは、caseは意味がある)。したがって‘?\H-\M-\A-x’はAlt-Hyper-Meta-xを表します(‘-’が後にない‘\s’はスペース文字を表すことに注意)。 数値としてはビット値2**22はアルト、2**23はスーパー、2**24はハイパーです。


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

2.4.4 シンボル型

GNU Emacs Lispでのシンボル(symbol)とは、名前をもつオブジェクトです。シンボル名は、そのシンボルのプリント表現としての役割があります。Lispの通常の使用では、1つのobarray(シンボルの作成とinternを参照)により、シンボル名は一意です — 2つのシンボルが同じ名前をもつことはありません。

シンボルは変数や関数名としての役割、プロパティリストを保持する役割をもつことができます。データ構造内にそのようなシンボルが存在することが確実に認識できるように、他のすべてのLispオブジェクトから区別するためだけの役割をもつ場合もあります。与えられたコンテキストにおいて、通常はこれらのうちの1つの使用だけが意図されます。しかし3つすべての方法で、1つのシンボルを独立して使用することもできます。

名前がコロン(‘:’)で始まるシンボルはキーワードシンボル(keyword symbol)と呼ばれます。これらのシンボルは自動的に定数として振る舞い、通常は未知のシンボルといくつかの特定の候補を比較することだけに使用されます。変更不可な変数を参照してください。

シンボル名にはどんな文字でも含めることができます。ほとんどのシンボル名は英字、数字、‘-+=*/’などの区切り文字で記述されます。このような名前には特別な区切り文字は必要ありません。名前が数字のように見えない限り、名前にはどのような文字も使用できます(名前が数字のように見える場合は、名前の先頭に‘\’を記述して強制的にシンボルとして解釈させる)。文字‘_~!@$%^&:<>{}?’はあまり使用されませんが、これらも特別な句読点文字を必要としません。他の文字も、バックスラッシュでエスケープすることにより、シンボル名に含めることができます。しかし文字列内でのバックスラッシュの使用とは対照的に、シンボル名でのバックスラッシュは、バックスラッシュの後の1文字をエスケープするだけです。たとえば文字列内では、‘\t’はタブ文字を表します。しかしシンボル名の中では、‘\t’は英字‘t’をクォートするに過ぎません。名前にタブ文字をもつシンボルを記述するには、(バックスラッシュを前置した)実際のタブを使用しなければなりません。しかし、そのようなことを行なうことは稀です。

Common Lispに関する注意:Common Lispでは明示的にエスケープされない限り、小文字は常に大文字に“フォールド(folded)”される。Emacs Lispでは大文字と小文字は区別される。

以下はシンボル名の例です。4つ目の例の中の‘+’は、シンボルが数字として読み取られるのを防ぐためにエスケープされていることに注意してください。6つ目の例では、名前の残りの部分により数字としては不正なのでエスケープの必要はありません。

foo                 ; foo’という名前のシンボル
FOO                 ; foo’とは別の、‘FOO’という名前のシンボル
1+                  ; 1+’という名前のシンボル
                    ;   (整数の‘+1’ではない)
\+1                 ; +1’という名前のシンボル
                    ;   (判読しにくい名前)
\(*\ 1\ 2\)         ; (* 1 2)’という名前のシンボル(悪い名前)
+-*/_~!@$%^&=:<>{}  ; +-*/_~!@$%^&=:<>{}’という名前のシンボル
                    ;   これらの文字のエスケープは不要

シンボル名がプリント表現としての役割をもつというルールの例外として、‘##’があります。これは、名前が空文字列のinternされたシンボルのプリント表現です。さらに‘#:foo’は、internされていないfooという名前のシンボルにたいするプリント表現です(通常、Lispリーダーはすべてのシンボルをinternする。シンボルの作成とinternを参照されたい)。


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

2.4.5 シーケンス型

シーケンス(sequence)とは、要素の順序セットを表現するLispオブジェクトです。Emacs Lispには2種類のシーケンス — リスト(lists)配列(arrays)があります。

リストはもっとも一般的に使用されるシーケンスです。リストは任意の型の要素を保持でき、要素の追加と削除により簡単に長さを変更できます。リストについては、次のサブセクションを参照してください。

配列は固定長のシーケンスです。配列はさらに文字列(strings)、ベクター(vectors)、文字テーブル(char-tables)、ブールベクター(bool-vectors)に細分されます。ベクターは任意の型の要素を保持できますが、文字列の要素は文字でなければならず、ブールベクターの要素はtnilでなければなりません。文字テーブルはベクターと似ていますが、有効な文字によりインデックスづけされる点が異なります。文字列内の文字は、バッファー内の文字のようにテキストプロパティをもつことができます(テキストのプロパティを参照)。しかしベクターはその要素が文字のときでも、テキストプロパティをサポートしません。

リスト、文字列、およびその他の配列型も、重要な類似点を共有します。たとえば、それらはすべて長さlをもち、要素は0からl-1でインデックスづけされます。いくつかの関数はシーケンス関数と呼ばれ、これらは任意の種類のシーケンスを許容します。たとえば、関数lengthは、任意の種類のシーケンスの長さを報告します。シーケンス、配列、ベクターを参照してください。

シーケンスは読み取りにより常に新たに作成されるため、同じシーケンスを2回読み取るのは一般的に不可能です。シーケンスにたいする入力構文を2回読み取った場合には、内容が等しい2つのシーケンスを得ます。これには1つ例外があります。空リスト()は、常に同じオブジェクトnilを表します。


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

2.4.6 コンスセルとリスト型

コンスセル(cons cell)CARスロット、CDRスロットと呼ばれる2つのスロットから構成されるオブジェクトです。それぞれのスロットはには、任意のLispオブジェクトを保持できます。そのときCARスロットに保持されるオブジェクトが何であれ、わたしたちは“このコンスセルのCAR”のような言い方をします。これはCDRの場合も同様です。

リスト(list)はコンスセルの連続するシリーズで、各コンスセルのCDRスロットは次のコンスセル、または空リストを保持します。空リストは実際にはシンボルnilです。詳細については、リストを参照してください。ほとんどのコンスセルはリストの一部として使用されるので、わたしたちはコンスセルにより構成される任意の構造を、リスト構造(list structure)という用語で参照します。

Cプログラマーにたいする注意: Lispのリストはコンスセルにより構築されるリンクリスト(linked list)として機能する。Lispではポインターは暗黙的なので、コンスセルのスロットが値を“保持(hold)”するのか、それとも値を“指す(point)”のかは区別しない。

コンスセルはLispの中核なので、コンスセルではないオブジェクトにたいする用語もあります。これらのオブジェクトはアトム(atoms)と呼ばれます。

リストにたいする入力構文とプリント表現は同じで左カッコ、任意の数の要素、右カコから構成されます。以下はリストの例です:

(A 2 "A")            ; 3要素のリスト
()                   ; 要素がないリスト(空リスト)
nil                  ; 要素がないリスト(空リスト)
("A ()")             ; 1要素のリスト: 文字列"A ()"
(A ())               ; 2要素のリスト: Aと空リスト
(A nil)              ; 同上
((A B C))            ; 1要素のリスト
                     ;   (この要素は、3要素のリスト)

読み取りではカッコの内側はリストの要素になります。つまりコンスセルは各要素から作成されます。コンスセルのCARスロットは要素を保持し、CDRスロットはリスト内の次のコンスセル(このコンスセルはリスト内の次の要素をする)を参照します。最後のコンスセルのCDRスロットはnilを保持するようにセットされます。

CARCDRという名称はLispの歴史に由来します。オリジナルのLisp実装はIBM 704コンピューターで実行されていました。ワードを2つの部分、つまり“address”と呼ばれる部分と、“decrement”と呼ばれる部分に分割していて、その際CARはaddress部から内容を取り出す命令で、CDRはdecrement部から内容を取り出す命令でした。これとは対照的に“cons cells”は、これらを作成する関数consから命名されました。この関数は関数の目的、すなわちセルを作る(construction of cells)という目的から命名されました。


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

2.4.6.1 ボックスダイアグラムによるリストの描写

コンスセルを表現するドミノのような1対のボックスによる図で、リストを説明することができます(Lispリーダーがこのような図を読み取ることはできない。人間とコンピューターが理解できるテキスト表記と異なり、ボックス図は人間だけが理解できる)。この図は3要素のリスト(rose violet buttercup)を表したものです:

    --- ---      --- ---      --- ---
   |   |   |--> |   |   |--> |   |   |--> nil
    --- ---      --- ---      --- ---
     |            |            |
     |            |            |
      --> rose     --> violet   --> buttercup

この図では、ボックスは任意のLispオブジェクトへの参照を保持できるスロットを表します。ボックスのペアーはコンスセルを表します。矢印はLispオブジェクト(アトム、または他のコンスセル)への参照を表します。

この例では、1番目のボックスは1番目のコンスセルで、それのCARrose(シンボル)を参照または保持します。2番目のボックスは1番目のコンスセルのCDRを保持し、次のボックスペアすなわち2番目のコンスセルを参照します。2番目のコンスセルのCARvioletで、CDRは3番目のコンスセルです。(最後の)3番目のコンスセルのCDRnilです。

同じリスト(rose violet buttercup)を、違うやり方で描いた別の図で表してみましょう:

 ---------------       ----------------       -------------------
| car   | cdr   |     | car    | cdr   |     | car       | cdr   |
| rose  |   o-------->| violet |   o-------->| buttercup |  nil  |
|       |       |     |        |       |     |           |       |
 ---------------       ----------------       -------------------

要素がないリストは空リスト(empty list)で、これはシンボルnilと同じです。言い換えるとnilはシンボルであり、かつリストでもあります。

以下はリスト(A ())、または等価な(A nil)をボックスと矢印で描いたものです:

    --- ---      --- ---
   |   |   |--> |   |   |--> nil
    --- ---      --- ---
     |            |
     |            |
      --> A        --> nil

以下はもっと複雑な例です。これは1番目の要素が2要素のリストであるような、3要素のリスト((pine needles) oak maple)を表します:

    --- ---      --- ---      --- ---
   |   |   |--> |   |   |--> |   |   |--> nil
    --- ---      --- ---      --- ---
     |            |            |
     |            |            |
     |             --> oak      --> maple
     |
     |     --- ---      --- ---
      --> |   |   |--> |   |   |--> nil
           --- ---      --- ---
            |            |
            |            |
             --> pine     --> needles

同じリストを2番目のボックス表記で表すと、以下のようになります:

 --------------       --------------       --------------
| car   | cdr  |     | car   | cdr  |     | car   | cdr  |
|   o   |   o------->| oak   |   o------->| maple |  nil |
|   |   |      |     |       |      |     |       |      |
 -- | ---------       --------------       --------------
    |
    |
    |        --------------       ----------------
    |       | car   | cdr  |     | car     | cdr  |
     ------>| pine  |   o------->| needles |  nil |
            |       |      |     |         |      |
             --------------       ----------------

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

2.4.6.2 ドットペア表記

ドットペア表記(dotted pair notation)は、CARCDRが明示的に表されたコンスセルの一般的な構文です。この構文では(a . b)CARがオブジェクトaCDRがオブジェクトbという意味になります。CDRがリストである必要がないので、ドットペア表記はより一般的なリスト構文です。しかしリスト構文が機能するような場合には、より扱いにくくなります。ドットペア表記では、リスト‘(1 2 3)’は‘(1 . (2 . (3 . nil)))’と記述されます。nilで終端されたリストにたいしては、どちらの表記法も使用できますが、リスト表記の方が通常は明解で便利です。リストをプリントする場合には、コンスセルのCDRがリストでないときだけドットペア表記が使用されます。

以下はボックスを使用してドットペア表記を表した例です。これはペア(rose . violet)を表します:

    --- ---
   |   |   |--> violet
    --- ---
     |
     |
      --> rose

最後のCDRが非nilのコンスセルのチェーンを表すので、ドットペア表記とリスト表記を組み合わせることができます。リストの最後の要素の後にドットを記述して、その後に最後のコンスセルのCDRを記述します。たとえば(rose violet . buttercup)は、(rose . (violet . buttercup))と等価です。オブジェクトは以下のようになります:

    --- ---      --- ---
   |   |   |--> |   |   |--> buttercup
    --- ---      --- ---
     |            |
     |            |
      --> rose     --> violet

構文(rose . violet . buttercup)は無効です。なぜならこれは何も意味していないからです。何か意味があるとしても、violetのためにCDRがすでに使用されているコンスセルのCDRに、buttercupを置くということになります。

リスト(rose violet)(rose . (violet))と等価であり、以下のようになります:

    --- ---      --- ---
   |   |   |--> |   |   |--> nil
    --- ---      --- ---
     |            |
     |            |
      --> rose     --> violet

同様に3要素のリスト(rose violet buttercup)は、(rose . (violet . (buttercup)))と等価です。 これは以下のようになります:

    --- ---      --- ---      --- ---
   |   |   |--> |   |   |--> |   |   |--> nil
    --- ---      --- ---      --- ---
     |            |            |
     |            |            |
      --> rose     --> violet   --> buttercup

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

2.4.6.3 連想リスト型

連想リスト(association list)またはalistは、要素がコンスセルであるように特別に構成されたリストです。各要素においては、CARキー(key)で、CDR連想値(associated value)であると考えます(連想値がCDRCARに保存される場合もある)。リストの先頭への連想値の追加と削除は簡単なので、連想リストはスタック(stack)にしばしば使用されます。

たとえば、

(setq alist-of-colors
      '((rose . red) (lily . white) (buttercup . yellow)))

これは変数alist-of-colorsに3要素のalistをセットします。最初の要素では、roseがキーでredが値になります。

alistとalist関数についての詳細な説明は連想リストを参照してください。(多くのキーの操作をより高速に行なう)テーブルを照合する他の手段についてはハッシュテーブルを参照してください。


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

2.4.7 配列型

配列(array)は、他のLispオブジェクトを保持または参照する任意の数のスロットから構成され、メモリーの連続ブロックに配列されます。配列の任意の要素へのアクセス時間は大体同じです。対照的にリストの要素にたいするアクセスは、リスト内でのその要素の位置に比例した時間を要します(リストの最後の要素にアクセスするにはリストの最初の要素にアクセスするより長い時間が必要)。

Emacsは文字列(strings)、ベクター(vectors)、ブールベクター(bool-vectors)、文字テーブル(char-tables)という4種の配列を定義します。

文字列は文字の配列であり、ベクターは任意のオブジェクトの配列です。ブールベクターはtnilだけを保持できます。この種の配列はシステムアーキテクチャー制限と利用可能なメモリーにしたがったもっとも大きいfixnumまでの任意の長さをもつことができます。文字テーブルは、任意の有効な文字コードによりインデックスづけされる疎な配列であり、任意のオブジェクトを保持することができます。

配列の最初の要素はインデックス0、2番目の要素はインデックス1、...となります。これは0基準(zero-origin)のインデックスづけと呼ばれます。たとえば、4要素の配列はインデックス0、1、2、3をもちます。利用できる最大のインデックス値は、配列の長さより1つ小さくなります。▼一度配列が作成されると、長さは固定されます。

Emacs Lispのすべての配列は、1次元です(他のほとんどのプログラミング言語は多次元配列をサポートするが、これらは必須ではない。ネストされた1次元配列により同じ効果を得ることが可能)。各種の配列は独自の入力構文をもちます。詳細は以降のセクションを参照してください。

配列型はシーケンス型のサブセットであり文字列型、ベクター型、ブールベクター型、文字テーブル型が含まれます。


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

2.4.8 文字列型

文字列(string)とは文字の配列です。Emacsがテキストエディターであることから予想できるように、文字列はたとえばLispシンボルの名前、ユーザーへのメッセージ、バッファーから抽出されたテキストの表現など多くの目的のために使用されます。Lispの文字列は定数です。文字列を評価すると、それと同じ文字列がリターンされます。

文字列を操作する関数については文字列と文字を参照してください。


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

2.4.8.1 文字列の構文

文字列にたいする入力構文は"like this"のようにダブルクォート、任意個数の文字、もう1つのダブルクォートから構成されます。文字列内にダブルクォートを含める場合は、それの前にバックスラッシュを記述します。したがって"\""は1つのダブルクォート文字だけを含む文字列です。同様にバックスラッシュを含める場合は、"this \\ is a single embedded backslash"のように、それの前にもう1つのバックスラッシュを記述します。

文字列にたいする入力構文では、改行(newline)は特別ではありません。ダブルクォートの間に改行を記述すれば、その改行は文字列内の文字となります。しかしエスケープされた改行 — 前に‘\’をともなう改行 — は文字列の一部とはなりません。同様にエスケープされたスペース‘\  も無視されます。

"It is useful to include newlines
in documentation strings,
but the newline is \
ignored if escaped."
     ⇒ "It is useful to include newlines
in documentation strings,
but the newline is ignored if escaped."

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

2.4.8.2 文字列内の非ASCII文字

Emacsの文字列内の非ASCII文字にたいしては2つのテキスト表現 — マルチバイト(multibyte)とユニバイト(unibyte)があります(テキストの表現方法を参照)。大まかに言うとユニバイト文字列にはraw(生)バイトが保存され、マルチバイト文字列には人間が読めるテキストが保存されます。ユニバイト文字列内の各文字はバイトであり、値は0から255となります。対照的にマルチバイト文字列内の各文字は、0から4194303の値をもつかもしれません(文字型を参照)。いずれも127より上の文字は非ASCIIです。

文字をリテラルとして記述することにより、文字列に非ASCII文字を含めることができます。マルチバイトのバッファーや文字列、あるいはマルチバイトとしてvisitされたファイル等、マルチバイトのソースから文字列定数を読み込む場合、Emacsは非ASCII文字をマルチバイト文字として読み取り、その文字列を自動的にマルチバイト文字列にします。ユニバイトのソースから文字列定数を読み込む場合、Emacsは非ASCII文字をユニバイト文字として読み取り、その文字列をユニバイト文字列にします。

マルチバイト文字列内にリテラルとして文字を記述するかわりに、エスケープシーケンスを使用して文字コードとして記述できます。エスケープシーケンスについての詳細は、一般的なエスケープ構文を参照してください。

文字列定数内でUnicodeスタイルのエスケープシーケンス‘\uNNNN’または‘\U00NNNNNN’を使用する場合、(たとえASCII文字であっても)Emacsは自動的に文字列をマルチバイトとみなします。

文字列定数内で16進エスケープシーケンス(‘\xn’)と8進エスケープシーケンス(‘\n’)を使用することもできます。しかし注意してください: 文字列定数が16進または8進のエスケープシーケンスを含み、それらのエスケープシーケンスすべてがユニバイト文字(256より小)を指定していて、その文字列内に他にリテラルの非ASCII文字またはUnicodeスタイルのエスケープシーケンスが存在しない場合、Emacsは自動的に文字列をユニバイト文字列とみなします。つまり文字列内のすべての非ASCII文字は8ビットのrawバイトとみなされます。

16進および8進のエスケープシーケンスでは、エスケープされた文字コードに可変個の数字が含まれるかもしれないので、それに続く文字で16進および8進として有効ではない最初の文字は、そのエスケープシーケンスを終了させます。文字列内の次の文字が16進または8進として解釈できる文字の場合は、‘\  (バックスラッシュとスペース)を記述して、エスケープシーケンスを終了できます。たとえば‘\xe0\ はgrave accentつきの‘a’という1文字を表します。文字列内の‘\  はバックスラッシュ改行と同様です。これは文字列内の文字とはなりませんが、先行する16進エスケープを終了します。


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

2.4.8.3 文字列内の非プリント文字

リテラル文字と同様に、文字列定数内でバックスラッシュによるエスケープシーケンスを使用できます(ただし文字定数を開始するクエスチョンマークは使用しない)。たとえば非プリント文字のタブとC-aを含む文字列は、"\t, \C-a"のように、それらの間にカンマとスペースを記述します。文字にたいする入力構文については文字型を参照してください。

しかしバックスラッシュによるエスケープシーケンスとともに記述できるすべての文字が、文字列内で有効というわけではありません。文字列が保持できるコントロール文字はASCIIコントロール文字だけです。ASCIIコントロール文字では、文字列のcaseは区別されません。

正確に言うと、文字列はメタ文字を保持できません。しかし文字列がキーシーケンスとして使用される場合には、文字列内でメタ修飾されたASCII文字を表現するための方法を提供する特別な慣習があります。文字列定数内でメタ文字を示すために‘\M-’構文を使用した場合、これは文字列内の文字の 2**7 のビットをセットします。その文字列がdefine-keyまたはlookup-keyで使用される場合、この数字コードは等価なメタ文字に変換されます。文字型を参照してください。

文字列はハイパー(hyper)、スーパー(super)、アルト(alt)で修飾された文字を保持できません。


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

2.4.8.4 文字列内のテキストプロパティ

文字列にはその文字自身に加えて、文字のプロパティも保持することができます。これにより特別なことをしなくても、文字列とバッファーとの間でテキストをコピーするプログラムが、テキストプロパティをコピーすることが可能になります。テキストプロパティが何を意味するかについてはテキストのプロパティを参照してください。テキストプロパティをもつ文字列は、特別な入力構文とプリント構文を使用します。

#("characters" property-data...)

ここでproperty-dataは,3個でグループ化された0個以上の要素から構成されます:

beg end plist

要素begおよびendは整数で、文字列内のインデックスの範囲を指定します。plistはその範囲にたいするプロパティリストです。たとえば、

#("foo bar" 0 3 (face bold) 3 4 nil 4 7 (face italic))

これはテキスト内容が‘foo bar’で、最初の3文字はfaceプロパティに値boldをもち、最後の3文字はfaceプロパティに値italicをもつことを表します(4番目の文字にはテキストプロパティはないので、プロパティリストはnil。実際には範囲の中の指定されていない文字はデフォルトではプロパティをもたないので、範囲のプロパティリストをnilと指定する必要ない)。


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

2.4.9 ベクター型

ベクター(vector)は任意の型の要素からなる1次元の配列です。ベクター内の任意の要素へのアクセスに要す時間は一定です(リストの場合では要素へのアクセスに要す時間は、リストの先頭からその要素までの距離に比例する)。

ベクターのプリント表現は左角カッコ(left square bracket)、要素、右角カッコ(right square bracket)から構成されます。これは入力構文でもあります。数字や文字列と同様にベクターは評価において定数と判断されます。

[1 "two" (three)]      ; 3要素のベクター
     ⇒ [1 "two" (three)]

ベクターに作用する関数についてはベクターを参照してください。


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

2.4.10 文字テーブル型

文字テーブル(char-table)は任意の型の要素をもつ1次元の配列であり、文字コードによりインデックスづけされます。文字テーブルは、文字コードに情報を割り当てることを必要とする多くの処理を簡単にするための、特別な追加の機能をもちます — たとえば文字テーブルは継承する親、デフォルト値、特別な目的のために使用する余分なスロットをいくつかもつことができます。文字テーブルは文字セット全体にたいして1つの値を指定することもできます。

文字テーブルのプリント表現はベクターと似ていますが、最初に余分な‘#^’があります1

文字テーブルを操作する特別な関数については文字テーブルを参照してください。文字テーブルの使用には以下が含まれます:


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

2.4.11 ブールベクター型

ブールベクター(bool-vector)は、要素がtnilのいずれかでなければならない1次元の配列です。

ブールベクターのプリント表現は文字列と似ていますが、後に長さを記述した‘#&’で始まります。これに続く文字列定数は、ビットマップとして実際に内容を指定するブールベクターです — 文字列定数内のそれぞれの“文字”は8ビットを含み、これはブールベクターの次の8要素を指定します(1はt、0はnilです)。文字の最下位ビットが、ブールベクターの最下位のインデックスに対応しています。

(make-bool-vector 3 t)
     ⇒ #&3"^G"
(make-bool-vector 3 nil)
     ⇒ #&3"^@"

C-g’の2進コードは111、‘C-@’はコード0の文字なのでこの結果は理にかなっています。

長さが8の倍数でなければプリント表現には余分な要素が表示されますが、これらの余分な要素に意味はありません。たとえば以下の例では、最初の3ビットだけが使用されるので2つのブールベクターは等価です:

(equal #&3"\377" #&3"\007")
     ⇒ t

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

2.4.12 ハッシュテーブル型

ハッシュテーブルは非常に高速な照合テーブルの一種で、キーを対応する値にマップするalistと似ていますがより高速です。ハッシュテーブルのプリント表現では、以下のようにハッシュテーブルのプロパティと内容を指定します:

(make-hash-table)
     ⇒ #s(hash-table size 65 test eql rehash-size 1.5
                             rehash-threshold 0.8125 data ())

ハッシュテーブルについての詳細はハッシュテーブルを参照してください。


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

2.4.13 関数型

他のプログラミング言語の関数と同様、Lisp関数は実行可能なコードです。他の言語と異なり、Lispの関数はLispオブジェクトでもあります。Lispのコンパイルされていない関数はラムダ式 — つまり1番目の要素がシンボルlambdaであるリストです(ラムダ式を参照)。

ほとんどのプログラミング言語では名前のない関数はありません。Lispでは関数に本質的な名前はありません。名前がなくてもラムダ式を関数として呼び出すことができます。これを強調するために、わたしたちはこれを無名関数(anonymous function)とも呼びます(無名関数を参照)。Lispの名前つき関数は関数セルに有効な関数がセットされた単なるシンボルです(関数の定義を参照)。

ほとんどの場合、関数はLispプログラム内のLisp式の名前が記述されたところで呼び出されます。しかし実行時に関数オブジェクトを構築または取得してから、プリミティブ関数funcallおよびapplyにより呼び出すことができます。関数の呼び出しを参照してください。


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

2.4.14 マクロ型

Lispマクロ(Lisp macro)はLisp言語を拡張するユーザー定義の構成です。これはオブジェクトとしてではなく関数のように表現されますが、引数の渡し方の意味が異なります。Lispマクロの形式はリストです。これは最初の要素がmacroで、CDRがLisp関数オブジェクト(lambdaシンボルを含む)であるようなリストです。

Lispマクロオブジェクトは通常、ビルトインのdefmacro関数で定義されますが、macroで始まる任意のリストもEmacsにとってはマクロです。マクロを記述する方法の説明はマクロを参照してください。

警告: Lispマクロとキーボードマクロ(キーボードマクロを参照)は完全に別の物である。修飾なしで“マクロ”という単語を使用したときは、キーボードマクロではなくLispマクロのことを指す。


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

2.4.15 プリミティブ関数型

プリミティブ関数(primitive function)とは、Cプログラミング言語で記述されたLispから呼び出せる関数です。プリミティブ関数はsubrsビルトイン関数(built-in functions)とも呼ばれます(単語“subr”は“サブルーチン(subroutine)”が由来)。ほとんどのプリミティブ関数は、呼び出されたときにすべての引数を評価します。すべての引数を評価しないプリミティブ関数はスペシャルフォーム(special form)と呼ばれます(スペシャルフォームを参照)。

呼び出す側からすれば、その関数がプリミティブ関数かどうかは問題になりません。しかしプリミティブ関数をLispで記述された関数で再定義した場合に問題になります。理由はそのプリミティブ関数がCコードから直接呼び出されているかもしれないからです。Lispから再定義した関数を呼び出すと新しい定義を使用するでしょうが、Cコードから呼び出すとビルトインの定義が使用されるでしょう。したがって、プリミティブ関数の再定義はしないでください

関数(function)という用語で、LispやCで記述されたすべてのEmacs関数を参照します。Lispで記述された関数についての情報は関数型を参照してください。

プリミティブ関数に入力構文はなく、サブルーチン名とともにハッシュ表記でプリントします。

(symbol-function 'car)          ; そのシンボルの関数セルに
                                ;     アクセスする
     ⇒ #<subr car>
(subrp (symbol-function 'car))  ; これはプリミティブ関数?
     ⇒ t                ;    そのとおり

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

2.4.16 バイトコード関数型

バイトコード関数オブジェクト(byte-code function objects)は、Lispコードをバイトコンパイルすることにより生成されます(バイトコンパイルを参照)。バイトコード関数オブジェクトは、内部的にはベクターによく似ています。しかしバイトコード関数オブジェクトが関数呼び出しのように見える場合、評価プロセスによりこのデータ型は特別に処理されます。バイトコード関数オブジェクトを参照してください。

バイトコード関数オブジェクトのプリント表現と入力構文はベクターのものと似ていますが、開き角カッコ‘[’の前に‘#’があります。


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

2.4.17 レコード型

レコード(record)vectorと似ていますが、最初の要素はtype-ofでリターンされる型を保持するために使用されます。レコードの主要目的はプログラマーがEmacsのビルトインではない新たな型を作成することを可能にすることです。

レコードに作用する関数についてはレコードを参照してください。


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

2.4.18 型記述子

型記述子(type descriptor)は型に関する情報を保持するrecordです。レコードの1スロット目には型を命名するシンボルでなければならず、type-ofrecordオブジェクトの型をリターンするためにこれに依存しています。他の型記述子スロットをEmacsは使用しません。これらをLisp拡張が使用するのは自由です。

cl-structure-classのインスタンスはすべて型記述子の例です。


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

2.4.19 autoload型

autoloadオブジェクト(autoload object)は、最初の要素がシンボルautoloadのリストです。これはシンボルの関数定義として保存され、実際の定義にたいする代替としての役割をもちます。autoloadオブジェクトは、必要な時にロードされるLispコードファイルの中で実際の定義を見つけることができることを宣言します。これにはファイル名と、それに加えて実際の定義についての他のいくつかの情報が含まれます。

ファイルのロード後、そのシンボルはautoloadオブジェクトではない新しい関数定義をもつはずです。新しい定義は、最初からそこにあったかのように呼び出されます。ユーザーの観点からは関数呼び出しは期待された動作、つまりロードされたファイル内の関数定義を使用します。

autoloadオブジェクトは通常、シンボルの関数セルにオブジェクトを保存する関数autoloadにより作成されます。詳細はautoloadを参照してください。


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

2.4.20 ファイナライザー型

ファイナライザーオブジェクト(finalizer object)は、オブジェクトがもはや必要なくなった後のLispコードのクリーンアップを助けます。ファイナライザーは、Lisp関数オブジェクトを保持します。ガーベージコレクションをパス(通過)した後にファイナライザーオブジェクトが到達不能になったとき、Emacsはそのファイナライザーに関連付けられた関数オブジェクトを呼び出します。ファイナライザーの到達可否の判定時、もしかしてファイナライザーオブジェクト自身が参照を離さないのではないかと心配することなくファイナライザーを使用できるように、Emacsはファイナラーオブジェト自身からの参照は勘定しません。

ファイナラーザー内でのエラーは*Messages*にプリントされます。その関数が失敗しても、Emacsは与えられたファイナライザーオブジェクトに関連付けられた関数を正確に1回実行します。

Function: make-finalizer function

functionを実行するファイナライザーを作成する。functionはガーベージコレクション後、リターンされたファイナライザーオブジェクトが到達不能になったときに実行される。そのファイナライザーオブジェクトがファイナライザーオブジェクトからの参照を通じてのみ到達可能なら、functionの実行是非の判断時の目的にたいして、それは到達可能とみなされない。functionはファイナライザーオブジェクトごとに1回実行される。


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

2.5 編集用の型

前セクションの型は一般的なプログラミング目的のために使用され、これらの型のほとんどはLisp方言のほとんどで一般的です。Emacs Lispは編集に関する目的のために、いくつかの追加のデータ型を提供します。


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

2.5.1 バッファー型

バッファー(buffer)とは、編集されるテキストを保持するオブジェクトです(バッファーを参照)。ほとんどのバッファーはディスクファイル(ファイルを参照)の内容を保持するので編集できますが、他の目的のために使用されるものもいくつかあります。ほとんどのバッファーはユーザーにより閲覧されることも意図しているので、いつかはウィンドウ内(ウィンドウを参照)に表示されます。しかしバッファーはウィンドウに表示される必要はありません。バッファーはそれぞれ、ポイント(point)と呼ばれる位置指定をもちます(ポジションを参照)。ほとんどの編集コマンドは、カレントバッファー内のポイントに隣接する内容を処理します。常に1つのバッファーがカレントバッファー(current buffer)です。

バッファーの内容は文字列によく似ていますが、バッファーはEmacs Lispの文字列と同じようには使用されず、利用可能な操作は異なります。たとえば文字列にテキストを挿入するためには部分文字列の結合が必要であり、結果が完全に新しい文字列オブジェクトになるのにたいして。バッファーでは既存のバッファーに効率的にテキストを挿入してバッファーの内容を変更できます。

標準的なEmacs関数の多くは、カレントバッファー内の文字を操作したりテストするためのものです。このマニュアルはこれらの関数の説明のために、1つのチャプターを設けています(テキストを参照)。

他のデータ構造のいくつかは、各バッファーに関連付けられています:

ローカルキーマップと変数リストは、グローバルなバインディングや値を個別にオーバーライドするためのエントリーを含みます。これらは実際にプログラムを変更することなく、異なるバッファーでプログラムの振る舞いをカスタマイズするために使用されます。

バッファーはインダイレクト(indirect: 間接) — つまり他のバッファーとテキストを共有するがそれぞれ別に表示する — かもしれません。インダイレクトバッファーを参照してください。

バッファーに入力構文はありません。バッファーはバッファー名を含むハッシュ表記でプリントされます。

(current-buffer)
     ⇒ #<buffer objects-ja.texi>

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

2.5.2 マーカー型

マーカー(marker)は特定のバッファー内の位置を表します。したがってマーカーには2つの内容 — 1つはバッファー、もう1つは位置 — をもちます。バッファーのテキストの変更では、マーカーが常にバッファー内の同じ2つの文字の間に位置することを確実にするために、必要に応じて自動的に位置の値が再配置されます。

マーカーは入力構文をもちません。マーカーはカレントの文字位置とそのバッファー名を与える、ハッシュ表記でプリントされます。

(point-marker)
     ⇒ #<marker at 10779 in objects-ja.texi>

マーカーのテスト、作成、コピー、移動の方法についての情報はマーカーを参照してください。


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

2.5.3 ウィンドウ型

ウィンドウ(window)はEmacsがバッファーを表示するために使用するスクリーンの範囲を記述します。すべての生きたウィンドウ(Emacsウィンドウの基本概念を参照)には関連付けられた1つのバッファーがあり、バッファーの内容はそのウィンドウに表示されます。それとは対照的に、あるバッファーは1つのウィンドウに表示されるか表示されないか、それとも複数のウィンドウに表示されるかもしれません。ウィンドウはスクリーン上でフレームにグループ化されます。それらのウィンドウはただ1つのフレームに属します。フレーム型を参照してください。

同時に複数のウィンドウが存在するかもしれませんが、常に1つのウィンドウが選択されたウィンドウ(selected window)になります(ウィンドウの選択を参照)。Emacsがコマンドにたいして準備できているときは、(通常は)カーソルが表示されるウィンドウが選択されたウィンドウです。選択されたウィンドウは、通常はカレントバッファー(カレントバッファーを参照)を表示しますがこれは必須ではありません。

ウィンドウは入力構文をもちません。ウィンドウはウィンドウ番号と表示されているバッファー名を与える、ハッシュ表記でプリントされます。与えられたウィンドウに表示されるバッファーは頻繁に変更されるかもしれないので、一意にウィンドウを識別するためにウィンドウ番号が存在します。

(selected-window)
     ⇒ #<window 1 on objects-ja.texi>

ウィンドウに作用する関数の説明はウィンドウを参照してください。


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

2.5.4 フレーム型

フレーム(frame)とは1つ以上のEmacsウィンドウを含むスクリーン領域です。スクリーン領域を参照するためにEmacsが使用するLispオブジェクトを指す場合にも“フレーム”という用語を使用します。

フレームは入力構文をもちません。フレームはフレームのタイトルとメモリー内のアドレス(フレームを一意に識別するのに有用)を与えるハッシュ表記でプリントされます。

(selected-frame)
     ⇒ #<frame emacs@psilocin.gnu.org 0xdac80>

フレームに作用する関数の説明はフレームを参照してください。


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

2.5.5 端末型

端末(terminal)は1つ以上のEmacsフレーム(フレーム型を参照)を表示する能力があるデバイスです。

端末は入力構文をもちません。端末はその端末の順序番号とTTYデバイスファイル名を与える、ハッシュ表記でプリントされます。

(get-device-terminal nil)
     ⇒ #<terminal 1 on /dev/tty>

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

2.5.6 ウィンドウ構成型

ウィンドウ構成(window configuration)はフレーム内のウィンドウの位置とサイズ、内容についての情報を保持します。これにより後で同じウィンドウ配置を再作成できます。

ウィンドウ構成は入力構文をもちません。ウィンドウ構成のプリント表現は‘#<window-configuration>’のようになります。ウィンドウ構成に関連するいくつかの関数の説明はウィンドウの構成を参照してください。


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

2.5.7 フレーム構成型

フレーム構成(frame configuration)はすべてのフレーム内のウィンドウの位置とサイズ、内容についての情報を保持します。これは基本型ではありません — 実際のところ、これはCARframe-configurationCDRがalistであるようなリストです。それぞれのalist要素は、その要素のCARに示される1つのフレームを記述します。

フレーム構成に関連するいくつかの関数の説明はフレーム構成を参照してください。


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

2.5.8 プロセス型

プロセス(process)という単語は、通常は実行中のプログラムを意味します。Emacs自身はこの種のプロセス内で実行されます。しかしEmacs Lispでは、プロセスとはEmacsプロセスにより作成されたサブプロセスを表すLispオブジェクトです。シェル、GDB、ftp、コンパイラーなどのプログラムは、Emacsのサブプロセスとして実行されEmacsの能力を拡張します。さらに操作を行なうために、EmacsサブプロセスはEmacsからテキスト入力を受け取り、テキスト出力をEmacsにリターンします。Emacsがサブプロセスにシグナルを送ることもできます。

プロセスオブジェクトは入力構文をもちません。プロセスオブジェクトはプロセス名を与えるハッシュ表記でプリントされます。

(process-list)
     ⇒ (#<process shell>)

プロセスの作成、削除、プロセスに関する情報のリターン、入力やシグナルの送信、出力の受信を行なう関数についての情報はプロセスを参照してください。


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

2.5.9 スレッド型

Emacsでのスレッド(thread)とはEmacs Lispの実行スレッドとは別のスレッドを表します。これは自身のLispプログラムを実行して、自身のカレントバッファーを所有して、そのスレッドにロックされたサブプロセスをもつことができます(サブプロセスの出力を受け取ることができるのはそのスレッドのみ)。スレッドを参照してください。

スレッドオブジェクトは入力構文をもちません。スレッドオブジェクトは(名前を与えられていれば)スレッド名を与えるハッシュ表記かメモリー内のアドレスでプリントされます。

(all-threads)
    ⇒ (#<thread 0176fc40>)

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

2.5.10 ミューテックス型

ミューテックス(mutex)とはスレッド間で同期をとるためにスレッドが所有と非所有することができる排他ロックです。ミューテックスを参照してください。

ミューテックスオブジェクトは入力構文をもちません。プロセスオブジェクトは(名前を与えられていれば)ミューテックス名を与えるハッシュ表記かメモリー内のアドレスでプリントされます。

(make-mutex "my-mutex")
    ⇒ #<mutex my-mutex>
(make-mutex)
    ⇒ #<mutex 01c7e4e0>

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

2.5.11 状態変数型

状態変数(condition variable)はミューテックスがサポートするよりも複雑な非同期スレッドのためのデバイスです。スレッドは別のスレッドが状態を通知したときに再開するように状態変数を待機することができます。

状態変数オブジェクトは入力構文をもちません。プロセスオブジェクトは(名前が与えられていれば)状態変数の名前を与えるハッシュ表記かメモリー内のアドレスでプリントされます。

(make-condition-variable (make-mutex))
    ⇒ #<condvar 01c45ae8>

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

2.5.12 ストリーム型

ストリーム(stream)とは、文字のソースまたはシンクとして — つまり入力として文字を供給したり、出力として文字を受け入れるために使用できるオブジェクトです。多くの異なるタイプ — マーカー、バッファー、文字列、関数をこの方法で使用できます。ほとんどの場合、入力ストリーム(文字列ソース)はキーボード、バッファー、ファイルから文字を受け取り、出力ストリーム(文字シンク)は文字を*Help*バッファーのようなバッファーやエコーエリアに文字を送ります。

オブジェクトnilは、他の意味に加えてストリームとして使用されることがあります。nilは変数standard-inputstandard-outputの値を表します。オブジェクトtも入力としてミニバッファー(ミニバッファーを参照)、出力としてエコーエリア(エコーエリアを参照)の使用を指定するストリームになります。

ストリームは特別なプリント表現や入力構文をもたず、それが何であれそれらの基本型としてプリントされます。

パース関数およびプリント関数を含む、ストリームに関連した関数の説明はLispオブジェクトの読み取りとプリントを参照してください。


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

2.5.13 キーマップ型

キーマップ(keymap)はユーザーがタイプした文字をコマンドにマップします。このマップはユーザーのコマンド入力が実行される方法を制御します。キーマップは、実際にはCARがシンボルkeymapであるようなリストです。

キーマップの作成、プレフィクスキーの処理、ローカルキーマップやグローバルキーマップ、キーバインドの変更についての情報はキーマップを参照してください。


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

2.5.14 オーバーレイ型

オーバーレイ(overlay)はバッファーの一部に適用するプロパティを指定します。それぞれのオーバーレイはバッファーの指定された範囲に適用され、プロパティリスト(プロパティ名と値が交互に記述された要素のリスト)を含みます。オーバーレイプロパティは、バッファーの指定された一部を、一時的に異なるスタイルで表示するために使用されます。オーバーレイは入力構文をもたず、バッファー名と範囲の位置を与えるハッシュ表記でプリントされます。

オーバーレイを作成したり使用する方法についての情報はオーバーレイを参照してください。


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

2.5.15 フォント型

fontはグラフィカルな端末上のテキストを表示する方法を指定します。実際には異なる3つのフォント型 — フォントオブジェクト(font objects)フォントスペック(font specs)フォントエンティティー(font entities) — が存在します。これらは入力構文をもちません。これらのプリント構文は‘#<font-object>’、‘#<font-spec>’、‘#<font-entity>’のようになります。これらのLispオブジェクトの説明は低レベルのフォント表現を参照してください。


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

2.5.16 Xwidget型

xwidgetとはバッファー内に埋め込みができる、ウェブブラウザのような特別な表示要素のことです。xwidgetを表示しているウィンドウはそれぞれ、xwidgetビュー(xwidget view)ももつことができます。Xウィンドウにおいては、ウィジェットの表示に使用される単一のウィンドウに相当するのがxwidgetビューです。

これらのオブジェクトはいずれも読み取りができません。プリント構文はそれぞれ‘#<xwidget>’、‘#<xwidget-view>’のようになります。xwidgetに関する詳細については埋め込みネイティブウィジェットを参照してください。


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

2.6 循環オブジェクトの読み取り構文

複雑なLispオブジェクトでの共有された構造や循環する構造を表すために、リーダー構成‘#n=’と‘#n#’を使用することができます。

後でオブジェクトを参照するには、オブジェクトの前で#n=を使用します。その後で、他の場所にある同じオブジェクトを参照するために、#n#を使用することができます。ここでnは任意の整数です。たとえば以下は、1番目の要素が3番目の要素にも繰り替えされるリストを作成する方法です:

(#1=(a) b #1#)

これは、以下のような通常の構文とは異なります

((a) b (a))

これは1番目の要素と3番目の要素がそっくりなリストですが、これらは同じLispオブジェクトではありません。以下で違いを見ることができます:

(prog1 nil
  (setq x '(#1=(a) b #1#)))
(eq (nth 0 x) (nth 2 x))
     ⇒ t
(setq x '((a) b (a)))
(eq (nth 0 x) (nth 2 x))
     ⇒ nil

“要素”として自身を含むような循環する構造を作成するために、同じ構文を使用できます。以下は例です:

#1=(a #1#)

これは2番目の要素がそのリスト自身であるリストを作成します。これが実際にうまくいくのか、以下で確認できます:

(prog1 nil
  (setq x '#1=(a #1#)))
(eq x (cadr x))
     ⇒ t

変数print-circleを非nil値にバインドした場合、Lispプリンターは、循環および共有されるLispオブジェクトを記録するこの構文を生成することができます。出力に影響する変数を参照してください。


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

2.7 型のための述語

関数が呼び出されたとき、Emacs Lispインタープリター自身はその関数に渡された実際の引数の型チェックは行ないません。それが行なえないのは、Lispにおける関数の引数は他のプログラミング言語のようなデータ型宣言をもたないからです。したがって実際の引数が、その関数が使用できる型に属するかどうかをテストするのは、それぞれの関数に任されています。

すべてのビルトイン関数は適切なときに実際の引数の型チェックを行い、引数の型が違う場合はwrong-type-argumentエラーをシグナルします。たとえば以下は、+の引数に+が扱うことができない引数を渡したとき何が起こるかの例です:

(+ 2 'a)
     error→ Wrong type argument: number-or-marker-p, a

異なる型にたいして異なる処理をプログラムに行なわせる場合は、明示的に型チェックを行なわなければなりません。オブジェクトの型をチェックするもっとも一般的な方法は型述語(type predicate)関数の呼び出しです。Emacsはそれぞれの型にたいする型述語をもち、組み合わされた型にたいする述語もあります。

型述語関数は1つの引数をとり、その引数が適切な型であればt、そうでなければnilをリターンします。述語関数にたいする一般的なLisp慣習にしたがい、ほとんどの型述語の名前は‘p’で終わります。

以下はリストにたいしてチェックを行なう述語listpと、シンボルにたいしてチェックを行なう述語symbolpの例です。

(defun add-on (x)
  (cond ((symbolp x)
         ;; XがシンボルならLISTにputする
         (setq list (cons x list)))
        ((listp x)
         ;; Xがリストならその要素をLISTに追加
         (setq list (append x list)))
        (t
         ;; シンボルとリストだけを処理する
         (error "Invalid argument %s in add-on" x))))

以下のテーブルは事前定義された型述語(アルファベット順)と、さらに情報を得るためのリファレンスです。

atom

atomを参照のこと。

arrayp

arraypを参照のこと。

bignump

floatpを参照のこと。

bool-vector-p

bool-vector-pを参照のこと。

booleanp

booleanpを参照のこと。

bufferp

bufferpを参照のこと。

byte-code-function-p

byte-code-function-pを参照のこと。

compiled-function-p

compiled-function-pを参照のこと。

case-table-p

case-table-pを参照のこと。

char-or-string-p

char-or-string-pを参照のこと。

char-table-p

char-table-pを参照のこと。

commandp

commandpを参照のこと。

condition-variable-p

condition-variable-pを参照のこと。

consp

conspを参照のこと。

custom-variable-p

custom-variable-pを参照のこと。

fixnump

floatpを参照のこと。

floatp

floatpを参照のこと。

fontp

低レベルのフォント表現を参照のこと。

frame-configuration-p

frame-configuration-pを参照のこと。

frame-live-p

frame-live-pを参照のこと。

framep

framepを参照のこと。

functionp

functionpを参照のこと。

hash-table-p

hash-table-pを参照のこと。

integer-or-marker-p

integer-or-marker-pを参照のこと。

integerp

integerpを参照のこと。

keymapp

keymappを参照のこと。

keywordp

変更不可な変数を参照のこと。

listp

listpを参照のこと。

markerp

markerpを参照のこと。

mutexp

mutexpを参照のこと。

nlistp

nlistpを参照のこと。

number-or-marker-p

number-or-marker-pを参照のこと。

numberp

numberpを参照のこと。

overlayp

overlaypを参照のこと。

processp

processpを参照のこと。

recordp

recordpを参照のこと。

sequencep

sequencepを参照のこと。

string-or-null-p

string-or-null-pを参照のこと。

stringp

stringpを参照のこと。

subrp

subrpを参照のこと。

symbolp

symbolpを参照のこと。

syntax-table-p

syntax-table-pを参照のこと。

threadp

threadpを参照のこと。

vectorp

vectorpを参照のこと。

wholenump

wholenumpを参照のこと。

window-configuration-p

window-configuration-pを参照のこと。

window-live-p

window-live-pを参照のこと。

windowp

windowpを参照のこと。

あるオブジェクトがどの型かチェックするもっとも一般的な方法は、関数type-ofの呼び出しです。オブジェクトは、ただ1つだけの基本型に属することを思い出してください。type-ofは、それがどの型かを告げます(Lispのデータ型を参照)。しかしtype-ofは基本型以外の型については何も知りません。ほとんどの場合では、type-ofより型述語を使用するほうが便利でしょう。

Function: type-of object

この関数はobjectの基本型を名前とするシンボルをリターンする。リターン値はシンボルbool-vectorbufferchar-tablecompiled-functioncondition-variableconsfinalizerfloatfont-entityfont-objectfont-specframehash-tableintegermarkermutexoverlayprocessstringsubrsymbolthreadvectorwindowwindow-configurationのいずれか。ただしobjectがレコードなら最初のスロットで指定された型をリターンする。レコードを参照のこと。

(type-of 1)
     ⇒ integer
(type-of 'nil)
     ⇒ symbol
(type-of '())    ; ()nil
     ⇒ symbol
(type-of '(x))
     ⇒ cons
(type-of (record 'foo))
     ⇒ foo

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

2.8 同等性のための述語

ここでは2つのオブジェクトの同一性をテストする関数を説明します。(たとえば文字列などの)特定の型のオブジェクト同士で内容の同一性をテストするには、別の関数を使用します。これらの述語にたいしては、そのデータ型を説明する適切なチャプターを参照してください。

Function: eq object1 object2

この関数はobject1object2が同じオブジェクトならt、それ以外はnilをリターンする。

object1object2が同じ名前をもつシンボルなら、通常は同じオブジェクトだが例外もある。シンボルの作成とinternを参照のこと。他の非数値型(リストやベクター、文字列などの)にたいしては、同じ内容(または要素)の2つの引数が両者eqである必要はない。これらが同じオブジェクトの場合だけeqであり、その場合には一方の内容を変更するともう一方の内容にも同じ変更が反映される。

object1object2が異なるタイプや値をもつ数値なら同じオブジェクトではなく、eqnilをリターンする。同じ値をもつfixnumなら同じオブジェクトであり、eqtをリターンする。別個に計算されてたまたま同じ値をもち、かつ非fixnumタイプの同じ数値型なら、それらは同じかもしれないし違うかもしれず、Lispインタープリターが作成したオブジェクトが1つか2つかに依存してeqtnilをリターンする。

(eq 'foo 'foo)
     ⇒ t

(eq ?A ?A)
     ⇒ t

(eq 3.0 3.0)
     ⇒ t または nil
;; 浮動小数にたいするeqではオブジェクト同じかもしれず違うかもしれない

(eq (make-string 3 ?A) (make-string 3 ?A))
     ⇒ nil

(eq "asdf" "asdf")
     ⇒ t または nil
;; 文字列コンテンツにたいするeqではオブジェクト同じかもしれず違うかもしれない

(eq '(1 (2 (3))) '(1 (2 (3))))
     ⇒ nil

(setq foo '(1 (2 (3))))
     ⇒ (1 (2 (3)))
(eq foo foo)
     ⇒ t
(eq foo '(1 (2 (3))))
     ⇒ nil

(eq [(1 2) 3] [(1 2) 3])
     ⇒ nil

(eq (point-marker) (point-marker))
     ⇒ nil

make-symbol関数はinternされていないシンボルをリターンする。これはLisp式内でその名前を記述したシンボルとは区別される。同じ名前の異なるシンボルはeqではない。シンボルの作成とinternを参照のこと。

(eq (make-symbol "foo") 'foo)
     ⇒ nil

Emacs Lispバイトコンパイラーはリテラル文字列のような等価なリテラルオブジェクトを同一オブジェクトにたいする参照に落し込む(collapse into)かもしれない。バイトコンパイルされたコードはそのようなオブジェクトをeqで比較するだろうが、そうでないコードは異なるという効果がある。したがってコードではオブジェクトのリテラルコンテンツがeqか否かではなく、以下に説明するequalのような関数でオブジェクトの関数を使用すること。同様にコードではリテラルオブジェクトを変更(たとえばリテラル文字列へのテキストプロパティのput)しないこと。バイトコンパイラーがそれらの落し込みを行っていたら、同一コンテンツをもつ別のリテラルオブジェクトに影響があるかもしれない。

Function: equal object1 object2

この関数はobject1object2が同じ構成要素をもつならt、それ以外はnilをリターンする。eqが引数が同じオブジェクトなのかテストするのにたいして、equalは同一でない引数の内部を調べて、それらの要素または内容が同一化をテストする。したがって2つのオブジェクトがeqならばそれらはequalだが、その逆は常に真ではない。

(equal 'foo 'foo)
     ⇒ t

(equal 456 456)
     ⇒ t

(equal "asdf" "asdf")
     ⇒ t
(eq "asdf" "asdf")
     ⇒ nil

(equal '(1 (2 (3))) '(1 (2 (3))))
     ⇒ t
(eq '(1 (2 (3))) '(1 (2 (3))))
     ⇒ nil

(equal [(1 2) 3] [(1 2) 3])
     ⇒ t
(eq [(1 2) 3] [(1 2) 3])
     ⇒ nil

(equal (point-marker) (point-marker))
     ⇒ t

(eq (point-marker) (point-marker))
     ⇒ nil

文字列の比較はcaseを区別するがテキストプロパティは考慮しない — これは文字列内の文字だけを比較する。テキストのプロパティを参照のこと。テキストプロパティも比較する場合には、equal-including-propertiesを使用すること。技術的な理由によりユニバイト文字列とマルチバイト文字列は、それらが同じ文字コードのシーケンスを含み、それらのコードがすべて0から127(ASCII)の場合に限りequalとなる(テキストの表現方法を参照)。

(equal "asdf" "ASDF")
     ⇒ nil

equal関数はオブジェクトが整数、文字列、マーカー、ベクター、ブールベクター、バイトコード関数オブジェクト、文字テーブル、レコード、フォントオブジェクトなら、それらのコンテンツを再帰的に比較する。その他のオブジェクトは、それらがeqの場合のみequalとみなされる。たとえば個別の2つのバッファーは、たとえバッファーのテキスト的なコンテンツが同一であってもequalとみなされることはない。

equalでは等価性は再帰的に定義されています。たとえば2つのコンスセルxyを与えると、(equal x y)は、以下の式の両方がtをリターンする場合だけtをリターンします:

(equal (car x) (car y))
(equal (cdr x) (cdr y))

したがって循環リストの比較はエラーとなるような深い再帰を引き起こすかもしれず、(equal a b)tをリターンするにも関わらず(equal b a)はエラーをシグナルするといった直感に反する結果となることがあります。

Function: equal-including-properties object1 object2

この関数はすべてのケースにおいてequalと同様に振る舞うが、2つの文字列がequalになるためには、それらが同じテキストプロパティをもつ必要がある。

(equal "asdf" (propertize "asdf" 'asdf t))
     ⇒ t
(equal-including-properties "asdf"
                            (propertize "asdf" 'asdf t))
     ⇒ nil

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

2.9 可変性

変更されるべきではないLispオブジェクトがいくつかあります。たとえばLisp式"aaa"では文字列を生成しますが、そのコンテンツを変更するべきではありません。いくつかのオブジェクトは変更できません。たとえばある数値を計算して新たな数値を作成できたとしても、Lispは既存の数値を変更する操作を提供しません。

その他のLispオブジェクトはmutable(可変)オブジェクトで、副作用をともなう破壊的な操作を通じて値を変更しても安全です。たとえばマーカーを別のポイントを指すマーカーに移動することにより、既存のマーカーを変更することができます。

数値は変更不可でマーカーはすべてmutableだとしても、mutableと非mutableのメンバーをもつタイプがいくつかあります。これらのタイプにはコンス、ベクター、文字列が含まれます。たとえば"cons"(symbol-name 'cons)は変更するべきではない文字列を生成しますが、(copy-sequence "cons")(make-string 3 ?a)は後からasetを呼び出すことを通じて変更可能なmutable文字列を生成します。

mutableオブジェクトは評価される式の一部となったときにmutableであることを止めます。たとえば:

(let* ((x (list 0.5))
       (y (eval (list 'quote x))))
  (setcar x 1.5) ;; プログラムはこれを行うべきではない
  y)

作成時にリスト(0.5)がmutableでも、それはevalに与えられたのでsetcarを通じて変更するべきではありません。変更するべきではないオブジェクトが後からmutableになることは決してないので逆はあり得ません。

変更するべきではないオブジェクトの変更をプログラムが試みた際の動作は未定義です。Lispインタープリターがエラーをシグナルするかもしれず、クラッシュしたり他の方法で予測不能な振る舞いを引き起こすかもしれません2

プログラムの一部として類似した定数が出現する際には、既存の定数やそのコンポーネントの再利用によってLispが時間やスペースを節約できるかもしれません。たとえば(eq "abc" "abc")はインタープリターが文字列リテラル"abc"の1つのインスタンスを作成したらt、2つのインスタンスを作成したらnilをリターンします。したがってこの最適化使用の有無に関わらず機能するようにLispプログラムを記述する必要があります。


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

3 数値

GNU Emacsは2つの数値データ型 — 整数(integers)浮動小数点数(floating-point numbers)をサポートします。整数は-3、0、7、13、511などの整数です。浮動小数点数は-4.5、0.0、2.71828などの小数部をもちます。これらは指数記数法でも表現できます — ‘1.5e2’は‘150.0’と同じです。ここで‘e2’は10の2乗を表し、それに1.5を乗じるという意味です。整数計算は正確です。浮動小数点数の計算では数値は固定された精度をもつので、しばしば丸め誤差(rounding errors)が発生します。


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

3.1 整数の基礎

Lispリーダーは、10進数字のシーケンス(オプションで最初の符号記号と最後のピリオドをともなう)として整数を読み取ります。

 1               ; 整数1
 1.              ; 整数1
+1               ; これも整数1
-1               ; 整数-1
 0               ; 整数0
-0               ; 整数0

10以外の基数をもつ整数の構文は‘#’、基数表示(radix indication)、その後の1つ以上の数字から構成されます。基数表示は2進数(binary)は‘b’、8進数(octal)は‘o’、16進数(hex)は‘x’、基数radixにたいしては‘radixr’になります。したがって‘#binteger’は2進数、‘#radixrinteger’は基数radixintegerを読み取ります。radixの値として可能な値は2から36であり、最初のradix文字は‘0’–‘9’および‘A’–‘Z’から採択されます。英文字のcase(大文字小文字)は無視されて、最初の符号と最後のピリオドはありません。たとえば:

#b101100 ⇒ 44
#o54 ⇒ 44
#x2c ⇒ 44
#24r1k ⇒ 44

整数にたいして処理を行なうさまざまな関数、特にビット演算(整数にたいするビット演算を参照)を理解するためには、数を2進形式で見ることが助けになることがよくあります。

10進整数の5は2進数では以下のようになります:

…000101

(省略記号‘’は概念的に先頭ビットにマッチする無限個数のビットを意味する。ここでは無限個の0ビット。後の例でも‘’表記を使用する。)

整数の-1は以下のようになります:

…111111

-1はすべて1で表現されます(2の補数表記と呼ばれる)。

-1から4を減じることで負の整数-5が得られます。10進の整数4は2進では100です。したがって-5は以下のようになります:

…111011

このチャプターで説明する多くの関数は、数字の位置として引数にマーカー(マーカーを参照)を受け取ります。そのような関数にたいする実際の引数は数字かマーカーなので、わたしたちはこれらの引数にnumber-or-markerという名前を与えることがあります。引数の値がマーカーならマーカーの位置が使用され、マーカーのバッファーは無視されます。

Emacs Lispでは、テキスト文字は整数により表現されます。0から(max-char)までの整数は、有効な文字として判断されます。文字コードを参照してください。

Emacs Lispの整数はマシンのワードサイズに制限されません。しかしその背後にはfixnumsと呼ばれる小さい整数と、bignumsと呼ばれる大きい整数という2種類の整数が存在します。Emacs Lispコードは通常は整数がfixnumかbignumのいずれであるかに依存するべきではありませんが、Emacsの古いバージョンではfixnumだけがサポートされており、未だにfixnumだけを受け取るEmacs関数がいくつかあり、古いEmacs Lispコードがbignumを受け取ると問題が起こるかもしれません。たとえば古いEmacs Lispコードはeqで整数にたいする数値の等価性を安全に比較できましたが、bignumの登場により整数の比較にはeql=のような等価性にたいする述語を使うことが必要になりました。

bignumの値の範囲は主メモリー量、bignumの指数の表現に使用されるワードサイズのようなマシン特性、およびinteger-width変数により制限されます。これらの制限は通常はfixnumにたいする制限よりは寛大です。bignumが数値的にfixnumと等しくなることはありません。Emacsはfixnum範囲内の整数を、bignumではなく常にfixnumとして表現します。

fixnumの値の範囲はマシンに依存します。最小の範囲は-536,870,912から536,870,911(30ビット長の -2**29 から 2**29 - 1) ですが、多くのマシンはより広い範囲を提供します。

Variable: most-positive-fixnum

この変数の値はEmacs Lispが扱える“小さい”整数の最大値。典型的な値は32ビットでは 2**29 - 1 、64ビットでは 2**61 - 1 。

Variable: most-negative-fixnum

この変数の値はEmacs Lispが扱える数値的に最小の“小さい”整数。これは負の整数。典型的な値は32ビットでは -2**29 、64ビットでは -2**61、 。

Variable: integer-width

この変数の値は大きな整数の計算時にEmacsが範囲エラー(range error)をシグナルするかどうかを制御する負ではない整数。絶対値が 2**n (nはこの変数の値)より小さい整数の時は範囲エラーをシグナルしない。大きい整数を簡単に作成できればエラーがシグナルされない場合もあるが、通常は大きな整数の作成を試みると範囲エラーをシグナルする。この変数に大きな数値を設定すると、巨大な整数の計算にコストを要する可能性がある。


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

3.2 浮動小数点数の基礎

浮動小数点数は整数以外の数値の表現に有用です。浮動小数点数の範囲は使用中マシンでのCのデータ型doubleと同じ範囲です。EmacsがサポートするほとんどすべてのコンピューターではIEEEの64ビット浮動小数フォーマットであり、これはIEEE Std 754-2019で標準化されたもので、David Goldbergの論文“What Every Computer Scientist Should Know About Floating-Point Arithmetic”で更に議論されています。モダンなプラットフォームでは浮動小数処理はIEEE-754標準に厳密にしたがいますが、特に32ビットX86のような一部のシステムでは丸めは常に正しい訳ではありません。

一部の古いコンピューターシステムでは、EmacsがIEEEの浮動小数点数を使わないかもしれません。わたしたちが把握している、Emacsが正しく実行されているにも関わらずIEEE-754にしたがわないようなシステムとして、GCC 10.4.0を使用してNetBSDを実行するVAXシステムが挙げられます。このシステムではVAXの‘D_Floating’フォーマットが使用されています。IBMのSystem/370系メインフレームとそのXL/Cコンパイラーも16進浮動小数点数を扱う能力がありますが、今のところEmacsはそのような構成でビルドされていません。

浮動小数点数にたいする入力構文は、小数点と指数のどちらか1つ、または両方を必要とします。オプションの符号(‘+’か‘-’)は、その数字と指数の前に記述します。たとえば‘1500.0’、‘+15e2’、‘15.0e+2’、‘+1500000e-3’、‘.15e4’は値が1500の浮動小数点数を記述する5つの方法です。これらはすべて等価です。Common Lispと同様に、Emacs Lispは指数のない浮動小数点数の小数点の後に少なくとも1つの数字を必要とします。‘1500.’は整数であって浮動小数点数ではありません。

Emacs Lispは=のような数学的な比較に関して、-0.0を通常の0と数学的に同じものとして扱います。これは、(他の処理がこれらを区別するとしても-0.00.0は数学的に等しいとする)IEEE浮動小数点数規格にしたがっています。

IEEE浮動小数点数規格は浮動小数点数として、正の無限大と負の無限大をサポートします。この規格はNaNまたは“not a number(数字ではない)”と呼ばれる値クラスも提供します。正しい答えが存在しないような場合に、数学関数はこのような値をリターンします。たとえば(/ 0.0 0.0)はNaNをリターンします。数値的にNaNはたとえ自身と比較してもすべての値にたいして数値的にイコールになることはありません。NaNは符号と仮数をもち、非数学関数は符号と仮数が一致すれば2つのNaNを等しいものと扱います。NaNの仮数は文字列表現の数字のようにマシン依存です。

NaNはIEEE浮動小数点演算を使用しないシステムでは利用できません。たとえばNaNにたいする読み取り構文をVAXで使用すると、リーダーがエラーをシグナルするでしょう。

NaNと符号つき0が関係する際にはeqlequalsxhash-eqlsxhash-equalgethashのような非数学関数はそれらが数学的にイコールかではなく、値が区別できるかどうかを判断します。たとえばxyが同じNaNなら数値比較を使用する(= x y)nilをリターンするのにたいして(equal x y)tをリターンして、反対に(= 0.0 -0.0)tをリターンするのにたいして(equal 0.0 -0.0)nilをリターンします。

以下は、これらの特別な浮動小数点数にたいする入力構文です:

infinity

1.0e+INF’と‘-1.0e+INF

not-a-number

0.0e+NaN’と‘-0.0e+NaN

以下の関数は浮動小数点数を扱うために特化したものです:

Function: isnan x

この述語は浮動小数引数がNaNならt、それ以外はnilをリターンする。

Function: frexp x

この関数はコンスセル(s . e)をリターンする。ここでseは、浮動小数点数の仮数(浮動小数点数を2の指数表現したときの仮数)と指数である。

xが有限ならsは0.5以上1.0未満の浮動小数点数、eは整数で、 x = s * 2**eとなる。 xが0または無限ならsxと等しくなる。xがNaNならsもNaN。xが0ならeは0。

Function: ldexp s e

数値の仮数sと整数の指数eを与えられると、この関数は浮動小数点数 s * 2**eをリターンする。

Function: copysign x1 x2

この関数はx2の符号をx1の値にコピーして結果をリターンする。x1x2は浮動小数でなければならない。

Function: logb x

この関数はxの2進指数をリターンする。より正確にはxが有限かつ非0なら|x|の2を底とする対数を整数に切り下げた値。xが0または無限なら値は無限大。xがNaNなら値はNaN。

(logb 10)
     ⇒ 3
(logb 10.0e20)
     ⇒ 69
(logb 0)
     ⇒ -1.0e+INF

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

3.3 数値のための述語

このセクションの関数は数値や、特定の数値型にたいしてテストを行ないます。関数integerpfloatpは、引数として任意のLispオブジェクト型をとることができます(でなければ、あまり使用する機会ない)。しかし述語zeropは引数として数値を要求します。マーカーのための述語integer-or-marker-pnumber-or-marker-pも参照してください。

Function: bignump object

この述語は引数が大きい整数かどうかをテストしてもしそうならt、それ以外はnilをリターンする。小さい整数とは異なり大きい整数はeqでなくても=eqlになり得る。

Function: fixnump object

この述語は引数が小さい整数かどうかをテストしてもしそうならt、それ以外はnilをリターンする。小さい整数はeqで比較できる。

Function: floatp object

この述語は引数が浮動小数かどうかをテストしてもしそうならt、それ以外はnilをリターンする。

Function: integerp object

この述語は引数が整数かどうかをテストしてもしそうならt、それ以外はnilをリターンする。

Function: numberp object

この述語は引数が数(整数か浮動小数)かどうかをテストしてもしそうならt、それ以外はnilをリターンする。

Function: natnump object

この述語は引数が正の整数かどうかをテストしてもしそうならt、それ以外はnilをリターンする(名前は“natural number: 自然数”が由来)。0は負でないと判断される。

wholenumpnatnumpのシノニム。

Function: zerop number

この述語は引数が0かどうかをテストしてもしそうならt、それ以外はnilをリターンする。引数は数でなければならない。

(zerop x)(= x 0)と等価。


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

3.4 数値の比較

数値にたいして数学的な等価性をテストするには通常はeqeqlequalのような非数値的な比較述語のかわりに=を使用するべきです。異なる浮動小数点オブジェクトと大きい整数オブジェクトを数値的に等しくすることができます。これらの比較にeqを使用した場合にはそれらが同一のオブジェクトかどうかを、eqlequalを使用した場合にはそれらの値が区別不能かどうかをテストすることになります。対照的に=は数値比較を使用して、非数値的な比較がnilをリターンするような場合にtをリターンしたり、その逆もあり得ます。浮動小数点数の基礎を参照してください。

Emacs Lispでは2つのfixnumが数値的に等しければ同一のLispオブジェクトです。つまりfixnumではeq=と同じです。値が未知のfixnumの比較にeqを使用する方が便利な場合があります。なぜなら未知の値が数でない場合でもeqはエラーを報告しないからです。これは任意のタイプの引数を受け付けます。対照的に引数が数でもマーカーでもなければ=はエラーをシグナルします。しかし整数の比較においてさえ、使用できる場合には=を使用するのがよいプログラミング習慣です。

数の比較において、2つの数が同じデータ型(どちらも整数であるかどちらも浮動小数であるか)で同じ値の場合は等しい数として扱うeqlequalのほうが便利なときもあります。対照的に=は整数と浮動小数点数を(訳注:同じ値の場合には)等しい数と扱うことができます。同等性のための述語を参照してください。

他の欠点もあります。浮動小数演算は正確ではないので、浮動小数値を比較するのが悪いアイデアとなるときがよくあります。通常は近似的に等しいことをテストするほうがよいでしょう。以下はこれを行なう関数です:

(defvar fuzz-factor 1.0e-6)
(defun approx-equal (x y)
  (or (= x y)
      (< (/ (abs (- x y))
            (max (abs x) (abs y)))
         fuzz-factor)))
Function: = number-or-marker &rest number-or-markers

この関数はすべての引数が数値的に等しいかどうかをテストしてもしそうならt、それ以外はnilをリターンする。

Function: eql value1 value2

この関数はeqと同様に振る舞うが引数が両方とも数のときを除く。これは数を型と数値的な値により比較するので(eql 1.0 1)nilをリターンするが、(eql 1.0 1.0)(eql 1 1)tをリターンする。これは小さい整数と同様に大きい整数の比較に使用できる。符号、指数部、小数部が同じ浮動小数点数はeqlであり、これは数値の比較とは異なる。(eql 0.0 -0.0)nil(eql 0.0e+NaN 0.0e+NaN)tをリターンするが、これは=の動作とは逆である。

Function: /= number-or-marker1 number-or-marker2

この関数は引数が数値的に等しいかどうかをテストして、もし異なる場合はt、等しい場合はnilをリターンする。

Function: < number-or-marker &rest number-or-markers

この関数は、各引数それぞれを後の引数より小さいかどうかをテストしてもしそうならt、それ以外はnilをリターンする。

Function: <= number-or-marker &rest number-or-markers

この関数は、各引数それぞれが後の引数以下かどうかをテストしてもしそうならt、それ以外はnilをリターンする。

Function: > number-or-marker &rest number-or-markers

この関数は、各引数それぞれが後の引数より大きいかどうかをテストしてもしそうならt、それ以外はnilをリターンする。

Function: >= number-or-marker &rest number-or-markers

この関数は、各引数それぞれが後の引数以上かどうかをテストしてもしそうならt、それ以外はnilをリターンする。

Function: max number-or-marker &rest numbers-or-markers

この関数は最大の引数をリターンする。

(max 20)
     ⇒ 20
(max 1 2.5)
     ⇒ 2.5
(max 1 3 2.5)
     ⇒ 3
Function: min number-or-marker &rest numbers-or-markers

この関数は最小の引数をリターンする。

(min -4 1)
     ⇒ -4
Function: abs number

この関数はnumberの絶対値をリターンする。


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

3.5 数値の変換

整数を浮動小数の変換には関数floatを使用します。

Function: float number

これは浮動小数点数に変換されたnumberをリターンする。すでにnumberが浮動小数点数ならfloatはそれを変更せずにリターンする。

浮動小数点数を整数に変換する関数が4つあります。これらは浮動小数点数を丸める方法が異なります。これらはすべて引数number、およびオプション引数としてdivisorを受け取ります。引数は両方とも整数か浮動小数点数です。divisornilのこともあります。divisornilまたは省略された場合、これらの関数はnumberを整数に変換するか、それが既に整数の場合は変更せずにリターンします。divisorが非nilなら、これらの関数はnumberdivisorで除して結果を整数に変換します。divisorが(整数か浮動小数かに関わらず)0の場合、Emacsはarith-errorエラーをシグナルします。

Function: truncate number &optional divisor

これは0に向かって丸めることにより整数に変換したnumberをリターンする。

(truncate 1.2)
     ⇒ 1
(truncate 1.7)
     ⇒ 1
(truncate -1.2)
     ⇒ -1
(truncate -1.7)
     ⇒ -1
Function: floor number &optional divisor

これは下方(負の無限大に向かって)に丸めることにより整数に変換したnumberをリターンする。

divisorが指定された場合には、modに相当する種類の除算演算を使用して下方に丸めを行う。

(floor 1.2)
     ⇒ 1
(floor 1.7)
     ⇒ 1
(floor -1.2)
     ⇒ -2
(floor -1.7)
     ⇒ -2
(floor 5.99 3)
     ⇒ 1
Function: ceiling number &optional divisor

これは上方(正の無限大に向かって)に丸めることにより整数に変換したnumberをリターンする。

(ceiling 1.2)
     ⇒ 2
(ceiling 1.7)
     ⇒ 2
(ceiling -1.2)
     ⇒ -1
(ceiling -1.7)
     ⇒ -1
Function: round number &optional divisor

これはもっとも近い整数に向かって丸めることにより、整数に変換したnumberをリターンする。2つの整数から等距離にある値の丸めでは、偶数の整数をリターンする。

(round 1.2)
     ⇒ 1
(round 1.7)
     ⇒ 2
(round -1.2)
     ⇒ -1
(round -1.7)
     ⇒ -2

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

3.6 算術演算

Emacs Lispは伝統的な4つの算術演算(加減乗除)、同様に剰余とmodulusの関数、および1の加算と減算を行う関数を提供します。%を除き、これらの各関数は引き数として整数か浮動小数を受け取り、浮動小数の引数がある場合は浮動小数点数をリターンします。

Function: 1+ number-or-marker

この関数はnumber-or-marker + 1をリターンする。例えば、

(setq foo 4)
     ⇒ 4
(1+ foo)
     ⇒ 5

この関数はCの演算子++とは異なり、変数をインクリメントしない。この関数は和を計算するだけである。したがって以下を続けて評価すると、

foo
     ⇒ 4

変数をインクリメントしたい場合は、以下のようにsetqを使用しなければならない:

(setq foo (1+ foo))
     ⇒ 5
Function: 1- number-or-marker

この関数はnumber-or-marker - 1をリターンする。

Function: + &rest numbers-or-markers

この関数は引数すべてを加算する。引数を与えないと+は0をリターンする。

(+)
     ⇒ 0
(+ 1)
     ⇒ 1
(+ 1 2 3 4)
     ⇒ 10
Function: - &optional number-or-marker &rest more-numbers-or-markers

-関数は2つの目的 — 符号反転と減算 — をもつ。-に1つの引数を与えると、値は引数の符号を反転したものになる。複数の引数の場合は、number-or-markerからmore-numbers-or-markersまでの各値を蓄積的に減算する。引数がなければ結果は0。

(- 10 1 2 3 4)
     ⇒ 0
(- 10)
     ⇒ -10
(-)
     ⇒ 0
Function: * &rest numbers-or-markers

この関数はすべての引数を乗じて積をリターンする。引数がなかれば*は1をリターンする。

(*)
     ⇒ 1
(* 1)
     ⇒ 1
(* 1 2 3 4)
     ⇒ 24
Function: / number &rest divisors

divisorsが1つ以上ならこの関数はdivisors内の除数で順にnumberを除して、その商をリターンする。divisorsがなければ、この関数は1/number、つまりnumberの逆数をリターンする。各引数には数かマーカーを指定できる。

すべての引数が整数なら、結果は各除算の後に商を0へ向かって丸めることにより得られる整数となる。

(/ 6 2)
     ⇒ 3
(/ 5 2)
     ⇒ 2
(/ 5.0 2)
     ⇒ 2.5
(/ 5 2.0)
     ⇒ 2.5
(/ 5.0 2.0)
     ⇒ 2.5
(/ 4.0)
     ⇒ 0.25
(/ 4)
     ⇒ 0
(/ 25 3 2)
     ⇒ 4
(/ -17 6)
     ⇒ -2

整数を整数0で除するとEmacsはarith-errorエラー(エラーを参照)をシグナルする。IEEE-754の浮動小数点数を使用するシステムにおける浮動小数点数の除算では、非0の数を0で除することで正の無限大または負の無限大を得る(浮動小数点数の基礎を参照)。それ以外のシステムでは通常通りarith-errorエラーがシグナルされる。

Function: % dividend divisor

この関数はdividenddivisorで除した後、その剰余を整数でリターンする。引数は整数かマーカーでなければならない。

任意の2つの整数dividenddivisorにたいして、

(+ (% dividend divisor)
   (* (/ dividend divisor) divisor))

は、divisorが非0なら常にdividendと等しくなる。

(% 9 4)
     ⇒ 1
(% -9 4)
     ⇒ -1
(% 9 -4)
     ⇒ 1
(% -9 -4)
     ⇒ -1
Function: mod dividend divisor

この関数はdividenddivisorにたいするmodulo、言い換えるとdividenddivisorで除した後の剰余(ただし符号はdivisorと同じ)をリターンする。引数は数かマーカーでなければならない。

%とは異なりmodは浮動小数の引数を許す。これは商を整数に下方(負の無限大に向かって)へ丸めて剰余を計算するのにこの商を使用する。

moddivisorが0のとき、両方の引数が整数ならarith-errorエラーをシグナルし、それ以外はNaNをリターンする。

(mod 9 4)
     ⇒ 1
(mod -9 4)
     ⇒ 3
(mod 9 -4)
     ⇒ -3
(mod -9 -4)
     ⇒ -1
(mod 5.5 2.5)
     ⇒ .5

任意の2つの数dividenddivisorにたいして、

(+ (mod dividend divisor)
   (* (floor dividend divisor) divisor))

は常にdividendになる(ただし引数のどちらかが浮動小数なら、丸め誤差の範囲内で等しく、かつdividendが整数でdivisorが0ならarith-errorとなる)。floorについては、数値の変換を参照のこと。


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

3.7 丸め処理

関数ffloorfceilingfroundftruncateは浮動小数の引数をとり、値が近くの整数であるような浮動小数をリターンします。ffloorは一番近い下方の整数、fceilingは一番近い上方の整数、ftruncateは0に向かう方向で一番近い整数、froundは一番近い整数をリターンします。

Function: ffloor float

この関数はfloatを次に小さい整数値に丸めて、その値を浮動小数点数としてリターンする。

Function: fceiling float

この関数はfloatを次に大きい整数値に丸めて、その値を浮動小数点数としてリターンする。

Function: ftruncate float

この関数はfloatを0方向の整数値に丸めて、その値を浮動小数点数としてリターンする。

Function: fround float

この関数はfloatを一番近い整数値に丸めて、その値を浮動小数点数としてリターンする。2つの整数値との距離が等しい値にたいする丸めでは、偶数の整数をリターンする。


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

3.8 整数にたいするビット演算

コンピューターの中では、整数はビット(bit: 0か1の数字)のシーケンスである2進数で表されます。ビットシーケンスは概念的には最上位ビットがすべて0か1であるような左側に無限なシーケンスです。ビット演算はそのようなシーケンスの中の個々のビットに作用します。たとえばシフト(shifting)はシーケンス全体を1つ以上左または右に移動して、移動されたのと同じパターンを再現します。

Emacs Lispのビット演算は整数だけに適用されます。

Function: ash integer1 count

ash (算術シフト(arithmetic shift))は、integer1の中のビット位置を左にcountシフトする。countが負なら右にシフトする。左シフトでは右側に0が挿入されて、右シフトでは最右ビットが破棄される。整数処理として考えると、ashinteger1に 2**count を乗じてから、負の無限大に向かって丸めることによりその結果を変換する。

以下はビットパターンを1ビット左にシフトしてから右にシフトする例。この例で2進数パターンの下位ビットだけを示している。先頭ビットはすべて表示されている最上位ビットと一致する。ご覧のとおり1ビットの左シフトは2を乗ずること、1ビットの右シフトは2で除してから負の無限大方向に丸められることと等価である。

(ash 7 1) ⇒ 14
;; 10進の7は10進の14になる
…000111
     ⇒
…001110

(ash 7 -1) ⇒ 3
…000111
     ⇒
…000011

(ash -7 1) ⇒ -14
…111001
     ⇒
…110010

(ash -7 -1) ⇒ -4
…111001
     ⇒
…111100

以下は2ビット左にシフトしてから右に2ビットシフトする例:

                  ;         2進数値
(ash 5 2)         ;   5  =  …000101
     ⇒ 20         ;      =  …010100
(ash -5 2)        ;  -5  =  …111011
     ⇒ -20        ;      =  …101100
(ash 5 -2)
     ⇒ 1          ;      =  …000001
(ash -5 -2)
     ⇒ -2         ;      =  …111110
Function: lsh integer1 count

lshlogical shiftの略で、integer1のビットを左にcount回シフト(countが負なら右にシフト、空いたビットには0を補填)する。countが負ならinteger1はfixnumか正のbignumのいずれかでなければならず、lshはシフト前に負のfixnumをmost-negative-fixnumで2回減算してあたかも符号なしであるかのように非負の結果を生成する。この奇妙な振る舞いはEmacsがfixnumsだけをサポートしていた頃の振る舞いであり、現在ではashがより良い選択である。

integer1count1がいずれも負の場合を除いてlshashのように振る舞うので、以下の例ではこれらの例外ケースに焦点をあてている。これらの例は30ビットのfixnumsを想定している。

                 ;      2進数値
(ash -7 -1)      ; -7 = …111111111111111111111111111001
     ⇒ -4        ;    = …111111111111111111111111111100
(lsh -7 -1)
     ⇒ 536870908 ;    = …011111111111111111111111111100
(ash -5 -2)      ; -5 = …111111111111111111111111111011
     ⇒ -2        ;    = …111111111111111111111111111110
(lsh -5 -2)
     ⇒ 268435454 ;    = …001111111111111111111111111110
Function: logand &rest ints-or-markers

この関数は引数のビットのANDをリターンする。すべての引数のn番目のビットが1の場合に限り、結果のn番目のビットが1となる。

たとえば13と12では、4ビット2進数を使用すると1101と1100のビットANDは1100を生成する。この2進数ではいずれも左の2ビットがセット(つまり1)されているので、リターンされる値の左2ビットがセットされる。しかし右の2ビットにたいしては少なくとも1つの引数でそのビットが0なので、リターンされる値の右2ビットは0になる。

したがって、

(logand 13 12)
     ⇒ 12

logandに何も引数も渡さなければ、値-1がリターンされる。-1を2進数で表すとすべてのビットが1なので、-1はlogandにたいする単位元(identity element)である。logandに渡す引数が1つだけならその引数がリターンされる。

                   ;        2進数値

(logand 14 13)     ; 14  =  …001110
                   ; 13  =  …001101
     ⇒ 12         ; 12  =  …001100

(logand 14 13 4)   ; 14  =  …001110
                   ; 13  =  …001101
                   ;  4  =  …000100
     ⇒ 4          ;  4  =  …000100

(logand)
     ⇒ -1         ; -1  =  …111111
Function: logior &rest ints-or-markers

この関数は、引数のビット単位の包含的ORをリターンする。少なくとも1つの引数でn番目のビットが1なら、結果のn番目のビットが1になる。引数を与えなければ、結果はこの処理にたいする単位元である0となる。logiorに渡す引数が1つだけならその引数がリターンされる。

                   ;        2進数値

(logior 12 5)      ; 12  =  …001100
                   ;  5  =  …000101
     ⇒ 13         ; 13  =  …001101

(logior 12 5 7)    ; 12  =  …001100
                   ;  5  =  …000101
                   ;  7  =  …000111
     ⇒ 15         ; 15  =  …001111
Function: logxor &rest ints-or-markers

この関数は、引数のビット単位の排他的ORをリターンする。n番目のビットが1であるような引数の数が奇数個の場合のみ、結果のn番目のビットが1となる。引数を与えなければ、結果はこの処理の単位元である0となる。logxorに渡す引数が1つだけならその引数がリターンされる。

                   ;        2進数値

(logxor 12 5)      ; 12  =  …001100
                   ;  5  =  …000101
     ⇒ 9          ;  9  =  …001001

(logxor 12 5 7)    ; 12  =  …001100
                   ;  5  =  …000101
                   ;  7  =  …000111
     ⇒ 14         ; 14  =  …001110
Function: lognot integer

この関数は引数のビット単位の補数(bitwise complement)をリターンする。integern番目のビットが0の場合に限り、結果のn番目のビットが1になり、その逆も成り立つ。結果は-1 - integerと等価。

(lognot 5)
     ⇒ -6
;;  5  =  …000101
;; becomes
;; -6  =  …111010
Function: logcount integer

この関数はintegerハミング重み (Hamming weight: integerの2進数表現での1の個数)をリターンする。integerが負なら、その2の補数の2進数表現での0ビットの個数をリターンする。結果は常に非負となる。

(logcount 43)     ;  43 = …000101011
     ⇒ 4
(logcount -43)    ; -43 = …111010101
     ⇒ 3

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

3.9 標準的な数学関数

以下の数学的関数は、引数として整数と同様に浮動小数点数も受け入れます。

Function: sin arg
Function: cos arg
Function: tan arg

これらは三角関数であり、引数argはラジアン単位。

Function: asin arg

(asin arg)の値は、sinの値がargとなるような -pi/2 から pi/2 (両端を含む)の数である。argが範囲外([-1, 1]の外)なら、asinはNaNをリターンする。

Function: acos arg

(acos arg)の値は、cosの値がargとなるような、0から pi (両端を含む)の数である。argが範囲外([-1, 1]の外)ならacosはNaNをリターンする。

Function: atan y &optional x

(atan y)の値は、tanの値がyとなるような、 -pi/2 から pi/2 (両端を含まず)の数である。オプションの第2引数xが与えられると、(atan y x)の値はベクトル[x, y]X軸が成す角度のラジアン値となる。

Function: exp arg

これは指数関数である。この関数はeの指数argをリターンする。

Function: log arg &optional base

この関数は底をbaseとするargの対数をリターンする。baseを指定しなければ、自然底(natural base)eが使用される。argbaseが負なら、logはNaNをリターンする。

Function: expt x y

この関数はxy乗をリターンする。引数が両方とも整数でyが非負なら結果は整数になる。この場合オーバーフローはエラーをシグナルするので注意。xが有限の負数でyが有限の非整数なら、exptはNaNをリターンする。

Function: sqrt arg

これはargの平方根をリターンする。argが有限で0より小さければ、sqrtはNaNをリターンする。

加えて、Emacsは以下の数学的な定数を定義します:

Variable: float-e

自然対数e(2.71828…)

Variable: float-pi

円周率pi(3.14159…)


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

3.10 乱数

決定論的なコンピュータープログラムでは真の乱数を生成することはできません。しかしほとんどの目的には、疑似乱数(pseudo-random numbers)で充分です。一連の疑似乱数は決定論的な手法により生成されます。真の乱数ではありませんが、それらにはランダム列を模する特別な性質があります。たとえば疑似ランダム系では、すべての可能な値は均等に発生します。

疑似乱数はシード値(seed value)から生成されます。与えられた任意のシードから開始することにより、random関数は常に同じ数列を生成します。デフォルトでは、Emacsは開始時に乱数シードを初期化することにより、それぞれのEmacsの実行において、randomの値シーケンスは(ほとんど確実に)異なります。乱数シードは通常はシステムエントロピーから初期化されます。ただしエントロピープールをもたない時代遅れのプラットフォームでは、カレント時刻のようなランダム度に劣る揮発性データからシードを取得します。

再現可能な乱数シーケンスが欲しい場合もあります。たとえば乱数シーケンスに依存するプログラムをデバッグする場合、プログラムの各実行において同じ挙動を得ることが助けになります。再現可能なシーケンスを作成するには、(random "")を実行します。これは特定のEmacsの実行可能ファイルにたいして、シードに定数値をセットします(しかしこの実行可能ファイルは、その他のEmacsビルドと異なるものになるであろう)。シード値として、他のさまざまな文字列を使用することができます。

Function: random &optional limit

この関数は疑似乱数の整数をリターンする。繰り返し呼び出すと一連の疑似乱数の整数をリターンする。

limitが正の整数なら、値は負ではないlimit未満の値から選択される。それ以外なら値はLispで表現可能な任意のfixnum(most-negative-fixnumからmost-positive-fixnumの間の任意の整数)となるだろう(整数の基礎を参照)。

limitが文字列なら、その文字列定数にもとづいた新しいシードを選択することを意味する。これにより後でrandomを呼び出して再現可能な結果シーケンスをリターンさせることができる。

limittなら、あたかもEmacsが再起動されたかのように新たなシードが選択されることを意味する。これにより後でrandomを呼び出して予測不能な結果シーケンスをリターンさせることができる。

暗号化用に乱数ノンス(random nonce: 使い捨てのランダム値)が必要な場合にrandomを使用するのは、いくつかの理由により適切ではありません:

  • システムエントロピーの参照に(random t)を用いるのは可能とはいえ、あなたのプログラムのうち再現可能な結果から恩恵を受ける他の部分に悪影響を与えるかもしれない。
  • randomが使用するシステム依存の疑似乱数ジェネレーター(PRNG: pseudo-random number generator)は、必ずしも暗号化に適している訳ではない。
  • (random t)は、システムエントロピーへの直接的アクセスを提供しない。このエントロピーはシステム依存のPRNGを通過するので、結果にバイアスがかかる可能性がある。
  • 典型的なプラットフォームの乱数シードに含まれるのは32ビットだけであり、これはEmacsのfixnumより小さいので、暗号化という目的にたいしては不十分である。
  • (random t)の呼び出しによって、Emacsの内部状態が散在するノンス情報が残るので、内部的な攻撃面のサイズが増加する。
  • エントロピープールのない旧式のシステムでは、(random t)が暗号化にたいして脆弱なソースからシードされる。

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

4 文字列と文字

Emacs Lispの文字列は、文字列の順序列(ordered sequence)を含む配列です。文字列はシンボル、バッファー、ファイルの名前に使用されます。その他にもユーザーにたいしてメッセージを送ったりバッファー間でコピーする文字列を保持したり等、多くの目的に使用されます。文字列は特に重要なので、Emacs Lispは特別には文字列を操作するために多くの関数があります。Emacs Lispプログラムでは個々の文字より文字列を多用します。

キーボードの文字イベントの文字列にたいする特別な考慮は、文字列内へのキーボードイベントの配置を参照してください。


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

4.1 文字列と文字の基礎

文字(character)とは、テキスト内の1つの文字を表すLispオブジェクトです。Emacs Lispでは文字は単なる整数です。ある整数が文字か文字でないかを区別するのは、それが使用される方法だけです。Emacsでの文字表現についての詳細は文字コードを参照してください。

文字列(string)とは固定された文字シーケンスです。これは配列(array)と呼ばれるシーケンス型であり、配列長が固定で一度作成したら変更できないことを意味します(シーケンス、配列、ベクターを参照)。Cとは異なり、Emacs Lispの文字列は文字コードを判断することにより終端されません。(訳注: 文字列の終端用の文字コードはない、ということ。)

文字列は配列であるということは同様にシーケンスでもあるので、シーケンス、配列、ベクターにドキュメントされている一般的な配列関数やシーケンス関数で文字列を処理できます。たとえば関数arefを使用して文字列内の特定の文字にアクセスしたり変更することができます(配列を操作する関数を参照)。

Emacs文字列での非ASCIIにたいすテキスト表現は2つ — ユニバイト(unibyte)とマルチバイト(multibyte)があります。ほとんどのLispプログラミングでは、これら2つの表現を気にする必要はありません。詳細はテキストの表現方法を参照してください。

キーシーケンスがユニバイト文字列で表されることがあります。ユニバイト文字列がキーシーケンスの場合、範囲128から255までの文字列要素は範囲128から255の文字コードではなく、メタ文字(これは非常に大きな整数である)を表します。文字列はハイパー(hyper)、スーパー(super)、アルト(alt)で修飾された文字を保持できません。文字列はASCIIコントロール文字を保持できますが、それは他のコントロール文字です。文字列はASCIIコントロール文字のcaseを区別できません。そのような文字をシーケンスに保存したい場合は、文字列ではなくベクターを使用しなければなりません。キーボード入力文字についての情報は文字型を参照してください。

文字列は正規表現を保持するために便利です。string-match (正規表現の検索を参照)を使用して、文字列にたいして正規表現をマッチすることもできます。関数match-string (単純なマッチデータへのアクセスを参照)とreplace-match (マッチしたテキストの置換を参照)は、文字列にたいして正規表現をマッチした後に、文字列を分解・変更するのに便利です。

バッファーのように、文字列は文字列内の文字自身とその文字にたいするテキストプロパティを含みます。テキストのプロパティを参照してください。文字列からバッファーや他の文字列にテキストをコピーする、すべてのLispプリミティブ(Lisp primitives)はコピーされる文字のプロパティもコピーします。

文字列の表示やバッファーにコピーする関数についての情報はテキストを参照してください。文字または文字列の構文についての情報は、文字型文字列型を参照してください。異なるテキスト表現間で変換したり、文字コードのエンコードやデコードを行う関数についてはASCII文字を参照してください。ディスプレイ上の文字列幅の計算にlength使用するべきではないことにも注意してください。かわりにstring-widthを使用してください(表示されるテキストのサイズを参照)。


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

4.2 文字列のための述語

一般的なシーケンスや配列にたいする述語についての情報は、シーケンス、配列、ベクター配列を参照してください。

Function: stringp object

この関数はobjectが文字列ならt、それ以外はnilをリターンする。

Function: string-or-null-p object

この関数はobjectが文字列かnilならt、それ以外はnilをリターンする。

Function: char-or-string-p object

この関数はobjectが文字列か文字(たとえば整数)ならt、それ以外はnilをリターンする。


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

4.3 文字列の作成

以下の関数はスクラッチ、文字列同士、またはその一部から文字列を作成します(string-replacereplace-regexp-in-stringのように他の文字列内容を変更して文字列を作成する関数については検索と置換を参照)。

Function: make-string count character &optional multibyte

この関数はcharactercount回繰り返すことにより作成された文字列をリターンする。countが負ならエラーをシグナルする。

(make-string 5 ?x)
     ⇒ "xxxxx"
(make-string 0 ?x)
     ⇒ ""

characterASCII文字なら、結果は通常はユニバイト文字列になる。しかしオプション引数multibyteが非nilなら、この関数はかわりにマルチバイト文字列を生成する。これは結果を後で非ASCII文字列と結合したり、結果の中のいくつかの文字を非ASCII文字で置換する必要がある際に有用。

この関数に対応する他の関数にはmake-vector (ベクターを参照)やmake-list (コンスセルおよびリストの構築を参照)が含まれる。

Function: string &rest characters

この関数は文字charactersを含む文字列をリターンする。

(string ?a ?b ?c)
     ⇒ "abc"
Function: substring string &optional start end

この関数はstringから、インデックスstartの文字(その文字を含む)とendの文字(その文字は含まない)の間の範囲の文字で構成される、新しい文字列をリターンする。文字列の最初の文字はインデックス0。引数が1つなら、この関数は単にstringをコピーする。

(substring "abcdefg" 0 3)
     ⇒ "abc"

上記の例では‘a’のインデックスは0、‘b’のインデックスは1、‘c’のインデックスは2となる。インデックス3 — この文字列の4番目の文字 — は、コピーされる部分文字列の文字位置までをマークする。したがって文字列"abcdefg"から‘abc’がコピーされる。

負の数は文字列の最後から数えることを意味するので、-1は文字列の最後の文字のインデックスである。たとえば:

(substring "abcdefg" -3 -1)
     ⇒ "ef"

この例では‘e’のインデックスは-3、‘f’のインデックスは-2、‘g’のインデックスは-1。つまり‘e’と‘f’が含まれ、‘g’は含まれない。

endnilを使用した場合、それは文字列の長さを意味する。したがって、

(substring "abcdefg" -3 nil)
     ⇒ "efg"

引数endを省略した場合、それはnilを指定したのと同じである。(substring string 0)stringのすべてをコピーしてリターンする。

(substring "abcdefg" 0)
     ⇒ "abcdefg"

しかしこの目的のためにはcopy-sequenceを推奨する(シーケンスを参照)。

stringからコピーされた文字がテキストプロパティをもつなら、そのプロパティは新しい文字列へもコピーされる。テキストのプロパティを参照のこと。

substringの最初の引数にはベクターも指定できる。たとえば:

(substring [a b (c) "d"] 1 3)
     ⇒ [b (c)]

startが整数でない、またはendが整数でもnilでもななければ、wrong-type-argumentエラーがシグナルされる。startendの後の文字を指す、またはstringにたいして範囲外の整数をいずれかに指定すると、args-out-of-rangeエラーがシグナルされる。

この関数に対応するのはbuffer-substring (バッファーのコンテンツを調べるを参照)で、これはカレントバッファー内のテキストの一部を含む文字列をリターンする。文字列の先頭はインデックス0だが、バッファーの先頭はインデックス1である。

Function: substring-no-properties string &optional start end

これはsubstringと同じように機能するが、値のすべてのテキストプロパティを破棄する。startを省略したりnilを指定することができ、その場合は0と等価である。したがって(substring-no-properties string)は、すべてのテキストプロパティが削除されたstringのコピーをリターンする。

Function: concat &rest sequences

この関数は渡された引数内の文字からなる文字列をリターンする(もしあればテキストプロパティも)。引数には文字列、数のリスト、数のベクターを指定できる。引数は変更されない。concatに引数を指定しなければ空文字列をリターンする。

(concat "abc" "-def")
     ⇒ "abc-def"
(concat "abc" (list 120 121) [122])
     ⇒ "abcxyz"
;; nilは空のシーケンス。
(concat "abc" nil "-def")
     ⇒ "abc-def"
(concat "The " "quick brown " "fox.")
     ⇒ "The quick brown fox."
(concat)
     ⇒ ""

この関数は常に新たな文字列の割り当てを行う訳ではない。呼び出し側は結果が新たな文字列であること、もしくは既存の文字列にたいしてeqであることに依存しないよう推奨する。

特にリターン値を変更すると誤って別の文字列を変更したり、プログラム内の定数文字列の変更や、エラーをraiseすることさえあり得る。安全に変更できる文字列を取得するには、結果にcopy-sequenceを使用すること。

他の結合関数(concatenation functions)についての情報は関数のマッピングmapconcatベクターのための関数vconcatコンスセルおよびリストの構築appendを参照のこと。シェルコマンドで使用される文字列の中に、個々のコマンドライン引数を結合するには、combine-and-quote-stringsを参照されたい。

Function: split-string string &optional separators omit-nulls trim

この関数は正規表現separators(正規表現を参照)にもとづいて、stringを部分文字列に分解する。separatorsにたいする各マッチは分割位置を定義する。分割位置の間にある部分文字列をリストにまとめてリターンする。

separatorsnil (か省略)ならデフォルトはsplit-string-default-separatorsの値となり、関数はomit-nullstであるかのように振る舞う。

omit-nullsnil(または省略)なら、連続する2つのseparatorsへのマッチか、stringの最初か最後にマッチしたときの空文字列が結果に含まれる。omit-nullstなら、これらの空文字列は結果から除外される。

オプションの引数trimが非nilなら、その値は各部分文字列の最初と最後からトリム(trim: 除去)するテキストにマッチする正規表現を指定する。トリムによりその部分文字列が空になるようなら、それは空文字列として扱われる。

文字列を分割してcall-processstart-processに適するような、個々のコマンドライン引数のリストにする必要がある場合はsplit-string-and-unquoteを参照のこと。

以下は例:

(split-string "  two words ")
     ⇒ ("two" "words")

有用性はほとんどないであろう("" "two" "words" "")という結果とはならない。このような結果が必要ならseparatorsに明示的な値を使用すること

(split-string "  two words "
              split-string-default-separators)
     ⇒ ("" "two" "words" "")
(split-string "Soup is good food" "o")
     ⇒ ("S" "up is g" "" "d f" "" "d")
(split-string "Soup is good food" "o" t)
     ⇒ ("S" "up is g" "d f" "d")
(split-string "Soup is good food" "o+")
     ⇒ ("S" "up is g" "d f" "d")

空のマッチはカウントされます。例外は、空でないマッチを使用することにより、すでに文字列の最後に到達しているとき、またはstringが空の時で、この場合split-stringは最後の空マッチを探しません。

(split-string "aooob" "o*")
     ⇒ ("" "a" "" "b" "")
(split-string "ooaboo" "o*")
     ⇒ ("" "" "a" "b" "")
(split-string "" "")
     ⇒ ("")

しかしseparatorsが空文字列にマッチできるとき、通常はomit-nullstにすれば、前の3つの例の不明瞭さはほとんど発生しない:

(split-string "Soup is good food" "o*" t)
     ⇒ ("S" "u" "p" " " "i" "s" " " "g" "d" " " "f" "d")
(split-string "Nice doggy!" "" t)
     ⇒ ("N" "i" "c" "e" " " "d" "o" "g" "g" "y" "!")
(split-string "" "" t)
     ⇒ nil

空でないマッチより空のマッチを優先するような、一部の“非貪欲(non-greedy)”な値をseparatorsに指定することにより、幾分奇妙(ではあるが予見可能)な振る舞いが発生することがある。繰り返しになるが、そのような値は実際には稀である:

(split-string "ooo" "o*" t)
     ⇒ nil
(split-string "ooo" "\\|o+" t)
     ⇒ ("o" "o" "o")
Variable: split-string-default-separators

split-stringseparatorsにたいするデフォルト値。通常の値は"[ \f\t\n\r\v]+"

Function: string-clean-whitespace string

string内の連続する空白文字を単一のスペースに、同様にstringの先頭と終端にあるすべての空白文字を取り除くことにより空白文字を整理する。

Function: string-trim-left string &optional regexp

stringの先頭からregexpにマッチするテキストを削除する。regexpのデフォルトは‘[ \t\n\r]+’。

Function: string-trim-right string &optional regexp

stringの末尾からregexpにマッチするテキストを削除する。regexpのデフォルトは‘[ \t\n\r]+’。

Function: string-trim string &optional trim-left trim-right

stringからtrim-leftにマッチする先頭のテキストと、trim-rightにマッチする末尾のテキストを削除する。いずれのregexpもデフォルトは‘[ \t\n\r]+’。

Function: string-fill string length

lengthより長い行が無くなるようにstringのワードラップを試みる。フィルは空白文字境界でのみ行われる。lengthより長い個別の単語は短くならない。

Function: string-limit string length &optional end coding-system

stringの文字数がlengthより短ければstringをそのままリターンする。それ以外なら最初のlength文字からなるstringの部分文字列をリターンする。オプションのパラメーターendが与えられた場合には、かわりに最後のlength文字からなる文字列をリターンする。

coding-systemが非nilならstringを切り詰める前にエンコードして、結果はlengthバイトより短いユニバイト文字列になる。stringにエンコードされると複数バイトになる文字(たとえばutf-8使用時)が含まれる場合には、結果となるユニバイト文字列が文字表現の途中で切り詰められることはない。

この関数は文字列長を文字数かバイトで数えるので、文字列を表示用に短くする必要がある場合には一般的に適していない。かわりにtruncate-string-to-widthwindow-text-pixel-sizestring-glyph-splitを使用すること(表示されるテキストのサイズを参照)。

Function: string-lines string &optional omit-nulls keep-newlines

改行を境界としてstringを文字列のリストに分割する。オプション引数omit-nullsが非nilなら、結果から空行を除外する。オプション引数keep-newlinesが非nilなら、結果文字列から末尾の改行を取り除かない。

Function: string-pad string length &optional padding start

paddingをパディング文字に使用して、与えられたlengthになるようにstringをパディングする。paddingのデフォルトはスペース文字。lengthよりstringが長ければパディングしない。startnil (または省略)ならパディングは文字列終端、非nilなら文字列先頭に追加される。

Function: string-chop-newline string

stringからもしあれば最後の改行を削除する。


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

4.4 文字列の変更

このセクションで説明する処理を介して変更可能な文字列のコンテンツを変更できます。可変性を参照してください。

既存の文字列の内容を変更するもっとも基本的な方法は、aset (配列を操作する関数を参照)を使用する方法です。(aset string idx char)は、stringの文字インデックスidxに、charを格納します。これはstringが純正なASCIIなら必要に応じてマルチバイト文字列(テキストの表現方法を参照)に変換しますが、charがrawバイトではなく非ASCII文字の場合には、たとえばstring-to-multibyte (テキスト表現の変換を参照)を使う等により、stringがマルチバイトになるよう常に保証することをお勧めします。

より強力な関数はstore-substringです:

Function: store-substring string idx obj

この関数は文字インデックスidxで開始される位置にobjを格納することにより、指定されたstringの内容の一部を変更する。objは文字(この場合にはasetとまったく同じように振る舞う)、または(stringより小さい)文字列。objがマルチバイト文字列の場合には、たとえstringが純正のASCII文字列であってもマルチバイト文字列に変更することを推奨する。

既存の文字列の文字数を変更するのは不可能なので、文字インデックスidxを開始位置としたときにobjstringに収まらないような文字数で構成される場合にはエラーとなる。

パスワードを含む文字列をクリアーするときにはclear-stringを使用します:

Function: clear-string string

これはstringをユニバイト文字列にして、内容を0にクリアーする。これによりstringの長さも変更されるだろう。


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

4.5 文字および文字列の比較

Function: char-equal character1 character2

この関数は引数が同じ文字を表すならt、それ以外はnilをリターンする。case-fold-searchが非nilなら、この関数はcaseの違いを無視する。

(char-equal ?x ?x)
     ⇒ t
(let ((case-fold-search nil))
  (char-equal ?x ?X))
     ⇒ nil
Function: string= string1 string2

この関数は、2つの文字列の文字が正確にマッチすればtをリターンする。引数にはシンボルも指定でき、この場合はそのシンボル名が使用される。case-fold-searchとは無関係にcaseは常に意味をもつ。

この関数は、equalで2つの文字列を比較するのと等価である(同等性のための述語を参照)。特に、2つの文字列のテキストプロパティは無視される。テキストプロパティだけが異なる文字列を区別する必要があるならequal-including-propertiesを使用すること。しかしequalとは異なり、いずれかの引数が文字列でもシンボルでもなければ、string=はエラーをシグナルする。

(string= "abc" "abc")
     ⇒ t
(string= "abc" "ABC")
     ⇒ nil
(string= "ab" "ABC")
     ⇒ nil

ユニバイト文字列とマルチバイト文字列がstring=において等しくなるのは、すべての文字が0から127の範囲(ASCII)にある同じ文字シーケンスを含む場合だけである。テキストの表現方法を参照のこと。

Function: string-equal string1 string2

string-equalstring=の別名である。

Function: string-equal-ignore-case string1 string2

string-equal-ignore-casecase-fold-searchtの際のchar-equalのように、case(大文字小文字)の違いを無視して文字列を比較する。

Function: string-collate-equalp string1 string2 &optional locale ignore-case

この関数はlocale (デフォルトはカレントのシステムlocale)で指定された照合ルール(collation rule)にもとづいて、string1string2が等しければtをリターンする。照合ルールはstring1string2に含まれる文字の辞書順だけではなく、それらの文字間の関係に関する他のルールにより判断される。これは通常はEmacs実行中のlocale環境、およびEmacsがリンクされた標準Cライブラリー3により決定される。

たとえばUnicode文字の異なるグレイブアクセントのように、コーディングポイントが異なっても意味が同じなら、一部のlocaleでは等しいとみなされるかもしれない。

(string-collate-equalp (string ?\uFF40) (string ?\u1FEF))
     ⇒ t

オプション引数locale(文字列)は、照合用のカレントlocale識別子(current locale identifier)をオーバーライドする。値はシステムに依存する。たとえばPOSIXシステムでは"en_US.UTF-8"、MS-Windowsシステムでは"enu_USA.1252"localeが適用できるだろう。

ignore-caseが非nilなら、文字を小文字に変換することによってcaseを区別せずに文字の比較を行う。ただし背景となるシステムライブラリーがlocale固有の照合ルールを提供していない場合には、この関数はstring-equalにフォールバックする。この場合にはignore-case引数を無視して、常にcaseを区別した比較を行う。

MS-WindowsシステムでUnicode互換の照合をエミュレートする場合、MS-Windowsではlocaleのコードセット部分を"UTF-8"にできないので、w32-collate-ignore-punctuationに非nil値をバインドすること。

あるlocale環境をシステムがサポートしなれければ、この関数はstring-equalと同様に振る舞う。

一般的にファイルシステムは照合ルールが実装するような文字列の言語学的な等価性を尊重しないので、この関数をファイル名の等価性の比較に使用しないこと

Function: string< string1 string2

この関数は2つの文字列を1文字ずつ比較する。この関数は同時に2つの文字列をスキャンして、対応する文字同士がマッチしない最初のペアを探す。2つの文字列内で小さいほうの文字がstring1の文字ならstring1が小さいことになり、この関数はtをリターンする。小さいほうの文字がstring2の文字ならstring1が大きいことになり、この関数はnilをリターンする。2つの文字列が完全にマッチしたら値はnilになる。

文字のペアーは文字コードで比較される。ASCII文字セットでは英小文字は英大文字より高い数値をもつことに留意されたい。数字と区切り文字の多くは英大文字より低い数値をもつ。ASCII文字は任意の非ASCII文字より小さくなる。ユニバイトの非ASCII文字は、任意のマルチバイト非ASCII文字より常に小さくなります(テキストの表現方法を参照)。

(string< "abc" "abd")
     ⇒ t
(string< "abd" "abc")
     ⇒ nil
(string< "123" "abc")
     ⇒ t

文字列の長さが異なり、string1の長さまでマッチする場合、結果はtになる。string2の長さまでマッチする場合、結果はnilになる。文字を含まない文字列は、他の任意の文字列より小さくなる。

(string< "" "abc")
     ⇒ t
(string< "ab" "abc")
     ⇒ t
(string< "abc" "")
     ⇒ nil
(string< "abc" "ab")
     ⇒ nil
(string< "" "")
     ⇒ nil

引数としてシンボルを指定することもでき、この場合はシンボルのプリント名が比較される。

Function: string-lessp string1 string2

string-lesspstring<の別名である。

Function: string-greaterp string1 string2

この関数は逆順でstring1string2を比較した結果をリタンーする。つまりこれは(string-lessp string2 string1)を呼び出すのと等価である。

Function: string-collate-lessp string1 string2 &optional locale ignore-case

この関数は指定されたlocale (デフォルトはカレントのシステムlocale)の照合順において、string1string2より小さければtをリターンする。照合順はstring1string2に含まれる文字の辞書順だけではなく、それらの文字間の関係に関するルールによっても判断される。これは通常はEmacs実行中のlocale環境、およびEmacsとリンクされた標準Cライブラリーによって決定される。

たとえばソートでは区切り文字と空白文字は無視されるだろう(シーケンスを参照)。

(sort (list "11" "12" "1 1" "1 2" "1.1" "1.2") 'string-collate-lessp)
     ⇒ ("11" "1 1" "1.1" "12" "1 2" "1.2")

この振る舞いはシステム依存であり、例えばCygwinではlocaleに関係なく区切り文字と空白文字が無視されることは一切ない。

オプション引数locale(文字列)は、照合用のカレントlocale識別子(current locale identifier)をオーバーライドする。値はシステムに依存する。たとえばPOSIXシステムでは"en_US.UTF-8"、MS-Windowsシステムでは"enu_USA.1252"localeが適用できるだろう。localeの値を"POSIX""C"にすると、string-collate-lesspstring-lesspと同様に振る舞う。

(sort (list "11" "12" "1 1" "1 2" "1.1" "1.2")
      (lambda (s1 s2) (string-collate-lessp s1 s2 "POSIX")))
     ⇒ ("1 1" "1 2" "1.1" "1.2" "11" "12")

ignore-caseが非nilなら、文字を小文字に変換することによってcaseを区別せずに文字の比較を行う。ただし背景となるシステムライブラリーがlocale固有の照合ルールを提供していない場合には、この関数はstring-equalにフォールバックする。この場合にはignore-case引数を無視して、常にcaseを区別した比較を行う。

MS-WindowsシステムでUnicode互換の照合をエミュレートする場合、MS-Windowsではlocaleのコードセット部分を"UTF-8"にできないので、w32-collate-ignore-punctuationに非nil値をバインドすること。

locale環境をサポートしないシステムでは、この関数はstring-lesspと同様に振る舞う。

Function: string-version-lessp string1 string2

この関数は文字列を辞書順で比較するが、数字のシーケンスを10進数で構成されているかのように扱い、その数値を比較する。つまりたとえ辞書順で‘12’が‘2’より“小”だとしても、この述語に応じて‘foo12.png’より‘foo2.png’が“小”になる。

Function: string-prefix-p string1 string2 &optional ignore-case

この関数はstring1string2のプレフィクス(たとえばstring2string1で始まる)なら、非nilをリターンする。オプションの引数ignore-caseが非nilなら、比較においてcaseの違いは無視される。

Function: string-suffix-p suffix string &optional ignore-case

この関数はsuffixstringのサフィックス(たとえばstringsuffixで終わる)なら、非nilをリターンする。オプションの引数ignore-caseが非nilなら、比較においてcaseの違いは無視される。

Function: string-search needle haystack &optional start-pos

haystack内で最初にneedle (いずれも文字列)が出現する位置をリターンする。start-posが非nilなら、検索はneedle内のその位置から開始される。マッチ(一致するもの)が見つからなければnilをリターンする。この関数は比較を行う際にはテキストプロパティは無視して、文字列内の文字だけを考慮する。マッチングでは常にcaseを区別する。

Function: compare-strings string1 start1 end1 string2 start2 end2 &optional ignore-case

この関数はstring1の指定部分をとstring2指定部分を比較する。string1の指定部分とは、インデックスstart1(その文字を含む)から、インデックスend1(その文字を含まない)まで。start1nilを指定すると文字列の最初という意味になり、end1nilを指定すると文字列の長さを意味する。同様にstring2の指定部分とはインデックスstart2からインデックスend2まで。

文字列は文字列内の文字の数値により比較される。たとえばstr1str2は、最初に異なる文字でstr1の文字の数値が小さければ小さいと判断される。ignore-caseが非nilなら比較を行なう前に、カレントバッファーのcaseテーブル(caseテーブルを参照)を使用して大文字に変換される。比較用にユニバイト文字列はマルチバイト文字列に変換されるので(テキストの表現方法を参照)、ユニバイト文字列とそれを変換したマルチバイト文字列は常に等しくなる。

2つの文字列の指定部分がマッチ(一致)した場合、値はtになる。それ以外なら値は整数で、何文字が一致してどちらの文字が小さいかを示す。この値の絶対値は、2つの文字列の先頭から一致した文字数に1加えた値になる。string1(または指定部分)のほうが小さければ符号は負になる。

Function: string-distance string1 string2 &optional bytecompare

この関数はソース文字列string1とターゲット文字列string2の間のレーベンシュタイン距離(Levenshtein distance)をリターンする。レーベンシュタイン距離はソース文字列をターゲット文字列に変換(削除、挿入、置換)するために必要な単一文字の個数。これは文字列間の編集距離(edit distance)として使用可能な定義の1つである。

計算距離にとって文字列の英字のcase(大文字小文字)は意味をもつが、テキストプロパティは無視される。オプション引数bytecompareが非nilなら、この関数は文字ではなくバイトで計算する。バイト単位での比較はEmacsの内部的な文字表現を使用するので、rawバイトを含むマルチバイト文字列では不正確な結果を生成するかもしれない(テキストの表現方法を参照)。rawで正確な結果が必要なら、エンコードして文字列をユニバイトにすること(明示的なエンコードとデコードを参照)。

Function: assoc-string key alist &optional case-fold

この関数はassocと同様に機能するが、keyは文字列かシンボルでなければならず、比較はcompare-stringsを使用して行なわれる。テストする前にシンボルは文字列に変換される。case-foldが非nilなら、keyalistの要素は比較前に大文字に変換される。assocとは異なり、この関数はコンスではない文字列またはシンボルのalist要素もマッチできる。特にalistは実際のalistではなく、文字列またはリストでも可。連想リストを参照のこと。

バッファー内のテキストを比較する方法として、テキストの比較の関数compare-buffer-substringsも参照してください。文字列にたいして正規表現のマッチを行なう関数string-matchも、ある種の文字列比較に使用することができます。正規表現の検索を参照してください。


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

4.6 文字および文字列の変換

このセクションでは文字、文字列、整数の間で変換を行なう関数を説明します。format (文字列のフォーマットを参照)とprin1-to-string (出力関数を参照)もLispオブジェクトを文字列に変換できます。read-from-string (入力関数を参照)は、Lispオブジェクトの文字列表現をオブジェクトに“変換”できます。関数string-to-multibytestring-to-unibyteは、テキスト表現を文字列に変換します(テキスト表現の変換を参照)。

テキスト文字と一般的なインプットイベントにたいするテキスト記述を生成する関数(single-key-descriptiontext-char-description)については、ドキュメントを参照してください。これらの関数は主にヘルプメッセージを作成するために使用されます。

Function: number-to-string number

この関数はnumberの10進プリント表現からなる文字列をリターンする。引数が負ならリターン値はマイナス記号から開始される。

(number-to-string 256)
     ⇒ "256"
(number-to-string -23)
     ⇒ "-23"
(number-to-string -23.5)
     ⇒ "-23.5"

int-to-stringはこの関数にたいする半ば廃れたエイリアスである。

文字列のフォーマットの関数formatも参照されたい。

Function: string-to-number string &optional base

この関数はstring内の文字の数値的な値をリターンする。baseが非nilなら値は2以上16以下でなければならず、整数はその基数に変換される。basenilなら基数に10が使用される。浮動小数点数の変換は基数が10のときだけ機能する。わたしたちは浮動小数点数にたいして他の基数を実装しない。なぜならこれには多くの作業を要し、その割にその機能が有用には思えないからだ。

パースではstringの先頭にあるスペースとタブはスキップして、与えられた基数で数字として解釈できるところまでstringを読み取る(スペースとタブだけではなく先頭にある他の空白文字を無視するシステムもある)。stringを数字として解釈できなければこの関数は0をリターンする。

(string-to-number "256")
     ⇒ 256
(string-to-number "25 is a perfect square.")
     ⇒ 25
(string-to-number "X256")
     ⇒ 0
(string-to-number "-4.5")
     ⇒ -4.5
(string-to-number "1e5")
     ⇒ 100000.0

string-to-intはこの関数にたいする半ば廃れたエイリアスである。

Function: char-to-string character

この関数は1つの文字characterを含む新しい文字列をリターンする。関数stringのほうがより一般的であり、この関数は半ば廃れている。文字列の作成を参照のこと。

Function: string-to-char string

この関数はstringの最初の文字をリターンする。これはほとんど(aref string 0)と同じで、例外は文字列が空のときに0をリターンすること(文字列の最初の文字がASCIIコード0のヌル文字のときも0をリターンする)。この関数は残すのに充分なほど有用と思えなければ、将来削除されるかもしれない。

以下は文字列へ/からの変換に使用できるその他の関数です:

concat

この関数はベクターまたはリストから文字列に変換する。文字列の作成を参照のこと。

vconcat

この関数は文字列をベクターに変換する。ベクターのための関数を参照のこと。

append

この関数は文字列をリストに変換する。コンスセルおよびリストの構築を参照のこと。

byte-to-string

この関数は文字データのバイトをユニバイト文字列に変換する。テキスト表現の変換を参照のこと。


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

4.7 文字列のフォーマット

フォーマット(formatting)とは、定数文字列内のさまざまな場所を計算された値で置き換えることにより、文字列を構築することを意味します。この定数文字列は他の値がどのようにプリントされるか、およびどこに表示するかを制御します。これはフォーマット文字列(format string)と呼ばれます。

表示されるメッセージを計算するためにフォーマットが便利なことがしばしばあります。実際に関数messageerrorは、ここで説明する機能と同じフォーマットを提供します。これらの関数とformat-messageの違いはフォーマットされた結果を使用する方法だけです。

Function: format string &rest objects

この関数はstringのすべてのフォーマット仕様を、対応するobjectsを復号化したものと置換したものと等しい文字列をリターンする。引数objectsはフォーマットされる計算値。

(もしあれば)string内のフォーマット仕様以外の文字はテキストプロパティを含めて出力に直接コピーされる。フォーマット仕様のすべてのテキストプロパティは引数objectsを表現する生成された文字列にコピーされる。

出力される文字列は新規に割り当てられる必要はない。たとえばxが文字列"foo"なら(eq x (format x))(eq x (format "%s" x))はいずれもtとなるだろう。

Function: format-message string &rest objects

この関数はformatと同様に機能するが、string内のすべてのグレイブアクセント(`)とアポストロフィー(')をtext-quoting-styleの各値に応じて変換する点が異なる。

フォーマット内のグレイブアクセントとアポストロフィーはマッチするcurved quotesに変換される("Missing `%s'""Missing ‘foo’"という結果になる)この変換の影響と回避についてはテキストのクォートスタイルを参照のこと。

フォーマット仕様(format specification)は‘%’で始まる文字シーケンスです。したがってstring内に‘%d’があるとformatはそれを、フォーマットされる値の1つ(引数objectsのうちの1つ)にたいするプリント表現で置き換えます。たとえば:

(format "The value of fill-column is %d." fill-column)
     ⇒ "The value of fill-column is 72."

formatは文字‘%’をフォーマット仕様と解釈するので、決して最初の引数に不定な文字列(arbitrary string)を渡すべきではありません。これは特に何らかのLispコードが生成した文字列の場合に当てはまります。その文字列が決して文字‘%’を含まないと確信できないならば、以下で説明するように最初の引数に"%s"を渡して、その不定な文字列を2番目の引数として渡します:

  (format "%s" arbitrary-string)

ある種のフォーマット仕様は特定の型の値を要求します。その要求に適合しない値を与えた場合にはエラーがシグナルされます。

以下は有効なフォーマット仕様のテーブルです:

%s

フォーマット仕様を、クォートなしのオブジェクトのプリント表現で置き換える(つまりprin1ではなくprincを使用して置き換える。出力関数を参照されたい)。したがって文字列は‘"’文字なしの文字列内容だけが表示され、シンボルは‘\’文字なしで表される。

オブジェクトが文字列なら文字列のプロパティは出力にコピーされる。‘%s’のテキストプロパティ自身もコピーされるが、オブジェクトのテキストプロパティが優先される。

%S

フォーマット仕様を、クォートありのオブジェクトのプリント表現で置き換える(つまりprin1を使用して変換する。出力関数を参照されたい)。したがって文字列は‘"’文字で囲まれ、必要となる特別文字の前に‘\’文字が表示される。

%o

フォーマット仕様を整数の8進表現に置き換える。負の整数はプラットフォーム依存の方法でフォーマットされる。オブジェクトは浮動小数点数(小数部分を切り捨てて整数にフォーマット)でもよい。

%d

フォーマット仕様を10進表現の符号つき整数で置き換える。オブジェクトは浮動小数点数(小数部分を切り捨てて整数にフォーマット)でもよい。

%x
%X

フォーマット仕様を16進表現の整数で置き換える。負の整数はプラットフォーム依存の方法でフォーマットされる。‘%x’なら小文字、‘%X’なら大文字が使用される。オブジェクトは小数部分を切り捨てて整数にフォーマットされた浮動小数点数でもよい。

%c

フォーマット仕様を与えられた値の文字で置き換える。

%e

フォーマット仕様を浮動小数点数の指数表現で置き換える。

%f

フォーマット仕様を浮動小数点数にたいする10進小数表記で置き換える。

%g

指数表記か小数点表記のいずれかを使用してフォーマット仕様を浮動小数点数にたいする表記に置き換える。指数が-4未満または精度(デフォルトは6)以上なら指数表記を使用する。デフォルトでは結果の小数部の末尾の0は削除されて、小数点が現れるのは後に数字が続く場合のみ。

%%

フォーマット仕様を1つの‘%’で置き換える。このフォーマット仕様は唯一のフォームが素の‘%%’であり値を使用しないという点で特殊。たとえば(format "%% %d" 30)"% 30"をリターンする。

他のフォーマット文字は‘Invalid format operation’エラーとなります。

以下は典型的なtext-quoting-styleのセッティングを想定した場合の例です:

(format "The octal value of %d is %o,
         and the hex value is %x." 18 18 18)
     ⇒ "The octal value of 18 is 22,
         and the hex value is 12."

(format-message
 "The name of this buffer is ‘%s’." (buffer-name))
     ⇒ "The name of this buffer is ‘strings-ja.texi’."

(format-message
 "The buffer object prints as `%s'." (current-buffer))
     ⇒ "The buffer object prints as ‘strings-ja.texi’."

フォーマット仕様はデフォルトではobjectsから連続して値を引き当てます。つまりstring内の1番目のフォーマット仕様は1番目の値、2番目のフォーマット仕様は2番目の値、...を使用します。余分なフォーマット仕様(対応する値がない場合)にはエラーとなります。フォーマットされる値が余分にある場合には無視されます。

フォーマット仕様はフィールド番号(field number)をもつことができます。これは最初の‘%’の直後に10進数字、その後にドル記号‘$’が続きます。これにより次の引数ではなく与えられた番号の引数をフォーマット仕様に変換させることができます。フィールド番号は1から始まります。フォーマットのフォーマット仕様が番号を含むことも含まないことも可能ですが、両方を含むことはできません。ただし例外は‘%%’であり、これは番号付きのフォーマット仕様と混交できます。

(format "%2$s, %3$s, %%, %1$s" "x" "y" "z")
     ⇒ "y, z, %, x"

%’とすべてのフィールド番号の後にフラグ文字(flag characters)を配置できます。

フラグ‘+’は非負の数の前にプラス符号を挿入するので、数には常に符号がつきます。フラグとしてスペースを指定すると、非負の数の前に1つのスペースが挿入されます(それ以外は非負の数は最初の数字から開始される)。これらのフラグは非負の数と負数にたいして確実に同じ列数を使用させるために有用です。これらは‘%d’、‘%e’、‘%f’、‘%g’以外では無視され、両方が指定された場合は‘+’が優先されます。

フラグ‘#’は代替形式(alternate form)を指定します。これは使用するフォーマットに依存します。‘%o’にたいしては結果を‘0’で開始させます。‘%x’と‘%X’にたいしては非0の結果のプレフィクスは‘0x’または‘0X’になります。‘%e’、‘%f’にたいしての‘#’フラグは、小数部が0のときにも小数点が含まれることを意味します。‘%g’にたいしては常に小数点が含まれるとともに、それ以外なら削除される小数点の後の末尾のすべての0も強制的に残されます。

フラグ‘0’はスペースの代わりに文字‘0’でパディングします。このフラグは‘%s’、‘%S’、‘%c’のような非数値のフォーマット仕様文字では無視されます。これらのフォーマット仕様文字で‘0’フラグを指定できますが、それでもスペースでパディングされます。

フラグ‘-’はフィールド幅指定子により挿入されるすべてのパディングに作用して、もしパディングが指定された場合には左側ではなく右側にパディングされます。‘-’と‘0’の両方が指定されると‘0’フラグは無視されます。

(format "%06d is padded on the left with zeros" 123)
     ⇒ "000123 is padded on the left with zeros"

(format "'%-6d' is padded on the right" 123)
     ⇒ "'123   ' is padded on the right"

(format "The word '%-7s' actually has %d letters in it."
        "foo" (length "foo"))
     ⇒ "The word 'foo    ' actually has 3 letters in it."

フォーマット仕様はフィールド幅(width)をもつことができます。これはすべてのフィールド番号とフラグの後にある10進の数字です。オブジェクトのプリント表現がこのフィールド幅より少ない文字を含む場合には、formatはパディングによりフィールド幅に拡張します。フォーマット仕様‘%%’ではフィールド幅の指定は無視されます。フィールド幅指定子により行なわれるパディングは、通常は左側に挿入されるスペースで構成されます:

(format "%5d is padded on the left with spaces" 123)
     ⇒ "  123 is padded on the left with spaces"

フィールド幅が小さすぎる場合でもformatはオブジェクトのプリント表現を切り詰めません。したがって情報を失う危険を犯すことなく、フィールドの最小幅を指定することができます。以下の2つの例では‘%7s’は最小幅に7を指定します。1番目の例では‘%7s’に挿入される文字列は3文字だけなので、4つのブランクスペースによりパディングされます。2番目の例では文字列"specification"は13文字ですが切り詰めはされません。

(format "The word '%7s' has %d letters in it."
        "foo" (length "foo"))
     ⇒ "The word '    foo' has 3 letters in it."
(format "The word '%7s' has %d letters in it."
        "specification" (length "specification"))
     ⇒ "The word 'specification' has 13 letters in it."

すべてのフォーマット仕様文字にはフィールド番号、フラグ、フィールド幅の後にオプションで精度(precision)を指定できます。精度は小数点‘.’と、その後に桁文字列(digit-string)を指定します。浮動小数点数のフォーマット仕様(‘%e’と‘%f’)では、精度は表示する小数点以下の桁数を指定します。0なら小数点も省略されます。%gの精度が0か未指定なら1として扱われます。‘%s’と‘%S’では精度として与えられた幅に文字列が切り詰められるので、‘%.3s’ではobjectの表現の最初の3文字だけが表示されます。その他の仕様文字では、printfファミリーのローカルライブラリーが生成する精度の効果が表れます。

%s’と‘%S’にたいしては、文字列を精度で指定された幅に切り詰めます。したがって‘%.3s’では、objectにたいするプリント表現の最初の3文字だけが表示されます。他のフォーマット仕様文字にたいしては、精度の効果はローカルライブラリーのprintf関数ファミリーが生成する効果となります。

フォーマット済みの値のコピーを取得するために後でreadを使用する予定なら、readが値を再構築する仕様を使用してください。この逆手順で数値をフォーマットするには‘%s’と‘%S’、整数だけなら‘%d’、非負の整数なら‘#x%x’と‘#o%o’も使用できます。その他のフォーマットでは問題があるかもしれません。たとえば‘%d’と‘%g’はNaNを誤って処理したり精度や型を失うかもしれず、‘#x%x’と‘#o%o’は負の整数を誤って処理するかもしれません。入力関数を参照してください。

このセクションでは仕様文字の固定セットを受け取る関数を説明します。次のセクションでは‘%a’や‘%z’のようなカスタム仕様文字を受け取ることができる関数format-specを説明します。


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

4.8 カスタムフォーマット文字列

ユーザーやLispプログラムが、カスタムフォーマットの制御文字列を介して特定のテキストが生成される方法を制御できるようにすると便利な場合があります。たとえばフォーマット文字列は人の姓や名、emailアドレスを表示する方法を制御できます。前のセクションで説明した関数formatを使用することにより、フォーマット文字列は"%s %s <%s>"のようになるかもしれません。しかしこのアプローチはどの仕様文字がどの情報に対応するかが不明瞭なのですぐに非実用的になります。

そのような場合には"%f %l <%e>"のようなフォーマット文字列のほうが便利かもしれません。このフォーマット文字列では仕様文字それぞれがより意味的な情報をもち、他の仕様文字に関連して簡単に再配置できるので、このようなフォーマット文字列はユーザーにより簡単にカスタマイズできます。

このセクションで説明する関数format-specformatと同様の機能を処理しますが、任意の仕様文字を使用するフォーマットコントロール文字列を処理する点が異なります。

Function: format-spec template spec-alist &optional ignore-missing split

この関数はspec-alistで指定された変換にしたがってフォーマット文字列templateから生成された文字列をリターンする。spec-alist(letter . replacement)という形式のalist(連想リストを参照)。template内の仕様%letterはそれぞれ結果文字列のフォーマット時に置換される。

(もしあれば)template内のフォーマット仕様以外の文字はテキストプロパティを含めて出力に直接コピーされる。フォーマット仕様のすべてのテキストプロパティは置換先にコピーされる。

変換の指定にalistを使用することによって有用な特性がいくつか生成される:

  • template内に存在する一意な仕様文字より多くの一意なletterキーがspec-alistに含まれていると、使用されないキーは単に無視される。
  • 同じletterにたいして複数の連想値がspec-alistに含まれていると、リスト先頭にもっとも近いものを使用する。
  • templateに同じ仕様文字が複数個含まれている場合には、その文字のすべての置換の基礎としてspec-alist内で見つけたreplacementを使用する。
  • template内の仕様の順序は、spec-alist内の連想値の順序に対応する必要はない。

REPLACEMENTは引数なしで呼び出されて置換に用いる文字列をリターンする関数でもよい。この関数はTEMPLATEで対応するLETTERが使用された際にのみ呼び出される。これはたとえば必要なとき以外は入力を求めるプロンプトの表示を避ける場合に役に立つかもしれない。

オプション引数ignore-missingは、spec-alistで見つからないtemplate内の仕様文字の処理方法を示す。nilか省略なら、関数はエラーをシグナルする。ignoreならこれらのフォーマット仕様は(もしあれば)テキストプロパティも含めてそのまま出力する。deleteならこれらのフォーマット仕様は出力から取り除かれる。これら以外の非nil値はignoreと同様に処理されるが、出力中に‘%%’があればそのまま残される。

オプション引数splitが非nilなら、format-specは単一文字列のかわりに置換場所を基準に結果を文字列リストに分割してリターンする。たとえば:

(format-spec "foo %b bar" '((?b . "zot")) nil t)
     ⇒ ("foo " "zot" " bar")

format-specが受け取るフォーマット仕様の構文はformatが受け取るフォーマット仕様と似ていますが同一ではありません。いずれの場合でもフォーマット仕様は‘%’で始まり‘s’のようなアルファベット文字で終わる文字シーケンスです。

仕様文字の固定セットに特定の意味を割り当てるformatとは異なり、format-specは任意の仕様文字を受け取ってそれらをすべて等しく扱います。たとえば:

(setq my-site-info
      (list (cons ?s system-name)
            (cons ?t (symbol-name system-type))
            (cons ?c system-configuration)
            (cons ?v emacs-version)
            (cons ?e invocation-name)
            (cons ?p (number-to-string (emacs-pid)))
            (cons ?a user-mail-address)
            (cons ?n user-full-name)))

(format-spec "%e %v (%c)" my-site-info)
     ⇒ "emacs 27.1 (x86_64-pc-linux-gnu)"

(format-spec "%n <%a>" my-site-info)
     ⇒ "Emacs Developers <emacs-devel@gnu.org>"

フォーマット仕様には置換の様相を変更するために、‘%’の直後に任意個数のフラグ文字を含めることができます。

0

このフラグは指定された幅のパディングをスペースのかわりに‘0’で構成する。

-

このフラグは指定された幅のパディングを左側ではなく右側に挿入する。

<

このフラグはもし幅と精度が指定されたら置換の左側を切り捨てる。

>

このフラグはもし幅が指定されたら置換の右側を切り捨てる。

^

このフラグは置換されるテキストを大文字に変換する(Lispでの大文字小文字変換を参照)。

_ (アンダースコアー)

このフラグは置換されるテキストを小文字に変換する(Lispでの大文字小文字変換を参照)。

矛盾したフラグ(たとえば大文字と小文字)を使用した場合の結果は未定義です。

formatの場合と同様に幅(任意のフラグの後の10進数値)、精度(任意のフラグと幅の後の小数点‘.’に続く10進数)をフォーマット仕様に含めることができます。

指定した幅より置換の文字が少なければ左側がパディングされます。

(format-spec "%8a is padded on the left with spaces"
             '((?a . "alpha")))
     ⇒ "   alpha is padded on the left with spaces"

指定した精度より置換の文字が多ければ右側が切り詰められます。

(format-spec "%.2a is truncated on the right"
             '((?a . "alpha")))
     ⇒ "al is truncated on the right"

以下は前述の機能をいくつか組み合わせたより複雑な例です:

(setq my-battery-info
      (list (cons ?p "73")      ; パーセント表示
            (cons ?L "Battery") ; 状態
            (cons ?t "2:23")    ; 残り時間
            (cons ?c "24330")   ; 容量
            (cons ?r "10.6")))  ; 放電率

(format-spec "%>^-3L : %3p%% (%05t left)" my-battery-info)
     ⇒ "BAT :  73% (02:23 left)"

(format-spec "%>^-3L : %3p%% (%05t left)"
             (cons (cons ?L "AC")
                   my-battery-info))
     ⇒ "AC  :  73% (02:23 left)"

このセクションの例で示したように、format-specはさまざまな情報の断片を選択的にフォーマットするために頻繁に使用されます。これはプログラムが可能にする情報のサブセットだけをユーザーが通常の構文で望む順序で選択できるように、ユーザーにカスタマイズ可能なフォーマット文字列を提供するプログラムにとって有用です。


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

4.9 Lispでの大文字小文字変換

case変換関数(character case functions)は、1つの文字または文字列中の大文字小文字を変換します。関数は通常、アルファベット文字(英字‘A’から‘Z’と‘a’から‘z’、同様に非ASCIIの英字)だけを変換し、それ以外の文字は変換しません。caseテーブル(case table。caseテーブルを参照されたい)で指定することにより、caseの変換に異なるマッピングを指定できます。

これらの関数は引数として渡された文字列は変更しません。

以下の例では文字‘X’と‘x’を使用します。これらのASCIIコードは88と120です。

Function: downcase string-or-char

この関数はstring-or-char(文字か文字列)を小文字に変換する。

string-or-charが文字列なら、この関数は引数の大文字を小文字に変換した新しい文字列をリターンする。string-or-charが文字なら、この関数は対応する小文字(整数)をリターンする。元の文字が小文字か非英字ならリターン値は元の文字と同じ。

(downcase "The cat in the hat")
     ⇒ "the cat in the hat"

(downcase ?X)
     ⇒ 120
Function: upcase string-or-char

この関数はstring-or-char(文字か文字列)を大文字に変換する。

string-or-charが文字列なら、この関数は引数の小文字を大文字に変換した新しい文字列をリターンする。string-or-charが文字なら、この関数は対応する大文字(整数)をリターンする。元の文字が大文字か非英字ならリターン値は元の文字と同じ。

(upcase "The cat in the hat")
     ⇒ "THE CAT IN THE HAT"

(upcase ?x)
     ⇒ 88
Function: capitalize string-or-char

この関数は文字列や文字をキャピタライズ(capitalize: 先頭が大文字で残りは小文字)する。この関数はstring-or-charが文字列ならstring-or-charの各単語をキャピタライズした新たなコピーをリターンする。これは各単語の最初の文字が大文字に変換され、残りは小文字に変換されることを意味する。

単語の定義はカレント構文テーブル(current syntax table)の単語構成構文クラス(word constituent syntax class)に割り当てられた、連続する文字の任意シーケンスである(構文クラスのテーブルを参照)。

string-or-charが文字ならこの関数はupcaseと同じことを行なう。

(capitalize "The cat in the hat")
     ⇒ "The Cat In The Hat"

(capitalize "THE 77TH-HATTED CAT")
     ⇒ "The 77th-Hatted Cat"

(capitalize ?x)
     ⇒ 88
Function: upcase-initials string-or-char

この関数はstring-or-charが文字列なら、string-or-charの中の単語の頭文字をキャピタライズして、頭文字以外の文字は変更しない。この関数はstring-or-charの各単語の頭文字が大文字に変換された新しいコピーをリターンする。

単語の定義はカレント構文テーブル(current syntax table)の単語構成構文クラス(word constituent syntax class)に割り当てられた、連続する文字の任意シーケンスである(構文クラスのテーブルを参照)。

upcase-initialsの引数が文字なら、upcase-initialsの結果はupcaseと同じ。

(upcase-initials "The CAT in the hAt")
     ⇒ "The CAT In The HAt"

case変換コードポイントを1対1でマップするものではなく、結果の文字列長は引数の文字列長と異なるかもしれません。さらに文字を渡すことによりリターンされる型にも文字が強制されるので、関数は正しい置換を行えずに1文字の文字列を処理する場合とは結果が異なるかもしれません。たとえば:

(upcase "fi")  ; 注意: 1文字の合字 "fi"
     ⇒ "FI"
(upcase ?fi)
     ⇒ 64257  ; つまり ?fi

これを避けるためにはcase関数のいずれかに文字を渡す前にstring関数を使用して文字列に変換しなければなりません。もちろん結果の長さについて仮定はできません。

このような特殊ケースのマッピングはspecial-uppercasespecial-lowercasespecial-titlecaseから取得されます。文字のプロパティを参照してください。

文字列を比較する関数(caseの違いを無視するものや、オプションでcaseの違いを無視できるもの)については、文字および文字列の比較を参照されたい。


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

4.10 caseテーブル

特別なcaseテーブル(case table)をインストールすることにより、caseの変換をカスタマイズできます。caseテーブルは大文字と小文字の間のマッピングを指定します。caseテーブルはLispオブジェクトにたいするcase変換関数(前のセクションを参照)と、バッファー内のテキストに適用される関数の両方に影響します。それぞれのバッファーにはcaseテーブルがあります。新しいバッファーのcaseテーブルを初期化するために使用される、標準のcaseテーブル(standard case table)もあります。

caseテーブルは、サブタイプがcase-tableの文字テーブル(char-table。文字テーブルを参照)です。この文字テーブルはそれぞれの文字を対応する小文字にマップします。caseテーブルは、関連するテーブルを保持する3つの余分なスロットをもちます:

upcase

upcase(大文字)テーブルはそれぞれの文字を対応する大文字にマップする。

canonicalize

canonicalize(正準化)テーブルは、caseに関連する文字セットのすべてを、その文字セットの特別なメンバーにマップする。

equivalences

equivalence(同値)テーブルは、大文字・小文字に関連した文字セットのそれぞれを、そのセットの次の文字にマップする。

単純な例では、小文字へのマッピングを指定することだけが必要です。3つの関連するテーブルは、このマッピングから自動的に計算されます。

大文字と小文字が1対1で対応しない言語もいくつかあります。これらの言語では、2つの異なる小文字が同じ大文字にマップされます。このような場合、大文字と小文字の両方にたいするマップを指定する必要があります。

追加のcanonicalizeテーブルは、それぞれの文字を正準化された等価文字にマップします。caseに関連する任意の2文字は、同じ正準等価文字(canonical equivalent character)をもちます。たとえば‘a’と‘A’はcase変換に関係があるので、これらの文字は同じ正準等価文字(両方の文字が‘a’、または両方の文字が‘A’)をもつべきです。

追加のequivalencesテーブルは、等価クラスの文字(同じ正準等価文字をもつ文字)それぞれを循環的にマップします(通常のASCIIでは、これは‘a’を‘A’に‘A’を‘a’にマップし、他の等価文字セットにたいしても同様にマップする)。

caseテーブルを構築する際は、canonicalizenilを指定できます。この場合、Emacsは大文字と小文字のマッピングでこのスロットを充填します。equivalencesにたいしてnilを指定することもできます。この場合、Emacsはcanonicalizeからこのスロットを充填します。実際に使用されるcaseテーブルでは、これらのコンポーネントは非nilです。canonicalizeを指定せずにequivalencesを指定しないでください。

以下はcaseテーブルに作用する関数です:

Function: case-table-p object

この述語は、objectが有効なcaseテーブルなら非nilをリターンする。

Function: set-standard-case-table table

この関数はtableを標準caseテーブルにして、これ以降に作成される任意のバッファーにたいしてこのテーブルが使用されるようにする。

Function: standard-case-table

これは標準caseテーブル(standard case table)をリターンする。

Function: current-case-table

この関数はカレントバッファーのcaseテーブルをリターンする。

Function: set-case-table table

これはカレントバッファーのcaseテーブルをtableにセットする。

Macro: with-case-table table body…

with-case-tableマクロはカレントcaseテーブルを保存してから、tableをカレントcaseテーブルにセットし、その後にbodyフォームを評価してから、最後にcaseテーブルをリストアします。リターン値は、bodyの最後のフォームの値です。throwかエラー(非ローカル脱出を参照)により異常終了した場合でも、caseテーブルはリストアされます。

ASCII文字のcase変換を変更する言語環境(language environment)がいくつかあります。たとえばトルコ語の言語環境では、ASCIIの大文字‘I’にたいする小文字は、トルコ語のドットがないi(‘ı’)です。これは(ASCIIベースのネットワークプロトコル実装のような)ASCIIの通常のcase変換を要求するコードに干渉する可能性があります。このような場合には、変数ascii-case-tableにたいしてwith-case-tableマクロを使用してください。これにより変更されていないASCII文字セットのcaseテーブルが保存されます。

Variable: ascii-case-table

ASCII文字セットにたいするcaseテーブル。すべての言語環境セッティングにおいて、これを変更するべきではない。

以下の3つの関数は、非ASCII文字セットを定義するパッケージにたいして便利なサブルーチンです。これらはcase-tableに指定されたcaseテーブルを変更します。これは標準構文テーブルも変更します。構文テーブルを参照してください。通常これらの関数は、標準caseテーブルを変更するために使用されます。

Function: set-case-syntax-pair uc lc case-table

この関数は対応する文字のペアー(一方は大文字でもう一方は小文字)を指定する。

Function: set-case-syntax-delims l r case-table

この関数は文字lrを、case不変区切り(case-invariant delimiter)のマッチングペアーとする。

Function: set-case-syntax char syntax case-table

この関数はcharを構文syntaxのcase不変(case-invariant)とする。

Command: describe-buffer-case-table

このコマンドはカレントバッファーのcaseテーブルの内容にたいする説明を表示する。


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

5 リスト

リスト(list)は0個以上の要素(任意のLispオブジェクト)のシーケンスを表します。リストとベクターの重要な違いは、2つ以上のリストが構造の一部を共有できることです。加えて、リスト全体をコピーすることなく要素の挿入と削除ができます。


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

5.1 リストとコンスセル

Lispでのリストは基本データ型ではありません。リストはコンスセル(cons cells)から構築されます(コンスセルとリスト型を参照)。コンスセルは順序つきペアを表現するデータオブジェクトです。つまりコンスセルは2つのスロットをもち、それぞれのスロットはLispオブジェクトを保持(holds)または参照(refers to)します。1つのスロットはCAR、もう1つはCDRです(これらの名前は歴史的なものである。コンスセルとリスト型を参照されたい)。CDRは“could-er(クダー)”と発音します。

わたしたちは、コンスセルのCARスロットに現在保持されているオブジェクトが何であれ、“このコンスセルのCARは、...”のような言い方をします。これはCDRの場合でも同様です。

リストとは互いに連なる(chained together)一連のコンスセルであり、各セルは次のセルを参照します。リストの各要素にたいして1つのコンスセルがあります。慣例によりコンスセルのCARはリストの要素を保持し、CDRはリストをチェーンするのに使用されます(CARCDRの間の非対称性は完全に慣例的なものである。コンスセルのレベルではCARスロットとCDRスロットは同じようなプロパティをもつ)。したがって、リスト内の各コンスセルのCDRスロットは次のコンスセルを参照します。

これも慣例的なものですがリスト内の最後のコンスセルのCDRnilです。わたしたちはこのようなnilで終端された構造を正リスト(proper list)と呼びます4。Emacs Lispではシンボルnilはシンボルであり、かつ要素なしのリストでもあります。便宜上、シンボルnilはそのCDR(とCAR)にnilをもつと考えます。

したがって正リストのCDRは常に正リストです。空でない正リストのCDRは1番目の要素以外を含む正リストです。

リストの最後のコンスセルのCDRnil以外の何らかの値の場合、このリストのプリント表現はドットペア表記(dotted pair notation。ドットペア表記を参照のこと)を使用するので、わたしたちはこの構造をドットリスト(dotted list)と呼びます。他の可能性もあります。あるコンスセルのCDRが、そのリストのそれより前にある要素を指すかもしれません。わたしたちは、この構造を循環リスト(circular list)と呼びます。

ある目的においてはそのリストが正リストか循環リストなのか、あるいはドットリストなのかが問題にならない場合もあります。そのプログラムがリストを充分に辿って最後のコンスセルのCDRを確認しようとしないなら、これは問題になりません。しかしリストを処理する関数のいくつかは正リストを要求し、ドットリストの場合はエラーをシグナルします。リストの最後を探そうと試みる関数のほとんどは循環リストを与えると無限ループに突入します。リストが正リストかどうかを判断するためには、次セクションで説明する関数proper-list-p (proper-list-pを参照)を使うことができます。

ほとんどのコンスセルはリストの一部として使用されるので、わたしたちはコンスセルで構成される任意の構造をリスト構造(list structure)と呼びます。


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

5.2 リストのための述語

以下の述語はあるLispオブジェクトがアトムか、コンスセルか、リストなのか、またはオブジェクトがnilかどうかテストします(これらの述語の多くは他の述語で定義することもできるが、多用されるので個別に定義する価値がある)。

Function: consp object

この関数はobjectがコンスセルならt、それ以外はnilをリターンする。たとえnilリストであっても、コンスセルではない。

Function: atom object

この関数はobjectがアトムならt、それ以外はnilをリターンする。シンボルnilはアトムであり、かつリストでもある。そのようなLispオブジェクトはnilだけである。

(atom object) ≡ (not (consp object))
Function: listp object

この関数はobjectがコンスセルかnilならt、それ以外はnilをリターンする。

(listp '(1))
     ⇒ t
(listp '())
     ⇒ t
Function: nlistp object

この関数はlistpの反対である。objectがリストでなければt、それ以外はnilをリターンする。

(listp object) ≡ (not (nlistp object))
Function: null object

この関数はobjectnilならt、それ以外はnilをリターンする。この関数はnotと等価だが、明解にするためにobjectをリストだと考えるときはnull、真偽値だと考えるときはnotを使用すること(組み合わせ条件の構築notを参照)。

(null '(1))
     ⇒ nil
(null '())
     ⇒ t
Function: proper-list-p object

この関数はobjectが適正なリストならobjectの長さ、それ以外はnilをリターンする(リストとコンスセルを参照)。適正なリストとはlistpを満足することに加えて、循環リストやドットリストでもない。

(proper-list-p '(a b c))
    ⇒ 3
(proper-list-p '(a b . c))
    ⇒ nil

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

5.3 リスト要素へのアクセス

Function: car cons-cell

この関数はコンスセルcons-cellの1番目のスロットが参照する値をリターンする。言い換えるとこの関数はcons-cellCARをリターンする。

特別なケースとしてcons-cellnilの場合、この関数はnilをリターンする。したがってリストはすべて引数として有効である。引数がコンスセルでもnilでもなければエラーがシグナルされる。

(car '(a b c))
     ⇒ a
(car '())
     ⇒ nil
Function: cdr cons-cell

この関数はコンスセルcons-cellの2番目のスロットにより参照される値をリターンする。言い換えるとこの関数はcons-cellCDRをリターンする。

特別なケースとしてcons-cellnilの場合、この関数はnilをリターンする。したがってリストはすべて引数として有効である。引数がコンスセルでもnilでもければエラーがシグナルされる。

(cdr '(a b c))
     ⇒ (b c)
(cdr '())
     ⇒ nil
Function: car-safe object

この関数により他のデータ型によるエラーを起こさずに、コンスセルのCARを取得できり。この関数はobjectがコンスセルならobjectCAR、それ以外はnilをリターンする。この関数は、objectがリストでなければエラーをシグナルするcarとは対象的である。

(car-safe object)
≡
(let ((x object))
  (if (consp x)
      (car x)
    nil))
Function: cdr-safe object

この関数により他のデータ型によるエラーを起こさずに、コンスセルのCDRを取得できる。この関数はobjectがコンスセルならobjectCDR、それ以外はnilをリターンする。この関数は、objectがリストでないときはエラーをシグナルするcdrとは対象的である。

(cdr-safe object)
≡
(let ((x object))
  (if (consp x)
      (cdr x)
    nil))
Macro: pop listname

このマクロはリストのCARを調べて、それをリストから取り去るのを一度に行なう便利な方法を提供する。この関数はlistnameに格納されたリストにたいして処理を行なう。この関数はリストから1番目の要素を削除して、CDRlistnameに保存し、その後で削除した要素をリターンする。

もっとも単純なケースは、リストに名前をつけるためのクォートされていないシンボルの場合である。この場合、このマクロは(prog1 (car listname) (setq listname (cdr listname)))と等価である。

x
     ⇒ (a b c)
(pop x)
     ⇒ a
x
     ⇒ (b c)

より一般的なのはlistnameが汎変数(generalized variable)の場合である。この場合、このマクロはsetfを使用してlistnameに保存する。ジェネリック変数を参照のこと。

リストに要素を追加するpushマクロについてはリスト変数の変更を参照のこと。

Function: nth n list

この関数はlistn番目の要素をリターンする。要素は0から数えられるのでlistCARは要素0になる。listの長さがn以下なら値はnil

(nth 2 '(1 2 3 4))
     ⇒ 3
(nth 10 '(1 2 3 4))
     ⇒ nil

(nth n x) ≡ (car (nthcdr n x))

これは関数eltも類似しているが、任意の種類のシーケンスに適用される。歴史的な理由によりこの関数は逆の順序で引数を受け取る。シーケンスを参照のこと。

Function: nthcdr n list

この関数はlistn番目のCDRをリターンする。言い換えると、この関数はlistの最初のn個のリンクをスキップしてから、それ以降をリターンする。

nが0ならnthcdrlist全体をリターンする。listの長さがn以下ならnthcdrnilをリターンする。

(nthcdr 1 '(1 2 3 4))
     ⇒ (2 3 4)
(nthcdr 10 '(1 2 3 4))
     ⇒ nil
(nthcdr 0 '(1 2 3 4))
     ⇒ (1 2 3 4)
Function: take n list

この関数はlistの最初のn個の要素をリターンする。要するにlistからnthcdrをスキップした部分をリターンする。

listの要素の数がnより少なければlistnが0か負ならnilをリターンする。

(take 3 '(a b c d))
     ⇒ (a b c)
(take 10 '(a b c d))
     ⇒ (a b c d)
(take 0 '(a b c d))
     ⇒ nil
Function: ntake n list

これは引数であるリストの構造を破壊的に変更することによって機能するバージョンのtakeである。これにより高速になるが、listの元の値は失われるだろう。

ntakeは要素の数がnより少なければ変更せずにlistを、nが0か負ならnilをリターンする。それ以外の場合には最初のn個の要素に切り詰められたlistをリターンする。

これはnが正だと判っていない場合には単純に切り詰め効果を信頼するのではなく、通常はリターン値を使うほうが賢明だということを意味している。

Function: last list &optional n

この関数はlistの最後のリンクをリターンする。このリンクのcarはこのリストの最後の要素。listがnullならnilがリターンされる。nが非nilならn番目から最後までのリンクがリターンされる。nlistの長さより大きければlist全体がリターンされる。

Function: safe-length list

この関数はエラーや無限ループの危険なしで、listの長さをリターンする。この関数は一般的に、リスト内のコンスセルの個数をリターンする。しかし循環リストでは単に上限値が値となるため、非常に大きくなる場合があります。

listnilとコンスセルのいずれでもなければsafe-lengthは0をリターンする。

循環リストを考慮しなくてもよい場合にリストの長さを計算するもっとも一般的な方法は、lengthを使う方法です。シーケンスを参照してください。

Function: caar cons-cell

これは(car (car cons-cell))と同じ。

Function: cadr cons-cell

これは(car (cdr cons-cell))(nth 1 cons-cell)と同じ。

Function: cdar cons-cell

これは(cdr (car cons-cell))と同じ。

Function: cddr cons-cell

これは(cdr (cdr cons-cell))(nthcdr 2 cons-cell)と同じ。

上記に加えてcxxxrcxxxxrのようなcarcdrで構成される24の関数が定義されています。ここでxadのいずれかです。cadrcaddrcadddrはそれぞれリストの2つ目、3つ目、4つ目の要素です。cl-libは同じものをcl-secondcl-thirdcl-fourthという名前で提供しています。List Functions in Common Lisp Extensionsを参照してください。

Function: butlast x &optional n

この関数はリストxから、最後の要素か最後のn個の要素を削除してリターンする。nが0より大きければこの関数はリストのコピーを作成するので、元のリストに影響はない。一般的に(append (butlast x n) (last x n))は、xと等しいリストをリターンする。

Function: nbutlast x &optional n

この関数はリストのコピーを作成するのではなく、cdrを適切な要素に変更することにより破壊的に機能するバージョンのbutlastである。


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

5.4 コンスセルおよびリストの構築

リストはLispの中核にあたる機能なので、リストを構築するために多くの関数があります。consはリストを構築する基本的な関数です。しかしEmacsのソースコードでは、consよりlistのほうが多く使用されているのは興味深いことです。

Function: cons object1 object2

この関数は新しいリスト構造を構築するための、もっとも基本的な関数である。この関数はobject1CARobject2CDRとする新しいコンスセルを作成して、それから新しいコンスセルをリターンする。引数object1object2には任意のLispオブジェクトを指定できるが、ほとんどの場合object2はリストである。

(cons 1 '(2))
     ⇒ (1 2)
(cons 1 '())
     ⇒ (1)
(cons 1 2)
     ⇒ (1 . 2)

リストの先頭に1つの要素を追加するために、consがよく使用される。これをリストに要素をコンスすると言います。5たとえば:

(setq list (cons newelt list))

この例で使用されているlistという名前の変数と、以下で説明するlistという名前の関数は競合しないことに注意されたい。すべてのシンボルが、変数と関数の両方の役割を果たすことができる。

Function: list &rest objects

この関数はobjectsを要素とするリストを作成する。結果となるリストは常にnilで終端される。objectsを指定しないと空リストがリターンされる。

(list 1 2 3 4 5)
     ⇒ (1 2 3 4 5)
(list 1 2 '(3 4 5) 'foo)
     ⇒ (1 2 (3 4 5) foo)
(list)
     ⇒ nil
Function: make-list length object

この関数は各要素がobjectであるような、length個の要素からなるリストを作成する。make-listmake-string(文字列の作成を参照)を比較してみよ。

(make-list 3 'pigs)
     ⇒ (pigs pigs pigs)
(make-list 0 'pigs)
     ⇒ nil
(setq l (make-list 3 '(a b)))
     ⇒ ((a b) (a b) (a b))
(eq (car l) (cadr l))
     ⇒ t
Function: append &rest sequences

この関数はsequencesのすべての要素を含むリストをreturnします。sequencesにはリスト、ベクター、ブールベクター、文字列も指定できるが、通常は最後にリストを指定すること。最後の引数を除くすべての引数はコピーされるので、変更される引数はない(コピーを行なわずにリストを結合する方法についてはリストを再配置する関数nconcを参照のこと)。

より一般的にはappendにたいする最後の引数は任意のLispオブジェクトを指定できる。最後の引数のコピーや変換は行わない。最後の引数は新しいリストの最後のコンスセルのCDRとなる。最後の引数もリストならば、このリストの要素は実質的には結果リストの要素になる。最後の要素がリストでなければ、最後のCDRが(正リストで要求される)nilではないので結果はドットリストになる(リストとコンスセルを参照)。

以下はappendを使用した例です:

(setq trees '(pine oak))
     ⇒ (pine oak)
(setq more-trees (append '(maple birch) trees))
     ⇒ (maple birch pine oak)

trees
     ⇒ (pine oak)
more-trees
     ⇒ (maple birch pine oak)
(eq trees (cdr (cdr more-trees)))
     ⇒ t

appendがどのように機能するか、ボックスダイアグラムで確認できます。変数treesはリスト(pine oak)にセットされ、それから変数more-treesにリスト(maple birch pine oak)がセットされます。しかし変数treesは継続して元のリストを参照します:

more-trees                trees
|                           |
|     --- ---      --- ---   -> --- ---      --- ---
 --> |   |   |--> |   |   |--> |   |   |--> |   |   |--> nil
      --- ---      --- ---      --- ---      --- ---
       |            |            |            |
       |            |            |            |
        --> maple    -->birch     --> pine     --> oak

空のシーケンスはappendによりリターンされる値に寄与しません。この結果、最後の引数にnilを指定すると、それより前の引数のコピーを強制することになります。

trees
     ⇒ (pine oak)
(setq wood (append trees nil))
     ⇒ (pine oak)
wood
     ⇒ (pine oak)
(eq wood trees)
     ⇒ nil

関数copy-sequenceが導入される以前は,これがリストをコピーする通常の方法でした。シーケンス、配列、ベクターを参照してください。

以下はappendの引数としてベクターと文字列を使用する例です:

(append [a b] "cd" nil)
     ⇒ (a b 99 100)

apply (関数の呼び出しを参照)の助けを借りることにより、リストのリストの中のすべてのリストをappendできます。

(apply 'append '((a b c) nil (x y z) nil))
     ⇒ (a b c x y z)

sequencesが与えられなければnilがリターンされます:

(append)
     ⇒ nil

以下は最後の引数がリストでない場合の例です:

(append '(x y) 'z)
     ⇒ (x y . z)
(append '(x y) [z])
     ⇒ (x y . [z])

2番目の例は最後の引数はリストではないシーケンスの場合で、このシーケンスの要素は、結果リストの要素にはなりません。かわりに最後の引数がリストでないときと同様、シーケンスが最後のCDRになります。

Function: copy-tree tree &optional vecp

この関数はツリーtreeのコピーをリターンする。treeがコンスセルなら同じCARCDRをもつ新しいコンスセルを作成してから、同じ方法によってCARCDRを再帰的にコピーする。

treeがコンスセル以外の場合、通常はcopy-treeは単にtreeをリターンする。しかしvecpが非nilなら、この関数はベクターでもコピーします(そしてベクターの要素を再帰的に処理する)。

Function: flatten-tree tree

この関数はtreeを“平坦化”したコピー( treeをルートとするコンスセルのツリーのすべての非nilな終端nodeとleave)をリターンする。リターンされたリストのleaveの順序はtreeでの順序と同じ。

(flatten-tree '(1 (2 . 3) nil (4 5 (6)) 7))
    ⇒(1 2 3 4 5 6 7)
Function: ensure-list object

この関数はobjectをリストとしてリターンする。objectがすでにリストならそれをリターンし、それ以外ならobjectを含む1要素のリストをリターンする。

これは通常はリストのときもあればそうでないときもある変数を使用する場合に有用であり、たとえば以下のような記述ができる:

(dolist (elem (ensure-list foo))
  (princ elem))
Function: number-sequence from &optional to separation

この関数はfromからseparationずつインクリメントして、toの直前で終わる数字のリストをリターンする。separationには正か負の数を指定でき、デフォルトは1。tonil、または数値的にfromと等しければ、値は1要素のリスト(from)になる。separationが正でtofromより小さい、またはseparationが負でtofromより大きければ、これらの引数は空のシーケンスを指示することになるので、値はnilになる。

separationが0で、tonilでもなく、数値的にfromとも等しくなければ、これらの引数は無限シーケンスを指示することになるので、エラーがシグナルされる。

引数はすべて数字である。浮動小数点数の計算は正確ではないので、浮動小数点数の引数には注意する必要がある。たとえばマシンへの依存により、(number-sequence 0.4 0.8 0.2)が3要素のリストをリターンして、(number-sequence 0.4 0.6 0.2)が1要素のリスト(0.4)をリターンすることがよく起こる。リストのn番目の要素は、厳密に(+ from (* n separation))という式により計算される。リストに確実にtoが含まれるようにするために、この式に適切な型のtoを渡すことができる。別の方法としてtoを少しだけ大きな値(separationが負なら少しだけ小さな値)に置き換えることもできる。

例をいくつか示す:

(number-sequence 4 9)
     ⇒ (4 5 6 7 8 9)
(number-sequence 9 4 -1)
     ⇒ (9 8 7 6 5 4)
(number-sequence 9 4 -2)
     ⇒ (9 7 5)
(number-sequence 8)
     ⇒ (8)
(number-sequence 8 5)
     ⇒ nil
(number-sequence 5 8 -1)
     ⇒ nil
(number-sequence 1.5 6 2)
     ⇒ (1.5 3.5 5.5)

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

5.5 リスト変数の変更

以下の関数と1つのマクロは、変数に格納されたリストを変更する便利な方法を提供します。

Macro: push element listname

このマクロはCARelementで、CDRlistnameのリストであるような新しいリストを作成して、そのリストをlistnameに保存する。listnameがリストに名前をつけるクォートされていないシンボルのときは単純で、この場合マクロは(setq listname (cons element listname))と等価になる。

(setq l '(a b))
     ⇒ (a b)
(push 'c l)
     ⇒ (c a b)
l
     ⇒ (c a b)

より一般的なのはlistnameが汎変数の場合である。この場合、このマクロは(setf listname (cons element listname))と等価になる。ジェネリック変数を参照のこと。

リストから1番目の要素を取り出すpopマクロについては、リスト要素へのアクセスを参照されたい。

以下の2つの関数は、変数の値であるリストを変更します。

Function: add-to-list symbol element &optional append compare-fn

この関数はelementsymbolの値のメンバーでなければ、symbolelementをコンスすることにより、変数symbolをセットする。この関数はリストが更新されているか否かに関わらず、結果のリストをリターンする。symbolの値は呼び出し前にすでにリストであることが望ましい。elementがリストの既存メンバーか比較するために、add-to-listcompare-fnを使用する。compare-fnnilならequalを使用する。

elementが追加される場合は、通常はsymbolの前に追加されるが、オプションの引数appendが非nilなら最後に追加される。

引数symbolは暗黙にクォートされない。setqとは異なりadd-to-listsetのような通常の関数である。クォートしたい場合には自分で引数をクォートすること。

symbolがレキシカル変数を参照する際にはこの関数を使用しないこと。

以下にadd-to-listを使用する方法をシナリオで示します:

(setq foo '(a b))
     ⇒ (a b)

(add-to-list 'foo 'c)     ;; cを追加
     ⇒ (c a b)

(add-to-list 'foo 'b)     ;; 効果なし
     ⇒ (c a b)

foo                       ;; fooが変更された
     ⇒ (c a b)

以下は(add-to-list 'var value)と等価な式です:

(if (member value var)
    var
  (setq var (cons value var)))
Function: add-to-ordered-list symbol element &optional order

この関数は古い値のorder (リストであること)で指定された位置に、elementを挿入して変数symbolをセットする。elementがすでにこのリストのメンバなら、リスト内の要素の位置はorderにしたがって調整される。メンバーか否かはeqを使用してテストされる。この関数は更新されているかどうかに関わらず、結果のリストをリターンする。

orderは通常は数字(整数か浮動小数点数)で、リストの要素はその数字の昇順で並べられる。

orderは省略またはnilを指定できる。これによりリストにelementがすでに存在するなら、elementの数字順序は変更されない。それ以外ならelementは数字順序をもたない。リストの数字順序をもたない要素はリストの最後に配置され、特別な順序はつかない。

orderに他の値を指定すると、elementがすでに数字順序をもつときは数字順序が削除される。それ以外はならnilと同じ。

引数symbolは暗黙にクォートされない。add-to-ordered-listsetqなどとは異なり、setのような通常の関数である。必要なら引数を自分でクォートすること。

順序の情報はsymbollist-orderプロパティにハッシュテーブルで保存される。symbolはレキシカル変数を参照できない。

以下にadd-to-ordered-listを使用する方法をシナリオで示します:

(setq foo '())
     ⇒ nil

(add-to-ordered-list 'foo 'a 1)     ;; aを追加
     ⇒ (a)

(add-to-ordered-list 'foo 'c 3)     ;; cを追加
     ⇒ (a c)

(add-to-ordered-list 'foo 'b 2)     ;; bを追加
     ⇒ (a b c)

(add-to-ordered-list 'foo 'b 4)     ;; bを移動
     ⇒ (a c b)

(add-to-ordered-list 'foo 'd)       ;; dを後に追加
     ⇒ (a c b d)

(add-to-ordered-list 'foo 'e)       ;; eを追加
     ⇒ (a c b e d)

foo                       ;; fooが変更された
     ⇒ (a c b e d)

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

5.6 既存のリスト構造の変更

プリミティブsetcarsetcdrでコンスセルのCARおよびCDRのコンテンツを変更できます。これらは既存のリスト構造を変更するので破壊的な操作です。破壊的操作はmutable(変更可能)なリスト、すなわちconslist、または類似の操作により構築される必要があります。クォートにより作成されたリストはプログラムの一部であり、破壊的な操作により変更するべきではありません。可変性を参照してください。

Common Lispに関する注意: Common Lispはリスト構造の変更にrplacarplacdを使用する。これらはsetcarsetcdrと同じ方法でリスト構造を変更するが、setcarsetcdrは新しいCARCDRをリターンするのにたいして、Common Lispの関数はコンスセルをリターンする。


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

5.6.1 setcarによるリスト要素の変更

コンスセルのCARの変更はsetcarで行ないます。リストにたいして使用するとsetcarはリストの1つの要素を別の要素に置き換えます。

Function: setcar cons object

この関数は以前のCARを置き換えて、consの新しいCARobjectを格納する。言い換えると、この関数はconsCARスロットをobjectを参照するように変更する。この関数は値objectをリターンする。たとえば:

(setq x (list 1 2))
     ⇒ (1 2)
(setcar x 4)
     ⇒ 4
x
     ⇒ (4 2)

コンスセルが複数のリストを共有する構造の一部なら、コンスに新しいCARを格納することにより、これら共有されたリストの各1つの要素を変更します。以下は例です:

;; 部分的に共有された2つのリストを作成
(setq x1 (list 'a 'b 'c))
     ⇒ (a b c)
(setq x2 (cons 'z (cdr x1)))
     ⇒ (z b c)

;; 共有されたリンクのCARを置き換え
(setcar (cdr x1) 'foo)
     ⇒ foo
x1                           ; 両方のリストが変更された
     ⇒ (a foo c)
x2
     ⇒ (z foo c)

;; 共有されていないリンクのCARを置き換え
(setcar x1 'baz)
     ⇒ baz
x1                           ; 1つのリストだけが変更された
     ⇒ (baz foo c)
x2
     ⇒ (z foo c)

なぜbを置き換えると両方が変更されるのかを説明するために、変数x1x2の2つのリストによる共有構造を視覚化してみましょう:

        --- ---        --- ---      --- ---
x1---> |   |   |----> |   |   |--> |   |   |--> nil
        --- ---        --- ---      --- ---
         |        -->   |            |
         |       |      |            |
          --> a  |       --> b        --> c
                 |
       --- ---   |
x2--> |   |   |--
       --- ---
        |
        |
         --> z

同じ関係を別のボックス図で示すと、以下のようになります:

x1:
 --------------       --------------       --------------
| car   | cdr  |     | car   | cdr  |     | car   | cdr  |
|   a   |   o------->|   b   |   o------->|   c   |  nil |
|       |      |  -->|       |      |     |       |      |
 --------------  |    --------------       --------------
                 |
x2:              |
 --------------  |
| car   | cdr  | |
|   z   |   o----
|       |      |
 --------------

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

5.6.2 リストのCDRの変更

CDRを変更するもっとも低レベルのプリミティブ関数はsetcdrです:

Function: setcdr cons object

この関数は前のCDRを置き換えて、consの新しいCDRobjectを格納する。言い換えると、この関数はconsCDRobjectを参照するように変更する。この関数は値objectをリターンする。

以下はリストのCDRを、他のリストに置き換える例です。1番目の要素以外のすべての要素は、別のシーケンスまたは要素のために取り除かれます。1番目の要素はリストのCARなので変更されず、CDRを通じて到達することもできないからです。

(setq x (list 1 2 3))
     ⇒ (1 2 3)
(setcdr x '(4))
     ⇒ (4)
x
     ⇒ (1 4)

リスト内のコンスセルのCDRを変更することにより、リストの途中から要素を削除できます。たとえば以下では、1番目のコンスセルのCDRを変更することにより、2番目の要素bをリスト(a b c)から削除します。

(setq x1 (list 'a 'b 'c))
     ⇒ (a b c)
(setcdr x1 (cdr (cdr x1)))
     ⇒ (c)
x1
     ⇒ (a c)

以下に結果をボックス表記で示します:

                   --------------------
                  |                    |
 --------------   |   --------------   |    --------------
| car   | cdr  |  |  | car   | cdr  |   -->| car   | cdr  |
|   a   |   o-----   |   b   |   o-------->|   c   |  nil |
|       |      |     |       |      |      |       |      |
 --------------       --------------        --------------

以前は要素bを保持していた2番目のコンスセルは依然として存在し、そのCARbのままですが、すでにこのリストの一部を形成していません。

CDRを変更して新しい要素を挿入するのも同じくらい簡単です:

(setq x1 (list 'a 'b 'c))
     ⇒ (a b c)
(setcdr x1 (cons 'd (cdr x1)))
     ⇒ (d b c)
x1
     ⇒ (a d b c)

以下に結果をボックス表記で示します:

 --------------        -------------       -------------
| car  | cdr   |      | car  | cdr  |     | car  | cdr  |
|   a  |   o   |   -->|   b  |   o------->|   c  |  nil |
|      |   |   |  |   |      |      |     |      |      |
 --------- | --   |    -------------       -------------
           |      |
     -----         --------
    |                      |
    |    ---------------   |
    |   | car   | cdr   |  |
     -->|   d   |   o------
        |       |       |
         ---------------

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

5.6.3 リストを再配置する関数

以下ではリストの構成要素であるコンスセルのCDRを変更することにより、リストを破壊的に再配置する関数をいくつか示します。これらの関数が破壊的だという理由は、これらの関数が引数として渡された元のリストを処理してリターン値となる新しいリストを形成するために、リストのコンスセルを再リンクするからです。

コンスセルを変更する他の関数については、集合としてのリストの使用delqを参照してください。

Function: nconc &rest lists

この関数はlistsの要素すべてを含むリストをリターンする。append (コンスセルおよびリストの構築を参照)とは異なり、listsコピーされない。かわりにlistsの各リストの最後のCDRが次のリストを参照するように変更される。listsの最後のリストは変更されない。たとえば:

(setq x (list 1 2 3))
     ⇒ (1 2 3)
(nconc x '(4 5))
     ⇒ (1 2 3 4 5)
x
     ⇒ (1 2 3 4 5)

nconcの最後の引数は変更されないので、上記の例のように'(4 5)のような定数リストを使用するのが合理的である。また同じ理由により最後の引数がリストである必要はない。

(setq x (list 1 2 3))
     ⇒ (1 2 3)
(nconc x 'z)
     ⇒ (1 2 3 . z)
x
     ⇒ (1 2 3 . z)

しかし他の(最後を除くすべての)引数はmutableリストでなければなければならない。

一般的な落とし穴としては、nconcにたいしてリスト定数を最後以外の引数として使用した場合である。これを行なった場合の結果としての挙動は未定義である(自己評価を行うフォームを参照)。実行するごとにプログラムはリスト定数を変更する可能性がある! (必ず発生する保証はないが)以下のようなことが起こり得る:

(defun add-foo (x)            ; この関数ではfoo
  (nconc '(foo) x))           ;   を引数の前に追加したい

(symbol-function 'add-foo)
     ⇒ (lambda (x) (nconc '(foo) x))

(setq xx (add-foo '(1 2)))    ; 動いているように見える
     ⇒ (foo 1 2)
(setq xy (add-foo '(3 4)))    ; 何が起きているのか?
     ⇒ (foo 1 2 3 4)
(eq xx xy)
     ⇒ t

(symbol-function 'add-foo)
     ⇒ (lambda (x) (nconc '(foo 1 2 3 4) x))

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

5.7 集合としてのリストの使用

リストは順序なしの数学的集合 — リスト内に要素があれば集合の要素の値としてリスト内の順序は無視される — を表すことができます。2つの集合を結合(union)するには、(重複する要素を気にしなければ)appendを使用します。equalである重複を取り除くにはdelete-dupsseq-uniqを使用します。集合にたいする他の有用な関数にはmemqdelqや、それらのequalバージョンであるmemberdeleteが含まれます。

Common Lispに関する注意: 集合を処理するためにCommon Lispには関数union (要素の重複がない)とintersectionがある。Emacs Lispではcl-libがこれらの変種を提供する。Lists as Sets in Common Lisp Extensionsを参照のこと。

Function: memq object list

この関数はobjectlistのメンバーかどうかをテストする。メンバーならmemqは、objectで最初に見つかった要素から開始されるリストをリターンする。メンバーでなければnilをリターンする。memqの文字‘q’は、この関数がobjectとリスト内の要素の比較にeqを使用することを示す。たとえば:

(memq 'b '(a b c b a))
     ⇒ (b c b a)
(memq '(2) '((1) (2)))    ; 2つの(2)eqである必要はない未定義; nil((2))かも
Function: delq object list

この関数はlistからobjecteqであるような、すべての要素を破壊的に取り除いて結果のリストをリターンする。delqの文字‘q’は、この関数がobjectとリスト内の要素の比較にeqを使用することを示す(memqremqと同様)。

delqを呼び出すときは、通常は元のリストを保持していた変数にリターン値を割り当てて使用する必要がある(理由は以下参照)。

delq関数がリストの先頭にある要素を削除する場合は、単にリストを読み進めてこの要素の後から開始される部分リストをリターンします。つまり:

(delq 'a '(a b c)) ≡ (cdr '(a b c))

リストの途中にある要素を削除するときは、必要なCDR (リストのCDRの変更を参照)を変更することで削除を行います。

(setq sample-list (list 'a 'b 'c '(4)))
     ⇒ (a b c (4))
(delq 'a sample-list)
     ⇒ (b c (4))
sample-list
     ⇒ (a b c (4))
(delq 'c sample-list)
     ⇒ (a b (4))
sample-list
     ⇒ (a b (4))

(delq 'a sample-list)は何も取り除きませんが(単に短いリストをリターンする)、(delq 'c sample-list)は3番目の要素を取り除いてsample-listを変更することに注意してください。引数listを保持するように形成された変数が、実行後にもっと少ない要素になるとか、元のリストを保持すると仮定しないでください! かわりにdelqの結果を保存して、それを使用してください。元のリストを保持していた変数に結果を書き戻すことはよく行なわれます。

(setq flowers (delq 'rose flowers))

以下の例では、delqが比較しようとしている(list 4)sample-list内の(4)は、equalですがeqではありません:

(delq (list 4) sample-list)
     ⇒ (a c (4))

与えられた値とequalな要素を削除したい場合には、delete (以下参照)を使用してください。

Function: remq object list

この関数はobjecteqなすべての要素が除かれた、listのコピーをリターンする。remqの文字‘q’は、この関数がobjectとリスト内の要素の比較にeqを使用することを示す。

(setq sample-list (list 'a 'b 'c 'a 'b 'c))
     ⇒ (a b c a b c)
(remq 'a sample-list)
     ⇒ (b c b c)
sample-list
     ⇒ (a b c a b c)
Function: memql object list

関数memqleql(浮動小数点数の要素は値で比較される)を使用してメンバーとeqlを比較することにより、objectlistのメンバーかどうかをテストする。objectがメンバーなら、memqllist内で最初に見つかった要素から始まるリスト、それ以外ならnilをリターンする。

memqと比較してみよう:

(memql 1.2 '(1.1 1.2 1.3))  ; 1.21.2eql
     ⇒ (1.2 1.3)
(memq 1.2 '(1.1 1.2 1.3))  ; 2つの1.2eqである必要はない未定義; nil(1.2 1.3)かもしれない

以下の3つの関数はmemqdelqremqと似ていますが、要素の比較にeqではなくequalを使用します。同等性のための述語を参照してください。

Function: member object list

関数memberは、メンバーとobjectequalを使用して比較して、objectlistのメンバーかどうかをテストする。objectがメンバーなら、memberlistで最初に見つかったところから開始されるリスト、それ以外ならnilをリターンする。

memqと比較してみよう:

(member '(2) '((1) (2)))  ; (2) and (2) are equal.
     ⇒ ((2))
(memq '(2) '((1) (2)))    ; 2つの(2)eqである必要はない未定義; nil(2)かもしれない
;; 同じ内容の2つの文字列はequal
(member "foo" '("foo" "bar"))
     ⇒ ("foo" "bar")
Function: delete object sequence

この関数はsequenceからobjectequalな要素を取り除いて、結果のシーケンスをリターンする。

sequenceがリストなら、deletedelqに対応するように、membermemqに対応する。つまりこの関数はmemberと同様、要素とobjectの比較にequalを使用する。マッチする要素が見つかったら、delqが行なうようにその要素を取り除く。delqと同様、通常は元のリストを保持していた変数にリターン値を割り当てて使用する。

sequenceがベクターか文字列なら、deleteobjectequalなすべての要素を取り除いたsequenceのコピーをリターンする。

たとえば:

(setq l (list '(2) '(1) '(2)))
(delete '(2) l)
     ⇒ ((1))
l
     ⇒ ((2) (1))
;; lの変更に信頼性を要するときは
;; (setq l (delete '(2) l))と記述する。
(setq l (list '(2) '(1) '(2)))
(delete '(1) l)
     ⇒ ((2) (2))
l
     ⇒ ((2) (2))
;; このケースではlのセットの有無に違い
;; はないが他のケースに倣ってセットするべき
(delete '(2) [(2) (1) (2)])
     ⇒ [(1)]
Function: remove object sequence

この関数はdeleteに対応する非破壊的な関数である。この関数はobjectequalな要素を取り除いた、sequence(リスト、ベクター、文字列)のコピーをリターンする。たとえば:

(remove '(2) '((2) (1) (2)))
     ⇒ ((1))
(remove '(2) [(2) (1) (2)])
     ⇒ [(1)]

Common Lispに関する注意: GNU Emacs Lispの関数memberdeleteremoveはCommon Lispではなく、Maclispを継承する。Common Lispでは比較にequalを使用しない。

Function: member-ignore-case object list

この関数はmemberと同様だが、objectが文字列でcaseとテキスト表現の違いを無視する。文字の大文字と小文字は等しいものとして扱われ、比較に先立ちユニバイト文字列はマルチバイト文字列に変換される。

Function: delete-dups list

この関数はlistからすべてのequalな重複を破壊的に取り除いて、結果をlistに保管してそれをリターンする。list内の要素にequalな要素がいくつかあるなら、delete-dupsは最初の要素を残す。非破壊的な操作についてはseq-uniqを参照してください(シーケンスを参照)。

変数に格納されたリストへの要素の追加や、それを集合として使用する方法については、リスト変数の変更の関数add-to-listも参照してください。


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

5.8 連想リスト

連想リスト(association list、短くはalist)は、キーと値のマッピングを記録します。これは連想(associations)と呼ばれるコンスセルのリストです。各コンスセルにおいてCARキー(key)で、CDR連想値(associated value)となります。6

以下はalistの例です。キーpineは値cones、キーoakacorns、キーmapleseedsに関連付けられます。

((pine . cones)
 (oak . acorns)
 (maple . seeds))

alist内の値とキーには、任意のLispオブジェクトを指定できます。たとえば以下のalistでは、シンボルaは数字1、文字列"b"リスト(2 3)(alist要素のCDR)に関連付けられます。

((a . 1) ("b" 2 3))

要素のCDRCARに連想値を格納するようにalistデザインするほうがよい場合があります。以下はそのようなalistです。

((rose red) (lily white) (buttercup yellow))

この例では、redroseに関連付けられる値だと考えます。この種のalistの利点は、CDRCDRの中に他の関連する情報 — 他のアイテムのリストでさえも — を格納することができることです。不利な点は、与えられた値を含む要素を見つけるためにrassq(以下参照)を使用できないことです。これらを検討することが重要でない場合には、すべての与えられたalistにたいして一貫している限り、選択は好みの問題といえます。

上記で示したのと同じalistは、要素のCDRに連想値をもつと考えることができます。この場合、roseに関連付けられる値はリスト(red)になるでしょう。

連想リストは新しい連想値を簡単にリストの先頭に追加できるので、スタックに保持したいような情報を記録するのによく使用されます。連想リストから与えられたキーにたいして連想値を検索する場合、それが複数ある場合は、最初に見つかったものがreturnされます。

Emacs Lispでは、連想リストがコンスセルでなくても、それはエラーではありません。alist検索関数は、単にそのような要素を無視します。多くの他のバージョンのLispでは、このような場合はエラーをシグナルします。

いくつかの観点において、プロパティリストは連想リストと似ていることに注意してください。それぞれのキーが一度だけ出現するような場合、プロパティリストは連想リストと同様に振る舞います。プロパティリストと連想リストの比較については、プロパティリストを参照してください。

Function: assoc key alist &optional testfn

この関数はalist要素にたいしてtestfnが関数ならtestfn、それ以外ならequalを使用して、alist内からkeyをもつ最初の連想をリターンする。testfnが関数の場合にはalistの要素のCARkeyの2つの引数で呼び出される。testfnでテストした結果、CARkeyと一致する連想がalistになければ、この関数はnilをリターンする。たとえば:

(setq trees '((pine . cones) (oak . acorns) (maple . seeds)))
     ⇒ ((pine . cones) (oak . acorns) (maple . seeds))
(assoc 'oak trees)
     ⇒ (oak . acorns)
(cdr (assoc 'oak trees))
     ⇒ acorns
(assoc 'birch trees)
     ⇒ nil

以下はキーと値がシンボルでない場合の例である:

(setq needles-per-cluster
      '((2 "Austrian Pine" "Red Pine")
        (3 "Pitch Pine")
        (5 "White Pine")))

(cdr (assoc 3 needles-per-cluster))
     ⇒ ("Pitch Pine")
(cdr (assoc 2 needles-per-cluster))
     ⇒ ("Austrian Pine" "Red Pine")

関数assoc-stringassocと似ていますが、文字列間の特定の違いを無視する点が異なります。文字および文字列の比較を参照してください。

Function: rassoc value alist

この関数はalistの中から値valueをもつ最初の連想をリターンする。CDRvalueequalであるような連想値がalistになければ、この関数はnilをリターンする。

rassocassocと似てイルが、CARではなくalistの連想値のCDRを比較する。この関数は与えられた値に対応するキーを探す、assocの逆バージョンと考えることができよう。

Function: assq key alist

この関数はalistからkeyをもつ最初の連想値をリターンする点はassocと同様だが、比較にeqを使用する点が異なる。CARkeyeqであるような連想値がalist内に存在しなければassqnilをリターンする。eqequalより高速であり、ほとんどのalistはキーにシンボルを使用するので、この関数はassocより多用される。同等性のための述語を参照のこと。

(setq trees '((pine . cones) (oak . acorns) (maple . seeds)))
     ⇒ ((pine . cones) (oak . acorns) (maple . seeds))
(assq 'pine trees)
     ⇒ (pine . cones)

逆にキーがシンボルではないalistでは、通常はassqは有用ではない:

(setq leaves
      '(("simple leaves" . oak)
        ("compound leaves" . horsechestnut)))

(assq "simple leaves" leaves)
     ⇒ 未定義; nil("simple leaves" . oak)かもしれない
(assoc "simple leaves" leaves)
     ⇒ ("simple leaves" . oak)
Function: alist-get key alist &optional default remove testfn

この関数はassqと似ている。これはalistの要素のkeyを比較して最初の連想(key . value)を見つける。連想が見つからなければ、関数はdefaultをリターンする。alistにたいするkeyの比較にはtestfnで指定された関数を使用する(デフォルトはeq)。

これはsetfでの値の変更に使用できる汎変数(ジェネリック変数を参照)である。値の設定にこれを使用する際にオプション引数removenilの場合は、新たな値がdefaulteqlならalistからkeyの連想を削除することを意味する。

Function: rassq value alist

この関数は、alist内から値valueをもつ最初の連想値をリターンする。alist内にCDRvalueeqであるような連想値が存在しないならnilをリターンする。

rassqassqと似ていますが、CARではなくalistの各連想のCDRを比較します。この関数を、与えられた値に対応するキーを探すassqの逆バージョンと考えることができます。

たとえば:

(setq trees '((pine . cones) (oak . acorns) (maple . seeds)))

(rassq 'acorns trees)
     ⇒ (oak . acorns)
(rassq 'spores trees)
     ⇒ nil

rassqは要素のCDRCARに保管された値の検索はできません:

(setq colors '((rose red) (lily white) (buttercup yellow)))

(rassq 'white colors)
     ⇒ nil

この場合、連想(lily white)CDRwhiteではなくリスト(white)です。これは連想をドットペア表記で記述すると明確になります:

(lily white) ≡ (lily . (white))
Function: assoc-default key alist &optional test default

この関数は、keyにたいするマッチをalistから検索する。alistの各要素にたいして、この関数はkeyと要素(アトムの場合)、または要素のCAR(コンスの場合)を比較する。比較はtestに2つの引数 — 要素(か要素のCAR)とkey — を与えて呼び出すことにより行なわれる。引数はこの順番で渡されるので、正規表現(正規表現の検索を参照)を含むalistでは、string-matchを使用することにより有益な結果を得ることができる。testが省略またはnilなら比較にequalが使用される。

alistの要素がこの条件によりkeyとマッチすると、assoc-defaultはその要素の値をリターンする。要素がコンスなら値は要素のCDR、それ以外ならリターン値はdefaultとなる。

keyにマッチする要素がalistに存在しないなら、assoc-defaultnilをリターンする。

Function: copy-alist alist

この関数は深さのレベルが2のalistのコピーをリターンする。この関数は各連想の新しいコピーを作成するので、元のalistを変更せずに新しいalistを変更できる。

(setq needles-per-cluster
      '((2 . ("Austrian Pine" "Red Pine"))
        (3 . ("Pitch Pine"))
        (5 . ("White Pine"))))
⇒
((2 "Austrian Pine" "Red Pine")
 (3 "Pitch Pine")
 (5 "White Pine"))

(setq copy (copy-alist needles-per-cluster))
⇒
((2 "Austrian Pine" "Red Pine")
 (3 "Pitch Pine")
 (5 "White Pine"))

(eq needles-per-cluster copy)
     ⇒ nil
(equal needles-per-cluster copy)
     ⇒ t
(eq (car needles-per-cluster) (car copy))
     ⇒ nil
(cdr (car (cdr needles-per-cluster)))
     ⇒ ("Pitch Pine")
(eq (cdr (car (cdr needles-per-cluster)))
    (cdr (car (cdr copy))))
     ⇒ t

以下の例は、copy-alistを使用して、他方のコピーへの影響なしに一方のコピーの連想を変更することが可能である方法を示す:

(setcdr (assq 3 copy) '("Martian Vacuum Pine"))
(cdr (assq 3 needles-per-cluster))
     ⇒ ("Pitch Pine")
Function: assq-delete-all key alist

この関数は、delqを使用してマッチする要素を1つずつ削除するときのように、CARkeyeqであるようなすべての要素をalistから削除する。この関数は短くなったalistをリターンし、alistの元のリスト構造を変更することもよくある。正しい結果を得るために、alistに保存された値ではなくassq-delete-allのリターン値を使用すること。

(setq alist (list '(foo 1) '(bar 2) '(foo 3) '(lose 4)))
     ⇒ ((foo 1) (bar 2) (foo 3) (lose 4))
(assq-delete-all 'foo alist)
     ⇒ ((bar 2) (lose 4))
alist
     ⇒ ((foo 1) (bar 2) (lose 4))
Function: assoc-delete-all key alist &optional test

この関数はassq-delete-allと同様だが、オプション引数test ( alist内のキーを比較するための述語関数)を受け取る点が異なる。testが省略かnilならデフォルトはequal。この関数はassq-delete-allのように、多くの場合はalistの元のリスト構造を変更する。

Function: rassq-delete-all value alist

この関数は、alistからCDRvalueeqであるようなすべての要素を削除する。この関数は短くなったリストをリターンし、alistの元のリスト構造を変更することもよくある。rassq-delete-allassq-delete-allと似ているが、CARではなくalistの各連想のCDRを比較する。

Macro: let-alist alist body

連想リストalistのキーとして使用される先頭にドットを付したシンボルそれぞれにたいしてバインディングを作成する。これは同じ連想リスト内の複数のアイテムにアクセスする際に有用かもしれない。理解するためにもっともよいのは以下のシンプルな例だろう:

(setq colors '((rose . red) (lily . white) (buttercup . yellow)))
(let-alist colors
  (if (eq .rose 'red)
      .lily))
     ⇒ white

bodyをコンパイル時に検査して、body内に出現する先頭文字として‘.’を付したシンボルだけがバインドされる。キーの検索はassq、このassqのリターン値のcdrがそのバインディングにたいする値として割り当てられる。

ネストされた連想リストをサポートする:

(setq colors '((rose . red) (lily (belladonna . yellow) (brindisi . pink))))
(let-alist colors
  (if (eq .rose 'red)
      .lily.belladonna))
     ⇒ yellow

互いに内部にlet-alistをネストすることが可能だが、内側のlet-alistは外側のlet-alistがバインドする変数にはアクセスできない。


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

5.9 プロパティリスト

プロパティリスト(property list、短くはplist)は、ペアになった要素のリストです。各ペアはプロパティ名(通常はシンボル)とプロパティ値を対応づけます。以下はプロパティリストの例です:

(pine cones numbers (1 2 3) color "blue")

このプロパティリストはpineconesnumbers(1 2 3)color"blue"に関連づけます。プロパティ名とプロパティ値には任意のLispオブジェクトを指定できますが、通常プロパティ名は(この例のように)シンボルです。

いくつかのコンテキストでプロパティリストが使用されます。たとえば関数put-text-propertyはプロパティリストを引数にとり、文字列やバッファー内のテキストにたいして、テキストプロパティとテキストに適用するプロパティ値を指定します。テキストのプロパティを参照してください。

プロパティリストが頻繁に使用される他の例は、シンボルプロパティの保管です。すべてのシンボルはシンボルに関する様々な情報を記録するために、プロパティのリストを処理します。これらのプロパティはプロパティリストの形式で保管されます。シンボルのプロパティを参照してください。

Function: plistp object

この述語関数はobjectが有効なプロパティリストなら非nilをリターンする。


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

5.9.1 プロパティリストと連想リスト

連想リスト(連想リストを参照)は、プロパティリストとよく似ています。連想リストとは対照的にプロパティ名は一意でなければならないので、プロパティリスト内でペアの順序に意味はありません。

様々なLisp関数や変数に情報を付加するためには、連想リストよりプロパティリストの方が適しています。プログラムでこのような情報すべてを1つの連想リストに保持する場合は、特定のLisp関数や変数にたいする連想をチェックする度にリスト全体を検索する必要が生じ、それにより遅くなる可能性があります。対照的に関数名や変数自体のプロパティリストに同じ情報を保持すれば、検索ごとにそのプロパティリストの長さだけを検索するようになり、通常はこちらの方が短時間で済みます。変数のドキュメントがvariable-documentationという名前のプロパティに記録されているのはこれが理由です。同様にバイトコンパイラーも、特別に扱う必要がある関数を記録するためにプロパティを使用します。

とはいえ連想リストにも独自の利点があります。アプリケーションに依存しますが、プロパティを更新するより連想リストの先頭に連想を追加する方が高速でしょう。シンボルにたいするすべてのプロパティは同じプロパティリストに保管されるので、プロパティ名を異なる用途のために使用すると衝突の可能性があります(この理由により、そのプログラムで通常の変数や関数の名前につけるプレフィクスをプロパティ名の先頭につけて、一意と思われるプロパティ名を選ぶのはよいアイデアだと言える)。連想リストは、連想をリストの先頭にpushして、その後にある連想は無視されるので、スタックと同様に使用できます。これはプロパティリストでは不可能です。


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

5.9.2 プロパティリストと外部シンボル

以下の関数はプロパティリストを操作するために使用されます。これらの関数はすべて、デフォルトではプロパティ名の比較にeqを使用します。

Function: plist-get plist property &optional predicate

この関数はプロパティリストplistに保管された、プロパティpropertyの値をリターンする。比較はpredicate (デフォルトはeq)で行われる。この関数には不正な形式(malformed)のplist引数を指定できる。plistpropertyが見つからないと、この関数はnilをリターンする。たとえば、

(plist-get '(foo 4) 'foo)
     ⇒ 4
(plist-get '(foo 4 bad) 'foo)
     ⇒ 4
(plist-get '(foo 4 bad) 'bad)
     ⇒ nil
(plist-get '(foo 4 bad) 'bar)
     ⇒ nil
Function: plist-put plist property value &optional predicate

この関数はプロパティリストplistに、プロパティpropertyの値としてvalueを保管する。比較はpredicate (デフォルトはeq)で行われる。この関数はplistを破壊的に変更するかもしれず、元のリスト構造を変更せずに新しいリストを構築することもある。この関数は変更されたプロパティリストをリターンするので、plistを取得した場所に書き戻すことができる。たとえば、

(setq my-plist (list 'bar t 'foo 4))
     ⇒ (bar t foo 4)
(setq my-plist (plist-put my-plist 'foo 69))
     ⇒ (bar t foo 69)
(setq my-plist (plist-put my-plist 'quux '(a)))
     ⇒ (bar t foo 69 quux (a))
Function: lax-plist-get plist property

この廃れた関数はplist-getと同様だが、プロパティの比較にeqではなくequalを使用する。

Function: lax-plist-put plist property value

この廃れた関数はplist-putと同様だが、プロパティの比較にeqではなくequalを使用する。

Function: plist-member plist property &optional predicate

この関数は与えられたpropertyplistに含まれるなら非nilをリターンする。比較はpredicate (デフォルトはeq)で行われる。plist-getとは異なりこの関数は存在しないプロパティと、値がnilのプロパティを区別できる。実際にリターンされる値は、carpropertyで始まるplistの末尾部分である。


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

6 シーケンス、配列、ベクター

シーケンス(sequence)型は2つの異なるLisp型 — リストと配列 — を結合した型です。言い換えると任意のリストはシーケンスであり任意の配列はシーケンスです。すべてのシーケンスがもつ共通な属性は、それぞれが順序づけされた要素のコレクションであることです。

配列(array)はスロットがその要素であるような、固定長のオブジェクトです。すべての要素に一定時間でアクセスできます。配列の4つの型として文字列、ベクター、文字テーブル、ブールベクターがあります。

リストは要素のシーケンスですが、要素は単一の基本オブジェクトではありません。リストはコンスセルにより作られ、要素ごとに1つのセルをもちます。n番目の要素を探すにはn個のコンスセルを走査する必要があるので、先頭から離れた要素ほどアクセスに時間を要します。しかしリストは要素の追加や削除が可能です。

以下の図はこれらの型の関連を表しています:

          _____________________________________________
         |                                             |
         |          Sequence                           |
         |  ______   ________________________________  |
         | |      | |                                | |
         | | List | |             Array              | |
         | |      | |    ________       ________     | |
         | |______| |   |        |     |        |    | |
         |          |   | Vector |     | String |    | |
         |          |   |________|     |________|    | |
         |          |  ____________   _____________  | |
         |          | |            | |             | | |
         |          | | Char-table | | Bool-vector | | |
         |          | |____________| |_____________| | |
         |          |________________________________| |
         |_____________________________________________|

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

6.1 シーケンス

このセクションでは任意の種類のシーケンスを許す関数を説明します。

Function: sequencep object

この関数はobjectがリスト、ベクター、文字列、ブールベクター、文字テーブルならt、それ以外はnilをリターンする。以下のseqpも参照のこと。

Function: length sequence

この関数はsequence内の要素の数をリターンする。sequenceがシーケンス以外、またはドットリストならwrong-type-argumentエラーをシグナルする。引数が循環リストならcircular-listエラーをシグナルする。文字テーブルではEmacsの最大文字コードより1大きい値が常にリターンされる。

関連する関数safe-lengthについてはDefinition of safe-lengthを参照のこと。

(length '(1 2 3))
    ⇒ 3
(length ())
    ⇒ 0
(length "foobar")
    ⇒ 6
(length [1 2 3])
    ⇒ 3
(length (make-bool-vector 5 nil))
    ⇒ 5

テキストの表現方法string-bytesも参照されたい。

ディスプレイ上での文字列の幅を計算する必要があるなら、文字数だけを数えて各文字のディスプレイ幅を計算しないlengthではなく、string-width (表示されるテキストのサイズを参照)を使用すること。

Function: length< sequence length

sequencelengthより短ければ非nilをリターンする。これはsequenceが長いリストの場合にsequenceの長さを計算するより効率的かもしれない。

Function: length> sequence length

sequencelengthより長ければ非nilをリターンする。

Function: length= sequence length

sequenceの長さがlengthなら非nilをリターンする。

Function: elt sequence index

この関数はindexによりインデックスづけされた、sequenceの要素をリターンする。indexの値として妥当なのは、0からsequenceの長さより1小さい数までの範囲の整数。sequenceがリストなら範囲外の値はnthと同じように振る舞う。Definition of nthを参照のこと。それ以外なら範囲外の値はargs-out-of-rangeエラーを引き起こす。

(elt [1 2 3 4] 2)
     ⇒ 3
(elt '(1 2 3 4) 2)
     ⇒ 3
;; eltがどの文字をreturnするか明確にするためにstringを使用
(string (elt "1234" 2))
     ⇒ "3"
(elt [1 2 3 4] 4)
     error→ Args out of range: [1 2 3 4], 4
(elt [1 2 3 4] -1)
     error→ Args out of range: [1 2 3 4], -1

この関数はaref (配列を操作する関数を参照)とnth (Definition of nthを参照)を一般化したものである。

Function: copy-sequence seqr

この関数はseqr (シーケンスかレコードであること)のコピーをリターンする。コピーはオリジナルと同じオブジェクト型であり、同じ要素を同じ順序でもつ。しかしseqrが空なら長さが0の文字列やベクターと同じように関数がリターンする値はコピーではないかもしれないが、seqrと同じ型の空のオブジェクトである。

コピーに新しい要素を格納するのは元のseqrに影響を与えずその逆も真である。しかし新しいシーケンス内の要素はコピーではなく、元のシーケンスの要素と同一(eq)になる。したがってコピーされたシーケンスを介して見つかった要素を変更するとオリジナルでも変更を見ることができる。

引数がテキストプロパティをもつ文字列なら、コピー内のプロパティリスト自身もコピーとなり、元のシーケンスのプロパティリストと共有はされない。しかしプロパティリストの実際の値は共有される。テキストのプロパティを参照のこと。

この関数はドットリストでは機能しない。循環リストのコピーは無限ループを起こすだろう。

シーケンスをコピーする別の方法についてはコンスセルおよびリストの構築append文字列の作成concatベクターのための関数vconcatも参照されたい。

(setq bar (list 1 2))
     ⇒ (1 2)
(setq x (vector 'foo bar))
     ⇒ [foo (1 2)]
(setq y (copy-sequence x))
     ⇒ [foo (1 2)]

(eq x y)
     ⇒ nil
(equal x y)
     ⇒ t
(eq (elt x 1) (elt y 1))
     ⇒ t

;; 一方のシーケンスの要素を置き換え
(aset x 0 'quux)
x ⇒ [quux (1 2)]
y ⇒ [foo (1 2)]

;; 共有された要素の内部を変更
(setcar (aref x 1) 69)
x ⇒ [quux (69 2)]
y ⇒ [foo (69 2)]
Function: reverse sequence

この関数はsequenceの要素を反転した要素をもつ新たなシーケンスを作成する。元となる引数sequence変更されない。文字テーブルは反転できないことに注意。

(setq x '(1 2 3 4))
     ⇒ (1 2 3 4)
(reverse x)
     ⇒ (4 3 2 1)
x
     ⇒ (1 2 3 4)
(setq x [1 2 3 4])
     ⇒ [1 2 3 4]
(reverse x)
     ⇒ [4 3 2 1]
x
     ⇒ [1 2 3 4]
(setq x "xyzzy")
     ⇒ "xyzzy"
(reverse x)
     ⇒ "yzzyx"
x
     ⇒ "xyzzy"
Function: nreverse sequence

この関数はsequenceの要素を反転する。reverseとは異なり、元となるsequenceは変更されるかもしれない。

たとえば:

(setq x (list 'a 'b 'c))
     ⇒ (a b c)
x
     ⇒ (a b c)
(nreverse x)
     ⇒ (c b a)
;; 先頭にあったコンスセルが末尾となった
x
     ⇒ (a)

混乱しないように、通常は元となるリストを保持する同じ変数に、nreverseの結果を書き戻す:

(setq x (nreverse x))

お馴染の例(a b c)nreverseを以下に図示する:

Original list head:                       Reversed list:
 -------------        -------------        ------------
| car  | cdr  |      | car  | cdr  |      | car | cdr  |
|   a  |  nil |<--   |   b  |   o  |<--   |   c |   o  |
|      |      |   |  |      |   |  |   |  |     |   |  |
 -------------    |   --------- | -    |   -------- | -
                  |             |      |            |
                   -------------        ------------

setqが不要なのでベクターはより単純になる:

(setq x (copy-sequence [1 2 3 4]))
     ⇒ [1 2 3 4]
(nreverse x)
     ⇒ [4 3 2 1]
x
     ⇒ [4 3 2 1]

reverseとは異なり、この関数は文字列では機能しない。asetを使用して文字列データを変更できても、たとえmutableであったとしても文字列は不変として扱うことを強く推奨する。可変性を参照のこと。

Function: sort sequence predicate

この関数はsequenceを安定ソートする。この関数はすべてのシーケンスにたいしては機能せず、リストとベクターにたいしてのみ使用できることに注意されたい。sequenceがリストなら破壊的に変更される。この関数はソートされたsequenceをリターンして、要素の比較にはpredicateを使用する。安定ソートでは、ソートキーが等しい要素の相対順序がソートの前後で保たれる。この安定性は異なる条件により要素を並べ替えるために、連続してソートを行う場合に重要となる。

引数predicateは2つの引数を受け取る関数でなければならない。これはsequenceの2つの要素で呼び出される。昇順でソートするなら、1つ目の要素が2つ目の要素より“小”なら非nil、それ以外ならnilをリターンすること。

比較関数predicateは、少なくともsortの単一の呼び出しにおいて、与えられた任意の引数ペアにたいして信頼できる結果をリターンしなければならない。これは非対照的(antisymmetric)、すなわちabより小なら、baより小であってはならず、推移律(transitive)、すなわちabより小、かつbcより小なら、acより小でなければならない。これらの要件に合致しない比較関数を使用すると、sortの結果は予想できない。

sortのリストにたいする破壊的側面は、コンスセルによって形成されたsequenceの内容を、もしかしたら違う順序に再配置するような変更を施すことによって再利用することである。これは入力リストのソート後の値が未定義であることを意味する。定義された有効な値は、sortによってリターンされるリストだけである。

(setq nums (list 2 1 4 3 0))
(sort nums #'<)
     ⇒ (0 1 2 3 4)
     ; この時点においてnumsは予測不可能

元のリストを保持していた変数に結果を書き戻す場合がほとんどだろう:

(setq nums (sort nums #'<))

元の値話破壊せずにソート済みのコピーが欲しければ、まずコピーしてからソートすること:

(setq nums (list 2 1 4 3 0))
(sort (copy-sequence nums) #'<)
     ⇒ (0 1 2 3 4)
nums
     ⇒ (2 1 4 3 0)

安定ソートの何たるかをより理解するには、以下のベクターのサンプルを考えてみよ。ソート後、carが8であるようなすべてのアイテムはvectorの先頭にグループ化されるが、それらの相対的な順序は保たれる。carが9であるようなすべてのアイテムはvectorの末尾にグループ化されるが、それらの相対的な順序も保たれる。

(setq
  vector
  (vector '(8 . "xxx") '(9 . "aaa") '(8 . "bbb") '(9 . "zzz")
          '(9 . "ppp") '(8 . "ttt") '(8 . "eee") '(9 . "fff")))
     ⇒ [(8 . "xxx") (9 . "aaa") (8 . "bbb") (9 . "zzz")
         (9 . "ppp") (8 . "ttt") (8 . "eee") (9 . "fff")]
(sort vector (lambda (x y) (< (car x) (car y))))
     ⇒ [(8 . "xxx") (8 . "bbb") (8 . "ttt") (8 . "eee")
         (9 . "aaa") (9 . "zzz") (9 . "ppp") (9 . "fff")]

ソートを行う他の関数についてはテキストのソートを参照のこと。sortの有用な例は、ドキュメント文字列へのアクセスdocumentationを参照されたい。

seq.elライブラリーは、以下のようなプレフィクスseq-がついたシーケンス操作用の追加のマクロと関数を提供します。

このライブラリー内で定義されたすべての関数は、副作用をもちません。これらは引数として渡されたすべてのシーケンス(リスト、ベクター、文字列)を変更しません。特に明記しなければ、結果は入力と同じ型のシーケンスです。述語を受け取る関数では、それらは単一の関数である必要があります。

seq.elライブラリーは、シーケンシャルなデータ構造の追加型で機能するように拡張可能です。そのためにすべての関数はcl-defgenericを使用して定義されています。cl-defgenericを使用した拡張の追加に関する詳細は、ジェネリック関数を参照してください。

Function: seq-elt sequence index

この関数はindex(有効な範囲は0からsequenceの長さより1少ない整数)で指定されたsequenceの要素をリターンする。ビルトインのシーケンス型にたいする範囲外(out-of-range)の値にたいして、seq-elteltと同様に振る舞う。詳細はDefinition of eltを参照のこと。

(seq-elt [1 2 3 4] 2)
⇒ 3

seq-eltsetfを使用してセット可能なplaceをリターンする(setfマクロを参照)。

(setq vec [1 2 3 4])
(setf (seq-elt vec 2) 5)
vec
⇒ [1 2 5 4]
Function: seq-length sequence

この関数はsequence内の要素の個数をリターンする。ビルトインのシーケンス型にたいしてseq-lengthlengthと同様に振る舞う。Definition of lengthを参照のこと。

Function: seqp object

この関数はobjectがシーケンス(リストか配列)、またはseq.elのジェネリック関数を通じて定義されたすべての追加シーケンス型なら非nilをリターンする。これはsequencepの拡張された変種である。

(seqp [1 2])
⇒ t
(seqp 2)
⇒ nil
Function: seq-drop sequence n

この関数はsequenceの最初のn個(整数)を除く、すべての要素をリターンする.nが0以下なら結果はsequence

(seq-drop [1 2 3 4 5 6] 3)
⇒ [4 5 6]
(seq-drop "hello world" -4)
⇒ "hello world"
Function: seq-take sequence n

この関数はsequenceの最初のn個(整数)の要素をリターンする。nが0以下なら結果はnil

(seq-take '(1 2 3 4) 3)
⇒ (1 2 3)
(seq-take [1 2 3 4] 0)
⇒ []
Function: seq-take-while predicate sequence

この関数はsequenceのメンバーを順にリターンし、predicateが最初にnilをリターンした要素の前で停止する。

(seq-take-while (lambda (elt) (> elt 0)) '(1 2 3 -1 -2))
⇒ (1 2 3)
(seq-take-while (lambda (elt) (> elt 0)) [-1 4 6])
⇒ []
Function: seq-drop-while predicate sequence

この関数はpredicateが最初にnilをリターンした要素から、sequenceのメンバーを順にリターンする。

(seq-drop-while (lambda (elt) (> elt 0)) '(1 2 3 -1 -2))
⇒ (-1 -2)
(seq-drop-while (lambda (elt) (< elt 0)) [1 4 6])
⇒ [1 4 6]
Function: seq-split sequence length

この関数は(最大で)長さlengthsequenceの部分シーケンスから構成されるリストをリターンする(sequenceの長さがlengthの倍数でなければ最後の要素の長さはlengthより短くなるかもしれない)。

(seq-split [0 1 2 3 4] 2)
⇒ ([0 1] [2 3] [4])
Function: seq-do function sequence

この関数はsequenceの各要素にたいして、(恐らくは副作用を得るために)順番にfunctionを適用して、sequenceをリターンする。

Function: seq-map function sequence

この関数はsequenceの各要素にfunctionを適用した結果をリターンする。リターン値はリスト。

(seq-map #'1+ '(2 4 6))
⇒ (3 5 7)
(seq-map #'symbol-name [foo bar])
⇒ ("foo" "bar")
Function: seq-map-indexed function sequence

この関数はsequenceの各要素およびseqであるようなインデックスにfunctionを適用した結果をリターンする。リターン値はリスト。

(seq-map-indexed (lambda (elt idx)
                   (list idx elt))
                 '(a b c))
⇒ ((0 a) (1 b) (2 c))
Function: seq-mapn function &rest sequences

この関数はsequencesの各要素にfunctionを適用した結果をリターンする。 functionのarity (関数が受け取れる引数の個数。subr-arityを参照)はシーケンスの個数にマッチしなければならない。マッピングは最短のシーケンス終端で停止する。リターン値はリスト。

(seq-mapn #'+ '(2 4 6) '(20 40 60))
⇒ (22 44 66)
(seq-mapn #'concat '("moskito" "bite") ["bee" "sting"])
⇒ ("moskitobee" "bitesting")
Function: seq-filter predicate sequence

この関数はpredicateが非nilをリターンしたsequence内のすべての要素のリストをリターンする。

(seq-filter (lambda (elt) (> elt 0)) [1 -1 3 -3 5])
⇒ (1 3 5)
(seq-filter (lambda (elt) (> elt 0)) '(-1 -3 -5))
⇒ nil
Function: seq-remove predicate sequence

この関数はpredicatenilをリターンしたsequence内のすべての要素のリストをリターンする。

(seq-remove (lambda (elt) (> elt 0)) [1 -1 3 -3 5])
⇒ (-1 -3)
(seq-remove (lambda (elt) (< elt 0)) '(-1 -3 -5))
⇒ nil
Function: seq-remove-at-position sequence n

この関数はインデックスn (0基準)にある要素が削除されたsequenceのコピーをリターンする。結果のタイプはsequenceと同じ。

(seq-remove-at-position [1 -1 3 -3 5] 0)
⇒ [-1 3 -3 5]
(seq-remove-at-position [1 -1 3 -3 5] 3)
⇒ [1 -1 3 5]
Function: seq-keep function sequence

この関数はsequenceの要素それぞれにたいしてfunctionを呼び出して、結果が非nilだった要素すべてからなるリストをリターンする。

(seq-keep #'cl-digit-char-p '(?6 ?a ?7))
⇒ (6 7)
Function: seq-reduce function sequence initial-value

この関数はinitial-valuesequenceの1つ目の要素でfunctionを呼び出し、次にその結果とsequenceの2つ目の要素でfunctionを呼び出し、その次にその結果とsequenceの3つ目の要素で、...と呼び出した結果をリターンする。functionは引数が2つの関数であること。

functionは2つの引数で呼び出される。1つ目の引数としてinitial-value (その後は累積値)、2つ目の引数としてsequence内の要素が使用される。

sequenceが空なら、functionを呼び出さずにinitial-valueをリターンする。

(seq-reduce #'+ [1 2 3 4] 0)
⇒ 10
(seq-reduce #'+ '(1 2 3 4) 5)
⇒ 15
(seq-reduce #'+ '() 3)
⇒ 3
Function: seq-some predicate sequence

この関数はsequenceの各要素に順にpredicateを適用してリターンされた、最初の非nil値をリターンする。

(seq-some #'numberp ["abc" 1 nil])
⇒ t
(seq-some #'numberp ["abc" "def"])
⇒ nil
(seq-some #'null ["abc" 1 nil])
⇒ t
(seq-some #'1+ [2 4 6])
⇒ 3
Function: seq-find predicate sequence &optional default

この関数はpredicateが非nilをリターンした、sequence内の最初の要素をリターンする。predicateにマッチする要素がなければ、この関数はdefaultをリターンする。

この関数は見つかった要素がdefaultと等しい場合、要素が見つかったかどうかを知る術がないので曖昧さをもつことに注意。

(seq-find #'numberp ["abc" 1 nil])
⇒ 1
(seq-find #'numberp ["abc" "def"])
⇒ nil
Function: seq-every-p predicate sequence

この関数はsequenceの各要素にpredicateを適用して、すべてが非nilをリターンしたら非nilをリターンする。

(seq-every-p #'numberp [2 4 6])
⇒ t
(seq-every-p #'numberp [2 4 "6"])
⇒ nil
Function: seq-empty-p sequence

この関数はsequenceが空ならnilをリターンする。

(seq-empty-p "not empty")
⇒ nil
(seq-empty-p "")
⇒ t
Function: seq-count predicate sequence

この関数はsequence内でpredicateが非nilをリターンした要素の個数をリターンする。

(seq-count (lambda (elt) (> elt 0)) [-1 2 0 3 -2])
⇒ 2
Function: seq-sort function sequence

この関数はfunctionに応じてソートされたsequenceのコピーをリターンする。functionは2つの引数を受け取り、1つ目の引数が2つ目より前にソートされるべきなら非nilをリターンする。

Function: seq-sort-by function predicate sequence

この関数はseq-sortと似ているがソート前にsequenceの要素にfunctionを適用して変換する点が異なる。functionは単一の引数を受け取る関数。

(seq-sort-by #'seq-length #'> ["a" "ab" "abc"])
⇒ ["abc" "ab" "a"]
Function: seq-contains-p sequence elt &optional function

この関数はsequence内の少なくとも1つの要素がeltとequalなら非nilをリターンする。オプション引数functionが非nilなら、それはデフォルトのequalのかわりに使用する2つの引数を受け取る関数であること。

(seq-contains-p '(symbol1 symbol2) 'symbol1)
⇒ t
(seq-contains-p '(symbol1 symbol2) 'symbol3)
⇒ nil
Function: seq-set-equal-p sequence1 sequence2 &optional testfn

この関数は順序とは無関係にsequence1sequence2が同じ要素を含むかどうかをチェックする。オプション引数testfnが非nilなら、デフォルトのequalのかわりに使用する2つの引数を受け取る関数であること。

(seq-set-equal-p '(a b c) '(c b a))
⇒ t
(seq-set-equal-p '(a b c) '(c b))
⇒ nil
(seq-set-equal-p '("a" "b" "c") '("c" "b" "a"))
⇒ t
(seq-set-equal-p '("a" "b" "c") '("c" "b" "a") #'eq)
⇒ nil
Function: seq-position sequence elt &optional function

この関数はeltequalであるようなsequence内の最初の要素のインデックス(0基準)をリターンする。オプション引数functionが非nilなら、それはデフォルトのequalのかわりに使用する2つの引数を受け取る関数であること。

(seq-position '(a b c) 'b)
⇒ 1
(seq-position '(a b c) 'd)
⇒ nil
Function: seq-positions sequence elt &optional testfn

この関数はsequenceの要素それぞれにたいして、eltとともに引数としてtestfnを呼び出し、非nilをリターンするような要素のインデックス(0基準)のリストをリターンする。testfnのデフォルトはequal

(seq-positions '(a b c a d) 'a)
⇒ (0 3)
(seq-positions '(a b c a d) 'z)
⇒ nil
(seq-positions '(11 5 7 12 9 15) 10 #'>=)
⇒ (0 3 5)
Function: seq-uniq sequence &optional function

この関数は重複を削除したsequenceの要素のリストをリターンする。オプション引数functionが非nilなら、それはデフォルトのequalのかわりに使用する2つの引数を受け取る関数であること。

(seq-uniq '(1 2 2 1 3))
⇒ (1 2 3)
(seq-uniq '(1 2 2.0 1.0) #'=)
⇒ (1 2)
Function: seq-subseq sequence start &optional end

この関数はsequencestartからend(いずれも整数)までのサブセットをリターンする(endのデフォルトは最後の要素)。startendが負ならsequenceの最後から数える。

(seq-subseq '(1 2 3 4 5) 1)
⇒ (2 3 4 5)
(seq-subseq '[1 2 3 4 5] 1 3)
⇒ [2 3]
(seq-subseq '[1 2 3 4 5] -3 -1)
⇒ [3 4]
Function: seq-concatenate type &rest sequences

この関数はsequencesを結合して作成されたtype型のシーケンスをリターンする。typevectorliststringのいずれか。

(seq-concatenate 'list '(1 2) '(3 4) [5 6])
⇒ (1 2 3 4 5 6)
(seq-concatenate 'string "Hello " "world")
⇒ "Hello world"
Function: seq-mapcat function sequence &optional type

この関数はsequenceの各要素にfunctionを適用した結果に、seq-concatenateを適用した結果をリターンする。結果はtype型のシーケンス、またはtypenilならリストである。

(seq-mapcat #'seq-reverse '((3 2 1) (6 5 4)))
⇒ (1 2 3 4 5 6)
Function: seq-partition sequence n

この関数は長さnのサブシーケンスへグループ化したsequenceの要素のリストをリターンする。最後のシーケンスに含まれる要素はnより少ないかもしれない。nは整数であること。nが0以下の整数ならリターン値はnil

(seq-partition '(0 1 2 3 4 5 6 7) 3)
⇒ ((0 1 2) (3 4 5) (6 7))
Function: seq-union sequence1 sequence2 &optional function

この関数はsequence1sequence2のいずれかに出現する要素のリストをリターンする。リターンされるリストの要素はすべて、2要素を比較してequalにならないという意味において一意である。オプション引数functionが非nilなら、それはデフォルトのequalのかわりに比較に使用する2つの引数を受け取る関数であること。

(seq-union [1 2 3] [3 5])
⇒ (1 2 3 5)
Function: seq-intersection sequence1 sequence2 &optional function

この関数はsequence1sequence2の両方に出現する要素のリストをリターンする。オプション引数functionが非nilなら、それはデフォルトのequalのかわりに比較に使用する2つの引数を受け取る関数であること。

(seq-intersection [2 3 4 5] [1 3 5 6 7])
⇒ (3 5)
Function: seq-difference sequence1 sequence2 &optional function

この関数はsequence1に出現するがsequence2に出現しない要素のリストをリターンする。オプション引数functionが非nilなら、それはデフォルトのequalのかわりに比較に使用する2つの引数を受け取る関数であること。

(seq-difference '(2 3 4 5) [1 3 5 6 7])
⇒ (2 4)
Function: seq-group-by function sequence

この関数はsequenceの各要素にfunctionを適用して、その結果をキーとしてsequenceをalistに分割する。キーの比較にはequalを使用する。

(seq-group-by #'integerp '(1 2.1 3 2 3.2))
⇒ ((t 1 3 2) (nil 2.1 3.2))
(seq-group-by #'car '((a 1) (b 2) (a 3) (c 4)))
⇒ ((b (b 2)) (a (a 1) (a 3)) (c (c 4)))
Function: seq-into sequence type

この関数はシーケンスsequencetype型のシーケンスに変換する。typevectorstringlistのいずれかであること。

(seq-into [1 2 3] 'list)
⇒ (1 2 3)
(seq-into nil 'vector)
⇒ []
(seq-into "hello" 'vector)
⇒ [104 101 108 108 111]
Function: seq-min sequence

この関数はsequenceの最小の要素をリターンする。sequenceの要素は数字かマーカー(マーカーを参照)でなければならない。

(seq-min [3 1 2])
⇒ 1
(seq-min "Hello")
⇒ 72
Function: seq-max sequence

この関数はsequenceの最大の要素をリターンする。sequenceの要素は数字かマーカーでなければならない。

(seq-max [1 3 2])
⇒ 3
(seq-max "Hello")
⇒ 111
Macro: seq-doseq (var sequence) body…

このマクロはdolist (dolistを参照)と同様だが、sequenceにリスト、ベクター、文字列のいずれかを指定できる点が異なる。これ主な利点は副作用である。

Macro: seq-let var-sequence val-sequence body…

このマクロはvar-sequence内で定義される変数にval-sequenceの対応する要素をバインドする。これは分割代入(destructuring binding)として知られている。var-sequenceの要素は、ネストされた非構造化を許容することにより自身にシーケンスを含むことができる。

var-sequenceシーケンスには、val-sequenceの残りにバインドされる変数名が後続するような&restマーカーを含めることもできる。

(seq-let [first second] [1 2 3 4]
  (list first second))
⇒ (1 2)
(seq-let (_ a _ b) '(1 2 3 4)
  (list a b))
⇒ (2 4)
(seq-let [a [b [c]]] [1 [2 [3]]]
  (list a b c))
⇒ (1 2 3)
(seq-let [a b &rest others] [1 2 3 4]
  others)
⇒ [3 4]

pcaseパターンは分割代入にたいする代替えの機能を提供する。pcaseパターンによる分解を参照のこと。

Macro: seq-setq var-sequence val-sequence

このマクロはseq-letと同様に機能するが、letではなくあたかもsetqで値が変数にバインドされる点が異なる。

(let ((a nil)
      (b nil))
  (seq-setq (_ a _ b) '(1 2 3 4))
  (list a b))
⇒ (2 4)
Function: seq-random-elt sequence

この関数はsequenceの要素をランダムにリターンする。

(seq-random-elt [1 2 3 4])
⇒ 3
(seq-random-elt [1 2 3 4])
⇒ 2
(seq-random-elt [1 2 3 4])
⇒ 4
(seq-random-elt [1 2 3 4])
⇒ 2
(seq-random-elt [1 2 3 4])
⇒ 1

sequenceが空ならこの関数はエラーをシグナルする。


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

6.2 配列

配列(array)オブジェクトは、いくつかのLispオブジェクトを保持するスロットをもち、これらのオブジェクトは配列の要素と呼ばれます。配列内の任意の要素は一定時間でアクセスされます。対照的にリスト内の要素のアクセスに要する時間は、その要素がリスト内のどの位置にあるかに比例します。

Emacsは4つの配列型 —文字列(strings、文字列型を参照)ベクター(vectors、ベクター型を参照)ブールベクター(bool-vectors、ブールベクター型を参照)文字テーブル(char-tables、文字テーブル型を参照) — を定義しており、これらはすべて1次元です。ベクターと文字テーブルは任意の型の要素を保持できますが、文字列は文字だけ、ブールベクターはtnilしか保持できません。

4種のすべての配列はこれらの特性を共有します:

  • 配列の1番目の要素はインデックス0、2番目はインデックス1、...となる。これは0基準(zero-origin)のインデックスづけと呼ばれる。たとえば4要素の配列のインデックスは0、1、2、3。
  • 配列の長さは一度配列が作成されたら固定されるので、既存の配列の長さは変更できない。
  • 評価において配列は定数 — つまりそれ自身へと評価される。
  • 配列の要素は関数arefで参照したり、関数asetで変更できる(配列を操作する関数を参照)。

配列を作成したとき、文字テーブル以外では長さを指定しなければなりません。文字テーブルの長さは文字コードの範囲により決定されるので長さを指定できません。

原則として、テキスト文字の配列が欲しい場合は、文字列とベクターのどちらかを使用できます。実際のところ4つの理由により,そのような用途にたいしては、わたしたちは常に文字列を選択します:

  • 文字列は同じ要素をもつベクターと比較して占めるスペースが1/4である。
  • 文字列の内容はテキストとして、より明解な方法によりプリントされる。
  • 文字列はテキストプロパティを保持できる。テキストのプロパティを参照のこと。
  • Emacsの特化した編集機能とI/O機能の多くが文字列だけに適用される。たとえば文字列をバッファーに挿入する方法では、文字のベクターをバッファーに挿入できない。文字列と文字を参照のこと

対照的に、(キーシーケンスのような)キーボード入力文字の配列では、多くのキーボード入力文字は文字列に収まる範囲の外にあるので、ベクターが必要になるでしょう。キーシーケンス入力を参照してください。


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

6.3 配列を操作する関数

このセクションではすべての型の配列に適用される関数を説明します。

Function: arrayp object

この関数はobjectが配列(ベクター、文字列、ブールベクター、文字テーブル)ならtをリターンする。

(arrayp [a])
     ⇒ t
(arrayp "asdf")
     ⇒ t
(arrayp (syntax-table))    ;; 文字テーブル
     ⇒ t
Function: aref arr index

この関数はarr (配列かレコード)のindex番目の要素をリターンする。1番目の要素のインデクスは0。

(setq primes [2 3 5 7 11 13])
     ⇒ [2 3 5 7 11 13]
(aref primes 4)
     ⇒ 11
(aref "abcdefg" 1)
     ⇒ 98           ; b’のASCIIコードは98

シーケンスの関数eltも参照されたい。

Function: aset array index object

この関数はarrayindex番目の要素をobjectにセットする。この関数はobjectをリターンする。

(setq w (vector 'foo 'bar 'baz))
     ⇒ [foo bar baz]
(aset w 0 'fu)
     ⇒ fu
w
     ⇒ [fu bar baz]

;; copy-sequenceは後で変更する文字列をコピーする
(setq x (copy-sequence "asdfasfd"))
     ⇒ "asdfasfd"
(aset x 3 ?Z)
     ⇒ 90
x
     ⇒ "asdZasfd"

arrayはmutableであること。可変性を参照のこと。

arrayが文字列でobjectが文字でなければ、結果はwrong-type-argumentエラーとなる。この関数は文字列の挿入で必要なら、ユニバイト文字列をマルチバイト文字列に変換する。

Function: fillarray array object

この関数は配列arrayobjectで充填するので、arrayのすべての要素はobjectになる。この関数はarrayをリターンする。

(setq a (copy-sequence [a b c d e f g]))
     ⇒ [a b c d e f g]
(fillarray a 0)
     ⇒ [0 0 0 0 0 0 0]
a
     ⇒ [0 0 0 0 0 0 0]
(setq s (copy-sequence "When in the course"))
     ⇒ "When in the course"
(fillarray s ?-)
     ⇒ "------------------"

arrayが文字列でobjectが文字でなければ、結果はwrong-type-argumentエラーとなる。

配列と判っているオブジェクトにたいしては、一般的なシーケンス関数copy-sequencelengthが有用なときがよくあります。シーケンスを参照してください。


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

6.4 ベクター

ベクター(vector)とは任意のLispオブジェクトを要素にもつことができる、一般用途のための配列です(対照的に文字列の要素は文字のみ。文字列と文字を参照)。Emacsではベクターはキーシーケンス(キーシーケンスを参照)、シンボル検索用のテーブル(シンボルの作成とinternを参照)、バイトコンパイルされた関数表現の一部(バイトコンパイルを参照)などの多くの目的で使用されます。

他の配列と同様、ベクターは0基準のインデックスづけを使用し、1番目の要素はインデックス0になります。

ベクターは角カッコ(square brackets)で囲まれた要素としてプリントされます。したがってシンボルabaを要素にもつベクターは、[a b a]とプリントされます。Lisp入力として同じ方法でベクターを記述できます。

文字列や数値と同様にベクターは定数として評価され、評価された結果は同じベクターになります。ベクターの要素は評価も確認もされません。自己評価を行うフォームを参照してください。角カッコ(square brackets)で記述されたベクターをasetや他の破壊的操作を通じて修正しないでください。可変性を参照してください。

以下はこれらの原理を表す例です:

(setq avector [1 two '(three) "four" [five]])
     ⇒ [1 two '(three) "four" [five]]
(eval avector)
     ⇒ [1 two '(three) "four" [five]]
(eq avector (eval avector))
     ⇒ t

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

6.5 ベクターのための関数

ベクターに関連した関数をいくつか示します:

Function: vectorp object

この関数はobjectがベクターならtをリターンする。

(vectorp [a])
     ⇒ t
(vectorp "asdf")
     ⇒ nil
Function: vector &rest objects

この関数は引数objectsを要素にもつベクターを作成してリターンする。

(vector 'foo 23 [bar baz] "rats")
     ⇒ [foo 23 [bar baz] "rats"]
(vector)
     ⇒ []
Function: make-vector length object

この関数は各要素がobjectに初期化された、length個の要素からなる新しいベクターをリターンする。

(setq sleepy (make-vector 9 'Z))
     ⇒ [Z Z Z Z Z Z Z Z Z]
Function: vconcat &rest sequences

この関数はsequencesのすべての要素を含む新しいベクターをリターンする。引数sequencesは正リスト、ベクター、文字列、ブールベクター。sequencesが与えられければ空のベクターがリターンされる。

値は空のベクター、またはすべての既存ベクターとeqではないような空ではない新しいベクターのいずれか。

(setq a (vconcat '(A B C) '(D E F)))
     ⇒ [A B C D E F]
(eq a (vconcat a))
     ⇒ nil
(vconcat)
     ⇒ []
(vconcat [A B C] "aa" '(foo (6 7)))
     ⇒ [A B C 97 97 foo (6 7)]

vconcat関数は、引数としてバイトコード関数オブジェクトも受け取ることができる。これはバイトコード関数オブジェクトの内容全体にアクセスするのを容易にするための特別な機能である。バイトコード関数オブジェクトを参照のこと。

結合を行なう他の関数については関数のマッピングmapconcat文字列の作成concatコンスセルおよびリストの構築appendを参照されたい。

append関数はベクターを同じ要素をもつリストに変換する方法も提供します:

(setq avector [1 two (quote (three)) "four" [five]])
     ⇒ [1 two '(three) "four" [five]]
(append avector nil)
     ⇒ (1 two '(three) "four" [five])

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

6.6 文字テーブル

文字テーブル(char-table)はベクターとよく似ていますが、文字テーブルは文字コードによりインデックスづけされます。文字テーブルのインデックスには、修飾キーをともなわない任意の有効な文字コードを使用できます。他の配列と同様に、arefasetで文字テーブルの要素にアクセスできます。加えて、文字テーブルは追加のデータを保持するために、特定の文字コードに関連づけられていないエキストラスロット(extra slots)をもつことができます。ベクターと同様、文字テーブルは定数として評価され、任意の型の要素を保持できます。

文字テーブルはそれぞれサブタイプ(subtype)をもち、これは2つの目的をもつシンボルです:

  • サブタイプはそれがなんのための文字テーブルなのかを簡単に表す方法を提供する。たとえばディスプレイテーブル(display tables)はサブタイプがdisplay-tableの文字テーブルであり、構文テーブル(syntax tables)はサブタイプがsyntax-tableの文字テーブル。以下で説明するように関数char-table-subtypeを使用してサブタイプの問い合わせが可能。
  • サブタイプは文字テーブル内のいくつかのエキストラスロット(extra slots)を制御する。エキストラスロットの数は、そのサブタイプのchar-table-extra-slotsシンボルプロパティ(シンボルのプロパティを参照)により指定され、値は0から10の整数。サブタイプにそのようなシンボルプロパティがなければ、その文字テーブルはエキストラスロットをもたない。

文字テーブルは親(parent)をもつことができ、これは他の文字テーブルです。文字テーブルが親をもつ場合、その文字テーブルで特定の文字cにたいしてnilが指定されていたら、親と指定された文字テーブルで指定された値を継承します。言い方を変えると、文字テーブルchar-tablecnilが指定されていたら、(aref char-table c)char-tableの親の値をリターンします。

文字テーブルはデフォルト値(default value)をもつこともできます。デフォルト値をもつとき、文字テーブルchar-tablecにたいしてnil値を指定すると、(aref char-table c)はデフォルト値をリターンします。

Function: make-char-table subtype &optional init

サブタイプsubtype(シンボル)をもつ、新たに作成された文字テーブルをリターンする。各要素はinitに初期化され、デフォルトはnil。文字テーブルが作成された後で、文字テーブルのサブタイプを変更することはできない。

すべての文字テーブルは、インデックスとなる任意の有効な文字テーブルのための空間をもつので、文字テーブルの長さを指定する引数はない。

subtypeがシンボルプロパティchar-table-extra-slotsをもつなら、それはその文字列テーブル内のエキストラスロットの数を指定する。値には0から10の整数を指定し、これ以外ならmake-char-tableはエラーとなる。subtypeがシンボルプロパティchar-table-extra-slots(プロパティリストを参照)をもたなければ、その文字テーブルはエキストラスロットをもたない。

Function: char-table-p object

この関数はobjectが文字テーブルならt、それ以外はnilをリターンする。

Function: char-table-subtype char-table

この関数はchar-tableのサブタイプのシンボルをリターンする。

文字テーブルのデフォルト値にアクセスするための特別な関数は存在しません。これを行なうにはchar-table-rangeを使用します(以下参照)。

Function: char-table-parent char-table

この関数はchar-tableの親をリターンする。親は常にnilか他の文字テーブルである。

Function: set-char-table-parent char-table new-parent

この関数はchar-tableの親をnew-parentにセットする。

Function: char-table-extra-slot char-table n

この関数はchar-tableのエキストラスロットn (0基準)の内容をリターンする。文字テーブルのエキストラスロットの数は文字テーブルのサブタイプにより決定される。

Function: set-char-table-extra-slot char-table n value

この関数はchar-tableのエキストラスロットn (0基準)にvalueを格納する。

文字テーブルは1つの文字コードにたいして1つの要素値(element value)を指定できます。文字テーブルは文字セット全体にたいして値を指定することもできます。

Function: char-table-range char-table range

この関数は文字範囲rangeにたいしてchar-tableで指定された値をリターンする。可能なrangeは以下のとおり:

nil

デフォルト値への参照。

char

文字charにたいする要素への参照(charは有効な文字コードであると仮定)。

(from . to)

包括的な範囲‘[from..to]’内のすべての文字を参照するコンスセル。

Function: set-char-table-range char-table range value

この関数はchar-table内の文字範囲rangeにたいして値をセットする。可能なrangeは以下のとおり:

nil

デフォルト値への参照。

t

文字コード範囲の全体を参照。

char

文字charにたいする要素への参照(charは有効な文字コードであると仮定)。

(from . to)

包括的な範囲‘[from..to]’内のすべての文字を参照するコンスセル。

Function: map-char-table function char-table

この関数はchar-tableの非nil値ではない各要素にたいして引数functionを呼び出す。functionの呼び出しでは2つの引数(keyとvalue)が指定される。keyはchar-table-rangeにたいする可能なrange (有効な文字か、同じ値を共有する文字範囲を指定するコンスセル(from . to))。valueは(char-table-range char-table key)がリターンする値。

全体として、functionに渡されるkey-valueのペアはchar-tableに格納されたすべての値を表す。

リターン値は常にnilである。map-char-table呼び出しを有用にするためにfunctionは副作用をもつこと。たとえば以下は構文テーブルを調べる方法:

(let (accumulator)
   (map-char-table
    (lambda (key value)
      (setq accumulator
            (cons (list
                   (if (consp key)
                       (list (car key) (cdr key))
                     key)
                   value)
                  accumulator)))
    (syntax-table))
   accumulator)
⇒
(((2597602 4194303) (2)) ((2597523 2597601) (3))
 ... (65379 (5 . 65378)) (65378 (4 . 65379)) (65377 (1))
 ... (12 (0)) (11 (3)) (10 (12)) (9 (0)) ((0 8) (3)))

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

6.7 ブールベクター

ブールベクター(bool-vector)はベクターとよく似ていますが、値にtnilしか格納できません。ブールベクターの要素に非nil値の格納を試みると、そこにはtが格納されます。すべての配列と同様、ブールベクターのインデックスは0から開始され、一度ブールベクターが作成されたら長さを変更することはできません。ブールベクターは定数として評価されます。

ブールベクターを処理する特別な関数がいくつかあります。その関数以外にも、他の種類の配列に使用されるのと同じ関数でブールベクターを操作できます。

Function: make-bool-vector length initial

initialに初期化されたlength要素の新しいブールベクターをリターンする。

Function: bool-vector &rest objects

この関数は引数objectsを要素にもつブールベクターを作成してリターンする。

Function: bool-vector-p object

この関数はobjectがブールベクターであればt、それ以外はnilをリターンする。

以下で説明するように、ブールベクターのセット処理を行なう関数がいくつかあります:

Function: bool-vector-exclusive-or a b &optional c

ブールベクターabビットごとの排他的論理和(bitwise exclusive or)をリターンする。オプション引数cが与えられたら、この処理の結果はcに格納される。引数にはすべて同じ長さのブールベクターを指定すること。

Function: bool-vector-union a b &optional c

ブールベクターabビットごとの論理和(bitwise or)をリターンする。オプション引数cが与えられたら、この処理の結果はcに格納される。引数にはすべて同じ長さのブールベクターを指定すること。

Function: bool-vector-intersection a b &optional c

ブールベクターabビットごとの論理積(bitwise and)をリターンする。オプション引数cが与えられたら、この処理の結果はcに格納される。引数にはすべて同じ長さのブールベクターを指定すること。

Function: bool-vector-set-difference a b &optional c

ブールベクターab差集合(set difference)をリターンする。オプション引数cが与えられたら、この処理の結果はcに格納される。引数にはすべて同じ長さのブールベクターを指定すること。

Function: bool-vector-not a &optional b

ブールベクターa補集合(set complement)をリターンする。オプション引数bが与えられたら、この処理の結果はbに格納される。引数にはすべて同じ長さのブールベクターを指定すること。

Function: bool-vector-subsetp a b

a内のすべてのt値がbでもt値ならt、それ以外はnilをリターンする。引数にはすべて同じ長さのブールベクターを指定すること。

Function: bool-vector-count-consecutive a b i

iから始まるaの、bと等しい連続する要素の数をリターンする。aはブールベクターで、btniliaのインデックス。

Function: bool-vector-count-population a

ブールベクターaからtであるような要素の数をリターンする。

長さ8以下のブール値のプリント表記は1文字で表されます。

(bool-vector t nil t nil)
     ⇒ #&4"^E"
(bool-vector)
     ⇒ #&0""

他のベクター同様、vconcatを使用してブールベクターをプリントできます:

(vconcat (bool-vector nil t nil t))
     ⇒ [nil t nil t]

以下はブールベクターを作成、確認、更新する別の例です:

(setq bv (make-bool-vector 5 t))
     ⇒ #&5"^_"
(aref bv 1)
     ⇒ t
(aset bv 3 nil)
     ⇒ nil
bv
     ⇒ #&5"^W"

control-_の2進コードは11111、control-Wは10111なので、この結果は理にかなっています。


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

6.8 オブジェクト用固定長リングの管理

リング(ring)は挿入、削除、ローテーション、剰余(modulo)でインデックスづけされた、参照と走査(traversal)をサポートする固定長のデータ構造です。ringパッケージにより効率的なリングデータ構造が実装されています。このパッケージは、このセクションにリストした関数を提供します。

Emacsにあるkillリングやマークリングのようないくつかのリングは、実際には単なるリストとして実装されていることに注意してください。したがってこれらのリングにたいしては、以下の関数は機能しないでしょう。

Function: make-ring size

この関数はsizeオブジェクトを保持できる、新しいリングをリターンする。sizeは整数。

Function: ring-p object

この関数はobjectがリングならt、それ以外はnilをリターンする。

Function: ring-size ring

この関数はringの最大の要素数をリターンする。

Function: ring-length ring

この関数はringに現在含まれるオブジェクトの数をリターンする。値がring-sizeのリターンする値を超えることはない。

Function: ring-elements ring

この関数はring内のオブジェクトのリストをリターンする。リストの順序は新しいオブジェクトが先頭になる。

Function: ring-copy ring

この関数は新しいリングとしてringのコピーをリターンする。新しいリングはringと同じ(eqな)オブジェクトを含む。

Function: ring-empty-p ring

この関数はringが空ならt、それ以外はnilをリターンする。

リング内の一番新しい要素は常にインデックス0をもちます。より大きいインデックスは、より古い要素に対応します。インデックスはリング長のmoduloにより計算されます。インデックス-1は一番古い要素、-2は次に古い要素、...となります。

Function: ring-ref ring index

この関数はインデックスindexにあるring内のオブジェクトをリターンする。indexには負やリング長より大きい数を指定できる。ringが空ならring-refはエラーをシグナルする。

Function: ring-insert ring object

この関数は一番新しい要素としてobjectringに挿入してobjectをリターンする。

リングが満杯なら新しい要素用の空きを作るために、挿入により一番古い要素が削除される。

Function: ring-remove ring &optional index

ringからオブジェクトを削除してそのオブジェクトをリターンする。引数indexはどのアイテムを削除するかを指定する。これがnilなら、それは一番古いアイテムを削除することを意味する。ringが空ならring-removeはエラーをシグナルする。

Function: ring-insert-at-beginning ring object

この関数は一番古い要素としてobjectringに挿入する。リターン値に意味はない。

リングが満杯なら、この関数は挿入される要素のための空きを作るために一番新しい要素を削除する。

Function: ring-resize ring size

ringのサイズをsizeにセットする。新たなサイズのほうが小さければリング内の古いアイテムは破棄される。

リングサイズを超過しないよう注意すれば、そのリングをFIFO(first-in-first-out: 先入れ先出し)のキューとして使用することができます。たとえば:

(let ((fifo (make-ring 5)))
  (mapc (lambda (obj) (ring-insert fifo obj))
        '(0 one "two"))
  (list (ring-remove fifo) t
        (ring-remove fifo) t
        (ring-remove fifo)))
     ⇒ (0 t one t "two")

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

7 レコード

レコードの目的はEmacsにビルトインされていない新たな型のオブジェクトをプログラマーが作成できるようにすることです。これらはcl-defstructdefclassのインスタンスを表現する基礎として使用されています。

レコードオブジェクトは内部的にはベクターと似ています。レコードオブジェクトのスロットはarefを使用してアクセス可能であり、copy-sequenceを使用してコピーできます。しかし最初のスロットはtype-ofがリターンする型を保持するために使用されます。更に現実装ではレコードは最大で4096スロットを所有できますが、ベクターはそれより多くのスロットを所有できます。レコードは配列と同じように0基準のインデックスを使用するので、最初のスロットはインデックスが0になります。

型スロット(type slot)はシンボルか型記述子であるべきです。型記述子なら型を命名するシンボルがリターンされます。型記述子を参照してください。その他の種類のオブジェクトはすべてそのままリターンされます。

レコードのプリント表現では‘#s’の後にコンテンツを指定するリストが続きます。リストの最初の要素はそのレコードの型である必要があります。後続の要素はレコードのスロットです。

レコードの型を新たに定義するLispプログラムは他の型名との衝突を避けるために、通常はレコード型を導入する部分では型名にパッケージの命名規約を使用するべきです。衝突する可能性がある型名は、パッケージが定義したレコード型のロード時には不明かもしれないことに注意してください。これらは将来のある時点でロードされる可能性があります。

レコードは評価にたいして定数とみなされます。評価すると結果は同じレコードになります。レコードは評価されずにスロットのチェックさえ行われません。自己評価を行うフォームを参照してください。


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

7.1 レコード関数

Function: recordp object

この関数はobjectがレコードならtをリターンする。

(recordp #s(a))
     ⇒ t
Function: record type &rest objects

この関数は型がtypeであり、残りのスロットが残りの引数objectsであるようなレコードを作成してリターンする。

(record 'foo 23 [bar baz] "rats")
     ⇒ #s(foo 23 [bar baz] "rats")
Function: make-record type length object

この関数は型がtypeobjectで初期化されたスロット数がlengthの新たなレコードをリターンする。

(setq sleepy (make-record 'foo 9 'Z))
     ⇒ #s(foo Z Z Z Z Z Z Z Z Z)

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

7.2 後方互換

レコードを使用しない古いバージョンのcl-defstructでコンパイルされたコードを新しいEmacsで実行したときに問題が発生するかもしれません。この魔問題を軽減するために、Emacsは古いcl-defstructの使用を検知した際に古い構造体オブジェクトがレコードであるかのように処理するモードを有効にします。

Function: cl-old-struct-compat-mode arg

argが正なら旧スタイルの構造体にたいする後方互換を有効にする。


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

8 ハッシュテーブル

ハッシュテーブル(hash table)は非常に高速なルックアップテーブルの一種で、キーに対応する値をマップするという点ではalist(連想リストを参照)に似ています。ハッシュテーブルは以下の点でalistと異なります:

Emacs Lispは一般的な用途のハッシュテーブルデータ型とともに、それらを処理する一連の関数を提供します。ハッシュテーブルは‘#s’、その後にハッシュテーブルのプロパティと内容を指定するリストが続く、特別なプリント表現をもちます。ハッシュテーブルの作成を参照してください(ハッシュ表記の最初に使用される‘#’文字は、読み取り表現をもたないオブジェクトのプリント表現であり、これはハッシュテーブルに何も行わない。プリント表現と読み取り構文を参照のこと)。

obarray(オブジェクト配列)もハッシュテーブルの一種ですが、これらは異なる型のオブジェクトであり、intern(インターン)されたシンボルを記録するためだけに使用されます(シンボルの作成とinternを参照)。


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

8.1 ハッシュテーブルの作成

ハッシュテーブルを作成する基本的な関数はmake-hash-tableです。

Function: make-hash-table &rest keyword-args

この関数は指定された引数に対応する新しいハッシュテーブルを作成する。引数はキーワード(特別に認識される独自のシンボル)と、それに対応する値を交互に指定することで構成される。

make-hash-tableではいくつかのキーワードが意味をもつが、実際に知る必要があるのは:test:weaknessの2つだけである。

:test test

これはそのハッシュテーブルにたいしてキーを照合する方法を指定する。デフォルトはeqlであり他の代替としてはeqequalがある:

eql

キーが数字ならそれらがequal、つまりそれらの値が等しくどちらも整数か浮動小数点数なら同一。それ以外なら別の2つのオブジェクトは決して同一とならない。

eq

別の2つのLispオブジェクトはすべて別のキーになる。

equal

別の2つのLispオブジェクトで、それらがequalなら同一のキーである。

testにたいして追加の選択肢を定義するために、define-hash-table-test (ハッシュの比較の定義を参照)を使用することができる。

:weakness weak

ハッシュテーブルのweakness(強度)は、ハッシュテーブル内に存在するキーと値をガーベージコレクションから保護するかどうかを指定する。

weakにはnilkeyvaluekey-or-valuekey-and-value、またはt(key-and-valueのエイリアス)のいずれかを指定しなければならない。weakkeyならそのハッシュテーブルは、(キーが他の場所で参照されていなければ)ハッシュテーブルのキーがガーベージコレクトされるのを妨げられない。ある特定のキーがガーベージコレクトされると、それに対応する連想はハッシュテーブルから削除される。

weakvalueならそのハッシュテーブルは、(値が他の場所で参照されていなければ)ハッシュテーブルの値がガベージコレクトされるのを妨げられない。ある特定の値がガーベージコレクトされると、それに対応する連想はハッシュテーブルから削除される。

weakkey-and-value(かt)なら、その連想を保護するためにはキーと値の両方が生きていなければならない。したがってそのハッシュテーブルは、キーと値の一方だけをガーベージコレクトから守ることはしない。キーか値のどちらか一方がガーベージコレクトされたら、その連想は削除される。

weakkey-or-valuenara、キーか値のどちらか一方で、その連想を保護することができる。したがってキーと値の両方がガベージコレクトされたときだけ(それがハッシュテーブル自体にたいする参照でなければ)、ハッシュテーブルからその連想が削除される。

weakのデフォルトはnilなので、ハッシュテーブルから参照されているキーと値はすべてガーベージコレクションから保護される。

:size size

これはそのハッシュテーブルに保管しようとしている、連想の数にたいするヒントを指定する。数が概算で判っていれば、この方法でそれを指定して処理を若干効率的にすることができる。小さすぎるサイズを指定すると、そのハッシュテーブルは必要に応じて自動的に拡張されるが、これを行なうために時間が余計にかかる。

デフォルトのサイズは65。

:rehash-size rehash-size

ハッシュテーブルに連想を追加するとき、そのテーブルが満杯ならテーブルを自動的に拡張する。この値はその際にどれだけハッシュテーブルを拡張するかを指定する。

rehash-sizeが整数(正であること)なら、通常のサイズにrehash-sizeに近い値を加えることによりハッシュテーブルが拡張される。rehash-sizeが浮動小数(1より大きい方がよい)なら、古いサイズにその数に近い値を乗じることによりハッシュテーブルが拡張される。

デフォルト値は1.5。

:rehash-threshold threshold

これはハッシュテーブルが一杯(なのでもっと大きく拡張する必要がある)だと判断される基準を指定する。thresholdの値は1以下の正の浮動小数点数であること。実際のエントリー数が通常のサイズにたいする指定した割合に近い値を超えるとハッシュテーブルは一杯(full)になる。thresholdのデフォルトは0.8125。

ハッシュテーブルのプリント表現を使用してハッシュテーブルを作成することもできます。指定されたハッシュテーブル内の各要素が、有効な入力構文(プリント表現と読み取り構文を参照)をもっていれば、Lispリーダーはこのプリント表現を読み取ることができます。たとえば以下は値val1 (シンボル)と300 (数字)に関連づけられた、キーkey1key2 (両方ともシンボル)をハッシュテーブルに指定します。

#s(hash-table size 30 data (key1 val1 key2 300))

しかしこれをEmacs Lispコードで使用する際には、ハッシュテーブルを新たに作成するかどうかは未定義であることに注意してください。ハッシュテーブルを新たに作成したければ、常にmake-hash-tableを使う必要があります(自己評価を行うフォームを参照)。

ハッシュテーブルのプリント表現は‘#s’と、その後の‘hash-table’で始まるリストにより構成されます。このリストの残りの部分はそのハッシュテーブルのプロパティと初期内容を指定する、0個以上のプロパティと値からなるペアで構成されるべきです。プロパティと値はそのまま読み取られます。有効なプロパティ名はsizetestweaknessrehash-sizerehash-thresholddataです。dataプロパティは、初期内容にたいするキーと値のペアからなるリストであるべきです。他のプロパティは、上記で説明したmake-hash-tableのキーワード(:size:testなど)と同じ意味をもちます。

バッファーやフレームのような、入力構文をもたないオブジェクトを含んだ初期内容をもつハッシュテーブルを指定できないことに注意してください。そのようなオブジェクトは、ハッシュテーブルを作成した後に追加します。


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

8.2 ハッシュテーブルへのアクセス

このセクションではハッシュテーブルにアクセスしたり、連想を保管する関数を説明します。比較方法による制限がない限り、一般的には任意のLispオブジェクトをハッシュキーとして使用できます。

Function: gethash key table &optional default

この関数はtablekeyを照合してそれに関連づけられたvaluetable内にkeyをもつ連想が存在しなければdefaultをリターンする。

Function: puthash key value table

この関数はtable内に値valueをもつkeyの連想を挿入します。tableがすでにkeyの連想をもつなら、valueで古い連想値を置き換える。この関数は常にvalueをリターンする。

Function: remhash key table

この関数はtablekeyの連想があればそれを削除する。keyが連想をもたなければremhashは何も行なわない。

Common Lispに関する注意: Common Lispではremhashが実際に連想を削除したときは非nil、それ以外はnilをリターンする。Emacs Lispではremhashは常にnilをリターンする。

Function: clrhash table

この関数はハッシュテーブルtableからすべての連想を削除するので、そのハッシュテーブルは空になる。これはハッシュテーブルのクリーニング(clearing)とも呼ばれる。clrhashは空のtableをリターンする。

Function: maphash function table

この関数はtable内の各連想にたいして一度ずつfunctionを呼び出す。関数functionは2つの引数 — tableにリストされたkeyと、それに関連づけられたvalue — を受け取ること。maphashnilをリターンする。


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

8.3 ハッシュの比較の定義

define-hash-table-testでキーを照合する新しい方法を定義できます。この機能を使用するにはハッシュテーブルの動作方法と、ハッシュコード(hash code)の意味を理解する必要があります。

概念的にはハッシュテーブルを1つの連想を保持できるスロットがたくさんある巨大な配列として考えることができます。キーを照合するにはまず、gethashがキーから整数(ハッシュコード)を計算します。配列の長さを法(modulo)としてこの整数を縮小して(訳注:配列の長さで割った余りの整数にして)、配列内のインデックスを生成することができます。それから探しているキーが見つかったかどうか確認するためにそのスロット、必要なら近くのスロットを調べます。

したがってキーを照合する新たな方法を定義するにはキーからハッシュコードを計算する関数、および2つのキーを直接比較する関数の両方を指定する必要があります。この2つの関数は互いに一貫性をもつ必要があります。すなわちキーを比較してequalなら、2つのキーのハッシュコードは同一であるべきです。さらに(ガーベージコレクターからの呼び出しのように)2つの関数は任意のタイミングで呼び出される可能性があるので、関数が副作用をもたないこと、すぐにリターンすること、そしてこれらの関数の挙動はそのキーの不変の性質だけに依存する必要があります。

Function: define-hash-table-test name test-fn hash-fn

この関数はnameという名前の新たなハッシュテーブルテストを定義します。

この方法でnameを定義した後は、make-hash-tableの引数testにこれを使用することができる。これを行なう際は、そのハッシュテーブルのキー値の比較にtest-fn、キー値からハッシュコードを計算するためにhash-fnを使用することになる。

関数test-fnは2つの引数(2つのキー)をとり、それらが同一と判断されたときは非nilをリターンする。

関数hash-fnは1つの引数(キー)を受け取り、そのキーのハッシュコード(整数)をリターンすること。よい結果を得るために、その関数は負のfixnumを含むfixnumの全範囲をハッシュコードに使用すること。

指定された関数は、プロパティhash-table-testの配下の、nameというプロパティリストに格納される。そのプロパティの値形式は(test-fn hash-fn)

Function: sxhash-equal obj

この関数はLispオブジェクトobjのハッシュコードをリターンする。リターン値はobjと、それが指す別のLispオブジェクトの内容を表す整数。

2つのオブジェクトobj1obj2equalならば(sxhash-equal obj1)(sxhash-equal obj2)は同じ整数になる。

2つのオブジェクトがequalでなければ、通常ならsxhash-equalがリターンする値は異なるが常に異なるとも限らない。sxhash-equalはネストされた構造体を深く再帰しないことによって十分高速になるようデザインされている(ハッシュテーブルのインデックス作成に使用するため)。加えて稀に(運次第)ではあるがsxhash-equalが同じ結果を与える、2つの異なって見えるシンプルなオブジェクトに出会うことがあるかもしれない。したがって一般的にはオブジェクトが変更されたかどうかのチェックにsxhash-equalを用いることはできない。

Common Lispに関する注意: Common Lispではこれに似た関数はsxhashと呼ばれる。Emacsは互換性のためにsxhash-equalにたいするエイリアスとしてこの名前を提供している。

Function: sxhash-eq obj

この関数はLispオブジェクトobjにたいするハッシュコードをリターンする。結果はobjの識別値であり内容が反映されているわけではない。

2つのオブジェクトobj1obj2eqなら(sxhash-eq obj1)(sxhash-eq obj2)は同じ整数になる。

Function: sxhash-eql obj

この関数はeqlによる比較に適したLispオブジェクトobjにたいするハッシュコードをリターンする。つまり浮動小数点数とbignum以外のobjなら、それにたいする識別値(浮動小数点数ならその値にたいするハッシュコード)を生成する。

2つのオブジェクトobj1obj2eqlなら(sxhash-eql obj1)(sxhash-eql obj2)は同じ整数になる。

以下はcaseを区別しない文字列のキーをもつハッシュテーブルを作成する例です。

(defun string-hash-ignore-case (a)
  (sxhash-equal (upcase a)))

(define-hash-table-test 'ignore-case
  'string-equal-ignore-case 'string-hash-ignore-case)

(make-hash-table :test 'ignore-case)

以下は事前に定義されたテスト値equalと等価なテストを行なうハッシュテーブルを定義できるという例です。キーは任意のLispオブジェクトで、equalに見えるオブジェクトは同じキーと判断されます。

(define-hash-table-test 'contents-hash 'equal 'sxhash-equal)

(make-hash-table :test 'contents-hash)

ハッシュ関数の実装はセッション間や異なるアークテクチャー間で変わる可能性のあるオブジェクトストレージのいくつかの詳細を使用するので、LispプログラムはEmacsセッションの間はハッシュコードが保存されることに依存するべきではありません


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

8.4 ハッシュテーブルのためのその他関数

以下はハッシュテーブルに作用する他の関数です。

Function: hash-table-p table

この関数はtableがハッシュテーブルオブジェクトなら非nilをリターンする。

Function: copy-hash-table table

この関数はtableのコピーを作成してリターンする。そのテーブル自体がコピーされたものである場合のみ、キーと値が共有される。

Function: hash-table-count table

この関数はtable内の実際のエントリー数をリターンする。

Function: hash-table-test table

この関数はハッシュを行なう方法と、キーを比較する方法を指定するために、table作成時に与えられたtestの値をリターンする。ハッシュテーブルの作成make-hash-tableを参照されたい。

Function: hash-table-weakness table

この関数はハッシュテーブルtableに指定されたweakの値をリターンする。

Function: hash-table-rehash-size table

この関数はtableのrehash-sizeをリターンする。

Function: hash-table-rehash-threshold table

この関数はtableのrehash-thresholdをリターンする。

Function: hash-table-size table

この関数はtableの現在の定義されたサイズをリターンする。


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

9 シンボル

シンボル(symbol)は一意な名前をもつオブジェクトです。このチャプターではシンボル、シンボルの構成要素とプロパティリスト、およびシンボルの作成とインターンする方法を説明します。別のチャプターではシンボルを変数として使用したり、関数名として使用する方法が説明されています。変数関数を参照してください。シンボルの正確な入力構文については、シンボル型を参照してください。

symbolpを使用して、任意のLispオブジェクトがシンボルかどうかをテストできます:

Function: symbolp object

この関数はobjectがシンボルならt、それ以外はnilをリターンする。


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

9.1 シンボルの構成要素

各シンボルは4つの構成要素(もしくは“セル”)をもち、構成要素はそれぞれ別のオブジェクトを参照します:

プリント名(print name)

そのシンボルの名前。

値(value)

変数としてのそのシンボルの現在値。

関数(function)

そのシンボルの関数定義。シンボル、キーマップ、キーボードマクロも保持できる。

プロパティリスト(property list)

そのシンボルのプロパティリスト。

プリント名のセルは常に文字列を保持し、それを変更することはできません。他の3つのセルには、任意のLispオブジェクトをセットすることができます。

プリント名のセルはシンボルの名前となる文字列を保持します。シンボルはシンボル名によりテキストとして表されるので、2つのシンボルが同じ名前をもたないことが重要です。Lispリーダーはシンボルを読み取るごとに、それを新規作成する前に、指定されたシンボルがすでに存在するかを調べます。シンボルの名前を得るには関数symbol-name(シンボルの作成とinternを参照)を使用します。しかしシンボルがそれぞれ一意なプリント名(print name)を1つだけもつとしても、“ショートハンド(shorthand)”と呼ばれる違うエイリアス名を通じて同じシンボルを参照することは可能です(ショートハンドを参照)。

値セルは変数としてのシンボルの値(そのシンボル自身がLisp式として評価されたときに得る値)を保持します。ローカルバインディング(local binding)スコーピングルール(scoping rules)等のような複雑なものを含めて、変数のセットや取得方法については変数を参照してください。ほとんどのシンボルは値として任意のLispオブジェクトをもつことができますが、一部の特別なシンボルは変更できない値をもちます。これらにはnilt、および名前が‘:’で始まるすべてのシンボル(キーワード(keyword)と呼ばれる)が含まれます。変更不可な変数を参照してください。

関数セルはシンボルの関数定義を保持します。実際はにはfooの関数セルの中に保管されている関数を意味するときに、“関数foo”といってそれを参照することがよくあります。わたしたちは必要なときだけ、これを明確に区別することにします。関数セルは通常は関数(関数を参照)か、マクロ(マクロを参照)を保持するために使用されます。しかし関数セルはシンボル(シンボル関数インダイレクションを参照)、キーボードマクロ(キーボードマクロを参照)、キーマップ(キーマップを参照)、またはオートロードオブジェクト(自動ロードを参照)を保持するためにも使用できます。シンボルの関数セルの内容を得るには、関数symbol-function (関数セルの内容へのアクセスを参照)を使用します。

プロパティリストのセルは、通常は正しくフォーマットされたプロパティリストを保持するべきです。シンボルのプロパティリストを得るには関数symbol-plistを使用します。シンボルのプロパティを参照してください。

マクロセルと値セルがvoid(空)のときもあります。voidとはそのセルがどのオブジェクトも参照していないことを意味します(これはシンボルvoidを保持するのともシンボルnilを保持するのとも異なる)。voidの関数セルまたは値セルを調べようとすると結果は‘Symbol's value as variable is void’のようなエラーとなります。

各シンボルは値セルと関数セルを別個にもつので、変数名と関数名が衝突することはありません。たとえばシンボルbuffer-file-nameが値(カレントバッファーでvisitされているファイルの名前)をもつと同様に、関数定義(ファイルの名前をリターンするプリミティブ関数)をもつことができます:

buffer-file-name
     ⇒ "/gnu/elisp/symbols-ja.texi"
(symbol-function 'buffer-file-name)
     ⇒ #<subr buffer-file-name>

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

9.2 シンボルの定義

定義(definition)とは、特別な方法での使用の意図を宣言する特別な種類のLisp式です。定義とは通常はシンボルにたいする値を指定するか、シンボルにたいする1つの種類の使用についての意味とその方法で使用する際のシンボルの意味のドキュメントを指定します。したがってシンボルを変数として定義すると、その変数の初期値に加えてその変数のドキュメントを提供できます。

defvardefconstグローバル変数(global variable) — Lispプログラムの任意の箇所からアクセスできる変数 — として定義するためのスペシャルフォームです。変数についての詳細は変数を参照してください。カスタマイズ可能な変数を定義するにはdefcustom (サブルーチンとしてdefvarも呼び出す)を使用します(カスタマイゼーション設定を参照)。

最初にシンボルが変数として定義されているかどうかに関わらず、原則としてsetqで任意のシンボルに値を割り当てることができます。しかし使用したいグローバル変数それぞれにたいして変数定義を記述するべきです。さもないとレキシカルスコープ(変数のバインディングのスコーピングルールを参照)が有効なときに変数が評価されると、Lispプログラムが正しく動作しないかもしれません。

defunはラムダ式(lambda expression)を生成して、そのシンボルの関数セルに格納することにより、そのシンボルを関数として定義します。したがってこのシンボルの関数定義は、そのラムダ式になります(関数セルの内容を意味する用語“関数定義(function definition)”は、defunがシンボルに関数としての定義を与えるというアイデアに由来する)。関数を参照してください。

defmacroはシンボルをマクロとして定義します。これはマクロオブジェクトを作成してシンボルの関数セルにそれを格納します。シンボルにはマクロと関数を与えることができますが、マクロと関数定義はどちらも関数セルに保持されるのにたいし、関数セルに保持できるのは常にただ1つのLispオブジェクトなので、一度に両方を行なうことはできないことに注意してください。マクロを参照してください。

前に注記したようにEmacs Lispではシンボルを(たとえばdefvarで)変数として定義して、同じシンボルを(たとえばdefunで)関数やマクロとして両方定義することができます。このような定義は衝突しません。

これらの定義は、プログラミングツールのガイドを果たすこともできます。たとえば、C-h fおよびC-h vコマンドは、関係ある変数、関数、マクロ定義へのリンクを含むヘルプバッファーを作成します。Name Help in The GNU Emacs Manualを参照してください。


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

9.3 シンボルの作成とintern

GNU Emacs Lispでシンボルが作成される方法を理解するには、Lispがシンボルを読み取る方法を理解しなければなりません。Lispは同じコンテキストで同じ文字シーケンスを読み取ったら、毎回同じシンボルを見つけることを保証しなければなりません。これに失敗すると、完全な混乱を招くでしょう。

ソースコード内でシンボルを参照する名前に出会うと、Lispリーダーはその名前の文字すべてを読み取ります。それからプログラマーが意図したシンボルを見つけるために、obarray(オブジェクト配列)と呼ばれるテーブルでその名前を照合します。この照合に使用されるテクニックは“ハッシュ化(hashing)”と呼ばれています。これは照合を行う際に文字シーケンスを“ハッシュコード(hash code)”として知られる数値に変換する効率的な手法です。たとえばJan Jonesを見つけるときは、電話帳を表紙から1頁ずつ探すのではなくJの頁から探し始めます。これはハッシュ化の簡単なバージョンです。obarrayの各要素は与えられたハッシュコードとともに、すべてのシンボルを保持するバケット(bucket)です。与えられた名前を探すためには、バケットの中からハッシュコードがその名前であるような、すべてのシンボルを探すのが効果的です(同じアイデアは一般的なEmacsのハッシュテーブルでも使用されていがこれらはデータ型が異なる。ハッシュテーブルを参照されたい)。

Lispリーダーは名前の照合時には“ショートハンド(shorthands 速記、簡略表記)”も考慮します。プログラマーがショートハンドを提供した場合には、たとえソースコード内でシンボル名が完全な形式で与えられなくても、リーダーはシンボルを見つけることができます。もちろんリーダーはそのようなショートハンドに関して事前に既定されたコンテキストを認識する必要があり、同様に“Jan”という名前だけでJan Jonesを一意に参照できるコンテキストが必要です。これはJonesの中にいるときや、Janが最近言及されていれば問題はないでしょうが、他の状況下では非常に曖昧です。ショートハンドを参照してください。

探している名前のシンボルが見つかったら、リーダーはそのシンボルを使用します。obarrayにその名前のシンボルが含まれなければ、リーダーは新しいシンボルを作成してそれをobarrayに追加します。特定の名前のシンボルを探して追加することをインターン(intern)と言い、これが行なわれた後はそのシンボルはインターンされたシンボル(interned symbol)と呼ばれます。

インターンすることによりある特定の名前のシンボルは、各obarrayに1つだけであることが保証されます。同じ名前のシンボルが他に存在するかもしれませんが、同じobarrayには存在しません。したがってリーダーは、(同じobarrayを読みつづける限り)同じ名前にたいして同じシンボルを取得します。

インターンは通常はリーダー内で自動的に発生しますが、他のプログラムがこれを行ないたい場合もあるかもしれません。たとえばM-xコマンドはその後にミニバッファーを使用してコマンド名を文字列として取得して、その文字列をインターンしてからインターンされたその名前のシンボルを得ます。別の例として、照合する人名それぞれをシンボル名としてインターンする架空の電話帳プログラムは、たとえそれがobarrayに含まれていなくても、誰かが最後にそれを照合した際に情報をアタッチできるようにする場合などです。

すべてのシンボルを含むobarrayはありません。実際にどのobarrayにも含まれないシンボルがいくつかあります。これらはインターンされていないシンボル(uninterned symbols)と呼ばれます。インターンされていないシンボルも、他のシンボルと同じく4つのセルをもちます。しかしインターンされていないシンボルへのアクセスを得る唯一の方法は、他の何らかのオブジェクトとして探すか、変数の値として探す方法だけです。インターンされていないシンボルはLispコード生成時に有用な場合があります。以下を参照してください。

Emacs Lispではobarrayはベクターです。ベクター内の各要素がバケットになります。要素の値は、名前がそのバケットにハッシュされるようなインターンされたシンボル、またはバケットが空のときは0です。インターンされたシンボルは、そのバケット内の次のシンボルへの内部リンク(ユーザーからは見えない)をもちます。これらのリンクは不可視なので、mapatoms (以下参照)を使用する方法をのぞき、obarray内のすべてのシンボルを探す方法はありません。バケット内のシンボルの順番に意味はありません。

空のobarrayではすべての要素が0なので、(make-vector length 0)でobarrayを作成することができます。obarrayを作成する有効な方法はこれだけです。長さに素数を指定するとよいハッシュ化がされる傾向があります。2の累乗から1減じた長さもよい結果を生む傾向があります。

自分でobarrayにシンボルを置かないでください。これはうまくいきません — obarrayに正しくシンボルを入力できるのはinternだけです。

Common Lispに関する注意: Common Lispとは異なりEmacs Lispでは複数の異なる“パッケージ”における同一の名前のインターンは提供されていないので、異なるパッケージごとに同じ名前のシンボルが複数作成される。Emacs Lispは“ショートハンド”と呼ばれる別の名前空間システムを提供する(ショートハンドを参照)。

以下の関数のほとんどは、引数に名前とobarrayをとります。名前が文字列以外、またはobarrayがベクター以外ならwrong-type-argumentエラーがシグナルされます。

Function: symbol-name symbol

この関数はsymbolの名前を文字列としてリターンする。たとえば:

(symbol-name 'foo)
     ⇒ "foo"

警告: この関数がリターンした文字列は絶対変更してはならない。これを行うことによってEmacsの機能が損なわれるかもしれず、Emacsのクラッシュすら招きかねない。

インターンされていないシンボルの作成は、Lispコードを生成するとき有用です。なぜなら作成されたコード内で変数として使用されているインターンされていないシンボルは、他のLispプログラムで使用されている任意の変数と競合することはありえないからです。

Function: make-symbol name

この関数は新たに割り当てられた、名前がname(文字列でなければならない)であるような、インターンされていないシンボルをリターンする。このシンボルの値と関数はvoidで、プロパティリストはnil。以下の例ではsymの値はfooeqではない。なぜならこれは名前が‘foo’という、インターンされていないシンボルだからである。

(setq sym (make-symbol "foo"))
     ⇒ foo
(eq sym 'foo)
     ⇒ nil
Function: gensym &optional prefix

この関数はmake-symbolを使用してprefixgensym-counterを付加した名前のシンボルをリターンする。更にこの関数を複数回呼び出しても同一名のシンボルが生成されないことを保証するためにカウンターを増加する。プレフィックスのデフォルトは"g"

意図せず生成したコードのプリント表現をインターンした際の問題を避けるために、make-symbolではなくgensymの使用をお勧めします。(プリント表現と読み取り構文を参照)。

Function: intern name &optional obarray

この関数は名前がnameであるような、インターンされたシンボルをリターンする。オブジェクト配列obarrayの中にそのようなシンボルが存在しなければ、internは新たにシンボルを作成してobarrayに追加してそれをリターンする。obarrayが省略されると、グローバル変数obarrayの値が使用される。

(setq sym (intern "foo"))
     ⇒ foo
(eq sym 'foo)
     ⇒ t

(setq sym1 (intern "foo" other-obarray))
     ⇒ foo
(eq sym1 'foo)
     ⇒ nil

Common Lispに関する注意: Common Lispでは既存のシンボルをobarrayにインターンできる。Emacs Lispではinternの引数はシンボルではなく文字列なのでこれを行なうことはできない。

Function: intern-soft name &optional obarray

この関数はobarray内の名前がnameのシンボル、obarrayにその名前のシンボルが存在しなければnilをリターンする。したがって与えられた名前のシンボルがすでにインターンされているかテストするために、intern-softを使用することができる。obarrayが省略されるとグローバル変数obarrayの値が使用される。

引数nameにはシンボルも使用できる。この場合、指定されたobarrayにnameがインターンされていればname、それ以外ならnilをリターンする。

(intern-soft "frazzle")        ; そのようなシンボルは存在しない
     ⇒ nil
(make-symbol "frazzle")        ; インターンされていないシンボルを作成する
     ⇒ frazzle
(intern-soft "frazzle")        ; そのようなシンボルは見つからない
     ⇒ nil
(setq sym (intern "frazzle"))  ; インターンされたシンボルを作成する
     ⇒ frazzle
(intern-soft "frazzle")        ; シンボルが見つかった!
     ⇒ frazzle
(eq sym 'frazzle)              ; そしてそれは同じシンボル
     ⇒ t
Variable: obarray

この変数はinternreadが使用する標準のobarrayである。

Function: mapatoms function &optional obarray

この関数はオブジェクト配列obarrayの中の各シンボルにたいして、functionを一度呼び出しその後nilをリターンする。obarrayが省略されると、通常のシンボルにたいする標準のオブジェクト配列obarrayの値がデフォルトになる。

(setq count 0)
     ⇒ 0
(defun count-syms (s)
  (setq count (1+ count)))
     ⇒ count-syms
(mapatoms 'count-syms)
     ⇒ nil
count
     ⇒ 1871

mapatomsを使用する他の例については、ドキュメント文字列へのアクセスdocumentationを参照のこと。

Function: unintern symbol obarray

この関数はオブジェクト配列obarrayからsymbolを削除する。obarrayの中にsymbolが存在しなければ、uninternは何も行なわない。obarraynilなら現在のobarrayが使用される。

symbolにシンボルではなく文字列を与えると、それはシンボルの名前を意味する。この場合、uninternは(もしあれば)obarrayからその名前のシンボルを削除する。そのようなシンボルが存在するならuninternは何も行なわない。

uninternがシンボルを削除したらt、それ以外はnilをリターンする。


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

9.4 シンボルのプロパティ

シンボルはそのシンボルについての様々な情報を記録するために使用される、任意の数のシンボルプロパティ(symbol properties)をもつことができます。たとえばシンボルのrisky-local-variableプロパティがnilなら、その変数の名前が危険なファイルローカル変数(ファイルローカル変数を参照)であることを意味します。

シンボルのプロパティとプロパティ値はそれぞれ、シンボルのプロパティリストセル(シンボルの構成要素を参照)に、プロパティリスト形式(プロパティリストを参照)で格納されます。


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

9.4.1 シンボルのプロパティへのアクセス

以下の関数を使用してシンボルプロパティにアクセスできます。

Function: get symbol property

この関数はsymbolのプロパティリスト内の、名前がpropertyというプロパティの値をリターンする。そのようなプロパティが存在しなければnilをリターンする。したがって値がnilのときとプロパティが存在しないときの違いはない。

名前propertyeqを使用して既存のプロパティと比較されるので、すべてのオブジェクトがプロパティとして適正である。

putの例を参照のこと。

Function: put symbol property value

この関数はsymbolのプロパティリストの、プロパティ名propertyvalueをputして、前のプロパティ値を置き換える。put関数はvalueをリターンする。

(put 'fly 'verb 'transitive)
     ⇒'transitive
(put 'fly 'noun '(a buzzing little bug))
     ⇒ (a buzzing little bug)
(get 'fly 'verb)
     ⇒ transitive
(symbol-plist 'fly)
     ⇒ (verb transitive noun (a buzzing little bug))
Function: symbol-plist symbol

この関数はsymbolのプロパティリストをリターンする。

Function: setplist symbol plist

この関数はsymbolのプロパティリストをplistにセットする。plistは通常は適正なプロパティリストであるべきだが、これは強制ではない。リターン値はplistです。

(setplist 'foo '(a 1 b (2 3) c nil))
     ⇒ (a 1 b (2 3) c nil)
(symbol-plist 'foo)
     ⇒ (a 1 b (2 3) c nil)

通常の用途には使用されない特別なobarray内のシンボルでは、非標準的な方法でプロパティリストセルを使用することに意味があるかもしれない。実際にabbrev(abbrevとabbrev展開を参照)のメカニズムでこれを行なっている。

以下のようにsetplistplist-putputを定義できる:

(defun put (symbol prop value)
  (setplist symbol
            (plist-put (symbol-plist symbol) prop value)))
Function: function-get symbol property &optional autoload

この関数はgetと等価だがsymbolが関数のエイリアス名なら。実際の関数を命名するシンボルのプロパティリストを照合する点が異なる。関数の定義を参照のこと。オプション引数autoloadが非nilで、symbolが自動ロードされていれば、その自動ロードによりsymbolpropertyがセットされるかもしれないので、この関数はそれの自動ロードを試みるだろう。autoloadがシンボルmacroなら、symbolが自動ロードされたマクロのときだけ自動ロードを試みる。

Function: function-put function property value

この関数はfunctionpropertyvalueをセットする。functionはシンボルであること。関数のプロパティのセットには、putよりこの関数を呼び出すほうがよい。この関数を使用すれば、いつか古いプロパティから新しいプロパティへのリマップを実装することができるからである。


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

9.4.2 シンボルの標準的なプロパティ

Emacsで特別な目的のために使用されるシンボルプロパティを以下に一覧します。以下のテーブルで、“命名される関数(the named function)”と言うときは、関数名がそのシンボルであるような関数を意味します。“命名される変数(the named variable)”等の場合も同様です。

:advertised-binding

このプロパティリストは、命名される関数のドキュメントを表示する際に優先されるキーバインディングを指定する。ドキュメント内でのキーバインディングの置き換えを参照のこと。

char-table-extra-slots

値が非nilなら、それは命名される文字テーブル型の追加スロットの数を指定する。文字テーブルを参照のこと。

customized-face
face-defface-spec
saved-face
theme-face

これらのプロパティはフェイスの標準のフェイス仕様(face specs)と、フォント仕様のsaved-face、customized-face、themed-faceを記録するために使用される。これらのプロパティを直接セットしないこと。これらのプロパティはdeffaceと関連する関数により管理される。フェイスの定義を参照のこと。

customized-value
saved-value
standard-value
theme-value

これらのプロパティは、カスタマイズ可能な変数のstandard-value、saved-value、customized-value(しかし保存はされない)、themed-valueを記録するために使用される。これらのプロパティを直接セットしないこと。これらはdefcustomと関連する関数により管理される。カスタマイゼーション変数の定義を参照のこと。

definition-name

このプロパティはソースファイルのテキスト検索ではシンボルの定義を見つけるのが困難な際に、ソースコードから定義を見つけるために使用される。たとえばdefine-derived-mode (派生モードの定義を参照)によってモード固有の関数や変数が暗黙裡に定義されたのかもしれないし、Lispプログラム実行時にdefunを呼び出して関数を定義したのかもしれない(関数の定義を参照)。このようなケースや類似したケースにおいては、そのシンボルのdefinition-nameプロパティはテキスト検索によって検索可能な定義をもち、そのコードによって元のシンボルを定義するような別のシンボルであることが必要になる。define-derived-modeの例では、定義される関数および変数にたいするこのプロパティの値がモードシンボルであることが必要になる。C-h f (Help in The GNU Emacs Manualを参照)のようなEmacsのヘルプコマンドでは、そのシンボルのドキュメントを表示する*Help*バッファーのボタンを通じてシンボルの定義を表示するためにこのプロパティが使用されている。

disabled

値が非nilなら命名される関数はコマンドとして無効になる。コマンドの無効化を参照のこと。

face-documentation

値には命名されるフェイスのドキュメント文字列が格納される。これはdeffaceにより自動的にセットされる。フェイスの定義を参照のこと。

history-length

値が非nilなら、命名されるヒストリーリスト変数のミニバッファーヒストリーの最大長を指定する。ミニバッファーのヒストリーを参照のこと。

interactive-form

この値は命名される関数のインタラクティブ形式である。通常はこれを直接セットするべきではない。かわりにスペシャルフォームinteractiveを使用すること。インタラクティブな呼び出しを参照されたい。

menu-enable

この値は命名されるメニューアイテムが、メニュー内で有効であるべきか否かを決定するための式である。単純なメニューアイテムを参照のこと。

mode-class

値がspecialなら命名されるメジャーモードはspecial(特別)である。メジャーモードの慣習を参照のこと。

permanent-local

値が非nilなら命名される変数はバッファーローカル変数となり、メジャーモードの変更によって変数の値はリセットされない。バッファーローカルなバインディングの作成と削除を参照のこと。

permanent-local-hook

値が非nilなら、命名される関数はメジャーモード変更時にフック変数のローカル値から削除されない。フックのセットを参照のこと。

pure

値が非nilの場合には、名づけられた関数は純粋(pure)だとみなされる。定数の引数で呼び出された場合には、コンパイル時に評価することができる。これは実行時のエラーをコンパイル時へとシフトする。純粋ストレージ(pure storage)と混同しないこと(純粋ストレージを参照)。

risky-local-variable

値が非nilなら、命名される変数はファイルローカル変数としては危険だとみなされる。ファイルローカル変数を参照のこと。

safe-function

値が非nilなら、命名される関数は評価において一般的に安全だとみなされます。安全に関数を呼び出せるかどうかの判断を参照のこと。

safe-local-eval-function

値が非nilなら、命名される関数はファイルローカルの評価フォーム内で安全に呼び出すことができる。ファイルローカル変数を参照のこと。

safe-local-variable

この値は命名される変数にたいして、ファイルローカル値が安全かを判断する関数を指定する。ファイルローカル変数を参照のこと。この値はファイルのロード時に参照されるので、指定する関数は効率的かつ安全性判断のために理想的にはライブラリーを何もロードしない(autoload関数にしない)ようにする必要がある。

side-effect-free

nil値は命名される関数が副作用(関数とは?を参照)をもたないことを示すので、バイトコンパイラーは値が使用されない呼び出しを無視する。このプロパティの値がerror-freeなら、バイトコンパイラーはそのような呼び出しの削除すら行うかもしれない。バイトコンパイラーの最適化に加えて、このプロパティは関数の安全性を判断するためにも使用される(安全に関数を呼び出せるかどうかの判断を参照)。

undo-inhibit-region

nilの場合には、命名される関数の直後にundoが呼び出されると、undo操作をアクティブなリージョンに限定することを抑止する。アンドゥを参照のこと。

variable-documentation

nilなら、それは命名される変数のドキュメント文字列を指定する。ドキュメント文字列はdefvarと関連する関数により自動的にセットされる。フェイスの定義を参照のこと。


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

9.5 ショートハンド

“名前変更シンボル(renamed symbols)”と呼ばれることもあるシンボルのショートハンド(shorthands: 速記、簡略表記)とは、Lispソースで目にする抽象形式です。これらは正規の抽象形式と類似していますが、Lispリーダーがそれらに遭遇した際に別の通常はもっと長いプリント名(print name)を生成する点が異なリます(シンボルの構成要素を参照)。

ショートハンドを意図するシンボルの完全名にたいする略語(abbreviating)と考えることは有益です。その点を除けばAbbrevシステム(abbrevとabbrev展開を参照)とショートハンドを混同しないでください。

ショートハンドによりEmacs Lispのネームスペース作法(namespacing etiquette)にしたがうことが容易になります。すべてのシンボルは単一のobarray (シンボルの作成とinternを参照)に格納されるので、一般的にプログラマーはシンボル名それぞれにたいして出自ライブラリー名をプレフィクスとして付加します。たとえば関数text-property-search-forwardtext-property-search-backwardはどちらもtext-property-search.elライブラリーに属しています(ロードを参照)。シンボル名に正しくプレフィクスを付加することによって、異なるライブラリーに属する別のことを行う同一名シンボル間でのクラッシュを効果的に回避できます。しかしこれを実践してしばらくすると、一般的にはタイプしにくく読み難い、非常に長いシンボル名となります。これらの問題をショートハンドは明快な方法により解決します。

Variable: read-symbol-shorthands

この変数の値は要素が(shorthand-prefix . longhand-prefix)という形式であるようなalist。それぞれの要素はLispリーダーにたいして、shorthand-prefixで始まるすべてのシンボルを、longhand-prefixで始まるシンボルとして読み取るよう指示する。

この変数はファイルローカル変数としてのみセットできる(Local Variables in Files in The GNU Emacs Manualを参照)。

以下は架空の文字列操作ライブラリーsome-nice-string-utils.elでショートハンドを使用する例です。

(defun some-nice-string-utils-split (separator s &optional omit-nulls)
  "match-dataを保存する`split-string'の変種"
  (save-match-data (split-string s separator omit-nulls)))

(defun some-nice-string-utils-lines (s)
  "文字列Sを改行文字で分割して文字列リストにする"
  (some-nice-string-utils-split "\\(\r\n\\|[\n\r]\\)" s))

見ての通りタイプするシンボル名が非常に長いので、このコードを読んだり開発するのはとても退屈です。これの緩和にショートハンドが使用できます。

(defun snu-split (separator s &optional omit-nulls)
  "match-dataを保存する`split-string'の変種"
  (save-match-data (split-string s separator omit-nulls)))

(defun snu-lines (s)
  "文字列Sを改行文字で分割して文字列リストにする"
  (snu-split "\\(\r\n\\|[\n\r]\\)" s))

;; Local Variables:
;; read-symbol-shorthands: (("snu-" . "some-nice-string-utils-"))
;; End:

この2つの例が異なるように見えても、これらをLispリーダーが処理した後はまったく同じです。どちらもインターン(シンボルの作成とinternを参照)される同一のシンボルへと導かれます。したがって2つのファイルのどちらをバイトコンパイルしても、同じ結果が得られます。2つ目のバージョンのショートハンドsnu-splitsnu-linesはobarrayにインターンされません。これはショートハンド使用箇所にポイントを移動して、ポイント位置のシンボルの真のシンボル名のヒントをElDoc (Local Variables in Files in The GNU Emacs Manualを参照)がエコーエリアに表示するのを待つことで容易に確認できます。

read-symbol-shorthandsはファイルローカル変数なので、some-nice-string-utils-lines.elに依存する複数のライブラリーが同一のシンボルを異なるショートハンドで参照したり、あるいはショートハンドをまったく使用せずに参照することが可能になります。次の例ではmy-tricks.elライブラリーがsnu-ではなく、sns-というプレフィクスを使用してシンボルsome-nice-string-utils-linesを参照しています。

(defun t-reverse-lines (s) (string-join (reverse (sns-lines s)) "\n")

;; Local Variables:
;; read-symbol-shorthands: (("t-" . "my-tricks-")
;;                          ("sns-" . "some-nice-string-utils-"))
;; End:

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

9.5.1 例外

ショートハンド変換適用を管理するにあたって2つの例外があります:

  • Emacs Lispシンボル構成クラス(構文クラスのテーブルを参照)の文字だけでシンボルフォーム全体が形成される場合には変換されない。たとえば-/=をショートハンドプレフィクスとして使用するのは可能だが、それらの名前は算術の関数をシャドーしない。
  • 名前が‘#_’で始まるシンボルフォームは変換されない。

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

9.6 位置をもつシンボル

位置つきシンボル(symbol with position)とはbareシンボル(bare symbol: 裸のシンボル)位置(position)と呼ばれる符号なし整数を合わせたシンボルのことです。これらのオブジェクトはバイトコンパイラーによって使用されます。バイトコンパイラーはシンボルそれぞれの出現位置を記録して、警告メッセージやエラーメッセージでそれらの位置を使用します。

位置つきシンボルのプリント表現には、プリント表現と読み取り構文で概説したハッシュ表記が使用されます。‘#<symbol foo at 12345>’のようなプリント表現であり、入力構文はありません。プリント操作の前後で変数print-symbols-bareを非nilにバインドすれば、bareシンボルだけをプリントさせることができます。バイトコンパイラーはコンパイル済みLispファイルへ書き込む前にこれを行っています。

フラグ変数symbols-with-pos-enabledが非nilであっても、ほとんどの用途にたいして位置つきシンボルはbareシンボルと同じように動作します。たとえばこの変数がセットされている場合には、‘(eq #<symbol foo at 12345> foo)’の値はtになります(ただしセットされていなければnil)。Emacsではほとんどの場合この変数はnilですが、バイトコンパイラーの実行時にはtにバインドされます。

位置つきシンボルは通常はバイトコンパイラーがリーダー関数read-positioning-symbolsを呼び出すことによって作成されます(入力関数を参照)が、関数position-symbolによって作成することもできます。

Variable: symbols-with-pos-enabled

この変数が非nilの際には、位置つきシンボルはそれに内包されているbareシンボルと同様に振る舞う。この場合にはEmacsの実行が少しだけ遅くなる。

Variable: print-symbols-bare

nilにバインドされていると、Lispプリンターは位置つきシンボルの位置は無視してbareシンボルだけをプリントする。

Function: symbol-with-pos-p symbol.

この関数はsymbolがシンボルならt、それ以外はnilをリターンする。

Function: bare-symbol symbol

この関数はsymbolに含まれるbareシンボル、symbolがすでにbareシンボルならsymbol自体をリターンする。それ以外のタイプのオブジェクトの場合にはエラーをシグナルする。

Function: symbol-with-pos-pos symbol

この関数は位置つきシンボルの位置(数値)をリターンする。それ以外のタイプのオブジェクトの場合にはエラーをシグナルする。

Function: position-symbol sym pos

位置つきシンボルを新たに作成する。symはbareシンボルか位置つきシンボルで、これは新たなオブジェクトにたいしてシンボル部分を提供する。posは整数(新オブジェクトの数値部分となる)、あるいは位置つきシンボル(このシンボルの位置を使用)のいずれか。引数のいずれかが無効であればEmacsはエラーをシグナルする。


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

10 評価

Emacs Lispでの式の評価(evaluation)は、Lispインタープリター — 入力としてLispオブジェクトを受け取り、それの式としての値(value as an expression)を計算する — により処理されます。評価を行なう方法はそのオブジェクトのデータ型に依存していて、それはこのチャプターで説明するルールにより行なわれます。インタープリターはプログラムの一部を評価するために自動的に実行されますが、Lispプリミティブ関数のevalを通じて明示的に呼び出すこともできます。


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

10.1 評価の概要

Lispインタープリター(またはLispエバリュエーター)はEmacsの一部であり、与えられた式の値を計算します。Lispで記述された関数が呼び出されると、エバリュエーターはその関数のbody(本文)の中の式を評価してその関数の値を計算します。したがってLispプログラムを実行するとは、実際にはLispインタープリターを実行することを意味します。

評価を意図したLispオブジェクトはフォーム(form)、または式(expression)と呼ばれます7。フォームはデータオブジェクトであって単なるテキストではないという事実は、Lisp風の言語と通常のプログラミング言語との間にある基本的な相違点の1つです。任意のオブジェクトを評価できますが、実際に評価される事が非常に多いのは数字、シンボル、リスト、文字列です。

以降のセクションでは、各種フォームにたいしてそれを評価することが何を意味するかの詳細を説明します。

Lispフォームを読み取ってそのフォームを評価するのは、非常に一般的なアクティビティーですが、読み取りと評価は別のアクティビティーであって、どちらか一方を単独で処理することができます。読み取っただけでは何も評価されません。読み取りはLispオブジェクトのプリント表現をそのオブジェクト自体に変換します。そのオブジェクトが評価されるべきフォームなのか、それともまったく違う目的をもつかを指定するのは、readの呼び出し元の役目です。入力関数を参照してください。

評価とは再帰的な処理であり、あるフォームを評価するとそのフォームの一部が評価されるといったことがよくあります。たとえば(car x)のような関数呼び出し(function call)のフォームを評価する場合、Emacsは最初にその引数(サブフォーム x)を評価します。引数を評価した後、Emacsはその関数(car)を実行(executes)します。その関数がLispで記述されていれば、関数のbody(本文)を評価することによって実行が行なわれます(しかしこの例で使用しているcarはLisp関数ではなくCで実装されたプリミティブ関数である)。関数と関数呼び出しについての情報は関数を参照してください。

評価は環境(environment)と呼ばれるコンテキストの内部で行なわれます。環境はすべてのLisp変数(変数を参照)のカレント値とバインディングにより構成されます。8フォームが新たなバインディングを作成せずに変数を参照する際、その変数はカレントの環境から与えられる値へと評価されます。フォームの評価は、変数のバインディングによって一時的にその環境を変更することもあります(ローカル変数を参照)。

フォームの評価が永続する変更を行なうこともあります。これらの変更は副作用(side effects)と呼ばれます。副作用を生成するフォームの例は(setq foo 1)です。

コマンドキー解釈での評価と混同しないでください。エディターのコマンドループはアクティブなキーマップを使用して、キーボード入力をコマンド(インタラクティブに呼び出すことができる関数)に変換してからそのコマンドを実行するために、call-interactivelyを使用します。そのコマンドがLispで記述されていれば、そのコマンドの実行には通常は評価を伴います。しかしこのステップはコマンドキー解釈の一部とは考えません。コマンドループを参照してください。


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

10.2 フォームの種類

評価される事を意図したLispオブジェクトはフォーム(form)、または式(expression))と呼ばれます。Emacsがフォームを評価する方法はフォームのデータ型に依存します。Emacsは3種の異なるフォーム — シンボル、リスト、およびその他すべての型 — をもち、それらが評価される方法は異なります。このセクションではまず最初に自己評価フォームのその他の型から開始して、3つの種類をすべて1つずつ説明します。


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

10.2.1 自己評価を行うフォーム

自己評価フォーム(self-evaluating form)はリストやシンボルではないすべてのフォームです。自己評価フォームはそのフォーム自身を評価します。評価の結果は評価されたオブジェクトと同じです。したがって数字の25は25、文字列"foo"は文字列"foo"に評価されます。同様にベクターの評価では、ベクターの要素の評価は発生しません — 内容が変更されずに同じベクターがリターンされます。

'123               ; 評価されずに表示される数字
     ⇒ 123
123                ; 通常どおり評価され、同じものがreturnされる
     ⇒ 123
(eval '123)        ; 手動での評価 — 同じものがreturnされる
     ⇒ 123
(eval (eval '123)) ; 2度評価しても何も変わらない。
     ⇒ 123

自己評価フォームはプログラムの一部となる値を生成します。これをsetcaraset、その他の類似操作を通じて変更しようと試みるべきではありません。Lispインタープリターがプログラム中の自己評価フォームにより生成される定数を統合して、これらの定数が構造を共有するかもしれません。可変性を参照してください。

自己評価されるという事実による利点から数字、文字、文字列、そしてベクターでさえLispコード内で記述されるのが一般的です。しかし入力構文がない型にたいしてこれを行なうのは極めて異例です。なぜなら、これらをテキスト的に記述する方法がないからです。Lispプログラムを使用してこれらの型を含むLisp式を構築することは可能です。以下は例です:

;; バッファーオブジェクトを含む式を構築する。
(setq print-exp (list 'print (current-buffer)))
     ⇒ (print #<buffer eval-ja.texi>)
;; それを評価する。
(eval print-exp)
     -| #<buffer eval-ja.texi>
     ⇒ #<buffer eval-ja.texi>

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

10.2.2 シンボルのフォーム

シンボルが評価されるときは変数として扱われます。それが値をもつなら結果はその変数の値になります。そのシンボルが変数としての値をもたなければ、Lispインタープリターはエラーをシグナルします。変数の使用法についての情報は変数を参照してください。

以降の例ではsetqでシンボルに値をセットしています。その後シンボルを評価してからをsetqに戻します。

(setq a 123)
     ⇒ 123
(eval 'a)
     ⇒ 123
a
     ⇒ 123

シンボルniltは特別に扱われるので、nilの値は常にniltの値は常にtになります。これらに他の値をセットしたり、他の値にバインドすることはできません。したがってこの2つのシンボルは、(たとえevalがそれらを他の任意のシンボルと同様に扱うとはいえ)自己評価フォームと同じように振る舞います。名前が‘:’で始まるシンボルも同じ方法で自己評価されます。そして、(通常は)値を変更できない点も同じです。変更不可な変数を参照してください。


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

10.2.3 リストフォームの分類

空ではないリストフォームは関数呼び出し、マクロ呼び出し、スペシャルフォームのいずれかで、それは1番目の引数にしたがいます。これら3種のフォームは、以下で説明するように異なる方法で評価されます。残りの要素は関数、マクロ、またはスペシャルフォームにたいする引数(arguments)を構成します。

空ではないリストを評価する最初のステップは、1番目の要素の確認です。この要素は単独でそのリストがどの種類のフォームなのかと、残りの引数をどのように処理するがを決定します。SchemeのようなLisp方言とは異なり、1番目の要素は評価されません。


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

10.2.4 シンボル関数インダイレクション

リストの最初の要素がシンボルなら、評価はそのシンボルの関数セルを調べて、元のシンボルの代わりに関数セルの内容を使用します。その内容が他のシンボルなら、シンボルではないものが得られるまでこのプロセスが繰り返されます。このプロセスのことをシンボル関数インダイレクション(symbol function indirection: indirectionは間接の意)と呼びます。シンボル関数インダイレクションについての情報は関数の命名を参照してください。

このプロセスの結果、シンボルの関数セルが同じシンボルを参照する場合には、無限ループを起こす可能性があります。それ以外なら最終的には非シンボルにたどりつき、それは関数か他の適切なオブジェクトである必要があります。

適切なオブジェクトとは、より正確にはLisp関数(ラムダ式)、バイトコード関数、プリミティブ関数、Lispマクロ、スペシャルフォーム、またはオートロードオブジェクトです。これらそれぞれの型については以降のセクションで説明します。これらの型以外のオブジェクトならEmacsはinvalid-functionエラーをシグナルします。

以下の例はシンボルインダイレクションのプロセスを説明するものです。わたしたちはシンボルの関数セルへの関数のセットにfset、関数セルの内容(関数セルの内容へのアクセスを参照)の取得にsymbol-functionを使用します。具体的にはfirstの関数セルにシンボルcarを格納して、シンボルfirstersteの関数セルに格納します。

;; この関数セルのリンクを構築する:
;;   -------------       -----        -------        -------
;;  | #<subr car> | <-- | car |  <-- | first |  <-- | erste |
;;   -------------       -----        -------        -------
(symbol-function 'car)
     ⇒ #<subr car>
(fset 'first 'car)
     ⇒ car
(fset 'erste 'first)
     ⇒ first
(erste '(1 2 3))   ; ersteにより参照される関数を呼び出す
     ⇒ 1

対照的に、以下の例ではシンボル関数インダイレクションを使用せずに関数を呼び出しています。なぜなら1番目の要素はシンボルではなく、無名Lisp関数(anonymous Lisp function)だからです。

((lambda (arg) (erste arg))
 '(1 2 3))
     ⇒ 1

関数自身を実行するとその関数のbodyを評価します。ここではersteを呼び出すとき、シンボル関数インダイレクションが行なわれています。

このフォームが使用されるのは稀であり、現在では推奨されていません。かわりに以下のように記述するべきです:

(funcall (lambda (arg) (erste arg))
         '(1 2 3))

または単に

(let ((arg '(1 2 3))) (erste arg))

ビルトイン関数のindirect-functionは、明示的にシンボル関数インダイレクションを処理するための簡単な方法を提供します。

Function: indirect-function function &optional noerror

この関数はfunctionが意味するものを関数としてリターンする。functionがシンボルならfunctionの関数定義を探して、その値で最初からやり直す。functionがシンボルでなければfunction自身をリターンする。

この関数は最終的なシンボルがバインドされていなければnilをリターンする。特定のシンボル内にループがあれば、この関数はcyclic-function-indirectionエラーをシグナルする。

オペション引数noerrorは廃れており、後方互換のためだけのもので効果はない。

以下はLispでindirect-functionを定義する例である:

(defun indirect-function (function)
  (if (and function
           (symbolp function))
      (indirect-function (symbol-function function))
    function))

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

10.2.5 関数フォームの評価

リストの1番目の要素がLispの関数オブジェクト、バイトコードオブジェクト、プリミティブ関数オブジェクトのいずれかと評価されると、そのリストは関数呼び出し(function call)になります。たとえば、以下は関数+を呼び出します:

(+ 1 x)

関数呼び出しを評価する最初のステップでは、そのリストの残りの要素を左から右に評価します。結果は引数の実際の値で、リストの各要素にたいして1つの値となります。次のステップでは関数apply(関数の呼び出しを参照)を使用して、引数のリストでその関数を呼び出します。関数がLispで記述されていたら引数はその関数の引数変数にバインドするために使用されます。その後に関数body内のフォームが順番に評価されて、リストのbodyフォームの値が関数呼び出しの値になります。


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

10.2.6 Lispマクロの評価

リストの最初の要素がマクロオブジェクトと評価されると、そのリストはマクロ呼び出し(macro call)になります。マクロ呼び出しが評価されるとき、リストの残りの要素は最初は評価されません。そのかわりこれらの要素自体がマクロの引数に使用されます。そのマクロ定義は、元のフォームが評価される場所で置換フォームを計算します。これをマクロの展開(expansion)と言います。展開した結果は、任意の種類のフォーム — 自己評価定数、シンボル、リストになります。展開した結果自体がマクロ呼び出しなら、結果が他の種類のフォームになるまで、繰り返し展開処理が行なわれます。

通常のマクロ展開は、その展開結果を評価することにより終了します。しかし他のプログラムもマクロ呼び出しを展開し、それらが展開結果を評価するか、あるいは評価しないかもしれないので、そのマクロ展開が即時または最終的に評価される必要がない場合があります。

引数式は通常はマクロ展開の計算の一部としては評価されませんが、展開の部分として出現するので、展開結果が評価されるときに計算されます。

たとえば以下のようなマクロ定義が与えられたとします:

(defmacro cadr (x)
  (list 'car (list 'cdr x)))

(cadr (assq 'handler list))のような式はマクロ呼び出しであり、展開結果は以下のようになります:

(car (cdr (assq 'handler list)))

引数(assq 'handler list)が展開結果に含まれることに注意してください。

Emacs Lispマクロの完全な説明はマクロを参照してください。


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

10.2.7 スペシャルフォーム

スペシャルフォーム(special form)とは、特別だとマークされたプリミティブであり、引数がすべて評価される訳ではありません。もっとも特別なフォームは制御構文の定義や変数バインディングの処理等、関数ではできないことを行ないます。

スペシャルフォームはそれぞれ、どの引数を評価して、どの引数を評価しないかについて独自のルールをもちます。特定の引数が評価されるかどうかは、他の引数を評価した結果に依存します。

式の最初のシンボルがスペシャルフォームなら、式はそのスペシャルフォームのルールにしたがう必要があります。それ以外ならEmacsの挙動は(たとえクラッシュしてないとしても)未定義です。たとえば((lambda (x) x . 3) 4)lambdaで始まるサブ式を含みますが、これは適正なlambda式ではないので、Emacsはエラーをシグナルするかもしれないし、3や4やnilをリターンしたり、もしかしたら他の挙動を示すかもしれません。

Function: special-form-p object

この述語は引数がスペシャルフォームかをテストして、スペシャルフォームならt、それ以外ならnilをリターンする。

以下にEmacs Lispのスペシャルフォームすべてと、それらがどこで説明されているかのリファレンスをアルファベット順でリストします。

and

see 組み合わせ条件の構築

catch

see 明示的な非ローカル脱出: catchthrow

cond

see 条件

condition-case

see エラーを処理するコードの記述

defconst

see グローバル変数の定義

defvar

see グローバル変数の定義

function

see 無名関数

if

see 条件

interactive

see インタラクティブな呼び出し

lambda

see ラムダ式

let
let*

see ローカル変数

or

see 組み合わせ条件の構築

prog1
prog2
progn

see 順序

quote

see クォート

save-current-buffer

see カレントバッファー

save-excursion

see エクスカーション

save-restriction

see ナローイング

setq

see 変数の値のセット

setq-default

see バッファーローカルなバインディングの作成と削除

unwind-protect

see 非ローカル脱出

while

see 繰り返し

Common Lispに関する注意: GNU EmacsとCommon Lispのスペシャルフォームを比較する。setqifcatchはEmacs LispとCommon Lispの両方でスペシャルフォームである。save-excursionはEmacs Lispではスペシャルフォームだが、Common Lispには存在しない。throwはCommon Lispではスペシャルフォーム(なぜなら複数の値をthrowできなければならない)だが、Emacs Lispでは(複数の値をもたない)関数である。


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

10.2.8 自動ロード

オートロード(autoload)機能により、まだ関数定義がEmacsにロードされていない関数(またはマクロ)を呼び出すことができます。オートロードは定義がどのファイルに含まれるかを指定します。オートロードオブジェクトがシンボルの関数定義にある場合は、関数としてそのシンボルを呼び出すことにより、自動的に指定されたファイルがロードされます。その後にファイルからロードされた実際の定義を呼び出します。シンボル内の関数定義としてオートロードオブジェクトをアレンジする方法はautoloadで説明します。


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

10.3 クォート

スペシャルフォームquoteは、単一の引数を記述されたままに評価せずにリターンします。これはプログラムに自己評価オブジェクトではない、定数シンボルや定数リストを含める方法を提供します(数字、文字列、ベクターのような自己評価オブジェクトをクォートする必要はない)。

Special Form: quote object

このスペシャルフォームはobjectを評価せずにリターンする。リターン値は共有されるかもしれないので変更しないこと。自己評価を行うフォームを参照のこと。

quoteはプログラム中で頻繁に使用されるので、Lispはそれにたいする便利な入力構文を提供します。アポストロフィー文字(‘'’)に続けてLispオブジェクト(の入力構文)を記述すると、それは1番目の要素がquote、2番目の要素がそのオブジェクトであるようなリストに展開されます。つまり入力構文'x(quote x)の略記になります。

以下にquoteを使用した式の例をいくつか示します:

(quote (+ 1 2))
     ⇒ (+ 1 2)
(quote foo)
     ⇒ foo
'foo
     ⇒ foo
''foo
     ⇒ 'foo
'(quote foo)
     ⇒ 'foo
['foo]
     ⇒ ['foo]

(list '+ 1 2)'(+ 1 2)の2つの式はいずれも(+ 1 2)とequalなリストを生成しますが前者はmutableリストを新たに作成するのにたいして、後者は共有される可能性のある変更すべきではないコンスから構築したリストを作成します。自己評価を行うフォームを参照してください。

他のクォート構文としては、コンパイル用にLispで記述された無名のラムダ式の元となるfunction (無名関数を参照)、リストを計算して置き換える際にリストの一部だけをクォートするために使用される‘`’(バッククォートを参照)があります。


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

10.4 バッククォート

バッククォート構文(backquote constructs)を使用することにより、リストをクォートしてそのリストのある要素を選択的に評価することができます。もっとも単純な場合、スペシャルフォーム quote (前セクションで説明済み。クォートを参照)と同じになります。 たとえば以下の2つのフォームは同じ結果を生みます:

`(a list of (+ 2 3) elements)
     ⇒ (a list of (+ 2 3) elements)
'(a list of (+ 2 3) elements)
     ⇒ (a list of (+ 2 3) elements)

バッククォートする引数の内側でスペシャルマーカー‘,’を使用すると、それは値が定数でないことを示します。Emacs Lispエバリュエーターは‘,’がついた引数を放置して、リスト構文内にその値を配置します:

`(a list of ,(+ 2 3) elements)
     ⇒ (a list of 5 elements)

,’による置き換えを、リスト構文のより深いレベルでも使用できます。たとえば:

`(1 2 (3 ,(+ 4 5)))
     ⇒ (1 2 (3 9))

スペシャルマーカー‘,@’を使用すれば、評価された値を結果リストに継ぎ足す(splice)こともできます。継ぎ足されたリストの要素は、結果リスト内の他の要素と同じレベルになります。‘`’を使用しない等価なコードは読むのが困難なことがよくあります。以下にいくつかの例を示します:

(setq some-list '(2 3))
     ⇒ (2 3)
(cons 1 (append some-list '(4) some-list))
     ⇒ (1 2 3 4 2 3)
`(1 ,@some-list 4 ,@some-list)
     ⇒ (1 2 3 4 2 3)

(setq list '(hack foo bar))
     ⇒ (hack foo bar)
(cons 'use
  (cons 'the
    (cons 'words (append (cdr list) '(as elements)))))
     ⇒ (use the words foo bar as elements)
`(use the words ,@(cdr list) as elements)
     ⇒ (use the words foo bar as elements)

バッククォート構文の部分式に置換や継ぎ足し(splice)がなければ、これは共有される可能性があり変更するべきではないコンス、ベクター、文字列でのquoteのように振る舞います。自己評価を行うフォームを参照してください。


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

10.5 evalについて

フォームはほとんどの場合、実行されるプログラム内に出現することにより自動的に評価されます。ごく稀に実行時 — たとえば編集されているテキストやプロパティリストから取得したフォームを読み取った後 — に計算されるようにフォームを評価するコードを記述する必要があるかもしれません。このようなときはeval関数を使用します。evalが不必要だったり、かわりに他の何かを使用すべきときがよくあります。たとえば変数から値を取得するにはevalも機能しますが、symbol-valueのほうが適しています。evalで評価するためにプロパティリストに式を格納するかわりに、funcallに渡すように関数を格納した方がよいでしょう。

このセクションで説明する関数と変数はフォームの評価、評価処理の制限の指定、最後にリターンされた値の記録を行なうものです。ファイルのロードでも評価が行なわれます(ロードを参照)。

データ構造に式を格納して評価するより、データ構造に関数を格納してfuncallapplyで呼び出すほうが、より明解で柔軟です。関数を使用することにより、引数に情報を渡す能力が提供されます。

Function: eval form &optional lexical

これは式を評価する基本的な関数である。この関数はカレント環境内でformを評価して、その結果をリターンする。formオブジェクトの型はそれが評価される方法を決定します。フォームの種類を参照のこと。

引数lexicalは、ローカル変数にたいするスコープ規則(変数のバインディングのスコーピングルールを参照)を指定する。これが省略またはnilならデフォルトのダイナミックスコープ規則を使用してformを評価することを意味する。tならレキシカルスコープ規則が使用されることを意味する。lexicalの値にはレキシカルバインディングでの特定のレキシカル環境(lexical environment)を指定する空ではないalistも指定できる。しかしこの機能はEmacs Lispデバッガーのような、特別な用途にたいしてのみ有用。レキシカルバインディングを参照のこと。

evalは関数なのでeval呼び出しに現れる引数式は2回 — evalが呼び出される前の準備で一度、eval関数自身によりもう一度 — 評価される。以下に例を示す:

(setq foo 'bar)
     ⇒ bar
(setq bar 'baz)
     ⇒ baz
;; evalが引数fooを受け取る
(eval 'foo)
     ⇒ bar
;; evalが、fooの値である、引数barを受け取る
(eval foo)
     ⇒ baz

evalで現在アクティブな呼び出しの数はmax-lisp-eval-depthに制限される(以下参照)。

Command: eval-region start end &optional stream read-function

この関数はカレントバッファー内の、位置startendで定義されるリージョン内のフォームを評価する。この関数はリージョンからフォームを読み取ってevalを呼び出す。これはリージョンの最後に達するか、処理されないエラーがシグナルされるまで行なわれる。

デフォルトではeval-regionは出力を何も生成しない。しかしstreamが非nilなら出力関数(出力関数を参照)で生成された任意の出力、同様にリージョン内の式を評価した結果の値が、streamを使用してプリントされる。出力ストリームを参照のこと。

read-functionが非nilなら、readのかわりに1つずつ式を読み取るために使用する関数を指定すること。これは入力を読み取るストリームを指定する、1つの引数で呼び出される関数である。この関数を指定するために変数load-read-function(How Programs Do Loadingを参照)も使用できるが、引数read-functionを使用するほうが堅実である。

eval-regionはポイントを移動しない。常にnilをリターンする。

Command: eval-buffer &optional buffer-or-name stream filename unibyte print

この関数はeval-regionと似ているが、引数は異なるオプション機能を提供する。eval-bufferはバッファーbuffer-or-nameのアクセス可能な部分(Narrowing in The GNU Emacs Manualを参照)の全体を処理する。buffer-or-nameにはバッファー名(文字列)を指定でき、nil(または省略)のときはカレントバッファーを意味する。streamが非nil、またはprintnilなら、eval-regionのようにstreamが使用される。この場合には式の評価結果の値は依然として破棄されるが、出力関数による出力はエコーエリアにプリントされる。filenameload-history (アンロードを参照)に使用されるファイル名であり、デフォルトはbuffer-file-name (バッファーのファイル名を参照)。unibyteが非nilならread可能な限りは文字列をユニコードに変換する。

User Option: max-lisp-eval-depth

この変数はエラー(エラーメッセージは"Lisp nesting exceeds max-lisp-eval-depth")がシグナルされる前にevalapplyfuncallの呼び出しで許容される最大の深さを定義する。

超過した際にエラーを起こすこの制限は、誤って定義された関数による無限再帰をEmacs Lispが回避するための手段として用いられる。max-lisp-eval-depthの値を過大に増加させると、そのようなコードはかわりにスタックオーバーフローを起こすだろう。オーバーフローを処理できるシステムがいくつかある。この場合には通常のLisp評価は割り込まれて、制御はトップレベルのコマンドループ(top-level)に戻される。この状況ではEmacs Lispデバッガにエンターする手段は存在しないことに注意されたい。エラーによるデバッガへのエンターを参照のこと。

Lisp式に記述された関数の呼び出し、関数呼び出しの引数と関数bodyフォームにたいする再帰評価、Lispコード内での明示的な呼び出し等では内部的にevalapplyfuncallを使用して深さ制限を計数する。

この変数のデフォルト値は1600。この値を100未満にセットした場合には、値が与えられた値に達するとLispはそれを100にリセットする。空きが少なければデバッガー自身を実行するために空きが必要になるので、Lispデバッガーに入ったときは値が増加される。

Variable: values

この変数の値は読み取り、評価、プリントを行なった標準的なEmacsコマンドにより、バッファー(ミニバッファーを含む)からリターンされる値のリストである(これには*ielm*バッファーでの評価、lisp-interaction-modeでのC-jC-x C-e、類似の評価コマンドを使用した評価は含まれないことに注意)。

この変数は時代遅れでありEmacsプロセスのメモリーフットプリントを常に増加させるため、将来のバージョンでは削除されるだろう。この理由により使用を推奨しない。

valuesの要素の順序はもっとも最近の要素が最初になる。

(setq x 1)
     ⇒ 1
(list 'A (1+ 2) auto-save-default)
     ⇒ (A 3 t)
values
     ⇒ ((A 3 t) 1 …)

この変数は最近評価されたフォームの値を後で参照するのに有用かもしれない。values自体の値のプリントは、値がおそらく非常に長くなるので通常は悪いアイデアである。かわりに以下のように特定の要素を調べること:

;; もっとも最近評価された結果を参照する
(nth 0 values)
     ⇒ (A 3 t)
;; これは新たな要素をputするので
;;   すべての要素が1つ後に移動する
(nth 1 values)
     ⇒ (A 3 t)
;; これは次に新しい、この例の前の次に新しい要素を取得する
(nth 3 values)
     ⇒ 1

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

10.6 遅延されたLazy評価

たとえばプログラムの将来において計算結果が不要ということがわかった場合に時間を要する計算処理を回避したい等、式の評価を遅延させると便利な場合があります。そのような遅延評価(deferred evaluation)をサポートするために、thunkライブラリは以下の関数とマクロを提供します。

Macro: thunk-delay forms…

formsを評価するためのthunkをリターンする(訳注: thunkとは、別のサブルーチンに計算を追加で挿入するために使用するサブルーチンであり、計算結果が必要になるまで計算を遅延したり、別のサブルーチンの先頭や最後に処理を挿入するために使用される。英語版Wikipediaより)。thunkはthunk-delay呼び出しのlexical環境を継承するクロージャである(クロージャを参照)。このマクロの使用にはlexical-bindingが必要。

Function: thunk-force thunk

thunkを作成したthunk-delayで指定されたフォームの評価をthunkに強制する。最後のフォームの評価結果をリターンする。thunkが強制されたことも“記憶”される。同一のthunkにたいする以降のthunk-force呼び出しでは、フォームを再度評価せずに同じ結果をリターンする。

Macro: thunk-let (bindings…) forms…

このマクロはletの類似だが“lazy(遅延された)”変数バインディングを作成する。すべてのバインディングは(symbol value-form)という形式をもつ。letとは異なり、すべてのvalue-formの評価はformsを最初に評価する際に、対応するsymbolのバインディングが使用されるまで遅延される。すべてのvalue-formは最大でも1回評価される。このマクロの使用にはlexical-bindingが必要。

例:

(defun f (number)
  (thunk-let ((derived-number
              (progn (message "Calculating 1 plus 2 times %d" number)
                     (1+ (* 2 number)))))
    (if (> number 10)
        derived-number
      number)))

(f 5)
⇒ 5

(f 12)
-| Calculating 1 plus 2 times 12
⇒ 25

遅延バインドされた変数の特性として、それらにたいする(setqによる)セットはエラーになります。

Macro: thunk-let* (bindings…) forms…

これはthunk-letと似ているが、bindings内の任意の式がこのthunk-let*フォーム内の先行するバインディングの参照を許されている点が異なる。このマクロの使用にはlexical-bindingが必要。

(thunk-let* ((x (prog2 (message "Calculating x...")
                    (+ 1 1)
                  (message "Finished calculating x")))
             (y (prog2 (message "Calculating y...")
                    (+ x 1)
                  (message "Finished calculating y")))
             (z (prog2 (message "Calculating z...")
                    (+ y 1)
                  (message "Finished calculating z")))
             (a (prog2 (message "Calculating a...")
                    (+ z 1)
                  (message "Finished calculating a"))))
  (* z x))

-| Calculating z...
-| Calculating y...
-| Calculating x...
-| Finished calculating x
-| Finished calculating y
-| Finished calculating z
⇒ 8

thunk-letthunk-let*はthunkを暗黙に使用します。これらの拡張はヘルパーシンボルを作成してバインディング式をラップするthunkにバインドします。forms本体中の元の変数にたいするすべての参照は、対応するヘルパー変数を引数とするthunk-force呼び出し式に置き換えられます。したがってthunk-letthunk-let*を使用するコードはthunkを使用するように書き換えが可能ですが、多くの場合には明示的にthunkを使用するよりこれらのマクロを使用するほうが優れたコードになるでしょう。


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

11 制御構造

Lispプログラムは一連の、あるいはフォーム (フォームの種類を参照)により形成されます。これらのフォームの実行順は制御構造(control structures)で囲むことによって制御します。制御構造とはその制御構造が含むフォームをいつ、どのような条件で、何回実行するかを制御するスペシャルフォームです。

もっとも単純な実行順は1番目はa、2番目はb、...というシーケンシャル実行(sequential execution: 順番に実行)です。これは関数のbody内の連続する複数のフォームや、Lispコードのファイル内のトップレベルを記述したときに発生します — つまりフォームは記述した順に実行されます。わたしたちはこれをテキスト順(textual order)と呼びます。たとえば関数のbodyが2つのフォームabから構成される場合、関数の評価は最初にa、次にbを評価します。bを評価した結果がその関数の値となります。

明示的に制御構造を使用することにより、非シーケンシャルな順番での実行が可能になります。

Emacs Lispは他の様々な順序づけ、条件、繰り返し、(制御された)ジャンプを含む複数の種類の制御構造を提供しており、以下ではそれらのすべてを記述します。ビルトインの制御構造は制御構造のサブフォームが評価される必要がなかったり、順番に評価される必要がないのでスペシャルフォームです。独自の制御構造を構築するためにマクロを使用することができます(マクロを参照)。


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

11.1 順序

フォームを出現順に評価するのは、あるフォームから別のフォームに制御を渡すもっとも一般的な制御です。関数のbodyのようなコンテキストにおいては自動的にこれが行なわれます。他の場所ではこれを行なうために制御構造を使用しなければなりません。Lispで一単純な制御構造はprognです。

スペシャルフォームprognは以下のようなものです:

(progn a b c …)

これは順番にabc、...を実行するよう指定します。これらはprognフォームのbodyと呼ばれます。body内の最後のフォームの値がprogn全体の値になります。(progn)nilをリターンします。

初期のLispではprognは、連続で複数のフォームを実行して最後のフォームの値を使用する唯一の方法でした。しかしプログラマーは関数のbodyの、(その時点では)1つのフォームだけが許される場所でprognを使用する必要が多いことに気づきました。そのため関数のbodyを暗黙のprognにして、prognのbodyのように複数のフォームを記述できるようにしました。他の多くの制御構造も暗黙のprognを同様に含みます。結果として昔ほどprognは多用されなくなりました。現在ではprognが必要になるのはunwind-protectandor、またはifthenパートの中であることがほとんどです。

Special Form: progn forms…

このスペシャルフォームはformsのすべてをテキスト順に評価してフォームの結果をリターンする。

(progn (print "The first form")
       (print "The second form")
       (print "The third form"))
     -| "The first form"
     -| "The second form"
     -| "The third form"
⇒ "The third form"

他の2つの構文は一連のフォームを同様に評価しますが、異なる値をリターンします:

Special Form: prog1 form1 forms…

このスペシャルフォームはform1formsのすべてをテキスト順に評価してform1の結果をリターンする。

(prog1 (print "The first form")
       (print "The second form")
       (print "The third form"))
     -| "The first form"
     -| "The second form"
     -| "The third form"
⇒ "The first form"

以下の例は変数xのリストから1番目の要素を削除して、削除した1番目の要素の値をリターンする:

(prog1 (car x) (setq x (cdr x)))
Special Form: prog2 form1 form2 forms…

このスペシャルフォームはform1form2、その後のformsのすべてをテキスト順で評価してform2の結果をリターンする。

(prog2 (print "The first form")
       (print "The second form")
       (print "The third form"))
     -| "The first form"
     -| "The second form"
     -| "The third form"
⇒ "The second form"

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

11.2 条件

条件による制御構造は候補の中から選択を行ないます。Emacs Lispは5つの条件フォームをもちます。ifは他の言語のものとほとんど同じです。whenunlessifの変種です。condは一般化されたcase命令です。condを汎用化したものがpcaseです(パターンマッチングによる条件を参照)。

Special Form: if condition then-form else-forms…

ifconditionの値にもとづきthen-formelse-formsを選択する。評価されたconditionが非nilならthen-formが評価されて結果がリターンされる。それ以外ならelse-formsがテキスト順に評価されて最後のフォームの値がリターンされる(ifelseパートは暗黙のprognの例である。順序を参照)。

conditionの値がnilelse-formsが与えられなければ、ifnilをリターンする。

選択されなかったブランチは決して評価されない — 無視される — ので、ifはスペシャルフォームである。したがって以下の例ではprintが呼び出されることはないのでtrueはプリントされない。

(if nil
    (print 'true)
  'very-false)
⇒ very-false
Macro: when condition then-forms…

これはelse-formsがなく、複数のthen-formsが可能なifの変種である。特に、

(when condition a b c)

は以下と完全に等価である

(if condition (progn a b c) nil)
Macro: unless condition forms…

これはthen-formがないifの変種です:

(unless condition a b c)

は以下と完全に等価である

(if condition nil
   a b c)
Special Form: cond clause…

condは任意個数の選択肢から選択を行なう。cond内の各clauseはリストでなければならない。このリストのCARconditionで、(もしあれば)残りの要素はbody-formsとなる。したがってclauseは以下のようになる:

(condition body-forms…)

condは各clauseのconditionを評価することにより、テキスト順でclauseを試みる。conditionの値が非nilならそのclauseは成り立つ。その後にcondはそのclauseのbody-formsを評価して、body-formsの最後の値をリターンする。残りのclauseは無視される。

conditionの値がnilならそのclauseは失敗して、condは次のclauseに移動してそれのconditionを試みる。

clauseは以下のようにも見えるかもしれない:

(condition)

conditionがテストされたときに非nilなら、condフォームはconditionの値をリターンする。

すべてのconditionnilに評価された場合 — つまりすべてのclauseが不成立なら、condnilをリターンする。

以下の例はxの値が数字、文字列、バッファー、シンボルなのかをテストする4つのclauseをもつ:

(cond ((numberp x) x)
      ((stringp x) x)
      ((bufferp x)
       (setq temporary-hack x) ; 1つのclauseに
       (buffer-name x))        ; 複数bodyフォーム
      ((symbolp x) (symbol-value x)))

前のclauseが不成立のとき最後の条項を実行したいときがよくある。これを行なうには(t body-forms)のように、conditionの最後のclauseにtを使用する。フォームttに評価され決してnilにならないので、このclauseが不成立になることはなく最終的にcondはこのclauseに到達する。たとえば:

(setq a 5)
(cond ((eq a 'hack) 'foo)
      (t "default"))
⇒ "default"

このcond式はaの値がhackならfoo、それ以外は文字列"default"をリターンする。

すべての条件構文はcondifのいずれかで表すことができます。したがってどちらを選択するかはスタイルの問題になります。たとえば:

(if a b c)
≡
(cond (a b) (t c))

変数のバインドとあわせて条件を使うと便利かもしれません。変数の計算を行って、その後もし値が非nilなら何かしたいというのはよくあることです。これを行うには、たとえば以下のように単にそのまま記述すればよいのです:

(let ((result1 (do-computation)))
  (when result1
    (let ((result2 (do-more result1)))
      (when result2
        (do-something result2)))))

これはパターンとしては非常に一般的なのでEmacsではこれを簡単に行って、かつ可読性を向上させるためのマクロがいくつか提供されています。上記のコードは以下のように記述することができます:

(when-let ((result1 (do-computation))
           (result2 (do-more result1)))
  (do-something result2))

このテーマにはバリエーションがいくつかあり、以下にそれらを概略します。

Macro: if-let spec then-form else-forms...

spec内のバインディングを、let* (ローカル変数を参照)のようにそれぞれ順番に評価して、値がnilになるバインディングがあれば停止する。すべて非nilならthen-form、それ以外ではelse-formsの最後のフォームの値をリターンする。

Macro: when-let spec then-forms...

if-letと同様だがelse-formsがない。

Macro: while-let spec then-forms...

when-letと同様だが、spec内のバインディングがnilになるまで繰り返す。リターン値は常にnil


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

11.3 組み合わせ条件の構築

このセクションでは複雑な条件を表現するためにifcondとともによく使用される構文を説明します。andorの構文は、ある種の複数条件の構文として個別に使用することもできます。

Function: not condition

この関数はconditionが偽であることをテストする。この関数はconditionnilならt、それ以外はnilをリターンする。関数notnullと等価であり、空のリストをテストする場合はnullの使用を推奨する。

Special Form: and conditions…

スペシャルフォームandは、すべてのconditionsが真かどうかをテストする。この関数はconditionsを記述順に1つずつ評価することにより機能する。

あるconditionsnilに評価されると、残りのconditionsに関係なく、andnilをリターンしなければならない。この場合andは即座にnilをリターンして、残りのconditionsは無視される。

すべてのconditionsが非nilなら、それらの最後の値がandフォームの値になる。conditionsがない単独の(and)tをリターンする。なぜならすべてのconditionsが非nilとなるので、これは適切である(考えてみてみよ、非nilでないconditionsはどれか?)。

以下に例を示す。1番目の条件は整数1をリターンし、これはnilではない。同様に2番目の条件は整数2をリターンし、これもnilではない。3番目の条件はnilなので、のこりの条件が評価されることは決してない。

(and (print 1) (print 2) nil (print 3))
     -| 1
     -| 2
⇒ nil

以下はandを使用した、より現実的な例である:

(if (and (consp foo) (eq (car foo) 'x))
    (message "foo is a list starting with x"))

(consp foo)nilをリターンすると、(car foo)は実行されないのでエラーにならないことに注意。

ifcondのいずれかを使用して、and式を記述することもできる。以下にその方法を示す:

(and arg1 arg2 arg3)
≡
(if arg1 (if arg2 arg3))
≡
(cond (arg1 (cond (arg2 arg3))))
Special Form: or conditions…

スペシャルフォームorは、少なくとも1つのconditionsが真かどうかをテストする。この関数はすべてのconditionsを1つずつ、記述された順に評価することにより機能する。

あるconditionsが非nil値に評価されたら、orの結果は非nilでなければならない。この場合orは即座にリターンし、残りのconditionsは無視される。この関数がリターンする値は、非nil値に評価された条件の値そのものである。

すべてのconditionsnilなら、or式はnilをリターンします。conditionsのない単独の(or)nilをリターンする。なぜならすべてのconditionsnilになるのでこれは適切である(考えてみよ、nilでないconditionsはどれか?)。

たとえば以下の式は、xnilか整数0かどうかをテストする:

(or (eq x nil) (eq x 0))

and構文と同様に、orcondに置き換えて記述することができる。たとえば:

(or arg1 arg2 arg3)
≡
(cond (arg1)
      (arg2)
      (arg3))

ほとんどの場合は、orifに置き換えて記述できるが完全ではない:

(if arg1 arg1
  (if arg2 arg2
    arg3))

これは完全に同一ではない。なぜならarg1arg2を2回評価するかもしれないからである。対照的に(or arg1 arg2 arg3)が2回以上引数を評価することは決してない。

Function: xor condition1 condition2

この関数はcondition1condition2の排他的論理和をリターンする。つまりxorは引数がいずれもnilあるいは非nilならnilをリターンする。それ以外なら非nilの引数の値をリターンする。

orとは対照的に引数はどちらも常に評価されることに注意。


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

11.4 パターンマッチングによる条件

4つの基本的な条件フォームとは別に、Emacs Lispにはcondcl-case (Conditionals in Common Lisp Extensionsを参照)の合成物とも言うべき、pcaseマクロというパターンマッチングによる条件フォームがあります。これはcondcl-caseの制限を克服して、パターンマッチングによるプログラミングスタイル(pattern matching programming style)を導入するものです。そのpcaseが克服する制限とは:

  • condフォームはclauseそれぞれにたいして述語conditionを評価して候補から選択を行う(条件を参照)。condition内でのletバインドされた変数がclauseのbody-formsで利用できないのが主な制限。

    もう1つの煩しい(制限というより不便な)点は一連のcondition述語が等価なテストを実装する際にはコードが多数回繰り返されること(cl-caseはこの不便さを解決している)。

  • cl-caseマクロは最初の引数と特定の値セットの等価性を評価することにより候補から選択を行う。

    制限は2つ:

    1. 等価性のテストにeqlを使用。
    2. 値は既知でありあらかじめ記述されていなければならない。

    これらの制限は文字列や複合データ構造にたいしてcl-caseを不適格にする(このような制限はcondにはないが上述のように別の制限をもつ)。

pcaseマクロはパターンマッチング(pattern matching)の変種であるような等価性テストを汎化したものによるconditionの置き換え、clauseの述語を簡潔に表現できるような機能の追加、clauseの述語とbody-formsの間でletバインディングを共有するようなアレンジにより、概念的には最初の引数のフォーカスではcl-case、clauseの処理フローではcondを借用しています。

この述語の簡潔な表現はパターン(pattern)として知られています。最初の引数の値にたいして呼び出される述語が非nilをリターンしたときには、“パターンが値にマッチした”といいます(“値がパターンにマッチした”ということもある)。


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

11.4.1 pcaseマクロ

背景はパターンマッチングによる条件を参照してください。

Macro: pcase expression &rest clauses

clauses内のclauseは(pattern body-forms…)という形式をもつ。

expressionの値( expval )を決定するために評価する。patternexpvalにマッチするような最初のclauseを探して、そのclauseのbody-formsに制御を渡す。

マッチが存在すればpcaseの値はマッチが成功したclauseのbody-formsの最後の値、それ以外ならpcasenilに評価される。

patternpcaseパターン(pcase pattern)である必要があります。これは以下に定義されるコアパターンのいずれか、またはpcase-defmacro (pcaseの拡張を参照)を通じて定義されるパターンの1つを使用できます。

このサブセクションの残りの部分ではコアパターンの異なるフォームをいくつかの例を交えて説明して、いくつかのパターンフォームが提供するletバイディング機能を使用する上で重要な注意点で締めくくります。コアパターンは以下のフォームをもつことができます:

_ (アンダースコア)

任意のexpvalにマッチ。これはdon’t care、あるいはワイルドカード(wildcard)としても知られる。

'val

expvalvalが等しければマッチ。比較はequalのように行われる(同等性のための述語を参照)。

keyword
integer
string

expvalがリテラルオブジェクトと等しければマッチ。これは上述の'valの特殊なケースであり、これらのタイプのリテラルオブジェクトが自己クォート(self-quoting)を行うために可能となる。

symbol

任意のexpvalにマッチするとともに、追加でsymbolexpvalにletバインドする。このようなバインディングはbody-forms内でも利用できる(ダイナミックバインディングを参照)。

symbolが(以下のandを使用することにより)シーケンスパターンseqpatの一部なら、symbolに後続するseqpat部分でもバインディングは利用可能。この使用法にはいくつかの注意点がある。caveatsを参照のこと。

使用を避けるべき2つのシンボルは_ (上述)と同様に振る舞う非推奨のtnil(エラーをシグナルする)。同様にキーワードシンボルへのバインドは無意味(変更不可な変数を参照)。

(cl-type type)

expvalがタイプtype ( cl-typepが許す型記述子。 Type Predicates in Common Lisp Extensionsを参照)ならマッチ。たとえば:

(cl-type integer)
(cl-type (integer 0 10))
(pred function)

expvalにたいして述語functionが非nilをリターンしたらマッチ。このテストは構文(pred (not function))で否定となる。述語functionは以下のフォームのいずれかが可能:

関数名(シンボル)

expvalを単一の引数として名前つきの関数を呼び出す。

例: integerp

lambda式

expvalを単一の引数として無名関数を呼び出す(ラムダ式を参照)。

例: (lambda (n) (= 42 n))

n個の引数での関数呼び出し

関数(関数呼び出しの1つ目の要素)をn個の引数(残りの要素)、およびexpvaln+1番目の追加の引数としてで呼び出す。

例: (= 42)
この例では関数が=nが1であり、実際の関数呼び出しは(= 42 expval)になる。

(app function pattern)

expvalにたいして呼び出したfunctionpatternにマッチする値をリターンすればマッチ。functionは上述のpredで説明したフォームのいずれかが可能。しかしpredとは異なり、appはブーリーンの真値ではなくpatternにたいして結果をテストする点が異なる。

(guard boolean-expression)

boolean-expressionが非nilに評価されればマッチ。

(let pattern expr)

exprvalを取得するためにexprを評価して、exprvalpatternにマッチすればマッチ(patternsymbolを使用することでシンボルに値をバインドできるのでletと呼ばれる)。

seqpatとしても知られるシーケンスパターン(sequencing pattern)はサブパターンを順に処理するパターンです。pcaseにたいしてはandorの2つが存在します。これらは同じ名前のスペシャルフォーム(組み合わせ条件の構築を参照)と同様の方式で振る舞いますが、値ではなくサブパターンを処理します。

(and pattern1…)

pattern1…のいずれかがマッチに失敗するまで順にマッチを試みる。この場合にはandもマッチに失敗して、残りのサブパターンはテストしない。すべてのサブパターンがマッチすればandはマッチする。

(or pattern1 pattern2…)

pattern1pattern2、…のいずれかがマッチに成功するまで順にマッチを試みる。この場合にはorもマッチして、残りのサブパターンはテストしない。

body-formsにたいして一貫した環境 (評価の概要を参照) を与える(マッチでの評価エラーを回避できる)ために、パターンがバインドする変数セットは各サブパターンがバインドする変数を結合したものになる。ある変数がマッチしたサブパターンにバインドされない場合にはnilにバインドされる。

(rx rx-expr…)

string-matchが行うようにrx正規表現表記を使用して文字列を正規表現rx-expr…にマッチする(rx構造化Rgexp表記を参照)。

通常のrx構文に加えて、rx-expr…には以下の構文を含めることができる:

(let ref rx-expr…)

シンボルrefrx-expr...にマッチする部分マッチにバインドする。refbody-forms内で部分マッチの文字列かnilにバインドされるが、backrefでも使用可能。

(backref ref)

標準のbackref構文と同様だが、refは前の(let ref …)構文で導入された名前にもなる。

例: cl-caseにたいする利点

以下はcl-case (Conditionals in Common Lisp Extensionsを参照)にたいするpcaseの利点のいくつかを強調する例です。

(pcase (get-return-code x)
  ;; 文字列
  ((and (pred stringp) msg)
   (message "%s" msg))
  ;; シンボル
  ('success       (message "完了!"))
  ('would-block   (message "残念、今は実行できない"))
  ('read-only     (message "shmliblickは読み取り専用"))
  ('access-denied (message "必要な権限がない"))
  ;; default
  (code           (message "未知のリターンコード %S" code)))

cl-caseではget-return-codeのリターン値を保持するためにローカル変数codeを宣言する必要があります。さらにcl-caseは比較にeqlを使用するので文字列の使用も難しくなります。

例: andの使用

後続のサブパターン(と同様にbodyフォーム)にバインディングを提供する1つ以上のsymbolサブパターンをもつandで開始するのが、パターンを記述する際の一般的なイディオムです。たとえば以下のパターンは1桁の整数にマッチします。

(and
  (pred integerp)
  n                     ; nexpvalをバインド
  (guard (<= -9 n 9)))

まずpred(integerp expval)が非nilに評価されればマッチになります。次にnはすべてにマッチするsymbolパターンであり、nexpvalがバインドされます。最後にguardはブーリーン式(<= -9 n 9)が非nilに評価されればマッチになります(nへの参照に注意)。これらすべてのサブパターンがマッチすればandがマッチになります。

例: pcaseによる書き換え

以下はシンプルなマッチングタスクを伝統的な実装(関数grok/traditionalから、pcaseを使用する実装(関数grok/pcase)に書き換える別の例です。これらの関数のdocstringはいずれも“If OBJ is a string of the form "key:NUMBER", return NUMBER (a string). Otherwise, return the list ("149" default).”です。最初は伝統的な実装です(正規表現を参照):

(defun grok/traditional (obj)
  (if (and (stringp obj)
           (string-match "^key:\\([[:digit:]]+\\)$" obj))
      (match-string 1 obj)
    (list "149" 'default)))

(grok/traditional "key:0")   ⇒ "0"
(grok/traditional "key:149") ⇒ "149"
(grok/traditional 'monolith) ⇒ ("149" default)

この書き換えではsymbolバインディング、およびorandpredappletを実演します。

(defun grok/pcase (obj)
  (pcase obj
    ((or                                     ; L1
      (and                                   ; L2
       (pred stringp)                        ; L3
       (pred (string-match                   ; L4
              "^key:\\([[:digit:]]+\\)$"))   ; L5
       (app (match-string 1)                 ; L6
            val))                            ; L7
      (let val (list "149" 'default)))       ; L8
     val)))                                  ; L9

(grok/pcase "key:0")   ⇒ "0"
(grok/pcase "key:149") ⇒ "149"
(grok/pcase 'monolith) ⇒ ("149" default)

grok/pcaseは主に1つのpcaseフォームのclause、L1からL8のパターン、L9の(1つの)フォームからなります。パターンは引数であるサブパターンにたいして順にマッチを試みるorです。これは最初にand (L2からL7)、次にlet (L8)のように、いずれかが成功するまで順にマッチを試みます。

前出の例(Example 1を参照)のように、andは以降のサブパターンが正しいタイプのオブジェクト(この場合は文字列)に作用することを保証するためにpredサブパターンで始まります。(stringp expval)nilならpredは失敗となり、したがってandも失敗となります。

次のpred (L4からL5)は(string-match RX expval)を評価して結果が非nil ( expvalが期待するフォームkey:NUMBERであることを意味する)ならマッチになります。これが失敗すると再びpredは失敗となり、したがってandも失敗となります。

(andの一連のサブパターンでは)最後のappは一時的な値tmp (部分文字列 “NUMBER”)を取得するために(match-string 1 expval) (L6)を評価して、パターンval (L7)とtmpのマッチを試みます。これはsymbolパターンなので無条件でマッチして、valtmpを追加でバインドします。

ついにappがマッチしたので、andのすべてのサブパターンがマッチして、andがマッチとなります。同じように一度andがマッチすればorがマッチするので、サブパターンlet (L8)の処理が試みられることはありません。

objが文字列以外、あるいは間違った形式の文字列の場合を考えてみましょう。この場合にはいずれかのpred (L3からL5)がマッチに失敗するので、and (L2)がマッチに失敗して、or (L1)がサブパターンlet (L8)の処理を試みます。

まずlet("149" default)を取得するために(list "149" 'default)を評価して、それからパターンvalにたいしてexprvalのマッチを試みます。これはsymbolパターンなので無条件にマッチして、追加でvalexprvalをバインドします。これでletがマッチしたので、orがマッチとなります。

andletのサブパターンはどちらも同じ方法、すなわちvalをバインドする過程でsymbolパターンのvalに(常に成功する)マッチを試みることにより完了することに注意してください。したがってorは常にマッチして、常に制御をbodyフォーム(L9)に渡します。マッチが成功したpcaseのclauseとしては最後のbodyなので、これはpcaseの値となり、同様にgrok/pcaseのリターン値になります(関数とは?を参照)。

シーケンスパターンにおけるsymbolの注意点

前出の例のすべてでは、何らかの方法によりsymbolサブパターンが含まれるシーケンスパターンが使用されています。以下に使用法に関する重要な詳細をいくつか挙げます。

  1. seqpat内にsymbolが複数回出現する場合には、 2回目以降に出現してもリバインドには展開されないが、かわりにeqを使用した等価性テストに展開される。

    以下の例には2つのclauseと2つのseqpat (AとB)を使用している。AとBはいずれも最初に(predを使用することにより)expvalがペアであることをチェックして、それから(それぞれにたいしてappを使用することにより) expvalcarcdrにシンボルをバインドする。

    Aではシンボルstが2回記述されているので、2つ目の記述はeqを使用した等価性チェックになる。一方でBはs1s2という別個のシンボルを使用するので、独立したバインディングになる。

    (defun grok (object)
      (pcase object
        ((and (pred consp)        ; seqpat A
              (app car st)        ; st: 1回目
              (app cdr st))       ; st: 2回目
         (list 'eq st))
    
        ((and (pred consp)        ; seqpat B
              (app car s1)        ; s1: 1回目
              (app cdr s2))       ; s2: 1回目
         (list 'not-eq s1 s2))))
    
    
    
    (let ((s "yow!"))
      (grok (cons s s)))      ⇒ (eq "yow!")
    (grok (cons "yo!" "yo!")) ⇒ (not-eq "yo!" "yo!")
    (grok '(4 2))             ⇒ (not-eq 4 (2))
    
  2. symbolを参照するコードの副作用は未定義。 無視する。たとえば以下2つの関数は類似している。いずれの関数もandsymbolguardを使用する:
    (defun square-double-digit-p/CLEAN (integer)
      (pcase (* integer integer)
        ((and n (guard (< 9 n 100))) (list 'yes n))
        (sorry (list 'no sorry))))
    
    (square-double-digit-p/CLEAN 9) ⇒ (yes 81)
    (square-double-digit-p/CLEAN 3) ⇒ (no 9)
    
    
    
    (defun square-double-digit-p/MAYBE (integer)
      (pcase (* integer integer)
        ((and n (guard (< 9 (incf n) 100))) (list 'yes n))
        (sorry (list 'no sorry))))
    
    (square-double-digit-p/MAYBE 9) ⇒ (yes 81)
    (square-double-digit-p/MAYBE 3) ⇒ (yes 9)  ; WRONG!
    

    違いはguard内のboolean-expressionである。CLEANは単に直接nを参照するのにたいして、MAYBEは式(incf n)の中で副作用によりnを参照している。integerの際には以下のようなことが発生している:

    • 最初のnexpval (評価した結果である(* 3 3)、つまり9)にバインドされる。
    • boolean-expressionが評価される:
      start:   (< 9 (incf n)        100)
      becomes: (< 9 (setq n (1+ n)) 100)
      becomes: (< 9 (setq n (1+ 9)) 100)
      
      becomes: (< 9 (setq n 10)     100)
                                         ; ここで副作用!
      becomes: (< 9       n         100) ; nは10にバインドされている
      becomes: (< 9      10         100)
      becomes: t
      
    • 結果は非nilなので guardがマッチしてandがマッチとなり、制御はそのclauseのbodyフォームに渡される。

    MAYBEには9が2桁の整数だと判定してしまう数学的な誤り以外にも問題がある。bodyフォームはnの更新された値(10)を確認せずに参照を複数回行う。するとどうなるか?

    要約すると( guardでの) boolean-expressionだけではなく( letでの) expr、( predappでの) functionでも副作用をもつsymbolパターンにたいする参照は完全に避けることが最良である。

  3. マッチではclauseのbodyフォームはletバインドされたパターンのシンボルセットを参照できる。 このシンボルセットはseqpatandの際には、各サブパターンでletバインドされるすべてのシンボルそれぞれを結合したものになる。andのマッチではすべてのサブパターンがマッチしなければならないので、これには意味がある。

    seqpatorなら事情は異なる。orは最初にマッチしたサブパターンでマッチとなり、残りのサブパターンは無視される。bodyフォームにはどのサブパターンがマッチして異なるセットの中からどれが選択されたかを知る術はないので、各シンボルが異なるシンボルセットをletバインドすることに意味はない。たとえば以下は無効:

    (require 'cl-lib)
    (pcase (read-number "Enter an integer: ")
      ((or (and (pred cl-evenp)
                e-num)      ; e-numexpvalにバインド
           o-num)           ; o-numexpvalにバインド
       (list e-num o-num)))
    
    
    
    Enter an integer: 42
    error→ Symbol’s value as variable is void: o-num
    
    Enter an integer: 149
    error→ Symbol’s value as variable is void: e-num
    

    bodyフォーム(list e-num o-num)の評価によりエラーがシグナルされる。サブパターンを区別するために、すべてのサブパターンごとに異なる値をもつ同一名のシンボルを使用できる。上記の例を書き換えると:

    (require 'cl-lib)
    (pcase (read-number "Enter an integer: ")
      ((and num                                ; L1
            (or (and (pred cl-evenp)           ; L2
                     (let spin 'even))         ; L3
                (let spin 'odd)))              ; L4
       (list spin num)))                       ; L5
    
    
    
    Enter an integer: 42
    ⇒ (even 42)
    
    Enter an integer: 149
    ⇒ (odd 149)
    

    L1ではexpvalのバインディング(この場合はnum )をandsymbolで“分解”している。L2では前と同じ方法でorは始まるが、異なるシンボルにバインドするかわりに、両方のサブパターン内で同一のシンボルspinに回バインドするために2回letを使用している(L3からL4)。spinの値によりサブパターンは区別される。そしてbodyフォームでは両方のシンボルを参照している(L5)。


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

11.4.2 pcaseの拡張

pcaseマクロは数種類のパターンをサポートします(パターンマッチングによる条件を参照)。pcase-defmacroを使用すれば違う種類のパターンにたいするサポートを追加できます。

Macro: pcase-defmacro name args [doc] &rest body

(name actual-args)のように呼び出すために新たな種類のpcase用のパターンを定義する。pcaseマクロはbodyを評価する呼び出しへと展開する。このマクロの役割はargsactual-argsにバインドした環境下において、呼び出されたパターンを別の何らかのパターンに書き換えることである。

さらにpcaseのドキュメント文字列とともにdocが表示されるように計らう。docでは慣例によりexpressionの評価結果を示すためにEXPVALを使用すること。

bodyは通常はより基本的なパターンを使用して呼び出されたパターンを書き換える。最終的にはすべてのパターンはコアパターンに絞り込まれるが、bodyがすぐにコアパターンを使用する必要はない。以下の例ではless-thaninteger-less-thanという2つのパターンを定義している。

(pcase-defmacro less-than (n)
  "Matches if EXPVAL is a number less than N."
  `(pred (> ,n)))

(pcase-defmacro integer-less-than (n)
  "Matches if EXPVAL is an integer less than N."
  `(and (pred integerp)
        (less-than ,n)))

args (このケースではnの1つだけ)に言及するdocstringは通常の方法、EXPVALでは慣例にもとづく方法であることに注意してください。1つ目の書き換え( less-thanbody )ではpredというコアパターンだけが使用されていて、2つ目では2つのコアパターンandpredと新たに定義したパターンless-thanが使用されています。そしていずれの書き換えにおいてもシングルバッククォート構文が使用されています(バッククォートを参照)。


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

11.4.3 バッククォートスタイルパターン

このサブセクションでは構造化マッチングを容易にするビルトインパターンであるバッククォートスタイルパターン(backquote-style patterns)について説明します。背景についてはパターンマッチングによる条件を参照してください。

バッククォートスタイルパターンは(pcase-defmacroを使用して作成された)強力なpcaseパターン拡張であり、その構造(structure)の仕様にたいするexpvalのマッチを容易にします。

たとえば1つ目の要素が特定の文字列、2つ目の要素が任意の値であるような2要素リストのexpvalにたいするマッチはコアパターンを使用して記述できます:

(and (pred listp)
     ls
     (guard (= 2 (length ls)))
     (guard (string= "first" (car ls)))
     (let second-elem (cadr ls)))

しかし等価なバッククォートスタイルパターンで記述することもできます:

`("first" ,second-elem)

バッククォートスタイルパターンはより簡潔かつexpvalの構造と似ており、lsのバインドを要しません。

バッククォートスタイルパターンは`qpatのような形式をもちます。ここでqpatは以下の形式をもつことができます:

(qpat1 . qpat2)

expvalが( carqpat1cdrqpat2にマッチする)コンスセルならマッチ。(qpat1 qpat2 …)のように容易に一般化できる。

[qpat1 qpat2qpatm]

expvalが長さmの(0から(m-1)番目の要素がqpat1qpat2、…、qpatmにマッチする)ベクターならマッチ。

symbol
keyword
number
string

expvalの対応する要素が指定されたリテラルオブジェクトとequalならマッチ。

,pattern

expvalの対応する要素がpatternにマッチすればマッチ。patternpcaseがサポートするすべての種類のパターンであることに注意(上記の例ではsecond-elemsymbolコアパターンであり、これはすべてにマッチしてsecond-elemをletでバインドする)。

対応する要素(corresponding element)とはバッククォートスタイルパターンqpatにたいする構造的な位置に等しいようなexpvalの構造的な位置部分のことです(上記の例ではsecond-elemの対応する要素はexpvalの2つ目の要素)。

以下は小さな式言語用の単純なインタープリターの実装用にpcaseを使用する例です(bodyargを正しくキャプチャーするにはfnのclause内でlambda式にレキシカルバインディングが必要なことに注意):

(defun evaluate (form env)
  (pcase form
    (`(add ,x ,y)       (+ (evaluate x env)
                           (evaluate y env)))
    (`(call ,fun ,arg)  (funcall (evaluate fun env)
                                 (evaluate arg env)))
    (`(fn ,arg ,body)   (lambda (val)
                          (evaluate body (cons (cons arg val)
                                               env))))
    ((pred numberp)     form)
    ((pred symbolp)     (cdr (assq form env)))
    (_                  (error "Syntax error: %S" form))))

最初の3つのclauseではバッククォートスタイルパターンが使用されています。`(add ,x ,y)formがリテラルシンボルaddから始まる3要素リストであることをチェックしてから2つ目と3つ目の要素を取り出してシンボルxyにバインドします。clauseのbodyではxyを評価して結果を加算します。同じようにcall clauseは関数呼び出しを実装して、fn clauseは無名関数定義を実装します。

残りのclauseではコアパターンが使用されています。(pred numberp)formが数値ならマッチします。マッチした場合にはbodyがそれを評価します。(pred symbolp)formがシンボルならマッチします。マッチした場合にはbodyはenv内のシンボルを照合して、それの連想値をリターンします。最後の_はすべてにマッチするcatch-allパターンなので、構文エラーの報告に適しています。

以下は評価した結果を含む、この小さな言語のサンプルプログラムの例です:

(evaluate '(add 1 2) nil)                 ⇒ 3
(evaluate '(add x y) '((x . 1) (y . 2)))  ⇒ 3
(evaluate '(call (fn x (add 1 x)) 2) nil) ⇒ 3
(evaluate '(sub 1 2) nil)                 ⇒ error

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

11.4.4 pcaseパターンによる分解

pcaseのパターンはあるオブジェクトがマッチ可能なフォーム上の条件を表現するだけではなく、それらのオブジェクトのサブフィールドの抽出もできます。たとえば以下のコードにより、変数my-listの値であるリストから2つの要素を抽出できます:

  (pcase my-list
    (`(add ,x ,y)  (message "Contains %S and %S" x y)))

これはxyを抽出するだけではなく、加えてmy-listが正確に3つの要素を含むリストであり、最初の要素がシンボルaddかどうかをテストします。これらのテストのいずれかが失敗したら、pcasemessageを呼び出さずに即座にnilをリターンします。

あるオブジェクトから格納された複数の値を抽出する処理は分割(destructuring)という処理としても知られています。pcaseパターンの使用によりバインディングの分割(destructuring binding)を処理することが可能になります。これはローカルバインディング(ローカル変数を参照)と似ていますが、互換性のあるオブジェクトから値を抽出することにより、変数の複数要素に値を与えることができます。

このセクションで説明したマクロはバインディングを分割するためにpcaseパターンを使用しています。オブジェクト構造に互換性があるという条件は、そのオブジェクトがパターンにマッチしなければならないことを意味しています。なぜならマッチした場合のみオブジェクトのサブフィールドが抽出可能になるからです。たとえば:

  (pcase-let ((`(add ,x ,y) my-list))
    (message "Contains %S and %S" x y))

これは最初にmy-listが正しい個数の要素をもつリストであり、かつ1つ目の要素がaddか検証せずに、my-listから直接xyの抽出を行う点を除いて前の例と同じことを行います。実際にオブジェクトがパターンにマッチしない場合には、たとえbodyが暗黙にスキップされることはないとしても、その振る舞いは未定義でありエラーがシグナルされるか、あるいはいくつかの変数がnilのような任意の値にバインドされた状況でbodyが実行されるかもしれません。

バインディングの分割に有用なpcaseパターンとしては、マッチされるオブジェクト構造の仕様を表現するバッククォートスタイルパターンで説明したパターンが一般的です。

バインディングの分割にたいする代替え機能についてはseq-letを参照してください。

Macro: pcase-let bindings body…

bindingsに応じて変数のバインディング分割を行い、それからbodyを評価する。

bindings(pattern exp)という形式のバインディングのリスト。ここでexpは評価する式、patternpcaseパターン。

expはすべて最初に評価されて、その後で対応するpatternにマッチされて、bodyの内部で使用可能な変数バインディングが導入される。この変数バインディングはpatternの要素を、評価されたexpの対応する要素の値に分割してのバインディングすることにより生成される。

以下はその例:

(pcase-let ((`(,major ,minor)
	     (split-string "image/png" "/")))
  minor)
     ⇒ "png"
Macro: pcase-let* bindings body…

bindingsに応じて変数のバインディング分割を行い、それからbodyを評価する。

bindings(pattern exp)という形式のバインディングのリスト。ここでexpは評価する式、patternpcaseパターン。この変数バインディングはpatternの要素を、評価されたexpの対応する要素の値に分割してバインディングすることにより生成される。

pcase-letとは異なり(しかしlet*と同じように)、各expbindingsの次要素の処理前に対応するpatternにたいしてマッチされるので、各bindingsのいずれかによって導入される変数バインディングはbody内で利用可能になるのに加えて、その後に続くbindingsexp内で利用可能になる。

Macro: pcase-dolist (pattern list) body…

繰り返しごとにpatternの変数をlistの要素の対応するサブフィールドに分割バインディングしながら、listの各要素ごとに一度bodyを実行する。このバインディングはpcase-letの場合のように行われる。patternが単なる変数ならdolistと等価(繰り返しを参照)。

Macro: pcase-setq pattern value…

patternに応じて各valueの分割を行い、setqフォーム内の変数に値を割り当てる。

Macro: pcase-lambda lambda-list &rest body

lambdaと同様だが、各引数はパターンでも良い。たとえば以下は引数としてコンスセルを受け取る単純な関数の例:

(setq fun
      (pcase-lambda (`(,key . ,val))
        (vector key (* val 10))))
(funcall fun '(foo . 2))
    ⇒ [foo 20]

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

11.5 繰り返し

繰り返し(iteration)とは、プログラムの一部を繰り返し実行することを意味します。たとえばリストの各要素、または0からnの整数にたいして、繰り返し一度ずつ何らかの計算を行いたいとしましょう。Emacs Lispではスペシャルフォームwhileでこれを行なうことができます:

Special Form: while condition forms…

whileは最初にconditionを評価する。結果が非nilならformsをテキスト順に評価する。その後にconditionを再評価して結果が非nilなら、再度formsを評価する。この処理はconditionnilに評価されるまで繰り返される。

繰り返し回数に制限はない。このループはconditionnilに評価されるか、エラーになるか、またはthrowで抜け出す(非ローカル脱出を参照)まで継続される。

whileフォームの値は常にnilである。

(setq num 0)
     ⇒ 0
(while (< num 4)
  (princ (format "Iteration %d." num))
  (setq num (1+ num)))
     -| Iteration 0.
     -| Iteration 1.
     -| Iteration 2.
     -| Iteration 3.
     ⇒ nil

各繰り返しごとに何かを実行して、その後も終了テストを行なうrepeat-untilループを記述するには、以下のようにwhileの1番目の引数としてbodyの後に終了テストを記述して、それをprognの中に配置する:

(while (progn
         (forward-line 1)
         (not (looking-at "^$"))))

これは1行前方に移動して、空行に達するまで行単位の移動を継続する。独特な点はwhileがbodyをもたず、終了テスト(これはポイント移動という実処理も行なう)だけを行うことである。

マクロdolistおよびdotimesは、2つの一般的な種類のループを記述する、便利な方法を提供します。

Macro: dolist (var list [result]) body…

この構文はlistの各要素に一度bodyを実行して、カレント要素をローカルに保持するように、変数varにバインドする。その後にresultを評価した値、resultが省略された場合はnilをリターンする。たとえば以下はreverse関数を定義するためにdolistを使用する方法の例である:

(defun reverse (list)
  (let (value)
    (dolist (elt list value)
      (setq value (cons elt value)))))
Macro: dotimes (var count [result]) body…

この構文は0以上count未満の各整数にたいして、一度bodyを実行してから、繰り返しのカレント回数となる整数を変数varにバインドする。その後にresultの値、resultが省略された場合はnilをリターンする。resultの使用は推奨しない。以下はdotimesを使用して、何らかの処理を100回行なう例:

(dotimes (i 100)
  (insert "I will not obey absurd orders\n"))

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

11.6 ジェネレーター

ジェネレーター(generator)とは、潜在的に無限な値ストリームを生成する関数です。毎回その関数が値を生成するごとに、呼び出し側が次の値を要求するまで、自身をサスペンドします。

Macro: iter-defun name args [doc] [declare] [interactive] body…

iter-defunはジェネレーター関数を定義する。ジェネレーター関数は通常の関数と同様のsignatureをもつが、異なるように機能する。ジェネレーター関数は呼び出し時にbodyを実行するのではなく、かわりにiteratorオブジェクトをリターンする。このiteratorは値を生成するためにbodyを実行、値を発行するとiter-yielditer-yield-fromが出現するまで一時停止する。bodyが正常にリターンした際に、iter-nextがコンディションデータとなるbodyの結果とともに、iter-end-of-sequenceをシグナルする。

body内部では任意の種類のLispコードが有効だが、iter-yielditer-yield-fromunwind-protectフォームの内部にあってはならない。

Macro: iter-lambda args [doc] [interactive] body…

iter-lambdaiter-defunで生成されたジェネレーター関数と同様な、無名のジェネレーター関数を生成する。

Macro: iter-yield value

iter-yieldがジェネレーター関数内部で出現した際には、カレントiteratorが一時停止してiter-nextからvalueをリターンすることを示す。iter-yieldは、次回iter-next呼び出しのvalueパラメーターへと評価される。

Macro: iter-yield-from iterator

iter-yield-fromiteratorが生成するすべての値を生成して、そのiteratorのジェネレーター関数が通常リターンする値へと評価される。これが制御を得ている間、iteratoriter-nextを使用して送信された値を受け取る。

ジェネレーター関数を使用するには、まずそれを普通に呼び出してiteratorオブジェクトを生成します。iteratorはジェネレーターの固有のインスタンスです。その後でこのiteratorから値を取得するためにiter-nextを使用します。iteratorから取得する値がなくなると、iter-nextはそのiteratorの最終値とともにiter-end-of-sequenceのコンディションをraisesします。

ジェネレーター関数のbodyは、iter-nextの呼び出しの内側でのみ実行されることに注意することが重要です。iter-defunで定義された関数の呼び出しはiteratorを生成します。何か興味があることが発生したら、iter-nextでこのiteratorを制御しなければなりません。ジェネレーター関数の個々の呼び出しは、それぞれが独自に状態をもつ別個のiteratorを生成します。

Function: iter-next iterator &optional value

iteratorから次の値を取得する。(iteratorのジェネレーター関数がリターンしていて)生成される値が存在しない場合、iter-nextはコンディションiter-end-of-sequenceをシグナルする。このコンディションに関連付けられるデータ値は、iteratorのジェネレーター関数がリターンした値である。

valueはiteratorに送信されて、iter-yieldを評価した値になる。iteratorのジェネレーター関数の開始時には、ジェネレーター関数はiter-yieldフォームを何も評価していないので、与えられたiteratorにたいする最初のiter-next呼び出しではvalueは無視される。

Function: iter-close iterator

iteratorunwind-protectbodyformフォーム内でサスペンドされていたら、ガーベージコレクション処理後にEmacsが最終的にunwindハンドラーを実行する(unwind-protectunwindforms内部ではiter-yieldは不当であることに注意)。その前に確実にこれらのハンドラーを実行するには、iter-closeを使用すること。

iteratorを簡単に連携できるように、便利な関数がいくつか提供されています:

Macro: iter-do (var iterator) body …

iteratorが生成する各値をvarにバインドしつつbodyを実行する。

Common Lispのループ機能にはiteratorとともに機能も含まれています。Loop Facility in Common Lisp Extensionsを参照してください。

以下のコード片はiteratorとの連携における重要な原則を示すものです。

(require 'generator)
(iter-defun my-iter (x)
  (iter-yield (1+ (iter-yield (1+ x))))
   ;; 普通にリターンする
  -1)

(let* ((iter (my-iter 5))
       (iter2 (my-iter 0)))
  ;; 6をプリント
  (print (iter-next iter))
  ;; 9をプリント
  (print (iter-next iter 8))
  ;; 1をプリント
  ;; iterとiterは異なる状態をもつ
  (print (iter-next iter2 nil))

  ;; ここでiterシーケンスの終了を待機
  (condition-case x
      (iter-next iter)
    (iter-end-of-sequence
      ;; my-iterが通常の方法でリターンした-1をプリント
      (print (cdr x)))))

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

11.7 非ローカル脱出

非ローカル脱出(nonlocal exit)とは、プログラム内のある位置から別の離れた位置へ制御を移します。Emacs Lispではエラーの結果として非ローカル脱出が発生することがあります。明示的な制御の下で非ローカル脱出を使用することもできます。非ローカル脱出は脱出しようとしている構文により作成された、すべての変数バインディングのバインドを解消します。


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

11.7.1 明示的な非ローカル脱出: catchthrow

ほとんどの制御構造は、その構文自身の内部の制御フローだけに影響します。関数throwは、この通常のプログラム実行でのルールの例外です。これはリクエストにより非ローカル脱出を行ないます(他にも例外はあるがそれらはエラー処理用のものだけ)。throwcatchの内部で使用され、catchに制御を戻します。たとえば:

(defun foo-outer ()
  (catch 'foo
    (foo-inner)))

(defun foo-inner ()
  …
  (if x
      (throw 'foo t))
  …)

throwフォームが実行されると、対応するcatchに制御を移して、catchは即座にリターンします。throwの後のコードは実行されません。throwの2番目の引数はcatchのリターン値として使用されます。

関数throwは1番目の引数にもとづいて、それにマッチするcatchを探します。throwは1番目の引数が、throwで指定されたものとeqであるようなcatchを検索します。複数の該当するcatchがある場合には、最も内側にあるものが優先されます。したがって上記の例ではthrowfooを指定していて、foo-outer内のcatchが同じシンボルを指定しているので、(この間に他のマッチするcatchは存在しないと仮定するなら)そのcatchが該当します。

throwの実行により、マッチするcatchまでのすべてのLisp構文(関数呼び出しを含む)を脱出します。この方法によりletや関数呼び出しのようなバインディング構文を脱出する場合には、これらの構文を正常にexitしたときのように、そのバインディングは解消されます(ローカル変数を参照)。同様にthrowsave-excursion(エクスカーションを参照)によって保存されたバッファーと位置を復元します。throwがスペシャルフォームunwind-protectを脱出した場合には、unwind-protectにより設定されたいくつかのクリーンアップも実行されます。

ジャンプ先となるcatch内にレキシカル(局所的)である必要はありません。throwcatch内で呼び出された別の関数から、同じようにに呼び出すことができます。throwが行なわれたのが、時系列的にcatchに入った後で、かつexitする前である限り、そのthrowcatchにアクセスできます。エディターのコマンドループから戻るexit-recursive-editのようなコマンドで、throwが使用されるのはこれが理由です。

Common Lispに関する注意: Common Lispを含む、他のほとんどのバージョンのLispは非シーケンシャルに制御を移すいくつかの方法 — たとえばreturnreturn-fromgo — をもつ。Emacs Lispはthrowのみ。cl-libライブラリーはこれらのうちいくつかを提供する。Blocks and Exits in Common Lisp Extensionsを参照のこと。

Special Form: catch tag body…

catchthrow関数にたいするリターン位置を確立する。リターン位置はtagにより、この種の他のリターン位置と区別される。tagnil以外の任意のLispオブジェクト。リターン位置が確立される前に、引数tagは通常どおり評価される。

リターン位置が有効な場合、catchbodyのフォームをテキスト順に評価する。フォームが(エラーや非ローカル脱出なしで)通常に実行されたなら、bodyの最後のフォームの値がcatchからリターンされる。

bodyの実行の間にthrowが実行された場合、tagと同じ値を指定するとcatchフォームは即座にexitする。リターンされる値は、それが何であれthrowの2番目の引数に指定された値である。

Function: throw tag value

throwの目的は、以前にcatchにより確立されたリターン位置に戻ることである。引数tagは、既存のさまざまなリターン位置からリターン位置を選択するために使用される。複数のリターン位置がtagにマッチしたら、最も内側のものが使用される。

引数valuecatchからリターンされる値として使用される。

タグtagのリターン位置が存在しなければ、データ(tag value)とともにno-catchエラーがシグナルされます。


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

11.7.2 catchthrowの例

2重にネストされたループから脱出する1つの方法は、catchthrowを使うことです(これはほとんどの言語ではgotoにより行なわれるだろう)。ここではijを0から9に変化させて、(foo i j)を計算します:

(defun search-foo ()
  (catch 'loop
    (let ((i 0))
      (while (< i 10)
        (let ((j 0))
          (while (< j 10)
            (if (foo i j)
                (throw 'loop (list i j)))
            (setq j (1+ j))))
        (setq i (1+ i))))))

fooが非nilをリターンしたら即座に処理を中止して、ijのリストをリターンしています。fooが常にnilをリターンする場合には、catchは通常どおりリターンして、その値はwhileの結果であるnilとなります。

以下では2つのリターン位置を一度に表す、微妙に異なるトリッキーな例を2つ示します。まず同じタグhackにたいして2つのリターン位置があります:

(defun catch2 (tag)
  (catch tag
    (throw 'hack 'yes)))
⇒ catch2

(catch 'hack
  (print (catch2 'hack))
  'no)
-| yes
⇒ no

どちらのリターン位置もthrowにマッチするタグをもつので内側のもの、つまりcatch2で確立されたcatchへgotoします。したがってcatch2は通常どおり値yesをリターンして、その値がプリントされます。最後に外側のcatchの2番目のbody、つまり'noが評価されて外側のcatchからそれがリターンされます。

ここでcatch2に与える引数を変更してみましょう:

(catch 'hack
  (print (catch2 'quux))
  'no)
⇒ yes

この場合も2つのリターン位置がありますが、今回は外側だけがタグhackで、内側はかわりにタグquuxをもちます。したがってthrowにより、外側のcatchが値yesをリターンします。関数printが呼び出されることはなくbodyのフォーム'noも決して評価されません。


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

11.7.3 エラー

Emacs Lispが何らかの理由で評価できないようなフォームの評価を試みると、エラー(error)シグナル(signal)されます。

エラーがシグナルされるとエラーメッセージを表示して、カレントコマンドの実行を終了するのがEmacsデフォルトの反応です。たとえばバッファーの最後でC-fとタイプしたときのように、ほとんどの場合にはこれは正しい反応になります。

複雑なプログラムでは単なる終了が望ましくない場合もあるでしょう。たとえばそのプログラムがデータ構造に一時的に変更を行なっていたり、プログラム終了前に削除する必要がある一時バッファーを作成しているかもしれません。このような場合には、エラー時に評価されるクリーンアップ式(cleanup expressions)を設定するために、unwind-protectを使用するでしょう(非ローカル脱出のクリーンアップを参照)。サブルーチン内のエラーにもかかわらずに、プログラムの実行を継続したいときがあるかもしれません。このような場合には、エラー時のリカバリーを制御するエラーハンドラー(error handlers)を設定するためにcondition-caseを使用するでしょう。

カレントコマンドの実行を終了せずに問題を報告するためには、かわりに警告の発行を考慮しましょう。警告のレポートを参照してください。

エラーハンドラーを使用せずにプログラムの一部から別の部分へ制御を移すためには、catchthrowを使用します。明示的な非ローカル脱出: catchthrowを参照してください。


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

11.7.3.1 エラーをシグナルする方法

エラーのシグナリング(signaling)とは、エラーの処理を開始することを意味します。エラー処理は通常は実行中のプログラムのすべて、または一部をアボート(abort)してエラーをハンドルするためにセットアップされた位置にリターンします。ここではエラーをシグナルする方法を記述します。

ほとんどのエラーは、たとえば整数にたいしてCARの取得を試みたり、バッファーの最後で1文字前方に移動したときなどのように、他の目的のために呼び出したLispプリミティブ関数の中で自動的にシグナルされます。関数errorsignalで明示的にエラーをシグナルすることもできます。

ユーザーがC-gをタイプしたときに発生するquitはエラーとは判断されませんが、ほとんどはエラーと同様に扱われます。quitを参照してください。

すべてのエラーメッセージはそれぞれ、何らかのエラーメッセージを指定します。そのメッセージはどうであるべきか(“File must exist”)ではなく、何が悪いのか(“File does not exist”)を示すべきです。Emacs Lispの慣習ではエラーメッセージは大文字で開始され、区切り文字で終わるべきではありません。

Function: error format-string &rest args

この関数はformat-stringargsにたいして、format-message (文字列のフォーマットを参照)を適用して構築されたエラーメッセージとともに、エラーをシグナルする。

以下はerrorを使用する典型的な例である:

(error "That is an error -- try something else")
     error→ That is an error -- try something else

(error "Invalid name `%s'" "A%%B")
     error→ Invalid name ‘A%%B’

2つの引数 — エラーシンボルerrorformat-messageがリターンする文字列を含むリスト — でsignalを呼び出すことによりerrorは機能する。

"Missing `%s'""Missing ‘foo’"となるように、通常はフォーマット内のgrave accentとapostropheはマッチするcurved quotesに変換される。この変換の効果や抑制についてはテキストのクォートスタイルを参照のこと。

警告: エラーメッセージとして固定の文字列を使用したい場合、単に(error string)とは記述しないこと。もしstringが‘%’、‘`’、‘'’を含んでいると、再フォーマットされて望む結果は得られないだろう。かわりに、(error "%s" string)を使用すること。

Function: signal error-symbol data

この関数はerror-symbolで命名されるエラーをシグナルする。引数dataはエラー状況に関連する追加のLispオブジェクトのリスト。

引数error-symbolエラーシンボル(error symbol)define-errorで定義されたシンボル — でなければならない。これはEmacs Lispが異なる種類のエラーをクラス分けする方法である。エラーシンボル(error symbol)、エラーコンディション(error condition)、コンディション名(condition name)の説明についてはエラーシンボルとエラー条件を参照のこと。

エラーが処理されない場合には、エラーメッセージをプリントするために2つの引数が使用される。このエラーメッセージは通常、error-symbolerror-messageプロパティにより提供される。dataが非nilなら、その後にコロンとdataの未評価の要素をカンマで区切ったリストが続く。errorにたいするエラーメッセージはdataCARである(文字列であること)。サブカテゴリーfile-errorは特別に処理される。

data内のオブジェクトの数と意味はerror-symbolに依存する。たとえばwrong-type-argumentエラーではリスト内に2つのオブジェクト — 期待する型を記述する述語とその型への適合に失敗したオブジェクト — であること。

エラーを処理する任意のエラーハンドラーにたいしてerror-symboldataの両方を利用できる。condition-caseはローカル変数を(error-symbol . data)というフォームでバインドする(エラーを処理するコードの記述を参照)。

関数signalは決してリターンしない。

(signal 'wrong-number-of-arguments '(x y))
     error→ Wrong number of arguments: x, y

(signal 'no-such-error '("My unknown error condition"))
     error→ peculiar error: "My unknown error condition"
Function: user-error format-string &rest args

この関数は、errorとまったく同じように振る舞うが、errorではなくエラーシンボルuser-errorを使用する。名前が示唆するように、このエラーはコード自身のエラーではなく、ユーザー側のエラーの報告を意図している。たとえばInfoの閲覧履歴の開始を超えて履歴を遡るためにコマンドInfo-history-back (l)を使用した場合、Emacsはuser-errorをシグナルする。このようなエラーでは、たとえdebug-on-errorが非nilであっても、デバッガーへのエントリーは発生しない。エラーによるデバッガへのエンターを参照のこと。

Common Lispに関する注意: Emacs LispにはCommon Lispのような継続可能なエラーのような概念は存在しない。


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

11.7.3.2 Emacsがエラーを処理する方法

エラーがシグナルされたとき、signalはそのエラーにたいするアクティブなハンドラー(handler)を検索します。ハンドラーとは、Lispプログラムの一部でエラーが発生したときに実行するよう意図されたLisp式のシーケンスです。そのエラーが適切なハンドラーをもっていればそのハンドラーが実行され、そのハンドラーの後から実行が再開されます。ハンドラーはそのハンドラーが設定されたcondition-caseの環境内で実行されます。condition-case内のすべての関数呼び出しはすでに終了しているので、ハンドラーがそれらにリターンすることはありません。

そのエラーにたいする適切なハンドラーが存在しなければ、カレントコマンドを終了してエディターのコマンドループに制御をリターンします(コマンドループにはすべての種類のエラーにたいする暗黙のハンドラーがある)。コマンドループのハンドラーは、エラーメッセージをプリントするためにエラーシンボルと、それに関連付けられたデータを使用します。変数command-error-functionを使用して、これが行なわれる方法を制御できます:

Variable: command-error-function

この変数が非nilなら、それはEmacsのコマンドループに制御をリターンしたエラーの処理に使用する関数を指定する。この関数は3つの引数を受け取る。1つ目のdataは、condition-caseが自身の変数にバインドするのと同じフォーム。2つ目のcontextはエラーが発生した状況を記述する文字列か、(大抵は)nil。3つ目のcallerはエラーをシグナルしたプリミティブ関数を呼び出したLisp関数。

明示的なハンドラーがないエラーは、Lispデバッガーを呼び出すかもしれません。変数debug-on-error (エラーによるデバッガへのエンターを参照)が非nilならデバッガーが有効です。エラーハンドラーと異なり、デバッガーはそのエラーの環境内で実行されるので、エラー時の変数の値を正確に調べることができます。


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

11.7.3.3 エラーを処理するコードの記述

エラーをシグナルすることによる通常の効果は、実行されていたコマンドを終了してEmacsエディターのコマンドループに即座にリターンすることです。スペシャルフォームcondition-caseを使用してエラーハンドラーを設定することにより、プログラム内の一部で発生するエラーのをトラップを調整することができます。以下は単純な例です:

(condition-case nil
    (delete-file filename)
  (error nil))

これはfilenameという名前のファイルを削除して、任意のエラーをcatch、エラーが発生した場合はnilをリターンします(このような単純なケースではマクロignore-errorsを使用することもできる。以下を参照のこと)。

condition-case構文は、insert-file-contents呼び出しによるファイルオープンの失敗のような、予想できるエラーをトラップするために多用されます。condition-case構文はユーザーから読み取った式を評価するプログラムのような、完全には予測できないエラーのトラップにも使用されます。

condition-caseの2番目の引数は保護されたフォーム(protected form)と呼ばれます(上記の例では保護されたフォームはdelete-fileの呼び出し)。このフォームの実行が開始されるとエラーハンドラーが効果をもち、このフォームがリターンすると不活性になります。その間のすべてにおいてエラーハンドラーは効果をもちます。特にこのフォームで呼び出された関数とそのサブルーチン等を実行する間、エラーハンドラーは効果をもちます。厳密にいうと保護されたフォーム自身ではなく、保護されたフォームから呼び出されたLispプリミティブ関数(signalerrorを含む)だけがシグナルされるというのは、よいことと言えます。

保護されたフォームの後の引数はハンドラーです。各ハンドラーはそれぞれ、どのエラーを処理するかを指定する1つ以上のコンディション名(シンボル)をリストします。エラーがシグナルされたとき、エラーシンボルはコンディション名のリストも定義します。エラーが共通のコンディション名をもつ場合、そのハンドラーがそのエラーに適用されます。上記の例では1つのハンドラーがあり、それはすべてのエラーをカバーするコンディション名errorを指定しています。

適切なハンドラーの検索は、もっとも最近に設定されたハンドラーから始まり、設定されたすべてのハンドラーをチェックします。したがってネストされたcondition-caseフォームに同じエラー処理がある場合には、内側のハンドラーがそれを処理します。

何らかのcondition-caseによりエラーが処理されると、debug-on-errorでエラーによりデバッガーが呼び出されるようにしていても、通常はデバッガーの実行が抑制されます。

condition-caseで補足されるようなエラーをデバッグできるようにしたいなら、変数debug-on-signalに非nil値をセットします。以下のようにコンディション内にdebugを記述することにより、最初にデバッガーを実行するような特定のハンドラーを指定することもできます:

(condition-case nil
    (delete-file filename)
  ((debug error) nil))

ここでのdebugの効果は、デバッガー呼び出しを抑制するcondition-caseを防ぐことだけです。debug-on-errorとその他のフィルタリングメカニズムがデバッガーを呼び出すように指定されているときだけ、エラーによりデバッガーが呼び出されます。エラーによるデバッガへのエンターを参照してください。

Macro: condition-case-unless-debug var protected-form handlers…

マクロcondition-case-unless-debugは、そのようなフォームのデバッギングを処理する、別の方法を提供する。このマクロは変数debug-on-errornil、つまり任意のエラーを処理しないようなケース以外は、condition-caseとまったく同様に振る舞う。

特定のハンドラーがそのエラーを処理するとEmacsが判断すると、Emacsは制御をそのハンドラーにreturnします。これを行うために、Emacsはそのとき脱出しつつあるバインディング構成により作成されたすべての変数のバインドを解き、そのとき脱出しつつあるすべてのunwind-protectフォームを実行します。制御がそのハンドラーに達すると、そのハンドラーのbodyが通常どおり実行されます。

そのハンドラーのbodyを実行した後、condition-caseフォームから実行がreturnされます。保護されたフォームは、そのハンドラーの実行の前に完全にexitしているので、そのハンドラーはそのエラーの位置から実行を再開することはできず、その保護されたフォーム内で作られた変数のバインディングを調べることもできません。ハンドラーが行なえることは、クリーンアップと、処理を進行させることだけです。

エラーのシグナルとハンドルにはthrowcatch (明示的な非ローカル脱出: catchthrowを参照)に類似する点がいくつかありますが、これらは完全に別の機能です。エラーはcatchでキャッチできず、throwをエラーハンドラーで処理することはできません(しかし対応するcatchが存在しないときにthrowを使用することによりシグナルされるエラーは処理できる)。

Special Form: condition-case var protected-form handlers…

このスペシャルフォームはprotected-formの実行を囲い込むエラーハンドラーhandlersを確立する。エラーなしでprotected-formが実行されると、リターンされる値はcondition-caseフォームの値になる(成功ハンドラー不在時。以下参照)。この場合にはcondition-caseは効果をもたない。protected-formの間にエラーが発生すると、condition-caseフォームは違いを生じる。

handlersはそれぞれ、(conditions body…)というフォームのリストである。ここでconditionsはハンドルされるエラーコンディション名、またはそのハンドラーの前にデバッガーを実行するためのコンディション名(debugを含む)。tというコンディション名はすべてのコンディションにマッチする。bodyはこのハンドラーがエラーを処理するときに実行される1つ以上のLisp式。

(error nil)

(arith-error (message "Division by zero"))

((arith-error file-error)
 (message
  "Either division by zero or failure to open a file"))

発生するエラーはそれぞれ、それが何の種類のエラーかを記述するエラーシンボル(error symbol)をもち、これはコンディション名のリストも記述する(エラーシンボルとエラー条件を参照)。Emacsは1つ以上のコンディション名を指定するハンドラーにたいして、すべてのアクティブなcondition-caseフォームを検索する。condition-caseの最も内側のマッチがそのエラーを処理する。condition-case内では、最初に適合したハンドラーがそのエラーを処理する。

ハンドラーのbodyを実行した後、condition-caseは通常どおりリターンして、ハンドラーのbodyの最後の値をハンドラー全体の値として使用する。

引数varは変数である。protected-formを実行するとき、condition-caseはこの変数をバインドせず、エラーを処理するときだけバインドする。その場合には、varエラー記述(error description)にバインドする。これはエラーの詳細を与えるリストである。このエラー記述は(error-symbol . data)というフォームをもつ。ハンドラーは何を行なうか決定するために、このリストを参照することができる。たとえばファイルオープンの失敗にたいするエラーなら、ファイル名がdata(エラー記述の3番目の要素)の2番目の要素になる。

varnilなら、それはバインドされた変数がないことを意味する。この場合、エラーシンボルおよび関連するデータは、そのハンドラーでは利用できない。

特殊なケースとしてhandlersのいずれか1つが(:success body…)形式のリストの場合がある。ここでbodyprotected-formがエラーなしで終了した際のリターン値(非nilの場合)にバインドされたvarとともに実行される。

より外側のレベルのハンドラーにcatchさせるために、condition-caseによりcatchされたシグナルを再度throwする必要がある場合もある。以下はこれを行なう方法である:

  (signal (car err) (cdr err))

ここでerrはエラー記述変数(error description variable)で、condition-caseの1番目の引数は、再throwしたいエラーコンディション。Definition of signalを参照のこと。

Function: error-message-string error-descriptor

この関数は与えられたエラー記述子(error descriptor)にたいするエラーメッセージ文字列をリターンする。これはそのエラーにたいする通常のエラーメッセージをプリントすることにより、エラーを処理したい場合に有用。Definition of signalを参照のこと。

以下は0除算の結果によるエラーを処理するために、condition-caseを使用する例です。このハンドラーは、(beepなしで)エラーメッセージを表示して、非常に大きい数をリターンします。

(defun safe-divide (dividend divisor)
  (condition-case err
      ;; 保護されたフォーム
      (/ dividend divisor)
    ;; ハンドラー
    (arith-error                        ; コンディション
     ;; このエラーにたいする、通常のメッセージを表示する
     (message "%s" (error-message-string err))
     1000000)))
⇒ safe-divide

(safe-divide 5 0)
     -| Arithmetic error: (arith-error)
⇒ 1000000

このハンドラーはコンディション名arith-errorを指定するので、division-by-zero(0除算)エラーだけを処理します。他の種類のエラーは(このcondition-caseによっては)、処理されません。したがって:

(safe-divide nil 3)
     error→ Wrong type argument: number-or-marker-p, nil

以下はerrorによるエラーを含む、すべての種類のエラーをcatchするcondition-caseです:

(setq baz 34)
     ⇒ 34

(condition-case err
    (if (eq baz 35)
        t
      ;; 関数errorの呼び出し
      (error "Rats!  The variable %s was %s, not 35" 'baz baz))
  ;; フォームではないハンドラー
  (error (princ (format "The error was: %s" err))
         2))
-| The error was: (error "Rats!  The variable baz was 34, not 35")
⇒ 2
Macro: ignore-errors body…

この構文は、それの実行中に発生する任意のエラーを無視してbodyを実行する。その実行中にエラーがなければ、ignore-errorsbody内の最後のフォームの値を、それ以外はnilをリターンする。

以下はこのセクションの最初の例をignore-errorsを使用して記述する例である:

  (ignore-errors
   (delete-file filename))
Macro: ignore-error condition body…

このマクロはignore-errorsと同様だが、指定した特定のエラーコンディションだけを無視する点が異なる。

  (ignore-error end-of-file
    (read ""))

conditionはエラーコンディションのリストでも可。

Macro: with-demoted-errors format body…

このマクロはいわばignore-errorsの穏やかなバージョンである。これはエラーを完全に抑止するのではなく、エラーをメッセージに変換する。これはメッセージのフォーマットに、文字列formatを使用する。format"Error: %S"のように、単一の‘%’シーケンスを含むこと。エラーをシグナルするとは予測されないが、もし発生した場合は堅牢であるべきようなコードの周囲にwith-demoted-errorsを使用する。このマクロはcondition-caseではなく、condition-case-unless-debugを使用することに注意。


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

11.7.3.4 エラーシンボルとエラー条件

エラーをシグナルするとき、想定するエラーの種類を指定するためにエラーシンボル(error symbol)を指定します。エラーはそれぞれ、それをカテゴリー分けするために単一のエラーシンボルをもちます。これはEmacs Lisp言語で定義されるエラーを分類する、もっともよい方法です。

これらの狭義の分類はエラー条件(error conditions)と呼ばれる、より広義のクラス階層にグループ化され、それらはコンディション名(condition names)により識別されます。そのようなもっとも狭義なクラスは、エラーシンボル自体に属します。つまり各エラーシンボルは、コンディション名でもあるのです。すべての種類のエラー(quitを除く)を引き受けるコンディション名errorに至る、より広義のクラスにたいするコンディション名も存在します。したがって各エラーは1つ以上のコンディション名をもちます。つまりerrorerrorとは区別されるエラーシンボル、もしかしたらその中間に分類されるものかもしれません。

Function: define-error name message &optional parent

シンボルをエラーシンボルとするために、シンボルは親コンディションを受け取るdefine-errorで定義されなければならない。この親はその種のエラーが属するコンディションを定義する。親の推移的な集合は、常にそのエラーシンボルとシンボルerrorを含む。quitはエラーと判断されないので、quitの親の集合は単なる(quit)である。

親のコンディションに加えてエラーシンボルはメッセージ(message)をもち、これは処理されないエラーがシグナルされたときプリントされる文字列です。そのメッセージが有効でなければ、エラーメッセージ‘peculiar error’が使用されます。Definition of signalを参照してください。

内部的には親の集合はエラーシンボルのerror-conditionsプロパティに格納され、メッセージはエラーシンボルのerror-messageプロパティに格納されます。

以下は新しいエラーシンボルnew-errorを定義する例です:

(define-error 'new-error "A new error" 'my-own-errors)

このエラーは複数のコンディション名 — もっとも狭義の分類new-error、より広義の分類を想定するmy-own-errors、およびmy-own-errorsのコンディションすべてを含むerrorであり、これはすべての中でもっとも広義なものです。

エラー文字列は大文字で開始されるべきですが、ピリオドで終了すべきではありません。これはEmacsの他の部分との整合性のためです。

もちろんEmacs自身がnew-errorをシグナルすることはありません。あなたのコード内で明示的にsignal (Definition of signalを参照)を呼び出すことにより、これを行なうことができます。

(signal 'new-error '(x y))
     error→ A new error: x, y

このエラーは、エラーの任意のコンディション名により処理することができます。以下の例はnew-errorとクラスmy-own-errors内の他の任意のエラーを処理します:

(condition-case foo
    (bar nil t)
  (my-own-errors nil))

エラーが分類される有効な方法はコンディション名による方法で、その名前はハンドラーのエラーのマッチに使用されます。エラーシンボルは意図されたエラーメッセージと、コンディション名のリストを指定する便利な方法であるという役割をもつだけです。1つのエラーシンボルではなく、コンディション名のリストをsignalに与えるのは面倒でしょう。

対照的にコンディション名を伴わずにエラーシンボルだけを使用すると、それはcondition-caseの効果を著しく減少させるでしょう。コンディション名はエラーハンドラーを記述するとき、一般性のさまざまなレベルにおいて、エラーをカテゴリー分けすることを可能にします。エラーシンボルを単独で使用することは、もっとも狭義なレベルの分類を除くすべてを捨ててしまうことです。

主要なエラーシンボルとそれらのコンディションについては、標準的なエラーを参照してください。


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

11.7.4 非ローカル脱出のクリーンアップ

unwind-protect構文は、データ構造を一時的に不整合な状態に置くときに重要です。これはエラーやthrouのイベントにより、再びデータを整合された状態にすることができます(バッファー内容の変更だけに使用される他のクリーンアップ構成はアトミックな変更グループである。グループのアトミックな変更を参照)。

Special Form: unwind-protect body-form cleanup-forms…

unwind-protectは制御がbody-formを離れる場合に、cleanup-formsが評価されるという保証の下において、何が起こったかに関わらずbody-formを実行する。body-formは通常どおり完了するかもしれず、unwind-protectの外側でthrowの実行やエラーが発生するかもしれないが、cleanup-formsは評価される。

body-formが正常に終了したら、unwind-protectcleanup-formsを評価した後に、body-formの値をリターンする。body-formが終了しなかったら、unwind-protectは通常の意味におけるような値はリターンしない。

unwind-protectで保護されるのはbody-formだけである。cleanup-forms自体の任意のフォームが、(throwまたはエラーにより)非ローカルにexitすると、unwind-protectは残りのフォームが評価されることを保証しないcleanup-formsの中の1つが失敗することが問題となるようなら、そのフォームの周囲に他のunwind-protectを配置して保護すること。

たとえば以下は一時的な使用のために不可視のバッファーを作成して、終了する前に確実にそのバッファーをkillする例です:

(let ((buffer (get-buffer-create " *temp*")))
  (with-current-buffer buffer
    (unwind-protect
        body-form
      (kill-buffer buffer))))

(kill-buffer (current-buffer))のように記述して、変数bufferを使用せずに同様のことを行えると思うかもしれません。しかし上の例は、別のバッファーにスイッチしたときにbody-formでエラーが発生した場合、より安全なのです(一時的なバッファーをkillするとき、そのバッファーがカレントとなることを確実にするために、かわりにbody-formの周囲にsave-current-bufferを記述することもできる)。

Emacsには上のコードとおおよそ等しいコードに展開される、with-temp-bufferという標準マクロが含まれます(Current Bufferを参照)。このマニュアル中で定義されるいくつかのマクロは、この方法でunwind-protectを使用します。

以下はFTPパッケージ由来の実例です。これはリモートマシンへの接続の確立を試みるために、プロセス(プロセスを参照)を作成しています。関数ftp-loginは関数の作成者が予想できない多くの問題から非常に影響を受け易いので、失敗イベントでプロセスの削除を保証するフォームで保護されています。そうしないとEmacsは無用なサブプロセスで一杯になってしまうでしょう。

(let ((win nil))
  (unwind-protect
      (progn
        (setq process (ftp-setup-buffer host file))
        (if (setq win (ftp-login process host user password))
            (message "Logged in")
          (error "Ftp login failed")))
    (or win (and process (delete-process process)))))

この例には小さなバグがあります。ユーザーがquitするためにC-gとタイプすると、関数ftp-setup-bufferのリターン後に即座にquitが発生しますが、それは変数processがセットされる前なので、そのプロセスはkillされないでしょう。このバグを簡単に訂正する方法はありませんが、少なくともこれは非常に稀なことだと言えます。


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

12 変数

変数(variable)とはプログラム内で値を表すために使用される名前です。Lispでは変数はそれぞれLispシンボルとして表されます(シンボルを参照)。変数名は単にそのシンボルの名前であり、変数の値はそのシンボルの値セル(value cell)に格納されます9シンボルの構成要素を参照してください。Emacs Lispではシンボルを変数として使用することは、同じシンボルを関数名として使用することと関係ありません。

このマニュアルで前述したとおり、Lispプログラムはまず第1にLispオブジェクトとして表され、副次的にテキストとして表現されます。Lispプログラムのテキスト的な形式は、そのプログラムを構成するLispオブジェクトの入力構文により与えられます。したがってLispプログラム内の変数のテキスト的な形式は、その変数を表すシンボルの入力構文を使用して記述されます。


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

12.1 グローバル変数

変数を使用するための一番シンプルな方法は、グローバル(globally)を使用する方法です。これはある時点でその変数はただ1つの値をもち、その値が(少なくともその時点では)Lispシステム全体で効果をもつことを意味します。あらたな値を指定するまでその値が効果をもちます。新しい値で古い値を置き換えるとき、古い値を追跡する情報は変数内に残りません。

シンボルの値はsetqで指定します。たとえば、

(setq x '(a b))

これは変数xに値(a b)を与えます。setqはスペシャルフォームであることに注意してください。これは1番目の引数(変数の名前)は評価しませんが、2番目の引数(新しい値)は評価します。

変数が一度値をもつと、そのシンボル自身を式として使用することによって参照することができます。したがって、

x ⇒ (a b)

これは上記のsetqフォームが実行された場合です。

同じ変数を再びセットすると、古い値は新しい値で置き換えられます:

x
     ⇒ (a b)
(setq x 4)
     ⇒ 4
x
     ⇒ 4

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

12.2 変更不可な変数

Emacs Lispでは特定のシンボルは、通常は自分自身に評価されます。これらのシンボルにはnilt、同様に名前が‘:’で始まる任意のシンボル(これらはキーワードと呼ばれる)が含まれます。これらのシンボルはリバインドや、値の変更はできません。niltへのセットやリバインドは、setting-constantエラーをシグナルします。これはキーワード(名前が‘:’で始まるシンボル)についても当てはまります。ただしキーワードが標準のobarrayにinternされていれば、そのようなシンボルを自分自身にセットしてもエラーになりません。

nil ≡ 'nil
     ⇒ nil
(setq nil 500)
error→ Attempt to set constant symbol: nil
Function: keywordp object

この関数はobjectが‘:’で始まる名前のシンボルであり、標準のobarrayにinternされていればt、それ以外はnilをリターンする。

これらの定数はスペシャルフォームdefconst(グローバル変数の定義を参照)を使用して定義された定数(constant)とは根本的に異なります。defconstフォームは、人間の読み手に値の変更を意図しない変数であることを知らせる役目は果たしますが、実際にそれを変更してもEmacsはエラーを起こしません。

現実的な種々の理由により、追加で少数のシンボルが読み取り専用になります。これらにはenable-multibyte-charactersmost-positive-fixnummost-negative-fixnumの他にいくつかのシンボルが含まれます。これらにたいしてセットやバインドを試みると、すべてsetting-constantエラーがシグナルされます。


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

12.3 ローカル変数

グローバル変数は新しい値で明示的に置き換えるまで値が持続します。変数にローカル値(local value) — Lispプログラム内の特定の部分で効果をもつ — を与えると便利なときがあります。変数がローカル値をもつとき、わたしたちは変数がその値にローカルにバインド(locally bound)されていると言い、その変数をローカル変数(local variable)と呼びます。

たとえば関数が呼び出されるとき、関数の引数となる変数はローカル値(その関数の呼び出しにおいて実際の引数に与えられた値)を受け取ります。これらのローカルバインディングは関数のbody内で効果をもちます。他にもたとえばスペシャルフォームletは特定の変数にたいして明示的にローカルなバインディングを確立して、これはletフォームのbody内だけで効果を持ちます。

これにたいしてグローバルなバインディング(global binding)とは、(概念的には)グローバルな値が保持される場所です。

ローカルバインディングを確立すると、その変数の以前の値は他の場所に保存されます(または失われる)。わたしたちはこれを、以前の値がシャドー(shadowed)されたと言います。シャドーはグローバル変数とローカル変数の両方で発生し得ます。ローカルバインディングが効果を持つときには、ローカル変数にsetqを使用することにより、指定した値をローカルバインディングに格納します。ローカルバインディングが効果を持たなくなったとき、以前にシャドーされた値が復元されます(または失われる)。

変数は同時に複数のローカルバインディングを持つことができます(たとえばその変数をバインドするネストされたlet)。カレントバインディング(current binding)とは、実際に効果を持つローカルバインディングのことです。カレントバインディングは、その変数の評価によりリターンされる値を決定し、setqにより影響を受けるバインディングです。

ほとんどの用途において、最内(innermost)のローカルバインディングとローカルバインディングをもたないグローバルバインディングを、カレントバインディングと考えることができます。より正確に言うと、スコープルール(scoping rule)と呼ばれるルールは、プログラム内でローカルバインディングが効果を持つ任意の与えられた場所を決定します。Emacs Lispのスコープルールはダイナミックスコープ(dynamic scoping)と呼ばれ、これは単に実行中のプログラム内の与えられた位置でのカレントバインディングを示しており、その変数がまだ存在すれば、その変数にたいしてもっとも最近作成されたバインディングです。ダイナミックスコープについての詳細、およびその代替であるレキシカルスコープ(lexical scoping)と呼ばれるスコープルールについては、変数のバインディングのスコーピングルールを参照してください。Emacsの最近の動向として、レキシカルバインディングをデフォルトにするという最終ゴールに向けて、レキシカルバインディングがますます多くの場所で使用される方向に進んでいます。特にEmacs Lispのソースファイルすべてと*scratch*バッファーではレキシカルなスコープが使用されています。

スペシャルフォームletlet*は、ローカルバインディングを作成するために存在します:

Special Form: let (bindings…) forms…

このスペシャルフォームはbindingsにより指定される特定の変数セットにたいするローカルバインディングをセットアップしてから、formsのすべてをテキスト順に評価する。これはforms内の最後のフォームの値をリターンする。letがセットアップしたローカルバインディングはformsのbody内でのみ効果をもつ。

bindingsの各バインディングは2つの形式のいずれかである。(i) シンボルなら、そのシンボルはnilにローカルにバインドされる。(ii) フォーム(symbol value-form)のリストなら、symbolvalue-formを評価した結果へローカルにバインドされる。value-formが省略されたらnilが使用される。

bindings内のすべてのvalue-formは、シンボルがそれらにバインドされるに、記述された順番に評価される。以下の例ではzyの新しい値(つまり1)にではなく、古い値(つまり2)にバインドされる。

(setq y 2)
     ⇒ 2

(let ((y 1)
      (z y))
  (list y z))
     ⇒ (1 2)

その一方でbindingsの順序は指定されない。以下の例では1か2のどちらかがプリントされる。

(let ((x 1)
      (x 2))
  (print x))

したがって単一のletフォーム内で変数を複数回バインディングするのは避けること。

Special Form: let* (bindings…) forms…

このスペシャルフォームはletと似ているが、次の変数値にたいするローカル値を計算する前に、ローカル値を計算してそれを変数にバインドする。したがてbindings内の式は、このlet*フォーム内の前のシンボルのバインドを参照できる。以下の例を上記letの例と比較されたい。

(setq y 2)
     ⇒ 2

(let* ((y 1)
       (z y))    ; yの値に今計算されたばかりの値を使用する
  (list y z))
     ⇒ (1 1)

上記例におけるxylet*バインディングは、基本的には以下のようなネストされたletを使うのと同じ:

(let ((y 1))
  (let ((z y))
    (list y z)))
Special Form: letrec (bindings…) forms…

このスペシャルフォームはlet*と同様だが、ローカル値を計算する前にすべての変数をバインドする。値はその後にバインドされた変数にローカルに割り当てられる。これはレキシカルバインディングが効力をもち、let*の使用しても有効にならないバインディングを参照するクロージャを作成したい場合のみ有用。

たとえば以下は一度実行後にフックから自身を削除するクロージャ:

(letrec ((hookfun (lambda ()
                    (message "Run once")
                    (remove-hook 'post-command-hook hookfun))))
  (add-hook 'post-command-hook hookfun))
Special Form: dlet (bindings…) forms…

このスペシャルフォームはletと似ているが、すべての変数をダイナミックにバインドする。これが役に立つことは稀だろう — 通常ならノーマル変数はレキシカルに、スペシャル変数(defvarで定義された変数)はダイナミックにバインドしたいと望むだろうし、これは正にletが行うことだからだ。

特定の変数がダイナミックにバインド(ダイナミックバインディングを参照)されていることを想定している古いコードとインターフェイスをとる際、それらの変数をdefvarとするのは非現実的な場合にdletは有用かもしれない。dletはこれらの変数を一時的にスペシャルとしてバインドしてフォームを実行、それから再び変数を非スペシャルにする。

Special Form: named-let name bindings &rest body

このスペシャルフォームはScheme言語からインスパイアされたロープ構文である。これはletのようにbindings内の変数をバインドしてからbodyを評価する。ただしnamed-letは正規の引数がbindings内の変数で本体がbodyであるようなローカル関数にたいしてnameのバインドも行う。これによりnameを呼び出してbodyが自身を再帰的に呼び出すことができる。再帰呼び出しにおいては、バインドされる変数の新たな値としてnameに渡された引数が使用される。

数値にリストを加算するループの例:

(named-let sum ((numbers '(1 2 3 4))
                (running-sum 0))
  (if numbers
      (sum (cdr numbers) (+ running-sum (car numbers)))
    running-sum))
⇒ 10

body末尾位置(tail positions)におけるnameへの再帰呼び出しは、末尾呼び出し(tail calls)としての最適化が保証される。これは再帰の実行深さに関わらず追加のスタック空間を消費しないことを意味する。このような再帰呼び出しでは、変数にたいして新たな値でループ先頭に効果的にジャンプを行う。

一番最後に行うことが関数呼び出しならそれは末尾位置にあり、したがってその呼び出しのリターン値は上記sumにたいする再帰呼び出しと同じようにbodyの値となる。

警告: named-letが期待通り動作するのはレキシカルバインディングg有効な場合のみ。See レキシカルバインディングを参照のこと。

以下はローカルバインディングを作成する他の機能のリストです:

  • 関数呼び出し(関数を参照)。
  • マクロ呼び出し(マクロを参照)。
  • condition-case (エラーを参照)。

変数はバッファーローカルなバインディングを持つこともできます(バッファーローカル変数を参照)。数は多くありませんが、端末ローカル(terminal-local)なバインディングをもつ変数もあります(複数の端末を参照)。この種のバインディングは、通常のローカルバインディングのように機能することもありますが、これらはEmacs内のどこにいるかに依存してローカルになります。


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

12.4 変数がvoidのとき

シンボルの値セル(シンボルの構成要素を参照)に値が割り当てられていない場合、その変数はvoid(空)であると言います。

Emacs Lispのデフォルトであるダイナミックスコープルール(変数のバインディングのスコーピングルールを参照)の下では、値セルはその変数のカレント値(ローカルまたはグローバル)を保持します。値が割り当てられていない値セルは、値セルにnilをもつのとは異なることに注意してください。シンボルnilはLispオブジェクトであり、他のオブジェクトと同様に変数の値となることができます。nilは値なのです。変数がvoidの場合にその変数の評価を試みると、値をリターンするかわりに、void-variableエラーがシグナルされます。

オプションであるレキシカルスコープルール(lexical scoping rule)の下では、値セル保持できるのはその変数のグローバル値 — 任意のレキシカルバインディング構造の外側の値だけです。変数がレキシカルにバインドされている場合、ローカル値はそのレキシカル環境により決定されます。したがってこれらのシンボルの値セルに値が割り当てられていなくても、変数はローカル値を持つことができます。

Function: makunbound symbol

この関数はsymbolの値セルを空にして、その変数をvoidにする。この関数はsymbolをリターンする。

symbolがダイナミックなローカルバインディングをもつなら、makunboundはカレントのバインディングをvoidにして、そのローカルバインディングが効果を持つ限りvoidにする。その後で以前にシャドーされたローカル値(またはグローバル値)が再び有効になって、再び有効になった値がvoidでなければ、その変数はvoidではなくなる。

いくつか例を示す(ダイナミックバインディングが有効だとする):

(setq x 1)               ; グローバルバインディングに値をセットする
     ⇒ 1
(let ((x 2))             ; それをローカルにバインドする
  (makunbound 'x)        ; ローカルバインディングをvoidにする
  x)
error→ Symbol's value as variable is void: x
x                        ; グローバルバインディングは変更されない
     ⇒ 1

(let ((x 2))             ; ローカルにバインドする
  (let ((x 3))           ; もう一度
    (makunbound 'x)      ; 最内のローカルバインディングをvoidにする
    x))                  ; それを参照すると、void
error→ Symbol's value as variable is void: x

(let ((x 2))
  (let ((x 3))
    (makunbound 'x))     ; 内側のバインディングをvoidにしてから取り除く
  x)                     ; 外側のletバインディングが有効になる
     ⇒ 2
Function: boundp variable

この関数はvariable(シンボル)がvoidでなければt、voidならnilをリターンする。

いくつか例を示す(ダイナミックバインディングが有効だとする):

(boundp 'abracadabra)          ; 最初はvoid
     ⇒ nil
(let ((abracadabra 5))         ; ローカルにバインドする
  (boundp 'abracadabra))
     ⇒ t
(boundp 'abracadabra)          ; グローバルではまだvoid
     ⇒ nil
(setq abracadabra 5)           ; グローバルで非voidにする
     ⇒ 5
(boundp 'abracadabra)
     ⇒ t

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

12.5 グローバル変数の定義

変数定義(variable definition)とは、そのシンボルをグローバル変数として使用する意図を表明する構文です。これには以下で説明するスペシャルフォームdefvardefconstが使用されます。

変数宣言は3つの目的をもちます。1番目はコードを読む人にたいして、そのシンボルが特定の方法(変数として)使用されることを意図したものだと知らせることです。2番目はLispシステムにたいしてオプションで初期値とドキュメント文字列を与えて、これを知らせることです。3番目はetagsのようなプログラミングツールにたいして、その変数が定義されている場所を見つけられるように情報を提供することです。

defconstdefvarの主な違いは、人間の読み手に値が変更されるかどうかを知らせることにあります。Emacs Lispは実際に、defconstで定義された変数の値の変更を妨げません。この2つのフォームの特筆すべき違いは、defconstは無条件で変数を初期化して、defvarは変数が元々voidのときだけ初期化することです。

カスタマイズ可能な変数を定義する場合は、defcustomを使用するべきです(これはサブルーチンとしてdefvarを呼び出す)。カスタマイゼーション変数の定義を参照してください。

Special Form: defvar symbol [value [doc-string]]

このスペシャルフォームは変数としてsymbolを定義する。symbolが評価されないことに注意。シンボルはdefvarフォーム内に明示的に表記して定義される必要がある。この変数は特別だとマークされて、これは常に変数がダイナミックにバインドされることを意味する(変数のバインディングのスコーピングルールを参照)。

valueが指定されていてsymbolがvoid(たとえばこのシンボルがダイナミックにバインドされた値を持たないとき。変数がvoidのときを参照)ならvalueが評価されて、その結果がsymbolにセットされる。しかしsymbolがvoidでなければ、valueは評価されずsymbolの値は変更されない。valueが省略された場合は、いかなる場合もsymbolの値は変更されない。

たとえnilであっても値を指定することにより、その変数は特別だと永続的にマークされることに注意。一方でvalueが省略されると変数はローカル(カレントのレキシカルスコープまたはトップレベルにあればファイル)でのみ特別だとマークされる。これはバイトコンパイルの警告を抑止するために有用。コンパイラーのエラーを参照のこと。

symbolがカレントバッファー内でバッファーローカルなバインディングをもつ場合、defvarはデフォルト値に作用する。デフォルト値はバッファーローカルなバインディングではなく、バッファーにたいして独立である。デフォルト値がvoidのときはデフォルト値をセットする。バッファーローカル変数を参照のこと。

すでにsymbolがletバインドされている(たとえばletフォーム内にdefvarがある)場合には、set-default-toplevel-valueと同じようにdefvarはトップレベルの値をセットする。letバインディングの構文を抜けるまでバインディングの効果は持続する。変数のバインディングのスコーピングルールを参照のこと。

C-M-x (eval-defun)、またはEmacs LispモードでC-x C-e (eval-last-sexp)によりトップレベルのdefvarを評価する際には、これら2つのコマンドの特別な機能はその値がvoidであるかテストすることなく、その変数を無条件にセットする。

引数doc-stringが与えられたら、それは変数にたいするドキュメント文字列を指定する(そのシンボルのvariable-documentationプロパティに格納される)。ドキュメントを参照のこと。

以下にいくつか例を示す。これはfooを定義するが初期化は行わない:

(defvar foo)
     ⇒ foo

以下の例はbarの値を23に初期化してドキュメント文字列を与える:

(defvar bar 23
  "The normal weight of a bar.")
     ⇒ bar

defvarフォームはsymbolをリターンするが、これは通常は値が問題にならないファイル内のトップレベルで使用される。

値をもたないdefvarのより詳細な使用例はLocal defvar exampleを参照のこと。

Special Form: defconst symbol value [doc-string]

このスペシャルフォームはある値でsymbolを定義して、それを初期化する。これはコードを読む人に、symbolがここで設定される標準的なグローバル値をもち、ユーザーや他のプログラムがそれを変更すべきではないことを知らせる。symbolが評価されないことに注意。定義されるシンボルはdefconst内に明示的に記されなければならない。

defvarと同様、defconstは変数を特別 — この変数が常にダイナミックにバインドされているという意味 — であるとマークする(変数のバインディングのスコーピングルールを参照)。加えてこれはその変数を危険であるとマークする(ファイルローカル変数を参照)。

defconstは常にvalueを評価して、その結果をsymbolの値にセットする。カレントバッファー内でsymbolがバッファーローカルなバインディングをもつなら、defconstはデフォルト値ではなくバッファーローカルな値をセットする(しかしdefconstで定義されたシンボルにたいしてバッファーローカルなバインディングを作らないこと)。

defconstの使い方の例は、Emacsのfloat-pi — (たとえインディアナ州議会が何を試みようと)何者かにより変更されるべきではない数学定数piにたいする定義である。しかし2番目のdefconstの例のように、これは単にアドバイス的なものである。

(defconst float-pi 3.141592653589793 "The value of Pi.")
     ⇒ float-pi
(setq float-pi 3)
     ⇒ float-pi
float-pi
     ⇒ 3

警告: 変数がローカルバインディングをもつとき(letにより作成された、または関数の引数の場合)に、スペシャルフォームdefconstまたはdefvarを使用すると、これらのフォームはグローバルバインディングではなく、ローカルバインディングをセットします。これは通常は、あなたが望むことではないはずです。これを防ぐには、これらのスペシャルフォームをファイル内のトップレベルで使用します。この場所は通常、何のローカルバインディングも効果をもたないので、その変数にたいするローカルバインディングが作成される前にファイルがロードされることが確実だからです。


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

12.6 堅牢な変数定義のためのヒント

値が関数(または関数のリスト)であるような変数を定義するときには、変数の名前の最後に‘-function’(または‘-functions’)を使用します。

他にも変数名に関する慣習があります。以下はその完全なリストです:

…-hook

変数はノーマルフック(フックを参照)。

…-function

値は関数。

…-functions

値は関数のリスト。

…-form

値はフォーム(式)。

…-forms

値はフォーム(式)のリスト。

…-predicate

値は述語(predicate) — 1つの引数をとる関数 — であり成功なら非nil、失敗ならnilをリターンする。

…-flag

nilか否かだけが意味をもつような値。結局そのような変数は、やがては多くの値をもつことが多いので、この慣習を強く推奨はしない。

…-program

値はプログラム名。

…-command

値は完全なシェルコマンド。

…-switches

値はコマンドにたいして指定するオプション。

prefix--…

これは内部的な使用を意図した変数でありファイルprefix.el内で定義される(他の規約にしたがうかもしれない2018年以前に貢献されたEmacsコードは段階的に廃止される)。

…-internal

これは内部的な使用を意図した変数でありファイルCコード内で定義される(他の規約にしたがうかもしれない2018年以前に貢献されたEmacsコードは段階的に廃止される)。

変数を定義するときは、その変数を安全(safe)とマークすべきか、それとも危険(risky)とマークすべきかを常に考慮してください。ファイルローカル変数を参照してください。

複雑な値を保持する変数(バインディングをもつkeymapなど)の定義や初期化を行う場合は、以下のように値の計算をすべてdefvarの中に配置するのが最良です:

(defvar my-mode-map
  (let ((map (make-sparse-keymap)))
    (keymap-set map "C-c C-a" 'my-command)
    …
    map)
  docstring)

この方法にはいくつかの利点があります。1つ目はファールをロード中にユーザーが中断した場合、変数はまだ初期化されていないか、初期化されているかのどちらかであり、その中間ということはありません。まだ初期化されていなければ、ファイルをリロードすれば正しく初期化されます。2つ目は一度初期化された変数は、ファイルをリロードしても変更されないことです。コンテンツの一部を変更(たとえばキーのリバインド)するフックをユーザーが実行した場合などに、これは重要です。3つ目はC-M-xdefvarを評価すると、そのマップは完全に再初期化されることです。


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

12.7 変数の値へのアクセス

変数を参照する通常の方法は、それに名前をつけるシンボルを記述する方法です。シンボルのフォームを参照してください。

実行時にのみ決定される変数を参照したいときがあるかもしれません。そのような場合、プログラム中のテキストで変数名を指定することはできません。そのような値を抽出するためにsymbol-valueを使うことができます。

Function: symbol-value symbol

この関数はsymbolの値セルに格納された値をリターンする。これはその変数の(ダイナミックな)カレント値が格納された場所である。その変数がローカルバインディングをもたなければ単にその変数のグローバル値になる。変数がvoidならvoid-variableはエラーをシグナルする。

その変数がレキシカルにバインドされていれば、symbol-valueが報告する値は、その変数のレキシカル値と同じである必要はない。レキシカル値はそのシンボルの値セルではなく、レキシカル環境により決定される。変数のバインディングのスコーピングルールを参照のこと。

(setq abracadabra 5)
     ⇒ 5
(setq foo 9)
     ⇒ 9

;; ここでシンボルabracadabra
;;   は値がテストされるシンボル
(let ((abracadabra 'foo))
  (symbol-value 'abracadabra))
     ⇒ foo

;; ここではabracadabraの値、
;;   つまりfooが値を
;;   テストされるシンボル
(let ((abracadabra 'foo))
  (symbol-value abracadabra))
     ⇒ 9

(symbol-value 'abracadabra)
     ⇒ 5

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

12.8 変数の値のセット

ある変数の値を変更する通常の方法は、スペシャルフォームsetqを使用する方法です。実行時に変数選択を計算する必要がある場合には関数setを使用します。

Special Form: setq [symbol form]…

このスペシャルフォームは、変数の値を変更するためのもっとも一般的な方法である。symbolにはそれぞれ、新しい値(対応するformが評価された結果)が与えられる。そのシンボルのカレントバインディングは変更される。

setqsymbolを評価せずに、記述されたシンボルをセットする。この引数のことを自動的にクォートされた(automatically quoted)と呼ぶ。setqの‘q’は“quoted(クォートされた)”が由来。

setqフォームの値は最後のformの値となる。

(setq x (1+ 2))
     ⇒ 3
x                   ; ここでxはグローバル値をもつ
     ⇒ 3
(let ((x 5))
  (setq x 6)        ; xのローカルバインディングをセット
  x)
     ⇒ 6
x                   ; グローバル値は変更されない
     ⇒ 3

1番目のformが評価されてから1番目のsymbolがセット、次に2番目のformが評価されてからsymbolが評価されて、...となることに注意:

(setq x 10          ; ここで、xがセットされるのは
      y (1+ x))     ;   yの計算前であることに注目
     ⇒ 11
Function: set symbol value

この関数はsymbolの値セルにvalueを配置する。これはスペシャルフォームではなく関数なので、シンボルにセットするためにsymbolに記述された式は評価される。リターン値はvalue

ダイナミックな変数バインドが有効(デフォルト)なら、setは自身の引数symbolを評価するが、setqは評価しないという点を除き、setsetqと同じ効果をもつ。しかし変数がレキシカルバインドなら、setは変数のダイナミックな値に、setqは変数のカレント値(レキシカル値)に影響する。変数のバインディングのスコーピングルールを参照のこと。

(set one 1)
error→ Symbol's value as variable is void: one
(set 'one 1)
     ⇒ 1
(set 'two 'one)
     ⇒ one
(set two 2)         ; twoはシンボルoneに評価される
     ⇒ 2
one                 ; したがってoneがセットされる
     ⇒ 2
(let ((one 1))      ; oneのこのバインディングがセットされる
  (set 'one 3)      ;   のであってグローバル値はセットされない
  one)
     ⇒ 3
one
     ⇒ 2

symbolが実際のシンボルでなければwrong-type-argumentエラーがシグナルされる。

(set '(x y) 'z)
error→ Wrong type argument: symbolp, (x y)
Macro: setopt [symbol form]…

これはsetq(上記参照)と似ているがユーザーオプションを意図したマクロであり、変数(複数可)のセットにCustomizeの仕組みを使用している(カスタマイゼーション変数の定義を参照)。特にsetoptはその変数に割り当てられたset用の関数を実行する。たとえば以下のような場合に:

(defcustom my-var 1
  "My var."
  :type 'number
  :set (lambda (var val)
         (set-default var val)
         (message "We set %s to %s" var val)))

ここで次を実行するとmy-varに‘2’がセットされるとともに、メッセージも発行されるだろう:

(setopt my-var 2)

ユーザーオプションにたいしてsetoptは値が妥当かどうかのチェックも行う。たとえばsetoptnumberタイプと定義されたユーザーオプションに文字列をセットするとエラーがシグナルされるだろう。

defcustomcustomize-variableのようなCustomize関連コマンドとは異なり、setoptは非インタラクティブな使用、特にユーザーのinitファイルでの使用を意図している。この理由により値がstandard、saved、user-setのいずれなのかは記録せず、customファイルへの保存用に変数をマークすることも行わない。

setoptマクロはユーザーオプションではない通常の変数にも使用できるが、setqに比べると効率において遥かに劣る。このマクロのユースケースは、主にinitファイル内でのユーザーオプションのセットである。


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

12.9 変数が変更されたときに実行される関数。

変数の値が変化したときに何らかのアクションを行えれば便利なときがあります。変数watchpoint(variable watchpoint)機能はそのための機能を提供します。この機能の有効な利用方法としては変数セッティングと表示の同期、変数への予期せぬ変更を追跡するためのデバッガの呼び出しが含まれます(変数の変更時にデバッガにエンターする。を参照)。

以下の関数は関数にたいするwatch関数の操作や問い合わせに使用できます。

Function: add-variable-watcher symbol watch-function

この関数はsymbolが変化したときは常にwatch-functionが呼び出されるようにアレンジする。エイリアスを介した変更にも同じ効果をもつ(変数のエイリアスを参照)。

watch-functionsymbolの値の変更直前にsymbolnewvaloperationwhereという4つの引数で呼び出される。symbolは変更される変数、newvalは変更後の値(watch-functionではnewvalに変更される前なので古い値はsymbolの値で利用可能)、operationは変更の種類を表すシンボルでありsetletunletmakunbounddefvaraliasのいずれか。whereは変数のバッファーローカルな値が変更される場合にはバッファー、それ以外はnil

Function: remove-variable-watcher symbol watch-function

この関数はsymbolのwatcherリストからwatch-functionを削除する。

Function: get-variable-watchers symbol

この関数はsymbolのアクティブなwatcher関数のリストをリターンする。


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

12.9.1 制限

watchpointをトリガーせずに変数が変更される(または少なくとも変更されたように見える)方法がいくつかあります。

watchpointはシンボルにアタッチされるので変数内に含まれるオブジェクトの変更(リスト変更関数による変更。既存のリスト構造の変更を参照のこと)はこのメカニズムにより検出されません。

さらにCのコードはwatchpointメカニズムをバイパスして変数の値を直接変更できます。

繰り返しになりますがこれはシンボルをターゲットとするので、この機能のマイナーな制限はダイナミックなスコープをもつ変数だけをウォッチできるということです。レキシカル変数への変更は変数スコープ内のコードを調べれば容易に発見できるので、これが問題をもたらすことは稀でしょう(結局のところいかなるコードからも変更され得るダイナミック変数とは異なる。変数のバインディングのスコーピングルールを参照のこと)。


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

12.10 変数のバインディングのスコーピングルール

ある変数にたいするローカルバインディングを作成するとき、そのバインディングはプログラムの限られた一部だけに効果をもちます(ローカル変数を参照)。このセクションでは、これが正確には何を意味するかについて説明します。

ローカルバインディングはそれぞれ、個別にスコープ(scope: 範囲という意味)エクステント(extent: これも範囲を意味する)をもちます。スコープはそのバインディングにアクセスできるのが、テキストのソースコードのどこ(where)であるかを示します。エクステントはプログラムの実行中に、そのバインディングが存在するのがいつ(when)であるかを示します。

デフォルトではEmacsが作成したローカルバインディングは、ダイナミックバインディング(dynamic binding)です。このようなバインディングはダイナミックスコープ(dynamic scope)をもち、それはプログラムの任意の範囲が、その変数バインディングにアクセスするかもしれないことを意味します。これはダイナミックエクステント(dynamic extent)ももっています。これはそのバインディング構造(letフォームのbodyなど)が実行される間だけ、そのバインディングが存続することを意味します。

Emacsはオプションでレキシカルバインディング(lexical binding)を作成することができます。レキシカルバインディングはレキシカルスコープ(lexical scope)をもち、これはその変数にたいするすべての参照が、バインディング構文内にテキスト的に配置されなければならないことを意味します10。レキシカルバインディングは不定エクステント(indefinite extent)ももっています。これはある状況下において、クロージャ(closures)と呼ばれるスペシャルオブジェクトにより、バインディング構造が実行を終えた後でさえも、存続し続けることを意味します。

Emacsでは長年に渡り(そして現在でも)ダイナミックバインディングがデフォルトでしたが、最近の動向としてはレキシカルバインディングをデフォルトにするという最終ゴールに向けて、レキシカルバインディングがますます多くの場所で使用される方向に進んでいます。

以降のサブセクションでは、ダイナミックバインディングとレキシカルバインディング、およびEmacs Lispプログラムでレキシカルバインディングを有効にする方法についてより詳細に説明します。


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

12.10.1 ダイナミックバインディング

デフォルトでは、Emacsにより作成されるローカル変数のバインディングはダイナミックバインディングです。ある変数がダイナミックにバインドされていると、Lispプログラムの実行における任意のポイントでのカレントバインディングは、単にそのシンボルにたいしてもっとも最近作成されたダイナミックなローカルバインディング、またはそのようなローカルバインディングが存在しなければグローバルバインディングになります。

以下の例のように、ダイナミックバインディングはダイナミックスコープとダイナミックエクステントをもちます:

(defvar x -99)  ; xは初期値として-99を受け取る

(defun getx ()
  x)            ; この関数内ではxは自由に使用される

(let ((x 1))    ; xはダイナミックにバインドされている
  (getx))
     ⇒ 1

;; letフォームが終了した後に
;; xは前の値-99にリバートされる

(getx)
     ⇒ -99

関数getxxを参照します。defun構文自体の中にxにたいするバインディングが存在しないという意味において、これはフリーな参照です。xが(ダイナミックに)バインドされているletフォーム内からgetxを呼び出すと、ローカル値(つまり1)が取得されます。しかしその後letフォームの外側からgetxを呼び出すと、グローバル値(つまり-99)が取得されます。

以下はsetqを使用してダイナミックに変数をバインドする例です:

(defvar x -99)      ; xは初期値として-99を受け取る

(defun addx ()
  (setq x (1+ x)))  ; xに1加算して新しい値をリターンする

(let ((x 1))
  (addx)
  (addx))
     ⇒ 3           ; addxを2回呼び出すとxに2回加算される

;; letフォームが終了した後に
;; xは前の値-99にリバートされる

(addx)
     ⇒ -98

Emacs Lispでのダイナミックバインディングは、シンプルな方法で実装されています。シンボルはそれぞれ、シンボルのカレントのダイナミック値(または値の不在)を指定する値セルをもちます。シンボルの構成要素を参照してください。あるシンボルがダイナミックなローカル値を与えられたとき、Emacsは値セルの内容(または値の不在)をスタックに記録して、新しいローカル値を値セルに格納します。バインディング構文が実行を終えたとき、Emacsはスタックから古い値をpopして値セルにそれを配置します。

ダイナミックバインディングを使用したコードのネイティブコンパイル時には、ネイティブコンパイラーはLisp固有の最適化を何も行わないことに注意してください。


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

12.10.2 ダイナミックバインディングの正しい使用

ダイナミックバインディングは、プログラムにたいしてテキスト的なローカルスコープ内で定義されていない変数を参照することを許容する、強力な機能です。しかし無制限に使用した場合には、プログラムの理解を困難にしてしまうこともあります。このテクニックを使用するために2つの明解な方法があります:

  • ある変数がグローバルな定義をもたなければ、ローカル変数としてバインディング構文内(その変数がバインドされるletフォームのbodyなどの場所)だけでそれを使用する。プログラムでこの慣習に一貫してしたがえば、プログラム内の他の場所で同じ変数シンボルを任意に使用しても、その変数の値に影響を与えたり、影響を受けることがなくなる。
  • それ以外ではdefvardefconst (グローバル変数の定義を参照)、defcustom (カスタマイゼーション変数の定義を参照)で変数を定義する。この定義は通常はEmacs Lispファイル内のトップレベルであること。この定義には可能な限り変数の意味と目的を説明するドキュメント文字列を含めること。また名前の衝突を避けるように変数を命名すること(Emacs Lispコーディング規約を参照)。

    そうすればプログラム内のどこか別の場所で、それが何に影響するか確信をもって変数をバインドすることができます。その変数にどこで出会っても、(たとえば変数の定義がEmacsにロードされていればC-h vコマンドを通じて)定義を参照するのが簡単になります。Name Help in The GNU Emacs Manualを参照してください。

    たとえばcase-fold-searchのようなカスタマイズ可能な変数にたいしてローカルバインディングを使用するのは一般的です:

    (defun search-for-abc ()
      "Search for the string \"abc\", ignoring case differences."
      (let ((case-fold-search t))
        (re-search-forward "abc")))
    

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

12.10.3 レキシカルバインディング

Emacsのバージョン24.1からオプションの機能としてレキシカルバインディングが導入されました。わたしたちはこの機能の重要性が時とともに増加することを期待します。レキシカルバインディングは最適化の機会をより広げるので、この機能を使用するプログラムはおそらく将来のEmacsバージョンで高速に実行されるようになるでしょう。レキシカルバインディングは、バージョン26.1のEmacsで追加した並列性(concurrency)とも互換があります。

レキシカルにバインドされた変数はレキシカルスコープ(lexical scope)をもちます。これはその変数にたいする参照が、そのバインディング構文内にテキスト的に配置されなければならないことを意味しています。以下は例です (実際にレキシカルバインディングを有功にする方法は、レキシカルバインディングの使用を参照のこと):

(let ((x 1))    ; xはレキシカルにバインドされる
  (+ x 3))
     ⇒ 4

(defun getx ()
  x)            ; この関数内ではxは自由に使用される

(let ((x 1))    ; xはレキシカルにバインドされる
  (getx))
error→ Symbol's value as variable is void: x

ここではxはグローバル値をもちません。letフォーム内でレキシカルにバインドされたとき、この変数はletのテキスト境界内で使用できます。しかしこのlet内から呼び出されるgetx関数からは、getxの関数定義がletフォームの外側なので使用することができません

レキシカルバインディングが機能する方法を説明します。バインディング構文はぞれぞれ、その構文内でローカル値にバインドする変数を指定する、レキシカル環境(lexical environment)を定義します。Lispの評価機能(Lisp evaluator)が、ある変数のカレント値を得たいときは、最初にレキシカル環境内を探します。そこで変数が指定されていなければ、ダイナミック値が格納されるシンボルの値セルを探します。

(レキシカル環境は内部的には、通常はシンボルと値のペアーによるコンスセルをメンバーとするリストだが、一部のメンバーはコンスセルではなくシンボルでもよい。このリストにおけるシンボルは、そのシンボルの変数はローカルではダイナミックにバインドされているとみなすよう宣言されたレキシカル環境を意味している。このリストはフォームを評価するためのレキシカル環境を指定するために、eval関数の2番目の引数として渡すことができる。evalについてを参照のこと。しかしほとんどのEmacs Lispプログラムは、この方法で直接レキシカル環境を使用するべきではない。デバッガーのような特化されたプログラムだけが使用すること。)

レキシカルバインディングは不定エクステント(indefinite extent)をもちます。バインディング構造が終了した後でも、そのレキシカル環境はクロージャ(closures)と呼ばれるLispオブジェクト内に“保持”されるかもしれ、あせん。クロージャはレキシカルバインディングが有効な、名前つきまたは無名(anonymous)の関数が作成されたときに作成されます。詳細はクロージャを参照してください。

クロージャが関数として呼び出されたとき、その関数の定義内のレキシカル変数にたいする任意の参照は、維持されたレキシカル環境を使用します。以下は例です:

(defvar my-ticker nil)   ; クロージャを格納するために
                         ; この変数を使用する

(let ((x 0))             ; xはレキシカルにバインドされる
  (setq my-ticker (lambda ()
                    (setq x (1+ x)))))
    ⇒ (closure ((x . 0)) ()
          (setq x (1+ x)))

(funcall my-ticker)
    ⇒ 1

(funcall my-ticker)
    ⇒ 2

(funcall my-ticker)
    ⇒ 3

x                        ; xはグローバル値をもたないことに注意
error→ Symbol's value as variable is void: x

letバインディングは、内部に変数xをもつレキシカル環境を定義して、変数は0にローカルにバインドされます。このバインディング構文内でxを1増加して、増加された値をリターンするクロージャを定義しています。このラムダ式は自動的にクロージャとなり、たとえlet構文を抜けた後でも、その内部ではレキシカル環境が存続します。クロージャを評価するときは、毎回レキシカル環境内のxのバインディングが使用されて、xが加算されます。

シンボルオブジェクト自体に束縛されるダイナミック変数と異なり、レキシカル変数とシンボルの関係はインタープリター(かコンパイラー)内にのみ存在します。したがって(symbol-valueboundpsetのような)シンボル引数を受け取る関数ができるのは、変数のダイナミックなバインディング(そのシンボルの値セルの内容)の取得と変更だけです。


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

12.10.4 レキシカルバインディングの使用

Emacs LispファイルのロードやLispバッファーを評価するとき、バッファーローカルな変数lexical-bindingが非nilなら、レキシカルバインディングが有効になります:

Variable: lexical-binding

このバッファーローカルな変数が非nilなら、Emacs Lispファイルとバッファーはダイナミックバインディングではなくレキシカルバインディングを使用して評価される(しかし特別な変数はダイナミックにバインドされたまま。以下を照)。nilならすべてのローカル変数にたいしてダイナミックバインディングが使用される。この変数は、通常はファイルローカル変数として、Emacs Lispファイル全体にたいしてセットされる(ファイルローカル変数を参照)。他のファイルローカル変数などとは異なり、ファイルの最初の行でセットされなければならないことに注意。

eval呼び出しを使用してEmacs Lispコードを直接評価するとき、evallexical引数が非nilなら、レキシカルバインディングが有効になります。evalについてを参照してください。

レキシカルバインディングは*scratch*バッファーで使用されるLisp Interactionモード、および*ielm*バッファーで使用されるIELMモードでも有効であり、M-: (eval-expression)を通じた式の評価や、Emacsとemacsclient (emacsclient Options in The GNU Emacs Manualを参照)の--evalコマンドラインオプション(Action Arguments in The GNU Emacs Manualを参照)を処理する際にも有効です。

レキシカルバインディングが有効な場合でも、特定の変数はダイナミックにバインドされたままです。これらはスペシャル変数(special variable)と呼ばれます。defvardefcustomdefconstで定義されたすべての変数はスペシャル変数です(グローバル変数の定義を参照)。その他のすべての変数はレキシカルバインディングの対象になります。

値なしでdefvarを使用することにより、他の場所ではレキシカルにバインドされている状態のまま、単一ファイルやファイルの一部だけで変数をダイナミックにバインドすることが可能になります。たとえば:

(let (_)
  (defvar x)      ; xへのletバインドはこのlet内ではダイナミック
  (let ((x -99))  ; これはxのダイナミックバインド
    (defun get-dynamic-x ()
      x)))

(let ((x 'lexical)) ; これはxのレキシカルバインド
  (defun get-lexical-x ()
    x))

(let (_)
  (defvar x)
  (let ((x 'dynamic))
    (list (get-lexical-x)
          (get-dynamic-x))))
    ⇒ (lexical dynamic)
Function: special-variable-p symbol

この関数はsymbolがスペシャル変数(つまり変数がdefvardefcustomdefconstによる定義をもつ)なら非nilをリターンする。、それ以外ならリターン値はnil

これは関数なので永続的にスペシャルな変数には非nilをリターンできるが、カレントレキシカルスコープでのみスペシャルな変数では異なることに注意。

関数内の正式な引数としてのスペシャル変数の使用はサポートされていません。


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

12.10.5 レキシカルバインディングへの変換

Emacs Lispプログラムをレキシカルバインディングに変換するのは簡単です。最初にEmacs Lispソースファイルのヘッダー行でlexical-bindingtにして、ファイルローカル変数を追加します(ファイルローカル変数を参照)。次に意図せずレキシカルにバインドしてしまわないように、ダイナミックなバインドをもつ必要がある変数が変数定義をもつことを各変数ごとにチェックします。

どの変数が変数定義をもつ必要があるか見つけるシンプルな方法は、ソースファイルをバイトコンパイルすることです。バイトコンパイルを参照してください。letフォームの外側で非スペシャル変数が使用されていれば、バイトコンパイラーはフリーな変数にたいする参照や割り当てについて警告するでしょう。非スペシャル変数がバインドされているがletフォーム内で使用されていなければ、バイトコンパイラーは使用されないレキシカル変数に関して警告するでしょう。バイトコンパイラーは、スペシャル変数を関数の引数として使用している場合も問題を警告します。

フリー変換にたいする参照や割り当てに関する警告は、通常はその変数をダイナミックスコープにすべきだという明解なサインなので、その変数を最初に使用する前に適切なdefvarを追加する必要があります。

使用されない変数についての警告は、それが(実際には別の関数で使用されているので)ダイナミックスコープを意図した変数だという良いヒントかもしれませんが、その変数が実際に未使用であり、単に削除可能であることを示しているのかもしれません。そのために、あなたはこれがいずれのケースなのかを調べて、それにもとづいてdefvarを追加するか、あるいはその変数を完全に削除する必要があります。削除が不可能、あるいは望ましくない場合(典型的にはそれが正規の引数であり、呼び出し側すべての変更が不可能だったり望ましくない場合)には、それが使用されないと判っている変数であることをコンパイラーに示すために、変数名の先頭にアンダースコアを追加することもできます。

クロスファイル変数のチェック

警告: これは事前通知なしに変更あるいは消滅するかもしれない実験的な機能です。

バイトコンパイラーは別のEmacs Lispファイル内ではスペシャルであるようなレキシカル変数についても警告するかもしれません。これはしばしばdefvar宣言の欠落を示しています。これは便利ですが3つのステップを要する幾分特殊なチェックを行います:

  1. 環境変数EMACS_GENERATE_DYNVARSに非空の文字列をセットして、対象となりそうなスペシャル変数宣言をもつすべてのファイルをバイトコンパイルする。これは通常は同一パッケージ、関連するパッケージ、Emacsサブシステム内のすべてのファイルが該当する。この処理によりコンパイル済みEmacs Lispファイルそれぞれにたいして、名前が.dynvarsで終わるファイルが生成される。
  2. .dynvarsファイルを単一のファイルに結合する。
  3. チェックを要するファイルをバイトコンパイルする。このときには環境変数EMACS_DYNVARS_FILEにはステップ2で作成した集約済みファイルがセットされる。

以下はUnixシェル上でmakeを使用してバイトコンパイルしたら何が行われるかを示した例です:

$ rm *.elc                                # 再コンパイルを強制
$ EMACS_GENERATE_DYNVARS=1 make           # .dynvarsを生成
$ cat *.dynvars > ~/my-dynvars            # .dynvarsを結合
$ rm *.elc                                # 再コンパイルを強制
$ EMACS_DYNVARS_FILE=~/my-dynvars make    # チェック実施

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

12.11 バッファーローカル変数

グローバルおよびローカルな変数バインディングは、いずれかの形式をほとんどのプログラミング言語で見つけることができます。しかしEmacsは1つのバッファーだけに適用されるバッファーローカル(buffer-local)なバインディング用に、普通には存在しない類の変数バインディングもサポートしています。ある変数にたいして異なるバッファーごとに別の値をもつのは、カスタマイズでの重要な手法です(変数は端末ごとにローカルなバインディングをもつこともできる。複数の端末を参照)。


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

12.11.1 バッファーローカル変数の概要

バッファーローカル変数は特定のバッファーに関連づけられた、バッファーローカルなバインディングをもちます。このバインディングはそのバッファーがカレントのときに効果をもち、カレントでないときには効果がありません。バッファーローカルなバインディングが効力をもつときにその変数をセットすると、そのバインディングは新しい値をもちますが他のバインディングは変更されません。これはバッファーローカルなバインディングを作成したバッファーだけで変更が見えることを意味します。

その変数にたいする特定のバッファーに関連しない通常のバインディングは、デフォルトバインディング(default binding)と呼ばれます。これはほとんどの場合はグローバルバインディングです。

変数はあるバッファーではバッファーローカルなバインディングをもつことができ、他のバッファーではもたないことができます。デフォルトバインディングは、その変数にたいして自身のバインディングをもたないすべてのバッファーで共有されます(これには新たに作成されたバッファーが含まれる)。ある変数にたいして、その変数のバッファーローカルなバインディングをもたないバッファーでその変数をセットすると、それによりデフォルトバインディングがセットされるので、デフォルトバインディングを参照するすべてのバッファーで新しい値を見ることになります。

バッファーローカルなバインディングのもっとも一般的な使用は、メジャーモードがコマンドの動作を制御するために変数を変更する場合です。たとえばCモードやLispモードは、空行だけがパラグラフの区切りになるように変数paragraph-startをセットします。これらのモードは、CモードやLispモードになるようなバッファー内でこの変数をバッファーローカルにすることでこれを行って、その後そのモードにたいする新しい値をセットします。メジャーモードを参照してください。

バッファーローカルなバインディングを作成する通常の方法は、make-local-variableによる方法で、これは通常はメジャーモードが使用します。これはカレントバッファーだけに効果があります。その他すべてのバッファー(まだ作成されていないバッファーを含む)は、それらのバッファー自身が明示的にバッファーローカルなバインディングを与えるまでデフォルト値を共有し続けます。

変数を自動的にバッファーローカルになるようにマークする、より強力な操作はmake-variable-buffer-localを呼び出すことにより行われます。これはたとえその変数がまだ作成されていなくても、変数をすべてのバッファーにたいしてローカルにすると考えることができます。より正確には変数を自動的にセットすることにより、その変数がカレントバッファーにたいしてローカルでなくても、変数をローカルにする効果があります。すべてのバッファーは最初は通常のようにデフォルト値を共有しますが、変数をセットすることでカレントバッファーにたいしてバッファーローカルなバインディングを作成します。新たな値はバッファーローカルなバインディングに格納され、デフォルトバインディングは変更されずに残ります。これは任意のバッファーでsetqによりデフォルト値を変更できないことを意味します。変更する唯一の方法はsetq-defaultだけです。

警告: ある変数が1つ以上のバッファーでバッファーローカルなバインディングをもつ際に、letはそのとき効力がある変数のバインディングをリバインドします。たとえばカレントバッファーがバッファーローカルな値をもつなら、letは一時的にそれをリバインドします。効力があるバッファーローカルなバインディングが存在しなければletはデフォルト値をリバインドします。letの内部で、別のバインディングが効力をもつ別のバッファーをカレントバッファーにすると、それ以上letバインディングを参照できなくなります。他のバッファーにいる間にletを抜けると、(たとえそれが正しくても)バインディングの解消を見ることはできません。以下にこれを示します:

(setq foo 'g)
(set-buffer "a")
(make-local-variable 'foo)
(setq foo 'a)
(let ((foo 'temp))
  ;; foo ⇒ 'temp  ; バッファー‘a’内でのletバインディング
  (set-buffer "b")
  ;; foo ⇒ 'g     ; fooは‘b’にたいしてローカルではないためグローバル値
  body…)
foo ⇒ 'g        ; exitによりバッファー‘a’のローカル値が復元されるが
                 ; バッファー‘b’では見ることができない
(set-buffer "a") ; ローカル値が復元されたことを確認
foo ⇒ 'a

body内のfooにたいする参照は、バッファー‘b’のバッファーローカルなバインディングにアクセスすることに注意してください。

あるファイルがローカル変数の値をセットする場合、これらの変数はファイルをvisitするときバッファーローカルな値になります。File Variables in The GNU Emacs Manualを参照してください。

バッファーローカル変数を端末ローカル(terminal-local)にすることはできません(複数の端末を参照)。


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

12.11.2 バッファーローカルなバインディングの作成と削除

Command: make-local-variable variable

この関数はカレントバッファー内で、variable(シンボル)にたいするバッファーローカルなバインディングを作成する。他のバッファーは影響を受けない。リターンされる値はvariable

variableのバッファーローカルな値は、最初は以前にvariableがもっていた値と同じ値をもつ。variableがvoidのときはvoidのまま。

;; バッファー‘b1’で行う:
(setq foo 5)                ; すべてのバッファーに影響する。
     ⇒ 5
(make-local-variable 'foo)  ; b1’内でローカルになった
     ⇒ foo
foo                         ; 値は変更されない
     ⇒ 5
(setq foo 6)                ; b1’内で値を変更
     ⇒ 6
foo
     ⇒ 6

;; バッファー‘b2’では、値は変更されていない
(with-current-buffer "b2"
  foo)
     ⇒ 5

変数をletバインディングでバッファーローカルにしても、letへの出入り時の両方でこれを行うバッファーがカレントでなければ信頼性はない。これはletがバインディングの種類を区別しないからである。letに解るのはバインディングが作成される変数だけである。

定数や読み取り専用の変数をバッファーローカルにするとエラーになる。変更不可な変数を参照のこと。

変数が端末ローカル(複数の端末を参照)なら、この関数はエラーをシグナルする。そのような変数はバッファーローカルなバインディングをもつことができない。

警告: フック変数にたいしてmake-local-variableを使用しないこと。フック変数はadd-hookremove-hooklocal引数を使用すると、必要に応じて自動でバッファーローカルになる。

Macro: setq-local &rest pairs

pairsは変数と値のペアからなるリスト。このマクロはカレントバッファー内で変数それぞれにたいしてバッファーローカルなバインディングを作成して、それにバッファーローカルな値を与える。このマクロは各変数にたいしてmake-local-variableの後にsetqを呼び出すのと等価。変数はクォートされていないシンボルであること。

(setq-local var1 "value1"
            var2 "value2")
Command: make-variable-buffer-local variable

このコマンドはvariable(シンボル)が自動的にバッファーローカルになるようにマークするので、それ以降にその変数へのセットを試みると、その時点でカレントのバッファーにローカルになる。しばしば混乱を招くmake-local-variableとは異なり、これが取り消されることはなく、すべてのバッファー内での変数の挙動に影響する。

この機能特有の欠点は、(letやその他のバインディング構文による)変数のバインディングが、その変数にたいするバッファーローカルなバインディングを作成しないことである。(setsetqによる)変数のセットだけは、その変数がカレントバッファーで作成されたletスタイルのバインディングをもたないので、ローカルなバインディングを作成する。

variableがデフォルト値をもたない場合、このコマンドの呼び出しはnilのデフォルト値を与える。variableがすでにデフォルト値をもつなら、その値は変更されずに残る。それ以降にvariableにたいしてmakunboundを呼び出すと、バッファーローカル値をvoidにして、デフォルト値は影響を受けずに残る。

▼リターン値はvariable

定数や読み取り専用の変数をバッファーローカルにするとエラーになる。変更不可な変数を参照のこと。

警告: ユーザーオプション変数では、ユーザーは異なるバッファーにたいして異なるカスタマイズを望むかもしれないので、make-variable-buffer-localを使うべきだと決め込むべきではない。ユーザーは望むなら任意の変数をローカルにできる。その選択の余地を残すほうがよい。

make-variable-buffer-localを使用すべきなのは、複数のバッファーが同じバインディングを共有しないことが自明な場合である。たとえばバッファーごとに個別な値をもつことに依存するLispプログラム内の内部プロセスにたいして変数が使用されるときは、make-variable-buffer-localの使用が最善の解決策になるかもしれない。

Macro: defvar-local variable value &optional docstring

このマクロはvariableを初期値valuedocstringの変数として定義して、それを自動的にバッファーローカルとマークする。これはdefvarの後につづけてmake-variable-buffer-localを呼び出すのと同じ。variableはクォートされていないシンボル。

Function: local-variable-p variable &optional buffer

これはvariableがバッファーbuffer(デフォルトはカレントバッファー)内でバッファーローカルならt、それ以外はnilをリターンする。

Function: local-variable-if-set-p variable &optional buffer

これはvariableがバッファーbuffer内でバッファーローカル値をもつ、または自動的にバッファーローカルになるならt、それ以外はnilをリターンする。bufferが省略またはnilの場合のデフォルトはカレントバッファー。

Function: buffer-local-value variable buffer

この関数はバッファーbuffer内の、variable(シンボル)のバッファーローカルなバインディングをリターンする。variableがバッファーbuffer内でバッファーローカルなバインディングをもたなければ、かわりにvariableのデフォルト値(バッファーローカル変数のデフォルト値を参照)をリターンする。

Function: buffer-local-boundp variable buffer

これはvariableがバッファーbufferでバッファーローカルにバインドされているか、あるいはグローバルにバインドされていれば非nilをリターンする。

Function: buffer-local-variables &optional buffer

この関数はバッファーbuffer内のバッファーローカル変数を表すリストをリターンする(bufferが省略された場合はカレントバッファーが使用される)。リストの各要素は通常は(sym . val)という形式をもつ。ここでsymはバッファーローカル変数(シンボル)、valはバッファーローカル値。しかしbuffer内のある変数のバッファーローカルなバインディングがvoidなら、その変数に対応するリスト要素は単にsymとなる。

(make-local-variable 'foobar)
(makunbound 'foobar)
(make-local-variable 'bind-me)
(setq bind-me 69)
(setq lcl (buffer-local-variables))
    ;; 最初はすべてのバッファー内でローカルなビルトイン変数:
⇒ ((mark-active . nil)
    (buffer-undo-list . nil)
    (mode-name . "Fundamental")
    …
    ;; 次にビルトインでないバッファーローカル変数
    ;; This one is buffer-local and void:
    foobar
    ;; これはバッファーローカルでvoidではない:
    (bind-me . 69))

このリスト内のコンスセルのCDRに新たな値を格納しても、その変数のバッファーローカル値は変化しないことに注意。

Command: kill-local-variable variable

この関数はカレントバッファー内のvariable(シンボル)にたいするバッファーローカルなバインディング(もしあれば)を削除する。その結果として、このバッファー内でvariableのデフォルトバインディングが可視になる。これは通常はvariableの値を変更する。デフォルト値は削除されたバッファーローカル値とは異なるのが普通だからである。

セットしたとき自動的にバッファーローカルになる変数のバッファーローカルなバインディングをkillすると、これによりカレントバッファー内でデフォルト値が可視になる。しかし変数を再度セットすると、その変数にたいするバッファーローカルなバインディングが再作成される。

kill-local-variablevariableをreturnします。

この関数はコマンドである。なぜならバッファーローカル変数のインタラクティブな作成が有用な場合があるように、あるバッファーローカル変数のインタラクティブなkillが有用な場合があるからである。

Function: kill-all-local-variables &optional kill-permanent

この関数はカレントバッファーにおいてバッファーローカル変数のすべてのバインディングを解消する。結果としてそのバッファーではほとんどの変数にたいしてデフォルト値を参照することになる。デフォルトではpermanent(永続的)とマークされた変数、および非nilpermanent-local-hookプロパティをもつローカルフック関数(フックのセットを参照)は除外されるが、オプションのkill-permanent引数が非nilならこれらの変数をもkillされる。

この関数はそのバッファーに関連する他の特定の情報もリセットする。これはローカルキーマップをnil、構文テーブルを(standard-syntax-table)の値、caseテーブルを(standard-case-table)、abbrevテーブルをfundamental-mode-abbrev-tableの値にセットする。

この関数が一番最初に行うのはノーマルフックchange-major-mode-hook(以下参照)の実行である。

すべてのメジャーモードコマンドはこの関数を呼び出すことによって開始され、これによりFundamentalモードにスイッチし、以前のメジャーモードの影響のほとんどを消去する効果があります。この関数が処理を行うのを確実にするために、メジャーモードがセットする変数はpermanentとマークすべきではない。

kill-all-local-variablesnilをreturnします。

Variable: change-major-mode-hook

関数kill-all-local-variablesは、何か他のことを行う前にまずこのノーマルフックを実行する。この関数はメジャーモードにたいして、ユーザーが他のメジャーモードにスイッチした場合に行われる何か特別なことを準備する方法を与える。この関数はユーザーがメジャーモードを変更した場合に忘れられるべき、バッファー固有のマイナーモードにたいしても有用。

最善の結果を得るために、この変数をバッファーローカルにすれば、処理が終了したときに消えるので、以降のメジャーモードに干渉しなくなる。フックを参照のこと。

変数名(シンボル)が非nilpermanent-localプロパティをもつなら、そのバッファーローカル変数はpermanent(永続的)です。そのような変数はkill-all-local-variablesの影響を受けず、したがってメジャーモードの変更によりそれらのローカルバインディングは作成されません。permanentなローカル変数はファイルの内容を編集する方法ではなく、どこから読み込んだファイルか、あるいはどのように保存するかといったことに関連するデータに適しています。


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

12.11.3 バッファーローカル変数のデフォルト値

バッファーローカルなバインディングをもつ変数のグローバル値もデフォルト値(default)値と呼ばれます。なぜならその変数にたいしてカレントバッファーや選択されたフレームもバインディングをもたなければ、その値が常に効果をもつからです。

関数default-valuesetq-defaultは、カレントバッファーがバッファーローカルなバインディングをもつかどうかに関わらず、その変数のデフォルト値にアクセスまたは変更します。たとえばほとんどのバッファーにたいして、paragraph-startのデフォルトのセッティングを変更するために、setq-defaultを使用できます。そしてこの変数にたいするバッファーローカルな値をもつCモードやLispモードにいるときでさえ、これは機能します。

スペシャルフォームdefvardefconstもバッファーローカルな値ではなく、(もし変数にセットする場合は)デフォルト値をセットします。

Function: default-value symbol

この関数はsymbolのデフォルト値をリターンする。これはこの変数にたいして独自の値をもたないバッファーやフレームから参照される値である。symbolがバッファーローカルでなければ、これはsymbol-value(変数の値へのアクセスを参照)と同じ。

Function: default-boundp symbol

関数default-boundpsymbolのデフォルト値がvoidでないか報告する。(default-boundp 'foo)nilをリターンした場合には(default-value 'foo)はエラーになる。

default-boundpは、boundpsymbol-valueに対応するように、default-valueに対応する。

Special Form: setq-default [symbol form]…

このスペシャルフォームは各symbolに新たなデフォルト値として、対応するformを評価した結果を与える。これはsymbolを評価しないがformは評価する。setq-defaultフォームの値は最後のformの値。

カレントバッファーにたいしてsymbolがバッファーローカルでなく、自動的にバッファーローカルにマークされていなければ、setq-defaultsetqと同じ効果をもつ。カレントバッファーにたいしてsymbolがバッファーローカルなら、(バッファーローカルな値をもたない)他のバッファーから参照できる値を変更するが、それはカレントバッファーが参照する値ではない。

;; バッファー‘foo’で行う:
(make-local-variable 'buffer-local)
     ⇒ buffer-local
(setq buffer-local 'value-in-foo)
     ⇒ value-in-foo
(setq-default buffer-local 'new-default)
     ⇒ new-default
buffer-local
     ⇒ value-in-foo
(default-value 'buffer-local)
     ⇒ new-default

;; (新しい)バッファー‘bar’で行う:
buffer-local
     ⇒ new-default
(default-value 'buffer-local)
     ⇒ new-default
(setq buffer-local 'another-default)
     ⇒ another-default
(default-value 'buffer-local)
     ⇒ another-default

;; バッファー‘foo’に戻って行う:
buffer-local
     ⇒ value-in-foo
(default-value 'buffer-local)
     ⇒ another-default
Function: set-default symbol value

この関数はsetq-defaultと似ているが、symbolは通常の引数として評価される。

(set-default (car '(a b c)) 23)
     ⇒ 23
(default-value 'a)
     ⇒ 23

ある変数に値をletバインドできます(ローカル変数を参照)。このバインディングにより変数のグローバル値はシャドーされます。default-valueはグローバル値ではなくそのバインディングの値をリターンして、set-defaultによるグローバル値のセットは防がれます(かわりにletバインドされた値が変更される)。以下の2つの関数によりletバインドでグローバル値がシャドーされていてもグローバル値を参照できます。

Function: default-toplevel-value symbol

この関数はsymbolにたいするすべてのletバインディングの外部の値としてトップレベルのデフォルト値をリターンする。

(defvar variable 'global-value)
    ⇒ variable
(let ((variable 'let-binding))
  (default-value 'variable))
    ⇒ let-binding
(let ((variable 'let-binding))
  (default-toplevel-value 'variable))
    ⇒ global-value
Function: set-default-toplevel-value symbol value

この関数はsymbolのトップレベルのデフォルト値に指定されたvalueをセットする。これはコードがsymbolのletバインディングのコンテキスト下で実行中かどうかとは無関係にsymbolのグローバル値をセットしたいときに便利。


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

12.12 ファイルローカル変数

ファイルにローカル変数の値を指定できます。そのファイルをvisitしているバッファー内で、これらの変数にたいしてバッファーローカルなバインディングを作成するために、Emacsはこれらを使用します。ファイルローカル変数の基本的な情報については、Local Variables in Files in The GNU Emacs Manualを参照してください。このセクションではファイルローカル変数が処理される方法に影響する関数と変数を説明します。

ファイルローカル変数が勝手に関数や、後で呼び出されるLisp式を指定できたら、ファイルのvisitによってEmacsが乗っ取られてしまうかもしれません。Emacsは既知のファイルローカル変数だけにたいして、指定された値が安全だと自動的にセットすることにより、この危険から保護します。これ以外のファイルローカル変数は、ユーザーが同意した場合のみセットされます。

追加の安全策としてEmacsがファイルローカル変数を読み込むとき、一時的にread-circlenilにバインドします(入力関数を参照)。これは循環認識と共有されたLisp構造からLispリーダーを保護します(循環オブジェクトの読み取り構文を参照)。

User Option: enable-local-variables

この変数はファイルローカル変数を処理するかどうかを制御する。以下の値が利用できる:

t(デフォルト)

安全な変数をセット、安全でない変数は問い合わせる(1回)。

:safe

安全な変数だけをセット、問い合わせはしない。

:all

問い合わせをせずに、すべての変数をセット。

nil

変数をセットしない。

その他

すべての変数にたいして問い合わせる(1回)。

Variable: inhibit-local-variables-regexps

これは正規表現のリストである。ファイルがこのリストの要素にマッチする名前をもつなら、すべてのファイルローカル変数のフォームはスキャンされない。どんなときにこれを使いたいかの例は、Emacsがメジャーモードを選択する方法を参照のこと。

Variable: permanently-enabled-local-variables

たとえenable-local-variablesnilであっても、いくつかのローカル変数セッティングは、デフォルトでは注意する必要があるだろう。これはデフォルトにおいてローカル変数lexical-bindingのセッティングの場合だけだが、この変数(シンボルのリスト)を使用して制御できる。

Function: hack-local-variables &optional handle-mode

この関数はカレントバッファーの内容により指定された任意のローカル変数にたいしてパースを行い、適切にバインドと評価を行う。変数enable-local-variablesはここでも効果をもつ。しかしこの関数は‘-*-行の、‘mode:’ローカル変数を探さない。set-auto-modeはこれを行ってenable-local-variablesも考慮する(Emacsがメジャーモードを選択する方法を参照)。

この関数はfile-local-variables-alist内に格納されたalistを調べて、各ローカル変数を順に適用することにより機能する。この関数は変数に適用する前(か後)に、before-hack-local-variables-hook(かhack-local-variables-hook)を呼び出す。alistが非nilの場合のみ、事前のフック(before-hook)を呼び出し、その他のフックは常に呼び出す。この関数はそのバッファーがすでにもつメジャーモードと同じメジャーモードが指定された場合は‘mode’要素を無視する。

オプションの引数handle-modetなら、この関数が行うのはメジャーモードを指定するシンボルをリターンすることだけであり、‘-*-行やローカル変数リストがメジャーモードを指定していればそのモード、それ以外はnilをリターンする。この関数はモードや他のファイルローカル変数をセットしない。handle-modeの値がniltのいずれでもなければ‘-*-行の‘mode’に関するすべてのセッティングとローカル変数リストは無視されて、別のセッティングが適用される。handle-modenilならすべてのファイルローカル変数がセットされる。

Variable: file-local-variables-alist

このバッファーローカルな変数は、ファイルローカル変数のセッティングのalistを保持する。alistの各要素は(var . value)という形式で、varはローカル変数のシンボル、valueはその値である。Emacsがファイルをvisitするとき、最初にすべてのファイルローカル変数をこのalistに収集して、その後で変数に1つずつ関数hack-local-variablesを適用する。

Variable: before-hack-local-variables-hook

Emacsはfile-local-variables-alistに格納されたファイルローカル変数を適用する直前にこのフックを呼び出す。

Variable: hack-local-variables-hook

Emacsはfile-local-variables-alistに格納されたファイルローカル変数を適用し終えた直後にこのフックを呼び出す。

ある変数にたいしてsafe-local-variableプロパティによって安全な値を指定できます。このプロパティは引数を1つとる関数です。与えられた値にたいして、その関数が非nilをリターンしたらその値は安全です。一般的に目にするファイル変数の多くは、safe-local-variableプロパティをもちます。これらのファイル変数にはfill-columnfill-prefixindent-tabs-modeが含まれます。ブーリーン値の変数にたいしては、プロパティの値にbooleanpを使用します。

Cソースコード内で定義された変数にsafe-local-variableプロパティを定義したければ、それらの変数の名前とプロパティをfiles.elのセクション“Safe local variables”のリストに追加してください。

defcustomを使用してユーザーオプションを定義する際には、defcustomに引数:safe functionを追加してsafe-local-variableプロパティをセットできます(カスタマイゼーション変数の定義を参照)。しかし:safeを使用して定義された安全性の述語は、そのdefcustomを含むパッケージのロード時の一度だけ認識されるものであり、それでは遅すぎることがしばしばあります。代替策としては、以下のようにオプションに安全性の述語を割り当てるためにautoloadクッキー(autoloadを参照)を使用できます:

;;;###autoload (put 'var 'safe-local-variable 'pred)

autoloadで指定された安全な値の定義は、そのパッケージのautoloadファイル(Emacsに同梱されたパッケージのほとんどではloaddefs.el)にコピーされて、セッションの開始からEmacsにより認識されます。

User Option: safe-local-variable-values

この変数はある変数の値が安全であることをマークする、別の方法を提供する。これはコンスセル(var . val)のリストでありvarは変数名、valはその変数にたいして安全な値である。

Emacsが一連のファイルローカル変数にしたがうかどうかユーザーに尋ねるとき、ユーザーはそれらの変数が安全だとマークすることができる。安全とマークするとsafe-local-variable-valuesにこれらのvariable/valueペアーが追加されて、ユーザーのカスタムファイルに保存する。

User Option: ignored-local-variable-values

特定のローカル変数にたいして常に完全に無視したい値がいくつかある場合には、この変数を使用できる。値はsafe-local-variable-valuesと同じ形式であり、ファイルが指定するローカル変数の処理時にこのリストに現れる値にセットされるファイルローカル変数は常に無視される。safe-local-variable-valuesの場合のように、ファイルローカル変数にしたがうべきかEmacsがユーザーに尋ねる際に、ユーザーは特定の値を恒久的に無視することを選択でき、この選択によってこの変数は変更されてユーザーのcustomファイルに保存される。この変数にある変数/値ペアーは、safe-local-variable-values内にある同一ペアーより優先される。

Function: safe-local-variable-p sym val

この関数は上記の条件に基づき、symに値valを与えても安全ななら非nilをリターンする。

いくつかの変数は危険(risky)だと判断されます。ある変数が危険なら、その変数がsafe-local-variable-valuesに自動的に追加されることはありません。ユーザーがsafe-local-variable-valuesを直接カスタマイズすることで明示的に値を許さない限り、危険な変数をセットする前にEmacsは常に確認を求めます。

名前が非nilrisky-local-variableプロパティをもつすべての変数は危険だと判断されます。defcustomを使用してユーザーオプションを定義するとき、defcustomに引数:risky valueを追加することにより、ユーザーオプションにrisky-local-variableプロパティをセットできます。それに加えて名前が‘-command’、‘-frame-alist’、‘-function’、‘-functions’、‘-hook’、‘-hooks’、‘-form’、‘-forms’、‘-map’、‘-map-alist’、‘-mode-alist’、‘-program’、‘-predicate’で終わるすべての変数は自動的に危険だと判断されます。後に数字をともなう変数‘font-lock-keywords’と‘font-lock-keywords’、さらには‘font-lock-syntactic-keywords’も危険だと判断されます。

Function: risky-local-variable-p sym

この関数はsymが上記の条件にもとづき危険な変数なら非nilをリターンする。

Variable: ignored-local-variables

この変数はファイルによりローカル値を与えらるべきではない変数のリストを保持する。これらの変数に指定された任意の値は、完全に無視される。

“変数”‘Eval:’も抜け道になる可能性があるので、Emacsは通常はそれを処理する前に確認を求めます。

User Option: enable-local-eval

この変数は‘-*-’の行中、またはvisitされるファイル内のローカル変数リストにたいする、‘Eval:’の処理を制御する。値tは無条件に実行し、nilはそれらを無視することを意味します。それ以外なら各ファイルにたいして何を行うか、ユーザーに確認を求めることを意味する。デフォルト値はmaybe

User Option: safe-local-eval-forms

この変数はファイルローカル変数リスト内で‘Eval:’“変数”が見つかった際に評価しても安全な式のリストを保持する。

式が関数呼び出しであり、その関数がsafe-local-eval-functionプロパティをもつなら、その式の評価が安全かどうかはそのプロパティ値が決定します。プロパティ値はその式をテストするための述語(predicate)、そのような述語のリスト(成功した述語があれば安全)、またはt(引数が定数である限り常に安全)を指定できます。

テキストプロパティには、それらの値に関数呼び出しを含めることができるので抜け道になる可能性があります。したがってEmacsはファイルローカル変数にたいして指定された文字列値から、テキストプロパティを取り除きます。


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

12.13 ディレクトリーローカル変数

ディレクトリーは、そのディレクトリー内のすべてのファイルに共通なローカル変数値を指定することができます。Emacsはそのディレクトリー内の任意のファイルをvisitしているバッファー内で、それらの変数にたいするバッファーローカルなバインディングを作成するためにこれを使用します。これはそのディレクトリー内のファイルが何らかのプロジェクトに属していて、同じローカル変数を共有するときなどに有用です。

ディレクトリーローカル変数を指定するために2つの異なる方法があります: 1つは特別なファイルにそれを記述する方法、もう1つはそのディレクトリーにプロジェクトクラス(project class)を定義する方法です。

Constant: dir-locals-file

この定数はEmacsがディレクトリーローカル変数を見つけることができると期待するファイルの名前。ファイル名は.dir-locals.el11。ディレクトリー内でその名前をもつファイルによりEmacsはディレクトリー内の任意のファイル、または任意のサブディレクトリー(オプションでサブディレクトリーを除外できる。以下参照し)にセッティングを適用する。独自に.dir-locals.elをもつサブディレクトリーがある場合には、Emacsはサブディレクトリーで見つかったもっとも深いファイルのディレクトリーからディレクトリーツリーを上方に移動しながら、もっとも深いファイルのセッティングを使用する。この定数は2番目のdir-localsファイル.dir-locals-2.elの名前を導出するためにも使用される。この2番目のdir-localsファイルが与えられた場合には、そのファイルが.dir-locals.elに加えてロードされる。これは.dir-locals.elがバージョンコントロールの共有レポジトリの配下にあって個人のカスタマイズ用に使用できないときに有用。このファイルはローカル変数をフォーマットされたリストとして指定する。詳細はPer-directory Local Variables in The GNU Emacs Manualを参照のこと。

Function: hack-dir-local-variables

この関数は.dir-locals.elファイルを読み込み、そのディレクトリー内の任意のファイルをvisitしているバッファーにローカルなfile-local-variables-alist内に、それらを適用することなくディレクトリーローカル変数を格納する。この関数はディレクトリーローカルなセッティングもdir-locals-class-alist(.dir-locals.elファイルが見つかったディレクトリーにたいする特別なクラスを定義する)内に格納する。この関数は以下で説明するように、dir-locals-set-class-variablesdir-locals-set-directory-classを呼び出すことにより機能する。

Function: hack-dir-local-variables-non-file-buffer

この関数はディレクトリーローカル変数を探して、即座にそれらをカレントバッファーに適用する。これはDiredバッファーのような、非ファイルバッファーをディレクトリーローカル変数のセッティングにしたがわせるために、モードコマンド呼び出しの中から呼び出されることを意図したものである。非ファイルバッファーにたいしては、Emacsはdefault-directoryとその親ディレクトリーの中から、ディレクトリーローカル変数を探す。

Function: dir-locals-set-class-variables class variables

この関数はclassという名前がつけられたシンボルにたいして一連の変数セッティングを定義する。その後はこのクラスを1つ以上のディレクトリーに割り当てることができるので、Emacsはこれらの変数セッティングをディレクトリー内のすべてのファイルに適用する。variables内のリストは2つの形式 — (major-mode . alist)、または(directory . list) — のうちのいずれかをもつことができる。1番目の形式ではそのファイルのバッファーがmajor-modeを継承するモードに切り替わるときに、連想リストalist内のすべての変数が適用される。alist(name . value)という形式。major-modeにたいする特別な値nilは、そのセッティングが任意のモードに適用できることを意味する。alist内では特別なnameとしてsubdirsを使用することができる。連想値がnilならalistは関連するディレクトリー内のファイルだけに適用されて、それらのサブディレクトリーには適用されない。

variablesの2番目の形式では、directoryがそのファイルのディレクトリーの最初のサブディレクトリーなら、上記のルールにしたがいlistが再帰的に適用される。listはこの関数のvariablesで指定できる2つの形式のうち1つを指定する。

Function: dir-locals-set-directory-class directory class &optional mtime

この関数はdirectoryとサブディレクトリー内のすべてのファイルにclassを割り当てる。その後、classにたいして指定されたすべての変数セッティングは、directoryとその子ディレクトリー内でvisitされたすべてのファイルに適用される。classは事前にdir-locals-set-class-variablesで定義されていなければならない。

Emacsが.dir-locals.elファイルからディレクトリー変数をロードする際、内部的にこの関数を使用する。その場合、オプションの引数mtimeはファイルの修正日時(modification time。file-attributesによりリターンされる)を保持する。Emacsは記憶されたローカル変数がまだ有効化チェックするために、この日時を使用する。ファイルを介さず直接クラスを割り当てる場合、この引数はnilになる。

Variable: dir-locals-class-alist

このalistはクラスシンボル(class symbol)とそれに関連づけられる変数のセッティングを保持する。これはdir-locals-set-class-variablesにより更新される。

Variable: dir-locals-directory-cache

このalistはディレクトリー名、それらに割り当てられたクラス名、およびこのエントリーに関連するディレクトリーローカル変数ファイルの修正日時を保持する。関数dir-locals-set-directory-classはこのlistを更新する。

Variable: enable-dir-local-variables

nilならディレクトリーローカル変数は無視される。この変数はファイルローカル変数(ファイルローカル変数を参照)にはしたがうが、ディレクトリーローカル変数は無視したいモードにたいして有用かもしれない。


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

12.14 接続ローカル変数

接続ローカル変数(connection-local variable)はリモート接続をもつバッファーにおいて、異なる変数セッティングにたいする汎用のメカニズムを提供します(Remote Files in The GNU Emacs Manualを参照)。これはそのリモート接続に専用のバッファーに応じてバインドおよびセットされる変数です。


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

12.14.1 接続ローカルなプロファイル

接続ローカルプロファイルとは、特定の接続にたいして適用する変数のセッティングを保存するためにEmacsが使用するプロファイルのことです。connection-local-set-profilesを使用してプロファイルを適用すべき条件を定義することで、プロファイルとリモート接続を関連付けることができます。

Function: connection-local-set-profile-variables profile variables

この関数は接続profile (シンボル)にたいする一連の変数セッティングを定義する。この接続プロファイルに後から1つ以上のリモート接続を割り当てることができ、Emacsはそれらの接続にたいするすべてのプロセスバッファーにそれらの変数セッティングを適用するだろう。variables内のリストは(name . value)という形式のalist。たとえば:

(connection-local-set-profile-variables
  'remote-bash
  '((shell-file-name . "/bin/bash")
    (shell-command-switch . "-c")
    (shell-interactive-switch . "-i")
    (shell-login-switch . "-l")))

(connection-local-set-profile-variables
  'remote-ksh
  '((shell-file-name . "/bin/ksh")
    (shell-command-switch . "-c")
    (shell-interactive-switch . "-i")
    (shell-login-switch . "-l")))

(connection-local-set-profile-variables
  'remote-null-device
  '((null-device . "/dev/null")))

既存のプロファイルにたいして変数セッティングを追加したい場合には、以下のように関数connection-local-get-profile-variablesを使って既存のセッティングを取得できる

(connection-local-set-profile-variables
  'remote-bash
  (append
   (connection-local-get-profile-variables 'remote-bash)
   '((shell-command-dont-erase-buffer . t))))
User Option: connection-local-profile-alist

このalistは接続プロファイルシンボルと連想変数セッティングを保持する。これはconnection-local-set-profile-variablesにより更新される。

Function: connection-local-set-profiles criteria &rest profiles

この関数はcriteriaで識別されるすべてのリモート接続にprofiles (シンボル)を割り当てる。criteriaは接続を識別するplistであり、アプリケーションはその接続を使用する。プロパティ名は:application:protocol:user:machineのいずれか。:applicationのプロパティ値はシンボル、それ以外のプロパティ値は文字列。プロパティはすべてオプション。criterianilなら常に適用される。たとえば:

(connection-local-set-profiles
  '(:application tramp :protocol "ssh" :machine "localhost")
  'remote-bash 'remote-null-device)

(connection-local-set-profiles
  '(:application tramp :protocol "sudo"
    :user "root" :machine "localhost")
  'remote-ksh 'remote-null-device)

criterianilならすべてのリモート接続に適用される。したがって上記の例は以下と等価

(connection-local-set-profiles
  '(:application tramp :protocol "ssh" :machine "localhost")
  'remote-bash)

(connection-local-set-profiles
  '(:application tramp :protocol "sudo"
    :user "root" :machine "localhost")
  'remote-ksh)

(connection-local-set-profiles
  nil 'remote-null-device)

profilesのすべてのプロファイルはconnection-local-set-profile-variablesで定義済みでなければならない。

User Option: connection-local-criteria-alist

このalistは接続のcriteria(判断基準)それに割り当てられたとprofileの名前を含む。関数connection-local-set-profilesはこのリストを更新する。


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

12.14.2 接続ローカル変数の適用

接続を認識するコードの記述時には接続ローカル変数を収集して、もしかしたらそれらを適用する必要があるでしょう。これを行うには以下のようにいくつかの方法があります。

Function: hack-connection-local-variables criteria

この関数はconnection-local-variables-alist内のcriteriaに関連する適用可能な接続ローカル変数を適用することなく収集する。たとえば:

(hack-connection-local-variables
  '(:application tramp :protocol "ssh" :machine "localhost"))

connection-local-variables-alist
     ⇒ ((null-device . "/dev/null")
        (shell-login-switch . "-l")
        (shell-interactive-switch . "-i")
        (shell-command-switch . "-c")
        (shell-file-name . "/bin/bash"))
Function: hack-connection-local-variables-apply criteria

この関数はcriteriaに対応する接続ローカル変数を探してカレントバッファーに即座に適用する。

Macro: with-connection-local-application-variables application &rest body

default-directoryによって指定されるすべての接続ローカル変数をapplicationに適用する。

その後にbodyを実行して接続ローカル変数を非バインド化する。たとえば:

(connection-local-set-profile-variables
  'my-remote-perl
  '((perl-command-name . "/usr/local/bin/perl5")
    (perl-command-switch . "-e %s")))

(connection-local-set-profiles
  '(:application my-app :protocol "ssh" :machine "remotehost")
  'my-remote-perl)

(let ((default-directory "/ssh:remotehost:/working/dir/"))
  (with-connection-local-application-variables 'my-app
    do something useful))
Variable: connection-local-default-application

with-connection-local-variablesが適用されるデフォルトのアプリケーション(シンボル)。デフォルトはtrampだが、letバインドによって一時的にアプリケーションを変更できる(ローカル変数を参照)。

この変数をグローバルに変更してはならない。

Macro: with-connection-local-variables &rest body

これはwith-connection-local-application-variablesと同じだが、そのアプリケーションにたいしてconnection-local-default-applicationを使用する。

Macro: setq-connection-local [symbol form]…

このマクロはconnection-local-profile-name-for-setqで指定された接続ローカルプロファイルを用いて、それぞれのsymbolを対応するformを評価した結果に接続ローカルでバインドする。接続ローカルプロファイルの名前がnilの場合には、このマクロはsetqが行うような通常の方法によって変数をセットする(変数の値のセットを参照)。

たとえば接続ローカルなセッティングの初期化を遅延させるには、このマクロを以下のようにwith-connection-local-variableswith-connection-local-application-variablesと組み合わせて使用する:

(defvar my-app-variable nil)

(connection-local-set-profile-variables
 'my-app-connection-default-profile
 '((my-app-variable . nil)))

(connection-local-set-profiles
 '(:application my-app)
 'my-app-connection-default-profile)

(defun my-app-get-variable ()
  (with-connection-local-application-variables 'my-app
    (or my-app-variable
        (setq-connection-local my-app-variable
                               do something useful))))
Variable: connection-local-profile-name-for-setq

setq-connection-localを通じて変数をセットする際に使用する接続ローカルプロファイル名(シンボル)。これはwith-connection-local-variablesのbody内でletバインドされているが、別のプロファイルで変数をセットしたければ自分でletバインドすることもできる。

この変数をグローバルに変更してはならない。

Variable: enable-connection-local-variables

nilなら接続ローカル変数を無視する。この変数は特殊なモード内でのみ一時的に変更されるべきである。


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

12.15 変数のエイリアス

2つの変数をシノニム(同義語)にすれば、2つの変数は常に同じ値をもち、どちらか一方を変更するともう一方も変更されるようになり、便利なときがあります。変数の名前を変更 — 古い名前はよく考慮して選択されたものではなかったとか、変数の意味が部分的に変更された等の理由で — するとき、互換性のために新しい名前のエイリアス(alias)として古い名前を維持できれば便利なときがあるかもしれません。defvaraliasによってこれを行うことができます。

Function: defvaralias new-alias base-variable &optional docstring

この関数はシンボルbase-variableのエイリアスとして、シンボルnew-aliasを定義する。これはnew-aliasから値を取得するとbase-variableの値がリターンされ、new-aliasの値を変更するとbase-variableの値が変更されることを意味する。エイリアスされた2つの変数名は、常に同じ値と同じバインディングを共有する。

docstring引数が非nilなら、それはnew-aliasのドキュメント文字列を指定する。それ以外なら、エイリアスは(もしあれば)base-variableと同じドキュメント文字列となる。ただしそれはbase-variable自体がエイリアスではない場合で、エイリアスならnew-aliasはエイリアスチェーンの最後の変数のドキュメント文字列になる。

この関数はbase-variableをリターンする。

変数のエイリアスは、変数にたいする古い名前を新しい名前に置き換える便利な方法です。make-obsolete-variableは古い名前を陳腐化(obsolete)していると宣言して。それが将来のある時点で削除されるかもしれないことを宣言します。

Function: make-obsolete-variable obsolete-name current-name when &optional access-type

この関数はバイトコンパイラーに変数obsolete-nameが陳腐化していると警告させる。current-nameがシンボルなら、それはこの変数の新たな名前である。警告メッセージはその後、obsolete-nameのかわりにcurrent-nameを使用するよう告げるようになる。current-nameが文字列なら、それはメッセージであり、置き換えられる変数はない。whenはその変数が最初に陳腐化するのがいつかを示す文字列(通常はバージョン番号文字列)。

オプションの引数access-typeが非nilなら、それは陳腐化の警告を引き起こすアクセスの種類を指定すること。getsetを指定できる。

2つの変数シノニムを作成してマクロdefine-obsolete-variable-aliasを使用することにより、1つが陳腐化していると同時に宣言できます。

Macro: define-obsolete-variable-alias obsolete-name current-name when &optional docstring

このマクロは変数obsolete-nameが陳腐化しているとマークして、それを変数current-nameにたいするエイリアスにする。これは以下と等価である:

(defvaralias obsolete-name current-name docstring)
(make-obsolete-variable obsolete-name current-name when)

このマクロはすべてのパラメーターを評価する。obsolete-namecurrent-nameはいずれもシンボルのはずなので、通常は以下のような使用方法になる:

(define-obsolete-variable-alias 'foo-thing 'bar-thing "27.1")
Function: indirect-variable variable

この関数はvariableのエイリアスチェーンの最後の変数をリターンする。variableがシンボルでない、またはvariableがエイリアスとして定義されていなければ、この関数はvariableをリターンする。

この関数はシンボルのチェーンがループしていたら、cyclic-variable-indirectionエラーをシグナルする。

(defvaralias 'foo 'bar)
(indirect-variable 'foo)
     ⇒ bar
(indirect-variable 'bar)
     ⇒ bar
(setq bar 2)
bar
     ⇒ 2
foo
     ⇒ 2
(setq foo 0)
bar
     ⇒ 0
foo
     ⇒ 0

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

12.16 値を制限された変数

通常のLisp変数には、有効なLispオブジェクトである任意の値を割り当てることができます。しかしLispではなくCで定義されたLisp変数もあります。これらの変数のほとんどは、DEFVAR_LISPを使用してCコードで定義されています。Lispで定義された変数と同様、これらは任意の値をとることができます。しかしいくつかの変数はDEFVAR_INTDEFVAR_BOOLを使用して定義されています。C実装の概要的な議論は、Writing Emacs Primitives、特にsyms_of_filename型の関数の説明を参照してください。

DEFVAR_BOOL型の変数は、値にniltしかとることができません。他の値の割り当てを試みるとtがセットされます:

(let ((display-hourglass 5))
  display-hourglass)
     ⇒ t
Variable: byte-boolean-vars

この変数はDEFVAR_BOOL型のすべての変数のリストを保持する。

DEFVAR_INT型の変数は、整数値だけをとることができます。他の値の割り当てを試みると結果はエラーになります:

(setq undo-limit 1000.0)
error→ Wrong type argument: integerp, 1000.0

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

12.17 ジェネリック変数

ジェネリック変数(generalized variable: 汎変数)またはplace formsetfマクロ(setfマクロを参照)を使用して値が格納される、Lispメモリー内の多くの場所のうちの1つです。一番シンプルなplace formは通常のLisp変数です。しかしリストのCARCDR、配列の要素、シンボルのプロパティ、その他多くのロケーション(location)もLisp値が格納される場所です。

ジェネリック変数は、C言語のlvalues(左辺値)と類似しています。C言語のlvalueでは‘x = a[i]’で配列から要素を取得し、同じ表記を使用して‘a[i] = x’で要素を格納します。Cではa[i]のような特定のフォームがlvalueになれるように、Lispでジェネリック変数になることができる一連のフォームが存在します。


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

12.17.1 setfマクロ

setfマクロはジェネリック変数を操作するもっとも基本的な方法です。setfフォームはsetqと似ていますが、シンボルだけでなくそれぞれのペアーの1つ目(左)の任意のplace formを受け入れます。たとえば(setf (car a) b)aのcarをbにセットして(setcar a b)と同じ操作を行いますが、このタイプのplaceにセットやアクセスするために2つの関数を個別に覚える必要はありません。

Macro: setf [place form]…

このマクロはformを評価して、その値をplaceに格納する。placeは有効なジェネリック変数フォームでなければならない。複数のplace/formペアーがある場合の割り当てについてはsetqの場合と同様。setfは最後のformの値をリターンする。

以下のLispフォームはEmacsではジェネリック変数として機能するフォームなので、setfplace引数にすることができます:

  • シンボル。言い換えると、(setf x y)は完全に(setq x y)と正に等しく、厳密に言うとsetq自体はsetfが存在するので冗長です。これは純粋にスタイルと歴史的な理由によりますが、ほとんどのプログラマーは依然として単純な変数へのセットにはsetqの方を好みます。マクロ(setf x y)は実際には(setq x y)に展開されるので、コンパイルされたコードでこれを使用することにパフォーマンス的な不利はありません。
  • 以下の標準的なLisp関数の呼び出し:
    aref      cddr      symbol-function
    car       elt       symbol-plist
    caar      get       symbol-value
    cadr      gethash
    cdr       nth
    cdar      nthcdr
    
  • 以下のEmacs特有な関数の呼び出し:
    alist-get                     overlay-start
    default-value                 overlay-get
    face-background               process-buffer
    face-font                     process-filter
    face-foreground               process-get
    face-stipple                  process-sentinel
    face-underline-p              terminal-parameter
    file-modes                    window-buffer
    frame-parameter               window-dedicated-p
    frame-parameters              window-display-table
    get-register                  window-hscroll
    getenv                        window-parameter
    keymap-parent                 window-point
    match-data                    window-start
    overlay-end
    
  • (substring subplace n [m])という形式の呼び出し。ここでsubplaceはそれ自体がカレント値として文字列をもち、それに格納される値も文字列であるような有効なジェネリック変数。新たな文字列は目的となる文字列の指定した箇所につなぎ合わされる。たとえば:
    (setq a (list "hello" "world"))
         ⇒ ("hello" "world")
    (cadr a)
         ⇒ "world"
    (substring (cadr a) 2 4)
         ⇒ "rl"
    (setf (substring (cadr a) 2 4) "o")
         ⇒ "o"
    (cadr a)
         ⇒ "wood"
    a
         ⇒ ("hello" "wood")
    
  • ジェネリック変数ではifcondというコンディションも機能する。たとえば以下はfoobarいずれかの変数をzotにセットする例:
    (setf (if (zerop (random 2))
    	  foo
    	bar)
          'zot)
    

どのように処理すれば良いか未知なplaceフォームを渡すと、setfはエラーをシグナルします。

nthcdrの場合、関数のリスト引数はそれ自体が有効なplaceフォームでなければならないことに注意してください。たとえば(setf (nthcdr 0 foo) 7)は、foo自体に7をセットするでしょう。

マクロpush(リスト変数の変更を参照)とpop(リスト要素へのアクセスを参照)は、リストだけでなくジェネリック変数を操作できます。(pop place)place内に格納されたリストの最初の要素を削除してリターンします。これは(prog1 (car place) (setf place (cdr place)))と似ていますが、すべてのサブフォームを一度だけ評価します。(push x place)place内に格納されたリストの一番前にxを挿入します。これは(setf place (cons x place))と似ていますが、サブフォームの評価が異なります。nthcdr placeへのpushpopは、リスト内の任意の位置での挿入ち削除に使用できることに注意してください。

cl-libライブラリーでは追加のsetf placeを含む、ジェネリック変数にたいするさまざまな拡張が定義されています。Generalized Variables in Common Lisp Extensionsを参照してください。


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

12.17.2 新たなsetfフォーム

このセクションでは、setfが操作できる新たなフォームの定義方法を説明します。

Macro: gv-define-simple-setter name setter &optional fix-return

このマクロは単純なケースでsetfメソッドを簡単に定義することを可能にする。nameは関数、マクロ、スペシャルフォームの名前。nameがそれを更新するための対応するsetter関数をもつなら、このマクロを使用できる(たとえば(gv-define-simple-setter car setcar))。

このマクロは以下のフォームの呼び出しを

(setf (name args…) value)

以下のように変換する。

(setter argsvalue)

このようなsetfの呼び出しはvalueをリターンするとドキュメントされている。これはcarsetcarでは問題はない。setcarはそれがセットする値をリターンするからである。setter関数がvalueをリターンしない場合には、gv-define-simple-setterfix-return引数に、非nil値を使用すること。これは以下のようなものに展開される

(let ((temp value))
  (setter args… temp)
  temp)

これで正しい結果がリターンされることが保証される。

Macro: gv-define-setter name arglist &rest body

このマクロは上述のフォームより複雑なsetf展開を可能にする。たとえば呼び出すべきシンプルなsetter関数が存在しないときや、もしそれが存在してもplaceフォームとは異なる引数を要求するなら、このフォームを使う必要があるかもしれない。

このマクロは最初にsetf引数フォーム(value args…)arglistにバインドして、その後bodyを実行することによって、フォーム(setf (name args…) value)を展開する。bodyは割り当てを行うLispフォームをリターンして、最終的にはセットされた値をリターンすること。以下はこのマクロの使用例:

(gv-define-setter caar (val x) `(setcar (car ,x) ,val))
Macro: gv-define-expander name handler

展開をより詳細に制御するためにgv-define-expanderマクロが使用できる。たとえばセット可能なsubstringは以下の方法で実装できる:

(gv-define-expander substring
  (lambda (do place from &optional to)
    (gv-letplace (getter setter) place
      (macroexp-let2* (from to)
        (funcall do `(substring ,getter ,from ,to)
                 (lambda (v)
                   (macroexp-let2* (v)
                     `(progn
                        ,(funcall setter `(cl--set-substring
                                           ,getter ,from ,to ,v))
                        ,v))))))))
Macro: gv-letplace (getter setter) place &rest body

マクロgv-letplacesetfのような処理を行うマクロを定義するのに有用。たとえばCommon Lispのincfマクロは以下の方法で実装できる:

(defmacro incf (place &optional n)
  (gv-letplace (getter setter) place
    (macroexp-let2* ((v (or n 1)))
      (funcall setter `(+ ,v ,getter)))))

getterplaceの値をリターンするコピー可能な式にバインドされる。setterは式vを受け取り、placevをセットする新たな式をリターンする関数にセットされる。bodygettersetterを介してplaceを操作するEmacs Lisp式をリターンすること。

詳細はgv.elのソースファイルを参照。

Function: make-obsolete-generalized-variable obsolete-name current-name when

この関数はバイトコンパイラーにジェネリック変数obsolete-nameが陳腐化していると警告させる。current-nameがシンボルなら、obsolete-nameのかわりにcurrent-nameを使用するよう告げるメッセージにより警告が行われる。current-nameが文字列なら、それはメッセージであること。whenはその変数が最初に陳腐化するのがいつかを示す文字列(通常はバージョン番号文字列)。

Common Lispに関する注意: Common Lispは関数としてのsetf、すなわち関数名がシンボルではなくリスト(setf name)であるようなsetf関数の挙動を指定するために別の方法を定義する。たとえば(defun (setf foo) …)は、setffooに適用されるときに使用される関数を定義する。Emacsはこれをサポートしない。適切な展開が定義されていないフォームにsetfを使用するとコンパイル時エラーとなる。Common Lispでは後で関数(setf func)が定義されるのでエラーにならない。


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

12.18 マルチセッション変数

ある変数に値をセットしてからEmacsを終了すると、その後に再起動してもその値が自動的に復元されることはありません。ユーザーが値を永続的にセットする場合には、通常の変数であればスタートアップファイル、ユーザーオプションであればCustomize(カスタマイゼーション設定を参照)を用いるのが普通です。更にデータを格納するためにさまざまなファイルをもつパッケージが沢山あります(例: Gnusはデータを.newsrc.eld、URLライブラリーはcookieを~/.emacs.d/url/cookiesに格納する)。

これらの2つの対極的な事項(スタートアップファイルに書き込まれる構成、あるいは大規模なアプリケーションが個別のファイルへ書き込む状態)にたいして、Emacsはセッションに跨がるデータを複製(replicate)するためのマルチセッション変数(multisession variables)と呼ばれる機能を提供しています(この機能はすべてのシステムで利用できる訳ではない)。これらがどのような利用を意図しているかヒントを与えるために、以下に小さな例を示しましょう:

(define-multisession-variable foo-var 0)
(defun my-adder (num)
  (interactive "nAdd number: ")
  (setf (multisession-value foo)
        (+ (multisession-value foo) num))
  (message "The new number is: %s" (multisession-value foo)))

これは変数foo-varを定義して、(この変数が以前のセッション以降に存在していなければ)値‘0’に初期化された特別なマルチセッションオブジェクトにバインドしています。my-adderコマンドはユーザーに数値の入力を求めて、それを(もしかしたら保存されていた)古い値に加算してから新しい値へと保存します。

この機能は巨大なデータ構造にたいする使用を意図したものではありませんが、ほとんどの値にたいしてパフォーマンスは高いはずです。

Macro: define-multisession-variable name initial-value &optional doc &rest args

このマクロはマルチセッション変数としてnameを定義して、その変数に以前に値が割り当てられていなければinitial-valueを与える。docはdoc文字列、argsにはいくつかのキーワード引数を使用できる:

:package package-symbol

マルチセッション変数がpackage-symbolで指定されたパッケージに属することを告げるキーワード。package-symbolnameは一意な組み合わせであること。package-symbolが与えられない場合には、nameのシンボル名の1つ目の“セグメント”(シンボル名の最初の‘-’の手前までの部分)がデフォルトになる。たとえばnamefoo-varpackage-symbolを与えなければ、package-symbolのデフォルトはfoo

:synchronized bool

boolが非nilであればマルチセッション変数を同期(synchronized)できる。同時に2つのEmacsインスタンスが実行中に、別のEmacsがマルチセッション変数foo-varを変更すると、カレントのEmacsインスタンスがその値にアクセスした際には変更済みのデータが取得されることを意味する。これはsynchronizednilあるいは未指定の場合には発生せず、この変数を使用するすべてのEmacsセッションそれぞれにたいして独立した値となる。

:storage storage

storageで指定されたメソッドを使用する。sqlite(SQLiteサポートつきでコンパイルされたEmacsの場合)、あるいはfilesのいずれか。与えられない場合には、後述のmultisession-storage変数の値がデフォルトになる。

Function: multisession-value variable

この関数はvariableのカレント値をリターンする。そのEmacsセッションにおいて変数にこれまでアクセスしていない、あるいは変数が外部から変更されていた場合には外部ストレージから読み込まれる。それ以外の場合にはそのセッションでのカレント値がそのままリターンされる。マルチセッション変数ではないvariableにたいしてこの関数を呼び出すとエラーとなる。

multisession-valueを通じて取得した値は互いにeqのときもあれば異なるときもあるが、常にequalである。

これはジェネリック化された変数(ジェネリック変数を参照)なので、そのような変数はたとえば以下のような方法によって更新される:

(setf (multisession-value foo-bar) 'zot)

この方法によって保存できるのは読み取り可能なプリント構文(プリント表現と読み取り構文を参照)をもつEmacs Lisp値のみ。

そのマルチセッション変数が同期化されている場合にセットすると、最初に値が更新されるかもしれない。たとえば:

(cl-incf (multisession-value foo-bar))

ここではまず別のEmacsセッションによって値が変更されているかどうかをチェックして、その後に値に1を加算して格納している。これはロックなしでおこなわれために、多くのセッションが同時に値を変更する場合にどのセッションが“勝利”するか予想できないことに注意。

Function: multisession-delete object

この関数はobjectとその値を永続化されたストレージから削除する。

Function: make-multisession

特定の変数ではなく明示的なパッケージとキーに結びつけられらた永続的な値を作成することもできる。

(setq foo (make-multisession :package "mail"
                             :key "friends"))
(setf (multisession-value foo) 'everybody)

この関数はdefine-multisession-variableと同じキーワードに加えて、:initial-valueキーワード(デフォルト値を指定する)もサポートする。

User Option: multisession-storage

この変数はマルチセッション変数をどのように格納するかを制御する。デフォルト値のfilesmultisession-directoryで指定されたディレクトリー内に変数1つにたいしてファイル1つという構造で値が格納されることを意味する。これがsqliteなら値はSQLiteデータベースに格納される(SQLiteサポートつきでビルドされたEmacsでのみ利用可能)。

User Option: multisession-directory

このディレクトリー配下にマルチセッション変数は格納される。デフォルトはuser-emacs-directoryのサブディレクトリーmultisession/ (通常なら~/.emacs.d/multisession/)。

Command: list-multisession-values

このコマンドはすべてのマルチセッション変数をリストするバッファーをポップアップして、それらの値の削除や編集が行える特別なモードmultisession-edit-modeにエンターする。


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

13 関数

Lispプログラムは主にLisp関数で構成されます。このチャプターはで関数とは何か、引数を受け取る方法、そして関数を定義する方法を説明します。


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

13.1 関数とは?

一般的な意味では関数とは引数(arguments)と呼ばれる与えられた入力値の計算を担うルールです。計算の結果は関数の値(value)、またはreturn値(return value)と呼ばれます。計算は変数の値やデータ構造の内容を変更する等の副作用をもつこともできます(Definition of side effectを参照)。純粋関数(pure function)とは、それらに加えて副作用をもたず、機種別やシステム状態のような外部要因とは無関係に同じ条件の引数にたいして常に同一の値をリターンする関数のことです。

ほとんどのコンピューター言語では、関数はそれぞれ名前をもちます。しかしLispでは厳密な意味において関数は名前をもちません。関数はオブジェクトであり、関数の名前の役割を果たすシンボルに関連づけることができますが(たとえばcar)、それはオプションです。関数の命名を参照してください。関数が名前を与えられたとき、通常はそのシンボルを“関数”として参照します(たとえば関数carのように参照する)。このマニュアルでは、関数名と関数オブジェクト自身との間の区別は通常は重要ではありませんが、それが意味をもつような場合には注記します。

スペシャルフォーム(special form)マクロ(macro)と呼ばれる関数likeなオブジェクトがいくつかあり、それらも引数を受け取って計算を行います。しかし以下で説明するようにEmacs Lispではこれらは関数とはみなされません。

以下は関数と関数likeなオブジェクトにたいする重要な条件です:

lambda expression

Lispで記述された関数(厳密には関数オブジェクト)。これらについては以降のセクションで説明します。 ラムダ式を参照のこと。

primitive

Lispから呼び出すことができるが実際にはCで記述されている。プリミティブはビルトイン関数(built-in functions)とかサブルーチン(subr)のようにも呼ばれる。それらの例には関数likeなcarappendが含まれる。加えてすべてのスペシャルフォーム(以下参照)もプリミティブとみなされる。

関数はLispの基礎となる部分(たとえばcar)であり、オペレーティングシステムのサービスにたいして低レベルのインターフェースを与え、高速に実行される必要があるために、通常はプリミティブとして実装されている。Lispで定義された関数と異なり、プリミティブの修正や追加には、Cソースの変更とEmacsのリコンパイルが必要となる。Emacsプリミティブの記述を参照のこと。

special form

プリミティブは関数と似ているが、すべての引数が通常の方法で評価されない。いくつかの引数だけが評価されるかもしれず、通常ではない順序で評価されるか、複数回評価されるかもしれない。プリミティブの例にはifandwhileが含まれる。スペシャルフォームを参照のこと。

macro

あるLisp式をオリジナルの式のかわりに評価される別の式に変換する、関数とは別のLispで定義された構文。マクロはスペシャルフォームが行う一連のことを、Lispプログラマーが行うのを可能にする。マクロを参照のこと。

command

プリミティブcommand-executeを通じて呼び出すことができるオブジェクトで、通常はそのコマンドにバインドされたキーシーケンスをユーザーがタイプすることにより呼び出される。インタラクティブな呼び出しを参照のこと。コマンドは通常は関数である。その関数がLispで記述されていれば、関数の定義内のinteractiveフォームによってコマンドとなる(コマンドの定義を参照)。関数であるコマンドは他の関数と同様、Lisp式から呼び出すこともできる。

キーボードマクロ(文字列かベクター)は関数ではないが、これらもコマンドである。キーボードマクロを参照のこと。シンボルの関数セルにコマンドが含まれてれば、わたしたちはそのシンボルをコマンドと言う(シンボルの構成要素を参照)。そのような名前つきコマンド(named command)M-xで呼び出すことができる。

closure

ラムダ式とよく似た関数オブジェクトだが、クロージャはレキシカル変数バインディングの環境にも囲われている。クロージャを参照のこと。

byte-code function

バイトコンパイラーによりコンパイル済みの関数。バイトコード関数型を参照のこと。

autoload object

実際の関数のプレースホルダー。autoloadオブジェクトが呼び出されると、Emacsは実際の関数の定義を含むファイルをロードした後に実際の関数を呼び出す。autoloadを参照のこと。

関数functionpを使用して、あるオブジェクトが関数かどうかテストできます:

Function: functionp object

この関数はobjectが任意の種類の関数(funcallに渡すことができる)ならtをリターンする。functionpは関数を名づけるシンボルにたいしてはt、マクロやスペシャルフォームにたいしてはnilをリターンすることに注意。

objectは関数でなければ、この関数は通常はnilをリターンする。ただし関数オブジェクトの表現は複雑なので、効率上の理由によりobjectがたとえ関数でなくてもこの関数がtをリターンするときが稀にある。

任意の関数が期待する引数の個数を調べることもできます:

Function: func-arity function

この関数は指定されたfunctionの引数リストに関する情報を提供する。リターン値は(min . max)という形式のコンスセル。ここでminは引数の最小個数、maxは引数の最大個数、または&rest引数をもつ関数ではmanyfunctionがスペシャルフォームならシンボルunevalled

以下のようにある状況下ではこの関数は不正確な結果をリターンすることに注意:

functionpと異なり、以下の3つの関数はシンボルをそれの関数定義としては扱いません

Function: subrp object

この関数はobjectがビルトイン関数(たとえばLispプリミティブ)ならtをリターンする。

(subrp 'message)            ; messageはシンボルであり、
     ⇒ nil                 ;   subrオブジェクトではない
(subrp (symbol-function 'message))
     ⇒ t
Function: byte-code-function-p object

この関数はobjectがバイトコード関数ならtをリターンする。たとえば:

(byte-code-function-p (symbol-function 'next-line))
     ⇒ t
Function: compiled-function-p object

この関数はobjectがELispソースコード形式ではなくても、何らかのマシンコードやバイトコードならtをリターンする。より正しくは、ビルドイン関数(別名“プリミティブ(primitive)”。関数とは?を参照)、バイトコンパイル済み関数(バイトコンパイルを参照)、ネイティブコンパイル済み関数(Lispからネイティブコードへのコンパイルを参照)、またはダイナミックモジュールからロードされた関数(Emacsのダイナミックモジュールを参照)の場合にtをリターンする。

Function: subr-arity subr

これはfunc-arityと同様だがシンボルインダイレクションなしのビルトイン関数にたいしてのみ機能する。非ビルトイン関数にたいしてはエラーをシグナルする。かわりにfunc-arityの使用を推奨する。


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

13.2 ラムダ式

ラムダ式(lambda expression)はLispで記述された関数オブジェクトです。以下は例です:

(lambda (x)
  "Xの双曲線コサインをreturnする"
  (* 0.5 (+ (exp x) (exp (- x)))))

Emacs Lispではこのようなリストは、関数オブジェクトに評価される有効な式です。

ラムダ式自身は名前をもたない無名関数(anonymous function)です。ラムダ式をこの方法で使用できますが(無名関数を参照)、名前付き関数(named functions)を作成するためにシンボルに関連付けられる方が一般的です(関数の命名を参照)。これらの詳細に触れる前に以下のサブセクションではラムダ式の構成要素と、それらが行うことについて説明します。


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

13.2.1 ラムダ式の構成要素

ラムダ式は以下のようなリストです:

(lambda (arg-variables…)
  [documentation-string]
  [interactive-declaration]
  body-forms…)

ラムダ式の1番目の要素は常にシンボルlambdaです。これはそのリストが関数を表すことを示します。lambdaで関数定義を開始する理由は、別の目的での使用が意図された他のリストが、意図せずに関数として評価されないようにするためです。

2番目の要素はシンボル — 引数変数名のリストです(引数リストの機能を参照)。これはラムダリスト(lambda list)と呼ばれます。Lisp関数が呼び出されたとき、引数値はラムダリスト内の変数と対応付けされます。ラムダリストには、与えられた値にたいするローカルバインディングが付与されます。ローカル変数を参照してください。

ドキュメント文字列(documentation string)はEmacs Lispのヘルプ機能にたいして、その関数を説明する関数定義に配されたLispの文字列オブジェクトです。関数のドキュメント文字列を参照してください。

インタラクティブ宣言(interactive declaration)は、(interactive code-string)という形式のリストです。これはこの関数が対話的に使用された場合に引数を提供する方法を宣言します。この宣言をもつ関数は、コマンド(command)と呼ばれます。コマンドはM-xを使用したり、キーにバインドして呼び出すことができます。この方法で呼び出されることを意図しない関数は、インタラクティブ宣言を持つべきではありません。インタラクティブ定義を記述する方法は、コマンドの定義を参照してください。

残りの要素はその関数のbody(本体) — その関数が処理を行うためのLispコード(Lispプログラマーは“評価されるLispフォームのリスト”と言うだろう)です。この関数からリターンされる値は、bodyの最後の要素によりリターンされる値です。


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

13.2.2 単純なラムダ式の例

以下の例を考えてみてください:

(lambda (a b c) (+ a b c))

以下のようにfuncallに渡すことにより、この関数を呼び出すことができます:

(funcall (lambda (a b c) (+ a b c))
         1 2 3)

この呼び出しは変数aに1、bに2、cに3をバインドして、ラムダ式のbodyを評価します。bodyの評価によってこれら3つの数が加算されて、6が結果として生成されます。したがってこの関数呼び出しにより6がリターンされます。

以下のように引数は他の関数の結果であってもよいことに注意してください:

(funcall (lambda (a b c) (+ a b c))
         1 (* 2 3) (- 5 4))

これは引数1(* 2 3)(- 5 4)を左から右に評価します。その後ラムダ式に引数1、6、1を適用して値8が生成されます。

これらの例が示すように、ローカル変数を作成してそれらに値を与えるフォームとして、CARがラムダ式であるようなフォームを使用することができます。古い時代のLispでは、この方法がローカル変数をバインドして初期化する唯一の方法でした。しかし現在ではこの目的にはフォームletを使用するほうが明解です(ローカル変数を参照)。ラムダ式は主に他の関数の引数として渡される無名関数(無名関数を参照)として、あるいは名前つき関数(関数の命名を参照)を生成するためにシンボルの関数定義に格納するために使用されます。


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

13.2.3 引数リストの機能

シンプルなサンプル関数(lambda (a b c) (+ a b c))は3つの引数変数を指定しているので、3つの引数で呼び出されなければなりません。引数を2つしか指定しなかったり4つ指定した場合にはwrong-number-of-argumentsエラーとなります(エラーを参照)。

特定の引数を省略できる関数を記述できると便利なこともあります。たとえば関数substringは3つの引数 — 文字列、開始インデックス、終了インデックス — を受け取りますが、3つ目の引数を省略すると、デフォルトでその文字列のlengthとなります。関数list+が行うように、特定の関数にたいして不定個の引数を指定できると便利なときもあります。

関数が呼び出されるとき省略されるかもしれないオプションの引数を指定するには、オプションの引数の前にキーワード&optionalを含めるだけです。0個以上の追加引数のリストを指定するには、最後の引数の前にキーワード&restを含めます。

したがって引数リストの完全な構文は以下のようになります:

(required-vars[&optional [optional-vars]]
 [&rest rest-var])

角カッコ(square bracket)は&optional&rest、およびそれらに続く変数が省略できることを示します。

この関数の呼び出しではrequired-varsのそれぞれにたいして、実際の引数が要求されます。0個以上のoptional-varsにたいして実際の引数があるかもしれませんが、ラムダ式が&restを使用していなければ、その個数を超えて実際の引数を記述することはできません。&restが記述されていれば、追加で任意の個数の実際の引数があるかもしれません。

optionaやrest変数にたいして実際の引数が省略されると、それらのデフォルトは常にnilになります。関数にたいして引数に明示的にnilが使用されたのか、引数が省略されたのかを区別することはできません。しかし関数のbodyが、nilを他の有意な値が省略されたと判断することは自由です。substringはこれを行います。substringの3つ目の引数がnilなら、それは文字列の長さを使用することを意味します。

Common Lispに関する注意: Common Lispではオプションの引数が省略されたときに使用するデフォルト値を指定できる。Emacs Lispでは、引数が明示的に渡されたかを調べるsupplied-p変数はサポートされない。

例えば引数リストは以下のようになります:

(a b &optional c d &rest e)

これはabは最初の2つの実引数となり、これらは必須です。さらに1つまたは2つの引数が指定された場合には、それらは順番にcdにバインドされます。1つ目から4つ目の引数の後の引数はリストにまとめられて、eにそのリストがバインドされます。したがって2つしか引数が指定されなかった場合にはcdenilになります。2つまたは3つの引数の場合にはdenilです。引数が4つ以下の場合には、enilになります。正確に5つの引数に明示的にnilが指定された場合には、eにたいして他の単一値が与えられたときのように、引数のnilが1要素のリスト(nil)としてeに与えられます。

オプションの引数の後ろに必須の引数を指定する方法はありません — これは意味を成さないからです。なぜそうなるかは、この例でcがオプションでdが必須な場合を考えてみてください。実際に3つの引数が与えられたとします。3番めの引数は何を指定したのでしょうか? この引数はcなのでしょうか、それともdに使用されるのでしょうか? 両方の場合が考えられます。同様に&rest引数の後に、さらに引数(必須またはオプション)をもつことも意味を成しません。

以下に引数リストと、それを正しく呼び出す例をいくつか示します:

(funcall (lambda (n) (1+ n))        ; 1つの必須:
         1)                         ; これは正確に1つの引数を要求する
     ⇒ 2
(funcall (lambda (n &optional n1)   ; 1つは必須で、1つはオプション:
           (if n1 (+ n n1) (1+ n))) ; 1つまたは2つの引数
         1 2)
     ⇒ 3
(funcall (lambda (n &rest ns)       ; 1つは必須で、後は残り:
           (+ n (apply '+ ns)))     ; 1つ以上の引数
         1 2 3 4 5)
     ⇒ 15

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

13.2.4 関数のドキュメント文字列

ラムダ式はラムダリストの直後に、オプションでドキュメント文字列(documentation string)をもつことができます。この文字列は、その関数の実行に影響を与えません。これはコメントの一種ですがLisp機構に内在するシステム化されたコメントであり。Emacsのヘルプ機能で使用できます。ドキュメント文字列にアクセスする方法は、ドキュメントを参照してください。

たとえその関数があなたのプログラム内だけで呼び出される関数だとしても、すべての関数にドキュメント文字列を与えるのはよいアイデアです。ドキュメント文字列はコメントと似ていますが、コメントより簡単にアクセスできます。

ドキュメント文字列の1行目は、関数自体にもとづくものであるべきです。なぜならaproposは、最初の1行目だけを表示するからです。ドキュメント文字列の1行目は、その関数の目的を要約する1つか2つの完全なセンテンスで構成されるべきです。

ドキュメント文字列の開始は通常、ソースファイル内ではインデントされていますが、ドキュメント文字列の開始のダブルクォート文字の前にインデントのスペースがあるので、インデントはドキュメント文字列の一部にはなりません。ドキュメント文字列の残りの行がプログラムソース内で揃うようにインデントする人がいます。これは間違いです。後続の行のインデントは文字列の内部にあります。これはソースコード内での見栄えはよくなりますが、ヘルプコマンドで表示したとき見栄えが悪くなります。

ドキュメント文字列がなぜオプションになるのか不思議に思うかもしれません。なぜならドキュメント文字列の後には必須となる関数の構成要素であるbodyが続くからです。文字列を評価するとその文字列自身がリターンされるので、それがbody内の最後のフォームでない限りなんの効果もありません。したがって実際はbodyの1行目とドキュメント文字列で混乱が生じることはありません。bodyの唯一のフォームが文字列なら、それはリターン値とドキュメントの両方の役目を果たします。

ドキュメント文字列の最後の行には、実際の関数引数とは異なる呼び出し規約を指定できます。これは以下のようなテキストを記述します

\(fn arglist)

そのテキストの後に空行を配置して、テキスト自身は行頭から記述、ドキュメント文字列内でこのテキストの後に改行が続かないように記述します(‘\’はEmacsの移動コマンドが混乱するのを避けるために使用する)。この方法で指定された呼び出し規約は、ヘルプメッセージ内で関数の実引数から生成される呼び出し例と同じ場所に表示されます。

マクロ定義内に記述された引数は、ユーザーがマクロ呼び出しの一部だと考える方法とは合致しない場合がしばしばあるので、この機能はマクロ定義で特に有用です。

呼び出し規約を廃止して上記の仕様で示す規約を公開したければ、この機能を使用してはなりません。かわりに廃止された呼び出し規約を使用するLispプログラムのバイトコンパイル時に警告メッセージを発する宣言advertised-calling-convention (declareフォームを参照)かset-advertised-calling-convention (関数の陳腐化の宣言を参照)を使用してください。

ドキュメント文字列は通常だと静的ですが、動的な生成を要するときもあるかもしれません。コンパイル時にドキュメント文字列と一緒に関数コードを生成するマクロを記述することでこれを達成できる場合もあります。しかしドキュメント文字列のかわりに(:documentation form)を記述することで、doc文字列を動的に生成することもできます。これは実行時に関数が定義されるとformを評価して、それをドキュメント文字列として使用します12。関数のシンボルのfunction-documentationプロパティに文字列に評価されるLispフォームをセットすれば、オンザフライでドキュメント文字列を算出することもできます。

たとえば:

(defun adder (x)
  (lambda (y)
    (:documentation (format "Add %S to the argument Y." x))
    (+ x y)))
(defalias 'adder5 (adder 5))
(documentation 'adder5)
    ⇒ "Add 5 to the argument Y."

(put 'adder5 'function-documentation
     '(concat (documentation (symbol-function 'adder5) 'raw)
              "  Consulted at " (format-time-string "%H:%M:%S")))
(documentation 'adder5)
    ⇒ "Add 5 to the argument Y.  Consulted at 15:52:13"
(documentation 'adder5)
    ⇒ "Add 5 to the argument Y.  Consulted at 15:52:18"

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

13.3 関数の命名

シンボルは関数の名前となることができます。これはそのシンボルの関数セル(function cell: シンボルの構成要素を参照)が、関数オブジェクト(たとえばラムダ式)を含むときに起こります。するとそのシンボル自身が呼び出し可能な有効な関数、つまりそのシンボルの関数セルの関数と等価になります。

関数セルの内容はそのシンボルの関数定義(function definition)と呼ぶこともできます。そのシンボルのかわりにシンボルの関数定義を使う手続きのことをシンボル関数インダイレクション(symbol function indirection)と呼びます。シンボル関数インダイレクションを参照。与えられたシンボルに関数定義がなければシンボルの関数セルはvoidと呼ばれ、それを関数として使用することはできません。

実際のところほとんどすべての関数は名前をもち、その名前により参照されます。ラムダ式を定義することで名前つきのLisp関数を作成、それを関数セル(関数セルの内容へのアクセスを参照)に置くことができます。しかしより一般的なのはdefunマクロ(次のセクションで説明)を使う方法です。 関数の定義を参照してください。

わたしたちが関数に名前を与えるのは、Lisp式内で関数を名前で参照するのが便利だからです。また名前つきの関数は簡単に自分自身を — 再帰的(recursive)に参照することができます。さらにプリミティブはテキスト的な名前だけで参照することができます。なぜならプリミティブ関数は入力構文(read syntax)をもたないオブジェクトだからです(プリミティブ関数型を参照)。

関数が一意な名前をもつ必要はありません。与えられた関数オブジェクトは通常は1つのシンボルの関数セルだけに存在しますが、これは単に慣習的なものです。fsetを使用すれば関数を複数のシンボルに格納するのは簡単です。それらのシンボルはそれぞれ、同じ関数にたいする有効な名前となります。

関数として使用しているシンボルを、変数としても利用できることに注意してください。シンボルのこれら2つの利用法は独立しており、競合はしません(これはSchemaのような他のいくつかのLisp方言には当てはまらない)。

慣例により関数のシンボルが‘--’で分割される2つの名前で構成される場合には、その関数は内部的な使用を意図しており、名前の最初の部分は関数を定義するファイルです。たとえばvc-git--rev-parseという名前の関数はvc-git.elで定義される内部関数です。Cで記述された内部関数はbury-buffer-internalのように名前が‘-internal’で終わります。2018年より前に貢献されたEmacsコードは内部的な使用にたいして別の命名規約を使用するかもしれませんが、これらは徐々に廃止されます。


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

13.4 関数の定義

わたしたちは通常は関数を最初に作成したときに名前を与えます。これは関数の定義(defining a function)と呼ばれており、通常はdefunマクロにより行われます。このセクションでは関数を定義する別の方法も説明します。

Macro: defun name args [doc] [declare] [interactive] body…

defunは新たなLisp関数を定義する通常の方法である。これは引数リストargs、およびbodyにより与えられるbodyフォームとともに、シンボルnameを関数として定義する(引数リストの機能を参照)。nameargsをクォートする必要はない。

docが与えられたら、それはその関数のドキュメント文字列を指定する文字列であること(関数のドキュメント文字列を参照)。declareが与えられたら、それは関数のメタデータを指定するdeclareフォームであること(declareフォームを参照)。interactiveが与えられたら、それは関数が対話的に呼び出される方法を指定するinteractiveフォームであるこ(インタラクティブな呼び出しを参照)。

defunのリターン値は定義されていません。

以下にいくつか例を示す:

(defun foo () 5)
(foo)
     ⇒ 5

(defun bar (a &optional b &rest c)
    (list a b c))
(bar 1 2 3 4 5)
     ⇒ (1 2 (3 4 5))
(bar 1)
     ⇒ (1 nil nil)
(bar)
error→ Wrong number of arguments.

(defun capitalize-backwards ()
  "Upcase the last letter of the word at point."
  (interactive)
  (backward-word 1)
  (forward-word 1)
  (backward-char 1)
  (capitalize-word 1))

Emacsの関数のほとんどはLispプログラムのソースコードの一部であり、実行前にEmacs Lispリーダーがプログラムソースを読み込んだ際に定義される。しかし実行時にダイナミックに関数を定義することもできる(プログラムのコード実行時にdefun呼び出しを生成する)。関数の定義にジャンプするボタンを*Help*バッファーに表示するC-h fのようなEmacsのヘルプコマンドが、ソースコードを発見できないかもしれないので、これを行う際には注意を要する。なぜなら関数のダイナミックな生成は、defunにたいする通常の静的な呼び出しと比べて普通は非常に異なって見えるからである。このような関数を生成するコードを見つける作業を容易にするためにdefinition-nameプロパティを用いることができる。シンボルの標準的なプロパティを参照のこと。

意図せず既存の関数を再定義しないように注意されたい。defuncarのようなプリミティブ関数でさえ、問い合わせせずに躊躇なく再定義する。Emacsがこれを妨げることはない。なぜなら関数の再定義は故意に行われることがあり、そのような意図した再定義を、意図しない再定義と見分ける方法はがないからである。

Function: defalias name definition &optional doc

この関数は定義がdefinitionであるような関数としてシンボルnameを定義する。definitionには有効な任意のLisp関数、マクロ、スペシャルフォーム(スペシャルフォームを参照)、キーマップ(キーマップを参照)、ベクター、文字列(キーボードマクロ)を指定できる。defaliasのリターン値は未定義

docが非nilなら、それは関数nameのドキュメントとなる。それ以外ならdefinitionにより提供されるドキュメントが使用される。

内部的にはdefaliasは、通常は定義のセットにfsetを使用する。しかしnamedefalias-fset-functionプロパティをもつなら、fsetを呼び出すかわりにそれに割り当てられた値を使用する。

defaliasを使う正しい場所は、特定の関数やマクロの名前が正に定義される場所 — 特にソースファイルがロードされるときに明示的にその名前が出現する場所である。これはdefaliasdefunと同じように、どれが関数を定義するファイルなのか記録するからである(アンロードを参照)。

それとは対象的に他の目的のために関数を操作するプログラムでは、そのような記録を保持しないfsetを使用するほうがよいだろう。関数セルの内容へのアクセスを参照のこと。

Function: function-alias-p object &optional noerror

objectが関数のエイリアス(alias: 別名)かどうかをチェックする。エイリアスならその関数のエイリアスのチェーン(chain: 連鎖)を表すシンボルのリスト、エイリアスでなければnilをリターンする。たとえばabのエイリアスで、bcのエイリアスなら:

(function-alias-p 'a)
    ⇒ (b c)

定義中にループがあるとエラーをシグナルする。noerrorが非nilの場合には、ループしていないチェーン部分をリターンする。

defundefaliasで新たなプリミティブ関数を作成することはできませんが、任意の関数定義を変更するのに使用することができ、通常の定義がプリミティブであるcarx-popup-menuのような関数でさえ変更することができます。しかしこれは危険なことです。たとえばLispの完全性を損なうことなく、carを再定義するのはほとんど不可能だからです。それほど有名ではないx-popup-menuのような関数の再定義では、危険は減少しますが、それでも期待したとおりに機能しないかもしれません。Cコードにそのプリミティブの呼び出しがあれば、それは直接そのプリミティブのC定義を呼び出すので、シンボル定義を変更してもそれらに影響はありません。

defsubstも参照してください。これはdefunのように関数を定義して、それのインライン展開を処理するようLispコンパイラーに指示します。インライン関数Inliを参照してください。

関数名を未定義にするにはfmakunboundを使用します。関数セルの内容へのアクセスを参照してください。


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

13.5 関数の呼び出し

関数を定義しただけでは半分しか終わっていません。関数はそれを呼び出す(call) — たとえば実行(run)するまでは何も行いません。関数のcallはinvocationとしても知られています。

関数を呼び出すもっとも一般的な方法は、リストの評価によるものです。たとえばリスト(concat "a" "b")を評価することにより、関数concatが引数"a""b"で呼び出されます。評価については評価を参照してください。

プログラム内で式としてリストを記述するときは、プログラム内にテキストでどの関数を呼び出すか、いくつの引数を与えるかを指定します。通常はこれが行いたいことです。どの関数を呼び出すかを実行時に計算する必要がある場合もあります。これを行うには関数funcallを使用します。実行時にいくつの引数を渡すか決定する必要があるときはapplyを使用します。

Function: funcall function &rest arguments

funcallは関数functionを引数argumentsで呼び出して、functionがリターンした値をリターンする。

funcallは関数なので、functionを含むすべての引数はfuncallの呼び出し前に評価される。これは呼び出される関数を得るために任意の式を使用できることを意味している。またfuncallargumentsに記述した式ではなく、その値だけを見ることを意味している。これらの値はfunction呼び出し中では、2回目は評価されないfuncallの処理は関数の通常の呼び出し手続きと似ており、すでに評価された引数は評価されない。

引数functionはLisp関数かプリミティブ関数でなければならない。つまりスペシャルフォームやマクロは、未評価の引数式を与えられたときだけ意味があるので、指定することはできない。上述したように最初の場所でfuncallがそれらを知らないので、funcallがそれらを提供することはできない。

コマンドの呼び出しにfuncallを使用して、それがインタラクティブに呼び出されたように振る舞うようにする必要があるなら、funcall-interactivelyを使用すること(インタラクティブな呼び出しを参照)。

(setq f 'list)
     ⇒ list
(funcall f 'x 'y 'z)
     ⇒ (x y z)
(funcall f 'x 'y '(z))
     ⇒ (x y (z))
(funcall 'and t nil)
error→ Invalid function: #<subr and>

これらの例をapplyの例と比較されたい。

Function: apply function &rest arguments

applyは関数functionを引数argumentsで呼び出す。これはfuncallと同様だが1つ違いがある。argumentsの最後はオブジェクトのリストである。これは1つのリストではなく、個別の引数としてfunctionに渡される。わたしたちはこれを、applyがこのリストを展開(spread)(個々の要素が引数となるので)すると言う。

単一の引数でのapplyは特別である。引数(非空のリスト)の最初の要素は、残りの要素を個別の引数に関数として呼び出される。2つ以上の引数を渡すほうが早くなるだろう。

applyfunctionを呼び出した結果をリターンする。funcallと同様、functionはLisp関数かプリミティブ関数でなければならない。つまりスペシャルフォームやマクロはapplyでは意味をもたない。

(setq f 'list)
     ⇒ list
(apply f 'x 'y 'z)
error→ Wrong type argument: listp, z
(apply '+ 1 2 '(3 4))
     ⇒ 10
(apply '+ '(1 2 3 4))
     ⇒ 10

(apply 'append '((a b c) nil (x y z) nil))
     ⇒ (a b c x y z)

(apply '(+ 3 4))
     ⇒ 7

applyを使用した興味深い例はDefinition of mapcarを参照のこと。

ある関数にたいして、その関数のある引数を特定の値に固定して、他の引数は実際に呼びだされたときの値にできれば便利なことがあります。関数のいくつかの引数を固定することは、その関数の部分適用(partial application)と呼ばれます13。これの結果は残りの引数をとる新たな関数で、すべての引数を合わせて元の関数を呼び出します。

Emacs Lispで部分適用を行う方法を示します:

Function: apply-partially func &rest args

この関数は新たな関数をリターンする。この新しい関数は呼びだされたときにargs、および呼び出し時に指定された追加の引数から成る引数リストでfuncを呼び出す関数である。funcn個の引数を指定できる場合、m < n個の引数でapply-partiallyを呼び出すと、n - m個の新たな関数を生成する14

以下はビルトイン関数1+が存在しないものとして、apply-partiallyと他のビルトイン関数+を使用して1+を定義する例である15:

(defalias '1+ (apply-partially '+ 1)
  "Increment argument by one.")
(1+ 10)
     ⇒ 11

引数として関数を受け取ったり、データ構造(特にフック変数やプロパティリスト)から関数を探す関数はLispでは一般的で、それらはfuncallapplyを使用してそれらの関数を呼び出します。引数として関数をとる関数は、ファンクショナル(functional)と呼ばれるときもあります。

ファンクショナルを呼び出すとき、引数としてno-op関数(何も行わない関数)を指定できると便利なときがあります。以下に2つの異なるno-op関数を示します:

Function: identity argument

この関数はargumentをリターンする。副作用はない。

Function: ignore &rest arguments

この関数はすべてのargumentsを無視してnilをリターンする。

Function: always &rest arguments

この関数はすべてのargumentsを無視してtをリターンする。

関数のいくつかはユーザーに可視なコマンドで、これらは(通常はキーシーケンスを介して)対話的に呼び出すことができます。そのようなコマンドは、call-interactively関数を使用することにより、対話的に呼びだされたときと同様に呼び出すことができます。インタラクティブな呼び出しを参照してください。


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

13.6 関数のマッピング

マップ関数(mapping function)は与えられた関数(スペシャルフォームやマクロではない)をリストや他のコレクションの各要素に適用します。Emacs Lispにはそのような関数がいくつかあります。このセクションではリストにたいしてマッピングを行うmapcarmapcmapconcatmapcanを説明します。obarray内のシンボルにたいしてマッピングを行う関数mapatomsDefinition of mapatomsを参照してください。ハッシュテーブル内のkey/value関係にたいしてマッピングを行う関数maphashDefinition of maphashを参照してください。

これらのマップ関数は文字テーブル(char-table)には適用されません。なぜなら文字テーブルは非常に広い範囲の疎な配列だからです。疎な配列であるという性質に適う方法で文字テーブルにマッピングするには、関数map-char-tableを使用します(文字テーブルを参照)。

Function: mapcar function sequence

mapcarは関数functionsequenceの各要素にたいして順番に適用して、その結果をリストでリターンする。

引数sequenceには、文字テーブルを除く任意の種類のシーケンス — つまりリスト、ベクター、ブールベクター、文字列を指定できる。結果は常にリストになる。結果の長さはsequenceの長さと同じ。たとえば:

(mapcar #'car '((a b) (c d) (e f)))
     ⇒ (a c e)
(mapcar #'1+ [1 2 3])
     ⇒ (2 3 4)
(mapcar #'string "abc")
     ⇒ ("a" "b" "c")

;; my-hooks内の各関数を呼び出す
(mapcar 'funcall my-hooks)

(defun mapcar* (function &rest args)
  "Apply FUNCTION to successive cars of all ARGS.
Return the list of results."
  ;; リストが消費されていなければ
  (if (not (memq nil args))
      ;; CARに関数を適用する
      (cons (apply function (mapcar #'car args))
            (apply #'mapcar* function
                   ;; 残りの要素のための再帰
                   (mapcar 'cdr args)))))

(mapcar* #'cons '(a b c) '(1 2 3 4))
     ⇒ ((a . 1) (b . 2) (c . 3))
Function: mapcan function sequence

この関数はmapcarのようにsequenceの各要素にfunctionを適用するが、結果をリストに収集するかわりに結果を変更(nconcを使用。see リストを再配置する関数を参照)して結果のすべての要素を単一のリストでリターンする。mapcarと同様にsequenceには文字テーブルを除く任意のタイプのシーケンスを指定できる。

;; 以下と:
(mapcar #'list '(a b c d))
     ⇒ ((a) (b) (c) (d))
;; 以下を比較してみよ:
(mapcan #'list '(a b c d))
     ⇒ (a b c d)
Function: mapc function sequence

mapcmapcarと似ているが、functionは副作用のためだけに使用される — つまりfunctionがリターンする値は無視されてリストに収集されない。mapcは常にsequenceをリターンする。

Function: mapconcat function sequence &optional separator

mapconcatsequenceのそれぞれの要素にfunctionを適用する。結果は文字のシーケンス(文字列、ベクター、リスト)でなければならず、単一の文字列に結合されてリターン値となる。mapconcatは結果シーケーンスの各ペアの間にseparatorの文字を挿入する。これも文字列、または文字のベクターかリストでなければならない。nil値は空文字列として扱われる。シーケンス、配列、ベクターを参照のこと。

引数functionは1つの引数を受け取り文字のシーケンス、すなわち文字列、ベクター、リストのいずれかをリターンする。引数sequenceは文字テーブル以外の任意の種類のシーケンス、すなわちリスト、ベクター、ブールベクター、または文字列を指定できる。

(mapconcat #'symbol-name
           '(The cat in the hat)
           " ")
     ⇒ "The cat in the hat"

(mapconcat (lambda (x) (format "%c" (1+ x)))
           "HAL-8000")
     ⇒ "IBM.9111"

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

13.7 無名関数

関数は通常はdefunにより定義されて、同時に名前が与えられますが、明示的にラムダ式を使う — 無名関数(anonymous function)のほうが便利なときもあります。無名関数は名前つき関数が有効な場所ならどこでも有効です。無名関数は変数や関数の引数に割り当てられることがよくあります。たとえばある関数をリストの各要素に適用するmapcarfunction引数に渡すかもしれません(関数のマッピングを参照)。現実的な例はdescribe-symbols exampleを参照してください。

無名関数として使用するためのラムダ式を定義するとき、原則的にはリストを構築する任意の手法を使用できます。しかし通常はマクロlambda、スペシャルフォームfunction、または入力構文#'を使用するべきです。

Macro: lambda args [doc] [interactive] body…

このマクロは引数リストargs、(もしあれば)ドキュメント文字列doc、(もしあれば)インタラクティブ指定interactive、およびbodyで与えられるbodyフォームをもつ無名関数をリターンする。

ダイナミックバインディングの下では、このマクロはlambdaフォームを効果的に“自己クォート(self-quoting)”する。つまりCARlambdaであるようなフォームはフォーム自身を得る。

(lambda (x) (* x x))
     ⇒ (lambda (x) (* x x))

レキシカルバインディングの下で評価した際には、結果はクロージャオブジェクトになることに注意(クロージャを参照)。

lambdaフォームは別の1つの効果をもつ。このマクロはfunction(以下参照)をサブルーチンとして使用することにより、Emacs評価機能(Emacs evaluator)とバイトコンパイラーに、その引数が関数であることを告げる。

Special Form: function function-object

このスペシャルフォームは評価を行わずにfunction-objectをリターンする。この点ではquote(クォートを参照)と似ている。しかしquoteとは異なり、Emacs評価機能とバイトコンパイラーに、これを関数として使用する意図を告げる役割をもつ。function-objectが有効なラムダ式と仮定すると、これは2つの効果をもつ:

  • そのコードがバイトコンパイルされているとき、function-objectはバイトコード関数オブジェクトにコンパイルされる(バイトコンパイルを参照)。
  • レキシカルバインドが有効ならfunction-objectはクロージャに変換される。クロージャを参照のこと。

function-objectがシンボルかつバイトコンパイル済みコードの場合には、その関数が未定義、あるいは実行時に認識されていなければバイトコンパイラーは警告を発する。

入力構文#'functionの使用の略記です。以下のフォームは等価です:

(lambda (x) (* x x))
(function (lambda (x) (* x x)))
#'(lambda (x) (* x x))

以下の例では3つ目の引数に関数をとるchange-property関数を定義して、その後のchange-propertyで無名関数を渡してこれを使用しています:

(defun change-property (symbol prop function)
  (let ((value (get symbol prop)))
    (put symbol prop (funcall function value))))

(defun double-property (symbol prop)
  (change-property symbol prop (lambda (x) (* 2 x))))

lambdaフォームをクォートしていないことに注意してください。

上記のコードをコンパイルすると無名関数もコンパイルされます。リストをクォートすることにより無名関数を構築した場合にはコンパイルはされません。

(defun double-property (symbol prop)
  (change-property symbol prop '(lambda (x) (* 2 x))))

この場合、無名関数はコンパイルされたコード内のラムダ式に保持されます。バイトコンパイラーはchange-propertyが関数としての使用を意図していることを知ることができないので、たとえこの関数が関数のように見えるとしても、このリストが関数であると決め込むことができません。


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

13.8 ジェネリック関数

defunを使用して定義された関数は、その引数の型と期待する値に関して、ハードコードされた一連の仮定をもちます。たとえば数字か数字のリストを引数値として処理するようにデザインされた関数は、ベクターや文字列のような他の型の値で呼び出されると失敗したりエラーをシグナルするでしょう。これはその関数実装が、デザイン時に想定した以外の型に対応しないために発生します。

対照的に多相型関数(polymorphic functions)を使用したオブジェクト指向プログラムでは、同一の名前をもつ一連の特化した関数のそれぞれが、特定の引数型セットにたいして記述されます。どの関数が実際に呼び出されるかは、実際の引数の型にもとづいて実行時に決定されます。

Emacsはポリモーフィズム(polymorphism)にたいするサポートを提供します。他のLisp環境、特にCommon LispとCommon Lispオブジェクトシステム(CLOS)と同じように、このサポートはジェネリック関数(generic functions)を基礎としています。Emacsのジェネリック関数は同一名の使用を含むCLOSに密接にしたがっているので、CLOSの経験があればこのセクションの残りの部分は非常に身近に感じるでしょう。

ジェネリック関数は、その名前と引数のリストを指定して、(通常は)実装されていない抽象操作(abstract operation)を指定します。引数のいくつかの固有クラスにたいする実際の実装はメソッド(methods)により提供され、これは個別に定義されるべきです。ジェネリック関数を実装するそれぞれのメソッドはジェネリック関数としてとして同じ名前をもちますが、そのジェネリック関数で定義された引数のスペシャライジング(specializing)により、メソッドの定義はどの種類の引数を処理可能かを示します。これらの引数スペシャライザー(argument specializers)は多少の差はあれ特化したものにできます。たとえばstring型はsequenceのようなより一般的な型より特化した型です。

C++やSimulaのようなメッセージベースのOO言語と異なり、ジェネリック関数を実装するメソッドはクラスに属さずに、それらが実装するジェネリック関数に属することに注意してください。

ジェネリック関数が呼び出されると、呼び出し側に渡された実際の引数と各メソッドの引数スペシャライザーを比較することにより、適用可能なメソッドを呼び出します。その呼び出しの実際の引数がメソッドのスペシャライザーと互換性があれば、そのメソッドが適用可能です。複数のメソッドが適用可能ならば、それらは以下で説明する特定のルールにより合成されて、その組み合わせが呼び出しを処理します。

Macro: cl-defgeneric name arguments [documentation] [options-and-methods…] &rest body

このマクロは指定したnameargumentsでジェネリック関数を定義する。bodyが与えられたなら、それは実装のデフォルトを与える。(常に与えられるべきであるが)documentationが与えられたなら、それは(:documentation docstring)の形式でそのジェネリック関数のドキュメント文字列を指定する。オプションのoptions-and-methodsは以下のフォームのいずれかを指定できる:

(declare declarations)

declareフォームで説明するようなdeclareフォーム。

(:argument-precedence-order &rest args)

このフォームは適用可能なメソッド合成にたいするソート順に影響を与える。合成において2つのメソッドを比較する際、メソッドの引数は通常は左から右に試験されて、引数スペシャライザーがより特化した最初のメソッドが他のメソッドより前になる。このフォームで定義された順序はそれをオーバーライドして、左から右ではなくこのフォームの順に応じて試験される。

(:method [qualifiers…] args &rest body)

このメソッドはcl-defmethodが行うようなメソッドを定義する。

Macro: cl-defmethod name [extra] [qualifier] arguments [&context (expr spec)…] &rest [docstring] body

このマクロはnameと呼ばれるジェネリック関数の、特定の実装を定義する。実装コードはbodyで与えられる。もし与えられたらdocstringはそのメソッドのドキュメント文字列である。リストargumentsはジェネリック関数を実装するすべてのメソッドで等しく、その関数の引数リストとマッチしなければならず、(arg spec)という形式の引数スペシャライザーを提供する。ここでargcl-defgeneric呼び出しで指定された引数名、specは以下のスペシャライザーフォームのいずれかであること:

type

このスペシャライザーは、引数がtypeのいずれかであることを要求する。typeは以下で説明する型ヒエラルキーのいずれかの型である。

(eql object)

このスペシャライザーは、引数がobjecteqlであることを要求する。

(head object)

引数はcarobjecteqlであるようなコンスセルでなければならない。

struct-type

引数はcl-defstruct (Structures in Common Lisp Extensions for GNU Emacs Lispを参照)で定義されたstruct-typeという名前のクラス、またはその子クラスのインスタンスでなければならない。

メソッド定義は新たな引数リストのキーワード&contextを使用できる。これはメソッド実行時に環境をテストする余分なスペシャライザーを導入する。このキーワードは必須の引数リストの後、かつすべての&rest&optionalキーワードの前に記述すること。&contextスペシャライザーは正規の引数スペシャライザー(expr spec)と非常によく似ているが、exprはカレントコンテキストで評価される式であり、specは比較対象となる値となる。たとえば&context (overwrite-mode (eql t))は、メソッドをoverwrite-modeがオンのとだけ適用可能にする。&contextキーワードの後には任意個数のコンテキストスペシャライザーを続けることができる。コンテキストスペシャライザーはジェネリック関数の引数signatureの一部ではないので、これらを必要としないメソッドでは省略できる。

型スペシャライザー(arg type)は以下のリストのシステム型(system types)のいずれかを指定できる。親の型が指定されたときは、型がより特化した子型、孫型、曾孫型、...のいずれかであるような任意の引数も互換となるだろう。

integer

親型: number

number
null

親型: symbol

symbol
string

親型: array

array

親型: sequence

cons

親型: list

list

親型: sequence

marker
overlay
float

親型: number

window-configuration
process
window
subr
compiled-function
buffer
char-table

親型: array

bool-vector

親型: array

vector

親型: array

frame
hash-table
font-spec
font-entity
font-object

として表されるオプション要素extraによって、同一のspecializerとqualifierにたいして、stringで区別されるメソッドを追加できる。

オプションのqualifierは複数の適用可能なメソッドの合成を許容する。与えられなければ定義されるメソッドはprimary(主)メソッドとなり、スペシャライズされた引数にたいする主要な実装の提供に責任を有する。qualifierとして以下の値のいずれかを使用してauxiliary(副)メソッドも定義できる:

:before

このauxiliaryメソッドはprimaryメソッドの前に実行される。より正確にはすべての:beforeメソッドは、より特化したメソッドが最初になる順で、primaryメソッドの前に実行される。

:after

このauxiliaryメソッドはprimaryメソッドの後に実行される。より正確にはすべてのこの類のメソッドは、より特化したメソッドが最後になる順で、primaryメソッドの後に実行される。

:around

このauxiliaryメソッドはprimaryメソッドの代替えとして実行される。この類のメソッドでもっとも特化したものが他のメソッドより前に実行される。このようなメソッドは他のauxiliaryメソッドやprimaryメソッドを呼び出すために、通常は以下で説明するcl-call-next-methodを使用する。

cl-defmethodを使用して定義した関数をインタラクティブにすることはできない。つまりinteractiveフォームを追加してコマンドにすることはできない(コマンドの定義を参照)。多相型コマンド(polymorphic command)が必要なら、cl-defgenericcl-defmethodを通じて定義した多相型関数(polymorphic function)を呼び出す通常のコマンドを定義することを推奨する。

ジェネリック関数が呼び出されると、毎回その関数にたいして定義された適用可能なメソッドを合成することによってその呼び出しを処理するeffectiveメソッド(effective method)を構築します。適用可能なメソッドを探してeffectiveメソッドを生成するプロセスはdispatchと呼ばれます。その呼び出しの実際の引数と互換性があるスペシャライザーをもつすべてのメソッドが、互換性のあるメソッドです。すべての引数がスペシャライザーと互換でなければならないので、それらはすべてメソッドが適用可能かどうか判定します。複数の引数に明示的に特化したメソッドをmultiple-dispatchメソッド(multiple-dispatch methods)と呼びます。

適用可能なメソッドはそれらが合成される順にソートされます。最左の引数スペシャライザーがもっとも特化したものであるようなメソッドが、順序の最初になります(上述したようにcl-defmethodの一部として:argument-precedence-orderを指定することによりこれをオーバーライドできる)。そのメソッドのbodyがcl-call-next-methodを呼び出すと、もっとも特化した次のメソッドが実行されます。適用可能な:aroundメソッドがあれば、それらのうちもっとも特化したメソッドが実行されます。そのメソッドはより特化していない任意の:aroundメソッドを実行するために、cl-call-next-methodを呼び出すべきです。次に:beforeメソッドがその特化した順に、その後にspecificityメソッドが実行されます。そして後に:afterメソッドがその特化した順と逆順で実行されます。

Function: cl-call-next-method &rest args

primaryメソッドか:around auxiliaryメソッド内のレキシカルbody内で呼び出されると、同じジェネリック関数にたいして適用可能な次のメソッドを呼び出す。通常これは引数なしで呼び出され、これは次の適用可能なメソッドを呼び出すメソッドが、呼び出されたときと同じ引数で次のメソッドを呼び出すことを意味する。それ以外ならかわりに指定された引数が使用される。

Function: cl-next-method-p

primaryメソッドか:around auxiliaryメソッドのレキシカルbody内からこの関数を呼び出したときは、呼び出す次のメソッドが存在すれば非nilをリターンする。


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

13.9 関数セルの内容へのアクセス

シンボルの関数定義(function definition)とは、そのシンボルの関数セルに格納されたオブジェクトのことです。ここではシンボルの関数セルへのアクセスやテスト、それをセットする関数を説明します。

Definition of indirect-functionの関数indirect-functionも参照してください。

Function: symbol-function symbol

これはsymbolの関数セル内のオブジェクトをリターンする。これはリターンされたオブジェクトが本物のの関数であるかチェックしない。

関数セルがvoidならリターン値はnil。関数セルがvoidのときとnilがセットされているときを区別するにはfboundp(以下参照)を使用する。

(defun bar (n) (+ n 2))
(symbol-function 'bar)
     ⇒ (lambda (n) (+ n 2))
(fset 'baz 'bar)
     ⇒ bar
(symbol-function 'baz)
     ⇒ bar

シンボルに何の関数定義も与えていなければ、そのシンボルの関数セルはvoidだと言います。言い換えると、その関数セルはどんなLispオブジェクトも保持しません。そのシンボルを関数として呼びだそうとすると、Emacsはvoid-functionエラーをシグナルします。

voidはnilやシンボルvoidとは異なることに注意してください。シンボルnilvoidはLispオブジェクトであり、他のオブジェクトと同じように関数セルに格納することができます(defunで定義すればvoidは有効な関数足り得る)。voidであるような関数セルは、どのようなオブジェクトも含んでいません。

fboundpを使用して任意のシンボルの関数定義がvoidかどうかテストすることができます。シンボルに関数定義を与えた後は、fmakunboundを使用して再びvoidにすることができます。

Function: fboundp symbol

この関数はそのシンボルが関数セルにオブジェクトをもっていればt、それ以外はnilをリターンする。これはそのオブジェクトが本物の関数であるかチェックしない。

Function: fmakunbound symbol

この関数はsymbolの関数セルをvoidにする。そのためこれ以降に関数セルへのアクセスを試みると、void-functionエラーが発生する。これはsymbolをリターンします(変数がvoidのときmakunboundも参照)。

(defun foo (x) x)
(foo 1)
     ⇒1
(fmakunbound 'foo)
     ⇒ foo
(foo 1)
error→ Symbol's function definition is void: foo
Function: fset symbol definition

この関数はsymbolの関数セルにdefinitionを格納する。結果はdefinitiondefinitionは通常は関数か関数の名前であるべきだが、これはチェックされない。引数symbolは通常のどおり評価される引数である。

この関数は主に関数を定義したり変更して構築を行う、defunadvice-addのようなものからサブルーチンとして使用される。たとえばキーボードマクロ(キーボードマクロを参照)のような、関数ではない関数定義をシンボルに与えるためにも使用することができる:

;; 名前つきのキーボードマクロを定義する。
(fset 'kill-two-lines "\^u2\^k")
     ⇒ "\^u2\^k"

関数にたいして別の名前を作成するためにfsetを使いたいなら、かわりにdefaliasの使用を考慮すること。Definition of defaliasを参照。


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

13.10 クロージャ

変数のバインディングのスコーピングルールで説明したように、Emacsはオプションで変数のレキシカルバインディングを有効にできます。レキシカルバインディングが有効な場合は、(たとえばdefunなどで)作成したすべての名前つき関数、同様にlambdaマクロやfunctionスペシャルフォーム、#'構文を使用して作成したすべての無名関数(無名関数を参照)が、自動的にクロージャ(closure)に変換されます。

クロージャとはその関数が定義されたどときに存在したレキシカル環境の記録をあわせもつ関数です。クロージャが呼び出されたとき、定義内のレキシカル変数の参照には、その保持されたレキシカル環境が使用されます。他のすべての点では、クロージャは通常の関数と同様に振る舞います。特にクロージャは通常の関数と同じ方法で呼び出すことができます。

クロージャを使用する例はレキシカルバインディングを参照してください。

現在のところEmacs Lispのクロージャオブジェクトは、1つ目の要素にシンボルclosureをもつリストとして表現されます。そのリストは2つ目の要素としてレキシカル環境、残りの要素で引数リストとbodyフォームを表します:

;; レキシカルバインディングが有効
(lambda (x) (* x x))
     ⇒ (closure (t) (x) (* x x))

しかし実際にはクロージャの内部構造は、内部的な実装の詳細と判断される残りのLisp界を晒け出すものだと言えます。この理由により、クロージャオブジェクトの構造を直接調べたり変更することは推奨しません。


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

13.11 オープンクロージャ

関数とは伝統的には呼び出し以外の機能を提供しない不透明なオブジェクトです。(Emacs Lisp関数はdoc文字列や引数リスト、interactive仕様のようないくつかの情報を抽出できるので完全に不透明という訳ではないが、そのほとんどは依然として不透明である)。これはわたしたちの要望を通常は満たしていますが、関数自体に関する情報をもう少し公開する必要がある場合もあるでしょう。

オープンクロージャ(Open closure)、略してOClosureは追加のタイプ情報をもった関数オブジェクトであり、アクセッサ関数を通じてアクセス可能なスロット形式で自身の情報の一部を公開します。

OClosureは2つのステップから定義されます。まずoclosure-defineを使ってそのタイプのOClosuresがもつスロットを指定することにより新たなOClosureタイプを定義します。それからoclosure-lambdaを使用して与えられたタイプのOClosureオブジェクトを作成するのです。

たとえばキーボードマクロ、すなわちキーイベントのシーケンスを再実行するインタラクティブな関数を定義したいとします(キーボードマクロを参照)。これは以下のような普通の関数で行うことができます:

(defun kbd-macro (key-sequence)
  (lambda (&optional arg)
    (interactive "P")
    (execute-kbd-macro key-sequence arg)))

しかしこのような定義では関数からkey-sequenceを抽出して、たとえばプリントするといったようなことを簡単に行う方法はありません。

この問題は以下のようなOClosureを使えば解決できます。まずはキーボードマクロのタイプを定義します(ついでにcounterスロットを追加することにします):

(oclosure-define kbd-macro
  "Keyboard macro."
  keys (counter :mutable t))

その後にkbd-macro関数の定義を書き換えることができます:

(defun kbd-macro (key-sequence)
  (oclosure-lambda (kbd-macro (keys key-sequence) (counter 0))
      (&optional arg)
    (interactive "P")
    (execute-kbd-macro keys arg)
    (setq counter (1+ counter))))

ご覧のとおり、このOClosureのスロットkeyscounterには、OClosureのbodyからローカル変数としてアクセスすることができます。しかしOClosureのbody外部からもアクセスできるようになったのです。たとえばキーボードマクロをdescribeする関数は:

(defun describe-kbd-macro (km)
  (if (not (eq 'kbd-macro (oclosure-type km)))
      (message "Not a keyboard macro")
    (let ((keys    (kbd-macro--keys km))
          (counter (kbd-macro--counter km)))
      (message "Keys=%S, called %d times" keys counter))))

ここでkbd-macro--keyskbd-macro--counterはタイプがkbd-macroであるようなoclosureのために、oclosure-defineマクロによって生成されたアクセッサ関数です。

Macro: oclosure-define oname &optional docstring &rest slots

このマクロはslotsのアクセッサ関数とともに、新たなOClosureタイプを定義する。onameはシンボル(新たなタイプの名前)、または(oname . type-props)という形式のリスト。この場合のtype-propsはこのoclosureタイプの追加プロパティのリストである。slotsはスロットを記述するリストであり、スロットはそれぞれシンボル(スロットの名前)、または(slot-name . slot-props)という形式を指定できる。ここでslot-propsは対応するスロットslot-nameのプロパティリストである。type-propsで指定するOClosureタイプのプロパティには以下を含めることができる:

(:predicate pred-name)

pred-nameという名前の述語関数の作成をリクエストする。その関数はタイプonameのOClosureの識別に使用される。このタイプのプロパティが未指定なら、oclosure-defineはその述語にたいするデフォルト名を生成する。

(:parent otype)

タイプotypeのOClosureをタイプonameの親にする。タイプonameのOClosureは親タイプで定義されたslotsを継承する。

(:copier copier-name copier-args)

copierと呼ばれる機能更新関数を定義する。1つ目の引数にタイプonameのOClosureを受け取り、copier-argsという名前のスロット(copier-nameの実際の呼び出し時には対応するはそれぞれ引数に渡された値が含まれるように変更される)をもつコピーをリターンする。

oclosure-defineマクロがslots内のスロットそれぞれにたいして、oname--slot-nameという名前で、スロットの値へのアクセスに使用できるアクセッサ関数を定義する。slotsでのそれぞれのスロットの定義では、以下のスロットのプロパティを指定できる:

:mutable val

デフォルトではスロットはimmutable(変更不可、不変)だが、:mutableプロパティに非nilを指定すれば、たとえばsetf (setfマクロを参照)でスロットを変更できるようにmutable(変更可能)になる。

:type val-type

そのスロットに期待される値のタイプを指定する。

Macro: oclosure-lambda (type . slots) arglist &rest body

このマクロはタイプtypeの無名OClosureを作成する。typeoclosure-defineによって定義されていること。slots(slot-name expr)という形式の要素からなるリスト。実行時にはexprが順に評価された後に、その結果の値によってスロットが初期化されたOClosureが作成される。

関数として呼び出された場合には(関数の呼び出しを参照)、このマクロによって作成されたOClosureはarglistに応じた引数を受け取り、bodyのコードを実行する。bodyからはあたかも静的スコープにキャプチャされたローカル変数のように任意のスロットの値を直接参照できる。

Function: oclosure-type object

この関数はobjectがOClosureであればそのOClosureタイプ(シンボル)そうでなければnilをリターンする。

他にもOClosureに関連する関数としてoclosure-interactive-formがあります。これは一部のOClosureタイプにたいしてダイナミックなinteractiveフォームの算出を可能にする関数です。oclosure-interactive-formを参照してください。


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

13.12 Emacs Lisp関数にたいするアドバイス

他のライブラリーの関数定義を変更する必要があるとき、およびfoo-functionoのようなフックやプロセスフィルター(process filter)や、関数を値としてもつ任意の変数やオブジェクトを変更する必要があるときには、名前つきの関数にはfsetdefun、フック変数にはsetq、プロセスフィルターにはset-process-filterのように、適切なセッター関数(setter function)を使用することができます。しかしこれらが以前の値を完全に破棄してしまうのが好ましくない場合もあります。

アドバイス(advice)機能によって関数にアドバイスすることにより、既存の関数定義に機能を追加できます。これは関数全体を再定義するより明解な手法です。

Emacsのアドバイスシステムは2つのプリミティブセットを提供します。コアとなるセットは変数やオブジェクトのフィールドに保持された関数値にたいするものです(対応するプリミティブはadd-functionremove-function)。もう1つのセットは名前つき関数の最上位のレイヤーとなるものです(主要なプリミティブはadvice-addadvice-remove)。

簡単な例として、以下は関数の呼び出し時に毎回リターン値を変更するアドバイスを追加する方法です:

(defun my-double (x)
  (* x 2))
(defun my-increase (x)
  (+ x 1))
(advice-add 'my-double :filter-return #'my-increase)

このアドバイスの追加後に‘3’でmy-doubleを呼び出すとリターン値は‘7’になるでしょう。このアドバイスを削除するには、以下のようにします

(advice-remove 'my-double #'my-increase)

より高度な例として、以下はプロセスprocのプロセスフィルターの呼び出しをトレースする例です:

(defun my-tracing-function (proc string)
  (message "Proc %S received %S" proc string))

(add-function :before (process-filter proc) #'my-tracing-function)

これによりそのプロセスの出力は元のプロセスフィルターに渡される前に、my-tracing-functionに渡されるようになります。my-tracing-functionは元の関数と同じ引数を受け取ります。これを行えば以下のようにしてトレースを行う前の振る舞いにリバートすることができます。

(remove-function (process-filter proc) #'my-tracing-function)

同様にdisplay-bufferという名前つきの関数の実行をトレースしたいなら以下を使用できます:

(defun his-tracing-function (orig-fun &rest args)
  (message "display-buffer called with args %S" args)
  (let ((res (apply orig-fun args)))
    (message "display-buffer returned %S" res)
    res))

(advice-add 'display-buffer :around #'his-tracing-function)

ここでhis-tracing-functionは元の関数のかわりに呼び出されて、元の関数(に加えてその関数の引数)を引数として受け取るので、必要な場合はそれを呼び出すことができます。出力を確認し終えたら、以下のようにしてトレースを行う前の振る舞いにリバートできます:

(advice-remove 'display-buffer #'his-tracing-function)

上記の例で使用されている引数:before:aroundは、2つの関数が構成される方法を指定します(これを行う多くの方法があるから)。追加された関数もアドバイス(advice)と呼ばれます。


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

13.12.1 アドバイスを操作するためのプリミティブ

Macro: add-function where place function &optional props

このマクロはplace(ジェネリック変数を参照)に格納された関数に、アドバイスfunctionを追加する手軽な方法である。

whereは既存の関数のどこ — たとえば元の関数の前や後 — にfunctionが構成されるかを決定する。2つの関数を構成するために利用可能な方法のリストは、アドバイスの構築方法を参照のこと。

(通常は名前が-functionで終わる)変数を変更するときには、functionがグローバルに使用されるか、あるいはカレントバッファーだけに使用されるか選ぶことができる。placeが単にシンボルならfunctionplaceのグローバル値に追加される。place(local symbol)というフォームなら、symbolはその変数の名前をリターンする式なので、functionはカレントバッファーだけに追加される。最後にレキシカル変数を変更したければ、(var variable)を使用する必要があるだろう。

add-functionで追加されたすべての関数は、自動的にプロパティpropsの連想リストに加えることができる。現在のところ特別な意味をもつのは以下の2つのプロパティのみ:

name

これはアドバイスの名前を与える。この名前はremove-functionが取り除く関数を識別するのに使用できます。これは通常はfunctionが無名関数のときに使用されます。

depth

これは複数のアドバイスが与えられたときにアドバイスを順番づける方法を指定します。depthのデフォルト0です。depthが100のときにはアドバイスが可能な限りの深さを保持すべきことを、-100のときは最外のアドバイスに留めることを意味します。同じdepthで2つのアドバイスが指定された場合には、もっとも最近に追加されたアドバイスが最外になります。

:beforeアドバイスにたいしては、最外(outermost)になるということは、このアドバイスが他のすべてのアドバイスの前、つまり1番目に実行されることを意味し、最内(innermost)とは元の関数が実行される直前、すなわちこのアドバイスと元の関数の間に実行されるアドバイスは存在しないことを意味する。同様に:afterアドバイスにたいしては、最内とは元の関数の直後、つまりこの元の関数とアドバイスの間に実行される他のアドバイスは存在せず、最外とは他のすべてのアドバイスが実行された直後にこのアドバイスが実行されることを意味する。:overrideの最内アドバイスは、元の関数だけをオーバーライドし、他のアドバイスはそれに適用されるが、:overrideの最外アドバイスは元の関数だけではなく、その他すべての適用済みのアドバイスをも同様にオーバーライドする。

functionがインタラクティブでなければ合成された関数は、(もしあれば)元の関数のインタラクティブ仕様(interactive spec)を継承します。それ以外なら合成された関数はインタラクティブとなりfunctionのインタラクティブ仕様を使用します。1つ例外があります。functionのインタラクティブ仕様が関数(式や文字列ではないlambda式やfboundシンボル)なら、合成される関数のインタラクティブ仕様は、元の関数のインタラクティブ仕様を唯一の引数とする、その関数の呼び出しとなります。引数として受け取ったインタラクティブ仕様を解釈するためにはadvice-eval-interactive-specを使用します。

注意: functionのインタラクティブ指定は結合された関数に適用されるべきであり、functionではなく結合された関数の呼び出し規約にしたがうこと。これらは多くの場合には等しいので差異は生じないが、placeに格納されたオリジナルの関数とは異なる引数を受け取るfunctionでは:around:filter-args:filter-returnでは重要になる。

Macro: remove-function place function

このマクロはplaceに格納された関数からfunctionを取り除く。これはadd-functionを使用してfunctionplaceに追加されたときだけ機能する。

functionplaceに追加された関数にたいして、ラムダ式にたいしても機能するようにequalを使用して比較を試みる。これは追加でplaceに追加された関数のnameプロパティも比較する。これはequalを使用してラムダ式を比較するより信頼性がある。

Function: advice-function-member-p advice function-def

adviceがすでにfunction-def内にあれば非nilをリターンする。上記のremove-functionと同様、実際の関数adviceのかわりにアドバイスのnameも使用できる。

Function: advice-function-mapc f function-def

function-defに追加されたすべてのアドバイスにたいして、関数fを呼び出す。fは2つの引数 — アドバイス関数とそれのプロパティで呼びだされる。

Function: advice-eval-interactive-spec spec

そのようなインタラクティブ仕様で関数がインタラクティブに呼び出されたようにspecを評価して、構築された引数のリストに対応するリストをリターンする。たとえば(advice-eval-interactive-spec "r\nP")はリージョンの境界、カレントプレフィクス引数を含む、3つの要素からなるリストをリターンする。

たとえばC-x m (compose-mail)コマンドに‘From:’ヘッダーの入力を求めるさせるようにするには、以下のようにすればよい:

(defun my-compose-mail-advice (orig &rest args)
  "Read From: address interactively."
  (interactive
   (lambda (spec)
     (let* ((user-mail-address
             (completing-read "From: "
                              '("one.address@example.net"
                                "alternative.address@example.net")))
            (from (message-make-from user-full-name
                                     user-mail-address))
            (spec (advice-eval-interactive-spec spec)))
       ;; Put the From header into the OTHER-HEADERS argument.
       (push (cons 'From from) (nth 2 spec))
       spec)))
  (apply orig args))

(advice-add 'compose-mail :around #'my-compose-mail-advice)

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

13.12.2 名前つき関数にたいするアドバイス

アドバイスは名前つき関数やマクロにたいして使用するのが一般的な使い方です。これは単にadd-functionを使用して以下のように行うことができます:

(add-function :around (symbol-function 'fun) #'his-tracing-function)

しかしかわりにadvice-addadvice-removeを使うべきです。この異なる関数セットは名前つき関数に適用されるアドバイスを操作するためのもので、add-functionと比較して以下の追加機能があります。まずこれらはマクロとオートロードされた関数を扱う方法を知っています。次にdescribe-functionにたいして追加されたアドバイスと同様に、元のドキュメント文字列を維持します。さらに関数が定義される前でも、アドバイスの追加と削除ができます。

既存の関数全体を再定義せずに既存の呼び出しを変更するために、advice-addが有用になります。しかしその関数の既存の呼び出し元は古い振る舞いを前提としているかもしれず、アドバイスによりその振る舞いが変更されたときに正しく機能しないかもしれないので、これはソー内スのバグにもなり得ます。アドバイスはデバッグを難しくする可能性もあります。デバッグを行う人はその関数がアドバイスにより変更されたことに気づかなかったり、失念しているかもしれません。

これらの理由により、他の方法で関数の振る舞いを変更できない場合に備えるために、アドバイスの使用は控えるべきです。フックを通じて同じことが行えるならフック(フックを参照)の使用が望ましい方法です。特定のキーが行う何かを変更したいだけなら、新しいコマンドを記述して、古いコマンドのキーバインドを新しいコマンドにリマップ(コマンドのリマップを参照)するのが、おそらくより優れた方法です。

他の人が使用するリリース用のコードを記述する場合には、アドバイスを含めることを避けるよう試みてください。アドバイスしたい関数にその処理を行うフックがなければ、適切なフックの追加についてEmacs開発者に相談してください。特にEmacs自身のソースファイルでは、Emacs関数にアドバイスを配置するべきではありません(現在のところこの慣習にたいするいくつかの例外があるが修正する予定)。一般的にはfooにアドバイスとしてbarを配置するよりも、foo内に新たなフックを作成してbarにそのフックを使用させるほうが明快です。

スペシャルフォーム(スペシャルフォームを参照)はアドバイスできませんが、マクロは関数と同じ方法でアドバイスできます。もちろんこれはすでにマクロ展開されたコードには影響しないため、マクロ展開前にアドバイスが確実にインストールされる必要があります。

プリミティブ(関数とは?を参照)にアドバイスするのは可能ですが、2つの理由により通常は行うべきではありません。1つ目の理由はいくつかのプリミティブがアドバイスのメカニズム内で使用されているため、それらにたいしてアドバイスを行うと無限再帰が発生するからです。2つ目の理由は多くのプリミティブがCから直接呼び出されていて、そのような呼び出しはアドバイスを無視するからです。したがってプリミティブにたいしてアドバイスの使用を控えることにより、ある呼び出しはアドバイスにしたがい(Lispコードから呼びだされたため)、他の呼び出しではアドバイスにしたがわない(Cコードから呼び出されたため)という混乱した状況を解決できます。

Macro: define-advice symbol (where lambda-list &optional name depth) &rest body

このマクロはアドバイスを定義してsymbolという名前の関数に追加する。namenilsymbol@nameという名前の関数ならアドバイスは無名関数。他の引数についての説明はadvice-addを参照のこと。

Function: advice-add symbol where function &optional props

名前つき関数symbolにアドバイスfunctionを追加する。wherepropsadd-function(アドバイスを操作するためのプリミティブを参照)のときと同じ意味をもつ。

Function: advice-remove symbol function

名前つき関数symbolからアドバイスfunctionを取り除く。functionにアドバイスのnameを指定することもできる。

Function: advice-member-p function symbol

名前つき関数symbol内にすでにアドバイスfunctionがあれば非nilをリターンする。functionにアドバイスのnameを指定することもできる。

Function: advice-mapc function symbol

名前つき関数symbolにすでに追加されたすべての関数にたいしてfunctionを呼び出す。functionはアドバイス関数とそのプロパティという2つの引数で呼び出される。


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

13.12.3 アドバイスの構築方法

以下はadd-functionadvice-addwhere引数に可能な値であり、そのアドバイスfunctionと元の関数が構成される方法を指定します。

:before

古い関数の前にfunctionを呼び出す。関数は両方とも同じ引数を受け取り、2つの関数の結合のリターン値は古い関数のリターン値である。より正確に言うと2つの関数の結合は以下のように振る舞う:

(lambda (&rest r) (apply function r) (apply oldfun r))

(add-function :before funvar function)はノーマルフックにたいする(add-hook 'hookvar function)のような1関数のフックと同等。

:after

古い関数の後にfunctionを呼び出す。関数は両方とも同じ引数を受け取り、2つの関数の結合のリターン値は古い関数のリターン値である。より正確に言うと2つの関数の結合は以下のように振る舞う:

(lambda (&rest r) (prog1 (apply oldfun r) (apply function r)))

(add-function :after funvar function)はノーマルフックにたいする(add-hook 'hookvar function 'append)のような1関数のフックと同等。

:override

これは古い関数を新しい関数に完全に置き換える。もちろんremove-functionを呼び出した後に古い関数が復元される。

:around

古い関数のかわりにfunctionを呼び出すが、古い関数はfunctionの追加の引数になる。これはもっとも柔軟な結合である。たとえば古い関数を異なる引数で呼び出したり、複数回呼び出したり、letバインディングで呼び出したり、あるときは古い関数に処理を委譲し、またあるときは完全にオーバーライドすることが可能になる。より正確に言うと2つの関数の結合は以下のように振る舞う:

(lambda (&rest r) (apply function oldfun r))
:before-while

古い関数の前にfunctionを呼び出し、functionnilをリターンしたら古い関数を呼び出さない。関数は両方とも同じ引数を受け取り、2つの関数の結合のリターン値は古い関数のリターン値である。より正確に言うと2つの関数の結合は以下のように振る舞う:

(lambda (&rest r) (and (apply function r) (apply oldfun r)))

(add-function :before-while funvar function)run-hook-with-args-until-failureを通じてhookvarが実行されたときの(add-hook 'hookvar function)のような1関数のフックと同等。

:before-until

古い関数の前にfunctionを呼び出し、functionnilをリターンした場合だけ古い関数を呼び出す。より正確に言うと2つの関数の結合は以下のように振る舞う:

(lambda (&rest r) (or (apply function r) (apply oldfun r)))

(add-function :before-until funvar function)run-hook-with-args-until-successを通じてhookvarが実行されたときの(add-hook 'hookvar function)のような1関数のフックと同等。

:after-while

古い関数が非nilをリターンした場合だけ、古い関数の後にfunctionを呼び出す。関数は両方とも同じ引数を受け取り、2つの関数の結合のリターン値はfunctionのリターン値である。より正確に言うと2つの関数の結合は以下のように振る舞う:

(lambda (&rest r) (and (apply oldfun r) (apply function r)))

(add-function :after-while funvar function)run-hook-with-args-until-failureを通じてhookvarが実行されたときの(add-hook 'hookvar function 'append)のような1関数のフックと同等。

:after-until

古い関数がnilをリターンした場合だけ、古い関数の後にfunctionを呼び出す。より正確に言うと2つの関数の結合は以下のように振る舞う:

(lambda (&rest r) (or  (apply oldfun r) (apply function r)))

(add-function :after-until funvar function)run-hook-with-args-until-successを通じてhookvarが実行されたときの(add-hook 'hookvar function 'append)のような1関数のフックと同等。

:filter-args

最初にfunctionを呼び出し、その結果(リスト)を新たな引数として古い関数に渡す。より正確に言うと2つの関数の結合は以下のように振る舞う:

(lambda (&rest r) (apply oldfun (funcall function r)))
:filter-return

最初に古い関数を呼び出し、その結果をfunctionに渡す。より正確に言うと2つの関数の結合は以下のように振る舞う:

(lambda (&rest r) (funcall function (apply oldfun r)))

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

13.12.4 古いdefadviceを使用するコードの改良

多くのコードは古いdefadviceメカニズムを使用しており、これらの大半はadvice-addによって陳腐化しました。advice-addの実装とセマンティックは非常にシンプルです。

古いアドバイスは以下のようなものです:

(defadvice previous-line (before next-line-at-end
                                 (&optional arg try-vscroll))
  "Insert an empty line when moving up from the top line."
  (if (and next-line-add-newlines (= arg 1)
           (save-excursion (beginning-of-line) (bobp)))
      (progn
        (beginning-of-line)
        (newline))))

新しいアドバイスメカニズムを使用すれば、これを通常の関数に変換できます:

(defun previous-line--next-line-at-end (&optional arg try-vscroll)
  "Insert an empty line when moving up from the top line."
  (if (and next-line-add-newlines (= arg 1)
           (save-excursion (beginning-of-line) (bobp)))
      (progn
        (beginning-of-line)
        (newline))))

これが実際のprevious-lineを変更しないことは明確です。古いアドバイスには以下が必要です:

(ad-activate 'previous-line)

一方、新しいアドバイスメカニズムでは以下が必要です:

(advice-add 'previous-line :before #'previous-line--next-line-at-end)

ad-activateはグローバルな効果をもつことに注意してください。これは指定された関数にたいして、アドバイスのすべてを有効にします。特定のアドバイスだけをアクティブ、または非アクティブにしたいなら、ad-enable-advicead-disable-adviceでアドバイスを有効無効にする必要があります。新しいメカニズムではこの区別はなくなりました。

以下のようなaroundのアドバイスがあるとします:

(defadvice foo (around foo-around)
  "Ignore case in `foo'."
  (let ((case-fold-search t))
    ad-do-it))
(ad-activate 'foo)

これは以下のように変換できます:

(defun foo--foo-around (orig-fun &rest args)
  "Ignore case in `foo'."
  (let ((case-fold-search t))
    (apply orig-fun args)))
(advice-add 'foo :around #'foo--foo-around)

アドバイスのクラスについて、新たな:beforeは古いbeforeは完全に等価ではないことに注意してください。なぜなら古いアドバイス内では、(たとえばad-set-argを使って)その関数の引数を変更でき、それは元の関数が参照する引数値に影響します。しかし新しい:beforeは、setqを通じてアドバイス内の引数を変更して、その変更は元の関数からの参照に影響しません。この振る舞いにもとづいてbeforeアドバイスを移行するときは、代わりにそれを新たなアドバイス:around:filter-argsに変更する必要があるでしょう。

同様に古いafterアドバイスは、ad-return-valueを変更することによりリターン値を変更できますが、新しい:afterは変更できないので、そのようなafterを移行するときは、かわりにそれらを新しいアドバイス:around:filter-returnに変更する必要があるでしょう。


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

13.12.5 アドバイスとバイトコード

すべての関数にたいして信頼性をもってアドバイスできる訳ではありません。バイトコンパイラーが関数の呼び出しを、あなたが変更したい関数を呼び出さない命令シーケンスに置き換えることを選択するかもしれないからです。

これは通常は以下の3つのメカニズムのいずれかのために発生します:

byte-compileプロパティ

ある関数のシンボルにbyte-compileプロパティがあると、シンボルの関数定義のかわりにそのプロパティが使用される。バイトコンパイル関数を参照のこと。

byte-optimizeプロパティ

ある関数のシンボルにbyte-optimizeプロパティがあると、バイトコンパイラーが関数の引数を書き換えたり、まったく別の関数の使用を決断するかもしれない。

declareフォームcompiler-macro

関数は定義内に特別なdeclareフォームであるcompiler-macroをもつことができる(declareフォームを参照)。これは関数のコンパイル時に呼び出すexpanderを定義する。その場合にはexpanderが元の関数を呼び出さないバイトコードを生成するかもしれない。


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

13.13 関数の陳腐化の宣言

名前つき関数を陳腐化している(obsolete)とマークすることができます。これはその関数が将来のある時点で削除されるかもしれないことを意味します。陳腐化しているとマークされた関数を含むコードをバイトコンパイルしたとき、Emacsは警告を発します。またその関数のヘルプドキュメントは表示されなくなります。他の点では陳腐化した関数は他の任意の関数と同様に振る舞います。

関数を陳腐化しているとマークするもっとも簡単な方法は、その関数のdefun定義に(declare (obsolete …))を配置することです。declareフォームを参照してください。かわりに以下で説明しているmake-obsolete関数を使うこともできます。

make-obsoleteを使用してマクロ(マクロを参照)を陳腐化しているとマークすることもできます。これは関数のときと同じ効果をもちます。関数やマクロにたいするエイリアスも、陳腐化しているとマークできます。これはエイリアス自身をマークするのであって、名前解決される関数やマクロにたいしてではありません。

Function: make-obsolete obsolete-name current-name when

この関数はobsolete-nameを陳腐化しているとマークする。obsolete-nameには関数かマクロを命名するシンボル、または関数やマクロにたいするエイリアスを指定する。

current-nameがシンボルならobsolete-nameのかわりにcurrent-nameの使用を促す警告メッセージになる。current-nameobsolete-nameのエイリアスである必要はない。似たような機能をもつ別の関数かもしれない。current-nameには警告メッセージとなる文字列も指定できる。メッセージは小文字で始まりピリオドで終わること。nilも指定でき、この場合には警告メッセージに追加の詳細は提供されない。

引数whenは最初にその関数が陳腐化する時期を示す文字列 — たとえば日付やリリース番号を指定する。

Macro: define-obsolete-function-alias obsolete-name current-name when &optional doc

この便利なマクロは関数obsolete-nameを陳腐化しているとマークして、それを関数current-nameのエイリアスにする。これは以下と等価:

(defalias obsolete-name current-name doc)
(make-obsolete obsolete-name current-name when)

加えて陳腐化した関数にたいする特定の呼び出し規約をマークできます。

Function: set-advertised-calling-convention function signature when

この関数はfunctionを呼び出す正しい方法として、引数リストsignatureを指定する。これによりEmacs Lispプログラムが他の方法でfunctionを呼び出していたら、Emacsのバイトコンパイラーが警告を発する(それでもコードはバイトコンパイルされる)。whenにはその変数が最初に陳腐化するときを示す文字列(通常はバージョン番号)を指定する。

たとえば古いバージョンのEmacsでは、sit-forには以下のように3つの引数を指定していた

  (sit-for seconds milliseconds nodisp)

しかしこの方法によるsit-forの呼び出しは陳腐化していると判断される(時間の経過や入力の待機を参照)。以下のように古い呼び出し規約は推奨されない:

(set-advertised-calling-convention
  'sit-for '(seconds &optional nodisp) "22.1")

この関数の代替えとなるのがadvertised-calling-conventionにおけるspecのdeclareです。declareフォームを参照してください。


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

13.14 インライン関数Inli

インライン関数(inline function)は関数と同様に機能しますが、1つ例外があります。その関数の呼び出しがバイトコンパイルされると(バイトコンパイルを参照)、その関数の定義が呼び出し側に展開されます。

インライン関数を定義するには、defunのかわりにdefsubstを記述するのがシンプルに方法です。定義の残りの部分は同一に見えますが、defsubstの使用によりバイトコンパイルにそれをインラインにするように指示します。

Macro: defsubst name args [doc] [declare] [interactive] body…

このマクロはインライン関数を定義する。マクロの構文はdefunとまったく同じ(関数の定義を参照)。

関数をインラインにすることにより、その関数の呼び出しが高速になる場合があります、が欠点もありその1つは柔軟性の減少です。その関数の定義を変更すると、すでにインライン化された呼び出しは、リコンパイルを行うまで古い定義を使用することになります。

もう1つの欠点は、大きな関数をインライン化することにより、コンパイルされたコードのファイル上およびメモリー上のサイズが増大することです。スピード面でのインライン化の有利性は小さい関数で顕著なので、一般的に大きな関数をインライン化するべきではありません。

インライン関数はデバッグ、トレース、アドバイス(Emacs Lisp関数にたいするアドバイスを参照)に際してうまく機能しません。デバッグの容易さと関数の再定義の柔軟さはEmacsの重要な機能なので、スピードがとても重要であってdefunの使用が実際に性能の面で問題となるのか検証するためにすでにコードをチューニングしたのでなければ、たとえその関数が小さくてもインライン化するべきではありません。

インライン関数を定義した後そのインライン展開はマクロ同様、同じファイル内の後の部分で処理されます。

インライン関数が実行するのと同じコードに展開されるマクロ(マクロを参照してください)を定義するためにdefmacroを使用できます。しかし式内でのマクロの直接の使用には制限があります — applymapcarなどでマクロを呼び出すことはできません。通常の関数からマクロへの変換には余分な作業が必要になります。通常の関数をインライン関数に変換するのは簡単です。defundefsubstに置き換えるだけです。インライン関数の引数はそれぞれ正確に1回評価されるので、マクロのときのようにbodyで引数を何回使用するかを心配する必要はありません。

かわりにコンパイラーマクロとしてインライン展開されるコードを記述することにより関数を定義できます(declareフォームを参照)。以下のマクロがこれを可能にします。

Macro: define-inline name args [doc] [declare] body…

自身をインライン化するコードを提供することにより、コンパイラーマクロとして関数nameを定義する。この関数は引数リストargsを受け取り、指定されたbodyをもつ。

docが与えられたなら、それは関数のドキュメント文字列であること(関数のドキュメント文字列を参照)。declareが与えられたなら、それは関数のメタデータを指定するdeclareフォームであること(declareフォームを参照)。

define-inlineで定義された関数は、defsubstdefmacroで定義されたマクロにたいして複数の利点をもちます。

  • - mapcarに渡すことができる(関数のマッピングを参照)。
  • - より効率的である。
  • - 値を格納するためのplaceフォーム(place forms)として使用できる(ジェネリック変数を参照)。
  • - cl-defsubstより予測可能な方法で振る舞う(Argument Lists in Common Lisp Extensions for GNU Emacs Lispを参照)。

defmacroと同様に、define-inlineでインライン化された関数は、呼び出し側からダイナミックかレキシカルいずれかのスコーピングルールを継承します。変数のバインディングのスコーピングルールを参照してください。

以下のマクロはdefine-inlineで定義された関数のbody内で使用する必要があります。

Macro: inline-quote expression

define-inlineにたいしてexpressionをクォートする。これはバッククォート(バッククォートを参照)と似ているが、コードをクォートして,だけを受け入れ、,@は受け入れない。

Macro: inline-letevals (bindings…) body…

インライン関数の引数が正確に一度評価されて、ローカル変数を作成することを保証する便利な手段を提供する。

これはlet (ローカル変数を参照)と似ている。これはbindingsで指定されたようにローカル変数をセットアップしてから、それらのバインディングの効力の下にbodyを評価する。

bindingsの各要素はシンボル、または(var expr)という形式のリストであること。これはexprを評価して結果をvarにバインドする。しかしbindingsの要素がシンボルvarだけなら、varの評価結果はvarに再バインドされる(これはletの挙動と大きく異なる)。

bindingsの終端はnil、または引数リストを保持するシンボル。シンボルの場合には各引数を評価して、結果のリストがシンボルにバインドされる。

Macro: inline-const-p expression

expressionの値が既知なら非nilをリターンする。

Macro: inline-const-val expression

expressionの値をリターンする。

Macro: inline-error format &rest args

formatに応じてargsをフォーマットしてエラーをシグナルする。

以下はdefine-inlineを使用した例です:

(define-inline myaccessor (obj)
  (inline-letevals (obj)
    (inline-quote (if (foo-p ,obj) (aref (cdr ,obj) 3) (aref ,obj 2)))))

これは以下と等価です

(defsubst myaccessor (obj)
  (if (foo-p obj) (aref (cdr obj) 3) (aref obj 2)))

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

13.15 declareフォーム

declare(宣言)は特別なマクロで、関数やマクロにメタプロパティを追加するために使用できます。たとえば陳腐化しているとマークしたり、Emacs Lispモード内の特別なTABインデント規約を与えることができます。

Macro: declare specs…

このマクロは引数を無視してnilとして評価されるので、実行時の効果はない。しかしdefundefsubst(関数の定義を参照)、またはdefmacroマクロ(マクロの定義を参照)の定義のdeclare引数にdeclareフォームがある場合は、specsで指定されたプロパティを関数またはマクロに追加します。これはdefundefsubstdefmacroにより特別に処理される。

specs内の各要素は(property args…)というフォームをもつこと。またそれあをクォートしないこと。これらは以下の効果をもつ:

(advertised-calling-convention signature when)

これはset-advertised-calling-convention(関数の陳腐化の宣言を参照)の呼び出しと同じように振る舞う。signatureにはその関数(またはマクロ)にたいする正しい引数リスト、whenには古い引数リストが最初に陳腐化する時期を示す文字列を指定する。

(debug edebug-form-spec)

これはマクロだけに有効である。Edebugでそのマクロ入ったときに、edebug-form-specを使用する。マクロ呼び出しのインストルメントを参照のこと。

(doc-string n)

自身が関数やマクロ、変数のようなエンティティーを定義するために使用されるような関数やマクロを定義するときにこれが使用される。これはn番目の引数というこを示し、もしそれがあれば、それはドキュメント文字列とみなされる。

(indent indent-spec)

この関数(かマクロ)にたいするインデント呼び出しは、indent-specにしたがう。これは関数でも機能するが、通常はマクロで使用される。マクロのインデントを参照のこと。

(interactive-only value)

その関数のinteractive-onlyプロパティにvalueをセットする。The interactive-only propertyを参照のこと。

(obsolete current-name when)

make-obsolete(関数の陳腐化の宣言を参照)と同様に、関数(かマクロ)が陳腐化しているとマークする。current-nameにはシンボル(かわりにこのシンボルを使うことを促す警告メッセージになる)、文字列(警告メッセージを指定)、またはnil(警告メッセージには追加の詳細が含まれない)を指定すること。whenにはその関数(かマクロ)が最初に陳腐化する時期を示す文字列を指定すること。

(compiler-macro expander)

これは関数だけに使用でき、最適化関数(optimization function)としてexpanderを使用するようコンパイラーに告げる。(function args…)のようなその関数への呼び出しフォームに出会うと、マクロ展開機能(macro expander)はargs…と同様のフォームでexpanderを呼び出す。expanderはその関数呼び出しのかわりに使用するための新しい式、または変更されていないフォーム(その関数呼び出しを変更しないことを示す)のどちらかをリターンすることができる。

expanderがlambdaフォームなら、((lambda (arg) body)のように)単一の引数をもつフォームとして記述すること。関数の正規引数はlambdaの引数リストに自動的に追加されるため。

(gv-expander expander)

expandergv-define-expanderと同様、ジェネリック変数としてマクロ(か関数)にたいする呼び出しを処理する関数であることを宣言する。expanderはシンボルかフォーム(lambda (arg) body)を指定できる。フォームなら、その関数は追加でそのマクロ(か関数)の引数にアクセスできる。

(gv-setter setter)

setterがジェネリック変数としてマクロ(か関数)にたいする呼び出しを処理する関数であることを宣言する。setterはシンボルかフォームを指定できる。シンボルなら、そのシンボルはgv-define-simple-setterに渡される。フォームなら(lambda (arg) body)という形式で、その関数は追加でマクロ(か関数)の引数にアクセスでき、それはgv-define-setterに渡される。

extra

M-xでの補完にたいして入力を求める際に、関数のシンボルを関数リストに含めるかどうかを決定する関数としてcompletion-predicateを宣言する。この述語関数はread-extended-command-predicatecommand-completion-default-include-pにカスタマイズされているときだけ呼び出される。read-extended-command-predicateのデフォルトの値はnil (execute-extended-commandを参照)。述語completion-predicateは関数のシンボル、カレントバッファーという2つの引数で呼び出される。

(modes modes)

指定されたmodesにのみ適用されることを意図したコマンドであることを指定する。

(interactive-args arg ...)

repeat-command用に格納されるべき引数を指定する。argはそれぞれargument-name formという形式。

(pure val)

valが非nilなら、その関数は純粋(pure)である(関数とは?を参照)。これは関数のシンボルのpureプロパティと同じ(シンボルの標準的なプロパティを参照)。

(side-effect-free val)

valが非nilならこの関数には副作用がないので、関数の値を無視するような呼び出しをバイトコンパイラーは無視できる。これは関数のシンボルのside-effect-freeプロパティと同じ。シンボルの標準的なプロパティを参照のこと。

(speed n)

この関数のネイティブコンパイルにたいして有効なnative-comp-speedの値を指定する(ネイティブコンパイル関数を参照)。これによりその関数に発行されるネイティブコードに用いる最適化レベルを関数レベルで制御できるようになる。特にnが-1の場合には、その関数のネイティブコンパイルによってその関数にたいするネイティブコードではなくバイトコードが発行される。

no-font-lock-keyword

これはマクロにたいしてのみ有効。この宣言をもつマクロは特にマクロとしてではなく、通常の関数としてfont-lockによりハイライトされる(Font Lockモードを参照)。


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

13.16 コンパイラーへの定義済み関数の指示

あるファイルをバイトコンパイルするとき、コンパイラーが知らない関数について警告が生成されるときがあります(コンパイラーのエラーを参照してください)。実際に問題がある場合もありますが、問題となっている関数がそのコードの実行時にロードされる他のファイルで定義されている場合が通常です。たとえば以前はsimple.elをバイトコンパイルすると以下のような警告が出ていました:

simple.el:8727:1:Warning: the function ‘shell-mode’ is not known to be
    defined.

実際のところshell-mode(require 'shell)を実行する関数内のshell-modeを呼び出す前でのみ使用されるので、shell-modeは実行時に正しく定義されるでしょう。そのような警告が実際には問題を示さないことを知っているときには警告を抑制したほうがよいでしょう。そうすれば実際に問題があることを示す新しい警告の識別性が良くなります。これはdeclare-functionを使用して行うことができます。

必要なのは問題となっている関数を最初に使用する前にdeclare-function命令を追加するだけです:

(declare-function shell-mode "shell" ())

これはshell-modeshell.el (‘.el’は省略可)の中で定義していることを告げます。コンパイラーは関数がそのファイルで実際に定義されているとみなしてチェックを行いません。

3つ目の引数はオプションでありshell-modeの引数リストを指定します。この例では引数はありません(nilと値を指定しないのは異なる)。それ以外の場合には(file &optional overwrite)のようになります。引数リストを指定する必要はありませんが、指定すればコンパイラーはその呼び出しが宣言と合致するかチェックできます。

Macro: declare-function function file &optional arglist fileonly

ファイルfile内でfunctionが定義されているとみなすようにバイトコンパイラーに告げる。オプションの3つ目の引数arglistt (引数リストが未指定という意味)、またはdefunと同スタイルな正式パラメーターリスト(カッコを含む)のいずれか。arglistを省略した際のデフォルトはnilではなくt。これは引数省略時の非定形な挙動であり、3つ目の引数を指定せずに4つ目引数を与える場合には通常のnilのかわりに3つ目の引数のプレースホルダーにtを指定しなければならないことを意味する。オプションの4つ目の引数fileonlyが非nilなら実際にfunctionが定義されているかではなくfileの存在だけをチェックすることを意味する。

これらの関数がdeclare-functionが告げる場所で実際に宣言されているかどうかを検証するには、check-declare-fileを使用して1つのソースファイル中のすべてのdeclare-function呼び出しをチェックするか、check-declare-directoryを使用して特定のディレクトリー配下のすべてのファイルをチェックする。

これらのコマンドは、locate-libraryで使用する関数の定義を含むはずのファイルを探す。ファイルが見つからなければ、これらのコマンドはdeclare-functionの呼び出しを含むファイルがあるディレクトリーからの相対ファイル名に、定義ファイル名を展開する。

.c’や‘.m’で終わるファイル名を指定することにより、プリミティブ関数を指定することもできる。これが有用なのは特定のシステムだけで定義されるプリミティブを呼び出す場合だけである。ほとんどのプリミティブは常に定義されているので、それらについて警告を受け取ることはありえないはずである。

あるファイルがオプションとして外部のパッケージの関数を使う場合もある。declare-function命令内のファイル名のプレフィクスを‘ext:’にすると、そのファイルが見つかった場合はチェックして、見つからない場合はエラーとせずにスキップする。

check-declare’が理解しない関数定義もいくつか存在する(たとえばdefstructやその他いくつかのマクロ)。そのような場合はdeclare-functionfileonly引数に非nilを渡すことができる。これはファイルの存在だけをチェックして、その関数の実際の定義はチェックしないことを意味する。これを行うなら引数リストを指定する必要はないが、arglist引数にはtをセットする必要があることに注意(なぜならnilは引数リストが指定されなかったという意味ではなく空の引数リストを意味するため)。


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

13.17 安全に関数を呼び出せるかどうかの判断

SESのようないくつかのメジャーモードは、ユーザーファイル内に格納された関数を呼び出します(SESの詳細は(ses)Simple Emacs Spreadsheetを参照)。 ユーザーファイルは素性があやふやな場合があります — 初対面の人から受け取ったスプレッドシートかもしれず、会ったことのない誰かから受け取ったeメールかもしれません。そのためユーザーファイルに格納されたソースコードの関数を呼び出すのは、それが安全だと決定されるすまでは危険です。

Function: unsafep form &optional unsafep-vars

form安全(safe)なLisp式ならnil、危険ならなぜその式が危険かもしれないのか説明するリストをリターンする。引数unsafep-varsは、この時点で一時的なバインドだと判っているシンボルのリスト。これは主に内部的な再帰呼び出しで使用される。カレントバッファーは暗黙の引数になり、これはバッファーローカルなバインディングのリストを提供する。

高速かつシンプルにするために、unsafepは非常に軽量な分析を行うので、実際には安全な多くのLisp式を拒絶します。安全ではない式にたいしてunsafepnilをリターンするケースは確認されていません。しかし安全なLisp式はdisplayプロパティと一緒に文字列をリターンでき、これはその文字列がバッファーに挿入された後に実行される、割り当てられたLisp式を含むことができます。割り当てられた式はウィルスかもしれません。安全であるためにはバッファーへ挿入する前に、ユーザーコードで計算されたすべての文字列からプロパティを削除しなければなりません。


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

14 マクロ

マクロ(macros)により新たな制御構造や、他の言語機能の定義を可能にします。マクロは関数のように定義されますが、値の計算方法を指定するかわりに、値を計算する別のLisp式を計算する方法を指示します。わたしたちはこの式のことをマクロの展開(expansion)と呼んでいます。

マクロは関数が行うように引数の値を処理するのではなく、引数にたいする未評価の式を処理することによって、これを行うことができます。したがってマクロは、これらの引数式かその一部を含む式を構築することができます。

て通常の関数が行えることをマクロを使用して行う場合、単にそれが速度面の理由ならばかわりにインライン関数の使用を考慮してください。インライン関数Inliを参照してください。


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

14.1 単純なマクロの例

Cの++演算子のように、変数の値をインクリメントするためのLisp構造を定義したいとしましょう。(inc x)のように記述すれば、(setq x (1+ x))という効果を得たいとします。以下はこれを行うマクロ定義です:

(defmacro inc (var)
   (list 'setq var (list '1+ var)))

これを(inc x)のように呼び出すと、引数varはシンボルxになります — 関数のときのようにx値ではありません。このマクロのbodyはこれを展開の構築に使用して、展開形は(setq x (1+ x))になります。マクロが一度この展開形をリターンするとLispはそれを評価するので、xがインクリメントされます。

Function: macrop object

この述語はその引数がマクロかどうかテストして、もしマクロならt、それ以外はnilをリターンする。


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

14.2 マクロ呼び出しの展開

マクロ呼び出しは関数の呼び出しと同じ外観をもち、マクロの名前で始まるリストで表されます。そのリストの残りの要素はマクロの引数になります。

マクロ呼び出しの評価は1つの重大な違いを除いて、関数の評価と同じように開始されます。重要な違いとはそのマクロの引数はマクロ呼び出し内で実際の式として現れます。これらの引数はマクロ定義に与えられる前には評価されません。対象的に関数の引数はその関数の呼び出しリストの要素を評価した結果です。

こうして得た引数を使用して、Lispは関数呼び出しのようにマクロ定義を呼び出します。マクロの引数変数はマクロ呼び出しの引数値にバインドされるか、a &rest引数の場合は引数地のリストになります。そしてそのマクロのbodyが実行されて、関数bodyが行うようにマクロbodyの値をリターンします。

マクロと関数の2つ目の重要な違いは、マクロのbodyからリターンされる値が代替となるLisp式であることで、これはマクロの展開(expansion)としても知られています。Lispインタープリターはマクロから展開形が戻されると、すぐにその展開形の評価を行います。

展開形は通常の方法で評価されるので、もしかしたらその展開形は他のマクロの呼び出しを含むかもしれません。一般的ではありませんが、もしかすると同じマクロを呼び出すかもしれません。

EmacsはコンパイルされていないLispファイルをロードするときに、マクロの展開を試みることに注意してください。これは常に利用可能ではありませんが、もし可能ならそれ以降の実行の速度を改善します。プログラムがロードを行う方法を参照してください。

macroexpandを呼び出すことにより、与えられたマクロ呼び出しにたいする展開形を確認することができます。

Function: macroexpand form &optional environment

この関数はそれがマクロ呼び出しならformを展開する。結果が他のマクロ呼び出しなら、結果がマクロ呼び出しでなくなるまで順番に展開を行う。これがmacroexpandからリターンされる値になる。formがマクロ呼び出しで開始されなければ、与えられたformをそのままリターンする。

macroexpandは、(たとえいくつかのマクロ定義がそれを行っているとしても)formの部分式(subexpression)を調べないことに注意。たとえ部分式自身がマクロ呼び出しでも、macroexpandはそれらを展開しない。

関数macroexpandはインライン関数の呼び出しを展開しない。なぜならインライン関数の呼び出しは、通常の関数呼び出しと比較して理解が難しい訳ではないので、通常はそれを行う必要がないからである。

environmentが与えられたら、それはそのとき定義されているマクロをシャドーするマクロのalistを指定する。バイトコンパイルではこの機能を使用している。

(defmacro inc (var)
    (list 'setq var (list '1+ var)))

(macroexpand '(inc r))
     ⇒ (setq r (1+ r))

(defmacro inc2 (var1 var2)
    (list 'progn (list 'inc var1) (list 'inc var2)))

(macroexpand '(inc2 r s))
     ⇒ (progn (inc r) (inc s))  ; ここではincは展開されない
Function: macroexpand-all form &optional environment

macroexpand-allmacroexpandと同様にマクロを展開するが、ドップレベルだけではなくform内のすべてのマクロを探して展開する。展開されたマクロがなければリターン値はformeqになる。

上記macroexpandで使用した例をmacroexpand-allに用いると、macroexpand-allincに埋め込まれた呼び出しの展開を行うことを確認できる

(macroexpand-all '(inc2 r s))
     ⇒ (progn (setq r (1+ r)) (setq s (1+ s)))
Function: macroexpand-1 form &optional environment

この関数はmacroexpandのようにマクロを展開するが、展開の1ステップだけを行う。結果が別のマクロ呼び出しならmacroexpand-1はそれを展開しない。


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

14.3 マクロとバイトコンパイル

なぜわざわざマクロにたいする展開形を計算して、その後に展開形を評価する手間をかけるのか、不思議に思うかもしれません。なぜマクロbodyは直接望ましい結果を生成しないのでしょうか? それはコンパイルする必要があるからです。

コンパイルされるLispプログラム内にマクロ呼び出しがあるとき、Lispコンパイラーはインタープリターが行うようにマクロ定義を呼び出して展開形を受け取ります。しかし展開形を評価するかわりに、コンパイラーは展開形が直接プログラム内にあるかのようにコンパイルを行います。結果としてコンパイルされたコードはそのマクロにたいする値と副作用を生成しますが、実行速度は完全にコンパイルされたときと同じになります。もしマクロbody自身が値と副作用を計算したら、このようには機能しません — コンパイル時に計算されることになり、それは有用ではありません。

マクロ呼び出しのコンパイルが機能するためには、マクロを呼び出すコードがコンパイルされるとき、そのマクロがLisp内ですでに定義されていなければなりません。コンパイラーにはこれを行うのを助ける特別な機能があります。コンパイルされるファイルがdefmacroフォームを含むなら、そのファイルの残りの部分をコンパイルするためにそのマクロが一時的に定義されます。

ファイルをバイトコンパイルすると、ファイル内のトップレベルにあるすべてのrequire呼び出しも実行されるので、それらを定義しているファイルをrequireすることにより、コンパイルの間に必要なマクロ定義が利用できることが確実になります(名前つき機能を参照)。誰かがコンパイルされたプログラムを実行するときに、マクロ定義ファイルのロードをしないようにするには、require呼び出しの周囲にeval-when-compileを記述します(コンパイル中の評価を参照)。


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

14.4 マクロの定義

Lispのマクロオブジェクトは、CARmacroCDRが関数であるようなリストです。マクロの展開形はマクロ呼び出しから、評価されていない引数のリストに、(applyを使って)関数を適用することにより機能します。

無名関数のように無名Lispマクロを使用することも可能ですが、無名マクロをmapcarのような関数に渡すことに意味がないので、これが行われることはありません。実際のところすべてのLispマクロは名前をもち、ほとんど常にdefmacroマクロで定義されます。

Macro: defmacro name args [doc] [declare] body…

defmacroはシンボルname(クォートはしない)を、以下のようなマクロとして定義する:

(macro lambda args . body)

(このリストのCDRはラムダ式であることに注意。) このマクロオブジェクトはnameの関数セルに格納される。argsの意味は関数の場合と同じで、キーワード&rest&optionalが使用されることもある(引数リストの機能を参照)。nameargsはどちらもクォートされるべきではない。defmacroのリターン値は未定義。

docが与えられたら、それはマクロのドキュメント文字列を指定する文字列であること。declareが与えられたら、それはマクロのメタデータを指定するdeclareフォームであること(declareフォームを参照)。マクロを対話的に呼び出すことはできないので、インタラクティブ宣言をもつことはできないことに注意。

マクロが定数部と非定数部の混合体から構築される巨大なリスト構造を必要とする場合があります。これを簡単に行うためには‘`’構文(バッククォートを参照)を使用します。たとえば:

(defmacro t-becomes-nil (variable)
  `(if (eq ,variable t)
       (setq ,variable nil)))

(t-becomes-nil foo)
     ≡ (if (eq foo t) (setq foo nil))

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

14.5 マクロ使用に関する一般的な問題

マクロ展開が直感に反する結果となることがあり得ます。このセクションでは問題になりやすい重要な結果と、問題を避けるためにしたがうべきルールをいくつか説明します。


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

14.5.1 タイミング間違い

マクロを記述する際のもっとも一般的な問題として、展開形の中ではなくマクロ展開中に早まって実際に何らかの作業を行ってしまうことがあります。たとえば実際のパッケージが以下のマクロ定義をもつとします:

(defmacro my-set-buffer-multibyte (arg)
  (if (fboundp 'set-buffer-multibyte)
      (set-buffer-multibyte arg)))

この誤ったマクロ定義は解釈(interpret)されるときは正常に機能しますがコンパイル時に失敗します。このマクロ定義はコンパイル時にset-buffer-multibyteを呼び出してしまいますが、それは間違っています。その後でコンパイルされたパッケージを実行しても何も行いません。プログラマーが実際に望むのは以下の定義です:

(defmacro my-set-buffer-multibyte (arg)
  (if (fboundp 'set-buffer-multibyte)
      `(set-buffer-multibyte ,arg)))

このマクロは、もし適切ならset-buffer-multibyteの呼び出しに展開され、それはコンパイルされたプログラム実行時に実行されるでしょう。


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

14.5.2 マクロ引数の多重評価

マクロを定義する場合、展開形が実行されるときに引数が何回評価されるか注意を払わなければなりません。以下の(繰り返し処理を用意にする)マクロで、この問題を示してみましょう。このマクロでfor-loop構文を記述できます。

(defmacro for (var from init to final do &rest body)
  "Execute a simple \"for\" loop.
For example, (for i from 1 to 10 do (print i))."
  (list 'let (list (list var init))
        (cons 'while
              (cons (list '<= var final)
                    (append body (list (list 'inc var)))))))

(for i from 1 to 3 do
   (setq square (* i i))
   (princ (format "\n%d %d" i square)))
→
(let ((i 1))
  (while (<= i 3)
    (setq square (* i i))
    (princ (format "\n%d %d" i square))
    (inc i)))

     -|1       1
     -|2       4
     -|3       9
⇒ nil

マクロ内の引数fromtodoは構文糖(syntactic sugar)であり完全に無視されます。このアイデアはマクロ呼び出し中で(fromtodoのような)余計な単語をこれらの位置に記述できるようにするというものです。

以下はバッククォートの使用により、より単純化された等価の定義です:

(defmacro for (var from init to final do &rest body)
  "Execute a simple \"for\" loop.
For example, (for i from 1 to 10 do (print i))."
  `(let ((,var ,init))
     (while (<= ,var ,final)
       ,@body
       (inc ,var))))

この定義のフォームは両方(バッククォートのあるものとないもの)とも、各繰り返しにおいて毎回finalが評価されるという欠点をもちます。finalが定数のときは問題がありません。しかしこれがより複雑な、たとえば(long-complex-calculation x)のようなフォームならば、実行速度は顕著に低下し得ます。finalが副作用をもつなら、複数回実行するとおそらく誤りになります。

うまく設計されたマクロ定義は、繰り返し評価することがそのマクロの意図された目的でない限り、引数を正確に1回評価を行う展開形を生成することで、この問題を避けるためのステップを費やします。以下はforマクロの正しい展開形です:

(let ((i 1)
      (max 3))
  (while (<= i max)
    (setq square (* i i))
    (princ (format "%d      %d" i square))
    (inc i)))

以下はこの展開形を生成するためのマクロ定義です:

(defmacro for (var from init to final do &rest body)
  "Execute a simple for loop: (for i from 1 to 10 do (print i))."
  `(let ((,var ,init)
         (max ,final))
     (while (<= ,var max)
       ,@body
       (inc ,var))))

残念なことにこの訂正により以下のセクションで説明する、別の問題が発生します。


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

14.5.3 マクロ展開でのローカル変数

前のセクションではforの定義を、展開形がマクロ引数を正しい回数評価するように訂正しました:

(defmacro for (var from init to final do &rest body)
  "Execute a simple for loop: (for i from 1 to 10 do (print i))."
  `(let ((,var ,init)
         (max ,final))
     (while (<= ,var max)
       ,@body
       (inc ,var))))

forの新しい定義には新たな問題があります。この定義はユーザーが意識していない、maxという名前のローカル変数を導入しています。これは以下の例で示すようなトラブルを招きます:

(let ((max 0))
  (for x from 0 to 10 do
    (let ((this (frob x)))
      (if (< max this)
          (setq max this)))))

forのbody内部のmaxへの参照は、maxのユーサーバインディングの参照を意図したものですが、実際にはforにより作られたバインディングにアクセスします。

これを修正する方法は、maxのかわりにinternされていない(uninterned)シンボルを使用することです(シンボルの作成とinternを参照)。internされていないシンボルは他のシンボルと同じようにバインドして参照することができますが、forにより作成されるので、わたしたちはすでにユーザーのプログラムに存在するはずがないことを知ることができます。これはinternされていないので、プログラムの後続の部分でそれを配置する方法はありません。これはforにより配置された場所をのぞき、他の場所で配置されることがないのです。以下はこの方法で機能するforの定義です:

(defmacro for (var from init to final do &rest body)
  "Execute a simple for loop: (for i from 1 to 10 do (print i))."
  (let ((tempvar (make-symbol "max")))
    `(let ((,var ,init)
           (,tempvar ,final))
       (while (<= ,var ,tempvar)
         ,@body
         (inc ,var)))))

作成されたinternされていないシンボルの名前はmaxで、これを通常のinternされたシンボルmaxのかわりに、式内のその位置に記述します。


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

14.5.4 展開におけるマクロ引数の評価

マクロ定義自体がeval(evalについてを参照)の呼び出しなどによりマクロ引数式を評価した場合には別の問題が発生します。まだ呼び出し側のコンテキスト(マクロ展開が評価される場所)にアクセスできない場合には、コード実行の遥か前にマクロが展開されることを考慮する必要があります。

更にマクロ定義でlexical-bindingバインディングを使用していなければ、ユーザーの同じ名前の変数ををマクロの正規引数が隠してしまうかもしれません。マクロのbody内では、マクロ引数のバインディングはこのような変数のもっともローカルなバインディングなので、そのフォーム内部の任意の参照はそれを参照するように評価されます。以下は例です:

(defmacro foo (a)
  (list 'setq (eval a) t))
(setq x 'b)
(foo x) → (setq b t)
     ⇒ t                  ; bがセットされる
;; but
(setq a 'c)
(foo a) → (setq a t)
     ⇒ t                  ; しかしcではなくaがセットされる

ユーザーの変数の名前がaxかということで違いが生じています。これはaがマクロの引数変数aと競合しているからです。

更に上記の(foo x)の展開は、コードがコンパイル済みの際には(setq x 'b)の実行は後刻そのコードが実行されるときだけ発生するのに、(foo x)はコンパイル時に展開されるので、異なる結果をリターンしたりエラーをシグナルするでしょう。

この問題を避けるためには、マクロ展開形の計算では引数式を評価しないでください。かわりにその式をマクロ展開形の中に置き換えれば、その値は展開形の実行の一部として計算されます。これは、このチャプターの他の例が機能する方法です。


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

14.5.5 マクロが展開される回数は?

逐次解釈される関数で毎回マクロ呼び出しが展開されるが、コンパイルされた関数では(コンパイル時の)1回だけしか展開されないという事実にもとづく問題が時折発生します。そのマクロ定義が副作用をもつなら、そのマクロが何回展開されたかによって、それらのマクロは異なる動作をとるでしょう。

したがってあなたが何をしているか本当に判っていないのであれば、マクロ展開形の計算での副作用は避けるべきです。

避けることのできない特殊な副作用が1つあります。それはLispオブジェクトの構築です。ほとんどすべてのマクロ展開形にはリストの構築が含まれます。リスト構築はほとんどのマクロの核心部分です。これは通常は安全です。用心しなければならないケースが1つだけあります。それは構築するオブジェクトがマクロ展開形の中でクォートされた定数の一部となるときです。

そのマクロが1回だけ — コンパイル時 — しか展開されないなら、そのオブジェクトの構築もコンパイル時の1回です。しかし逐次実行では、そのマクロはマクロ呼び出しが実行されるたびに展開され、これは毎回新たなオブジェクトが構築されることを意味します。

クリーンなLispコードのほとんどでは、この違いは問題になりません。しかしマクロ定義によるオブジェクト構築の副作用を処理する場合には、問題になるかもしれません。したがって問題を避けるために、マクロ定義によるオブジェクト構築の副作用を避けてください。以下は副作用により問題が起こる例です:

(defmacro empty-object ()
  (list 'quote (cons nil nil)))

(defun initialize (condition)
  (let ((object (empty-object)))
    (if condition
        (setcar object condition))
    object))

initializeが解釈されると、initializeが呼び出されるたびに新しいリスト(nil)が構築されます。したがって各呼び出しの間において副作用は存続しません。しかしinitializeがコンパイルされると、マクロempty-objectはコンパイル時に展開され、これは1つの定数(nil)を生成し、この定数はinitializeの呼び出しの各回で再利用、変更されます。

このような異常な状態を避ける1つの方法は、empty-objectをメモリー割り当て構造ではなく一種の奇妙な変数と考えることです。'(nil)のような定数にたいしてsetcarを使うことはないでしょうから、当然(empty-object)にも使うことはないでしょう。


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

14.6 マクロのインデント

マクロ定義ではマクロ呼び出しをTABがどのようにインデントすべきか指定するために、declareフォーム(マクロの定義を参照)を使うことができます。インデント指定は以下のように記述します:

(declare (indent indent-spec))

このlisp-indent-functionプロパティ内の結果はマクロの名前にセットされます。

以下は利用できるindent-specです:

nil

これはプロパティを指定しない場合と同じ — 標準的なインデントパターンを使用する。

defun

この関数を‘def’構文 — 2番目の行がbodyの開始 — と同様に扱う。

整数: number

関数の最初のnumber個の引数は区別され、残りは式のbodyと判断される。その式の中の行は、最初の引数が区別されているかどうかにしたがってインデントされる。引数がbodyの一部なら、その行はこの式の先頭の開カッコ(open-parenthesis)よりもlisp-body-indentだけ多い列にインデントされる。引数が区別されていて1つ目か2つ目の引数なら、2倍余分にインデントされる。引数が区別されていて1つ目か2つ目以外の引数なら、その行は標準パターンによってインデントされる。

シンボル: symbol

symbolは関数名。この関数はこの式のインデントを計算するために呼び出される関数。この関数は2つの引数をとる:

pos

その行のインデントが開始される位置。

state

その行の開始まで解析したとき、parse-partial-sexp(インデントとネスト深さの計算のためのLispプリミティブ)によりリターンされる値。

これは数(その行のインデントの列数)、またはそのような数がcarであるようなリストをリターンすること。数とリストの違いは、数の場合は同じネスト深さの後続のすべての行はこの数と同じインデントとなる。リストなら、後続の行は異なるインデントを呼び出すかもしれない。これはC-M-qによりインデントが計算されるときに違いが生じる。値が数ならC-M-qはリストの終わりまでの後続の行のインデントを再計算する必要はない。


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

15 カスタマイゼーション設定

EmacsのユーザーはCustomizeインターフェースにより、Lispコードを記述することなく変数とフェースをカスタマイズできます。Easy Customization in The GNU Emacs Manualを参照してください。このチャプターではCustomizeインターフェースを通じて、ユーザーとやりとりするためのカスタマイズアイテム(customization items)を定義する方法を説明します。

カスタマイズアイテムにはdefcustomマクロ で定義されるカスタマイズ可能変数 defface(フェイスの定義で個別に説明)で定義されるカスタマイズ可能フェイス、およびdefgroup で定義される カスタマイゼーショングループ(customization groups)が含まれ、これは関連するカスタマイゼーションアイテムのコンテナとして振る舞います。


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

15.1 一般的なキーワードアイテム

以降のセクションで説明するカスタマイゼーション宣言(customization declaration) — defcustomdefgroupなどはすべてさまざまな情報を指定するためのキーワード引数(変更不可な変数を参照)を受け取ります。このセクションではカスタマイゼーション宣言のすべての種類に適用されるキーワードを説明します。

:tag以外のすべてのキーワードは、与えられたアイテムにたいして複数回使用できます。キーワードの使用はそれぞれ独立した効果をもちます。例外は:tagで、これはすべての与えられたアイテムは1つの名前だけを表示できるからです。

:tag label

labelを使用すると、カスタマイゼーションメニュー(customization menu)とカスタマイゼーションバッファー(customization buffer)のアイテムのラベルづけに、そのアイテムの名前のかわりに指定された文字列を使用します。混乱を招くのでそのアイテムの実際の名前と大きく異なる名前は使用しないでください

:group group

このカスタマイゼーションアイテムをグループgroupにputする。カスタマイゼーションアイテムからこのキーワードが欠落していると、アイテムは最後に定義された同じグループ内に配置されるだろう。

defgroup内で:groupを使用すると、そのアイテムは新しいグループ(:groupのサブグループ)になる。

このキーワードを複数回使用すると、1つのアイテムを複数のグループに配置することができる。それらのグループのいずれかを表示すると、このアイテムが表示される。煩雑になるので多用しないこと。

このアイテムのドキュメント文字列の後に外部リンクを含める。これは他のドキュメントを参照するセンテンスを含んだボタンである。

link-dataに使用できる複数の選択肢がある:

(custom-manual info-node)

infoノードへのリンク。info-node"(emacs)Top"のような、ノード名を示す文字列である。このリンクはカスタマイゼーションバッファーの‘[Manual]’に表示され、info-nodeにたいしてビルトインのinfoリーダーを起動する。

(info-link info-node)

custom-manualと同様だが、カスタマイゼーションバッファーにはそのinfoノード名が表示される。

(url-link url)

ウェブページヘのリンク。urlURLを指定する文字列である。カスタマイゼーションバッファーに表示されるリンクはbrowse-url-browser-functionで指定されたWWWブラウザーを呼び出す。

(emacs-commentary-link library)

ライブラリーのコメントセクション(commentary section)へのリンク。libraryはライブラリー名を指定する文字列である。Emacsライブラリーのヘッダーの慣習を参照のこと。

(emacs-library-link library)

Emacs Lispライブラリーファイルへのリンク。libraryはライブラリー名を指定する文字列である。

(file-link file)

ファイルへのリンク。fileはユーザーがこのリンクを呼び出したときにfind-fileでvisitするファイルの名前を指定する文字列である。

(function-link function)

関数のドキュメントへのリンク。functionはユーザーがこのリンクを呼び出したときにdescribe-functionで説明を表示する関数の名前を指定する文字列である。

(variable-link variable)

変数のドキュメントへのリンク。variableはユーザーがこのリンクを呼び出したときにdescribe-variableで説明を表示する変数の名前を指定する文字列である。

(face-link face)

フェイスのドキュメントへのリンク。faceはユーザーがこのリンクを呼び出したときにdescribe-faceで説明を表示する関数の名前を指定する文字列である。

(custom-group-link group)

他のカスタマイゼーショングループへのリンク。このリンクを呼び出すことによりgroupにたいする新たなカスタマイゼーションバッファーが作成される。

link-dataの1つ目の要素の後に:tag nameを追加することにより、カスタマイゼーションバッファーで使用するテキストを指定できます。たとえば(info-link :tag "foo" "(emacs)Top")は、そのバッファーで‘foo’と表示されるEmacs manualへのリンクを作成します。

複数のリンクを追加するために、このキーワードを複数回使用することができます。

:load file

そのカスタマイゼーションアイテムを表示する前にファイルfileをロードする(ロードを参照)。ロードはloadにより行われ、そのファイルがまだロードされていないときだけロードを行う。

:require feature

保存したカスタマイゼーションがこのアイテム値をセットするとき、(require 'feature)が実行される。featureはシンボル。

:requireを使用するもっとも一般的な理由は、ある変数がマイナーモードのような機能を有効にするとき、そのモードを実装するコードがロードされていなければ、変数のセットだけでは効果がないからである。

:version version

このキーワードはそのアイテムが最初に導入されたEmacsバージョンversionか、そのアイテムのデフォルト値がそのバージョンで変更されたことを指定する。値versionは文字列でなければならない。

:package-version '(package . version)

このキーワードはそのアイテムが最初に導入されたpackageのバージョンversionか、アイテムの意味(またはデフォルト値)が変更されたバージョンを指定する。このキーワードは:versionより優先される。

packageにはそのパッケージの公式名をシンボルとして指定すること(たとえばMH-E)。versionには文字列であること。パッケージpackageがEmacsの一部としてリリースされたなら、packageversionの値はcustomize-package-emacs-version-alistの値に表示されるはずである。

Emacsの一部として配布された:package-versionキーワードを使用するパッケージは、customize-package-emacs-version-alist変数も更新しなければなりません。

Variable: customize-package-emacs-version-alist

これは:package-versionキーワード内でリストされたパッケージのバージョンに関連付けられたEmacsのバージョンにたいして、マッピングを提供するalistである。このalistの要素は:

(package (pversion . eversion)…)

それぞれのpackage(シンボル)にたいして、パッケージバージョンpversionを含む1つ以上の要素と、それに関連付けられるEmacsバージョンeversionが存在する。これらのバージョンは文字列である。たとえばMH-Eパッケージは以下によりalistを更新する:

(add-to-list 'customize-package-emacs-version-alist
             '(MH-E ("6.0" . "22.1") ("6.1" . "22.1") ("7.0" . "22.1")
                    ("7.1" . "22.1") ("7.2" . "22.1") ("7.3" . "22.1")
                    ("7.4" . "22.1") ("8.0" . "22.1")))

packageの値は一意である必要があり、:package-versionキーワード内に現れるpackageの値とマッチする必要がある。おそらくユーザーはエラーメッセージからこの値を確認するので、MH-EやGnusのようなパッケージの公式名を選択するのがよいだろう。


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

15.2 カスタマイゼーショングループの定義

Emacs Lispパッケージはそれぞれ、1つのメインのカスタマイゼーショングループ(main customization group)をもち、それにはすべてのオプションとフェイス、そのパッケージ内の他のグループが含まれるべきです。そのパッケージに少数のオプションとフェイスしかなければ、1つのグループだけを使用してその中にすべてを配置します。20以上のオプションやフェイスがあるなら、それらをサブグループ内に構造化して、そのサブグループをメインのカスタマイゼーショングループの下に配置します。そのパッケージ内の任意のオプションやフェイスを、サブグループと並行してメイングループに配置しても問題はありません。

そのパッケージのメイングループ(または唯一のグループ)は、1つ以上の標準カスタマイゼーショングループ(standard customization group)のメンバーであるべきです(これらの完全なリストを表示するにはM-x customizeを使用する)。それらの内から1つ以上(多すぎないこと)を選択して、:groupを使用してあなたのグループをそれらに追加します。

新しいカスタマイゼーショングループはdefgroupで宣言します。

Macro: defgroup group members doc [keyword value]…

membersを含むカスタマイゼーショングループとしてgroupを宣言する。シンボルgroupはクォートしない。引数docはそのグループにたいするドキュメント文字列を指定する。

引数membersはそのグループのメンバーとなるカスタマイゼーションアイテムの初期セットを指定するリストである。しかしほとんどの場合はmembersnilにして、メンバーを定義するときに:groupキーワードを使用することによってそのグループのメンバーを指定する。

membersを通じてグループのメンバーを指定したければ、要素はそれぞれ(name widget)という形式で指定すること。ここでnameはシンボル、widgetはそのシンボルを編集するウィジェット型(widget type)である。変数にはcustom-variable、フェイスにはるcustom-face、グループにはcustom-groupが有用なウィジェットである。

Emacsに新しいグループを導入するときはdefgroup内で:versionキーワードを使用する。そうすればグループの個別のメンバーにたいしてそれを使用する必要がなくなる。

一般的なキーワード(一般的なキーワードアイテムを参照)に加えて、defgroup内では以下のキーワードも使用できる:

:prefix prefix

グループ内のアイテムの名前がprefixで始まり、カスタマイズ変数custom-unlispify-remove-prefixesが非nilなら、そのアイテムのタグからprefixが省略される。グループは任意の数のプレフィクスをもつことができる。

変数およびグループのサブグループはグループのシンボルのcustom-groupプロパティに格納される。シンボルのプロパティへのアクセスを参照のこと。このプロパティの値はcarが変数、フェイスまたはサブグループのシンボル、cdrはそれぞれcustom-variablecustom-face、またはcustom-groupのうちいずれかに対応するシンボルであるようなリスト。

User Option: custom-unlispify-remove-prefixes

この変数が非nilならグループの:prefixキーワードで指定されたプレフィクスは、ユーザーがグループをカスタマイズするときは常にタグ名から省略される。

デフォルト値はnil、つまりプレフィクス省略(prefix-discarding)の機能は無効となる。これはオプションやフェイスの名前にたいするプレフィクスの省略が混乱を招くことがあるからである。


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

15.3 カスタマイゼーション変数の定義

カスタマイズ可能変数(customizable variable)ユーザーオプション(user option)とも呼ばれ、これはCustomizeインターフェースを通じてセットできるグローバルなLisp変数です。defvar(グローバル変数の定義を参照)デ定義される他のグローバル変数と異なり、カスタマイズ可能変数はdefcustomマクロを使用して定義されます。サブルーチンとしてdefvarを呼び出すことに加えテ、defcustomはCustomizeインターフェースでその変数が表示される方法や、その変数がとることができる値などを明示します。

Macro: defcustom option standard doc [keyword value]…

このマクロはユーザーオプション(かカスタマイズ可能変数)としてoptionを宣言する。optionはクォートしないこと。

引数standardoptionの標準値を指定する式である。defcustomフォームの評価によりstandardが評価されるが、その値にそのオプションをバインドする必要はない。optionがすでにデフォルト値をもつなら、それは変更されずに残る。ユーザーがすでにoptionにたいするカスタマイゼーションを保存していれば、ユーザーによりカスタマイズされた値がデフォルト値としてインストールされる。それ以外ならstandardを評価した結果がデフォルト値としてインストールされる。

defvarと同様、このマクロはoptionをスペシャル変数 — 常にダイナミックにバインドされることを意味する — としてマークする。optionがすでにレキシカルバインドをもつなら、そのレキシカルバインドはバインディング構文を抜けるまで効果をもつ。変数のバインディングのスコーピングルールを参照のこと。

standardは別の様々な機会 — カスタマイゼーション機能がoptionの標準値を知る必要があるときは常に — にも評価される可能性がある。そのため任意回数の評価を行ても安全な式を使用するように留意されたい。

引数docはその変数にたいするドキュメント文字列を指定する。

defcustomが何も:groupを指定しなければ、同じファイル内でdefgroupによって最後に定義されたグループが使用される。この方法ではほとんどのdefcustomは明示的な:groupが不必要になる。

Emacs LispモードでC-M-x(eval-defun)でdefcustomフォームを評価するとき、eval-defunの特別な機能は変数の値がvoidかどうかテストせずに、無条件に変数をセットするよう段取りする(同じ機能はdefvarにも適用される。グローバル変数の定義を参照)。すでに定義されたdefcustomでeval-defunを使用することにより、(もしあれば):set関数(以下参照)が呼び出される。

事前ロード(pre-loaded)されたEmacs Lispファイル(Emacsのビルドを参照)にdefcustomを配置すると、ダンプ時にインストールされた標準値は正しくない — たとえば依存している他の変数がまだ正しい値を割り当てられていない — かもしれない。この場合はEmacs起動後に標準値を再評価するために、以下で説明するcustom-reevaluate-settingを使用する。

一般的なキーワードアイテムにリストされたキーワードに加えて、このマクロには以下のキーワードを指定できる

:type type

このオプションのデータ型としてtypeを使用する。これはどんな値が適正なのか、その値をどのように表示するかを指定する(カスタマイゼーション型を参照)。defcustomはそれぞれこのキーワードにたいする値を指定すること。

:options value-list

このオプションに使用する適正な値のリストを指定する。ユーザーが使用できる値はこれらの値に限定されないが、これらは便利な値の選択肢を提示する。

これは特定の型にたいしてのみ意味をもち現在のところhookplistalistが含まれる。:optionsを使用する方法は個別の型の定義を参照のこと。

異なる:options値によるdefcustomフォームの再評価では以前の評価で追加された値や、custom-add-frequent-value (以下参照)呼び出しで追加された値はクリアーされない。

:set setfunction

Customizeインターフェースを使用してこのオプションの値を変更する方法としてsetfunctionを指定する。関数setfunctionは2つの引数 — シンボル(オプション名)と新しい値 — を受け取り、このオプションにたいして正しく値を更新するために必要なことは何であれ行うこと(これはおそらくLisp変数として単にオプションをセットすることを意味しない)。この関数は引数の値を破壊的に変更しないことが望ましい。setfunctionのデフォルトはset-default-toplevel-value

定義された場合にはEmacs LispモードからC-M-xによりdefcustomが評価されたとき、あるいはsetoptマクロ(setoptを参照)を介してoptionの値が変更された際にもsetfunctionが呼び出される。

このキーワードを指定すると、その変数のドキュメント文字列にはsetfunctionを直接呼び出すか、setoptを用いることによって手入力のLispコードで同じことを行う方法が記載されていること。

:get getfunction

このオプションの値を抽出する方法としてgetfunctionを指定する。関数getfunctionは1つの引数(シンボル)を受け取り、カスタマイズがそのシンボル(シンボルのLisp値である必要はない)にたいするカレント値としてそれを使うべきかどうかをリターンすること。デフォルトはdefault-toplevel-value

:getを正しく使用するためには、Customの機能を真に理解する必要がある。これは変数としてCustom内で扱われる値のためのものだが、実際にはLisp変数には格納されない。実際にLisp変数に格納されている値にgetfunctionを指定するのは、ほとんどの場合は誤りである。

:initialize function

functiondefcustomが評価されるときに変数を初期化するために使用される関数であること。これは2つの引数 — オプション名(シンボル)と値を受け取る。この方法での使用のために事前定義された関数がいくつかある:

custom-initialize-set

変数の初期化にその変数の:set関数を使用するが、値がすでに非voidなら再初期化を行わない。

custom-initialize-default

custom-initialize-setと同様だが、その変数の:setのかわりに関数set-default-toplevel-valueを使用して変数をセットする。これは変数の:set関数がマイナーモードを有効または無効にする場合の通常の選択である。この選択により変数の定義ではマイナーモード関数を呼び出しは行わないが、変数をカスタマイズしたときはマイナーモード関数を呼び出すだろう。

custom-initialize-reset

変数の初期化に常に:set関数を使用する。変数がすでに非voidなら、(:getメソッドでリターンされる)カレント値を使用して:set関数を呼び出して変数をリセットする。これはデフォルトの:initialize関数である。

custom-initialize-changed

変数がすでにセットされている、またはカスタマイズされていれば:set関数、それ以外なら単にset-default-toplevel-valueを使用して変数の初期化を行う。

custom-initialize-delay

この関数はcustom-initialize-setと同様に振る舞うが、実際の初期化をEmacsの次回起動時に遅延させる。これはビルド時ではなく実行時のコンテキストで初期化を行わせるように、事前ロードされるファイル(やautoloadされる変数)で使用すること。これは(遅延された)初期化が:set関数で処理されるという副作用ももつ。Emacsのビルドを参照のこと。

:local value

valuetならoptionをバッファーローカルと自動的にマークする。値がpermanentならoptionpermanent-localプロパティもtにセットする。バッファーローカルなバインディングの作成と削除を参照のこと。

:risky value

その変数のrisky-local-variableプロパティをvalueにセットする(ファイルローカル変数を参照)。

:safe function

その変数のsafe-local-variableプロパティをfunctionにセットします(ファイルローカル変数を参照)。

:set-after variables

保存されたカスタマイゼーションに合わせて変数をセッティングするときは、その前に変数variables確実にセット — つまりこれら他のものが処理される後までセッティングを遅延 — すること。これら他の変数が意図された値をもっていない場合に、この変数のセッティングが正しく機能しなければ:set-afterを使用すること。

特定の機能をオンに切り替えるオプションには、:requireキーワードを指定すると便利です。これはその機能がまだロードされていないときには、そのオプションがセットされればEmacsがその機能をロードするようにします。一般的なキーワードアイテムを参照してください。以下は例です:

(defcustom frobnicate-automatically nil
  "Non-nil means automatically frobnicate all buffers."
  :type 'boolean
  :require 'frobnicate-mode
  :group 'frobnicate)

あるカスタマイゼーションアイテムが:optionsがサポートするhookalistのような型をもつなら、custom-add-frequent-valueを呼び出すことによってdefcustom宣言の外部から別途値を追加できます。たとえばemacs-lisp-mode-hookから呼び出されることを意図した関数my-lisp-mode-initializationを定義する場合は、emacs-lisp-mode-hookにたいする正当な値として、その定義を編集することなくその関数をリストに追加したいと思うかもしれません。これは以下のようにして行うことができます:

(custom-add-frequent-value 'emacs-lisp-mode-hook
   'my-lisp-mode-initialization)
Function: custom-add-frequent-value symbol value

カスタマイズオプションsymbolにたいして正当な値のリストにvalueを追加する。

追加による正確な効果はsymbolのカスタマイズ型に依存する。

以前に追加した値はdefcustomフォームの評価ではクリアーされないので、Lispプログラムは未定義のユーザーおっしゃるへの値追加にこの関数を使用できる。

defcustomは内部的に、標準値にたいする式の記録にシンボルプロパティstandard-value、カスタマイゼーションバッファーでユーザーが保存した値の記録にsaved-value、カスタマイゼーションバッファーでユーザーがセットして未保存の値の記録にcustomized-valueを使用します。シンボルのプロパティを参照してください。加えてテーマによりセットされた値の記録に使用されるthemed-valueも存在します(Customテーマを参照)。これらのプロパティは、carがその値を評価する式であるようなリストです。

Function: custom-reevaluate-setting symbol

この関数はdefcustomを通じて宣言されたユーザーオプションsymbolの標準値を再評価する。変数がカスタマイズされたなら、この関数はかわりに保存された値を再評価する。それからこの関数はその値に、(もし定義されていればそのオプションの:setプロパティを使用して)ユーザーオプションをセットする。

これは値が正しく計算される前に定義されたカスタマイズ可能オプションにたいして有用である。たとえばstartupの間、Emacsは事前ロードされたEmacs Lispファイルで定義されたユーザーオプションにたいしてこの関数を呼び出すが、これらの初期値は実行時だけ利用可能な情報に依存する。

Function: custom-variable-p arg

この関数はargがカスタマイズ可能変数なら非nilをリターンする。カスタマイズ可能変数とは、standard-valuecustom-autoloadプロパティをもつ(通常はdefcustomで宣言されたことを意味する)変数、または別のカスタマイズ可能変数にたいするエイリアスのことである。


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

15.4 カスタマイゼーション型

defcustomでユーザーオプションを定義するときは、ユーザーオプションのカスタマイゼーション型(customization type)を指定しなければなりません。これは(1)どの値が適正か、および(2)編集のためにカスタマイゼーションバッファーで値を表示する方法を記述するLispオブジェクトです。

カスタマイゼーション型はdefcustom内の:typeキーワードで指定します。:typeの引数は評価されますが、defcustomが実行されるときに1回だけ評価されるので、さまざまな値をとる場合には有用でありません。通常はクォートされた定数を使用します。たとえば:

(defcustom diff-command "diff"
  "The command to use to run diff."
  :type '(string)
  :group 'diff)

一般的にカスタマイゼーション型は最初の要素が以降のセクションで定義されるカスタマイゼーション型の1つであるようなリストです。このシンボルの後にいくつかの引数があり、それはそのシンボルに依存します。型シンボルと引数の間にはオプションでkeyword-valueペアー(型キーワードを参照)を記述できます。

いくつかの型シンボルは引数を使用しません。これらはシンプル型(simple types)と呼ばれます。シンプル型ではkeyword-valueペアーを使用しないなら、型シンボルの周囲のカッコ(parentheses)を省略できます。たとえばカスタマイゼーション型として単にstringと記述すると、それは(string)と等価です。

すべてのカスタマイゼーション型はウィジェットとして実装されます。詳細は、Introduction in The Emacs Widget Libraryを参照してください。


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

15.4.1 単純型

このセクションではすべてのシンプルデータ型を説明します。これらのカスタマイゼーション型のうちのいくつかにたいして、カスタマイゼーションウィジェットはC-M-iM-TABによるインライン補完を提供します。

sexp

値はプリントと読み込みができる任意のLispオブジェクト。より特化した型を使用するために時間をとりたくなければ、すべてのオプションにたいするフォールバックとしてsexpを使用することができる。

integer

値は整数でなければならない。

natnum

値は非負の整数でなければならない。

number

値は数(浮動小数点数か整数)でなければならない。

float

値は浮動小数点数でなければならない。

string

値は文字列でなければならない。カスタマイゼーションバッファーはその文字列を区切り文字‘"’文字と‘\’クォートなしで表示する。

regexp

string文字と同様だがその文字列は有効な正規表現でなければならない。

character

値は文字コードでなければならない。文字コードは実際には整数だが、この型は数字を表示せずにバッファー内にその文字を挿入することにより値を表示する。

file

値はファイル名でなければならない。ウィジェットは補完を提供する。

(file :must-match t)

値は既存のファイル名でなければならない。ウィジェットは補完を提供する。

directory

値はディレクトリーでなければならない。ウィジェットは補完を提供する。

hook

値は関数のリストでなければならない。このカスタマイゼーション型はフック変数にたいして使用される。フック内で使用を推奨される関数のリストを指定するために、フック変数のdefcustom内で:optionsキーワードを使用できる。カスタマイゼーション変数の定義を参照のこと。

symbol

値はシンボルでなければならない。これはカスタマイゼーションバッファー内でシンボル名として表示される。ウィジェットは補完を提供する。

function

値はラムダ式か関数名でなければならない。ウィジェットは関数名にたいする補完を提供する。

variable

値は変数名でなければならない。ウィジェットは補完を提供する。

face

値はフェイス名のシンボルでなければならない。ウィジェットは補完を提供する。

boolean

値は真偽値 — niltである。choiceconstを合わせて使用することにより(次のセクションを参照)、値はniltでなければならないが、それら選択肢に固有の意味に適合する方法でそれぞれの値を説明するテキストを指定することもできる。

key

key-valid-pに照らして有効となるような、たとえばkeymap-setに用いるのに適した値。

key-sequence

値はキーシーケンス。カスタマイゼーションバッファーはkbd関数と同じ構文を使用してキーシーケンスを表示する。このタイプは過去の遺物であり、かわりにkbd関数を使うこと。キーシーケンスを参照されたい。

coding-system

値はコーディングシステム名でなければならず、M-TABで補完することができる。

color

値は有効なカラー名でなければならない。ウィジェットはカラー名にたいする補完と、同様に*Colors*バッファーに表示されるカラーサンプルとカラー名のリストからカラー名を選択するボタンを提供する。

fringe-bitmap

値はフリンジビットマップ名でなければならない。ウィジェットは補完を提供する。


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

15.4.2 複合型

適切なシンプル型がなければ複合型(composite types)を使用することができます。複合型は特定のデータにより、他の型から新しい型を構築します。指定された型やデータは、その複合型の引数(argument)と呼ばれます。複合型は通常は以下のようなものです:

(constructor arguments…)

しかし以下のように引数の前にkeyword-valueペアーを追加することもできます。

(constructor {keyword value}arguments…)

以下のテーブルに、コンストラクター(constructor)と複合型を記述するためにそれらを使用する方法を示します:

(cons car-type cdr-type)

値はコンスセルでなければならずCARcar-typeCDRcdr-typeに適合していなければならない。たとえば(cons string symbol)は、("foo" . foo)のような値にマッチするデータ型となる。

カスタマイゼーションバッファーでは、CARCDRはそれぞれ特定のデータ型に応じて個別に表示と編集が行われる。

(list element-types…)

値はelement-typesで与えられる要素と数が正確に一致するリストでなければならず、リストの各要素はそれぞれ対応するelement-typeに適合しなければならない。

たとえば(list integer string function)は3つの要素のリストを示し、1つ目の要素は整数、2つ目の要素は文字列、3つ目の要素は関数である。

カスタマイゼーションバッファーでは、各要素はそれぞれ特定のデータ型に応じて個別に表示と編集が行われる。

(group element-types…)

これはlistと似ているが、Customバッファー内でのテキストのフォーマットが異なる。listは各要素の値をそのタグでラベルづけするが、groupはそれを行わない。

(vector element-types…)

これはlistと似ているが、リストではなくベクターでなければならない。各要素はlistの場合と同様に機能する。

(alist :key-type key-type :value-type value-type)

値はコンスセルのリストでなければならず、各セルのCARはカスタマイゼーション型key-typeのキーを表し、同じセルのCDRはカスタマイゼーション型value-typeの値を表す。ユーザーはkey/valueペアーの追加や削除ができ、各ペアのキーと値の両方を編集することができる。

省略された場合のkey-typevalue-typeのデフォルトはsexp

ユーザーは指定されたkey-typeにマッチする任意のキーを追加できるが、:options(カスタマイゼーション変数の定義を参照)で指定することにより、あるキーを優先的に扱うことができる。指定されたキーは、(適切な値とともに)常にカスタマイゼーションバッファーに表示される。またalistにkey/valueを含めるか、除外するか、それとも無効にするかを指定するチェックボックスも一緒に表示される。ユーザーは:optionsキーワード引数で指定された値を変更できない。

:optionsキーワードにたいする引数は、alist内の適切なキーにたいする仕様のリストであること。これらは通常は単純なアトムであり、それらは自身を意味します。たとえば:

:options '("foo" "bar" "baz")

これは名前が"foo""bar""baz"であるような3つの既知のキーがあることを指定し、それらは常に最初に表示される。

たとえば"bar"キーに対応する値を整数だけにするというように、特定のキーに対して値の型を制限したいときがあるかもしれない。これはリスト内でアトムのかわりにリストを使用することにより指定することができる。前述のように1つ目の要素はそのキー、2つ目の要素は値の型を指定する。たとえば:

:options '("foo" ("bar" integer) "baz")

最後にキーが表示される方法を変更したいときもあるだろう。デフォルトでは:optionsキーワードで指定された特別なキーはユーザーが変更できないので、キーは単にconstとして表示される。しかしたとえばそれが関数バインディングをもつシンボルであることが既知なら、function-itemのようにあるキーの表示のためにより特化した型を使用したいと思うかもしれない。これはキーにたいしてシンボルを使うかわりに、カスタマイゼーション型指定を使用することにより行うことができる。

:options '("foo"
           ((function-item some-function) integer)
           "baz")

多くのalistはコンスセルのかわりに2要素のリストを使用する。たとえば、

(defcustom cons-alist
  '(("foo" . 1) ("bar" . 2) ("baz" . 3))
  "Each element is a cons-cell (KEY . VALUE).")

のかわりに以下を使用する

(defcustom list-alist
  '(("foo" 1) ("bar" 2) ("baz" 3))
  "Each element is a list of the form (KEY VALUE).")

リストはコンスセルの最上位に実装されているため、上記のlist-alistをコンスセルのalist(値の型が実際の値を含む1要素のリスト)として扱うことができる。

(defcustom list-alist '(("foo" 1) ("bar" 2) ("baz" 3))
  "Each element is a list of the form (KEY VALUE)."
  :type '(alist :value-type (group integer)))

listのかわりにgroupを使用するのは、それが目的に適したフォーマットだという理由だけである。

同様に以下のようなトリックの類を用いることにより、より多くの値が各キー連づけられたalistを得ることができる:

(defcustom person-data '(("brian"  50 t)
                         ("dorith" 55 nil)
                         ("ken"    52 t))
  "Alist of basic info about people.
Each element has the form (NAME AGE MALE-FLAG)."
  :type '(alist :value-type (group integer boolean)))
(plist :key-type key-type :value-type value-type)

このカスタマイゼーション型はalist(上記参照)と似ているが、(1)情報がプロパティリスト(プロパティリストを参照)に格納されていて、(2)key-typeが省略された場合のデフォルトはsexpではなくsymbolになる。

(choice alternative-types…)

値はalternative-typesのうちのいずれかに適合しなければならない。たとえば(choice integer string)では整数か文字列が許容される。

カスタマイゼーションバッファーでは、ユーザーはメニューを使用して候補を選択して、それらの候補にたいして通常の方法で値を編集できる。

通常はこの選択からメニューの文字列が自動的に決定される。しかし候補の中に:tagキーワードを含めることにより、メニューにたいして異なる文字列を指定できる。たとえば空白の数を意味する整数と、その通りに使用したいテキストにたいする文字列なら、以下のような方法でカスタマイゼーション型を記述したいと思うかもしれない

(choice (integer :tag "Number of spaces")
        (string :tag "Literal text"))

この場合のメニューは‘Number of spaces’と‘Literal text’を提示する。

const以外のnilが有効な値ではない選択肢には、:valueキーワードを使用して有効なデフォルト値を指定すること。型キーワードを参照のこと。

複数の候補によりいくつかの値が提供されるなら、カスタマイズは適合する値をもつ最初の候補を選択する。これは常にもっとも特有な型が最初で、もっとも一般的な型が最後にリストされるべきことを意味する。以下は適切な使い方の例である

(choice (const :tag "Off" nil)
        symbol (sexp :tag "Other"))

この使い方では特別な値nilはその他のシンボルとは別に扱われ、シンボルは他のLisp式とは別に扱われる。

(radio element-types…)

これはchoiceと似ているが、選択はメニューではなくラジオボタンで表示される。これは該当する選択にたいしてドキュメントを表示できる利点があるので、関数定数(function-itemカスタマイゼーション型)の選択に適している場合がある。

(const value)

値はvalueでなければならず他は許容されない。

constは主にchoiceの中で使用される。たとえば(choice integer (const nil))では整数かnilが選択できる。

choiceの中では:tagとともにconstが使用される場合がある。たとえば、

(choice (const :tag "Yes" t)
        (const :tag "No" nil)
        (const :tag "Ask" foo))

これはtがyes、nilがno、fooが“ask”を意味することを示す。

(other value)

この選択肢は任意のLisp値にマッチできるが、ユーザーがこの選択肢を選択したら値valueが選択される。

otherは主にchoiceの最後の要素に使用される。たとえば、

(choice (const :tag "Yes" t)
        (const :tag "No" nil)
        (other :tag "Ask" foo))

これはtがyes、nilがno、それ以外は“ask”を意味することを示す。ユーザーが選択肢メニューから‘Ask’を選択したら、値fooが指定される。しかしその他の値(tnilfooを除く)ならfooと同様に‘Ask’が表示される。

(function-item function)

constと同様だが値が関数のときに使用される。これはドキュメント文字列も関数名と同じように表示する。ドキュメント文字列は:docで指定した文字列かfunction自身のドキュメント文字列。

(variable-item variable)

constと同様だが値が変数名のときに使用される。これはドキュメント文字列も変数名と同じように表示する。ドキュメント文字列は:docで指定した文字列かvariable自身のドキュメント文字列。

(set types…)

値はリストでなければならず指定されたtypesのいずれかにマッチしなければならない。

これはカスタマイゼーションバッファーではチェックリストとして表示されるので、typesはそれぞれ対応する要素を1つ、あるいは要素をもたない。同じ1つのtypesにマッチするような、異なる2つの要素を指定することはできない。たとえば(set integer symbol)はリスト内で1つの整数、および/または1つのシンボルが許容されて、複数の整数や複数のシンボルは許容されない。結果としてset内でintegerのような特化していない型を使用するのは稀である。

以下のようにconst型はset内のtypesでよく使用される:

(set (const :bold) (const :italic))

alist内で利用できる要素を示すために使用されることもある:

(set (cons :tag "Height" (const height) integer)
     (cons :tag "Width" (const width) integer))

これによりユーザーにオプションでheightとwidthの値を指定させることができる。

(repeat element-type)

値はリストでなければならず、リストの各要素は型element-typeに適合しなければならない。カスタマイゼーションバッファーでは要素のリストとして表示され、‘[INS]’と‘[DEL]’ボタンで要素の追加や削除が行われる。

(restricted-sexp :match-alternatives criteria)

これはもっとも汎用的な複合型の構築方法である。値はcriteriaを満足する任意のLispオブジェクト。criteriaはリストで、リストの各要素は以下のうちのいずれかを満たす必要がある:

  • 述語 — つまり引数は1つで、引数に応じてnilか非nilのどちらかをリターンする関数。リスト内での述語の使用により、その述語が非nilをリターンするようなオブジェクトが許されることを意味する。
  • クォートされた定数 — つまり'object。リスト内でこの要素はobject自身が許容される値であることを示す。

たとえば、

(restricted-sexp :match-alternatives
                 (integerp 't 'nil))

これは整数、tnilを正当な値として受け入れる。

カスタマイゼーションバッファーは適切な値をそれらの入力構文de表示して、ユーザーはこれらをテキストとして編集できる。

以下は複合型でキーワード/値ペアーとして使用できるキーワードのテーブルです:

:tag tag

tagはユーザーとのコミュニケーションのために、その候補の名前として使用される。choice内に出現する型にたいして有用。

:match-alternatives criteria

criteriaは可能な値とのマッチに使用される。restricted-sexp内でのみ有用。

:args argument-list

型構築の引数としてargument-listの要素を使用する。たとえば(const :args (foo))(const foo)と等価である。明示的に:argsと記述する必要があるのは稀である。なぜなら最後のキーワード/値ペアーの後に続くものは何であれ、引数として認識されるからである。


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

15.4.3 リストへのスプライス

:inline機能により可変個の要素を、カスタマイゼーション型のlistvectorの途中にスプライス(splice: 継ぎ足す)することができます。listvector記述を含む型にたいして:inline tを追加することによってこれを使用します。

listvector型の仕様は、通常は単一の要素型を表します。しかしエントリーが:inline tを含むなら、マッチする値は含まれるシーケンスに直接マージされます。たとえばエントリーが3要素のリストにマッチするなら、全体が3要素のシーケンスになります。これはバッククォート構文(バッククォートを参照)の‘,@’に類似しています。

たとえば最初の要素がbazで、残りの引数は0個以上のfoobarでなければならないようなリストを指定するには、以下のカスタマイゼーション型を使用します:

(list (const baz) (set :inline t (const foo) (const bar)))

これは(baz)(baz foo)(baz bar)(baz foo bar)のような値にマッチします。

要素の型がchoiceなら、choice自身の中で:inlineを使用せずに、choiceの選択肢(の一部)の中で使用します。たとえば最初がファイル名で始まり、その後にシンボルtか2つの文字列を続けなければならないようなリストにマッチさせるには、以下のカスタマイゼーション型を使用します:

(list file
      (choice (const t)
              (list :inline t string string)))

選択においてユーザーが選択肢の1つ目を選んだ場合はリスト全体が2つの要素をもち、2つ目の要素はtになります。ユーザーが2つ目の候補を選んだ場合にはリスト全体が3つの要素をもち、2つ目と3つ目の要素は文字列でなければなりません。

ウィジェットは:match-inline要素でインライン値がウィジェットにマッチするかどうかを告げる述語を指定できます。


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

15.4.4 型キーワード

カスタマイゼーション型内の型名シンボルの後にキーワード/引数ペアーを指定できます。以下は使用できるキーワードとそれらの意味です:

:value default

デフォルト値を提供する。

その候補にたいしてnilが有効な値でなければ、:valueに有効なデフォルトを指定することが必須となる。

choiceの内部の選択肢として出現する型にたいしてこれを使用するなら、ユーザーがカスタマイゼーションバッファー内のメニューでその選択肢を選択したときに使用するデフォルト値を最初に指定する。

もちろんオプションの実際の値がこの選択肢に適合するなら、defaultではなく実際の値が表示される。

:format format-string

この文字列はその型に対応する値を記述するために、バッファーに挿入される。format-string内では以下の‘%’エスケープが利用できる:

%[button%]

ボタンとしてマークされたテキストbuttonを表示する。:action属性はユーザーがそれを呼び出したときに、そのボタンが何を行うか指定する。この属性の値は2つの引数 — ボタンが表示されるウィジェットとイベント — を受け取る関数である。

異なるアクションを行う2つの異なるボタンを指定する方法はない。

%{sample%}

:sample-faceにより指定されたスペシャルフェイス内のsampleを表示する。

%v

そのアイテムの値を代替えする。その値がどのように表示されるかはアイテムの種類と、(カスタマイゼーション型にたいしては)カスタマイゼーション型にに依存する。

%d

そのアイテムのドキュメント文字列を代替えする。

%h

%d’と同様だが、ドキュメント文字列が複数行なら、ドキュメント文字列全体か最初の行だけかを制御するボタンを追加する。

%t

その位置でタグに置き換える。:tagキーワードでタグを指定する。

%%

リテラル‘%’を表示する。

:action action

ユーザーがボタンをクリックしたらactionを実行する。

:button-face face

%[…%]’で表示されたボタンテキストにたいして、フェイスface(フェイス名、またはフェイス名のリスト)を使用する。

:button-prefix prefix
:button-suffix suffix

これらはボタンの前か後に表示されるテキストを指定する。以下が指定できる:

nil

テキストは挿入されない。

文字列

その文字列がリテラルに挿入される。

シンボル

そのシンボルの値が使用される。

:tag tag

この型に対応する値(または値の一部)にたいするタグとしてtag(文字列)を使用する。

:doc doc

この型に対応する値(か値の一部)にたいするドキュメント文字列としてdocを使用する。これが機能するためには:formatにたいする値を指定して、その値にたいして‘%d’か‘%h’を使用しなければならない。

ある型にたいしてドキュメント文字列を指定するのはchoice内の選択肢の型や、他の複合型の一部について情報を提供するのが通常の理由。

:help-echo motion-doc

widget-forwardwidget-backwardでこのアイテムに移動したときに、エコーエリアに文字列motion-docを表示する。さらにマウスのhelp-echo文字列としてmotion-docが使用され、これには実際には」ヘルプ文字列を生成するために評価される関数かフォームを指定できる。もし関数ならそれは1つの引数(そのウィジェット)で呼び出される。

:match function

値がその型にマッチするか判断する方法を指定する。対応する値functionは2つの引数(ウィジェットと値)を受け取る関数であり、値が適切なら非nilをリターンすること。

:match-inline function

インライン値がその型にマッチするか判断する方法を指定する。対応する値functionは2つの引数(ウィジェットとインライン値)を受け取る関数であり、値が適切なら非nilをリターンすること。インライン値に関する詳細な情報はリストへのスプライスを参照のこと。

:validate function

入力にたいして検証を行う関数を指定する。functionは引数としてウィジェットを受け取り、そのウィジェットのカレント値がウィジェットにたいして有効ならnilをリターンすること。それ以外なら無効なデータを含むウィジェットをリターンして、そのウィジェットの:errorプロパティに、そのエラーを記述する文字列をセットすること。

:type-error string

stringは値がなぜ:match関数で判定されるような値にマッチしないかを説明する文字列であること。:match関数がnilをリターンした際には、ウィジェットの:errorプロパティがstringにセットされる。


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

15.4.5 新たな型の定義

前のセクションでは、defcustomにたいして型の詳細な仕様を作成する方法を説明しました。そのような型仕様に名前を与えたい場合があるかもしれません。理解しやすいケースとしては、多くのユーザーオプションに同じ型を使用する場合などです。各オプションにたいして仕様を繰り返すよりその型に名前を与えて、defcustomそれぞれにその名前を使用することができます。他にもユーザーオプションの値が再帰的なデータ構造のケースがあります。あるデータ型がそれ自身を参照できるようにするためには、それが名前をもつ必要があります。

カスタマイゼーション型はウィジェットとして実装されているめ、新しいカスタマイゼーション型を定義するには、新たにウィジェット型を定義します。ここではウィジェットインターフェイスの詳細は説明しません。Introduction in The Emacs Widget Libraryを参照してください。かわりにシンプルな例を用いて、カスタマイゼーション型を新たに定義するために必要な最小限の機能について説明します。

(define-widget 'binary-tree-of-string 'lazy
  "A binary tree made of cons-cells and strings."
  :offset 4
  :tag "Node"
  :type '(choice (string :tag "Leaf" :value "")
                 (cons :tag "Interior"
                       :value ("" . "")
                       binary-tree-of-string
                       binary-tree-of-string)))

(defcustom foo-bar ""
  "Sample variable holding a binary tree of strings."
  :type 'binary-tree-of-string)

新しいウィジェットを定義するための関数はdefine-widgetと呼ばれます。1つ目の引数は新たなウィジェット型にしたいシンボルです。2つ目の引数は既存のウィジェットを表すシンボルで、新しいウィジェットではこの既存のウィジェットと異なる部分を定義することになります。新たなカスタマイゼーション型を定義する目的にたいしてはlazyウィジェットが最適です。なぜならこれはdefcustomにたいするキーワード引数と同じ構文と名前でキーワード引数:typeを受け取るからです。3つ目の引数は新しいウィジェットにたいするドキュメント文字列です。この文字列はM-x widget-browse RET binary-tree-of-string RETコマンドで参照することができます。

これらの必須の引数の後にキーワード引数が続きます。もっとも重要なのは:typeで、これはこのウィジェットにマッチさせたいデータ型を表します。上記の例ではbinary-tree-of-stringは文字列、またはcarとcdrがbinary-tree-of-stringであるようなコンスセルです。この定義中でのウィジェット型への参照に注意してください。:tag属性はユーザーインターフェイスでウィジェット名となる文字列、:offset引数はカスタマイゼーションバッファーでのツリー構造の外観で,子ノードと関連する親ノードの間に4つのスペースを確保します。

defcustomは通常のカスタマイゼーション型に使用される方法で新しいウィジェットを表示します。

lazyという名前の由来は、他のウィジェットではそれらがバッファーでインスタンス化されるとき、他の合成されたウィジェットが下位のウィジェットを内部形式に変換するからです。この変換は再帰的なので、下位のウィジェットはそれら自身の下位ウィジェットへと変換されます。データ構造自体が再帰的なら、その変換は無限再帰(infinite recursion)となります。lazyウィジェットは、:type引数を必要なときだけ変換することによってこの再帰を防ぎます。


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

15.5 カスタマイゼーションの適用

以下の関数には変数とフェイスにたいして、そのユーザーのカスタマイゼーション設定をインストールする役目をもちます。それらの関数はユーザーがCustomizeインターフェイスで‘Save for future sessions’を呼び出したとき、次回のEmacs起動時に評価されるようにcustom-set-variablesフォーム、および/またはcustom-set-facesフォームがカスタムファイルに書き込まれることによって効果をもちます。

Function: custom-set-variables &rest args

この関数はargsにより指定された変数のカスタマイゼーションをインストールする。args内の引数はそれぞれ、以下のようなフォームであること

(var expression [now [request [comment]]])

varは変数名(シンボル)、expressionはカスタマイズされた値に評価される式である。

このcustom-set-variables呼び出しより前にvarにたいしてdefcustomフォームが評価されたら即座にexpressionが評価されて、その変数の値にその結果がセットされる。それ以外ならその変数のsaved-valueプロパティにexpressionが格納されて、これに関係するdefcustomが呼び出されたとき(通常はその変数を定義するライブラリーがEmacsにロードされたとき)に評価される。

nowrequestcommentエントリーは内部的な使用に限られており、省略されるかもしれない。nowがもし非nilなら、たとえその変数のdefcustomフォームが評価されていなくても、その変数の値がそのときセットされる。requestは即座にロードされる機能のリストである(名前つき機能を参照)。commentはそのカスタマイゼーションを説明する文字列。

Function: custom-set-faces &rest args

この関数はargsにより指定されたフェイスのカスタマイゼーションをインストールする。args内の引数はそれぞれ以下のようなフォームであること

(face spec [now [comment]])

faceはフェイス名(シンボル)、specはそのフェイスにたいするカスタマイズされたフェイス仕様(フェイスの定義を参照)。

nowrequestcommentエントリーは内部的な使用に限られており、省略されるかもしれない。nowがもし非nilなら、たとえdeffaceフォームが評価されていなくても、そのフェイス仕様がそのときセットされる。commentはそのカスタマイズを説明する文字列。


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

15.6 Customテーマ

Customテーマ(Custom themes)とはユニットとして有効や無効にできるセッティングのコレクションです。Custom Themes in The GNU Emacs Manualを参照してください。CustomテーマはそれぞれEmacs Lispソースファイルにより定義され、それらはこのセクションで説明する慣習にしたがう必要があります(Customテーマを手作業で記述するかわりに、Customize風のインターフェイスを使用して作成することもできる。Creating Custom Themes in The GNU Emacs Manualを参照)。

Customテーマファイルはfoo-theme.elのように命名すること。ここでfooはテーマの名前。このファイルでの最初のLispフォームはdefthemeの呼び出しで、最後のフォームはprovide-themeにすること。

Macro: deftheme theme &optional doc &rest properties

このマクロはCustomテーマの名前としてtheme(シンボル)を宣言する。オプション引数docは、そのテーマを説明する文字列であること。この文字列はユーザーがdescribe-themeコマンドを呼び出したり、‘*Custom Themes*’バッファーで?をタイプしたときに表示される。残りの引数propertiesテーマの属性を含んだプロパティリストを渡すために使用される。

サポートされている属性は以下のとおり:

:family

テーマがどの“ファミリー(family)”に属すかを示すシンボル。テーマのファミリーとは、フレームのバックグラウンドのライト(light: 明るい)とダーク(dark: 暗い)を意図したフェイスカラーのように、似ているがマイナーな側面は異なるテーマセットのこと。

:kind

シンボル。テーマが有効かつこのプロパティの値がcolor-schemeなら、テーマを切り替えるためにコマンドtheme-choose-variantは同じファミリーに属する他のの利用可能なテーマを探す。現在のところ他の値は指定されておらず、使用するべきではない。

:background-mode

lightdarkいずれかのシンボル。この属性は現在のところ使用されていないが依然として指定はする必要がある。

2つの特別なテーマ名は禁止されている(使用するとエラーになる)。userはそのユーザーの直接的なカスタマイズ設定を格納するためのダミーのテーマである。そしchangedはCustomizeシステムの外部で行われた変更を格納するためのダミーのテーマである。

Macro: provide-theme theme

このマクロは完全に仕様が定められたテーマ名themeを宣言する。

defthemeprovide-themeの違いは、そのテーマセッティングを規定するLispフォームです(通常はcustom-theme-set-variablesの呼び出し、および/またはcustom-theme-set-facesの呼び出し)。

Function: custom-theme-set-variables theme &rest args

この関数はCustomテーマthemeの変数のセッティングを規定する。themeはシンボル。args内の各引数はフォームのリスト。

(var expression [now [request [comment]]])

ここでリストエントリーはcustom-set-variablesのときと同じ意味をもつ。カスタマイゼーションの適用を参照のこと。

Function: custom-theme-set-faces theme &rest args

この関数はCustomテーマthemeのフェイスのセッティングを規定する。themeはシンボル。args内の各引数はフォームのリスト。

(face spec [now [comment]])

ここでリストエントリーはcustom-set-facesのときと同じ意味をもつ。カスタマイゼーションの適用を参照のこと。

原則的にテーマファイルは他のLispフォームを含むこともでき、それらはそのテーマがロードされるときに評価されるでしょうが、これは悪いフォームです。悪意のあるコードを含むテーマのロードを防ぐために最初に非ビルトインテーマをロードする前に、Emacsはソースファイルを表示してユーザーに確認を求めます。このようにテーマは通常のバイトコンパイルは行わずに、Emacsがテーマをロードする際には通常はソースファイルが優先されます。

以下の関数は、テーマをプログラム的に有効または無効にするのに有用です:

Function: custom-theme-p theme

この関数はtheme(シンボル)がCustomテーマの名前(たとえばそのテーマが有効かどうかにかかわらず、CustomテーマがEmacsにロードされている)なら非nilをリターンする。それ以外はnilをリターンする。

Variable: custom-known-themes

この変数の値はEmacsにロードされたテーマのリストである。テーマはそれぞれLispシンボル(テーマ名)により表される。この変数のデフォルト値は2つのダミーテーマ(user changed)を含む。changedテーマにはCustomテーマが適用される前に行われたセッティング(たとえばCustomの外部での変数のセット)が格納されている。userテーマにはそのユーザーがカスタマイズして保存したセッティングが格納されている。defthemeマクロで宣言されたすべての追加テーマは、このリストの先頭に追加される。

Command: load-theme theme &optional no-confirm no-enable

この関数はthemeという名前のCustomテーマを、変数custom-theme-load-pathで指定されたディレクトリーから探して、ソースファイルからロードする。Custom Themes in The GNU Emacs Manualを参照のこと。またそのテーマの変数とフェイスのセッティングが効果を及ぼすようにテーマをenablesにする(オプション引数no-enablenilの場合)。さらにオプション引数no-confirmnilなら、そのテーマをロードする前にユーザーに確認を求める。

Function: require-theme feature &optional noerror

この関数はfeatureをprovideするファイルをcustom-theme-load-pathから検索してロードする。これは関数require (名前つき機能を参照)と似ているが、load-path (ライブラリー検索を参照)ではなくcustom-theme-load-pathを検索する点が異なるこれはLispサポートファイルおロードを要するCustomテーマにおいて、requireが不適切な際に有用かもしれない。

カレントのEmacsセッションにおいてfeaturepに照らしてfeature (シンボル)がまだ与えられていなければ、require-themecustom-theme-load-pathで指定されたディレクトリー内から、featureに‘.elc’、次に‘.el’のサフィックスを追加した名前をもつファイルを検索する。

featureをprovideするファイルが見つかりロードに成功すると、require-themefeatureをリターンする。オプション引数noerrorは検索やロードの失敗時に何が発生するかを決定する。nilならこの関数はエラーをシグナルして、それ以外ならnilをリターンする。ファイルのロードには成功してもfeatureをlprovideしない場合には、require-themeはエラーをシグナルする(これは抑止不可)。

Command: enable-theme theme

この関数はthemeという名前のCustomテーマを有効にする。そのようなテーマがロードされていなければ、エラーをシグナルする。

Command: disable-theme theme

この関数はthemeという名前のCustomテーマを無効にする。テーマはロードされたまま残るので、続けてenable-themeを呼び出せばテーマは再び有効になる。


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

16 ロード

Lispコードのファイルをロードすることは、その内容をLispオブジェクト形式でLisp環境に取り込むことを意味します。Emacsはファイルを探してオープンして、テキストを読み込んで各フォームを評価してから、そのファイルをクローズします。そのようなファイルはLispライブラリー(Lisp library)とも呼ばれます。

eval-buffer関数がバッファー内のすべての式を評価するのと同様に、load関数はファイル内のすべての式を評価します。異なるのはEmacsバッファー内のテキストではなく、load関数はディスク上で見つかったファイル内のテキストを読み込んで評価することです。

ロードされたファイルは、ソースコードかバイトコンパイルされたコードとしてLisp式を含んでいなければなりません。このファイル内の各フォームはトップレベルフォーム(top-level form)と呼ばれます。ロード可能なファイル内のフォームにたいする特別なフォーマットはありません。ファイル内のフォームはどれも同じように直接バッファーにタイプされて、そこで評価されるでしょう(実際ほとんどのコードはこの方法でテストされる)。多くの場合はそのフォームは関数定義と変数定義です。

Emacsはコンパイルされたダイナミックモジュールも同様にロードできます。これはEmacs Lispプログラム内で、Emacs Lispで記述されたパッケージと同様に使用するための、追加機能を提供する共有ライブラリーです。ダイナミックモジュールのロード時に、Emacsはそのモジュールが実装する必要がある特殊な名前の初期化関数を呼び出して、Emacs Lispプログラムに追加の関数と変数を公開します。

特定のEmacsプリミティブで必要となるとあらかじめ判明している外部ライブラリーのオンデマンドローディングについては、動的にロードされるライブラリーを参照してください。


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

16.1 プログラムがロードを行う方法

Emacs Lispにはロードのためのインターフェイスがいくつかあります。たとえばautoloadはファイル内で定義された関数にたいしてプレースホルダーとなるオブジェクトを作成します。この関数はオートロードされる関数を呼び出すために、ファイルからその関数の実際の定義の取得を試みます(autoloadを参照)。requireはファイルがまだロードされていない場合にファイルをロードします(名前つき機能を参照)。これらすべての関数は処理を行うために最終的にloadを呼び出します。

Function: load filename &optional missing-ok nomessage nosuffix must-suffix

この関数はLispコードのファイルを見つけてオープンして、その中のすべてのフォームを評価してそのファイルをクローズする。

loadはまずファイルを見つけるために、filename.elcという名前、つまりfilenameに拡張子‘.elc’を足した名前のファイルを探す。このようなファイルが存在して、かつネイティブコンパイル(Lispからネイティブコードへのコンパイルを参照)のサポートつきでEmacsがコンパイルされていれば、loadは対応する‘.eln’を探して、見つかったらfilename.elcのかわりにそのファイルを、見つからなければfilename.elcをロードする(そして見つからなかった‘.eln’を生成するためにバックグラウンドでネイティブコンパイルを開始してコンパイルしたファイルをロードする)。filename.elcというファイルが存在しなければ、loadfilename.elという名前のファイルを探す。このファイルが存在したらそれをロードする。Emacsがダイナミックモジュール(Emacsのダイナミックモジュールを参照)のサポートつきでコンパイルされていれば、、次にloadfilename.extという名前のファイルを探す。ここでextは共有ライブラリーのシステム依存のファイル名拡張子である(GNUおよびUnixシステムでは‘.so’)。最後に、もしこれらの名前がいずれも見つからなければ、loadは何も付け足さないfilenameという名前のファイルを探してそれが存在したらロードする(load関数にfilenameを認識する賢さはない。foo.el.elのような正しくない名前のファイルでも、(load "foo.el")を評価してそれを見つけてしまうだろう)。

Auto Compressionモードが有効(残念ながらデフォルトでは有効)なら、loadは他のファイル名を試みる前に圧縮されたバージョンのファイル名を探すのでファイルを見つけることができない。圧縮されたファイルが存在したら、それを解凍してロードする。loadはファイル名にjka-compr-load-suffixes内の各サフィックスを足して圧縮されたバージョンを探す。この変数の値は文字列のリストでなければならない。標準的な値は(".gz")

オプション引数nosuffixが非nilなら、loadはサフィックス‘.elc’と‘.el’のロードを試みない。この場合はロードしたいファイルの正確な名前を指定しなければならない。ただしAuto Compressionモードが有効ならloadは圧縮されたバージョンを探すために、jka-compr-load-suffixesを使用する。正確なファイル名を指定して、nosuffixtを使用することにより、foo.el.elのような名前のファイルにたいするロードの試みを抑止できる。

オプション引数must-suffixが非nilの場合、ロードに使用されるファイルの名前に明示的にディレクトリー名が含まれていなければ、loadはファイル名が‘.el’か‘.elc’、または共有ライブラリーの拡張子で終わること(もしかしたら圧縮による拡張子が付加されているかもしれない)を要求する。

オプションload-prefer-newerが非nilなら、loadはサフィックスを検索するとき、どんなファイル(‘.elc’、‘.el’等)であっても、もっとも最近変更されたファイルのバージョンを選択する。この場合には、ネイティブコンパイルされた‘.eln’があっても、loadはそれをロードしない。

filenamefoobaz/foo.barのような相対ファイル名なら、loadは変数load-pathを使用してそのファイルを探す。これはload-path内にリストされた各ディレクトリーにfilenameを追加して、最初に見つかった名前のマッチするファイルをロードする。デフォルトディレクトリーを意味するnilload-pathで措定されたときだけ、カレントデフォルトディレクトリーを試みる。loadload-path内の最初のディレクトリーで利用可能な3つのサフィックスすべてを試行してから、2つ目のディレクトリーで3つのサフィックスすべてを試行する、...というようにファイルを探す。ライブラリー検索を参照のこと。

最終的に見つかったファイル、およびEmacsがそのファイルを見つけたディレクトリーが何であれ、Emacsはそのファイル名を変数load-file-nameの値にセットする。

foo.elcfoo.elより古いと警告されたら、それはfoo.elのリコンパイルを考慮すべきことを意味する。バイトコンパイルを参照のこと。

(コンパイルされていない)ソースファイルをロードしたとき、Emacsがファイルをvisitしたときと同じようにloadは文字セットの変換を行う。コーディングシステムを参照のこと。

コンパイルされていないファイルをロードするとき、Emacsはそのファイルに含まれるすべてのマクロ(マクロを参照)を展開する。わたしたちはこれをeagerマクロ展開(eager macro expansion)と呼んでいる。(関連するコードを実行するまで展開を延期しないで)これを行うことにより、コンパイルされていないコードの実行スピードが明らかに向上する。循環参照によりこのマクロ展開を行うことができないときもある。これの一番簡単な例は、ロードしようとしているファイルが他のファイルで定義されているマクロを参照しているが、そのファイルはロードしようとしているファイルを必要としている場合である。Emacsは問題の詳細を与えるために、(‘Eager macro-expansion skipped due to cycle…’)というエラーを報告するだろう。これが起こらないようにするためには、コードのリストラクチャリング(restructuring: 再構築)が必要となる。コンパイル済みのファイルのロードではマクロの展開は行われない(コンパイル時に既に行われているため)。マクロとバイトコンパイルを参照のこと。

nomessageが非nilでなければ、エコーエリアに‘Loading foo...’や‘Loading foo...done’のようなメッセージがロードの間に表示される。ネイティブコンパイルされた‘.eln’ファイルをロードしたら、メッセージでその旨を伝える。

ファイルをロードする間のハンドルされないエラーはロードを終了させる。autoloadのためのロードの場合、ロードの間に定義された任意の関数定義は元に戻される。

loadがロードするファイルを見つけられなかった場合には、通常は(‘Cannot open load file filename’のメッセージとともに) file-errorがシグナルされる。しかしmissing-okが非nilならloadは単にnilをリターンする。

式の読み取りにたいしてloadreadのかわりに使用する関数を指定するために、変数load-read-functionを使用できる。以下を参照されたい。

ファイルが正常にロードされたら、loadtをリターンする。

Command: load-file filename

このコマンドはファイルfilenameをロードする。filenameが相対ファイル名のなら、それはカレントデフォルトディレクトリーを指定したとみなされる。このコマンドはload-pathを使用せず、サフィックスの追加もしない。しかし(Auto Compressionモードが有効なら)圧縮されたバージョンの検索を行う。ロードするファイル名を正確に指定したければ、このコマンドを使用すること。

Command: load-library library

このコマンドはlibraryという名前のライブラリーをロードする。このコマンドは引数を読み取る方法がインタラクティブであることを除きloadと同じ。Lisp Libraries in The GNU Emacs Manualを参照のこと。

Variable: load-in-progress

この変数はEmacsがファイルをロード中なら非nil、それ以外はnilである。

Variable: load-file-name

このセクションの最初に説明した検索でEmacsがファイルを見つけて、そのファイルをロード中のとき、この変数の値はそのファイルの名前である。

Variable: load-read-function

この変数はloadeval-regionが式を読み取るために、readのかわりに使用する関数を指定する。指定する関数はreadと同様、引数が1つの関数であること。

デフォルトではこの変数の値はread入力関数を参照のこと。

この変数を使用するかわりに別の新たな方法を使用するほうが明確である。それはeval-regionread-function引数にその関数を渡す方法である。Evalを参照のこと。

Emacsのビルドでloadがどのように使用されているかについての情報は、Emacsのビルドを参照のこと。


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

16.2 ロードでの拡張子

ここではloadが試行するサフィックスについて、技術的な詳細を説明します。

Variable: load-suffixes

これは(ソースまたはコンパイル済みの)Emacs Lispファイルを示すサフィックスのリストである。空の文字列が含まないこと。loadは指定されたファイル名にLispファイルのサフィックスを追加するときに、これらのサフィックスを使用する。標準的な値は(".elc" ".el")で、これは前のセクションで説明した振る舞いとなる。

Variable: load-file-rep-suffixes

これは同じファイルにたいして異なる表現を示すサフィックスのリストである。このリストは空の文字列から開始されること。loadはファイルを検索するときは、他のファイルを検索する前にこのリストのサフィックスを順番にファイル名に追加する。

Auto Compressionモードを有効にすることによりjka-compr-load-suffixesのサフィックスがこのリストに追加され、無効にすると再びリストから取り除かれる。load-file-rep-suffixesの標準的な値は、Auto Compressionモードが無効なら("")jka-compr-load-suffixesの標準的な値が(".gz")であることを考慮すると、Auto Compressionモードが有効な場合のload-file-rep-suffixesの標準的な値は("" ".gz")である。

Function: get-load-suffixes

この関数はmust-suffix引数が非nilのときは、loadが試みるべきすべてのサフィックスを順番にしたがったリストでリターンする。この関数はload-suffixesload-file-rep-suffixesの両方を考慮する。load-suffixesjka-compr-load-suffixesload-file-rep-suffixesがすべて標準的な値の場合、この関数はAuto Compressionモードが有効なら(".elc" ".elc.gz" ".el" ".el.gz")、無効なら(".elc" ".el")をリターンする。

まとめると、loadは通常まず(get-load-suffixes)の値のサフィックスを試み、次にload-file-rep-suffixesを試みる。nosuffixが非nilなら前者がスキップされ、must-suffixが非nilなら後者がスキップされる。

User Option: load-prefer-newer

このオプションが非nilなら、ファイルが見つかった最初のサフィックスで停止せずに、loadはすべてのサフィックスをテストして、一番新しいファイルを使用する。


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

16.4 非ASCII文字のロード

Emacs Lispプログラムが非ASCII文字の文字列定数を含むとき、Emacsはそれらをユニバイト文字列かマルチバイト文字列のいずれかで表現する場合があります。どちらの表現が使用されるかは、そのファイルがどのようにEmacsに読み込まれたかに依存します。マルチバイト表現へのデコーディングとともに読み込まれた場合、Lispプログラム内のテキストはマルチバイトのテキストとなり、ファイル内の文字列定数はマルチバイト文字列になります。(たとえば)Latin-1文字を含むファイルをデコーディングなしで読み込むと、そのプログラムのテキストはユニバイトのテキストとなり、ファイル内の文字列定数はユニバイト文字列になります。コーディングシステムを参照してください。

マルチバイト文字列がユニバイトバッファーに挿入されるときは自動的にユニバイトに変換されるため、大部分のEmacs Lispプログラムにおいて、マルチバイト文字列が非ASCII文字列であるという事実を意識させないようにするべきです。しかしこれが行われことにより違いが生じる場合には、ローカル変数セクションに‘coding: raw-text’と記述することにより、特定のLispファイルを強制的にユニバイトとして解釈させることができます。この識別子により、そのファイルは無条件でユニバイトとして解釈されます。これは?vliteralで記述された非ASCII文字にキーバインドするとき重要になります。


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

16.5 autoload

オートロード(autoload: 自動ロード)の機能により、定義されているファイルをロードすることなく関数やマクロの存在を登録できます。関数の最初の呼び出しで実際の定義およびその他の関連するコードをインストールするために適切なライブラリーを自動的にロードして、すべてがすでにロードされていたかのように実際の定義を実行します。関数やマクロのドキュメントの参照(ドキュメントの基礎を参照)、変数名や関数名の補完(以下のプレフィックスによるautoloadを参照)によってもオートロードが発生します。

オートロードされた関数をセットアップするには2つの方法があります。それはautoloadを呼び出す方法と、ソースの実際の定義の前に“マジック”コメントを記述する方法です。autoloadはオートロードのための低レベルのプリミティブです。任意のLispプログラムが、任意のタイミングでautoloadを呼び出すことができます。Emacsとともにインストールされるパッケージにとって、マジックコメントは関数をオートロードできるようににするための一番便利な方法です。そのコメント自身は何も行いませんが、コマンドloaddefs-generateにたいするガイドの役目を果たします。このコマンドはautoloadの呼び出しを構築して、Emacsビルド時に実行されるようにアレンジします。

Function: autoload function filename &optional docstring interactive type

この関数はfilenameから自動的にロードされるように、functionという名前の関数(かマクロ)を定義する。文字列filenameにはfunctionの実際の定義を取得するファイルを指定する。

filenameがディレクトリー名、またはサフィックス.el.elcのいずれも含まなければ、この関数はこれらのサフィックスのいずれかを強制的に追加して、サフィックスがないただのfilenameという名前のファイルはロードしない(変数load-suffixesにより要求される正確なサフィックスが指定される)。

引数docstringはその関数のドキュメント文字列である。autoloadの呼び出しでドキュメント文字列を指定することにより、その関数の実際の定義をロードせずにドキュメントを見ることが可能になる。この引数の値は通常は関数定義のドキュメント文字列と等しいこと。もし等しくなければ、その関数定義のドキュメント文字列がロード時に有効になる。

interactiveが非nilなら、その関数はインタラクティブに呼び出すことが可能になる。これによりfunctionの実際の定義をロードせずに、M-xによる補完が機能するようになる。ここでは完全なインタラクティブ仕様は与えられない。完全な仕様はユーザーが実際にfunctionを呼び出すまで必要ない。ユーザーが実際に呼び出したときに、実際の定義がロードされる。

interactiveがリストなら、そのコマンドを適用可能なモードのリストとして解釈される。

普通の関数と同様、マクロとキーマップをオートロードできる。functionが実際にはマクロならtypemacro、キーマップのならtypekeymapを指定する。Emacsのさまざまな部分では、実際の定義をロードせずにこれらの情報を知ることが必要とされる。

オートロードされたキーマップは、あるプレフィクスキーがシンボルfunctionにバインドされているとき、キーを探す間に自動的にロードされる。そのキーマップにたいする他の類のアクセスではオートロードは発生しない。特にLispプログラムが変数の値からそのキーマップを取得してkeymap-setを呼び出した場合には、たとえその変数の名前がシンボルfunctionと同じであってもオートロードは発生しない。

functionが非voidのオートロードされたオブジェクトではない関数定義をもつなら、その関数は何も行わずにnilをリターンする。それ以外ならオートロードされたオブジェクト(autoload型を参照)を作成して、それをfunctionにたいする関数定義として格納する。オートロードされたオブジェクトは以下の形式をもつ:

(autoload filename docstring interactive type)

たとえば、

(symbol-function 'run-prolog)
     ⇒ (autoload "prolog" 169681 t nil)

このような場合、"prolog"はロードするファイルの名前、169681はemacs/etc/DOCファイル(ドキュメントの基礎を参照)内のドキュメント文字列への参照で、tはその関数がインタラクティブであること、nilはそれがマクロやキーマップでないことを意味する。

Function: autoloadp object

この関数はobjectがオートロードされたオブジェクトなら非nilをリターンする。たとえばrun-prologがオートロードされたオブジェクトかチェックするには以下を評価する

(autoloadp (symbol-function 'run-prolog))

オートロードされたファイルは、通常は他の定義を含み1つ以上の機能を必要としたり、あるいは提供するかもしれません。(内容の評価でのエラーにより)そのファイルが完全にロードされていなければ、そのロードの間に行われた関数定義やprovideの呼び出しはアンドゥされます。これはそのファイルからオートロードされる関数にたいして再度呼び出しを試みたときに、そのファイルを確実に再ロードさせるためです。こうしないと、そのファイル内のいくつかの関数はアボートしたロードにより定義されていて、それらはロードされない修正後のファイルで提供される正しいサブルーチンを欠くため、正しく機能しないからです。

オートロードされたファイルが意図したLisp関数またはマクロの定義に失敗すると、データ"Autoloading failed to define function function-name"とともにエラーがシグナルされます。

オートロードのマジックコメント(autoload cookieとも呼ばれる)は、オートロード可能なソースファイル内の実際の定義の直前にある、‘;;;###autoload’だけの行から構成されます。関数loaddefs-generateは、対応するautoload呼び出しをloaddefs.el内に書き込みます(autoload cookieとなる文字列とloaddefs-generateで生成されるファイルの名前は、上述のデフォルトから変更可能です。以下参照)。Emacsのビルドではloaddefs.elをロードするためにautoloadを呼び出します。

このマジックコメントは任意の種類のフォームをloaddefs.el内にコピーできます。このマジックコメントに続くフォームはそのままコピーされます。しかしオートロード機能が特別に処理するフォームの場合は除外されます(たとえばautoload内への変換)。以下はそのままコピーされないフォームです:

関数や関数風オブジェクトの定義:

defundefmacrocl-defuncl-defmacro(Argument Lists in Common Lisp Extensionsを参照)、およびdefine-overloadable-function (mode-local.el内のコメントを参照)も該当する。

メジャーモードとマイナーモードの定義:

define-minor-modedefine-globalized-minor-modedefine-generic-modedefine-derived-modeeasy-mmode-define-minor-modeeasy-mmode-define-global-modedefine-compilation-modedefine-global-minor-mode

その他のタイプの定義:

defcustomdefgroupdefthemedefclass (EIEIO in EIEIOを参照)、およびdefine-skeleton (Autotyping in Autotypingを参照)。

ビルド時にそのファイル自身をロードするときにフォームを実行しないようにするためにマジックコメントを使用することもできます。これを行なうにはマジックコメントと同じ行にフォームを記述します。これはコメントなのでソースファイルをロードするときには何も行いません。ただしビルド時に実行されたEmacsでは、loaddefs-generateloaddefs.elにコピーします。

以下はマジックコメントによるオートロードのためにdoctorを準備する例です:

;;;###autoload
(defun doctor ()
  "Switch to *doctor* buffer and start giving psychotherapy."
  (interactive)
  (switch-to-buffer "*doctor*")
  (doctor-mode))

これにより以下がloaddefs.el内に書き込まれます:

(autoload 'doctor "doctor" "\
Switch to *doctor* buffer and start giving psychotherapy.

\(fn)" t nil)

ダブルクォートの直後のバックスラッシュと改行は、loaddefs.elのように事前ロードされる未コンパイルのLispファイルだけに用いられる慣習です。これらはetc/DOCファイルにドキュメント文字列を配置するよう指示する文字です。Emacsのビルド、およびlib-src/make-docfile.cのコメントも参照してください。loaddefs.elは編集用ではありませんが、ある程度は人が読みやすいように保とうと努めています。たとえばdefvarの値の中のコントロール文字をエスケープしたり、行が長くならないようにdoc文字列のダブルクォーテーションの直後にはバックスラッシュと改行を挿入するようにしています。ドキュメント文字列の使い方(usage part)の中の‘(fn)’は、種々のヘルプ関数(ヘルプ関数を参照)が表示するときにその関数の名前に置き換えられます。

関数定義手法として既知ではなく、認められてもいないような、通常とは異なるマクロにより関数定義を記述した場合、通常のオートロードのマジックコメントの使用によって定義全体がloaddefs.el内にコピーされるでしょう。これは期待した動作ではありません。かわりに以下を記述することにより、意図したautoload呼び出しをloaddefs.el内に配置することができます。

;;;###autoload (autoload 'foo "myfile")
(mydefunmacro foo
  ...)

autoload cookieとしてデフォルト以外の文字列を使用して、デフォルトのloaddefs.elとは異なるファイル内に対応するオートロード呼び出しを記述できます。これを制御するためにEmacsは2つの変数を提供します:

Variable: lisp-mode-autoload-regexp

この定数の値はautoload cookieにマッチさせるregexp。loaddefs-generateはそのcookieの後に続くLispフォームを、生成したautoloadファイルにコピーする。これは‘;;;###autoload’や‘;;;###calc-autoload’のようなコメントにマッチするだろう。

Variable: generated-autoload-file

この変数の値は、オートロード呼び出しが書き込まれるEmacs Lispファイルを命名する。デフォルト値はloaddefs.elだが、(たとえば.elファイル内のセクションLocal Variables))をオーバーライドできる。オートロードファイルは、フォームフィード文字で開始される終端を含んでいると仮定される。

以下の関数はオートロードオブジェクトにより指定されたライブラリーを明示的にロードするために使用されるかもしれません:

Function: autoload-do-load autoload &optional name macro-only

この関数はオートロードオブジェクトautoloadにより指定されたロードを処理する。オプション引数nameに非nilを指定するなら、関数値がautoloadとなるシンボルを指定すること。この場合、この関数のリターン値がそのシンボルの新しい関数値になる。オプション引数macro-onlyの値がmacroなら、この関数は関数ではなくマクロのロードだけを有効にする。


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

16.5.1 プレフィックスによるautoload

コマンドdescribe-variabledescribe-functionの補完の間に、Emacsは補完されるプレフィクスにマッチする定義を含むファイルのロードを試みます。変数definition-prefixesにはプレフィクスとそれをロードするファイルのリストをマップするハッシュテーブルが保持されています。このマッピングのエントリーは、loaddefs-generate (autoloadを参照)が生成するregister-definition-prefixesを呼び出すことによって追加されます。ロードする価値のある定義を含んでいないファイル(たとえばテストファイル)ではファイルローカル変数としてautoload-compute-prefixesnilにセットする必要があります。


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

16.5.2 autoloadを使用するケース

本当に必要でなければautoloadコメントを追加しないでください。コードをautoloadすることは、それが常にグローバルに可視になることを意味しています。一度あるアイテムがautoloadされれば、autoload以前の状態(autoload後には明示的なロードなしで通常のように使用できる)に戻るための互換性のある手段はありません。

  • autoloadするアイテムとしてもっとも一般的なライブラリーにたいするインタラクティブなエントリーポイント。たとえばPythonコードの編集用のメジャーモードを定義するライブラリーがpython.elなら、python-mode関数の定義をautoloadすればユーザーは単にM-x python-modeを使用してライブラリーをロードできる。
  • 変数は通常はautoloadする必要はない。例外はライブラリー定義全体をロードしなくても変数自体が有用な場合(これの例としてはfind-exec-terminatorのようなものが該当するだろう)。
  • ユーザーがセットできるように、ユーザーオプションをautoloadしないこと。
  • 別ファイルでのコンパイラー警告を抑制するためにautoloadのコメントを決して追加してはならない。警告の発生元となるファイルでは未定義の変数にたいする警告の抑制には(defvar foo)、未定義の関数にたいする警告の抑制にはdeclare-function (コンパイラーへの定義済み関数の指示を参照)を使用するか、あるいは使用する関連ライブラリーをrequireしたり明示的にautoloadの命令文を使用すること。

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

16.6 多重ロード

1つのEmacsセッション内でファイルを複数回ロードできます。たとえばバッファーで関数定義を編集して再インストールした後に元のバージョンに戻したいときがあるかもしれません。これは元のファイルをリロードすることにより行なうことができます。

ファイルのロードやリロードを行う際、loadload-library関数は未コンパイルのファイルではなく、バイトコンパイルされた同名のファイルを自動的にロードすることに留意してください。ファイルを再記述して保存後に再インストールする場合には、新しいバージョンをバイトコンパイルする必要があります。さもないとEmacsは新しいソースではなく、古いバイトコンパイルされたファイルをロードしてしまうでしょう! この場合にはファイルロード時に表示されるメッセージに、そのファイルのリコンパイルを促す‘(compiled; note, source is newer)’というメッセージが含まれます。

Lispライブラリーファイル内にフォームを記述するときは、そのファイルが複数回ロードされるかもしれないことに留意してください。たとえば、そのライブラリーをリロードするときには、各変数が再初期化されるべきかどうか考慮してください。。変数がすでに初期化されていれば、defvarはその変数の値を変更しません(グローバル変数の定義を参照)。

alistに要素を追加するもっともシンプルな方法は、以下のようなものでしょう:

(push '(leif-mode " Leif") minor-mode-alist)

しかしこれはそのライブラリーがリロードされると、複数の要素を追加してしまうでしょう。この問題を避けるにはadd-to-list(リスト変数の変更を参照)を使用します:

(add-to-list 'minor-mode-alist '(leif-mode " Leif"))

時にはライブラリーが既にロード済みか、明示的にテストしたいときがあるでしょう。そのライブラリーがprovideを使用して名前付きフィーチャ(named feature)を提供していれば、featurepを使用して以前にprovideが実行されているかテストすることができます。かわりに以下のようにすることもできます:

(defvar foo-was-loaded nil)

(unless foo-was-loaded
  execute-first-time-only
  (setq foo-was-loaded t))

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

16.7 名前つき機能

providerequireは、autoloadにかわってファイルを自動的にロードする関数です。これらは名前付きのフィーチャ(feature: 機能)という面で機能します。オートロードは特定の関数の呼び出しをトリガーにしますが、フィーチャは最初は他のプログラムが名前により問い合わせたときにロードされます。

フィーチャ名とは関数や変数などのコレクションを表すシンボルです。これらを定義するファイルは、そのフィーチャをプロバイド(provide: 提供)するべきです。これらのフィーチャを使用する他のプログラムは、その機能をリクワイア(require: 要求)することによって、それらが定義されているか確認できるでしょう。これは定義がまだロードされていなければ、定義ファイルをロードします。

フィーチャをリクワイアするには、フィーチャ名を引数としてrequireを呼び出します。requireは意図する機能がすでにプロバイドされているか確認するために、グローバル変数featuresを調べます。もしプロバイドされていなければ、適切なファイルからそのフィーチャをロードします。このファイルはそのフィーチャをfeaturesに追加するために、トップレベルでprovideを呼び出すべきです。これに失敗するとrequireはエラーをシグナルします。

たとえばidlwave.el内のidlwave-complete-filenameにたいする定義には以下のコードが含まれます:

(defun idlwave-complete-filename ()
  "Use the comint stuff to complete a file name."
   (require 'comint)
   (let* ((comint-file-name-chars "~/A-Za-z0-9+@:_.$#%={}\\-")
          (comint-completion-addsuffix nil)
          ...)
       (comint-dynamic-complete-filename)))

(require 'comint)comint.elがまだロードされていなければ、comint-dynamic-complete-filenameが確実に定義されるようにそのファイルをロードします。フィーチャは通常はそれらを提供するファイルにしたがって命名されるため、requireにファイル名を与える必要はありません(require命令文がletのbodyの外側にあるのが重要なことに注意。変数がletバインドされているライブラリーをロードすることにより、意図せぬ結果、つまりletをexitした後にその変数がアンバインドされる)。

comint.elには以下のトップレベル式が含まれます:

(provide 'comint)

これはcomintをグローバルなリストfeaturesに追加するので、(require 'comint)は今後何も行う必要がないことを知ることができます。

ファイルのトップレベルでrequireが使用されたときは、それをロードしたときと同様、そのファイルをバイトコンパイル(バイトコンパイルを参照)するときにも効果が表れます。これはリクワイアされたパッケージがマクロを含んでいて、バイトコンパイラーがそれを知らなければならない場合です。これはrequireによりロードされるファイルで定義される関数と変数にへのバイトコンパイラーの警告も無効にします。

バイトコンパイルの間にトップレベルのrequireが評価されるとしても、provide呼び出しは評価されません。したがって以下の例のようにprovideの後に同じ機能にたいするrequireを含めることにより、バイトコンパイル前に定義しているファイルを確実にロードできます。

(provide 'my-feature)  ; バイトコンパイラーには無視され
                       ;   loadには評価される
(require 'my-feature)  ; バイトコンパイラーにより評価される。

コンパイラーはprovideを無視して、その後に対象のファイルをロードすることによりrequireが処理されます。ファイルのロードはprovide呼び出しを実行するので、後続のrequireはファイルがロードされていれば何も行いません。

Function: provide feature &optional subfeatures

この関数はカレントEmacsセッションにfeatureがロードされたこと、あるいはロードされつつあることをアナウンスする。これはfeatureに関連する機能が他のLispプログラムから利用可能できる、あるいは利用可能になることを意味する。

provide呼び出にによる直接的な効果は、リストfeature内にまだ追加されていなければfeatureの先頭にそれを追加して、それを必要としているeval-after-loadコードを呼び出すことである(ロードのためのフックを参照)。引数featureはシンボルでなければならない。providefeatureをリターンする。

subfeaturesが与えられたら、それはfeatureの当該バージョンによりプロバイドされる特定のサブフィーチャのセットを示すシンボルのリストであること。featurepを使用して、サブフィーチャの存在をテストできる。そのパッケージがロードされるかどうか、あるいは与えられるバージョンで存在するかどうか不明であるようなあるパッケージ(1つのfeature)において、パッケージの種々の部分やパッケージ機能に命名することでそのパッケージを使いやすくするのが困難なほど複雑なときに使用するというのがサブフィーチャのアイデアである。ネットワーク機能の可用性のテストの例を参照されたい。

features
     ⇒ (bar bish)

(provide 'foo)
     ⇒ foo
features
     ⇒ (foo bar bish)

オートロードによりあるファイルがロードされて、その内容の評価エラーによりストップしたときは、そのロードの間に発生した関数定義やprovide呼び出しはアンドゥされる。autoloadを参照のこと。

Function: require feature &optional filename noerror

この関数はカレントEmacsセッションにおいて、featureが存在するかどうかを((featurep feature)を使用する。以下参照)をチェックする。引数featureはシンボルでなければならない。

そのフィーチャが存在しなければ、requireloadによってfilenameをロードする。filenameが与えられなければ、シンボルfeatureの名前がロードするファイル名のベースとして使用される。しかしこの場合、requirefeatureを探すためにサフィックス‘.el’と‘.elc’の追加を強制する(圧縮ファイルのサフィックスに拡張されるかもしれない)。名前がただのfeatureというファイルは使用されない(変数load-suffixesは要求されるLispサフィックスを正確に指定する)。

noerrorが非nilなら、ファイルの実際のロードにおけるエラーを抑止する。この場合はそのファイルのロードが失敗するとrequirenilをリターンする。通常ではrequirefeatureをリターンする。

ファイルのロードは成功したがfeatureをプロバイドしていない場合には、requireは欠落している機能に関するエラーをシグナルする。

Function: featurep feature &optional subfeature

この関数はカレントEmacsセッションでfeatureがプロバイドされていれば(たとえばfeaturefeaturesのメンバーなら)tをリターンする。subfeatureが非nilなら、この関数はサブフィーチャも同様にプロバイドされているとき(たとえばsubfeatureがシンボルfeatureのプロパティsubfeatureのメンバーのとき)だけtをリターンする。

Variable: features

この変数の値はシンボルのリストであり、そのシンボルはカレントEmacsセッションにロードされたフィーチャである。シンボルはそれぞれprovideを呼び出すことにより、このリストにputされたものである。リストfeatures内の要素の順番に意味はない。

use-packageは機能のロードやそれを使うための構成にたいして便利な手段を提供するためのマクロです。requireが行うような機能のrequire、それにロード時のフック(see ロードのためのフック)のようにその機能が既にロード済みならコードを実行するという処理を組み合わせる手段を提供するのです。use-packageの宣言的な構文によって、ユーザーのinitファイルで非常に簡単に使うことができます。

Macro: use-package feature &rest args

このマクロはfeatureという名前の機能をロードする方法、およびどのようにそれを構成、カスタマイズして使用するかを指定する。引数argsはキーワード/値のペアー。重要なキーワードと値の一部を以下に記す:

:init forms

featureのロード前に実行するformsを指定する。

:config forms

featureのロード後に実行するformsを指定する。

:defer condition

conditionが非nilなら、featureのautoloadされるコマンドか変数のいずれかが最初に使用されるまで、featureのロードを遅延するように指定する。conditionが数値nの場合には、アイドル後n秒経過後にfeatureをロードするよう指定する。

:commands commands

autoloadするfeatureのコマンドを指定する。

:bind keybindings

featureのコマンドのkeybindingsを指定する。バインドはそれぞれ以下の形式をもつ

(key-sequence . command)

または

(:map keymap (key-sequence . command))

ここでkey-sequencekbdマクロが受け付けるような形式であること(キーシーケンスを参照)。

use-packageに関する詳細はTop in use-package User Manualを参照のこと。


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

16.8 どのファイルで特定のシンボルが定義されているか

Function: symbol-file symbol &optional type native-p

この関数はsymbolを定義しているファイルの名前をリターンする。typenilなら、どのようなタイプの定義も受け入れる。typedefunなら関数定義、defvarは変数定義、deffaceはフェイス定義だけを指定する。

値は通常は絶対ファイル名である。定義がどのファイルにも関係しなければnilになることもある。symbolがオートロード関数を指定するなら、値が拡張子なしの相対ファイル名になることもある。

オプションの3番目の引数native-pが非nil、かつネイティブコンパイルのサポートつき(Lispからネイティブコードへのコンパイルを参照)でビルドされたEmacsの場合には、この関数は.elc.elといったファイルではなく、.elnファイルで定義されたsymbolを探そうと試みる。そのような.elnファイルが見つかり古くなっていなければ、この関数は絶対ファイル名をリターンする。それ以外の場合にはソースファイルかバイトコンパイル済みファイルのいずれかの名前をリターンする。

symbol-fileは変数load-historyの値にもとづく。

Variable: load-history

この変数の値はロードされたライブラリーファイルの名前を、それらが定義する関数と変数の名前、およびそれらがプロバイドまたはリクワイアするフィーチャに関連付けるalistである。

このalist内の各要素は、1つのロード済みライブラリー(スタートアップ時にプリロードされたライブラリーを含む)を記述する。要素はCARがライブラリーの絶対ファイル名(文字列)であるようなリストである。残りのリスト要素は以下の形式をもつ:

var

シンボルvarが変数として定義された。

(defun . fun)

関数funは定義済み。(defun . fun)funを関数として定義されていることを表す。

(defface . face)

フェイスfaceが定義された。

(require . feature)

フィーチャfeatureがリクワイアされた。

(provide . feature)

フィーチャfeatureがプロバイドされた。

(cl-defmethod method specializers)

cl-defmethodを使用してスペシャライザーspecializersとともにmethodという名前が定義された。

(define-type . type)

typeが定義された。

load-historyの値には、CARnilであるような要素が1つ含まれるかもしれない。この要素はファイルをvisitしていないバッファーでeval-bufferにより作成された定義を記述する。

コマンドeval-regionload-historyを更新しますが、要素を置き換えずに、visitされているファイルの要素にたいして定義されたシンボルを追加します。evalについてを参照してください。

load-historyに加えて、関数はそれぞれシンボルプロパティfunction-historyで自身のヒストリーを追跡します。この点において関数が特別扱いされる理由は、関数は2つの異なるファイルにおいて2段階で定義されることがよくある(典型的にはそのうちの一方がautoloadされる)ので、ファイルを正しいunloadを可能にするために、そのファイルが関数定義に何を行ったかをより正確に知る必要があるのです。

シンボルプロパティfunction-historyには(file1 def2 file2 def3 ...)という形式のリストが保持されています。ここでfile1は定義を最後に変更したファイル、def2file1の前にfile2によってセットされた定義、...となります。論理的にはこのリストの最後はその関数を最初に定義したファイルですが、容量削減のために通常は最後の要素は省略されます。


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

16.9 アンロード

他のLispオブジェクト用にメモリーを回収するために、ライブラリーによりロードされた関数や変数を破棄することができます。これを行うには関数unload-featureを使用します:

Command: unload-feature feature &optional force

このコマンドはフィーチャfeatureをプロバイドしていたライブラリーをアンロードする。そのライブラリー内のdefundefaliasdefsubstdefmacrodefconstdefvardefcustomによって定義されたすべての関数、マクロ、変数は未定義になる。その後に、それらのシンボルにたいして事前に関連付けられていたオートロードをリストアする(ロードはシンボルのfunction-historyプロパティにこれらを保存している)。

以前の定義をリストアする前に、特定のフックからライブラリーが定義した関数を取り除くために、unload-featureremove-hookを実行する。これらのフックには名前が‘-hook’(または廃止されたサフィックス‘-hooks’)で終わる変数、加えてunload-feature-special-hooks、同様にauto-mode-alistにリストされた変数も含まれる。これは重要なフックがすでに定義されていない関数を参照をすることにより、Emacsの機能が停止することを防ぐためである。

標準的なアンロードアクティビティでは、そのライブラリー内の関数のELPプロファイリング、そのライブラリーによりプロバイドされたフィーチャ、そのライブラリーで定義された変数に保持されたタイマーをアンドゥする。

これらの基準が機能不全を防ぐのに十分でなければ、ライブラリーはfeature-unload-functionという名前の明示的なアンローダーを定義できる。そのシンボルが関数として定義されていたら、unload-featureは何かを行う前にまず引数なしでそれを呼び出す。これはライブラリーのアンロードのために適切なすべてのことを行うことができる。これがnilをリターンしたら、unload-featureは通常のアンロードアクションを処理する。それ以外ならアンロード処理は完了したとみなす。

unload-featureは通常は他のライブラリーが依存するライブラリーのアンロードを拒絶する(ライブラリーbにたいするrequireがライブラリーaに含まれるなら、abに依存している)。オプション引数forceが非nilなら依存関係は無視されて、どのようなライブラリーもアンロードできる。

unload-feature関数はLispで記述されており、その動作は変数load-historyにもとづきます。

Variable: unload-feature-special-hooks

この変数はライブラリー内で定義された関数を取り除くために、ライブラリーをアンロードする前にスキャンするフックのリストを保持する。


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

16.10 ロードのためのフック

変数after-load-functionsを使用することにより、Emacsがライブラリーをロードするたびにコードを実行させることができます:

Variable: after-load-functions

このアブノーマルフック(abnormal hook)は、ファイルをロードした後に実行される。フック内の各関数は1つの引数(ロードされたファイルの絶対ファイル名)で呼び出される。

特定のライブラリーのロード後にコードを実行したければ、マクロwith-eval-after-loadを使用します:

Macro: with-eval-after-load library body…

このマクロはlibraryがロードされるたびに、ファイルlibraryのロードの最後でbodyが評価されるよう準備する。libraryがすでにロード済みなら即座にbodyを評価する。

ファイル名libraryにディレクトリーや拡張子を与える必要はない。通常は以下のようにファイル名だけを与える:

(with-eval-after-load "js" (keymap-set js-mode-map "C-c C-c" 'js-eval))

どのファイルが評価をトリガーするか制限するには、ディレクトリーか拡張子、またはその両方をlibraryに含める。実際のファイル名(シンボリックリンク名はすべて除外される)が、与えられた名前すべてにマッチするファイルだけがマッチとなる。以下の例ではどこかのディレクトリー..../foo/barにあるmy_inst.elcmy_inst.elc.gzは評価をトリガーするが、my_inst.elは異なる。:

(with-eval-after-load "foo/bar/my_inst.elc" …)

libraryはフィーチャ(たとえばシンボル)でもよく、その場合には(provide library)を呼び出す任意のファイルの最後にbodyが評価される。

body内でのエラーはロードをアンドゥしないが、bodyの残りの実行を防げる。

上手く設計されたLispプログラムは、通常はwith-eval-after-loadを使用するべきではありません。(外部からの使用を意図した)他のライブラリーで定義された変数を調べたりセットする必要があるなら、それは即座に行うことができます −−− そのライブラリーがロードされるのを待つ必要はありまん。そのライブラリーで定義された関数を呼び出す必要があるならそのライブラリーをロードすべきであって、それにはrequire(名前つき機能を参照)が適しています。


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

16.11 Emacsのダイナミックモジュール

ダイナミックEmacsモジュール(dynamic Emacs module: 動的Emacsモジュール)とは、Emacs Lispで記述されたパッケージのように、Emacs Lispプログラムで使用するための追加機能を提供する共有ライブラリーです。

Emacs Lispパッケージをロードする関数は、ダイナミックモジュールのロードもできます。これらの関数はファイル名の拡張子、いわゆる“サフィックス”を調べることによってダイナミックモジュールを認識します。

Variable: module-file-suffix

この変数はモジュールファイルにたいするシステム依存なファイル名拡張子を保持する。POSIXホストでは.so、macOSでは.dylib 、MS-Windowsでは.dll

macOSではダイナミックモジュールは.dylibに加えて、サフィックス.soをもつこともできます。

すべてのダイナミックモジュールはemacs_module_initという名前のCから呼び出し可能な関数をエクスポートする必要があります。Emacsはそのモジュールをロードするloadrequireの呼び出しの一部として、その関数を呼び出します。自身のコードがGPLまたは互換ライセンスの下にリリースされていることを示すために、plugin_is_GPL_compatibleという名前のシンボルもエクスポートするべきです。このようなシンボルをエクスポートしないモジュールをプログラムがロードしようとすると、Emacsはエラーをシグナルするでしょう。

あるモジュールがEmacsの関数の呼び出しを必要とするなら、Emacsディストリビューションに同梱されているヘッダーファイルemacs-module.hで定義および文書化されたAPI (Application Programming Interface)を介して行う必要があります。独自モジュールを記述する際におけるこのAPI使用の詳細は動的にロードされるモジュールの記述を参照してください。

モジュールはモジュールが定義するC構造体への埋め込みポインターとなるLispオブジェクトuser-ptrを作成できます。これはモジュールが作成する複雑なデータ構造を維持してモジュールの関数に渡して戻す場合に有用です。user-ptrオブジェクトはそれに関連付けられるファイナライザー(finalizer: オブジェクトがガーベージコレクトされる際に呼び出される関数)をもつこともできます。これはメモリー、オープンしたファイル記述子等のデータ構造の背後に割り当てられたリソースの解放に有用です。Lisp・モジュール間の値変換を参照してください。

Function: user-ptrp object

この関数は引数がuser-ptrオブジェクトならtをリターンする。

Function: module-load file

Emacsは指定されたfileからモジュールをロードして、そのモジュールに必要な初期化えを行うために、この低レベルのプリミティブを呼び出す。これはモジュールがシンボルplugin_is_GPL_compatibleをエクスポートすることを保証して、モジュールのemacs_module_init関数を呼び出し、その関数のリターン値がエラーを示したりユーザーが初期化中にC-gをタイプしたらエラーをシグナルする。初期化が成功するとmodule-loadtをリターンする。この関数はloadとは異なり既知の拡張子をもつファイルの検索を試みないので、fileは正確なファイル名拡張子をもたなければならないことに注意。

loadとは異なり、module-loadload-historyにモジュールを記録せず、何もメッセージをプリントしないし、再帰ロードにたいする保護も行わない。したがってほとんどのユーザーはmodule-loadのかわりにloadload-fileload-libraryrequireを使用するべきである。

Emacsのロード可能モジュールは、configure時にオプション--with-modulesを使用することにより有効になります。


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

17 バイトコンパイル

Emacs LispにはLispで記述された関数をより効率的に実行できる、バイトコード(byte-code)と呼ばれる特別な表現に翻訳するコンパイラー(compiler)があります。コンパイラーはLispの関数定義をバイトコードに置き換えます。バイトコード関数が呼び出されたとき、その定義はバイトコードインタープリター(byte-code interpreter)により評価されます。

バイトコンパイルされたコードは、(本当のコンパイル済みコードのように)そのマシンのハードウェアによって直接実行されるのではなく、バイトコンパイラーによって評価されるため、バイトコードはリコンパイルしなくてもマシン間での完全な可搬性を有します。しかし本当にコンパイルされたコードほど高速ではありません。

一般的に任意のバージョンのEmacsはそれ以前のバージョンのEmacsにより生成されたバイトコンパイル済みコードを実行できますが、その逆は成り立ちません。

あるLispファイルを常にコンパイルせずに実行したい場合は、以下のようにno-byte-compileをバインドするファイルローカル変数を配置します:

;; -*-no-byte-compile: t; -*-

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

17.1 バイトコンパイル済みコードのパフォーマンス

バイトコンパイルされた関数はCで記述されたプリミティブ関数ほど効率的ではありませんが、Lispで記述されたバージョンよりは高速に実行されます。以下は例です:

(defun silly-loop (n)
  "ループをN回繰り返し実行して時間を秒でリターンする"
  (let ((t1 (float-time)))
    (while (> (setq n (1- n)) 0))
    (- (float-time) t1)))
⇒ silly-loop

(silly-loop 50000000)
⇒ 5.200886011123657

(byte-compile 'silly-loop)
⇒ [コンパイルされたコードは表示されない]

(silly-loop 50000000)
⇒ 0.6239290237426758

この例ではインタープリターによる実行には5秒以上を要しますが、バイトコンパイルされたコードは1秒未満です。これは典型的な結果例ですが、実際の結果はさまざまでしょう。


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

17.2 バイトコンパイル関数

byte-compileにより、関数やマクロを個別にバイトコンパイルできます。byte-compile-fileでファイル全体、byte-recompile-directoryまたはbatch-byte-compileで複数ファイルをコンパイルできます。

バイトコンパイラーが警告および/またはエラーメッセージを生成することもあります(詳細はコンパイラーのエラーを参照)。これらのメッセージは通常はCompilationモードが使用する*Compile-Log*と呼ばれるバッファーに記録されます。Compilation Mode in The GNU Emacs Manualを参照してください。しかし変数byte-compile-debugが非nilならエラーメッセージはLispエラーとしてシグナルされます(エラーを参照)。

バイトコンパイルを意図したファイル内にマクロ呼び出しを記述する際には注意が必要です。マクロ呼び出しはコンパイル時に展開されるので、そのマクロはEmacsにロードされる必要があります(さもないとバイトコンパイラーが正しく処理しないだろう)。これを処理する通常の方法は、必要なマクロ定義を含むファイルをrequireフォームで指定することです。バイトコンパイラーは通常はコンパイルするコードを評価しませんが、requireフォームは指定されたライブラリーをロードすることにより特別に扱われます。誰かがコンパイルされたプログラムを実行する際にマクロ定義ファイルのロードを回避するためには、require呼び出しの周囲にeval-when-compileを記述します(コンパイル中の評価を参照)。詳細はマクロとバイトコンパイルを参照してください。

インライン関数(defsubst)はこれほど面倒ではありません。定義が判明する前にそのような関数呼び出しをコンパイルした場合でも、その呼び出しは低速になるだけで正しく機能するでしょう。

Function: byte-compile symbol

この関数はsymbolの関数定義をバイトコンパイルして、以前の定義をコンパイルされた定義に置き換える。symbolの関数定義は、その関数にたいする実際のコードでなければならない。byte-compileはインダイレクト関数を処理しない。リターン値は、symbolのコンパイルされた定義であるようなバイトコード関数ブジェクト(バイトコード関数オブジェクトを参照)。

(defun factorial (integer)
  "INTEGERの階乗を計算する。"
  (if (= 1 integer) 1
    (* integer (factorial (1- integer)))))
⇒ factorial

(byte-compile 'factorial)
⇒
#[257
  "\211\300U\203^H^@\300\207\211\301^BS!_\207"
  [1 factorial] 4
  "Compute factorial of INTEGER.\n\n(fn INTEGER)"]

symbolの定義がバイトコード関数オブジェクトなら、byte-compileは何も行わずnilをリターンする。そのシンボルの関数セル内の(コンパイルされていない)オリジナルのコードはすでにバイトコンパイルされたコードに置き換えられているので、シンボルの定義の再コンパイルはしない。

byte-compileの引数としてlambda式も指定できる。この場合、関数は対応するコンパイル済みコードをリターンするが、それはどこにも格納されない。

Command: compile-defun &optional arg

このコマンドはポイントを含むdefunを読み取りそれをコンパイルして結果を評価する。実際に関数定義であるようなdefunでこれを使用した場合には、その関数のコンパイル済みバージョンをインストールする効果がある。

compile-defunは通常は評価した結果をエコーエリアに表示するが、argが非nilならフォームをコンパイルした後にカレントバッファーに結果を挿入する。

Command: byte-compile-file filename

この関数はfilenameという名前のLispコードファイルを、バイトコードのファイルにコンパイルする。出力となるファイルの名前は、サフィックス‘.el’を‘.elc’に変更することにより作成される。filenameが‘.el’で終了しない場合には、‘.elc’をfilenameの最後に付け足す。

コンパイルは入力ファイルから1つのフォームを逐次読み取ることにより機能する。フォームが関数かマクロなら、コンパイル済みの関数かマクロが書き込まれる。それ以外のフォームはまとめられて、まとめられたものごとにコンパイルされて、そのファイルが読まれたとき実行されるようにコンパイルされたコードが書き込まれる。入力ファイルを読み取る際には、すべてのコメントは無視される。

このコマンドはエラーがなければt、それ以外はnilをリターンする。インタラクティブに呼び出されたときは、ファイル名の入力をもとめる。

$ ls -l push*
-rw-r--r-- 1 lewis lewis 791 Oct  5 20:31 push.el

(byte-compile-file "~/emacs/push.el")
     ⇒ t

$ ls -l push*
-rw-r--r-- 1 lewis lewis 791 Oct  5 20:31 push.el
-rw-rw-rw- 1 lewis lewis 638 Oct  8 20:25 push.elc
Command: byte-recompile-directory directory &optional flag force follow-symlinks

このコマンドはdirectory(またはそのサブディレクトリー)内の、リコンパイルを要するすべての‘.el’ファイルをリコンパイルする。‘.elc’ファイルが存在して、それが‘.el’より古いファイルは、リコンパイルが必要となる。

.el’ファイルに対応する‘.elc’ファイルが存在しない場合に何を行うかをflagで指定する。nilなら、このコマンドはこれらのファイルを無視する。flagが0なら、それらをコンパイルする。nilと0以外なら、それらのファイルをコンパイルするかユーザーに尋ねて、同様にそれぞれのサブディレクトリーについても尋ねる。

インタラクティブに呼び出されると、byte-recompile-directorydirectoryの入力を求めて、flagはプレフィクス引数となる。

forceが非nilなら、このコマンドは‘.elc’ファイルが存在するすべての‘.el’ファイルをリコンパイルする。

このコマンドは通常はシンボリックリンクであるような‘.el’ファイルをコンパイルしない。オプションのfollow-symlinkパラメーターが非nilなら、シンボリックリンクされた‘.el’もコンパイルされる。

リターン値は不定。

Function: batch-byte-compile &optional noforce

この関数はコマンドラインで指定されたファイルにたいしてbyte-compile-fileを実行する。この関数は処理が完了するとEmacsをkillするので、Emacsのバッチ実行でのみ使用しなければならない。1つのファイルでエラーが発生しても、それによって後続のファイルにたいする処理が妨げられることはないが、そのファイルにたいする出力ファイルは生成されず、Emacsプロセスは0以外のステータスコードで終了する。

noforceが非nilなら、この関数は最新の‘.elc’ファイルがあるファイルをリコンパイルしない。

$ emacs -batch -f batch-byte-compile *.el

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

17.3 ドキュメント文字列とコンパイル

Emacsがバイトコンパイルされたファイルから関数や変数をロードする際、通常はメモリー内にそれらのドキュメント文字列をロードしません。それぞれのドキュメント文字列は、必要なときだけバイトコンパイルされたファイルからダイナミック(dynamic: 動的)にロードされます。ドキュメント文字列の処理をスキップすることにより、メモリーが節約されてロードが高速になります。

この機能には欠点があります。コンパイル済みのファイルを削除や移動、または(新しいバージョンのコンパイル等で)変更した場合、Emacsは以前にロードした関数や変数のドキュメント文字列にアクセスできなくなるでしょう。このような問題は通常なら、あなた自身がEmacsをビルドしたときに、そのLispファイルを編集および/またはリコンパイルしたときだけ発生します。この問題は、リコンパイル後にそれぞれのファイルをリロードするだけで解決します。

バイトコンパイルされたファイルからのドキュメント文字列のダイナミックロードは、バイトコンパイルされたファイルごとにコンパイル時に解決されます。これはオプションbyte-compile-dynamic-docstringsで無効にできます。

User Option: byte-compile-dynamic-docstrings

これが非nilなら、バイトコンパイラーはドキュメント文字列をダイナミックロードするようにセットアップしたコンパイル済みファイルを生成する。

特定のファイルでダイナミックロード機能を無効にするには、以下のようにヘッダー行でこのオプションにnilをセットする(Local Variables in Files in The GNU Emacs Manualを参照)。

-*-byte-compile-dynamic-docstrings: nil;-*-

これは主として、あるファイルを変更しようとしていて、そのファイルをすでにロード済みのEmacsセッションがファイルを変更した際にも正しく機能し続けることを望む場合に有用である。

内部的にはドキュメント文字列のダイナミックロードは、特殊なLispリーダー構文‘#@count’とともにコンパイル済みファイルに書き込むことによって達成される。この構文は次のcount文字をスキップする。さらに‘#$’構文も使用され、これはこのファイルの名前(文字列)を意味する。これらの構文をLispソースファイル内で使用しないこと。これらは人間がファイルを読む際に明確であるようにデザインされていない。


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

17.4 個々の関数のダイナミックロード

ファイルをコンパイルするとき、オプションでダイナミック関数ロード(dynamic function loading)機能(laxyロード(lazy loading)とも呼ばれる)を有効にできます。ダイナミック関数ロードでは、ファイルのロードでファイル内の関数定義は完全には読み込まれません。かわりに各関数定義にはそのファイルを参照するプレースホルダーが含まれます。それぞれ関数が最初に呼び出されるときにそのプレースホルダーを置き換えるために、ファイルから完全な定義が読み込まれます。

ファイルのロードがより高速になるだろうというのがダイナミック関数ロードの利点です。ユーザーが呼び出せる関数を多く含むファイルにとって、それらの関数のうち1つを使用したら多分残りの関数も使用するというのでなければ、これは利点になります。多くのキーボードコマンドを提供する特化したモードは、このパターンの使い方をする場合があります。ユーザーはそのモードを呼び出すかもしれませんが、使用するのはそのモードが提供するコマンドのわずか一部です。

ダイナミックロード機能には不利な点がいくつかあります:

  • ロード後にコンパイル済みファイルの削除や移動を行うと、Emacsはまだロードされていない残りの関数定義をロードできなくなる。
  • (新しいバージョンのコンパイル等で)コンパイル済みファイルを変更した場合に、まだロードされていない関数のロードを試みると通常は無意味な結果となる。

このような問題は通常の状況でインストールされたEmacsファイルでは決して発生しません。しかしあなたが変更したLispファイルでは発生し得ます。それぞれのファイルをリコンパイルしたらすぐに新たなコンパイル済みファイルをリロードするのが、これらの問題を回避する一番簡単な方法です。

ダイナミックな関数ロードの使用により提供される利点がほとんど計測できないという経験から、この機能はEmacs 27.1以降は廃止されます。

コンパイル時に変数byte-compile-dynamicが非nilなら、バイトコンパイラーはダイナミック関数ロード機能を使用します。ダイナミックロードが望ましいのは特定のファイルにたいしてだけなので、この変数をグローバルにセットしないでください。そのかわりに、特定のソースファイルのファイルローカル変数でこの機能を有効にしてください。たとえばソースファイルの最初の行に以下のテキストを記述することにより、これを行うことができます:

-*-byte-compile-dynamic: t;-*-
Variable: byte-compile-dynamic

これが非nilなら、バイトコンパイラーはダイナミック関数ロード用にセットアップされたコンパイル済みファイルを生成する。

Function: fetch-bytecode function

functionがバイトコード関数オブジェクトなら、それがまだ完全にロードされていなければ、バイトコンパイル済みのファイルからのfunctionのバイトコードのロードを完了させる。それ以外なら何も行わない。この関数は常にfunctionをリターンする。


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

17.5 コンパイル中の評価

これらの機能によりプログラムのコンパイル中に評価されるコードを記述できます。

Macro: eval-and-compile body…

このフォームはそれを含むコードがコンパイルされるとき、および(コンパイルされているかいないかに関わらず)実行されるときの両方でbodyが評価されるようにマークする。

bodyを別のファイルに配置して、そのファイルをrequireで参照すれば同様の結果が得られる。これはbodyが大きいときに望ましい方法である。事実上、requireは自動的にeval-and-compileされて、そのパッケージはコンパイル時と実行時の両方でロードされる。

autoloadも実際はeval-and-compileされる。これはコンパイル時に認識されるので、そのような関数の使用により警告“not known to be defined”は生成されない。

ほとんどのeval-and-compileの使用は、完全に妥当であると言えよう。

あるマクロがマクロの結果を構築するためのヘルパー関数をもち、そのマクロがそのパッケージにたいしてローカルと外部の両方で使用される場合には、コンパイル時と後の実行時にそのヘルパー関数を取得するためにeval-and-compileを使用すること。

これは関数がプログラム的に(fsetで)定義されている場合には、コンパイル時と実行時にプログラム的な定義を行わせてそれらの関数の呼び出しをチェックするためにも使用できる(“not known to be defined”の警告は抑制される)。

Macro: eval-when-compile body…

このフォームはbodyがコンパイル時に評価され、コンパイルされたプログラムがロードされるときは評価されないようにマークする。コンパイラーによる評価の結果はコンパイル済みのプログラム内の定数となる。ソースファイルをコンパイルではなくロードすると、bodyは通常どおり評価される。

生成するために何らかの計算が必要な定数があるなら、eval-when-compileはコンパイル時にそれを行なうことができる。たとえば、

(defvar my-regexp
  (eval-when-compile (regexp-opt '("aaa" "aba" "abb"))))

他のパッケージを使用しているが、そのパッケージのマクロ(バイトコンパイラーはそれらを展開します)だけが必要なら、それらを実行せずにコンパイル用にロードさせるためにeval-when-compileを使用できる。たとえば、

(eval-when-compile
  (require 'my-macro-package))

これらの事項は、マクロとdefsubst関数がローカルに定義されていて、そのファイル内だけで使用されることを要求する。これらはそのファイルのコンパイルに必要だが、コンパイル済みファイルの実行には、ほとんどの場合必要ない。たとえば、

(eval-when-compile
  (unless (fboundp 'some-new-thing)
    (defmacro 'some-new-thing ()
      (compatibility code))))

これは大抵は他のバージョンのEmacsとの互換性の保証のためのコードにたいしてのみ有用である。

Common Lispに関する注意: トップレベルでは、eval-when-compileはCommon Lispのイディオム(eval-when (compile eval) …)に類似する。トップレベル以外では、Common Lispのリーダーマクロ‘#.’(ただし解釈時を除く)が、eval-when-compileと近いことを行う。


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

17.6 コンパイラーのエラー

バイトコンパイルのエラーメッセージと警告メッセージは、*Compile-Log*という名前のバッファーにプリントされます。これらのメッセージには、問題となる箇所を示すファイル名と行番号が含まれます。これらのメッセージにたいして、コンパイラー出力を操作する通常のEmacsコマンドが使用できます。

あるエラーがプログラムのシンタックスに由来する場合、バイトコンパイラーはエラーの正確な位置の取得に際して混乱するかもしれません。バッファー *Compiler Input*.にスイッチするのは、これを調べ1つの方法です(このバッファー名はスペースで始まるので、Buffer Menuに表示されない)。このバッファーにはコンパイルされたプログラムと、バイトコンパイラーが読み取った箇所からポイントがどれほど離れているかが含まれ、エラーの原因はその近傍の可能性があります。シンタックスエラーを見つけるヒントについては、無効なLisp構文のデバッグを参照してください。

定義されていない関数や変数の使用は、バイトコンパイラーにより報告される警告のタイプとしては一般的です。そのような警告では、定義されていない関数や変数を使用した位置ではなく、そのファイルの最後の行の行番号が報告されるので、それを見つけるには手作業で検索しなければなりません。

定義のない関数や変数の警告が間違いだと確信できる場合には、警告を抑制する方法がいくつかあります:

  • 関数funcへの特定の呼び出しにたいする警告は、それを条件式fboundpでテストすることで抑制できる:
    (if (fboundp 'func) ...(func ...)...)
    

    funcへの呼び出しはif文のthen-form内になければならず、funcfboundp呼び出し内でクォートされていなければならない(この機能はcondでも同様に機能する)。

  • 同じように、変数variableの特定の使用についの警告を、条件式内のboundpテストで抑制できる:
    (if (boundp 'variable) ...variable...)
    

    variableへの参照はif文のthen-form内になければならず、variableboundp呼び出し内でクォートされていなければならない。

  • コンパイラーに関数がdeclare-functionを使用して定義されていると告げることができる。コンパイラーへの定義済み関数の指示を参照のこと。
  • 同じように変数が初期値なしのdefvarを使用して定義されているとコンパイラーに告げることができる(カレントレキシカルスコープ、またはトップレベルにあればファイルでのみダイナミックにバインドされているとして変数を特別な変数としてマークすることに注意。グローバル変数の定義を参照のこと。

with-suppressed-warningsマクロを使用して特定の式にたいするコンパイラーの警告を抑制することもできます:

Special Form: with-suppressed-warnings warnings body…

これは実行においては(progn body...)と等価だが、コンパイラーはbody内の指定したコンディションにたいする警告を発しない。warningsは警告シンボルと、それらを適用する関数/変数シンボルの連想リスト。たとえばfooという時代遅れ(obsolete)の関数を呼び出したいがコンパイル時の警告を抑止したければ、以下のようにする:

(with-suppressed-warnings ((obsolete foo))
  (foo ...))

コンパイラー警告の抑制をより粗く行うにはwith-no-warnings構文を使用できます:

Special Form: with-no-warnings body…

これは実行時には(progn body...)と等価だが、コンパイラーはbodyの中で起こるいかなる事項にたいしても警告を発しない。

わたしたちはかわりにwith-suppressed-warningsの使用を推奨するが、この構文を使用する場合には、あなたが抑制したいと意図する警告以外の警告を失わないようにするために、可能な限り小さいコード断片にたいしてこの構文を使用すること。

変数byte-compile-warningsをセットすることにより、コンパイラーの警告をより詳細に制御できます。詳細は変数のドキュメント文字列を参照してください。

errorを使用してバイトコンパイラーの警告が報告されることを望む場合があるかもしれません。そのような場合にはbyte-compile-error-on-warnを非nil値にセットしてください。


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

17.7 バイトコード関数オブジェクト

バイトコンパイルされた関数は、バイトコード関数オブジェクト(byte-code function objects)という特別なデータ型をもちます。関数呼び出しとしてそのようなオブジェクトが出現したとき、Emacsはそのバイトコードを実行するために、常にバイトコードインタープリターを使用します。

内部的にはバイトコード関数オブジェクトはベクターとよく似ています。バイトコード関数オブジェクトの要素にはarefを通じてアクセスできます。バイトコード関数オブジェクトのプリント表現(printed representation)はベクターと似ていて、開き‘[’の前に‘#’が追加されます。バイト関数オブジェクトは少なくとも4つの要素をもたねばならず、その要素数に上限はありません。しかし通常使用されるのは最初の6要素です。これらは:

argdesc

引数の記述子(descriptor)。これは引数リストの機能で説明されるような引数のリスト、または要求される引数の個数をエンコードする整数のいずれかである。後者の場合、その記述子の値は0ビットから6ビットで引数の最小個数、8ビットから14ビットで引数の最大個数を指定する。引数リストが&restを使用するなら7ビットがセットされて、それい以外ならクリアーされる。

argdescがリストなら、そのバイトコード実行前に引数はダイナミックにバインドされる。argdescが整数なら、引数リストはそのバイトコード実行前にバイトコーピンタープリンターのスタックにpushされる。

byte-code

バイトコード命令を含む文字列。

constants

バイトコードにより参照されるLispオブジェクトのベクター。関数名と変数名に使用されるシンボルが含まれる。

stacksize

この関数が要するスタックの最大サイズ。

docstring

(もしあれば)ドキュメント文字列。それ以外はnil。ドキュメント文字列がファイルに格納されている場合、値は数字かリストかもしれない。本当のドキュメント文字列の取得には、関数documentationを使用する(ドキュメント文字列へのアクセスを参照)。

interactive

(もしあれば)インタラクティブ仕様。文字列かLisp式。インタラクティブでない関数ではnil

以下はバイトコード関数オブジェクトのプリント表現の例です。これはコマンドbackward-sexpの定義です。

#[256
  "\211\204^G^@\300\262^A\301^A[!\207"
  [1 forward-sexp]
  3
  1793299
  "^p"]

バイトコードオブジェクトを作成するプリミティブな方法はmake-byte-codeです:

Function: make-byte-code &rest elements

この関数はelementsを要素とするバイトコードオブジェクトを構築してリターンする。

あなた自身で要素を収集してバイトコード関数を構築しないでください。それらが矛盾する場合、その関数の呼び出しによりEmacsがクラッシュするかもしれません。これらのオブジェクトの作成は常にバイトコンパイラーにまかせてください。(願わくば)バイトコンパイラーは要素を矛盾なく構築します。


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

17.8 逆アセンブルされたバイトコード

人はバイトコードを記述しません。それはバイトコンパイラーの仕事です。しかし好奇心を満たすために、わたしたちはディスアセンブラを提供しています。ディスアセンブラはバイトコードを人間が読めるフォームに変換します。

バイトコードインタープリターは、シンプルなスタックマシンとして実装されています。これは値を自身のスタックにpushして、計算で使用するためにそれらをpopして取り出し、その結果を再びそのスタックにpushして戻します。バイトコード関数がリターンするときは、スタックから値をpopして取り出し、その関数の値としてリターンします。

それに加えてスタックとバイトコード関数は、値を変数とスタック間で転送することにより、普通のLisp変数を使用したり、バインドやセットを行うことができます。

Command: disassemble object &optional buffer-or-name

このコマンドはobjectにたいするディスアセンブルされたコードを表示する。インタラクティブに使用した場合、またはbuffer-or-namenilか省略された場合は、*Disassemble*という名前のバッファーに出力します。buffer-or-nameが非nilなら、それはバッファーもしくは既存のバッファーの名前でなければならない。その場合は、そのバッファーのポイント位置に出力され、ポイントは出力の前に残りされる。

引数objectには関数名、ラムダ式(ラムダ式を参照)、またはバイトコードオブジェクト(バイトコード関数オブジェクトを参照)を指定できる。ラムダ式ならdisassembleはそれをコンパイルしてから、そのコンパイル済みコードをディスアセンブルする。

以下にdisassemble関数を使用した例を2つ示します。バイトコードとLispソースを関連付ける助けとなるように、説明的なコメントを追加してあります。これらのコメントはdisassembleの出力にはありません。

(defun factorial (integer)
  "Compute factorial of an integer."
  (if (= 1 integer) 1
    (* integer (factorial (1- integer)))))
     ⇒ factorial

(factorial 4)
     ⇒ 24

(disassemble 'factorial)
     -| byte-code for factorial:
 doc: Compute factorial of an integer.
 args: (arg1)

0   dup                   ; integerの値を取得して
                          ;   それをスタック上にpushする
1   constant 1            ; スタック上に1をpushする
2   eqlsign               ; 2つの値をスタックからpopして取り出し、
                          ;   それらを比較して結果をスタック上にpushする
3   goto-if-nil 1         ; スタックのトップをpopしてテストする
                          ;   nilなら1へ、それ以外はcontinue
6   constant 1            ; スタックのトップに1をpushする
7   return                ; スタックのトップの要素をリターンする
8:1 dup                   ; integerの値をスタック上にpushする
9   constant factorial    ; factorialをスタック上にpushする
10  stack-ref 2           ; integerの値をスタック上にpushする
11  sub1                  ; integerをpopして値をデクリメントする
                          ;   スタック上に新しい値をpushする
12  call     1            ; スタックの最初(トップ)の要素を引数として
                          ;   関数factorialを呼び出す
                          ;   リターン値をスタック上にpushする
13 mult                   ; スタックのトップ2要素をpopして取り出し乗じ
                          ;   結果をスタック上にpushする
14 return                 ; スタックのトップ要素をリターンする

silly-loopは幾分複雑です:

(defun silly-loop (n)
  "Return time before and after N iterations of a loop."
  (let ((t1 (current-time-string)))
    (while (> (setq n (1- n))
              0))
    (list t1 (current-time-string))))
     ⇒ silly-loop

(disassemble 'silly-loop)
     -| byte-code for silly-loop:
 doc: Return time before and after N iterations of a loop.
 args: (arg1)

0   constant current-time-string  ; current-time-string
                                  ;   スタック上のトップにpushする
1   call     0            ; 引数なしでcurrent-time-stringを呼び出して
                          ;   結果をt1のようにスタック上にpushする
2:1 stack-ref 1           ; 引数nの値を取得して
                          ;   その値をスタック上にpushする
3   sub1                  ; スタックのトップから1を減ずる
4   dup                   ; スタックのトップを複製する
                          ;   つまりスタックのトップをコピーしてスタック上にpushする
5   stack-set 3           ; ; スタックのトップをpopして
                          ;   nにその値をセットする

;; (要はシーケンスdup stack-setはpopせずに
;;  スタックのトップをnの値にコピーする)

7   constant 0            ; スタック上に0をpushする
8   gtr                   ; スタックのトップ2値をpopして取り出し
                          ;   nが0より大かテストし
                          ;   結果をスタック上にpushする
9   goto-if-not-nil 1     ; n > 0なら1へ
                          ;   (これはwhile-loopを継続する)
                          ;   それ以外はcontinue
12  dup                   ; t1の値をスタック上にpushする
13  constant current-time-string  ; current-time-string
                                  ;   スタックのトップにpushする
14  call     0            ; 再度current-time-stringを呼び出す
15  list2                 ; スタックのトップ2要素をpopして取り出し
                          ;   それらのリストを作りスタック上にpushする
16  return                ; スタックのトップの値をリターンする

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

18 Lispからネイティブコードへのコンパイル

the previous chapterで述べたバイトコンパイルに加えて、EmacsではオプションでLisp関数定義をネイティブコード(native code)として知られている真のコンパイル済みコードにコンパイルすることもできます。この機能はGCCディストリビューションの一部であるlibgccjitを使用しており、そのライブラリー使用のサポートと共にEmacsがビルドされている必要があります。更にLispコードをネイティブコンパイルするために、システムにGCCとBinutils(アセンブラとリンカ)がインストールされている必要があります。

Emacsのカレントプロセスでネイティブコンパイル済みLispコードの生成およびロードが可能かどうか判断するには、native-comp-available-p (ネイティブコンパイル関数を参照)を呼び出してください。

バイトコンパイル済みコードとは異なり、ネイティブコンパイル済みLispコードはマシンのハードウェアにより直接実行されるので、ホストCPUが提供できる最高スピードで実行されます。このスピードアップの結果は一般的にはそのLispコードが何を行うかに依りますが、対応するバイトコンパイル済みコードに比べて、通常は2.5から5倍高速になります。

一般的に異なるシステム間ではネイティブコードに互換性はないので、あるマシンから別のマシンへのネイティブコンパイル済みコードの可搬性はありません。ネイティブコンパイル済みコードはそれを生成したのと同じマシン、もしくは類似のマシン(同一のCPUおよびランタイムライブラリー)でのみ使用できます。ネイティブコンパイル済みコードの可搬性は、共有ライブラリー(.so.dllのファイル)の可搬性と同様です。

ネイティブコンパイル済みコードのライブラリーにはEmacs Lispプリミティブ(関数とは?を参照)とそれらの呼び出し規約に関して重大な依存性が含まれているので、Emacsは通常はバージョンの異なるEmacsが生成したネイティブコンパイル済みコードをロードしません。同一のLispコードで異なるバージョンのEmacsがネイティブコンパイルしたコードは、ネイティブコンパイル済みライブラリーをそのバージョンのEmacsだけがロードできる一意なファイル名で生成します。しかし一意なファイル名の使用により、複数の異なるバージョンのEmacsによりネイティブコンパイルされた同一ライブラリーが、同一ディレクトリーに存在することになります。

ファイルローカル変数としてno-byte-compileに非nilをバインドしても、そのファイルのネイティブコンパイルが無効になります。加えて同様の変数no-native-compileは、ファイルのネイティブコンパイルだけを無効にします。no-byte-compileno-native-compileの両方が指定された場合には、前者が優先されます。

ネイティブコンパイルによるuser-emacs-directoryのサブディレクトリー内の*.elnファイルへの結果の書き込みを防がなければならない場合もあるかもしれません。これはnative-comp-eln-load-pathの値を変更するか(ネイティブコンパイル関数を参照)、あるいは環境変数HOMEが一時的に既存ディレクトリー以外を指すようにすることで行うことができます。後者のテクニックはEmacsがトランポリン(trampolines)を生成する必要がある場合(Lispコード内においてLispプリミティブをネイティブにコンパイルするためにアドバイスまたは再定義する際に用いられる)には、依然として少数の*.elnファイルを生成するかもしれないことに注意が必要です。trampolinesを参照してください。かわりにstartup-redirect-eln-cache関数を使用してデフォルト以外のディレクトリーに*.elnファイルを書き込むよう指定できます。ネイティブコンパイル関数を参照してください。


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

18.1 ネイティブコンパイル関数

ネイティブコンパイルはバイトコンパイル(バイトコンパイルを参照)の副作用として実装されています。したがってLispコードをネイティブコンパイルすると、同様にバイトコードが常に生成されるため、バイトコンパイル用にLispコードを準備する際の規則や注意事項(バイトコンパイル関数を参照)は、ネイティブコンパイルでも同じようにすべて有効です。

native-compile関数により単一の関数やマクロ、あるいはLispコードのファイル全体をネイティブコンパイルできます。ファイルをネイティブコンパイルすると、それに対応するバイトコードの.elcファイルと、ネイティブコードの.elnファイルの両方が生成されます。

ネイティブコンパイルでは警告やエラーが生成されるかもしれません。これらは通常は*Native-compile-Log*と呼ばれるバッファーに記録されます。このバッファーではインタラクティブなセッションではLIMPLEという特別なモードが使用されます。このモードではログにたいして適切なfont-lockロックをセットアップされて、それ以外はFundamentalモードと同じです。ネイティブコンパイルの結果メッセージのロギングは変数native-comp-verboseで制御できます(ネイティブコンパイル関数を参照)。

Emacsが非インタラクティブに実行されている際には、ネイティブコンパイルによって生成されたメッセージはmessage (エコーエリアへのメッセージの表示を参照)の呼び出しによって報告されます。これは通常はEmacsを呼び出した端末の標準エラーストリームに表示されます。

Function: native-compile function-or-file &optional output

この関数はfunction-or-fileをネイティブコードにコンパイルする。引数function-or-fileにはコンパイルする関数シンボル、Lispフォーム、またはEmacs Lispソースコードを含むファイル名(文字列)を指定できる。オプション引数outputが与えられた場合には、コンパイル済みコードを書き込むファイルの名前を指定する文字列でなければならない。それ以外の場合には、function-or-fileが関数かLispフォームならコンパイル済みオブジェクト、ファイル名ならコンパイル済みコード用に作成したファイルの完全な絶対ファイル名をリターンする。出力ファイルにはデフォルトで拡張子.elnが与えられる。

この関数はlibgccjitを通じて別のサブプロセス内でGCCを呼び出すネイティブコンパイルの最終フェーズを実行する。これはこの関数を呼び出したプロセスとして、同じEmacs実行可能形式を呼び出す。

Function: batch-native-compile &optional for-tarball

この関数はbatchモードでEmacsのコマンドラインで指定されたファイルにたいしてネイティブコンパイルを実行する。これはコンパイル完了によりEmacsをkillするので、Emacsのバッチ実行でのみ使用しなければならない。1つ以上のファイルでコンパイルが失敗すると、Emacsプロセスはそれ以外のすべてのファイルのコンパイルを試みて、非0のexitステータスで終了する。オプション引数for-tarballが非nilなら、この関数はコンパイルした結果の.elnファイルをnative-comp-eln-load-pathに記述された最後のディレクトリーに配置する(ライブラリー検索を参照)。これは初回にEmacsソースtarballをビルドするときに、ソースtarballに含まれていないネイティブコンパイル済みファイルをユーザーのキャッシュディレクトリーではなくビルドツリー内に生成する必要がある際に使用されることを意図している。

ネイティブコンパイルはメインのEmacsプロセスのサブプロセス中で、全体を非同期に実行できます。これによりバックグラウンドでコンパイルを実行する間、メインのEmacsプロセスをフリーにできます。これはEmacsにロードされた任意のLispファイルやバイトコンパイル済みLispファイルを、Emacsがネイティブコンパイルするために使用する手法です。サブプロセスをこのように使用することによって、ネイティブコンパイルではバイトコンパイルでは発生しない警告やエラーが生成されるかもしれず、それ故に正しく機能するようにLispコードの修整が必要かもしれないことに注意してください。詳細はネイティブコンパイル関数native-comp-async-report-warnings-errorsを参照してください。

Function: native-compile-async files &optional recursively load selector

この関数はfilesという名前のファイルを非同期にコンパイルする。引数filesは単一のファイル名(文字列)、または1つ以上のファイルおよび/またはディレクトリー名のリストであること。このリスト中にディレクトリーが与えられた場合には、それらのディレクトリー内で再帰的にコンパイルするように、オプション引数recursivelyは非nilであること。loadが非nilなら、Emacsはコンパイルが成功したそれぞれのファイルをロードする。オプション引数selectorによりfilesのどれをコンパイルするか制御できる。これには以下のいずれかの値を指定できる:

nilまたは省略

files内のすべてのファイルとディレクトリーを選択。

正規表現文字列

このregexpに名前がマッチするファイルとディレクトリーを選択。

関数

files内のファイルおよびディレクトリーそれぞれにたいして呼び出される述語関数。そのファイルまたはディレクトリーを選択する必要があるなら非nilをリターンすること。

複数のCPU実行ユニットをもつシステムでは、この関数はfilesが複数のファイル名の際には、通常はnative-comp-async-jobs-number (ネイティブコンパイル関数を参照)の制御の下で複数のコンパイル用サブプロセスを並行で開始する。

以下の関数により、実行時にネイティブコンパイルが利用可能かどうかをLispプログラムがテストできます。

Function: native-comp-available-p

この関数は実行中のEmacsにネイティブコンパイルのサポートがコンパイルされていれば非nilをリターンする。libgccjitを動的にロードするシステムでは、ライブラリーg利用できロードできることも確認する。ネイティブコンパイルが利用可能か事前に知る必要があるLispプログラムはこの述語を使用すること。

非同期なネイティブコンパイルはnative-comp-eln-load-path変数(ネイティブコンパイル関数を参照)で指定された最初の書き込み可能なディレクトリーのサブディレクトリーに生成した*.elnファイルを書き込む。スタートアップファイルで以下の関数を使用してこれを変更できる:

Function: startup-redirect-eln-cache cache-directory

この関数は非同期なネイティブコンパイルがcache-directory (単一のディレクトリーを表す文字列)に生成した*.elnファイルを書き込むように手配する。更にnative-comp-eln-load-pathの最初の要素がcache-directoryになるように破壊的な変更も行う。cache-directoryが絶対ファイル名でなければ、user-emacs-directory (initファイル)。を参照から相対的なファイル名と解釈する。


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

18.2 ネイティブコンパイル関数

このセクションではネイティブコンパイルを制御する変数について述べます。

User Option: native-comp-speed

この変数はネイティブコンパイルの最適化レベルを指定する。値は-1から3の数値であること。値0から3はコンパイラーの対応する最適化レベル-O0-O1、...のコマンドラインオプションと等しい。値-1はネイティブコンパイルの無効化を意味する。この場合には関数およびファイルはバイトコンパイルされる。ただしバイトコード形式でコンパイルされたコードだけを含む*.elnファイルは依然として生成される((declare (speed -1))を使えばこれを関数単位で行うこともできる。declareフォームを参照)。デフォルト値は2。

User Option: native-comp-debug

この変数はネイティブコンパイルが生成するデバッグ情報のレベルを指定する。値は0から3の数値で、以下のような意味をもつ:

0

デバッグ出力なし。これがデフォルト。

1

ネイティブコードでデバッグシンボルを発行する。これはgdbのようなデバッガによるネイティブコードの電話を容易にする。

2

1と同様だが、更に疑似Cコードをダンプする。

3

2と同様、更にGCC中間パス(GCC intermediate passes)とlibgccjitログファイルをダンプする。

User Option: native-comp-verbose

この変数はネイティブコンパイルが発行する一部またはすべてのログメッセージを抑制することにより、ネイティブコンパイルの冗長性(verbosity)を制御する。値が0(デフォルト)なら、ログメッセージはすべて抑制される。1から3の値をセットすることにより、レベルが上述の値であるようなメッセージのロギングを可能にする。値には以下のような解釈がある:

0

ログなし。これがデフォルト。

1

コードの最終的なLIMPLE表現をログ。

2

LAP、最終的なLIMPLE、および追加のパス情報をログ。

3

最大の冗長性。すべてをログ。

User Option: native-comp-async-jobs-number

この変数は同時に開始するネイティブコンパイルのサブプロセスの最大数を決定する。非負の数値であること。デフォルト値0はCPU実行ユニットの半数の使用、1は単一の実行ユニットの使用を意味する。

User Option: native-comp-async-report-warnings-errors

この変数の値が非nilなら、ネイティブコンパイルの非同期サブプロセスからの警告とエラーは、メインのEmacsセッションの*Warnings*という名前のバッファーに報告される。デフォルト値のtはそのバッファーへの表示を意味する。*Warnings*バッファーをポップアップせずに警告をログするには、この変数にsilentをセットすればよい。

非同期ネイティブコンパイルで警告が生成されるのは、必要な機能にたいするrequireが欠落したファイルのコンパイルが原因であることが多い。この機能はメインのEmacsにロードされるかもしれないが、ネイティブコンパイルは常にサブプロセスから初期状態の環境で開始されるので、サブプロセスではロードされないかもしれない。

User Option: native-comp-async-query-on-exit

この変数の値が非nilなら、Emacsはexitに際して実行中のネイティブコンパイルの非同期サブプロセスをすべてkillしてexitするかどうかを尋ねる(対応する.elnファイルへの書き込みを防ぐため)。値がnil (デフォルト)なら、Emacsは問い合わせを行わずにそれらのサブプロセスをkillする。

変数native-comp-eln-load-pathはEmacsが*.elnファイルを探すディレクトリーのリストを保持します(ライブラリー検索を参照)。これは役割りの面では*.el*.elcのファイルを探すために使用されるload-pathと同じです。このリストにあるディレクトリーは非同期のネイティブコンパイルによって生成された*.elnファイルの書き込みにも使用されます。特にEmacsはこのリスト中の最初に書き込み可能なディレクトリーにファイルを書き込むでしょう。したがってこの変数の値を変更することで、ネイティブコンパイルが結果を格納する場所を制御することができます。

Variable: native-comp-jit-compilation

この変数が非nilであれば、対応する*.elnがまだ存在しないEmacsにロード済みの*.elcの非同期(別名just-in-time、あるいはJIT)なネイティブコンパイルを有効にする。このJITコンパイルはnative-comp-async-jobs-numberの値に応じて、batchモードで走行する別個のEmacsサブプロセスを使用する。LispファイルのJITコンパイルが、成功裏に終了した際にはコンパイル結果の.elnファイルがロードされて、.elcファイルによって提供されていた関数定義をコンパイルしたコードで置き換える。

native-comp-jit-compilationの値をnilにセットすることによって、JITネイティブコンパイルが無効になります。ただしたとえJITネイティブコンパイルを無効にしても、トランポリン(trampolines)を生成するために依然としてEmacsは非同期ネイティブコンパイルを開始する必要があるかもしれません。これを制御するためには、以下で説明する別の変数を使用します。

Variable: native-comp-enable-subr-trampolines

この変数はトランポリンの生成を制御する。トランポリンとはnative-comp-speedが2以上でネイティブコンパイルされたLispコードから、アドバイスまたは再定義されたLispプリミティブの呼び出しを許すために必要な小さいネイティブコード片のこと。Emacsは生成されたトランポリンを別の*.elnファイルに格納する。この変数のデフォルトの値はトランポリンファイルの生成を有効にするtだが、値をnilにセットすることでトランポリンの生成が無効になる。プリミティブにたいするアドバイスや再定義に必要となるトランポリンが利用できなければ、ネイティブコンパイルされたLispからのプリミティブ呼び出しでは再定義とアドバイスは無視されて、プリミティブは直接Cから呼び出されたかのように振る舞うことに注意。したがってあなたのLispプログラムに必要なトランポリンすべてがコンパイル済みでEmacsからアクセス可能であることが不明なら、トランポリン生成の無効化は推奨しない。

この変数の値は文字列でもよく、その場合には生成されたトランポリンである*.elnファイルを格納するディレクトリー名を指定する。このディレクトリー名はnative-comp-eln-load-pathのディレクトリーをオーバーライドする。これは必要に応じてトランポリンを生成したいものの、ユーザーのHOMEディレクトリーや*.elnが保持されるその他のパブリックディレクトリーの配下には格納したくない場合に役に立つ。ただしnative-comp-eln-load-path内のディレクトリーとは異なり、トランポリンはバージョン固有のサブディレクトリーではなくこの変数で与えられたディレクトリーに格納されることになる。このディレクトリーが絶対名でなければ、invocation-directory (オペレーティングシステムの環境を参照)に相対的なディレクトリー名と解釈される。

この変数が非nil、かつEmacsがトランポリンの生成を要するもののトランポリンを格納するための書き込み可能ディレクトリーが見つからない場合には、トランポリンをtemporary-file-directory (一意なファイル名の生成を参照)の内部に格納する。

格納するための書き込み可能ディレクトリーが見つからない、あるいはこの変数の値が文字列の際に生成されたトランポリンは、Emacsのカレントセッションの間のみ利用できる。なぜならEmacsはいずれの場所からもトランポリンを探さないからである。


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

19 Lispプログラムのデバッグ

Emacs Lispプログラム内の問題を見つけて詳細に調べる方法がいくつかあります。

入出力の問題をデバックする便利なその他のツールとして、ドリブルファイル(dribble file: 端末の入力を参照)と、open-termscript関数(端末の出力)があります。


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

19.1 Lispデバッガ

普通のLispデバッガは、フォーム評価のサスペンド機能を提供します。評価がサスペンド(一般的にはbreakの状態として知られる)されている間、実行時スタックを調べたり、ローカル変数やグローバル変数の値を調べたり変更することができます。breakは再帰編集(recursive edit)なので、Emacsの通常の編集機能が利用可能です。デバッガにエンターするようにプログラムを実行することさえ可能です。再帰編集を参照してください。


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

19.1.1 エラーによるデバッガへのエンター

デバッガに入るタイミングとして一番重要なのは、Lispエラーが発生したときです。デバッガではエラーの直接原因を調査できます。

しかしデバッガへのエンターは、エラーによる通常の結末ではありません。多くのコマンドは不適切に呼び出されたときにLispエラーをシグナルするので、通常の編集の間にこれが発生するたびデバッガにエンターするのは、とても不便でしょう。したがってエラーの際にデバッガにエンターしたいなら、変数debug-on-errorに非nilをセットします(コマンドtoggle-debug-on-errorはこれを簡単に行う方法を提供する)。

再表示コードによって呼び出されたLispエラーは、技術的な理由によりこのサブセクションで定義されている機能ではデバッグできないことに注意してください。これらについてのヘルプについては再表示エラーのデバッグを参照してください。

User Option: debug-on-error

この変数はエラーがシグナルされて、それがハンドルされていないときにデバッガを呼び出すかどうかを決定する。debug-on-errortなら、debug-ignored-errors(以下参照)にリストされているエラー以外の、すべての種類のエラーがデバッガを呼び出す。nilならデバッガを呼び出さない。

値にはエラー条件(エラーをシグナルする方法を参照)のリストも指定できる。その場合はこのリスト内のエラー条件だけによってデバッガが呼び出される(debug-ignored-errorsにもリストされているエラー条件は除外される)。たとえばdebug-on-errorをリスト(void-variable)にセットすると、値をもたない変数に関するエラーにたいしてのみデバッガが呼び出される。

eval-expression-debug-on-errorがこの変数をオーバーライドするケースがいくつかあることに注意(以下参照)。

この変数が非nilのとき、Emacsはプロセスフィルター関数と番兵(sentinel)の周囲にエラーハンドラーを作成しない。したがってこれらの関数内でのエラーは、デバッガを呼び出す。プロセスを参照のこと。

User Option: debug-ignored-errors

この変数はdebug-on-errorの値に関わらず、デバッガにエンターすべきでないエラーを指定する。変数の値はエラー条件のシンボルおよび/または正規表現のリスト。エラーがこれら条件シンボルのいずれか、またはエラーメッセージが正規表現のいずれかにマッチすれば、そのエラーはデバッガにエンターしない。

この変数の通常の値にはuser-error、および編集中に頻繁に発生するがLispプログラムのバグに起因することは稀であるような、いくつかのエラーが含まれる。しかし“稀である”ことは“絶対ない”ということではない。あなたのプログラムがこのリストにマッチするエラーによって機能しないなら、そのエラーをデバッグするためにこのリストの変更を試みるのもよいだろう。通常はdebug-ignored-errorsnilにセットしておくのが、もっとも簡単な方法である。

User Option: eval-expression-debug-on-error

この変数が非nil値(デフォルト)なら、コマンドeval-expressionの実行により一時的にdebug-on-errortがバインドされる。Evaluating Emacs Lisp Expressions in The GNU Emacs Manualを参照のこと。

eval-expression-debug-on-errornilなら、eval-expressionの間もdebug-on-errorの値は変更されない。

User Option: debug-on-signal

condition-caseでキャッチされたエラー、は通常は決してデバッガを呼び出さない。condition-caseはデバッガがそのエラーをハンドルする前にエラーをハンドルする機会を得る。

debug-on-signalを非nil値に変更すると、condition-caseの存在如何に関わらずすべてのエラーにおいてデバッガが最初に機会を得る(デバッガを呼び出すためには依然としてそのエラーがdebug-on-errordebug-ignored-errorsで指定された条件を満たさなければならない)。

たとえばemacsclientの--evalオプションによるコードの評価からバックトレースを取得するためにはこの変数をセットすると便利。この変数が非nilのときにemacsclientで評価されたLispコードがエラーをシグナルすると、バックトレースは実行中のEmacsにポップアップされる。

警告: この変数を非nilにセットすると、芳しくない効果があるかもしれない。Emacsのさまざまな部分で処理の通常の過程としてエラーがキャッチされており、そのエラーが発生したことに気づかないことさえあるかもしれない。condition-caseでラップされたコードをデバッグする必要があるなら、condition-case-unless-debug(see エラーを処理するコードの記述を参照)の使用を考慮されたい。

User Option: debug-on-event

debug-on-eventをスペシャルイベント(スペシャルイベントを参照)にセットすると、Emacsはspecial-event-mapをバイパスしてこのイベントを受け取ると即座にデバッガへのエンターを試みる。現在のところサポートされる値は、シグナルSIGUSR1SIGUSR2に対応する値のみ(これがデフォルト)。これはinhibit-quitがセットされていて、それ以外はEmacsが応答しない場合に有用かもしれない。

Variable: debug-on-message

debug-on-messageに正規表現をセットした場合は、それにマッチするメッセージがエコーエリアに表示されると、Emacsはデバッガにエンターする。たとえばこれは特定のメッセージの原因を探すのに有用かもしれない。

Variable: debug-allow-recursive-debug

*Backtrace*’バッファーのカレントスタックフレーム内のフォームはeコマンドで評価できる。またedebug中ならeC-x C-eのコマンドを使用すれば、同様のことを行うことができる。デフォルトではこれらのコマンドによってデバッガは抑制される(この時点でデバッガに(再)エンターすると、デバッグ中のコンテキストから抜け出してしまうので)。しかしdebug-allow-recursive-debugを非nil値にセットすると、これらのコマンドが再帰的にデバッガにエンターできるようになる。

initファイルロード中に発生したエラーをデバッグするには、オプション‘--debug-init’を使用する。これはinitファイルロードの間にdebug-on-errortにバインドして、通常はinitファイル内のエラーをキャッチするcondition-caseをバイパスする。


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

19.1.2 再表示エラーのデバッグ

再表示によって呼び出されたLispコード内でエラーが発生した際には、技術的な理由によりEmacsでの通常時のデバッグメカニズムが使えなくなります。このサブセクションではそのようなエラーからどのようにしてバックトレースを取得するかを説明します。デバッグ中に役に立つはずです。

これらの説明はたとえばモードライン構文:eval (モードラインのデータ構造を参照)のように、再表示から呼び出される以下のようなすべてのフック内で使用されているLispフォームに適用されます。

再表示から呼び出されたフック関数でエラーが発生すると、エラー処理によってその関数がフックから削除されているかもしれないことに注意してください。したがってそのバグを再現するためにそのフックを何らかの手段、恐らくはadd-hookを使って再初期化する必要があるでしょう。

これらのような状況下でバックトレースを生成するには、変数backtrace-on-redisplay-errorに非nilをセットします。エラーが発生するとEmacsはバッファー*Redisplay-trace*にバックトレースをダンプしますが、そのバッファーを自動的にウィンドウには表示しません。これはデバッグ中の再表示弐不必要な破壊を避けるためです。したがってswitch-to-buffer-other-frame C-x 5 bのようなコマンドによって、このバッファーを自分で表示する必要があります。

Variable: backtrace-on-redisplay-error

再表示から呼び出されたすべてのLispにたいしてエラー発生時のバックトレース生成を有効にするには、この変数に非nilをセットする。


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

19.1.3 無限ループのデバッグ

プログラムが無限にループしてリターンできないとき、最初の問題はそのループをいかに停止するかです。ほとんどのオペレーティングシステムでは、(quitさせる)C-gでこれを行うことができます。quitを参照してください。

普通のquitでは、なぜそのプログラムがループしたかについての情報は与えられません。変数debug-on-quitに非nilをセットすることにより、より多くの情報を得ることができます。無限ループの途中でデバッガを実行すれば、デバッガからステップコマンドで先へ進むことができます。ループ全体をステップで追えば、問題を解決するために十分な情報が得られるでしょう。

C-gによるquitはエラーとは判断されないので、C-gのハンドルにdebug-on-errorは効果がありません。同じようにdebug-on-quitはエラーにたいして効果がありません。

User Option: debug-on-quit

この変数はquitがシグナルされて、それがハンドルされていないときにデバッガを呼び出すかどうかを決定する。debug-on-quitが非nilなら、quit(つまりC-gをタイプ)したときは常にデバッガが呼び出される。debug-on-quitnil(デフォルト)なら、quitしてもデバッガは呼び出されない。


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

19.1.4 関数呼び出しによるデバッガへのエンター

プログラムの途中で発生する問題を調べるための有用なテクニックの1つは、特定の関数が呼び出されたときデバッガにエンターする方法です。問題が発生した関数にこれを行ってその関数をステップで追ったり、問題箇所の少し手前の関数呼び出しでこれを行って、その関数をステップオーバーしてその後をステップで追うことができます。

Command: debug-on-entry function-name

この関数はfunction-nameが呼び出されるたびにデバッガの呼び出しを要求する。

Lispコードで定義された任意の関数とマクロは、インタープリターに解釈されたコードかコンパイル済みのコードかに関わらず、エントリーにbreakをセットできる。その関数がコマンドならLispから呼び出されたときと、インタラクティブに呼び出されたときにデバッガにエンターする。(たとえばCで記述された)プリミティブ関数にもこの方法でdebug-on-entryをセットできるが、そのプリミティブがLispコードから呼び出されたときだけ効果がある。debug-on-entryはスペシャルフォームにはセットできない。

debug-on-entryがインタラクティブに呼び出されたときは、ミニバッファーでfunction-nameの入力を求める。その関数がすでにエントリーでデバッガを呼び出すようにセットアップされていたら、debug-on-entryは何も行わない。debug-on-entryは常にfunction-nameをリターンする。

以下はこの関数の使い方を説明するための例である:

(defun fact (n)
  (if (zerop n) 1
      (* n (fact (1- n)))))
     ⇒ fact
(debug-on-entry 'fact)
     ⇒ fact
(fact 3)

------ Buffer: *Backtrace* ------
Debugger entered--entering a function:
* fact(3)
  eval((fact 3))
  eval-last-sexp-1(nil)
  eval-last-sexp(nil)
  call-interactively(eval-last-sexp)
------ Buffer: *Backtrace* ------

Command: cancel-debug-on-entry &optional function-name

この関数はfunction-nameにたいするdebug-on-entryの効果をアンドゥする。インタラクティブに呼び出されたときは、ミニバッファーでfunction-nameの入力を求める。function-nameが省略またはnilなら、すべての関数にたいするbreak-on-entryをキャンセルする。エントリー時にbreakするようセットアップされていない関数にcancel-debug-on-entryを呼び出したときは何も行わない。


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

19.1.5 変数の変更時にデバッガにエンターする。

不正な変数のセッティングが関数に問題をもたらすときがあります。元のセッティングを調べるためには、変数の変更時に常にデバッガがトリガーされるようにセットアップするのが手軽な方法です。

Command: debug-on-variable-change variable

この関数はvariableの変更時に常にデバッガが呼び出されるようにアレンジする。

これはwatchpointメカニズムを使用して実装されているので同じような特徴と制限を継承する。つまりvariableのすべてのエイリアスは一緒にwatchされて、watch対象はダイナミック変数のみであり変数から参照されるオブジェクトの変更は検出されない。詳細は変数が変更されたときに実行される関数。を参照のこと。

Command: cancel-debug-on-variable-change &optional variable

この関数はvariableにたいするdebug-on-variable-changeの効果をアンドゥする。インタラクティブに呼び出されたときはミニバッファーでvariableの入力をもとめる。variableが省略かnilならすべての変数にたいする変更時のブレークを取り消す。カレントで変更時にブレークするようにセットアップされていない変数にたいしてcancel-debug-on-variable-changeの呼び出しは何も行わない。


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

19.1.6 明示的なデバッガへのエントリー

プログラム内の特定箇所に式(debug)を記述することによって、その箇所でデバッガが呼び出されるようにできます。これを行うにはソースファイルをvisitして、適切な箇所にテキスト‘(debug)’を挿入し、C-M-x(Lispモードでのeval-defunにたいするキーバインド)をタイプします。警告: 一時的なデバッグ目的のためにこれを行なう場合には、ファイルを保存する前に確実にアンドゥしてください!

(debug)’を挿入する箇所は追加フォームが評価されることができ、かつその値を無視することができる箇所でなければなりません(‘(debug)’の値を無視しないとプログラムの実行が変更されてしまうだろう!)。一般的にもっとも適した箇所は、prognまたは暗黙的なprogn(順序を参照)の内部です。

デバッグ命令を配置したいソースコード中の正確な箇所がわからないが、特定のメッセージが表示されたときにバックトレースを表示したい場合には、意図するメッセージにマッチする正規表現をdebug-on-messageにセットできます。


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

19.1.7 デバッガの使用

デバッガにエンターすると、その前に選択されていたウィンドウを1つのウィンドウに表示して、他のウィンドウに*Backtrace*という名前のバッファーを表示します。backtraceバッファーには、現在実行されているLisp関数の各レベルが1行ずつ含まれます。このバッファーの先頭は、デバッガが呼び出された理由を説明するメッセージ(デバッガがエラーにより呼び出された場合はエラーメッセージや関連するデータなど)です。

backtraceバッファーは読み取り専用で、文字キーにデバッガコマンドが定義されたDebuggerモードという特別なメジャーモードを使用します。通常のEmacs編集コマンドが利用できます。したがってエラー時に編集されていたバッファーを調べるためにウィンドウを切り替えたり、バッファーの切り替えやファイルのvisit、その他一連の編集処理を行なうことができます。しかしデバッガは再帰編集レベル(再帰編集を参照)にあり、編集が終わったらそれはbacktraceバッファーに戻って、(qコマンドで)デバッガをexitできます。デバッガをexitすることによって再帰編集を抜け出し、backtraceバッファーはバリー(bury: 覆い隠す)されます(変数debugger-bury-or-killwをセットすることによってbacktraceバッファーでqコマンドが何を行うかをカスタマイズできる。たとえばバッファーをバリーせずにkillしたいなら、この変数をkillにセットする。他の値については変数のドキュメントを調べてほしい)。

デバッガにエンターしたとき、eval-expression-debug-on-errorに一致するように変数debug-on-errorが一時的にセットされます。変数eval-expression-debug-on-errorが非nilなら、debug-on-errorは一時的にtにセットされます。ただしデバッグ中に更にエラーが発生しても、(デフォルトでは)別のデバッガをトリガーすることはありません。それはinhibit-debuggerも非nilにバインドされているからです。

デバッガはLispインタープリターの状態について想定を行うので、バイトコンパイルされて実行されなければなりません。デバッガがインタープリターに解釈されて実行されているときは、これらの想定は正しくなくなります。


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

19.1.8 バックトレース

DebuggerモードはEdebugとERT(Edebugthe ERT manual in ERT: Emacs Lisp Regression Testingを参照)がbacktrace表示にも使用するBacktraceモードから派生したモードです。

backtraceバッファーは実行されている関数と、その関数の引数の値を示します。backtraceバッファー作成時には1つのスタックフレームにたいして1行(非常に長い可能性がある)を表示します(スタックフレームとはLispインタープリターが特定の関数呼び出しに関する情報を記録する場所のこと)。もっとも最近の呼び出しが最上行になります。

backtraceではフレームを記述する行にポイントを移動してフタックフレームを指定できます。ポイントのある行のフレームがカレントフレーム(current frame)とみなされます。

関数名に下線が引かれている場合には、Emacsがソースコードの場所を知っていることを意味します。その関数名をマウスでクリックするか、そこに移動してRETをタイプすることにより、ソースコードをvisitできます。下線のない関数名や変数名にポイントがあるときにRETをタイプした場合には、もしあればそのシンボルにたいするヘルプ情報をhelpバッファーで確認することもできます。M-.にバインドされているxref-find-definitionsコマンドはbacktrace内の任意の識別子にも使用できます(Looking Up Identifiers in The GNU Emacs Manualを参照)。

backtraceでは長いリストの末尾およびベクターや構造、同じように深くネストされたオブジェクトの終端は下線つきの“...”でプリントされます。“...”上でマウスをクリックするか、その上にポイントがある状態でRETをタイプすることにより、オブジェクトの隠蔽されている部分を表示できます。省略を行う量の制御はbacktrace-line-lengthをカスタマイズしてください。

以下はbacktraceの操作と閲覧を行うコマンドのリストです:

v

カレントスタックフレームのローカル変数の表示を切り替える。

p

フレームまたは前のフレームの先頭に移動する。

n

次のフレームの先頭に移動する。

+

可読性向上のためにポイント位置に行ブレークを追加してトップレベルLispフォームにインデントする。

-

ポイント位置のトップレベルLispフォームを1行に折り畳む。

#

ポイント位置のフレームのprint-circleを切り替える。

:

ポイント位置のフレームのprint-gensymを切り替える。

.

ポイント位置のフレームの“...”で省略されたすべてのフォームを展開する。


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

19.1.9 デバッガのコマンド

(Debuggerモードの)debuggerバッファーでは通常のEmacsコマンドに加えて特別なコマンド、および前セクションで説明したBacktraceモードのコマンドが提供されます。デバッガでもっとも重要な使い方をするのは、制御フローを見ることができるコードをステップ実行するコマンドです。デバッガはインタープリターによって解釈された制御構造のステップ実行はできますが、バイトコンパイル済みの関数ではできません。バイトコンパイル済み関数をステップ実行したいなら、同じ関数の解釈された定義に置き換えてください(これを行なうにはその関数のソースをvisitして、関数の定義でC-M-xとタイプする)。プリミティブ関数のステップ実行にLispデバッガは使用できません。

デバッガのコマンドのいくつかはカレントフレームを処理します。フレームが星印で開始される場合には、そのフレームをexitすることにより再びデバッガが呼び出されることを意味します。これは関数のリターン値の検証に有用です。

以下はDebuggerモードのコマンドのリストです:

c

デバッガをexitして実行を継続する。これはあたかもデバッガにエンターしなかったかのようにプログラムの実行を再開する(デバッガ内で行った変数値やデータ構造の変更などの副作用は除外)。

d

実行を継続するが、次にLisp関数が何か呼び出されたときはデバッガにエンターする。これによりある式の下位の式をステップ実行して、下位の式が計算する値や行うことを確認できる。

デバッガにエンターした関数呼び出しにたいして、この方法で作成されたスタックフレームには自動的にフラグがつくため、そのフレームをexitすると再びデバッガが呼び出される。このフラグはuコマンドを使用してキャンセルできる。

b

カレントフレームにフラグをつけるので、そのフレームをexitするときデバッガにエンターする。この方法でフラグがつけられたフレームは、backtraceバッファーでスターのマークがつく。

u

カレントフレームをexitしたときデバッガにエンターしない。これはそのフレームのbコマンドをキャンセルする。目に見える効果としてはbacktraceバッファーの行からスターが削除される。

j

bと同じようにカレントフレームにフラグをつける。その後にcのように実行を継続するが、debug-on-entryによりセットアップされたすべての関数にたいするbreak-on-entryを一時的に無効にする。

e

ミニバッファーのLisp式を読み取り、(関連するlexical環境が適切なら)それを評価してエコーエリアに値をプリントする。デバッガは特定の重要な変数とバッファーを処理の一部として変更する。eは一時的にデバッガの外部からそれらの値をリストアするので、それらを調べて変更できる。これによりデバッガはより透過的になる。対照的にデバッガ内でM-:は特別なことを行わず、デバッガ内での変数の値を表示する。このコマンドは既存のエラーの最上位の上に新たなエラーとして式の評価によるエラーを追加しないように、デフォルトでは評価の間はデバッガを抑止する。これはユーザーオプションdebug-allow-recursive-debugを非nil値にセットすることによってオーバーライドできる。

R

eと同様だがバッファー*Debugger-record*内の評価結果も保存する。

q

デバッグされているプログラムを終了して、Emacsコマンド実行のトップレベルにリターンする。

C-gによりデバッガにエンターしたが、実際はデバッグではなくquitしたいときはqコマンドを使用する。

r

デバッガから値をリターンする。ミニバッファーで式を読み取ってそれを評価することにより値が計算される。

dコマンドは、(bによるリクエストやdによるそのフレームへのエンターによる)Lisp呼び出しフレームからのexitでデバッガが呼び出されたときに有用である。rコマンドで指定された値は、そのフレームの値として使用される。これはdebugを呼び出して、そのリターン値を使用するときにも有用。それ以外はrcと同じ効果をもち、指定されたリターン値は問題とはならない。

エラーによりデバッガにエンターしたときはrコマンドは使用できない。

l

呼び出されたときにデバッガを呼び出す関数をリストする。これはdebug-on-entryによりエントリー時にbreakするようセットされた関数のリストである。


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

19.1.10 デバッガの呼び出し

以下ではデバッガを呼び出すために使用される関数debugの完全な詳細を説明します。

Command: debug &rest debugger-args

この関数はデバッガにエンターする。この関数は*Backtrace*(デバッガへの2回目以降の再帰エントリーでは*Backtrace*<2>、...)という名前のバッファーにバッファーを切り替えて、Lisp関数呼び出しについての情報を書き込む。それから再帰編集にエンターして、Debuggerモードでbacktraceバッファーを表示する。

Debuggerモードのコマンドcdjrは再帰編集をexitする。その後、debugは以前のバッファーに戻って、debugを呼び出したものが何であれそこにリターンする。これは関数debugが呼び出し元にリターンできる唯一の方法である。

debugger-argsを使用すると、debug*Backtrace*の最上部に残りの引数を表示するしてユーザーがそれらを確認できる。以下で説明する場合を除いて、これはこれらの引数を使用する唯一の方法である。

しかしdebugへの1つ目の引数にたいする値は、特別な意味をもつ(これらの値は通常はdebugを呼び出すプログラマーではなく、Emacs内部でのみ使用される)。以下はこれら特別な値のテーブルである:

lambda

1つ目の引数がlambdaのなら、それはdebug-on-next-callが非nilのときに関数にエントリーしたことによってdebugが呼び出されたことを意味する。デバッガはバッファーのトップのテキスト行に‘Debugger entered--entering a function:’と表示する。

debug

1つ目の引数がdebugなら、それはエントリー時にデバッグされるようにセットされた関数にエントリーしたことにってdebugが呼び出されたことを意味する。デバッガはlambdaのときと同様、‘Debugger entered--entering a function:’を表示する。これはその関数のスタックフレームもマークするので、exit時にデバッガが呼び出される。

t

1つ目の引数がtなら、それはdebug-on-next-callが非nilのときに関数呼び出しの評価によってdebugが呼び出されたことを示す。デバッガはバッファーのトップの行に‘Debugger entered--beginning evaluation of function call form:’と表示する。

exit

1つ目の引数がexitのときは、exit時にデバッガを呼び出すよう以前にマークされたスタックフレームをexitしたことを示す。この場合はdebugに与えられた2つ目の引数がそのフレームからリターンされた値になる。デバッガはバッファーのトップの行に‘Debugger entered--returning value:’とリターンされた値を表示する。

error

1つ目の引数がerrorのときは、ハンドルされていないエラーまたはquitがシグナルされてデバッガにエンターした場合であり、デバッガは‘Debugger entered--Lisp error:’とその後にシグナルされたエラーとsignalへの引数を表示してそれを示す。たとえば、

(let ((debug-on-error t))
  (/ 1 0))

------ Buffer: *Backtrace* ------
Debugger entered--Lisp error: (arith-error)
  /(1 0)
...
------ Buffer: *Backtrace* ------

エラーがシグナルされた場合はおそらく変数debug-on-errorは非nilで、quitがシグナルされた場合はおそらく変数debug-on-quitは非nilである。

nil

明示的にデバッガにエンターしたいときは、debugger-argsの1つ目の引数にnilを使用する。残りのdebugger-argsはバッファーのトップの行にプリントされる。メッセージ — たとえばdebugが呼び出された条件を思い出すためのリマインダーとして — の表示にこの機能を使用できる。


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

19.1.11 デバッガの内部

このセクションではデバッガ内部で使用される関数と変数について説明します。

Variable: debugger

この関数の値はデバッガを呼び出す関数呼び出しである。値には任意個数の引数をとる関数、より具体的には関数の名前でなければならない。この関数は何らかのデバッガを呼び出すこと。この変数のデフォルト値はdebug

関数にたいしてLispが渡す1つ目の引数は、その関数がなぜ呼び出されたかを示す。引数の慣習についてはdebug(デバッガの呼び出し)に詳解がある。

Function: backtrace

この関数は現在アクティブなLisp関数呼び出しのトレースをプリントする。このトレースはdebug*Backtrace*バッファーで表示するものと等しい。リターン値は常にnil

以下の例ではLisp式で明示的にbacktraceを呼び出している。これはストリームstandard-output(この場合はバッファー‘backtrace-output’)にbacktraceをプリントする。

backtraceの各行は1つの関数呼び出しを表す。関数の引数が既知なら行に関数とその後に値が表示される。まだ計算中なら関数と未評価の引数を含むリストから行が構成される。長いリストや深くネストされた構造は省略されるかもしれない。

(with-output-to-temp-buffer "backtrace-output"
  (let ((var 1))
    (save-excursion
      (setq var (eval '(progn
                         (1+ var)
                         (list 'testing (backtrace))))))))

     ⇒ (testing nil)

----------- Buffer: backtrace-output ------------
  backtrace()
  (list 'testing (backtrace))
  (progn ...)
  eval((progn (1+ var) (list 'testing (backtrace))))
  (setq ...)
  (save-excursion ...)
  (let ...)
  (with-output-to-temp-buffer ...)
  eval((with-output-to-temp-buffer ...))
  eval-last-sexp-1(nil)
  eval-last-sexp(nil)
  call-interactively(eval-last-sexp)
----------- Buffer: backtrace-output ------------
User Option: debugger-stack-frame-as-list

この変数が非nilならバックトレースのすべてのスタックフレームはリストとして表示される。これは通常の関数呼び出しとバックトレースの特殊形式の視覚的な違いによるコストをなくして、バックトレースの可読性を向上することが目的。

debugger-stack-frame-as-listが非nilなら上記の例は以下のようになる:

----------- Buffer: backtrace-output ------------
  (backtrace)
  (list 'testing (backtrace))
  (progn ...)
  (eval (progn (1+ var) (list 'testing (backtrace))))
  (setq ...)
  (save-excursion ...)
  (let ...)
  (with-output-to-temp-buffer ...)
  (eval (with-output-to-temp-buffer ...))
  (eval-last-sexp-1 nil)
  (eval-last-sexp nil)
  (call-interactively eval-last-sexp)
----------- Buffer: backtrace-output ------------
Variable: debug-on-next-call

この変数が非nilなら、それは次のevalapplyfuncallの前にデバッガを呼び出すよう指定する。デバッガへのエンターによってdebug-on-next-callnilにセットされる。

デバッガのdコマンドは、この変数をセットすることにより機能します。

Function: backtrace-debug level flag

この関数はそのスタックフレームのlevel下位のスタックフレームのdebug-on-exitフラグにflagに応じた値をセットする。flagが非nilなら、後でそのフレームをexitするときデバッガにエンターする。そのフレームを通じた非ローカルexitでも、デバッガにエンターする。

この関数はデバッガだけに使用される。

Variable: command-debug-status

この変数はカレントのインタラクティブコマンドのデバッグ状態を記録する。コマンドがインタラクティブに呼び出されるたびに、この変数はnilにバインドされる。デバッガは同じコマンドが呼び出されたときのデバッガ呼び出しに情報を残すために、この変数をセットできる。

普通のグローバル変数ではなくこの変数を使用する利点は、そのデータが後続のコマンド呼び出しに決して引き継がれないことである。

この変数は時代遅れであり将来のバージョンで削除されるだろう。

Function: backtrace-frame frame-number &optional base

関数backtrace-frameはLispデバッガ内での使用を意図している。これはframe-numberレベル下位のスタックフレームで何の評価が行われているかに関する情報をリターンする。

そのフレームがまだ引数を評価していない、またはそのフレームがスペシャルフォームなら値は(nil function arg-forms…)

そのフレームが引数を評価して関数をすでに呼び出していたらリターン値は(t function arg-values…)

リターン値のfunctionは何であれ評価されたリストのCARとして提供される。マクロ呼び出しならlambda式。その関数に&rest引数があればリストarg-valuesの末尾に示される。

baseを指定するとframe-numberfunctionbaseであるようなフレームの上端から相対的に数えられる。

frame-numberが範囲外ならbacktrace-framenilをリターンする。

Function: mapbacktrace function &optional base

関数mapbacktraceはバックトレース上の関数がbaseであるようなフレーム(baseが省略かnilなら先頭)から順に各フレームにたいして一度functionを呼び出す。

functionevaldfuncargsflagsという4つの引数で呼び出される。

そのフレームがまだ引数を評価していない、またはそのフレームがスペシャルフォームならevaldnilargsはフォームのリスト。

フレームが引数を評価して関数を呼び出し済みならevaldtargsは値リスト。flagsはカレントフレームのプロパティのplist。サポートされるプロパティは現在のところ:debug-on-exitのみであり、そのスタックフレームのdebug-on-exitフラグがセットされていればt


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

19.2 Edebug

EdebugはEmacs Lispプログラムにたいするソースレベルデバッガです。これにより以下のことができます:

  • 式の前後でストップして評価をステップで実行する。
  • 条件付きまたは無条件のbreakpointのセット。
  • 指定された条件がtrueならストップする(グローバルbreakpoint)。
  • ストップポイントごとに停止したり、breakpointごとに簡単に停止して低速または高速にトレースを行う。
  • Edebug外部であるかのように式の結果を表示して、式を評価する。
  • 式のリストを自動的に再評価して、Edebugがディスプレイを更新するたびにそれらの結果を表示する。
  • 関数呼び出しとリターンのトレース情報を出力する。
  • エラー発生時にストップする。
  • Edebug自身のフレームを除外してbacktraceを表示する。
  • マクロとフォームの定義で引数の評価を指定する。
  • 初歩的なカバレッジテストと頻度数の取得。

以下の初めの3つのセクションは、Edebugの使用を開始するために十分な説明を行います。


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

19.2.1 Edebugの使用

EdebugでLispプログラムをデバッグするには、最初にデバッグしたいLispコードをインストルメント(instrument: 計装)しなければなりません。これを行なうもっともシンプルな方法は、関数またはマクロの定義に移動してC-u C-M-x(プレフィクス引数を指定したeval-defun)を行います。コードをインストルメントする他の手段については、Edebugのためのインストルメントを参照してください。

一度関数をインストルメントすると、その関数にたいする任意の呼び出しによってEdebugがアクティブになります。Edebugがアクティブになると、どのEdebug実行モードを選択したかに依存して、その関数をステップ実行できるように実行がストップされるか、ディスプレイを更新してデバッグコマンドにたいするチェックの間、実行が継続されます。デフォルトの実行モードstepで、これは実行をストップします。Edebugの実行モードを参照してください。

Edebugでは通常は、デバッグしているLispコードをEmacsバッファーで閲覧します。これをソースコードバッファー(source code buffer)と呼び、バッファーは一時的に読み取り専用になります。

左フリンジの矢印は、その関数で実行されている行を示します。ポイントは最初はその関数の実行されている行にありますが、ポイントを移動するとこれは真ではなくなります。

以下はfacの定義(以下を参照)をインストルメントして(fac 3)を実行した場合に通常目にするものです。ポイントはifの前の開きカッコにあります。

(defun fac (n)
=>∗(if (< 0 n)
      (* n (fac (1- n)))
    1))

関数内でEdebugが実行をストップできる位置のことを、ストップポイント(stop points)と呼びます。ストップポイントはリストであるような部分式の前後、および変数参照の後でも発生します。以下は関数fac内のストップポイントをピリオドで示したものです:

(defun fac (n)
  .(if .(< 0 n.).
      .(* n. .(fac .(1- n.).).).
    1).)

Emacs Lispモードのコマンドに加えて、ソースコードバッファーではEdebugのスペシャルコマンドが利用できます。たとえばEdebugコマンドSPCで次のストップポイントまで実行することができます。facにエントリーした後に一度SPCとタイプした場合は、以下のように表示されるでしょう:

(defun fac (n)
=>(if ∗(< 0 n)
      (* n (fac (1- n)))
    1))

式の後でEdebugが実行をストップしたときは、エコーエリアにその式の値が表示されます。

他にも頻繁に使用されるコマンドとして、ストップポイントにbreakpointをセットするb、breakpointに達するまで実行するg、Edebugをexitしてトップレベルのコマンドループにリターンするqがあります。また?とタイプするとすべてのEdebugコマンドがリストされます。


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

19.2.2 Edebugのためのインストルメント

LispコードのデバッグにEdebugを使用するためには、最初にそのコードをインストルメント(instrument: 計装)しなければなりません。コードをインストルメントすると、適切な位置でEdebugを呼び出すために追加コードが挿入されます。

関数定義でプレフィクス引数とともにコマンドC-M-x (eval-defun)を呼び出すと、それを評価する前にその定義をインストルメントします(ソースコード自体は変更しない)。変数edebug-all-defsが非nilならプレフィクス引数の意味を反転します。この場合は、C-M-xはプレフィクス引数がなければその定義をインストルメントします。edebug-all-defsのデフォルト値はnilです。コマンドM-x edebug-all-defsは変数edebug-all-defsの値を切り替えます。

edebug-all-defsが非nilならeval-regioneval-bufferもそれらが評価する定義をインストルメントします。同様にedebug-all-formsは、eval-regionが(非定義フォームさえ含むあらゆるフォームをインストルメントするべきかを制御します。これはミニバッファー内でのロードや評価には適用されません。コマンドM-x edebug-all-formsはこのオプションを切り替えます。

他にもコマンドM-x edebug-eval-top-level-formが利用でき、これはedebug-all-defsedebug-all-formsの値に関わらずトップレベルのすべてのフォームをインストルメントします。edebug-defunedebug-eval-top-level-formのエイリアスです。

Edebugがアクティブのの間、コマンドI(edebug-instrument-callee)はポイント後のリストフォームに呼び出される関数およびマクロ定義がまだインストルメントされていなければ、それらをインストルメントします。これはそのファイルのソースの場所をEdebugが知っている場合だけ可能です。この理由によりEdebugロード後は、たとえ評価する定義をインストルメントしない場合でも、eval-regionは評価するすべての定義の位置を記録します。インストルメント済み関数呼び出しにステップインするiコマンドも参照してください(ジャンプを参照)。

Edebugはすべての標準スペシャルフォーム、式引数をもつinteractiveフォーム、無名ラムダ式、およびその他の定義フォームのインストルメント方法を知っています。しかしEdebugはユーザー定義マクロが引数にたいして何を行うかを判断できないので、Edebug仕様を使用してその情報を与えなければなりません。詳細はEdebugとマクロを参照してください。

Edebugがセッション内で最初にコードをインストルメントしようとするときは、フックedebug-setup-hookを実行してからそれにnilをセットします。使おうとしているパッケージに結びつけてEdebug仕様をロードするためにこれを使用できますが、それはEdebugを使用するときだけ機能します。

Edebugがインストルメント中にシンタックスエラー(syntax error: 構文エラー)を検知した場合には、以下のように間違ったコードの箇所にポイントを残してinvalid-read-syntaxエラーをシグナルします:

error→ Invalid read syntax: "Expected lambda expression"

このようにインストルメントに失敗する可能性の1つとして、いくつかのマクロ定義をEmacsが把握していない場合があります。これに対処するためには、インストルメントしようとしている関数を定義しているファイルをロードしてください。

定義からインストルメントを削除するには、単にインストルメントを行わない方法でその定義を再評価するだけです。フォームを絶対にインストルメントせずに評価するには2つの方法があります。それはファイルからのloadによる評価と、ミニバッファーからのeval-expression(M-:)による評価です。

定義からインストルメントを削除する別の方法はedebug-remove-instrumentationコマンドの使用です。これはインストルメントしたすべてからインストルメントを削除することもできます。

Edebug内で利用可能な他の評価関数については、評価を参照してください。


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

19.2.3 Edebugの実行モード

Edebugはデバッグするプログラムの実行にたいして、いくつかの実行モードをサポートします。これらの実行モードをEdebug実行モード(Edebug execution modes)と呼びます。これらをメジャーモードやマイナーモードと混同しないでください。カレントのEdebug実行モードは、プログラムをストップする前にEdebugがどれだけ実行を継続するか — たとえばストップポイントごとにストップ、あるいは次のbreakpointまで継続など — 、およびストップする前にEdebugがどれだけ進捗を表示するかを決定します。

Edebug実行モードは、通常はある特定のモードでプログラムを継続させるコマンドをタイプすることによって指定します。以下はそれらのコマンドのテーブルです。S以外のコマンドはプログラムの実行を再開して、少なくともある長さの間だけは実行を継続します。

S

Stop(ストップ): これ以上プログラムを実行しないでEdebugのコマンドを待つ(edebug-stop)。

SPC

Step(ステップ): 次のストップポイントでストップする(edebug-step-mode)。

n

Next(次へ): 式の後にある次のストップポイントでストップする(edebug-next-mode)。ジャンプedebug-forward-sexpも参照のこと。

t

Trace(トレース): Edebugのストップポイントごとにpause(通常は1秒)する(edebug-trace-mode)。

T

Rapid trace(高速でトレース):ストップポイントごとに表示を更新するが、実際にpauseはしない(edebug-Trace-fast-mode)。

g

Go(進む): 次のbreakpointまで実行する(edebug-go-mode)。Edebugのブレークポイントを参照のこと。

c

Continue(継続): breakpointごとにpauseしてから継続する(edebug-continue-mode)。

C

Rapid continue(高速で継続): ポイントを各breakpointへ移動するがpauseしない(edebug-Continue-fast-mode)。

G

Go non-stop(ストップせず進む): breakpointを無視する(edebug-Go-nonstop-mode)。まだSやその他の編集コマンドでプログラムをストップするのは可能。

一般的に上記リストの最初のほうにある実行モードは後のほうの実行モードに比べて、プログラムをより低速に実行するか、すぐにストップさせます。

新たなEdebugレベルにエンターしたとき、Edebugは通常は最初に遭遇したインストルメント済みの関数でストップするでしょう。breakpointでのみストップするか、(たとえばカバレッジデータ収集時など)ストップさせないようにするには、edebug-initial-modeの値をデフォルトのstepからgoGo-nonstop、あるいはその他の値に変更してください(Edebugのオプションを参照)。C-x C-a C-m (edebug-set-initial-mode)でこれを容易に行うことができます:

Command: edebug-set-initial-mode

C-x C-a C-mにバインドされるこのコマンドはedebug-initial-modeをセットする。これはモードを示すキーの入力を求める。対応するモードをセットする上述8つのキーのいずれかを入力すること。

たとえば1つのコマンドからインストルメント済みの関数が複数回呼び出されたら、同じEdebugレベルに再エンターするかもしれないことに注意してください。

実行中とトレース中は、任意のEdebugコマンドをタイプすることによって実行をインタラプト(interrupt: 中断、割り込み)できます。Edebugは次のストップポイントでプログラムをストップしてからタイプされたコマンドを実行します。たとえば実行中にtをタイプすると、次のストップポイントでトレースモードに切り替えます。Sを使用すれば他に何も行わずに実行をストップできます。

関数でたまたま読み取り入力が発生した場合には、実行のインタラプトを意図してタイプされた文字は、かわりにその関数により読み取られます。そのプログラムが入力を欲するタイミングに注意を払うことで、そのような意図せぬ結果を避けることができます。

このセクションのコマンドを含むキーボードマクロは、完全には機能しません。プログラムを再開するためにEdebugからexitすると、キーボードマクロの追跡記録は失われます。これに対処するのは簡単ではありません。またEdebug外部でキーボードマクロを定義または実行しても、Edebug内部のコマンドに影響しません。通常これは利点です。Edebugのオプション内のedebug-continue-kbd-macroオプションも参照してください。

User Option: edebug-sit-for-seconds

このオプションはtraceモードとcontinueモードで実行ステップの間を何秒待つか指定する。デフォルトは1秒。


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

19.2.4 ジャンプ

このセクションで説明するコマンドは、指定された場所に達するまで実行を続けます。iを除くすべてのコマンドは、ストップ場所を確立するために一時的なbreakpointを作成してからgoモードにスイッチします。意図されたストップポイントの前にある他のストップポイントに達した場合にも実行はストップします。breakpointの詳細は、Edebugのブレークポイントを参照してください。

以下のコマンドでは、非ローカルexitはプログラムのストップを望む一時的なbreakpointをバイパスできるので、期待どおり機能しないかもしれません。

h

ポイントがある場所の近くのストップポイントへ実行を進める(edebug-goto-here)。

f

プログラムの式を1つ実行する(edebug-forward-sexp)。

o

sexpを含む終端までプログラムを実行する(edebug-step-out)。

i

ポイントの後のフォームから呼び出された関数かマクロにステップインする(edebug-step-in)。

hコマンドは一時的なbreakpointを使用してポイントのカレント位置、またはその後のストップポイントまで処理を進めます。

fコマンドは式を1つ飛び越してプログラムを実行します。より正確にはforward-sexpにより到達できる位置に一時的なbreakpointをセットしてからgoモードで実行するので、プログラムはそのbreakpointでストップすることになります。

プレフィクス引数nとともに使用すると、ポイントからn個のsexp(s-expression: S式)を超えた場所に一時的なbreakpointをセットします。ポイントを含むリストがnより少ない要素で終わるような場合には、ストップ箇所はポイントが含まれる式の後になります。

forward-sexpが見つける位置が、プログラムを実際にストップさせたい位置なのかチェックしなければなりません。たとえばcond内ではこれは正しくないかもしれません。

fコマンドは柔軟性を与えるために、forward-sexpをストップポイントではなくポイント位置から開始します。カレントのストップポイントから1つの式を実行したい場合には、まずそこにポイントを移動するためにw(edebug-where)をタイプして、それからfをタイプしてください。

oコマンドは、式の外側で実行を継続します。これはポイントを含む式の最後に一時的なbreakpointを配置します。ポイントを含むsexpが関数定義ならoはその定義内の最後のsexpの直前まで実行を継続します。もし定義内の最後のsexpの直前にポイントがある場合は、その関数からリターンしてからストップします。言い換えるとこのコマンドは最後のsexpの後にポイントがなければ、カレントで実行中の関数からexitしません。

コマンドhfoは通常は“Break”を表示して、正に評価した結果を表示する前にedebug-sit-for-secondsの間、一時停止します。edebug-sit-on-breaknilにセットすることによりこの一時停止を回避できます。Edebugのオプションを参照してください。

iコマンドは、ポイントの後のリストフォームに呼び出された関数やマクロにステップインします。そのフォームは評価されようとしているものの1つである必要はないことに注意してください。しかしそのフォームが評価されようとしている関数呼び出しなら、引数が何も評価されないうちにこのコマンドを使用しないと、遅すぎることを覚えておいてください。

iコマンドはステップインしようとしている関数やマクロがまだインストルメントされていなければ、それらをインストルメントします。これは便利かもしれませんが、それらを明示的に非インストルメントしなければ、その関数やマクロはインストルメントされたままになることを覚えておいてください。


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

19.2.5 その他のEdebugコマンド

ここではその他のEdebugコマンドを説明します。

?

Edebugのヘルプメッセージを表示する(edebug-help)。

a
C-]

1レベルを中断して以前のコマンドレベルへ戻る(abort-recursive-edit)。

q

エディターのトップレベルのコマンドループにリターンする(top-level)。これはすべてのレベルのEdebugアクティビティを含むすべての再帰編集レベルをexitする。しかしフォームunwind-protectcondition-caseで保護されたインストルメント済みのコードはデバッグを再開するかもしれない。

Q

qと同様だが、保護されたコードでもストップしない(edebug-top-level-nonstop)。

r

エコーエリアにもっとも最近の既知のコマンドを再表示する(edebug-previous-result)。

d

backtraceを表示するが、明確であるようにEdebug自身の関数は除外される(edebug-pop-to-backtrace)。

backtraceとbacktraceに作用するコマンドの説明はバックトレースを参照のこと。

backtrace内でEdebugの関数を確認したければM-x edebug-backtrace-show-instrumentation、それらを再び隠すにはM-x edebug-backtrace-hide-instrumentationを使用する。

backtraceのフレームの先頭が‘>’なら、そのフレームにたいするソースコードの場所をEdebugが知っていることを意味する。カレントフレームのソースコードにジャンプするにはsを使用する。

実行を継続したときにbacktraceバッファーは自動的にkillされる。

Edebugから再帰的にEdebugをアクティブにするコマンドを呼び出すことができます。Edebugがアクティブなときは常にqによトップレベルの終了、またはC-]による再帰編集1レベルの中断ができます。dによってすべての未解決な評価のbacktraceを表示できます。


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

19.2.6 ブレーク

Edebugのstepモードは、次のストップポイントに達したときに実行をストップします。一度開始されたEdebugの実行をストップするには、他に3つの方法があります。それはbreakpoint、グローバルbreak条件、およびソースbreakpointです。


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

19.2.6.1 Edebugのブレークポイント

Edebugを使用しているときは、テスト中のプログラム内にbreakpointを指定できます。breakpointとは実行がストップされる場所のことです。Edebugの使用で定義されている任意のストップポイントにbreakpointをセットできます。breakpointのセットと解除で影響を受けるストップポイントは、ソースコードバッファー内でポイント位置、またはポイント位置の後の最初のストップポイントです。以下はEdebugのbreakpoint用のコマンドです:

b

ポイント位置、またはポイント位置の後のストップポイントにbreakpointをセットする(edebug-set-breakpoint)。プレフィクス引数を使用すると、それは一時的なbreakpointとなり、プログラムが最初にそこで停止したときに解除される。breakpoint位置にはedebug-enabled-breakpointまたはedebug-disabled-breakpointフェイスのオーバーレイが配置される。

u

(もしあれば)ポイント位置、またはポイント位置の後のストップポイントにあるbreakpointを解除(unset)する(edebug-unset-breakpoint)。

U

カレントフォーム内のすべてのbreakpointにポイントのセットを解除する(edebug-unset-breakpoints)。

D

ポイント付近のbreakpointの有効と無効を切り替える(edebug-toggle-disable-breakpoint)。このコマンドは主にbreakpointが条件つきであり、そのコンディションの再作成に幾分かの作業を要する場合に有用。

x condition RET

conditionを評価して非nil値になる場合だけプログラムをストップする条件付きbreakpointをセットする(edebug-set-conditional-breakpoint)。プレフィクス引数を指定すると一時的なbreakpointになる。

B

カレント定義内の次のbreakpointにポイントを移動する(edebug-next-breakpoint)。

Edebug内ではbでbreakpointをセットして、uでそれを解除できます。最初に望ましいストップポイントにポイントを移動してから、そこにbreakpointをセットまたは解除するためにbまたはuをタイプします。breakpointがない場所でbreakpointを解除しても影響はありません。

ある定義の再評価や再インストルメントを行うと、以前のbreakpointはすべて削除されます。

条件付きbreakpoint(conditional breakpoint)は、プログラムがそこに達するたびに条件をテストします。条件を評価した結果エラーが発生した場合、エラーは無視されて結果はnilになります。条件付きbreakpointをセットするにはxを使用して、ミニバッファーで条件式を指定します。以前にセットされた条件付きbreakpointがあるストップポイントに条件付きbreakpointをセットすると、以前の条件式がミニバッファーに配置されるのでそれを編集できます。

プレフィクス引数を指定してbreakpointをセットするコマンドを使用することによって、一時的な条件付きbreakpoint、および無条件のbreakpointを作成できます。一時的なbreakpointによりプログラムがストップしたとき、そのbreakpointは自動的に解除されます。

Go-nonstopモードを除き、Edebugは常にbreakpointでストップ、またはpauseします。Go-nonstopモードではbreakpointは完全に無視されます。

breakpointがどこにあるか探すにはBコマンドを使用します。このコマンドは同じ関数内からポイント以降にある次のbreakpoint(ポイント以降にbreakpointが存在しなければ最初のbreakpoint)にポイントを移動します。このコマンドは実行を継続せずに、単にバッファー内のポイントを移動します。


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

19.2.6.2 グローバルなブレーク条件

グローバルbreak条件(global break condition)は指定された条件が満たされたとき、それがどこで発生したかによらず、実行をストップします。Edebugは、すべてのストップポイントでグローバルbreak条件を評価します。これが非nil値に評価された場合は、あたかもそのストップポイントにbreakpointがあったかのように、実行をストップまたはpauseします(実行モードによる)。条件の評価でエラーを取得した場合は、実行をストップしません。

条件式はedebug-global-break-conditionに格納されます。EdebugがアクティブなときにソースバッファーからXコマンドを使用するか、Edebugがロードされている間は任意のバッファーから任意のタイミングでC-x X X(edebug-set-global-break-condition)を使用して新たな式を指定できます。

グローバルbreak条件は、コード内のどこでイベントが発生したかを見つけるもっともシンプルな方法ですが、コードの実行は遅くなります。そのため使用しないときは条件をnilにリセットするべきです。


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

19.2.6.3 ソースブレークポイント

定義内のすべてのbreakpointは、それをインストルメントするたびに失われます。breakpointが失われないようにしたければソースコード内で単に関数edebugを呼び出すソースbreakpoint(source breakpoint)を記述できます。もちろんそのような呼び出しを条件付きすることにもできます。たとえばfac関数内に以下のような行を1行目に挿入して、引数が0になったときストップさせることができます:

(defun fac (n)
  (if (= n 0) (edebug))
  (if (< 0 n)
      (* n (fac (1- n)))
    1))

facの定義がインストルメントされて呼び出されたとき、edebug呼び出しはbreakpointとして振る舞います。実行モードに応じてEdebugはそこでストップまたはpauseします。

edebugが呼び出されたときにインストルメント済みのコードが実行されていなければ、この関数はdebugを呼び出します。


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

19.2.7 エラーのトラップ

エラーがシグナルされて、それがcondition-caseでハンドルされていないとき、Emacsは通常はエラーメッセージを表示します。Edebugがアクティブでインストルメント済みコードの実行中は、ハンドルされていないエラーには通常はEdebugが対応します。オプションedebug-on-erroredebug-on-quitでこれをカスタマイズできます。Edebugのオプションを参照してください。

Edebugがエラーに対応するときは、エラー発生箇所の前にある最後のストップポイントを表示します。この場所はインストルメントされていない関数の呼び出しであったり、その関数内で実際にエラーが発生したのかもしれません。バインドされていない変数に関するエラーの場合は、最後の既知のストップポイントは、その不正な変数参照から遠く離れた場所にあるかもしれません。そのような場合には完全なbacktraceを表示したいと思うでしょう(その他のEdebugコマンドを参照)。

Edebugがアクティブの間にdebug-on-errordebug-on-quitを変更すると、それらの変更はEdebugが非アクティブになったとき失われます。さらにEdebugの再帰編集の間、これらの変数はEdebugの外部でもっていた値にバインドされます。


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

19.2.8 Edebugのビュー

これらのEdebugコマンドは、Edebugにエントリーする前のバッファーの外観とウィンドウの状態を調べるコマンドです。外部のウィンドウ構成はウィンドウのコレクションとその内容であり、それらは実際にはEdebugの外部にあります。

P
v

外部のウィンドウ構成ビューに切り替える(edebug-view-outside)。EdebugにリターンするにはC-x X wをタイプする。

p

一時的に外部のカレントバッファーを表示して、ポイントもその外部の位置になる(edebug-bounce-point)。Edebugにリターンする前に1秒 pauseする。プレフィクス引数nを指定すると、かわりにn秒 pauseする。

w

ソースコードバッファー内のカレントストップポイントにポイントを戻す(edebug-where)。

このコマンドを同じバッファーを表示する異なるウィンドウで使用すると、そのウィンドウは将来カレント定義を表示するために代用される。

W

Edebugが外部のウィンドウ構成の保存とリストアを行うかどうかを切り替える(edebug-toggle-save-windows)。

プレフィクス引数を指定すると、Wは選択されたウィンドウの保存とリストアだけを切り替える。ソースコードバッファーを表示していないウィンドウを指定するには、グローバルキーマップからC-x X Wを使用しなければならない。

v、または単にpでカレントバッファーにポイントを反跳させれば、たとえ通常は表示されないウィンドウでも外部のウィンドウ構成を調べることができます。

ポイントを移動した後にストップポイントに戻りたいときがあるかもしれません。これはソースコードバッファーからwで行うことができます。どのバッファーにいてもC-x X wを使用すれば、ソースコードバッファー内のストップポイントに戻ることができます。

保存をオフにするためにWを使用するたびに、Edebugは外部のウィンドウ構成を忘れます。そのためたとえ保存をオンに戻しても、(プログラムを実行することによって)次にEdebugをexitしたとき、カレントウィンドウ構成は変更されないまま残ります。しかし十分な数のウィンドウをオープンしていない場合には、*edebug**edebug-trace*の再表示があなたが見たいバッファーと競合するかもしれません。


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

19.2.9 評価

Edebug内では、まるでEdebugが実行されていないかのように式を評価できます。式の評価とプリントに際して、Edebugは不可視になるよう試みます。副作用をもつ式の評価は、Edebugが明示的に保存とリストアを行うデータへの変更を除いて期待したとおり機能するでしょう。このプロセスの詳細は、コンテキスト外部を参照してください。

e exp RET

Edebugのコンテキスト外で式expを評価する(edebug-eval-expression)。つまり、Edebugはその式への干渉を最小限にしようと努める。評価した結果はエコーエリア、プレフィックス引数を与えられた場合には新たにバッファーをポップアップしてそこに結果を見栄えよくプリントする。

このコマンドはデフォルトでは評価の間はデバッガを抑制する。これにより評価される式内のエラーが新たなエラーとして既存のエラーの最上位に追加されることはなくなる。ユーザーオプションdebug-allow-recursive-debugを非nilにセットすれば、これをオーバーライドできる。

M-: exp RET

Edebug自身のコンテキスト内で式expを評価する(eval-expression)。

C-x C-e

ポイントの前の式をEdebugのコンテキスト外で評価する(edebug-eval-last-sexp)。プレフィックス引数が0(C-u 0 C-x C-e)なら、(文字列やリストのような)長いアイテムを短縮しない。それ以外のプレフィックスなら別のバッファーに値を見栄えよくプリントする。

Edebugはcl.el内の構文(lexical-letmacroletsymbol-macrolet)によって作成された、レキシカル(lexical)にバインドされたシンボルへの参照を含む式の評価をサポートします。


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

19.2.10 評価リストバッファー

式をインタラクティブに評価するために、*edebug*と呼ばれる評価リストバッファー(evaluation list buffer)を使用できます。Edebugがディスプレイを更新するたびに自動的に評価される、式の評価リスト(evaluation list)もセットアップできます。

E

評価リストバッファー*edebug*に切り替える(edebug-visit-eval-list)。

*edebug*バッファーでは、以下の特別なコマンドと同様にLisp Interactionモード(Lisp Interaction in The GNU Emacs Manualを参照)のコマンドも使用できます。

C-j

ポイントの前の式をコンテキスト外で評価して、その値をバッファーに挿入する(edebug-eval-print-last-sexp)。プレフィクス引数が0(C-u 0 C-j)なら、(文字列やリストのような)長いアイテムを短縮しない。

C-x C-e

Edebugのコンテキスト外でポイントの前の式を評価する(edebug-eval-last-sexp)。

C-c C-u

バッファー内のコンテンツから新たに評価リストを構築する(edebug-update-eval-list)。

C-c C-d

ポイントのある評価リストグループを削除する(edebug-delete-eval-item)。

C-c C-w

ソースコードバッファーに切り替えてカレントストップポイントに戻る(edebug-where)。

評価リストウィンドウ内では、*scratch*にいるときと同様にC-jC-x C-eで式を評価できますが、それらはEdebugのコンテキスト外で評価されます。

インタラクティブに入力した式(と結果)は、実行を継続すると失われます。しかし実行がストップされるたびに評価されるように、式から構成される評価リストをセットアップできます。

これを行なうには、評価リストバッファー内で1つ以上の評価リストグループ(evaluation list group)を記述します。評価リストグループは1つ以上のLisp式から構成されます。グループはコメント行で区切られます。

コマンドC-c C-u(edebug-update-eval-list)はバッファーをスキャンして、各グループの最初の式を使用して評価リストを再構築します(これはグループの2つ目の式は以前に計算、表示されている値だという発想からである)。

Edebugにエントリーするたびに、評価リストの各式(および式の後に式のカレント値)をバッファーに挿入して再表示します。これはコメント行も挿入するので、各式はそのグループの一員となります。したがってバッファーのテキストを変更せずにC-c C-uとタイプすると、評価リストは実際には変更されません。

評価リストからの評価の間にエラーが発生すると、それが式の結果であるかのようにエラーメッセージが文字列で表示されます。したがってカレントで無効な変数を使用する式によって、デバッグが中断されることはありません。

以下はいくつかの式を評価リストウィンドウに追加したとき、どのように見えるかの例です:

(current-buffer)
#<buffer *scratch*>
;---------------------------------------------------------------
(selected-window)
#<window 16 on *scratch*>
;---------------------------------------------------------------
(point)
196
;---------------------------------------------------------------
bad-var
"Symbol's value as variable is void: bad-var"
;---------------------------------------------------------------
(recursion-depth)
0
;---------------------------------------------------------------
this-command
eval-last-sexp
;---------------------------------------------------------------

グループを削除するにはグループ内にポイントを移動してC-c C-dをタイプするか、単にグループのテキストを削除してC-c C-uで評価リストを更新します。評価リストに新たな式を追加するには、適切な箇所にその式を挿入して新たなコメント行を挿入してからC-c C-uをタイプします。コメント行にダッシュを挿入する必要はありません — 内容は関係ないのです。

*edebug*を選択した後にC-c C-wでソースコードバッファーにリターンできます。*edebug*は実行を継続したときにkillされて、次回必要となったときに再作成されます。


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

19.2.11 Edebugでのプリント

プログラム内の式が循環リスト構造(circular list structure)を含む値を生成する場合は、Edebugがそれをプリントしようとしたときエラーとなるかもしれません。

循環構造への対処の1つとして、print-lengthprint-levelにプリントの切り詰めをセットする方法があります。Edebugは変数edebug-print-lengthedebug-print-levelの値(非nil値なら)を、これらの変数にバインドします。出力に影響する変数を参照してください。

User Option: edebug-print-length

nilなら結果をプリントするときEdebugはprint-lengthをこの値にバインドする。デフォルト値は50

User Option: edebug-print-level

nilなら結果をプリントするときEdebugはprint-levelをこの値にバインドする。デフォルト値は50

print-circleを非nil値にバインドして、循環構造や要素を共有する構造にたいして、より参考になる情報をプリントするよういにすることもできます。

以下は循環構造を作成するコードの例です:

(setq a (list 'x 'y))
(setcar a a)

print-circleが非nilなら、プリント関数(prin1等)はaを‘#1=(#1# y)’のようにプリントします。‘#1=’という表記はその後の構造をラベル‘1’とラベル付けして、‘#1#’表記はその前にラベル付けされた構造を参照しています。この表記はリストとベクターの任意の共有要素に使用されます。

User Option: edebug-print-circle

nilなら結果をプリントするときEdebugはprint-circleをこの値にバインドする。デフォルト値はt

プリントをどのようにカスタマイズできるかに関する詳細は出力関数を参照してください。


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

19.2.12 トレースバッファー

Edebugは実行トレースを*edebug-trace*という名前のバッファーに格納して記録できます。実行トレースとは関数呼び出しとリターンのログのことで関数名と引数、および値を確認できます。トレースレコードを有効にするには、edebug-traceを非nil値にセットしてください。

トレースバッファーの作成は実行モードのトレースの使用(Edebugの実行モードを参照)と同じではありません。

トレースレコードが有効なときは、関数へのエントリーとexitのたびにトレースバッファーに行が追加されます。関数エントリーレコードは‘::::{’、および関数名と引数の値によって構成されます。関数のexitレコードは‘::::}’、および関数名と関数の結果によって構成されます。

:’の数は関数エントリーの再帰レベルを表します。トレースバッファーでは関数呼び出しの開始と終了の検索に‘{’と‘}’を使用できます。

関数edebug-print-trace-beforeedebug-print-trace-afterを再定義することによって、関数エントリーと関数exitのトレースレコードをカスタマイズできます。

Macro: edebug-tracing string body…

このマクロはbodyフォームの実行活動にたいして追加のトレース情報をリクエストする。引数stringはトレースバッファーに配置する‘{’と‘}’の後のテキストを指定する。すべての引数は評価されて、edebug-tracingbody内の最後のフォームの値をリターンする。

Function: edebug-trace format-string &rest format-args

この関数はトレースバッファーにテキストを挿入する。テキストは(apply 'format format-string format-args)によって計算される。エントリー間の区切りとして改行も付け加える。

edebug-tracingedebug-traceは、たとえEdebugが非アクティブでも、呼び出されたときは常にトレースバッファーに行を挿入します。トレースバッファーへのテキストの追加により、挿入された最後の行が見えるようにウィンドウもスクロールします。


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

19.2.13 カバレッジテスト

Edebugは基本的なカバレッジテスト(coverage test)と実行頻度(execution frequency)の表示を提供します。

カバレッジテストは、すべての式の結果と以前の結果を比較することによって機能します。プログラム内の各フォームがカレントEmacsセッション内でカバレッジテストを開始して以降に、2つの異なる値をリターンしたら、それらのフォームはカバーされたと判断されます。したがってプログラムにカバレッジテストを行なうには、そのプログラムをさまざまなコンディション下で実行して、プログラムが正しく振る舞うかに注目します。異なるコンディション下で十分にテストして、すべてのフォームが異なる2つの値をリターンしたとき、Edebugはそのことを告げるでしょう。

カバレッジテストにより実行速度が低下するので、edebug-test-coverageが非nilのときだけカバレッジテストが行なわれます。頻度計数(frequency count)はたとえ実行モードがGo-nonstopでも、カバレッジテストが有効か無効かに関わらずすべての式にたいして行われます。

定義にたいするカバレッジ情報と頻度数の両方を表示するにはC-x X = (edebug-display-freq-count)を使用します。単に= (edebug-temp-display-freq-count)とすると、他のキーをタイプするまでの間だけ一時的に同様の情報を表示します。

Command: edebug-display-freq-count

このコマンドはカレント定義の各行の頻度数を表示する。

このコマンドはコードの各行の下にコメント行として頻度数を挿入する。1回のundoコマンドですべての挿入をアンドゥできる。頻度数は式の前の‘(’か式の後の‘)’、または変数の最後の文字の下に表示される。表示をシンプルにするために同一行にたいして式の以前頻度数と頻度数が同じ場合は表示しない。

ある式にたいする頻度数の後に文字‘=’がある場合は、その式が評価されるたびに同じ値を毎回リターンしていることを表す。言い換えるとカバレッジテストの目的からは、その式はまだカバーされていないということである。

ある定義にたいして頻度数とカバレッジデータを明確にするには、単にeval-defunで再インストルメントすればよい。

たとえばソースのbreakpointで(fac 5)を評価した後にedebug-test-coveragetにセットすると、breakpointに達したときの頻度データは以下のようになります:

(defun fac (n)
  (if (= n 0) (edebug))
;#6           1      = =5
  (if (< 0 n)
;#5         =
      (* n (fac (1- n)))
;#    5               0
    1))
;#   0

コメント行はfacが6回呼び出されたことを表しています。最初のif命令は毎回同じ結果を5回リターンしています。同じ結果という意味では2つ目のifの条件にも当てはまります。facの再帰呼び出しは結局リターンしません。


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

19.2.14 コンテキスト外部

Edebugはデバッグ中のプログラムにたいして透過的であろうと努めますが完全には達成されません。Edebugはeや評価リストバッファーで式を評価するときにも、一時的に外部のコンテキストをリストアして透明化を試みます。このセクションではEdebugがリストアするコンテキストと、Edebugが完全に透過的になるのに失敗する理由を正確に説明します。


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

19.2.14.1 停止するかどうかのチェック

Edebugにエンターするときは常に特定のデータの保存とリストアを行なう必要があり、それはトレース情報を作成するか、あるいはプログラムを停止するかを決定する前に行なう必要があります。

  • max-lisp-eval-depth (evalについてを参照)はEdebugがスタックに与える影響の低減効果を高める。しかしそれでもEdebug使用時にスタック空間を使い切ってしまうことがあり得る。非常に大きいクォートされたリストを含むコードをインストルメントすることによってEdebugが再帰深さの制限に達してしまうようなら、edebug-max-depthの値を大きくすることもできる。
  • キーボードマクロの実行状態の保存とリストアが行われる。Edebugがアクティブの間、edebug-continue-kbd-macronilならexecuting-kbd-macronilにバインドされる。

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

19.2.14.2 Edebugの表示の更新

(たとえばtraceモードなどで)Edebugが何かを表示する必要があるときは、Edebugの外部からカレントウィンドウ構成(ウィンドウの構成を参照)を保存します。Edebugをexitするときに、以前のウィンドウ構成がリストアされます。

Emacsはpause時だけ再表示を行います。通常は実行を継続すると、そのプログラムはbreakpointかステップ実行後にEdebugに再エンターして、その間にpauseや入力の読み取りはありません。そのような場合、Emacsが外部の構成を再表示する機会は決してありません。結果としてユーザーが目にするウィンドウ構成は、前回Edebugが中断なしでアクティブだったときのウィンドウ構成と同じになります。

何かを表示するためにEdebugにエントリーすることにより、(たとえこれらのうちのいくつかは、エラーやquitがシグナルされたときは故意にリストアしないデータだとしても)以下のデータも保存とリストアが行われます。

  • カレントバッファー、およびカレントバッファー内のポイントとマークの位置が保存およびリストアされる。
  • edebug-save-windowsが非nilなら、外部のウィンドウ構成の保存とリストアが行われる(Edebugのオプションを参照)。edebug-save-windowsの値がリストの場合には、保存とリストアはリストされたウィンドウにたいしてのみ行われる。

    エラーやquitではウィンドウ構成はリストアされないが、save-excursionがアクティブなら、たとえエラーやquitのときでも外部の選択されたウィンドウが再選択される

    ただしソースコードバッファーのウィンドウの開始位置と水平スクロールはリストアされないので、表示はEdebug内で整合性が保たれたままとなる。

    外部のウィンドウ構成の保存やリストアによってデバッグ中のLispプログラムが作用するバッファーのポイントが変更されてしまうときがある(特にプログラムがポイントを移動する場合)。もしこれが発生してデバッグに干渉するようなら、edebug-save-windowsnilをセットすることをお勧めする(Edebugのオプションを参照)。

  • edebug-save-displayed-buffer-pointsが非nilなら、表示されているそれぞれのバッファー内のポイント値は保存およびリストアされる。
  • 変数overlay-arrow-positionoverlay-arrow-stringは保存とリストアが行われるので、同じバッファー内の他の場所の再帰編集から安全にEdebugを呼び出せる。
  • cursor-in-echo-areanilにローカルにバインドされるのでカーソルはそのウィンドウ内に現れる。

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

19.2.14.3 Edebugの再帰編集

Edebugにエンターしてユーザーのコマンドが実際に読み取られるとき、Edebugは以下の追加データを保存(および後でリストア)します:

  • カレントマッチデータ。マッチデータを参照のこと。
  • 変数last-commandthis-commandlast-command-eventlast-input-eventlast-event-framelast-nonmenu-eventtrack-mouse。Edebug内のコマンドはEdebug外部のこれらの変数に影響をあたえない。

    Edebug内でのコマンド実行はthis-command-keysによりリターンされるキーシーケンスを変更でき、Lispからそのキーシーケンスをリセットする方法はない。

    Edebugはunread-command-eventsの値の保存とリストアができない。この変数が重要な値をもつときにEdebugにエンターすると、デバッグ中のプログラムの実行に干渉する可能性がある。

  • Edebug内で実行された複雑なコマンドは変数command-historyに追加される。これは稀に実行に影響を与える。
  • Edebug内では再帰の深さがEdebug外部の再帰の深さより1つ深くなる。これは自動的に更新される評価リストウィンドウでは異なる。
  • standard-outputstandard-inputは、recursive-editによってnilにバインドされるがEdebugは評価の間それらを一時的にリストアする。
  • キーボードマクロ定義の状態は保存およびリストアされる。Edebugがアクティブの間、defining-kbd-macroedebug-continue-kbd-macroにバインドされる。

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

19.2.15 Edebugとマクロ

Edebugが正しくマクロを呼び出す式をインストルメントするには、いくつかの特定な配慮が必要になります。このサブセクションでは、その詳細を説明します。


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

19.2.15.1 マクロ呼び出しのインストルメント

EdebugがLispマクロを呼び出す式をインストルメントするときは、正しくインストルメントを行なうために、そのマクロに関して追加の情報が必要になります。これはマクロ呼び出しのどの部分式(subexpression)が評価されるフォームなのか推測する方法がないからです(評価はマクロのbodyで明示的に発生するかもしれないし、展開結果が評価されるとき、または任意のタイミングで行われるかもしれない)。

したがってEdebugが処理するかもしれないすべてのマクロにたいして、そのマクロの呼び出しフォーマットを説明するためのEdebug仕様(Edebug specification)を定義しなければなりません。これを行なうにはマクロ定義にdebug宣言を追加します。以下はマクロ例for(マクロ引数の多重評価を参照)にたいする簡単な仕様の例です。

(defmacro for (var from init to final do &rest body)
  "Execute a simple \"for\" loop.
For example, (for i from 1 to 10 do (print i))."
  (declare (debug (symbolp "from" form "to" form "do" &rest form)))
  ...)

このEdebug仕様はマクロ呼び出しのどの部分が評価されるフォームなのかを示しています。単純なマクロにたいするEdebug仕様は、そのマクロ定義の正式な引数リストに酷似している場合がありますが、Edebug仕様はマクロ引数に比べてより汎的です。declareフォームの詳細はマクロの定義を参照してください。

コードをインストルメントするときEdebugに仕様が確実に解るように留意してください。別ファイルで定義されたマクロを使用する関数をインストルメントする場合には、関数を含むファイル内のrequireフォームを評価するか、あるいはマクロを含むファイルを明示的にロードする必要があるかもしれません。マクロの定義がeval-when-compileでラップされていれば、それを評価する必要があるでしょう。

def-edebug-specによりマクロ定義から個々のマクロにたいしてEdebug仕様を定義することもできます。Lispで記述されたマクロ定義にたいしてはdebug宣言を追加するほうが好ましく便利でもありますが、def-edebug-specではCで実装されたスペシャルフォームにたいしてEdebug仕様を定義することが可能になります。

Macro: def-edebug-spec macro specification

マクロmacro呼び出しのどの式が評価される式かを指定する。specificationはEdebug仕様である。どちらの引数も評価されない。

引数macroには単なるマクロ名ではない、任意の実シンボルを指定できる。

以下はspecificationに指定できるシンボルと、引数を処理する方法のテーブルです。

t

すべての引数は評価のためにインストルメントされる。(body)の省略形。

シンボル

そのシンボルはかわりに使用されるEdebug仕様をもたなければならない。このインダイレクションは他の種類の仕様が見つかるまで繰り返される。これによって他のマクロの仕様を継承できる。

リスト

リストの要素はフォーム呼び出しの引数の型を記述する。仕様リストに指定できる要素については以降のセクションを参照のこと。

マクロがEdebug仕様をもたなければ、debug宣言およびdef-edebug-spec呼び出しのどちらを介しても、変数edebug-eval-macro-argsが効果を発揮します。

User Option: edebug-eval-macro-args

これはEdebugが明示的なEdebug仕様をもたないマクロ引数を扱う方法を制御する。nil(デフォルト)なら引数は評価のためにインストルメントされない。それ以外ならすべての引数がインストルメントされる。


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

19.2.15.2 仕様リスト

あるマクロ呼び出しにおいて、いくつかの引数は評価されても、それ以外の引数は評価されないような場合には、Edebug仕様のために仕様リスト(specification list)が必要となります。仕様リスト内のいくつかの要素は1つ以上の引数にマッチしますが、それ以外の要素は以降に続くすべての引数の処理を変更します。後者は仕様キーワード(specification keywords)と呼ばれ、(&optionalのように)‘&’で始まるシンボルです。

仕様リストはそれ自身がリストであるような引数にマッチする部分リスト(sublist)、あるいはグループ化に使用されるベクターを含むかもしれません。したがって部分式とグループは仕様リストをレベル階層に細分化します。仕様キーワードは部分式やグループを含むものの残りに適用されます。

仕様リストに選択肢や繰り返しが含まれる場合は、実際のマクロの呼び出しのマッチでバックトラックが要求されるかもしれません。詳細は仕様でのバックトレースを参照してください。

Edebug仕様は釣り合いのとれたカッコで括られた部分式へのマッチ、フォームの再帰処理、インダイレクト仕様を通じた再帰等の、正規表現によるマッチングとコンテキストに依存しない文法構成を提供します。

以下は仕様リストに使用できる要素と、その意味についてのテーブルです(使用例は仕様の例を参照):

sexp

評価されない単一のLispオブジェクト。インストルメントされない。

form

評価される単一の式。インストルメントされる。評価前にマクロが式のをlambdaでラップしていれば、かわりにdef-formを使用すること(以下のdef-formを参照)。

place

汎変数(generalized variable)。ジェネリック変数を参照のこと。

body

&rest formの短縮形(以下の&restを参照)。評価前にマクロが式のをlambdaでラップしていれば、かわりにdef-formを使用すること(以下のdef-formを参照)。

lambda-expr

クォートされないラムダ式。

&optional

仕様リスト内の後続の要素はオプション。マッチしない要素が出現するとEdebugはこのレベルのマッチングを停止する。

後続が非オプションの要素であるような数個の要素をオプションにするだけなら、[&optional specs…]を使用する。複数の要素すべてのマッチや非マッチを指定するには、&optional [specs…]を使用する。defunの例を参照のこと。

&rest

仕様リスト内の後続のすべての要素は0回以上繰り返される。しかし最後の繰り返しでは、仕様リスト内のすべての要素にたいするマッチングの前に式が終了しても問題はない。

数個の要素を繰り返すには[&rest specs…]を使用する。各繰り返しにおいてすべてマッチしなければならない複数要素を指定するには、&rest [specs…]を使用する。

&or

仕様リスト内の後続の各要素は選択肢である。選択肢の1つがマッチしなければならず、マッチしなければ&or仕様は失敗する。

&orに続く各リスト要素は単一の選択肢である。複数のリスト要素を単一の選択肢にグループ化するには、それらを[…]で括る。

&not

後続の各要素は&orが使用されたときのように選択肢にマッチするが、要素がマッチしたら失敗となる。マッチする要素がなければ何もマッチされないが&not仕様は成功となる。

&define

フォームを定義する仕様であることを示す。フォームを定義するEdebugの定義は、後刻(フォーム定義の実行後に)保存および実行される1つ以上のコードを含んだフォーム。

フォーム定義自体はインストルメントされない(つまりEdebugはフォーム定義の前後でストップしない)が、フォーム内部は通常はインストルメントされるであろう。&defineキーワードはリスト仕様の最初の要素であること。

nil

カレント引数レベルでマッチさせる引数が存在しなければ成功し、それ以外は失敗する。部分リスト仕様とバッククォートの例を参照のこと。

gate

引数はマッチされないがgateを通じたバックトラックは、このレベルの仕様の残りをマッチングする間は無効にされる。これは主に特定の構文エラーメッセージを一般化するために使用される。詳細は仕様でのバックトレース、およびletの例も参照のこと。

&error

&errorの後にはedebug仕様のエラーメッセージ(文字列)が続くこと。これはインストルメントをabortして、メッセージをミニバッファーに表示する。

&interpose

残りのコードのパースを関数に制御させる。これは&interpose spec fun args...のような形式をとり、Edebugがコードにたいして最初にspecをマッチして、それからspecにマッチしたコードとともにfun、パース関数pf、最後にargs...を呼び出すことを意味する。パース関数は、残りのコードのパースに使用するための仕様リストを単一の引数として期待する。これは正確に1回呼び出されて、funがリターンすることを期待されるインストルメント済みコードをリターンすること。たとえば(&interpose symbolp pcase--match-pat-args)は最初の要素がシンボルであるようなsexpにマッチしてから、pcase--match-pat-argspcase--match-pat-argsに照らしてheadとなるシンボルに対応するspecを照合、その後にそれらを引数として受け取るpfに渡す。

other-symbol

仕様リスト内のその他の要素は、述語(predicate)かインダイレクト仕様(indirect specification)である。

シンボルがEdebug仕様をもつなら、インダイレクト仕様(indirect specification)はシンボル位置に使用されるリスト仕様か、引数を処理するための関数のいずれかである。この仕様はdef-edebug-specで定義できる。

Function: def-edebug-elem-spec element specification

シンボルelementの箇所で使用するspecificationを定義する。specificationはリストでなければ鳴らす。

それ以外ならシンボルは述語(predicate)である。述語は引数とともに呼び出されてnilをリターンしたら、その仕様は失敗して引数はインストルメントされない。

適切な述語としてはsymbolpintegerpstringpvectorpatomが含まれる。

[elements…]

要素のベクターは要素を単一のグループ仕様(group specification)にグループ化する。このグループ仕様はベクター自体には何も行わない。

"string"

引数はstringという名前のシンボルである。この仕様はsymbolの名前がstringであるようなクォートされたシンボル'symbolと等価だが、文字列形式のほうが好ましい。

(vector elements…)

引数は要素が仕様内のelementsにマッチするようなベクターである。バッククォートの例を参照のこと。

(elements…)

他のリストは部分リスト仕様(sublist specification)であり、引数は要素が仕様のelementsにマッチするリストでなければならない。

部分リスト仕様はドットリスト(dotted list)かもしれず、その場合対応するリスト引数はドットリストである。かわりにドットリスト仕様の最後のCDRが、(グループ化やインダイレクト仕様による)他の部分リスト仕様かもしれない(たとえば要素が非ドットリストにマッチする(spec . [(more specs…)])))。これはバッククォートの例のような再帰仕様に有用。このような再帰を終了させるには上述のnil仕様も参照のこと。

(specs . nil)のように記述された部分リスト仕様は(specs)(specs . (sublist-elements…))(specs sublist-elements…)と等価であることに注意。

以下は&defineの後だけに出現する追加仕様のリストです。defunの例を参照してください。

&name

コードからカレントで定義しているフォーム名を抽出する。これは&name [prestring] spec [poststring] fun args...という形式をとり、Edebugがコードにたいしてspecをマッチしてから結合したカレント名、args...prestringspecにマッチしたコード、poststringとともにfunを呼び出すことを意味する。funが未指定なら、、デフォルトは引数を(前の名前と新しい名前の間に@を置いて)結合する関数。

name

引数(シンボル)は定義フォームの名前。[&name symbolp]の省略形。

定義フォームは名前フィールドをもつ必要はなく、複数の名前フィールドをもつかもしれない。

arg

引数(シンボル)は定義フォームの引数の名前である。しかしlambda-listキーワード(‘&’で始まるシンボル)は許されない。

lambda-list

これはラムダリスト(ラムダ式の引数リスト)にマッチする。

def-body

引数は定義内のコードのbodyである。これは上述のbodyと似ているが、定義のbodyはその定義に関連する情報を照会する別のEdebug呼び出しでインストルメントされていなければならない。定義内のより高位レベルのフォームリストにはdef-bodyを使用する。

def-form

引数は定義内のもっとも高位レベルの単一フォームである。これはdef-bodyと似ているが、フォームリストではなく単一フォームのマッチに使用される。特別なケースとしてdef-formはフォームが実行されるときトレース情報を出力しないことも意味する。interactiveの例を参照のこと。


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

19.2.15.3 仕様でのバックトレース

あるポイント位置で仕様がマッチに失敗しても、構文エラーがシグナルされるとは限りません。そのかわりバックトラッッキング(backtracking)が開始されます。バックトラックはすべての選択肢をマッチングするまで行なわれます。最終的に引数リストのすべての要素は仕様内の要素のいずれかとマッチしなければならず、仕様内の必須要素は引数のいずれかとマッチしなければなりません。

構文エラーが検出されてもその時点では報告されず、より高位レベルの選択肢のマッチングが終わった後、実際のエラー箇所から離れたポイント位置でエラーが報告されるかもしれません。しかしエラー発生時にバックトラックが無効ならエラーは即座に報告されるでしょう。ある状況ではバックトラックも自動的に再有効化されることに注意してください。&optional&rest&orにより新たな選択肢が設定されたとき、または部分リスト、グループ、インダイレクト仕様が開始されたときはバックトラックが自動的に有効になります。バックトラックを有効、または無効にした場合の影響は、現在処理中のレベルの残り要素と低位レベルに限定されます。

何らかのフォーム仕様(すなわちformbodydef-formdef-body)をマッチングする間、バックトラックは無効になっています。これらの仕様は任意のフォームにマッチするので、何らかのエラーが発生するとしたらそれは高位レベルではなく、そのフォーム自体の内部でなければなりません。

バックトラックはクォートされたシンボル、文字列仕様、または&defineキーワードとのマッチに成功した後にも無効になります。なぜなら通常これは構文が認識されたことを示すからです。しかし同じシンボルで始まる一連の選択肢構文がある場合には、たとえば["foo" &or [first case] [second case] ...]のように、通常は選択肢の外部にそのシンボルをファクタリングすることによりこの制約に対処できます。

ほとんどのニーズは、バックトラックを自動的に無効にする、これら2つの方法で満足させることができますが、gate仕様を使用して明示的にバックトラックを無効にするほうが便利なときもあります。これは高位に適用可能な選択肢が存在しないことが分かっている場合に有用です。let仕様の例を参照してください。


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

19.2.15.4 仕様の例

以下で提供する例から学ぶことにより、Edebug仕様の理解が容易になるでしょう。

与えられたデータりすとにテストを実行する架空nマクロmy-test-generatorを考えてみましょう。edebug-eval-macro-args (マクロ呼び出しのインストルメントを参照)によって制御されるようにEdebugのデフォルトの振る舞いでは引数をコードとしてインストルメントしませんが、引数がデータであることをドキュメントするのは役に立つかもしれません。

(def-edebug-spec my-test-generator (&rest sexp))

スペシャルフォームletは、バインディングとbodyのシーケンスをもちます。各バインディングはそシンボル、またはシンボルとオプションの部分リストです。以下の仕様では部分リストを見つけたらバックトラックを抑止するために、部分リスト内のgateがあることに注目してください。

(def-edebug-spec let
  ((&rest
    &or symbolp (gate symbolp &optional form))
   body))

Edebugはdefunおよび関連する引数リスト、interactive仕様にたいして以下の仕様を使用します。式の引数はその関数bodyの外部で実際に評価されるので、interactiveフォームは特別に処理する必要があります。(defmacroにたいする仕様はdefunにたいする仕様と酷似するがdeclare命令文が許される)

(def-edebug-spec defun
  (&define name lambda-list
           [&optional stringp]   ; ドキュメント文字列が与えられた場合はマッチする。
           [&optional ("interactive" interactive)]
           def-body))

(def-edebug-elem-spec 'lambda-list
  '(([&rest arg]
     [&optional ["&optional" arg &rest arg]]
     &optional ["&rest" arg]
     )))

(def-edebug-elem-spec 'interactive
  '(&optional &or stringp def-form))    ; def-formに注目

以下のバッククォートにたいする仕様はドットリストにマッチさせる方法と、nilを使用して再帰を終了させる方法を説明するための例です。またベクターのコンポーネントをマッチさせる方法も示しています(Edebugにより定義される実際の仕様は少し異なり、失敗するかもしれない非常に深い再帰を引き起こすためドットリストについてはサポートしない)。

(def-edebug-spec \` (backquote-form))   ; 単なる明確化用エイリアス

(def-edebug-elem-spec 'backquote-form
  '(&or ([&or "," ",@"] &or ("quote" backquote-form) form)
        (backquote-form . [&or nil backquote-form])
        (vector &rest backquote-form)
        sexp))

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

19.2.16 Edebugのオプション

以下のオプションはEdebugの動作に影響を与えます:

User Option: edebug-setup-hook

Edebugが使用される前に呼び出される関数。この関数は毎回新たな値をセットする。Edebugはこれらの関数を一度呼び出したら、その後にedebug-setup-hooknilにリセットする。使用するパッケージに関係するEdebug仕様をロードするために使用でdきるがそれはEdebugを使用するときだけである。Edebugのためのインストルメントを参照のこと。

User Option: edebug-all-defs

これが非nilの場合にdefundefmacroのような定義フォームの普通に評価すると、Edebug用にインストルメントされる。これはeval-defuneval-regioneval-bufferに適用される。

このオプションの切り替えにはコマンドM-x edebug-all-defsを使用する。Edebugのためのインストルメントを参照のこと。

User Option: edebug-all-forms

これが非nilの場合にはeval-defuneval-regioneval-bufferはたとえフォームが何も定義していなくても、すべてのフォームをインストルメントする。これはロードとミニバッファー内の評価には適用されない。

このオプションの切り替えにはコマンドM-x edebug-all-formsを使用する。Edebugのためのインストルメントを参照のこと。

User Option: edebug-eval-macro-args

これが非nilなら、すべてのマクロ引数が生成されるコード内にインストルメントされる。debug宣言はこのオプションをオーバーライドする。ある引数を評価して他の引数は評価しないマクロにたいする例外を指定するためには、debug宣言を指定するためはEdebugフォーム仕様を使用すること。

User Option: edebug-save-windows

このオプションが非nilなら、Edebugはウィンドウ構成の保存とリストアを行う。これには幾分時間を要するので、あなたのプログラムがウィンドウ構成に何が起こったかを気にしないようなら、この変数にはnilをセットしたほうがよい。このオプションがデフォルト値のままだとウィンドウ構成の保存やリストアの結果として、デバッグ中のプログラムに含まれるバッファーのポイント位置がEdebugに上書きされてしまう場合もnilにセットすることをお勧めする。これはあなたのプログラムがこのようなバッファーの1つ以上でポイントを移動した場合に起こり得る。他にも後述のedebug-save-displayed-buffer-pointsのカスタマイズを試してみるという手もある。

edebug-save-windowsの値がリストなら、リストされたウィンドウだけが保存およびリストアされる。

Edebug内ではこの変数をインタラクティブに変更するためにWコマンドを使用できる。Edebugの表示の更新を参照のこと。

User Option: edebug-save-displayed-buffer-points

これが非nilならEdebugは表示されているすべてのバッファー内のポイントを保存およびリストアする。

選択されていないウィンドウ内に表示されているバッファーのポイントを変更するコードをデバッグしている場合は、他のバッファーのポイントを保存およびリストアする必要がある。その後にEdebugまたはユーザーがそのウィンドウを選択した場合は、そのバッファー内のポイントはそのウィンドウのポイント値に移動される。

すべてのバッファー内のポイントの保存とリストアは、それぞれのウィンドウを2回選択する必要があり高価な処理なので、必要なときだけ有効にする。Edebugの表示の更新を参照のこと。

User Option: edebug-initial-mode

この変数が非nilなら、Edebugが最初にアクティブになったときのEdebugの最初の実行モードを指定する。指定できる値はstepnextgoGo-nonstoptraceTrace-fastcontinueContinue-fast

デフォルト値はstep。この変数はC-x C-a C-mでインタラクティブにセットできる。Edebugの実行モードを参照のこと。

User Option: edebug-trace

これが非nilなら各関数のエントリーとexitをトレースする。トレース出力は関数のエントリーとexitを行ごとに、再帰レベルにしたがって*edebug-trace*という名前のバッファーに表示される。

トレースバッファーedebug-tracingも参照されたい。

User Option: edebug-test-coverage

nilならEdebugはデバッグされるすべての式のカバレッジをテストする。カバレッジテストを参照のこと。

User Option: edebug-continue-kbd-macro

nilならEdebug外部で実行されている任意のキーボードマクロの定義または実行を継続する。これはデバッグされないので慎重に使用すること。Edebugの実行モードを参照されたい。

User Option: edebug-print-length

nilなら、それはEdebugでの結果プリントにおけるprint-lengthのデフォルト値。出力に影響する変数を参照のこと。

User Option: edebug-print-level

nilなら、それはEdebugでの結果プリントにおけるprint-levelのデフォルト値。出力に影響する変数を参照のこと。

User Option: edebug-print-circle

nilなら、それはEdebugでの結果プリントにおけるprint-circleのデフォルト値。出力に影響する変数を参照のこと。

User Option: edebug-unwrap-results

nilならEdebugは式の結果を表示するときに、その式自体のインストルメント結果の削除を試みる。マクロをデバッグするときは、式の結果自体がインストルメントされた式になるということに関連するオプションである。実際的な例ではないが、サンプル例の関数facがインストルメントされたとき、そのフォームのマクロを考えてみるとよい。

(defmacro test () "Edebug example."
  (if (symbol-function 'fac)
      …))

testマクロをインストルメントしてステップ実行すると、デフォルトではsymbol-function呼び出しは多数のedebug-afterフォームとedebug-beforeフォームをもつことになり、それにより実際の結果の確認が難しくなり得る。edebug-unwrap-resultsが非nilならEdebugは結果からこれらのフォームの削除を試みる。

User Option: edebug-on-error

debug-on-errorが以前nilだったら、Edebugはdebug-on-errorをこの値にバインドする。エラーのトラップを参照のこと。

User Option: edebug-on-quit

debug-on-quitの以前の値がnilなら、Edebugはdebug-on-quitにこの値をバインドする。エラーのトラップを参照のこと。

Edebugがアクティブな間にedebug-on-erroredebug-on-quitの値を変更したら、次回に新たなコマンドを通じてEdebugが呼び出されるまでこれらの値は使用されない。

User Option: edebug-global-break-condition

nilなら、値はすべてのステップポイントでテストされる式である。式の結果がnilならbreakする。エラーは無視される。グローバルなブレーク条件を参照のこと。

User Option: edebug-sit-for-seconds

実行モードがtraceかcontinueでbreakpointに達した際に一時停止する秒数。Edebugの実行モードを参照のこと。

User Option: edebug-sit-on-break

breakpointに達したときにedebug-sit-for-secondsの間、一時停止するかどうか。nilで一時停止の抑止、非nilなら一時停止を許可。

User Option: edebug-behavior-alist

デフォルトでは、このalistにはキーがedebugで3つの関数edebug-enteredebug-beforeedebug-afterからなるリストという1つのエントリーが含まれる。これらの関数はインストルメントされるコードに挿入される関数のデフォルト実装である。Edebugの全般的な挙動を変更するためには、このデフォルトエントリーを変更する。

Edebugの挙動はこのalistにエントリーにユーザーが選択したキーと3つの関数を追加することにより、定義ごとにもとづいて変更もできる。それからインストルメントされた定義のシンボルプロパティedebug-behaviorに新たなエントリーのキーをセットすれば、Edebugはその定義にたいして自身の関数を呼び出す箇所で新たな関数を呼び出す。

User Option: edebug-new-definition-function

定義やクロージャのbodyをラップした後にEdebugが実行する関数。Edebugが自身のデータを初期化後に、この関数は定義に関連付けられたシンボル(Edebugが定義または生成した実際のシンボルかもしれない)を単一の引数として呼び出される。この関数はEdebugによりインストルメントされる各定義のシンボルプロパティedebug-behaviorをセットするために使用されるかもしれない。

User Option: edebug-after-instrumentation-function

使用前にEdebugのインストルメントの検査や修正を行うには、インストルメントするトップレベルのフォームを単一の引数として受け取り、その後にEdebugがインストルメントの最終結果として使用することになる同一フォームあるいは置換フォームをリターンする関数をこの変数にセットする。


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

19.3 無効なLisp構文のデバッグ

Lispリーダーは無効な構文(invalid syntax)について報告はしますが実際の問題箇所は報告しません。たとえばある式を評価中のエラー‘End of file during parsing’は、開カッコまたは開角カッコ(open parenthese or open square bracket)が多いことを示しています。Lispリーダーはこの不一致をファイル終端で検出しましたが、本来閉カッコがあるべき箇所を解決することはできません。同様に‘Invalid read syntax: ")"’は開カッコの欠落を示していますが、欠落しているカッコが属すべき場所は告げません。ならばどうやって変更すべき箇所を探せばよいのでしょうか?

問題が単なるカッコの不一致でない場合の便利なテクニックは、各defunの先頭でC-M-e ( end-of-defunMoving by Defuns in The GNU Emacs Manualを参照)とタイプして、そのdefunの最後と思われる箇所に移動するか確認する方法です。もし移動しなければ、問題はそのdefunの内部にあります。

マッチしないカッコがLispにおいてもっとも一般的な構文エラーなので、これらのケースにたいしてさらにアドバイスすることができます(Show Parenモードを有効にしてコードにポイントを移動するだけでカッコの不一致を探しやすくなるだろう)。


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

19.3.1 過剰な開カッコ

カッコがマッチしないdefunを探すのが、最初のステップです。過剰な開カッコが存在する場合は、ファイルの終端に移動してC-u C-M-u ( backward-up-listMoving by Parens in The GNU Emacs Manualを参照)とタイプします。これにより、カッコがマッチしない最初のdefunの先頭に移動するでしょう。

何が間違っているのか正確に判断するのが次のステップです。これを確実に行なうにはプログラムを詳しく調べる以外に方法はありませんが、カッコがあるべき箇所を探すのに既存のインデントが手掛かりになることが多々あります。C-M-q (indent-pp-sexpMulti-line Indent in The GNU Emacs Manualを参照)で再インデントして何が移動されるか確認するのが、この手掛かりを使用するもっとも簡単な方法です。しかし、行うのはちょっと待ってください! まず続きを読んでからにしましょう。

これを行なう前にdefunに十分な閉カッコがあるか確認します。十分な閉カッコがなければ C-M-qがエラーとなるか、そのdefunからファイル終端までの残りすべてが再インデントされます。その場合にはdefunの最後に移動して、そこに閉カッコを挿入します。そのdefunのカッコの釣り合いがとれるまでは、defunの最後に移動するのにC-M-e (end-of-defun)は使用できません(失敗する)。

これでdefunの先頭に移動してC-M-qとタイプすることができます。通常は一定のポイントからその関数の最後までのすべての行が、右へとシフトされるでしょう。これはおそらくそのポイント付近で閉カッコが欠落していたり不要な開カッコがあります(しかしこれを真実と仮定せずコードを詳しく調べること)。不一致箇所を見つけたら、元のインデントはおそらく意図されたカッコに適しているはずなので、C-_ (undo)でC-M-qをアンドゥしてください。

問題をfixできたと思った後に、再度C-M-qを使用します。実際に元のインデントが意図したカッコのネストに適合していて、足りないカッコを追加していたら、C-M-qは何も変更しないはずです。


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

19.3.2 過剰な閉カッコ

過剰な閉カッコへの対処は、まずファイルの先頭に移動してからカッコのマッチしないdefunを探すためにC-u -1 C-M-u (引数-1でbackward-up-list)をタイプします。

それからdefunの先頭でC-M-f (forward-sexpExpressions in The GNU Emacs Manualを参照)をタイプして、実際にマッチする閉カッコを探します。これによりdefunの終端より幾分手前の箇所に移動するでしょう。その付近に間違った閉カッコが見つかるはずです。

そのポイントに問題が見つからない場合には、そのdefunの先頭でC-M-q (indent-pp-sexp)をタイプするのが次のステップです。ある行範囲はおそらく左へシフトするでしょう。その場合には欠落している開カッコや間違った閉カッコは、おそらくそれらの行の1行目の近くにあるでしょう(しかしこれを真実と仮定せずコードを詳しく調べること)。不一致箇所が見つけたら、元のインデントはおそらく意図されたカッコに適しているはずなのでC-_ (undo)でC-M-qをアンドゥしてください。

問題をfixできたと思った後に再度C-M-qを使用します。実際に元のインデントが意図したカッコのネストに適合していて、足りないカッコを追加していたら、C-M-qは何も変更しないはずです。


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

19.4 カバレッジテスト

testcoverライブラリーをロードしてコマンドM-x testcover-start RET file RETでコードをインストルメントすることにより、Lispコードのファイルにたいしてカバレッジテストを行なうことができます。コードを1回以上呼び出すことによってテストが行なわれます。コマンドM-x testcover-mark-allを使用すれば、カバレッジが不十分な箇所が色付きでハイライト表示されます。コマンドM-x testcover-next-markは次のハイライトされた箇所へポイントを前方に移動します。

赤くハイライトされた箇所は通常はそのフォームが完全に評価されたことが一度もないことを示し、茶色でハイライトされた箇所は常に同じ値に評価された(その結果にたいして少ししかテストされていない)ことを意味します。しかしerrorのように完全に評価するのが不可能なフォームにたいしては、赤いハイライトはスキップされます。(setq x 14)のように常に同じ値に評価されることが期待されるフォームにたいしては、茶色のハイライトはスキップされます。

難しいケースではテストカバレッジツールにアドバイスを与えるために、コードにdo-nothingマクロを追加することができます。

Macro: 1value form

formを評価してその値をリターンするが、テストカバレッジにたいしてformが常に同じ値だという情報を与える。

Macro: noreturn form

formを評価してformが決してリターンしないという情報をカバレッジテストに与える。もしリターンしたらrun-timeエラーとなる。

Edebugにもカバレッジテスト機能があります(カバレッジテストを参照)。これらの機能は部分的に重複しており、組み合わせることで明確になるでしょう。


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

19.5 プロファイリング

プログラムは正常に機能しているものの、十分に高速ではないのでより高速かつ効率的に実行させたい場合には、そのプログラムが実行時間の大半をどこで消費しているか知るために、コードをプロファイル(profile)することが最初に行うべきことです。ある特定の関数の実行が実行時間のうちの無視できない割り合いを占めるようなら、その部分を最適化する方法を探すことを開始できます。

Emacsにはこのためのビルトインサポートがあります。プロファイリングを開始するにはM-x profiler-startをタイプします。CPU使用率の定期的なサンプリング(cpu、かメモリー割り当て時(memory)、またはその両方を選択できます。それから高速化したいコードを実行します。その後にM-x profiler-reportとタイプすると、プロファイルに選択した各タイプ(cpuとmemory)によりサンプリングされたCPU使用率がsummaryバッファーに表示されます。reportバッファーの名前にはレポートが生成された時刻が含まれるので、前の結果を消去せずに後で他のレポートを生成できます。プロファイリングが終了したらM-x profiler-stopとタイプしてください(プロファイリングに関連したオーバーヘッドが若干あるので実際に調査したいコードの実行中以外にアクティブのままに放置することは推奨しない)。

profiler reportバッファーでは、各行に呼び出された関数、その前にプロファイリングが開始されてから使用したCPUリソースの絶対時間とパーセンテージが表示されます。関数名の左にシンボル‘+’のある行ではRETをタイプして行を展開して高位レベルの関数に呼び出された関数を確認できます。関数ツリー配下全体の呼び出しを確認するにはプレフィクス引数を使用します(C-u RET)。もう一度RETをタイプすれば元の状態へと行が折り畳まれます。

jmouse-2を押下するとポイント位置の関数の定義にジャンプします。dを押下すると関数のドキュメントを閲覧できます。C-x C-wを使用してプロファイルをファイルに保存できます。=を使用すれば2つのプロファイルを比較することができます。

elpライブラリーはプロファイルしたいLisp関数が事前に解っているときに有用な別のアプローチを選択肢として提供します。このライブラリーの使用するには、まずelp-function-listに関数シンボルのリスト(プロファイルしたい関数)をセットします。それから関数をプロファイル用にアレンジするためにM-x elp-instrument-list RET nil RETとタイプします。プロファイルしたいコードの実行後にM-x elp-resultsを呼び出してカレント結果を表示します。処理手順の詳細についてはelp.elファイルを参照してください。このアプローチはLispで記述された関数のプロファイリングに限定されており、Emacsプリミティブのプロファイルはできません。

benchmarkライブラリーを使用して個々のEmacs Lispフォームの評価に消費される時間を計測できます。benchmark.el内の関数benchmark-call、同様にマクロbenchmark-runbenchmark-run-compiledbenchmark-prognを参照してください。フォームをインタラクティブに時間計測するためにbenchmarkコマンドも使用できます。

configureのオプションに--enable-profilingを使用してビルドすることにより、EmacsをCコードのレベルでプロファイルすることができます。こうしてビルドされたEmacsは、Emacsをexitするときにgprofユーティリティを使用して検証できるファイルgmon.outを生成します。この機能は主にEmacsのデバッグに有用です。このEmacsは実行状態から上述のM-x profiler-…コマンドによりLispレベルで実際にストップします。


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

20 Lispオブジェクトの読み取りとプリント

プリント(print)読み取り(read)はLispオブジェクトからテキスト形式への変換、またはその逆の変換を行なう操作です。これらはLispのデータ型で説明したプリント表現(printed representation)と入力構文(read syntax)を使用します。

このチャプターでは読み取りとプリントのためのLisp関数について説明します。このチャプターではさらにストリーム(stream)についても説明します。ストリームとは、(読み取りでは)テキストがどこから取得されるか、(プリントでは)テキストをどこに出力するかを指定します。


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

20.1 読み取りとプリントの概念

Lispオブジェクトの読み取りとは、テキスト形式のLisp式をパース(parse: 解析)して、対応するLispオブジェクトを生成することを意味します。これはLLispプログラムがLispコードファイルからLispに取得される方法でもあります。わたしたちはそのテキストのことを、そのオブジェクトの入力構文(read syntax)と呼んでいます。たとえばテキスト‘(a . 5)’は、CARaCDRが数字の5であるようなコンスセルにたいする入力構文です。

Lispオブジェクトのプリントとは、あるオブジェクトをそのオブジェクトのプリント表現(printed representation)に変換することによって、そのオブジェクトを表すテキストを生成することを意味します(プリント表現と読み取り構文を参照)。上述のコンスセルをプリントするとテキスト‘(a . 5)’が生成されます。

読み取りとプリントは概ね逆の処理といえます。あるテキスト断片を読み取った結果として生成されたオブジェクトをプリントすると、多くの場合は同じテキストが生成され、あるオブジェクトをプリントした結果のテキストを読み取ると、通常は同じようなオブジェクトが生成されます。たとえばシンボルfooをプリントするとテキスト‘foo’が生成されて、そのテキストを読み取るとシンボルfooがリターンされます。要素がabのリストをプリントするとテキスト‘(a b)’が生成されて、そのテキストを読み取ると、(同じリストではないが)要素がabのリストが生成されます。

しかし、これら2つの処理は互いにまったく逆の処理というわけではありません。3つの例外があります:

  • プリントは読み取ることが不可能なテキストを生成できる。たとえばバッファー、フレーム、サブプロセス、マーカーは‘#’で始まるテキストとしてプリントされる。このテキストの読み取りを試みるとエラーとなる。これらのデータ型を読み取る方法は存在しない。
  • 1つのオブジェクトが複数のテキスト的な表現をもつことができる。たとえば‘1’と‘01’は同じ整数を表し、‘(a b)’と‘(a . (b))’は同じリストを表す。読み取りは複数の候補を受容するかもしれないが、プリントはそのうちのただ1つを選択しなければならない。
  • あるオブジェクトの読み取りシーケンスの中間の特定ポイントに、読み取り結果に影響を与えないコメントを置くことができる。

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

20.2 入力ストリーム

テキストを読み取るLisp関数の大部分は、引数として入力ストリーム(input stream)を受け取ります。入力ストリームは読み取られるテキストの文字をどこから、どのように取得するかを指定します。以下は利用できる入力ストリーム型です:

buffer

入力文字はbufferのポイントの後の文字から直接読み取られる。文字の読み取りとともにポイントが進む。

marker

入力文字はmarkerがあるバッファーの、マーカーの後の文字から直接読み取られる。文字の読み取りとともにマーカーが進む。ストリームがマーカーならバッファー内のポイント値に影響はない。

string

入力文字はstringの最初の文字から必要な文字数分が取得される。

function

入力文字はfunctionから生成され、その関数は2種類の呼び出しをサポートしなければならない:

  • 引数なしで呼び出されたときは次の文字をリターンする。
  • 1つの引数(常に文字)で呼び出されたとき、functionは引数を保存して次の呼び出しでリターンするように準備する。これは文字の読み戻し(unreading)と呼ばれ、Lispリーダーが1文字多く読みとったとき、それを‘読みとった場所に戻したいときに発生する。この場合にはfunctionのリターン値と違いはない。
t

tはその入力がミニバッファーから読み取られるストリームであることを意味する。実際にはミニバッファーが1回呼び出されて、ユーザーから与えられたテキストが、その後に入力ストリームとして使用される文字列となる。Emacsがbatchモード(batchモードを参照)で実行されている場合には、ミニバッファーのかわりに標準入力が使用される。たとえば、

(message "%s" (read t))

batchモードでは標準入力からLisp式が読み取られて、結果は標準出力にプリントされるだろう。

nil

入力ストリームとしてnilが与えられた場合は、かわりにstandard-inputの値が使用されることを意味する。この値はデフォルトの入力ストリーム(default input stream)であり、非nilの入力ストリームでなければならない。

symbol

入力ストリームとしてのシンボルは、(もしあれば)そのシンボルの関数定義と等価である。

以下の例ではバッファーストリームから読み込んで、読み取りの前後におけるポイント位置を示しています:

---------- Buffer: foo ----------
This∗ is the contents of foo.
---------- Buffer: foo ----------

(read (get-buffer "foo"))
     ⇒ is
(read (get-buffer "foo"))
     ⇒ the

---------- Buffer: foo ----------
This is the∗ contents of foo.
---------- Buffer: foo ----------

最初の読み取りではスペースがスキップされていることに注意してください。読み取りでは意味のあるテキストに先行する、任意のサイズの空白文字がスキップされます。

以下はマーカーストリームからの読み取りの例で、最初は表示されているバッファーの先頭にマーカーを配置されています。読み取られた値はシンボルThisです。


---------- Buffer: foo ----------
This is the contents of foo.
---------- Buffer: foo ----------

(setq m (set-marker (make-marker) 1 (get-buffer "foo")))
     ⇒ #<marker at 1 in foo>
(read m)
     ⇒ This
m
     ⇒ #<marker at 5 in foo>   ;; 最初のスペースの前

以下では文字列のコンテンツから読み取っています:

(read "(When in) the course")
     ⇒ (When in)

以下はミニバッファーから読み取る例です。プロンプトは‘Lisp expression: です(このプロンプトはストリームtから読み取る際は常に使用される)。ユーザーの入力はプロンプトの後に表示されます。

(read t)
     ⇒ 23
---------- Buffer: Minibuffer ----------
Lisp expression: 23 RET
---------- Buffer: Minibuffer ----------

最後はuseless-streamという名前の関数ストリームから読み取る例です。ストリームを使用する前に変数useless-listを文字のリストで初期化しています。その後はリスト内の次の文字を取得するため、または文字をリストの先頭に追加することにより読み戻すために関数useless-streamを呼び出します。

(setq useless-list (append "XY()" nil))
     ⇒ (88 89 40 41)

(defun useless-stream (&optional unread)
  (if unread
      (setq useless-list (cons unread useless-list))
    (prog1 (car useless-list)
           (setq useless-list (cdr useless-list)))))
     ⇒ useless-stream

このストリームを使って以下のように読み取ります:

(read 'useless-stream)
     ⇒ XY

useless-list
     ⇒ (40 41)

開カッコと閉カッコがリスト内に残されることに注意してください。Lispリーダーは開カッコに出会うと、それを入力の終わりと判断して読み戻します。次にこのポイント位置からこのストリームを読み取ると、‘()’が読み取られてnilがリターンされます。


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

20.3 入力関数

このセクションでは、読み取りに関係のあるLisp関数と変数について説明します。

以下の関数ではstreamは入力ストリーム(前のセクションを参照)を意味します。streamnilまたは省略された場合のデフォルト値はstandard-inputです。

読み取りにおいて終端されていないリスト、ベクター、文字列に遭遇したらend-of-fileがシグナルされます。

Function: read &optional stream

この関数はstreamからテキスト表現されたLisp式を1つ読み取ってLispオブジェクトとしてリターンする。これは基本的なLisp入力関数である。

Function: read-from-string string &optional start end

この関数はstring内のテキストからテキスト表現された最初のLisp式を読み取る。リターン値はCARがその式で、CDRが次に読み取られるその文字列内の残りの文字(読み取られていない最初の文字)の位置を与える整数であるようなコンスセルである。

startが与えられると、文字列内のインデックスstart(最初の文字はインデックス0)から読み取りが開始される。endを指定すると、残りの文字列が存在しないかのごとくそのインデックスの直前で読み取りがストップされる。

たとえば:

(read-from-string "(setq x 55) (setq y 5)")
     ⇒ ((setq x 55) . 11)
(read-from-string "\"A short string\"")
     ⇒ ("A short string" . 16)

;; 最初の文字から読み取りを開始
(read-from-string "(list 112)" 0)
     ⇒ ((list 112) . 10)
;; 2つ目の文字から読み取りを開始
(read-from-string "(list 112)" 1)
     ⇒ (list . 5)
;; 7番目の文字から読み取りを開始
;;   して9番目の文字で停止
(read-from-string "(list 112)" 6 8)
     ⇒ (11 . 8)
Function: read-positioning-symbols &optional stream

この関数はreadが行うようにstreamからテキストとして1つの式を読み取るが、読み込んだシンボルにたいしてそのシンボルがstreamで出現した位置を読み込んだシンボルに付加する。効率上の理由によりシンボルnilだけは位置を付加しない。位置をもつシンボルを参照のこと。これはバイトコンパイラーによって使用される関数である。

Variable: standard-input

この変数はデフォルト入力ストリーム(引数streamnilのときにreadが使用するストリーム)を保持する。デフォルトはtで、これはミニバッファーを使用することを意味する。

Variable: read-circle

nilなら、この変数は循環構造(circular structure)と共有構造(shared structures)の読み取りを有効にする。循環オブジェクトの読み取り構文を参照のこと。デフォルト値はt

batchモードのEmacsプロセスの標準入力や標準出力のストリームにたいして読み取りや書き込みを行う際には、任意のバイナリーデータにたいしてそのまま読み取りや書き込みを行うことや、改行とCR-LFの変換を何も行わないことを保証することが要求される場合があります。この問題はMS-WindowsとMS-DOSだけに存在する問題であり、POSIXではそのような問題はありません。以下の関数によりEmacsプロセスのすべての標準ストリームのI/Oモードを制御することができます。

Function: set-binary-mode stream mode

streamのI/Oモードのバイナリーとテキストを切り替える。modeが非nilならバイナリーモード、それ以外ならテキストモードに切り替える。streamの値はstdinstdoutstderrのいずれか。この関数は副作用としてstreamの保留中の出力データをすべてフラッシュして、streamの以前のI/Oモードの値をリターンする。POSIXでは常に非nil値をリターンして、保留中の出力のフラッシュ以外は何も行わない。

Function: readablep object

この述語はobject読み取り可能構文(readable syntax)かどうか、つまり書き込んでからEmacs Lispリーダーによって読み戻せるかどうかを判定する。読み取り可能でなければnil、読み取り可能であればこの関数はobjectのプリント表現をリターンする(prin1を通じて; 出力関数を参照)。


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

20.4 出力ストリーム

出力ストリームはプリントによって生成された文字に何を行うかを指定します。ほとんどのプリント関数は引数としてオプションで出力ストリームを受け取ります。以下は利用できる出力ストリーム型です:

buffer

出力文字はbufferのポイント位置に挿入される。文字が挿入された分だけポイントが進む。

marker

出力文字はmarkerがあるバッファーのマーカー位置に挿入される。文字が挿入された分だけマーカー位置が進む。ストリームがマーカーのときは、そのバッファー内のポイント位置にプリントは影響せず、この種のプリントでポイントは移動しない(マーカー位置がポイント位置かポイント位置より前の場合は除く。通常はテキストの周囲にポイントが進む)。

function

出力文字は文字を格納する役目をもつfunctionに渡される。この関数は1つの文字を引数に出力される文字の回数呼び出され、格納したい場所にその文字を格納する役目をもつ。

t

出力文字はエコーエリアに表示される。Emacsがbatchモード(batchモードを参照)で実行中なら、出力はかわりに標準出力デスクリプターに書き込まれる。

nil

出力ストリームにnilが指定された場合は、かわりにstandard-output変数の値が使用されることを意味する。この値はデフォルトの出力ストリーム(default output stream)であり、非nilでなければならない。

symbol

出力ストリームとしてのシンボルは、(もしあれば)そのシンボルの関数定義と等価である。

有効な出力ストリームの多くは、入力ストリームとしても有効です。したがって入力ストリームと出力ストリームの違いは、Lispオブジェクトの型ではなく、どのようにLispオブジェクトを使うかという点です。

以下はバッファーを出力ストリームとして使用する例です。ポイントは最初は‘the’の中の‘h’の直前にあります。そして最後も同じ‘h’の直前に配置されます。

---------- Buffer: foo ----------
This is t∗he contents of foo.
---------- Buffer: foo ----------

(print "This is the output" (get-buffer "foo"))
     ⇒ "This is the output"

---------- Buffer: foo ----------
This is t
"This is the output"
∗he contents of foo.
---------- Buffer: foo ----------

次はマーカーを出力ストリームとして使用する例です。マーカーは最初はバッファーfoo内の単語‘the’の中の‘t’と‘h’の間にあります。最後には挿入されたテキストによってマーカーが進んで、同じ‘h’の前に留まります。通常の方法で見られるようなポイント位置への影響がないことに注意してください。

---------- Buffer: foo ----------
This is the ∗output
---------- Buffer: foo ----------

(setq m (copy-marker 10))
     ⇒ #<marker at 10 in foo>

(print "More output for foo." m)
     ⇒ "More output for foo."

---------- Buffer: foo ----------
This is t
"More output for foo."
he ∗output
---------- Buffer: foo ----------

m
     ⇒ #<marker at 34 in foo>

以下はエコーエリアに出力を表示する例です:

(print "Echo Area output" t)
     ⇒ "Echo Area output"
---------- Echo Area ----------
"Echo Area output"
---------- Echo Area ----------

最後は関数を出力ストリームとして使用する例です。関数eat-outputは与えられたそれぞれの文字をlast-outputの先頭にconsします(コンスセルおよびリストの構築を参照)。最後にはリストには出力されたすべての文字が逆順で含まれます。

(setq last-output nil)
     ⇒ nil

(defun eat-output (c)
  (setq last-output (cons c last-output)))
     ⇒ eat-output

(print "This is the output" #'eat-output)
     ⇒ "This is the output"

last-output
     ⇒ (10 34 116 117 112 116 117 111 32 101 104
    116 32 115 105 32 115 105 104 84 34 10)

このリストを逆転すれば正しい順序で出力することができます:

(concat (nreverse last-output))
     ⇒ "
\"This is the output\"
"

concatを呼び出してリストを文字列に変換すれば、内容をより明解に確認できます。

Function: external-debugging-output character

この関数はデバッグ時の出力ストリームとして有用。これは標準エラーストリームにcharacterを書き込む。

たとえば

(print "This is the output" #'external-debugging-output)
-| This is the output
⇒ "This is the output"

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

20.5 出力関数

このセクションではオブジェクトをオブジェクトのプリント表現に変換して、LispオブジェクトをプリントするLisp関数を説明します。

Emacsプリント関数には、正しく読み取れるように必要なとき出力にクォート文字を追加するものがあります。使用されるクォート文字は‘"’と‘\’です。これらは文字列をシンボルと区別するとともに、文字列とシンボル内の区切り文字が読み取りの際に区切り文字として扱われることを防ぎます。完全な詳細はプリント表現と読み取り構文を参照してください。クォートするかしないかはプリント関数の選択によって指定できます。

そのテキストがLispに読み戻す場合、またはLispプログラマーにLispオブジェクトを明解に説明するのが目的の場合は、曖昧さを避けるためにクォート文字をプリントするべきです。しかしプログラマー以外の人間にたいして出力の見栄えを良くするのが目的なら、通常はクォートなしでプリントしたほうがよいでしょう。

Lispオブジェクトは自己参照ができます。通常の方法で自己参照オブジェクトをプリントするにはテキストが無限に必要であり、その試みにより無限再帰が発生する恐れがあります。Emacsはそのような再帰を検知して、すでにプリントされたオブジェクトを再帰的にプリントするかわりに、‘#level’をプリントします。たとえば以下はカレントのプリント処理において、レベル0のオブジェクトを再帰的に参照することを示しています:

(setq foo (list nil))
     ⇒ (nil)
(setcar foo foo)
     ⇒ (#0)

以下の関数ではstreamは出力ストリームを意味します(出力ストリームの説明は前のセクションを参照。デバッグではストリーム値としてexternal-debugging-outputも有用) streamnilか省略された場合のデフォルトはstandard-outputの値です。

Function: print object &optional stream

print関数はプリントを行うための便利な手段である。この関数はobjectの前後に改行を付与してobjectのプリント表現をstreamにプリントする。クォート文字が使用される。printobjectをリターンする。たとえば:

(progn (print 'The\ cat\ in)
       (print "the hat")
       (print " came back"))
     -|
     -| The\ cat\ in
     -|
     -| "the hat"
     -|
     -| " came back"
     ⇒ " came back"
Function: prin1 object &optional stream overrides

この関数はobjectのプリント表現をstreamに出力する。この関数はprintのように出力を分割するための改行をプリントしないが、printのようにクォート文字を使用する。objectをリターンする。

(progn (prin1 'The\ cat\ in)
       (prin1 "the hat")
       (prin1 " came back"))
     -| The\ cat\ in"the hat"" came back"
     ⇒ " came back"

overridesが非nilなら、それはt (すべてのプリンター関連変数にたいしてデフォルトとしてprin1を使うよう指示する)、あるいはセッティングのリストであること。詳細については出力変数のオーバーライドを参照のこと。

Function: princ object &optional stream

この関数はobjectのプリント表現をstreamに出力する。objectをリターンする。

この関数はreadではなく人間が読める出力を生成することを意図しているので、クォート文字を挿入せず文字列のコンテンツの前後にダブルクォート文字を配置しない。各呼び出しの間にスペースを何も出力しない。

(progn
  (princ 'The\ cat)
  (princ " in the \"hat\""))
     -| The cat in the "hat"
     ⇒ " in the \"hat\""
Function: terpri &optional stream ensure

この関数はstreamに改行を出力する。名前の由来は“terminate print(プリントを終端する)”。ensureが非nilの場合には、streamがすでに行頭にあれば改行をプリントしない。この場合にはstreamに関数は指定できず、指定するとエラーがシグナルされる。この関数は改行をプリントしたらtをリターンする。

Function: write-char character &optional stream

この関数はcharacterstreamに出力する。characterをリターンする。

Function: flush-standard-output

端末に出力を送信するようなEmacsベースのバッチスクリプトでは、standard-outputに改行文字を書き込むたびにEmacsが自動的に出力を表示する。この関数を使えば最初に改行文字を送信せずにstandard-outputをフラッシュ(flush)できるので、不完全な行を表示することができる。

Function: prin1-to-string object &optional noescape overrides

この関数は同じ引数でprin1がプリントするテキストを含む文字列をリターンする。

(prin1-to-string 'foo)
     ⇒ "foo"
(prin1-to-string (mark-marker))
     ⇒ "#<marker at 2773 in strings-ja.texi>"

If overrides is non-nil, it should either be t
(which tells prin1 to use the defaults for all printer related
variables), or a list of settings.  See 出力変数のオーバーライド, for details.

noescapeが非nilなら出力中のクォート文字の使用を抑制する(この引数はEmacsバージョン19以降でサポートされた)。

(prin1-to-string "foo")
     ⇒ "\"foo\""
(prin1-to-string "foo" t)
     ⇒ "foo"

Lispオブジェクトのプリント表現を文字列として取得する別の手段については、文字列のフォーマットformatを参照のこと。

Macro: with-output-to-string body…

このマクロは出力を文字列に送るようstandard-outputをセットアップしてフォームbodyを実行する。その文字列をリターンする。

たとえばカレントバッファー名が‘foo’なら、

(with-output-to-string
  (princ "The buffer is ")
  (princ (buffer-name)))

"The buffer is foo"をリターンする。

Function: pp object &optional stream

この関数はprin1と同じようにobjectstreamに出力するが、より優雅(pretty)な方法でこれを行う。すなわちこの関数は人間がより読みやすいようにオブジェクトのインデントとパディングを行う。

任意のバイナリーデータを書き込んだり非POSIXホストで改行変換を回避するためにこのセクションで説明した関数を使用してbatchモードでバイナリーI/Oモードを使用する必要がある場合にはset-binary-modeを参照してください。


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

20.6 出力に影響する変数

Variable: standard-output

この変数の値はデフォルト出力ストリーム(stream引数がnilのときプリント関数が使用するストリーム)である。デフォルトはtで、これはエコーエリアに表示することを意味する。

Variable: print-quoted

これが非nilなら、省略されたリーダー構文(たとえば(quote foo)'foo(function foo)#'fooのように)を使用してクォートされたフォームをプリントすることを意味する。デフォルトはt

Variable: print-escape-newlines

この変数が非nilなら、文字列内の改行は‘\n’、改ページは‘\f’でプリントされる。これらの文字は通常は実際の改行と改ページとしてプリントされる。

この変数はクォートつきのプリントを行うプリント関数prin1printに影響を与える。princに影響はない。以下はprin1を使用した場合の例である:

(prin1 "a\nb")
     -| "a
     -| b"
     ⇒ "a
b"

(let ((print-escape-newlines t))
  (prin1 "a\nb"))
     -| "a\nb"
     ⇒ "a
b"

2つ目の式ではprin1を呼び出す間はprint-escape-newlinesのローカルバインドが効果をもつが、結果をプリントするときには効果がない。

Variable: print-escape-control-characters

この変数が非nilなら、クォートつきでプリントするプリント関数prin1printは、文字列内のコントロール文字をバックスラッシュシーケンスとしてプリントする。この変数とprint-escape-newlinesがいずれも非nilなら改行と改頁には後者が優先される。

Variable: print-escape-nonascii

この変数が非nilなら、クォートつきでプリントするプリント関数prin1printは文字列内のユニバイトの非ASCII文字を無条件でバックスラッシュシーケンスとしてプリントする。

これらの関数は出力ストリームがマルチバイトバッファー、あるいはマーカーがマルチバイトバッファーをポイントするときは、この変数の値に関わらずユニバイト非ASCII文字にたいしてバックスラッシュシーケンスを使用する。

Variable: print-escape-multibyte

この変数が非nilなら、クォートつきでプリントするプリント関数prin1printは、文字列内のマルチバイトの非ASCII文字を無条件でバックスラッシュシーケンスとしてプリントする。

これらの関数は出力ストリームがユニバイトバッファー、あるいはマーカーがユニバイトバッファーをポイントするときは、この変数の値に関わらずマルチバイト非ASCII文字にたいしてバックスラッシュシーケンスを使用する。

Variable: print-charset-text-property

この変数は文字列のプリントにおいてテキストプロパティ‘charset’のプリントを制御する。値はnilt、またはdefaultのいずれか。

値がnilならcharsetテキストプロパティを決してプリントせず、tなら常にプリントする。

値がdefaultなら“予期せぬ(unexpected)”charsetプロパティがある場合だけcharsetテキストプロパティをプリントする。ASCII文字ではすべてのcharsetが“期待された(expected)”ものとみなされる。それ以外なら文字の期待されるcharsetプロパティはchar-charsetにより与えられる。

Variable: print-length

この変数の値は任意のリスト、ベクター、ブールベクターをプリントする際の最大要素数である。プリントされるオブジェクトがこれより多くの要素をもつ場合は、省略記号(“...”)で省略される。

値がnil(デフォルト)の場合は無制限。

(setq print-length 2)
     ⇒ 2
(print '(1 2 3 4 5))
     -| (1 2 ...)
     ⇒ (1 2 ...)
Variable: print-level

この変数の値はプリント時の丸カッコ(parentheses: “()”)と角カッコ(brackets: “[]"’)のネスト最大深さである。この制限を超える任意のリストとベクターは省略記号(“...”)で省略される。値nil(デフォルト)は無制限を意味する。

User Option: eval-expression-print-length
User Option: eval-expression-print-level

これらはeval-expressionによって使用されるprint-lengthprint-levelの値であり、したがって間接的に多くのインタラクティブな評価コマンドにより使用される(Evaluating Emacs Lisp Expressions in The GNU Emacs Manualを参照)。

以下の変数は循環構造および共有構造の検出と報告に使用されます:

Variable: print-circle

nilなら、この変数はプリント時の循環構造と共有構造の検出を有効にする。循環オブジェクトの読み取り構文を参照のこと。

Variable: print-unreadable-function

デフォルトではEmacsは読み取り可能ではないオブジェクトを‘#<...>"’のようにプリントする。たとえば:

(prin1-to-string (make-marker))
     ⇒ "#<marker in no buffer>"

この変数が非nilなら、これらのオブジェクトにたいするプリントを処理するために呼び出される関数であること。この関数はそのオブジェクト、およびプリント関数(出力関数を参照)によって使用されるnoescapeフラグという2つの引数で呼び出される。

この関数はnil(通常のようにオブジェクトをプリント)、文字列(プリントする文字列)、あるいは他のオブジェクト(そのオブジェクトをプリントしない)のいずれかをリターンすること。たとえば:

(let ((print-unreadable-function
       (lambda (object escape) "hello")))
  (prin1-to-string (make-marker)))
     ⇒ "hello"
Variable: print-gensym

nilなら、この変数はプリント時のインターンされていないシンボル(シンボルの作成とinternを参照)の検出を有効にする。これが有効なら、インターンされていないシンボルはプレフィックス‘#:’とともにプリントされる。このプレフィックスは、Lispリーダーにたいしてインターンされていないシンボルを生成するよう告げる。

Variable: print-continuous-numbering

nilなら、複数のプリント呼び出しを通じて通番が振られることを意味する。これは‘#n=’ラベルと‘#m#’参照にたいしてプリントされる数字に影響する。この変数をsetqでセットしてはならない。letを使用して一時的にtにバインドすること。これを行う場合はprint-number-tablenilにバインドすること。

Variable: print-number-table

この変数はprint-circle機能を実装するために、プリント処理で内部的に使用されるベクターを保持する。print-continuous-numberingをバインドするときにこの変数をnilにバインドする以外は、この変数を使用するべきではない。

Variable: float-output-format

この変数は浮動小数点数をプリントする方法を指定する。デフォルトはnilで、これは情報を失わずにその数値を表せるもっとも短い出力を使用することを意味する。

出力フォーマットをより精密に制御するために、この変数に文字列をセットできる。この文字列にはCのsprintf関数で使用される‘%’指定子をセットする。この変数で使用することのできる制限についての詳細は、この変数のドキュメント文字列を参照のこと。

Variable: print-integers-as-characters

この変数が非nilならグラフィックベース文字を表す整数はLispの文字構文を用いてプリントされる(基本的な文字構文を参照)。それ以外の数は通常の方法でプリントされる。たとえばリスト(4 65 -1 10)は‘(4 ?A -1 ?\n)’のようにプリントされるだろう。

正確にはUnicode一般カテゴリーLetter、Number、Punctuation、Symbol、Private-useに属する文字(文字のプロパティを参照)を表す文字、同じように改行のようなエスケープシーケンスを独自にもつコントロール文字にたいする値は、文字構文を使用してプリントされる。


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

20.7 出力変数のオーバーライド

前のセクション(出力関数を参照)では、Emacs Lispプリンターが出力用にデータをどのようにフォーマットするかを制御するさまざまな変数を説明しました。これらは一般的には変更用にユーザーが利用できますが、デフォルトのフォーマットでデータを出力したり、あるいは他の手段でユーザーセッティングをオーバーライドしたい場合があるかもしれません。たとえばEmacs Lispのデータをファイルに格納したい場合には、そのデータがprint-lengthのセッティングによって短縮されたくはないでしょう。

そのためにprin1およびprin1-to-stringという関数にはオプションとしてoverrides引数があります。この引数にはt(すべてのプリント用変数をデフォルト値にリセット)、あるいはいくつかの変数にたいするセッティングのリストのいずれかを指定できます。このリストの要素はそれぞれt(“デフォルトへのリセット”を意味しており、通常はリストの最初の要素)、あるいはcarが出力変数を意味するシンボルでcdrがその変数にたいする値であるようなペアーを指定できます。

たとえば以下はデフォルトだけを用いてプリントします:

(prin1 object nil t)

以下はカレントのプリントセッティングを用いてobjectをプリントしますが、print-lengthの値を5にオーバーライドします:

(prin1 object nil '((length . 5)))

そして最後はprint-lengthを5にバインドする以外はデフォルトセッティングを用いてobjectをプリントする例です:

(prin1 object nil '(t (length . 5)))

以下は使用できるシンボルと、それらのシンボルがマップされる変数のリストです:

length

print-lengthをオーバーライドする。

level

print-levelをオーバーライドする。

circle

print-circleをオーバーライドする。

quoted

print-quotedをオーバーライドする。

escape-newlines

print-escape-newlinesをオーバーライドする。

escape-control-characters

print-escape-control-charactersをオーバーライドする。

escape-nonascii

print-escape-nonasciiをオーバーライドする。

escape-multibyte

print-escape-multibyteをオーバーライドする。

charset-text-property

print-charset-text-propertyをオーバーライドする。

unreadeable-function

print-unreadable-functionをオーバーライドする。

gensym

print-gensymをオーバーライドする。

continuous-numbering

print-continuous-numberingをオーバーライドする。

number-table

print-number-tableをオーバーライドする。

float-format

float-output-formatをオーバーライドする。

integers-as-characters

print-integers-as-charactersをオーバーライドする。

将来的には変数に直接マップされない、このパラメーターだけを介してのみ使用できるオーバーライドが更に提供されるかもしれません。


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

21 ミニバッファー

ミニバッファー(minibuffer)とは、単一の数プレフィックス引数(numeric prefix argument)より複雑な引数を読み取るためにEmacsコマンドが使用する特別なバッファーのことです。これらの引数にはファイル名、バッファー名、(M-xでの)コマンド名が含まれます。ミニバッファーはフレームの最下行、エコーエリア(エコーエリアを参照)と同じ場所に表示されますが、引数を読み取るときだけ使用されます。


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

21.1 ミニバッファーの概要

ほとんどの点においてミニバッファーは普通のEmacsバッファーです。編集コマンドのようなバッファーにたいする操作のほとんどはミニバッファーでも機能します。しかしバッファーを管理する操作の多くはミニバッファーに適用できません。ミニバッファーは常に‘ *Minibuf-number*という形式の名前をもち変更はできません。ミニバッファーはミニバッファー用の特殊なウィンドウだけに表示されます。これらのウィンドウは常にフレーム最下に表示されます(フレームにミニバッファーウィンドウがないときやミニバッファーウィンドウだけをもつ特殊なフレームもある)。ミニバッファーとフレームを参照してください。

ミニバッファー内のテキストは常にプロンプト文字列(prompt string)で開始されます。これはミニバッファーを使用しているプログラムが、ユーザーにたいしてどのような種類の入力が求められているか告げるために指定するテキストです。このテキストは意図せずに変更してしまわないように、読み取り専用としてマークされます。このテキストはbeginning-of-lineforward-wordforward-sentenceforward-paragraphを含む特定の移動用関数が、プロンプトと実際のテキストの境界でストップするようにフィールド(フィールドの定義と使用を参照)としてもマークされています。

ミニバッファーのウィンドウは通常は1行です。ミニバッファーのコンテンツがより多くのスペースを要求する場合には自動的に拡張されます。ミニバッファーのウィンドウがアクティブな間はウィンドウのサイズ変更コマンドで一時的にウィンドウのサイズを変更できます。サイズの変更はミニバッファーをexitしたときに通常のサイズにリバートされます。ミニバッファーがアクティブでないときはフレーム内の他のウィンドウでウィンドウのサイズ変更コマンドを使用するか、マウスでモードラインをドラッグして、ミニバッファーのウィンドウのサイズを永続的に変更できます(現実装ではこれが機能するにはresize-mini-windowsnilでなければならない)。フレームがミニバッファーウィンドウだけを含む場合にはフレームのサイズを変更してミニバッファーのサイズを変更できます。

ミニバッファーの使用によって入力イベントが読み取られて、this-commandlast-commandのような変数の値が変更されます(コマンドループからの情報を参照)。プログラムにそれらを変更させたくない場合は、ミニバッファーを使用するコードの前後でそれらをバインドするべきです。

ある状況下では、アクティブなミニバッファーが存在するときでもコマンドがミニバッファーを使用できます。そのようなミニバッファーは再帰ミニバッファー(recursive minibuffer)と呼ばれます。この場合は最初のミニバッファーは‘ *Minibuf-1*という名前になります。再帰ミニバッファーはミニバッファー名の最後の数字を増加することにより命名されます(名前はスペースで始まるので通常のバッファーリストには表示されない)。再帰ミニバッファーが複数ある場合は、最内の(もっとも最近にエンターされた)ミニバッファーがアクティブミニバッファー(active minibuffer)です( RET (exit-minibuffer)をタイプして終了できるミニバッファー)。わたしたちは通常はこれを、所謂 ミニバッファーと呼んでいます。変数enable-recursive-minibuffers、またはコマンドシンボルのその名前のプロパティをセットすることにより再帰ミニバッファーを許可したり禁止できます(再帰的なミニバッファーを参照)。

他のバッファーと同様、ミニバッファーは特別なキーバインドを指定するためにローカルキーマップ(キーマップを参照)を使用します。ミニバッファーを呼び出す関数も、処理を行うためにローカルマップをセットアップします。補完なしのミニバッファーローカルマップについてはミニバッファーでのテキスト文字列の読み取りを参照してください。補完つきのミニバッファーローカルマップについては補完を行うミニバッファーコマンドを参照してください。

アクティブミニバッファーのメジャーモードは、通常はminibuffer-modeです。これは特別な機能をもたない、Emacsの内部モードです。ミニバッファーのセットアップをカスタマイズするには、minibuffer-mode-hookよりminibuffer-setup-hook (ミニバッファー、その他の事項を参照)の使用を推奨します。なぜならminibuffer-mode-hookはセットアップの後、ミニバッファーが完全に初期化された後に実行されるからです。

ミニバッファーが非アクティブのときのメジャーモードはminibuffer-inactive-mode、キーマップはminibuffer-inactive-mode-mapです。これらは実際にはミニバッファーが別フレームにある場合のみ有用です。ミニバッファーとフレームを参照してください。

Emacsがバッチモードで実行されている場合には、ミニバッファーからの読み取りリクエストは、実装にはEmacs開始時に提供された標準入力記述子から行を読み取ります。これは基本的な入力だけをサポートします。特別なミニバッファーの機能(ヒストリー、補完など)はバッチモードでは利用できません。


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

21.2 ミニバッファーでのテキスト文字列の読み取り

ミニバッファー入力にたいする基本的なプリミティブはread-from-minibufferで、これは文字列とLispオブジェクトの両方からテキスト表現されたフォームを読み取ることができます。関数read-regexpは特別な種類の文字列である正規表現式(正規表現を参照)の読み取りに使用されます。コマンドや変数、ファイル名などの読み取りに特化した関数もあります(補完を参照)。

ほとんどの場合でにはLisp関数の途中でミニバッファー入力関数を呼び出すべきではありません。かわりにinteractive指定されたコマンドの引数の読み取りの一環として、すべてのミニバッファー入力を行います。コマンドの定義を参照してください。

Function: read-from-minibuffer prompt &optional initial keymap read history default inherit-input-method

この関数はミニバッファーから入力を取得するもっとも一般的な手段である。デフォルトでは任意のテキストを受け入れて、それを文字列としてリターンする。しかしreadが非nilなら、テキストをLispオブジェクトに変換するためにreadを使用する(入力関数を参照)。

この関数が最初に行うのはミニバッファーをアクティブにして、プロンプトにprompt(文字列でなければならない)を用いてミニバッファーを表示することである。その後にユーザーはミニバッファーでテキストを編集できる。

ミニバッファーをexitするためにユーザーがコマンドをタイプするとき、read-from-minibufferはミニバッファー内のテキストからリターン値を構築する。通常はそのテキストを含む文字列がリターンされる。しかしreadが非nilなら、read-from-minibufferはテキストを読み込んで結果を未評価のLispオブジェクトでリターンする(読み取りについての詳細はSee 入力関数を参照)。

引数defaultはヒストリーコマンドを通じて利用できるデフォルト値を指定する。値には文字列、文字列リスト、またはnilを指定する。文字列と文字列リストは、ユーザーがM-nで利用可能な“未来のヒストリー(future history)”になる。更に(keymap引数を通じて)呼び出しで補完が提供された場合には、defaultの値をM-nで使い果たすと、その補完候補が“未来のヒストリー”に追加される。minibuffer-default-add-functionを参照のこと。

readが非nilなら、ユーザーの入力が空のときのreadの入力としてもdefaultが使用される。defaultが文字列リストの場合には最初の文字列が入力として使用される。defaultnilなら、空の入力はend-of-fileエラーとなる。しかし通常(readnil)の場合には、ユーザーの入力が空のときread-from-minibufferdefaultを無視して空文字列""をリターンする。この点ではこの関数はこのチャプターの他のどのミニバッファー入力関数とも異なる。

keymapが非nilなら、そのキーマップはミニバッファー内で使用されるローカルキーマップとなる。keymapが省略またはnilなら、minibuffer-local-mapの値がキーマップとして使用される。キーマップの指定は補完のようなさまざまなアプリケーションにたいしてミニバッファーをカスタマイズする、もっとも重要な方法である。

引数historyは入力の保存やミニバッファー内で使用されるヒストリーコマンドが使用するヒストリーリスト変数を指定する。デフォルトはminibuffer-historyhistoryがシンボルtなら、ヒストリーを記録しない。同様にオプションでヒストリーリスト内の開始位置を指定できる。ミニバッファーのヒストリーを参照のこと。

変数minibuffer-allow-text-propertiesが非nilなら、リターンされる文字列にはミニバッファーでのすべてのテキストプロパティが含まれる。それ以外なら、値がリターンされるときすべてのテキストプロパティが取り除かれる。

minibuffer-prompt-properties内のテキストプロパティはプロンプトに適用される。このプロパティリストはデフォルトではプロンプトに使用するフェイスを定義する。このフェイスが与えられるとフェイスリストの最後に適用されて表示前にマージされる。

ユーザーがプロンプトの外観を完全に制御したければすべてのフェイスリストの最後にdefaultフェイスを指定するのがもっとも簡便な方法である。たとえば:

(read-from-minibuffer
 (concat
  (propertize "Bold" 'face '(bold default))
  (propertize " and normal: " 'face '(default))))

引数inherit-input-methodが非nilなら、ミニバッファーにエンターする前にカレントだったバッファーが何であれ、カレントの入力メソッド(入力メソッドを参照)、およびenable-multibyte-charactersのセッティング(テキストの表現方法を参照)が継承される。

ほとんどの場合、initialの使用は推奨されない。非nil値の使用は、historyにたいするコンスセル指定と組み合わせる場合のみ推奨する。入力の初期値を参照のこと。

Function: read-string prompt &optional initial history default inherit-input-method

この関数はミニバッファーから文字列を読み取ってそれをリターンする。引数promptinitialhistoryinherit-input-methodread-from-minibufferで使用する場合と同様。使用されるキーマップはminibuffer-local-map

オプション引数defaultread-from-minibufferの場合と同様に使用されるが、ユーザーの入力が空の場合にリターンするデフォルト値も指定する。read-from-minibufferの場合と同様に値は文字列、文字列リスト、またはnil(空文字列と等価)である。defaultが文字列のときは、その文字列がデフォルト値になる。文字列リストのときは、最初の文字列がデフォルト値になる(これらの文字列はすべて“未来のミニバッファーヒストリー(future minibuffer history)”としてユーザーが利用できる)。

この関数はread-from-minibufferを呼び出すことによって機能する。

(read-string prompt initial history default inherit)
≡
(let ((value
       (read-from-minibuffer prompt initial nil nil
                             history default inherit)))
  (if (and (equal value "") default)
      (if (consp default) (car default) default)
    value))

長い文字列(たとえば複数行に跨がるような文字列)を編集したい場合にread-stringを使うのは理想的ではないかもしれない。そのような場合にはその文字列をユーザーが編集できる通常のバッファーを新たにポップアップしたほうが便利かもしれない。これはread-string-from-bufferを使用して行うことができる。

Function: read-regexp prompt &optional defaults history

この関数はミニバッファーから文字列として正規表現を読み取ってそれをリターンする。ミニバッファーのプロンプト文字列promptが‘:’(とその後にオプションの空白文字)で終端されていなければ、この関数はデフォルトのリターン値(空文字列でない場合。以下参照)の前に‘: ’を付加する。

オプション引数defaultsは、入力が空の場合にリターンするデフォルト値を制御する。値は文字列、nil(空文字列と等価)、文字列リスト、シンボルのうちのいずれか。

defaultsがシンボルの場合、read-regexpは変数read-regexp-defaults-function(以下参照)の値を調べて非nilのときはdefaultsよりそちらを優先的に使用する。この場合は値は以下のいずれか:

  • - regexp-history-last。これは適切なミニバッファーヒストリーリスト(以下参照)の最初の要素を使用することを意味する。
  • - 引数なしの関数。リターン値(nil、文字列、文字列リストのいずれか)がdefaultsの値となる。

これでread-regexpdefaultsを処理した結果はリストに確定する(値がnilまたは文字列の場合は1要素のリストに変換する)。このリストにたいしてread-regexpは以下のような入力として有用な候補をいくつか追加する:

  • - ポイント位置の単語かシンボル。
  • - インクリメンタル検索で最後に使用されたregexp。
  • - インクリメンタル検索で最後に使用された文字列。
  • - 問い合わせつき置換コマンドで最後に使用された文字列またはパターン。

これで関数はユーザー入力を取得するためにread-from-minibufferに渡す正規表現のリストを得た。リストの最初の要素は入力が空の場合のデフォルト値である。リストのすべての要素は“未来のミニバッファーヒストリー(future minibuffer history)”となるリスト(see future list in The GNU Emacs Manualを参照)としてユーザーが利用可能になる。

オプション引数historyが非nilなら、それは使用するミニバッファーヒストリーリストを指定するシンボルである(ミニバッファーのヒストリーを参照)。これが省略またはnilなら、ヒストリーリストのデフォルトはregexp-historyとなる。

ユーザーはcase foldingをオンまたはオフにするかどうかを示すために、M-s cコマンドを使うことができる。ユーザーがこのコマンドを使うと、リターンされる文字列のテキストプロパティcase-foldにはfoldまたはinhibit-foldのいずれかがセットされる。この値を実際に使うかどうかはread-regexpの呼び出し側に任されており、そのための利便的関数としてread-regexp-case-fold-searchが提供されている。典型的な使い方は以下のようになるだろう:

(let* ((regexp (read-regexp "Search for: "))
       (case-fold-search (read-regexp-case-fold-search regexp)))
  (re-search-forward regexp))
User Option: read-regexp-defaults-function

関数read-regexpは、デフォルトの正規表現リストを決定するためにこの変数の値を使用するかもしれない。非nilなら、この変数は以下のいずれかである:

  • - シンボルregexp-history-last
  • - nil、文字列、文字列リストのいずれかをリターンする引数なしの関数。

これらの変数の使い方についての詳細は、上述のread-regexpを参照のこと。

Variable: minibuffer-allow-text-properties

この変数がnilなら、read-from-minibufferread-stringはミニバッファー入力をリターンする前にすべてのテキストプロパティを取り除く。しかしread-no-blanks-input(以下参照)、同様に補完つきでミニバッファー入力を行うread-minibufferとそれに関連する関数(Reading Lisp Objects With the Minibufferを参照)は、この変数の値に関わらず、無条件でfaceプロパティを破棄する。

この変数が非nilなら、補完テーブル由来の文字列(ただし補完された文字列部分のみ)のほとんどのテキストプロパティは保持される。

(let ((minibuffer-allow-text-properties t))
  (completing-read "String: " (list (propertize "foobar" 'data 'zot))))
=> #("foobar" 3 6 (data zot))

この例ではユーザーが‘foo’とタイプしてからTABキーを押下しており、最後の3文字のテキストプロパティだけが保持される。

Variable: minibuffer-local-map

これはミニバッファーからの読み取りにたいするデフォルトローカルキーマップである。デフォルトでは以下のバインディングをもつ:

C-j

exit-minibuffer

RET

exit-minibuffer

M-<

minibuffer-beginning-of-buffer

C-g

abort-recursive-edit

M-n
DOWN

next-history-element

M-p
UP

previous-history-element

M-s

next-matching-history-element

M-r

previous-matching-history-element

Function: read-no-blanks-input prompt &optional initial inherit-input-method

この関数はミニバッファーから文字列を読み取るが、入力の一部として空白文字を認めず、そのかわりに空白文字は入力を終端させる。引数promptinitialinherit-input-methodread-from-minibufferで使用するときと同様。

これは関数read-from-minibufferの簡略化されたインターフェイスであり、キーマップminibuffer-local-ns-mapの値をkeymap引数としてread-from-minibuffer関数に渡す。キーマップminibuffer-local-ns-mapC-qをリバインドしないので、クォートすることによって文字列内にスペースを挿入することが可能である。

minibuffer-allow-text-propertiesの値に関わらず、この関数はテキストプロパティを破棄する。

(read-no-blanks-input prompt initial)
≡
(let (minibuffer-allow-text-properties)
  (read-from-minibuffer prompt initial minibuffer-local-ns-map))
Variable: minibuffer-local-ns-map

このビルトイン変数は関数read-no-blanks-input内でミニバッファーローカルキーマップとして使用されるキーマップである。デフォルトではminibuffer-local-mapのバインディングに加えて、以下のバインディングが有効になる:

SPC

exit-minibuffer

TAB

exit-minibuffer

?

self-insert-and-exit

Function: format-prompt prompt default &rest format-args

minibuffer-default-prompt-format変数に応じたデフォルト値defaultpromptをフォーマットする。

minibuffer-default-prompt-formatはフォーマット文字列(デフォルトは‘" (default %s)"’)であり、これは‘"Local filename (default somefile): "’のようなプロンプトの“default”部分をどのようにフォーマットするかを指示する。

これをどのように表示させるかをユーザーがカスタマイズできるようにするには、ユーザーに(デフォルト値をもつ)値の入力を求めるコードが、そのコードスニペット行に沿って何らかを調べる必要がある:

(read-file-name
 (format-prompt "Local filename" file)
 nil file)

format-argsnilなら、promptはリテラル文字列として使用される。format-argsが非nilならpromptはフォーマットコントロール文字列として使用され、promptformat-argsformatに渡される(文字列のフォーマットを参照)。

minibuffer-default-prompt-formatは‘""’でもよく、その場合には何のデフォルト値も表示されない。

defaultnilならデフォルト値はなく、したがって結果となる値には“default value”文字列は含まれない。defaultが非nilのリストなら、プロンプトでリストの最初の要素が使用される。

promptminibuffer-default-prompt-formatはいずれもsubstitute-command-keysを通じて実行される(ドキュメント内でのキーバインディングの置き換えを参照)。

Variable: read-minibuffer-restore-windows

このオプションが非nil (デフォルト)の場合には、ミニバッファーからの入力を取得してexitする際に、ミニバッファーにエンターしたフレーム、それが別のフレームならミニバッファーウィンドウを所有するフレームのウィンドウ構成をリストアする。これはたとえば同じフレームにあるミニバッファーから入力を所得中にユーザーがウィンドウを分割した場合には、ミニバッファーのexit時にその分割が取り消されることを意味する。

このオプションがnilなら、そのようなリストアは行われない。したがって上記のような分割はミニバッファーexit後も保持される。


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

21.3 ミニバッファーでのLispオブジェクトの読み取り

このセクションではミニバッファーでLispオブジェクトを読み取る関数を説明します。

Function: read-minibuffer prompt &optional initial

この関数はミニバッファーを使用してLispオブジェクトを読み取って、それを評価せずにリターンする。引数promptinitialread-from-minibufferのときと同様に使用する。

これはread-from-minibuffer関数にたいする簡略化されたインターフェイスである。

(read-minibuffer prompt initial)
≡
(let (minibuffer-allow-text-properties)
  (read-from-minibuffer prompt initial nil t))

以下の例では初期入力として文字列"(testing)"を与えている:

(read-minibuffer
 "Enter an expression: " (format "%s" '(testing)))

;; 以下はミニバッファーでの表示:

---------- Buffer: Minibuffer ----------
Enter an expression: (testing)∗
---------- Buffer: Minibuffer ----------

ユーザーはRETをタイプして初期入力をデフォルトとして利用したり入力を編集することができる。

Function: eval-minibuffer prompt &optional initial

この関数はミニバッファーを使用してLisp式を読み取り、それを評価して結果をリターンする。引数promptinitialの使い方はread-from-minibufferと同様。

この関数はread-minibufferの呼び出し結果を単に評価する:

(eval-minibuffer prompt initial)
≡
(eval (read-minibuffer prompt initial))
Function: edit-and-eval-command prompt form

この関数はミニバッファーでLisp式を読み取り、それを評価して結果をリターンする。このコマンドとeval-minibufferの違いは、このコマンドでは初期値としてのformはオプションではなく、テキストの文字列ではないプリント表現に変換されたLispオブジェクトとして扱われることである。これはprin1でプリントされるので、文字列の場合はテキスト初期値内にダブルクォート文字(‘"’)が含まれる。出力関数を参照のこと。

以下の例では、すでに有効なフォームであるようなテキスト初期値として式をユーザーに提案している:

(edit-and-eval-command "Please edit: " '(forward-word 1))

;; 前の式を評価した後に、
;;   ミニバッファーに以下が表示される:

---------- Buffer: Minibuffer ----------
Please edit: (forward-word 1)∗
---------- Buffer: Minibuffer ----------

すぐにRET をタイプするとミニバッファーをexitして式を評価するので、1単語分ポイントは前進する。


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

21.4 ミニバッファーのヒストリー

ミニバッファーヒストリーリスト(minibuffer history list)は手軽に再利用できるように以前のミニバッファー入力を記録します。ミニバッファーヒストリーリストは、(以前に入力された)文字列のリストであり、もっとも最近の文字列が先頭になります。

多数のミニバッファーが個別に存在し、異なる入力の種類に使用されます。それぞれのミニバッファー使用にたいして正しいヒストリーリストを指定するのはLispプログラマーの役目です。

ミニバッファーヒストリーリストは、read-from-minibuffercompleting-readのオプション引数historyに指定します。以下が利用できる値です:

variable

ヒストリーリストとしてvariable(シンボル)を使用する。

(variable . startpos)

ヒストリーリストとしてvariable(シンボル)を使用して、ヒストリー位置の初期値をstartpos(負の整数)とみなす。

startposに0を指定するのは、単にシンボルvariableだけを指定するのと等価である。previous-history-elementはミニバッファー内のヒストリーリストの最新の要素を表示するだろう。 正のstartposを指定すると、ミニバッファーヒストリー関数は(elt variable(1- startpos))がミニバッファー内でカレントで表示されているヒストリー要素であるかのように振る舞う。

一貫性を保つためにミニバッファー入力関数のinitial引数(入力の初期値を参照)を使用して、ミニバッファーの初期内容となるヒストリー要素も指定すべきである。

historyを指定しない場合には、デフォルトのヒストリーリストminibuffer-historyが使用されます。他の標準的なヒストリーリストについては以下を参照してください。最初に使用する前にnilに初期化するだけで、独自のヒストリーリストを作成することもできます。変数がバッファーローカルなら各バッファーが独自に入力ヒストリーリストを所有することになります。

read-from-minibuffercompleting-readは、どちらも新たな要素を自動的にヒストリーリストに追加して、ユーザーがそのリストのアイテムを再使用するためのコマンドを提供します(ミニバッファーのコマンドを参照)。ヒストリーリストを使用するためにプログラムが行う必要があるのはリストの初期化と、使用するときに入力関数にリストの名前を渡すだけです。しかしミニバッファー入力関数がリストを使用していないときに手動でリストを変更しても問題はありません。

デフォルトではM-n (next-history-element, next-history-elementを参照)によってミニバッファーから入力の読み取りを開始したコマンドが提供デフォルト値の終端に達すると、minibuffer-completion-table (補完を行うミニバッファーコマンドを参照)で指定されている補完候補すべてがデフォルトのリストに追加されるので、これらの候補がすべて“未来のヒストリー(future history)”として利用できます。あなたのプログラムは変数minibuffer-default-add-functionを通じてこれを制御することができます。値が関数以外ならこの自動的な追加は無効になります。またはこの変数に独自に関数をセットして一部の候補だけを、あるいは何か他の値を“未来のヒストリー”に追加することもできます。

新たな要素をヒストリーリストに追加するEmacs関数は、リストが長くなりすぎたときに古い要素の削除を行うこともできます。変数history-lengthは、ほとんどのヒストリーリストの最大長を指定する変数です。特定のヒストリーリストにたいして異なる最大長を指定するには、そのヒストリーリストのシンボルのhistory-lengthプロパティにその最大長をセットします。変数history-delete-duplicatesにはヒストリー内の重複を削除するかどうかを指定します。

Function: add-to-history history-var newelt &optional maxelt keep-all

この関数はneweltが空文字列でなければ、それを新たな要素として変数history-varに格納されたヒストリーリストに追加して、更新されたヒストリーリストをリターンする。これはmaxelthistory-lengthがが非nilなら、リストの長さをその変数の値に制限する(以下参照)。maxeltに指定できる値の意味はhistory-lengthの値と同様。history-varはレキシカル変数を参照できない。

add-to-historyは通常はhistory-delete-duplicatesが非nilならば、ヒストリーリスト内の重複メンバーを削除する。しかしkeep-allが非nilなら、それは重複を削除しないことを意味し、たとえneweltが空でもリストに追加する。

Variable: history-add-new-input

この変数の値がnilなら、ミニバッファーから読み取りを行う標準的な関数はヒストリーリストに新たな要素を追加しない。これによりLispプログラムがadd-to-historyを使用して明示的に入力ヒストリーを管理することになる。デフォルト値はt

User Option: history-length

この変数の値は、最大長を独自に指定しないすべてのヒストリーリストの最大長を指定する。値がtなら最大長がない(古い要素を削除しない)ことを意味する。ヒストリーリスト変数のシンボルのhistory-lengthプロパティが非nilなら、その特定のヒストリーリストにたいする最大長として、そのプロパティ値がこの変数をオーバーライドする。

User Option: history-delete-duplicates

この変数の値がtなら、それは新たなヒストリー要素の追加時に以前からある等しい要素が削除されることを意味する。

以下は標準的なミニバッファーヒストリーリスト変数です:

Variable: minibuffer-history

ミニバッファーヒストリー入力にたいするデフォルトのヒストリーリスト。

Variable: query-replace-history

query-replaceの引数(と他のコマンドの同様の引数)にたいするヒストリーリスト。

Variable: file-name-history

ファイル名引数にたいするヒストリーリスト。

Variable: buffer-name-history

バッファー名引数にたいするヒストリーリスト。

Variable: regexp-history

正規表現引数にたいするヒストリーリスト。

Variable: extended-command-history

拡張コマンド名引数にたいするヒストリーリスト。

Variable: shell-command-history

シェルコマンド引数にたいするヒストリーリスト。

Variable: read-expression-history

評価されるためのLisp式引数にたいするヒストリーリスト。

Variable: face-name-history

フェイス引数にたいするヒストリーリスト。

Variable: custom-variable-history

read-variableが読み取る変数名引数にたいするヒストリーリスト。

Variable: read-number-history

read-numberが読み取る数値にたいするヒストリーリスト。

Variable: goto-line-history

goto-lineの引数にたいするヒストリーリスト。ユーザーオプションgoto-line-history-localをカスタマイズすれば、各バッファーにたいしてこの変数をローカルにできる。


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

21.5 入力の初期値

ミニバッファー入力にたいする関数のいくつかには、initialと呼ばれる引数があります。これは通常のように空の状態で開始されるのではなく、特定のテキストとともにミニバッファーが開始されることを指定しますが、ほとんどの場合においては推奨されない機能です。

initialが文字列なら、ミニバッファーはその文字列のテキストを含む状態で開始され、ユーザーがそのテキストの編集を開始するとき、ポイントはテキストの終端にあります。ユーザーがミニバッファーをexitするために単にRETをタイプした場合には、この入力文字列の初期値をリターン値だと判断します。

initialにたいして非nil値の使用には反対します。なぜなら初期入力は強要的なインターフェイスだからです。ユーザーにたいして有用なデフォルト入力を提案するためには、ヒストリーリストやデフォルト値の提供のほうがより有用です。

しかしinitial引数にたいして文字列を指定すべき状況が1つだけあります。それはhistory引数にコンスセルを指定したときです。ミニバッファーのヒストリーを参照してください。

initial(string . position)という形式をとることもできます。これはstringをミニバッファーに挿入するが、その文字列のテキスト中のpositionにポイントを配置するという意味です。

歴史的な経緯により、positionは異なる関数の間で実装が統一されていません。completing-readではpositionの値は0基準です。つまり値0は文字列の先頭、1は最初の文字の次、...を意味します。しかしread-minibuffer、およびこの引数をサポートする補完を行わない他のミニバッファー入力関数では、1は文字列の先頭、2は最初の文字の次、...を意味します。

initialの値としてのコンスセルの使用は推奨されません。


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

21.6 補完

補完(complete, ompletion)は省略された形式から始まる名前の残りを充填する機能です。補完はユーザー入力と有効な名前リストを比較して、ユーザーが何をタイプしたかで名前をどの程度一意に判定できるか判断することによって機能します。たとえばC-x b (switch-to-buffer)とタイプしてからスイッチしたいバッファー名の最初の数文字をタイプして、その後にTAB (minibuffer-complete)をタイプすると、Emacsはその名前を可能な限り展開します。

標準的なEmacsコマンドはシンボル、ファイル、バッファー、プロセスの名前にたいする補完を提案します。このセクションの関数により、他の種類の名前にたいしても補完を実装できます。

try-completion関数は補完にたいする基本的なプリミティブです。これは初期文字列にたいして文字列セットをマッチして、最長と判定された補完をリターンします。

関数completing-readは補完にたいする高レベルなインターフェイスを提供します。completing-readの呼び出しによって有効な名前リストの判定方法が指定されます。その後にこの関数は補完にたいして有用ないくつかのコマンドにキーバインドするローカルキーマップとともに、ミニバッファーをアクティブ化します。その他の関数は特定の種類の名前を補完つきで読み取る、簡便なインターフェイスを提供します。


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

21.6.1 基本的な補完関数

以下の補完関数は、その関数自身ではミニバッファーで何も行いません。ここではミニバッファーを使用する高レベルの補完機能とともに、これらの関数について説明します。

Function: try-completion string collection &optional predicate

この関数はcollection内のstringに可能なすべての補完の共通する最長部分文字列をリターンする。

collection補完テーブル(completion table)と呼ばれる。値は文字列リスト、コンスセル、obarray、ハッシュテーブル、または補完関数でなければならない。

try-completionは補完テーブルにより指定された許容できる補完それぞれにたいして、stringと比較を行う。許容できる補完マッチが存在しなければnilをリターンする。マッチする補完が1つだけで、それが完全一致ならばtをリターンする。それ以外は、すべてのマッチ可能な補完に共通する最長の初期シーケンスをリターンする。

collectionがリストなら、許容できる補完(permissible completions)はそのリストの要素によって指定される。リストの要素は文字列、またはCARが文字列、または(symbol-nameによって文字列に変換される)シンボルであるようなコンスセルである。リストに他の型の要素が含まれる場合は無視される。

collectionがobarray(シンボルの作成とinternを参照)なら、そのobarray内のすべてのシンボル名が許容できる補完セットを形成する。

collectionがハッシュテーブルの場合には、文字列かシンボルのキーが利用可能な補完となる。他のキーは無視される。

collectionとして関数を使用することもできる。この場合にはその関数だけが補完を処理する役目を担う。つまりtry-completionは、この関数が何をリターンしようともそれをリターンする。この関数はstringpredicatenilの3つの引数で呼び出される(3つ目の引数は同じ関数をall-completionsでも使用して、どちらの場合でも適切なことを行うため)。プログラムされた補完を参照のこと。

引数predicateが非nilの場合には、collectionがハッシュテーブルなら1引数、それ以外は2引数の関数でなければならない。これは利用可能なマッチのテストに使用され、マッチはpredicateが非nilをリターンしたときだけ受け入れられる。predicateに与えられる引数は文字列、alistのコンスセル(CARが文字列)、またはobarrayのシンボル(シンボル名ではない)のいずれか。collectionがハッシュテーブルなら、predicateは文字列キー(string key)と連想値(associated value)の2引数で呼び出される。

これらに加えて許容され得るためには、補完はcompletion-regexp-list内のすべての正規表現にもマッチしなければならない。(collectionが関数なら、その関数自身がcompletion-regexp-listを処理する必要がある)。

以下の1つ目の例では、文字列‘foo’がalistのうち3つのCARとマッチされている。すべてのマッチは文字‘fooba’で始まるので、それが結果となる。2つ目の例では可能なマッチは1つだけで、しかも完全一致なのでリターン値はtになる。

(try-completion
 "foo"
 '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4)))
     ⇒ "fooba"

(try-completion "foo" '(("barfoo" 2) ("foo" 3)))
     ⇒ t

以下の例では文字‘forw’で始まるシンボルが多数あり、それらはすべて単語‘forward’で始まる。ほとんどのシンボルはその後に‘-’が続くが、すべてではないので‘forward’までしか補完できない。

(try-completion "forw" obarray)
     ⇒ "forward"

最後に以下の例では述語testに渡される利用可能なマッチは3つのうち2つだけである(文字列‘foobaz’は短すぎる)。これらは両方とも文字列‘foobar’で始まる。

(defun test (s)
  (> (length (car s)) 6))
     ⇒ test
(try-completion
 "foo"
 '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4))
 'test)
     ⇒ "foobar"
Function: all-completions string collection &optional predicate

この関数はstringの利用可能な補完すべてのリストをリターンする。この関数の引数はtry-completionの引数と同じであり、try-completionが行うのと同じ方法でcompletion-regexp-listを使用する。

collectionか関数ならstringpredicatetの3つの引数で呼び出される。この場合はその関数がリターンするのが何であれ、all-completionsはそれをリターンする。プログラムされた補完を参照のこと。

以下の例はtry-completionの例の関数testを使用している。

(defun test (s)
  (> (length (car s)) 6))
     ⇒ test

(all-completions
 "foo"
 '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4))
 'test)
     ⇒ ("foobar1" "foobar2")
Function: test-completion string collection &optional predicate

この関数はstringcollectionpredicateで指定された有効な補完候補ならnilをリターンする。引数はtry-completionの引数と同じ。たとえばcollectionが文字列リストなら、stringがリスト内に存在して、かつpredicateを満足すればtrueとなる。

この関数はtry-completionが行うのと同じ方法でcompletion-regexp-listを使用する。

predicateが非nilcollectionが同じ文字列を複数含む場合には、completion-ignore-caseにしたがってcompare-stringsで判定してそれらすべてをリターンするか、もしくは何もリターンしない。それ以外ではtest-completionのリターン値は基本的に予測できない。

collectionが関数の場合はstringpredicatelambdaの3つの引数で呼び出される。それが何をリターンするにせよtest-completionはそれをリターンする。

Function: completion-boundaries string collection predicate suffix

この関数はポイントの前のテキストがstring、ポイントの後がsuffixと仮定して、collectionが扱うフィールドの境界(boundary)をリターンする。

補完は通常は文字列(string)全体に作用するので、すべての普通のコレクション(collection)にたいして、この関数は常に(0 . (length suffix))をリターンするだろう。しかしファイルにたいする補完などの、より複雑な補完は1回に1フィールド行われる。たとえばたとえ"/usr/share/doc"が存在しても、"/usr/sh"の補完に"/usr/share/"は含まれるが、"/usr/share/doc"は含まれないだろう。また"/usr/sh"にたいするall-completions"/usr/share/"は含まれず、"share/"だけが含まれるだろう。string"/usr/sh"suffix"e/doc"なら、completion-boundaries(5 . 1)をリターンするだろう。これはcollection"/usr/"の後ろにあり"/doc"の前にある領域に関する補完情報だけをリターンするであろうことを告げている。try-completionは意味のある境界に影響されない。すなわち"/usr/sh"にたいしてtry-completion"share/"ではなく、依然として"/usr/share/"をリターンする。

補完alistを変数に格納した場合は、変数のrisky-local-variableプロパティに非nilをセットして、その変数がrisky(危険)だとマークすること。ファイルローカル変数を参照のこと。

Variable: completion-ignore-case

この変数の値が非nilなら、補完でのcase(大文字小文字)の違いは意味をもたない。read-file-nameでは、この変数はread-file-name-completion-ignore-case (ファイル名の読み取りを参照)にオーバーライドされる。read-bufferでは、この変数はread-buffer-completion-ignore-case (高レベルの補完関数を参照)にオーバーライドされる。

Variable: completion-regexp-list

これは正規表現のリストである。補完関数はこのリスト内のすべての正規表現にマッチした場合のみ許容できる補完と判断する。case-fold-search (検索と大文字小文字を参照)ではcompletion-ignore-caseの値にバインドされる。

この変数にグローバルに非nilをセットしてはならない。安全ではないし恐らく補完コマンドでエラーが発生するだろう。この変数への非nil値のバインドはtry-completiontest-completionall-completionsといった基本的な補完コマンド呼び出しの前後においてletでのみバインドを行う必要がある。

Macro: lazy-completion-table var fun

この変数は変数varを補完のためのcollectionとしてlazy(lazy: 力のない、だらけさせる、のろのろした、怠惰な、不精な、眠気を誘う)な方法で初期化する。ここでlazyとは、collection内の実際のコンテンツを必要になるまで計算しないという意味。このマクロはvarに格納する値の生成に使用する。varを使用して最初に補完を行ったとき、真の値が実際に計算される。これは引数なしでfunを呼び出すことにより行われる。funがリターンする値はvarの永続的な値となる。

以下は例:

(defvar foo (lazy-completion-table foo make-my-alist))

既存の補完テーブルを受け取って変更したバージョンをリターンする関数がいくつかあります。completion-table-case-foldは大文字小文字を区別しない、case-insensitiveなテーブルをリターンします。completion-table-in-turncompletion-table-mergeは、複数の入力テーブルを異なる方法で組み合わせます。completion-table-subvertはテーブルを異なる初期プレフィックス(initial prefix)で変更します。completion-table-with-quotingはクォートされたテキストの処理に適したテーブルをリターンします。completion-table-with-predicateは述語関数(predicate function)によるフィルタリングを行います。completion-table-with-terminatorは終端文字列(terminating string)を追加します。


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

21.6.2 補完とミニバッファー

このセクションでは補完つきでミニバッファーから読み取るための、基本的なインターフェイスを説明します。

Function: completing-read prompt collection &optional predicate require-match initial history default inherit-input-method

この関数は補完の提供によりユーザーを支援して、ミニバッファーから文字列を読み取る。prompt (文字列でなければならない)のプロンプトとともにミニバッファーをアクティブ化する。

実際の補完は補完テーブルcollectionと補完述語predicateを関数try-completion (基本的な補完関数を参照)に渡すことにより行われる。これは補完の使用されるローカルキーマップに特定のコマンドをバインドしたとき発生する。これらのコマンドのいくつかはtest-completionも呼び出す。したがってpredicateが非nilなら、collectioncompletion-ignore-caseが矛盾しないようにすること。Definition of test-completionを参照されたい。

collectionが関数のときの詳細な要件はプログラムされた補完を参照のこと。

オプション引数require-matchの値はユーザーがミニバッファーをexitする方法を決定する。

  • nilなら、通常のミニバッファーexitコマンドはミニバッファーの入力と無関係に機能する。
  • tなら、入力がcollectionの要素に補完されるまで通常のミニバッファーexitコマンドは機能しない。
  • confirmなら、どのような入力でもユーザーはexitできるが、入力がconfirmの要素に補完されていなければ確認を求められる。
  • confirm-after-completionなら、どのような入力でもユーザーはexitできるが、前のコマンドが補完コマンド(たとえばminibuffer-confirm-exit-commandsの中のコマンドのいずれか)で、入力の結果がcollectionの要素でなければ確認を求められる。補完を行うミニバッファーコマンドを参照のこと。
  • 関数の場合には入力を唯一の引数として呼び出される。その入力が許容できる場合には関数は非nilをリターンすること。
  • require-matchにたいする他の値はtと同じだが、exitコマンドは補完処理中はexitしない。

しかしrequire-matchの値に関わらず、空の入力は常に許容される。この場合completing-readdefaultがリストなら最初の要素、defaultnilなら""、またはdefaultをリターンする。文字列とdefault内の文字列はヒストリーコマンドを通じてユーザーが利用できる(ミニバッファーのコマンドを参照)。更にdefaultの値をM-nで使い果たすと、その補完候補が“未来のヒストリー”に追加される。minibuffer-default-add-functionを参照のこと。

関数completing-readrequire-matchnilならキーマップとしてminibuffer-local-completion-mapを、require-matchが非nilならminibuffer-local-must-match-mapを使用する。補完を行うミニバッファーコマンドを参照のこと。

引数historyは入力の保存とミニバッファーヒストリーコマンドに、どのヒストリーリスト変数を使用するか指定する。デフォルトはminibuffer-historyhistoryがシンボルtなら、ヒストリーを記録しない。ミニバッファーのヒストリーを参照のこと。

initialはほとんどの場合は推奨されない。historyにたいするコンスセル指定と組み合わせた場合のみ非nil値の使用を推奨する。入力の初期値を参照のこと。デフォルト入力にたいしてはかわりにdefaultを使用すること。

引数inherit-input-methodが非nilなら、ミニバッファーにエンターする前にカレントだったバッファーが何であれ、カレントの入力メソッド(入力メソッドを参照)、およびenable-multibyte-charactersのセッティング(テキストの表現方法を参照)が継承される。

変数completion-ignore-caseが非nilなら、利用可能なマッチにたいして入力を比較するときの補完はcaseを区別しない。基本的な補完関数を参照のこと。このモードでの操作では、predicateもcaseを区別してはならない(さもないと驚くべき結果となるであろう)。

以下はcompleting-readを使用した例:

(completing-read
 "Complete a foo: "
 '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4))
 nil t "fo")

;; 前の式を評価後に、
;;   ミニバッファーに以下が表示される:

---------- Buffer: Minibuffer ----------
Complete a foo: fo∗
---------- Buffer: Minibuffer ----------

その後ユーザーがDEL DEL b RETをタイプすると、completing-readbarfooをリターンする。

completing-read関数は、実際に補完を行うコマンドの情報を渡すために変数をバインドする。これらの変数は以降のセクションで説明する。

Variable: completing-read-function

この変数の値は関数でなければならず、補完つきの読み取りを実際に行うためにcompleting-readから呼び出される。この関数はcompleting-readと同じ引数を受け入れる。他の関数のバインドして通常のcompleting-readの振る舞いを完全にオーバーライドすることができる。


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

21.6.3 補完を行うミニバッファーコマンド

このセクションでは補完のためにミニバッファーで使用されるキーマップ、コマンド、ユーザーオプションを説明します。

Variable: minibuffer-completion-table

この変数の値はミニバッファー内の補完に使用される補完テーブル(基本的な補完関数を参照)。これはcompleting-readtry-completionに渡す補完テーブルを含むバッファーローカル変数。minibuffer-completeのようなミニバッファー補完コマンドにより使用される。

Variable: minibuffer-completion-predicate

この変数の値はcompleting-readtry-completionに渡す述語(predicate)である。この変数は他のミニバッファー補完関数にも使用される。

Variable: minibuffer-completion-confirm

この変数はミニバッファーをexitする前にEmacsが確認を求めるかどうかを決定する。completing-readはこの変数をセットして、exitする前に関数minibuffer-complete-and-exitがこの値をチェックする。値がnilなら確認は求められない。値がconfirmの場合は、入力が有効な補完候補でなくてもユーザーはexitするかもしれないがEmacsは確認を求めない。値がconfirm-after-completionの場合、入力が有効な補完候補でなくてもユーザーはexitするかもしれないが、ユーザーがminibuffer-confirm-exit-commands内の任意の補完コマンドの直後に入力を確定した場合にはEmacsは確認を求める。

Variable: minibuffer-confirm-exit-commands

この変数には、completing-readの引数require-matchconfirm-after-completionのときにミニバッファーexit前にEmacsに確認を求めさせるコマンドのリストが保持されている。このリスト内のコマンドを呼び出した直後にユーザーがミニバッファーのexitを試みるとEmacsは確認を求める。

Command: minibuffer-complete-word

この関数はせいぜい1つの単語からミニバッファーを補完する。たとえミニバッファーのコンテンツが1つの補完しかもたない場合でも、minibuffer-complete-wordはその単語に属さない最初の文字を超えた追加はしない。構文テーブルを参照のこと。

Command: minibuffer-complete

この関数は可能な限りミニバッファーのコンテンツを補完する。

Command: minibuffer-complete-and-exit

この関数はミニバッファーのコンテンツを補完して確認が要求されない場合(たとえばminibuffer-completion-confirmnilのとき)はexitする。確認が要求される場合には、このコマンドを即座に繰り返すことによって確認が行われないようにする。このコマンドは2回連続で実行された場合は確認なしで機能するようにプログラムされている。

Command: minibuffer-completion-help

この関数はカレントのミニバッファーのコンテンツで利用可能な補完のリストを作成する。これはall-completionsの引数collectionに変数minibuffer-completion-tableの値、引数predicateminibuffer-completion-predicateの値を使用して呼び出すことによって機能する。補完リストは*Completions*と呼ばれるバッファーのテキストとして表示される。

Function: display-completion-list completions

この関数はstandard-output内のストリーム(通常はバッファー)にcompletionsを表示する(ストリームについての詳細はLispオブジェクトの読み取りとプリントを参照)。引数completionsは通常はall-completionsがリターンする補完リストそのものだが、そうである必要はない。要素はシンボルか文字列で、どちらも単にプリントされる。文字列2つのリストでもよく、2つの文字列が結合されたかのようにプリントされる。この場合、1つ目の文字列は実際の補完で、2つ目の文字列は注釈の役目を負う。

この関数はminibuffer-completion-helpより呼び出される。一般的には以下のようにwith-output-to-temp-bufferとともに使用される。

(with-output-to-temp-buffer "*Completions*"
  (display-completion-list
    (all-completions (buffer-string) my-alist)))
User Option: completion-auto-help

この変数が非nilなら、次の文字が一意でなく決定できないために補完が完了しないときは常に、補完コマンドは利用可能な補完リストを自動的に表示する。

Variable: minibuffer-local-completion-map

completing-readの値は、補完の1つが完全に一致することを要求されないときにローカルキーマップとして使用される。デフォルトではこのキーマップは以下のバインディングを作成する:

?

minibuffer-completion-help

SPC

minibuffer-complete-word

TAB

minibuffer-complete

親キーマップとしてminibuffer-local-mapを使用する(Definition of minibuffer-local-mapを参照)。

Variable: minibuffer-local-must-match-map

completing-readは、1つの補完の完全な一致が要求されないときのローカルキーマップとしてこの値を使用する。したがってexit-minibufferにキーがバインドされていなければ、無条件にミニバッファーをexitする。デフォルトでは、このキーマップは以下のバインディングを作成する:

C-j

minibuffer-complete-and-exit

RET

minibuffer-complete-and-exit

親キーマップはminibuffer-local-completion-mapを使用する。

Variable: minibuffer-local-filename-completion-map

これは単にSPCを非バインドするsparseキーマップ(sparse: 疎、希薄、まばら)を作成する。これはファイル名にスペースを含めることができるからである。関数read-file-nameは、このキーマップとminibuffer-local-completion-mapminibuffer-local-must-match-mapのいずれかを組み合わせる。

Variable: minibuffer-beginning-of-buffer-movement

nilの場合には、M-<コマンドはポイントがプロンプト終端の後ならポイントをプロンプト終端に移動する。ポイントがプロンプト終端またはプロンプト終端より前ならバッファーの先頭に移動する。この変数がnilならM-<beginning-of-bufferのように振る舞う。


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

21.6.4 高レベルの補完関数

このセクションでは特定の種類の名前を補完つきで読み取る便利な高レベル関数を説明します。

ほとんどの場合は、Lisp関数の中盤でこれらの関数を呼び出すべきではありません。可能なときはinteractive指定の内部で呼び出して、ミニバッファーのすべての入力をコマンドの引数読み取りの一部にします。コマンドの定義を参照してください。

Function: read-buffer prompt &optional default require-match predicate

この関数はバッファーの名前を読み取ってそれを文字列でリターンする。プロンプトはprompt。引数defaultはミニバッファーが空の状態でユーザーがexitした場合にリターンされるデフォルト名として使用される。非nilなら文字列、文字列リスト、またはバッファーを指定する。リストならリストの先頭の要素がデフォルト値になる。デフォルト値はプロンプトに示されるが、初期入力としてミニバッファーには挿入されない。

引数promptはコロンかスペースで終わる文字列である。defaultが非nilなら、この関数はデフォルト値つきでミニバッファーから読み取る際の慣習にしたがってコロンの前のpromptの中にこれを挿入する。

オプション引数require-matchcompleting-readのときと同じ。補完とミニバッファーを参照のこと。

オプション引数predicateが非nilなら、それは考慮すべきバッファーをフィルターする関数を指定する。この関数は可能性のある候補を引数として呼び出されて、候補を拒絶するならnil、許容するなら非nilをリターンすること。

以下の例ではユーザーが‘minibuffer.t’とエンターしてから、RETをタイプしている。引数require-matchtであり、与えられた入力で始まるバッファー名は‘minibuffer.texi’だけなので、その名前が値となる。

(read-buffer "Buffer name: " "foo" t)
;; 前の式を評価した後、
;;   空のミニバッファーに
;;   以下のプロンプトが表示される:

---------- Buffer: Minibuffer ----------
Buffer name (default foo): ∗
---------- Buffer: Minibuffer ----------

;; ユーザーがminibuffer.t RETとタイプする
     ⇒ "minibuffer.texi"
User Option: read-buffer-function

この変数が非nilなら、それはバッファー名を読み取る関数を指定する。read-bufferは通常行うことを行うかわりに、read-bufferと同じ引数でその関数を呼び出す。

User Option: read-buffer-completion-ignore-case

この変数が非non-nilなら、バッファー名の読み取りの補完処理においてread-bufferはcaseを無視する。

Function: read-command prompt &optional default

この関数はコマンドの名前を読み取って、Lispシンボルとしてそれをリターンする。引数promptread-from-minibufferで使用される場合と同じ。それが何であれcommandptをリターンすればコマンドであり、コマンド名とはcommandptをリターンするシンボルだということを思い出してほしい。インタラクティブな呼び出しを参照のこと。

引数defaultはユーザーがnull入力をエンターした場合に何をリターンするか指定する。シンボル、文字列、文字列リストを指定できる。文字列ならread-commandはリターンする前にそれをinternする。リストならread-commandはリストの最初の要素をinternする。defaultnilならデフォルトが指定されなかったことを意味する。その場合には、もしユーザーがnull入力をエンターするとリターン値は(intern "")、つまり名前が空文字列でプリント表現が##であるようなシンボル(シンボル型を参照)。

(read-command "Command name? ")

;; 前の式を評価した後に、
;;   空のミニバッファーに以下のプロンプトが表示される:

---------- Buffer: Minibuffer ----------
Command name?
---------- Buffer: Minibuffer ----------

ユーザーがforward-c RETとタイプすると、この関数はforward-charをリターンする。

read-command関数はcompleting-readの簡略化されたインターフェイスである。実在するLisp変数のセットを補完するために変数obarray、コマンド名だけを受け入れるために述語commandpを使用する。

(read-command prompt)
≡
(intern (completing-read prompt obarray
                         'commandp t nil))
Function: read-variable prompt &optional default

この変数はカスタマイズ可能な変数の名前を読み取って、それをシンボルとしてリターンする。引数の形式はread-commandの引数と同じ。この関数はcommandpのかわりにcustom-variable-pを述語に使用する点を除いてread-commandと同様に振る舞う。

Command: read-color &optional prompt convert allow-empty display

この関数はカラー指定(カラー名、または#RRRGGGBBBのような形式のRGB16進値)の文字列を読み取る。これはプロンプトにprompt(デフォルトは"Color (name or #RGB triplet):")を表示して、カラー名にたいする補完を提供する(16進RGB値は補完しない)。標準的なカラー名に加えて、補完候補にはポイント位置のフォアグラウンドカラーとバックグラウンドカラーが含まれる。

Valid RGB values are described in カラー名.

この関数のリターン値はミニバッファー内でユーザーがタイプした文字列である。しかしインタラクティブに呼び出されたとき、またはオプション引数convertが非nilなら、入力されたカラー名のかわりにそれに対応するRGB値文字列をリターンする。この関数は入力として有効なカラー指定を求める。allow-emptyが非nilでユーザーがnull入力をエンターした場合は空のカラー名が許容される。

インタラクティブに呼び出されたとき、またはdisplayが非nilなら、エコーエリアにもリターン値が表示される。

ユーザーが選択したコーディングシステムの関数read-coding-systemread-non-nil-coding-system、および入力メソッドread-input-method-nameも参照されたい。


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

21.6.5 ファイル名の読み取り

高レベル補完関数read-file-nameread-directory-nameread-shell-commandはそれぞれファイル名、ディレクトリー名、シェルコマンドを読み取るようにデザインされています。これらはデフォルトディレクトリーの自動挿入を含む特別な機能を提供します。

Function: read-file-name prompt &optional directory default require-match initial predicate

この関数はプロンプトpromptとともに補完つきでファイル名を読み取る。

例外として以下のすべてが真ならば、この関数はミニバッファーのかわりにグラフィカルなファイルダイアログを使用してファイル名を読み取る:

  1. マウスコマンドを通じて呼び出された。
  2. グラフィカルなディスプレイ上の選択されたフレームがこの種のダイアログをサポートしている。
  3. 変数use-dialog-boxが非nilの場合。Dialog Boxes in The GNU Emacs Manualを参照のこと。
  4. directory引数(以下参照)がリモートファイルを指定しない場合。Remote Files in The GNU Emacs Manualを参照のこと。

グラフィカルなファイルダイアログを使用したときの正確な振る舞いはプラットホームに依存する。ここでは単にミニバッファーを使用したときの振る舞いを示す。

read-file-nameはリターンするファイル名を自動的に展開しない。絶対ファイル名が必要ならば自分でexpand-file-nameを呼び出すことができる。

オプション引数require-matchcompleting-readのときと同じ。補完とミニバッファーを参照のこと。

引数directoryは、相対ファイル名の補完に使用するディレクトリーを指定する。値は絶対ディレクトリー名。変数insert-default-directoryが非nilなら、初期入力としてミニバッファーにdirectoryも挿入される。デフォルトはカレントバッファーのdefault-directoryの値。

initialを指定すると、それはミニバッファーに挿入する初期ファイル名になる(directoryが挿入された場合はその後に挿入される)。この場合、ポイントはinitialの先頭に配置される。initialのデフォルト値はnil(ファイル名を挿入しない)。initialが何を行うか確認するには、ファイルをvisitしているバッファーでC-x C-vを試すとよい。注意: ほとんどの場合はinitialよりもdefaultの使用を推奨する。

defaultが非nilなら、最初にread-file-nameが挿入したものと等しい空以外のコンテンツを残してユーザーがミニバッファーをexitすると、この関数はdefaultをリターンする。insert-default-directoryが非nilならそれがデフォルトとなるので、ミニバッファーの初期コンテンツは常に空以外になる。require-matchの値に関わらずdefaultの有効性はチェックされない。とはいえrequire-matchが非nilなら、ミニバッファーの初期コンテンツは有効なファイル名(またはディレクトリー名)であるべきだろう。それが有効でなければ、ユーザーがそれを編集せずにexitするとread-file-nameは補完を試みて、defaultはリターンされない。defaultはヒストリーコマンドからも利用できる。

defaultnilなら、read-file-nameはその場所に代用するデフォルトを探そうと試みる。この代用デフォルトは明示的にdefaultにそれが指定されたかのように、defaultとまったく同じ方法で扱われる。defaultnilでもinitialが非nilなら、デフォルトはdirectoryinitialから得られる絶対ファイル名になる。defaultinitialの両方がnilで、そのバッファーがファイルをvisitしているバッファーなら、read-file-nameはそのファイルの絶対ファイル名をデフォルトとして使用する。バッファーがファイルをvisitしていなければデフォルトは存在しない。この場合はユーザーが編集せずにRETをタイプすると、read-file-nameは前にミニバッファーに挿入されたコンテンツを単にリターンする。

空のミニバッファー内でユーザーがRETをタイプすると、この関数はrequire-matchの値に関わらず空文字列をリターンする。たとえばユーザーがM-x set-visited-file-nameを使用して、カレントバッファーをファイルをvisitしていないことにするために、この方法を使用している。

predicateが非nilなら、それは補完候補として許容できるファイル名を決定する1引数の関数である。predicateが関数名にたいして非nilをリターンすれば、それはファイル名として許容できる値である。

以下はread-file-nameを使用した例:

(read-file-name "The file is ")

;; 前の式を評価した後に、
;;   ミニバッファーに以下が表示される:

---------- Buffer: Minibuffer ----------
The file is /gp/gnu/elisp/∗
---------- Buffer: Minibuffer ----------

manual TABをタイプすると以下がリターンされる:

---------- Buffer: Minibuffer ----------
The file is /gp/gnu/elisp/manual.texi∗
---------- Buffer: Minibuffer ----------

ここでユーザーがRETをタイプすると、read-file-nameは文字列"/gp/gnu/elisp/manual.texi"をファイル名としてリターンする。

Variable: read-file-name-function

nilなら、read-file-nameと同じ引数を受け取る関数である。read-file-nameが呼び出されたとき、read-file-nameは通常の処理を行なうかわりに与えられた引数でこの関数を呼び出す。

User Option: read-file-name-completion-ignore-case

この変数が非nilなら、read-file-nameは補完を行なう際にcaseを無視する。

Function: read-directory-name prompt &optional directory default require-match initial

この関数はread-file-nameと似ているが補完候補としてディレクトリーだけを許す。

defaultnilinitialが非nilなら、read-directory-namedirectory (directorynilならカレントバッファーのデフォルトディレクトリー)とinitialを組み合わせて代用のデフォルトを構築する。この関数はdefaultinitialの両方がnilならdirectorydirectorynilならカレントバッファーのデフォルトディレクトリーを代用のデフォルトとして使用する。

User Option: insert-default-directory

この変数はread-file-nameにより使用されるため、ファイル名を読み取るほとんどのコマンドにより間接的に使用される(これらのコマンドにはコマンドのインタラクティブフォームに‘f’や‘F’のコードレター(code letter))をふくむすべてのコマンドが含まれる。Code Characters for interactiveを参照されたい)。この変数の値は、(もしあれば)デフォルトディレクトリー名をミニバッファー内に配置してread-file-nameを開始するかどうかを制御する。変数の値がnilなら、read-file-nameはミニバッファーに初期入力を何も配置しない(ただしinitial引数で初期入力を指定しない場合)。この場合には依然としてデフォルトディレクトリーが相対ファイル名の補完に使用されるが表示はされない。

この変数がnilでミニバッファーの初期コンテンツが空なら、ユーザーはデフォルト値にアクセスするために次のヒストリー要素を明示的にフェッチする必要があるだろう。この変数が非nilならミニバッファーの初期コンテンツは常に空以外となり、ミニバッファーで編集をおこなわず即座にRETをタイプすることによって、常にデフォルト値を要求できる(上記参照)。

たとえば:

;; デフォルトディレクトリーとともにミニバッファーが開始
(let ((insert-default-directory t))
  (read-file-name "The file is "))

---------- Buffer: Minibuffer ----------
The file is ~lewis/manual/∗
---------- Buffer: Minibuffer ----------

;; ミニバッファーはプロンプトだけで空
;;   appears on its line.
(let ((insert-default-directory nil))
  (read-file-name "The file is "))

---------- Buffer: Minibuffer ----------
The file is ∗
---------- Buffer: Minibuffer ----------
Function: read-shell-command prompt &optional initial history &rest args

この関数はプロンプトpromptとインテリジェントな補完を提供して、ミニバッファーからシェルコマンドを読み取る。これはコマンド名にたいして適切な候補を使用してコマンドの最初の単語を補完する。コマンドの残りの単語はファイル名として補完する。

この関数はミニバッファー入力にたいするキーマップとしてminibuffer-local-shell-command-mapを使用する。history引数は使用するヒストリーリストを指定する。省略またはnilの場合のデフォルトはshell-command-history (shell-command-historyを参照)。オプション引数initialはミニバッファーの初期コンテンツを指定する(入力の初期値を参照)。もしあれば残りのargsread-from-minibuffer内のdefaultinherit-input-methodとして使用される(ミニバッファーでのテキスト文字列の読み取りを参照)。

Variable: minibuffer-local-shell-command-map

このキーマップはread-shell-commandにより、コマンドとシェルコマンドの一部となるファイル名の補完のために使用される。これは親キーマップとしてminibuffer-local-mapを使用して、TABcompletion-at-pointにバインドする。


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

21.6.6 補完変数

補完のデフォルト動作を変更するために使用される変数がいくつかあります。

User Option: completion-styles

この変数の値は補完を行うために使用される補完スタイル(シンボル)である。補完スタイル(completion style)とは、補完を生成するためのルールセットのこと。このリストにあるシンボルはそれぞれ、completion-styles-alist内に対応するエントリーをもたなければならない。

Variable: completion-styles-alist

この変数には補完スタイルのリストが格納される。リスト内の各要素は以下の形式をもつ

(style try-completion all-completions doc)

ここでstyleは補完スタイルの名前(シンボル)であり、そのスタイルを参照するために変数completion-styles内で使用されるかもしれない。try-completionは補完を行なう関数で、all-completions補完をリストする関数、docは補完スタイルを説明する文字列である。

関数try-completionall-completionsstringcollectionpredicatepointの4つの引数をとる。引数stringcollectionpredicateの意味はtry-completion (基本的な補完関数を参照)のときと同様。引数pointstring内のポイント位置。各関数は自身の処理を行ったら非nil、行わなかった場合(たとえば補完スタイルに一致するようにstringを行う方法がない場合)はnilをリターンする。

ユーザーがminibuffer-complete (補完を行うミニバッファーコマンドを参照)のような補完コマンドを呼び出すと、Emacsはcompletion-stylesに最初にリストされたスタイルを探して、そのスタイルのtry-completion関数を呼び出す。この関数がnilをリターンしたら、Emacsは次にリストされた補完スタイルに移動してそのスタイルのtry-completion関数を呼び出すといったように、try-completion関数の1つが補完の処理に成功して非nil値をリターンするまで順次これを行なう。同様の手順はall-completions関数を通じて補完のリストにも行われる。

利用できる補完スタイルについてはCompletion Styles in The GNU Emacs Manualを参照のこと。

User Option: completion-category-overrides

この変数は特別な補完スタイルと、特定の種類のテキスト補完時に使用するその他の補完動作を指定する。この変数の値は(category . alist)という形式の要素をもつようなalistである。categoryは何が補完されるかを記述するシンボルで、現在のところカテゴリーにbufferfileunicode-nameが定義されているが、これに特化した補完関数(プログラムされた補完を参照)を通じて他のカテゴリーを定義できる。alistはそのカテゴリーにたいして補完がどのように振る舞うべきかを記述する連想リスト。alistのキーとして以下がサポートされる:

styles

値は補完スタイル(シンボル)のリスト。

cycle

値はそのカテゴリーにたいするcompletion-cycle-threshold (Completion Options in The GNU Emacs Manualを参照)の値。

将来、さらにalistエントリーが定義されるかもしれない。

Variable: completion-extra-properties

この変数はカレント補完コマンドの特別なプロパティの指定に使用される。この変数は補完に特化したコマンドによりletバインドされることを意図している。値はプロパティ/値ペアーのリスト。以下のプロパティがサポートされる:

:annotation-function

値は補完バッファー内に注釈(annotation)を加える関数。この関数は引数completionを1つ受け取りnil、または補完の隣に表示する文字列をリターンしなければならない。この関数が自身で注釈サフィックス文字列にフェイスをputしなければ、その文字列にはデフォルトでcompletions-annotationsフェイスが追加される。

:affixation-function

値は補完にプレフィックスとサフィックスを追加する関数であること。この関数は単一の引数として補完リストを受け取り、注釈付きの補完リストをリターンすること。リターンされるリストは補完、プレフィックス文字列、サフィックス文字列の3要素からなるリストを要素とするリストでなければならない。この関数は:annotation-functionより優先される。

:exit-function

値は補完を行った後に実行する関数。この関数は2つの引数stringstatusを受け取る。stringは補完されたフィールドのテキストで、statusは行われた操作の種類を示す。操作の種類はテキストの補完が完了したならfinished、それ以上補完できないが補完が完了していなければsole、有効な補完だがさらに補完できるときはexactとなる。


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

21.6.7 プログラムされた補完

意図した利用可能な補完のすべてを含むalistかobarrayを事前に作成するのが不可能または不便なことがあります。このような場合は与えられた文字列にたいする補完を計算するために独自の関数を提供できます。これはプログラム補完(programmed completion)と呼ばれます。Emacsは数あるケースの中でも特にファイル名の補完(ファイル名の補完を参照)でプログラム補完を使用しています。

この機能を使用するためには、関数をcompleting-readcollection引数として渡します。関数completing-readはその補完関数がtry-completionall-completionsなどの基本的な補完関数に渡されて、その関数がすべてを行えるよう取り計らいます。

補完関数は3つの引数を受け取ります:

  • 補完される文字列。
  • 利用可能なマッチをフィルターする述語関数。もしなければnil。関数は利用可能なマッチにたいしてこの述語(predicate)を呼び出して、述語がnilをリターンしたらそのマッチを無視する。
  • 実行する補完操作のタイプを指定するフラグ。基本的な補完関数を参照のこと。以下の値のうちいずれか1つを指定する:
    nil

    これはtry-completionを指定する。マッチがなければ関数はnilをリターンすること。指定された文字列が一意でかつ正確にマッチしたらtをリターンすること。それ以外ならすべてのマッチに共通な最長の前置部分文字列をリターンすること。

    t

    all-completionsを指定する。関数は指定された文字列の利用可能なすべての補完のリストをリターンする。

    lambda

    test-completionを指定する。関数は指定された文字列がいくつかの補完候補に完全一致するならt、それ以外はnilをリターンする。

    (boundaries . suffix)

    completion-boundariesを指定する。関数は(boundaries start . end)をリターンする。ここでstartは指定された文字列内の境界の開始位置、endsuffix内の境界の終了位置。

    Lispプログラムが些細とは言えない境界をリターンする場合には、それらとall-completions操作との整合を確認すること。all-completionsがリターンする補完は、補完境界がカバーするプレフィックスとサフィックスだけに関係していること。補完境界に期待される正確なセマンティックスについては基本的な補完関数を参照のこと。

    metadata

    カレント補完の状態に関する情報の要求を指定する。リターン値は(metadata . alist)の形式をもち、alistは以下で説明する要素をもつ連想リスト。

    フラグに他の値が指定されたら、補完関数はnilをリターンする。

以下はmetadataフラグ引数への応答として補完関数がリターンするかもしれないmetadataエントリーのリストです:

category

値は補完関数が補完を試みているテキストの種類を説明するシンボル。シンボルがcompletion-category-overrides内のキーの1つにマッチする場合、通常の補完動作はオーバーライドされる。補完変数を参照のこと。

annotation-function

値は補完に注釈(annotation)を付ける関数。この関数は1つの引数stringを受け取り、これは利用可能な補完である。リターン値は文字列で、*Completions*バッファー内の補完stringの後に表示される。この関数が自身で注釈サフィックス文字列にフェイスをputしなければ、その文字列にはデフォルトでcompletions-annotationsフェイスが追加される。

affixation-function

値は補完にプレフィックスとサフィックスを追加する関数であること。この関数は単一の引数としてcompletions (可能な補完のリスト)を受け取り、それぞれの要素が3要素(補完、*Completions*バッファーにおいて補完文字列の前に表示するプレフィックス、補完文字列の後に表示するサフィックス)のリストであるようなcompletionsリストをリターンすること。この関数はannotation-functionより優先される。

group-function

値は補完候補をグループ化するための関数であること。この関数はcompletion (補完候補)、transform (ブーリーンフラグ)という2つの引数を受け取らなければならない。transformnilなら、その関数は補完候補が属するグループのグループタイトルをリターンしなければならない。リターンされるタイトルはnilでもよい。それ以外なら、その関数は変換された候補をリターンしなければならない。この変換はたとえば、グループタイトルに表示される冗長なプレフィックスの削除などが考えられる。

display-sort-function

値は補完をソートする関数。関数は1つの引数をとる。これは補完文字列のリストで、ソートされた補完文字列リストがリターンされる。その入力のリストは破壊的に変更することが許容される。

cycle-sort-function

値はcompletion-cycle-thresholdが非nil、かつユーザーが補完候補を巡回するときに補完をソートする関数。引数のリストとリターン値はdisplay-sort-functionと同様。

Function: completion-table-dynamic function &optional switch-buffer

この関数はプログラムされた補完関数として動作可能な関数を記述する便利な方法である。引数functionは1つの引数(文字列)をとる関数であり、利用可能な補完すべてを含む補完テーブル(基本的な補完関数を参照)をリターンする。functionがリターンするテーブルには文字列引数にマッチしない要素を含めることもできる。これらはcompletion-table-dynamicによって自動的にフィルターされる。特にfunctionは引数を無視して利用可能なすべての補完の完全なリストをリターンできる。completion-table-dynamicfunctionとプログラムされた補完関数との間の変換器として考えることができる。

オプション引数switch-bufferが非nil、かつ補完がミニバッファーで行われた場合、functionはそのミニバッファーにエンターしたときのバッファーをカレントバッファーにセットして呼び出される。

completion-table-dynamicのリターン値はtry-completionおよびall-completionsの2つ目の引数として使用できる。この関数は常に空のメタデータと無意味な境界をリターンすることに注意。

Function: completion-table-with-cache function &optional ignore-case

これは前回の引数/結果ペアーを保存するcompletion-table-dynamicにたいするラッパーである。これは同じ引数にたいする複数回の検査に必要なのが、1回のfunction呼び出しだけであることを意味する。これは外部プロセス呼び出しなど、処理が低速のとき有用かもしれない。


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

21.6.8 通常バッファーでの補完

補完は通常はミニバッファー内で行われますが、補完機能は通常のEmacsバッファー内のテキストにも使用できます。多くのメジャーモードで、コマンドC-M-iまたはM-TABによってバッファー内補完が行われ、それらはcompletion-at-pointにバインドされています。Symbol Completion in The GNU Emacs Manualを参照してください。このコマンドはアブノーマルフック変数completion-at-point-functionsを使用します:

Variable: completion-at-point-functions

このアブノーマルフックの値は関数のリスト。これらの関数はポイント位置のテキストの補完にたいする補完テーブルの計算に使用される(基本的な補完関数を参照)。これはメジャーモードによるモード固有の補完テーブル(メジャーモードの慣習を参照)の提供に使用できる。

コマンドcompletion-at-pointが実行されると引数なしでリスト内の関数が1つずつ呼び出される。それぞれの関数はポイント位置のテキストにたいして補完テーブルを生成でき、かつそれに責任を負いたいのでなければnilをリターンすること。それ以外なら以下の形式のリストをリターンすること:

(start end collection . props)

ここでstartendは補完する(ポイントを取り囲む)テキストの区切りである。collectionはそのテキストを補完する補完テーブルであり、try-completion (基本的な補完関数を参照)の2つ目の引数として渡すのに適した形式である。補完候補はcompletion-styles (補完変数を参照)で定義された補完スタイルを通じて、この補完テーブルを通常の方法で使用して生成されるだろう。propsは追加の情報のためのプロパティリストである。completion-extra-properties内のすべてのプロパティ(補完変数を参照)と、以下の追加のプロパティが認識される:

:predicate

値は補完候補が満足する必要がある述語。

:exclusive

値がnoの場合は、もし補完テーブルがポイント位置のテキストのマッチに失敗したなら、補完の失敗を報告するかわりにcompletion-at-pointcompletion-at-point-functions内の次の関数へ移動する。

このフック上の関数は(たとえばpost-command-hookから)頻繁に呼び出され得るので一般的には素早くリターンすること。補完リストの生成が高価な処理ならcollectionにたいする関数の提供を強く推奨する。Emacsはcompletion-at-point-functions内の関数を頻繁に呼び出すかもしれないが、それらの呼び出しのいくつかにたいしてのみcollectionの値を考慮する。collectionにたいして関数を提供することによりEmacsは必要になるまで補完の生成を遅延できる。ラッパー関数を作成するためにcompletion-table-dynamicを使用できる:

;; このパターンは避けて
(let ((beg ...) (end ...) (my-completions (my-make-completions)))
  (list beg end my-completions))

;; かわりに以下を使用する
(let ((beg ...) (end ...))
  (list beg
        end
        (completion-table-dynamic
          (lambda (_)
            (my-make-completions)))))

さらに一般的にはcollectionstartendの間のカレントのテキストにもとづいて事前にフィルターされるべきではない。なぜなら使用を判断した補完スタイルに応じてこれを行うのはcompletion-at-point-functionsの呼び出し側の責任だからである。

completion-at-point-functions内の関数も上述のリストのかわりに関数をリターンするかもしれない。その場合には引数なしでリターンされた関数が呼び出されて、その関数が補完処理の全責任を負う。この方法は推奨されない。これはcompletion-at-pointを使用する古いコードの救済だけを意図したものだからである。

nil値を最初にリターンしたcompletion-at-point-functions内の関数が、completion-at-pointによって使用される。残りの関数は呼び出されない。例外は上述の:exclusive指定があるとき。

以下の関数はEmacsバッファー内の任意に拡張されたテキストにたいして便利な補完方法を提供します:

Function: completion-in-region start end collection &optional predicate

この関数はcollectionを使用してカレントバッファー内の位置startendの間のテキストを補完する。引数collectiontry-completion (基本的な補完関数を参照)のときと同じ意味をもつ。

この関数は補完テキストを直接カレントバッファーに挿入する。completing-read (補完とミニバッファーを参照)とは異なり、ミニバッファーをアクティブにしない。

この関数が機能するためには、ポイントがstartendの間になければならない。


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

21.7 Yes-or-Noによる問い合わせ

このセクションではユーザーにyes-or-noの確認を求める関数を説明します。関数y-or-n-pは1文字での応答に使用できます。この関数は不注意による誤った答えが深刻な結果を招かない場合に有用です。yes-or-no-pは3文字から4文字の答えを要求するので、より重大な問いに適しています。

マウスやその他ウィンドウシステムのジェスチャーを使って呼び出されたコマンド、あるいはメニュー経由で呼び出されたコマンドからこれらの関数のいずれかが呼び出されると、ダイアログボックスがサポートされていればダイアログボックスかポップアップメニューを使って質問にたいする答えを求めます。それ以外の場合にはキーボード入力を使用します。呼び出しの前後でlast-nonmenu-eventに適切な値をバインドすることによってマウス、あるいはキーボード入力のいずれかの使用を強制できます。tならキーボードによる対話、リストにバインドすればダイアログボックスの使用が強制されます。

yes-or-no-py-or-n-pはどちらもミニバッファーを使用します。

Function: y-or-n-p prompt

この関数はユーザーに答えを尋ねてミニバッファーに入力を求める。ユーザーがyをタイプしたらtnをタイプしたらnilをリターンする。この関数はyesの意味でSPC、noの意味でDELも受け入れる。quitとしてC-gC-]も受け入れる。これは問いがミニバッファーを使用して、かつミニバッファーを抜けるためにユーザーがC-]の使用を試みるかもしれないということが理由。応答は1文字であり、問いを終了させるためのRETは必要ない。大文字と小文字は等価である。

“答えを尋ねる”とはミニバッファーにprompt、その後に文字列‘(y or n) をプリントすることを意味する。期待される答え(ynSPCDEL、もしくは質問を終了するその他のキー)以外が入力されると、この関数は‘Please answer y or n.’と応答して繰り返し答えの入力を要求する。

この関数は実際にはミニバッファーを使用するが答えの編集を許容しない。答えを求めているる間、カーソルはモイニバッファーに移動される。

答えとその意味は、たとえ‘y’と‘n’であっても固定されたものではなく、キーマップquery-replace-mapによって指定される(検索と置換を参照)。特にユーザーがrecenterscroll-upscroll-downscroll-other-windowscroll-other-window-down(それぞれquery-replace-map内でC-lC-vM-vC-M-vC-M-S-vにバインドされている)のような特殊な応答をエンターした場合、この関数はは指定されたウィンドウの再センタリングやスクロール操作を処理してから再度答えを求める。

y-or-n-pの呼び出し中にhelp-form (ヘルプ関数を参照)を非nil値にバインドすると、help-charの押下によりhelp-formを評価して結果を表示する。help-charpromptに自動的に追加される。

Function: y-or-n-p-with-timeout prompt seconds default

y-or-n-pと同様だがユーザーがseconds秒以内に答えないと、この関数は待つのをやめてdefaultをリターンする。これはタイマーをセットアップすることによって機能する。引数secondsは数字である。

Function: yes-or-no-p prompt

この関数は質問してミニバッファーに答えの入力を求める。これはユーザーが‘yes’をエンターするとt、‘no’をエンターするとnilをリターンする。ユーザーは応答を終えるためにRETをタイプしなければならない。大文字と小文字は等価。

yes-or-no-pはミニバッファーにpromptとその後に‘(yes or no) を表示することによって開始される。ユーザーは期待される応答の1つをタイプしなければならない。それ以外の答えなら、この関数は‘Please answer yes or no.’と応答して約2秒待った後に要求を繰り返す。

yes-or-no-py-or-n-pより多くの作業をユーザーに要求するので、より重大な決定に適している。

以下は例:

(yes-or-no-p "Do you really want to remove everything? ")

;; 前の式を評価した後、
;;   空のミニバッファーに
;;   以下のプロンプトが表示される:

---------- Buffer: minibuffer ----------
Do you really want to remove everything? (yes or no)
---------- Buffer: minibuffer ----------

ユーザーが最初にy RETとタイプしたら無効になる。なぜならこの関数は‘yes’という単語全体を要求しているので、一時停止して以下のプロンプトを説明のために表示する。

---------- Buffer: minibuffer ----------
Please answer yes or no.
Do you really want to remove everything? (yes or no)
---------- Buffer: minibuffer ----------

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

21.8 複数の問いを尋ねる

このセクションではより複雑な質問や複数の似かよった質問をユーザーに尋ねる機能を説明します。

同じような連続する質問と答えがある場合、たとえば各バッファーにたいして順に“Do you want to save this buffer?”と確認を求めるような場合には、個別に質問するよりmap-y-or-n-pを使用して質問のコレクションを尋ねるべきです。これはユーザーにたいして、質問全体にたいして1回で答えられるような便利な機能を提供します。

Function: map-y-or-n-p prompter actor list &optional help action-alist no-cursor-in-echo-area

この関数はユーザーに一連の質問をし、それぞれの質問にたいしてエコーエリア内の1文字の答えを読み取る。

listは質問をするオブジェクトを指定する。これはリスト、オブジェクト、または生成関数(generator function)のいずれかである。関数なら引数なしで呼び出されて次に質問するオブジェクト、または質問の中止を意味するnilのいずれかをリターンすること。

引数prompterは各質問について問い合わせ方法を指定する。prompterが文字列なら質問テキストは以下のようになる:

(format prompter object)

ここでobjectは、(listから得られる)質問する次のオブジェクトである。formatについての詳細は文字列のフォーマットを参照のこと。

prompterが文字列でなければ、1つの引数(質問する次のオブジェクト)をとる関数であり、そのオブジェクトにたいする質問テキストをリターンすること。値が文字列ならユーザーに問う質問であること。関数はt(ユーザーに尋ねずこのオブジェクトを処理する)、またはnil(ユーザーに尋ねずこのオブジェクトを無視する)をリターンすることもできる。

引数actorはユーザーがyesと答えにたいして、どのように作処理するかを指定する。これはlistから取得したそれぞれのオブジェクトであるを単一の引数として呼び出される関数であること。

引数helpが与えられたら、それは以下の形式のリストである:

(singular plural action)

singularは処理するオブジェクトを説明する単数形の名詞を含む文字列、pluralはそれに対応する複数形の名詞、actionactorがオブジェクトに何を行うかを説明する他動詞である。

helpを指定しない場合のリストのデフォルトは("object" "objects" "act on")

尋ねられる質問ごとにユーザーは以下のように答えることができる:

yY、またはSPC

そのオブジェクトを処理する

nN、またはDEL

そのオブジェクトをスキップ

!

以降のオブジェクトをすべて処理する

ESCq

exit(以降のオブジェクトすべてをスキップ)する

. (ピリオド)

そのオブジェクトを処理してからexitする

C-h

ヘルプを表示する

これらはquery-replaceが受け入れる応答と同じである。キーマップquery-replace-mapmap-y-or-n-pquery-replaceにたいして、これらの応答の意味を定義する。検索と置換を参照のこと。

action-alistを使用して、利用できる追加の答えとそれらが何を意味するかを指定できる。action-alistが与えられた場合には、要素が(char function help)という形式のalistであること。alistの要素はそれぞれ追加の答えを1つ定義する。各要素のcharは文字(応答)、functionは単一の引数( listのオブジェクト)、helpは文字列。ユーザーがcharで応答した際には、map-y-or-n-pfunctionを呼び出す。非nilをリターンすると、オブジェクトを処理対象とみなして、map-y-or-n-plistの次オブジェクトに処理を進める。nilをリターンした場合には、同じオブジェクトにたいして繰り返し入力を求める。ユーザーがヘルプを要求した場合には、これらの追加質問を説明するためにhelpのテキストを使用する。

確認を求める間、map-y-or-n-pは通常はcursor-in-echo-areaをバインドする。しかしno-cursor-in-echo-areaが非nilならバインドしない。

マウスやその他ウィンドウシステムのジェスチャー、あるいはメニュー経由で呼び出されたコマンドからmap-y-or-n-pが呼び出された場合には、ダイアログボックスがサポートされていれば質問の答えを求めるためにダイアログボックスかポップアップメニューが使用される。この場合にはキーボード入力やエコーエリアは使用されない。呼び出しの前後でlast-nonmenu-eventを適切な値にバインドすることによって、マウスあるいはキーボード入力を強制できる。tならキーボードによる対話、リストにバインドすればダイアログボックスの使用が強制される。

map-y-or-n-pのリターン値は処理したオブジェクトの個数である。

3つ以上の答えをもつかもしれない質問をユーザーに尋ねる必要がある場合にはread-answerを使用してください。

Function: read-answer question answers

この関数はquestionのテキスト( ‘SPC’文字で終端されていること)とともにユーザーに入力を求める。この関数はquestionanswersを追加することにより、プロンプト内に可能な応答を含めることができる。この可能な応答は以下の形式の要素をもつalistとしてanswers内に提供される。

(long-answer short-answer help-message)

long-answerはユーザーの応答の完全なテキスト(文字列)、short-answerは同じ応答の短い形式(単一文字かファンクションキー)、help-messageはその応答の意味を説明するテキスト。変数read-answer-shortが非nilなら可能な応答の短いバージョンをプロンプトに表示して、ユーザーがプロンプトに表示された1文字をタイプすることを期待する。それ以外なら可能な応答の長いバージョンをプロンプトに表示して、ユーザーにはプロンプトに表示された完全なテキストのいずれかを入力してから、入力完了でRETを押下することが期待される。RETが非nilかつこの関数がマウスイベントから呼び出された場合には問いと答えはGUIのダイアログボックス内に表示される。

この関数はプロンプトに表示された応答の長短やユーザーがタイプした応答とは無関係に、ユーザーがセンタクしたlong-answerのテキストをリターンする。

以下はこの関数の使用例:

(let ((read-answer-short t))
  (read-answer "Foo "
     '(("yes"  ?y "perform the action")
       ("no"   ?n "skip to the next")
       ("all"  ?! "perform for the rest without more questions")
       ("help" ?h "show help")
       ("quit" ?q "exit"))))
Function: read-char-from-minibuffer prompt &optional chars history

この関数はミニバッファーを使用して単一文字を読み取りリターンする。オプションで許容する文字のリストchars以外のメンバーはすべて無視する。history引数は使用するヒストリーリストシンボルを指定する。これが省略かnilなら、この関数はヒストリーを使用しない。

read-char-from-minibufferの呼び出し中にhelp-form (ヘルプ関数を参照)を非nil値にバインドすると、help-charの押下によりhelp-formを評価して結果を表示する。


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

21.9 パスワードの読み取り

他のプログラムに渡すためのパスワードを読み取るために関数read-passwdを使用できます。

Function: read-passwd prompt &optional confirm default

この関数はプロンプトpromptを表示してパスワードを読み取る。これはユーザーがタイプしたパスワードのかわりに、パスワード内の各文字を‘*’に変更してエコーする。パスワードを隠すために別の文字を適用したければ、その文字をread-hide-charにletバインドすること。

オプション引数confirmが非nilなら、パスワードを2回読み取ることでそれらが同じものであることを強制する。同じでなければ、2回の入力が同じになるまで、ユーザーはパスワードを繰り返しタイプする必要がある。

オプション引数defaultは、ユーザーが空入力をエンターした場合のデフォルトパスワードである。defaultnilなら、read-passwdはnull文字列をリターンする。


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

21.10 ミニバッファーのコマンド

このセクションではミニバッファー内で使用するコマンドを説明します。

Command: exit-minibuffer

このコマンドはアクティブなミニバッファーをexitする。これは通常はミニバッファー内のローカルキーマップのキーにバインドされる。カレントバッファーがミニバッファーだがアクティブミニバッファーでなければ、このコマンドはエラーをthrowする。

Command: self-insert-and-exit

このコマンドはキーボードでタイプされた最後の文字を挿入した後にアクティブなミニバッファーをexitする。コマンドループからの情報)を参照のこと。

Command: previous-history-element n

このコマンドはn個前(古い)のヒストリー要素の値でミニバッファー内のコンテンツを置換する。

Command: next-history-element n

このコマンドはミニバッファー内のポイントの前のカレントコンテンツを、n個分のより最近のヒストリー要素の値で置換する。現在位置を超えたヒストリー内の位置への移動も可能であり、それは“未来のヒストリー(future history)”を呼び出す(ミニバッファーでのテキスト文字列の読み取りを参照)。

Command: previous-matching-history-element pattern n

このコマンドはpattern(正規表現)にマッチするn個前(古い)のヒストリー要素でミニバッファー内のコンテンツを置換する。

Command: next-matching-history-element pattern n

このコマンドはpattern(正規表現)にマッチするn個先(新しい)のヒストリー要素でミニバッファー内のコンテンツを置換する。

Command: previous-complete-history-element n

このコマンドはミニバッファー内のポイントの前のカレントコンテンツを、n個前(古い)ヒストリー要素の値で置換する。

Command: next-complete-history-element n

このコマンドはミニバッファー内のポイントの前のカレントコンテンツを、n個先(新しい)ヒストリー要素の値で置換する。

Command: goto-history-element nabs

この関数はミニバッファーにミニバッファーヒストリーの要素を配置する。引数nabsは絶対ヒストリー位置(absolute history position)を降順で指定する。0ならカレント要素、正の数nn個前の要素を意味する。負の数-nn番目の“未来のヒストリー”を意味する。この関数はread-from-minibuffer (ミニバッファーでのテキスト文字列の読み取りを参照)およびcompleting-read (補完とミニバッファーを参照)によって提供されるデフォルト値の終端に達すると、補完候補を“未来のヒストリー”に追加する。minibuffer-default-add-functionを参照のこと。


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

21.11 ミニバッファーのウィンドウ

以下の関数はミニバッファーウィンドウにアクセスと選択を行い、それがアクティブかどうかテストしてリサイズされる方法を制御します。

Function: minibuffer-window &optional frame

この関数はフレームframeにたいして使用されるミニバッファーウィンドウをリターンする。framenilならそれは選択されたフレームを意味する。

フレームが使用するミニバッファーウィンドウがフレームの一部である必要はないことに注意(ミニバッファーをもたないフレームは必要に応じて別のフレームのミニバッファーウィンドウを使用する)。ミニバッファーのないフレームのミニバッファーウィンドウは、そのフレームのminibufferフレームパラメーターをセットすることにより変更できる(バッファーのパラメーターを参照)。

Function: set-minibuffer-window window

この関数はミニバッファーウィンドウとしてwindowを使用するよう指定する。これは通常のミニバッファーコマンドを呼び出さずにミニバッファーにテキストを入力する場合には、ミニバッファーをどこに表示するかに影響を及ぼす。通常のミニバッファー入力関数はすべて選択されたフレームに対応するミニバッファーを選択して開始されるので影響はない。

Function: window-minibuffer-p &optional window

この関数はwindowがミニバッファーウィンドウならtをリターンする。windowのデフォルトは選択されたウィンドウ。

以下の関数はカレントでアクティブなミニバッファーを表示しているウィンドウをリターンします。

Function: active-minibuffer-window

この関数はカレントでアクティブなミニバッファーのウィンドウ、アクティブなミニバッファーがなければnilをリターンする。

(minibuffer-window)の結果の比較だけでは、与えられたウィンドウがカレントでアクティブなミニバッファーを表示するかどうかを判断するのは不十分である。なぜなら複数のフレームがある場合にはミニバッファーウィンドウも複数あり得る。

Function: minibuffer-window-active-p window

この関数はwindowがカレントでアクティブなミニバッファーを表示するウィンドウなら非nilをリターンする。

以下の2つのオプションはミニバッファーウィンドウが自動的にリサイズされるか否か、およびその処理でミニバッファーが大きくなり得るサイズを制御します。

User Option: resize-mini-windows

このオプションはミニバッファーウィンドウが自動的にリサイズされるかどうかを指定する。デフォルト値はgrow-onlyで、これはミニバッファーが表示するテキストを収容するために、ミニバッファーウィンドウがデフォルトにより自動的に拡張されて、ミニバッファーが空になれば即座に1行に縮小されることを意味する。値がtならEmacsは常にミニバッファーが表示するテキストにミニバッファーウィンドウの高さをフィットさせるように試みる。値がnilならミニバッファーウィンドウのサイズが自動的に変更されることは決してない。この場合には、ミニバッファーウィンドウの高さの調節のために、ウィンドウリサイズコマンドを使用できる(ウィンドウのリサイズを参照)。

User Option: max-mini-window-height

このオプションはミニバッファーウィンドウの自動的なリサイズにたいする最大高さを提供する。浮動小数点数はフレーム高さにたいする割合として最大高さを指定する。整数はフレームの正規文字高さの単位で最大高さを指定する(フレームのフォントを参照)。デフォルト値は0.25。

上記の2つの変数の値は表示時に効果を発揮するので、エコーエリアのメッセージを生成するコードの前後でこれらの変数をletバインドしても機能しないことに注意してください。長いメッセージを表示する際にミニバッファーウィンドウのリサイズを抑止したければ、かわりにmessage-truncate-lines変数をバインドしてください(エコーエリアのカスタマイズを参照)。

オプションresize-mini-windowsはミニバッファーのみのフレームの振る舞いには影響を与えません(フレームのレイアウトを参照)。以下のオプションによりそのようなフレームも同じように自動的にリサイズすることが可能になります。

User Option: resize-mini-frames

これがnilならミニバッファーのみのフレームは決して自動的にリサイズされない。

これが関数なら、その関数はリサイズするミニバッファーのみフレームを単一の引数として呼び出される。この関数が呼び出されるときは、そのフレームのミニバッファーウィンドウのバッファーは、そのウィンドウの次回再表示時にコンテンツが表示されるバッファーである。この関数には何らかの適切な方法によりフレームをバッファーにフィットさせることが期待される。

それ以外の非nil値はfit-mini-frame-to-bufferを呼び出すことによりミニバッファーのみのフレームをリサイズすることを意味する。この関数はfit-frame-to-bufferと似ているが、バッファーテキストから先頭や末尾の空行を取り除かない(ウィンドウのリサイズを参照)。


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

21.12 ミニバッファーのコンテンツ

以下の関数はミニバッファーのプロンプトとコンテンツにアクセスします。

Function: minibuffer-prompt

この関数はカレントでアクティブなミニバッファーのプロンプト文字列をリターンする。アクティブなミニバッファーがなければnilをリターンする。

Function: minibuffer-prompt-end

この関数はミニバッファーがカレントならミニバッファープロンプトの終端のカレント位置をリターンする。それ以外はバッファーの有効な最小位置をリターンする。

Function: minibuffer-prompt-width

この関数はミニバッファーがカレントならミニバッファープロンプトのカレントの表示幅をリターンする。それ以外は0をリターンする。

Function: minibuffer-contents

この関数はミニバッファーがカレントなら、ミニバッファーの編集可能なコンテンツ(つまりプロンプト以外のすべて)を文字列でリターンする。それ以外はカレントバッファーのコンテンツ全体をリターンする。

Function: minibuffer-contents-no-properties

これはminibuffer-contentsと同様だが、テキストプロパティをコピーせずに文字自身だけをリターンする。テキストのプロパティを参照のこと。

Command: delete-minibuffer-contents

このコマンドはミニバッファーがカレントなら、ミニバッファーの編集可能なコンテンツ(つまりプロンプト以外のすべて)を削除する。それ以外はカレントバッファー全体を削除する。


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

21.13 再帰的なミニバッファー

以下の関数と変数は再帰ミニバッファーを処理します(再帰編集を参照):

Function: minibuffer-depth

この関数はアクティブなミニバッファーのカレント再帰深さを正の整数でリターンする。アクティブなミニバッファーが存在しなければ0をリターンする。

User Option: enable-recursive-minibuffers

この変数が非nilならミニバッファーがアクティブでも、(find-fileのような)ミニバッファーを使用するコマンドを呼び出すことができる。このような呼び出しは新たなミニバッファーにたいして再帰編集レベル(recursive editing level)を生成する。内側レベルの編集中は、デフォルトでは、外側レベルのミニバッファーは非表示になる。minibuffer-follows-selected-framenilをセットしていれば、複数フレームで同時にミニバッファーを可視にできる。(emacs)Basic Minibufferを参照のこと。

この変数がnilならミニバッファーがアクティブなときは、たとえ他のウィンドウに切り替えてもミニバッファーコマンドの呼び出しはできない。

コマンド名が非nilのプロパティenable-recursive-minibuffersをもつ場合には、たとえミニバッファーから呼び出された場合でも、そのコマンドは引数の読み取りにミニバッファーを使用できる。コマンドのinteractive宣言内でenable-recursive-minibufferstにしても、これを行うことができる(interactiveの使用を参照)。ミニバッファーコマンドnext-matching-history-element (ミニバッファー内では通常M-s)は後者を行う。


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

21.14 対話の抑止

ネットワーク越しに与えたコマンドに応答するヘッドレスサーバープロセスとしてEmacsを実行できると便利な場合があります。とはいえEmacsは主として対話的に使用するためのプラットフォームなので、特定の例外的な状況ではユーザーに入力を求めるコマンドが沢山あります。ユーザー入力の待機によりサーバーは単にハングしてしまうでしょうから、この使用方法はより困難になります。

inhibit-interactionnil以外の何らかにバインドすることによって、Emacsに入力を求めさせるのではなく、そのような状況をサーバーが処理するために使用可能なinhibited-interactionエラーをシグナルさせることができます。

以下は典型的な使用例です:

(let ((inhibit-interaction t))
  (respond-to-client
   (condition-case err
       (my-client-handling-function)
     (inhibited-interaction err))))

(y-or-n-pread-from-minibuffer等を通じて)ユーザーに入力を求める何かをmy-client-handling-functionが呼び出すことになると、かわりにinhibited-interactionエラーをシグナルします。それからサーバーコードはそのエラーをcatchしてクライアントに報告します。


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

21.15 ミニバッファー、その他の事項

Function: minibufferp &optional buffer-or-name live

この関数はbuffer-or-nameがミニバッファーなら非nilをリターンする。buffer-or-namenilか省略なら、カレントバッファーをテストする。liveが非nilなら、この関数はbuffer-or-nameがアクティブミニバッファーのときだけ非nilをリターンする。

Variable: minibuffer-setup-hook

これはミニバッファーがエンターされたときは常に実行されるノーマルフックである。フックを参照のこと。

Macro: minibuffer-with-setup-hook function &rest body

このマクロは指定されたfunctionminibuffer-setup-hookを通じて呼び出されるように計らった後にbodyを実行する。デフォルトではfunctionminibuffer-setup-hookリストの他の関数の前に呼び出されるが、function(:append func)というフォームなら、funcは他のフック関数のに呼び出される。

bodyはミニバッファーを複数回使用しないこと。ミニバッファーが再帰的に再エンターされると、functionは最外のミニバッファーの使用にたいして1回だけ呼び出されるだろう。

Variable: minibuffer-exit-hook

これはミニバッファーがexitされたときは常に実行されるノーマルフックである。

Variable: minibuffer-help-form

この変数のカレント値はミニバッファー内でhelp-formをローカルにリバインドするために使用される(ヘルプ関数を参照)。

Variable: minibuffer-scroll-window

この変数の値が非nilなら、それはウィンドウオブジェクトである。ミニバッファー内で関数scroll-other-windowが呼び出されたときは、このウィンドウをスクロールする(テキスト的なスクロールを参照)。

Function: minibuffer-selected-window

この関数はミニバッファーウィンドウが選択される直前に選択されていたウィンドウをリターンする。選択されたウィンドウがミニバッファーウィンドウ以外ならnilをリターンする。

Function: minibuffer-message string &rest args

この関数はmessage (see エコーエリアへのメッセージの表示を参照)と似ているが、(典型的にはEmacsがユーザーに何らかの入力を求めたことによって)ユーザーがミニバッファー内でタイプする際にメッセージを特別な方法で表示する。ミニバッファーがカレントバッファーの際には、この関数はメッセージをエコーエリアに表示することによってミニバッファーのテキストが隠されることを避けるために、stringで指定されたメッセージを一時的にミニバッファーのテキストの終端に表示する。このメッセージは数秒経過するか、あるいは次の入力イベントが到達するまで表示される。

ミニバッファーがカレントバッファーでないときに呼び出されるとこの関数は単にmessageを呼び出すので、stringはエコーエリアに表示される。

Command: minibuffer-inactive-mode

これはインタラクティブなミニバッファー内で使用されるメジャーモードである。キーマップminibuffer-inactive-mode-mapを使用する。ミニバッファーが別のフレームにある場合には有用かもしれない。ミニバッファーとフレームを参照のこと。


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

22 コマンドループ

Emacsを実行すると、ほぼ即座にエディターコマンドループ(editor command loop)に移行します。このループはキーシーケンスを読み取り、それらの定義を実行して結果を表示します。このチャプターではこれらが行われる方法と、Lispプログラムがこれらを行えるようにするサブルーチンを説明します。


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

22.1 コマンドループの概要

コマンドループが最初に行わなければならないのはキーシーケンスの読み取りです。キーシーケンスはコマンドに変換される入力イベントのシーケンスです。これは関数read-key-sequenceを呼び出すことによって行われます。Lispプログラムもこの関数を呼び出すことができます(キーシーケンス入力を参照)。これらはより低レベルのread-keyread-event (単一イベントの読み取り)で入力を読み取ったり、discard-input (その他のイベント入力の機能を参照)で保留中の入力を無視することもできます。

キーシーケンスはカレントでアクティブなキーマップを通じてコマンドに変換されます。これが行われる方法についてはキーの照合を参照してください。結果はキーボードマクロかインタラクティブに呼び出し可能な関数になります。キーがM-xなら他のコマンドの名前を読み取って、それを呼び出します。これはコマンドexecute-extended-command (インタラクティブな呼び出しを参照)により行われます。

コマンドの実行に先立ち、Emacsはアンドゥ境界(undo boundary)を作成するためにundo-boundaryを実行します。アンドゥリストの保守を参照してください。

コマンドを実行するために、Emacsはまずcommand-executeを呼び出してコマンドの引数を読み取ります(インタラクティブな呼び出しを参照)。Lispで記述されたコマンドについては、interactive指定で引数を読み取る方法を指定します。これはプレフィクス引数(プレフィクスコマンド引数を参照)を使用したり、ミニバッファー内(ミニバッファーを参照)で確認を求めて読み取りを行うかもしれません。たとえばコマンドfind-fileにはinteractive指定があり、これはミニバッファーを使用してファイル名を読み取ることを指定します。find-fileの関数bodyはミニバッファーを使用しないので、Lispコードから関数としてfind-fileを呼び出す場合には、通常のLisp関数引数としてファイル名を文字列で与えなければなりません。

コマンドがキーボードマクロ(文字列やベクター)なら、Emacsはexecute-kbd-macroを使用してそれを実行します(キーボードマクロを参照)。

Variable: pre-command-hook

このノーマルフックはコマンドを実行する前に、エディターコマンドループにより実行される。その際、this-commandには実行しようとするコマンドが含まれ、last-commandには前のコマンドが記述される。コマンドループからの情報を参照のこと。

Variable: post-command-hook

このノーマルフックはコマンドを実行した後(quitやエラーにより早期に終了させられたコマンドを含む)に、エディターコマンドループにより実行される。その際、this-commandは正に実行されたコマンド、last-commandは前に実行されたコマンドを参照する。

このフックはEmacsが最初にコマンドループにエンターしたときにも実行される(その時点ではthis-commandlast-commandはいずれもnil)。

pre-command-hookpost-command-hookの実行中は、quitは抑制されます。これらのフックのいずれかを実行中にエラーが発生しても、そのエラーはフックの実行を終了させません。そのかわりにエラーは黙殺されて、エラーが発生した関数はそのフックから取り除かれます。

Emacsサーバー(Emacs Server in The GNU Emacs Manualを参照)に届くリクエストは、キーボードコマンドが行うのと同じように、これらの2つのフックを実行します。

バッファーのテキストに非常に長い行が含まれている場合には、これら2つのフックはあたかもポイント周辺の一部にナローイングされて、long-line-optimizations-in-command-hooksのラベルが付されたwith-restrictionフォーム(ナローイングを参照)の内部であるかのように呼び出されることに注意してください。


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

22.2 コマンドの定義

スペシャルフォームinteractiveはLisp関数をコマンドに変更します。interactiveフォームは関数bodyのトップレベルに置かなければならず、通常はbody内の最初のフォームとして記述されます。これはラムダ式(ラムダ式を参照)とdefun (関数の定義を参照)の両方を受け入れます。このフォームはその関数が実際に実行される間は何も行いません。このフォームの存在はフラグとしての役割りをもち、Emacsコマンドループにたいしてその関数がインタラクティブに呼び出せることを告げます。interactiveフォームの引数はインタラクティブな呼び出しが引数を読み取る方法を指定します。

interactiveフォームのかわりに、関数シンボルのinteractive-formプロパティで指定されることもあります。このプロパティが非nil値なら、関数body内のinteractiveフォームより優先されます。この機能はほとんど使用されません。

インタラクティブに呼び出されることだけを意図していて、決してLispから直接呼び出されない関数が時折あります。この場合には、直接あるいはdeclare (declareフォームを参照)を通じて、その関数のinteractive-onlyプロパティに非nilを与えます。これにより、そのコマンドがLispから呼び出されるとバイトコンパイラーが警告を発します。describe-functionの出力にはこれに類似する情報が含まれます。このプロパティの値には文字列、t、または任意のシンボルを指定できます。文字列なら、それはバイトコンパイラーによる警告内で直接使用されます(最初は大文字でなくピリオドで終端される文字列であること。たとえば"use (system-name) instead.")。シンボルなら、それはLispコード内で使用されるかわりの関数です。

ジェネリック関数(ジェネリック関数を参照)にinteractiveフォームを追加してコマンドにすることはできません。


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

22.2.1 interactiveの使用

このセクションでは、Lisp関数をインタラクティブに呼び出し可能なコマンドにするinteractiveフォームの記述方法と、コマンドのinteractiveフォームの検証方法について説明します。

Special Form: interactive &optional arg-descriptor &rest modes

このスペシャルフォームは関数がコマンドであり、したがって(M-xを通じて、またはそのコマンドにバインドされたキーシーケンスをエンターすることにより)インタラクティブに呼び出すことができることを宣言する。引数arg-descriptorは、そのコマンドがインタラクティブに呼び出されたときに引数を計算する方法を宣言する。

コマンドは他の関数と同じようにLisp関数から呼び出されるかもしれないが、その場合には呼び出し側は引数を提供して、arg-descriptorは効果をもたない。

interactiveフォームは関数body内のトップレベルに置くか、関数シンボルのinteractive-formプロパティ((シンボルのプロパティ)を参照)になければならない。これはコマンドループが関数を呼び出す前にinteractiveフォームを調べることにより効果をもつ(インタラクティブな呼び出しを参照)。一度関数が呼び出されると関数body内のすべてのフォームが実行される。このときbody内にinteractiveフォームが出現しても、そのフォームは引数の評価さえされず単にnilをリターンする。

modesリストではコマンドの使用を意図したモードを指定できる。modes指定の効果と使用するタイミングに関する詳細はコマンドにたいするモード指定を参照のこと。

慣例によりinteractiveフォームは関数body内の最初のトップレベルフォームとするべきである。interactiveフォームがシンボルのinteractive-formプロパティと関数bodyの両方に存在する場合には前者が優先される。interactive-formフォームは既存の関数にinteractiveフォームを追加したり、その関数を再定義することなく引数をインタラクティブに処理する方法を変更するために使用できる。

引数arg-descriptorは以下の3つの可能性があります:

  • 省略またはnilならコマンドは引数なしで呼び出される。コマンドが1つ以上の引数を要求する場合は即座にエラーとなる。
  • 文字列なら、その文字列の内容は改行で区切られた要素シーケンスであり、1つの要素が1つの引数に対応する16。各要素はコード文字(interactiveにたいするコード文字を参照)と、オプションでその後のプロンプト(コード文字として使用される文字やコード文字としては無視されるものもある)により構成される。以下は例である:
    (interactive "P\nbFrobnicate buffer: ")
    

    コード文字‘P’はそのコマンドの1つ目の引数をrawコマンドプレフィクス(プレフィクスコマンド引数を参照)にセットする。‘bFrobnicate buffer: ’は、ユーザーに‘Frobnicate buffer: ’のプロンプトを示して既存のバッファーの名前の入力を促し、これは2つ目かつ最後の引数になる。

    プロンプト文字列には、プロンプト内の前の引数(1つ目の引数から始まる)の値を含めるために‘%’を使用できる。これはformat-message (文字列のフォーマットを参照)を使用して行われる。たとえば以下は既存のバッファーの名前を読み取って、その後にそのバッファーに与える新たな名前を読み取る例である:

    (interactive "bBuffer to rename: \nsRename buffer %s to: ")
    

    文字列の先頭に‘*’がある場合、そのバッファーが読み取り専用ならエラーがシグナルされる。

    文字列の先頭が‘@’で、そのコマンドの呼び出しに使用されたキーシーケンスに何らかのマウスイベントが含まれる場合は、そのコマンドを実行する前に、それらのうち最初のイベントに結びつくウィンドウが選択される。

    文字列の先頭が‘^’で、そのコマンドがシフト転換(shift-translation)を通じて呼び出された場合は、そのコマンドを実行する前にマークをセットして一時的にリージョンをアクティブにするか、すでにアクティブなリージョンを拡張する。コマンドがシフト転換なしで呼び出されて、リージョンが一時的にアクティブな場合は、コマンドを実行する前にそのリージョンを非アクティブにする。シフト転換はshift-select-modeによりユーザーレベルで制御される。Shift Selection in The GNU Emacs Manualを参照のこと。

    *’、‘@’、^は一緒に使用でき、その場合は順序に意味はない。実際の引数の読み取りは残りのプロンプト文字列(‘*’、‘@’、^以外の最初の文字以降)により制御される。

  • 文字列以外のLisp式なら、そのコマンドに渡す引数リストを取得するために評価されるフォームである。このフォームは通常はユーザーから入力を読み取るためにさまざまな関数を呼び出し、そのためにほとんどの場合はミニバッファー(ミニバッファーを参照)を通じてか、キーボードから直接読み取りを行う(入力の読み取りを参照)。

    引数値としてポイントやマークを提供するのも一般的だが、何かを行いかつ(ミニバッファー使用の有無に関わらず)入力を読み取る場合には、読み取りの前にポイント値またはマーク値の整数を確実に取得しておくこと。カレントバッファーはサブプロセスの出力を受信するかもしれず、コマンドが入力を待つ間にサブプロセス出力が到着すると、ポイントやマークの再配置が起こり得る。

    以下は行ってはいけない例である:

    (interactive
     (list (region-beginning) (region-end)
           (read-string "Foo: " nil 'my-history)))
    

    これにたいして以下はキーボード入力を読み取った後にポイントとマークを調べることにより、上記の問題を避ける例である:

    (interactive
     (let ((string (read-string "Foo: " nil 'my-history)))
       (list (region-beginning) (region-end) string)))
    

    警告: 引数値にはプリントや読み取りが不可能なデータ型を含めないこと。いくつかの機能は後続のセッションに読み込ませるためにcommand-historyをファイルに保存する。コマンドの引数に‘#<…>’構文を使用してプリントされるデータ型が含まれていると、それらの機能は動作しなくなるだろう。

    しかしこれには少数の例外がある。(point)(mark)(region-beginning)(region-end)などの一連の式に限定して使用することに問題はない。なぜならEmacsはこれらを特別に認識して、コマンドヒストリー内に(値ではなく)その式を配置すからである。記述した式がこれらの例外に含まれるかどうか確認するには、コマンドを実行した後に(car command-history)を調べればよい。

Function: interactive-form function

この関数はfunctioninteractiveフォームをリターンする。functionがインタラクティブに呼び出し可能な関数(インタラクティブな呼び出しを参照)なら、値はそのコマンドの引数を計算する方法を指定するinteractiveフォーム((interactive spec))である。それ以外なら値はnilfunctionがシンボルなら、そのシンボルの関数定義が使用される。OClosureで呼び出された場合には、処理はジェネリック関数oclosure-interactive-formに委譲される。

Function: oclosure-interactive-form function

この関数はinteractive-formと同様にコマンドを受け取り、そのインタラクティブなフォームをリターンする。これがジェネリック関数であること、そしてfunctionがOClosureのときだけ呼び出される点が異なる。この関数の目的は一部のOClosureタイプ(オープンクロージャを参照)にたいしてそれらのスロットの1つにインタラクティブフォームを格納するのではなく、動的なインタラクティブフォームの計算を可能にすることにある。

これはたとえばすべてのkmacroは同じインタラクティブフォームを共有するので、kmacroに用いることでメモリーサイズを削減できる。インタラクティブフォームが関数のコンポーネントのインタラクティブフォームから計算されるadvice関数においても、いずれかのコンポーネントが再定義された際の計算を更に遅延でき、かつインタラクティブフォームをより正確に調整できる。


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

22.2.2 interactiveにたいするコード文字

ここで説明されているコード文字には、以下で定義されるいくつかのキーワードが含まれています:

Completion

補完を提供する。TABSPCRETcompleting-read (補完を参照)を使用して引数を読み取って名前の補完を行う。?で利用可能な補完リストを表示する。

Existing

既存オブジェクトの名前を要求する。無効な名前は受け付けられない。カレント入力が有効でなければ、ミニバッファーをexitするコマンドはexitしない。

Default

ユーザーがテキストを何もエンターしなければ、ある種のデフォルト値が使用される。デフォルトはコード文字に依存する。

No I/O

このコード文字は入力を読み取らずに引数を計算する。したがってプロンプト文字列を使用せず、与えられたプロンプト文字列は無視される。

たとえそのコード文字がプロンプト文字列を使用しなくても、それが文字列内で最後のコード文字でなければ、その後に改行を付加しなければならない。

Prompt

コード文字の直後にプロンプトが続く。プロンプトの終端は文字列の終端、または改行。

Special

このコード文字はインタラクティブ文字列の先頭にあるときのみ意味があり、プロンプトと改行を要求しない。単一の独立した文字。

以下はinteractiveで使用されるコード文字です:

*

カレントバッファーが読み取り専用ならエラーをシグナルする。[Special]

@

このコマンドを呼び出したキーシーケンス内の最初のマウスイベントに関連するウィンドウを選択する。[Special]

^

シフト転換を通じてコマンドが呼び出された場合はコマンドを実行する前に、マークをセットして一時的にリージョンをアクティブにするか、すでにリージョンがアクティブならリージョンを拡張する。シフト転換を通じずにコマンドが呼び出されて、リージョンが一時的にアクティブならコマンドを実行する前にそのリージョンを非アクティブにする。[Special]

a

関数名(fboundpを満足するシンボル)。[Existing]、[Completion]、[Prompt]

b

既存バッファーの名前。デフォルトではカレントバッファー(バッファーを参照)の名前を使用する。[Existing]、[Completion]、[Default]、[Prompt]

B

バッファー名。そのバッファーが存在する必要はない。デフォルトではカレントバッファーではなくもっとも最近使用されたバッファーの名前を使用する。[Completion]、[Default]、[Prompt]

c

文字。カーソルはエコーエリアに移動しない。[Prompt]

C

コマンド名(commandpを満足するシンボル)。[Existing]、[Completion]、[Prompt]

d

ポイント位置の整数(ポイントを参照)。[No I/O]

D

ディレクトリー。デフォルトはカレントバッファーのカレントのデフォルトディレクトリーdefault-directory (ファイル名を展開する関数を参照)。[Existing]、[Completion]、[Default]、[Prompt]

e

そのコマンドを呼び出したキーシーケンス内の1つ目か2つ目の非キーボードイベント。より正確には、‘e’はリストとしてイベントを取得するので、リスト内のデータを調べることができる。入力イベントを参照のこと。[No I/O]

e’はマウスイベント、および特別なシステムイベント(その他のシステムイベントを参照)にたいして使用する。コマンドが受け取るイベントリストは、そのイベントに依存する。入力イベントではそれぞれのイベントのリスト形式を、対応するサブセクションでそれぞれ説明しているので参されたい。

1つのコマンドのinteractive仕様の中で‘e’を複数回使用できる。そのコマンドを呼び出したキーシーケンスがイベントn(リスト)をもつなら、‘e’のn番目がそのイベントを提供する。フンクションキーやASCII文字のようなリスト以外のイベントは、‘e’に関連するイベントとしてカウントされない。

f

既存ファイルのファイル名(ファイルの名前を参照)。デフォルト値の詳細についてはファイル名の読み取りを参照のこと。[Existing]、[Completion]、[Default]、[Prompt]

F

ファイル名。ファイルが存在している必要はない。[Completion]、[Default]、[Prompt]

G

ファイル名。ファイルが存在している必要はない。ユーザーがディレクトリー名だけをエンターしたら値はそのディレクトリー名となり、そのディレクトリー名にファイル名は追加されない。[Completion]、[Default]、[Prompt]

i

無関係な引数。このコード文字は引数値として常にnilを与える。[No I/O]

k

キーシーケンス(キーシーケンスを参照)。これはカレントキーマップ内でコマンド(または未定義のコマンド)が見つかるまで、イベントを読み取り続ける。キーシーケンス引数は文字列かベクターで表される。カーソルはエコーエリアに移動しない。[Prompt]

k’が(マウスの)down-eventで終わるキーシーケンスを読み取ると、後続の(マウスの)up-eventも読み取ってそれを廃棄する。コード文字‘U’によりup-eventへのアクセスを得られる。

この種の入力はdescribe-keykeymap-global-setのようなコマンドにより使用される。

K

keymap-setのような関数の入力として使用されるフォーム上のキーシーケンス。これは‘k’と同じように機能するが、キーシーケンス内の最後の入力イベントにたいして、通常は(必要なら)使用される未定義キーから定義済みキーへの変換(キーシーケンス入力を参照)を抑制する。そのためこのフォームは、通常はコマンドにバインドするために新たなキーシーケンスの入力を求める際に使用される。

m

マーク位置の整数。[No I/O]

M

任意のテキスト。ミニバッファー内でカレントバッファーの入力メソッド(Input Methods in The GNU Emacs Manualを参照)を使用して読み取りを行い、それを文字列でリターンする。[Prompt]

n

数字。ミニバッファーで読み取られる。入力が数字でなければユーザーは再試行する必要がある。‘n’は決してプレフィクス引数を使用しない。[Prompt]

N

数引数(numeric prefix argument)。ただしプレフィクス引数がなければnのように数字を読み取る。値は常に数字。プレフィクスコマンド引数を参照のこと。[Prompt]

p

数引数(小文字の‘p’であることに注意)。[No I/O]

P

rawプレフィクス引数(大文字の‘P’であることに注意)。[No I/O]

r

2つの数引数(ポイントとマーク)。小さいほうが先。これは1つではなく連続する2つの引数を指定する唯一のコード文字である。コマンド呼び出し時にカレントなバッファーにマークがセットされていなければエラーをシグナルする。Transient Markモード(マークを参照)がオン(デフォルト)かつユーザーオプションmark-even-if-inactivenilの場合には、たとえマークがセットされていても非アクティブならEmacsはエラーをシグナルする。[No I/O]

s

任意のテキスト。ミニバッファー内で読み取りを行って文字列としてリターンする(ミニバッファーでのテキスト文字列の読み取りを参照)。C-jRETで入力を終端する(これらの文字を入力に含めるためにC-qを使用できる)。[Prompt]

S

intern済みのシンボル。名前はミニバッファー内で読み取られる。C-jRETで入力を終端する。ここでは通常はシンボルを終端するその他の文字(たとえば空白文字、丸カッコ、角カッコ)では終端されない。[Prompt]

U

キーシーケンスかnil。‘k’(または‘K’)が読み取った後に、(もしあれば)捨てられる(マウスの)up-eventを取得するために、引数‘k’(または‘K’)の後で使用され得る。捨てられたup-eventが存在しなければ、‘U’は引数としてnilを提供する。[No I/O]

v

ユーザーオプションとして宣言された変数(述語custom-variable-pを満足する)。これはread-variableを使用して変数を読み取る。Definition of read-variableを参照のこと。[Existing]、[Completion]、[Prompt]

x

Lispオブジェクト。そのオブジェクトの入力構文により指定され、C-jRETで終端される。オブジェクトは評価されない。ミニバッファーでのLispオブジェクトの読み取りを参照のこと。[Prompt]

X

Lispフォームの値。‘X’は‘x’のように読み取りを行いフォームを評価して、その値がコマンドの引数になる。[Prompt]

z

コーディングシステム名(シンボル)。ユーザーがnull入力をエンターすると、引数値はnilになる。コーディングシステムを参照のこと。[Completion]、[Existing]、[Prompt]

Z

コマンドにプレフィクス引数があればコーディングシステム名。プレフィクス引数がなければ‘Z’は引数値としてnilを提供する。[Completion]、[Existing]、[Prompt]


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

22.2.3 interactiveの使用例

以下にinteractiveの例をいくつか示します:

(defun foo1 ()              ; foo1は1つの引数をとり
    (interactive)           ;   単に2単語分前に移動する
    (forward-word 2))
     ⇒ foo1

(defun foo2 (n)             ; foo2は引数を1つとる
    (interactive "^p")      ;   引数は数引数
                            ; shift-select-modeでは、
                            ;   リージョンをアクティブにするか、拡張する
    (forward-word (* 2 n)))
     ⇒ foo2

(defun foo3 (n)             ; foo3は引数を1つとる
    (interactive "nCount:") ;   引数はミニバッファーで読み取られる
    (forward-word (* 2 n)))
     ⇒ foo3

(defun three-b (b1 b2 b3)
  "Select three existing buffers.
Put them into three windows, selecting the last one."
    (interactive "bBuffer1:\nbBuffer2:\nbBuffer3:")
    (delete-other-windows)
    (split-window (selected-window) 8)
    (switch-to-buffer b1)
    (other-window 1)
    (split-window (selected-window) 8)
    (switch-to-buffer b2)
    (other-window 1)
    (switch-to-buffer b3))
     ⇒ three-b
(three-b "*scratch*" "declarations.texi" "*mail*")
     ⇒ nil

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

22.2.4 コマンドにたいするモード指定

Emacsのコマンドの多くは汎用であり、特定のモードに関連付けられていません。たとえばM-x kill-regionは編集可能テキストをもつほとんどのモード、(M-x list-buffersのような)情報表示コマンドはほとんどのコンテキストで使用できます。

しかしそれ以外の多くのコマンドはモードに具体的に関連付けられており、そのコンテキスト外部では意味をなしません。たとえばDiredバッファーの外部でM-x dired-diffを使用すると、単にエラーをシグナルするでしょう。

したがってEmacsにはコマンドが“所属する”モードが何かを指定するためのメカニズムがあります:

(defun dired-diff (...)
  ...
  (interactive "p" dired-mode)
  ...)

これはそのコマンドをdired-mode (やdired-modeから派生したモード)だけに適用されるようにマークします。interactiveフォームには任意個数のモードを追加できます。

モードの指定は、M-S-x (execute-extended-command-for-buffer)でのコマンド補完に影響を与えます(インタラクティブな呼び出しを参照)。read-extended-command-predicateの値に応じて、モード指定がM-xでの補完にも影響を与えるかもしれません。

たとえばread-extended-command-predicateの値としてcommand-completion-default-include-p述語を使用する際には、特定モードに適用されるとマークされたコマンドはM-xでリストされないでしょう(もちろんそのモードを使用するバッファーにいない場合)。これはメジャーモードとマイナーモードの両方に言えることです(対照的にM-S-xは適用されないコマンドを補完候補から常に省略する)。

read-extended-command-predicateはデフォルトではnilであり、M-xでの補完ではカレントバッファーのモードに適用されるとマークされているか否かに関わらず、ユーザーがタイプしたものにマッチするすべてのコマンドがリストされます。

あるモードにたいして適用されるものとしてコマンドをマークすると、(何らかのキーにバインドされていなければ)それらはC-h mでもリストされるようになります。

(拡張interactiveフォームをサポートしない古いバージョンのEmacsでは動作すると思われるコードがある等で)この拡張interactiveフォームの使用が不便なら、かわりに等価な以下の宣言(declareフォームを参照)を使用できます:

(declare (modes dired-mode))

コマンドのモードへのタグ付けはある意味好みの問題ですが、そのモードの外部では動作しないことが明確なコマンドはタグ付けするべきです。これにはどこか別の場所で呼び出すとエラーをシグナルするだけではなく、期待しないモードからの呼び出しが破壊的なコマンドも含まれます(これは通常はスペシャルモード、すなわち編集不可なモード用に記述されたコマンドのほとんどが含まれる)。

別モードから呼び出した際にも害がなく、“機能する”コマンドもありますが、それでも別の場所使用することが実際に無意味なコマンドには、依然としてタグ付けする必要があります。たとえば多くのスペシャルモードはバッファーのexitコマンドにqをバインドしており、これは"Goodbye from this mode"のようなメッセージを発行してkill-bufferを呼び出す以外は何も行わないかもしれません。このコマンドは別のモードでも“機能する”でしょうが、そのスペシャルモードのコンテキスト外部でこのコマンドを実際に使いたいと思う人が居るようには思えません。

多くのモードには、そのモードを異なる方法で開始するために、一連の異なるコマンドがあります (例: eww-open-in-new-buffereww-open-file)。このようなコマンドはユーザーがさまざまなコンテキストから発行し得るので、モード固有とタグ付けするべきでは決してありません。


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

22.2.5 コマンド候補からの選択

マクロdefine-alternativesジェネリックコマンド(generic command)を定義するために使用できます。これらはユーザーの選択により複数の候補から選択可能なinteractive関数の実装です。

Macro: define-alternatives command &rest customizations

新たなコマンドcommand(シンボル)を定義する。

最初にユーザーがM-x command RETを実行したとき、Emacsはコマンドが使用する実際のフォームにたいして確認を求めて、その選択をカスタム変数として記録する。プレフィクス引数を使用すると選択肢の選択のプロセスを繰り返す。

変数command-alternativesには、commandの実装候補がalistで含まれる。この変数がセットされるまでdefine-alternativesは効果をもたない。

customizationsが非nilなら、defcustomキーワード(典型的には:group:version)と、command-alternativesの宣言に追加する値により構成される選択肢。


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

22.3 インタラクティブな呼び出し

コマンドループはキーシーケンスをコマンドに変換した後、関数command-executeを使用してその関数を呼び出します。そのコマンドが関数なら、command-executeは引数を読み取りコマンドを呼び出すcall-interactivelyを呼び出します。自分でこれらの関数を呼び出すこともできます。

このコンテキストにおいて用語“command”はインタラクティブにコール可能な関数(または関数likeなオブジェクト)やキーボードマクロを指すことに注意してください。つまりコマンドを呼び出すキーシーケンスのことではありません(キーマップを参照)。

Function: commandp object &optional for-call-interactively

この関数はobjectがコマンドならt、それ以外はnilをリターンする。

コマンドには文字列とベクター(キーボードマクロとして扱われる)、トップレベルのinteractiveフォーム(interactiveの使用を参照)を含むラムダ式、そのようなラムダ式から作成されたバイトコンパイル関数オブジェクト、interactiveとして宣言(autoloadの4つ目の引数が非nil)されたautoloadオブジェクト、およびいくつかのプリミティブ関数が含まれる。interactive-formプロパティが非nilのシンボル、および関数定義がcommandpを満足するシンボルもコマンドとされる。

for-call-interactivelyが非nilなら、call-interactivelyが呼び出すことができるオブジェクトにたいしてのみcommandptをリターンする。したがってキーボードマクロは該当しなくなる。

commandpを使用する現実的な例については、ドキュメント文字列へのアクセス内のdocumentationを参照のこと。

Function: call-interactively command &optional record-flag keys

この関数はinteractive呼び出し仕様にしたがって引数を取得し、インタラクティブに呼び出し可能な関数commandを呼び出す。これはcommandがリターンするものが何であれ、それをリターンする。

たとえばもし以下の署名をもつ関数があり:

(defun foo (begin end)
  (interactive "r")
  ...)

以下を行うと

(call-interactively 'foo)

これはリージョン(pointmark)を引数としてfooを呼び出すだろう。

commandが関数でない、またはインタラクティブに呼び出せない(コマンドでない)場合にはエラーをシグナルする。たとえコマンドだとしても、キーボードマクロ(文字列かベクター)は関数ではないので許容されないことに注意。commandがシンボルならcall-interactivelyはそれの関数定義を使用する。

record-flagが非nilなら、このコマンドとコマンドの引数は無条件にリストcommand-historyに追加される。それ以外なら引数の読み取りにミニバッファーを使用した場合のみコマンドが追加される。コマンドのヒストリーを参照のこと。

引数keysが与えらたら、それはコマンドを呼び出すためにどのイベントを使用するかコマンドが問い合わせた場合に与えるべきイベントシーケンスを指定するベクターである。keysnilまたは省略された場合のデフォルトは、this-command-keys-vectorのリターン値である。Definition of this-command-keys-vectorを参照のこと。

Function: funcall-interactively function &rest arguments

この関数はfuncall (関数の呼び出しを参照)と同様に機能するが、インタラクティブな呼び出しのように見える呼び出しを生成する。function内部でのcalled-interactively-pの呼び出しはtをリターンするだろう。functionがコマンドでなければ、エラーをシグラルすることなくそれを呼び出す。

Function: command-execute command &optional record-flag keys special

この関数はcommandを実行する。引数commandは述語commandpを満足しなければならない。つまりインタラクティブに呼び出し可能な関数かキーボードマクロでなければならない。

commandが文字列かベクターなら、execute-kbd-macroにより実行される。関数はrecord-flagおよびkeys引数とともにcall-interactivelyに渡される(上記参照)。

commandがシンボルなら、その位置にシンボルの関数定義が使用される。autoload定義のあるシンボルは、インタラクティブに呼び出し可能な関数を意味するよう宣言されていればコマンドとして判断される。そのような宣言は指定されたライブラリーのロードと、シンボル定義の再チェックにより処理される。

引数specialが与えられたら、それはプレフィクス引数を無視して、それをクリアーしないという意味である。これはスペシャルイベント(スペシャルイベントを参照)を実行する場合に使用される。

Command: execute-extended-command prefix-argument

この関数はcompleting-read(補完を参照)を使用して、ミニバッファーからコマンド名を読み取る。その後で指定されたコマンドを呼び出すためにcommand-executeを使用する。そのコマンドがリターンするのが何であれ、それがexecute-extended-commandの値となる。

そのコマンドがプレフィクス引数を求める場合には、prefix-argumentの値を受け取る。execute-extended-commandがインタラクティブに呼び出されたら、カレントのrawプレフィクス引数がprefix-argumentに使用され、それが何であれ実行するコマンドに渡される。

通常はexecute-extended-commandM-xの定義なので、プロンプトとして文字列‘M-x を使用する(execute-extended-commandを呼び出したイベントからプロンプトを受け取るほうが良いのだろうが実装は苦痛を併なう)。プレフィクス引数の値の説明がもしあれば、それもプロンプトの一部となる。

(execute-extended-command 3)
---------- Buffer: Minibuffer ----------
3 M-x forward-word RET
---------- Buffer: Minibuffer ----------
     ⇒ t

このコマンドはカレントメジャーモード(や有効なマイナーモード)に不適切なコマンドを除外するread-extended-command-predicate変数を考慮する。この変数の値はデフォルトではnilであり、除外されるコマンドはない。しかし関数command-completion-default-include-pを呼び出すようにカスタマイズすることで、モードに応じたフィルタリングを行うようになる。read-extended-command-predicateには任意の述語関数を指定できる。これはそのコマンドのシンボル、およびカレントバッファーという2つのパラメーターで呼び出される。そのバッファーニオイそのコマンドを補完に含めるなら非nilをリターンすること。

Command: execute-extended-command-for-buffer prefix-argument

これはexecute-extended-commandと似ているが、補完にたいしてカレントバッファー(や有効なマイナーモード)と特に関連するものに限定してコマンドを提案する。これらにはそのモードにタグ付けされたコマンド(interactiveの使用を参照)、およびローカルでアクティブなキーマップにバインドされたコマンドも含まれる。このコマンドはM-S-x (すなわち“meta shift x”)の通常の定義である。

これらのコマンドはいずれもコマンド名の入力を求めますが、補完ルールは異なります。入力を求められた際にM-S-xコマンドを使用することで、2つの補完モードを切り替えることができます。


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

22.4 インタラクティブな呼び出しの区別

interactive呼び出しの際に、コマンドが(エコーエリア内の情報メッセージなどのような)視覚的な追加フィードバックを表示すべきときがあります。これを行うためには3つの方法があります。その関数がcall-interactivelyを使用して呼び出されたかどうかテストするには、オプション引数print-messageを与えるとともに、interactive呼び出しで非nilとなるようにinteractive仕様を使うのが推奨される方法です。以下は例です:

(defun foo (&optional print-message)
  (interactive "p")
  (when print-message
    (message "foo")))

数プレフィクス引数は決してnilにならないので、わたしたちは"p"を使用します。この方法で定義された関数はキーボードマクロから呼び出されたときにメッセージを表示します。

追加引数による上記の手法は、呼び出し側に“この呼び出しをinteractiveとして扱うように”伝えることができるので通常は最善です。しかしcalled-interactively-pをテストすることによってこれを行うこともできます。

Function: called-interactively-p kind

この関数は呼び出された関数がcall-interactivelyを使用して呼び出されえいたらtをリターンする。

引数kindはシンボルinteractiveかシンボルanyのいずれかである。これがinteractiveなら、called-interactively-pはユーザーから直接呼び出しが行われたとき — たとえば関数呼び出しにバインドされたキーシーケンスをユーザーがタイプした場合がそれに該当するが、ユーザーがその関数を呼び出すキーボードマクロ(キーボードマクロを参照)を実行中した場合は該当しない — だけtをリターンする。kindanyなら、called-interactively-pはキーボードマクロを含む任意の種類のinteractive呼び出しにたいしてtをリターンする。

疑わしい場合にはanyを使用すること。interactiveの使用が正しいと解っているのは、関数が実行中に役に立つメッセージを表示するかどうか判断が必要な場合だけである。

Lisp評価(またはapplyfuncall))を通じて呼び出された場合には、関数は決してインタラクティブに呼び出されたとは判断されない。

以下はcalled-interactively-pを使用する例:

(defun foo ()
  (interactive)
  (when (called-interactively-p 'any)
    (message "Interactive!")
    'foo-called-interactively))

;; M-x fooとタイプする
     -| Interactive!

(foo)
     ⇒ nil

以下はcalled-interactively-pの直接呼び出しと間接呼び出しを比較した例。

(defun bar ()
  (interactive)
  (message "%s" (list (foo) (called-interactively-p 'any))))

;; M-x barとタイプする
     -| (nil t)

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

22.5 コマンドループからの情報

エディターコマンドループは自分自身と実行するコマンドのために、いくつかのLisp変数にステータス記録を保持します。一般的にthis-commandlast-command以外は、Lispプログラム内でこれらの変数を変更するのは良いアイデアではありません。

Variable: last-command

この変数はコマンドループによって実行された以前のコマンド(前にカレントだったコマンド)の名前を記録する。値は通常は関数定義をもつシンボルだが、その保証はない。

コマンドがコマンドループからリターンするとき、this-commandから値がコピーされる。ただしそのコマンドが後続のコマンドにたいしてプレフィクス引数を指定されたときを除く。

この変数は常にカレント端末にたいしてローカルであり、バッファーローカルにできない。複数の端末を参照のこと。

Variable: real-last-command

この変数はEmacsによりlast-commandと同様にセットアップされるが、Lispプログラムから決して変更されない。

Variable: last-repeatable-command

この変数は入力イベントの一部ではない、もっとも最近実行されたコマンドを格納する。これはコマンドrepeatが再実行を試みるコマンドである。Repeating in The GNU Emacs Manualを参照のこと。

Variable: this-command

この変数はコマンドループにより現在実行中のコマンドの名前を記録する。last-commandと同様、通常は関数定義をもつシンボルである。

コマンドループはコマンドを実行する直前にこの変数をセットして、(そのコマンドが後続のコマンドのプレフィクス引数を指定しなければ)そのコマンドが終了したときにその値をlast-commandにコピーする。

いくつかのコマンドは次に実行されるコマンドが何であれ、それにたいするフラグとして実行中の間この変数をセットする。特にテキストをkillする関数はthis-commandkill-regionにセットするので、直後に実行された任意のkillコマンドは、killしたテキストを前にkillされたテキストに追加するべきことが解かるだろう。

特定のコマンドでエラー発生時に前のコマンドとして認識されたくなければ、それを防ぐようにそのコマンドをコーディングしなければなりません。これを行う1つの方法は、以下のようにコマンドの最初でthis-commandtをセットして、最後にthis-commandに正しい値をセットする方法です:

(defun foo (args…)
  (interactive …)
  (let ((old-this-command this-command))
    (setq this-command t)
    … 処理を行う …
    (setq this-command old-this-command)))

エラーならletは古い値をリストアするので、わたしたちはletthis-commandをバインドしません。この場合におけるletの機能は、わたしたちが正に避けたいと思っていることを行ってしまうでしょう。

Variable: this-original-command

コマンドのリマップ(コマンドのリマップを参照)が発生したときを除き、これはthis-commandと同じ値をもつ。リマップが発生するとthis-commandは実際に実行されたコマンド、this-original-commandは実行を指定されたが他のコマンドにリマップされたコマンドを与える。

Variable: current-minibuffer-command

これはthis-commandと同じ値をもつが、ミニバッファーへエンター時2再帰的にバインドされる。この変数はカレントミニバッファーセッションをオープンしたコマンドが何かを判定するために、ミニバッファーフック等から使用されるかもしれない。

Function: this-command-keys

この関数は現在のコマンドを呼び出したキーシーケンスを含む文字列かベクターをリターンする。read-eventを使用するコマンドにより、タイムアウトせずに読み取られたすべてのイベントが最後に加えられる。

しかしそのコマンドがread-key-sequenceを呼び出していたら、最後に読み取られたキーシーケンスをリターンする。キーシーケンス入力を参照のこと。シーケンス内のすべてのイベントが文字列として適当な文字なら文字列が値になる。入力イベントを参照のこと。

(this-command-keys)
;; これを評価するためにC-u C-x C-eを使用すると
     ⇒ "^U^X^E"
Function: this-command-keys-vector

this-command-keysと同様だが常にベクターでイベントをリターンするので、入力イベントを文字列内に格納する複雑さを処理する必要がない(文字列内へのキーボードイベントの配置を参照)。

Function: clear-this-command-keys &optional keep-record

この関数はthis-command-keysがリターンするイベントテーブルを空にする。keep-recordnilなら、その後に関数recent-keys(入力の記録を参照)がリターンするレコードも空にする。これは特定のケースにおいてパスワードを読み取った後、次のコマンドの一部として不用意にパスワードがエコーされるのを防ぐために有用である。

Variable: last-nonmenu-event

この変数はキーシーケンス(マウスメニューからのイベントは勘定しない)の一部として読み取られた最後の入力イベントを保持する。

この変数の1つの使い方は、x-popup-menuにたいしてどこにメニューをポップアップすべきか告げる場合である。これは内部的に y-or-n-p(Yes-or-Noによる問い合わせを参照)にも使用されている。

Variable: last-command-event

この変数にはコマンドの一部としてコマンドループに読み取られた最後の入力イベントがセットされる。この変数は主にself-insert-command (どの文字が挿入されたか判断するため)、およびpost-self-insert-hook (挿入された文字にアクセスするため)の内部で使用されている(ユーザーレベルの挿入コマンドを参照)。

last-command-event
;; これを評価するためにC-u C-x C-eを使用すると
     ⇒ 5

C-eASCIIコードの5が値になる。

Variable: last-event-frame

この変数は最後の入力イベントが送られたフレームを記録する。これは通常はそのイベントが生成されたときに選択されていたフレームだが、そのフレームの入力が他のフレームにリダイレクトされていたら、そのリダイレクトされていたフレームが値となる。入力のフォーカスを参照のこと。

最後のイベントがキーボードマクロに由来する場合、値はmacroになる。

入力イベントには、その発生元となるどこかから送られてこなければなりません。それがキーボードマクロ、シグナル、あるいは‘unread-command-events’のときもありますが、通常はコンピューターに接続されたユーザーの制御する物理的な入力デバイスからでしょう。これらのデバイスは入力デバイス(input device)と呼ばれており、Emacsは入力イベントそれぞれを発生元である入力デバイスに関連付けています。これらのデバイスは入力デバイスそれぞれにたいして一意な名前によって識別されます。

使用された入力デバイスを正確に判別できる能力は、各システムの詳細に依存します。その情報が利用できなければ、Emacsはキーボードイベントの発生元を‘"Virtual core keyboard"’、その他のイベントの発生元を‘"Virtual core pointer"’のように報告します(これらは詳細なデバイス情報が不明なときにXサーバーが報告するデバイス名なので、すべてのプラットフォームでこれらの値をデバイス名として使用する)。

Variable: last-event-device

この変数は最後に読み取られた入力イベントの発生元となる入力デバイス名を記録する。そのようなデバイスが存在しなければnil(たとえば最後の入力イベントをunread-command-eventsから読み取ったときや、キーボードマクロが発生元のとき)。

XウィンドウでXInput拡張(X Input Extension)が使用される際のデバイス名はXサーバーに接続された物理キーボード、ポインティングデバイス、タッチスクリーンそれぞれにたいして一意な文字列となる。それ以外の場合には‘"Virtual core pointer"’か‘"Virtual core keyboard"’という文字列のいずれかであり、それはそのイベントが(マウスのような)ポインティングデバイス、あるいはキーボードのいずれによって生成されたかに依存する。

Function: device-class frame name

異なるさまざまなタイプのデバイスがあり、それらのデバイスは名前によって判別できる。この関数はframeで発生したイベントにたいして、デバイスnameの正しいタイプを決定するために使用できる。

リターン値は以下のシンボル(“デバイスクラス”)のいずれか:

core-keyboard

コアキーボード(core keyboard)。そのデバイスがキーボードのようなデバイスだが、その他の特徴が不明なことを意味する。

core-pointer

コアキーボード(core pointer)。そのデバイスがポインティングデバイスのようなデバイスだが、その他の特徴が不明なことを意味する。

mouse

コンピューターマウス。

trackpoint

トラックポイントやジョイスティック(または同種のコントローラー)。

eraser

グラフィックタブレットのスタイラス(タッチペン)の反対側やスタンドアロンのイレイサー(消しゴム)。

pen

グラフィックタブレットのペン、スタイラス、または同種デバイスのペン先端。

puck

コンピュータのマウスのように見えるが、他の何かの面にたいする絶対座標を報告するデバイス。

power-button

電源ボタンやボリュームボタン(または同種のコントローラー)。

keyboard

コンピューターキーボード。

touchscreen

コンピュータータッチパッド。

pad

描画タブレットの周辺機器で一般的なセンシティブボタン(sensitive button)、リング(ring)、ストリップ(strip)のコレクション。

touchpad

タッチパッドのような二次的タッチデバイス。

piano

電子キーボードのような音楽器。

test

入力を報告するためにXTEST拡張が使用するデバイス。


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

22.6 コマンド後のポイントの調整

プロパティdisplaycompositionをもつテキストや非表示のテキストシーケンスの中間では、Emacsはポイント値を表示できません。したがってコマンドが終了した後にコマンドループにリターンした後にそのようなシーケンス中にポイントがある場合には、そのシーケンスを効果的に不可触にするために、コマンドループは通常ポイントをそのようなシーケンスの端へと移動します。

変数disable-point-adjustmentをセットすることにより、コマンドはこの機能を抑制できます:

Variable: disable-point-adjustment

この変数が非nilならコマンドがコマンドループにリターンするとき、コマンドループはこれらのテキストプロパティをチェックせず、これらのプロパティをもつシーケンスの外にポイントを移動しない。

コマンドループは各コマンドを実行する前にこの変数をnilにセットするので、あるコマンドがこれをセットしても効果が適用されるのはそのコマンドにたいしてだけである。

Variable: global-disable-point-adjustment

この変数を非nilにセットするとシーケンス外にポイントを移動する、これらの機能は完全にオフになる。


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

22.7 入力イベント

Emacsコマンドループは入力イベント(input events)のシーケンスを読み取ります。入力イベントとはキーボードやマウスのアクティビティ、またはEmacsに送られるシステムイベントを表します。キーボードアクティビティにたいするイベントは文字かシンボルです。それ以外のイベントは常にリストになります。このセクションでは入力イベントの表現と意味について詳細を説明します。

Function: eventp object

この関数はobjectが入力イベントかイベント型なら非nilをリターンする。

イベントまたはイベント型として非nilの任意のシンボルが使用されるかもしれないことに注意。eventpはLispコードによりイベントとして使用されることを意図したシンボルかどうかは区別できない。


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

22.7.1 キーボードイベント

キーボードから取得できる入力には2つの種類があります。それは通常のキーとファンクションキーです。通常のキーは文字に対応しており(修飾されているかもしれない)、それらが生成するイベントはLisp内では文字で表現されます。文字イベントのイベント型は文字自身(整数)であり、何らかの修飾ビットがセットされているかもしれません。イベントの分類を参照してください。

入力文字イベントは0から524287までの基本コード(basic code)に加えて、以下の修飾ビット(modifier bits)の一部、またはすべてによって構成されます:

meta

文字イベントコードのビット 2**27 はメタキーが押下された状態で文字がタイプされたことを示す。

control

文字イベントコードのビット 2**26 は非ASCIIコントロール文字を示す。

C-aのような非ASCIIコントロール文字は、自身が特別な基本コードをもつため、それらを示すためにEmacsは特別なビットを必要としない。つまりC-aのコードは単なる1である。

しかし%のような非ASCIIとコントロールを組み合わせてタイプすると取得される数値は%に 2**26 を加えた値となる(端末が非ASCIIコントロール文字、すなわち27番目のビットがセットされた文字をサポートすると仮定する)。

shift

文字イベントコードのビット 2**25 (26番目のビット)はシフトキーが押下された状態でASCIIコントロール文字がタイプされたことを示す。

アルファベット文字にたいしては、基本コード自身が大文字か小文字かを示す。数字と句読点文字にたいしてシフトキーは、異なる基本コードをもつ完全に違う文字を選択する。可能な限りASCII文字として保つために、Emacsはこれらの文字にたいしてビット 2**25 を使用しない。

しかしASCIIC-AC-aを区別する方法を提供しないので、EmacsはC-Aにたいしてビット 2**25 を使用し、C-aには使用しない。

hyper

文字イベントコードのビット 2**24 はハイパーキーが押下された状態で文字がタイプされたことを示す。

super

文字イベントコードのビット 2**23 はスーパーキーが押下された状態で文字がタイプされたことを示す。

alt

文字イベントコードのビット 2**22 はアルトキーが押下された状態で文字がタイプされたことを示す(ほとんどのキーボードでAltとラベルされたキーは、実際にはアルトキーではなくメタキーとして扱われる)。

プログラム内での特定のビット数値の記述は避けるのが最善の方法です。文字の修飾ビットをテストするためには、関数event-modifiers (イベントの分類を参照)を使用してください。keymap-setでキーバインディングを作成する際には、‘C-H-x’ (“control hyper x”)のような文字列を使ってこれらのイベントを指定できます(キーバインディングの変更を参照)。


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

22.7.2 ファンクションキー

ほとんどのキーボードにはファンクションキー(function keys)があります。これは名前や文字以外のシンボルをもつキーです。Emacs Lispではファンクションキーはシンボルとして表現されます。そのシンボル名はファンクションキーのラベルの小文字です。たとえばF1とラベルされたキーを押下すると、シンボルf1で表される入力イベントが生成されます。

ファンクションキーのイベント型はイベントシンボル自身です。イベントの分類を参照してください。

ファンクションキーにたいするシンボルの命名規約には、以下のような特別なケースがいくつかあります:

backspacetabnewlinereturndelete

これらのキーは、ほとんどのキーボードにおいて特別にキーをもつ、一般的なASCIIコントロール文字に対応する。

ASCIIではC-iTABは同じ文字である。端末がこれらを区別できるならEmacsは前者を整数の9、後者をシンボルtabで表現することによってLispプログラムにこれらの違いを伝える。

ほとんどの場合はこれらの2つを区別するのは役に立たない。そのためlocal-function-key-map (イベントシーケンス変換のためのキーマップを参照)はtabを9にマップするようセットアップされている。したがって文字コード9(文字C-i)へのキーバインディングはtabにも適用される。このグループ内の他のシンボルも同様である。関数read-charがこれらのイベントを文字に変換する場合も同様である。

ASCIIではBSは実際はC-hである。しかしbackspaceは文字コード8(BS)ではなく、文字コード127(DEL)に変換される。ほとんどのユーザーにとってこれは好ましいだろう。

leftuprightdown

矢印カーソルキー

kp-addkp-decimalkp-divide、…

キーパッドのキー(標準的なキーボードにおいては右側にある)。

kp-0kp-1、…

キーパッドの数字キー。

kp-f1kp-f2kp-f3kp-f4

キーパッドのPFキー。

kp-homekp-leftkp-upkp-rightkp-down

キーパッドの矢印キー。Emacsは通常これらを非キーパッドのキーhomeleft、…に変換する。

kp-priorkp-nextkp-endkp-beginkp-insertkp-delete

通常は他の箇所にあるキーと重複するキーパッド追加キー。Emacsは通常これらを同じような名前の非キーパッドキーに変換する。

ファンクションキーにたいしても修飾キーALTCTRLHYPERMETASHIFTSUPERを使用できます。シンボル名のプレフィクスとしてこれらを表します:

A-

アルト修飾。

C-

コントロール修飾。

H-

ハイパー修飾。

M-

メタ修飾。

S-

シフト修飾。

s-

スーパー修飾。

したがってMETAを押下した場合のF3キーにたいするシンボルはM-f3になります。複雑のプレフィクスを使用する場合には、アルファベット順の記述を推奨します。とはいえキーバインディングが修飾されたファンクションキーを探す際に引数の順序は関係ありません。


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

22.7.3 マウスイベント

Emacsは4つの種類のマウスイベントをサポートします。それはクリックイベント、ドラッグイベント、ボタンダウンイベント、モーションイベントです。すべてのマウスイベントはリストで表現されます。このリストのCARはイベント型です。イベント型はどのマウスボタンが関与するのか、それにたいしてどの修飾キーが使用されたかを示します。イベント型によりダブル、あるいはトリプルでボタンが押されたかを区別することもできます(リピートイベントを参照)。残りのリスト要素は位置と時間の情報を提供します。

キーの照合ではイベント型だけが問題になります。2つのイベントが同じコマンドを実行するには同じイベント型が必要です。実行されるコマンドはinteractiveのコード‘e’を使用して、これらのイベントの完全な値にアクセスできます。interactiveにたいするコード文字を参照してください。

マウスイベントで開始されたキーシーケンスはカレントバッファーではなく、マウスのあったウィンドウ内のバッファーのキーマップを使用して読み取られます。これはウィンドウ内でクリックすることによりそのウィンドウやそのウィンドウのバッファーが選択されることを意味しません。つまりそれは完全にそのキーシーケンスのコマンドバインディングの制御下にあるのです。


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

22.7.4 クリックイベント

ユーザーが同じ場所でマウスボタンを押してからリリース(release: 離す)すると、clickイベントが生成されます。ウィンドウシステムがマウスホイールイベントを報告する方法に応じて、マウスホイールはマウスクリックかマウスホイールイベントを生成します。すべてのマウスイベントは同じフォーマットを共有します:

(event-type position click-count)
event-type

これはマウスボタンが使用されたことを示す。これはシンボルmouse-1mouse-2、…のうちのいずれかで、マウスボタンは左から右に番号が付される。マウスホイールイベントならwheel-upwheel-downかもしれない。

ファンクションキーにたいして行うのと同様にアルト、コントロール、ハイパー、メタ、シフト、スーパーの修飾にたいしてプレフィクス‘A-’、‘C-’、‘H-’、‘M-’、‘S-’、‘s-’も使用できる。

このシンボルはイベントのイベント型としての役割りももつ。イベントのキーバインディングはこれらの型により示される。したがってmouse-1にたいするキーバインディングが存在すれば、そのバインディングはevent-typemouse-1であるようなすべてのイベントに適用されるだろう。

position

これはマウスイベントがどこで発生したかを表すマウス位置リスト(mouse position list)である。詳細は以下を参照のこと。

click-count

これは同じマウスボタンを素早く繰り返し押下したときの回数、あるいはホイールを繰り返し回した回数である。リピートイベントを参照のこと。

マウスイベントのpositionスロット内にあるマウス位置リストの内容にアクセスするためには、一般的にはマウスイベントへのアクセスに記述された関数を使用するべきです。

このリストの明示的なフォーマットはどこでイベントが発生したかに依存します。テキストエリア、モードライン、ヘッダーライン、タブライン、フリンジ、マージンエリアでのクリックにたいしてマウス位置リストは以下のフォーマットをもちます

(window pos-or-area (x . y) timestamp
 object text-pos (col . row)
 image (dx . dy) (width . height))

以下はこれらのリスト要素がもつ意味です:

window

マウスイベントが発生したウィンドウ。

pos-or-area

テキストエリア内でクリックされた文字のバッファー位置。またはテキストエリア外がクリックされたなら、イベントが発生したウィンドウエリア。これはシンボルmode-lineheader-linetab-linevertical-lineleft-marginright-marginleft-fringeright-fringeのいずれか。

特別なケースの1つとしてpos-or-areaが単なるシンボルではなく、(上記シンボルのいずれか1つの)シンボルを含むリストのような場合がある。これはEmacsにより登録されたイベントにたいする、イマジナリープレフィクスキー(imaginary prefix key)の後に発生する。キーシーケンス入力を参照のこと。

x, y

イベントの相対ピクセル座標(relative pixel coordinates)。あるウィンドウのテキストエリア内でのイベントにたいする座標原点(0 . 0)は、テキストエリアの左上隅となる。ウィンドウのサイズを参照のこと。モードライン、ヘッダーラインやタブライン内でのイベントにたいする座標原点は、そのウィンドウ自身の左上隅となる。フリンジ、マージン、垂直ボーダー(vertical border)ではxは有意なデータをもたない。フリンジ、マージンではyはヘッダーラインの最下端からの相対位置である。すべてのケースにおいてxyの座標はそれぞれ右方向と下方向で増加する。

timestamp

そのイベントが発生した時刻をシステム依存の初期時刻(initial time)からの経過ミリ秒で表す整数。

object

nil (バッファーテキスト上でイベントが発生したことを意味する)、イベント箇所にテキストプロパティやオーバーレイがあれば(string . string-pos)という形式のコンスセル。

string

クリックされた文字列。すべてのテキストプロパティを含む。

string-pos

クリックが発生した文字列内の位置。

text-pos

マージンエリアやフリンジにたいするクリックでは、そのウィンドウ内の対応する行内の最初の可視な文字のバッファー位置となる。モードライン、ヘッダーラインやタブラインにたいするクリックではnil。他のイベントにたいしてはクリックされたバッファーのクリックされた最寄りの位置となる。

col, row

これらはxyの位置にあるグリフ(gliph)の実際の行と列の座標数値である。行xがその行の実際のテキストの最後の列を超えるなら、colはデフォルトの文字幅をもつ仮想的な追加列数を加えた値が報告される。そのウィンドウがヘッダーラインをもてば行0はヘッダーライン、タブラインももてば行1はタブラインとなり、それ以外ならテキストエリアの上端ラインが行0となる。ウィンドウのテキストエリアのクリックにたいしては、テキストエリアの左端列が列0となり、モードラインまたはヘッダーラインのクリックにたいしてはそのラインの左端が列0となる。フリンジまたは垂直ボーダーのクリックにたいしては、これらは有意なデータをもたない。マージンのクリックにたいしては、colはマージンエリアの左端、rowはマージンエリアの上端から測られる。

image

クリック箇所にイメージがあればfind-imageがリターンするようなイメージオブジェクト(イメージの定義を参照)、それ以外はnil

dx, dy

クリック位置からもっとも近いobjectのグリフ左上隅からクリック位置への相対オフセット(ピクセル)。関係のあるobjectはバッファー、文字列、またはイメージ(上記参照)。objectnilか文字列なら、クリックされた文字グリフの左上隅からの相対座標。テキストモードのフレームではすべてのグリフのピクセルサイズは正確に1x1とみなされるので、objectnilならオフセットは常に0になることに注意。

width, height

クリックがバッファーテキスト、あるいはオーバーレイ文字列やディスプレイ文字列の文字上の場合には、その文字のグリフのピクセル単位での幅と高さ。それ以外の場合にはクリックされたobjectのサイズ。

スクロールバーへのクリックにたいして、positionは以下の形式をもちます:

(window area (portion . whole) timestamp part)
window

スクロールバーがクリックされたウィンドウ。

area

これはシンボルvertical-scroll-barである。

portion

スクロールバーの上端からクリック位置までのピクセル数。GTK+を含むいくつかのツールキットでは、Emacsがこれらのデータを抽出できないので値は常に0

whole

スクロールバーの全長のピクセル数。GTK+を含むいくつかのツールキットでは、Emacsがこれらのデータを抽出できないので値は常に0

timestamp

イベントが発生したミリ秒時刻。GTK+を含むいくつかのツールキットでは、Emacsがこれらのデータを抽出できないので値は常に0

part

クリックが発生したスクロールバー部分。これはシンボルhandle(スクロールバーのハンドル)、above-handle(ハンドルの上側エリア)、below-handle(ハンドルの下側エリア)、up(スクロールバー端の上矢印)、down(スクロールバー端の下矢印)のいずれか。

フレームのインターナルボーダー(フレームのレイアウトを参照)、フレームのツールバー(ツールバーを参照)やタブバーにたいするクリックではpositionは以下の形式をもちます:

 (frame part (X . Y) timestamp)
frame

インターナルボーダー、ツールバー、またはタブバーがクリックされたフレーム。

part

クリックされたフレームの部分。以下のいずれか:

tool-bar

フレームにはツールバーがあり、イベントはツールバー領域。

tab-bar

フレームにはタブバーがあり、イベントはタブバー領域。

left-edge
top-edge
right-edge
bottom-edge

対応するボーダーの直近のコーナーから少なくとも1正規文字の範囲内がクリックされた。

top-left-corner
top-right-corner
bottom-right-corner
bottom-left-corner

インターナルボーダーの対応するコーナーがクリックされた。

nil

フレームにインターナルボーダーがなく、イベントがツールバーやタブバー上ではない。これは通常はテキストモードフレームで発生する。これは非nil値にセットされたdrag-internal-borderパラメーター(マウスドラッグのパラメーターを参照)をもたないGUIフレームのインターナルボーダーでも発生し得る。


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

22.7.5 ドラッグイベント

Emacsでは特別なことをしなくてもドラッグイベントを取得できます。ドラッグイベント(drag event)はユーザーがマウスボタンを押下して、ボタンをリリースする前にマウスを異なる文字位置に移動すると毎回発生します。すべてのマウスイベントと同じように、ドラッグイベントはLispではリストで表現されます。このリストは以下のように開始マウス位置と最終位置ぼ両方を記録します:

(event-type
 (window1 START-POSITION)
 (window2 END-POSITION))

ドラッグイベントにたいしては、シンボルevent-typeの名前にプレフィクス‘drag-’が含まれます。たとえばボタン2を押下したままマウスをドラッグするとdrag-mouse-2イベントが生成されます。このイベントの2つ目と3つ目の要素は、マウス位置リスト(クリックイベントを参照)としてドラッグの開始と終了の位置を与えます。任意のマウスイベントの2つ目の要素に同じ方法でアクセスできます。しかしドラッグイベントは最初に選択されていたフレームの境界外で終了するかもしれません。この場合のには3つ目の要素の位置リストに、ウィンドウのかわりにそのフレームが含まれます。

drag-’プレフィクスは、その後に‘C-’や‘M-’のような修飾キープレフィクスが続きます。

read-key-sequenceがキーバインディングをもたず、対応するクリックイベントにキーバインディングがあるようなドラッグイベントを受け取ると、この関数はそのドラッグイベントをドラッグ開始位置でのクリックイベントに変更します。これはもし望まなければクリックイベントとドラッグイベントを区別する必要がないことを意味します。


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

22.7.6 ボタンダウンイベント

クリックイベントとドラッグイベントは、ユーザーがマウスボタンをリリースしたときに発生します。ボタンがリリースされるまでクリックとドラッグを区別することはできないので、リリース前にイベントが発生することはありません。

ボタンが押下されたらすぐに何か処理したいなら、ボタンダウン(button-down)イベントを処理する必要があります17。これらはevent-typeのシンボル名に‘down-’が含まれることを除き、クリックイベントとまったく同じようなリストにより表現されます。‘down-’プレフィクスの後には‘C-’や‘M-’のような修飾キープレフィクスが続きます。

関数read-key-sequenceはコマンドバインディングをもたないボタンダウンイベントを無視します。したがってEmacsコマンドループもこれらを無視します。これはボタンダウンイベントで何かしたい場合以外は、ボタンダウンイベントの定義について配慮する必要がないことを意味します。ボタンダウンイベントを定義する通常の理由は、ボタンがリリースされるまで(モーションイベントを読み取ることにより)マウスモーションを追跡できるからです。モーションイベントを参照してください。


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

22.7.7 リピートイベント

マウスを移動せずに同じマウスボタンを素早く2回以上連続して押下すると、Emacsは2回目とそれ以降の押下にたいして特別なリピート(repeat)マウスイベントを生成します。

もっとも一般的なリピートイベントはダブルクリック(double-click)イベントです。Emacsはボタンを2回クリックしたときにダブルクリックイベントを生成します。このイベントは、(すべてのクリックイベントが通常そうであるように)ボタンをリリースしたときに発生します。

ダブルクリックイベントのイベント型にはプレフィクス‘double-’が含まれます。したがってmetaを押しながら2つ目のマウスボタンをダブルクリックすると、LispプログラムにはM-double-mouse-2が渡されます。ダブルクリックイベントがバインディングをもたなければ、対応する通常のクリックイベントのバインディングが実行に使用されます。したがって実際に望んだ場合でなければダブルクリック機能に注意を払う必要はありません。

ユーザーがダブルクリックを行うとき、Emacsはまず通常のクリックイベントを生成して、その後ダブルクリックイベントを生成します。したがってダブルクリックイベントのコマンドバインディングは、すでにシングルクリックイベントが実行された想定でデザインしなければなりません。つまりシングルクリックの結果から開始して、ダブルクリックの望むべき結果を生成しなければならないのです。

これはダブルクリックの意味合いが、シングルクリックの意味合いの何らかにもとづいて構築される場合は便利です。これはダブルクリックにたいするユーザーインターフェイスにおける推奨されるデザインプラクティスです。

ボタンをクリックした後にもう一度ボタンを押下して、そのままマウスの移動を開始すると、最終的にボタンをリリースしたときダブルドラッグ(double-drag)イベントが取得されます。このイベント型には単なる‘drag’のかわりに‘double-drag’が含まれます。ダブルドラッグイベントがバインディングをもたなければ、それがあたかも通常のドラッグイベントだったかのようにEmacsはかわりのバインディングを探します。

ダブルクリックやダブルドラッグイベントの前に、Emacsはユーザーが2回目にボタンを押したタイミングでダブルダウン(double-down)イベントを生成します。このイベント型には単なる‘down’のかわりに‘double-down’が含まれます。ダブルダウンイベントがバインディングをもたなければ、それがあたかも通常のボタンダウンイベントだったかのようにEmacsはかわりのバインディングを探します。どちらの方法でもバインディングが見つからなければダブルダウンイベントは無視されます。

要約するとボタンをクリックしてすぐにまた押したとき、Emacsは1回目のクリックにたいしてダウンイベントとクリックイベントを生成して、2回目に再度ボタンを押したときにダブルダウンイベント、そして最後にダブルクリックまたはダブルドラッグイベントを生成します。

ボタンを2回クリックした後にもう一度押したとき、それらすべてが素早く連続で行われたら、Emacsはトリプルダウン(triple-down)イベントと、その後続のトリプルクリック(triple-click)トリプルドラッグ(triple-drag)イベントを生成します。これらイベントのイベント型には‘double’のかわりに‘triple’が含まれます。トリプルイベントがバインディングをもたなければEmacsは対応するダブルイベントに使用されるであろうバインディングを使用します。

ボタンを3回以上クリックした後に再度ボタンを押すと、3回を超えた押下にたいするイベントはすべてトリプルイベントになります。Emacsはクワドループル(quadruple: 4連)、クインティプル(quintuple: 5連)、...等のイベントにたいして個別のイベント型をもちません。しかしボタンが何回押下されたかを正確に調べるためにイベントリストを調べることができます。

Function: event-click-count event

この関数はeventを誘因した連続するボタン押下の回数をリターンする。eventがダブルダウン、ダブルクリック、ダブルドラッグなら値は2である。eventがトリプルイベントなら値は3以上になる。eventが(リピートイベントではない)通常のマウスイベントなら値は1。

User Option: double-click-fuzz

リピートイベントを生成するためには、ほぼ同じスクリーン位置で連続でマウスボタンを押下しなければならない。double-click-fuzzの値はダブルクリックを生成するために連続する2回のクリック間で、マウスが移動(水平と垂直)するかもしれない最大ピクセル数を指定する。

この変数はドラッグとみなされるマウスモーションの閾値でもある。

User Option: double-click-time

リピートイベントを生成するためには、連続するボタン押下のミリ秒間隔がdouble-click-timeの値より小さくなければならない。double-click-timenilにセットすると複数回クリック検知が完全に無効になる。tにセットすると時間制限が取り除かれる。その場合はEmacsは位置だけで複数回のクリックを検知する。


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

22.7.8 モーションイベント

Emacsは、ボタンアクティビティが何もないマウスのモーション(motion: 動き)を記述するマウスモーション(mouse motion)イベントを生成するときがあります。マウスモーションイベントは以下のようなリストによって表現されます:

(mouse-movement POSITION)

positionはマウスカーソルのカレント位置を指定するマウス位置リスト(クリックイベントを参照)です。ドラッグイベントの終了位置のように、この位置リストは最初に選択されていた境界外の位置を表すかもしれず、その場合にはそのフレーム内のその位置のウィンドウが含まれます。

マクロtrack-mouseは、ボタン内でのモーションイベントの生成を有効にします。track-mouseのbodyの外側では、Emacsはマウスの単なるモーションにたいするイベントは生成せず、これらのイベントは発生しません。マウスの追跡を参照してください。

Variable: mouse-fine-grained-tracking

nilならたとえ非常に小さい移動でもマウスモーションイベントを生成する。それ以外ならテキスト内の同一グリフをマウスカーソルがポイントし続けるかぎりモーションイベントは生成されない。


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

22.7.9 タッチスクリーンのイベント

一部のウィンドウシステムではユーザーがスクリーンにタッチしたり、タッチしながら指を動かすことで反応する入力デバイスがサポートされています。Emacsはこれらのタッチスクリーンと呼ばれる入力デバイスが生成したイベントをタッチスクリーンイベント(touchscreen event)として報告します。

タッチスクリーンが生成した個々のイベントのほとんどは、他のイベントのより大きなシーケンスの一部としての意味しかもっていません。たとえばタッチスクリーンをタップするという単純な操作はユーザーがタッチスクリーンに指を置いて離すという操作、ディスプレイをスクロールためのスワイプはタッチスクリーンに指を置いて何度も上(下)に動かしてから指を離すという操作を引き起こすのです。

タップやスクロールにたいしては一本の指で構成される単純なモデルで十分ですが、より複雑なジェスチャーには複数の指を追跡するためのサポートが要求されまづ。指が複数の場合には、それぞれの指の位置はタッチポイント(touch point)によって表されることになります。たとえば“ズームするためのピンチアウト”というジェスチャーは、ユーザーが指を2本置いて、それらの指を別個に反対方向へ動かすことから構成されます。ここでこれら2本の指による個別のポイント位置の間の距離によってディスプレイのズーム量、これらの位置を結ぶ想像上の線の中央位置によってズーム後にどこにディスプレイをパンする(振る)かが決まります。

下記の低レベルなタッチスクリーンイベントを使って、上述したタッチシーケンスすべてを実装できます。これらのイベントでは、ポイントはそれぞれポイントを識別する任意の番号、およびイベント発生時の指の位置を指定するマウス位置リスト(クリックイベントを参照)のコンスセルによって表現されます。

(touchscreen-begin point)

これはユーザーがタッチスクリーンにたいして指を押すことでpointが作成されたときに送信されるイベント。

(touchscreen-update points)

これはタッチスクリーン上のポイントの位置が変更されたときに送信されるイベント。pointsはカレントでタッチスクリーン上にあるタッチポイントの最新位置を含んだタッチポイントのリスト。

(touchscreen-end point)

これは他のプログラムにより奪われたりユーザーがタッチスクリーンから指を離したことによってpointがディスプレイ上に存在しなくなった際に送信されるイベント。


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

22.7.10 フォーカスイベント

ウィンドウシステムはユーザーにたいしてどのウィンドウがキーボード入力を受け取るか制御するための一般的な方法を提供します。このウィンドウ選択はフォーカス(focus)と呼ばれます。Emacsのフレームを切り替えるためにユーザーが何かを行うと、それはフォーカスイベント(focus event)を生成します。フォーカスイベントの通常の定義はグローバルキーマップ内にあり、ユーザーが期待するようにEmacsで新たなフレームを選択するためのものです。入力のフォーカスではフォーカスイベントに関連するフックも説明しています。

フォーカスイベントは以下のようにLispのリストで表現されます:

(switch-frame new-frame)

ここでnew-frameは切り替え先のフレームです。

Xウィンドウマネージャーには、あるウィンドウにマウスを移動するだけで、そこにフォーカスされるようにセットアップするものがいくつかあります。通常は他の種類の入力が到着するまで、Lispプログラムがフォーカスの変更を知る必要はありません。Emacsはユーザーが新たなフレーム内で実際にキーボードのキーをタイプするかマウスボタンを押下したときしか、フォーカスイベントを生成しません。つまりフレーム間でマウスを移動させても、フォーカスイベントは生成されません。

キーシーケンスの途中におけるフォーカスイベントは、そのシーケンスを誤ったものにするかもしれません。そのためEmacsは決してキーシーケンスの途中でフォーカスイベントを生成しません。ユーザーがキーシーケンスの途中(つまりプレフィクス引数の後)でフォーカスを変更すると、複数イベントキーシーケンスの前か後にフォーカスイベントが到着するように、Emacsはフォーカスイベントを記録しておきます。


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

22.7.11 Xwidgetイベント

Xwidgetsは自身の状態によってLispプログラムを更新するためにイベントを送信することができます。(埋め込みネイティブウィジェットを参照)。これらのイベントはxwidget-eventsという、変更の性質を説明するさまざまなデータを含んだイベントに置き換えられます。

(xwidget-event kind xwidget arg)

これはxwidgetである種の更新が発生した際は常に送信されるイベント。更新には複数の種類があり、それらはkindによって識別される。

これはxwidgetにたいするxwidgetイベントを受信した際は常に呼び出されるようなコールバック(callback)をxwidgetに追加することによって処理する必要があるスペシャルイベントである(スペシャルイベントを参照)。

コールバックは引数としてxwidgetkindを受け取る関数であること。コールバックはwidgetのプロパティリストのcallbackをセットすることによって追加できる。

load-changed

これはxwidgetがページローディングプロセスの特定のポイントに達したことを示すxwidgetイベント。argにはこれらのイベントが送信される際には、widgetの状態が更に記述された文字列が含められる。

load-started

これはそのwidgetがページローディング操作を開始したことを意味する。

load-finished

これはxwidgetが前に処理していたページローディング操作が何であれ処理が終了したことを意味する。

load-redirected

これはxwidgetがページローディング操作中にリダイレクトに遭遇して、それをフォローしたことを意味する。

load-committed

これはxwidgetがページローディング操作中に与えられたURLにコミット(つまりそのURLがカレントのページローディング操作中にレンダリングする最終URL)したことを意味する。

download-callback

このイベントはある種のダウンロードが完了したことを示す。

上記イベントではargの後に引数があるかもしれない。その引数自体はダウンロードしたファイルを取得したURLを示す。argの後の1つ目の引数はそのダウンロードのMIMEタイプ(文字列)を示し、2つ目の引数はダウンロードしたファイルの完全なファイル名が含まれる。

download-started

このイベントはダウンロードが開始したことを示す。これらのイベントにおいて、argにはカレントでダウンロードされるファイルのURLが含まれる。

javascript-callback

このイベントにはJavaScriptのコールバックデータが含まれる。これらのイベントはxwidget-webkit-execute-scriptによって内部的に使用される。

(xwidget-display-event xwidget source)

このイベントはxwidgetが他のxwidgetの表示をリクエストした際は常に送信される。xwidgetは表示されることになるxwidget、sourcexwidgetの表示を要求したxwidget。

これはコールバックを通じて処理を要するスペシャルイベントでもある。そのようなコールバックは引数としてxwidgetsourceを受け取る関数であり、sourceのプロパティリストのdisplay-callbackにセットして追加できる。

xwidgetのバッファーは一時バッファーにセットされる。widget表示の際には、set-xwidget-buffer (埋め込みネイティブウィジェットを参照)を使用してバッファーをxwidgetが表示されるバッファーに置き換えるよう注意すること。


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

22.7.12 その他のシステムイベント

他にもシステム内での出来事を表現するイベント型がいくつかあります。

(delete-frame (frame))

このイベントの種類はユーザーがウィンドウマネージャーに特定のウィンドウを削除するコマンドを与えたことを示し、Emacsのフレームにたいして発生する。

フレーム削除(delete-frame)イベントの標準的な定義ではframeが削除される。

(iconify-frame (frame))

このイベントの種類はウィンドウマネージャーを使用してユーザーがframeをアイコン化したことを示す。標準的な定義はignore。これはそのフレームがすでにアイコン化されているので、Emacsが行う必要のことは何もないからである。このイベント型の目的は、望むならこのようなイベントの追跡を可能にしておくためである。

(make-frame-visible (frame))

このイベントの種類はウィンドウマネージャーを使用してユーザーがframeを非アイコン化したことを示す。標準的な定義はignore。これは、そのフレームがすでに可視化されているので、Emacsが行う必要のことは何もないからである。

(touch-end (position))

この種のイベントはユーザーの指がマウスホイールやタッチパッドから離れたことを示す。マウス位置リストのposition要素(クリックイベントを参照)は、マウスホイールから指が離れた際のマウスカーソルの位置を指定する。

(wheel-up position clicks lines pixel-delta)
(wheel-down position clicks lines pixel-delta)

この種類のイベントはマウスホイールを動かすことによって発生する。position要素はそのイベント発生時のマウスカーソル位置を指定するマウス位置リスト(クリックイベントを参照)。

clicksが与えられた場合には、ホイールが連続して素早く動いた回数を示す。リピートイベントを参照のこと。linesが与えられて、それがnilでなければ、それはスクロールされるべきスクリーン行の行数である。pixel-deltaが与えられた場合には、それが(x . y)という形式のコンスセルであれば、xyはそれぞれの軸方向にたいしてスクロールされたピクセル数、いわゆるピクセル単位デルタ(pixelwise delta)である。

これらのピクセル単位デルタxyを用いれば、マウスホイールがピクセル解像度で実際にどれだけ動いたかを判断できる。たとえばピクセル単位デルタを使うことによって、ユーザーが回したマウスホイールとまったく同じようにディスプレイをスクロールできるだろう。

この種類のイベントはある種のシステムでのみ発生する。いくつかのシステムでは、かわりにmouse-4mouse-5が使用される。可搬性のあるコードとするためには、マウスホイールにたいしてどのイベント型が期待されるかを決定するために、mwheel.el内で定義されている変数mouse-wheel-up-eventmouse-wheel-up-alternate-eventmouse-wheel-down-eventmouse-wheel-down-alternate-eventを使用すること。

同様にmouse-wheel-left-eventmouse-wheel-right-eventを生成できる一部のマウスでは、mouse-wheel-tilt-scrollが非mouse-wheel-tilt-scrollならこれらをスクロールに使用できる。ただしこれらのスクロールイベントと同時に別のイベントをも生成するマウスもいくつかあり、邪魔をするかもしれない。この問題を解決するにはこれらのイベントにたいするバインドを削除する方法が一般的である(たとえばmouse-6mouse-7等を削除するがバインドはハードウェアとオペレーティングシステムに大きく依存する)。

(pinch position dx dy scale angle)

この種のイベントはタッチパッドに指を2本置いてそれらを互いに近づけたり離したりする、“ピンチ(pinch)”というジェスチャーをユーザーが行った際に生成される。positionはイベント発生時のマウスポインターの位置を提供するマウス位置リスト(クリックイベントを参照)、dxは同一シーケンス内の最後のイベントから2本の指の間の水平距離の変分、dyは同じく垂直距離の変分、scaleはこのシーケンス開始時の2本の指の間の距離とカレント距離の比率、angleはこのイベントで指と指をつなぐ線分の方向と同一シーケンスの最後のイベントにおける同線分方向との間の角度差(degree)である。

ピンチイベントが送信されるのはピンチシーケンスの開始かその間だけであり、ユーザーがタッチパッド置いた2本の指をピンチではなく回転(rotate)させるように動かすジェスチャーは報告されない。

positionの後の引数はすべて浮動小数点数。

これはユーザーがタッチパッドに2本の指を置いたときが開始、指を離したときに終了するイベントであり、通常はあるシーケンスの一部として送信される。先頭のイベントではdxdyangle0.0になる。後続するイベントではこのイベント構造のこれらのメンバーにたいしては非0値が報告されるだろう。

dxdy1.0がそれぞれタッチパッドの幅と高さに相当するような想像上の相対的単位として報告される。これらは通常はジェスチャーの下にあるイメージやウィンドウ等のオブジェクトサイズに相対的なものと解釈される。

(preedit-text arg)

これは何が挿入されるかをユーザーに示すために、システムのインプットメソッドがEmacsに何らかのテキストを表示するよう伝える際に送信されるイベント。argの内容は使用中のウィンドウシステムに依存する。

Xではargはカーソルの向こうに配置するテキストを記述する文字列。nilなら前に表示していたすべてのテキストの削除を意味する。

PGTKフレーム(フレームを参照)では、argはカラーとアンダーラインの属性に関する情報をもつ文字列リスト。以下の形式をもつ:

   ((string1
     (ul . underline-color)
     (bg . background-color)
     (fg . foreground-color))
    (string2
     (ul . underline-color)
     (bg . background-color)
     (fg . foreground-color))
    …
   )

文字列に関するテキストを残してカラーの情報は省略可。underline-colortならテキストのアンダーラインがデフォルトのアンダーラインカラーになること、文字列ならそのカラー名によってアンダーラインが描画されることを意味する。

これは通常ならユーザーがコマンドにバインドするべきではないスペシャルイベントである(スペシャルイベントを参照)。Emacsは通常はこのイベントを受信すると、ポインター背後にあるオーバーレイにイベントに含まれるテキストを表示する。

(drag-n-drop position files)

この種類のイベントはEmacs外部アプリケーション内でファイルグループが選択されて、それがEmacsフレーム内にドラッグアンドドロップされたときに発生する。

要素positionは、そのイベント位置を記述しマウスクリックイベントで使用されるフォーマット(クリックイベントを参照)と同じ。要素filesはドラッグアンドドロップされたファイル名のリスト。通常はそれらのファイルをvisitすることによってこのイベントは処理される。

この種類のイベントは現在のところある種のシステムでのみ生成される。

help-echo

この種類のイベントは、テキストプロパティhelp-echoをもつバッファーテキスト部分上にマウスポインターが移動したときに生成される。生成されるイベントは以下の形式をもつ:

(help-echo frame help window object pos)

イベントパラメーターの正確な意味とヘルプテキストを表示するためにこれらのパラメーターを使用する方法は、Text help-echoで説明されている。

sigusr1
sigusr2

これらのイベントはEmacsプロセスがシグナルSIGUSR1SIGUSR2を受け取ったときに生成される。シグナルは追加情報を運搬しないので追加データは含まれない。これらのシグナルはデバッグに有用(エラーによるデバッガへのエンターを参照)。

ユーザーシグナルをcatchするためには、special-event-map (アクティブなキーマップの制御を参照)内で対応するイベントにバインドする。そのコマンドは引数なしで呼び出され、last-input-event内の特定のシグナルイベントが利用できる(その他のイベント入力の機能を参照)。たとえば:

(defun sigusr-handler ()
  (interactive)
  (message "Caught signal %S" last-input-event))

(keymap-set special-event-map "<sigusr1>" 'sigusr-handler)

シグナルハンドラーをテストするために、自身でEmacsにシグナルを送信できる:

(signal-process (emacs-pid) 'sigusr1)
language-change

この種類のイベントはMS-Windows上で入力言語が変更されたときに生成される。これは通常はキーボードキーが異なる言語の文字でEmacsに送られることを意味する。生成されるイベントは以下の形式をもつ:

(language-change frame codepage language-id)

ここでframeは言語が変更されたときカレントだったフレーム、codepageは新たなコードページ番号(codepage number)、language-idは新たな入力言語の数値IDである。codepageに対応するコーディングシステム(コーディングシステムを参照)は、cpcodepagewindows-codepagelanguage-idを文字列に変更する(たとえばset-language-environmentのようなさまざまな言語依存機能にたいしこれを使用する)には、以下のようにw32-get-locale-info関数を使用する:

;; 英語にたいする"ENU"のような言語の省略形を取得する
(w32-get-locale-info language-id)
;; "English (United States)"のような
;; その言語の完全な英語名を取得する
(w32-get-locale-info language-id 4097)
;; その言語の完全なローカライズ名を取得する
(w32-get-locale-info language-id t)
end-session

このイベントはMS-Windowsにおいてユーザーがインタラクティブなセッションを終了したとき、またはシステムがシャットダウンすることをオペレーティングシステムがEmacsに知らせる際に生成される。このイベントの標準的な定義では、秩序に則ってEmacsをシャットダウンできるようにkill-emacsコマンドを呼び出す(Emacsのkillを参照)。未保存の変更が存在する場合には、ユーザーが後で未保存の変更をリストアするセッションの再起動に使用できるauto-saveファイルを生成する(自動保存を参照)。

キーシーケンスの途中、つまりプレフィクスキーの後にこれらのイベントの1つが到着すると、複数イベントキー内ではなくその前か後にそのイベントが到着するようにEmacsはそのイベントを記録する。

いくつかのdelete-frameのようなスペシャルイベントは、デフォルトではEmacsコマンドを呼び出します(他のイベントはバインドされない)。special-event-mapを通じて、あるスペシャルイベントがコマンドを呼び出すようにすることができます。このマップでファンクションキーにバインドしたコマンドは、last-input-event内でそれが呼び出された完全なイベントを調べることができます。スペシャルイベントを参照してください。


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

22.7.13 イベントの例

ユーザーが同じ場所でマウス左ボタンを押して離すと、それは以下のようなイベントシーケンスを生成します:

(down-mouse-1 (#<window 18 on NEWS> 2613 (0 . 38) -864320))
(mouse-1      (#<window 18 on NEWS> 2613 (0 . 38) -864180))

コントロールキーを押したままユーザーがマウス第2ボタンを押してマウスをある行から次の行へドラッグすると、以下のような2つのイベントが生成されます:

(C-down-mouse-2 (#<window 18 on NEWS> 3440 (0 . 27) -731219))
(C-drag-mouse-2 (#<window 18 on NEWS> 3440 (0 . 27) -731219)
                (#<window 18 on NEWS> 3510 (0 . 28) -729648))

メタキーとシフトキーを押したままユーザーがそのウィンドウのモードライン上でマウス第2ボタンを押して他ウィンドウへマウスをドラッグすると、以下のようなイベントのペアが生成されます:

(M-S-down-mouse-2 (#<window 18 on NEWS> mode-line (33 . 31) -457844))
(M-S-drag-mouse-2 (#<window 18 on NEWS> mode-line (33 . 31) -457844)
                  (#<window 20 on carlton-sanskrit.tex> 161 (33 . 3)
                   -453816))

全画面表示されていないフレームに入力フォーカスがあってユーザーがマウスをそのフレームのスコープ外へマウスを移動すると、マクロtrack-mouse内では以下のようなイベントが生成されます:

(mouse-movement (#<frame *ielm* 0x102849a30> nil (563 . 205) 532301936))

SIGUSR1シグナルを処理するためにはインタラクティブ関数を定義して、それをsignal usr1イベントシーケンスにバインドします:

(defun usr1-handler ()
  (interactive)
  (message "Got USR1 signal"))
(keymap-global-set "<signal> <usr1>" 'usr1-handler)

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

22.7.14 イベントの分類

すべてのイベントはイベント型(event type)をもっています。イベント型はキーバインディング目的でイベントをクラス分けします。キーボードイベントにたいするイベント型はイベント値と等しく、したがって文字のイベント型は文字、ファンクションキーシンボルのイベント型はそのシンボル自身になります。リストであるようなイベントのイベント型は、そのリストのCAR内のシンボルです。したがってイベント型は常にシンボルか文字です。

同じ型の2つのイベントはキーバインディングに関する限りは同じものです。したがってそれらは常に同じコマンドを実行します。これらが同じことを行う必要があるという意味ではありませんが、イベント全体を調べてから何を行うか決定するコマンドもいくつかあります。たとえばバッファー内でどこに作用するか決定するためにマウスイベントの場所を使用するコマンドもいくつかあります。

広範なイベントのクラス分けが役に立つときもあります。たとえば他の修飾キーやマウスボタンが使用されたかとは無関係に、METAキーとともに呼び出されたイベントを尋ねたいと思うかもしれません。

関数event-modifiersevent-basic-typeは、そのような情報を手軽に取得するために提供されています。

Function: event-modifiers event

この関数はeventがもつ修飾子のリストをリターンする。この修飾子はシンボルでありshiftcontrolmetaalthypersuperが含まれる。さらにマウスイベントシンボルの修飾子リストには常にclickdragdownのいずれか1つが含まれる。ダブルイベントとトリプルイベントには、doubletripleも含まれる。

引数eventはイベントオブジェクト全体、または単なるイベント型かもしれない。eventがカレントEmacsセッション内で入力として読み取られたイベント内で決して使用されないシンボルなら、実際にeventが変更されたときでもevent-modifiersnilをリターンできる。

いくつか例を挙げる:

(event-modifiers ?a)
     ⇒ nil
(event-modifiers ?A)
     ⇒ (shift)
(event-modifiers ?\C-a)
     ⇒ (control)
(event-modifiers ?\C-%)
     ⇒ (control)
(event-modifiers ?\C-\S-a)
     ⇒ (control shift)
(event-modifiers 'f5)
     ⇒ nil
(event-modifiers 's-f5)
     ⇒ (super)
(event-modifiers 'M-S-f5)
     ⇒ (meta shift)
(event-modifiers 'mouse-1)
     ⇒ (click)
(event-modifiers 'down-mouse-1)
     ⇒ (down)

クリックイベントにたいする修飾子リストは明示的にclickを含むが、イベントシンボル名自体には‘click’が含まれない。同じように‘C-a’のようなASCIIコントロール文字にたいする修飾子リストでは、たとえ‘C-a’の修飾ビットを取り除いて値1をリターンするread-charを通じて読み取られたイベントであってもcontrolが含まれる。

Function: event-basic-type event

この関数はeventを記述するキー、またはマウスボタンをリターンする。event引数はevent-modifiersの場合と同様。たとえば:

(event-basic-type ?a)
     ⇒ 97
(event-basic-type ?A)
     ⇒ 97
(event-basic-type ?\C-a)
     ⇒ 97
(event-basic-type ?\C-\S-a)
     ⇒ 97
(event-basic-type 'f5)
     ⇒ f5
(event-basic-type 's-f5)
     ⇒ f5
(event-basic-type 'M-S-f5)
     ⇒ f5
(event-basic-type 'down-mouse-1)
     ⇒ mouse-1
Function: mouse-movement-p object

objectがマウス移動イベントなら、この関数は非nilをリターンする。モーションイベントを参照のこと。


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

22.7.15 マウスイベントへのアクセス

このセクションではマウスボタンやモーションイベント内のデータアクセスに役立つ関数を説明します。同じ関数を使用してキーボードイベントデータにもアクセスできますが、キーボードイベントに不適切なデータ要素は0かnilになります。

以下の2つの関数は、マウスイベントの位置を指定するマウス位置リスト(クリックイベントを参照)をリターンします。

Function: event-start event

これはeventの開始位置をリターンする。

eventがクリックイベントかボタンダウンイベントなら、この関数はそのイベントの位置をリターンする。eventがドラッグイベントなら、そのドラッグの開始位置をリターンする。

Function: event-end event

これはeventの終了位置をリターンする。

eventがドラッグイベントなら、この関数はユーザーがマウスボタンをリリースした位置をリターンする。eventがクリックイベントかボタンダウンイベントなら、値はそのイベント固有の開始位置となる。

Function: posnp object

この関数はobjectが(クリックイベントに記述されたフォーマットの)マウス位置リストなら非nil、それ以外ではnilをリターンする。

以下の関数は引数にマウス位置リストを受け取り、そのリストのさまざまな部分をリターンします:

Function: posn-window position

positionがあったウィンドウをリターンする。positionが最初にイベントがあったフレームの外部の位置を表す場合には、かわりにそのフレームをリターンする。

Function: posn-area position

position内に記録されたウィンドウエリアをリターンする。そのウィンドウのテキストエリアでイベントが発生したときはnil、それ以外ではイベントがどこで発生したかを識別するシンボルをリターンする。

Function: posn-point position

position内のバッファー位置をリターンする。ウィンドウのテキストエリア、マージンエリア、フリンジでイベントが発生したときはバッファー位置を識別する整数値、それ以外では値は未定義。

Function: posn-x-y position

position内のピクセル単位のxy座標を、コンスセル(x . y)でリターンする。これらはposn-windowにより与えられるウィンドウにたいする相対座標である。

以下はあるウィンドウのテキストエリア内のウィンドウ相対座標をフレーム相対座標に変換する方法を示す例:

(defun frame-relative-coordinates (position)
  "POSITIONのフレーム相対座標をリターンする。
POSITIONはウィンドウのテキストエリアにあるものとする。"
  (let* ((x-y (posn-x-y position))
         (window (posn-window position))
         (edges (window-inside-pixel-edges window)))
    (cons (+ (car x-y) (car edges))
          (+ (cdr x-y) (cadr edges)))))
Function: posn-col-row position &optional use-window

この関数はpositionで記述されるのバッファー位置で推定される列と行を含むコンスセル(col . row)をリターンする。リターン値はpositionにたいするxyの値より計算され、そのフレームのデフォルト文字幅とデフォルト行高(行間スペースを含む)の単位で与えられる(そのため実際の文字サイズが非デフォルト値の場合には、実際の行と列は計算された値とは異なるかもしれない)オプションの。window引数が非nilの場合には、フレームではなくpositionで示されるウィンドウのデフォルト文字幅を使用する(これはたとえば非デフォルトのズームレベルでバッファーを表示しているウィンドウで違いが生じる)。

rowはそのテキストエリアの上端から数えられることに注意。positionにより与えられるウィンドウがヘッダーライン(ウィンドウのヘッダーラインを参照)やタブラインをもつなら、それらはrowの数に含まれない

Function: posn-actual-col-row position

position内の実際の行と列をコンスセル(col . row)でリターンする。値はposition与えられるウィンドウの実際の行と列。クリックイベントを参照のこと。positionが実際のポジション値を含まなければ、この関数はnilをリターンする。この場合にはおおよその値を取得するためにposn-col-rowを使用できる。

この関数はタブ文字やイメージによるビジュアル列数のように、ディスプレイ上の文字のビジュアル幅を意味しない。標準的な文字単位の座標が必要なら、かわりにposn-col-rowを使用すること。

Function: posn-string position

positionに記述された文字列オブジェクトをリターンする。nil (positionがバッファーテキストを記述することを意味する)、またはコンスセル(string . string-pos)のいずれか。

Function: posn-image position

positionにあるイメージオブジェクトをリターンする。nil (positionにイメージがない)、またはイメージspec (image …)のいずれか。

Function: posn-object position

positionにより記述されるイメージオブジェクトか文字列オブジェクトをリターンする。nil (positionがバッファーテキストを記述することを意味する)、イメージ(image …)、またはコンスセル(string . string-pos)のいずれか。

Function: posn-object-x-y position

positionで記述されるオブジェクトの左上隅からのピクセル単位のxy座標を、コンスセル(dx . dy)でリターンする。positionがバッファーテキストを記述する場合には、その位置にもっとも近いバッファーテキストの相対位置をリターンする。

Function: posn-object-width-height position

positionで記述されるオブジェクトのピクセル幅とピクセル高さを、コンスセル(width . height)でリターンする。positionがバッファー位置を記述する場合には、その位置の文字のサイズをリターンする。

Function: posn-timestamp position

positionのタイムスタンプをリターンする。これはミリ秒で表したイベント発生時刻である。このようなタイムスタンプは使用しているウィンドウシステムに応じてさまざまに異なる任意の開始時刻からの相対時刻として報告される。たとえばXウィンドウシステムでは、そのXサーバー開始から経過したミリ秒数となる。

以下の関数は与えられた特定のバッファー、またはスクリーン位置によって位置リストを計算します。上述の関数でこの位置リスト内のデータにアクセスできます。

Function: posn-at-point &optional pos window

この関数はwindow内の位置posにたいする位置リストをリターンする。posのデフォルトはwindow内のポイント、windowのデフォルトは選択されたウィンドウ。

window内でposが不可視なら、posn-at-pointnilをリターンする。

Function: posn-at-x-y x y &optional frame-or-window whole

この関数は指定されたフレームかウィンドウframe-or-window(デフォルトは選択されたウィンドウ)内のピクセル座標xyに対応する位置情報をリターンする。xyは、選択されたウィンドウのテキストエリアにたいする相対座標である。wholeが非nilなら、x座標はスクロールバー、マージン、フリンジを含むウィンドウエリア全体にたいする相対座標。


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

22.7.16 スクロールバーイベントへのアクセス

以下の関数はスクロールバーイベントの解析に役立ちます。

Function: scroll-bar-event-ratio event

この関数はスクロールバーで発生したスクロールバーイベントの位置の垂直位置の割り合いをリターンする。値は位置の割り合いを表す2つの整数を含むコンスセル(portion . whole)

Function: scroll-bar-scale ratio total

この関数は、(実質的には)ratiototalを乗じて、結果を整数に丸める。引数ratioは数字ではなく、scroll-bar-event-ratioによってリターンされる典型的な値ペア(num . denom)である。

この関数はスクロールバー位置をバッファー位置にスケーリングするのに有用。以下のように行う:

(+ (point-min)
   (scroll-bar-scale
      (posn-x-y (event-start event))
      (- (point-max) (point-min))))

スクロールバーイベントは、xy座標ペアのかわりに割り合いを構成する2つの整数をもつことを思い出してほしい。


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

22.7.17 文字列内へのキーボードイベントの配置

文字列が使用される場所のほとんどにおいて、わたしたちはテキスト文字を含むもの、つまりバッファーやファイル内で見出すのと同種のものとして文字列を概念化します。Lispプログラムはときおりキーボード文字、たとえばキーシーケンスやキーボードマクロ定義かもしれないキーボード文字を概念的に含んだ文字列を使用します。しかし文字列内へのキーボード文字の格納は、歴史的な互換性の理由から複雑な問題であり、常に可能なわけではありません。

新たに記述するプログラムでは文字列内にコントロール文字類を含むキーボードイベントを格納せずに、key-valid-pが理解できるEmacsの一般形式で格納することを推奨する。

read-key-sequence-vector(あるいはread-key-sequence)でキーシーケンスを読み取ったり、this-command-keys-vector(あるいはthis-command-keys)でキーシーケンスにアクセスする場合には、key-descriptionを使用することでキーシーケンスを推奨フォーマットに変換することができます。

複雑さはキーボード入力に含まれるかもしれない修飾ビットに起因します。メタ修飾以外の修飾ビットは文字列に含めることができず、メタ文字も特別な場合だけ許容されます。

GNU Emacsの初期のバージョンでは、メタ文字を128から255のコードで表していました。その頃は基本的な文字コードの範囲は0から127だったので、すべてのキーボード文字を文字列内に適合させることができました。Lispプログラムの多くは、特にdefine-keyやその種の関数の引数として文字列定数内にメタ文字を意味する‘\M-’を使用していて、キーシーケンスとイベントシーケンスは常に文字列として表現されていました。

127超のより大きい基本文字コードと追加の修飾ビットにたいするサポートを加えたとき、わたしたちはメタ文字の表現を変更する必要がありました。現在では文字のメタ修飾を表すフラグは 2**27 であり、そのような値は文字列内に含めることができません。

プログラムで文字列定数内の‘\M-’をサポートするために、文字列内に特定のメタ文字を含めるための特別なルールがあります。以下は入力文字シーケンスとして文字列を解釈するためのルールです:

  • キーボード文字の値の範囲が0から127なら、文字列を変更せずに含めることができる。
  • これらの 2**27 から 2**27+127, までの文字のコード範囲にあるメタ修飾された変種も文字列に含めることができるが、それらの数値を変更しなければならない。値が128から255の範囲となるように、ビット 2**7 のかわりにビット 2**27 をセットしなければならない。ユニバイト文字列だけがこれらの文字を含むことができる。
  • 265を超える非ASCII文字はマルチバイト文字に含めることができる。
  • その他のキーボード文字イベントは文字列に適合させられない。これには128から255の範囲のキーボードイベントが含まれる。

キーボード入力文字の文字列定数を構築するread-key-sequenceのような関数は、イベントが文字列内に適合しないときは文字列のかわりにベクターを構築するというルールにしたがいます。

文字列内で入力構文‘\M-’を使用すると、それは128から255の範囲のコード、つまり対応するキーボードイベントを文字列内に配すために変更するとき取得されるのと同じコードが生成されます。したがって文字列内のメタイベントは、それが文字列内にどのように配置されたかと無関係に一貫して機能します。

しかしほとんどのプログラムはこのセクションの冒頭の推奨にしたがって、これらの問題を避けたほうがよいでしょう。


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

22.8 入力の読み取り

エディターコマンドループはキーシーケンスの読み取りに関数read-key-sequenceを使用して、この関数はread-eventを使用します。イベント入力にたいしてこれらの関数、およびその他の関数がLisp関数から利用できます。一時的な表示momentary-string-display、および時間の経過や入力の待機sit-forも参照してください。端末の入力モードの制御、および端末入力のデバッグに関する関数と変数については、端末の入力を参照してください。

高レベル入力機能についてはミニバッファーを参照してください。


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

22.8.1 キーシーケンス入力

コマンドループはread-key-sequenceを呼び出すことによって、キーシーケンスの入力を一度に読み取ります。Lisp関数もこの関数を呼び出すことができます。たとえばdescribe-keyはキーを記述するためにこの関数を使用します。

Function: read-key-sequence prompt &optional continue-echo dont-downcase-last switch-frame-ok command-loop

この関数はキーシーケンスを読み取って、それを文字列かベクターでリターンする。この関数は完全なキーシーケンスに蓄積されるまで、つまりカレントでアクティブなキーマップを使用してプレフィクスなしでコマンドを指定するのに十分なキーシーケンスとなるまでイベントの読み取りを継続する(マウスイベントで始まるキーシーケンスは、カレントバッファーではなくマウスのあったウィンドウ内のバッファーのキーマップを使用して読み取られることを思い出してほしい)。

イベントがすべて文字で、それらがすべて文字列に適合すれば、read-key-sequenceは文字列をリターンする(文字列内へのキーボードイベントの配置を参照)。それ以外なら文字、シンボル、リストなどすべての種類のイベントを保持できるベクターをリターンする。文字列やベクターの要素は、キーシーケンス内のイベント。

キーシーケンスの読み取りには、そのイベントを変換するさまざまな方法が含まれる。イベントシーケンス変換のためのキーマップを参照のこと。

引数promptはプロンプトとしてエコーエリアに表示される文字列、プロンプトを表示しない場合はnil。引数continue-echoが非nilなら、それは前のキーの継続としてそのキーをエコーすることを意味する。

元となる大文字のイベントが未定義で、それと等価な小文字イベントが定義されていれば、通常は大文字のイベントが小文字のイベントに変換される。引数dont-downcase-lastが非nilなら、それは最後のイベントを小文字に変換しないことを意味する。これはキーシーケンスを定義するときに適している。

引数switch-frame-okが非nilなら、たとえ何かをタイプする前にユーザーがフレームを切り替えたとしても、この関数がswitch-frameを処理すべきではないことを意味する。キーシーケンスの途中でユーザーがフレームを切り替えた場合、またはシーケンスの最初だがswitch-frame-oknilのときにフレームを切り替えた場合、そのイベントはカレントキーシーケンスの後に延期される。

引数command-loopが非nilなら、そのキーシーケンスがコマンドを逐次読み取る何かによって読み取られることを意味する。呼び出し側が1つのキーシーケンスだけを読み取る場合には、nilを指定すること。

以下の例ではEmacsはエコーエリアにプロンプト‘?’を表示して、その後ユーザーがC-x C-fをタイプする。

(read-key-sequence "?")

---------- Echo Area ----------
?C-x C-f
---------- Echo Area ----------

     ⇒ "^X^F"

関数read-key-sequenceはquitを抑制する。この関数による読み取りの間にタイプされたC-gは他の文字と同じように機能し、quit-flagをセットしない。quitを参照のこと。

Function: read-key-sequence-vector prompt &optional continue-echo dont-downcase-last switch-frame-ok command-loop

これはread-key-sequenceと同様だが、キーシーケンスを常にベクターでリターンして、文字列では決してリターンしない点が異なる。文字列内へのキーボードイベントの配置を参照のこと。

入力文字が大文字(またはシフト修飾をもつ)でキーバインディングをもたないものの、等価な小文字はキーバインディングをもつ場合には、read-key-sequenceはその文字を小文字に変換します(この挙動はユーザーオプションtranslate-upper-case-key-bindingsnilにセットして無効にできる)。lookup-keyはこの方法によるcase変換を行わないことに注意してください。

入力を読み取った結果がシフト変換(shift-translation)されていたら、Emacsは変数this-command-keys-shift-translatedに非nil値をセットします。シフト変換されたキーにより呼びだされたときに挙動を変更する必要があるLispプログラムは、この変数を調べることができます。たとえば関数handle-shift-selectionはリージョンをアクティブ、または非アクティブにするかを判断するためにこの変数の値を調べます(handle-shift-selectionを参照)。

関数read-key-sequenceもマウスイベントのいくつかを変換します。これはバインドされていないドラッグイベントをクリックイベントに変換して、バインドされていないボタンダウンイベントを完全に破棄します。さらにフォーカスイベントとさまざまなウィンドウイベントの再配置も行うため、これらのイベントはキーシーケンス中に他のイベントととも出現することは決してありません。

モードラインやスクロールバーのような、ウィンドウやフレームの特別な箇所でマウスイベントが発生したとき、そのイベント型は特別なことは何も示さずにマウスボタンと修飾キーの組み合わせを通常表すのと同じシンボルになります。ウィンドウの箇所についての情報はイベント内の別のどこか、すなわち座標に保持されています。しかしread-key-sequenceはこの情報を仮想的なプレフィクスキーに変換します。これらはすべてシンボルでありtab-lineheader-linehorizontal-scroll-barmenu-bartab-barmode-linevertical-linevertical-scroll-barleft-marginright-marginleft-fringeright-fringeright-dividerbottom-dividerです。これらの仮想的なプレフィクスキーを使用してキーシーケンスを定義することにより、ウィンドウの特別な部分でのカウスクリックにたいして意味を定義できます。

たとえばread-key-sequenceを呼び出した後にそのウィンドウのモードラインをマウスでクリックすると、以下のように2つのマウスイベントが取得されます:

(read-key-sequence "Click on the mode line: ")
     ⇒ [mode-line
         (mouse-1
          (#<window 6 on NEWS> mode-line
           (40 . 63) 5959987))]
Variable: num-input-keys

この変数の値は、そのEmacsセッション内で処理されたキーシーケンスの数である。これには端末からのキーシーケンスと、実行されるキーボードマクロによって読み取られたキーシーケンスが含まれる。


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

22.8.2 単一イベントの読み取り

read-eventread-charread-char-exclusiveはコマンド入力にたいするもっとも低レベルの関数です。

ミニバッファーを使用して1文字を読み取る関数が必要ならread-char-from-minibufferを使用してください(複数の問いを尋ねるを参照)。

Function: read-event &optional prompt inherit-input-method seconds

この関数はコマンド入力の次のイベントを読み取ってリターンする。必要ならイベントが利用可能になるまで待機する。

リターンされるイベントはユーザーからの直接のイベントかもしれないし、キーボードマクロからのイベントかもしれない。イベントはキーボードの入力コーディングシステム(端末I/Oのエンコーディングを参照)によりデコードされていない。

オプション引数promptが非nilなら、それはエコーエリアにプロンプトとして表示される文字列。 promptnilか文字列‘""’なら、read-eventは入力待ちを示すメッセージを何も表示せず、エコーを行うことによってプロンプトの代用とする。エコーに表示される記述はカレントコマンドに至ったイベントや読み取られたイベント。エコーエリアを参照のこと。

inherit-input-methodが非nilなら、(もしあれば)非ASCII文字の入力を可能にするためにカレントの入力メソッドが採用される。それ以外では、このイベントの読み取りにたいして入力メソッドの処理が無効になる。

cursor-in-echo-areaが非nilの場合、read-eventはカーソルを一時的にエコーエリアの、そこに表示されているメッセージの終端に移動する。それ以外では、read-eventはカーソルを移動しない。

secondsが非nilなら、それは入力を待つ最大秒数を指定する数値である。その時間内に入力が何も到着しなければ、read-eventは待機を終えてnilをリターンする。浮動小数点数secondsは待機する秒の分数を意味する。いくつかのシステムではサポートされるのは整数の秒数だけであり、そのようなシステムではsecondsは切り捨てられる。secondsnilなら、read-eventは入力が到着するのに必要なだけ待機する。

secondsnilならユーザー入力が到着するのを待つ間、Emacsはアイドル状態にあるとみなされる。この期間中にアイドルタイマー — run-with-idle-timer (アイドルタイマーを参照) — を実行できる。しかしsecondsが非nilなら、非アイドル状態は変更されずに残る。read-eventが呼び出されたときEmacsが非アイドルだったら、read-eventの処理を通じて非アイドルのままとなる。Emacsがアイドルだった場合(これはアイドルタイマー内部からその呼び出しが行われた場合に起こり得る)は、アイドルのままとまる。

read-eventがヘルプ文字として定義されたイベントを取得すると、ある状況においてはread-eventがリターンせずに直接イベントを処理することがある。ヘルプ関数を参照のこと。その他のスペシャルイベント(special events)(スペシャルイベントを参照)と呼ばれる特定のイベントもread-eventで直接処理される。

以下はread-eventを呼び出してから右矢印キーを押下したとき何が起こるかの例:

(read-event)
     ⇒ right
Function: read-char &optional prompt inherit-input-method seconds

この関数は文字入力イベントを読み取ってリターンする。ユーザーが文字以外(たとえばマウスクリックやファンクションキー)のイベントを生成した場合には、read-charはエラーをシグナルする。引数はread-eventと同じように機能する。

イベントが修飾子をもつ場合には、Emacsはそれらの解決を試みて対応する文字のコードをリターンする。たとえばユーザーがC-aをタイプすると、関数は文字‘C-a’のASCIIコードである1をリターンする。いくつかの修飾子を文字コードに反映できない場合には、read-charは未解決の修飾子ビットをセットしたままイベントをリターンする。たとえばユーザーがC-M-aをタイプすると、関数は134217729(16進の8000001であり、これはメタ修飾子がセットされた‘C-a’)をリターンする。この値は有効な文字コードではないので、characterpのテストに失敗する(文字コードを参照)。修飾子ビットが削除された文字の復元にはevent-basic-type (イベントの分類を参照)、read-charがリターンした文字イベント内の修飾子をテストするにはevent-modifiersを使用すること。

以下の1つ目の例ではユーザーは文字1(ASCIIコード49)をタイプしている。2つ目の例ではeval-expressionを使用してミニバッファーからread-charを呼び出すキーボード定義を示している。read-charはキーボードマクロの直後の文字1を読み取る。その後にeval-expressionはリターン値をエコーエリアに表示する。

(read-char)
     ⇒ 49

;; M-:を使用して以下を評価するものとする
(symbol-function 'foo)
     ⇒ "^[:(read-char)^M1"
(execute-kbd-macro 'foo)
     -| 49
     ⇒ nil
Function: read-char-exclusive &optional prompt inherit-input-method seconds

この関数は文字入力イベントを読み取ってリターンする。ユーザーが文字イベント以外を生成した場合には、read-char-exclusiveはそれを無視して文字を取得するまで他のイベントを読み取る。引数はread-eventと同じように機能する。リターン値にはread-charのように修飾ビットが含まれるかもしれない。

上記の関数でquitを抑制するものはありません。

Variable: num-nonmacro-input-events

この変数は端末から受信した入力イベント(キーボードマクロにより生成されたイベントは勘定しない)の総数を保持する。

read-key-sequenceと異なり関数read-eventread-charread-char-exclusiveイベントシーケンス変換のためのキーマップで説明した変換を行わないことを強調しておきます。単一キー読み取りでこれらの変換を行う — たとえば端末からファンクションキー(ファンクションキーを参照)、xterm-mouse-modeからマウスイベント(マウスイベントを参照)を読み取る場合 — には関数read-keyを使用してください。

Function: read-key &optional prompt disable-fallbacks

この関数は1つのキーを読み取る。これはread-key-sequenceread-eventの間の中間的な関数である。read-key-sequenceと異なるのは、キーシーケンスではなく単一キーを読み取ることである。read-eventと異なるのは、rawイベントをリターンせずにinput-decode-maplocal-function-key-mapkey-translation-map (イベントシーケンス変換のためのキーマップを参照)に合わせてデコードと変換を行うことである。

引数promptはプロンプトとしてエコーエリアに表示する文字列で、nilはプロンプトを表示しないことを意味する。

引数disable-fallbacksが非nilなら、read-key-sequenceでバインドされないキーにたいする通常のフォールバックロジックは適用されない。これはbutton-downちmulti-clickのイベントは棄却されず、local-function-key-mapkey-translation-mapが適用されないことを意味する。nilまたは指定されなければ、フォールバックの無効化は最後のイベントのダウンキャスト(訳注: 基本イベントから継承イベントへの型変換)となる。

Function: read-char-choice prompt chars &optional inhibit-quit

この関数はcharsのメンバーであるような文字を読み取って1文字をリターンするためにread-from-minibufferを使用する。charsのメンバーではない文字が入力されると、その旨を伝えるメッセージして入力を破棄する。

オプション引数inhibit-quitはデフォルトでは無視されるが、変数read-char-choice-use-read-keyが非nilならこの関数はread-from-minibufferではなくread-keyを使用する。この場合にはinhibit-quitが非nilだと、有効な入力待機中のkeyboard-quitイベントを無視することを意味する。加えてread-char-choice-use-read-keyが非nilの場合には、この関数の呼び出し中にhelp-formに非nil値をバインドすることによって、ユーザーがhelp-char文字を押下した際にhelp-formを評価してその結果を表示、その後は有効な入力文字、あるいはkeyboard-quitの待機を継続する。

Function: read-multiple-choice prompt choices &optional help-string show-help long-form

複数の選択肢のある問いをユーザーに尋ねる。promptはプロンプトとして表示する文字列であること。

choicesは各エントリーの1つ目の要素が入力される文字、2つ目の要素がプロンプトを表示する際にそのエントリーにたいして表示する短い名前であるようなalist(スペースがあれば短縮され得る)であり、3つ目のオプションのエントリーはユーザーがより多くのヘルプを要求した際にヘルプバッファーに表示する長い説明。

オプション引数help-stringが非nilなら、すべてのchoiceをより詳細に記述する文字列であること。これはユーザーが?をタイプした際に、自動生成されたデフォルトの説明のかわりとしてヘルプバッファーに表示される。

オプション引数show-helpが非nilなら、ユーザーが入力する前に即座にヘルプバッファーが表示される。文字列ならそれがヘルプバッファーの名前として用いられる。

オプション引数long-formが非nilなら、ユーザーは単一キーではなく(completing-readを使用して)長い形式をタイプして応答する必要がある。この応答はリストchoicesの2つ目の要素内に存在しなければならない。

リターン値はchoicesのマッチする値。

(read-multiple-choice
 "Continue connecting?"
 '((?a "always" "Accept certificate for this and future sessions.")
   (?s "session only" "Accept certificate this session only.")
   (?n "no" "Refuse to use certificate, close connection.")))

グラフィカル端末で名前文字列にマッチする文字をハイライトするためにread-multiple-choice-faceフェイスが使用される。


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

22.8.3 入力イベントの変更と変換

Emacsはextra-keyboard-modifiersに合わせて読み取ったすべてのイベントを変更してread-eventからリターンする前に、(もし適切なら)keyboard-translate-tableを通じてそれを変換します。

Variable: extra-keyboard-modifiers

この変数はLispプログラムにキーボード上の修飾キーを“押下”させる。値は文字。文字の修飾子だけが対象となる。ユーザーがキーボードのキーを押下するたびに、その修飾キーがすでに押下されたかのように処理される。たとえばextra-keyboard-modifiers?\C-\M-aにバインドすると、このバインディングのスコープ内にある間、すべてのキーボード入力文字はコントロール修飾とメタ修飾を適用されるだろう。文字?\C-@は0と等価なので、この目的にたいしてはコントロール文字として勘定されないが、修飾無しの文字として扱われる。したがってextra-keyboard-modifiersを0にセットすることによって、すべての修飾をキャンセルできる。

ウィンドウシステムを利用していれば、この方法によってプログラムが任意の修飾キーを押下できる。それ以外ではCTLMETAのキーだけを仮想的に押下できる。

この変数は実際にキーボードに由来するイベントだけに適用され、マウスイベントやその他のイベントには効果がないことに注意。

Variable: keyboard-translate-table

この端末ローカルな変数はキーボード文字にたいする変換テーブルである。これによりコマンドバインディングを変更することなく、キーボード上のキーを再配置できる。値は通常は文字テーブル、またはnil(文字列かベクターも指定できるが時代遅れとされている)。

keyboard-translate-tableが文字テーブル(文字テーブルを参照)なら、キーボードから読み取られた各文字はその文字テーブルを調べる。非nilの値が見つかったら実際の入力文字のかわりにそれを使用する。

この変換は文字が端末から読み取られた後、最初に発生することに注意。recent-keysのような記録保持機能や文字を記録するdribbleファイルは、この変換の後に処理される。

さらにこの変換は入力メソッド(入力メソッドを参照)に文字を提供する前に行われることにも注意。入力メソッド処理の後に文字を変換したいならtranslation-table-for-input (文字の変換を参照)を使用すること。

Function: key-translate from to

この関数は文字コードfromを文字コードtoに変換するためにkeyboard-translate-tableを変更する。 必要ならキーボード変換テーブルを作成する。

以下はC-xでカット、C-でコピー、C-vでペーストを処理するようにkeyboard-translate-tableを使用する例:

(key-translate "C-x" "<control-x>")
(key-translate "C-c" "<control-c>")
(key-translate "C-v" "<control-v>")
(keymap-global-set "<control-x>" 'kill-region)
(keymap-global-set "<control-c>" 'kill-ring-save)
(keymap-global-set "<control-v>" 'yank)

拡張ASCII入力をサポートするグラフィカルな端末上では、シフトキーとともにタイプすることによって、標準的なEmacsにおける意味をこれらの文字から依然として取得することが可能です。これはキーボード変換が関与する文字とは異なりますが、それらは通常と同じ意味をもちます。

read-key-sequenceのレベルでイベントシーケンスを変換するメカニズムについては、イベントシーケンス変換のためのキーマップを参照してください。


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

22.8.4 入力メソッドの呼び出し

イベント読み取り関数は、もしあればカレント入力メソッドを呼び出します(入力メソッドを参照)。input-method-functionの値が非nilなら関数を指定します。read-eventが修飾ビットのないプリント文字(SPCを含む)を読み取ったときは、その文字を引数としてその関数を呼び出します。

Variable: input-method-function

これが非nilなら、その値はカレントの入力メソッド関数を指定する。

警告: この変数をletでバインドしてはならない。この変数はバッファーローカルであることが多く、入力の前後(これは正にあなたがバインドするであろうタイミングである)でバインドすると、Emacsが待機中に非同期にバッファーを切り替えた場合に、誤ったバッファーに値がリストアされてしまう。

入力メソッド関数は入力として使用されるイベントのリストをリターンするべきです(このリストがnilなら、それは入力がないことを意味するのでread-eventは他のイベントを待機する)。これらのイベントはunread-command-events (その他のイベント入力の機能を参照)内のイベントの前に処理されます。入力メソッドによってリターンされるイベントは、たとえそれらが修飾ビットのないプリント文字であっても再度入力メソッドに渡されることはありません。

入力メソッド関数がread-eventread-key-sequenceを呼び出したら、再帰を防ぐために最初にinput-method-functionnilにバインドするべきです。

キーシーケンスの2つ目および後続のイベントを読み取るときは、入力メソッド関数は呼び出されません。したがってそれらの文字は入力メソッドの処理対象外です。入力メソッド関数はoverriding-local-mapoverriding-terminal-local-mapの値をテストするべきです。これらの変数のいずれかが非nilなら入力メソッドは引数をリストにputして、それ以上の処理を行わずにそのリストをリターンするべきです。


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

22.8.5 クォートされた文字の入力

ユーザーが手軽にコントロール文字やメタ文字、リテラルや8進文字コードを指定できるように文字の指定をもとめることができます。コマンドquoted-insertはこの関数を使用しています。

Function: read-quoted-char &optional prompt

この関数はread-charと同様だが、最初に読み取った文字が8進数(0–7)なら任意の個数の8進数(8進数以外の文字を見つけた時点でストップする)を読み取って、その文字コードにより表される文字をリターンする。8進シーケンスを終端させた文字がRETならそれは無視される。他の終端文字はこの関数がリターンした後の入力として使用される。

最初の文字の読み取り時にはquitは抑制されるので、ユーザーははC-gを入力できる。quitを参照のこと。

promptが与えられたら、それはユーザーへのプロンプトに使用する文字列を指定する。プロンプト文字列はその後に1つの‘-’とともに常にエコーエリアに表示される。

以下の例ではユーザーは8進数の177(10進数の127)をタイプしている。

(read-quoted-char "What character")

---------- Echo Area ----------
What character 1 7 7-
---------- Echo Area ----------

     ⇒ 127

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

22.8.6 その他のイベント入力の機能

このセクションではイベントを使い切らずに先読みする方法と、入力の保留や保留の破棄の方法について説明します。パスワードの読み取りの関数read-passwdも参照してください。

Variable: unread-command-events

この変数はコマンド入力として読み取り待機中のイベントのリストを保持する。イベントはこのリスト内の出現順に使用され、使用されるごとにリストから取り除かれる。

ある関数がイベントを読み取ってそれを使用するかどうか決定する場合がいくつかあるためにこの変数が必要になる。この変数にイベントを格納するとコマンドループやコマンド入力を読み取る関数によってイベントは通常のように処理される。

たとえば数引数を実装する関数は、任意の個数の数字を読み取る。数字イベントが見つからないとき、関数はそのイベントを読み戻す(unread)ので、そのイベントはコマンドループによって通常通り読み取られることができる。同様にインクリメンタル検索は、検索において特別な意味をもたないイベントを読み戻すためにこの機能を使用する。なぜならそれらのイベントは検索をexitして、通常どおり実行されるべきだからである。

unread-command-eventsにイベントを置くためにキーシーケンスからイベントを抽出するには、listify-key-sequence (以下参照)を使用するのが簡単で信頼のおける方法である。

もっとも最近読み戻したイベントが最初に再読み取りされるように、通常はこのリストの先頭にイベントを追加する。

このリストから読み取ったイベントは、通常はそのイベントが最初に読み取られたときにすでに一度追加されたときのように、カレントコマンドのキーシーケンスに(たとえばthis-command-keysにリターンされたときのように)追加される。フォーム(t . event)の要素はカレントコマンドのキーシーケンスにeventを強制的に追加する。

このリストから読み取った要素は通常は記録保持機能(入力の記録を参照)により記録されるとともに、キーボードマクロ定義の間(キーボードマクロを参照)は記録される。しかし(no-record . event)という形式の要素は、通常は記録されることなくeventが処理される。

Function: listify-key-sequence key

この関数は文字列かベクターのkeyunread-command-eventsにputすることができる個別のイベントのリストに変換する。

Function: input-pending-p &optional check-timers

この関数はコマンド入力がカレントで読み取り可能かどうか判断する。入力が利用可能ならt、それ以外はnilを即座にリターンする。非常に稀だが入力が利用できないときはtをリターンする。

オプション引数check-timersが非nilなら、Emacsは準備ができるとすべてのタイマーを実行する。遅延実行のためのタイマーを参照のこと。

Variable: last-input-event

この変数は最後に読み取られた端末入力イベントがコマンドの一部なのか、それともLispプログラムによる明示的なものなのかを記録する。

以下の例では文字1(ASCIIコード49)をLispプログラムが読み取っている。C-e (C-x C-eは式を評価するコマンドとする)がlast-command-eventに値として残っている間は、それがlast-input-eventの値となる。

(progn (print (read-char))
       (print last-command-event)
       last-input-event)
     -| 49
     -| 5
     ⇒ 49
Macro: while-no-input body…

この構文はbodyフォームを実行して、入力が何も到着しない場合だけ最後のフォームの値をリターンする。bodyフォームを実行する間に何らかの入力が到着したら、それらの入力をabortする(quitのように機能する)。while-no-inputフォームは実際のquitによりabortしたらnil、入力の到着によってabortしたらtをリターンする。

bodyの一部でinhibit-quitを非nilにバインドすると、その部分の間に到着した入力はその部分が終わるまでabortしない。

両方のabort条件をbodyにより計算された可能なすべての値で区別できるようにしたければ、以下のようにコードを記述する:

(while-no-input
  (list
    (progn . body)))
Variable: while-no-input-ignore-events

この変数はwhile-no-inputが無視するべきスペシャルイベントのセッティングを可能にする。これはイベントシンボルのリスト(イベントの例を参照)。

Function: discard-input

この関数は端末入力バッファーの内容を破棄して定義処理中かもしれないキーボードマクロをキャンセルする。この関数はnilをリターンする。

以下の例ではフォームの評価開始直後にユーザーが数字か文字をタイプするかもしれない。sleep-forがスリープを終えた後にdiscard-inputはスリープ中にタイプされた文字を破棄する。

(progn (sleep-for 2)
       (discard-input))
     ⇒ nil

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

22.9 スペシャルイベント

特定のスペシャルイベント(special event)は、読み取られると即座に非常に低レベルで処理されます。read-event関数はそれらのイベントを自身で処理してそれらを決してリターンしません。かわりにスペシャルイベント以外の最初のイベントを待ってそれをリターンします。

スペシャルイベントはエコーされず、決してキーシーケンスにグループ化されず、last-command-event(this-command-keys)の値として出現することもありません。スペシャルイベントは数引数を破棄して、unread-command-eventsによる読み戻しができず、キーボードマクロ内に出現することもなく、キーボードマクロ定義中にキーボードマクロに記録されることもありません。

しかしスペシャルイベントは読み取られた直後にlast-input-event内に出現するので、これがイベント定義にたいして実際のイベントを探す方法になります。

イベント型iconify-framemake-frame-visibledelete-framedrag-n-droplanguage-change、およびsigusr1ようなユーザーシグナルは通常はこの方法によって処理されます。何がスペシャルイベントで、スペシャルイベントをどのように処理するかを定義するキーマップは変数special-event-map (アクティブなキーマップの制御を参照)の中にあります。


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

22.10 時間の経過や入力の待機

待機関数(wait function)は特定の時間が経過するか、入力があるまで待機するようにデザインされています。たとえば計算の途中でユーザーがディスプレイを閲覧できるように一時停止したいときがあるかもしれません。sit-forは一時停止して画面を更新して、sleep-forは画面を更新せずに一時停止して入力が到着したら即座にリターンします。

Function: sit-for seconds &optional nodisp

この関数は、(ユーザーからの保留中入力がければ)再描画を行ってからseconds秒、または入力が利用可能になるまで待機する。sit-forの通常の目的は、表示したテキストをユーザーが読み取る時間を与えるためである。入力が何も到着せず(その他のイベント入力の機能を参照)、時間をフルに待機したらt、それ以外はnilが値となる。

引数secondsは整数である必要はない。浮動小数点数ならsit-forは小数点数の秒を待機する。整数の秒だけをサポートするいくつかのシステムではsecondsは切り捨てられる。

保留中の入力が存在しなければ、式(sit-for 0)は遅延なしで再描画をリクエストする(redisplay)と等価である。強制的な再表示を参照のこと。

nodispが非nilならsit-forは再描画を行わないが、それでも入力が利用可能になると(またはタイムアウト時間が経過すると)即座にリターンする。

batchモード(batchモードを参照)では、たとえ標準入力ディスクリプタからの入力でも割り込みできない。これは以下で説明するsleep-forでも同様。

(sit-for seconds millisec nodisp)のように3つの引数でsit-forを呼び出すことも可能だが、時代遅れだと考えられている。

Function: sleep-for seconds &optional millisec

この関数は表示を更新せず単にseconds秒の間一時停止する。これは利用可能な入力に注意を払わない。この関数はnilをリターンする。

引数secondsは整数である必要はない。浮動小数点数ならsleep-forは小数点数の秒を待機する。整数の秒だけをサポートするいくつかのシステムではsecondsは切り捨てられる。

オプション引数millisecはミリ秒単位で追加の待機時間を指定する。これはsecondsで指定された時間に追加される。システムが小数点数の秒数をサポートしなければ、非0のmillisecを指定するとエラーとなる。

遅延を保証したければsleep-forを使用すること。

現在時刻を取得する関数については時刻を参照してください。


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

22.11 quit

Lisp関数を実行中にC-gをタイプすると、Emacsが何を行っていてもEmacsをquit(中止、終了)させます。これはアクティブなコマンドループの最内に制御がリターンすることを意味します。

コマンドループがキーボード入力の待機中にC-gをタイプしてもquitはしません。これは通常の入力文字として機能します。もっともシンプルなケースでは、通常C-gはquitの効果をもつkeyboard-quitを実行するので区別はできません。しかしプレフィクスキーの後のC-gは、未定義のキー組み合わせになります。これはプレフィクスキーやプレフィクス引数も同様にキャンセルする効果をもちます。

ミニバッファー内ではC-gは異なる定義をもち、それはミニバッファーをabort(失敗、中止、中断)します。これは実際にはミニバッファーをexitしてquitします(単にquitするのはミニバッファー内のコマンドループにリターンするだろう)。C-gがなぜコマンドリーダーが入力読み取り時に直接quitしないかという理由は、ミニバッファー内でのC-gの意味をこの方法によって再定義可能にするためです。プレフィクスキーの後のC-gはミニバッファー内で再定義されておらず、プレフィクスキーおよびプレフィクス引数のキャンセルという通常の効果をもちます。もしC-gが常に直接quitするならこれは不可能でしょう。

C-gが直接quitを行うときは、変数quit-flagtにセットすることによってそれを行います。Emacsは適切なタイミングでこの変数をチェックして、nilでなじぇればquitします。どのような方法でもquit-flagを非nilにセットするとquitが発生します。

Cコードのレベルでは任意の場所でquitを発生させることはできず、quit-flagをチェックする特別な場所でのみquitが発生します。この理由は他の場所でquitすると、Emacsの内部状態で矛盾が生じるかもしれないからです。安全な場所までquitが遅延されるので、quitがEmacsをクラッシュさせることがなくなります。

read-key-sequenceread-quoted-charのような特定の関数は、たとえ入力を待機中でもquitを抑制します。quitするかわりにC-gは要求された入力として処理されます。read-key-sequenceの場合、これはコマンドループ内でのC-gの特別な振る舞いを引き起こすのに役立ちます。read-quoted-charの場合、これはC-gをクォートするのにC-qを使用できるようにします。

変数inhibit-quitを非nil値にバインドすることにより、Lisp関数の一部でquitを抑止できます。その場合はquit-flagtにセットされていても、C-gの通常の結果であるquitは抑止されます。letフォームの最後でこのバインディングがunwindされるなどして、結果としてinhibit-quitは再びnilになります。このときquit-flagnilなら、即座に要求されたquitが発生します。この挙動はプログラム中のクリティカルセクション内でquitが発生しないことを確実にしたいときに理想的です。

(read-quoted-charのような)いくつかの関数では、quitを起こさない特別な方法でC-gが処理されます。これはinhibit-quittにバインドして入力を読み取り、再びinhibit-quitnilになる前にquit-flagnilにセットすることにより行われます。以下はこれを行う方法を示すためのread-quoted-charの抜粋です。この例は入力の最初の文字の後で通常のquitを許す方法も示しています。

(defun read-quoted-char (&optional prompt)
  "…documentation…"
  (let ((message-log-max nil) done (first t) (code 0) char)
    (while (not done)
      (let ((inhibit-quit first)
            …)
        (and prompt (message "%s-" prompt))
        (setq char (read-event))
        (if inhibit-quit (setq quit-flag nil)))
      … 変数codeをセット …)
    code))
Variable: quit-flag

この変数が非nilinhibit-quitnilなら、Emacsは即座にquitする。C-gをタイプすると通常はinhibit-quitとは無関係にquit-flagを非nilにセットする。

Variable: inhibit-quit

この変数はquit-flagが非nilにセットされているときEmacsがquitするかどうかを決定する。inhibit-quitが非nilならquit-flagに特に効果はない。

Macro: with-local-quit body…

このマクロはbodyを順番に実行するが、たとえこの構文の外部でinhibit-quitが非nilでも、少なくともローカルにbody内でのquitを許容する。このマクロはquitによりexitしたらnil、それ以外はbody内の最後のフォームの値をリターンする。

inhibit-quitnilならwith-local-quitへのエントリーでbodyだけが実行され、quit-flagをセットすることにより通常のquitが発生する。しかし通常のquitが遅延されるようにinhibit-quitが非nilにセットされていれば、非nilquit-flagは特別な種類のローカルquitを引き起こす。これはbodyの実行を終了して、quit-flagを非nilのままにしてwith-local-quitのbodyをexitするので、許され次第(通常の)別のquitが発生する。bodyの先頭ですでにquit-flagが非nilなら即座にローカルquitが発生して結局bodyは実行されない。

このマクロは主にタイマー、プロセスフィルター、プロセスセンチネル、pre-command-hookpost-command-hook、およびinhibit-quitが通常のようにtにバイドされている場所で役に立つ。

Command: keyboard-quit

この関数は(signal 'quit nil)によってquit条件をシグナルする。これはquitが行うことと同じ(エラーsignalを参照)。

キーボードマクロの定義や実行をabortさせることなくquitするために、minibuffer-quit条件をシグナルすることができます。これはキーボードマクロの定義や実行をexitせずに、コマンド内のエラーハンドラーがこの条件を処理することを除き、quitとほとんど同じ効果をもつ。

quitに使用するC-g以外の文字を指定できます。入力のモード内の関数set-input-modeを参照してください。


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

22.12 プレフィクスコマンド引数

ほとんどのEmacsコマンドはプレフィクス引数(prefix argument)を使用できます。プレフィクス引数はコマンド自身の前に数字を指定するものです(プレフィクス引数とプレフィクスキーを混同しないこと)。プレフィクス引数は常に値により表され、nilのときはカレントでプレフィクス引数が存在しないことを意味します。すべてのコマンドはプレフィクス引数を使用するか、あるいは無視します。

プレフィクス引数には2つの表現があります。それはraw(生の、加工していない、原料のままの、未加工の)数字(numeric)です。エディターコマンドループは内部的にraw表現を使用し、Lisp変数もその情報を格納するのにこれを使用しますが、コマンドはいずれかの表現を要求できます。

以下は利用できるrawプレフィクス引数の値です:

  • nilはプレフィクス引数がないことを意味する。これの数値的な値は1だが多くのコマンドはnilと整数1を区別する。
  • 整数はそれ自身を意味する。
  • 整数の要素を1つもつリスト。プレフィクス引数のこの形式は、1つまたは数字無しの連続するC-uの結果である。数値的な値はリスト内の整数だが、そのようなリストと単独の整数を区別するコマンドがいくつかある。
  • シンボル-。これは後に数字をともなわないM--C-u -がタイプされたことを示す。数値的に等価な値は-1だが、整数の-1をシンボルの-を区別するコマンドがいくつかある。

以下の関数をさまざまなプレフィクスで呼び出して、これらの可能なプレフィクスを説明しましょう:

(defun display-prefix (arg)
  "rawプレフィクス引数の値を表示する"
  (interactive "P")
  (message "%s" arg))

以下はさまざまなrawプレフィクス引数でdisplay-prefixを呼び出した結果です:

        M-x display-prefix  -| nil

C-u     M-x display-prefix  -| (4)

C-u C-u M-x display-prefix  -| (16)

C-u 3   M-x display-prefix  -| 3

M-3     M-x display-prefix  -| 3      ; (C-u 3と同じ)

C-u -   M-x display-prefix  -| -

M--     M-x display-prefix  -| -      ; (C-u -と同じ)

C-u - 7 M-x display-prefix  -| -7

M-- 7   M-x display-prefix  -| -7     ; (C-u -7と同じ)

Emacsにはプレフィクス引数を格納するために2つの変数prefix-argcurrent-prefix-argがあります。他のコマンドにたいしてプレフィクス引数をセットアップするuniversal-argumentのようなコマンドは、プレフィクス引数をprefix-arg内に格納します。対照的にcurrent-prefix-argはカレントコマンドにプレフィクス引数を引き渡すので、これらの変数をセットしても将来のコマンドにたいするプレフィクス引数に効果はありません。

コマンドは通常はinteractive内で、プレフィクス引数にたいしてrawと数値のどちらの表現を使用するかを指定します(interactiveの使用を参照)。そのかわりに関数は変数current-prefix-arg内のプレフィクス引数の値を直接調べるかもしれませんが、これは明確さで劣っています。

Function: prefix-numeric-value arg

この関数はargの有効なrawプレフィクス引数の数値的な意味をリターンする。引数はシンボル、数字、またはリストかもしれない。これがnilなら値1、-なら-1がリターンされる。これが数字なら、その数字がリターンされる。リスト(数字であること)なら、そのリストのCARがリターンされる。

Variable: current-prefix-arg

この変数はカレントのコマンドにたいするrawプレフィクス引数を保持する。コマンドはこの変数を直接調べるかもしれないが、この変数にたいするアクセスには通常は(interactive "P")を使用する。

Variable: prefix-arg

この変数の値はの編集コマンドにたいするrawプレフィクス引数である。後続のコマンドにたいしてプレフィクス引数を指定するuniversal-argumentのようなコマンドは、この変数をセットすることによって機能する。

Variable: last-prefix-arg

このrawプレフィクス引数の値は、前のコマンドにより使用された値である。

以下のコマンドは、後続のコマンドにたいしてプレフィクス引数をセットアップするために存在します。これらを他の用途で呼び出さないでください。

Command: universal-argument

このコマンドは入力を読み取って、後続のコマンドにたいするプレフィクス引数を指定する。何をしているかわかっているのでなければ、このコマンドを自分で呼び出してはならない。

Command: digit-argument arg

このコマンドは、後続のコマンドにたいしてプレフィクス引数を追加する。引数argはこのコマンドの前のrawプレフィクス引数であり、これはプレフィクス引数を更新するために使用される。何をしているかわかっているのでなければ、このコマンドを自分で呼び出してはならない。

Command: negative-argument arg

このコマンドは、次のコマンドにたいして数引数を追加する。引数argはこのコマンドの前のrawプレフィクス引数であり、この値に負の符号が付されて新しいプレフィクス引数を構築する。何をしているかわかっているのでなければ、このコマンドを自分で呼び出してはならない。


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

22.13 再帰編集

Emacsはスタートアップ時に、自動的にEmacsコマンドループに移行します。このトップレベルのコマンドループ呼び出しは決してexitすることなく、Emacs実行中は実行を継続します。Lispプログラムもコマンドループを呼び出せます。これは複数のコマンドループを活性化するので、再帰編集(recursive editing)と呼ばれています。再帰編集レベルは呼び出したコマンドが何であれそれをサスペンドして、そのコマンドを再開する前にユーザーが任意の編集を行うことを可能にする効果をもちます。

再帰編集の間に利用可能なコマンドは、トップレベルの編集ループ内で利用できるコマンドと同じでありキーマップ内で定義されます。数少ない特別なコマンドだけが再帰編集レベルをexitして、他のコマンドは再帰編集レベルが終了したときに再帰編集レベルからリターンします(exitするための特別なコマンドは常に利用できるが再帰編集が行われていないときは何も行わない)。

再帰コマンドループを含むすべてのコマンドループは、コマンドループから実行されたコマンド内のエラーによってそのループをexitしないように、汎用エラーハンドラーをセットアップします。

ミニバッファー入力は特殊な再帰編集です。これはミニバッファーとミニバッファーウィンドウの表示を有効にするなどの欠点をもちますが、それはあなたが思うより少ないでしょう。ミニバッファー内では特定のキーの振る舞いが異なりますが、これははミニバッファーのローカルマップによるものです。ウィンドウを切り替えれば通常のEmacsコマンドを使用できます。

再帰編集レベルを呼び出すには関数recursive-editを呼び出します。この関数はコマンドループを含んでいます。さらにexitをthrowすることにより再帰編集レベルのexitを可能にする、タグexitをともなったcatch呼び出しも含んでいます(明示的な非ローカル脱出: catchthrowを参照)。コマンドC-M-c (exit-recursive-edit)がこれを行います。値tをthrowすることによってrecursive-editがquitされるので、1レベル上位のコマンドループに制御がリターンされます。これはabortと呼ばれ、C-](abort-recursive-edit)がこれを行います。同様にrecursive-editにエラーをシグナルさせるために文字列値をthrowできます。この文字列はメッセージとしてプリントされます。関数値をthrowすると。recursive-editはリターンする前に引数なしでそれを呼び出します。それ以外の値をthrowすると、recursive-editは自身を呼び出した関数に正常にリターンします。コマンドC-M-c (exit-recursive-edit)がこれを行います。

ほとんどのアプリケーションはミニバッファー使用の一部として使用する場合を除き、再帰編集を使用するべきではありません。カレントバッファーのメジャーモードから特殊なメジャーモードに一時的に変更する場合に、そのモードに戻るコマンドをもつ必要があるときは、通常は再帰編集のほうが便利です(Rmailのeコマンドはこのテクニックを使用)。またはユーザーが新たなバッファーの特殊なモードで、異なるテキストを再帰的に編集・作成・選択できるようにしたい場合が該当します。このモードでは処理を完了させるコマンドを定義して前のバッファーに戻ります(Rmailのmコマンドはこれを使用)。

再帰編集はデバッグに便利です。一種のブレークポイントとして関数定義内にdebugを挿入して、関数がそこに達したときにその箇所を調べることができます。debugは再帰編集を呼び出しますが、デバッガのその他の機能も提供します。

query-replace内でC-rをタイプしたときやC-x q (kbd-macro-query)を使用したときにも再帰編集レベルが使用されます。

Command: recursive-edit

この関数はエディターコマンドループを呼び出す。これはユーザーに編集を開始させるために、Emacsの初期化により自動的に呼び出される。Lispプログラムから呼び出されたときは再帰編集レベルにエンターする。

カレントバッファーが選択されたウィンドウのバッファーと異なる場合、recursive-editはカレントバッファーの保存とリストアを行う。それ以外ではバッファーを切り替えると、recursive-editがリターンした後にその切り替えたバッファーがカレントになる。

以下の例では関数simple-recが最初にポイントを1単語分進めてからメッセージをエコーエリアにプリントして再帰編集にエンターする。その後ユーザーは望む編集を行い、C-M-cをタイプすれば再帰編集をexitしてsimple-recの実行を継続できる。

(defun simple-rec ()
  (forward-word 1)
  (message "Recursive edit in progress")
  (recursive-edit)
  (forward-word 1))
     ⇒ simple-rec
(simple-rec)
     ⇒ nil
Command: exit-recursive-edit

この関数は最内の再帰編集(ミニバッファー入力を含む)からexitする。関数の実質的な定義は(throw 'exit nil)

Command: abort-recursive-edit

この関数は再帰編集をexitした後にquitをシグナルすることにより、最内の再帰編集(ミニバッファー入力を含む)を要求したコマンドをabortする。関数の実質的な定義は(throw 'exit t)quitを参照のこと。

Command: top-level

この関数はすべての再帰編集レベルをexitする。これはすべての計算を直接抜け出してメインのコマンドループに戻って値をリターンしない。

Function: recursion-depth

この関数は再帰編集のカレントの深さをリターンする。アクティブな再帰編集が存在しなければ0をリターンする。


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

22.14 コマンドの無効化

コマンドを無効化(disabling a command)とは、それを実行可能にする前にユーザーによる確認を要求するようにコマンドをマークすることです。無効化は初めてのユーザーを混乱させるかもしれないコマンドにたいして、意図せずそのコマンドが使用されるのを防ぐために使用されます。

コマンド無効化の低レベルにおけるメカニズムは、そのコマンドにたいするLispシンボルのdisabledプロパティに非nilをputすることです。これらのプロパティは、通常はユーザーのinitファイル(initファイルを参照)で以下のようなLisp式によりセットアップされます:

(put 'upcase-region 'disabled t)

いくつかのコマンドにたいしては、これらのプロパティがデフォルトで与えられています(これらを削除したければinitファイルで削除できる)。

disabledプロパティの値が文字列なら、そのコマンドが無効化されていることを告げるメッセージにその文字列が含まれます。たとえば:

(put 'delete-region 'disabled
     "この方法で削除されたテキストはyankで戻せない!\n")

無効化されたコマンドをインタラクティブに呼び出したときに何が起こるかの詳細は、Disabling in The GNU Emacs Manualを参照してください。コマンドの無効化は、それをLispプログラムから関数として呼び出したときは効果がありません。

disabledプロパティの値には、1つ目の要素がシンボルqueryであるようなリストも指定できます。この場合には、ユーザーはそのコマンドを実行するかどうか問い合わせられることになります。このリストの2つ目の要素にはy-or-n-pを使用するならnilyes-or-no-pなら非nilを指定する必要があり、3つ目に要素は質問として使用されます。コマンドにたいする問い合わせを有効にするには、利便性のための関数command-queryを使う必要があります。

Command: enable-command command

その時点から特別な確認なしでcommand(シンボル)が実行されることを許す。さらにユーザーのinitファイル(initファイルを参照)も修正するので将来のセッションにもこれが適用される。

Command: disable-command command

その時点からcommand(シンボル)の実行に特別な確認を要求する。さらにユーザーのinitファイル(initファイルを参照)も修正するので将来のセッションにもこれが適用される。

Variable: disabled-command-function

この変数の値は関数であること。ユーザーが無効化されたコマンドを呼び出したときは無効化されたコマンドのかわりにその関数が呼び出される。そのコマンドを実行するためにユーザーが何のキーをタイプしたかを判断するためにthis-command-keysを使用して、そのコマンド自体を探すことができる。

値はnilもあり得る。その場合にはたとえ無効化されたコマンドでも、すべてのコマンドが通常のように機能する。

デフォルトでは値はユーザーに処理を行うかどうかを尋ねる関数。


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

22.15 コマンドのヒストリー

コマンドループは複雑なコマンドを手軽に繰り返せるように、すでに実行された複雑なコマンドのヒストリー(history: 履歴)を保持します。複雑なコマンド(complex command)とは、ミニバッファーを使用してinteractive引数を読み取るコマンドです。これにはM-xコマンド、M-:コマンド、およびinteractive指定によりミニバッファーから引数を読み取るすべてのコマンドが含まれます。コマンド自身の実行の間に明示的にミニバッファーを使用するものは、複雑なコマンドとは判断されません。

Variable: command-history

この変数の値は最近実行された複雑なコマンドのリストであり、それぞれが評価されるべきフォームとして表現される。このリストは編集セッションの間、すべての複雑なコマンドを蓄積するが、最大サイズ(ミニバッファーのヒストリーを参照)に達したときは、もっとも古い要素が削除されて新たな要素が追加される。

command-history
⇒ ((switch-to-buffer "chistory.texi")
    (describe-key "^X^[")
    (visit-tags-table "~/emacs/src/")
    (find-tag "repeat-complex-command"))

このヒストリーリストは実際にはミニバッファーヒストリーの特殊ケースであり、それは要素が文字列ではなく式であることです。

以前のコマンドを編集したり再呼び出しするためのコマンドがいくつかあります。コマンドrepeat-complex-commandlist-command-historyはユーザーマニュアルに説明されています(Repetition in The GNU Emacs Manualを参照)。ミニバッファー内では通常のミニバッファーヒストリーコマンドが利用できます。


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

22.16 キーボードマクロ

キーボードマクロ(keyboard macro)はコマンドとして考えることが可能な入力イベントの記録されたシーケンスであり、キー定義によって作成されます。キーボードマクロのLisp表現はイベントを含む文字列かベクターです。キーボードマクロとLispマクロ(マクロを参照)を混同しないでください。

Function: execute-kbd-macro kbdmacro &optional count loopfunc

この関数はイベントシーケンスとしてkbdmacroを実行する。kbdmacroが文字列かベクターなら、たとえそれがユーザーによる入力であっても、その中のイベントは忠実に実行される。シーケンスは単一のキーシーケンスであることを要求されない。キーボードマクロ定義は、通常は複数のキーシーケンスを結合して構成される。

kbdmacroがシンボルなら、そのシンボルの関数定義はkbdmacroの箇所に使用される。それが別のシンボルならこのプロセスを繰り返す。最終的に結果は文字列かベクターになる。結果がシンボル、文字列、ベクターでなければエラーがシグナルされる。

引数countは繰り返すカウントであり、kbdmacroがその回数実行される。countが省略またはnilなら1回実行される。0ならkbdmacroはエラーに遭遇するか検索が失敗するまで何度も実行される。

loopfuncが非nilなら、それはマクロの繰り返しごとに呼び出される引数なしの関数である。loopfuncnilをリターンするとマクロの実行が停止する。

execute-kbd-macroの使用例は単一イベントの読み取りを参照のこと。

Variable: executing-kbd-macro

この変数はカレントで実行中のキーボードマクロを定義する文字列かベクター。nilならカレントで実行中のマクロは存在しない。マクロの実行により実行されたときに異なる振る舞いをするように、コマンドはこの変数をテストできる。この変数を自分でセットしてはならない。

Variable: defining-kbd-macro

この変数はキーボードマクロの定義中のときだけ非nilである。マクロ定義中の間は異なる振る舞いをするように、コマンドはこの変数をテストできる。既存のマクロ定義に追加する間、値はappendになる。コマンドstart-kbd-macrokmacro-start-macroend-kbd-macroはこの変数をセットする。この変数を自分でセットしてはならない。

この変数は常にカレント端末にたいしてローカルであり、バッファーローカルにできない。複数の端末を参照のこと。

Variable: last-kbd-macro

この変数はもっとも最近定義されたキーボードマクロの定義である。値は文字列、ベクター、またはnil

この変数は常にカレント端末にたいしてローカルであり、バッファーローカルにできない。複数の端末を参照のこと。

Variable: kbd-macro-termination-hook

これはキーボードマクロが終了したときに実行されるノーマルフックであり、何がキーボードマクロを終了させたか(マクロの最後に到達したのか、あるいはエラーにより最後到達する前に終了したのか)は問わない。


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

23 キーマップ

入力イベントのコマンドバインディングはキーマップ(keymap)と呼ばれるデータ構造に記録されます。キーマップ内の各エントリーは個別のイベント型(他のキーマップ、またはコマンド)に関連づけ(またはバインド)されます。イベント型がキーマップにバインドされていれば、そのキーマップは次の入力イベントを調べるために使用されます。これはコマンドが見つかるまで継続されます。このプロセス全体をキールックアップ(key lookup: キーの照合)と呼びます。


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

23.1 キーシーケンス

キーシーケンス(key sequence)、短くはキー(key)とは1つの単位を形成する1つ以上の入力イベントのシーケンスです。入力イベントには文字、ファンクションキー、マウスアクション、またはiconify-frameのようなEmacs外部のシステムイベントが含まれます(入力イベントを参照)。キーシーケンスにたいするEmacs Lispの表現は文字列かベクターです。特に明記しない限り、引数としてキーシーケンスを受け取るEmacs Lisp関数は両方の表現を処理することができます。

文字列表現ではたとえば"a"a"2"2を表すといったように、英数字はその文字自身を意味します。コントロール文字イベントは部分文字列"\C-"、メタ文字は"\M-"によりプレフィクスされます。たとえば"\C-x"はキーC-xを表します。それらに加えてTABRETESCDELなどのイベントはそれぞれ"\t""\r""\e""\d"で表されます。複雑なキーシーケンスの文字列表現はイベント成分の文字列表現を結合したものです。したがって"\C-xl"はキーシーケンスC-x lを表します。

キーシーケンスにはファンクションキー、マウスボタンイベント、システムイベント、またはC-=H-aのような文字列で表現できない非ASCII文字が含まれます。これらはベクターとして表現する必要があります。

ベクター表現ではベクターの各要素は1つの入力イベントをイベントのLisp形式で表します。入力イベントを参照してください。たとえばベクター[?\C-x ?l]はキーシーケンスC-x lを表します。

キーシーケンスを文字列やベクターによる表現で記述する例は、Init Rebinding in The GNU Emacs Manualを参照してください。

Function: kbd keyseq-text

この関数はテキストkeyseq-text(文字列定数)をキーシーケンス(文字列かベクターの定数)に変換する。keyseq-textの内容はC-x C-k RET (kmacro-edit-macro)コマンドにより呼び出されたバッファー内と同じ構文を使用するべきである。特にファンクションキーの名前は‘<…>’で囲まなければならない。Edit Keyboard Macro in The GNU Emacs Manualを参照のこと。

(kbd "C-x") ⇒ "\C-x"
(kbd "C-x C-f") ⇒ "\C-x\C-f"
(kbd "C-x 4 C-f") ⇒ "\C-x4\C-f"
(kbd "X") ⇒ "X"
(kbd "RET") ⇒ "\^M"
(kbd "C-c SPC") ⇒ "\C-c "
(kbd "<f1> SPC") ⇒ [f1 32]
(kbd "C-M-<down>") ⇒ [C-M-down]

kbdは非常に融通の効く関数であり、完全には準拠していない構文が使用されたとしても適切な何かをリターンしようと試みる。構文が実際に有効か否かをチェックするにはkey-valid-p関数を使用すること。


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

23.2 キーマップの基礎

キーマップはさまざまなキーシーケンスにたいしてキーバインディング(key binding)を指定するLispデータ構造です。

1つのキーマップが、個々のイベントにたいする定義を直接指定します。単一のイベントでキーシーケンスが構成されるとき、そのキーシーケンスのキーマップ内でのバインディングは、そのイベントにたいするそのキーマップの定義です。それより長いキーシーケンスのバインディングは対話的プロセスによって見つけ出されます。まず最初にイベント(それ自身がキーマップでなければならない)の定義を探します。そして次にそのキーマップ内で2つ目のイベントを探すといったように、そのキーシーケンス内のすべてのイベントが処理されるまで、これを続けます。

あるキーシーケンスのバインディングがキーマップであるような場合、わたしたちはそのキーシーケンスをプレフィクスキー(prefix key)と呼び、それ以外の場合には(それ以上イベントを追加できないので)コンプリートキー(complete keylと呼んでいます。バインディングがnilの場合、わたしたちはそのキーを未定義(undefined)と呼びます。C-cC-xC-x 4などはプレフィクスキーの例です。XRETC-x 4 C-fなどは定義されたコンプリートキーの例です。C-x C-gC-c 3などは未定義なコンプリートキーの例です。詳細はプレフィクスキーを参照してください。

キーシーケンスのバインディングを見つけ出すルールは、(最後のイベントの前までに見つかる)中間的なバインディングがすべてキーマップであると仮定します。もしそうでなければ、そのイベントシーケンスは単位を形成せず、実際の単一キーシーケンスではありません。言い換えると任意の有効なキーシーケンスから1つ以上のイベントを取り除くと、常にプレフィクスキーにならなければなりません。たとえばC-f C-nはキーシーケンスではありません。C-fはプレフィクスキーではないので、C-fで始まるこれより長いシーケンスは、キーシーケンスではあり得ないからです。

利用可能な複数イベントキーシーケンスのセットは、プレフィクスキーにたいするバインディングに依存します。したがってこれはキーマップが異なれば異なるかもしれず、バインディングが変更されたときに変更されるかもしれません。しかし単一イベントキーシーケンスは整合性において任意のプレフィクスキーに依存しないので、常に単一のキーシーケンスです。

常に複数のプライマリーキーマップ(primary keymap: 主キーマップ)がアクティブであり、これらはキーバインディングを見つけるために使用されます。すべてのバッファーで共有されるグローバルキーマップ(global map)というキーマップが存在します。ローカルキーマップ(local keymap)は通常は特定のメジャーモードに関連します。そして0個以上のマイナーモードキーマップ(minor mode keymap)はカレントで有効なマイナーモードに属します(すべてのマイナーモードがキーマップをもつわけでなない)。ローカルキーマップは対応するグローバルバインディングをshadow(訳注: 隠すという意味)します。マイナーモードキーマップは、ローカルキーマップとグローバルキーマップの両方をshadowします。詳細はアクティブなキーマップを参照してください。


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

23.3 キーマップのフォーマット

キーマップはそれぞれCARがシンボルkeymapであるようなリストです。このリストの残りの要素はそのキーマップのキーバインディングを定義します。関数定義がキーマップであるようなシンボルもキーマップです。あるオブジェクトがキーマップかどうかテストするには、関数keymapp(以下参照)を使用してください。

キーマップを開始するシンボルkeymapの後には、いくつかの種類の要素が出現します:

(type . binding)

これは型typeのイベントにたいする1つのバインディングを指定する。通常のバインディングはそれぞれ、常に文字かシンボルであるような特定のイベント型(event type)のイベントに適用される。イベントの分類を参照のこと。この種のバインディングでは、bindingはコマンドである。

(type item-name . binding)

これはメニュー内でitem-nameとして表示されるシンプルなメニューアイテムでもあるようなバインディングを指定する。単純なメニューアイテムを参照のこと。

(type item-name help-string . binding)

これはヘルプ文字列help-stringのシンプルなメニューアイテムである。

(type menu-item . details)

これは拡張されたメニューアイテムでもあるようなバインディングを指定する。これは他の機能も使用できる。拡張メニューアイテムを参照のこと。

(t . binding)

これはデフォルトキーバインディング(default key binding)を指定する。キーマップの他の要素でバインドされないイベントは、バインディングとしてbindingが与えられる。デフォルトバインディングにより、利用可能なすべてのイベント型を列挙することなくバインドできる。デフォルトバインディングをもつキーマップは、明示的にnilにバインドされるイベント(以下参照)を除いて、より低い優先度にあるすべてのキーマップをマスクする。

char-table

キーマップのある要素が文字テーブル(char-table)なら、それは修飾ビットなしのすべての文字イベントにたいするバインディングを保持するとみなされる(modifier bitsを参照)。インデックスcの要素は文字cにたいしてバインドされる。これは多量のバインディングを記録するためのコンパクトな方法である。そのような文字テーブルのキーマップは、fullキーマップ(full keymap: 完全なキーマップ)と呼ばれる。それにたいして他のキーマップはsparseキーマップ(sparse keymaps: 疎なキーマップ)と呼ばれる。

vector

この種の要素は文字テーブルと類似する。インデックスcの要素は文字cにバインドされる。この方法でバインド可能な文字の範囲はそのベクターのサイズに制限され、かつベクターの作成により0からすべての文字コードまでスペースが割り当てられるので、バインディング自身が問題とならないメニューキーマップ(メニューキーアップを参照)の作成以外では、このフォーマットを使用しないこと。

string

キーにたいするバインディングを指定する要素は別として、キーマップは要素として文字列ももつことができる。これはoverallプロンプト文字列(overall prompt string: 全般的なプロンプト文字列)と呼ばれ、メニューとしてキーマップを使用することを可能にする。メニューの定義を参照のこと。

(keymap …)

キーマップのある要素それ自身がキーマップなら、外側のキーマップ内でこれが内側のキーマップとしてinline指定されているかのようにみなされる。これはmake-composed-keymap内で行なわれるような多重継承にたいして使用される。

バインディングがnilなら、それは定義の構成要素ではありませんが、デフォルトバインディングや親キーマップ内のバインディングに優先されます。一方nilのバインディングは、より低い優先度のキーマップをオーバーライドしません。したがってローカルマップでnilのバインディングが与えられると、Emacsはグローバルマップのバインディングを使用します。

キーマップはメタ文字にたいするバインディングを直接記録しません。かわりにメタ文字は1文字目がESC(または何であれmeta-prefix-charのカレント値)であるような、2文字のキーシーケンスをルックアップするものとみなされます。したがってキーM-aは内部的にはESC aで表され、そのグローバルバインディングはesc-map内のaにたいするスロットで見つけることができます(プレフィクスキーを参照)。

この変換は文字にたいしてのみ適用され、ファンクションキーや他の入力イベントには適用されないのでM-endESC endと何も関係ありません。

以下に例としてLispモードにたいするローカルキーマップ(sparseキーマップ)を挙げます。以下ではDELC-c C-zC-M-qC-M-xにたいするバインディングを定義しています(実際の値はメニューバインディングも含まれるが簡潔にするためここでは省略)。

lisp-mode-map
⇒
(keymap
 (3 keymap
    ;; C-c C-z
    (26 . run-lisp))
 (27 keymap
     ;; C-M-xESC C-xとして扱われる
     (24 . lisp-send-defun))
 ;; この部分はlisp-mode-shared-mapから継承
 keymap
 ;; DEL
 (127 . backward-delete-char-untabify)
 (27 keymap
     ;; C-M-qESC C-qとして扱われる
     (17 . indent-sexp)))
Function: keymapp object

この関数はobjectがキーマップならt、それ以外はnilをリターンする。より正確にはこの関数はリストにたいしてそのCARkeymapか、あるいはシンボルにたいしてその関数定義がkeymappかどうかをテストする。

(keymapp '(keymap))
    ⇒ t
(fset 'foo '(keymap))
(keymapp 'foo)
    ⇒ t
(keymapp (current-global-map))
    ⇒ t

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

23.4 キーマップの作成

以下はキーマップを作成する関数です。

Function: make-sparse-keymap &optional prompt

この関数はエントリーをもたない新たなsparseキーマップを作成してそれをリターンする(sparseキーマップはあなたが通常望む類のキーマップのこと)。make-keymapと異なり新たなキーマップは文字テーブルを含まず、何のイベントもバインドしない。

(make-sparse-keymap)
    ⇒ (keymap)

promptを指定すると、それはキーマップにたいするoverallプロンプト文字列になる。これはメニューキーマップ(メニューの定義を参照)にたいしてのみ指定すべきである。overallプロンプト文字列をともなうキーマップがアクティブなら、次の入力イベントのルックアップにたいしてマウスメニューとキーボードメニューを常に提示する。これはコマンドループにたいして毎回キーボードメニューを提示するので、overallプロンプト文字列をメインマップ、メジャーモードマップ、マイナーモードマップに指定しないこと。

Function: make-keymap &optional prompt

この関数は新たなfullキーマップを作成してそれをリターンする。このキーマップは修飾されないすべての文字にたいするスロットをもつ文字テーブル(文字テーブルを参照)を含む。この新たなキーマップは初期状態ではすべての文字、およびその他の種類のイベントがnilにバインドされている。引数promptmake-sparse-keymapのようにプロンプト文字列を指定する。

(make-keymap)
    ⇒ (keymap #^[nil nil keymap nil nil nil …])

fullキーマップは多くのスロットを保持するときはsparseキーマップより効果的であり、少ししかスロットを保持しないときはsparseキーマップのほうが適している。

Function: define-keymap &key options... &rest pairs...

上述した関数によってキーマップを作成してから、keymap-set (キーバインディングの変更を参照)を使用してそのマップ内のキーバインディングを指定する。ただしモードを記述する際には一度に大量のキーのバインドを要することが頻繁にあるため、keymap-setを使用してそれらすべてをバインドするのは面倒かもしれないしエラーも起きやすいだろう。かわりにキーマップの作成と複数のキーのバインドを行うdefine-keymapを使うことができる。基本的な例を以下に示す:

(define-keymap
  "n" #'forward-line
  "f" #'previous-line
  "C-c C-c" #'quit-window)

この関数はpairs内のキーストロークを定義するsparseキーマップを新たに作成して、そのキーマップをリターンする。pairs内に重複したキーバインディングがあればエラーをシグナルする。

pairskeymap-setが受け入れるようなキーバインディングとキー定義が交互に指定されたリスト。更にキーは特別なシンボル:menuでもよい。この場合には、定義easy-menu-define (easy-menuを参照)が許容するようなメニュー定義であること。以下は使い方を示す簡単な例:

(define-keymap :full t
  "g" #'eww-reload
  :menu '("Eww"
          ["Exit" quit-window t]
          ["Reload" eww-reload t]))

新たなキーマップの機能を変更するために、キー/定義のペアーの前にいくつかのキーワードを使うことができる。define-keymapの呼び出しに含まれていないキーワードの機能にたいするデフォルト値はnil。利用可能な機能キーワードは以下のとおり:

:full

nilなら(make-sparse-keymapが作成するような)sparseキーマップのかわりに、(make-keymapが作成するような)文字テーブルキーマップを作成する(キーマップの作成を参照)。デフォルトはsparseキーマップ。

:parent

nilなら値は親として使用するキーマップであること(継承とキーマップを参照)。

:keymap

nilなら、値はキーマップであること。新たにキーマップを作成するかわりに指定されたキーマップを変更する。

:suppress

nilなら、そのキーマップはsuppress-keymapによって抑制される(キーバインディングの変更を参照)。デフォルトでは数字とマイナス記号は抑制から除外されるが、値がnodigitsなら他の文字と同様に数字とマイナス記号も抑制する。

:name

nil、かつx-popup-menu (ポップアップメニューを参照)によるメニューとして使用する場合には、値をメニューとして使用するような文字列にする必要がある。

:prefix

nilなら、値はプレフィックスコマンドとして使用するシンボルであること(プレフィクスキーを参照)。この場合にはマップ自体ではなく、このシンボルがdefine-keymapによってリターンされる。

Macro: defvar-keymap name &key options... &rest pairs...

キーマップでもっとも一般的に行われるのは専ら変数へのバインドであろう。これはほぼすべてのモードが行っていることであり、fooと呼ばれるモードにはほとんど常にfoo-mode-mapと呼ばれる変数が存在する。

このマクロはnameを変数として定義して、optionspairsdefine-keymapに渡した結果をその変数のデフォルト値として使用する。pairs内に重複したキーバインディングがあればエラーをシグナルする。

optionsdefine-keymapにおけるキーワードと同様だが、定義される変数にたいしてdoc文字列を提供するためのキーワード:docが追加されている。

以下は例:

(defvar-keymap eww-textarea-map
  :parent text-mode-map
  :doc "Keymap for the eww text area."
  "RET" #'forward-line
  "TAB" #'shr-next-link)

キーマップ内のコマンドはそれぞれrepeat-mapプロパティを配置することによって、(repeat-modeで便利なように)‘repeatable(繰り返し可能)’とマークすることができる、たとえば

(put 'undo 'repeat-map 'undo-repeat-map)

repeat-modeによって使用されるマップがこのプロパティになる。

putを繰り返し呼び出すことを避けるためのキーワードとして、defvar-keymapには:repeatがある。このキーワードを使えばキーマップのどのコマンドがrepeat-modeで使用可能かを指定できる。使用できる値は以下のとおり:

t

キーマップのすべてのコマンドが繰り返し可能ということを意味する。もっとも一般的な使い方。

(:enter (commands ...) :exit (commands ...))

:enterリストにあるコマンドでrepeat-modeにエンター、:exitリストにあるコマンドでrepeatモードからexitすることを指定する。

:enterリストが空の場合には、そのマップのすべてのコマンドがrepeat-modeにエンターする。このリストに1つ以上のコマンドを指定しておけば、定義しているマップには存在しないものの、repeat-mapプロパティをもつべきコマンドがある場合に役に立つだろう。

:exitリストが空なら、そのマップにおいてrepeat-modeをexitするコマンドは存在しない。このリストに1つ以上のコマンドを指定しておけば、定義しているマップにrepeat-mapプロパティをもつべきではないコマンドが含まれる場合に役に立つだろう。

たとえばuundoコマンドを繰り返す場合には、以下の2節は等価である:

(defvar-keymap undo-repeat-map
  "u" #'undo)
(put 'undo 'repeat-map 'undo-repeat-map)

または

(defvar-keymap undo-repeat-map
  :repeat t
  "u" #'undo)

マップに多くのコマンドがあり、それらすべてを繰り返し可能にする必要がある場合には後者を使うほうがよいだろう。

Function: copy-keymap keymap

この関数はkeymapのコピーをリターンする。これはほとんど必要ないだろう。ほとんど差のないキーマップが必要なら、コピーより以下のように継承を使用するべきである:

(let ((map (make-sparse-keymap)))
  (set-keymap-parent map <theirmap>)
  (keymap-set map ...)
  ...)

copy-keymapを処理する際には、keymap内でバインディングとして直接出現するすべてのキーマップも、すべてのレベルまで再帰的にコピーされる。しかしある文字の定義が関数定義にキーマップをもつ関数のときには再帰的なコピーは行われず、新たにコピーされたキーマップには同じシンボルがコピーされる。

(setq map (copy-keymap (current-local-map)))
⇒ (keymap
     ;; (これはメタ文字を実装する)
     (27 keymap
         (83 . center-paragraph)
         (115 . center-line))
     (9 . tab-to-tab-stop))

(eq map (current-local-map))
    ⇒ nil
(equal map (current-local-map))
    ⇒ t

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

23.5 継承とキーマップ

キーマップは他のキーマップを継承することができ、この継承元のキーマップを親キーマップ(parent keymap)と呼びます。そのようなキーマップは以下のようなキーマップです:

(keymap elements… . parent-keymap)

これにはそのキーマップのキールックアップ時にparent-keymapのすべてのバインディングを継承するものの、それらにバインディングを追加したりelementsでオーバーライドできるという効果があります。

keymap-setや他のキーバインディング関数を使用してparent-keymap内のバインディングを変更すると、変更されたバインディングはelementsで作られたバインディングにshadowされない限り継承されたキーマップ内で可視になります。逆は成り立ちません。keymap-setを使用して継承されたキーマップ内のバインディングを変更すると、これらの変更はelements内に記録されますがparent-keymapに影響はありません。

親キーマップからキーマップを構築するにはset-keymap-parentを使用するのが正しい方法です。親キーマップから直接キーマップを構築するコードがあるなら、かわりにset-keymap-parentを使用するようにプログラムを変更してください。

Function: keymap-parent keymap

これはkeymapの親キーマップをリターンする。keymapに親キーマップがなければkeymap-parentnilをリターンする。

Function: set-keymap-parent keymap parent

これはkeymapの親キーマップをparentにセットしてparentをリターンする。parentnilならこの関数はkeymapに親キーマップを与えない。

keymapがサブマップ(プレフィクスキーにたいするバインディング)をもつ場合は、それらも新たな親キーマップを受け取ってそれらのプレフィクスキーにたいしてparentが何を指定するかが反映される。

以下はtext-mode-mapから継承してキーマップを作成する方法を示す例です:

(let ((map (make-sparse-keymap)))
  (set-keymap-parent map text-mode-map)
  map)

非sparseキーマップも親キーマップをもつことができますが便利とは言えません。非sparseキーマップは修飾ビットをもたないすべての数値文字コードにたいするバインディングとして、たとえそれがnilであっても常に何かを指定するので、これらの文字のバインディングが親キーマップから継承されることは決してないのです。

複数のマップからキーマップを継承したいときがあるかもしれません。これにたいして関数make-composed-keymapが使用できます。

Function: make-composed-keymap maps &optional parent

この関数は既存のキーマップから構成される新たなキーマップをリターンする。またオプションで親キーマップparentから継承を行う。mapsには単一のキーマップ、または複数のキーマップのリストを指定できる。リターンされた新たなマップ内でキーをルックアップするとき、Emacsはmaps内のキーマップを順に検索してからparent内を検索する。この検索は最初のマッチで停止する。mapsのいずれか1つのキーマップ内のnilバインディングは、parent内のすべてのバインディングをオーバーライドするが、mapsにないキーマップの非nilなバインディングはオーバーライドしない。

For example, here is how Emacs sets the parent of たとえば以下はbutton-buffer-mapspecial-mode-mapの両方を継承するhelp-mode-mapのようなキーマップの親キーマップをEmacsがセットする方法です:

(defvar-keymap help-mode-map
  :parent (make-composed-keymap button-buffer-map
                                special-mode-map)
  ...)

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

23.6 プレフィクスキー

プレフィクスキー(prefix key)とは、バインディングがキーマップであるようなキーシーケンスです。このキーマップはプレフィクスキーを拡張するキーシーケンスが何を行うかを定義します。たとえばC-xはプレフィクスキーであり、これはキーマップを使用してそのキーマップは変数ctl-x-mapにも格納されています。このキーマップはC-xで始まるキーシーケンスにたいするバインディングを定義します。

標準的なEmacsのプレフィクスキーのいくつかは、Lisp変数でも見い出すことができるキーマップを使用しています:

  • esc-mapはプレフィクスキーESCにたいするグローバルキーマップである。したがってすべてのメタ文字にたいする定義は、このキーマップで見い出すことができる。このマップはESC-prefixの関数定義でもある。
  • help-mapはプレフィクスキーC-hにたいするグローバルキーマップである。
  • mode-specific-mapはプレフィクスキーC-cにたいするグローバルキーマップである。このマップは実際にはモード特有(mode-specific)ではなくグローバルであるが、このプレフィクスキーは主にモード特有なバインディングに使用されるので、C-h b (display-bindings)の出力内のC-cに関する情報で、この名前は有意義な情報を提供する。
  • ctl-x-mapはプレフィクスキーC-xにたいして使用されるグローバルキーマップである。このマップはシンボルControl-X-prefixの関数セルを通して見つけることができる。
  • mule-keymapはプレフィクスキーC-x RET にたいして使用されるグローバルキーマップである。
  • ctl-x-4-mapはプレフィクスキーC-x 4にたいして使用されるグローバルキーマップである。
  • ctl-x-5-mapはプレフィクスキーC-x 5にたいして使用されるグローバルキーマップである。
  • 2C-mode-mapはプレフィクスキーC-x 6にたいして使用されるグローバルキーマップである。
  • tab-prefix-mapはプレフィクスキーC-x tにたいして使用されるグローバルキーマップである。
  • vc-prefix-mapはプレフィクスキーC-x vにたいして使用されるグローバルキーマップである。
  • goto-mapはプレフィクスキーM-gにたいして使用されるグローバルキーマップである。
  • search-mapはプレフィクスキーM-sにたいして使用されるグローバルキーマップである。
  • Emacsの他のプレフィクスキーにはC-x @C-x a iC-x ESCESC ESCがある。これらは特別な名前をもたないキーマップを使用する。

プレフィクスキーのキーマップバインディングは、プレフィクスキーに続くイベントをルックアップするために使用されます(これは関数定義がキーマップであるようなシンボルかもしれない。効果は同じだがシンボルはプレフィクスキーにたいする名前の役割を果たす)。したがってC-xのバインディングはシンボルControl-X-prefixであり、このシンボルの関数セルがC-xコマンドにたいするキーマップを保持します(ctl-x-mapの値も同じキーマップ)。

プレフィクスキー定義は任意のアクティブなキーマップ内に置くことができます。プレフィクスキーとしてのC-cC-xC-hESCの定義はグローバルマップ内にもあるので、これらのプレフィクスキーは常に使用できます。メジャーモードとマイナーモードは、ローカルマップやマイナーモードのマップ内にプレフィクスキー定義を置くことによってキーをプレフィクスキーとして再定義できます。アクティブなキーマップを参照してください。

あるキーが複数のアクティブなマップ内でプレフィクスキーとして定義されていると、それぞれの定義がマージされて効果をもちます。まずマイナーモードキーマップ内で定義されたコマンド、次にローカルマップのプレフィクス定義されたコマンド、そしてグローバルマップのコマンドが続きます。

以下の例ではローカルキーマップ内でC-pC-xと等価なプレフィクスキーにしています。するとC-p C-fにたいするバインディングはC-x C-fと同様に関数find-fileになります。これとは対照的にキーシーケンスC-p 9はすべてのアクティブなキーマップで見つけることができません。

(use-local-map (make-sparse-keymap))
    ⇒ nil
(keymap-local-set "C-p" ctl-x-map)
    ⇒ (keymap #^[nil nil keymap …
(keymap-lookup nil "C-p C-f")
    ⇒ find-file
(keymap-lookup nil "C-p 9")
    ⇒ nil
Function: define-prefix-command symbol &optional mapvar prompt

この関数はプレフィクスキーのバインディングとして使用するためにsymbolを用意する。これはsparseキーマップを作成してそれをsymbolの関数定義として格納する。その後はsymbolにキーシーケンスをバインディングすると、そのキーシーケンスはプレフィクスキーになるだろう。リターン値はsymbol

この関数は値がそのキーマップであるような変数としてもsymbolをセットする。しかしmapvarが非nilなら、かわりにmapvarを変数としてセットする。

promptが非nilなら、これはそのキーマップにたいするoverallプロンプト文字列になる。プロンプト文字列はメニューキーマップにたいして与えらること(メニューの定義を参照)。


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

23.7 アクティブなキーマップ

Emacsには多くのキーマップを含まれていますが、常にいくつかのキーマップだけがアクティブです。Emacsがユーザー入力を受け取ったとき、それは入力イベントに変換されて(イベントシーケンス変換のためのキーマップを参照)、アクティブなキーマップ内でキーバインディングがルックアップされます。

アクティブなキーマップは通常は、(1) keymapプロパティにより指定されるキーマップ、(2) 有効なマイナーモードのキーマップ、(3) カレントバッファーのローカルキーマップ、(4) グローバルキーマップの順です。Emacsは入力キーシーケンスそれぞれにたいして、これらすべてのキーマップ内を検索します。

これらの通常のキーマップのうち最優先されるのは、もしあればポイント位置のkeymapテキストにより指定されるキーマップかoverallプロパティです(マウス入力イベントにたいしてはEmacsはポイント位置のかわりにイベント位置を使用する。 アクティブなキーマップの検索を参照されたい)。

次に優先されるのは有効なマイナーモードにより指定されるキーマップです。もしあればこれらのキーマップは変数emulation-mode-map-alistsminor-mode-overriding-map-alistminor-mode-map-alistにより指定されます。アクティブなキーマップの制御を参照してください。

次に優先されるのはバッファーのローカルキーマップ(local keymap)で、これにはそのバッファー特有なキーバインディングが含まれます。ミニバッファーもローカルキーマップをもちます(ミニバッファーの概要を参照)。ポイント位置にlocal-mapテキスト、またはoverlayプロパティがあるなら、それはバッファーのデフォルトローカルキーマップのかわりに使用するローカルキーマップを指定します。

ローカルキーマップは通常はそのバッファーのメジャーモードによってセットされます。同じメジャーモードをもつすべてのバッファーは、同じローカルキーマップを共有します。したがってあるバッファーでローカルキーマップを変更するためにkeymap-local-set (キーのバインドのためのコマンドを参照)を呼び出すと、それは同じメジャーモードをもつ他のバッファーのローカルキーマップにも影響を与えます。

最後はC-fのようなカレントバッファーとは関係なく定義されるキーバインディングを含んだグローバルキーマップ(global keymap)です。このキーマップは常にアクティブであり変数global-mapにバインドされています。

これら通常のキーマップとは別に、Emacsはプログラムが他のキーマップをアクティブにするための特別な手段を提供します。1つ目はグローバルキーマップ以外の通常アクティブなキーマップを置き換えるキーマップを指定する変数overriding-local-mapです。2つ目は他のすべてのキーマップより優先されるキーマップを指定する端末ローカル変数overriding-terminal-local-mapです。この端末ローカル変数は通常はmodal(訳注: 他のキーマップを選択できない状態)かつ一時的なキーバインディングに使用されます(ここの変数にたいして関数set-transient-mapは便利なインターフェイスを提供する)。詳細はアクティブなキーマップの制御を参照してください。

これらを使用するのがキーマップをアクティブにする唯一の方法ではありません。キーマップはread-key-sequenceによるイベントの変換のような他の用途にも使用されます。イベントシーケンス変換のためのキーマップを参照してください。

いくつかの標準的なキーマップのリストは標準的なキーマップを参照してください。

Function: current-active-maps &optional olp position

これはカレント状況下でコマンドループによりキーシーケンスをルックアップするために使用される、アクティブなキーマップのリストをリターンする。これは通常はoverriding-local-mapoverriding-terminal-local-mapを無視するが、olpが非nilなら、それらのキーマップにも注意を払う。オプションでpositionevent-startによってリターンされるイベント位置、またはバッファー位置を指定でき、keymap-lookup (keymap-lookupを参照)で説明されているようにキーマップを変更するかもしれない。


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

23.8 アクティブなキーマップの検索

以下はEmacsがアクティブなキーマップを検索する方法を示すLisp処理の概要です:

(or (if overriding-terminal-local-map
        (find-in overriding-terminal-local-map))
    (if overriding-local-map
        (find-in overriding-local-map)
      (or (find-in (get-char-property (point) 'keymap))
          (find-in-any emulation-mode-map-alists)
          (find-in-any minor-mode-overriding-map-alist)
          (find-in-any minor-mode-map-alist)
          (if (get-char-property (point) 'local-map)
              (find-in (get-char-property (point) 'local-map))
            (find-in (current-local-map)))))
    (find-in (current-global-map)))

ここでfind-infind-in-anyはそれぞれ、1つのキーマップとキーマップのalistを検索する仮の関数です。関数set-transient-mapoverriding-terminal-local-map (アクティブなキーマップの制御を参照)をセットすることによって機能する点に注意してください。

上記の処理概要ではキーシーケンスがマウスイベント(マウスイベントを参照)で始まる場合には、ポイント位置のかわりにそのイベント位置、カレントバッファーのかわりにそのイベントのバッファーが使用されます。これは特にプロパティkeymaplocal-mapをルックアップする方法に影響を与えます。displaybefore-stringafter-stringプロパティ(特殊な意味をもつプロパティを参照)が埋め込まれていてkeymaplocal-mapプロパティが非nilの文字列上でマウスイベントが発生すると、それは基調となるバッファーテキストの対応するプロパティをオーバーライドします(バッファーテキストにより指定されたプロパティは無視される)。

アクティブなキーマップの1つでキーバインディングが見つかって、そのバインディングがコマンドなら検索は終了してそのコマンドが実行されます。しかしそのバインディングが値をもつ変数か文字列なら、Emacsは入力キーシーケンスをその変数の値か文字列で置き換えて、アクティブなキーマップの検索を再開します。 キーの照合を参照してください。

最終的に見つかったコマンドもリマップされるかもしれません。コマンドのリマップを参照してください。


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

23.9 アクティブなキーマップの制御

Variable: global-map

この変数はEmacsキーボード入力をコマンドにマップするデフォルトのグローバルキーマップを含む。通常はこのキーマップがグローバルキーマップである。デフォルトグローバルキーマップはself-insert-commandをすべてのプリント文字にバインドするfullキーマップである。

これはグローバルキーマップ内のバインディングを変更する通常の手段だが、この変数に開始時のキーマップ以外の値を割り当てるべきではない。

Function: current-global-map

この関数はカレントのグローバルキーマップをリターンする。デフォルトグローバルキーマップとカレントグローバルキーマップのいずれも変更していなければglobal-mapと同じ値。リターン値はコピーではなく参照である。これにkeymap-setなどの関数を使用すると、グローバルバインディングが変更されるだろう。

(current-global-map)
⇒ (keymap [set-mark-command beginning-of-line …
            delete-backward-char])
Function: current-local-map

この関数はカレントバッファーのローカルキーマップをリターンする。ローカルキーマップがなければnilをリターンする。以下の例では、(Lisp Interactionモードを使用する)*scratch*バッファーにたいするキーマップは、ESC(ASCIIコード27)にたいするエントリーが別のsparseキーマップであるようなsparseキーマップである。

(current-local-map)
⇒ (keymap
    (10 . eval-print-last-sexp)
    (9 . lisp-indent-line)
    (127 . backward-delete-char-untabify)
    (27 keymap
        (24 . eval-defun)
        (17 . indent-sexp)))

current-local-mapはローカルキーマップのコピーではなく参照をリターンします。これにkeymap-setなどの関数を使用するとローカルバインディングが変更されるでしょう。

Function: current-minor-mode-maps

この関数はカレントで有効なメジャーモードのキーマップリストをリターンする。

Function: use-global-map keymap

この関数はkeymapを新たなカレントグローバルキーマップにする。これはnilをリターンする。

グローバルキーマップの変更は異例である。

Function: use-local-map keymap

この関数はkeymapをカレントバッファーの新たなローカルキーマップにする。keymapnilなら、そのバッファーはローカルキーマップをもたない。use-local-mapnilをリターンする。ほとんどのメジャーモードコマンドはこの関数を使用する。

Variable: minor-mode-map-alist

この変数はアクティブかどうかに関わらず、特定の変数の値にたいするキーマップを示すalistである。要素は以下のようになる:

(variable . keymap)

キーマップkeymapvariableが非nil値をもつときはアクティブである。variableは通常はメジャーモードを有効か無効にする変数である。キーマップとマイナーモードを参照のこと。

minor-mode-map-alistの要素がminor-mode-alistの要素と異なる構造をもつことに注意。マップは要素のCDRでなければならず、そうでなければ2つ目の要素にマップリストは用いられないだろう。CDRはキーマップ(リスト)、または関数定義がキーマップであるようなシンボルである。

1つ以上のマイナーモードキーマップがアクティブなとき、minor-mode-map-alist内で前のキーマップが優先される。しかし互いが干渉しないようにマイナーモードをデザインすること。これを正しく行えば順序は問題にならない。

マイナーモードについての詳細な情報は、キーマップとマイナーモードを参照のこと。minor-mode-key-binding (キー照合のための関数を参照)も確認されたい。

Variable: minor-mode-overriding-map-alist

この変数はメジャーモードによる特定のマイナーモードにたいするキーバインディングのオーバーライドを可能にする。このalistの要素はminor-mode-map-alistの要素のような(variable . keymap)という形式である。

ある変数がminor-mode-overriding-map-alistの要素として出現するなら、その要素によって指定されるマップはminor-mode-map-alist内の同じ変数にたいして指定されるすべてのマップを完全に置き換える。

すべてのバッファーにおいてminor-mode-overriding-map-alistは自動的にバッファーローカルである。

Variable: overriding-local-map

この変数が非nilならバッファーのローカルキーマップ、テキストプロパティまたはoverlayによるキーマップ、マイナーモードキーマップのかわりに使用されるするキーマップを保持する。このキーマップが指定されると、カレントグローバルキーマップ以外のアクティブだった他のすべてのマップがオーバーライドされる。

Variable: overriding-terminal-local-map

この変数が非nilならoverriding-local-map、バッファーのローカルキーマップ、テキストプロパティまたはoverlayによるキーマップ、およびすべてのマイナーモードキーマップのかわりに使用されるキーマップを保持する。

この変数はカレント端末にたいして常にローカルでありバッファーローカルにできない。複数の端末を参照のこと。これはインクリメンタル検索モードの実装に使用される。

Variable: overriding-local-map-menu-flag

この変数が非nilなら、overriding-local-mapoverriding-terminal-local-mapの値がメニューバーの表示に影響し得る。デフォルト値はnilなので、これらのマップ変数なメニューバーに影響をもたない。

これら2つのマップ変数は、たとえこれらの変数がメニューバー表示に影響し得るを与えない場合でも、メニューバーを使用してエンターされたキーシーケンスの実行には影響を与えることに注意。したがってもしメニューバーキーシーケンスが到着したら、そのキーシーケンスをルックアップして実行する前に変数をクリアーすること。この変数を使用するモードは通常は何らかの手段でこれを行っている。これらのモードは通常は“読み戻し(unread)”とexitによって処理されないイベントに応答する。

Variable: special-event-map

この変数はスペシャルイベントにたいするキーマップを保持する。あるイベント型がこのキーマップ内でバインディングをもつなら、それはスペシャルイベントであり、そのイベントにたいするバインディングはread-eventによって直接実行される。スペシャルイベントを参照のこと。

Variable: emulation-mode-map-alists

この変数はエミュレーションモードにたいして使用するキーマップのalistのリストを保持する。この変数は複数マイナーモードキーマップを使用するモードとパッケージを意図している。リストの各要素はminor-mode-map-alistと同じフォーマットと意味をもつキーマップのalistか、そのようなalist形式の変数バインディングをもつシンボルである。それぞれのalist内のアクティブなキーマップはminor-mode-map-alistminor-mode-overriding-map-alistの前に使用される。

Function: set-transient-map keymap &optional keep-pred on-exit

この関数は一時的(transient)なキーマップとしてkeymapを追加する。一時的なキーマップは1つ以上の後続するキーにたいして、他のキーマップより優先される。

keymapは通常は直後のキーをルックアップするために1回だけ使用される。しかし、オプション引数keep-predtなら、そのマップはユーザーがkeymap内で定義されたキーをタイプするまでアクティブのままとなる。keymap内にないキーをユーザーがタイプしたとき一時的キーマップは非アクティブとなり、そのキーにたいして通常のキールックアップが継続される。

keep-predには関数も指定できる。この場合にはkeymapがアクティブの間は、各コマンドの実行に優先してその関数が引数なしで呼び出される。keymapがアクティブの間、関数は非nilをリターンすること。

オプション引数on-exitが非nilなら、それはkeymapが非アクティブになった後に引数なしで呼び出される関数を指定する。

オプション引数messageには一時的なマップをアクティブ化後に表示するメッセージを指定する。messageが文字列ならメッセージ用のフォーマット文字列であり、文字列中のすべての‘%k’指定子は一時的マップのキーのリストに置き換えられる。messageの値としては、それ以外の非nil値はデフォルトのメッセージフォーマット‘Repeat with %k’を意味する。

オプション引数timeoutが非nilなら、それはkeymapを非アクティブにするまでに待機するアイドル時間を秒数で指定する数値であること。変数set-transient-map-timeoutの値が非nilなら、この引数の値をオーバーライドする。

この関数は他のすべてのアクティブなキーマップに優先される変数overriding-terminal-local-mapにたいして、keymapを追加または削除することによって機能する(アクティブなキーマップの検索を参照)。


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

23.10 キーの照合

キールックアップ(key lookup: キー照合)とは与えられたキーマップからキーシーケンスのバインディングを見つけ出すことです。そのバインディングの使用や実行はキールックアップの一部ではありません。

キールックアップはキーシーケンス内の各イベントのイベント型だけを使用して、そのイベントの残りは無視します。実際のところキールックアップに使用されるキーシーケンスは、マウスイベントをイベント全体(リスト)のかわりにイベント型のみ(シンボル)を用いるでしょう。入力イベントを参照してください。そのようなキーシーケンスはcommand-executeによる実行には不十分ですが、キーのルックアップやリバインドには十分です。

キーシーケンスが複数イベントから構成されるとき、キールックアップはイベントを順に処理します。最初のイベントのバインディングが見つかったとき、それはキーマップでなければなりません。そのキーマップ内で2つ目のイベントを見つけ出して、そのキーシーケンス内のすべてのイベントが消費されるまで、このプロセスを続けます(故に最後のイベントにたいして見つかったイベントはキーマップかどうかはわからない)。したがってキールックアッププロセスはキーマップ内で単一イベントを見つけ出す、よりシンプルなプロセスで定義されます。これが行なわれる方法はキーマップ内でそのイベントに関連するオブジェクトの型に依存します。

キーマップ内のイベント型ルックアップによる値の発見を説明するために、キーマップエントリー(keymap entry)という用語を導入しましょう(これにはメニューアイテムにたいするキーマップ内のアイテム文字列や他の余計な要素は含まれない。なぜならkeymap-lookupや他のキーマップルックアップ関数がリターン値にそれらを含まないから)。任意のLispオブジェクトがキーマップエントリーとしてキーマップに格納されるかもしれませんが、すべてがキールックアップに意味をもつわけではありません。以下のテーブルはキーマップエントリーで重要な型です:

nil

nilはそれまでにルックアップに使用されたイベントが未定義キーを形成することを意味する。最終的にキーマップがイベント型を調べるのに失敗してデフォルトバインディングも存在しないときは、そのイベント型のバインディングがnilであるのと同じである。

command

それまでにルックアップに使用されたイベントがコンプリートキーを形成して、commandがそのバインディングである。関数とは?を参照のこと。

array

array(文字列かベクター)はキーボードマクロである。それまでにルックアップに使用されたイベントはコンプリートキーを形成して、arrayがそのバインディングである。詳細はキーボードマクロを参照のこと。

keymap

それまでにルックアップに使用されたイベントはプレフィクスキーを形成する。そのキーシーケンスの次のイベントはkeymap内でルックアップされる。

list

listの意味はそのリストが何を含んでいるかに依存する:

  • listCARがシンボルkeymapなら、そのリストはキーマップでありキーマップとして扱われる(上記参照)。
  • listCARlambdaなら、そのリストはラムダ式である。これは関数とみなされてそのように扱われる(上記参照)。キーバインディングとして正しく実行されるために、この関数はコマンドでなければならずinteractive指定をもたなければならない。コマンドの定義を参照のこと。
symbol

symbolの関数定義がsymbolのかわりに使用される。もし関数定義もシンボルなら、任意の回数このプロセスが繰り返される。これは最終的にキーマップであるようなオブジェクト、コマンド、またはキーボードマクロに行き着くはずである。

キーマップとキーボードマクロ(文字列かベクター)は有効な関数ではないので関数定義にキーマップ、文字列、ベクターをもつシンボルは関数としては無効であることに注意。しかしキーバインディングとしては有効である。その定義がキーボードマクロなら、そのシンボルはcommand-execute(インタラクティブな呼び出しを参照)の引数としても有効である。

シンボルundefinedは特記するに値する。これはそのキーを未定義として扱うことを意味する。厳密に言うとそのキーは定義されているが、そのバインディングがコマンドundefinedなのである。しかしこのコマンドは未定義キーにたいして自動的に行われるのと同じことを行う。これは(dingを呼び出して)bellを鳴らすがエラーはシグナルしない。

undefinedはグローバルキーバインディングをオーバーライドして、そのキーをローカルに未定義とするために使用される。nilにローカルにバインドしてもグローバルバインディングをオーバーライドしないであろうから、これを行うのに失敗するだろう。

anything else

オブジェクトの他の型が見つかったら、それまでにルックアップで使用されたイベントはコンプリートキーを形成してそのオブジェクトがバインディングになるが、そのバインディングはコマンドとして実行不可能である。

要約するとキーマップエントリーはキーマップ、コマンド、キーボードマクロ、あるいはそれらに導出されるシンボル、あるいはnilのいずれかです。


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

23.11 キー照合のための関数

以下はキールックアップに関連する関数および変数です。

Function: keymap-lookup keymap key &optional accept-defaults no-remap position

この関数はkeymap内のkeyの定義をリターンする。このチャプターで説明されているキーをルックアップする他のすべての関数がkeymap-lookupを使用する。以下は例:

(keymap-lookup (current-global-map) "C-x C-f")
    ⇒ find-file
(keymap-lookup (current-global-map) "C-x C-f 1 2 3 4 5")
    ⇒ 2

文字列かベクターのkeykeymap内で指定されるプレフィクスキーとして有効なキーシーケンスでなければ、それは最後に余計なイベントをもった、単一のキーシーケンスに適合しない長過ぎるキーのはずである。その場合のリターン値は数となり、この数はコンプリートキーを構成するkeyの前にあるイベントの数である。

accept-defaultsが非nilなら、keymap-lookupkey内の特定のイベントにたいするバインディングと同様にデフォルトバインディングも考慮する。それ以外ではkeymap-lookupは特定のkeyのシーケンスにたいするバインディングだけを報告して、明示的に指定したとき以外はデフォルトバインディングを無視する(これを行うにはkeyの要素としてtを与える。キーマップのフォーマットを参照)。

keyがメタ文字(ファンクションキーではない)を含むなら、その文字は暗黙にmeta-prefix-charの値と対応する非メタ文字からなる2文字シーケンスに置き換えられる。したがって以下の1つ目の例は2つ目の例に変換されて処理される。

(keymap-lookup (current-global-map) "M-f")
    ⇒ forward-word
(keymap-lookup (current-global-map) "ESC f")
    ⇒ forward-word

keymap引数はnilでもよい。これはカレントキーマップ(current-active-mapsによってリターンされるキーマップ; アクティブなキーマップを参照)でkeyを探すことを意味する。またはキーマップやキーマップのリストでもよく、この場合には指定されたキーマップからのみキーを探すことを意味する。

read-key-sequenceとは異なり、この関数は指定されたイベントの情報を破棄する変更(キーシーケンス入力を参照)を行わない。特にこの関数はアルファベット文字を小文字に変更せず、ドラッグイベントをクリックイベントに変更しない。

keymap-lookupは通常のコマンドループが行うように、カレントキーマップ内のコマンドを調べることによってkeyを見つけ出し、その結果によってコマンドのリマップを行う。ただしオプションの第3引数no-remapが非nilなら。keymap-lookupはリマップをせずにそのコマンドをリターンする。

オプション引数positionが非nilなら、それはevent-startevent-endがリターンするようなマウス位置を指定する。そしてルックアップはkeymapではなく、その位置に関連付けられているキーマップにたいして行われる。positionは数値かマーカーでもよく、その場合にはバッファー位置として解釈されて、この関数はポイント位置ではなく指定した位置のキーマッププロパティを使用する。

Command: undefined

キーを未定義にするためにキーマップ内で使用される。これはdingを呼び出すがエラーを発生ささない。

Function: keymap-local-lookup key &optional accept-defaults

この関数はカレントのローカルキーマップ内のkeyにたいするバインディングをリターンする。カレントのローカルキーマップ内で未定義ならnilをリターンする。

引数accept-defaultskeymap-lookup(上記)と同じようにデフォルトバインディングのチェックを制御する。

Function: keymap-global-lookup key &optional accept-defaults

この関数はカレントのグローバルキーマップ内でコマンドkeyにたいするバインディングをリターンする。カレントのグローバルキーマップ内で未定義ならnilをリターンする。

引数accept-defaultskeymap-lookup(上記)と同じようにデフォルトバインディングのチェックを制御する。

Function: minor-mode-key-binding key &optional accept-defaults

この関数はアクティブなマイナーモードのkeyのバインディングをリストでリターンする。より正確にはこの関数は(modename . binding)のようなペアのalistをリターンする。ここでmodenameなそのマイナーモードを有効にする変数、bindingはそのモードでのkeyのバインディングである。keyがマイナーモードバインディングをもたなければ値はnil

最初に見つかったバインディングがプレフィクス定義(キーマップ、またはキーマップとして定義されたシンボル)でなければ、他のマイナーモードに由来するすべての後続するバインディングは完全にshadowされて省略される。同様にこのリストはプレフィクスバインディングに後続する非プレフィクスバインディングは省略される。

引数accept-defaultskeymap-lookup(上記)と同じようにデフォルトバインディングのチェックを制御する。

User Option: meta-prefix-char

この変数はメタ/プレフィクス文字コードである。これはメタ文字をキーマップ内でルックアップできるように2文字シーケンスに変換する。有用な結果を得るために値はプレフィクスイベント(プレフィクスキーを参照)であること。デフォルト値は27で、これはESCにたいするASCIIコード。

meta-prefix-charの値が27であるような限り、キールックアップは通常はbackward-wordコマンドとして定義されるM-bESC bに変換する。しかしmeta-prefix-charを24(C-xのコード)にセットすると、EmacsはM-bC-x bに変換するだろうが、これの標準のバインディングはswitch-to-bufferコマンドである。以下に何が起こるかを示す(実際にこれを行ってはならない!):

meta-prefix-char                    ; デフォルト値
     ⇒ 27
(key-binding "\M-b")
     ⇒ backward-word
?\C-x                               ; 文字.の
     ⇒ 24                          ; プリント表現
(setq meta-prefix-char 24)
     ⇒ 24
(key-binding "\M-b")
     ⇒ switch-to-buffer            ; 今やM-bをタイプすると
                                    ;   C-x bをタイプしたようになる

(setq meta-prefix-char 27)          ; 混乱を避けよう!
     ⇒ 27                          ; デフォルト値をリストア!

この単一イベントから2イベントへの変換は文字にたいしてのみ発生し、他の種類の入力イベントには発生しない。したがってファンクションキーM-F1ESC F1に変換されない。


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

23.12 キーバインディングの変更

キーのリバインド(rebind: 再バインド、再束縛)は、キーマップ内でそのキーのバインディングエントリーを変更することによって行われます。グローバルキーマップ内のバインディングを変更すると、その変更は(たとえローカルバインディングによりグローバルバインディングをshadowしているバッファーでは直接影響しないとしても)すべてのバッファーに影響します。カレントバッファーのローカルマップを変更すると、通常は同じメジャーモードを使用するすべてのバッファーに影響します。関数keymap-global-setkeymap-local-setは、これらの操作のための使いやすいインターフェイスです(キーのバインドのためのコマンドを参照)。より汎用的な関数keymap-setを使用することもできます。その場合には変更するマップを明示的に指定しなければなりません。

Lispプログラムでリバインドするキーシーケンスを選択するときは、さまざまなキーの使用についてのEmacsの慣習にしたがってください(キーバインディング規約を参照)。

以下の関数はkeymapがキーマップではない、あるいはkeyが有効なキーでなければエラーをシグナルします。

keyは単一のキーを表す文字列、あるいは一連のキーストロークであり、key-valid-pを満足しなければなりません。キーストロークは1つのスペース文字によって区切られています。

キーストロークはそれぞれ単一の文字、あるいは山カッコ(angle brackets)で括られたイベント名です。更にすべてのキーストロークにたいして1つ以上の修飾キーが前置されているかもしれません。最後に数は限られますが特別な短縮構文をもつ文字があります。以下に例としてキーシーケンスの例を示します:

f

キーのf

S o m

Somの3文字からなるキーシーケンス。

C-c o

controlで修飾されたキーc、その後にキーo

H-<left>

hyperで修飾されたleftという名前のキー。

M-RET

metaで修飾されたreturnキー。

C-M-<space>

controlとmetaで修飾されたspaceキー。

特別な短縮構文をもつキーはNULRETTABLFDESCSPCDELだけです。

修飾キーは‘Alt-Control-Hyper-Meta-Shift-super’、すなわち‘A-C-H-M-S-s’のアルファベット順に指定する必要があります。

Function: keymap-set keymap key binding

この関数はkeymap内でkeyにたいするバインディングをセットする(keyが長さ2以上のイベントなら、その変更は実際はkeymapから辿られる他のキーマップで行なわれる)。引数bindingには任意のLispオブジェクトを指定できるが、意味があるのは特定のオブジェクトだけである(意味のある型のリストはキーの照合を参照)。keymap-setのリターン値はbindingである。

key<t>なら、それはkeymap内でデフォルトバインディングをセットする。イベントが自身のバインディングをもたないとき、そのキーマップ内にデフォルトバインディングが存在すればEmacsコマンドループはそれを使用する。

keyのすべてのプレフィクスはプレフィクスキー(キーマップにバインドされる)か未定義のいずれかでなけらばならず、それ以外ならエラーがシグナルされる。keyのいくつかのプレフィクスが未定義ならkeymap-setはそれをプレフィクスキーとして定義するので、残りのkeyは指定されたように定義できる。

前にkeymap内でkeyにたいするバインディングが存在しなければ、新たなバインディングがkeymapの先頭に追加される。キーマップ内のバインディングの順序はキーボード入力にたいし影響を与えないが、メニューキーマップにたいしては問題となる(メニューキーアップを参照)。

Function: keymap-unset keymap key &optional remove

これはkeymap-setの逆バージョンの関数。keymap内のkeyのバインディングを解除(unset)する(nilにセットするのと同じ)。バインディングを完全に削除する場合には、removeに非nilを指定すればよい。これに違いが生じるのは、keymapに親キーマップがある場合のみ。子マップでキーのバインディングを解除しただけでは、依然としてそれが親マップの同じキーをシャドーし続けるだろう。removeを使うことによって、親キーマップのキーが用いられることになる。

注意: removeに非nilを指定してのkeymap-unsetの使用は、ユーザーがinitファイルに記述する場合を想定したものです。Emacsパッケージは他のパッケージのキーマップを変更するべきではなく、いずれにせよ自身のキーマップにたいして完全な制御を有しているので、可能であれば使用を避けてください。

以下はsparseキーマップを作成してその中にバインディングをいくつか作成する例:

(setq map (make-sparse-keymap))
    ⇒ (keymap)
(keymap-set map "C-f" 'forward-char)
    ⇒ forward-char
map
    ⇒ (keymap (6 . forward-char))

;; C-xにたいしsparseサブマップを作成して
;; その中でfをバインドする
(keymap-set map "C-x f" 'forward-word)
    ⇒ forward-word
map
⇒ (keymap
    (24 keymap                ; C-x
        (102 . forward-word)) ;      f
    (6 . forward-char))       ; C-f

;; C-pctl-x-mapにバインド
(keymap-set map "C-p" ctl-x-map)
;; ctl-x-map
⇒ [nil … find-file … backward-kill-sentence]

;; ctl-x-map内でC-ffooにバインド
(keymap-set map "C-p C-f" 'foo)
⇒ 'foo
map
⇒ (keymap     ; ctl-x-map内のfooに注目
    (16 keymap [nil … foo … backward-kill-sentence])
    (24 keymap
        (102 . forward-word))
    (6 . forward-char))

C-p C-fにたいする新たなバインディングの格納は、実際にはctl-x-map内のエントリーを変更することによって機能し、これはデフォルトグローバルマップ内のC-p C-fC-x C-fの両方のバインディングを変更する効果をもつことに注意。

一般的にキーマップ内でキーを定義する際に主に作業を担うのがkeymap-setです。ただしモードを記述する際には一度に大量のキーのバインドを要することが多々あり、それらすべてにたいしてkeymap-setを使うのは煩雑ですし、エラーも起こりやすくなります。かわりにdefine-keymapを使えばキーマップを作成して複数のキーのバインドを行うことができます。詳細についてははキーマップの作成を参照してください。

関数substitute-key-definitionはキーマップから特定のバインディングをもつキーをスキャンして、それらを異なるバインディングにリバインドする。より明快かつ多くの場合には同じ結果を生成できる他の機能として、あるコマンドから別のコマンドへのリマップがある(コマンドのリマップを参照)。

Function: substitute-key-definition olddef newdef keymap &optional oldmap

この関数はkeymap内でolddefにバインドされるすべてのキーについてolddefnewdefに置き換える。言い換えるとolddefが出現する箇所のすべてをnewdefに置き換える。この関数はnilをリターンする。

たとえば以下をEmacsの標準バインディングで行うとC-x C-fを再定義する:

(substitute-key-definition
 'find-file 'find-file-read-only (current-global-map))

oldmapが非nilなら、どのキーをリバインドするかをoldmap内のバインディングが決定するようにsubstitute-key-definitionの動作を変更する。リバインディングは依然としてoldmapではなくkeymapで発生する。したがって他のマップ内のバインディングの制御下でマップを変更することができる。たとえば、

(substitute-key-definition
  'delete-backward-char 'my-funny-delete
  my-map global-map)

これは標準的な削除コマンドにグローバルにバインドされたキーにたいしてmy-map内の特別な削除コマンドを設定する。

以下はキーマップの置き換え(substitution)の前後を示した例:

(setq map (list 'keymap
                (cons ?1 olddef-1)
                (cons ?2 olddef-2)
                (cons ?3 olddef-1)))
⇒ (keymap (49 . olddef-1) (50 . olddef-2) (51 . olddef-1))

(substitute-key-definition 'olddef-1 'newdef map)
⇒ nil
map
⇒ (keymap (49 . newdef) (50 . olddef-2) (51 . newdef))
Function: suppress-keymap keymap &optional nodigits

この関数はself-insert-commandをコマンドundefinedにリマップ(コマンドのリマップを参照)することによってfullキーマップのコンテンツを変更する。これはすべてのプリント文字を未定義にする効果をもつので、通常のテキスト挿入は不可能になる。suppress-keymapnilをリターンする。

nodigitsnilなら、suppress-keymapは数字がdigit-argument-negative-argumentを実行するように定義する。それ以外は残りのプリント文字と同じように、それらの文字も未定義にする。

suppress-keymap関数はyankquoted-insertのようなコマンドを抑制(suppress)しないのでバッファーの変更は可能。バッファーの変更を防ぐには、バッファーを読み取り専用(read-only)にすること(読み取り専用のバッファーを参照)。

この関数はkeymapを変更するので、通常は新たに作成したキーマップにたいして使用するだろう。他の目的のために使用されている既存のキーマップに操作を行うと恐らくトラブルの原因となる。たとえばglobal-mapの抑制はEmacsをほとんど使用不可能にするだろう。

この関数はテキストの挿入が望ましくないメジャーモードの、ローカルキーマップ初期化に使用され得る。しかしそのようなモードは通常はspecial-mode (基本的なメジャーモードを参照)から継承される。この場合にはそのモードのキーマップは既に抑制済みのspecial-mode-mapから自動的に受け継がれる。以下にspecial-mode-mapが定義される方法を示す:

(defvar special-mode-map
  (let ((map (make-sparse-keymap)))
    (suppress-keymap map)
    (keymap-set map "q" 'quit-window)
    …
    map))

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

23.13 低レベルなキーバインディング

歴史的にEmacsはキーを定義するために、異なる複数の構文を複数サポートしてきました。現時点ではキーをバインドする方法として文書化されているのは、key-valid-pがサポートしている構文を使用する方法です。これはkeymap-setkeymap-lookupのような関数がサポートするすべてのことを行うことができます。このセクションでは旧スタイルの構文とインターフェイス関数について記述しました。これらを新しいコードで使用するべきではありません。

define-key (およびキーのリバインドに用いられるその他の低レベル関数)は、キーにたいして複数の異なる構文を理解します。

キーのリストを含むベクター

修飾名に基本イベント(文字かファンクションキー名)を1つを加えたものをリストに含めることができる。たとえば[(control ?a) (meta b)]C-a M-b[(hyper control left)]C-H-leftと等価。

修飾された文字列

キーシーケンスは内部的にはshift、control、metaといった修飾キー用の特別なエスケープシーケンス(文字列型を参照)を用いた文字列として表現されていることがよくあるが、この表現はユーザーがキーのリバインドを行う際にも使うことができる。"\M-x""\C-f"のような文字列はそれぞれ単一のM-xC-f"\M-\C-x""\C-\M-x"はいずれも単一のC-M-xを含んだキーシーケンスとして読み取られる。

文字とキーシンボルのベクター

これはキーシーケンスを表す別の内部表現である。文字列表現よりも幅広い範囲の修飾をサポートしており、ファンクションキーもサポートしている。‘[?\C-\H-x home]を例とすると、これはC-H-x homeというキーシーケンスを表している。文字型を参照のこと。

Function: define-key keymap key binding &optional remove

これはkeymap-set (キーバインディングの変更を参照)と似ているが、旧来のキー構文だけを理解する。

この関数には更にremove引数もある。これが非nilだと、その定義は削除される。これは概ね定義にnilをセットするのと同義だが、keymapに親があってkeyが親の同一バインディングをシャドーしている場合に違いが生じる。removeの場合にはそれ以降のルックアップで親のバインディングがリターンされるが、nilの定義ではルックアップにたいしてnilがリターンされるだろう。

他にも以下のような旧来のキー定義関数とコマンドがありますが、新しいコードでは等価な新式の関数を使用してください。

Command: global-set-key key binding

この関数はカレントグローバルマップ内でkeyのバインディングをbindingにセットする。かわりにkeymap-global-setを使うこと。

Command: global-unset-key key

この関数はカレントグローバルマップからkeyのバインディングを削除する。かわりにkeymap-global-unsetを使うこと。

Command: local-set-key key binding

この関数はカレントローカルキーマップ内のkeyのバインディングをbindingにセットする。かわりにkeymap-local-setを使うこと。

Command: local-unset-key key

この関数はカレントローカルキーマップからkeyのバインディングを削除する。かわりにkeymap-local-unsetを使うこと。

Function: substitute-key-definition olddef newdef keymap &optional oldmap

この関数はkeymap内でolddefにバインドされるすべてのキーについてolddefnewdefに置き換える。言い換えるとolddefが出現する箇所のすべてをnewdefに置き換える。この関数はnilをリターンする。かわりにkeymap-substituteを使うこと。

Function: define-key-after map key binding &optional after

define-keyと同じようにmap内にkeyにたいする値bindingのバインディングを定義するが、map内でのバインディング位置はイベントafterのバインディングの後になる。引数keyは長さ1 — 1要素だけのベクターか文字列にすること。しかしafterは単一のイベント型 — シーケンスではないシンボルか文字にすること。新たなバインディングはafterのバインディングの後に追加される。aftertまたは省略された場合には、新たなバインディングはそのキーマップの最後に追加される。しかし新たなバインディングは継承されたすべてのキーマップの前に追加される。この関数ではなくkeymap-set-afterを使うこと。

Function: keyboard-translate from to

この関数は文字コードをfromからtoに変換することによってkeyboard-translate-table話変更する。かわりにkey-translateを使うこと。

Function: key-binding key &optional accept-defaults no-remap position

この関数はカレントでアクティブなキーマップに応じて、keyにたいするバインディングをリターンする。そのキーマップでkeyが未定義なら結果はnilになる。引数accept-defaultslookup-key (キー照合のための関数を参照)の場合と同じように、デフォルトのバインディングのチェックを行うかどうかを制御する。no-remapが非nilならkey-bindingはコマンドのリマップ(コマンドのリマップを参照)を無視して、keyに直接指定されているバインディングをリターンする。オプション引数positionはバッファー位置、あるいはevent-startの値のようなイベント位置のいずれかであること。これによりpositionにもとづいて照会するマップを判断するように告げる。

keyが文字列とベクターのいずれでもなければEmacsはエラーをシグナルする。

この関数ではなくかわりにkeymap-lookupを使うこと。

Function: lookup-key keymap key &optional accept-defaults

この関数はkeymapからkeyの定義をリターンする。文字列かベクターのkeykeymap内で指定されるプレフィクスキーとして有効なキーシーケンスでなければ、それは最後に余計なイベントをもった、単一のキーシーケンスに適合しない長過ぎるキーのはずである。その場合のリターン値は数となり、この数はコンプリートキーを構成するkeyの前にあるイベントの数である。

accept-defaultsが非nilなら、lookup-keykey内の特定のイベントにたいするバインディングと同様にデフォルトバインディングも考慮する。それ以外ではlookup-keyは特定のkeyのシーケンスにたいするバインディングだけを報告して、明示的に指定したとき以外はデフォルトバインディングを無視する。

この関数ではなくかわりにkeymap-lookupを使うこと。

Function: local-key-binding key &optional accept-defaults

この関数はカレントのローカルキーマップ内のkeyにたいするバインディングをリターンする。カレントのローカルキーマップ内で未定義ならnilをリターンする。

引数accept-defaultslookup-key(上記)と同じようにデフォルトバインディングのチェックを制御する。

Function: global-key-binding key &optional accept-defaults

この関数はカレントのグローバルキーマップ内でコマンドkeyにたいするバインディングをリターンする。カレントのグローバルキーマップ内で未定義ならnilをリターンする。

引数accept-defaultslookup-key(上記)と同じようにデフォルトバインディングのチェックを制御する。

Function: event-convert-list list

この修飾名のリストと基本的なイベントタイプを、それらすべてを指定するイベントタイプに変換する。基本的なイベントタイプはリストの最後の要素でなければならない。たとえば、

(event-convert-list '(control ?a))
     ⇒ 1
(event-convert-list '(control meta ?a))
     ⇒ -134217727
(event-convert-list '(control super f1))
     ⇒ C-s-f1

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

23.14 コマンドのリマップ

あるコマンドから他のコマンドへのリマップ(remap)には、特別な種類のキーバインディングが使用できます。この機能を使用するためには、ダミーイベントremapで始まり、その後にリマップしたいコマンド名が続くようなキーシーケンスにたいするキーバインディングを作成します。そしてそのバインディングにたいしては、新たな定義(通常はコマンド名だがキーバインディングにたいして有効な他の任意の定義を指定可能)を指定します。

たとえばMyモードというモードが、kill-lineのかわりに呼び出されるmy-kill-lineという特別なコマンドを提供するとします。これを設定するには、このモードのキーマップに以下のようなリマッピングが含まれるはずです:

(keymap-set my-mode-map "<remap> <kill-line>" 'my-kill-line)

その後はmy-mode-mapがアクティブなときは常に、ユーザーがC-k (kill-lineにたいするデフォルトのグローバルキーシーケンス)をタイプするとEmacsはかわりにmy-kill-lineを実行するでしょう。

リマップはアクティブなキーマップでのみ行なわれることに注意してください。たとえばctl-x-mapのようなプレフィクスキーマップ内にリマッピングを置いても、そのようなキーマップはそれ自体がアクティブでないので通常は効果がありません。それに加えてリマップは1レベルを通じてのみ機能します。以下の例では、

(keymap-set my-mode-map "<remap> <kill-line>" 'my-kill-line)
(keymap-set my-mode-map "<remap> <my-kill-line>" 'my-other-kill-line)

これはkill-linemy-other-kill-lineにリマップしません。かわりに通常のキーバインディングがkill-lineを指定する場合には、それがmy-kill-lineにリマップされます。通常のバインディングがmy-kill-lineを指定すると、my-other-kill-lineにリマップされます。

コマンドのリマップをアンドゥするには、以下のようにそれをnilにリマップします:

(keymap-set my-mode-map "<remap> <kill-line>" nil)
Function: command-remapping command &optional position keymaps

この関数はカレントアクティブキーマップによって与えられるcommand(シンボル)にたいするリマッピングをリターンする。commandがリマップされていない(これは普通の状況である)、あるいはシンボル以外なら、この関数はnilをリターンする。positionkey-bindingの場合と同様、使用するキーマップを決定するためにバッファー位置かイベント位置をオプションで指定できる。

オプション引数keymapsが非nilなら、それは検索するキーマップのリストを指定する。この引数はpositionが非nilなら無視される。


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

23.15 イベントシーケンス変換のためのキーマップ

read-key-sequence関数がキーシーケンス(キーシーケンス入力を参照)を読み取るときには、特定のイベントシーケンスを他のものに変換(translate)するために変換キーマップ(translation keymaps)を使用します。input-decode-maplocal-function-key-mapkey-translation-map(優先順)は変換キーマップです。

変換キーマップは他のキーマップと同じ構造をもちますが使い方は異なります。変換キーマップはキーシーケンスを読み取るときに、コンプリートキーシーケンスにたいするバインディングではなくキーシーケンスに行う変換を指定します。キーシーケンスが読み取られると、それらのキーシーケンスは変換キーマップにたいしてチェックされます。ある変換キーマップがkをベクターvにバインドするなら、キーシーケンス内のどこかにサブシーケンスとしてkが出現すると、それはv内のイベントに置き換えられます。

たとえばキーパッドキーPF1が押下されたとき、VT100端末はESC O Pを送信します。そのような端末ではEmacsはそのイベントシーケンスを単一イベントpf1に変換しなければなりません。これはinput-decode-map内でESC O P[pf1]にバインドすることにより行われます。したがってその端末上でC-c PF1をタイプしたとき、端末は文字シーケンスC-c ESC O Pを発行して、read-key-sequenceがそれをC-c PF1に変換、ベクター[?\C-c pf1]としてリターンします。

変換キーマップは、(keyboard-coding-systemで指定された入力コーディングシステムを通じて)Emacsがキーボード入力をデコードした直後だけ効果をもちます。端末I/Oのエンコーディングを参照してください。

Variable: input-decode-map

この変数は通常の文字端末上のファンクションキーから送信された文字シーケンスを記述するキーマップを保持する。

input-decode-mapの値は、通常はその端末のTerminfoかTermcapのエントリーに応じて自動的にセットアップされるが、Lispの端末仕様ファイルの助けが必要なときもある。Emacsには一般的な多くの端末の端末仕様ファイルが同梱されている。これらのファイルの主な目的はTermcapやTerminfoから推定できないエントリーをinput-decode-map内に作成することである。端末固有の初期化を参照のこと。

Variable: local-function-key-map

この変数はinput-decode-mapと同じようにキーマップを保持するが、通常は優先される解釈選択肢(alternative interpretation)に変換されるべきキーシーケンスを記述するキーマップを保持する。このキーマップはinput-decode-mapの後、key-translation-mapの前に適用される。

local-function-key-map内のエントリーはマイナーモード、ローカルキーマップ、グローバルキーマップによるバインディングと衝突する場合には無視される。つまり元のキーシーケンスが他にバインディングをもたない場合だけリマッピングが適用される。

local-function-key-mapfunction-key-mapを継承する。後者はすべての端末にバインディングを適用したい場合のみ修正するべきなので、ほとんど常に前者の使用が望ましい。

Variable: key-translation-map

この変数は入力イベントを他のイベントに変換するために、input-decode-mapと同じように使用される別のキーマップを保持する。input-decode-mapとの違いは、local-function-key-mapの前ではなく後に機能する点である。このキーマップはlocal-function-key-mapによる変換結果を受け取る。

input-decode-mapと同様だがlocal-function-key-mapとは異なり、このキーマップは入力キーシーケンスが通常のバインディングをもつかどうかかに関わらず適用される。しかしこのキーマップによりキーバインディングがオーバーライドされても、key-translation-mapでは実際のキーバインディングが効果をもち得ることに注意。確かに実際のキーバインディングはlocal-function-key-mapをオーバーライドし、したがってkey-translation-mapが受け取るキーシーケンスは変更されるだろう。明確にするためにはこのような類の状況は避けたほうがよい。

key-translation-mapは通常はself-insert-commandにバインディングされるような通常文字を含めて、ユーザーがある文字を他の文字にマップすることを意図している。

キーシーケンスのかわりにキーの変換として関数を使用することにより、シンプルなエイリアスより多くのことにinput-decode-maplocal-function-key-mapkey-translation-mapを使用できます。その場合にはこの関数はそのキーの変換を計算するために呼び出されます。

キー変換関数は引数を1つ受け取ります。この引数はread-key-sequence内で指定されるプロンプトです。キーシーケンスがエディターコマンドループに読み取られる場合はnilです。ほとんどの場合にはプロンプト値は無視できます。

関数が自身で入力を読み取る場合、その関数は後続のイベントを変更する効果をもつことができます。たとえば以下はC-c hをハイパー文字に後続する文字とするために定義する方法の例です:

(defun hyperify (prompt)
  (let ((e (read-event)))
    (vector (if (numberp e)
                (logior (ash 1 24) e)
              (if (memq 'hyper (event-modifiers e))
                  e
                (add-event-modifier "H-" e))))))

(defun add-event-modifier (string e)
  (let ((symbol (if (symbolp e) e (car e))))
    (setq symbol (intern (concat string
                                 (symbol-name symbol))))
    (if (symbolp e)
        symbol
      (cons symbol (cdr e)))))

(keymap-set local-function-key-map "C-c h" 'hyperify)

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

23.15.1 通常のキーマップとの対話

そのキーシーケンスがコマンドにバインドされたとき、またはさらにイベントを追加してもコマンドにバインドされるシーケンスにすることができないとEmacsが判断したときにキーシーケンスの終わりが検出されます。

これは元のキーシーケンスがバインディングをもつかどうかに関わらず、input-decode-mapkey-translation-mapを適用するときに、そのようなバインディングが変換の開始を妨げることを意味します。たとえば前述のVT100の例に戻って、グローバルマップにC-c ESCを追加してみましょう。するとユーザーがC-c PF1をタイプしたとき、EmacsはC-c ESC O PC-c PF1に変換するのに失敗するでしょう。これはEmacsがC-c ESCの直後に読み取りを停止して、O Pが読み取られずに残るからです。この場合にはユーザーが実際にC-c ESCをタイプすると、ユーザーが実際にESCを押下したのか、あるいはPF1を押下したのか判断するためにEmacsが待つべきではないのです。

この理由によりキーシーケンスの終わりがキー変換のプレフィクスであるようなキーシーケンスをコマンドにバインドするのは、避けたほうがよいでしょう。そのような問題を起こす主なサフィックス、およびプレフィクスはESCM-O (実際はESC O)、M-[ (実際はESC [)です。


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

23.16 キーのバインドのためのコマンド

このセクションではキーバインディングを変更するために役に立つ、インタラクティブなインターフェイスをいくつか説明します。これらのインターフェイスはkeymap-set (キーバインディングの変更を参照)を呼び出すことによって機能します。これらのコマンドはインタラクティブに使用すると引数keyの入力を求めて、ユーザーが有効なキーシーケンスをタイプすることを期待します。更にそのキーシーケンスにたいするbindingの入力も求めて、ユーザーがコマンド名(commandpを満足するシンボル; インタラクティブな呼び出しを参照)を入力することを期待します。これらのコマンドはLispから呼び出されるとkeyにはkey-valid-p (see キーシーケンス)を満足するような文字列、bindingにはキーマップにおいて意味をもつ任意のLispオブジェクト(キーの照合を参照)を期待します。

ユーザーはinitファイルにたいしてシンプルなカスタマイズを行うとき、しばしばkeymap-global-setを使用します。たとえば、

(keymap-global-set "C-x C-\\" 'next-line)

は、次の行に移動するようにC-x C-\を再定義します。

(keymap-global-set "M-<mouse-1>" 'mouse-set-point)

は、メタキーを押してマウスの第一ボタン(左ボタン)をクリックすると、クリックした箇所にポイントをセットするように再定義します。

バインドするキーのLisp指定に非ASCII文字のテキストを使用するときには注意してください。マルチバイトとして読み取られたテキストがあるなら、Lispファイル内でマルチバイトテキストが読み取られるときのように(ASCII文字のロードを参照)、マルチバイトとしてキーをタイプしなければなりません。たとえば、

(keymap-global-set "ö" 'my-function) ; bind o-umlaut

をLatin-1のマルチバイト環境で使用すると、これらのコマンドはLatin-1端末から送信されたバイトコード246(M-v)ではなく、コード246のマルチバイト文字に実際にはバインドされます。このバインディングを使用するためには適切な入力メソッド(Input Methods in The GNU Emacs Manualを参照)を使用して、キーボードをデコードする方法をEmacsに教える必要があります。

Command: keymap-global-set key binding

この関数はカレントグローバルマップ内でkeyのバインディングをbindingにセットする。

(keymap-global-set key binding)
≡
(keymap-set (current-global-map) key binding)
Command: keymap-global-unset key

この関数はカレントグローバルマップからkeyのバインディングを削除する。

プレフィクスとしてkeyを使用する長いキーの定義の準備に使用するのもこの関数の1つの用途である。keyが非プレフィクスのようなバインディングをもつならこの使い方は許容されないだろう。たとえば、

(keymap-global-unset "C-l")
    ⇒ nil
(keymap-global-set "C-l C-l" 'redraw-display)
    ⇒ nil
Command: keymap-local-set key binding

この関数はカレントローカルキーマップ内のkeyのバインディングをbindingにセットする。

(keymap-local-set key binding)
≡
(keymap-set (current-local-map) key binding)
Command: keymap-local-unset key

この関数はカレントローカルキーマップからkeyのバインディングを削除する。


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

23.17 キーマップのスキャン

このセクションではヘルプ情報のプリントのために、すべてのカレントキーマップのスキャンに使用される関数を説明します。特定のキーマップのバインディングを表示するにはdescribe-keymapコマンドを使用してください(Other Help Commands in The GNU Emacs Manualを参照)。

Function: accessible-keymaps keymap &optional prefix

この関数は、(0個以上のプレフィクスキーを通じて)keymapから到達可能なすべてのキーマップのリストをリターンする。リターン値は(key . map)のような形式の要素をもつ連想リスト(alist)である。ここでkeykeymap内での定義がmapであるようなプレフィクスキーである。

alistの要素はkeyの長さにたいして昇順にソートされている。1つ目の要素は常に([] . keymap)。これは指定されたキーマップがイベントなしのプレフィクスによって、自分自身からアクセス可能だからである。

prefixが与えられたら、それはプレフィクスキーシーケンスである。その場合にはprefixで始まるプレフィクスキーをもつサブマップだけがaccessible-keymapsに含まれる。これらの要素の意味は(accessible-keymaps)の値の場合と同様であり、いくつかの要素が省略されている点だけが異なる。

以下の例ではリターンされるalistにより‘^[’と表示されるキーESCがプレフィクスキーであり、その定義がsparseキーマップ(keymap (83 . center-paragraph) (115 . foo))であることが示される。

(accessible-keymaps (current-local-map))
⇒(([] keymap
      (27 keymap   ; 以降ESCにたいするこのキーマップが繰り返されることに注意
          (83 . center-paragraph)
          (115 . center-line))
      (9 . tab-to-tab-stop))

   ("^[" keymap
    (83 . center-paragraph)
    (115 . foo)))

また以下の例ではC-h(keymap (118 . describe-variable)…)で始まるsparseキーマップを使用するプレフィクスキーである。他のプレフィクスC-x 4は変数ctl-x-4-mapの値でもあるキーマップを使用する。イベントmode-lineはウィンドウの特別な箇所でのマウスイベントにたいするプレフィクスとして使用される、いくつかのダミーイベントのうちの1つである。

(accessible-keymaps (current-global-map))
⇒ (([] keymap [set-mark-command beginning-of-line …
                   delete-backward-char])
    ("^H" keymap (118 . describe-variable) …
     (8 . help-for-help))
    ("^X" keymap [x-flush-mouse-queue …
     backward-kill-sentence])
    ("^[" keymap [mark-sexp backward-sexp …
     backward-kill-word])
    ("^X4" keymap (15 . display-buffer) …)
    ([mode-line] keymap
     (S-mouse-2 . mouse-split-window-horizontally) …))

これらが実際に目にするであろうキーマップのすべてではない。

Function: map-keymap function keymap

関数map-keymapkeymap内のバインディングそれぞれにたいして1回functionを呼び出す。呼び出す際の引数はイベント型と、そのバインディングの値の2つ。keymapに親キーマップがあれば、その親キーマップのバインディングも含まれる。これは再帰的に機能する。つまりその親キーマップ自身が親キーマップをもてば、それのバインディングも含まれる、といった具合である。

これはキーマップ内のすべてのバインディングを検証するもっとも明快な方法である。

Function: where-is-internal command &optional keymap firstonly noindirect no-remap

この関数はwhere-isコマンド(Help in The GNU Emacs Manualを参照)により使用されるサブルーチンである。これはキーマップのセット内でcommandにバインドされる、(任意の長さの)キーシーケンスすべてのリストをリターンする。

引数commandには任意のオブジェクトを指定できる。このオブジェクトはすべてのキーマップエントリーにたいして、eqを使用して比較される。

keymapnilなら、overriding-local-mapの値とは無関係に(overriding-local-mapの値がnilであると装って)、カレントアクティブキーマップをマップとして使用する。keymapがキーマップならkeymapとグローバルキーマップが検索されるマップとなる。keymapがキーマップのリストなら、それらのキーマップだけが検索される。

keymapにたいする式としては、通常はoverriding-local-mapを使用するのが最善である。その場合にはwhere-is-internalは正にアクティブなキーマップを検索する。グローバルマップだけを検索するにはkeymapの値に(keymap)(空のキーマップ)を渡せばよい。

firstonlynon-asciiなら、値はすべての可能なキーシーケンスのリストではなく最初に見つかったキーシーケンスを表す単一のベクターとなる。firstonlytなら、値は最初のキーシーケンスだが全体がASCII文字(またはメタ修飾されたASCII文字)で構成されるキーシーケンスが他のすべてのキーシーケンスに優先されて、リターン値がメニューバインディングになることは決してない。

noindirectが非nilならwhere-is-internalは自身のコマンドを探すためにメニューアイテムの内部を調べない。これによりメニューアイテム自体の検索が可能になる。

5つ目の引数no-remapはこの関数がコマンドリマッピング(コマンドのリマップを参照)を扱う方法を決定する。興味深いケースが2つある:

コマンドother-commandcommandにリマップされる場合:

no-remapnilならother-commandにたいするバインディングを探して、commandにたいするバインディングであるかのようにそれらを扱う。no-remapが非nilならそれらのバインディングを探すかわりに、利用可能なキーシーケンスリストにベクター[remap other-command]を含める。

commandother-commandにリマップされる場合:

no-remapnilなら、commandではなくother-commandにたいするバインディングをリターンする。no-remapが非nilなら、リマップされていることを無視してcommandにたいするバインディングをリターンする。

[some-event]のようなキーバインディングをマップするコマンドがあり、some-eventには非nilnon-key-eventプロパティを含んだシンボルplistがある場合には、そのバインディングはwhere-is-internalによって無視される。

Command: describe-bindings &optional prefix buffer-or-name

この関数はすべてのカレントキーバインディングのリストを作成して、*Help*という名前のバッファーにそれを表示する。テキストはモードごとにグループ化されて順番はマイナーモード、メジャーモード、グローバルバインディングの順である。

prefixが非nilなら、それはプレフィクスキーである。その場合にはリストに含まれるのはprefixで始まるキーだけになる。

複数の連続するASCIIコードが同じ定義をもつとき、それらは‘firstchar..lastchar’のようにまとめて表示される。この場合にはそれがどの文字に該当するかを理解するには、そのASCIIコードを知っている必要がある。たとえばデフォルトグローバルマップでは文字‘SPC .. ~’は1行で記述される。SPCASCIIの32,~ASCIIの126で、その間のすべての文字には通常のプリント文字(アルファベット文字や数字、区切り文字等)が含まれる。これらの文字はすべてself-insert-commandにバインドされる。

buffer-or-nameが非nilのならそれはバッファーかバッファー名である。その場合はdescribe-bindingsはカレントバッファーのかわりに、そのバッファーのバインディングをリストする。


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

24 メジャーモードとマイナーモード

モード(mode)とはEmacsの挙動を簡便な方法でカスタマイズする定義のセットです。モードは2種類あります。マイナーモード(minor modes)は編集時にユーザーがオンとオフを切り替えられる機能を提供します。メジャーモード(major modes)は特定の種類のテキストにたいする編集や相互作用に使用します。ある時点においてバッファーはそれぞれ正確に1つのメジャーモードをもちます。

このチャプターではメジャーモードとマイナーモードを記述する方法、それらをモードラインに示す方法、そしてそれらのモードがユーザーが提供するフックを実行する方法を説明します。キーマップ(keymaps)や構文テーブル(syntax tables)のような関連するトピックについてはキーマップ構文テーブルを参照してください。


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

24.1 フック

フック(hook)とは既存のプログラムから特定のタイミングで呼び出される関数(複数可)を格納できる変数のことです(関数とは?を参照)。Emacsはカスタマイズ用にフックを提供します。ほとんどの場合にはinitファイル内(initファイルを参照)でフックをセットアップしますが、Lispプログラムもフックをセットできます。標準的なフック変数のリストは標準的なフックを参照してください。

Emacsのほとんどのフックはノーマルフック(normal hooks)です。これらの変数は、引数なしで呼び出される関数のリストを含んでいます。慣習により名前が‘-hook’で終わるフックは、そのフックがノーマルフックであることを意味します。わたしたちは一貫した方法でフックを使用できるように、すべてのフックが可能な限りノーマルフックとなるよう努力しています。

すべてのメジャーモードコマンドは、初期化の最終ステップの1つとして、モードフック(mode hook)と呼ばれるノーマルフックを実行するとみなされます。これによってそのモードですでに作成されたバッファーローカル変数割り当てをオーバーライドすることにより、ユーザーがそのモードの動作をカスタマイズするのが簡単になります。ほとんどのマイナーモード関数も最後にモードフックを実行します。しかしフックは他のコンテキストでも使用されます。たとえばフックsuspend-hookは、Emacsが自身をサスペンド(Emacsのサスペンドを参照)する直前に実行されます。

フック変数の名前が‘-hook’で終わらなければ、それが恐らくアブノーマルフック(abnormal hook)であることを示しています。これらとノーマルフック違うのはフック関数が1つ以上の引数とともに呼ぶ出されること、何らかの方法によってそのリターン値が使用されることという2つの点です。その関数の呼び出し方や引数の使われ方はそのフックのドキュメントに記載されています。アブノーマルフックに追加する関数は、フックの呼び出し規約にしたがって関数を記述しなければなりません。慣習によりアブノーマルフックの名前の最後は‘-functions’です。

変数名の最後が‘-predicate’や‘-function’ (単数形)なら、値は関数のリストではなく単一の関数でなければなりません。このような単一関数フック(single function hook)が期待する引数やリターン値の意味はアブノーマルフックと同様さまざまです。それらの詳細については、各変数のdocstringで説明されています。

フック(単一関数と複数関数の両方)とは変数なので、値はsetq、または一時的にletで変更できます。しかしフックがもつ他の関数を保持しつつ、特定の関数の追加や削除ができると便利なことがあります。複数関数フックでこれを行う推奨方法はadd-hookremove-hookです(フックのセットを参照)。ほとんどのノーマルフック変数の初期値はvoidであり、add-hookはこれを扱う方法を理解しています。フックへのグローバルまたはバッファーローカルな追加はadd-hookで行うことができます。単一の関数だけを保持するフックではadd-hookは不適切ですが、フックに新たな関数を組み合わせるためにadd-function (Emacs Lisp関数にたいするアドバイスを参照)を使用できます。いくつかの単一関数フックはadd-functionが扱えないnilかもしれないので、add-functionの呼び出し前にそれをチェックしなければならないことに注意してください。


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

24.1.1 フックの実行

このセクションではノーマルフックを実行するために使用されるrun-hooksについて説明します。またさまざまな種類のアブノーマルフックを実行する関数についても説明します。

Function: run-hooks &rest hookvars

この関数は引数として1つ以上のノーマルフック変数名を受け取って、各フックを順に実行する。引数はそれぞれノーマルフック変数であるようなシンボルであること。これらの引数は指定された順に処理される。

フック変数の値が非nilならその値は関数のリストであること。run-hooksはすべての関数を引数なしで1つずつ呼び出す。

フック変数の値には、単一の関数(ラムダ式、またはシンボルの関数定義)も指定でき、その場合run-hooksはそれを呼び出す。しかしこの使い方は時代遅れである。

フック変数がバッファーローカルならグローバル変数のかわりにそのバッファーローカル変数が使用される。しかしそのバッファーローカル変数が要素tを含む場合には、そのグローバルフック変数も同様に実行されるだろう。

Function: run-hook-with-args hook &rest args

この関数は、hook内のすべての関数に1つの引数argsを渡して呼び出すことによってアブノーマルフックを実行する。

Function: run-hook-with-args-until-failure hook &rest args

この関数は各フック関数を順に呼び出すことによりアブノーマルフック関数を実行し、それらのうち1つがnilをリターンして失敗すると停止する。それぞれのフック関数は引数としてargsを渡される。この関数はフック関数の1つが失敗して停止したらnil、それ以外は非nil値をリターンする。

Function: run-hook-with-args-until-success hook &rest args

この関数は各フック関数を順に呼び出すことによりアブノーマルフック関数を実行して、それらのうち1つが非nil値をリターンして成功したら停止する。それぞれのフック関数は引数としてargsを渡される。この関数はフック関数の1つが失敗して停止したらその値、それ以外はnilをリターンする。


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

24.1.2 フックのセット

以下はLisp InteractionモードのときにAuto Fillモードをオンに切り替えるためにモードフックに関数を追加する例です:

(add-hook 'lisp-interaction-mode-hook 'auto-fill-mode)

フック変数の値は関数のリストにする必要があります。通常のLisp機能を使用してこのリストを操作できますが、モジュール方式では以下で説明する関数add-hookremove-hookを使用します。これらの関数はいくつかの異常な状況を処理して問題を回避します。

フックにlambda式を配置しても機能しますが、これは混乱を招くので避けることを推奨します。2回目は記述を微妙に変えて同じlambda式を追加すると、そのフックは等価な2つの別々の関数をもつことになります。それから一方を削除しても、もう一方は残り続けるでしょう。

Function: add-hook hook function &optional depth local

この関数はフック変数に関数functionを追加する手軽な方法である。ノーマルフックと同じようにアブノーマルフックにたいしてもこの関数を使用できる。functionには正しい数の引数を受け付ける任意のLisp関数を指定できる。たとえば、

(add-hook 'text-mode-hook 'my-text-hook-function)

text-mode-hookと呼ばれるフックにmy-text-hook-functionを追加する。

hook内にfunctionがすでに存在する場合(比較にはequalを使用)、add-hookは2回目の追加を行わない。

functionのプロパティpermanent-local-hookが非nilならkill-all-local-variables(またはメジャーモードを変更しても)はそのフック変数のローカル値から関数を削除しない。

ノーマルフックにたいしてフック関数は実行される順序に無関係であるようにデザインされるべきである。順序への依存はトラブルを招く。とはいえその順序は予測可能である。functionは通常はフックリストの先頭に追加されるので、(他のadd-hook呼び出しがなければ)それは最初に実行される。

いくつかのケースではフック上の相対順序の制御が重要になる。オプション引数によりリストのどこに関数を挿入するべきかを指定できる。値は-100から100の数値であり、より大きい値では関数はリストの終端に近づく。depthのデフォルトは0であり、後方互換のために非nilならdepthを90と解釈する。さらにdepthが厳密に0より大なら、関数は同じdepthの関数の前ではなくに追加される。あなたの関数の前(や後)に他の関数を配置する必要が絶対ないとは限らないので、100(や-100)のをdepthは決して使用しないこと。

add-hookhookがvoidのとき、または値が単一の関数の場合には、値を関数リストにセットまたは変更してそれらを扱うことができる。

localが非nilなら、グローバルフックリストではなくバッファーローカルフックリストにfunctionを追加する。これはフックをバッファーローカルにして、そのバッファーローカルな値にtを追加する。バッファーローカルな値へのtの追加は、ローカル値と同じようにデフォルト値でもフック関数を実行するためのフラグである。

Function: remove-hook hook function &optional local

この関数はフック変数hookからfunctionを削除する。これはequalを使用してfunctionhook要素を比較するので、その比較はシンボルとラムダ式の両方で機能する。

localが非nilなら、それはグローバルフックリストではなくバッファーローカルフックリストからfunctionを削除する。


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

24.2 メジャーモード

メジャーモードは特定の種類のテキストの編集や相互作用にたいしてEmacsを特化します。すべてのバッファーは一度に1つのメジャーモードをもちます。すべてのメジャーモードは、メジャーモードコマンド(major mode command)に関連付けられ、そのコマンド名は‘-mode’で終わるべきです。このコマンドは、ローカルキーマップのようなさまざまなバッファーローカル変数をセットすることにより、カレントバッファー内でそのモードに切り替える配慮をします。メジャーモードの慣習を参照してください。マイナーモードとは異なりメジャーモードを“オフに切り替える”手段は存在せず、かわりにバッファーは別のメジャーモードに切り替えられなければなりません。しかしメジャーモードを一時的にサスペンドして、後でサスペンドしたモードをリストアできます。以下を参照してください。

Fundamentalモードと呼ばれるモードはもっとも特化されていないメジャーモードであり、モード特有な定義や変数セッティングをもちません。

Command: fundamental-mode

これはFundamentalモードにたいするメジャーモードコマンドである。他のモードコマンドと異なり、このモードはカスタマイズしてはならないことになっているので、モードフックは何も実行されない(メジャーモードの慣習を参照)。

Function: major-mode-suspend

この関数はすべてのバッファーローカル変数をkillする点においてfundamental-modeのように機能するが、これは後でリストアできるように効力をもつメジャーモードを記録する。この関数とmajor-mode-restore (以下参照)は、Emacsがそのバッファー用に自動的に選択したモード(Emacsがメジャーモードを選択する方法を参照)ではない何らかの特化したモードにバッファーを置く必要があり、なおかつ後で元のモードに戻れるようにしたい場合に有用。

Function: major-mode-restore &optional avoided-modes

この関数はmajor-mode-suspendが記録したメジャーモードをリストアする。メジャーモードが何も記録されていなければ、この関数はnormal-mode (normal-modeを参照)を呼び出すが、avoided-modes引数が非nilならこの引数内のモードを選択させないように試みる。

Function: clean-mode

メジャーモード変更によってほとんどのローカル変数はクリアーされるが、バッファー内に残された残置物(テキストプロパティやオーバーレイなど)がすべて削除される訳ではない。あるバッファーのメジャーモードを別のモードに変更することは稀であり、これは通常なら問題にならない(fundamental-modeからそれ以外のメジャーモードへの変更は除く)。バッファーの“完全リセット”を行うことができれば、(主としてバッファーでの問題をデバッグ中には)便利なときがあるかもしれず、正にそれがメジャーモードclean-modeの提供する機能である。これはすべてのローカル変数(永続的なローカル変数さえも)をkillするとともに、すべてのオーバーレイおよびテキストプロパティを削除する。

メジャーモードを記述するもっとも簡単な方法はマクロdefine-derived-modeを使用する方法です。これは既存のメジャーモードを変形して新たなモードをセットアップします。派生モードの定義を参照してください。define-derived-modeは多くのコーディング規約を自動的に強要するので、たとえ新たなモードが他のモードから明示的に派生されない場合でも、わたしたちはdefine-derived-modeの使用を推奨します。派生元とするための一般的なモードについては基本的なメジャーモードを参照してください。

標準的なGNU EmacsのLispディレクトリーツリーには、いくつかのメジャーモードがtext-mode.eltexinfo.ellisp-mode.elrmail.elのようなファイルとして含まれています。モードの記述方法を確認するために、これらのライブラリーを学ぶことができます。

User Option: major-mode

この変数のバッファーローカル値はカレントのメジャーモードにたいするシンボルを保持する。この変数のデフォルト値は新たなバッファーにたいするデフォルトのメジャーモードを保持する。標準的なデフォルト値はfundamental-modeである。

デフォルト値がnilなら、C-x b (switch-to-buffer)のようなコマンドを通じてEmacsが新たなバッファーを作成したとき、新たなバッファーは以前カレントだったバッファーのメジャーモードになる。例外として以前のバッファーのメジャーモードのシンボルプロパティmode-classが値specialをもつ場合には、新たなバッファーはFundamentalモードになる(メジャーモードの慣習を参照)。


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

24.2.1 メジャーモードの慣習

メジャーモードにたいするすべてのコードはさまざまなコーディング規約にしたがうべきであり、それらの規約にはローカルキーマップおよび構文テーブルの初期化、関数名や変数名、フックにたいする規約が含まれます。

define-derived-modeマクロを使用すれば、これらの規約を自動的に配慮します。派生モードの定義を参照してください。FundamentalモードはEmacsのデフォルト状態を表すモードなので、これらの規約が該当しないことに注意してください。

以下の規約リストはほんの一部です。一般的にすべてのメジャーモードはEmacs全体が首尾一貫するよう、他のEmacsメジャーモードとの一貫性を目指すべきです。ここでこの問題を洗い出すすべての想定される要点をリストするのは不可能です。自身の開発するメジャーモードが通常の規約を逸脱する領域を示すような場合には、Emacs開発者は互換性を保つようにしてください。

  • 名前が‘-mode’で終わるようにメジャーモードコマンドを定義する。引数なしで呼び出されたときこのコマンドはキーマップ、構文テーブル、既存バッファーのバッファーローカル変数をセットアップして、カレントバッファーを新たなモードに切り替えること。そのバッファーのコンテンツを変更しないこと。
  • そのモードで利用できる特別なコマンドを説明するドキュメント文字列を記述する。メジャーモードでのヘルプ入手を参照のこと。

    そのユーザー自身のキーバインディングに自動的に適合してヘルプが表示されるように、ドキュメント文字列に特別なドキュメントサブストリング‘\[command]’、‘\{keymap}’、‘\<keymap>’を含めるとよいかもしれない。ドキュメント内でのキーバインディングの置き換えを参照のこと。

  • メジャーモードコマンドはkill-all-local-variablesを呼び出すことによって開始すること。これはノーマルフックchange-major-mode-hookを実行してから、前のメジャーモードで効力のあったバッファーローカル変数を解放する。バッファーローカルなバインディングの作成と削除を参照のこと。
  • メジャーモードコマンドは変数major-modeにメジャーモードコマンドのシンボルをセットすること。これはdescribe-modeがプリントするドキュメントを探す手掛かりとなる。
  • メジャーモードコマンドは変数mode-nameにそのモードの“愛称(pretty name)”をセットすること(これは通常は文字列だが他の利用可能な形式についてはモードラインのデータ構造を参照)。このモード名はモードラインに表示される。
  • 連続してメジャーモードコマンドを直接呼び出しても失敗せずに、1回だけ呼び出されたときと同じことを行うこと。言い換えるとメジャーモードコマンドはべき等であること。
  • すべてのグローバル名は同じネームスペースにあるので、モードの一部であるようなすべてのグローバルな変数、定数、関数はメジャーモード名(メジャーモード名が長いようなら短縮名)で始まる名前をもつこと。Emacs Lispコーディング規約を参照されたい。
  • プログラム言語のようなある種の構造型テキストを編集するためのメジャーモードでは、その構造に応じたテキストのインデントがおそらく有用であろう。したがってそのようなモードはindent-line-functionに適切な関数をセットするとともに、インデント用のその他の変数をカスタマイズするべきだろう。コードの自動インデントを参照のこと。
  • メジャーモードは、通常はそのモードにあるすべてのバッファーのローカルキーマップとして使用されるモード自身のキーマップをもつこと。メジャーモードコマンドはそのローカルマップをインストールするために、use-local-mapを呼び出すこと。詳細はアクティブなキーマップを参照されたい。

    このキーマップはmodename-mode-mapという名前のグローバル変数に永続的に格納されること。そのモードを定義するライブラリーは、通常はこの変数をセットする。

    モード用のキーマップ変数をセットアップするコードの記述する方法に関するアドバイスは堅牢な変数定義のためのヒントを参照されたい。

  • メジャーモードのキーマップ内でバインドされるキーシーケンスは、通常はC-cで始まってその後にコントロール文字、数字、{}<>:;が続くこと。その他の記号文字(punctuation characters)はマイナーモード、通常のアルファベット文字はユーザー用に予約済みである。

    メジャーモードはM-nM-pM-sなどのキーもリバインドできる。M-nM-pにたいするバインディングは、通常は 前方か後方への移動を意味するような類のものであるべきだが、これが必ずしもカーソル移動を意味する必要はない。

    そのモードにより適した方法でテキストに同じ処理を行うコマンドを提供する場合には、メジャーモードが標準的なキーシーケンスをリバインドするのは正当性がある。たとえばプログラム言語を編集するためのメジャーモードは、その言語にとって関数の先頭に移動するために、より良く機能する方法でC-M-aを再定義するかもしれない。メジャーモードにニーズに応じてC-M-aを構成するための推奨方法は、そのモード固有の関数を呼び出すためにbeginning-of-defun-functionをセットすること(釣り合いのとれたカッコを越えた移動を参照)。

    ある標準的なキーシーケンスの標準的な意味がそのモードではほとんど役に立たないような場合にも、メジャーモードが標準的なキーシーケンスをリバインドする正当性がある。たとえばM-rの標準的な意味はミニバッファーではほとんど使用されないので、このキーシーケンスをリバインドする。テキストの自己挿入を許さないDiredやRmailのようなメジャーモードがアルファベット文字や、その他のプリント文字を特別なコマンドに再定義することには正当性がある。

  • テキストを編集するメジャーモードは改行の挿入以外の何かにRETを定義すべきではない。しかしユーザーが直接テキストを編集しない、DiredやInfoのような特別なモードにたいしては完全に異なることを行うようにRETを再定義しても構わない。
  • メジャーモードは、たとえばAuto-Fillモードを有効にする等の、主にユーザーの好みに関するオプションを変更しないこと。それらのオプションはユーザーに選択に任せること。ただしもしユーザーがAuto-Fillモードを使用すると決定したら、それが便利に機能するように他の変数をカスタマイズすること。
  • モードは自身の構文テーブルをもつことができ、他の関連するモードと構文テーブルを共有するかもすることもできる。モードが自身の構文テーブルをもつ場合には、modename-mode-syntax-tableという名前の変数にそれを格納すること。構文テーブルを参照されたい。
  • コメントにたいする構文をもつ言語を扱うモードは、コメント構文を定義する変数をセットすること。Options Controlling Comments in The GNU Emacs Manualを参照されたい。
  • モードは自身のabbrevテーブルをもつことができ、他の関連するモードと構文テーブルを共有することもできる。モードが自身のabbrevテーブルをもつ場合には、modename-mode-abbrev-tableという名前の変数にそれを格納すること。メジャーモードコマンドが自身で何らかのabbrevを定義する場合には、define-abbrevsystem-flag引数にtを渡すこと。abbrevの定義を参照されたい。
  • モードは変数font-lock-defaultsにバッファーローカルな値をセットすることによって、Font Lockモードにたいしてハイライトする方法を指定すること(Font Lockモードを参照)。
  • モードが定義するすべてのフェイスは、もし可能なら既存のEmacsフェイスを継承すること。基本的なフェイスFont Lockのためのフェイスを参照されたい。
  • メニューバーへのモード固有メニュー追加を検討すること。ユーザーが迅速かつ効率的に主機能を発見できるよう、もっとも重要なモード固有のセッティングとコマンドを含めることが望ましい。
  • そのモードにたいして、ユーザーがcontext-menu-mode (Menu Mouse Clicks in The Emacs Manualを参照)をアクティブにした際に使用されるモード固有のコンテキストメニューの追加を検討すること。これを達成するにはバッファー内でmouse-3がクリックされた位置に応じて1つ以上のメニューを構築するモード固有関数の定義して、context-menu-functionsのバッファーローカル値にその関数を追加すればよい。
  • モードは変数imenu-generic-expressionimenu-prev-index-position-functionimenu-extract-index-name-functionの2つの変数、または変数imenu-create-index-functionにバッファーローカルな値をセットすることによってImenuがバッファー内の定義やセクションを探す方法を指定すること(Imenuを参照)。
  • モードはスペシャルフックeldoc-documentation-functionsに1つ以上のバッファーローカルエントリーを追加することにより、ポイント位置にあるものにたいして異なるタイプのドキュメントを取得する方法をElDocモードに指示できる。
  • モードはスペシャルフックcompletion-at-point-functionsに1つ以上のバッファーローカルエントリーを追加することにより、さまざまなキーワードの補完方法を指定できる。通常バッファーでの補完を参照のこと。
  • Emacsのカスタマイズ変数にたいしてバッファーローカルなバインディングを作成するには、make-variable-buffer-localではなくメジャーモードコマンド内でmake-local-variableを使用すること。関数make-variable-buffer-localはそれ以降にカスタマイズ変数をセットするすべてのバッファーにたいしてその変数をローカルにして、そのモードを使用しないバッファーにたいしても影響があるだろう。そのようなグローバルな効果はモードにとって好ましくない。バッファーローカル変数を参照のこと。

    稀な例外としてLispパッケージ内でmake-variable-buffer-localを使用する唯一の正当な方法は、そのパッケージ内でのみ使用される変数にたいして使用をする場合である。他のパッケージにより使用される変数にたいしてこの関数を使用すると競合が発生するだろう。

  • すべてのメジャーモードはmodename-mode-hookという名前のノーマルなモードフック(mode hook)をもつこと。メジャーモードコマンドが一番最後にrun-mode-hooksを呼び出すこと。これはノーマルフックchange-major-mode-after-body-hook、モードフック、(バッファーがファイルをvisitしていれば)関数hack-local-variables、その後にノーマルフックafter-change-major-mode-hookを実行する。モードフックを参照のこと。
  • メジャーモードコマンドは親モード(parent mode)と呼ばれる他のいくつかのメジャーモードを呼び出すことにより開始されるかもしれず、それらのセッティングのいくつかを変更するかもしれない。これを行うモードは派生モード(derived mode)と呼ばれる。派生モードを定義する推奨方法はdefine-derived-modeマクロの使用だが必須ではない。そのようなモードはdelay-mode-hooksフォーム内で親のモードコマンドを呼び出すこと(define-derived-modeは自動的にこれを行う)。派生モードの定義モードフックを参照されたい。
  • ユーザーがそのモードのバッファーから他のモードのバッファーに切り替える際に特別な何かを行う必要がある場合、モードはchange-major-mode-hookにたいしてバッファーローカル値をセットアップできる(バッファーローカルなバインディングの作成と削除を参照)。
  • そのモードが、(ユーザーがキーボードでタイプしたテキストや外部ファイルのテキストではなく)モード自身が生成する特別に用意されたテキストにたいしてのみ適している場合、メジャーモードコマンドのシンボルは以下のようにmode-classという名前のプロパティに値specialをputすること:
    (put 'funny-mode 'mode-class 'special)
    

    これはEmacsにたいしてカレントバッファーがFunnyモードのときに新たなバッファーを作成したとき、たとえmajor-modeのデフォルト値がnilであってもそのバッファーをFunnyモードにしないよう指示する。デフォルトではmajor-modeにたいする値nilは新たなバッファー作成時にカレントバッファーのメジャーモードを使用することを意味するが(Emacsがメジャーモードを選択する方法を参照)、specialなモードにたいしてはかわりにFundamentalモードが使用される。Dired、Rmail、Buffer Listのようなモードはこの機能を使用する。

    関数view-bufferはmode-classがspecialであるようなバッファーではViewモードを有効にしない。そのようなモードは通常は自身でViewに相当するバインディングを提供するからである。

    define-derived-modeマクロは親モードがspecialなら、自動的に派生モードをspecialにマークする。親モードでspecialモードが有用ならそれを継承したモードでも有用だろう。基本的なメジャーモードを参照のこと。

  • 新たなモードを識別可能な特定のファイルにたいするデフォルトとしたければ、そのようなファイル名にたいしてそのモードを選択するためにauto-mode-alistに要素を追加する。autoload用にモードコマンドを定義する場合には、autoloadを呼び出すのと同じファイル内にその要素を追加すること。モードコマンドにたいしてautoload cookieを使用する場合はに、その要素を追加するフォームにたいしてもautoload cookieを使用できる(autoload cookieを参照)。モードコマンドをautoloadしない場合には、モード定義を含むファイル内で要素を追加すれば十分である。
  • 悪影響を与えることなく1回以上評価されるように、モード定義はファイル内のトップレベルのフォームとして記述すべきである。たとえばすでに値をもつ変数が再初期化されないように、モードに関連した変数をセットするときはdefvardefcustomを使用する(グローバル変数の定義を参照)。

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

24.2.2 Emacsがメジャーモードを選択する方法

Emacsはファイルをvisitするとき、ファイル名やファイル自体の内容などの情報を元にそのバッファーにたいするメジャーモードを選択します。またファイルのテキスト内で指定されたローカル変数も処理します。

Command: normal-mode &optional find-file

この関数はカレントバッファーにたいして適切なメジャーモード、およびバッファーローカル変数のバインディングを設定する。これはset-auto-mode (以下参照)を呼び出す。Emacs 26.1ではもはやhack-local-variablesを呼び出さずに、メジャーモードの初期化時のrun-mode-hooksでこれが行われる(モードフックを参照)。

normal-modefind-file引数が非nilなら、normal-modefind-file関数が自身を呼び出したとみなす。この場合、normal-modeはそのファイル内の‘-*-’行、またはファイルの最後にあるローカル変数を処理できる。これを行うかどうかは変数enable-local-variablesが制御する。ファイルのローカル変数セクションの構文はLocal Variables in Files in The GNU Emacs Manualを参照のこと。

インタラクティブにnormal-modeを実行すると、引数find-fileは通常はnilである。この場合、normal-modeは無条件に任意のファイルローカル変数を処理する。

この関数はメジャーモードを選択してセットするためにset-auto-modeを呼び出す。この関数がモードを特定しなければバッファーのmajor-mode (以下参照)のデフォルト値により決定されるメジャーモードに留まる。

normal-modeはメジャーモードコマンド呼び出しの周囲にcondition-caseを使用するのでエラーはcatchされて、‘File mode specification error’とともに元のエラーメッセージがその後に報告される。

Function: set-auto-mode &optional keep-mode-if-same

この関数はカレントバッファーにたいして適切なメジャーモードを選択してセットする。この選択は関数自身の(優先順位による)決定にもとづく。優先順位は‘-*-行、ファイル終端近傍の任意の‘mode:’ローカル変数、‘#!行(interpreter-mode-alistを使用)、バッファーの先頭のテキスト(magic-mode-alistを使用)、最後がvisitされるファイル名(auto-mode-alistを使用)の順。How Major Modes are Chosen in The GNU Emacs Manualを参照のこと。enable-local-variablesnilならset-auto-modeは‘-*-行とファイル終端近傍にたいしてmodeタグのチェックを何も行わない。

モード特定のためにファイル内容をスキャンするのがふさわしくないファイルタイプがいくつかある。たとえばtarアーカイブファイルの終端付近に特定のファイルにたいしてモードを指定するローカル変数セクションをもつアーカイブメンバーファイルがたまたま含まれているかもしれない。こがそのファイルを含んだtarファイルに適用されるべきではないだろう。同様にtiffイメージファイルが‘-*-パターンにマッチするように見える行を最初の行に偶然含むかもしれない。これらの理由により、これらのファイル拡張子はいずれもinhibit-local-variables-regexpsリストのメンバーになっている。Emacsが、(モード指定に限らず)ファイルから任意の種類のローカル変数を検索することを防ぐには、このリストにパターンを追加する。

keep-mode-if-sameが非nilなら、すでにそのバッファーが適切なメジャーモードをもつときにこの関数はモードコマンドを呼び出さない。たとえばset-visited-file-nameはユーザーがセットしたかもしれないバッファーローカル変数をkillすることを防ぐために、これをtにセットする。

Function: set-buffer-major-mode buffer

この関数はbufferのメジャーモードをmajor-modeのデフォルト値にセットする。major-modenilなら、(それが適切なら)カレントバッファーのメジャーモードを使用する。例外としてbufferの名前が*scratch*なら、モードをinitial-major-modeにセットする。

バッファーを作成する低レベルのプリミティブはこの関数を使用しないが、switch-to-bufferfind-file-noselectのような中位レベルのコマンドは、バッファー作成時は常にこの関数を使用する。

User Option: initial-major-mode

この変数の値は*scratch*バッファーの初期のメジャーモードを決定する。値はメジャーモードコマンドであるようなシンボルであること。デフォルト値はlisp-interaction-mode

Variable: interpreter-mode-alist

この変数は‘#!’行内のコマンドインタープリターを指定するスクリプトにたいして使用するメジャーモードを指定する。変数の値は(regexp . mode)という形式の要素をもつalistである。これはそのファイルが\\`regexp\\'にマッチするインタープリターを指定する場合にはmodeを使用することを意味する。たとえばデフォルト要素の1つは("python[0-9.]*" . python-mode)である。

Variable: magic-mode-alist

この変数の値は(regexp function)という形式の要素をもつalistである。ここでregexpは正規表現、functionは関数、またはnilである。ファイルをvisitした後にバッファーの先頭のテキストがregexpにマッチした場合、functionが非nilならset-auto-modefunctionを呼び出す。functionnilならauto-mode-alistがモードを決定する。

Variable: magic-fallback-mode-alist

これはmagic-mode-alistと同様に機能するが、そのファイルにたいしてauto-mode-alistがモードを指定しない場合だけ処理される点が異なる。

Variable: auto-mode-alist

この変数はファイル名パターン(正規表現)と対応するメジャーモードコマンドの連想リストを含む。ファイル名パターンは通常は‘.el’や‘.c’のようなサフィックスをテストするが必須ではない。このalistの通常の要素は(regexp . mode-function)のようになる。

たとえば、

(("\\`/tmp/fol/" . text-mode)
 ("\\.texinfo\\'" . texinfo-mode)
 ("\\.texi\\'" . texinfo-mode)
 ("\\.el\\'" . emacs-lisp-mode)
 ("\\.c\\'" . c-mode)
 ("\\.h\\'" . c-mode)
 …)

バージョン番号とバックアップ用サフィックスをもつファイルをvisitしたとき、それらのサフィックスはfile-name-sans-versions (ファイル名の構成要素を参照)を使用して展開されたファイル名(ファイル名を展開する関数を参照)から取り除かれてregexpとマッチされて、set-auto-modeはそれに対応するmode-functionを呼び出す。この機能によりほとんどのファイルにたいしてEmacsが適切なメジャーモードを選択することが可能になる。

auto-mode-alistの要素が(regexp function t)という形式なら、functionを呼び出した後にEmacsは前回マッチしなかったファイル名部分にたいしてマッチするために再度auto-mode-alistを検索する。この機能は圧縮されたパッケージにたいして有用である。("\\.gz\\'" function t)という形式のエントリーは、ファイルを解凍してから‘.gz’抜きのファイル名の解凍されたファイルを適切なモードに置く。

regexpがファイル名にマッチする要素がauto-mode-alistに複数ある場合には、Emacsは最初のマッチを使用する。

以下はauto-mode-alistの先頭に複数のパターンペアーを追加する方法の例である(あなたはinitファイル内でこの種の式を使ったことがあるかもしれない)。

(setq auto-mode-alist
  (append
   ;; ドットで始まる(ディレクトリー名付きの)ファイル名
   '(("/\\.[^/]*\\'" . fundamental-mode)
     ;; ドットのないファイル名
     ("/[^\\./]*\\'" . fundamental-mode)
     ;; .C’で終わるファイル名
     ("\\.C\\'" . c++-mode))
   auto-mode-alist))

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

24.2.3 メジャーモードでのヘルプ入手

describe-mode関数はメジャーモードに関する情報を提供します。これは通常はC-h mにバインドされています。この関数は変数major-mode (メジャーモードを参照)の値を使用します。すべてのメジャーモードがこの変数をセットする必要があるのはこれが理由です。

Command: describe-mode &optional buffer

このコマンドはカレントバッファーのメジャーモードとマイナーモードのドキュメントを表示する。この関数はメジャーモードおよびマイナーモードのコマンドのドキュメント文字列を取得するためにdocumentation関数を使用する(ドキュメント文字列へのアクセスを参照)。

buffer引数に非nilを指定してLispから呼び出されると、この関数はカレントバッファーではなくそのバッファーのメジャーモードとマイナーモードのドキュメントを表示する。


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

24.2.4 派生モードの定義

新しいメジャーモードを定義する推奨方法は、define-derived-modeを使用して既存のメジャーモードから派生させる方法です。それほど近いモードが存在しない場合はtext-modespecial-mode、またはprog-modeから継承するべきです。基本的なメジャーモードを参照してください。これらがいずれも適切でなければ、fundamental-modeから継承することができます(メジャーモードを参照)。

Macro: define-derived-mode variant parent name docstring keyword-args… body…

このマクロはvariantをメジャーモードコマンドとして定義して、nameをモード名の文字列形式とする。variantparentはクォートされていないシンボルであること。

新たなコマンドvariantは関数parentを呼び出すよう定義されて、その後その親モードの特定の性質をオーバーライドする。

  • 新たなモードはvariant-mapという名前の、自身のsparseキーマップ(疎キーマップ)をもつ。define-derived-modevariant-mapがすでにセットされていて、かつすでに親をもつ場合を除いて親モードのキーマップを新たなマップの親キーマップにする。
  • 新たなモードは自身の構文テーブル(syntax table)をもち、それは変数variant-syntax-tableに保持される。ただし:syntax-tableキーワード(以下参照)を使用してこれをオーバーライドした場合は異なる。define-derived-modevariant-syntax-tableがすでにセットされていて、かつ標準的な構文テーブルよ異なる親をもつ場合を除いて、親モードの構文テーブルをvariant-syntax-tableの親とする。
  • 新たなモードは自身のabbrevテーブル(略語テーブル)をもち、それは変数variant-abbrev-tableに保持される。ただし:abbrev-tableキーワード(以下参照)を使用してこれをオーバーライドした場合は異なる。
  • 新たなモードは自身のモードフックvariant-hookをもつ。これはフックを実行した後に:after-hookがあればそれを実行して、それとは別に最後にrun-mode-hooksによって自身の祖先のモードのフックを実行する。

これらに加えてbodyparentのその他の性質をオーバーライドする方法を指定できます。コマンドvariantは通常のオーバーライドをセットアップした後、そのモードのフックを実行する直前にbody内のフォームを評価します。

parentが非nilmode-classシンボルプロパティをもつ場合、define-derived-modevariantmode-classプロパティに同じ値をセットします。これはたとえばparentがspecialモードならvariantもspecialモードになることを保証します(メジャーモードの慣習を参照)。

parentにたいしてnilを指定することもできます。これにより新たなモードは親をもたなくなります。その後にdefine-derived-modeは上述のように振る舞いますが、当然parentにつながるすべてのアクションは省略されます。

引数docstringは新たなモードにたいするドキュメント文字列を指定します。define-derived-modeはこのドキュメント文字列の最後にそのモードフックに関する一般的な情報と、その後にそのモードのキーマップを追加します。docstringを省略するとdefine-derived-modeがドキュメント文字列を生成します。

keyword-argsはキーワードと値のペアー。:after-hookのものを除いて値は評価される。現在のところ以下のキーワードがサポートされる:

:syntax-table

新たなモードにたいする構文テーブルを明示的に指定するためにこれを使用できる。nil値を指定すると新たなモードはparentと同じ構文テーブル、parentnilなら標準的な構文テーブルを使用する(これはnil値の非キーワード引数は引数を指定しないのと同じという通常の慣習にはしたがわないことに注意)。

:abbrev-table

新たなモードにたいするabbrevテーブルを明示的に指定するためにこれを使用できる。nil値を指定すると新たなモードはparentと同じabbrevテーブル、parentnilならfundamental-mode-abbrev-tableを使用する(繰り返すがnil値はこのキーワードを指定しないことではない)。

:interactive

モードはデフォルトではインタラクティブコマンド。nil値を指定すると、ここで指定したモードはインタラクティブにならない。これはユーザーが手動でアクティブにされることはないが、特別にフォーマットされたバッファーでのみ使用されることを意図したモードで有用。

:group

これが指定する場合、値はそのモードにたいするカスタマイズグループ(customization group)であること(すべてのメジャーモードがカスタマイズグループをもつ訳ではない)。customize-modeコマンドはこれを使用する。define-derived-modeは指定されたカスタマイズグループを自動的に定義しない

:after-hook

このオプションのkeyはモードフック実行後にモード関数の最後の活動として評価される単一のLispフォームを指定する。クォートしないこと。モードにが終了した後にフォーが評価されるので、モード関数のローカル状態のすべての要素にアクセスするべきではない。:after-hookフォームはモードフックで変更されているかもしれないユーザーのセッティングに依存するモードの様相をセットアップするために有用。

以下は架空の例:

(defvar-keymap hypertext-mode-map
  "<down-mouse-3>" #'do-hyper-link)

(define-derived-mode hypertext-mode
  text-mode "Hypertext"
  "ハイパーテキスト用のメジャーモード"
  (setq-local case-fold-search nil))

define-derived-modeが自動的に行うので、この定義内にinteractive指定を記述してはならない。

Function: derived-mode-p &rest modes

この関数はカレントメジャーモードがシンボルmodesで与えられたメジャーモードのいずれかから派生されていたら非nilをリターンする。


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

24.2.5 基本的なメジャーモード

Fundamentalモードは別として他のメジャーモードの一般的な派生元となるメジャーモードが3つあります。それはTextモード、Progモード、およびSpecialモードです。Textモードはその本来もつ機能から有用なモードです(たとえば.txtファイルの編集など)。一方、ProgモードとSpecialモードは主にそのようなモード以外のモードの派生元とするために存在します。

新たなモードは直接と間接を問わず、可能な限りそれら3つのモードから派生させるべきです。その理由の1つは関連のあるモードファミリー全体(たとえばすべてのプログラミング言語のモード)にたいして、ユーザーが単一のモードフックをカスタマイズできるからからです。

Command: text-mode

Textモードは人間の言語を編集するためのメジャーモードである。このモードは文字‘"’と‘\’を区切り文字構文(punctuation syntax: 構文クラスのテーブルを参照)としてもち、M-TABispell-complete-wordにバインドする(Spelling in The GNU Emacs Manualを参照)。

Textモードから派生されたメジャーモードの例としてHTMLモードがある。SGML and HTML Modes in The GNU Emacs Manualを参照のこと。

Command: prog-mode

Progモードはプログラミング言語のソースコードを含むバッファーにたいする基本的なメジャーモードである。Emacsビルトインのプログラミング言語用メジャーモードはこのモードから派生されている。

Progモードはparse-sexp-ignore-commentst (パースにもとづくモーションコマンドを参照)、bidi-paragraph-directionleft-to-right (双方向テキストの表示を参照)にバインドする。

Command: special-mode

Specialモードはファイルから直接ではなく、Emacsにより特別(specially)に生成されたテキストを含むバッファーにたいする基本的なメジャーモードである。Specialモードから派生されたメジャーモードはmode-classプロパティにspecialが与えられる(メジャーモードの慣習を参照)。

Specialモードはバッファーを読み取り専用にセットする。このモードのキーマップはいくつかの一般的なバインディングを定義して、それにはquit-windowにたいするqrevert-buffer (リバートを参照)にたいするgが含まれる。

Specialから派生されたメジャーモードの例としてはBuffer Menuモードがあり、これは*Buffer List*バッファーにより使用される。Listing Existing Buffers in The GNU Emacs Manualを参照のこと。

これらに加えて表形式データのバッファーにたいするモードをTabulated Listモードから継承できます。このモードはSpecialモードから順に派生されているモードです。Tabulated Listモードを参照してください。


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

24.2.6 モードフック

すべてのメジャーモードコマンドはモード独自のノーマルフックchange-major-mode-after-body-hook、そのモードのモードフック、ノーマルフックafter-change-major-mode-hookを実行することによって終了すべきです。これはrun-mode-hooksを呼び出すことにより行われます。もしそのモードが派生モードなら自身のbody内で他のメジャーモード(親モード)を呼び出す場合には、親モードが自身でこれらのフックを実行しないようにdelay-mode-hooksの中でこれを行うべきです。かわりに派生モードは親のモードフックも実行するrun-mode-hooksを呼び出します。メジャーモードの慣習を参照してください。

Emacs 22より前のバージョンのEmacsにはdelay-mode-hooksがありません。またEmacs 24より前のバージョンにはchange-major-mode-after-body-hookがありません。ユーザー実装のメジャーモードがrun-mode-hooksを使用せず、これらの新しい機能を使用するようにアップデートされていないときは、これらのメジャーモードは以下の慣習に完全にしたがわないでしょう。それらのモードは親のモードフックをあまりに早く実行したり、after-change-major-mode-hookの実行に失敗するかもしれません。そのようなメジャーモードに遭遇したら以下の慣習にしたがって修正をお願いします。

define-derived-modeを使用してメジャーモードを定義したときは、自動的にこれらの慣習にしたがうことが保証されます。define-derived-modeを使用せずにメジャーモードを“手動”で定義したら、これらの慣習を自動的に処理するように以下の関数を使用してください。

Function: run-mode-hooks &rest hookvars

メジャーモードはこの関数を使用してモードフックを実行すること。これはrun-hooks (フックを参照)と似ているがchange-major-mode-after-body-hook、(バッファーがファイルをvisitしていれば)hack-local-variables (ファイルローカル変数を参照)、after-change-major-mode-hookも実行する。これは最後に親モード(派生モードの定義を参照)で宣言されている:after-hookフォームをすべて評価する。

この関数がdelay-mode-hooksフォーム実行中に呼び出されたときはフックやhack-local-variablesの実行、およびフォームの評価を即座には行わない。かわりに次のrun-mode-hooks呼び出しでそれらを実行するようにアレンジする。

Macro: delay-mode-hooks body…

あるメジャーモードコマンドが他のメジャーモードコマンドを呼び出すときはdelay-mode-hooksの内部で行うこと。

このマクロはbodyを実行するが、body実行中はすべてのrun-mode-hooks呼び出しにたいしてそれらのフックの実行を遅延するよう指示する。それらのフックは実際にはdelay-mode-hooks構造の最後の後、次のrun-mode-hooks呼び出しの間に実行されるだろう。

Variable: change-major-mode-after-body-hook

これはrun-mode-hooksにより実行されるノーマルフックである。これはそのモードのフックの前に実行される。

Variable: after-change-major-mode-hook

これはrun-mode-hooksにより実行されるノーマルフックである。これはすべての適切に記述されたメジャーモードコマンドの一番最後に実行される。


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

24.2.7 Tabulated Listモード

Tabulated Listモードとは、表形式データ(エントリーから構成されるデータで各エントリーはそれぞれテキストの1行を占め、エントリーの内容は列に分割されるようなデータ)を表示するためのメジャーモードです。Tabulated Listモードは行列の見栄えよくプリントする機能、および各列の値に応じて行をソートする機能を提供します。これはSpecialモードから派生されたモードです(基本的なメジャーモードを参照)。

Tabulated Listモードは単一のフォントとテキストサイズによりモノスペースフォントを使用してテキストを表示するように調整されています。可変ピッチフォントやイメージを使用したテーブルが表示したければ、かわりにmake-vtableを使うことができます。vtableでは1つのバッファーに複数のテーブルをもったり、テーブルと追加のテキストの両方を含んだバッファーをもつことができます。詳細については(vtable)Introductionを参照してください。

Tabulated Listモードは、より特化したメジャーモードの親モードとして使用されることを意図しています。例としてはProcess Menuモード(プロセスの情報を参照)、Package Menuモード(Package Menu in The GNU Emacs Manualを参照)が含まれます。

このような派生されたモードはtabulated-list-modeを2つ目の引数に指定して、通常の方法でdefine-derived-modeを使用するべきです(派生モードの定義を参照)。define-derived-modeフォームのbodyは以下にドキュメントされている変数に値を割り当てることにより、表形式データのフォーマットを指定するべきです。その後にオプションで列名のヘッダーを挿入する関数tabulated-list-init-headerを呼び出すことができます。

派生されたモードはリスティングコマンド(listing command)も定義するべきです。これはモードコマンドではなく、(M-x list-processesのように)ユーザーが呼び出すコマンドです。リスティングコマンドはバッファーを作成または切り替えて、派生モードをオンにして表形式データを指定し、最後にそのバッファーを事前設定(populate)するためにtabulated-list-printを呼び出すべきです。

User Option: tabulated-list-gui-sort-indicator-asc

この変数はGUIフレームにおいて列が昇順でソートされていることを示すために使用する文字を指定する。

Tabulated Listバッファーでソート方向を変更するたびに、このインジケーターの昇順(“asc”)と降順(“desc”)が切り替わる。

User Option: tabulated-list-gui-sort-indicator-desc

tabulated-list-gui-sort-indicator-ascと同様だが列が降順でソートされている際に使用される。

User Option: tabulated-list-tty-sort-indicator-asc

tabulated-list-gui-sort-indicator-ascと同様だがテキストモードのフレームに使用される。

User Option: tabulated-list-tty-sort-indicator-desc

tabulated-list-tty-sort-indicator-ascと同様だが列が降順でソートされている際に使用される。

Variable: tabulated-list-format

このバッファーローカル変数は表形式データのフォーマットを指定する。値はベクターであり、ベクターの各要素はデータ列を表すリスト(name width sort)である。ここで

  • nameは列の名前(文字列)。
  • widthは列にたいして予約される文字数幅(整数)。最終列は各行の終端までなので意味がない。
  • sortは列によりエントリーをソートする方法を指定する。nilならその列はソートに使用できない。tなら列の文字列値を比較することによりソートされる。それ以外ならtabulated-list-entriesの要素と同じ形式の2つの引数をとる、sortにたいする述語関数(predicate function)であること。
Variable: tabulated-list-entries

このバッファーローカル変数はTabulated Listバッファー内に表示されるエントリーを指定する。値はリストか関数のいずれかであること。

値がリストなら各リスト要素は1つのエントリーに対応し、(id contents)という形式であること。ここで

  • idnil、またはエントリーを識別するLispオブジェクト。Lispオブジェクトならエントリーを再ソートした際、カーソルは同じエントリー上に留まる。比較はequalで行われる。
  • contentstabulated-list-formatと要素数が同じベクター。ベクター要素は文字列(バッファーにそのまま挿入される)、あるいはイメージディスクリプター(イメージの挿入に使用される; イメージのディスクリプタを参照)、あるいは(label . properties)という形式のリスト。これはlabelpropertiesを引数としてinsert-text-buttonを呼び出すことによりテキストボタンを挿入することを意味する(ボタンの作成を参照)。

    これらの文字列には改行を含めないこと。

それ以外なら、それは値は引数なしで呼び出されて上記形式のリストをリターンする関数であること。

Variable: tabulated-list-revert-hook

このノーマルフックはTabulated Listバッファーのリバートに先立ち実行される。派生モードはtabulated-list-entriesを再計算するためにこのフックに関数を追加できる。

Variable: tabulated-list-printer

この変数の値はポイント位置にエントリー(エントリーを終端する改行を含む)を挿入するために呼び出される関数である。この関数はtabulated-list-entriesと同じ意味をもつ2つの引数idcontentsを受け取る。デフォルト値はエントリーをそのまま挿入する関数である。より複雑な方法でTabulated Listモードを使用するモードは別の関数を指定できる。

Variable: tabulated-list-sort-key

この変数の値はTabulated Listバッファーにたいするカレントのソートキーを指定する。nilならソートは行われない。それ以外なら(name . flip)という形式の値をもつ。ここでnametabulated-list-format内の列目の1つとマッチする文字列、flipが非nilなら逆順でのソートを意味する。

Function: tabulated-list-init-header

この関数はTabulated Listバッファーにたいするheader-line-formatを計算してセットし、列ヘッダー上でのクリックでソートを可能にするキーマップをヘッダー行に割り当てる。

Tabulated Listから派生したモードは、上記の変数(特にtabulated-list-formatをセットした後のみ)をセットした後にこれを呼び出すこと。

Function: tabulated-list-print &optional remember-pos update

この関数はカレントバッファーにエントリーを挿入する。これをリスティングコマンドとして呼び出すこと。この関数はバッファーを消去してtabulated-list-entriesで指定されるエントリーをtabulated-list-sort-keyにしたがってソートした後、各エントリーを挿入するためにtabulated-list-printerで指定される関数を呼び出す。

オプション引数remember-posが非nilなら、この関数はカレント行でid要素を探して、もしあればすべてのエントリーを(再)挿入して、その後にそのエントリーの移動を試みる。

オプション引数updateが非nilなら、この関数は最後のプリント以降に変更されたエントリーの削除か追加だけを行う。この関数が最後に呼び出されて以降、ほとんどのエントリーが変更されていなければ、この関数は数倍高速になる。結果の違いはtabulated-list-put-tagを通じて配置されたタグが変更されていないエントリーから削除されないことだけである(通常はすべてのタグが削除される)。

Function: tabulated-list-delete-entry

この関数はポイント位置のエントリーを削除する。

リスト(id cols)をリターンする。ここでidは削除したエントリーのID、colsは列修飾子(column descriptors)のベクター。カレント行の先頭にポイントを移動する。ポイント位置にエントリーがなければnilをリターンする。

この関数はバッファーのコンテンツだけを変更することに注意。tabulated-list-entriesは変更しない。

Function: tabulated-list-get-id &optional pos

このdefsubsttabulated-list-entriesがリストならIDオブジェクト、関数ならtabulated-list-entriesがリターンするリストからIDオブジェクトをリターンする。posが省略かnilの場合のデフォルトはポイント位置。

Function: tabulated-list-get-entry &optional pos

このdefsubsttabulated-list-entriesがリストならエントリーオブジェクト、関数ならtabulated-list-entriesがリターンするリストからエントリーオブジェクトをリターンする。これはposにあるIDにたいするベクターになるだろう。posにエントリーがなければ、この関数はnilをリターンする。

Function: tabulated-list-header-overlay-p &optional POS

このdefsubstposに偽ヘッダーがあれば非nilをリターンする。偽ヘッダー(fake header)はバッファー先頭に列名を配置するためにtabulated-list-use-header-linenilにセットされている場合に使用される。posが省略かnilの場合のデフォルトはpoint-min

Function: tabulated-list-put-tag tag &optional advance

この関数はレント行のパディングエリアにtagを配置する。パディングエリアはその行の先頭にある空スペースであり、幅はtabulated-list-paddingにより制御される。tagは長さがtabulated-list-padding以下の文字列であること。advanceが非nilなら、この関数は1行分ポイントを前方に移動する。

Function: tabulated-list-clear-all-tags

この関数はカレントバッファーのパディングエリアからすべてのタグをクリアーする。

Function: tabulated-list-set-col col desc &optional change-entry-data

この関数はcoldescにセットしてポイント位置にあるTabulated Listのエントリーを変更する。colは変更する列番号か列名、descは新たな列記述子であり、tabulated-list-print-colを通じて挿入される。

change-entry-dataが非nilなら、この関数は列記述子のベクターをdescにセットすることにより、背後のデータ(通常はリストtabulated-list-entries内の列記述子)を変更する。


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

24.2.8 ジェネリックモード

genericモード(汎用モード)とは、コメント構文にたいする基本的なサポートとFont Lockモードをもつシンプルなメジャーモードです。genericモードを定義するにはマクロdefine-generic-modeを使用します。define-generic-modeの使い方の例は、ファイルgeneric-x.elを参照してください。

Macro: define-generic-mode mode comment-list keyword-list font-lock-list auto-mode-list function-list &optional docstring

このマクロはmode (クォートされていないシンボル)という名前のgenericモードコマンドを定義する。オプション引数docstringは、そのモードコマンドにたいするドキュメント文字列。これを与えなければdefine-generic-modeがデフォルトのドキュメント文字列を生成する。

引数comment-listは要素が文字、2文字以下の文字列、またはコンスセルである。文字か文字列ならそのモードの構文テーブル内でコメント開始識別子としてセットアップされる。エントリーがコンスセルならCARはコメント開始識別子、CDRはコメント終了識別子としてセットアップされる(行末によりコメントを終端させたければ後者にnilを使用する)。構文テーブルのメカニズムには実際にコメントの開始および終了識別子に関する制限があることに注意。 構文テーブルを参照のこと。

引数keyword-listfont-lock-keyword-faceでハイライトするキーワードのリストである。キーワードは文字列であること。一方、font-lock-listはハイライトするための追加の式リストである。このリストの各要素はfont-lock-keywordsの要素と同じ形式をもつこと。検索ベースのフォント化を参照されたい。

引数auto-mode-listは変数auto-mode-alistに追加する正規表現のリストである。これらのは、マクロ呼び出しの展開時ではなく、define-generic-modeの実行時に追加される。

最後にfunction-listは追加セットアップのためにモードコマンドに呼び出される関数のリストである。これらの関数はモードフック変数mode-hookの実行の直前に呼び出される。


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

24.2.9 メジャーモードの例

おそらくTextモードは、Fundamentalを除いてもっともシンプルなモードです。上述した慣習の多くを説明するために以下にtext-mode.elの抜粋を示します:

;; Create the syntax table for this mode.
(defvar text-mode-syntax-table
  (let ((st (make-syntax-table)))
    (modify-syntax-entry ?\" ".   " st)
    (modify-syntax-entry ?\\ ".   " st)
    ;; Add 'p' so M-c on 'hello' leads to 'Hello', not 'hello'.
    (modify-syntax-entry ?' "w p" st)
    …
    st)
  "Syntax table used while in `text-mode'.")

;; このモード用にキーマップを作成
(defvar text-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "\e\t" 'ispell-complete-word)
    …
    map)
  "Keymap for `text-mode'.
Many other modes, such as `mail-mode', `outline-mode' and
`indented-text-mode', inherit all the commands defined in this map.")

そして実際にモードコマンドが定義される方法が以下になります:

(define-derived-mode text-mode nil "Text"
  "人間が読むために記述されたテキストを編集するためのメジャーモード
このモードではパラグラフを区切るのはブランク行か空白行だけである
したがって適応型フィル(adaptive filling)の全恩恵を受けられる
 (変数`adaptive-fill-mode'を参照のこと)
\\{text-mode-map}
Textモードのオンによりノーマルフック`text-mode-hook'が実行される"
  (setq-local text-mode-variant t)
  (setq-local require-final-newline mode-require-final-newline))

3つのLisp用モード(Lispモード、Emacs Lispモード、Lisp Interactionモード)はTextモードより多くの機能をもち、それにふさわしくコードもより複雑です。そのようなモードの記述方法を説明するためにlisp-mode.elの抜粋を示します。

以下はLispモードの構文テーブルとabbrevテーブルを定義する方法です:

;; モード固有のテーブル変数の作成
(define-abbrev-table 'lisp-mode-abbrev-table ()
  "Abbrev table for Lisp mode.")

(defvar lisp-mode-syntax-table
  (let ((table (make-syntax-table lisp--mode-syntax-table)))
    (modify-syntax-entry ?\[ "_   " table)
    (modify-syntax-entry ?\] "_   " table)
    (modify-syntax-entry ?# "' 14" table)
    (modify-syntax-entry ?| "\" 23bn" table)
    table)
  "`lisp-mode'で使用される構文テーブル")

Lisp用の3つのモードは多くのコードを共有します。たとえばLispモードとEmacs LispモードはLisp Dataモード、Lisp InteractionモードはEmacs Lispモードから派生したモードです。

その中でも特にLisp Dataモードは、Lispコメントを処理するために変数comment-startをセットアップします:

  (setq-local comment-start ";")
  …

これらの異なるLisp用モードは、微妙に異なるキーマップをもちます。たとえばLispモードはC-c C-zrun-lispにバインドしますが、他のLisp用モードはこれを行いません。とはいえすべてのLisp用モードに共通なコマンドがいくつかあります。以下のコードはそれらの共通コマンドをセットアップします:

(defvar-keymap lisp-mode-shared-map
  :parent prog-mode-map
  :doc "Keymap for commands shared by all sorts of Lisp modes."
  "C-M-q" #'indent-sexp
  "DEL" #'backward-delete-char-untabify)

そして以下がLispモードのためのキーマップをセットアップするコードです:

(defvar-keymap lisp-mode-map
  :doc "Keymap for ordinary Lisp mode.
All commands in `lisp-mode-shared-map' are inherited by this map."
  :parent lisp-mode-shared-map
  "C-M-x" #'lisp-eval-defun
  "C-c C-z" #'run-lisp)

最後はLispモードのためのメジャーモードコマンドです:

(define-derived-mode lisp-mode lisp-data-mode "Lisp"
  "GNU Emacs Lisp以外のLispコードを編集するためのメジャーモード
コマンド:
あたかも後方に移動するようにタブをスペースに削除変換する
パラグラフ区切りはブランク行でコメント開始はセミコロン

\\{lisp-mode-map}
`run-lisp'はinferior Lispジョブの開始と既存ジョブ
から戻るための両方に使われるかもしれないことに注意"
  (setq-local find-tag-default-function 'lisp-find-tag-default)
  (setq-local comment-start-skip
              "\\(\\(^\\|[^\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *")
  (setq imenu-case-fold-search t))

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

24.3 マイナーモード

マイナーモード(minor mode)はメジャーモードの選択とは無関係にユーザーが有効や無効にできるオプション機能の使用を提供します。マイナーモードは個別、あるいは組み合わせて有効にできます。

ほとんどのマイナーモードはメジャーモードとは独立した機能を実装するので、ほとんどのメジャーモードと一緒に使用することができます。たとえばAuto Fillモードはテキスト挿入を許容する任意のメジャーモードとともに機能します。しかし少数ながら特定のメジャーモードに特化したマイナーモードもあります。たとえばDiff Auto RefineモードはDiffモードとの使用だけを意図したマイナーモードです。

理想的にはマイナーモードは他のマイナーモードの効果と無関係に期待した効果をもつべきです。任意の順序でマイナーモードをアクティブや非アクティブにすることも可能であるべきです。

Variable: local-minor-modes

このバッファーローカル変数はカレントバッファーで有効なマイナーモード(シンボル)のリスト。

Variable: global-minor-modes

このバッファーローカル変数はカレントで有効なマイナーグローバルモード(シンボル)のリスト。

Variable: minor-mode-list

この変数の値はすべてのマイナーモードコマンドのリスト。


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

24.3.1 マイナーモード記述の規約

メジャーモードにも監修があるように(メジャーモードを参照)、マイナーモードの記述にも慣習があります。その慣習について以下で説明します。これらの慣習にしたがうにはマクロdefine-minor-modeを使用するのがもっとも簡単な方法です。マイナーモードの定義を参照してください。

  • 名前が‘-mode’で終わる変数を定義する。これをモード変数(mode variable)と呼ぶ。マイナーモードコマンドはこの変数をセットすること。値はそのモードが無効ならnil、有効なら非nilになる。そのマイナーモードがバッファーローカルならこの変数もバッファーローカルであること。

    この変数はモードラインにマイナーモードの名前を表示するためにminor-mode-alistと結合して使用される。これはminor-mode-map-alistを通じて、そのマイナーモードのキーマップがアクティブかどうかも判定する(アクティブなキーマップの制御を参照)。個々のコマンドやフックもこの変数の値をチェックできる。

  • モード変数と同じ名前をもつモードコマンド(mode command)と呼ばれるコマンドを定義する。このコマンドの役目はモード変数の値のセットに加えて、そのモードの機能を使用を実際に有効や無効にするために必要な他のすべてを行うことである。

    モードコマンドは1つのオプション引数を受け入れること。プレフィクス引数なしでinteractiveに呼び出されたらモードをトグルする(toggle: 切り替える。たとえば無効なら有効に、有効なら無効にする)こと。プレフィクス引数とともにinteractiveに呼び出された場合にはその引数が正であればモードを有効にして、それ以外なら無効にすること。

    モードコマンドがLispから(つまり非interactiveに)呼び出された場合は、引数が省略またはnilならモードを有効にすること。引数がシンボルtoggleならモードをトグルして、それ以外なら上述の数引数とともにinteractiveに呼び出されたときと同じ方法によってその引数を扱うこと。

    以下はこの挙動の実装方法を示す例である(define-minor-modeマクロが生成するコードもこれに類似する)。

    (interactive (list (or current-prefix-arg 'toggle)))
    (let ((enable
           (if (eq arg 'toggle)
               (not foo-mode) ; そのモードのモード変数
             (> (prefix-numeric-value arg) 0))))
      (if enable
          do-enable
        do-disable))
    

    やや複雑なこの挙動の理由は、ユーザーが簡単かつinteractiveにマイナーモードをトグルできることと、以下のようにモードフック内で簡単にマイナーモードを有効にできるからである:

    (add-hook 'text-mode-hook 'foo-mode)
    

    foo-modeモードコマンドは引数なしでLispから呼び出されたときは無条件にそのマイナーモードを有効にするので、これはfoo-modeがすでに有効でもそうでなくても正しく振る舞う。モードフック内でマイナーモードを無効にする場合は少々醜くなる:

    (add-hook 'text-mode-hook (lambda () (foo-mode -1)))
    

    しかしこれは頻繁には行われない。

    マイナーモードを2回連続で直接有効(や無効)にしても失敗せずに、1回だけ有効(や無効)にしたときと同じことを行うこと。言い換えるとマイナーモードコマンドはべき等であること。

  • モードラインにマイナーモードを表示したければ、それぞれのマイナーモードにたいして要素をminor-mode-alistに追加する(Definition of minor-mode-alistを参照)。この要素は以下の形式のリストであること:
    (mode-variable string)
    

    ここでmode-variableはマイナーモードの有効化を制御する変数、stringはモードラインに表示するためのスペースで始まる短い文字列である。一度に複数モードの文字列がスペースを占有するので、これらの文字列は短くなければならない。

    minor-mode-alistに要素を追加する際は、重複を避けるために既存要素のチェックにassqを使用すること。たとえば:

    (unless (assq 'leif-mode minor-mode-alist)
      (push '(leif-mode " Leif") minor-mode-alist))
    

    または以下のようにadd-to-list(リスト変数の変更を参照)を使用すること:

    (add-to-list 'minor-mode-alist '(leif-mode " Leif"))
    

これらに加えてメジャーモードにたいする慣習(メジャーモードの慣習を参照)のいくつかは、マイナーモードにたいしても同様に適用されます。それらの慣習はグローバルシンボルの名前、初期化関数の最後でのフックの使用、キーマップおよびその他のテーブルの使用です。

マイナーモードは、可能ならCustom(カスタマイゼーション設定を参照)を通じた有効化と無効化をサポートするべきです。これを行うには、モード変数は:type 'booleanとともにdefcustomで通常は定義されるべきです。その変数をセットするだけではモードの有効化に不足なら、モードコマンドを呼び出すことによりモードを有効にする:setメソッドも指定するべきです。そしてその変数のドキュメント文字列にCustomを通じて変数をセットしなければ効果がないことを注記してください。さらにその定義をautoload cookie(autoload cookieを参照)でマークして、その変数のカスタマイズによりモードを定義するライブラリーがロードされるように:requireを指定します。たとえば:

;;;###autoload
(defcustom msb-mode nil
  "msb-modeをトグルする
この変数を直接セットしても効果がない
\\[customize]か関数`msb-mode'を使用すること"
  :set 'custom-set-minor-mode
  :initialize 'custom-initialize-default
  :version "20.4"
  :type    'boolean
  :group   'msb
  :require 'msb)

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

24.3.2 キーマップとマイナーモード

マイナーモードはそれぞれ自身のキーマップをもつことができ、そのモードが有効になるとそのキーマップがアクティブになります。マイナーモード用のキーマップをセットアップするにはminor-mode-map-alistというalistに要素を追加します。Definition of minor-mode-map-alistを参照してください。

特定の自己挿入文字にたいして自己挿入と同様に他の何かを行うように振る舞いを変更するのは、マイナーモードキーマップの1つの使い方です。(self-insert-commandをカスタマイズする別の方法はpost-self-insert-hookを通じて行う方法。ユーザーレベルの挿入コマンドを参照のこと。これ以外のself-insert-commandカスタマイズ用の機能は特別なケースに限定されておりabbrevモードとAuto Fillモードのためにデザインされている。self-insert-commandの標準定義から独自の定義への置き換えを試みてはならない。エディターコマンドループはこの関数を特別に処理する。)

マイナーモードはコマンドをC-cとその後の区切り文字よって構成されるキーシーケンスにバインドできます。しかしC-cとその後の{}<>:;のいずれかの文字、またはコントロール文字、数字より構成されるシーケンスはメジャーモード用に予約済みです。またC-c letterはユーザー用に予約済みです。キーバインディング規約を参照してください。


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

24.3.3 マイナーモードの定義

マクロdefine-minor-modeは、自己完結した単一定義内にモードを実装する便利な方法を提供します。

Macro: define-minor-mode mode doc keyword-args… body…

このマクロは名前がmode(シンボル)の新たなマイナーモードを定義する。これはドキュメント文字列としてdocをもつマイナーモードをトグルするためにmodeという名前のコマンドを定義する。

トグルコマンドは1つのオプション(プレフィクス)引数を受け取る。引数なしでinteractiveに呼び出されると、そのモードのオンとオフをトグルする。正のプレフィクス引数はモードを有効にして、それ以外のプレフィクス引数はモードを無効にする。Lispから呼び出すと引数がtoggleならモードをトグルして、引数が省略かnilならモードを有効にする。これはたとえばメジャーモードフック内でマイナーモードを有効にするのを簡便にする。docnilなら、このマクロは上記を記述したデフォルトのドキュメント文字列を提供する。

デフォルトではこれはモードを有効にするとt、無効にするとnilにセットされる、modeという名前の変数も定義する。

keyword-argsはキーワードとその後の対応する値により構成され、いくつかのキーワードは特別な意味をもつ:

:global global

nilならそのマイナーモードがバッファーローカルでなくグローバルであることを指定する。デフォルトはnil

マイナーモードをグローバルにしたときの効果の1つは、mode変数がカスタマイズ変数になることである。Customizeインターフェイスを通じてこの変数をトグルするとモードがオンやオフになり、変数の値は将来のEmacsセッション用に保存できるようになる(Saving Customizations in The GNU Emacs Manualを参照)。保存された変数が機能するためには、Emacsが開始されるたびにマイナーモード関数が利用できるようにする必要がある。これは通常はdefine-minor-modeフォームをautoloadすることにより行われる。

:init-value init-value

これはmode変数を初期化するための値。特殊な状況(以下参照)を除き、この値はnilでなければならない。

:lighter lighter

文字列lighterはモード有効時にモードライン内に何を表示するか指定する。これがnilならこのモードはモードライン内に表示されない。

:keymap keymap

オプション引数keymapはそのマイナーモードにたいするキーマップを指定する。非nilなら、それは(値がキーマップであるような)変数の名前かキーマップ、または以下の形式のalistであること

(key-sequence . definition)

ここでkey-sequencedefinitiondefine-keyに渡すのに適した引数である(キーバインディングの変更を参照)。keymapはキーマップかalistであり、これは変数mode-mapも定義する。

:variable place

これはそのモードの状態を格納するために使用されるデフォルトの変数modeを置き換える。これを指定するとmode変数は定義されず、すべてのinit-value引数は使用されない。placeは異なる名前の変数(あなた自身が定義しなければならない)、またはsetf関数とともに使用され得るすべてのもの(ジェネリック変数を参照)。placeにはコンス(get . set)も指定できる。ここでgetはカレント状態をリターンする式であり、setはそれをセットする1つの引数(placeに割り当てられる状態)をとる関数。

:after-hook after-hook

これはモードフック実行後に評価される単一のLispフォームを定義する。これをクォートしないこと。

:interactive value

デフォルトではインタラクティブコマンドであるようなマイナーモード。nil値を指定するとこれを抑制。valueがシンボルのリストなら、そのマイナーモードが有用なメジャーモードを指定するために使用される。

その他のすべてのキーワード引数は変数modeにたいして生成されたdefcustomに直接渡される。これらのキーワードと値についてはカスタマイゼーション変数の定義を参照のこと。

modeという名前のコマンドは最初にmodeという名前の変数をセットする等の標準的な動作を処理した後に、もしあればbodyフォームを実行する。それからモードフック変数mode-hookを実行してから:after-hook内のフォームを評価して終了する(フック実行を含めて、これらすべてはモードの有効化と無効化の両方で行われることに注意)。

init-valueの値はnilでなければなりません。ただし、(1)Emacsによりそのモードが事前ロードされている、または(2)たとえユーザーが要求しなくともモードを有効にするためにロードするのが容易な場合を除きます。たとえば他の何かが有効でなければそのモードの効果がなく、常にそのタイミングでロードされるような場合には、デフォルトでそのモードを有効にすることに害はありません。しかしこの状況は通常はあり得ません。通常はinit-valueの値はnilでなければなりません。

easy-mmode-define-minor-modeという名前はこのマクロにたいするエイリアスです。

以下はdefine-minor-modeの使い方の例です:

(define-minor-mode hungry-mode
  "Hungryモードをトグルする
引数なしでinteractiveに呼び出すとモードをトグルする
正のプレフィクス引数でモードを有効に、その他のプレフィクス引数で
無効にする。Lispから呼び出す場合、引数を省略、またはnilなら
モードを有効に、`toggle'なら状態をトグルする

Hungryモードが有効なときは、C-DELキーは、
最後を除く先行するすべての空白を飲み込む
コマンド \\[hungry-electric-delete] を参照"
 ;; 初期値
 nil
 ;; モードラインの標示
 " Hungry"
 ;; マイナーモードのバインディング
 '(([C-backspace] . hungry-electric-delete)))

これは“Hungry mode”という名前のマイナーモード、モードをトグルするhungry-modeという名前のコマンド、モードが有効かどうかを示すhungry-modeという名前の変数、モードが有効なときそのキーマップを保持するhungry-mode-mapという名前の変数を定義します。これはC-DELにたいするキーバインディングでキーマップを初期化します。bodyフォームはありません — 多くのマイナーモードはそれを必要としません。

以下はこれを記述する等価な方法です:

(define-minor-mode hungry-mode
  "Hungryモードをトグルする
...省略..."
 ;; 初期値
 :init-value nil
 ;; モードラインへのインジケーター
 :lighter " Hungry"
 ;; マイナーモードのバインディング
 :keymap
 '(([C-backspace] . hungry-electric-delete)
   ([C-M-backspace]
    . (lambda ()
        (interactive)
        (hungry-electric-delete t)))))
Macro: define-globalized-minor-mode global-mode mode turn-on keyword-args… body…

これはglobal-modeという名前をグローバルにトグルする。これはmodeという名前のバッファーローカルなマイナーモードをすべてのバッファー(または一部のバッファー。以下参照)で有効か無効にするということを意味する。bodyフォームの実行も行う。あるバッファー内でそのマイナーモードをオンにするには関数turn-onを使用する。マイナーモードをオフにするには-1を引数としてmodeを呼び出す(turn-onは別の関数なのでそのマイナーモードを有効にすべきか先験的に明確でない場合でも有効にするかどうかを決定できる)。

モードをグローバルに有効にすると、それ以降ファイルをvisitすることによって作成されるバッファーやFundamental以外のメジャーモードを使用するバッファーにも影響がある。しかしFundamentalで作成される新たなバッファーは検知しない。

これはCustomizeインターフェイスを通じて、そのマイナーモードのオン/オフを切り替えるカスタムオプションglobal-mode (カスタマイゼーション設定を参照)を定義するマクロ。define-minor-modeと同様に、たとえば:requireを与える等によってEmacs開始時に毎回確実にdefine-globalized-minor-modeフォームが評価されるようにすること。

グローバルマイナーモードのモード変数にたいしてカスタムグループを指定するにはkeyword-args内で:group groupを使用する。

モードのオンかオフかを示すバッファーローカルなマイナーモード変数は、デフォルトではモード自身の名前なまと同じ。これが該当しない場合(状態情報を異なる変数に格納するいくつかのモード)には、:variable variableを使用すること。

一般的にはグローバル化されたマイナーモードを定義するときは、ユーザーがバッファーごとにモードを使用(または無効に)できるように非グローバル版も定義すること。これにより特定のメジャーモード内でそのモードのフックを使用すればグローバルに有効化されたマイナーモードを無効にすることができるようになる。

キーワード:predicateが与えられると、このマクロはグローバルモード変数と似ているが-modeではなく-modesで終わるユーザーオプションを作成する(つまりglobal-modesということ)。この変数は特定のメジャーモードにおいてそのメジャーモードをアクティブにするかどうかを判断する述語関数で使用される。ユーザーは変数の値をカスタマイズして、そのマイナーモードをオンに切り替えるモードを制御できる。:predicateにたいする有効な値 (つまりこれが作成するユーザーオプションの有効な値)にはt (すべてのメジャーモードで使用)、nil (どのメジャーモードでも使用しない)、あるいはモード名のリスト(オプションで(not mode-name …)のようにnotを前置して否定)が含まれる。以下の例のようにこれらの要素を混合させることもできる。

(c-mode (not mail-mode message-mode) text-mode)

これは“c-modeの派生モードで使用、message-modemail-modeの派生モードでは使用せず、text-modeの派生モードでは使用,それ以外に使用するモードはない”ことを意味する。

((not c-mode) t)

c-modeの派生モードでは使用しないが、それ以外なら使用する”ことを意味する。

(text-mode)

これは“text-modeの派生モードでは使用するが他では使用しない”ことを意味する(終端にnil要素が暗に存在する)。

Macro: buffer-local-set-state variable value...

Emacsの一部機能に影響を与えるようなバッファーローカル変数をマイナーモードがセットすることがよくある。あるモードをオフに切り替えた際には、これらの変数の元の状態へのリストアがモードには求められる。これはそれらのことを行う助けとなる利便的なマクロである。これはsetq-localと同じように機能するが、(相方となる関数buffer-local-restore-stateを使って)これらの変数を以前の値や状態をリストアするために使用できるオブジェクトをリターンする。


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

24.4 モードラインのフォーマット

Emacsの各ウィンドウ(ミニバッファーウィンドウを除く)には、通常は最下部にモードラインがあってそのウィンドウ内に表示されたバッファーに関するステータス情報がモードラインに表示されます。モードラインにはバッファー名、関連するファイル、再帰編集の深さ、およびメジャーモードやマイナーモードなどのようなそのバッファーに関する情報が含まれています。ウィンドウはヘッダーライン(header line)をもつこともでき、これはモードラインによく似ていますがウィンドウの最上部に表示されます。

このセクションではモードラインおよびヘッダーラインのコンテンツの制御の仕方について説明します。このチャプターにモードラインを含めた理由は、モードラインに表示される情報の多くが有効化されたメジャーモードとマイナーモードに関連があるからです。


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

24.4.1 モードラインの基礎

各モードラインのコンテンツはバッファーローカル変数mode-line-formatにより指定されます(モードライン制御のトップレベルを参照)。この変数はモードライン構文(mode line construct)を保持します。これはバッファーのモードラインに何を表示するかを制御するテンプレートです。header-line-formatの値は同じ方法によりバッファーのヘッダーラインを指定します。同一のバッファーにたいするすべてのウィンドウは、mode-line-formatheader-line-formatのパラメーター(ウィンドウのパラメーターを参照)がそのウィンドウに指定されていなければ、同じmode-line-formatheader-line-formatを使用します。

効率的な理由によりEmacsは各ウィンドウのモードラインとヘッダーラインを連続で再評価しません。たとえばウィンドウ構成(window configuration)の変更やバッファーの切り替え、バッファーのナローイング(narrowing)やワイドニング(widening)、スクロールやバッファーの変更等、それを呼び出す状況が出現したときにEmacsは再評価を行います。mode-line-formatheader-line-format(モードラインで使用される変数を参照)により参照されるすべての変数、またはテキストが表示される方法に影響を与えるデータ構造(Emacsのディスプレイ表示を参照)を変更する場合には、表示を更新するために関数force-mode-line-updateを使用するべきです。

Function: force-mode-line-update &optional all

この関数は次の再表示サイクルの間にすべての関連する変数の最新の値にもとづいて、カレントバッファーのモードラインとヘッダーラインの更新をEmacsに強制する。オプション引数allが非nilなら、すべてのモードラインとヘッダーラインの更新を強制する。

この関数はメニューバーとフレームタイトルの更新も強制する。

選択されたウィンドウのモードラインは、通常はフェイスmode-line-activeを使用して異なるカラーで表示されます。かわりに他のウィンドウのモードラインはフェイスmode-line-inactiveで表示されます。フェイスを参照してください。

Function: mode-line-window-selected-p

モードラインのウィンドウの選択/非選択の間にもっと大きな差異をもたせたければ、:eval構文内でこの述語を使うことができる。たとえば選択されているウィンドウのバッファー名をボールド(bold: 太字)、他のウィンドウはイタリック(italic: 斜体)で表示したければ以下のように記述できる:

(setq-default
 mode-line-buffer-identification
 '(:eval (propertize "%12b"
		     'face (if (mode-line-window-selected-p)
			       'bold
			     'italic))))

モードラインに大量のデータを出力して、モードラインの最後にある要素を右側へ押し出すモードがあります。mode-line-compact変数が非nilなら、Emacsは連続する複数のスペースを単一のスペースにして、モードラインを“圧縮する”ことができます。この変数がlongなら、モードラインがカレントで選択されたウィンドウより広いときだけこれを行います(これは文字の表示幅ではなく文字数にもとづく近似により計算される)。この変数は特定バッファーでのみモードラインを圧縮するために、バッファーローカルにすることができます。


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

24.4.2 モードラインのデータ構造

モードラインのコンテンツはモードライン構文(mode line construct)と呼ばれるデータ構造によって制御されます。モードライン構文はリストやシンボル、数字を保持するバッファーローカル変数により構成されます。それぞれのデータ型は以下で説明するようにモードラインの外見にたいして特別な意味をもちます。フレームタイトル(フレームのタイトルを参照)とヘッダーライン(ウィンドウのヘッダーラインを参照)にも同じデータ構造が使用されます。

固定文字列のようなシンプルなモードライン構文の場合もありますが、通常はモードライン構文のテキストを構築するために固定文字列と変数の値を組み合わせる方法を指定します。これらの変数の多くはその変数自体がその値によりモードライン構文を定義する変数です。

以下はモードライン構文における、さまざまなデータ型の意味です:

string

モードライン構文における文字列は、文字列内に%構文(%-constructs)を含む以外はそのまま表現される。これらは他のデータによる置換を意味する。モードラインでの%構文を参照のこと。

文字列の一部がfaceプロパティをもつ場合には、バッファー内でそれらが表示されるときと同じようにテキスト表示を制御する。faceプロパティをもたない文字はデフォルトのフェイスmode-line、またはmode-line-inactiveで表示される(Standard Faces in The GNU Emacs Manualを参照)。string内のhelp-echoプロパティとkeymapプロパティは特別な意味をもつ。モードラインでのプロパティを参照のこと。

symbol

モードライン構文におけるシンボルはその値を意味する。モードライン構文としては、symbolの値はsymbolの位置に使用される。しかしシンボルtnilは値がvoidであるようなシンボルとして無視される。

例外が1つある。symbolの値が文字列なら、それはそのまま表示されて%構文は認識されない。

symbolがrisky(危険)とマークされていない(非nilrisky-local-variableプロパティをもつ)場合には、symbolの値中で指定されたテキストプロパティはすべて無視される。これにはsymbolの値中の文字列のテキストプロパティ、同様に文字列内の:evalフォームと:propertizeフォームすべてが含まれる(これはセキュリティー上の理由による。危険とマークされていない変数は、ユーザーへの問い合わせなしでファイル変数から自動的にセットされ得る)。

(string rest…)
(list rest…)

最初の要素が文字列、またはすべての要素を再帰的に処理して結果を結合することを意図したリスト。これはもっとも一般的なモードライン構文である(モードラインへの文字列表示時には、テキストプロパティは(効率的理由により)特別に処理されることに注意。文字列の最初の文字のテキストプロパティだけを考慮して、それを文字列全体に使用する。別のテキストプロパティをもつ文字列が必要なら、特別モードライン構文:propertizeを使う必要がある)。

(:eval form)

最初の要素がシンボル:evalであるようなリストは、formを評価してその結果を表示する文字列として使用するよう指示する。この評価が任意のファイルをロードできないことを確認すること。ファイルをロードすると無限再帰が発生するかもしれない。

(:propertize elt props…)

最初の要素がシンボル:propertizeであるようなリストはモードライン構文eltを再帰的に処理して、propsにより指定されるテキストプロパティに結果を加えるよう指示する。引数propsは0個以上のtext-propertyvalueのペアーで構成されること。eltがテキストプロパティをもつ文字列、またはテキストプロパティをもつ文字列を生成する場合には、その文字列内のすべての文字は同一のプロパティをもつこと。さもなければ:propertizeによっていくつかのプロパティは削除されるかもしれない。

(symbol then else)

最初の要素がキーワード以外のシンボルであるようなリストは条件文を指定する。その意味はsymbolの値に依存する。symbolが非nil値をもつ場合は、モードライン構文として2つ目の要素thenが再帰的に処理され、それ以外は3つ目の要素elseが再帰的に処理される。elseは省略でき、その場合にはsymbolの値がnilかvoidならモードライン構文は何も表示しない。

(width rest…)

最初の要素が整数であるようなリストはrestの結果の切り詰め、またはパディングを指定する。残りの要素restはモードライン構文として再帰的に処理されて互いに結合される。widthが正で結果の幅がwidthより少なければ右側にスペースがパディングされる。widthが負で結果の幅が-widthより大きければ右側が切り詰められる。

たとえばウィンドウ最上部からのバッファー位置をパーセント表示するには(-3 "%p")のようなリストを使用すればよい。


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

24.4.3 モードライン制御のトップレベル

変数mode-line-formatはモードラインの全体的な制御を行います。

User Option: mode-line-format

この変数の値はモードラインのコンテンツを制御するモードライン構文である。これはすべてのバッファーにおいて常にバッファーローカルである。

あるバッファー内でこの変数にnilをセットすると、そのバッファーはモードラインをもたない(高さが1行しかないウィンドウもモードラインを表示しない)。

mode-line-formatのデフォルト値はmode-line-positionmode-line-modes (これはmode-nameminor-mode-alistの値を組み込む)のような、他の変数の値を使用するようデザインされています。mode-line-format自体を変更する必要があるモードはほとんどありません。ほとんどの用途にたいしては、mode-line-formatが直接または間接的に参照するいくつかの変数を修正すれば十分です。

mode-line-formatl自体の変更を行う場合には、コンテンツを複製したり異なる様式で情報を表示するのではなく、新たな値にはデフォルト値(モードラインで使用される変数を参照)に出現する同じ変数を使用するべきです。この方法を使用すればユーザーや(display-timeやメジャーモードのような)Lispプログラムにより行われたカスタマイズは、それらの変数への変更を通じて効力を保ちます。

以下はShellモードにたいして有用かもしれない架空のmode-line-formatの例です(実際にはShellモードはmode-line-formatをセットしない):

(setq mode-line-format
  (list "-"
   'mode-line-mule-info
   'mode-line-modified
   'mode-line-frame-identification
   "%b--"
   ;; これはリスト作成中に評価されることに注意
   ;; これは単なる文字列のモードライン構文を作成する
   (getenv "HOST")
   ":"
   'default-directory
   "   "
   'global-mode-string
   "   %[("
   '(:eval (format-time-string "%F"))
   'mode-line-process
   'minor-mode-alist
   "%n"
   ")%]--"
   '(which-function-mode ("" which-func-format "--"))
   '(line-number-mode "L%l--")
   '(column-number-mode "C%c--")
   '(-3 "%p")))

(変数line-number-modecolumn-number-modewhich-function-modeは特定のマイナーモードを有効にする。これらの変数名は通常のようにマイナーモードコマンド名でもある。)


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

24.4.4 モードラインで使用される変数

このセクションではmode-line-formatの標準的な値としてモードラインテキストに組み込まれる変数を説明します。これらの変数は本質的には特別なものではありません。mode-line-formatが使用する変数を他の変数に変更すれば、それらはモードライン上で同様の効果をもちます。しかしEmacsのさまざまな部分は、それらの変数がモードラインを制御するという認識の元でそれらの変数をセットします。したがって事実上モードラインでそれらの変数を使用するのは必須なのです。Optional Mode Line in The GNU Emacs Manualも参照してください。

Variable: mode-line-mule-info

この変数は言語環境(language environment)、バッファーコーディングシステム、カレント入力メソッド(current input method)に関する情報のモードライン構文の値を保持する。ASCII文字を参照のこと。

Variable: mode-line-modified

この変数はカレントバッファーが変更されたかどうかを表示するモードライン構文の値を保持する。デフォルト値ではバッファーが変更されていれば‘**’、バッファーが変更されていなければ‘--’、バッファーが読み取り専用なら‘%%’、読み取り専用だが変更されているときは‘%*’を表示する。

この変数を変更してもモードラインは強制的に更新されない。

Variable: mode-line-frame-identification

この変数はカレントフレームを識別する。デフォルト値では複製フレームを表示可能なウィンドウシステムを使用している場合は" "、一度に1つのフレームだけを表示する通常の端末では"-%F "を表示する。

Variable: mode-line-buffer-identification

この変数はそのウィンドウ内で表示されているバッファーを識別する。デフォルト値では少なくとも12列になるようスペースパディングされたバッファー名を表示する。

Variable: mode-line-position

この変数はバッファー内での位置を表示する。デフォルト値ではバッファーのパーセント位置、オプションでバッファーサイズ、行番号、列番号を表示する。

User Option: mode-line-percent-position

このオプションはmode-line-positionの中で使用される。これの値はバッファーのパーセンテージ(nil"%o""%p""%P""%q"のいずれか。モードラインでの%構文を参照)とフィルするスペースか切り詰めの幅の両方を指定する。このオプションはcustomize-variable機能でセットすることを推奨する。

Variable: vc-mode

変数vc-modeは各バッファーにたいしてバッファーローカルであり、そのバッファーがvisitしているファイルがバージョンコントロールで保守されているかどうか、保守されている場合はバージョンコントロールシステムの種別を表示する。値はモードラインに表示される文字列、またはバージョンコントロールされていなければnil

Variable: mode-line-modes

この変数はそのバッファーのメジャーモードとマイナーモードを表示する。デフォルト値では再帰編集レベル(recursive editing level)、プロセス状態の情報、ナローイング(narrowing)効果の有無を表示する。

Variable: mode-line-remote

この変数はカレントバッファーのdefault-directoryがリモートかどうかを表示するために使用される。

Variable: mode-line-client

この変数はemacsclientフレームを識別するために使用される。

以下の3つの変数はmode-line-modes内で使用されます:

Variable: mode-name

このバッファーローカル変数はカレントバッファーのメジャーモードの“愛称(pretty name)”を保持する。モードラインにモード名が表示されるように、すべてのメジャーモードはこの変数をセットすること。値は文字列である必要はなく、モードライン構文内で有効な任意のデータ型(モードラインのデータ構造を参照)を使用できる。モードライン内でモード名を識別する文字列の計算にはformat-mode-lineを使用する(モードラインのフォーマットのエミュレートを参照)。

Variable: mode-line-process

このバッファーローカル変数には、そのモードにおいてサブプロセスとの通信にたいするプロセス状態のモードライン情報が含まれる。これはメジャーモード名の直後(間にスペースはない)に表示される。たとえば*shell*バッファーでの値は(":%s")であり、これは‘(Shell:run)’のように、メジャーモードとともにその状態を表示する。この変数は通常はnil

Variable: mode-line-front-space

この変数はモードラインの一番前に表示される。memory-fullメッセージがある場合を除き、デフォルトではこの構文はモードライン先頭の右側に表示される。

Variable: mode-line-end-spaces

この変数はモードラインの終端に表示される。

Variable: mode-line-misc-info

その他の情報にたいするモードライン構文。デフォルトではglobal-mode-stringで指定される情報を表示する。

Variable: mode-line-position-line-format

line-number-mode (Optional Mode Line in The GNU Emacs Manualを参照)がオンの際に行番号表示に使用するフォーマット。フォーマット内の‘%l’は行番号に置き換えられる。

Variable: mode-line-position-column-format

column-number-mode (Optional Mode Line in The GNU Emacs Manualを参照)をオンに切り替えた際に列番号の表示に使用するフォーマット。フォーマット内の‘%c’は0基準、‘%C’は1基準の列番号に置き換えられる。

Variable: mode-line-position-column-line-format

line-number-modecolumn-number-modeの両方がオンの際に列番号表示に使用するフォーマット。フォーマットspecsの‘%l’、‘%c’、‘%C’の意味については、前出の2つの変数を参照のこと。

Variable: minor-mode-alist

この変数はアクティブなマイナーモードをモードラインに示す方法を指定する要素をもった連想リスト(association list)を保持する。minor-mode-alistの各要素は以下のような2要素のリストであること:

(minor-mode-variable mode-line-string)

より一般的にはmode-line-stringは任意のモードライン構文を指定できる。minor-mode-variableの値が非nilならモードラインに表示され、それ以外なら表示されない。混合しないようにこれらの文字列はスペースで始めること。慣例的に特定のモードにたいするminor-mode-variableは、そのマイナーモードがアクティブになった際に非nil値にセットされる。

minor-mode-alist自体はバッファーローカルではない。このalist内で参照される各変数は、そのマイナーモードをバッファーごとに個別に有効にできるならバッファーローカルであること。

Variable: global-mode-string

この変数は、デフォルトではmode-line-misc-infoの一部としてモードラインに表示されるモードライン構文が保持されている。マイナーモードwhich-function-modeが有効ならこのモード情報の直後、有効でなければmode-line-modesの後に表示される。この構文に追加する要素は通常はスペース内に収まること(後続のglobal-mode-string要素が正しく表示されるために)。

%M’構文はglobal-mode-stringの値を置き換える。この変数自体はmode-line-misc-infoで使用されているので、この構文はデフォルトのモードライン使用されない。

以下はmode-line-formatのデフォルト値の簡略化バージョンです。実際のデフォルト値には追加のテキストプロパティ指定も含まれます。

("-"
 mode-line-mule-info
 mode-line-modified
 mode-line-frame-identification
 mode-line-buffer-identification
 "   "
 mode-line-position
 (vc-mode vc-mode)
 "   "
 mode-line-modes
 (which-function-mode ("" which-func-format "--"))
 (global-mode-string ("--" global-mode-string))
 "-%-")

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

24.4.5 モードラインでの%構文

モードライン構文として使用される文字列では、さまざまな種類のデータを置き換えるために%構文を使用できます。以下は定義済みの%構文と意味のリストです。

%%’以外の構文では、フィールドの最小幅を指定するために‘%’の後に10進整数を追加できます。幅がそれより小さければそのフィールドは最小幅にパディングされます。純粋に数値的な構文(‘c’、‘i’、‘I’、‘l’)は左側、それ以外は右側にスペースを追加してパディングされます。

%b

buffer-name関数により取得されるカレントバッファー名。バッファーの名前を参照のこと。

%c

ポイント位置のカレント列番号。そのウィンドウの左マージンより0からカウントされる。

%C

ポイント位置のカレント列番号。そのウィンドウの左マージンより1からカウントされる。

%e

EmacsがLispオブジェクトにたいしてメモリー不足になりそうなときは、それを伝える簡略なメッセージを示す。それ以外の場合は空。

%f

buffer-file-name関数により取得されるvisit中のファイル名。バッファーのファイル名を参照のこと。

%F

選択されたフレームのタイトル(ウィンドウシステム上のみ)か名前。基本パラメーターを参照のこと。

%i

カレントバッファーのアクセス可能な範囲のサイズ。基本的には(- (point-max) (point-min))

%I

%i’と同様だが10^3は‘k’、10^6は‘M’、10^9は‘G’を使用して略記することで、より読みやすい方法でサイズをプリントする。

%l

ポイント位置のカレント行番号。そのバッファーのアクセス可能な範囲内でカウントされる。

%M

global-mode-stringの値(デフォルトではmode-line-misc-infoの一部)。

%n

ナローイングが有効なときは‘Narrow’、それ以外は何も表示しない(ナローイングnarrow-to-regionを参照)。

%o

バッファー(の可視な範囲)を通じてウィンドウがtravel した割合(ウィンドウ外部にあるすべてのテキストにたいしてウィンドウ上端の上にあるテキストのサイズのパーセンテージまたは‘Top’、‘Bottom’、‘All’)。

%p

ウィンドウの最上部より上にあるバッファーテキストのパーセント表示、または‘Top’、‘Bottom’、‘All’のいずれか。デフォルトのモードライン構文は、これを3文字に切り詰めることに注意。

%P

ウィンドウの最下部より上にあるバッファーテキスト(ウィンドウ内の可視なテキストと最上部の上にあるテキスト)のパーセント表示、およびバッファーの最上部がスクリーン上で可視なら、それに加えて‘Top’。または‘Bottom’か‘All’。

%q

-’で区切ったウィンドウの上端および下端より上にあるテキストのパーセンテージ、または‘All’。

%s

process-statusにより取得されるカレントバッファーに属するサブプロセスの状態。プロセスの情報を参照のこと。

%z

キーボード、端末、およびバッファーコーディングシステムのニーモニック。

%Z

%z’と同様だが、EOL形式(end-of-line format: 改行形式)を含む。

%*

バッファーが読み取り専用(buffer-read-onlyを参照)なら‘%’、
変更(buffer-modified-pを参照)されていればは‘*’、
それ以外は‘-’。バッファーの変更を参照のこと。

%+

バッファーが変更(buffer-modified-pを参照)されていれば‘*
バッファーが読み取り専用(buffer-read-onlyを参照)なら‘%’、
それ以外は‘-’。これは読み取り専用バッファーの変更にたいしてのみ‘%*’と異なる。バッファーの変更を参照のこと。

%&

バッファーが変更されてれば‘*’、それ以外は‘-’。

%@

バッファーのdefault-directory (ファイル名を展開する関数を参照)がリモートマシンなら‘@’、それ以外なら‘-’。

%[

再帰編集レベルの深さを表示する(ミニバッファーレベルは勘定しない)編集レベル1つが‘[’。再帰編集を参照のこと。

%]

編集レベル1つが‘]’(ミニバッファーレベルは勘定しない)。

%-

モードラインの残りを充填するのに十分なダッシュ。

%%

文字‘%’。%構文が許される文字列内にリテラル‘%’を含めるにはこの方法を使用する。

廃止となる%-構文

以下の構文は今後使用するべきではありません。

%m

廃止; かわりにmode-name変数を使うこと。mode-nameの値が(たとえばemacs-lisp-modeの値のように)非文字列のモードライン構文の場合には、%m構文は空文字列を生成するので不十分である。


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

24.4.6 モードラインでのプロパティ

モードライン内では特定のテキストプロパティが意味をもちます。faceプロパティはテキストの外見に影響します。help-echoプロパティはそのテキストのヘルプ文字列に関連し、keymapによりテキストをマウスに感応させることができます。

モードライン内のテキストにたいしてテキストプロパティを指定するには4つの方法があります:

  1. モードラインデータ構造内にテキストプロパティをもつ文字列を直接配置するが、それに関する注意点はモードラインのデータ構造を参照のこと。
  2. %12b’のようなモードライン%構文にテキストプロパティを配置する。その場合には%構文を展開すると同じテキストプロパティをもつことになる。
  3. propsで指定されるテキストプロパティをeltに与えるために(:propertize elt props…)構文を使用する。
  4. formがテキストプロパティをもつ文字列に評価されるようにモードラインデータ構造内に:eval formを含むリストを使用する。

キーマップを指定するためにkeymapプロパティを使用できます。このキーマップはマウスクリックにたいしてのみ実際の効果をもちます。モードライン内にポイントを移動させるのは不可能なので、これに文字キーやファンクションキーをバインドしても効果はありません。

risky-local-variableが非nilであるようなプロパティをもつ変数をモードラインが参照する場合には、その変数の値から取得または指定されるテキストプロパティはすべて無視されます。そのようなプロパティは呼び出される関数を指定するかもしれず、その関数はファイルローカル変数に由来するかもしれないからです。


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

24.4.7 ウィンドウのヘッダーライン

最下部にモードラインをもつことができるのと同じように、ウィンドウは最上部にヘッダーライン(header line)をもつことができます。ヘッダーライン機能は、それがheader-line-formatによって制御されることを除けばモードラインと同じように機能します。

Variable: header-line-format

すべてのバッファーにたいしてローカルなこの変数は、そのバッファーを表示するバッファーにたいしてヘッダーラインを表示する方法を指定する。この変数の値のフォーマットはmode-line-formatにたいするフォーマットと同じ(モードラインのデータ構造を参照)。この変数は通常はnilなので、通常のバッファーはヘッダーラインをもたない。

バッファーでdisplay-line-numbers-mode (display-line-numbers-mode in The GNU Emacs Manualを参照)がオンになっていると、バッファーのテキストは行番号の表示に必要なスクリーンスペース分インデントされて表示されます。それとは対照的にヘッダーラインのテキストは自動的にインデントされません。ヘッダーラインに行番号が表示されることはありませんし、ヘッダーラインとその下にあるバッファーのテキストが直接関連する必要はないからです。バッファーのテキストに合わせてヘッダーラインのテキストを位置揃えする必要があるLispプログラムや、tabulated-list-mode (Tabulated Listモードを参照)のように列形式データを表示するバッファーは、マイナーモードheader-line-indent-modeをオンにする必要があります。

Command: header-line-indent-mode

このバッファーローカルなマイナーモードはスクリーン上で表示されている行番号の幅(そのウィンドウで表示されている行番号範囲に応じて大きく異なる可能性あり)の変更を追跡して、行番号の幅が変更された際にヘッダーラインとバッファーラインのテキストを常に位置揃えさせる手段をLispプログラムに提供する。このようなLispプログラムはバッファーでこのモードをオンにして、常時テキストのインデントを確実に調節するために、header-line-formatの中でheader-line-indentおよびheader-line-indent-widthという変数を使う必要がある。

Variable: header-line-indent

そのウィンドウで表示されているバッファーでheader-line-indent-modeの場合には、表示中の行番号のカレント幅と同じ幅をもつ空白文字列がこの変数の値となる。空白の個数はヘッダーラインのテキストのフェイスにおいて、サイズも含めてフレームのデフォルトフォントと同じフォントが使用されている前提で計算される。この前提が成り立たない場合には、かわりに下記のheader-line-indent-widthを使うこと。これは値をヘッダーラインのテキストの先頭に追加することによって、バッファーのテキストに合わせてヘッダーラインのテキスト全体のインデントを再調整するというシンプルな状況で使用されることを意図した変数である。たとえば以下のheader-line-formatの定義では:

(setq header-line-format
      `("" header-line-indent ,my-header-line))

ここでmy-header-lineはヘッダーラインの実際のテキストを生成するフォーマット文字列。これによりヘッダーラインのテキストはその下にあるバッファーと同じように常にインデントされることが保証される。

Variable: header-line-indent-width

そのウィンドウで表示されているバッファーでheader-line-indent-modeの場合には、この変数の値は行番号の表示に用いられるフレームの正規文字幅単位でカレント幅を提供するよう最新に保たれる。バッファーのテキストに合わせてヘッダーラインのテキストを位置揃えするにあたり、header-line-indentでは柔軟性に欠けるような際に用いることができる。たとえばヘッダーラインでデフォルトフェイスのフォントと異なるメトリクス(訳注: 個々の文字や全体の文字の平均について様々な値を定義する測定情報のこと)のフォントを使用している場合には、frame-char-width (フレームのフォントを参照)のリターン値にこの変数の値を乗じて表示されている行番号のピクセル幅を計算、その結果をheader-line-frormatの関連する部分にピクセル単位で適用するためにディスプレイプロパティ仕様:align-to (スペースの指定を参照)を用いてヘッダーラインのテキストの位置合わせをを行えばよい。

Function: window-header-line-height &optional window

この関数はwindowのヘッダーラインの高さをピクセルでリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。

高さが1行しかないウィンドウがヘッダーラインを表示することは決してありません。また高さが2行しかないウィンドウは、同時にモードラインとヘッダーラインを表示できません。そのようなウィンドウがモードラインをもつ場合にはヘッダーラインは表示されません。


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

24.4.8 モードラインのフォーマットのエミュレート

関数format-mode-lineを使用して、特定のモードライン構文にもとづいてモードラインやヘッダーラインに表示されるテキストを計算できます。

Function: format-mode-line format &optional face window buffer

この関数は、あたかもwindowにたいしてモードラインを生成するかのようにformatに応じてテキスト行をフォーマットするが、さらにそのテキストを文字列としてリターンする。引数windowのデフォルトは選択されたウィンドウ。bufferが非nilなら、使用されるすべての情報はbufferから取得される。デフォルトではwindowのバッファーから取得される。

文字列の値は通常はモードラインがもつであろうフェイス、キーマップ等に対応したテキストプロパティをもつ。formatにより指定されるfaceプロパティをもたないすべての文字は、faceにより決定されるデフォルト値を取得する。facetの場合はwindowが選択されていればmode-line、それ以外はmode-line-inactiveであることを意味する。facenilまたは省略された場合はデフォルトのフェイスを意味する。faceが整数なら、この関数はテキストプロパティをもたない値をリターンするだろう。

faceの値として他の有効なフェイスを指定することもできる。指定された場合、それはformatでフェイスを指定されていない文字のfaceプロパティのフェイスを提供する。

faceとしてmode-linemode-line-inactiveheader-lineを使用することにより、フォーマットされた文字列のリターンに加えて、対応するフェイスのカレント定義を使用して実際にモードラインやヘッダーラインの再描画が行われることに注意(他のフェイスでは再描画は行われない)。

たとえば(format-mode-line header-line-format)は選択されたウィンドウに表示されるテキスト(ヘッダーラインがない場合は"")をリターンするだろう。(format-mode-line header-line-format 'header-line)は、各文字がヘッダーライン内でもつであろうフェイスをもつ同じテキストをリターンするとともに、それに加えてヘッダーラインの再描画も行う。


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

24.5 Imenu

Imenuとはバッファー内の定義やセクションをすべてリストするメニューをユーザーが選択することによって、バッファー内の該当箇所に直接移動する機能です。Imenuは定義(またはバッファーのその他の名前つき範囲)の名前とその定義のバッファー内での位置をリストするバッファーインデックスを構築して、ユーザーがそれを選択すればポイントをそこに移動できるようにして機能します。メジャーモードはimenu-add-to-menubarを使用して、メニューバーアイテムを追加することができます。

Command: imenu-add-to-menubar name

この関数はImenuを実行するためのnameという名前のローカルメニューバーを定義する。

Imenuを使用するためのユーザーレベルコマンドはEmacsマニュアルで説明されています(Imenu in the Emacs Manualを参照)。このセクションでは特定のメジャーモードにたいして定義や名前つき範囲を見つけるImenuメソッドのカスタマイズ方法を説明します。

変数imenu-generic-expressionをセットするのが通常、かつもっともシンプルな方法です:

Variable: imenu-generic-expression

この変数が非nilなら、それはImenuにたいして定義を探すための正規表現を指定するリストである。シンプルなimenu-generic-expressionの要素は以下のようになる:

(menu-title regexp index)

ここでmenu-titleが非nilなら、それはこの要素にたいするマッチがバッファーインデックスのサブメニューとなることを指示する。menu-title自体はそのサブメニューにたいして名前を指定する。menu-titlenilなら、この要素にたいするマッチは直接トップレベルのバッファーインデックスとなる。

このリストの2つ目の要素regexpは正規表現である(正規表現を参照)。これはバッファー内でこれにマッチするものは定義、あるいはバッファーインデックス内に記載すべき何かであると判断される。3つ目の要素indexは0以上の整数なら、regexp内の部分式(subexpression)が定義名にマッチすることを示す。

以下のような要素もある:

(menu-title regexp index function arguments…)

この要素にたいする各マッチはインデックスアイテムを作成して、ユーザーにがそのインデックスアイテムを選択したときアイテム名、バッファー位置、およびargumentsから構成される引数でfunctionを呼び出す。

Emacs Lispモードではimenu-generic-expressionは以下のようになるだろう:

((nil "^\\s-*(def\\(un\\|subst\\|macro\\|advice\\)\
\\s-+\\([-A-Za-z0-9+]+\\)" 2)
 ("*Vars*" "^\\s-*(def\\(var\\|const\\)\
\\s-+\\([-A-Za-z0-9+]+\\)" 2)
 ("*Types*"
  "^\\s-*\
(def\\(type\\|struct\\|class\\|ine-condition\\)\
\\s-+\\([-A-Za-z0-9+]+\\)" 2))

この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。

Variable: imenu-case-fold-search

この変数はimenu-generic-expressionの値中の正規表現マッチがcase(大文字小文字)を区別するかどうかを制御する。t(デフォルト)ならcaseの違いを無視することを意味する。

この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。

Variable: imenu-syntax-alist

この変数はimenu-generic-expression処理中に、カレントバッファーの構文テーブルをオーバーライドするために使用する構文テーブル変更用のalist。このalistの各要素は以下の形式をもつこと:

(characters . syntax-description)

CARcharactersには文字か文字列を指定できる。この要素はその文字か文字列がsyntax-descriptionにより指定される構文であることを示し、modify-syntax-entryに渡される(構文テーブルの関数を参照)。

典型的にはこの機能はシンボル構文(symbol syntax)をもつ文字にたいして単語構文(word syntax)を与えるために通常は使用され、それによりimenu-generic-expressionが単純になってマッチングのスピードも向上する。たとえばFortranモードでは以下のようにこれを使用する:

(setq imenu-syntax-alist '(("_$" . "w")))

imenu-generic-expressionの正規表現は、‘\\(\\sw\\|\\s_\\)+’のかわりに、‘\\sw+’を使用できる。このテクニックは名前をモード名として許容されるより短い頭文字に制限する必要があるときは不便かもしれないことに注意。

この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。

あるメジャーモードにたいしてImenuをカスタマイズする別の方法としてimenu-prev-index-position-functionimenu-extract-index-name-functionがあります:

Variable: imenu-prev-index-position-function

この変数が非nilなら、その値はポイント位置からバッファーを後方にスキャンしてバッファーインデックスに配置すべき次の定義を探すための関数であること。そしてポイントより前に他の定義が見つからなければnilをリターンすること。見つかった場合には定義を見つけた場所にポイントを残して任意の非nil値をリターンすること。

この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。

Variable: imenu-extract-index-name-function

この変数が非nilなら、その値はポイントが定義中にある(imenu-prev-index-position-function関数がポイントを残す場所)という想定にもとづき、その定義の名前をリターンする関数であること。

この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。

メジャーモードにたいしてImenuをカスタマイズするための最後の方法は変数imenu-create-index-functionのセットです:

Variable: imenu-create-index-function

この変数はバッファーインデックスを作成するために使用する関数を指定する。この関数は引数がを受け取らず、カレントバッファーにたいするインデックスalist(index alist)をリターンすること。この関数はsave-excursion内で呼び出されるので、どこにポイントを残しても違いはない。

このインデックスalistは3つのタイプの要素をもつことができる。以下はシンプル要素(simple element)の例:

(index-name . index-position)

シンプル要素の選択はそのバッファー内の位置index-positionに移動する効果をもつ。スペシャル要素(special element)は以下のようなもの:

(index-name index-position function arguments…)

スペシャル要素の選択により以下が処理される:

(funcall function
         index-name index-position arguments…)

ネストされたサブalist要素(nested sub-alist element)は以下のようなもの:

(menu-title . sub-alist)

これはsub-alistにより指定されるサブメニューmenu-titleを作成する。

imenu-create-index-functionのデフォルト値はimenu-default-create-index-function。この関数はインデックスalistを生成するためにimenu-prev-index-position-functionの値とimenu-extract-index-name-functionの値を呼び出す。しかしこれら2つ変数のいずれかがnilなら、デフォルト関数はかわりにimenu-generic-expressionを使用する。

この変数はセットによりカレントバッファーにたいしてバッファーローカルになる。

tree-sitterとともにEmacsをビルドしていてメジャーモードが関連する変数をセットしていれば、自動的にImenuのインデックスが生成されます。

Variable: treesit-simple-imenu-settings

これはどのようにImenuインデックスを生成するかをEmacsに指示するための変数である。(category regexp pred name-fn)という形式のリストであること。

categoryは"Function"、"Class"等のようなカテゴリー名、regexpcategoryに属すノードタイプにマッチするregexp、prednil、または引数としてノードを受け取る関数であること。この関数はノードがcategoryにたいして有効なら非nil、そうでなければnilをリターンする必要がある。

categorynilでもよく、その場合にはregexpregexpでマッチされたエントリーはcategory下にグループ化されない。

name-fnnil、あるいはdefunノードを受け取りそのdefunの名前(関数定義にたいする関数名)をリターンする関数のいずれかであること。name-fnnilの場合には、かわりにtreesit-defun-name (tree-sitterを用いるメジャーモードの開発を参照)が使用される。

この変数が非nilの場合には、treesit-major-mode-setup (tree-sitterを用いるメジャーモードの開発を参照)が自動的にImenuをセットアップする。


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

24.6 Font Lockモード

Font Lockモードとはバッファーの特定の部分にたいして、それらの構文的役割(syntactic role)にもとづき自動的にfaceプロパティをアタッチするバッファーローカルなマイナーモードです。このモードがバッファーをパースする方法はそのメジャーモードに依存します。ほとんどのメジャーモードは、どのコンテキストでどのフェイスを使用するかにたいして構文的条件(syntactic criteria)を定義します。このセクションでは特定のメジャーモードにたいしてFont Lockをカスタマイズする方法を説明します。

Font Lockモードは(通常は外部のライブラリーやプログラムを介した)本格的なパーサー、Emacs組み込みの構文テーブルにもとづく構文解析、(通常は正規表現にたいする)検索という3つの手法によりハイライトするテキストを見つけます。有効になっていればまずパーサーベース(パーサーベースのFont Lockを参照)のフォント表示、次にコメントと文字列定数を見つけてハイライトする構文的なフォント表示、最後に検索ベースのフォント表示が行われます。


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

24.6.1 Font Lockの基礎

Font Lock機能はいくつかの基本的な関数にもとづきます。これらはそれぞれ対応する変数により指定される関数を呼び出します。このインダイレクションによりメジャーモードとマイナーモードはそのモードにあるバッファーのフォント表示が機能する方法を変更したり、フォント表示を何も行わない機能にたいしてさえFont Lockメカニズムを使用することが可能になります(以下の記述で関数が何を行うか説明する際に“should(すること、するべき)”と表現しているのはこれが理由。モードは完全に異なる何かを行うように対応する変数をカスタマイズできる)。以下で言及される変数はFont Lockのその他の変数で説明されています。

font-lock-fontify-buffer

この関数はfont-lock-fontify-buffer-functionで指定される関数の呼び出しにより、カレントバッファーのアクセス可能範囲をフォント表示すること。

font-lock-unfontify-buffer

フォント表示削除のためにFont Lockをオフに切り替える際に使用する。font-lock-unfontify-buffer-functionで指定される関数を呼び出す。

font-lock-fontify-region beg end &optional loudly

begendの間のリージョンをフォント表示すること。loudlyが非nilなら、フォント表示中にステータスメッセージを表示すること。font-lock-fontify-region-functionで指定される関数を呼び出す。

font-lock-unfontify-region beg end

begendの間のリージョンのフォント表示を削除すること。font-lock-unfontify-region-functionで指定される関数を呼び出す。

font-lock-flush &optional beg end

この関数はbegendの間のリージョンのフォント表示を期限切れ(outdated)とマークすること。begendが未指定またはnilなら、デフォルトはそのバッファーのアクセス可能範囲の先頭と終端。font-lock-flush-functionで指定される関数を呼び出す。

font-lock-ensure &optional beg end

この関数はbegendの間のリージョンのフォント表示を保証すること。オプション引数begendのデフォルトは、そのバッファーのアクセス可能範囲の先頭と終端。font-lock-ensure-functionで指定される関数を呼び出す。

font-lock-debug-fontify

これはモード用のFont Lock開発時の使用を意図した利便的なコマンドであり、Lispコードから呼び出すべきではありません。これは関連するすべての変数を再計算してから、バッファー全体にたいしてfont-lock-fontify-regionを呼び出します。

Font Lockモードのテキストのハイライト方法を制御する変数がいくつかあります。しかしメジャーモードはこれらの変数を直接セットするべきではありません。かわりにメジャーモードはバッファーローカル変数としてfont-lock-defaultsをセットするべきです。Font Lockモードが有効なときは、他のすべての変数をセットするためにこの変数に割り当てられた値が使用されます。

Variable: font-lock-defaults

この変数はそのモード内のテキストをフォント表示する方法を指定するためにモードによりセットされる。この変数はセットした際に自動的にバッファーローカルになる。変数の値がnilならFont Lockモードはハイライトを行わず、バッファー内のテキストに明示的にフェイスを割り当てるために‘Faces’メニュー(メニューバーの‘Edit’の下の‘Text Properties’)を使用できる。

nilなら値は以下のようであること:

(keywords [keywords-only [case-fold
 [syntax-alist other-vars…]]])

1つ目の要素keywordsは検索ベースのフォント表示を制御するfont-lock-keywordsの値を間接的に指定する。値にはシンボル、変数、またはfont-lock-keywordsにたいして使用するリストが値であるような関数を指定できる。またそれぞれのシンボルがフォント表示の可能なレベルであるような、いくつかのシンボルからなるリストも指定できる。この場合には、1つ目のシンボルはフォント表示の‘モードデフォルト(mode default)’レベル、次のシンボルはフォント表示のレベル1、その次はレベル2、...のようになる。‘モードデフォルト’レベルは通常はレベル1と等しい。これはfont-lock-maximum-decorationnil値をもつとき使用される。Font Lockのレベルを参照のこと。

2つ目の要素keywords-onlyは変数font-lock-keywords-onlyの値を指定する。これが省略またはnilなら、(文字列とコメントの)構文的フォント表示も行われる。非nilなら構文的フォント表示は行われない。構文的なFont Lockを参照のこと。

3つ目の要素case-foldfont-lock-keywords-case-fold-searchの値を指定する。非nilなら検索ベースフォント表示の間、Font Lockモードはcaseの違いを無視する。

4つ目の要素syntax-alistが非nilなら、それは(char-or-string . string)という形式のコンスセルのリストであること。これらは構文的フォント表示にたいする構文テーブルのセットアップに使用される。結果となる構文テーブルはfont-lock-syntax-tableに格納される。syntax-alistが省略またはnilなら、構文的フォント表示はsyntax-table関数によりリターンされる構文テーブルを使用する。構文テーブルの関数を参照のこと。

(もしあれば)残りすべての要素はまとめてother-varsと呼ばれる。これらの要素はすべて(variable . value)という形式をもつこと。これはvariableをバッファーローカルにしてから、それにvalueをセットすることを意味する。これらother-varsを使用して、最初の5つの要素による制御とは別にフォント表示に影響する他の変数をセットできる。Font Lockのその他の変数を参照のこと。

モードがfont-lock-faceプロパティ追加により明示的にテキストをフォント表示する場合には、自動的なフォント表示すべてをオフにするためにfont-lock-defaults(nil t)を指定できます。しかしこれは必須ではありません。font-lock-faceを使用して何かをフォント表示して、それ以外の部分のテキストを自動的にフォント表示するようにセットアップすることが可能です。


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

24.6.2 検索ベースのフォント化

検索ベースのフォント表示を直接制御する変数はfont-lock-keywordsです。この変数は通常はfont-lock-defaults内の要素keywordsを通じて指定されます。

Variable: font-lock-keywords

この変数の値はハイライトするキーワードのリスト。Lispプログラムはこの変数を直接セットしないこと。通常はfont-lock-defaults内の要素keywordsを使用してFont Lockモードが自動的に値をセットする。この値は関数font-lock-add-keywordsfont-lock-remove-keywordsを使用して変更することもできる(検索ベースのフォント化のカスタマイズを参照)。

font-lock-keywordsの各要素は、特定の例に該当するテキストを見つける方法や、それらをハイライトする方法を指定します。Font Lockモードはfont-lock-keywordsの要素を逐次処理してマッチを探して、すべてのマッチを処理します。通常はテキストの一部はすでに一度はフォント表示されており、同じテキスト内で連続するマッチによりこれをオーバーライドすることははできません。しかしsubexp-highlighterの要素overrideを使用して異なる挙動を指定できます。

font-lock-keywordsの各要素は以下の形式のいずれかをもつべきです:

regexp

font-lock-keyword-faceを使用してregexpにたいするすべてのマッチをハイライトする。たとえば、

;; font-lock-keyword-faceを使用して
;; 単語‘foo’をハイライトする
"\\<foo\\>"

これらの正規表現を作成するときは慎重に行うこと。下手に記述されたパターンによりスピードが劇的に低下し得る! 関数regexp-opt (正規表現の関数を参照)は、いくつかのキーワードとマッチするために最適な正規表現の計算に有用である。

function

functionを呼び出すことによりテキストを探し、font-lock-keyword-faceを使用して見つかったマッチをハイライトする。

functionは呼び出される際に1つの引数(検索のリミット)を受け取る。検索はポイント位置から開始しリミットを超えた検索は行わないこと。これは検索が成功したら非nilをリターンして見つかったマッチを表すマッチデータをセットすること。nilのリターンは検索の失敗を示す。

フォント表示は前の呼び出しでポイントが残された位置から同じリミットを用いてfunctionを呼び出し、functionが失敗するまでfunctionを繰り返し呼び出すだろう。検索が失敗しても何らかの特別な方法でfunctionがポイントをリセットする必要はない。

(matcher . subexp)

この種の要素ではmatcherは上述のregexpかfunctionのいずれかである。CDRsubexpは、(matcherがマッチするテキスト全体のかわりに)matcherのどの部分式(subexpression)がハイライトされるべきかを指定する。

;; font-lock-keyword-faceを使用して
;; bar’が‘fubar’の一部のときに
;; ハイライトする
("fu\\(bar\\)" . 1)
(matcher . facespec)

この種の要素ではfacespecの値がハイライトに使用するフェイスを指定する。もっともシンプルな例ではfacespecは値がフェイス名であるようなはLisp変数(シンボル)。

;; fubar-faceの値のフェイスを使用して
;; fubar’をハイライトする
("fubar" . fubar-face)

しかしfacespecは以下のような形式のリストに評価されてもよい:

(subexp
(face face prop1 val1 prop2 val2…))

これはマッチしたテキストにフェイスfaceを指定し、さまざまなテキストプロパティをputする。これを行う場合には、この方法によってfont-lock-extra-managed-propsに値をセットする、他テキストプロパティ名を確実に追加すること。そうすればそれらのプロパティが妥当性を失ったとき、それらのプロパティもクリアーされるだろう。これらのプロパティをクリアーする関数を変数font-lock-unfontify-region-functionにセットすることもできる。Font Lockのその他の変数を参照のこと。

(matcher . subexp-highlighter)

この種の要素ではsubexp-highlightermatcherにより見つかったマッチをハイライトする方法を指定するリストである。これは以下の形式をもつ。

(subexp facespec [override [laxmatch]])

CARsubexpはマッチのどの部分式をフォント表示するかを指定する整数(0はマッチしたテキスト全体を意味する)。これの2つ目の要素facespecは上述したような、値がフェイスを指定する式である。

subexp-highlighter内の残りの値overridelaxmatchはオプションのフラグである。overridetなら、この要素は前のfont-lock-keywordsの要素により作成された既存のフォント表示をオーバーライドできる。値がkeepなら、すでに他の要素によりフォント表示されていない文字がフォント表示される。値がprependなら、facespecにより指定されたフェイスがfont-lock-faceプロパティの先頭に追加される。値がappendなら、そのフェイスがfont-lock-faceプロパティの最後に追加される。

laxmatchが非nilなら、それはmatcher内で番号付けされた部分式subexpが存在しなくてもエラーにならないことを意味する。番号付けされた部分式subexpのフォント表示は当然発生しない。しかし他の部分式(と他のregexp)のフォント表示は継続されるだろう。laxmatchnil、かつ指定された部分式が存在しなければ、エラーがシグナルされて検索ベースのフォント表示は終了する。

以下はこのタイプの要素とそれが何を行うかの例:

;; foo-bar-faceを使用して、たとえハイライト済みでも
;; foo’と‘bar’をハイライトする
;; foo-bar-faceは値がフェイスであるような変数であること
("foo\\|bar" 0 foo-bar-face t)

;; fubar-faceの値のフェイスを使用して
;; 関数fubar-matchが見つけた各マッチの
;; 最初の部分式をハイライトする
(fubar-match 1 fubar-face)
(matcher . anchored-highlighter)

この種の要素ではanchored-highlightermatcherが見つけたマッチに後続するテキストをハイライトする方法を指定する。つまりmatcherが見つけたマッチは、anchored-highlighterにより指定されるその先の検索にたいするアンカー(anchor)として機能する。anchored-highlighterは以下の形式のリストである:

(anchored-matcher pre-form post-form subexp-highlighters…)

ここでanchored-matchermatcherと同様、正規表現か関数である。matcherにたいするマッチを見つけた後に、ポイントはそのマッチの終端に移動する。そこでFont Lockはフォームpre-formを評価する。それからanchored-matcherにたいするマッチを検索し、subexp-highlightersを使用してそれらのマッチをハイライトする。subexp-highlighterについては上記を参照のこと。最後にFont Lockはpost-formを評価する。

フォームpre-formpost-formは、anchored-matcher使用時の事前の初期化と事後のクリーンアップに使用できる。pre-formは通常はanchored-matcherの開始前に、matcherのマッチに関連する何らかの位置にポイントを移動するために使用される。post-formは、matcherの再開前にポイントを戻すために使用できる。

pre-formを評価した後、Font Lockはその行の終端の先にたいしてanchored-matcherの検索を行わない。しかしpre-formpre-form評価後のポイント位置より大きいバッファー位置をリターンした場合には、かわりにpre-formによりリターンされた位置が検索リミットとして使用される。その行の終端より大きい位置をリターンするのは、一般的にはよいアイデアではない。言い換えるとanchored-matcher検索は複数行にわたる(span lines)べきではない。

たとえば、

;; item-faceの値を使用して
;; 単語‘anchor’に(同一行内で)
;; 後続する単語‘item’をハイライトする
("\\<anchor\\>" "\\<item\\>" nil nil (0 item-face))

ここではpre-formpost-formnilである。したがって‘item’にたいする検索は‘anchor’にたいするマッチの終端から開始されて、後続する‘anchor’インスタンスにたいする検索は‘item’にたいする検索が終了した位置から再開される。

(matcher highlighters…)

この種の要素は単一のmatcherにたいして複数のhighlighterリストを指定する。highlighterリストには、上述したsubexp-highlighteranchored-highlighterのいずれかを指定できる。

たとえば、

;; anchor-faceの値内に現れる単語‘anchor’、
;; および、(同じ行の)後続のitem-face
;;  値内に現れる単語‘item’をハイライトする
("\\<anchor\\>" (0 anchor-face)
                ("\\<item\\>" nil nil (0 item-face)))
(eval . form)

ここでformはバッファー内でこのfont-lock-keywordsの値が最初に使用されるときに評価される式である。この値は上述のテーブルで説明したいずれかの形式をもつこと。

警告: 複数行にわたるテキストにたいするマッチさせるために、font-lock-keywordsの要素をデザインしてはならない。これは確実に機能するとは言えない。詳細は複数行のFont Lock構造を参照のこと。

検索ベースのフォント表示がcaseを区別すべきかどうかを告げるfont-lock-keywords-case-fold-searchの値を指定するためにfont-lock-defaults内でcase-foldを使用できる。

Variable: font-lock-keywords-case-fold-search

nilfont-lock-keywordsのための正規表現マッチングがcaseを区別すべきではないことを意味する。


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

24.6.3 検索ベースのフォント化のカスタマイズ

メジャーモードにたいして検索ベースフォント表示ルールを追加するためにfont-lock-add-keywords、削除にはfont-lock-remove-keywordsを使用することができます。特定の条件にマッチするキーワードにたいして選択的にフォント表示を無効にするよう、font-lock-ignoreオプションをカスタマイズすることもできます。

Function: font-lock-add-keywords mode keywords &optional how

この関数はカレントバッファー、またはメジャーモードmodeにたいしてハイライトするkeywordsを追加する。引数keywordsは変数font-lock-keywordsと同じ形式のリストであること。

modeが、c-modeのようにメジャーモードのコマンド名であるようなシンボルなら、そのmode内でFont Lockモードを有効にすることによってkeywordsfont-lock-keywordsに追加される効果がある。非nil値のmodeによる呼び出しは~/.emacsファイル内でのみ正しい。

modenilなら、この関数はカレントバッファーのfont-lock-keywordskeywordsを追加する。この方法でのfont-lock-add-keywords呼び出しは通常はモードフック関数内で使用される。

デフォルトではkeywordsfont-lock-keywordsの先頭に追加される。オプション引数howsetなら、それらはfont-lock-keywordsの値の置換に使用される。howがそれ以外の非nil値なら、これらはfont-lock-keywordsの最後に追加される。

追加のハイライトパターンの使用を可能にする、特別なサポートを提供するモードがいくつかある。それらの例については変数c-font-lock-extra-typesc++-font-lock-extra-typesjava-font-lock-extra-typesを参照のこと。

警告: メジャーモードコマンドはモードフックを除き、いかなる状況においても直接間接を問わずfont-lock-add-keywordsを呼び出してはならない(これを行うといくつかのマイナーモードは不正な振る舞いを起こしかねない)。メジャーモードコマンドはfont-lock-keywordsをセットすることにより、検索ベースフォント表示のルールをセットアップすること。

Function: font-lock-remove-keywords mode keywords

この関数はカレントバッファーやメジャーモードmodeにたいして、font-lock-keywordsからkeywordsを削除する。font-lock-add-keywordsの場合と同様にmodeはメジャーモードコマンド名かnilであること。この関数にもfont-lock-add-keywordsにたいするすべての制約と条件が適用される。引数keywordsは対応するfont-lock-add-keywordsが使用するキーワードと正確に一致しなければならない。

たとえば以下はCモードに2つのフォント表示パターンを追加するコードの例である。フォント表示の1つはたとえコメント内であろうとも単語‘FIXME’をフォント表示し、もう1つは‘and’、‘or’、‘not’をキーワードとしてフォント表示する。

(font-lock-add-keywords 'c-mode
 '(("\\<\\(FIXME\\):" 1 font-lock-warning-face prepend)
   ("\\<\\(and\\|or\\|not\\)\\>" . font-lock-keyword-face)))

この例は厳密にCモードだけに効果がある。Cモード、およびその派生モードにたいして同じパターンを追加するには、かわりに以下を行う:

(add-hook 'c-mode-hook
 (lambda ()
  (font-lock-add-keywords nil
   '(("\\<\\(FIXME\\):" 1 font-lock-warning-face prepend)
     ("\\<\\(and\\|or\\|not\\)\\>" .
      font-lock-keyword-face)))))
User Option: font-lock-ignore

このオプションは特定のFont Lockキーワードによってフォント表示を選択的に無効にするための条件を定義する。非nilなら、値は以下のような形式の要素からなるリストであること:

(symbol condition …)

ここでsymbolはシンボル(通常はメジャーモードかマイナーモード)。symbolの後のリスト要素conditionsymbolがバインドされていて、なおかつ値が非nilなら効力をもつ。あるモードのシンボルについて考えると、カレントのメジャーモードがそのモードの派生モードであること、あるいはバッファーでそのマイナーモードが有効であることを意味する。conditionが効力をもつ間は要素font-lock-keywordsに因をなすすべてのフォント表示は、conditionがマッチした場合には無効化される。

conditionにはそれぞれ以下のいずれかを指定できる:

シンボル

この条件はそのシンボルを参照するFont Lockキーワード要素すべてにマッチする。通常はフェイスだが、font-lock-keywordsリストの要素によって参照される任意のシンボルを指定できる。シンボルにはワイルドカードを含めることができる。*はシンボルの名前に含まれる任意の文字列にマッチ、?は1文字にマッチ、そして[char-set] (char-setは1文字以上の文字列はその文字セットの1文字にマッチする。

文字列

この条件はmatcherが文字列にマッチするregexpであるようなFont Lockキーワード要素すべてにマッチする。言い換えると、これはその文字列をハイライトさせるようなFont Lockルールにマッチする条件である。したがってこの文字列に、ハイライトを無効にしたい特定のプログラムキーワードを指定できるかもしれない。

(pred function)

この条件は、その要素を引数としてfunctionを呼び出した際に非nilがリターンされるようなFont Lockキーワード要素すべてにマッチする。

(not condition)

これはconditionが成り立たなければマッチする。

(and condition …)

これはすべてのconditionがマッチすればマッチする。

(or condition …)

これは少なくとも1つのconditionがマッチすればマッチする。

(except condition)

この条件はトップレベルかor節内だけで使用できる。同一レベルにおいて前にマッチした条件の効果を取り消す。

セッティングの例として以下を考えてみましょう:

(setq font-lock-ignore
      '((prog-mode font-lock-*-face
                   (except help-echo))
        (emacs-lisp-mode (except ";;;###autoload)")
        (whitespace-mode whitespace-empty-at-bob-regexp)
        (makefile-mode (except *))))

これは1行ごとに以下のことを行っています:

  1. すべてのプログラミング用モードで、標準のfont-lockフェイスのいずれかを適用するようなfont-lockキーワードによるフォント表示を無効にする構文的なFont Lockが受けもつ文字列やコメントは除外)。
  2. ただしテキストプロパティhelp-echoに追加を行うキーワードはすべて保持。
  3. Emacs Lispモードでは最初の条件で除外され得るautoload cookieのハイライトは保持。
  4. whitespace-mode (マイナーモード)が有効なら、バッファー先頭の空行もハイライトさせない。
  5. 最後にMakefileモードでは条件を何も適用しない。

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

24.6.4 Font Lockのその他の変数

このセクションではfont-lock-defaults内のother-varsを用いて、メジャーモードがセットできる追加の変数について説明します(Font Lockの基礎を参照)。

Variable: font-lock-mark-block-function

この変数が非nilなら、それはコマンドM-x font-lock-fontify-blockで再フォント表示するテキスト範囲を選択するために引数なしで呼び出される関数であること。

この関数は結果を報告するために選択されたテキスト範囲にリージョンを配置すること。正しい結果を与えるのに十分、かつ再フォント表示が低速にならない程度のテキスト範囲がよい選択である。典型的な値はプログラミングのモードにたいしてはmark-defun、テキストを扱うモードにたいしてはmark-paragraph

Variable: font-lock-extra-managed-props

この変数は、(font-lock-face以外の)Font Lockにより管理される追加プロパティを指定する。これらの追加プロパティは通常はfont-lock-faceプロパティだけを管理する、font-lock-default-unfontify-regionにより使用される。他のプロパティも同様にFont Lockに管理させたければ、このリストに追加するのと同じようにfont-lock-keywords内のfacespec内でもこれらを指定しなければならない。検索ベースのフォント化を参照のこと。

Variable: font-lock-fontify-buffer-function

そのバッファーをフォント表示するために使用する関数。デフォルト値はfont-lock-default-fontify-buffer

Variable: font-lock-unfontify-buffer-function

そのバッファーを非フォント表示するために使用する関数。デフォルト値はfont-lock-default-unfontify-buffer

Variable: font-lock-fontify-region-function

リージョンをフォント表示するための関数。この関数はリージョンの開始と終了の2つを引数に受け取り、オプションで3つ目の引数verboseを受け取ること。verboseが非nilなら、その関数はステータスメッセージをプリントすべきである。デフォルト値はfont-lock-default-fontify-region

Variable: font-lock-unfontify-region-function

リージョンを非フォント表示するための関数。この関数はリージョンの開始と終了の2つを引数に受け取ること。デフォルト値はfont-lock-default-unfontify-region

Variable: font-lock-flush-function

リージョンのフォント表示の期限切れの宣言に使用する関数。そのリージョンの開始と終了という2つの引数を受け取る。この変数のデフォルト値はfont-lock-after-change-function

Variable: font-lock-ensure-function

カレントバッファーのリージョンのフォント表示の保証に使用する関数。そのリージョンの開始と終了という2つの引数を受け取る。この変数のデフォルト値は、バッファーがフォント表示されていないときにfont-lock-default-fontify-bufferを呼び出す関数。効果はそのバッファーのアクセス可能範囲全体がフォント表示されることの保証。

Function: jit-lock-register function &optional contextual

この関数はカレントバッファーの一部をフォント表示/非表示する必要がある任意のタイミングで、Font LockモードがLisp関数functionを実行することを宣言する。これはデフォルトのフォント表示関数が呼び出される前に、フォント表示/非表示するリージョンを指定する2つの引数startendfunctionを呼び出す。functionがフォント表示を行う場合には、フォント表示したリージョン領域を示すためにフォーム(jit-lock-bounds beg . end)のリストをリターンできる。後続する再表示サイクルおよび将来functionに渡されるバッファーテキストの最適化に、Just-In-Time(いわゆる“JIT”)なfont-lockがこの情報を使用するだろう。

オプション引数contextualが非nilなら、行が更新されたときに限らずそのバッファーの構文的に関連する部分を常にフォント表示するようFont Lockモードに強制する。この引数は通常は省略できる。

バッファーでFont Lockがアクティブのときには、もしfont-lock-keywords-only (構文的なFont Lockを参照)の値がnilなら、非nil値のcontextualでこの関数を呼び出す。

Function: jit-lock-unregister function

以前にjit-lock-registerを使用してフォント表示関数としてfunctionを登録した場合は、その関数を未登録にする。

Command: jit-lock-debug-mode &optional arg

これはJIT font-lockが実行するコードのデバッグを支援するためのマイナーモード。このモードが有効だと、(Lispエラーが抑制される)再表示サイクル中にJIT font-lockが実行する通常のコードのほとんどがタイマーによって実行される。したがってこのモードではfont-lockやJIT font-lockが実行するその他のコード内の問題を見つけて訂正するために、debug-on-error (エラーによるデバッガへのエンターを参照)やEdebug (Edebugを参照)のようなデバッグ支援機能を使用することができる。


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

24.6.5 Font Lockのレベル

フォント表示にたいして3つの異なるレベルを提供するモードがいくつかあります。font-lock-defaults内のkeywordsにたいしてシンボルのリストを使用することにより複数のレベルを定義できます。このリストのシンボルはそれぞれフォント表示の1レベルを指定します。これらのレベルの選択は、通常はfont-lock-maximum-decorationをセットすることによりユーザーの責任で行われます(Font Lock in the GNU Emacs Manualを参照)。選択されたレベルのシンボルの値はfont-lock-keywordsの初期化に使用されます。

フォント表示レベルの定義方法に関する慣習を以下に挙げます:

  • レベル1: 関数宣言、(includeやimportのような)ファイルディレクティブ、文字列、コメントをハイライトする。これは、もっとも重要かつトップレベルのコンポーネントだけをフォント表示すれば高速になるという発想である。
  • レベル2: レベル1に加えて、すべての言語のキーワード(キーワードと同様に作用する型名を含む)、および名前付き定数値をハイライトする。これは、(構文的、または意味的な)すべてのキーワードは適切にフォント表示されるべきという発想である。
  • レベル3: レベル2に加えて、関数内で定義されるシンボル、変数宣言、およびすべてのビルトイン関数名にたいして、それがどこに出現しようとハイライトする。

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

24.6.6 事前計算されたフォント化

list-buffersoccurのようないくつかのメジャーモードは、バッファーのテキストをプログラム的に構築します。これらにたいしてFont Lockモードをサポートするためには、そのバッファーにテキストを挿入するタイミングでテキストのフェイスを指定するのがもっとも簡単な方法です。

これはスペシャルテキストプロパティfont-lock-face (特殊な意味をもつプロパティを参照)により、テキスト内にフェイスを指定することによって行われます。Font Lockモードが有効になったとき、このプロパティはfaceと同じように表示を制御します。Font Lockモードが無効になるとfont-lock-faceは表示に効果をもちません。

何らかのテキストにたいしてfont-lock-faceを使用するモードや、通常のFont Lock機構を使用するモードでも問題はありません。しかし通常のFont Lock機構を使用しないモードでは、変数font-lock-defaultsをセットするべきではありません。この場合にはfaceプロパティはオーバーライドされないので、faceプロパティの使用も機能します。しかしfont-lock-modeの切り替えによりユーザーがフォント化を制御でき、かつモードのFont Lock機構の使用の有無に関わらずコードが機能するので、一般的にはfont-lock-faceの使用の方が優っています。


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

24.6.7 Font Lockのためのフェイス

Font Lockモードはハイライトに任意のフェイスを使用できますが、Emacsは特にFontLockがテキストのハイライトに使用するいくつかのフェイスを定義しています。これらのFont Lockフェイス(Font Lock faces)を以下にリストします。これらのフェイスはFontLockモードの外部における構文的なハイライトでメジャーモードが使用することもできます(メジャーモードの慣習を参照)。

以下の各シンボルはフェイス名であり、かつデフォルト値がシンボル自身であるような変数でもあります。つまりfont-lock-comment-faceのデフォルト値はfont-lock-comment-faceです。

リストはそのフェイスの典型的な使い方の説明とともに、重要度が高い順にソートされています。あるモードの構文的カテゴリーが以下の使い方の記述にうまく適合しない場合には、この並び順をガイドとして使用することによってフェイスを割り当てることができるでしょう。

font-lock-warning-face

特有な構文(たとえば‘‘foo’のようにEmacs Lispシンボルにおけるエスケープされていない判りにくいクォート)や、Emacs Lispの‘;;;###autoload’、Cの‘#error’のような他のテキストの意味を大きく変更する構文にたいして使用される。

font-lock-function-name-face

定義、または宣言される関数の名前にたいして使用される。

font-lock-function-call-face

呼び出される関数の名前にたいして使用される。このフェイスはデフォルトではfont-lock-function-name-faceを継承する。

font-lock-variable-name-face

定義、または宣言される変数の名前にたいして使用される。

font-lock-variable-use-face

参照される変数の名前にたいして使用される。このフェイスはデフォルトではfont-lock-variable-name-faceを継承する。

font-lock-keyword-face

Cの‘for’や‘if’のように、構文的に特別な意味をもつキーワードにたいして使用される。

font-lock-comment-face

コメントにたいして使用される。

font-lock-comment-delimiter-face

Cの‘/*’と‘*/’のようなコメント区切りにたいして使用される。ほとんどの端末ではこのフェイスはfont-lock-comment-faceを継承する。

font-lock-type-face

ユーザー定義データ型にたいして使用される。

font-lock-constant-face

Cの‘NULL’のような定数の名前にたいして使用される。

font-lock-builtin-face

ビルトイン関数の名前にたいして使用される。

font-lock-preprocessor-face

プロセッサーコマンドにたいして使用される。デフォルトでは、font-lock-builtin-faceを継承する。

font-lock-string-face

文字列定数にたいして使用される。

font-lock-doc-face

特別な形式のコメントや文字列内のプログラムコード内に埋め込まれたドキュメントにたいして使用される。デフォルトではfont-lock-string-faceを継承する。

font-lock-doc-markup-face

font-lock-doc-faceを使用するテキスト内のmark-up要素にたいして使用される。これは通常はHaddock、Javadoc、Doxygenなどの慣例にしたがってプログラムコード内に埋め込まれた、ドキュメント内のマークアップ構文にたいして使用される。このフェイスは、デフォルトではfont-lock-constant-faceを継承する。

font-lock-negation-char-face

見逃しやすい否定文字にたいして使用される。

font-lock-escape-face

文字列内のエスケープシーケンスにたいして使用される。このフェイスはデフォルトではfont-lock-regexp-grouping-backslashを継承する。

以下はPythonでエスケープシーケンス\nが使用されている例:

print('Hello world!\n')
font-lock-number-face

数値にたいして。

font-lock-operator-face

演算子にたいして。

font-lock-property-name-face

構造体におけるフィールド定義のようなオブジェクトのプロパティにたいして使用される。このフェイスはデフォルトではfont-lock-variable-name-faceを継承する。

font-lock-property-use-face

構造体のフィールドの使用のように、オブジェクトのプロパティにたいして使用される。このフェイスはデフォルトではfont-lock-property-name-faceを継承する。

たとえば、

typedef struct
{
  int prop;
//    ^ property
} obj;

int main()
{
  obj o;
  o.prop = 3;
//  ^ property
}
font-lock-punctuation-face

カッコや区切り文字などの句読点文字。

font-lock-bracket-face

カッコ(()[]{})にたいして使用される。このフェイスはデフォルトではfont-lock-punctuation-faceを継承する。

font-lock-delimiter-face

区切り文字(;:,)にたいして使用される。このフェイスはデフォルトではfont-lock-punctuation-faceを継承する。

font-lock-misc-punctuation-face

カッコや区切り文字以外の句読点文字にたいして使用される。このフェイスはデフォルトではfont-lock-builtin-faceを継承する。


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

24.6.8 構文的なFont Lock

構文的フォント表示(syntactic fontification)は、構文的に関連性のあるテキストを探してハイライトするために構文テーブル(syntax table: 構文テーブルを参照)を使用します。有効な場合には検索ベースのフォント表示に先立って実行されます。以下で説明する変数font-lock-syntactic-face-functionはどの構文的構造をハイライトするかを決定します。構文的フォント表示に影響を与える変数がいくつかあります。font-lock-defaultsのためにそれらをセットするべきです(Font Lockの基礎を参照)。

Font Lockモードが一連のテキストにたいして構文的フォント表示を処理するときは、常にsyntax-propertize-functionで指定される関数を最初に呼び出します。メジャーモードは特別なケースではsyntax-tableテキストプロパティを適用してバッファーの構文テーブルをオーバーライドするために、これを使用することができます。構文プロパティを参照してください。

Variable: font-lock-keywords-only

この変数の値が非nilなら、Font Lockは構文的フォント表示を行わずにfont-lock-keywordsにもとづく検索ベースのフォント表示だけを行う。これは通常はfont-lock-defaults内のkeywords-only要素にもとづいてFont Lockモードによりセットされる。値がnilならFont Lockはjit-lock-register (Font Lockのその他の変数を参照)を呼び出して、変更行以降のバッファーテキストに変更による新たな構文コンテキストを反映するために、自動的な再フォント表示をセットアップする。

構文的なフォント表示だけを使用するにはこの変数に非nil、そしてfont-lock-keywordsnilをセットする必要がある(Font Lockの基礎を参照)。

Variable: font-lock-syntax-table

この変数はコメントと文字列のフォント表示に使用するための構文テーブルを保持する。これは通常はfont-lock-defaults内のsyntax-alist要素にもとづいてFont Lockモードによりセットされる。この値がnilなら、構文的フォント表示はバッファーの構文テーブル(関数syntax-tableがリターンする構文テーブル。構文テーブルの関数を参照)を使用する。

Variable: font-lock-syntactic-face-function

この変数が非nilなら、それは与えられた構文的要素(文字列かコメント)にどのフェイスを使用するかを決定する関数であること。

この関数は1つの引数で呼び出され、parse-partial-sexpがリターンするポイントの状態をパースしてフェイスをリターンすること。リターンされるデフォルト値はコメントにたいしてはfont-lock-comment-face、文字列にたいしてはfont-lock-string-face (Font Lockのためのフェイスを参照)。

この変数は通常はfont-lock-defaults内の“他”の要素を通じてセットされる:

(setq-local font-lock-defaults
            `(,python-font-lock-keywords
              nil nil nil nil
              (font-lock-syntactic-face-function
               . python-font-lock-syntactic-face-function)))

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

24.6.9 複数行のFont Lock構造

font-lock-keywordsの要素は、通常は複数行にわたるマッチを行うべきではありません。それらの動作に信頼性はありません。なぜならFont Lockは通常はバッファーのごく一部をスキャンするので、そのスキャンが開始される行境界をまたがる複数行構造を見逃しかねないからです(スキャンは通常は行頭から開始される)。

ある要素にたいして複数行構造にたいするマッチを正しく機能させるために2つの観点があります。それは識別(identification)の補正と、再ハイライト(rehighlighting)の補正です。1つ目はFont Lockがすべての複数行構造を探すことを意味します。2つ目は複数行構造が変更されたとき、たとえば以前は複数行構造の一部だったテキストが複数行構造から除外されたときに、関連するすべてのテキストをFont Lockに正しく再ハイライトさせることを意味します。これら2つの観点は密接に関連しており、一方を機能させることがもう一方を機能させるようなことが多々あります。しかし信頼性のある結果を得るためには、これら2つの観点双方にたいして明示的に注意しなければなりません。

複数行構造の識別を確実に補正するには3つの方法があります:

  • スキャンされるテキストが複数行構造の途中で開始や終了することがないように識別を行ってスキャンを拡張する関数をfont-lock-extend-region-functionsに追加する。
  • 同様に、スキャンされるテキストが複数行構造の途中で開始や終了することがないようスキャンを拡張するために、font-lock-fontify-region-functionフックを使用する。
  • 複数行構造がバッファーに挿入されたとき(または挿入後にFont Lockがハイライトを試みる前の任意のタイミングで)、何らかの方法によりそれを正しく認識して、Font Lockが複数行構造の途中で開始や終了しないように指示するfont-lock-multilineでそれをマークする。

複数行構造の再ハイライトを行うにはいくつかの方法があります:

  • その構造にたいして正しくfont-lock-multilineを配置する。これによりその構造の一部が変更されると構造全体が再ハイライトされるだろう。あるケースにおいてはそれを参照するfont-lock-multiline変数をセットすることにより自動的にこれを行うことができる。
  • jit-lock-contextuallyを確実にセットしてそれが行う処理に委ねる。これにより、実際の変更に続いて構造の一部だけが若干の遅延の後に再ハイライトされるだろう。これは複数行構造のさまざまな箇所のハイライトが後続行のテキストに依存しない場合のみ機能する。jit-lock-contextuallyはデフォルトでアクティブなので、これは魅力的な解決策になり得る。
  • その構造上に正しくjit-lock-defer-multilineを配置する。これはjit-lock-contextuallyが使用された場合のみ機能し、再ハイライト前に同様の遅延を伴うが、font-lock-multilineのように後続行に依存する箇所のハイライトも処理する。
  • 構造(construct)の構文(syntax)のパースが単一のchunkでパースされることに依存している場合には、問題となっている構造にテキストプロパティsyntax-multilineを追加できる。これのもっとも一般的な用途は、‘FOO’に適用する構文プロパティ(syntax property)が後出するテキスト‘BAR’に依存する場合である。このテキストプロパティを‘FOO...BAR’全体に配置することによって、‘BAR’にたいする任意の変更が‘FOO’の構文プロパティに影響を与えて再計算されることが保証される。これが機能するためには、モードがsyntax-propertize-extend-region-functionssyntax-propertize-multilineを追加する必要があることに注意。

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

24.6.9.1 複数行のFont Lock

複数行構造のFont Lockを確実に再ハイライトする方法の1つは、それらをテキストプロパティfont-lock-multilineにputする方法です。複数行構造の一部であるようなテキストには値が非nilであるようなこのプロパティが存在するべきです。

Font Lockがテキスト範囲をハイライトしようとする際は、まずそれらがfont-lock-multilineプロパティでマークされたテキストにならないように必要に応じて範囲の境界を拡張します。それからその範囲のすべてのfont-lock-multilineを削除してハイライトします。ハイライト指定(大抵はfont-lock-keywords)は、適宜このプロパティを毎回再インストールしなければなりません。

警告: ハイライトが低速になるので大きなテキスト範囲にたいしてfont-lock-multilineを使用してはならない。

Variable: font-lock-multiline

font-lock-multiline変数がtにセットされているとFont Lockは自動的に複数行構造にたいしてfont-lock-multilineプロパティの追加を試みる。しかしこれによりFont Lockが幾分遅くなるので普遍的解決策ではない。これは何らかの複数行構造を見逃したり、必要なものより多く、または少なくプロパティをセットするかもしれない。

matcherが関数であるような要素は、たとえ少量のサブパート(subpart)だけがハイライトされるような場合でも、submatch 0(訳注:正規表現の後方参照においてsubmatch 0はマッチした文字列全体を指す)が関連する複数行構造全体を確実に網羅するようにすべきである。単に手動でfont-lock-multilineを追加するのが容易な場合も多々ある。

font-lock-multilineプロパティは正しい再フォント表示を確実に行うことを意図しています。これは新たな複数行構造を自動的に認識しません。それらを認識するためにはFont Lockが一度に十分な大きさのchunkを処理することを要求します。これは多くの場合にアクシデントにより発生し得るかもしれないので、複数行構造が不可解に機能するような印象を与えるかもしれません。変数font-lock-multilineを非nilにセットした場合には、発見されたこれらの構造にたいするハイライトは変数をセットした後は正しく更新されるので、さらにこの印象が強くなるでしょう。しかしこれは信頼性をもって機能しません。

信頼性を保ち複数行構造を見つけるためには、Font Lockが調べる前にテキストのfont-lock-multilineプロパティを手動で配置するか、font-lock-fontify-region-functionを使用しなければなりません。


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

24.6.9.2 バッファー変更後のリージョンのフォント化

バッファーが変更されたときFont Lockが再フォント表示するリージョンは、デフォルトではその変更に関連する最小の行全体からなるシーケンスです。これはほとんどの場合は良好に機能しますが、うまく機能しないとき(たとえば変更がそれより前の行のテキストの構文的な意味を変更してしまうとき)もあります。

以下の変数をセットすることにより、再フォント表示するリージョンを拡張(または縮小さえ)することができます:

Variable: font-lock-extend-after-change-region-function

このバッファーローカル変数はnil、またはFont Lockモードにたいしてスキャンしてフォント表示すべきリージョンを決定するために呼び出される関数である。

この関数には標準的なbegend、およびafter-change-functionsold-len (フックの変更を参照)という3つのパラメーターが渡される。この関数はフォント表示するリージョンのバッファー位置の開始と終了(この順)からなるコンスセル、またはnil (標準的な方法でリージョンを選択することを意味する)のいずれかをリターンすること。この関数はポイント位置、match-data、カレントのナローイングを保つ必要がある。これがリターンするリージョンは、行の途中で開始や終了するかもしれない。

この関数はバッファーを変更するたびに呼び出されるので有意に高速であること。


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

24.6.10 パーサーベースのFont Lock

シンプルな構文的Font LockやregexpベースのFont Lockに加えて、Emacsはパーサーを用いた完全な構文的Font Lockも提供します。Emacsでは現在のところは、この目的のためにtree-sitterライブラリーを使用しています(プログラムソースの解析を参照)。

パーサーベースのFont Lockそれ以外のFont Lockのメカニズムは互いに排他ではありません。もしパーサーベースのFont Lockが有効なら、最初に構文的Font Lock置き換わり実行されて、その後にregexpベースのFont Lockが実行されます。

パーサーベースのFont LockがregexpベースのFont Lockと同じカスタマイズ変数を共有しないとしても、カスタマイズでは類似したスキームを使用します。tree-sitterにおいてfont-lock-keywordsのカウンターパートとなるのがtreesit-font-lock-settingsです。

tree-sitterのフォント表示は一般的には以下のように機能します:

  • Lispプログラム(通常はメジャーモードの一部)がパターン(pattern)から構成されるqueryを提供する。ここでパターンはそれぞれキャプチャ名(capture name)に関連付けられている。
  • tree-sitterライブラリーがこれらのパターンにマッチするパースツリー(parse tree: 解析木)からノードを探して、そのノードに対応するキャプチャ名でタグ付けして、それらをLispプログラムにリターンする。
  • Lispプログラムはリターンされたノードを用いて、それぞれのノードに対応するバッファーのテキスト部分にたいして、ノードにタグ付けされたキャプチャ名から正しいフォント表示を決定して適切にハイライトする。たとえばfont-lock-keywordとタグ付けされたノードなら、font-lock-keywordフェイスによってハイライトされることになるだろう。

クエリー、パターン、キャプチャ名n関する詳細についてはtree-sitterノードにたいするパターンマッチングを参照してください。

tree-sitterのフォント表示をセットアップするためには、まずメジャーモードがtreesit-font-lock-rulesの出力をtreesit-font-lock-settingsにセットしてからtreesit-major-mode-setupを呼び出す必要があります。

Function: treesit-font-lock-rules &rest query-specs

これはtreesit-font-lock-settingsのセットに使用される関数である。この関数はクエリーのコンパイルやその他の後処理を受けもち、treesit-font-lock-settingsが受け入れる値を出力する。以下は例:

(treesit-font-lock-rules
 :language 'javascript
 :feature 'constant
 :override t
 '((true) @font-lock-constant-face
   (false) @font-lock-constant-face)
 :language 'html
 :feature 'script
 "(script_element) @font-lock-builtin-face")

この関数は一連のquery-spec (query-specとは1つ以上のkeyword/valueが前置されたqueryのこと)を受け取る。queryとはそれぞれ文字列、S式、あるいはコンパイル済みフォームのいずれかによるtree-sitterクエリーのこと。

queryそれぞれの前にはクエリーにメタ情報を付加するkeyword/valueペアーが前置される。キーワード:languagequeryの言語を宣言、キーワード:featurequeryのfeature名をセットする。ユーザーhtreesit-font-lock-leveltreesit-font-lock-feature-listによって、どのfeatureを有効にするかを制御できる(後述)。いずれのキーワードも必須。

その他のキーワードはオプションである:

キーワード意味
:overridenilそのリージョンにすでにフェイスがセットされていれば新たなフェイスを破棄
t常に新たなフェイスを適用する
append既存フェイスの後に新たなフェイスを追加
prepend既存フェイスの前に新たなフェイスを追加
keep既存フェイスなしでリージョンをフィルする

Lispプログラムはquery内のパターンをキャプチャ名(@で始まる名前)でマークする。そしてtree-sitterは同じキャプチャ名でタグ付けされたノードをリターンする。フォント表示という目的のために、queryのキャプチャ名はfont-lock-keyword-faceのようなフェイス名であること。キャプチャされたノードはそのフェイスによってフォント表示されることになる。

キャプチャ名は関数でもよい。この場合にはnode and overridestartendという4つの引数で呼び出される関数であること。ここでnodeはそのノード自身、overrideはそのノードにキャプチャされたルールの:overrideプロパティ、startendはこの関数がフォント表示するべきリージョンを制限する(この関数がoverrideを尊重したければtreesit-fontify-with-overrideを使用できる)。

機能拡張を可能にするために、その関数は5つ以上の引数が与えられた場合にはそれらをオプションの引数として受け入れる必要がある。

キャプチャ名がフェイスと関数のどちらにも当てはまる場合にはフェイスが優先される。フェイスにも関数にも当てはまらないキャプチャ名は無視される。

Variable: treesit-font-lock-feature-list

これはfeatureシンボル(feature symbol: 機能シンボル)のリストのリスト。このリストの要素はそれぞれ装飾レベルを表すためのリストである。どのレベルをアクティブにするかを制御するのがtreesit-font-lock-level

リストの要素はそれぞれ(feature …)という形式のリスト。ここでfeatureはそれぞれtreesit-font-lock-rules内で定義されるクエリーで対応する:featureの値。このリストからfeatureシンボルを削除することによって、font-lockの間に対応するクエリーが無効なる。

多くのプログラミング言語にとって一般的なfeature名にはdefinitiontypeassignmentbuiltinconstantkeywordstring-interpolationcommentdocstringoperatorpreprocessorescape-sequencekeyが含まれる。メジャーモードはこれらの一般的なfeatureを自由に分割あるいは拡張ができる。

これらのfeatureのうちいくつかは説明が必要だろう。definitionは何であれ定義されつつあるものをハイライトする(関数定義の関数名、構造体定義構造体名、変数定義の変数など)。assignmentは何であれ割り当てされつつあるものをハイライトする(割り当て命令の変数やフィールドなど)。keyはキー/値ペアーのキーをハイライトする(JSONオブジェクトのキーやPythonのdictionaryなど)。docはdoc文字列やdocコメントをハイライトする。

この変数の値はたとえば以下のようになるかもしれない:

((comment string doc) ; level 1
 (function-name keyword type builtin constant) ; level 2
 (variable-name string-interpolation key)) ; level 3

メジャーモードはtreesit-major-mode-setupの呼び出し前にこの変数をセットすること。

この変数が効力をもつためには、Lispプログラムが(適宜treesit-font-lock-settingsをリセットする)treesit-font-lock-recompute-features、または(treesit-font-lock-recompute-featuresを呼び出す)treesit-major-mode-setupを呼び出す必要がある。

Variable: treesit-font-lock-settings

tree-sitterベースのfont lock用のセッティングのリスト。セッティングそれぞれの正確なフォーマットは内部的なフォーマットとみなされる。この変数のセットには、常にtreesit-font-lock-rulesを使うこと。

複数言語用のメジャーモードはtreesit-range-functionsでrange関数(range function: 範囲関数)を提供する必要があり、Emacsはリージョンのフォント表示を行う前にrangeを適宜セットします(複数言語ののパースを参照)。


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

24.7 コードの自動インデント

プログラミング言語のメジャーモードにとって、自動的なインデントの提供は重要な機能です。これには2つのパートがあります。1つ目は正しい行のインデントが何か、そして2つ目はいつ行を再インデントするかの判断です。デフォルトではelectric-indent-charsに含まれる文字(デフォルトでは改行のみ)をタイプしたとき、Emacsは常に行を再インデントします。メジャーモードはその言語の構文に合わせてelectric-indent-charsに文字を追加できます。

正しいインデントの決定はindent-line-functionによりEmacs内で制御されます(メジャーモードが制御するインデントを参照)。いくつかのモードではへのインデントは信頼性がないことが知られています。これは通常は複数のインデントが有効であり、それぞれが異なる意味をもつのでインデント自体が重要だからです。そのような場合には、そのモードは行が常にユーザーの意に反して行が毎回再インデントされないことを保証するためにelectric-indent-inhibitをセットするべきです。

よいインデント関数の記述は難しく、その広範な領域において未だ黒魔術の域を脱していません。メジャーモード作者の多くは、単純なケース(たとえば前のテキスト行のインデントとの比較)にたいして機能する、単純な関数の記述からスタートすることでしょう。実際には行ベースではないほとんどのプログラミング言語にたいして、これは貧弱なスケールになりがちです。そのような関数にたいして、より多様な状況を処理するような改良を行うと関数はより一層複雑になり、最終的な結果は誰にも触れようとする気を起こさせない、巨大で複雑な保守不可能のインデント関数になる傾向があります。

よいインデント関数は、通常はその言語の構文に応じて実際にテキストをパースする必要があるでしょう。幸運なことにこのテキストパースはコンパイラーが要するほど詳細である必要はないでしょうが、その一方でインデントコードに埋め込まれたパーサーは構文的に不正なコードにたいして、コンパイラーより幾分寛容な振る舞いを求められるでしょう。

保守可能なよいインデント関数は、通常は2つのカテゴリーに落ち着きます。どちらも何らかの安全な開始ポイントから、関心のある位置まで前方か後方へパースを行います。この2つの方法は、いずれも一方が他方に明快に優る選択ではありません。後方へのパースはプログラミング言語が前方にパースされるようデザインされているため、前方へのパースに比べて難しいことが多々ありますが、インデントという目的においては安全な開始ポイントを推測する必要がないという利点があり、一般的にある行のインデントの判断のために分析を要するのは最小限のテキストだけという特性に恵まれているので、前の無関係なコード片内にある何らかの構文エラーの影響をインデントが受けにくくなる傾向があります。一方で前方へのパースは通常はより簡単であり、一度のパースでリージョン全体を効果的に再インデントすることが可能になるという利点があります。

インデント関数をスクラッチから記述するよりも、既存のインデント関数の使用と再利用、または一般的なインデントエンジンに委ねるほうが優る場合がしばしばあります。しかしそのようなエンジンは悲しむべきほど少数しかありません。(C、C++、Java、Awk、およびその類のモードに使用される)CCモードのインデントコードは年月を経てより一般化されてきているので、あなたの言語にこれらの言語と何らかの類似点があるなら、このエンジンの使用を試みるかもしれません。もう一方のSMIEはLispのsexp精神によるアプローチを採用して、それを非Lisp言語に適応します。他にもたとえばtree-sitterライブラリーのような本格的なパーサーに頼る方法もあります。


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

24.7.1 SMIE: 無邪気なインデントエンジン

SMIEは一般的な操作とインデントを提供するエンジンです。これは演算子順位文法(operator precedence grammar)を使用する非常にシンプルなパーサーにもとづいたエンジンであり、メジャーモードがLispのS式ベースの操作を非Lisp言語に拡張するのを助けるとともにシンプルに使用できるにも関わらず、信頼できる自動インデントを提供します。

演算子順位文法はコンパイラー内で使用されるより一般的なパーサーと比較すると非常に原始的なパーステクノロジーです。このパーサーには次のような特徴があります。このパーサーのパース能力は非常に限定的で構文エラーを大概は検出できません。しかしアルゴリズム的に前方パースと同様に後方パースを効果的に行うことが可能です。実際にそれはSMIEが後方パースにもとづくインデントを使用でき、forward-sexpbackward-sexpの両方の機能を提供できるとともに、特別な努力を要さずに構文的に不正なコードにたいして自然に機能するであろうことを意味します。欠点はほとんどのプログラミング言語は、少なくとも何らかの特別なトリック(非力なパーサーと歩むを参照)で再分類しなければSMIEを使用して正しくパースできないことをも意味することです。


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

24.7.1.1 SMIEのセットアップと機能

SMIEは構造的な操作とコードの構造的構造にもとづくその他さまざまな機能、特に自動インデントにたいするワンストップショップ(一カ所で必要な全ての買い物ができる店やそのような場所)であることを意図しています。メインのエントリーポイントはsmie-setupで、これは通常はメジャーモードセットアップの間に呼び出される関数です。

Function: smie-setup grammar rules-function &rest keywords

SMIEの操作とインデントをセットアップする。grammarsmie-prec2->grammarにより生成される文法テーブル(grammar table)、rules-functionsmie-rules-functionで使用されるインデントルールのセット、keywordsは追加の引数であり以下のキーワードを含むことができる:

  • :forward-token fun: 使用する前方lexer(lexer=lexical analyzer: 字句解析プログラム)を指定する。
  • :backward-token fun: 使用する後方lexerを指定する。

この関数を呼び出せばforward-sexpbackward-sexptranspose-sexpsのようなコマンドが、すでに構文テーブルにより処理されている単なるカッコのペア以外の、構造的な要素を正しく扱うことができるようになります。たとえば与えられた文法が十分に明快ならば、transpose-sexpsはその言語の優先順位のルールを考慮して+演算子の2つの引数を正しく入れ替えることができます。

smie-setupの呼び出しはbegin...endのような要素に適用するためにblink-matching-parenを拡張してTABによるインデントを期待通り機能させるとともに、メジャーモードのキーマップ内でバインドできるいくつかのコマンドの提供を満足します。

Command: smie-close-block

このコマンドは、もっとも最近オープンされた(まだクローズされていない)ブロックをクローズする。

Command: smie-down-list &optional arg

このコマンドはdown-listと似ているが、begin...endのようなカッコ以外のネストされたトークンにも注意を払う。


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

24.7.1.2 演算子順位文法

SMIEの演算子順位文法は、各トークンにたいしてシンプルに左優先(left-precedence)と右優先(right-precedence)という順位ペアを与えます。トークンT1の右優先がトークンT2の左優先より小さければT1 < T2であると言うことにしましょう。これを解読するには<をカッコの一種だとみなすのがよい方法です。... T1 something T2 ...を見つけたら、これは... T1 something) T2 ...ではなく... T1 (something T2 ...とパースされるべきです。... T1 something) T2 ...と解釈するのはT1 > T2を見つけた場合でしょう。T1 = T2を見つけた場合、それはトークンT2とその後のトークンT1が同じ構文にあり、通常は"begin" = "end"を得ます。このような優先順位のペアは2項演算子(infix operator)、カッコのようなネストされたトークン、およびその他多くのケースにたいして左結合(left-associativity)や右結合(right-associativity)を表現するのに十分です。

Function: smie-prec2->grammar table

この関数はprec2文法tableを引数に受け取り、smie-setupで使用するのに適したalistをリターンする。prec2文法tableは、それ自体が以下の関数のいずれかによりビルドされることを意図している。

Function: smie-merge-prec2s &rest tables

この関数は複数のprec2文法tablesを、新たなprec2テーブルにマージする。

Function: smie-precs->prec2 precs

この関数は順位テーブルprecsからprec2テーブルをビルドする。precsは優先順(たとえば"+""*"より前にくる)にソートされたリストであり、要素は(assoc op ...)の形式であること。ここでopは演算子として振る舞うトークン、assocはそれらの結合法則でありleftrightassocnonassocのいずれかである。与えられた要素内のすべての演算子は同じ優先レベルと結合法則を共有する。

Function: smie-bnf->prec2 bnf &rest resolvers

この関数によりBNF記法を使用した文法を指定することができる。これはその文法のbnf表記と、同様に競合解決ルールresolversを受け取ってprec2テーブルをリターンする。

bnf(nonterm rhs1 rhs2 ...)という形式の非終端定義、各rhsは終端記号(トークンとも呼ばれる)、または非終端記号の(空でない)リストである。

すべての文法が許容される訳ではない:

  • rhsに空のリストは指定できない(いずれにせよSMIEは空文字列にマッチさせるためにすべての非終端記号を許容するので空リストが必要になることは決してない)。
  • rhsの後に連続する2つの非終端記号は指定できない。非終端記号の各ペアは終端記号(かトークン)で区切られる必要がある。これは演算子順位文法の基本的な制約である。

さらに競合が発生し得る:

  • リターンされるprec2テーブルはトークンのペア間の制約を保持し、与えられた任意のペアはT1 < T2、T1 = T2、T1 > T2のいずれかのうち1つの制約をだけ与えることができる。
  • トークンはopener(開カッコに似た何か)、closer(閉カッコのようなもの)、またはこれら2つのいずれでもないneither(2項演算子や"else"のようなinnerトークン)である。

順位の競合はresolversを通じて解決され得る。これはprecsテーブル(smie-precs->prec2を参照)のリストである。それぞれの順位競合にたいして、これらのprecsテーブルが特定の制約を指定している場合は、かわりにこの制約により競合が解決され、それ以外は競合する制約のうち任意の1つが報告されて他は単に無視される。


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

24.7.1.3 言語の文法の定義

ある言語にたいしてSMIE文法を定義する通常の方法は、順位のテーブルを保持する新たなグローバル変数を定義してBNFルールのセットを与える方法です。たとえば小規模なPascal風言語の文法定義は以下のようになるでしょう:

(require 'smie)
(defvar sample-smie-grammar
  (smie-prec2->grammar
   (smie-bnf->prec2
    '((id)
      (inst ("begin" insts "end")
            ("if" exp "then" inst "else" inst)
            (id ":=" exp)
            (exp))
      (insts (insts ";" insts) (inst))
      (exp (exp "+" exp)
           (exp "*" exp)
           ("(" exps ")"))
      (exps (exps "," exps) (exp)))
    '((assoc ";"))
    '((assoc ","))
    '((assoc "+") (assoc "*")))))

注意すべき点がいくつかあります:

  • 上記の文法は関数呼び出しの構文に明示的に言及していない。SMIEは識別子、対応がとれたカッコ(balanced parentheses)、またはbegin ... endブロックのようなsexpの任意のシーケンスがどこに、どのように出現しても自動的にそれを許容するだろう。
  • 文法カテゴリーidは右側に何ももたない。これはidが空文字列だけにマッチ可能なことを意味しない。なぜなら上述のように任意のsexpシーケンスはどこに、どのような方法でも出現するからである。
  • BNF文法では非終端記号が連続して出現し得ないので、終端記号として作用するトークンを正しく扱うのが困難なため、上述の文法ではSMIEが容易に扱える";"セパレーター(separator)ステートメントのかわりとして扱っている。
  • シーケンス内で使用される、(上記の","";"のような)セパレーターは、BNFルールでは(foo (foo "separator" foo) ...)のように定義するのが最善である。これは順位の競合を生成するが、明示的に(assoc "separator")を与えることにより解決される、
  • SMIEは構文テーブル(syntax table)内でカッコ構文(paren syntax)をもつようにマークされた任意の文字をペアにするだろうから、("(" exps ")")ルールにカッコをペアにする必要はなかった。(expsの定義と併せて)これはかわりに","がカッコの外に出現すべきではないことを明確にするためのルール。
  • 競合解決のためのprecsテーブルは単一のテーブルより複数のテーブルをもつほうが、可能な場合は文法のBNF部分が関連する順位を指定できるので優れている。
  • leftrightを選択することが優るという明白な理由がなければ、通常はassocを使用して演算子を結合演算子(associative)とマークするほうが優れている。この理由により上述の"+""*"は、たとえその言語がそれらを形式上は左結合(left associative)と定義していてもassocとして定義されている。

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

24.7.1.4 トークンの定義

SMIEには事前定義された字句解析プログラムが付属しており、それは次の方法で構文テーブルを使用します: 文字の任意のシーケンスはトークンとみなせる単語構文(word syntax)かシンボル構文(symbol syntax)をもち、区切り文字構文(punctuation syntax)をもつ任意の文字シーケンスもトークンとみなされます。このデフォルトのlexerは開始ポイントとして適している場合が多々ありますが、任意の与えられた言語にたいして実際に正しいことは稀です。たとえばこれは"2,+3"が3つのトークン"2"",+""3"から構成されていると判断するでしょう。

あなたの言語のlexerルールをSMIEにたいして説明するためには、次のトークンをfetchする関数と前のトークンをfetchする関数という2つの関数が必要になります。これらの関数は通常は最初に空白文字とコメントをスキップして、その後に次のテキストchunk(塊)を調べてそれが特別なトークンか確認します。これは通常は単にバッファーから抽出された文字列ですが、あなたが望む他の何かでも構いません。たとえば:

(defvar sample-keywords-regexp
  (regexp-opt '("+" "*" "," ";" ">" ">=" "<" "<=" ":=" "=")))
(defun sample-smie-forward-token ()
  (forward-comment (point-max))
  (cond
   ((looking-at sample-keywords-regexp)
    (goto-char (match-end 0))
    (match-string-no-properties 0))
   (t (buffer-substring-no-properties
       (point)
       (progn (skip-syntax-forward "w_")
              (point))))))
(defun sample-smie-backward-token ()
  (forward-comment (- (point)))
  (cond
   ((looking-back sample-keywords-regexp (- (point) 2) t)
    (goto-char (match-beginning 0))
    (match-string-no-properties 0))
   (t (buffer-substring-no-properties
       (point)
       (progn (skip-syntax-backward "w_")
              (point))))))

これらのlexerがカッコの前にあるとき空文字列をリターンする方法に注目してください。これはSMIEが構文テーブル内で定義されているカッコにたいして自動的に配慮するからです。より厳密にはlexerがnil、または空文字列をリターンしたら、SMIEは構文テーブルにしたがって対応するテキストをsexpとして処理します。


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

24.7.1.5 非力なパーサーと歩む

SMIEが使用するパーステクニックは、異なるコンテキストでトークンが異なる振る舞いをすることを許容しません。ほとんどのプログラミング言語にたいして、これは順位の競合によりBNF文法を変換するとき明らかになります。

その文法を若干異なるように表現することにより、これらの競合を回避できる場合があります。たとえばModula-2にたいしては以下のようなBNF文法をもつことが自然に思えるかもしれません:

  ...
  (inst ("IF" exp "THEN" insts "ELSE" insts "END")
        ("CASE" exp "OF" cases "END")
        ...)
  (cases (cases "|" cases)
         (caselabel ":" insts)
         ("ELSE" insts))
  ...

しかしこれは"ELSE"にたいする競合を生み出すでしょう。その一方でIFルールは、(他の多くのものの中でも特に)"ELSE" = "END"を暗示します。しかしその一方で"ELSE"cases内に出現しますが、cases"END"の左に出現するので、わたしたちは"ELSE" > "END"も得ることになります。これは以下を使用して解決できます:

  ...
  (inst ("IF" exp "THEN" insts "ELSE" insts "END")
        ("CASE" exp "OF" cases "END")
        ("CASE" exp "OF" cases "ELSE" insts "END")
        ...)
  (cases (cases "|" cases) (caselabel ":" insts))
  ...

または

  ...
  (inst ("IF" exp "THEN" else "END")
        ("CASE" exp "OF" cases "END")
        ...)
  (else (insts "ELSE" insts))
  (cases (cases "|" cases) (caselabel ":" insts) (else))
  ...

文法書き換えによる競合の解決には欠点があります。なぜならSMIEはその文法がコードの論理的構造を反映すると仮定するからです。そのためBNFと意図する抽象的構文木の関係を密接に保つことが望まれます。

注意深く考慮した結果、これらの競合が深刻ではなく、smie-bnf->prec2resolvers引数を通じて解決する決心をする場合もあるでしょう。これは通常はその文法が単に不明瞭だからです。その文法により記述されるプログラムセットは競合の影響を受けませんが、それらのプログラムにたいする唯一の方法はパースだけです。'((assoc "|"))のようなリゾルバ(resolver: 解決するもの)を追加したいと望むような場合、通常それはセパレーターと2項結合演算子にたいするケースです。これが発生し得る他のケースは'((assoc "else" "then"))を使用するような場合における、古典的なぶら下がりelse問題(dangling else problem)です。これは実際に競合があり解決不能なものの、実際のところ問題が発生しそうにないケースにたいしても発生し得ます。

最後に多くのケースではすべての文法再構築努力にも関わらず、いくつかの競合が残るでしょう。しかし失望しないでください。パーサーをより賢くすることはできませんが、あなたの望むようにlexerをスマートにすることは可能です。その方法は競合が発生したら競合を引き起こしたトークンを調べて、それらのうちの1つを2つ以上の異なるトークンに分割する方法です。たとえばトークン"begin"にたいする互換性のない2つの使用を文法が区別する必要があり、見つかった"begin"の種類によってlexerに異なるトークン(たとえば"begin-fun""begin-plain")をリターンさせる場合です。これはlexerにたいして異なるケースを区別する処理を強制し、そのためにlexerは特別な手がかりを見つけるために周囲のテキストを調べる必要があるでしょう。


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

24.7.1.6 インデントルールの指定

提供された文法にもとづき、他に特別なことを行わなくてもSMIEは自動的なインデントを提供できるでしょう。しかし恐らく実際にはこのデフォルトのインデントスタイルでは十分ではありません。多くの異なる状況においてこれを微調整したいと思うかもしれません。

SMIEのインデントは、インデントルールは可能な限りローカルであるべきという考えにもとづきます。バーチャルインデント(virtual indentation)という考えによってこの目的を達成しています。これは特定のプログラムポイント(program point)は行頭にバーチャルインデントがあれば、それをもつだろう、という発想です。もちろんそのプログラムポイントが正に行頭にあれば、そのプログラムポイントのバーチャルインデントはプログラムポイントのカレントのインデントです。しかしそうでなければSMIEがそのポイントのバーチャルインデントを計算するためにインデントアルゴリズムを使用します。ところで実際にはあるプログラムポイントのバーチャルインデントは、その前に改行を挿入した場合にプログラムポイントがもつであろうインデントと等しい必要はありません。これが機能する方法を確認するためには、Cにおける{の後のSMIEのインデントルールは{がインデントする行自体にあるか、あるいは前の行の終端にあるかを配慮しないことが挙げられます。かわりにこれらの異なるケースは{の前のインデントを決定するインデントルール内で処理されます。

他の重要な考え方としてparentの概念があります。あるトークンparentは周囲にある直近の構文構造の代表トークン(head token)です。たとえばelseのparentはそれが属するifであり、ifのparentは周囲を取り囲む構造の先導トークン(lead token)です。コマンドbackward-sexpは、あるトークンからトークンのparentにジャンプしますが注意する点がいくつかあります。他のトークンではそのトークンの後のポイントから開始する必要があるのにたいして、opener (ifのようなある構造を開始するトークン)ではそのトークンの前のポイントから開始する必要があります。backward-sexpはparentトークンがそのトークンのopenerならparentトークンの前のポイントで停止し、それ以外ではparentトークンの後のポイントで停止します。

SMIEのインデントルールは、2つの引数methodargを受け取る関数により指定されます。ここでargの値と期待されるリターン値はmethodに依存します。

methodには以下のいずれかを指定できます:

  • :after: この場合、argはトークンであり関数はargの後に使用するインデントにたいするoffsetをリターンすること。
  • :before: この場合、argはトークンであり関数はarg自体に使用するインデントのoffsetをリターンすること。
  • :elem: この場合、関数は関数の引数に使用するインデントのオフセット(argがシンボルargの場合)、または基本的ナインデントステップ(argがシンボルbasicの場合)のいずれかをリターンすること。
  • :list-intro: この場合、argはトークンであり関数はそのトークンの後が単一の式ではなく、(任意のトークンにより区切られない)式のリストが続くなら非nilをリターンすること。

argがトークンのとき関数はそのトークンの直前のポイントで呼び出されます。リターン値nilは常にデフォルトの振る舞いへのフォールバックを意味するので、関数は期待した引数でないときはnilをリターンするべきです。

offsetには以下のいずれかを指定できます:

  • nil: デフォルトのインデントルールを使用する。
  • (column . column): 列columnにインデントする。
  • number: 基本トークン(base token: :afterにたいするカレントトークンであり、かつ:beforeにたいしてparentであるようなトークン)にたいして相対的なnumberによるオフセット。

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

24.7.1.7 インデントルールにたいするヘルパー関数

SMIEはインデントを決定する関数内で使用するために特別にデザインされたさまざまな関数を提供します(これらの関数のうちのいくつかは異なるコンテキスト内で使用された場合に中断する)。これらの関数はすべてプレフィックスsmie-rule-で始まります。

Function: smie-rule-bolp

カレントトークンが行の先頭にあれば非nilをリターンする。

Function: smie-rule-hanging-p

カレントトークンがhanging(ぶら下がり)なら非nilをリターンする。トークンがその行の最後のトークンであり、他のトークンが先行する場合、そのトークンはhangingである。行に単独のトークンはhangingではない。

Function: smie-rule-next-p &rest tokens

次のトークンがtokens内にあれば非nilをリターンする。

Function: smie-rule-prev-p &rest tokens

前のトークンがtokens内にあれば非nilをリターンする。

Function: smie-rule-parent-p &rest parents

カレントトークンのparentがparents内にあれば非nilをリターンする。

Function: smie-rule-sibling-p

カレントトークンのparentが実際はsibling(兄弟)なら非nilをリターンする。たとえば","のparentが直前の","のような場合が該当。

Function: smie-rule-parent &optional offset

カレントトークンをparentとアライン(align: 桁揃え)するための適切なオフセットをリターンする。offsetが非nilなら、それは追加オフセットとして適用される整数であること。

Function: smie-rule-separator method

セパレーター(separator)としてカレントトークンをインデントする。

ここでのセパレーターとは周囲を取り囲む何らかの構文構造内でさまざまな要素を区切ることを唯一の目的とするトークンであり、それ自体は何も意味をもたないトークン(通常は抽象構文木内でノードとして存在しないこと)を意味する。

このようなトークンは結合構文をもち、その構文的parentと密に結び付けられることが期待される。典型的な例としては引数リスト内の"," (カッコで括られた内部)、または命令文シーケンス内の";" ({...}begin...endで括られたブロックの内部)が挙げられる。

methodsmie-rules-functionに渡されるメソッド名であること。


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

24.7.1.8 インデントルールの例

以下はインデント関数の例です:

(defun sample-smie-rules (kind token)
  (pcase (cons kind token)
    (`(:elem . basic) sample-indent-basic)
    (`(,_ . ",") (smie-rule-separator kind))
    (`(:after . ":=") sample-indent-basic)
    (`(:before . ,(or `"begin" `"(" `"{"))
     (if (smie-rule-hanging-p) (smie-rule-parent)))
    (`(:before . "if")
     (and (not (smie-rule-bolp)) (smie-rule-prev-p "else")
          (smie-rule-parent)))))

注意すべき点がいくつかあります:

  • 最初のcaseは使用する基本的なインデントの増分を示す。sample-indent-basicnilなら、SMIEはグローバルセッティングsmie-indent-basicを使用する。メジャーモードがかわりにsmie-indent-basicをバッファーローカルにセットするかもしれないが推奨しない。
  • トークン","にたいするルールによってカンマセパレーターが行頭にある場合にSMIEをより賢明に振る舞わせようとしている。これはセパレーターのインデントを解除(outdent)、カンマの後のコードにアラインされるよう試みる。たとえば:
    x = longfunctionname (
            arg1
          , arg2
        );
    
  • そうしなければSMIEが":="を2項演算子として扱い、左の引数に併せて右の引数をアラインするであろうから、":="の後のインデントのルールが存在する。
  • "begin"の前のインデントのルールはバーチャルインデントの使用例である。このルールは"begin"がhangingのときだけ使用され、これは"begin"が行頭にないときのみ発生し得る。そのためこれは"begin"自体のインデントには使用されないが、この"begin"に関連する何かをインデントするときだけ使用される。このルールは具体的には以下のフォームを:
        if x > 0 then begin
                dosomething(x);
            end
    

    以下に変更する

        if x > 0 then begin
            dosomething(x);
        end
    
  • "if"の前のインデントのルールは"begin"のインデントルールと似ているが、ここでの目的は"else if"を1単位として扱うことにあり、それにより各テストより右にインデントされずに一連のテストにアラインされる。この関数はsmie-rule-bolpをテストして"if"が別の行にないときだけこれを行う。

    "else"がそれの属する"if"にたいして常にアラインされて、かつそれが常に行頭であるることが判っていれば、より効果的なルールを使用できる:

    ((equal token "if")
     (and (not (smie-rule-bolp))
          (smie-rule-prev-p "else")
          (save-excursion
            (sample-smie-backward-token)
            (cons 'column (current-column)))))
    

    この式の利点はこれがシーケンスの最初の"if"まで戻ってすべてをやり直すのではなく、前の"else"のインデントを再利用することである。


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

24.7.1.9 インデントのカスタマイズ

SMIEにより提供されるインデントを使用するモードを使っている場合には、好みに合わせてインデントをカスタマイズできます。これはモードごと(オプションsmie-configを使用)、またはファイルごと(ファイルローカル変数指定内で関数smie-config-localを使用)に行うことができます。

User Option: smie-config

このオプションによりモードごとにインデントをカスタマイズできる。これは(mode . rules)という形式の要素をもつalist。rulesの正確な形式については変数のドキュメントを参照のこと。しかしコマンドsmie-config-guessを使用したほうが、より簡単に見つけられるかもしれない。

Command: smie-config-guess

このコマンドは好みのスタイルのインデントを生成する適切セッティングの解決を試みる。あなたのスタイルでインデントされたファイルをvisitしているときに単にこのコマンドを呼び出せばよい。

Command: smie-config-save

smie-config-guessを使用した後にこのコマンドを呼び出すと将来のセッション用にセッティングを保存する。

Command: smie-config-show-indent &optional move

このコマンドはカレント行のインデントに使用されているルールを表示する。

Command: smie-config-set-indent

このコマンドはカレント行のインデントに合わせてローカルルールを追加する。

Function: smie-config-local rules

この関数はカレントバッファーにたいするインデントルールとしてrulesを追加する。これらのルールはsmie-configオプションにより定義された任意のモード固有ルールに追加される。特定のファイルにたいしてカスタムインデントルールを指定するには、eval: (smie-config-local '(rules))の形式のエントリーをそのファイルのローカル変数に追加する。


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

24.7.2 パーサーベースのインデント

tree-sitterライブラリー(プログラムソースの解析を参照)とともにEmacsをビルドした場合には、Emacsによるプログラムソースのパースと構文ツリー(syntax tree)の生成が可能になります。プログラムソースのインデントコマンドにたいするガイド役としてこの構文ツリーを使用することができます。柔軟性を最大限発揮できるように構文ツリーに問い合わせを行うインデント用のカスタマイズ関数を記述して、それぞれの言語に応じたインデントを行うことも可能ですが、これには多くの作業が伴います。より使いやすいのは、この後に説明するシンプルなインデント用エンジンでしょう。そうすればメジャーモードに要求されるのはいくつかのインデントルールの記述だけとなり、残りはこのエンジンが面倒を見てくれます。

パーサーベースのインデントエンジンを有効にするにはtreesit-simple-indent-rulesをセットしてtreesit-major-mode-setupを呼び出すか、indent-line-functionの値をtreesit-indentにセットしてください(どちらを選んでも同じ)。

Variable: treesit-indent-function

この変数はtreesit-indentによって呼び出される実際の関数が格納される。デフォルトの値はtreesit-simple-indent。将来より複雑なエンジンが追加されるかもしれない。

インデントルールの記述

Variable: treesit-simple-indent-rules

このローカル変数にはすべての言語用のインデントルールが格納される。値は(language . rules)というフォームのalist。ここでlanguageは言語シンボル、rules(matcher anchor offset)という形式の要素をもつリスト。

最初にEmacsはカレント行の先頭にある最小のtree-sitterノードをmatcherに渡して、非nilがリターンされればそのルールが適用できる。その後にEmacsはそのノードをanchorに渡して、バッファーの位置がリターンされる。Emacsがその位置の列番号を取得してoffsetを追加すると、、その結果がカレント行のインデント列となる。

matcheranchorは関数。これらにたいしてEmacsは便利なデフォルトを提供している。

matcherおよびanchorはそれぞれnodeparentbolという3つの引数を受け取る関数。引数bolはインデントが要求されるバッファー位置(行頭の後の最初の非空白文字の位置)、引数nodeはその位置から開始されるもっとも大きい(かつルートではない)ノード、parentnodeの親ノードである。ただしその位置にあるのが空白だったり、あるいは複数行文字列の内部の場合には、その位置から開始可能なノードは存在しないので、nodenilとなる。このような場合には、その位置を跨ぐもっとも小さいノードがparentとなる。

ルールが適用可能ならmatcherは非nilanchorはバッファー位置をリターンすること。

offsetは整数、値が整数であるような変数、あるいは整数をリターンする関数を指定できる。関数の場合にはmatcherやanchorと同様にnodeparentbolが渡される。

Variable: treesit-simple-indent-presets

これはtreesit-simple-indent-rulesmatcheranchorにたいするデフォルトのリスト。これらはそれぞれnodeparentbolという3つの引数を受け取る関数である。利用できるデフォルト関数は以下のとおり:

no-node

このmatcherはnodeparentbolという3つの引数で呼び出される。nodenil (bolで始まるノードが存在せず、bolが空行や複数行の内部にbolがある場合などが該当)の場合には、マッチを表す非nilをリターンする。

parent-is

このmatcherはtypeという1つの引数で呼び出される関数をリターンする。この関数はnodeparentbolという3つの引数とともに呼び出されて、parentのタイプがregexpのtypeとマッチすれば非nil (マッチしたことを意味する)をリターンする。

node-is

このmatcherはtypeという1つの引数を受け取る関数。この関数はnodeparentbolという3つの引数とともに呼び出されて、nodeのタイプがregexpのtypeとマッチすれば非nilをリターンする。

field-is

このmatcherはnameという1つの引数を受け取る関数。この関数はnodeparentbolという3つの引数とともに呼び出されて、parentnodeのフィールド名がregexpのnameとマッチすれば非nilをリターンする。

query

このmatcherはqueryという1つの引数を受け取る関数。この関数はnodeparentbolという3つの引数とともに呼び出されて、queryparentに問い合わせた場合にnodeをキャプチャすれば非nilをリターンする(tree-sitterノードにたいするパターンマッチングを参照)。

match

このmatcherはnode-typeparent-typenode-fieldnode-index-minnode-index-maxという5つの引数とともに呼び出される関数。ここでリターンされた関数はnodeparentbolという3つの引数で呼び出される関数をリターンする。ここでリターンされた関数はnodeのタイプがregexpのnode-typeparentのタイプがregexpのparent-typeparentnodeのフィールド名がregexpのnode-fieldnodeのインデックスが兄弟ノードnode-index-minnode-index-maxの間にあれば非nilをリターンする。このmatcherは引数の値がnilであれば、その引数はチェックしない。たとえば親ノードとしてargument_listをもつ最初の子ノードにマッチさせるには、以下のようにすればよい

(match nil "argument_list" nil nil 0 0)

更にnode-typeは特別な値nullでもよく、これはnodeの値がnilのときにマッチする。

n-p-gp

“node-parent-grandparent(ノード-親-祖父母)”の略。このmatcherはnode-typeparent-typegrandparent-typeという3つの引数を受け取る関数。これはnodeparentbolという3つの引数で呼び出されて(1) node-typenode’のタイプとマッチ、(2) parent-typeparentのタイプとマッチ (3) grandparent-typeparentの親のタイプという3つのマッチがすべて成り立てば非nilをリターンする関数をリターンする。この関数はnode-typeparent-typegrandparent-typeのいずれかがnilならチェックを行わない。

comment-end

このmatcherはnodeparentbolという3つの引数で呼び出されて、コメント終了トークンn前にポイントがあれば非nilをリターンする関数。コメント終了トークンはcomment-end-skipのregexpによって定義される。

catch-all

このmatcherはnodeparentbolという3つの引数で呼び出される関数。この関数はマッチを示すために常に非nilをリターンする。

first-sibling

このanchorはnodeparentbolという3つの引数とともに呼び出されて、parentの最初の子ノードの開始をリターンする関数。

nth-sibling

このanchorはn、オプションとしてnamedという2つの引数を受け取る関数。nodeparentbolという3つn引数で呼び出されて、parentn番目の開始をリターンする関数をリターンする。namedが非nilなら、名前付きの子だけを考慮する(named nodeを参照)。

parent

このanchorはnodeparentbolという3つの引数とともに呼び出されて、parentの開始をリターンする関数。

grand-parent

このanchorはnodeparentbolという3つの引数とともに呼び出されて、parentの親の開始をリターンする関数。

great-grand-parent

このanchorはnodeparentbolという3つの引数とともに呼び出されて、parentの親の親の開始をリターンする関数。

parent-bol

このanchorはnodeparentbolという3つの引数とともに呼び出されて、parentの開始位置にある行の最初の非スペース文字をリターンする関数。

standalone-parent

このanchorはnodeparentbolという3つの引数で呼び出される関数。この関数は独自の行で始まるようなnodeの最初の祖先(親、祖父母、etc)を探して、そのノードの開始をリターンする。“独自の行で始まる”とはそのノードが開始する行において、ノードの前に空白文字しか存在しないことを意味する。

prev-sibling

このanchorはnodeparentbolという3つの引数とともに呼び出されて、nodeの前の兄弟ノードの開始をリターンする関数。

no-indent

このanchorはnodeparentbolという3つの引数とともに呼び出されて、nodeの開始をリターンする関数。

prev-line

このanchorはnodeparentbolという3つの引数とともに呼び出されて、前の行の最初の必要空白文字をリターンする関数。

column-0

このanchorはnodeparentbolという3つの引数とともに呼び出されて、列0にあるカレント行先端をリターンする。

comment-start

このanchorはnodeparentbolという3つの引数とともに呼び出されて、コメント開始トークンの後の位置をリターンする。コメント開始トークンは正規表現comment-start-skipによって定義される。この関数はparentがコメントノードであるとみなす。

prev-adaptive-prefix

このanchorはnodeparentbolという3つの引数で呼び出される関数。前にある空ではない行の先頭にあるテキストにたいして、adaptive-fill-regexpとのマッチを試みる。マッチが存在すればマッチの終端、存在しなければnilをリターンする。ただしカレント行がプレフィックス(例: ‘-’)で始まる場合には、前の行のプレフィックスと位置が揃うように、前の行のプレフィックスの開始をリターンする。このanchorはブロックコメントにたいして、indent-relative-*のような挙動のインデントを行う際に役に立つ。

インデント用のユーティリティー

以下にパーサーベースのインデントルールを記述する助けとなるユーティリティー関数をいくつか挙げます。

Command: treesit-check-indent mode

このコマンドはメジャーモードmodeにたいするカレントバッファーのインデントをチェックする。この関数はmodeに応じてカレントバッファーをインデントして、その結果をカレントのインデントと比較、その後に差分を表示するバッファーをポップアップする。(インデント対象の)正しいインデントはグリーン、カレントのインデントは赤のカラーで示される。

インデントのルールを記述する際には、treesit-inspect-modeを使用するのも助けとなるでしょう(Tree-sitter Language Grammarを参照)。


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

24.8 Desktop Saveモード

Desktop Saveモードとは、あるセッションから別のセッションへEmacs状態を保存する機能です。Desktop Saveモードの使用に関するユーザーレベルのコマンドについては、GNU Emacsマニュアルに記載されています(Saving Emacs Sessions in the GNU Emacs Manualを参照)。バッファーでファイルをvisitしているモードでは、この機能を使うために何も行う必要はありません。

ファイルをvisitしていないバッファーについて状態を保存するには、そのメジャーモードがバッファーローカル変数desktop-save-bufferを非nil値にバインドしなければなりません。

Variable: desktop-save-buffer

このバッファーローカル変数が非nilなら、デスクトップ保存時にそのバッファー状態がdesktopファイルに保存される。値が関数なら、その関数はデスクトップ保存時に引数desktop-dirnameで呼び出されて、関数が呼び出されたバッファーの状態とともに関数の値がdesktopファイルに保存される。補助的な情報の一部としてファイル名がリターンされたとき、それらは以下を呼び出してフォーマットされること

(desktop-file-name file-name desktop-dirname)

ファイルをvisitしていないバッファーがリストアされるようにするには、メジャーモードがその処理を行う関数を定義しなければならず、その関数は連想リストdesktop-buffer-mode-handlersにリストされなければならない。

Variable: desktop-buffer-mode-handlers

以下を要素にもつalist

(major-mode . restore-buffer-function)

関数restore-buffer-functionは以下の引数リストで呼び出される

(buffer-file-name buffer-name desktop-buffer-misc)

この関数はリストアされたバッファーをリターンすること。ここでdesktop-buffer-miscは、オプションでdesktop-save-bufferにバインドされる関数がリターンする値。


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

25 ドキュメント

GNU Emacsには便利なビルトインのヘルプ機能があり、それらのほとんどは関数や変数のドキュメント文字列に付属するドキュメント文字列の情報が由来のものです。このチャプターではLispプログラムからドキュメント文字列にアクセスする方法について説明します。

ドキュメント文字列のコンテンツはある種の慣習にしたがう必要があります。特に最初の行はその関数や変数を簡単に説明する1つか2つの完全なセンテンスであるべきです。よいドキュメント文字列を記述する方法についてはドキュメント文字列のヒントを参照してください。

Emacs向けのドキュメント文字列はEmacsマニュアルと同じものではないことに注意してください。マニュアルはTexinfo言語で記述された独自のソースファイルをもちます。それにたいしドキュメント文字列はそれが適用される関数と変数の定義内で指定されたものです。ドキュメント文字列を収集してもそれはマニュアルとしては不十分です。なぜならよいマニュアルはそのやり方でまとめられたものではなく、議論にたいするトピックという観点でまとめられたものだからです。

ドキュメント文字列を表示するコマンドについては、Help in The GNU Emacs Manualを参照してください。


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

25.1 ドキュメントの基礎

ドキュメント文字列はテキストをダブルクォート文字で囲んだ文字列にたいするLisp構文を使用して記述されます。実はこれは実際のLisp文字列です。関数または変数の定義内の適切な箇所に文字列があると、それは関数や変数のドキュメントの役割を果たします。

関数定義(lambdadefunフォーム)の中では、ドキュメント文字列は引数リストの後に指定され、通常は関数オブジェクト内に直接格納されます。関数のドキュメント文字列を参照してください。関数名のfunction-documentationプロパティに関数ドキュメントをputすることもできます(ドキュメント文字列へのアクセスを参照)。

変数定義(defvarフォーム)の中では、ドキュメント文字列は初期値の後に指定されます。グローバル変数の定義を参照してください。この文字列はその変数のvariable-documentationプロパティに格納されます。

Emacsがメモリー内にドキュメント文字列を保持しないときがあります。それには、これには2つの状況があります。1つ目はメモリーを節約するためでプリミティブ関数(関数とは?を参照)およびビルトイン変数のドキュメントは、doc-directoryで指定されたディレクトリー内のDOCという名前のファイルに保持されます(ドキュメント文字列へのアクセスを参照)。2つ目は関数や変数がバイトコンパイルされたファイルからロードされたときで、Emacsはそれらのドキュメント文字列のロードを無効にします(ドキュメント文字列とコンパイルを参照)。どちらの場合も、ある関数にたいしてユーザーがC-h f(describe-function)を呼び出したとき等の必要なときだけEmacsはファイルのドキュメント文字列を照会します。

ドキュメント文字列にはユーザーがドキュメントを閲覧するときのみルックアップされるキーバインディングを参照する、特別なキー置換シーケンス(key substitution sequences)を含めることができます。これにより、たとえユーザーがデフォルトのキーバインディングを変更していてもヘルプコマンドが正しいキーを表示できるようになります。

オートロードされたコマンド(autoloadを参照)のドキュメント文字列ではこれらのキー置換シーケンスは特別な効果をもち、そのコマンドにたいするC-h fによってオートロードをトリガーします(これは*Help*バッファー内のハイパーリンクを正しくセットアップするために必要となる)。


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

25.2 ドキュメント文字列へのアクセス

Function: documentation-property symbol property &optional verbatim

この関数はプロパティproperty配下のsymbolのプロパティリスト内に記録されたドキュメント文字列をリターンする。これはほとんどの場合propertyvariable-documentationにして、変数のドキュメント文字列の照会に使用される。しかしカスタマイゼーショングループのような他の種類のドキュメント照会にも使用できる(が関数のドキュメントには以下のdocumentation関数を使用する)。

そのプロパティの値がDOCファイルやバイトコンパイル済みファイルに格納されたドキュメント文字列を参照する場合、この関数はその文字列を照会してそれをリターンする。

プロパティの値がnilや文字列以外でファイル内のテキストも参照しなければ、文字列を取得するLisp式として評価される。

最終的にこの関数はキーバインディングを置換するために、文字列をsubstitute-command-keysに引き渡す(ドキュメント内でのキーバインディングの置き換えを参照)。verbatimが非nilならこのステップはスキップされる。

(documentation-property 'command-line-processed
   'variable-documentation)
     ⇒ "Non-nil once command line has been processed"
(symbol-plist 'command-line-processed)
     ⇒ (variable-documentation 188902)
(documentation-property 'emacs 'group-documentation)
     ⇒ "Customization of the One True Editor."
Function: documentation function &optional verbatim

この関数はfunctionのドキュメント文字列をリターンする。この関数はマクロ、名前付きキーボードマクロ、およびスペシャルフォームも通常の関数と同様に処理する。

functionがシンボルならそのシンボルのfunction-documentationプロパティを最初に調べる。それが非nil値をもつなら、その値(プロパティの値が文字列以外ならそれを評価した値)がドキュメントとなる。

functionがシンボル以外、あるいはfunction-documentationプロパティをもたなければ、documentationは必要ならファイルを読み込んで実際の関数定義のドキュメント文字列を抽出する。

最後にverbatimnilなら、この関数はsubstitute-command-keysを呼び出す。結果はリターンするための文字列。

documentation関数はfunctionが関数定義をもたなければvoid-functionエラーをシグナルする。しかし関数定義がドキュメントをもたない場合は問題ない。その場合はdocumentationnilをリターンする。

Function: function-documentation function

documentationが関数オブジェクトから生のdoc文字列を抽出するために用いるジェネリック関数。対応するメソッドを追加することによって、特定の関数タイプのdoc文字列を取得する方法を指定できる。

Function: face-documentation face

この関数はfaceのドキュメント文字列をフェイスとしてリターンする。

以下はdocumentationdocumentation-propertyを使用した例で、いくつかのシンボルのドキュメント文字列を*Help*バッファー内に表示します。

(defun describe-symbols (pattern)
  "Describe the Emacs Lisp symbols matching PATTERN.
All symbols that have PATTERN in their name are described
in the *Help* buffer."
  (interactive "sDescribe symbols matching: ")
  (let ((describe-func
         (lambda (s)
            ;; シンボルの説明をプリントする
            (if (fboundp s)             ; これは関数
                (princ
                 (format "%s\t%s\n%s\n\n" s
                   (if (commandp s)
                       (let ((keys (where-is-internal s)))
                         (if keys
                             (concat
                              "Keys: "
                              (mapconcat 'key-description
                                         keys " "))
                           "Keys: none"))
                     "Function")
                  (or (documentation s)
                      "not documented"))))

           (if (boundp s)              ; これは変数
               (princ
                (format "%s\t%s\n%s\n\n" s
                  (if (custom-variable-p s)
                      "Option " "Variable")
                  (or (documentation-property
                        s 'variable-documentation)
                      "not documented"))))))
        sym-list)

    ;; パターンにマッチするシンボルのリストを構築
    (mapatoms (lambda (sym)
                (if (string-match pattern (symbol-name sym))
                    (setq sym-list (cons sym sym-list)))))

    ;; データを表示
    (help-setup-xref (list 'describe-symbols pattern)
                 (called-interactively-p 'interactive))
    (with-help-window (help-buffer)
      (mapcar describe-func (sort sym-list 'string<)))))

describe-symbols関数はaproposのように機能しますが、より多くの情報を提供します。

(describe-symbols "goal")

---------- Buffer: *Help* ----------
goal-column     Option
Semipermanent goal column for vertical motion, as set by …

minibuffer-temporary-goal-position      Variable
not documented

set-goal-column Keys: C-x C-n
Set the current horizontal position as a goal for C-n and C-p.
Those commands will move to this position in the line moved to
rather than trying to keep the same horizontal position.
With a non-nil argument ARG, clears out the goal column
so that C-n and C-p resume vertical motion.
The goal column is stored in the variable ‘goal-column’.

msgid ""
"(defun describe-symbols (pattern)\n"
"  \"Describe the Emacs Lisp symbols matching PATTERN.\n"
"All symbols that have PATTERN in their name are described\n"
"in the `*Help*' buffer.\"\n"
"  (interactive \"sDescribe symbols matching: \")\n"
"  (let ((describe-func\n"
"         (function\n"
"          (lambda (s)\n"

temporary-goal-column   Variable
Current goal column for vertical motion.
It is the column where point was at the start of the current run
of vertical motion commands.

When moving by visual lines via the function ‘line-move-visual’, it is a cons
cell (COL . HSCROLL), where COL is the x-position, in pixels,
divided by the default column width, and HSCROLL is the number of
columns by which window is scrolled from left margin.

When the ‘track-eol’ feature is doing its job, the value is
‘most-positive-fixnum’.
---------- Buffer: *Help* ----------
Function: Snarf-documentation filename

この関数はEmacsビルド時の実行可能なEmacsダンプ直前に使用される。これはファイルfilename内に格納されたドキュメント文字列の位置を探して、メモリー上の関数定義および変数のプロパティリスト内にそれらの位置を記録する。Emacsのビルドを参照のこと。

Emacsはemacs/etcディレクトリーからファイルfilenameを読み込む。その後ダンプされたEmacs実行時に、ディレクトリーdoc-directory内の同じファイルを照会する。filenameは通常は"DOC"

Variable: doc-directory

この変数はビルトインの関数と変数のドキュメント文字列を含んだファイル"DOC"があるべきディレクトリーの名前を保持する。

これはほとんどの場合はdata-directoryと同一。実際にインストールしたEmacsではなくEmacsをビルドしたディレクトリーからEmacsを実行したときは異なるかもしれない。Definition of data-directoryを参照のこと。


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

25.3 ドキュメント内でのキーバインディングの置き換え

ドキュメント文字列がキーシーケンスを参照する際、それらはカレントである実際のキーバインディングを使用するべきです。これらは以下で説明する特別なキーシーケンスを使用して行うことができます。通常の方法によるドキュメント文字列へのアクセスは、これらの特別なキーシーケンスをカレントキーバインディングに置き換えます。これはsubstitute-command-keysを呼び出すことにより行われます。あなた自身がこの関数を呼び出すこともできます。

以下はそれら特別なシーケンスと、その意味についてのリストです:

\[command]

これはcommandを呼び出すキーシーケンス、またはcommandがキーバインディングをもたなければ‘M-x command’。

\{mapvar}

これは変数mapvarの値であるようなキーマップの要約(summary)を意味する。この要約はdescribe-bindingsを用いて作成される。

\<mapvar>

これ自体は何のテキストも意味せず副作用のためだけに使用される。これはこのドキュメント文字列内にある、後続のすべての‘\[command]’にたいするキーマップとしてmapvarの値を指定する。

\`KEYSEQ'

これはキーシーケンスKEYSEQを表し、コマンド置き換えと同じフェイスが使用される。これはキーシーケンスがたとえばread-key-sequenceによって直接読み取られた場合のように、対応するコマンドがない場合のみ使用すること。キーシーケンスはkey-valid-pに照らして有効なキーシーケンスでなければならない。これは‘\`M-x foo'’のようなコマンド名にたいして、キーボードシーケンスのようにフォント表示したいものの、‘\[foo]’が行うようなキーシーケンスへの変換を抑止したい場合にも使用できる。

`

グレイブアクセント(grave accent)は左クォートを意味する。これはtext-quoting-styleの値に応じて左シングルクォーテーションマーク、アポストロフィ、グレイブアクセントのいずれかを生成する。テキストのクォートスタイルを参照のこと。

'

アポストロフィ(apostrophe)は右クォートを意味する。これはtext-quoting-styleの値に応じて右シングルクォーテーションマーク、アポストロフィのいずれかを生成する。テキストのクォートスタイルを参照のこと。

\=

これは後続の文字をクォートして無効にする。したがって‘\=`’は‘`’、‘\=\[’は‘\[’、‘\=\=’は‘\=’を出力する。

\+

これは直後のシンボルを*Help*バッファーでリンクとしてマークするべきではないことを示す。

注意してください: Emacs Lisp内の文字列として記述する際は‘\’を2つ記述しなければなりません。

Function: substitute-command-keys string &optional no-face include-menus

この関数は上述の特別なシーケンスをstringからスキャンして、それらが意味するもので置き換えてその結果を文字列としてリターンする。これによりそのユーザー自身がカスタマイズした実際のキーシーケンスを参照するドキュメントが表示できる。そのキーバインディングにはデフォルトでは特別なフェイスhelp-key-bindingが与えられるが、オプション引数no-faceが非nilなら、この関数は生成した文字列にこのフェイスを追加しない。

Function: substitute-quotes string

この関数はsubstitute-command-keysと同じように機能するが、クォート文字だけを置き換える。

あるコマンドが複数のバインディングをもつ場合、通常この関数は最初に見つかったバインディングを使用する。以下のようにしてコマンドのシンボルプロパティ:advertised-bindingに割り当てることにより、特定のキーバインディングを指定できる:

(put 'undo :advertised-binding [?\C-/])

:advertised-bindingプロパティはメニューアイテム(メニューバーを参照)に表示されるバインディングにも影響する。コマンドが実際にもたないキーバインディングを指定するとこのプロパティは無視される。

以下は特別なキーシーケンスの例:

(substitute-command-keys
   "To abort recursive edit, type `\\[abort-recursive-edit]'.")
⇒ "To abort recursive edit, type ‘C-]’."

(substitute-command-keys
   "The keys that are defined for the minibuffer here are:
  \\{minibuffer-local-must-match-map}")
⇒ "The keys that are defined for the minibuffer here are:

?               minibuffer-completion-help
SPC             minibuffer-complete-word
TAB             minibuffer-complete
C-j             minibuffer-complete-and-exit
RET             minibuffer-complete-and-exit
C-g             abort-recursive-edit
"

The keymap description will normally exclude menu items, but if
include-menus is non-nil, include them.

(substitute-command-keys
   "To abort a recursive edit from the minibuffer, type \
`\\<minibuffer-local-must-match-map>\\[abort-recursive-edit]'.")
⇒ "To abort a recursive edit from the minibuffer, type ‘C-g’."

ドキュメント文字列内のテキストにたいしては他にも特別な慣習があります。それらはたとえばこのマニュアルの関数、変数、およびセクションで参照できます。詳細はドキュメント文字列のヒントを参照してください。


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

25.4 テキストのクォートスタイル

ドキュメント文字列や診断メッセージの中では、グレイブアクセント(grave accent)とアポストロフィ(apostrophe)は通常は特別に扱われてマッチするシングルクォーテーションマーク(“curved quotes”とも呼ばれる)に変換されます。たとえばドキュメント文字列"Alias for `foo'."と関数呼び出し(message "Alias for `foo'.")はどちらも"Alias for ‘foo’."に変換されます。あまり一般的ではありませんが、Emacsがグレイブアクセントとアポストロフィをそのまま表示したり、アポストロフィだけ("Alias for 'foo'.")を表示する場合もあります。ドキュメント文字列やメッセージフォーマットは、これらのスタイルすべてで良好に表示されるように記述する必要があります。たとえば通常の英語スタイル"Alias for ’foo’."で表示できるのならば、ドキュメント文字列"Alias for 'foo'."はあなたが望むスタイルではないでしょう。

テキストのクォートスタイルとは無関係に変換なしでグレイブアクセントやアポストロフィの表示を要するときがあるかもしれません。ドキュメント文字列ではエスケープでこれを行うことができます。たとえばドキュメント文字列"\\=`(a ,(sin 0)) ==> (a 0.0)"では、グレイブアクセントはLispコードの表現を意図しているので、グレイブアクセントエスケープしてクォートスタイルとは無関係にそれ自身を表示します。messageerrorの呼び出しでは、フォーマット"%s"format呼び出しを引数として変換を回避できます。たとえば(message "%s" (format "`(a ,(sin %S)) ==> (a %S)" x (sin x)))はテキストのクォートスタイルに関わらず、グレイブアクセントで始まるメッセージを表示します。

User Option: text-quoting-style

このユーザーオプションの値はヘルプやメッセージの文言中のシングルクォートにたいして、Emacsが使用するべきスタイルを指定するシンボル。このオプションの値がcurveなら‘like this’のようなcurved single quotesスタイル。値がstraightなら'like this'のような素のアポストロフィスタイル。値がgraveならクォートは変換せずに、`like this'のようなEmacsバージョン25以前の標準スタイルであるグレイブアクセントとアポストロフィのスタイル。デフォルト値のnilはcurved single quotesが表示可能なようならcurve、それ以外ならgraveのように機能する。

このオプションはcurved quotesに問題があるプラットフォームで有用。個人の好みに応じてこれを自由にカスタマイズできる。

Function: text-quoting-style

変数text-quoting-styleの値を直接読み取るべきではない。カレント端末においてこの変数にnilがセットされている際の正しいクォートスタイルを動的に算出するために、この同名の関数を使用すること。


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

25.5 ヘルプメッセージの文字記述

以下の関数はイベント、キーシーケンス、文字をテキスト表記(textual descriptions)に変換します。これらの変換された表記は、メッセージ内に任意のテキスト文字やキーシーケンスを含める場合に有用です。なぜなら非プリント文字や空白文字はプリント文字シーケンスに変換されるからです。空白文字以外のプリント文字はその文字自身が表記になります。

Function: key-description sequence &optional prefix

この関数はsequence内の入力イベントにたいしてEmacsの標準表記を含んだ文字列をリターンする。prefixが非nilなら、それはsequenceに前置される入力イベントシーケンスであり、リターン値にも含まれる。引数には文字列、ベクター、またはリストを指定できる。有効なイベントに関する詳細は入力イベントを参照のこと。

(key-description [?\M-3 delete])
     ⇒ "M-3 <delete>"
(key-description [delete] "\M-3")
     ⇒ "M-3 <delete>"

以下のsingle-key-descriptionの例も参照のこと。

Function: single-key-description event &optional no-angles

この関数はキーボード入力にたいするEmacsの標準表記としてeventを表記する文字列をリターンする。通常のプリント文字はその文字自身で表れるが、コントロール文字は‘C-’で始まる文字列、メタ文字は‘M-’で始まる文字列、スペースやタブ等は‘SPC’や‘TAB’のように変換される。ファンクションキーのシンボルは‘<…>’のように角カッコ(angle brackets)の内側に表れる。リストであるようなイベントは、そのリストのCAR内のシンボル名が角カッコの内側に表れる。

オプション引数no-anglesが非nilなら、ファンクションキーやイベントシンボルを括る角カッコは省略される。これは角カッコを使用しない古いバージョンのEmacsとの互換性のため。

(single-key-description ?\C-x)
     ⇒ "C-x"
(key-description "\C-x \M-y \n \t \r \f123")
     ⇒ "C-x SPC M-y SPC C-j SPC TAB SPC RET SPC C-l 1 2 3"
(single-key-description 'delete)
     ⇒ "<delete>"
(single-key-description 'C-mouse-1)
     ⇒ "C-<mouse-1>"
(single-key-description 'C-mouse-1 t)
     ⇒ "C-mouse-1"
Function: text-char-description character

この関数はテキスト内に出現し得る文字にたいするEmacsの標準表記としてcharacterを記述する文字列をリターンする。これはsingle-key-descriptionと似ているが、引数がcharacterpによるテスト(文字コードを参照)をパスする有効な文字コードでなければならない点が異なる。この関数は先頭のカレットによりコントロール文字の記述を生成する(Emacsがバッファー内にコントロール文字を表示する通常の方法)。修飾ビットをもつ文字にたいして、この関数はエラーをシグナルする(コントロール修飾されたASCII文字は例外であり、これらはコントロール文字として表現される)。

(text-char-description ?\C-c)
     ⇒ "^C"
(text-char-description ?\M-m)
     error→ Wrong type argument: characterp, 134217837
Command: read-kbd-macro string &optional need-vector

この関数は主にキーボードマクロを操作するために使用されるが、大雑把な意味でkey-descriptionの逆の処理にも使用できる。キー表記を含むスペース区切りの文字列でこれを呼び出すと、それに対応するイベントを含む文字列かベクターをリターンする(これは単一の有効なキーシーケンスであるか否かは問わず何のイベントを使用するかに依存する。キーシーケンスを参照のこと)。need-vectorが非nilならリターン値は常にベクター。


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

25.6 ヘルプ関数

Emacsはさまざまなビルトインのヘルプ関数を提供しており、それらはすべてプレフィックスC-hのサブコマンドとしてユーザーがアクセスできます。それらについての詳細はHelp in The GNU Emacs Manualを参照してください。ここでは同様な情報に関するプログラムレベルのインターフェイスを説明します。

Command: apropos pattern &optional do-all

この関数は名前にaproposパターン(apropos pattern: 適切なパターン) patternを含む重要なすべてのシンボルを探す。マッチに使用されるaproposパターンは単語、最低2つはマッチしなければならないスペース区切りの単語、または(特別な正規表現文字があれば)正規表現のいずれか。あるシンボルが関数、変数、フェイスとしての定義、あるいはプロパティをもつならそのシンボルは重要とみなされる。

この関数は以下のような要素のリストをリターンする:

(symbol score function-doc variable-doc
 plist-doc widget-doc face-doc group-doc)

ここでscoreはマッチの面からそのシンボルがどれだけ重要に見えるかを比較する整数である。残りの各要素はsymbolにたいする関数、変数、...等のドキュメント文字列(またはnil)。

これは*Apropos*という名前のバッファーにもシンボルを表示する。その際、各行にはドキュメント文字列の先頭から取得した1行説明とともに表示される。

do-allが非nil、またはユーザーオプションapropos-do-allが非nilなら、aproposは見つかった関数のキーバインディングも表示する。これは重要なものだけでなく、internされたすべてのシンボルも表示する(同様にリターン値としてもそれらをリストする)。

Variable: help-map

この変数の値はHelpキーC-hに続く文字にたいするローカルキーマップである。

Prefix Command: help-command

このシンボルは関数ではなく関数定義セルにはhelp-mapとしてキーマップを保持する。これはhelp.el内で以下のように定義されている:

(keymap-set global-map (key-description (string help-char)) 'help-command)
(fset 'help-command help-map)
User Option: help-char

この変数の値はヘルプ文字(help character: Helpを意味する文字としてEmacsが認識する文字)。デフォルトの値はC-hを意味する8。この文字を読み取った際にhelp-formが非nilのLisp式なら、Emacsはその式を評価して結果が文字列の場合はウィンドウ内にそれを表示する。

help-formの値は通常はnil。その場合にはヘルプ文字はコマンド入力のレベルにおいて特別な意味を有さず、通常の方法におけるキーシーケンスの一部となる。C-hの標準的なキーバインディングは、複数の汎用目的をもつヘルプ機能のプレフィックスキー。

ヘルプ文字はプレフィックスキーの後でも特別な意味をもつ。ヘルプ文字がプレフィックスキーのサブコマンドとしてバインディングをもたなければ、そのプレフィックスキーのすべてのサブコマンドのリストを表示するdescribe-prefix-bindingsを実行する。

User Option: help-event-list

この変数の値はヘルプ文字の選択肢の役割を果たすイベント型のリスト。これらのイベントはhelp-charで指定されるイベントと同様に処理される。

Variable: help-form

この変数が非nilなら、その値は文字help-charが読み取られるたびに評価されるフォームであること。そのフォームの評価によって文字列が生成されたらその文字列が表示される。

read-eventread-char-choiceread-charread-char-from-minibuffery-or-n-pを呼び出すコマンドは、それが入力を行う間は恐らくhelp-formを非nilにバインドするべきだろう(C-hが他の意味をもつなら行わないこと)。この式を評価した結果は、それが何にたいする入力なのかと、それを正しくエンターする方法を説明する文字列であること。

ミニバッファーへのエントリーにより、この変数はminibuffer-help-formの値にバインドされる(Definition of minibuffer-help-formを参照)。

Variable: prefix-help-command

この変数はプレフィックスキーにたいするヘルプをプリントする関数を保持する。その関数はユーザーが後にヘルプ文字を伴うプレフィックスキーをタイプして、そのヘルプ文字がプレフィックスの後のバインディングをもたないたときに呼び出される。この変数のデフォルト値はdescribe-prefix-bindings

Command: describe-prefix-bindings

この関数はもっとも最近のプレフィックスキーのサブコマンドすべてにたいするリストを表示するdescribe-bindingsを呼び出す。記述されるプレフィックスは、そのキーシーケンスの最後のイベントを除くすべてから構成される(最後のイベントは恐らくヘルプ文字)。

以下の2つの関数はelectricモードのように制御を放棄せずにヘルプを提供したいモードを意図しています。これらは通常のヘルプ関数と区別するために名前が‘Helper’で始まります。

Command: Helper-describe-bindings

このコマンドはローカルキーマップとグローバルキーマップの両方のキーバインディングすべてのリストを含むヘルプバッファーを表示するウィンドウをポップアップする。これはdescribe-bindingsを呼び出すことによって機能する。

Command: Helper-help

このコマンドはカレントモードにたいするヘルプを提供する。これはミニバッファー内でメッセージ‘Help (Type ? for further options)’とともにユーザーに入力を求めて、その後キーバインディングが何か、何を意図するモードなのかを探すための助けを提供する。これはnilをリターンする。

これはマップHelper-help-mapを変更することによってカスタマイズできる。

Variable: data-directory

この変数はEmacsに付随する特定のドキュメントおよびテキストファイルを探すディレクトリーの名前を保持する。

Function: help-buffer

この関数はヘルプバッファーの名前(通常は*Help*)をリターンする。そのようなバッファーが存在しなければ最初にそれを作成する。

Macro: with-help-window buffer-or-name body…

このマクロはwith-output-to-temp-buffer (一時的な表示を参照)のようにbodyを評価して、そのフォームが生成したすべての出力をbuffer-nameで指定されるバッファーに挿入する(buffer-nameは関数help-bufferによりリターンされる値であることが多い)。このマクロは指定されたバッファーをHelpモードにして、ヘルプウィンドウのquitやスクロールする方法を告げるメッセージを表示する。これはユーザーオプションhelp-window-selectのカレント値が適切にセットされていればヘルプウィンドウの選択も行う。これはbody内の最後の値をリターンする。

Function: help-setup-xref item interactive-p

この関数は*Help*バッファー内のクロスリファレンスデータを更新する。このクロスリファレンスはユーザーが‘Back’ボタンか‘Forward’ボタン上でクリックした際のヘルプ情報の再生成に使用される。*Help*バッファーを使用するほとんどのコマンドは、バッファーをクリアーする前にこの関数を呼び出すべきである。item引数は(function . args)という形式であること。ここでfunctionは引数リストargsで呼び出されるヘルプバッファーを再生成する関数。コマンド呼び出しがinteractiveに行われた場合、interactive-p引数は非nil。この場合には*Help*バッファーの‘Back’ボタンにたいするitemのスタックはクリアーされる。

help-bufferwith-help-windowhelp-setup-xrefの使用例はdescribe-symbols exampleを参照してください。

Macro: make-help-screen fname help-line help-text help-map

このマクロは提供するサブコマンドのリストを表示するプレフィックスキーのように振る舞う、fnameという名前のヘルプコマンドを定義する。

呼び出された際、fnameはウィンドウ内にhelp-textを表示してからhelp-mapに応じてキーシーケンスの読み取りと実行を行う。文字列help-texthelp-map内で利用可能なバインディングを説明すること。

コマンドfnamehelp-textの表示をスクロールすることによる、自身のいくつかのイベントを処理するために定義される。fnameがこれらのスペシャルイベントのいずれかを読み取った際には、スクロールを行った後で他のイベントを読み取る。自身が処理する以外のイベントを読み取りそのイベントがhelp-map内にバインディングを有す際は、そのキーのバインディングを実行した後にリターンする。

引数help-linehelp-map内の候補の1行要約であること。Emacsのカレントバージョンでは、オプションthree-step-helptにセットした場合のみこの引数が使用される。

このマクロはC-h C-hにバインドされるコマンドhelp-for-help内で使用される。

User Option: three-step-help

この変数が非nilなら、make-help-screenで定義されたコマンドは最初にエコーエリア内に自身のhelp-line文字列を表示して、ユーザーが再度ヘルプ文字をタイプした場合のみ長いhelp-text文字列を表示する。


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

25.7 ドキュメントのグループ

Emacsは種々のグループにもとづいて関数をリストできます。たとえばstring-trimmapconcatなどは“string(文字列)”の関数ですが、M-x shortdoc RET string RETによって文字列を操作する関数の概要を得ることができます。

ドキュメンテーショングループはdefine-short-documentation-groupマクロにより作成されます。

Macro: define-short-documentation-group group &rest functions

関数グループとしてgroupを定義して、それらの関数の使用に関する短いサマリーを提供する。オプション引数functionsは要素が以下の形式であるようなリスト:

(func [keyword val]…)

以下のキーワードが認識される:

:eval

値は評価時の副作用をもたないフォームであること。このフォームはドキュメント内でprin1でプリントして使用されることになる(出力関数を参照)。しかしこのフォームが文字列ならそのまま挿入されてから、フォームを生成するためにreadされる。いずれのケースでも、その後にフォームは評価されて結果が使用される。たとえば:

:eval (concat "foo" "bar" "zot")
:eval "(make-string 5 ?x)"

は以下の結果になる:

(concat "foo" "bar" "zot")
⇒ "foobarzot"
(make-string 5 ?x)
⇒ "xxxxx"

(Lispフォームと文字列の両方を受け付けるのは、特定のフォーム表現が望まれるいくつかのケースにおいてプリントのコントロールを可能にするのが理由。この例では‘?x’が文字列に含まれていなければ‘120’としてプリントされるだろう。)

:no-eval

これは:evalと似ているが、フォームを評価しない点が異なる。この場合では何らかの類の:result要素が含まれている必要がある。

:no-eval (file-symlink-p "/tmp/foo")
:eg-result t
:no-eval*

:no-evalと同様だが、常に‘[it depends]’を結果として挿入する。たとえば:

:no-eval* (buffer-string)

は以下の結果になる:

(buffer-string)
→ [it depends]
:no-value

:no-evalと同様だが、対象となっている関数が明確に定義されたリターン値をもち、副作用のためだけに使用される際に用いられる。

:result

評価されないフォーム例の結果を出力するために使用される。

:no-eval (setcar list 'c)
:result c
:eg-result

評価されないフォーム例の結果例を出力するために使用される。たとえば:

:no-eval (looking-at "f[0-9]")
:eg-result t

は以下の結果になる:

(looking-at "f[0-9]")
eg. → t
:result-string
:eg-result-string

これら2つはそれぞれ:result:eg-resultと同じだが、そのまま挿入される。これは結果が読めなかったり、特定の形式が要求される際に有用:

:no-eval (find-file "/tmp/foo")
:eg-result-string "#<buffer foo>"
:no-eval (default-file-modes)
:eg-result-string "#o755"
:no-manual

その関数がマニュアルにドキュメントされていないことを示す。

:args

デフォルトではその関数の実際の引数リストが表示される。:argsが与えられたら、かわりにそれらが使用される。

:args (regexp string)

以下に非常に短い例を示す:

(define-short-documentation-group string
  "Creating Strings"
  (substring
   :eval (substring "foobar" 0 3)
   :eval (substring "foobar" 3))
  (concat
   :eval (concat "foo" "bar" "zot")))

1つ目の引数は定義するグループ名、その後に任意個数の関数説明が続く。

関数は任意個数のドキュメンテーショングループに所属できます。

このリストは関数説明に加えて、ドキュメントからセクションへの分割に使用される文字列要素ももつことができます。

Function: shortdoc-add-function group section elem

この関数によりLispパッケージは関数をグループに追加できる。elemはそれぞれ上述したような関数説明であること。groupは関数グループ、sectionは関数を挿入する関数グループのセクション。

groupが存在しなければ作成する。sectionが存在しなければ、その関数グループの最後に追加される。


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

26 ファイル

このチャプターでは検索、作成、閲覧、保存、その他ファイルとディレクトリーにたいして機能するEmacs Lispの関数と変数について説明します。その他のいくつかのファイルに関する関数についてはバッファー、バックアップとauto-save(自動保存)に関する関数についてはバックアップと自動保存で説明されています。

ファイル関数の多くはファイル名であるような引数を1つ以上受け取ります。このファイル名は文字列です。これらの関数のほとんどは関数expand-file-nameを使用してファイル名引数を展開するので、~は相対ファイル名(../と空文字列を含む)として正しく処理されます。ファイル名を展開する関数を参照してください。

加えて特定のmagicファイル名は特別に扱われます。たとえばリモートファイル名が指定された際、Emacsは適切なプロトコルを通じてネットワーク越しにファイルにアクセスします。Remote Files in The GNU Emacs Manualを参照してください。この処理は非常に低レベルで行われるので、特に注記されたものを除いて、このチャプターで説明するすべての関数がファイル名引数としてmagicファイル名を受け入れると想定しても良いでしょう。詳細はSee 特定のファイル名の“Magic”の作成を参照してください。

ファイルI/O関数がLispエラーをシグナルする際、通常はコンディションfile-errorを使用します(エラーを処理するコードの記述を参照)。ほとんどの場合にはオペレーティングシステムからロケールsystem-messages-localeに応じたエラーメッセージが取得されて、コーディングシステムlocale-coding-systemを使用してデコードされます(localeを参照)。


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

26.1 ファイルのvisit

ファイルのvisitとはファイルをバッファーに読み込むことを意味します。一度これを行うと、わたしたちはバッファーがファイルをvisit(訪問)していると言い、ファイルのことをバッファーのvisitされたファイルと呼んでいます。

ファイルとバッファーは2つの異なる事柄です。ファイルとは、(削除しない限り)コンピューター内に永続的に記録された情報です。一方バッファーとは編集セッションの終了(またはバッファーのkill)とともに消滅する、Emacs内部の情報です。あるバッファーがファイルをvistしているとき、バッファーにはファイルからコピーされた情報が含まれます。編集コマンドにより変更されるのはバッファー内のコピーです。バッファーへの変更によってファイルは変更されません。その変更を永続化するためにはバッファーを保存(save)しなければなりません。これは変更されたバッファーのコンテンツをファイルにコピーして書き戻すことを意味します。

ファイルとバッファーは異なるにも関わらず、人はバッファーという意味でファイルを呼んだり、その逆を行うことが多々あります。実際のところ、“わたしはまもなく同じ名前のファイルに保存するためのバッファーを編集している”ではなく、“わたしはファイルを編集している”と言います。人間がこの違いを明確にする必要は通常はありません。しかしコンピュータープログラムで対処する際には、この違いを心に留めておくのが良いでしょう。


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

26.1.1 ファイルをvisitする関数

このセクションではファイルのvisitに通常使用される関数を説明します。歴史的な理由によりこれらの関数は‘visit-’ではなく、‘find-’で始まる名前をもちます。バッファーをvisitしているファイルの名前へのアクセスや、visitされたファイル名から既存のバッファーを見つける関数および変数についてはバッファーのファイル名を参照してください。

ファイル内容を見たいものの変更したくない場合にはテンポラリーバッファー(temporary buffer: 一時的なバッファー)でinsert-file-contentsを使用例するのが、Lispプログラム内ではもっとも高速な方法です。時間を要するファイルのvisitは必要ありません。ファイルからの読み込みを参照してください。

Command: find-file filename &optional wildcards

このコマンドはファイルfilenameをvisitしているバッファーを選択する。visitしている既存のバッファーがあればそのバッファー、なければバッファーを新たに作成してそのバッファーにファイルを読み込む。これはそのバッファーをリターンする。

技術的な詳細を除けばfind-file関数のbodyは基本的には以下と等価:

(switch-to-buffer (find-file-noselect filename nil nil wildcards))

(ウィンドウ内のバッファーへの切り替えswitch-to-bufferを参照されたい。)

wildcardsが非nil (interactiveに呼び出された場合は常に真)の場合、find-filefilename内のワイルドカード文字を展開してマッチするすべてのファイルをvisitする。

find-fileがinteractiveに呼び出された際にはミニバッファー内でfilenameの入力を求める。

Command: find-file-literally filename

このコマンドはfind-fileが行うようにfilenameをvisitするが、フォーマット変換(ファイルのフォーマット変換を参照)、文字コード変換(コーディングシステムを参照)、EOL変換(End of line conversionを参照)を何も行わない。ファイルをvisitしているバッファーはunibyteになり、ファイル名とは無関係にバッファーのメジャーモードはFundamentalモードになる。ファイル内で指定されたファイルローカル変数(ファイルローカル変数を参照)は無視され、自動的な解凍とrequire-final-newlineによるファイル終端への改行追加(require-final-newlineを参照)も無効になる。

Emacsがすでにリテラリー(literally: 文字通り、そのまま)でない方法で同じファイルをvisitしているバッファーをもつ場合には、Emacsはその同じファイルをリテラリーにvisitせず、単に既存のバッファーに切り替えることに注意。あるファイルのコンテンツにたいして確実にリテラリーにアクセスしたければテンポラリーバッファーを作成して、insert-file-contents-literallyを使用してファイルのコンテンツを読み込むこと(ファイルからの読み込みを参照)。

Function: find-file-noselect filename &optional nowarn rawfile wildcards

これはファイルをvisitするすべての関数の要となる関数である。これはファイルfilenameをvisitしているバッファーをリターンする。望むならそのバッファーをカレントにしたり、あるウィンドウ内に表示することができるだろうがこの関数はそれを行わない。

関数は既存のバッファーがあればそれをリターンし、なければ新たにバッファーを作成してそれにファイルを読み込む。find-file-noselectが既存のバッファーを使用する際は、まずファイルがそのバッファーに最後にvisit、または保存したときから変更されていないことを検証する。ファイルが変更されていれば、この関数は変更されたファイルを再読み込みするかどうかをユーザーに尋ねる。ユーザーが‘yes’と応えたら、以前に行われたそのバッファー内での編集は失われる。

ファイルの読み込みはEOL変換、フォーマット変換(ファイルのフォーマット変換を参照)を含むファイルコンテンツのデコードを要する(コーディングシステムを参照)。wildcardsが非nilなら、find-file-noselectfilename内のワイルドカード文字を展開してマッチするすべてのファイルをvisitする。

この関数はオプション引数nowarnnilなら、さまざまな特殊ケースにおいて警告メッセージ(warning message)、および注意メッセージ(advisory message)を表示する。たとえば関数がバッファーの作成を必要とし、かつfilenameという名前のファイルが存在しなければ、エコーエリア内にメッセージ‘(New file)’を表示してそのバッファーを空のままに留める。

find-file-noselect関数は、ファイルを読み込んだ後に通常はafter-find-fileを呼び出す(visitのためのサブルーチンを参照)。この関数はバッファーのメジャーモードのセット、ローカル変数のパース、正にvisitしたファイルより新しいauto-saveファイルが存在する場合にユーザーへの警告を行い、find-file-hook内の関数を実行することにより終了する。

オプション引数rawfileが非nilならafter-find-fileは呼び出されず、失敗時にfind-file-not-found-functionsは呼び出されない。さらに非nil値のrawfileは、コーディングシステム変換とフォーマット変換を抑制する。

find-file-noselect関数は、通常はファイルfilenameをvisitしているバッファーをリターンする。しかしワイルドカードが実際に使用、展開された場合には、それらのファイルをvisitしているバッファーのリストをリターンする。

(find-file-noselect "/etc/fstab")
     ⇒ #<buffer fstab>
Command: find-file-other-window filename &optional wildcards

このコマンドはファイルfilenameをvisitしているバッファーを選択するが、選択されたウィンドウではない他のウィンドウでこれを行う。これは別の既存ウィンドウを使用したり、ウィンドウを分割するかもしれない。ウィンドウ内のバッファーへの切り替えlを参照のこと。

このコマンドがinteractiveに呼び出された際はfilenameの入力を求める。

Command: find-file-read-only filename &optional wildcards

このコマンドはfind-fileのようにファイルfilenameをvisitしているバッファーを選択するが、そのバッファーを読み取り専用(read-only)とマークする。関連する関数と変数については読み取り専用のバッファーを参照のこと。

このコマンドがinteractiveに呼び出された際はfilenameの入力を求める。

User Option: find-file-wildcards

この変数が非nilなら、各種find-fileコマンドはワイルドカード文字をチェックして、それらにマッチするすべてのファイルをvisitする(interactiveに呼び出されたときやwildcards引数が非nilのとき)。このオプションがnilなら、find-fileコマンドはそれらのwildcards引数を無視してワイルドカード文字を特別に扱うことは決してない。

User Option: find-file-hook

この変数の値はファイルがvisitされた後に呼び出される関数のリスト。ファイルのローカル変数指定は、(もしあれば)このフックが実行される前に処理されるだろう。フック関数実行時はそのファイルをvisitしているバッファーがカレントになる。

この変数はノーマルフックである。フックを参照のこと。

Variable: find-file-not-found-functions

この変数の値はfind-filefind-file-noselectが存在しないファイル名を受け取った際に呼び出される関数のリスト。存在しないファイルを検知するとfind-file-noselectは直ちにこれらの関数を呼び出す。これらのいずれかが非nilをリターンするまで、リスト順に関数を呼び出す。buffer-file-nameはすでにセットアップ済みである。

関数の値が使用されること、および多くの場合いくつかの関数だけが呼び出されるので、これはノーマルフックではない。

Variable: find-file-literally

このバッファーローカル変数が非nil値にセットされると、save-bufferはあたかもそのバッファーがリテラリー、つまり何の変換も行わずにファイルをvisitしていたかのように振る舞う。コマンドfind-file-literallyはこの変数のローカル値をセットするが、その他の等価な関数およびコマンドも、たとえばファイル終端への改行の自動追加を避けるためにこれを同様に行うことができる。この変数は恒久的にローカルなのでメジャーモードの変更による影響を受けない。


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

26.1.2 visitのためのサブルーチン

find-file-noselect関数は、2つの重要なサブルーチンcreate-file-bufferafter-find-fileを使用します。これらはユーザーのLispコードでも役に立つことがあります。このセクションではそれらの使い方について説明します。

Function: create-file-buffer filename

この関数はfilenameのvisitにたいして適切な名前のバッファーを作成してそれをリターンする。これはfilename (ディレクトリーを含まず)の名前がフリーならバッファー名にそれを使用し、フリーでなければ未使用の名前を取得するために‘<2>’のような文字列を付加する。バッファーの作成も参照のこと。uniquifyライブラリーはこの関数の結果に影響を与えることに注意。Uniquify in The GNU Emacs Manualを参照のこと。

注意されたい: create-file-bufferはファイルに新たなバッファーを関連付けない。バッファーの選択もせず、さらにデフォルトのメジャーモードも使用しない。

(create-file-buffer "foo")
     ⇒ #<buffer foo>
(create-file-buffer "foo")
     ⇒ #<buffer foo<2>>
(create-file-buffer "foo")
     ⇒ #<buffer foo<3>>

この関数はfind-file-noselectにより使用される。この関数自身はgenerate-new-bufferを使用する(バッファーの作成を参照)。

Function: after-find-file &optional error warn noauto after-find-file-from-revert-buffer nomodes

この関数はバッファーのメジャーモードをセットして、ローカル変数をパースする(Emacsがメジャーモードを選択する方法を参照)。これはfind-file-noselect、およびデフォルトのリバート関数(リバートを参照)により呼び出される。

ファイルが存在しないという理由によりファイルの読み込みがエラーを受け取るがディレクトリーは存在するなら、呼び出し側はerrorにたいして非nil値を渡すこと。この場合、after-find-fileは警告‘(New file)’を発する。より深刻なエラーにたいしては、呼び出し側は通常はafter-find-fileを呼び出さないこと。

warnが非nilなら、もしauto-saveファイルが存在して、かつそれがvisitされているファイルより新しければ、この関数は警告を発する。

noautoが非nilなら、それはAuto-Saveモードを有効や無効にしないことを告げる。以前にAuto-Saveモードが有効なら有効のまま留まる。

after-find-file-from-revert-bufferが非nilなら、それはこの関数がrevert-bufferから呼び出されたことを意味する。これに直接的な効果はないが、モード関数とフック関数の中には、この変数の値をチェックするものがいくつかある。

nomodesが非nilなら、それはバッファーのメジャーモードを変更せず、ファイル内のローカル変数指定を処理せず、find-file-hookを実行しないことを意味する。この機能はあるケースにおいてrevert-bufferにより使用される。

after-find-fileはリストfind-file-hook内のすべての関数を最後に呼び出す。


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

26.2 バッファーの保存

Emacs内でファイルを編集する際には、実際にはそのファイルをvisitしているバッファーにたいして編集を行っています。つまりファイルのコンテンツをバッファーにコピーしてそのコピーを編集しています。そのバッファーを変更してもバッファーを保存(save)するまでファイルは変更されません。保存とはバッファーのコンテンツをファイルにコピーすることを意味します。ファイルをvisitしていないバッファーでも、バッファーローカルんqwrite-contents-functionsの関数を使用することにより“saved(保存済み)”にすることができます。

Command: save-buffer &optional backup-option

この関数はバッファーが最後にvisitされたときや保存されたときから変更されていれば、カレントバッファーのコンテンツをバッファーによってvisitされているファイルに保存、変更されていなければ何も行わない。

save-bufferはバックアップファイルの作成に責任を負う。backup-optionは通常はnilであり、save-bufferはファイルのvisit以降、それが最初の保存の場合のみバックアップファイルを作成する。backup-optionにたいする他の値は、別の条件によるバックアップファイル作成を要求する:

  • 引数4は1つのC-u、引数64は3つのC-uを意味するので、save-bufferはバッファーの次回保存時にこのバージョンのファイルがバックアップされるようマークする。
  • 引数16は2つのC-u、引数64は3つのC-uを意味するので、save-buffer関数はそれを保存する前に前バージョンのファイルを無条件にバックアップする。
  • 引数0は無条件にバックアップファイルを何も作成しない
Command: save-some-buffers &optional save-silently-p pred

このコマンドはファイルをvisitしている変更されたバッファーのいくつかを保存する。これは通常は各バッファーごとにユーザーに確認を求める。しかしsave-silently-pが非nilなら、ユーザーに質問せずにファイルをvisitしているすべてのバッファーを保存する。

オプション引数predは、どのバッファーで確認を求めるか(またはsave-silently-pが非nilならどのバッファーで確認せずに保存するか)を制御する。

prednilなら、predのかわりにsave-some-buffers-default-predicateの値を使用することを意味する。その結果がnilならファイルをvisitしているバッファーにたいしてのみ確認を求めることを意味する。tならbuffer-offer-saveのバッファーローカル値がnilであるような非ファイルバッファー以外の特定のバッファーの保存も提案することを意味する(バッファーのkillを参照)。ユーザーが非ファイルバッファーの保存にたいして‘yes’と応えると保存に使用するファイル名の指定を求める。save-buffers-kill-emacs関数はpredにたいして値tを渡す。

述語がtnilのいずれでもなければ引数なしの関数であること。その関数はバッファーの保存を提案するか否かを決定するためにバッファーごとに呼び出される。これが特定のバッファーで非nil値をリターンすればバッファー保存の提案を行うことを意味する。

Command: write-file filename &optional confirm

この関数はカレントバッファーをファイルfilenameに書き込んで、バッファーがそのファイルをvisitしていることにして未変更とマークする。次にfilenameにもとづいてバッファー名をリネームする。バッファー名を一意にするため、必要なら‘<2>’のような文字列を付加する。処理のほとんどはset-visited-file-name (バッファーのファイル名を参照)、およびsave-bufferを呼び出すことにより行われる。

confirmが非nilなら、それは既存のファイルを上書きする前に確認を求めることを意味する。ユーザーがプレフィックス引数を与えなければinteractiveに確認が求められる。

filenameがディレクトリー名(ディレクトリーの名前を参照)、または既存のディレクトリーへのシンボリックリンクなら、write-fileはディレクトリーfilename内でvisitされているファイルの名前を使用する。そのバッファーがファイルをvisitしていなければ、かわりにバッファーの名前を使用する。

バッファーの保存によりフックがいくつか実行されます。これによりフォーマット変換も処理されます(ファイルのフォーマット変換を参照)。以下で説明するこれらのフックはバッファーのテキストをファイルに書き込むsave-buffer以外の他のプリミティブや関数、とりわけauto-saving (自動保存を参照)では実行されないことに注意してください。

Variable: write-file-functions

この変数の値はvisitされているファイルをバッファーに書き出す前に呼び出される関数のリスト。それらのうちのいずれかが非nilをリターンしたら、そのファイルは書き込み済みだと判断されて残りの関数は呼び出されないし、ファイルを書き込むための通常のコードも実行されない。

write-file-functions内の関数が非nilをリターンしたら、(それが適切なら)その関数はファイルをバックアップする責任を負う。これを行うには以下のコードを実行する:

(or buffer-backed-up (backup-buffer))

backup-bufferによりリターンされるファイルモードの値を保存して、(もし非nilなら)書き込むファイルのモードビットをセットしたいと思うかもしれない。これは正にsave-bufferが通常行うことである。Making Backup Filesを参照のこと。

write-file-functions内のフック関数は、データのエンコード(が望ましければ)にも責任を負う。これらは適切なコーディングシステムと改行規則(Lispでのコーディングシステムを参照)を選択してエンコード(明示的なエンコードとデコードを参照)を処理して、使用されていたコーディングシステム(エンコーディングとI/Oを参照)をlast-coding-system-usedにセットしなければならない。

バッファー内でこのフックをローカルにセットすると、バッファーはそのファイル、またはバッファーのコンテンツを取得したファイルに類するものに関連付けられる。このようにして変数は恒久的にローカルとマークされるので、メジャーモードの変更がバッファーローカルな値を変更することはない。その一方でset-visited-file-nameを呼び出すことによって変数はリセットされるだろう。これを望まなければ、かわりにwrite-contents-functionsを使用したいと思うかもしれない。

たとえこれがノーマルフックでなくても、このリストを操作するためにadd-hookremove-hookを使用することはできる。フックを参照のこと。

Variable: write-contents-functions

これは正にwrite-file-functionsと同様に機能するが、こちらはvisitしている特定のファイルやファイルの場所ではなくバッファーのコンテンツに関連するフックを意図しており、実際にはファイルをvisitしていないバッファーにたいして任意の保存処理を作成するために使用できる。そのようなフックは、この変数にたいするバッファーローカルなバインディングとして、通常はメジャーモードにより作成される。この変数はセットされた際には常に自動的にバッファーローカルになる。新たなメジャーモードへの切り替えは常にこの変数をリセットするが、set-visited-file-nameの呼び出しではリセットされない。

このフック内の関数のいずれかが非nilをリターンすると、そのファイルはすでに書き込み済みとみなされて、残りの関数は呼び出されずwrite-file-functions内の関数も呼び出されない。

(スペシャルモードのバッファーのような)ファイルをvisitしていないバッファーを保存するためにこのフックを利用する際には、その関数が正常に保存することに失敗してnil値をリターンすると、save-bufferがユーザーにたいしてバッファーを保存するファイルの入力を求めることに留意。これが望ましくなければエラーのレイズによる関数の失敗を考慮されたい。

User Option: before-save-hook

このノーマルフックはvisitしているファイルにバッファーが保存される前に実行される。保存が通常の方法で行われるか、あるいは上述のフックのいずれかで行われたかは問題ではない。たとえばcopyright.elプログラムは、ファイルの保存においてそれの著作権表示が今年であることを確認するためにこのフックを使用する。

User Option: after-save-hook

これはバッファーをvisitするファイルに保存後に実行されるノーマルフック。

User Option: file-precious-flag

この変数が非nilなら、save-bufferは保存ファイルがもつ名前のかわりに一時的な名前で新たなファイルに書き込み、エラーがないことが明確になった後にファイルを意図する名前にリネームすることによって保存中のI/Oエラーから防御する。この手順は無効なファイルが原因となるディスク容量逼迫のような問題を防ぐ。

副作用としてバックアップ作成にコピーが必要になる。リネームかコピーのどちらでバックアップするか?を参照のこと。しかし同時にこの高価なファイル保存によって保存したファイルと他のファイル名との間のすべてのハードリンクは切断される。

いくつかのモードは特定のバッファーにおいてこの変数に非nilのバッファーローカル値を与える。

User Option: require-final-newline

この変数はファイルが改行で終わらないように書き込まれるかどうかを決定する。変数の値がtなら、save-bufferはバッファーの終端に改行がなければ暗黙理に改行を追加する。値がvisitなら、Emacsはファイルをvisitした直後に不足している改行を追加する。値がvisit-saveなら、Emacsはvisitと保存の両方のタイミングで不足している改行を追加する。その他の非nil値にたいしては、そのようなケースが生じるたびに改行を追加するかどうかsave-bufferがユーザーに尋ねる。

変数の値がnilならsave-bufferは改行を追加しない。デフォルト値はnilだが、特定のバッファーでこれをtにセットするメジャーモードも少数存在する。

バッファーのファイル名の関数set-visited-file-nameも参照されたい。


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

26.3 ファイルからの読み込み

ファイルのコンテンツをバッファーにコピーするためには関数insert-file-contentsを使用します(マークをセットするのでLispプログラム内でコマンドinsert-fileは使用してはならない)。

Function: insert-file-contents filename &optional visit beg end replace

この関数はファイルfilenameのコンテンツをカレントバッファーのポイントの後に挿入する。これは絶対ファイル名と挿入だれたデータの長さからなるリストをリターンする。filenameが読み取り可能なファイルの名前でなければエラーがシグナルされる。

この関数は定義されたファイルフォーマットに照らしてファイルのコンテンツをチェックして、適切ならそのコンテンツの変換、およびリストafter-insert-file-functions内の関数の呼び出しも行う。ファイルのフォーマット変換を参照のこと。通常はリストafter-insert-file-functions内のいずれかの関数がEOL変換を含むファイルコンテンツのデコードに使用されるコーディングシステム(コーディングシステムを参照)を判断する。しかしファイルにnullバイトが含まれる場合には、デフォルトではコード変換なしでvisitされる。inhibit-null-byte-detectionを参照のこと。

visitが非nilなら、この関数は追加でそのバッファーを未変更とマークしてそのバッファーのさまざまなフィールドをセットアップして、バッファーがファイルfilenameをvisitしているようにする。これらのフィールドにはバッファーがvisitしたファイルの名前、最終保存したファイルのmodtimeが含まれる。これらの機能はfind-file-noselectにより使用されるものであり、恐らくあなた自身が使用するべきではない。

begendが非nilなら、それらはファイル挿入範囲を指定するバイトオフセット数値であること。この場合、visitnilでなければならない。たとえば、

(insert-file-contents filename nil 0 500)

これはファイルの先頭500文字(バイト)でコードされた文字を挿入する。

begendが偶然マルチバイトシーケンス文字の中間だった場合には、Emacsお文字コード規約によりバッファーに1つ以上の8ビット文字(いわゆる“rawバイト”)が挿入されるだろう(文字セットを参照)。この方法でバッファーの一部にたいして読み取りを行いたければ、この関数の呼び出し前後に適切な値をcoding-system-for-readにバインドして(単一の操作にたいするコーディングシステムの指定を参照)、境界にあるrawバイトをチェックするとともに、これらのバイトシーケンス全体を読み取り有効な文字に変換して戻すLisp関数を記述することをお勧めする。

引数replaceが非nilなら、それはバッファーのコンテンツ(実際にはアクセス可能な範囲)をファイルのコンテンツで置き換えることを意味する。これは単にバッファーのコンテンツを削除してファイル全体を挿入するより優れている。なぜなら、(1)マーカー位置を維持して、(2)undoリストに配置するデータも少ないからである。

replacevisitbegnilならinsert-file-contentsで(FIFOやI/Oデバイスのような)スペシャルファイルの読み取りが可能。とはいえバッファーに(潜在的には)無制限のデータが挿入されることを防ぐために(たとえば/dev/urandomからのデータ挿入時)、これらのファイルにたいしては通常はend引数を使用するべきだろう。

Function: insert-file-contents-literally filename &optional visit beg end replace

この関数はinsert-file-contentsのように機能するが、ファイル内の各バイトを必要なら8ビット文字へ変換するために個別に処理する点が異なる。またafter-insert-file-functionsを実行せずフォーマットのデコード、文字コード変換、自動解凍、...などを行わない。

他のプログラムがファイルを読めるように他プロセスにファイル名を渡したければ関数file-local-copyを使用します。特定のファイル名の“Magic”の作成を参照してください。


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

26.4 ファイルへの書き込み

関数append-to-filewrite-regionを使用することによってディスク上のファイルにバッファーのコンテンツやバッファーの一部を直接書き込むことができます。visitされているファイルに書き込むためにこれらの関数を使用しないでください。これによってvisitにたいするメカニズムが混乱するかもしれません。

Command: append-to-file start end filename

この関数はカレントバッファー内でstartendによるリージョンのコンテンツをファイルfilenameの終端に追加する。そのファイルが存在しなければ作成する。この関数はnilをリターンする。

filenameの書き込みや作成ができなければエラーがシグナルされる。

Lispから呼び出した場合、この関数は以下と完全に等価:

(write-region start end filename t)
Command: write-region start end filename &optional append visit lockname mustbenew

この関数はカレントバッファー内のstartendで区切られたリージョンをfilenameで指定されたファイルに書き込む。

startnilなら、このコマンドはバッファーのコンテンツ全体(アクセス可能な範囲だけではない)をファイルに書き込んでendは無視する。

startが文字列なら、write-regionはバッファーのテキストではなくその文字列を追加する。その場合にはendは無視される。

appendが非nilなら、指定されたテキストが(もしあれば)既存のファイルコンテンツに追加される。appendが数字ならwrite-regionはファイル開始位置からそのバイトオフセットをseekしてデータをそこに書き込む。

mustbenewが非nilの場合には、filenameが既存ファイルの名前ならwrite-regionは確認を求める。mustbenewがシンボルexclなら、ファイルがすでに存在する場合にはwrite-regionは確認を求めるかわりにエラーfile-already-existsをシグナルする。たとえwrite-regionが通常はシンボリックリンクをフォローして、もしシンボリックリンクが壊れていればpointed-toファイル(訳注: ファイルへのハードリンクにたいするポインター)を作成するとしても、mustbenewexclならシンボリックリンクをフォローしない。

mustbenewexclのときは、存在するファイルのテストに特別なシステム機能を使用する。少なくともローカルディスク上のファイルにたいしては、Emacsがファイルを作成する前にEmacsに通知せずに他のプログラムが同じ名前のファイルを作成することはありえない。

visittなら、Emacsはバッファーとファイルの関連付けを設定してそのバッファーがそのファイルをvictiする。またカレントバッファーにたいする最終ファイル変更日時にfilenameをセットして、そのバッファーを未変更としてマークする。この機能はsave-bufferにより使用されるが、おそらくあなた自身が使用するべきではないだろう。

visitが文字列なら、それはvisitするファイルの名前を指定する。この方法を使えば、そのバッファーが別のファイルをvisitしていると記録しつつ1つのファイル(filename)にデータを書き込むことができる。引数visitはエコーエリアに使用される他にファイルのロックにも使用され、visitbuffer-file-nameに格納される。この機能はfile-precious-flagの実装に使用される。自分が何をしているか本当にわかっているのでなければこれを使用してはならない。

オプション引数locknameが非nilなら、それはロックとアンロックの目的に使用するfilenamevisitをオーバーライドするファイル名を指定する。

関数write-regionは書き込むデータをbuffer-file-formatによって指定される適切なファイルフォーマットに変換しするとともに、リストwrite-region-annotate-functions内の関数の呼び出しも行う。ファイルのフォーマット変換を参照のこと。

write-regionは通常はエコーエリア内にメッセージ‘Wrote filename’を表示する。visittnil、文字列のいずれでもない場合、こまたはEmacsがbatchモード(batchモードを参照)で処理中ならこのメッセージは抑制される。この機能は内部的な目的のためにユーザーが知る必要がないファイルを使用したり、Emacsがbatchモードで処理中に有用である。

Variable: write-region-inhibit-fsync

この変数の値がnilならwrite-regionはファイル書き込み後にシステムコールfsyncを使用する。これはたとえEmacsを低速化するとしても、電源喪失時のデータ損失リスクを軽減する。値がtならEmacsはfsyncを使用しない。デフォルト値はEmacsが対話的に実行されていればnil、batchモードで実行時にはtファイルと二次媒体を参照のこと。

Macro: with-temp-file file body…

with-temp-fileマクロは一時バッファー(temporary buffer)をカレントバッファーとしてbodyフォームを評価して、最後にそのバッファーのコンテンツをfileに書き込む。これは終了時に一時バッファーをkillして、with-temp-fileフォームの前にカレントだったバッファーをリストアする。その後にbody内の最後のフォームの値をリターンする。

throwやエラーによる異常なexit(abnormal exit)でも、カレントバッファーはリストアされる(非ローカル脱出を参照)。

with-temp-buffer (Current Bufferを参照)と同様に、このマクロが使用する一時バッファーではフックkill-buffer-hookkill-buffer-query-functions (バッファーのkillを参照)、buffer-list-update-hook (バッファーリストを参照)は実行されない。


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

26.5 ファイルのロック

2人のユーザーが同時に同じファイルを編集する際には、彼らはおそらく互いに干渉しあうでしょう。Emacsはファイルが変更される際にファイルロック(file lock)を記録することにより、このような状況の発生を防ぎます。そしてEmacsは他のEmacsジョブにロックされているファイルをvisitしているバッファーへの変更の最初の試みを検知して、ユーザーに何を行うべきかを尋ねます。このファイルロックの実態は、編集中のファイルと同じディレクトリーに格納される特別な名前をもつシンボリックリンクです。この名前はバッファーのファイル名に.#を前置することにより構築されます。シンボリックリンクのターゲットはuser@host.pid:bootという形式になります。ここでuserはカレントのユーザー名( user-login-nameかより得)、hostはEmacsを実行中のホスト( system-nameより取得)、pidはEmacsのプロセスID、bootは最後のブートからの経過時間です。ブート時刻が利用できなければ:bootは省略されます。(シンボリックリンクをサポートしないファイルシステムでは、user@host.pid:bootという形式を構築するか割りに通常のファイルが使用される)。

ファイルのアクセスにNFSを使用する際には、可能性は小さいものの他のユーザーと同じファイルを同時にロックするかもしれません。これが発生すると2人のユーザーが同時にファイルを変更することが可能になりますが、それでもEmacsは2番目に保存するユーザーにたいして警告を発するでしょう。たファイルをvisitしているバッファーでディスク上でファイルの変更を検知することにより、ある種の同時編集を捕捉できます。バッファーの変更時刻を参照してください。

Function: file-locked-p filename

この関数はファイルfilenameがロックされていなければnilをリターンする。このEmacsプロセスによりロックされていればt、他のEmacsジョブによりロックされている場合はロックしたユーザーの名前をリターンする。

(file-locked-p "foo")
     ⇒ nil
Function: lock-buffer &optional filename

この関数はカレントバッファーが変更されていればファイルfilenameをロックする。引数filenameのデフォルトはカレントバッファーがvisitしているファイル。カレントバッファーがファイルをvisitしていない、バッファーが変更されていない、またはcreate-lockfilesnilなら何もしない。

Function: unlock-buffer

この関数はカレントバッファーが変更されていればバッファーによりvisitされているファイルをアンロックする。バッファーが変更されていなければ、そのファイルをロックしてはならないのでこの関数は何もしない。カレントバッファーがファイルをvisitしていない、またはファイルがロックされていなければこの関数は何もしない。この関数はdisplay-warning呼び出しによってファイルシステムエラーを処理して、それ以外の場合にはエラーを無視する。

User Option: create-lockfiles

この変数がnilならEmacsはファイルをロックしない。

User Option: lock-file-name-transforms

デフォルトでは、Emacsはロックするファイルと同じディレクトリーにロックファイルを作成する。この変数をカスタマイズしてこれを変更できる。これはauto-save-file-name-transformsと同じ構文をもつ(自動保存を参照)。たとえばEmacsにすべてのロックファイルを/var/tmp/に書き込ませるには、以下のようにすればよい:

(setq lock-file-name-transforms
      '(("\\`/.*/\\([^/]+\\)\\'" "/var/tmp/\\1" t)))
Function: ask-user-about-lock file other-user

この関数はユーザーがfileの変更を試みたが、それが名前other-userのユーザーにロックされていたとき呼び出される。この関数のデフォルト定義は何を行うかユーザーに尋ねる関数。この関数がリターンする値はEmacsが次に何を行うかを決定する:

  • tはそのファイルのロックを奪うことを意味する。その場合にはother-userはロックを失い、そのユーザーがファイルを編集することができる。
  • nilはロックを無視して、とにかくユーザーがファイルを編集できるようにすることを意味する。
  • この関数はかわりにエラーfile-lockedをシグナルする。この場合には、ユーザーが行おうとしていた変更は行われない。

    このエラーにたいするエラーメッセージは以下のようになる:

    error→ File is locked: file other-user
    

    ここでfileはファイル名、other-userはそのファイルのロックを所有するユーザーの名前。

望むなら他の方法で判定を行う独自バージョンでask-user-about-lock関数を置き換えることができる。

User Option: remote-file-name-inhibit-locks

変数remote-file-name-inhibit-lockstをセットして、リモートロックファイルの作成を抑止できる。

Command: lock-file-mode

これはインタラクティブに呼び出されるコマンドであり、カレントバッファーでcreate-lockfilesのローカル値を切り替える。


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

26.6 ファイルの情報

このセクションではファイル(またはディレクトリーやシンボリックリンク)に関してファイルが読み込み可能か、書き込み可能か、あるいはファイルのサイズのようなさまざまなタイプの情報を取得する関数を説明します。これらの関数はすべて引数にファイルの名前を受け取ります。特に注記した場合を除きこれらの引数には既存のファイルを指定する必要があり、ファイルが存在しなければエラーをシグナルします。

スペースで終わるファイル名には気をつけてください。いくつかのファイルシステム(特にMS-Windows)では、ファイル名の末尾の空白文字は暗黙かつ自動的に無視されます。


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

26.6.1 アクセシビリティのテスト

以下の関数はファイルにたいする読み取り、書き込み、実行のパーミッションをテストします。これらの関数は明示しない限りボリックリンクをフォローします。ファイル種別の区別を参照してください。

いくつかのオペレーティングシステムではACL(Access Control Lists: アクセス制御リスト)のような機構を通じて、より複雑なアクセスパーミッションセットが指定できます。それらのパーミッションにたいする問い合わせやセットの方法については拡張されたファイル属性を参照してください。

Function: file-exists-p filename

この関数はファイル名filenameが存在しているようならtをリターンする。これはファイルが読み取り可能である必要はなく、ファイルの属性を調べることが恐らく可能なこと意味する(Unixやその他のPOSIXシステム類ではファイルが存在してファイルを含むディレクトリーの実行パーミッションをもつ場合にはファイル自体のパーミッションに関わらずt)。

ファイルが存在しない、またはファイルが存在するかどうかの判断に問題があるようなら、この関数はnilをリターンする。

空文字列であるようなファイル名はカレントバッファーのデフォルトディレクトリーから相対的なファイル(絶対ファイル名と相対ファイル名を参照)と解釈されるので、引数に空文字列を指定してfile-exists-pを呼び出すとそのバッファーのデフォルトディレクトリーについてレポートされることになる。

ディレクトリーはファイルなので、ディレクトリーが与えられるとfile-exists-ptをリターンするかもしれない。しかしfile-exists-pはシンボリックリンクをフォローするので、リンクのターゲットが存在する場合のみシンボリックリンク名にたいしてtをリターンする。Lispプログラムにおいて既存のファイルとしてターゲットが存在しない壊れたシンボリックリンク(dangling symlinks)を考慮する必要がある場合には、file-exists-pではなくfile-attributes (ファイルの属性を参照)を使うこと。

Function: file-readable-p filename

この関数はfilenameという名前のファイルが存在して、それを読み取ることが可能ならt、それ以外はnilをリターンする。

Function: file-executable-p filename

この関数は、filenameという名前のファイルが存在して、それを実行することが可能ならtをリターンする。それ以外はnilをリターンする。Unixやその他のPOSIXシステム類ではファイルがディレクトリーなら実行パーミッションはディレクトリー内のファイルの存在と属性をチェックできるので、ファイルのモードが許せばオープンできることを意味する。

Function: file-writable-p filename

この関数はfilenameという名前のファイルが書き込み可能か作成可能可能ならt、それ以外はnilをリターンする。ファイルが存在してそれに書き込むことができるならファイルは書き込み可能。ファイルは存在しないが親ディレクトリーが存在して、そのディレクトリーに書き込むことができるなら書き込み可能。

以下の例では、fooは親ディレクトリーが存在しないので、たとえユーザーがそのディレクトリーを作成可能であってもファイルは書き込み可能ではない。

(file-writable-p "~/no-such-dir/foo")
     ⇒ nil
Function: file-accessible-directory-p dirname

この関数はファイルとしての名前がdirnameであるようなディレクトリー内にある既存のファイルをオープンするパーミッションをもつ場合はt、それ以外(そのようなディレクトリーが存在しない場合)はnilをリターンする。dirnameの値はディレクトリー名(/foo/など)、または名前がディレクトリー(最後のスラッシュがない/fooなど)であるようなファイル。

たとえば以下では/foo/内の任意のファイルを読み取る試みはエラーになると推測できる:

(file-accessible-directory-p "/foo")
     ⇒ nil
Macro: with-existing-directory body…

このマクロはbody実行前にdefault-directoryが存在するディレクトリーにバインドされていることを保証する。すでにdefault-directoryが存在していれば優先し、存在していなければ何処か別のディレクトリーを使用する。このマクロはたとえば存在するディレクトリー内での実行を要する外部コマンド呼び出し時に有用かもしれない。選択されるディレクトリーへの書き込み権限は保証しない。

Function: access-file filename string

この関数はfilenameが読み取り可能ならnil、それ以外ならstringをエラーメッセージのテキストに使用してエラーをシグナルする。

Function: file-ownership-preserved-p filename &optional group

この関数はファイルfilenameを削除後に新たに作成してもファイルの所有者が変更されずに維持されるようならtをリターンする。これは存在しないファイルにたいしてもtをリターンする。

オプション引数groupが非nilなら、この関数はファイルのグループが変更されないこともチェックする。

この関数はシンボリックリンクをフォローしない。

Function: file-modes filename &optional flag

この関数はfilenameモードビット(mode bits)をリターンする。これは読み取り、書き込み、実行パーミッションを要約する整数。この関数はシンボリックリンクを許容する。ファイルが存在しなければリターン値はnil

モードビットの説明はFile permissions in The GNU Coreutils Manualを参照のこと。たとえば最下位ビットが1ならそのファイルは実行可能、2ビット目が1なら書き込み可能、...となる。設定できる最大の値は4095(8進の7777)であり、これはすべてのユーザーが読み取り、書き込み、実行のパーミッションをもち、他のユーザーとグループにたいしてSUIDビット、およびstickyビットがセットされる。

デフォルトでは、この関数はシンボリックリンクをフォローする。しかしオプション引数flagがシンボルnofollowなら、この関数はシンボリックリンクのfilenameをフォローしない。これはどこか別の場所でうっかりモードビットを取得してしまうことを防ぎ、file-attributesとの整合性を保つ助けとなり得る(ファイルの属性を参照)。

これらのパーミッションのセットに使用されるset-file-modes関数についてはファイルの名前と属性の変更を参照のこと。

(file-modes "~/junk/diffs" 'nofollow)
     ⇒ 492               ; 10進整数
(format "%o" 492)
     ⇒ "754"             ; 8進に変換した値

(set-file-modes "~/junk/diffs" #o666 'nofollow)
     ⇒ nil

$ ls -l diffs
-rw-rw-rw- 1 lewis lewis 3063 Oct 30 16:00 diffs

MS-DOSにたいする注意: MS-DOSでは実行可能であることをを表すようなファイルのモードビットは存在しない。そのためfile-modesはファイル名が.com.bat.exeなどのような標準的な実行可能な拡張子のいずれかで終わる場合にはファイルを実行可能であると判断する。POSIX標準の‘#!’署名で始まるshellスクリプトやPerlスクリプトも実行可能と判断される。POSIXとの互換性のためにディレクトリーも実行可能と報告される。file-attributes (ファイルの属性を参照)もこれらの慣習にしたがう。


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

26.6.2 ファイル種別の区別

このセクションではディレクトリー、シンボリックリンク、および通常ファイルのようなさまざまな種類のファイルを区別する方法を説明します。

シンボリックリンクは通常はそれが出現した場合には常にフォローされます。たとえばファイル名a/b/cを解釈するためにシンボリックリンクかもしれないaa/ba/b/cはすべてフォローされて、リンクターゲット自身がシンボリックリンクなら再帰的にフォローされるかもしれません。しかしいくつかの関数は最後のファイル名(この例ではa/b/c)ではシンボリックリンクをフォローしません。そのような関数のことをシンボリックリンク非フォロー(not follow symbolic links)と呼びます。

ファイルfilenameがシンボリックリンクならfile-symlink-p関数はリンクをフォローせずに、かわりにリンクターゲットを文字列としてリターンする(リンクターゲット文字列はターゲットの完全な絶対ファイル名である必要はない。リンクが指すのが完全なファイル名かどうかを判断するのは簡単な処理ではない。以下参照)。

file-symlink-pはファイルfilenameがシンボリックリンクではないか、あるいは存在しなかったりシンボリックリンクかどうか判断するのに問題がある場合にはnilをリターンする。

この関数の使用例をいくつか示す:

(file-symlink-p "not-a-symlink")
     ⇒ nil
(file-symlink-p "sym-link")
     ⇒ "not-a-symlink"
(file-symlink-p "sym-link2")
     ⇒ "sym-link"
(file-symlink-p "/bin")
     ⇒ "/pub/bin"

3つ目の例では関数はsym-linkをリターンするが、たとえそれ自体がシンボリックリンクであってもリンク先の解決を行わないことに注意。これは関数がシンボリックリンクをフォローしない、すなわちシンボリックリンクをフォローする処理はファイル名の最後のコンポーネントには適用されないからである。

この関数がリターンするのはそのシンボリックリンクに何が記録されているかを示す文字列であり、それにディレクトリー部分が含まれているかどうかは構わない。この関数は完全修飾されたファイル名を生成するためにリンクターゲットを展開しないし、リンクターゲットが絶対ファイル名でなければ、(もしあっても)filename引数のディレクトリー部分は使用しない。以下に例を示す:

(file-symlink-p "/foo/bar/baz")
     ⇒ "some-file"

ここでは、たとえ与えられた/foo/bar/bazが完全修飾されたファイル名であるにも関わらずその結果は異なり、実際には何のディレクトリー部分ももたない。some-file自体がシンボリックリンクかもしれないので、単にその前に先行ディレクトリーを追加することはできず、絶対ファイル名を生成するために単にexpand-file-name (ファイル名を展開する関数を参照)を使用することもできないからである。

この理由により、あるファイルがシンボリックリンクか否かという単一の事実よりも多くを判定する必要がある場合にこの関数が有用であることは稀である。実際にリンクターゲットのファイル名が必要なら、本当の名前で説明するfile-chase-linksfile-truenameを使用すること。

Function: file-directory-p filename

この関数はfilenameが既存のディレクトリー名ならtfilenameがディレクトリー名ではない、あるいはディレクトリーかどうかの判断に問題がある場合にはnilをリターンする。この関数はシンボリックリンクをフォローする。

(file-directory-p "~rms")
     ⇒ t
(file-directory-p "~rms/lewis/files-ja.texi")
     ⇒ nil
(file-directory-p "~rms/lewis/no-such-file")
     ⇒ nil
(file-directory-p "$HOME")
     ⇒ nil
(file-directory-p
 (substitute-in-file-name "$HOME"))
     ⇒ t
Function: file-regular-p filename

この関数はファイルfilenameが存在して、それが通常ファイル(ディレクトリー、名前付きパイプ、端末、その他I/Oデバイス以外)ならtをリターンする。filenameが存在しない、通常ファイルではない、あるいは通常ファイルかどうかの判断に問題がある場合にはnilをリターンする。この関数はシンボリックリンクをフォローする。


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

26.6.3 本当の名前

ファイルの実名(truename)とは、全階層においてシンボリックリンクを残らずフォローした後に名前コンポーネントに出現する‘.’と‘..’を除いて簡略化した名前のことです。これはそのファイルにたいする正規名(canonical name)の一種です。ファイルが常に一意な実名をもつ訳ではありません。あるファイルにたいする異なる実名の個数は、そのファイルにたいするハードリンクの個数と同じです。しかし実名はシンボリックリンクによる名前の変動を解消するのに有用です。

Function: file-truename filename

この関数はファイルfilenameの実名をリターンする。引数が絶対ファイル名でなければ、この関数は最初にdefault-directoryにたいしてこれを展開する。

この関数は環境変数を展開しない。これを行うのはsubstitute-in-file-nameのみ。Definition of substitute-in-file-nameを参照のこと。

名前コンポーネントに出現する‘..’に先行するシンボリックリンクリンクをフォローする必要がある場合には直接と間接を問わず、expand-file-nameを呼び出す前にfile-truenameを呼び出すこと。そうしないと‘..’の直前にある名前コンポーネントは、file-truenameが呼び出される前の簡略化により取り除かれてしまう。expand-file-name呼び出しの必要を無くすために、file-truenameexpand-file-nameが行うのと同じ方法で‘~’を扱う。Functions that Expand Filenamesを参照のこと。

シンボリックリンクのターゲットがリモートファイル名の構文をもつ場合には、file-truenameはそれをクォートしてリターンする。Functions that Expand Filenamesを参照のこと。

この関数はfilenameで始まるシンボリックリンクを、シンボリックリンクではない名前のファイル名までフォローして、そのファイル名をリターンする。この関数は親ディレクトリーの階層にあるシンボリックリンクをフォローしない

limitに数を指定するとその数のリンクを追跡した後、この関数はたとえそれが依然としてシンボリックリンクであってもそれをリターンする。

file-chase-linksfile-truenameの違いを説明するために、/usr/fooがディレクトリー/home/fooへのシンボリックリンク、/home/foo/helloが(少なくともシンボリックリンクではない)通常ファイル、または存在しないファイルだとします。この場合には以下のようになります:

(file-chase-links "/usr/foo/hello")
     ;; 親ディレクトリーのリンクはフォローしない
     ⇒ "/usr/foo/hello"
(file-truename "/usr/foo/hello")
     ;; /homeはシンボリックリンクではないと仮定
     ⇒ "/home/foo/hello"
Function: file-equal-p file1 file2

この関数はファイルfile1file2の名前が同じファイルならtをリターンする。これはリモートファイル名も適切な方法で処理することを除いて実名の比較と似ている。file1file2が存在しなければリターン値は不定。

Function: file-name-case-insensitive-p filename

ファイル名やその一部にたいして文字列としての比較を要する場合には、背景にあるファイルシステムが非caseセンシティブ(case-insensitive: 大文字小文字を区別しない)かどうかを知ることが重要になる。この関数はファイルfilenameが非caseセンシティブなファイルシステムにあればtをリターンする。MS-DOSとMS-Windowsでは常にtをリターンする。CygwinとmacOSでは非caseセンシティブかもしれないので、実行時テストによりcaseセンシティブ性の判定を試みる。テストで決定されなければCygwinならt、macOSならnilをリターンする。

この関数は現在のところMS-DOS、MS-Windows、Cygwin、macOS以外のプラットフォームでは常にnilをリターンする。これはSamba共有やNFSマウントされたWindowsボリュームのようにマウントされたファイルシステムのcaseセンシティブ性は検知しない。リモートホストでは‘smb’メソッドにたいしてはtとみなす。

Function: vc-responsible-backend file

この関数は与えられたfileにたいしてVCバックエンドが責任を負うかどうかを判断する。たとえばemacs.cがGitでトラック(track: 追跡)されていれば(vc-responsible-backend "emacs.c")は‘Git’をリターンする。fileがシンボリックリンクならvc-responsible-backendはシンボリックリンクを解決せずに、シンボリックリンクにたいするバックエンドが報告されることに注意。fileが参照するファイルのバックエンドVCを取得するには、file-chase-linksのようなシンボリックリンク解決用の関数でfileをラップすること。

(vc-responsible-backend (file-chase-links "emacs.c"))

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

26.6.4 ファイルの属性

このセクションではファイルの詳細な情報を取得する関数について説明します。それらの情報にはファイルの所有者やグループの番号、ファイル名の個数、inode番号、サイズやアクセス日時、変更日時が含まれます。

Function: file-newer-than-file-p filename1 filename2

この関数はファイルfilename1がファイルfilename2より新しければtをリターンする。filename1が存在しなければnilfilename1は存在するがfilename2が存在しなければtをリターンする。

以下の例では、aug-19の書き込みが19日、aug-20の書き込みが20日、ファイルno-fileは存在しないものとする。

(file-newer-than-file-p "aug-19" "aug-20")
     ⇒ nil
(file-newer-than-file-p "aug-20" "aug-19")
     ⇒ t
(file-newer-than-file-p "aug-19" "no-file")
     ⇒ t
(file-newer-than-file-p "no-file" "aug-19")
     ⇒ nil
Function: file-has-changed-p filename tag

この関数は最後に呼び出されて以降にfilenameのタイムスタンプが変更されていれば非nilをリターンする。何らかのfilenameにたいして初めて呼び出された際には、そのファイルの最終修整時刻とサイズを記録して、filenameが存在すれば非nilをリターンする。これ以降に同じfilenameで呼び出されると、カレントのタイムスタンプとサイズを記録されたものと比較してタイムスタンプかサイズのいずれか(あるいは両方)が異なる場合のみ非nilをリターンする。これはあるファイルが変更されたら常に再読み込みするようなLispプログラムで役に立つ。オプション引数tag (シンボル)を指定して呼び出すと、サイズと最終修整時刻の比較は同一tagにたいする呼び出しに限定される。

Function: file-attributes filename &optional id-format

この関数はファイルfilenameの属性(attributes)のリストをリターンする。オープンできないファイルが指定された場合は、nilをリターンする。指定されたファイルが存在しなければnilをリターンする。この関数はシンボリックリンクをフォローしない。オプション引数id-formatは属性UIDGID(以下参照)にたいして望ましいフォーマットを指定する。有効な値は'string'integer。デフォルトは'integerだが、わたしたちはこれの変更を計画しているので、リターンされるUIDGIDを使用する場合にはid-formatにたいして非nil値を指定すること。

GNUプラットフォームではこの関数はロックファイル処理時はアトミックである。別のプロセスによりファイルシステムが同時に変更された場合には、この関数は変更の前か後のいずれかのファイル属性をリターンする。それ以外ならこの関数はアトミックではなく競合状態を検知したらnil、または以前とカレントが混ざったファイル属性をリターンするかもしれない。

このリスト内の要素にアクセスするためにアクセッサ関数が提供される。このアクセッサ以下の要素の記述とともに示される。

リストの要素は順に:

  1. ディレクトリーにたいしてはt、シンボリックリンクにたいしては文字列(リンクされる名前)、テキストファイル(file-attribute-type)にたいしてはnil
  2. そのファイルがもつ名前の個数(file-attribute-link-number)。ハードリンクとして知られる代替え名は関数add-name-to-fileを使用して作成できる(ファイルの名前と属性の変更を参照)。
  3. ファイルのUIDであり通常は文字列file-attribute-user-id。しかし名前をもつユーザーに対応しなければ値は整数。
  4. 同様にファイルのGID (file-attribute-group-id)。
  5. Lispのタイムスタンプによる最終アクセス時刻(file-attribute-access-time)。タイムスタンプはcurrent-time (時刻を参照)の形式であり、ファイルシステムのタイムスタンプの精度に切り詰められる。たとえばFATベースのいくつかのファイルシステムでは最終アクセスの日付だけが記録されるので、この時刻には常に最終アクセス日の真夜中が保持されることに注意。
  6. Lispのタイムスタンプによる最終変更時刻(file-attribute-modification-time)。これはファイルのコンテンツが変更された最終時刻。
  7. Lispのタイムスタンプによるステータスの最終変更時刻(file-attribute-status-change-time。上記参照)。これはファイルのアクセスモードビット、所有者とグループ、およびファイルにたいしてファイルのコンテンツ以外にファイルシステムが記録するその他の情報にたいする最終変更時刻。
  8. ファイルのバイトサイズ(file-attribute-size)。
  9. ls -l’で表示されるような10個の文字、またはダッシュからなる文字列で表されるファイルのモード(file-attribute-modes)。
  10. 後方互換のために提供される不定値。
  11. ファイルのinode番号であり非負の整数(file-attribute-inode-number)。
  12. そのファイルがあるデバイスのファイルシステムの識別子(file-attribute-device-number)を表す整数、あるいは2つの整数からなるコンスセル。後者のコンスセルはリモートとローカルのファイルシステムを区別するために、リモートファイルにたいして使われる場合がある。

ファイルのinodeとデバイスを合わせれば、そのシステム上の2つの任意のファイルを区別するために十分な情報が得られる(この2つの属性の両方に等しい値を2つのファイルがもつことはできない)。ファイルを一意に識別するこのタプル(tuple: 組)は、file-attribute-file-identifierによってリターンされる。

たとえば以下はfiles-ja.texiのファイル属性:

(file-attributes "files-ja.texi" 'string)
     ⇒  (nil 1 "lh" "users"
          (20614 64019 50040 152000)
          (20000 23 0 0)
          (20614 64555 902289 872000)
          122295 "-rw-rw-rw-"
          t 6473924464520138
          1014478468)

この結果を解釈すると:

nil

ディレクトリーでもシンボリックリンクでもない。

1

(カレントデフォルトディレクトリー内で名前files-ja.texiは)単一の名前をもつ。

"lh"

名前"lh"のユーザーにより所有される。

"users"

名前"users"のグループ。

(20614 64019 50040 152000)

最終アクセス時刻は2012年10月23日のUTC(協定世界時)で20:12:03.050040152(current-time-listnilならタイムスタンプは(1351023123050040152 . 1000000000)になる)。

(20000 23 0 0)

最終修整時刻は2001年7月15日のUTCで08:53:43.000000000(current-time-listnilならタイムスタンプは(1310720023000000000 . 1000000000)になる)。

(20614 64555 902289 872000)

最後のステータス変更時刻は2012年10月23日のUTCで20:20:59.902289872(current-time-listnilならタイムスタンプは(1351023659902289872 . 1000000000)になる)。

122295

バイト長は122295バイト(しかしマルチバイトシーケンスが含まれていたり、EOLフォーマットがCRLFなら122295文字は含まれないかもしれない)。

"-rw-rw-rw-"

所有者、グループ、その他にたいして読み取り、書き込みアクセスのモードをもつ。

t

単なるプレースホルダーであり何の情報ももたない。

6473924464520138

inode番号は6473924464520138。

1014478468

ファイルシステムのデバイス番号は1014478468。

この関数はファイルfilenameがもつ名前(ハードリンク)の個数をリターンする。ファイルが存在しなければ、この関数はnilをリターンする。シンボリックリンクはリンク先のファイルの名前とは判断されないので、この関数に影響しないことに注意。この関数はシンボリックリンクをフォローしない。

$ ls -l foo*
-rw-rw-rw- 2 rms rms 4 Aug 19 01:27 foo
-rw-rw-rw- 2 rms rms 4 Aug 19 01:27 foo1

(file-nlinks "foo")
     ⇒ 2
(file-nlinks "doesnt-exist")
     ⇒ nil

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

26.6.5 拡張されたファイル属性

いくつかのオペレーティングシステムでは、それぞれのファイルを任意の拡張ファイル属性(extended file attributes)に関連付けることができます。現在のところEmacsは拡張ファイル属性のうち2つの特定セット(ACL: Access Control List、およびSELinuxコンテキスト)にたいする問い合わせと設定をサポートします。これらの拡張ファイル属性は、前のセクションで議論したUnixスタイルの基本的なパーミッションより洗練されたファイルアクセス制御を強制するために、いくつかのシステムで利用されます。

ACLとSELinuxについての詳細な解説はこのマニュアルの範囲を超えています。わたしたちの目的のためには、それぞれのファイルはACL (ACLベースのファイル制御システムの元でACLのプロパティを指定)および/またはSELinuxコンテキスト (SELinuxシステムの元でSELinuxのプロパティを指定)に割り当てることができるという理解で問題ないでしょう。

Function: file-acl filename

この関数はファイルfilenameにたいするACLをリターンする。ACLにたいする正確なLisp表現は不確定(かつ将来のEmacsバージョンで変更され得る)だが、これはset-file-aclが引数aclにとる値と同じである(ファイルの名前と属性の変更を参照)。

根底にあるACL実装はプラットフォームに固有である。EmacsはGNU/LinuxとBSDではPOSIX ACLインターフェイスを使用して、MS-WindowsではネイティブのファイルセキュリティAPIをPOSIX ACLインターフェイスでエミュレートする。

ACLがサポートされていない、あるいはファイルが存在しなければリターン値はnil

Function: file-selinux-context filename

この関数はファイルfilenameのSELinuxコンテキストを(user role type range)という形式のリストでリターンする。リストの要素はそのコンテキストのユーザー、ロール、タイプ、レンジを文字列として表す値である。これらの実際の意味についての詳細はSELinuxのドキュメントを参照のこと。リターン値はset-file-selinux-contextcontext引数で受け取るのと同じ形式(ファイルの名前と属性の変更を参照)。

SELinuxをサポートしない、あるいはファイルが存在しなければリターン値は(nil nil nil nil)

Function: file-extended-attributes filename

この関数はEmacsが認識するファイルfilenameの拡張属性をalistでリターンする。現在のところこの関数はACLとSELinuxの両方を取得するための便利な方法としての役目を果たす。他のファイルに同じファイルアクセス属性を適用するためにリターンされたalistを2つ目の引数としてset-file-extended-attributesを呼び出すことができる(ファイルの名前と属性の変更を参照)。

要素のうちの1つは(acl . acl)で、aclfile-aclがリターンするのと同じ形式。

他の要素は(selinux-context . context)で、contextfile-selinux-contextがリターンするのと同じ形式。


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

26.6.6 標準的な場所へのファイルの配置

このセクションではディレクトリーのリスト(パス(path))からファイルを検索したり、標準の実行可能ファイル用ディレクトリーから実行可能ファイルを検索する方法を説明します。

ユーザー固有の設定ファイル(configuration file)の検索については標準的なファイル名の関数locate-user-emacs-fileを参照してください。

Function: locate-file filename path &optional suffixes predicate

この関数はpathで与えられるディレクトリーリスト内でfilenameという名前のファイルを検索して、suffixes内のサフィックスの検索を試みる。そのようなファイルが見つかったらファイルの絶対ファイル名(絶対ファイル名と相対ファイル名を参照)、それ以外はnilをリターンする。

オプション引数suffixesは検索時にfilenameに追加するファイル名サフィックスのリストを与える。locate-fileは検索するディレクトリーごとにそれらのサフィックスを試みる。suffixesnil("")なら、サフィックスなしでfilenameだけがそのまま使用される。suffixesの典型的な値はexec-suffixes (サブプロセスを作成する関数を参照)、load-suffixesload-file-rep-suffixes、および関数get-load-suffixes (ロードでの拡張子を参照)。

実行可能プログラムを探すときはexec-path (サブプロセスを作成する関数を参照)、Lispファイルを探すときはload-path (ライブラリー検索を参照)がpathの典型的な値である。filenameが絶対ファイル名ならpathの効果はないが、サフィックスにたいするsuffixesは依然として試行される。

オプション引数predicateが非nilなら、それは候補ファイルが適切かどうかテストする述語関数を指定する。述語関数には単一の引数として候補ファイル名が渡される。predicatenilか省略なら述語としてfile-readable-pを使用する。file-executable-pfile-directory-pなど、その他の有用な述語についてはファイル種別の区別を参照のこと。

この関数は通常はディレクトリーをスキップするので、ディレクトリーを探したければ、predicate関数がディレクトリーにたいして確実にdir-okをリターンすること。たとえば:

(locate-file "html" '("/var/www" "/srv") nil
             (lambda (f) (if (file-directory-p f) 'dir-ok)))

互換性のためにpredicateにはexecutablereadablewritableexists、またはこれらシンボルの1つ以上のリストも指定できる。

Function: executable-find program &optional remote

この関数はprogramという名前の実行可能ファイルを検索して、その実行可能ファイルの絶対ファイル名と、もしあればファイル名の拡張子も含めてリターンする。ファイルが見つからなければnilをリターンする。この関数はexec-path内のすべてのディレクトリーを検索して、exec-suffixes内のすべてのファイル名拡張子の検索も試みる(サブプロセスを作成する関数を参照)。

remotenil、かつ非default-directoryがリモートディレクトリーなら、programは各リモートホスト上で検索される。


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

26.7 ファイルの名前と属性の変更

このセクションの関数はファイルのリネーム、コピー、削除やリンク、モードをセットします。これらの関数は処理に失敗すると、通常は失敗の理由を記述するシステム依存のエラーメッセージを報告するfile-errorエラーをシグナルします。ファイルが存在しないために失敗すると、かわりにfile-missingエラーをシグナルします。

性能的な理由によりオペレーティングシステムはこれらの関数により行われた変更を2次記憶装置に書き込むかわりに、キャッシュしたりエイリアスするかもしれません。ファイルと二次媒体を参照してください。

引数newnameをもつ関数では、それがディレクトリー名ならsource名の非ディレクトリー部分が追加されたかのように扱われます。ディレクトリー名は通常は‘/’で終端されます(ディレクトリーの名前を参照)。たとえばoldnamea/b/cnewnamed/e/f/ならd/e/f/cであるかのように処理されます。newnameがディレクトリー名ではなくディレクトリーであるような名前なら、この特別な扱いは適用されません。たとえばnewnamed/e/fがディレクトリーでも、そのまま処理されます。

newnameという引数をもつ関数では、newnameという名前のファイルが既に存在する場合には、その挙動が引数ok-if-already-existsの値に依存します。

  • ok-if-already-existsnilならfile-already-existsエラーがシグナルされる。
  • ok-if-already-existsが数字なら確認を求める。
  • ok-if-already-existsが他の値なら確認なしで古いファイルを置き換える。
Command: add-name-to-file oldname newname &optional ok-if-already-exists

この関数は、oldnameという名前のファイルにnewnameという名前を追加で与える。これはnewnameという名前がoldnameにたいする新たなハードリンクになることを意味する。

newnameがシンボリックリンクなら、リンクが指すディレクトリーエントリーではなく、シンボリックリンクリンクのディレクトリーエントリーが置き換えられる。oldnameがシンボリックリンクなら、この関数はリンクをフォローする可能性があるが、GNUプラットフォームではリンクをフォローしない。oldnameがディレクトリーなら、たとえ処理を正常に行ってツリー構造ではないファイルシステムを作成できる古い様式の非GNUプラットフォームのスーパーユーザーでも、この関数は通常は失敗する。

以下の例の最初の部分では2つのファイルfoofoo3をリストする。

$ ls -li fo*
81908 -rw-rw-rw- 1 rms rms 29 Aug 18 20:32 foo
84302 -rw-rw-rw- 1 rms rms 24 Aug 18 20:31 foo3

ここでadd-name-to-fileを呼び出してハードリンクを作成して再度ファイルをリストする。このリストには1つのファイルにたいして2つの名前foofoo2が表示される。

(add-name-to-file "foo" "foo2")
     ⇒ nil

$ ls -li fo*
81908 -rw-rw-rw- 2 rms rms 29 Aug 18 20:32 foo
81908 -rw-rw-rw- 2 rms rms 29 Aug 18 20:32 foo2
84302 -rw-rw-rw- 1 rms rms 24 Aug 18 20:31 foo3

最後に以下を評価する:

(add-name-to-file "foo" "foo3" t)

そしてファイルを再度リストする。今度は1つのファイルにたいして3つの名前foofoo2foo3がある。foo3の古いコンテンツは失われた。

(add-name-to-file "foo1" "foo3")
     ⇒ nil

$ ls -li fo*
81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo
81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo2
81908 -rw-rw-rw- 3 rms rms 29 Aug 18 20:32 foo3

この関数は1つのファイルにたいして複数の名前をもつことが許されないオペレーティングシステムでは無意味である。いくつかのシステムでは、かわりにファイルをコピーすることにより複数の名前を実装している。

ファイルの属性file-nlinksも参照のこと。

Command: rename-file filename newname &optional ok-if-already-exists

このコマンドはfilenamenewnameにリネームする。

filenamefilenameとは別に追加の名前をもつ場合には、それらは自身の名前をもち続ける。実際のところadd-name-to-fileで名前newnameを追加してからfilenameを削除するのは、瞬間的な遷移状態とエラーの処理、ディレクトリーとシンボリックリンクを別とすればリネームと同じ効果がある。

このコマンドはシンボリックリンクをフォローしない。filenameがシンボリックリンクなら、このコマンドはリンクが指すファイルではなくシンボリックリンクをリネームする。newnameがシンボリックリンクなら、リンクが指すディレクトリーエントリーではなくリンクのディレクトリーエントリーを置き換える。

filenamenewnameが同じディレクトリーエントリー(親ディレクトリーが同じでありそのディレクトリー内で同じ名前を与える)なら、このコマンドは何もしない。それ以外ならfilenamenewnameが同一のファイルを命名する場合には、このコマンドはPOSIX準拠システムでは何も行わなず、いくつかの非POSIXシステムではfilenameを削除する。

newnameがすでに存在する場合にはoldnameがディレクトリーなら空のディレクトリー、非ディレクトリーなら非ディレクトリーでなければならない。

Command: copy-file oldname newname &optional ok-if-already-exists time preserve-uid-gid preserve-extended-attributes

このコマンドはファイルoldnamenewnameにコピーする。oldnameが通常のファイルでなければエラーをシグナルする。newnameがディレクトリーなら最後の名前コンポーネントを保持するようにディレクトリーの中にoldnameをコピーする。

この関数はnewnameを作成するために壊れたシンボリックリンクをフォローしない点を除いて、シンボリックリンクをフォローする。

timeが非nilなら、この関数は新たなファイルにたいして古いファイルと同じ最終変更時刻を与える(これはいくつかの限られたオペレーティングシステムでのみ機能する)。時刻のセットでエラーが発生すると、copy-filefile-date-errorエラーをシグナルする。インタラクティブに呼び出された場合には、プレフィックス引数はtimeにたいして非nil値を指定する。

引数preserve-uid-gidnilなら、新たなファイルのユーザーとグループの所有権の決定をオペレーティングシステムに委ねる(通常はEmacsを実行中のユーザー)。preserve-uid-gidが非nilなら、そのファイルのユーザーとグループの所有権のコピーを試みる。これはいくつかのオペレーティングシステムで、かつそれを行うための正しいパーミッションをもつ場合のみ機能する。

オプション引数preserve-permissionsが非nilなら、この関数はoldnameのファイルモード(または“パーミッション”)、同様にACL(Access Control List)とSELinuxコンテキストをnewnameにコピーする。ファイルの情報を参照のこと。

それ以外では、newnameが既存ファイルならファイルモードは変更されず、新たに作成された場合はデフォルトのファイルパーミッション(以下のset-default-file-modesを参照)によりマスクされる。どちらの場合でもACLやSELinuxコンテキストはコピーされない。

このコマンドはlinknameという名前でtargetにたいするシンボリックリンクを作成する。これはシェルコマンドと‘ln -s target linkname’と似ている。targetは文字列としてのみ扱われる。既存ファイルの名前である必要はない。ok-if-already-existsが整数ならインタラクティブな使用を意味しており、target文字列内の先頭の‘~’は展開されて、先頭の‘/:’は取り除かれる。

targetが相対ファイル名なら結果となるシンボリックリンクはシンボリックリンクを含むディレクトリーにたいして相対的に解釈される。絶対ファイル名と相対ファイル名を参照のこと。

targetlinknameの両方がリモートファイル構文をもち、かつ両者のリモート識別が等価なら、シンボリックリンクはtargetのローカルファイル名部分を指す。

この関数はシンボリックリンクをサポートしないシステムでは利用できない。

Command: delete-file filename &optional trash

このコマンドはファイルfilenameを削除する。ファイルが複数の名前をもつ場合には他の名前で存在し続ける。filenameがシンボリックリンクならdelete-fileはシンボリックリンクだけを削除してターゲットは削除しない。

ファイルが存在しない、または削除できない場合には適切な種類のfile-errorエラーがシグナルされる(GNU/およびその他のPOSIX準拠システムではファイルのディレクトリーが書き込み可能ならファイルは削除可能)。

オプション引数trashが非nil、かつ変数delete-by-moving-to-trashが非nilなら、このコマンドはファイルを削除するかわりにシステムのTrash(ゴミ箱)にファイルを移動する。Miscellaneous File Operations in The GNU Emacs Manualを参照のこと。インタラクティブに呼び出された際には、プレフィックス引数がなければtrasht、それ以外はnil

ディレクトリーの作成・コピー・削除delete-directoryも参照のこと。

Command: set-file-modes filename mode &optional flag

この関数は、filenameファイルモード (またはパーミッション)をmodeにセットする。

この関数はデフォルトではシンボリックリンクをフォローする。しかしオプション引数flagがシンボルnofollowの場合には、filenameがシンボリックリンクでもこの関数はシンボリックリンクをフォローしない。これによりどこか別の場所で意図せずモードビットを変更してしまうことを防げるかもしれない。シンボリックリンクでのモードビット変更をサポートしないプラットフォームでは、この関数はfilenameがシンボリックリンクかつflagnofollowの際にエラーをシグナルする。

非インタラクティブに呼び出された場合には、modeは整数でなければならない。その整数の下位12ビットだけが使用される。ほとんどのシステムでは意味があるのは下位9ビットのみ。modeを入力するLisp構文を使用できる。たとえば、

(set-file-modes "myfile" #o644 'nofollow)

これはそのファイルにたいして所有者による読み取りと書き込み、グループメンバーによる読み取り、その他のユーザーによる読み取り可能であることを指定する。モードビットの仕様の説明はFile permissions in The GNU Coreutils Manualを参照のこと。

インタラクティブに呼び出されると、moderead-file-modes(以下参照)を使用してミニバッファーから読み取られる。この場合にはユーザーは整数、またはパーミッションをシンボルで表現する文字列をタイプできる。

ファイルのパーミッションをリターンする関数file-modesについてはアクセシビリティのテストを参照のこと。

Function: set-default-file-modes mode

この関数はEmacsおよびEmacsのサブプロセスが新たに作成するファイルにデフォルトのパーミッションをセットする。Emacsにより作成されたすべてのファイルはこれらのパーミッション、およびそれらのサブセットとなるパーミッションをもつ(デフォルトファイルパーミッションが実行を許可しても、write-regionは実行パーミッションを付与しないだろう)。GNUやその他のPOSIX準拠システムでは、デフォルトのパーミッションは‘umask’の値のビット単位の補数で与えられる。すなわち引数modeでセットされた各ビットはEmacsが作成するファイルのデフォルトパーミッション内ではリセットされる。

引数modeは上記のset-file-modesと同様、パーミッションを指定する整数であること。意味があるのは下位9ビットのみ。

デフォルトのファイルパーミッションは、既存ファイルの変更されたバージョンを保存する際は効果がない。ファイルの保存では既存のパーミッションが保持される。

Macro: with-file-modes mode body…

このマクロは新たなファイルにたいするデフォルトのパーミッションを一時的にmodes (値は)set-file-modesにたいする値と同様)にセットしてフォームbodyを評価する。終了時には元にデフォルトのファイルノパーミッションをリストアして、bodyの最後のフォームの値をリターンする。

これはたとえばプライベートファイルの作成に有用である。

Function: default-file-modes

この関数はデフォルトのファイルのパーミッションを整数でリターンする。

Function: read-file-modes &optional prompt base-file

この関数はミニバッファーからファイルモードのビットのセットを読み取る。1つ目のオプション引数promptは非デフォルトのプロンプトを指定する。2つ目のオプション引数base-fileはユーザーが既存ファイルのパーミッションに相対的なモードビット指定をタイプした場合に、この関数がリターンするモードビッの元となる権限をもつファイルの名前を指定する。

ユーザー入力が8進数で表される場合には、この関数はその数字をリターンする。それが"u=rwx"のようなモードビットの完全なシンボル指定なら、この関数はfile-modes-symbolic-to-numberを使用して、それを等価な数字に変換して結果をリターンする。"o+g"のように相対的な指定なら、その指定の元となるパーミッションはbase-fileのモードビットから取得される。base-fileが省略またはnilなら、この関数は元となるモードビットとして0を使用する。完全指定と相対指定は"u+r,g+rx,o+r,g-w"のように組み合わせることができる。ファイルモード指定の説明はFile permissions in The GNU Coreutils Manualを参照のこと。

Function: file-modes-symbolic-to-number modes &optional base-modes

この関数はmodes内のシンボルによるファイルモード指定を等価な整数に変換する。シンボル指定が既存ファイルにもとづく場合には、オプション引数base-modesからそのファイルのモードビットが取得される。その引数が省略またはnilなら、0(すべてのアクセスが許可されない)がデフォルトになる。

Function: file-modes-number-to-symbolic modes

この関数はmodes内の数値ファイルモード指定を等価な文字列形式に変換する。 This function converts a numeric file mode specification in modes into the equivalent string form. この関数がリターンする文字列はシェルコマンドのls -lfile-attributesが生成する文字列と同じであり、file-modes-symbolic-to-numberやシェルコマンドのchmodが受け付けるシンボリックフォーマットとは異なる

Function: set-file-times filename &optional time flag

この関数はfilenameのアクセス時刻と変更時刻をtimeにセットする。時刻が正しくセットされればt、それ以外はnilがリターン値となる。timeのデフォルトはカレント時刻でありtime値でなければならない(時刻を参照)。

この関数はデフォルトではシンボリックリンクをフォローする。しかしオプション引数flagがシンボルnofollowの場合には、filenameがシンボリックリンクでもフォローしない。これはどこか別の場所でファイル時刻をうっかり変更してしまうことを防ぐのに役立つかもしれない。シンボリックリンクの時刻変更をサポートしないプラットフォームでは、この関数はfilenameがシンボリックリンクかつflagnofollowの際にはエラーをシグナルする。

Function: set-file-extended-attributes filename attribute-alist

この関数はfilenameにたいしてEmacsが認識する拡張ファイル属性をセットする。2つ目の引数attribute-alistfile-extended-attributesがリターンするalistと同じ形式であること。属性のセットが成功したらt、それ以外はnilがリターン値となる。拡張されたファイル属性を参照のこと。

Function: set-file-selinux-context filename context

この関数はfilenameにたいするSELinuxセキュリティコンテキストにcontextをセットする。context引数は各要素が文字列であるような(user role type range)というリストであること。拡張されたファイル属性を参照のこと。

この関数はfilenameのSELinuxコンテキストのセットに成功したらtをリターンする。コンテキストがセットされなかった場合(SELinuxが無効、またはEmacsがSELinuxサポートなしでコンパイルされた場合等)にはnilをリターンする。

Function: set-file-acl filename acl

この関数はfilenameにたいするACLにaclをセットする。acl引数は関数file-aclがリターンするのと同じ形式であること。拡張されたファイル属性を参照のこと。

この関数はfilenameのACLのセットに成功したらt、それ以外はnilをリターンする。


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

26.8 ファイルと二次媒体

Emacsがファイルを変更した後、その後に生じた電源喪失と媒体エラーにより行った変更が保存されないことには2つの理由があります。1つ目は一方または他方のファイルが後で変更されるまで、オペレーティングシステムは書き込まれたデータを2次ストレージのどこかに格納済みのデータにエイリアスすることです。媒体エラーにより2次ストレージ上のコピーだけが失われると、ファイルは両方とも失われるでしょう。2つ目はオペレーティングシステムがデータを2次ストレージに即座に書き込まないかもしれないので、電源喪失時にはデータが失われます。

これらはいずれも適切なファイルシステムの設定により回避され得る類のエラーですが、そのようなシステムは通常はより高価であるか非効率的です。より典型的なシステムでは媒体エラーに備えて異なるデバイスにファイルをコピーでき、電源喪失にたいしては変数write-region-inhibit-fsyncnilをセットしてwrite-regionを使用できます。ファイルへの書き込みを参照してください。


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

26.9 ファイルの名前

ファイルは一般的に名前で参照され、これはEmacsでも他と同様です。Emacsではファイル名は文字列で表現されます。ファイルを操作する関数はすべてファイル名引数に文字列を期待します。

ファイル自体の操作に加えて、Emacs Lispプログラムでファイル名を処理する必要(ファイル名の一部を取得して関連するファイル名構築にその一部を使用する等)がしばしばあります。このセクションではファイル名を扱う方法を説明します。

このセクションの関数は実際にファイルにアクセスする訳ではないので、既存のファイルやディレクトリーを参照しないファイル名を処理できます。

MS-DOSやMS-Windowsでは、(実際にファイルを操作する関数と同様)これらの関数はMS-DOSとMS-Windowsのファイル名構文を受け入れます。この構文はPOSIX構文のようにバックスラッシュでコンポーネントを区切りますが、これらの関数は常にPOSIX構文をリターンします。これによりPOSIX構文でファイル名を指定するLispプログラムが変更なしですべてのシステムで正しく機能することが可能になります19


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

26.9.1 ファイル名の構成要素

オペレーティングシステムはファイルをディレクトリーにグループ化します。あるファイルを指定するためには、ディレクトリーとそのディレクトリー内でのファイルの名前を指定しなければなりません。それゆえEmacsはファイル名をディレクトリー名パートと非ディレクトリー(またはディレクトリー内ファイル名)パートという、2つの主要パートから判断します。どちらのパートも空の場合があり得ます。これら2つのパートを結合することによって元のファイル名が再構築されます。20

ほとんどのシステムでは最後のスラッシュ(MS-DOSとMS-Windowsではバックスラッシュも許される)までのすべてがディレクトリーパートです。残りが非ディレクトリーパートです。

ある目的のために、非ディレクトリーパートはさらに正式名称(the name proper)とバージョン番号に細分されます。ほとんどのシステムでは、名前にバージョン番号をもつのはバックアップファイルだけです。

Function: file-name-directory filename

この関数はfilenameのディレクトリーパートをディレクトリー名(ディレクトリーの名前を参照)としてリターンする。filenameがディレクトリーパートを含まなければnilをリターンする。

GNUや他のPOSIX準拠ixシステムでは、この関数がリターンする文字列は常にスラッシュで終わる。MS-DOSではコロンで終わることもあり得る。

(file-name-directory "lewis/foo")  ; GNUの例
     ⇒ "lewis/"
(file-name-directory "foo")        ; GNUの例
     ⇒ nil
Function: file-name-nondirectory filename

この関数はfilenameの非ディレクトリーパートをリターンする。

(file-name-nondirectory "lewis/foo")
     ⇒ "foo"
(file-name-nondirectory "foo")
     ⇒ "foo"
(file-name-nondirectory "lewis/")
     ⇒ ""
Function: file-name-sans-versions filename &optional keep-backup-version

この関数は、任意のファイルバージョン番号、バックアップバージョン番号、末尾のチルダを取り除いたfilenameをリターンする。

keep-backup-versionが非nilなら、ファイルシステムなどが認識するような真のファイルバージョン番号は破棄されるが、バックアップバージョン番号は保持される。

(file-name-sans-versions "~rms/foo.~1~")
     ⇒ "~rms/foo"
(file-name-sans-versions "~rms/foo~")
     ⇒ "~rms/foo"
(file-name-sans-versions "~rms/foo")
     ⇒ "~rms/foo"
Function: file-name-extension filename &optional period

この関数はfilenameから、もしあればすべてのバージョン番号とバックアップ番号を取り除いた後の、終端の拡張子(extension)をリターンする。ファイル名の拡張子とは最後の名前コンポーネント(からすべてのバージョン番号とバックアップ番号を取り去った後)の最後の‘.’に後続するパートのこと。

この関数はfooのような拡張子のないファイル名にたいしてはnilfoo.のようなnull拡張子にたいしては""をリターンする。ファイル名の最終コンポーネントが‘.’で始まる場合には、その‘.’は拡張子の開始とはみなされない。したがって.emacsの拡張子は‘.emacs’ではなくnil

periodが非nilなら、拡張子を区切るピリオドもリターン値に含まれる。その場合には、もしfilenameが拡張子をもたなければリターン値は""

Function: file-name-with-extension filename extension

この関数は拡張子にextensionをセットしたfilenameをリターンする。すでにドットがあればextensionの先頭のドットは取り除く。たとえば:

(file-name-with-extension "file" "el")
     ⇒ "file.el"
(file-name-with-extension "file" ".el")
     ⇒ "file.el"
(file-name-with-extension "file.c" "el")
     ⇒ "file.el"

filenameextensionが空、あるいはfilenameがディレクトリー(つまりdirectory-name-pが非nilをリターンする)のようなら、この関数はエラーとなることに注意。

Function: file-name-sans-extension filename

この関数は、もしあればfilenameから拡張子を除いてリターンする。もしバージョン番号やバックアップ番号があるなら、ファイルが拡張子をもつ場合のみそれを削除する。たとえば、

(file-name-sans-extension "foo.lose.c")
     ⇒ "foo.lose"
(file-name-sans-extension "big.hack/foo")
     ⇒ "big.hack/foo"
(file-name-sans-extension "/my/home/.emacs")
     ⇒ "/my/home/.emacs"
(file-name-sans-extension "/my/home/.emacs.el")
     ⇒ "/my/home/.emacs"
(file-name-sans-extension "~/foo.el.~3~")
     ⇒ "~/foo"
(file-name-sans-extension "~/foo.~3~")
     ⇒ "~/foo.~3~"

最後の2つの例の‘.~3~’は拡張子ではなくバックアップ番号であることに注意。

Function: file-name-base filename

これはfile-name-sans-extensionfile-name-nondirectoryを組み合わせた関数。たとえば、

(file-name-base "/my/home/foo.c")
    ⇒ "foo"
Function: file-name-split filename

この関数はファイル名をコンポーネントに分割する。これを適切なディレクトリー区切りを用いてstring-joinの逆を行う関数とみなすことができる。たとえば、

(file-name-split "/tmp/foo.txt")
    ⇒ ("" "tmp" "foo.txt")
(string-join (file-name-split "/tmp/foo.txt") "/")
    ⇒ "/tmp/foo.txt"

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

26.9.2 絶対ファイル名と相対ファイル名

ファイルシステム内のすべてのディレクトリーはルートディレクトリーから開始されるツリーを形成します。このツリーのルートから開始されるすべてのディレクトリー名によりファイル名を指定でき、それを絶対(absolute)ファイル名と呼びます。デフォルトディレクトリーからの相対的なツリー中の位置でファイルを指定することもでき、それらは相対(relative)ファイル名と呼ばれます。GNUや他のPOSIX準拠システムでは‘~’で開始されるすべてのファイル名は‘/’で始まる絶対ファイル名(abbreviate-file-nameを参照)に展開されますが、相対ファイル名は展開されません。。MS-DOSとMS-Windowsでは絶対ファイル名はスラッシュ、バックスラッシュ、またはドライブ指定‘x:/’で始まります。ここでxドライブ文字(drive letter)です。

Function: file-name-absolute-p filename

この関数はファイルfilenameが絶対ファイル名ならt、それ以外はnilをリターンする。ファイル名の最初のコンポーネントが‘~’か‘~user’ (userは有効なログイン名)なら絶対ファイル名とみなす。以下の例では‘rms’という名前のユーザーは存在するが、‘nosuchuser’という名前のユーザーは存在しないものとする。

(file-name-absolute-p "~rms/foo")
     ⇒ t
(file-name-absolute-p "~nosuchuser/foo")
     ⇒ nil
(file-name-absolute-p "rms/foo")
     ⇒ nil
(file-name-absolute-p "/user/rms/foo")
     ⇒ t

相対ファイル名が与えられた場合には先頭に‘~’があれば展開して、expand-file-nameを使用して絶対ファイル名に変換できます(ファイル名を展開する関数を参照)。この関数は絶対ファイル名を相対ファイル名に変換します:

Function: file-relative-name filename &optional directory

この関数はdirectory(絶対ディレクトリー名かディレクトリーファイル名)から相対的なファイルと仮定して、filenameと等価な相対ファイル名のリターンを試みる。directoryが省略かnilなら、カレントバッファーのデフォルトディレクトリーがデフォルト。

絶対ファイル名がデバイス名で始まるオペレーティングシステムがいくつか存在する。そのようなシステムでは、2つの異なるデバイス名から開始されるfilenameは、directoryにもといた等価な相対ファイル名をもたない。この場合には、file-relative-nameは絶対形式でfilenameをリターンする。

(file-relative-name "/foo/bar" "/foo/")
     ⇒ "bar"
(file-relative-name "/foo/bar" "/hack/")
     ⇒ "../foo/bar"

空文字列であるようなファイル名は、カレントバッファーのデフォルトディレクトリーを意味しています。


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

26.9.3 ディレクトリーの名前

ディレクトリー名(directory name)とは、ある文字列が何らかのファイルを命名する場合にはディレクトリーを命名する文字列のことです。ディレクトリーは実際にはファイルの一種なので、ファイル名(ディレクトリーファイル名と呼ばれる)をもち、これはディレクトリー名と関係はあるものの通常は等価ではありません(これはPOSIXの通常の用語と完全に同一ではない)。同じ実体にたいするこれら2つの異なる名前は構文的な変換により関連付けられます。GNUや他のPOSIXシステムではことは単純です。ディレクトリー名の最後が‘/’でなければ、ディレクトリーファイル名に‘/’を追加してディレクトリー名を取得できます。MS-DOSではこの関連付けはより複雑です。

ディレクトリー名とディレクトリーファイル名の違いは些細ですが重要です。Emacsの変数や関数の引数を記述する際には、それがディレクトリー名であるとしており、ディレクトリーファイル名は許容されません。file-name-directoryが文字列をリターンするときには常にディレクトリー名をリターンします。

以下の2つの関数は、ディレクトリー名とディレクトリーファイル名の間で変換を行います。これらの関数は‘$HOME’のような環境変数や‘~’、‘.’、‘..’などの構文にたいして、特別なことは何も行いません。

Function: file-name-as-directory filename

この関数はオペレーティングシステムがディレクトリーの名前(ディレクトリー名)と解釈する形式でfilenameを表す文字列をリターンする。これはほとんどのシステムでは、(もし終端にそれがなければ)これは文字列にスラッシュを追加することを意味する。

(file-name-as-directory "~rms/lewis")
     ⇒ "~rms/lewis/"
Function: directory-name-p filename

この関数はfilenameの終端がディレクトリー区切り文字なら非nilをリターンする。これはGNUや他のPOSIX準拠システムではスラッシュ‘/’、MS-WindowsとMS-DOSではスラッシュとバックスラッシュ‘\’がディレクトリー区切りとして認識される。

Function: directory-file-name dirname

この関数はオペレーティングシステムがファイルの名前と解釈する形式(ディレクトリーファイル名)でdirnameを表す文字列をリターンする。ほとんどのシステムではこれは文字列すべてがディレクトリー区切り文字で構成されている場合を除き、文字列から最後のディレクトリー区切り文字を削除することを意味する。

(directory-file-name "~lewis/")
     ⇒ "~lewis"
Function: file-name-concat directory &rest components

directoryまたは前置されるコンポーネントがスラッシュで終端されていなければコンポーネントの前にスラッシュを挿入して、directorycomponentsを結合する。

(file-name-concat "/tmp" "foo")
     ⇒ "/tmp/foo"

componentsや空文字列のdirectoryやコンポーネントは無視する。これらは最初に除外されて、結果に影響することはない。

この関数はconcatを使用するのとほとんど同じだが、dirname(と最後のコンポーネント)がスラッシュで終端されているか否かに関わらずスラッシュ文字を2重に連結することはない点が異なる。

ディレクトリー名をディレクトリーの省略名に変換するには以下の関数を使用します:

Function: abbreviate-file-name filename

この関数はfilenameの省略された形式をリターンする。 これはdirectory-abbrev-alist (File Aliases in The GNU Emacs Manualを参照)で指定される省略名を適用して、引数で与えられるファイル名ががホームディレクトリーかそのサブディレクトリーにあれば、ユーザーのホームディレクトリーを‘~’に置換する。ホームディレクトリーがルートディレクトリーなの場合には、多くのシステムでは結果が短縮されないので‘~’で置き換えない。

これは名前の一部であるような省略形さえも認識するので、ディレクトリー名とファイル名にも使用できる。

Function: file-name-parent-directory filename

この関数はfilenameの親ディレクトリーのディレクトリー名をリターンする。filenameがソンファイルシステムのルートディレクトリーにある場合にはnilをリターンする。相対的なfilenameの場合にはdefault-directoryから相対的なディレクトリーとみなし、リターンされる値も相対的なディレクトリー名となる。リターン値が非nilならスラッシュで終端される。


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

26.9.4 ファイル名を展開する関数

ファイル名の展開(expanding)と、相対ファイル名を絶対ファイル名に変換することを意味します。これはデフォルトディレクトリーから相対的に行われるため、展開されるファイル名と同様にデフォルトディレクトリーも指定しなければなりません。これは~/のような省略形 (abbreviate-file-nameを参照)、 の展開、および./name/../のような冗長さの排除も行います。

Function: expand-file-name filename &optional directory

この関数はfilenameを絶対ファイル名に変換する。directoryが与えられた場合にはfilenameが相対的であり先頭が‘~’でなければ、それが開始点となるデフォルトディレクトリーになる(directoryの値はそれ自体が絶対ディレクトリー名かディレクトリーファイル名であるべきで、それは‘~’で始まるかもしれない)。それ以外ではカレントバッファーのdefault-directoryの値が使用される。たとえば:

(expand-file-name "foo")
     ⇒ "/xcssun/users/rms/lewis/foo"
(expand-file-name "../foo")
     ⇒ "/xcssun/users/rms/foo"
(expand-file-name "foo" "/usr/spool/")
     ⇒ "/usr/spool/foo"

filenameの最初のスラッシュの前が‘~’ならユーザーのホームディレクトリー(通常は環境変数HOMEの値で指定される)に展開される(General Variables in The GNU Emacs Manualを参照)。最初のスラッシュの前が‘~user’でuserが有効なログイン名ならuserのホームディレクトリーに展開される。リテラル‘~’で始まるかもしれない相対的なfilenameにたいして展開を望まない場合には(expand-file-name filename directory)のかわりに(concat (file-name-as-directory directory) filename)を使用できる。

File names containing ‘.’ or ‘..’ are simplified to their canonical form:

(expand-file-name "bar/../foo")
     ⇒ "/xcssun/users/rms/lewis/foo"

出力に‘..’部分が残り得る場合もある:

(expand-file-name "../home" "/")
     ⇒ "/../home"

これはルートディレクトリー/の上位のスーパールート(superroot)という概念をもつファイルシステムのためのものである。その他のファイルシステムでは/..//とまったく同じに解釈される。

.や空文字列を展開するとデフォルトディレクトリーがリターンされる:

(expand-file-name "." "/usr/spool/")
     ⇒ "/usr/spool"
(expand-file-name "" "/usr/spool/")
     ⇒ "/usr/spool"

expand-file-nameは環境変数を展開しないことに注意。それを行うのはsubstitute-in-file-nameのみ。

(expand-file-name "$HOME/foo")
     ⇒ "/xcssun/users/rms/lewis/$HOME/foo"

expand-file-nameはあらゆる階層においてシンボリックリンクをフォローしないことにも注意。これは‘..’の扱いがfile-truenameexpand-file-nameで異なることに起因する。‘/tmp/bar’がディレクトリー‘/tmp/foo/bar’にたいするシンボリックリンクであると仮定すると:

(file-truename "/tmp/bar/../myfile")
     ⇒ "/tmp/foo/myfile"
(expand-file-name "/tmp/bar/../myfile")
     ⇒ "/tmp/myfile"

直接間接を問わず事前にexpand-file-nameを呼び出さずに‘..’に先行するシンボリックリンクをフォローする必要があるかもしれない場合には、それを呼び出さずに確実にfile-truenameを呼び出すこと。本当の名前を参照されたい。

Variable: default-directory

このバッファーローカル変数の値はカレントバッファーにたいするデフォルトディレクトリー。これは絶対ディレクトリー名であること。これは‘~’で始まるかもしれない。この変数はすべてのバッファーにおいてバッファーローカル。

2つ目の引数がnilなら、expand-file-nameはデフォルトディレクトリーを使用する。

値は常にスラッシュで終わる文字列。

default-directory
     ⇒ "/user/lewis/manual/"
Function: substitute-in-file-name filename

この関数はfilename内で参照される環境変数を環境変数の値に置き換える。標準的なUnixシェル構文にしたがい ‘$’は環境変数値を置き換るプレフィックスである。入力に‘$$’が含まれる場合には、それらは‘$’に置き換えられる。これによりユーザーが‘$’をクォートする手段が与えられる。

環境変数名は‘$’の後に続く一連の英数字(アンダースコアを含む)である。‘$’の後続文字が‘{’なら対応する‘}’までのすべてが変数名である。

substitute-in-file-nameにより生成された出力でsubstitute-in-file-nameを呼び出すと不正な結果となる傾向がある。たとえば単一の‘$’をクォートするために‘$$’を使用しても正しく機能せずに環境変数値の中の‘$’は再帰的な置換を導くだろう。したがってこの関数を呼び出して出力をこの関数に渡すプログラムは、その後の不正な結果を防ぐためにすべての‘$’文字を二重化する必要がある。

以下ではユーザーのホームディレクトリーを保持する環境変数HOMEの値が‘/xcssun/users/rms’だと仮定する。

(substitute-in-file-name "$HOME/foo")
     ⇒ "/xcssun/users/rms/foo"

置き換え後には、‘/’の直後に‘~’や別の‘/’が出現すると、この関数は‘/’の前にあるすべてを無視する。

(substitute-in-file-name "bar/~/foo")
     ⇒ "~/foo"
(substitute-in-file-name "/usr/local/$HOME/foo")
     ⇒ "/xcssun/users/rms/foo"
     ;; /usr/local/は破棄された

ファイル名の展開が望ましくない場合もあります。そのような場合には展開を抑制するためにファイル名をクォートしてファイル名をそのままリテラルとして処理することができます。ファイル名の前に‘/:’を前置することによりクォートが行われます。

Macro: file-name-quote name

このマクロはファイルnameにクォーテーションプレフィクス‘/:’を付加する。ローカルファイルnameにはnameの前にプレフィクス‘/:’を付加する。nameがリモートファイル名ならnameのローカル部分がクォートされる(特定のファイル名の“Magic”の作成を参照)。nameがクォート済みのファイル名なら、nameは変更せずにリターンする。

(substitute-in-file-name (file-name-quote "bar/~/foo"))
     ⇒ "/:bar/~/foo"

(substitute-in-file-name (file-name-quote "/ssh:host:bar/~/foo"))
     ⇒ "/ssh:host:/:bar/~/foo"

マジックファイル名によるファイル名ハンドラーを抑制するためにこのマクロは使用できない(特定のファイル名の“Magic”の作成を参照)。

Macro: file-name-unquote name

このマクロはファイルnameにクォーテーションプレフィクス‘/:’があれば削除する。nameがリモートファイル名ならnameのローカル部分を非クォート化する。

Macro: file-name-quoted-p name

このマクロはnameがプレフィクス‘/:’でクォートされていれば非nilをリターンする。nameがリモートファイル名ならnameのローカル部分をチェックする。


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

26.9.5 一意なファイル名の生成

一時ファイルに書き込む必要があるプログラムがいくつかあります。以下は、そのようなファイルを構築する便利な方法です:

(make-temp-file name-of-application)

make-temp-fileの役目は、2人の異なるユーザーやジョブが完全に一致する名前のファイルの使用を防ぐことです。

Function: make-temp-file prefix &optional dir-flag suffix text

この関数は一時ファイルを作成して、その名前をリターンする。EmacsはEmacsの各ジョブごとに異なるランダムないくつかの文字をprefixに追加することにより一時ファイルの名前を作成する。結果として文字列としてtextが与えられた場合にはそれを含むファイル、それ以外は空ファイルが新たに作成されることが保障される。MS-DOSでは、8+3のファイル名制限に適合するように、文字列stringが切り詰められる可能性がある。prefixが相対ファイル名ならtemporary-file-directoryにたいして展開される。

(make-temp-file "foo")
     ⇒ "/tmp/foo232J6v"

make-temp-fileがリターンした際には、一時ファイルは空で作成される。この時点でそのファイルに意図するコンテンツを書き込むこと。

dir-flagnilなら、make-temp-fileは空のファイルのかわりに空のディレクトリーを作成する。これはディレクトリー名ではなく、ディレクトリーのファイル名をリターンする。ディレクトリーの名前を参照のこと。

suffixが非nilなら、make-temp-fileはそれをファイル名の最後に追加する。

textが文字列ならmake-temp-fileはそれをファイルに挿入する。

同じEmacs内で実行される異なるライブラリー間での競合を防ぐために、make-temp-fileを使用する各Lispプログラムがプログラム自身のprefixを使用すること。prefixの最後に追加される数字は、異なるEmacsジョブ内で実行される同じアプリケーションを区別する。追加される文字により、同一のEmacsジョブ内でも多数の名前を区別することが可能になる。

一時ファイル用のデフォルトディレクトリーは変数temporary-file-directoryにより制御されます。この変数によりすべての一時ファイルにたいして、ユーザーがディレクトリーを指定する一貫した方法が与えられます。small-temporary-file-directoryが非nilなら、かわりにそれを使うプログラムもいくつかあります。これを使う場合には、make-temp-fileを呼び出す前に正しいディレクトリーにたいしてプレフィックスを展開するべきです。

User Option: temporary-file-directory

この変数は一時ファイル作成用のディレクトリー名を指定する。値はディレクトリー名であるべきだが、もし値がディレクトリーのファイル名(ディレクトリーの名前を参照)ならば、Lispプログラムがかわりに対処すればよい。expand-file-nameの2つ目の引数としてその値を使用するのは、それを達成するよい方法である。

デフォルト値はオペレーティングシステムにたいして適切な方法により決定される。これは環境変数TMPDIRTMPTEMPにもとづく値で、これらの変数が定義されていなければシステム依存の名前にフォールバックする。

一時ファイルの作成にmake-temp-fileを使用しない場合でも、一時ファイルを置くディレクトリーを判断するために依然としてこの変数を使用するべきである。しかし一時ファイルが小さくなることを求める場合には、small-temporary-file-directoryが非nilならそれを使用すること。

User Option: small-temporary-file-directory

この変数はサイズが小さいと予想される特定の一時ファイル作成用のディレクトリー名を指定する。

小さくなるかもしれない一時ファイルに書き込みたいなら、以下のようにディレクトリーを計算すること:

(make-temp-file
  (expand-file-name prefix
                    (or small-temporary-file-directory
                        temporary-file-directory)))
Function: make-temp-name base-name

この関数は一意なファイル名として使用できる文字列を生成する。この名前はbase-nameで始まり、それに各Emacsジョブごとに異なる複数のランダムな文字を追加したものである。これはmake-temp-fileと似ているが、(i)名前だけを作成してファイルは作成せず、(ii)base-nameはマジックファイル名ではない絶対ファイル名であること、(iii)リターンされるファイル名がマジックファイル名なら既存のファイルかもしれない、という点が異なる(MS-DOSシステムでは8+3ファイル名制限に適合するようにbase-nameが切り詰められる)。

警告: この関数を使用するべきではない。かわりにmake-temp-fileを使用すること! この関数は競合状態の影響を受けやすい。make-temp-name呼び出しと一時ファイル作成のタイムラグはセキュリティーホールとなり得る。

リモートホストやマウントされたディレクトリーで一時ファイルの作成を要する場合があります。以下の2つの関数はそれをサポートします。

Function: make-nearby-temp-file prefix &optional dir-flag suffix

この関数はmake-temp-fileと同様だができ得るかぎりdefault-directoryに近接した一時ファイルを作成する点が異なる。prefixが相対ファイル名でdefault-directoryがリモートファイル名かマウントされたファイルシステムに配置されていれば、一時ファイルは関数temporary-file-directoryがリターンするディレクトリー内に作成される。それ以外なら関数make-temp-fileを使用する。prefixdir-flagsuffixの意味はmake-temp-fileの場合と同様。

(let ((default-directory "/ssh:remotehost:"))
  (make-nearby-temp-file "foo"))
     ⇒ "/ssh:remotehost:/tmp/foo232J6v"
Function: temporary-file-directory

make-nearby-temp-fileを通じて一時ファイルを書き込むディレクトリー。default-directoryがリモートの場合にはリモートホスト上の一時ファイル用のディレクトリー。そのようなディレクトリーが存在しない、またはdefault-directoryがマウントされるファイルシステム上に配置される場合(mounted-file-systemsを参照)には、この関数はdefault-directoryをリターンする。リモートでもマウントされたファイルシステムでもないdefault-directoryではtemporary-file-directoryの値がリターンされる。

一時ファイルのファイル名のローカル部分を抽出するためにはfile-local-nameを使用してください(特定のファイル名の“Magic”の作成を参照)。


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

26.9.6 ファイル名の補完

このセクションではファイル名を補完するための低レベルサブルーチンについて説明します。より高レベルの関数についてはファイル名の読み取りを参照してください。

Function: file-name-all-completions partial-filename directory

この関数はディレクトリーdirectory内でpartial-filenameで始まる名前のファイルにたいする、すべての補完可能なリストをリターンする。補完の順番はそのディレクトリー内でのファイル順序であり、これは予測不能であり何の情報ももたない。

引数partial-filenameは非ディレクトリーパートを含むファイル名でなければならず、スラッシュ(いくつかのシステムではバックスラッシュ)が含まれていてはならない。directoryが絶対ディレクトリーでなければ、directoryの前にカレントバッファーのデフォルトディレクトリーが追加される。

以下の例では~rms/lewisがカレントデフォルトディレクトリーで、名前が‘f’で始まる5つのファイルfoofile~file.cfile.c.~1~file.c.~2~がある:

(file-name-all-completions "f" "")
     ⇒ ("foo" "file~" "file.c.~2~"
                "file.c.~1~" "file.c")

(file-name-all-completions "fo" "")
     ⇒ ("foo")
Function: file-name-completion filename directory &optional predicate

この関数はディレクトリーdirectory内でファイル名filenameを補完する。これはディレクトリーdirectory内で、filenameで始まるすべてのファイル名にたいして、最長の共通プレフィックスをリターンする。predicateが非nilなら展開された絶対ファイル名を単一の引数として呼び出して、predicateを満足しない補完候補を無視する。

マッチが1つだけ存在して、かつfilenameが正確にそれにマッチする場合には、この関数はtをリターンする。関数はディレクトリーdirectoryfilenameで始まる名前のファイルを含まなければnilをリターンする。

以下の例では~rms/lewisがカレントデフォルトディレクトリーで、名前が‘f’で始まる5つのファイルfoofile~file.cfile.c.~1~file.c.~2~がある:

(file-name-completion "fi" "")
     ⇒ "file"

(file-name-completion "file.c.~1" "")
     ⇒ "file.c.~1~"

(file-name-completion "file.c.~1~" "")
     ⇒ t

(file-name-completion "file.c.~3" "")
     ⇒ nil
User Option: completion-ignored-extensions

file-name-completionはこのリスト内の任意の文字列で終わるファイル名を通常は無視する。すべての可能な補完がこれらのサフィックスのいずれか1つで終わるときはそれらを無視しない。この変数はfile-name-all-completionsに影響しない。

以下は典型的な値:

completion-ignored-extensions
     ⇒ (".o" ".elc" "~" ".dvi")

completion-ignored-extensionsのある要素がスラッシュ‘/’で終わる場合には、それはディレクトリーを示す。スラッシュで終わらない要素がディレクトリーにマッチすることは決してない。したがって上記の値はfoo.elcという名前のディレクトリーを除外しないだろう。


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

26.9.7 標準的なファイル名

Emacs Lispプログラムが特定の用途のために標準的なファイル名を指定することが必要な場合があります。典型的にはカレントユーザーによって指定された設定データを保持する場合が該当します。そのようなファイルは、通常はuser-emacs-directoryで指定されるディレクトリーに配置されて、 デフォルトでは通常は~/.config/emacs/~/.emacs.d/です(How Emacs Finds Your Init File in The GNU Emacs Manualを参照)。たとえばabbrev(abbreviation: 省略形)の定義は、デフォルトでは~/.config/emacs/abbrev_defs~/.emacs.d/abbrev_defsに格納されます。このようなファイル名を指定するためには、関数locate-user-emacs-fileを使用するのがもっとも簡単な方法です。

Function: locate-user-emacs-file base-name &optional old-name

この関数はEmacs特有の設定ファイルやデータファイルにたいする絶対ファイル名をリターンする。引数base-nameは、相対ファイル名であること。リターン値はuser-emacs-directoryで指定されるディレクトリー内の絶対ファイル名。そのディレクトリーが存在しなければ、この関数はディレクトリーを作成する。

オプション引数old-nameが非nilなら、それはユーザーのホームディレクトリー内のファイル~/old-nameを指定する。そのようなファイルが存在すれば、リターン値はbase-nameで指定されるファイルではなくそのファイルの絶対ファイル名となる。これはEmacsパッケージが後方互換を提供するために使用されることを意図した引数。たとえばuser-emacs-directory導入前には、abbrevファイルは~/.abbrev_defsに置かれていた。以下はabbrev-file-nameの定義である:

(defcustom abbrev-file-name
  (locate-user-emacs-file "abbrev_defs" ".abbrev_defs")
  "Default name of file from which to read abbrevs."
  …
  :type 'file)

ファイル名の標準化のための低レベル関数はconvert-standard-filenameで、これはサブルーチンとしてlocate-user-emacs-fileにより使用されます。

Function: convert-standard-filename filename

この関数はfilenameにもとづいたカレントオペレーティングシステムの慣習に適合するファイル名をリターンする。

GNUや他のPOSIX準拠システムでは単にfilenameをリターンする。その他のオペレーティングシステムではシステム固有のファイル名規約にしたがうだろう。たとえばMS-DOSでは、この関数はMS-DOSファイル名制限にしたがうように先頭の‘.’を‘_’に変換したり、‘.’の後続の文字を3文字に切り詰める等、さまざまな変更を行う。

この関数でGNUとUnixシステムの慣習に適合する名前を指定して、それをconvert-standard-filenameに渡すのが推奨される使用方法である。


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

26.10 ディレクトリーのコンテンツ

ディレクトリーとはファイルの一種であり、さまざまな名前のファイルを含んでいます。ディレクトリーはファイルシステムの機能です。

Emacsはディレクトリー内のファイル名をLispのリストとして一覧したり、シェルコマンドlsを使用してバッファー内にファイル名を表示することができます。後者の場合には、Emacsはオプションで各ファイルに関する情報も表示でき、それはlsコマンドに渡すオプションに依存します。

Function: directory-files directory &optional full-name match-regexp nosort count

この関数はディレクトリーdirectory内のファイルの名前のリストをリターンする。デフォルトではリストはアルファベット順。

この関数はfull-nameが非nilならファイルの絶対ファイル名、それ以外なら指定されたディレクトリーにたいする相対ファイル名をリターンする。

match-regexpが非nilなら、この関数は非ディレクトリー部分に正規表現へのマッチを含むファイル名だけをリターンして、それ以外のファイル名はリストから除外される。case(大文字小文字)を区別するファイルシステムでは、caseを区別する正規表現マッチングが行われる。

nosortが非nilならdirectory-filesはリストをソートしないので、取得するファイル名に特定の順序はない。最大限の可能なスピードを得る必要がありファイル処理順を気にしなければこれを使用する。ユーザーから処理順が可視なら、名前をソートすれば多分ユーザーはより幸せになるだろう。

countが非nilなら最初のcount個のファイル名、またはすべてのファイル名のいずれか早いほうをリターンする。countは0より大な整数であること。

(directory-files "~lewis")
     ⇒ ("#foo#" "#foo.el#" "." ".."
         "dired-mods.el" "files-ja.texi"
         "files-ja.texi.~1~")

directoryが読み取り可能なディレクトリー名でなければエラーがシグナルされる。

Function: directory-empty-p directory

このユーティリティー関数は与えられたdirectoryがアクセス可能なディレクトリーかつ何のファイルも含まない(空ディレクトリー)場合にはtをリターンする。ディレクトリー内のファイルとして‘.’や‘..’をリターンするシステムでは、それらは無視される。

ディレクトリーへのシンボリックリンクはディレクトリーとみなされる。シンボリックリンクと区別する方法についてはfile-symlink-pを参照のこと。

Function: directory-files-recursively directory regexp &optional include-directories predicate follow-symlinks

regexpにマッチする名前をもつdirectory配下のすべてのファイルをリターンする。この関数はベースネーム(basename: 先行するディレクトリー部分を除外したファイル名)がregexpにマッチするファイルを、directoryとそのサブディレクトリーを再帰的に検索して、マッチしたファイルの絶対ファイル名(absolute file namesを参照)のリストをリターンする。ファイル名は深さ優先順でリターンされ、それは親ディレクトリーの前に任意のサブディレクトリー内のファイルが配置されることを意味する。加えて各ディレクトリー内で見つかったファイルはベースネームにもとづいてソートされる。デフォルトではregexpにマッチする名前のディレクトリーはリストから省略されるが、オプション引数include-directoriesが非nilならそれらも含まれる。

デフォルトではすべてのサブディレクトリーが含まれる。predicatetならサブディレクトリーを含める際のエラー(たとえばそのユーザーでは読み取り不可の場合)は無視される。nilt以外なら、1つのパラメーター(サブディレクトリー名)を受け取り、そのディレクトリーを含める場合には非nilをリターンする関数であること。

デフォルトではサブディレクトリーへのシンボリックリンクはフォローしないが、follow-symlinksが非nilならフォローする。

Function: locate-dominating-file file name

fileから開始してディレクトリーツリー階層を上方にname (文字列)というディレクトリーを検索して、最初に見つけたディレクトリーをリターンする。fileがファイルならファイルのディレクトリーが検索の開始位置、それ以外ならfileは検索を開始するディレクトリーであること。この関数は開始ディレクトリーを調べて、それからその親ディレクトリー、更にその親ディレクトリー、...のようにnameというディレクトリーを見つけるか、あるいはnameが見つけることなくファイルシステムのロートディレクトリーに到達するまで検索を行う。後者の場合にはnilをリターンする。

引数nameは述語関数でもよい。この述語は関数により検査される、file (fileがディレクトリーでない場合でも)から開始されるすべてのディレクトリーにたいして呼び出される。この述語は1つの引数(ファイルかディレクトリー)で呼び出されて、それが検索しているディレクトリーなら非nilをリターンすること。

Function: file-in-directory-p file dir

この関数は、fileがディレクトリーdir内のファイルかサブディレクトリーならtをリターンする。またfiledirが同じディレクトリーの場合もtをリターンする。この関数は2つのディレクトリーの実名を比較する。dirが既存のディレクトリーの名前でなければリターン値はnil

Function: directory-files-and-attributes directory &optional full-name match-regexp nosort id-format count

これはどのファイルを報告するか、およびファイル名を報告する方法においてdirectory-filesと似ている。しかしこの関数はファイル名のリストをリターンするかわりに、各ファイルごとにリスト(filename . attributes)をリターンする。ここでattributesは、そのファイルにたいしてfile-attributesがリターンする値。オプション引数id-formatは、file-attributesの対応する引数と同じ意味をもつ(Definition of file-attributesを参照)。

Constant: directory-files-no-dot-files-regexp

この正規表現は‘.’と‘..’を除いたすべてのファイル名にマッチする。より正確にはこれら2つを除いたすべての空文字列以外の部分にマッチする。これはdirectory-filesおよびdirectory-files-and-attributesmatch-regexp引数として有用。

(directory-files "/foo" nil directory-files-no-dot-files-regexp)

ディレクトリー‘/foo’が空ならnilをリターンする。

Function: file-expand-wildcards pattern &optional full regexp

この関数はワイルドカードパターンpatternを展開して、それにマッチするファイル名のリストをリターンする。

patternはデフォルトでは‘"/tmp/*.png"’や‘"/*/*/foo.png"’のような“glob”あるいはワイルドカード文字列だが、オプションのregexpパラメーターが非nilなら正規表現でもよい。いずれの場合でもマッチが親ディレクトリーとサブディレクトリーにまたがらないように、サブディレクトリーごとに適用される。

絶対ファイル名としてpatternが記述されると値も絶対ファイル名になる。

patternが相対ファイル名で記述されていれば、それはカレントデフォルトディレクトリーにたいして相対的に解釈される。通常はリターンされるファイル名もカレントデフォルトディレクトリーにたいする相対ファイル名になる。しかしfullが非nilなら絶対ファイル名がリターンされる。

Function: insert-directory file switches &optional wildcard full-directory-p

この関数はlsswitchesに対応するフォーマットで、(カレントバッファー内に)ディレクトリーfileのディレクトリーリストを挿入する。これは挿入したテキストの後にポイントを残す。switchesにはオプション文字列、または個別のオプションを表す文字列リストを指定できる。

引数fileにはディレクトリー、またはワイルドカード文字を含むファイル名を指定できる。wildcardが非nilならfileはワイルドカードを伴うファイル指定として扱われることを意味する。

full-directory-pが非nilなら、ディレクトリーリストにたいしてディレクトリーの完全なコンテンツ表示を要求することを意味する。fileがディレクトリーでスイッチに‘-d’が含まれないときには、tを指定すること(lsへのオプション‘-d’は、ディレクトリーのコンテンツではなくファイルとしてディレクトリーを表示するよう指定する)。

ほとんどのシステムでは、この関数は変数insert-directory-programの名前のディレクトリーリスト用プログラムを実行することにより機能する。wildcardが非nilなら、ワイルドカード展開するためにshell-file-nameで指定されるシェルの実行も行う。

MS-DOSとMS-Windowsシステムは標準的なUnixプログラムlsを欠くので、この関数はLispコードでlsをエミュレートする。

技術的な詳細としてはswitchesにロングオプション‘--dired’が含まれる際に、insert-directoryはdiredのためにこれを特別に扱う。しかし他のオプションと同様、通常は等価なショートオプション‘-D’が単にinsert-directory-programに渡されるだけである。

Variable: insert-directory-program

この変数の値は関数insert-directory用にディレクトリーリストを生成するプログラムである。この値はLispコードでこのリストを生成するシステムでは無視される。


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

26.11 ディレクトリーの作成・コピー・削除

Emacs Lispのファイル操作関数のほとんどは、ディレクトリーであるようなファイルに使用されたときはエラーとなります。たとえばdelete-fileでディレクトリーの削除はできません。以下のスペシャル関数はディレクトリーの作成と削除を行うために存在します。

Command: make-directory dirname &optional parents

このコマンドはdirnameという名前のディレクトリーを作成する。parentsが非nilの場合(インタラクティブな呼び出しでは常に非nil)には、その親ディレクトリーがまだ存在しなければ最初にそれを作成することを意味する。関数としてのmake-directorydirnameがディレクトリーとして既に存在していてparentsが非nilなら非nildirnameを成功裏に作成できたらnilをリターンする。mkdirはこのコマンドにたいするエイリアス。

Command: make-empty-file filename &optional parents

このコマンドはfilenameという名前の空のファイルを作成する。このコマンドはmake-directoryと同様に、parentsが非filenameがすでに存在する場合には、このコマンドはエラーをシグナルする。

Command: copy-directory dirname newname &optional keep-time parents copy-contents

このコマンドはdirnameという名前のディレクトリーをnewnameにコピーする。newnameがディレクトリー名ならdirnameはそれのサブディレクトリーにコピーされる。ディレクトリーの名前を参照のこと。

これは常にコピーされるファイルのファイルモードを、対応する元のファイルモードと一致させる。

3つ目の引数keep-timeが非nilなら、それはコピーされるファイルの修正時刻を保持することを意味する。プレフィックス引数を与えると、keep-timeは非nilになる。

4つ目の引数parentsは、親ディレクトリーが存在しない場合に作成するかどうかを指定する。インタラクティブな場合には、これはデフォルトで発生する。

5つ目の引数copy-contentsが非nilの場合には、それはnewnameがディレクトリー名ならば、そのサブディレクトリーとしてdirnameをコピーするかわりにdirnameのコンテンツをnewnameにコピーする。

Command: delete-directory dirname &optional recursive trash

このコマンドはdirnameという名前のディレクトリーを削除する。関数delete-fileはディレクトリーであるようなファイルにたいしては機能しない。それらにたいしてはdelete-directoryを使用しなければならない。recursivenilでディレクトリー内にファイルが存在する場合には、delete-directoryはエラーをシグナルする。recursiveが非nilなら、delete-directoryの処理前にそのディレクトリーやディレクトリーのファイルを他のプロセスが削除したという稀な状況を除いてエラーは発生しない。

delete-directoryは親ディレクトリーの階層のシンボリックリンクだけをフォローする。

オプション引数trashが非nil、かつ変数delete-by-moving-to-trashが非nilなら、このコマンドはファイルを削除するかわりにシステムのTrash(ゴミ箱)にファイルを移動する。Miscellaneous File Operations in The GNU Emacs Manualを参照のこと。インタラクティブに呼び出された際には、プレフィックス引数がなければtrasht、それ以外はnil


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

26.12 特定のファイル名の“Magic”の作成

特定のファイル名にたいして特別な処理を実装できます。これはそれらの名前にたいするmagic化と呼ばれます。この機能は主にリモートファイルにたいするアクセスの実装用に使用されます(Remote Files in The GNU Emacs Manualを参照)。

magicファイル名を定義するには、名前クラスを定義するための正規表現とそれにマッチするファイル名用のEmacsファイル操作プリミティブすべてを実装するハンドラーを定義しなければなりません。

変数file-name-handler-alistは各ハンドラーに適用するときを決定する正規表現とともにハンドラーのリストを保持します。各要素は以下の形式をもちます:

(regexp . handler)

ファイルアクセスとファイル名変換にたいするすべてのEmacsプリミティブは、file-name-handler-alistにたいして与えられたファイル名をチェックします。そのファイル名がregexpにマッチしたら、そのプリミティブがhandlerを呼び出してファイルを処理します。

handlerの1つ目の引数には、プリミティブの名前をシンボルとして与えます。残りの引数はそのプリミティブに引数として渡されます(これらの引数の1つ目はほとんどの場合はファイル名自身)。たとえば以下を行って:

(file-exists-p filename)

filenameがハンドラーhandlerをもつなら、handlerは以下のように呼び出されます:

(funcall handler 'file-exists-p filename)

関数が2つ以上の引数を受け取る場合には、それらはファイル名でなければならず、関数はそれらのファイル名それぞれにたいしてハンドラーをチェックします。たとえば、

(expand-file-name filename dirname)

以下を行うと、filenameにたいするハンドラーをチェックした後にdirnameにたいするハンドラーをチェックします。どちらの場合でもhandlerは以下のように呼び出されます:

(funcall handler 'expand-file-name filename dirname)

その後にhandlerfilenamedirnameのいずれかを処理するか解決する必要があります。

指定されたファイル名が2つ以上のハンドラーにマッチする場合には、ファイル名の中で最後に開始するマッチが優先されます。リモートファイルアクセスのようなジョブにたいするハンドラーに先立って、解凍のようなジョブにたいするハンドラーが最初に処理されるようにこのルールが選択されました。

以下はmagicファイル名ハンドラーが処理する操作です:

abbreviate-file-nameaccess-fileadd-name-to-filebyte-compiler-base-file-name
copy-directorycopy-filedelete-directorydelete-filediff-latest-backup-filedirectory-file-namedirectory-filesdirectory-files-and-attributesdired-compress-filedired-uncacheexec-pathexpand-file-name
file-accessible-directory-pfile-aclfile-attributesfile-directory-pfile-equal-pfile-executable-pfile-exists-pfile-in-directory-pfile-local-copyfile-locked-pfile-modesfile-name-all-completionsfile-name-as-directoryfile-name-case-insensitive-pfile-name-completionfile-name-directoryfile-name-nondirectoryfile-name-sans-versionsfile-newer-than-file-pfile-notify-add-watchfile-notify-rm-watchfile-notify-valid-pfile-ownership-preserved-pfile-readable-pfile-regular-pfile-remote-pfile-selinux-contextfile-symlink-pfile-system-infofile-truenamefile-writable-pfind-backup-file-name
get-file-bufferinsert-directoryinsert-file-contents
list-system-processesloadlock-filemake-auto-save-file-namemake-directorymake-lock-file-namemake-nearby-temp-filemake-processmake-symbolic-link
memory-infoprocess-attributesprocess-filerename-fileset-file-aclset-file-modesset-file-selinux-contextset-file-timesset-visited-file-modtimeshell-commandstart-file-processsubstitute-in-file-name
temporary-file-directoryunhandled-file-name-directoryunlock-filevc-registeredverify-visited-file-modtime
write-region

insert-file-contentsにたいするハンドラーはvisit引数が非nilなら、通常は(set-buffer-modified-p nil)によりそのバッファーの変更フラグをクリアーする必要があります。これにはもしそのバッファーがロックされていたら、ロックを解除する効果もあります。

ハンドラー関数は上記すべての操作を処理しなければならず、他の操作が将来追加される可能性もあります。これらの操作自体すべてを実装する必要はありません — 特定の操作にたいして特別なことを行う必要がないときには、その操作を通常の方法で処理するように、そのプリミティブを再呼び出しできます。認識できない操作にたいしては、常にそのプリミティブを再呼び出しするべきです。以下はこれを行う方法の1つです:

(defun my-file-handler (operation &rest args)
  ;; 特別に処理する必要がある、
  ;; 特別な操作を最初にチェックする
  (cond ((eq operation 'insert-file-contents) …)
        ((eq operation 'write-region) …)
        …
        ;; 関知しないその他の操作を処理する
        (t (let ((inhibit-file-name-handlers
                  (cons 'my-file-handler
                        (and (eq inhibit-file-name-operation operation)
                             inhibit-file-name-handlers)))
                 (inhibit-file-name-operation operation))
             (apply operation args)))))

ハンドラー関数が通常のEmacsプリミティブを呼び出す決定をした際には、無限再帰を引き起こすような同一ハンドラーからのプリミティブの再呼び出しを防ぐ必要があります。上記の例では変数inhibit-file-name-handlersinhibit-file-name-operationによって、これを行う方法を示しています。上記の例のように、これらを正確に使用するよう注意してください。複数ハンドラーの正しい振る舞いと、それぞれがハンドラーをもつかもしれない2つのファイル名にたいする操作にたいする詳細は非常に重要です。

ファイルへの実アクセスにたいして実際には特別なことを行わないハンドラー(たとえばリモートファイル名にたいしてホスト名の補完を実装するハンドラー等)は、safe-magicプロパティに非nilをもつべきです。たとえばEmacsは通常はPATH内で見い出されるようなディレクトリーがプレフィックス‘/:’によってmagicファイル名に見えるようなら、magicファイル名にならないように保護します。しかしsafe-magicプロパティに非nilをもつハンドラーがそれらにたいして使用された場合には、‘/:’は追加されません。

ファイル名ハンドラーは普通とは異なる方法でそれを処理(handle)するのがどの操作(operation)なのかを宣言するために、operationsプロパティをもつことができます。このプロパティが非nil値をもつなら、それは操作のリストであるべきです。その場合には、それらの操作だけがハンドラーを呼び出すでしょう。これは無駄を省きますが、主な目的はオートロードされるハンドラー関数が実際に処理を行うとき以外はロードされないようにすることです。

通常のプリミティブにたいして単にすべての操作を延期しても機能しません。たとえばファイル名ハンドラーがfile-exists-pにたいして適用された場合には、通常のloadコードは正しく機能しないでしょうから、ハンドラー自身でloadを処理しなければなりません。しかしハンドラーがfile-exists-pプロパティを使用してfile-exists-pを処理しないことを宣言した場合には、普通とは異なる方法でloadを処理する必要はなくなります。

Variable: inhibit-file-name-handlers

この変数は特定の操作にたいして現在のところ使用を抑制されているハンドラーのリストを保持する。

Variable: inhibit-file-name-operation

特定のハンドラーにたいしてその時点で抑制されている操作。

Function: find-file-name-handler file operation

この関数はfileというファイル名にたいするハンドラー関数、それが存在しなければnilをリターンする。引数operationはそのファイルを処理する操作であること。これはハンドラー呼び出し時に1つ目の引数として渡すことになる値である。operationinhibit-file-name-operationと等しいか、そのハンドラーのoperations内に存在しなければ、この関数はnilをリターンする。

Function: file-local-copy filename

この関数はファイルfilenameがまだローカルマシン上になければ、それをローカルマシン上の通常の非magicファイルにコピーする。magicファイル名は、それらが他のマシン上のファイルを参照する場合には、file-local-copy操作を処理するべきである。リモートファイルアクセス以外の目的にたいして使用されるmagicファイル名は、file-local-copyを処理するべきではない。この場合には関数はそのファイルをローカルファイルとして扱うだろう。

filenameがローカルなら、それがmagicか否かにかかわらずこの関数は何も行わずにnilをリターンする。それ以外ならローカルコピーファイルのファイル名をリターンする。

Function: file-remote-p filename &optional identification connected

この関数はfilenameがリモートファイルかどうかをテストする。filenameがローカル(リモートではない)ならリターン値はnilfilenameが正にリモートならリターン値はそのリモートシステムを識別する文字列。

この識別子文字列はホスト名とユーザー名、およびリモートシステムへのアクセスに使用されるメソッドを表す文字列も同様に含めることができる。たとえばファイル名/sudo::/some/fileにたいするリモート識別子文字列は/sudo:root@localhost:

2つの異なるファイルにたいしてfile-remote-pが同じ識別子をリターンした場合には、それらが同じファイルシステム上に格納されていて互いに配慮しつつアクセス可能であることを意味する。これはたとえば同時に両方のファイルにアクセスするリモートプロセスを開始することが可能なことを意味する。ファイル名ハンドラーの実装者はこの方式を保証する必要がある。

identificationは文字列としてリターンされるべき識別子の一部を指定する。identificationにはmethoduserhostのシンボルを指定できる。他の値はすべてnilのように扱われて、それは完全な識別子文字列をリターンすることを意味する。上記の例ではリモートのuser識別子文字列はrootになるだろう。

connectedが非nilなら、たとえfilenameがリモートであってもEmacsがそのホストにたいする接続をもたなければ、この関数はnilをリターンする。これは接続が存在しない際の接続の遅延を回避したいときに有用。

Function: unhandled-file-name-directory filename

この関数は非magicのディレクトリーの名前をリターンする。これは非magicのfilenameには対応するディレクトリー名(ディレクトリーの名前を参照)をリターンする。magicのfilenameには、何の値をリターンするかを決定するためにファイル名ハンドラーを呼び出す。filenameがローカルプロセスからアクセス不能なら、ファイル名ハンドラーはnilをリターンすることによってそれを示すこと。

これはサブプロセスの実行に有用。すべてのサブプロセスは自身が所属するカレントディレクトリーとして非magicディレクトリーをもたなければならず、この関数はそれを導出するよい手段である。

Function: file-local-name filename

この関数はfilenameローカル部分(local part)をリターンする。これはリモートホスト上でファイル名を識別する部分であり、通常はリモートファイル名からリモートホストを指定する部分とアクセス方法を取り除いた部分である。たとえば:

(file-local-name "/ssh:user@host:/foo/bar")
     ⇒ "/foo/bar"

この関数はリモートのfilenameにたいして、リモートプロセス(非同期プロセスの作成同期プロセスの作成を参照)やリモートホスト上で実行されるプログラムの引数として直接使用可能なファイル名をリターンする。filenameがローカルなら、この関数はそれを変更せずにリターンする。

User Option: remote-file-name-inhibit-cache

リモートファイルの属性は、よりよいパフォーマンスのためにキャッシュすることができる。キャッシュがEmacsの制御外で変更されると、そのキャッシュ値は無効になり再読込しなければならない。

この変数がnilにセットされているとキャッシュ値は決して失効しない。このセッティングはEmacs以外にリモートファイルを変更するものがないことが確実な場合のみ慎重に使用すること。これがtにセットされているとキャッシュ値は決して使用されない。これはもっとも安全な値であるがパフォーマンスは低下するかもしれない。

折衷的な値としてはこれを正の数字にセットする。これはキャッシュされてからその数字の秒数の間は、ャッシュ値を使用することを意味する。リモートファイルが定期的にチェックされる場合には、この変数を定期的なチェックの間隔より小さい値にletバインドするのは、よい考えかもしれない。たとえば:

(defun display-time-file-nonempty-p (file)
  (let ((remote-file-name-inhibit-cache
         (- display-time-interval 5)))
    (and (file-exists-p file)
         (< 0 (file-attribute-size
               (file-attributes
                (file-chase-links file)))))))

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

26.13 ファイルのフォーマット変換

Emacsはバッファー内のデータ(テキスト、テキストプロパティ、あるいはその他の情報)とファイルへの格納に適した表現との間で双方向の変換をするために複数のステップを処理します。このセクションでは、このフォーマット変換(format conversion)を行う基本的な関数、すなわちファイルをバッファーに読み込むinsert-file-contentsと、バッファーをファイルに書き込むwrite-regionを説明します。


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

26.13.1 概要

関数insert-file-contents:

  • 最初に、ファイルからバイトをバッファーに挿入して
  • バイトを適切な文字にデコードした後に
  • format-alistのエントリーで定義されているようにフォーマット処理してから
  • after-insert-file-functions内の関数を呼び出す。

関数write-region:

  • 最初にwrite-region-annotate-functions内の関数を呼び出して
  • format-alistのエントリーで定義されているようにフォーマット処理してから
  • 文字を適切なバイトにエンコードした後に
  • そのバイトでファイルを変更する。

これはもっとも低レベルでの操作を対照的に示したもので、対象の読み取りと書き込みの処理が逆順で対応しています。このセクションの残りの部分では、上記で名前を挙げた3つの変数を取り巻く2つの機能と、関連するいくつかの関数を説明します。文字のエンコードとデコードについての詳細はコーディングシステムを参照してください。


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

26.13.2 ラウンドトリップ仕様

読み取りと書き込みのもっとも一般的な機能は変数format-alistで制御されます。これはファイルフォーマット(file format)仕様のリストで、Emacsバッファー内のデータにたいしてファイル内で使用されるテキスト表現を記述します。読み取りと書き込みの仕様記述はペアーになっており、わたしたちがそれを“ラウンドトリップ(round-trip)”仕様と呼ぶのはこれが理由です(非ペアー仕様については漸次仕様を参照)。

Variable: format-alist

このリストには定義されるファイルフォーマットごとに1つのフォーマット定義が含まれる。フォーマット定義はそれぞれ以下の形式のリスト:

(name doc-string regexp from-fn to-fn modify mode-fn preserve)

以下はフォーマット定義内で要素がもつ意味:

name

フォーマットの名前。

doc-string

フォーマットのドキュメント文字列。

regexp

このフォーマットで表現されるファイルの認識に使用される正規表現。nilならフォーマットが自動的に適用されることは決してない。

from-fn

このフォーマットのデータをデコードする、(ファイルデータを通常のEmacsデータ表現に変換するための)シェルコマンドか関数。

シェルコマンドは文字列として表され、Emacsはそのコマンドを変換処理用のフィルターとして実行する。

from-fnが関数なら、それは変換するべきバッファー部分を指定する2つの引数beginendで呼び出される。これはインプレースでテキストを編集することにより変換を行うこと。これはテキスト長を変更する可能性があるのでfrom-fnは変更されたend位置をリターンすること。

ファイルの先頭が変換によりregexpにマッチしないようにするのはfrom-fnの役目の1つである。そうでないとおそらく再度変換が呼び出される。さらにfrom-fnはデコードされるバッファーやバッファーではないこと。さもなければフォーマット用の内部バッファーが上書きされるかもしれない。

to-fn

このフォーマットのデータをエンコード、すなわち通常のEmacsデータ表現をこのフォーマットに変換するためのシェルコマンドか関数。

to-fnが文字列ならそれはシェルコマンドである。Emacsは変換処理のためのフィルターとしてこのコマンドを実行する。

to-fnが関数なら、それは3つの引数で呼び出される。beginendは変換されるべきバッファー部分、bufferでそれがどのバッファーかを指定する。変換を行うには2つの方法がある:

  • そのバッファー内でインプレースで編集を行う。to-fnはこの場合は変更にしたがいテキスト範囲のend位置をリターンすること。
  • 注釈(annotation)のリストをリターンする。これは(position . string)という形式の要素をもつリストで、positionは書き込まれるテキスト内での相対位置を指定する整数、stringはそこに追加される注釈である。このリストはto-fnがそれをリターンする際には、位置順でソートされていなければならない。

    write-regionが実際にバッファーからファイルにテキストを書き込む際には、指定された注釈を対応する位置に混合する。これはすべてバッファーを変更せずに行われる。

from-fnはデコードされるバッファーやバッファーではないこと。さもなければフォーマット用の内部バッファーが上書きされるかもしれない。

modify

フラグ。エンコード関数がバッファーを変更するならt、注釈リストをリターンすることによって機能するならnil

mode-fn

このフォーマットから変換されたファイルをvisit後に呼び出されるマイナーモード関数。この関数は1つの引数で呼び出されて、それが整数1ならマイナーモード関数はそのモードを有効にする。

preserve

フラグ。format-write-filebuffer-file-formatからこのフォーマットを取り除くべきでなければt

関数insert-file-contentsは指定されたファイルを読み込む際にファイルフォーマットを自動的に認識します。これはフォーマット定義の正規表現にたいしてファイルの先頭テキストをチェックして、マッチが見つかったら、そのフォーマットにたいするデコード関数を呼び出します。その後は再度すべての既知のフォーマットをチェックします。適用できるフォーマットがない間はチェックを続行します。

find-file-noselectやそれを使用するコマンドでファイルをvisitすることにより、同じように変換が行われます(内部でinsert-file-contentsを呼び出すため)。さらにそれをデコードする各フォーマットのモード関数も呼び出します。これはバッファーローカル変数buffer-file-format内にフォーマット名のリストを格納します。

Variable: buffer-file-format

この変数はvisitしているファイルのフォーマットを表す。より正確にはこれはカレントバッファーのファイルをvisitに起因するデコードのファイルフォーマット名のリストである。これはすべてのバッファーにたいして常にローカル。

write-regionがデータをファイルに書き込む際には、まずbuffer-file-formatにリストされたフォーマットにたいするエンコード関数をリスト内での出現順に呼び出します。

Command: format-write-file file format &optional confirm

このコマンドはカレントバッファーのコンテンツをフォーマット名のリストformatにもとづいたフォーマットでファイルfileに書き込む。これはformatを起点に、buffer-file-formatの値からpreserveフラグ(上記参照)が非nilの要素にたいして、それがまだformat内に存在しなければ任意の個数それらを追加する。その後に将来の保存においてデフォルトとなるように、このフォーマットでbuffer-file-formatを更新する。format引数を除けばこのコマンドはwrite-fileと似ている。特にconfirmwrite-fileでの対応する引数と、意味やinteractiveでの扱いが同じである。Definition of write-fileを参照のこと。

Command: format-find-file file format

このコマンドはファイルfileを探してそれをフォーマットformatにしたがって変換する。これは後でそのバッファーを保存する場合にformatをデフォルトにすることも行う。

引数formatはフォーマット名のリスト。formatnilなら何の変換も行われない。interactiveに呼び出した場合には、formatにたいして単にRETをタイプするとnilが指定される。

Command: format-insert-file file format &optional beg end

このコマンドはファイルfileのコンテンツをフォーマットformatにしたがって変換して挿入する。begendが非nilなら、それはinsert-file-contentsと同様、ファイルのどの部分を読み込むかを指定する(ファイルからの読み込みを参照)。

リターン値は絶対ファイル名のリスト、および挿入されたデータの長さ(変換後)であり、これはinsert-file-contentsがリターンするものと同様。

引数formatはフォーマット名のリスト。formatnilなら何の変換も行われない。interactiveに呼び出した場合には、formatにたいして単にRETをタイプするとnilが指定される。

Variable: buffer-auto-save-file-format

この変数は自動保存(auto-saving)にたいして使用するフォーマットを指定する。値はbuffer-file-formatと同様、ファイル名のリストだが、これはauto-saveファイルへの書き込みでbuffer-file-formatのかわりに使用される。値がt(デフォルト)なら自動保存は当バッファーの通常の保存時と同じフォーマットを使用する。この変数はすべてのバッファーにおいて常にバッファーローカル。


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

26.13.3 漸次仕様

前のサブセクション(ラウンドトリップ仕様を参照)で説明したラウンドトリップ指定とは対照的に、変数after-insert-file-functionswrite-region-annotate-functionsを使用して読み取りと書き込みの変換を個別に制御できます。

変換はある表現を起点として他の表現を生成します。これを行う変換が1つだけのときは、何を起点とするかに関して競合は存在しません。しかし複数の変換呼び出しが存在する場合には、同じデータを起点にする必要がある2つの変換の間に競合が発生するかもしれません。

この状況を理解するには、write-region中のテキストプロパティの変換コンテキストが最善です。たとえばあるバッファーの位置42の文字が‘X’で、それのテキストプロパティがfooだとします。fooにたいする変換が、たとえばそのバッファーに‘FOO:’を挿入することにより行われる場合には、それは位置42の文字‘X’を‘F’に変更します。そして次の変換は間違ったデータを起点に開始されるでしょう。

競合を避けるためには協調的な変換がバッファーを変更せずに、position昇順でソートされた(position . string)という形式の要素をもつリストを注釈(annotations)に指定します。

2つ以上の変換が存在する場合には、write-regionはそれらの注釈を1つのソート済みリストに破壊的にマージします。後でそのバッファーのテキストを実際にファイルに書き込む際に、対応する位置にある指定された注釈を混合します。これはすべてバッファーを変更せずに行われます。

読み取り時にはこれとは対照的にそのテキストの混合された注釈は即座に処理されます。insert-file-contentsは変更される何らかのテキストの先頭にポイントをセットしてから、そのテキストの長さで変換関数を呼び出します。これらの関数は常に挿入されるテキストの先頭のポイントをリターンするべきです。最初の変換により注釈が削除されても、その後の変換が誤って処理することはないので、このアプローチは読み取りに際しては正しく機能します。すべての変換関数は、それが認識する注釈のスキャン、その注釈の削除、バッファーテキストの変更(たとえばテキストプロパティのセット等)、およびそれらの変更に由来する更新されたテキスト長のリターンを行うべきです。1つの関数によりリターンされた値は次の関数への引数になります。

Variable: write-region-annotate-functions

write-regionにたいして呼び出す関数のリスト。リスト内の各関数は書き込まれるリージョンの開始と終了の2つの引数で呼び出される。これらの関数はそのバッファーのコンテンツを変更するべきではない。かわりに注釈をリターンすること。

特別なケースとして、関数がカレントと異なるバッファーをリターンするかもしれない。Emacsはこれを、出力される変更されたテキストをカレントバッファーが含むものとして理解する。つまりEmacsはwrite-region呼び出しの引数startendを、新たなバッファーのpoint-minpoint-maxに変更して与える。さらに以前のすべての注釈はこの関数により処理されるのでEmacsはそれらの破棄も行う。

Variable: write-region-post-annotation-function

この変数の値が非nilなら、それは関数であること。この関数はwrite-region完了後に引数なしで呼び出される。

write-region-annotate-functions内のある関数がカレントと異なるバッファーをリターンした場合には、Emacsはwrite-region-post-annotation-functionを複数回呼び出す。Emacsは最後にカレントだったバッファーでそれを呼び出し、その前にカレントだったバッファーで再度これを呼び出す、...のようにして元のバッファーに戻る。

したがってwrite-region-annotate-functions内の関数は、バッファーを作成して、kill-bufferのそのバッファーでのローカル値にこの変数を与え、変更されたテキストでそのバッファーをセットアップして、そのバッファーをカレントにすることができる。そのバッファーは、write-region完了後にkillされるだろう。

Variable: after-insert-file-functions

このリスト内の各関数は、挿入されるテキストの先頭にポイントがある状態で、挿入される文字数を1つの引数としてinsert-file-contentsにより呼び出される。すべての関数はポイントを未変更のまま、その関数によって変更された挿入後テキストの新たな文字数をリターンすること。

わたしたちは、ユーザーがファイル内にテキストプロパティを格納したりそれらを取得するために、そしてさまざまなデータフォーマットを体験することにより適切なフォーマットを見つけるために、これらのフックを使用してLispプログラムを記述することを推奨します。最終的にはわたしたちがEmacs内にインストールできる、良質で汎用性のある拡張をユーザーが開発することを望みます。

わたしたちはテキストプロパティの名前や値として、任意のLispオブジェクトの処理を試みることは推奨しません — なぜなら汎用的なプログラムはおそらく記述が困難かつ低速だからです。かわりに十分な柔軟性をもちエンコードが難しすぎない、想定されるデータ型のセットを選択してください。


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

27 バックアップと自動保存

バックアップファイルとauto-save(自動保存)ファイルは、Emacsのクラッシュやユーザー自身のエラーからユーザーの保護を試みるための2つの手段です。自動保存(auto-saving)はカレントの編集セッションを開始した以降のテキストを保存します。一方バックアップファイルはカレントセッションの前のファイルコンテンツを保存します。


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

27.1 ファイルのバックアップ

バックアップファイル(backup file)とは編集中ファイルの古いコンテンツのコピーです。Emacsはvisitされているファイルにバッファーを最初に保存するときにバックアップファイルを作成します。したがってバックアップファイルには、通常はカレント編集セッションの前にあったファイルのコンテンツが含まれています。バックアップファイルを一度存在したら、そのコンテンツは変更されずに残ります。

バックアップは通常はvisitされているファイルを新たな名前にリネームすることによって作成されます。オプションでバックアップファイルがvisitされているファイルをコピーすることにより作成されるように指定できます。この選択により、複数の名前をもつファイルの場合に違いが生じます。また編集中のファイルの所有者が元のオーナーのままか、それとも編集ユーザーになるかにも影響し得ます。

デフォルトではEmacsは編集中のファイルごとに単一のバックアップファイルを作成します。かわりに番号付きバックアップ(numbered backup)を要求することもできます。その場合には新たなバックアップファイルそれぞれが新たな名前を得ます。必要なくなったときには古い番号付きバックアップを削除したり、Emacsにそれらを自動的に削除させることもできます。

性能的な理由によりオペレーティングシステムはバックアップファイルのコンテンツを二次ストレージに即座に書き込まないかもしれず、オリジナルデータとバックアップデータのいずれかが変更されるまでバックアップデータをエイリアスするかもしれません。ファイルと二次媒体を参照してください。


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

27.1.1 バックアップファイルの作成

Function: backup-buffer

この関数は、もしそれが適切ならカレントバッファーにvisitされているファイルのバックアップを作成する。これは最初のバッファー保存を行う前にsave-bufferにより呼び出される。

リネームによりバックアップが作成されると、リターン値は(modes extra-alist backupname)という形式のコンスセルになる。ここでmodesfile-modes (アクセシビリティのテストを参照)でリターンされるような元ファイルのモードビット、extra-alistfile-extended-attributes (拡張されたファイル属性を参照)によりリターンされるような元ファイルの拡張属性を示すalist、そしてbackupnameはバックアップの名前。

他のすべての場合(コピーによりバックアップが作成された、またはバックアップが作成されなかった)には、この関数はnilをリターンする。

Variable: buffer-backed-up

このバッファーローカル変数は、そのバッファーのファイルがバッファーによりバックアップされたかどうかを明示する。非nilならバックアップファイルは書き込み済み、それ以外なら(バックアップが有効なら)次回保存時にファイルはバックアップされる。この変数は永続的にローカルでありkill-all-local-variablesはこれを変更しない。

User Option: make-backup-files

この変数はバックアップファイルを作成するかどうかを決定する。非nilなら、Emacsは初回保存時にすべてのファイルのバックアップを作成する — ただしbackup-inhibitednilの場合(以下参照)。

以下の例はRmailバッファーだけで変数make-backup-filesを変更して、それ以外では変更しない方法を示す。この変数をnilにセットすると、Emacsはそれらのファイルのバックアップ作成をストップするのでディスク容量の消費を節約するだろう(あなたはこのコードをinitファイルに配置したいと思うかもしれない)。

(add-hook 'rmail-mode-hook
          (lambda () (setq-local make-backup-files nil)))
Variable: backup-enable-predicate

この変数の値は、あるファイルがバックアップファイルをもつべきかどうかを決定するために、特定のタイミングで呼び出される関数ある。この関数は判断対象の絶対ファイル名という1つの引数を受け取る。この関数がnilをリターンすると、そのファイルにたいするバックアップは無効になる。それ以外なら、このセクション内の他の変数がバックアップ作成の是非と方法を指定する。

デフォルト値はnormal-backup-enable-predicateで、これはtemporary-file-directorysmall-temporary-file-directory内のファイルをチェックする。

Variable: backup-inhibited

この変数が非nilならバックアップは抑制される。これはvisitされているファイル名にたいするbackup-enable-predicateのテスト結果を記録する。さらにvisitされているファイルにたいするバックアップ抑制にもとづいたその他の機構からも使用され得る。たとえばVCはバージョンコントロールシステムに管理されるファイルのバックアップを防ぐために、この変数を非nilにセットする。

これは永続的にローカルなのでメジャーモード変更により値は失われない。メジャーモードはこの変数ではなく、かわりにmake-backup-filesをセットすること。

User Option: backup-directory-alist

この変数の値はファイル名パターンとバックアップディレクトリーのalist。各要素は以下の形式をもつ

(regexp . directory)

この場合には名前がregexpにマッチするファイルのバックアップが、directory内に作成されるだろう。directoryには相対ディレクトリーか絶対ディレクトリーを指定できる。絶対ディレクトリーなら、マッチするすべてのファイルが同じディレクトリー内にバックアップされる。このディレクトリー内でのファイル名はクラッシュを避けるために、バックアップされるファイルの完全名のすべてのディレクトリー区切りが‘!’に変更される。結果の名前を切り詰めるファイルシステムでは、これは正しく機能しないだろう。

すべてのバックアップが単一のディレクトリーで行われる一般的なケースでは、alistは‘"."’と適切なディレクトリーからなるペアーという単一の要素を含むこと。

この変数がnil(デフォルト)、またはファイル名のマッチに失敗するとバックアップは元のファイルのディレクトリーに作成される。

長いファイル名がないMS-DOSファイルシステムでは、この変数は常に無視される。

User Option: make-backup-file-name-function

この変数の値はバックアップファイル名を作成する関数。関数make-backup-file-nameはこれを呼び出す。Naming Backup Filesを参照のこと。

特定のファイルにたいして特別なことを行うために、これをバッファーローカルにすることもできる。変更する場合には、backup-file-name-pfile-name-sans-versionsを変更する必要もあるかもしれない。


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

27.1.2 リネームかコピーのどちらでバックアップするか?

Emacsのバックアップファイル作成には2つの方法があります:

  • Emacsは元のファイルをリネームすることができ、それがバックアップファイルになる。その後、バッファーの保存は新たなファイルに書き込まれる。この手順の後には、元ファイルの他のすべての名前(ハードリンク)はバックアップファイルを参照することになる。新たなファイルの所有者は編集を行っているユーザーになり、グループはそのディレクトリー内でそのユーザーが新たなファイルを書き込んだときのデフォルトのグループになる。
  • Emacsは元のファイルをバックアップファイルにコピーでき、新たな内容はその後は元のファイルに上書きされる。この手順の後は、元のファイルの他のすべての名前(ハードリンク)は、そのファイルの(更新された)カレントバージョンを参照し続ける。ファイルの所有者とグループは変更されない。

デフォルトの方法は1つ目のリネームです。

変数backup-by-copyingが非nilなら、それは2つ目の方法、つまり元のファイルをコピーして新たなバッファー内容で上書きすることを意味します。変数file-precious-flagが非nilの場合にも、(メイン機能の副作用として)この効果があります。バッファーの保存を参照してください。

User Option: backup-by-copying

この変数が非nilなら、Emacsは常にコピーによりバックアップファイルを作成する。デフォルトはnil

以下の3つの変数が非nilの際は、ある特定のケースに2つ目の方法が使用されます。その特定のケースに該当しないファイルの処理には影響はありません。

User Option: backup-by-copying-when-linked

この変数が非nilなら、Emacsは複数名(ハードリンク)をもつファイルにたいしてコピーによりバックアップを作成する。デフォルトはnil

backup-by-copyingが非nilなら常にコピーによりバックアップが作成されるので、この変数はbackup-by-copyingnilのときだけ意味がある。

User Option: backup-by-copying-when-mismatch

この変数が非nil(デフォルト)なら、リネームによりファイルの所有者やグループが変更されるケースではEmacsはコピーによりバックアップを作成する。

リネームによりファイルの所有者やグループが変更されなければ、値に効果はない。つまり、そのディレクトリーで新たに作成されるファイルにたいするデフォルトのグループに属するユーザーにより所有されるファイルが該当する。

backup-by-copyingが非nilなら常にコピーによりバックアップが作成されるので、この変数はbackup-by-copyingnilのときだけ意味がある。

User Option: backup-by-copying-when-privileged-mismatch

この変数が非nilなら、特定のユーザーIDおよびグループIDの値(具体的には特定の値以下のID数値)にたいしてのみ、backup-by-copying-when-mismatchと同じように振る舞うことを指定する。変数にはその数値をセットする。

したがってファイル所有者の変更を防ぐ必要がある際には、backup-by-copying-when-privileged-mismatchを0にセットすればスーパーユーザーとグループ0だけがコピーによるバックアップを行うことができる。

デフォルトは200。


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

27.1.3 番号つきバックアップファイルの作成と削除

ファイルの名前がfooなら、番号付きバックアップのバージョン名はfoo.~v~となります。vfoo.~1~foo.~2~foo.~3~、…、foo.~259~のように、さまざまな整数です。

User Option: version-control

この変数は単一の非番号付きバックアップファイルを作成するか、それとも複数の番号付きバックアップを作成するかを制御する。

nil

visitされたファイルが番号付きバックアップなら番号付きバックアップを作成して、それ以外は作成しない。これがデフォルト。

never

番号付きバックアップを作成しない。

anything else

番号付きバックアップを作成する。

番号付きバックアップを使用することにより、バックアップのバージョン番号は最終的には非常に大きな番号になるので、それらを削除しなければなりません。Emacsはこれを自動で行うことができ、ユーザーに削除するか確認することもできます。

User Option: kept-new-versions

この変数の値は新たな番号付きバックアップが作成された際に保持するべき、もっとも新しいバージョンの個数。新たに作成されたバックアップもカウントされる。デフォルトは2。

User Option: kept-old-versions

この変数の値は新たな番号付きバックアップが作成された際に保持するべき、もっとも古いバージョンの個数。デフォルトは2。

番号が1、2、3、5、7のバックアップがあり、かつこれらの変数が値2をもつ場合には、番号が1と2のバックアップは古いバージョンとして保持されて、番号が5と7のバックアップは新しいバージョンとして保持される。そして番号が3のバックアップは余分なバックアップとなる。関数find-backup-file-name (バックアップファイルの命名を参照)は、どのバージョンのバックアップを削除するかを決定する役目を負うが、この関数自身がバックアップを削除する訳ではない。

User Option: delete-old-versions

この変数がtなら、ファイルの保存により余分なバージョンのバックアップは暗黙に削除される。nilなら余分なバックアップの削除前に確認を求めるて、それ以外なら余分なバックアップは削除されないことを意味する。

User Option: dired-kept-versions

この変数はDired内のコマンド. (ピリオド。dired-clean-directory)で、もっとも新しいバージョンのバックアップをいくつ保持するかを指定する。これは新たにバックアップファイルを作成する際にkept-new-versionsを指定するのと同等。デフォルトは2。


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

27.1.4 バックアップファイルの命名

このセクションでは、主にバックアップファイルの命名規則を再定義してカスタマイズできる関数を記載します。これらの1つを変更した場合には、おそらく残りも変更する必要があります。

Function: backup-file-name-p filename

この関数はfilenameがバックアップファイルとして利用可能なら非nil値をリターンする。これは名前のチェックだけを行って、filenameという名前のファイルが存在するかどうかはチェックしない。

(backup-file-name-p "foo")
     ⇒ nil
(backup-file-name-p "foo~")
     ⇒ 3

この関数の標準的な定義は、以下のようになる:

(defun backup-file-name-p (file)
  "FILEがバックアップファイルなら\
(番号付きか否かに関わらず)非nilをリターンする"
  (string-match "~\\'" file))

このようにファイル名が‘~’で終われば、この関数は非nil値をリターンする(ドキュメント文字列を分割するために1行目でバックスラッシュを使用しているが、これはドキュメント文字列内で単一行を生成する)。

この単純な式はカスタマイズのための再定義を簡便にするために、個々の関数内に配置されている。

Function: make-backup-file-name filename

この関数はファイルfilenameの非番号付きバックアップファイル名として使用される文字列をリターンする。Unixではこれは単にfilenameにチルダを追加する。

ほとんどのオペレーティングシステムでは、この関数の標準的な定義は以下のようになる:

(defun make-backup-file-name (file)
  "FILEにたいして非番号付きバックアップファイル名を作成する"
  (concat file "~"))

この関数を再定義することにより、バックアップファイルの命名規則を変更できる。以下はチルダの追加に加えて、先頭に‘.’を追加するようにmake-backup-file-nameを再定義する例:

(defun make-backup-file-name (filename)
  (expand-file-name
    (concat "." (file-name-nondirectory filename) "~")
    (file-name-directory filename)))

(make-backup-file-name "backups-ja.texi")
     ⇒ ".backups-ja.texi~"

Diredコマンドのいくつかを含むEmacsの一部では、バックアップファイル名が‘~’で終わることを仮定している。この規則にしたがわない場合、深刻な問題とはならないだろうが、それらのコマンドが若干好ましくない結果をもたらすかもしれない。

Function: find-backup-file-name filename

この関数はfilenameの新たなバックアップファイル用のファイル名を計算する。これは特定の既存バックアップファイルにたいする削除の提案も行うかもしれない。find-backup-file-nameCARが新たなバックアップファイル名、CDRが削除を提案するバックアップファイルのリストであるようなリストをリターンする。値にはnilも指定でき、これはバックアップが作成されないことを意味する。

kept-old-versionskept-new-versionsの2つの変数は、どのバージョンのバックアップを保持するべきかを決定する。この関数は値のCDRから該当するバージョンを除外することによってそれらを保持する。番号つきバックアップファイルの作成と削除を参照のこと。

以下の例の値は新しいバックアップファイルに使用する名前が~rms/foo.~5~~rms/foo.~3~は呼び出し側が削除を検討するべき余分なバージョンであることを示している。

(find-backup-file-name "~rms/foo")
     ⇒ ("~rms/foo.~5~" "~rms/foo.~3~")
Function: file-backup-file-names filename

この関数はfilenameにたいするバックアップファイルすべてのリスト、それらが存在しなければnilをリターンする。ファイルは更新日時(modification time)にたいして降順でソートされるので、もっとも最近に更新されたファイルが最初になる。

Function: file-newest-backup filename

この関数はfile-backup-file-namesがリターンするリストの最初の要素をリターンする。

ファイル比較関数のいくつかは、自動的にもっとも最近のバックアップを比較できるようにこの関数を使用している。


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

27.2 自動保存

Emacsは、visitしているすべてのファイルを定期的に保存します。これは自動保存(auto-saving)と呼ばれます。自動保存はシステムがクラッシュした場合に失われる作業量を、一定の作業量以下にします。デフォルトでは自動保存は300キーストロークごと、またはidleになった30秒後に発生します。自動保存に関するユーザー向けの情報についてはAuto-Saving: Protection Against Disasters in The GNU Emacs Manualを参照してください。ここでは自動保存の実装に使用される関数と、それらを制御する変数について説明します。

Variable: buffer-auto-save-file-name

このバッファーローカル変数はカレントバッファーの自動保存に使用されるファイル名。そのバッファーが自動保存されるべきでなければnil

buffer-auto-save-file-name
     ⇒ "/xcssun/users/rms/lewis/#backups-ja.texi#"
Command: auto-save-mode arg

これはバッファーローカルなマイナーモードであるAuto Saveモードにたいするモードコマンド。Auto Saveモードが有効なときはそのバッファーで自動保存が有効。呼び出し方法は他のマイナーモードと同様(マイナーモード記述の規約を参照)。

ほとんどのマイナーモードと異なりauto-save-mode変数は存在しない。buffer-auto-save-file-nameが非nilbuffer-saved-size(以下参照)が非0ならAuto Saveモードが有効。

Variable: auto-save-file-name-transforms

この変数はバッファーにたいしてauto-saveファイル名を作成する前にバッファーのファイル名に適用する変換(transform)をリストする。

この変換はそれぞれ(regexp replacement [uniquify])という形式のリスト。regexpはファイル名にたいしてマッチを行う正規表現であり、マッチしたらマッチ部分をreplacementで置き換えるためにreplace-matchが使用される。オプション要素uniquifyが非nilなら、クラッシュを回避するために変換ファイルのディレクトリー部分(クラッシュ回避のためにディレクトリー区切り文字はすべて‘!’に変更)とバッファーのファイル名を結合してauto-saveファイル名を構築する(ファイルシステムが結果となるファイルを切り詰める場合には正しく機能しないだろう)。

uniquifysecure-hash-algorithmsのメンバーのいずれかなら、バッファーのファイル名にsecure-hashを適用することによって、Emacsはauto-saveファイルのディレクトリー部分以外を構築する。これは極端に長いファイル名というリスクを回避する。

リストにあるすべての変換をリスト順に試行する。いずれかの変換が適用されたらそれが最終結果となり、それ以上の変換は試みられない。

デフォルト値ではリモートファイルのauto-saveファイルは一時ディレクトリーに置くようセットアップされている(一意なファイル名の生成を参照)。

長いファイル名がないMS-DOSファイルシステムでは、この変数は常に無視される。

Function: auto-save-file-name-p filename

この関数はfilenameがauto-saveファイルのような文字列なら非nilをリターンする。先頭と末尾がハッシュマーク(‘#’)であるような名前はauto-saveファイルの可能性があるという、auto-saveファイルにたいする通常の命名規則を想定する。引数filenameはディレクトリーパートを含まないこと。

(make-auto-save-file-name)
     ⇒ "/xcssun/users/rms/lewis/#backups-ja.texi#"
(auto-save-file-name-p "#backups-ja.texi#")
     ⇒ 0
(auto-save-file-name-p "backups-ja.texi")
     ⇒ nil
Function: make-auto-save-file-name

この関数はカレントバッファーの自動保存に使用されるファイル名をリターンする。これはファイル名の先頭と末尾にハッシュマーク(‘#’)を単に追加する。この関数は変数auto-save-visited-file-name(以下参照)を調べない。呼び出し側はまずその変数をチェックすること。

(make-auto-save-file-name)
     ⇒ "/xcssun/users/rms/lewis/#backups-ja.texi#"
User Option: auto-save-visited-file-name

この変数が非nilならEmacsはvisit中のファイルにバッファーを自動保存する。つまり自動保存は編集中ファイルと同じファイルにたいして行われる。この変数は通常はnilなので、auto-saveファイルはmake-auto-save-file-nameで作成された別の名前をもつ。

この変数の値を変更した際、バッファー内でauto-saveモードを再度有効にするまで、既存バッファーにたいして新たな値は効果をもたない。すでにauto-saveモードが有効なら、再度auto-save-modeが呼び出されるまで同じファイルに自動保存が行われる。

この変数を非nilにセットしても自動保存とバッファーの保存は異なるという事実は変わらないことに注意(バッファーの保存で説明したフックはバッファーが自動保存された際には実行されない)。

Function: recent-auto-save-p

この関数はカレントバッファーが最後に読み込み、または保存されて以降に自動保存されていればtをリターンする。

Function: set-buffer-auto-saved

この関数はカレントバッファーを自動保存済みとマークする。そのバッファーは、バッファーテキストが再度変更されるまで自動保存されないだろう。この関数はnilをリターンする。

User Option: auto-save-interval

この変数の値は自動保存の頻度を入力イベント数で指定する。この分の入力イベント読み取りごとに、Emacsは自動保存が有効なすべてのバッファーにたいして自動保存を行う。これを0にするとタイプした文字数にもとづいた自動保存は無効になる。

User Option: auto-save-timeout

この変数の値は自動保存が発生すべきidle時間の秒数。この秒数分ユーザーが休止するたびに、Emacsは自動保存が有効なすべてのバッファーにたいして自動保存を行う(カレントバッファーが非常に大きければ、指定されたタイムアウトはサイズ増加とともに増加される因子で乗ぜられる。この因子は1MBのバッファーにたいしておよそ4)。

値が0かnilならidle時間にもとづいた自動保存は行われず、auto-save-intervalで指定される入力イベント数の後のみ自動保存が行われる。

Variable: auto-save-hook

このノーマルフックは自動保存が行われようとするたびに毎回実行される。

User Option: auto-save-default

この変数が非nilならファイルをvisitするバッファーの自動保存がデフォルトで有効になり、それ以外では有効にならない。

Command: do-auto-save &optional no-message current-only

この関数は自動保存される必要があるすべてのバッファーを自動保存する。これは自動保存が有効なバッファーであり、かつ前回の自動保存以降に変更されたすべてのバッファーを保存する。

いずれかのバッファーが自動保存される場合には、do-auto-saveは自動保存が行われる間、通常はそれを示すメッセージ‘Auto-saving...’をエコーエリアに表示する。しかしno-messageが非nilならこのメッセージは抑制される。

current-onlyが非nilなら、カレントバッファーだけが自動保存される。

Function: delete-auto-save-file-if-necessary &optional force

この関数はdelete-auto-save-filesが非nilならカレントバッファーのauto-saveファイルを削除する。これはバッファー保存時に毎回呼び出される。

この関数はforcenilなら最後に本当の保存が行われて以降、カレントEmacsセッションにより書き込まれたファイルだけを削除する。

User Option: delete-auto-save-files

この変数は関数delete-auto-save-file-if-necessaryにより使用される。これが非nilなら、Emacsは(visitされているファイルに)本当に保存が行われたときにauto-saveファイルを削除する。これはディスク容量を節約してディレクトリーを整理する。

Function: rename-auto-save-file

この関数はvisitされているファイルの名前が変更されていればカレントバッファーのauto-saveファイルの名前を調整する。これはカレントEmacsセッションでauto-saveファイルが作成されていれば、既存のauto-saveファイルのリネームも行う。visitされているファイルの名前が変更されていなければ、この関数は何も行わない。

Variable: buffer-saved-size

このバッファーローカル変数の値はカレントバッファーが最後に読み取り、保存、または自動保存されたときのバッファーの長さ。これはサイズの大幅な減少の検知に使用され、それに応じて自動保存がオフに切り替えられる。

-1なら、それはサイズの大幅な減少によりそのバッファーの自動保存が一時的に停止されていることを意味する。明示的な保存によりこの変数に正の値が格納されて、自動保存が再び有効になる。自動保存をオフやオンに切り替えることによってもこの変数は更新されるので、サイズの大幅な減少は忘れられさられる。

-2なら、特にバッファーサイズの変更により一時的に自動保存を停止されないように、そのバッファーがバッファーサイズの変更を無視することを意味する。。

Variable: auto-save-list-file-name

この変数は、(非nilなら)すべてのauto-saveファイルの名前を記録するファイルを指定する。Emacsが自動保存を行うたびには自動保存が有効な各バッファーごとに2行ずつ書き込みを行う。1行目はvisitされているファイルの名前(ファイルをvisitしないバッファーの場合は空)、2行目はauto-saveファイルの名前を示す。

Emacsを正常にexitした際にこのファイルは削除される。Emacsがクラッシュした場合にはこのファイルを調べることにより、失われるはずだった作業を含んだすべてのauto-saveファイルを探すことができる。recover-sessionコマンドはそれらを見つけるためにこのファイルを使用する。

このファイルにたいするデフォルト名は、ユーザーのホームディレクトリーにある‘.saves-’で始まるファイルを指定する。この名前にはEmacsのプロセスIDとホスト名も含まれる。

User Option: auto-save-list-file-prefix

initファイルを読み込んだ後、(nilにセット済みでなければ)Emacsはこのプレフィックスにもとづいたホスト名とプロセスIDを追加して、auto-save-list-file-nameを初期化する。initファイル内でこれをnilにセットした場合には、Emacsはauto-save-list-file-nameを初期化しない。


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

27.3 リバート

あるファイルにたいして大きな変更を行った後、気が変わって元に戻したくなった場合は、revert-bufferコマンドでそのファイルの以前のバージョンを読み込むことにより、それらの変更を取り消すことができます。詳細は、Reverting a Buffer in The GNU Emacs Manualを参照してください。

Command: revert-buffer &optional ignore-auto noconfirm preserve-modes

このコマンドはバッファーのテキストをディスク上のvisitされているファイルのテキストで置き換える。これによりファイルがvisitや保存された以降に行ったすべての変更はアンドゥ(undo: 取り消し)される。

デフォルトでは、最新のauto-saveファイルのほうがvisitされているファイルより新しく引数ignore-autonilなら、revert-bufferはユーザーにたいしてかわりにauto-saveファイルを使用するかどうか確認を求める。このコマンドをinteractiveに呼び出したときプレフィックス数引数が指定されていなければ、ignore-autotとなる。つまりinteractive呼び出しは、デフォルトではauto-saveファイルのチェックを行わない。

revert-bufferは通常はバッファーを変更する前に確認を求める。しかし引数noconfirmが非nilならrevert-bufferは確認を求めない。

このコマンドは通常はnormal-modeを使用することにより、そのバッファーのメジャーモードとマイナーモードを再初期化する。しかしpreserve-modesが非nilならモードは変更されずに残る。

リバート(revert: 戻す、復元する)はinsert-file-contentsの置き換え機能を使用することにより、バッファー内のマーカー位置の保持を試みる。バッファーのコンテンツとファイルのコンテンツがリバート操作を行う前と等しければリバートはすべてのマーカーを保持する。等しくなければリバートによってバッファーは変更される。この場合は、(もしあれば)バッファーの最初と最後にある未変更のテキスト内にあるマーカーは保持される。他のマーカーを保持してもそれらは正しくないだろう。

ファイル以外のソースからリバートする際には、通常はマーカーは保持されないが、これはrevert-buffer-functionの個別の実装次第である。

Variable: revert-buffer-in-progress-p

revert-bufferは処理を行っている間、この変数を非nil値にバインドする。

このセクションの残りの部分で説明する変数をセットすることにより、revert-bufferが処理方法をカスタマイズできます。

User Option: revert-without-query

この変数は問い合わせなしでリバートされるファイルのリストを保持する。値は正規表現のリスト。visitされているファイルの名前がこれらの正規表現のいずれかにマッチし、かつバッファーが未変更だがディスク上のファイルは変更されていれば、revert-bufferはユーザーに確認を求めることなくファイルをリバートする。

いくつかのメジャーモードは以下の変数をローカルにバインドすることによりrevert-bufferをカスタマイズします:

Variable: revert-buffer-function

この変数の値はそのバッファーをリバートするために使用する関数。これはリバート処理を行うために2つのオプション引数をとる関数であること。2つのオプション引数ignore-autonoconfirmrevert-bufferが受け取る引数である。

Diredモードのような編集されるテキストにファイルのコンテンツが含まれず他の方式によって再生成され得るモードは、この変数のバッファーローカル値にコンテンツを再生成する特別な関数を与えることができる。

Variable: revert-buffer-insert-file-contents-function

この変数の値はそのバッファーをリバートする際に更新されたコンテンツの挿入に使用される関数を指定する。その関数は2つの引数を受け取る。1つ目は使用するファイル名で2つ目がtなら、ユーザーはauto-saveファイルの読み込みにたいして確認を求められる。

revert-buffer-functionのかわりにこの変数をモードが変更する理由は、revert-bufferが行残りの処理(ユーザーへの確認、アンドゥリストのクリアー、適切なメジャーモードの決定、以下のフックの実行)にたいする重複や置き換えを避けるためである。

Variable: before-revert-hook

このノーマルフックは変更されたコンテンツを挿入する前に、デフォルトのrevert-buffer-functionにより実行される。カスタマイズしたrevert-buffer-functionは、このフックを実行するかどうか判らない。

Variable: after-revert-hook

このノーマルフックは変更されたコンテンツを挿入した後に、デフォルトのrevert-buffer-functionによって実行される。カスタマイズしたrevert-buffer-functionは、このフックを実行するかどうか判らない。

Emacsはバッファーを自動的にリバートできます。これはファイルをvisitしているバッファーにはデフォルトで行われます。以下では新たなタイプのバッファーにたいして自動リバートのサポートを追加する方法を説明します。

そのようなバッファーはまず適切に定義されたrevert-buffer-functionbuffer-stale-functionをもたなければなりません。

Variable: buffer-stale-function

この変数の値はバッファーがリバートを要するかどうかをチェックするために呼び出される関数を指定する。デフォルト値では、修正時刻をチェックすることによりファイルをvisitするバッファーだけを処理する。ファイルをvisitしないバッファーにはオプション引数を1つ受け取るカスタム関数が必要になる。この関数はバッファーをリバートする必要があれば非nilをリターンする。関数の呼び出し時にはそのバッファーがカレントになる。

この関数は主として自動リバートを意図しているが、他の用途にも使用できる。たとえば自動リバートが有効でなければ、ユーザーにバッファーのリバートが必要なバッファーを警告するために使用できる。noconfirm引数の背景にあるアイデアは、ユーザーへの確認なしでバッファーがリバートされるようならt、関数がバッファーの期限切れをユーザーに警告する。特に自動リバートにおける使用ではnoconfirmtになる。関数が自動リバートにたいしてのみ使用されるようならnoconfirm引数は無視できる。

(Buffer Menuのように) auto-revert-interval秒ごとに自動リバートをしたければバッファーのモード関数で:

(setq-local buffer-stale-function
     (lambda (&optional noconfirm) 'fast))

を使用する。

特別なリターン値‘fast’はリバートの必要性はチェックしていないがバッファーのリバートは高速であることを告げる。さらにauto-revert-verboseが非nilでもリバートメッセージを何もプリントしないようにAuto Revertに指示する。auto-revert-interval秒ごとのリバートメッセージが非常に煩雑になり得ることから、これは重要である。自動リバート以外の目的でこの関数が考慮される場合には、リターン値が提供する情報は有用になるかもしれない。

バッファーが適切なrevert-buffer-functionbuffer-stale-functionをもった後にも、通常はいくつかの問題が残ります。

未変更とマークされた場合のみバッファーは自動リバートされます。したがって種々の関数はリバートにより失われるかもしれない情報をバッファーが含む場合や、ユーザーがバッファーにたいして作業を行っていて自動リバートがユーザーにとって不便だと確信できる理由がある場合にのみバッファーを変更済みとマークすることを保証する必要があるでしょう。バッファーの変更状態を手動で調整することによりユーザーは常にこれをオーバーライドできます。これをサポートするために、未変更とマークされたバッファーでのrevert-buffer-function呼び出しでは、常にバッファーの未変更とマークされた状態を保つ必要があります。

自動リバートの結果としてその前後で連続してポイントがジャンプしないことを保証することが重要です。もちろんバッファーが根本的に変更されればポイントの移動は必然的かもしれません。

revert-buffer-functionauto-revert-verbosetの場合に表示されるAuto Revert自身のメッセージを不必要に重複してプリントしないことと、auto-revert-verboseにたいするnil値を効果的にオーバーライドすることを保証する必要があります。したがって自動リバートにたいするモードの調整には、このようなメッセージを取り除くことを要する場合が多々あります。とりわけこれはauto-revert-interval秒ごとに自動的にリバートされるバッファーにおいて重要です。

新しい自動リバートがEmacsの一部であるなら、global-auto-revert-non-file-buffersのドキュメント文字列でそれに言及するべきです。

同様にEmacsマニュアル内に追加でドキュメントするべきです。


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

28 バッファー

バッファー(buffer)とは編集されるテキストを含んだLispオブジェクトのことです。バッファーはvisitされるファイルのコンテンツを保持するために使用されます。しかしファイルをvisitしないバッファーも存在します。一度に複数のバッファーが存在するかもしれませんが、カレントバッファー(current buffer)に指定できるのは常に1つのバッファーだけです。ほとんどの編集コマンドはカレントバッファーのコンテンツにたいして作用します。カレントバッファーを含むすべてのバッファーは任意のウィンドウ内に表示されるときもあれば、表示されない場合もあります。


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

28.1 バッファーの基礎

バッファー(buffer)とは編集されるテキストを含むLispオブジェクトのことです。バッファーはvisitされるファイルのコンテンツを保持するために使用されます。しかしファイルをvisitしないバッファーも存在します。一度に複数のバッファーが存在するかもしれませんが、カレントバッファー(current buffer)に指定できるのは常に1つのバッファーだけです。ほとんどの編集コマンドはカレントバッファーのコンテンツにたいして作用します。カレントバッファーを含むすべてのバッファーは、いずれかのウィンドウ内に表示されるときもあるし、表示されない場合もあります。

Emacs編集におけるバッファーとは個別に名前をもち、編集可能なテキストを保持するオブジェクトです。Lispプログラムにおけるバッファーはスペシャルデータ型として表されます。バッファーのコンテンツを拡張可能な文字列と考えることができます。挿入と削除はバッファー内の任意の箇所で発生し得ます。テキストを参照してください。

Lispのバッファーオブジェクトは多くの情報要素を含んでいます。これらの情報のいくつかは変数を通じてプログラマーが直接アクセスできるのにたいして、その他の情報は特殊な目的のための関数を通じてのみアクセスすることができます。たとえばvisitされているファイルの名前は変数を通じて直接アクセスできますが、ポイント値はプリミティブ関数からのみアクセスできます。

直接アクセス可能なバッファー固有の情報は、バッファーローカル(buffer-local)な変数バインディング内に格納されます。これは特定のバッファー内だけで効力のある変数値のことです。この機能により、それぞれのバッファーは特定の変数の値をオーバーライドすることができます。ほとんどのメジャーモードはこの方法でfill-columncomment-columnのような変数をオーバーライドしています。バッファーローカルな変数、およびそれらに関連する関数についての詳細はバッファーローカル変数を参照してください。

バッファーからファイルをvisitする関数および変数についてはファイルのvisitバッファーの保存を参照してください。ウィンドウ内へのバッファー表示に関連する関数および変数についてはバッファーとウィンドウを参照してください。

Function: bufferp object

この関数はobjectがバッファーならt、それ以外はnilをリターンする。


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

28.2 カレントバッファー

一般的に1つのEmacsセッション内には多くのバッファーが存在します。常にそれらのうちの1つがカレントバッファー(current buffer)に指定されます。カレントバッファーとは、ほとんどの編集が行われるバッファーのことです。テキストを調べたり変更するプリミティブのほとんどは暗黙にカレントバッファーにたいして処理を行います(テキストを参照)。

通常は選択されたウィンドウ(ウィンドウの選択を参照)の中に表示されるバッファーがカレントバッファーですが、常にそうであるとは言えません。Lispプログラムはバッファーのコンテンツを処理するために、スクリーン上に表示されているものを変更することなく任意のバッファーを一時的にカレントに指定できます。カレントバッファーの指定にたいするもっとも基本的な関数はset-bufferです。

Function: current-buffer

この関数はカレントバッファーをリターンする。

(current-buffer)
     ⇒ #<buffer buffers-ja.texi>
Function: set-buffer buffer-or-name

この関数はbuffer-or-nameをカレントバッファーにする。buffer-or-nameは既存のバッファー、または既存のバッファーの名前でなければならない。リターン値はカレントになったバッファー。

この関数はそのバッファーをどのウィンドウにも表示しないので、必然的にユーザーはそのバッファーを見ることはできない。しかしLispプログラムはその後に、そのバッファーにたいして処理を行うことになるだろう。

編集コマンドがエディターコマンドループにリターンする際、Emacsは選択されたウィンドウ(ウィンドウの選択を参照)の中に表示されているバッファーにたいして、自動的にset-bufferを呼び出します。これは混乱を防ぐためであり、これによりEmacsがコマンドを読み取るときにカーソルのあるバッファーが、コマンドを適用されるバッファーになることが保証されます(コマンドループを参照)。したがって異なるバッファーを指示して切り替える場合にはset-bufferを使用するべきではありません。これを行うためにはウィンドウ内のバッファーへの切り替えで説明されている関数を使用してください。

Lisp関数を記述する際は、処理後にカレントバッファーをリストアするためにコマンドループのこの振る舞いに依存しないでください。編集コマンドはコマンドループだけではなく、他のプログラムからLisp関数としても呼び出されます。呼び出し側にとっては、そのサブルーチンがカレントだったバッファーを変更しないほうが便利です(もちろんそれがサブルーチンの目的でない場合)。

他のバッファーにたいして一時的に処理を行うには、save-current-bufferフォーム内にset-bufferを配置します。以下の例はコマンドappend-to-bufferの簡略版です:

(defun append-to-buffer (buffer start end)
  "リージョンのテキストをBUFFERに追加する"
  (interactive "BAppend to buffer: \nr")
  (let ((oldbuf (current-buffer)))
    (save-current-buffer
      (set-buffer (get-buffer-create buffer))
      (insert-buffer-substring oldbuf start end))))

ここではカレントバッファーを記録するためにローカル変数にバインドしてから、後でsave-current-bufferがそれを再びカレントにするようにアレンジしています。次にset-bufferが指定されたバッファーをカレントにして、insert-buffer-substringが元のバッファーの文字列を指定された(今はカレントの)バッファーにコピーします。

かわりにwith-current-bufferマクロを使用することもできます:

(defun append-to-buffer (buffer start end)
  "BUFFERにリージョンのテキストを追加する"
  (interactive "BAppend to buffer: \nr")
  (let ((oldbuf (current-buffer)))
    (with-current-buffer (get-buffer-create buffer)
      (insert-buffer-substring oldbuf start end))))

いずれのケースでも、追加されるバッファーが偶然他のウィンドウに表示されていると、次回の再表示でそのテキストがどのように変更されたか表示されるでしょう。どのウィンドウにも表示されていなければスクリーン上で即座に変更を目にすることはありません。コマンドはバッファーを一時的にカレントにしますが、そのことがバッファーの表示を誘発する訳ではありません。

バッファーローカルなバインディングをもつ変数にたいして、(letや関数引数などで)ローカルバインディングを作成する場合には、そのローカルバインディングのスコープの最初と最後で同じバッファーがカレントとなることを確認してください。そうしないと、あるバッファーではバインドして他のバッファーではバインドされないことになるかもしれません!

set-bufferの使用において、カレントバッファーが戻ることに依存しないでください。なぜなら間違ったバッファーがカレントのときにquitが発生した場合には、その処理は行われないでしょう。たとえば上記の例に倣うと以下は間違ったやり方です:

  (let ((oldbuf (current-buffer)))
    (set-buffer (get-buffer-create buffer))
    (insert-buffer-substring oldbuf start end)
    (set-buffer oldbuf))

例で示したようにsave-current-bufferwith-current-bufferを使用すれば、quitやthrowを通常の評価と同様に処理できます。

Special Form: save-current-buffer body…

スペシャルフォームsave-current-bufferはカレントバッファーの識別を保存してbodyフォームを評価し、最後にそのバッファーをカレントにリストアする。リターン値はbody内の最後のフォームの値。throwやエラーを通じた異常exitの場合にもカレントバッファーはリストアされる(非ローカル脱出を参照)。

カレントとして使用されていたバッファーがsave-current-bufferによるexit時にkillされていたら、当然それが再びカレントとなることはない。かわりにexit直前にカレントバッファーが何であれ、それがカレントになる。

Macro: with-current-buffer buffer-or-name body…

with-current-bufferマクロはカレントバッファーの識別を保存してbuffer-or-nameをカレントにし、bodyフォームを評価してから最後にカレントバッファーをリストアする。buffer-or-nameには既存のバッファー、または既存のバッファー名を指定しなければならない。

リターン値はbody内の最後のフォームの値。throwやエラーを通じた異常exitの場合にも、カレントバッファーはリストアされる(非ローカル脱出を参照)。

Macro: with-temp-buffer body…

with-temp-bufferマクロは一時的なバッファーをカレントバッファーとしてbodyフォームを評価する。これはカレントバッファーの識別を保存して一時的なバッファーを作成、それをカレントとしてbodyフォームを評価して、一時バッファーをkillする間に以前のカレントバッファーをリストアする。

このマクロが作成したバッファーでは、デフォルトではアンドゥ情報(アンドゥを参照)は記録されない(が必要ならbodyで有効にできる)。また一時バッファーはkill-buffer-hookkill-buffer-query-functions (バッファーのkillを参照)、buffer-list-update-hook (バッファーリストを参照)のフックも実行しない。

リターン値はbody内の最後のフォームの値。最後のフォームとして(buffer-string)を使用することにより、一時バッファーのコンテンツをリターンできる。

throwやエラーを通じた異常exitの場合にも、カレントバッファーはリストアされる(非ローカル脱出を参照)。

Writing to Fileswith-temp-fileも参照のこと。


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

28.3 バッファーの名前

それぞれのバッファーは文字列で表される一意な名前をもちます。バッファーにたいして機能する関数の多くは、引数としてバッファーとバッファー名の両方を受け入れます。buffer-or-nameという名前の引数がこのタイプであり、それが文字列でもバッファーでもなければエラーがシグナルされます。bufferという名前の引数は名前ではなく実際のバッファーオブジェクトでなければなりません。

短命でユーザーが関心をもたないようなバッファーは名前がスペースで始まり、それらについてはlist-buffersbuffer-menuコマンドは無視します(がファイルをvisitしているようなバッファーは無視されない)。スペースで始まる名前は初期状態ではアンドゥ情報の記録も無効になっています。アンドゥを参照してください。

Function: buffer-name &optional buffer

この関数はbufferの名前を文字列としてリターンする。bufferのデフォルトはカレントバッファー。

buffer-namenilをリターンした場合、それはbufferがkillされていることを意味する。バッファーのkillを参照のこと。

(buffer-name)
     ⇒ "buffers-ja.texi"

(setq foo (get-buffer "temp"))
     ⇒ #<buffer temp>
(kill-buffer foo)
     ⇒ nil
(buffer-name foo)
     ⇒ nil
foo
     ⇒ #<killed buffer>
Command: rename-buffer newname &optional unique

この関数はカレントバッファーをnewnameにリネームする。newnameが文字列でなければエラーをシグナルする。

newnameがすでに使用済みなら、rename-bufferは通常はエラーをシグナルする。しかしuniqueが非nilなら、未使用の名前となるようにnewnameを変更する。interactiveに呼び出した場合は、プレフィックス数引数によりuniqueに非nilを指定できる(この方法によってコマンドrename-uniquelyは実装される)。

この関数は実際にバッファーに与えられた名前をリターンする。

Function: get-buffer buffer-or-name

この関数はbuffer-or-nameで指定されたバッファーをリターンする。buffer-or-nameが文字列で、かつそのような名前のバッファーが存在しなければ値はnilbuffer-or-nameがバッファーなら与えられたバッファーをリターンする。これは有用とは言い難く、引数は通常は名前である。たとえば:

(setq b (get-buffer "lewis"))
     ⇒ #<buffer lewis>
(get-buffer b)
     ⇒ #<buffer lewis>
(get-buffer "Frazzle-nots")
     ⇒ nil

バッファーの作成の関数get-buffer-createも参照のこと。

Function: generate-new-buffer-name starting-name &optional ignore

この関数は新たなバッファーにたいして一意となるような名前をリターンする — がバッファーは作成しない。この名前はstarting-nameで始まり内部が数字であるような‘<…>’を追加することにより、すべてのバッファーでカレントで使用されていない名前を生成する。この数字は2で始まり、既存バッファーの名前でないような名前になる数字まで増加される。

オプション引数ignoreが非nilなら、それは潜在的にバッファー名であるような文字列であること。これは、たとえそれが(通常は拒絶されるであろう)既存バッファーの名前であっても、試みられた場合には潜在的に受容可能なバッファーとして考慮することを意味する。つまり‘foo’、‘foo<2>’、‘foo<3>’、‘foo<4>’という名前のバッファーが存在する場合には、

(generate-new-buffer-name "foo")
     ⇒ "foo<5>"
(generate-new-buffer-name "foo" "foo<3>")
     ⇒ "foo<3>"
(generate-new-buffer-name "foo" "foo<6>")
     ⇒ "foo<5>"

バッファーの作成の関連する関数generate-new-bufferも参照のこと。


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

28.4 バッファーのファイル名

バッファーファイル名(buffer file name)とは、そのバッファーにvisitされているファイルの名前です。バッファーがファイルをvisitしていなければ、バッファーファイル名はnilです。バッファー名は大抵はバッファーファイル名の非ディレクトリーパートと同じですが、バッファーファイル名とバッファー名は別物であり個別にセットすることができます。ファイルのvisitを参照してください。

Function: buffer-file-name &optional buffer

この関数はbufferがvisitしているファイルの絶対ファイル名をリターンする。bufferがファイルをvisitしていなければ、buffer-file-namenilをリターンする。bufferが与えられない場合のデフォルトはカレントバッファー。

(buffer-file-name (other-buffer))
     ⇒ "/usr/user/lewis/manual/files-ja.texi"
Variable: buffer-file-name

このバッファーローカル変数はカレントバッファーにvisitされているファイルの名前、ファイルをvisitしていなければnil。これは永続的なローカル変数でありkill-all-local-variablesの影響を受けない。

buffer-file-name
     ⇒ "/usr/user/lewis/manual/buffers-ja.texi"

他のさまざまな事項を変更せずにこの変数を変更するのは危険である。通常はset-visited-file-nameを使用するほうがよい(以下参照)。バッファー名の変更などのような、そこで行われることのいくつかは絶対必要という訳ではないが、その他の事項はEmacsが混乱するのを防ぐために必要不可欠である。

Variable: buffer-file-truename

このバッファーローカル変数はカレントバッファーにvisitされているファイルの省略された形式の実名(truename)、ファイルをvisitしていなければnilを保持する。これは永続的にローカルでありkill-all-local-variablesの影響を受けない。See 本当の名前abbreviate-file-nameを参照のこと。

Variable: buffer-file-number

このバッファーローカル変数はカレントバッファーにvisitされているファイルのinode番号とディレクトリーデバイス識別子、ファイルをvisitしていなければnilを保持する。これは永続的にローカルでありkill-all-local-variablesの影響を受けない。

値は通常は(inodenum device)のような形式のリスト。このタプル(tuple: 組)はシステム上でアクセス可能なすべてのファイルの中からファイルを一意に識別する。より詳細な情報はファイルの属性file-attributesを参照のこと。

buffer-file-nameがシンボリックリンク名なら、inodenumdeviceの両方がリンクのターゲットを再帰的に参照する。

Function: get-file-buffer filename

この関数はファイルfilenameをvisitしているバッファーをリターンする。そのようなバッファーが存在しなければnilをリターンする。引数filenameは文字列でなければならず、展開(ファイル名を展開する関数を参照)された後に、killされていないすべてのバッファーがvisitしているファイル名と比較される。バッファーのbuffer-file-namefilenameの展開形と正確にマッチしなければならないことに注意。この関数は同じファイルにたいする他の名前は認識しないだろう。

(get-file-buffer "buffers-ja.texi")
    ⇒ #<buffer buffers-ja.texi>

特殊な状況下では、複数のバッファーが同じファイル名をvisitすることがあり得る。そのような場合には、この関数はバッファーリスト内の最初に該当するバッファーをリターンする。

Function: find-buffer-visiting filename &optional predicate

これはget-file-bufferと似ているが、そのファイルを違う名前でvisitしているかもしれないすべてのバッファーをリターンする。つまりバッファーのbuffer-file-namefilenameの展開形式と正確にマッチする必要はなく、同じファイルを参照することだけが要求される。predicateが非nilなら、それはfilenameをvisitしているバッファーを1つの引数とする関数であること。そのバッファーにたいしてpredicateが非nilをリターンした場合のみ適切なリターン値と判断される。リターンすべき適切なバッファーが見つからなければ、find-buffer-visitingnilをリターンする。

Command: set-visited-file-name filename &optional no-query along-with-file

filenameが非空文字列なら、この関数はカレントバッファーにvisitされているファイルの名前をfilenameに変更する(バッファーがファイルをvisitしていなければvisitするファイルとしてfilenameを与える)。そのバッファーにたいする次回の保存では、新たに指定されたファイルに保存されるだろう。

このコマンドは、たとえそのバッファーのコンテンツがその前にvisitされていたファイルとマッチしていても、(Emacsが関知するかぎり) filenameのコンテンツとはマッチしないのでバッファーが変更されている(modified)とマークする。これはその名前がすでに使用されていなければ、新たなファイル名に対応してバッファーをリネームする。

filenamenilか空文字列なら、それは“visitされているファイルがない”ことを意味する。この場合にはset-visited-file-nameはバッファーの変更フラグを変更することなく、そのバッファーがファイルをvisitしていないとマークする。

この関数はfilenameをvisitしているバッファーがすでに存在する場合は、通常はユーザーに確認を求める。しかしno-queryが非nilならこの質問を行わない。filenameをvisitしているバッファーがすでに存在し、かつユーザーが承認するかno-queryが非nilなら、この関数は中に数字が入った‘<…>’をfilenameに追加して新たなバッファーの名前を一意にする。

along-with-fileが非nilなら、それは前にvisitされていたファイルがfilenameにリネームされたと想定することを意味する。この場合、コマンドはバッファーの修正フラグを変更せず、そのバッファーの記録されている最終ファイル変更時刻をvisited-file-modtimeが報告する時刻(バッファーの変更時刻を参照)で変更することもしない。along-with-filenilなら、この関数はvisited-file-modtimeが0をリターンした後に、記録済みの最終ファイル変更時刻をクリアーする。

関数set-visited-file-nameがinteractiveに呼び出されたときはミニバッファー内でfilenameの入力を求める。

Variable: list-buffers-directory

このバッファーローカル変数はvisitしているファイル名をもたないバッファーにたいして、バッファーリスト中のvisitしているファイル名を表示する場所に表示する文字列を指定する。Diredバッファーはこの変数を使用する。


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

28.5 バッファーの変更

Emacsは各バッファーにたいしてバッファーのテキストを変更したかどうかを記録するために、変更フラグ(modified flag)と呼ばれるフラグを管理しています。このフラグはバッファーのコンテンツを変更すると常にtにセットされ、バッファーを保存したときnilにクリアーされます。したがってこのフラグは保存されていない変更があるかどうかを表します。フラグの値は通常はモードライン内(モードラインで使用される変数を参照)に表示され、保存(バッファーの保存を参照)と自動保存(自動保存を参照)を制御します。

いくつかのLispプログラムは、このフラグを明示的にセットします。たとえば、関数set-visited-file-nameは、このフラグをtにセットします。なぜなら、たとえその前にvisitしていたファイルが変更されていなくても、テキストは新たにvisitされたファイルとマッチしないからです。

バッファーのコンテンツを変更する関数はテキストで説明されています。

Function: buffer-modified-p &optional buffer

この関数はbufferが最後に読み込まれた、あるいは保存されて以降に変更されていれば非nil、そうでなければnilをリターンする。bufferが最後に変更されて以降に自動保存されていれば、この関数はシンボルautosavedをリターンする。bufferbufferか省略の際のデフォルトはカレントバッファー。

Function: set-buffer-modified-p flag

この関数はflagが非nilならカレントバッファーを変更済みとして、nilなら未変更としてマークする。

この関数を呼び出すことによる別の効果は、それがカレントバッファーのモードラインの無条件な再表示を引き起こすことである。実際のところ関数force-mode-line-updateは以下を行うことにより機能する:

(set-buffer-modified-p (buffer-modified-p))
Function: restore-buffer-modified-p flag

set-buffer-modified-pと同様だがモードラインの再表示を強制しない。この関数のflagの値にシンボルautosavedも指定できる。これによりバッファーは変更されていること、そして最後に変更された後にauto-saveされているものとしてマークされる。

Command: not-modified &optional arg

このコマンドはカレントバッファーが変更されておらず保存する必要がないとマークする。argが非nilなら変更されているとマークするので、次回の適切なタイミングでバッファーは保存されるだろう。interactiveに呼び出された場合には、argはプレフィックス引数。

この関数はエコーエリア内にメッセージをプリントするのでプログラム内で使用してはならない。かわりにset-buffer-modified-p (上述)を使用すること。

Function: buffer-modified-tick &optional buffer

この関数はbufferの変更カウント(modification-count)をリターンする。これはバッファーが変更されるたびに増加されるカウンター。buffernil (または省略)ならカレントバッファーが使用される。

Function: buffer-chars-modified-tick &optional buffer

この関数はbufferの文字変更に関わる変更カウントをリターンする。テキストプロパティを変更してもこのカウンターは変化しない。しかしそのバッファーにテキストが挿入または削除されるたびに、このカウンターはbuffer-modified-tickによりリターンされるであろう値にリセットされる。buffer-chars-modified-tickを2回呼び出してリターンされる値を比較することにより、その呼び出しの間にバッファー内で文字変更があったかどうかを知ることができる。buffernil (または省略)ならカレントバッファーが使用される。

テキストプロパティの変更の等、バッファーのテキストを実際には変更しない方法でバッファーを変更することを要する場合があります。プログラムがフックやバッファー変更にたいするリアクションを何もトリガーせずにバッファーを変更する必要がある場合には、with-silent-modificationsマクロを使用します。

Macro: with-silent-modifications body…

バッファーを変更しないように装ってbodyを実行する。これにはバッファーのファイルがロックされているかどうかのチェック(ファイルのロックを参照)、バッファーの変更フック(フックの変更を参照)等が含まれる。(バッファーのテキストプロパティとは対照的に)bodyが実際にバッファーテキストを変更する場合にはアンドゥするデータが破損するかもしれないことに注意。


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

28.6 バッファーの変更時刻

あるファイルをvisitしてそのバッファー内で変更を行い、その一方ではディスク上でファイル自身が変更されたとします。この時点でバッファーを保存するとファイル内の変更は上書きされるでしょう。これが正に望んでいる動作のときもありますが、通常は有用な情報が失われてしまいます。したがってEmacsはファイルを保存する前に、以下で説明する関数を使用してファイルの変更時刻をチェックします(ファイルの変更時刻を調べる方法はファイルの属性を参照)。

Function: verify-visited-file-modtime &optional buffer

この関数はbuffer(デフォルトはカレントバッファー)にvisitされているファイルにたいして記録されている変更時刻と、オペレーティングシステムにより記録された実際の変更時刻を比較する。これら2つの時刻はEmacsがそのファイルをvisitか保存して以降、他のプロセスにより書き込みがされていなければ等しくなるはずである。

この関数は実際の最終変更時刻とEmacsが記録した変更時刻が同じならt、それ以外はnilをリターンする。そのバッファーが記録済みの最終変更時刻をもたない、すなわちvisited-file-modtimeが0をリターンするような場合にもtをリターンする。

これはたとえvisited-file-modtimeが非0の値をリターンしたとしても、ファイルをvisitしていないバッファーにたいしては常にtをリターンする。たとえばDiredバッファーにたいして、この関数は常にtをリターンする。また存在せず、 以前に存在したこともなかったファイルをvisitするバッファーにたいしてtをリターンするが、visitしているファイルが削除されたバッファーにたいしてはnilをリターンする。

Function: clear-visited-file-modtime

この関数はカレントバッファーによりvisitされているファイルの最終変更時刻の記録をクリアーする。結果としてこのバッファーにを次回の保存ではファイルの変更時刻の食い違いは報告されなくなる。

この関数はset-visited-file-name、および変更済みファイルの上書きを防ぐための通常テストを行わない例外的な箇所で呼び出される。

Function: visited-file-modtime

この関数はカレントバッファーにたいして記録された最終ファイル変更時刻をLispタイムスタンプ(時刻を参照)としてリターンする。

バッファーが最終変更時刻の記録をもたなければこの関数は0をリターンする。これが発生するのは、たとえばバッファーがファイルをvisitしていなかったり、clear-visited-file-modtimeで最終変更時刻が明示的にクリアーされた場合。しかしvisited-file-modtimeは、いくつかの非ファイルバッファーにたいするタイムスタンプをリターンすることに注意。たとえばディレクトリーをリストするDiredバッファーでは、Diredが記録するそのディレクトリーの最終変更時刻がリターンされる。

バッファーが存在しないファイルをvisitしている場合には、この関数は-1をリターンする。

Function: set-visited-file-modtime &optional time

この関数はバッファーがvisitしているファイルの最終変更時刻の記録を、timeが非nilならtime、それ以外はvisitしているファイルの最終変更時刻に更新する。

timenilvisited-file-modtimeがリターンする整数フラグでなければ、それはLispのtime値であること(時刻を参照)。

この関数はバッファーが通常のようにファイルから読み取られたものでない場合や、ファイル自身が害のない既知の理由により変更されている場合に有用。

Function: ask-user-about-supersession-threat filename

これはvisitしているファイルfilenameがバッファーのテキストより新しいときにバッファーの変更を試みた後に、ユーザーに処理方法を尋ねるために使用する関数。Emacsはディスク上のファイルの変更時刻がバッファーを最後に保存した時刻新しいかどうか、バッファーのコンテンツが変更されているかによりこれを検知する。これはおそらく他のプログラムがファイルを変更したことを意味する。

この関数が正常にリターンするかどうかは、ユーザーの応答に依存する。関数はバッファーの変更が処理された場合は正常にリターンし、バッファーの変更が許可されなかった場合はデータ(filename)とともにエラーfile-supersessionをシグナルする。

この関数は適切なタイミングでEmacsにより自動的に呼び出される。これは再定義することによりEmacsをカスタマイズ可能にするために存在する。標準的な定義はファイルuserlock.elを参照のこと。

ファイルのロックのファイルロックのメカニズムも参照されたい。


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

28.7 読み取り専用のバッファー

あるバッファーが読み取り専用(read-only)の場合には、たとえスクロールやナローイングによってファイルのコンテンツのビューを変更しても、そのコンテンツを変更することはできません。

読み取り専用バッファーは、2つのタイプの状況において使用されます:

  • 書き込み保護されたファイルをvisitするバッファーは、通常は読み取り専用になる。

    ここでの目的はユーザーにたいしてそのファイルへの保存を意図したバッファーの編集が無益、または望ましくないかもしれないことを伝えることである。それにも関わらずバッファーのテキストの変更を望むユーザーは、C-x C-qで読み取り専用フラグをクリアーした後にこれを行うことができる。

  • DiredやRmailのようなモードは、通常の編集コマンドによるコンテンツの変更がおそらく間違いであるようなときにバッファーを読み取り専用にする。

    このようなモードのスペシャルコマンドは、buffer-read-onlyを(letによって)nilにバインドしたり、テキストを変更する箇所ではinhibit-read-onlytにバインドする。

Variable: buffer-read-only

このバッファーローカル変数は、そのバッファーが読み取り専用かどうかを指定する。この変数が非nilならそのバッファーは読み取り専用。しかしテキストプロパティinhibit-read-onlyをもつ文字は依然として編集可能。inhibit-read-onlyを参照のこと。

Variable: inhibit-read-only

この変数が非nilなら、読み取り専用バッファー、およびその実際の値に依存して、一部もしくはすべての読み取り専用文字が変更されている。バッファー内の読み取り専用文字とはテキストプロパティread-onlyが非nilの文字。テキストプロパティについての詳細は特殊な意味をもつプロパティを参照のこと。

inhibit-read-onlytなら、すべてのread-only文字プロパティは効果がなくなる。inhibit-read-onlyがリストの場合には、read-only文字プロパティがリストのメンバーなら効果がなくなる(比較はeqで行われる)。

Command: read-only-mode &optional arg

これはバッファーローカルなマイナーモードRead Onlyモードにたいするモードコマンド。このモードが有効なときは、そのバッファーのbuffer-read-onlyは非nil。無効なときは、そのバッファーのbuffer-read-onlynil。呼び出す際の慣習は、他のマイナーモードコマンドの慣習と同じ(マイナーモード記述の規約を参照)。

このマイナーモードは他のマイナーモードとは異なり、主にbuffer-read-onlyにたいするラッパーの役目を果たし、別個にread-only-mode変数は存在しない。Read Onlyモードが無効なときでも、read-onlyテキストプロパティが非nilの文字は読み取り専用のままである。一時的にすべての読み取り専用ステータスを無視するには上述のinhibit-read-onlyをバインドすること。

Read Onlyモードを有効にする際、このモードコマンドはオプションview-read-onlyが非nilならViewモードも有効にする。Miscellaneous Buffer Operations in The GNU Emacs Manualを参照のこと。Read Onlyモードを無効にする際に、もしもViewモードが有効ならViewモードも無効にする。

Function: barf-if-buffer-read-only &optional position

この関数はカレントバッファーが読み取り専用ならbuffer-read-onlyエラーをシグナルする。position (デフォルトはポイント位置)のテキストのテキストプロパティinhibit-read-onlyがセットされていればエラーは発生しないだろう。

カレントバッファーが読み取り専用の場合にエラーをシグナルする他の方法については、interactiveの使用を参照のこと。


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

28.8 バッファーリスト

バッファーリスト(buffer list)とは、すべての生きた(killされていない)バッファーのリストです。このリスト内のバッファーの順序は主に、それぞれのバッファーがウィンドウに表示されたのがどれほど最近なのかにもとづきます。いくつかの関数、特にother-bufferはこの順序を使用します。ユーザーに表示されるバッファーリストもこの順序にしたがいます。

バッファーを作成するとそれはバッファーリストの最後に追加され バッファーをkillすることによってそのリストから削除されます。ウィンドウに表示するためにバッファーが選択されたとき(ウィンドウ内のバッファーへの切り替えを参照)、あるいはバッファーを表示するウィンドウが選択されたとき(ウィンドウの選択を参照)、そのバッファーは常にこのリストの先頭に移動します。バッファーがバリー(以下のbury-bufferを参照)されたときは、このリストの最後に移動します。バッファーリストを直接操作するために利用できるLispプログラマー向けの関数は存在しません。

説明した基本バッファーリスト(fundamental buffer list)に加えて、Emacsはそれぞれのフレームにたいしてローカルバッファーリスト(local buffer list)を保守します。ローカルバッファーリストでは、そのフレーム内で表示されていた(または選択されたウィンドウの)バッファーが先頭になります(この順序はそのフレームのフレームパラメーターbuffer-listに記録される。バッファーのパラメーターを参照)。並び順は基本バッファーリストにならい、そのフレームでは表示されていないフレームは後になになります。。

Function: buffer-list &optional frame

この関数はすべてのバッファーを含むバッファーリストをリターンする(名前がスペースで始まるバッファーも含む)。リストの要素はバッファーの名前ではなく実際のバッファー。

frameがフレームなら、frameのローカルバッファーリストをリターンする。framenilか省略された場合は、基本バッファーリストが使用される。その場合には、そのバッファーを表示するフレームがどれかとは無関係に、もっとも最近に表示または選択されたバッファーの順になる。

(buffer-list)
     ⇒ (#<buffer buffers-ja.texi>
         #<buffer  *Minibuf-1*> #<buffer buffer.c>
         #<buffer *Help*> #<buffer TAGS>)

;; ミニバッファーの名前が
;;   スペースで始まることに注意!
(mapcar #'buffer-name (buffer-list))
    ⇒ ("buffers-ja.texi" " *Minibuf-1*"
        "buffer.c" "*Help*" "TAGS")

buffer-listからリターンされるリストはそれ専用に構築されたリストであって、Emacsの内部的なデータ構造ではなく、それを変更してもバッファーの並び順に影響はありません。基本バッファーリスト内のバッファーの並び順を変更したい場合に簡単なのは以下の方法です:

(defun reorder-buffer-list (new-list)
  (while new-list
    (bury-buffer (car new-list))
    (setq new-list (cdr new-list))))

この方法により、バッファーを失ったり有効な生きたバッファー以外の何かを追加する危険を犯さずにリストに任意の並び順を指定できます。

特定のフレームのバッファーリストの並び順や値を変更するには、modify-frame-parametersでそのフレームのbuffer-listパラメーターをセットしてください(フレームパラメーターへのアクセスを参照)。

Function: other-buffer &optional buffer visible-ok frame

この関数はバッファーリスト中でbuffer以外の最初のバッファーをリターンする。これは通常は選択されたウィンドウ(フレームframe、または選択されたフレーム(入力のフォーカスを参照)にもっとも最近表示されたbuffer以外のバッファーである。名前がスペースで始まるバッファーは考慮されない。

bufferが与えられない(または生きたバッファーでない)場合には、other-bufferは選択されたフレームのローカルバッファーリスト内の最初のバッファーをリターンする(frameが非nilならframeのローカルバッファーリスト内の最初のバッファーをリターンする)。

frameが非nilbuffer-predicateパラメーターをもつ場合には、どのバッファーを考慮すべきかを決定するためにother-bufferはその述語を使用する。これはそれぞれのバッファーごとにその述語を一度呼び出して、値がnilならそのバッファーは無視される。バッファーのパラメーターを参照のこと。

visible-oknilならother-bufferはやむを得ない場合を除き、任意の可視のフレーム上のウィンドウ内で可視のバッファーをリターンすることを避ける。visible-okが非nilなら、バッファーがどこかで表示されているかどうかは問題にしない。

適切なバッファーが存在しなければ、バッファー*scratch*を(必要なら作成して)リターンする。

Function: last-buffer &optional buffer visible-ok frame

この関数はframeのバッファーリスト内からbuffer以外の最後のバッファーをリターンする。frameが省略またはnilなら選択されたフレームのバッファーリストを使用する。

引数visible-okは上述したother-bufferと同様に扱われる。適切なバッファーを見つけられなければバッファー*scratch*がリターンされる。

Command: bury-buffer &optional buffer-or-name

このコマンドはバッファーリスト内の他のバッファーの並び順を変更することなく、buffer-or-nameをバッファーリストの最後に配置する。つまりこのバッファーはother-bufferがリターンする候補でもっとも期待度が低くなる。引数はバッファー自身かバッファーの名前を指定できる。

この関数は基本バッファーリストと同様に、それぞれのフレームのbuffer-listパラメーターを操作する。したがってバリー(bury: 埋める、隠す)したバッファーは(buffer-list frame)(buffer-list)の値の最後に置かれるだろう。さらにバッファーが選択されたウィンドウに表示されていれば、ウィンドウのバッファーリストの最後にバッファーを置くことも行う(ウィンドウのヒストリーを参照)。

buffer-or-namenilまたは省略された場合には、カレントバッファーをバリーすることを意味する。加えてカレントバッファーが選択されたウィンドウ(ウィンドウの選択を参照)に表示されていれば、そのウィンドウを削除するか他のバッファーを表示する。より正確には選択されたウィンドウが専用(dedicated)のウィンドウ(see 専用のウィンドウ)であり、かつそのフレーム上に他のウィンドウが存在する場合には専用ウィンドウは削除される。それがフレーム上で唯一のウィンドウであり、かつそのフレームが端末上で唯一のフレームでなければ、そのフレームはframe-auto-hide-functionで指定される関数を呼び出すことにより開放される(ウィンドウのquitを参照)。それ以外の場合はに、他のバッファーをそのウィンドウ内に表示するためにswitch-to-prev-bufferを呼び出す(ウィンドウのヒストリーを参照)。buffer-or-nameが他のウィンドウで表示されていれば、そのまま表示され続ける。

あるバッファーにたいして、それを表示するすべてのウィンドウでバッファーを置き換えるにはreplace-buffer-in-windowsを使用する。バッファーとウィンドウを参照のこと。

Command: unbury-buffer

このコマンドは選択されたフレームのローカルバッファーリストの最後のバッファーに切り替える。より正確には選択されたウィンドウ内で、last-buffer (上記参照)がリターンするバッファーを表示するために関数switch-to-bufferを呼び出す(ウィンドウ内のバッファーへの切り替えを参照)。

Variable: buffer-list-update-hook

これはバッファーリストが変更されたときに常に実行されるノーマルフック。(暗黙に)このフックを実行する関数はget-buffer-create (バッファーの作成を参照)、rename-buffer (バッファーの名前を参照)、kill-buffer (バッファーのkillを参照)、bury-buffer (上記参照)、select-window (ウィンドウの選択を参照)。このフックはget-buffer-creategenerate-new-bufferinhibit-buffer-hooks引数に非nilを指定して作成した内部バッファーや一時バッファーには実行されない。

このフックが実行する関数は無限再帰を引き起こすので、nilnorecord引数によるselect-windowの呼び出しは避けること。

Function: buffer-match-p condition buffer-or-name &optional arg

この関数はbuffer-or-nameで指定されたバッファーがconditionの指定を満足するかチェックする。3つ目のオプション引数argconditionの述語関数に渡される。有効なconditionは以下のいずれか:

  • 文字列。正規表現として解釈される。この正規表現がファイル名にマッチすれば、そのバッファーは条件を満たす。
  • 述語関数。バッファーがマッチすれば非nilをリターンすること。1つの引数を期待する関数の場合は引数としてbuffer-or-name、2つの引数を期待する関数の場合には1つ目の引数がbuffer-or-name、2つ目の引数がarg(argの省略時はnil)で呼び出される。
  • コンスセル(oper . expr)operは以下のいずれか
    (not cond)

    そのバッファーとargではbuffer-match-pが偽となるようなcondなら真。

    (or conds…)

    conds内のいずれかの条件にたいして、そのバッファーとargならばbuffer-match-pが真になれば真。

    (and conds…)

    conds内のすべての条件にたいして、そのバッファーとargならばbuffer-match-pが真になれば真。

    derived-mode

    そのバッファーのメジャーモードがexprを継承していれば真。

    major-mode

    そのバッファーのメジャーモードがexprなら真。どちらでも機能するのならderived-modeの使用を推奨する。

  • t どのバッファーでも真。""(空文字列)、(and)(empty conjunction: 空論理積)を使いやすくした代替え。
Function: match-buffers condition &optional buffer-list arg

この関数はconditionを満たすすべてのバッファーのリスト、マッチするバッファーがなければnilをリターンする。引数conditionは上述のbuffer-match-pと同様に定義される。デフォルトではすべてのバッファーを考慮するが、オプション引数buffer-list (考慮すべきバッファーのリスト)を通じて制限できる。オプションの3つ目の引数argは、buffer-match-pと同じ方法によってconditionに渡される。


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

28.9 バッファーの作成

このセクションではバッファーを作成する2つのプリミティブについて説明します。get-buffer-createは指定された名前の既存バッファーが見つからなければ作成します。generate-new-bufferは常に新たにバッファーを作成してそれに一意な名前を与えます。

どちらの関数もオプション引数inhibit-buffer-hooksを受け取ります。これが非nilなら、これらの関数が作成したバッファーはkill-buffer-hookkill-buffer-query-functions (バッファーのkillを参照)、buffer-list-update-hook (バッファーリストを参照)のフックを実行しません。これはユーザーに提示されたり他のアプリケーションに渡されることが決してない、内部バッファーや一時バッファーの速度低下を避けるためです。

バッファーを作成するために使用できる他の関数にはwith-output-to-temp-buffer (一時的な表示を参照)、およびcreate-file-buffer (ファイルのvisitを参照)が含まれます。サブプロセスの開始によってもバッファーを作成することができます(プロセスを参照)。

Function: get-buffer-create buffer-or-name &optional inhibit-buffer-hooks

この関数はbuffer-or-nameという名前のバッファーをリターンする。リターンされたバッファーはカレントにならない — この関数はカレントがどのバッファーであるかを変更しない。

buffer-or-nameは文字列、または既存バッファーのいずれかでなければならない。これが文字列で、かつ既存の生きたバッファーの名前なら、get-buffer-createはそのバッファーをリターンする。そのようなバッファーが存在しなければ、新たにバッファーを作成する。buffer-or-nameが文字列ではなくバッファーなら、たとえそのバッファーが生きていなくても与えられたバッファーをリターンする。

(get-buffer-create "foo")
     ⇒ #<buffer foo>

新たに作成されたバッファーにたいするメジャーモードはFundamentalモードにセットされる(変数major-modeのデフォルト値はより高いレベルで処理される。Emacsがメジャーモードを選択する方法を参照)。名前がスペースで始まる場合には、そのバッファーのアンドゥ情報の記録は初期状態では無効である(アンドゥを参照)。

Function: generate-new-buffer name &optional inhibit-buffer-hooks

この関数は新たに空のバッファーを作成してリターンするが、それをカレントにはしない。バッファーの名前は関数generate-new-buffer-namenameを渡すことにより生成される(バッファーの名前を参照)。つまりnameという名前のバッファーが存在しなければ、それが新たなバッファーの名前になり、その名前が使用されていたら‘<n>’という形式のサフィックスがnameに追加される。ここでnは整数。

nameが文字列でなければエラーがシグナルされる。

(generate-new-buffer "bar")
     ⇒ #<buffer bar>
(generate-new-buffer "bar")
     ⇒ #<buffer bar<2>>
(generate-new-buffer "bar")
     ⇒ #<buffer bar<3>>

新たなバッファーにたいするメジャーモードはFundamentalモードにセットされる。変数major-modeのデフォルト値は、より高いレベルで処理される。Emacsがメジャーモードを選択する方法を参照のこと。


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

28.10 バッファーのkill

バッファーのkill(Killing a buffer)により、 そのバッファーの名前はEmacsにとって未知の名前となり、そのバッファーが占めていたメモリースペースは他の用途に使用できるようになります。

バッファーに対応するバッファーオブジェクトは、それを参照するものがあればkillされても存在し続けますが、それをカレントにしたり表示することができないように特別にマークされます。とはいえkillされたバッファーの同一性は保たれるので、2つの識別可能なバッファーをkillした場合には、たとえ両方死んだバッファーであってもeqによる同一性は残ります。

あるウィンドウ内においてカレント、あるいは表示されているバッファーをkillした場合、Emacsはかわりに他の何らかのバッファーを自動的に選択または表示します。これはバッファーのkillによってカレントバッファーが変更されることを意味します。したがってバッファーをkillする際には、(killされるバッファーがカレントを偶然知っていた場合を除き)カレントバッファーの変更に関しても事前に注意を払うべきです。カレントバッファーを参照してください。

1つ以上のインダイレクト バッファー(インダイレクトバッファーを参照) のベースとなるバッファーをkillした場合には、同様にインダイレクトバッファーも自動的にkillされます。

バッファーのbuffer-namenilの場合のみバッファーはkillされます。killされていないバッファーは生きた(live)バッファーと呼ばれます。あるバッファーにたいして、そのバッファーが生きているか、またはkillされているかを確認するにはbuffer-live-pを使用します(下記参照)。

Command: kill-buffer &optional buffer-or-name

この関数はバッファーbuffer-or-nameをkillして、そのバッファーのメモリーを他の用途のために開放、またはオペレーティングシステムに返却する。buffer-or-namenilまたは省略された場合にはカレントバッファーをkillする。

そのバッファーをprocess-bufferとして所有するすべてのプロセスには、通常はプロセスを終了させるシグナルSIGHUP (hangup)が送信される。プロセスへのシグナルの送信を参照のこと。

バッファーがファイルをvisitしていて、かつ保存されていない変更が含まれる場合には、kill-bufferはバッファーをkillする前にユーザーにたいして確認を求める。これはkill-bufferがinteractiveに呼び出されていなくても行われる。この確認要求を抑制するにはkill-bufferの呼び出し前に、変更フラグ(modified flag)をクリアーすればよい。バッファーの変更を参照のこと。

killされるバッファーをカレントで表示しているすべてのバッファーをクリーンアップするために、この関数はreplace-buffer-in-windowsを呼び出す。

すでに死んでいるバッファーをkillしても効果はない。

この関数は実際にバッファーをkillするとtをリターンする。ユーザーが確認で拒否を選択、またはbuffer-or-nameがすでに死んでいる場合にはnilをリターンする。

(kill-buffer "foo.unchanged")
     ⇒ t
(kill-buffer "foo.changed")

---------- Buffer: Minibuffer ----------
Buffer foo.changed modified; kill anyway? (yes or no) yes
---------- Buffer: Minibuffer ----------

     ⇒ t
Variable: kill-buffer-query-functions

保存されていない変更について確認を求める前に、kill-bufferはリストkill-buffer-query-functions内の関数を出現順に引数なしで呼び出す。それらが呼び出される際にはkillされるバッファーがカレントになる。この機能はこれらの関数がユーザーに確認を求めるというアイデアが元となっている。これらの関数のいずれかがnilをリターンしたら、kill-bufferはそのバッファーを殺さない。

このフックは非nilinhibit-buffer-hooks引数のget-buffer-createまたはgenerate-new-bufferで作成された内部バッファーや一時バッファーにたいしては実行されない。

Variable: kill-buffer-hook

これは尋ねることになっている質問をすべて終えた後、実際にバッファーをkillする直前にkill-bufferにより実行されるノーマルフック。この変数は永続的にローカルであり、メジャーモードの変更により、そのローカルバインディングはクリアーされない。

このフックは非nilinhibit-buffer-hooks引数のget-buffer-createまたはgenerate-new-bufferで作成された内部バッファーや一時バッファーにたいしては実行されない。

User Option: buffer-offer-save

特定のバッファーにおいてこの変数が非nilなら、あたかもファイルをvisitするバッファーにたいして提案するときのように、バッファーの保存を提案するようにsave-buffers-kill-emacsに指示する。2つ目のオプション引数をtにセットしてsave-some-buffersを呼び出せばバッファーの保存も提案する。最後にこの変数をシンボルalwaysにセットすると、save-buffers-kill-emacssave-some-buffersは常に保存を提案する。Definition of save-some-buffersを参照のこと。何らかの理由により変数buffer-offer-saveがセットされると自動的にバッファーローカルになる。バッファーローカル変数を参照のこと。

Variable: buffer-save-without-query

特定のバッファーにおいてこの変数が非nilなら、save-buffers-kill-emacssave-some-buffersは、(バッファーが変更されていれば)ユーザーに確認を求めることなくそのバッファーを保存する。何らかの理由によりこの変数をセットする際には自動的にバッファーローカルになる。

Function: buffer-live-p object

この関数はobjectが生きたバッファー(killされていないバッファー)ならt、それ以外はnilをリターンする。


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

28.11 インダイレクトバッファー

インダイレクトバッファー(indirect buffer: 間接バッファー)とは、ベースバッファー(base buffer)と呼ばれる他のバッファーとテキストを共有します。いくつかの点においてインダイレクトバッファーはファイル間でのシンボリックリンクに類似しています。ベースバッファー自身はインダイレクトバッファーではない可能性があります。

インダイレクトバッファーのテキストは、常にベースバッファーのテキストと同一です。編集により一方が変更されると、それは即座に他方のバッファーから可視になります。これには文字自体に加えてテキストプロパティも同様に含まれます。

他のすべての観点において、インダイレクトバッファーとそのベースバッファーは完全に別物です。それらは別の名前、独自のポイント値、ナローイング、マーカー、オーバーレイ、メジャーモード、バッファーローカルな変数バインディングをもちます(ただしどちらかのバッファーでのテキストの挿入や削除を行うと両方のバッファーでマーカーとオーバーレイが再配置される)。

インダイレクトバッファーはファイルをvisitできませんがベースバッファーには可能です。インダイレクトバッファーの保存を試みると、実際にはベースバッファーが保存されます。

インダイレクトバッファーをkillしてもベースバッファーに影響はありません。ベースバッファーをkillするとインダイレクトバッファーはkillされて再びカレントバッファーにすることはできません。

Command: make-indirect-buffer base-buffer name &optional clone inhibit-buffer-hooks

これはベースバッファーがbase-bufferであるような、nameという名前のインダイレクトバッファーを作成してリターンする。引数base-bufferは生きたバッファー、または既存バッファーの名前(文字列)を指定できる。nameが既存バッファーの名前ならエラーがシグナルされる。

cloneが非nilならインダイレクトバッファーは最初はbase-bufferのメジャーモード、マイナーモード、バッファーローカル変数等の状態を共有する。cloneが省略またはnilなら、インダイレクトバッファーの情報は新たなバッファーにたいするデフォルト状態にセットされる。

base-bufferがインダイレクトバッファーなら、新たなバッファーのベースとしてそれのベースバッファーが使用される。さらにcloneが非nilなら、初期状態はbase-bufferではなく実際のベースバッファーからコピーされる。

inhibit-buffer-hooksの意味についてはバッファーの作成を参照のこと。

Command: clone-indirect-buffer newname display-flag &optional norecord

この関数はカレントバッファーのベースバッファーを共有するインダイレクトバッファーを新たに作成して、カレントバッファーの残りの属性をコピーしてリターンする(カレントバッファーがインダイレクトバッファーでなければそれがベースバッファーとして使用される)。

display-flagが非nil (インタラクティブな呼び出しでは常に非nil)なら、それはpop-to-bufferを呼び出すことにより新しいバッファーを表示することを意味する。norecordが非nilなら、それは新しいバッファーをバッファーリストの先頭に置かないことを意味する。

Function: buffer-base-buffer &optional buffer

この関数はbuffer (デフォルトはカレントバッファー)のベースバッファーをリターンする。bufferがインダイレクトバッファーでなければ値はnil、それ以外では値は他のバッファーとなり、そのバッファーがインダイレクトバッファーであることは決してない。


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

28.12 2つのバッファー間でのテキストの交換

特別なモードでは、ユーザーが同一のバッファーから複数の非常に異なったテキストにアクセスできるようにしなければならない場合があります。たとえばバッファーのテキストのサマリーを表示して、ユーザーがそのテキストにアクセスできるようにする場合です。

これは、(ユーザーがテキストを編集した際には同期を保つ)複数バッファーや、ナローイング(ナローイングを参照)により実装することができるかもしれません。しかしこれらの候補案はときに退屈になりがちであり、特にそれぞれのテキストタイプが正しい表示と編集コマンドを提供するために高価なバッファーグローバル操作を要求する場合には、飛び抜けて高価になる場合があります。

Emacsはそのようなモードにたいして別の機能を提供します。buffer-swap-textを使用すれば、2つのバッファー間でバッファーテキストを素早く交換することができます。この関数はテキストの移動は行わずに異なるテキスト塊(text chunk)をポイントするように、バッファーオブジェクトの内部的なデータ構造だけを変更するため非常に高速です。これを使用することにより、2つ以上のバッファーグループから個々のバッファーのコンテンツすべてを併せもつような、単一の仮想バッファー(virtual buffer)が実在するように見せかけることができます。

Function: buffer-swap-text buffer

この関数はカレントバッファーのテキストと、引数bufferのテキストを交換する。2つのバッファーのいずれか一方がインダイレクトバッファー(インダイレクトバッファーを参照)、またはインダイレクトバッファーのベースバッファーの場合はエラーをシグナルする。

バッファーテキストに関連するすべてのバッファープロパティ、つまりポイントとマークの位置、すべてのマーカーとオーバーレイ、テキストプロパティ、アンドゥリスト、enable-multibyte-charactersフラグの値(enable-multibyte-charactersを参照)等も同様に交換される。

警告: この関数をsave-excursion内部で呼び出すと、位置とバッファーを保存するためにsave-excursionが使用するマーカーも同様に交換されるので、そのフォームを抜ける際にはカレントバッファーはbufferにセットされるだろう。

ファイルをvisitしているバッファーにbuffer-swap-textを使用する場合には、交換されたテキストではなくそのバッファーの元のテキストを保存するようにフックをセットアップするべきです。write-region-annotate-functionsは正にこの目的のために機能します。そのバッファーのbuffer-saved-sizeを、おそらく交換されたテキストにたいする変更が自動保存に干渉しないであろう、-2にセットするべきです。


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

28.13 バッファーのギャップ

Emacsのバッファーは挿入と削除を高速にするために不可視のギャップ(gap)を使用して実装されています。挿入はギャップ部分を充填、削除はギャップを追加することにより機能します。もちろんこれは最初にギャップを挿入や削除の部位(locus)に移動しなければならないことを意味します。Emacsはユーザーが挿入か削除を試みたときだけギャップを移動します。大きなバッファー内の遠く離れた位置で編集した後に、他の箇所での最初の編集コマンドに無視できない遅延が発生する場合があるのはこれが理由です。

このメカニズムは暗黙に機能するものであり、Lispコードはギャップのカレント位置に影響されるべきでは決してありませんが、以下の関数はギャップ状態に関する情報の取得に利用できます。

Function: gap-position

この関数はカレントバッファー内のギャップのカレント位置をリターンする。

Function: gap-size

この関数はカレントバッファー内のギャップのサイズをリターンする。


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

29 ウィンドウ

このチャプターではEmacsのウィンドウに関連する関数と変数について説明します。Emacsが利用可能なスクリーン領域にウィンドウが割り当てられる方法についてはフレームを参照してください。ウィンドウ内にテキストが表示される方法についての情報はEmacsのディスプレイ表示を参照してください。


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

29.1 Emacsウィンドウの基本概念

ウィンドウ(window)とはバッファー(バッファーを参照)の表示に使用されるスクリーン領域です。ウィンドウはフレームへとグループ化されます(フレームを参照)。それぞれのフレームは最低でも1つのウィンドウを含みます。ユーザーは複数のバッファーを一度に閲覧するために、フレームを複数のオーバーラップしないウィンドウに分割することができます。Lispプログラムはさまざまな目的にたいして複数のウィンドウを使用できます。たとえばRmailでは1つのウィンドウでメッセージタイトル、もう一方のウィンドウで選択したメッセージのコンテンツを閲覧できます。

EmacsはX Window Systemのようなグラフィカルなデスクトップ環境やウィンドウシステムとは異なる意味で“ウィンドウ(window)”という用語を使用します。EmacsがX上で実行されているときはEmacsに所有されるグラフィカルなXウィンドウは、Emacsでのフレームに相当します。Emacsがテキスト端末上で実行されているときには、Emacsフレームそれぞれが1つの端末スクリーン全体を占有します。いずれの場合においても、フレームには1つ以上のEmacsウィンドウが含まれます。曖昧さをなくすために、Emacsフレームに相当するウィンドウシステムのウィンドウを指す際には、ウィンドウシステムのウィンドウ(window-system window)という用語を使うことにします。

Xのウィンドウとは異なり、Emacsのウィンドウはタイル表示(tiled)されるので、それらのフレーム領域内でオーバーラップされることは決してありません。あるウィンドウが作成、リサイズ、削除されるとき変更されたウィンドウスペースの変更は他のウィンドウから取得・譲与されるので、そのフレームの総領域に変化はありません。

Emacs Lispではウィンドウは特別なLispオブジェクトタイプで表されます(ウィンドウ型を参照)。

Function: windowp object

この関数はobjectがウィンドウ(バッファーの表示有無に関わらず)ならt、それ以外はnilをリターンする。

生きたウィンドウ(live window)とは、あるフレーム内で実際にバッファーを表示しているウィンドウのことです。

Function: window-live-p object

この関数はobjectが生きたウィンドウならt、それ以外はnilをリターンする。生きたウィンドウとはバッファーを表示するウィンドウのこと。

各フレーム内のウィンドウはウィンドウツリー(window tree)内へと組織化されます。ウィンドウとフレームを参照してください。それぞれのウィンドウツリーのリーフノード(leaf nodes)は、実際にバッファーを表示している生きたウィンドウです。ウィンドウツリーの内部ノード(internal node)は内部ウィンドウ(internal windows)と呼ばれ、これらは生きたウィンドウではありません。

有効なウィンドウ(valid window)とは、生きたウィンドウか内部ウィンドウのいずれかです。有効なウィンドウにたいしては、それを削除(delete)、すなわちそのウィンドウのフレームから削除することができます(ウィンドウの削除を参照)。その場合、それは有効なウィンドウではなくなりますが、それを表すLispオブジェクトは依然として他のLispオブジェクトから参照されたままかもしれません。削除されたウィンドウは保存されたウィンドウ構成(window configuration)をリストアすることにより再び有効にすることができます(ウィンドウの構成を参照)。

window-valid-pにより、削除されたウィンドウから有効なウィンドウを区別できます。

Function: window-valid-p object

この関数はobjectが生きたウィンドウかウィンドウツリー内の内部ウィンドウならtをリターンする。それ以外(objectが削除されたウィンドウの場合も含む)はnilをリターンする。

以下の図は生きたウィンドウの構造を示しています:

        ____________________________________________
       |________________ Tab Line _______________|RD| ^
       |______________ Header Line ______________|  | |
     ^ |LS|LM|LF|                       |RF|RM|RS|  | |
     | |  |  |  |                       |  |  |  |  | |
Window |  |  |  |                       |  |  |  |  | Window
Body | |  |  |  |      Window Body      |  |  |  |  | Total
Height |  |  |  |                       |  |  |  |  | Height
     | |  |  |  |<- Window Body Width ->|  |  |  |  | |
     v |__|__|__|_______________________|__|__|__|  | |
       |_________ Horizontal Scroll Bar _________|  | |
       |_______________ Mode Line _______________|__| |
       |_____________ Bottom Divider _______________| v
        <---------- Window Total Width ------------>

ウィンドウの中央はボディー(body: 本体、本文)と呼ばれるバッファーテキストが表示される場所です。テキストエリアは、ウィンドウ装飾(window decorations)と呼ばれる一連のオプションエリアで囲まれている可能性があります。左右には内側から外側に向かって図中にLFとRFで示される左右のフリンジ(フリンジを参照)、LMとRMで示される左右のマージン(マージン内への表示を参照)、そしてLSとRSはスクロールバー(スクロールバーを参照)で、これは常に表示されるのはいずれか一方だけです。さらにRDで示されるのが右ディバイダー(ウィンドウディバイダーを参照)です。ウィンドウ上端にはヘッダーライン(ウィンドウのヘッダーラインを参照)、ウィンドウ下端には水平スクロールバー(スクロールバーを参照)、モードライン(モードラインのフォーマットを参照)、下端ディバイダー(ウィンドウディバイダーを参照)があります。これらを合わせて、ウィンドウの左や右の装飾(left and right decorations)と呼びます。

ウィンドウの上端にあるのがタブラインとヘッダーライン(ウィンドウのヘッダーラインを参照)です。ウィンドウにヘッダーラインやタブラインがある場合には、それらはウィンドウのテキストエリア(text area: テキスト領域)に含まれます。ウィンドウの下端にあるのが水平スクロールバー(スクロールバーを参照)とモードライン(モードラインのフォーマットを参照)、そして下ディバイダー(ウィンドウディバイダーを参照)です。これらを合わせてウィンドウの上や下の装飾(top and bottom decorations)と呼びます。

図には省略した特別なエリアが2つあります。

  • フリンジのいずれかが存在しない際には、テキスト行がウィンドウに収まらなければ、ディスプレイエンジンがその箇所に1文字セルの継続または切り詰めを表すグリフを使用するかもしれない。
  • 垂直スクロールバーと右ディバイダーの両方が存在しない際には、そのウィンドウの右にウィンドウがあれば、ディスプレイエンジンがウィンドウとウィンドウの間の1ピクセルを使って垂直ディバイダーを描画する。テキスト端末においては、このディバイダーは常に1文字セルを専有する。

いずれのケースでも、たとえ結果となる構造のスクリーンスペースがバッファーテキストの表示に使用されなくても、そのウィンドウのボディーとみなされます。

行番号(と周囲の空白)display-line-numbers-mode (Display Custom in The GNU Emacs Manualを参照)によって表示されるので装飾ではなく、そのウィンドウのボディー部分とみなされます。

内部ウィンドウがテキストを表示したり装飾をもつことはありません。したがってこれらにたいして“body”という概念は意味をもちません。実際にウィンドウのbodyを操作するほとんどの関数は、内部ウィンドウに適用するとエラーとなります。

デフォルトではEmacsフレームはメッセージ表示やユーザー入力受け取りに使用される1つの特別な生きたウィンドウ — ミニバッファーウィンドウ(minibuffer window)を表示します(ミニバッファーのウィンドウを参照)。ミニバッファーウィンドウはテキストの表示に使用されるのでbodyがありますが、タブライン、ヘッダーライン、それにマージンはありません。最後にツールチップフレームでツールチップを表示するのに使用されるツールチップウィンドウ(tooltip window)には、ボディーはありますが装飾は何もありません(ツールチップを参照)。


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

29.2 ウィンドウとフレーム

それぞれのウィンドウは正確に1つのフレームに属します(フレームを参照)。ある特定のフレームに属するすべてのウィンドウにたいして、それらのウィンドウがそのフレームに所有されている(owned)、あるいは単にそのフレーム上にあるというときもあります。

Function: window-frame &optional window

この関数は指定されたwindowのフレーム(windowが属するフレーム)をリターンする。windownilの場合のデフォルトは選択されたウィンドウ(ウィンドウの選択を参照)。

Function: window-list &optional frame minibuffer window

この関数は指定されたframeに所有されるすべての生きたウィンドウのリストをリターンする。frameが省略またはnilの場合のデフォルトは選択されたフレーム(入力のフォーカスを参照)。

オプション引数minibufferはそのリストにミニバッファーウィンドウ(ミニバッファーのウィンドウを参照)を含めるべきかどうかを指定する。minibuffertならミニバッファーウィンドウが含まれ、nilまたは省略された場合にはミニバッファーウィンドウがアクティブのときだけ含まれる。minibuffernilt以外ならミニバッファーウィンドウは含まれない。

オプション引数windowが非nilなら、それは指定されたフレーム上の生きたウィンドウでなければならない。その場合にはwindowがリターンされるリストの最初の要素になる。windowが省略またはnilなら、frameの選択されたウィンドウ(ウィンドウの選択を参照)が最初の要素になる。

同一フレーム内のウィンドウは、リーフノード(leaf nodes)が生きたウィンドウであるようなウィンドウツリー(window tree)内に組織化されます。ウィンドウツリーの内部ノード(internal nodes)は生きたウィンドウではありません。これらのウィンドウは生きたウィンドウ間の関係を組織化するという目的のために存在します。ウィンドウツリーのルートノード(root node)はルートウィンドウ(root window)と呼ばれます。ルートノードは生きたウィンドウ、または内部ウィンドウのいずれかです。生きたウィンドウの場合には、ミニバッファーウィンドウ以外にウィンドウが1つだけあるフレーム、あるいはミニバッファーだけのフレームです。フレームのレイアウトを参照してください。

フレーム内で唯一ではないミニバッファーウィンドウ(ミニバッファーのウィンドウを参照)は親ウィンドウをもたないので、厳密に言えばフレームのウィンドウツリーの一部ではありません。それでもフレームのルートウィンドウの兄弟ウィンドウなので、ルートウィンドウからwindow-next-sibling (以下参照)を通じて到達することができます。さらにこのセクションの最後に説明する関数window-treeは実際のウィンドウツリーと共にミニバッファーウィンドウをリストします。

Function: frame-root-window &optional frame-or-window

この関数はframe-or-windowにたいするルートウィンドウをリターンする。引数frame-or-windowはウィンドウかフレームのいずれかであること。これが省略またはnilの場合のデフォルトは選択されたフレーム。frame-or-windowがウィンドウなら、リターン値はそのウィンドウのフレームのルートウィンドウ。

生きたウィンドウが分割(split)されているとき(ウィンドウの分割を参照)は、以前は1つだった2つの生きたウィンドウが存在します。これらのうちの一方は、元のウィンドウと同じLispウィンドウオブジェクトとして表され、もう一方は新たに作成されたLispウィンドウオブジェクトとして表されます。これらの生きたウィンドウはいずれも単一の内部ウィンドウの子ウィンドウ(child windows)として、ウィンドウツリーのリーフノードになります。もし必要ならEmacsはこの内部ウィンドウを自動的に作成します。この内部ウィンドウは親ウィンドウ(parent window)とも呼ばれ、ウィンドウツリー内の適切な位置に配置されます。同じ親を共有するウィンドウセットは兄弟(sibling)と呼ばれます。

Function: window-parent &optional window

この関数はwindowの親ウィンドウ(parent window)をリターンする。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ。windowが親をもたない場合(ミニバッファーウィンドウやそのフレームのルートウィンドウ)にはリターン値はnil

親ウィンドウは常に最低でも2つの子ウィンドウをもちます。ウィンドウ削除(ウィンドウの削除を参照)によりこの数値が1になると、Emacsは自動的に親ウィンドウも削除して、その1つだけ残った子ウィンドウがウィンドウツリー内のその位置に配置されます。

子ウィンドウは生きたウィンドウ、または(次に自身の子ウィンドウをもつであろう)内部ウィンドウのいずれかです。したがって各内部ウィンドウは、最終的にはその内部ウィンドウの子孫であるような生きたウィンドウにより占有される領域を結合した、特定の矩形スクリーン領域(screen area)を占有すると考えることができます。

内部ウィンドウそれぞれにたいして、近接する子たちのスクリーン領域は垂直(vertically)か水平(horizontally)のいずれかにより整列されます(両方で整列されることはない)。子ウィンドウが他の子ウィンドウと上下に整列される場合、それらは垂直コンビネーション(vertical combination)、左右に整列される場合は水平コンビネーション(horizontal combination)を形成すると表現されます。以下の例で考えてみましょう:

     ______________________________________
    | ______  ____________________________ |
    ||      || __________________________ ||
    ||      |||                          |||
    ||      |||                          |||
    ||      |||                          |||
    ||      |||____________W4____________|||
    ||      || __________________________ ||
    ||      |||                          |||
    ||      |||                          |||
    ||      |||____________W5____________|||
    ||__W2__||_____________W3_____________ |
    |__________________W1__________________|

このフレームのルートウィンドウは内部ウィンドウW1です。これの子ウィンドウは、生きたウィンドウW2と内部ウィンドウW3からなる水平コンビネーションを形成します。W3の子ウィンドウは、生きたウィンドウW4W5からなる垂直コンビネーションを形成します。したがって、このウィンドウツリー内の生きたウィンドウはW2W4、およびW5です。

以下の関数は内部ウィンドウの子ウィンドウ、および子ウィンドウの兄弟を取得するために使用できます。これらの関数のwindow引数のデフォルトは常に選択されたウィンドウです(ウィンドウの選択を参照)。

Function: window-top-child &optional window

この関数は内部ウィンドウwindowの子ウィンドウが垂直コンビネーションを形成する場合には、windowの一番上の子ウィンドウをリターンする。他のタイプのウィンドウにたいするリターン値はnil

Function: window-left-child &optional window

この関数は内部ウィンドウwindowの子ウィンドウが水平コンビネーションを形成する場合には、windowの一番左の子ウィンドウをリターンする。他のタイプのウィンドウにたいするリターン値はnil

Function: window-child window

この関数は内部ウィンドウwindowの最初の子ウィンドウをリターンする。これは垂直コンビネーションにたいしては一番上、水平コンビネーションにたいしては一番左の子ウィンドウ。windowが生きたウィンドウならリターン値はnil

Function: window-combined-p &optional window horizontal

この関数はwindowが垂直コンビネーションの一部である場合のみ非nilをリターンする。

オプション引数horizontalが非nilなら、windowが水平コンビネーションの一部である場合のみ非nilをリターンすることを意味する。

Function: window-next-sibling &optional window

この関数は指定されたwindowの次の兄弟をリターンする。windowがその親の最後の子ならリターン値はnil

Function: window-prev-sibling &optional window

この関数はウィンドウwindowの前の兄弟をリターンする。windowがその親の最初の子ならリターン値はnil

関数window-next-siblingwindow-prev-siblingを、ウィンドウのサイクル順(ウィンドウのサイクル順を参照)で次や前のウィンドウをリターンする関数next-windowprevious-windowと混同しないでください。

以下の関数はフレーム内のウィンドウの配置に有用です。

Function: frame-first-window &optional frame-or-window

この関数はframe-or-windowにより指定されたフレームの左上隅の生きたウィンドウをリターンする。引数frame-or-windowはウィンドウか生きたフレームを指定しなければならず、デフォルトは選択されたフレーム。frame-or-windowがウィンドウを指定する場合には、この関数はそのウィンドウのフレームの最初のウィンドウをリターンする。前の例のフレームが(frame-first-window)で選択されたとするとW2がリターンされる。

Function: window-at-side-p &optional window side

この関数はwindowのフレーム内でwindowsideに配置されていればtをリターンする。引数windowは有効なウィンドウでなければならず、デフォルトは選択されたウィンドウ。引数sideはシンボルlefttoprightbottomのいずれか。デフォルト値のnilbottomとして扱われる。

この関数はミニバッファーウィンドウを無視することに注意(ミニバッファーのウィンドウを参照)。したがってsidebottomなら、windowの右下にミニバッファーウィンドウがある際にもtをリターンするかもしれない。

Function: window-in-direction direction &optional window ignore sign wrap minibuf

この関数はウィンドウwindow内の位置window-pointから、方向directionにあるもっとも近い生きたウィンドウをリターンする。引数directionabovebelowleftrightのいずれかでなければならない。オプション引数windowは生きたウィンドウでなければならず、デフォルトは選択されたウィンドウ。

この関数はパラメーターno-other-windowが非nilのウィンドウをリターンしない(ウィンドウのパラメーターを参照)。もっとも近いウィンドウのno-other-windowパラメーターが非nilなら、この関数は指定された方向でno-other-windowパラメーターがnilであるような他のウィンドウを探す。オプション引数ignoreが非nilなら、たとえno-other-windowパラメーターが非nilのウィンドウでもリターンされるだろう。

オプション引数signが負の数値なら、それは参照位置としてwindow-pointのかわりにwindowの右端、または下端を使用することを意味する。signが正の数値なら、それは参照位置としてwindowの左端か上端を使用することを意味する。

オプション引数wrapが非nilなら、それはフレームのボーダー(borders: 枠線)をdirectionがラップアラウンド(wrap around: 最後に達したら最初に戻る)することを意味する。たとえばwindowはフレームの最上にありdirectionaboveなら、そのフレームのミニバッファーウィンドウがアクティブでそれがフレームの他のウィンドウの最下にある場合には、この関数は通常はミニバッファーウィンドウをリターンする。

オプション引数minibuftなら、ミニバッファーウィンドウが非アクティブでもこの関数はそれをリターンするかもしれない。nilならカレントでアクティブな場合のみミニバッファーウィンドウをリターンすることを意味する。niltのいずれでもなければ、この関数がミニバッファーウィンドウをリターンすることはない。しかしwrapが非nilなら、常にminibufnilであるかのように振る舞う。

適切なウィンドウが見つからなければ、この関数はnilをリターンする。

この関数をdirectionにウィンドウが存在しないかどうかをチェックするために使用しないこと。それを行うには上述のwindow-at-side-pを呼び出すほうが効果的である。

以下の関数はフレームのウィンドウツリー全体を取得します:

Function: window-tree &optional frame

この関数はフレームframeにたいするウィンドウツリーを表すリストをリターンする。frameが省略nilの場合のデフォルトは選択されたフレーム。

リターン値は(root mini)という形式のリスト。ここでrootはそのフレームのウィンドウツリーのルートウィンドウ、miniはそのフレームのミニバッファーウィンドウを表す。

ルートウィンドウが生きていればrootはそのウィンドウ自身、それ以外ならrootはリスト(dir edges w1 w2 ...)。ここでdirは水平コンビネーションならnil、垂直コンビネーションならtとなり、edgesはそのコンビネーションのサイズと位置を与え、残りの要素は子ウィンドウである。子ウィンドウはそれぞれ、同じようにウィンドウオブジェクト(生きたウィンドウにたいして)、または上記フォーマットと同じ形式のリスト(内部ウィンドウにたいして)かもしれない。edges要素はwindow-edgesがリターンする値のようなリスト(left top right bottom) (座標とウィンドウを参照)。


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

29.3 ウィンドウの選択

それぞれのフレーム内において、常にただ1つのEmacsウィンドウがそのフレームで選択されている(selected within the frame)として指定されます。選択されたフレームにたいしてそのウィンドウは選択されたウィンドウ(selected window)と呼ばれます。選択されたウィンドウは編集のほとんどが行われるウィンドウであり、選択されたウィンドウに表示されるカーソルがあるウィンドウです(カーソルのパラメーターを参照)。テキストの挿入や削除を行うキーボード入力もそのウィンドウにたいして行われます。選択されたウィンドウのバッファーは、通常はset-bufferが使用された場合を除いてカレントバッファーでもあります(カレントバッファーを参照)。選択されていないフレームでは、そのフレームが選択されたときはフレームで選択されていたウィンドウが選択されたウィンドウになります。

Function: selected-window

この関数は選択されたウィンドウをリターンする(これは常に生きたウィンドウ)。

以下の関数はウィンドウとそのフレームを明示的に選択します。

Function: select-window window &optional norecord

この関数はwindowを選択されたウィンドウにすることによりそのフレーム内で選択されたウィンドウとして、そのフレームを選択する。またwindowのバッファー(バッファーとウィンドウを参照)をカレントにして、そのバッファーのpointの値(ウィンドウとポイントを参照)をwindowwindow-pointの値にセットする。windowは生きたウィンドウでなければならない。リターン値はwindow

デフォルトではこの関数はwindowのバッファーをバッファーリストの先頭(バッファーリストを参照)に移動して、windowをもっとも最近選択されたウィンドウにする。オプション引数norecordが非nilなら、これらの追加処理は省略される。

加えてこの関数はデフォルトではwindowのフレームの次回再表示の際にwindowを更新するようにディスプレイエンジンに指示する。norecordが非nilなら、そのような更新は通常は行わない。しかしnorecordが特別なシンボルmark-for-redisplayと等しければ上述の追加アクションは省略されるが、それにも関わらずwindowの表示は更新される。

ウィンドウを選択することではウィンドウの表示やそのフレームをディスプレイ上の最上フレームにすることを満足しない場合があることに注意。さらにそのフレームのレイズやフレームにフォーカスが当たることを確実にする必要もあるだろう。入力のフォーカスを参照のこと。

歴史的な理由によりウィンドウ選択時にEmacsが個別にフックを実行することはありません。アプリケーションや内部ルーチンがあるウィンドウ上でいくつかの処理を行うために一時的にウィンドウを選択することはよくあります。これらはwindow引数が何も指定されていなければデフォルトでは選択されたウィンドウを処理する関数が多数存在するのでコーディングを単純化するために、あるいは引数としてウィンドウを受け取らないために常に選択されたウィンドウを処理する関数がいくつか存在した(そして今も存在する)ためにこれを行います。あるウィンドウが短時間選択されたときと、以前に選択されていたウィンドウがリストアされるたびに毎回フックを実行するのは有用ではありません。

しかしnorecord引数がnilの際にはselect-windowがバッファーリストを更新するので、間接的にノーマルフックbuffer-list-update-hookが実行されます(バッファーリストを参照)。結果としてこのフックは、あるウィンドウがより“永続的”に選択された際に関数を実行する1つの手段を提供します。

buffer-list-update-hookはウィンドウ管理とは無関係な関数によっても実行されるので、選択されたウィンドウの値を何かに保存しておいて、このフックの実行中にselected-windowの値と比較することには意味があります。buffer-list-update-hookを使用する際の誤検出を防ぐためにも、一時的にのみウィンドウの選択を意図するselect-windowの呼び出しごとにnorecord引数に非nilを渡すことはよい習慣です。そのような場合にはマクロwith-selected-window (以下参照)を使用するべきです。

最後の再表示以降に別ウィンドウが選択されたことを再表示ルーチンが検知した際には、常にEmacsはフックwindow-selection-change-functionsも実行します。詳細な説明はウィンドウのスクロールと変更のためのフックを参照してください。(同じセクションに記載されている) window-state-change-functionsは別ウィンドウ選択後に実行される別のアブノーマルフックですが、これは他のウィンドウの変更時にも同様にトリガーされます。

引数norecordに非nilを指定したselect-windowの連続呼び出しは、ウィンドウの並び順を選択または使用時刻により決定します(以下参照)。関数get-lru-windowはたとえば、もっとも昔に選択されたウィンドウ(ウィンドウのサイクル順を参照)を取得するために使用できます。

Function: frame-selected-window &optional frame

この関数はフレームframe内で選択されているウィンドウをリターンする。frameは生きたフレームであること。省略またはnilの場合のデフォルトは選択されたフレーム。

Function: set-frame-selected-window frame window &optional norecord

この関数はwindowをフレームframe内で選択されたウィンドウにする。frameは生きたフレームであること。省略またはnilの場合のデフォルトは選択されたフレーム。windowは生きたウィンドウでなければならない

frameが選択されたフレームなら、windowを選択されたウィンドウにする。

オプション引数norecordが非nilなら、この関数はもっとも最近に選択されたウィンドウやバッファーリストのいずれの順序も変更はしない。

以下のマクロはもっとも最近選択されたウィンドウやバッファーリストの順序に影響を与えずにウィンドウを一時的に選択するのに有用です。

Macro: save-selected-window forms…

このマクロは選択されたフレーム、同様に各フレームの選択されたウィンドウを記録して、formsを順に実行してから以前に選択されていたフレームとウィンドウをリストアする。これはカレントバッファーの保存とリストアも行う。リターン値はforms内の最後のフォームの値。

このマクロはウィンドウのサイズ、コンテンツ、配置についての保存やリストアは何も行わない。したがってformsがそれらを変更すると、その変更は永続化される。あるフレームにおいて以前に選択されていたウィンドウがformsのexit時にすでに生きていなければ、そのフレームの選択されたウィンドウはそのまま放置される。以前に選択されていたウィンドウがすでに生きていなければformsの最後に選択されていたウィンドウが何であれ、それが選択されたままになる。カレントバッファーformsのexit時にそれが生きている場合のみリストアされる。

このマクロは、もっとも最近に選択されたウィンドウとバッファーリストの順番をいずれも変更しない。

Macro: with-selected-window window forms…

このマクロはwindowを選択してformsを順に実行してから、以前に選択されていたウィンドウとカレントバッファーをリストアする。たとえば引数norecordnilselect-windowを呼び出す等、forms内で故意に変更しない限り、もっとも最近に選択されたウィンドウとバッファーリストの順番は変更されない。したがってこのマクロは不要なbuffer-list-update-hookの実行なしに、windowを選択されたウィンドウとして一時的に作業するために好ましい手段である。

このマクロはウィンドウ管理コードを一時的に不安定な状態に置くことに注意。特にもっとも最近使用されたウィンドウ(下記参照)が、選択されたウィンドウと一致する必要はなくなる。したがってこのマクロのbodyでget-lru-windowget-mru-windowのような関数を呼び出すと、予期せぬ結果を得ることになるかもしれない。

Macro: with-selected-frame frame forms…

このマクロはframeを選択したフレームとしてformsを実行する。リターン値はformsの最後のフォームの値。このマクロは選択されたフレームの保存とリストアを行い、もっとも最近に選択されたフレーム、およびバッファーリスト内のバッファーのどちらの順序も変更しない。

Function: window-use-time &optional window

この関数はウィンドウwindowの使用回数をリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。

ウィンドウの使用回数(use time)は実際にはtime値ではなく、nilnorecord引数によるselect-windowの呼び出しごとに毎回単調に増加する整数。通常は最小の使用回数をもつウィンドウは、もっとも最近使用されていないウィンドウ(the least recently used window)と呼ばれる。最大の使用回数をもつウィンドウはもっとも最近使用されたウィンドウ(the most recently used window)と呼ばれる(ウィンドウのサイクル順を参照)。これはwith-selected-windowを使用していなければ、通常は選択されたウィンドウである。

Function: window-bump-use-time &optional window

この関数はwindowを2番目に最近使われたウィンドウ(選択されたウィンドウの次)としてマークする。windowが選択されたウィンドウ、あるいは選択されたウィンドウの使用時間がすべてのウィンドウの中で最長ではない場合(with-selected-windowのスコープ内で発生し得る)には何もしない。

たとえばFollowモード((emacs)Follow Modeを参照)の管理下では、あるウィンドウが単独で表示可能な部分より大きい部分をそのウィンドウにまとめて表示するように、複数のウィンドウが集合かつ協調してバッファーを表示することがあります。そのようなウィンドウグループ(window group)を1つのエンティティーとしてとらえると便利なことがよくあります。window-group-start (ウィンドウの開始位置と終了位置を参照)のようないくつかの関数では、グループ全体の代表としてウィンドウの1つを引数に与えることにより、これを行うことができます。

Function: selected-window-group

選択されたウィンドウがウィンドウグループのメンバーなら、この関数はそのバッファーの最前箇所を表示するウィンドウが先頭になる順序で、グループ内のウィンドウのリストをリターンする。それ以外なら、この関数は選択されたウィンドウだけを含むリストをリターンする。

バッファーローカル変数selected-window-group-functionが関数にセットされているときは、選択されたウィンドウはグループの一部とみなされる。この場合には、selected-window-groupはその関数を引数なしで呼び出し、その結果をリターンする(これはそのグループ内のウィンドウのリストであること)。


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

29.4 ウィンドウのサイズ

Emacsはウィンドウの高さと幅を求めるためのさまざまな関数を提供します。これらの関数がリターンする値の多くはピクセル単位、または行単位と列単位のいずれかにより指定できます。グラフィカルなディスプレイでは後者は実際にはframe-char-heightframe-char-width (フレームのフォントを参照)によりリターンされる、そのフレームのデフォルトフォントが指定するデフォルト文字の高さと幅に対応します。したがってあるウィンドウが異なるフォントやサイズでテキストを表示していると、そのウィンドウにたいして報告される行高さと列幅は、実際にウィンドウ内で表示されるテキスト行数と列数とは異なるかもしれません。

トータル高さ(total height)とは、そのウィンドウのボディー、上下の装飾(Emacsウィンドウの基本概念を参照)を構成する行数です。

Function: window-total-height &optional window round

この関数はウィンドウwindowのトータル高さを行数でリターンする。windowが省略nilの場合のデフォルトは選択されたウィンドウ。windowが内部ウィンドウなら、リターン値はそのウィンドウの子孫となるウィンドウにより占有されるトータル高さになる。

ウィンドウのピクセル高さがそのウィンドウがあるフレームのデフォルト文字高さの整数倍でなければ、そのウィンドウが占有する行数が内部で丸められる。これはそのウィンドウが親ウィンドウの場合には、すべての子ウィンドウのトータル高さの合計が、親ウィンドウのトータル高さと内部的に等しくなるような方法により行われる。これはたとえ2つのウィンドウのピクセル高さが等しくでも、内部的なトータル高さは1行分異なるかもしれないことを意味する。さらにこれはそのウィンドウが垂直コンビネーションされていて、かつ次の兄弟をもつ場合には、その兄弟の上端行は、このウィンドウの上端行とトータル高さから計算されるかもしれないことも意味する(座標とウィンドウを参照)。

オプション引数roundceilingなら、この関数はwindowのピクセル高さをそのフレームの文字高さで除した数より大であるような最小の整数、floorなら除した数より小であるような最大の整数、それ以外のroundにたいしてはwindowsのトータル高さの内部値をリターンする。

トータル幅(total width)とはそのウィンドウのボディー、左右の装飾(Emacsウィンドウの基本概念を参照)を構成する列数です。

Function: window-total-width &optional window round

この関数はウィンドウwindowのトータル幅を列でリターンする。windowが省略nilの場合のデフォルトは選択されたウィンドウ。windowが内部ウィンドウならリターン値はその子孫のウィンドウが占有するトータル幅になる。

ウィンドウのピクセル幅がそのウィンドウがあるフレームのデフォルト文字幅の整数倍でなければ、そのウィンドウが占有する列数が内部で丸められる。これはそのウィンドウが親ウィンドウの場合には、すべての子ウィンドウのトータル幅の合計が親ウィンドウのトータル幅と内部的に等しくなるような方法により行われる。これはたとえ2つのウィンドウのピクセル幅が等しくでも、内部的なトータル幅は1列分異なるかもしれないことを意味する。さらにこれはそのウィンドウが水平コンビネーションされていて、かつ次の兄弟をもつ場合、その兄弟の左端行はこのウィンドウの左端行とトータル幅から計算されるかもしれないことも意味する(座標とウィンドウを参照)。オプション引数roundwindow-total-heightの場合と同様に振る舞う。

Function: window-total-size &optional window horizontal round

この関数はウィンドウwindowのトータル高さを行数、またはトータル幅を列数でリターンする。horizontalが省略またはnilならwindowにたいしてwindow-total-heightを呼び出すのと等価、それ以外ではwindowにたいしてwindow-total-widthを呼び出すのと等価である。オプション引数roundwindow-total-heightの場合と同様に振る舞う。

以下の2つの関数はウィンドウのトータルサイズをピクセル単位で取得するために使用できます。

Function: window-pixel-height &optional window

この関数はウィンドウwindowのトータル高さをピクセル単位でリターンする。windowは有効なウィンドウでなければならずデフォルトは選択されたウィンドウ。

リターン値には上下の装飾の高さが含まれる。windowが内部ウィンドウなら、そのピクセル高さは子ウィンドウたちによりスパンされるスクリーン領域のピクセル高さになる。

Function: window-pixel-width &optional window

この関数はウィンドウwindowの幅をピクセル単位でリターンする。windowは有効なウィンドウでなければならずデフォルトは選択されたウィンドウ。

リターン値には左右の装飾の幅が含まれる。windowが内部ウィンドウなら、そのピクセル幅は子ウィンドウたちにより占有されるスクリーン領域の幅になる。

以下の関数は与えられたウィンドウに隣接するウィンドウがあるかどうかを判断するために使用できます。

Function: window-full-height-p &optional window

この関数はフレーム内でwindowの上下に他のウィンドウがなければ非nilをリターンする。より正確には、windowのトータル高さがそのフレームのルートウィンドウの高さに等しいことを意味する。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ。

Function: window-full-width-p &optional window

この関数はフレーム内でwindowの左右に他のウィンドウがなければ非nilをリターンする(トータル幅がそのフレーム上のルートウィンドウと等しい)。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ。

ウィンドウのボディー高さ(body height)とは上下の装飾(Emacsウィンドウの基本概念を参照)を含まないbodyの高さです。

Function: window-body-height &optional window pixelwise

この関数はウィンドウwindowのボディーの高さを行数でリターンする。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ、それ以外なら生きたウィンドウでなければならない。

オプション引数pixelwiseは高さにたいして用いる単位を定義する。nilなら、必要に応じて文字で計ったwindowのbody高さはもっとも近い整数に切り下げられる。これはテキスト領域の下端行が部分的に可視の場合にその行は計数されないこと、さらに任意のウィンドウのボディー高さはwindow-total-heightによりリターンされるそのウィンドウのトータル高さ決して超過し得ないことも意味する。

pixelwiseremap、かつデフォルトフェイスがリマップ(フェイスのリマップを参照)されている場合には、文字の高さの判定にリマップされたフェイスを使用する。それ以外の非nil値にたいしてはピクセル単位で高さをリターンする。

ウィンドウのボディー幅(body width)とは左右の装飾を何も含まないbodyとテキスト領域の幅です。

(幅を0にセットすることにより)一方または両方のフリンジが削除されたときには、継続と切り詰めのグリフを表示するためにディスプレイエンジンが文字セル2つを予約するので、テキスト表示にたいして2列少なくなることに注意してください(以下で説明するwindow-max-chars-per-lineはこの特性を考慮する)。

Function: window-body-width &optional window pixelwise

この関数はウィンドウwindowのボディーの幅を列数でリターンする。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ、それ以外なら生きたウィンドウでなければならない。

オプション引数pixelwiseは幅にたいして用いる単位を定義する。nilなら、必要に応じて文字で計ったwindowのbody幅はもっとも近い整数に切り下げられる。これはテキスト領域の右端の列が部分的に可視な場合にその列が計数されないことを意味する。さらにこれはウィンドウのボディーの幅がwindow-total-widthによりリターンされるウィンドウのトータル幅を決して超過し得ないことをも意味する。

pixelwiseremap、かつデフォルトフェイスがリマップ(フェイスのリマップを参照)されている場合には、文字の幅の判定にリマップされたフェイスを使用する。それ以外の非nil値にたいしてはピクセル単位で幅をリターンする。

Function: window-body-size &optional window horizontal pixelwise

この関数はwindowのボディーの高さか幅をリターンする。horizontalが省略またはnilならwindowにたいしてwindow-body-height、それ以外ならwindow-body-widthを呼び出すのと同じ。いずれの場合もオプション引数pixelwiseは呼び出された関数に渡される。

ウィンドウのモードライン、タブライン、ヘッダーラインのピクセル高さは以下の関数により取得できます。それらのリターン値は、そのウィンドウが以前に表示されていない場合を除いて通常は加算されます。その場合のリターン値はそのウィンドウのフレームにたいして使用を予想されるフォントが元になります。

Function: window-mode-line-height &optional window

この関数はwindowモードラインの高さをピクセルでリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。windowにモードラインがなければリターン値は0。

Function: window-tab-line-height &optional window

この関数はwindowのタブラインの高さをピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。windowにタブラインがない場合のリターン値は0。

Function: window-header-line-height &optional window

この関数はwindowのヘッダーラインの高さをピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。windowにヘッダーラインがない場合のリターン値は0。

ウィンドウディバイダー(ウィンドウディバイダーを参照)、フリンジ(フリンジを参照)、スクロールバー(スクロールバーを参照)、ディスプレイマージン(マージン内への表示を参照)を取得する関数については、それぞれ対応するセクションで説明されています。

Lispプログラムでレイアウト上の判断を要する場合には、以下の関数を有用と思うでしょう:

Function: window-max-chars-per-line &optional window face

この関数は指定されたウィンドウwindow (生きたウィンドウであること)内で、指定されたフェイスfaceで表示される文字数をリターンする。faceがリマップ(フェイスのリマップを参照)されていたらリマップされたフェイスの情報がリターンされる。省略またはnilの場合、faceのデフォルトはデフォルトフェイス、windowのデフォルトは選択されたウィンドウ。

この関数はwindow-body-widthと異なり、windowのフレームの正準文字幅(canonical character width)の単位ではなく、faceのフォントの実サイズを考慮する。またwindowの一方または両方のフリンジがなければ、継続グリフに使用されるスペースも考慮する。

ウィンドウのサイズを変更(ウィンドウのリサイズを参照)したりウィンドウを分割(split)するコマンド(ウィンドウの分割を参照)は、指定できるウィンドウの最小の高さと幅を指定する変数window-min-heightwindow-min-widthにしたがう。これらのコマンドはウィンドウのサイズがfixed(固定)になる変数window-size-fixedにもしたがう(ウィンドウサイズの保持を参照)。

User Option: window-min-height

このオプションは任意のウィンドウの最小のトータル高さを行で指定する。この値は最低でも1つのテキスト行、および上下のすべての装飾が含まれている必要がある。

User Option: window-min-width

このオプションはすべてのウィンドウの最小のトータル幅を列で指定する。この値は2つのテキスト列、および左右のすべての装飾が含まれている必要がある。

以下の関数は、ある特定の大きさのウィンドウにたいして、それのwindow-min-heightwindow-min-width、およびwindow-size-fixed (ウィンドウサイズの保持を参照)の値と領域のサイズを示す。

Function: window-min-size &optional window horizontal ignore pixelwise

この関数はwindowの最小のサイズをリターンする。windowは有効なウィンドウでなければならず、デフォルトは選択されたウィンドウ。オプション引数horizontalが非nilならwindowの最小の列数、それ以外はwindowの最小の行数をリターンすることを意味する。

このリターン値によってwindowのサイズが実際にその値にセットされた場合にwindowのすべてのコンポーネントが完全に可視にとどまることが保証される。horizontalnilなら上下のすべての装飾が含まれる。horizontalが非nilなら、windowの左右のすべての装飾が含まれる。

オプション引数ignoreが非nilなら、window-min-heightwindow-min-widthによりセットされる固定サイズのウィンドウに強いられる制限を無視することを意味する。ignoresafeなら、生きたウィンドウは可能な限り小さなwindow-safe-min-heightの行、およびwindow-safe-min-widthの列を得る。ignoreにウィンドウが指定されると、そのウィンドウにたいする制限だけを無視する。その他の非nil値では、すべてのウィンドウにたいする上記制限のすべてが無視されることを意味する。

オプション引数pixelwiseが非nilなら、windowの最小サイズがピクセルで計数されてリターンされることを意味する。


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

29.5 ウィンドウのリサイズ

このセクションではフレームのサイズを変更せずにウィンドウのサイズを変更する関数について説明します。生きたウィンドウはオーバーラップしないので、これらの関数は2つ以上のウィンドウを含む関数上でのみ意味があります(ウィンドウのリサイズにより他の少なくとも1つのウィンドウのサイズも変更される)。フレーム上に単一のウィンドウしか存在しない場合には、フレームの変更以外でウィンドウのサイズ変更はできません(フレームのサイズを参照)。

注記した場合を除き、これらの関数は引数として内部ウィンドウも許容します。内部ウィンドウのリサイズにより、同じスペースにフィットするように子ウィンドウもリサイズされます。

Function: window-resizable window delta &optional horizontal ignore pixelwise

この関数はwindowのサイズがdelta行により垂直に変更され得る場合にはdeltaをリターンする。オプション引数horizontalが非nilの場合には、windowdelta列単位に水平方向にリサイズ可能ならかわりにdeltaをリターンする。これは実際にはウィンドウのサイズを変更しない。

windownilの場合のデフォルトは選択されたウィンドウ。

deltaが正の値ならそのウィンドウが行または列の単位で拡張可能かどうかをチェックすることを意味し、deltaが負の値ならそのウィンドウが行または列の単位で縮小可能かどうかをチェックすることを意味する。deltaが非0の場合のリターン値0は、そのウィンドウがリサイズ可能であることを意味する。

変数window-min-heightwindow-min-widthには通常は許容される最小のウィンドウサイズを指定する(ウィンドウのサイズを参照)。しかしオプション引数ignoreが非nilなら、この関数はwindow-size-fixedと同様にwindow-min-heightwindow-min-widthを無視する。そのかわりに上下の装飾と1行分の高さのテキストの合計をウィンドウの最小高さ、左右の装飾と2列分を占めるのテキストの合計をウィンドウの最小幅と判断する。

オプション引数pixelwiseが非nilならdeltaはピクセル単位として解釈される。

Function: window-resize window delta &optional horizontal ignore pixelwise

この関数はwindowdelta増加することによりリサイズを行う。horizontalnilなら高さをdelta行、それ以外は幅をdelta行変更する。正のdeltaはウィンドウの拡大、負のdeltaは縮小を意味する。

windownilの場合のデフォルトは選択されたウィンドウ。要求されたようにウィンドウをリサイズできなければエラーをシグナルする。

オプション引数ignoreは上述の関数window-resizableの場合と同じ意味をもつ。

オプション引数pixelwiseが非nilならdeltaはピクセル単位として解釈される。

この関数がどのウィンドウのエッジを変更するかの選択はオプションwindow-combination-resizeの値、および関連するウィンドウのコンビネーションリミット(combination limits: 組み合わせ制限)に依存し、両方のエッジを変更するような場合もいくつかある。ウィンドウの再結合を参照のこと。ウィンドウの下端か右端のエッジを移動することだけでリサイズするには関数adjust-window-trailing-edgeを使用すること。

Function: adjust-window-trailing-edge window delta &optional horizontal pixelwise

この関数はwindowの下端エッジをdelta行分移動する。オプション引数horizontalが非nilなら、かわりに右端エッジをdelta列分移動する。windownilの場合のデフォルトは選択されたウィンドウ。

オプション引数pixelwiseが非nilならdeltaはピクセル単位として解釈される。

正のdeltaはエッジを下方か右方、負のdeltaはエッジを上方か左方へ移動する。deltaで指定された範囲までエッジを移動できなければ、この関数はエラーをシグナルせずに可能な限りエッジを移動する。

この関数は移動されたエッジに隣接するウィンドウのリサイズを試みる。何らかの理由(隣接するウィンドウが固定サイズの場合等)によりそれが不可能なら、他のウィンドウをリサイズするかもしれない。

User Option: window-resize-pixelwise

このオプションの値が非nilならEmacsはウィンドウをピクセル単位でリサイズする。これは現在のところsplit-window (ウィンドウの分割を参照)、maximize-windowminimize-windowfit-window-to-bufferfit-frame-to-buffershrink-window-if-larger-than-buffer (すべて以下に記述)のような関数に影響を与える。

あるフレームのピクセルサイズがそのフレームの文字サイズの整数倍でないときは、たとえこのオプションがnilであっても少なくとも1つのウィンドウがピクセル単位でリサイズされるであろうことに注意。デフォルト値はnil

以下のコマンドは、より具体的な方法でウィンドウをリサイズします。これらがインタラクティブに呼び出されたときは選択されたウィンドウにたいして作用します。

Command: fit-window-to-buffer &optional window max-height min-height max-width min-width preserve-size

このコマンドはwindowの高さか幅をウィンドウ内のテキストにフィットするように調整する。windowがリサイズできたら非nil、それ以外はnilをリターンする。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ、それ以外の場合には生きたウィンドウであること。

windowが垂直コンビネーションの一部なら、この関数はwindowの高さを調整する。新たな高さはそのウィンドウのバッファーのアクセス可能な範囲の実際の高さから計算される。オプション引数max-heightが非nilなら、それはこの関数がwindowに与えることができる最大のトータル高さを指定する。オプション引数min-heightが非nilなら、それは与えることができる最小のトータル高さを指定して、それは変数window-min-heightをオーバーライドする。max-heightmin-heightはいずれもwindow上下のすべての装飾を含んだ行数で指定する。

windowが水平コンビネーションの一部で、かつオプションfit-window-to-buffer-horizontally (以下参照)の値が非nilなら、この関数はwindowの幅を調整する。新たな幅はwindowのカレントのスタート位置以降のバッファーの最長の行から計算される。オプション引数max-widthは最大幅を指定して、デフォルトはwindowのフレーム幅。オプション引数min-widthは最小幅を指定して、デフォルトはwindow-min-widthmax-widthmin-widthはどちらもwindowの左右のすべての装飾を含んだ列数で指定する。

オプション引数preserve-sizeが非nilなら、将来のリサイズ操作の間のwindowのサイズを予約するパラメーターをインストールする(ウィンドウサイズの保持を参照)。

オプションfit-frame-to-buffer (以下参照)が非nilなら、この関数はfit-frame-to-buffer (以下参照)を呼び出すことにより、windowのコンテンツにフィットするようにwindowのフレームのリサイズを試みるだろう。

User Option: fit-window-to-buffer-horizontally

これが非nilなら、fit-window-to-bufferはウィンドウを水平方向にリサイズできる。これがnil (デフォルト)ならfit-window-to-bufferはウィンドウ決して水平方向にリサイズしない。これがonlyならウィンドウを水平方向だけにリサイズできる。その他の値ではfit-window-to-bufferがウィンドウをどちらの方向にもリサイズできることを意味する。

User Option: fit-frame-to-buffer

このオプションが非nilなら、fit-window-to-bufferはフレームをフレームのコンテンツにフィットさせることができる。フレームは、フレームのルートウィンドウが生きたウィンドウで、かつこのオプションが非nilの場合のみフィットされる。horizontallyならフレームは水平方向にのみフィットされる。verticallyならフレームは垂直方向にのみフィットされる。その他の非nil値はフレームがどちらの方向にもフィットできることを意味する。

単一のウィンドウだけを表示するフレームではコマンドfit-frame-to-bufferを使用してそのバッファーにフレームをフィットできます。

Command: fit-frame-to-buffer &optional frame max-height min-height max-width min-width only

このコマンドはframeのサイズを、表示しているバッファーのコテンツに正確に調整する。frameには任意の生きたフレームを指定できデフォルトは選択されたフレーム。frameのルートウィンドウが生きている場合のみフィットが行われる。

引数max-heightmin-heightmax-widthmin-widthが非nilの場合にはframeのルートウィンドウの新たなボディーサイズの境界を指定する。これらの引数いずれかに非nil値を指定した場合には、後述のfit-frame-to-buffer-sizesオプションで指定された対応する値をオーバーライドする。

この関数はオプション引数onlyverticallyなら垂直方向のみ、onlyhorizontallyなら水平方向のみフレームをリサイズする。

fit-frame-to-bufferの振る舞いは次にリストする2つのオプションで制御可能です。

User Option: fit-frame-to-buffer-margins

このオプションはフレーム周辺のマージンを指定してfit-frame-to-bufferでフィットさせるために使用できる。このようなマージンはたとえばタスクバーや親フレームの一部とオーバーラップするフレームのリサイズを防ぐために有用かもしれない。

これはフィットされるフレームの左右上下にフリーとして残されるピクセル数を指定する。デフォルトのnilはそれぞれにたいしてマージンを使用しないことを指定する。ここで指定した値は、特定のフレームにたいしてもしそのフレームのfit-frame-to-buffer-marginsが与えられればオーバーライドされ得る。

User Option: fit-frame-to-buffer-sizes

このオプションはfit-frame-to-bufferにたいするサイズ境界を指定する。これはすべてのフレームにおいてバッファーにフィットされるルートウィンドウのbodyの行の最大と最小、列の最大と最小の合計を指定する。指定された値が非nilであるようなオプションは、fit-frame-to-bufferの対応する引数にオーバーライドされる。

Command: shrink-window-if-larger-than-buffer &optional window

このコマンドはwindowにたいしてそのバッファーを完全に表示できるが、window-min-height以上の行を表示できるまで可能な限りwindowの高さを縮小する。リターン値はそのウィンドウがリサイズされれば非nil、それ以外なら非nilwindowが省略またはnilの場合のデフォルトは選択されたウィンドウ。それ以外では生きたウィンドウであること。

このコマンドはそのウィンドウがバッファーのすべてを表示するにはすでに高さが低すぎる場合、バッファーのどこかがスクリーンからスクロールオフされている場合、またはそのウィンドウがフレーム内で唯一の生きたウィンドウの場合は何も行わない。

このコマンドは自身の処理を行うためにfit-window-to-buffer (上記参照)を呼び出す。

Command: balance-windows &optional window-or-frame

この関数は各ウィンドウにたいして完全な幅、および/または完全な高さを与えるような方法によって各ウィンドウの釣り合いをとる。window-or-frameにフレームを指定すると、そのフレーム上のすべてのウィンドウのバランスをとる。window-or-frameにウィンドウを指定すると、そのウィンドウとウィンドウのsiblings(兄弟)にたいしてのみのバランスをとる(ウィンドウとフレームを参照)。

Command: balance-windows-area

この関数は選択されたフレーム上のすべてのウィンドウにたいして、おおよそ同じスクリーンエリアを与えようと試みる。完全な幅か高さをもつウィンドウにたいしては、他のウィンドウと比較してより多くのスペースは与えられない。

Command: maximize-window &optional window

この関数は、windowにたいして、そのフレームをリサイズしたり他のウィンドウを削除することなく、水平垂直の両方向で可能な限り大きくなるように試みる。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ。

Command: minimize-window &optional window

この関数はwindowにたいして、そのフレームをリサイズしたりそのウィンドウを削除することなく、水平垂直の両方向で可能な限り小さくなるように試みる。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ。


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

29.6 ウィンドウサイズの保持

前セクションのいずれかの関数を使用してウィンドウを明示的にリサイズしたり、たとえば隣接するウィンドウのリサイズ時、ウィンドウの分割や削除(ウィンドウの分割とsee ウィンドウの削除を参照)、あるいはそのウィンドウのフレームをリサイズ(フレームのサイズを参照)する際に暗黙的にリサイズできます。

同一フレーム上に1つ以上のリサイズ可能なウィンドウが他に存在する際には、特定のウィンドウにたいして暗黙のリサイズを避けることが可能です。この目的にたいして、Emacsにそのウィンドウのサイズの予約(preserve)をアドバイスしなければなりません。これを行うための基本的な方法が2つあります。

Variable: window-size-fixed

このバッファーローカル変数が非nilなら、通常はそのバッファーを表示するすべてのウィンドウのサイズが変更できなくなる。ウィンドウ削除やそのフレームのサイズ変更により、それ以外に方法がなければ依然としてウィンドウのサイズは変更され得る。

値がheightならそのウィンドウの高さのみ、値がwidthならそのウィンドウの幅のみが固定される。その他の非nil値では幅と高さの両方が固定される。

この変数がnilでも、そのバッファーを表示している任意のウィンドウを任意の方向にリサイズできるとはいえない。これを判断するには関数window-resizableを使用する。ウィンドウのリサイズを参照のこと。

影響を受けるウィンドウにたいする明示的なリサイズや分割の試みも同様に抑制するので、window-size-fixedの積極性が過度な場合が多々あります。これはたとえそのウィンドウが暗黙にリサイズされた後にも、たとえば隣接するウィンドウの削除やウィンドウのフレームのリサイズの際に発生するかもしれません。以下の関数では、そのようなウィンドウのリサイズを絶対禁止としないよう試みます:

Function: window-preserve-size &optional window horizontal preserve

この関数は将来のリサイズ操作用にウィンドウwindowの高さを予約済み(preserved)としてマーク(または非マーク)する。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。オプション引数horizontalが非nilならwindowの幅を予約済みとしてマーク(または非マーク)する。

オプション引数preservetならwindowボディーのカレントの高さまたは幅を予約することを意味する。windowの高さまたは幅はEmacsが他によい選択をもたないときのみ変更される。この関数により予約されたウィンドウにたいする高さや幅のリサイズは決してエラーをthrowしない。

preservenilなら、この関数の以前の呼び出しにより誘発されたwindowにたいする任意の拘束を解除して、windowの高さまたは幅の予約を停止することを意味する。引数にwindowを与えてenlarge-windowshrink-windowfit-window-to-bufferを呼び出すことによっても対応する高速を削除できる。

現在のことろwindow-preserve-sizeは以下の関数から呼び出されています:

fit-window-to-buffer

この関数のオプション引数preserve-sizeが非nilなら、この関数により確保されたサイズは予約される(ウィンドウのリサイズを参照)。

display-buffer

この関数のalist引数にpreserve-sizeエントリーがあれば、この関数により生成されるウィンドウサイズは予約される(バッファーを表示するウィンドウの選択を参照)。

window-preserve-sizeはウィンドウリサイズ関数から参照されるwindow-preserved-sizeと呼ばれるウィンドウパラメーターをインストールします(ウィンドウのパラメーターを参照)。このパラメーターはウィンドウがwindow-preserve-sizeが呼び出されたときと異なるバッファーを表示していたり、呼び出し以降にウィンドウのサイズが変化していたらウィンドウのリサイズを妨げません。

以下の関数は特定のウィンドウの高さが予約済みかどうかチェックするために使用できます:

Function: window-preserved-size &optional window horizontal

この関数はウィンドウwindowの予約済み高さをピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。オプション引数horizontalが非nilならwindowの予約済み幅をリターンする。windowのサイズが予約されていなければnilをリターンする。


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

29.7 ウィンドウの分割

このセクションでは既存のウィンドウを分割(splitting)することによりウィンドウを新たに作成する関数を説明します。ここで説明する理由により関数が失敗するという意味において、特別なウィンドウがいくつかあることに注意してください。このようなウィンドウの例としてサイドウィンドウ(サイドウィンドウを参照)やアトミックウィンドウ(アトミックウィンドウを参照)があります。

Function: split-window &optional window size side pixelwise

この関数はウィンドウwindowの隣に生きたウィンドウを新たに作成する。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ。そのウィンドウは分割(split)されてサイズは縮小される。そのスペースはリターンされる新たなウィンドウによって吸収される。

オプションの第2引数sizeは、windowおよび/または新たなウィンドウのサイズを決定する。これが省略またはnilなら、両方のウィンドウに同じサイズが割り当てられる。行数が奇数なら、余りの1行は新たなウィンドウに割り当てられる。sizeが正の数値なら、windowsizeの行数(sideの値によっては列数)が与えられる。sizeが負の数値なら、新たなウィンドウに-sizeの行数(または列数)が与えられる。

sizenilなら、この関数は変数window-min-heightwindow-min-widthにしたがう(ウィンドウのサイズを参照)。つまり分割によりこれらの変数の指定より小さいウィンドウが作成されるようならエラーをシグナルする。しかしsizeにたいして非nil値を指定すると、これらの変数は無視される。その場合には許容される最小のウィンドウはテキストの高さが1行、および/または幅が2列のウィンドウとみなされる。

したがってsizeが指定された場合には、生成されるウィンドウがモードラインやスクロールバー等すべての装飾を含むのに十分な大きさがあるかどうかチェックするのは呼び出し側の責任である。これに関して必要最小限のwindowを決定するために関数window-min-size (ウィンドウのサイズを参照)を使用できる。新たなウィンドウは通常はモードラインやスクロールバー等のエリアをwindowから継承するので、この関数は新たなウィンドウの最小サイズも良好に推定する。呼び出し側は、次回の再表示前にこれに応じて継承されたエリアを削除する場合のみ、より小さなサイズを指定すること。

オプションの第3引数sideは新たなウィンドウの位置をwindowから相対的に指定する。nilまたはbelowなら新たなウィンドウはwindowの下、aboveならwindowの上に配置される。どちらの場合でもsizeはウィンドウのトータル高さを行数で指定する。

sidetrightなら新たなウィンドウはwindowの右、sideleftならwindowの左に配置される。どちらの場合でもsizeはウィンドウのトータル幅を列数で指定する。

オプションの第4引数pixelwiseが非nilなら、sizeを行や列ではなくピクセル単位で解釈することを意味する。

windowが生きたウィンドウの場合には、新たなウィンドウはマージンやスクロールバーを含むさまざまなプロパティを継承する。windowが内部ウィンドウ(internal window)の場合には、新たなウィンドウはwindowのフレームのプロパティを継承する。

変数ignore-window-parametersnilの場合に限り、この関数の挙動はwindowなパラメーターにより変更されるかもしれない。ウィンドウパラメーターsplit-windowの値がtなら、この関数はその他すべてのウィンドウパラメーターを無視する。それ以外ではウィンドウパラメーターsplit-windowの値が関数の場合には、split-windowの通常アクションのかわりに引数windowsizesideでその関数が呼び出される。値が関数以外なら、この関数は(もしあれば)ウィンドウパラメーターwindow-atomまたはwindow-sideにしたがう。ウィンドウのパラメーターを参照のこと。

例としてウィンドウとフレームで議論したウィンドウ構成(window configuration)を得るための、一連のsplit-window呼び出しを以下に示します。この例では生きたウィンドウの分割と、内部ウィンドウの分割も示しています。最初はW4で表される単一のウィンドウ(生きたルートウィンドウ)を含むフレームから開始します。(split-window W4)を呼び出すことにより以下のウィンドウ構成が得られます。

     ______________________________________
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||_________________W4_________________||
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||_________________W5_________________||
    |__________________W3__________________|

split-window呼び出しによりW5で示す生きたウィンドウが新たに作成されました。W3で示される内部ウィンドウも新たに作成され、これはルートウィンドウかつW4W5の親ウィンドウになります。

次は引数として内部ウィンドウW3を渡して(split-window W3 nil 'left)を呼び出します。

     ______________________________________
    | ______  ____________________________ |
    ||      || __________________________ ||
    ||      |||                          |||
    ||      |||                          |||
    ||      |||                          |||
    ||      |||____________W4____________|||
    ||      || __________________________ ||
    ||      |||                          |||
    ||      |||                          |||
    ||      |||____________W5____________|||
    ||__W2__||_____________W3_____________ |
    |__________________W1__________________|

内部ウィンドウW3の左に生きたウィンドウW2が新たに作成されました。そして内部ウィンドウW1が新たに作成され、これが新たにルートウィンドウになります。

インタラクティブな使用にたいして、Emacsは選択されたウィンドウを常に分割するコマンドを2つ提供します。これらは内部でsplit-windowを呼び出しています。

Command: split-window-right &optional size window-to-split

この関数はウィンドウwindow-to-splitが左側になるように、ウィンドウwindow-to-splitを2つの横並びのウィンドウに分割する。window-to-splitのデフォルトは選択されたウィンドウ。sizeが正ならば左のウィンドウがsize列、負ならば右のウィンドウが-size列を与えられる。

Command: split-window-below &optional size window-to-split

この関数はウィンドウwindow-to-splitが上側になるように、ウィンドウwindow-to-splitを2つの縦並びのウィンドウに分割する。window-to-splitのデフォルトは選択されたウィンドウ。sizeが正ならば上のウィンドウがsize行、負ならば下のウィンドウが-size行を与えられる。

Command: split-root-window-below &optional size

この関数はフレーム全体を2つに分割する。カレントのウィンドウ構成は上側に留まり、フレーム全体の幅を占めるような新たなウィンドウを下側に作成する。sizesplit-window-belowの場合と同様に扱われる。

Command: split-root-window-right &optional size

この関数はフレーム全体を2つに分割する。カレントのウィンドウ構成は左側に留まり、フレーム全体の高さを占めるような新たなウィンドウを右側に作成する。sizesplit-window-belowの場合と同様に扱われる。

User Option: split-window-keep-point

この変数の値が非nil (デフォルト)ならsplit-window-belowは上述のように振る舞う。

nilならsplit-window-belowは再表示が最小となるように、2つのウィンドウの各ポイントを調節する(これは低速な端末で有用)。これは何であれ、以前ポイントがあったスクリーン行(screen line)を含むウィンドウを選択する。これは低レベルsplit-window関数ではなくsplit-window-belowだけに影響することに注意。


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

29.8 ウィンドウの削除

ウィンドウを削除(delete)することにより、フレームのウィンドウツリーからウィンドウが取り除かれます。それが生きたウィンドウならスクリーンに表示されなくなります。内部ウィンドウならその子ウィンドウも削除されます。

ウィンドウを削除した後であっても、それへの参照が残っている限りはLispオブジェクトとして存在し続けます。ウィンドウ構成(window configuration)をリストアすることにより、ウィンドウの削除は取り消すことができます(ウィンドウの構成を参照)。

Command: delete-window &optional window

この関数は表示からwindowを削除してnilをリターンする。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ。

ウィンドウ削除によりウィンドウツリーにウィンドウが何も残らなくなるか(それがフレーム内で唯一の生きたウィンドウの場合)、あるいはwindowのフレーム上の残りすべてのウィンドウがサイドウィンドウ(サイドウィンドウを参照)ならエラーがシグナルされる。windowがアトミックウィンドウ(アトミックウィンドウを参照)の一部なら、この関数はかわりにアトミックウィンドウのルートウィンドウの削除を試みる。

デフォルトではwindowが占めていたスペースは、(もしあれば)隣接する兄弟ウィンドウのうちの1つに与えられる。しかし変数window-combination-resizeが非nilなら、そのスペースは同一ウィンドウコンビネーション内の残りのすべてのウィンドウに比例的に分配される。See ウィンドウの再結合を参照のこと。

変数ignore-window-parametersnilの場合に限り、この関数の振る舞いはwindowのウィンドウパラメーターにより変更される可能性がある。ウィンドウパラメーターdelete-windowの値がtなら、この関数はその他すべてのウィンドウパラメーターを無視する。ウィンドウパラメーターdelete-windowが関数なら、通常のdelete-windowのかわりに引数windowでその関数が呼び出される。ウィンドウのパラメーターを参照のこと。

フレームの選択されたウィンドウをdelete-windowで削除したときは、別のウィンドウをそのフレームの新たな選択されたウィンドウにする必要があります。このとき選択されるウィンドウを以下のオプションで設定できます。

User Option: delete-window-choose-selected

このオプションでdelete-windowが選択されたウィンドウを削除した後に、かわりの選択するウィンドウを指定できる。可能な選択肢は

  • mru そのフレームでもっとも最近に使用したウィンドウを選択する(デフォルト)。
  • pos そのフレームで前に選択されていたポイントのフレーム座標を含むウィンドウを選択する。
  • nil そのフレームの最初のウィンドウ(frame-first-windowがリターンするウィンドウ)を選択する。

nilno-other-windowパラメーターをもつウィンドウは、そのフレームの他のすべてのウィンドウもこのパラメーターが非nil値をもつ場合しか選択されることはない。

Command: delete-other-windows &optional window

この関数は必要に応じて他のウィンドウを削除することにより、windowでフレームを充填する。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ。windowがサイドウィンドウならエラーをシグナルする(サイドウィンドウを参照)。windowがアトミックウィンドウの一部なら、この関数はアトミックウィンドウのルートウィンドウによるフレームの重点を試みる(アトミックウィンドウを参照)。リターン値はnil

変数ignore-window-parametersnilの場合に限り、この関数の振る舞いは変更される可能性がある。ウィンドウパラメーターdelete-other-windowsの値がtなら、この関数は他のすべてのウィンドウパラメーターを無視する。ウィンドウパラメーターdelete-other-windowsの値が関数なら、delete-other-windowsの通常の動作のかわりに引数windowでその関数が呼び出される。ウィンドウのパラメーターを参照のこと。

さらにignore-window-parametersnilなら、この関数はno-delete-other-windowsパラメーターが非nilのウィンドウを削除しない。

Command: delete-windows-on &optional buffer-or-name frame

この関数はbuffer-or-nameを表示しているすべてのウィンドウにたいしてdelete-windowを呼び出すことによってそれらを削除する。buffer-or-nameはバッファー、またはバッファー名であること。省略またはnilの場合のデフォルトはカレントバッファー。指定されたバッファーを表示するウィンドウが存在しなければ、この関数は何も行わない。ミニバッファーが指定されるとエラーをシグナルする。

そのバッファーの表示に専用(dedicated)のウィンドウがあり、フレーム上でそれが唯一のウィンドウの場合には、それが端末上で唯一のフレームでなければこの関数はそのフレームも削除する。

オプション引数frameは操作を行うフレームがどれかを指定する:

  • nil すべてのフレームを処理することを意味する。
  • t 選択されたフレームを処理することを意味する。
  • visible 可視なすべてのフレームを処理することを意味する。
  • 0 可視またはアイコン化されたすべてのフレームを処理することを意味する。
  • フレーム そのフレームを処理することを意味する。

この引数の意味は、すべての生きたウィンドウを走査する他の関数(ウィンドウのサイクル順を参照)の場合とは異なることに注意。特にここでのtnilのもつ意味は、これら他の関数の場合とは逆になる。


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

29.9 ウィンドウの再結合

ウィンドウWの最後の兄弟を削除したときは、ウィンドウツリー内の親ウィンドウをWを置き換えることにより、その親ウィンドウも削除されます。これは新たなウィンドウコンビネーションを形成するために、Wがその親の兄弟たちと再結合されなければならないことを意味します。生きたウィンドウを削除することにより、必然的に2つの内部ウィンドウが削除されるかもしれない場合もあります。

     ______________________________________
    | ______  ____________________________ |
    ||      || __________________________ ||
    ||      ||| ___________  ___________ |||
    ||      ||||           ||           ||||
    ||      ||||____W6_____||_____W7____||||
    ||      |||____________W4____________|||
    ||      || __________________________ ||
    ||      |||                          |||
    ||      |||                          |||
    ||      |||____________W5____________|||
    ||__W2__||_____________W3_____________ |
    |__________________W1__________________|

この構成におけるW5の削除は、通常はW3W4の削除を誘発します。残りの生きたウィンドウW2W6W7は親をW7とする水平コンビネーションを形成するために再結合されます。

しかし、ときにはW4のような親ウィンドウを削除しないほうが合理的な場合もあります。特に親ウィンドウが同じタイプのコンビネーション内に埋め込まれるコンビネーションを保護するために使用されるときは、それを削除するべきではありません。そのような埋め込みは、あるウィンドウを分割した後に続けて新たなウィンドウを削除する際、Emacsが関連するフレームで分割前にあったレイアウトを確実に再構築するために意味があります。

親がW1であるような2つの生きたウィンドウW2W3を出発点とするシナリオを考えてみましょう。

     ______________________________________
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||_________________W2_________________||
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||_________________W3_________________||
    |__________________W1__________________|

W2を分割すると以下のようにウィンドウW4が新たに作成されます。

     ______________________________________
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||_________________W2_________________||
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||_________________W4_________________||
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||_________________W3_________________||
    |__________________W1__________________|

ここでウィンドウを垂直方向に拡大すると、Emacsはもしそのようなウィンドウがあれば下位の兄弟ウィンドウから対応するスペースを得ようと試みます。このシナリオではW4の拡大により、W3からスペースが奪われます。

     ______________________________________
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||_________________W2_________________||
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||_________________W4_________________||
    | ____________________________________ |
    ||_________________W3_________________||
    |__________________W1__________________|

W4を削除すると、前にW3から奪ったスペースを含むスペース全体がW2に与えられるでしょう。

     ______________________________________
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||_________________W2_________________||
    | ____________________________________ |
    ||_________________W3_________________||
    |__________________W1__________________|

これは特にW4が一時的にバッファーを表示するために使用されていて(一時的な表示を参照)、かつ初期のレイアウトで作業を継続したい場合には直感に反するかもしれません。

この振る舞いはW2を分割する際に新たな親ウィンドウを作成することにより解決できます。

User Option: window-combination-limit

この変数はウィンドウ分割により新たに親ウィンドウを作成させるかどうかを制御する。以下の値が認識される:

nil

これは既存のウィンドウコンビネーションと同じ方向で分割が発生した場合(これ以外の場合には、いずれにせよ内部ウィンドウが新たに作成される)は、既存の親ウィンドウが存在するなら新たな生きたウィンドウがそれを共有できることを意味する。

window-size

これはdisplay-bufferがウィンドウを分割する際に新たな親ウィンドウを作成してalist引数のwindow-heightエントリーやwindow-widthエントリーに渡すことを意味する(バッファー表示用のアクション関数を参照)。それ以外の場合にはウィンドウの分割は値がnilのときのように振る舞う。

temp-buffer-resize

この場合にはwith-temp-buffer-windowがウィンドウを分割して、かつtemp-buffer-resize-modeが有効なら新たに親ウィンドウを作成する(一時的な表示を参照)。それ以外ならウィンドウ分割はnilの場合のように振る舞う。

temp-buffer

この場合にはwith-temp-buffer-windowは既存のウィンドウの分割時に常に新たな親ウィンドウを作成する(一時的な表示を参照)。それ以外ならウィンドウ分割はnilの場合のように振る舞う。

display-buffer

これはdisplay-buffer (バッファーを表示するウィンドウの選択を参照)がウィンドウを分割する際に、常に親ウィンドウを新たに作成することを意味する。それ以外ならウィンドウ分割はnilの場合のように振る舞う。

t

これはウィンドウを分割することによって常に親ウィンドウが新たに作成されることを意味する。したがってこの変数の値が常にtなら、すべてのウィンドウツリーは常に2分木(ルートウィンドウ以外のすべてのウィンドウが正確に1つの兄弟をもつようなツリー)になる。

デフォルトはwindow-sizeであり、それ以外の値は将来のために予約済み。

この変数のセッティングの結果としてsplit-windowが新たに親ウィンドウを作成したら、新たに作成された内部ウィンドウにたいしてset-window-combination-limit (以下参照)も呼び出す。これは子ウィンドウが削除された際のウィンドウツリーの再配置に影響する(以下参照)。

window-combination-limittなら、このシナリオの初期構成では以下のようになるでしょう:

     ______________________________________
    | ____________________________________ |
    || __________________________________ ||
    |||                                  |||
    |||________________W2________________|||
    || __________________________________ ||
    |||                                  |||
    |||________________W4________________|||
    ||_________________W5_________________||
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||_________________W3_________________||
    |__________________W1__________________|

子としてW2と新たな生きたウィンドウをもつ内部ウィンドウW5が新たに作成されます。ここでW2W4の唯一の兄弟なので、W4を拡大するとW3は変更せずにW2の縮小を試みるでしょう。W5は垂直コンビネーションW1に埋め込まれた2つのウィンドウからなる垂直コンビネーションを表すことに注意してください。

Function: set-window-combination-limit window limit

この関数はウィンドウwindowコンビネーションリミット(combination limit: 結合限界)limitにセットする。この値は関数window-combination-limitを通じて取得できる。効果については以下を参照のこと。これは内部ウィンドウにたいしてのみ意味をもつことに注意。split-windowは呼び出された際に変数window-combination-limittなら、tlimitとしてこの関数を呼び出す。

Function: window-combination-limit window

この関数はwindowにたいするコンビネーションリミットをリターンする。

コンビネーションリミットは内部ウィンドウにたいしてのみ意味をもつ。これがnilならEmacsはウィンドウ削除に応じて、兄弟同士で新たなウィンドウコンビネーションを形成することによりwindowの子ウィンドウをグループ化するために、windowの自動的な削除を許す。コンビネーションリミットがtならwindowの子ウィンドウがその兄弟と自動的に再結合されることは決してない。

このセクションの冒頭で示した構成の場合は、W4 (W6W7の親ウィンドウ)のコンビネーションリミットはtなのでtを削除しても暗黙でW4も削除されることはない。

かわりに同じ構成内の中の1つのウィンドウが分割や削除されたときは、常に構成内のすべてのウィンドウをリサイズすることにより上記で示した問題を避けることができます。これはそのような操作にたいして、この方法以外では小さすぎるようなウィンドウの分割も可能にします。

User Option: window-combination-resize

この変数がnilなら、split-windowはウィンドウ(以下window)自身と新たなウィンドウの両方にたいして、windowのスクリーンエリアが十分大きい場合のみwindowを分割できる。

この変数がtなら、split-windowは新たなウィンドウに対応するためにwindowと同一コンビネーション内のすべてのウィンドウのリサイズを試みる。これは特にwindowが固定サイズウィンドウのときや、通常の分割には小さすぎるときもsplit-windowをが成功することを許す。さらに続けてwindowのリサイズや削除を行うと、そのコンビネーション内のその他すべてのウィンドウをリサイズする。

デフォルトはnilであり、それ以外の値は将来の使用のため予約済みである。window-combination-limitの非nil値の影響を受ける場合には、この変数の値は特定の分割操作にたいして無視される。

window-combination-resizeの効果を説明するために以下のフレームレイアウトを考えてください。

     ______________________________________
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||_________________W2_________________||
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||_________________W3_________________||
    |__________________W1__________________|

window-combination-resizenilなら、ウィンドウW3を分割してもW2のサイズは変更されません:

     ______________________________________
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||                                    ||
    ||_________________W2_________________||
    | ____________________________________ |
    ||                                    ||
    ||_________________W3_________________||
    | ____________________________________ |
    ||                                    ||
    ||_________________W4_________________||
    |__________________W1__________________|

window-combination-resizetなら、W3を分割すると3つの生きたウィンドウすべてをおおよそ同じ高さにします:

     ______________________________________
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||_________________W2_________________||
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||_________________W3_________________||
    | ____________________________________ |
    ||                                    ||
    ||                                    ||
    ||_________________W4_________________||
    |__________________W1__________________|

生きたウィンドウW2W3W4のいずれを削除しても、削除されたウィンドウのスペースは残りの2つの生きたウィンドウに相対的に分配されます。


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

29.10 ウィンドウのサイクル順

他のウィンドウを選択するためにコマンドC-x o (other-window)を使う際には、生きたウィンドウを特定の順番で巡回します。与えられた任意のウィンドウ構成にたいして、この順序は決して変更されません。これはウィンドウのサイクル順序(cyclic ordering of windows)と呼ばれます。

この順序は各フレームのリーフノードである生きたウィンドウを取得するために、ツリーを深さ優先で走査することにより決定されます(ウィンドウとフレームを参照)。ミニバッファーがアクティブならミニバッファーウィンドウも含まれます。この順序は巡回的(cyclic)なので、この順序の最後のウィンドウの次には最初のウィンドウが配置されます。

Function: next-window &optional window minibuf all-frames

この関数はウィンドウのサイクル順でwindowの次の生きたウィンドウをリターンする。windowは生きたウィンドウであること。省略またはnilの場合のデフォルトは選択されたウィンドウ。

オプション引数minibufはサイクル順にミニバッファーウィンドウを含めるべきかどうかを指定する。通常はminibufnilのときは、ミニバッファーウィンドウがカレントでアクティブな場合のみミニバッファーウィンドウが含まれる。これはC-x oの振る舞いと合致する(ミニバッファーが使用されている限りミニバッファーウィンドウはアクティブであることに注意。ミニバッファーを参照のこと)。

minibuftなら、サイクル順にはすべてのミニバッファーウィンドウが含まれる。minibuftnilのいずれとも異なる場合には、たとえアクティブであってもミニバッファーウィンドウは含まれない。

オプション引数all-framesは考慮にするフレームを指定する:

  • nilwindowのフレーム上にあるウィンドウを考慮することを意味する。(minibuf引数で指定されたことにより)ミニバッファーウィンドウが考慮される場合には、ミニバッファーウィンドウを共有するフレームも考慮される。
  • t はすべての既存フレーム上のウィンドウを考慮することを意味する。
  • visible はすべての可視フレーム上のウィンドウを考慮することを意味する。
  • 0 は可視またはアイコン化されたすべてのフレーム上のウィンドウを考慮することを意味する。
  • フレーム は指定されたフレーム上のウィンドウを考慮することを意味する。
  • その他 はwindowのあるフレーム上のウィンドウを考慮して、それ以外は考慮しないことを意味する。

複数のフレームが考慮される場合は、すべての生きたフレームのリストの順にしたがってそれらのフレームを順に追加することによりサイクル順を取得する(すべてのフレームを探すを参照)。

Function: previous-window &optional window minibuf all-frames

この関数はウィンドウのサイクル順においてwindowの前に位置する生きたウィンドウをリターンする。その他の引数はnext-windowの場合と同様に処理される。

Command: other-window count &optional all-frames

この関数はウィンドウのサイクル順において、選択されたウィンドウからcount番目に位置する生きたウィンドウをリターンする。countが正の数ならcount個のウィンドウを前方にスキップし、負の数なら-count個のウィンドウを後方にスキップする。countが0なら選択されたウィンドウを単に再選択する.インタラクティブに呼び出された場合には、countはプレフィックス数引数。

オプション引数all-framesは、nilminibuf引数を指定したときのnext-windowの場合と同じ意味をもつ。

この関数はignore-window-parametersnilなら非nilのウィンドウパラメーターno-other-windowをもつウィンドウを選択しない。

選択されたウィンドウのother-windowパラメーターが関数でignore-window-parametersnilなら、この関数の通常の処理のかわりに、other-windowパラメーターの関数が引数countall-framesで呼び出される。

Function: walk-windows fun &optional minibuf all-frames

この関数は生きたウィンドウそれぞれにたいしてウィンドウを引数に関数funを呼び出す。

これはウィンドウのサイクル順にしたがう。オプション引数minibufall-framesには、含まれるウィンドウセットを指定する。これらはnext-windowの引数の場合と同じ意味をもつ。all-framesがフレームを指定する場合には、最初に処理されるのはそのフレームの最初のウィンドウ(frame-first-windowがリターンするウィンドウ)であり、選択されたウィンドウである必要はない。

funがウィンドウの分割や削除によりウィンドウ構成を変更する場合でも、処理するウィンドウセットは初回のfun呼び出しに先立ち決定されるため変更されない。

Function: one-window-p &optional no-mini all-frames

この関数は選択されたウィンドウが唯一の生きたウィンドウならt、それ以外はnilをリターンする。

ミニバッファーウィンドウがアクティブなら、ミニバッファーウィンドウは通常は考慮される(そのためこの関数はnilをリターンする)。しかしオプション引数no-miniが非nilなら、たとえアクティブであってもミニバッファーウィンドウは無視される。オプション引数all-framesnext-windowの場合と同じ意味をもつ。

以下は何らかの条件を満足するウィンドウを、それらを選択することなくリターンする関数です:

Function: get-lru-window &optional all-frames dedicated not-selected no-other

この関数は発見的に最近もっとも使用されていない生きたウィンドウをリターンする。最近もっとも使用されていないウィンドウ(least recently used window)とは最近選択されたのがもっとも少ない、すなわち他のすべての生きたウィンドウより使用時間が少ないウィンドウのこと。オプション引数all-framesnext-windowの場合と同じ意味をもつ。

フル幅のウィンドウが存在する場合には、それらのウィンドウだけが考慮される。ミニバッファーが候補になることは決してない。オプション引数dedicatednilなら、専用バッファー(専用のウィンドウを参照)が候補になることは決してない。唯一の候補が選択されたウィンドウである場合以外は選択されたウィンドウを決してリターンしない。しかしオプション引数not-selectedが非nilなら、そのような場合でもこの関数はnilをリターンする。オプション引数no-otherが非nilなら、no-other-windowパラメーターが非nilのウィンドウをリターンすることは決してないことを意味する。

Function: get-mru-window &optional all-frames dedicated not-selected no-other

この関数はget-lru-windowと同様だが、かわりにもっとも最近使用されたウィンドウをリターンする。最近もっとも使用されたウィンドウ(most recently used window)とは最近選択されたのがもっとも多い、すなわち他のすべての生きたウィンドウより使用時間が多いウィンドウのこと。引数の意味はget-lru-windowと同様。

もっとも最近使用されたウィンドウは実際には常に選択されたウィンドウになるので、非nilnot-selected引数でこの関数を呼び出すことには通常は道理がある。

Function: get-largest-window &optional all-frames dedicated not-selected no-other

この関数はもっとも広い領域(高さ掛ける幅)のウィンドウをリターンする。同サイズの候補ウィンドウが2つある場合には、ウィンドウのサイクル順で選択されたウィンドウから数えて最初にあるウィンドウを優先する。引数の意味はget-lru-windowと同じ。

Function: get-window-with-predicate predicate &optional minibuf all-frames default

この関数はウィンドウのサイクル順内の各ウィンドウにたいして、そのウィンドウを引数として関数predicateを順に呼び出す。いずれかのウィンドウにたいしてpredicateが非nilをリターンすると、この関数は処理を停止してそのウィンドウをリターンする。そのようなウィンドウが見つからなければリターン値はdefault (これのデフォルトはnil)。

オプション引数 minibufall-framesは検索するウィンドウを指定する。意味はnext-windowの場合と同様。


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

29.11 バッファーとウィンドウ

このセクションではウィンドウのコンテンツを調べたりセットするための低レベルな関数を説明します。ウィンドウ内に特定のバッファーを表示するための高レベルな関数についてはウィンドウ内のバッファーへの切り替えを参照してください。

Function: window-buffer &optional window

この関数はwindowが表示しているバッファーをリターンする。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ。windowが内部ウィンドウならこの関数はnilをリターンする。

Function: set-window-buffer window buffer-or-name &optional keep-margins

この関数はwindowbuffer-or-nameを表示させる。windowは生きたウィンドウであること。nilの場合のデフォルトは選択されたウィンドウ。buffer-or-nameはバッファー、あるいは既存のバッファー名であること。この関数は選択されていたウィンドウを変更せず、カレントバッファーも直接変更しない(カレントバッファーを参照)。リターン値はnil

windowがあるバッファーにたいして特に専用(strongly dedicated)であり、かつbuffer-or-nameがそのバッファーを指定しなければ、この関数はエラーをシグナルする。専用のウィンドウを参照のこと。

デフォルトではこの関数は指定されたバッファーのローカル変数にもとづいてwindowの位置、ディスプレイマージン、フリンジ幅、スクロールバーのセッティングをリセットする。しかしオプション引数keep-marginsが非nilなら、windowのディスプレイマージンおよびフリンジとスクロールバーのセッティングは未変更のままにする。

アプリケーションを記述する際には直接set-window-bufferを呼び出すのではなく、通常はdisplay-buffer (バッファーを表示するウィンドウの選択を参照)やウィンドウ内のバッファーへの切り替えで説明する高レベルの関数を使用すること。

これはwindow-scroll-functionsの後にwindow-configuration-change-hookを実行する。ウィンドウのスクロールと変更のためのフックを参照のこと。

Variable: buffer-display-count

このバッファーローカル変数はウィンドウ内にバッファーが表示された回数を記録する。。これはそのバッファーにたいしてset-window-bufferが呼び出されるたびに増分される

Variable: buffer-display-time

このバッファーローカル変数はバッファーがウィンドウに最後に表示された時刻を記録する。バッファーが表示されたことがなければnilをリターンする。これはそのバッファーにたいしてset-window-bufferが呼び出されるたびにcurrent-timeがリターンする値により更新される(時刻を参照)。

Function: get-buffer-window &optional buffer-or-name all-frames

この関数はウィンドウのサイクル順内で選択されたウィンドウを起点に、buffer-or-nameを表示する最初のウィンドウをリターンする(ウィンドウのサイクル順を参照)。そのようなウィンドウが存在しなければリターン値はnil

buffer-or-nameはバッファーかバッファーの名前であること。省略またはnilの場合のデフォルトはカレントバッファー。オプション引数all-framesには考慮するウィンドウを指定する。

  • tはすべての既存フレーム上のウィンドウを考慮することを意味する。
  • visibleはすべての可視フレーム上のウィンドウを考慮することを意味する。
  • 0はすべての可視またはアイコン化されたフレーム上のウィンドウを考慮することを意味する。
  • フレームを指定すると、そのフレーム上のウィンドウだけを考慮することを意味する。
  • その他の値は選択されたフレーム上のウィンドウを考慮することを意味する。

これらの意味はnext-windowall-frames引数の場合とは若干異なることに注意(ウィンドウのサイクル順を参照)。この不一致の解消のためにEmacsの将来のバージョンにおいて、この関数は変更されるかもしれない。

Function: get-buffer-window-list &optional buffer-or-name minibuf all-frames

この関数はその時点でbuffer-or-nameを表示している、すべてのウィンドウのリストをリターンする。buffer-or-nameはバッファーまたは既存バッファーの名前であること。省略またはnilの場合のデフォルトはカレントバッファー。カレントで選択されたウィンドウがbuffer-or-nameを表示していれば、それはこの関数がリターンするリストの先頭となる。

引数minibufall-framesは、関数next-windowの場合と同じ意味をもつ(ウィンドウのサイクル順を参照)。all-frames引数は、get-buffer-windowの場合と正確に同じようには振る舞わないことに注意。

Command: replace-buffer-in-windows &optional buffer-or-name

このコマンドはbuffer-or-nameを表示しているすべてのウィンドウで、それを他の何らかのバッファーに置き換える。buffer-or-nameはバッファーまたは既存のバッファーの名前であること。省略またはnilの場合のデフォルトはカレントバッファー。

各ウィンドウで置き換えられるバッファーはswitch-to-prev-bufferを通じて選択される(ウィンドウのヒストリーを参照)。サイドウィンドウ(サイドウィンドウを参照)を除き、buffer-or-nameを表示している専用ウィンドウは可能ならすべて削除される(専用のウィンドウを参照)。そのようなウィンドウがそのフレームで唯一のウィンドウで、かつ同一端末上に他のフレームが存在する場合には、そのフレームも同様に削除される。その端末上の唯一のフレームの唯一のウィンドウの場合は、いずれにせよそのバッファーは置き換えられる。


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

29.12 ウィンドウ内のバッファーへの切り替え

このセクションでは、あるウィンドウ内で特定のバッファーにスイッチするための高レベルな関数について説明します。“バッファーをスイッチする”とは一般的に、(1)そのバッファーをあるウィンドウに表示して、(2)そのウィンドウを選択されたウィンドウとし(かつそのフレームを選択されたフレームとし)、(3)そのバッファーウィンドウカレントバッファーにすることを意味します。

Lispプログラムがアクセスや変更できるように、バッファーを一時的にカレントにするためにこれらの関数を使用しないでください。これらはウィンドウヒストリー(ウィンドウのヒストリーを参照)の変更のような副作用をもつので、そのような方法での使用はユーザーを驚かせることになるでしょう。バッファーをLispで変更するためにカレントにしたければwith-current-buffersave-current-bufferset-bufferを使用してください。カレントバッファーを参照してください。

Command: switch-to-buffer buffer-or-name &optional norecord force-same-window

このコマンドは選択されたウィンドウ内でbuffer-or-nameを表示して、それをカレントバッファーにしようと試みる。これはよくインタラクティブ(C-x bのバインディングで)に使用され、同様にLispプログラムでも使用される。リターン値はスイッチしたバッファー。

buffer-or-namenilの場合のデフォルトはother-bufferによりリターンされるバッファー(バッファーリストを参照)。buffer-or-nameが既存のバッファーの名前でない文字列なら、この関数はその名前で新たにバッファーを作成する。新たなバッファーのメジャーモードは変数major-modeにより決定される(メジャーモードを参照)。

通常は指定されたバッファーはバッファーリスト — グローバルバッファーリストと選択されたフレームのバッファーリストの両方の先頭に置かれる(バッファーリストを参照)。しかしオプション引数norecordが非nilなら、これは行われない。

選択されたウィンドウにそのバッファーを表示することが不適切なこともあるだろう。これは選択されたウィンドウがミニバッファーウィンドウの場合、および選択されたウィンドウがそのバッファーに特に専用(専用のウィンドウを参照)な場合に発生する。そのようなケースでは、このコマンドはpop-to-buffer (以下参照)を呼び出すことにより、通常は別のウィンドウにバッファーの表示を試みる。

オプション引数force-same-windowが非nil、かつ選択されたウィンドウがそのバッファーの表示に不適切なら、非インタラクティブに呼び出された際にはこの関数は常にエラーをシグナルする。インタクラクティブな使用においては、もし選択されたウィンドウがミニバッファーウィンドウなら、この関数はかわりに別のウィンドウの使用を試みる。選択されたウィンドウがそのバッファーにたいして特に専用なら、次に説明するオプションswitch-to-buffer-in-dedicated-windowが使用される。

User Option: switch-to-buffer-in-dedicated-window

このオプションが非nilなら、switch-to-bufferがインタラクティブに呼び出されて、かつ選択されたウィンドウがそのバッファーに特に専用な際に、処理を先に進めることが許される、

以下の値が許される:

nil

切り替えを許さず非インタラクティブな使用ではエラーをシグナルする。

prompt

切り替えを許すかどうかユーザーに確認を求める。

pop

処理を行うためにpop-to-bufferを呼び出す。

t

選択されたウィンドウを非専用としてマークして処理を進める。

このオプションは非インタラクティブなswitch-to-bufferの呼び出しには影響しない。

デフォルトではswitch-to-bufferはバッファーのpoint位置の維持を試みます。この振る舞いは以下のオプションを使用して調整できます。

User Option: switch-to-buffer-preserve-window-point

この変数がnilなら、switch-to-bufferbuffer-or-nameにより指定されたバッファーを、そのバッファーのpoint位置で表示する。この変数がalready-displayedなら、そのバッファーが任意の可視またはアイコン化されたフレーム上の他のウィンドウで表示されていれば、選択されたウィンドウ内の以前の位置でバッファーの表示を試みる。この変数がtなら、switch-to-bufferは選択されたウィンドウ内の以前の位置でそのバッファーを表示しようと試みる。

この変数はバッファーがすでに選択されたウィンドウに表示されている、これまで表示されたことがない、またはバッファーを表示するためにswitch-to-bufferpop-to-bufferを呼び出した場合には無視される。

User Option: switch-to-buffer-obey-display-actions

この変数が非nilならswitch-to-bufferdisplay-buffer-overriding-actiondisplay-buffer-alist、およびその他の表示に関係する変数で指定されるディスプレイアクションにしたがいます。

以下の2つのコマンドは、説明している機能以外はswitch-to-bufferと類似しています。

Command: switch-to-buffer-other-window buffer-or-name &optional norecord

この関数はbuffer-or-nameで指定されたバッファーを、選択されたウィンドウ以外の別のウィンドウに表示する。これは関数pop-to-buffer(以下参照)を内部で使用する。

選択されたウィンドウが指定されたバッファーをすでに表示していれば表示を続けるが、見つかった他のウィンドウも同様にそのバッファーを表示する。

引数buffer-or-namenorecordswitch-to-bufferの場合と同じ意味をもつ。

Command: switch-to-buffer-other-frame buffer-or-name &optional norecord

この関数はbuffer-or-nameで指定されたバッファーを新たなフレームに表示する。これは関数pop-to-buffer (以下参照)を内部で使用する。

指定されたバッファーがすでにカレント端末上の任意のフレームの他のウィンドウに表示されている場合には、フレームを新たに作成せずにそのウィンドウに切り替える。しかしこれを行うために選択されたウィンドウを使用することは決してない。

引数buffer-or-namenorecordswitch-to-bufferの場合と同じ意味をもつ。

上述したコマンドは任意のウィンドウにバッファーを柔軟に表示して、編集用にそのウィンドウを選択する関数pop-to-bufferを使用しています。次にpop-to-bufferはバッファーの表示にdisplay-bufferを使用します。したがってdisplay-bufferに影響する変数も同様に影響します。display-bufferのドキュメントについてはバッファーを表示するウィンドウの選択を参照してください。

Command: pop-to-buffer buffer-or-name &optional action norecord

この関数はbuffer-or-nameをカレントバッファーにして、なるべく選択されたウィンドウではないウィンドウにそれを表示する。そしてその後に表示しているウィンドウを選択する。そのウィンドウが別のグラフィカルなフレーム上にある場合には、可能ならそのフレームが入力フォーカスを与えられる(入力のフォーカスを参照)。

buffer-or-namenilの場合のデフォルトはother-bufferによりリターンされるバッファー(バッファーリストを参照)。buffer-or-nameが既存のバッファーの名前でない文字列なら、この関数はその名前で新たにバッファーを作成する。新たなバッファーのメジャーモードは変数major-modeにより決定される(メジャーモードを参照)。バッファーの表示に適したウィンドウが存在しなくても、すべてのケースにおいてそのバッファーがカレントになりリターンされる。

actionが非nilなら、それはdisplay-bufferに渡すディスプレイアクション(display action)であること(バッファーを表示するウィンドウの選択を参照)。非nilか非リスト値なら、たとえそのバッファーがすでに選択されたウィンドウに表示されていたとしても、選択されたウィンドウではなく別のウィンドウをポップ(pop)することを意味する。

この関数はswitch-to-bufferと同じように、norecordnilならバッファーリストを更新する。


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

29.13 適切なウィンドウへのバッファーの表示

このセクションでは特定のバッファーの表示にたいしてEmacsが検索や作成に使用する低レベルの関数を説明します。これらの関数の共通点は、受け取ったすべてのバッファー表示要求を最終的に処理するdisplay-buffer (バッファーを表示するウィンドウの選択を参照)を主に用いるという点です。

display-bufferは適切なウィンドウを見つけるタスクを、いわゆるアクション関数に委譲します(バッファー表示用のアクション関数を参照)。まずdisplay-bufferは、いわゆるアクションalist (アクション関数が振る舞いを微調整するために使用可能な連想リスト)をコンパイルします。それから呼び出す関数それぞれにたいして、そのalistを渡します(バッファー表示用のアクションalistを参照)。

display-bufferの動作は高度にカスタマイズ可能です。実際にカスタマイゼーションが使用される方法を理解するためには、display-bufferがアクション関数を呼び出す際に使用する優先順を示す例を学びたいと思うかもしれません(アクション関数の優先順を参照)。display-bufferを呼び出すLispプログラムや、display-bufferの動作にたいするユーザーのカスタマイズとの間の競合を避けるためには、このセクションの最後に示すいくつかのガイドラインにしたがうのが合理的かもしれません(バッファー表示の思想を参照)。


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

29.13.1 バッファーを表示するウィンドウの選択

コマンドdisplay-bufferは表示のために柔軟にウィンドウを選択して、そのウィンドウ内に指定されたバッファーを表示します。これはキーバインディングC-x 4 C-oを通じてインタラクティブに呼び出すことができます。またswitch-to-bufferpop-to-bufferを含む多くの関数やコマンドにからサブルーチンとしても使用されます(ウィンドウ内のバッファーへの切り替えを参照)。

このコマンドは表示するウィンドウを探すために、いくつかの複雑なステップを実行します。これらのステップはディスプレイアクション(display actions)を用いて記述されます。ディスプレイアクションは(functions . alist)という形式をもちます。ここでfunctionsは“アクション関数”と呼ばれる単一の関数か関数のリスト(バッファー表示用のアクション関数を参照)、alistは“アクションalist”と呼ばれる連想リストです(バッファー表示用のアクションalistを参照)。ディスプレイアクションの例についてはバッファー表示の思想を参照してください。

アクション関数は、表示するバッファーと、アクションalistという、2つの引数を受け取ります。これは、自身の条件にしたがってウィンドウを選択、または作成して、バッファーをウィンドウ内に表示します。成功した場合はそのウィンドウ、それ以外はnilをリターンします。

display-bufferは複数ソースからのディスプレイアクションを組み合わせて、アクション関数のいずれか1つがバッファーの表示を管理して非nil値をリターンするまでアクション関数を順に呼び出します。

Command: display-buffer buffer-or-name &optional action frame

このコマンドは、ウィンドウを選択したり、そのバッファーをカレントにすることなく、buffer-or-nameをウィンドウに表示させる。引数buffer-or-nameはバッファー、または既存のバッファーの名前でなければならない。リターン値はバッファーを表示するために選ばれたウィンドウ、適切なウィンドウが見つからなければnil

オプション引数actionが非nilなら、それは通常はディスプレイアクション(上述)であること。display-bufferは以下のソース(優先度の高位順)からディスプレイアクションを集約してアクション関数リストとアクションalistを構築する:

  • 変数display-buffer-overriding-action
  • ユーザーオプションdisplay-buffer-alist
  • action引数。
  • ユーザーオプションdisplay-buffer-base-action
  • 定数display-buffer-fallback-action

これはこれらのディプレイアクションにより指定されるアクション関数すべてのリストを、実際にはdisplay-bufferが構築することを意味する。このリストの最初の要素は(もしあれば) display-buffer-overriding-actionが指定する最初のアクション関数、最後の要素はdisplay-buffer-pop-up-frame (display-buffer-fallback-actionが指定する最後のアクション関数)。このリストから重複要素は削除されないので、1回のdisplay-buffer呼び出しの間に同一のアクション関数が複数回呼び出されるかもしれない。

display-bufferはバッファーを1つ目の引数、組み合わされたalistを2つ目の引数として、いずれかの関数が非nilをリターンするまで、このリスト内で指定されたアクション関数を順に呼び出す。異なるソースから指定されたディスプレイアクションをdisplay-bufferがどのように処理するかの例はアクション関数の優先順を参照のこと。

2つ目の引数は常に、上記に挙げたソースが指定するすべてのアクションalistエントリーのリストであることに注意。したがってこのリストの最初の要素は(もしあれば) display-buffer-overriding-actionが指定する最初のアクションalistエントリー、最後の要素はもしあれば display-buffer-base-actionの最後のalistエントリーとなる(display-buffer-fallback-actionのアクションalistが空の場合)。

組み合わされたアクションalistは重複したエントリーを含むかもしれず、同じキーのエントリーが異なる値をもつかもしれないことにも注意。アクション関数はルールとして見つかった最初のキーの連想値を常に使用する。したがってアクション関数が使用する連想値が、そのアクション関数に指定されたディスプレイアクションが提供する連想値である必要はない。

引数actionにはリストではない非nil値も指定できる。これはたとえ選択されたウィンドウがすでにそのバッファーを表示していても、選択されたウィンドウではない別のウィンドウにバッファーが表示されるべきという特別な意味をもつ。プレフィックス引数とともにインタラクティブに呼び出された場合には、actiontである。Lispプログラムは値として常にリストを提供すること。

オプション引数frameが非nilの場合は、そのバッファーがすでに表示されているか判断する際、どのフレームをチェックするかを指定する。これはactionのアクションalistに要素(reusable-frames . frame)を追加するのと等価(バッファー表示用のアクションalistを参照)。frameは互換性のために提供される引数であり、Lispプログラムは使用するべきではない。

Variable: display-buffer-overriding-action

この変数の値はdisplay-bufferにより最高の優先順で扱われるディスプレイアクションであること。デフォルト値は空のディスプレイアクション(つまり(nil . nil))。

User Option: display-buffer-alist

このオプションの値はディスプレイアクションにコンディション(condition: 状態)をマップするalist。各コンディションはバッファー名、display-bufferに渡されたaction引数とともにbuffer-match-pに渡される。これが非nil値をリターンしたら、display-bufferは対応するディスプレイアクションをそのバッファーの表示に使用する。

User Option: display-buffer-base-action

このオプションの値はディスプレイアクションであること。このオプションはdisplay-buffer呼び出しにたいする標準のディスプレイアクションを定義するために使用できる。

Constant: display-buffer-fallback-action

このディスプレイアクションはdisplay-bufferにたいして、他のディスプレイアクションが与えられなかった場合の代替え処理を指定する。


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

29.13.2 バッファー表示用のアクション関数

アクション関数(action function)とはバッファーを表示するウィンドウを選択するためにdisplay-bufferが呼び出す関数です。アクション関数はbuffer (表示するバッファー)、およびalist (アクションalist、バッファー表示用のアクションalistを参照)という2つの引数を受け取ります。これらの関数は成功時にはbufferを表示するウィンドウ、失敗時にはnilをリターンします。

以下の基本的なアクション関数がEmacsで定義されています。

Function: display-buffer-same-window buffer alist

この関数は選択されたウィンドウ内にbufferの表示を試みる。選択されたウィンドウがミニバッファーウィンドウや他のバッファー専用(専用のウィンドウを参照)の場合には失敗する。alistに非nilinhibit-same-windowエントリーがある場合にも失敗する。

Function: display-buffer-reuse-window buffer alist

この関数はすでにbufferを表示しているウィンドウを探すことによりバッファーの表示を試みる。選択されたフレーム上のウィンドウは別フレーム上のウィンドウより優先される。

alistに非nilinhibit-same-windowエントリーがある場合には、選択されたウィンドウは再利用に適さない。bufferをすでに表示しているウィンドウを検索するフレームセットは、アクションalistのreusable-framesエントリーで指定できる。alistreusable-framesエントリーが含まれる場合には、この関数は選択されたフレームだけを検索する。

この関数が他のフレーム上のウィンドウを選択した場合には、そのフレームを可視にするとともに、alistinhibit-switch-frameエントリーを含んでいなければ、必要ならそのフレームを最前面に移動(raise)する。

Function: display-buffer-reuse-mode-window buffer alist

この関数は与えられたモードですでにbufferを表示しているウィンドウを探すことによりバッファーの表示を試みる。

alistmodeエントリーを含んでいれば、その値がメジャーモード(シンボル)、またはメジャーモードのリストを指定する。alistmodeエントリーが含まれていなければ、かわりにbufferのカレントのメジャーモードが使用される。このように指定されたモードのいずれかから継承されたモードでバッファーを表示しているウィンドウは候補となる。

display-buffer-reuse-windowのように関数の挙動はinhibit-same-windowreusable-framesinhibit-switch-frameにたいするalistエントリーによっても制御される。

Function: display-buffer-pop-up-window buffer alist

この関数は、最大もしくはもっとも長い間参照されていないウィンドウ(通常は選択されたフレームに配置されている)を分割することによりbufferの表示を試みる。これは実際には、split-window-preferred-function (バッファー表示の追加オプションを参照)内で指定された関数を呼び出すことにより分割を行う。

新たなウィンドウのサイズはalistにエントリーwindow-heightwindow-widthを与えることにより調整できる。alistpreserve-sizeエントリーが含まれていれば、Emacsは将来のリサイズ操作の間に新たなウィンドウのサイズの維持も試みる(ウィンドウサイズの保持を参照)。

この関数は分割可能なウィンドウがなければ失敗する。これの多くは、分割を許容するのに十分大きいウィンドウがない場合に発生する。この問題にたいしてはsplit-height-thresholdsplit-width-thresholdに小さい値をセットすることが助けになるかもしれない。選択されたフレームがフレームパラメーターunsplittableをもつ場合にも分割は失敗する。バッファーのパラメーターを参照のこと。

Function: display-buffer-in-previous-window buffer alist

この関数はbufferを以前に表示したウィンドウにbufferの表示を試みる。

alistに非nilinhibit-same-windowエントリーが含まれる場合には、選択されたウィンドウは使用に適さない。専用ウィンドウ(dedicated window)は、すでにbufferを表示済みの場合のみ使用可能。alistprevious-windowエントリーが含まれる場合には、そのエントリーで指定されるウィンドウが以前にbufferを表示したことがなくても、そのウィンドウが使用される。

alistreusable-framesエントリー(バッファー表示用のアクションalistを参照)が含まれる場合には、その値が適切なウィンドウを検索するフレームを決定する。この関数はalistreusable-framesエントリーが含まれず、display-buffer-reuse-framespop-up-framesがいずれもnilなら選択されたフレームのみ、いずれかが非nilならカレント端末上のすべてのフレームを検索する。

これらのルールに照らして1つ以上のウィンドウが使用に適している場合には、この関数は以下の優先順にしたがって選択を行う:

  • alistprevious-windowエントリーで指定されるウィンドウが選択されたウィンドウでなければそのウィンドウ。
  • 以前にbufferを表示していたウィンドウが選択されたウィンドウでなければそのウィンドウ。
  • alistprevious-windowエントリーで指定されているか、あるいは以前にbufferを表示していれば選択されたウィンドウ。
Function: display-buffer-use-some-window buffer alist

この関数は既存のウィンドウを選んでそのウィンドウにバッファーを表示することによってbufferの表示を試みる。まずalistlru-framesエントリーによって指定されたすべてのフレームにおいて最近使用されていないウィンドウ(ウィンドウのサイクル順を参照)を探す(そのようなエントリーが存在しなければ選択されたウィンドウにフォールバック)。alistwindow-min-widthエントリーとwindow-min-heightエントリーに指定された制約を満足するようなウィンドウも優先される(window-min-widthエントリーがなければfull-widthのウィンドウを優先)。最後にalistlru-timeエントリーで指定された値より長い使用時間のウィンドウは除外する。

最近使用されていないウィンドウが見つからなければ、この関数は別のウィンドウ(可視なフレーム上のなるべく大きいウィンドウを優先)の使用を試みる。ウィンドウがすべて別のバッファー専用(専用のウィンドウを参照)の場合には失敗するかもしれない。

Function: display-buffer-use-least-recent-window buffer alist

この関数はdisplay-buffer-use-some-windowと似ているが、より厳格に最近使用されたウィンドウを使用しないよう試みる。特に選択されたウィンドウを使用することはない。更に加えてまず既にbufferを表示しているウィンドウの再利用を試み、次に別のバッファーを表示しているウィンドウの使用時間だけにもとづいてそのウィンドウを使用すべきかどうかを判断、それでも利用可能なウィンドウが見つからなければ新たなウィンドウをポップアップする。

最後にこの関数は以降の呼び出しでそのウィンドウに別のバッファーを表示することを避けるために、リターンするウィンドウの使用時間(ウィンドウの選択を参照)を増加させる。この関数を使って複数のバッファーを順に表示したいアプリケーションは、alistlru-timeに初期値として選択されたウィンドウの使用時間をセットして提供することによって、この関数を支援することができる。この関数は呼び出されるごとにリターンするウィンドウの使用時間をより長い使用時間に増加することによって、以降の呼び出しでは以前にリターンしたウィンドウの使用を回避する。

Function: display-buffer-in-direction buffer alist

この関数はalistで指定した位置でbufferの表示を試みる。この目的のために、alistには値がleftabove (かup)、rightbelow (かdown)のいずれかであるようなdirectionエントリーを含めること。それ以外の値は通常はbelowと解釈される。

alistwindowエントリーも含まれている場合には、その値は参照ウィンドウ(reference window)を指定する。値には選択されたフレームのメインウィンドウ(サイドウィンドウのオプションと関数を参照)を意味するmain、選択されたフレームのルートウィンドウ(ウィンドウとフレームを参照)を意味するrootのような特別なシンボルを指定できる。任意の有効なウィンドウの指定も可能。それ以外の値(またはwindowエントリーを完全に省略)は参照ウィンドウとして選択されたウィンドウを使用することを意味する。

この関数は、指定方向ですでにbufferを表示しているウィンドウの再利用を試みる。そのようなウィンドウが存在しなければ、指定方向に新たなウィンドウを生成するために参照ウィンドウの分割を試みる。これも同様に失敗したら指定方向にある既存ウィンドウにbufferの表示を試みる。いずれの場合でもdirectionエントリーで指定された参照ウィンドウ側に、少なくとも1辺を参照ウィンドウと共有したウィンドウが選ばれることになる。

参照ウィンドウが生きたウィンドウなら、選択されるウィンドウのエッジはdirectionエントリーで指定された方向と反対側が共有される。たとえばdirectionエントリーの値がleftなら、選択されるウィンドウの右エッジ座標は、参照ウィンドウの左エッジ座標と等しくなる(座標とウィンドウを参照)。

参照ウィンドウが内部ウィンドウなら、再利用されるウィンドウはdirectionエントリーで指定されるエッジが共有されなければならない。したがって、たとえば参照ウィンドウがフレームのルートウィンドウ、directionエントリーの値がleftなら、再利用されるウィンドウはフレームの左側でなければならない。これは選択されるウィンドウと参照ウィンドウの左エッジ座標が等しいことを意味する。

しかし新たなウィンドウは選択したウィンドウが参照ウィンドウの反対側エッジを共有するように参照ウィンドウを分割して作成される。上記の例では参照ウィンドウを子ウィンドウとして、新たな生きたウィンドウと共にルートウィンドウが新たに作成される。選択されたウィンドウの右エッジ座標は、参照ウィンドウの左エッジ座標、左エッジ座標はフレームのルートウィンドウの左エッジ座標と等しくなる。

directionエントリーにたいする特別な4つの値leftmosttoprightmostbottomでは参照ウィンドウとして選択されたフレームのメインウィンドウを暗黙に指定できる。これはたとえば(direction . left)  (window . main)のかわりに、単に(direction . leftmost)と指定することができることを意味する。このような場合ではalistの既存のwindowエントリーは無視される。

Function: display-buffer-below-selected buffer alist

この関数は選択されたウィンドウの下のウィンドウ内にbufferの表示を試みる。選択されたウィンドウの下にすでにそのバッファーを表示するウィンドウがあれば、そのウィンドウを再利用する。

そのようなウィンドウが存在しなければ、この関数は選択されたウィンドウを分割することにより新たなウィンドウを作成してbufferの表示を試みる。alistに適切なwindow-heightwindow-widthのエントリーが含まれていれば、ウィンドウのサイズ調整も試みる(上記参照)。

選択されたウィンドウの分割に失敗、かつ選択されたウィンドウの下に別のバッファーを表示中の非専用ウィンドウがある場合には、この関数はbufferの表示にそのウィンドウの使用を試みる。

alistwindow-min-heightエントリーが含まれていると、この関数は少なくとも使用するウィンドウの高さがこのエントリーで指定された値になることを保証する。これは単なる保証であることに注意。使用するウィンドウを実際にリサイズするためには、alistで適切なwindow-heightエントリーも提供しなければならない。

Function: display-buffer-at-bottom buffer alist

この関数は選択されたフレームの最下にあるウィンドウ内にbufferの表示を試みる。

これはフレーム最下のウィンドウまたはフレームのルートウィンドウを分割、または選択されたフレーム最下の既存ウィンドウを試みる。

Function: display-buffer-pop-up-frame buffer alist

この関数は新たにフレームを作成して、そのフレームのウィンドウ内にバッファーを表示する。これは実際にはpop-up-frame-function (バッファー表示の追加オプションを参照)内で指定された関数を呼び出すことによりフレーム作成の処理を行う。alistpop-up-frame-parametersエントリーを含む場合には、その連想値(associated value)が新たに作成されたフレームのパラメーターに追加される。

Function: display-buffer-full-frame buffer alist

この関数はカレントフレームの他のウィンドウをすべて削除して、フレーム全体を占めるようにバッファーを表示する。

Function: display-buffer-in-child-frame buffer alist

この関数は選択されたフレームの既存の子フレーム、または子フレームを新たに作成してbufferの表示を試みる(子フレームを参照)。alistに非nilchild-frame-parametersエントリーがあれば、対応する値が新たなフレームのフレームパラメーターのalistとして与えられる。デフォルトとして選択されたフレームを指定するparent-frameパラメーターが提供される。その子フレームが別のフレームの子になる場合には、対応するエントリーをalistに追加しなければならない。

子フレームの外観はalistを通じて提供されるパラメーターに大きく依存する。子フレームが可視のままでいることを保証するために、少なくとも子フレームのサイズ(サイズのパラメーターを参照)と位置(位置のパラメーターを参照)を指定して比率(ratio)を使用すること、およびkeep-ratioパラメーター(フレームとの相互作用のためのパラメーターを参照)の追加を推奨する。他に考慮すべきパラメーターについては子フレームを参照のこと。

Function: display-buffer-use-some-frame buffer alist

この関数は述語を満足するフレーム(デフォルトは選択されたフレーム以外のフレーム)を探してbufferの表示を試みる。

この関数が他のフレーム上のウィンドウを選択した場合には、そのフレームを可視にするとともに、alistinhibit-switch-frameエントリーを含んでいなければ、必要ならそのフレームを最前面に移動(raise)する。

alistに非nilframe-predicateエントリーがあれば、その値は1つの引数(フレーム)を受け取ってそのフレームが候補なら非nilをリターンする、デフォルトの述語を置き換える関数。

alistに非nilinhibit-same-windowエントリーがある場合には選択されたウィンドウは使用しない。したがって選択されたフレームに単一のウィンドウしかなければ使用しない。

Function: display-buffer-no-window buffer alist

この関数はalistに非nilallow-no-windowエントリーがあればbufferを表示せずにシンボルfailをリターンする。この構成はアクション関数がnilbufferを表示するウィンドウをリターンするという慣習の唯一の例外である。alistにそのようなallow-no-windowエントリーがなければ、この関数はnilをリターンする。

この関数がfailをリターンした場合には、display-bufferはそれ以上のディスプレイアクションをスキップして即座にnilをリターンする。この関数がnilをリターンした場合には、display-bufferはもしあれば次のディスプレイアクションを継続する。

display-bufferの呼び出し側が非nilallow-no-windowエントリーを指定した場合には、nilのリターン値の処理も可能とみなされる。

他の2つのアクション関数display-buffer-in-side-windowdisplay-buffer-in-atom-windowについては、それぞれ適正なセクションで説明します(サイドウィンドウへのバッファーの表示アトミックウィンドウを参照)。


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

29.13.3 バッファー表示用のアクションalist

アクションalist(action alist)とはアクション関数が認識可能な事前定義されたシンボルと、それに応じてそれらの関数が解釈することを意図した値をマップする連想リストです。各呼び出しにおいてdisplay-bufferは新たなアクションalist(空の場合もある)を作成して、呼び出すすべてのアクション関数にそのリスト全体を渡します。

仕様によりアクション関数はアクションalist全体を自由に解釈できます。実際のところallow-no-windowprevious-windowのようないくつかのエントリーはいくつかのアクション関数にとってのみ意味があり、他のアクション関数では無視されます。それ以外のinhibit-same-windowwindow-parametersのようなエントリーは、アプシケーションプログラムや外部パッケージから提供されるものも含めて、ほとんどのアクション関数がしたがいます。

前のサブセクションでは、個別のアクション関数がアクションエントリーを処理する方法の詳細を説明しました。ここでは既知のアクションalistエントリーに対応するすべてのシンボル、およびそれらの値とそれらを認識するアクション関数(バッファー表示用のアクション関数を参照)とともに示すリファレンスリストを提供します。このリストにおいて用語“バッファー”はdisplay-bufferが表示しようとするバッファー、“値”はそのエントリーの値を意味しています。

inhibit-same-window

値が非nilなら、バッファーの表示に選択されたウィンドウを使用してはならないことを告げる。既存のウィンドウを(再)使用するすべてのアクション関数は、このエントリーにしたがう必要がある。

previous-window

値には以前にバッファーを表示した可能性のあるウィンドウを指定しなければならない。そのようなウィンドウがまだ生きていて他のバッファー専用でなれば、display-buffer-in-previous-windowはそのウィンドウを優先する。

mode

値はメジャーモードかメジャーモードのリスト。このエントリーが指定する値がウィンドウのバッファーのメジャーモードにマッチすれば、display-buffer-reuse-mode-windowは常にそのウィンドウを再利用する。これ以外のアクション関数はこのエントリーを無視する。

frame-predicate

値はそのフレームがバッファーを表示する候補なら非nilをリターンする単一の引数(フレーム)を受け取る関数でなければならない。このエントリーはdisplay-buffer-use-some-frameが使用する。

reusable-frames

値はバッファーをすでに表示していたことにより再利用可能なウィンドウを検索するためのフレームセットを指定する。以下をセット可能:

  • nilは選択されたフレーム(実際にはミニバッファーフレーム以外の最後に使用されたフレーム)上のウィンドウだけを考慮することを意味する。
  • visibleはすべての可視フレーム上のウィンドウを考慮することを意味する。
  • 0はすべての可視またはアイコン化されたフレーム上のウィンドウを考慮することを意味する。
  • フレームを指定すると、そのフレーム上のウィンドウだけを考慮することを意味する。
  • tはすべてのフレームのウィンドウを考慮することを意味する(ツールチップフレームがリターンされるかもしれないので、この値が使用に耐えることは稀であることに注意)。

nilの意味はnext-windowにたいするall-frames引数の場合の意味とは若干異なることに注意(ウィンドウのサイクル順を参照)。

これの主要クライアントはdisplay-buffer-reuse-windowだが、ウィンドウの再利用を試みる他のすべてのアクション関数も同様に影響を受ける。display-buffer-in-previous-windowはバッファーを以前に表示していたウィンドウを別フレーム上で検索する際にこれを参照する。

inhibit-switch-frame

nil値の場合には、display-bufferにより選択されたウィンドウがすでに表示されていれば別のフレームのraiseや選択を抑制する。これにより主に影響を受けるのはdisplay-buffer-use-some-framedisplay-buffer-reuse-window。理想的にはdisplay-buffer-pop-up-frameも同様に影響を受けるべきだが、ウィンドウマネージャーがこれに準拠する保証はない。

window-parameters

値は選択したウィンドウに与えるウィンドウパラメーターのalist。ウィンドウを選択するすべてのアクション関数は、このエントリーを処理する必要がある。

window-min-width

値は使用するウィンドウの最小幅をフレームの正準列で指定する。特別な値full-widthは、そのフレームにおいて左右に他のウィンドウがないウィンドウを選択することを意味する。

このエントリーに影響を受けるのは現在のところdisplay-buffer-use-some-window、およびdisplay-buffer-use-least-recent-window (最近使用されていないウィンドウのリターンにおいてこのエントリーを満足しないようなウィンドウのリターンをより厳格に回避する)。

このようなエントリーを単独で提供しても、ウィンドウがその値で指定した幅になるとは限らないことに注意。既存ウィンドウを実際にリサイズしたり新たなウィンドウの幅を指定した値にするためには、同様にこの値を指定するwindow-widthエントリーを提供する必要がある。しかしこのようなwindow-widthエントリーでまったく異なる値を指定したり、ウィンドウ幅をバッファーにフィットするように要請することができる。そのような場合にはwindow-width使用するウィンドウの最小幅にたいする保証を与える。

window-min-height

値は使用するウィンドウの最小高さをフレームの正準行で指定する。特別な値full-heightは、そのフレームにおいて上下に他のウィンドウがないウィンドウを選択することを意味する。

このエントリーは現在のところdisplay-buffer-below-selected (このエントリーで指定された高さより低いウィンドウは使用しない)に影響を与える。更にdisplay-buffer-use-some-window、およびdisplay-buffer-use-least-recent-window (最近使用されていないウィンドウのリターンにおいてこの制約を満足しないようなウィンドウのリターンをより厳格に回避する)にも影響を与える。

このようなエントリーを単独で提供しても、ウィンドウがその値で指定した高さになるとは限らないことに注意。既存ウィンドウを実際にリサイズしたり新たなウィンドウの高さを指定した値にするためには、同様にこの値を指定するwindow-heightエントリーを提供する必要がある。しかしこのようなwindow-heightエントリーでまったく異なる値を指定したり、ウィンドウ高さをバッファーにフィットするように要請することができる。そのような場合にはwindow-min-height使用するウィンドウの最小高さにたいする保証を与える。

window-height

値は選択したウィンドウの高さを調節するかとその方法を指定する。以下のいずれか:

  • nilは選択したウィンドウの高さを変更しないことを意味する。
  • 整数値は選択したウィンドウの望ましい高さを行数で指定する。
  • 浮動小数点値は選択したウィンドウの望ましい高さをフレームのルートウィンドウのトータル高さにたいする比率で指定する。
  • CARbody-linesCDRが選択されたウィンドウのボディー高さをフレーム行数で指定する整数であるようなコンスセル。
  • 値が関数を指定する場合には、その関数は選択したウィンドウを引数として呼び出される関数。この関数はそのウィンドウの高さを調整することを期待されておりリターン値は無視される。これに適した関数はfit-window-to-buffershrink-window-if-larger-than-bufferウィンドウのリサイズを参照のこと。

慣例により選択したウィンドウの高さは、そのウィンドウが垂直コンビネーション(ウィンドウとフレームを参照)の一部であり、他の無関係のウィンドウの高さの変更を避ける場合のみ調整される。さらにこのエントリーはこのリストの後に指定する特定の条件下でのみ処理される必要がある。

window-width

これは上述のwindow-heightと同様だが、かわりに選択したウィンドウの幅の調節に使用される。値は以下のいずれか:

  • nilは選択したウィンドウの幅を変更しないことを意味する。
  • 整数値は選択したウィンドウの望ましい幅を列数で指定する。
  • 浮動小数点値は選択したウィンドウの望ましい幅をフレームのルートウィンドウのトータル幅にたいする比率で指定する。
  • CARbody-columnsCDRが選択されたウィンドウのボディー幅をフレーム列数で指定する整数であるようなコンスセル。
  • 値が関数を指定する場合には、その関数は選択したウィンドウを引数として呼び出される関数。この関数はそのウィンドウの高さを調整することを期待されておりリターン値は無視される。
window-size

これは前の2つを組み合わせたエントリーであり、選択したウィンドウの高さと幅の両方の調節に用いることができる。他のウィンドウに影響を与えずにウィンドウをリサイズできる方向は1つだけなので、window-sizeはフレーム上に単独で表示されるウィンドウのサイズのセットアップでのみ効果的である。値は以下のいずれか:

  • nilは選択したウィンドウのサイズを変更しないことを意味する。
  • 選択されるウィンドウに求めるトータル高さの行数とトータル幅の列数を指定する、2つの整数からなるコンスセル。これに応じてフレームサイズを調整する効果がある。
  • CARbody-charsCDRが2つの整数からなるコンスセル(選択したウィンドウの望ましい幅と高さをフレームの行数と列数で指定)であるようなコンスセル。これに応じてフレームのサイズを調節する効果がある。
  • 値が関数を指定する場合には、その関数は選択したウィンドウを引数として呼び出される関数。この関数はそのウィンドウのフレームのサイズを調整することを期待されておりリターン値は無視される。

このエントリーはこのリストのすぐ下で指定されている特定の条件の下で処理される必要がある。

dedicated

このようなエントリーが非nilなら、display-bufferは作成するすべてのウィンドウをそのバッファー専用であるとマークする(専用のウィンドウを参照)。これは最初の引数に選択したウィンドウ、2つ目の引数にエントリーの値を指定してset-window-dedicated-pを呼び出すことにより行われる。サイドウィンドウはデフォルトでは値sideで専用となる(サイドウィンドウのオプションと関数を参照)。

preserve-size

このようなエントリーが非nilなら、選択したウィンドウのサイズを維持するようにEmacsに指示する(ウィンドウサイズの保持を参照)。値は(t . nil) (ウィンドウの幅を維持)、(nil . t) (高さを維持)、または(t . t) (幅と高さの両方を維持)のいずれか。このエントリーはこのリストの後に指定する特定の条件下でのみ処理される必要がある。

lru-frames

値はバッファーの表示に使用可能なウィンドウを検索するフレームを指定する。display-buffer-use-some-window、およびdisplay-buffer-use-least-recent-windowが最近使用されていない別のバッファーを表示中のウィンドウを探す際に参照される。値は上述のreusable-framesエントリーと同様。

lru-time

値には使用時間(use time)の指定が求められる(ウィンドウの選択を参照)。このエントリーはdisplay-buffer-use-some-window、およびdisplay-buffer-use-least-recent-windowが最近使用されていない別のバッファーを表示中のウィンドウを探す際に参照される。これらの関数はバッファーの表示において、このオプションで指定された値より長い使用時間をもつウィンドウを勘定に入れない。

bump-use-time

このエントリーが非nilなら、display-bufferが使用するウィンドウの使用時間(ウィンドウの選択を参照)を増加させる。これにより後刻display-buffer-use-some-windowdisplay-buffer-use-least-recent-windowのようなアクション関数が別のバッファーを表示する際に、このウィンドウが使用されることが回避される筈である。

このエントリーの使用とアクション関数display-buffer-use-least-recent-windowの使用の間には僅かな違いが存在する。後者の呼び出しは、この関数がバッファーの表示に使用するウィンドウの使用時間だけを増加させることを意味する。ここで説明しているエントリーには、display-bufferがバッファーの表示に使用するすべてのウィンドウの使用時間を増加させるという意味をもつ。

pop-up-frame-parameters

この値は新たにフレームが作成された場合に与えるフレームパラメーターのalist。display-buffer-pop-up-frameがけが参照する。

parent-frame

値は子フレームにバッファーを表示時に使用する親フレームを指定する。このエントリーを使用するのはdisplay-buffer-in-child-frameのみ。

child-frame-parameters

値は子フレームにバッファー表示時に使用するフレームパラメーターのalistを指定する。このエントリーを使用するのはdisplay-buffer-in-child-frameのみ。

side

値はバッファーを表示する新たなウィンドウを、フレームやバッファーのどのサイドに作成するかを示す。このエントリーは新たなサイドウィンドウをフレームのどのサイドに配置するかを示すためにdisplay-buffer-in-side-windowが使用する(サイドウィンドウへのバッファーの表示を参照)。さらに新たなサイドウィンドウを既存ウィンドウのどのサイドに配置するかを示すためにdisplay-buffer-in-atom-windowにも使用される(アトミックウィンドウを参照)。

slot

値が非nilならバッファーを表示するサイドウィンドウのスロットを指定する。このエントリーを使用するのはdisplay-buffer-in-side-windowのみ。

direction

この値はwindowエントリーとともに、display-buffer-in-directionがバッファーを表示するウィンドウ位置を決定するための方向を指定する。

window

値はdisplay-bufferで選択されたウィンドウと何らかの関連があるウィンドウを指定する。このエントリーは現在のところ新たなウィンドウが作成されるサイドのウィンドウを示すためにdisplay-buffer-in-atom-windowが使用する。これは結果のウィンドウが出現する側の参照ウィンドウを指定するためにdisplay-buffer-in-directionも使用する。

allow-no-window

値が非nilならdisplay-bufferは必ずしもバッファーを表示する必要はなく、呼び出し側はそれを受け入れる準備がある。display-bufferの任意の呼び出し手がバッファーを表示するウィンドウが存在しないケースを処理できる保証がないので、、このエントリーはユーザーのカスタマイゼーションを意図したものではない。このエントリーを考慮するアクション関数はdisplay-buffer-no-windowのみ。

body-function

値は1つの引数(表示されるウィンドウ)を受け取る関数でなければならない。この関数は表示されるウィンドウのサイズに応じて、表示されるウィンドウのbodyを何らかのコンテンツで充填するために使用できるかもしれない。これはバッファー表示の、かつ挿入したコンテンツに適合するようにリサイズを適用できるwindow-heightwindow-widthpreserve-sizeの開始のに呼び出される。

慣例によりエントリーwindow-heightwindow-widthpreserve-sizeは選択したウィンドウのバッファーのセットアップ後、かつそのウィンドウが以前に他のバッファーを表示していない場合のみ適用されます。後者はより正確にはカレントのdisplay-buffer呼び出しによりウィンドウが作成されたか、以前にそのバッファーを表示するためにdisplay-bufferによりウィンドウが作成されて、カレントのdisplay-buffer呼び出しによる再利用まで他のバッファーの表示に使用されたことがないことを意味します。

window-heightwindow-width、あるいはwindow-sizeのエントリーが何も指定されていない場合でも、そのバッファーが一時的なバッファーであり、かつtemp-buffer-resize-mode有効ならウィンドウは依然としてリサイズされる可能性があります。一時的な表示を参照してください。このような場合には特定のバッファーやdisplay-buffer呼び出しにたいするtemp-buffer-resize-modeのデフォルトの挙動の抑制やオーバーライドにwindow-heightwindow-width、あるいはwindow-sizeといったエントリーのCDRを用いることができます。


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

29.13.4 バッファー表示の追加オプション

以下のユーザーオプションでバッファーのディスプレイアクション(バッファーを表示するウィンドウの選択を参照)の振る舞いをさらに変更することができます。

User Option: pop-up-windows

この変数の値が非nilなら、display-bufferは表示のために既存のバッファーを分割して新たなウィンドウを作成できる。

この変数は後方互換のためだけに提供される。このオプションの値が非nilのときはアクション関数display-buffer-pop-up-window (バッファー表示用のアクション関数を参照)を呼び出すだけのdisplay-buffer-fallback-action内の特別なメカニズムを経由してdisplay-bufferにしたがう。この変数はdisplay-buffer-alist等により直接指定できるdisplay-buffer-pop-up-window自体からは参照されない。

User Option: split-window-preferred-function

この変数は、バッファーを表示する新たなウィンドウを作成するための、ウィンドウを分割する関数を指定する。これは、実際にウィンドウを分割するために、アクション関数display-buffer-pop-up-windowにより使用される。

値はウィンドウを単一の引数とする関数でなければならず、(要求されたバッファーを表示するために使用される)新たなウィンドウ、またはnil (分割の失敗を意味する)をリターンしなければならない。デフォルト値はsplit-window-sensibly (次に説明)。

Function: split-window-sensibly &optional window

この関数はwindowを分割して新たに作成したウィンドウをリターンする。windowを分割できなければnilをリターンする。windowが省略かnilの場合のデフォルトは選択されたウィンドウ。

この関数はウィンドウが分割できるかどうか判断する際の通常のルールにしたがう(ウィンドウの分割を参照)。最初にまずsplit-height-threshold(以下参照)、およびその他が課す制約の元で新たなウィンドウが下になるように分割を試みる。これが失敗したらsplit-width-threshold(以下参照)が課す制約の元で新たなウィンドウが右になるように分割を試みる。これも失敗して、かつそのウィンドウがそのフレームの唯一のウィンドウなら、この関数はsplit-height-thresholdを無視して新たなウィンドウが下になるように再度分割を試みる。これも同様に失敗したら、この関数は諦めてnilをリターンする。

User Option: split-height-threshold

この変数はsplit-window-sensiblyがウィンドウを分割して新たなウィンドウを下に配置できるかどうかを指定する。整数なら元のウィンドウが最低でもその行数なければ分割しないことを意味する。nilなら、この方法では分割しないことを意味する。

User Option: split-width-threshold

この変数はsplit-window-sensiblyがウィンドウを分割して新たなウィンドウを右に配置できるかどうかを指定する。整数なら元のウィンドウが最低でもその列数なければ分割しないことを意味する。nilなら、この方法では分割しないことを意味する。

User Option: even-window-sizes

この変数が非nilならdisplay-bufferが既存のウィンドウを再利用する際は常にウィンドウのサイズを均等にして、そのウィンドウを選択されたウィンドウに隣接させる。

値がwidth-onlyなら再利用されるウィンドウが選択されたウィンドウの左か右にあり、かつ選択されたウィンドウが再利用されるウィンドウより広い場合のみサイズは均等になる。値がheight-onlyなら再利用されるウィンドウが選択されたウィンドウの上か下にあり、かつ選択されたウィンドウが再利用されるウィンドウより高い場合のみサイズは均等になる。その他の非nil値は、選択されたウィンドウと再利用されるウィンドウをコンビネーション的に比較して選択されたウィンドウの方が大ならサイズを均等にすることを意味する。

User Option: pop-up-frames

この変数の値が非nilなら、新たにフレームを作成することによりdisplay-bufferがバッファーを表示できることを意味する。デフォルトはnil

nil値はdisplay-bufferがすでにbuffer-or-nameを表示しているウィンドウを探す際に、選択されたフレームだけでなく可視およびアイコン化されたフレームを検索できることも意味する。

この変数は主に後方互換のために提供されている。値が非nilのときは、アクション関数display-buffer-pop-up-frame (バッファー表示用のアクション関数を参照)を呼び出すだけのdisplay-buffer-fallback-action内の特別なメカニズムを経由してdisplay-bufferにしたがう。この変数はdisplay-buffer-alist等により直接指定できる、display-buffer-pop-up-window自体からは参照されない(これはウィンドウの分割前に行われる)。この変数はdisplay-buffer-alist等により直接指定できるdisplay-buffer-pop-up-frame自体からは参照されない。

User Option: pop-up-frame-function

この変数はバッファーを表示する新たなウィンドウを作成するためのフレームを作成する関数を指定する。これはアクション関数display-buffer-pop-up-frameにより使用される。

値はフレーム、またはフレームを作成できなかったらnilをリターンする引数をとらない関数であること。デフォルト値はpop-up-frame-alist (以下参照)により指定されるパラメーターを使用してフレームを作成する関数。

User Option: pop-up-frame-alist

この変数はフレームを新たに作成するためのpop-up-frame-functionで指定される関数が使用するフレームパラメーター(フレームのパラメーターを参照)のalistを保持する。デフォルトはnil

このオプションは後方互換のためだけに提供される。これはdisplay-buffer-pop-up-framepop-up-frame-functionの指定する関数を呼び出す際に、すべてのアクションalistのpop-up-frame-parametersエントリーの値に前置されるので、アクションalistのエントリーが指定する値がpop-up-frame-alistの対応する値を効果的にオーバーライドすることに注意。

したがってユーザーはpop-up-frame-alistをカスタマイズするのではなく、display-buffer-alistnoアクションalistのpop-up-frame-parametersエントリーをセットアップするべきである。ユーザーが指定したパラメーターの値だけが、display-bufferの呼び出し手が指定したパラメーターの値をオーバーライドするこが保証されている。

display-bufferのデザインではpop-up-windowspop-up-framespop-up-frame-alistsame-window-buffer-namessame-window-regexpsのような古いオプションを使用するコードにたいする保守に互換性を与えるために多くの努力が払われています。Lispプログラムやユーザーはこれらのオプションの使用は控えるべきです。上述のようにpop-up-frame-alistのカスタマイズにたいしては警告済みです。ここでは残りのオプションではなくディスプレイアクションを使用するように変換する方法を説明します。

pop-up-windows

この変数のデフォルトはt。これをnilにカスタマイズしてdisplay-bufferに何を行うべきではないかを指示するよりも、かわりに試みるべきアクション関数をdisplay-buffer-base-action内にリストするほうがよい。たとえば:

(setopt
 display-buffer-base-action
 '((display-buffer-reuse-window display-buffer-same-window
    display-buffer-in-previous-window
    display-buffer-use-some-window)))
pop-up-frames

この変数をtにカスタマイズするのではなく、たとえば以下のようにdisplay-buffer-base-actionをカスタマイズすること:

(setopt
 display-buffer-base-action
 '((display-buffer-reuse-window display-buffer-pop-up-frame)
   (reusable-frames . 0)))
same-window-buffer-names
same-window-regexps

これらのオプションのいずれかにたいしてバッファー名や正規表現を追加するかわりに、そのバッファーにたいしてアクション関数display-buffer-same-windowを指定するdisplay-buffer-alistエントリーを使用すること。

(setopt
 display-buffer-alist
 (cons '("\\*foo\\*" (display-buffer-same-window))
        display-buffer-alist))

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

29.13.5 アクション関数の優先順

これまでのサブセクションによってバッファーを表示するためには、display-bufferにいくつかのディスプレイアクションを提供しなければならないことがわかりました(バッファーを表示するウィンドウの選択を参照)。まったくカスタマイズしていないEmacsでは、これらのアクションはdisplay-buffer-fallback-actionによってウィンドウの再利用、同一フレーム上での新たなウィンドウのポップアップ、そのバッファーを以前に表示したウィンドウの使用、新たなフレームをポップアップして何らかのウィンドウを使用するという優先順で指定されます(display-buffer-fallback-actionいより命名される残りのアクションは未カスタマイズのEmacsではvoidであることに注意)。

以下のフォームを考えてください:

(display-buffer (get-buffer-create "*foo*"))

このフォームをカスタマイズされていないEmacsの*scratch*バッファーで評価すると、通常はすでに*foo*を表示しているウィンドウの再利用は失敗しますが、新たなウィンドウのポップアップは成功するでしょう。そこで同じフォームを再度評価すると、今度はdisplay-bufferはすでに*foo*を表示しているウィンドウを再利用して視覚的な変化は生じません。なぜならそれは許容され得るアクションであるとともに、すべての許容され得るアクションの中でもっとも高い優先度をもつからです。

選択されたフレームに十分なスペースがなければ、新たなウィンドウのポップアップは失敗します。カスタマイズされていないEmacsでは、通常はフレームに2つのウィンドウがすでに存在すれば失敗します。たとえば今度はC-x 1の後にC-x 2をタイプしてからもう一度フォームを評価すると、*foo*は下側のウィンドウに表示されるはずです( display-bufferは単に“何らか”のウィンドウを使用した)。C-x 2をタイプする前にC-x oをタイプしていれば、*foo*は上側のウィンドウに表示されるでしょう。なぜなら“何らか”のウィンドウとは“最近もっとも使用されていない”ウィンドウという意味であり、選択されたウィンドウが最近もっとも使用されていないウィンドウになるのは、それがフレームで唯一のウィンドウの場合だけだからです。

C-x oをタイプせずに*foo*が下側のウィンドウに表示されているとしましょう。下側のウィンドウに移動するためにC-x oの後にC-x leftをタイプして、再びフォームを評価してみます。すると*foo*は同じ下側のウィンドウに表示されるはずです。なぜなら*foo*は以前にそのウィンドウで表示されているので何らかのウィンドウのかわりにそのウィンドウが選択されるからです。

ここまではカスタマイズしていないEmacsのデフォルトの動作を観察してきました。この動作のカスタマイズの仕方を確認するために、オプションdisplay-buffer-base-actionについて考えてみましょう。これは概念的に任意のバッファーの表示に影響を与える、非常に大まかなカスタマイズを提供します。これはdisplay-buffer-fallback-actionにより提供されるアクションの並び替えや、提供されていないもののユーザーの編集方法により密接に適合するアクションを追加することにより、display-buffer-fallback-actionの補強に使用することができます。しかしデフォルトの動作をより深く変更するためにも使用できます。

ルールとして別フレームにバッファーを表示することを好むユーザーを考えてみましょう。そのようなユーザーなら以下のようなカスタマイズを行うかもしれません:

(setopt
 display-buffer-base-action
 '((display-buffer-reuse-window display-buffer-pop-up-frame)
   (reusable-frames . 0)))

このセッティングによりdisplay-bufferはバッファーを表示するウィンドウを探すために、まず可視のフレームとアイコン化されたフレームを探して、そのようなフレームが存在しなければ新たなフレームをポップアップします。グラフィカルなシステム上で*scratch*を表示しているウィンドウでC-x 1をタイプして例のdisplay-bufferフォームを評価して動作を観察できます。これは通常はルートウィンドウに*foo*を表示するフレームを新たに作成(およびフォーカスを付与)します。このフレームをアイコン化して例のフォームを再度評価すると、display-bufferは新たなフレーム(通常はフレームをraiseしてフォーカスを付与)のウィンドウを再利用するでしょう。

display-bufferは新たなフレームの作成に失敗した場合のみdisplay-buffer-fallback-actionが提供するアクション(ウィンドウ再利用の再試行、新たなウィンドウのポップアップ等)を適用します。以下のフォームでフレーム作成を簡単に失敗させることができます:

(let ((pop-up-frame-function 'ignore))
  (display-buffer (get-buffer-create "*foo*")))

新たなフレーム作成に失敗してかわりにフォールバックアクションの使用を観察した直後にこのフォームを忘れてしまうでしょう。

display-buffer-base-actionのカスタマイズにおいてdisplay-buffer-reuse-windowは冗長に思えることに注意してください。なぜならすでにdisplay-buffer-reuse-windowdisplay-buffer-fallback-actionの一部であり、いずれにせよフォールバックアクションで試みられるはずだからです。しかしこれはdisplay-buffer-pop-up-frameが優先順ですでに優っていた時点で、display-buffer-base-actiondisplay-buffer-fallback-actionより優先されることにより失敗するでしょう。実際のところ:

(setopt
 display-buffer-base-action
 '(display-buffer-pop-up-frame (reusable-frames . 0)))

display-bufferに新たなフレームをポップアップして、これはおそらくユーザーが望んでいない動作です。

ここまではユーザーdisplay-bufferのデフォルト動作をカスタマイズする方法だけを示しました。今度はアプリケーションdisplay-bufferの動作を変更する方法について見てみましょう。これを行う正規の手順はdisplay-bufferpop-to-bufferのようなdisplay-bufferを呼び出す関数のaction引数を使用する方法です(ウィンドウ内のバッファーへの切り替えを参照)。

あるアプリケーションが(新たなウィンドウにユーザーを即座に注目させるために)可能なら選択されたウィンドウの下、それが失敗したらフレームの最下ウィンドウにに*foo*を表示したいと仮定してみましょう。これは以下のような呼び出しで行うことができます:

(display-buffer
 (get-buffer-create "*foo*")
 '((display-buffer-below-selected display-buffer-at-bottom)))

この新しい変更されたフォームがどのように機能するか確認するために*foo*を表示しているすべてのフレームを削除してから、*scratch*を表示中のウィンドウでC-x 1の後にC-x 2をタイプしてから、続けてそのフォームを評価してみてください。display-bufferは上側のウィンドウを分割して、新たなウィンドウに*foo*を表示するはずです。C-x 2の後にC-x oをタイプした場合には、display-bufferはかわりに最下にあるウィンドウを分割するでしょう。

今度は新たなフォームを評価する前に、(たとえば選択されたウィンドウで(fit-window-to-buffer)を評価して)選択されたウィンドウを可能なかぎり小さくしたとします。この場合にはdisplay-bufferは選択されたウィンドウの分割に失敗して、フレームの最下に効果的に*foo*を表示するために、かわりにフレームのルートウィンドウを分割するでしょう。

いずれの場合においても新たなフォームの2回目の評価では、すでに*foo*を表示しているウィンドウの再利用を試みるはずです。これはaction引数が提供するどちらの関数も、そのようなウィンドウの使用を最初に試みるからです。

action引数をセットすることにより、アプリケーションはdisplay-buffer-base-actionのすべてのカスタマイゼーションを効果的に無効にします。今度はユーザーはアプリケーションの選択を受け入れるか、以下のようにオプションdisplay-buffer-alistをさらにカスタマイズすることができます:

(setopt
 display-buffer-alist
 '(("\\*foo\\*"
    (display-buffer-reuse-window display-buffer-pop-up-frame))))

*foo*がどこにも表示されていない設定で新たな変更版のフォームを試みると、display-bufferactionを完全に無視して別フレームに*foo*が表示されます。

display-buffer-alistの仕様において,reusable-framesアクションalistの指定を気にしていない点に注意してください。display-bufferは常に最初に見つかったウィンドウ、この場合ではdisplay-buffer-base-actionで指定されたウィンドウを採用します。しかし異なる仕様を使用したいとき、たとえば再利用可能なウィンドウから*foo*を表示中のアイコン化されたフレームを除外したければ個別にそれを指定する必要があります:

(setopt
 display-buffer-alist
 '(("\\*foo\\*"
    (display-buffer-reuse-window display-buffer-pop-up-frame)
    (reusable-frames . visible))))

これを試せば繰り返し*foo*の表示を試みた場合に、フレームが可視のときだけフレームの再利用に成功することに気がつくでしょう。

上記の例によりアプリケーションが選択したaction引数を無視するという単一の目的にたいしてユーザーがdisplay-buffer-alistをカスタマイズできるという結論が導かれるかもしれません。そのような結論は正しくありません。display-buffer-alistは表示がaction引数によってもガイドされるかどうかに関わらず、ユーザーが好む方法で特定のバッファーの表示方法を指示するための標準オプションです。

しかし2つの主要な観点から、display-buffer-alistのカスタマイズはdisplay-buffer-base-actionのカスタマイズとは異なると合理的に結論づけることができます。display-buffer-alistのカスタマイズはdisplay-bufferaction引数をオーバーライドして、影響を受けるバッファーを明示的に指定できることからより強力です。実際のところ*foo*のカスタマイズによって他のバッファーの表示には何も影響がありません。たとえば、

(display-buffer (get-buffer-create "*bar*"))

display-buffer-base-actiondisplay-buffer-fallback-actionのセッティングだけに管理されます。

ここで例を止めることもできますが、Lispプログラムにはdisplay-buffer-alistにたいする任意のカスタマイズの無効化に使用できる取って置きの切り札があります。その切り札display-buffer-overriding-actionは以下のようにdisplay-buffer呼び出しの前後でバインドすることができます:

(let ((display-buffer-overriding-action
       '((display-buffer-same-window))))
  (display-buffer
   (get-buffer-create "*foo*")
   '((display-buffer-below-selected display-buffer-at-bottom))))

このフォームの評価により通常はaction引数や任意のユーザーカスタマイゼーションとは無関係に、選択されたウィンドウに*foo*が表示されます(通常はアプリケーションがactionを提供する必要もないが、ここではオーバーライドされる事実を示すために提供されている)。

ここで提供したカスタマイゼーションで*foo*の表示を試みたアクション関数のリストを調べれば、それが実例になるかもしれません。そのリスト(何がそれを追加したかと後続の要素を含む)は:

(display-buffer-same-window  ;; `display-buffer-overriding-action'
 display-buffer-reuse-window ;; `display-buffer-alist'
 display-buffer-pop-up-frame
 display-buffer-below-selected ;; ACTION argument
 display-buffer-at-bottom
 display-buffer-reuse-window ;; `display-buffer-base-action'
 display-buffer-pop-up-frame
 display-buffer--maybe-same-window ;; `display-buffer-fallback-action'
 display-buffer-reuse-window
 display-buffer--maybe-pop-up-frame-or-window
 display-buffer-in-previous-window
 display-buffer-use-some-window
 display-buffer-pop-up-frame)

ここで列挙した内部関数の中でdisplay-buffer--maybe-pop-up-frame-or-windowが実際にdisplay-buffer-pop-up-windowを実行しているにも関わらず、display-buffer--maybe-same-windowが効果的に無視されていることに注意してください。

アクション関数の各呼び出しにおいて渡されるアクションalistは:

((reusable-frames . visible)
 (reusable-frames . 0))

これは上述のdisplay-buffer-alistの2つ目の仕様を使用して、display-buffer-base-actionが提供する仕様をオーバーライドすることを示しています。これをユーザーが以下のように記述したと考えてみましょう

(setopt
 display-buffer-alist
 '(("\\*foo\\*"
    (display-buffer-reuse-window display-buffer-pop-up-frame)
    (inhibit-same-window . t)
    (reusable-frames . visible))))

この場合にはalistのinhibit-same-windowエントリーはdisplay-buffer-overriding-actionからdisplay-buffer-same-window仕様を成功裏に無効化して、display-bufferは別フレームに*foo*を表示するでしょう。この点においてdisplay-buffer-overriding-actionをより堅牢にするためには、アプリケーションはたとえば以下のように適切なinhibit-same-windowエントリーも指定する必要があるでしょう:

(let ((display-buffer-overriding-action
       '(display-buffer-same-window (inhibit-same-window . nil))))
  (display-buffer (get-buffer-create "*foo*")))

最後の例ではバッファーを表示するウィンドウの選択で説明したようにアクション関数の優先順は固定ではあるものの、優先順で低位のディスプレイアクションが指定したアクションalistのエントリーが、より高位のディスプレイアクションの実行に影響を与えれれることを示しています。


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

29.13.6 バッファー表示の思想

フレームのもっとも単純な形式では常にバッファー表示に使用可能な単一のウィンドウが収容されています。結果としてdisplay-bufferのもっとも最近の呼び出しは、常にそのウィンドウへのバッファーの配置に成功した呼び出しとなります。

そのようなフレームを処理することは実際的ではないので、デフォルトではEmacsはフレームサイズのデフォルト値、split-height-thresholdsplit-width-thresholdのオプションにより制御される、より複雑なレイアウトを許容しています。そのフレームでまだ表示されていないバッファーを表示すると、フレーム上の単一ウィンドウを分割するか、2つのウィンドウのいずれかを(再)利用します。

これらのしきい値のいずれかをカスタマイズしたり手動でフレームのレイアウトを変更するとデフォルトの動作は棄却されます。非nilaction引数でdisplay-bufferを呼び出したり、前のサブセクションに示したオプションのいずれかをユーザーがカスタマイズした際にもデフォルト動作は棄却されます。display-bufferを習得次第、表示可能なディスプレイアクションとフレイムレイアウト結果の膨大さにフラストレーションを覚えるかもしれません。

しかしバッファー表示関数の使用を控えてウィンドウのウィンドウの分割と削除のメタファーに逆行するのは良い考えではありません。Lispプログラムやユーザーにたいしてバッファー表示関数は、異なるニーズを調整するフレームワークを提供します。ウィンドウの分割と削除にたいする同等なフレームワークは存在しません。バッファー表示関数ではフレームからバッファーを削除する際に、少なくともフレームレイアウトを部分的に後からリストアすることが可能です(ウィンドウのquitを参照)。

上述したフラストレーションを埋め合わせるとともに、文字通りフレームのウィンドウ間でバッファーが失われることを避けるために、以下にいくつのガイダンスを示します。

無理せずディスプレイアクションを記述する

ディスプレイアクションの記述はアクション関数とアクションalistを1つの巨大なリストにまとめる必要があるので多大な苦痛をともなう恐れがある(歴史的な理由によってdisplay-bufferの引数として個別にサポートすることができなかった)。以下のリストのような基本形式を覚えておくと便利かもしれない:

'(nil (inhibit-same-window . t))

アクション関数なしのアクションalistエントリーだけを指定する。これの唯一の目的は、どこかで指定されたdisplay-buffer-same-window関数が同一ウィンドウ内でのバッファー表示を抑制すること。前のサブセクションの最後の例も参照のこと。

'(display-buffer-below-selected)

一方こちらは1つのアクション関数と空のアクションalistを指定する。上記2つの指定の効果を1つ組み合わせるためには以下のようなフォームを記述

'(display-buffer-below-selected (inhibit-same-window . t))

別のアクション関数の追加は以下のように記述

'((display-buffer-below-selected display-buffer-at-bottom)
  (inhibit-same-window . t))

別のアクションalistを追加するには以下のように記述

'((display-buffer-below-selected display-buffer-at-bottom)
  (inhibit-same-window . t)
  (window-height . fit-window-to-buffer))

最後のフォームは以下の方法によりdisplay-bufferaction関数に使用できる:

(display-buffer
 (get-buffer-create "*foo*")
 '((display-buffer-below-selected display-buffer-at-bottom)
   (inhibit-same-window . t)
   (window-height . fit-window-to-buffer)))

display-buffer-alistのカスタマイズでは以下のように使用できる:

(setopt
 display-buffer-alist
 '(("\\*foo\\*"
    (display-buffer-below-selected display-buffer-at-bottom)
    (inhibit-same-window . t)
    (window-height . fit-window-to-buffer))))

2つ目のバッファーへのカスタマイズを追加するには以下のように記述:

(setopt
 display-buffer-alist
 '(("\\*foo\\*"
    (display-buffer-below-selected display-buffer-at-bottom)
    (inhibit-same-window . t)
    (window-height . fit-window-to-buffer))
   ("\\*bar\\*"
    (display-buffer-reuse-window display-buffer-pop-up-frame)
    (reusable-frames . visible))))
互いを尊重して扱う

display-buffer-alistdisplay-buffer-base-actionはユーザーオプションであって、Lispプログラムはそれらのセットやリバインドを行ってはならない。一方でdisplay-buffer-overriding-actionはアプリケーション用に予約されていて滅多に使用されず、使用する場合には細心の注意を払うこと。

display-bufferの旧実装では、pop-up-framespop-up-windowsのようなユーザーオプションのセッティングをめぐってユーザーとアプリケーションの競合が頻発した(バッファー表示の追加オプションを参照)。これがdisplay-bufferを再デザイン(ユーザーおよびアプリケーションにたいして何を行うことが許容されているかを指定する明快なフレームワークを提供する)した主な理由である。

Lispプログラムはユーザーのカスタマイゼーションによって予期せぬ方法でバッファーが表示されるかもしれないことに備えなければならない。display-bufferの後続の振る舞いにおいてaction引数で要求した方法でバッファーが正確に表示されていると仮定しないこと。

ユーザーは任意のバッファーが表示される方法について厳しすぎる制限を過度に多く設けるべきではない。さもないと特定の目的でバッファーを表示する際の特性を失うリスクがある。横並びの2つのウィンドウでバッファーの異なるバージョンを比較するLispプログラムを記述するとしよう。display-buffer-alistのカスタマイズによりそのようなすべてのバッファーは常に選択されたウィンドウの下に表示されるように定められていたら、display-bufferを通じて望ましいウィンドウ構成を構成するのはプログラムにとって困難だろう。

任意のバッファーを表示するための設定を指定するためには、ユーザーはdisplay-buffer-base-actionをカスタマイズする必要がある。複数のフレームで作業を行うことを好むユーザーについての例は前のサブセクションを参照のこと。display-buffer-alistは特定のバッファーを特定の方法で表示するために予約済みである。

すでにバッファーを表示しているウィンドウの再利用の考慮

一般的にユーザーとLispプログラムにとって、ウィンドウがすでに対象となるバッファーを表示していて、それを再利用するのは常に良いアイデアである。前のサブセクションではバッファーを表示しているフレームがすでに存在していても、正しく行うことに失敗するとdisplay-bufferが継続的に新たなフレームをポップアップすることを示した。たとえばバッファーの異なる部分をそのウィンドウで表示する必要がある際のように、少数のケースにおいてはウィンドウの再利用は望ましくないかもしれない。

したがってdisplay-buffer-reuse-windowaction引数とカスタマイゼーションの両方で可能なかぎり使用するべきアクション関数の1つである。action引数のinhibit-same-windowエントリーは、通常はバッファーをを表示中のウィンドウ、つまり対象となるウィンドウが選択されたウィンドウならそのウィンドウの再利用を避けるような、一般的なケースのほとんどを考慮する。

選択したウィンドウにフォーカスを当てる

これは複数フレームで作業を行う人にとっては思考を要しない。バッファーを表示中のフレームは自動的にraiseされてinhibit-switch-frameが禁じていなければフォーカスを取得する。単一フレームのユーザーにとっては、このタスクは顕著に困難になり得る。この点において特にdisplay-buffer-pop-up-windowdisplay-buffer-use-some-windowが厄介になる可能性がある。これらは表面上は任意に見えるウィンドウ(最大のウィンドウか最近もっとも使用されていないウィンドウ)を分割または使用してユーザーの注意を逸らす。

したがってLispプログラムのいくつかは、たとえば新たなウィンドウに関して問いに答える場所として期待されるミニバッファーウィンドウの近傍にバッファーを表示するためにフレーム最下のウィンドウの選択を試みる。選択されたウィンドウは通常はすでにユーーザーの注意を喚起済みなので、入力とは無関係なアクションであるdisplay-buffer-below-selectedが好ましいかもしれない。

どのウィンドウが選択されているのか配慮する

アプリケーションの多くは引数norecordに非nilを指定してwith-selected-windowselect-windowを呼び出すことによって生成されたウィンドウエクスカーション内部からdisplay-bufferを呼び出す。これはほとんど常に間違った考えである。なぜならそのようなエクスカーション内部で選択されたウィンドウは、ユーザーに提示されているウィンドウ構成で選択されているウィンドウと通常は異なるから。

たとえばユーザーがalistにエントリーinhibit-same-windowを追加していたとすると、そのエントリーによってエクスカーションのスコープ内で選択されたウィンドウを回避するが、結果となる構成において選択されたウィンドウは回避しないだろう。たとえそのようなエントリーが追加されていなくても、結果として奇妙に振る舞うかもしれない。1つの生きたウィンドウを含んだフレームで以下のフォームを評価すると

(progn
  (split-window)
  (display-buffer "*Messages*"))

これは他のウィンドウが選択されたまま最下に*Messages*バッファーを表示する。次のフォームを評価すると

(with-selected-window (split-window)
  (display-buffer "*Messages*"))

これは最上ウィンドウに*Messages*を表示してそれを選択する(display-bufferの場合は通常は選択しない)。

一方、以下のフォームを評価すると

(progn
  (split-window)
  (pop-to-buffer "*Messages*"))

これは*Messages*バッファーを正しく選択するが、次のフォーム

(progn
  (split-window)
  (with-selected-window (selected-window)
    (pop-to-buffer "*Messages*")))

こちらは異なる。

更に選択されたウィンドウの使用時間がすべてのウィンドウの中でもっとも長いことを期待するdisplay-buffer-use-some-windowdisplay-buffer-use-least-recent-windowのようなアクション関数の呼び出しは、その仕様にしたがったウィンドウの生成に失敗するかもしれない。

したがってウィンドウ エクスカーションの使用に依存するアプリケーションは、そのエクスカーションが終了するまでdisplay-bufferの呼び出しの延期を試みるべきである。


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

29.14 ウィンドウのヒストリー

ウィンドウはそれぞれ、リスト内に以前表示されていたバッファーと、それらのバッファーがウィンドウから削除された順序を記憶しています。このヒストリーが、たとえばreplace-buffer-in-windows (バッファーとウィンドウを参照)やウィンドウのquit (ウィンドウのquitを参照)の際に使用されます。このリストはEmacsにより自動的に保守されますが、これを明示的に調べたり変更するために、以下の関数を使用できます:

Function: window-prev-buffers &optional window

この関数はwindowの前のコンテンツを指定するリストをリターンする。オプション引数windowには生きたウィンドウを指定すること。デフォルトは選択されたウィンドウ。

リスト要素はそれぞれ(buffer window-start window-pos)という形式をもつ。ここでbufferはそのウィンドウで前に表示されていたウィンドウ、window-startはそのバッファーが最後に表示されていたときのウィンドウのスタート位置(ウィンドウの開始位置と終了位置を参照)、window-poswindow内にそのバッファーが最後に表示されていたときのポイント位置(ウィンドウとポイントを参照)。

このリストは順序付きであり、より前の要素がより最近に表示されたバッファーに対応してして、通常は最初の要素がそのウィンドウからもっとも最近削除されたバッファーに対応する。

Function: set-window-prev-buffers window prev-buffers

この関数はwindowの前のバッファーをprev-buffersの値にセットする。引数windowは生きたウィンドウでなければならず、デフォルトは選択されたウィンドウ。引数prev-bufferswindow-prev-buffersによりリターンされるリストと同じ形式であること。

これらに加えて各ウィンドウは次バッファー(next buffers)のリストを保守します。これはswitch-to-prev-buffer (以下参照)により再表示されたバッファーのリストです。このリストは主に切り替えるバッファーを選択するために、switch-to-prev-bufferswitch-to-next-bufferにより使用されます。

Function: window-next-buffers &optional window

この関数はswitch-to-prev-bufferを通じてwindow内に最近表示されたバッファーのリストをリターンする。window引数は生きたウィンドウかnil (選択されたウィンドウの意)でなければならない。

Function: set-window-next-buffers window next-buffers

この関数はwindowの次バッファーリストをnext-buffersにセットする。window引数は生きたウィンドウかnil (選択されたウィンドウの意)、引数next-buffersはバッファーのリストであること。

以下のコマンドはbury-bufferunbury-bufferのように、グローバルバッファーリストを巡回するために使用できます。ただしこれらはグローバルバッファーリストではなく、指定されたウィンドウのヒストリーリストのしたがって巡回します。それに加えてこれらはウィンドウ固有なウィンドウのスタート位置とポイント位置をリストアして、すでに他のウィンドウに表示されているバッファーをも表示できます。特にswitch-to-prev-bufferコマンドは、ウィンドウにたいする置き換えバッファーを探すためにreplace-buffer-in-windowsbury-bufferquit-windowにより使用されます。

Command: switch-to-prev-buffer &optional window bury-or-kill

このコマンドはwindow内に前のバッファーを表示する。引数windowは生きたウィンドウかnil (選択されたウィンドウの意)であること。オプション引数bury-or-killが非nilなら、それはwindow内にカレントで表示されているバッファーは今まさにバリーもしくはkillされるバッファーであり、したがって将来におけるこのコマンドの呼び出しでこのバッファーに切り替えるべきではないことを意味する。

前のバッファーとは、通常はwindow内にカレントで表示されているバッファーの前に表示されていたバッファーである。しかしバリーやkillされたバッファー、または直近のswitch-to-prev-buffer呼び出しですでに表示されたバッファーは前のバッファーとしては不適格となる。

このコマンドを繰り返して呼び出すことによりwindow内で前に表示されたすべてのバッファーが表示されてしまったら、将来の呼び出しではwindowが表示されているフレームのバッファーリスト(バッファーリストを参照)からバッファーを表示する。

特定のバッファー、たとえば別ウィンドウに表示済みのバッファーへの切り替えを抑制するために、以下で説明するオプションswitch-to-prev-buffer-skipを使用できる。同様にwindowのフレームがbuffer-predicateパラメーター(バッファーのパラメーターを参照)をもつ場合には、この述語は特定のバッファーへの切り替えを抑制する。

Command: switch-to-next-buffer &optional window

このコマンドはwindow内の次バッファーに切り替える。つまりwindow内での最後のswitch-to-prev-bufferコマンドの効果をアンドゥする。引数windowは生きたウィンドウであること。デフォルトは選択されたウィンドウ。

アンドゥ可能なswitch-to-prev-bufferの直近の呼び出しが存在しなければ、この関数はwindowが表示されているフレームのバッファーリスト(バッファーリストを参照)からバッファーの表示を試みる。

windowのフレームのオプションswitch-to-prev-buffer-skipbuffer-predicate (バッファーのパラメーターを参照)はswitch-to-prev-bufferの場合のように、このコマンドに影響を与える。

デフォルトでは、switch-to-prev-bufferswitch-to-next-bufferは他のウィンドウで表示済みのバッファーに切り替えることができます。この挙動をオーバーライドするために以下のオプションを使用できます。

User Option: switch-to-prev-buffer-skip

この変数がnilなら、switch-to-prev-bufferは別のウィンドウに表示済みのバッファーを含むすべてのバッファーに切り替えることができる。

この変数が非nilなら、switch-to-prev-bufferは特定のバッファーへの切り替えを抑制する。以下の値を使用できる:

  • thisswitch-to-prev-bufferが動作するウィンドウをホストするフレームで表示中のバッファーに切り替えないことを意味する。
  • visibleは可視フレームで表示中のバッファーに切り替えないことを意味する。
  • 0(数値の0)は可視やアイコン化されたフレームで表示中のバッファーに切り替えないことを意味する。
  • tは生きたフレームで表示中のバッファーに切り替えないことを意味する。
  • switch-to-prev-bufferwindow引数、switch-to-prev-bufferが切り替えようとするバッファー、switch-to-prev-bufferbury-or-kill引数という3つの引数を受け取る関数。この関数が非nilをリターンすると、switch-to-prev-bufferは2つ目の引数で指定されたバッファーからの切り替えを抑制する。

コマンドswitch-to-next-bufferは同様の方法でこのオプションにしたがう。このオプションに関数が指定されると、switch-to-next-bufferは3つ目の引数を常にnilにしてその関数を呼び出す。

switch-to-prev-bufferbury-buffer、同じくreplace-buffer-in-windowsquit-restore-windowが呼び出すので、このオプションをカスタマイズすることによりウィンドウのquitやバッファーがバリーやkillされる際のEmacsの挙動にも影響することに注意。

更にswitch-to-prev-bufferswitch-to-next-bufferは特定の状況下、たとえばこれらの関数が切り替え可能なバッファーが1つしか残っていないときには、このオプションが無視されるかもしれないことにも注意。

User Option: switch-to-prev-buffer-skip-regexp

このユーザーオプションは正規表現、または正規表現のリストであること。名前がこれらの正規表現にマッチするバッファーを、switch-to-prev-bufferおよびswitch-to-next-bufferは無視する(切り替えるバッファーが他に存在しない場合を除く)。


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

29.15 専用のウィンドウ

特定のウィンドウがそのウィンドウのバッファーにたいして専用(dedicated)であるとマークすることにより、バッファーを表示する関数にそのウィンドウを使用しないように告げることができます。display-buffer (バッファーを表示するウィンドウの選択を参照)は、他のバッファーの表示に専用バッファーを決して使用しません。 get-lru-windowget-largest-window (ウィンドウのサイクル順を参照)は、dedicated引数が非nilのときは専用ウィンドウを候補とはみなしません。専用ウィンドウにたいする配慮に関してset-window-buffer (バッファーとウィンドウを参照)の挙動は若干異なります。以下を参照してください。

ウィンドウからのバッファー削除、およびフレームからのウィンドウ削除を意図した関数は、処理するウィンドウが専用ウィンドウのときは特別な挙動を示す可能性があります。ここでは4つの基本ケース、すなわち(1)そのウィンドウがフレーム上で唯一のウィンドウの場合、(2)ウィンドウはフレーム上で唯一のウィンドウだが同一端末上に別のフレームがある場合、(3)そのウィンドウが同一端末上で唯一のフレームの唯一のウィンドウの場合、(4) dedicated(専用ウィンドウ)の値がside (サイドウィンドウへのバッファーの表示を参照)の場合を明確に区別することにします。

特にdelete-windows-on (ウィンドウの削除を参照)は関連するフレームを削除する際にケース(2)を、フレーム上で唯一のウィンドウに他のバッファーを表示する際にケース(3)と(4)を処理します。バッファーがkillされる際に呼び出される関数replace-buffer-in-windows(バッファーとウィンドウを参照)は、ケース(1)ではウィンドウを削除して、それ以外ではdelete-windows-onのように振る舞います。

bury-buffer (バッファーリストを参照)が選択されたウィンドウを操作する際は、選択されたフレームを処理するためにframe-auto-hide-function (ウィンドウのquitを参照)を呼び出すことによってケース(2)を取り扱います。他の2つのケースはreplace-buffer-in-windowsと同様に処理されます。

Function: window-dedicated-p &optional window

この関数はwindowがそのバッファーにたいして専用なら非nil、それ以外はnilをリターンする。より正確には最後のset-window-dedicated-p呼び出しで割り当てられた値、set-window-dedicated-pwindowを引数として呼び出されたことがなければnilがリターン値となる。windowのデフォルトは選択されたウィンドウ。

Function: set-window-dedicated-p window flag

この関数はflagが非nilならwindowがそのバッファーに専用、それ以外は非専用とマークする。

特別なケースとしてflagtの場合には、windowはそのバッファーにたいして特に専用(strongly dedicated)になる。set-window-bufferは処理対象のウィンドウが特に専用のウィンドウで、かつ表示を要求されたバッファーが表示済みでなければエラーをシグナルする。その他の関数はtを他の非nil値と区別して扱わない。

適切なdedicatedアクションalistエントリー(バッファー表示用のアクションalistを参照)を与えることにより、display-bufferが作成するウィンドウにたいしてそのバッファー専用であるとマークするよう指示することもできます。


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

29.16 ウィンドウのquit

コマンドがスクリーンにバッファーを配置するためにdisplay-bufferを使用した後に、ユーザーはそれを隠してEmacsディスプレイの以前の構成をリターンすることを選択できます。わたしたちはこれをウィンドウのquit(quitting the window)と呼びます。これを行うにはdisplay-bufferが使用中のウィンドウが選択されたウィンドウである間にquit-windowを呼び出してください。

以前の表示の構成を正しくリストアする方法は、そのときバッファーが表示されているウィンドウにたいして何が行われたのかに依存します。ウィンドウの削除が正しいかもしれないし、フレームの削除やそのウィンドウに別のバッファーを単に表示することが正しいことなのかもしれません。難しいのは、そのバッファーを表示するという行為の後でユーザーがウィンドウ構成を変更しているかもしれず、ユーザーが明示的に要求したその変更をアンドゥするのは望ましくないということも1つの理由です。

quit-windowが正しく事を行うことができるように、display-bufferはそのウィンドウのquit-restoreパラメーター(ウィンドウのパラメーターを参照)に行ったことに関する情報を保存します。

Command: quit-window &optional kill window

このコマンドはwindowをquitしてそのバッファーをバリーする。引数windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。プレフィックス引数killが非nilならバッファーをバリーするかわりにkillする。

まず関数quit-windowquit-window-hookを実行する。その後にウィンドウとそのバッファーを処理するために、厄介な処理をこなす関数quit-restore-window (次に説明)を呼び出す。

かわりにquit-restore-windowを呼び出すことで、より多くの制御を得ることができます。

Function: quit-restore-window &optional window bury-or-kill

この関数はwindowのquit後にウィンドウとウィンドウのバッファーを処理する。オプション引数windowは生きたウィンドウでなければならず、デフォルトは選択されたウィンドウ。この関数はwindowquit-restoreパラメーターを考慮する。

オプション引数bury-or-killにはwindowを処理する方法を指定し、以下の値が意味をもつ。

nil

これはバッファーを特別な方法で処理しないことを意味する。その結果としてwindowが削除されない場合には、switch-to-prev-bufferの呼び出しにより通常はそのバッファーが再び表示されるだろう。

append

これはwindowが削除されない場合には、そのバッファーをwindowの前のバッファーのリスト(ウィンドウのヒストリーを参照)の最後に移動するので、将来のswitch-to-prev-buffer呼び出しでこのバッファーには切り替わることは少なくなる。これはそのバッファーをフレームのバッファーリストの最後への移動も行う(バッファーリストを参照)。

bury

これはwindowが削除されない場合には、そのバッファーをwindowの前のバッファーリストから削除する。これはそのバッファーをフレームのバッファーリストの最後への移動も行う。これはswitch-to-prev-bufferがそのバッファーをkillすることなく、このバッファーに再び切り替えさせないようにするもっとも信頼できる方法である。

kill

これはwindowのバッファーをkillすることを意味する。

引数bury-or-killwindowがそのフレームで唯一のウィンドウであり、かつそのフレームの端末上に他のフレームが存在する場合には、windowを削除するべき際にはそのフレームに何を行うかも指定する。bury-or-killkillはフレームの削除を意味する。それ以外ではフレームの処遇はそのフレームを単一の引数とするframe-auto-hide-function (以下参照)の呼び出しにより決定される。

この関数はウィンドウを削除しない場合には、windowquit-restoreパラメーターに常にnilをセットする。

ウィンドウwindowquit-restoreパラメーター(ウィンドウのパラメーターを参照)はnil、あるいは4要素のリストである必要があります:

(method obuffer owindow this-buffer)

1つ目の要素methodwindowframesameotherの4つのシンボルのうちのいずれかです。framewindowwindowを削除する方法、sameotherwindowへの別バッファーの表示を制御します。

具体的には、windowはそのウィンドウが特にdisplay-bufferによって作成されたこと、frameは別のフレームが作成されたこと、sameはこのウィンドウにはそのバッファーしか表示されていないこと、otherは以前は別のバッファーを表示していたことを意味します。

2つ目の要素obufferwindowframeのシンボルのいずれか、あるいは以下の形式のリストです

(prev-buffer prev-window-start prev-window-point height)

これはそれぞれ以前windowにどのバッファーが表示されていたか、その時点でのバッファーのウィンドウ開始(ウィンドウの開始位置と終了位置を参照)とウィンドウポイント(ウィンドウとポイントを参照)の位置、そしてwindowのその時点での高さです。windowのquit時にまだprev-bufferが生きていれば、ウィンドウのquitによってprev-bufferの表示にwindowが再利用されるかもしれません。

3つ目の要素owindowは表示が行われる直前に選択されていたウィンドウです。quitによってwindowが削除された場合にはowindowの選択を試みます。

4つ目の要素this-bufferは表示によってquit-restoreパラメーターをセットしたバッファーです。windowのquitではまだそのバッファーを表示している場合のみウィンドウを削除します。

windowのquitにおいては、(1) methodwindowframeのいずれかで、(2) そのウィンドウに以前表示されていたバッファー履歴がなく、(3) windowにカレントで表示されているバッファーがthis-bufferと等しい場合のみウィンドウの削除を試みます。windowがアトミックウィンドウ(アトミックウィンドウを参照)の一部の場合には、quitはかわりにそのアトミックウィンドウのルートウィンドウの削除を試みます。いずれのケースにおいてもwindowが削除できない場合は、エラーのシグナルの回避を試みます。

obufferがリストでprev-bufferがまだ生きていたら、quitすることによってobufferの残りの要素に応じたwindowprev-bufferが表示されます。これにはthis-bufferを表示するために一時的にリサイズされていた場合にウィンドウをheightにリサイズすることが含まれます。

それ以外の場合には、以前に別のバッファーの表示にwindowが使用されていれば(ウィンドウのヒストリーを参照)、その履歴中でもっとも最近のバッファーが表示される。

以下のオプションはウィンドウを1つ含むフレームで、そのウィンドウをquitする際に正しく事を行うための関数を指定します。

User Option: frame-auto-hide-function

このオプションで指定された関数は自動的にフレームを隠すために呼び出される。この関数はフレームを唯一の引数として呼び出される。

ここで指定される関数は選択されたウィンドウが専用(dedicated)であり、かつバリーされるバッファーを表示しているときにbury-buffer (バッファーリストを参照)から呼び出される。またquitされるウィンドウのフレームがそのウィンドウのバッファーを表示するために特別に作成されたフレームで、かつそのバッファーがkillされないときにもquit-restore-window (上記)から呼び出される。

デフォルトではiconify-frame (フレームの可視性を参照)を呼び出す。かわりにフレームをディスプレイから削除するdelete-frame (フレームの削除を参照)、フレームを不可視にするmake-frame-invisible、フレームを変更せずに残すignore、またはフレームを唯一の引数とする任意の関数のいずれかを指定できる。

このオプションで指定された関数は指定されたフレームが生きたウィンドウただ1つを含み、かつ同一端末上に少なくとも1つ他のフレームが存在する場合のみ呼び出されることに注意。

特定のフレームにたいしてここで指定した値は、そのフレームのフレームパラメーターauto-hide-functionでオーバーライドされるかもしれない(フレームとの相互作用のためのパラメーターを参照)。


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

29.17 サイドウィンドウ

サイドウィンドウ(side window)とは、フレームのルートウィンドウ(ウィンドウとフレームを参照)の4辺のいずれかに位置する特別なウィンドウです。これは実際にはフレームのルートウィンドウ領域は、メインウィンドウとメインウィンドウ周囲のいくつかのサイドウィンドウに分割されることを意味します。メインウィンドウは“通常”の生きたウィンドウ、またはすべての通常ウィンドウを含んだ領域を指定します。

この形式のもっともシンプルな使用では、サイドウィンドウによって特定のバッファーを常にフレームの同一領域に表示することが可能です。したがってこれはdisplay-buffer-at-bottom (バッファー表示用のアクション関数を参照)によって提供される概念を残りのサイド(訳注: 下辺以外)に一般化したものとみなすことができます。しかし適切にカスタマイズすることにより、いわゆる統合開発環境(IDE)で見い出されるようなフレームレイアウトを提供するためにも、サイドウィンドウを使用できます。


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

29.17.1 サイドウィンドウへのバッファーの表示

以下のdisplay-buffer (バッファー表示用のアクション関数を参照)用のアクション関数は特定のバッファーを表示するためにサイドウィンドウの作成や再利用を行います。

Function: display-buffer-in-side-window buffer alist

この関数は選択されたフレームのサイドウィンドウにbufferを表示する。bufferの表示に使用したウィンドウをリターンする。そのようなウィンドウが見つからない、または作成できなければnilをリターンする。

alistdisplay-bufferの場合と同様のシンボルと値からなる連想リスト。alist内で以下のシンボルはこの関数では特別な意味をもつ:

side

ウィンドウを配置するフレームのサイド(側面)を表す。有効な値はlefttoprightbottom。未指定ならウィンドウはフレームの底部(bottom)に配置される。

slot

指定したウィンドウを配置するサイドのスロットを表す。値0は指定したサイドのおおよそ中央にウィンドウを配置する。負の値は中央スロットの前(上方か左方)、正の値は中央スロットの後(下方か右方)を意味する。つまり特定のサイド上にあるすべてのウィンドウはslotの値の順になる。未指定ならウィンドウは指定したサイドの中央に配置される。

dedicated

サイドウィンドウにたいしては、dedicatedフラグ(専用のウィンドウを参照)は若干異なる意味をもつ。他のアクション関数によりdisplay-bufferがそのウィンドウを使用することを防ぐために、サイドウィンドウ作成時にそのフラグは値sideにセットされる。この値はquit-windowkill-bufferprevious-buffernext-buffer呼び出しの間保たれる。

一度セットアップされれば、サイドウィンドウにたいするswitch-to-prev-bufferswitch-to-next-buffer (ウィンドウのヒストリーを参照)の挙動も変更されます。特にサイドウィンドウでは、これらのコマンドは以前にそのウィンドウに表示されたことのないバッファーの表示を抑制します。さらにすでにサイドウィンドウに表示されているバッファーの、通常の非サイドウィンドウでの表示も抑制します。後者ルールの明記するべき例外は、アプリケーションがバッファー表示後にバッファーのローカル変数をリセットしたときに発生します。quit-windowkill-bufferが常に削除して、最終的にprevious-buffernext-bufferの使用を防ぐためにこれらの規則をオーバーライドするには、この値にtをセットするか、display-buffer-mark-dedicatedを通じて値を指定してください。

同一サイドの同一スロットに2つ以上の異なるバッファーすると、最後に表示されたバッファーが対応するウィンドウに表示される。したがってバッファー間で同じサイドウィンドウを共有するためにスロットを使用できる。

この関数はパラメーターwindow-sidewindow-slotをインストールして永続化する(ウィンドウのパラメーターを参照)。alist内のwindow-parametersエントリーを通じて明示的に提供されない限り、他のウィンドウパラメーターは何もインストールしない。

デフォルトではサイドウィンドウはsplit-window (ウィンドウの分割を参照)で分割できません。さらにサイドウィンドウはアクションのターゲットとして明示的に指定されていなければ、バッファーディスプレイアクション(バッファー表示用のアクション関数を参照)によって再利用や分割されることはありません。delete-other-windowsはサイドウィンドウをフレーム上で唯一ののウィンドウにできないことにも注意してください(ウィンドウの削除を参照)。


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

29.17.2 サイドウィンドウのオプションと関数

以下のオプションはサイドウィンドウ配置において更なる制御を提供します。

User Option: window-sides-vertical

nilならフレームの左右のサイドウィンドウはフレームの全高さを占有する。それ以外ならフレームの上下のサイドウィンドウはフレームの全幅を占有する。

User Option: window-sides-slots

このオプションはフレーム各サイドのサイドウィンドウの最大数を指定する。値は各フレームのサイドウィンドウのスロット数を左辺、上辺、右辺、下辺の順で指定する4要素のリスト。要素が数値なら対応するサイドで表示できる最大のウィンドウ数を意味する。要素がnilならそのサイドのスロット数に制限がないことを意味する。

指定された値のいずれかが0なら、対応するサイドへのウィンドウは作成できない。この場合にはdisplay-buffer-in-side-windowはエラーをシグナルしないがnilをリターンする。指定した値が単にサイドウィンドウの追加作成を禁止する場合には、そのサイド上にあるもっとも適したウィンドウが再利用されて、それに応じてウィンドウのwindow-slotも変更される。

User Option: window-sides-reversed

このオプションは上や下のサイドウィンドウが逆順で表示されるかどうかを指定する。nilならフレームの上や下にあるサイドウィンドウはスロット値の増加にともない常に左から右に描画される。tなら描画順は反転してフレームの上や下にあるサイドウィンドウはスロット値の増加にともない右から左に描画される。

これがbidiなら描画順はフレームのメインウィンドウ内でもっとも最近選択されたウィンドウに表示されるバッファーのbidi-paragraph-direction (双方向テキストの表示を参照)の値がright-to-leftの場合のみ逆順になる。このウィンドウを見つけるのが困難なときがあるかもしれないので、別のウィンドウ選択時に意図せず描画順が変更されることを避けるために経験則が使用される。

フレームの左右にあるサイドウィンドウのレイアウトは、この変数の値から影響を受けない。

以下の関数はサイドウィンドウをもつフレームのメインウィンドウをリターンします。

Function: window-main-window &optional frame

この関数は指定したframeのメインウィンドウをリターンする。オプション引数frameは生きたフレームでなければならず、デフォルトは選択されたフレーム。

frameにサイドウィンドウがなければframeのルートウィンドウをリターンする。それ以外ならframe上にある他のすべての非サイドウィンドウの系統元であるようなサイドウィンドウではない内部ウィンドウ、またはframeの単一の生きた非サイドウィンドウのいずれか。フレームのメインウィンドウはdelete-windowで削除できないことに注意。

以下のコマンドは指定したフレーム上にあるすべてのサイドウィンドウの外観を手軽にトグル(toggle: オンとオフを切り替える)できます。

Command: window-toggle-side-windows &optional frame

この関数は指定されたframeのサイドウィンドウをトグルする。オプション引数frameは生きたフレームでなければならずデフォルトは選択されたframe

frameに少なくとも1つのサイドウィンドウがあれば、このコマンドはframeのルートウィンドウの状態をframewindow-stateパラメーターに保存して、その後にframeのサイドウィンドウをすべて削除する。

frameにサイドウィンドウがなく、しかしwindow-stateパラメーターがあれば、このコマンドはパラメーターの値を使用してframeのメインウィンドウを残しつつframeのサイドウィンドウをリストアする。

frameにサイドウィンドウがなく保存した状態も見つからなければエラーをシグナルする。


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

29.17.3 サイドウィンドウによるフレームのレイアウト

サイドウィンドウは統合開発環境(IDE)が提供するような、より複雑なフレームレイアウトの作成に使用できます。そのようなレイアウトでは通常の編集アクティビティが行われるのはメインウィンドウ領域になります。サイドウィンドウは通常の意味においての編集は意図していません。それよりはカレント編集アクティビティを補足するためのファイルやタグやバッファーのリスト、ヘルプ情報、検索やgrepの結果、シェル出力などの情報の表示を意図しています。

そのようなフレームのレイアウトは以下のような外観になるでしょう:

     ___________________________________
    |          *Buffer List*            |
    |___________________________________|
    |     |                       |     |
    |  *  |                       |  *  |
    |  d  |                       |  T  |
    |  i  |                       |  a  |
    |  r  |   Main Window Area    |  g  |
    |  e  |                       |  s  |
    |  d  |                       |  *  |
    |  *  |                       |     |
    |_____|_______________________|_____|
    | *help*/*grep*/  |  *shell*/       |
    | *Completions*   |  *compilation*  |
    |_________________|_________________|
    |             Echo Area             |
    |___________________________________|


以下は上図フレームレイアウトを作成するコードをセットアップするためにdisplay-buffer-in-side-windowとともにウィンドウパラメーター(see ウィンドウのパラメーター) を使用する方法を説明するための例です。

(defvar parameters
  '(window-parameters . ((no-other-window . t)
                         (no-delete-other-windows . t))))

(setq fit-window-to-buffer-horizontally t)
(setq window-resize-pixelwise t)

(setq
 display-buffer-alist
 `(("\\*Buffer List\\*" display-buffer-in-side-window
    (side . top) (slot . 0) (window-height . fit-window-to-buffer)
    (preserve-size . (nil . t)) ,parameters)
   ("\\*Tags List\\*" display-buffer-in-side-window
    (side . right) (slot . 0) (window-width . fit-window-to-buffer)
    (preserve-size . (t . nil)) ,parameters)
   ("\\*\\(?:help\\|grep\\|Completions\\)\\*"
    display-buffer-in-side-window
    (side . bottom) (slot . -1) (preserve-size . (nil . t))
    ,parameters)
   ("\\*\\(?:shell\\|compilation\\)\\*" display-buffer-in-side-window
    (side . bottom) (slot . 1) (preserve-size . (nil . t))
    ,parameters)))

これは固定化された名前をもつバッファーにたいしてdisplay-buffer-alistエントリー(バッファーを表示するウィンドウの選択を参照)を指定します。特にフレーム上辺に高さ調節可能な*Buffer List*と、フレーム右辺に幅調節可能な*Tags List*の表示を要求します。さらにフレーム下辺左側のウィンドウでバッファー*help**grep**Completions*の共有、フレーム下辺右側のウィンドウではバッファー*shell**compilation*の表示を要求します。

ウィンドウの水平調節を可能にするためにオプションfit-window-to-buffer-horizontallyが非nil値をもたなければならないことに注意してください。フレームの上下にあるサイドウィンドウの高さとフレームの左右にあるサイドウィンドウの幅を保持するためのエントリーも追加しています。フレーム最大化時にサイドウィンドウがそれに応じたサイズを維持することを保証するために、変数window-resize-pixelwiseに非nil値をセットしています。ウィンドウのリサイズを参照してください。

最後のフォームではこれらの各ウィンドウにno-other-windowパラメーターをインストールすることによって、作成したサイドウィンドウにたいするC-x oを介してアクセスできないことも保証しています。さらにこれらの各ウィンドウにno-delete-other-windowsパラメーターをインストールして、C-x 1によるサイドウィンドウの削除ができないことを保証しています。

diredバッファーは固定化された名前をもたないので、フレーム左辺の細いディレクトリーバッファーを表示するためにスペシャル関数dired-default-directory-on-leftを使用しています。

(defun dired-default-directory-on-left ()
  "左側サイドウィンドウに詳細を隠して`default-directory'を表示する。"
  (interactive)
  (let ((buffer (dired-noselect default-directory)))
    (with-current-buffer buffer (dired-hide-details-mode t))
    (display-buffer-in-side-window
     buffer `((side . left) (slot . 0)
              (window-width . fit-window-to-buffer)
              (preserve-size . (t . nil)) ,parameters))))

これまでのフォームを評価して任意の順序でM-x list-buffersC-h fM-x shellM-x list-tagsM-x dired-default-directory-on-leftを評価すれば上図のフレームレイアウトが再作成されるはずです。


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

29.18 アトミックウィンドウ

アトミックウィンドウ(atomic window)とは少なくとも2つ以上の生きたウィンドウから組成された矩形領域であり以下のような特性をもちます:

  • アトミックウィンドウの構成にたいして関数split-window (ウィンドウの分割を参照)を適用するとアトミックウィンドウ外部に新たなウィンドウの作成を試みる。
  • アトミックウィンドウの構成にたいして関数delete-window (ウィンドウの削除を参照)を適用するとアトミックウィンドウ全体の削除を試みる。
  • アトミックウィンドウの構成にたいして関数delete-other-windows (ウィンドウの削除を参照)を適用するとアトミックウィンドウによるフレームの充填、またはメインウィンドウ化を試みる(サイドウィンドウを参照)。

これはウィンドウ構造を変更する基本的な関数グループはアトミックウィンドウを生きたウィンドウのように扱い、それゆえアトミックウィンドウ内部の構造を保持することを意味しています。

アトミックウィンドウはファイルのリビジョン間の差異、異なる言語やマークアップでの同一テキストの表示のように、関連するバッファーを特定のマナーにしたがって同時に表示する際にのみ有意義なウィンドウレイアウトの構築と保持に有用です。特定のウィンドウの側面上のバーでウィンドウの情報を永続的に表示するためにも使用できます。

アトミックウィンドウは予約済みのウィンドウパラメーターwindow-atom (ウィンドウのパラメーターを参照)の助けを借りて実装されていて、内部ウィンドウ(Emacsウィンドウの基本概念を参照)はアトミックウィンドウのルートウィンドウと呼ばれます。同じアトミックウィンドウの一部であるようなすべてのウィンドウは共通の祖先としてこのルートウィンドウをもち、window-atomパラメーターに非nilが割り当てられます。

以下の関数は指定したウィンドウを一部とするアトミックウィンドウのルートをリターンします:

Function: window-atom-root &optional window

この関数はwindowを一部とするようなアトミックウィンドウのルートウィンドウをリターンする。windowには有効なウィンドウを指定しなければならず、デフォルトは選択されたウィンドウ。windowがアトミックウィンドウの一部でなければnilをリターンする。

アトミックウィンドウを新たに作成するには既存の内部ウィンドウを選んで以下の関数を適用するのがもっともシンプルなアプローチです:

Function: window-make-atom window

この関数はwindowをアトミックウィンドウに変換する。windowには内部ウィンドウを指定しなければならない。この関数が行うのはwindowの子孫それぞれのwindow-atomパラメーターにtをセットすることだけである。

既存の生きたウィンドウから新たにアトミックウィンドウを作成したり、既存のアトミックウィンドウに新たにウィンドウを追加するには、以下のバッファーディスプレイアクション関数を使用できます(バッファー表示用のアクション関数を参照):

Function: display-buffer-in-atom-window buffer alist

この関数は既存のウィンドウと組み合わせてアトミックウィンドウを形成することになる新たなウィンドウ内でbufferを表示する。既存のウィンドウがすでにアトミックウィンドウの一部なら、そのアトミックウィンドウに新たなウィンドウを追加する。

alistにはシンボルと値からなる連想リストを指定する。以下は特別な意味をもつシンボル:

window

このような要素は新たなウィンドウを組み合わせる既存のウィンドウを指定する。内部ウィンドウを指定すると、そのウィンドウのすべての子ウィンドウもアトミックウィンドウの一部になる。ウィンドウを何も指定しなければ新たなウィンドウは選択されたウィンドウの兄弟ウィンドウになる。既存ウィンドウのwindow-atomパラメーターはそれが生きたウィンドウであり、かつwindow-atomがすでにセット済みでなければmainにセットされる。

side

このような要素は既存ウィンドウで新たなウィンドウが配置されるサイドを表す。有効な値はbelowrightaboveleft。デフォルトはbelow。この値は新たなウィンドウのwindow-atomパラメーターにセットされる。

リターン値は新たなウィンドウ、ウィンドウ作成に失敗するとnil

nilである限りwindow-atomパラメーターの値は問題ではないことに注意してください。display-buffer-in-atom-windowが割り当てる値は、関数の適用後に元のウィンドウと新たなウィンドウを簡単に取得することだけが目的です。display-buffer-in-atom-windowが割り当てるウィンドウパラメーターはwindow-atomパラメーターだけであることにも注意してください。それ以外のパラメーターはalist内のwindow-parametersエントリーを介してアプリケーションがセットする必要があります。

アトミックウィンドウはそれを構成するウィンドウのいずれかが削除された際には存在を終えます。アトミックウィンドウを手動で分解するためには、それを構成するウィンドウ(アトミックウィンドウのルートウィンドウと子孫)のwindow-atomパラメーターをリセットしてください。

以下のスニペットコードを単一ウィンドウのフレームに適用すると、最初に選択されたウィンドウを分割して選択されたウィンドウと新たなウィンドウの親をルートとしてアトミックウィンドウを構成します。それからフレーム下辺にある新たなウィンドウでバッファー*Messages*を表示して、新たなウィンドウを作成したアトミックウィンドウの一部にします。

(let ((window (split-window-right)))
  (window-make-atom (window-parent window))
  (display-buffer-in-atom-window
   (get-buffer-create "*Messages*")
   `((window . ,(window-parent window)) (window-height . 5))))

この時点においてフレーム内の任意のウィンドウでC-x 2をタイプすると、フレーム下辺に新たなウィンドウが作成されます。かわりにC-x 3をタイプすれば新たなウィンドウはフレーム右辺に配置されるでしょう。いずれのケースでもここでアトミックウィンドウ内の任意のウィンドウでC-x 1をタイプすると、新たなウィンドウだけが削除されます。アトミックウィンドウ内の任意のウィンドウでC-x 0をタイプすればフレームは新たなウィンドウで充填されるでしょう。


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

29.19 ウィンドウとポイント

それぞれのウィンドウは独自のポイント値(ポイントを参照)をもち、同じバッファーを表示する他のウィンドウの間でも、ポイント値はそれぞれ独立しています。これは1つのバッファーを複数ウィンドウで表示するのに有用です。

  • ウィンドウポイント(window point)は、ウィンドウが最初に作成されたときに設定される。ウィンドウポイントはバッファーのポイント、またはそのバッファーからオープンされたウィンドウがあればそのウィンドウのウィンドウポイントにより初期化される。
  • ウィンドウの選択により、ウィンドウのポイント値からそのバッファーのポイント値がセットされる。反対にウィンドウの非選択により、ウィンドウのポイント値にバッファーのポイント値がセットされる。つまり与えられたバッファーを表示するウィンドウ間で切り替えを行ったときには、そのバッファーでは選択されたウィンドウのポイント値が効力をもつが、他のウィンドウのポイント値はそのウィンドウに格納される。
  • 選択されたウィンドウがカレントバッファーの表示を続ける限り、そのウィンドウのポイントとバッファーのポイントは常に連動して移動して等しく保たれる。

デフォルトではEmacsは塗りつぶした矩形ブロックで各ウィンドウのポイント位置にカーソルを表示します。あるウィンドウでユーザーが別のバッファーに切り替えた際には、そのウィンドウのカーソルはそのバッファーのポイント位置に移動します。display文字列やイメージ等の何らかのディスプレイ要素により正確な位置が隠れている場合には、Emacsはそのdisplay要素の直前か直後にカーソルを表示する。

Function: window-point &optional window

この関数はwindow内のカレントのポイント位置をリターンする。選択されていないウィンドウでは、そのウィンドウが選択された場合の、(そのウィンドウのバッファーの)ポイント値である。windowにたいするデフォルトは選択されたウィンドウ。

windowが選択されたウィンドウのときのリターン値は、そのウィンドウのバッファーのポイント値。厳密にはすべてのsave-excursionフォームの外側のトップレベルのポイント値のほうがより正確であろう。しかしこの値は見つけるのが困難である。

Function: set-window-point window position

この関数はwindow内のポイントをwindowのバッファー内の位置positionに配置する。リターン値はposition

windowが選択されていれば単にwindow内でgoto-charを行う。

Variable: window-point-insertion-type

この変数はwindow-pointのマーカー挿入型(マーカーの挿入タイプを参照)を指定する。デフォルトはnilで、window-pointは挿入されたテキストの後に留まるだろう。


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

29.20 ウィンドウの開始位置と終了位置

ウィンドウはそれぞれバッファー位置を追跡するために、バッファー内で表示を開始すべき位置を指定するマーカーを保守しています。この位置はそのウィンドウのdisplay-start(表示開始)、または単にstart(開始)と呼ばれます。この位置の後の文字がウィンドウの左上隅に表示される文字となります。これは通常はテキスト行の先頭になりますが必須ではありません。

ウィンドウやバッファーの切り替え後やいくつかのケースにおいては、ウィンドウが行の途中で開始される場合にEmacsがィンドウの開始を行の開始に調整します。これは行中で無意味な位置のウィンドウ開始のまま特定の操作が行われるのを防ぐためです。この機能はLispモードのコマンドを使用して実行することによりある種のLispコードをテストする場合には、それらのコマンドがこの再調整を誘発してしまうので邪魔かもしれません。そのようなコードをテストするためには、それをコマンド内に記述して何らかのキーにバインドしてください。

Function: window-start &optional window

この関数はウィンドウwindowの表示開始位置をリターンする。windownilなら選択されたウィンドウが使用される。

ウィンドウを作成したり他のバッファーをウィンドウ内に表示する際、display-start位置は同じバッファーにたいしてもっとも最近に使用されたdisplay-start位置、そのバッファーがそれをもたなければpoint-minにセットされる。

ポイントがスクリーン上に確実に現れるように、再表示はwindow-start位置を更新する(前の再表示以降にwindow-start位置を明示的に指定していない場合)。再表示以外にwindow-start位置を自動的に変更するものはない。ポイントを移動した場合には、次の再表示後までポイントの移動に応じてwindow-startが変更されることを期待してはならない。

Function: window-group-start &optional window

この関数はwindow-startと同様だが、windowがウィンドウグループ(Window Groupを参照)の一部なら、window-group-startはグループ全体の開始位置をリターンする点が異なる。この条件はバッファーローカル変数window-group-start-functionに関数がセットされている際に保持される。この場合には、window-group-startはその関数を単一の引数windowで呼び出して結果をリターンする。

Function: window-end &optional window update

この関数はwindowのバッファーの最後を表示する位置をリターンする。windowにたいするデフォルトは選択されたウィンドウ。

バッファーテキストの単なる変更やポイントの移動ではwindow-endがリターンする値は更新されない。この値はEmacsが再表示を行って、妨害されることなく再表示が完了したときのみ更新される。

windowの最後の再表示が妨害されて完了しなかったら、Emacsはそのウィンドウ内の表示のend位置を知らない。関数はこの場合はnilをリターンする。

updateが非nilなら、window-endwindow-startのカレント値にもとづき、どこが表示のendなのか最新の値をリターンする。以前に保存された位置の値がまだ有効なら、window-endはその値をリターンする。それ以外はバッファーのテキストをスキャンして正しい値を計算する。

たとえupdateが非nilであっても、window-endはポイントが画面外に移動した場合に実際の再表示が行うような表示のスクロールを試みない。これはwindow-startの値を変更しない。これは実際にはスクロールが要求されない場合の表示されたテキストのendがどこかを報告する。リターンされる位置は部分的に可視なだけかもしれないことに注意。

Function: window-group-end &optional window update

この関数はwindow-endと同様だが、windowがウィンドウグループ(Window Groupを参照)の一部なら、window-group-endはグループ全体の終了位置をリターンする点が異なる。この条件はバッファーローカル変数window-group-end-functionに関数がセットされている際に保持される。この場合には、window-group-endはその関数を2つの引数windowupdateで呼び出して結果をリターンする。引数updatewindow-endの場合と同じ意味をもつ。

Function: set-window-start window position &optional noforce

この関数はwindowのdisplay-start位置をwindowのバッファーのpositionにセットする。リターン値はposition

表示ルーチンはバッファーが表示されたときにポイント位置が可視になることを強要する。通常これらは内部ロジックに応じてポイントを可視にするためにdisplay-start位置を選択(および必要ならつまりウィンドウをスクロール)する。しかしこの関数でnoforcenilを使用してstart位置を指定した場合は、たとえポイントを画面外になるような場所に配置したとしても、positionでの表示開始を望んでいることを意味する。これによりポイントが画面外に配置されると、表示ルーチンはポイントをウィンドウ内の中央行の左マージンに移動しようと試みる。

たとえばポイントが1のときにウィンドウのstartを次行の開始37にセットすると、ポイントはウィンドウの最上端より上になるだろう。表示ルーチンは再表示が発生したときにポイントが1のままならポイントを動かすことになる。以下は例:

;; 以下は式set-window-start実行前
;;   fooの様子

---------- Buffer: foo ----------
∗This is the contents of buffer foo.
2
3
4
5
6
---------- Buffer: foo ----------

(set-window-start
 (selected-window)
 (save-excursion
   (goto-char 1)
   (forward-line 1)
   (point)))
⇒ 37

;; 以下は式set-window-start実行後の
;;   foo’の様子
---------- Buffer: foo ----------
2
3
∗4
5
6
---------- Buffer: foo ----------

ポイントを可視(つまり完全に可視なスクリーン行内にポイントを配置)にする試みが失敗すると、表示ルーチンは要求されたwindow-start位置を無視して、とにかく新しい位置を計算する。したがってこの関数を呼び出すLispプログラムが信頼できる結果を得るためには、表示がpositionで始まるウィンドウ内部に常にポイントを移動すること。

noforceが非nilで、かつ次回の再表示でポイントが画面外に配される場合、再表示はポイントと協調して機能する位置となるような新たなwindow-startを計算するので、positionは使用されない。

Function: set-window-group-start window position &optional noforce

この関数はset-window-startと同様だが、windowがウィンドウグループ(Window Groupを参照)の一部なら、set-window-group-startはグループ全体の開始位置をリターンする点が異なる。この条件はバッファーローカル変数set-window-group-start-functionに関数がセットされている際に保持される。この場合には、set-window-group-startはその関数を3つの引数windowpositionnoforceで呼び出して結果をリターンする。この関数の引数positionnoforceset-window-startの場合と同じ意味をもつ。

Function: pos-visible-in-window-p &optional position window partially

この関数はwindow内のpositionが画面上カレントで可視のテキスト範囲内にあれば非nilpositionが表示範囲のスクロール外にあればnilをリターンする。partiallynilなら部分的に不明瞭な位置は可視とは判断されない。引数positionのデフォルトはwindow内のポイントのカレント位置、windowのデフォルトは選択されたウィンドウ。positiontなら、それはwindowの最後に可視だった行の位置、またはEOB(end-of-buffer: バッファー終端位置のいずれか前方になる位置をチェックすることを意味する。

この関数は垂直スクロールだけを考慮する。positionが表示範囲外にある理由が、windowが水平にスクロールされただけなら、いずれにせよpos-visible-in-window-pは非nilをリターンする。水平スクロールを参照のこと。

positionが可視でpartiallynilなら、pos-visible-in-window-ptをリターンする。partiallyが非nilposition以降の文字が完全に可視なら、(x y)という形式のリストをリターンする。ここでxyはウィンドウの左上隅からの相対的なピクセル座標。position以降の文字が完全に可視ではなければ、拡張された形式のリスト(x y rtop rbot rowh vpos)をリターンする。ここでrtoprbotpositionでウィンドウ外となった上端と下端のピクセル数、rowhはその行の可視な部分の高さ、vposはその行の垂直位置(0基準の行番号)を示す。

以下は例:

;; ポイントが画面外ならrecenterする
(or (pos-visible-in-window-p
     (point) (selected-window))
    (recenter 0))
Function: pos-visible-in-window-group-p &optional position window partially

この関数はpos-visible-in-window-pと同様だが、windowがウィンドウグループ(Window Groupを参照)の一部なら、pos-visible-in-window-group-pwindow単独ではなく、グループ全体でposの可視性をテストする点が異なる。この条件はバッファーローカル変数pos-visible-in-window-group-p-functionに関数がセットされている際に保持される。この場合には、pos-visible-in-window-group-pはその関数を3つの引数positionwindowpartiallyで呼び出して結果をリターンする。この関数の引数positionpartiallypos-visible-in-window-pの場合と同じ意味をもつ。

Function: window-line-height &optional line window

この関数はwindow内のテキスト行lineの高さをリターンする。lineheader-linemode-linewindow-line-heightのいずれかなら、そのウィンドウの対応する行についての情報をリターンする。それ以外では、lineは0から始まるテキスト行番号。負数ならそのウィンドウのendから数える。lineにたいするデフォルトはwindow内のカレント行、windowにたいするデフォルトは選択されたウィンドウ。

表示が最新でなければwindow-line-heightnilをリターンする。その場合には関連する情報を入手するためにpos-visible-in-window-pを使用できる。

指定されたlineに対応する行がなければ、window-line-heightnilをリターンする。それ以外では、リスト(height vpos ypos offbot)をリターンする。ここでheightはその行の可視部分のピクセル高さ、vposyposは最初のテキスト行上端からのその行への相対的な垂直位置の行数とピクセル数、offbotはそのテキスト行下端のウィンドウ外のピクセル数。(最初の)テキスト行上端にウィンドウ外のピクセルがある場合にはyposは負となる。


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

29.21 テキスト的なスクロール

テキスト的なスクロール(textual scrolling)とは、ウィンドウ内のテキストを上や下に移動することを意味します。これはそのウィンドウのdisplay-startを変更することにより機能します。これはポイントを画面上に維持するためにwindow-pointの値も変更するかもしれません(ウィンドウとポイントを参照)。

テキスト的なスクロールの基本的な関数は、(前方にスクロールする) scroll-up、および(後方にスクロールする) scroll-downです。これらの関数の名前の“up”と“down”は、バッファーテキストのそのウィンドウにたいする相対的な移動方向を示しています。そのテキストが長いロール紙に記述されていて、スクロールコマンドはその上を上下に移動すると想像してみてください。つまりバッファーの中央に注目している場合には、繰り返してscroll-downを呼び出すと最終的にはバッファーの先頭を目にすることになるでしょう。

これは残念なことに時折混乱を招きます。なぜならある人はこれを逆の慣習にもとづいて考える傾向があるからです。彼らはテキストがその場所に留まりウィンドウが移動して、“down”コマンドによりバッファー終端に移動するだろうと想像します。この慣習はそのようなコマンドが現代風のキーボード上のPageDownという名前のキーにバインドされているという事実と一致しています。

選択されたウィンドウ内で表示されているバッファーがカレントバッファーでなければ、(scroll-other-window以外の)テキスト的スクロール関数の結果は予測できません。カレントバッファーを参照してください。

(たとえば大きなイメージがある等で)ウィンドウにウィンドウの高さより高い行が含まれる場合には、スクロール関数は部分的に可視な行をスクロールするためにそのウィンドウの垂直スクロール位置を調整します。Lisp呼び出し側は変数auto-window-vscrollnilにバインドすることにより、この機能を無効にできます(割り合いによる垂直スクロールを参照)。

Command: scroll-up &optional count

この関数は選択されたウィンドウ内でcount行前方にスクロールする。

countが負ならかわりに後方へスクロールする。countnil (または省略)ならスクロールされる距離は、そのウィンドウのボディーの高さより小さいnext-screen-context-linesとなる。

この関数は選択されたウィンドウがそれ以上スクロールできなければエラーをシグナルして、それ以外はnilをリターンする。

Command: scroll-down &optional count

この関数は選択されたウィンドウ内でcount行後方にスクロールする。

countが負ならかわりに前方へスクロールする。それ以外の点ではこれはscroll-upと同様に振る舞う。

Command: scroll-up-command &optional count

これはscroll-upと同様に振る舞うが選択されたウィンドウがそれ以上スクロールできず、かつ変数scroll-error-top-bottomの値がtなら、かわりにそのバッファーの終端への移動を試みる。ポイントがすでに終端にあればエラーをシグナルする。

Command: scroll-down-command &optional count

これはscroll-downと同様に振る舞うが選択されたウィンドウがそれ以上スクロールできず、かつ変数scroll-error-top-bottomの値がtなら、かわりにそのバッファーの先頭への移動を試みる。ポイントがすでに先頭にあればエラーをシグナルする。

Command: scroll-other-window &optional count

この関数は他のウィンドウ内のテキストを上方にcount行スクロールする。countが負かnilならscroll-upのように処理される。

変数other-window-scroll-bufferにバッファーをセットすることにより、どのバッファーをスクロールするかを指定できる。そのバッファーが表示されていなければ、scroll-other-windowはそれを何らかのウィンドウにそれを表示する。

選択されたウィンドウがミニバッファーのとき、次ウィンドウは通常はそのウィンドウの直上最左のウィンドウである。変数minibuffer-scroll-windowをセットすることにより、スクロールする別のウィンドウを指定できる。この変数はミニバッファー以外のウィンドウが選択されているときは効果がない。これが非nil、かつミニバッファーが選択されているときにはother-window-scroll-bufferより優先される。Definition of minibuffer-scroll-windowを参照のこと。

Command: scroll-other-window-down &optional count

この関数は他のウィンドウ内のテキストを下方にcount行スクロールする。countが負かnilならscroll-downのように処理される。それ以外の点においてはscroll-other-windowと同様の方法で振る舞う。

Variable: other-window-scroll-buffer

この変数が非nilなら、それはscroll-other-windowがどのバッファーのウィンドウをスクロールするかを指定する。

User Option: scroll-margin

このオプションはスクロールマージン(ポイントとウィンドウの上端/下端との最小行数)のサイズを指定する。ポイントがウィンドウの上端/下端からその行数になったとき、(可能なら)再表示はポイントをそのマージン外のウィンドウ中央付近に移動するためにテキストを自動的にスクロールする。

User Option: maximum-scroll-margin

この変数はscroll-marginの実効値をカレントウィンドウの行高さの割合に制限する。たとえばカレントウィンドウが20行でmaximum-scroll-marginが0.1なら、scroll-marginがどれほど大きくてもスクロールマージンが2より大きくなることはない。

maximum-scroll-margin自体は最大値として0.5という値をもち、これはウィンドウの中央行(ウィンドウが偶数行なら中央の2行)までカーソルを維持するためにマージンを大きくセットすることを可能にする。大きな値(または0.0から0.5までの浮動小数点数以外の値)をセットするとデフォルト値0.25がかわりに使用される。

User Option: scroll-conservatively

この変数はポイントがスクリーン外(またはスクロールマージン内)に移動したときに自動的にスクロールを行う方法を指定する。値が正の整数nなら再表示はそれが正しい表示範囲内にポイントを戻すなら、いずれかの方向にn行以下のテキストをスクロールする。この振る舞いは保守的なスクロール(conservative scrolling)と呼ばれる。それ以外ならスクロールはscroll-up-aggressivelyscroll-down-aggressivelyのような他の変数の制御の下に通常の方法で発生する。

デフォルトの値は0でこれは保守的スクロールが発生し得ないことを意味する。

User Option: scroll-down-aggressively

この変数の値はnil、または0から1までの小数点数fであること。小数点数ならスクリーン上でポイントが置かれたとき下にスクロールする場所を指定する。より正確にはポイントがウィンドウstartより上という理由でウィンドウが下にスクロールされるときには、新たなstart位置がウィンドウ上端からウィンドウ高さのfの箇所にポイントが置かれるように選択される。より大きなfなら、よりaggressive(積極的)にスクロールする。

その効果はポイントを中央に配置することであり、値nilは.5と等価である。どのような方法によりセットされたときでも、この変数は自動的にバッファーローカルになる。

User Option: scroll-up-aggressively

scroll-up-aggressivelyの場合と同様。値fはポイントがウィンドウ下端からどれほどの位置に置かれるべきかを指定する。つまり、scroll-up-aggressivelyと同様に大きな値ではよりaggressive(積極的)になる。

User Option: scroll-step

この変数はscroll-conservativelyの古い変種である。違いは値がnならn以下の値ではなく、正確にnだけのスクロールを許容することである。この機能はscroll-marginとは共に機能しない。デフォルトは0。

User Option: scroll-preserve-screen-position

このオプションがtなら、スクロールによりポイントがウィンドウ外に移動したとき、Emacsは常にポイントがポイントの上下端ではなくカーソルがそのウィンドウ内の元の垂直位置に保たれるようポイントの調整を試みる。

値が非nilかつ非tなら、たとえスクロールコマンドによりポイントがウィンドウ外に移動していなくとも、Emacsはカーソルが同じ垂直位置に保たれるようにポイントを調整する。

このオプションはシンボルプロパティscroll-commandが非nilであるような、すべてのスクロールコマンドに影響する。

User Option: next-screen-context-lines

この変数の値は全画面スクロールされたときに継続して残される行数を指定する。たとえば引数がnilscroll-upはウィンドウ上端ではなく下端に残される行数でスクロールする。デフォルト値は2

User Option: scroll-error-top-bottom

このオプションがnil(デフォルト)なら、それ以上のスクロールが不可能な際にscroll-up-commandscroll-down-commandは単にエラーをシグナルする。

値がtなら、これらのコマンドはかわりにポイントをバッファーの先頭か終端(スクロール方向に依存する)に移動する。ポイントがすでにその位置にある場合のみエラーをシグナルする。

Command: recenter &optional count redisplay

この関数は選択されたウィンドウ内の指定された垂直位置にポイントを表示するようにウィンドウ内のテキストをスクロールする。これはテキストに応じたポイント移動を行わない。

countが非負の数なら、そのウィンドウ上端からcount行下にポイントを含む行を配置する。countが負ならウィンドウ下端から上に数えるので、-1はそのウィンドウ内で最後の利用可能な行となる。

countnil (または非nilのリスト)なら、recenterはポイントを含む行をウィンドウの中央に配置する。countredisplayが非nilなら、この関数はrecenter-redisplayの値に応じてフレームを再描画するかもしれない。recenter-redisplayが非nilの場合の効果を打ち消すために、したがって2つ目の引数の省略を使用できる。インタラクティブな呼び出しではredisplayに非nilが渡される。

recenterがインタラクティブに呼び出されたときはrawプレフィックス引数がcountとなる。したがってプレフィックスとしてC-uをタイプするとcountに非nilC-u 4ではcountに4がセットされte、後者ではカレント行を上端から4行目にセットする。

引数0ではrecenterはカレント行をウィンドウ上端に配置する。コマンドrecenter-top-bottomはこれを達成するためにより簡便な方法を提供する。

Function: recenter-window-group &optional count

この関数はrecenterと同様だが、選択されたウィンドウがウィンドウグループ(Window Groupを参照)の一部の際には、recenter-window-groupがグループ全体をスクロールする点が異なる。この条件はバッファーローカル変数recenter-window-group-functionが関数にセットされている際に保持される。この場合にはrecenter-window-groupはその関数を引数countで呼び出して結果をリターンする。引数countrecenterの場合と同様の意味をもつが、ウィンドウグループ全体に作用する。

User Option: recenter-redisplay

この変数が非nilなら引数redisplaynil、引数countを非nilrecenterを呼び出すことによりフレームを再描画する。デフォルト値はttyで、これはフレームがttyフレームのときだけフレームを再描画することを意味する。

Command: recenter-top-bottom &optional count

デフォルトではC-lにバインドされているこのコマンドは、recenterと同様に動作するが引数なしで呼び出されたときの動作が異なる。この場合には連続して呼び出すことにより変数recenter-positionsで定義されるサイクル順に応じてポイントを配置する。

User Option: recenter-positions

これはrecenter-top-bottomを引数なしで呼び出したときの挙動を制御する。デフォルト値は(middle top bottom)で、これは引数なしでrecenter-top-bottomを連続して呼び出すとポイントをウィンドウの中央、上端、下端と巡回して配置することを意味する。


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

29.22 割り合いによる垂直スクロール

垂直フラクショナルスクロール(vertical fractional scrolling)とは、指定された値を行に乗ずるることによりウィンドウ内のテキストを上下にシフトすることを意味します。たとえばEmacsはウィンドウより高さが大きいイメージやスクリーン行でこれを使用します。ウィンドウはそれぞれ決して0より小さくなることはない、垂直スクロール位置(vertical scroll position)という数値をもっています。これはコンテンツを表示しているウィンドウにたいして、コンテンツをどこから表示開始(raise)するかを指定します。ウィンドウのコンテンツの表示開始により一般的には上端の何行かのすべて、または一部が表示されなくなり他の何行かのすべて、または一部が下端に表示されるようになります。通常の値は0です。

垂直スクロール位置は行の通常高さ(デフォルトフォントの高さ)の単位で数えられます。したがって値が.5なら、それはウィンドウのコンテンツが通常行の半分の高さで上にスクロール、3.3なら通常行の3倍を若干超える高さで上にスクロールされていることを意味します。

垂直スクロールが覆い隠す(cover)のがどれほどの行断片(fraction of a line)なのか、あるいは行数かはそれらの行に何が含まれるかに依存します。3.3という値により高い行やイメージの一部だけを画面外にスクロールできることもあれば、.5という値が非常に小さい高さの行を画面外にスクロールできることもあります。

Function: window-vscroll &optional window pixels-p

この関数はwindowのカレントの垂直スクロール位置をリターンする。windowのデフォルトは選択されたウィンドウ。pixels-pが非nilならリターン値は通常行高さ単位ではなくピクセル単位で測定される。

(window-vscroll)
     ⇒ 0
Function: set-window-vscroll window lines &optional pixels-p preserve-vscroll-p

この関数はwindowの垂直スクロール位置をlinesにセットする。windownilなら選択されたウィンドウが使用される。引数linesは0または正であること。それ以外は0として扱われる。

実際の垂直スクロール位置は常にピクセルの整数に対応しなければならないため、指定した値はそれに応じて丸められる。

この丸め結果がリターン値となる。

(set-window-vscroll (selected-window) 1.2)
     ⇒ 1.13

pixels-pが非nilならlinesはピクセル数を指定する。この場合にはリターン値はlines

vscrollは通常はminibuffer-scroll-window、あるいはミニバッファーウィンドウのリサイズ時に選択されているウィンドウ(ミニバッファーのウィンドウを参照)のいずれでもないウィンドウには効果がない。この“凍結された挙動”は、preserve-vscroll-pパラメーターが非nilの場合には無効になる。これはvscrollを通常のようにセットすることを意味する。

Variable: auto-window-vscroll

この変数が非nilなら関数line-movescroll-upscroll-downは、たとえば大きなイメージが存在する等でウィンドウ高さより高いディスプレイ行をスクロールするために垂直スクロール位置を自動的に変更するだろう。


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

29.23 水平スクロール

水平スクロール(horizontal scrolling)とは指定された通常文字幅の倍数でウィンドウ内のイメージを左右にシフトすることを意味します。ウィンドウはそれぞれ、決して0より小さくなることはない水平スクロール位置(horizontal scroll position)という数値をもっています。これはコンテンツをどれほど左にシフトするかを指定します。ウィンドウのコンテンツを左にシフトすることにより一般的には左にある文字のすべて、または一部が表示されなくなり右にある文字のすべて、または一部が表示されることを意味します。通常の値は0です。

水平スクロール位置は通常の文字幅を単位として数えられます。したがって値が5なら、それはウィンドウのコンテンツは通常文字幅の5倍左にスクロールされることを意味します。左の何文字が表示されなくなるかは、それらの文字の文字幅とに依存していて、それは行ごとに異なります。

読み取りを行う際には内側のループ(inner loop)で横方向、外側のループ(outer loop)で上から下に読み取るため、水平スクロールの効果はテキスト的スクロールや垂直スクロールとは異なります。テキスト的スクロールは表示するためのテキスト範囲の選択を引き起こし、垂直スクロールはウィンドウコンテンツを連続して移動します。しかし水平スクロールはすべての行の一部をスクリーン外へスクロールします。

通常は水平スクロールは行われないので、ウィンドウ左端には最左列があります。この状態では右スクロールにより左端に新たに表示されるデータは存在しないので、右へのスクロールはできません。左スクロールによってテキストの1列目がウィンドウ端からウィンドウ外にスクロールされ、右端にはその前は切り詰められていた(truncated)列が新たに表示されるので左へのスクロールはできます。ウィンドウが左へ非0の値で水平スクロールされていれば右スクロールしてそれを戻すことができますが、正味の水平スクロールが0に減少するまでの間のみ右スクロールができます。左へどれほどスクロールできるかに制限はありませんが、最終的にはすべてのテキストが左端の外に消えるでしょう。

auto-hscroll-modeがセットされている場合には、再表示はポイントが常に可視となることを保証するために必要に応じて水平スクロールを自動的に変更する。とはいえ依然として水平スクロール位置を明示的に指定するのは可能である。指定した値は自動スクロールの下限値としての役目を果たす(自動スクロールは指定された値より小さい列にウィンドウをスクロールしない)。

auto-hscroll-modeのデフォルト値はtです。これをcurrent-lineにセットするとカーソルのある行だけがポイントが可視になるように水平スクロールされて、ウィンドウの残りはスクロールされないかscroll-leftscroll-right (以下参照)にセットされた最小量だけスクロールされる自動水平スクロールの変種がアクティブになります。

Command: scroll-left &optional count set-minimum

この関数は選択されたウィンドウを左( countが負なら右)にcount列スクロールする。countのデフォルトはウィンドウ幅から2を減じた値。

リターン値はwindow-hscroll(以下参照)がリターンする値と同じように、変更後に実際に左に水平スクロールされたトータル量。

基本方向がR2L(双方向テキストの表示を参照)のパラグラフ内のテキストは、正のcount値でscroll-leftが呼び出された際には右へと移動するように、反対方向に移動することに注意。

ウィンドウを可能な限り右にスクロールした後は、左スクロールの合計が0であるような通常の位置に戻り、右へのそれ以上のスクロールの試みは効果をもたない。

set-minimumが非nilなら新たなスクロール量は自動スクロールの下限値となる。つまり自動スクロールはこの関数がリターンする値より小さい列にウィンドウをスクロールしないだろう。インタラクティブに呼び出すとset-minimumに非nilを渡す。

Command: scroll-right &optional count set-minimum

この関数は選択されたウィンドウを右( countが負なら左)にcount列スクロールする。countのデフォルトはウィンドウ幅から2を減じた値。スクロール方向を除けばこれはscroll-leftと同様に機能する。

Function: window-hscroll &optional window

この関数はwindowの左への水平スクロールのトータル(左マージンを超えて左にスクロールされたwindow内のテキスト列数)をリターンする(R2Lパラグラフでの値はかわりに右方向への総スクロール量となる)。windowのデフォルトは選択されたウィンドウ。

リターン値が負になることは決してない。windowで水平スクロールが行われていない場合(これが通常)にはリターン値は0。

(window-hscroll)
     ⇒ 0
(scroll-left 5)
     ⇒ 5
(window-hscroll)
     ⇒ 5
Function: set-window-hscroll window columns

この関数はwindowの水平スクロールをセットする。columnsの値はスクロール量を左マージン(R2Lパラグラフでは右マージン)からの列数で指定する。引数columnsは0または正の数であること。そうでない場合ニは0とみなされる。小数点数のcolumns値は現在のところサポートされない。

シンプルにM-:を呼び出して評価する方法でテストすると、set-window-hscrollが機能していないように見えるかもしれないことに注意。ここで何が発生しているかというと、この関数は水平スクロール値をセットしてリターンするが、その後にポイントを可視にするために水平スクロールを調整するよう再表示が行なわれて、これが関数の行った処理をオーバーライドしている。この関数の効果は左マージンからポイントまでのスクロール量が、ポイントが可視のまま留まるように関数を呼び出すことにより観察できる。

リターン値はcolumns

(set-window-hscroll (selected-window) 10)
     ⇒ 10

以下は与えられた位置positionが水平スクロールによりスクリーン外にあるかどうかを判断する例です:

(defun hscroll-on-screen (window position)
  (save-excursion
    (goto-char position)
    (and
     (>= (- (current-column) (window-hscroll window)) 0)
     (< (- (current-column) (window-hscroll window))
        (window-width window)))))

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

29.24 座標とウィンドウ

このセクションでは位置とそのウィンドウを報告する関数を説明します。これらの関数のほとんどはウィンドウのフレームのネイティブ位置の原点から相対的な位置を報告します(フレームのジオメトリーを参照)。いくつかの関数はウィンドウのフレームのディスプレイの原点から相対的な位置を報告します。いずれのケースにおいても原点は座標 (0, 0)をもち、X座標とY座標はそれぞれ右方向と下方向で増加します。

以下の関数ではX座標とY座標は整数の文字単位(行数と列数)で報告されます。グラフィカルなディスプレイ上での“行”と“列”はそれぞれ、そのフレームのデフォルトフォントにより指定されるデフォルト文字の高さと幅に対応します(フレームのフォントを参照)。

Function: window-edges &optional window body absolute pixelwise

この関数はwindow端の座標のリストをリターンする。windowが省略またはnilの場合のデフォルトは選択されたウィンドウ。

リターン値は(left top right bottom)という形式をもつ。リストの要素は順にそのウィンドウにより占有される最左列のX座標、最上行のY座標、最右列より1列右のX座標、最下行より1行下のY座標。

これらは装飾すべてを含んだウィンドウの実際の端であることに注意。テキスト端末ではそのウィンドウの右に隣接するウィンドウがあれば、ウィンドウの右端にはそのウィンドウと隣接するウィンドウの間のセパレーターラインが含まれる。

オプション引数bodynilなら、それはwindowの総サイズに対応する端をリターンすることを意味する。bodyが非nilならwindowのボディーの端をリターンすることを意味する。bodyが非nilならwindowには生きたウィンドウを指定しなければならない。

オプション引数absolutenilなら、それはwindowのフレームのネイティブ位置に相対的な端のリターンを意味する。absoluteが非nilならwindowのディスプレイの原点(0, 0)からの相対座標のリターンを意味する。非グラフィカルなシステムではこの引数に効果はない。

オプション引数pixelwisenilなら、それはwindowのフレームのデフォルト文字の幅と高さの単位で座標をリターンすることを意味する。pixelwiseが非nilならピクセル単位で座標をリターンすることを意味する。rightbottomで指定されるピクセルはこれらの端の外側であることに注意。absoluteが非nilなら、pixelwiseも暗黙に非nilとなる。

Function: window-body-edges &optional window

この関数はwindowのボディーの端をリターンする(ウィンドウのサイズを参照)。(window-body-edges window)の呼び出しは(window-edges window t) (上記参照)の呼び出しと等価。

以下の関数は一連のフレーム相対座標(frame-relative coordinates)からウィンドウへの関連付けに使用できます:

Function: window-at x y &optional frame

この関数はframeのネイティブ位置(フレームのジオメトリーを参照)から相対的に、デフォルト文字単位(フレームのフォントを参照)で与えられる座標xyにある生きたウィンドウをリターンする。

その位置にウィンドウがなければリターン値はnilframeが省略またはnilの場合のデフォルトは選択されたフレーム。

Function: coordinates-in-window-p coordinates window

この関数はウィンドウwindowがフレーム相対座標coordinatesを占有するかどうかをチェックして、もしそうならウィンドウのどの部分かをチェックする。windowは生きたウィンドウであること。

coordinates(x . y)という形式のコンスセルであること。ここでxywindowのフレームのネイティブ位置(フレームのジオメトリーを参照)から相対的に、デフォルト文字サイズ(フレームのフォントを参照)の単位で与えられる。

指定された位置にウィンドウが存在しなければリターン値はnil。それ以外ではリターン値は以下のいずれか:

(relx . rely)

その座標はwindow内にある。数値relxrelyは指定された位置にたいする、ウィンドウ左上隅を原点に0から数えたウィンドウ相対座標と等価。

mode-line

その座標はwindowのモードライン内にある。

header-line

その座標はwindowのヘッダーライン内にある。

tab-line

その座標はwindowのタブライン内にある。

right-divider

その座標はwindowと右に隣接するウィンドウを分けるディバイダー内にある。

bottom-divider

その座標はwindowと下にあるウィンドウを分けるディバイダー内にある。

vertical-line

その座標はwindowと右に隣接するウィンドウを分ける垂直ライン内にある。この値はウィンドウにスクロールバーがないときのみ発生し得る。スクロールバー内の位置はこれらの目的にたいしてはウィンドウ外側と判断される。

left-fringe
right-fringe

その座標はウィンドウの左か右のフリンジ内にある。

left-margin
right-margin

その座標はウィンドウの左か右のマージン内にある。

nil

その座標はwindowのいずれの部分でもない。

関数coordinates-in-window-pwindowのあるフレームを使用するので引数としてフレームを要求しない。

以下の関数は文字単位ではなくピクセル単位でウィンドウ位置をリターンします。主にグラフィカルなディスプレイで有用ですがテキスト端末上でも呼び出すことができ、その場合は各文字の占めるスクリーン領域が1ピクセルとなります。

Function: window-pixel-edges &optional window

この関数はwindow端にたいするピクセル座標のリストをリターンする。(window-pixel-edges window)の呼び出しは、(window-edges window nil nil t) (上記参照)の呼び出しと等価。

Function: window-body-pixel-edges &optional window

この関数はwindowのボディー端をピクセルでリターンする。(window-body-pixel-edges window)の呼び出しは、(window-edges window t nil t) (上記参照)の呼び出しと等価。

以下の関数はフレーム原点ではなく、ディスプレイ画面(display screen)の原点に相対的なウィンドウ位置をピクセルでリターンします。

Function: window-absolute-pixel-edges &optional window

この関数はwindowのフレームのディスプレイの(0, 0)にある原点から相対的なwindowのピクセル座標をリターンする。(window-absolute-pixel-edges)の呼び出しは(window-edges window nil t t)の呼び出しと等価。上記を参照のこと。

Function: window-absolute-body-pixel-edges &optional window

この関数はwindowのフレームのディスプレイの(0, 0)にある原点から相対的なwindowのbodyのピクセル座標のリストをリターンする。(window-absolute-body-pixel-edges window)の呼び出しは(window-edges window t t t)の呼び出しと等価。上記を参照のこと。

set-mouse-absolute-pixel-positionと組み合わせることにより、あるウィンドウ内で可視な任意のバッファー位置にマウスポインターを移動するためにこの関数を使用できる。

(let ((edges (window-absolute-body-pixel-edges))
      (position (pos-visible-in-window-p nil nil t)))
  (set-mouse-absolute-pixel-position
   (+ (nth 0 edges) (nth 0 position))
   (+ (nth 1 edges) (nth 1 position))))

グラフィカルな端末では上記フォームは選択されたウィンドウのポイントにあるグリフ左上隅にマウスカーソルを“ワープ”させる。この方法で計算される位置は、そこにツールチップウィンドウを表示するためにも使用できる。

以下の関数はウィンドウ内で可視なバッファー位置のスクリーン座標をリターンします。

Function: window-absolute-pixel-position &optional position window

バッファー位置positionがウィンドウwindow内で可視なら、この関数はpositionにあるグリフの左上隅のディスプレイ座標をリターンする。リターン値はwindowのディスプレイ原点(0, 0)から相対的な、X座標とY座標からなるコンスセル。window内でpositionが不可視ならnilをリターンする。

windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。positionのデフォルトはwindowwindow-pointの値。

これは選択されたウィンドウ内のポイント位置へのマウスポインターの移動は、以下のような記述で足りることを意味する:

(let ((position (window-absolute-pixel-position)))
  (set-mouse-absolute-pixel-position
   (car position) (cdr position)))

以下の関数はそのウィンドウに表示するテキストを変換することなくウィンドウに内接する最大の矩形をリターンします。

Function: window-largest-empty-rectangle &optional window count min-width min-height positions left

この関数は指定死windowに内接する空の最大の矩形のディメンションをリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。

リターン値はwindowのテキスト領域の空スペース(テキストを何も表示していないスペース)に内接可能な最大矩形の幅、Y座標の開始と終了からなる3要素のリスト。このような矩形はwindowのテキスト領域の右エッジで終端されるとみなされるので、この関数はX座標をリターンしない。空のスペースが見つからなければリターン値はnil

オプション引数countが非nilなら、それはリターンする矩形の最大数を指定する。これはリターン値が最大の矩形が1つ目になるような矩形(3要素のリスト)のリストであることを意味する。countはコンスセルでもよく、この場合にはCARがリターンする矩形数、CDRが非nilならリターンされるすべての矩形が互いに素でなければならないことを示す。

オプション引数min-widthmin-heightが非nilなら、リターンされる矩形の最小の幅と高さを指定する。

オプション引数positionsnilなら、それはリターンされる矩形がカバーしなければならない最上のピクセル位置がCAR、最下のピクセル位置がCDRであるようなコンスセル。これらの位置はwindowのテキスト領域の開始から計測される。

オプション引数leftが非nilなら、それはリターン値がテキストを右から左に表示するバッファーに適していることを意味する。この場合にはリターンされる矩形はすべてwindowのテキスト領域の左端から開始するとみなされる。

この関数はwindow-lines-pixel-dimensions (表示されるテキストのサイズを参照)を通じてwindowのグリフマトリクスの各行のディメンションを取得する必要があることに注意。したがってこの関数はwindowのグリフマトリクスが最新でなければnilをリターンするかもしれない。


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

29.25 マウスによるウィンドウの自動選択

以下のオプションによりマウスポインターの下のウィンドウを自動的に選択することができます。これはウィンドウシステムのウィンドウにマウスポインターがエンターした際は常にフレームにフォーカスを与える(それゆえ以降の選択をトリガーする)ウィンドウマネージャーと同様なポリシーを実現します(入力のフォーカスを参照)。

User Option: mouse-autoselect-window

この変数が非nilなら、Emacsはマウスポインターの下のウィンドウの自動的な選択を試みる。有意な値は以下のとおり:

正の数値

これは自動選択トリガー後の遅延秒数を指定する。マウスポインター下のウィンドウはこの遅延秒数の間マウスが留まった後に選択される。

負の数値

負の数値は正の数値と同様の効果をもつが、数値の絶対数の遅延秒数の間マウスポインターがウィンドウ内に留まり加えて移動を停止した後にウィンドウを選択する点が異なる。

その他の値

その他の非nil値はマウスポインターがウィンドウ上にエンターすると即座にウィンドウを選択することを意味する。

いずれのケースでもウィンドウの選択をトリガーするために、マウスポインターはウィンドウのテキスト領域にエンターしなければならない。スクロールバーのスライダーのドラッグやウィンドウのモードラインではコンセプト的には自動選択を発生させるべきではない。

マウスによる自動選択はミニバッファーウィンドウがアクティブなときのみ選択を行い、アクティブなミニバッファーウィンドウの選択解除は決して行わない。

マウスによる自動選択はウィンドウマネージャーが追跡しない子フレーム(子フレームを参照)にたいしてマウスフォーカス追従ポリシーをエミュレートするために使用できます。これを行うためにはfocus-follows-mouse (入力のフォーカスを参照)に非nil値をセットすることが必要です。focus-follows-mouseの値がauto-raiseなら、マウスで子フレームにエンターすることにより親フレームの他のすべての子フレームの前面にその子フレームが自動的にレイズされます。


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

29.26 ウィンドウの構成

ウィンドウ構成(window configuration)とは1つのフレーム上全体のレイアウト — すべてのウィンドウとサイズ、どんなバッファーを含んでいるか、それらのバッファーがスクロールされる方法、およびポイント値を記録して、更に装飾も記録します。これにはminibuffer-scroll-windowの値も含まれます。特別な例外としてウィンドウ構成には選択されたウィンドウのカレントバッファーのポイント値は記録されません。

以前に保存されたウィンドウ構成をリストアすることにより、フレーム全体のレイアウトをリストアすることができます。1つだけではなくすべてのフレームのレイアウトを記録したければ、ウィンドウ構成のかわりにフレーム構成(frame configuration)を使用します。フレーム構成を参照してください。

Function: current-window-configuration &optional frame

この関数はframeのカレントのウィンドウ構成を表す新たなオブジェクトをリターンする。frameのデフォルトは選択されたフレーム。変数window-persistent-parametersはこの関数により保存されるウィンドウパラメーター(もしあれば)を指定する。ウィンドウのパラメーターを参照のこと。

Function: set-window-configuration configuration &optional dont-set-frame dont-set-miniwindow

この関数はconfigurationが作成されたフレームにたいして、そのフレームが選択されているかどうかに関わらず、ウィンドウとバッファーの構成をconfigurationで指定された構成にリストアする。引数configurationはそのフレームにたいして以前にcurrent-window-configurationがリターンした値でなければならない。この関数は通常は構成に記録されているフレームも選択するが、dont-set-frameが非nilなら関数の開始にすでに選択されていたフレームを選択したままにする。

この関数は通常はミニバッファー(もしあれば)のリストアと保存を行うが、dont-set-miniwindowが非nilなら関数の開始でカレントだったミニバッファー(もしあれば)はミニウィンドウ内に残る。

configurationが保存されたフレームが死んでいる(生きていない)場合には、この関数が行うのは変数minibuffer-scroll-windowの値のリストア、minibuffer-selected-windowがリターンした値の調整のみ。この場合には関数はnil、それ以外はtをリターンする。

configurationのウィンドウのバッファーがconfiguration作成後にkillされていたら、そのウィンドウは規則としてリストアされる構成から削除される。しかしリストアされる構成内でそのウィンドウが最後に残ったウィンドウなら、そのウィンドウに別の生きたバッファーが表示される。

以下はsave-window-excursionと同様な効果を得るためにこの関数を使用する例:

(let ((config (current-window-configuration)))
  (unwind-protect
      (progn (split-window-below nil)
             …)
    (set-window-configuration config)))
Macro: save-window-excursion forms…

このマクロは選択されたフレームのウィンドウ構成を記録して、formsを順に実行してから以前のウィンドウ構成をリストアする。リターン値はforms内の最後のフォームの値。

Lispコードのほとんどはこのマクロを使用するべきではない。大抵はsave-selected-windowで十分であろう。特にこのマクロはforms内で新たなウィンドウをオープンするコードを確実に防ぐことができず、新たなウィンドウは別のフレーム内でオープンされるかもしれないが(バッファーを表示するウィンドウの選択を参照)、save-window-excursionが保存とリストアするのはカレントフレーム上のウィンドウ構成だけだからである。

Function: window-configuration-p object

この関数はobjectがウィンドウ構成ならtをリターンする。

Function: window-configuration-equal-p config1 config2

この関数は2つのウィンドウ構成のウィンドウレイアウトが同じかどうかを判断するが、ポイント値および保存されたスクロール位置は無視される(つまりこれらの点では異なるウィンドウ構成であってもtをリターンし得る)。

Function: window-configuration-frame config

この関数はウィンドウ構成configが作成されたフレームをリターンする。

ウィンドウ構成の内部を調べる他のプリミティブも有用かもしれませんが、わたしたちはこれらを必要としないので実装されていません。ウィンドウ構成にたいしてより多くの操作を知りたければ、ファイルwinner.elを参照してください。

current-window-configurationがリターンするオブジェクトはEmacsプロセスとともに死滅します。ウィンドウ構成をディスク上に格納してそれを別のEmacsセッションに読み戻すために、次に説明する関数を使用できます。これらの関数はフレームの状態を任意の生きたウィンドウにクローンする場合にも有用です(set-window-configurationはフレームのウィンドウをそのフレームのルートウィンドウだけに効果的にクローンする)。

Function: window-state-get &optional window writable

この関数はwindowの状態をLispオブジェクトとしてリターンする。引数windowは有効なウィンドウでなければならずデフォルトは選択されたフレームのルートウィンドウ。

オプション引数writableが非nilなら、それはwindow-pointwindow-startのようなサンプリング位置にたいするマーカーを使用しないことを意味する。この状態をディスクに書き込んで別のセッションに読み戻すなら、この引数は非nilであること。

この関数によりどのウィンドウパラメーターが保存されるかは、引数writableと変数window-persistent-parametersの両方で指定する。ウィンドウのパラメーターを参照のこと。

window-state-getによりリターンされる値は、同一セッション内の他のウィンドウ内にあるウィンドウのクローンを作成するために使用できます。これはディスクに書き込んで別のセッションに読み戻すこともできます。いずれの場合にもウィンドウの状態をリストアするためには以下の関数を使用します。

Function: window-state-put state &optional window ignore

この関数はウィンドウ状態statewindow内にputする。引数stateは以前に呼び出したwindow-state-getがリターンしたウィンドウ状態であること。オプション引数windowには生きたウィンドウか内部ウィンドウ(ウィンドウとフレームを参照)のいずれかを指定できる。windowが生きていなければ、stateをputする前に生きたウィンドウに置き換える。windowが生きたウィンドウでなければ、それにstateをputする前に同一フレーム上に作成された新たな生きたウィンドウに置き換えられる。windownilならウィンドウの状態を新たなウィンドウにputする。

オプション引数ignoreが非nilなら、それは最小ウィンドウサイズと固定サイズの制限を無視することを意味する。ignoresafeなら、それは1行および/または2列までできる限り小さくできることを意味する。

関数window-state-getwindow-state-putでは2つの生きたウィンドウ間でのコンテンツの交換も可能です。以下の関数はこれを正確に行います:

Command: window-swap-states &optional window-1 window-2 size

このコマンドは2つの生きたウィンドウwindow-1window-2の状態を交換する。window-1には生きたウィンドウを指定しなければならずデフォルトは選択されたウィンドウ。window-2には生きたウィンドウを指定しなければならず、デフォルトはミニバッファーウィンドウを除き、すべての可視なフレーム上の生きたウィンドウを含むウィンドウサイクル順においてwindow-1の次のウィンドウ。

オプション引数sizeが非nilなら、それはwindow-1window-2のサイズも同様に交換を試みることを意味する。値heightは高さのみ、値widthは幅のみ、tは幅と高さの両方を可能なら交換することを意味する。この関数はフレームをリサイズしない。


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

29.27 ウィンドウのパラメーター

このセクションではウィンドウに追加の情報を関連付けるために使用できるウィンドウパラメーターを説明します。

Function: window-parameter window parameter

この関数はwindowparameterの値をリターンする。windowのデフォルトは選択されたウィンドウ。windowparameterにたいするセッティングがなければ、この関数はnilをリターンする。

Function: window-parameters &optional window

この関数はwindowのすべてのパラメーターと値をリターンする。windowのデフォルトは選択されたウィンドウ。リターン値はnil、または(parameter . value)という形式をもつ要素からなる連想リスト。

Function: set-window-parameter window parameter value

この関数はwindowparameterの値にvalueをセットしてvalueをリターンする。windowのデフォルトは選択されたウィンドウ。

デフォルトではウィンドウ構成(window configuration)やウィンドウ状態(states of windows)の保存とリストアを行う関数は、ウィンドウパラメーターについては関知しません(ウィンドウの構成を参照)。これはsave-window-excursionのボディー内でパラメーターの値を変更したときは、そのマクロのexit時に以前の値がリストアされないことを意味します。これはまた以前にwindow-state-getで保存されたウィンドウ状態をwindow-state-putでリストアしたときは、クローンされたすべてのウィンドウのパラメーターがnilにリセットされることも意味します。以下の変数によってこの標準の挙動をオーバーライドできます:

Variable: window-persistent-parameters

この変数はcurrent-window-configurationwindow-state-getにより保存、set-window-configurationwindow-state-putによりリストアされるパラメーターを指定するalistである。ウィンドウの構成を参照のこと。

このalistの各エントリーのCARはパラメーターを指定するシンボル。CDRは以下のいずれかであること:

nil

この値はそのパラメーターがwindow-state-getcurrent-window-configurationのいずれによっても保存されていないことを意味する。

t

この値はそのパラメーターがcurrent-window-configuration、および(writable引数がnilなら)window-state-getにより保存されたことを意味する。

writable

これはそのパラメーターが無条件でcurrent-window-configurationwindow-state-getの両方により保存されたことを意味する。この値は入力構文(read syntax)をもたないパラメーターに使用するべきではない。使用した場合には、別のセッションでwindow-state-putを呼び出すとinvalid-read-syntaxエラーで失敗するだろう。

いくつかの関数(特にdelete-windowdelete-other-windowssplit-window)は、window引数で指定されたウィンドウがその関数の名前と同じ名前のパラメーターセをもつ場合には特別な挙動を示すかもしれません。以下の変数を非nil値にバインドすることにより、そのような特別な挙動をオーバーライドできます:

Variable: ignore-window-parameters

この変数が非nilなら、いくつかの標準関数はウィンドウパラメーターを処理しない。現在のところ影響を受ける関数はsplit-windowdelete-windowdelete-other-windowsother-window

これらの関数の呼び出し周辺でアプリケーションはこの変数を非nilにバインドできる。これを行うと、そのアプリケーションはその関数のexit時に関連するすべてのウィンドウのパラメーターを正しく割り当てる責任をもつ。

以下のパラメーターは現在のところウィンドウ管理コードにより使用されています:

delete-window

このパラメーターはdelete-windowの実行に影響する(ウィンドウの削除を参照)。

delete-other-windows

このパラメーターはdelete-other-windowsの実行に影響する(ウィンドウの削除を参照)。

no-delete-other-windows

このパラメーターはそのウィンドウをdelete-other-windowsにより削除できないことをマークする(ウィンドウの削除を参照)。

split-window

このパラメーターはsplit-windowの実行に影響する(ウィンドウの分割を参照)。

other-window

このパラメーターはother-windowの実行に影響する(ウィンドウのサイクル順を参照)。

no-other-window

このパラメーターはそのウィンドウをother-windowによる選択が不可だとマークする(ウィンドウのサイクル順を参照)。

clone-of

このパラメーターはそのウィンドウがクローンされたことを指定する。これはwindow-state-getによりインストールされる(ウィンドウの構成を参照)。

window-preserved-size

このパラメーターはバッファー、方向(nilは垂直でtは水平)、ピクセル単位のサイズを指定する。そのウィンドウが指定されたバッファーを表示していて、かつ指示された方向のサイズがこのパラメーターで指定されたサイズと等しければ、Emacsはそのウィンドウの指示された方向のサイズを予約する。関数window-preserve-sizeによりこのパラメーターのインストールと更新が行われる(ウィンドウサイズの保持を参照)。

quit-restore

このパラメーターはバッファー表示関数によりインストールされて、quit-restore-windowにより参照される(ウィンドウのquitを参照)。これは4つの要素をもつリストであり、詳細はウィンドウのquitquit-restore-windowの説明を参照のこと。

window-side
window-slot

これらはサイドウィンドウを実装するために内部的に使用される(サイドウィンドウを参照)。

window-atom

このパラメーターはアトミックウィンドウを実装するために内部的に使用される(アトミックウィンドウを参照)。

mode-line-format

このパラメーターはウィンドウが表示されるたびにそのウィンドウのバッファーのバッファーローカル変数mode-line-format (モードラインの基礎を参照)の値を置き換える。シンボルnoneはそのウィンドウのモードライン表示の抑制を意味する。そのバッファーを表示する他のウィンドウのモードラインの表示とコンテンツは影響を受けない。

header-line-format

このパラメーターはウィンドウが表示されるたびにそのウィンドウのバッファーのバッファーローカル変数header-line-format (モードラインの基礎を参照)の値を置き換える。シンボルnoneはそのウィンドウのヘッダーライン表示の抑制を意味する。そのバッファーを表示する他のウィンドウのヘッダーラインの表示とコンテンツは影響を受けない。

tab-line-format

このパラメーターはウィンドウが表示されるたびにそのウィンドウのバッファーのバッファーローカル変数tab-line-format (モードラインの基礎を参照)の値を置き換える。シンボルnoneはそのウィンドウのタブライン表示の抑制を意味する。そのバッファーを表示する他のウィンドウのタブラインの表示とコンテンツは影響を受けない。

min-margins

このパラメーターの値はCARCDRが非nilのコンスセルなら、そのウィンドウの左ージンと右マージンの最小値を列数で指定する(マージン内への表示を参照)。与えられた場合には、Emacsはウィンドウを分割するか水平方向に縮小するかの判断にたいして、実際のマージン幅のかわりにこれらの値を使用する。

すべてのウィンドウにたいして、分割やリサイズ後にEmacsがマージンの自動調整をすることは決してない。これはそのウィンドウト分割のためにこのウィンドウのマージンを継承する新たなウィンドウニタイシテ、マージンを調整するためにこのパラメーターをセットするすべてのアプリケーション単独の責任である。window-configuration-change-hookwindow-size-change-functionsはいずれもこの用途に使用すること(ウィンドウのスクロールと変更のためのフックを参照)。

これはウィンドウ内でバッファーをセンタリングするために大きなマージンを使用するアプリケーションのサポート用にEmacsのバージョン25.1から導入されたパラメーターであり、それらのアプリケーションと排他となるよう留意して使用すること。Emacsの将来のバージョンで改善策により置換され得る。


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

29.28 ウィンドウのスクロールと変更のためのフック

このセクションではLispプログラムがウィンドウのスクロール後や、その他のウィンドウ変更が発生した際にどのようにしてアクションを起こすことができるかを説明します。最初はウィンドウがバッファーの異なる部分を表示するケースについて考えてみます。

Variable: window-scroll-functions

この変数はウィンドウのスクロールによりEmacsが再表示前に呼び出すべき関数のリストを保持する。そのウィンドウ内への異なるバッファーの表示や新たなウィンドウの作成でもこれらの関数が実行される。

この変数はそれぞれの関数がウィンドウとウィンドウのdisplay-start位置という2つの引数を受け取るのでノーマルフックではない。呼び出し時にはwindow引数のdisplay-start位置は新たな値、そのウィンドウに表示されるバッファーがカレントバッファーとしてセットされる。

これらの関数はwindow-end (ウィンドウの開始位置と終了位置を参照)を使用する際には気をつけなければならない。最新の値が必要なら、それを確実に入力するためにupdate引数を使用しなければならない。

警告: ウィンドウのスクロール方法を変更するためにこの機能を使用してはならない。これはそのような用途のためにデザインされておらず、そのような使用では機能しないだろう。

加えてFont Lockフォント表示関数(Font Lock fontification function)を登録するためにjit-lock-registerを使用できる。バッファーの一部が(再)フォント表示されたときは、ウィンドウがスクロールまたはサイズ変更されたという理由で、これが常に呼び出されるだろう。Font Lockのその他の変数を参照のこと。

このセクションの残りの部分ではウィンドウのスクロールをともなわないウィンドウの有意な変更を検知した際の再表示の間に呼び出される6つのフックについて補足します。単純化するために、これらのフックおよびそれらが呼び出す関数をまとめてウィンドウ変更関数(window change functions)と呼ぶことにします。他のフックと同様に、これらのフックはインストール時にadd-hooklocal引数(フックのセットを参照)を通じてグローバル、またはバッファーローカルにセットできます。

これらのフックのうち最初のフックはウィンドウバッファー変更(window buffer change)を検知した後に実行されます。ウィンドウバッファー変更とはウィンドウの作成や削除、他のバッファーの割り当てを意味します。

Variable: window-buffer-change-functions

この変数はウィンドウバッファー変更時の再表示の間に呼び出す関数を指定する。値は1つの引数を受け取る関数のリストであること。

バッファーローカルに指定された関数は、対応するバッファーを表示するすべてのウィンドウにたいして、最後にウィンドウ変更関数が実行されて以降にウィンドウが作成されたり、そのバッファーが割り当てられた場合に呼び出される。この場合にはそのウィンドウが引数として渡される。

デフォルト値として指定された関数はフレームにたいして、最後にウィンドウ変更関数が実行されて以降にそのフレームに少なくとも1つのウィンドウの追加か削除が行われるか、別のバッファーが割り当てられた場合に呼び出される。この場合にはフレームが引数として渡される。

2つ目のフックはウィンドウサイズ変更(window size change)の検出時に実行されます。ウィンドウサイズ変更とはウィンドウ作成、別バッファーの割り当て、合計サイズやテキストエリアの合計サイズの変更を意味します。

Variable: window-size-change-functions

この変数はウィンドウサイズ変更発生時の再表示の間に呼び出される関数を指定する。値は1つの引数を受け取る関数のリストであること。

バッファーローカルに指定された関数は、対応するバッファーを表示するすべてのウィンドウにたいして、最後にウィンドウ変更関数が実行されて以降にウィンドウの追加や別バッファーの割り当て、合計サイズやボディーサイズが変更された場合に呼び出される。この場合にはそのウィンドウが引数として渡される。

デフォルト値として指定された関数は、最後にフレームにたいしてウィンドウ変更関数が実行されて以降に、そのフレーム上の少なくとも1つのウィンドウ追加や別バッファーの割り当て、または合計サイズやボディーサイズが変更された場合に呼び出される。この場合にはフレームが引数として渡される。

3つ目のフックは前回の再表示以降にウィンドウ選択変更(window selection change)により別のウィンドウが選択された際に実行されます。

Variable: window-selection-change-functions

この変数は選択されたウィンドウやフレームの選択されたウィンドウの変更時の再表示の間に実行される関数を指定する。値は1つの引数を受け取る関数のリストであること。

バッファーローカルに指定された関数は、対応するバッファーを表示するすべてのウィンドウにたいして、最後にウィンドウ変更関数が実行されて以降に(すべてのウィンドウあるいはウィンドウのフレーム上のすべてのウィンドウの中から)ウィンドウが選択されたり選択解除された場合に呼び出される。この場合にはそのウィンドウが引数として渡される。

デフォルト値として指定された関数はフレームにたいして、最後にウィンドウ変更関数が実行されて以降のそのフレームの選択や非選択、あるいはフレームの選択されたウィンドウが変更された場合に呼び出される。この場合にはフレームが引数として渡される。

4つ目のフックはウィンドウ状態変更(window state change)の検出時に実行されます。ウィンドウ状態変更とは上述の3つのウィンドウ変更のうち少なくとも1つが発生したことを意味します。

Variable: window-state-change-functions

この変数はウィンドウのバッファーかサイズの変更発生時、または選択されたウィンドウやフレームの選択されたウィンドウの変更時の再表示の間に呼び出される関数を指定する。値は1つの引数を受け取る関数のリストであること。

バッファーローカルに指定された関数は、対応するバッファーを表示するすべてのウィンドウにたいして、最後にウィンドウ変更関数が実行されて以降にそのウィンドウの追加や別バッファーの割り当て、合計サイズやボディーサイズが変更されたり、(すべてのウィンドウあるいはウィンドウのフレーム上のすべてのウィンドウの中から)ウィンドウが選択されたり選択解除された場合に呼び出される。この場合にはそのウィンドウが引数として渡される。

デフォルト値として指定された関数はフレームにたいして、最後にウィンドウ変更関数が実行されて以降にそのフレームの少なくとも1つのウィンドウが追加や削除、別バッファーを割り当てられるか、合計サイズやボディーサイズの変更、またはフレームの選択または選択されていないウィンドウが変更された場合に呼び出される。この場合にはフレームが引数として渡される。

デフォルト値として指定された関数は、最後の再表示以降にそのフレームのウィンドウ状態変更フラグ(以下参照)がセットされた場合にもフレームにたいして実行される。

5つ目のフックはウィンドウ構成変更(window configuration change)の検出時に実行されます。ウィンドウ構成変更とはバッファーやウィンドウサイズの変更を意味します。このフックは実行方向において前記4つのフックとは異なります。

Variable: window-configuration-change-hook

この変数はウィンドウのバッファーかサイズの変更時の再表示の間に呼び出される関数を指定する。値は引数を受け取らない関数のリストであること。

バッファーローカルに指定された関数は、対応するバッファーを表示するすべてのウィンドウにたいして、最後にウィンドウ変更関数が実行されて以降に、そのフレームの少なくとも1つのウィンドウの追加や削除、別バッファーの割り当て、あるいは合計サイズやボディーサイズが変更された場合に呼び出される。各呼び出しは一時的にそのバッファーを表示するウィンドウを選択して、そのバッファーをカレントにして行われる。

デフォルト値として指定された関数は各フレームにたいして、最後にウィンドウ変更関数が実行されて以降に、そのフレームに少なくとも1つのウィンドウの追加や削除、別バッファーの割り当て、あるいは合計サイズやボディーサイズが変更された場合に呼び出される。各呼び出しは一時的にそのフレームを選択して、その選択されたウィンドウのバッファーをカレントにして行われる。

最後にEmacsはwindow-state-change-functionsの振る舞いを一般化したノーマルフックを実行します。

Variable: window-state-change-hook

この変数のデフォルト値はウィンドウ状態変更、または少なくとも1つのフレームでウィンドウ状態変更フラグのセットを検出した際の再表示の間に呼び出される関数を指定する。値は引数を受け取らない関数のリストであること。

アプリケーションは最後の再表示以降に複数のフレームで発生した(またはシグナルされた)変更に対処したい場合のみ、このフックに関数を配置すること。他のすべてのケースにたいしてはwindow-state-change-functionsに関数を配置するほうが好ましい。

ウィンドウ変更関数は各フレームにたいする再表示の間に次のように呼び出されます。まずすべてのバッファーローカルなウィンドウバッファー変更関数、ウィンドウサイズ変更関数、ウィンドウ選択変更関数、ウィンドウ状態変更関数を順番に呼び出します。次にこれらの関数のデフォルト値を同じ順番で呼び出します。これらの関数のデフォルト値で指定された関数の呼び出した後に、すべてのバッファーローカルなウィンドウ構成変更関数を呼び出します。そして最後にwindow-state-change-hookの関数が実行されます。

ウィンドウ変更関数は対応する変更が前に登録されている特定のフレームにたいしてのみ実行されます。そのような変更にはウィンドウの作成や削除、ウィンドウへの別バッファーやサイズの割り当てが含まれます。そのような変更が登録されていたとしても、それは上述したフックのいずれかが実行されることを意味しないことに注意してください。たとえばある変更がウィンドウエクスカーション(ウィンドウの構成を参照)のスコープ内で登録されると、ウィンドウ変更関数呼び出しはウィンドウ変更関数実行時にそのエクスカーションがまだ持続している場合のみトリガーされるでしょう。それ以前にエクスカーションがexitされていれば、そのエクスカーションのスコープ外で登録された変更の場合のみフックが実行されます。

フレームのウィンドウ状態変更フラグ(window state change flag)をセットすることにより、そのフレームにたいしてウィンドウ状態変更が実際に発生したかどうかに関わらず、次回の再表示の間に(そのフレームにたいする) window-state-change-functionswindow-state-change-hookのデフォルト値が実行されます。これらのフックのすべての関数を実行した後に、各フレームにたいしてフラグをリセットを行います。アプリケーションは以下の関数を使用してこのフラグのセットや検査を行うことができます。

Function: set-frame-window-state-change &optional frame arg

この関数はargが非nilならframeのウィンドウ状態変更フラグをセット、それ以外はリセットする。frameは生きたフレームでなければならず、デフォルトは選択されたフレーム。

Function: frame-window-state-change &optional frame

この関数はframeのウィンドウ状態変更フラグがセットされていればt、それ以外はnilをリターンする。frameは生きたフレームでなければならず、デフォルトは選択されたフレーム。

ウィンドウ変更関数の実行中に下記の関数を呼び出すことにより、最後の再表示以降に特定のウィンドウやフレームにたいして何が変更されたかについてより詳細な知見を得ることができます。これらの関数はすべて生きたウィンドウを単一かつオプションの引数として受け取ります(デフォルトは選択されたウィンドウ)。

Function: window-old-buffer &optional window

この関数はwindowのフレームにたいして最後にウィンドウ変更関数が実行された時点において、windowに表示されていたバッファーをリターンする。その時点より後にwindowが作成された場合にはnilをリターンする。その時点ではwindowは表示されていなかったが、後から以前に保存されたウィンドウ構成がリストアされた場合にはtをリターンする。それ以外ならリターン値はその時点でwindowが表示していたバッファー。

Function: window-old-pixel-width &optional window

この関数はウィンドウ変更関数がフレーム上でwindowが生きていることを確認した最終時点におけるwindowのトータルピクセル幅をリターンする。その後にwindowが作成された場合は0。

Function: window-old-pixel-height &optional window

この関数はウィンドウ変更関数がフレーム上でwindowが生きていることを確認した最終時点におけるwindowのトータルピクセル高さをリターンする。その後にwindowが作成された場合は0。

Function: window-old-body-pixel-width &optional window

この関数はウィンドウ変更関数がフレーム上でwindowが生きていることを確認した最終時点におけるwindowのテキストエリアのピクセル幅をリターンする。その後にwindowが作成された場合は0。

Function: window-old-body-pixel-height &optional window

この関数はウィンドウ変更関数がフレーム上でwindowが生きていることを確認した最終時点におけるwindowのテキストエリアのピクセル高さをリターンする。その後にwindowが作成された場合は0。

ウィンドウ変更関数が最後に実行された時点でどのウィンドウまたはフレームが選択されていたかを調べるために以下の関数を使用できます:

Function: frame-old-selected-window &optional frame

この関数はウィンドウ変更関数が最後に実行された時点におけるframeの選択されていたウィンドウをリターンする。frameが省略またはnilの場合のデフォルトは選択されたフレーム。

Function: old-selected-window

この関数はウィンドウ変更関数が最後に実行された時点において選択されていたウィンドウをリターンする。

Function: old-selected-frame

この関数はウィンドウ変更関数が最後に実行された時点において選択されていたフレームをリターンする。

ウィンドウ変更関数は最後に実行されて以降に削除されたウィンドウに関する情報は提供しないことに注意してください。アプリケーションがそれを必要とする場合には、特定のバッファーを表示するすべてのウィンドウをバッファーのローカル変数に記憶するとともに、それをウィンドウバッファー変更の検出時に実行されるすべてのフックのデフォルト値の関数で更新する必要があります。

ウィンドウ変更関数に関数を追加する際には、以下の点を考慮する必要があります:

  • ウィンドウ変更関数の呼び出しをトリガーしない操作がある。これにはミニバッファーウィンドウでの別バッファー表示やツールチップウィンドウのすべての変更が含まれる。
  • ウィンドウ変更関数はウィンドウの作成や削除、バッファー変更、ウィンドウのサイズや選択状態を何も変更するべきではない。なぜならそのような変更に関する情報が他のウィンドウ変更関数に伝播される保証は何もないから。もしそのような変更行うならwindow-state-change-hookのデフォルト値の最後にリストされる関数で行うこと。
  • ウィンドウ変更関数の実行時にはsave-window-excursionwith-selected-windowwith-current-bufferのようなマクロを使用できる。
  • マッチデータはウィンドウ変更関数の実行により保存やリストアされない。window-configuration-change-hookの実行以外では選択されたウィンドウやフレーム、カレントバッファーの保存やリストアは行われない。
  • ウィンドウ変更関数の実行をトリガーするすべての再表示はabort(異常終了)する可能性がある。ウィンドウ変更関数が完了する前にabortが発生すると、ウィンドウ変更関数は以前の値、すなわち再表示が行われなかったかのような値で再実行される。その後にabortした場合には新たな値、すなわち再表示が実際に処理されたかのような値で実行される

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

30 フレーム

フレーム(frame)とは、1つ以上のEmacsウィンドウを含むスクリーンオブジェクトです(ウィンドウを参照)。これはグラフィカル環境では“ウィンドウ”と呼ばれる類のオブジェクトです。しかしEmacsはこの単語を異なる方法で使用しているので、ここではそれを“ウィンドウ”と呼ぶことはできません。Emacs Lispにおいてフレームオブジェクト(frame object)とは、スクリーン上のフレームを表すLispオブジェクトです。フレーム型を参照してください。

フレームには最初は1つのメインウィンドウおよび/またはミニバッファーウィンドウが含まれます。メインウィンドウは、より小さいウィンドウに垂直か水平に分割することができます。ウィンドウの分割を参照してください。

端末(terminal)とは1つ以上のEmacsフレームを表示する能力のあるデバイスのことです。Emacs Lispにおいて端末オブジェクト(terminal object)とは端末を表すLispオブジェクトです。端末型を参照してください。

端末にはテキスト端末(text terminals)グラフィカル端末(graphical terminals)という2つのクラスがあります。テキスト端末はグラフィック能力をもたないディスプレイであり、xtermやその他の端末エミュレーターが含まれます。テキスト端末上ではそれぞれのEmacsフレームはその端末のスクリーン全体を占有します。たとえ追加のフレームを作成してそれらを切り替えることができたとしても、端末が表示するのは一度に1つのフレームだけです。一方でグラフィカル端末はXウィンドウシステムのようなグラフィカルディスプレイシステムにより管理されています。これによりEmacsは同一ディスプレイ上に複数のフレームを同時に表示することができます。

GNUおよびUnix systemsシステムでは、単一のEmacsセッション内でそのEmacsがテキスト端末とグラフィカル端末のいずれで開始されたかに関わらず、任意の利用可能な端末上で追加のフレームを作成することができます。Emacsは、グラフィカル端末とテキスト端末の両方を同時に表示することができます。 これはたとえばリモートから同じセッションに接続する際などに便利でしょう。複数の端末を参照してください。

Function: framep object

この述語(predicate)はobjectがフレームなら非nil、それ以外はnilをリターンする。フレームにたいしてはフレームが使用するディスプレイの種類が値:

t

そのフレームはテキスト端末上で表示されている。

x

そのフレームはXグラフィカル端末上で表示されている。

w32

そのフレームはMS-Windowsグラフィカル端末上で表示されている。

ns

そのフレームはGNUstepかMacintosh Cocoaグラフィカル端末上で表示されている。

pc

そのフレームはMS-DOS端末上で表示されている。

pgtk

そのフレームはpure GTK機能を使って表示されている。

Function: frame-terminal &optional frame

この関数はframeを表示する端末オブジェクトをリターンする。framenilまたは未指定の場合のデフォルトは選択されたフレーム。

Function: terminal-live-p object

この述語はobjectが生きた(削除されていない)端末なら非nil、それ以外はnilをリターンする。生きた端末にたいしては、リターン値はその端末上で表示されているフレームの種類を示す。可能な値は上述のframepと同様。

グラフィカルな端末ではフレームを2つのタイプに区別しています。通常のトップレベルフレーム(top-level frame)は、ウィンドウ(ウィンドウシステム)としては端末にたいするルートウィンドウ(ウィンドウシステム)の子であるようなフレームです。子フレーム(child frame)は、ウィンドウ(ウィンドウシステム)としてはEmacsの別フレームのウィンドウ(ウィンドウシステム)の子であるようなフレームです。子フレームを参照してください。


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

30.1 フレームの作成

新たにフレームを作成するためには関数make-frameを呼び出します。

Command: make-frame &optional parameters

この関数はカレントバッファーを表示するフレームを作成してそれをリターンする。

parameters引数は新たなフレームのフレームパラメーターを指定するalist。フレームのパラメーターを参照のこと。alist内でterminalパラメーターを指定すると新たなフレームはその端末上で作成される。それ以外の場合には、alist内でwindow-systemフレームパラメーターを指定すると、それはフレームがテキスト端末とグラフィカル端末のどちらで表示されるべきかを決定する。ウィンドウシステムを参照のこと。どちらも指定しなければ新たなフレームは選択されたフレームと同じ端末上に作成される。

parametersで指定されなかったパラメーターのデフォルトは連想リストdefault-frame-alist内の値となる。そこでも指定されないパラメーターのデフォルトはXリソース、またはそのオペレーティングシステムで同等なものの値(X Resources in The GNU Emacs Manualを参照)。フレームが作成された後に、この関数はframe-inherited-parameters (以下参照)内で指定されたパラメーターのうち未割り当てのパラメーターにたいして、make-frame呼び出し時に選択されていたフレームから値を取得して適用する。

マルチモニターディスプレイ(複数の端末を参照)では、ウィンドウマネージャーがparameters内の位置パラメーター(位置のパラメーターを参照)の指定とは異なる位置にフレームを配置するかもしれないことに注意。たとえばウィンドウの大きな部分、いわゆる支配モニター(dominating monitor)上のフレームを表示するポリシーをもつウィンドウマネージャーがいくつかある。

この関数自体が新たなフレームを選択されたフレームにする訳ではない。入力のフォーカスを参照のこと。以前に選択されていたフレームは選択されたままである。しかしグラフィカル端末上ではウィンドウシステム自身の理由によって新たなフレームが選択されるかもしれない。

Variable: before-make-frame-hook

make-frameがフレームを作成する前に、それにより実行されるノーマルフック。

Variable: after-make-frame-functions

make-frameがフレームを作成した後に実行するアブノーマルフック。after-make-frame-functions内の各関数は作成された直後のフレームを単一の引数として受け取る。

initファイルでこれらのフックに追加した関数は、初期フレームの作成後にEmacsがinitファイルを読み込むために、通常は初期フレームにたいして実行されないことに注意してください。しかし別のミニバッファーフレーム(ミニバッファーとフレームを参照)を使用して初期フレームを指定すれば、これらの関数はミニバッファーなしのフレームとミニバッファーフレームの両方にたいして実行されます。かわりに“早期initファイル(early init file)”でこれらのフックに関数を追加することができます(initファイルを参照)。この場合には初期フレームにも同じように効果があります。

Variable: frame-inherited-parameters

この変数はカレントで選択されているフレームから継承して新たに作成されたフレームのフレームパラメーターのリストを指定する。リスト内の各要素はmake-frameの処理において前に割り当てられていないパラメーター(シンボル)であり、make-frameは新たに作成されたフレームのそのパラメーターに選択されたフレームの値をセットする。

User Option: server-after-make-frame-hook

Emacsサーバーがクライアントフレームを作成する際に実行されるノーマルフック。このフックの呼び出し時には作成されたフレームが選択されたフレームとなる。Emacs Server in The GNU Emacs Manualを参照のこと。


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

30.2 複数の端末

Emacsはそれぞれの端末を端末オブジェクト(terminal object)というデータ型で表します(端末型を参照)。GNUおよびUnixシステムではEmacsはそれぞれのセッション内で複数の端末を同時に実行できます。その他のシステムでは単一の端末だけが使用できます。端末オブジェクトはそれぞれ以下の属性をもちます:

  • その端末により使用されるデバイスの名前(たとえば‘:0.0’や/dev/tty )。
  • その端末により使用される端末とキーボードのコーディングシステム。端末I/Oのエンコーディングを参照のこと。
  • その端末に関連付けられたディスプレイの種類。これは関数terminal-live-pによりリターンされるシンボル(たとえばxtw32nspchaikupgtk)。フレームを参照のこと。
  • 端末パラメーターのリスト。端末のパラメーターを参照のこと。

端末オブジェクトを作成するプリミティブはありません。make-frame-on-display (以下参照)を呼び出したときなどに、Emacsが必要に応じてそれらを作成します。

Function: terminal-name &optional terminal

この関数はterminalにより使用されるデバイスのファイル名をリターンする。terminalが省略またはnilの場合のデフォルトは選択されたフレームの端末。terminalはフレームでもよく、その場合はそのフレームの端末。

Function: terminal-list

この関数はすべての生きた端末オブジェクトのリストをリターンする。

Function: get-device-terminal device

この関数はdeviceにより与えられたデバイス名の端末をリターンする。deviceが文字列なら端末デバイス名、または‘host:server.screen’という形式のXディスプレイのいずれかを指定できる。deviceならこの関数はそのフレームの端末をリターンする。nilは選択されたフレームを意味する。最後にもしdeviceが生きた端末を表す端末オブジェクトなら、その端末がリターンされる。引数がこれらのいずれとも異なれば、この関数はエラーをシグナルする。

Function: delete-terminal &optional terminal force

この関数はterminal上のすべてのフレームを削除して、それらが使用していたリソースを解放する。これらはアブノーマルフックdelete-terminal-functionsを実行して、各関数の引数としてterminalを渡す。

terminalが省略またはnilの場合のデフォルトは選択されたフレームの端末。terminalはフレームでもよく、その場合はそのフレームの端末を意味する。

この関数は通常は唯一アクティブな端末の削除を試みるとエラーをシグナルするが、forceが非nilならこれを行うことができる。端末上で最後のフレームを削除した際には、Emacsは自動的にこの関数を呼び出す(フレームの削除を参照)。

Variable: delete-terminal-functions

delete-terminalにより実行されるアブノーマルフック。各関数はdelete-terminalに渡されたterminalを唯一の引数として受け取る。技術的な詳細により、この関数は端末の削除の直前または直後のいずれかに呼び出される。

数は多くありませんが、Lisp変数のいくつかは端末ローカル(terminal-local)です。つまりそれらは端末それぞれにたいして個別にバインディングをもちます。いかなるときも実際に効果をもつバインディングはカレントで選択されたフレームに属する端末にたいして1つだけです。これらの変数にはdefault-minibuffer-framedefining-kbd-macrolast-kbd-macrosystem-key-alistが含まれます。これらは常に端末ローカルであり、決してバッファーローカル(バッファーローカル変数を参照)にはできません。

GNUおよびUnixシステムでは、Xディスプレイはそれぞれ別のグラフィカル端末になります。Xウィンドウシステム内でEmacsが開始された際は環境変数DISPLAY、または‘--display’オプション(Initial Options in The GNU Emacs Manualを参照)により指定されたXディスプレイを使用します。Emacsはコマンドmake-frame-on-displayを通じて別のXディスプレイに接続できます。それぞれのXディスプレイは、それぞれが選択されたフレームとミニバッファーをもちます。しかしあらゆる瞬間(入力のフォーカスを参照)において、それらのフレームのうちの1つだけが、いわゆる選択されたフレームになります。emacsclientとの対話により、Emacsが別のテキスト端末と接続することさえ可能です。Emacs Server in The GNU Emacs Manualを参照してください。

1つのXサーバーが1つ以上のディスプレイを処理できます。各Xディスプレイには‘hostname:displaynumber.screennumber’という3つの部分からなる名前があります。1つ目の部分のhostnameはその端末が物理的に接続されるマシン名です。2つ目の部分のdisplaynumberは同じキーボードとポインティングデバイス(マウスやタブレット等)を共有するマシンに接続された1つ以上のモニターを識別するための0基準の番号です。3つ目の部分のscreennumberは、そのXサーバー上の単一のモニターコレクション(a single monitor collection)の一部である0基準のスクリーン番号(個別のモニター)です。1つのサーバー配下にある2つ以上のスクリーンを使用する際には、Emacsはそれらの名前の同一部分から、それらが単一のキーボードを共有することを知ることができるのです。

MS-WindowsのようにXウィンドウシステムを使用しないシステムはXディスプレイの概念をサポートせず、各ホスト上には1つのディスプレイだけがあります。これらのシステム上のディスプレイ名は上述したような3つの部分からなる名前にしたがいません。たとえばMS-Windowsシステム上のディスプレイ名は文字列定数‘w32’です。これは互換性のために存在するものであり、ディスプレイ名を期待する関数にこれを渡すことができます。

Command: make-frame-on-display display &optional parameters

この関数はdisplay上に新たにフレームを作成してそれをリターンする。その他のフレームパラメーターは、parametersというalistから取得する。displayはXディスプレイの名前(文字列)であること。

この関数はフレーム作成前にEmacsがグラフィックを表示するためにセットアップされることを保証する。(テキスト端末上で開始された等で)たとえばEmacsがXリソースを未処理ならこの時点で処理を行う。他のすべての点においては、この関数はmake-frame(フレームの作成を参照)と同様に振る舞う。

Function: x-display-list

この関数はEmacsがどのXディスプレイに接続したかを識別するリストをリターンする。このリストの要素は文字列で、それぞれがディスプレイ名を表す。

Function: x-open-connection display &optional xrm-string must-succeed

この関数はディスプレイ上にフレームを作成することなく、Xディスプレイdisplayへの接続をオープンする。通常はmake-frame-on-displayが自動的に呼び出すので、Emacs Lispプログラムがこの関数を呼び出す必要はない。これを呼び出す唯一の理由は、与えられたXディスプレイにたいして通信を確立できるかどうかチェックするためである。

オプション引数xrm-stringが非nilなら、それは.Xresourcesファイル内で使用されるフォーマットと同一なリソース名とリソース値。X Resources in The GNU Emacs Manualを参照のこと。これらの値はそのXサーバー上で記録されたリソース値をオーバーライドして、このディスプレイ上で作成されるすべてのEmacsフレームにたいして適用される。以下はこの文字列がどのようなものかを示す例:

"*BorderWidth: 3\n*InternalBorder: 2\n"

must-succeedが非nilなら、接続オープンの失敗によりEmacsが終了させられる。それ以外なら通常のLispエラーとなる。

Function: x-close-connection display

この関数はディスプレイdisplayへの接続をクローズする。これを行う前には、まずそのディスプレイ上でオープンしたすべてのフレームを削除しなければならない(フレームの削除を参照)。

マルチモニターのセットアップにおいて、単一のXディスプレイが複数の物理モニターに出力される場合があります。そのようなセットアップを取得するために関数display-monitor-attributes-listframe-monitor-attributesを使用できます。

Function: display-monitor-attributes-list &optional display

この関数はdisplay上の物理モニターの属性のリストをリターンする。displayにはディスプレイ名(文字列)、端末、フレームを指定でき、省略またはnilの場合のデフォルトは選択されたフレームのディスプレイ。このリストの各要素は物理モニターの属性を表す連想リスト。1つ目の要素はプライマリーモニターである。以下は属性のキーと値:

geometry

(x y width height)’のようなピクセル単位でのそのモニターのスクリーンの左上隅の位置とサイズ。そのモニターがプライマリーモニターでなければ、いくつかの座標が負になり得る。

workarea

(x y width height)’のようなピクセル単位でのワークエリア(使用可能なスペース)の左上隅の位置とサイズ。ウィンドウマネージャーのさまざまな機能(dock、taskbar等)によりそのスペースが占有される‘geometry’とは異なり、これはワークエリアから除外され得る。そのような機能が実際にワークエリアから差し引かれるかどうかは、そのプラットフォームと環境に依存する。繰り返しになるが、そのモニターがプライマリーモニターでなければ、いくつかの座標は負になり得る。

mm-size

(width height)’<のようなミリメートル単位での幅と高さ。

frames

その物理モニターが支配(dominate)するフレームのリスト(以下参照)。

name

stringのようなその物理モニターの名前。

source

stringのようなマルチモニターの情報ソース(例: ‘XRandR 1.5’、‘XRandr’、‘Xinerama’等)。

xywidthheightは整数。‘name’と‘source’は欠落しているかもしれない。

あるモニター内にフレームの最大領域がある、または(フレームがどの物理モニターにも跨がらないなら)そのモニターがフレームに最も近いとき、フレームは物理モニターにより支配(dominate)される。グラフィカルなディスプレイ内の(ツールチップではない)すべてのフレームは、たとえそのフレームが複数の物理モニターに跨がる(または物理モニター上にない)としても、(可視か否かによらず)正確に1つの物理モニターにより支配される。

以下は2つのモニターディスプレイ上でこの関数により生成されたデータの例:

  (display-monitor-attributes-list)
  ⇒
  (((geometry 0 0 1920 1080) ;; 左手側プライマリーモニター
    (workarea 0 0 1920 1050) ;; タスクバーが幾分かの高さを占有
    (mm-size 677 381)
    (name . "DISPLAY1")
    (frames #<frame emacs@host *Messages* 0x11578c0>
            #<frame emacs@host *scratch* 0x114b838>))
   ((geometry 1920 0 1680 1050) ;; 右手側モニター
    (workarea 1920 0 1680 1050) ;; スクリーン全体を使用可
    (mm-size 593 370)
    (name . "DISPLAY2")
    (frames)))
Function: frame-monitor-attributes &optional frame

この関数はframeを支配(上記参照)する物理モニターの属性をリターンする。 frameのデフォルトは選択されたフレーム。

マルチモニターディスプレイではフレームを指定したモニター上にするためにコマンドmake-frame-on-monitorを使用することが可能です。

Command: make-frame-on-monitor monitor &optional display parameters

この関数はdisplay上に配置されるmonitorに新たにフレームを作成してそれをリターンする。その他のフレームパラメーターは、parametersというalistから取得する。monitorは物理モニター名であり、display-monitor-attributes-list関数のリターン値の属性nameの文字列と同一の文字列であること。displayはXディスプレイの名前(文字列)であること。

Variable: display-monitors-changed-functions

この変数はモニター構成が変更された際に実行されるアブノーマルフック。モニター構成の変更はモニターのローテート(rotate: 回転)、移動、マルチモニターセットアップへの追加や削除、プライマリーモニターの変更、モニター解像度の変更によって起こり得る。フックの関数はモニター構成が変更された端末で構成された単一の引数とともに呼び出される。プログラムは端末の新たなモニター構成を取得するために、その端末を引数としてdisplay-monitor-attributes-listを呼び出すこと。


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

30.3 フレームのジオメトリー

フレームのジオメトリー(geometry)は、そのEmacsインスタンスのビルドに使用されたツールキット、およびそのフレームを表示する端末に依存します。このチャプターではこれらの依存関係とそれらを処理するいくつかの関数を説明します。これらの関数すべてにたいして、frame引数には生きたフレームを指定する必要があることに注意してください(フレームの削除を参照)。省略またはnilなら選択されたフレーム(入力のフォーカスを参照)が指定されます。


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

30.3.1 フレームのレイアウト

可視なフレームは端末のディスプレイの矩形(rectangular)の領域を占有します。この領域にはそれぞれが異なる用途をサービスする、いくつかのネストされた矩形を含むことができます。以下のスケッチはグラフィカル端末上でのレイアウトを描いたものです:


        <------------ Outer Frame Width ----------->
        ____________________________________________
     ^(0)  ________ External/Outer Border _______   |
     | |  |_____________ Title Bar ______________|  |
     | | (1)_____________ Menu Bar ______________|  | ^
     | | (2)_____________ Tool Bar ______________|  | ^
     | | (3)_____________ Tab Bar _______________|  | ^
     | |  |  _________ Internal Border ________  |  | ^
     | |  | |   ^                              | |  | |
     | |  | |   |                              | |  | |
Outer  |  | | Inner                            | |  | Native
Frame  |  | | Frame                            | |  | Frame
Height |  | | Height                           | |  | Height
     | |  | |   |                              | |  | |
     | |  | |<--+--- Inner Frame Width ------->| |  | |
     | |  | |   |                              | |  | |
     | |  | |___v______________________________| |  | |
     | |  |___________ Internal Border __________|  | v
     v |___________ External/Outer Border __________|
           <-------- Native Frame Width -------->

実際のところ上図で示した領域すべてが存在するわけではありません。これらの領域については以下で説明します。

アウターフレーム(Outer Frame)

アウターフレーム(outer frame)とは上図で示すすべての領域を網羅する矩形。この矩形の端はそのフレームのアウターエッジ(outer edges)と呼ばれる。フレームのアウター幅(outer width)アウター高さ(outer height)は併せて矩形のアウターサイズ(outer size)を指定する。

フレームのアウターサイズを把握することはフレームのディスプレイの作業領域にフレームをフィットさせたり、スクリーンで2つのフレームを隣接して配置するのに有用である(複数の端末を参照)。アウターサイズは通常はフレームが少なくとも1回マップ(可視にすること。フレームの可視性を参照)された後でなければ利用できない。初期フレームやまだ作成されていないフレームにたいするアウターサイズは予想するかウィンドウシステムやウィンドウマネージャーのデフォルトから計算しなければならない。回避策としてはマップ済みフレームのアウターサイズとネイティブサイズを取得して、新たなフレームのアウターサイズの計算に使用すればよい。

(上図‘(0)’で示される)アウターフレームの左上隅の位置はフレームのアウター位置(outer position)と呼ばれる。グラフィカルなフレームのアウター位置は、ディスプレイではフレームのリサイズやレイアウト変更では未変更のままなので、そのフレームの“位置”としても参照される。

アウター位置はフレームパラメーターlefttopを通じて指定とセットができる(位置のパラメーターを参照)。これらのパラメーターは通常のトップレベルのフレームにたいして、通常はフレームのディスプレイの原点からみた絶対位置(以下参照)を表す。子フレーム(子フレームを参照)にたいしては親フレームのネイティブ位置(以下参照)から相対的な位置を表す。これらのパラメーターの値はテキスト端末のフレームでは意味がなく常に0である。

エクスターナルボーダー(External Border)

エクスターナルボーダー(external border)はウィンドウマネージャーにより提供される装飾の一部。典型的にはマウスによるフレームのリサイズで典型的に使用される。そのため“全画面化(fullboth)”や最大化されたフレームでは表示されない(サイズのパラメーターを参照)。エクスターナルボーダーの幅はウィンドウマネージャーにより決定されて、Emacsの関数では変更できない。

テキスト端末のフレームではエクスターナルボーダーは存在しない。グラフィカルなフレームではフレームパラメーターoverride-redirectundecoratedをセットすることにより表示を抑制できる(ウィンドウ管理のパラメーターを参照)。

アウターボーダー(Outer Border)

アウターボーダー(outer border)はフレームパラメーターborder-width (レイアウトのパラメーターを参照)で指定可能な分割線。実際にはエクスターナルボーダーとアウターボーダーのいずれかが表示されるが、両方が同時に表示されることはない。アウターボーダーはツールチップフレーム(ツールチップを参照)、子フレーム(子フレームを参照)、およびundecoratedoverride-redirectをセットされたフレーム(ウィンドウ管理のパラメーターを参照)のようにウィンドウマネージャーにより(完全に)制御される特別なフレームでは通常は表示されない。

アウターボーダーはテキスト端末のフレームとGTK+ルーチンが生成したフレームでは表示されない。MS-Windowsではアウターボーダーはピクセル幅が1のエクスターナルボーダーの助けを借りてエミュレートされる。X上でのツールキットによらないビルドではフレームパラメーターborder-colorをセットすることによりアウターボーダーのカラーを変更できる(レイアウトのパラメーターを参照)。

タイトルバー(Title Bar)

タイトルバー(title bar)、いわゆるキャプションバー(caption bar)もウィンドウマネージャーの装飾の一部であり通常はフレームのタイトル(フレームのタイトルを参照)、同様に最小化や最大化、削除のボタンを表示する。これはマウスによるフレームのドラッグにも使用できる。タイトルバーは通常は全画面化(fullboth)されたフレーム(サイズのパラメーターを参照)、ツールチップフレーム(ツールチップを参照)、子フレーム(see 子フレームを参照)では表示されず、端末フレームでは存在しない。タイトルバーの表示はフレームパラメーターoverride-redirectundecoratedをセットすることにより抑制できる(ウィンドウ管理のパラメーターを参照)。

メニューバー(Menu Bar)

メニューバー(メニューバーを参照)にはインターナル(Emacs自身が描画)とエクスターナル(ツールキトが描画)がある。ほとんどのビルド(GTK+、Lucid、Motif、MS-Windows)ではエクスターナルメニューバーを依拠とする。NSもエクスターナルメニューバーを使用するが、これはアウターフレームの一部ではない。非ツールキットのビルドはインターナルメニューバーを提供できる。テキスト端末フレームではメニューバーはフレームのルートウィンドウの一部である(ウィンドウとフレームを参照)。ルールとして子フレームでメニューバーが表示されることはない(子フレームを参照)。パラメーターmenu-bar-lines (レイアウトのパラメーターを参照)をセットすることによりメニューバーの表示は抑制できる。

メニューバーの幅がフレームにフィットするには大きくなりすぎた際に折り返されるか(wrapped)、それとも切り詰められるか(truncated)はツールキットに依存する。通常はMotifとMS-Windowsのビルドだけがニューバーを折り返すことができる。これらはメニューバーの折り返し、またはそれを解除する際にフレームのアウター高さの保持を試みるの、でかわりにフレームのネイティブ高さ(以下参照)が変更される。

ツールバー(Tool Bar)

メニューバーと同じように、ツールバーにはインターナルツールバー(Emacsが描画)とエクスターナルツールバー(ツールキットが描画)がある。GTK+とNSのビルドにはそれらのツールキットが描画するツールバーがある。その他のビルドはインターナルツールバーを使用する。GTK+ではフレームのインタナルボーダー(以下参照)のすぐ外側のいずれかのサイドにツールバーを配置できる。子フレームは通常はツールバーを表示しない(子フレームを参照)。パラメーターtool-bar-lines (レイアウトのパラメーターを参照)に0をセットすることでツールバーの表示を抑制できる。

変数auto-resize-tool-barsが非nilなら、フレームに収まらないほど幅が大きくなるとEmacsはツールバーを折り返す。Emacsがインターナルツールバーの折り返しや折り返しの解除を行う場合には、デフォルトではフレームのアウター高さを未変更に保つので、かわりにフレームのネイティブ高さ(以下参照)が変更される。一方GTK+とともにビルドされたEmacsではツールバーの折り返しは決して行われないが、長くなりすぎたツールバーが収まるようにフレームのアウター幅が自動的に増加される。

タブバー(Tab Bar)

タブバー(Tab Bars in The GNU Emacs Manualを参照)は常にEmacs自身によって描画される。タブバーはインターナルツールバーとともビルドされたEmacsのツールバーの上、エクスターナルツールバーとともにビルドされたEmacsではツールバーの下に表示される。tab-bar-linesパラメーターを0に設定すればタブバーの表示を抑止できる(レイアウトのパラメーターを参照)。

ネイティブフレーム(Native Frame)

ネイティブフレーム(native frame)は全体的にアウターフレーム内に配置される。ネイティブフレームにはエクスターナルボーダーとアウターボーダー、タイトルバーとエクスターナルメニューバーとツールバーが占有する領域は含まれない。ネイティブフレームのエッジ(edge: 端)はフレームのネイティブエッジ(native edges)と呼ばれる。フレームのネイティブサイズ(native size)ハ、フレームのネイティブ幅(native width)ネイティブ高さ(native height)で指定される。

フレームのネイティブサイズはEmacs内のフレームの作成やリサイズをEmacsが行う際にウィンドウシステムやウィンドウマネージャーに渡すサイズである。これはたとえばタイトルバーの対応するボタンのクリックによりフレームを最大化した後やマウスでエクスターナルボーダーをドラッグした際等、フレームの(ウィンドウシステムの)ウィンドウをリサイズする際にウィンドウシステムやウィンドウマネージャーに渡すサイズでもある。

ネイティブフレームの左上隅の位置はフレームのネイティブ位置(native position)を指定する。上図の(1)から(3)は種々のビルドにたいするネイティブ位置を示す。

  • (1) 非ツールキット、Haiku、および端末のフレーム
  • (2) Lucid、Motif、MS-Windowsのフレーム
  • (3) GTK+とNSのフレーム

したがってLucid、Motif、MS-Windowsではネイティブ高さにツールバーの高さは含まれるがメニューバーの高さは含まれず、非ツールキットおよび端末のフレームではメニューバーとツールバーの高さは含まれない。

フレームのネイティブ位置はマウスのカレント位置(マウスの位置を参照)のセットやリターンを行う関数やwindow-edgeswindow-atcoordinates-in-window-pのようにウィンドウ位置(座標とウィンドウを参照)を扱う関数にたいして参照位置となる。これはフレームの子フレームの配置や位置にたいする原点(0, 0)も指定する。

フレームパラメーターoverride-redirectundecorated (ウィンドウ管理のパラメーターを参照)を変更してウィンドウマネージャーの装飾の削除や追加を行う際にも、フレームのネイティブ位置は未変更のままであることにも注意。

インターナルボーダー(Internal Border)

インターナルボーダーはインナーフレーム周囲にEmacsが描画するボーダー(以下参照)。その外観仕様は与えられたフレームが子フレームかどうかによる(子フレームを参照)。

通常のフレームでは、フレームの幅はフレームパラメーターinternal-border-width (レイアウトのパラメーターを参照)、カラーはinternal-borderフェイスのバックグラウンドで指定される。

子フレームでは、フレームの幅はフレームパラメーターchild-frame-border-width (ただしフォールバックとしてinternal-border-widthパラメーターを使用)、カラーはchild-frame-borderフェイスのバックグラウンドで指定される。

インナーフレーム(Inner Frame)

インナーフレーム(inner frame)はフレームのウィンドウにたいして予約された矩形のこと。インナーフレームはインターナルボーダー(これはインナーフレームの一部ではない)に囲われている。インナーフレームのエッジはフレームのインナーエッジ(inner edges)と呼ばれる。この矩形のインナーサイズ(inner size)インアー幅(inner width)インナー高さ(inner height)により指定される。このインナーフレームはフレームのディスプレイエリア(display area)として参照されることもある。

ルールとしてインナーフレームはフレームのルートウィンドウ(ウィンドウとフレームを参照)とミニバッファーウィンドウ(ミニバッファーのウィンドウを参照)に細分される。この2つには注目すべき2つの例外がある。それはミニバッファーウィンドウをもたないルートウィンドウのみのミニバッファーlessフレーム(minibuffer-less frame)と、ミニバッファーウィンドウだけをもち、それがフレームのルートウィンドウの役目も果たすミニバッファーonlyウィンドウ(minibuffer-only frame)である。そのようなフレーム構成を作成する方法はフレームの初期パラメーターを参照のこと。

テキストエリア(Text Area)

フレームのテキストエリア(text area)はネイティブフレームに埋め込み可能な一種の架空領域である。テキストエリアの位置は指定されない。テキストエリアの幅はネイティブ幅からインターナルボーダーの幅、そのフレームに指定されていれば(レイアウトのパラメーターを参照)1つの垂直スクロールバーの幅、左右のフリンジ各1の幅を取り除くことにより取得できる。テキストエリアの高さはネイティブ高さからインターナルボーダーの幅、そのフレームに指定されていればフレームのインターナルのメニューバー、ツールバー、タブバーの高さ、1つの水平スロールバーの高さを取り除くことにより取得できる。

フレームの絶対位置(absolute position)は(X, Y)というペア、またはフレームのディスプレイの原点(0, 0)から相対的な水平および垂直のピクセル単位のオフセットにより与えられる。これに対応してフレームの絶対エッジ(absolute edges)はこの原点からのピクセル単位のオフセットにより与えられる。

マルチモニターではディスプレイの原点が端末の利用可能な表示エリア全体の左上隅と一致する必要はない。したがってそのような環境では、たとえそのフレームが完全に可視であってもフレームの絶対位置は負の値になり得る。

慣例により垂直方向のオフセットは“下方向”にたいして増加する。これはフレームの下エッジから上エッジのオフセットを減ずることによりフレームの高さが得られることを意味する。期待されるように水平方向のオフセットは“右方向”にたいして増加するので、フレームの右エッジから左エッジのオフセットを減ずることによりフレームの幅を計算できる。

以下の関数はグラフィカル端末上のフレームにたいして上述したエリアのサイズをリターンします:

Function: frame-geometry &optional frame

この関数はframeの幾何学的な属性をリターンする。リタ^ン値は以下のような属性のリストの連想リスト。すべての座標、高さや幅の値はピクセル単位の整数。まだframeがマップされていなければ(フレームの可視性を参照)、いくつかのリターン値は実際の値の近似値しか表していないかもしれない(それらの値はフレームのマップ後に確認可能になる)。

outer-position

frameのアウターフレームの絶対位置を表すコンスであり、frameのディスプレイの原点(0, 0)から相対的な位置。

outer-size

frameのアウター幅とアウター高さを表すコンス。

external-border-size

ウィンドウマネージャーにより与えられる、frameエクスターナルボーダーの水平幅と垂直幅を表すコンス。ウィンドウマネージャーによりこれらの値が提供されなければ、Emacsはアウターフレームとインナーフレームの座標からそれらの推測を試みる。

outer-border-width

frameのアウターボーダーの幅。この値は非GTK+のXビルドでのみ意味がある。

title-bar-size

ウィンドウマネージャーまたはオペレーティングシステムが与える、frameのタイトルバーの幅と高さを表すコンス。いずれも0なら、そのフレームにタイトルバーはない。幅だけが0なら、Emacsが幅の情報を取得できなかったことを意味する。

menu-bar-external

nilなら、それはメニューバーがエクスターナルである(frameのネイティブフレームの一部ではない)ことを意味する。

menu-bar-size

frameのメニューバーの幅と高さを表すコンス。

tool-bar-external

nilなら、それはツールバーがエクスターナルである(frameのネイティブフレームの一部ではない)ことを意味する。

tool-bar-position

これはツールバーがframeのどの端に配置されているかを示しlefttoprightbottomのいずれか。現在のところtop以外の値をサポートするツールキットはGTK+のみ。

tool-bar-size

frameのツールバーの幅と高さを表すコンス。

internal-border-width

frameのインターナルボーダーの幅。

以下の関数はフレームにたいするアウター、ネイティブ、インナーのエッジの取得に使用できます。

Function: frame-edges &optional frame type

この関数はframeのアウター、ネイティブ、インナーフレームの絶対エッジをリターンする。frameは生きたフレームでなければならずデフォルトは選択されたフレーム。リターンされるリストは(left top right bottom)という形式をもつ。すべてframeのディスプレイの原点から相対的なピクセル単位の値。端末フレームではlefttopにたいしてリターンされる値は常に0。

オプション引数typeはリターンするエッジのタイプを指定する。outer-edgesframeのアウターエッジ、native-edges (かnil)はネイティブエッジ、inner-edgesはインナーエッジをリターンすることを意味する。

慣例によりlefttopにたいしてリターンされたディスプレイのピクセル位置はframeの内部(一部)とみなされる。したがってlefttopがいずれも0なら、ディスプレイの原点のピクセル位置はframeの一部となる。その一方でbottomrightのピクセル位置はframeのすぐ外側にあるとみなされる。これはたとえば2つの横並びのフレームがあり、左フレームの右アウトーエッジが右フレームの左エッジと等しければ、そのエッジ上のピセルは右フレームの一部として表されることを意味する。


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

30.3.2 フレームのフォント

フレームにはそれぞれ、そのフレームにたいするデフォルト文字サイズを指定するデフォルトフォント(default font)があります。このサイズは、行や列の単位でのフレームサイズの取得や変更での使用を意図したものです(サイズのパラメーターを参照)。これはウィンドウのリサイズ(ウィンドウのサイズを参照)や分割(ウィンドウの分割を参照)の際にも使用されます。

“デフォルト文字高さ(default character height)t”のかわりに行高さ(line height)正準文字高さ(canonical character height)という用語を使用するときがあります。同様に“デフォルト文字幅(default character width)”のかわりに列幅(column width)正準文字幅(canonical character width)という用語も使用されます。

Function: frame-char-height &optional frame
Function: frame-char-width &optional frame

これらの関数はピクセルで測ったframe内の文字のデフォルトの高さまたは幅をリターンする。両者をあわせたサイズによりframeframeのサイズが確立される。値はframeにたいして選択されたフォントに依存する。フォントとカラーのパラメーターを参照のこと。

以下の関数でデフォルトフォントを直接セットすることもできます:

Command: set-frame-font font &optional keep-size frames

これはデフォルトフォントにfontをセットする。インタラクティブに呼び出された際にはフォント名の入力を求めて、選択されたフレームにそのフォントを使用する。Lispから呼び出す際には、fontはフォント名(文字列)、フォントオブジェクト、フォントエンティティー、フォントspecのいずれかであること。

オプション引数keep-sizenilならフレームの行数と列数を固定に保つ(非nilなら次セクションで説明するオプションframe-inhibit-implied-resizeがこれをオーバーライドするだろう)。keep-sizeが非nil (またはプレフィクス引数を指定)なら行数と列数を調節することにより、カレントフレームのディスプレイエリアのサイズの維持を試みる。

オプション引数framesnilなら、そのフォントは選択されたフレームだけに適用される。framesが非nilならそれは作用するフレームのリスト、またはすべての既存フレームおよび将来のすべてのグラフィカルフレームを意味するtのいずれかであること。


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

30.3.3 フレームの位置

グラフィカルなシステムでは通常のトップレベルのフレームの位置はアウターフレームの絶対位置として指定されます(フレームのジオメトリーを参照)。子フレーム(子フレームを参照)の位置は親フレームのネイティブ位置から子フレームのアウターエッジまでのピクセル単位のオフセットとして相対的に指定されます。

フレーム位置はフレームパラメーターlefttop(位置のパラメーターを参照)を使用すれば変更やアクセスができます。既存の可視なフレームの位置を処理するために追加で2つの関数が存在します。いずれの関数でも引数frameは生きたフレームでなければならず、デフォルトは選択されたフレームです。

Function: frame-position &optional frame

この関数は子フレームではない通常のフレームにたいしてフレームのアウター位置(フレームのレイアウトを参照)を、フレームのディスプレイの原点(0, 0)からのピクセル座標をコンスセルでリターンする。子フレーム(子フレームを参照)にたいしてはフレームのアウター位置を、frameのネイティブ位置を原点(0, 0)として、そこからのピクセル座標をリターンする。

負の値はframeのディスプレイまたは親フレームの右エッジか下エッジからのオフセットではない。これらはframeのアウター位置が、フレームのデイスプレイの原点または親フレームのネイティブ位置の左および/または上にあることを意味する。これは通常はframeの一部だけが可視(または完全に不可視)であることを意味している。しかしディスプレイの原点がディスプレイの左上隅と一致しないシステムではセカンダリーモニター上ではフレームは可視かもしれない。

てきすと端末ではいずれの値も0。

Function: set-frame-position frame x y

この関数はframeのアウターフレームの位置を(x, y)にセットする。後の引数は通常はframeのディスプレイの位置(0, 0)にある原点からのピクセル数、子フレームではframeの親フレームのネイティブ位置からのピクセル数。

負のパラメーター値はアウターフレームの右エッジをスクリーンの右エッジ(または親フレームのネイティブ矩形位置)から左に-xピクセル、または下エッジをスクリーンの下エッジ(または親フレームのネイティブ矩形位置)から上に-yピクセルの位置にセットする。

負の値ではframeの右エッジや下エッジを性格にディスプレイや親フレームの右エッジや下エッジには揃えられないことに注意。負の値ではディスプレイや親フレーム内にあるエッジにある位置は指定できない。フレームパラメーターlefttop (位置のパラメーターを参照)でこれを行うことはできるものの、初期フレームや新たなフレームでは依然として良好な結果は得られないかもしれない。

この関数はテキスト端末フレームでは効果がない。

Variable: move-frame-functions

このフックはウィンドウシステムやウィンドウマネージャーがフレームを(新たな位置を割り当てて)移動した際に実行される関数を指定する。関数は移動されたフレームを単一の引数として実行される。子フレーム(子フレームを参照)では親フレームとの関連性においてのフレーム位置が変更されたときだけ関数が実行される。


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

30.3.4 フレームのサイズ

Emacs内からフレームサイズ(size of a frame)を指定する正規の方法はテキストサイズ(text size)の指定による方法です(フレームのテキストエリアの幅と高さの組み合わせ。フレームのレイアウトを参照)。これはピクセルやフレームの標準の文字サイズ(フレームのフォントを参照)で計ることができます。

インターナルメニューやインターナルツールバーのあるフレームでは実際にフレームが描画されるまでフレームのネイティブ高さを告げることはできません。一般的にこれはフレームの初期サイズの指定にネイティブサイズを使用できないことを意味しています。可視フレームのネイティブフレームが解り次第、frame-geometryのリターン値から残りのコンポーネントを追加してアウターサイズ(フレームのレイアウトを参照)を計算できます。しかし不可視のフレームやまだ作成されていないフレームにたいするアウターサイズは推定しかできません。これはスクリーンの右エッジや下エッジからのオフセットの指定ではフレームの正確な初期位置を計算することが不可能であることも意味しています(フレームの位置を参照)。

フレームのテキストサイズはフレームパラメーターheightwidthを使用してセットや取得が可能です(サイズのパラメーターを参照)。初期フレームのテキストサイズはX様式のジオメトリー仕様でもセットや取得が可能です。Command Line Arguments for Emacs Invocation in The GNU Emacs Manualを参照してください。以下に既存で可視なフレーム(デフォルトは選択されたフレーム)のサイズにたいしてセットやアクセスを行う関数をいくつかリストします。

Function: frame-height &optional frame
Function: frame-width &optional frame

これらの関数はframeのテキストエリアの高さと幅を、frameのデフォルトフォントの高さと幅を単位に計測してリターンする。これらの関数は単に(frame-parameter frame 'height)(frame-parameter frame 'width)を略記したもの。

ピクセルで計測したframeのテキストエリアがデフォルトフォントサイズの倍数でなければ、これらの関数がリターンする値はテキストエリアに完全に収まるデフォルトフォントの文字数に切り捨てられる。

以下の関数は与えられたフレームのネイティブフレーム、アウターフレーム、インナーフレーム、テキストエリアのピクセル幅とピクセル高さをリターンします(フレームのレイアウトを参照)。テキスト端末では結果はピクセルではなく文字単位になります。

Function: frame-outer-width &optional frame
Function: frame-outer-height &optional frame

これらの関数はframeのアウター幅やアウター高さをピクセル単位でリターンする。

Function: frame-native-height &optional frame
Function: frame-native-width &optional frame

これらの関数はframeのネイティブ幅やネイティブ高さをピクセル単位でリターンする。

Function: frame-inner-width &optional frame
Function: frame-inner-height &optional frame

これらの関数はframeのインナー幅やインナー高さをピクセル単位でリターンする。

Function: frame-text-width &optional frame
Function: frame-text-height &optional frame

これらの関数はframeのテキストエリアの幅や高さをピクセル単位でリターンする。

ウィンドウシステムがサポートしていれば、Emacsはデフォルトでフレームのピクセル単位でのテキストサイズをフレームの文字サイズの倍数にしようと試みます。しかし通常これはエクスターナルボーダーのドラッグ時にフレームが文字サイズの増減だけでリサイズできることを意味しています。さらにこれはフレームの下および/または右に空のスペースが残ることにより、フレームを最大化したり“fullheight”や“fullwidth”にする試みを阻害するかもしれません。このような場合には以下のオプションが助けになるでしょう。

User Option: frame-resize-pixelwise

このオプションがnil (デフォルト)ならフレームのテキストのピクセルサイズは、フレームのリサイズの際に通常はframe-char-heightframe-char-widthのカレント値の倍数に丸められる。非nilなら丸めは行われず、フレームのサイズはピクセル単位で増加/減少が可能になる。

この変数をセットすることにより次回のリサイズ処理では、通常はウィンドウマネージャーにこれに相当するサイズのヒントを渡す。これはユーザーの初期ファイル内でのみこの変数をセットすべきで、アプリケーションが一時的にこれをバインドすべきではないことを意味する。

このオプションにたいしてnil値がもつ正確な意味は使用されるツールキットに依存する。マウスによるエクスターナルボーダーのドラッグは、ウィンドウマネージャーが対応するサイズヒントを処理する意思があれば文字単位で行われる。文字サイズの整数倍ではないフレームサイズを引数としてset-frame-size (以下参照)を呼び出すと、もしかしたら丸められたり(GTK+)、あるいは受容される(Lucid、Motif、MS-Windows)かもしれない。

いくつかのウィンドウマネージャーでは、フレームを本当に最大化や全画面で表示させるために、これを非nilにセットする必要があるかもしれない。

Function: set-frame-size frame width height &optional pixelwise

この関数はframeのテキストエリアのサイズを、frameの文字の正準高さと正準幅で計測した単位でセトする(フレームのフォントを参照)。

オプション引数pixelwiseが非nilなら、かわりにピクセル単位で新たな幅と高さを測ることを意味する。frame-resize-pixelwisenilの場合には、それが文字の整数倍でフレームサイズを増加あるいは減少させないなら、この要求を完全にはしたがわずに拒絶するツールキットがいくつかあることに注意。

Function: set-frame-height frame height &optional pretend pixelwise

この関数はframeのテキストエリアをheight行の高さにリサイズする。frame内の既存ウィンドウのサイズはフレームにフィットするよう比例して変更される。

pretendが非nilなら、Emacsはframe内でheight行の出力を表示するが、そのフレームの実際の高さにたいする値は変更しない。これはテキスト端末上でのみ有用。端末が実際に実装するより小さい高さの使用は、より小さいスクリーン上での振る舞いの再現したり、スクリーン全体を使用時の端末の誤動作を観察するとき有用かもしれない。フレームの高さの直接セットは常に機能するとは限らない。なぜならテキスト端末上でのカーソルを正しく配置するために、正確な実サイズを知る必要があるかもしれないからである。

オプションの第4引数pixelwiseが非nilなら、それはframeの高さがheightピクセル高くなることを意味する。frame-resize-pixelwisenilの場合、それが文字の整数倍でフレームサイズを増加あるいは減少させないなら、この要求に完全にはしたがわずに拒絶するウィンドウマネージャーがいくつかあることに注意。

インタラクティブにこのコマンドを使用時には、このコマンドはカレントで選択されたフレーム高さをセットするための行数をユーザーに尋ねる。

Function: set-frame-width frame width &optional pretend pixelwise

この関数は文字単位でframeのテキストエリアの幅をセットする。引数pretendset-frame-heightのときと同じ意味をもつ。

オプションの第4引数pixelwiseが非nilなら、それはframeの幅がheightピクセル広くなることを意味する。frame-resize-pixelwisenilの場合には、それが文字の整数倍でフレームサイズを増加あるいは減少させないなら、この要求に完全にはしたがわずに拒絶するウィンドウマネージャーがいくつかあることに注意。

インタラクティブにこのコマンドを使用時には、このコマンドはカレントで選択されたフレーム幅をセットするための列数をユーザーに尋ねる。

これらの3つの関数はスクロールバー、フリンジ、マージン、ディバイダー、モードラインやヘッダーラインと一緒にすべてのウィンドウを表示するために必要な最小よりフレームを小さくしません。これはたとえばマウスによるフレームのエクスターナルボーダーのドラッグなどによるウィンドウマネージャーがトリガーとなる要求と対照的です。このような要求は、もし必要なら表示できないフレームの右下隅の部分をクリッピングすることにより常に尊重されます。Emacs内からのフレームサイズの変更時に同様の振る舞いを得るには、パラメーターmin-widthmin-heightを使用できます(サイズのパラメーターを参照)。

アブノーマルフックwindow-size-change-functions (ウィンドウのスクロールと変更のためのフックを参照)はウィンドウシステムやウィンドウマネージャーに起因するのもを含む、フレームのインナーサイズの変更のすべてを追跡します。実際にインナーフレームのサイズを変更せずにフレームのウィンドウのサイズだけを変更した際に発生するかもしれない誤検出を除外するために以下の関数を使用できます。

Function: frame-size-changed-p &optional frame

この関数はframeにたいして最後にwindow-size-change-functionsが実行されて以降にframeのインナー幅かインナー高さが変更されていれば非nilをリターンする。これはframeにたいするwindow-size-change-functionsの実行直後は常にnilをリターンする。


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

30.3.5 フレームの暗黙的なリサイズ

たとえばメニューバーやツールバーの表示切り替え、デフォルトフォントの変更、フレームのスクロールバーの幅のセットの際には、Emacsはデフォルトではフレームのテキストエリアの行数と列数を未変更に保つように試みます。しかしこれはそのような場合のサイズ変更を調停するために、Emacsがウィンドウマネージャーにフレームのウィンドウのリサイズを依頼しなければならないことを意味します。

たとえばフレームの最大化や全画面化の際のように、そのような暗黙なフレームのリサイズ(implied frame resizing)がおそらく望ましくないケースもあります(デフォルトではオフになっている)。一般的には以下のオプションで暗黙のリサイズを無効にできます。

User Option: frame-inhibit-implied-resize

このオプションがnilならフレームのフォント、メニューバー、ツールバー、インターナルボーダー、フリンジ、スクロールバーを変更においてフレームのテキストエリアの列数と行数を維持するために、アウターフレームがリサイズされるかもしれない。このオプションがtならそのようなリサイズは行われない。

このオプションの値はフレームパラメーターのリストでもよい。この場合にはリスト内に出現するパラメーター変更にたいする暗黙のリサイズは抑制される。このオプションで処理されるフレームパラメーターは現在のところfontfont-backendinternal-border-widthmenu-bar-linestool-bar-lines

フレームパラメーターscroll-bar-widthscroll-bar-heightvertical-scroll-barshorizontal-scroll-barsleft-fringeright-fringeのいずれかにたいする変更は、あたかもそのフレームが単一の生きたウィンドウを含むかのように処理される。これはたとえば複数の横並びのウィンドウをフレームで垂直スクロールバーを削除すると、このオプションがnilならnilはスクロールバーの幅の分だけ縮小されて、tvertical-scroll-barsを含む場合には未変更に保たれることを意味する。

Lucid、Motif、MS-Windowsのデフォルト値は(tab-bar-lines tool-bar-lines)であり、これはツールバーやタブバーの追加や削除でアウターフレーム高さが変更されないことを意味する。GTK+を含むその他すべてのウィンドウシステムでは(tab-bar-lines)であり、これは上記リストのtab-bar-lines以外のパラメーターのいずれかを変更するとアウターフレームのサイズは変更されるかもしれないことを意味する。それ以外ではtであり、これはウィンドウシステムのサポートがなければ暗黙にアウターフレームのサイズが変更されることはないことを意味する。

フレームが上述のいずれかのパラメーターにたいする変更の調停に不十分な際には、たとえこのオプションが非nilでもEmacsがフレームの拡大を試みるかもしれないことに注意。

ウィンドウマネージャーは通常はエクスターナルメニューバーやエクスターナルツールバーが占有する行数の変更時にフレームのリサイズを要求しないことにも注意。典型的にはこのような“折り返し(wrappings)”はユーザーがフレームのメニューバーやツールバーのすべての要素を表示できないほどフレームを水平方向に縮小しや際に発生する。これはメニューバーやツールバーのアイテム数を変化させるようなメジャーモードの変更によっても発生し得る。このような折り返しはフレームのテキストエリアの行数を暗黙に変更するかもしれ、このオプションのセットによる影響を受けない。


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

30.4 フレームのパラメーター

フレームにはその外見と挙動を制御する多くのパラメーターがあります。フレームがどのようなパラメーターをもつかは、そのフレームが使用するディスプレイのメカニズムに依存します。

フレームパラメーターは主にグラフィカルディスプレイのために存在します。ほとんどのフレームパラメーターはテキスト端末上のフレームへの適用時には効果がありません。テキスト端末上のフレームで何か特別なことを行うパラメーターはheightwidthnametitlemenu-bar-linesbuffer-listbuffer-predicateだけです。その端末がカラーをサポートする場合にはforeground-colorbackground-colorbackground-modedisplay-typeなどのパラメーターも意味をもちます。その端末が透過フレーム(frame transparency)をサポートする場合には、パラメーターalphaにも意味があります。

デフォルトでは変数desktop-restore-framesが非nilのときには、フレームパラメーターはデスクトップライブラリー関数(Desktop Saveモードを参照)が保存とリストアを行います。リストアされたセッションでは無意味や有害になることを避けるためにパラメーターをframeset-persistent-filter-alistに含めるのはアプリケーションの責任です。


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

30.4.1 フレームパラメーターへのアクセス

以下の関数でフレームのパラメーター値の読み取りと変更ができます。

Function: frame-parameter frame parameter

この関数はframeのパラメーターparameter (シンボル)の値をリターンする。framenilなら選択されたフレームのパラメーターをリターンする。frameparameterにたいするセッティングをもたなければ、この関数はnilをリターンする。

Function: frame-parameters &optional frame

関数frame-parametersframeのすべてのパラメーターとその値をリストするalistをリターンする。frameが省略またはnilなら選択されたフレームのパラメーターをリターンする。

Function: modify-frame-parameters frame alist

この関数はalistの要素にもとづきフレームframeを変更する。alist内の要素はそれぞれ(parm . value)という形式をもつ。ここでparmはパラメーターを名付けるシンボルである。 alist内に指定されないパラメーターの値は変更されない。framenilの場合のデフォルトは選択されたフレーム。

いくつかのパラメーターは特定の種類のディスプレイ上のフレーム(フレームを参照)でのみ意味がある。frameのディスプレイで意味をもたないパラメーターがalistに含まれているようなら、この関数はそのフレームのパラメーターリスト内の値を変更するが、その他の値を変更しないパラメーターは無視するだろう。

frameの新たなサイズに影響し得る値をもつようなパラメーターがalistで複数指定されている際には、フレームの最終的なサイズは使用しているツールキットに応じて異なるかもしれない。たとえばあるフレームにたいしてメニューバーおよび/またはツールバーをもたない状態から保有するように指定して、同時に新たなフレーム高さを指定すると、必然的にフレームの高さの再計算を招くだろう。そのようなケースでは、概念的にはこの関数は明示的な高さ指定を優先するよう試みる。しかしツールキットによりその後に処理されるメニューバーやツールバーの追加(や削除)を除外することはできないので、高さ指定を優先するという意図は打ち消されてしまうだろう。

ここで概略した問題は、この関数の呼び出し前後にframe-inhibit-implied-resize (フレームの暗黙的なリサイズを参照)を非nil値にバインドすることで訂正できる場合がある。しかしそのようなバインディングが正に問題を引き起こす場合もある。

Function: set-frame-parameter frame parm value

この関数はフレームパラメーターparmに指定されたvalueをセットする。framenilの場合のデフォルトは選択されたフレーム。

Function: modify-all-frames-parameters alist

この関数は alistに応じて既存のフレームすべてのフレームパラメーターを変更してから、今後に作成されるフレームに同じパラメーター値を適用するために、default-frame-alist (必要ならinitial-frame-alistも)を変更する。


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

30.4.2 フレームの初期パラメーター

initファイル(initファイルを参照)の内部でinitial-frame-alistをセットすることにより、フレームの初期スタートアップにパラメーターを指定できます。

User Option: initial-frame-alist

この変数の値は初期フレーム作成時に使用されるパラメーター値のalist。以降のフレームを変更することなく初期フレームの外見を指定するためにこの変数を使用できる。要素はそれぞれ以下の形式をもつ:

(parameter . value)

Emacsはinitファイル読み取り前に初期フレームを作成する。Emacsはこのファイル読み取り後にinitial-frame-alistをチェックして、変更する値に含まれるパラメーターのセッティングを作成済みの初期フレームに適用する。

これらのセッティングがフレームのジオメトリーと外見に影響する場合には、間違った外見のフレームを目にした後に、指定した外見に変更される様を目にするだろう。これが煩わしければ、Xリソースで同じジオメトリーと外見を指定できる。これらはフレーム作成前に効果をもつ。X Resources in The GNU Emacs Manualを参照のこと。

Xリソースセッティングは、通常はすべてのフレームに適用される。初期フレームのためにあるXリソースを単独で指定して、それ以降のフレームには適用したくなければ、次の方法によりこれを達成できる。それ以降のフレームにたいするXリソースをオーバーライドするためにdefault-frame-alist内でパラメーターを指定してから、それらが初期フレームに影響するのを防ぐためにinitial-frame-alist内の同じパラメーターにたいしてXリソースにマッチする値を指定すればよい。

これらのパラメーターに(minibuffer . nil)が含まれていれば、それは初期フレームがミニバッファーをもつべきではないことを示しています。この場合には、Emacsは同じようにミニバッファーonlyフレーム(minibuffer-only frame)を個別に作成します。

User Option: minibuffer-frame-alist

この変数の値は、初期ミニバッファーonlyフレーム( initial-frame-alistがミニバッファーのないフレームを指定する場合にEmacsが作成するミニバッファーonlyフレーム)を作成時に使用されるパラメーター値のalist。

User Option: default-frame-alist

これはすべてのEmacsフレーム(最初のフレームとそれ以降のフレーム)にたいしてフレームパラメーターのデフォルト値を指定するalist。Xウィンドウシステム使用時には、大抵はXリソースで同じ結果を得られる。

この変数のセットは既存フレームに影響しない。さらに別フレームにバッファーを表示する関数は、自身のパラメーターを提供することによりデフォルトパラメーターをオーバーライドできる。

フレームの外見を指定するコマンドラインオプションとともにEmacsを呼び出すと、これらのオプションはinitial-frame-alistdefault-frame-alistのいずれかに要素を追加することにより効果を発揮します。‘--geometry’や‘--maximized’のような初期フレームだけに影響するオプションはinitial-frame-alist、その他のオプションはdefault-frame-alistに要素を追加します。Command Line Arguments for Emacs Invocation in The GNU Emacs Manualを参照してください。


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

30.4.3 ウィンドウフレームパラメーター

フレームがどんなパラメーターをもつかは、どのようなディスプレイのメカニズムがそれを使用するかに依存します。このセクションでは一部、またはすべての端末種類において特別な意味をもつパラメーターを説明します。これらのうちnametitleheightwidthbuffer-listbuffer-predicateは端末フレームにおいて意味をもつ情報を提供し、tty-color-modeはテキスト端末上のフレームにたいしてのみ意味があります。


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

30.4.3.1 基本パラメーター

以下のフレームパラメーターはフレームに関するっとも基本的な情報を提供します。titlenameはすべての端末において意味をもちます。

display

このフレームをオープンするためのディスプレイ。これは環境変数DISPLAYのような‘host:dpy.screen’という形式の文字列であること。ディスプレイ名についての詳細は、複数の端末を参照のこと。

display-type

このパラメーターはこのフレーム内で使用できる利用可能なカラーの範囲を記述する。値はcolorgrayscalemonoのいずれか。

title

フレームが非nilのtitleをもつ場合には、そのタイトルがフレーム上端にあるウィンドウシステムのタイトルバーに表示される。mode-line-frame-identificationに‘%F’ (モードラインでの%構文を参照)を使用していればそのフレーム内のウィンドウのモードラインにも表示される。これは通常はEmacsがウィンドウシステムを使用しておらず、かつ同時に1つのフレームのみ表示可能なケースが該当する。フレームのタイトルを参照のこと。Emacsがウィンドウシステムを使用している際にこのパラメーターが非nilだと、nameによって決定されたタイトルがオーバーライドされて、frame-title-formatに応じて暗黙裡にタイトルが計算される。更にicon-title-formatによって決定されたアイコン化されたフレームのタイトルもオーバーライドする。フレームのタイトルを参照のこと。

name

フレームの名前。このパラメーターを通じて名前を指定しなければ、Emacsがframe-title-formaticon-title-formatで指定されたフレーム名を自動的にセットする。そしてEmacsがウィンドウシステムを使用している際には、(titleパラメーターによってオーバーライドされていなければ)これがフレームのタイトルとして表示される。

フレーム作成時に明示的にフレーム名を指定すると、そのフレームにたいしてXリソースを照合する際にも、(Emacs実行可能形式名のかわりに)その名前が使用される。

explicit-name

フレーム作成時にフレーム名が明示的に指定されると、このパラメーターはその名前。明示的に名付けられなかったら、このパラメーターはnil


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

30.4.3.2 位置のパラメーター

フレームのXY方向のオフセットを記述するパラメーターは常にピクセル単位です。子フレームではない通常のフレームでは、フレームのアウター位置(フレームのジオメトリーを参照)はディスプレイの原点から相対的に指定されます子フレーム(子フレームを参照)では、フレームのアウター位置は親フレームのネイティブ位置から相対的に指定されます(これらのパラメーターにTTYフレームで意味のあるものはないことに注意)。

left

フレームのディスプレイ(か親フレーム)の左エッジからフレームの左アウターエッジまでのピクセル単位での位置。以下のいずれかの方法で指定できる。

整数

正の整数はフレームの左エッジをディスプレイ(か親フレーム)の左エッジ、負の整数はフレームの右エッジをディスプレイ(か親フレーム)の右エッジに相対的に指定する。

(+ pos)

これはディスプレイ(か親フレーム)の左エッジにたいしフレームの左エッジの相対的位置を指定する。整数posは正と負の値をとり得る。負の値はスクリーン(か親フレーム)の外側、または(マルチモニターディスプレイにたいしては)プライマリーモニター以外のモニター上の位置を指定する。

(- pos)

これはディスプレイ(か親フレーム)ノ右エッジにたいしフレームノ右エッジの相対的位置を指定する。整数posは正ト負の値をとり得る。負の値はスクリーン外側、または(マルチモニターディスプレイにたいしては)プライマリーモニター以外のモニター上の位置を指定する。

a floating-point value

0.0から1.0の範囲の浮動小数点数はフレームの左位置比率(left position ratio)を通じて左エッジのオフレットを指定する。これはアウターフレームの左エッジの位置にたいする、フレームのワークエリア(複数の端末を参照)または親のネイティブフレーム(子フレームを参照)からアウターフレームの幅を減じた値との比率。したがって左位置比率0.0はディスプレイ(か親フレーム)の左、比率0.5は中央、1.0は右に揃える。同様に上位置比率(top position ratio)はアウターフレームの上エッジの位置にたいする、フレームのワークエリア(か親のネイティブフレーム)からフレームの高さを減じた値との比率。

Emacsは子フレームのパラメーターkeep-ratio (フレームとの相互作用のためのパラメーターを参照)が非nilなら、親フレームがリサイズされた場合に子フレームの位置比率を未変更のままにしようと試みる。

通常はフレームが可視になるまでフレームのアウターサイズ(フレームのジオメトリーを参照)は利用できないので、装飾つきのフレーム作成時には浮動小数点値の一般的には使用はできない。浮動小数点値は親フレームの領域内で子フレームの適切な配置を保証したい場合により適している。

プログラム指定の位置を無視するウィンドウマネージャーがいくつかある。指定した位置が無視されない保証を望む場合には、パラメーターuser-positionにも以下の例のように非nil値を指定すること。

(modify-frame-parameters
  nil '((user-position . t) (left . (+ -4))))

一般的にフレームをディスプレイの右エッジや下エッジから相対的に配置するのは良いアイデアではない。初期フレームや新たなフレームの配置は不正確になる(フレームが可視になるまでアウターフレームのサイズは完全には解らない)か、または(可視になった後にフレームが再配置されると)追加のちらつき(flickering)をもたらすだろう。

さらにディスプレイ(やワークエリア、親フレーム)の右エッジや下エッジから相対的に指定された位置、同様に浮動小数点数のオフセットは内部的にはディスプレイ(やワークエリア、親フレーム)の左エッジや上エッジから相対的な整数のオフセットとして格納されることに注意。これらの値はframe-parametersのような関数によるリターン値やデスクトップ保存ルーチンのリストアにも使用される。

top

ディスプレイ(か親フレーム)の上エッジ(下エッジ)にたいして、上エッジ(下エッジ)のスクリーン位置をピクセル単位で指定する。方向が水平ではなく垂直である点を除イテ、これはleftと同様に機能する。

icon-left

スクリーン左エッジから数えた、フレームアイコン左エッジのピクセル単位のスクリーン位置。ウィンドウマネージャーがこの機能をサポートすれば、これはフレームをアイコン化したとき効果を発揮する。このパラメーターに値を指定する場合にはicon-topにも値を指定しなければならず、その逆も真。

icon-top

スクリーン上端から数えたフレームアイコン上端のピクセル単位のスクリーン位置。ウィンドウマネージャーがこの機能をサポートすれば、これはフレームをアイコン化したときに効果を発揮する。

user-position

フレームを作成してパラメーターlefttopで位置を指定する際は、指定した位置がユーザー指定(人間であるユーザーにより明示的に要求された位置)なのか、それとも単なるプログラム指定(プログラムにより選択された位置)なのかを告げるためにこのパラメーターを使用する。非nil値はそれがユーザー指定の位置であることを告げる。

ウィンドウマネージャーは一般的にユーザー指定位置に留意するとともに、プログラム指定位置にも幾分か留意する。しかし多くのウィンドウマネージャーはプログラム指定位置を無視して、ウィンドウをウィンドウマネージャーのデフォルトの方法で配置するかユーザーのマウスによる配置に任せる。twmを含むウィンドウマネージャーのいくつかは、プログラム指定位置にしたがうか無視するかをユーザーの指定に任せる。

make-frameを呼び出す際にパラメーターlefttopの値がそのユーザーにより示される嗜好を表すなら、このパラメーターに非nil値、それ以外はnilを指定すること。

z-group

このんパラメーターはフレームのウィンドウシステム的なウィンドウの相対位置を、フレームのディスプレイのスタック順(Zオーダー)で指定する。

これがaboveならウィンドウシステムは、aboveプロパティがセットされていない他のすべてのウィンドウシステムのウィンドウの前面にフレームに対応するウィンドウを表示する。nilならフレームのウィンドウはaboveプロパティがセットされたすべてのウィンドウの背後、かつbelowプロパティがセットされたすべてのウィンドウの前面に表示される。belowならフレームのウィンドウはbelowプロパティがセットされていないすべてのウィンドウの背後に表示される。

特定のフレームの前面や背後にフレームを配置するためには関数frame-restackを使用すること(フレームのraise、lower、re-stackを参照)。


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

30.4.3.3 サイズのパラメーター

フレームパラメーターは通常はフレームのサイズを文字単位で指定します。グラフィカルなディスプレイ上ではdefaultフェイスがこれら文字単位の実際のピクセルサイズを決定します(フェイスの属性を参照)。

width

このパラメーターはフレームの幅を指定する。これは以下の方法でも指定できる:

整数

フレームのテキストエリア(フレームのジオメトリーを参照)の幅を文字単位で指定する正の整数。

a cons cell

これがCARにシンボルtext-pixelsをもつコンスセルなら、CDRはフレームのテキストエリアの幅をピクセル単位で指定する。

a floating-point value

0.0から1.0の範囲の浮動小数点数はフレームの幅比率(width ratio)を通じてフレームの幅の指定に使用できる。これはアウター幅(フレームのジオメトリーを参照)にたいする、フレームのワークエリア(複数の端末を参照)または親フレームのネイティブフレーム(子フレームを参照)からアウターフレームの幅を減じた値との比率。したがって値0.5はワークエリア(か親フレーム)の半分の幅、値1は全幅をフレームに占有させる。同様に高さ比率(height ratio)はアウターフ高さにたいする、フレームのワークエリア(か親のネイティブフレーム)からフレームの高さとの比率。

Emacsは子フレームのパラメーターkeep-ratio (フレームとの相互作用のためのパラメーターを参照)が非nilなら、親フレームがリサイズされた場合に子フレームの幅と高さの比率を未変更のままにしようと試みる。

通常はフレームが可視になるまでフレームのアウターサイズ(フレームのジオメトリーを参照)は利用できないので、装飾つきのフレーム作成時には浮動小数点値の一般的には使用はできない。浮動小数点値は、たとえばdisplay-buffer-in-child-frameを通じてdisplay-buffer-alist (バッファーを表示するウィンドウの選択を参照)をカスタマイズする際に親フレームの領域内へ常に子フレームを確実にフィットさせたい場合により適している。

パラメーターの指定方法にかかわらず、このパラメーターの値を報告するframe-parametersのような関数は、常にフレームのデフォルトの文字幅の倍数にするために必要に応じて丸めを行いフレームのテキストエリアの幅を整数でリターンする。この値はデスクトップ保存ルーチンでも使用される。

height

このパラメーターはフレームの高さを指定する。これは水平ではなく垂直であるという点を除きwidthのように機能する。

user-size

これはサイズパラメーターheightwidthにたいして、user-position (user-positionを参照)がtopleftが行うのと同じことを行う。

min-width

このパラメーターはフレームの最小ネイティブ幅(フレームのジオメトリーを参照)を文字単位で指定する。フレームの初期幅やフレームを水平方向にリサイズする関数は、通常はフレームのすべてのウィンドウ、垂直スクロールバー、フリンジ、マージン、垂直ディバイダーが表示できるよう保証する。このパラメーターが非nilなら、収まりきらないコンポーネントが結果としてウィンドウマネージャーにクリップされてしまうようなフレームより小さいフレームを作成できる。

min-height

このパラメーターはフレームの最小ネイティブ高さ(フレームのジオメトリーを参照)を文字単位で指定する。フレームの初期幅やフレームを水平方向にリサイズする関数は、通常はフレームのすべてのウィンドウ、水平スクロールバー、水平ディバイダー、モードライン、ヘッダーライン、エコーエリアー、インターナルメニューバー、インターナルツールバーが表示できるよう保証する。このパラメーターが非nilなら、収まりきらないコンポーネントが結果としてウィンドウマネージャーにクリップされてしまうようなフレームより小さいフレームを作成できる。

fullscreen

このパラメータはフレームの幅、高さ、またはその両方を最大化するかどうかを指定する。値はfullwidthfullheightfullboth、またはmaximizedのいずれか。21フレームがfullwidthなら幅、fullheightなら高さ、fullbothまら幅と高さが可能なかぎり大きくなる。maximizedは“fullboth”と同様だが、通常はタイトルバーとフレームのリサイズやクローズ用のボタンが維持される点が異なる。同様に最大化されたフレームでは、デスクトップ上に表示されているタスクバーやパネルが見えなくなること通常はない。一方で“fullboth(全画面)”のフレームは、通常はタイトルバーは省略されて、利用可能なスクリーンスペース全体を占有する。

この点ではfullheightやfullwidthのフレームは最大化されたフレームと類似している。しかしこれらは通常は最大化フレームでは存在しないエクスターナルボーダーを表示する。したがって最大化されたフレームの高さと幅は、fullheightのフレームの高さやfullwidthのフレームの幅とあ数ピクセル異なることがある。

いくつかのウィンドウマネージャーではフレームを真に最大化やフルスクリーンで表示させるために、変数frame-resize-pixelwise (フレームのサイズを参照)をカスタマイズする必要があるかもしれない。さらにフルスクリーンや最大化の種々の状態間でスムーズな遷移をサポートしないウィンドウマネージャーもいくつかある。これの回避には変数x-frame-normalize-before-maximizeのカスタマイズが助けになるかもしれない。

macOSのフルスクリーンではツールバーとメニューバーの両方が非表示になるが、マウスポインターがスクリーン上端に移動すればどちらも表示される。

fullscreen-restore

このパラメータはtoggle-frame-fullscreenコマンド (Frame Commands in The GNU Emacs Manualを参照)呼び出し後の“fullboth”状態での、望ましい全画面状態を指定する。このパラメーターはFrame Commands in The GNU Emacs Manualを参照の切り替え時に、このコマンドによって自動的にインストールされる。しかしEmacsが“fullboth”の状態で開始された場合には、以下の例のように初期ファイル内で望ましい挙動を指定する必要がある

(setq default-frame-alist
    '((fullscreen . fullboth)
      (fullscreen-restore . fullheight)))

これはF11の初回タイプ後に、フレームに新たにfullheightを与えるだろう。

fit-frame-to-buffer-margins

このパラメーターはfit-frame-to-buffer (ウィンドウのリサイズを参照)でフレームをルートウィンドウのバッファーにフィットさせる際に、オプションfit-frame-to-buffer-marginsの値のオーバーライドを可能にする。

fit-frame-to-buffer-sizes

このパラメーターはfit-frame-to-buffer (ウィンドウのリサイズを参照)でフレームをルートウィンドウのバッファーにフィットさせる際に、オプションfit-frame-to-buffer-sizesの値のオーバーライドを可能にする。


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

30.4.3.4 レイアウトのパラメーター

以下のフレームパラメーターによりフレームのさまざまなパーツを有効または無効にしたりサイズを制御できます。

border-width

ピクセル単位でのフレームのアウターボーダー幅(フレームのジオメトリーを参照)。

internal-border-width

ピクセル単位でのフレームのインターナルボーダー幅(フレームのジオメトリーを参照)。

child-frame-border-width

与えられたフレームが子フレーム(子フレームを参照)なら、フレームのインターナルボーダーのピクセル幅。nilならかわりにinternal-border-widthで指定した値を使用する。

vertical-scroll-bars

フレームが垂直スクロール用のスクロールバー(スクロールバーを参照)をもつべきか否か、およびスクロールバーをフレームのどちら側に置くか。可能な値はleftright、スクロールバーなしはnil

horizontal-scroll-bars

フレームが水平スクロール用のスクロールバーをもつべきかと、スクロールバーをフレームのどちら側に置くか(tbottomはスクロールバーあり、nilはスクロールバーなしを意味する)。

scroll-bar-width

垂直スクロールバーのピクセル単位による幅。nilはデフォルト幅の使用を意味する。

scroll-bar-height

垂直スクロールバーのピクセル単位による高さ。nilはデフォルト高さの使用を意味する。

left-fringe
right-fringe

そのフレーム内のウィンドウの左右フリンジのデフォルト幅(フリンジを参照)。いずれかが0なら対応するフリンジを削除する効果がある。

これら2つのフレームパラメーターの値を問い合わせるためにframe-parameterを使用する際のリターン値は常に整数。nil値を渡してset-frame-parameterを使用する際には、実際のデフォルト値8ピクセルが課せられる。

right-divider-width

フレーム上のすべてのウィンドウの右ディバイダー(ウィンドウディバイダーを参照)用に予約されるピクセル単位の幅(厚さ)。値0は右ディバイダーを描画しないことを意味する。

bottom-divider-width

フレーム上のすべてのウィンドウの下ディバイダー(ウィンドウディバイダーを参照)用に予約されるピクセル単位の幅(厚さ)。値0は下ディバイダーを描画しないことを意味する。

menu-bar-lines

メニューバー用にフレーム上端に割り当てる行数(メニューバーを参照)。デフォルトはMenu Barモードが有効なら1、それ以外なら0。Menu Bars in The GNU Emacs Manualを参照のこと。エクスターナルメニューバー(フレームのレイアウトを参照)では、メニューバーが複数行に折り返されても値は変更されない。この場合にはframe-geometryがリターンするmenu-bar-sizeの値で実際にメニューバーが占有する行数を導出できる(フレームのジオメトリーを参照)。

tool-bar-lines

ツールバー用に使用する行数(ツールバーを参照)。デフォルトはTool Barモードが有効なら1、それ以外は0。Tool Bars in The GNU Emacs Manualを参照のこと。ツールバーが折り返されているかどうかで値は変化するかもしれない(フレームのレイアウトを参照)。

tool-bar-position

EmacsがGTK+とともにビルドされた際のツールバーの位置。値はtopbottomleftrightのいずれか(デフォルトはtop)。

tab-bar-lines

タブバー用に使用する行数(Tab Bars in The GNU Emacs Manualを参照)。デフォルトはTab Barモードが有効なら1、それ以外は0。ツールバーが折り返されているかどうかで値は変化するかもしれない(フレームのレイアウトを参照)。

line-spacing

各テキスト行の下に残すピクセル単位の追加スペース(正の整数)。詳細は行の高さを参照のこと。

no-special-glyphs

nilならそのフレームで表示するすべてのバッファーにたいする切り詰めと継続のグリフ(切り詰めを参照)の表示をすべて抑制する。これはfit-frame-to-buffer (ウィンドウのリサイズを参照)を通じてフレームをバッファーにフィットさせる際のグリフ排除に有用。


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

30.4.3.5 バッファーのパラメーター

以下はフレーム内でどのバッファーが表示されているか、表示されるべきかを扱うためのフレームパラメーターであり、すべての種類の端末上で意味があります。

minibuffer

そのフレームが自身のミニバッファーをもつか否か。もつ場合にはt、もたない場合はnilonlyならそのフレームが正にミニバッファーであることを意味する。値が(別フレーム内の)ミニバッファーウィンドウなら、そのフレームはそのミニバッファーを使用する。

このパラメーターはフレームの作成時に効果をもつ。nilを指定するとEmacsはdefault-minibuffer-frameのミニバッファーウィンドウ(ミニバッファーとフレームを参照)にそのフレームをセットしようと試みる。このパラメーターは既存のフレームでは別のミニバッファーウィンドウを指定するためにのみ使用できる。nilからt、およびその逆の変更も許されていない。このパラメーターがすでにミニバッファーウィンドウを指定していれば、これをnilにセットしても効果はない。

特別な値child-frameは作成されるフレームが親となるようなミニバッファーのみの子フレーム(子フレームを参照)を作成することを意味する。Emacsはnilが指定されたかのように子フレームのイニバッファーウィンドウにこのパラメーターをセットするが、作成後に子フレームを選択しない。

buffer-predicate

このフレームにたいするバッファー述語関数。関数other-bufferはこの述語が非nilなら、(選択されたフレームから)どのバッファーを考慮すべきか決定するためにこれを使用する。これは各バッファーにたいして、そのバッファーを唯一の引数としてこの述語を1回呼び出す。この述語が非nil値をリターンしたら、そのバッファーは考慮される。

buffer-list

そのフレーム内で選択されたことのあるバッファーにたいする、もっとも最近選択されたバッファーが先頭になるような順のリスト。

unsplittable

nilなら、このフレームのウィンドウは決して自動的に分割されることはない。


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

30.4.3.6 フレームとの相互作用のためのパラメーター

以下のパラメーターは別のフレームとの間での相互作用するためのフォームを提供します。

parent-frame

nilならそのフレームが子フレーム(子フレームを参照)であることを意味しており、そのパラメーターは親フレームを指定する。nilならそのフレームが通常のトップレベルのフレームであることを意味する。

delete-before

このパラメーターが非nilなら、それは削除によってこのウレームも自動的にトリガーされるようなフレームを指定する。フレームの削除を参照のこと。

mouse-wheel-frame

このパラメーターが非nilならフレーム上でマウスホイールをスクロールするたびにウィンドウがスクロールされるようなフレームを指定する。Mouse Commands in The GNU Emacs Manualを参照のこと。

no-other-frame

nilならそのフレームは関数next-frameprevious-frame (すべてのフレームを探すを参照)、other-frameの候補として適格ではない。Frame Commands in The GNU Emacs Manualを参照のこと。

auto-hide-function

このパラメーターが関数を指定する場合には、他のフレームが存在しないときにフレーム唯一のウィンドウをquit(ウィンドウのquitを参照)した際に変数frame-auto-hide-functionで指定された関数のかわりに呼び出される関数を指定する。

minibuffer-exit

このパラメーターが非nilなら、Emacsはミニバッファーのexit(ミニバッファーを参照)の際は常にそのフレームを不可視にする。かわりに関数iconify-framedelete-frameも指定できる。このパラメーターはミニバッファーのexit時に(Emacsがウィンドウを処理する際のように)自動的に子フレームを非表示にするために有用。

keep-ratio

このパラメーターは現在のところ子フレーム(子フレームを参照)にたいしてのみ意味がある。非nilなら親フレームのリサイズ時に、Emacsはフレームのサイズ比率(幅と高さ。サイズのパラメーターを参照)と位置比率(左と右。位置のパラメーターを参照のこと)を変更しないよう試みる。

このパラメーターの値がnilなら親フレームのリサイズ時にフレームのサイズと位置は変更されないので、位置とサイズの比率は変更されるかもしれない。パラメーターの値がtなら、Emacsはフレームのサイズと位置の比率を維持しようと試みるので、親フレームから相対的なフレームのサイズと位置は変更されるかもしれない。

コンスセルを使用することにより、さらに特化した制御が可能になる。この場合にはコンスセルのCARtwidth-onlyならフレームの幅比率、CARtheight-onlyなら高さ比率、CDRtleft-onlyなら左位置比率、CDRttop-onlyなら上位置比率が維持される。


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

30.4.3.7 マウスドラッグのパラメーター

以下のパラメーターはマウスでのインターナルボーダーのドラッグによるフレームのリサイズにたいするサポートを提供します。これらは最上ウィンドウのヘッダーラインやタブライン、最下ウィンドウのモードラインのマウスドラッグによるフレームの移動も可能にします。

これらのパラメーターはウィンドウマネージャーによる装飾がない子フレーム(子フレームを参照)にたいしてもっとも有用です。もし必要なら未装飾のトップレベルのフレームにたいしても使用できます。

drag-internal-border

nilなら、(もしあれば)マウスでインターナルボーダーをドラッグしてフレームをリサイズできる。

drag-with-header-line

nilなら、マウスで最上ウィンドウのヘッダーラインをドラッグしてフレームを移動できる。

drag-with-tab-line

nilなら、マウスで最上ウィンドウのタブラインをドラッグしてフレームを移動できる。

drag-with-mode-line

nilなら、マウスで最下ウィンドウのモードラインをドラッグしてフレームを移動できる。このようなフレームは自身のミニバッファーウィンドウをもつことが許されないことに注意。

snap-width

マウスで移動されるフレームはディスプレイ(か親ウィンドウ)のいずれかのエッジにこのパラメーターで指定されたピクセル数までドラッグされるとディスプレイ(か親ウィンドウ)のボーダーに“snapする(とびつく)”。

top-visible

このパラメーターが数値ならフレームの上エッジがディスプレイ(か親フレーム)の上エッジより上に表示されることは決してない。さらにディスプレイ(か親フレーム)の他のエッジにたいしてフレームが移動された際には、フレームの指定されたピクセル数分が可視に留まる。このパラメーターのセットは非nildrag-with-header-lineパラメーターをもつ子フレームが、ドラッグにより完全に親フレームのエリア外になることを防ぐために有用。

bottom-visible

このパラメーターが数値ならフレームの下エッジがディスプレイ(か親フレーム)の下エッジより下に表示されることは決してない。さらにディスプレイ(か親フレーム)の他のエッジにたいしてフレームが移動された際には、フレームの指定されたピクセル数分が可視に留まる。このパラメーターのセットは非nildrag-with-mode-lineパラメーターをもつ子フレームが、ドラッグにより完全に親フレームのエリア外になることを防ぐために有用。


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

30.4.3.8 ウィンドウ管理のパラメーター

以下のフレームパラメーターはウィンドウマネージャーやウィンドウシステムとフレームとの相互作用のさまざまな面を制御します。これらはテキスト端末上では効果がありません。

visibility

フレームの可視性(visibility)の状態。可能な値は3つありnilは不可視、tは可視、iconはアイコン化されていることを意味する。フレームの可視性を参照のこと。

auto-raise

nilなら、Emacsはそのフレーム選択時に自動的にそれを前面に移動(raise)する。これを許さないウィンドウマネージャーがいくつかある。

auto-lower

nilなら、Emacsはそのフレームの選択解除時に自動的にそれを背面に移動(lower)する。これを許さないウィンドウマネージャーがいくつかある。

icon-type

そのフレームに使用するアイコンのタイプ。値が文字列なら使用するビットマップを含むファイル、nilならアイコンなしを指定する(何を表示するかはウィンドウマネージャーが決定する)。その他の非nil値はデフォルトのEmacsアイコンを指定する。

icon-name

このフレームにたいするアイコンで使用する名前。アイコンを表示する場合は、その際に表示される。これがnilならフレームのタイトルが使用される。

window-id

グラフィカルディスプレイがこのフレームにたいして使用するID番号。Emacsはフレーム作成時にこのパラメーターを割り当てる。このパラメーターを変更しても実際のID番号に効果はない。

outer-window-id

そのフレームが存在する最外殻のウィンドウシステムのウィンドウのID番号。window-idと同じように、このパラメーターを変更しても実際の効果はない。

wait-for-wm

nilならジオメトリー変更を確認するために、ウィンドウマネージャーを待機するようXtに指示する。Fvwm2およびKDEのバージョンを含むウィンドウマネージャーのいくつかは確認に失敗してXtがハングする。これらウィンドウマネージャーのハングを防ぐためには、これをnilにセットすること。

sticky

nilなら仮想デスクトップを伴うシステム上のすべての仮想デスクトップ上でそのフレームが可視になる。

shaded

nilならウィンドウマネージャーにたいして、タイトルバーを残しコンテンツが隠れるようにフレームを表示するよう指示する。

use-frame-synchronization

nilならグラフィックのティアリングを防ぐために、フレームの再表示とモニターのリフレッシュレートを同期させる。これは現時点ではHaiku、および非ツールキットとXツールキットとともにビルドされたXウィンドウシステムでのみ実際されており、ツールキットのスクロールバーでは正しく動作しない。更に関連するディスプレイ同期プロトコルをサポートするコンポジット型ウィンドウマネージャーを要求する。XリソースのsynchronizeResizeにも文字列"extended"がセットされていなければならない。

inhibit-double-buffering

nilならフレームはダブルバッファリングなしでスクリーンに描画される。通常はちらつきを減少させるために、利用可能ならEmacsはダブルバッファリングの使用を試みる。ディスプレイのバグや昔のようにちらつく感覚があるようならこのプロパティをセットすること。

skip-taskbar

nilならウィンドウマネージャーならフレームのディスプレイに関連するタスクバーからフレームのアイコンを削除して、Alt-TABのコンビネーションキーを通じたフレームへの切り替えを抑制するようにウィンドウマネージャーに指示する。MS-Windowsではこのようなフレームをアイコン化するとデスクトップ下部にある、フレームにたいするウィンドウシステムのウィンドウに"ロールイン(roll in)"される。いくつかのウィンドウマネージャーはこのパラメーターにしたがわない。

no-focus-on-map

nilならフレームはマップ時に入力フォーカスの受け取りを希望しないことを意味する。いくつかのウィンドウマネージャーはこのパラメーターにしたがわない。

no-accept-focus

nilならフレームは明示的なマウスクリックやfocus-follows-mouse (入力のフォーカスを参照)、mouse-autoselect-window (マウスによるウィンドウの自動選択を参照)によりマウスがフレーム内に移動した際に入力フォーカスの受け取りを希望しないことを意味する。これはユーザーが選択されていないフレームをマウスでスクロールできないという、望ましくない副作用をもたらすかもしれない。いくつかのウィンドウマネージャーはこのパラメーターにしたがわない。HaikuでもたとえユーザーがAlt-TABというキー組み合わせでそのフレームに切り替えた場合であっても、ウィンドウがユーザーからのキーボード入力を何も受け取ることができないという副作用があるだろう。

undecorated

nilならフレームのウィンドウシステムのウィンドウはタイトル、最小化ボックスや最大化ボックス、エクスターナルボーダーのような装飾なしで描画される。これは通常はマウスによるそのウィンドウシステムのウィンドウのドラッグ、リサイズ、アイコン化、最大化、削除ができないことを意味する。nilの場合にはウィンドウマネージャーのセッティングでディスプレイがサスペンドされていなければ、フレームのウィンドウは上述のすべての要素とともに描画される。

Xでは装飾をオフに切り替えるために、EmacsはMotifウィンドウマネージャーのヒントを使用する。いくつかのウィンドウマネージャーはこれらのヒントにしたがわない。

NSビルドはツールバーを装飾とみなすので未装飾のフレームでは表示されない。

override-redirect

nilならオーバーライド・リダイレクト(override redirect)のフレームであることを意味する。これはフレームがX配下のウィンドウマネージャーで処理されないことを意味する。オーバーライド・リダイレクト・フレームはウィンドウマネージャーの装飾をもたず、Emacsの配置関数やリサイズ関数でしか配置やリサイズができない。また他のすべてのフレームの最上位に通常は描画される。このパラメーターをセットしてもMS-Windowsでは効果がない。

ns-appearance

macOSのみ利用可能でありdarkにセットすると“vibrant dark”テーマ、lightにセットすると“aqua”テーマ、それ以外ならシステムのデフォルトを使用してフレームのウィンドウシステムのウィンドウを描画する。暗色(dark)のバックグラウンドのEmacsテーマ使用時にツールバーやスクロールバーに暗色の外観をセットするために“vibrant dark”テーマを使用できる。

ns-transparent-titlebar

macOSでのみ利用可能であり非nilならタイトルバーとツールバーをトランスペアレント(transparent: 透明)にセットする。これはEmacsのバックグラウンドカラーにマッチするようにタイトルバーとツールバーのバックグラウンドカラーを効果的にセットする。


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

30.4.3.9 カーソルのパラメーター

このフレームパラメーターはカーソルの外見を制御します。

cursor-type

カーソルの表示方法。適正な値は:

box

塗りつぶされた四角形(filled box)を表示する(デフォルト)。

(box . size)

塗りつぶされた四角形(filled box)を表示する。しかしポイントがいずれかの次元がsizeピクセルより大きいマスクされたイメージ配下にあれば中抜きの四角形(hollow box)を表示する。

hollow

中抜きの四角形(hollow box)を表示する。

nil

カーソルを表示しない。

bar

文字間に垂直バー(vertical bar)を表示する。

(bar . width)

文字間に幅がwidthピクセルの垂直バー(vertical bar)を表示する。

hbar

文字間に水平バー(horizontal bar)を表示する。

(hbar . height)

文字間に高さがheightピクセルの水平バー(horizontal bar)を表示する。

フレームパラメーターcursor-typeは変数cursor-typecursor-in-non-selected-windowsによりオーバーライドされるかもしれません。

User Option: cursor-type

このバッファーローカル変数は選択されたウィンドウ内で表示されているそのバッファーのカーソルの外見を制御する。この値がtなら、それはフレームパラメーターcursor-typeで指定されたカーソルのーを使用することを意味する。それ以外では値は上記リストのカーソルタイプのいずれかであるべきであり、これはフレームパラメーターcursor-typeをオーバーライドする。

User Option: cursor-in-non-selected-windows

このバッファーローカル変数は選択されていないウィンドウ内でのカーソルの外見を制御する。これはフレームパラメーターcursor-typeと同じ値をサポートする。さらにnilは選択されていないウィンドウ内にはカーソルを表示せず、tは通常のカーソルタイプの標準的な変更(塗りつぶされた四角形は中抜きの四角形、バーはより細いバーになる)の使用を意味する。

User Option: x-stretch-cursor

この変数はタブや伸長された空白文字のようなエクストラワイドグリフで表示されるblockカーソルの幅を制御する。デフォルトではそのフォントのデルト文字だけの幅で、これはカーソル一のグリフがエクストラワイドなら幅を完全にカバーしないだろう。この変数にたいする非nil値はカーソル位置のグリフの幅に応じてblockカーソルを描画することを意味する。デフォルト値はnil

テキストモードのフレームではEmacsの制御外部の端末によりカーソルが描画されるので、この変数に効果はない。

この変数はカーソルのブリンク(blink: 点滅)方法を指定する。各要素は(on-state . off-state)という形式をもつ。カーソルタイプがon-stateと等しい(equalを用いて比較)ときは、これに対応するoff-stateがブリンクが“off”の際のカーソルの外見を指定する。on-stateoff-stateはどちらもフレームパラメーターcursor-typeに適した値であること。

それぞれのカーソルタイプのブリンク方法にたいして、そのタイプがここでon-stateとして指定されていなければ、さまざまなデフォルトが存在する。フレームパラメーターcursor-typeで指定した際に限り、この変数内での変更は即座に効果を発揮しない。


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

30.4.3.10 フォントとカラーのパラメーター

以下のフレームパラメーターはフォントとカラーの使用を制御します。

font-backend

フレーム上で文字の描画に使用するフォントバックエンド(font backends)を優先順に指定するシンボルのリスト。CairoなしでビルドされたEmacsのXでの描画では現在のところx (Xのコアフォントドライバー)、xft (Xftフォントドライバー)、xfthb (HarfBuzzテキストシェイピングをもつXftフォントドライバー)という3つのフォントバックエンドが潜在的に利用できる。Cairo描画つきでビルドされた場合にもX上のフォントバックエンドとしてxftcr (CairoのFreeTypeフォントドライバー)、ftcrhb (HarfBuzzテキストシェイピングをもつCairo上のFreeTypeフォントドライバー)の3つが潜在的に利用できる。HarfBuzzつきでEmacsをビルドした場合には、非推奨のftcrドライバーの使用が可能であっても、デフォルトのフォントドライバーはftcrhbとなる。MS-Windowsでは現在のところgdi (MS-Windowsのコアフォントドライバー)、uniscribe (OTFフォントとTTFフォントにたいするUniscribeエンジンによるテキストシェイピングをもつフォントドライバー)、harfbuzz (OTFフォントとTTFフォントにたいするHarfBuzzテキストシェイピングをもつフォントドライバー)という3つのフォントバックエンドが利用できる(Windows Fonts in The GNU Emacs Manualを参照)。同様にharfbuzzも推奨される。Haikuでは複数のフォントドライバーが存在する可能性がある(Haiku Fonts in The GNU Emacs Manualを参照)。

それ以外のシステムでは利用可能なフォントバックエンドは1つだけなので、このフレームパラメーターの変更は意味をもたない。

background-mode

このパラメーターはdarklightのいずれかで、それぞれバックグラウンドを暗く(dark)するか、明るく(light)するかに対応する。

tty-color-mode

このパラメーターは端末上で使用するカラーモードを指定して、そのシステムの端末機能データベース(terminal capabilities database、termcap)により与えられた端末のカラーサポートをオーバーライドする。値にはシンボルか数値を指定できる。数値なら使用するカラー数(および間接的にはそれぞれのカラーを生成するためのコマンド)を指定する。たとえば(tty-color-mode . 8)は標準的なテキストカラーにたいしてANSIエスケープシーケンスの使用を指定する。値-1はカラーサポートをオフに切り替える。

このパラメーターの値がシンボルなら、それはtty-color-mode-alistの値を通じて数値を指定するもので、そのシンボルに割り当てられた数値がかわりに使用される。

screen-gamma

これが数値ならEmacsはすべてのカラーの輝度を調整するガンマ補正(gamma correction)を行う。値はディスプレイのスクリーンのガンマであること。

通常のPCモニターはスクリーンガンマが2.2なので、EmacsとXウィンドウのカラー値は一般的にそのガンマ値のモニター上で正しく表示するよう校正されている。screen-gammaにたいして2.2を指定すると、それは補正が不必要であることを意味する。その他の値は通常のモニター上のガンマ値2.2で表示されるように、補正したカラーがスクリーン上に表示されることを意図された補正を要求する。

モニターが表示するカラーが明るすぎる場合には、screen-gammaに2.2より小さい値を指定すること。これはカラーをより暗くする補正を要求する。スクリーンガンマの値1.5は、LCDカラーディスプレイにたいして良好な結果を与えるだろう。

alpha

このパラメーターは可変透明度(variable opacity)をサポートするグラフィカルディスプレイ上でそのフレームの透明度を指定する。これは0から100の整数であるべきで0は完全な透明、100は完全な不透明を意味する。nil値をもつこともでき、これはEmacsにフレームのopacityをセットしないよう告げる(ウィンドウマネージャーに委ねる)。

フレームが完全に見えなくなるのを防ぐために、変数frame-alpha-lower-limitは透明度の最低限度を定義する。フレームパラメーターの値がこの変数の値より小さければEmacsは後者を使用する。デフォルトのframe-alpha-lower-limitは20。

フレームパラメーターalphaにはコンスセル(active . inactive)も指定できる。ここでactiveは選択時のフレームの透明度、inactiveは未選択時の透明度。

いくつかのウィンドウシステムは子フレーム(子フレームを参照)にたいしてalphaパラメーターをサポートしない。

alpha-background

フレームのバックグラウンドの透明度をセットする。フレームパラメーターalphaとは異なり、テキストは完全に不透明のままといったようにフォアグラウンド要素は保ちつつ、バックグラウンドの透明度だけを制御する。値は0から100の整数であり0は完全に透明、100(デフォルト)は完全に不透明を意味する。

以下は特定のフェイスの特定のフェイス属性と自動的に等しくなるので、ほぼ時代遅れとなったフレームパラメーターです(Standard Faces in The Emacs Manualを参照)。

font

フレーム内でテキストを表示するためのフォントの名前。これはシステムで有効なフォント名か、Emacsフォントセット名(フォントセットを参照)のいずれかであるような文字列。これはdefaultフェイスのfont属性と等価。

foreground-color

文字に使用するカラー。これはdefaultフェイスの:foreground属性と等価。

background-color

文字のバックグラウンドに使用するカラー。これはdefaultフェイスの:background属性と等価。

mouse-color

マウスポインターのカラー。これはmouseフェイスの:background属性と等価。

cursor-color

ポイントを表示するカーソルのカラー。これはcursorフェイスの:background属性と等価。

border-color

これはフレームのボーダーのカラー。これはborderフェイスの:background属性と等価。

scroll-bar-foreground

nilならスクロールバーのフォアグラウンドカラー。これはscroll-barフェイスの:foreground属性と等価。

scroll-bar-background

nilならスクロールバーのバックグラウンドカラー。これはscroll-barフェイスの:background属性と等価。


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

30.4.4 ジオメトリー

以下はXスタイルのウィンドウジオメトリー指定によるアクションのデータを調べる方法です:

Function: x-parse-geometry geom

関数x-parse-geometryは標準的なXウィンドウのジオメトリー文字列をmake-frameの引数の一部として使用できるalistに変換する。

このalistはgeom内で指定されたパラメーターと、そのパラメーターに指定された値を記述する。各要素は(parameter . value)のような形式。可能なparameterの値はlefttopwidthheight

サイズのパラメーターの値は整数でなければならない。位置のパラメーターlefttopの名前に関しては、かわりに右端または下端の位置を示す値もいくつかあるので完全に正確ではない。位置パラメーターにたいして可能なvalueは前述したような整数(位置のパラメーターを参照)、リスト(+ pos)、リスト(- pos)である。

以下は例:

(x-parse-geometry "35x70+0-0")
     ⇒ ((height . 70) (width . 35)
         (top - 0) (left . 0))

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

30.5 端末のパラメーター

端末はそれぞれ関連するパラメーターのリストをもっています。これら端末パラメーター(terminal parameters)は主に端末ローカル変数を格納するための便利な手段ですが、いくつかの端末パラメーターは特別な意味をもっています。

このセクションでは端末のパラメーター値の読み取りや変更を行う関数を説明します。これらはすべて引数として端末かフレームいずれかを受け入れます。フレームならそれはそのフレームの端末の使用を意味します。引数nilは選択されたフレームの端末という意味です。

Function: terminal-parameters &optional terminal

この関数はterminalnのすべてのパラメーターとその値をリストするalistをリターンする。

Function: terminal-parameter terminal parameter

この関数はterminalのパラメーターparameter (シンボル)の値をリターンする。terminalparameterにたいするセッティングをもたなければ、この関数はnilをリターンする。

Function: set-terminal-parameter terminal parameter value

この関数はterminalのパラメーターparameterに指定されたvalueをセットしてパラメーターの以前の値をリターンする。

以下は特別な意味をもついくつかの端末パラメーターのリストです:

background-mode

端末のバックグラウンドカラーの区分でlightdarkのいずれか。

normal-erase-is-backspace

値は1か0で、これはその端末上でnormal-erase-is-backspace-modeがオンまたはオフのいずれに切り替えられたかに依存する。DEL Does Not Delete in The Emacs Manualを参照のこと。

terminal-initted

端末の初期化後に端末固有の初期化関数にセットされる。

tty-mode-set-strings

与えられた際には、読み取り用にttyを設定時にEmacsが出力するエスケープシーケンスを含む文字列のリスト。Emacsは端末の設定時のみこれらの文字列を発行する。すでにアクティブな端末上(たとえばtty-setup-hook内)でモードを有効にしたければ、tty-mode-set-stringsへのシーケンスの追加に加えて、send-string-to-terminalを使用して明示的に必要なエスケープシーケンスを出力すること。

tty-mode-reset-strings

与えられた際には、tty-mode-set-strings内の文字列の効果をアンドゥする文字列のリスト。Emacsはexit、端末の削除、Emacs自身のサスペンドの際にそれらの文字列を発行する。


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

30.6 フレームのタイトル

フレームにはそれぞれnameというパラメーターがあります。これはウィンドウシステムが通常フレーム上端に表示するフレームタイトルにたいするデフォルトとしての役割をもちます。フレームプロパティnameをセットすることにより明示的に名前を指定できます。

通常は名前を明示的に指定せずに、Emacsが変数frame-title-formatに格納されたテンプレートにもとづいて自動的にフレーム名を計算します。Emacsはフレームが再表示されるたびに名前を再計算します。

Variable: frame-title-format

この変数はフレーム名の明示的な指定(フレームのパラメーターを通じて; 基本パラメーターを参照)がされていない場合にフレーム名を計算する方法を指定する。この変数の値は実際にはmode-line-formatのようなモードライン構文(mode line construct)だが‘%c’、‘%C’、‘%l’の構文は無視される。モードラインのデータ構造を参照のこと。

Variable: icon-title-format

これはフレームのパラメーターを通じてフレームの名前を明示的に指定していない際に、アイコン化されたフレームの名前を計算する方法を指定する変数である。計算の結果得られたタイトルが、そのフレームのアイコン自体に表示される。値が文字列であれば、frame-title-formatのようなモードライン構文であること。値はtでもよく、この場合にはかわりにframe-title-formatを使用することを意味する。これによって(フレームがアイコン化されているときに)フレームのタイトルを変更すると、そのフレームのraiseおよび/または入力フォーカスの要求と解釈する、一部のウィンドウマネージャーやデスクトップ環境における問題を避けることができる。この値はフレームがアイコン化されているかどうかに関わらず、フレームのタイトルを同じにしたい場合にも役に立つ。デフォルト値はframe-title-formatのデフォルト値と同じ文字列。

Variable: multiple-frames

この変数はEmacsにより自動的にセットされる。フレームが2つ以上(ミニバッファーのみのフレームと不可視のフレームは勘定に入らない)のとき、値はtとなる。frame-title-formatのデフォルト値はフレームが複数存在する場合のみ、フレーム名にバッファー名を入れるためにmultiple-framesを使用する。

この変数の値はframe-title-formaticon-title-formatの処理中を除き正確である保証はない。


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

30.7 フレームの削除

生きたフレーム(live frame)とは削除されていないフレームのことです。フレームが削除される際には、たとえそれへの参照元がなくなるまでLispオブジェクトとして存在し続けるとしても端末ディスプレイからは削除されます。

Command: delete-frame &optional frame force

この関数はフレームframeを削除する。引数frameは生きたフレーム(以下参照)を指定しなければならず、デフォルトは選択されたフレーム。

この関数はまずframeのすべての子フレーム(子フレームを参照)とフレームパラメーターdelete-before (フレームとの相互作用のためのパラメーターを参照)がframeを指定するすべてのフレームを削除する。祖先としてframeをもつフレームが他に存在しないことを保証するために、このような削除はすべて再帰的に行われる。その後にframeがツールチップを指定していなければ、実際にフレームをkillする前にフックdelete-frame-functionsを実行する(フックの各関数は単一の引数としてframeを受け取る)。delete-frameは実際にフレームをkillしてフレームリストからフレームを削除した後にafter-delete-frame-functionsを実行する。

フレームのミニバッファーが別のフレームの代替えミニバッファー(ミニバッファーとフレームを参照)の役割をもつかぎりフレームを削除できないことに注意。他のフレームすべてが不可視なら通常はフレームは削除できないが、forceが非nilなら削除が可能になる。

Function: frame-live-p frame

この関数はフレームframeが削除されていなければ非nilをリターンする。リターンされ得る非nilの値はframepと同様。フレームを参照のこと。

いくつかのウィンドウマネージャーはウィンドウを削除するコマンドを提供します。これらはそのウィンドウを操作するプログラムに特別なメッセージを送ることにより機能します。Emacsがそれらメッセージのいずれかを受け取ったときはdelete-frameイベントを生成します。このイベントの通常の定義は関数delete-frameを呼び出すコマンドです。その他のシステムイベントを参照してください。

Command: delete-other-frames &optional frame iconify

このコマンドはframeの端末上からframe以外のすべてのフレームを削除する。frameが別のフレームのミニバッファーを使用している場合には、そのミニバッファーフレームは処理せずに残る。引数frameは生きたフレームを指定しなければならず、デフォルトは選択されたフレーム。このコマンドは内部的には削除するすべてのフレームにたいして、forcenilを指定してdelete-frameを呼び出すことにより機能する。

この関数はframeの子フレームは削除しない(子フレームを削除)。frameが子フレームならframeの兄弟だけを削除する。

プレフィックス引数iconifyを指定するとフレームを削除せずにアイコン化する。


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

30.8 すべてのフレームを探す

Function: frame-list

この関数はすべての生きたフレーム(削除されていないフレーム)のリストをリターンする。これはバッファーにたいするbuffer-listに類似しており、すべての端末上のフレームが含まれる。リターンされるリストは新たに作成されたものであり、このリストを変更してもEmacs内部への影響はない。

Function: visible-frame-list

この関数はカレントで可視なフレームだけのリストをリターンする。See フレームの可視性を参照のこと。テキスト端末上のフレームは、実際に表示されるのが選択されたフレームだけだとしても常に可視であるとみなされる。

Function: frame-list-z-order &optional display

この関数はZオーダー(重なり)の順でEmacsのフレームのリストをリターンする(フレームのraise、lower、re-stackを参照)。オプション引数displayは調査するディスプレイを指定する。displayはフレームかディスプレイ名(文字列)であること。省略かnilなら選択されたフレームのディスプレイを意味する。displayにEmacsフレームが含まれていなければnilをリターンする。

フレームは最前面(最初)から最背面(最後)の順にリストされる。特別なケースとしてdisplayが非nilで生きたフレームを指定する場合には、そのフレームの子フレームをZオーダー(重なり順)でリターンする。

この関数はテキスト端末では意味がない。

Function: next-frame &optional frame minibuf

この関数により特定の端末上のすべてのフレームを任意の開始位置から簡単に巡回できる。これはframeの端末上のすべての生きたフレームのリストからframeの後のフレームをリターンする。引数frameは生きたフレームを指定しなければならず、デフォルトは選択されたフレーム。no-other-frameパラメーター(フレームとの相互作用のためのパラメーターを参照)が非nilであるようなフレームをリターンすることは決してない。

2つ目の引数minibufは、次フレームを決定する際にどのフレームを考慮するかを示す:

nil

ミニバッファーのみのフレームを除いたすべてのフレームを考慮する。

visible

可視フレームだけを考慮する。

0

可視フレームとアイコン化されたフレームだけを考慮する。

ウィンドウ

特定のウィンドウをミニバッファーウィンドウとして使用するフレームだけを考慮する。

その他

すべてのフレームを考慮する。

Function: previous-frame &optional frame minibuf

next-frameと同様だがすべてのフレームを逆方向に巡回する。

ウィンドウのサイクル順next-windowprevious-windowも参照してください。


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

30.9 ミニバッファーとフレーム

それぞれのフレームは通常は下端に自身のミニバッファーウィンドウをもち、フレームが選択された際は常にそれを使用します。このウィンドウは関数minibuffer-windowで取得できます(ミニバッファーのウィンドウを参照)。

しかしミニバッファーをもたないフレームも作成できます。そのようなフレームは、別のフレームのミニバッファーを使用しなければなりません。この別フレームはそのフレームにたいする代替えミニバッファーフレーム(surrogate minibuffer frame)としての役目を果たし、そのフレームが生きているかぎりdelete-frameで削除することはできなくなります(フレームの削除を参照)。

フレームパラメーターminibufferにより、フレーム作成時に(別フレーム上にある)使用するミニバッファーを明示的に指定できます(バッファーのパラメーターを参照)。これを行わない場合には変数default-minibuffer-frameの値であるようなフレーム内でミニバッファーを探します。この値はミニバッファーをもつフレームである必要があります。

ミニバッファーのみのフレームを使用する場合には、ミニバッファーにエンター時にそのフレームを前面に移動(raise)したいと思うかもしれません。その場合には変数minibuffer-auto-raisetをセットします。フレームのraise、lower、re-stackを参照してください。

Variable: default-minibuffer-frame

この変数はデフォルトでミニバッファーウィンドウとして使用するフレームを指定する。これは既存のフレームには影響しない。これはカレント端末にたいして常にローカルであり、バッファーローカルにはできない。複数の端末を参照のこと。


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

30.10 入力のフォーカス

どんなときでもEmacs内のただ1つのフレームが選択されたフレーム(selected frame)です。選択されたウィンドウ(ウィンドウの選択を参照)は常に選択されたフレーム上にあります。

Emacsがフレームを複数端末(複数の端末を参照)上に表示する際には、各端末は自身の選択されたフレームをもちます。しかしそれらのうち1つだけが、いわゆる選択されたフレームであり、それはもっとも最近に入力があった端末に属すフレームです。つまり特定の端末からのコマンドをEmacsが実行する際には、その端末上の1つが選択されたフレームです。Emacsが実行するコマンドは常に1つだけなので、選択されたフレームは常に1つだけだと考える必要があります。このフレームこそが、このマニュアルで選択されたフレームと呼ぶフレームです。選択されたフレームを表示するディスプレイは、選択されたフレームのディスプレイ(selected frame’s display)です。

Function: selected-frame

この関数は選択されたフレームをリターンする。

いくつかのウィンドウシステムおよびウィンドウマネージャーは、マウスがあるウィンドウオブジェクトにキーボード入力をダイレクトします。それ以外は、さまざまなウィンドウオブジェクトにフォーカスをシフト(shift the focus)するために、明示的なクリックやコマンドを要求します。どちらの方法でもEmacsはフォーカスをもつフレーム(複数形のframes)を自動的に追跡します。Lisp関数から別フレームに明示的に切り替えるためには、select-frame-set-input-focusを呼び出します。

前のパラグラフ中の“複数形のframes”は意図したものです。Emacs自身は選択されたフレームを1つしかもたないのにたいして、Emacsは多くの異なる端末上にフレームをもつことができ(ウィンドウシステムへの接続は端末とみなされることを思い出してほしい)、各端末は入力フォーカスをもつフレームにたいして独自のアイデアをもっています。Xウィンドウシステムの下ではユーザー入力は個別に入力の“指定席”に組織化されていて、それらの指定席それぞれが独自に特定の入力フォーカスを順に得ることができるのです。あるフレームに入力フォーカスをセットすると、Emacsが最後に相互作用を行った指定席のフレームの端末にフォーカスがセットされますが、他の端末上のフレームや指定席に依然としてフォーカスが残るかもしれません。

入力フォーカスをセットする前に指定された端末上でユーザーと何らかの相互作用が発生した場合には、Xサーバーが指定席をランダムに選んで(通常はもっとも小さい番号の指定席)、そこに入力フォーカスをセットします。

関数select-frameを呼び出すことにより、Lispプログラムが一時的にフレームを切り替えることができます。これはそのウィンドウシステムのフォーカス概念を変更はしません。変更ではなく何らかの方法により制御が再確認(reasserted)されるまで、ウィンドウマネージャーの制御から抜け出す(escape)のです。

テキスト端末使用時はその端末上で一度に表示できるフレームは1つだけなので、select-frame呼び出し後に次回の再表示で新たに選択されたフレームが実際に表示されます。このフレームは次のselect-frame呼び出しまで選択されたままです。テキスト端末上の各フレームはバッファー名の前に表示される番号をもちます(モードラインで使用される変数を参照)。

Function: select-frame-set-input-focus frame &optional norecord

この関数はframeを選択して、(他のフレームのせいで不明瞭な場合には)それを前面に移動(raise)してウィンドウシステムのフォーカス授与を試みる。テキスト端末上では、次回再表示時に端末スクリーン全体に新たにフレームが表示される。オプション引数norecordselect-frame(下記参照)のときと同じ意味をもつ。この関数のリターン値に意味はない。

以下で説明する関数は理想的には他のフレームを前面にレイズすることなくフレームにフォーカスするべきです。残念ながらウィンドウシステムやウィンドウマネージャーの多くはこの要求を拒絶するかもしれません。

Function: x-focus-frame frame &optional noactivate

この関数はframeのレイズを要さずにframeにXサーバーのフォーカスを与える。framenilなら選択されたフレームを意味する。Xの配下ではオプション引数noactivateが非nilなら、frameのウィンドウシステムのウィンドウが“アクティブ”なウィンドウになることを防ぐことを意味する。これはframeが他のフレームの前面にならないようさらに強く主張する。

MS-Windowsではnoactivate引数に効果はない。しかしframeが子フレーム(子フレームを参照)なら、この関数は通常は他の子レームの前面にレイズすることなくframeにフォーカスする。

この関数はウィンドウシステムのサポートがなければ何もしない。

Command: select-frame frame &optional norecord

この関数はフレームframeを選択して、Xサーバーのフォーカスがあればそれを一時的に無視する。frameにたいする選択は次回ユーザーが別フレームに何かを行うか、この関数の次回呼び出しまで継続する(ウィンドウシステムを使用する場合には以前に選択されていたフレームに依然としてウィンドウシステムの入力フォーカスがあるかもしれないので、コマンドループからリターン後にそのフレームが選択されたフレームとしてリストアされるかもしれない)。

指定されたframeは選択されたフレームとなり、その端末が選択された端末になる。この関数はその後にframe内で選択されていたウィンドウを第1引数、norecordを第2引数にしてselect-windowをサブルーチンとして呼び出す(したがってnorecordが非nilなら、もっとも最近に選択されたウィンドウとバッファーリストの変更を避ける)。ウィンドウの選択を参照のこと。

この関数はframeframeが削除されていればnilをリターンする。

一般的には実行後に端末を戻すよう切り替えることなく、別の端末に切り替えるのが可能な手段としてselect-frameを決して使用しないこと。

Emacsは選択されたフレームをサーバーとしてアレンジしてウィンドウシステムに要求することによりウィンドウシステムと協調します。Emacsのいずれかのフレームが選択されたことをあるウィンドウシステムが通知すると、Emacsは内部的にfocus-inイベントを生成します。Emacsフレームをフォーカス変更イベントの通知をサポートするxtermのようなテキスト端末エミュレーター上で表示している際には、テキストモードのフレームでもfocus-inとfocus-outのイベントを利用できます。フォーカスイベントは通常はhandle-focus-inで処理されます。

Command: handle-focus-in event

この関数は明示的なフォーカス通知をサポートするウィンドウシステムと端末からのfocus-inイベントを処理する。これはframe-focus-stateが問い合わせてafter-focus-change-functionを呼び出すフレームごとのフォーカスフラグを更新する。加えてEmacsが認識する選択されたフレームを、いくつかの端末でもっとも最近フォーカスされたフレームに切り替えるためにswitch-frameイベントを生成する。Emacsの選択されたフレームをもっとも最近フォーカスされたフレームに切り替えることは、それぞれの端末にある他のフレームがフォーカスをもち続けることを意味しないことに注意することが大事。自分でこの関数を呼び出してはならない。かわりにロジックをafter-focus-change-functionにつけ加えること。

Command: handle-switch-frame frame

この関数はフォーカス通知や最後のイベントとは異なるフレームから到着した入力イベントを含むさまざまな状況においてEmacsが自身のために生成するswitch-frameイベントを処理する。自分でこの関数を呼び出してはならない。

Function: redirect-frame-focus frame &optional focus-frame

この関数はframeからfocus-frameにフォーカスをリダイレクトする。これはframeにかわってfocus-frameが以降のキーストロークとイベントを受け取るであろうことを意味する。そのようなイベント後にはlast-event-frameの値はfocus-frameになるだろう。またframeを指定したswitch-frameイベントも、かわりにfocus-frameを選択するだろう。

focus-frameが省略またはnilなら、frameにたいするすべての既存のリダイレクションがキャンセルされるので、frameが自身のイベントを再度受け取ることになる。

フォーカスリダイレクトの用途の1つは、ミニバッファーをもたないフレームにたいしてである。これらのフレームは別フレーム上のミニバッファーを使用する。別フレーム上のミニバッファーをアクティブにすることは、そのフレームにフォーカスをリダイレクトすることである。これはたとえマウスがミニバッファーをアクティブにしたフレーム内に留まっていても、ミニバッファーが属すフレームにフォーカスを置く。

フレーム選択はフォーカスリダイレクションの変更も可能にする。fooが選択されているときにフレームbarを選択することにより、fooを指すすべてのリダイレクションはかわりにbarを指す。これはユーザーがselect-windowを使用してあるフレームから別のフレームに切り替えた際に、フォーカスのリダイレクトが正しく機能することを可能にする。

これはフォーカスが自身にリダイレクトされたフレームが、フォーカスがリダイレクトされていないフレームとは異なる扱いを受けることを意味する。前者にたいしてselect-frameは影響するが、後者には影響がない。

このリダイレクションは、それを変更するためにredirect-frame-focusが呼び出されるまで継続する。

Function: frame-focus-state frame

この関数はframeの既知の最後のフォーカス状態を取得する。

フレームにフォーカスがないと解っていればnil、フォーカスがあると解っていればt、フレームのフォーカス状態をEmacsが知らなければunknownをリターンする(この最後の状態は明示的なフォーカス通知をサポートしない端末で実行中のTTYフレームで見ることがあるかもしれない)。

Variable: after-focus-change-function

これはEmacsがフレームへのフォーカスを取得あるいは喪失する可能性に気づいた際に引数なしで呼び出される関数である。フォーカスイベントの配信は非同期であり、期待する順に配信されないかもしれないので、フレームのフォーカス状態に応じて何かを行いたいコードはすべてのフレームをチェックする必要がある。

たとえばフレームへのフォーカス有無にもとづきバックグラウンドカラーをセットするシンプルな関数例を以下に示す:

(add-function :after after-focus-change-function
              #'my-change-background)
(defun my-change-background ()
  (dolist (frame (frame-list))
    (pcase (frame-focus-state frame)
      (`t (set-face-background 'default "black" frame))
      (`nil (set-face-background 'default "#404040" frame)))))

フォーカスイベント配信の差異や別の要因のせいで、複数フレームが入力イベントをもつように見える場合があるので、このような状況に直面しても大丈夫なように堅牢なコードを記述するべきである。

ウィンドウシステムによってはフォーカスイベントが繰り返し配信されて、期待した値にセットする前に異なるフォーカス状態が配信されるかもしれない。フォーカス通知にもとづくコードはおそらく再表示まで処理を遅延することにより、フォーカス変更から生じるユーザーに可視の更新を“デバウンス(debounce)”する必要がある。

この関数はread-eventの内部を含む任意のコンテキストで呼び出されるかもしれないので、プロセスフィルター記述時と同様の注意を払うこと。

User Option: focus-follows-mouse

このオプションはフレーム内にマウスポインターを移動した際にウィンドウマネージャーがフォーカスを転送するかどうかと、その方法についてEmacsに知らせる。意味がある値は以下の3つ:

nil

デフォルト値nilはウィンドウマネージャーが“click-to-focus(フレームがフォーカスを取得するためにフレーム内部でマウスをクリックする必要がある)”のポリシーにしたがう際に使用すること。

t

tはマウスポインターの位置にしたがってウィンドウマネージャーが自動的にフォーカスするが、フォーカスを得たフレームは自動的にレイズされず別のウィンドウシステムのウィンドウに隠されたままかもしれないときに使用すること。

auto-raise

auto-raiseはマウスポインターの位置にしたがってウィンドウマネージャーが自動的にフォーカスして、フォーカスを得たフレームは自動的にレイズされる際に使用すること。

このオプションが非nilなら、Emacsはselect-frame-set-input-focusが選択したフレームにマウスポインターを移動する。この関数はother-framepop-to-bufferなどいくつかのコマンドで使用される。

ウィンドウマネージャーは“通常”のフレームのレイズには通常は配慮するので、値tauto-raiseを区別する必要はない。これはmouse-autoselect-window (マウスによるウィンドウの自動選択を参照)を通じて子フレームをレイズするために有用。

このオオプションは“sloppy”なフォーカス(ウィンドウシステムの別ウィンドウにマウスポインターが移動しないかぎり以前にフォーカスのあったフレームがフォーカスを保持する)と“strict”なフォーカス(マウスポインターが去るとフレームは即座にフォーカスを失う)を区別しないことに注意。ウィンドウマネージャーがフォーカスや自動レイズの遅延をサポートしていなくても、新たなフレームがフォーカスを取得(あるいは自動レイズ)するまでの時間を明示的に指定できる。

変数mouse-autoselect-window (マウスによるウィンドウの自動選択を参照)をカスタマイズすることにより、個別のEmacsウィンドウにたいして“focus follows mouse”ポリシーを提供できる。


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

30.11 フレームの可視性

グラフィカルなディスプレイ上のフレームは可視(visible)不可視(invisible)、またはアイコン化(iconified)されているかもしれません。可視ならそのコンテンツは通常の方法により表示されます。アイコン化されている場合にはそのコンテンツは表示されませんが、ビュー内にフレームを戻すための小さいアイコンがどこかにあります(いくつかのウィンドウマネージャーはこの状態をアイコン化ではなく最小化と呼ぶがEmacsの見地ではこれらは同等である)。フレームが不可視ならまったく表示されません。

可視性の概念はマップ(または非マップ)されたフレームと強い関連性があります。フレーム(より正確にはウィンドウシステムのウィンドウ)は最初に表示されるときにマップ済み(mapped)となり、状態がiconifiedinvisibleからvisibleに変化します。それとは逆に状態がvisibleからiconifiedinvisibleに変化したときは、フレームは常に非マップ済み(unmapped)になります。

テキスト端末では実際に表示されるのは常に選択されたフレームだけなので可視性に意味はありません。

Function: frame-visible-p frame

この関数はフレームframeの可視性の状態をリターンする。値はframeが可視ならt、不可視ならnil、アイコン化されていればicon

テキスト端末上ではたとえ1つのフレームだけが表示されているとしても、この関数の目的にたいしてはすべてのフレームが可視とみなされる。フレームのraise、lower、re-stackを参照のこと。

Command: iconify-frame &optional frame

この関数はフレームframeをアイコン化する。frameを省略すると選択されたフレームをアイコン化する。これにより通常はframeのすべての子フレーム(と子孫)は不可視になる(子フレームを参照)。

Command: make-frame-visible &optional frame

この関数はフレームframeを可視にする。frameを省略すると選択されたフレームを可視にする。これはフレームを前面に移動しないが、望むならraise-frameでこれを行うことができる(フレームのraise、lower、re-stackを参照)。

通常はフレームを可視とすることにより、すべての子フレーム(と子孫)も同様に可視になる(子フレームを参照)。

Command: make-frame-invisible &optional frame force

この関数はフレームframeを不可視にする。frameを省略すると選択されたフレームを不可視にする。これにより通常はframeのすべての子フレーム(と子孫)も不可視になる(子フレームを参照)。

この関数はforcenilの場合には、他のすべてのフレームが不可視ならframeを不可視にすることを拒絶する。

フレームの可視性の状態はフレームパラメーターとしても利用可能である。つまりフレームパラメーターとして読み取りと変更ができる。ウィンドウ管理のパラメーターを参照のこと。ウィンドウマネージャーによりユーザーがフレームのアイコン化や非アイコン化を行うこともできる。これはEmacsが何らかの制御を及ぼすのが可能なレベルより下のレベルにおいて発生するが、Emacsはそのような変化を追跡するために使用するイベントを提供する。その他のシステムイベントを参照のこと。

Function: x-double-buffered-p &optional frame

この関数はframeがカレントでダブルバッファリングで描画されていれば非nilをリターンする。frameのデフォルトは選択されたフレーム。


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

30.12 フレームのraise、lower、re-stack

ほとんどのウィンドウシステムではデスクトップというメタファー(metaphor: 比喩的概念)が使用されています。このメタファーの一部はシステムレベルのウィンドウ(Emacsではフレーム)がスクリーン表面に向かって、概念的3次元の垂直方向にスタッキングされる(重ねて表示される)というアイデアにもとづいています。スタッキングによる順序は合計であり、通常はスタッキングの順序(またはZオーダー)として参照されます。2つのゥィンドウがオーバーラップする領域では、このオーダーにおいて高位のウィンドウが、下位のウィンドウ(の一部)をカバーします。

関数raise-framelower-frameを使用してフレームのZオーダーの一番上にraiseしたり一番下にlowerすることができます。関数frame-restackを使用すれば別のフレームの上や下にフレームを直接restackできます。

以下で説明するすべての関数はフレーム(および他のウィンドウシステムのウィンドウすべて)の対応するZグループを尊重することに注意してください(位置のパラメーターを参照)。たとえば通常はフレームをデスクトップウィンドウよりlower(下位)にすることや、z-groupパラメータ0が非nilのフレームをウィンドウシステムのタスクバーやツールチップウィンドウよりraise(上位)にすることはできません。

Command: raise-frame &optional frame

この関数はをframeのz-groupと同じかlower(下位)にある他のすべのフレームの上位にフレームframe (デフォルトは選択されたフレーム)をraiseする。frameが不可視やアイコン化されていたら可視になる。frameが子フレーム(子フレームを参照)なら、親フレームの他のすべての子フレームの上位にframeをraiseする。

Command: lower-frame &optional frame

この関数はをframeのz-groupと同じか上位にある他のすべのフレームの下位へフレームframe (デフォルトは選択されたフレーム)をlowerにする。frameが子フレーム(子フレームを参照)なら、親フレームの他のすべての子フレームの下位にframeをlowerする。

Function: frame-restack frame1 frame2 &optional above

この関数はframe2の下にframe1を再スタックする(restack: 再び重ねる)。いずれのフレームも可視で表示エリアがオーバーラップしていたら、frame2frame1を(部分的に)隠すことを暗に示している。オプションの3つ目の引数aboveが非nilなら、この関数はframe2の上にframe1を再スタックする。これはいずれのフレームも可視で表示エリアがオーバーラップしていたら、frame1frame2を(部分的に)隠すことを意味している。

この関数は最初のステップではディスプレイからframe1のウィンドウシステムのウィンドウを削除して、2つ目のステップで( aboveが真なら)frame2のウィンドウの下にframe1のウィンドウを再挿入を行う、2つのステップによりアトミックなアクションを処理すると技術的に考えることができる。したがってframe1を除く他のすべてのフレームに相対的なframe2のディスプレイ内でのZオーダー(スタッキングオーダー)は変更されない。

いくつかのウィンドウマネージャーはウィンドウの再スタックを拒絶する。

再スタックの効果は関連するフレームがアイコン化されたり不可視になったりしないかぎり継続することに注意してください。フレームを他のフレームの上位(や下位)に永続的に表示されるフレームグループに追加するためにフレームパラメーターz-group (位置のパラメーターを参照)を使用できます。これらのグループのいずれかにフレームが所属するかぎり、再スタックはそのグループ内での相対的なスタッキング位置にのみ効果があります。異なるZグループに所属するフレームにたいする再スタックの効果は未定義です。関数frame-list-z-orderでカレントのフレームスタッキングオーダーをリストできます(すべてのフレームを探すを参照)。

User Option: minibuffer-auto-raise

これが非nilならミニバッファーをアクティブにすることにより、ミニバッファーウィンドウのあるフレームが前面に移動される。

ウィンドウシステム上ではフレームパラメーターを使用して、(フレーム選択時に)auto-raising、(フレーム選択解除時に)auto-loweringを有効にできます。ウィンドウ管理のパラメーターを参照してください。

フレームを前面や背面に移動するという概念は、テキスト端末のフレームにも適用できます。各テキスト端末上では一度に表示されるのは常に最前面のフレームだけです。

Function: tty-top-frame &optional terminal

この関数はterminal上の最前面のフレームをリターンする。terminalは端末オブジェクト、フレーム(そのフレームの端末を意味する)、またはnil (選択されたフレームの端末を意味する)であること。これがテキスト端末を参照しなければリターン値はnil


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

30.13 フレーム構成

フレーム構成(frame configuration)はフレームのカレント配置、すべてのプロパティ、および各ウィンドウのウィンドウ構成(ウィンドウの構成を参照)を記録します。

Function: current-frame-configuration

この関数はフレームのカレント配置とそのコンテンツを記述するフレーム構成のリストをリターンする。

Function: set-frame-configuration configuration &optional nodelete

この関数はフレームの状態をconfigurationの記述にリストアする。ただしこの関数は削除されたフレームはリストアしない。

この関数は通常はconfiguration内にリストされない既存フレームすべてを削除する。しかしnodeleteが非nilなら、それらのフレームはかわりにアイコン化される。


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

30.14 子フレーム

子フレームはウィンドウ(ウィンドウを参照)と“通常”のフレームとの中間にあるオブジェクトです。ウィンドウのよように所属するフレームにアタッチされますが、ウィンドウとは異なり互いにオーバーラップすることができます。子フレームの1つのサイズや位置を変更しても兄弟となる他の子フレームのサイズや位置は変化しません。

仕様により子フレームの作成や変更を行う操作は特別な関数やカスタマイズ可能な変数ではなくフレームパラメーター(フレームのパラメーターを参照)の助けを借りて実装されています。子フレームはグラフィカル端末でのみ意味があることに注意してください。

子フレームを新たに作成したり通常のフレームを子フレームに変換するためには、そのフレームのparent-frameパラメーター(フレームとの相互作用のためのパラメーターを参照)にすでに存在するフレームをセットします。このパラメーターで指定されたフレームは、パラメーターが変更やリセットされるまでフレームの親フレームになります。これにより技術的には子フレームのウィンドウシステムのウィンドウは、親フレームのウィンドウシステムのウィンドウの子ウィンドウになります。

parent-frameパラメーターはいつでも変更できます。これを他のフレームにセットすれば子フレームがreparent(親を変更)されます。別の子フレームにセットすればフレームをネストされた(nested)子フレームにします。にセットすればフレームの状態をトップレベルのフレーム(ウィンドウシステムのウィンドウがディスプレイーのルートウィンドウの子であるようなフレーム)にリストアします。22

子フレームは任意にネスト(入れ子)させることができるので、フレームは子フレームと親フレームの両方になることができます。また子フレームと親フレームの相対的な役割はいつでも逆転させることができます(たとえ子フレームを親フレームより十分小さいサイズに保つことが通常はよいアイデアであるとしても)。フレームをそのフレームの祖先にしようと試みるとエラーがシグナルされます。

ほとんどのウィンドウシステムは親フレームのネイティブエッジ(フレームのジオメトリーを参照)で子フレームをクリップします(これらのエッジの外側は通常は不可視になる)。子フレームのパラメーターlefttopは親のネイティブフレームの左上隅から相対的な位置を指定します。親フレームがリサイズされたとき、この位置は概念的には変更されません。

NSビルドは親フレームのエッジで子フレームをクリップしないので、子フレーム自身が可視であっても親フレームを隠さないように配置することができます。

通常は親フレームを移動することにより、すべての子フレームとその子孫も相対的な位置が変化しないように一緒に移動されます。フックmove-frame-functions (フレームの位置を参照)は子フレームの親フレームにたいする相対的な位置が変化したときだけ実行されます。

親フレームがリサイズされた際には、子フレームは概念的には以前のサイズと親フレームの左上隅からの相対的な位置を保ちます。これは親フレームが縮小されると子フレームが(部分的に)不可視になるかもしれないことを意味しています。親フレームのリサイズ時に常に子フレームを比例してリサイズおよび再配置するためにパラメーターkeep-ratioを使用できます(フレームとの相互作用のためのパラメーターを参照)。これにより親フレームが縮小された際にフレームの一部が隠されることを防ぐことができます。

可視な子フレームは常に親フレームの最上位に表示されるので、親フレームの下位に表示可能なNSビルド以外では親フレームの一部を隠すことになります。これは常に親ウィンドウであるデスクトップのルートウィンドウの最上位に表示されるトップレベルフレームのウィンドウシステムのウィンドウに相当します。親フレームがアイコン化されたり不可視(フレームの可視性を参照)になったときには子フレームは不可視になります。親フレームが非アイコン化されたり可視になると子フレームは可視になります。

親フレームが削除される際には、その前に子フレームが再帰的に削除されます(フレームの削除を参照)。この規則には1つの例外があります。子フレームが他のフレームの代理ミニバッファーフレーム(ミニバッファーとフレームを参照)を果たす際には、親フレームが削除されるまで削除されずに留まります。。この時点でその子フレームをミニバッファーとして使用するフレームが残っていなければ、Emacsは子フレームの削除も試みます。理由は何であれこの削除が失敗すると、その子フレームがトップレベルのフレームになります。

子フレームがメニューバーやツールバーをもてるかどうかはウィンドウシステムやウィンドウマネージャーに依存します。ほとんどのウィンドウシステムは子フレームのメニューバーを明示的に許可していません。フレームの初期パラメーターのセッティングでメニューバーとツールバーの両方を無効にすることを推奨します。

子フレームは通常はタイトルバーやエクスターナルボーダー(フレームのジオメトリーを参照)のようなウィンドウマネージャーの装飾を表示しません。子フレームがメニューバーやツールバーを表示しないときには他の種類のフレームのボーダーをエクスターナルボーダーのかわりに使用できます(レイアウトのパラメーターを参照)。

特にX(ただしGTK+ビルド以外)ではフレームのアウターボーダーを使用できます。MS-Windowsでは非0のアウターボ^ダーを指定することにより、幅が1ピクセルのエクスターナルボーダーが表示されます。すべてのウィンドウシステムにおいてインターナルボーダーを使用できます。いずれのケースでもフレームパラメーターundecorated (ウィンドウ管理のパラメーターを参照)で子フレームにたいするウィンドウマネージャーの装飾を無効にすることを推奨します。

マウスで装飾されていない子フレームのリサイズや移動を行うためには、特別なフレームパラメーターを使う必要があります(マウスドラッグのパラメーターを参照)。子フレームのインターナルボーダーが存在する場合には、そのフレームが非nildrag-internal-borderパラメーターをもっていればマウスによるフレームのリサイズに使用できます。snap-widthがセットされていれば、それは親フレームのエッジやコーナーそれぞれでフレームをスナップ(snaps)するピクセル数を表します。

マウスで子フレーム全体をドラッグするためには2つの方法があります。drag-with-mode-lineパラメーターが非nilなら、ミニバッファーウィンドウのないフレーム(ミニバッファーのウィンドウを参照)の最下ウィンドウのモードラインエリアを通じてドラッグできます。drag-with-header-lineパラメーターが非nilなら、フレームの最上ウィンドウのヘッダーラインを通じたドラッグが可能です。

子フレームにドラッグ可能なヘッダーラインやモードラインを与えるためには、ウィンドウパラメーターmode-line-formatheader-line-format (ウィンドウのパラメーターを参照)を使用するのが手軽です。これらにより(drag-with-header-lineの選択時に)不要なモードラインを削除したり、フレームのドラッグと干渉するマウス感応エリアを削除できます。

ユーザーが親フレームの外へフレームをマウスでドラッグすれば、親フレームのスクリーン領域外へ簡単にドラッグできます。マウスボタンを一度離してしまうと、そのようなフレームを取得するのは難しくなります。そのような状況を避けるために、フレームのパラメーターtop-visibleおよびbottom-visible (マウスドラッグのパラメーターを参照)をセットすることをお勧めします。

ヘッダーラインでユーザーにフレームをドラッグさせたければ、子フレームのtop-visibleパラメーターに数値をセットします。top-visibleに数値をセットすることによって、親フレームの上エッジを超えて子フレームの上エッジをドラッグすることが抑制されます。モードラインを介してフレームをドラッグさせたければ、bottom-visibleに数値をセットしてください。これは親フレームの下エッジを超えて子フレームの下エッジをドラッグすることを抑制します。いずれの場合でも、セットした数値は同時にドラッグの間に可視に留まる子フレーム領域の幅および高さをピクセルで指定します。

display-buffer-in-child-frame (バッファー表示用のアクション関数を参照)を介してバッファー表示に子フレームが使用されている際には、バッファーを表示中のウィンドウがquitされる際にフレームを適切に処理するために、フレームのauto-hide-functionパラメーターに関数をセットできます(フレームとの相互作用のためのパラメーターを参照)。

たとえば別のウィンドウに補完を表示する等でミニバッファーとの相互作用中子フレームを使用する際には、ミニバッファーのexit時にフレームを適切に処理するためにminibuffer-exitパラメーター(フレームとの相互作用のためのパラメーターを参照)が便利です。

子フレームの振る舞いは他のいくつかの点においても、トップレベルのフレームから逸脱しています。それらのいくつかを以下に挙げます:

  • 子フレームにたいする最大化とアイコン化の意味はウィンドウシステムに大きく依存する。原則としてアプリケーションは子フレームでこれらのオプションを決して呼び出すべきではない。デフォルトでは子フレームでiconify-frameを呼び出すと子フレームにに対応するトップレベルのフレームにたいしてアイコン化を試みる。異なる挙動を得るためには、以下で説明するオプションiconify-child-frameをカスタマイズできる。
  • 子フレームのraise、lower、restack (フレームのraise、lower、re-stackを参照)やz-group (位置のパラメーターを参照)の変更では、同じ親をもつ子フレームのstack順だけが変更される。
  • ウィンドウシステムの多くは子フレームの透明度(フォントとカラーのパラメーターを参照)を変更できない。
  • いくつかのウィンドウシステムでは、祖先のウィンドウの可視部分のマウスクリックによる、子フレームから親以外の祖先へのフォーカスの移動は失敗する。最初に直接的な親のウィンドウシステムのウィンドウを直接クリックする必要があるだろう。
  • ウィンドウマネージャーマウスポリシーにしたがってフォーカスを子フレームに拡大しないかもしれない。この問題にたいしてmouse-autoselect-windowのカスタマイズが助けになるかもしれない(マウスによるウィンドウの自動選択を参照)。
  • 子フレームへのドロップ(ドラッグアンドドロップを参照)はすべてのウィンドウシステムで動作を保証されない。親フレームにオブジェクトをドロップしたり、他の祖先にドロップするものもある。

以下の2つの関数は子フレームと親フレームで処理を行う際に役に立つかもしれません:

Function: frame-parent &optional frame

この関数はframeの親フレームをリターンする。frameの親フレームはウィンドウシステムのウィンドウがframeのウィンドウシステムのウィンドウの親ウィンドウであるようなEmacsフレーウである。そのようなフレームが存在すれば、frameはそのフレームの子フレームとみなされる。

この関数はframeに親フレームがなければnilをリターンする。

Function: frame-ancestor-p ancestor descendant

この関数はancestordescendantの祖先なら非nilをリターンする。ancestordescendantの親フレームかdescendantの親フレームの祖先なら、ancestordescendantの祖先である。ancestordescendantにはいずれも生きたフレームを指定しなければならない。

既存ウィンドウの最大の空エリア内への子フレームの描画に使用できる関数window-largest-empty-rectangleにも注意してください(座標とウィンドウを参照)。これは子フレームがウィンドウ内に表示されているテキストを隠さないようにするために有用です。

子フレームにたいするiconify-frameの挙動の調整に以下のオプションのカスタマイズが役に立つかもしれません。

User Option: iconify-child-frame

このオプションはEmacsにたいして子フレームのアイコン化を要求された際に処理を行う方法を指定する。nilならiconify-frameが子フレームに呼び出された際には何も行わない。iconify-top-levelなら子フレームの祖先であるトップレベルのフレームをアイコン化する。make-invisibleならアイコン化せずに子フレームを不可視にしようと試みる。

その他の値は子フレームのアイコン化を試みることを意味する。そのような試みはすべてのウィンドウマネージャーで許容されるとはかぎらず、子フレームがユーザーのアクションに無応答になることさえあり得るので、デフォルトではトップレベルのフレームをアイコン化する。


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

30.15 マウスの追跡

マウスをトラック(track: 追跡)するのが有用なことが時折あります。マウスのトラックとはマウスの位置を示す何かを表示して、マウス移動とともにそのインジケーターを移動するという意味です。効果的にマウスをトラックするためには、マウスが実際に移動するまで待機する手段が必要になります。

マウスをトラックするためには、マウスのモーション(motion: 移動)を表すイベントを問い合わせるのが便利な方法です。その後はそのイベントを待機することによりモーションを待機できます。それに加えて発生し得る他の類のイベントも簡単に処理できます。ボタンのリリースのような何か他のイベントだけを待機してマウスを永久にトラックすることは、通常は望ましくないのでこれは有用です。

Macro: track-mouse body…

このマクロはマウスモーションイベントの生成を有効にしてbodyを実行する。bodyはモーションイベントを読み取るために、通常はread-eventを使用してそれに対応して表示を変更する。マウスモーションイベントのフォーマットについてはモーションイベントを参照のこと。

body内の最後のフォームの値がtrack-mouseの値となる。ボタンのリリースを示すup-eventや、何であれトラッキングを停止すべきタイミングを意味するイベントを確認したらbodyからリターンするようデザインすること。この変数の値はマウスボタンが押されたときに、そのマウスイベントがどのように報告されるかも制御する。値がdroppingdrag-sourceなら、ポインター下にあるフレームに関連するモーションイベントが報告される。そのようなフレームがなければ、そのイベントはマウスボタンが最初に押されたフレームと関連のあるイベントとして報告される。加えて値がdrag-sourceなら、マウス位置リストのposn-windownilになる。これはマウスポインター下にあるフレームが直接見えないときに有用。

track-mouseマクロでは変数track-mouseを非nil値にバインドすることにより、Emacsにマウスモーションイベントを生成させる。この変数が特別な値draggingをもつなら、ディスプレイエンジンにマウスポインターのシェイプ(形状)の変更を控えるように追加で指示する。これはEmacsが表示する大きな範囲を横断するマウスドラッグを要するLispプログラムでは、そうしなければ表示箇所に応じてマウスポインターのシェイプが変更されてしまうので望ましいだろう(ポインターの形状を参照)。したがってドラッグ中にオリジナルのマウスポインターシェイプを保つ必要があるLispプログラムは、bodyの先頭でtrack-mouseを値draggingにバインドすること。

マウスモーションをトラックする通常の目的は、それ以降に発生するボタンのプッシュやリリースをカレント位置に示すことです。

多くの場合はテキストプロパティmouse-face(特殊な意味をもつプロパティを参照)を使用することにより、マウスをトラックする必要性を回避できます。これはより低レベルで機能して、かつLispレベルのマウストラッキングよりスムーズに実行されます。


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

30.16 マウスの位置

関数mouse-positionset-mouse-positionはマウスのカレント位置にたいするアクセスを提供します。

Function: mouse-position

この関数はマウス位置の記述子をリターンする。値は(frame x . y)のような形式であり、xyframeのネイティブ位置(フレームのジオメトリーを参照)から相対的に、frameのデフォルト文字サイズ(フレームのフォントを参照)の単位で位置を与える整数(丸められている可能性あり)。

Variable: mouse-position-function

この変数の値は非nilならmouse-positionにたいして呼び出される関数。mouse-positionはリターン直前に、自身の通常のリターン値を唯一の引数としてこの関数を呼び出して、それが何であれその関数がリターンした値をリターンする。

このアブノーマルフックはxt-mouse.elのようにLispレベルでマウス処理を行う必要があるパッケージのために存在する。

Variable: tty-menu-calls-mouse-position-function

nilなら、上述のようにTTYメニューはmouse-position-functionを呼び出す。これは再表示をトリガーする等、TTYメニューからのmouse-position-function呼び出しが安全ではない場合のために存在する。

Function: set-mouse-position frame x y

この関数はフレームframe内の位置xyマウスをワープ(warps the mouse)する。引数xyframeのネイティブ位置(フレームのジオメトリーを参照)から相対的に、frameのデフォルト文字サイズ(フレームのフォントを参照)の単位で位置を与える整数(丸められている可能性あり)。

結果となるマウス位置はframeのネイティブフレームに拘束される。この関数はframeが不可視なら何も行わない。リターン値に意味はない。

Function: mouse-pixel-position

この関数はmouse-positionと似ているが文字単位ではなくピクセル単位の座標をリターンする。

Function: set-mouse-pixel-position frame x y

この関数はset-mouse-positionのようにマウスをワープするが、xyが文字単位ではなくピクセル単位である点が異なる。

結果となるマウス位置はframeのネイティブフレームに拘束される。この関数はframeが不可視なら何も行わない。リターン値に意味はない。

フラフィカルな端末上では、以下の2つの関数によりマウスカーソルの絶対位置の取得とセットができます。

Function: mouse-absolute-pixel-position

この関数は選択されたフレームのディスプレイの位置(0, 0)から相対的に、マウスカーソルの位置の座標をピクセル単位のコンスセル(x . y)でリターンする。

Function: set-mouse-absolute-pixel-position x y

この関数はマウスカーソルを位置(x, y)に移動する。座標xyは、選択されたフレームのディスプレイの位置(0, 0)から相対的なピクセル値と解釈される。

以下の関数はフレーム上のマウスカーソルがレントで可視かどうかを確認します:

Function: frame-pointer-visible-p &optional frame

この述語関数はframe上に表示されたマウスポインターが可視なら非nil、それ以外はnilをリターンする。frameが省略またはnilならそれは選択されたフレームを意味する。これはmake-pointer-invisibletにセットされているときに有用。これによりポインターが隠されていることを知ることができる。Mouse Avoidance in The Emacs Manualを参照のこと。


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

30.17 ポップアップメニュー

Lispプログラムがポップアップメニューを表示して、ユーザーがマウスで候補を選択できます。テキスト端末上では、マウスが利用不可ならキーボードのモーションキーC-nC-p、上矢印キーや下矢印キーで候補を選択できます。

Function: x-popup-menu position menu

この関数はポップアップメニューを表示して、ユーザーが何を選択したかの指標をリターンする。

引数positionには、メニュー左上隅をスクリーン上のどこに置くか指定する。これはマウスボタンイベント(ユーザーがボタンを操作した位置にメニューを置くよう指示する)、または以下の形式のリストのいずれか:

((xoffset yoffset) window)

ここでxoffsetyoffsetwindowの左上隅からピクセル単位で測られた座標である。windowはウィンドウかフレーム。

positiontなら、それはマウスのカレント位置の使用を意味する(テキスト端末上でマウスが利用不可ならフレーム左上隅)。positionnilなら、それは実際にメニューをポップアップせずに、menu内で指定されたキーマップと等価なキーバインディングを事前に計算することを意味する。

引数menuはメニュー内で何を表示するかを意味する。これはキーマップかキーマップのリストを指定できる(メニューキーアップを参照)。この場合にはリターン値はユーザー選択に対応するイベントのリスト。選択がサブメニュー内で発生した場合には、このリストには複数の要素がある(x-popup-menuはそのイベントシーケンスにバインドされたコマンドを実際には実行しないことに注意)。テキスト端末やメニュータイトルをサポートするツールキットでは、menuがキーマップならタイトルはmenuのプロンプト文字列、menuがキーマップのリストなら最初のキーマップのプロンプト文字列から取得される(メニューの定義を参照)。

かわりにmenuは以下の形式をもつこともできる:

(title pane1 pane2...)

ここでpaneはそれぞれ以下の形式のリストである

(title item1 item2...)

itemはそれぞれコンスセル(line . value)であること。ここでlineは文字列、valuelineが選択された場合にリターンされる値。メニューキーマップとは異なりnilvalueは選択不可のメニューアイテムを作成しない。かわりにitemにコンスセルではなく文字列を指定できる。これは選択不可のメニューアイテムを作成する。

たとえば有効な選択からマウスを外してクリックしたり、C-gをタイプすることにより、有効な選択を行うことなくユーザーがメニューを取り除いた場合は、通常はquitしてx-popup-menuはリターンしない。しかしpositionがマウスボタンイベント(ユーザーがマウスでメニューを呼び出したことを示す)なら、quitは発生せずにx-popup-menuはリターンする。

使用上の注意: メニューキーマップで定義したプレフィクスキー処理を行える場合には、メニューの表示にx-popup-menuを使用しないでください。メニューの実装にメニューキーマップを使用する場合には、C-h cC-h aでメニュー内の個別アイテムの確認、およびそれらにたいするヘルプを提供できます。かわりにx-popup-menuを呼び出すコマンドを定義することによりメニューを実装した場合には、ヘルプ機能はそのコマンド内部で何が起こっているか知ることができず、そのメニューアイテムのヘルプを何も与えることはできません。

マウス移動によってサブメニュー間を切り替えるメニューバーのメカニズムは、それがx-popup-menuを呼び出すか確認するためにコマンドの定義を見ることができません。したがってx-popup-menuを使用してサブメニューの実装を試みた場合には、それは統合された方式でメニューバーとともに機能しません。メニューバーのすべてのサブメニューは親メニューのメニューキーマップにより実装されて、決してx-popup-menuで実装されないのはこれが理由です。メニューバーを参照してください。

メニューバーのサブメニューのコンテンツを変化させたい場合にも、その実装には依然としてメニューキーマップを使用するべきです。コンテンツを変化させるためには、必要に応じてメニューキーマップのコンテンツを更新するためにフック関数をmenu-bar-update-hookに追加してください。

Variable: x-pre-popup-menu-hook

x-popup-menuの呼び出しから直接、またはメニューキーマップを通して表示されるポップアップメニューの表示直前に実行されるノーマルフック。何らかの理由によりポップアップメニューを表示せずにx-popup-menuがリターンしたら呼び出されない。


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

30.18 ダイアログボックス

ダイアログボックスとはポップアップメニューの一種です。外見は多少異なり常にフレーム中央に表示されて、階層を1つしかもたず1つ以上のボタンがあります。ユーザーが“yes”、“no”、および別のいくつかの候補で応答ができる質問を尋ねるのがダイアログボックスの主な用途です。単一のボタンではユーザーに重要な情報の確認を強いることもできます。関数y-or-n-pyes-or-no-pは、マウスのクリックで呼び出されたコマンドから呼び出された際には、キーボードのかわりにダイアログボックスを使用します。

Function: x-popup-dialog position contents &optional header

この関数はポップアップダイアログボックスを表示してユーザーが何を選択したかの指標をリターンする。引数contentsは提供する選択肢を指定する。これは以下のフォーマットをもつ:

(title (string . value)…)

これはx-popup-menuにたいして単一のpaneを指定するリストのように見える。

リターン値は選択された候補のvalue

x-popup-menuの場合と同じように、このリストの要素はコンスセル(string . value)のかわりに単なる文字列かもしれない。これは選択不可のボックスを作成する。

このリスト内にnilがある場合には、それは左手側と右手側のアイテムを分ける。つまりnilより前のアイテムは左、nilより後のアイテムは右に表示される。リスト内にnilを含めない場合には、およそ半数ずつが両サイドに表示される。

ダイアログボックスは常にフレームの中央に表示される。引数positionはどのフレームかを指定する。可能な値はx-popup-menuの場合と同様だが、正確な座標や個別のウィンドウは問題ではなくフレームだけが問題となる。

headerが非nilならボックスのフレームタイトルは‘Information’、それ以外は‘Question’になる。前者はmessage-box (message-boxを参照)にたいして使用される(テキスト端末上ではボックスタイトルは表示されない)。

いくつかの構成ではEmacsは本当のダイアログボックスを表示できないので、かわりにフレーム中央のポップアップメニュー内に同じアイテムを表示する。

たとえばウィンドウマネージャーを使用して有効な選択を行うことなくユーザーがダイアログボックスを取り除いた場合には、通常はquitしてx-popup-dialogはリターンしない。


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

30.19 ポインターの形状

テキストプロパティpointerや、イメージならイメージプロパティ:pointer:mapを使用して、特定のテキストやイメージにたいしてマウスポインターのスタイルを指定できます。以下のテーブルの値を、これらのプロパティに使用できます。実際のシェイプはシステムにより異なります。記述してあるのはその例です。これらのプロパティには以下のテーブル内の値が使用できます。説明では例を示していますが、実際の外観はシステムに依存します。

text
nil

テキスト上にあるときの通常のマウスポインタースタイル(“I”のようなシェイプ)。

arrow
vdrag
modeline

北西向き矢印。

hand

上向きの手。

hdrag

左右の矢印。

nhdrag

上下の矢印。

hourglass

回転する輪。

ウィンドウの空部分(void parts: バッファーコンテンツのどの部分にも対応しない部分)の上では、マウスポインターは通常arrowスタイルを使用しますが、void-text-area-pointerをセットすることにより異なるスタイルを指定できます。

User Option: void-text-area-pointer

この変数は空テキストエリアにたいするマウスポインタースタイルを指定する。このエリアには行末の後やバッファー終端行の下が含まれる。デフォルトではarrow(non-text)ポインタースタイルを使用する。

一部のウィンドウシステムを使用する際には、変数x-pointer-shapeをセットすることによりtextの実際の外見を指定できます。

Variable: x-pointer-shape

この変数はEmacsフレーム内でポインタースタイルtextに通常使用するポインターシェイプを指定する。

Variable: x-sensitive-text-pointer-shape

この変数はマウスがマウスセンシティブテキスト上にあるときのポインターシェイプを指定する。

これらの変数は新たに作成されるフレームに影響します。これらは通常は既存のフレームに効果はありませんが、フレームのマウスカラーのインストール時にはこれら2つ変数のカレント値もインストールされます。フォントとカラーのパラメーターを参照してください。

これらのポインターシェイプのいずれかを指定するために使用可能な値はファイルlisp/term/x-win.el内で定義されています。それらのリストを確認するにはM-x apropos RET x-pointer RETを使用してください。


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

30.20 ウィンドウシステムによる選択

Xのようなウィンドウシステムでは、異なるアプリケーション間のデータ転送は選択(selections)により行われます。Xは任意の数の選択タイプ(selection types)を定義し、それぞれが独自にデータを格納できます。しかし一般的に使用されるのはクリップボード(clipboard)プライマリー選択(primary selection)セカンダリー選択(secondary selection)の3つだけです。それ以外のウィンドウシステムではクリップボードだけがサポートされます。これら3つの選択を使用するEmacsコマンドについてはCut and Paste in The GNU Emacs Manualを参照してください。このセクションではウィンドウシステムによる選択の読み取りとセットを行う低レベル関数について説明します。

Command: gui-set-selection type data

この関数はウィンドウシステムの選択をセットする。これは選択タイプtype、それに割り当てる値dataという2つの引数を受け取る。

typeはシンボルであること。通常はPRIMARYSECONDARYCLIPBOARDのいずれかである。これらはXウィンドウシステムの慣例に対応する大文字のシンボル名である。typenilならそれはPRIMARYを意味する。

datanilなら、それはその選択をクリアーすることを意味する。それ以外ならdataは文字列、シンボル、整数、オーバーレイ、同じバッファーを指す2つのマーカーのコンスを指定できる。オーバーレイとマーカーのペアは、そのオーバーレイまたはマーカー間のテキストを意味する。引数dataには有効な非ベクターの選択のベクターも指定できる。

dataが文字列なら、そのテキストプロパティによって個々のデータタイプに使用する値を指定できる。たとえばdatatext/uri-listという名前のテキストプロパティを保有していれば、データタイプtext/uri-listとともにgui-get-selectionを呼び出すことによって、data自身のかわりにそのプロパティの値が使用される。

この関数はdataをリターンする。

Function: gui-get-selection &optional type data-type

この関数はEmacsや他のプログラムによりセットアップされた選択にアクセスする。これはtypedata-typeの2つの引数を受け取る。typeは選択のタイプでありデフォルトはPRIMARY

data-type引数は別のXクライアントから取得したrawデータをLispデータに変換するためにデータ変換に使用する形式を指定する。有意義な値にはTEXTSTRINGUTF8_STRINGTARGETSLENGTHDELETEFILE_NAMECHARACTER_POSITIONNAMELINE_NUMBERCOLUMN_NUMBEROWNER_OSHOST_NAMEUSERCLASSATOMINTEGERが含まれる(これらは対応するX慣習の大文字シンボル名である)。data-typeのデフォルトはSTRING。X以外のウィンドウシステムは、通常はSTRINGに加えて、少数の部分集合だけをサポートする。

User Option: selection-coding-system

この変数は選択やクリップボードに読み書きする際のコーディングシステムを指定する。コーディングシステムを参照のこと。デフォルトはcompound-text-with-extensionsで、これはX11が通常使用するテキスト表現に変換する。

EmacsがMS-Windows上で実行されている際には、一般的にX選択はサポートされませんがクリップボードはサポートされます。MS-Windowsでのgui-get-selectiongui-set-selectionは、テキストデータタイプだけをサポートします。クリップボードが他のタイプのデータを保持している場合には、Emacsはクリップボードを空として扱います。サポートされるデータタイプはSTRINGです。

後方互換性のためにgui-get-selectiongui-set-selectionにたいして、Emacs 25.1以前の名前x-get-selectionx-set-selectionが時代遅れのエイリアスとして存在します。


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

30.21 メディアのyank

たとえばあなたがウェブブラウザで“Copy Image(イメージをコピー)”を選択したとすると、そのイメージはクリップボードに配置されて、Emacsはgui-get-selectionを通じてそのイメージにアクセスすることができます。ただし一般的にはイメージデータを任意のバッファーに挿入してもあまり役には立ちません。デフォルトのままでは実際のところ大したことはできないのです。

そのためにEmacsでは、これらの“複雑”な選択にたいしてモードがハンドラーを登録できるようになっています。

Function: yank-media-handler types handler

typesMIMEメディアタイプのシンボルやそれらにマッチするregexp、またはシンボルとregexpのリスト。たとえば:

(yank-media-handler 'text/html #'my-html-handler)
(yank-media-handler "image/.*" #'my-image-handler)

モードは必要な数のハンドラーを登録できる。

関数handlerはメディアタイプシンボルMIMEとデータ(文字列)という2つのパラメーターで呼び出される。このハンドラーはそのオブジェクトのバッファーへの挿入や保存、あるいはそれが何であれそのモードにとって適切な処理を行うこと。

yank-mediaコマンドはカレントバッファーで登録されたハンドラーを照会するとともに、クリップボード上の利用可能なメディアタイプと比較を行い、(もしあれば)マッチした選択をそのハンドラーに渡します。マッチする選択が複数あれば、まずユーザーに問い合わせを行います。

クリップボード/プライマリー選択を調べるためにyank-media-typesコマンドを使うことができます。これはカレントで利用可能なメディアタイプすべてをリストします。これは実際に利用可能なデータは何なのかを確認できるので、ハンドラーの作成時に便利でしょう。一部のアプリケーションは、驚くほど多くの異なるデータタイプをクリップボードに配置します。


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

30.22 ドラッグアンドドロップ

他のアプリケーションからユーザーが何かをEmacsの上にドロップすると、Emacsはドロップされたテキストの挿入、あるいはドロップされたURLのオープンを試みます。Emacsは常にテキストがドロップされると、そのドロップ発生時のマウスポインター位置にテキストを挿入するか、挿入が失敗した場合には(そのバッファーが読み取り専用の場合に発生し得る)そのテキストをkillリングに保存します。URLがドロップされた場合には、EmacsはそのURLと変数dnd-protocol-alistに定義されたregexp、その後は変数browse-url-handlersbrowse-url-default-handlersに定義されたregexpをマッチして適切なハンドラー関数の呼び出しを試みます。もし適切なハンドラーが見つからなければ、EmacsはそのURLを平文テキストとして挿入するというフォールバック処理を行います。

Variable: dnd-protocol-alist

この変数は(pattern . action)という形式のコンスセルのリストである。ここでpatternはドロップされた後にそのURLにたいしてマッチされるregexp、actionはドロップされたURLがpatternにマッチした場合に2つの引数で呼び出される関数で、1つ目の引数はドロップされたURL、2つ目の引数はcopymovelinkprivateaskというシンボルのいずれか。

actionprivateなら、それはドロップ操作を開始したプログラムが、そのURLでは指定されていないアクションをEmacsに行って欲しいことを意味する。この場合に行うべき妥当なアクションはそのURLのオープン、あるいはカレントバッファーへのそのURLのコンテンツのコピーとなる。それ以外のactionは、dnd-begin-file-dragにたいするaction引数と同じ意味合いとなる。

Emacsはウィンドウシステムそれぞれにたいして個別にテキストとURLの受信を実装しており、他の種別のドロップによる受信はデフォルトではサポートしていません。他の種別のデータの受信をサポートするためには、以下のX固有のインターフェイスを使用してください。

Xウィンドウシステムにおいてユーザーが別のアプリケーションからEmacsに何かをドラッグすると、そのアプリケーションはEmacsがドラッグされたデータを理解しているかどうかを告げることを期待します。このような問いにたいして何を応答するか決定するためにEmacsが用いるのが、変数x-dnd-test-function内の関数です。デフォルト値はx-dnd-default-test-functionで、これはドロップされたデータのタイプがx-dnd-known-types内に存在すればドロップを受け入れます。何か別の条件にもとづいてEmacsにドロップを許容または拒絶させたければ、x-dnd-test-functionおよびx-dnd-known-typesを変更してください。

Emacsが別のデータタイプのドロップを受け取る方法を変更したり、新たなタイプを理解するためにドロップを有効にしたい場合にはx-dnd-types-alistを変更してください。これを正しく行うためには他のアプリケーションがドラッグアンドドロップに使用するデータタイプが何なのかに関する詳細な知識が要求されます。

これらのデータタイプは通常は他のアプリケーションから提供されたX選択から入手できるスペシャルデータタイプとして実装されています。ほとんどのケースにおいて、これらはgui-set-selectionが通常許容するのと同じデータタイプかMIMEタイプのいずれかであり、それは使用される固有のドラッグアンドドロップのプロトコルに依存します。たとえば平文テキストに用いられるのは"STRING""STRING"のいずれかでしょう。

XウィンドウシステムでEmacsを実行する際には、XDS (X Direct Save)というプロトコルがサポートされます。このプロトコルによってユーザーがファイルをDiredウィンドウのようなEmacsウィンドウにドラッグアンドドロップして保存ができるようになります。XDSに独特な要件に準拠するために、これらのドラッグアンドドロップの要求は特別に処理されます。つまりx-dnd-types-alistに応じて処理されるのではなく、変数x-dnd-direct-save-functionの値であるdirect-save関数(direct-save function)によって処理されるのです。これはneed-nameおよびfilenameという2つの引数を受け取る関数である必要があります。XDSプロトコルではファイルのドラッグにたいして2段階の手続きが用いられます:

  1. ファイルのドラッグ元であるアプリケーションは、ファイルを保存するためにEmacsにたいして完全なファイル名の提供を求める。この目的のために1つ目の引数need-nameに非nil、2つ目の引数filenameに保存するファイルのディレクトリー部分を除いた名前をセットしてdirect-save関数が呼び出される。この関数はファイルを保存するための完全に展開された絶対ファイル名をリターンする必要がある。たとえばDiredウィンドウにファイルがドラッグされれば、そのファイルのディレクトリーは当然ドロップされた場所に表示されているファイルのディレクトリーになるだろう。何らかの理由によりファイルの保存が不可能な場合には、この関数はドラッグアンドドロップ操作をキャンセルするnilをリターンする必要がある。
  2. ファイルのドラッグ元のアプリケーションは、1回目のdirect-save関数呼び出しでリターンされた名前でファイルを保存する。ファイルの保存に成功したら1つ目の引数need-namenil、2つ目の引数filenameに保存したファイルの完全な絶対ファイル名をセットして、もう一度direct-save関数を呼び出す。この関数にはファイルが保存されたという事実に鑑み、何であれ必要な処理を行うことが期待される。たとえばDiredならそこに新たなファイルを表示して、ディスプレイ上のディレクトリーを更新する必要があるだろう。

x-dnd-direct-save-functionのデフォルト値はx-dnd-save-directです。

Function: x-dnd-save-direct need-name filename

引数need-nameが非nilで呼び出されると、この関数はファイルを保存するためにユーザーに絶対ファイル名の入力を求める。指定されたファイルがすでに存在する場合には、上書きするかどうかの入力をユーザーに追加で求めて、ユーザーが上書きに同意した場合のみ絶対ファイル名をリターンする。

引数need-namenilで呼び出された際には、カレントバッファーがDiredモード、あるいはDiredを継承する子孫の場合にはDiredの一覧リストをリバート、それ以外の場合にはfind-file (ファイルをvisitする関数を参照)を呼び出してそのファイルをvisitする。

Function: x-dnd-save-direct-immediately need-name filename

この関数はx-dnd-save-directと同様に機能するが、引数need-nameが非nilで呼び出されても、ファイルを保存するための完全なファイル名の入力をユーザーに求めずに、カレントバッファーのデフォルトディレクトリーにたいしてfilename引数を展開してリターンする(デフォルトディレクトリーにその名前のファイルが既に存在する場合に確認を求めるのは変わらず)。

ウィンドウシステムが対応していれば、Emacsのフレームから他のアプリケーションウィンドウへのコンテンツのドラッグもEmacsはサポートします。

Function: dnd-begin-text-drag text &optional frame action allow-same-frame

この関数はframeから別のプログラム(ドロップターゲット(drop target)と呼ばれるへのテキストのドラッグを開始して、テキストがドロップされた際のドラッグアンドドロップ操作の結果、またはドラッグアンドドロップ操作がキャンセルされたという結果をリターンする。textはドロップターゲットによって挿入されることになるテキスト。

actioncopymoveというシンボルのいずれかでなければならない。ここでcopyはドロップターゲットによってtextが挿入されるべきであることを意味する。movecopyと同様だが、後述するように呼び出し元は更にソースからtextを削除する必要があるかもしれないことを意味する。

frameはマウスボタンをカレントで押下したフレーム。nilは選択されているフレームを意味する。どのマウスボタンも押されていなければ即座にリターンするかもしれないので、down-mouse-1やそれに類するイベント(マウスイベントを参照)の直後のみ、そのイベントが発生したフレーム(クリックイベントを参照)をframeにセットして呼び出すこと。

allow-same-frameframe自体の上へのドロップを無視するかどうかを指定する。

リターン値はドロップターゲットが実際に行ったアクション、オプションで呼び出し元が何を行うべきかを指定する。リターン値は以下のうちのシンボルのいずれか:

copy

ドロップターゲットはドロップされたテキストを挿入した。

move

ドロップターゲットはドロップされたテキストを挿入したが、呼び出し元はそのドロップ元(たとえばバッファー)からtextを削除する必要がある。

private

ドロップターゲットは指定されていない何らかのアクションを行った。

nil

ドラッグアンドドロップの操作はキャンセルされた。

Function: dnd-begin-file-drag file &optional frame action allow-same-frame

この関数はframeから別のアプリケーションへのfileのドラッグを開始して、そのファイルがドロップされた際のドラッグアンドドロップ操作の結果、あるいはドラッグアンドドロップ操作がキャンセルされたという結果をリターンする。

fileがリモートファイルなら、一時的なコピーを作成する。

actioncopymove、またはlink,のいずれかでなければならない。ここでcopyはドロップターゲットによってfileがオープンまたはコピーされるべきことを、moveはドロップターゲットがファイルを別の場所に移動すべきことを、そしてlinkはドロップターゲットがfileへのシンボリックリンクを作成するべきであることを意味する。fileがリモートファイルの場合にアクションとしてlinkを指定するとエラーになる。

frameallow-same-frameの意味はdnd-begin-text-dragの場合と同様。

リターン値はドロップターゲットが実際に行ったアクションで、以下のうちのシンボルのいずれか:

copy

ドロップターゲットはfileをオープンした、または別の場所へコピーした。

move

ドロップターゲットはfileを別の場所に移動した。

link

ドロップターゲット(通常はファイルマネージャー)はfileへのシンボリックリンクを作成した。

private

ドロップターゲットは指定されていない何らかのアクションを行った。

nil

ドラッグアンドドロップの操作はキャンセルされた。

Function: dnd-begin-drag-files files &optional frame action allow-same-frame

この関数はdnd-begin-file-dragと同様だが、filesがファイルのリストである点が異なる。ドロップターゲットが複数ファイルのドロップをサポートしていなければ、かわりに1つ目のファイルが使用される。

Function: dnd-direct-save file name &optional frame allow-same-frame

この関数はdnd-begin-file-dragと似ているが、アクションのかわりにnameを指定することによって、ターゲットプログラムがその名前のコピーを作成する点が異なる(デフォルトのアクションとしてコピーを行う関数)。

上述した高レベルのインターフェイスは、低レベルなプリミティブの上位に実装されています。ファイルやテキスト以外のコンテンツのドラッグを使用が必要なら、x-begin-dragのかわりに低レベルのインターフェイスを使用してください。ただしこれらの低レベルなインターフェイスの使用にはデータタイプ、それにあなたがサポートしたいプラットフォームそれぞれにおいて、プログラムがドラッグアンドドロップを通じたコンテンツ転送に用いるアクションに関する詳細な知識が必要となるでしょう。

Function: x-begin-drag targets &optional action frame return-frame allow-current-frame follow-tooltip

この関数はframeからのドラッグを開始して、そのドラッグアンドドロップがドロップに成功するか、あるいは拒絶されたかのいずれにより操作終了したらリターンする。ドロップはframe以外のトップレベルのXウィンドウ(ドロップターゲットallow-current-frameが非nilなら任意のXウィンドウ)の上でマウスボタンがリリースされた際に発生する。そのドラッグアンドドロップ操作の開始時にどのマウスボタンも押されていなければ、この関数は即座にnilをリターンする。

targetsgui-get-selectiondata-type引数のような、選択されているターゲットを記述した文字列のリストであり、ドロップターゲットがEmacsに要求する可能性がある(ウィンドウシステムによる選択を参照)。

actionはターゲットに推奨されているアクションを記述したシンボル。XdndActionCopy (選択されているXdndSelectionのコンテンツをドロップターゲットにコピー)、XdndActionMove (XdndActionCopyのようにコピーを行い更にコピー後は選択に格納されていたものが何であれ削除が必要)のいずれか。

利用可能なアクションが記述されたシンボルと、ドロップターゲットが利用可能なアクションを選択する際にユーザーへの提示を期待する文字列を関連付けるalistでもよい。

return-frameが非nil、および最初にマウスがframeの外に移動してからEmacsフレームに移動した場合には、マウスが移動したフレームを即座にリターンする。return-frameがシンボルnowなら、最初にマウスがframeの外に移動するのを待機せずに、フレームが何であれマウスポインター配下にあればそのフレームをリターンする。return-frameは特にあるフレームから別のフレームへのコンテンツのドラッグを扱いたい際に役に立つだろう。他のプログラムへのコンテンツのドラッグも扱えるものの、すべてのシステムやウィンドウマネージャーで動作する保証はない。

follow-tooltipが非nilの場合には、ドラッグアンドドロップ操作の間にマウスポインターが移動するたびに、(tooltip-showによって表示されるような)ツールチップの位置がマウスポインターの位置にしたがうようになる。マウスボタンがリリースされるとツールチップは非表示になる。

ドロップが拒絶されるかドロップターゲットが見つからなければ、この関数はnilをリターンする。それ以外の場合には、ターゲットが行うことを選択したアクション(ドロップターゲットがサポートしていなければactionとは異なるかもしれない)を記述するシンボルをリターンする。XdndActionCopyXdndActionMoveに加えてXdndActionPrivateも有効なリターンである。これはドロップターゲットが指定されていないアクションを選択したことを意味しており、呼び出し元はそれ以上の処理を要求されない。

呼び出し元はターゲットによって選択された処理を完遂するために、ターゲットと協力しなければならない。たとえばこの関数がXdndActionMoveをリターンしたら、呼び出し元はドラッグされたバッファーのテキストを削除すること。

Xウィンドウではx-begin-dragは、複数の異なるドラッグアンドドロップのプロトコルをサポートします。ある特定のドラッグアンドドロップのプロトコルによってサポートされているか不明なコンテンツをドラッグする際には、以下の変数の値を変更してそのプロトコルをオフに切り替えることが望ましい場合があります:

Variable: x-dnd-disable-motif-protocol

この変数が非nilならMotifのドラッグアンドドロップのプロトコルは無効化となり、それらのプロトコルしか理解していないプログラムへのドロップは機能しない。

Variable: x-dnd-use-offix-drop

この変数がnilならOffiX(旧KDE)のドラッグアンドドロップのプロトコルは無効となる。シンボルfilesなら、x-begin-dragによって与えられたターゲットのいずれかが"FILE_NAME"の場合のみOffiXプロトコルが使用される。それ以外の値の場合には、サポートされているコンテンツのドロップにOffiXプロトコルが使用される。

Variable: x-dnd-use-unsupported-drop

x-begin-dragによって与えられたリスト内に"STRING""UTF8_STRING""COMPOUND_TEXT""TEXT"のいずれかのターゲットがあれば、ドロップターゲットが何もドラッグアンドドロップのプロトコルをサポートしていなくても、Emacsは合成されたマウスイベントとプライマリー選択を用いてテキストの挿入を試みる。

そのようなドロップにおいては、Emacsがそのプライマリー選択の所有者になるという副作用がある。これが望ましくなければ、この変数をnilにセットされたドロップエミュレーションを無効にできる。


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

30.23 カラー名

カラー名(color name)とはカラーを指定するテキスト(通常は文字列)です。‘black’、‘white’、‘red’等を指定できます。定義された名前のリストはM-x list-colors-displayを使用して確認できます。‘#rgb’や‘RGB:r/g/b’のような数値的な形式でカラーを指定することもできます。ここでrは赤(red)、gは緑(green)、bは青(blue)のレベルを指定します。1桁、2桁、3桁、または4桁の16進数をrに使用できます。その後のgbには同じ桁数の16進数を同様に使用しなければなりません。これにより総桁数が3、6、9、または12桁の16進数となります(カラーの数値的なRGB指定についての詳細はXウィンドウシステムのドキュメントを参照)。

以下の関数は有効なカラー名と、それらの外見を判断する手段を提供します。以下で説明するようにその値は選択されたフレーム(selected frame)に依存する場合があります。“選択されたフレーム”という用語の意味については入力のフォーカスを参照してください。

補完付きでカラー名のユーザー入力を読み取るにはread-colorを使用します(read-colorを参照)。

Function: color-defined-p color &optional frame

この関数はカラー名が有意かどうかを報告する。もし有意ならt、それ以外はnilをリターンする。引数frameはどのフレームのディスプレイにたいして問い合わせるかを指定する。frameが省略またはnilの場合は選択されたフレームが使用される。

これは使用しているディスプレイがそのカラーをサポートするかどうかは告げないことに注意。X使用時にはすべての種類のディスプレイ上のすべての定義されたカラーを問い合わせることができ、何らかの結果(通常は可能な限り近いカラー)を得ることができるだろう。あるフレームが特定のカラーを実際に表示できるかどうか判断するためにはcolor-supported-p (以下参照)を使用する。

この関数は以前はx-color-defined-pと呼ばれており、その名前は今でもエイリアスとしてサポートされている。

Function: defined-colors &optional frame

この関数はframe(デフォルトは選択されたフレーム)上で定義されていて、かつサポートされるカラー名のリストをリターンする。frameがカラーをサポートしなければ値はnil

この関数は以前はx-defined-colorsと呼ばれており、その名前は今でもエイリアスとしてサポートされている。

Function: color-supported-p color &optional frame background-p

これは、frameが実際にカラーcolor (または最低でもそれに近いカラー)を表示可能ならtをリターンする。frameが省略またはnilならこの問いは選択されたフレームに適用される。

フォアグラウンドとバックグラウンドにたいして異なるカラーセットをサポートする端末がいくつかある。background-pが非nilなら、それはcolorがバックグラウンドとして、それ以外はフォアグラウンドとして使用可能かどうかを問うことを意味する。

引数colorは有効なカラー名でなければならない。

Function: color-gray-p color &optional frame

これはcolorframeのディスプレイ上の定義としてグレイスケールならtをリターンする。frameが省略またはnilなら、この問いは選択されたフレームに適用される。colorが有効なカラー名でなければ、この関数はnilをリターンする。

Function: color-values color &optional frame

この関数はframe上で理想的にはcolorがどのように見えるべきかを記述する値をリターンする。colorが定義済みなら値は赤、緑、青の割合を与える3つの整数からなるリストとなる。それぞれの整数の範囲は原則として0から65535だが、この範囲全体を使用しないディスプレイもいくつか存在するだろう。この3要素のリストはカラーのRGB値(rgb values)と呼ばれる。

colorが未定義なら値はnil

(color-values "black")
     ⇒ (0 0 0)
(color-values "white")
     ⇒ (65535 65535 65535)
(color-values "red")
     ⇒ (65535 0 0)
(color-values "pink")
     ⇒ (65535 49344 52171)
(color-values "hungry")
     ⇒ nil

カラーの値はframeのディスプレイにたいしてリターンされる。frameが省略またはnilの場合には、この情報は選択されたフレームのディスプレイにたいしてリターンされる。このフレームがカラーを表示できなければ値はnil

この関数は以前はx-color-valuesと呼ばれており、その名前は今でもエイリアスとしてサポートされている。

Function: color-name-to-rgb color &optional frame

この関数はcolor-valuesと同じことを行うが、0.0から1.0(両端を含む)の浮動小数点数としてカラー値をリターンする。

Function: color-dark-p rgb

この関数はRGBトリプレットで示されるカラーrgbが、暗いバックグラウンド(dark background)のときより明るいバックグラウンド(white background)のときの方が可読性に優れる場合には非nilをリターンする。引数rgb(r g b)という形式のリストであること。リストの要素はそれぞれ0.0から1.0(両端を含む)の浮動小数点数。カラー名をこのようなリストに変換するためにはcolor-name-to-rgbを使うことができる。


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

30.24 テキスト端末のカラー

テキスト端末は通常は少しのカラーしかサポートせず、コンピューターはカラー選択に小さい整数を使用します。これは選択したカラーがどのように見えるかコンピューターが信頼性をもって告げることができず、どのカラーがどのような小さい整数に対応するかという情報をアプリケーションに伝える必要があることを意味します。しかしEmacsは標準的なカラーセットを知っており、それらの自動的な使用を試みるでしょう。

このセクションで説明する関数はEmacsが端末カラーを使用する方法を制御します。

これらの関数のうちのいくつかはカラー名で説明したRGB値(rgb values)を使用またはリターンします。

これらの関数はオプション引数としてディスプレイ(フレームまたは端末名のいずれか)を受け取ります。わたしたちは将来には異なる端末上で異なるカラーをEmacsにサポートさせたいと望んでいます。そうすればこの引数はどの端末を処理するか(デフォルトは選択されたフレームの端末。入力のフォーカスを参照)を指定するようになるでしょう。しかし現在のところframe引数に効果はありません。

Function: tty-color-define name number &optional rgb frame

この関数はカラー名nameをその端末上のカラー値numberに関連付ける。

オプション引数rgbが指定された場合、それはそのカラーが実際にどのように見えるかを指定する3つの数値のリストからなるRGB値である。rgbを指定しなければEmacsはそれがどのように見えるか知らないので、そのカラーを他のカラーに近似するためにtty-color-approximateで使用することができない。

Function: tty-color-clear &optional frame

この関数はテキスト端末の定義済みカラーのテーブルをクリアーする。

Function: tty-color-alist &optional frame

この関数はテキスト端末がサポートする既知のカラーを記録したalistをリターンする。

それぞれの要素は(name number . rgb)、または(name number)という形式をもつ。ここでnameはカラー名、numberはその端末でカラー指定に使用される数値。rgbが与えられたら、それはそのカラーが実際にどのように見えるかを告げる3つのカラー値(赤、緑、青)のリストである。

Function: tty-color-approximate rgb &optional frame

この関数はdisplayにたいしてサポートされた既知のカラーの中から、RGB値rgb (カラー値のリスト)で記述されたもっとも近いカラーを探す。リターン値はtty-color-alistの要素。

Function: tty-color-translate color &optional frame

この関数はdisplayにたいしてサポートされた既知のカラーの中から、もっとも近いカラーのインデックス(整数)をリターンする。名前colorが未定義なら値はnil


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

30.25 Xリソース

このセクションではXリソース、または他のオペレーティングシステム上での等価物を問い合わせたり使用する関数および変数をいくつか説明します。Xリソースにたいする詳細な情報はX Resources in The GNU Emacs Manualを参照してください。

Function: x-get-resource attribute class &optional component subclass

関数x-get-resourceはXウィンドウのデフォルトデータベースからリソース値を取得する。

リソースはキー(key)クラス(class)の組み合わせによりインデックス付けされている。この関数は‘instance.attribute’という形式をキー(instanceはEmacsが呼び出されたときの名前)、クラスとして‘Emacs.class’として使用することにより検索を行う。

オプション引数componentsubclassは、それぞれキーとクラスを追加する。指定する場合には両方を指定するか、さもなくばどちらも指定してはならない。これらを指定した場合にはキーは‘instance.component.attribute’、クラスは‘Emacs.class.subclass’となる。

Variable: x-resource-class

この変数はx-get-resourceが照会すべきアプリケーション名を指定する。デフォルト値は"Emacs"x-get-resourceの呼び出し周辺で、この変数を他のアプリケーション名の文字列にバインドすることにより、アプリケーション名にたいしてXリソースを調べることができる。

Variable: x-resource-name

この変数はx-get-resourceが照会すべきインスタンス名を指定する。デフォルト値はEmacs呼び出し時の名前、またはスイッチ‘-name’、または‘-rn’で指定された値。

上述のいくつかを説明するためにXリソースファイル(通常は~/.Xdefaults~/.Xresources)内に以下のような行があるとしましょう:

xterm.vt100.background: yellow

その場合は:

(let ((x-resource-class "XTerm") (x-resource-name "xterm"))
  (x-get-resource "vt100.background" "VT100.Background"))
     ⇒ "yellow"
(let ((x-resource-class "XTerm") (x-resource-name "xterm"))
  (x-get-resource "background" "VT100" "vt100" "Background"))
     ⇒ "yellow"
Variable: inhibit-x-resources

この変数が非nilならEmacsはXリソースを照会せず、新たなフレーム作成時にXリソースは何も効果をもたない。


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

30.26 ディスプレイ機能のテスト

このセクションの関数は特定のディスプレイの基本的な能力を説明します。Lispプログラムはそのディスプレイが行えることに挙動を合わせるために、それらを使用できます。たとえばポップアップメニューがサポートされなければ、通常はポップアップメニューを使用するプログラムはミニバッファーを使用できます。

これらの関数のオプション引数displayは問い合わせるディスプレイを指定します。これにはディスプレイ名、フレーム(フレームがあるディスプレイを指定)、またはnil (選択されたフレームのディスプレイを参照する。入力のフォーカスを参照)を指定できます。

ディスプレイに関する情報を取得するその他の関数についてはカラー名を参照してください。

Function: display-popup-menus-p &optional display

この関数はdisplay上でポップアップメニューがサポートされていればt、それ以外はnilをリターンする。Emacsディスプレイのある部分をマウスでクリックすることによりメニューがポップアップするので、ポップアップメニューのサポートにはマウスが利用可能であることが要求される。

Function: display-graphic-p &optional display

この関数はdisplayが一度に複数フレームおよび複数の異なるフォントを表示する能力を有すグラフィックディスプレイならtをリターンする。これはXのようなウィンドウシステムのディスプレイにたいしては真、テキスト端末にたいしては偽となる。

Function: display-mouse-p &optional display

この関数はdisplayでマウスが利用可能ならt、それ以外はnilをリターンする。

Function: display-color-p &optional display

この関数はそのスクリーンがカラースクリーンならtをリターンする。これは以前はx-display-color-pと呼ばれており、その名前はエイリアスとして今でもサポートされる。

Function: display-grayscale-p &optional display

この関数はスクリーンがグレースケールを表示可能ならtをリターンする(カラーディスプレイはすべてこれを行うことができる)。

Function: display-supports-face-attributes-p attributes &optional display

この関数はattributes内のすべてのフェイス属性がサポートされていれば非nilをリターンする(フェイスの属性を参照)。

幾分発見的ではあるが“サポートされる”という言葉は、基本的にはあるフェイスがattributes内のすべての属性を含み、ディスプレイにたいしてデフォルトフェイスにマージ時に、

  1. デフォルトフェイスとは異なる外見で表示でき、かつ
  2. 指定した属性と正確に一致しない場合はより近い(close in spirit)外見で表示する

2つ目のポイントによると属性:weight blackは太字(bold)表示可能、同様に属性:foreground "yellow"は黄色がかった何らかのカラーを表示可能なすべてのディスプレイで満たされるだろうが、属性:slant italicは斜体(italic)を自動的に淡色(dim)に置き換えるttyの表示コードでは満たされないであろうことを暗示している。

Function: display-selections-p &optional display

この関数はdisplayが選択(selections)をサポートすればtをリターンする。ウィンドウ化されたディスプレイでは通常は選択がサポートされるが、他の場合にもサポートされ得る。

Function: display-images-p &optional display

この関数はdisplayがイメージを表示可能ならtをリターンする。ウィンドウ化されたディスプレイは原則イメージを処理するが、イメージにたいするサポートを欠くシステムもいくつかある。イメージをサポートしないディスプレイ上ではEmacsはツールバーを表示できない。

Function: display-screens &optional display

この関数はそのディスプレイに割り当てられたスクリーンの数をリターンする。

Function: display-pixel-height &optional display

この関数はスクリーンの高さをピクセルでリターンする。文字端末では文字数で高さを与える。

マルチモニターにセットアップされているグラフィカル端末では、displayに割り当てられたすべての物理モニターのピクセル幅を参照することに注意。複数の端末を参照のこと。

Function: display-pixel-width &optional display

この関数はスクリーンの幅をピクセルでリターンする。文字端末では文字数で幅を与える。

マルチモニターにセットアップされているグラフィカル端末では、displayに割り当てられたすべての物理モニターのピクセル幅を参照することに注意。複数の端末を参照のこと。

Function: display-mm-height &optional display

この関数はスクリーンの高さをミリメートルでリターンする。nilならEmacsがその情報を取得できなかったことを意味する。

マルチモニターにセットアップされているグラフィカル端末では、displayに割り当てられたすべての物理モニターのピクセル幅を参照することに注意。複数の端末を参照のこと。

Function: display-mm-width &optional display

この関数はスクリーンの幅をミリメートルでリターンする。nilならEmacsがその情報を取得できなかったことを意味する。

マルチモニターにセットアップされているグラフィカル端末では、displayに割り当てられたすべての物理モニターのピクセル幅を参照することに注意。複数の端末を参照のこと。

User Option: display-mm-dimensions-alist

この変数はシステムの提供する値が不正な場合にdisplay-mm-heightdisplay-mm-widthがリターンするグラフィカルなディスプレイのサイズをユーザーが指定できるようにする。

Function: display-backing-store &optional display

この関数はそのディスプレイのバッキングストアー(backing store)の能力をリターンする。バッキングストアーとは非露出ウィンドウ(およびウィンドウの一部)のピクセルを記録しておいて、露出時に素早く表示できるようにすることを意味する。

値はシンボルalwayswhen-mappednot-useful。特定の種類のディスプレイにたいしてこの問いが適用外の際には、この関数はnilをリターンすることもある。

Function: display-save-under &optional display

この関数はそのディスプレイがSaveUnder機能をサポートすれば非nilをリターンする。この機能はポップアップウィンドウに隠されるピクセルを保存して素早くポップダウンができるようにするために使用される。

Function: display-planes &optional display

この関数はそのディスプレイがサポートする平面数(number of planes)をリターンする。これは通常はピクセルごとのビット数(bits per pixel: 色深度[bpp])。ttyディスプレイではサポートされるカラー数の2進対数(log to base two)。

Function: display-visual-class &optional display

この関数はそのスクリーンのビジュアルクラスをリターンする。値はシンボルstatic-gray (カラー数変更不可の限定されたグレイ)、gray-scale (フルレンジのグレイ)、static-color (カラー数変更不可の限定されたカラー)、pseudo-color (限定されたカラー数のカラー)、true-color (フルレンジのカラー)、およびdirect-color (フルレンジのカラー)のいずれか。

Function: display-color-cells &optional display

この関数はそのスクリーンがサポートするカラーのセル数をリターンする。

以下の関数はEmacsが指定されたdisplayを表示する場所に使用されるウィンドウシステムの追加情報を取得します(関数名先頭のx-は歴史的理由による)。

Function: x-server-version &optional display

この関数はGNUおよびUnixシステム上のXサーバーのような、display上で実行されているGUIウィンドウシステムのバージョン番号のリストをリターンする。値は3つの整数からなるリストで、1つ目と2つ目の整数はそのプロトコルのメジャーバージョン番号とマイナーバージョン番号、3つ目の整数はウィンドウシステムソフトウェア自体のディストリビューター固有のリリース番号。GNUおよびUnixシステムでは、通常これらはXプロトコルのバージョン番号と、Xサーバーソフトウェアのディストリビューター固有のリリース番号。MS-WindowsではWidowsのOSバージョン番号。

Function: x-server-vendor &optional display

この関数はウィンドウシステムソフトウェアを提供するベンダー(文字列)をリターンする。GNUおよびUnixシステムでは、それが誰であれそのXサーバーを配布するベンダーを意味する。MS-WindowsではWidows OSのベンダーID文字列(Microsoft)。

X開発者がソフトウェア配布者を“vendors”とラベル付けしたことは、いかなるシステムも非商業的に開発および配布できないと彼らが誤って仮定したことを示している。


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

31 ポジション

位置(position)とは、バッファーのテキストの文字のインデックスです。より正確には、位置とは2つの文字間(または最初の文字の前か最後の文字の後)の箇所を識別して、与えられた位置の前あるいは後の文字のように表現することができます。しかし“ある位置にある文字”のように表現することもあり、その場合にはその位置の後にある文字を意味します。

位置は通常は1から始まる整数として表されますが、マーカー(markers)として表現することもできます。関数は引数に位置(整数)を期待しますが、代替としてマーカーも受け入れ、通常はそのマーカーが指すのがどのバッファーなのかは無視します。これらの関数はマーカーを整数に変換して、たとえそのマーカーが誤ったバッファーを指していたとしても、まるで引数として単にその整数が渡されたかのようにその整数を使用します。整数に変換できない場所を指すマーカーを整数のかわりに使用するとエラーとなります。マーカーを参照してください。

多くのカーソルモーションコマンドにより使用される関数を提供するフィールド(field)機能も参照してください(フィールドの定義と使用を参照)。


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

31.1 ポイント

ポイント(point)とは多くの編集コマンドにより使用されるバッファーの特別な位置のことです。これらのコマンドには自己挿入型のタイプ文字やテキスト挿入関数が含まれます。その他のコマンドは別の箇所でテキストの編集や挿入ができるようにポイントを移動します。

ポイントは他の位置と同様に特定の文字ではなく、2つの文字の間(または最初の文字の前か最後の文字の後)を指します。端末では通常はポイント直後の文字の上にカーソルを表示します。つまりポイントは実際はカーソルのある文字の前にあります。

ポイントの値は1より小さくなることはなく、そのバッファーのサイズに1を加えた値より大きくなることはありません。ナローイング(ナローイングを参照)が効力をもつ場合には、ポイントはそのバッファーのアクセス可能な範囲内(範囲の境界はバッファーの先頭か終端のいずれかの可能性がある)に拘束されます。

バッファーはそれぞれ自身のポイント値をもち、それは他のバッファーのポイント値とは無関係です。ウィンドウもそれぞれポイント値をもち、他のウィンドウ内の同じバッファー上のポイント値とは無関係です。同じバッファーを表示する種々のウィンドウが異なるポイント値をもてるのはこれが理由です。あるバッファーがただ1つのウィンドウに表示されているときは、そのバッファーのポイントとそのウィンドウのポイントは通常は同じ値をもち、区別が重要になることは稀です。詳細はウィンドウとポイントを参照してください。

Function: point

この関数はカレントバッファー内のポイントの値を整数でリターンする。

(point)
     ⇒ 175
Function: point-min

この関数はカレントバッファー内のアクセス可能なポイントの最小値をリターンする。これは通常は1だがナローイングが効力をもつ場合は、ナローイングしたリージョンの開始位置となる(ナローイングを参照)。

Function: point-max

この関数はカレントバッファー内のアクセス可能なポイントの最大値をリターンする。これはナローイングされていなければは(1+ (buffer-size))だが、ナローイングが効力をもつ場合は、ナローイングしたリージョンの終端位置となる(ナローイングを参照)。

Function: buffer-end flag

この関数はflagが0より大なら(point-max)、それ以外は(point-min)をリターンする。引数flagは数値でなければならない。

Function: buffer-size &optional buffer

この関数はカレントバッファー内の文字数のトータルをリターンする。ナローイング(ナローイングを参照)されていなければ、point-maxはこれに1を加えた値をリターンする。

bufferにバッファーを指定すると値はbufferのサイズになる。

(buffer-size)
     ⇒ 35
(point-max)
     ⇒ 36

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

31.2 モーション

モーション関数はポイントのカレント値、バッファーの先頭か終端、または選択されたウィンドウ端のいずれかより相対的にポイントの値を変更します。ポイントを参照してください。


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

31.2.1 文字単位の移動

以下の関数は文字数にもとづいてポイントを移動します。 goto-charは基本的なプリミティブであり、その他の関数はこれを使用しています。

Command: goto-char position

この関数はカレントバッファー内のポイントの値をpositionにセットする。

ナローイングが効力をもつ場合でもpositionは依然としてバッファー先頭から数えられるが、ポイントをアクセス可能な範囲外に移動することはできない。positionが範囲外なら、goto-charはアクセス可能な範囲の先頭または終端にポイントを移動する。

この関数がインタラクティブに呼び出された際は、positionの値は数プレフィクス引数、プレフィクス引数が与えられなかった場合はミニバッファーから値を読み取る。

goto-charpositionをリターンする。

Command: forward-char &optional count

この関数は前方、すなわちバッファーの終端方向にポイントをcount文字移動する(countが負なら後方、すなわちバッファーの先頭方向にポイントを移動する)。countnilの場合のデフォルトは1。

バッファー(ナローイングが効力をもつ場合はアクセス可能な範囲の境界)の先頭か終端を超えて移動を試みるとエラーシンボルbeginning-of-bufferend-of-bufferのエラーをシグナルする。

インタラクティブな呼び出しでは数プレフィクス引数がcountとなる。

Command: backward-char &optional count

移動方向が逆であることを除いて、これはforward-charと同様。


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

31.2.2 単語単位の移動

以下で説明する単語をパースする関数は、与えられた文字が単語の一部かどうかを判断するために構文テーブルとchar-script-tableを使用します。構文テーブル文字のプロパティを参照してください。

Command: forward-word &optional count

この関数はcountの単語数分ポイントを前方に移動する。(countが負なら後方に移動する)。countが省略またはnilの場合のデフォルトは1。インタラクティブな呼び出しでは、countは数プレフィクス引数により指定される。

“単語1つ移動”とは単語構成文字を横断(これは単語の先頭を示す)して単語の終わりまで移動を継続することを意味する。デフォルトでは単語を開始や終了させる文字は単語境界(word boundaries)として知られており、これはカレントバッファーの構文テーブル(構文クラスのテーブルを参照)で定義されるが、後述のfind-word-boundary-function-tableを適切にセットすることによりモードはこれをオーバーライドできる。(char-script-tableにより定義される)異なるスクリプトに属する文字も単語境界を定義できる(文字のプロパティを参照)。いずれにせよ、この関数はバッファーのアクセス可能範囲の境界やフィールド境界(フィールドの定義と使用を参照)を超えてポイントを移動できない。フィールド境界のもっとも一般的な例はミニバッファー内のプロンプト終端である。

バッファー境界やフィールド境界により途中で停止することなく単語count個分の移動が可能なら値はtとなる。それ以外ではリターン値はnilとなり、ポイントはバッファー境界またはフィールド境界で停止する。

inhibit-field-text-motionが非nilなら、この関数はフィールド境界を無視する。

Command: backward-word &optional count

この関数は単語の前に遭遇するまで前方ではなく後方に移動することを除いてforward-wordと同様。

User Option: words-include-escapes

この変数は、forward-wordbackward-word、およびそれらを使用するすべての関数の挙動に影響する。これが非nilなら、構文クラスescapeとcharacter-quote内の文字は単語の一部とみなされる。それ以外なら単語の一部とはみなされない。

Variable: inhibit-field-text-motion

この変数が非nilならforward-wordforward-sentenceforward-paragraphを含む特定のモーション関数はフィールド境界を無視する。

Variable: find-word-boundary-function-table

この変数はforward-wordbackward-word、およびそれらを使用するすべての挙動に影響する。値は単語境界を検索するための関数の文字テーブル(文字テーブルを参照)。このテーブル内である文字が非nilのエントリーをもつ場合には、単語がその文字で開始または終了する際に対応する関数が2つの引数poslimitで呼び出される。この関数は別の単語境界の位置をリターンすること。具体的には、poslimitより小さければposは単語の先頭にあり関数はその単語の最後の文字の後の位置、それ以外ならposは単語の最後の文字にあり関数はその単語の最初の文字の位置をリターンすること。

Function: forward-word-strictly &optional count

この関数はforward-wordと同様だがfind-word-boundary-function-tableによる影響を受けない点が異なる。このテーブルをセットするsubword-modeのようなモードにより単語単位の移動が変更されている際に挙動を変えるべきではないLispプログラムは、forward-wordのかわりにこの関数を使用すること。

Function: backward-word-strictly &optional count

この関数はbackward-wordと同様だが、find-word-boundary-function-tableの影響を受けない点が異なる。forward-word-strictlyと同様に、構文テーブルだけを考慮して単語単位の移動を行う必要がある際には、backward-wordのかわりにこの関数を使用すること。


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

31.2.3 バッファー終端への移動

バッファーの先頭にポイントを移動するには以下のように記述します:

(goto-char (point-min))

同様にバッファーの終端に移動するには以下を使用します:

(goto-char (point-max))

以下の2つのコマンドは、ユーザーがこれらを行うためのコマンドです。これらはマークをセットしてメッセージをエコーエリアに表示するため、Lispプログラム内で使用しないよう警告するためにここに記述します。

Command: beginning-of-buffer &optional n

この関数はバッファー(ナローイングが効力をもつ場合はアクセス可能範囲の境界)の先頭にポイントを移動して、以前の位置にマークをセットする(Transient Markモードの場合にはマークがすでにアクティブならマークはセットしない)。

nが非nilならバッファーのアクセス可能範囲の先頭からn/10の位置にポイントを配置する。インタラクティブな呼び出しではnは数プレフィクス引数が与えられればその値、それ以外でのデフォルトはnil

警告: この関数をLispプログラム内で使用してはならない。

Command: end-of-buffer &optional n

この関数はバッファー(ナローイングが効力をもつ場合はアクセス可能範囲の境界)の終端にポイントを移動して、以前の位置にマークをセットする(Transient Markモードの場合にはマークがすでにアクティブならマークはセットしない)。nが非nilならバッファーのアクセス可能範囲の終端からn/10の位置にポイントを配置する。

インタラクティブな呼び出しではnは数プレフィクス引数が与えられればその値、それ以外でのデフォルトはnil

警告: この関数をLispプログラム内で使用してはならない。


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

31.2.4 テキスト行単位の移動

テキスト行とは改行で区切られたバッファーの範囲です。改行は前の行の一部とみなされます。最初のテキスト行はバッファー先頭で始まり、最後のテキスト行は最後の文字が改行かどうかは関係なくバッファー終端で終わります。バッファーからテキスト行への分割はそのウィンドウの幅、表示の行継続、タブやその他の制御文字の表示方法に影響されません。

Command: beginning-of-line &optional count

この関数はカレント行の先頭にポイントを移動する。引数countが非nilまたは1以外なら前方にcount-1行移動してから、その行の先頭に移動する。

この関数は別の行に移動する場合を除いてフィールド境界(フィールドの定義と使用を参照)を超えてポイントを移動しない。したがってcountnilか1で、かつポイントがフィールド境界で開始される場合にはポイントを移動しない。フィールド境界を無視させるにはinhibit-field-text-motiontにバインドするか、かわりにforward-line関数を使用する。たとえばフィールド境界を無視することを除けば、(forward-line 0)(beginning-of-line)と同じことを行う。

この関数がバッファー(ナローイングが効力をもつ場合はアクセス可能範囲)の終端に到達したらポイントをその位置に配置する。エラーはシグナルされない。

Function: line-beginning-position &optional count

(beginning-of-line count)が移動するであろう位置をリターンする。

Command: end-of-line &optional count

この関数は、カレント行の終端にポイントを移動する。引数countが非nilまたは1以外なら前方にcount-1行移動してから、その行の終端に移動する。

この関数は別の行に移動する場合を除いてフィールド境界(フィールドの定義と使用を参照)を超えてポイントを移動しない。したがってcountnilまたは1で、かつポイントがフィールド境界で開始される場合にはポイントを移動しない。フィールド境界を無視させるにはinhibit-field-text-motiontにバインドする。

この関数がバッファー(ナローイングが効力をもつ場合はアクセス可能範囲)の終端に到達したらポイントをその位置に配置する。エラーはシグナルされない。

Function: line-end-position &optional count

(end-of-line count)が移動するであろう位置をリターンする。

Function: pos-bol &optional count

line-beginning-positionと似ているがフィールドを無視する(そしてより効率的である)。

Function: pos-eol &optional count

line-end-positionと似ているがフィールドを無視する(そしてより効率的である)。

Command: forward-line &optional count

この関数は後続行へ前方にcount行移動して、その行の先頭にポイントを移動する。countが負なら先行行へ後方に-count行移動して、その行の先頭にポイントを移動する。countが0ならカレント行の先頭にポイントを移動する。countnilならそれは1を意味する。

forward-lineが指定された行数を移動する前にバッファー(またはアクセス可能範囲)の先頭か終端に遭遇したら、そこにポイントをセットする。エラーはシグナルされない。

forward-linecountと実際に移動した行数の差をリターンする。3行しかないバッファーの先頭から5行下方への移動を試みると、ポイントは最終行の終端で停止して値は2となるだろう。明示的な例外としてアクセス可能な最終行が空ではなく改行がなければ(バッファーが改行で終わらない場合)、この関数はその行の終端にポイントをセットして、この関数がリターンする値はその行を移動に成功した1行として計数する。

インタラクティブな呼び出しでは数プレフィクス引数がcountとなる。

Function: count-lines start end &optional ignore-invisible-lines

この関数はカレントバッファー内の位置startendの間の行数をリターンする。startendが等しければリターン値は0。それ以外は、たとえstartendが同一行にあっても最小でも1をリターンする。これらの間にあるテキストは、それだけを孤立して考えたると、それが空でない限りは最小でも1行を含まなければならないからである。

オプションのignore-invisible-linesが非nilなら、不可視の行は行数に含まれない。

Command: count-words start end

この関数はカレントバッファー内の位置startendの間にある単語の数をリターンする。

この関数はインタラクティブに呼び出すこともできる。その場合はバッファー、またはリージョンがアクティブならリージョン内の行数、単語数、文字数を報告するメッセージをプリントする。

Function: line-number-at-pos &optional pos absolute

この関数はカレントバッファーのバッファー位置posに対応する行番号をリターンする。posnilか省略ならカレントのバッファー位置を使用する。absolutenil (デフォルト)なら(point-min)から数え始めるので、値は(ナローイングされているかもしれない)バッファーのアクセス可能範囲を参照する。absoluteが非nilならすべてのナローイングを無視して行の絶対番号をリターンする。

ポイント近傍のテキストを調べるの関数bolpeolpも参照してください。これらの関数はポイントを移動しませんが、ポイントがすでに行頭または行末にあるかどうかをテストします。


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

31.2.5 スクリーン行単位の移動

前のセクションの行関数は、改行文字で区切られたテキスト行だけを数えました。それらとは対照的に以下の関数はスクリーン行を数えます。スクリーン行はスクリーン上でテキストが表示される方法にしたがって定義されます。あるテキスト行1行が選択されたウィンドウの幅にフィット可能な程に十分短ければそれはスクリーン行で1行になりますが、それ以外は複数のスクリーン行になり得ます。

テキスト行が追加スクリーン行に継続されずに、そのスクリーンで切り詰められる(truncated)場合があります。そのような場合にはvertical-motionforward-lineのようにポイントを移動します。切り詰めを参照してください。

文字列が与えられると、その幅は文字の外見を制御するフラグに依存するために与えられたテキスト断片にたいして、たとえそれが選択されたウィンドウ上でさえも(幅、切り詰めの有無、ディスプレイテーブルはウィンドウごとに異なり得るので)、そのテキストがあるバッファーに応じてvertical-motionの挙動は異なります。通常の表示の慣習を参照してください。

以下の関数はスクリーン行のブレーク位置を判断するためにテキストをスキャンするために、スキャンする長さに比例して時間を要します。

Function: vertical-motion count &optional window cur-col

この関数はポイントのあるスクリーン行からスクリーン行でcount行下方に移動して、そのスクリーン行の先頭にポイントを移動する。countが負ならかわりに上方に移動する。countが0の場合には、カレントスクリーン行の視覚的な先頭にポイントを移動する。

count引数には整数のかわりにコンスセル(cols . lines)を指定できる。その場合には関数はcountで上述したように、スクリーン行でlines行移動して、そのスクリーン行の視覚的な行頭(visual start)からcols列目にポイントを配置する。colsの値は浮動小数点数でもよく、この場合にはそのフレームの正規文字幅(フレームのフォントを参照)の単位として解釈される。これにより目標となるスクリーン行で可変幅フォントが使用されている際に、正確な水平位置を指定することが可能になる。colsはその行の視覚的(visual)な開始から数えられることに注意。そのウィンドウが水平スクロール(水平スクロールを参照)されていれば、ポイントが配置される列は、スクロールされたテキストの列数が加えられるだろう。更に目標となる行が継続行の場合には一番左の列を列0とみなす(列指向の関数とは異なる; 列を数えるを参照)。

リターン値はポイントが移動したスクリーン行の行数。バッファーの先頭か終端に到達していたら、この値は絶対値ではcountより小になるかもしれない。

ウィンドウwindowは幅、水平スクロール、ディスプレイテーブルのようなパラメーターの取得に使用される。しかしvertical-motionは、たとえwindowがカレントで他のバッファーを表示していたとしても、常にカレントバッファーにたいして処理を行う。

オプション引数cur-colは関数呼び出し時のカレント列を指定する。これはフレームのデフォルトフェイスのフォント幅の単位で計測したウィンドウに相対的なポイントの水平座標である。これを提供することにより関数はカレント列を判断するためにバッファーを戻る必要がなくなるので、特に長い行において関数が高速化される。cur-colは行のビジュアル的な開始からも計測されることに注意。

Function: count-screen-lines &optional beg end count-final-newline window

この関数はbegからendのテキスト内のスクリーン行の行数をリターンする。スクリーン行数は行継続やディスプレイテーブル等により実際の行数とは異なるかもしれない。begendnil、または省略された場合のデフォルトは、そのバッファーのアクセス可能範囲の先頭と終端。

そのリージョンが改行で終わる場合には、オプションの第3引数count-final-newlinenilならそれは無視される。

オプションの第4引数windowは幅や水平スクロール等のパラメーターを取得するウィンドウを指定する。デフォルトは選択されたウィンドウのパラメーターを使用する。

vertical-motionと同じうように、count-screen-lineswindow内にどのバッファーが表示されていようと常にカレントバッファーを使用する。これによりバッファーが何らかのウィンドウにカレントで表示されているか否かにかかわらず、任意にバッファーにたいしてcount-screen-linesの使用が可能になる。

Command: move-to-window-line count

この関数は選択されたウィンドウ内にカレントで表示されているテキストに応じてポイントを移動する。これはウィンドウ上端からスクリーン行でcount行目(0は最上行を意味する)の先頭にポイントを移動する。countが負ならバッファー下端(バッファーが指定されたスクリーン位置の上で終わる場合にはバッファーの最終行)から-count行目の位置を指定する。したがってcountが-1ならウィンドウの最後の完全に可視なスクリーン行を指定する。

countnilならポイントはウィンドウ中央の行の先頭に移動する。countの絶対値がウィンドウサイズより大の場合には、ウィンドウが十分に高かったらそのスクリーン行は表示されていたであろう位置にポイントを移動する。これはおそらく次回の再表示の際に、その箇所がスクリーン上になるようなスクロールを発生させるだろう。

インタラクティブな呼び出しでは数プレフィクス引数がcountとなる。

リターン値はポイントが移動した先の、ウィンドウ上端行から相対的なスクリーン行番号。

Function: move-to-window-group-line count

この関数はmove-to-window-lineと同様だが、選択されたウィンドウがウィンドウグループ(Window Groupを参照)の一部なら、move-to-window-group-lineは単一のウィンドウではなくグループ全体にたいする位置に移動する。この条件はバッファーローカル変数move-to-window-group-line-functionに関数がセットされている際に保持される。この場合にはmove-to-window-group-lineは引数countでその関数を呼び出して、その結果をリターンする。

Function: compute-motion from frompos to topos width offsets window

この関数はカレントバッファーをスキャンしてスクリーン位置を計算する。これは位置fromがスクリーン座標fromposにあると仮定して、そこから位置toまたは座標toposのいずれか先に到達したほうまでバッファーを前方にスキャンする。これはスキャン終了のバッファー位置とスクリーン座標をリターンする。

座標引数frompostoposは、(hpos . vpos)という形式のコンスセル。

引数widthはテキストを表示するために利用可能な列数。これは継続行の処理に影響する。nilはそのウィンドウ内で使用可能な実際のテキスト列数であり、(window-width window)がリターンする値と等しい。

引数offsetsnil、または(hscroll . tab-offset)という形式のコンスセルのいずれかであること。ここでhscrollは左マージンのために表示されない列数であり、呼び出し側のほとんどはwindow-hscrollを呼び出すことによりこれを取得する。一方tab-offsetはスクリーン上の列数とバッファー内の列数の間のオフセットである。これは継続行において前のスクリーン行の幅がtab-widthの整数倍でないときは非0になる可能性がある。非継続行ではこれは常に0。

ウィンドウwindowの唯一の役割は使用するディスプレイテーブルの指定である。compute-motionwindow内に表示されているのがどのバッファーであろうとカレントバッファーを処理する。

リターン値は5つの要素をもつリストである:

(pos hpos vpos prevhpos contin)

ここでposはスキャンが停止したバッファー位置、vposは垂直スクリーン位置、hposは水平スクリーン位置である。

結果のprevhposposから1文字戻った水平位置、continは最後の行が前の文字の後(または中)から継続されていればtとなる。

たとえばあるウィンドウのスクリーン行lineの列colのバッファー位置を求めるには、そのウィンドウのdisplay-start(表示開始)位置をfrom、そのウィンドウの左上隅の座標をfromposとして渡す。スキャンをそのバッファーのアクセス可能範囲の終端に制限するために、バッファーの(point-max)tolinecoltoposに渡す。以下はこれを行う関数:

(defun coordinates-of-position (col line)
  (car (compute-motion (window-start)
                       '(0 . 0)
                       (point-max)
                       (cons col line)
                       (window-width)
                       (cons (window-hscroll) 0)
                       (selected-window))))

ミニバッファーにたいしてcompute-motionを使う際には、最初のスクリーン行の先頭の水平位置を取得するためにminibuffer-prompt-widthを使用する必要がある。


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

31.2.6 釣り合いのとれたカッコを越えた移動

以下は釣り合いの取れたカッコ式(balanced-parenthesis。これらの式を横断して移動することと関連してEmacsではsexp(S式)とも呼ばれる)と関係のあるいくつかの関数です。これらの関数がさまざまな文字を処理する方法は構文テーブル(syntax table)が制御します。構文テーブルを参照してください。sexpやその一部にたいする低レベルのプリミティブについては式のパースを参照してください。ユーザーレベルのコマンドについてはCommands for Editing with Parentheses in The GNU Emacs Manualを参照してください。

Command: forward-list &optional arg

この関数は釣り合いの取れたカッコのグループをarg (デフォルトは1)グループ前方に移動する(単語やクォート文字のペアーでクォートされた文字列は無視される)。

Command: backward-list &optional arg

この関数は釣り合いの取れたカッコのグループをarg (デフォルトは1)グループ後方に移動する(単語やクォート文字のペアーでクォートされた文字列は無視される)。

Command: up-list &optional arg escape-strings no-syntax-crossing

この関数はarg (デフォルトは1)の外側のカッコへ前方に移動する。負の引数では後方へ移動するが、それでもより浅いスポットへと移動する。 escape-stringsが非nil (インタラクティブ時が該当)なら、取り囲まれた文字列の外側にも同様に移動する。no-syntax-crossingが非nil (インタラクティブ時が該当)なら、複数の文字列を横断してリスト先頭に移動するかわりに、取り囲む文字列から脱け出すことを優先する。エラー時にはポイントの位置は未定義。

Command: backward-up-list &optional arg escape-strings no-syntax-crossing

この関数はup-listとど同様だが引数の正負が逆。

Command: down-list &optional arg

この関数はカッコをarg (デフォルトは1)レベル内側、前方に移動する。負の引数では後方に移動するが、それでも深いレベル(-argレベル)に移動する。

Command: forward-sexp &optional arg

この関数は釣り合いの取れた式(balanced expressions)をarg (デフォルトは1)前方に移動する。釣り合いの取れた式にはカッコ等で区切られた式、および単語や文字列定数のようなものも含まれる。式のパースを参照のこと。たとえば、

---------- Buffer: foo ----------
(concat∗ "foo " (car x) y z)
---------- Buffer: foo ----------

(forward-sexp 3)
     ⇒ nil

---------- Buffer: foo ----------
(concat "foo " (car x) y∗ z)
---------- Buffer: foo ----------
Command: backward-sexp &optional arg

この関数は釣り合いの取れた式(balanced expressions)を、arg (デフォルトは1)後方に移動する。

Command: beginning-of-defun &optional arg

この関数は後方にarg番目のdefunの先頭に移動する。argが負なら実際には前方に移動するが、defunの終端ではなく先頭に移動することは変わらない。argのデフォルトは1。

Command: end-of-defun &optional arg

この関数は前方にarg番目のdefunの終端に移動する。argが負なら実際には後方に移動するが、defunの先頭ではなく終端に移動することは変わらない。argのデフォルトは1。

User Option: defun-prompt-regexp

このバッファーローカル変数は非nilならdefunの始まりとなる開きカッコの前に出現し得るテキストを指定する正規表現を保持する。つまりこの正規表現にたいするマッチで始まり、その後に開きカッコ構文(open-parenthesis syntax)が続くものがdefunである。

User Option: open-paren-in-column-0-is-defun-start

この変数の値が非nilなら列0にある開きカッコはdefunの始まりとみなされる。nilなら列0の開きカッコは特別な意味をもたない。デフォルトはt。リテラル文字列の列0にカッコがあるような場合には偽陽性を回避するためにバックスラッシュでエスケープすること。

Variable: beginning-of-defun-function

この変数は非nilならdefunの開始を見つける関数を保持する。関数beginning-of-defunは通常の手法を使うかわりに、この関数に自身のオプション引数を渡して呼び出す。引数が非nilなら、その関数はその回数分の関数呼び出しによってbeginning-of-defunが行うように後方に移動すること。

Variable: end-of-defun-function

この変数は非nilならdefunの終端を見つける関数を保持する。関数end-of-defunは、通常の手法を使うかわりにその関数を呼び出す。

tree-sitterとともにEmacsがビルドされていれば、構文構造(syntax construct)を横断して移動するためにtree-sitterのパーサー情報を使うことができます。正確に何がdefunとみなされるかは言語によってさまざまなので、それを判断するためにメジャーモードはtreesit-defun-type-regexpをセットする必要があります。そうすればtreesit-beginning-of-defuntreesit-end-of-defunを使うことによって、モードはdefun単位でのナビゲーション機能を労せず手に入れられるのです。

Variable: treesit-defun-type-regexp

この変数はEmacsがどのノードをdefunとみなすかを決定する。defunノードのタイプにマッチするregexpを指定できる(“ノード”および “ノードタイプ”についてはプログラムソースの解析を参照)。

たとえばpython-modeはこの変数に‘function_definition’か‘class_definition’のいずれかにマッチするregexpをセットする。

このregexpによってマッチしたノードすべてが有効なdefunという訳ではないときもある。したがってこの変数の値は(regexp . pred)という形式のコンスセルでもよい。ここでpredはノードを引数として受け取りそのノードが有効なdefunであれば非nil、有効でなければnilをリターンする関数であること。

Variable: treesit-defun-tactic

この変数はEmacsがどのようにネスト(nest: 入れ子)されたdefunを扱うかを決定する。値がtop-levelなら、ナビゲーション関数はトップレベルのdefun間だけを移動、nestedならナビゲーション関数はネストされたdefunを認識する。


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

31.2.7 文字のスキップ

以下の2つの関数は指定された文字セットを超えてポイントを移動します。これらの関数は、たとえば空白文字をスキップするためによく使用されます。関連する関数についてはモーションと構文を参照してください。

これらの関数は検索関数(検索とマッチングを参照)が行うように、そのバッファーがマルチバイト(multibyte)ならマルチバイトに、ユニバイト(unibyte)ならユニバイトにその文字列セットを変換します。

Function: skip-chars-forward character-set &optional limit

この関数は与えられた文字セットをスキップしてカレントバッファー内のポイント前方に移動する。これはポイントの後の文字を調べて、その文字がcharacter-setにマッチすればポイントを進める。そしてマッチしない文字に到達するまでこれを継続する。この関数は飛び超えて移動した文字数をリターンする。

引数character-setが正規表現での‘[…]’内部と同じだが、‘]’で終端されず‘\’が‘^’、‘-’、‘\’をクォートする点が異なる。つまり"a-zA-Z"はすべての英字をスキップして最初の非英字の前で停止して、"^a-zA-Z"はすべての非英字をスキップして最初の英字の前で停止する(正規表現を参照)"[:alnum:]"のような文字クラスも使用できる(文字クラスを参照)。

limit (数字かマーカー)が与えられたら、それはポイントがスキップして到達できるそのバッファー内の最大位置を指定する。ポイントはlimit、またはlimitの前でストップするだろう。

以下の例ではポイントは最初‘T’の直前に置かれている。フォーム評価後にポイントはその行の末尾( ‘hat’の‘t’と改行の間)に配置される。この関数はすべての英字とスペースをスキップするが改行はスキップしない。

---------- Buffer: foo ----------
I read "∗The cat in the hat
comes back" twice.
---------- Buffer: foo ----------

(skip-chars-forward "a-zA-Z ")
     ⇒ 18

---------- Buffer: foo ----------
I read "The cat in the hat∗
comes back" twice.
---------- Buffer: foo ----------
Function: skip-chars-backward character-set &optional limit

この関数はlimitに至るまでcharacter-setにマッチする文字をスキップしてポイントを後方に移動する。これはskip-chars-forwardと同様だがポイントを移動する方向が異なる。

リターン値は移動した距離を示す。これは0以上の整数。


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

31.3 エクスカーション

プログラム中の限定された部分でポイントを一時的に移動するのが便利なことが時折あります。これはエクスカーション(excursion: 遠足、小旅行)と呼ばれるもので、スペシャルフォームsave-excursionにより行われます。この構文は初期のカレントバッファー自体とポイントの値を記憶して、そのエクスカーション完了時にそれらをリストアします。これはプログラムのある部分においてプログラムの他の部分に影響を与えることなくポイントを移動する標準的な手段であり、EmacsのLispソース内では何度も使用されています。

カレントバッファー自体のみの保存やリストアが必要なら、かわりにsave-current-bufferwith-current-bufferを使用してください(カレントバッファーを参照)。ウィンドウ構成の保存やリストアが必要なら、ウィンドウの構成フレーム構成で説明されているフォームを参照してください。

Special Form: save-excursion body…

このスペシャルフォームはカレントバッファー自体とポイント値を保存、bodyを評価してから最後にバッファーと保存したポイントとマークの値をリストアする。throwやエラーを通じたアブノーマルexit(非ローカル脱出を参照)の場合にも、保存されたいずれの値もリストアされる。

save-excursionがリターンする値はbody内の最後のフォームの結果、またはbodyフォームが与えられなければnilをリターンする。

save-excursionはエクスカーション開始時にカレントだったバッファーのポイントだけを保存するために、そのエクスカーション中に変更された他のバッファーのポインはその後も効果が残るでしょう。これはしばしば予期せぬ結果を招くので、エクスカーション中にset-bufferを呼び出すとバイトコンパイラーは警告を発します:

Warning: Use ‘with-current-buffer’ rather than
         save-excursion+set-buffer

このような問題を回避するためには、以下の例のように望むカレントバッファーをセット後にのみsave-excursionを呼び出すべきです:

(defun append-string-to-buffer (string buffer)
  "BUFFER末尾にSTRINGを追加"
  (with-current-buffer buffer
    (save-excursion
      (goto-char (point-max))
      (insert string))))

同様にsave-excursionswitch-to-bufferのような関数が変更したウィンドウ/バッファーの対応をリストアしません。

警告: 保存されたポイント値に隣接する通常のテキスト挿入は、それがすべてのマーカーを再配置するのと同じように、保存されたポイントカーを再配置します。より正確には保存される値は挿入タイプnilのマーカーです。マーカーの挿入タイプを参照してください。したがって保存されたポイント値は、リストア時には通常は挿入されたテキストの直前になります。

Macro: save-mark-and-excursion body…

このマクロはsave-excursionと同様だが、マークの位置とmark-activeの保存とリストアも行う点が異なる。このマクロはEmacsのバージョン25.1以前にsave-excursionが行っていたことを行う。


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

31.4 ナローイング

ナローイング(narrowing)とはEmacs編集コマンドがアドレス指定可能なテキストを、あるバッファー内の制限された文字範囲に限定することを意味します。アドレス可能なテキストは、そのバッファーのアクセス可能範囲(accessible portion)と呼ばれます。

ナローイングは2つのバッファー位置により指定されるもので、それらの位置がアクセス可能範囲の開始と終了になります。ほとんどの編集コマンドやプリミティブにたいして、これらの位置はそれぞれそのバッファーの先頭と終端に置き換えられます。ナローイングが効果をもつ間にはアクセス可能範囲外のテキストは表示されず、その外部にポイントを移動することはできません。ナローイングは実際のバッファー位置(ポイントを参照)を変更しないことに注意してください。ほとんどの関数はアクセス可能範囲外のテキストにたいする操作を受け入れません。

バッファーを保存するコマンドはナローイングの影響を受けません。どんなナローイングであろうと、それらはバッファー全体を保存します。

単一バッファー内にタイプが大きく異なるテキストを複数表示する必要がある場合には、2つのバッファー間でのテキストの交換で説明する代替機能の使用を考慮してください。

Command: narrow-to-region start end

この関数はアクセス可能範囲の開始と終了にカレントバッファーのstartendをセットする。どちらの引数も文字位置で指定すること。

インタラクティブな呼び出しでは、startendはカレントリージョンにセットされる(ポイントとマークで小さいほうが前者)。

ただしlabel引数(以下参照)を指定したwith-restrictionによってナローイングがセットされている際には、そのナローイングの制限の範囲内にたいしてのみnarrow-to-regionを使用できる。startendがこの制限の範囲外であれば、with-restrictionによってセットされた対応する制限がかわりに使用される。バッファーのそれ以外の部分へのアクセスを取得するには、同じlabelを指定してwithout-restrictionを使えばよい。

Command: narrow-to-page &optional move-count

この関数はカレントページだけを含むようにカレントバッファーのアクセス可能範囲をセットする。1つ目のオプション引数move-countが非nilなら、move-countで前方か後方へ移動後に1ページにナローすることを意味する。変数page-delimiterはページの開始と終了の位置を指定する(編集で使用される標準的な正規表現を参照)。

インタラクティブな呼び出しではmove-countには数プレフィクス引数がセットされる。

Command: widen

この関数はカレントバッファーにたいするすべてのナローイングをキャンセルする。これはワイドニング(widening)と呼ばれる。これは以下の式と等価:

(narrow-to-region 1 (1+ (buffer-size)))

ただしlabel引数(以下参照)を指定したwith-restrictionによってナローイングがセットされている際には、ナローイングをキャンセルするかわりにwith-restrictionでセットした制限がリストアされる。バッファーのそれ以外の部分へのアクセスを取得するには、同じlabelを指定してwithout-restrictionを使えばよい。

Function: buffer-narrowed-p

この関数はそのバッファーがナローされていれば非nil、それ以外はnilをリターンする。

Special Form: save-restriction body…

このスペシャルフォームはアクセス可能範囲のカレントのバインドを保存してbodyを評価、その後に以前有効だったナローイング(またはナローイングがない状態)と同じ状態になるように、最後に保存された境界をリストアする。ナローイングの状態は、throwやエラーを通じたアブノーマルexit(非ローカル脱出を参照)イベント内においてもリストアされる。したがってこの構文は一時的にバッファーをナローする明快な手段である。

この構文はlabel引数(以下参照)とともにwith-restrictionによってセットされたナローイングの保存とリストアも行う。

save-restrictionがリターンする値はbody内の最後のフォームのリターン値、bodyフォームが与えられなければnil

注意: save-restriction使用の際は間違いを起こしやすい。これを試みる前にこの説明全体に目を通すこと。

bodyがカレントバッファーを変更する場合でもsave-restrictionは依然として元のバッファー(その制限が保存されたバッファー)上の制限をリストアするが、カレントバッファー自体はリストアしない。

save-restrictionはポイントをリストアしない。これを行うにはsave-excursionを使用する。save-restrictionsave-excursionの両方を共に使用するなら、始め(外側)にsave-excursionを記述すること。それ以外では一時的なナローイング影響下で古いポイント値がリストアされる。古いポイント値が一時的なナローイング境界外なら、それを実際にリストアすることは失敗するだろう。

以下はsave-restrictionの正しい使い方の簡単な例:

---------- Buffer: foo ----------
This is the contents of foo
This is the contents of foo
This is the contents of foo∗
---------- Buffer: foo ----------

(save-excursion
  (save-restriction
    (goto-char 1)
    (forward-line 2)
    (narrow-to-region 1 (point))
    (goto-char (point-min))
    (replace-string "foo" "bar")))

---------- Buffer: foo ----------
This is the contents of bar
This is the contents of bar
This is the contents of foo∗
---------- Buffer: foo ----------
Special Form: with-restriction start end [:label label] body

このスペシャルフォームはバッファーのアクセス可能範囲のカレント境界を保存、startで始まりendで終わるアクセス可能範囲をセットしてbodyフォームを評価、それから保存してある境界をリストアする。この場合は以下と等しい

(save-restriction
  (narrow-to-region start end)
  body)

オプション引数label (使用するラベルを取得するために評価される; 非nil値が生成されなければならない)が与えられた場合には、そのナローイングはラベル付け(labeled)される。ラベル付けされたナローイングは、ラベル付けされていないナローイングといくつかの点で異なる:

  • bodyフォームの評価の間は、narrow-to-regionwidenが使えるのはstartからendまでの制限の内部のみ。
  • with-restrictionでセットされた制限を解除してバッファーの他の部分へのアクセスを取得するためには、同じlabel引数を使ってwithout-restrictionを呼び出す(バッファーの他の部分へのアクセスを取得する別の方法としてインダイレクトバッファーの使用がある; インダイレクトバッファーを参照)。
  • ラベル付けされたナローイングはネストできる。
  • ラベル付けされたナローイングはLispプログラムでのみ使用できる。このナローイングは表示上で可視になることはなく、ユーザーがセットしたナローイングに干渉することもない。

オプション引数labelとともにwith-restrictionを使う場合には、あなたのコードを呼び出す他のLispプログラムが必要に応じてナローイングを解除できるように、これを使う関数のdoc文字列でそのlabelのドキュメントを記述することを推奨する。

Special Form: without-restriction [:label label] body

このスペシャルフォームはバッファーのアクセス可能範囲のカレント境界を保存、そのバッファーをワイドニングしてからbodyフォームを評価、それから保存した境界をリストアする。この場合は以下と等しい

(save-restriction
  (widen)
  body)

オプション引数labelが与えられた場合には、同じlabel引数のwith-restrictionでセットされたナローイングが解除される。


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

32 マーカー

マーカー(marker)とは、あるバッファー内で取り囲んでいるテキストにたいして相対的な位置を指定するために使用されるオブジェクトです。テキストが挿入や削除される際には、常にマーカーは自動的にそのバッファーの先頭からのオフセットを自動的に変更して自身の左右にある文字の間に留まります。


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

32.1 マーカーの概要

マーカーはバッファーとそのバッファー内の位置を指定します。マーカーは位置を要求する関数内において、整数と同じように位置を表すために使用することができます。その場合には、そのマーカーのバッファーは通常は無視されます。この方法で使用されるマーカーは、通常はその関数が処理するバッファー内の位置を指しますが、それは完全にプログラマーの責任です。位置についての完全な説明はポジションを参照してください。

マーカーはマーカー位置(marker position)、マーカーバッファー(marker buffer)、挿入タイプ(insertion type)という3つの属性をもちます。マーカー位置はそのバッファー内の位置としてのマーカーと(その時点において)等しい整数です。しかしマーカー位置はマーカーの生存期間中に変化し得るものであり頻繁に変更されます。バッファー内でのテキストの挿入や削除によってマーカーは再配置されます。マーカー前後の2文字以外の場所で挿入や削除がおこなわれても、マーカー位置はその2文字間に留まるというのがこのアイデアです。再配置によってマーカーと等価な整数は変更されます。

マーカー位置周辺のテキストを削除することにより、そのマーカーは削除されたテキストの直前と直後にある文字の間に残されます。マーカー位置へのテキスト挿入では、マーカーは通常は新たなテキストの前か後のいずれかに配置されます。その挿入がinsert-before-markers (テキストの挿入を参照)で行われたものでなければ、どちらに配置されるかはマーカーの挿入タイプ(マーカーの挿入タイプを参照)に依存します。

バッファーでの挿入と削除では、すべてのマーカーをチェックして必要ならそれらを再配置しなければなりません。これは多数のマーカーをもつバッファーでの処理を低速にします。この理由によりそれ以上マーカーが不必要なことが確信できるなら、存在しない場所を指さないようにマーカーを設定することはよいアイデアといえるでしょう。それ以上アクセスされる可能性がないマーカーは最終的には削除されます(ガーベージコレクションを参照)。

マーカー位置にたいして算術演算を行うことは一般的なので、それらの演算子のほとんど(+-を含む)が引数としてマーカーに渡すことができます。そのような場合でのマーカーはカレント位置を意味します。

以下ではマーカーの作成とセットを行ってポイントをマーカーに移動しています:

;; 最初はどこも指さない新たなマーカーを作成:
(setq m1 (make-marker))
     ⇒ #<marker in no buffer>

;; カレントバッファーの99と100番目の
;;   文字間を指すようm1をセット:
(set-marker m1 100)
     ⇒ #<marker at 100 in markers-ja.texi>

;; ここでバッファー先頭に1文字挿入:
(goto-char (point-min))
     ⇒ 1
(insert "Q")
     ⇒ nil

;; m1は適切に更新された
m1
     ⇒ #<marker at 101 in markers-ja.texi>

;; 同じ位置を指す2つのマーカーは
;;   equalだがeqに非ず
(setq m2 (copy-marker m1))
     ⇒ #<marker at 101 in markers-ja.texi>
(eq m1 m2)
     ⇒ nil
(equal m1 m2)
     ⇒ t

;; マーカー使用終了時、存在しない場所を指すようセット
(set-marker m1 nil)
     ⇒ #<marker in no buffer>

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

32.2 マーカーのための述語

あるオブジェクトがマーカーなのか、それとも整数かマーカーのいずれかであるかを確認するためのテストを行うことができます。後者のテストはマーカーと整数の両方にたいして機能する算術関数において有用です。

Function: markerp object

この関数はobjectがマーカーならnil、それ以外はtをリターンする。多くの関数はマーカーか整数のいずれかを受け入れるだろうが、整数はマーカーとは異なることに注意。

Function: integer-or-marker-p object

この関数はobjectが整数かマーカーならt、それ以外はnilをリターンする。

Function: number-or-marker-p object

この関数はobjectが数値(整数か浮動小数点数)またはマーカーならt、それ以外はnilをリターンする。


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

32.3 マーカーを作成する関数

マーカーを新たに作成する際には存在しない場所、ポイントの現在位置、バッファーのアクセス可能範囲の先頭や終端、または別の与えられたマーカーと同じ箇所を指すようにすることができます。

以下の4つの関数はすべて挿入タイプnilのマーカーをリターンします。マーカーの挿入タイプを参照してください。

Function: make-marker

この関数はどこも指さないマーカーを新たに作成してリターンする。

(make-marker)
     ⇒ #<marker in no buffer>
Function: point-marker

この関数はカレントバッファーのポイント現在位置を指すマーカーを新たに作成してリターンする。ポイントを参照のこと。例は以下のcopy-markerを参照のこと。

Function: point-min-marker

この関数はバッファーのアクセス可能範囲の先頭を指すマーカーを新たに作成してリターンする。ナローイングが効力をもたなければ、これはバッファーの先頭になるだろう。ナローイングを参照のこと。

Function: point-max-marker

この関数はバッファーのアクセス可能範囲の終端を指すマーカーを新たに作成してリターンする。ナローイングが効力をもたなければ、これはバッファーの終端になるだろう。ナローイングを参照のこと。

以下はこのチャプターのテキストのソースファイルのバージョンを含むバッファーにたいして、この関数とpoint-min-markerを使用する例。

(point-min-marker)
     ⇒ #<marker at 1 in markers-ja.texi>
(point-max-marker)
     ⇒ #<marker at 24080 in markers-ja.texi>

(narrow-to-region 100 200)
     ⇒ nil
(point-min-marker)
     ⇒ #<marker at 100 in markers-ja.texi>
(point-max-marker)
     ⇒ #<marker at 200 in markers-ja.texi>
Function: copy-marker &optional marker-or-integer insertion-type

引数としてマーカーを渡されると、copy-markermarker-or-integerが行うように同じバッファーの同じ位置を指すマーカーを新たに作成してリターンする。整数を渡されると、copy-markerはカレントバッファーの位置marker-or-integerを指すマーカーを新たに作成してリターンする。

新たなマーカーの挿入タイプは引数insertion-typeにより指定される。マーカーの挿入タイプを参照のこと。

(copy-marker 0)
     ⇒ #<marker at 1 in markers-ja.texi>

(copy-marker 90000)
     ⇒ #<marker at 24080 in markers-ja.texi>

markerがマーカーと整数のいずれでもなければエラーがシグナルされる。

2つのマーカーはそれらが同じバッファーの同じ位置、またはどちらも存在しない場所を指す場合には、(eqではないが)equalとみなされます。

(setq p (point-marker))
     ⇒ #<marker at 2139 in markers-ja.texi>

(setq q (copy-marker p))
     ⇒ #<marker at 2139 in markers-ja.texi>

(eq p q)
     ⇒ nil

(equal p q)
     ⇒ t

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

32.4 マーカーからの情報

このセクションではマーカーオブジェクトの構成要素にアクセスする関数を説明します。

Function: marker-position marker

この関数はmarkerが指す位置、存在しない場所ならnilをリターンする。

Function: marker-buffer marker

この関数はmarkerがその内部を指すバッファー、存在しない場所を指す場合にはnilをリターンする。

(setq m (make-marker))
     ⇒ #<marker in no buffer>
(marker-position m)
     ⇒ nil
(marker-buffer m)
     ⇒ nil

(set-marker m 3770 (current-buffer))
     ⇒ #<marker at 3770 in markers-ja.texi>
(marker-buffer m)
     ⇒ #<buffer markers-ja.texi>
(marker-position m)
     ⇒ 3770

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

32.5 マーカーの挿入タイプ

マーカーが指す位置に直接テキストを挿入する際には、そのマーカーを再配置するために利用可能な手段が2つあります。そのマーカーは挿入されたテキストの前か後を指すことができます。マーカーの挿入タイプ(insertion type)を指定することにより、マーカーがどちらを行うか指定できます。insert-before-markersを使用する場合には、マーカーの挿入タイプを無視して常にマーカーが挿入されたテキストの後を指すよう再配置されることに注意してください。

Function: set-marker-insertion-type marker type

この関数はマーカーmarkerの挿入タイプをtypeにセットする。typetなら、テキスト挿入時にmarkerはその位置まで進められるだろう。typenilなら、テキスト挿入時にmarkerはそこまで進められることはない。

Function: marker-insertion-type marker

この関数はmarkerのカレント挿入タイプを報告する。

挿入タイプを指定するための引数を受け取らずにマーカーを作成するすべての関数は、挿入タイプnilでマーカーを作成します。マークもデフォルトでは挿入タイプnilをもちます。


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

32.6 マーカー位置の移動

このセクションでは既存マーカーの位置を変更する方法について説明します。これを行う際にはそのマーカーがあなたのプログラム外部に使用されているかどうか、もし使用されているならマーカーを移動した結果どのような影響が生じるかを確実に理解する必要があります。さもないとEmacsの他の部分で混乱した出来事が発生するかもしれません。

Function: set-marker marker position &optional buffer

この関数はbuffer内でmarkerpositionに移動する。bufferが与えられなかった場合のデフォルトはカレントバッファー。

positionnil、または存在しない場所を指すマーカーなら、markerは存在しない場所を指すようにセットされる。

リターン値はmarker

(setq m (point-marker))
     ⇒ #<marker at 4714 in markers-ja.texi>
(set-marker m 55)
     ⇒ #<marker at 55 in markers-ja.texi>
(setq b (get-buffer "foo"))
     ⇒ #<buffer foo>
(set-marker m 0 b)
     ⇒ #<marker at 1 in foo>
Function: move-marker marker position &optional buffer

これはset-markerの別名。


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

32.7 マーク

バッファーはそれぞれマーク(mark)というバッファー専用の特別なマーカーをもちます。バッファーが新たに作成される際には、このマーカーはすでに存在していますがどこも指していません。これはそのバッファーにはまだマークが存在しないことを意味します。それ以降のコマンドがマークをセットできます。

マークはkill-regionindent-rigidlyのような多くのコマンドにたいしてテキスト範囲をバインドするための位置を指定します。これらのコマンドは、通常はポイントとマークの間のリージョン(region)と呼ばれるテキストに作用します。リージョンを操作するコマンドを記述する場合にはマークを直接調べず、かわりに‘r’指定とともにinteractiveを使用してください。このようにすればインタラクティブな呼び出しではコマンドの引数としてポイントとマークの値が提供され、かつ他のLispプログラムは引数を明示的に指定できます。interactiveにたいするコード文字を参照してください。

いくつかのコマンドは副作用(side-effect)としてマークをセットします。コマンドはユーザーがそれを使用する可能性がある場合のみマークをセットするべきであって、決してコマンドの内部的な目的にたいして使用してはなりません。たとえばreplace-regexpコマンドは何らかの置換を行う前にマークにポイントの値をセットしますが、その理由はこれによりユーザーが置換を終えた後に簡単にその位置に戻ることが可能になるからです。

一度バッファー内にマークが存在すれば、その存在は通常は決して消えることはありません。しかしTransient Markモードが有効だとマークが非アクティブ(inactive)になることはあります。バッファーローカル変数mark-activeが非nilなら、それはマークがアクティブであることを意味します。コマンドはマークを直接非アクティブにするために関数deactivate-markを呼び出すことができ、変数deactivate-markを非nil値にセットすることにより、エディターコマンドループ(editor command loop)にリターン時にマークの非アクティブ化を要求できます。

Transient Markモードが有効だと、通常ならポイント近傍に適用される特定の編集コマンドはマークがアクティブなときはかわりにリージョンに適用されます。これがTransient Markモードを使用する主な動機です(他にもマークアクティブ時にはリージョンのハイライトが有効になるという理由もある。Emacsのディスプレイ表示を参照)。

マークに加えてバッファーはそれぞれマークリング(mark ring)をもっています。これは以前のマーク値を含むマーカーのリストです。編集コマンドがマークを変更する際には、それらのコマンドは通常はマークの旧値をマークリングに保存するべきです。変数mark-ring-maxはマークリング内のエントリー最大数を指定します。リストがこの長さに達すると最後の要素を削除して新たな要素が追加されます。

これとは別にグローバルマークリング(global mark ring)がありますが、それは少数の特定のユーザーレベルコマンドでのみ使用されて、Lispプログラムとは関連しないのでここでは説明しません。

Function: mark &optional force

この関数はカレントバッファーのマーク位置を整数でリターンする。そのバッファー内でそれまでマークがセットされていなければnilをリターンする。

Transient Markモードが有効、かつmark-even-if-inactivenilの場合、マークが非アクティブならmarkはエラーをシグナルする。しかし、forceが非nilなら、markはマークの非アクティブ性を無視して、何にせよマーク位置(かnil)をリターンする。

Function: mark-marker

この関数はカレントバッファーのマークを表すマーカーをリターンする。これはコピーではなく内部的に使用されるマーカー。したがってこのマーカー位置にたいする変更は、そのバッファーのマークに直接影響する。それが望む効果でなければこれを行ってはならない。

(setq m (mark-marker))
     ⇒ #<marker at 3420 in markers-ja.texi>
(set-marker m 100)
     ⇒ #<marker at 100 in markers-ja.texi>
(mark-marker)
     ⇒ #<marker at 100 in markers-ja.texi>

他のマーカー同じように、このマーカーを任意のバッファー位置にセットできる。このマーカーにたいして、これがマークする以外のバッファーを指すようにすると、完全に整合性があるものの、いささか奇妙な結果を得ることになるだろう。わたしたちはこれを行わないことを推奨する!

Function: set-mark position

この関数はマークをpositionにセットして、そのマークをアクティブにする。マークの旧値はマークリングにpushされない

注意: マークが移動したことをユーザーに確認させて、かつ前のマーク位置が失われることを望む場合のみこの関数を使用すること。通常はマークセット時に古いマークをmark-ringにpushすること。この理由により、ほとんどのアプリケーションはset-markではなく、push-markpop-markを使用するべきである。

Emacs Lisp初心者のプログラマーは誤った用途にマークの使用を試みがちである。ユーザーの利便のために位置を保存するのがマークである。編集コマンドはマーク変更がコマンドのユーザーレベル機能の一部でない限りマークを変更しないこと(そのような場合にはその効果をドキュメントするべきである)。Lispプログラムの内部的な使用のために位置を記憶するためには、マークをLisp変数に格納すること。たとえば:

(let ((beg (point)))
  (forward-line 1)
  (delete-region beg (point)))
Function: push-mark &optional position nomsg activate

この関数はカレントバッファーのマークをpositionにセットして、前のマークをmark-ringにpushする。positionnilならポイントの値を使用する。

関数push-markは通常はマークをアクティブにしない。アクティブにする場合には引数activatetを指定する。

nomsgnilならメッセージ‘Mark set’が表示される。

Function: pop-mark

この関数はmark-ringのトップ要素をpopして、そのマークをバッファーの実際のマークにする。これはバッファー内のポイントを移動せず、mark-ringが空なら何も行わない。これはマークを非アクティブ化する。

User Option: transient-mark-mode

この変数が非nilならTransient Markモードを有効にする。Transient Markモードでは、すべてのバッファー変更プリミティブがdeactivate-markをセットする。結果としてバッファーを変更するほとんどのコマンドもマークを非アクティブにする。

Transient Markモードが有効かつマークがアクティブなら、通常はポイント近傍に適用されるコマンドの多くは、かわりにリージョンに適用される。そのようなコマンド、リージョンを処理すべきかどうかをテストするために、関数use-region-pを使用すること。リージョンを参照のこと。

Lispプログラムは一時的にTransient Markモードを有効にするために、transient-mark-modenilでもtでもない値にセットできる。値がlambdaなら、通常ならマークを非アクティブ化するバッファー変更ような操作の後に、Transient Markモードを自動的にオフに切り替える。値が(only . oldval)なら後続のコマンドがポイントを移動かつシフト変換(shift-translationを参照)されていない場合、あるいは通常はマークを非アクティブにするその他の操作の場合に、transient-mark-modeに値oldvalをセットする(マウスでリージョンをマークした際には、、この方法によって一時的にtransient-mark-modeがオンになる)。

User Option: mark-even-if-inactive

これが非nilなLispプログラムおよびEmacsユーザーは、たとえ非アクティブでもマークを使用できる。このオプションはTransient Markモードの動作に影響を及ぼす。このオプションが非nilならマークの非アクティブ化によりリージョンのハイライトはオフに切り替えられるが、マークを使用するコマンドは、あたかもマークがアクティブであるかのように振る舞う。

Variable: deactivate-mark

エディターコマンドがこの変数を非nilにセットすると、エディターコマンドループはコマンドのリターン後に、(Transient Markモードが有効なら)マークを非アクティブにする。バッファーを変更するすべてのプリミティブは、コマンド終了時にマークを非アクティブにするためにdeactivate-markをセットする。この変数はセットすらことによりバッファーローカルになる。

コマンド終了時にマークを非アクティブにすることなくバッファーを変更するLispコードを記述するためには、変更を行うコードの周辺でdeactivate-marknilにバインドすること。たとえば:

(let (deactivate-mark)
  (insert " "))
Function: deactivate-mark &optional force

Transient Markモードが有効、またはforceが非nilなら、この関数はマークを非アクティブにしてノーマルフックdeactivate-mark-hookを実行して、それ以外は何も行わない。

Variable: mark-active

この変数が非nilならマークはアクティブ。この変数はそれぞれのバッファーにたいして常にローカル。通常はポイント近傍を操作するコマンドが、かわりにリージョンを操作すべきかどうかを判断するためにこの変数の値を使用してはならない。その目的にたいしては関数use-region-pを使用すること(リージョンを参照)。

Variable: activate-mark-hook
Variable: deactivate-mark-hook

これらのノーマルフックはマークがアクティブや非アクティブになった際に順次実行される。たとえばアクティブなマークがあるバッファーに切り替えて戻るコマンドの使用後のようにリージョンが再アクティブ化された際には、フックactivate-mark-hookも実行される。

Function: handle-shift-selection

この関数はポイント移動コマンドのシフト選択(shift-selection)の動作を実装する。Shift Selection in The GNU Emacs Manualを参照のこと。これはinteractive指定に文字‘^’を含むコマンドの呼び出し時は常に、そのコマンド自身を実行する前にEmacsコマンドループにより自動的に呼び出される(^を参照)。

shift-select-modeが非nil、かつカレントコマンドがシフト変換(shift-translationを参照)を通じて呼び出された場合には、この関数はマークをセットして一時的にリージョンをアクティブにする(すでにこの方法によりリージョンが一時的にアクティブにされている場合を除く)。それ以外ではリージョンが一時的にアクティブにされていればマークを非アクティブにして、変数transient-mark-modeに前の値をリストアする。

Variable: mark-ring

このバッファーローカル変数の値は、もっとも最近のものが先頭となるような、以前に保存されたカレントバッファーのマークのリスト。

mark-ring
⇒ (#<marker at 11050 in markers-ja.texi>
    #<marker at 10832 in markers-ja.texi>
    …)
User Option: mark-ring-max

この変数の値はmark-ringの最大サイズ。これより多くのマークがmark-ringにpushされると、push-mark新たなマーク追加時には古いマークを破棄する。

Delete Selectionモード(Delete Selection in The GNU Emacs Manualを参照)が有効な際には、アクティブリージョン(いわゆる“選択”)を操作するコマンドは若干異なる振る舞いをします。これはpre-command-hookに関数delete-selection-pre-hookを追加することにより機能します(コマンドループの概要を参照)。この関数はそのコマンドにたいして適切なように選択を削除するためにdelete-selection-helperを呼び出します。コマンドをDelete Selectionモードに適応させたければ、その関数シンボルのdelete-selectionプロパティにputしてください(シンボルのプロパティへのアクセスを参照)。シンボルにこのプロパティをもたないコマンドは選択を削除しません。そのコマンドに期待される挙動を調整するために、このプロパティはいくつかの値のいずれかをもつことができます。詳細はdelete-selection-pre-hookdelete-selection-helperのドキュメント文字列を参照してください。


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

32.8 リージョン

ポイントとマークの間のテキストは、リージョン(region)という名で知られています。さまざまな関数がポイントとマークで区切られたテキストを操作しますが、ここではリージョンそのものに特に関連する関数だけを説明します。

以下の2つの関数はマークが何処も指していなければエラーをシグナルします。Transient Markモードが有効、かつmark-even-if-inactivenilな、マークが非アクティブな場合にエラーをシグナルします。

Function: region-beginning

この関数はリージョンの先頭位置を、(整数として)リターンする。これはポイントかマークのいずれか小さいほうの位置。

Function: region-end

この関数はリージョンの終端位置を、(整数として)リターンする。これはポイントかマークのいずれか大きいほうの位置。

リージョンにたいして操作を行うようにデザインされたコマンドがリージョンの先頭と終端を探すためには、region-beginningregion-endを使用するかわりに、通常は‘r’指定とともにinteractiveを使用するべきです。これにより他のLispプログラムが引数として明示的にリージョンの境界を指定できるようになります。interactiveにたいするコード文字を参照してください。。

Function: use-region-p

この関数はTransient Markモードが有効でマークがアクティブであり、かつバッファー内に有効なリージョンがあればtをリターンする。この関数はマークアクティブ時にはポイント近傍のテキストのかわりにリージョンを操作するコマンドにより使用されることを意図している。

リージョンはそれが非0のサイズをもつか、あるいはユーザーオプションuse-empty-active-regionが非nil (デフォルトはnil)なら有効。関数region-active-puse-region-pと同様だが、すべてのリージョンを有効とみなす。リージョンが空ならポイントにたいして操作を行うほうが適切な場合が多いために、ほとんどの場合はregion-active-pを使用するべきではない。


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

33 テキスト

このチャプターではバッファー内のテキストを扱う関数を説明します。ほとんどはカレントバッファー内のテキストにたいして検査、挿入、削除を行ってポイント位置やポイントに隣接するテキストを操作することが多々あります。その多くはインタラクティブ(interactive: 対話的)です。テキストを変更するすべての関数は、その変更にたいするundo(アンドゥ、取り消し)を提供します(アンドゥを参照)。

テキストに関連する関数の多くが、startendという名前の引数として渡された2つのバッファー位置により定義されるテキストのリージョンを操作します。これらの引数はマーカー(マーカーを参照)か数値的な文字位置(ポジションを参照)のいずれかであるべきです。これらの引数の順序は関係ありません。startがリージョンの終端でendがリージョンの先頭であっても問題はありません。たとえば(delete-region 1 10)(delete-region 10 1)は等価です。startendのいずれかがバッファーのアクセス可能範囲の外部ならargs-out-of-rangeエラーがシグナルされます。インタラクティブな呼び出しでは、これらの引数にポイントとマークが使用されます。

このチャプターを通じて、“テキスト(text)”とは(関係あるときは)そのプロパティも含めたバッファー内の文字を意味します。ポイントは常に2つの文字の間にあり、カーソルはポイントの後の文字上に表示されることを覚えておいてください。


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

33.1 ポイント近傍のテキストを調べる

ポイント付近にある文字を調べるための関数が数多く提供されています。簡単な関数のいくつかはここで説明します。正規表現の検索looking-atも参照してください。

以下の4つの関数でのバッファーの“先頭(beginning)”と“終端(end)”はそれぞれ、アクセス可能範囲の先頭と終端を意味します。

Function: char-after &optional position

この関数はカレントバッファーの位置position (つまり直後)の文字をリターンする。positionがこの目的にたいする範囲の外にある場合、すなわちバッファーの先頭より前、またはバッファーの終端以降にあるなら値はnilpositionのデフォルトはポイント。

以下の例ではバッファーの最初の文字が‘@’であると仮定する:

(string (char-after 1))
     ⇒ "@"
Function: char-before &optional position

この関数はカレントバッファーの位置positionの直前の文字をリターンする。positionがこの目的にたいする範囲の外にある場合、すなわちバッファーの先頭より前、またはバッファーの終端より後にあるなら値はnilpositionのデフォルトはポイント。

Function: following-char

この関数はカレントバッファーのポイントの後にある文字をリターンする。これは(char-after (point))と同様。ただしポイントがバッファー終端にある場合には、following-charは0をリターンする。

ポイントが常に2つの文字の間にあり、カーソルは通常はポイント後の文字上に表示されることを思い出してほしい。したがってfollowing-charがリターンする文字はカーソル上の文字となる。

以下の例では‘a’と‘c’の間にポイントがある。

---------- Buffer: foo ----------
Gentlemen may cry ``Pea∗ce! Peace!,''
but there is no peace.
---------- Buffer: foo ----------

(string (preceding-char))
     ⇒ "a"
(string (following-char))
     ⇒ "c"
Function: preceding-char

この関数はカレントバッファーのポイントの前の文字をリターンする。上記following-charの下の例を参照のこと。ポイントがバッファー先頭にあれば、preceding-charは0をリターンする。

Function: bobp

この関数はポイントがバッファー先頭にあればtをリターンする。ナローイングが効力をもつなら、これはテキストのアクセス可能範囲の先頭を意味する。ポイントpoint-minも参照のこと。

Function: eobp

この関数はポイントがバッファー終端にあればtをリターンする。ナローイングが効力をもつなら、これはテキストのアクセス可能範囲の終端を意味する。ポイントpoint-maxも参照のこと。

Function: bolp

この関数はポイントが行の先頭にあればtをリターンする。テキスト行単位の移動を参照のこと。バッファー(またはアクセス可能範囲)の先頭は、常に行の先頭とみなされる。

Function: eolp

この関数はポイントが行の終端にあればtをリターンする。テキスト行単位の移動を参照のこと。バッファー(またはアクセス可能範囲)の終端は常に行の先頭とみなされる。


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

33.2 バッファーのコンテンツを調べる

このセクションではLispプログラムがバッファー内の任意の範囲にあるテキストを文字列に変換するための関数を説明します。

Function: buffer-substring start end

この関数はカレントバッファー内の位置startendで定義されるリージョンのテキストのコピーを含む文字列をリターンする。引数がバッファーのアクセス可能範囲内の位置でなければ、buffer-substringargs-out-of-rangeエラーをリターンする。

以下の例ではFont-Lockモードが有効でないものとする:

---------- Buffer: foo ----------
This is the contents of buffer foo

---------- Buffer: foo ----------

(buffer-substring 1 10)
     ⇒ "This is t"
(buffer-substring (point-max) 10)
     ⇒ "he contents of buffer foo\n"

コピーされるテキストが何らかのテキストプロパティをもっていたら、それらのプロパティが属する文字とともに文字列にコピーされる。しかしバッファー内のオーバーレイ(オーバーレイを参照)、およびそれらのプロパティは無視されるためコピーされない。

たとえばFont-Lockモードが有効なら以下のような結果を得るだろう:

(buffer-substring 1 10)
     ⇒ #("This is t" 0 1 (fontified t) 1 9 (fontified t))
Function: buffer-substring-no-properties start end

これはbuffer-substringと同様だが、テキストプロパティはコピーせずに文字自体だけをコピーする点が異なる。テキストのプロパティを参照のこと。

Function: buffer-string

この関数はカレントバッファーのアクセス可能範囲全体のコンテンツを文字列としてリターンする。コピーするテキストに何らかのテキストプロパティがあれば、それらを所有する文字とともに文字列にコピーされる。

異なる場所からのコピー時に双方向テキストの再配置によって結果の文字列の視覚的外見が変更されないように保証する必要があるなら、buffer-substring-with-bidi-context関数を使用すること(buffer-substring-with-bidi-contextを参照)。

Function: filter-buffer-substring start end &optional delete

この関数は変数filter-buffer-substring-functionにより指定された関数を使用して、startendの間のバッファーテキストをフィルターしてその結果をリターンする。

デフォルトのフィルター関数は時代遅れとなったラッパーフックfilter-buffer-substring-functions (この時代遅れの機能に関する詳細はマクロwith-wrapper-hookのドキュメント文字列を参照)がnilならバッファーから未変更のテキスト、すなわちbuffer-substringがリターンするであろうテキストをリターンする。

deleteが非nilなら、この関数はdelete-and-extract-regionと同じように、コピー後にstartendの間のテキストを削除する。

Lispコードはkillリング、Xクリップボード、レジスターのようなユーザーがアクセス可能なデータ構造内にコピーする際にはbuffer-substringbuffer-substring-no-propertiesdelete-and-extract-regionのかわりにこの関数を使用すること。メジャーモードとマイナーモードはバッファー外部にコピーするテキストを変更するためにfilter-buffer-substring-functionを変更することができる。

Variable: filter-buffer-substring-function

この変数の値は実際の処理を行うためにfilter-buffer-substringが呼び出す関数。その関数はfilter-buffer-substringと同じように3つの引数を受けとり、それらはfilter-buffer-substringにドキュメントされているように扱うこと。関数はフィルターされたテキストをリターン(およびオプションでソーステキストを削除)すること。

The following two variables are obsoleted by 以下の2つの変数はfilter-buffer-substring-functionにより時代遅れになりましたが、後方互換のために依然としてサポートされます。

Variable: filter-buffer-substring-functions

これは時代遅れとなったラッパーフックであり、このフックのメンバーはfunstartenddeleteの4つの引数を受け取る関数であること。funは3つの引数(startenddelete)を受け取り、文字列をリターンする関数。いずれも引数startenddeletefilter-buffer-substringのときと同様の意味をもつ。

1つ目のフック関数はfilter-buffer-substringのデフォルトの処理と同じくstartendの間のバッファー部分文字列をリターン(オプションでバッファーから元テキストを削除)する関数であり、それがfunに渡される。ほとんどの場合にはフック関数はfunを1回だけ呼び出してから、その結果にたいして自身の処理を行う。次のフック関数はこれと等しいfunを受け取って、それが順次繰り返されていく。実際のリターン値はすべてのフック関数が順次処理した結果。

Function: current-word &optional strict really-word

この関数はポイント位置またはその付近のシンボル(または単語)を文字列としてリターンする。リターン値にテキストプロパティは含まれない。

オプション引数really-wordが非nilなら単語、それ以外はシンボル(単語文字とシンボル構成文字の両方を含む)を探す。

オプション引数strictが非nilのならポイントは単語(またはシンボル)の内部にあるか隣接しなければならない。そこに単語(またはシンボル)がなければ、この関数はnilをリターンする。strictnilならポイントと同一行にある近接する単語(またはシンボル)を許容する。

Function: thing-at-point thing &optional no-properties

ポイントに隣接または周辺にあるthingを文字列としてリターンする。

引数thingは構文エンティティの種別を指定するシンボルである。可能なシンボルとしてはsymbollistsexpdefunfilenameexisting-filenameurlwordsentencewhitespacelinepagestring、および他が含まれる。

オプション引数no-propertiesは非nilなら、この関数はリターン値からテキストプロパティを取り除く。

---------- Buffer: foo ----------
Gentlemen may cry ``Pea∗ce! Peace!,''
but there is no peace.
---------- Buffer: foo ----------

(thing-at-point 'word)
     ⇒ "Peace"
(thing-at-point 'line)
     ⇒ "Gentlemen may cry ``Peace! Peace!,''\n"
(thing-at-point 'whitespace)
     ⇒ nil
Variable: thing-at-point-provider-alist

ユーザーおよびモードは、この変数によってthing-at-pointが機能する方法を調節できる。これはthing、およびそれ(thing)をリターンする関数(パラメーターなしで呼び出される)の連想リストである。thingのエントリーは非nilの結果がリターンされるまで順に評価される。

たとえばメジャーモードは以下のように指定できる:

(setq-local thing-at-point-provider-alist
            (append thing-at-point-provider-alist
                    '((url . my-mode--url-at-point))))

nilをリターンするproviderがなければ、標準的な方法によってthingを計算する。


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

33.3 テキストの比較

以下の関数により最初にバッファー内のテキストを文字列内にコピーすることなく、バッファー内のテキスト断片を比較することが可能になります。

Function: compare-buffer-substrings buffer1 start1 end1 buffer2 start2 end2

この関数により1つのバッファー、または2つの異なるバッファーの2つの部分文字列(substrings)を比較できる。最初の3つの引数はバッファーとそのバッファー内の2つの位置を与えることにより、1つの部分文字列を指定する。最後の3つの引数は、同様の方法によりもう一方の部分文字列を指定する。buffer1buffer2のいずれか、または両方にたいしてカレントバッファーを意味するnilを使用できる。

1つ目の部分文字列が2つ目の部分文字列より小なら負、大なら正、等しければ値は0となる。結果の絶対値は部分文字列内で最初に異なる文字のインデックスに1を和した値。

case-fold-searchが非nilなら、この関数はcase(大文字小文字)の違いを無視する。テキストプロパティは常に無視される。

カレントバッファー内にテキスト‘foobarbar haha!rara!がある。そしてこの例では2つの部分文字列が‘rbar ’と‘rara!’だとする。1つ目の文字列の2つ目の文字が大きいので値は2となる。

(compare-buffer-substrings nil 6 11 nil 16 21)
     ⇒ 2

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

33.4 テキストの挿入

挿入(insertion)とはバッファーへの新たなテキストの追加を意味します。テキストはポイント位置、すなわちポイント前の文字とポイント後の文字の間に追加されます。挿入関数は挿入されたテキストの後にポイントを残しますが、前にポイントを残す関数もいくつかあります。前者の挿入をポイント後挿入(after point)、後者をポイント前挿入(before point)と呼びます。

挿入により挿入位置の後にあったマーカーは、テキストを取り囲むように移動されます(マーカーを参照)。マーカーが挿入箇所をさしている際には、挿入によるマーカーの再配置の有無はそのマーカーの挿入タイプに依存します(マーカーの挿入タイプを参照)。insert-before-markersのような特定のスペシャル関数は、マーカーの挿入タイプとは関係なく挿入されたテキストの後にそのようなすべてのマーカーを再配置します。

カレントバッファーが読み取り専用(読み取り専用のバッファーを参照)、または読み取り専用テキスト(特殊な意味をもつプロパティを参照)を挿入しようとすると、挿入関数はエラーをシグナルします。

以下の関数は文字列やバッファーからプロパティとともにテキスト文字をコピーします。挿入される文字はコピー元の文字と完全に同一のプロパティをもちます。それとは対照的に文字列やバッファーの一部ではない個別の引数として指定された文字は、隣接するテキストからテキストプロパティを継承します。

テキストが文字列かバッファー由来なら、マルチバイトバッファーに挿入するために挿入関数はユニバイトからマルチバイトへの変換、およびその逆も行います。しかしたとえカレントバッファーがマルチバイトバッファーであったとしても、コード128から255までのユニバイトはマルチバイトに変換しません。テキスト表現の変換を参照してください。

Function: insert &rest args

この関数は文字列および/または1つ以上の文字argsをカレントバッファーのポイント位置に挿入して、ポイントを前方に移動する。言い換えるとポイントの前にテキストを挿入する。すべてのargsが文字列が文字列と文字のいずれでもなければエラーをシグナルする。値はnil

Function: insert-before-markers &rest args

この関数は文字列および/または1つ以上の文字argsをカレントバッファーのポイント位置に挿入して、ポイントを前方に移動する。すべてのargsが文字列が文字列と文字のいずれでもなければエラーをシグナルする。値はnil

この関数は他の挿入関数と異なり、挿入されたテキストの後を指すように、まずマーカーが挿入位置を指すよう再配置する。挿入位置からオーバーレイが開始される場合には、挿入されたテキストはそのオーバーレイの外側に出される。空でないオーバーレイが挿入位置で終わる場合には、挿入されたテキストはそのオーバーレイの内側に入れられる。

Command: insert-char character &optional count inherit

このコマンドはカレントバッファーのポイントの前に、characterのインスタンスをcount個挿入する。引数countは整数、characterは文字でなければならない。

インタラクティブに呼び出された際には、このコマンドはcharacterにたいしてコードポイントかUnicode名による入力を求める。Inserting Text in The GNU Emacs Manualを参照のこと。

この関数はたとえカレントバッファーがマルチバイトバッファーであっても、コード128から255のユニバイト文字をマルチバイト文字に変換しない。テキスト表現の変換を参照のこと。

inheritが非nilなら、挿入された文字は挿入位置前後の2文字からステッキーテキストプロパティ(sticky text properties)を継承する。テキストプロパティの粘着性を参照のこと。

Function: insert-buffer-substring from-buffer-or-name &optional start end

この関数はカレントバッファーのポイント前に、バッファーfrom-buffer-or-nameの一部を挿入する。挿入されるテキストはstart (を含む)からend (を含まない)の間のリージョン(これらの引数のデフォルトは、そのバッファーのアクセス可能範囲の先頭と終端)。この関数はnilをリターンする。

以下の例ではバッファー‘bar’をカレントバッファーとしてフォームを実行する。バッファー‘bar’は最初は空であるものとする。

---------- Buffer: foo ----------
We hold these truths to be self-evident, that all
---------- Buffer: foo ----------

(insert-buffer-substring "foo" 1 20)
     ⇒ nil

---------- Buffer: bar ----------
We hold these truth∗
---------- Buffer: bar ----------
Function: insert-buffer-substring-no-properties from-buffer-or-name &optional start end

これはinsert-buffer-substringと似ているが、テキストプロパティをコピーしない点が異なる。

Function: insert-into-buffer to-buffer &optional start end

これはinsert-buffer-substringと同様だが、反対方向に機能する。テキストはカレントバッファーからto-bufferにコピーされる。テキストブロックはto-bufferのカレントポイントにコピーされて、(そのバッファーの)ポイントはコピーしたテキスト終端に進められる。start/endnilなら、カレントバッファーのテキスト全体をコピーする。

テキスト挿入に加えて、隣接するテキストからテキストプロパティを継承する他の関数についてはテキストプロパティの粘着性を参照のこと。インデント関数により挿入された空白文字もテキストプロパティを継承する。


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

33.5 ユーザーレベルの挿入コマンド

このセクションではテキスト挿入のための高レベルコマンド、ユーザーによる使用を意図しているがLispプログラムでも有用なコマンドについて説明します。

Command: insert-buffer from-buffer-or-name

このコマンドはfrom-buffer-or-name (存在しなければならない)のアクセス可能範囲全体をカレントバッファーのポイントの後に挿入する。マークは挿入されたテキストの後に残される。値はnil

Command: self-insert-command count &optional char

このコマンドは文字charを挿入する。これをポイント前でcount回繰り返してnilをリターンする。ほとんどのプリント文字はこのコマンドにバインドされる。通常の使用ではself-insert-commandはEmacsでもっとも頻繁に呼び出される関数だが、Lispプログラムではそれをキーマップにインストールする場合を除いて使用されるのは稀。

インタラクティブな呼び出しではcountは数プレフィクス引数。

自己挿入では入力文字はtranslation-table-for-inputを通じて変換される。文字の変換を参照のこと。

これは、入力文字がテーブルauto-fill-chars内にあり、auto-fill-functionが非nilなら常にそれを呼び出す(オートfillを参照)。

このコマンドはAbbrevモードが有効で、かつ入力文字が単語構成構文をもたなければabbrev展開を行う(abbrevとabbrev展開構文クラスのテーブルを参照)。さらに入力文字が閉カッコ構文(close parenthesis syntax)をもつ場合にはblink-paren-functionを呼び出す責任もある(カッコの点滅を参照)。

このコマンドは最後にフックpost-self-insert-hookを実行する。これを使えば、テキストのタイプ時に自動的に再インデントを行うことができる。このフックにセットした関数はlast-command-event (コマンドループからの情報を参照)を使うことにより、挿入したばかりの文字にアクセスすることができる。

このフックのいずれかの関数がリージョン(リージョンを参照)にたいして作用する必要があるなら、post-self-insert-hookの関数が呼び出される前にDelete Selectionモード(Delete Selection in The GNU Emacs Manualを参照)がリージョンを削除しないようにする必要がある。これを行うにはDelete Selectionモードにリージョンを削除しないように告げる特別なフックself-insert-uses-region-functionsnilをリターンする関数を追加すること。

self-insert-commandの標準的な定義にたいして、独自の定義による置き換えを試みてはならない。エディターコマンドループはこのコマンドを特別に扱うからだ。

Command: newline &optional number-of-newlines interactive

このコマンドはカレントバッファーのポイントの前に改行を挿入する。number-of-newlinesが与えられたら、その個数の改行文字が挿入される。インタラクティブな呼び出しでは、number-of-newlinesはプレフィクス数引数。

この関数はカレント列数がfill-columnより大、かつnumber-of-newlinesnilならauto-fill-functionを呼び出す。このコマンドは改行を挿入するためにself-insert-commandを呼び出して、続けてauto-fill-functionを呼び出すことにより前の行をブレークする(オートfillを参照)。auto-fill-functionが通常行うのは改行の挿入であり、最終的な結果としてはポイント位置と、その行のより前方の位置という2つの異なる箇所に改行を挿入する。number-of-newlinesが非nilならnewlineはauto-fillを行わない。

このコマンドはインタラクティブな呼び出し、またはinteractiveが非nilならフックpost-self-insert-hookを実行する。

このコマンドは左マージンが0でなければ、左マージンにインデントする。fillのマージンを参照のこと。

リターン値はnil

Command: ensure-empty-lines &optional number-of-empty-lines

このコマンドはポイントの前に特定の行数の空行を確保するために用いることができる(ここで言う“空行”とは文字が何もない行のことを指し、空白文字があればそれは空行ではない)。デフォルトではポイントの前に1行の空行を確保する。

ポイントが行頭になければ、まず改行文字を挿入する。指定したより多くの空行がポイントの前にある場合には空行の行数を減らす。それ以外の場合には指定した行数に増やす。

Variable: overwrite-mode

この変数はoverwriteモードが効力をもつかどうかを制御する。値はoverwrite-mode-textualoverwrite-mode-binary、またはniloverwrite-mode-textualはテキスト的なoverwriteモード(改行とタブを特別に扱う)、overwrite-mode-binaryはバイナリーoverwriteモード(改行とタブを普通の文字と同様に扱う)を指定する。


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

33.6 テキストの削除

削除とはバッファー内のテキストの一部をkillリングに保存せずに取り除くことを意味します(killリングを参照)。削除されたテキストをyankすることはできませんが、undoメカニズム(アンドゥを参照)を使用すれば再挿入が可能です。特別なケースにおいてはkillリングにテキストの保存を行う削除関数がいくつかあります。

削除関数はすべてカレントバッファーにたいして処理を行います。

Command: erase-buffer

この関数はカレントバッファーのテキスト全体(アクセス可能範囲だけではない)を削除してバッファーが読み取り専用ならbuffer-read-only、バッファー内の一部テキストが読み取り専用ならtext-read-onlyをシグナルする。それ以外では確認なしでテキストを削除する。リターン値はnil

バッファーからの大量テキストの削除では、バッファーが大幅に縮小されたという理由により、通常はさらなる自動保存が抑制される。しかしerase-bufferは将来のテキストが以前のテキストと関連があるのは稀であり、以前のテキストのサイズと比較されるべきではないというアイデアにもとづいてこれを行わない。

Command: delete-region start end

このコマンドはカレントバッファー内の位置startからendまでの間のテキストを削除してnilをリターンする。削除されるリージョン内にポイントがあれば、リージョン削除後のポイントの値はstart。それ以外の場合は、マーカーが行うようにポイントはテキストを取り囲むように再配置される。

Function: delete-and-extract-region start end

この関数はカレントバッファー内の位置startからendまでの間のテキストを削除して、削除されたテキストを含む文字列をリターンする。

削除されるリージョン内にポイントがあれば、リージョン削除後のポイントの値はstart。それ以外ならマーカーが行うようにポイントはテキストを取り囲むように再配置される。

Command: delete-char count &optional killp

このコマンドはポイント直後のcount文字、countが負なら直前のcount文字を削除する。killpが非nilなら削除した文字をkillリングに保存する。

インタラクティブな呼び出しでは、countは数プレフィクス引数、killpは未処理プレフィクス引数(unprocessed prefix argument)。すなわちプレフィクス引数が与えられたらそのテキストはkillリングに保存され、与えられなければ1文字が削除されて、それはkillリングに保存されない。

リターン値は常にnil

Command: delete-backward-char count &optional killp

このコマンドはポイント直前のcount文字、countが負なら直後のcount文字を削除する。killpが非nilなら、削除した文字をkillリングに保存する。

インタラクティブな呼び出しでは、countは数プレフィクス引数、killpは未処理プレフィクス引数(unprocessed prefix argument)。すなわちプレフィクス引数が与えられたらそのテキストはkillリングに保存され、与えられなければ1文字が削除されて、それはkillリングに保存されない。

リターン値は常にnil

Command: backward-delete-char-untabify count &optional killp

このコマンドはタブをスペースに変換しながら、後方にcount文字を削除する。次に削除する文字がタブなら、まず適正な位置を保つような数のスペースに変換してから、それらのうちのスペース1つをタブのかわりに削除する。killpが非nilなら、このコマンドは削除した文字をkillリングに保存する。

タブからスペースへの変換はcountが正の場合のみ発生する。負の場合はポイント後の正確に-count文字が削除される。

インタラクティブな呼び出しでは、countは数プレフィクス引数、killpは未処理プレフィクス引数(unprocessed prefix argument)。すなわちプレフィクス引数が与えられたらそのテキストはkillリングに保存され、与えられなければ1文字が削除されて、それはkillリングに保存されない。

リターン値は常にnil

User Option: backward-delete-char-untabify-method

このオプションはbackward-delete-char-untabifyが空白文字を扱う方法を指定する。可能な値にはuntabify (タブを個数分のスペースに変換してスペースを1つ削除。これがデフォルト)、hungry (1コマンドでポイント前のタブとスペースすべてを削除する)、all (ポイント前のタブとスペース、および改行すべてを削除する)、nil (空白文字にたいして特に何もしない)。


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

33.7 ユーザーレベルの削除コマンド

このセクションでは、主にユーザーにたいして有用ですがLispプログラムでも有用なテキストを削除するための高レベルのコマンドを説明します。

Command: delete-horizontal-space &optional backward-only

この関数はポイント近辺のすべてのスペースとタブを削除する。リターン値はnil

backward-onlyが非nilなら、この関数はポイント前のスペースとタブを削除するがポイント後のスペースとタブは削除しない。

以下の例では、各行ごとに2番目と3番目の間にポイントを置いて、delete-horizontal-spaceを4回呼び出している。

---------- Buffer: foo ----------
I ∗thought
I ∗     thought
We∗ thought
Yo∗u thought
---------- Buffer: foo ----------

(delete-horizontal-space)   ; Four times.
     ⇒ nil

---------- Buffer: foo ----------
Ithought
Ithought
Wethought
You thought
---------- Buffer: foo ----------
Command: delete-indentation &optional join-following-p beg end

この関数はポイントのある行をその前の行に結合(join)する。結合においてはすべての空白文字を削除、特定のケースにおいてはそれらを1つのスペースに置き換える。join-following-pが非nilなら、delete-indentationはかわりに後続行と結合を行う。それ以外の場合にはbegendが非nilなら、この関数はbegendで定義されるリージョン内のすべての行を結合する。

インタラクティブな呼び出しではjoin-following-pはプレフィクス引数、begendはリージョンがアクティブならリージョンの開始と終了、それ以外はnil。この関数はnilをリターンする。

fillプレフィクスがあり、結合される2つ目の行もそのプレフィクスで始まる場合には、行の結合前にdelete-indentationはそのfillプレフィクスを削除する。fillのマージンを参照のこと。

以下の例では‘events’で始まる行にポイントがあり、前の行の末尾に1つ以上のスペースが存在しても違いは生じない。

---------- Buffer: foo ----------
When in the course of human
∗    events, it becomes necessary
---------- Buffer: foo ----------

(delete-indentation)
     ⇒ nil

---------- Buffer: foo ----------
When in the course of human∗ events, it becomes necessary
---------- Buffer: foo ----------

行の結合後に結合点に単一のスペースを残すか否かを決定するのは、関数fixup-whitespaceの責任である。

Command: fixup-whitespace

この関数はポイントを取り囲むすべての水平スペースを、コンテキストに応じて1つのスペースまたはスペースなしに置き換える。リターン値はnil

行の先頭や末尾において、スペースの適正な数は0。閉カッコ構文(close parenthesis syntax)の前の文字、開カッコの後の文字、式プレフィクス構文(expression-prefix syntax)においても、スペースの適正な数は0。それ以外ではスペースの適正な数は1。構文クラスのテーブルを参照のこと。

以下の例では最初に1行目の単語‘spaces’の前にポイントがある状態で、fixup-whitespaceを呼び出している。2回目の呼び出しでは‘(’の直後にポイントがある。

---------- Buffer: foo ----------
This has too many     ∗spaces
This has too many spaces at the start of (∗   this list)
---------- Buffer: foo ----------

(fixup-whitespace)
     ⇒ nil
(fixup-whitespace)
     ⇒ nil

---------- Buffer: foo ----------
This has too many spaces
This has too many spaces at the start of (this list)
---------- Buffer: foo ----------
Command: just-one-space &optional n

このコマンドはポイントを取り囲むすべてのスペースを1つのスペース、nが指定された場合はn個のスペースで置き換える。リターン値はnil

Command: delete-blank-lines

この関数はポイントを取り囲む空行を削除する。ポイントが前後に1行以上の空行がある空の行にある場合には、1行を除いてそれらすべてを削除する。ポイントが孤立した空行にあればその行を削除する。ポイントが空でない行にあれば、その直後にあるすべての空白を削除する。

空行とはタブまたはスペースのみを含む行として定義される。

delete-blank-linesnilをリターンする。

Command: delete-trailing-whitespace &optional start end

startendで定義されるリージョン内から末尾の空白文字を削除する。

このコマンドはリージョン内の各行の最後の非空白文字後にある空白文字を削除する。

このコマンドがバッファー全体(マークが非アクティブな状態で呼び出された場合やLispからendnilで呼び出された場合)にたいして動作する場合には、変数delete-trailing-linesが非nilならバッファーの終端行の末尾の行も削除する。


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

33.8 killリング

kill関数(kill functions)は削除関数のようにテキストを削除しますが、ユーザーがyankにより再挿入できるようにそれらを保存する点が異なります。これらの関数のほとんどは‘kill-’という名前をもちます。対照的に名前が‘delete-’で始まる関数は、(たとえ削除をundoできるとしても)通常はyank用にテキストを保存しません。それらは削除(deletion)関数です。

ほとんどのkillコマンドは主にインタラクティブな使用を意図しており、ここでは説明しません。ここで説明するのは、そのようなコマンドの記述に使用されるために提供される関数です。テキストをkillするために、これらの関数を使用できます。Lisp関数の内部的な目的のためにテキストの削除を要するときは、killリング内のコンテンツに影響を与えないように通常は削除関数を使用するべきでしょう。テキストの削除を参照してください。

killされたテキストは後のyank用にkillリング(kill ring)内に保存されます。これは直前のkillだけでなく直近のkillのいくつかを保持するリストです。yankがそれをサイクル順に要素をもつリストとして扱うので、これを“リング(ring)”と称しています。このリストは変数kill-ringに保持されており、リスト用の通常関数で操作可能です。このセクションで説明する、これをリングとして扱うために特化された関数も存在します。

特にkillされた実体が破壊されてしまわないような操作を参照するという理由から、“kill”という単語の使用が不適切だと考える人もいます。これは通常の生活において死は永遠であり、killされた実体は生活に戻ることはないことと対照的です。したがって他の比喩表現も提案されてきました。たとえば、“cutリング(cut ring)”という用語は、コンピューター誕生前に原稿を再配置するためにハサミで切り取って貼り付けていたような人に意味があるでしょう。しかし今となってはこの用語を変更するのは困難です。


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

33.8.1 killリングの概念

killリングはリスト内でもっとも最近にkillされたテキストが先頭になるように、killされたテキストを記録します。たとえば短いkillリングは以下のようになるでしょう:

("some text" "a different piece of text" "even older text")

このリストのエントリー長がkill-ring-maxに達すると、新たなエントリー追加により最後のエントリーが自動的に削除されます。

killコマンドが他のコマンドと混ざり合っているときは、各killコマンドはkillリング内に新たなエントリーを作成します。連続する複数のkillコマンドは単一のkillリングエントリーを構成します。これは1つの単位としてyankされます。2つ目以降の連続するkillコマンドは、最初のkillにより作成されたエントリーにテキストを追加します。

yankにたいしては、killリング内のただ1つのエントリーが、そのリングの先頭のエントリーとなります。いくつかのyankコマンドは、異なる要素を先頭に指定することにより、リングを回転(rotate)させます。しかしこの仮想的回転はリスト自身を変更しません。もっとも最近のエントリーが、常にリスト内の最初に配置されます。


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

33.8.2 kill用の関数

kill-regionはテキストkill用の通常サブルーチンです。この関数を呼び出すすべてのコマンドはkillコマンドです(そして恐らくは名前に‘kill’が含まれる)。kill-regionは新たにkillされたテキストをkillリング内の最初の要素内に置くか、それをもっとも最近の要素に追加します。これは前のコマンドがkillコマンドか否かを、(last-commandを使用して)自動的に判別して、もしkillコマンドならkillされたテキストをもっとも最近のエントリーに追加します。

以下で説明するコマンドはkillされるテキストがkillリングに保存される前に、それらをフィルターできます。これらの関数は、このフィルタリングを行うためにfilter-buffer-substringを呼び出します(バッファーのコンテンツを調べるを参照)。デフォルトではこれらはフィルタリングを行いませんが、バッファーにあったときと異なるようにテキストをkillリングに保存するために、マイナーモードとフック関数はフィルタリングをセットアップできます。

Command: kill-region start end &optional region

この関数はstartendの間のテキスト範囲をkillするが、オプション引数regionが非nilなら、かわりにカレントリージョンのテキストをkillする。そのテキストは削除されるが、そのテキストプロパティと共にkillリングに保存される。値は常にnil

インタラクティブな呼び出しではstartendはポイントとマークでregionは常に非nilなので、このコマンドは常にカレントリージョン内のテキストをkillする。

バッファーまたはテキストが読み取り専用なら、kill-regionは同じようにkillリングを変更後に、バッファーを変更せずにエラーをシグナルする。これはユーザーが一連のkillコマンドで、読み取り専用バッファーからkillリングにテキストをコピーするのに有用。

User Option: kill-read-only-ok

このオプションが非nilなら、バッファーやテキストが読み取り専用でもkill-regionはエラーをシグナルしない。かわりにバッファーを変更せずにkillリングを更新して単にリターンする。

Command: copy-region-as-kill start end &optional region

この関数はstartendの間のテキスト範囲(テキストプロパティを含む)をkillリングに保存するが、バッファーからそのテキストを削除しない。しかしオプション引数regionが非nilなら、この関数はstartendを無視して、かわりにカレントリージョンを保存する。この関数は常にnilをリターンする。

インタラクティブな呼び出しではstartendはポイントとマークでregionは常に非nilなので、このコマンドは常にカレントリージョン内のテキストをkillする。

このコマンドは後続のkillコマンドが同一のkillリングエントリーに追加しないように、this-commandkill-regionをセットしない。


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

33.8.3 yank

yankとはkillリングからテキストを挿入しますが、それが単なる挿入ではないことを意味します。yankとそれに関連するコマンドは、テキスト挿入前に特別な処理を施すためにinsert-for-yankを使用します。

Function: insert-for-yank string

この関数はinsertと同様に機能するが、結果をカレントバッファーに挿入する前にテキストプロパティyank-handler、同様に変数yank-handled-propertiesyank-excluded-propertiesに応じてstring内のテキストを処理する点が異なる。

stringを挿入する前にyank-transform-functions (以下参照)が実行される。

Function: insert-buffer-substring-as-yank buf &optional start end

この関数はinsert-buffer-substringと似ているが、yank-handled-propertiesyank-excluded-propertiesに応じてテキストを処理する点が異なる(これはyank-handlerプロパティを処理しないが、いずれにせよバッファー内のテキストでは通常は発生しない)。

文字列の一部またはすべてにテキストプロパティyank-handlerをputすると、insert-for-yankが文字列を挿入する方法が変更されます。文字列の別の箇所が異なるyank-handlerの値をもつ場合(比較はeq)、部分文字列はそれぞれ個別に処理されます。プロパティ値は以下の形式からなる1から4要素のリストでなければなりません(2番目以降の要素は省略可):

(function param noexclude undo)

これらの要素が何を行うかを以下に示します:

function

functionが非nilなら、insertのかわりに文字列を挿入するために、挿入する文字列を単一の引数として、その関数が呼び出される。

param

nilparamが与えられた場合には、それはstring (または処理されるstringの部分文字列)を置き換えるオブジェクトとしてfunction (またはinsert)に渡される。たとえばfunctionyank-rectangleなら、paramは矩形(rectangle)として挿入されるべき文字列のリスト。

noexclude

nilnoexcludeが与えられたら、挿入される文字列にたいするyank-handled-propertiesyank-excluded-propertiesの通常の動作を無効にする。

undo

nilundoが与えられたら、それはカレントオブジェクトの挿入をundoするためにyank-popが呼び出す関数。この関数はカレントリージョンのstartとendという2つの引数で呼び出される。functionyank-undo-functionをセットすることによりundoの値をオーバーライドできる。

User Option: yank-handled-properties

この変数はyankされるテキストの状態を処理するスペシャルテキストプロパティを指定する。これは(通常の方法、またはyank-handlerを通じた)テキストの挿入後、yank-excluded-propertiesが効力をもつ前に効果を発揮する。

値は要素が(prop . fun)であるようなalistであること。alistの各要素は順番に処理される。挿入されるテキストはテキスト範囲にたいして、テキストプロパティがpropeqなものがスキャンされる。そのような範囲にたいしてプロパティの値、そのテキストの開始と終了の位置という3つの引数によりfunが呼び出される。

User Option: yank-excluded-properties

この変数の値は挿入されるテキストから削除するためのプロパティのリスト。デフォルト値にはマウスに応答したりキーバインディングの指定を引き起こすテキストのような、煩わしい結果をもたらすかもしれないプロパティが含まれる。これはyank-handled-propertiesの後に効果を発揮する。

Variable: yank-transform-functions

この変数は関数のリストである。関数はそれぞれyankする文字列を引数として(順番に)呼び出されて、(恐らくは変換後の)文字列をリターンすること。この変数をグローバルにセットすることもできるが、yankの変種として新たなコマンドの作成にも用いることができる。たとえばyankのように機能するが、挿入前に空白文字を整理するようなコマンドを作成するには以下のように記述すればよい:

(defun yank-with-clean-whitespace ()
  (interactive)
  (let ((yank-transform-functions
	 '(string-clean-whitespace)))
    (call-interactively #'yank)))

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

33.8.4 yank用の関数

このセクションではyank用の高レベルなコマンドを説明します。これらのコマンドは主にユーザー用に意図されたものですが、Lispプログラム内での使用にたいしても有用です。yankyank-popはいずれも、変数yank-excluded-propertiesとテキストプロパティyank-handlerにしたがいます(yankを参照)。

Command: yank &optional arg

このコマンドはkillリングの先頭にあるテキストをポイントの前に挿入する。これはpush-mark(マークを参照)を使用して、そのテキストの先頭にマークをセットする。

argが非nilのリスト(これはユーザーがインタラクティブに数字を指定せずにC-uタイプ時に発生する)なら、yankは上述のようにテキストを挿入するがポイントはyankされたテキストの前、マークはyankされたテキストの後に置かれる。

argが数字ならyankarg番目に最近killされたテキスト、すなわちkillリングリストのarg番目の要素を挿入する。この順番はコマンドの目的にたいして1番目の要素としてみなされるリスト先頭の要素から巡回的に数えられる。

yankは、それが他のプログラムから提供されるテキストを使用しないかぎり(使用する場合はそのテキストをkillリングにpushする)、killリングのコンテンツを変更しない。しかしargが非1の整数なら、killリングを転回(rotate)してyankされるテキストをリング先頭に置く。

yanknilをリターンする。

Command: yank-pop &optional arg

yankや別のyank-popの直後に呼び出されると、このコマンドはkillリングからyankしたばかりのエントリーを、killリングの別のエントリーに置き換える。このようにコマンドが呼び出されたときは、リージョンには別のyankコマンドが挿入したばかりのテキストが含まれる。yank-popはそのテキストを削除して、killされた別のテキスト片をその位置に挿入する。そのテキスト片はすでにkillリング内のどこか別の箇所にあるので、これは削除されたテキストをkillリングに追加しない。しかし新たにyankされたテキストが先頭になるように、killリングの転回は行う。

argnilなら置換テキストはkillリングの1つ前の要素。argが数字なら置換テキストはkillリングのarg個前の要素である。argが負なら、より最近のkillが置換される。

killリング内のkillされたエントリーの順序はラップするので、繰り返しyank-popを呼び出してもっとも古いkillに達すると、その後はもっとも新しいkillとなり、もっとも新しいkillの前がもっとも古いkillとなる。

このコマンドはyank以外のコマンドの後でも呼び出せる。この場合にはミニバッファーでkillリングエントリーにたいする入力を求めて、ミニバッファーヒストリー(ミニバッファーのヒストリーを参照)としてkillリング要素を使用する。これによりユーザーはkillリング内に記録されている以前のkillをインタラクティブに選択できる。

リターン値は常にnilである。

Variable: yank-undo-function

この変数が非nilなら、関数yank-popは前のyankyank-popにより挿入されたテキストを削除するために、delete-regionのかわりにこの変数の値を使用する。値はカレントリージョンの開始と終了という2つの引数をとる関数でなければならない。

関数insert-for-yankはテキストプロパティyank-handlerの要素undoに対応して、この変数を自動的にセットする。


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

33.8.5 低レベルのkillリング

以下の関数と変数はkillリングにたいして低レベルなアクセスを提供しますが、それらはウィンドウシステムの選択(ウィンドウシステムによる選択を参照)との相互作用にも留意するので、Lispプログラム内での使用に関しても依然として有用です。

Function: current-kill n &optional do-not-move

関数current-killはkillリングの先頭を指すyankポインターを、(新しいkillから古いkillに) n個転回して、リング内のその箇所のテキストをリターンする。

オプションの第2引数do-not-moveが非nilなら、current-killはyankポインターを変更しない。カレントyankポインターからn個目のkillを単にリターンする。

nが0ならそれは最新のkillの要求を意味しており、current-killはkillリング照会前にinterprogram-paste-function(以下参照)の値を呼び出す。その値が関数で、かつそれが文字列か複数の文字列からなるリストをリターンすると、current-killはその文字列をkillリング上にpushして最初の文字列をリターンする。これはdo-not-moveの値に関わらず、interprogram-paste-functionがリターンする最初の文字列のkillリングエントリーを指すようにyankポインターのセットも行う。それ以外ではcurrent-killnにたいする0値を特別に扱うことはなく、yankポインターが指すエントリーをリターンしてyankポインターの移動は行わない。

Function: kill-new string &optional replace

この関数はテキストstringをkillリング上にpushしてyankポインターがそれを指すようにセットする。それが適切なら、もっとも古いエントリーを破棄する。 interprogram-paste-functioninterprogram-paste-function (ユーザーオプションsave-interprogram-paste-before-killにしたがう)とinterprogram-cut-function (以下参照)の値の呼び出しも行う。

replaceが非nilならkill-newはkillリング上にstringをpushせずに、killリングの1つ目の要素をstringに置き換える。

Function: kill-append string before-p

この関数はkillリング内の最初のエントリーにテキストstringを追加して、その結合されたエントリーを指すようにyankポインターをセットする。通常はそのエントリーの終端にstringが追加されるが、before-pが非nilならエントリーの先頭に追加される。この関数はサブルーチンとしてkill-newも呼び出すのでinterprogram-cut-functionとおそらくinterprogram-paste-functionの値(以下参照)が拡張により呼び出される。

Variable: interprogram-paste-function

この変数は他のプログラムからkillリングへkillされたテキストを転送する方法を提供する。値はnil、または引数のない関数であること。

値が関数なら、もっとも最近のkillを取得するためにcurrent-killはそれを呼び出す。その関数が非nil値をリターンすると、その値がもっとも最近のkillとして使用される。nilをリターンしたらkillリングの先頭が使用される。

複数選択をサポートするウィンドウシステムのサポートを容易にするために、この関数は文字列のリストをリターンすることもある。その場合には1つ目の文字列がもっとも最近のkillとして使用され、その他の文字列はすべてyank-popによるアクセスを容易にするためにkillリング上にpushされる。

この関数の通常の用途は、たとえそれが他アプリケーションに属する選択であっても、もっとも最近のkillとしてウィンドウシステムのクリップボードからそれを取得することである。しかしクリップボードのコンテンツがカレントEmacsセッションに由来するなら、この関数はnilをリターンする筈である。

Variable: interprogram-cut-function

この変数はウィンドウシステム使用時に、他のプログラムにkillされたテキストを転送する方法を提供する。値はnil、または1つの引数を要求する関数であること。

値が関数ならkill-newkill-appendはkillリングの新たな1つ目要素を引数としてそれを呼び出す。

この関数の通常の用途は、新たにkillされたテキストをウィンドウシステムのクリップボードに配置することである。ウィンドウシステムによる選択を参照のこと。


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

33.8.6 killリングの内部

変数kill-ringは、文字列リスト形式でkillリングのコンテンツを保持します。もっとも最近のkillが常にこのリストの先頭になります。

変数kill-ring-yank-pointerは、CARが次のyankのテキストであるような、killリングリスト内のリンクをpointします。これをリングの先頭を識別すると言います。そして、kill-ring-yank-pointerを異なるリンクに移動することをkillリングの転回(rotating the kill ring)と呼びます。yankポインターを移動する関数はyankポインターをリスト終端から先頭、またはその逆へラップするのでkillリングを“ring”と呼びます。killリングの転回は仮想的なものであってkill-ringの値は変更しません。

kill-ringkill-ring-yank-pointerはいずれも、通常は値がリストであるようなLisp変数です。kill-ring-yank-pointerの名前にある単語“pointer”は、その変数の目的が次回yankコマンドにより使用されるリストの最初の要素を指すことであることを示します。

kill-ring-yank-pointerの値は常にkillリングリスト内の1つのリンクとeqです。それが指す要素は、そのリンクのCARです。killリングを変更するkillコマンドも、この変数にkill-ringの値をセットします。その効果は新たにkillされた先頭になるように、リングを転回することです。

以下は変数kill-ring-yank-pointerが、killリング("some text" "a different piece of text" "yet older text")内の2番目のエントリーを指すことを表すダイアグラムです。

kill-ring                  ---- kill-ring-yank-pointer
  |                       |
  |                       v
  |     --- ---          --- ---      --- ---
   --> |   |   |------> |   |   |--> |   |   |--> nil
        --- ---          --- ---      --- ---
         |                |            |
         |                |            |
         |                |             -->"yet older text"
         |                |
         |                 --> "a different piece of text"
         |
          --> "some text"

この状態はC-y (yank)の直後にM-y (yank-pop)を行うことにより発生し得ます。

Variable: kill-ring

この変数はもっとも最近にkillされたテキストが先頭になるように、killされたテキストのシーケンスのリストを保持する。

Variable: kill-ring-yank-pointer

この変数の値は、yankにたいして使用されるkillリングの先頭にある要素を示す。より正確には値はkill-ringの値のtail値であり、そのCARC-yによりyankされるはずのkill文字列。

User Option: kill-ring-max

この変数の値は、リング終端の要素を破棄する前にkillリングが成長し得る最大長。kill-ring-maxのデフォルト値は120。


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

33.9 アンドゥ

ほとんどのバッファーは、バッファーのテキストにたいして行われた変更をundoできるように、すべての変更を記録するundoリスト(undo list)をもっています(undoリストをもたないバッファーとは通常はEmacsがundoを有用とみなさない特殊用途のバッファーである。特に名前がスペースで始まるバッファーはすべてundoの記録がデフォルトでオフになっている。バッファーの名前を参照)。バッファー内でテキストを変更するすべてのプリミティブはundoリストの先頭に自動的に要素を追加して、それは変数buffer-undo-listに格納されます。

Variable: buffer-undo-list

このバッファーローカル変数の値は、カレントバッファーのundoリスト。値がtならundo情報の記録を無効にする。

以下はundoリストが保有可能な要素の種類です:

position

この種の要素は前のポイント値を記録する。この要素をundoすることによりポイントはpositionに移動する。通常のカーソル移動はどのような類のundo記録も作成しないが、削除操作はそのコマンド以前にポイントがあった場所を記録するためにこのエントリーを使用する。

(beg . end)

この種の要素は挿入されたテキストを削除する方法を示す。挿入においてそのテキストはバッファー内の範囲begからendを占める。

(text . position)

この種の要素は削除されたテキストを再度挿入する方法を示す。文字列textは削除されたテキストそのもの。削除されたテキストを再挿入する位置は(abs position)positionが正ならポイントがあったのは削除されたテキストの先頭、それ以外では末尾。この要素の直後に0個以上の(marker . adjustment)要素が続く。

(t . time-flag)

この種の要素は未変更のバッファーが変更されたことを示す。time-flag (非整数のLispタイムスタンプ)は、visitされたファイルにたいしてそれが以前にvisitや保存されたときの更新時刻(modification time)を、current-timeと同じ形式を用いて表す。時刻を参照のこと。time-flagが0ならそのバッファーに対応するファイルがないことを、-1ならvisitされたファイルは以前は存在しなかったことを意味する。primitive-undoはバッファーを再度未変更とマークするかどうかを判断するために、これらの値を使用する(ファイルの状態がtime-flagのそれとマッチする場合のみ未変更とマーク)。

(nil property value beg . end)

この種の要素はテキストプロパティの変更を記録する。変更をundoする方法は以下のようになる:

(put-text-property beg end property value)
(marker . adjustment)

この種の要素はマーカーmarkerがそれを取り囲むテキストの削除により再配置されて、adjustment文字位置を移動したということを記録する。undoリスト内の前にある要素(text . position)とマーカーの位置が一致する場合には、この要素をundoすることによりmarker - adjustment文字移動する。

(apply funname . args)

これは拡張可能なundoアイテムであり、引数argsとともにfunnameを呼び出すことによりundoが行われる。

(apply delta beg end funname . args)

これは拡張可能なundoアイテムであり、begからendまでに限定された範囲にたいして、そのバッファーのサイズをdelta文字増加させる変更を記録する。これは引数argsとともにfunnameを呼び出すことによりundoが行われる。

この種の要素は、それがリージョンと関係するか否かを判断することによりリージョンに限定されたundoを有効にする。

nil

この要素は境界(boundary)である。2つの境界の間にある要素を変更グループ(change group)と呼び、それぞれの変更グループは通常1つのキーボードコマンドに対応するとともに、undoコマンドは通常はグループを1つの単位として全体をundoを行う。

Function: undo-boundary

この関数はundoリスト内に境界を配置する。このような境界ごとにundoコマンドは停止して、連続するundoコマンドは、より以前の境界へとundoを行っていく。この関数はnilをリターンする。

この関数を明示的に呼び出すことは、あるコマンドの効果を複数単位に分割するために有用である。たとえばquery-replaceはユーザーが個別に置換をundoできるように、それぞれの置換後にundo-boundaryを呼び出している。

しかしほとんどの場合には、この関数は適切なタイミングで自動的に呼び出される。

Function: undo-auto-amalgamate

エディターコマンドループは各アンドゥがが通常はそれぞれ1つのコマンドの効果をアンドゥするように、各キーシーケンスを実行する直前にundo-boundaryを呼び出す。少数の例外は融合(amalgamating)コマンドである。これらのコマンドは一般的にバッファーにたいして小さい変更を発生させるので、変更をグループとしてアンドゥできるように、20回目のコマンドごとに境界が挿入される。デフォルトでは自己挿入入力文字を生成するコマンドself-insert-command (ユーザーレベルの挿入コマンドを参照)、文字を削除するコマンドdelete-char (テキストの削除を参照)は融合コマンドである。複数バッファーのコンテンツに影響するコマンド、たとえば発生し得るとすればpost-command-hook上の関数がcurrent-buffer以外のバッファーに影響を及ぼす場合には、影響を受ける各バッファーごとにundo-boundaryが呼び出されるだろう。

この関数を融合コマンドの前に呼び出すことができる。そのような一連の呼び出しが行われていると、以前のundo-boundaryは削除される。

融合可能な最大の変更数はamalgamating-undo-limit変数で制御される。この変数が1なら変更は融合されない。

Lispプログラムはundo-amalgamate-change-groupを呼び出すことによって、一連の変更を単一の変更グループにまとめることができます(グループのアトミックな変更を参照)。この関数で生成したグループにたいしてamalgamating-undo-limitは効果がないことに注意してください。

Variable: undo-auto-current-boundary-timer

プロセスバッファーのようないくつかのバッファーでは、何もコマンドを実行していなくても変更が発生し得る。このような場合には、通常はundo-boundaryこの変数内のタイマーにより定期的に呼び出される。この挙動を抑制するには、この変数を非nilにセットすること。

Variable: undo-in-progress

この変数は通常はnilだが、undoコマンドはこれをtにバインドする。これによりさまざまな種類の変更フックがundoにより呼び出された際に、それを告げることが可能になる。

Function: primitive-undo count list

これはundoリストの要素のundoにたいする基本的な関数。これはlistの最初のcount要素をundoしてlistの残りをリターンする。

primitive-undoはバッファー変更時に、そのバッファーのundoリストに要素を追加する。undoコマンドは混乱を避けるためにundo操作シーケンス冒頭にundoリストの値を保存する。その後でundo操作は保存された値の使用と更新を行う。undoにより追加された新たな要素はこの保存値の一部でないので継続するundoと干渉しない。

この関数はundo-in-progressをバインドしない。

Macro: with-undo-amalgamate body…

このマクロはbodyの実行中に挿入されたundo境界を削除して、一度にまとめてundoできるようにする。

いくつかのコマンは、コマンドの選択的なアンドゥを妨害する方法により、実行後にリージョンをアクティブなままにします。undoをそのようなコマンドの直後に呼び出した際にアクティブなリージョンを無視するには、コマンドの関数シンボルのundo-inhibit-regionプロパティに非nil値をセットします。シンボルの標準的なプロパティを参照してください。


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

33.10 アンドゥリストの保守

このセクションでは与えられたバッファーにたいしてundo情報を有効や無効にする方法を説明します。undoリストが巨大化しないようにundoリストを切り詰める方法も説明します。

新たに作成されたバッファー内のundo情報記録は、通常は開始とともに有効になります。しかしバッファー名がスペースで始まる場合には、undoの記録は初期状態では無効になっています。以下の2つの関数、または自身でbuffer-undo-listをセットすることにより、undo記録の有効化や無効化を明示的に行うことができます。

Command: buffer-enable-undo &optional buffer-or-name

このコマンドは以降の変更をundo可能にするように、バッファーbuffer-or-nameのundo情報記録を有効にする。引数が与えられなければカレントバッファーを使用する。そのバッファー内のundo記録がすでに有効ならこの関数は何も行わない。リターン値はnil

インタラクティブな呼び出しではbuffer-or-nameはカレントバッファーであり、他のバッファーを指定することはできない。

Command: buffer-disable-undo &optional buffer-or-name

この関数はbuffer-or-nameのundoリストを破棄して、それ以上のundo情報記録を無効にする。結果として以前の変更と以後のすべての変更にたいするそれ以上のundoは不可能になる。buffer-or-nameのundoリストがすでに無効ならこの関数に効果はない。

インタラクティブな呼び出しではBUFFER-OR-NAMEはカレントバッファー。他のバッファーを指定することはできない。リターン値はnil

編集が継続されるにつれてundoリストは次第に長くなっていきます。利用可能なメモリー空間すべてを使い尽くすのを防ぐために、ガベージコレクションがundoリストを設定可能な制限サイズに切り詰めて戻します(この目的のためにundoリストのサイズはリストを構成するコンスセルに加えて削除された文字列により算出される)。undo-limitundo-strong-limitundo-outer-limitの3つの変数は、許容できるサイズの範囲を制御します。これらの変数においてサイズは専有するバイト数で計数され、それには保存されたテキストとその他データが含まれます。

User Option: undo-limit

これは許容できるundoリストサイズのソフトリミット。このサイズを超過した箇所の変更グループは最新の変更グループ1つが保持される。

User Option: undo-strong-limit

これはundoリストの許容できるサイズの上限。このサイズを超過する箇所の変更グループは(その他すべてのより古い変更グループとともに)自身を破棄する。1つ例外がありundo-outer-limitを超過すると最新の変更グループだけが破棄される。

User Option: undo-outer-limit

ガベージコレクション時にカレントコマンドのundo情報がこの制限を超過したら、Emacsはその情報を破棄して警告を表示する。これはメモリーオーバーフローを防ぐための最後の回避用リミットである。

User Option: undo-ask-before-discard

この変数が非nilならundo情報のundo-outer-limit超過時に、Emacsはその情報を破棄するかどうかをエコーエリアで尋ねる。デフォルト値はnilでこれは自動的な破棄を意味する。

このオプションは主にデバッグを意図している。これを尋ねる際にはガベージコレクションは抑制されており、もしユーザーがその問にたいして答えるのをあまりに長くかかるなら、Emacsがメモリーリークを起こすかもしれないことを意味する。


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

33.11 fill

フィル(fill: 充填)とは、指定された最大幅付近(ただし超過せず)に、(行ブレークを移動することにより)行の長さを調整することを意味します。加えて複数行を位置揃え(justify)することもできます。位置揃えとはスペースを挿入して左および/または右マージンを正確に整列させることを意味します。その幅は変数fill-columnにより制御されます。読みやすくするために行の長さは70列程度を超えないようにするべきです。

テキストの挿入とともに自動的にテキストをフィルするAuto Fillモードを使用できますが、既存テキストの変更では不適切にフィルされたままになるかもしれません。その場合にはテキストを明示的にフィルしなければなりません。

このセクションのコマンドのほとんどは有意な値をリターンしません。フィルを行うすべての関数はカレント左マージン、カレント右マージン、カレント位置揃えスタイルに留意します(fillのマージンを参照)。カレント位置揃えスタイルがnoneなら、フィル関数は実際には何も行いません。

フィル関数のいくつかは引数justifyを受け取ります。これが非nilなら、それは何らかの類の位置揃えを要求します。特定の位置揃えスタイルを要求するためにleftrightfullcenterを指定できます。これがtなら、それはそのテキスト部分にたいしてカレント位置揃えスタイルを使用することを意味します(以下のcurrent-justificationを参照)。その他すべての値はfullとして扱われます。

インタラクティブにフィル関数を呼び出すには際、プレフィクス引数の使用はjustifyにたいして暗に値fullを指定します。

Command: fill-paragraph &optional justify region

このコマンドはポイント位置、またはその後のパラグラフ(paragraph: 段落)をフィルする。justifyが非nilなら、同様に各行が位置揃えされる。これはパラグラフ境界を探すために、通常のパラグラフ移動コマンドを使用する。Paragraphs in The GNU Emacs Manualを参照のこと。

もしregionが非nilで、Transient Markモードが有効かつマークがアクティブなら、このコマンドはカレントパラグラフのみフィルするかわりに、リージョン内すべてのパラグラフをフィルするためにコマンドfill-regionを呼び出す。このコマンドがインタラクティブに呼び出された際は、regiont

Command: fill-region start end &optional justify nosqueeze to-eop

このコマンドはstartからendのリージョン内のすべてのパラグラフをフィルする。justifyが非nilなら同様に位置揃えも行う。

nosqueezeが非nilなら、それは行ブレーク以外の空白文字を残すことを意味する。to-eopが非nilなら、それはパラグラフ終端(以下のuse-hard-newlinesが有効なら次のhard改行)までのフィルを維持することを意味する。

変数paragraph-separateはパラグラフを分割する方法を制御する。編集で使用される標準的な正規表現を参照のこと。

Function: pixel-fill-region start end pixel-width

Emacsのほとんどのバッファーでは文字数とchar-widthにもとづいて(fill-regionのような)fill関数が機能するように、等幅(monospace)のテキストを使用する。しかしEmacsは可変幅フォント(proportional font)を使ったイメージを含むテキストのような、他のタイプのオブジェクトを描画でき、正にこれを処理するために存在するのがpixel-fill-regionである。これはstartendの間にあるリージョンのテキストをピクセル単位の粒度でfillするので、可変ピッチのフォントや異なるいくつかのフォントはサイズに関わらずfillされるようになる。引数pixel-widthはfill後に線に許容される最大のピクセル幅を指定する。これはfill-regionにおけるfill-columnのピクセル解像度に相当する。以下のLispコードはプロポーショナルフォントを用いてテキストを挿入してから、300ピクセルを超えない幅になるようにfillする例である:

(insert (propertize
	 "This is a sentence that's ends here."
	 'face 'variable-pitch))
(pixel-fill-region (point) (point-max) 300)

startが行頭にある場合には、後続行のインデントのプレックスとしてstartの水平位置をピクセル単位に変換した値が用いられる。

pixel-fill-widthはピクセル幅を計算するために使用できるヘルパー関数である。引数なしならカレントウィンドウの幅より若干小さい値をリターンする。1つ目のオプションcolumnsの値には、fill-columnが用いる標準的なモノスペースフォントによる列数を指定する。2つ目のオプションの値は使用するウィンドウである。典型的には以下のように使用する:

(pixel-fill-region
  start end (pixel-fill-width fill-column))
Command: fill-individual-paragraphs start end &optional justify citation-regexp

このコマンドはリージョン内の各パラグラフを、それの固有なフィルプレフィクスに応じてフィルする。したがってパラグラフの行がスペースでインデントされていれば、フィルされたパラグラフは同じ様式でインデントされた状態に保たれるだろう。

最初の2つの引数startendはフィルするリージョンの先頭と終端。3つ目の引数justify、4つ目の引数citation-regexpはオプション。justifyが非nilなら、そのパラグラフはフィルと同様に位置揃えも行われる。citation-regexpが非nilなら、それはこの関数がメールメッセージを処理しているのでヘッダーラインをフィルするべきではないことを意味する。citation-regexpが文字列なら、それは正規表現として扱われる。それが行の先頭にマッチすれば、その行は引用マーカー(citation marker)として扱われる。

fill-individual-paragraphsは通常はインデントの変更を新たなパラグラフの開始とみなす。fill-individual-varying-indentが非nilならセパレーターラインだけがパラグラフを分割する。その場合には、最初の行からさらにインデントが追加されたパラグラフを処理することが可能になる。

User Option: fill-individual-varying-indent

この変数は上述のようにfill-individual-paragraphsの動作を変更する。

Command: fill-region-as-paragraph start end &optional justify nosqueeze squeeze-after

このコマンドはテキストのリージョンを1つのパラグラフとみなしてそれをフィルする。そのリージョンが多数のパラグラフから構成されていたらパラグラフ間の空行は削除される。justifyが非nilならフィルとともに位置揃えも行う。

nosqueezeが非nilなら、それは改行以外の空白に手を加えずに残すことを意味する。squeeze-afterが非nilなら、それはリージョン内の位置を指定して、その位置より前にある改行以外の空白文字に手を加えず残すことを意味する。

Adaptive Fillモードでは、このコマンドはフィルプレフィクスを選択するためにデフォルトでfill-context-prefixを呼び出す。Adaptive Fillモードを参照のこと。

Command: justify-current-line &optional how eop nosqueeze

このコマンドはその行が正確にfill-columnで終わるように単語間にスペースを挿入する。リターン値はnil

引数howが非nilなら、それは位置揃えスタイルを明示的に指定する。指定できる値はleftrightfullcenter、またはnone。値がtなら指定済みの位置揃えスタイル(以下のcurrent-justificationを参照)にしたがうことを意味する。nilは位置揃えfullと同じ。

eopが非nilなら、それはcurrent-justificationがfull位置揃えを指定する場合にleft位置揃えだけを行うことを意味する。これはパラグラフ最終行にたいして使用される。パラグラフ全体がfull位置揃えだったとしても最終行はfull位置揃えであるべきではない。

nosqueezeが非nilなら、それは内部のスペースを変更しないことを意味する。

User Option: default-justification

この変数の値は位置揃えに使用するスタイルをテキストプロパティで指定しないテキストにたいするスタイルを指定する。可能な値はleftrightfullcenter、またはnone。デフォルト値はleft

Function: current-justification

この関数はポイント周辺のフィルに使用するための適正な位置揃えスタイルをリターンする。

これはポイント位置のテキストプロパティjustificationの値、そのようなテキストプロパティが存在しなければ変数default-justificationの値をリターンする。しかし“位置揃えなし”なら、noneではなくnilをリターンする。

User Option: sentence-end-double-space

この変数が非nilならピリオドの後の単一のスペースをセンテンスの終わりとみなさず、フィル関数はそのような箇所でのラインブレークを行わない。

User Option: sentence-end-without-period

この変数が非nilなら、ピリオドなしでセンテンスは終了できる。これはたとえばピリオドなしの2連スペースでセンテンスが終わるタイ語などに使用される。

User Option: sentence-end-without-space

この変数が非nilなら、それは後にスペースをともなうことなくセンテンスを終了させ得る文字列であること。

User Option: fill-separate-heterogeneous-words-with-space

この変数が非nilなら異種(たとえば英語のCJK)の2つの単語は一方が行末にあり、もう一方が次行の先頭にある場合にはフィルでの結合時にスペースで分割される。

Variable: fill-paragraph-function

この変数はパラグラフのフィルをオーバーライドする手段を提供する。この値が非nilなら、fill-paragraphはその処理を行うためにその関数を呼び出す。その関数が非nil値をリターンすると、fill-paragraphは処理が終了したとみなして即座にその値をリターンする。

この機能の通常の用途はプログラミング言語のモードにおいてコメントをフィルすることである。通常の方法でその関数がパラグラフをフィルする必要があるなら、以下のようにそれを行うことができる:

(let ((fill-paragraph-function nil))
  (fill-paragraph arg))
Variable: fill-forward-paragraph-function

この変数はfill-regionfill-paragraphのようなフィル関数が次のパラグラフへ前方に移動する方法をオーバーライドするための手段を提供する。値は移動するパラグラフの数nを唯一の引数として呼び出される関数であり、nと実際に移動したパラグラフ数の差をリターンすること。この変数のデフォルト値はforward-paragraphParagraphs in The GNU Emacs Manualを参照のこと。

Variable: use-hard-newlines

この変数が非nilなら、フィル関数はテキストプロパティhardをもつ改行を削除しない。これらのhard改行、パラグラフのセパレーターとして機能する。Hard and Soft Newlines in The GNU Emacs Manualを参照のこと。


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

33.12 fillのマージン

User Option: fill-prefix

このバッファーローカル変数が非nilなら、それは通常のテキスト行の先頭に出現して、それらのテキスト行をフィルする際には無視されるべきテキスト文字列を指定する。そのフィルプレフィクスで始まらない行はパラグラフの開始とみなされ、フィルプレフィクスで始まる行はその後にスペースが追加される。フィルプレフィクスで始まりその後に追加のスペースがない行はフィル可能な通常のテキスト行。結果となるフィル済みの行もフィルプレフィクスで開始される。

もしあればフィルプレフィクスは左マージンのスペースの後になる。

User Option: fill-column

このバッファーローカル変数はフィルされる行の最大幅を指定する。値は列数を表す整数であること。Auto Fillモード(オートfillを参照)を含むフィル、位置揃え、センタリングを行うすべてのコマンドがこの変数の影響を受ける。

実際の問題として他の人が読むためのテキストを記述する場合には、fill-columnを70より大きくするべきではない。これにしたがわないと人が快適に読むには行が長くなり過ぎてしまい、下手に記述されたテキストに見えてしまうだろう。

fill-columnのデフォルト値は70。特定のモードでAuto Fillモードを無効にするには以下のように記述できる:

(add-hook 'foo-mode-hook (lambda () (auto-fill-mode -1))
Command: set-left-margin from to margin

これはfromからtoのテキストのleft-marginプロパティに値marginをセットする。Auto Fillモードが有効なら、このコマンドは新たなマージンにフィットするようにリージョンの再フィルも行う。

Command: set-right-margin from to margin

これはfromからtoのテキストのright-marginプロパティに値marginをセットする。Auto Fillモードが有効なら、このコマンドは新たなマージンにフィットするようにリージョンの再フィルも行う。

Function: current-left-margin

この関数はポイント周辺をフィルするために使用する、適切な左マージン値をリターンする。値はカレント行開始文字のleft-marginプロパティの値(なければ0)と変数left-marginの値の合計。

Function: current-fill-column

この関数はポイント周辺のテキストをフィルするために使用する、適切なフィル列値をリターンする。値は変数fill-columnからポイント後の文字のright-marginプロパティの値を減じた値。

Command: move-to-left-margin &optional n force

この関数はカレント行の左マージンにポイントを移動する。移動先の列は関数current-left-marginにより決定される。引数nが非nilなら、まずmove-to-left-marginn行前方に移動する。

forceが非nilなら、それは行のインデントが左マージン値とマッチしなければインデントを修正するように指定する。

Function: delete-to-left-margin &optional from to

この関数はfromからtoの間のテキストから左マージンのインデントを取り除く。削除するインデントの量はcurrent-left-marginを呼び出すことにより決定される。この関数が非空白文字を削除することはない。fromtoが省略された場合のデフォルトはそのバッファー全体。

Function: indent-to-left-margin

この関数はカレント行の先頭のインデントを変数left-marginに指定された値に調整する(これにより空白文字の挿入や削除が起こるかもしれない)。Paragraph-Indent Textモード内の変数indent-line-functionの値はこの関数。

User Option: left-margin

この変数は左マージンの基本列を指定する。Fundamentalモードでは、RETはこの列にインデントする。この変数は手段の如何を問わずセットされると自動的にバッファーローカルになる。

User Option: fill-nobreak-predicate

この変数はメジャーモードにたいして、特定の箇所で行ブレークしないように指定する手段を提供する。値は関数のリストであること。フィルがバッファー内の特定箇所で行ブレークすると判断されるときは、常にその箇所にポイントを置いた状態でこれらの関数を引数なしで呼び出す。これらの関数のいずれかが非nilをリターンすると、その行のその箇所では行ブレークしない。


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

33.13 Adaptive Fillモード

Adaptive Fillモードが有効なとき、Emacsは事前定義された値を使用するのではなく、フィルされる各パラグラフのテキストから自動的にフィルプレフィクスを決定します。fillオートfillで説明されているように、このフィルプレフィクスはフィルの間にそのパラグラフの2行目以降の行頭に挿入されます。

User Option: adaptive-fill-mode

この変数が非nilならAdaptive Fillモードは有効。デフォルトはt

Function: fill-context-prefix from to

この関数はAdaptive Fillモード実装の肝である。これはfromからto、通常はパラグラフの開始から終了にあるテキストにもとづいてフィルプレフィクスを選択する。これは以下で説明する変数にもとづき、そのパラグラフの最初の2行を調べることによりこれを行う。

この関数は通常は文字列としてフィルプレフィクスをリターンする。しかしこれを行う前に、この関数はそのプレフィクスで始まる行がパラグラフの開始とは見えないだろうか、最終チェックを行う(以降では特に明記しない)。これが発生した場合には、この関数はかわりにnilをリターンすることにより異常を通知する。

以下はfill-context-prefixが行う詳細:

  1. 1行目からフィルプレフィクス候補を取得するために、(もしあれば)まずadaptive-fill-function内の関数、次にadaptive-fill-regexp (以下参照)の正規表現を試みる。これらの非nilの最初の結果、いずれもnilなら空文字列が1行目の候補となる。
  2. そのパラグラフが1行だけなら、関数は見つかったプレフィクス候補の妥当性をテストする。その後でこの関数はそれが妥当ならその候補を、それ以外はスペース文字列をリターンする(以下のadaptive-fill-first-line-regexpの説明を参照)。
  3. すでにそのパラグラフが2行以上なら、この関数は次に1行目にたいして行なったのとまったく同じ方法で2行目でプレフィクス候補を探す。見つからなければnilをリターンする。
  4. ここでこの関数は発見的手法により2つのプレフィクス候補を比較する。2行目の候補の非空白文字の並びが1行目の候補と同じなら、この関数は2行目の候補をリターンする。それ以外では2つの候補に共通するもっとも長い先頭の部分文字列(これは空文字列かもしれない)をリターンする。
User Option: adaptive-fill-regexp

Adaptive Fillモードは、(もしあれば)行の左マージン空白文字の後から開始されるテキストにたいしてこの正規表現をマッチする。マッチする文字列がその行のフィルプレフィクス候補。

デフォルト値は空白文字と特定の句読点文字が混在した文字列にマッチする。

User Option: adaptive-fill-first-line-regexp

この正規表現は1行だけのパラグラフに使用され、1つの可能なフィルプレフィクス候補の追加の妥当性評価として機能する。その候補はこの正規表現にマッチするか、comment-start-skipにマッチしなければならない。マッチしなければfill-context-prefixはその候補を同じ幅のスペース文字列に置き換える。

この変数のデフォルト値は "\\`[ \t]*\\'"であり、これは空白文字列だけにマッチする。このデフォルトの効果は1行パラグラフで見つかったフィルプレフィクスが、常に純粋な空白文字となるよう強制することである。

User Option: adaptive-fill-function

この変数に関数をセットすることにより、自動的なフィルプレフィクス選択にたいしてより複雑な方法を指定することが可能になる。その関数は、(もしあれば)行の左マージンの後のポイントで呼び出され、かつポイントを保たなければならない。その関数はその行のフィルプレフィクス、またはプレフィクスの判断に失敗したことを意味するnilのいずれかをリターンすること。


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

33.14 オートfill

Auto Fillモードはテキスト挿入とともに自動的に行をフィルするマイナーモードです。Auto Fill in The GNU Emacs Manualを参照してください。このセクションではAuto Fillモードにより使用される変数をいくつか説明します。既存テキストを明示的にフィルしたり位置揃えすることができる関数の説明はfillを参照してください。

Auto Fillモードではテキスの一部を再フィルするためにマージンや位置揃えを変更する関数も利用できます。fillのマージンを参照してください。

Variable: auto-fill-function

このバッファーローカル変数の値はテーブルauto-fill-chars (以下参照)からの文字の自己挿入後に呼び出される関数(引数なし)であること。nilでもよく、その場合は特に何もしない。

Auto Fillモードが有効ならauto-fill-functionの値はdo-auto-fill。これは行ブレークにたいする通常のストラテジーを実装することを唯一の目的とする関数である。

Variable: normal-auto-fill-function

この変数はAuto Fillがオンのときはauto-fill-functionにたいして使用する関数を指定する。Auto Fillの動作方法を変更するためにメジャーモードはこの変数にバッファーローカル値をセットできる。

Variable: auto-fill-chars

文字が自己挿入された際にauto-fill-functionを呼び出す文字からなる文字テーブル(ほとんどの言語環境においてはスペースと改行)。

User Option: comment-auto-fill-only-comments

この変数が非nilなら行のフィルは自動的にコメントだけになる。より正確にはカレントバッファーにたいしてコメント構文が定義されていれば、コメントの外側の自己挿入文字がauto-fill-functionを呼び出さないことを意味する。


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

33.15 テキストのソート

このセクションで説明するソート関数は、すべてバッファー内のテキストを再配置します。これはリスト要素を再配置するsort関数とは対照的です(see リストを再配置する関数)。これらの関数がリターンする値に意味はありません。

Function: sort-subr reverse nextrecfun endrecfun &optional startkeyfun endkeyfun predicate

この関数はバッファーをレコードに細分してそれらをソートする一般的なテキストソートルーチン。このセクションのコマンドのほとんどは、この関数を使用する。

sort-subrが機能する方法を理解するためには、バッファーのアクセス可能範囲をソートレコード(sort records)と呼ばれる分離された断片に分割すると考えればよい。レコードは連続、あるいは非連続かもしれないがオーバーラップしてはならない。各ソートレコードの一部(全体かもしれない)はソートキーとして指定される。これらソートキーによるソートによりレコードは再配置される。

レコードは通常はソートキー昇順で再配置される。sort-subrの1つ目の引数reverseが非nilならレコードはソートキー降順にソートされて再配置される。

sort-subrにたいする以下の4つの引数は、ソートレコード間でポイントを移動するために呼び出される。これらはsort-subr内で頻繁に呼び出される。

  1. nextrecfunはレコード終端のポイントで呼び出される。この関数は次のレコードの先頭にポイントを移動する。sort-subrが呼び出された際には、ポイント位置が1つ目のレコードの開始とみなされる。したがってsort-subrを呼び出す前は、通常はそのバッファーの先頭にポイントを移動すること。

    この関数はバッファー終端にポイントを残すことにより、それ以上のソートレコードがないことを示すことができるできる。

  2. endrecfunはレコード内にあるポイントで呼び出される。これはレコード終端にポイントを移動する。
  3. startkeyfunはポイントをレコード先頭からソートキー先頭に移動する。この引数はオプションで、省略された場合はレコード全体がソートキーとなる。もし与えられた場合には、その関数はソートキーとして使用する非nil値、またはnil (ソートキーはそのバッファー内のポイント位置から始まることを示す)のいずれかをリターンすること。後者の場合にはソートキー終端を見るけるためにendkeyfunが呼び出される。
  4. endkeyfunはソートキー先頭からソートキー終端にポイントを移動するために呼び出される。引数はオプション。startkeyfunnilをリターンし、かつこの引数が省略(またはnil)の場合には、そのソートキーはレコード終端まで拡張される。startkeyfunが非nil値をリターンした場合にはendkeyfunは不要。

引数predicateはキーの比較に使用する関数。この関数は引数として比較する2つのキーを受け取り、1つ目のキーが2つ目のキーよりソート順で前なら非nilをリターンすること。引数のキーが正確に何であるかはstartkeyfunendkeyfunがリターンする値に依存する。predicateが省略またはnilの場合のデフォルトはキーが数値なら<、キーがコンスセル(carがキーのバッファー位置の開始でcdrが終了)ならcompare-buffer-substrings、それ以外ならstring< (キーを文字列とみなす)。

sort-subrの例として以下はsort-lines関数の完全な定義である:

;; ドキュメント文字列の冒頭2行は
;; ユーザー閲覧時には1行となることに注意
(defun sort-lines (reverse beg end)
  "リージョン内の行をアルファベット順にソート;\
 引数は降順を意味する
プログラムから呼び出す場合は、以下の3つの引数がある:
REVERSE(非nilは逆順の意)、\
およびBEGとEND(ソートするリージョン)
変数`sort-fold-case'は英字\
大文字小文字の違いが
ソート順に影響するかどうかを決定する"
  (interactive "P\nr")
  (save-excursion
    (save-restriction
      (narrow-to-region beg end)
      (goto-char (point-min))
      (let ((inhibit-field-text-motion t))
        (sort-subr reverse 'forward-line 'end-of-line)))))

ここでforward-lineは次のレコードの先頭にポイントを移動して、end-of-lineはレコードの終端にポイントを移動する。レコード全体をソートキーとするので引数startkeyfunendkeyfunは渡していない。

sort-paragraphsはほとんど同じだが、sort-subrの呼び出しが以下のようになる:

(sort-subr reverse
           (lambda ()
             (while (and (not (eobp))
                         (looking-at paragraph-separate))
               (forward-line 1)))
           'forward-paragraph)

ソートレコード内を指す任意のマーカーは、sort-subrリターン後は無意味なマーカー位置のまま取り残される。

User Option: sort-fold-case

この変数が非nilなら、sort-subrとその他のバッファーソート関数は文字列比較時にcase(大文字小文字)の違いを無視する。

Command: sort-regexp-fields reverse record-regexp key-regexp start end

このコマンドはstartからendの間のリージョンを、record-regexpkey-regexpで指定されたようにアルファベット順にソートする。reverseが負の整数なら逆順にソートする。

アルファベット順のソートとは2つのソートキーにたいして、それぞれの1つ目の文字同士、2つ目の文字同士、...のように比較することにより、キーを比較することを意味する。文字が一致しなければ、それはソートキーが不等なことを意味する。最初の不一致箇所で文字が小さいソートキーが小さいソートキーとなる。個別の文字はEmacs文字セット内の文字コードの数値に応じて比較される。

引数record-regexpの値はバッファーをソートレコードに分割する方法を指定する。各レコードの終端で、この正規表現にたいする検索は完了して、これにマッチするテキストが次のレコードとして採用される。たとえば改行の前に少なくとも1つの文字がある行にマッチする正規表現‘^.+$’は、そのような行をソートレコードとするだろう。正規表現の構文と意味については正規表現を参照のこと。

引数key-regexpの値は各レコードのどの部分がソートキーかを指定する。key-regexpはレコード全体、またはその一部にマッチすることができる。後者の場合にはレコードの残りの部分はソート順に影響しないが、レコードが新たな位置に移動される際はともに移動される。

引数key-regexprecord-regexpの部分式(subexpression)、またはその正規表現自体にマッチしたテキストを参照できる。

key-regexpには以下を指定できる:

\digit

record-regexp内でdigit番目のカッコ‘\(...\)’でグループ化によりマッチしたテキストがソートキーになる。

\&

レコード全体がソートキーとなる。

正規表現

sort-regexp-fieldsは、そのレコード内で正規表現にたいするマッチを検索する。そのようなマッチがあればそれがソートキー。レコード内にkey-regexpにたいするマッチがなければそのレコードは無視されて、そのバッファー内でのレコードの位置は変更されないことを意味する(他のレコードがそのレコードを移動するかもしれない)。

たとえばリージョン内のすべての行にたいして、最初の単語が文字‘f’で始まる行をソートすることを目論むなら、record-regexpを‘^.*$’、key-regexpを‘\<f\w*\>’にセットすること。結果は以下のような式になる

(sort-regexp-fields nil "^.*$" "\\<f\\w*\\>"
                    (region-beginning)
                    (region-end))

sort-regexp-fieldsをインタラクティブに呼び出した場合にはミニバッファー内でrecord-regexpkey-regexpの入力を求める。

Command: sort-lines reverse start end

このコマンドはstartendの間のリージョン内の行をアルファベット順にソートする。reverseが非nilなら逆順にソートする。

Command: sort-paragraphs reverse start end

このコマンドはstartendの間のリージョン内のパラグラフをアルファベット順にソートする。reverseが非nilなら逆順にソートする。

Command: sort-pages reverse start end

このコマンドはstartendの間のリージョン内のページをアルファベット順にソートする。reverseが非nilなら逆順にソートする。

Command: sort-fields field start end

このコマンドはstartendの間のリージョン内の行にたいして、各行のfield番目のフィールドをアルファベット順に比較することに行をソートする。fieldは空白文字により区切られて、1から数えられる。fieldが負なら行の終端から-field番目のフィールドでソートする。このコマンドはテーブルのソートに有用。

Command: sort-numeric-fields field start end

このコマンドはstartendの間のリージョン内の行にたいして、各行のfield番目のフィールドを数値的に比較することにより行をソートする。fieldは空白文字により区切られて、1から数えられる。リージョン内の各行の指定されたフィールドは数字を含んでいなければならない。0で始まる数字は8進数、‘0x’で始まる数字は16進数として扱われる。

fieldが負なら行の終端から-field番目のフィールドでソートする。このコマンドはテーブルのソートに有用。

User Option: sort-numeric-base

この変数はsort-numeric-fieldsにたいして数字を解析するための基本基数を指定する。

Command: sort-columns reverse &optional beg end

このコマンドはbegendの間にある行にたいして特定の列範囲をアルファベット順に比較することによりソートする。begendの列位置はソートが行われる列範囲にバインドされる。

reverseが非nilなら逆順にソートする。

このコマンドが通常と異なるのは、位置begを含む行全体と位置endを含む行全体がソートされるリージョンに含まれることである。

タブは指定された列に分割される可能性があるので、sort-columnsはタブを含むテキストを受け付けないことに注意。ソート前にM-x untabifyを使用してタブをスペースに変換すること。

可能ならユーティリティプログラムsortを呼び出すことにより、このコマンドは実際に機能する。


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

33.16 列を数える

列関数は文字位置(バッファー先頭から数えた文字数)と列位置(行先頭から数えたスクリーン文字数)を変換する関数です。

これら列関数はスクリーン上占める列数に応じて各文字を数えます。これはコントロール文字はctl-arrowの値に応じて2列または4列を、タブはtab-widthの値と、タブが始まる列の位置に依存する列数を占めるものとして数えられることを意味します。通常の表示の慣習を参照してください。

列数計算はウィンドウ幅と水平スクロール量を無視します。結果として列値は任意に大きくなる可能性があります。最初(または左端)の列は0と数えられます。列値は不可視性を別としてオーバーレイとテキストプロパティを無視します。buffer-invisibility-specで不可視のテキストを省略記号(ellipsis)として表示するように指定していないかぎり(不可視のテキストを参照)、不可視のテキストは幅が0であるとみなされます。

Function: current-column

この関数は左マージンを0として列単位で数えたポイントの水平位置をリターンする。列の位置はカレント行の開始からポイントまでの間の文字の表示上の表現すべての幅の和。

Command: move-to-column column &optional force

この関数はカレント行のcolumnにポイントを移動する。columnの計算には行の開始からポイントまでの文字の表示上の表現の幅が考慮される。

インタラクティブに呼び出された際には、columnはプレフィクス数引数の値。columnが整数でなければエラーがシグナルされる。

columnがタブのような複数列を占める文字の中間にあるために列を移動することが不可能な場合には、ポイントはその文字の終端に移動される。しかしforceが非nil、かつcolumnがタブの中間にあるなら、(indent-tabs-modenilなら)move-to-columnはタブをスペースに変換するか、(それ以外なら)その前に十分なスペースを挿入するので正確に列columnに移動することができる。それ以外の複数列文字については分割する手段がないので、force指定に関わらず異常を引き起こす恐れがある。

その行が列columnに達するほど長くない場合にも引数forceは効果をもつ。columntならその列に達するよう行端に空白を追加することを意味する。

リターン値は実際に移動した列番号。


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

33.17 インデント

インデント関数は行の先頭にある空白文字の調査、移動、変更に使用されます。行の他の箇所にある空白文字を変更できる関数もいくつかあります。列とインデントは左マージンを0として数えられます。


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

33.17.1 インデント用のプリミティブ

このセクションではインデントのカウントと挿入に使用されるプリミティブ関数について説明します。以降のセクションの関数はこれらのプリミティブを使用します。関連する関数については表示されるテキストのサイズを参照してください。

Function: current-indentation

この関数はカレント行のインデント、すなわち最初の非ブランク文字の水平位置をリターンする。行のコンテンツ全体がブランクなら、それは行終端の水平位置である。

buffer-invisibility-specで不可視のテキストを省略記号(ellipsis)として表示するように指定していないかぎり、この関数は不可視のテキストの幅を0とみなす。不可視のテキストを参照のこと。

Command: indent-to column &optional minimum

この関数はポイントからcolumnに達するまでタブとスペースでインデントを行う。minimumが指定されて、かつそれが非nilなら、たとえcolumnを超えることが要求される場合であっても、少なくともその個数のスペースが挿入される。それ以外ではポイントがすでにcolumnを超える場合には、この関数は何も行わない。値は挿入されたインデントの終端列。

挿入される空白文字は周囲のテキスト(通常は先行するテキストのみ)のテキストプロパティを継承する。テキストプロパティの粘着性を参照のこと。

User Option: indent-tabs-mode

この変数が非nilなら、インデント関数はスペースと同じようにタブを挿入でき、それ以外ではスペースだけを挿入できる。この変数はセットすることにより自動的にカレントバッファー内でバッファーローカルになる。


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

33.17.2 メジャーモードが制御するインデント

すべてのメジャーモードにとって重要な関数は、編集対象の言語にたいして正しくインデントを行うようにTABキーをカスタマイズします。このセクションではTABキーのメカニズムと、それを制御する方法について説明します。このセクションの関数は予期せぬ値をリターンします。

Command: indent-for-tab-command &optional rigid

これはほとんどの編集用モードでTABにバインドされるコマンド。これの通常の動作はカレント行のインデントだが、かわりにタブ文字の挿入やリージョンのインデントを行うこともできる。

これは以下のことを行う:

  • まずTransient Markモードが有効かどうか、そしてリージョンがアクティブかどうかをチェックする。もしそうならリージョン内のテキストすべてをインデントするためにindent-regionを呼び出す(リージョン全体のインデントを参照)。
  • それ以外ならindent-line-function内のインデント関数がindent-to-left-marginの場合、または変数tab-always-indentが挿入する文字としてタブ文字を指定する場合(以下参照)にはタブ文字を挿入する。
  • それ以外ならカレント行をインデントする。これはindent-line-function内の関数を呼び出すことにより行われる。その行がすでにインデント済みで、かつtab-always-indentの値がcomplete(以下参照)ならポイント位置のテキストの補完を試みる。

rigidが非nil (インタラクティブな場合はプレフィクス引数)なら、このコマンドが行をインデントした後、あるいはタブを挿入後に新たなインデントを反映するために、このコマンドはカレント行先頭にある釣り合いのとれた式全体も厳正にインデントする。この引数はコマンドがリージョンをインデントする場合は無視される。

Variable: indent-line-function

この変数の値はカレント行をインデントするためにindent-for-tab-command、およびその他種々のインデントコマンドにより使用される関数。これは通常はメジャーモードにより割り当てられ、たとえばLispモードはこれをlisp-indent-line、Cモードはc-indent-lineのようにセットする。デフォルト値はindent-relativeコードの自動インデントを参照のこと。

Command: indent-according-to-mode

このコマンドはカレントのメジャーモードに適した方法でカレント行をインデントするためにindent-line-function内の関数を呼び出す。

Command: newline-and-indent

この関数は改行を挿入後に、メジャーモードに応じて新たな行(挿入した改行の次の行)をインデントする。これはindent-according-to-modeを呼び出すことによりインデントを行う。

Command: reindent-then-newline-and-indent

このコマンドはカレント行の再インデント、ポイント位置への改行の挿入、その後に新たな行(挿入した改行の次の行)のインデントを行う。これはindent-according-to-modeを呼び出すことにより両方の行をインデントする。

User Option: tab-always-indent

この変数はTAB (indent-for-tab-command)コマンドの挙動のカスタマイズに使用できる。値がt(デフォルト)ならコマンドは通常はカレント行だけをインデントする。値がnilならコマンドはポイントが左マージン、またはその行のインデント内ににあるときのみカレント行をインデントして、それ以外はタブ文字を挿入する。値がcompleteならコマンドはまずカレント行のインデントを試みて、その行がすでにインデント済みならポイント位置のテキストを補完するためにcompletion-at-pointを呼び出す(通常バッファーでの補完を参照)。

User Option: tab-first-completion

tab-always-indentcompleteなら、tab-first-completion変数を介して拡張するか、それともインデントするかを更にカスタマイズできる。以下の値を使用できる:

eol

ポイントが行末にあれば補完のみ。

word

次の文字が単語構文をもたなければ補完。

word-or-paren

次の文字が単語構文やカッコでなければ補完。

word-or-paren-or-punct

次の文字が単語構文やカッコや句読点でなければ補完。

いずれの場合でも、2回目のTABの結果は常に補完となる。

いくつかのメジャーモードでは、異なるメジャーモードに所属する構文をもつ埋め込みのテキストリージョンをサポートする必要があります。これらの例にはドキュメントとソースコード断片の組み合わせである文芸的プログラミング(literate programming)のソースファイル、PythonやJSのコード断片を含んだYacc/Bisonプログラムが含まれます。埋め込みチャンクをを正しくインデントするためには、主モードがインデントをガイドする何らかのコンテキストを提供しつつ、他のモードのインデントエンジン(JSではjs-indent-line、Pythonではpython-indent-lineの呼び出し)にインデントを委譲する必要があります。メジャーモードはインデントコードでwidenの呼び出しを避けてprog-first-columnにしたがうべきです。

Variable: prog-indentation-context

この変数が非nilなら副モードのインデントエンジンにたいして上位モードが提供するインデントのコンテキストを保持する。値は(first-column . rest)という形式のリストであること。リストのメンバーは以下の意味をもつ:

first-column

トップレベルの構文にたいして使用する列。これは副モードが使用するトップレベルの列のデフォルト値(通常は0)を置き換える。

rest

現在のところ使用しない。

以下は他のメジャーモードの副モードとしての呼び出しをサポートする際に、そのメジャーモードのインデントエンジンが使用するべき便宜用の関数です。

Function: prog-first-column

トップレベルのプログラム上のコンテキストの列値にたいしてリテラル値(通常は0)を使用するかわりにこの関数を呼び出す。関数の値はトップレベルに使用する列数。上位モードの影響下になければ関数は0をリターンする。


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

33.17.3 リージョン全体のインデント

このセクションではリージョン内すべての行をインデントするコマンドを説明します。これらは予期せぬ値をリターンします。

Command: indent-region start end &optional to-column

このコマンドはstart (含む)からend (含まず)で始まる非ブランク行すべてをインデントする。to-columnnilならindent-regionはカレントモードのインデント関数、すなわちindent-line-functionの値を呼び出すことにより非ブランク行すべてをインデントする。

to-columnが非nilなら、それはインデントの列数を指定する整数であること。その場合には、この関数は空白文字を追加か削除することにより正確にその量のインデントを各行に与える。

フィルプレフィクスがある場合には、indent-regionはそのフィルプレフィクスで開始されるように各行をインデントする。

Variable: indent-region-function

この変数の値はショートカットとしてindent-regionにより使用されるかもしれない関数。その関数はリージョンの開始と終了という2つの引数を受け取ること。その関数はリージョンの行を1行ずつインデントするときと同じような結果を生成するようにデザインするべきだが、おそらくより高速になるであろう。

値がnilならショートカットは存在せずindent-regionは実際に1行ずつ機能する。

ショートカット関数はindent-line-functionが関数定義先頭をスキャンしなければならないCモードやLispモードのようなモードにたいして有用であり、それを各行に適用するためには行数の2乗に比例する時間を要するだろう。ショートカットは各行のインデントとともに移動してスキャン情報を更新でき、それは線形時間である。行を個別にインデントするのが高速なモードではショートカットの必要性はない。

引数to-columnが非nilindent-regionでは意味は異なり、この変数は使用しない。

Command: indent-rigidly start end count

この関数はstart (含む)からend (含まず)までのすべての行を横にcount列インデントする。これは影響を受けるリージョンの外観を保ち、それを厳密な単位として移動する。

これはインデントされていないテキストリージョンのインデントだけでなく、フォーマット済みコードのリージョンにたいするインデントにも有用。たとえばcountが3なら、このコマンドは指定されたリージョン内で始まるすべての行のインデントに3を追加する。

プレフィクス引数なしでインタラクティブに呼び出された場合には、このコマンドはインデントを厳密に調整するためにTransient Markモードを呼び出す。Indentation Commands in The GNU Emacs Manualを参照のこと。

Command: indent-code-rigidly start end columns &optional nochange-regexp

これはindent-rigidlyと似ているが文字列やコメントで始まる行を変更しない点が異なる。

加えて( nochange-regexpが非nilなら) nochange-regexpが行先頭にマッチする場合にはその行を変更しない。


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

33.17.4 前行に相対的なインデント

このセクションでは前の行のコンテンツにもとづいてカレント行をインデントするコマンドを2つ説明します。

Command: indent-relative &optional first-only unindented-ok

このコマンドは前の非ブランク行の次のインデントポイント(indent point)と同じ列に拡張されるように、ポイント位置に空白文字を挿入する。インデントポイントとは後に空白文字をともなった非空白文字。次のインデントポイントはポイントのカレント列より大きい、最初のインデントポイントになる。たとえばポイントがテキスト行の最初の非ブランク文字の下と左にある場合には、空白文字を挿入してその列に移動する。

前の非ブランク行に次のインデントポイントがない(列の位置が十分大きくない)場合には、( unindented-okが非nilなら)何もしないか、あるいはtab-to-tab-stopを呼び出す。したがってポイントが短いテキスト行の最後の列の下と右にある場合には、このコマンドは通常は空白文字を挿入することにより次のタブストップにポイントを移動する。

first-onlyが非nilなら、最初のインデント位置だけを考慮する。

indent-relativeのリターン値は予測できない。

以下の例ではポイントは2行目の先頭にある:

            This line is indented twelve spaces.
∗The quick brown fox jumped.

(indent-relative nil)の評価により以下が生成される:

            This line is indented twelve spaces.
            ∗The quick brown fox jumped.

次の例ではポイントは‘jumped’の‘m’と‘p’の間にある:

            This line is indented twelve spaces.
The quick brown fox jum∗ped.

(indent-relative nil)の評価により以下が生成される:

            This line is indented twelve spaces.
The quick brown fox jum  ∗ped.
Command: indent-relative-first-indent-point

このコマンドは引数first-onlytを指定してindent-relativeを呼び出すことにより、前の非ブランク行に倣ってカレント行をインデントする。リターン値は予測できない。

カレント列より先のインデントポイントが前の非ブランク行に存在しなければこのコマンドは何もしない。


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

33.17.5 調整可能なタブストップ

このセクションではユーザー指定のタブストップ(tab stops)と、それらの使用やセットするメカニズムについて説明します。“タブストップ”という名前はタイプライターのタブストップと機能が類似しているため使用されています。この機能は次のタブストップ列に到達するために、適切な数のスペースとタブを挿入することにより機能します。これはバッファー内のタブ文字の表示に影響を与えません(通常の表示の慣習を参照)。Textモードのような少数のメジャーモードだけが、TAB文字を入力としてこのタブストップ機能を使用することに注意してください。Tab Stops in The GNU Emacs Manualを参照してください。

Command: tab-to-tab-stop

このコマンドはtab-stop-listにより定義される次のタブストップ列までポイント前にスペースかタブを挿入する。

User Option: tab-stop-list

この変数はtab-to-tab-stopにより使用されるタブストップ列を定義する。これはnil、もしくは増加(均等に増加する必要はない)していく整数のリストであること。このリストは暗黙に、最後の要素と最後から2番目の要素の間隔(またはリストの要素が2未満ならtab-width)を繰り返すことにより無限に拡張される。値nilは列tab-widthごとにタブストップすることを意味する。

インタラクティブにタブストップの位置を編集するにはM-x edit-tab-stopsを使用すればよい。


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

33.17.6 インデントにもとづくモーションコマンド

以下は主にインタラクティブに使用されるコマンドであり、テキスト内のインデントにもとづいて動作します。

Command: back-to-indentation

このコマンドはカレント行(ポイントのある行のこと)の最初の非空白文字にポイントを移動する。リターン値はnil

Command: backward-to-indentation &optional arg

このコマンドは後方へarg行ポイントを移動した後に、その行の最初の非ブランク文字にポイントを移動する。リターン値はnilargが省略またはnilのときのデフォルトは1。

Command: forward-to-indentation &optional arg

このコマンドは前方へarg行ポイントを移動した後に、その行の最初の非ブランク文字にポイントを移動する。リターン値はnilargが省略またはnilのときのデフォルトは1。


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

33.18 大文字小文字の変更

ここで説明するcase(大文字小文字)変換コマンドはカレントバッファー内のテキストに作用します。文字列と文字のcase変換コマンドはLispでの大文字小文字変換、大文字や小文字に変換する文字やその変換方法のカスタマイズはcaseテーブルを参照してください。

Command: capitalize-region start end

この関数はstartendで定義されるリージョン内のすべての単語をcapitalizeする。capitalizeとは各単語の最初の文字を大文字、残りの文字を小文字に変換することを意味する。この関数はnilをリターンする。

リージョンのいずれかの端が単語の中間にある場合には、リージョン内にある部分を単語全体として扱う。

インタラクティブにcapitalize-regionが呼び出された際には、startendはポイントとマークになり小さいほうが先になる。

---------- Buffer: foo ----------
This is the contents of the 5th foo.
---------- Buffer: foo ----------

(capitalize-region 1 37)
⇒ nil

---------- Buffer: foo ----------
This Is The Contents Of The 5th Foo.
---------- Buffer: foo ----------
Command: downcase-region start end

この関数はstartendで定義されるリージョン内のすべての英文字を小文字に変換する。この関数はnilをリターンする。

インタラクティブにdowncase-regionが呼び出された際には、startendはポイントとマークになり小さいほうが先になる。

Command: upcase-region start end

この関数はstartendで定義されるリージョン内のすべての英文字を大文字に変換する。この関数はnilをリターンする。

インタラクティブにupcase-regionが呼び出された際には、startendはポイントとマークになり小さいほうが先になる。

Command: capitalize-word count

この関数はポイントの後のcount単語をcapitalizeして、変換後その後にポイントを移動する。capitalizeとは各単語の先頭を大文字、残りを小文字に変換することを意味する。countが負なら、この関数は前の-count単語をcapitalizeするがポイントは移動しない。値はnil

ポイントが単語の中間にある場合には、ポイントの前にある単語部分は前方に移動する際は無視される。そして残りの部分が単語全体として扱われる。

インタラクティブにcapitalize-wordが呼び出された際には、countに数プレフィクス引数がセットされる。

Command: downcase-word count

この関数はポイントの後のcount単語を小文字に変換して、変換後その後にポイントを移動する。countが負なら、この関数は前の-count単語を小文字に変換するがポイントは移動しない。値はnil

インタラクティブにdowncase-wordが呼び出された際には、countに数プレフィクス引数がセットされる。

Command: upcase-word count

この関数はポイントの後のcount単語を大文字に変換して、変換後その後にポイントを移動する。countが負なら、この関数は前の-count単語を小文字に変換するがポイントは移動しない。値はnil

インタラクティブにupcase-wordが呼び出された際には、countに数プレフィクス引数がセットされる。


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

33.19 テキストのプロパティ

バッファーや文字列内の各文字位置は、シンボルにおけるプロパティリスト(プロパティリストを参照)のようにテキストプロパティリスト(text property list)をもつことができます。特定の位置の特定の文字に属するプロパティ、たとえばこのセンテンス先頭の文字‘T’ (訳注: 翻訳前のセンテンスは"The properties belong to a ..."で始まる)、または‘foo’の最初の‘o’など、もし同じ文字が異なる2箇所に存在する場合には、2つの文字は一般的に異なるプロパティをもちます。

それぞれのプロパティには名前と値があります。どちらも任意のLispオブジェクトをもつことができますが、名前は通常はシンボルです。典型的にはそれぞれのプロパティ名シンボルは特定の目的のために使用されます。たとえばテキストプロパティfaceは、文字を表示するためのフェイスを指定します(特殊な意味をもつプロパティを参照)。名前を指定してそれに対応する値を尋ねるのが、このプロパティリストにアクセスするための通常の方法です。

ある文字がcategoryプロパティをもつ場合は、それをその文字のプロパティカテゴリー(property category)と呼びます。これはシンボルであるべきです。そのシンボルのプロパティはその文字のプロパティにたいしてデフォルトとしての役割をもちます。

文字列とバッファーの間でのテキストのコピーでは、文字とともにそのプロパティが保持されます。これにはsubstringinsertbuffer-substringのようなさまざまな関数が含まれます。


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

33.19.1 テキストプロパティを調べる

テキストプロパティを調べるもっともシンプルな方法は、特定の文字の特定のプロパティの値を尋ねる方法です。これを行うにはget-text-propertyを使用します。ある文字のプロパティリスト全体を取得するにはtext-properties-atを使用します。複数の文字のプロパティを一度に調べる関数についてはテキストプロパティの検索関数を参照してください。

以下の関数は文字列とバッファーの両方を処理します。バッファー内の位置は1から始まりますが、文字列内の位置は0から始まることに留意してください。カレントバッファー以外のバッファーのパースは低速になるかもしれません。

Function: get-text-property pos prop &optional object

この関数はobject (バッファーか文字列)内の位置posの後にある文字のプロパティpropの値をリターンする。引数objectはオプションでありデフォルトはカレントバッファー。

positionobjectの終端にあれば値はnilになるが、バッファーのナローイングは値に影響しないことに注意。つまりobjectがバッファーかnilの場合には、そのバッファーがナローイングされていて、かつobjectがナローイングされたバッファーの終端にあれば結果は非nilになるだろう。

厳密な意味でpropプロパティは存在しないが、その文字がシンボルのプロパティカテゴリーをもつなら、get-text-propertyはそのシンボルのpropプロパティをリターンする。

Function: get-char-property position prop &optional object

この関数はget-text-propertyと似ているが、まずオーバーレイをチェックして次にテキストプロパティをチェックする点が異なる。オーバーレイを参照のこと。

引数objectは文字列、バッファー、あるいはウィンドウかもしれない。ウィンドウならそのウィンドウ内に表示されているバッファーのテキストプロパティとオーバーレイが使用されるが、そのウィンドウにたいしてアクティブなオーバーレイだけが考慮される。objectがバッファーなら、そのバッファー内のオーバーレイがまず優先的に考慮されて、その後にテキストプロパティが考慮される。objectが文字列なら文字列がオーバーレイをもつことは決してないのでテキストプロパティだけが考慮される。

Function: get-pos-property position prop &optional object

この関数はget-char-propertyと似ているが、position (すぐ右)にある文字のプロパティのかわりにプロパティのstickiness(粘着性)とオーバーレイのadvancement(前向的)のセッティングに注意を払う点が異なる。

Function: get-char-property-and-overlay position prop &optional object

これはget-char-propertyと似ているが、そのプロパティ値が由来するオーバーレイについて追加情報を与える点が異なる。

値はCARがプロパティ値であるようなコンスセルであり、これは同じ引数によりget-char-propertyがリターンするであろう値と同じ。CDRはそのプロパティが見つかった箇所のオーバーレイ、テキストプロパティとして見つかった場合や見つからなかった場合にはnil

positionobjectの終端ならCARCDRの値はどちらもnil

Variable: char-property-alias-alist

この変数はプロパティ名と代替となるプロパティ名リストをマップするalistを保持する。文字があるプロパティにたいして直接値を指定しなければ、順に代替プロパティ名が調べられて最初の非nil値が使用される。この変数はdefault-text-propertiesより優先されて、この変数よりcategoryプロパティが優先される。

Function: text-properties-at position &optional object

この関数は文字列かバッファーobject内の位置positionにある文字のプロパティリスト全体をリターンする。objectnilならデフォルトはカレントバッファー。

positionobjectの終端にあれば値はnilになるが、バッファーのナローイングは値に影響しないことに注意。つまりobjectがバッファーかnilの場合には、そのバッファーがナローイングされていて、かつobjectがナローイングされたバッファーの終端にあれば結果は非nilになるだろう。

Variable: default-text-properties

この変数はテキストプロパティにたいしてデフォルト値を与えるプロパティリストを保持する。あるプロパティにたいして文字が直接、あるいはカテゴリーシンボルやchar-property-alias-alistを通じて値を指定しないときは、常にこのリストに格納された値がかわりに使用される。以下は例:

(setq default-text-properties '(foo 69)
      char-property-alias-alist nil)
;; 文字1は自身のプロパティをもたない
(set-text-properties 1 2 nil)
;; 取得される値はデフォルト値
(get-text-property 1 'foo)
     ⇒ 69
Function: object-intervals OBJECT

この関数はobject内のインターバル(テキストプロパティ)をインターバルのリストとしてリターンする。objectは文字列かバッファーでなければならない。このリストの構造を変更しても、オブジェクト内のインターバルは変更されない。

(object-intervals (propertize "foo" 'face 'bold))
     ⇒ ((0 3 (face bold)))

リターンされたリストの各要素は1つのインターバルを表す。インターバルはそれぞれ3つのパーツをもつ。1つ目は開始、2つ目は終了、3つ目はそのインターバル自身のテキストプロパティ。


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

33.19.2 テキストプロパティの変更

プロパティを変更するプリミティブは、バッファーや文字列内の指定されたテキスト範囲に適用されます。関数set-text-properties (セクションの最後を参照)は、その範囲内のテキストのプロパティリスト全体をセットします。名前を指定することにより特定のプロパティだけを追加、変更、削除するためにも有用です。

テキストプロパティはバッファー(か文字列)のコンテンツの一部とみなされ、かつスクリーン上でのバッファーの見栄えに影響を与えることができるので、バッファー内のテキストプロパティの変更はすべてバッファーを変更済みとマークします。バッファーテキストプロパティの変更もアンドゥできます(アンドゥを参照)。バッファー内の位置は1から始まりますが、文字列内の位置は0から始まります。

Function: put-text-property start end prop value &optional object

この関数は文字列かバッファーobject内のstartendの間のテキストにたいして、プロパティpropvalueをセットする。objectnilならデフォルトはカレントバッファー。

Function: add-text-properties start end props &optional object

この関数は文字列かバッファーobject内のstartendの間のテキストにたいして、テキストプロパティを追加またはオーバーライドする。objectnilならデフォルトはカレントバッファー。

引数propsには追加するプロパティを指定する。これはプロパティリストの形式(プロパティリストを参照)、つまりプロパティ名と対応する値が交互に出現するような要素を含むリストであること。

関数が実際に何らかのプロパティの値を変更したらt、それ以外( propsnil、またはプロパティの値がテキスト内のプロパティの値と一致している場合)はnilがリターン値となる。

たとえば以下はテキストの範囲にcommentfaceのプロパティをセットする例:

(add-text-properties start end
                     '(comment t face highlight))
Function: remove-text-properties start end props &optional object

この関数は文字列かバッファーobject内のstartendの間のテキストから、指定されたテキストプロパティを削除する。objectnilならデフォルトはカレントバッファー。

引数propsは削除するプロパティを指定する。これはプロパティリストの形式(プロパティリストを参照)、つまりプロパティ名と対応する値が交互に出現するような要素を含むリストであること。しかし問題となるのは名前であって付随する値は無視される。たとえばfaceプロパティを削除するには以下のようにすればよい。

(remove-text-properties start end '(face nil))

関数が実際に何らかのプロパティの値を変更したらt、それ以外( propsnil、または指定されたテキスト内にそれらのプロパティをもつ文字がない場合)はnilがリターン値となる。

特定のテキストからすべてのテキストプロパティを削除するには、新たなプロパティリストにnilを指定してset-text-propertiesを使用すればよい。

Function: remove-list-of-text-properties start end list-of-properties &optional object

remove-text-propertiesと同様だが、list-of-propertiesがプロパティ名と値が交互になったリストではなくプロパティ名だけのリストである点が異なる。

Function: set-text-properties start end props &optional object

この関数は文字列かバッファーobject内のstartからendの間のテキストにたいするテキストプロパティリストを完全に置き換える。objectnilならデフォルトはカレントバッファー。

引数propsは新たなプロパティリスト。これはプロパティ名と対応する値が交互となるような要素のリストであること。

set-text-propertiesのリターン後には、指定された範囲内のすべての文字は等しいプロパティをもつ。

propsnilなら、指定されたテキスト範囲からすべてのプロパティを取り除く効果がある。以下は例:

(set-text-properties start end nil)

この関数のリターン値を信用してはならない。

Function: add-face-text-property start end face &optional appendp object

この関数はstartendの間のテキストのテキストプロパティfaceにフェイスfaceを追加するように動作する。faceはフェイス名、もしくはanonymousフェイス(anonymous face: 無名フェイス)のようなfaceプロパティ(特殊な意味をもつプロパティを参照)にたいして有効な値であること(フェイスを参照)。

リージョン内の任意のテキストがすでに非nilfaceプロパティをもつ場合には、それらのフェイスは保たれる。この関数はfaceプロパティに最初の要素(デフォルト)がface、以前に存在していたフェイスが残りの要素であるようなフェイスのリストをセットする。オプション引数appendpが非nilなら、faceはかわりにリストの最後に追加される。フェイスリスト内では、各属性にたいして最初に出現する値が優先されることに注意。

たとえば以下のコードではstartendの間のテキストにグリーン斜体のフェイスを割り当てるだろう:

(add-face-text-property start end 'italic)
(add-face-text-property start end '(:foreground "red"))
(add-face-text-property start end '(:foreground "green"))

オプション引数objectが非nilなら、それはカレントバッファーではなく動作するバッファーか文字列を指定する。objectが文字列ならstartendは0基準で文字列内をインデックス付けする。

文字列にテキストプロパティを付するもっとも簡単な方法はpropertizeです:

Function: propertize string &rest properties

この関数はテキストプロパティpropertiesを追加したstringのコピーをリターンする。これらのプロパティはリターンされる文字列内のすべての文字に適用される。以下はfaceプロパティとmouse-faceプロパティとともに文字列を構築する例:

(propertize "foo" 'face 'italic
            'mouse-face 'bold-italic)
     ⇒ #("foo" 0 3 (mouse-face bold-italic face italic))

文字列のさまざまな部分に異なるプロパティをputするには、それぞれの部分をpropertizeで構築して、それらをconcatで結合すればよい:

(concat
 (propertize "foo" 'face 'italic
             'mouse-face 'bold-italic)
 " and "
 (propertize "bar" 'face 'italic
             'mouse-face 'bold-italic))
     ⇒ #("foo and bar"
                 0 3 (face italic mouse-face bold-italic)
                 3 8 nil
                 8 11 (face italic mouse-face bold-italic))

プロパティではなくバッファーからテキストをコピーする関数buffer-substring-no-propertiesについてはバッファーのコンテンツを調べるを参照してください。

バッファーを変更せずにバッファーにテキストプロパティを追加したり削除したければ、その呼び出しを上記のwith-silent-modificationsマクロでラップできます。バッファーの変更を参照してください。


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

33.19.4 特殊な意味をもつプロパティ

以下はビルトインで特別な意味をもつテキストプロパティ名のテーブルです。以降のセクションではフィルとプロパティ継承を制御する特別なプロパティ名をいくつか追加でリストしています。これ以外のすべての名前は特別な意味をもたず自由に使用できます。

注意: プロパティcompositiondisplayinvisibleintangibleはすべてのEmacsコマンドの後に好ましい箇所にポイントを移動させることもできます。コマンド後のポイントの調整を参照してください。

category

ある文字がcategoryプロパティをもつ場合には、それをその文字のプロパティカテゴリー(property category)と呼ぶ。これはシンボルであること。このシンボルのプロパティはその文字のプロパティのデフォルトとしての役割をもつ。

face

faceプロパティはその文字の外観を制御する(フェイスを参照)。このプロパティの値は以下が可能:

  • フェイス名(シンボルか文字列)。
  • anonymousフェイス: (keyword value …)形式のプロパティリスト。keywordはそれぞれフェイス属性名、valueはその属性の値。
  • フェイスのリスト。各リスト要素はフェイス名かanonymousフェイスであること。これはリストされた各フェイス属性を集計したフェイスを指定する。このリスト内で最初にあるフェイスがより高い優先度をもつ。
  • (foreground-color . color-name)または(background-color . color-name)という形式のコンスセル。これは(:foreground color-name)(:background color-name)と同じようにフォアグラウンドやバックグラウンドを指定する。この形式は後方互換のためだけにサポートされており無視すること。
  • (:filtered filter face-spec)という形式のコンスセル。これはface-specで与えられたフェイスを指定するが、フェイスを表示に使用する際にfilterがマッチした場合のみ。face-specには上述した任意のフォームを使用できる。filter(:window param value)という形式であること。これはパラメーターparamvalueeqであるようなウィンドウにマッチする。変数face-filters-always-matchが非nilなら、すべてのフェイスフィルターがマッチしたとみなす。

Font Lockモード(Font Lockモードを参照)はほとんどのバッファーにおいて、コンテキストにもとづき文字のfaceプロパティを動的に更新することにより機能する。

add-face-text-property関数は、このプロパティをセットする便利な手段を提供する。テキストプロパティの変更を参照のこと。

font-lock-face

このプロパティはFont Lockモードが配下にあるテキストに適用すべきfaceプロパティにたいして値を指定する。これはFont Lockモードに使用されるフォント表示手法の1つであり、独自のハイライトを実装する特別なモードにたいして有用。事前計算されたフォント化を参照のこと。Font Lockモードが無効ならfont-lock-faceに効果はない。

mouse-face

このプロパティは、このプロパティをもつテキストの上にマウスポインターがある際に、faceのかわりに使用される。これが発生する際にはマウスの下にある文字だけではなく、同じ値のmouse-faceプロパティをもつテキスト全体がハイライトされる。

Emacsはテキストサイズ(:height:weight:slant)を変更するmouse-faceプロパティ由来の属性すべてを無視する。これらの属性はハイライトされていないテキストと常に等しい。

cursor-face

これはmouse-faceと似ているが、このプロパティをもつテキスト内にポイント(マウスではない)がある際に使用されるプロパティである。ハイライトはモードcursor-face-highlight-modeが有効な場合のみ行われる。変数cursor-face-highlight-nonselected-windowが非nilならば、たとえウィンドウが選択されていなくてもhighlight-nonselected-windowsがリージョンにたいして行うのと同様(The Mark and the Region in The GNU Emacs Manualを参照)に、このフェイスをもつテキストがハイライトされる。

fontified

このプロパティはそのテキストの表示準備が整っているかどうかを告げる。nilならEmacsの再表示ルーチンはバッファーの該当部分を表示する前に、準備のためにfontification-functions (フェイスの自動割り当てを参照)の中の関数を呼び出す。これはフォントロックのコードのjust-in-timeにより内部的に使用される。

display

このプロパティはテキストが表示される方法を変更するさまざまな機能をアクティブ化する。たとえばこれによりテキスト外観を縦長(taller)または縦短(short)したり、高く(higher)または低く(lower)、太く(wider)または細く(narrower)したり、あるいはイメージに置き換えることができる。displayプロパティを参照のこと。

help-echo

テキストがhelp-echoプロパティに文字列をもつ場合には、そのテキスト上にマウスを移動した際には、substitute-command-keysを通じて文字列を渡した後にEmacsはエコーエリアかツールチップウィンドウ(ツールチップを参照)にその文字列を表示する。

help-echoプロパティの値が関数なら、その関数はwindowobjectposの3つの引数で呼び出されてヘルプ文字列、ヘルプ文字列が存在しなければnilをリターンすること。1つ目の引数windowはそのヘルプが見つかったウィンドウ。2つ目の引数objecthelp-echoプロパティをもつバッファー、オーバーレイ、または文字列。pos引数は以下のとおり:

  • objectがバッファーならposはそのバッファー内の位置。
  • objectがオーバーレイなら、そのオーバーレイはhelp-echoプロパティをもちposはそのオーバーレイのバッファー内の位置。
  • objectが文字列(オーバーレイ文字列、またはdisplayプロパティにより表示された文字列)ならposはその文字列内の位置。

help-echoプロパティの値が関数と文字列のいずれでもなければ、それはヘルプ文字列を得るために評価される。

変数show-help-functionをセットすることにより、ヘルプテキストが表示される方法を変更できる(Help displayを参照)。

この機能はモードライン内、およびその他のアクティブテキストにたいして使用される。

help-echo-inhibit-substitution

help-echo文字列の最初の文字が非nilhelp-echo-inhibit-substitutionプロパティをもつ場合には、substitute-command-keysを通じて渡すことなくshow-help-functionが行うように表示される。

keymap

keymapプロパティはコマンドにたいして追加のキーマップを指定する。このキーマップを適用する際には、マイナーモードキーマップとバッファーのローカルマップの前に、このマップがキー照合のために使用される。アクティブなキーマップを参照のこと。プロパティ値がシンボルなら、そのシンボルの関数定義がキーマップとして使用される。

ポイントの前の文字のプロパティの値は、それが非nilでrear-stickyであり、かつポイントの後の文字のプロパティ値が非nilでfront-stickyなら適用される(マウスクリックではポイント位置のかわりにクリック位置が使用される)。

local-map

このプロパティはkeymapと同じように機能するが、これはそのバッファーのローカルマップのかわりに使用するキーマップを指定する点が異なる。ほとんど(もしかするとすべて)の目的にたいしてはkeymapを使用するほうが良いだろう。

syntax-table

syntax-tableプロパティは特定の文字にたいしてどのシンタックステーブルがオーバーライドするかを告げる。構文プロパティを参照のこと。

read-only

ある文字がプロパティread-onlyをもつなら、その文字の変更は許可されない。これを行おうとするすべてのコマンドはtext-read-onlyエラーを受け取る。プロパティの値が文字列ならその文字列がエラーメッセージとして使用される。

read-only文字に隣接する箇所への挿入は、そこに通常のテキストの行うことがstickinessによるread-onlyプロパティを継承するならエラーとなる。つまりstickinessを制御することによりread-onlyテキストに隣接する挿入の権限を制御することができる。テキストプロパティの粘着性を参照のこと。

プロパティ変更はバッファー変更とみなされるので、特別なトリック(inhibit-read-onlyを非nilにバインドしてからプロパティを削除する)を知らないかぎり、read-onlyプロパティを取り除くことは不可能。読み取り専用のバッファーを参照のこと。

inhibit-read-only

プロパティinhibit-read-onlyをもつ文字はたとえ読み取り専用バッファーでも編集できる。読み取り専用のバッファーを参照のこと。

invisible

nilinvisibleプロパティにより、スクリーン上で文字を不可視にできる。詳細は不可視のテキストを参照のこと。

inhibit-isearch

inhibit-isearchプロパティが非nilなら、isearchはそのテキストをスキップする。

intangible

連続する文字のグループが非nilの等しいintangibleプロパティをもつなら、それらの文字の間にポイントを置くことは不可能。そのグループ内に前方へポイントの移動を試みると、ポイントは実際にはそのグループの終端に移動する。そのグループ内に後方へポイントの移動を試みると、ポイントは実際にはそのグループの先頭に移動する。

連続する文字のグループが非nilの等しくないintangibleプロパティをもつなら、それらの文字は個別のグループに属して、各グループは上述のように別のグループとして扱われる。

変数inhibit-point-motion-hooksが非nil (デフォルト)ならintangibleプロパティは無視される。

注意せよ: このプロパティは非常に低レベルで処理されて、予想外の方法により多くのコードに影響する。そのため使用に際しては特別な注意を要する。誤った使用方法としては不可視のテキストにintangibleプロパティをputするのが一般的な誤りであり、コマンドループは各コマンドの終わりに不可視テキストの外部へポイントを移動するだろうから、これは実際には必要ない。コマンド後のポイントの調整を参照のこと。これらの理由によりこのプロパティは時代遅れであり、かわりにcursor-intangibleプロパティを使用すること。

cursor-intangible

マイナーモードcursor-intangible-modeがオンになっている際には、再表示が発生する直前に非nilcursor-intangibleプロパティをもつすべての位置からポイントが移動させられる。許容されるカーソル位置の計算時にはこのプロパティの“粘着性(stickiness)”が考慮される(テキストプロパティの粘着性を参照)ので、たとえばカーソルがエンターできないような連続する5つの‘x’を挿入するためには、以下のような何かしらを行う必要がある:

(insert
 (propertize "xxxx" 'cursor-intangible t)
 (propertize "x" 'cursor-intangible t 'rear-nonsticky t))

変数cursor-sensor-inhibitが非nilなら、cursor-intangibleプロパティとcursor-sensor-functionsプロパティ(以下参照)は無視される。

field

同じfieldプロパティをもつ連続する文字はフィールドを構成する。forward-wordbeginning-of-lineを含むいくつかの移動関数はフィールド境界で移動を停止する。フィールドの定義と使用を参照のこと。

cursor

カーソルは通常はカレントバッファー位置を“隠している”(つまりかわりに表示されている)オーバーレイ、およびテキストプロパティ文字列の先頭か終端に表示される。Emacsに指示するかわりに文字に非nilcursorテキストプロパティを与えることにより、それら文字列内の任意の望む文字にカーソルを置くことができる。加えてcursorプロパティの値が整数なら、それはカーソルがその文字上に表示されるようにオーバーレイまたはdisplayプロパティが始まる位置から数えたバッファーの文字位置の数字を指定する。特にある文字のcursorプロパティの値が数字nなら、カーソルは範囲[ovpos..ovpos+n)内の任意のバッファー位置にあるその文字上に表示されるだろう。ここでovposoverlay-start (オーバーレイの管理を参照)により与えられるオーバーレイ開始位置、またはそのバッファー内でdisplayプロパティが始まる位置である。

言い換えると文字列の非nil値のcursorプロパティをもつ文字はカーソルが表示される文字である。このプロパティの値はオーバーレイまたはディスプレイ文字列が表示上でポイントを不可視にしている際に、カーソルを表示するバッファーの位置を告げる。値が整数nならオーバーレイまたはdisplayプロパティの始まりからn後ろの位置までの間にポイントがあるとき、カーソルはそこに表示される。値がそれ以外の非nilならポイントがdisplayプロパティの先頭となるバッファー位置にあるとき、あるいはディスプレイ上でその位置が不可視ならoverlay-startとなるバッファー位置でのみカーソルが表示される。cursorプロパティの整数値は、たとえそのポイントがディスプレイ上可視でなくとも、その文字上でカーソルが表示されることを意味し得ることに注意。

このプロパティの微妙なのは、ディスプレイまたはオーバーレイ文字列の一部であるような改行にはこのプロパティが機能しない点である。これはEmacsがディスプレイ上の文字にたいしてソンcursorプロパティを探す際に、検索するスクリーン上で改行文字がグラフィック表現をもたないからである。

バッファーのテキストを網羅するオーバーレイ文字列(before-stringを参照)や文字列であるようなdisplayプロパティがバッファーに多くある場合には、それらの文字列を走査する間にカーソルを置く箇所をEmacsに合図するために、cursorプロパティを使用するのはよいアイデアである。これはdisplayやオーバーレイ文字列に“カバー”された何らかのバッファー位置にポイントがある際に、Lispプログラムやユーザーがカーソルを配置したい箇所でディスプレイエンジンと直接通信する。

pointer

これはそのテキストやイメージ上にマウスポインターがあるときの特定のマウスシェイプを指定する。利用できるポインターシェイプについてはポインターの形状を参照のこと。

line-spacing

改行は改行で終わるディスプレイ行の高さを制御するテキストプロパティやオーバーレイプロパティline-spacingをもつことができる。このプロパティ値はデフォルトのフレーム行スペーシングと、バッファーローカル変数line-spacingをオーバーライドする。行の高さを参照のこと。

line-height

改行は改行で終わるディスプレイ行のトータル高さを制御するテキストプロパティ、またはオーバーレイプロパティline-heightをもつことができる。行の高さを参照のこと。

wrap-prefix

テキストがwrap-prefixプロパティをもつなら、それが定義するプレフィクスはテキストラッピング(text wrapping: テキスト折り返し)に由来するすべての継続行の先頭に表示時に追加されるだろう(行が切り詰められた場合にはwrap-prefixが使用されることはない)。これは文字列、イメージ(その他のディスプレイ仕様を参照)、あるいはディスプレイプロパティ:width:align-to (スペースの指定を参照)により指定された空白文字範囲かもしれない。

wrap-prefixはバッファーローカル変数wrap-prefixを使用して、バッファー全体にも指定され得る(がwrap-prefixテキストプロパティはwrap-prefix変数の値より優先される)。切り詰めを参照のこと。

line-prefix

テキストがline-prefixプロパティをもつなら、それが定義するプレフィクスは表示時にすべての非継続行の先頭に追加されるだろう。これは文字列、イメージ(その他のディスプレイ仕様を参照)、あるいはディスプレイプロパティ:width:align-to (スペースの指定を参照)により指定された空白文字範囲かもしれない。

line-prefixはバッファーローカル変数line-prefixを使用して、バッファー全体にも指定され得る(がline-prefixテキストプロパティはline-prefix変数の値より優先される)。切り詰めを参照のこと。

modification-hooks

ある文字がプロパティmodification-hooksをもつなら、その値は関数のリストであること。その文字の変更により、実際の変更前にそれらの関数すべてが呼び出される。それぞれの関数は、変更されようとするバッファー部分の先頭と終端という2つの引数を受け取る。特定のmodificationフック関数が単一のプリミティブにより変更されつつある複数の文字に出現する場合は、その関数が呼び出される回数を予測することはできない。さらに挿入は既存の文字を変更しないので、このフックは文字の削除、他の文字への置換、またはそれらのテキストプロパティ変更時のみ実行されるだろう。

他の同類フックとは異なり、Emacsはこれらの関数を呼び出し時にinhibit-modification-hooksを非nilバインドしない。関数がバッファーを変更するようなら、バッファー変更による変更フックの実行を防ぐために、この変数を非nilにバインドすることを考慮する必要がある。そうでなければ再帰呼び出しに備えなければならない。フックの変更を参照のこと。

オーバーレイもmodification-hooksプロパティをサポートするが詳細は若干異なる(オーバーレイのプロパティを参照)。

insert-in-front-hooks
insert-behind-hooks

あるバッファーへの挿入操作は後続文字のinsert-in-front-hooksプロパティ、および先行文字のinsert-behind-hooksプロパティにリストされる関数の呼び出しも行う。これらの関数は挿入されるテキストの先頭と終端という2つの引数を受け取る。関数は優先される実際の挿入が行われた後に呼び出される。

これらの関数を呼び出す際にはinhibit-modification-hooksは非nilにバインドされる。関数がバッファーを変更する場合には、これらの変更にたいして変更フックが実行されるように、inhibit-modification-hooksnilにバインドしたいと思うかもしれない。しかしこれを行うことによって、あなたの変更フックが再帰的に呼び出されるかもしれないので、確実にそれに備えること。

バッファー内のテキスト変更時にに呼び出される他のフックについてはフックの変更も参照のこと。

point-entered
point-left

スペシャルプロパティpoint-enteredpoint-leftはポイント移動をレポートするフック関数を記録する。ポイントを移動するたびにEmacsは以下の2つのプロパティ値を比較する:

  • 古い位置の後の文字のpoint-leftプロパティ。
  • 新しい位置の後の文字のpoint-enteredプロパティ。

これらの2つの値が異なる場合には、(nilでなければ)古いポイント値と新しいポイント値という2つの引数とともにそれらそれぞれ呼び出される。

同じ比較は古い位置と新しい位置の前の文字にたいしても行われる。この結果として2つのpoint-left関数(同じ関数かもしれない)、および/または2つのpoint-entered関数(同じ関数かもしれない)が実行される可能性がある。ある場合においては、まずすべてのpoint-left関数が呼び出されて、その後にすべてのpoint-entered関数が呼び出される。

さまざまなバッファー位置にたいして、そこにポイントを移動することなく文字を調べるためにchar-afterを使用することができる。実際のポイント値変更だけがこれらのフック関数を呼び出す。

変数inhibit-point-motion-hooksはデフォルトではpoint-leftpoint-enteredのフック実行を抑制する。Inhibit point motion hooksを参照のこと。

これらのプロパティは時代遅れであり、かわりにcursor-sensor-functionsを使用してほしい。

cursor-sensor-functions

このスペシャルプロパティはカーソル移動に反応する関数リストを記録する。このリスト内の各関数は影響を受けるウィンドウ、既知のカーソルの以前の位置、このプロパティをもつテキストにカーソルが入ったか離れたかに依存するシンボルenteredleftという3つの受け取って再表示の直前に呼び出される。関数はマイナーモードcursor-sensor-modeがオンのときのみ呼び出される。

変数cursor-sensor-inhibitが非nilならcursor-sensor-functionsプロパティは無視される。

composition

このテキストプロパティは文字シーケンスをコンポーネントから構成される単一グリフ(single glyph)として表示するために使用される。しかしこのプロパティの値自身は完全にEmacsの内部的なものであり、たとえばput-text-propertyなどで直接操作しないこと。

minibuffer-message

このテキストプロパティは、アクティブミニバッファーの一時的なメッセージを表示する場所を指定する。具体的にはこのプロパティをもつミニバッファーテキストの最初の文字が、その前に表示する一時的なメッセージを所有する。デフォルトではミニバッファーテキスト終端に一時的なメッセージが表示される。このテキストプロパティはset-message-functionのデフォルト値の関数が使用する(エコーエリアへのメッセージの表示を参照)。

Variable: inhibit-point-motion-hooks

この時代遅れの変数が非nilのときは、point-leftpoint-enteredのフックは実行されずintangibleプロパティは効果をもたない。この変数はグローバルにセットせずletでバインドすること。この変数の影響を受けるプロパティは時代遅れなので、それらを効果的に無効にするためにデフォルト値はt

Variable: show-help-function

この変数が非nilなら、それはヘルプ文字列を表示するために呼び出される関数を指定する。これらはhelp-echoプロパティ、メニューヘルプ文字列(単純なメニューアイテム拡張メニューアイテムを参照)、ツールバーヘルプ文字列(ツールバーを参照)かもしれない。指定された関数は、ヘルプ文字列の最初の文字が非nilhelp-echo-inhibit-substitutionをもっていなければ、表示するためのヘルプ文字列(関数に与えられる前にsubstitute-command-keysを通じて渡される)を単一の引数として呼び出される。ドキュメント内でのキーバインディングの置き換えを参照のこと。show-help-functionを使用するモードの例は、Tooltipモード(Tooltips in The GNU Emacs Manualを参照)のコード例を参照のこと。

Variable: face-filters-always-match

この変数が非nilなら、特定の条件が合致された際のみ適用される属性を指定するフェイスフィルターは常にマッチするとみなされる。


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

33.19.5 フォーマットされたテキストのプロパティ

以下のテキストプロパティはフィルコマンドの挙動に影響を与えます。これらはフォーマットされたテキストを表すために使用されます。fillfillのマージンを参照してください。

hard

改行文字がこのプロパティをもつならそれは“hard”改行。フィルコマンドはhard改行を変更せずそれらを横断して単語を移動しない。しかしこのプロパティはマイナーモードuse-hard-newlinesが有効な場合のみ影響を与える。Hard and Soft Newlines in The GNU Emacs Manualを参照のこと。

right-margin

このプロパティはその部分のテキストのフィルにたいして余分な右マージンを指定する。

left-margin

このプロパティはその部分のテキストのフィルにたいして余分な左マージンを指定する。

justification

このプロパティはその部分のテキストのフィルにたいして位置揃え(justification)のスタイルを指定する。


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

33.19.6 テキストプロパティの粘着性

ユーザーがそれらをタイプした際にはバッファーに挿入される自己挿入文字(ユーザーレベルの挿入コマンドを参照)は、通常は先行する文字と同じプロパティをもちます。これはプロパティの継承(inheritance)と呼ばれます。

対照的にLispプログラムは継承の有無に関わらず挿入を行うことができ、それは挿入プリミティブの選択に依存します。insertのような通常のテキスト挿入関数は何もプロパティを継承しません。これらは挿入される文字列と正確に同じプロパティをもち、それ以外のプロパティはもちません。これはたとえばkillリング外部にたいしてのように、あるコンテキストから他のコンテキストにテキストをコピーするプログラムにたいして適正です。継承つきで挿入を行うためには、このセクションで説明するスペシャルプリミティブを使用します。自己挿入文字はこれらのプリミティブを使用するのでプロパティを継承します。

継承つきで挿入を行う際に、何のプロパティがどこから継承されるかはsticky(スティッキー、粘着する)に依存します。ある文字の後への挿入における、それらの文字のプロパティ継承はrear-sticky(後方スティッキー)です。ある文字の前への挿入における、それらの文字ノプロパティ継承はfront-sticky(前方スティッキー)です。これら両側のstickyが同じプロパティにたいして異なるsticky値をもつ場合には、前の文字の値が優先します。

デフォルトではテキストプロパティはfront-stickyではなくrear-stickyです。したがってデフォルトでは、すべてのプロパティは前の文字から継承して、後の文字からは何も継承しません。

さまざまなテキストプロパティのstickiness(スティッキネス、スティッキー性、粘着性、粘着度)は、2つのテキストプロパティfront-stickyrear-nonsticky、および変数text-property-default-nonstickyで制御できます。与えられたプロパティにたいして異なるデフォルトを指定するためにこの変数を使用できます。テキストの任意の特定部分に特定のstickyや非stickyプロパティを指定するために、これら2つのテキストプロパティを使用できます。

ある文字のfront-stickyプロパティがtなら、その文字のすべてのプロパティはfront-stickyです。front-stickyプロパティがリストなら、その文字のstickyなプロパティは名前がそのリスト内にあるプロパティです。たとえばある文字が値が(face read-only)であるようなfront-stickyプロパティをもつなら、その文字の前への挿入ではその文字のfaceプロパティとread-onlyプロパティは継承できますが他のプロパティは継承できません。

rear-nonstickyは逆の方法で機能します。ほとんどのプロパティはデフォルトでrear-stickyであり、rear-nonstickyプロパティはどのプロパティがrear-stickyではないかを告げます。ある文字のrear-nostickyプロパティがtなら、その文字のすべてのプロパティはrear-stickyではありません。rear-nostickyプロパティがリストなら、その文字のstickyなプロパティは名前がそのリスト内にないプロパティです。

Variable: text-property-default-nonsticky

この変数はさまざまなテキストプロパティのデフォルトのrear-stickinessを定義するalist。各要素は(property . nonstickiness)という形式をもち、これは特定のテキストプロパティpropertyのstickinessを定義する。

nonstickinessが非nilなら、それはプロパティpropertyがデフォルトでrear-nonstickyであることを意味する。すべてのプロパティはデフォルトではfront-nonstickyなので、これによりpropertyは両方向にたいしてデフォルトでnonstickyになる。

テキストプロパティfront-stickyrear-nonstickyが使用された際には、text-property-default-nonsticky内で指定されたデフォルトのnonstickinessより優先される。

以下はプロパティ継承つきでテキストを挿入する関数です:

Function: insert-and-inherit &rest strings

関数insertと同じように文字列stringsを挿入するが、隣接するテキストからすべてのstickyなプロパティを継承する。

Function: insert-before-markers-and-inherit &rest strings

関数insert-before-markersと同じように文字列stringsを挿入するが、隣接するテキストからすべてのstickyなプロパティを継承する。

継承を行わない通常の挿入関数についてはテキストの挿入を参照してください。


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

33.19.7 テキストプロパティのlazyな計算

バッファー内のすべてのテキストにたいしてテキストプロパティを計算するかわりに、何かがテキスト範囲に依存している場合にはテキストプロパティを計算するようにアレンジできます。

プロパティとともにバッファーからテキストを抽出するプリミティブはbuffer-substringです。この関数はプロパティを調べる前にアブノーマルフックbuffer-access-fontify-functionsを実行します。

Variable: buffer-access-fontify-functions

この変数はテキストプロパティ計算用の関数のリストを保持する。buffer-substringがバッファーの一部のテキストとテキストプロパティをコピーする前にこのリスト内の関数すべてを呼び出す。各関数はアクセスされるバッファー範囲を指定する2つの引数を受け取る(バッファーは常にカレントバッファー)。

関数buffer-substring-no-propertiesはいずれにせよテキストプロパティを無視するので、これらの関数を呼び出さない。

同じバッファー部分にたいして複数回フック関数が呼び出されるのを防ぐために変数buffer-access-fontified-propertyを使用できる。

Variable: buffer-access-fontified-property

この変数の値が非nilなら、それはテキストプロパティ名として使用されるシンボル。そのテキストプロパティにたいする非nil値は、その文字にたいする他のテキストプロパティはすでに計算済みであることを意味する。

buffer-substringにたいして指定された範囲内のすべての文字、このプロパティにたいする値として非nilをもつなら、buffer-substringbuffer-access-fontify-functionsの関数を呼び出さない。それらの文字がすでに正しいテキストプロパティをもつとみなして、それらがすでに所有するプロパティを単にコピーする。

buffer-access-fontify-functionsの関数にこのプロパティ、同様に他のプロパティを処理対象の文字に追加させることがこの機能の通常の用途である。この方法では同じテキストにたいして、それらの関数が何度も呼び出されるのを防ぐことができる。


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

33.19.8 クリック可能なテキストの定義

クリック可能テキスト(clickable text)とは何らかの結果を生成するためにマウスやキーボードコマンドを通じてクリックできるテキストです。多くのメジャーモードがテキスト的なハイパーリンク、略してリンク(link)を実装するためにクリック可能テキストを使用しています。

リンクの挿入や操作を行うもっとも簡単な方法はbuttonパッケージの使用です。ボタンを参照してください。このセクションではテキストプロパティを使用してバッファー内に手作業でクリック可能テキストをセットアップする方法を説明します。簡略にするためにクリック可能テキストをリンクと呼ぶことにします。

リンクの実装には、(1)リンク上にマウスが移動した際にクリック可能であることを示し、(2)そのリンク上のRETmouse-2で何かを行うようにして、(3)そのリンクがmouse-1-click-follows-linkにしたがうようfollow-linkをセットアップする、という3つのステップが含まれます。

クリック可能なことを示すためには、そのリンクのテキストにmouse-faceプロパティを追加します。するとEmacsはそれ以降マウスがその上に移動した際にリンクをハイライトするでしょう。加えてhelp-echoテキストプロパティを使用してツールチップかエコーエリアメッセージを定義するべきです。特殊な意味をもつプロパティを参照してください。たとえば以下はDiredがファイル名がクリック可能なことを示す方法です:

 (if (dired-move-to-filename)
     (add-text-properties
       (point)
       (save-excursion
         (dired-move-to-end-of-filename)
         (point))
       '(mouse-face highlight
         help-echo "mouse-2: visit this file in other window")))

リンクをクリック可能にするためには、 RETmouse-2を望むアクションを行うコマンドにバインドします。各コマンドはリンク上から呼び出されたかチェックして、それに応じて動作するべきです。たとえばDiredメジャーモードのキーマップはmouse-2を以下のコマンドにバインドします:

(defun dired-mouse-find-file-other-window (event)
  "In Dired, visit the file or directory name you click on."
  (interactive "e")
  (let ((window (posn-window (event-end event)))
        (pos (posn-point (event-end event)))
        file)
    (if (not (windowp window))
        (error "No file chosen"))
    (with-current-buffer (window-buffer window)
      (goto-char pos)
      (setq file (dired-get-file-for-visit)))
    (if (file-directory-p file)
        (or (and (cdr dired-subdir-alist)
                 (dired-goto-subdir file))
            (progn
              (select-window window)
              (dired-other-window file)))
      (select-window window)
      (find-file-other-window (file-name-sans-versions file t)))))

このコマンドはクリックがどこで発生したかを判断するために関数posn-windowposn-point、visitするファイルの判断に関数dired-get-file-for-visitを使用します。

マウスコマンドをメジャーモードキーマップ内でバインドするかわりに、keymapプロパティ(特殊な意味をもつプロパティを参照)を使用してリンクテキスト内でバインドできます。たとえば:

(let ((map (make-sparse-keymap)))
  (define-key map [mouse-2] 'operate-this-button)
  (put-text-property link-start link-end 'keymap map))

この手法により異なるリンクに異なるコマンドを簡単に定義できます。さらにそのバッファー内の残りのテキストにたいしては、RETmouse-2のグローバル定義を利用可能なまま残すことができます。

リンク上でのクリックにたいするEmacsの基本コマンドはmouse-2です。しかし他のグラフィカルなアプリケーションとの互換性のために、ユーザーがマウスを動かさずに素早くリンクをクリックするという条件の下で、Emacsはリンク上でのmouse-1クリックも認識します。この振る舞いはユーザーオプションmouse-1-click-follows-linkにより制御されます。Mouse References in The GNU Emacs Manualを参照してください。

mouse-1-click-follows-linkにしたがうようにリンクをセットアップするには、(1)そのテキストにfollow-linkテキストプロパティまたはオーバーレイプロパティを適用する、または(2)follow-linkイベントをキーマップ(keymapテキストプロパティを通じたメジャーモードキーマップまたはローカルキーマップ)にバインドするかの、いずれかを行わなければなりません。follow-linkプロパティの値、またはfollow-linkイベントにたいするバインディングはリンクアクションにたいするコンディション(condition)として機能します。この条件はEmacsにたいして2つのことを告げます。それはmouse-1のクリックがそのリンクの内側で発生したとみなすべき状況、そしてmouse-1のクリックを何に変換するかを告げるアクションコード(action code)を計算する方法です。そのリンクのアクション条件は以下のうちの1つです:

mouse-face

コンディションがシンボルmouse-faceの場合には、その位置に非nilmouse-faceプロパティがあればそれはリンク内側の位置。アクションコードは常にt

以下はInfoモードがmouse-1を処理する例:

(keymap-set Info-mode-map "<follow-link>" 'mouse-face)
関数

コンディションが関数funcの場合には、(func pos)が非nilに評価されれば、位置posはリンクの内側。funcがリターンする値はアクションコードとして機能する。

以下はpcvsがファイル名の上でのみmouse-1によるリンクのフォローを有効にする方法の例:

(keymap-set map "<follow-link>"
            (lambda (pos)
              (eq (get-char-property pos 'face) 'cvs-filename-face)))
その他

コンディション値がそれ以外の場合には、その位置はリンク内側であり、そのコンディション自体がアクションコード。(バッファー全体に適用されないように)リンクテキストのテキストプロパティかオーバーレイプロパティを通じてコンディションを適用するときのみ、この類のコンディションを指定すべきなのは明確である。

アクションコードはmouse-1がリンクをフォローする方法を告げます:

文字列かベクター

アクションコードが文字列かベクターなら、mouse-1イベントは文字列かベクターの最初の要素に変換される。つまりmouse-1クリックのアクションはその文字、またはシンボルのローカルかグローバルのバインディング。したがってアクションコードが"foo"なら、mouse-1f[foo]ならmouse-1fooに変換される。

その他

その他の非nilのアクションコードでは、mouse-1イベントは同じ位置のmouse-2イベントに変換される。

define-button-typeで定義されるボタンをアクティブにするようにmouse-1を定義するには、そのボタンにfollow-linkプロパティを与えます。このプロパティの値は上述したリンクのアクションコンディションであるべきです。ボタンを参照のこと。たとえば以下はHelpモードがMouse-1を処理する例です。

(define-button-type 'help-xref
  'follow-link t
  'action #'help-button-action)

define-widgetで定義されたウィジェットにmouse-1を定義するには、そのウィジェットに:follow-linkプロパティを与えます。このプロパティの値は、上述したようなリンクのアクションコンディションであるべきです。たとえば以下はmouse-1クリックがRETに変換されるようにlinkウィジェットを指定する方法の例です:

(define-widget 'link 'item
  "An embedded link."
  :button-prefix 'widget-link-prefix
  :button-suffix 'widget-link-suffix
  :follow-link "\C-m"
  :help-echo "Follow the link."
  :format "%[%t%]")

この関数はカレントバッファー内の位置posがリンク上なら非nilをリターンする。posevent-startがリターンするようなマウスイベント位置でもよい(マウスイベントへのアクセスを参照)。


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

33.19.9 フィールドの定義と使用

フィールドとはバッファー内にある連続する文字範囲であり、fieldプロパティ(テキストプロパティかオーバーレイプロパティ)に同じ値(eqで比較)をもつことにより識別されます。このセクションではフィールドの操作に利用できるスペシャル関数を説明します。

フィールドはバッファー位置posで指定します。各フィールドはバッファー位置の範囲を含むと考えて、指定した位置はその位置を含むフィールドを表します。

posの前後の文字は同じフィールドに属し、どのフィールドがposを含むかという疑問はありません。それらの文字が属するフィールドがそのフィールドです。posがフィールド境界のときは、それがどのフィールドに属すかは、取り囲む2つの文字のfieldプロパティのstickinessに依存します(テキストプロパティの粘着性を参照)。posに挿入されたテキストからプロパティが継承されたフィールドがposを含むフィールドです。

posに新たに挿入されたテキストが、いずれの側からもfieldプロパティを継承しない異常なケースがあります。これは前の文字のfieldプロパティがrear-stickyでなく、後の文字のfieldプロパティがfront-stickyでもない場合に発生します。このケースではposは前後のフィールドいずれにも属しません。フィールド関数はそれを、開始と終了がposであるような空フィールドに属するものとして扱います。

以下のすべての関数では、posが省略かnilならポイントの値がデフォルトとして使用されます。ナローイング(narrowing)が効力をもつ場合には、posはアクセス可能部分にあるはずです。ナローイングを参照してください。

Function: field-beginning &optional pos escape-from-edge limit

この関数はposで指定されたフィールドの先頭をリターンする。

posが自身のフィールド先頭にあり、かつescape-from-edgeが非nilなら、pos周辺のfieldプロパティのstickinessに関わらず、リターン値は常にposが終端であるような、前にあるフィールドの先頭になる。

limitが非nilなら、それはバッファーの位置。そのフィールドの先頭がlimitより前なら、かわりにlimitがリターンされるだろう。

Function: field-end &optional pos escape-from-edge limit

この関数はposで指定されるフィールドの終端をリターンする。

posが自身のフィールド終端にあり、かつescape-from-edgeが非nilなら、pos周辺のfieldプロパティのstickinessに関わらず、リターン値は常にpos先頭であるような後のフィールドの終端になる。

limitが非nilなら、それはバッファーの位置である。そのフィールドの終端がlimitより後なら、かわりにlimitがリターンされるだろう。

Function: field-string &optional pos

この関数はposで指定されるフィールドのコンテンツを文字列としてリターンする。

Function: field-string-no-properties &optional pos

この関数はposで指定されるフィールドのコンテンツを、テキストプロパティを無視して文字列としてリターンする。

Function: delete-field &optional pos

この関数はposで指定されるフィールドのテキストを削除する。

Function: constrain-to-field new-pos old-pos &optional escape-from-edge only-in-line inhibit-capture-property

この関数はnew-posold-posが属するフィールドに“拘束(constrain)”する。言い換えると、これは old-posと同じフィールド内でnew-posにもっとも近い位置をリターンする。

new-posnilなら、constrain-to-fieldはかわりにポイントの値を使用してポイントをリターンすることに加えて、その位置にポイントを移動する。

old-posが2つのフィールドの境界なら、許容できる最後の位置は引数escape-from-edgeに依存する。escape-from-edgenilなら、new-posは新たに文字がold-posが挿入されたときに継承するであろう値と、fieldプロパティが等しいフィールドでなければならない。escape-from-edgeが非nilならnew-posは隣接する2つのフィールド内のどこでも構わない。さらに2つのフィールドが特別な値boundaryにより他のフィールドで分割されている場合には、このスペシャルフィールド内のすべてのポイントも境界上とみなされる。

引数なしのC-aコマンドのように、特別な種類の位置に後方へ移動して一度そこに留まるには、おそらくescape-from-edgeにたいしてnilを指定するべきであろう。フィールドをチェックする他の移動コマンドにたいしては、おそらくtを渡すべきである。

オプション引数only-in-lineが非nil、かつnew-posを通常の方法により拘束することにより異なる行へ移動するような場合には、new-posは非拘束でリターンされる。これはnext-linebeginning-of-lineのような行単位の移動コマンドで、それらのコマンドが正しい行へ移動できる場合のみフィールド境界を尊重するようにするために用いられる。

オプション引数inhibit-capture-propertyが非nil、かつold-posがその名前の非nilのプロパティをもつ場合には、すべてのフィールド境界は無視される。

変数inhibit-field-text-motionを非nil値にバインドすることにより、constrain-to-fieldにすべてのフィールド境界を無視(何者にも拘束されることがない)させることができる。


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

33.19.10 なぜテキストプロパティはインターバルではないのか

バッファー内のテキストへの属性の追加をサポートする一部のエディターの中には、ユーザーにテキスト内のインターバルを指定させて、そのインターバルにプロパティを追加することによって属性の追加をサポートするものがあります(訳注: 日本語のカタカナ英語として通用しているインターバルは「間隔」、「距離」、「合間」のようにインターバルの両端に実体がありインターバル自体は隔たりだけを表す疎な実体という日常会話でのinterval訳を連想しますが、Emacs Lispリファレンスにおけるインターバルは計算幾何学におけるインターバル木のように開始と終了をもった数学分野におけるinterval訳である「区間」の意味で用いられています; object-intervalsを参照してください)。それらのエディターではユーザーやプログラマーが個別にインターバルの開始と終了を決定することが許されています。わたしたちはテキスト変更に関連する逆説的な特定の振る舞いを避けるために、故意に異なる種類のインターフェイスをEmacs Lisp内に提供しました。

複数のインターバルに細分化することが実際に意味をもつなら、それは特定のプロパティをもつ単一のインターバルのバッファーと、同じテキストをもち両方が同じプロパティをもつ2つのインターバルに分割されたバッファーを区別できることを意味します。

インターバルを1つだけもつバッファーがあり、その一部をkillすることを考えてみてください。そのそのバッファーに残されるのは1つのインターバルであり、killリング(とundoリスト)内のコピーは別個のインターバルになります。そのkillされたテキストをyankで戻すと、同じプロパティをもつ2つのインターバルを得ることになります。したがって編集では1つのインターバルと2つのインターバルの違いは保たれません。

テキスト挿入時に2つのインターバルを結合することにより、この問題に“対応”したとします。これはそのバッファーが元々単一のインターバルだったなら上手く機能します。 しかしかわりに同じプロパティをもつ隣接する2つのインターバルがあり、そのうちの1つのインターバルからテキストをkillしてyankで戻すことを考えてみてください。あるケースを解決する同じインターバル結合機能が、他のケースにおいては問題を引き起こすのです。このyank後にインターバルはただ1つとなります。繰り返します、編集では1つのインターバルと2つのインターバルの違いは保たれないのです。

インターバルの間の境界上へのテキスト挿入においても満足できる回答が存在しないような問題が発生します。

しかし“バッファーにあるテキスト位置または文字列位置のプロパティは何か?”という形式の問にたいして、編集が一貫した振る舞いをするようアレンジするのは簡単です。そこでわたしたちはこれらが合理的な唯一の問いであると判断したのです。わたしたちはインターバルの開始と終了の場所を問うような実装をしませんでした。

実際には明白にインターバル境界であるような箇所では、通常はテキストプロパティ検索関数を使用できます。可能であるならインターバルは常に結合されるとみなすことにより、それらがインターバル境界を探すと考えることができます。テキストプロパティの検索関数を参照してください。

Emacsはプレゼンテーション機能として明示的なインターバルも提供します。オーバーレイを参照してください。


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

33.20 文字コードの置き換え

以下の関数は文字コードにもとづいて指定されたリージョン内の文字を置き換えます。

Function: subst-char-in-region start end old-char new-char &optional noundo

この関数はstartendで定義されるカレントバッファーのリージョン内に出現する文字old-charnew-charに置き換える。これら2つの文字はマルチバイト形式で同じ長さでなければならない。

noundoが非nilならsubst-char-in-regionはundo用に変更を記録せず、バッファーを変更済みとマークしない。これは古い機能である選択的ディスプレイ(選択的な表示を参照)にとって有用だった。

subst-char-in-regionはポイントを移動せずnilをリターンする。

---------- Buffer: foo ----------
This is the contents of the buffer before.
---------- Buffer: foo ----------

(subst-char-in-region 1 20 ?i ?X)
     ⇒ nil

---------- Buffer: foo ----------
ThXs Xs the contents of the buffer before.
---------- Buffer: foo ----------
Function: subst-char-in-string fromchar tochar string &optional inplace

この関数はstring内のすべての文字fromchartocharに置き換える。デフォルトではstringのコピーで置き換えは発生するが、オプション引数inplaceが非nilなら、この関数はstring自体を変更する。いずれの場合でも、この関数は結果となる文字列をリターンする。

Command: translate-region start end table

この関数はバッファー内の位置startendの間の文字にたいして、変換テーブル(translation table)を適用する。

変換テーブルtableは文字列か文字テーブル。(aref table ochar)ocharに対応した変換後の文字を与える。tableが文字列なら、tableの長さより大きいコードの文字はこの変更により変更されない。

translate-regionのリターン値は、その変換により実際に変更された文字数。変換テーブル内でその文字自身にマップされる文字は勘定に入らない。


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

33.21 レジスター

レジスター(register)とは、Emacs内の編集においてさまざまな異なる種類の値を保持できる一種の変数です。レジスターはそれぞれ1文字で命名されます。すべてのASCII文字、およびそれらのメタ修飾された変種(ただしC-gは例外)をレジスターの命名に使用できます。したがって利用可能なレジスター数は255になります。Emacs Lispではレジスターは自身の名前となるその文字により指定されます。

Variable: register-alist

この変数は要素が(name .contents)という形式のalist。使用中のEmacsレジスターごとに通常は1つの要素が存在する。

オブジェクトnameはレジスターを識別する文字(整数)。

レジスターのcontentsには、いくつかのタイプがある:

数字

数字はそれ自身を意味する。insert-registerはレジスター内の数字を探して10進数に変換する。

マーカー

マーカーはジャンプ先のバッファー位置を表す。

文字列

文字列の場合はレジスター内に保存されたテキスト。

矩形(rectangle)

矩形は文字列のリストを表す。

(window-configuration position)

これは1つのフレームにリストアされるウィンドウ構成、およびカレントバッファー内のジャンプ先の位置を表す。

(frame-configuration position)

これはリストア用のフレーム構成とカレントバッファー内のジャンプ先の位置。フレーム構成はフレームセット(frameset)とも呼ばれる。

(file filename)

これはvisitするファイルを表し、この値にジャンプすることによりファイルfilenameをvisitする。

(file-query filename position)

これはvisitするファイルとファイル内の位置を表す。この値にジャンプすることによりファイルfilenameをvisitしてバッファー位置positionに移動する。このタイプの位置をリストアすると、まずユーザーにたいして確認を求める。

(buffer buffer-name)

これはvisitするバッファーを表し、この値にジャンプすることによりバッファーbuffer-nameに切り替える。

このセクションの関数は特に明記しない限り予期せぬ値をリターンします。

Function: get-register reg

この関数はレジスターregのコンテンツ、コンテンツがなければnilをリターンする。

Function: set-register reg value

この関数はレジスターregのコンテンツにvalueをセットする。レジスターには任意の値をセットできるが、その他のレジスター関数は特定のデータ型を期待する。リターン値はvalue

Command: view-register reg

このコマンドはレジスターregに何が含まれているかを表示する。

Command: insert-register reg &optional beforep

このコマンドはカレントバッファーにレジスターregのコンテンツを挿入する。

このコマンドは通常は挿入したテキストの前にポイント、後にマークを配置する。しかしオプションの第2引数beforepが非nilならマークを前、ポイントを後に配置する。インタラクティブな呼び出しでは、プレフィクス引数を与えることにより2つ目の引数beforepnilを渡すことができる。

このコマンドはインタラクティブに呼び出された際には、デフォルトではテキストの後にポイントを配置して、プレフィクス引数を与えるとこの反対の振る舞いを行う。

レジスターに矩形が含まれる場合には、その矩形はポイントの左上隅に挿入される。これはそのテキストがカレント行と、その下に続く行に挿入されることを意味する。

レジスターが保存されたテキスト(文字列)または矩形(リスク)以外の何かを含む場合には、現在のところは役に立つようなことは起きない。これは将来変更されるかもしれない。

Function: register-read-with-preview prompt

この関数はprompt、およびもしかしたら既存レジスターとそのコンテンツをプレビューしてレジスターの名前を読み取ってレジスター名をリターンする。このプレビューはユーザーオプションregister-preview-delayregister-alistがいずれも非nilなら、register-preview-delayで指定された遅延の後に一時ウィンドウ内に表示される。このプレビューはユーザーが(たとえばヘルプ文字のタイプにより)ヘルプを要求した場合にも表示される。レジスター名を読み取るンタラクティブな関数には、この関数の使用を推奨する。


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

33.22 テキストの交換

以下の関数はテキストの一部を置き換えるために使用できます:

Function: transpose-regions start1 end1 start2 end2 &optional leave-markers

この関数はバッファーの重複しない2つの部分を交換する(重複する場合にはエラーをシグナルする)。引数start1end1は一方の部分の両端、引数start2end2はもう一方の部分の両端を指定する。

transpose-regionsは通常は置き換えたテキストにともないマーカーを再配置する。以前は2つの置き換えたテキストのうちの一方の部分に位置していたマーカーは、その部分とともに移動されるので、それを挟む2つの文字の新たな位置の間に留まることになる。しかしleave-markersが非nilなら、transpose-regionsはこれを行わず、すべてのマーカーを再配置せずに残す。


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

33.23 バッファーテキストの置換

以下の関数を使用して、あるバッファーのテキストを他のバッファーのテキストで置き換えることができます:

Command: replace-buffer-contents source &optional max-secs max-costs

この関数はバファーsourceのアクセス可能範囲でカレントバッファーのアクセス可能範囲を置き換える。sourceはバッファーオブジェクトかバッファー名のいずれか。replace-buffer-contentsが成功するとカレントバッファーのアクセス可能範囲のテキストは、バッファーsourceのアクセス可能範囲のテキストと等しくなる。

この関数はバファーsourceのアクセス可能範囲でカこの関数はカレントバッファーのポイント、マーカー、テキストプロパティ、オーバーレイをそのまま維持しようと試みる。この挙動が好都合であるような潜在的なケースは外部コードをフォーマットするプログラムだろう。これらは通常は再フォーマットしたテキストを一時的なバッファーかファイルに書き込んで、delete-regioninsert-buffer-substringを使用することによりそれらのプロパティを削除する。しかし後者の組み合わせのほうが通常は高速である(テキストの削除テキストの挿入を参照)。

これが機能するためにはreplace-buffer-contentsが元バッファーとsourceのコンテンツを比較する必要があり、これはバッファーが巨大で多数の差異が存在する場合にはコストがかかる処理となる。replace-buffer-contentsの実行時間を制限するために、2つのオプション引数がある。

max-secsは秒単位のハードリミットを定義する。これが与えられて超過した場合には、delete-regionおよびinsert-buffer-substringにフォールバックする。

max-costsは差分計算の品質を定義する。このリミットを実際のコストが超過したら、次善だがより高速な発見的手法を使用する。デフォルト値は1000000。

replace-buffer-contentsは非破壊的な置換ができればtをリターンする。それ以外の場合にはmax-secsを超過したらnilをリターンする。

Function: replace-region-contents beg end replace-fn &optional max-secs max-costs

この関数は与えられたreplace-fnを使用して、begendの間のリージョンを置換する。関数replace-fnはカレントバッファーを指定されたリージョンにナローして実行される。リージョンを置換する文字列またはバッファーのいずれかをリターンすること。

置換は上述のreplace-buffer-contents (引数max-secsmax-costs、リターン値についても記述あり)を使用して行われる。

注意: 置換物が文字列なら一時バッファーに配置されるのでreplace-buffer-contentsが処理することができる。したがってすでにバッファーに置換物がある場合には、buffer-substringの類を使用して文字列に変換することは無意味である。


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

33.24 圧縮されたデータの処理

auto-compression-modeが有効なときは、Emacsは圧縮されたファイルをvisitする際に自動的に解凍して、それを変更して保存する際は自動的に再圧縮します。Compressed Files in The GNU Emacs Manualを参照してください。

上記の機能は外部の実行可能ファイル(例: gzip)を呼び出すことにより機能します。zlibライブラリーを使用したビルトインの解凍サポートつきでEmacsをコンパイルすることもでき、これは外部プログラムの実行に比べて高速です。

Function: zlib-available-p

この関数はビルトインzlib解凍が利用可能なら非nilをリターンする。

Function: zlib-decompress-region start end &optional allow-partial

この関数はビルトインのzlib解凍を使用してstartendの間のリージョンを解凍する。このリージョンにはgzipかzlibで圧縮されたデータが含まれていなければならない。この関数は成功したらリージョンのコンテンツを解凍されたデータに置き換える。allow-partialnilか省略の場合に失敗すると、この関数はリージョンを変更せずにnilをリターンする。それ以外の場合には解凍されなかったバイト数をリターンして、正常に解凍されたデータが何であれ、それによりリージョンのテキストを置き換える。この関数はユニバイトバッファーでのみ呼び出すことができる。


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

33.25 Base 64エンコーディング

Base64コードは8ビットシーケンスをより長いASCIIグラフィック文字シーケンスにエンコードするためにemail内で使用されます。これはインターネットRFC2045およびRFC4648でも定義されます23。このセクションでは、このコードへの変換および逆変換を行う関数について説明します。

Command: base64-encode-region beg end &optional no-line-break

この関数はbegからendのリージョンをBase64コードに変換する。これはエンコードされたテキストの長さをリターンする。リージョン内の文字がマルチバイトならエラーをシグナルする(マルチバイトバッファーではリージョンにはASCIIとrawバイト以外の文字が含まれてはならない)。

この関数は通常は行が長くなりすぎるのを防ぐために、エンコードされたテキストに改行を挿入する。しかしオプション引数no-line-breakが非nilなら、これらの改行は追加されず出力は長い単一の行となる。

Command: base64url-encode-region beg end &optional no-pad

この関数はbase64-encode-regionと同様だがRFC4648にしたがいBase64エンコーディングのURLバリアントを実装する。エンコードされたテキストに改行を挿入しないので、出力は1行だけの長い行となる。

オプション引数no-padは非nilなら、この関数はパディング(=)を生成しない。

Function: base64-encode-string string &optional no-line-break

この関数は文字列stringをBase64コードに変換する。これはエンコードされたテキストを含む文字列をリターンする。base64-encode-regionと同じように文字列内の文字がマルチバイトならエラーをシグナルする。

この関数は通常は行が長くなりすぎるのを防ぐためにエンコードされたテキストに改行を挿入する。しかしオプション引数no-line-breakが非nilなら、これらの改行は追加されず結果となる文字列は長い単一の行となる。

Function: base64url-encode-string string &optional no-pad

base64-encode-stringと同様だがBase64のURLバリアントを生成する。エンコードされたテキストに改行を挿入しないので、結果は1行だけの長い行となる。

オプション引数no-padは非nilなら、この関数はパディングを生成しない。

Command: base64-decode-region beg end &optional base64url ignore-invalid

この関数はbegからendのリージョンのBase64コードを対応するデコードされたテキストに変換する。これはデコードされたテキストの長さをリターンする。

デコード関数はエンコード済みテキスト内の改行文字を無視する。

オプション引数base64urlが非nilならパディングはオプションであり、Base64エンコーディングのURLバリアントが使用される。オプション引数ignore-invalidが非nilの場合には、認識できない文字はすべて無視される。

Function: base64-decode-string string &optional base64url ignore-invalid

この関数は文字列stringを、Base64コードから対応するデコード済みテキストに変換する。これはデコード済みテキストを含むユニバイトをリターンする。

デコード関数はエンコード済みテキスト内の改行文字を無視する。

オプション引数base64urlが非nilならパディングはオプションであり、Base64エンコーディングのURLバリアントが使用される。オプション引数ignore-invalidが非nilの場合には、認識できない文字はすべて無視される。


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

33.26 チェックサムとハッシュ

Emacsには暗号化ハッシュ(cryptographic hashes)計算用のビルトインのサポートがあります。暗号化ハッシュ、またはチェックサム(checksum)とはデータ断片にたいするデジタルな指紋(fingerprint)であり、そのデータが変更されていないかチェックするために使用できます。

EmacsはMD5、SHA-1、SHA-2、SHA-224、SHA-256、SHA-384、SHA-512のような一般的な暗号化ハッシュアルゴリズムをサポートします。これらのアルゴリズムのうちMD5はもっとも古く、ネットワーク越しに転送されたメッセージの整合性をチェックするために一般的にはメッセージダイジェスト(message digests)内で使用されています。MD5とSHA-1は‘衝突耐性(collision resistant)をもたない(同じMD5またはSHA-1のハッシュをもつ異なるデータ片を故意にデザインすることが可能)ので、セキュリティに関連することに使用するべきではありません。セキュリティーに関するアプリケーションではSHA-2 (sha256sha512)のような他のハッシュタイプを使用するべきです。

Function: secure-hash-algorithms

この関数はsecure-hashが使用可能なアルゴリズムを表すシンボルのリストをリターンする。

Function: secure-hash algorithm object &optional start end binary

この関数はobjectにたいするハッシュをリターンする。引数algorithmはどのハッシュを計算するかを示すシンボルでmd5sha1sha224sha256sha384sha512のいずれか。引数objectはバッファーまたは文字列であること。

オプション引数startendは、メッセージダイジェストを計算するobject部分を指定する文字位置。これらがnilか省略なら、object全体にたいしてハッシュを計算する。

引数binaryが省略かnilなら、通常のLisp文字列としてハッシュのテキスト形式(text form)をリターンする。binaryが非nilなら、ユニバイト文字列に格納されたバイトシーケンスとしてハッシュのバイナリー形式(binary form)をリターンする。リターンされる文字列の長さはalgorithmに依存する:

  • md5: 32文字(binaryが非nilなら32バイト)
  • sha1: 40文字(binaryが非nilなら40バイト)
  • sha224: 56文字(binaryが非nilなら56バイト)
  • sha256: 64文字(binaryが非nilなら64バイト)
  • sha384: 96文字(binaryが非nilなら96バイト)"
  • sha512: 128文字(binaryが非nilなら128バイト)"

この関数はobjectのテキストの内部表現(テキストの表現方法を参照)からハッシュを直接計算しない。かわりにコーディングシステム(コーディングシステムを参照)を使用してテキストをエンコードして、そのエンコード済みテキストからハッシュを計算する。objectがバッファーなら使用されているコーディングが、バッファーのテキストをファイルに書き込むためのデフォルトとして選択される。objectが文字列ならユーザーの好むコーディングシステムが使用される(Recognize Coding in GNU Emacs Manualを参照)。

Function: md5 object &optional start end coding-system noerror

この関数はMD5ハッシュをリターンする。これはほとんどの目的において、algorithm引数にmd5を指定してsecure-hashを呼び出すのと等価であり半ば時代遅れである。引数のobjectstartendsecure-hashのときと同じ意味をもつ。この関数は32文字の文字列をリターンする。

coding-systemが非nilなら、それはテキストをエンコードするために使用するコーディングシステムを指定する。省略またはnilなら、secure-hashと同様にデフォルトコーディングシステムが使用される。

md5は通常は指定や選択されたコーディングシステムを使用してテキストをエンコードできなければエラーをシグナルする。しかしnoerrorが非nilなら、かわりに黙ってraw-textコーディングシステムを使用する。

Function: buffer-hash &optional buffer-or-name

buffer-or-nameのハッシュをリターンする。nilの場合のデフォルトはカレントバッファー。この関数はsecure-hashとは対照的にコーディングシステムとは無関係にバッファーの内部表現にもとづいてハッシュを計算する。したがって同一のEmacs上で実行中の2つのバッファーを比較する際にのみ有用であり、異なるバージョンのEmacs間で同じハッシュをリターンする保証はない。これは巨大なバッファーにたいしてsecure-hashより幾分効果的であり、secure-hashほど多くのメモリーを割り当てないはずである。

Function: sha1 object &optional start end binary

この関数は以下のようにsecure-hashを呼び出すことと同じ:

(secure-hash 'sha1 object start end binary)

これはbinarynilなら40文字の文字列、それ以外の場合には40バイトのユニバイト文字列をリターンする。


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

33.27 不審なテキスト

Emacsでは電子メールやWebサイトのような多くの外部ソースを表示することができます。アタッカー(攻撃者)は難読化したURLや電子メールアドレスを使い、それらのテキストを読むユーザーを混乱させて、意図していないウェブページに誘導したり、誤ったアドレスにメールを送信するようユーザーを欺くのです。

これには通常だとASCII文字と似た外観をもつスクリプトの文字(homographs、すなわち綴りは同じでも意味の違う文字)が必要ですが、bdo(bidirectional override: 双方向オーバーライド)や、何かを示すHTMLの背後に別のどこかを指し示すURLを仕込むといった別のテクニックも存在します。

これら不審なテキスト文字列(suspicious text strings)の識別を助けるために、Emacsはテキストにたいしていくつかのチェックを行うライブラリーを提供します(利用可能なチェックの背景となる根拠に関する詳細についてはUTS #39: Unicode Security Mechanismsを参照)。疑わしい恐れのあるデータを提供するパッケージは、表示に際して不審なテキストにフラグを立てるためにこんなライブラリーを使う必要があります。

Function: textsec-suspicious-p object type

この関数はパッケージが使用すべき高レベルのインターフェイス関数である。チェックの無効化をユーザーに許すユーザーオプションtextsec-checkを考慮する。

この関数はtypeのオブジェクトとしてobject(データのタイプはtypeに依存)を評価した際に疑わしいかどうかをチェックする。利用できるタイプおよび対応するobjectのデータタイプは以下のとおり:

domain

不審なドメイン(例: ‘www.gnu.org’)かどうかをチェック。objectはドメイン名(文字列)。

url

不審なURL(例: ‘http://gnu.org/foo/bar’)かどうかをチェック。objectはチェックするURL(文字列)。

link

不審なHTMLリンク(例: ‘<a href='http://gnu.org'>fsf.org</a>’)かどうかをチェック。この場合にはobjectcarURL文字列、cdrがリンクテキストであるようなconsセルであること。リンクテキストにドメイン名が含まれていて、それがURLと異なるドメイン名を指す場合には不審なリンクとみなされる。

email-address

不審な電子メールアドレス(例: ‘foo@example.org’)かどうかをチェック。objectは文字列であること。

local-address

電子メールアドレスのローカル部分(‘@’記号の前の部分が疑わしいかどうかをチェック。objectは文字列であること。

name

名前(電子メールアドレスのヘッダーに使用される)が疑わしいかどうかをチェック。objectは文字列であること。

email-address-header

RFC2822に完全準拠した電子メールアドレス(例: ‘=?utf-8?Q?=C3=81?= <foo@example.com>’)が疑わしいかどうかをチェック。objectは文字列であること。

この関数はobjectが疑わしい場合には、なぜそれが疑わしいかを説明する文字列をリターンする。objectに不審な点がなければ、この関数はnilをリターンする。

テキストが疑わしい場合には、アプリケーションはtextsec-suspiciousフェイスで疑わしいテキストファイルをマークするとともに、textsec-suspicious-pがリターンした説明を、何らかの手段(たとえばツールチップなど)でユーザーが利用できるようにする必要があります。疑わしい文字列にもとづいて何らかのアクション(たとえば疑わしい電子メールアドレスへのメール送信)を実行する前に、アプリケーションがユーザーに確認を求める場合もあります。


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

33.28 GnuTLS暗号化

GnuTLSとともにコンパイルされていれば、Emacsはビルトインの暗号化サポートを提供します。GnuTLSのAPI用語にしたがいダイジェスト(digests)、MAC(メッセージ認証符号)、共通鍵暗号(symmetric ciphers)、認証付き暗号(AEAD ciphers)のツールが利用できます。

ここで使用するIV(Initialization Vector: 初期化ベクトル)のような暗号化にある程度親しんでいる必要のある用語は詳細には定義しません。GnuTLSライブラリーの用語や構造を理解する助けとなる特定のドキュメントについてはhttps://www.gnutls.org/を参照してください。


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

33.28.1 GnuTLS暗号化入力のフォーマット

GnuTLS暗号化関数への入力はEmacs Lispのプリミティブかリストのいずれかにより、複数の方法で指定できます。

現在のところリストの形式はmd5secure-hashが動作する方法に似ています。

バッファー

入力として単にバッファーを渡すとバッファー全体が使用されることを意味する。

文字列

文字列は入力として直接使用される。(他のほとんどのEmacs Lisp関数とは異なり)関数の処理後に機密データ漏洩の機会を減少させるために関数が文字列を変更するかもしれない。

(buffer-or-string start end coding-system noerror)

これは上述のようにバッファーか文字列を指定するが、オプションでstartendで範囲を指定できる。

加えて必要ならオプションでcoding-systemを指定できる。

最後のオプションのアイテムnoerrorは指定もしくは選択されたコーディングシステムを使用してテキストをエンコードできない際の通常のエラーをオーバーライドする。noerrorが非nilなら関数は暗黙にraw-textコーディングシステムをかわりに使用する。

(iv-auto length)

これは指定した長さのランダムなIV(Initialization Vector: 初期化ベクトル)を生成して関数に渡す。これによってIVが予測不可能となり、かつ同一セッション内での再利用があり得なくなることが保証される。


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

33.28.2 GnuTLS暗号化関数

Function: gnutls-digests

この関数はGnuTLSダイジェストアルゴリズムのalistをリターンする。

各エントリーはアルゴリズムを表すキーとアルゴリズムの内部的な詳細を表すplistをもつ。plistは結果となるダイジェストのバイトサイズを示す:type gnutls-digest-algorithm、および:digest-algorithm-length 64のキーももつだろう。

GnuTLS MACとダイジェストアルゴリズムの間には類似した名前が存在するが、これらは内部的には別物であり混在させるべきではない。

Function: gnutls-hash-digest digest-method input

digest-methodgnutls-digests由来の完全なplist、単なるシンボルキー、またはシンボル名の文字列でもよい。

inputはバッファー、文字列、もしくは他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。

この関数はエラー時にはnildigest-methodinputが無効ならLispエラーをシグナルする。成功時にはバイナリー文字列(出力)と使用されるIVのリストをリターンする。

Function: gnutls-macs

この関数はGnuTLS MACアルゴリズムのalistをリターンする。

各エントリーはアルゴリズムを表すキーとアルゴリズムの内部的な詳細を表すplistをもつ。このplistは結果となるハッシュ、キー、ナンスのバイトサイズを示すキー:type gnutls-mac-algorithm:mac-algorithm-length:mac-algorithm-keysize:mac-algorithm-noncesize

現在のところナンスは使用されておらず、いくつかのMACでのみサポートされる。

GnuTLS MACとダイジェストアルゴリズムの間には類似した名前が存在するが、これらは内部的には別物であり混在させるべきではない。

Function: gnutls-hash-mac hash-method key input

hash-methodgnutls-macs由来の完全なplist、単なるシンボルキー、またはシンボル名の文字列でもよい。

keyはバッファー、文字列、あるいは他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。keyが文字列なら使用後に消去される。

inputはバッファー、文字列、もしくは他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。

この関数はエラー時にはnilhash-methodkeyinputが無効ならLispエラーをシグナルする。

成功時にはバイナリー文字列(出力)と使用されるIVをリターンする。

Function: gnutls-ciphers

この関数はGnuTLS暗号のリストをリターンする。

各エントリーは暗号を表すキーとそのアルゴリズムに関する内部的な詳細を表すplistをもつ。このplistは:type gnutls-symmetric-cipher、およびAEAD機能を示すためにniltにセットされたキー:cipher-aead-capable、さらにタグ、結果データのブロックサイズ、キー、IVのバイトサイズを示すキー:cipher-tagsize:cipher-blocksize:cipher-keysize :cipher-ivsizeももつ。

Function: gnutls-symmetric-encrypt cipher key iv input &optional aead_auth

ciphergnutls-ciphers由来の完全なplist、単なるシンボルキー、またはシンボル名の文字列でもよい。

keyはバッファー、文字列、あるいは他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。keyが文字列なら使用後に消去される。

ivinput、およびオプションのaead_authはバッファー、文字列、または他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。

aead_authはAEAD暗号、すなわちplistが:cipher-aead-capable tをもつ暗号でのみチェックされて、他では無視される。

この関数エラー時にはnilcipherkeyivinputが無効だったり、AEAD暗号でaead_authが指定されてそれが無効な場合にはLispエラーをシグナルする。

成功時にはバイナリー文字列(出力)と使用されるIVをリターンする。

Function: gnutls-symmetric-decrypt cipher key iv input &optional aead_auth

ciphergnutls-ciphers由来の完全なplist、単なるシンボルキー、またはシンボル名の文字列でもよい。

keyはバッファー、文字列、あるいは他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。keyが文字列なら使用後に消去される。

ivinput、およびオプションのaead_authはバッファー、文字列、または他の方法(GnuTLS暗号化入力のフォーマットを参照)でも指定できる。

aead_authはAEAD暗号、すなわちplistが:cipher-aead-capable tをもつ暗号でのみチェックされて、他では無視される。

この関数は解読エラー時にはnilcipherkeyivinputが無効だったり、AEAD暗号で指定されたaead_authが無効な場合にはLispエラーをシグナルする。

成功時にはバイナリー文字列(出力)と使用されるIVをリターンする。


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

33.29 データベース

SQLiteデータベースへのアクセスにたいする組み込みサポートとともにEmacsをコンパイルできます。このセクションではLispプログラムからSQLiteデータベースへアクセスするために利用できる機能について説明します。

Function: sqlite-available-p

この関数はビルトインSQLiteサポートが利用可能なら非nilをリターンする。

SQLiteサポートが利用可能なら、以下の関数を利用できます。

Function: sqlite-open &optional file

この関数はfileをSQLiteのデータベースファイルとしてオープンする。fileが存在しなければ、新たなデータベースを作成して指定されたファイルに格納する。fileが省略またはnilなら、かわりにインメモリーのデータベースを作成する。

リターン値はデータベースオブジェクト(database object)。これは以下に挙げるほとんどの関数の引数として利用できる。

Function: sqlitep object

この述語関数はobjectがSQLiteデータベースオブジェクトなら非nilをリターンする。sqlite-openがリターンしたデータベースオブジェクトは、この述語を満足する。

Function: sqlite-close db

データベースdbを閉じる。通常はこの関数を明示的に呼び出す必要はない(Emacsのシャットダウンやデータベースオブジェクトがガーベージコレクトされればデータベースは自動的に閉じられる)。

Function: sqlite-execute db statement &optional values

SQLの命令文statementを実行時する。たとえば:

(sqlite-execute db "insert into foo values ('bar', 2)")

オプション引数valuesを与える場合には、それは命令を実行する際に値としてバインドされるリストかベクターのいずれかであること。

(sqlite-execute db "insert into foo values (?, ?)" '("bar" 2))

これは前の例とまったく同じ効果をもつが、より効率的かつ安全である(文字列の解析や挿入を何も行わないので)。

sqlite-executeは通常は影響を受ける行数をリターンする。たとえば‘insert’文は通常だと‘1’をリターンするが、‘update’文は0、あるいはそれより大きい値をリターンするかもしれない。ただし‘insert into … returning …やその類いのSQL文を使った際には、かわりに‘returning …によって指定された値がリターンされる。

SQLiteでの文字列は、デフォルトではutf-8として格納されて、テキストの列をselectした場合にはその文字セット(charset)を使って文字列をデコードする。blobの列をselectした場合には、何もデコードせずにrawデータをリターンする(データベースに格納されているバイトを含んだユニバイトをリターンする)。バイナリーデータをblob列にinsertする場合には、デフォルトではsqlite-executeはすべての文字列をutf-8と解釈するため注意を要する。

したがってたとえばgifと呼ばれるユニバイト文字列としてGIFデータをもっている場合には、sqlite-executeにそれが判るように特別にマークする必要がある:

(put-text-property 0 1 'coding-system 'binary gif)
(sqlite-execute db "insert into foo values (?, ?)" (list gif 2))
Function: sqlite-select db query &optional values return-type

dbからデータをselectしてそれをリターンする。たとえば:

(sqlite-select db "select * from foo where key = 2")
  ⇒ (("bar" 2))

sqlite-executeの場合と同様に、selectの実行前にバインドする値としてリストまたはベクターをオプションとして渡すことができる:

(sqlite-select db "select * from foo where key = ?" [2])
  ⇒ (("bar" 2))

これは前の例で用いた手法に比べて、通常はより効果的かつ安全である。

この関数はデフォルトではマッチした行のリストをリターンする(行は列の値のリスト)。return-typefullの場合には、リターン値の1つ目の要素として列の名前(文字列のリスト)をリターンする。

return-typesetなら、この関数はかわりにステートメントオブジェクト(statement object)をリターンする。このオブジェクトはsqlite-nextsqlite-columnssqlite-more-pといった関数を用いて調べることができる。結果セットが小さければ単に直接データをリターンするほうが便利な場合が多いが、結果セットが大きい場合(あるいはそのセットのデータすべてを使いたい場合)には、割り当てられるメモリーが大幅に小さくメモリー効率に優れたsetメソッドを使用すること。

Function: sqlite-next statement

この関数は結果セットstatement(通常はsqlite-selectがリターンしたオブジェクト)の次の行をリターンする。

(sqlite-next stmt)
    ⇒ ("bar" 2)
Function: sqlite-columns statement

この関数は結果セットstatement (通常はsqlite-selectがリターンしたオブジェクト)の列名をリターンする。

(sqlite-columns stmt)
    ⇒ ("name" "issue")
Function: sqlite-more-p statement

結果セットstatement(通常はsqlite-selectがリターンしたオブジェクト)からfetchできるデータがまだあるかどうかを調べる述語である。

Function: sqlite-finalize statement

これ以上statementを使わない場合には、この関数を呼び出すことによってstatementが使用していたリソースが解放される。この関数の呼び出しは通常は必要ない(statementオブジェクトがガーベージコレクトされれば、Emacsがそのオブジェクトのリソースを自動的に解放する)。

Function: sqlite-transaction db

dbでトランザクションを開始する。トランザクションにおいてはsqlite-commitによってそのトランザクションがコミットされるまでは、そのデータベースの他の読み取り手は結果にアクセスできない。

Function: sqlite-commit db

dbのトランザクションを終了して、データベースのファイルにデータを書き込む。

Function: sqlite-rollback db

dbのトランザクションを終了して、そのトランザクションによって行われたすべての変更を破棄する。

Macro: with-sqlite-transaction db body…

progn(順序を参照)と同様だが、トランザクションとともにbodyを実行して、最後にそのトランザクションをコミットする。

Function: sqlite-pragma db pragma

dbにおいてpragmaを実行する。pragmaとは特定のテーブルではなく、通常はデータベース全体に効果を及ぼすコマンドのこと。たとえば不要になったデータのガーベージコレクトをSQLiteに自動的に行わせるには、以下のようにすればよい:

(sqlite-pragma db "auto_vacuum = FULL")

この関数はpragmaが成功すれば非nil、失敗するとnilをリターンする。pragmaの多くは空の新規データベースでのみ発行できる。

Function: sqlite-load-extension db module

名前つきエクステンション(拡張)であるmoduleをデータベースdbにロードする。エクステンションは通常は共有ライブラリーであり、GNUおよびUnixのシステムではファイル名の拡張子として.soがつけられている。

Function: sqlite-version

使用中のSQLiteライブラリーのバージョンを表す文字列をリターンする。

SQLiteファイルの内容を一覧したければ、sqlite-mode-open-fileコマンドを使うことができます。これはSQLiteデータベースの調査(と変更)が可能なsqlite-modeのバッファーをポップアップします。


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

33.30 HTMLとXMLの解析

ビルトインのlibxml2サポートつきでEmacsをコンパイルできます。

Function: libxml-available-p

この関数はビルトインlibxml2サポートが利用可能なら非nilをリターンする。

libxml2サポートが利用可能なら、HTMLやXMLのテキストをLispオブジェクトツリーにパースするために以下の関数を利用できます。

Function: libxml-parse-html-region &optional start end base-url discard-comments

この関数はstartendの間のテキストをHTMLとしてパースして、HTMLパースツリー(parse tree)を表すリストをリターンする。これは構文誤りにたいして強力に対処することにより、現実世界のHTMLの処理を試みる。

startまたはendnilの場合のデフォルト値は、それぞれpoint-minpoint-maxになる。

オプション引数base-urlが非nilなら、それはlibxml2がレポートする警告とエラーに使用されるべきだが、現在のところEmacsはエラーと警告を無効にしてこのライブラリーを呼び出すのでこの引数は使用されていない。

オプション引数discard-commentsが非nilなら、すべてのトップレベルのコメントを破棄する(この引数は時代遅れでありEmacsの将来のバージョンで削除されるだろう。コメントの削除にはパース関数の呼び出し前にデータにユーティリティ関数xml-remove-commentsを使用すること)。

パースツリー内では各HTMLノードは1つ目の要素がノード名を表すシンボル、2つ目の要素がノード属性のalist、残りの要素はサブノードであるようなリストにより表される。

以下の例でこれを示す。以下の(不正な)HTMLドキュメントを与えると:

<html><head></head><body width=101><div class=thing>Foo<div>Yes

libxml-parse-html-region呼び出しにより以下のDOM (document object model)がリターンされる:

(html nil
 (head nil)
 (body ((width . "101"))
  (div ((class . "thing"))
   "Foo"
   (div nil
    "Yes"))))
Function: shr-insert-document dom

この関数はdom内のパース済みHTMLをカレントバッファー内に描画する。引数domlibxml-parse-html-regionで生成されるようなリストであること。この関数はたとえばEWW in The Emacs Web Wowser Manualにより使用される。

Function: libxml-parse-xml-region &optional start end base-url discard-comments

この関数はlibxml-parse-html-regionと同様だが、HTMLではなくXML(構文についてより厳格)としてテキストをパースする点が異なる。


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

33.30.1 ドキュメントオブジェクトモデル

libxml-parse-html-region (およびその他のXMLパース関数)がリターンするDOMはツリー構造です。このツリー構造ではそれぞれのノードがノード名(タグ(tag)と呼ばれる)をもち、オプションでkey/value値からなる属性(attribute)リスト、その後に子ノード(child nodes)が続きます。子ノードは文字列かDOMオブジェクトのいずれかです。

(body ((width . "101"))
 (div ((class . "thing"))
  "Foo"
  (div nil
   "Yes")))
Function: dom-node tag &optional attributes &rest children

この関数はタイプtagDOMノードを作成する。もしattributesが与えられたら、それはkey/valueペアのリストであること。もしchildrenが与えられたら、それはDOMノードであること。

この構造を処理するために以下の関数を使用できます。それぞれの関数はDOMノードかノードのリストを受け取ります。後者の場合には、そのリストの最初のノードだけが使用されます。

シンプルなアクセサー

dom-tag node

ノードのタグ (“ノード名”とも呼ばれる)をリターンする。

dom-attr node attribute

ノードの属性の値をリターンする。以下は一般的な使用例:

(dom-attr img 'href)
=> "https://fsf.org/logo.png"
dom-children node

ノードのすべての子をリターンする。

dom-non-text-children node

ノードのすべての非文字列の子をリターンする。

dom-attributes node

ノードの属性のkey/valueペアのリストをリターンする。

dom-text node

ノードのすべてのテキスト的な要素を連結された文字列としてリターンする。

dom-texts node

ノードのすべてのテキスト的な要素、およびノードのすべての子のテキスト的な要素を、連結された文字列として再帰的にリターンする。この関数はテキスト的な要素の間に挿入するオプションのセパレーターも受け取る。

dom-parent dom node

dom内でのnodeの親をリターンする。

dom-remove dom node

domからnodeを削除する。

以下はDOMを変更するための関数です。

dom-set-attribute node attribute value

ノードのattributevalueをセットする。

dom-remove-attribute node attribute

nodeからattributeを削除する。

dom-append-child node child

nodeの最後の子としてchildを追加する。

dom-add-child-before node child before

nodeの子リストのノードbeforeの前にchildを追加する。beforenilなら、childが最初の子になる。

dom-set-attributes node attributes

ノードのすべての属性を新たなkey/valueリストに置き換える。

以下はDOM内の要素を検索する関数です。これらはマッチしたノードのリストをリターンします。

dom-by-tag dom tag

dom内のタイプがtagのすべてのノードをリターンする。典型的な使用例は:

(dom-by-tag dom 'td)
=> '((td ...) (td ...) (td ...))
dom-by-class dom match

dom内のクラス名が正規表現matchにマッチするすべてのノードをリターンする。

dom-by-style dom style

dom内のスタイルが正規表現matchにマッチするすべてのノードをリターンする。

dom-by-id dom style

dom内のIDが正規表現matchにマッチするすべてのノードをリターンする。

dom-search dom predicate

predicateが非nil値をリターンしたdom内のすべてのノードをリターンする。predicateはテストされるノードをパラメーターとして呼び出される。

dom-strings dom

dom内のすべての文字列をリターンする。

ユーティリティ関数:

dom-pp dom &optional remove-empty

ポイント位置のdomにたいしてプリティプリント(pp: 優雅なプリント)を行う。remove-emptyなら空白文字だけを含むテキスト的ノードはプリントしない。

dom-print dom &optional pretty xml

ポイント位置のdomをプリントする。xmlが非nilならXML、それ以外ならHTMLとしてプリントする。prettyが非nilなら、HTML/XMLを論理的にプリントする。


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

33.31 JSON値の解析と生成

JSON (JavaScript Object Notation)のサポートつきでEmacsをコンパイルした場合には、LispオブジェクトとJSON値との間で変換を行う関数がいくつか提供されます。任意のJSON値をLispオブジェクトに変換できますが、その逆は成り立ちません。具体的には:

  • JSONはtruenullfalseという3つのキーワードを使用する。trueはシンボルtを表す。デフォルトでは残り2つのキーワードはそれぞれシンボル:null:falseで表される。
  • JSONには浮動小数点数しかない。これらはLisp整数とLisp浮動小数点数の両方を表すことができる。
  • JSON文字列は常にUTF-8でエンコードされたUnicode文字列になる。Lisp文字列は非Unicode文字を含むことができる。
  • JSONのシーケンス型は配列のみ。JSON配列はLispベクターを使用して表される。
  • JSONのマップ型はオブジェクトのみ。JSONオブジェクトはLispのハッシュテーブル、alist、plistsを使用して表される。alistやplistが同じキーで複数の要素を含む際には、Emacsはassqの挙動にしたがいシリアライズに最初の要素だけを使用する。

alistとplistの両方で有効なnilは、空のJSONオブジェクト{}を表すことに注意してください。nullfalse、空の配列はJSONではすべて異なる値です。

Function: json-available-p

この述語はJSONサポート付きでEmacsがビルドされていて、そのライブラリーがカレントシステムで利用可能なら非nilをリターンする。

JSONで何らかのLispオブジェクトを表現できなければ、シリアライゼーション関数はタイプwrong-type-argumentのエラーをシグナルします。パース関数も以下のエラーをシグナルする可能性があります:

json-unavailable

パース用ライブラリーが利用できない際にシグナルされる。

json-end-of-file

入力テキストの早すぎる終端に遭遇した際にシグナルされる。

json-trailing-content

パース済みの最初のJSONオブジェクトの後で予期せぬ入力に遭遇した際にシグナルされる。

json-parse-error

無効なJSON構文に遭遇した際にシグナルされる。

トップレベルの値、およびそれらトップレベル値のサブオブジェクトをJSONにシリアライズできます。同様にパース関数は上述の利用可能なタイプをリターンします。

Function: json-serialize object &rest args

この関数はobjectのJSON表現を含むLisp文字列を新たにリターンする。引数argsはキーワード/引数のペアからなるリスト。以下のキーワードが可能:

:null-object

値はJSONキーワードのnullを表すために使用するLispオブジェクトを決定する。デフォルトはシンボル:null

:false-object

値はJSONキーワードのfalseを表すために使用するLispオブジェクトを決定する。デフォルトはシンボル:false

Function: json-insert object &rest args

このコマンドはカレントバッファーのポイントの前にobjectのJSON表現を挿入する。引数argsjson-parse-stringの場合と同様に扱われる。

Function: json-parse-string string &rest args

この関数はstring (Lisp文字列でなければならない)内のJSON値をパースする。stringに有効なJSONオブジェクトが含まれていなければ、この関数はjson-parse-errorエラーをシグナルする。

引数argsはキーワード/引数のペアのリスト。以下のキーワードが許されている:

:object-type

値はJSONオブジェクトのキーと値のマッピングを表現するために使用するLispオブジェクトを決定する。文字列をキーとするハッシュテーブルhash-table (デフォルト)、シンボルをキーとするalistを使用するalist、キーワードシンボルをキーとするplistを使用するplistのいずれかが可能。

:array-type

値はJSON配列の表現に使用するLispオブジェクトを決定する。Lisp配列を使用するarray (デフォルト)、またはリストを使用するlistのいずれかが可能。

:null-object

値はJSONキーワードのnullを表すために使用するLispオブジェクトを決定する。デフォルトはシンボル:null

:false-object

値はJSONキーワードのfalseを表すために使用するLispオブジェクトを決定する。デフォルトはシンボル:false

Function: json-parse-buffer &rest args

この関数はカレントバッファーのポイント位置の文字列から、次のJSON値を読み取る。値に有効なJSONオブジェクトが含まれていれば値の直後にポイントを移動、それ以外ならjson-parse-errorエラーをシグナルしてポイントは移動しない。引数argsjson-parse-stringの場合と同様に解釈される。


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

33.32 JSONRPCによる対話

jsonrpcライブラリーはhttps://www.jsonrpc.org/に記載されたJSONRPC仕様を実装します。JSONRPCはその名前が示すように、Lispとの間で相互に変換可能なJSONオブジェクトを中心に設計された、遠隔手続呼出(Remote Procedure Call)のための汎用プロトコルです。


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

33.32.1 概観

specから引用するとJSONRPCは、"同一プロセス、ソケットやhttp、多くのさまざまなメッセージパッシング環境において使用可能という概念においてトランスポート非依存"です。

この非依存性をモデル化するために、jsonrpcライブラリーはリモートのJSONのエンドポイントへの接続の表現にjsonrpc-connectionクラスのオブジェクトを使用します(Emacsのオブジェクトシステムの詳細はEIEIO in EIEIOを参照)。これはオブジェクト指向の現代的な用語では“抽象的(abstract)”なクラス、すなわち有用な接続オブジェクトの実クラスは常にjsonrpc-connectionのサブクラスになります。それにも関わらず、jsonrpc-connectionクラスを中心に2つのAPIを個別に定義できます。

  1. JSONRPCアプリケーション構築用のユーザーインターフェース

    このシナリオではJSONRPCアプリケーションはjsonrpc-connectionの具象サブクラスを選択して、make-instanceを使用することによりサブクラスのオブジェクト作成を行う。JSONRPCアプリケーションはリモートのエンドポイントとの対話を開始するために、関数jsonrpc-notifyjsonrpc-request、および/またはjsonrpc-async-requestにこのオブジェクトを渡す。一般的には非同期に到達するリモートで開始された対話を処理するために、インスタンス化には:request-dispatcher:notification-dispatcherの初期化引数(initarg)を含める必要があり、これらはいずれも接続オブジェクト、リモートで呼び出されたJSONRPCメソッドを命名するシンボル、JSONRPCのparamsオブジェクトという3つの引数を受け取る関数である。

    :request-dispatcherとして渡された関数は、ローカルのエンドポイントからのリプライ(この場合では構築するプログラム)を除いた、リモートのエンドポイントのリクエストを処理する役目を担う。その関数の内部では局所的なリターン(通常のリターン)と非局所的なリターン(エラーによるリターン)が起こり得る。局所的なリターン値はJSONとしてシリアライズ可能なLispオブジェクトでなければならない(JSON値の解析と生成を参照)。これは成功レスポンスを決定するとともに、オブジェクトはJSONRPCのresultオブジェクトとしてサーバーにフォワードされる。関数jsonrpc-errorの呼び出しにより達成される非局所的なリターンは、エラーレスポンスをサーバーに送信する。JSONRPCのerrorに付随する詳細には、jsonrpc-errorに渡されるものすべてが含まれる。他のタイプの予期せぬエラーからトリガーされた非局所的なリターンでも、( debug-on-errorをセットしていなければ)エラーレスポンスを送信して、この場合にはLispデバッガが呼び出される。エラーによるデバッガへのエンターを参照のこと。

  2. JSONRPCトランスポート実装構築用の継承インターフェース

    このシナリオでは基盤として異なるトランスポートストラテジーを実装するためにjsonrpc-connectionをサブクラス化する(サブクラス化する方法についての詳細は(eieio)Inheritanceを参照)。その後にアプリケーション構築インターフェースのユーザーは、( make-instance関数を使用して)その具象クラスのオブジェクトをインスタンス化して、そのストラテジーを使用してJSONRPCエンドポイントに接続できる。

    このAPIには必須部分とオプション部分がある。

    ユーザーがJSONRPCコンタクト(通知やリクエスト)を開始したり、エンドポイントにリプライできるようにするためには、そのサブクラスはjsonrpc-connection-sendメソッドを実装しなければならない。

    同様に3種類のリモートコンタクト(リクエスト、通知、ローカルリクエストへの応答)を処理するために、トランスポート実装はワイヤー(wire: 通信ライン)上への新たなJSONRPCメッセージの通知後に、(その"ワイヤー"が何であれ)関数jsonrpc-connection-receiveが呼び出されるように計らわなければならない。

    最後にオプジョンとしてjsonrpc-shutdownメソッドとjsonrpc-running-pメソッドの概念をトランスポートに適用する場合には、jsonrpc-connectionサブクラスはそれらのメソッドを実装する必要がある。それらを行う場合には、ワイヤー上でメッセージをリッスン(listen)するために使用するシステムリソース(プロセス、タイマー等)はjsonrpc-shutdownで解放する必要がある(それらのリソースはjsonrpc-running-pが非nilの間だけ必要なはずなので)。


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

33.32.2 プロセスベースのJSONRPC接続

jsonrpcライブラリーには利便性のために、ローカルサブプロセス(標準入力と標準出力を使用)やTCPホスト(ソケットを使用)、またはEmacsのプロセスオブジェクトが表現可能な他のリモートのエンドポイント(プロセスを参照)と対話可能なビルトインのjsonrpc-process-connectionトランスポート実装が付属しています。

このトランスポートを使用することによりJSONRPCメッセージはワイヤー上にプレーンテキストとしてエンコードされて、“Content-Length”のように何らかの基本的なHTTPスタイルのエンベロープヘッダーが前置されます。

このJSONRPC最上層のトランスポートスキームを使用したアプリケーションの例は、Language Server Protocolを参照してください。

:request-dispatcher:notification-dispatcherという必須の初期化引数(initarg)に加えて、jsonrpc-process-connectionクラスのユーザーはmake-instanceへのキーワード/値ペアとして以下の初期化引数を渡す必要があります:

:process

値は生きたプロセスオブジェクト、またはそのようなオブジェクトを生成する引数のない関数でなければならない。プロセスオブジェクトを渡された場合には、そのオブジェクトには事前に確立された接続が含まれていることが期待される。それ以外の場合には、オブジェクトの作成直後に関数が呼び出される。

:on-shutdown

値はjsonrpc-process-connectionオブジェクトを単一の引数とする関数でなければならない。この関数は背後にあるプロセスオブジェクトの削除(jsonrpc-shutdownによる故意の削除、または何らかの外部要因による予期せぬ削除)の後に呼び出される。


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

33.32.3 JSONRPCのJSONオブジェクトフォーマット

JSONRPCのJSONとLispのplist(プロパティリストを参照)は交換することができます。JSON互換のplistをディスパッチャ関数に渡したり、同様にJSON互換のplistをjsonrpc-notifyjsonrpc-requestjsonrpc-async-requestに渡すことができます。

plist処理を容易にするために、このライブラリーはcl-libライブラリー(cl-lib in Common Lisp Extensions for GNU Emacs Lispを参照)の積極的に使用しており、そのクライアントにたいしてもこれを同じように提案します(強制ではない)。以下の例のようにJSONオブジェクトの非構造化用lambdaの作成にはマクロjsonrpc-lambdaを使用できます:

(jsonrpc-async-request
 myproc :frobnicate `(:foo "trix")
 :success-fn (jsonrpc-lambda (&key bar baz &allow-other-keys)
               (message "Server replied back with %s and %s!"
                        bar baz))
 :error-fn (jsonrpc-lambda (&key code message _data)
             (message "Sadly, server reports %s: %s"
                      code message)))

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

33.32.4 遅延されたJSONRPCリクエスト

多くのRPC状況下において、対話中の2つのエンドポイント間での同期は、RPCアプリケーションを正しくデザインするために問題となります。同期が必要な際にはリクエスト(ブロックする)、不必要なら通知で十分です。しかしこれらのエンドポイントのいずれかでEmacsが動作している際にはリモートエンドポイントの状態に不確実性が依然として残っているので、(タイマーやプロセスに関連する)非同期イベントがトリガーされる可能性があります。さらにこれらのイベントへの対応では、イベント固有の性質により、同期の要求が限定されるかもしれません。

jsonrpc-requestjsonrpc-async-requestにたいするキーワード引数:deferredは特定のリクエストに同期が必要なことを呼び出し側が示せるようにして、リクエストの実際の発行は何らかの条件が満足されるまで遅延できるようにデザインされています。あるリクエストへの:deferred指定はリクエストが遅延されるのではなく、遅延される可能性があることを意味します。リクエストが即座に送信されなければ、エンドポイントにたいして他のメッセージの受信や送信を行う際のように、通信中の特定タイミングでjsonrpcはリクエストを送る新たな試みを行います。

リクエストを送信するすべての試みの前にアプリケーション固有の条件がチェックされます。jsonrpcライブラリーがこれらの条件を知ることはできないので、それらを指定するためにプログラムはジェネリック関数jsonrpc-connection-ready-pを使用できます(ジェネリック関数を参照)。この関数のデフォルトメソッドはtをリターンしますが、これをオーバーライドして渡された引数( jsonrpc-connectionオブジェクト。概観を参照)とキーワード引数:deferredとして渡されたすべて値にもとづいてnilをリターンするメソッドを追加できます。


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

33.33 グループのアトミックな変更

データベース用語においてのアトミック(atomic: 原子的、不可分)な変更とは、全体として成功か失敗をすることはできるが、部分的にはできない個別の変更のことです。Lispプログラムは単一もしくは複数のバッファーにたいする一連の変更をアトミック変更グループ(atomic change group)にすることができます。これはその一連の変更全体がそれらのバッファーに適用されるか、またはエラーの場合は何も適用されないかの、いずれかであることを意味します。

すでにカレントであるような単一のバッファーにたいしてこれを行うには、以下のように単に変更を行うコードの周囲にatomic-change-groupの呼び出しを記述します:

(atomic-change-group
  (insert foo)
  (delete-region x y))

atomic-change-groupのbody内部でエラー(またはその他の非ローカルexit)が発生した場合には、そのbodyの実行の間にそのバッファーでのすべての変更が行われなかったことになります。この類の変更グループは他のバッファーには影響を与えず、それらのバッファーにたいする変更はそのまま残されます。

さまざまなバッファー内で行った変更から1つのアトミックグループを構成する等、より複雑な何かを必要とする場合には、atomic-change-groupが使用する、より低レベルな関数を直接呼び出さなければなりません。

Function: prepare-change-group &optional buffer

この関数はbuffer (デフォルトはカレントバッファー)にたいする変更グループをセットアップする。これはその変更グループを表すhandleをリターンする。変更グループをactivateしたり、その後でそれを完了するためにはこのhandleを使用しなければならない。

変更グループを使用するためには、それをactivate(アクティブ化)しなければなりません。これはbufferのテキストを変更する前に行わなければなりません。

Function: activate-change-group handle

これはhandleが指定する変更グループをactiveにする。

変更グループをactivateした後には、そのバッファー内で行ったすべての変更は変更グループの一部となります。そのバッファー内で目論んでいたすべての変更を行ったら、変更グループをfinish(完了)しなければなりません。すべての変更を受け入れる(確定する)か、すべてをキャンセルするという2つの方法により、これを行うことができます。

Function: accept-change-group handle

この関数はhandleにより指定される変更グループ内のすべての変更にたいして、finalizeすることにより変更を受け入れる。

Function: cancel-change-group handle

この関数はhandleにより指定される変更グループ内のすべての変更をキャンセルしてundoする。

undo-amalgamate-change-groupを使用すれば、いくつか、あるいはすべての変更をundoコマンド(アンドゥを参照)の対象として単一の単位とみなせる変更グループにすることができます。

Function: undo-amalgamate-change-group

handleにより識別される状態以降にお子なわれた変更グループへの変更をすべてまとめる。この関数はhandleにより記述された状態以降の変更にたいするアンドゥレコード間のアンドゥ境界すべてを削除する。handleは通常はprepare-change-groupがリターンしたハンドルであり、この場合には変更先頭以降のすべての変更は、単一のアンドゥ単位にまとめられる。

グループが常に確実にfinishされるようにするために、コードではunwind-protectを使用するべきです。activate-change-groupの呼び出しは、実行直後にユーザーがC-gをタイプする場合に備えてunwind-protect内部にあるべきです(これがprepare-change-groupactivate-change-groupが別関数となっている1つの理由。なぜなら通常はunwind-protect開始前にprepare-change-groupを呼び出すであろうから)。グループを一度finishしたら、そのhandleを再度使用してはなりません。特に同じ変更グループを2回finishしないでください。

複数バッファー変更グループ(multibuffer change group)を作成するためには、カバーしたいバッファーそれぞれでprepare-change-groupを一度呼び出してから、以下のようにリターン値を結合するためにnconcを使用してください:

(nconc (prepare-change-group buffer-1)
       (prepare-change-group buffer-2))

その後は1回のactivate-change-group呼び出しで複数変更グループをアクティブにして、1回のaccept-change-groupcancel-change-group呼び出しでそれをfinishしてください。

同一バッファーにたいするネストされた複数の変更グループ使用は、あなたが期待するであろう通りに機能します。同一バッファーにたいするネストされていない変更グループの使用によりEmacsが混乱した状態になるので、これが発生しないようにしてください。与えられた何らかのバッファーにたいして最初に開始した変更グループは最後にfinishする変更グループです。


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

33.34 フックの変更

以下のフック変数によりバッファー(これらをバッファーローカルにした場合には特定のバッファー)での変更にたいして、通知を受け取るようにアレンジすることができます。テキストの特定部分にたいする変更の検出方法については特殊な意味をもつプロパティも参照してください。

これらのフック内で使用する関数は、もしそれらが正規表現を使用して何かを行う場合にはマッチしたデータの保存とリストアを行うべきです。さもないとそれらが呼び出す編集処理に奇妙な方法で干渉するでしょう。

Variable: before-change-functions

この変数はEmacsがバッファー変更を行おうとする際に呼び出す関数のリストを保持する。各関数は変更されようとするリージョンの先頭と終端を整数で表す2つの引数を受け取る。変更されようとするバッファーは関数の呼び出しの際には常にカレントバッファーである。

Variable: after-change-functions

この変数はEmacsがバッファー変更を行った後に呼び出す関数のリストを保持する。各関数は正に変更されたリージョンの先頭と終端、およびその変更前に存在したテキストの長さという3つの引数を受け取る。これら3つの変数は、すべて整数。変更されたバッファーは関数の呼び出しの際には常にカレントバッファーである。

古いテキストの長さは、変更される前のテキストでのテキストの前後のバッファー位置の差で与えられる。変更されたテキストでは、その長さは単に最初の2つの引数の差で与えられる。

これらの関数は*Messages*バッファーへのメッセージの出力では呼び出されず、特定の処理用にEmacsが作成する内部的なバッファーのようなLispプログラムからは可視であるべきではないバッファーへの変更でも呼び出されません。

バッファーを変更するプリミティブのほとんどは、釣り合いのとれたカッコ内でのそれぞれの変更にたいしてbefore-change-functionsafter-change-functionsを1回呼び出し、これらのフックにたいする引数は行われた変更を正確に区切ります。しかしフック関数は常にこのように行われると信頼すべきではありません。なぜなら複雑なプリミティブのいくつかは変更を行う前にbefore-change-functionsを呼び出してから、プリミティブが行なった個別の変更の数にもとづいてafter-change-functionsを0回以上呼び出すからです。これが発生した場合には、before-change-functionsの引数は個別の変更が行われたリージョンを囲むでしょうが、そのようなリージョンが最小である必要はなく、連続したafter-change-functions呼び出しそれぞれにたいする引数は変更されたテキスト部分を正確に区切るでしょう。一般的には、before-changeかafter-changeのいずれかのフックを使用して、両方は使用しないことを推奨します。

Macro: combine-after-change-calls body…

このマクロは普通にbodyを実行するが、もしそれが安全なように見えるなら一連の複数の変更にたいして正に一度、after-change関数を呼び出すようにアレンジする。

そのバッファーの同じ領域内でプログラムが複数のテキスト変更を行う場合には、その部分のプログラムの周囲でマクロcombine-after-change-callsを使用することにより、after-changeフック使用中の実行がかなり高速になり得る。after-changeフックが最終的に呼び出される際には、その引数はcombine-after-change-callsのbody内で行われたすべての変更にたいして含むバッファーの範囲を指定する。

警告: フォームcombine-after-change-callsのbody内でafter-change-functionsの値を変更してはならない。

警告: 組み合わされた変更がバッファーの広い範囲に点在してに出現する場合でも、これは依然として機能するが推奨できない。なぜならこれは、ある変更フック関数を非効率的な挙動へと導くかもしれないからである。

Macro: combine-change-calls beg end body…

これは通常のようにbodyを実行するが、before-change-functionsおよびafter-change-functionsの呼び出しをトリガーしないすべてのバッファー変更を除く。かわりにbegendで囲まれるリージョンにたいしてこれらのフックそれぞれを1回呼び出し、bodyが変更するサイズを反映したパラメーターをafter-change-functionsに与える。

このマクロの結果はbodyのリターンした結果。

このマクロはある関数がバッファーにたいして繰り返し多数の変更を行う可能性があり、このマクロ以外では個別のバッファー変更ごとにそれらの変更フックを実行するために実行に長時間を要する際に有用。Emacs自身は、たとえばコマンドcomment-regionuncomment-regionの中でこのマクロを使用している。

警告: body内でbefore-change-functionsafter-change-functionの値を変更してはならない。

警告: begendで指定したリージョン外部でのバッファー変更は何も行ってはならない。

Variable: first-change-hook

この変数は以前は未変更の状態だったバッファーが変更された際は常に実行されるノーマルフック。

Variable: inhibit-modification-hooks

この変数が非nilならすべての変更フックは無効。それらは何も実行されない。これはこのセクションで説明したすべてのフック変数、同様に特定のスペシャルテキストプロパティ(特殊な意味をもつプロパティを参照)とオーバーレイプロパティ(オーバーレイのプロパティを参照)にアタッチされたフックに影響を与える。

これらの同一フック変数上の関数の実行の間、バッファー変更によるデフォルトの変更フックが他の変更フック実行中に実行されないように、この変数は非nilにバインドされる。それ自体が変更フックから実行される特定のコード断片内で変更フックを実行したければ、inhibit-modification-hooksnilにローカルに再バインドすること。しかしこれを行うことで変更フックが再帰的に呼び出されるかもしれないのでそれに備えること(たとえばフックが何も行わないようにいくつかの変数をバインドする)。

バッファーのテキストコンテンツに永続的な変更をもたらさない変更(たとえばフェイス変更や一時的な変更)だけにこの変数をバインドすることを推奨する。一連の変更の間は変更フックを遅延させる必要がある(通常は性能上な理由による)なら、かわりにcombine-change-callscombine-after-change-callsを使用すること。


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

34 非ASCII文字

このチャプターは文字に関する特別な問題と、それらが文字列やバッファーに格納される方法について網羅しています。


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

34.1 テキストの表現方法

Emacsのバッファーと文字列は、既知のスクリプトで記述されたほとんどすべてのテキストをユーザーがタイプしたり表示できるように、多種多様な言語の広大な文字レパートリーをサポートします。

多種多様な文字やスクリプトをサポートするために、EmacsはUnicode標準(Unicode Standard)に厳密にしたがいます。Unicode標準はすべての文字それぞれにたいして、コードポイント(codepoint)と呼ばれる一意な番号を割り当てています。コードポイントの範囲はUnicode、またはUnicodeコード空間(codespace)により定義され、範囲は0..#x10FFFF(16進表記、範囲両端を含む)です。Emacsはこれを範囲#x110000..#x3FFFFFのコードポイント範囲に拡張します。この範囲はUnicodeとして統一されていない文字や、文字として解釈できない8ビットrawバイト(raw 8-bit bytes)を表すために使用します。したがってEmacs内の文字コードポイントは22ビットの整数になります。

メモリー節約のために、Emacsはバッファーや文字列内のテキスト文字にたいするコードポイントである22ビットの整数を固定長で保持しません。かわりにEmacsは文字の内部表現として可変長を使用します。これはそのコードポイントの値に応じて、各文字を5ビットから8ビットのバイトシーケンスとして格納するものです24。たとえばすべてのASCII文字は1バイト、Latin-1文字は2バイトといった具合です。わたしたちはこれをテキストのマルチバイト(multibyte)表現と呼んでいます。

Emacs外部ではISO-8859-1、GB-2312、Big-5等のような多種の異なるエンコーディングで文字を表すことができます。Emacsはバッファーや文字列へのテキスト読み込み時、およびディスク上のファイルへのテキスト書き込みや他プロセスへの引き渡し時に、これらの外部エンコーディングと内部表現の間で適切な変換を行います。

Emacsがエンコード済みテキストや非テキストデータをバッファーや文字列に保持したり操作する必要がある場合も時折あります。たとえばEmacsがファイルをvisitする際には、まずそのファイルのテキストをそのままバッファーに読み込んで、その後にのみそれを内部表現に変換します。この変換前にバッファーに保持されいるのはエンコード済みテキストです。

Emacsに関する限り、エンコードされたテキストは実際のテキストではなく8ビットrawバイトです。エンコード済みテキストを保持するバッファーや文字列は、Emacsがそれらを個々のバイトシーケンスとして扱うことから、ユニバイト(unibyte)のバッファー(文字列)と呼んでいます。Emacsは通常はユニバイトのバッファーや文字列を\237のような8進コードで表示します。エンコード済みテキストやバイナリー非テキストデータを処理する場合を除いて、ユニバイトバッファーとユニバイト文字列は決して使用しないよう推奨します。

バッファーでは変数enable-multibyte-charactersのバッファーローカルな値が使用する表現を指定します。文字列での表現は文字列構築時に判断して、それを文字列内に記録します。

Variable: enable-multibyte-characters

この変数はカレントバッファーのテキスト表現を指定する。非nilならバッファーはマルチバイトテキスト、それ以外ならエンコード済みユニバイトテキスト、またはバイナリー非テキストデータが含れる。

この変数は直接セットできない。バッファーの表現の変更には、かわりに関数set-buffer-multibyteを使用すること。

Function: position-bytes position

バッファー位置は文字単位で測られる。この関数はカレントバッファー内のバッファー位置を、それに対応するバイト位置でリターンする。これはバッファー先頭を1としてバイト単位で増加方向に数えられる。positionが範囲外なら値はnil

Function: byte-to-position byte-position

カレントバッファー内で与えられたbyte-positionに対応するバッファー位置を文字単位でリターンする。byte-positionが範囲外なら値はnil。マルチバイトバッファーではbyte-positionの任意の値が文字境界上になく、1文字として表現されたマルチバイトシーケンス内にあるかもしれない。この場合には関数はその文字のマルチバイトシーケンスがbyte-positionを含むようなバッファー位置をリターンする。言い換えるとこの値は同じ文字に属するすべてのバイト位置にたいして変化しない。

以下の2つの関数はバッファーにvisitされているファイル内でのバイトオフセットとバッファー位置をLispプログラムがマッピングする際に有用です。

Function: bufferpos-to-filepos position &optional quality coding-system

この関数はposition-bytesと似ているがカレントバッファー内でのバイト位置ではなく、バッファー内のpositionにより与えられる文字に対応するカレントバッファーのファイル先頭からのオフセットをリターンする点が異なる。この変換にはバッファーのファイル内でテキストがエンコードされる方法を知ることが要求される。これがcoding-system引数の存在意義であり、デフォルトはbuffer-file-coding-systemの値。オプション引数qualityは結果のあるべき正確さを指定する。これは以下いずれかであること:

exact

正確な結果でなければならない。関数は高価で低速になり得るバッファーの大きな範囲のエンコードとデコードを要するかもしれない。

approximate

近似的な値が可能。関数は高価な処理を回避して不正確な結果をリターンするかもしれない。

nil

正確な結果に高価な処理を要するなら、関数は近似値ではなくnilをリターンするだろう。これは引数が省略された場合のデフォルト。

Function: filepos-to-bufferpos byte &optional quality coding-system

この関数はbyte (ファイル先頭からの0基準のバイトオフセット)が指定するファイル位置に対応するバッファー位置をリターンする。この関数はbufferpos-to-fileposが行う変換と逆の処理を行う。オプション引数qualitycoding-systemのもつ意味と値はbufferpos-to-fileposの場合と同様。

Function: multibyte-string-p string

stringがマルチバイト文字列ならt、それ以外はnilをリターンする。この関数はstringが文字列以外でもnilをリターンする。

Function: string-bytes string

この関数はstring内のバイト数をリターンする。stringがマルチバイト文字列なら、これは(length string)より大きいかもしれない。

Function: unibyte-string &rest bytes

この関数は引数bytesをすべて結合して、その結果をユニバイト文字列で作成する。


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

34.2 マルチバイト文字の無効化

デフォルトではEmacsはマルチバイトモードで開始されます。Emacsはマルチバイトシーケンスを使用して非ASCII文字を表現する内部エンコーディングを使用することにより、バッファーや文字列のコンテンツを格納します。マルチバイトモードでは、サポートされるすべての言語とスクリプトを使用できます。

非常に特別な状況下においては、特定のバッファーでマルチバイト文字のサポートを無効にしたいときがあるかもしれません。あるバッファーにおいてマルチバイト文字が無効になっているときには、それをユニバイトモード(unibyte mode)と呼びます。ユニバイトモードではバッファー内の各文字は0から255(8進の0377)の範囲の文字コードをもちます。0から127(8進の0177)はASCII文字、128から255(8進の0377)は非ASCII文字を表します。

特定のファイルをユニバイト表現で編集するためには、find-file-literallyを使用してファイルをvisitします。ファイルをvisitする関数を参照してください。マルチバイトバッファーをファイルに保存してバッファーをkillした後に、再びそのファイルをfind-file-literallyでvisitすることによりマルチバイトバッファーをユニバイトに変換できます。かわりにC-x RET c(universal-coding-system-argument)を使用して、ファイルをvisitまたは保存するコーディングシステムとして‘raw-text’を指定することもできます。Specifying a Coding System for File Text in GNU Emacs Manualを参照してください。find-file-literallyとは異なり、‘raw-text’としてファイルをvisitしてもフォーマット変換、解凍、自動的なモード選択は無効になりません。

バッファーローカル変数enable-multibyte-charactersはマルチバイトバッファーなら非nil、ユニバイトバッファーならnilです。マルチバイトバッファーかどうかはモードラインにも示されます。グラフィカルなディスプレイでのマルチバイトバッファーには文字セットを示すモードライン部分と、そのバッファーがマルチバイトであること(とそれ以外の事項)を告げるツールチップがあります。ユニバイトバッファーでは文字セットのインジケーターはありません。したがって(グラフィカルなディスプレイ使用時の)ユニバイトバッファーでは入力メソッドを使用していなければ、visitしているファイルの行末変換(コロン、バックスラッシュ等)の標識の前には通常は何も標識がありません。

特定のバッファーでマルチバイトサポートをオフに切り替えるには、そのバッファー内でコマンドtoggle-enable-multibyte-charactersを呼び出してください。


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

34.3 テキスト表現の変換

Emacsはユニバイトテキストをマルチバイトに変換できます。マルチバイトテキストに含まれるのがASCIIと8ビットrawバイトだけという条件つきでマルチバイトテキストからユニバイトへの変換もできます。一般的にこれらの変換はバッファーへのテキスト挿入時、または複数の文字列を1つの文字列に合成してテキストにputするときに発生します。文字列のコンテンツを明示的にいずれかの表現に変換することもできます。

Emacsはそのテキストの構成にもとづいて文字列の表現を選択します。一般的なルールではユニバイトテキストが他のマルチバイトテキストと組み合わされていればマルチバイト表現のほうがより一般的であり、ユニバイトテキストのすべての文字を保有できるのでユニバイトテキストをマルチバイトテキストに変換します。

バッファーへのテキスト挿入時にEmacsはそのバッファーのenable-multibyte-charactersの指定にしたがってテキストをそのバッファーの表現に変換します。特にユニバイトバッファーにマルチバイトテキストを挿入する際には、たとえ一般的にはマルチバイトテキスト内のすべての文字を保持することはできなくてもEmacsはテキストをユニバイトに変換します。バッファーコンテンツをマルチバイトに変換するという自然な代替方法は、そのバッファーの表現が自動的にオーバーライドできないユーザーによる選択にもとづく表現であるため許容されません。

ユニバイトテキストからマルチバイトテキストへの変換ではASCII文字は未変更のまま残されて、128から255のコードをもつバイトが8ビットrawバイトのマルチバイト表現に変換されます。

マルチバイトテキストからユニバイトテキストへの変換では、すべてのASCIIと8ビット文字が、それらの1バイト形式に変換されますが、各文字のコードポイントの下位8ビット以外は破棄されるために非ASCII文字の情報は失われます。ユニバイトテキストからマルチバイトテキストに変換してそれをユニバイトに戻せば、元のユニバイトテキストが再生成されます。

以下の2つの関数は引数string、またはテキストプロパティをもたない新たに作成された文字列のいずれかをリターンします。

Function: string-to-multibyte string

この関数はstringと同じ文字シーケンスを含むマルチバイト文字列をリターンする。stringがマルチバイト文字列なら未変更のままそれがリターンされる。この関数はstringASCII文字と8ビットrawバイトだけを含むと仮定する。後者は#x3FFF80から#x3FFFFF(両端を含む)に対応する8ビットrawバイトのマルチバイト表現に変換される(codepointsを参照)。

Function: string-to-unibyte string

この関数はstringと同じ文字シーケンスを含むユニバイト文字列をリターンする。stringがユニバイト文字列なら変更せずにそれをリターンする。それ以外の場合にはASCII文字とeight-bit文字セットの文字を、それらに応じたバイト値に変換する。ASCII文字と8ビット文字だけを含むstring引数にたいしてのみこの関数を使用すること。これら以外の文字に遭遇すると、この関数はエラーをシグナルする。

Function: byte-to-string byte

この関数は文字データbyteの単一バイトを含むユニバイト文字列をリターンする。byteが0から255までの整数でなければ、エラーをシグナルする。

Function: multibyte-char-to-unibyte char

これはマルチバイト文字charをユニバイト文字に変換してその文字をリターンする。charASCIIと8ビットのいずれでもなければこの関数は-1をリターンする。

Function: unibyte-char-to-multibyte char

これはcharASCIIか8ビットrawバイトのいずれかであると仮定してユニバイト文字ASCIIをマルチバイト文字に変換する。


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

34.4 表現の選択

既存のバッファーや文字列がユニバイトの際に、それらをマルチバイトとして調べたり、その逆を行うことが有用なときがあります。

Function: set-buffer-multibyte multibyte

カレントバッファーの表現タイプをセットする。multibyteが非nilならバッファーはマルチバイト、nilならユニバイト。

この関数はバイトシーケンスとして認識時にはバッファーを未変更のままとする。結果として文字として認識時にはコンテンツを変更できる。たとえばマルチバイト表現では1文字として扱われる3バイトのシーケンスは、ユニバイト表現では3文字として数えられるだろう。例外はrawバイトを表す8ビット文字。これらはユニバイトバッファーでは1バイトで表現されるが、バッファーをマルチバイトにセットした際は2バイトのシーケンスに変換されて、その逆の変換も行われる。

この関数はどの表現が使用されているかを記録するためにenable-multibyte-charactersをセットする。これは以前の同じテキストをカバーするように、バッファー内のさまざまなデータ(オーバーレイ、テキストプロパティ、マーカーを含む)を調整する。

ナローイングはマルチバイト文字シーケンス中間で発生するかもしれないので、この関数はバッファーがナローイングされている場合はエラーをシグナルする。

そのバッファーがインダイレクトバッファー(indirect buffer: 間接バッファー)の場合にもエラーをシグナルする。インダイレクトバッファーは常にベースバッファー(base buffer: 基底バッファー)の表現を継承する。

Function: string-as-unibyte string

stringがすでにユニバイト文字列なら、この関数はstring自身をリターンする。それ以外はstringと同じバイトだが、それぞれの文字を個別の文字としてとして扱って新たな文字列をリターンする(値はstringより多くの文字をもつかもしれない)。例外としてrawバイトを表す8ビット文字は、それぞれ単一のバイトに変換される。新たに作成された文字列にテキストプロパティは含まれない。

Function: string-as-multibyte string

stringがすでにマルチバイト文字列なら、この関数はstring自身をリターンする。それ以外はstringと同じバイトだが、それぞれのマルチバイトシーケンスを1つの文字としてとして扱って新たな文字列をリターンする。これは値がstringより少ない文字をもつかもしれないことを意味する。string内のバイトシーケンスが単一文字のマルチバイト表現として無効なら、そのシーケンスないの各バイトは8ビットrawバイトとして扱われる。新たに作成された文字列にはテキストプロパティは含まれない


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

34.5 文字コード

ユニバイトやマルチバイトによるテキスト表現は異なる文字コードを使用します。ユニバイト表現にたいして有効な文字コードの範囲は0から#xFF(255)でこれは1バイト範囲に収まる値です。マルチバイト表現にたいして有効な文字コードの範囲は0から#x3FFFFFです。このコード空間では値0から#x7F(127)がASCII文字用、値#x80(128)から#x3FFF7F(4194175)が非ASCII文字用になります。

Emacsの文字コードは、Unicode標準のスーパーセット(superset: 上位集合)です。値0から#x10FFFF(1114111)は同じコードポイントのUnicode文字に対応します。値#x110000(1114112)から#x3FFF7F(4194175)はUnicodeに統一されていない文字、値#x3FFF80(4194176)から#x3FFFFF(4194303)は8ビットrawバイトを表します。

Function: characterp charcode

これはcharcodeが有効な文字ならt、それ以外はnilをリターンする。

(characterp 65)
     ⇒ t
(characterp 4194303)
     ⇒ t
(characterp 4194304)
     ⇒ nil
Function: max-char &optional unicode

この関数はEmacsにおいて有効な文字コードポイントとしてもつことができる最大値をリターンする。オプション引数unicodeが非nilの場合には、Unicode標準(Unicode Standard)によって定義される文字コードポイントの最大値をリターンする。

(characterp (max-char))
     ⇒ t
(characterp (1+ (max-char)))
     ⇒ nil
Function: char-from-name string &optional ignore-case

この関数はUnicode名がstringであるような文字をリターンする。ignore-caseが非nilならstringのcase(大文字小文字)は無視する。stringが文字の名前でなければ、この関数はnilをリターンする。

;; U+03A3
(= (char-from-name "GREEK CAPITAL LETTER SIGMA") #x03A3)
     ⇒ t
Function: get-byte &optional pos string

この関数はカレントバッファー内の文字位置posにあるバイトをリターンする。カレントバッファーがユニバイトなら、その位置のバイトをそのままリターンする。バッファーがマルチバイトなら、8ビットrawバイトは8ビットコードに変換される一方で、ASCII文字のバ値は文字コードポイントと同じになる。この関数はposにある文字が非ASCIIならエラーをシグナルする。

オプション引数stringはカレントバッファーのかわりに文字列からバイト値を得ることを意味する。


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

34.6 文字のプロパティ

文字プロパティ(character propertyとは、その文字の振る舞いとテキストが処理や表示される間にどのように処理されるべきかを指定する名前つきの文字属性です。したがって文字プロパティはその文字の意味を指定するための重要な一部です。

全体としてEmacsは自身の文字プロパティ実装においてUnicode標準にしたがいます。特にEmacsはUnicode Character Property Modelをサポートしており、Emacs文字プロパティデータベースはUnicode文字データベース(UCD: Unicode Character Database)から派生したものです。Unicode文字プロパティとその意味についての詳細な説明はCharacter Properties chapter of the Unicode Standardを参照してください。このセクションではあなたがすでにUnicode標準の該当する章に親しんでいて、その知識をEmacs Lispプログラムに適用したいものと仮定します。

Emacsでは各プロパティは名前をもつシンボルであり、そのシンボルは利用可能な値セットをもち、値の型はプロパティに依存します。ある文字が特定のプロパティをもたなければ、その値はnilになります。一般的なルールとしてEmacsでの文字プロパティ名は対応するUnicodeプロパティ名を小文字にして、文字‘_’をダッシュ文字‘-’で置き換えることにより生成されます。たとえばCanonical_Combining_Classcanonical-combining-classとなります。しかし簡単に使用できるように名前を短くすることもあります。

UCDによりいくつかのコードポイントは未割り当て(unassigned)のまま残されており、それらに対応する文字はありません。Unicode標準は、そのようなコードポイントのプロパティにたいしてデフォルト値を定義しています。それらについては以下の各プロパティごとに注記することにします。

以下はEmacsが関知するすべての文字プロパティにたいする値タイプの完全なリストです:

name

UnicodeプロパティNameに対応する。値はラテン大文字のAからZ、数字、スペース、ハイフン‘-’の文字から構成される文字列。未割り当てのコードポイントにたいする値はnil

general-category

UnicodeプロパティGeneral_Categoryに対応する。値はその文字の分類をアルファベット2文字に略したものを名前としてもつようなシンボル。未割り当てのコードポイントにたいする値はCn

canonical-combining-class

UnicodeプロパティCanonical_Combining_Classに対応する。値は整数。未割り当てのコードポイントにたいする値は0。

bidi-class

UnicodeプロパティBidi_Classに対応する。値はその文字のUnicode方向タイプ(directional type)が名前であるようなシンボル。Emacsは表示のために双方向テキストを並び替える際にこのプロパティを使用する(双方向テキストの表示を参照)。未割り当てのコードポイントにたいする値はそのコードポイントが属するコードブロックに依存する。未割り当てのコードポイントのほとんどはL(強い左方向)だが、AL ( Arabic letter: アラビア文字)やR (強い右方向)を受け取るコースポイントもいくつかある。

decomposition

UnicodeプロパティのDecomposition_TypeDecomposition_Valueに対応する。値は最初の要素がsmallのような互換性のあるフォーマットタグ(compatibility formatting tag)であるかもしれないリスト25。分割シーケンス(compatibility decomposition sequence)をもたない文字、および未割り当てのコードポイントにたいする値はその文字自身が唯一のメンバーであるようなリスト。

decimal-digit-value

Numeric_Typeが‘Decimal’であるような文字UnicodeプロパティNumeric_Valueに対応する。値は整数、その文字が10進値をもたなければnil。未割り当てのコードポイントにたいする値は、NaNまたは“not a number(数字ではない)”を意味するnil

digit-value

Numeric_Typeが‘Digit’であるような文字のUnicodeプロパティNumeric_Valueに対応する。値は整数。このような文字には互換性のある添字や上付き数字が含まれ、値は対応する数字。何も数値をもたない文字および未割り当てのコードポイントにたいする値はNaNを意味するnil

numeric-value

Numeric_Typeが‘Numeric’であるような文字のUnicodeプロパティNumeric_Valueに対応する。このプロパティの値は数字。このプロパティをもつ文字の例には分数、添字、上付き数字、ローマ数字、通貨分数(訳注: 原文は“currency numerators”でベンガル語の分数値用の歴史的な記号を指すと思われる)、丸数字が含まれる。たとえば文字U+2155 (VULGAR FRACTION ONE FIFTH: (訳注)スラッシュで分子と分母を区切った表記による5分の1のこと)にたいするこのプロパティの値は0.2。数値をもたない文字と未割り当てのコードポイントにたいする値はNaNを意味するnil

mirrored

UnicodeプロパティBidi_Mirroredに対応する。このプロパティの値はYNいずれかのシンボル。未割り当てのコードポイントにたいする値はN

mirroring

UnicodeプロパティBidi_Mirroring_Glyphに対応する。このプロパティの値は、そのグリフ(glyph)がその文字のグリフの鏡像(mirror image)を表すような文字、定義済みの鏡像グリフがなければnilmirroredプロパティがNであるようなすべての文字のmirroringプロパティはnil。しかしmirroredプロパティがYの文字でも、鏡像をもつ適切な文字がないという理由によりmirroringnilの文字もある。Emacsは適切な際は鏡像を表示するためにこのプロパティを使用する(双方向テキストの表示を参照)。未割り当てのコードポイントにたいする値はnil

paired-bracket

UnicodeプロパティBidi_Paired_Bracketに対応する。このプロパティの値は文字のpaired bracket(カッコのペア)のコードポイント、その文字がbracket文字でなければnil。これはUnicode双方向アルゴリズム(Unicode Bidirectional Algorithm)によりカッコのペアとして扱われる文字間のマッピングを確立する。 Emacsは丸カッコ(parentheses)や角カッコ(braces)、およびその類の文字を再配置する方法を決定する際にこのプロパティを使用する(双方向テキストの表示を参照)。

bracket-type

UnicodeのBidi_Paired_Bracket_Typeプロパティに対応する。paired-bracketプロパティが非nilの文字にたいするこのプロパティはo (開カッコ文字)かc (閉カッコ文字)を表すシンボルのいずれか。paired-bracketプロパティがnilの文字にたいする値はn (None: なし)。paired-bracketと同じようにこのプロパティは双方向ディスプレイにより使用される。

old-name

UnicodeプロパティUnicode_1_Nameに対応する。値は文字列。未割り当てのコードポイント、およびこのプロパティにたいする値をもたない文字では値はnil

iso-10646-comment

UnicodeプロパティISO_Commentに対応する。値は文字列かnil。未割り当てのコードポイントにたいする値はnil

uppercase

UnicodeプロパティSimple_Uppercase_Mappingに対応する。このプロパティの値は単一の文字。未割り当てのコードポイントの値はnilであり、これはその文字自身を意味する。

lowercase

UnicodeプロパティSimple_Lowercase_Mappingに対応する。このプロパティの値は単一の文字。未割り当てのコードポイントの値はnilであり、これはその文字自身を意味する。

titlecase

UnicodeプロパティSimple_Titlecase_Mappingに対応する。タイトルケース(title case)とは単語の最初の文字を大文字にする必要がある際に使用される文字の特別な形式のこと。このプロパティの値は単一の文字。未割り当てのコードポイントにたいする値はnilであり、これはその文字自身を意味する。

special-uppercase

Unicodeの言語やコンテキストに依存しない特別な大文字caseルールに対応する。このプロパティの値は文字列(空も可)。たとえばU+00DF LATIN SMALL LETTER SHARP Sにたいするマッピングは"SS"。特別なマッピングのない文字にたいする値はnil (かわりにuppercaseプロパティの照会が必要なことを意味する)。

special-lowercase

Unicodeの言語やコンテキストに依存しない特別な小文字caseルールに対応する。このプロパティの値は文字列(空も可)。たとえばU+0130 LATIN CAPITAL LETTER I WITH DOT ABOVEにたいするマッピングは\"i\\u0307\" (すなわちLATIN SMALL LETTER Iの後にU+0307 COMBINING DOT ABOVEが続くことによって構成される2文字の文字列)。特別なマッピングのない文字にたいする値はnil (かわりにlowercaseプロパティの照会が必要なことを意味する)。

special-titlecase

Unicodeの無条件の特別なタイトルcaseルールに対応する。このプロパティの値は文字列(空も可)。たとえばU+FB01 LATIN SMALL LIGATURE FIにたいするマッピングは"Fi"。特別なマッピングのない文字にたいする値はnil (かわりにtitlecaseプロパティの照会が必要なことを意味する)。

Function: get-char-code-property char propname

この関数はcharのプロパティpropnameの値をリターンする。

(get-char-code-property ?\s 'general-category)
     ⇒ Zs
(get-char-code-property ?1 'general-category)
     ⇒ Nd
;; U+2084
(get-char-code-property ?\N{SUBSCRIPT FOUR}
                        'digit-value)
     ⇒ 4
;; U+2155
(get-char-code-property ?\N{VULGAR FRACTION ONE FIFTH}
                        'numeric-value)
     ⇒ 0.2
;; U+2163
(get-char-code-property ?\N{ROMAN NUMERAL FOUR}
                        'numeric-value)
     ⇒ 4
(get-char-code-property ?\( 'paired-bracket)
     ⇒ 41  ; closing parenthesis
(get-char-code-property ?\) 'bracket-type)
     ⇒ c
Function: char-code-property-description prop value

この関数はプロパティpropvalueの説明文字列(description string)、valueが説明をもたなければnilをリターンする。

(char-code-property-description 'general-category 'Zs)
     ⇒ "Separator, Space"
(char-code-property-description 'general-category 'Nd)
     ⇒ "Number, Decimal Digit"
(char-code-property-description 'numeric-value '1/5)
     ⇒ nil
Function: put-char-code-property char propname value

この関数は文字charのプロパティpropnameの値としてvalueを格納する。

Variable: unicode-category-table

この変数の値は、それぞれの文字にたいしてそのUnicodeプロパティGeneral_Categoryをシンボルとして指定する文字テーブル(文字テーブルを参照)。

Variable: char-script-table

この変数の値は、それぞれの文字がシンボルを指定するような文字テーブル。シンボルの名前はUnicodeコードスペースからスクリプト固有ブロックへのUnicode標準分類にしたがうような、その文字が属するスクリプト。この文字テーブルは余分のスロットを1つもち、値はすべてのスクリプトシンボルのリスト。Emacsの文字からスクリプトへのクラス分けはUnicode標準と1対1で対応しないことに注意(たとえばUnicodeには‘symbol’スクリプトはない)。

Variable: char-width-table

この変数の値は、それぞれの文字がスクリーン上で占めるであろう幅を列単位で指定する文字テーブル。

Variable: printable-chars

この変数の値は、それぞれの文字にたいしてそれがプリント可能かどうかを指定する文字テーブル。すなわち(aref printable-chars char)を評価した結果がtならプリント可、nilなら不可。


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

34.7 文字セット

Emacsの文字セット(character set、もしくはcharset)とは、それぞれの文字が数字のコードポイントに割り当てられれた文字セットのことです(Unicode標準ではこれを符号化文字集合(coded character set)と呼ぶ)。Emacsの各文字セットはシンボルであるような名前をもちます。1つの文字が任意の数の異なる文字セットに属することができますが、各文字セット内で異なるコードポイントをもつのが一般的でしょう。文字セットの例にはasciiiso-8859-1greek-iso8859-7windows-1255が含まれます。文字セット内で文字に割り当てられるコードポイントは、Emacs内のバッファーや文字列内で使用されるコードポイントとは通常は異なります。

Emacsは特別な文字セットをいくつか定義しています。文字セットunicodeはEmacsコードポイントが0..#x10FFFFの範囲のすべての文字セットを含みます。文字セットemacsはすべてのASCII、および非ASCII文字を含みます。最後にeight-bit文字セットは8ビットrawバイトを含みます。テキスト内でrawバイトを見つけたときにEmacsはこれを使用します。

Function: charsetp object

objectは文字セットを命名するシンボルならt、それ以外はnilをリターンする。

Variable: charset-list

値はすべての定義済み文字セットの名前のリスト。

Function: charset-priority-list &optional highestp

この関数はすべての定義済み文字セットの優先順にソートされたリストをリターンする。highestpが非nilなら、この関数はもっとも優先度の高い文字セット1つをリターンする。

Function: set-charset-priority &rest charsets

この関数はcharsetsをもっとも高い優先度の文字セットにする。

Function: char-charset character &optional restriction

この関数はcharacterが属する文字セットで、もっとも優先度の高い文字セットの名前をリターンする。ただしASCII文字は例外であり、この関数は常にasciiをリターンする。

restrictionが非nilなら、それは検索する文字セットのリストであること。かわりにコーディングシステムも指定でき、その場合にはそのコーディングシステムによりサポートされている必要がある(コーディングシステムを参照)。

Function: charset-plist charset

この関数は文字セットcharsetのプロパティをリターンする。たとえcharsetがシンボルだったとしても、これはそのシンボルのプロパティリストと同じではない。文字セットプロパティにはドキュメント文字列、短い名前等、その文字セットに関する重要な情報が含まれる。

Function: put-charset-property charset propname value

この関数はcharsetのプロパティpropnameに与えられたvalueをセットする。

Function: get-charset-property charset propname

この関数はcharsetのプロパティpropnameの値をリターンする。

Command: list-charset-chars charset

このコマンドは文字セットcharset内の文字のリストを表示する。

Emacsは文字の内部的な表現と、その文字の特定の文字セット内でのコードポイントを相互に変換することができます。以下はこれらをサポートするための関数です。

Function: decode-char charset code-point

この関数はcharset内でcode-pointに割り当てられた文字をEmacsの対応する文字にデコードしてリターンする。そのコードポイントの文字がcharsetに含まれなければ値はnil

後方互換性のためにcode-pointがLispのfixnum (most-positive-fixnumを参照)に収まらなければ、コンスセル(high . low)として指定できる。ここでlowは値の下位16ビット、highは高位16ビット。この使用方法は時代遅れである。

Function: encode-char char charset

この関数はcharset内で文字charに割り当てられたコードポイントをリターンする。charsetcharにたいするコードポイントをもたなければ値はnil

以下の関数は文字セット内の文字の一部、またはすべてにたいして特定の関数を適用するのに有用です。

Function: map-charset-chars function charset &optional arg from-code to-code

charset内の文字にたいしてfunctionを呼び出す。functionは2つの引数で呼び出される。1つ目はコンスセル(from . to)であり、fromtocharset内に含まれる文字の範囲。argは2つ目の引数としてfunctionに渡される。argが省略された際にはnilが渡される。

デフォルトではfunctionに渡されるコードポイントの範囲にはcharset内のすべての文字が含まれるが、オプションの引数from-codeおよびto-codeは、charsetのこれら2つのコードポイント間の文字に範囲をする。これらのいずれかがnilの場合のデフォルトは、それぞれcharsetの最初または最後のコードポイント。from-codeto-codecharsetのコードポイントであって、Emacsの文字のコードではないことに注意。 対照的に、functionに渡されるコンスセルにおけるfrom-codeto-codeの値は、Emacsの文字コードである。 これらのEmacs文字コードはUnicodeコードポイント、あるいはUnicode文字の範囲0..#x10FFFFを超えて拡張されたEmacs内部コードポイントのいずれか(テキストの表現方法を参照)。後者はUnicodeに未統合の文字を指定する文字セットにたいするコードポイント用の過去のCJK文字セットであり滅多に使用されない。


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

34.8 文字セットのスキャン

特定の文字がどの文字セットに属するか調べられると便利なときがあります。これの用途の1つは、どのコーディングシステム(コーディングシステムを参照)が問題となっているテキストすべてを表現可能か判断することです。他にもそのテキストを表示するフォントの判断があります。

Function: charset-after &optional pos

この関数は、カレントバッファー内の位置posにある文字を含む、もっとも高い優先度の文字セットをリターンする。posが省略またはnilの場合のデフォルトはポイントのカレント値。posが範囲外なら値はnil

Function: find-charset-region beg end &optional translation

この関数はカレントバッファー内の位置begからendの間の文字を含む、もっとも優先度の高い文字セットのリストをリターンする。

オプション引数translationはテキストのスキャンに使用するための変換テーブルを指定する(文字の変換を参照)。これが非nilならリージョン内の各文字はそのテーブルを通じて変換され、リターンされる値にはバッファーの実際の文字ではなく変換された文字が記述される。

Function: find-charset-string string &optional translation

この関数はstring内の文字を含む、もっとも優先度の高い文字セットのリストをリターンする。これはfind-charset-regionと似ているが、カレントバッファーの一部ではなくstringのコンテンツに適用される点が異なる。


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

34.9 文字の変換

変換テーブル(translation table)とは文字から文字へのマッピングを指定する文字テーブルです(文字テーブルを参照)。これらのテーブルはエンコーディング、デコーディング、および他の用途にも使用されます。独自に変換テーブルを指定するコーディングシステムもいくつかあります。他のすべてのコーディングシステムに適用されるデフォルトの変換テーブルも存在します。

変換テーブルには余分のスロット(extra slots)が2つあります。1つ目のスロットはnil、または逆の変換を処理する変換テーブルです。2つ目のスロットは変換する文字シーケンスを照合する際の最大文字数です(以下のmake-translation-table-from-alistの説明を参照)。

Function: make-translation-table &rest translations

この関数は引数translationsにもとづいて変換テーブルをリターンする。translationsの各要素は(from . to)という形式のリストであること。これはfromからtoへの文字の変換を指示する。

各引数内の引数とフォームは順に処理され、もし前のフォームですでにtoがたとえばto-altに変換されていればfromto-altに変換される。

デコードを行う間、その変換テーブルの変換は通常のデコーディングの結果の文字に適用されます。あるコーディングシステムがプロパティ:decode-translation-tableをもつなら、それは使用する変換テーブル、または順に適用するべき変換テーブルのリストを指定します(これはコーディングシステムの名前であるようなシンボルのプロパティではなく、coding-system-getがリターンするようなコーディングシステムのプロパティ。Basic Concepts of Coding Systemsを参照)。最後にもしstandard-translation-table-for-decodeが非nilなら、結果となる文字はそのテーブルにより変換されます。

エンコードを行う間は、その変換テーブルの変換はバッファー内の文字に適用されて、変換結果は実際にエンコードされます。あるコーディングシステムがプロパティ:encode-translation-tableをもつならそれは使用する変換テーブル、または順に適用するべき変換テーブルのリストを指定します。加えてもし変数standard-translation-table-for-encodeが非nilなら、それは変換結果にたいして使用するべき変換テーブルを指定します。

Variable: standard-translation-table-for-decode

これはデコード用のデフォルトの変換テーブル。あるコーディングシステムが独自に変換テーブルを指定する場合には、この変数の値が非nilなら、それら独自のテーブルを適用後にこの変数の変換テーブルが適用される。

Variable: standard-translation-table-for-encode

これはエンコード用のデフォルトの変換テーブル。あるコーディングシステムが独自に変換テーブルを指定する場合には、この変数の値が非nilならそれら独自のテーブル適用後にこの変数の変換テーブルが適用される。

Variable: translation-table-for-input

自己挿入文字は挿入前にこの変換テーブルを通じて変換が行われる。検索コマンドもバッファー内の内容とより信頼性のある比較ができるようにこのテーブルを通じて入力を変換する。

この変数はセット時に自動的にバッファーローカルになる。

Function: make-translation-table-from-vector vec

この関数はバイト(値は0から#xFF)から文字にマップする256要素の配列であるような、vecから作成した変換テーブルをリターンする。未変換のバイトにたいする要素はnilかもしれない。リターンされるテーブルは余分な1つ目のスロットにそのマッピングを保持する変換テーブル、2つ目の余分なスロットに値1をもつ。

この関数は各バイトを特定の文字にマップするようなプライベートなコーディングシステムを簡単に作成する手段を提供する。define-coding-systemprops引数のプロパティ:decode-translation-table:encode-translation-tableに、リターンされるテーブルと逆変換テーブルを指定できる。

Function: make-translation-table-from-alist alist

この関数はmake-translation-tableと似ているが、シンプルな1対1のマッピングを行う変換テーブルではなく、より複雑な変換テーブルをリターンする。alistの各要素は(from . to)という形式をもち、ここでfromおよびtoは文字または文字シーケンスを指定するベクター。fromが文字なら、その文字はto(文字か文字シーケンス)に変換される。fromが文字のベクターならそのシーケンスはtoに変換される。リターンされるテーブルは1つ目の余分なスロットに逆のマッピングを行う変換テーブル、2つ目の余分なスロットには文字シーケンスfromすべての最大長をもつ。


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

34.10 コーディングシステム

Emacsがファイルにたいして読み書きをしたりサブプロセスとテキストの送受信を行う際には、通常は特定のコーディングシステム(coding system)の指定にしたがって文字コード変換や行末変換を行います。

コーディングシステムの定義は難解な問題であり、ここには記述しません。


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

34.10.1 コーディングシステムの基本概念

文字コード変換(character code conversion)により、Emacs内部で使用される文字の内部表現と他のエンコーディングの間で変換が行われます。Emacsは多くの異なるエンコーディングをサポートしており、それらは双方向に変換が可能です。たとえばLatin 1、Latin 2、Latin 3、Latin 4、Latin 5、およびいくつかのISO 2022の変種等のようなエンコーディングにたいしてテキストを双方向に変換できます。あるケースにおいては同じ文字にたいしてEmacsは複数のエンコーディング候補をサポートします。たとえばキリル(ロシア語)のアルファベットにたいしてはISO、Alternativnyj、KOI8のように3つにコーディングシステムが存在します。

コーディングシステムはそれぞれ特定の文字コード変換セットを指定しますが、undecidedというコーディングシステムは特別です。これはファイル(や文字列)にたいしてデコードやエンコードを行う際に、そのファイル(や文字列)のデータにもとづいて発見的に選択が行われるように、選択を未指定のままにします。コーディングシステムprefer-utf-8undecidedと似ていますが、可能ならutf-8を優先的に選択します。

一般的にコーディングシステムは可逆的な同一性を保証しません。あるコーディングシステムを使用してバイトシーケンスをデコードしてから、同じコーディングシステムで結果テキストをエンコードしても、異なるバイトシーケンスが生成される可能性があります。しかしデコードされたオリジナルのバイトシーケンスとなることを保証するコーディングシステムもいくつかあります。以下にいくつかの例を挙げます:

iso-8859-1、utf-8、big5、shift_jis、euc-jp

バッファーテキストのエンコードと結果のデコードでもオリジナルテキストの再生成に失敗する可能性があります。たとえばその文字をサポートしないコーディングシステムで文字をエンコードした場合の結果は予測できず、したがって同じコーディングシステムを使用してそれをデコードしても異なるテキストが生成されるでしょう。現在のところEmacsは未サポート文字のエンコーディングによる結果をエラーとして報告できません。

行末変換(end of line conversion: 改行変換)はファイル内の行末を表すために、さまざまなシステム上で使用される3つの異なる慣例を扱います。GNUやUnixシステムで使用されるUnixの慣例ではLF文字(linefeed文字、改行とも呼ばれる)が使用されます。MS-WindowsやMS-DOSシステムで使用されるDOSの慣例では行末にCR文字(carriage-return文字、復帰文字とも呼ばれる)とLF文字が使用されます。Macの慣例ではCR文字だけが使用されます(これはクラシックなMac OSで使用されていた慣例)。

latin-1のようなベースコーディングシステム(base coding systems: 基本コーディングシステム)では、データにもとづいて選択されるように行末変換は未指定となっています。latin-1-unixlatin-1-doslatin-1-macのようなバリアントコーディングシステム(variant coding systems: 変種コーディングシステム)では行末変換を明示的に指定します。ほとんどのベースコーディングシステムは‘-unix’、‘-dos’、‘-mac’を追加した3つの対応する形式の変種をもちます。

raw-textは文字コード変換を抑制して、このコーディングシステムでvisitされたバッファーがユニバイトバッファーとなる点において特殊なコーディングシステムです。歴史的な理由によりこのコーディングシステムによりユニバイトとマルチバイト両方のテキストを保存できます。マルチバイトテキストのエンコードにraw-textを使用した際には1文字コード変換を行います。8ビット文字は1バイトの外部表現に変換されます。raw-textは通常のようにデータにより判断できるように行末変換を指定せず、通常のように行末変換を指定する3つの変種をもちます。

no-conversion (とエイリアスのbinary)はraw-text-unixと等価です。これは文字コードおよび行末にたいする変換をいずれも指定しません。

utf-8-emacsはデータがEmacsの内部エンコーディング(テキストの表現方法を参照)で表されることを指定するコーディングシステムです。コード変換が何も発生しない点でraw-textと似ていますが、結果がマルチバイトデータである点が異なります。 emacs-internalという名前はutf-8-emacs-unixにたいするエイリアスです(そのため3種類すべての行末変換をデコードするutf-8-emacsと異なり行末変換を強制しない)。

Function: coding-system-get coding-system property

この関数はコーディングシステムcoding-systemの指定されたプロパティをリターンする。コーディングシステムのプロパティのほとんどは内部的な目的のために存在するが、:mime-charsetについては有用と思うかもしれない。このプロパティの値はそのコーディングシステムが読み書きできる文字コードにたいしてMIME内で使用される名前。以下は例:

(coding-system-get 'iso-latin-1 :mime-charset)
     ⇒ iso-8859-1
(coding-system-get 'iso-2022-cn :mime-charset)
     ⇒ iso-2022-cn
(coding-system-get 'cyrillic-koi8 :mime-charset)
     ⇒ koi8-r

:mime-charsetプロパティの値はそのコーディングシステムにたいするエイリアスとしても定義されている。

Function: coding-system-aliases coding-system

この関数はcoding-systemのエイリアスのリストをリターンする。


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

34.10.2 エンコーディングとI/O

コーディングシステムの主な目的はファイルの読み込みと書き込みへの使用です。関数insert-file-contentsはファイルデータのデコードにコーディングシステムを使用して、write-regionはバッファーコンテンツのエンコードにコーディングシステムを使用します。

使用するコーディングシステムは明示的(単一の操作にたいするコーディングシステムの指定を参照)、またはデフォルトメカニズム(デフォルトのコーディングシステムを参照)を使用により暗黙的に指定できます。しかしこれらの手法は何を行うかを完全には指定しないかもしれません。たとえば、これらはデータから文字コード変換を行わないundecidedのようなコーディングシステムを選択するかもしれません。このような場合、I/O処理はコーディングシステム選択により処理を完了します。後でどのコーディングシステムが選択されたか調べたいことが頻繁にあるでしょう。

Variable: buffer-file-coding-system

このバッファーローカル変数はバッファーの保存、およびwrite-regionによるバッファー部分のファイルへの書き出しに使用されるコーディングシステムを記録する。書き込まれるテキストがこの変数で指定されたコーディングシステムを使用して安全にエンコードできない場合には、これらの操作は関数select-safe-coding-systemを呼び出すことにより代替となるエンコーディングを選択する(ユーザーが選択したコーディングシステムを参照)。異なるエンコーディングの選択がユーザーによるコーディングシステムの指定を要するなら、buffer-file-coding-systemは新たに選択されたコーディングシステムに更新される。

buffer-file-coding-systemはサブプロセスへのテキスト送信に影響しない

Variable: save-buffer-coding-system

この変数は、(buffer-file-coding-systemをオーバーライドして)バッファーを保存するためのコーディングシステムを指定する。これはwrite-regionには使用されないことに注意。

あるコマンドがバッファーを保存するためにbuffer-file-coding-system (またはsave-buffer-coding-system)の使用を開始して、そのコーディングシステムがバッファー内の実際のテキストを処理できなければ、(select-safe-coding-systemを呼び出すことにより)そのコマンドは他のコーディングシステムの選択をユーザーに求める。これが発生した後はコマンドはユーザー指定のコーディングシステムを表すためにbuffer-file-coding-systemの更新も行う。

Variable: last-coding-system-used

ファイルやサブプロセスにたいするI/O操作は、使用したコーディングシステムの名前をこの変数にセットする。明示的にエンコードとデコードを行う関数(明示的なエンコードとデコードを参照)もこの変数をセットする。

警告: サブプロセス出力の受信によりこの変数がセットされるため、この変数はEmacsがwaitしている際は常に変更され得る。したがって興味対象となる値を格納する関数呼び出し後は、間を空けずにその値をコピーすること。

変数selection-coding-systemはウィンドウシステムにたいして選択(selection)をエンコードする方法を指定します。ウィンドウシステムによる選択を参照してください。

Variable: file-name-coding-system

変数file-name-coding-systemはファイル名のエンコーディングに使用するコーディングシステムを指定する。Emacsは、すべてのファイル操作にたいして、ファイル名のエンコードにそのコーディングシステムを使用する。file-name-coding-systemnilならEmacsは選択された言語環境(language environment)により決定されたデフォルトのコーディングシステムを使用する。デフォルト言語環境ではファイル名に含まれるすべての非ASCII文字は特別にエンコードされない。これらはEmacsの内部表現を使用してファイルシステム内で表される。

警告: Emacsのセッション中にfile-name-coding-system (または言語環境)を変更した場合には、以前のコーディングシステムを使用してエンコードされた名前をもつファイルをvisitしていると、新たなコーディングシステムでは異なるように扱われるので問題が発生し得る。これらのvisitされたファイル名でこれらのバッファーの保存を試みると、保存で間違ったファイル名が使用されたりエラーとなるかもしれない。そのような問題が発生したら、そのバッファーにたいして新たなファイル名を指定するためにC-x C-wを使用すること。

Windows 2000以降ではEmacsはOSに渡すファイル名にデフォルトでUnicode APIを使用するため、file-name-coding-systemの値は大部分が無視される。Lispレベルでファイル名のエンコードやデコードを必要とするLispアプリケーションは、system-typewindows-ntのときはutf-8をコーディングシステムに使用すること。UTF-8でエンコードされたファイル名から、OSと対話するために適したエンコーディングへの変換はEmacsにより内部的に処理される。


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

34.10.3 Lispでのコーディングシステム

以下はコーディングシステムと連携するLisp機能です:

Function: coding-system-list &optional base-only

この関数はすべてのコーディングシステムの名前(シンボル)をリターンする。base-onlyが非nilなら、値にはベースコーディングシステムだけが含まれる。それ以外ならエイリアス、およびバリアントコーディングシステムも同様に含まれる。

Function: coding-system-p object

この関数はobjectがコーディングシステムの名前ならt、またはnilをリターンする。

Function: check-coding-system coding-system

この関数はcoding-systemの有効性をチェックする。有効ならcoding-systemをリターンする。coding-systemnilなら、この関数はnilをリターンする。それ以外の値にたいしてはerror-symbolcoding-system-errorであるようなエラーをシグナルする(signalを参照)。

Function: coding-system-eol-type coding-system

この関数は行末(eolとも言う)をcoding-systemで使用されるタイプに変換する。coding-systemが特定のeol変換を指定する場合にはリターン値は0、1、2のいずれかであり、それらは順にunixdosmacを意味する。coding-systemが明示的にeol変換を指定しなければ、リターン値は以下のようにそれぞれが可能なeol変換タイプをもつようなコーディングシステムのベクター:

(coding-system-eol-type 'latin-1)
     ⇒ [latin-1-unix latin-1-dos latin-1-mac]

この関数がベクターをリターンしたら、Emacsはテキストのエンコードやデコードプロセスの一部として使用するeol変換を決定するだろう。デコードではテキストの行末フォーマットは自動検知され、eol変換はそれに適合するようセットされる(DOSスタイルのCRLFフォーマットは暗黙でeol変換にdosをセットする)。エンコードにたいしては適切なデフォルトコーディングシステム(buffer-file-coding-systemにたいするbuffer-file-coding-systemのデフォルト値)、または背景にあるプラットフォームにたいして適切なデフォルトeol変換が採用される。

Function: coding-system-change-eol-conversion coding-system eol-type

この関数はcoding-systemと似ているがeol-typeで指定されたeol変換の異なるコーディングシステムをリターンする。eol-typeunixdosmac、またはnilであること。これがnilならリターンされるコーディングシステムは、データのeol変換により決定される。

eol-typeunixdosmacを意味する0、1、2でもよい。

Function: coding-system-change-text-conversion eol-coding text-coding

この関数はeol-codingの行末変換と、text-codingのテキスト変換を使用するコーディングシステムをリターンする。text-codingnilならこれはundecided、またはeol-codingに対応するバリアントの1つをリターンする。

Function: find-coding-systems-region from to

この関数はfromtoの間のテキストのエンコードに使用可能なコーディングシステムのリストをリターンする。このリスト内のすべてのリストは、そのテキスト範囲内にあるすべてのマルチバイト文字を安全にエンコードできる。

そのテキストがマルチバイト文字を含まれなければ、この関数はリスト(undecided)をリターンする。

Function: find-coding-systems-string string

この関数はstringのテキストのエンコードに使用可能な、コーディングシステムのリストをリターンする。このリスト内のすべてのリストはstringにあるすべてのマルチバイト文字を安全にエンコードできる。そのテキストがマルチバイト文字を含まれなければ、この関数はリスト(undecided)をリターンする。

Function: find-coding-systems-for-charsets charsets

この関数はリストcharsets内のすべての文字セットのエンコードに使用可能なコーディングシステムのリストをリターンする。

Function: check-coding-systems-region start end coding-system-list

この関数はリストcoding-system-list内のコーディングシステムがstartendの間のリージョン内にあるすべての文字をエンコード可能かどうかをチェックする。このリスト内のすべてのコーディングシステムが指定されたテキストをエンコード可能なら、この関数はnilをリターンする。ある文字をエンコードできないコーディングシステムがある場合には、各要素が(coding-system1 pos1 pos2 …)という形式のalistが値となる。これはcoding-system1がバッファーの位置pos1pos2...にある文字をエンコードできないことを意味する。

startは文字列かもしれず、その場合にはendは無視されてリターン値はバッファー位置のかわりに文字列のインデックスを参照することになる。

Function: detect-coding-region start end &optional highest

この関数はstartからendのテキストのデコードに適したコーディングシステムを選択する。このテキストはバイトシーケンス、すなわちユニバイトテキスト、ASCIIのみのマルチバイトテキスト、8ビット文字のシーケンスであること(明示的なエンコードとデコードを参照)。

この関数は通常はスキャンしたテキストのデコーディングを処理可能なコーディングシステムのリストをリターンする。これらのコーディングシステムは優先度降順でリストされる。しかしhighestが非nilなら、リターン値はもっとも高い優先度のコーディングシステムただ1つとなる。

リージョンにISO-2022のESCのようなISO-2022制御文字を除いてASCII文字だけが含まれる場合には値はundecided(undecided)、またはテキストから推論可能ならeol変換を指定するバリアントとなる。

リージョンにnullバイトが含まれる場合には、あるコーディングシステムによりエンコードされたテキストがリージョン内に含まれる場合でも値はno-conversionとなる。

Function: detect-coding-string string &optional highest

この関数はdetect-coding-regionと似ているがバッファー内のバイトのかわりにstringのコンテンツを処理する点が異なる。

Variable: inhibit-null-byte-detection

この変数が非nil値をもつなら、リージョンや文字列のエンコーディング検出時にnullバイトを無視する。これによりIndexノードをもつInfoファイルのようなnullバイトを含むテキストのエンコーディングを正しく検出できる。

Variable: inhibit-iso-escape-detection

この変数が非nil値をもつなら、リージョンや文字列のエンコーディング検出時にISO-2022エスケープシーケンスを無視する。結果としてこれまでいくつかのISO-2022エンコーディングにおいてエンコード済みと検出されていたテキストがなくなり、バッファー内ですべてのエスケープシーケンスが可視になる。警告: この変数の使用には特に注意を払うこと。なぜならEmacsディストリビューション内で多くのファイルがISO-2022エンコーディングを使用するからである。

Function: coding-system-charset-list coding-system

この関数はcoding-systemがサポートする文字セット(文字セットを参照)のリストをリターンする。リストすべき文字セットを非常に多くサポートするいくつかのコーディングシステムでは特別な値がリストされる:

  • coding-systemがすべてのEmacs文字をサポートするなら値は(emacs)
  • coding-systemがすべてのUnicode文字をサポートするなら値は(unicode)
  • coding-systemがすべてのISO-2022文字をサポートするなら値はiso-2022
  • coding-systemがEmacsバージョン21(Unicodeサポートの内部的な実装以前)で使用される内部的コーディングシステム内のすべての文字をサポートするなら値はemacs-mule

サブプロセスへの入出力に使用されるコーディングシステムのチェックやセットの方法についてはProcess Information、特に関数process-coding-systemset-process-coding-systemの説明を参照してください。


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

34.10.4 ユーザーが選択したコーディングシステム

Function: select-safe-coding-system from to &optional default-coding-system accept-default-p file

この関数は指定されたテキストをエンコードするために、必要ならユーザーに選択を求めてコーディングシステムを選択する。指定されるテキストは通常はカレントバッファーのfromtoの間のテキスト。fromが文字列なら、その文字列がエンコードするテキストを指定して、toは無視される。

指定されたテキストにrawバイト(テキストの表現方法を参照)が含まれる場合には、select-safe-coding-systemはそのエンコーディングにraw-textを提案する。

default-coding-systemが非nilなら、それは試行すべき最初のコーディングシステムである。それがテキストを処理できるなら、select-safe-coding-systemはそのコーディングシステムをリターンする。これはコーディングシステムのリストの可能性もある。その場合にはこの関数はそれらを1つずつ試みる。それらをすべて試した後に、(undecided以外なら)カレントバッファーのbuffer-file-coding-systemの値、次にbuffer-file-coding-systemのデフォルト値、最後にユーザーがもっとも好むコーディングシステム(コマンドprefer-coding-systemでセットできる最優先されるコーディングシステム)を試みる(Recognizing Coding Systems in The GNU Emacs Manualを参照)。

これらのうちいずれかのコーディングシステムが指定されたテキストすべてを安全にエンコード可能なら、select-safe-coding-systemはそれを選択およびリターンする。それ以外ならコーディングシステムのリストからすべてのテキストをエンコードできるコーディングシステムの選択をユーザーに求めてユーザーの選択をリターンする。

default-coding-systemは、最初の要素がtで他の要素がコーディングシステムであるようなリストかもしれない。その場合にはリスト内にテキストを処理できるコーディングシステムがなければ、select-safe-coding-systemは上述した3つの代替えいずれを試みることなく即座にユーザーに問い合わせる。これはリスト内のコーディングシステムだけをチェックするのに手軽。

オプション引数accept-default-pはユーザーとの対話なしで選択されたコーディングシステムを許容するかどうかを決定する。これが省略かnilなら、そのような暗黙の選択は常に許容される。非nilなら関数であること。select-safe-coding-systemは選択するコーディングシステムのベースとなるコーディングシステムを単一の引数としてその関数を呼び出す。関数がnilをリターンしたらselect-safe-coding-systemは黙って選択されたコーディングシステムを拒絶して、可能な候補リストからコーディングシステムの選択をユーザーに求める。

変数select-safe-coding-system-accept-defaultf-pが非nilなら、それは1つの引数をとる関数であること。これはaccept-default-p引数に与えられた値をオーバーライドすることによりaccept-default-pのかわりに使用される。

最後のステップとして選択されたコーディングシステムをリターンする前に、select-safe-coding-systemはもしリージョンのコンテンツがファイルから読み込まれたものだったとしたなら選択されたであろうコーディングシステムと、そのコーディングシステムが一致するかどうかをチェックする(異なるならその後の再visitと編集でファイル内のデータ汚染が起こり得る)。select-safe-coding-systemは通常はこの目的のためのファイルとしてbuffer-file-nameを使用するが、fileが非nilならかわりにそのファイルを使用する(これはwrite-regionや類似の関数に関連し得る)。明らかな不一致が検出された場合にはselect-safe-coding-systemはそのコーディングシステムを選択する前にユーザーに問い合わせる。

Variable: select-safe-coding-system-function

この変数は出力処理がテキストを安全にエンコードできないときに、テキストをエンコードするための正しいコーディングシステムの選択をユーザーに求めるために呼び出される関数。この変数のデフォルト値はselect-safe-coding-systemwrite-regionのようにテキストをファイルに書き込んだり、process-send-regionのように別プロセスにテキストを送信するEmacsプリミティブは、coding-system-for-writenilにバインドされていれば、通常はこの変数の値を呼び出す(単一の操作にたいするコーディングシステムの指定を参照)。

以下の2つの関数は補完つきでユーザーにコーディングシステムの選択を求めるために使用できます。補完を参照してください。

Function: read-coding-system prompt &optional default

この関数は文字列promptをプロンプトにミニバッファーを使用してコーディングシステムを読み取り、そのコーディングシステムの名前をシンボルとしてリターンする。defaultはユーザーの入力が空の場合にリターンするべきコーディングシステムを指定する。これはシンボルか文字列であること。

Function: read-non-nil-coding-system prompt

この関数は文字列promptをプロンプトにミニバッファーを使用してコーディングシステムを読み取り、そのコーディングシステムの名前をシンボルとしてリターンする。ユーザーが空の入力を試みると再度ユーザーに問い合わせを行う。コーディングシステムを参照のこと。


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

34.10.5 デフォルトのコーディングシステム

このセクションでは特定のファイルや特定のサブプロセス実行時のデフォルトコーディングシステムを指定する変数、およびそれらへアクセスするためのI/O処理が使用する関数について説明します。

これらの変数は希望するデフォルトにそれらすべてを一度セットして、その後は再びそれを変更しないというアイデアにもとづいています。Lispプログラム内の特定の処理で特定のコーディングシステムを指定するために、これらの変数を変更しないでください。かわりにcoding-system-for-readcoding-system-for-writeを使用して、それらをオーバーライドしてください(単一の操作にたいするコーディングシステムの指定を参照)。

User Option: auto-coding-regexp-alist

この変数はテキストパターンと対応するコーディングシステムのalist。要素はそれぞれ(regexp . coding-system)という形式をもつ。冒頭の数キロバイトがregexpにマッチするファイルは、そのコンテンツをバッファーに読み込む際にcoding-systemによりデコードされる。このalist内のセッティングはファイル内のcoding:タグ、およびfile-coding-system-alist (以下参照)の内容より優先される。デフォルト値は、Emacsが自動的にBabylフォーマットのメールファイルを認識してコード変換なしでそれらを読み取れるようにセットされている。

User Option: file-coding-system-alist

この変数は特定のファイルの読み書きに使用するコーディングシステムを指定するalist。要素はそれぞれ(pattern . coding)という形式をもち、patternは特定のファイル名にマッチする正規表現。この要素はpatternにマッチするファイル名に適用される。

要素のCDRとなるcodingはコーディングシステム、2つのコーディングシステムを含むコンスセル、または関数名(関数定義をもつシンボル)であること。codingがコーディングシステムなら、そのコーディングシステムはファイルの読み込みと書き込みの両方で使用される。codingが2つのコーディングシステムを含むコンスセルなら、CARはデコード用のコーディングシステム、CDRはエンコード用のコーディングシステムを指定する。

codingが関数名なら、それはfind-operation-coding-systemに渡されたすべての引数からなるリストを唯一の引数とする関数であること。これはコーディングシステム、または2つのコーディングシステムを含むコンスセルをリターンしなければならない。この値は上記と同じ意味をもつ。

coding (または上記関数のリターン値)がundecidedなら通常のコード検出が行われる。

User Option: auto-coding-alist

この変数は特定のファイルの読み書きに使用するコーディングシステムを指定するalist。この変数の形式はfile-coding-system-alistの形式と似ているが、後者と異なるのはこの変数がファイル内のcoding:タグより優先されること。

Variable: process-coding-system-alist

この変数は何のプログラムがサブプロセス内で実行中かによって、そのサブプロセスにたいしてどのコーディングシステムを使用するかを指定するalist。これはfile-coding-system-alistと同じように機能するが、patternがそのサブプロセスを開始するために使用されたプログラム名にたいしてマッチされる点が異なる。コーディングシステム、またはalist内で指定されたコーディングシステムは、そのサブプロセスへのI/Oに使用されるコーディングシステムの初期化に使用されるが、set-process-coding-systemを使用して後から他のコーディングシステムを指定できる。

警告: データからコーディングシステムを判断するundecidedのようなコーディングシステムは、非同期のサブプロセスでは完全な信頼性をもって機能はしない。これはEmacsが非同期サブプロセスの出力を到着によりバッチ処理するためである。そのコーディングシステムが文字コード変換や行末変換を未指定にしておくと、Emacsは一度に1バッチから正しい変換の検出を試みなければならず、これは常に機能するとは限らない。

したがって非同期サブプロセスでは可能なら文字コード変換と行末変換の両方を判断するコーディングシステム、つまりundecidedlatin-1ではなくlatin-1-unixのようなコーディングシステムを使用すること。

Variable: network-coding-system-alist

この変数はネットワークストリームに使用するコーディングシステムを指定するalist。これはfile-coding-system-alistと同じように機能するが、要素内のpatternがポート番号、または正規表現かもしれない点が異なる。正規表現ならそのネットワークストリームのオープンに使用されたネットワークサービス名にたいしてマッチされる。

Variable: default-process-coding-system

この変数は他に何を行うか指定されていない際に、サブプロセス(とネットワークストリーム)への入出力に使用するコーディングシステムを指定する。

値は(input-coding . output-coding)という形式のコンスセルであること。ここでinput-codingはサブプロセスからの入力、output-codingはサブプロセスへの出力に適用される。

User Option: auto-coding-functions

この変数はファイルのデコードされていないコンテンツにもとづいて、ファイルにたいするコーディングシステムの判断を試みる関数のリストを保持する。

このリスト内の各関数はカレントバッファー内のテキストを調べるように、ただしいかなる方法にせよそれを変更しないよう記述されるべきである。そのバッファーはファイルの一部であるデコードされていないUnicodeテキストを含むだろう。各関数はポイントを始点に何文字を調べる可を告げる唯一の引数sizeをとること。そのファイルにたいするコーディングシステムの決定に関数が成功したら、そのコーディングシステムをリターンすること。それ以外はnilをリターンするべきである。

このリスト内の関数はファイルがvisitされる際にEmacsがファイルのコンテンツのデコードをしようとする場合、および/またはそのファイルのバッファーを保存しようとする際にEmacsがファイルのコンテンツのエンコード方法を決定しようと場合に呼び出されるかもしれない。

ファイルに‘coding:’タグがある場合にはそれが優先されるので、これらの関数が呼び出されることはないだろう。

Function: find-auto-coding filename size

この関数はfilenameに適するコーディングシステムの判定を試みる。これは上記で説明した変数により指定されたルールのいずれかにマッチするまで、それらの変数を順に使用してファイルをvisitするバッファーを調べる。そして(coding . source)という形式のコンスセルをリターンする。ここでcodingは使用するコーディングシステム、sourceauto-coding-alistauto-coding-regexp-alist:codingauto-coding-functionsのいずれかであるようなシンボルであり、マッチングルールとして提供されるルールを示す。値:codingはファイル内のcoding:タグによりコーディングシステムが指定されたことを意味する(coding tag in The GNU Emacs Manualを参照)。マッチングルールを調べる順序はauto-coding-alistauto-coding-regexp-alistcoding:auto-coding-functionsの順。マッチングルールが見つからなければこの関数はnilをリターンする。

2つ目の引数sizeはポイントの後のテキストの文字単位のサイズ。この関数はポイントの後のsize文字のテキストだけを調べる。coding:タグが置かれる箇所としてはファイルの先頭2行が想定される箇所の1つなので、通常はバッファーの先頭位置でこの関数を呼び出すこと。その場合にはsizeはそのバッファーのサイズであること。

Function: set-auto-coding filename size

この関数はファイルfilenameに適するコーディングシステムをリターンする。これはコーディングシステムを探すためにfind-auto-codingを使用する。コーディングシステムを決定できなかったら、この関数はnilをリターンする。引数sizeの意味はfind-auto-codingと同様。

Function: find-operation-coding-system operation &rest arguments

この関数はoperationargumentsで行う際に、(デフォルトで)使用するコーディングシステムをリターンする。値は以下の形式:

(decoding-system . encoding-system)

1つ目の要素decoding-systemはデコード(operationがデコードを行う場合)、encoding-systemはエンコード(operationがエンコードを行う場合)に使用するコーディングシステム。

引数operationはシンボルでwrite-regionstart-processcall-processcall-process-regioninsert-file-contentsopen-network-streamのいずれかであること。これらは文字コード変換と行末変換を行うことができるEmacsのI/Oプリミティブの名前である。

残りの引数は対応するI/Oプリミティブに与えられる引数と同じであること。そのプリミティブに応じてこれらの引数のうち1つがターゲットとして選択される。たとえばoperationがファイルI/Oならファイル名を指定する引数がターゲット。サブプロセス用のプリミティブではプロセス名がターゲット。open-network-streamではサービス名またはポート番号がターゲット。

operationに応じてこの関数はfile-coding-system-alistprocess-coding-system-alistnetwork-coding-system-alistの中からターゲットを探す。このalist内でターゲットが見つかったらfind-operation-coding-systemはalist内のassociation(連想: キーと連想値からなるコンスセル)、それ以外はnilをリターンする。

operationinsert-file-contentsならターゲットに対応する引数は(filename . buffer)という形式のコンスセルだろう。この場合にはfilenamefile-coding-system-alist内で照合されるファイル名であり、bufferはそのファイルの(デコードされていない)コンテンツを含むバッファー。file-coding-system-alistがこのファイルにたいして呼び出す関数を指定していて、かつ(通常行われるように)ファイルのコンテンツを調べる必要があるならファイルを読み込むかわりにbufferのコンテンツを調べること。


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

34.10.6 単一の操作にたいするコーディングシステムの指定

変数coding-system-for-readおよび/またはcoding-system-for-writeをバインドすることにより、特定の操作にたいしてコーディングシステムを指定できます。

Variable: coding-system-for-read

この変数が非nilなら、それはファイルの読み込みや同期サブプロセスプロセスからの入力にたいして使用するコーディングシステムを指定する。

これは非同期サブプロセスやネットワークストリームにも適用されるが方法は異なる。サブプロセス開始時やネットワークストリームオープン時のcoding-system-for-readの値は、サブプロセスやネットワークストリームにたいして入力のデコードメソッドを指定する。そのサブプロセスやネットワークストリームにたいして、オーバーライドされるまでそれが使用され続ける。

特定のI/O操作にたいしてletでバインドするのがこの変数の正しい使い方である。この変数のグローバル値は常にnilであり、他の値にグローバルにセットするべきではない。以下はこの変数の正しい使用例:

;; 文字コード変換なしでファイルを読み込む
(let ((coding-system-for-read 'no-conversion))
  (insert-file-contents filename))

この変数の値が非nilのときはfile-coding-system-alistprocess-coding-system-alistnetwork-coding-system-alistを含む、入力にたいして使用するコーディングシステムを指定するすべてのメソッドよりこの変数が優先される。

Variable: coding-system-for-write

これはcoding-system-for-readと同じように機能するが、入力ではなく出力に適用される点が異なる。これはファイルへの書き込み、同様にサブプロセスやネットワークストリームへの出力の送信にも適用される。これはEmacsがサブプロセスを呼び出す際のコマンドライン引数のエンコーディングにも適用される。

単一の操作がcall-process-regionstart-processのように入力と出力の両方を行う際には、coding-system-for-readcoding-system-for-writeの両方がそれに影響する。

Variable: coding-system-require-warning

coding-system-for-writeに非nil値をバインドすることにより、select-safe-coding-system-functionが指定する関数の呼び出しによる出力プリミティブを抑制する(ユーザーが選択したコーディングシステムを参照)。これはC-x RET c (universal-coding-system-argument)がcoding-system-for-writeをバインドすることにより機能して、かつEmacsはユーザーの選択にしたがう必要があるからである。Lispプログラムが書き込むテキストのエンコーディングに安全ではないかもしれない値をcoding-system-for-writeにバインドする場合には、coding-system-require-warningにも非nil値をバインドできる。これはたとえcoding-system-for-writeが非nilでもselect-safe-coding-system-functionの値の呼び出しによる出力プリミティブにエンコードのチェックを強制する。または指定されたエンコーディングを使用する前に、明示的にselect-safe-coding-systemを呼び出すこと。

User Option: inhibit-eol-conversion

この変数が非nilなら、どのコーディングシステムが指定されたかに関わらず行末変換は何も行われない。これはEmacsすべてのI/Oやサブプロセスにたいするプリミティブ、および明示的なエンコード関数(明示的なエンコードとデコードを参照)とデコード関数に適用される。

ある操作にたいして固定された1つのコーディングシステムではなく複数のコーディングシステムを選択する必要があることがあります。Emacsでは使用するコーディングシステムにたいして優先順位を指定できます。これはfind-coding-systems-region(Lispでのコーディングシステムを参照)のような関数によりリターンされるコーディングシステムのリストのソート順に影響します。

Function: coding-system-priority-list &optional highestp

この関数はコーディングシステムのカレント優先順にコーディングシステムのリストをリターンする。オプション引数highestpが非nilなら、それはもっとも高い優先度のコーディングシステムだけをリターンすることを意味する。

Function: set-coding-system-priority &rest coding-systems

この関数はコーディングシステムの優先リストの先頭にcoding-systemsを配置して、それらを他のコーディングシステムすべてより高い優先度とする。

Macro: with-coding-priority coding-systems &rest body

このマクロはcoding-systemsをコーディングシステム優先リスト先頭に配置して、progn (prognを参照)が行うようにbodyを実行する。coding-systemsbody実行中に選択するコーディングシステムのリストであること。


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

34.10.7 明示的なエンコードとデコード

Emacs内外へテキストを転送するすべての操作は、そのテキストをエンコードまたはデコードする能力をもっています。このセクション内の関数を使用してテキストの明示的なエンコードやデコードを行うことができます。

エンコード結果やデコーディングへの入力は通常のテキストではありません。これらは理論的には一連のバイト値から構成されており、すなわち一連のASCII文字と8ビット文字から構成されます。ユニバイトのバッファーや文字列では、これらの文字は0から#xFF(255)の範囲のコードをもちます。マルチバイトのバッファーや文字列では8ビット文字は#xFFより大きい文字コードをもちますが(テキストの表現方法を参照)、そのようなテキストのエンコードやデコードの際にEmacsは透過的にそれらを単一バイト値に変換します。

コンテンツを明示的にデコードできるようにバイトシーケンスとしてバッファーにファイルを読み込むには、insert-file-contents-literally (ファイルからの読み込みを参照)を使用するのが通常の方法です。あるいはfind-file-noselectでファイルをvisitする際には、引数rawfileに非nilを指定することもできます。これらのメソッドの結果はユニバイトバッファーになります。

テキストを明示的にエンコードした結果であるバイトシーケンスは、たとえばそれをwrite-region (ファイルへの書き込みを参照)で書き込み、coding-system-for-writeno-conversionにバインドすることによりエンコードを抑制する等、それをファイルまたはプロセスへコピーするのが通常の使い方です。

以下はエンコードやデコードを明示的に行う関数です。エンコード関数とはバイトシーケンスを生成し、デコード関数とはバイトシーケンスを操作する関数のことを意味します。これらの関数はすべてテキストプロパティを破棄します。これらは自身が使用したコーディングシステムを、正確にlast-coding-system-usedにセットすることも行います。

Command: encode-coding-region start end coding-system &optional destination

このコマンドはstartからendのテキストをコーディングシステムcoding-systemでエンコードする。バッファー内の元テキストは通常はエンコードされたテキストで置き換えられるが、オプション引数destinationでそれを変更できる。destinationがバッファーなら、エンコードされたテキストはそのバッファーのポイントの後に挿入される(ポイントは移動しない)。tならこのコマンドはエンコードされたテキストを挿入せずにユニバイトとしてリターンする。

エンコードされたテキストが何らかのバッファーに挿入された場合には、このコマンドはエンコードされたテキストの長さをリターンする。

エンコードされた結果は理論的にはバイトシーケンスだが、バッファーが以前マルチバイトだったならマルチバイトのまま留まり、すべての8ビットのバイトはマルチバイト表現に変換される(テキストの表現方法を参照)。

期待しない結果となる恐れがあるので、テキストをエンコードする際にはcoding-systemundecided使用してはならないcoding-systemにたいして自明な適値が存在しなければ適切なエンコードを提案させるために、かわりにselect-safe-coding-systemを使用すること(select-safe-coding-systemを参照)。

Function: encode-coding-string string coding-system &optional nocopy buffer

この関数はコーディングシステムcoding-systemstring内のテキストをエンコードする。これはエンコードされたテキストを含む新たな文字列をリターンするが、nocopyが非nilの場合には、それが些細なエンコード処理ならこの関数はstring自身をリターンする。エンコード結果はユニバイト文字列。

Command: decode-coding-region start end coding-system &optional destination

このコマンドはコーディングシステムcoding-systemで、startからendのテキストをデコードする。明示的なデコードを使いやすくするためにデコード前のテキストはバイトシーケンス値であるべきだが、マルチバイトとユニバイトのバッファーいずれでも許すようになっている(マルチバイトバッファーの場合rawバイト値は8ビット文字で表現されていること)。デコードされたテキストにより通常はバッファー内の元のテキストは置き換えられるが、オプション引数destinationはそれを変更する。destinationがバッファーなら、デコードされたテキストはそのバッファーのポイントの後に挿入される(ポイントは移動しない)。これがtならこのコマンドはデコードされたテキストを挿入せずにマルチバイト文字列としてリターンする。

デコードしたテキストを何らかのバッファーに挿入すると、このコマンドはデコード済みテキストの長さをリターンする。バッファーがユニバイトバッファー(表現の選択を参照)なら、デコード済みテキストの内部表現(テキストの表現方法を参照)が個別のバイトとしてバッファーに挿入される。

このコマンドはデコードされたテキストにテキストプロパティcharsetをputする。このプロパティの値は元のテキストのデコードに使用された文字セットを示す。

このコマンドは必要ならテキストのエンコーディングを検出する。coding-systemundecidedならコマンドはテキスト内に見出されたバイトシーケンスにもとづいてテキストのエンコーディングを検出するとともに、そのテキストが使用している行末変換のタイプ(eol typeを参照)も検出する。coding-systemundecided-eol-type (eol-typeunixdosmacのいずれか)なら、コマンドが検出するのはテキストのエンコーディングのみ。utf-8のようにeol-typeを指定しないすべてのcoding-systemにたいして、このコマンドは行末変換を検出する。そのテキストが使用している行末変換が事前に判っている場合には、余計な自動検出を防ぐために、utf-8-unixのようにエンコーディングを完全に指定すること。

Function: decode-coding-string string coding-system &optional nocopy buffer

この関数はcoding-systemstring内のテキストをデコードする。これはデコードされたテキストを含む新たな文字列をリターンするが、nocopyが非nilの場合には、それが些細なデコード処理ならstring自体をリターンするかもしれない。明示的なデコードを使いやすくするために、stringのコンテンツはバイトシーケンス値をもつユニバイト文字列であるべきだが、マルチバイト文字列も許すようになっている(マルチバイト形式で8ビットバイトを含むと仮定する)。

この関数は必要ならdecode-coding-regionが行うようにエンコーディングを検出する。

オプション引数bufferがバッファーを指定する場合には、デコードされたテキストはバッファー内のポイントの後に挿入される(ポイントは移動しない)。この場合にはリターン値はデコードされたテキストの長さとなる。バッファーがユニバイトバッファーなら、デコード済みテキストの内部表現が個別のバイトとしてバッファーに挿入される。

この関数はデコードされたテキストにテキストプロパティcharsetをputする。このプロパティの値は元のテキストのデコードに使用された文字セットを示す。

(decode-coding-string "Gr\374ss Gott" 'latin-1)
     ⇒ #("Grüss Gott" 0 9 (charset iso-8859-1))
Function: decode-coding-inserted-region from to filename &optional visit beg end replace

この関数はfromからtoのテキストを、あたかも与えられた残りの引数でinsert-file-contentsを使用してファイルfilenameから読み込んだかのようにデコードする。

デコードせずにファイルからテキストを読み込んだ後で、やはりデコードすることを決心したときに使用するのがこの関数の通常の使い方である。テキストを削除して再度読み込むかわりに、この関数を呼び出せばデコードして読み込むことができる。


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

34.10.8 端末I/Oのエンコーディング

Emacsはキーボード入力のデコード、および端末出力のエンコードにコーディングシステムを使用できます。これはLatin-1のような特定のエンコーディングを使用したテキストの送信や表示を行う端末にとって有用です。端末I/Oをエンコードまたはデコードする際には、Emacsはlast-coding-system-usedをセットしません。

Function: keyboard-coding-system &optional terminal

この関数はterminalからのキーボード入力をデコードするために使用するコーディングシステムをリターンする。no-conversionという値は何のデコーディングも行われていないことを意味する。terminalが省略またはnilなら、それは選択されたフレームの端末を意味する。複数の端末を参照のこと。

Command: set-keyboard-coding-system coding-system &optional terminal

このコマンドはterminalからのキーボード入力のデコードに使用するコーディングシステムとしてcoding-systemを指定する。coding-systemnilなら、キーボード入力をデコードしないことを意味する。terminalがフレームなら、それはそのフレームの端末を意味する。nilならそれはカレントで選択されたフレームの端末を意味する。複数の端末を参照のこと。EmacsはMS-Windowsシステムではキーボード入力のデコード時は常にUnicodeを使用するので、このコマンドでエンコーディングをセットしてもWindowsでは効果がないことに注意。

Function: terminal-coding-system &optional terminal

この関数はterminalからの端末出力のエンコードに使用中のコーディングシステムをリターンする。no-conversionという値は何のデコーディングも行われていないことを意味する。terminalがフレームならそれはそのフレームの端末を意味する。nilならそれはカレントで選択されたフレームの端末を意味する。

Command: set-terminal-coding-system coding-system &optional terminal

この関数はterminalからの端末出力のエンコードに使用するためのコーディングシステムとしてcoding-systemを指定する。coding-systemnilなら端末出力をエンコードしないことを意味する。terminalがフレームならそれはそのフレームの端末を意味する。nilならそれはカレントで選択されたフレームの端末を意味する。


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

34.11 入力メソッド

入力メソッド(input methods)はキーボードから非ASCII文字を簡単に入力する手段を提供します。プログラムが読み取ることを意図して非ASCII文字とエンコーディングを相互に変換するコーディングシステムとは異なり、入力メソッドはヒューマンフレンドリーなコマンドを提供します(テキストを入力するためにユーザーが入力メソッドを使う方法についてはInput Methods in The GNU Emacs Manualを参照)。入力メソッドの定義方法はまだこのマニュアルにはありませんが、ここではそれらの使い方について説明します。

現在のところ入力メソッドは文字列で名前をもっていますが、将来的には入力メソッド名としてシンボルも利用可能になるかもしれません。

Variable: current-input-method

この変数はカレントバッファーで現在アクティブな、入力メソッドの名前を保持する(方法に関わらずセット時には各バッファーで自動的にローカルになる)。バッファーで現在アクティブな入力メソッドがなければ値はnil

User Option: default-input-method

この変数は入力メソッドを選択するコマンドにたいしてデフォルトの入力メソッドを保持する。current-input-methodと異なり、この変数は通常はグローバルである。

Command: set-input-method input-method

このコマンドはカレントバッファーで入力メソッドinput-methodをアクティブにする。同様にdefault-input-methodinput-methodのセットも行う。input-methodnilなら、このコマンドはカレントバッファーで入力メソッドを非アクティブにする。

Function: read-input-method-name prompt &optional default inhibit-null

この関数はプロンプトpromptとともにミニバッファーで入力メソッドの名前を読み取る。defaultが非nilの場合には、ユーザーの入力が空ならそれがデフォルトとしてリターンされる。しかしinhibit-nullが非nilなら空の入力はエラーをシグナルする。

リターン値は文字列。

Variable: input-method-alist

この変数はサポートされているすべての入力メソッドを定義する。各要素は1つの入力メソッドを定義して、それぞれ以下の形式をもつ:

(input-method language-env activate-func
 title description args...)

ここでinput-methodはメソッド名の文字列、language-envはこの入力メソッドが推奨される言語環境の名前の文字列(これはドキュメントとしての目的のみの役割を果たす)。

activate-funcはこのメソッドをアクティブにするために呼び出す関数、もしあればargsactivate-funcに渡す引数。つまりactivate-funcの引数はinput-methodargs

titleは、その入力メソッドがアクティブな間にモードライン内に表示するための文字列、descriptionはそのメソッドを説明して、それが何に適するかを説明する文字列。

入力メソッドのための基本的インターフェースは変数input-method-functionです。単一イベントの読み取り入力メソッドの呼び出しを参照してください。


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

34.12 locale

POSIXでは、言語に関連する機能において使用する言語を制御するためにlocaleという概念があります。以下のEmacs変数はEmacsがこれらの機能と相互作用する方法を制御します。

Variable: locale-coding-system

この変数は標準出力とエラーストリームへのバッチ出力の送信、format-time-stringにたいするformat引数のエンコーディング、format-time-stringのリターン値のデコーディングに際してシステムエラーメッセージ(およびXウィンドウシステムに限りキーボード入力)をデコーディングするコーディングシステムを指定する。

Variable: system-messages-locale

この変数はシステムエラーメッセージを生成するために使用するlocaleを指定する。locale変更によりメッセージが異なる言語になったり異なる表記になり得る。この変数がnilなら通常のPOSIX方式のようにlocaleは環境変数により指定される。

Variable: system-time-locale

この変数はタイムバリューをフォーマットするために使用するlocaleを指定する。locale変更により異なる慣習によりメッセージが表示され得る。この変数がnilなら通常のPOSIX方式のようにlocaleは環境変数により指定される。

Function: locale-info item

この変数は、もし利用可能ならカレントPOSIX localeにたいするlocaleデータitemをリターンする。itemは以下のシンボルのいずれかであること:

codeset

文字列として文字セットをリターンする(localeアイテムのCODESET)。

days

曜日名からなる7要素のベクターをリターンする(localeアイテムのDAY_1からDAY_7)。

months

月の名前からなる12要素のベクターをリターンする(localeアイテムのMON_1からMON_12)。

paper

(width height)という2つの整数のリストで、デフォルト用紙サイズをmm単位でリターンする(localeアイテム_NL_PAPER_WIDTH_NL_PAPER_HEIGHT)。

システムが要求された情報を提供できなかったり、itemが上記いずれのシンボルでもなければ値はnil。リターン値内のすべての文字列はlocale-coding-systemを使用してデコードされる。localeとlocaleアイテムについての詳細な情報はLocales in The GNU Libc Manualを参照のこと。


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

35 検索とマッチング

GNU Emacsはバッファーから指定されたテキストを検索するために2つの手段を提供します。それは文字列の正確一致検索(exact string search)と正規表現検索(regular expression search)です。正規表現検索の後で、マッチしたテキストが正規表現全体にマッチしたのか、それとも正規表現のさまざまな部分に一致したかを判断するためにマッチデータ(match data)を調べることができます。

skip-chars…’関連の関数もある種の検索を行います。文字のスキップを参照してください。文字プロパティ内の変更の検索はテキストプロパティの検索関数を参照してください。


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

35.2 検索と大文字小文字

デフォルトのEmacs検索では検索するテキストのcase(大文字と小文字)は無視されます。検索対象に‘FOO’を指定すると、‘Foo’や‘foo’もマッチとみなされます。これは正規表現にも適用されます。つまり‘[aB]’は‘a’、‘A’、‘b’、‘B’にもマッチするでしょう。

この機能が望ましくなければ変数case-fold-searchnilをセットしてください。その場合にはすべての文字はcaseを含めて正確にマッチしなければなりません。これはバッファーローカル変数です。この変数の変更はカレントバッファーだけに影響を与えます(バッファーローカル変数の概要を参照)。かわりにデフォルト値を変更することもできます。Lispコードではletを使用してcase-fold-searchを望む値にバインドするほうが、より一般的でしょう。

ユーザーレベルのインクリメンタル検索機能ではcaseの区別が異なることに注意してください。検索文字列に含まれるのが小文字だけなら検索はcaseを無視しますが、検索文字列に1つ以上の大文字が含まれれば検索はcaseを区別するようになります。しかしLispコード内で使用される検索関数では、これは何も行いません。Incremental Search in The GNU Emacs Manualを参照してください。

User Option: case-fold-search

このバッファーローカル変数は検索がcaseを無視するべきかどうかを決定する。この変数がnilなら検索はcaseを無視しない。それ以外(とデフォルト)ではcaseを無視する。

User Option: case-replace

この変数は高レベルの置換関数がcaseを保持するべきかどうかを決定する。この変数がnilなら、それは置換テキストをそのまま使用することを意味する。非nil値は置換されるテキストに応じて、置換テキストのcaseを変換することを意味する。

この変数は関数replace-matchの引数として渡すことにより使用される。マッチしたテキストの置換を参照のこと。


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

35.3 正規表現

正規表現(regular expression)、略してregexpは文字列の(もしかしたら無限の)セットを表すパターンのことです。regexpにたいするマッチの検索はとても強力な処理です。このセクションではregexpの記述方法、それ以降のセクションではそれらを検索する方法を示します。

正規表現を対話的に開発するためにM-x re-builderコマンドを使用できます。このコマンドは別のバッファーに即座に視覚的なフィードバックを表示することにより、正規表現を作成するための便利なインターフェースを提供します。regexp編集とともにターゲットとなるバッファーのすべてのマッチがハイライトされます。カッコで括られたregexpの部分式(sub-expression)は別のフェイスで表示され、非常に複雑なregexpを簡単に検証することが可能になります。

Emacsの検索はデフォルトではcase(大文字小文字)を区別しないことに注意してください(検索と大文字小文字を参照)。caseを区別したregexpの検索とマッチを有効にするには、区別したいコードの前後でcase-fold-searchnilをバインドしてください。


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

35.3.1 正規表現の構文

正規表現は少数の文字が特別な構成要素であり、残りは通常の文字であるような構文をもちます。通常の文字はその文字自身だけにマッチするシンプルな正規表現です。特別な文字は‘.’、‘*’、‘+’、‘?’、‘[’、‘^’、‘$’、および‘\’です。将来に新たなスペシャル文字が定義されることはないでしょう。文字候補で終わる場合には‘]’はスペシャル文字です。文字候補の間では‘-’はスペシャル文字です。‘[:’と対応する‘:]’は文字候補内の文字クラスです。正規表現内に出現する他の文字は‘\’が前置されていない限り通常の文字です。

たとえば‘f’はスペシャル文字ではなく通常文字なので、‘f’は文字列‘f’にマッチして他の文字にはマッチしない正規表現です(これは文字列‘fg’にはマッチしないが、その文字列の部分にマッチする)。同様に‘o’は‘o’だけにマッチします。

任意の2つの正規表現abを結合することができます。結合した結果は文字列の先頭からある長さの文字列がaにマッチして、残りの文字列がbにマッチするような文字列にマッチする正規表現になります。

単純な例として文字列‘fo’だけにマッチする正規表現の構成要素‘fo’を取得するために正規表現‘f’と‘o’を結合できます。


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

35.3.1.1 正規表現内の特殊文字

以下は正規表現内で特別な文字のリストです:

.(Period)

これは改行を除く1文字にマッチするスペシャル文字。結合を使用して‘a.b’のような正規表現を作成できる。これは‘a’で始まり‘b’で終わる3文字の文字列にマッチする。

*

これはそれ自身が構成要素ではない。これは前置された正規表現を可能な限り繰り返したものにマッチすることを意味する後置演算子である。したがって‘o*’は任意の個数の‘o’にマッチする(‘o’を含まない場合にもマッチする)。

*’は常に前置された表現の最小の表現に適用される。つまり‘fo*’は‘o’の繰り返しであり‘fo’の繰り返しではない。これは‘f’、‘fo’、‘foo’、...にマッチする。

マッチを行う処理は構成要素‘*’をマッチングにより即座に見つけ得る回数分処理して、その後にパターンの残りを継続する。これが失敗したら残りのパターンのマッチが可能になるかもしれないという期待のもとに、‘*’の変更された構成のうちいくつかのマッチを破棄することでバックトラッキングが発生する。たとえば文字列‘caaar’にたいして‘ca*ar’をマッチングすると、‘a*’はまず3つすべての‘a’へのマッチを試みる。しかし残りのパターンは‘ar’であり、マッチ対象に残されているのは‘r’だけなので試みは失敗する。‘a*’にたいする次の代替策は、2つの‘a’だけへのマッチである。この選択では残りのregexpのマッチは成功する。

+

これは‘*’のような後置演算子だが前置された表現に少なくとも1回マッチしなければならない点が異なる。たとえば‘ca+r’は文字列‘car’や‘caaaar’にマッチするが文字列‘cr’にはマッチせず、その一方で‘ca*r’はこれら3つすべての文字列にマッチする。

?

これは‘*’のような後置演算子だが前置された表現に1回、またはマッチしないかのいずれかでなければならない点が異なる。例えば‘ca?r’は‘car’と‘cr’にマッチするが他にはマッチしない。

*?’, ‘+?’, ‘??

演算子 ‘*’、‘+’、‘?’の非欲張り(non-greedy)な変種。これらの演算子が可能な最長の部分文字列(含まれる表現全体へのマッチと等しい)とマッチするのにたいして、非欲張りな変種は可能な最短の部分文字列(含まれる表現全体と等しい)にマッチする。

たとえば正規表現‘c[ad]*a’を文字列‘cdaaada’に適用すると文字列全体にマッチするが、正規表現‘c[ad]*?a’を同じ文字列に適用すると‘cda’だけにマッチする(ここでマッチが許された表現全体にたいする‘[ad]*?’の可能な最短マッチは‘d’)。

[ … ]

これは‘[’で始まり‘]’で終端される文字候補(character alternative)。もっとも単純なケースでは、この2つのカッコ(brackets)の間にある文字が、この文字候補がマッチ可能な文字。

したがって‘[ad]’は1つの‘a’と1つの‘d’の両方にマッチし、‘[ad]*’は‘a’と‘d’だけで構成された任意の文字列(空文字列を含む)にマッチする。つまり‘c[ad]*r’は‘cr’、‘car’、‘cdr’、‘caddaar’等にマッチする。

開始文字と終了文字の間に‘-’を記述することにより文字候補内に文字範囲を含めることができる。つまり‘[a-z]’は小文字のASCIIアルファベット文字にマッチする。範囲は‘[a-z$%.]’のように個別の文字と自由に組み合わせることができる。これは任意のASCII小文字アルファベットと‘$’、‘%’、またはピリオドとマッチする。しかし1つの範囲の終端文字が別の範囲の開始文字ではないこと。たとえば‘[a-m-z]’は使用しないこと。

文字候補には名前付き文字クラスも指定できる(文字クラスを参照)。たとえば‘[[:ascii:]]’は任意のASCII文字にマッチする。文字クラスの使用は、そのクラス内すべての文字を記述するのと等しい。しかし異なる文字数千を含むクラスもあるので後者は実際は実現不可能。文字クラス範囲の上側や下側の境界に出現するべきではない。

文字候補の内部では、通常のregexpスペシャル文字ではスペシャルではない。完全に異なる文字セット‘]’、‘-’、‘^’がスペシャルになる。文字候補に‘]’を含めるには、それを先頭に配置する。‘^’を含めるには、それを先頭以外の場所に配置する。‘-’を含めるには、それを最後に配置する。したがって‘[]^-]’は、これら3つのスペシャル文字すべてにマッチする。ここでは‘\’はスペシャルではないので、これら3つの文字のエスケープに‘\’は使用できない。

以下の範囲にたいする側面はEmacs固有であり、POSIXはこの振る舞いを許容はするが必須ではなく、Emacs以外のプログラムは異なる振る舞いをするかもしれない。

  1. case-fold-searchが非nilなら‘[a-z]’は大文字にもマッチする。
  2. 範囲はlocaleの照合順の影響を受けない。範囲は常にその範囲の境界間に存在するコードポイントを文字セットで表現されるので、たとえCやPOSIXのlocale外部でも‘[a-z]’がマッチするのはASCII文字のみ。
  3. 範囲の下側境界が上側境界より大きければ範囲は空であり何の文字も表現しない。したがって‘[z-a]’は常にマッチに失敗するし、‘[^z-a]’は改行を含む任意の文字にマッチする。ただし逆転した範囲はtypoでないことを明確にするために、常に文字‘z’から文字‘a’にすること。たとえば‘[+-*/]’は意図した4つの文字ではなく、‘/’だけにマッチするので避けること。
  4. 範囲の終端が8ビットrawバイト(テキストの表現方法を参照)、あるいは(‘[a-\377]’のように)先頭がASCIIで終端がrawバイトなら、その範囲はASCII文字および8ビットrawバイトだけにマッチして、非ASCII文字にはマッチしない。この機能はユニバイトのバッファーおよび文字列におけるテキスト検索を意図している。

ある種の文字候補は、たとえそれらがEmacs内において明確に定義された意味をもっているとしても最良のスタイルとならない。これらには以下が含まれる:

  1. ほとんどすべての文字を範囲の境界にできるとはいえ、文字コードテーブルを記憶している人はほとんどいないので、ASCII文字や数字の自然な順序を守るほうがよいスタイルである。たとえば‘[.-9]’は‘[./0-9]’、‘[`-~]’は‘[`a-z{|}~]’より明確さに劣る。ここではUnicodeの文字エスケープが助けとなる。たとえばほとんどのプログラマーにとっては‘[ก-ฺ฿-๛]’より‘[\u0E01-\u0E3A\u0E3F-\u0E5B]’のほうが明確だろう。
  2. 文字候補に重複を含めることができたとしても、それを避けるほうがよいスタイルである。たとえば‘[XYa-yYb-zX]’は‘[XYa-z]’より明確さに劣る。
  3. 範囲を単に1文字、2文字、あるいは3文字で表せたとしても、文字をリストするほうがシンプルである。たとえば‘[a-a0]’は‘[a0]’、‘[i-j]’は‘[ij]’、‘[i-k]’は‘[ijk]’より明確さに劣る。
  4. たとえ文字候補の先頭や範囲の上側境界として‘-’を配置できるとしても、文字候補の最後に‘-’そのものを配置するほうがよいスタイルである。たとえば‘[-a-z]’が有効であっても‘[a-z-]’のほうがよいスタイルであり、‘[*--]’が有効だとしても‘[*+,-]’のほうが明確である。
[^ … ]

[^’は補完文字候補(complemented character alternative)を開始する。これは指定された以外の任意の文字とマッチする。つまり‘[^a-z0-9A-Z]’はASCII文字と数字以外の、すべての文字にマッチする。

^’は文字クラス内では先頭に記述されない限り特別ではない。‘^’に続く文字は、あたかもそれが先頭にあるかのように扱われる(言い換えると‘-’や‘]’はここでは特別ではない)。

マッチしない文字の1つとして改行が記述されていなければ、補完文字候補は改行にマッチできる。これはgrepのようなプログラム内でのregexpの扱いとは対照的である。

文字候補のように名前付き文字クラスを指定できる。たとえば‘[^[:ascii:]]’は任意の非ASCII文字にマッチする。文字クラスを参照のこと。

^

バッファーのマッチングの際には‘^’は空文字列、ただしマッチ対象のテキスト内にある行の先頭(またはバッファーのアクセス可能範囲の先頭)だけにマッチする。それ以外のマッチはすべて失敗する。つまり‘^foo’は行の先頭に出現する‘foo’にマッチする。

バッファーではなく文字列とマッチする際には、‘^’は文字列の先頭か改行文字の後にマッチする。

歴史的な互換性という理由により‘^’は正規表現の先頭、または‘\(’、‘\(?:’、‘\|’の後でのみ使用できる。

$

これは‘^’と似ているが、行の終端(またはバッファーのアクセス可能範囲の終端)だけにマッチする。つまり‘x+$’は行末にある1つ以上の‘x’からなる文字列にマッチする。

バッファーではなく文字列とマッチする際には、‘$’は文字列の終端か改行文字の前にマッチする。

歴史的な互換性という理由により‘$’は正規表現の終端、または‘\)’、‘\|’の前でのみ使用できる。

\

これはスペシャル文字(‘\’を含む)のクォートと、追加のスペシャル文字の導入という2つの機能をもつ。

\’はスペシャル文字をクォートするので‘\$’は‘$’、‘\[’は‘[’だけにマッチする正規表現のようになる。

\’はLisp文字列(文字列型を参照)の入力構文(read syntax)内でも特別な意味をもち、‘\’でクォートしなければならないことに注意。たとえば文字‘\’にマッチする正規表現は‘\\’。文字‘\\’を含むLisp文字列を記述するには、別の‘\’で‘\’をクォートすることをLisp構文は要求する。したがって‘\’にマッチする正規表現にたいする入力構文は"\\\\"となる。

注意してください: 歴史的な互換性のために、スペシャル文字はそれらがもつ特別な意味が意味を成さないコンテキスト内にある場合には通常の文字として扱われます。たとえば‘*foo’は‘*’が作用可能な前置された表現がないので、通常の‘*’として扱われます。この挙動に依存するのは悪い習慣です。どこにそれが出現しようとスペシャル文字はすべてクォートしてください。

文字候補内で‘\’は何ら特別ではないので‘-’、‘^’、‘]’がもつ特別な意味を取り除くことは決してありません。特別な意味をもたないような場合に、これらの文字をクォートするべきではありません。それによって何かが明確になる訳ではありません。なぜならバックスラッシュ以外の任意の1文字にマッチする‘[^\]’ (Lisp文字列構文では"[^\\]")の内部のように、これらの文字が特別な意味をもつ箇所では、これらの文字にバックスラッシュを問題なく前置できるからです。

実際には正規表現内に出現する‘]’は文字候補に近接しており、それ故そのほとんどがスペシャル文字です。しかしリテラルの‘[’と‘]’の複雑なパターンにたいしてマッチを試みることも時にはあるかもしれません。そのような状況では文字候補を囲う角カッコがどれなのかを判断するために、regexpを最初から注意深く解析することが必要なときもあるかもしれません。たとえば‘[^][]]’は補完文字候補‘[^][]’ (角カッコ以外の任意の1文字とマッチする)と、その後のリテラルの‘]’により構成されます。

厳密にはregexp先頭の‘[’は特別で、‘]’は特別ではないというのがルールです。これはクォートされていない最初の‘[’で終わり、その後は文字候補になります。(文字クラス開始を除き)‘[’はもはや特別ではありませんが、‘]’は直後にスペシャル文字‘[’があるか、その‘[’の後に‘^’がある場合を除いて特別です。これは文字クラス終了ではない次のスペシャル文字‘]’まで続きます。これは文字候補を終了させて、通常の正規表現の構文をリストアします。クォートされていない‘[’は再び特別となり、‘]’は特別ではなくなります。


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

35.3.1.2 文字クラス

以下は文字候補内で使用できるクラスと意味のテーブルです。クラス名を囲む‘[’と‘]’の文字は名前の一部なので、これらのクラスを使用する正規表現では1つ余分にカッコ(brackets)が必要になります。たとえば1つ以上のアルファベットか数字のシーケンスにマッチする正規表現は、‘[:alnum:]+’ではなく‘[[:alnum:]]+’です。

[:ascii:]

これは任意のASCII文字(コード0 – 127)にマッチする。

[:alnum:]

これは任意の英数字にマッチする。マルチバイト文字では、アルファベット文字か数字であることを示すUnicodeプロパティ‘general-category’ (文字のプロパティを参照)をもつ文字にマッチする。

[:alpha:]

これは任意のアルファベットにマッチする。マルチバイト文字では、アルファベット文字であることを示すUnicodeプロパティ‘general-category’ (文字のプロパティを参照)をもつ文字にマッチする。

[:blank:]

これは Unicode Technical Standard #18のAnnex Cで定義される水平の空白文字(horizontal whitespace)にマッチする。特にスペース、タブ、およびスペース区切りであることをUnicodeの‘general-category’プロパティ(文字のプロパティを参照)が示す他の文字にマッチする。

[:cntrl:]

これはコードが1から31の範囲にあるすべての文字にマッチする。

[:digit:]

これは‘0’から‘9’までにマッチする。つまり‘[-+[:digit:]]’は‘+’と‘-’、同様に任意の数にマッチする。

[:graph:]

これはUnicodeの‘general-category’プロパティで示されるようなグラフィック文字(スペース文字、ASCIIと非ASCIIの制御文字、サロゲートコードポイント、Unicodeで未割り当てのコードポイントを除くすべて)にマッチする(文字のプロパティを参照)。

[:lower:]

これはカレントのcaseテーブル(caseテーブルを参照)で小文字と判断される文字すべてにマッチする。case-fold-searchが非nilなら大文字にもマッチする。バッファーはデフォルトとは異なるローカルのcaseテーブルを独自にもてることに注意。

[:multibyte:]

これは任意のマルチバイト文字にマッチする(テキストの表現方法を参照)。

[:nonascii:]

これは非ASCII文字にマッチする。

[:print:]

これは任意のプリント文字(スペース文字か‘[:graph:]’でマッチされるグラフィック文字のいずれか)にマッチする。

[:punct:]

これは任意の句読点文字(punctuation character)にマッチする(現在のところマルチバイト文字では単語構文以外のすべてにマッチするが、文字の構文はメジャーモード次第なのでメジャーモードごとに正確な定義は様々である)。

[:space:]

空白文字の構文(構文クラスのテーブルを参照)をもつ任意の文字にマッチする。文字の構文、すなわち何の文字を“空白”とみなすかはメジャーモード次第だということに注意。

[:unibyte:]

これは任意のユニバイト文字(テキストの表現方法を参照)にマッチする。

[:upper:]

これはカレントのcaseテーブル(caseテーブルを参照)で大文字と判断される文字すべてにマッチする。case-fold-searchが非nilならこれは小文字にもマッチする。バッファーはデフォルトとは異なるローカルのcaseテーブルを独自にもてることに注意。

[:word:]

単語の構文(構文クラスのテーブルを参照)をもつ任意の文字にマッチする。文字の構文、すなわち何の文字を“単語の構成文字”とみなすかはメジャーモード次第だということに注意。

[:xdigit:]

これは16進数の数字‘0’から‘9’、‘a’から‘f’と‘A’から‘F’にマッチする。


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

35.3.1.3 正規表現内のバッククラッシュ構文

ほとんどの場合では、‘\’の後の任意の文字はその文字だけにマッチします。しかし例外もいくつかあります。‘\’で始まる特定のシーケンスには、特別な意味をもつものがあります。以下は特別な‘\’構成要素のテーブルです。

\|

これは選択肢を指定する。2つの正規表現ab、その間にある‘\|’により、abのいずれかにマッチする表現が形成される。

つまり‘foo\|bar’は、‘foo’か‘bar’のいずれかにマッチして他の文字列にはマッチしない。

\|’は周囲の適用可能な最大の表現に適用される。‘\|’を取り囲む‘\( … \)’でグループ化することによりグループ化の効力を制限できる。

複数の‘\|’の処理するための完全なバックトラッキング互換が必要なら、POSIX正規表現関数を使用すること(POSIX正規表現の検索を参照)。

\{m\}

これは前のパターンを正確にm回繰り返す後置演算子。つまり‘x\{5\}’は文字列‘xxxxx’にマッチして、それ以外にはマッチしない。‘c[ad]\{3\}r’は‘caaar’、‘cdddr’、‘cadar’等にマッチする。

\{m,n\}

これは最小でm回、最大でn回繰り返すより一般的な後置演算子。m省略時の最小は0、n省略時の最大は存在しない。いずれの形式でもmnが指定された場合には、 2**16 - 1 より大きくなることはない。

たとえば‘c[ad]\{1,2\}r’は文字列‘car’、‘cdr’、‘caar’、‘cadr’、‘cdar’、‘cddr’にマッチして、それ以外にはマッチしない。
\{0,1\}’や‘\{,1\}’は‘?’と同じ。
\{0,\}’や‘\{,\}’は‘*’と同じ。
\{1,\}’は‘+’と同じ。

\( … \)

これは以下の3つの目的を果たす役目をもつグループ化構成要素:

  1. 他の操作のために一連の‘\|’選択肢を囲う。つまり正規表現‘\(foo\|bar\)x’は、‘foox’か‘barx’のいずれかにマッチする。
  2. 後置演算子‘*’、‘+’、‘?’による複雑な表現を囲う。つまり‘ba\(na\)*’は‘ba’、‘bana’、‘banana’、‘bananana’、...等の任意の数(0以上)の文字列‘na’にマッチする。
  3. \digit’ (以下参照)による将来の参照にたいして、マッチする部分文字列を記録する。

この最後の目的はカッコによるグループ化というアイデアによるものではない。これは同じ構成要素‘\( … \)’にたいする2つ目の目的に割当てられた別の機能だが、実際のところ2つの意味は衝突しない。しかし稀に衝突が発生することがあり、それが内気(shy)なグループの導入をもたらした。

\(?: … \)

これは内気なグループ(shy group)の構成要素。内気なグループは通常のグループの最初の2つの役目(他の演算子のネスト制御)を果たすが、これは番号を取得せず‘\digit’でその値を後方参照できない。内気なグループは通常の非内気なグループを変更することなく自動的に追加できるので、機械的に正規表現を構築するのに特に適している。

内気なグループ化は非キャプチャリング(non-capturing)番号なしグループ(unnumbered groups)とも呼ばれる。

\(?num: … \)

これは明示的番号付きグループ(explicitly numbered group)の構成要素。通常のグループ化では位置をもとに番号が暗黙で取得されるが、これが不便な場合もあるだろう。この構成要素により特定のグループに番号を強制できる。番号の付与に特別な制限はなく、複数のグループに同じ番号を付与でき、その場合は最後の1つ(もっとも右のマッチ)がマッチとして採用される。暗黙に番号付けされたグループは、常に前のグループより大きい最小の整数となる番号を取得する。

\digit

これはグループ構成要素(‘\( … \)’)のdigit番目にマッチしたテキストと同じテキストにマッチする。

言い換えると最後のグループの後に、マッチ処理はそのグループによりマッチされたテキストの開始と終了を記憶する。その正規表現の先の箇所で‘\’とその後にdigitを使用すれば、それが何であれ同じテキストにマッチさせることができる。

検索やマッチングを行う関数に渡される正規表現全体の中で、最初の9つのグループ化構成要素にマッチする文字列には、その正規表現内で開カッコが出現する順に1から9までの番号が割り当てられる。したがって‘\1’から‘\9’までを使用して、対応するグループ化構成要素によりマッチされたテキストを参照できる。

たとえば‘\(.*\)\1’は、一方がもう一方と等しいような2つの文字列から構成される、改行を含まない任意の文字列にマッチする。‘\(.*\)’は前半分にマッチし、これは何でもよいが、それに続く‘\1’はそれと同じテキストに正確にマッチしなければならない。

構成要素‘\( … \)’が2回以上マッチする場合(これはたとえば後に‘*’をしたがえるとき発生し得る)には最後のマッチだけが記録される。

正規表現内の特定のグループ化構成要素がマッチしなかった場合には、たとえばそれが使用されない選択肢内にあったり、回数が0回の繰り返しの内部にあるなら、それに対応する‘\digit’構文は何にもマッチしない。作為的な例を用いると‘\(foo\(b*\)\|lose\)\2’は‘lose’にマッチできない。外側のグループ内の2つ目の選択肢がマッチするが、‘\2’が未定義となり何にたいしてもマッチできない。しかし‘foobb’にたいしては、1つ目の選択肢が‘foob’にマッチして、‘\2’が‘b’にマッチするのでマッチが可能になる。

\w

これは任意の単語構成文字にマッチする。エディターの構文テーブルが、どの文字が単語構成文字かを決定する。構文テーブルを参照のこと。

\W

これは任意の非単語構成文字にマッチする。

\scode

これは構文がcodeであるような任意の文字にマッチする。ここでcodeは、構文コードを表す文字。‘w’は単語構成要素、‘-’は空白文字、‘(’は開カッコ、...等。空白文字構文を表すには、‘-’かスペース文字のいずれかを使用する。構文コードとそれらを意味する文字のリストは構文クラスのテーブルを参照のこと。

\Scode

これは構文がcodeでないような任意の文字にマッチする。

\ccode

これはカテゴリーがcodeであるような任意の文字にマッチする。ここでcodeはカテゴリーを表す文字。たとえば標準カテゴリーテーブルでは‘c’はChinese(中国語)、‘g’はGreek(ギリシャ語)の文字を表す。M-x describe-categories RETで現在定義済みの全カテゴリーのリストを確認できる。define-category関数を使用すれば、標準カテゴリーに加えて独自カテゴリーを定義することもできる(カテゴリーを参照)。

\Ccode

これはカテゴリーがcodeではない任意の文字にマッチする。

以下は空文字列にマッチします(つまり文字を何も消費しない)が、マッチするかどうかがコンテキストに依存するような正規表現を構築します。これらすべてにたいして、そのバッファーのアクセス可能範囲の先頭と終端は、あたかもそのバッファーの実際の先頭と終端のように扱われます。

\`

これは空文字列、ただしバッファー先頭またはマッチ対象の文字列の先頭だけにマッチする。

\'

これは空文字列、ただしバッファー終端またはマッチ対象の文字列の終端だけにマッチする。

\=

これは空文字列、ただしポイント位置だけにマッチする(この構成要素はマッチ対象が文字列なら定義されない)。

\b

これは空文字列、ただし単語の先頭だけにマッチする。つまり‘\bfoo\b’は個別の単語として出現する‘foo’だけにマッチする。‘\bballs?\b’は、個別の単語として‘ball’か‘balls’にマッチする。

\b’は、隣接するテキストが何であるかと無関係に、バッファー(か文字列)の先頭または終端にマッチする。

\B

これは空文字列、単語の先頭や終端、またはバッファー(か文字列)の先頭や終端以外にマッチする。

\<

これは空文字列、ただし単語の先頭だけにマッチする。‘\<’は後に単語構成文字が続く場合のみバッファー(か文字列)の先頭にマッチする。

\>

これは空文字列、ただし単語の終端だけにマッチする。‘\<’はコンテンツが単語構成文字で終わる場合のみバッファー(か文字列)の終端にマッチする。

\_<

これは空文字列、ただしシンボルの先頭だけにマッチする。シンボルとは1つ以上の単語かシンボル構成文字のシーケンス。‘\_<’は後にシンボル構成文字が続く場合のみバッファー(か文字列)の先頭にマッチする。

\_>

これは空文字列、ただし単語の終端だけにマッチする。‘\_>’はコンテンツがシンボル構成文字で終わる場合のみバッファー(か文字列)の終端にマッチする。

すべての文字列が、有効な正規表現な訳ではありません。たとえば終端の‘]’がない文字選択肢の内側で終わる文字列は無効であり、単一の‘\’で終わる文字列も同様です。いずれかの検索関数にたいして無効な正規表現が渡されるとinvalid-regexpエラーがシグナルされます。


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

35.3.2 正規表現の複雑な例

以下は後続の空白文字とともにセンテンスの終わりを認識するために、以前のEmacsで使用されていた複雑な正規表現の例です(現在のEmacsは関数sentence-endにより構築される、同様のより複雑なregexpを使用する。編集で使用される標準的な正規表現を参照)。

以下ではまず、(スペースとタブ文字を区別するために)Lisp構文の文字列としてregexpを示して、それを評価した結果を示します。文字列定数の開始と終了はダブルクォーテーションです。‘\"’は文字列の一部としてのダブルクォーテーション、‘\\’は文字列の一部としてのバックスラッシュ、‘\t’はタブ、‘\n’は改行を意味します。

"[.?!][]\"')}]*\\($\\| $\\|\t\\|  \\)[ \t\n]*"
     ⇒ "[.?!][]\"')}]*\\($\\| $\\|  \\|  \\)[
]*"

改行とタブは、それら自身として出力されます。

この正規表現は連続する4つのパートを含み、以下のように解読できます:

[.?!]

この正規表現の1つ目のパートはピリオド、疑問符、感嘆符の3つのうちいずれか1つにマッチする文字選択肢。マッチはこれら3つの文字のいずれかで開始されなければならない(これは旧正規表現とEmacsが使用する新たなデフォルトregexpが異なる1つのポイントである。新たな値は後続の空白文字なしでセンテンスを終端する、いくつかの非ASCII文字を許容する)。

[]\"')}]*

パターンの2つ目のパートは任意の0個以上の閉カッコとクォーテーションマークであり、その後にピリオド、疑問符、感嘆符があるかもしれない。\"は文字列内でのダブルクォーテーションマークにたいするLisp構文。最後の‘*’は直前の正規表現(この場合は文字選択肢)の0回以上の繰り返しを示す。

\\($\\| $\\|\t\\|  \\)

パターンの3つ目のパートはセンテンスの後の空白文字、すなわち行の終端(スペースがあっても可)、タブ、または2つのスペースにマッチする。2連バックスラッシュはカッコと垂直バーを正規表現構文としてマークする。すなわちカッコはグループを句切り、垂直バーは選択肢を区別する。ダラー記号は行の終端へのマッチに使用される。

[ \t\n]*

最後にパターンの最終パートはセンテンスを終端させるために必要とされる以上の、余分な空白文字にマッチする。

rx (rx構造化Rgexp表記を参照)表記では以下のようにregexpを記述できます

(rx (any ".?!")                    ; センテンスを終端する区切り文字
    (zero-or-more (any "\"')]}"))  ; 終わりのクォートやカッコ
    (or line-end
        (seq " " line-end)
        "\t"
        "  ")                      ; 2つのスペース
    (zero-or-more (any "\t\n ")))  ; オプションの余分な空白文字

rxによるregexpsは単なるS式なので、このように整形してコメントを付することができるのです。


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

35.3.3 rx構造化Rgexp表記

文字ベースの構文にたいする代替えとして、EmacsはLispのS式にもとづく構造化されたrx表記を提供します。この表記により通常はregexp文字列をより簡単に読解、記述、保守することができ、自由にインデントしてコメントを記述できます。regexp関数が期待するのは文字列形式なので変換が必要になりますが、この変換はregexpを使用するLispコードの実行時ではなく、通常はバイトコンパイルの間に行われます。

以下はCプログラム言語のブロックコメントにマッチするrxのregexpです26

(rx "/*"                          ; 始まりの/*
    (zero-or-more
     (or (not (any "*"))          ;  非*
         (seq "*"                 ;  または
              (not (any "/")))))  ;  /が後置されていない*
    (one-or-more "*")             ; 少なくとも1つの*
    "/")                          ; と終わりの/

短いシノニムを使用してより簡潔に記述すると、

(rx "/*"
    (* (| (not "*")
          (: "*" (not "/"))))
    (+ "*") "/")

従来の文字列構文では以下のような記述になります

"/\\*\\(?:[^*]\\|\\*[^/]\\)*\\*+/"

rx表記は主にLispコード内で有用です。query-replace-regexpの実行時や変数のカスタマイゼーションのように、regexpが要求されるインタラクティブな状況下では使用することができません。


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

35.3.3.1 rxによるregexpの構築

rxのregexpsにおける種々のフォームを以下で説明します。省略形式として使用するrxは任意のrxフォームを表します。rx…は0個以上のrxフォームを表し、特に明記しないかぎりこれらのフォームは(seq …)というサブフォームで括られているかのように順にマッチします。

以下はすべてrxマクロにたいする有効な引数です。これらのフォームはすべて記述のされ方によって定義されます。それぞれに記述されている文字列regexpは、単に理解を容易にするために提供されています。(適切なカッコで括られた)AB、…は、それらの部分式における文字列regexpを意味します。

リテラル

"some-string"

文字列‘some-string’にリテラル(文字通り)にマッチする。文字列regexpsとは異なり特別な意味をもつ文字はない。

?C

文字‘C’にリテラルにマッチする。

シーケンスと候補

(seq rx…)
(sequence rx…)
(: rx…)
(and rx…)

順にrxをマッチする。引数なしなら、その式は空文字列にマッチする。
対応する文字列regexpは‘AB’ (シーケンス内の部分式)。

(or rx…)
(| rx…)

rxのうちのいずれか1つに正確にマッチする。すべての引数が文字列か文字、またはそのようなorフォームなら、可能な最長マッチを常に使用する。それ以外なら最長のマッチ、または(L2R順で)最初のマッチのいずれかを使用する。引数なしなら、その式は何にもマッチすることはない。
対応する文字列regexpは‘A\|B\|…’。

unmatchable

すべてのマッチを拒絶する。(or)と等価。regexp-unmatchableを参照のこと。

繰り返し

繰り返しフォームは通常は可能なかぎり多数回のマッチを試みるので欲張り(greedy)です。いくつかのフォームは可能なかぎり少数回のマッチを試みるので非欲張り(non-greedy)です(Non-greedy repetitionを参照)。

(zero-or-more rx…)
(0+ rx…)

rxに0回以上マッチする。デフォルトでは欲張り。
対応する文字列regexpは‘A*’ (欲張り)、‘A*?’ (非欲張り)。

(one-or-more rx…)
(1+ rx…)

rxに1回以上マッチする。デフォルトでは欲張り。
対応する文字列regexpは‘A+’ (欲張り)、‘A+?’ (非欲張り)。

(zero-or-one rx…)
(optional rx…)
(opt rx…)

rxに1回、または空文字列にマッチする。デフォルトでは欲張り。
対応する文字列regexpは‘A?’ (欲張り)、‘A??’ (非欲張り)。

(* rx…)

rxに0回以上マッチする。欲張り。
対応する文字列regexpは‘A*’。

(+ rx…)

rxに1回以上マッチする。欲張り。
対応する文字列regexpは‘A+’。

(? rx…)

rxに1回、または空文字列にマッチする。欲張り。
対応する文字列regexpは‘A?’。

(*? rx…)

rxに0回以上マッチする。非欲張り。
対応する文字列regexpは‘A*?’。

(+? rx…)

rxに1回以上マッチする。非欲張り。
対応する文字列regexpは‘A+?’。

(?? rx…)

rx、または空文字列にマッチする。非欲張り。
対応する文字列regexpは‘A??’。

(= n rx…)
(repeat n rx)

rxに正確にn回マッチする。
対応する文字列regexpは‘A\{n\}’。

(>= n rx…)

rxn回以上マッチする。欲張り。
対応する文字列regexpは‘A\{n,\}’。

(** n m rx…)
(repeat n m rx…)

rxに少なくともn回、ただしm回を超えない回数マッチする。欲張り。
対応する文字列regexpは‘A\{n,m\}’。

いくつかの繰り返しフォームの欲張りの度合いは以下の構文を使用して制御できます。しかしそのようなマッチングが要求される際には、通常は上述した明示的な非欲張りフォームを使用するほうがよいでしょう。

(minimal-match rx)

非欲張りなマッチングを使用してzero-or-more0+one-or-more1+zero-or-oneoptoptionalによりrxをマッチする。

(maximal-match rx)

欲張りなマッチングを使用してzero-or-more0+one-or-more1+zero-or-oneoptoptionalによりrxをマッチする。これがデフォルト。

単一文字のマッチ

(any set…)
(char set…)
(in set…)

setのいずれかより1文字をマッチする。setはそれぞれ文字、それ自身が文字セットを表す文字列、範囲、または文字クラス(以下参照)。範囲は"A-Z"のようにハイフンで区切られた文字列、または(?A . ?Z)のようなコンスセル。

この構文における文字列内のハイフン(-)は範囲区切りとして振る舞うのでスペシャル。ハイフンを含めるには区切り文字か単一文字の文字列として追加する。
対応する文字列regexpは‘[…]’。

(not charspec)

charspecに含まれない文字にマッチする。charspecは文字、単一文字の文字列、フォームanynotorintersectionsyntaxcategory、または文字クラス。charspecorフォームなら、その引数にはintersectionの引数と同じ制限がある。以下参照。
対応する文字列regexpは‘[^…]’、‘\Scode’、‘\Ccode’。

(intersection charset…)

charsetに含まれるすべての文字にマッチする。charsetはそれぞれ文字、単一文字の文字列、文字クラスなしのanyフォーム、または引数がcharsetであるようなintersectionornotフォーム。

not-newlinenonl

改行を除くすべての文字にマッチする。
対応する文字列regexpは‘.’ (ドット)。

anycharanything

すべての文字にマッチする。
対応する文字列regexpはたとえば‘.\|\n’。

文字クラス

以下の名前つき文字クラスの文字にマッチする:

alphaalphabeticletter

アルファベット文字にマッチする。より正確には、Unicodeの‘general-category’プロパティがアルファベット文字であることを示すような文字にマッチする。

alnumalphanumeric

アルファベット文字と数字にマッチする。より正確には、Unicodeの‘general-category’プロパティがアルファベット文字か10進数字であることを示すような文字にマッチする。

digitnumericnum

0’から‘9’の数字にマッチする。

xdigithex-digithex

0’から‘9’、‘A’から‘F’および‘a’から‘f’の16進数字にマッチする。

cntrlcontrol

コードが0から31の範囲の任意の文字にマッチする。

blank

水平空白文字(horizontal whitespace)にマッチする。より正確には、Unicodeの‘general-category’プロパティがスペース区切り文字(spacing separators)であることを示すような文字にマッチする。

spacewhitespacewhite

空白文字構文をもつすべての文字にマッチする(構文クラスのテーブルを参照)。

lowerlower-case

カレントのcaseテーブルで小文字として判断されるすべての文字にマッチする。case-fold-searchが非nilならすべての大文字にもマッチする。

upperupper-case

カレントのcaseテーブルで大文字として判断されるすべての文字にマッチする。case-fold-searchが非nilならすべての小文字にもマッチする。

graphgraphic

Unicodeの‘general-category’プロパティで示されるような空白文字、ASCIIと非ASCIIの制御文字、サロゲートコードポイント、Unicodeで未割り当てのコードポイントを除くすべての文字にマッチする。

printprinting

空白文字かgraphにマッチする文字にマッチする。

punctpunctuation

任意の句読点文字(punctuation character)にマッチする(現在のところマルチバイト文字では非単語構文のすべてにマッチする)。

wordwordchar

単語構文(構文クラスのテーブルを参照)をもつ任意の文字にマッチする。

ascii

任意のASCII文字(コード0から127)にマッチする。

nonascii

ASCII文字(ただしrawバイト以外)にマッチする。

対応する文字列regexpは‘[[:class:]]’。

(syntax syntax)

以下の名前のいずれかの構文syntaxの文字にマッチする。

構文名構文文字
whitespace-
punctuation.
wordw
symbol_
open-parenthesis(
close-parenthesis)
expression-prefix'
string-quote"
paired-delimiter$
escape\
character-quote/
comment-start<
comment-end>
string-delimiter|
comment-delimiter!

詳細は構文クラスのテーブルを参照のこと。(syntax punctuation)は文字クラスpunctuation等価ではないことに注意してほしい。
対応する文字列regexpは‘\schar’ (charは構文文字)。

(category category)

以下のカテゴリー名かカテゴリー文字のいずれかであるようなカテゴリーcategoryの文字にマッチする.

カテゴリー名カテゴリー文字
space-for-indentスペース
base.
consonant0
base-vowel1
upper-diacritical-mark2
lower-diacritical-mark3
tone-mark4
symbol5
digit6
vowel-modifying-diacritical-mark7
vowel-sign8
semivowel-lower9
not-at-end-of-line<
not-at-beginning-of-line>
alpha-numeric-two-byteA
chinese-two-byteC
greek-two-byteG
japanese-hiragana-two-byteH
indian-two-byteI
japanese-katakana-two-byteK
strong-left-to-rightL
korean-hangul-two-byteN
strong-right-to-leftR
cyrillic-two-byteY
combining-diacritic^
asciia
arabicb
chinesec
ethiopice
greekg
koreanh
indiani
japanesej
japanese-katakanak
latinl
laoo
tibetanq
japanese-romanr
thait
vietnamesev
hebreww
cyrillicy
can-break|

カレントで定義されているカテゴリーに関する情報は、コマンドM-x describe-categories RETを実行する。新たなカテゴリーを定義する方法についてはカテゴリーを参照のこと。
対応する文字列regexpは‘\cchar’ (charはカテゴリー文字)。

0幅アサーション

これらはすべて空文字列、ただし特定箇所箇所だけにマッチします。

line-startbol

行の先頭にマッチする。
対応する文字列regexpは‘^’。

line-endeol

行の終端にマッチする。
対応する文字列regexpは‘$’。

string-startbosbuffer-startbot

マッチする文字列かバッファーの先頭にマッチする。
対応する文字列regexpは‘\`’。

string-endeosbuffer-endeot

マッチする文字列かバッファーの終端にマッチする。
対応する文字列regexpは‘\'’。

point

ポイントにマッチする。
対応する文字列regexpは‘\=’。

word-startbow

単語の先頭にマッチする。
対応する文字列regexpは‘\<’。

word-endeow

単語の終端にマッチする。
対応する文字列regexpは‘\>’。

word-boundary

単語の先頭か終端にマッチする。
対応する文字列regexpは‘\b’。

not-word-boundary

単語の先頭と終端以外のすべての箇所にマッチする。
対応する文字列regexpは‘\B’。

symbol-start

シンボルの先頭にマッチする。
対応する文字列regexpは‘\_<’。

symbol-end

シンボルの終端にマッチする。
対応する文字列regexpは‘\_>’。

キャプチャーグループ

(group rx…)
(submatch rx…)

マッチデータ内でマッチしたテキストと位置にアクセスできるようにrxをマッチする。regexpの1つ目のグループは番号1、それ以降のグループはパターン内でそれ以前に最大の番号が付与されたグループより1つ大きい番号が付与される。
対応する文字列regexpは‘\(…\)’。

(group-n n rx…)
(submatch-n n rx…)

groupと同様だがグループ番号nを明示的に割り当てる。nは正でなければならない。
対応する文字列regexpは‘\(?n:…\)’。

(backref n)

前にグループ番号nでマッチされたテキストにマッチする。nは1から9の範囲になければならない。
対応する文字列regexpは‘\n’。

動的インクルージョン

(literal expr)

Lisp式exprを評価した結果であるリテラル文字列とマッチする。評価はカレントのレキシカル環境で呼び出し時に行われる。

(regexp expr)
(regex expr)

Lisp式exprを評価した結果であるregexpとマッチする。評価はカレントのレキシカル環境で呼び出し時に行われる。

(eval expr)

Lisp式exprを評価した結果であるrxとマッチする。評価はrx-to-string呼び出しの際のマクロ展開時に、カレントのグローバル環境で行われる。


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

35.3.3.2 rxのregexpを使用する関数とマクロ

Macro: rx rx-form…

rx-formがあたかも(seq …)フォームのbodyであるかのように文字列regexpに変換する。rxマクロは文字列定数、またはliteralregexpフォームが使用されていたら文字列に評価されるLisp式に展開される。たとえば:

(rx (+ alpha) "=" (+ digit))
  ⇒ "[[:alpha:]]+=[[:digit:]]+"
Function: rx-to-string rx-expr &optional no-group

rx-exprをリターンされる文字列regexpに変換する。no-groupが省略またはnilの場合には、後に付加する後置演算子が式全体に適用されるために、必要なら結果を非キャプチャリンググループ‘\(?:…\)’としてカッコで括る。たとえば:

(rx-to-string '(seq (+ alpha) "=" (+ digit)) t)
  ⇒ "[[:alpha:]]+=[[:digit:]]+"

rx-expr内のフォームliteralおよびregexpにたいする引数は、文字列リテラルでなければならない。

pcaseマクロはパターンとして直接rx式を使用できます。rx in pcaseを参照してください。

rx表記へのユーザー定義の拡張メカニズムについては、新たなrxフォームの定義を参照してください。


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

35.3.3.3 新たなrxフォームの定義

新たなシンボル他のrx式にたいしてパラメーター化されたフォームを定義することにより、rx表記を拡張できます。これにより手軽にパーツを複数のregexp間で共有して、より小さな断片を互いに組み合わせて、複雑なregexpをより簡単に構築、理解することができます。

たとえば(one-or-more letter)を意味するnameや、任意のxにたいして(seq ?' x ?')を意味する(quoted x)を定義できます。これらのフォームは他のrx式と同様に使用できます。(rx (quoted name))はシングルクォート内の非空の文字シーケンスにマッチするでしょう。

以下のLispマクロは定義にたいして名前を構築する別の手段を提供します。以下のルールはこれらすべてにたいして共通です:

  • digitgroupのようなビルトインのrxフォームは再定義不可。
  • 定義ははLisp変数のネームスペースから分離された、自身のネームスペース内でのみ有効。したがって名前に-regexpのようなサフィックスを付加する必要はない。これらが他と衝突することはあり得ない。
  • 直接か間接かを問わず、定義は自身を再帰的に参照できない。これを行う必要があることを見い出したなら、あなたが望むのは正規表現ではなくパーサーである。
  • 定義は定義マクロに存在するだけでは展開されず、rxrx-to-stringの呼び出し内でのみ展開される。これはたとえ定義が互いを参照している際でも定義の順序は問題ではなく、定義の構文エラーは定義時ではなく使用時のみ顕現することを意味する。
  • rx式が期待される任意の箇所でユーザー定義フォームが許される。たとえばzero-or-oneフォームのbody内では許されるが、anycategoryのフォーム内では許されない。これらはnotおよびintersectionのフォーム内でも許される。
Macro: rx-define name [arglist] rx-form

すべての後続するrxおよびrx-to-string呼び出しにおいて、グローバルにnameを定義する。arglistを省略すると、namerx-formで置き換えられるプレーンシンボルとして定義される。たとえば:

(rx-define haskell-comment (seq "--" (zero-or-more nonl)))
(rx haskell-comment)
     ⇒ "--.*"

arglistが与えられた場合には0個以上の引数名のリストでなければならず、その場合にはnameはパラメーター化されたフォームとして定義される。(name arg…)としてrx式内で使用時には、argはそれぞれrx-form内部の対応する引数名に置き換えられる。

arglist&restと残りのパラメーターを示す最後の引数名で終わる場合がある。残りのパラメーターはarglist内の他のパラメーターにマッチしないすべての追加引数の実際の値に展開されて、rx-formの出現箇所へとスプライスされる。たとえば:

(rx-define moan (x y &rest r) (seq x (one-or-more y) r "!"))
(rx (moan "MOO" "A" "MEE" "OW"))
     ⇒ "MOOA+MEEOW!"

定義はグローバルなので、nameには非ローカルな変数や関数を通常命名する際のように、別の場所の定義名との競合を避けるためにパッケージプレフィックスを付与することを推奨する。

この方法で定義したフォームは単純なテンプレート置換だけを行う。計算を任意で行うにはrxフォームのevalregexpliteralとともに使用すること。たとえば:

(defun n-tuple-rx (n element)
  `(seq "<"
        (group-n 1 ,element)
        ,@(mapcar (lambda (i) `(seq ?, (group-n ,i ,element)))
                  (number-sequence 2 n))
        ">"))
(rx-define n-tuple (n element) (eval (n-tuple-rx n 'element)))
(rx (n-tuple 3 (+ (in "0-9"))))
  ⇒ "<\\(?1:[0-9]+\\),\\(?2:[0-9]+\\),\\(?3:[0-9]+\\)>"
Macro: rx-let (bindings…) body…

body内のrxマクロ呼び出しでbindings内のrxをローカルに使用可能にしてから評価する。

bindingsの各要素は(name [arglistrx-form)という形式をもち、各パーツは上述のrx-defineの場合と同じ意味をもつ。たとえば:

(rx-let ((comma-separated (item) (seq item (0+ "," item)))
         (number (1+ digit))
         (numbers (comma-separated number)))
  (re-search-forward (rx "(" numbers ")")))

定義はbodyのマクロ展開の間だけ利用可能であり、したがってコンパイル済みコードの実行の間は存在しない。

rx-letは関数内部だけではなく、rxフォームの共通セットの共有を要するグローバルな変数および関数に含めるためにトップレベルでも使用できる。名前はbody内部でローカルなので、何のパッケージプレフィックスも必要としない。たとえば:

(rx-let ((phone-number (seq (opt ?+) (1+ (any digit ?-)))))
  (defun find-next-phone-number ()
    (re-search-forward (rx phone-number)))
  (defun phone-number-p (string)
    (string-match-p (rx bos phone-number eos) string)))

rx-letのスコープはレキシカルであり、これはたとえbodyから呼び出される関数であってみ、body自身の外部からは不可視であることを意味する。

Macro: rx-let-eval bindings body…

rx-letのようにbindingsをバインディングのリストに評価して、rx-to-string呼び出しに有効なこれらバインディングによってbodyを評価する。

このマクロはrx-letと同様だが、bindingsを評価して(したがってリストリテラルならクォート要)、定義が実行時(rx-to-stringが機能するために必要)に置換される点が異なる。たとえば:

(rx-let-eval
    '((ponder (x) (seq "Where have all the " x " gone?")))
  (looking-at (rx-to-string
               '(ponder (or "flowers" "young girls"
                            "left socks")))))

他にrx-letと異なるのは、bindingsはダイナミックにスコープされるので、bodyから呼び出される関数内でも利用可能なことである。しかしbody内で定義される関数の内部では不可視。


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

35.3.4 正規表現の関数

以下の関数は正規表現を扱います。

Function: regexp-quote string

この関数はstringだけに正確にマッチするような正規表現をリターンする。looking-at内でこの正規表現を使用すると、そのバッファー内の次の文字がstringのときだけ成功するだろう。検索関数でのこの正規表現の使用は、検索されるテキストがstringを含むなら成功するだろう。正規表現の検索を参照のこと。

これにより、その正規表現を求める関数呼び出し時に正確な文字列マッチや検索を要求できる。

(regexp-quote "^The cat$")
     ⇒ "\\^The cat\\$"

正規表現として記述されたコンテキストにおいて、正確な文字列マッチを結合することがregexp-quoteの1つの使い方である。たとえば以下は空白文で囲まれたstringの値であるような文字列を検索する:

(re-search-forward
 (concat "\\s-" (regexp-quote string) "\\s-"))

スペシャル文字を何も含まなければ、リターンされる文字列はstring自身となるだろう。

Function: regexp-opt strings &optional paren

この関数はリストstringsの文字列だけにマッチする効果的な正規表現をリターンする。これはマッチングや検索を可能な限り高速にする必要があるとき、たとえばFont Lockモードで有用である27

stringsが空リストなら、リターン値は何にもマッチすることはないregexpとなる。

オプション引数parenには以下のいずれかを指定できる:

文字列

結果となるregexpの前にparen、後に‘\)’が付加される。たとえば‘"\\(?1:"’を使用すると番号付きのグループを明示的に生成する。

words

結果となるregexpは‘\<\(’と‘\)\>’で括られる。

symbols

結果となるregexpは‘\_<\(’と‘\)\_>’で括られる(これはプログラミング言語のキーワードの類のマッチング時にしばしば適している)。

nil

結果となるregexpは‘\(’と‘\)’で括られる。

nil

後に付加する後置演算子が式全体に適用されるために必要なら、結果となるregexpは‘\(?:’と‘\)’で括られる。

リターンされるregexpは可能な最長文字列に常にマッチする方法の順序に整列される。

再整列されるまでregexp-optの結果regexpはその単純化されたバージョンと等価だが、通常はより効果的である。

(defun simplified-regexp-opt (strings &optional paren)
 (let ((parens
        (cond
         ((stringp paren)       (cons paren "\\)"))
         ((eq paren 'words)    '("\\<\\(" . "\\)\\>"))
         ((eq paren 'symbols) '("\\_<\\(" . "\\)\\_>"))
         ((null paren)          '("\\(?:" . "\\)"))
         (t                       '("\\(" . "\\)")))))
   (concat (car parens)
           (mapconcat 'regexp-quote strings "\\|")
           (cdr parens))))
Function: regexp-opt-depth regexp

この関数はregexp内のグループ化された構成要素(カッコで囲まれた正規表現)の総数をリターンする。これには内気なグループは含まれない(正規表現内のバッククラッシュ構文を参照)。

Function: regexp-opt-charset chars

この関数は文字リストchars内の文字にマッチする正規表現をリターンする。

(regexp-opt-charset '(?a ?b ?c ?d ?e))
     ⇒ "[a-e]"
Variable: regexp-unmatchable

この変数はすべての文字列にマッチしないことが保証されたregexpを含む。これは実際に何かとマッチするようにセットされ得る変数用のデフォルト値として特に有用。


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

35.3.5 正規表現にまつわるトラブル

Emacsのregexp実装は他の多くの類似する実装と同じように概ね堅牢ですが、2つの問題のいずれかを引き起こすことがあります。それはマッチングが内部スタックスペースを使い果たしてエラーをシグナルしたり、完了まで長時間を要するかもしれないという問題です。以下のアドバイスはこれらの症状を軽減して、発生する問題を緩和する助けとなるでしょう。

  • ゼロ幅アサーション(‘^’および\`)の使用による行、文字列、あるいはバッファー先頭のアンカーregexp。これは実装内部の高速パスを利用して、無駄なマッチングの試行を回避できる。これら以外のゼロ幅アサーションでも、早期にマッチを失敗させることによる利益が得られるかもしれない。
  • orパターンを避けて文字候補を使う(‘a\|b’のかわりに‘[ab]’と記述する)。‘\s-’および‘\sw’はそれぞれ‘[[:space:]]’および‘[[:word:]]’と等価であることを思い出してほしい。
  • orパターン最後の分岐はバックトラックポイントをスタックに追加しないので、もっともマッチしそうなパターンを最後に配置するよう検討する。たとえば‘^\(?:a\|.b\)*c’は‘a’からなる非常に長い文字列へのマッチを試みるとスタックを使い果たすだろうが、これと等価な‘^\(?:.b\|a\)*c’ならそのようなことはない。

    (これはトレードオフである。マッチに成功するorパターンは、もっとも頻繁にマッチするパターンを最初にすると実行が高速になる。)

  • テキストの任意の部分がただ1つの方法でのみマッチするよう試みる。たとえば‘a*a*’は同じ文字列セット‘a*’にマッチするだろうが、前者は多くの方法でマッチを行うので、そのマッチが後で失敗すると低速なバックトラッキングを引き起こすだろう。可能ならorパターンの分岐を互いに排他にすることによって、そのマッチが失敗する前に2つ以上先の分岐には進まなくなる。

    ネストした繰り返しには特に注意。曖昧さが存在すると、それらのマッチングが非常に低速になるのは容易である。たとえば‘\(?:a*b*\)+c’は‘a’からなる適切な長さの文字列にたいするマッチ試行でも、失敗までに長時間を要するだろう。これと等価な‘\(?:a\|b\)*c’はより高速であり、‘[ab]*c’は更に良い。

  • 本当に必要でないならキャプチャリングを使用しない。つまりカッコで括るのが目的なら‘\(…\)’のかわりに‘\(?:…\)’を使用する。
  • rxの使用を検討する(rx構造化Rgexp表記を参照)。これはいくつかのorパターンを自動的に最適化するとともに、明示的に要求されなければキャプチャリンググループを決して導入しない。

上記アドバイスにしたがってなおregexpがスタックオーバーフローするようなら、ためらうことなくマッチングを複数の関数呼び出しで行い、それぞれの関数呼び出しではバックトラッキングが容易に含まれるように単純なregexpを使ってください。


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

35.5 POSIX正規表現の検索

通常の正規表現関数は、‘\|’や繰り返しの構文要素を処理するために必要なときだけバックトラッキングを行いますが、何らかのマッチが見つかるまでの間だけこれを継続します。そして成功した後に見つかった最初のマッチを報告します。

このセクションでは正規表現にたいしてPOSIX標準で指定された完全なバックトラッキングを処理する他の検索関数を説明します。これらはPOSIXが要求する最長マッチを報告できるようにすべての可能なマッチを試みて、すべてのマッチが見つかるまでバックトラッキングを継続します。これは非常に低速なので、本当に最長マッチが必要なときだけこれらの関数を使用してください。

POSIXの検索とマッチ関数は、非欲張りな繰り返し演算子(non-greedyを参照)を正しくサポートしません。これはPOSIXのバックトラッキングが非欲張りな繰り返しのセマンチックと競合するからです。

Command: posix-search-forward regexp &optional limit noerror count

これはre-search-forwardと似ているが、正規表現マッチングにたいしてPOSIX標準が指定する完全なバックトラッキングを行う点が異なる。

Command: posix-search-backward regexp &optional limit noerror count

これはre-search-backwardと似ているが、正規表現マッチングにたいしてPOSIX標準が指定する完全なバックトラッキングを行う点が異なる。

Function: posix-looking-at regexp &optional inhibit-modify

これはlooking-atと似ているが、正規表現マッチングにたいしてPOSIX標準が指定する完全なバックトラッキングを行う点が異なる。

Function: posix-string-match regexp string &optional start inhibit-modify

これはstring-matchと似ているが、正規表現にたいしてPOSIX標準が指定する完全なバックトラッキングを行う点が異なる。


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

35.6 マッチデータ

Emacsは検索の間に見つかったテキスト片の開始と終了の位置を追跡します。これはマッチデータ(match data)と呼ばれます。このマッチデータのおかげで、メールメッセージ内のデータのような複雑なパターンを検索した後に、そのパターンの制御下でマッチ部分を抽出できるのです。

マッチデータには通常はもっとも最近の検索だけが記述されるので、後で参照したい検索とそのマッチデータの使用の間に誤って別の検索を行わないように注意しなければなりません。誤って別の検索を避けるのが不可能な場合には、マッチデータの上書きを防ぐために前後でマッチデータの保存とリストアを行わなければなりません。

上書きを行わないと明記されていない限り、すべての関数は上書きを許されていることに注意してください。結果としてバックグラウンド(遅延実行のためのタイマーアイドルタイマーを参照)で暗黙に実行される関数は、おそらく明示的にマッチデータの保存とリストアを行うべきでしょう。


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

35.6.1 マッチしたテキストの置換

以下の関数は、最後の検索でマッチされたテキストのすべて、または一部を置換します。これはマッチデータにより機能します。

Function: replace-match replacement &optional fixedcase literal string subexp

この関数はバッファーや文字列にたいして置換処理を行う。

あるバッファーで最後の検索を行った場合には、string引数を省略またはnilを指定すること。また最後に検索を行ったバッファーがカレントバッファーであることを確認すること。その場合には、この関数はマッチしたテキストをreplacementで置換することにより、そのバッファーを編集する。これは置換したテキスト終端にポイントを残す。

文字列にたいして最後の検索を行った場合には、同じ文字列がstringに渡される。その場合には、この関数はマッチしたテキストがreplacementに置き換えられた新たなテキストをリターンする。

fixedcaseが非nilならreplace-matchは大文字小文字を変更せずに置換テキストを使用して、それ以外は置換されるテキストがcapitalize(先頭が大文字)されているかどうかに応じて、置換テキストを変換する。元のテキストがすべて大文字なら置換テキストを大文字に変換する。元のテキストの単語すべてがcapitalizeされていたら置換テキストのすべての単語をcapitalizeする。すべての単語が1文字かつ大文字なら、それらはすべて大文字の単語ではなくcapitalizeされた単語として扱われる。

literalが非nilならreplacementはそのまま挿入されるが、必要に応じてcaseの変更だけが行われる。これがnil(デフォルト)なら文字‘\’は特別に扱われる。replacement内に‘\’が出現した場合には、それは以下のシーケンスのいずれかの一部でなければならない:

\&

これは置換されるテキスト全体を意味する。

\n’ (nは数字)

これは元のregexpのn番目の部分式にマッチするテキストを意味する。この部分式とは‘\(…\)’の内部にグループかされた式のこと。n番目のマッチがなければ空文字列が代用される。

\\

これは置換テキスト内で単一の‘\’を意味する。

\?

これはそれ自身を意味する(replace-regexpと関連するコマンドの互換用。Regexp Replace in The GNU Emacs Manualを参照)。

これら以外の‘\’に続く文字はエラーをシグナルする。

\&’や‘\n’により行われる代替えは、もしあればcase変換の後に発生する。したがって代替えする文字列は決してcase変換されない。

subexpが非nilなら、それは全体のマッチではなくマッチされたregexpの部分式番号subexpだけを置換することを指定する。たとえば‘foo \(ba*r\)’のマッチング後にreplace-matchを呼び出すと、subexpが1なら‘\(ba*r\)’にマッチしたテキストだけを置換することを意味する。

Function: match-substitute-replacement replacement &optional fixedcase literal string subexp

この関数はreplace-matchによりバッファーに挿入されるであろうテキストをリターンするがバッファーを変更しない。これは‘\n’や‘\&’のような構文要素をマッチしたグループで置き換えた実際の結果をユーザーに示したいとき有用。引数replacement、およびオプションのfixedcaseliteralstringsubexpreplace-matchのときと同じ意味をもつ。


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

35.6.2 単純なマッチデータへのアクセス

このセクションでは最後の検索やマッチング操作で、それが成功した場合に何がマッチされたのかを調べるために、マッチデータを使用する方法について説明します。

マッチしたテキスト全体または正規表現のカッコで括られた特定の部分式にたいして問い合わせることができます。以下の関数では、countによりどの部分式かを指定できます。countが0ならマッチ全体、countが正なら望む部分式を指定します。

正規表現での部分式とは、エスケープされたカッコ‘\(…\)’でグループ化された表現だったことを思い出してください。count番目の部分式は正規表現全体の先頭から‘\(’を数えることで見つけられます。最初の部分式が1、2つ目が2、...となります。正規表現だけが部分式をもつことができ、単純な文字列検索の後で利用できるのはマッチ全体の情報だけです。

成功したすべての検索はマッチデータをセットします。したがって検索後は別の検索を行うかもしれない関数を呼び出す前に、検索の直後にマッチデータを問い合わせるべきです。別の検索を呼び出すかもしれない関数の前後で、かわりにマッチデータの保存とリストアすることもできます(マッチデータの保存とリストアを参照)。またはstring-match-pのようなマッチデータを変更しないと明示されている関数を使用してください。

検索が成功しようと失敗しようとマッチデータは変更されます。現在はこのように実装されていますが、これは将来変更されるかもしれません。失敗した後のマッチデータを信用しないでください。

Function: match-string count &optional in-string

この関数は最後の検索やマッチ処理でマッチしたテキストを文字列としてリターンする。これはcountが0ならテキスト全体、countが正ならcount番目のカッコで括られた部分式に対応する部分だけをリターンする。

そのような最後の処理が文字列にたいするstring-match呼び出しなら、引数in-stringには同じ文字列を渡すこと。バッファーの検索やマッチの後は、in-stringを省略するかnilを渡すこと。しかし最後に検索やマッチを行ったバッファーが、match-string呼び出し時にカレントバッファーであることを確認すること。このアドバイスにしたがわなければ誤った結果となるだろう。

countが範囲外、‘\|’選択肢内部の部分式が使用されない、または0回の繰り返しなら値はnil

Function: match-string-no-properties count &optional in-string

この関数はmatch-stringと似ているが結果がテキストプロパティをもたない点が異なる。

Function: match-beginning count

最後の正規表現検索がマッチを見つけたら、この関数はマッチしたテキストか部分式の開始位置をリターンする。

countが0なら値はマッチ全体の開始位置。それ以外ならcountは正規表現内の部分式を指定するので、この関数の値はその部分式にたいするマッチの開始位置。

使用されない、あるいは0回の繰り返しであるような‘\|’選択肢内部の部分式にたいしての値はnil

Function: match-end count

この関数はmatch-beginningと似ているがマッチの開始ではなく終了位置である点が異なる。

以下はマッチデータを使用する例です。コメントの数字はテキスト内での位置を示しています:

(string-match "\\(qu\\)\\(ick\\)"
              "The quick fox jumped quickly.")
              ;0123456789
     ⇒ 4

(match-string 0 "The quick fox jumped quickly.")
     ⇒ "quick"
(match-string 1 "The quick fox jumped quickly.")
     ⇒ "qu"
(match-string 2 "The quick fox jumped quickly.")
     ⇒ "ick"

(match-beginning 1)       ; qu’にたいするマッチ先頭の
     ⇒ 4                 ;   インデックスは4

(match-beginning 2)       ; ick’にたいするマッチ先頭の
     ⇒ 6                 ;   インデックスは6

(match-end 1)             ; qu’にたいするマッチ終端の
     ⇒ 6                 ;   インデックスは6

(match-end 2)             ; ick’にたいするマッチ終端の
     ⇒ 9                 ;   インデックスは9

別の例を以下に示します。ポイントは最初は行の先頭にあります。検索の後はポイントはスペースと単語‘in’の間にあります。マッチ全体の先頭はバッファーの9つ目の文字‘T’、1つ目の部分式にたいするマッチの先頭は13番目の文字‘c’です。

(list
  (re-search-forward "The \\(cat \\)")
  (match-beginning 0)
  (match-beginning 1))
    ⇒ (17 9 13)

---------- Buffer: foo ----------
I read "The cat ∗in the hat comes back" twice.
        ^   ^
        9  13
---------- Buffer: foo ----------

(この場合にはリターンされるインデックスはバッファー位置であり、バッファーの1つ目の文字を1と数える。)


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

35.6.3 マッチデータ全体へのアクセス

関数match-dataset-match-dataは、マッチデータ全体にたいして一度に読み取り、または書き込みを行います。

Function: match-data &optional integers reuse reseat

この関数は最後の検索によりマッチしたテキストのすべての情報を記録する位置(マーカーか整数)をリターンする。要素0は正規表現全体にたいするマッチの先頭の位置。要素1はその正規表現にたいするマッチの終端の位置。次の2つの要素は1つ目の部分式にたいするマッチの先頭と終了、...となる。一般的に要素番号 2n(match-beginning n)、要素番号 2n + 1 は(match-end n)に対応する。

すべての要素は通常はマーカーかnilだが、もしintegersが非nilならマーカーのかわりに整数を使用することを意味する(この場合にはマッチデータの完全なリストアを容易にするために、リストの最後の要素としてバッファー自身が追加される)。最後の検索がstring-matchにより文字列にたいして行われた場合には、マーカーは文字列の内部をポイントできないので常に整数が使用される。

reuseが非nilなら、それはリストであること。この場合には、match-dataはマッチデータをreuse内に格納する。つまりreuseは破壊的に変更される。reuseが正しい長さである必要はない。特定のマッチデータにたいして長さが十分でなければリストは拡張される。reuseが長過ぎる場合には、長さはそのままで使用しない要素にnilがセットされる。この機能にはガベージコレクションの必要頻度を減らす目的がある。

reseatが非nilなら、reuseリスト内のすべてのマーカーは存在しない場所を指すよう再設定される。

他の場合と同じように検索関数とその検索のマッチデータへのアクセスを意図するmatch-data呼び出しの間に介入するような検索があってはならない。

(match-data)
     ⇒  (#<marker at 9 in foo>
          #<marker at 17 in foo>
          #<marker at 13 in foo>
          #<marker at 17 in foo>)
Function: set-match-data match-list &optional reseat

この関数はmatch-listの要素からマッチデータをセットする。match-listは前のmatch-data呼び出しの値であるようなリストであること(正確には同じフォーマットなら他のものでも機能するだろう)。

match-listが存在しないバッファーを参照する場合でもエラーとはならない。これは無意味だが害のない方法でマッチデータをセットする。

reseatが非nilなら、リストmatch-list内のすべてのマーカーは存在しない場所を指すよう再設定される。

store-match-dataset-match-dataの半ば時代遅れなエイリアス。


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

35.6.4 マッチデータの保存とリストア

以前に行った検索にたいするマッチデータを後で使用するために保護する必要があるなら、検索を行うかもしれない関数の呼び出し時に呼び出しの前後でマッチデータの保存とリストアを行う必要があるでしょう。以下はマッチデータ保存に失敗した場合に発生する問題を示す例です:

(re-search-forward "The \\(cat \\)")
     ⇒ 48
(foo)                   ; fooが他の検索を行うと
(match-end 0)
     ⇒ 61              ; 結果は期待する48と異なる!

save-match-dataでマッチデータの保存とリストアができます:

Macro: save-match-data body…

このマクロはbodyを実行して、その前後のマッチデータの保存とリストアを行う。リターン値はbody内の最後のフォームの値。

set-match-datamatch-dataを一緒に使用して、save-match-dataの効果を模倣することができます。以下はその方法です:

(let ((data (match-data)))
  (unwind-protect
      …   ; 元のマッチデータを変更してもOK
    (set-match-data data)))

プロセスフィルター関数(プロセスのフィルター関数を参照)、およびプロセスセンチネル(センチネル: プロセス状態の変更の検知を参照)の実行時には、Emacsが自動的にマッチデータの保存とリストアを行います。


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

35.7 検索と置換

バッファーのある部分でregexpにたいするすべてのマッチを見つけてそれらを置換したい場合には、以下のようにre-search-forwardreplace-matchを使用して明示的なループを記述するのがもっともフレキシブルな方法です:

(while (re-search-forward "foo[ \t]+bar" nil t)
  (replace-match "foobar"))

replace-matchの説明はReplacing the Text that Matchedを参照してください。

特定のリージョンに置換を限定すれば、より便利かもしれません。関数replace-regexp-in-regionはこれを行います。

Function: replace-regexp-in-region regexp replacement &optional start end

この関数はバッファーのstartからendのテキストリージョンにあるすべてのregexpreplacementに置換する。startのデフォルトはポイント位置、endのデフォルトはバッファーのアクセス可能範囲の終端。regexpにたいする検索はcase(大文字小文字)を区別し、replacementは文字のcaseを変更せずに挿入される。replacement文字列にはreplace-matchで使用するような、同じ‘\’で始まる特殊要素を使用できる。この関数は置換した個数、regexpが見つからなければnilをリターンする。この関数はポイント位置を維持する。

(replace-regexp-in-region "foo[ \t]+bar" "foobar")
Function: replace-string-in-region string replacement &optional start end

この関数はreplace-regexp-in-regionと同様に機能するが、正規表現のかわりにリテラルのstringの検索と置換を行う。

Emacsには文字列内でマッチを置換する特別な関数もあります。

Function: replace-regexp-in-string regexp rep string &optional fixedcase literal subexp start

この関数はstringをコピーしてregexpにたいするマッチを検索、それらをrepに置き換える。これは変更されたコピーをリターンする。startが非nilならマッチにたいする検索はstring内のそのインデックスから開始されて、リターン値にはstringの最初のstart文字は含まれない。置き換え後の文字列全体を取得するには、stringの最初のstart文字とリターン値を結合すること。

この関数は置換を行うためにオプション引数fixedcaseliteralsubexpを渡してreplace-matchを使用する。

repは文字列のかわりに関数でもよい。この場合にはreplace-regexp-in-stringはそれぞれのマッチにたいして、そのテキストを単一の引数としてrepを呼び出す。これはrepがリターンする値を収集して、それを置換文字列としてreplace-matchに渡す。この時点でのマッチデータはstringの部分文字列にたいするregexpのマッチ結果。

Function: string-replace from-string to-string in-string

この関数はin-string内に出現するすべてのfrom-stringto-stringに置換して、その結果をリターンする。引数のいずれかを変更せずに、文字列定数が新たな文字列をリターンするかもしれない。case(大文字小文字)には意味があるが、テキストプロパティは無視する。

query-replaceの行に関するコマンドを記述したい場合には、perform-replaceを使用してこれを行うことができます。

Function: perform-replace from-string replacements query-flag regexp-flag delimited-flag &optional repeat-count map start end backward region-noncontiguous-p

これはquery-replaceおよび関連するコマンドの根幹となる関数である。これは位置startendの間にあるテキスト内に出現するfrom-stringの一部またはすべてを置換する。startnil (または省略)ならかわりにポイントを、endにはそのバッファーのアクセス可能範囲の終端が使用される(オピション引数backwardが非nilなら検索はendから後方に開始される)。

query-flagnilならすべてのマッチを置換する。それ以外なら、それぞれにたいしてユーザーにたいして何をすべきか問い合わせる。

regexp-flagが非nilならfrom-stringは正規表現、それ以外はリテラルとしてマッチしなければならない。delimited-flagが非nilなら単語境界に囲まれた置換だけが考慮される。

引数replacementsはマッチを何で置き換えるかを指定する。文字列ならその文字列を使用する。サイクル順に使用される文字列リストでもよい。

replacementsがコンスセル(function . data)なら、置換テキストを取得するためにそれぞれのマッチ後にfunctionを呼び出すことを意味する。この関数はdataとすでに置換された個数という、2つの引数で呼び出される。

repeat-countが非nilなら、それは整数であること。その場合にはサイクルを次に進める前に、replacementsリスト内の各文字列を何度使用するかを指定する。

from-stringが大文字アルファベットを含む場合には、perform-replacecase-fold-searchnilにバインドして大文字小文字を変換せずにreplacementsを使用する。

キーマップquery-replace-mapは通常は問い合わせにたいして可能なユーザー応答を定義する。引数mapが非nilなら、それはquery-replace-mapのかわりに使用するキーマップを指定する。

region-noncontiguous-pが非nilなら、startendの間のリージョンは非連続部分から構成されることを意味する。これのもっとも一般的な例は部分が開業文字で区切られた矩形リージョンである。

この関数はfrom-stringの次のマッチを検索するために2つの関数のうちいずれか1つを使用する。これらの関数は2つの変数replace-re-search-functionreplace-search-functionにより指定される。引数regexp-flagが非nilなら前者、nilなら後者が呼び出される。

Variable: query-replace-map

この変数はperform-replaceにたいする有効なユーザー応答を定義するスペシャルキーマップを保持して、コマンドはy-or-n-pmap-y-or-n-pと同様にそれを使用する。このマップは2つの点において普通のマップと異なる。

  • キーバインディングはコマンドではなく、このマップを使用する関数にとって意味のある単なるシンボルであること。
  • プレフィクスキーはサポートされない。各キーバインディングは単一イベントキーシーケンスでなければならない。この関数は入力を取得するために単一イベントを読み取って、それを“手動”で照合するのでread-key-sequenceを使用しないからである。

query-replace-mapにたいして意味をもつバインディングがあります。それらのうちいくつかはquery-replaceとその同族にたいしてのみ意味をもちます。

act

判断している対象にたいしてアクションを起こす(言い換えると“yes”)。

skip

この問いにたいしてアクションを起こさない(言い換えると“no”)。

exit

この問いにたいして“no”を答えて、さらに一連の問いすべてにたいして“no”が応答されたとみなして問い合わせをあきらめる。

exit-prefix

exitと似ているが、unread-command-eventsにたいして押下されたキーを追加する(その他のイベント入力の機能を参照)。

act-and-exit

この問いにたいして“yes”を答えて、さらに一連の問いすべてにたいして後続の問いに“no”が応答されるとみなして問い合わせをあきらめる。

act-and-show

この問いに“yes”を答えるが、結果を表示してまだ次の問いへ進まない。

automatic

これ以上のユーザーとの対話を行わず、この問いと後続の問いにたいして“yes”を答える。

backup

前に問い合わせた以前の場所に戻る。

undo

最後の置換をアンドゥして置換が行われた位置に戻る。

undo-all

すべての置換をアンドゥして最初に置換が行われた位置に戻る。

edit

この問いに対処するために、通常とられるアクションのかわりに再帰編集にエンターする。

edit-replacement

ミニバッファー内で、この問いにたいする置換を編集する。

delete-and-edit

検討中のテキストを削除して、それを置換するために再帰編集にエンターする。

recenter
scroll-up
scroll-down
scroll-other-window
scroll-other-window-down

指定されたウィンドウスクロール操作を行って同じ問いを再度尋ねる。この問いにはy-or-n-pと関連する関数だけが使用される。

quit

即座にquitを行う。この問いにはy-or-n-pと関連する関数だけが使用される。

help

ヘルプを表示して再度尋ねる。

Variable: multi-query-replace-map

この変数はマルチバッファー置換で有用な追加キーバインディングを提供することによりquery-replace-mapを拡張するキーマップを保持する。追加されるバインディングは以下のとおり:

automatic-all

残りすべてのバッファーにたいして、それ以上の対話をせずその問いと後続のすべての問いに“yes”を答える。

exit-current

この問いに“no”を答えてカレントバッファーにたいする一連の問いすべてをあきらめる。そしてシーケンス内の次のバッファーへ問いを継続する。

Variable: replace-search-function

この変数は置換する次の文字列を検索するためにperform-replaceが呼び出す関数を指定する。デフォルト値はsearch-forward。それ以外の値の場合にはsearch-forwardの最初の3つの引数を引数とする関数を指定すること(文字列の検索を参照)。

Variable: replace-re-search-function

この変数は置換する次のregexpを検索するためにperform-replaceが呼び出す関数を指定する。デフォルト値はre-search-forward。それ以外の値の場合にはre-search-forwardの最初の3つの引数を引数とする関数を指定すること(正規表現の検索を参照)。


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

35.8 編集で使用される標準的な正規表現

このセクションでは、編集において特定の目的のために使用される正規表現を保持するいくつかの変数を説明します。

User Option: page-delimiter

これはページを分割する行開始を記述する正規表現。デフォルト値は"^\014" ("^^L"または"^\C-l")。これはフォームフィード文字(改頁文字)で始まる行とマッチする。

以下の2つの正規表現が、常に行頭からマッチが始まる正規表現とみなすべきではありません。これらを‘^’にマッチするアンカーとして使用するべきではありません。ほとんどの場合では、パラグラフコマンドは行頭にたいしてのみマッチのチェックを行うので、これは‘^’が不要であることを意味します。非0の左マージンが存在する場合には、これらは左マージンの後から始まるマッチに適用されます。その場合には、‘^’は不適切でしょう。しかし左マージンを決して使用しないモードでは‘^’は無害でしょう。

User Option: paragraph-separate

これはパラグラフを分割する行の開始を認識する正規表現(これを変更する場合はparagraph-startも変更する必要があるかもしれない)。デフォルト値は"[ \t\f]*$"であり、これは(左マージン以降)すべてがスペース、タブ、フォームフィードで構成される行とマッチする。

User Option: paragraph-start

これはパラグラフを開始または分割する行の開始を認識する正規表現。デフォルト値は"\f\\|[ \t]*$"であり、これは(左マージン以降)すべてが空白文字で構成される行やフォームフィードで始まる行とマッチする。

User Option: sentence-end

nilなら、以降に続く空白文字を含めてセンテンスの終わりを記述する正規表現であること(これとは無関係にパラグラフ境界もセンテンスを終了させる)。

値がnil (デフォルト)なら、関数sentence-endがregexpを構築する。センテンス終端の認識に使用するregexpを得るために常に関数sentence-endを使用するべきなのはこれが理由。

Function: sentence-end

この関数は変数sentence-endが非nilならその値をリターンする。それ以外なら変数sentence-end-double-space (Definition of sentence-end-double-spaceを参照)、sentence-end-without-periodsentence-end-without-spaceにもとづくデフォルト値をリターンする。


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

36 構文テーブル

構文テーブル(syntax table)はバッファー内のそれぞれの文字にたいして構文的な役割を指定します。単語、シンボル、その他の構文要素の開始と終了の判定にこれを使用できます。この情報はFont Lockモード(Font Lockモードを参照)や、種々の複雑な移動コマンド(モーションを参照)を含む多くのEmacs機能により使用されます。


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

36.1 構文テーブルの概念

構文テーブルは、それぞれの文字の構文クラス(syntax class)やその他の構文的プロパティを照合するために使用できるデータ構造です。構文テーブルはテキストを横断したスキャンや移動のためにLispプログラムから使用されます。

構文テーブルは内部的には文字テーブルです(文字テーブルを参照)。インデックスcの要素はコードcの文字を記述します。値は該当する文字の構文を指定するコンスセルです。詳細は構文テーブルの内部を参照してください。しかし構文テーブルの内容を変更や確認するためにasetarefを使用するかわりに、通常は高レベルな関数char-syntaxmodify-syntax-entryを使用するべきです。これらについては構文テーブルの関数で説明します。

Function: syntax-table-p object

この関数はobjectが構文テーブルならtをリターンする。

バッファーはそれぞれ自身のメジャーモードをもち、それぞれのメジャーモードはさまざまな文字の構文クラスにたいして独自の考えをもっています。たとえばLisモードでは文字‘;’はコメントの開始ですが、Cモードでは命令文の終端になります。これらのバリエーションをサポートするために、構文テーブルはそれぞれのバッファーにたいしてローカルです。一般的に各メジャーモードは自身の構文テーブルをもち、そのモードを使用するすべてのバッファーにそれがインストールされます。たとえば変数emacs-lisp-mode-syntax-tableはEmacsのLispモードが使用する構文テーブル、c-mode-syntax-tableはCモードが使用する構文テーブルを保持します。あるメジャーモードの構文テーブルを変更すると、そのモードのバッファー、およびその後でそのモードに置かれるすべてのバッファーの構文も同様に変更されます。複数の類似するモードが1つの構文テーブルを共有することがときおりあります。構文テーブルをセットアップする方法の例はメジャーモードの例を参照してください。

別の構文テーブルから構文テールを継承(inherit)できます。これを親構文テーブル(parent syntax table)と呼びます。構文テーブルは、ある文字にたいして構文クラス“inherit”を与えることにより、構文クラスを未指定にしておくことができます。そのような文字は親構文テーブルが指定する構文クラスを取得します(構文クラスのテーブルを参照)。Emacsは標準構文テーブル(standard syntax table)を定義します。これはデフォルトとなる親構文テーブルであり、Fundamentalモードが使用する構文テーブルでもあります。

Function: standard-syntax-table

この関数は標準構文テーブルをリターンする。これはFundamentalモードが使用する構文テーブルである。

Emacs Lispリーダーは変更不可な独自のビルトイン構文ルールをもつので、構文テーブルは使用しません(いくつかのLispシステムはリード構文を再定義する手段を提供するが、わたしたちは単純化のためこの機能をEmacs Lisp外部に留める決定をした)。


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

36.2 構文記述子

構文クラス(syntax class)の文字は、その文字の構文的な役割を記述します。各構文テーブルは、それぞれの文字の構文クラスを指定します。ある構文テーブルでの文字のクラスと、別のテーブルにおけるその文字のクラスとの間に関連性がある必要はありません。

構文テーブルはそれぞれニーモニック文字(mnemonic character)により選別され、クラスを指定する必要がある際にはそのクラスの名前としての役割を果たします。この指定子文字(designator character)は通常はそのクラスに割当てられることが多々あります。しかしその指定子としての意味は不変であり、その文字がカレントでもつ構文とは独立しています。つまりカレント構文テーブルにおいて実際に文字‘\’が構文をもつかどうかに関係なく、指定子文字としての‘\’は常にエスケープ文字(escape character)を意味します。 構文クラスとそれらの指定子文字のリストは構文クラスのテーブルを参照してください。

構文記述子(syntax descriptor)とは文字の構文クラスと、その他の構文的なプロパティを記述するLisp文字列です。ある文字の構文を変更したい際には、関数modify-syntax-entryを呼び出して引数に構文記述子を渡すことにより行います(構文テーブルの関数を参照)。

構文記述子の1つ目の文字は構文クラスの指定子文字でなければなりません。2つ目の文字がもしあれば、マッチング文字を指定します(Lispでは‘(’にたいするマッチング文字は‘)’)。スペースはマッチング文字が存在しないことを指定します。その後に続く文字は追加の構文プロパティを指定します(構文フラグを参照)。

マッチング文字やフラグが必要なければ、(構文クラスを指定する)1つの文字だけで十分です。

たとえばCモードでの文字‘*’の構文記述子は". 23" (区切り記号、マッチング文字用スロットは未使用、コメント開始記号の2つ目の文字、コメント終了記号の1つ目の文字)、‘/’にたいするエントリーは‘. 14’ (区切り記号、マッチング文字用スロットは未使用、コメント開始記号の1つ目の文字、コメント終了記号の2つ目の文字)です。

Emacsは低レベルでの構文クラスを記述するために使用されるraw構文記述子(raw syntax descriptors)も定義しています。構文テーブルの内部を参照してください。


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

36.2.1 構文クラスのテーブル

以下は構文クラス、それらの指定子となる文字と意味、および使用例を示すテーブルです。

空白文字: ‘ ’か‘-

シンボルや単語を区別する文字。空白文字は通常は他の構文的な意義をもたず、複数の空白文字は構文的には単一の空白文字と等しい。スペース、タブ、フォームフィードは、ほとんどすべてのメジャーモードにおいて空白文字にクラス分けされる。

この構文クラスは‘ か‘-’により指定できる。両指定子は等価。

単語構成文字: ‘w

人間の言語における単語の一部。これらは通常はプログラム内において変数やコマンドの名前として使用される。すべての大文字と小文字、および数字は通常は単語構成文字。

シンボル構成文字: ‘_

単語構成文字とともに変数やコマンドの名前で使用される追加の文字。例としてはLispモードの文字‘$&*+-_<>’が含まれ、これらはたとえ英単語の一部ではないとしてもシンボルの名前の一部となり得る。標準Cではシンボル内において非単語構成文字で有効な文字はアンダースコア(‘_’)のみ。

区切り文字: ‘.

人間の言語において句読点として使用される文字、またはプログラミング言語でシンボルを別のシンボルと区別するために使用される文字。Emacs Lispモードのようないくつかのプログラミング言語のモードでは、単語構成文字およびシンボル構成文字のいずれでもないいくつかの文字はすべて他の用途をもつので、このクラスの文字をもたない。Cモードのような他のプログラミング言語のモードでは演算子にたいして区切り文字構文が使用される。

開カッコ文字: ‘(
閉カッコ文字: ‘)

文や式を囲うために異なるペアとして使用される文字。そのようなグループ化は開カッコで開始され、閉カッコで終了する。開カッコ文字はそれぞれ特定の閉カッコ文字にマッチして、その逆も成り立つ。Emacsは通常は閉カッコ挿入時にマッチする開カッコを示す。カッコの点滅を参照のこと。

人間の言語やCのコードでは、カッコのペアは‘()’、‘[]’、‘{}’。Emacs Lispではリストとベクターにたいする区切り文字(‘()’と‘[]’)はカッコ文字としてクラス分けされる。

文字列クォート: ‘"

文字列定数を区切るために使用される文字。文字列の先頭と終端に同じ文字列クォート文字が出現する。このようなクォート文字列はネストされない。

Emacsのパース機能は文字列を単一のトークンとみなす。文字列内ではその文字の通常の構文的な意味は抑制される。

Lispモードはダブルクォーテーション(‘"’)と垂直バー(‘|’)とう2つの文字列クォート文字をもつ。Emacs Lispでは‘|’は使用しないがCommon Lispでは使用される。Cも文字列にたいするダブルクォート文字、および文字定数にたいするシングルアポストロフィ(‘'’)という2つのクォート文字をもつ。

人間用のテキストには文字列クォート文字がない。そのクォーテーション内の別の文字の通常の構文的プロパティを、クォーテーションマークがオフに切り替えることを、わたしたちは望まない。

エスケープ構文文字: ‘\

文字列や文字定数内で使用されるようなエスケープシーケンスで始まる文字。CとLispの両方で文字‘\’はこのクラスに属する(Cでは文字列内でのみ使用されるが、Cコード中を通じてこのように扱っても問題ないことがわかった)。

words-include-escapesが非nilなら、このクラスの文字は単語の一部とみなされる。単語単位の移動を参照のこと。

文字クォート: ‘/

その文字の通常の構文的な意義を失うように、後続の文字をクォートするために使用される文字。これは直後に続く文字だけに影響する点がエスケープ文字と異なる。

words-include-escapesが非nilなら、このクラスの文字は単語の一部とみなされる。単語単位の移動を参照のこと。

このクラスはTeXモードのバックスラッシュにたいして使用される。

区切りペアー: ‘$

文字列クォート文字と似ているが、この区切りの間にある文字の構文的なプロパティは抑制されない点が異なる。現在のところTeXモードだけが区切りペアを使用する(‘$’によりmathモードに出入りする)。

式プレフィクス: ‘'

式に隣接して出現した場合には式の一部とみなされる構文的演算子にたいして使用される文字。Lispモードではアポストロフィー‘'’ (クォートに使用)、カンマ‘,’ (マクロに使用)、‘#’ (特定のデータ型にたいするリード構文として使用)が、これらの文字に含まれる。

コメント開始文字: ‘<
コメント終了文字: ‘>

さまざまな言語においてコメントを区切るために使用する文字。人間用のテキストはコメント文字をもたない。Lispではセミコロン(‘;’)がコメントの開始、改行かフォームフィードで終了する。

標準構文の継承: ‘@

この構文クラスは特定の構文を指定しない。これはその文字の構文を探すために親構文テーブルを照合するよう告げる。

汎用コメント区切り: ‘!

特殊なコメントを開始または終了させる文字(この構文クラスは“comment-fence”としても知られる)。任意の汎用コメント区切りは任意の汎用コメント区切りにマッチするが、コメント開始とコメント終了はマッチできない。汎用コメント区切りは汎用コメント区切り同士としかマッチできない。

この構文クラスは主としてsyntax-tableテキストプロパティ(構文プロパティを参照)とともに使用することを意図している。任意の文字範囲の最初と最後の文字にたいして、それらが汎用コメント区切りであることを示すsyntax-tableプロパティを付与することにより、その範囲がコメントを形成するとマークすることができる。

汎用文字列区切り: ‘|

文字列を開始や終了させる文字(この構文クラスは“string-fence”としても知られる)。任意の汎用文字列区切りは任意の汎用文字列区切りにマッチするが、通常の文字列クォート文字とはマッチできない。

この構文クラスは主としてsyntax-tableテキストプロパティ(構文プロパティを参照)とともに使用することを意図している。任意の文字範囲の最初と最後の文字にたいして、それらが汎用文字列区切りであることを示すsyntax-tableプロパティを付与することにより、その範囲が文字列定数を形成するとマークすることができる。


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

36.2.2 構文フラグ

構文テーブル内の文字全体にたいして構文クラスに加えてフラグを指定できます。利用できる8つのフラグがあり、それらは文字‘1’、‘2’、‘3’、‘4’、‘b’、‘c’、‘n’、‘p’で表されます。

p’を除くすべてのフラグはコメント区切りを記述するために使用されます。数字のフラグは2文字から構成されるコメント区切りにたいして使用されます。これらは文字の文字クラスに関連付けられた構文的プロパティに加えて、その文字も同様にコメントシーケンスの一部となれることを示します。Cモードでは区切り文字であり、かつコメントシーケンス開始(‘/*’)の2文字目であり、かつコメントシーケンス終了(‘*/’)の1文字目である‘*’のような文字のためにフラグとクラスは互いに独立しています。フラグ‘b’、‘c’、‘n’は対応するコメント区切りを限定するために使用されます。

以下は文字cにたいして利用できるフラグと意味を示すテーブルです:

  • 1’はcが2文字からなるコメント開始シーケンスの開始であることを意味する。
  • 2’はcがそのようなシーケンスの2文字目であることを意味する。
  • 3’はcが2文字からなるコメント終了シーケンスの開始であることを意味する。
  • 4’はcがそのようなシーケンスの2文字目であることを意味する。
  • b’はcが代替えのコメントスタイル“b”に属するコメント区切りであることを意味する。このフラグは2文字のコメント開始では2文字目、2文字のコメント終了では1文字目にたいしてのみ意味をもつ。
  • c’はcが代替えのコメントスタイル“c”に属するコメント区切りであることを意味する。2文字からなるコメント区切りにたいしては、そのいずれかが‘c’であればスタイル“c”となる。
  • コメント区切り文字での‘n’は、この種のコメントがネスト可能であることを指定する。このようなコメント内では、同じスタイルのコメントだけが認識される。2文字からなるコメント区切りにたいしては、そのいずれかが‘n’であればネスト可能となる。

    Emacsは任意の構文テーブル1つにたいして同時に複数のコメントスタイルをサポートする。コメントスタイルはフラグ‘b’、‘c’、‘n’の組み合わせで8個の異なるコメントスタイルが可能で、コメントスタイルはそれぞれフラグセットにより命名される。コメント区切りはそれぞれスタイルをもち、同じスタイルのコメント区切りとのみマッチできる。つまりコメントがスタイル“bn”のコメント開始シーケンスで開始されるなら、そのコメントは次のスタイル“bn”のコメント終了シーケンスにマッチするまで拡張されるだろう。フラグセットが‘b’と‘c’のいずれでもなければ、結果となるスタイルは“a”スタイルと呼ばれる。

    C++にたいして適切なコメント構文は以下のようになる:

    /

    124

    *

    23b

    newline

    >

    これは4つのコメント区切りシーケンスを定義する:

    /*

    これは2文字目の‘*’が‘b’フラグをもつので、“b”スタイルのコメント開始シーケンス。

    //

    これは2文字目の‘/’が‘b’フラグをもたないので、“a”スタイルのコメント開始シーケンス。

    */

    これは1文字目の‘*’が‘b’フラグをもつので、“b”スタイルのコメント終了シーケンス。

    newline

    これは改行文字が‘b’フラグをもたないので、“a”スタイルのコメント終了シーケンス。

  • p’はLisp構文にたいして追加のプレフィクス文字を識別する。これらが式の間に出現した際には空白文字として扱われる。これらが式の内部に出現したときは、それらの通常の構文クラスに応じて処理される。

    関数backward-prefix-charsはこれらの文字、同様にメインの構文クラスがプレフィクスであるような文字(‘'’)を超えて後方に移動する。モーションと構文を参照のこと。


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

36.3 構文テーブルの関数

このセクションでは構文テーブルの作成、アクセス、変更を行う関数を説明します。

Function: make-syntax-table &optional table

この関数は新たに構文テーブルを作成する。tableが非nilなら新たな構文テーブルの親はtable、それ以外なら標準構文テーブルが親になる。

新たな構文テーブルでは最初はすべての文字に構文クラス“inherit”(‘@’)が与えられて、それらの構文は親テーブルから継承される(構文クラスのテーブルを参照)。

Function: copy-syntax-table &optional table

この関数はtableのコピーを構築してそれをリターンする。tableが省略またはnilなら標準構文テーブルのコピーをリターンする。それ以外の場合には、tableが構文テーブルでなければエラーをシグナルする。

Command: modify-syntax-entry char syntax-descriptor &optional table

この関数はsyntax-descriptorに応じてcharの構文エントリーをセットする。charは文字、または(min . max)という形式のコンスセルでなければならない。後者の場合には、この関数はminmax (両端を含む)の間のすべての文字にたいして構文エントリーをセットする。

構文はtable (デフォルトはカレントバッファーの構文テーブル)にたいしてのみ変更されて、他のすべての構文テーブルにたいしては変更されない。

引数syntax-descriptorは構文記述子、すなわち1文字目が構文クラス指定子、2文字目以降がオプションでマッチング文字と構文フラグを指定する文字列。構文記述子を参照のこと。syntax-descriptorが有効な構文記述子でなければエラーがシグナルされる。

この関数は常にnilをリターンする。この文字にたいするテーブル内の古い構文情報は破棄される。

例:

;; 空白文字クラスのスペースをputする
(modify-syntax-entry ?\s " ")
     ⇒ nil

;; $’を開カッコ文字にして、
;;   ^’を対応する閉カッコにする
(modify-syntax-entry ?$ "(^")
     ⇒ nil

;; ^’を閉カッコ文字にして
;;   $’を対応する開カッコにする
(modify-syntax-entry ?^ ")$")
     ⇒ nil

;; /’を区切り文字で
;;   コメント開始シーケンス1文字目、
;;   かつコメント終了シーケンス2文字目とする
;;   これはCモードで使用される
(modify-syntax-entry ?/ ". 14")
     ⇒ nil
Function: char-syntax character

この関数は指定子文字(構文クラスのテーブルを参照)の表現でcharacterの構文クラスをリターンする。これはクラスだけをリターンして、マッチング文字や構文フラグはリターンしない。

以下の例はCモードにたいして適用する( char-syntaxがリターンする文字を確認しやすいようにstringを使用する)。

;; スペース文字は空白文字構文クラスをもつ
(string (char-syntax ?\s))
     ⇒ " "

;; スラッシュ文字は区切り文字構文をもつ。
;; コメント開始やコメント終了シーケンスの一部でもある場合、
;; char-syntax呼び出しはこれを明らかにしないことに注意。
(string (char-syntax ?/))
     ⇒ "."

;; 開カッコ文字は開カッコ構文をもつ。
;; これがマッチング文字‘)’をもつことは
;; char-syntax呼び出しでは自明ではないことに注意。
(string (char-syntax ?\())
     ⇒ "("
Function: set-syntax-table table

この関数はカレントバッファーの構文テーブルをtableにする。これはtableをリターンする。

Function: syntax-table

この関数はカレント構文テーブル(カレントバッファーのテーブル)をリターンする。

Command: describe-syntax &optional buffer

このコマンドはbuffer (デフォルトはカレントバッファー)の構文テーブルのコンテンツをhelpバッファーに表示する。

Macro: with-syntax-table table body…

このマクロはtableをカレント構文テーブルとして使用してbodyを実行する。これは古いカレント構文テーブルのリストア後にbodyの最後のフォームの値をリターンする。

各バッファーは独自にカレント構文テーブルをもつので、マクロはこれを入念に行うべきだろう。with-syntax-tableはマクロの実行開始時には、そのときカレントのバッファーが何であれカレント構文テーブルを一時的に変更する。他のバッファーは影響を受けない。


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

36.4 構文プロパティ

ある言語の構文を指定するのに構文テーブルが十分に柔軟でないときは、 バッファー内に出現する特定の文字にたいしてテキストプロパティsyntax-tableを適用することにより構文テーブルをオーバーライドできます。テキストプロパティを適用する方法についてはテキストのプロパティを参照してください。

以下はテキストプロパティsyntax-tableの有効な値です:

syntax-table

プロパティの値が構文テーブルなら、根底となるテキスト文字の構文を決定するカレントバッファーの構文テーブルのかわりにそのテーブルが使用される。

(syntax-code . matching-char)

この形式のコンスセルは根底となるテキスト文字の構文クラスを直接指定するraw構文テーブル(構文テーブルの内部を参照)。

nil

このプロパティがnilなら、その文字の構文はカレント構文テーブルにより通常の方法で決定される。

Variable: parse-sexp-lookup-properties

これが非nilなら、forward-sexpのような構文をスキャンする関数はsyntax-tableテキストプロパティを考慮し、それ以外ならカレント構文テーブルだけを使用する。

Variable: syntax-propertize-function

この変数が非nilなら特定のテキスト範囲にたいしてsyntax-tableプロパティを適用する関数を格納すること。これはモードに適した方法でsyntax-tableプロパティを適用する関数をインストールするようにメジャーモードで使用されることを意図している。

この関数はsyntax-ppss (ある位置のパース状態を調べるを参照)、および構文フォント表示化(構文的なFont Lockを参照)の間にFont Lockモードにより呼び出される。これは作用すべきテキスト部分の開始startと終了endという2つの引数で呼び出される。startendで区切られたリージョン内でポイントを任意に移動でき、そのような移動にsave-excursion (エクスカーションを参照)を使う必要はない。endの前の任意の位置でsyntax-ppssを呼び出すこともできるが、Lispプログラムがどこかでsyntax-ppssを呼び出して、その後にそこより前の位置でバッファーを変更する場合には、もはや古くなってしまった情報をキャッシュからフラッシュするためにsyntax-ppss-flush-cacheを呼び出すのは、そのプログラムの責任である。

警告: この変数が非nilなら、Emacsはsyntax-tableテキストプロパティを任意に削除して、それらの再適用はsyntax-propertize-functionに依存する。つまりこの機能が使用される場合には、関数はメジャーモードが使用するすべてsyntax-tableテキストプロパティを適用しなければならない。特にCCモードはこれらのテキストプロパティの削除と適用に別の手段を使用するので、CCモードから派生したモードはこの変数を使用してはならない。

Variable: syntax-propertize-extend-region-functions

このアブノーマルフックはsyntax-propertize-function呼び出しに先立ち構文解析コードにより実行される。これはsyntax-propertize-functionに渡すために安全なバッファーの開始と終了の位置を見つける助けをする役割をもつ。たとえばメジャーモードは複数行の構文構成を識別して、境界が複数行の中間にならないようにこのフックに関数を追加できる。

このフック内の各関数は引数startendを受け取ること。これは2つのバッファー位置を調整するコンスセル(new-start . new-end)、調整が必要なければnilをリターンするべきである。フック関数はそれらすべてがnilをリターンするまで順番に繰り返し実行される。


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

36.5 モーションと構文

このセクションでは、特定の構文クラスをもつ文字間を横断して移動する関数を説明します。

Function: skip-syntax-forward syntaxes &optional limit

この関数はsyntaxesで指定された構文クラス(構文クラスの文字列)をもつ文字を横断してポイントを前方に移動する。バッファー終端か、(与えられた場合は)位置limitに到達、もしくはスキップしない文字に達した際に停止する。

syntaxesが‘^’で始まる場合には、この関数は構文がsyntaxesではない文字をスキップする。

リターン値は移動した距離を表す非負の整数。

Function: skip-syntax-backward syntaxes &optional limit

この関数はsyntaxesで指定された構文クラスをもつ文字を横断してポイントを後方に移動する。バッファー先頭か、(与えられた場合は)位置limitに到達、もしくはスキップしない文字に達した際に停止する。

syntaxesが‘^’で始まる場合には、この関数は構文がsyntaxesではない文字をスキップする。

リターン値は移動した距離を表す0以下の整数。

Function: backward-prefix-chars

この関数は式プレフィクス構文の任意個数の文字を横断して後方にポイントを移動する。これには式プレフィクス構文クラスとフラグ‘p’の文字の両方が含まれる。


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

36.6 式のパース

このセクションでは釣り合いのとれた式の解析やスキャンを行う関数を説明します。たとえこれらの関数がLisp以外の言語にたいして作用可能であったとしても、Lisp用語にしたがってそのような式のことをsexpsという用語で参照することにします。基本的にsexpはバランスのとれたカッコによるグループ化、または文字列、シンボル(構文が単語構成要素かシンボル構成要素である文字シーケンス)のいずれかです。しかし式プレフィクス構文(構文クラスのテーブルを参照)の文字は、それらがsexpに隣接する場合にはsexpの一部として扱われます。

構文テーブルは文字の解釈を制御するので、これらの関数はLispモードでのLisp式、CモードでのCの式にたいして使用できます。釣り合いのとれた式にたいして有用な高レベル関数については釣り合いのとれたカッコを越えた移動を参照してください。

ある文字の構文はパーサー自身の状態の記述ではなくパーサー状態の変更方法を制御します。たとえば文字列区切り文字はin-stringとin-codeの間でパーサー状態をトグルしますが、文字の構文が直接文字列内部にあるかどうかを告げることはありません。たとえば(15は汎用文字列区切りの構文コードであることに注意)、

(put-text-property 1 9 'syntax-table '(15 . nil))

これはEmacsにたいしてカレントバッファーの最初の8文字が文字列であることを告げますが、それらはすべて文字列区切りです。結果としてEmacsはそれらを連続する4つの空文字列定数として扱います。


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

36.6.1 パースにもとづくモーションコマンド

このセクションでは式のパースにもとづいて処理を行うシンプルなポイント移動関数を説明します。

Function: scan-lists from count depth

この関数は位置fromから釣り合いのとれたカッコのグループを前方にcount個スキャンする。これはスキャンが停止した位置をリターンする。countが負ならスキャンは後方に移動する。

depthが非0なら開始位置のカッコのネスト深さをdepthとして扱う。スキャナーはネスト深さが0になるまで繰り返してcount回、前方か後方に移動する。そのため正のdepthは開始位置からカッコをdepthレベル抜け出して移動する効果があり、負のdepthはカッコがdepthレベル深くなるよう移動する効果をもつ。

parse-sexp-ignore-commentsが非nilならスキャンはコメントを無視する。

count個のカッコのグループをスキャンする前にスキャンがバッファーのアクセス可能範囲の先頭か終端に達した場合には、そのポイントのネスト深さが0なら値nilをリターンする。ネスト深さが非0ならscan-errorエラーをシグナルする。

Function: scan-sexps from count

この関数は位置fromからcount個のsexpを前方にスキャンする。これはスキャンが停止した位置をリターンする。countが負ならスキャンは後方へ移動する。

parse-sexp-ignore-commentsが非nilならスキャンはコメントを無視する。

カッコのグループの中間でバッファー(のアクセス可能範囲)の先頭か終端に達したらエラーをシグナルする。count個を消費する前にカッコのグループの間でバッファーの先頭か終端に達したらnilをリターンする。

Function: forward-comment count

この関数はcount個の完全なコメント(すなわち、もしあれば開始区切りと終了区切りを含む)、および途中で遭遇する任意の空白文字を横断してポイントを前方に移動する。countが負なら後方に移動する。コメントまたは空白文字以外のものに遭遇したら停止して停止位置にポイントを残す。これには、(たとえば)前方に移動してコメント開始を調べる際にコメント終了を探すことも含まれる。この関数は指定された個数の完全なコメントを横断して移動した後にも即座に停止する。空白以外のものがコメント間に存在せずに期待どおりcount個のコメントが見つかったらt、それ以外はnilをリターンする。

この関数はコメントを横断する際に、それが文字列内に埋め込まれているかどうか区別できない。それらがコメントのように見えればコメントとして扱われる。

ポイントの後のすべてのコメントと空白文字を飛び越して移動するには(forward-comment (buffer-size))を使用する。バッファー内のコメント数は(buffer-size)を超えることはできないので、これは引数としての使用に適している。


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

36.6.2 ある位置のパース状態を調べる

インデントのような構文分析にとっては、与えられたバッファー位置に応じた構文状態の計算が有用なことが多々あります。それを手軽に行うのが以下の関数です。

Function: syntax-ppss &optional pos

この関数はパーサーがバッファーの可視範囲の先頭から開始して位置posで停止するだろうというパーサー状態をリターンする。 パーサー状態の説明はパーサー状態を参照のこと 。

リターン値はバッファーの可視範囲の先頭からposまでパースするために低レベル関数parse-partial-sexp (低レベルのパースを参照)を呼び出した場合と同じようになる。しかしsyntax-ppssは計算速度向上のためにキャッシュを使用する。この最適化のために、リターンされるパーサー状態のうち2つ目の値(前の完全な部分式)と6つ目の値(最小のカッコ深さ)は意味をもたない。

この関数はsyntax-ppss-flush-cache (以下参照)にたいして、before-change-functions (フックの変更を参照)にバッファーローカルなエントリーを追加するという副作用をもつ。このエントリーはバッファー変更にたいしてキャッシュの一貫性を保つ。とはいえbefore-change-functionsが一時的にletでバインドされている間にsyntax-ppssが呼び出された場合、またはinhibit-modification-hooks使用時のようにバッファーがフックを実行せずに変更される場合にはキャッシュは更新されないかもしれない。そのような場合には明示的にsyntax-ppss-flush-cacheを呼び出す必要がある。

Function: syntax-ppss-flush-cache beg &rest ignored-args

この関数はsyntax-ppssが使用するキャッシュを位置begからフラッシュする。残りの引数ignored-argsは無視される。before-change-functions (フックの変更を参照)のような関数で直接使用できるように、この関数はそれらの引数を受け入れる。


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

36.6.3 パーサー状態

パーサー状態(parser state)とはparse-partial-sexp (低レベルのパースを参照)を使用してバッファー内の指定された開始位置と終了位置の間のテキストをパースした後の構文パーサーの状態を記述する(現在のところは)11要素のリストです。syntax-ppssのようなパース関数 (ある位置のパース状態を調べるを参照) も値としてパーサー状態をリターンします。 parse-partial-sexp can はパースを再開するために引数としてパーサー状態を受け取ります。

以下はパーサー状態の要素の意味です:

  1. 0から数えたカッコの深さ。警告: パーサーの開始位置と終了位置の間に開カッコより多くの閉カッコがあれば負になることもある。
  2. 停止位置を含む最内のカッコグループの開始文字位置。なければnil
  3. 最後の終端された完全な部分式の開始文字位置。なければnil
  4. 文字列内部なら非nil。より正確には文字列を終端させるであろう文字、または汎用文字列区切りが終端すべきような場合にはt
  5. ネスト不可なコメント(または任意のコメントスタイル。構文フラグを参照)の内部ならt、ネスト可なコメントの内部ならコメントのネストレベル。
  6. 終了位置がクォート文字直後ならt
  7. 当該スキャン中に遭遇した最小のカッコ深さ。
  8. アクティブなコメントの種類。コメント以外、またはスタイル‘a’のコメント内ならnil、スタイル‘b’のコメントなら1、スタイル‘c’のコメントなら2、汎用コメント区切り文字で終端されるべきコメントならsyntax-table
  9. 文字列やコメントの開始位置。コメント内部ならコメントが始まる位置。文字列内部なら文字列が始まる位置。文字列やコメントの外部ならこの要素はnil
  10. もっとも外側のカッコから始まる開きカッコのカレント位置のリスト。
  11. スキャンされた最後のバッファー位置が(潜在的に)2文字構文(コメント区切りやエスケープされた文字とクォートされた文字のペア)の最初の文字ならその位置のsyntax-code (構文テーブルの内部を参照)、それ以外ならnil

パース継続のための引数としてparse-partial-sexpに渡す場合には要素1、2、6は無視されます。要素9と10は主にパーサーコードにより内部的に使用されます。

以下の関数を使用することにより追加でパーサー状態からいくつかの有用な情報を利用できます:

Function: syntax-ppss-toplevel-pos state

この関数はパーサー状態stateから文法構造上トップレベルでのパースでのスキャンした最後の位置をリターンする。“トップレベル”とはすべてのカッコ、コメント、文字列の外部であることを意味する。

stateがトップレベルの位置に到達したパースを表す場合には値はnil

Function: syntax-ppss-context state

stateをリターンするスキャン終了位置が文字列内にあればstring、コメント内にあればcomment、それ以外はnilをリターンする。


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

36.6.4 低レベルのパース

式パーサーを使用するもっとも基本的な方法は特定の状態で与えられた位置からパースを開始して、指定した位置でパースを終了するよう指示する方法です。

Function: parse-partial-sexp start limit &optional target-depth stop-before state stop-comment

この関数はカレントバッファー内のsexpを、startから開始してlimitを超えてスキャンしないようパースを行う。これは位置limit、または以下に記述する特定の条件に適合したら停止してパースが停止した位置にポイントをセットする。これはポイントが停止した位置でのパースの状態を記述するパーサー状態 をリターンする。

3つ目の引数target-depthが非nilの場合には、カッコの深さがtarget-depthと等しくなったらパースを停止する。この深さは0、またはstate内で与えられる深さなら何であれそこから開始される。

4つ目の引数stop-beforeが非nilの場合には、sexp開始となる任意の文字に到達したときにパースは停止する。stop-commentが非nilならネストされていないコメントの開始の後にパースは停止する。stop-commentがシンボルsyntax-tableならネストされていないコメントか文字列の開始の後、またはネストされていないコメントか文字列の終了のいずれか先に到達した方でパースは停止する。

statenilなら、startは関数定義先頭のようなカッコ構造のトップレベルであるとみなされる。かわりにこの構造の中間でパースを再開したいと思うかもしれない。これを行うにはパースの初期状態を記述するstate引数を提供しなければならない。前のparse-partial-sexp呼び出しでリターンされた値で、これをうまく行うことができるだろう。


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

36.6.5 パースを制御するためのパラメーター

Variable: multibyte-syntax-as-symbol

この変数が非nilなら構文テーブルがそれらについて何と言っているかに関わらず、scan-sexpsはすべての非ASCII文字をシンボル構成要素として扱う(とはいえ依然としてsyntax-tableテキストプロパティは構文をオーバーラードできる)。

User Option: parse-sexp-ignore-comments

この値が非nilならこのセクション内の関数、およびforward-sexpscan-listsscan-sexpsはコメントを空白文字として扱う。

parse-partial-sexpの振る舞いもparse-sexp-lookup-propertiesの影響を受けます(構文プロパティを参照)。

Variable: comment-end-can-be-escaped

このバッファーローカル変数が非nilなら、通常ならコメントを終端するような単一の文字は、エスケープ時にはコメントを終端しない。これはCとC++のモードにおいて‘\’でエスケープされた改行により、‘//’で開始される行コメントを次行に継続させるために使用される。

1つ、または複数のコメントを横断して前方や後方に移動するにはforward-commentを使用できます。


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

36.7 構文テーブルの内部

構文テーブルは文字テーブル(文字テーブルを参照)として実装されていますが、ほとんどのLispプログラムが直接それらの要素に作用することはありません。構文テーブルは構文データとして構文記述子を格納しません(構文記述子を参照)。それらは内部的なフォーマットを使用しており、それについてはこのセクションで説明します。この内部的フォーマットは構文プロパティとして割り当てることもできます(構文プロパティを参照)。

構文テーブル内の各要素はraw構文記述子(raw syntax descriptor)という(syntax-code . matching-char)という形式のコンスセルです。syntax-codeは下記のテーブルに応じて構文クラスと構文フラグをエンコードする整数です。matching-charが非nilなら、それはマッチング文字(構文記述子内の2つ目の文字と同様)を指定します。

raw構文記述子の文字を取得するには(aref (syntax-table) ch)のようにaref (配列を操作する関数を参照)を使用してください。

以下はさまざまな構文クラスに対応する構文コードです。

CodeClassCodeClass
0空白文字8区切り文字ペアー
1句読点9エスケープ
2単語10文字クォート
3シンボル11コメント開始
4開カッコ12コメント終了
5閉カッコ13継承
6式プレフィクス14汎用コメント
7文字列クォート15汎用文字列

たとえば標準構文テーブルでは‘(’にたいするエントリーは(4 . 41)、41は‘)’の文字コードです。

構文フラグは最下位ビットから16ビット目より始まる高位ビットにエンコードされます。以下のテーブルは対応する各構文フラグにたいして2のべき乗を与えます。

PrefixFlagPrefixFlag
1(ash 1 16)p(ash 1 20)
2(ash 1 17)b(ash 1 21)
3(ash 1 18)n(ash 1 22)
4(ash 1 19)c(ash 1 23)
Function: string-to-syntax desc

与えられた構文記述子desc(文字列)にたいして、この関数は対応するraw構文記述子をリターンする。

Function: syntax-class-to-char syntax

与えられた構文記述子syntax (整数)にたいして、この関数は対応する構文記述子(文字)をリターンする。

Function: syntax-after pos

この関数はバッファー内の位置posの後の文字にたいして、構文テーブルと同様に構文プロパティも考慮したraw構文記述子をリターンする。posがバッファーのアクセス可能範囲(accessible portionを参照)の外部ならリターン値はnil

Function: syntax-class syntax

この関数はraw構文記述子syntaxにたいする構文コードをリターンする。より正確にはこれはraw構文記述子のsyntax-code要素から構文フラグを記録する高位16ビットをマスクして、その結果の整数をリターンする。

syntaxnilならリターン値はnil。これは以下の式

(syntax-class (syntax-after pos))

posがバッファーのアクセス可能範囲外部なら、エラーをthrowしたり不正なコードをリターンすることなくnilに評価されるため。


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

36.8 カテゴリー

カテゴリー(categories)は構文的に文字をクラス分けする別の手段を提供します。必要に応じて複数のカテゴリーを定義して、それぞれの文字に独立して1つ以上のカテゴリーを割り当てることができます。構文クラスと異なりカテゴリーは互いに排他ではありません。1つの文字が複数のカテゴリーに属すのは普通のことです。

バッファーはそれぞれカテゴリーテーブル(category table)をもっています。これはどのカテゴリーが定義されていて、各カテゴリーにどの文字が属すかを記録しています。カテゴリーテールは自身のカテゴリーを定義しますが、標準カテゴリーはすべてのモードで利用可能なので、これらは通常は標準カテゴリーテーブルをコピーすることにより初期化されます。

カテゴリーはそれぞれ‘ から‘~’の範囲のASCIIプリント文字による名前をもちます。define-categoryで定義する際にはカテゴリーの名前を指定します。

カテゴリーテーブルは実際には文字テーブルです(文字テーブルを参照)。カテゴリーテーブルのインデックスcの要素は、文字cが属するカテゴリーを示すカテゴリーセット(category set)というブールベクターです。このカテゴリーセット内で、もしインデックスcatの要素がtならcatはそのセットのメンバーであり、その文字cはカテゴリーcatに属することを意味します。

以下の3つの関数のオプション引数tableのデフォルトは、カレントバッファーのカテゴリーテーブルです。

Function: define-category char docstring &optional table

この関数はカテゴリーテーブルtableにたいして名前がchar、ドキュメントがdocstringであるような新たなカテゴリーを定義する。

以下ではR2L(right-to-left: 右から左)への強い方向性(directionality)をもつ文字(双方向テキストの表示を参照)にたいするカテゴリーを新たに定義して、それを特別なカテゴリーテーブル内で使用する例を示す。文字の方向性に関する情報を取得するために、コード例ではUnicodeプロパティ‘bidi-class’ (bidi-classを参照)を使用する。

(defvar special-category-table-for-bidi
  ;;     空のcategory-tableを作成
  (let ((category-table (make-category-table))
        ;; Create a char-table which gives the 'bidi-class' Unicode
        ;; 各文字のプロパティ
        (uniprop-table
         (unicode-property-table-internal 'bidi-class)))
    (define-category ?R "Characters of bidi-class R, AL, or RLO"
                     category-table)
    ;; Unicodeの'bidi-class'プロパティが
    ;; R、AL、RLOであるような(R2Lの方向性をもつ)文字の
    ;; カテゴリーエントリーを変更する
    (map-char-table
     (lambda (key val)
         (if (memq val '(R AL RLO))
             (modify-category-entry key ?R category-table)))
     uniprop-table)
    category-table))
Function: category-docstring category &optional table

この関数はカテゴリーテーブルtable内のカテゴリーcategoryのドキュメント文字列をリターンする。

(category-docstring ?a)
     ⇒ "ASCII"
(category-docstring ?l)
     ⇒ "Latin"
Function: get-unused-category &optional table

この関数はtable内で現在のところ未定義なカテゴリーの名前(文字)をリターンする。table内で利用可能なカテゴリーがすべて使用済みならnilをリターンする。

Function: category-table

この関数はカレントバッファーのカテゴリーテーブルをリターンする。

Function: category-table-p object

この関数はobjectがカテゴリーテーブルならt、それ以外はnilをリターンする。

Function: standard-category-table

この関数は標準カテゴリーテーブルをリターンする。

Function: copy-category-table &optional table

この関数はtableのコピーを構築してリターンする。tableが与えられない(またはnil)なら、標準カテゴリーテーブルのコピーをリターンする。それ以外の場合には、もしtableがカテゴリーテーブルでなければエラーをシグナルする。

Function: set-category-table table

この関数はtableをカレントバッファーのカテゴリーテーブルにする。リターン値はtable

Function: make-category-table

これは空のカテゴリーテーブルを作成してリターンする。空のカテゴリーテーブルでは、どのカテゴリーも割り当てられておらず何らかのカテゴリーに属する文字もない。

Function: make-category-set categories

この関数は初期内容が文字列categoriesにリストされるカテゴリーであるような、新たなカテゴリーセット(ブールベクター)をリターンする。categoriesの要素はカテゴリー名であること。新たなカテゴリーセットはそれらのカテゴリーにたいしてt、それ以外のすべてのカテゴリーにたいしてnilをもつ。

(make-category-set "al")
     ⇒ #&128"\0\0\0\0\0\0\0\0\0\0\0\0\2\20\0\0"
Function: char-category-set char

この関数はカレントバッファーのカテゴリーテーブル内で、文字charにたいするカテゴリーセットをリターンする。これは文字charが属するカテゴリーを記録するブールベクター。関数char-category-setはカテゴリーテーブル内にある同じブールベクターをリターンするのでメモリーの割り当ては行わない。

(char-category-set ?a)
     ⇒ #&128"\0\0\0\0\0\0\0\0\0\0\0\0\2\20\0\0"
Function: category-set-mnemonics category-set

この関数はカテゴリーセットcategory-setを、そのセットのメンバーのカテゴリーを指定する文字を含む文字列に変換する。

(category-set-mnemonics (char-category-set ?a))
     ⇒ "al"
Function: modify-category-entry char category &optional table reset

この関数はカテゴリーテーブルtable (デフォルトはカレントバッファーのカテゴリーテーブル)内のcharのカテゴリーセットを変更する。charには文字、または(min . max)という形式のコンスセルを指定できる。後者の場合には、この関数はminmaxの間(両端を含む)の範囲にあるすべての文字のカテゴリーセットを変更する。

これは通常はカテゴリーセットにcategoryを追加することにより変更を行う。しかしresetが非nilなら、かわりにcategoryを削除する。

Command: describe-categories &optional buffer-or-name

この関数はカレントカテゴリーテーブル内のカテゴリー仕様を説明する。これはその説明をバッファーに挿入してから、そのバッファーを表示する。buffer-or-nameが非nilなら、かわりにそのバッファーのカテゴリーテーブルを説明する。


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

37 プログラムソースの解析

Emacsではプログラムソースのテキストのパース(parse: 解析)や構文ツリーまたは構文木(syntax tree)を生成するためにさまざまな方法が提供されています。構文ツリーにおけるテキストはもはや1次元の文字ストリームではなく、ノードというそれぞれがテキストの一部を表現するようなものを構造化したツリーとみなされます。つまり構文ツリーによって正確なフォント表示(fontification)、インデント、ナビゲーション、構造化された編集等といった興味深い機能を有効にできるのです。

Emacsには釣り合いのとれた式をパースするシンプルな機能があります(式のパースを参照)。一般的なナビゲーションとインデントにたいするSMIEというライブラリーもあります(SMIE: 無邪気なインデントエンジンを参照)。

これらに加えてtree-sitterライブラリーにたいするサポートがコンパイルされていれば、Emacsはtree-sitterとの統合も提供します。tree-sitterライブラリーはインクリメンタルパーサー(incremental parser: 増分解析ライブラリー)であり、幅広いプログラミング言語をサポートしています。

Function: treesit-available-p

この関数はカレントのEmacsセッションにおいてtree-sitter機能が利用可能なら非nilをリターンする。

tree-sitterライブラリーを用いたプログラムソースのパースとプログラムの構文ツリーへのアクセスを可能にするためには、Lispプログラムがその言語のグラマーライブラリーをロードするとともにその言語とカレントバッファーにたいするパーサーを作成する必要があります。Lispプログラムがこれを行った後に、構文ツリーの特定のノードに関してパーサーへの問い合わせを行うことができるのです。その後はそれぞれのノードに関するさまざまな種類の情報にアクセスして、強力なパターンマッチングを用いたノードの検索が可能になります。このチャプターではこれらすべてをどのように行うのか、そして複数のプログラミング言語がミックスされているソースファイルにたいしてLispプログラムが処理する方法についても説明します。


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

37.1 Tree-sitter Language Grammar

言語グラマーのロード

ある言語で記述されたテキストをパースするために、tree-sitterはその言語のグラマー(grammar: 文法)に依存します。Emacsにおける言語グラマーはシンボルによって表現されます。たとえばC言語のグラマーはシンボルcとして表現されます。このcというシンボルはtree-sitter関数のlanguage引数として渡すことができます。

tree-sitterの言語グラマーはダイナミックライブラリーとして配布されています。ある言語のグラマーをEmacsで使用するためには、そのダイナミックライブラリーがシステム上にインストール済みかを確認する必要があります。Emacsは以下の順序で複数の場所から言語グラマーを探します:

  • まず変数treesit-extra-load-pathで指定されたディレクトリーのリストから;
  • それからuser-emacs-directoryで指定されるディレクトリーのサブディレクトリーtree-sitterから(initファイルを参照);
  • 最後にシステムのダイナミックライブラリー用のデフォルト位置。

これらのディレクトリーそれぞれにおいて、Emacsは変数dynamic-library-suffixesが指定するファイル名拡張子をもつファイルを探すのです。

Emacsがライブラリーを見つけられなかったりロードに問題がある場合には、Emacsがtreesit-load-language-errorエラーをシグナルします。このシグナルのデータは以下のいずれかです:

(not-found error-msg …)

その言語のグラマーライブラリーをEmacsが見つけられなかったという意味。

(symbol-error error-msg)

すべての言語のグラマーライブラリーでエクスポートされているべき関数を、そのライブラリーではEmacsが見つけられなかったという意味。

(version-mismatch error-msg)

その言語のグラマーライブラリーとtree-sitterライブラリーのバージョンに互換性がないという意味。

上記すべてのケースにおいて、error-msgにより失敗に関する追加の詳細が提供されるかもしれません。

Function: treesit-language-available-p language &optional detail

この関数はlanguageにたいする言語グラマーが存在して、それがロード可能であれば非nilをリターンする。

detailが非nilの場合には、languageが利用可能なら(t . nil)、利用不可なら(nil . data)をリターンする。datatreesit-load-language-errorのシグナルデータ。

慣例によりlanguage用ダイナミックライブラリーのファイル名はlibtree-sitter-language.extです。ここでextはダイナミックライブラリー用のシステム固有な拡張子です。同じく慣例により、そのライブラリーが提供する関数の名前はtree_sitter_languageです。この慣例にしたがっていない言語グラマーライブラリーの場合には、

(language library-base-name function-name)

上記エントリーを変数treesit-load-name-override-listのリストに追加する必要があります。ここでlibrary-base-nameはダイナミックライブラリーのファイル名のベースネーム(basename: 先行するディレクトリー部分を除外したファイル名のことで、通常だとlibtree-sitter-language)、function-nameはそのライブラリーが提供する関数(通常だとtree_sitter_language)です。たとえば、

(cool-lang "libtree-sitter-coool" "tree_sitter_cooool")

これは慣例に屈するには自分があまりにも“cool”に過ぎると考える言語の例です。

Function: treesit-library-abi-version &optional min-compatible

この関数はtree-sitterライブラリーがサポートしている言語グラマーのABI (Application Binary Interface: アプリケーションバイナリーインターフェイス)のバージョンをリターンする。デフォルトではそのライブラリーがサポートする最新のABIバージョンをリターンするが、min-compatibleが非nilの場合にはそのライブラリーでまだサポートできる最古のABIバージョンをリターンする。言語グラマーライブラリーはtree-sitterライブラリーがサポートする最古と最新の間にあるABIバージョンにたいしてビルドしなければ、tree-sitterライブラリーがそれらをロードできなくなる。

Function: treesit-language-abi-version language

この関数はEmacsがロードしたlanguage用の言語グラマーライブラリーのABIバージョンをリターンする。languageが利用できなければnilをリターンする。

構文ツリーの具体例

構文ツリーはパーサーによって生成されます。構文ツリーにおけるノードはそれぞれがテキストのある部分を表し、お互いが親子関係というリレーションシップによって接続されています。たとえば以下のようなソーステキストがあるとします

1 + 2

これは以下のような構文ツリーになるかもしれません

                  +--------------+
                  | root "1 + 2" |
                  +--------------+
                         |
        +--------------------------------+
        |       expression "1 + 2"       |
        +--------------------------------+
           |             |            |
+------------+   +--------------+   +------------+
| number "1" |   | operator "+" |   | number "2" |
+------------+   +--------------+   +------------+

これを以下のようにS式で表すことも可能です:

(root (expression (number) (operator) (number)))

ノードタイプ

rootexpressionnumberoperatorのような名前はノードのタイプ(type: 型)を指定します。ただし構文ツリーのすべてのノードがタイプをもつ訳ではありません。タイプをもっていないノードは無名ノード(anonymous nodes)、タイプをもつノードは名前つきノード(named nodes)と呼ばれています。無名ノードは角カッコ‘]’のような区切り文字やreturnのようなキーワードを含む、固定化された綴りのトークン(token: 字句単位)です。

フィールド名

構文ツリーの分析を容易にするために、多くの言語グラマーは子ノードにフィールド名(field names)を割り当てています。たとえばfunction_definitionノードはdeclaratorbodyのフィールド名をもつかもしれません:

(function_definition
 declarator: (declaration)
 body: (compound_statement))

構文ツリーの調査

言語の構文の理解、および構文ツリー割り当て使用するLispプログラムのデバッグ支援のために、Emacsはカレントバッファーのソースの構文ツリーをリアルタイムで表示する“explore”モードを提供しています。更にEmacsにはポイント位置にあるノードの情報をモードラインに表示する“inspect”モードも付属しています。

Command: treesit-explore-mode

このモードはカレントバッファーのソースの構文ツリーを表示するウィンドウをポップアップする。ソースバッファーでテキストを選択することによって、表示されている構文ツリーの対応する部分がハイライトされる。構文ツリーでノードをクリックすれば、ソースバッファーの対応するテキストがハイライトされる。

Command: treesit-inspect-mode

このマイナーモードはポイント位置で始まるノードをモードラインに表示する。たとえばモードラインに以下のように表示されるかもしれない

parent field: (node (child (…)))

ここでnodechild、...等はポイント位置で始まるノード、parentnodeの親である。nodeはbold書体で表示される。field-namenodechild、...等のフィールド名である。

ポイント位置で始まるノードがない(ポイントがノードの中間にある)場合には、ポイントを跨ぐ(span)もっとも前のノード、およびそのノードの直近の親ノードがモードラインに表示される。

このマイナーモード自身はパーサーを作成せず、(treesit-parser-list)の最初のパーサーを使用する(tree-sitterパーサーの使用を参照)。

グラマー定義を読む

言語グラマーの製作者はプログラミング言語のグラマー(grammar: 文法)を定義します。パーサーがどのようにしてプログラムテキストから具体的な構文ツリーを構築するかを決めるのがグラマーです。構文ツリーを効果的に使用するためには、グラマーファイル(grammar file)を調べる必要があります。

グラマーファイルは通常だと言語グラマーのプロジェクトレポジトリにあるgrammar.jsです。言語グラマーのホームページへのリンクはtree-sitter’s homepageで見つけることができるでしょう。

グラマー定義はJavaScriptによって記述されます。たとえばfunction_definitionノードにマッチするようなルールは以下のようなものかもしれません

function_definition: $ => seq(
  $.declaration_specifiers,
  field('declarator', $.declaration),
  field('body', $.compound_statement)
)

ルールは単一の引数$を受け取る関数によって表現されます。この関数がグラマー全体を表すのです。この関数自体は他の関数によって構築されています。一連の子ノードをまとめるのがseq関数、子ノードにフィールド名の注釈をつけるのがfield関数です。上記の定義を俗にBNF (Backus-Naur Form: バッカス・ナウア記法)と呼ばれる構文で表せば以下のようになるでしょう

function_definition :=
  <declaration_specifiers> <declaration> <compound_statement>

そしてパーサーがリターンするノードは以下のようになります

(function_definition
  (declaration_specifier)
  declarator: (declaration)
  body: (compound_statement))

以下はグラマー定義で目にするかもしれない関数のリストです。これらの関数はいずれも引数として他のルールを受け取り新たなルールをリターンします。

seq(rule1, rule2, …)

すべてのルールに逐一マッチする。

choice(rule1, rule2, …)

引数のルールいずれかにマッチする。

repeat(rule)

rule0回以上マッチする。正規表現の演算子‘*’に似ている。

repeat1(rule)

rule1回以上マッチする。正規表現の演算子‘+’に似ている。

optional(rule)

rule0回または1回マッチする。正規表現の演算子‘?’に似ている。

field(name, rule)

ruleにマッチする子ノードにフィールド名nameを割り当てる。

alias(rule, alias)

ruleにマッチしたノードをパーサーが生成する構文ツリーでaliasとして表示する。たとえば、

alias(preprocessor_call_exp, call_expression)

これによりpreprocessor_call_expがマッチしたノードがcall_expressionと表示される。

以下は言語グラマーを読むにあたってそれほど重要ではないグラマー関数です。

token(rule)

単一の葉ノード(leaf node)としてruleをマークする。つまり個別の子ノードをもつ親ノードではなく、その単一の葉ノードにすべてが収斂されるようなノードを生成する。ノードの取得を参照のこと。

token.immediate(rule)

通常のグラマールールは先行する空白を無視するが、これは空白が前置されていないruleだけにマッチするよう変更する。

prec(n, rule)

ruleにたいしてレベルnの優先度を与える。

prec.left([n,] rule)

ruleにたいしてオプションとしてレベルnを付与して左結合(left-associative)とマークする。

prec.right([n,] rule)

ruleにたいしてオプションとしてレベルnを付与して右結合(right-associative)とマークする。

prec.dynamic(n, rule)

precと似ているが優先度は実行時に適用される。

tree-sitterプロジェクトにはmore about writing a grammarというドキュメントがあります。特に“The Grammar DSL”というセクションを読んでください。


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

37.2 tree-sitterパーサーの使用

このセクションではtree-sitterパーサーをどのようにして作成して構成するかについて説明します。Emacsにおけるtree-sitterパーサーはそれぞれバッファーに関連付けられます。ユーザーによるバッファーの編集にしたがって、関連付けられているパーサーと構文ツリーは自動的に最新に保たれるのです。

Variable: treesit-max-buffer-size

この変数にはtree-sitterをアクティブにし得るバッファーの最大サイズが含まれる。メジャーモードはtree-sitter機能を有効にするかどうかを判断する際にはこの変数をチェックすること。

Function: treesit-parser-create language &optional buffer no-reuse

指定されたbufferおよびlanguage (Tree-sitter Language Grammarを参照)にたいしてパーサーを作成する。バッファーが省略またはnilの場合にはカレントバッファーを意味する。

この関数はbufferlanguageにたいするパーサーがすでに存在していれば、デフォルトではそれを再利用するがno-reuseが非nilの場合には常に新たなパーサーを作成する。

そのバッファーがインダイレクトバッファーなら、かわりにベースバッファーを使用する。つまりインダイレクトバッファーではそのベースバッファーのパーサーが使用される。ベースバッファーがナローイングされていると、インダイレクトバッファーがベースバッファーで不可視なバッファーテキスト部分の情報を取得できないかもしれない。Lispプログラムがインダイレクトバッファーでパーサーを使用するためには、必要に応じてwiden(訳注: カレントバッファーからナローイングによる制限を取り去る関数)する必要がある。

パーサーが与えられれば、それに関する情報を問い合わせることができます。

Function: treesit-parser-buffer parser

この関数はparserに関連付けられているバッファーをリターンする。

Function: treesit-parser-language parser

この関数はparserが使用する言語をリターンする。

Function: treesit-parser-p object

この関数はobjectをチェックしてtree-sitterパーサーなら非nil、そうでなければnilをリターンする。

パースは自動的かつ遅延して行われるので、明示的にバッファーをパースする必要はありません。パーサーがパースを行うのは、Lispプログラムがパーサーの構文ツリーのノードにたいして問い合わせを行ったときだけです。したがって最初にパーサーが作成された際にはバッファーのパースは行われず、Lispプログラムがノードにたいする問い合わせを最初に行うまで待機します。同様に何らかの変更をバッファーに行った際にも、パーサーが即座に再パースする訳ではありません。

パーサーがパースを行う際にはバッファーのサイズをチェックします。tree-sitterが処理できるのはおよそ4GBまでです。サイズがそれを超えると、Emacsはそのバッファーサイズをシグナルデータとしてtreesit-buffer-too-largeエラーをシグナルするでしょう。

一度パーサーを作成すると、Emacsが自動的にそれを内部のパーサーリストに追加します。バッファーにたいして変更が行われるたびに、パーサーがインクリメンタルに構文ツリーを更新できるように、Emacsがこのリストにあるパーサーを更新するのです。

Function: treesit-parser-list &optional buffer

この関数はbufferのパーサーリストをリターンする。buffernilまたは省略の場合のデフォルトはカレントバッファー。そのバッファーがインダイレクトバッファーなら、かわりにベースバッファーを使用する。つまりインダイレクトバッファーではそのベースバッファーのパーサーが使用される。

Function: treesit-parser-delete parser

この関数はparserを削除する。

パーサーは通常はバッファー全体を“見ている”ものですが、バッファーがナローイング(ナローイングを参照)されているとパーサーが見るのはバッファーのアクセス可能範囲だけになります。パーサーが見る限りでは、隠されているリージョンは削除されたことになります。後刻バッファーがワイドニングされた際には、先頭と終端にテキストが挿入されたとパーサーは考えるでしょう。パーサーがナローイングを尊重するにしても、複数言語のバッファーを処理するという意味合いでモードはナローイングを使用するべきではありません。そのかわりにパーサーが処理する必要がある範囲をセットするべきです。複数言語ののパースを参照してください。

パーサーはパースを遅延させるので、ユーザーやLispプログラムがバッファーをナローイングしてもパーサーはすぐに影響を受けないのです。バッファーをナローイングしていても、モードがノードについて問い合わせをするまでパーサーはナローイングを認識しません。

バッファーにたいしてパーサーを作成するだけではなく、Lispプログラムが文字列のパースを行うことも可能です。バッファーと違い文字列のパースは一度かぎりの操作であり、結果を更新する手段はありません。

Function: treesit-parse-string string language

この関数はlanguageを使用してstringのパースを行い、生成された構文ツリーのルートノードをリターンする。

パースツリーへの変更による通知

Lispプログラムはインクリメンタルなパースによって影響を受けるテキストにたいして通知してほしい場合があるかもしれません。たとえばコメントを閉じるtokenの挿入によって、そのtokenの手前にあるテキストを変換する場合です。たとえテキストが直接変更されなくても、それは“変更”とみなされるのです。

Emacsではこれらの類いの変更にたいして、Lispプログラムにコールバック関数(別名notifier)を登録できます。notifier関数はrangesparserという2つの引数を受け取ります。ranges(start . end)という形式をもつコンスセルのリストです。ここでstartendは範囲の開始と終了をマークします。parserは通知を発行するパーサーです。

パーサーはバッファーを再パースするたびに構文ツリーの新旧を比較して、変更されたノード範囲の計算を行いその範囲をnotifier関数に引き渡します。最初のパースも“変更”とみなされるので、最初のパースではバッファー全体を範囲としてnotifier関数が呼び出されることに注意してください。

Function: treesit-parser-add-notifier parser function

この関数はparserのnotifier関数のafter-changeリストにfunctionを追加する。functionはlambda関数ではなく、関数シンボルでなければならない(無名関数を参照)。

Function: treesit-parser-remove-notifier parser function

この関数はparserのnotifier関数のafter-changeリストからfunctionを削除する。functionはlambda関数ではなく、関数シンボルでなければならない(無名関数を参照)。

Function: treesit-parser-notifiers parser

この関数はparserのnotifier関数のリストをリターンする。


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

37.3 ノードの取得

以下はわたしたちがtree-sitter関数を文書化する際に用いる用語と慣習についてです。

構文ツリーのノードは、バッファーのプログラムテキストのある部分に跨ります(span)。あるノードの跨ぐバッファーテキスト部分が、他のノードのそれより小さい(または大きい)場合には、わたしたちはそのノードが他のノードより“小さい”(または“大きい”)と表現します。ツリーにおいてより深い(“下位”の)ノードは、そのツリーのより“上位”ノードの子となるので、そのノード階層において下位のノードは常に上位のノードより小さくなります。構文ツリーの上位のノードには、その子として1つ以上の小さいノードが含まれており、したがってバッファーテキストのより大きい部分を跨ぐことになるのです。

関数がノードを見つけられなかった場合にはnilをリターンします。利便性のために、引数としてノードを受け取ってノードをリターンするすべての関数もnilの引数を許し、そのような場合には単にnilをリターンするようになっています。

関連付けられているバッファーが更新された際にノードが自動的に更新されることはなく、一度取得したノードを更新する術は存在しません。古くなってしまったノードを使用するとtreesit-node-outdatedエラーがシグナルされるでしょう。

構文ツリーからのノードの取得

Function: treesit-node-at pos &optional parser-or-lang named

この関数はバッファー位置posにある葉ノード(leaf node)をリターンする。葉ノードとは子ノードを何ももたないノードのこと。

この関数はposを跨がって覆う(cover)ようなノードのリターンを試みる。これは開始位置がpos以下、かつ終了位置がpos以上であるノードのこと。

posを跨いで覆うような葉ノードがない(たとえばposが2つの葉ノードの間にある空白にある)場合には、この関数はposの後にある最初の葉ノードをリターンする。

最後にもしposの後に葉ノードがなければ、posの前にある最初の葉ノードをリターンする。

parser-or-langがパーサーオブジェクトなら、この関数はそのパーサーを使用する。parser-or-langが言語の場合には、この関数はカレントバッファーにおいてその言語用の最初のパーサー、もし存在しなければパーサーを作成してそれを使用する。parser-or-langnilなら、この関数はtreesit-language-at (複数言語ののパースを参照)を呼び出して、posの言語の推測を試みる。

リターンする適切なノードが見つけられなかった場合には、この関数はnilをリターンする。

namedが非nilの場合には、この関数は名前つきのノードだけを探す(named nodeを参照)。

例:

;; Cパーサーの構文ツリーでポイント位置のノードを探す
(treesit-node-at (point) 'c)
  ⇒ #<treesit-node (primitive_type) in 23-27>
Function: treesit-node-on beg end &optional parser-or-lang named

この関数はbegendの間にあるバッファーテキストのリージョンを覆うような、もっとも小さいノードをリターンする。言い換えると開始がbeg以前、かつ終了がend以降であるようなノードのこと。

注意せよ: トップレベル構文(関数定義等)の内部ではない空行でこの関数を呼び出すと、恐らくルートノードが取得される場合がほとんどだろう。その空行を覆うもっとも小さいノードがルートノードだというのがその理由だが、あなたが使いたいと望んでいる機能は、ほとんどの場合はtreesit-node-atのほうだろう。

parser-or-langがパーサーオブジェクトなら、この関数はそのパーサーを使用する。parser-or-langが言語の場合には、この関数はカレントバッファーにおいてその言語用の最初のパーサー、もし存在しなければパーサーを作成してそれを使用する。parser-or-langnilなら、この関数はtreesit-language-at (複数言語ののパースを参照)を呼び出して、begの言語の推測を試みる。

namedが非nilの場合には、この関数は名前つきのノードだけを探す(named nodeを参照)。

Function: treesit-parser-root-node parser

この関数はparserが生成した構文ツリーのルートノードをリターンする。

Function: treesit-buffer-root-node &optional language

この関数はカレントバッファーでlanguage用の最初のパーサー、パーサーが存在しなければ作成して、そのパーサーが生成したルートノードをリターンする。languageが省略された場合にはパーサーリストの最初のパーサーを使用する。適切なパーサーが見つからなければnilをリターンする。

Lispプログラムはノードが与えられれば、そこから始まる他のノードを取得したり、そのノードに関する情報を問い合わせることができます。

ノードからの他ノードの取得

親族関係から

Function: treesit-node-parent node

この関数はnodeの直近の親をリターンする。

パースツリー(parse tree: 解析木)においてnodeが1000を超える深さのレベルにある場合のリターン値は未定義。現在のところnilをリターンするが、将来変更されるかもしれない。

Function: treesit-node-child node n &optional named

この関数はnoden番目の子をリターンする。namedが非nilなら名前つきのノードだけを考慮する(named nodeを参照)。

たとえば文字列"text"を表すノードの場合には開クォート"、文字列テキストのtext、それに閉クォート"という3つの子ノードが存在する。これら3つのノードの中で最初の子は開クォート"、最初の名前つきの子は文字列テキストとなる。

この関数はn番目の子が存在しなければnilをリターンする。nは負でも可(-1は最後の子を表す)。

Function: treesit-node-children node &optional named

この関数はnodeのすべての子をリストでリターンする。namedが非nilなら名前つきのノードだけを取得する。

Function: treesit-node-next-sibling node &optional named

この関数はnodeの次の兄弟を探す。namedが非nilなら次の名前つきの兄弟を探す。

Function: treesit-node-prev-sibling node &optional named

この関数はnodeの前の兄弟を探す。namedが非nilなら前の名前つきの兄弟を探す。

フィールド名から

構文ツリーの分析をより容易にするために、多くの言語ではグラマーで子ノードにフィールド名(field names)を割り当てています(field nameを参照)。たとえばfunction_definitionノードにはdeclaratorbodyというノードがあるかもしれません。

Function: treesit-node-child-by-field-name node field-name

この関数はフィールド名がfield-name(文字列)であるようなnodeの子を探す。

;; フィールド名が"body"という子を取得
(treesit-node-child-by-field-name node "body")
  ⇒ #<treesit-node (compound_statement) in 45-89>

位置から

Function: treesit-node-first-child-for-pos node pos &optional named

この関数はバッファー位置posを超えて広がるようなnodeの最初の子をリターンする。“超えて広がる(extends beyond)”とは子ノードの終端がpos以降であることを意味する。この関数はnodeの直接の子だけを調べる(孫は調べない)。namedが非nilの場合には最初の名前つきの子を探す(named nodeを参照)。

Function: treesit-node-descendant-for-range node beg end &optional named

これは位置begendの間にあるテキストリージョンを跨ぐような、もっとも小さいnodeの子孫ノードを探す、treesit-node-atと似た関数。namedが非nilの場合には、もっとも小さい名前つきの子を探す。

ノードの検索

Function: treesit-search-subtree node predicate &optional backward all depth

この関数はnodeのサブツリー(node自体を含む)を横断(traverse)して、predicateが非nilをリターンするようなノードを探す。predicateはノードそれぞれのタイプにたいしてマッチさせるregexp、あるいはノードを受け取りそのノードがマッチしたら非nilをリターンするような述語関数。この関数はマッチした最初のノード、何もマッチしなければnilをリターンする。

この関数が検索するのはデフォルトでは名前つきノードだけだが、allが非nilならすべてのノードを横断して検索を行う。backwardが非nilの場合には後方に横断して検索する(ツリーを下降して横断していく際に最後の子を最初に調べる)。depthが非nilなら、それはツリーを横断して下降できるレベル数を制限する数値でなければならない。depthnilの場合のデフォルトは1000。

Function: treesit-search-forward start predicate &optional backward all

この関数は(startを除けば)treesit-search-subtreeと同じようにパースツリーを横断して、predicateによりそれぞれのノードをマッチする(predicateはregexpまたは関数)。以下のようなツリー(‘S’マークはstart)の場合には、この関数は1から12の順に横断していく:

              12
              |
     S--------3----------11
     |        |          |
o--o-+--o  1--+--2    6--+-----10
|  |                  |        |
o  o                +-+-+   +--+--+
                    |   |   |  |  |
                    4   5   7  8  9

この関数はstartのサブツリーを横断せず、常に上方に移動する前にまず葉ノードを横断することに注意。

この関数が検索するのはtreesit-search-subtreeと同じようにデフォルトでは名前つきノードだけだが、allが非nilならすべてのノードを検索する。backwardが非nilの場合には後方に検索する。

treesit-search-subtreeはノードのサブツリーを横断するが、この関数はノードstartから開始してバッファーの位置順でその後にあるすべてのノード(開始位置がstartの終了位置より大きいノード)を横断する。

上図で示すツリーにおいて、treesit-search-subtreeはノード‘S’ (start)およびoのマークがついたノードを横断するが、この関数は数字のマークがついたノードを横断する。この関数は“バッファーでstartの後にあり何らかの条件を満足する最初のノードはどれ?”、のような問いの答えを求めるのに役に立つ。

Function: treesit-search-forward-goto node predicate &optional start backward all

この関数はバッファーでnodeの後にありpredicateにマッチする次のノードの開始または終了にポイントを移動する。startが非nilなら、ノードの終了ではなく開始で停止する。

この関数がリターンするマッチしたノードは、バッファー位置という点において進行方向にある(リターンされたノードの開始/終了はnodeのそれより常に大きい)ことが保証されている。

引数predicatebackwardalltreesit-search-forwardの場合と同じ。

Function: treesit-induce-sparse-tree root predicate &optional process-fn depth

この関数はrootのサブツリーからsparseツリー(疎らなツリー)を作成する。

この関数はroot配下のサブツリーを受け取って、predicateにマッチするノードだけが残るように間引く。前の関数と同じようにpredicateはノードそれぞれのタイプにマッチさせるためのregexp文字列、またはノードを受け取ってマッチした場合には非nilをリターンする。

たとえば数字と文字の両方で構成される左側のサブツリーが与えられた場合に、“文字のみ”というpredicateでリターンされるのが右側のツリー。

    a                 a              a
    |                 |              |
+---+---+         +---+---+      +---+---+
|   |   |         |   |   |      |   |   |
b   1   2         b   |   |      b   c   d
    |   |     =>      |   |  =>      |
    c   +--+          c   +          e
    |   |  |          |   |
 +--+   d  4       +--+   d
 |  |              |
 e  5              e

この関数はprocess-fnが非nilの場合には、マッチしたノードではなくノードをそれぞれprocess-fnに渡してリターン値を使用する。depthが非nilなら、それはrootから下降できるレベル数制限であること。depthnilの場合のデフォルトは1000。

リターンされるツリーのノードはそれぞれ(tree-sitter-node . (child …))のようになる。このツリーのルートであるtree-sitter-nodeは、rootpredicateにマッチしなければnilになる。predicateにマッチするノードがなければ、この関数はnilをリターンする。

より便利な関数

Function: treesit-filter-child node predicate &optional named

この関数はpredicateを満足するnodeの直接の子を探す。

predicateは引数としてノードを受け取り、そのノードを候補に残すべきなら非nilをリターンする関数であること。namedが非nilなら、この関数は名前つきのノードだけを調べる。

Function: treesit-parent-until node predicate &optional include-node

この関数はnodeの親を順繰りに探して、pred (引数としてノードを受け取りマッチを示すブーリーン値をリターンする関数)を満足する親をリターンする。predを満足する親がいなければ、この関数はnilをリターンする。

この関数は通常だとnode自体ではなくnodeの親だけを調べる。しかし、include-nodeが非nilの場合には、nodepredを満足すればnodeをリターンする。

Function: treesit-parent-while node pred

この関数はnodeを開始点としてノードがpred (引数としてノードを受け取る関数)を満足するかぎりツリーを上方に移動する。つまりこの関数はpredを満足するもっとも高位にあるnodeの親をリターンする。nodepredを満足して、かつ直近の親はpredを満足しなければ、node自体がリターンされることに注意。

Function: treesit-node-top-level node &optional type

この関数はnodeと同じタイプをもつ、もっとも高くにある親をリターンする。そのような親がいなければnilをリターンする。したがってこの関数はnodeがトップレベルかどうかをテストするためにも役に立つ。

typeが非nilの場合には、この関数はnodeのタイプではなく、regexpとしてtypeを用いてそれぞれの親のタイプをマッチする。


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

37.4 ノード情報へのアクセス

ノードの基本的な情報

すべてのノードはパーサーに関連付けられていて、そのパーサーが関連付けられているのがバッファーです。以下はそれらを取得する関数です。

Function: treesit-node-parser node

この関数はnodeに関連付けられているパーサーをリターンする。

Function: treesit-node-buffer node

この関数はnodeのパーサーに関連付けられているバッファーをリターンする。

Function: treesit-node-language node

この関数はnodeに関連付けられている言語をリターンする。

それぞれのノードはバッファー内のテキストのある範囲を表しています。そのテキストに関する情報を探すのが以下の関数です。

Function: treesit-node-start node

nodeの開始位置をリターンする。

Function: treesit-node-end node

nodeの終了位置をリターンする。

Function: treesit-node-text node &optional object

nodeが表しているバッファーテキストを文字列としてリターンする(nodeが文字列をパースすることによって取得されたものであれば、その文字列のテキストをリターンする)。

以下はtree-sitterのノード用の述語の一部です:

Function: treesit-node-p object

objectがtree-sitterの構文ノードかをチェックする。

Function: treesit-node-eq node1 node2

tree-sitterの構文ツリーにおいてnode1node2が同じノードを参照しているかをチェックする。この関数はequalと等価なメトリックを用いる。equalを使用してノードを比較することも可能(同等性のための述語を参照)。

プロパティ情報

具体的な構文ツリーにおけるノードは一般的に名前つきノード(named nodes)無名ノード(anonymous nodes)という2つのカテゴリーに大別されます。あるノードが名前つきか、それとも無名なのかは言語グラマーによって判断されます(named nodeを参照)。

ノードが名前つきか、あるいは無名かというプロパティに加えて、ノードは他のプロパティをもつことができます。ノードが“欠落(missing)”していることもあり得ます。このようなノードは特定の類の構文エラー(たとえばグラマーに照らせば恐らくそこにあるべき何らかが存在しない)から復帰するためにパーサーによって挿入されます。これはプログラムソースの編集中において、そのソースがまだ最終形になっていないときに発生し得るエラーです。

“余分(extra)”というノードもあります。このようなノードはテキスト内の任意の場所に出現し得る、コメントのようなオブジェクトを表しています。

パーサーがノードを作成した後に少なくとも1回再パースされた場合には、“期限切れ(outdated)”のノードになることがあります。

ノードが跨ぐテキストに構文エラーが含まれていれば、“エラーあり(has error)”のノードです。ノード自体にエラーがあったり、子孫のいずれかのノードにエラーがあるのかもしれません。

ノードはそのノードのパーサーが削除されておらず、更にそのノードが生きているバッファー(バッファーのkillを参照)であれば生きている(live)とみなされます。

Function: treesit-node-check node property

この関数はnodeが指定されたpropertyをもっていれば非nilをリターンする。propertynamedmissingextraoutdatedhas-errorliveのいずれか。

Function: treesit-node-type node

名前つきノードは“タイプ(type)”をもつことができる(node typeを参照)。たとえば名前つきノードstring_literalのタイプをstring_literalにすることができる。無名ノードは、単にそのノードが表すテキストがタイプとなる(たとえば‘,’ノードのタイプは単に‘,’)。

この関数はnodeのタイプを文字列としてリターンする。

子や親としての情報

Function: treesit-node-index node &optional named

この関数は親からnodeを子ノードとして見た場合のインデックスをリターンする。namedが非nilの場合には名前つきノードだけを考慮する(named nodeを参照)。

Function: treesit-node-field-name node

親をもつ子ノードはフィールド名をもつことができる(field nameを参照)。この関数は親からnodeを子ノードとして見た場合のフィールド名をリターンする。

Function: treesit-node-field-name-for-child node n

この関数はnoden番目の子のフィールド名をリターンする。n番目の子がいない、またはn番目の子にフィールド名がなければnilをリターンする。

nは名前つきの子と無名の子の両方を考慮することに注意。またnは負でもよい(-1は最後の子を表す)。

Function: treesit-node-child-count node &optional named

この関数はnodeの子の数をリターンする。namedが非nilの場合には名前つきの子だけを考慮する(named nodeを参照)。


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

37.5 tree-sitterノードにたいするパターンマッチング

tree-sitterでは小さな宣言型言語を用いてLispプログラムによるパターンのマッチングができます。このパターンマッチングは2つのステップから構成されています。まずtree-sitterが構文ツリーのノードにたいするパターン(pattern)のマッチを行い、その後にパターンにマッチした特定のノードをキャプチャー(capture)してそのノードをリターンするのです。

まずはもっとも基本的なクエリーパターンを記述してパターン内のノードをキャプチャーする方法、それからパターンマッチング関数、そして最後により上級のパターン構文について説明していきます。

基本的なクエリー構文

クエリー(query: 問い合わせ)は複数のパターン(patterns)によって構成されます。パターンはそれぞれ構文ノード内の特定ノードにマッチするS式です。パターンは(type (child…))という形式をもっています。

たとえば子ノードを含んだノードbinary_expressionにマッチするのは以下のようなパターンでしょう

(binary_expression (number_literal))

上記のクエリーパターンを用いてノードをキャプチャー(capture)するためには、キャプチャーしたいノードパターンの後に@capture-nameを追加します。たとえば、

(binary_expression (number_literal) @number-in-exp)

これはノードbinary_expressionにあるノードnumber_literalをキャプチャー名でキャプチャーします。

同じようにして、たとえばキャプチャー名biexpでノードbinary_expressionをキャプチャーできます:

(binary_expression
 (number_literal) @number-in-exp) @biexp

クエリー関数

これでクエリー関数(query functions)を説明する準備ができました。

Function: treesit-query-capture node query &optional beg end node-only

この関数はqueryのパターンをnodeとマッチする。引数queryはS式、文字列、またはコンパイル済みクエリーオブジェクトのいずれか。ここではS式構文に焦点を当てる。文字列構文およびコンパイル済みクエリーについては、このセクションの最後で説明しよう。

引数nodeはパーサー、あるいは言語シンボルでもよい。パーサーの場合にはそのルートノードを、言語シンボルならまずカレントバッファーでその言語用のパーサーを探すか作成してそのルートノードを使用する。

この関数はキャプチャーしたすべてのノードを、(capture_name . node)という要素をもつalistでリターンする。node-onlyが非nilの場合には、かわりにnodeのリストをリターンする。デフォルトではnodeのテキスト全体を検索するが、begendがいずれも非nilであれば、それはこの関数がノードをマッチするべきバッファーテキストのリージョンを指定する。begendの間のリージョンを跨いで重なるようなノードがマッチすればすべてキャプチャーされる(完全にそのリージョンに含まれている必要はない)。

この関数はqueryが不正な形式であればtreesit-query-errorエラーraiseする。シグナルデータには、その特定。エラーに関する説明が含まれている。クエリーの検証とデバッグにはtreesit-query-validateを使うことができる。

たとえばnodeのテキストが1 + 2で、以下のクエリーを考えてみましょう

(setq query
      '((binary_expression
         (number_literal) @number-in-exp) @biexp)

このクエリーをマッチングすると以下がリターンされます

(treesit-query-capture node query)
    ⇒ ((biexp . <node for "1 + 2">)
       (number-in-exp . <node for "1">)
       (number-in-exp . <node for "2">))

前に言及したように、queryに複数のパターンを含めることができます。たとえば以下のようにトップレベルのパターンを2つもつことができます:

(setq query
      '((binary_expression) @biexp
        (number_literal) @number @biexp)
Function: treesit-query-string string query language

この関数はlanguageとしてstringをパースして、そのルートノードにたいしてqueryをマッチ、その結果をリターンする。

その他のクエリー構文

ノードのタイプとキャプチャー名以外にも、tree-sitterのパターン構文により無名ノード、フィールド名、ワイルドカード、量化、グルーピング、選択、アンカー、述語を表現することができます。

無名ノード

無名ノードはクォートで括ることで逐語的に記述されます。キーワードreturnにマッチ(してキャプチャー)するパターンは以下のようになるでしょう

"return" @keyword

ワイルドカード

パターンにおいて‘(_)’は任意の名前つきノード、‘_’は名前つきノードや無名ノードのすべてにマッチします。たとえばbinary_expressionノードの名前つきの子をすべてキャプチャーするパターンは以下のようになるでしょう

(binary_expression (_) @in-biexp)

フィールド名

特定のフィールド名をもつ子ノードをキャプチャーすることは可能です。以下のパターンでは、フィールド名であることを示すコロンが後置されているdeclaratorbodyがフィールド名です。

(function_definition
  declarator: (_) @func-declarator
  body: (_) @func-body)

特定のフィールドをもたないノード、たとえばbodyフィールドのないfunction_definitionをキャプチャーすることも可能です:

(function_definition !body) @func-no-body

ノードの量化

tree-sitterは量化演算子(quantification operator)の‘:*’、‘:+’,‘:?’を認識します。これらの演算子の意味は正規表現の場合と同じです。‘:*’と‘:+’はそれぞれ前にあるパターンの0個以またはは1個以上の繰り返し、‘:?’は前のパターンの0個または1個の繰り返しにマッチします。

たとえば以下はlongというキーワードの0個以上の繰り返しにマッチするパターンです。

(type_declaration "long" :*) @long-type

こちらはlongというキーワードをもつか、あるいはもたないかというタイプ宣言用のパターンです:

(type_declaration "long" :?) @long-type

グルーピング

正規表現におけるグループと同じように、パターンをグループにまとめたり量化演算子を適用することができます。たとえばカンマで区切られた識別子を表現するには、以下のように記述できるでしょう

(identifier) ("," (identifier)) :*

選択

繰り返しになりますが正規表現と同じように、パターンにおいて“これらのパターンのいずれかにマッチ”と表現することができます。この構文はパターンのベクターです。たとえばCのいくつかのキーワードをキャプチャーするパターンは、以下のように記述できるでしょう

[
  "return"
  "break"
  "if"
  "else"
] @keyword

アンカー

たとえば2つのオブジェクトを隣接させるといったように、アンカー演算子:anchorを用いて並置させることができます。2つの“オブジェクト”には2つのノードや子ノードと最後の親などを指定できます。たとえば最初最後の子、あるいは2つの隣接した子をキャプチャーするには:

;; 子と最後で親をアンカー
(compound_expression (_) @last-child :anchor)

;; 子と最初の親をアンカー
(compound_expression :anchor (_) @first-child)

;; 隣接する2つの子をアンカー
(compound_expression
 (_) @prev-child
 :anchor
 (_) @next-child)

並置させる際には無名ノードは無視されることに注意してください。

述語

パターンに述語による制約を追加することができます。たとえば以下のパターンでは:

(
 (array :anchor (_) @first (_) @last :anchor)
 (:equal @first @last)
)

tree-sitterは配列の最初と最後の要素が等しい場合だけマッチします。パターンに述語を付加するためには、それらをグループにまとめる必要があります。現在のところ:equal:match:predという3つの述語があります。

Predicate: :equal arg1 arg2

arg1arg2が等しければマッチ。引数は文字列またはキャプチャー名のいずれか。キャプチャー名とは、バッファーにおいてキャプチャーされたノードが跨ぐテキストを表す。

Predicate: :match regexp capture-name

バッファーにおいてcapture-nameのノードが跨ぐテキストと、文字列リテラルとして与えられた正規表現regexpがマッチすればマッチ。マッチは大文字小文字を区別する。

Predicate: :pred fn &rest nodes

関数fnnodes内のノードそれぞれを渡して非nilがリターンされたらマッチ。

述語が参照できるのは、同じパターン内に出現するキャプチャー名だけであることに注意してください。実際問題として別のパターンからキャプチャー名を参照しても、意味はほとんどありません。

文字列パターン

S式の他にも、Emacsでは使用するtree-sitterのネイティブクエリー構文を文字列として記述することができます。これはS式の構文とよく似ています。たとえば以下のクエリーは

(treesit-query-capture
 node '((addition_expression
         left: (_) @left
         "+" @plus-sign
         right: (_) @right) @addition

         ["return" "break"] @keyword))

以下と等価です

(treesit-query-capture
 node "(addition_expression
        left: (_) @left
        \"+\" @plus-sign
        right: (_) @right) @addition

        [\"return\" \"break\"] @keyword")

ほとんどのパターンは文字列内部のS式として直接記述できます。変更が必要になるのはごく少数のパターンだけです:

  • アンカー:anchorは‘.’と記述。
  • :?’は‘?’と記述。
  • :*’は‘*’と記述。
  • :+’は‘+’と記述。
  • :equal:match:predはそれぞれ#equal#match#predと記述。一般的には述語の‘:’を‘#’に変更する。

たとえば、

'((
   (compound_expression :anchor (_) @first (_) :* @rest)
   (:match "love" @first)
   ))

文字列形式では以下のように記述します

"(
  (compound_expression . (_) @first (_)* @rest)
  (#match \"love\" @first)
  )"

クエリーのコンパイル

繰り返し使うことを意図したクエリー、とりわけタイトなループ(訳注 :少ない命令を含み多数回実行されるループ)では、クエリーのコンパイルが重要になります。なぜならコンパイル済みのクエリーは、コンパイルされていないものと比較して非常に高速だからです。クエリーの使用が許されている場所ならどこでもコンパイル済みクエリーを使うことができます。

Function: treesit-query-compile language query

この関数はlanguagequeryをコンパイル済みクエリーオブジェクトにコンパイルして、それをリターンする。

この関数はqueryが不正な形式であればtreesit-query-errorエラーraiseする。シグナルデータには、その特定。エラーに関する説明が含まれている。クエリーの検証とデバッグにはtreesit-query-validateを使うことができる。

Function: treesit-query-language query

この関数はqueryの言語をリターンする。

Function: treesit-query-expand query

この関数はS式のqueryを文字列フォーマットに変換する。

Function: treesit-pattern-expand pattern

この関数はS式のpatternを文字列フォーマットに変換する。

パターンマッチングに関する詳細については、https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queriesにあるtree-sitterプロジェクトのドキュメントを参照してください。


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

37.6 複数言語ののパース

プログラミング言語のソースの一部に他の言語のソースが含まれているときがあります。一例としてはHTML + CSS + JavaScriptが挙げられます。このような場合には、別の言語によって記述されたテキストセグメントには別のパーサーを割り当てる必要があります。伝統的にこれはナローイングの使用によって達成されてきました。tree-sitterはナローイング(narrowingを参照)とともに機能しますが、推奨される方法はバッファーテキストのリージョン(範囲)にそれを操作するパーサーを指定する方法です。このセクションではパーサーにたいして範囲のセットや取得を行う関数について説明します。

Lispプログラムがバッファーでパーサーを使う前には、treesit-update-rangesの呼び出しによってパーサーそれぞれにたいする範囲が正しいか確認して、その位置にあるテキストにたいして任を負うパーサーを解決する必要があります。この2つの関数自身は作業を行わず、実際に作業を行うにはメジャーモードがtreesit-language-at-point-functionおよびtreesit-language-at-point-functionをセットする必要があります。これらの関数および変数については、このセクションの終わり近くで詳細に説明しましょう。

範囲の取得とセット

Function: treesit-parser-set-included-ranges parser ranges

この関数はrangesにたいして処理を行なうためにparserをセットアップする。parserが読み込むのは指定された範囲のテキストのみ。ranges内の範囲はそれぞれ(beg . end)という形式のペアーである。

rangesの範囲は、以下の疑似コードのように重複せず順番に並んでいなければならない。

(cl-loop for idx from 1 to (1- (length ranges))
         for prev = (nth (1- idx) ranges)
         for next = (nth idx ranges)
         should (<= (car prev) (cdr prev)
                    (car next) (cdr next)))

rangesがこの制約に違反したり、何か他の問題が発生した場合には、この関数はtreesit-range-invalidエラーをシグナルする。シグナルデータには特定のエラーメッセージ、セットを試みた範囲が含まれている。

この関数は範囲を無効にするためにも使うことができる。rangesnilの場合には、パーサーはバッファー全体をパースするようにセットされる。

例:

(treesit-parser-set-included-ranges
 parser '((1 . 9) (16 . 24) (24 . 25)))
Function: treesit-parser-included-ranges parser

この関数はparserにセットされている範囲をリターンする。リターン値はtreesit-parser-included-rangesranges引数と同じく(beg . end)という形式のコンスセルのリスト。parserが範囲を何ももっていなければリターン値はnil

(treesit-parser-included-ranges parser)
    ⇒ ((1 . 9) (16 . 24) (24 . 25))
Function: treesit-query-range source query &optional beg end

この関数はsourcequeryでマッチングしてキャプチャーされたノードをリターンする。リターン値は(beg . end)という形式のコンスセルのリスト。ここでbegendはそれぞれテキスト範囲の開始と終了をする。

利便性のためにsourceは言語シンボル、パーサー、あるいはノードでもよい。この関数はそれが言語シンボルならその言語を使用する最初のパーサーのルートノード、パーサーならそのパーサーのルートノード、ノードならそのノードでマッチを行なう。

引数queryはノードのキャプチャーに用いるクエリー(tree-sitterノードにたいするパターンマッチングを参照)。引数begendがどちらも非nilなら、それはこの関数がクエリーを行なう範囲を制限する。

他のクエリー関数と同じように、この関数はqueryが不正であればtreesit-query-errorエラーをraiseする。

Lispプログラムで複数言語をサポートするには

一般的なLispプログラムにおいて言語が複数ミックスされたプログラムをサポートするには、以下の2つの関数を呼び出すだけで十分です。

Function: treesit-update-ranges &optional beg end

この関数はバッファーのパーサーの範囲を更新する。この関数はパーサーの範囲がbegendの間に正しくセットされているかをtreesit-range-settingsに照らして確認する。省略された場合のデフォルトはbegがバッファー先頭、endがバッファー終端となる。

たとえばフォント表示(fontification)を行なう関数は、リージョン内のノードにクエリーを行う前にこの関数を使用する。

Function: treesit-language-at pos

この関数はバッファー位置posにあるテキストの言語をリターンする。その背後ではtreesit-language-at-point-functionを呼び出して、そのリターンされた値をリターンしている。treesit-language-at-point-functionnilの場合には、この関数はtreesit-parser-listのリターン値から最初のパーサーの言語をリターンする。バッファーにパーサーがなければnilをリターンする。

メジャーモードで複数の言語をサポートするには

ミックスされているかもしれない一連の言語では、ホスト言語(host language)と1つ以上の埋め込み言語(embedded languages)が存在することが珍しくありません。Lispプログラムはまずホスト言語のパーサーでドキュメント全体をパースすることで情報を得てから、それを用いて埋め込み言語の範囲をセット、その後に埋め込み言語をパースするのです。

HTMLCSS、それにJavaScriptを含むバッファーを例にとります。LispプログラムはまずHTMLパーサーでバッファー全体をパースして、それからパーサーにCSSとJavaScriptに相当するstyle_elementscript_elementのノードをクエリーするのです。その後にCSSとJavaScriptそれぞれにたいして、対応するノードが跨がる範囲をセットします。

シンプルなHTMLドキュメントが与えられると:

<html>
  <script>1 + 2</script>
  <style>body { color: "blue"; }</style>
</html>

LispプログラムはまずHTMLパーサーでパースを行い、それからCSSとJavaScriptそれぞれのパーサーにたいして範囲をセットします:

;; パーサーの作成
(setq html (treesit-parser-create 'html))
(setq css (treesit-parser-create 'css))
(setq js (treesit-parser-create 'javascript))

;; CSSの範囲をセット
(setq css-range
      (treesit-query-range
       'html
       '((style_element (raw_text) @capture))))
(treesit-parser-set-included-ranges css css-range)

;; JavaScriptの範囲をセット
(setq js-range
      (treesit-query-range
       'html
       '((script_element (raw_text) @capture))))
(treesit-parser-set-included-ranges js js-range)

treesit-update-rangesによってEmacsがこのプロセスを自動化します。treesit-update-rangesがプロセスを自動化する方法を解決するためには、複数言語のメジャーモードがtreesit-range-settingsをセットする必要があります。treesit-range-settingsに割り当てられる値を生成するためには、メジャーモードがヘルパー関数treesit-range-rulesを使う必要があります。この操作を直接コード化したのが以下のセッティング例になります。

(setq treesit-range-settings
      (treesit-range-rules
       :embed 'javascript
       :host 'html
       '((script_element (raw_text) @capture))

       :embed 'css
       :host 'html
       '((style_element (raw_text) @capture))))
Function: treesit-range-rules &rest query-specs

この関数はtreesit-range-settingsをセットするために用いる。クエリーのコンパイルやその他の後処理に注意を払い、treesit-range-settingsにセットできるような値を出力する。

この関数は引数として一連のquery-specを受け取る。ここでquery-specとは0個以上のkeyword/valueペアーが前置されたqueryのこと。queryはそれぞれ文字列、S式、コンパイル済みフォーム、あるいは関数のいずれかによるtree-sitterクエリーである。

queryがtree-sitterクエリーなら:keyword/valueのペアーを2つを前置すること(:keyword:embedは埋め込み言語、:hostはホスト言語)。

treesit-update-rangesは埋め込み言語用のパーサーにたいして範囲をセットする方法の解決にqueryを使用する。ホスト言語パーサーにqueryを問い合わせてキャプチャーされたノードが跨ぐ範囲を計算、それらの範囲を埋め込み言語パーサーに適用するのである。

queryが関数の場合にはkeywordvalueのペアーは必要ない。関数の場合にはstartendという2つの引数を受け取り、カレントバッファーでstartendの間にあるリージョンでパーサー用の範囲をセットすること。その関数がstartendの間のリージョンを包むような広いリージョンに範囲をセットしても問題はない。

Variable: treesit-range-settings

これはバッファーでtreesit-update-rangesがパーサーにたいする範囲を更新する際の助けとなる変数である。settingのリストであり、その正確なフォーマットは内部的な使用を意図している。この変数が保持できる値を生成するにはtreesit-range-rulesを使うこと。

Variable: treesit-language-at-point-function

この変数の値はバッファー位置posを単一の引数として受け取り、posにあるテキストの言語をリターンする関数であること。この変数はtreesit-language-atにより使用される。


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

37.7 tree-sitterを用いるメジャーモードの開発

このセクションではメジャーモード用にtree-sitterを統合した開発における一般的なガイドラインの一部について説明します。

tree-sitter機能をサポートするメジャーモードは、大枠では以下のようなパターンにしたがう必要があります:

(define-derived-mode woomy-mode prog-mode "Woomy"
  "A mode for Woomy programming language."
  (when (treesit-ready-p 'woomy)
    (setq-local treesit-variables ...)
    ...
    (treesit-major-mode-setup)))

treesit-ready-pはtree-sitterを有効にする条件が揃っていなければ、自動的に警告を発します。

tree-sitterを使うメジャーモードは、その“ネイティブ”な相手先モードとセットアップを共有する場合には、以下のように共通のセットアップを含んだ“ベースモード”を作成することができます:

(define-derived-mode woomy--base-mode prog-mode "Woomy"
  "An internal mode for Woomy programming language."
  (common-setup)
  ...)

(define-derived-mode woomy-mode woomy--base-mode "Woomy"
  "A mode for Woomy programming language."
  (native-setup)
  ...)

(define-derived-mode woomy-ts-mode woomy--base-mode "Woomy"
  "A mode for Woomy programming language."
  (when (treesit-ready-p 'woomy)
    (setq-local treesit-variables ...)
    ...
    (treesit-major-mode-setup)))
Function: treesit-ready-p language &optional quiet

この関数はtree-sitterをアクティブにするための条件をチェックする。tree-sitterとともにEmacsがビルドされているか、tree-sitterが処理するにあたってカレントバッファーのサイズが大き過ぎないか、そのシステムでlanguageにたいするグラマー(Tree-sitter Language Grammarを参照)が利用できるかどうかをチェックする。

この関数はtree-sitterをアクティブにできなければ警告を発する。quietmessageなら、警告をメッセージに変更する。quiettの場合には警告やメッセージは何も表示されない。

この関数は必要とされる条件すべてが適えば非nil、そうでなければnilをリターンする。

Function: treesit-major-mode-setup

この関数はメジャーモードにたいしてtree-sitterに一部機能をアクティブにする。

現在のところ以下の機能のセットアップを行う:

  • treesit-font-lock-settings (パーサーベースのFont Lockを参照)が非nilならフォント表示(fontification)をセットアップ。
  • treesit-simple-indent-rules (パーサーベースのインデントを参照)が非nilならインデントをセットアップ。
  • treesit-defun-type-regexpが非nilなら、beginning-of-defunend-of-defunにたいしてナビゲーション関数をセットアップ。
  • treesit-defun-name-functionが非nilなら、add-log-current-defunによって使用されるadd-log関数をセットアップ。
  • treesit-simple-imenu-settingsが非nilならImenuをセットアップ。

これらtree-sitter組み込み機能の詳細についてはパーサーベースのFont Lockパーサーベースのインデント釣り合いのとれたカッコを越えた移動を参照してください。

メジャーモードにおける複数言語のミックスのサポートについては複数言語ののパースを参照してください。

beginning-of-defunend-of-defunの他にも、Emacsはdefunにたいして処理を行う追加の関数をいくつか提供します。treesit-defun-at-pointはポイント位置のdefunノード、treesit-defun-nameはdefunノードの名前をリターンする関数です。

Function: treesit-defun-at-point

この関数はポイント位置のdefunノードを、defunが見つからなければnilをリターンする。この関数はtreesit-defun-tacticに注意を払う。この変数の値がtop-levelならトップレベルのdefunを、値がnestedならすぐ外側のdefunをリターンする。

この関数が機能するためにはtreesit-defun-type-regexpが必要となる。この変数の値がnilであれば、この関数は単にnilをリターンする。

Function: treesit-defun-name node

この関数はnodeのdefun名をリターンする。nodeにたいするdefun名が存在しない、nodeがdefunノードではない、あるいはnodenilの場合はnilをリターンする。

言語とメジャーモードに応じて関数、クラス、構造体等の名前がdefun名となる。

treesit-defun-name-functionnilの場合には、この関数は常にnilをリターンする。

Variable: treesit-defun-name-function

この変数の値が非nilの場合には、ノードを引数として呼び出されてそのノードの名前をリターンする関数であること。この関数は意味合いとしてはtreesit-defun-nameと同じである必要がある。つまりそのノードがdefunノードではない、defunノードだが名前がない、あるいはノードがnilの場合にはnilをリターンすること。


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

37.8 tree-sitterのC APIとの対応表

Emacsのtree-sitter統合では、tree-sitterのCのAPIによって提供されるすべての機能が公開されている訳ではありません。欠落している機能には以下が含まれます:

  • ツリーカーソル(tree cursor)の作成、およびそれを用いた構文ツリーのナビゲーション。
  • パーサーにたいするタイムアウトおよびキャンセルのフラグのセッティング。
  • パーサー用のロガー(logger: ログ機能)のセッティング。
  • DOTグラフによるファイルへの構文ツリーのプリント。
  • 構文ツリーのコピーや変更(Emacsではツリーオブジェクトは非公開)。
  • 位置としての座標(行と列)の使用。
  • 変更によるノードの更新(Emacsでは既存ノードは更新せずに新たにノードを取得)。
  • 言語グラマーの統計問い合わせ。

更にEmacsでは、APIがより使いやすく慣れ親しんだ用語を用いるようにCのAPIの一部を変更しています:

  • Emacs LispのAPIではバイト位置ではなく文字位置を使用。
  • Nullノードをnilに変換。

CのすべてのAPIとELisp側での相方の対応を以下にまとめました。1つのElispがCの複数の関数に対応する場合もあるし、Elisp側の相方がいないC関数も沢山あります。

ts_parser_new                           treesit-parser-create
ts_parser_delete
ts_parser_set_language
ts_parser_language                      treesit-parser-language
ts_parser_set_included_ranges           treesit-parser-set-included-ranges
ts_parser_included_ranges               treesit-parser-included-ranges
ts_parser_parse
ts_parser_parse_string                  treesit-parse-string
ts_parser_parse_string_encoding
ts_parser_reset
ts_parser_set_timeout_micros
ts_parser_timeout_micros
ts_parser_set_cancellation_flag
ts_parser_cancellation_flag
ts_parser_set_logger
ts_parser_logger
ts_parser_print_dot_graphs
ts_tree_copy
ts_tree_delete
ts_tree_root_node
ts_tree_language
ts_tree_edit
ts_tree_get_changed_ranges
ts_tree_print_dot_graph
ts_node_type                            treesit-node-type
ts_node_symbol
ts_node_start_byte                      treesit-node-start
ts_node_start_point
ts_node_end_byte                        treesit-node-end
ts_node_end_point
ts_node_string                          treesit-node-string
ts_node_is_null
ts_node_is_named                        treesit-node-check
ts_node_is_missing                      treesit-node-check
ts_node_is_extra                        treesit-node-check
ts_node_has_changes
ts_node_has_error                       treesit-node-check
ts_node_parent                          treesit-node-parent
ts_node_child                           treesit-node-child
ts_node_field_name_for_child            treesit-node-field-name-for-child
ts_node_child_count                     treesit-node-child-count
ts_node_named_child                     treesit-node-child
ts_node_named_child_count               treesit-node-child-count
ts_node_child_by_field_name             treesit-node-child-by-field-name
ts_node_child_by_field_id
ts_node_next_sibling                    treesit-node-next-sibling
ts_node_prev_sibling                    treesit-node-prev-sibling
ts_node_next_named_sibling              treesit-node-next-sibling
ts_node_prev_named_sibling              treesit-node-prev-sibling
ts_node_first_child_for_byte            treesit-node-first-child-for-pos
ts_node_first_named_child_for_byte      treesit-node-first-child-for-pos
ts_node_descendant_for_byte_range       treesit-node-descendant-for-range
ts_node_descendant_for_point_range
ts_node_named_descendant_for_byte_range treesit-node-descendant-for-range
ts_node_named_descendant_for_point_range
ts_node_edit
ts_node_eq                              treesit-node-eq
ts_tree_cursor_new
ts_tree_cursor_delete
ts_tree_cursor_reset
ts_tree_cursor_current_node
ts_tree_cursor_current_field_name
ts_tree_cursor_current_field_id
ts_tree_cursor_goto_parent
ts_tree_cursor_goto_next_sibling
ts_tree_cursor_goto_first_child
ts_tree_cursor_goto_first_child_for_byte
ts_tree_cursor_goto_first_child_for_point
ts_tree_cursor_copy
ts_query_new
ts_query_delete
ts_query_pattern_count
ts_query_capture_count
ts_query_string_count
ts_query_start_byte_for_pattern
ts_query_predicates_for_pattern
ts_query_step_is_definite
ts_query_capture_name_for_id
ts_query_string_value_for_id
ts_query_disable_capture
ts_query_disable_pattern
ts_query_cursor_new
ts_query_cursor_delete
ts_query_cursor_exec                    treesit-query-capture
ts_query_cursor_did_exceed_match_limit
ts_query_cursor_match_limit
ts_query_cursor_set_match_limit
ts_query_cursor_set_byte_range
ts_query_cursor_set_point_range
ts_query_cursor_next_match
ts_query_cursor_remove_match
ts_query_cursor_next_capture
ts_language_symbol_count
ts_language_symbol_name
ts_language_symbol_for_name
ts_language_field_count
ts_language_field_name_for_id
ts_language_field_id_for_name
ts_language_symbol_type
ts_language_version

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

38 abbrevとabbrev展開

略語(abbreviationまたはabbrevは、より長い文字列へと展開される文字列です。ユーザーはabbrev文字列を挿入して、それを探して自動的にabbrevの展開形に置換できます。これによりタイプ量を節約できます。

カレントで効果をもつabbrevsのセットはabbrevテーブル(abbrev table)内に記録されます。バッファーはそれぞれローカルにabbrevテーブルをもちますが、通常は同一のメジャーモードにあるすべてのバッファーが1つのabbrevテーブルを共有します。グローバルabbrevテーブルも存在します。通常は両者が使用されます。

abbrevテーブルはobarrayとして表されます。obarraysについての情報はシンボルの作成とinternを参照してください。abbrevはそれぞれobarray内のシンボルとして表現されます。そのシンボルの名前がabbrevであり、値が展開形になります。シンボルの関数定義は展開を行うフック関数です(abbrevの定義を参照)。またシンボルのプロパティセルには使用回数やそのabbrevが展開された回数を含む、さまざまな追加プロパティが含まれます(abbrevプロパティを参照)。

システムabbrev(system abbrevs)と呼ばれる特定のabbrevは、ユーザーではなくメジャーモードにより定義されます。システムabbrevは非nil:systemプロパティにより識別されます(abbrevプロパティを参照)。abbrevがabbrevファイルに保存される際には、システムabbrevは省略されます。ファイルへのabbrevの保存を参照してください。

abbrevに使用されるシンボルは通常のobarrayにinternされないので、Lisp式の読み取り結果として現れることは決してありません。実際のところ通常はabbrevを扱うコードを除いて、それらが使用されることはありません。したがってそれらを非標準的な方法で使用しても安全なのです。

マイナーモードであるAbbrevモードが有効な場合には、バッファーローカル変数abbrev-modeは非nilとなり、そのバッファー内でabbrevは自動的に展開されます。abbrev用のユーザーレベルのコマンドについてはAbbrev Mode in The GNU Emacs Manualを参照してください。


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

38.1 abbrevテーブル

このセクションではabbrevテーブルの作成と操作を行う方法について説明します。

Function: make-abbrev-table &optional props

この関数は空のabbrevテーブル(シンボルを含まないobarray)を作成してリターンする。これは0で充填されたベクター。propsは新たなテーブルに適用されるプロパティリスト(abbrevテーブルのプロパティを参照)。

Function: abbrev-table-p object

この関数はobjectがabbrevテーブルなら非nilをリターンする。

Function: clear-abbrev-table abbrev-table

この関数はabbrev-table内のabbrevをすべて未定義として空のまま残す。

Function: copy-abbrev-table abbrev-table

この関数はabbrev-tableのコピー(同じabbrev定義を含む新たなabbrevテーブル)をリターンする。これは名前、値、関数だけをコピーしてプロパティリストは何もコピーしない

Function: define-abbrev-table tabname definitions &optional docstring &rest props

この関数はabbrevテーブル名(値がabbrevテーブルであるような変数)としてtabname (シンボル)を定義する。これはそのテーブル内にdefinitionsに応じて、abbrevを定義する。definitions(abbrevname expansion [hook] [props...])という形式の要素をもつリスト。これらの要素は引数としてdefine-abbrevに渡される。

オプション文字列docstringは変数tabnameのドキュメント文字列。プロパティリストpropsはabbrevテーブルに適用される(abbrevテーブルのプロパティを参照)。

同一のtabnameにたいしてこの関数が複数回呼び出されれると、元のコンテンツ全体を上書きせずに後続の呼び出しはdefinitions内の定義をtabnameに追加する(後続の呼び出しではdefinitions内で明示的に再定義または未定義にした場合のみabbrevを上書きできる)。

Variable: abbrev-table-name-list

これは値がabbrevテーブルであるようなシンボルのリスト。define-abbrev-tableはこのリストに新たなabbrevテーブル名を追加する。

Function: insert-abbrev-table-description name &optional human

この関数はポイントの前に名前がnameのabbrevテーブルの説明を挿入する。引数nameは値がabbrevテーブルであるようなシンボル。

humanが非nilなら人間向けの説明になる。システムabbrevはそのようにリストされて識別される。それ以外なら説明はLisp式(カレントで定義されているようにnameを定義するがシステムabbrevとしては定義しないようなdefine-abbrev-table呼び出し)となる(nameを使用するモードまたはパッケージはそれらを個別にnameに追加すると想定されている)。


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

38.2 abbrevの定義

define-abbrevはabbrevテーブル内にabbrevを定義するための基本的な低レベル関数です。

メジャーモードがシステムabbrevを定義する際には、:systemプロパティにtを指定してdefine-abbrevを呼び出すべきです。すべての保存された非システムabbrevは起動時(何らかのメジャーモードがロードされる前)にリストアされることに注意してください。したがってメジャーモードは最初にそのモードがロードされた際には、それらのモードのabbrevテーブルが空であると仮定するべきではありません。

Function: define-abbrev abbrev-table name expansion &optional hook &rest props

この関数はabbrev-table内にnameという名前でexpansionに展開されて、hookを呼び出すabbrevをプロパティprops (abbrevプロパティを参照)とともに定義する。リターン値はname。ここではprops内の:systemプロパティは特別に扱われる。このプロパティが値forceをもつなら、たとえ同じ名前の非システムabbrevでも既存の定義を上書きするだろう。

nameは文字列であること。引数expansionは通常は望む展開形(文字列)であり、nilならそのabbrevを未定義とする。これが文字列またはnil以外の何かなら、そのabbrevはhookを実行することにより単に展開される。

引数hookは関数またはnilであること。hookが非nilならabbrevがexpansionに置換された後に引数なしでそれが呼び出される。hook呼び出しの際にはポイントはexpansionの終端に配置される。

hookno-self-insertプロパティが非nilであるような非nilのシンボルなら、hookは展開をトリガーするような自己挿入入力文字を挿入できるかどうかを明示的に制御できる。この場合には、hookが非nilをリターンしたらその文字の挿入を抑止する。対照的にhooknilをリターンしたら、あたかも実際には展開が行われなかったかのようにexpand-abbrev (またはabbrev-insert)もnilをリターンする。

define-abbrevは実際にabbrevを変更した場合には、通常は変数abbrevs-changedtをセットする。これはいくつかのコマンドがabbrevの保存を提案するためである。いずれにせよシステムabbrevは保存されないので、システムabbrevにたいしてこれは行われない。

User Option: only-global-abbrevs

この変数が非nilなら、それはユーザーがグローバルabbrevのみの使用を計画していることを意味する。これはモード固有のabbrevを定義するコマンドにたいして、かわりにグローバルabbrevを定義するよう指示する。この変数はこのセクション内の関数の振る舞いを変更しない。それは呼び出し側により検証される。


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

38.3 ファイルへのabbrevの保存

abbrev定義が保存されたファイルは実際にはLispコードのファイルです。abbrevは同じコンテンツの同じabbrevテーブルを定義するLispプログラムの形式で保存されます。したがってそのファイルはloadによってロードすることができます(プログラムがロードを行う方法を参照)。しかしより簡便なインターフェースとして関数quietly-read-abbrev-fileが提供されています。Emacsは起動時に自動的にこの関数を呼び出します。

save-some-buffersのようなユーザーレベルの機能は、ここで説明する変数の制御下で自動的にabbrevをファイルに保存できます。

User Option: abbrev-file-name

これはabbrevの読み込みと保存にたいするデフォルトのファイル名。デフォルトではEmacsは~/.emacs.d/abbrev_defsを探して、見つからなければ~/.abbrev_defsを探して、いずれにもファイルが存在しなければ~/.emacs.d/abbrev_defsを作成する。

Function: quietly-read-abbrev-file &optional filename

この関数は以前にwrite-abbrev-fileで書き込まれたfilenameという名前のファイルからabbrevの定義を読み込む。filenameが省略またはnilならabbrev-file-name内で指定されているファイルが使用される。

関数の名前が暗示するようにこの関数は何のメッセージも表示しない。

User Option: save-abbrevs

save-abbrevsにたいする非nil値はファイル保存時に、(もし何か変更されていれば)Emacsがabbrevの保存を提案するべきであることを意味する。値がsilentlyならEmacsはユーザーに尋ねることなくabbrevを保存する。abbrev-file-nameはabbrevを保存するファイルを指定する。デフォルト値はt

Variable: abbrevs-changed

この変数はabbrev(システムabbrevを除く)の定義や変更によりセットされる。さまざまなEmacsコマンドにとって、これはユーザーにabbrevの保存を提案するためのフラグとしての役目をもつ。

Command: write-abbrev-file &optional filename

abbrev-table-name-list内にリストされたすべてのabbrevテーブルにたいして、ロード時に同じabbrevを定義するであろうLispプログラム形式で、すべてのabbrev定義(システムabbrevを除く)をファイルfilename内に保存する。保存すべきabbrevがないテーブルは省略する。filenamenilならabbrev-file-nameが使用される。この関数はnilをリターンする。


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

38.4 略語の照会と展開

abbrevは通常はself-insert-commandを含む特定のinteractiveなコマンドにより展開されます。このセクションではそのようなコマンドの記述に使用されるサブルーチン、並びに通信のために使用される変数について説明します。

Function: abbrev-symbol abbrev &optional table

この関数はabbrevという名前のabbrevを表すシンボルをリターンする。そのabbrevが定義されていなければnilをリターンする。オプションの2つ目の引数tableはそれを照合するためのabbrevテーブル。tablenilならこの関数はまずカレントバッファーのローカルabbrevテーブル、次にグローバルabbrevテーブルを試みる。

Function: abbrev-expansion abbrev &optional table

この関数はabbrevが展開されるであろう文字列(カレントバッファーにたいして使用されるabbrevテーブルで定義される文字列)をリターンする。これはabbrevが有効なabbrevでなければnilをリターンする。オプション引数tableabbrev-symbolの場合と同じように使用するabbrevテーブルを指定する。

Command: expand-abbrev

このコマンドは、(もしあれば)ポイントの前のabbrevを展開する。ポイントがabbrevの後になければこのコマンドは何もしない。展開を行うためにこれは変数abbrev-expand-functionの値となっている関数を引数なしで呼び出して、何であれその関数がリターンしたものをリターンする。

デフォルトの展開関数は展開を行ったらabbrevのシンボル、それ以外はnilをリターンする。そのabbrevシンボルがno-self-insertプロパティが非nilのシンボルであるようなフック関数をもち、そのフック関数が値としてnilをリターンした場合には、たとえ展開が行われたとしてもデフォルト展開関数はnilをリターンする。

Function: abbrev-insert abbrev &optional name start end

この関数はstartendの間のテキストを置換することによりabbrevのabbrev展開形を挿入する。startが省略された場合のデフォルトはポイント。nameが非nilなら、それはこのabbrevが見つかった名前(文字列)であること。これは展開形のcapitalizationを調整するかどうかを判断するために使用される。この関数はabbrevの挿入に成功したらabbrev、それ以外はnilをリターンする。

Command: abbrev-prefix-mark &optional arg

このコマンドはポイントのカレント位置をabbrevの開始としてマークする。expand-abbrevの次回呼び出しでは、通常のように以前の単語ではなく、ここからポイント(その時点での位置)にあるテキストが展開するべきabbrevとして使用される。

このコマンドは、まずargnilならポイントの前の任意のabbrevを展開する(インタラクティブな呼び出しではargはプレフィクス引数)。それから展開する次のabbrevの開始を示すためにポイントの前にハイフンを挿入する。実際の展開ではハイフンは削除される。

User Option: abbrev-all-caps

これが非nilにセットされているときは、すべて大文字で入力されたabbrevはすべて大文字を使用して展開される。それ以外ならすべて大文字で入力されたabbrevは、展開形の単語ごとにcapitalizeして展開される。

Variable: abbrev-start-location

この変数の値は次にabbrevを展開する開始位置としてexpand-abbrevに使用されるバッファー位置。値はnilも可能であり、それはかわりにポイントの前の単語を使用することを意味する。abbrev-start-locationexpand-abbrevの呼び出しごとに毎回nilにセットされる。この変数はabbrev-prefix-markからもセットされる。

Variable: abbrev-start-location-buffer

この変数の値はabbrev-start-locationがセットされたバッファー。他のバッファーでabbrev展開を試みることによりabbrev-start-locationはクリアーされる。この変数はabbrev-prefix-markによりセットされる。

Variable: last-abbrev

これは直近のabbrev展開のabbrev-symbol。これはunexpand-abbrevコマンド(Expanding Abbrevs in The GNU Emacs Manualを参照)のためにexpand-abbrevにより残された情報である。

Variable: last-abbrev-location

これは直近の.abbrev展開の場所。これにはunexpand-abbrevコマンドのためにexpand-abbrevにより残された情報が含まれる。

Variable: last-abbrev-text

これは直近のabbrev展開の正確な展開形を、(もしあれば)大文字小文字変換した後のテキストである。そのabbrevがすでに非展開されていれば値はnil。これにはunexpand-abbrevコマンドのためにexpand-abbrevga残sita情報が含まれる。

Variable: abbrev-expand-function

この変数の値は展開を行うためにexpand-abbrevが引数なしで呼び出すであろう関数。この関数では展開を行う前後に行いたいことを行うことができる。展開が行われた場合にはそのabbrevシンボルをリターンすること。

以下のサンプルコードではabbrev-expand-functionのシンプルな使い方を示します。このサンプルではfoo-modeが‘#’で始まる行がコメントであるような特定のファイルを編集するためのモードであるとします。それらコメント行にたいしてはTextモードのabbrevの使用が望ましく、その他すべての行にたいしては正規のローカルabbrevテーブルfoo-mode-abbrev-tableが適しています。local-abbrev-tabletext-mode-abbrev-tableの定義については、標準abbrevテーブルを参照してください。add-functionについての詳細はEmacs Lisp関数にたいするアドバイスを参照してください。

(defun foo-mode-abbrev-expand-function (expand)
  (if (not (save-excursion (forward-line 0) (eq (char-after) ?#)))
      ;; 通常の展開を行う
      (funcall expand)
    ;; コメント内はtext-modeのabbrevを使用
    (let ((local-abbrev-table text-mode-abbrev-table))
      (funcall expand))))

(add-hook 'foo-mode-hook
          (lambda ()
            (add-function :around (local 'abbrev-expand-function)
                          #'foo-mode-abbrev-expand-function)))

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

38.5 標準abbrevテーブル

以下はEmacsの事前ロードされるメジャーモード用のabbrevテーブルを保持する変数のリストです。

Variable: global-abbrev-table

これはモードに非依存なabbrev用のabbrevテーブル。この中で定義されるabbrevはすべてのバッファーに適用される。各バッファーはローカルabbrevテーブルももつかもしれず、それのabbrev定義はグローバルテーブル内のabbrev定義より優先される。

Variable: local-abbrev-table

このバッファーローカル変数の値はカレントバッファーの(モード固有な)abbrevテーブルである。これはそのようなテーブルのリストでもあり得る。

Variable: abbrev-minor-mode-table-alist

この変数の値は(mode . abbrev-table)という形式のリスト。ここでmodeは変数の名前。その変数が非nilにバインドされていればabbrev-tableはアクティブ、それ以外なら無視される。abbrev-tableはabbrevテーブルのリストでもあり得る。

Variable: fundamental-mode-abbrev-table

これはFundamentalモードで使用されるローカルabbrevテーブル。言い換えるとこれはFundamentalモードにあるすべてのバッファーのローカルabbrevテーブルである。

Variable: text-mode-abbrev-table

これはTextモードで使用されるローカルabbrevテーブル。

Variable: lisp-mode-abbrev-table

これはLispモードで使用されるローカルabbrevテーブルであり、Emacs Lispモードで使用されるローカルabbrevテーブルの親テーブル。abbrevテーブルのプロパティを参照のこと。


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

38.6 abbrevプロパティ

abbrevはプロパティをもち、それらのいくつかはabbrevの働きに影響します。これらのプロパティをdefine-abbrevの引数として提供して以下の関数で操作できます:

Function: abbrev-put abbrev prop val

abbrevのプロパティpropに値valをセットする。

Function: abbrev-get abbrev prop

abbrevのプロパティprop、そのabbrevがそのようなプロパティをもたなければnilをリターンする。

以下のプロパティには特別な意味があります:

:count

このプロパティはそのabbrevが展開された回数を計数する。明示的にセットしなければdefine-abbrevにより0に初期化される。

:system

nilならこのプロパティはシステムabbrevとしてそのabbrevをマスクする。そのようなabbrevは保存されない(ファイルへのabbrevの保存を参照)。

:enable-function

nilの場合には、そのabbrevが使用されるべきでなければnil、それ以外ならtをリターンするような引数なしの関数であること。

:case-fixed

nilなら、このプロパティはそのabbrevのcase(大文字小文字)には意味があり、同じパターンにcapitalizeされたテキストだけにマッチすべきことを示す。これは展開のcapitalizationを変更するコードも無効にする。


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

38.7 abbrevテーブルのプロパティ

abbrevと同じようにabbrevテーブルもプロパティをもち、それらのいくつかはabbrevテーブルの働きに影響を与えます。これらのプロパティをdefine-abbrev-tableの引数として提供して、それらを関数で操作できます:

Function: abbrev-table-put table prop val

abbrevテーブルtableのプロパティpropに値valをセットする。

Function: abbrev-table-get table prop

abbrevテーブルのプロパティprop、abbrevテーブルtableがそのようなをプロパティもたなければnilをリターンする。

以下のプロパティには特別な意味があります:

:enable-function

abbrevプロパティ:enable-functionと似ているが、そのテーブル内のすべてのabbrevに適用される点が異なる。これはポイントの前のabbrevを探すことを試みる前にも使用されるのでabbrevテーブルを動的に変更することが可能。

:case-fixed

これはabbrevプロパティ:case-fixedと似ているが、そのテーブル内のすべてのabbrevに適用される点が異なる。

:regexp

nilなら、このプロパティはそのテーブルを照合する前にポイント前のabbrev名を抽出するための方法を示す正規表現。その正規表現がポイントの前にマッチしたときは、そのabbrev名はsubmatchの1と期待される。このプロパティがnilならデフォルトはbackward-wordforward-wordを使用してabbrevの名前を探す。このプロパティにより単語構文以外の文字を含む名前のabbrevが使用できる。

:parents

このプロパティは他のabbrevを継承したテーブルのリストを保持する。

:abbrev-table-modiff

このプロパティはそのテーブルにabbrevが追加される度に増分されるカウンターを保持する。


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

39 スレッド

Emacs Lispはスレッド(thread)と呼ばれる限定的な並行性(concurrency)の形式を提供します。Emacsの与えられたインターフェース内のすべてのスレッドは同じメモリーを共有します。Emacs Lisp内の並行性は“概ね協調的(mostly cooperative)”であり、これはEmacsがスレッド間の実効を明確に定義された時間にだけ切り替えることを意味しています。しかしEmacsでのスレッドのサポートは将来よりきめの細かい並行性が可能な方法でデザインされており、正しいプログラムは協調的なスレッドに依存するべきではありません。

現在のところスレッドの切り替えはキーボード入力や非同期プロセスからの出力の待機中(つまりaccept-process-outputの間)、ミューテックスのロックやthread-joinのようなスレッドに関連するブロッキング処理の間での、thread-yieldを介した明示的な要求時に発生します。

Emacs Lispはスレッドの作成や制御、さらにスレッドの同期に有用なミューテックスや条件変数の作成や制御を行うプリミティブを提供します。

グローバル変数はEmacs Lispのすべてのスレッドの間で共有されますがローカル変数(letによるダイナミックなバインドはローカル)は異なります。スレッドはそれぞれ自身のカレントバッファー(カレントバッファーを参照)と自身のマッチデータ(マッチデータを参照)を所有します。

letによるバイディングはEmacs Lisp実装により特別に処理されることに注意してください。letの使う以外にこのunwind(巻き戻し)とrewind(巻き戻すための巻き取り)の振る舞いを複製する方法はありません。たとえばunwind-protectを使用してletの独自実装で記述しても変数値をスレッド固有にアレンジすることはできません。

レキシカルバインディング(変数のバインディングのスコーピングルールを参照)の場合には他のEmacs Lispオブジェクト類似するものはクロージ(closure)です。クロージャ内のバインディングはクロージャを呼び出したすべてのスレッド間で共有されます。


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

39.1 基本的なスレッド関数

スレッドを作成したり待機することができます。スレッドを直接exitすることはできませんがカンレントスレッドは暗黙にexitでき、他のスレッドはシグナルを受け取ることができます。

Function: make-thread function &optional name

functionを呼び出す新たなスレッドの実行を作成する。functionのリターン時にスレッドはexitする。

新たなスレッドは効力をもつローカル変数のバインディングが何もない状態で作成される。新たなスレッドのカレントバッファーはカレントスレッドから継承される。

nameでスレッドに名前を与えることができる。これはデバッグと情報的な用途だけに使用される名前であり、Emacsにとって意味はない。nameを与える場合には文字列でなければならない。

この関数は新たなスレッドをリターンする。

Function: threadp object

この関数はobjectがEmacsスレッドを表すならt、それ以外はnilをリターンする。

Function: thread-join thread

threadがexitするかカレントスレッドがシグナルされるまでブロックする。これはthread関数の結果をリターンする。threadがexit済みなら即座にリターンする。

Function: thread-signal thread error-symbol data

signal (エラーをシグナルする方法を参照)と同様だがシグナルはスレッドthreadに送信される。threadがカレントスレッドなら、即座にsignalを呼び出す。それ以外ならthreadがカレントになり次第、シグナルを受信する。mutex-lockcondition-waitthread-joinの呼び出しによりthreadがブロックされていたらthread-signalがロックを解除する。

threadがメインスレッドならシグナルは伝播されない。かわりにメインスレッド内のメッセージとして表れる。

Function: thread-yield

実行可能な次のスレッドに実行を譲り渡す。

Function: thread-name thread

make-threadで指定されたthreadの名前をリターンする。

Function: thread-live-p thread

threadが生きていればt、それ以外はnilをリターンする。スレッドは自身の関数がまだ実行中なら生きている。

Function: thread--blocker thread

threadが待機中のオブジェクトをリターンする。これは主にデバッグを糸した関数であり、それを示すために“2重ハイフン”の名前を付与してある。

threadthread-join内でブロックされていたら待機対象のスレッドをリターンする。

threadmutex-lock内でブロックされていたらミューテックスをリターンする。

threadcondition-wait内でブロックされていたら条件変数をリターンする。

それ以外ならnilをリターンする。

Function: current-thread

カレントスレッドをリターンする。

Function: all-threads

すべての生きたスレッドオブジェクトのリストをリターンする。呼び出しそれぞれにたいして新たなリストをリターンする。

Variable: main-thread

この変数はEmacs実行中のメインスレッド、スレッドサポートなしでEmacsコンパイル時にはnilを保持する。

スレッドが実行したコードがハンドルされないエラーをシグナルすると、そのスレッドはexitします。それ以外のスレッドは以下の関数を使用してスレッドのexitを誘発したエラーフォームにアクセスできます。

Function: thread-last-error &optional cleanup

この関数はエラーによりスレッドがexitした際に記録された最後のエラーフォームをリターンする。異常終了(abnormal exit)した各スレッドが、以前にスレッドエラーで格納されたフォームを新たな値に上書きするので、アクセスできるのは最後のフォームのみ。cleanupが非nilなら格納されたフォームをnilにリセットする。


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

39.2 ミューテックス

ミューテックス(mutex)は排他的なロックです。任意のタイミングにおいて0、または1つのスレッドがミューテックスを所有できます。スレッドがミューテックスの取得を試みたときに別スレッドがすでにそのミューテックスを所有していたら、ミューテックスが利用可能になるまで取得を試みたスレッドはブロックされます。

Emacs Lispのミューテックスは再帰的(recursive)と呼ばれるタイプです。これはスレッドがミューテックスを何回も再帰的に所有できることを意味します。ミューテックスは所有された回数を保持していて、それら所有のそれぞれがリリースとペアになっていなければなりません。スレッドによるミューテックスの最後のリリースによりミューテックスは他のスレッドが潜在的に所有可能である非所有な状態へとリバートされます。

Function: mutexp object

この関数はobjectがEmacsのミューテックスを表していればt、それ以外はnilをリターンする。

Function: make-mutex &optional name

新たなミューテックスを作成してリターンする。nameが指定されたらミューテックスの名前として与えられる(文字列でなければならない)。これはデバッグにたいする用途のみの名前でありEmacsにとって意味はない。

Function: mutex-name mutex

make-mutexで指定されたmutexの名前をリターンする。

Function: mutex-lock mutex

これはスレッドがmutexを所有するか、スレッドがthread-signalの使用によりシグナルされるまでブロックする。スレッドがmutexをすでに所有していたら単にリターンする。

Function: mutex-unlock mutex

mutexをリリースする。そのスレッドがmutexを所有していなければエラーをシグナルする。

Macro: with-mutex mutex body…

このマクロはもっともシンプルかつ安全にミューテックスを保持しつつフォームを評価する方法である。これはmutexを取得してbodyを呼び出してからmutexをリリースする。bodyの結果をリターンする。


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

39.3 条件変数

条件変数(condition variable)は何らかのイベントが発生するまでスレッドをブロックするための手段です。スレッドは別のスレッドが条件を通知した際に目覚めるように条件変数を待機できます。

条件変数はミューテックス、および概念的に何らかの条件に関連付けられます。正しく操作するために、ミューテックスを所有してから待機スレッドはループして、条件のテストを行い条件変数を待機しなければなりません。たとえば:

(with-mutex mutex
  (while (not global-variable)
    (condition-wait cond-var)))

ミューテックスはアトミック操作のために、ループは堅牢性のためのものです。これは偽の通知があるかもしれないからです。

同様にミューテックスは条件の通知前に所持されていなければなりません。ミューテックスを所有して条件に関連する変更を行い、それを通知するのが典型的かつ最良なアプローチです:

(with-mutex mutex
  (setq global-variable (some-computation))
  (condition-notify cond-var))
Function: make-condition-variable mutex &optional name

mutexに関連付けられた条件変数を作成する。nameが指定されたら条件変数の名前として与えられる(文字列でなければならない)。これはデバッグにたいする用途のみの名前でありEmacsにとって意味はない。

Function: condition-variable-p object

この関数はobjectが条件変数を表していればt、それ以外はnilをリターンする。

Function: condition-wait cond

他のスレッドによる条件変数condの通知を待機する。この関数は条件変数の通知、またはthread-signalの使用によりシグナルが送信されるまでブロックする。

ミューテックスに関連付けられた条件を所持しないcondition-waitの呼び出しはエラーとなる。

condition-waitは待機中に関連付けられたミューテックスをリリースする。これは別スレッドによる条件通知するためのミューテックス所有を可能にする。

Function: condition-notify cond &optional all

condを通知する。呼び出し前にcondに関連付けられるミューテックスを所有しなければならない。通常はcondition-notifyにより単一の待機中スレッドが目覚めさせられる。しかしallが非nilならcondを待機中のすべてのスレッドに通知される。

condition-notifyは関連付けられたミューテックスを待機中はリリースする。これによりスレッドが条件を待機するためにミューテックスを所有することが可能になる。

Function: condition-name cond

make-condition-variableに渡されたcondの名前をリターンする。

Function: condition-mutex cond

condに関連付けられたミューテックスをリターンする。関連付けられたミューテックスは変更できないことに注意。


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

39.4 スレッドリスト

list-threadsコマンドはカレントでアクティブなすべてのスレッドをリストします。その結果となるバッファー内では、それぞれのスレッドはmake-thread (基本的なスレッド関数を参照)に渡された名前、または名前つきで作成されていなければ一意な内部識別子により識別される。バッファーの作成時(または最終更新時)の各スレッドの状態、さらにその時点でスレッドがブロックされていたらブロックしているオブジェクトが表示されます。

Variable: thread-list-refresh-seconds

*Threads*バッファーは自動的に毎秒2回更新される。この変数をカスタマイズしてリフレッシュ間隔を加減できる。

以下はレッドリストバッファーで利用できるコマンドです:

b

ポイント位置のスレッドのバックトレースを表示する。これはbを押下した時点でスレッドが生成またはブロックされたコードを表示する。このバックトレースはスナップショットであることに注意。それ以降にスレッドが実行を再開して異なる状態になったりexitしているかもしれない。

バックトレースバッファーは自動的に更新されないので、スレッドのバックトレースバッファーでは、更新されたバックトレースを取得するためにgを使用できる。バックトレースおよびそれらに機能する他のコマンドの説明はバックトレースを参照のこと。

s

ポイント位置のスレッドにシグナルを送信する。sの後にqをタイプするとquit、eをタイプするとエラーをシグナルする。スレッドはシグナルを処理するように実装されているかもしれないが、デフォルトではすべてのシグナルにたいしてexitする。したがってターゲットとなるスレッドの再開方法を理解している場合のみこのコマンドを使用すること(必要なスレッドがkillされるとEmacsセッションは不正に振る舞うかもしれない)。

g

スレッドのリストと状態を更新する。


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

40 プロセス

オペレーティングシステムの用語ではプロセス(process)とはプログラムを実行できるスペースのことです。Emacsはプロセス内で実行されます。Emacs Lispプログラムは別のプログラムをそれら自身のプロセス内で呼び出すことができます。これらは親プロセス(parent process)であるEmacsプロセスのサブプロセス(subprocesses)、または子プロセス(child processes)と呼ばれます。

Emacsのサブプロセスは同期(synchronous)非同期(asynchronous)であり、それはそれらが作成された方法に依存します。同期サブプロセスを作成した際には、Lispプログラムは実行を継続する前にそのサブプロセスの終了を待機します。非同期サブプロセスを作成したときには、それをLispプログラムと並行して実行できます。この種のサブプロセスはEmacsではLispオブジェクととして表現され、そのオブジェクトも“プロセス”と呼ばれています。Lispプログラムはサブプロセスとのやり取りやサブプロセスの制御のためにこのオブジェクトを使用できます。たとえばシグナル送信、ステータス情報の取得、プロセス出力の受信やプロセスへ入力を送信することができます。

プログラムを実行するプロセスに加えて、Lispプログラムは同一または他のマシン上で実行中のデバイスやプロセスにたいして、いくつかのタイプの接続をオープンできます。サポートされる接続タイプはネットワーク接続のTCPとUDP、シリアルポート接続、およびパイプ接続です。そのような接続はそれぞれプロセスオブジェクトとしても表現されます。

Function: processp object

この関数は、objectがEmacsのプロセスオブジェクトを表すならt、それ以外はnilをリターンする。プロセスオブジェクトはプログラム実行中のサブプロセスやサポートされた任意のタイプの接続を表すことができる。

カレントEmacsセッションのサブプロセスに加えて、そのマシン上で実行中の他のプロセスにアクセスすることもできます。別のプロセスへのアクセスを参照してください。


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

40.1 サブプロセスを作成する関数

内部でプログラムを実行するサブプロセスを作成するために3つのプリミティブが存在します。それらの1つはmake-processであり、これは非同期プロセスを作成してプロセスオブジェクトをリターンします(非同期プロセスの作成を参照)。他の2つはcall-processcall-process-regionです。これらは同期プロセスを作成してプロセスオブジェクとをリターンしません(同期プロセスの作成を参照)。特定のタイプのプロセスを実行するために、これらのプリミティブを利用するさまざまな高レベル関数が存在します。

同期プロセスと非同期プロセスについては、以降のセクションで説明します。この3つの関数はすべて類似した様式で呼び出されるので、ここではそれらに共通の引数について説明します。

すべての場合において、関数は実行するプログラムを指定します。ファイルが見つからなかったり実行できなければエラーがシグナルされます。ファイル名が相対的なら、検索するディレクトリーのリストは変数exec-pathに格納されています。Emacsは起動の際に環境変数PATHの値にもとづいてexec-pathを初期化します。exec-path内では標準的なファイル名構成要素‘~’、‘.’、‘..’は通常どおりに解釈されますが、環境変数の置換(‘$HOME’等)は認識されません。それらの置換を行うにはsubstitute-in-file-nameを使用してください(ファイル名を展開する関数を参照)。このリスト内でnildefault-directoryを参照します。

プログラムの実行では指定された名前にサフィックスの追加を試みることもできます:

User Option: exec-suffixes

この変数は指定されたプログラムファイル名への追加を試みるためのサフィックス(文字列)のリスト。指定されたとおりの名前を試みたいならリストに""を含めること。デフォルト値はシステム依存。

注意してください: 引数programにはプログラムのファイル名だけが含まれて、コマンドライン引数を含めることはできない。これらを提供するために以下で説明する別の引数argsを使用しなければならない。

サブプロセス作成関数にはそれぞれbuffer-or-name引数があります。これはプログラムの出力の行き先を指定します。これはバッファーかバッファー名であるべきです。バッファー名の場合には、もしそのバッファーがまだ作成されていなければバッファーを作成します。nilを指定することもでき、その場合にはカスタム製のフィルター関数が出力を処理するのでなければ出力を破棄するよう指示します(プロセスのフィルター関数Lispオブジェクトの読み取りとプリントを参照)。通常は出力がランダムに混在してしまうために、同一バッファーに複数プロセスの出力を送信するのは避けるべきです。同期プロセスにたいしてはバッファーのかわりにファイルに出力を送信できます(したがって対応する引数はより適切なdestinationという名前で呼ばれる)。デフォルトでは標準出力と標準エラーの両ストリームの行き先(destination)は同じだが、3つのプリミティブはすべてオプションで標準エラーストリームに別の行き先を指定できる。

これら3つのサブプロセス作成関数は、すべて実行するプロセスにコマンドライン引数を指定できます。call-processcall-process-regionでは、これらは&rest形式の引数argsで与えられます。make-processでは実行するプログラムとコマンドライン引数はいずれも文字列のリストとして指定されます。コマンドライン引数はすべて文字列でなければならず、それらは別個の引数文字列としてプログラムに与えられます。文字列は指定されたプログラムに直接渡されるので、ワイルドカード文字やその他のshell構文はこれらの文字列内では特別な意味をもちません。

サブプロセスはその環境をEmacsから継承しますが、process-environmentでそれをオーバーラードするよう指定することができます。オペレーティングシステムの環境を参照してください。サブプロセスは自身のカレントディレクトリーをdefault-directoryの値から取得します。

Variable: exec-directory

この変数の値はGNU Emacsとともに配布されて、Emacsにより呼び出されることを意図したプログラムを含むディレクトリーの名前(文字列)。プログラムmovemailはそのようなプログラムの例であり、Rmailはinboxから新しいメールを読み込むためにこのプログラムを使用する。

User Option: exec-path

この変数の値はサブプロセス内で実行するためのプログラムを検索するためのディレクトリーのリスト。要素はそれぞれディレクトリーの名前(文字列)、またはnilのいずれか。nilはデフォルトディレクトリー(default-directoryの値)を意味する。この検索の詳細はexecutable-findを参照のこと。

exec-pathの値は、program引数が絶対ファイル名でないときにcall-processstart-processにより使用される。

一般的にはexec-pathを直接変更するべきではない。かわりにEmacs起動前に環境変数PATHが適切にセットされているか確認すること。PATHとは独立にexec-pathの変更を試みると混乱した結果へと導かれ得る。

Function: exec-path

この関数は変数exec-pathの拡張である。default-directoryがリモートパスを示す場合には、この関数は対応するリモートホスト上でプログラム検索に使用するデジレクトリーのリストをリターンする。default-directoryがローカルにあれば、この関数は単に変数exec-pathの値をリターンする。


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

40.2 shell引数

Lispプログラムがshellを実行して、ユーザーが指定したファイル名を含むコマンドを与える必要がある場合が時折あります。これらのプログラムは任意の有効なファイル名をサポート可能であるはずです。しかしshellは特定の文字を特別に扱い、それらの文字がファイル名に含まれているとshellを混乱させるでしょう。これらの文字を処理するためには関数shell-quote-argumentを使用します。

Function: shell-quote-argument argument &optional posix

この関数は実際のコンテンツがargumentであるような引数を表す文字列をshellの構文でリターンする。リターン値をshellコマンドに結合して実行のためにそれをshellに渡すことにより、信頼性をもって機能するはずである。

この関数が正確に何を行うかはオペレーティングシステムに依存する。この関数はそのシステムの標準shellの構文で機能するようデザインされている。非標準のshellを使用する場合には、この関数を再定義する必要があるだろう。セキュリティへの配慮を参照のこと。

;; この例はGNUおよびUnixシステムでの挙動を示す
(shell-quote-argument "foo > bar")
     ⇒ "foo\\ \\>\\ bar"

;; この例はMS-DOSおよびMS-Windowsでの挙動を示す
(shell-quote-argument "foo > bar")
     ⇒ "\"foo > bar\""

以下はshell-quote-argumentを使用してshellコマンドを構築する例:

(concat "diff -u "
        (shell-quote-argument oldfile)
        " "
        (shell-quote-argument newfile))

オプションのposix引数が非nilの場合には、そのシステムのシェルに関わらず、argumentはPOSIXシェルのクォート規制によってクォートされる。これは一般的にはPOSIXシェルが要求されるリモートホスト上でシェルを実行する際に役に立つだろう。

(shell-quote-argument "foo > bar" (file-remote-p default-directory))

以下の2つの関数はコマンドライン引数の文字列のリストを単一の文字列に結合したり、単一の文字列を個別のコマンドライン引数のリストへ分割するために有用です。これらの関数は主にミニバッファーでのユーザー入力であるLisp文字列をmake-processcall-processstart-processに渡す文字列引数のリストへ変換したり、そのような引数のリストをミニバッファーやエコーエリアに表示するためのLisp文字列に変換することを意図しています。(call-process-shell-commandを使用して)shellが呼び出される場合には、引数を依然としてshell-quote-argumentで保護する必要があることに注意。combine-and-quote-stringsはshellの評価から特殊文字を保護することを意図していない

Function: split-string-shell-command string

この関数はダブルクォート、シングルクォートと同様にバックスラッシュによるクォートにも注意を払い、stringを部分文字列に分割する。

(split-string-shell-command "ls /tmp/'foo bar'")
     ⇒ ("ls" "/tmp/foo bar")
Function: split-string-and-unquote string &optional separators

この関数はsplit-string(文字列の作成を参照)が行うように、正規表現separatorsにたいするマッチでstringを部分文字列に分割する。さらに加えてその部分文字列からクォートを削除する。それから部分文字列のリストを作成してリターンする。

separatorsが省略またはnilの場合のデフォルトは"\\s-+"であり、これは空白文字構文(構文クラスのテーブルを参照)をもつ1つ以上の文字にマッチする正規表現である。

この関数は2つのタイプのクォートをサポートする。1つは文字列全体をダブルクォートで囲う"…"のようなクォートで、もう1つはバックスラッシュ‘\’によるエスケープで文字を個別にクォートするタイプである。後者はLisp文字列内でも使用されるので、この関数はそれらも同様に扱うことができる。

Function: combine-and-quote-strings list-of-strings &optional separator

この関数はlist-of-stringsの各文字を必要に応じてクォートして単一の文字列に結合する。これはさらに各文字ペアーの間にseparator文字列も挿入する。separatorが省略またはnilの場合のデフォルトは" "。リターン値はその結果の文字列。

list-of-strings内のクォートを要する文字列には、部分文字列としてseparatorを含むものが該当する。文字列のクォートはそれをダブルクォートで"…"のように囲う。もっとも単純な例では、たとえば個別のコマンドライン引数からコマンドをコンス(cons)する場合には、埋め込まれたブランクを含む文字列はそれぞれクォートされるだろう。


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

40.3 同期プロセスの作成

同期プロセス(synchronous process)の作成後、Emacsは継続する前にそのプロセスの終了を待機します。GNUやUnix28でのDiredの起動が例です。プロセスは同期的なので、Emacsがそれにたいして何か行おうと試みる前にディレクトリーのリスト全体がバッファーに到着します。

同期サブプロセス終了をEmacsが待機する間に、ユーザーはC-gをタイプすることでquitが可能です。最初のC-gSIGINTシグナルによりサブプロセスのkillを試みます。しかしこれはquitする前に実際にそのサブプロセスが終了されるまで待機します。その間にユーザーがさらにC-gをタイプするとそれはSIGKILLで即座にサブプロセスをkillしてquitします(別プロセスにたいするkillが機能しないMS-DOSを除く)。quitを参照してください。

同期サブプロセス関数はプロセスがどのように終了したかの識別をリターンします。

同期サブプロセスからの出力はファイルからのテキスト読み込みと同じように、一般的にはコーディングシステムを使用してデコードされます。call-process-regionによりサブプロセスに送信された入力は、ファイルへのテキスト書き込みと同じようにコーディングシステムを使用してエンコードされます。コーディングシステムを参照してください。

Function: call-process program &optional infile destination display &rest args

この関数はprogramを呼び出して完了するまで待機する。

サブプロセスのカレント作業ディレクトリー(CWD: current working directory)はカレントバッファーのdefault-directoryがローカル(unhandled-file-name-directoryにより判断される)ならその値、それ以外は"~"。リモートディレクトリーでプロセスを実行したければprocess-fileを使用すること。

新たなプロセスの標準入力はinfileが非nilならファイルinfile、それ以外ならnullデバイス。引数destinationはプロセスの出力をどこに送るかを指定する。以下は可能な値:

バッファー

そのバッファーのポイントの前に出力を挿入する。これにはプロセスの標準出力ストリームと標準エラーストリームの両方が含まれる。

バッファー名(文字列)

その名前のバッファーのポイントの前に出力を挿入する。

t

カレントバッファーのポイントの前に出力を挿入する。

nil

出力を破棄する。

0

出力を破棄してサブプロセス完了を待機せずに即座にnilをリターンする。

この場合にはプロセスはEmacsと並列に実行可能なので真に同期的ではない。しかしこの関数リターン後は本質的にはすみやかにEmacsがサブプロセスを終了するという点から、これを同期的と考えることができる。

MS-DOSは非同期サブプロセスをサポートせずこのオプションは機能しない。

(:file file-name)

指定されたファイルに出力を送信して、ファイルが既に存在すれば上書きする。

(real-destination error-destination)

標準出力ストリームを標準エラーストリームと分けて保持する。通常の出力はreal-destinationの指定にしたがって扱い、エラー出力はerror-destinationにしたがって処分する。error-destinationnilならエラー出力の破棄、tなら通常の出力と混合することを意味して、文字列ならそれはエラー出力をリダイレクトするファイルの名前である。

エラー出力先に直接バッファーを指定することはできない。ただしエラー出力を一時ファイルに送信して、サブプロセス終了時にそのファイルをバッファーに挿入すればこれを達成できる。

displayが非nilなら、call-processは出力の挿入にしたがってバッファーを再表示する(しかし出力のデコードに選択されたコーディングシステムが実データからエンコーディングを推論することを意味するundecidedなら、非ASCIIに一度遭遇すると再表示が継続不能になることがある。これを修正するのが困難な根本的理由が存在する。プロセスからの出力の受信を参照)。

それ以外なら関数call-processは再表示を行わずに、通常のイベントに由来するEmacsの再表示時だけスクリーン上で結果が可視になります。

残りの引数argsはそのプログラムにたいしてコマンドライン引数を指定する文字列です。文字列はそれぞれ別個の引数としてprogramに渡されます。

(待機するよう告げた場合には) call-processがリターンする値はプロセスが終了した理由を示します。この数字はそのサブプロセスのexitステータスであり0が成功、それ以外のすべての値は失敗を意味します。シグナルによりそのプロセスが終了された場合には、call-processはそれを記述する文字列をリターンします。call-processに待機しないように指示した場合にはnilをリターンします。

以下の例ではカレントバッファーは‘foo’です。

(call-process "pwd" nil t)
     ⇒ 0

---------- Buffer: foo ----------
/home/lewis/manual
---------- Buffer: foo ----------

(call-process "grep" nil "bar" nil "lewis" "/etc/passwd")
     ⇒ 0

---------- Buffer: bar ----------
lewis:x:1001:1001:Bil Lewis,,,,:/home/lewis:/bin/bash

---------- Buffer: bar ----------

以下はcall-processの使用例であり、このような使用例はinsert-directory関数の定義内で見つけることができます:

(call-process insert-directory-program nil t nil switches
              (if full-directory-p
                  (concat (file-name-as-directory file) ".")
                file))
Function: process-file program &optional infile buffer display &rest args

この関数は別プロセス内でファイルを同期的に処理する。これはcall-processと似ているが、サブプロセスのカレントワーキングディレクトリーを指定する変数default-directoryの値にもとづいて、ファイル名ハンドラーを呼び出すかもしれない。

引数はcall-processの場合とほとんど同様の方法で処理されるが以下の違いがある:

引数infilebufferdisplayのすべての組み合わせと形式をサポートしないファイル名ハンドラーがあるかもしれない。たとえば実際に渡された値とは無関係に、displaynilであるかのように振る舞うファイル名ハンドラーがいくつかある。他の例としてはbuffer引数で標準出力とエラー出力を分離するのをサポートしないかもしれないファイル名ハンドラーがいくつか存在する。

ファイル名ハンドラーが呼び出されると、1つ目の引数programにもとづいて実行するプログラムを決定する。たとえばリモートファイルにたいするハンドラーが呼び出されたと考えてみよ。その場合にはプログラムの検索に使用されるパスはexec-pathとは異なるかもしれない。

2つ目の引数infileはファイル名ハンドラーを呼び出すかもしれない。そのファイル名ハンドラーは、process-file関数自身にたいして選択されたハンドラーと異なるかもしれない(たとえばdefault-directoryがリモートホスト上にありinfileは別のリモートホスト上の場合があり得る。もしくはdefault-directoryは普通だがinfileはリモートホスト上にあるかもしれない).

buffer(real-destination error-destination)という形式のリストであり、かつerror-destinationがファイルの名前ならinfileと同じ注意が適用される。

残りの引数( args )はそのままプロセスに渡される。Emacsはargs内で与えられたファイル名の処理に関与しない。混乱を避けるためにはargs内で絶対ファイル名を使用しないのが最善であり、default-directoryからの相対ファイル名ですべてのファイルを指定するほうがよいだろう。そのような相対ファイル名の構築には関数file-relative-nameが有用。かわりにリモートホスト視点から見た絶対ファイル名を取得するためにfile-local-nameも使用できる(特定のファイル名の“Magic”の作成を参照)。

Variable: process-file-side-effects

この変数はprocess-file呼び出しがリモートファイルを変更するかどうかを示す。

この変数はデフォルトではprocess-file呼び出しがリモートホスト上の任意のファイルを潜在的に変更し得ることを意味するtに常にセットされる。nilにセットされた際には、リモートファイル属性のキャッシュにしたがうことによりファイル名ハンドラーの挙動を最適化できる可能性がある。

この変数は決してsetqではなく、常にletバインディングでのみ変更すること。

User Option: process-file-return-signal-string

このユーザーオプションは、リモートプロセスに割り込んだシグナルを記述する文字列をprocess-file呼び出しがリターンするかどうかを示す。

プロセスが128より大なexitコードをリターンしたら、それはシグナルとして解釈される。process-fileはこのシグナルを説明する文字列のリターンを求められる。

この規約に違反するプロセスが存在するために、シグナルにバインドされない128より大なexitコードのリターンでは、常にprocess-fileはリモートプロセスにたいする自然数としてexitコードをリターンする。このユーザーオプションを非nilにセットすることによって、そのようなexitコードをシグナルとして解釈して、それに対応する文字列をリターンするようにprocess-fileに強制することができる。

Function: call-process-region start end program &optional delete destination display &rest args

この関数はstartからendのテキストを、実行中のプロセスprogramに標準入力として送信する。これはdeleteが非nilなら送信したテキストを削除する。これは出力をカレントバッファーの入力箇所に挿入するために、destinationtに指定している際に有用。

引数destinationdisplayはサブロセスからの出力にたいして何を行うか、および出力の到着にともない表示を更新するかどうかを制御する。詳細は上述のcall-processの説明を参照のこと。destinationが整数の0ならcall-process-regionは出力を破棄して、サブプロセス完了を待機せずに即座にnilをリターンする(これは非同期サブプロセスがサポートされる場合、つまりMS-DOS以外でのみ機能する)。

残りの引数argsはそのプログラムにたいしてコマンドライン引数を指定する文字列です。

call-process-regionのリターン値はcall-processの場合と同様。待機せずにリターンするよう指示した場合にはnil、数字か文字列ならそれはサブプロセスが終了した方法を表す。

以下の例ではバッファー‘foo’内の最初の5文字(単語‘input’)を標準入力として、call-process-regionを使用してcatユーティリティを実行する。catは自身の標準入力を標準出力へコピーする。引数destinationtなので出力はカレントバッファーに挿入される。

---------- Buffer: foo ----------
input∗
---------- Buffer: foo ----------

(call-process-region 1 6 "cat" nil t)
     ⇒ 0

---------- Buffer: foo ----------
inputinput∗
---------- Buffer: foo ----------

たとえばshell-command-on-regionコマンドは、以下のような方法でcall-shell-regionを使用する:

(call-shell-region
 start end
 command              ; shellコマンド
 nil                  ; regionを削除しない
 buffer)              ; 出力をbufferに出力
Function: call-process-shell-command command &optional infile destination display

この関数はshellコマンドcommandを非同期に実行する。他の引数はcall-processの場合と同様に処理される。古い呼び出し規約はdisplayの後に任意個数の追加引数を許容して、これはcommandに結合される。これはまだサポートされるものの使用しないことを強く推奨する。

Function: process-file-shell-command command &optional infile destination display

この関数はcall-process-shell-commandと同様だが内部的にprocess-fileを使用する点が異なる。default-directoryに依存してcommandはリモートホスト上でも実行可能。古い呼び出し規約はdisplayの後に任意個数の追加引数を許容して、これはcommandに結合される。これはまだサポートされるものの使用しないことを強く推奨する。

Function: call-shell-region start end command &optional delete destination

この関数はstartendの間のテキストを、commandを実行するシェルの標準入力として送信する。これはプロセスがシェルであるようなcall-process-regionと類似している。引数deletedestination、およびリターン値はcall-process-regionと同様。この関数は追加の引数を受け付けないことに注意。

Function: shell-command-to-string command

この関数はshellコマンドとしてcommand (文字列)を実行してコマンドの出力を文字列としてリターンする。

Function: process-lines program &rest args

この関数はprogramを実行して完了を待機して、出力を文字列のリストとしてリターンする。リスト内の各文字列はプログラムのテキスト出力の1つの行を保持する。各行のEOL文字(行末文字)は取り除かれる。programの後の引数argsはそのプログラム実行に際して、コマンドライン引数を指定する文字列。

programが非0のexitステータスでexitすると、この関数はエラーをシグナルする。

この関数はcall-processを呼び出すことにより機能して、プログラムの出力はcall-processの場合と同じ方法でデコードされる。

Function: process-lines-ignore-status program &rest args

この関数はprocess-linesと同様だが、programが非0のexitステータスでexitした場合にエラーをシグナルしない。


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

40.4 非同期プロセスの作成

このセクションでは非同期プロセス(asynchronous process)を作成する方法について説明します。非同期プロセスは作成後にEmacsと並列して実行され、Emacsは以降のセクション(プロセスへの入力の送信プロセスからの出力の受信を参照)で説明する関数を使用してプロセスとコミュニケーションができます。プロセスコミュニケーションは部分的に非同期なだけであることに注意してください。Emacsはこれらの関数を呼び出したときだけプロセスとのデータを送受信できます。

非同期プロセスはpty(pseudo-terminal: 疑似端末)、またはpipeのいずれかを通じて制御されます。ptyかpipeの選択はデフォルトでは変数process-connection-type (以下参照)の値にもとづいてプロセス作成時に行われます。Shellモードのように利用可能ならユーザーから可視なプロセスには、プロセスと子プロセス間でジョブ制御(C-cC-z等)が可能であり、インタラクティブなプログラムではptyを端末デバイスとして扱いますがpipeはそのような機能をサポートしないのでptyが通常は好まれます。しかし内部的な目的のためにLispプログラムが使用する(サブプロセスとユーザーの相互作用が要求されない)サブプロセスでは、サブプロセスとLispプログラム間で大量データのやり取りが要求される場合には、pipeがより効率的なのでpipeの使用が最良な場合がままあります。さらに多くのシステムではptyの合計数に制限があり、それを浪費するのは得策ではありません。

Function: make-process &rest args

この関数は非同期サブプロセスを開始するための基本的な低レベルなプリミティブである。これはサブプロセスを表すプロセスオブジェクトをリターンする。以下で説明するより高レベルなstart-processと比較すると、この関数はキーワード引数を受け取り、より柔軟であり、単独の呼び出しでプロセスフィルターやセンチネルを指定できる。

引数argsはkeyword/argumentペアのリスト。キーワードの省略は値nilでそれを指定することと常に等価。以下は意味のあるキーワード:

:name name

プロセス名として文字列nameを使用する。その名前のプロセスがすでに存在すれば、(‘<1>’、...の追加により)一意となるようにnameを修正する。

:buffer buffer

プロセスバッファーとしてbufferを使用する。値がnilなら、そのサブプロセスには何のバッファーも関連付けられない。

:command command

プロセスのコマドラインとしてcommandを使用する。値はプログラムの実行可能ファイル名で始まり、後にプログラムの引数として与える文字列が続くリストであること。リストの最初の要素がnilなら、Emacsは新たな擬似端末(pty)を作成して、実際には何もプログラムを実行せずに入出力をbufferに関連付ける。この場合には残りのリスト要素は無視される。

:coding coding

codingがシンボルなら、それはその接続にたいする読み取りと書き込みの両方で使用するコーディングシステムを指定する。codingがコンスセル(decoding . encoding)なら読み取りにdecoding、書き込みにencodingが使用される。プログラムに書き込むデータのエンコーディングに使用されるコーディングシステムは、コマンドライン引数のエンコーディングにも使用される(しかしプログラム自身にたいしてファイル名を別のファイル名にエンコードすることはない。file-name-coding-systemを参照)。

codingnilなら、デフォルトのコーディングシステム検出ルールを適用する。デフォルトのコーディングシステムを参照のこと。

:connection-type type

サブプロセスとの対話に使用するデバイスタイプを初期化する。値にはptyを使用するpty、pipeを使用するpipe、または変数process-connection-typeの値から継承されるデフォルトを使用するnilを指定できる。typeがコンスセル(input . output)の場合には、標準入力にinput、標準出力(および:stderrnilなら標準エラーも)にoutputが使用される。

ptyが利用できないシステム(MS-Windows)ではこのパラメーターを無視して、無条件でpipeが使用される。

:noquery query-flag

プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。

:stop stopped

stoppedが与えられた場合にはnilでなければならない。非nil値の使用はすべてエラーとなる。それ以外の場合には:stopは無視される。これはpipeプロセスのような他のプロセスタイプへの互換性のために維持されている。非同期サブプロセスがstopped状態で開始されることはあり得ない。

:filter filter

プロセスフィルターをfilterに初期化する。未指定ならデフォルトフィルターが提供されるが、これは後からオーバーライドできる。プロセスのフィルター関数を参照のこと。

:sentinel sentinel

プロセスセンチネルをsentinelに初期化する。未指定ならデフォルトセンチネルが使用されるが、これは後からオーバーライドできる。センチネル: プロセス状態の変更の検知を参照のこと。

:stderr stderr

プロセスの標準エラーにstderrを割り当てる。値が非nilならバッファー、または以下で説明するmake-pipe-processで作成されたpipeのいずれかであること。stderrnilなら標準エラーを標準出力と合成して、両者をbufferfilterに送信する。

stderrがバッファーならEmacsはpipeプロセス、標準エラープロセス(standard error process)を作成する。このプロセスはデフォルトフィルター(プロセスのフィルター関数を参照)、センチネル(センチネル: プロセス状態の変更の検知を参照)、コーディングシステム(デフォルトのコーディングシステムを参照)をもつ。その一方で、自身のquery-on-exitフラグとしてquery-flagを使用する(exit前の問い合わせを参照)。このプロセスはstderrバッファーに関連づけられて、そこに出力(メインプロセスの標準エラー)を送信する(プロセスのバッファーを参照)。標準エラープロセスにたいするプロセスオブジェクトを取得するには、get-buffer-processstderrバッファーを渡せばよい。

stderrがpipeプロセスなら、Emacsはそれを新たなプロセス用の標準エラープロセスとして使用する。

:file-handler file-handler

file-handlerが非nilなら、カレントバッファーのdefault-directoryにたいするファイル名ハンドラーを探して、プロセスを作成するためにそのファイル名ハンドラーを呼び出す。そのようなハンドラーがなければ、file-handlernilであるかのように処理する。

実際の接続情報で修正されたオリジナルの引数リストはprocess-contactを通じて利用できる。

サブプロセスのカレント作業ディレクトリー(CWD: current working directory)はカレントバッファーのdefault-directoryがローカル(unhandled-file-name-directoryにより判断される)ならその値、それ以外は~。リモートディレクトリーでプロセスを実行したければ、make-process:file-handler tを渡せばよい。この場合には、カレントのワーキングディレクトリー(CWD)はdefault-directoryの(file-local-nameで決定される)ローカル部分となる。

ファイル名ハンドラーの実装に依存して、結果となるプロセスオブジェクトへのfiltersentinelの適用が不可能かもしれない。:stderr引数はpipeプロセスではあり得ないので、ファイル名ハンドラーはこれにたいしてpipeプロセスをサポートしない。:stderr引数としてバッファーは許されており、バッファーのコンテンツはpipeプロセスを使用することなく表示される。プロセスのフィルター関数およびプロセスの出力を受け取るを参照のこと。

いくつかのファイルハンドラーはmake-processをサポートしないかもしれない。そのような場合には、この関数は何も行わずにnilをリターンする。

Function: make-pipe-process &rest args

この関数は子プロセスにアタッチ可能な双方向のpipeを作成する。これはmake-process:stderrキーワードと併用することで有用。この関数はプロセスオブジェクトをリターンする。

引数argsはkeyword/argumentペアのリスト。キーワードの省略はそのキーワードに値nilを指定することと常に等価。

以下は意味のあるキーワード。

:name name

プロセス名として文字列nameを使用する。make-processの場合のように、一意にするために必要に応じて変更され得る。

:buffer buffer

プロセスバッファーとしてbufferを使用する。

:coding coding

codingがシンボルなら、それはその接続にたいする読み取りと書き込みの両方で使用するコーディングシステムを指定する。codingがコンスセル(decoding . encoding)なら読み取りにdecoding、書き込みにencodingが使用される。

codingnilなら、デフォルトのコーディングシステム検出ルールを適用する。デフォルトのコーディングシステムを参照のこと。

:noquery query-flag

プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。

:stop stopped

stoppedが非nilなら停止状態でプロセスを開始する。停止状態ではpipeプロセスは入力データを受け取らないが出力データは送信できる。停止状態はstop-processでセットしてcontinue-processでクリアーされる(プロセスへのシグナルの送信を参照)。

:filter filter

プロセスフィルターをfilterに初期化する。未指定ならデフォルトフィルターが提供されるが後で変更できる。プロセスのフィルター関数を参照のこと。

:sentinel sentinel

プロセスセンチネルをsentinelに初期化する。未指定ならデフォルトセンチネルが使用されるが後で変更できる。センチネル: プロセス状態の変更の検知を参照のこと。

実際の接続情報で修正されたオリジナルの引数リストはprocess-contactを通じて利用できる。

Function: start-process name buffer-or-name program &rest args

この関数はcall-processの類似したインターフェースを提供する、make-process周辺の高レベルのラッパー。これは新たに非同期サブプロセスを作成して、指定されたprogramの実行をその内部で開始する。これはLispで新たなサブプロセスを意味するプロセスオブジェクトをリターンする。引数nameはプロセスオブジェクトの名前を指定する。make-processの場合のように、一意な名前となるように必要に応じて修正する。バッファーbuffer-or-nameはそのプロセスに関連付けるバッファー。

programnilならEmacsは疑似端末(pty)を新たにオープンして、サブプロセスを新たに作成することなくptyの入力と出力をbuffer-or-nameに関連付ける。この場合には残りの引数argsは無視される。

残りのargsはサブプロセスにコマンドライン引数を指定する文字列。

以下の例では1つ目のプロセスを開始して100秒間実行(というよりはsleep)される。その間に2つ目のプロセスを開始して、一意性を保つために‘my-process<1>’という名前が与えられる。これは1つ目のプロセスが終了する前にバッファー‘foo’の最後にディレクトリーのリストを挿入する。その後に2つ目のプロセスは終了して、その旨のメッセージがバッファーに挿入される。さらに遅れて1つ目のプロセスが終了して、バッファーに別のメッセージが挿入される。

(start-process "my-process" "foo" "sleep" "100")
     ⇒ #<process my-process>

(start-process "my-process" "foo" "ls" "-l" "/bin")
     ⇒ #<process my-process<1>>

---------- Buffer: foo ----------
total 8336
-rwxr-xr-x 1 root root 971384 Mar 30 10:14 bash
-rwxr-xr-x 1 root root 146920 Jul  5  2011 bsd-csh
…
-rwxr-xr-x 1 root root 696880 Feb 28 15:55 zsh4

Process my-process<1> finished

Process my-process finished
---------- Buffer: foo ----------
Function: start-file-process name buffer-or-name program &rest args

start-processと同じようにこの関数は非同期サブプロセスを開始して、その内部でprogramを実行してそのプロセスオブジェクトをリターンする。

start-processとの違いは、この関数がdefault-directoryの値にもとづいてファイル名ハンドラーを呼び出すかもしれないという点である。このハンドラーはローカルホスト上、あるいはdefault-directoryに応じたリモートホスト上でprogramを実行すること。後者の場合には、default-directoryのローカル部分はそのプロセスのワーキングディレクトリーになる。

この関数はprogramargsの残りにたいしてファイル名ハンドラーの呼び出しを試みない。programargsのいずれかがリモートファイル構文(特定のファイル名の“Magic”の作成を参照)を使用する場合には、file-local-nameを通じて実行することにより、それらの名前をdefault-directoryに相対的な名前やリモートホスト上でローカルにファイルを識別する名前に変換しなければならないことが理由。

そのファイル名ハンドラーの実装によっては、リターン結果のプロセスオブジェクトにprocess-filterprocess-sentinelを適用することができないかもしれない。プロセスのフィルター関数センチネル: プロセス状態の変更の検知を参照のこと。

いくつかのファイル名ハンドラーはstart-file-processをサポートしないかもしれない(たとえばange-ftp-hook-function関数)。そのような場合には、この関数は何も行わずにnilをリターンする。

Function: start-process-shell-command name buffer-or-name command

この関数はstart-processと同様だが、指定されたcommandの実行にshellを使用する点が異なる。引数commandはshellコマンド文字列。変数shell-file-nameはどのshellを使用するかを指定する。

make-processstart-processでプログラムを実行せずにshellを通じて実行することの要点は、引数内のワイルドカード展開のようなshell機能を利用可能にするためである。そのためにはコマンド内に任意のユーザー指定引数を含めるなら、任意の特別なshell文字がshellでの特別な意味をもたないように、まずshell-quote-argumentでそれらをクォートするべきである。shell引数を参照のこと。ユーザー入力にもとづいたコマンド実行時には当然セキュリティ上の影響も考慮するべきである。

Function: start-file-process-shell-command name buffer-or-name command

この関数はstart-process-shell-commandと似ているが、内部的にstart-file-processを使用する点が異なる。これによりdefault-directoryに応じてリモートホスト上でもcommandを実行できる。

Variable: process-connection-type

この変数は非同期サブプロセスと対話するために使用するデバイスタイプを制御する。これが非nilの場合には利用可能ならpty、それ以外ならpipeが使用される。

process-connection-typeの値はmake-processstart-processの呼び出し時に効果を発揮する。そのためにこれらの関数の呼び出し前後でこの変数をバインドすることにより、サブプロセスとやり取りする方法を指定できる。

この変数の値は非nil値の:stderrパラメーターでmake-processが呼び出された際には無視される。この場合にはEmacsはpipeを使用してプロセスと対話する。ptyが利用不能(MS-Windows)な場合にも無視される。

(let ((process-connection-type nil))  ; pipeを使用
  (start-process …))

与えられたサブプロセスが実際にはpipeとptyのどちらを取得したかを判断するには関数process-tty-nameを使用する(プロセスの情報を参照)。

Variable: process-error-pause-time

もしプロセスのセンチネルやフィルターの関数にエラーがあると、Emacsはそのエラーを表示した後に、ユーザーが問題となっているエラーを確認できるように(デフォルトでは)process-error-pause-timeに設定された秒数の間一時停止する。ただしEmacsが応答しなくなる状況に導かれる可能性もある(あまりに大量のエラーが発生した場合など)ので、process-error-pause-timeを0にセットして無効にできる。


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

40.5 プロセスの削除

プロセス削除(deleting a process)とはEmacsをサブプロセスから即座に切断することです。プロセスは終了後に自動的に削除されますが即座に削除される必要はありません。任意のタイミングで明示的にプロセスを削除できます。終了したプロセスが自動的に削除される前に明示的に削除しても害はありません。実行中のプロセスの削除はプロセス(もしあれば子プロセスにも)を終了するためにシグナルを送信してプロセスセンチネルを呼び出します。センチネル: プロセス状態の変更の検知を参照してください。

プロセスが削除される際、そのプロセスオブジェクト自体はそれを参照する別のLispオブジェクトが存在する限り継続し続けます。プロセスオブジェクトに作用するすべてのLispプリミティブはプロセスの削除を受け入れますが、I/Oを行ったりシグナルを送信するプリミティブはエラーを報告するでしょう。プロセスマークは通常はプロセスからの出力がバッファーに挿入される箇所となる、以前と同じ箇所をポイントし続けます。

User Option: delete-exited-processes

この変数は、(exit呼び出しやシグナルにより)終了したプロセスの自動的な削除を制御する。これがnilならユーザーがlist-processesを実行するまでプロセスは存在し続けて、それ以外ならexit後に即座に削除される。

Function: delete-process &optional process

この関数はプロセスがプログラムを実行していたらSIGKILLシグナルでkillすることによりプロセスを削除する。引数はプロセス、プロセスの名前、バッファー、バッファーの名前かもしれない(バッファーやバッファー名ならget-buffer-processがリターンするプロセスを、processが省略またはnilならカレントバッファーのプロセスをkillする必要があることを意味する)。実行中のプロセスにdelete-processを呼び出すことによりプロセスを終了してプロセス状態を更新して即座にセンチネルを実行する。そのプロセスがすでに終了していれば、delete-process呼び出しはプロセス状態、または(遅かれ早かれ発生するであろう)プロセスセンチネルの実行に影響を与えない。

プロセスオブジェクトがネットワーク接続、シリアル接続、pipe接続を表す場合には状態はclosed、それ以外ならそのプロセスがexit済みでなければsignalに変更される。process-statusを参照のこと。

(delete-process "*shell*")
     ⇒ nil

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

40.6 プロセスの情報

プロセスの状態に関する情報をリターンする関数がいくつかあり。

Command: list-processes &optional query-only buffer

このコマンドは、すべての生きたプロセスのリストを表示する。加えてこれは最後に、状態が‘Exited’か‘Signaled’だったすべてのプロセスを削除する。このコマンドはnilをリターンする。

プロセスはメジャーモードがProcess Menuモードであるような、*Process List*という名前のバッファーに表示される(オプション引数bufferで他の名前を指定していない場合)。

query-onlyが非nilなら、queryフラグが非nilのプロセスだけをリストする。exit前の問い合わせを参照のこと。

Function: process-list

この関数は削除されていないすべてのプロセスのリストをリターンする。

(process-list)
     ⇒ (#<process display-time> #<process shell>)
Function: num-processors &optional query

この関数はプロセッサー数を正の整数としてリターンする。使用可能なスレッドの各実行ユニットはプロセッサーとしてカウントされる。このカウントにはデフォルトでは利用できるプロセッサー数が含まれる。これはOpenMPの環境変数OMP_NUM_THREADSををセットすることによってオーバーライドできる。オプション引数querycurrentなら、この関数はOMP_NUM_THREADSを無視する。queryallならシステム上にあるがカレントプロセスで利用できないプロセッサーもカウントする。

Function: get-process name

この関数はname (文字列)というプロセス、存在しなければnilをリターンする。引数nameはプロセスオブジェクトでもよく、この場合にはそれがリターンされる。

(get-process "shell")
     ⇒ #<process shell>
Function: process-command process

この関数はprocessを開始するために実行されたコマンドをリターンする。これは文字列のリストで1つ目の文字列は実行されたプログラム、残りの文字列はそのプログラムに与えられた引数。ネットワーク接続、シリアル接続、pipe接続にたいしてはnil (プロセスは実行中)かt (プロセスは停止中)のいずれか。

(process-command (get-process "shell"))
     ⇒ ("bash" "-i")
Function: process-contact process &optional key no-block

この関数はネットワーク接続、シリアル接続、pipe接続がセットアップされた方法に関する情報をリターンする。keynilならネットワーク接続には(hostname service)、シリアル接続には(port speed)、pipe接続にはtをリターンする。普通の子プロセスにたいしては、この関数はkeynilで呼び出されると常にtをリターンする。

keytなら値はその接続、サーバー、シリアルポート、またはpipeについての完全な状態情報、すなわちmake-network-processmake-serial-process、またはmake-pipe-process内で指定されるキーワードと値のリストとなる。ただしいくつかの値については、指定した値のかわりにカレント状態を表す値となる。

ネットワークプロセスにたいしては以下の値が含まれる(完全なリストはmake-network-processを参照):

:buffer

値にはプロセスのバッファーが割り当てられる。

:filter

値にはプロセスのフィルター関数が割り当てられる。プロセスのフィルター関数を参照のこと。

:sentinel

値にはプロセスのセンチネル関数が割り当てられる。センチネル: プロセス状態の変更の検知を参照のこと。

:remote

接続にたいしては内部的なフォーマットによるリモートピアーのアドレス。

:local

内部的なフォーマットによるローカルアドレス。

:service

この値はサーバーではservicetを指定すると実際のポート番号。

make-network-process内で明示的に指定されていなくても:local:remoteは値に含まれる。

シリアル接続についてはmake-serial-process、キーのリストはserial-process-configureを参照のこと。pipe接続についてはmake-pipe-processを参照のこと。

keyがキーワードなら、この関数はそのキーワードに対応する値をリターンする。

processがまだ完全にセットアップされていない非ブロッキングネットワークストリームなら、この関数はセットアップされるまでブロックする。オプションのno-blockパラメーターが与えられると、この関数はブロックせずにnilをリターンする。

Function: process-id process

この関数はprocessPIDをリターンする。これは同じコンピューター上でカレント時に実行中の他のすべてのプロセスからプロセスprocessを区別するための整数。プロセスのPIDはプロセスの開始時にオペレーティングシステムのカーネルにより選択されて、そのプロセスが存在する限り定数として保たれる。この関数はネットワーク接続、シリアル接続、pipe接続にはnilをリターンする。

Function: process-name process

この関数はprocessの名前を文字列としてリターンする。

Function: process-status process-name

この関数はprocess-nameの状態を文字列でリターンする。引数process-nameはプロセス、バッファー、またはプロセス名(文字列)でなければならない。

実際のサブプセスにたいして可能な値は:

run

実行中のプロセス。

stop

停止しているが継続可能なプロセス。

exit

exitしたプロセス。

signal

致命的なシグナルを受信したプロセス。

open

オープンされたネットワーク接続、シリアル接続、またはpipe接続。

closed

クローズされたネットワーク接続、シリアル接続、またはpipe接続。一度クローズされた接続は、たとえ同じ場所にたいして新たな接続をオープンすることができたとしても再度オープンすることはできない。

connect

完了を待つ非ブロッキング接続。

failed

完了に失敗した非ブロッキング接続。

listen

listen中のネットワークサーバー。

nil

process-nameが既存のプロセス名でない場合。

(process-status (get-buffer "*shell*"))
     ⇒ run

ネットワーク接続、シリアル接続、pipe接続にたいしてprocess-statusopenstop、またはclosedいずれかのシンボルをリターンする。closedは相手側が接続をクローズしたか、あるいはEmacsがdelete-processを行なったことを意味する。値stopはその接続でstop-processが呼び出されたことを意味する。

Function: process-live-p process

この関数はprocessがアクティブなら、非nilをリターンする。状態がrunopenlistenconnectstopのプロセスはアクティブとみなされる。

Function: process-type process

この関数はネットワーク接続やサーバーにたいしてはnetwork、シリアルポート接続にたいしてはserial、pipe接続にたいしてはpipe、プログラム実行用に作成されたサブプロセスにたいしてはrealというシンボルをリターンする。

Function: process-exit-status process

この関数はprocessのexitステータス、またはプロセスをkillしたシグナル番号をリターンする(いずれであるかの判定にはprocess-statusの結果を使用)。processがまだ終了していなければ値は0。すでにcloseされたネットワーク接続、シリアル接続、pipe接続についての値は接続のcloseが正常か異常かによって0か256のいずれかとなる。

Function: process-tty-name process &optional stream

この関数はprocessがEmacsとの対話に使用する端末名、ptyではなくpipeを使用する場合にはnilをリターンする(非同期プロセスの作成process-connection-typeを参照)。この関数processの標準ストリームのいずれかが端末を使用していれば、デフォルトではその端末の名前をリターンする。streamstdinstdoutstderrのいずれかであれば、この関数は特にそのストリームにたいしてprocessが使用している端末の名前(または上述したようにnil)をリターンする。これを用いれば、特定のストリームがpipeとptyのどちらを使用しているかを判断できる。

この関数はprocessがリモートホストで実行中のプログラムを表す場合には、processと対話するローカルの端末名をリターンする。そのプログラムがリモートホスト上で使用している端末の名前については、そのプロセスにremote-ttyプロパティで取得できる。この関数はprocessがネットワーク、シリアル、あるいはpipeによる接続を表す場合には常にnilをリターンする。

Function: process-coding-system process

この関数はprocessからの出力のデコードに使用するコーディングシステムと、processへの入力のエンコードに使用するコーディングシステムを記述するコンスセル(decode . encode)をリターンする(コーディングシステムを参照)。

Function: set-process-coding-system process &optional decoding-system encoding-system

この関数はprocessにたいする後続の入出力に使用するコーディングシステムを指定する。これはサブプロセスの出力のデコードにdecoding-system、入力のエンコードにencoding-systemを使用する。

すべてのプロセスには、そのプロセスに関連するさまざまな値を格納するために使用できるプロパティリストもあります。

Function: process-get process propname

この関数はprocessのプロパティpropnameの値をリターンする。

Function: process-put process propname value

この関数はprocessのプロパティpropnameの値にvalueをセットする。

Function: process-plist process

この関数はprocessのプロセスplistをリターンする。

Function: set-process-plist process plist

この関数はprocessのプロセスplistにplistをセットする。


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

40.7 プロセスへの入力の送信

非同期サブプロセスはEmacsにより入力が送信されたときに入力を受信して、それはこのセクション内の関数で行われます。これを行うには入力を送信するプロセスと送信するための入力データを指定しなければなりません。サブプロセスがプログラムを実行していたら、データはプログラムの標準入力として出現します。接続にたいしては、データは接続されたデバイスかプログラムに送信されます。

オペレーティングシステムにはptyのバッファーされた入力にたいして制限をもつものがいくつかあります。それらのシステムでは、Emacsは他の文字列の間に定期的かつ強制的にEOFを送信します。ほとんどのプログラムにたいして、これらのEOFは無害です。

サブプロセスの入力はテキストをファイルに書き込むときと同じように、通常はサブプロセスが受信する前、コーディングシステムを使用してエンコードされます。どのコーディングシステムを使用するかを指定するにはset-process-coding-systemを使用できます(プロセスの情報を参照)。それ以外の場合には、非nilならcoding-system-for-writeがコーディングシステムとなり、さもなくばデフォルトのメカニズムがコーディングシステムを決定します(デフォルトのコーディングシステムを参照)。

入力バッファーが一杯のために、システムがプロセスからの入力を受け取ることができないことがあります。これが発生したときには、送信関数はしばらく待機してサブプロセスの出力を受け取り、再度送信を試みます。これは保留となっている更なる入力を読み取り、バッファーに空きを作る機会をサブプロセスに与えます。これはフィルター(現在実行中のものを含む)、センチネル、タイマーの実行も可能にするのでコードを記述する際はそれを考慮してください。

以下の関数ではprocess引数はプロセス、プロセス名、またはバッファー、バッファー名(get-buffer-processで取得されるプロセス)、nilはカレントバッファーのプロセスを意味します。

Function: process-send-string process string

この関数はstringのコンテンツを標準入力としてprocessに送信する。たとえばファイルをリストするShellバッファーを作成するには:

(process-send-string "shell<1>" "ls\n")
     ⇒ nil
Function: process-send-region process start end

この関数はstartendで定義されるリージョンのテキストを標準入力としてprocessに送信する。

startendが、カレントバッファー内の位置を示す整数かマーカーでなければエラーがシグナルされる(いずれかの大小は重要ではない)。

Function: process-send-eof &optional process

この関数はprocessが入力内のEOF (end-of-file)を見ることを可能にする。EOFはすべての送信済みテキストの後になる。この関数はprocessをリターンする。

(process-send-eof "shell")
     ⇒ "shell"
Function: process-running-child-p &optional process

この関数はprocessが接続ではない実際のサブプロセスであり、端末の制御を自身の子プロセスに与えたかどうかを示す。これが真なら関数はprocessのフォアグラウンドプロセスグループの数値ID、これが真ではないとEmacsが判断すればnilをリターンする。これが真かどうかをEmacsが判断できなければ値はtprocessがネットワーク接続、シリアル接続、pipe接続、またはアクティブではないサブプロセスなら関数はエラーをシグナルする。


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

40.8 プロセスへのシグナルの送信

サブプロセスへのシグナル送信(sending a signal)はプロセス活動に割り込む手段の1つです。異なる複数のシグナルがあり、それぞれが独自に意味をもちます。シグナルのセットとそれらの意味はオペレーティングシステムにより定義されます。たとえばシグナルSIGINTはユーザーがC-cをタイプしたか、それに類似する何かが発生したことを意味します。

各シグナルはサブプロセスに標準的な効果をもちます。ほとんどのシグナルはサブプロセスをkillしますが、かわりに実行を停止(や再開)するものもいくつかあります。ほとんどのシグナルはオプションでプログラムでハンドル(処理)することができます。プログラムがそのシグナルをハンドルする場合には、その影響についてわたしたちは一般的には何も言うことはできません。

このセクション内の関数を呼び出すことにより明示的にシグナルを送信できます。Emacsも特定のタイミングで自動的にシグナルを送信します。バッファーのkillにより、それに関連するプロセスにはSIGHUPシグナル、Emacsのkillにより残されたすべてのプロセスにSIGHUPシグナルが送信されます(SIGHUPは通常はユーザーが“hung up the phone”、電話を切った、つまり接続を断ったことを示す)。

シグナル送信関数はそれぞれprocesscurrent-groupいう2つのオプション引数を受け取ります。

引数processはプロセス、プロセス名、バッファー、バッファー名、またはnilのいずれかでなければなりません。バッファーやバッファー名はget-buffer-processを通じて得られるプロセスを意味します。nilはカレントバッファーに関連付けられたプロセスを意味します。stop-process and continue-processを除いて、processがプロセスを識別しない、あるいはネットワーク接続、シリアル接続、pipe接続を表す場合にはエラーがシグナルされます。

引数current-groupは、Emacsのサブプロセスとしてジョブ制御shell(job-control shell)を実行中の場合に異なる処理を行うためのフラグです。これが非nilなら、そのシグナルはEmacsがサブプロセスとの対話に使用する端末のカレントプロセスグループに送信されます。そのプロセスがジョブ制御shellなら、これはそのshellのカレントのsubジョブになります。current-groupnilなら、そのシグナルはEmacs自身のサブプロセスのプロセスグループに送信されます。そのプロセスがジョブ制御shellなら、それはshell自身になります。current-grouplambdaなら、端末を所有するもののそれ自身はshellでない場合にはプロセスグループにシグナルを送信します。

サブプロセスとの対話にpipeが使用されている際には、オペレーティングシステムがpipeの区別をサポートしないのでフラグcurrent-groupに効果はありません。同じ理由によりpipeが使用されていればジョブ制御shellは機能しないでしょう。非同期プロセスの作成process-connection-typeを参照してください。

Function: interrupt-process &optional process current-group

この関数はシグナルSIGINTを送信することによりプロセスprocessに割り込む。Emacs外部ではinterrupt character(割り込み文字。いくつかのシステムでは通常はC-c、それ以外のシステムではDEL)をタイプすることによりシグナルが送信される。引数current-groupが非nilのときは、Emacsがサブプロセスと対話する端末上でC-cがタイプされたと考えることができる。

Command: kill-process &optional process current-group

このコマンドはシグナルSIGKILLを送信することにより、プロセスprocessをkillする。このシグナルは即座にサブプロセスをkillする。サブプロセスでこれをハンドルすることはできない。インタラクティブに呼び出された場合には、ユーザーにプロセス名の入力を求める(デフォルトはもしあればカレントバッファーのプロセス)。

Function: quit-process &optional process current-group

この関数はプロセスprocessにシグナルSIGQUITを送信する。これはEmacs外部ではquit character(通常はC-\)により送信されるシグナル。

Function: stop-process &optional process current-group

この関数は指定したprocessを停止する。それがプログラムを実行中の実際のサブプロセスなら、そのサブプロセスにシグナルSIGTSTPを送信する。processがネットワーク接続、シリアル接続、pipe接続を表す場合には、この関数はその接続から到達するデータのハンドリングを抑制する。ネットワークサーバーでは、これは新たな接続をacceptしないことを意味する。通常の実行の再開にはcontinue-processを使用すること。

ジョブ制御をもつシステム上のEmacs外部ではstop character(通常はC-z)がSIGTSTPシグナルを送信する。current-groupが非nilなら、この関数をサブプロセスとの対話にEmacsが使用する端末上でC-zがタイプされたと考えることができる。

Function: continue-process &optional process current-group

この関数はプロセスprocessの実行を再開する。それがプログラムを実行中の実際のサブプロセスなら、そのサブプロセスにシグナルSIGCONTを送信する。この関数はprocessが以前に停止されたとみなす。processがネットワーク接続、シリアル接続、pipe接続を表す場合には、この関数はその接続から到達するデータのハンドリングを再開する。シリアル接続ではプロセス停止中に到達したデータは失われるかもしれない。

Command: signal-process process signal &optional remote

この関数はプロセスprocessにシグナルを送信する。引数signalはどのシグナルを送信するかを指定する。これは整数、または名前がシグナルであるようなシンボルであること。

process引数にはシステムプロセスID (整数)を指定できる。これによりEmacsの子プロセス以外のプロセスにシグナルを送信できる。別のプロセスへのアクセスを参照のこと。

processがプロパティremote-pidをもつプロセスオブジェクト、あるいはprocessが数値でremoteがリモートファイル名の場合には、processはプロセスにシグナルを送信するリモートホスト上のプロセスとして解釈される。

非ローカルな非同期プロセスへのシグナル送信が必要になることがあります。これはinterrupt-processおよびsignal-processにたいして実装を独自に記述することにより可能です。それからそれらの関数をそれぞれinterrupt-process-functionsおよびsignal-process-functionsに追加する必要があります。

Variable: interrupt-process-functions

この変数はinterrupt-process用に呼び出される関数のリスト。関数の引数はinterrupt-processにたいする引数と同じ。これらの関数はいずれかが非nilをリターンするまでリスト順に呼び出される。このリスト上で常に最後になるデフォルトの関数はinternal-default-interrupt-process

これはTrampがinterrupt-processを実装するメカニズムである。

Variable: signal-process-functions

この変数はsignal-process用に呼び出される関数のリスト。関数の引数はsignal-processにたいする引数と同じ。これらの関数はいずれかが非nilをリターンするまでリスト順に呼び出される。このリスト上で常に最後になるデフォルトの関数はinternal-default-signal-process

これはTrampがsignal-processを実装するメカニズムである。


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

40.9 プロセスからの出力の受信

非同期サブプロセスが自身の標準出力に書き込んだ出力はフィルター関数(filter function)と呼ばれる関数に渡されます。デフォルトのフィルター関数は単に出力をバッファーに挿入します。このバッファーをプロセスに関連付けられたバッファーと呼びます(プロセスのバッファーを参照)。プロセスがバッファーをもたなければデフォルトフィルターは出力を破棄します。

サブプロセスが自身の標準エラーストリームに書き込む場合には、デフォルトではそのエラー出力もプロセスフィルター関数に渡されます。かわりに非nil:stderrパラメーターでmake-process (make-processを参照)を呼び出して、エラーの出力先を標準出力から分けることができます。

サブプロセス終了時にEmacsは保留中の出力を読み取って、その後そのサブプロセスからの出力の読み取りを停止します。したがってそのサブプロセスに生きた子プロセスがあり、まだ出力を生成するような場合には、Emacsはその出力を受け取らないでしょう。

サブプロセスからの出力はEmacsが待機している間、端末入力読み取り時(関数waiting-for-user-input-p時間の経過や入力の待機sit-forsleep-forプロセスの出力を受け取るaccept-process-output、およびプロセスへのデータ送信関数(プロセスへの入力の送信を参照)のみ到着可能です。これは並列プログラミングで普遍的に悩みの種であるタイミングエラーの問題を最小化します。たとえば安全にプロセスを作成して、その後でのみプロセスのバッファーやフィルター関数を指定できます。その間にあるコードが待機するプリミティブを何も呼び出さなければ、完了するまで到着可能な出力はありません。

Variable: process-adaptive-read-buffering

いくつかのシステムではEmacsがサブプロセスの出力を読み取る際に出力データを非常に小さいブロックで読み取るために、結果として潜在的に非常に貧弱なパフォーマンスとなることがる。この挙動は変数process-adaptive-read-bufferingを非nil値(デフォルト)にセットして拡張することにより改善し得る。これにより、そのようなプロセスからの読み取りを自動的に遅延して、Emacsが読み取りを試みる前に出力がより多く生成されるようになる。


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

40.9.1 プロセスのバッファー

プロセスは関連付けられたバッファー(associated buffer)をもつことができます(通常はもつ)。これは普通のEmacsバッファーであり、2つの目的のために使用されます。1つはプロセスからの出力の格納、もう1つはプロセスをkillする時期を判断するためです。通常の習慣では任意の与えられたバッファーにたいして関連付けられるプロセスは1つだけなので、処理対象のプロセスを識別するためにそのバッファーを使用することもできます。プロセス使用の多くはプロセスに送信する入力を編集するためにもこのバッファーを使用しますが、これはEmacs Lispの組み込みではありません。

デフォルトでは、プロセスの出力は関連付けられたバッファーに挿入されます(カスタムフィルター関数の定義により変更可能。プロセスのフィルター関数を参照)。出力を挿入する位置はprocess-markにより決定されます。これは正に挿入されたテキストの終端にポイントを更新します。通常(常にではない)はprocess-markはバッファーの終端になります。

プロセスに関連付けられたバッファーをkillすることによりプロセスもkillされます。そのプロセスのprocess-query-on-exit-flagが非nilなら、Emacsはまず確認を求めます(exit前の問い合わせを参照)。この確認は関数process-kill-buffer-query-functionにより行われて、これはkill-buffer-query-functionsから実行されます(バッファーのkillを参照)。

Function: process-buffer process

この関数は指定されたprocessの関連付けられたバッファーをリターンする。

(process-buffer (get-process "shell"))
     ⇒ #<buffer *shell*>
Function: process-mark process

この関数はprocessにたいするプロセスマーカーをリターンする。これはプロセスからの出力をどこに挿入するかを示すマーカー。

processがバッファーをもたなければ、process-markは存在しない場所を指すマーカーをリターンする。

デフォルトのフィルター関数はプロセス出力の挿入場所の決定にこのマーカーを使用して、挿入したテキストの後にポイントを更新する。連続するバッチ出力が連続して挿入されるのはこれが理由。

カスタムフィルター関数はこのマーカーを通常は同じ方式で使用すること。process-markを使用するフィルター関数の例はProcess Filter Exampleを参照のこと。

ユーザーにプロセスバッファー内でプロセスに送信するための入力を期待する際には、プロセスマーカーは以前の出力から新たな入力を区別する。

Function: set-process-buffer process buffer

この関数はprocessに関連付けられたバッファーにbufferをセットする。buffernilならプロセスはバッファーに関連付けられない。非nilなら、bufferの終端ポイントにプロセスマークがセットされる。

Function: get-buffer-process buffer-or-name

この関数はbuffer-or-nameで指定されるバッファーに関連付けられた、削除されていないプロセスをリターンする。そのバッファーに複数のプロセスが関連付けられている場合には、この関数はいずれか1つ(現在のところもっとも最近作成されたプロセスだがこれを期待しないこと)を選択する。プロセスの削除(delete-processを参照)により、そのプロセスはこの関数がリターンするプロセスとしては不適格となる。

同一のバッファーに複数のプロセスを関連付けるのは、通常は悪いアイデアである。

(get-buffer-process "*shell*")
     ⇒ #<process shell>

プロセスのバッファーをkillすることにより、SIGHUPシグナルでサブプロセスをkillしてプロセスを削除する(プロセスへのシグナルの送信を参照)。

プロセスのバッファーがウィンドウに表示されている場合には、プロセスが出力をスクリーンのサイズに適応させるのと同様に、Lispプログラムでウィンドウのサイズにプロセス出力を適応させるようにプロセスに指示したいと思うでしょう。以下の関数によりプロセスにたいしてこの種の情報をやり取りできます。しかしすべてのシステムが基礎となる機能をサポートする訳ではないので、コマンドライン引数や環境変数を通じたフォールバックを提供するのが最良です。

Function: set-process-window-size process height width

processにたいして、その論理ウィンドウサイズが文字単位でwidthheightのサイズであることを告げる。関数がこの情報をプロセスとやり取りすることに成功したらt、それ以外はnilをリターンする。

プロセスに関連付けられたバッファーを表示するウィンドウがサイズを変更された際には、影響を受けるプロセスはその変更にたいして通知される必要があります。デフォルトではウィンドウ構成(window configuration)が変更されると、ウィンドウにバッファーが表示されている各プロセスにかわり、プロセスのバッファーを表示するすべてのウィンドウのうち最小のサイズのウィンドウを引数として、Emacsが自動的にset-process-window-sizeを呼び出します。これはバッファーが少なくとも1つのウィンドウに表示されているプセスそれぞれにたいして、変数window-adjust-process-window-size-functionの値である関数を呼び出すように指定するwindow-configuration-change-hook (ウィンドウのスクロールと変更のためのフックを参照)を通じて機能します。この変数をセットすることにより、この振る舞いをカスマイズできます。

User Option: window-adjust-process-window-size-function

この変数の値はプロセスとプロセスのバッファーを表示するウィンドウのリストという2つの引数を受け取る関数であること。その関数が呼び出される際には、そのプロセスのバッファーがカレントバッファーとなる。関数はset-process-window-sizeの呼び出しを通じて渡される論理プロセスウィンドウ(logical process window)を記述するコンスセル(width . height)をリターンすること。関数はnilをリターンすることもでき、Emacsはこの場合にはそのプロセスにたいしてset-process-window-sizeを呼び出さない。

この変数にたいしてEmacsは2つの事前定義された値を提供する。1つはwindow-adjust-process-window-size-smallestであり、これはプロセスのバッファーを表示するウィンドウのすべてのサイズから最小のサイズもう1つのwindow-adjust-process-window-size-largestは最大のサイズをリターンする。より複雑な方式には独自の関数を記述すること。

この変数はバッファーローカルにできる。

プロセスがadjust-window-size-functionプロパティ(プロセスの情報を参照)をもつ場合には、その値はwindow-adjust-process-window-size-functionのグローバル値とバッファーロール値をオーバーライドします。


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

40.9.2 プロセスのフィルター関数

プロセスのフィルター関数(filter function)は、関連付けられたプロセスからの標準出力を受信します。そのプロセスのすべての出力はそのフィルターに渡されます。デフォルトのフィルターは単にプロセスバッファーに直接出力します。

デフォルトではプロセス用のエラー出力がもしあれば、プロセス作成時にプロセスの標準エラーストリームが標準出力から分離されていなければフィルター関数に渡されます。Emacsは特定の関数の呼び出し中のみフィルター関数を呼び出します。プロセスからの出力の受信を参照してください。フィルターによりこれらの関数のいずれかが呼び出されると、フィルターが再帰的に呼び出されるかもしれないことに注意してください。

フィルター関数は関連付けられたプロセス、およびそのプロセスから正に受信した出力である文字列という2つの引数を受け取らなければなりません。関数はその後に出力にたいして何であれ自由に行うことができます。

quitは通常はフィルター関数内では抑制されます。さもないとコマンドレベルでのC-gのタイプ、またはユーザーコマンドのquitは予測できません。フィルター関数内部でのquitを許可したければinhibit-quitnilにバインドしてください。ほとんどの場合において、これを行う正しい方法はマクロwith-local-quitです。quitを参照してください。

フィルター関数の実行中にエラーが発生すると、フィルター開始時に実行中だったプログラムが何であれ実行を停止しないように自動的にcatchされます。しかしdebug-on-errorが非nilならエラーはcatchされません。これによりLispデバッガーを使用したフィルター関数のデバッグが可能になります。Lispデバッガを参照してください。エラーがcatchされると、ユーザーがそのエラーを確認できるようにEmacsは一時停止します(process-error-pause-time秒間)。非同期プロセスの作成を参照してください。

多くのフィルター関数は時折(または常に)、デフォルトフィルターの動作を真似てプロセスのバッファーにその出力を挿入します。そのようなフィルター関数は確実にカレントバッファーの保存と、(もし異なるなら)出力を挿入する前に正しいバッファーを選択して、その後に元のバッファーをリストアする必要があります。またそのバッファーがまだ生きているか、プロセスマーカーを更新しているか、そしていくつかのケースにおいてはポイントの値を更新しているかもチェックするべきです。以下はこれらを行う方法です:

(defun ordinary-insertion-filter (proc string)
  (when (buffer-live-p (process-buffer proc))
    (with-current-buffer (process-buffer proc)
      (let ((moving (= (point) (process-mark proc))))
        (save-excursion
          ;; テキストを挿入してプロセスマーカーを進める
          (goto-char (process-mark proc))
          (insert string)
          (set-marker (process-mark proc) (point)))
        (if moving (goto-char (process-mark proc)))))))

新たなテキスト到着時にフィルターが強制的にプロセスバッファーを可視にするためにwith-current-buffer構成の直前に以下のような行を挿入できます:

(display-buffer (process-buffer proc))

以前のポイント位置と関係なく新たな出力の終端にポイント位置を強制するためには、例から変数movingを削除して無条件でgoto-charを呼び出してください。これはウィンドウポイントの移動では必要ないことに注意してください。デフォルトのフィルターは実際にはウィンドウポイントを含むすべてのマーカーを移動するinsert-before-markersを使用します。これは無関係のマーカーを移動するかもしれないので、一般的にはウィンドウポイントを明示的に移動するか、挿入タイプをt (ウィンドウとポイントを参照)にセットしたほうがよいでしょう。

フィルター関数の実行中には、Emacsが自動的にマッチデータの保存とリストアを行うことに注意してください。マッチデータを参照してください。

フィルターへの出力は任意のサイズのchunkで到着する可能性があります。同じ出力を連続して2回生成するプログラムは一度に200文字を1回のバッチで送信して、次に40文字を5回のバッチで送信するかもしれません。フィルターが特定のテキスト文字列をサブプロセスの出力から探す場合には、それらの文字列が2回以上のバッチ出力を横断するケースに留意して処理してください。これを行うには受信したテキストを一時的なバッファーに挿入してから検索するのが1つの方法です。

Function: set-process-filter process filter

この関数はprocessにフィルター関数filterを与える。filternilなら、そのプロセスにたいしてプロセスバッファーにプロセス出力を挿入するデフォルトフィルターを与える。filtertの場合には、Emacsは接続待機でlisten中のネットワークサーバー以外のプロセスからの出力の受け入れを停止する。

Function: process-filter process

この関数はprocessのフィルター関数をリターンする。

そのプロセスの出力を複数のフィルターに渡す必要がある場合には、既存のフィルターに新たなフィルターを組み合わせるためにadd-functionを使用できる。Emacs Lisp関数にたいするアドバイスを参照のこと。

以下はフィルター関数の使用例:

(defun keep-output (process output)
   (setq kept (cons output kept)))
     ⇒ keep-output
(setq kept nil)
     ⇒ nil
(set-process-filter (get-process "shell") 'keep-output)
     ⇒ keep-output
(process-send-string "shell" "ls ~/other\n")
     ⇒ nil
kept
     ⇒ ("lewis@slug:$ "
"FINAL-W87-SHORT.MSS    backup.otl              kolstad.mss~
address.txt             backup.psf              kolstad.psf
backup.bib~             david.mss               resume-Dec-86.mss~
backup.err              david.psf               resume-Dec.psf
backup.mss              dland                   syllabus.mss
"
"#backups.mss#          backup.mss~             kolstad.mss
")

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

40.9.3 プロセス出力のデコード

Emacsが直接マルチバイトバッファーにプロセス出力を書き込む際には、プロセス出力のコーディングシステムに応じて出力をデコードします。コーディングシステムがraw-textno-conversionならEmacsはstring-to-multibyteを使用してユニバイト出力をマルチバイトに変換して、その結果のマルチバイトテキストを挿入します。

どのコーディングシステムを使用するかはset-process-coding-systemを使用して指定できます(プロセスの情報を参照)。それ以外ではcoding-system-for-readが非nilならそのコーディングシステム、nilならデフォルトのメカニズムが使用されます(デフォルトのコーディングシステムを参照)。プロセスのテキスト出力にnullバイトが含まれる場合には、Emacsはそれにたいしてデフォルトではno-conversionを使用します。この挙動を制御する方法についてはinhibit-null-byte-detectionを参照してください。

警告: データからコーディングシステムを判断するundecidedのようなコーディングシステムは、非同期サブプロセスの出力にたいして完全な信頼性をもって機能しません。これはEmacsが到着に応じて非同期サブプロセスの出力をバッチで処理する必要があるからです。Emacsは1つのバッチが到着するたびに正しいコーディングシステムを検出しなければならずこれは常に機能するわけではありません。したがって可能であれば文字コード変換とEOL変換の両方を決定するコーディングシステムつまりlatin-1-unixundecidedlatin-1のようなコーディングシステムを指定してください。

Emacsがプロセスフィルター関数を呼び出す際には、そのプロセスのフィルターのコーディングシステムに応じてEmacsはプロセス出力をマルチバイト文字列、またはユニバイト文字列で提供します。Emacsはプロセス出力のコーディングシステムに応じて出力をデコードします。これはbinaryraw-textのようなコーディングシステムを除いて、通常はマルチバイト文字列を生成します。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.9.4 プロセスの出力を受け取る

非同期サブプロセスからの出力は、通常はEmacsが時間の経過や端末入力のような、ある種の外部イベントを待機する間だけ到着します。特定のポイントで出力の到着を明示的に許可したり、あるいはプロセスからの出力が到着するまで待機することでさえ、Lispプログラムでは有用な場合が時折あります。

Function: accept-process-output &optional process seconds millisec just-this-one

この関数はプロセスからの保留中の出力をEmacsが読み取ることを許す。この出力はプロセスのフィルター関数により与えられる。この関数はprocessが非nilならprocessから何らかの出力を受け取るかprocessが接続をcloseするまでリターンしない。

引数secondsmillisecによりタイムアウトの長さを指定できる。前者は秒単位、後者はミリ秒単位でタイムアウトを指定する。この2つの秒数は、互いに足し合わせることによりタイムアウトを指定して、その秒数経過後はサブプロセスの出力が存在しなくてもリターンする。

secondsに浮動小数点数を指定することにより秒を小数点で指定できるので引数millisecは時代遅れ(であり使用するべきではない)。secondsが0ならこの関数は保留中の出力が何であれ受け取り待機しない。

processがプロセスで引数just-this-oneが非nilならプロセスからの出力だけが処理され、そのプロセスからの出力を受信するかタイムアウトとなるまで他のプロセスの出力は停止される。just-this-oneが整数ならタイマーの実行も抑制される。この機能は一般的には推奨されないが、音声合成のような特定のアプリケーションにとっては必要かもしれない。

関数accept-process-outputprocessprocessnilなら何らかのプロセスからから出力を取得したら非nilをリターンする。これは対応する接続にバッファーされたデータが含まれていれば、たとえプロセスのexit後にも発生し得る。この関数はタイムアウトが発生したり出力の到着前に接続がcloseされるとnilをリターンする。

プロセスからの接続にバッファーデータが含まれる場合には、プロセスのexit後でもaccept-process-outputが非nilをリターンするかもしれません。したがって、たとえ以下のようなループでも:

;; このループにはバグがある
(while (process-live-p process)
  (accept-process-output process))

これはprocessからすべての出力を読み取ることが頻繁にあり、接続にまだデータが含まれている間にprocess-live-pnilをリターンすると競合条件をもつとともに何らかのデータが失われるかもしれません。以下のようなループを記述するほうがよいでしょう:

(while (accept-process-output process))

make-processに非nilstderrを渡すと、標準エラープロセスをもつことになる。非同期プロセスの作成を参照のこと。この場合にはメインプロセスからのプロセス出力の待機は、標準エラープロセスからの出力を待機しない。プロセスからすべての標準出力と標準エラーを確実に受け取るためには、以下のコードを使用する:

(while (accept-process-output process))
(while (accept-process-output stderr-process))

make-processstderr引数にバッファーを渡した場合でも、以下のように標準エラープロセスを待機する必要があります:

(let* ((stdout (generate-new-buffer "stdout"))
       (stderr (generate-new-buffer "stderr"))
       (process (make-process :name "test"
                              :command '("my-program")
                              :buffer stdout
                              :stderr stderr))
       (stderr-process (get-buffer-process stderr)))
  (unless (and process stderr-process)
    (error "Process unexpectedly nil"))
  (while (accept-process-output process))
  (while (accept-process-output stderr-process)))

両方のaccept-process-outputフォームがnilをリターンしたときのみ、プロセスがexitしてEmacsがすべての出力を読み取ったと確信することができます。

この方法でリモートホスト上で実行中のプロセスからの保留中の標準エラーを読み取ることはできません。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.9.5 プロセスとスレッド

スレッドは比較的に新しくEmacs Lispに追加されたものであり、ダイナミックバインドがaccept-process-outputと組み合わせて使用される方法のために、デフォルトではプロセスはそれを作成したスレッドにロックされます。プロセスがスレッドにロックされた場合には、プロセスの出力はそのスレッドだけが受け取ることができます。

Lispプログラムはプロセスがロックされたスレッドがどれかを指定したり、あるいはEmacsにプロセスのアンロックを指示することができ、この場合にはプロセスの出力を任意のスレッドが受け取ることができます。与えられたプロセスから出力を待機できるのは一度に1つのスレッドだけです。1つのスレッドが一度出力を待機すると、プロセスはaccept-process-outputsit-forがリターンするまで一時的にロックされます。

スレッドがexitすると、それにロックされたすべてのプロセスがアンロックされます。

Function: process-thread process

processがロックされているスレッドをリターンする。processがロックされていなければnilをリターンする。

Function: set-process-thread process thread

processをロックするスレッドをthreadにセットする。threadnilでもよく、この場合にはプロセスはアンロックされる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.10 センチネル: プロセス状態の変更の検知

プロセスセンチネル(process sentinel: プロセス番兵)とは、(Emacsにより送信されたか、そのプロセス自身の動作が原因で送信された)プロセスを終了、停止、継続するシグナルを含む、何らかの理由により関連付けられたプロセスの状態が変化した際には常に呼び出される関数のことです。プロセスがexitする際にもプロセスセンチネルが呼び出されます。センチネルはイベントが発生したプロセスとイベントのタイプを記述する文字列という2つの引数を受け取ります。

プロセスにたいして何もセンチネル関数が指定されていなければ、プロセスのバッファーにプロセス名とイベントを記述する文字列とともにメッセージを挿入するデフォルトのセンチネル関数を使用します。

イベントを記述する文字列は以下のいずれかのような外見をもちます(ただしイベント文字列を網羅したリストではない):

  • "finished\n".
  • "deleted\n".
  • "exited abnormally with code exitcode (core dumped)\n".
    “core dumped”の部分はオプションであり、プロセスがコアをダンプした場合のみ出現する。
  • "failed with code fail-code\n".
  • "signal-description (core dumped)\n".
    signal-descriptionSIGKILLにたいする"killed"のようなシステム依存の説明テキスト。“core dumped”の部分はオプションであり、プロセスがコアをダンプした場合のみ出現する。
  • "open from host-name\n".
  • "open\n".
  • "run\n".
  • "connection broken by remote peer\n".

センチネルはEmacsが(端末入力や時間経過、またはプロセス出力を)待機している間だけ実行されます。これは他のLispプログラムの途中のランダムな箇所で実行されるセンチネルが原因となるタイミングエラーを無視します。プログラムはセンチネルが実行されるように、sit-forsleep-for(時間の経過や入力の待機を参照)、またはaccept-process-output(プロセスの出力を受け取るを参照)を呼び出すことにより待機することができます。Emacsはコマンドループが入力を読み取る際にもセンチネルの実行を許可します。delete-processは実行中のプログラムを終了させる際にセンチネルを呼び出します。

Emacsは1つのプロセスのセンチネル呼び出しの理由のために複数のキューを保持しません。これはカレント状態と変化があった事実だけを記録します。したがって非常に短い間隔で連続して状態に2つの変化があった場合には、一度だけセンチネルが呼び出されます。しかしプロセスの終了は常に正確に1回センチネルを実行するでしょう。これは終了後にプロセス状態が再び変更されることはないからです。

Emacsはプロセスセンチネル実行の前にプロセスからの出力をチェックします。プロセス終了によりセンチネルが一度実行されると、そのプロセスから更なる出力は到着しません。

プロセスのバッファーに出力を書き込むセンチネルは、そのバッファーがまだ生きているかチェックするべきです。死んだバッファーへの挿入を試みるとエラーになるでしょう。そのバッファーがすでに死んでいれば(buffer-name (process-buffer process))nilをリターンします。

quitは通常はセンチネル内では抑制されます。さもないとコマンドレベルでのC-gのタイプ、またはユーザーコマンドのquitは予測できません。センチネル内部でのquitを許可したければinhibit-quitnilにバインドしてください。ほとんどの場合において、これを行う正しい方法はマクロwith-local-quitです。quitを参照してください。

センチネルの実行中にエラーが発生した場合には、センチネル開始時に実行中だったプログラムが何であれ実行を停止しないように自動的にcatchされます。しかしdebug-on-errorが非nilならエラーはcatchされません。これによりLispデバッガーを使用したセンチネルのデバッグが可能になります。Lispデバッガを参照してください。エラーがcatchされると、ユーザーがそのエラーを確認できるようにEmacsは一時停止します(process-error-pause-time秒間)。非同期プロセスの作成を参照してください。

センチネルの実行中にはセンチネルが再帰的に実行されないように、プロセスセンチネルは一時的にnilにセットされます。この理由によりセンチネルが新たにセンチネルを指定することはできません。

センチネル実行中にはEmacsが自動的にマッチデータの保存とリストアを行うことに注意してください。マッチデータを参照してください。

Function: set-process-sentinel process sentinel

この関数はsentinelprocessに関連付ける。sentinelnilなら、そのプロセスはプロセス状態変更時にプロセスのバッファーにメッセージを挿入するデフォルトのセンチネルをもつことになるだろう。

プロセスセンチネルの変更は即座に効果を発揮する。そのセンチネルは実行される予定だがまだ呼び出されておらず、かつ新たなセンチネルを指定した場合には、最終的なセンチネル呼び出しには新たなセンチネルが使用されるだろう。

(defun msg-me (process event)
   (princ
     (format "Process: %s had the event '%s'" process event)))
(set-process-sentinel (get-process "shell") 'msg-me)
     ⇒ msg-me
(kill-process (get-process "shell"))
     -| Process: #<process shell> had the event 'killed'
     ⇒ #<process shell>
Function: process-sentinel process

この関数はprocessのセンチネルをリターンする。

あるプロセス状態の変化を複数のセンチネルに渡す必要がある場合には、既存のセンチネルと新たなセンチネルを組み合わせるためにadd-functionを使用できます。Emacs Lisp関数にたいするアドバイスを参照してください。

Function: waiting-for-user-input-p

この関数はセンチネルやフィルター関数の実行中に、もしEmacsがセンチネルやフィルター関数呼び出し時にユーザーのキーボード入力を待機していたら非nil、そうでなければnilをリターンする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.11 exit前の問い合わせ

Emacsがexitする際にはすべてのサブプロセスを終了します。プログラムを実行しているサブプロセスにはSIGHUPを送信して、接続は単にcloseされます。それらのサブプロセスはさまざまな処理を行っているかもしれないので、Emacsは通常ユーザーにたいしてそれらを終了しても大丈夫かどうか確認を求めます。各プロセスはquery(問い合わせ)のためのフラグをもち、これが非nilならEmacsはプロセスをkillしてexitする前に確認を行うべきであることを示します。queryフラグにたいするデフォルトはtで、これは問い合わせを行うことを意味しています。

Function: process-query-on-exit-flag process

これはprocessのqueryフラグをリターンする。

Function: set-process-query-on-exit-flag process flag

この関数はprocessのqueryフラグをflagにセットする。これはflagをリターンする。

以下はshellプロセス上で問い合わせを回避するためにset-process-query-on-exit-flagを使用する例:

(set-process-query-on-exit-flag (get-process "shell") nil)
     ⇒ nil
User Option: confirm-kill-processes

このユーザーオプションがt (デフォルト)にセットされていると、Emacsはexitに際してプロセスをkillする前に確認を求める。nilならEmacsは確認なしでプロセスをkillする(すべてのプロセスの問い合わせフラグを無視する)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.12 別のプロセスへのアクセス

カレントEmacsセッションのサブプロセスにたいするアクセスと操作に加えて、他のプロセスにたいしてEmacs Lispプログラムがアクセスすることもできます。Emacsのサブプロセスと区別するために、わたしたちはこれらをシステムプロセス(system processes)と呼んでいます。

Emacsはシステムプロセスへのアクセス用のプリミティブをいくつか提供します。これらのプリミティブはすべてのプラットフォームではサポートされません。これらのプリミティブはサポートされないシステムではnilをリターンします。

Function: list-system-processes

この関数はそのシステム上で実行中のすべてのプロセスのリストをリターンする。各プロセスはPIDというOSから割り当てられた数値によるプロセスIDにより識別され、同一時に同一マシン上で実行中の他のプロセスと区別される。

default-directoryがリモートホスト上を示す場合には、そのホスト上のプロセスがリターンされる。

Function: process-attributes pid

この関数はプロセスID pidで指定されるプロセスにたいする属性のalistをリターンする。このalist内の各属性は(key . value)という形式でありkeyは属性、valueはその属性の値である。この関数がリターン可能なさまざまな属性にたいするkeyを以下にリストした。これらすべての属性をすべてのプラットフォームがサポートする訳ではない。ある属性がサポートされていなければ、その連想値はリターンされるalist内に出現しない。

default-directoryがリモートホスト上を示す場合には、そのホスト上のpidとみなされる。

euid

そのプロセスを呼び出したユーザーの実効ユーザーID(effective user ID)。対応するvalueは数値。プロセスがカレントEmacsセッションを実行したユーザーと同じなら値はuser-uidがリターンする値と等しくなる(ユーザーの識別を参照)。

user

そのプロセスの実効ユーザーIDに対応するユーザー名であるような文字列。

egid

実行ユーザーIDのグループIDであるような数値。

group

実効ユーザーのグループIDに対応するグループ名であるような文字列。

comm

そのプロセス内で実効したコマンドの名前。これは通常は先行するディレクトリーを除いた実行可能ファイル名を指定する文字列。しかしいくつかの特別なシステムプロセスは、実行可能ファイルやプログラムに対応しない文字列を報告する可能性がある。

state

そのプロセスの状態コード。これはそのプロセスのスケジューリング状態をエンコードする短い文字列。以下は頻繁に目にするコードのリスト:

"D"

割り込み不可のsleep(通常はI/Oによる)

"R"

実行中

"S"

割り込み可能なsleep(何らかのイベント待ち)

"T"

ジョブ制御シグナルにより停止された

"Z"

zombie: 終了したが親プロセスに回収されていないプロセス

可能な状態の完全なリストはpsコマンドのman pageを参照のこと。

ppid

親プロセスのプロセスIDであるような数値。

pgrp

そのプロセスのプロセスグループIDであるような数値。

sess

そのプロセスのセッションID。これはそのプロセスのセッションリーダー(session leader)のプロセスIDであるような数値。

ttname

そのプロセスの制御端末の名前であるような文字列。これはUnixやGNUシステムでは通常は/dev/pts65のような対応する端末デバイスのファイル名。

tpgid

そのプロセスの端末を使用するフォアグラウンドプロセスグループのプロセスグループIDであるような数値。

minflt

そのプロセス開始以降に発生したマイナーなページフォルト数(マイナーなページフォルトとはディスクからの読み込みを発生させないページフォルト)。

majflt

そのプロセス開始以降に発生したメジャーなページフォルト数(メジャーなページフォルトとはディスクからの読み込みを要し、それ故にマイナーページフォルトより高価なページフォルト)。

cminflt
cmajflt

minfltmajfltと似ているが与えられたプロセスのすべての子プロセスのページフォルト数を含む。

utime

実行中のアプリケーションのコードにたいして、ユーザーコンテキスト内でプロセスに消費された時間。対応するvalueはLispのタイムスタンプ(時刻を参照)。

stime

システムコールの処理にたいしてシステム(kernel)コンテキスト内でプロセスに消費された時間。対応するvalueはLispのタイムスタンプ。

time

utimestimeの和。対応するvalueはLispのタイムスタンプ。

cutime
cstime
ctime

utimestimeと同様だが与えられたプロセスのすべての子プロセスの時間が含まれる点が異なる。

pri

そのプロセスの数値的な優先度。

nice

そのプロセスのnice値(nice value)であるような数値(小さいnice値のプロセスがより優先的にスケジュールされる)。

thcount

そのプロセス内のスレッド数。

start

プロセスの開始時刻(Lispのタイムスタンプ)。

etime

プロセスの開始からの経過時間(Lispのタイムスタンプ)。

vsize

そのプロセスの仮想メモリーのKB単位でのサイズ。

rss

そのプロセスがマシンの物理メモリー内で占める常駐セット(resident set)のKB単位でのサイズ。

pcpu

そのプロセス開始以降に使用されたCPU時間のパーセンテージ。valueは負ではない浮動小数点数。この数値はマルチコアプラットフォームでは理論上100を超過し得るものの、Emacsは通常はシングルスレッドなので100より小さくなる。

pmem

マシンにインストールされた物理メモリー合計のうち、そのプロセスの常駐セットのパーセンテージ。値は0から100の間の浮動小数点数。

args

そのプロセスが呼び出されたときのコマンドライン。これは個々のコマンドライン引数がブランクで区切られた文字列。引数に埋め込まれた空白文字はシステムに応じて適切にクォートされる。GNUやUnixではバックスラッシュ文字によるエスケープ、Windowsではダブルクォート文字で囲まれる。つまりこのコマンドライン文字列はshell-commandのようなプリミティブにより直接使用できる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.13 トランザクションキュー

トランザクションを用いてサブプロセスと対話するためにトランザクションキュー(transaction queue)を使用できます。まずtq-createを使用して指定したプロセスと対話するためのトランザクションキューを作成します。それからトランザクションを送信するためにtq-enqueueを呼び出すことができます。

Function: tq-create process

この関数はprocessと対話するトランザクションキューを作成してリターンする。引数processはバイトストリームを送受信する能力をもつサブプロセスであること。これは子プロセス、または(おそらく別のマシン上の)サーバーへのTCP接続かもしれない。

Function: tq-enqueue queue question regexp closure fn &optional delay-question

この関数はキューqueueにトランザクションを送信する。キューの指定は対話するサブプロセスを指定する効果をもつ。

引数questionはトランザクションを開始するために発信するメッセージ。引数fnは、それにたいする応答が返信された際に呼び出す関数。これはclosureと受信した応答という2つの引数で呼び出される。

引数regexpは応答全体の終端にマッチして、それより前にはマッチしない正規表現であること。これはtq-enqueueが応答の終わりを決定する方法である。

引数delay-questionが非nilなら、そのプロセスが以前に発信したすべてのメッセージへの返信が完了するまでメッセージの送信を遅延する。これによりいくつかのプロセスにたいして、より信頼性のある結果が生成される。

Function: tq-close queue

保留中のすべてのトランザクションの完了を待機して、トランザクションキューqueueをシャットダウンして、それから接続または子プロセスを終了する。

トランザクションキューはフィルター関数により実装されています。プロセスのフィルター関数を参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.14 ネットワーク接続

Emacs Lispプログラムは同一マシンまたは他のマシン上の別プロセスにたいしてストリーム(TCP)やデータグラム(UDP)のネットワーク接続(データグラムを参照)をオープンできます。ネットワーク接続はLispによりサブプロセスと同様に処理されて、プロセスオブジェクトとして表されます。しかし対話を行うそのプロセスはEmacsの子プロセスではなく、プロセスIDをもたず、それをkillしたりシグナルを送信することはできません。行うことができるのはデータの送信と受信だけです。delete-processは接続をクローズしますが、他方の端のプログラムをkillしません。そのプログラムは接続のクローズについて何を行うか決定しなければなりません。

ネットワークサーバーを作成することによりLispプログラムは接続をlistenできます。ネットワークサーバーもある種のプロセスオブジェクトとして表されますが、ネットワーク接続とは異なりネットワークサーバーがデータ自体を転送することは決してありません。接続リクエストを受信したときは、それにたいして作成した接続を表す新たなネットワーク接続を作成します(そのネットワーク接続はサーバーからプロセスplistを含む特定の情報を継承する)。その後でネットワークサーバーは更なる接続リクエストのlistenに戻ります。

ネットワーク接続とサーバーは、キーワード/引数のペアーで構成される引数リストでmake-network-processを呼び出すことにより作成されます。たとえば:server tはサーバープロセス、:type 'datagramはデータグラム接続を作成します。詳細は低レベルのネットワークアクセスを参照してください。以下で説明するopen-network-streamを使用することもできます。

異なるプロセスのタイプを区別するためにprocess-type関数はネットワーク接続とサーバーにはnetwork、シリアルポート接続はserial、pipe接続にはpipe、実際のサブプロセスにはrealをリターンします。

ネットワーク接続にたいしてprocess-status関数はopenclosedconnectstop、またはfailedをリターンします。ネットワークサーバーにたいしては状態は常にlistenになります。実際のサブプロセスにたいしてはstop以外の値はリターンされません。プロセスの情報を参照してください。

stop-processcontinue-processを呼び出すことにより、ネットワークプロセスの処理の停止と再開が可能です。サーバープロセスにたいする停止は新たな接続の受け付けないことを意味します(サーバー再開時は5つまでの接続リクエストがキューされる。これがOSによる制限でなければこの制限は増やすことができる。make-network-processmake-network-process:serverを参照)。ネットワークストリーム接続にたいしては、停止は入力の処理を行わないことを意味します(到着するすべての入力は接続の再開まで待つ)。データグラム接続にたいしては、いくらかのパケットはキューされますが入力は失われるかもしれません。ネットワーク接続またはサーバーが停止しているかどうかを判断するために、関数process-commandを使用できます。これが非nilなら停止しています。

ビルトインのGnuTLSトランスポート層セキュリティーライブラリーを使用することにより、Emacsは暗号化されたネットワーク接続を作成できます。the GnuTLS project pageを参照してください。これにはシステムにインストール済みの、gnutls-cliのようなヘルパーユーティリティーが必要です。GnuTLSサポートつきでEmacsをコンパイルした場合には関数gnutls-available-pが定義されて非nilをリターンします。詳細はOverview in The Emacs-GnuTLS manualを参照してください。open-network-stream関数は何であれ利用可能なサポートを使用して、暗号化接続作成の詳細を透過的に処理できます。

Function: open-network-stream name buffer host service &rest parameters

この関数はオプションで暗号つきでTCP接続をオープンして、その接続を表すプロセスオブジェクトをリターンする。

name引数はプロセスオブジェクトの名前を指定する。これは必要に応じて一意になるよう変更される。

buffer引数はその接続に関連付けるバッファー。その接続からの出力は出力を処理する独自のフィルター関数を指定していない場合には、buffernilならその接続はバッファーに関連付けられない。

引数hostserviceは接続先を指定する。hostはホスト名(文字列)、serviceは定義済みのネットワークサービス名(文字列)、またはポート番号(80のような整数か"80"のような整数文字列)。

残りの引数parametersは主に暗号化された接続に関連するキーワード/引数のペアー:

:nowait boolean

nilなら非同期接続を試みる。

:noquery query-flag

プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。

:coding coding

これはcoding-system-for-readcoding-system-for-writeのバインディングより優先してネットワークプロセスが使用するコーディングシステムをセットするために使用する。詳細はmake-network-processを参照のこと。

:type type

接続のタイプ。オプションは以下のとおり:

plain

通常の暗号化されていない接続。

tls
ssl

TLS (Transport Layer Security)接続。

nil
network

plain接続を開始してパラメーター‘:success’と‘:capability-command’が与えられたら、STARTTLSを通じて暗号化接続への更新を試みる。これが失敗したら暗号化されていない接続のまま留まる。

starttls

nilと同様だがSTARTTLSが失敗したらその接続を切断する。

shell

shell接続。

:always-query-capabilities boolean

nilなら、たとえ‘plain’な接続を行っているときでも常にサーバーの能力を問い合わせる。

:capability-command capability-command

ホストの能力を問い合わせるためのコマンド。文字列(そのままサーバーに送信される)、または関数(接続時のサーバーからの"greeting"を単一のパラメーターでとして呼び出されて文字列をリターンすること)のいずれか。

:end-of-command regexp
:end-of-capability regexp

コマンドの終端、またはコマンドcapability-commandの終端にマッチする正規表現。前者は後者のデフォルト。

:starttls-function function

単一の引数(capability-commandにたいする応答)をとりnil、またはサポートされていればSTARTTLSをアクティブにするコマンドをリターンする関数。

:success regexp

成功したSTARTTLSネゴシェーションにマッチする正規表現。

:use-starttls-if-possible boolean

nilなら、たとえEmacsがビルトインのTLSサポートをもっていなくても、日和見的(opportunistic)にSTARTTLSアップグレードを行う。

:warn-unless-encrypted boolean

nil、かつ:return-valueも非nilなら、接続が暗号化されていない場合にはEmacsは警告するだろう。これはほとんどのユーザーがネットワークトラフィックが暗号化されているこを期待するであろうIMAPやその類のプロトコルにたいして有用。

:client-certificate list-or-t

証明書(certificate)のキーと、証明書のファイル自身を命名する(key-file cert-file)という形式のリスト、またはこの情報にたいしてauth-sourceを尋ねることを意味するtのいずれか(auth-source in Emacs auth-source Libraryを参照)。TLSSTARTTLSにたいしてのみ使用される。:client-certificateを未指定時に、自動的なauth-sourceの問い合わせを有効にするには、network-stream-use-client-certificatestにカスタマイズすればよい。

:return-list cons-or-nil

この関数のリターン値。省略またはnilならプロセスオブジェクトをリターンする。それ以外なら(process-object . plist)という形式のコンスセルをリターンする。ここでplistは以下のキーワード:

:greeting string-or-nil

nilならホストからリターンされたgreeting(挨拶)文字列。

:capabilities string-or-nil

nilならホストの能力(capability)文字列。

:type symbol

接続タイプであり、‘plain’か‘tls’のいずれか。

:shell-command string-or-nil

接続typeshellなら、このパラメーターは接続の作成のために実行されるフォーマット仕様文字列として解釈される。利用可能な仕様はホスト名の‘%s’とポート番号の‘%p’。たとえばプレーン接続を作成する前にまず‘gateway’にsshで接続したければ、このパラメーターは‘ssh gateway nc %s %p’のようになるかもしれない。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.15 ネットワークサーバー

:server tmake-network-processを呼び出すことによりサーバーが作成されます(make-network-processを参照)。そのサーバーはクライアントからの接続リクエストをlistenするでしょう。クライアントの接続リクエストをaccept(受け入れる)する際は以下のようなパラメーターで、それ自体がプロセスオブジェクトであるようなネットワーク接続を作成します。

  • その接続のプロセス名はサーバープロセスのnameとクライアント識別文字列を結合して構築される。IPv4接続にたいするクライアント識別文字列はアドレスとポート番号を表す‘<a.b.c.d:p>’のような文字列。それ以外なら‘<nnn>’のようにカッコで囲まれた一意な数字。この数字はそのEmacsセッション内のそれぞれの接続にたいして一意。
  • サーバーが非デフォルトのフィルターをもつ場合には、その接続プロセスは別個にプロセスバッファーを取得しない。それ以外ならEmacsはその目的のために新たにバッファーを作成する。サーバーのバッファー名かプロセス名にクライアント識別文字列に結合したものがバッファー名になる。

    サーバーのプロセスバッファーの値が直接使用されることは決してないが、log関数は接続のログを記録するためにそれを取得して、そこにテキストを挿入して使用することができる。

  • 通信タイプ(communication type)、プロセスフィルター、およびセンチネルはそれぞれサーバーのものから継承される。サーバーが直接フィルターとセンチネルを使用することは決してない。それらの唯一の目的はサーバーへの接続を初期化することである。
  • その接続のプロセスコンタクト情報は、クライアントのアドレス情報(通常はIPアドレスとポート番号)に応じてセットされる。この情報はprocess-contactのキーワード:host:service:remoteに関連付けられる。
  • その接続のローカルアドレスは使用するポート番号に応じてセットアップされる。
  • クライアントプロセスのplistはサーバーのplistからインストールされる。

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.16 データグラム

データグラム(datagram)接続は、データストリームではなく個別のパッケージで対話します。process-sendを呼び出すたびに1つのデータグラムパケット(プロセスへの入力の送信を参照)が送信されて、受信されたデータグラムごとに1回フィルター関数が呼び出されます。

データグラム接続は毎回同じリモートピア(remote peer)と対話する必要はありません。データグラム接続はデータグラムの送信先を指定するリモートピアアドレス(remote peer address)をもちます。フィルター関数にたいして受信されたデータグラムが渡されるたびに、そのデータグラムの送信元アドレスがピアアドレスにセットされます。このようにもしフィルター関数がデータグラムを送信したら、それは元の場所へ戻ることになります。:remoteキーワードを使用してデータグラム接続を作成する際にはリモートピアアドレスを指定できます。set-process-datagram-addressを呼び出すことにより後からそれを変更できます。

Function: process-datagram-address process

processがデータグラム接続かサーバーなら、この関数はそれのリモートピアアドレスをリターンする。

Function: set-process-datagram-address process address

processがデータグラム接続かサーバーなら、この関数はそのリモートピアアドレスにaddressをセットする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.17 低レベルのネットワークアクセス

make-network-processを使用することにより、open-network-streamより低レベルでの処理からネットワーク接続を作成することもできます。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.17.1 make-network-process

ネットワーク接続やネットワークサーバーを作成する基本的な関数はmake-network-processです。これは与えられた引数に応じて、これらの仕事のいずれかを行うことができます。

Function: make-network-process &rest args

この関数はネットワーク接続やサーバーを作成して、それを表すプロセスオブジェクトをリターンする。引数argsはキーワード/引数のペアからなるリスト。キーワードの省略は:coding:filter-multibyte:reuseaddrを除いて、常に値としてnilを指定したのと同じことになる。重要なキーワードを以下に示す(ネットワークオプションに対応するキーワードを以降のセクションにリストする)。

:name name

プロセス名として文字列nameを使用する。一意にするために必要に応じて変更され得る。

:type type

コミュニケーションのタイプを指定する。値nilはストリーム接続(デフォルト)、datagramはデータグラム接続、seqpacketはシーケンスパケットストリーム(sequenced packet stream)による接続を指定する。接続およびサーバーの両方でこれらのタイプを指定できる。

:server server-flag

server-flagが非nilならサーバー、それ以外なら接続を作成する。ストリームタイプのサーバーではserver-flagはそのサーバーへの保留中の接続キューの長さを指定する整数を指定できる。キューのデフォルト長は5。

:host host

接続するホストを指定する。hostはホスト名かインターネットアドレス(文字列)、またはローカルホストを指定するシンボルlocal。サーバーをhostに指定する場合にはローカルホストにとって有効なアドレスを指定しなければならず、そのアドレスへはクライアント接続だけが許可されるようになる。localを使用する際にはデフォルトではIPv4を使用するが、ipv6familyを指定してこれをオーバーライドできる。すべてのインターフェースをlistenするにはIPv4では‘"0.0.0.0"’、IPv6では‘"::"’を指定する。いくつかのオペレーティングシステムでは‘"::"’をlistenするとIPv4もlistenするので、その後で別個にIPv4のlistenを試みると結果はエラーEADDRINUSE (‘"Address already in use"’)となるだろう。

:service service

serviceは接続先のポート番号、またはサーバーにたいしてはlistenするポート番号である。これは‘"https"’のようにポート番号に変換されるようなサービス名、または直接ポート番号を指定する‘443’のような整数か‘"443"’のような整数文字列であること。サーバーにたいしてはtも指定でき、これは未使用のポート番号をシステムに選択させることを意味する。

:family family

familyは接続のアドレス(またはプロトコル)のファミリーを指定する。nilは与えられたhostserviceにたいして自動的に適切なアドレスファミリーを決定する。localはUnixのsocketを指定して、この場合にはhostは無視される。ipv4ipv6はそれぞれIPv4とIPv6の使用を指定する。

:use-external-socket use-external-socket

use-external-socketが非nilなら割り当てられたsocketのかわりに呼び出し時にEmacsに渡されたsocketを使用する。これはEmacsサーバーのコードにおいてオンデマンドのsocketアクティベージョンを可能にするために使用される。Emacsがsocketを渡されていなければ、このオプションは暗黙に無視される。

:local local-address

サーバープロセスではlocal-addressはlistenするアドレスである。これはfamilyhostserviceをオーバーライドするので、これらを指定しないこともできる。

:remote remote-address

接続プロセスではremote-addressは接続先のアドレス。これはfamilyhostserviceをオーバーライドするので、これらを指定しないこともできる。

データグラムサーバーではremote-addressはリモートデータグラムアドレスの初期セッティングを指定する。

local-addressremote-addressのフォーマットはアドレスファミリーに依存する:

  • - IPv4アドレスは4つの8ビット整数と1つの16ビット整数からなる5要素のベクター[a b c d p]で表され、それぞれ数値的なIPv4アドレスa.b.c.d、およびポート番号pに対応する。
  • - IPv6アドレスは9要素の16ビット整数ベクター[a b c d e f g h p]で表され、それぞれ数値的なIPv6アドレスa:b:c:d:e:f:g:h、およびポート番号pに対応する。
  • - ローカルアドレスはローカルアドレススペース内でアドレスを指定する文字列として表される。
  • - 未サポートファミリー(unsupported family)のアドレスはコンスセル(f . av)で表される。ここでfはファミリー名、avはアドレスデータバイトごとに1つの要素を使用するソケットアドレスを指定するベクター。可搬性のあるコードでこのフォーマットを信頼してはならない。これは実装定義の定数、データサイズ、データ構造のアライメントに依存する可能性があるからだ。
:nowait bool

ストリーム接続にたいしてboolが非nilなら、その接続の完了を待機せずにリターンする。接続の成功や失敗時には、Emacsは"open" (成功時)、または"failed" (失敗時)にマッチするような第2引数によりセンチネル関数を呼び出すだろう。デフォルトではwaitせずにblockするので、make-network-processはその接続が成功または失敗するまでリターンしない。

非同期TLS接続をセットアップする場合には:tls-parametersパラメーター(下記参照)も提供する必要があるだろう。

Emacsの機能に応じて:nowaitが非同期になる方法は異なる。非同期で実行可能(または不可能)な3つの要素はドメイン名解決、socketのセットアップ、および(TLS接続にいする)TLSネゴシエーション。

プロセスオブジェクトと相互作用する多くの関数(たとえばprocess-datagram-address )は有用な値をリターンする以前に、少なくともsocketを所有することに依存する。これらの関数はsocketが望ましい状態に達するまでブロックされる。非同期socketと相互作用するための推奨方法はプロセスにセンチネルを配置して、その状態が‘"run"’になるまで相互作用を試みないことである。この方法ではこれらの関数はブロックされない。

:tls-parameters

TLS接続をオープンする際には最初の要素はTLSタイプ(gnutls-x509pkignutls-anonのいずれか)であり、残りの要素はgnutls-bootが受容するキーワードリスト形式であること(このキーワードリストはgnutls-boot-parameters関数で取得できる)。それからホストへの接続が完了後にTLS接続は確立される。

:stop stopped

stoppedが非nilならstopped(停止)の状態でネットワーク接続、またはサーバーを開始する。

:buffer buffer

プロセスバッファーとしてbufferを使用する。

:coding coding

このプロセスにたいするコーディングシステムとしてcodingを使用する。接続からのデータのデコードおよび接続への送信データのエンコードに異なるコーディングシステムを指定するには、codingにたいして(decoding . encoding)と指定する。

このキーワードをまったく指定しないかった場合のデフォルトは、そのデータからコーディングシステムを判断する。

:noquery query-flag

プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。

:filter filter

プロセスフィルターをfilterに初期化する。

:filter-multibyte multibyte

multibyteが非nilならマルチバイト文字列、それ以外ならユニバイト文字列がプロセスフィルターに与えられるデフォルトはt

:sentinel sentinel

プロセスセンチネルをsentinelに初期化する。

:log log

サーバープロセスのlog関数をlogに初期化する。サーバーがクライアントからネットワーク接続をacceptするたびにそのlog関数が呼び出される。log関数に渡される引数はserverconnectionmessage。ここでserverはサーバープロセス、connectionはその接続にたいする新たなプロセス、messageは何が発生したかを説明する文字列。

:plist plist

プロセスplistをplistに初期化する。

実際の接続情報で修正されたオリジナルの引数リストはprocess-contactを通じて利用できる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.17.2 ネットワークのオプション

以下のネットワークオプションはネットワークプロセス作成時に指定できます。:reuseaddrを除き、set-network-process-optionを使用してこれらのオプションを後からセットや変更することもできます。

サーバープロセスにたいしては、make-network-processで指定されたオプションはクライアントに継承されないので、子接続が作成されるたびに必要なオプションをセットする必要があるでしょう。

:bindtodevice device-name

device-nameがネットワークインターフェースを指定する空でない文字列なら、そのインターフェースで受信したパケットだけを処理する。device-namenil(デフォルト)なら任意のインターフェースが受信したパケットを処理する。

このオプションの使用にたいして特別な特権を要求するシステムがいくつかあるかもしれない。

:broadcast broadcast-flag

データグラムプロセスにたいしてbroadcast-flagが非nilなら、そのプロセスはブロードキャストアドレスに送信されたデータグラムパケットを受信して、ブロードキャストアドレスにパケットを送信できるだろう。これはストリーム接続では無視される。

:dontroute dontroute-flag

dontroute-flagが非nilならプロセスはローカルホストと同一ネットワーク上のホストだけに送信することができる。

:keepalive keepalive-flag

ストリーム接続にたいしてkeepalive-flagが非nilなら、低レベルのkeep-aliveメッセージの交換が有効になる。

:linger linger-arg

linger-argが非nilなら、接続を削除(delete-processを参照)する前にキューされたすべてのパケットの送信が成功するまで待機する。linger-argが整数なら、接続クローズ前のキュー済みパケット送信のために待機する最大の秒数を指定する。デフォルトはnilで、これはプロセス削除時に未送信のキュー済みパケットを破棄することを意味する。

:oobinline oobinline-flag

ストリーム接続にたいしてoobinline-flagが非nilなら、通常のデータストリーム内の帯域外(out-of-band)データを受信して、それ以外なら帯域外データは破棄する。

:priority priority

この接続で送信するパケットの優先順位を整数priorityにセットする。たとえばこの接続で送信するIPパケットのTOS(type of service)フィールドにセットする等、この数字の解釈はプロトコルに固有である。またそのネットワークインターフェース上で特定の出力キューを選択する等、これにはシステム依存の効果もある。

:reuseaddr reuseaddr-flag

ストリームプロセスサーバーにたいしてreuseaddr-flagが非nil (デフォルト)なら、そのホスト上の別プロセスがそのポートですでにlistenしていなければ、このサーバーは特定のポート番号(:serviceを参照)を再使用できる。reuseaddr-flagnilなら、(そのホスト上の任意のプロセスが)そのポートを最後に使用した後、そのポート上で新たなサーバーを作成するのが不可能となるような一定の期間が存在するかもしれない。

Function: set-network-process-option process option value &optional no-error

この関数はネットワークプロセスprocessにたいしてネットワークオプションのセットや変更を行う。指定できるオプションはmake-network-processと同様。no-errorが非nilなら、optionがサポートされないオプションの場合に、この関数はエラーをシグナルせずにnilをリターンする。この関数が成功裏に完了したらtをリターンする。

あるオプションのカレントのセッティングはprocess-contact関数を通じて利用できる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.17.3 ネットワーク機能の可用性のテスト

与えられネットワーク機能が利用可能かテストするためには以下のようにfeaturepを使用します:

(featurep 'make-network-process '(keyword value))

このフォームの結果はmake-network-process内でkeywordに値valueを指定することが機能するならtになります。以下はこの方法でテストできるkeyword/valueペアーのいくつかです。

(:nowait t)

非ブロッキング接続がサポートされていれば非nil

(:type datagram)

データグラムがサポートされていれば非nil

(:family local)

ローカルsocket(別名“UNIX domain”)がサポートされていれば非nil

(:family ipv6)

IPv6がサポートされていれば非nil

(:service t)

サーバーにたいしてシステムがポートを選択できれば非nil

与えられたネットワークオプションが利用可能かテストするためには、以下のようにfeaturepを使用します:

(featurep 'make-network-process 'keyword)

指定できるkeywordの値は:bindtodevice等です。完全なリストはネットワークのオプションを参照してください。このフォームはmake-network-process (またはset-network-process-option)が特定のネットワークオプションをサポートしていれば非nilをリターンします。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.18 その他のネットワーク機能

以下の追加の関数はネットワーク接続の作成や操作に有用です。これらはいくつかのシステムでのみサポートされることに注意してください。

Function: network-interface-list &optional full family

この関数は使用しているマシン上のネットワークインターフェースを記述するリストをリターンする。値は要素が(ifname . address)という形式をもつようなalist。ifnameはそのインターフェースを命名する文字列、addressmake-network-processの引数local-addressおよびremote-addressの形式と同じ。デフォルトでは可能ならIPv4とIPv6の両方のアドレスをリターンする。

オプション引数fullが非nilなら、かわりに(ifname addr bcast netmask)という形式の要素を1つ以上もつリストをリターンする。ifnameはそのインターフェースを命名する一意ではない文字列。addrbcastnetmaskはそれぞれIPアドレス、ブロードキャストアドレス、ネットワークマスクを詳述する整数のベクター。

シンボルipv4またはipv6としてオプション引数familyを指定すると、fullの値とは独立してリターンする情報をそれぞれIPv4またはIPv6に制限する。IPv6サポートが利用不可な際にipv6を指定するとエラーがシグナルされるだろう。

いくつか例を示す:

(network-interface-list) ⇒
(("vmnet8" .
  [172 16 76 1 0])
 ("vmnet1" .
  [172 16 206 1 0])
 ("lo0" .
  [65152 0 0 0 0 0 0 1 0])
 ("lo0" .
  [0 0 0 0 0 0 0 1 0])
 ("lo0" .
  [127 0 0 1 0]))
(network-interface-list t) ⇒
(("vmnet8"
  [172 16 76 1 0]
  [172 16 76 255 0]
  [255 255 255 0 0])
 ("vmnet1"
  [172 16 206 1 0]
  [172 16 206 255 0]
  [255 255 255 0 0])
 ("lo0"
  [65152 0 0 0 0 0 0 1 0]
  [65152 0 0 0 65535 65535 65535 65535 0]
  [65535 65535 65535 65535 0 0 0 0 0])
 ("lo0"
  [0 0 0 0 0 0 0 1 0]
  [0 0 0 0 0 0 0 1 0]
  [65535 65535 65535 65535 65535 65535 65535 65535 0])
 ("lo0"
  [127 0 0 1 0]
  [127 255 255 255 0]
  [255 0 0 0 0]))
Function: network-interface-info ifname

この関数はifnameという名前のネットワークインターフェースに関する情報をリターンする。値は(addr bcast netmask hwaddr flags)という形式をもつリスト。

addr

インターネットプロトコルアドレス。

bcast

ブロードキャストアドレス。

netmask

ネットワークマスク。

hwaddr

レイヤー2アドレス(たとえばイーサネットMACアドレス)。

flags

そのインターフェースのカレントのフラグ。

この関数はIPv4の情報だけをリターンすることに注意。

Function: format-network-address address &optional omit-port

この関数はネットワークアドレスのLisp表現を文字列に変換する。

5要素のベクター[a b c d p]はIPv4アドレスa.b.c.d、およびポート番号pを表す。format-network-addressはこれを文字列"a.b.c.d:p"に変換する。

9要素のベクター[a b c d e f g h p]はポート番号とともにIPv6アドレスを表す。format-network-addressはこれを文字列"[a:b:c:d:e:f:g:h]:p"に変換する。

このベクターにポート番号が含まれない、またはomit-portが非nilなら結果にサフィックス:pは含まれない。

Function: network-lookup-address-info name &optional family hints

この関数はnameでホスト名の照合を行う。この名前にはASCII文字列のみを期待しており、さもなくばエラーをシグナルする。国際化されたホスト名を照合したければ、最初にnameにたいしてpuny-encode-domainを呼び出すこと。

この関数は成功時にはネットワークアドレスを表すLispのリスト(フォーマットについてはmake-network-processを参照)、それ以外はnilをリターンする。後者の場合には、(運がよければ)何が悪かったのかを説明するエラーメッセージもロギングされるだろう。

デフォルトではIPv4とIPv6の両方の照合を試みる。オプション引数familyがこの挙動を制御する。これにシンボルipv4またはipv6を指定すると、それぞれIPv4またはIPv6に照合を制限する。

オプション引数のhintsnumericなら、この関数はnameを数値によるIPアドレスとして扱う(更にDNSの照合も行わない)。これは文字列がIPアドレスを表す有効な数値かどうかをチェックしたり、数値であるような文字列を正規の表現に変換する場合に役に立つかもしれない。たとえば

(network-lookup-address-info "127.1" 'ipv4 'numeric)
    ⇒ ([127 0 0 1 0])

(network-lookup-address-info "::1" nil 'numeric)
    ⇒ ([0 0 0 0 0 0 0 1 0])

特にIPv4ではたとえば‘0’や‘1’が有効であるのと同様に、‘0xe3010203’や‘0343.1.2.3’のように驚くような形式も有効であることに注意(ただしIPv6では無効)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.19 シリアルポートとの対話

Emacsはシリアルポートと対話できます。インタラクティブなM-x serial-termの使用にたいしては端末ウィンドウをオープンして、Lispプログラムmake-serial-processにたいしてはプロセスオブジェクトを作成します。

シリアルポートはクローズと再オープンなしで実行時に設定することができます。関数serial-process-configureによりスピード、バイトサイズ、およびその他のパラメーターを変更できます。serial-termで作成された端末ウィンドウではモードラインをクリックして設定を行うことができます。

シリアル接続はプロセスオブジェクトとして表されて、サブプロセスやネットワークプロセスと同様の方法で使用できます。これによりデータの送受信やシリアルポートの設定ができます。しかしシリアルプロセスオブジェクトにプロセスIDはありません。それにたいしてシグナルの送信はできずステータスコードは他のタイプのプロセスオブジェクトとは異なります。プロセスオブジェクトへのdelete-process、またはプロセスバッファーにたいするkill-bufferは接続をクローズしますが、そのシリアルポートに接続されたデバイスに影響はありません。

関数process-typeはシリアルポート接続を表すプロセスオブジェクトにたいするシンボルserialをリターンします。

シリアルポートはGNU/LinuxやUnix、そしてMS Windowsのシステムで利用できます。

Command: serial-term port speed &optional line-mode

新たなバッファー内でシリアルポートにたいする端末エミュレーターを開始する。portは接続先のシリアルポートの名前。たとえばUnixではこれは/dev/ttyS0のようになるだろう。MS WindowsではCOM1\\.\COM10のようになるかもしれない(Lisp文字列ではバックスラッシュは2重にすること)。

speedはビット毎秒でのシリアルポートのスピード。一般的な値は9600。そのバッファーはTermモードになる。このバッファーで使用するコマンドについてはTerm Mode in The GNU Emacs Manualを参照のこと。モードラインメニューからスピードと設定を変更できる。line-modeが非nilならterm-line-mode、それ以外はterm-raw-modeを使用する。

Function: make-serial-process &rest args

この関数はプロセスとバッファーを作成する。引数はキーワード/引数ペアーで指定する。以下は意味のあるキーワードのリストで、最初の2つ(portspeed)は必須:

:port port

これはシリアルポートの名前。UnixやGNUシステムでは/dev/ttyS0のようなファイル名、WindowsではCOM1COM9より高位のポートでは\\.\COM10のようになるかもしれない(Lisp文字列ではバックスラッシュは2重にすること)。

:speed speed

ビット毎秒でのシリアルポートのスピード。この関数はserial-process-configureを呼び出すことによりスピードを操作する。この関数の更なる詳細については以降のドキュメントを参照のこと。

:name name

そのプロセスの名前。nameが与えられなければportがプロセス名の役目も同様に果たす。

:buffer buffer

そのプロセスに関連付けられたバッファー。値はバッファー、またはそれがバッファーの名前であるような文字列かもしれない。出力を処理するために出力ストリームやフィルター関数を指定しなければ、プロセス出力はそのバッファーの終端に出力される。bufferが与えられなければ、そのプロセスバッファーの名前は:nameキーワードから取得される。

:coding coding

codingはこのプロセスにたいする読み書きに使用されるコーディングシステムを指定する。codingがコンス(decoding . encoding)なら読み取りにdecoding、書き込みにはencodingが使用される。指定されない場合のデフォルトはデータ自身から判断されるコーディングシステム。

:noquery query-flag

プロセスqueryフラグをquery-flagに初期化する。exit前の問い合わせを参照のこと。未指定の場合のフラグのデフォルトはnil

:stop bool

boolが非nilならstoppedの状態でプロセスを開始する。stopped状態ではシリアルプロセスは入力データを受け付けないが出力データの送信は可能。stopped状態のクリアーはcontinue-process、セットはstop-processで行う。

:filter filter

プロセスフィルターとしてfilterをインストールする。

:sentinel sentinel

プロセスセンチネルとしてsentinelをインストールする。

:plist plist

プロセスの初期plistとしてplistをインストールする。

:bytesize
:parity
:stopbits
:flowcontrol

これらはmake-serial-processが呼び出すserial-process-configureにより処理される。

後の設定により変更され得るオリジナルの引数リストは関数process-contactを通じて利用可能。

以下は例:

(make-serial-process :port "/dev/ttyS0" :speed 9600)
Function: serial-process-configure &rest args

この関数はシリアルポート接続を設定する。引数はキーワード/引数ペアーで指定する。与えられない属性はそのプロセスのカレントの設定(関数process-contactを通じて利用可能)から再初期化されるか、妥当なデフォルトにセットされる。以下の引数が定義されている:

:process process
:name name
:buffer buffer
:port port

設定するプロセスを識別するために、これらの引数のいずれかが与えられる。これらの引数が何も与えられなければカレントバッファーのプロセスが使用される。

:speed speed

ビット毎秒、別名ボーレート(baud rate)によるシリアルポートのスピード。値には任意の数字が可能だが、ほとんどのシリアルポートは1200から115200の間の数少ない定義済みの値でのみ機能して、もっとも一般的な値は9600。speednilなら、この関数は他のすべての引数を無視してそのポートを設定しない。これは接続を通じて送信された‘AT’コマンドでのみ設定可能な、Bluetooth/シリアル変換アダプターのような特殊なシリアルポートで有用かもしれない。speedにたいする値nilmake-serial-processserial-termの呼び出しにより、すでにオープン済みの接続にたいしてのみ有効。

:bytesize bytesize

ビット/バイトでの数値で7か8を指定できる。bytesizeが与えられない、またはnilの場合のデフォルトは8。

:parity parity

値にはnil (パリティなし)、シンボルodd (奇数パリティ)、シンボルeven (偶数パリティ)を指定できる。parityが与えられない場合のデフォルトはパリティなし。

:stopbits stopbits

各バイトの送信を終了するために使用されるストップビットの数値。stopbitsには1か2が可能。stopbitsが与えられない、またはnilの場合のデフォルトは1。

:flowcontrol flowcontrol

この接続にたいして使用するフロー制御のタイプでnil (フロー制御を使用しない)、シンボルhw (RTS/CTSハードウェアフロー制御)、シンボルsw (XON/XOFFソフトウェアフロー制御)のいずれか。flowcontrolが与えられない場合のデフォルトはフロー制御なし。

シリアルポートの初期設定のためにmake-serial-processは内部的にserial-process-configureを呼び出す。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.20 バイト配列のpackとunpack

このセクションでは通常はバイナリーのネットワークプロトコル用のバイト配列をpackやunpackする方法を説明します。以下の関数はバイト配列とalistとの間で相互に変換を行います。バイト配列はユニバイト文字列、または整数ベクターとして表現することができます。一方でalistはシンボルを固定サイズのオブジェクト、または再帰的な副alistのいずれかに関連付けます。このセクションで参照する関数を使用するためにはbindatライブラリーをロードしてください。

バイト配列からネストされたalistへの変換は逆方向への変換がシリアライズ化(serializing)またはpack化(packing)として呼ばれることから、非シリアル化【deserializing)またはunpack化(unpacking)として知られています。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.20.1 データレイアウトの記述

unpackとpackを制御するためには、データレイアウト仕様(data layout specification)を記述します(Bindatタイプ式(Bindat type expression)とも呼ばれる)。これにはベースタイプ(base type)と複数フィールドからなるコンポジットタイプ(composite type)があり、処理するフィールドそれぞれの長さ、packやunpackを行う方法をこの仕様が制御します。わたしたちはbindatタイプの値を、通常は-bindat-specで終わる名前の変数に保持しています。このような種類の名前は、自動的に危険(risky)だと認識されます(ファイルローカル変数を参照)。

Macro: bindat-type &rest type

Bindatタイプのであるtypeに応じて、Bindatタイプのオブジェクトを作成する。

フィールドのタイプ(type)はフィールドが表すオブジェクトのサイズ(バイト単位)、およびそれがマルチバイトフィールドならフィールがバイトオーダーされる方法を記述します。可能なオーダーはビッグエンディアン(big endian。ネットワークバイトオーダーとも呼ばれる)、およびリトルエンディアン(little endian)の2つです。たとえば数字#x23cd (10進の9165)のビッグエンディアンは#x23 #xcdの2バイト、リトルエンディアンは#xcd #x23になるでしょう。以下は可能なタイプの値です:

u8
byte

長さ1の符号なしタイプ。

uint bitlen &optional le

長さbitlenビットのネットワークバイトオーダー(ビッグエンディアン)による符号なし整数。bitlenは8の倍数であること。leが非nilなら、リトルエンディアンによるバイトオーダーを使用する。

sint bitlen le

長さbitlenビットのネットワークバイトオーダー(ビッグエンディアン)による符号付き整数。bitlenは8の倍数であること。leが非nilなら、リトルエンディアンによるバイトオーダーを使用する。

str len

長さがlenバイトであるようなユニバイト文字列(テキストの表現方法を参照)。packを行う際には入力文字列の最初のlenバイトがpack済み出力にコピーされる。入力文字列がlenより短い場合には、残りのバイトはnull(0)になる。ただし事前に割り当てた文字列がbindat-packに与えられた場合には、残りのバイトは未変更のまま残される。入力文字列がASCII文字とeight-bit文字だけから構成されたマルチバイト文字列の場合には、packを行う前にユニバイトに変換される。それ以外のマルチバイト文字列の場合にはエラーをシグナルする。unpackを行う際には、pack済み入力文字列中のすべてのnullバイトはunpack済み出力にも出現することになるだろう。

strz &optional len

lenが与えられない場合にはnull終端された可変長ユニバイト文字列である(テキストの表現方法を参照)。strzへpackする際には、入力文字列全体にnull(0)バイトを付加してpack出力にコピーする(strzへのpackに事前割り当て済みの文字列が与えられた場合には、その事前割り当て済み文字列は出力文字列の終端にnullバイトを付加するための十分なスペースをもっている必要がある; バイトのunpackとpackを行う関数を参照)。pack済み出力の長さは、入力文字列の長さに(null終端用の)1を加えた値になる。入力文字列にnullバイトが含まれていてはならない。入力文字列がASCII文字とeight-bit文字だけから構成されたマルチバイト文字列の場合には、packを行う前にユニバイトに変換される。それ以外のマルチバイト文字列の場合にはエラーをシグナルする。strzのunpack時には、入力文字列を終端するnullバイトまで(ただしnullバイト自体は除外)のすべてのバイトが出力文字列に含まれることになる。

lenが与えられた場合にはstrと同じように振る舞うが2つ異なる点がある:

  • pack時に入力文字列の文字数がlenより短ければpackした入力文字列の後にnull終端が書き込まれる。
  • unpack時にはpack済み文字列d最初に見つかったnullバイトはバイトの終端とみなされて、そのnullバイトと後続のバイトはunpackの結果から除外される。

警告: 入力文字列がlenより短かったり、最初のlenバイトにnullバイトが含まれている場合のみ、pack済出力がnull終端される。

vec len [type]

len要素のベクター。要素のタイプはtypeにより与えられる(デフォルトはバイト)。typeは任意のBindatタイプ式を指定できる。

repeat len [type]

vecと同様だがリストから双方向にunpack/packする(vecはunpackするベクター)。

bits len

lenバイト内で1にセットされたビットのリスト。バイトはビッグエンディアンオーダーで、ビットは8 * len - 1で始まり0で終わるよう番号が付けされる。たとえばbits 2では、#x28 #x1c(2 3 4 11 13)#x1c #x28(3 5 10 11 12)にunpackされる。

fill len

lenバイトは単なるフィラーとして使用される。これらのバイトはpack時には未変更のままとなり通常は0のままであることを、unpack時には単にnilをリターンすることを意味する。

align len

fillと同様だが、次のlenの倍数バイトまでスキップを要するバイト数である点が異なる。

type exp

これによりタイプを間接的に参照できる。expはBindatタイプvalueをリターンするLisp式であること。

unit exp

これは0ビットのスペースを使用する簡易タイプ。expはそのようなフィールドの“unpack”を試みた際にリターンされる値を記述する。

struct fields...

複数フィールドから構成されるコンポジットタイプ(composite typex: 複合型)。フィールドはそれぞれ(name type)という形式をもち、typeには任意のBindatタイプ式を指定できる。alignfillのフィールドのように、そのフィールド値が命名に値しない場合には、name_でもよい。コンテキストによりBindatタイプ式であることが明確なら、シンボルstructは省略可。

上述のタイプの中で、lenbitlenはフィールド内のバイト数(またはビット数)を指定する整数として与えられます。そのフィールドが固定長でなければ、通常は値は先行するフィールドの値に依存します。この理由により、lenの長さは定数である必要がないので任意のLisp式を指定することができ、フィールド名から先行するフィールドの値を通じて参照することができるのです。

たとえば先頭のバイトが16ビット整数の後続ベクターにサイズを与えるデータレイアウトの仕様は、以下のようになります:

(bindat-type
  (len      u8)
  (payload  vec (1+ len) uint 16))

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.20.2 バイトのunpackとpackを行う関数

以降のドキュメントではtypebindat-typeがリターンするようなBindatデータ値、rawはバイト配列、structはunpackされたフィールドデータを表すalistを参照します。

Function: bindat-unpack type raw &optional idx

この関数はユニバイト文字列、またはバイト配列rawのデータをtypeに応じてunpackする。これは通常はバイト配列の先頭からunpack化を開始するが、idxが非nilならかわりに使用する0基準の開始位置を指定する。

値はそれぞれの要素がunpackされたフィールドを記述するalistかネストされたalist。

Function: bindat-get-field struct &rest name

この関数はネストされたalistであるstructからフィールドのデータを選択する。structは通常はbindat-unpackがリターンしたもの。nameが単一の引数に対応する場合にはトップレベルのフィールド値を抽出することを意味する。複数のname引数は副構造体を繰り返して照合することを指定する。nameが整数なら配列のインデックスとして動作する。

たとえば(bindat-get-field struct a b 2 c)なら、フィールドaの副フィールドbの3つ目の要素からフィールドcを探すことを意味する(Cプログラミング言語の構文struct.a.b[2].cに該当)。

packやunpackの処理をすることによりメモリー内でデータ構造が変化しても、そのデータの全フィールド長の合計バイト数であるトータル長(total length)は保たれます。この値は一般的に仕様またはalist単独では固有ではありません。そのかわりこれら両方の情報がこの計算に役立ちます。同様にunpackされる文字列や配列の長さは仕様の記述にしたがってデータのトータル長より長くなるかもしれません。

Function: bindat-length type struct

この関数はstruct内のデータのtypeに応じたトータル長をリターンする。

Function: bindat-pack type struct &optional raw idx

この関数はalist struct内のデータからtypeに応じてpackされたバイト配列をリターンする。これは通常は先頭から充填された新たなバイト配列を作成する。しかしrawが非nilなら、それはpack先として事前に割り当てられたユニバイト文字列かベクターを指定する。idxが非nilならrawへpackする開始オフセットを指定する。

事前に割り当てる際にはout-of-rangeエラーを避けるために、(length raw)がトータル長またはそれ以上であることを確認すること。

Function: bindat-ip-to-string ip

インターネットアドレスのベクターipを通常のドット表記による文字列に変換する。

(bindat-ip-to-string [127 0 0 1])
     ⇒ "127.0.0.1"

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

40.20.3 高度なデータレイアウト仕様

Bindatタイプ式は、これまでに説明したタイプに限定されません。Bindatタイプ式をリターンする、任意のLispフォームも可能です。たとえば以下のタイプは24ビットカラー、またはバイトのベクターのいずれかを含むことが可能なデータを記述します:

(bindat-type
  (len      u8)
  (payload  . (if (zerop len) (uint 24) (vec (1- len)))))

さらに複合タイプは通常は連想リストにunpack(または逆にpack)されませんが、以下のスペシャルキーワード引数を使用してこれを変更することができます:

:unpack-val exp

フィールドのリストがこのキーワードで終わる場合には、unpack時リターンされる値は標準のalistではなくexpの値となる。expは名前によって前のフィールドすべてを参照できる。

:pack-val exp

このキーワード引数がフィールドのタイプの後に続く場合には、このフィールドにはalistから抽出するかわりにexpがリターンした値がpackされる。

:pack-var name

このキーワード引数がフィールドのリストの前に前置されている場合には、後続するすべての:pack-val引数がnameという名前の引数を介して、この複合タイプにpackされた全体値を参照できる。

たとえば以下のように16ビット符号付き整数を記述できます:

(defconst sint16-bindat-spec
  (let* ((max (ash 1 15))
         (wrap (+ max max)))
    (bindat-type :pack-var v
                 (n uint 16 :pack-val (if (< v 0) (+ v wrap) v))
                 :unpack-val (if (>= n max) (- n wrap) n))))

これは以下のようになります:

(bindat-pack sint16-bindat-spec -8)
     ⇒ "\377\370"

(bindat-unpack sint16-bindat-spec "\300\100")
     ⇒ -16320

最後にbindat-defmacroでBindatタイプ式を使用することによって、Bindatタイプフォームを新たに定義できます:

Macro: bindat-defmacro name args &rest body

argsを受け取るnameという名前のBindatタイプ式を新たに定義する。これの挙動はdefmacroに準ずるが、重要な違いは新たなフォームがBindatタイプ式でのみ使用できることである。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41 Emacsのディスプレイ表示

このチャプターではEmacsによるユーザーへのプレゼンテーションとなる、表示に関連するいくつかの機能を説明します。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.1 スクリーンのリフレッシュ

関数redraw-frameは与えられたフレーム(フレームを参照)のコンテンツ全体にたいしてクリアーと再描画を行います。これはスクリーンが壊れている(corrupted)場合に有用です。

Function: redraw-frame &optional frame

この関数はフレームframeのクリアーと再表示を行う。frameが省略かnilなら選択されたフレームを再描画する。

更に強力なのはredraw-displayです:

Command: redraw-display

この関数はすべての可視なフレームのクリアーと再描画を行う。

Emacsではユーザー入力は再描画より優先されます。入力が可能なときにこれらの関数を呼び出すと、これらはすぐに再描画はしませんが、要求された再描画はすべての入力処理後に行われます。

テキスト端末では通常はEmacsのサスペントと再開によりスクリーンのリフレッシュも行われます。Emacsのようなディスプレイ指向のプログラムと通常のシーケンシャル表示のプログラムで、コンテンツを区別して記録する端末エミュレーターがいくつかあります。そのような端末を使用する場合には、おそらく再開時の再表示を抑制したいでしょう。

User Option: no-redraw-on-reenter

この変数はEmacsがサスペンドや再開された後にスクリーン全体を再描画するかどうかを制御する。非nilなら再描画は不要、nilなら再描画が必要であることを意味する。デフォルトはnil


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.2 強制的な再表示

Emacsは入力の待機時は常に再表示を試みます。以下の関数により実際に入力を待機することなく、Lispコードの中から即座に再表示を試みることを要求できます。

Function: redisplay &optional force

この関数は即座に再表示を試みる。オプション引数forceが非nilの場合には、入力が保留中なら横取りされるかわりに強制的に再表示が行われる。

この関数は実際に再表示が試行されたならt、それ以外はnilをリターンする。tという値は再表示の試行が完了したことを意味しない。新たに到着した入力に横取りされた可能性がある。

redisplayが即座に再表示を試みたとしても、Emacsがフレーム(複数可)のどの部分を再表示するか決定する方法が変更されるわけではありません。それとは対照的に以下の関数は特定のウィンドウを、(あたかもコンテンツが完全に変更されたかのように)保留中の再表示処理に追加します。しかし再描画を即座には試みません。

Function: force-window-update &optional object

この関数はEmacsが次に再表示を行う際にいくつか、あるいはすべてのウィンドウが更新されるよう強制する。objectがウィンドウならそのウィンドウ、バッファーやバッファー名ならそのバッファーを表示するすべてのウィンドウ、nil (または省略)ならすべてのウィンドウが更新される。

この関数は即座に再表示を行わない。再表示はEmacsが入力を待機時、または関数redisplay呼び出し時に行われる。

Variable: pre-redisplay-function

再表示の直前に実行される関数。これは再表示されるウィンドウセットを単一の引数として呼び出される。ウィンドウセットは選択されたウィンドウを意味するnil、すべてのウィンドウを意味するtを指定できる。

Variable: pre-redisplay-functions

このフックは再表示の直前に実行される。これは再表示されようとするウィンドウそれぞれにたいして、そのウィンドウに表示されているバッファーをcurrent-bufferにセットして1回呼び出される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.3 切り詰め

Emacsはテキスト行がウィンドウ右端を超過する際には、その行を継続(continue)させる(次のスクリーン行へwrap、すなわち折り返す)か、あるいはその行を切り詰め(truncate)て表示(その行をスクリーン行の1行に制限)することができます。長いテキスト行を表示するために使用される追加のスクリーン行は継続(continuation)行と呼ばれます。継続はフィルとは異なります。継続はバッファーのコンテンツ内ではなくスクリーン上でのみ発生して、単語境界ではなく正確に右マージンで行をブレークします。fillを参照してください。

グラフィカルなディスプレイでは切り詰めと継続はウィンドウフリンジ内の小さな矢印イメージで示されます(フリンジを参照)。テキスト端末では切り詰めはそのウィンドウの最右列の‘$’、折り返しは最右列の‘\’で示されます(ディスプレイテーブルでこれを行うための代替え文字を指定できる。ディスプレイテーブルを参照)。

テキストの折り返しと切り詰めは互いに反する操作なので、Emacsは折り返しを要求されたら行の切り詰めをオフに、あるいはその逆も行います。

User Option: truncate-lines

このバッファーローカル変数が非nilならウィンドウ右端を超過する行は切り詰められて、それ以外なら継続される。特別な例外として部分幅(partial-width)ウィンドウ(フレーム全体の幅を占有しないウィンドウ)では変数truncate-partial-width-windowsが優先される。

User Option: truncate-partial-width-windows

この変数は部分幅(partial-width)ウィンドウ内の行の切り詰めを制御する。部分幅ウィンドウとはフレーム全体の幅を占有しないウィンドウ(ウィンドウの分割を参照)。値がnilなら行の切り詰めは変数truncate-lines (上記参照)により決定される。値が整数nの場合には、部分幅ウィンドウの列数がnより小さければtruncate-linesの値とは無関係に行は切り詰められて、部分幅ウィンドウの列数がn以上なら行の切り詰めはtruncate-linesにより決定される。それ以外の非nil値ではtruncate-linesの値とは無関係にすべての部分幅ウィンドウで行は切り詰められる。

ウィンドウ内で水平スクロール(水平スクロールを参照)を使用中は切り詰めが強制されます。

Variable: wrap-prefix

このバッファーローカル変数が非nilなら、それはEmacsが各継続行の先頭に表示する折り返しプレフィックス(wrap prefix)を定義する(行を切り詰めている場合にはwrap-prefixは使用されない)。この値は文字列、またはイメージ(その他のディスプレイ仕様を参照)やディスプレイプロパティ:width:align-toで指定されるような伸長された空白文字を指定できる(スペースの指定を参照)。値はテキストプロパティdisplayと同じ方法で解釈される。displayプロパティを参照のこと。

折り返しプレフィックスはテキストプロパティかオーバーレイプロパティwrap-prefixを使用することにより、テキストのリージョンにたいして指定することもできる。これはwrap-prefix変数より優先される。特殊な意味をもつプロパティを参照のこと。

Variable: line-prefix

このバッファーローカル変数が非nilなら、それはEmacsがすべての非継続行の先頭に表示する行プレフィックス(line prefix)を定義する。この値は文字列、イメージ(その他のディスプレイ仕様を参照)、またはディスプレイプロパティ:width:align-toで指定されるような伸長された空白文字を指定できる(スペースの指定を参照)。値はテキストプロパティdisplayと同じ方法で解釈される。displayプロパティを参照のこと。

行プレフィックスはテキストプロパティまたはオーバーレイプロパティline-prefixを使用することにより、テキストのリージョンにたいして指定することもできる。これはline-prefix変数より優先される。特殊な意味をもつプロパティを参照のこと。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.4 エコーエリア

エコーエリア(echo area)はエラーメッセージ(エラー)やmessageプリミティブで作成されたメッセージの表示、およびキーストロークをエコーするために使用されます。(アクティブ時には)ミニバッファーがスクリーン上のエコーエリアと同じ場所に表示されるという事実にも関わらずエコーエリアはミニバッファーと同じではありません。The Minibuffer in The GNU Emacs Manualを参照してください。

このセクションに記述された関数とは別に、出力ストリームとしてtを指定することによりエコーエリアにLispオブジェクトをプリントできます。出力ストリームを参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.4.1 エコーエリアへのメッセージの表示

このセクションではエコーエリア内にメッセージを表示する標準的な関数を説明します。

Function: message format-string &rest arguments

この関数はエコーエリア内にメッセージを表示する。format-message関数(文字列のフォーマットを参照)の場合と同じようにformat-stringはフォーマット文字列、argumentsはそのフォーマット仕様にたいするオブジェクトである。フォーマットされた結果文字列はエコーエリア内に表示される。それにfaceテキストプロパティが含まれる場合には指定されたフェイスにより表示される(フェイスを参照)。この文字列は*Messages*バッファーにも追加されるがテキストプロパティは含まれない(*Messages*へのメッセージのロギングを参照)。

フォーマット内のグレイヴアクセントとアポストロフィーは"Missing `%s'"から"Missing ‘foo’"のように、通常は対応するcurved quoteとして結果内に変換される。この変換に影響を与えたり抑制する方法についてはテキストのクォートスタイルを参照のこと。

バッチモードでは後に改行が付加されたメッセージが標準エラーストリームにプリントされる。

inhibit-messageが非nilのときはエコーエリアにはメッセージを何も表示せずに‘*Messages*’へのロギングだけとなる。

format-stringnilか空文字列なら、messageはエコーエリアをクリアーする。エコーエリアが自動的に拡張されていたら、これにより通常のサイズに復元される。ミニバッファーがアクティブなら、これによりスクリーン上に即座にミニバッファーのコンテンツが復元される。

(message "Reverting `%s'..." (buffer-name))
 -| Reverting ‘subr.el’...
⇒ "Reverting ‘subr.el’..."

---------- Echo Area ----------
Reverting ‘subr.el’...
---------- Echo Area ----------

エコーエリアやポップバッファー内に自動的にメッセージを表示するには、そのサイズに応じてdisplay-message-or-buffer (以下参照)を使用する。

警告: 逐語的なメッセージとして独自の文字列を使用したければ、単に(message string)と記述してはならない。stringに‘%’、‘`’、‘'’が含まれていると望まぬ結果に再フォーマットされるかもしれない。かわりに(message "%s" string)を使用すること。

以下の機能により、ユーザーおよびLispプログラムはエコーエリアメッセージの表示方法を制御できます。

Variable: set-message-function

この変数が非nilなら、エコーエリア内に表示するためのメッセージテキストを単一の引数とする関数であること。その関数はmessageおよび関連する関数から呼び出されることになる。その関数がnilをリターンすると、通常どおりメッセージはエコーエリアに表示される。関数が文字列をリターンすると、その文字列が元メッセージのかわりにエコーエリアに表示される。その関数が他の非nil値をリターンした場合にはメッセージが処理済みであることを意味するので、messageはエコーエリアに何も表示しない。その関数で表示されたメッセージのクリアーに使用可能なclear-message-functionも参照のこと。

デフォルト値では以下で説明するset-minibuffer-messageを呼び出す。

Variable: clear-message-function

この変数が非nilの場合には引数のない関数であること。messageおよび関連する関数は引数となるメッセージがnilか空文字列なら、エコーエリアをクリアーするために引数なしでその関数を呼び出す。

この関数は通常はエコーエリアメッセージの表示後、次の入力イベントの到着時に呼び出される。これはset-message-functionにより指定されたカウンターパートとなる関数が表示したメッセージのクリアーを期待される関数だが、必ずしもクリアーを行う必要はない。関数がクリアーしない状態でエコーエリアを残したければ、シンボルdont-clear-messageをリターンすること。それ以外の値であればエコーエリアがクリアーされたことを意味する。

デフォルト値はアクティブなミニバッファーに表示されたメッセージをクリアーする関数。

User Option: set-message-functions

このユーザーオプションの値は、エコーエリアへのメッセージ表示を処理する関数のリストである。関数はそれぞれ表示するメッセージテキストを唯一の引数として呼び出される。その関数が文字列をリターンしたら元の文字列はその文字列で置換されて、リストの次の関数はその新たなメッセージテキストを引数として呼び出される関数がnilをリターンした場合には同じテキストでリストの次の関数が呼び出される。リストで最後の関数がnilをリターンすると、エコーエリにメッセージテキストを表示、文字列以外の非nil値をリターンした場合にはメッセージを処理済みとみなしてそれ以上リストの関数は呼び出さない。

このリストに配置する値として役に立つ3つの関数を以下に挙げる。

Function: set-minibuffer-message message

この関数はミニバッファーが非アクティブならエコーエリア、アクティブならミニバッファー終端にメッセージを表示する。しかしアクティブなミニバッファーに表示されるテキストの何らかの文字がminibuffer-messageテキストプロパティ(特殊な意味をもつプロパティを参照)をもつ場合には、メッセージはそのプロパティをもつ最初の文字の前に表示される。

デフォルトではこの関数がset-message-functionsのリストの唯一のメンバーである。

Function: inhibit-message message

この関数はエコーエリアのmessageがユーザーオプションinhibit-message-regexpsの値となっているリストのregexpのいずれかにマッチしたらそのメッセージの表示を抑制して文字列以外の非nil値をリターンする。したがってこの関数がリストset-message-functionsにあると、messageinhibit-message-regexpsのregexpにマッチする場合にはリストの残りの関数は呼び出されない。マッチするmessageの表示を確実に抑制するには、この関数をset-message-functionsのリストの最初の要素にすればよい。

Function: set-multi-message message

この関数は発行されていく複数のエコーエリアメッセージを逐一溜め込み、改行を区切られた個々のメッセージを単一の文字列としてリターンする。直近でmulti-message-max回までのメッセージを蓄積できる。蓄積されたメッセージは最初のメッセージの発行からmulti-message-timeout秒経過後に破棄される。

Variable: inhibit-message

この変数が非nilなら、messageおよび関連する関数はエコーエリアに何もメッセージは表示しない。ただしエコーエリアのメッセージは依然として*Messages*バッファーにはロギングされる。

Macro: with-temp-message message &rest body

この構文はbody実行の間にエコーエリア内にメッセージを一時的に表示する。これはmessageを表示してbodyを実行して、それからエコーエリアの前のコンテンツをリストアするとともにbodyの最後のフォームの値をリターンする。

Function: message-or-box format-string &rest arguments

この関数はmessageと同様にメッセージを表示するが、エコーエリアではなくダイアログボックスにメッセージを表示するかもしれない。この関数があるコマンド内からマウスを使用して呼び出されると — より正確にはlast-nonmenu-event (コマンドループからの情報を参照)がnilかリストならメッセージの表示にダイアログボックスかポップアップメニュー、それ以外ならエコーエリアを使用する(これはy-or-n-pが同様の決定を行う際に使用する条件と同じ。Yes-or-Noによる問い合わせを参照)。

呼び出しの前後でlast-nonmenu-eventを適切な値にバインドすることによりエコーエリアでのマウスの使用を強制できる。

Function: message-box format-string &rest arguments

この関数はmessageと同様にメッセージを表示するが、利用可能なら常にダイアログボックス(かポップアップメニュー)を使用する。端末がサポートしないためにダイアログボックスやポップアップメニューが使用できなければ、message-boxmessageと同様にエコーエリアを使用する。

Function: display-message-or-buffer message &optional buffer-name action frame

この関数はメッセージmessageを表示する。messageには文字列かバッファーを指定できる。これがmax-mini-window-heightで定義されるエコーエリアの最大高さより小さければ、messageを使用してエコーエリアに表示される。それ以外ならメッセージを表示するためにdisplay-bufferはポップアップバッファーを使用する。

エコーエリアに表示したメッセージ、またはポップアップバッファー使用時はその表示に使用したウィンドウをリターンする。

messageが文字列ならオプション引数buffer-nameはポップアップバッファー使用時にメッセージ表示に使用するバッファー名(デフォルトは*Message*)。messageが文字列でエコーエリアに表示されていれば、いずれにせよコンテンツをバッファーに挿入するかどうかは指定されない。

オプション引数actionframedisplay-bufferの場合と同様に、バッファーが表示されている場合のみ使用される。

Function: current-message

この関数はエコーエリア内にカレントで表示されているメッセージ、またはそれが存在しなければnilをリターンする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.4.2 処理の進捗レポート

処理の完了まで暫く時間を要するかもしれない際には、進行状況についてユーザーに通知するべきです。これによりユーザーが残り時間を予測するとともに、Emacsがhungしているのではなく処理中であることを明確に確認できます。プログレスレポーター(progress reporter: 進行状況リポーター)を使用するのが、これを行う便利な方法です。

以下は何も有用なことを行わない実行可能な例です:

(let ((progress-reporter
       (make-progress-reporter "Collecting mana for Emacs..."
                               0  500)))
  (dotimes (k 500)
    (sit-for 0.01)
    (progress-reporter-update progress-reporter k))
  (progress-reporter-done progress-reporter))
Function: make-progress-reporter message &optional min-value max-value current-value min-change min-time

この関数は以下に挙げる他の関数の引数として使用されることになるプログレスレポーターオブジェクトを作成してリターンする。これはプログレスリポーターを高速にするように、可能なかぎり多くのデータを事前に計算するというアイデアが元となっている。

この後にプログレスレポーターを使用する際には、進行状況のパーセンテージを後に付加してmessageが表示されるだろう。messageは単なる文字列として扱われる。たとえばファイル名に依存させる必要があるなら、この関数の呼び出し前にformat-messageを使えばよい。

引数min-valuemax-valueは処理の開始と終了を意味する数値であること。たとえばバッファーをスキャンする処理なら、これらをそれぞれpoint-minpoint-maxにセットするべきだろう。max-valuemin-valueより大であること。

かわりにmin-valuemax-valuenilにセットすることができる。この場合にはプログレスレポーターは進行状況のパーセンテージを報告しない。かわりにプログレスリポーターを更新するたびに刻み(notch)を回転する“スピナー(spinner)”を表示する。

min-valuemax-valueが数値なら、進行状況の初期の数値を与える引数current-valueを与えることができる。省略時のデフォルトはmin-value

残りの引数はエコーエリアの更新レートを制御する。プログレスレポーターは次のメッセージを表示する前に、その処理が少なくともmin-changeパーセントより多く完了するまで待機する。デフォルトは1パーセント。min-timeは連続するプリントの間に空ける最小時間をミリ秒単位で指定する(いくつかのオペレーティングシステムではプログレスリポーターは秒の小数部をさまざまな精度で処理するかもしれない)。

この関数はprogress-reporter-updateを呼び出すので、最初のメッセージは即座にプリントされる。

Function: progress-reporter-update reporter &optional value

この関数は操作の進行状況報告に関する主要な機能を担う。これはreporterのメッセージと、その後にvalueにより決定された進行状況のパーセンテージを表示する。パーセンテージが0、または引数min-changemin-timeに比べて十分0に近ければ出力は省略される。

reportermake-progress-reporter呼び出しがリターンした結果でなければならない。valueは処理のカレント状況を指定して、make-progress-reporterに渡されたmin-valuemax-valueの間(両端を含む)でなければならない。たとえばバッファーのスキャンにおいては、valuepointび呼び出し結果であるべきだろう。

オプション引数suffixは、reporterのメインメッセージと進行状況テキストの後に表示する文字列。reporterが非数値のレポーターならvaluenil、またはsuffixのかわりに使用する文字列であること。

この関数はmake-progress-reporterに渡されたmin-changemin-timeにしたがい、毎回の呼び出しで新たなメッセージを出力しない。したがってこれは非常に高速であり、通常はこれを呼び出す回数を減らすことを試みるべきではない。結果として生じるオーバーヘッドは、あなたの努力をほぼ否定するだろう。

Function: progress-reporter-force-update reporter &optional value new-message suffix

この関数はprogress-reporter-updateと同様だが、これは無条件にメッセージをエコーエリアにプリントする点が異なる。

reportervaluesuffixprogress-reporter-updateの場合と同じ意味をもつ。オプションのnew-messagereporterのメッセージを変更できる。この関数は常にエコーエリアを更新するので、そのような変更は即座にユーザーに示されるだろう。

Function: progress-reporter-done reporter

この関数は処理の完了時に呼び出されること。これはエコーエリア内に単語‘done’を付加したreporterのメッセージを表示する。

progress-reporter-updateに‘100%’とプリントさせようとせずに、常にこの関数を呼び出すこと。まずこの関数は決してそれをプリントしないだろうし、これが発生しないために多くの正当な理由がある。次に‘done’はより自明である。

Macro: dotimes-with-progress-reporter (var count [result]) reporter-or-message body…

これはdotimesと同じ方法で機能するが、上述の関数を使用してループ進行状況(loop progress)の報告も行う便利なマクロである。これによりタイプ量を幾分節約できる。引数reporter-or-messageは文字列、またはプログレスレポーターオブジェクト。

以下の方法でこのマクロを使用することにより、このサブセクションの例を書き換えることができる:

(dotimes-with-progress-reporter
    (k 500)
    "Collecting some mana for Emacs..."
  (sit-for 0.01))

make-progress-reporterのオプション引数を指定したい場合には、reporter-or-message引数としてレポーターオブジェクトを使用するのが便利。たとえば前出の例は以下のように書き換えられる:

(dotimes-with-progress-reporter
    (k 500)
    (make-progress-reporter "Collecting some mana for Emacs..." 0 500 0 1 1.5)
  (sit-for 0.01))
Macro: dolist-with-progress-reporter (var list [result]) reporter-or-message body…

これはdolistと同じ方法で機能するが、上述の関数を使用してループ進行状況(loop progress)の報告も行う便利なマクロである。これによりタイプ量を幾分節約できる。dotimes-with-progress-reporterの場合のように、reporter-or-messageはプログレスレポーターか文字列。このマクロにより、前出の例を以下のように書き換えられる:

(dolist-with-progress-reporter
    (k (number-sequence 0 500))
    "Collecting some mana for Emacs..."
  (sit-for 0.01))
Macro: with-delayed-message (timeout message) body…

ある処理にたいして、実行に長時間を要するか否かが不明瞭だったり、処理がプログレスレポーターの実装に向いていない場合があるかもしれない。このマクロはそのような状況下で使用できるだろう。

(with-delayed-message (2 (format "Gathering data for %s" entry))
  (setq data (gather-data entry)))

この例では、処理の実行が2秒を超える場合にはメッセージが表示される。2秒以下の場合にはメッセージは表示されない。いずれの場合でもbodyは通常どおり評価される。このマクロのリターン値は、bodyの最後の要素のリターン値。

メッセージわwo表示するか否かに関わらず、要素messagebodyより前に、常に評価される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.4.3 *Messages*へのメッセージのロギング

エコーエリア内に表示されるほとんどすべてのメッセージは、ユーザーが後で参照できるように*Messages*バッファー内にも記録されます。これにはmessageにより出力されたメッセージも含まれます。デフォルトではこのバッファーは読み取り専用でメジャーモードmessages-buffer-modeを使用します。ユーザーによる*Messages*バッファーのkillを妨げるものは何もありませんが、次回のメッセージ表示でバッファーは再作成されます。*Messages*バッファーに直接アクセスする必要があり、それが確実に存在するようにしたいLispコードは、すべて関数messages-bufferを使用するべきです。

Function: messages-buffer

この関数は*Messages*バッファーをリターンする。バッファーが存在しなければ作成してバッファーをmessages-buffer-modeに切り替える。

User Option: message-log-max

この変数は*Messages*バッファー内に保持するべき行数を指定する。値tは保持すべき行数に制限がないことを意味して、値nilはメッセージのロギングを完全に無効にする。以下はメッセージを表示して、それがロギングされることを防ぐ例:

(let (message-log-max)
  (message …))
Variable: messages-buffer-name

この変数はメッセージのログの書き込み先となるバッファーの名前を保持する。デフォルトは*Messages*。(恐らくは後でバッファーをログファイルに書き込む等の理由で)一時的に出力を別バッファーにリダイレクトできると都合がよいパッケージがあれば、この変数に別のバッファー名をバインドすればよい(そのバッファーがまだ存在しなければ、そのバッファーが新たにmessages-buffer-modeで作成されることに注意)。

*Messages*にたいするユーザーの利便性を向上させるために、ロギング機能は連続する同じメッセージを結合します。さらに2つのケースのために連続する関連メッセージの結合も行います。2つのケースとは応答を後にともなう質問(question followed by answer)、および一連のプログレスメッセージ(series of progress messages)です。

応答を後にともなう質問(question followed by an answer)とは、1つ目が‘question’、2つ目が‘question...answer’のようにy-or-n-pが生成するような2つのメッセージをもつ応答です。1つ目のメッセージは2つ目のメッセージ以上の追加情報を伝えないので、2つ目のメッセージをロギングして1つ目のメッセージは破棄します。

一連のプログレスメッセージ(series of progress messages)は、make-progress-reporterが生成するような連続するメッセージをもちます。これらは‘base...how-far’のような形式であり、how-farは毎回異なりますがbaseは常に同じです。このシリーズ内の各メッセージのロギングでは、そのメッセージが前のメッセージと連続していれば前のメッセージを破棄します。

関数make-progress-reportery-or-n-pは、メッセージログ結合機能をアクティブにするために何ら特別なことを行う必要はありません。これは‘...’で終わる共通のプレフィックスを共有する連続する2つのメッセージをログする際には常にこの処理を行います。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.4.4 エコーエリアのカスタマイズ

以下の変数はエコーエリアが機能する方法の詳細を制御します。

Variable: cursor-in-echo-area

この変数はエコーエリア内にメッセージ表示時にカーソルを表示する場所を制御する。これが非nilならカーソルはメッセージの終端、それ以外ならカーソルはエコーエリア内ではなくポイント位置に表示される。

この値は通常はnil。Lispプログラムは短時間の間、これをtにバインドする。

Variable: echo-area-clear-hook

このノーマルフックは(message nil)、または別の何らかの理由によりエコーエリアが作成されると常に実行される。

User Option: echo-keystrokes

この変数はコマンド文字をエコーする前に、どれだけの時間を待機するかを決定する。この値は数字でなければならず、エコー前に待機する秒数を指定する。ユーザーが(C-xのような)プレフィックスキーをタイプしてから、継続してタイプを継続するのをこの秒数遅延した場合、エコーエリア内にそのプレフィックスキーがエコーされる(あるキーシーケンスで一度エコーが開始されると、同一のキーシーケンス内の後続するすべての文字は即座にエコーされる)。

値が0ならコマンド入力はエコーされない。

Variable: message-truncate-lines

長いメッセージの表示により、そのメッセージ全体を表示するために、通常はエコーエリアは長い行を折り返してリサイズされる。しかし変数message-truncate-linesが非nilなら、エコーエリアの長い行はエコーエリアに収まるようメッセージは切り詰められる。

ミニバッファーウィンドウのリサイズの最大高さを指定する変数max-mini-window-heightはエコーエリアにも適用される(エコーエリアは真にミニバッファーウィンドウの特殊な使い方である。ミニバッファーのウィンドウを参照)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.5 警告のレポート

警告(warnings)とはプログラムがユーザーにたいして問題の可能性を知らせるが、実行は継続するための機能です(エラーのシグナルとは逆; エラーを参照)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.5.1 警告の基礎

すべての警告はユーザーに問題を説明するためのテキストのメッセージと、それに関連付けられた重大度レベル(severity level)をもっています。重大度レベルはシンボルです。以下に想定される重大度レベルと意味を重大度の降順で示します:

:emergency

ユーザーが直ちに対処しなければEmacs処理が間もなく深刻に害される問題。

:error

本質的に悪いデータや状況に関するレポート。

:warning

本質的に悪くはないが、可能性のある問題を励起する恐れのあるデータや状況に関するレポート。

:debug

ユーザーが警告を発するLispプログラムをデバッグ中に役に立つかもしれない情報のレポート。

あなたのプログラムが無効な入力データに遭遇した際には、errorsignal (エラーをシグナルする方法を参照)の呼び出しによってLispエラーのシグナルするか、あるいは重大度:errorの警告をレポートすることができます。もっとも簡単なのはLispエラーのシグナルですが、それはプログラムが処理を継続できないようシグナルすることを意味します。間違ったデータでも処理を継続するための方法を実装するためにトラブルを受け取めたい場合には、その問題をユーザーに知らせるために重大度:errorの警告をレポートするのが正しい方法です。たとえばEmacs Lispバイトコンパイラーはこの方法によりエラーを報告して、他の関数のコンパイルを継続できます(プログラムがLispエラーをシグナルしてcondition-caseでhandleしたならユーザーがそのエラーを確認することはないだろう; これは警告としてレポートすることにより、問題を避けるのではなくユーザーに問題を報告するのだ)。

重大度レベルの他にも、クラス分けのために警告にはそれぞれ警告タイプ(warning type)があります。このタイプはシンボル、またはシンボルのリストです。シンボルならそのプログラムのユーザーオプションとして使用するカスタムグループ、リストならリストの1つ目の要素がそのカスタムグループであることが必要です。たとえばバイトコンパイラーの警告は警告タイプ(bytecomp)を使用しています。警告タイプがリストの場合には、後続する2つ目以降の要素はそれぞれが警告のサブカテゴリーを表す任意のシンボルであることが必要です。これらの要素は、その警告の特性についてよりよい説明を表示するために使用されることでしょう。

Function: display-warning type message &optional level buffer-name

この関数は警告テキストとして文字列message、警告タイプとしてtypeを使用して警告をレポートする。levelは重大度レベルであること。省略またはnilの場合のデフォルトは:warning

buffer-nameが非nilなら、それは警告メッセージをロギングするためのバッファー名を指定する。デフォルトは*Warnings*

Function: lwarn type level message &rest args

この関数は*Warnings*バッファー内のメッセージテキストとして(format-message message args…)がリターンした値を使用して警告をレポートする。他の点ではこれはdisplay-warningと同じ。

Function: warn message &rest args

この関数はメッセージテキストとして(format-message message args…)がリターンした値、タイプとしてemacs、重大度レベルとして:warningを使用して警告をレポートする。これは互換性のためだけに存在する。固有な警告タイプを指定するべきであり、この関数の使用は推奨しない。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.5.2 警告のための変数

このセクション内で説明する変数をバインドすることにより、プログラムは警告が表示される方法をカスタマイズできます。

Variable: warning-levels

このリストは警告の重大度レベルの意味と重大度の順序を定義する。それぞれの要素は1つの重大度レベルを定義して、それらを重大度の降順で配置した。

各要素は(level string [function])という形式をもち、levelはその要素が定義する重大度レベル。stringはそのレベルのテキストによる説明。stringは警告タイプ情報の配置箇所の指定に‘%s’を使用するか、さもなくばその情報を含まぬよう‘%s’を省略できる。

オプションのfunctionが非nilなら、これはユーザーの注目を得るために引数なしで呼び出される関数であること。dingの例は注目に値する(ビープを参照)。

通常はこの変数の値を変更しないこと。

Variable: warning-prefix-function

値が非nilなら、それは警告用にプレフィックスを生成する関数であること。プログラムはこの変数を適切な関数にバインドできる。display-warningはwarningsバッファーがカレントの状態でこの関数を呼び出して、関数はそのバッファーにテキストを挿入できる。そのテキストが警告メッセージの先頭になる。

この関数は重大度レベル、およびwarning-levels内でのその重大度レベルのエントリーという2つの引数で呼び出される。これはエントリーのかわりに使用するためのリストをリターンすること(この値はwarning-levelsの実際のメンバーである必要はないが同じ後続でなければならない)。この値を構築することにより関数はその警告の重大度レベルを変更したり、与えられた重大度レベルにたいして異なる処理を指定することができる。

変数の値がnilなら警告が表示される前のプレフィックステキストは存在せず、その警告のレベルに応じたwarning-levels内のエントリーのstring部分から始まる。

Variable: warning-series

プログラムは次の警告がシリーズの開始であることを告げるために、この変数をtにバインドできる。複数の警告がシリーズを形成するということは、それぞれの警告にたいしてポイントが維持されるように移動して、最後の警告にポイントが表示されるのではなくシリーズの最初の警告にポイントを残すことを意味する。このシリーズはこの変数のローカルバインドが解消されてwarning-seriesが再びnilになったときに終了する。

この値は関数定義をもつシンボルでもよい。これは次の警告によりwarningsバッファーがカレントの状態で、引数なしでその関数が呼び出されることを除きtと等価。この関数はたとえば警告シリーズのヘッダーの役目をもつであろうテキストを挿入できる。

あるシリーズが開始されると、この変数の値はwarningsバッファー内でシリーズ開始となるバッファー位置を指すマーカーとなる。

この変数の通常の値はnilで、これはそれぞれの警告を個別に処理することを意味する。

Variable: warning-fill-prefix

この変数が非nilなら、警告それぞれのテキストのフィルに使用するフィルプレフィックスを指定する。

Variable: warning-fill-column

警告をフィルする列。

Variable: warning-type-format

この変数は警告テキスト内の警告タイプを表示するためのフォーマットを指定する。この方法でフォーマットされたタイプは、warning-levels内のエントリー内の文字列制御下にあるメッセージに含まれることになる。デフォルト値は" (%s)"。これを空文字列""にバインドすると警告タイプはまったく表示されなくなる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.5.3 警告のためのオプション

以下の変数は何が発生したときにLispプログラムが警告をレポートするかをユーザーが制御するために使用されます。

User Option: warning-minimum-level

このユーザーオプションはどこかのウィンドウに警告バッファーをポップアップすることによってユーザーに即座に表示すべき最小の重大度レベルを指定する。デフォルトの:warning:debug以外のすべての警告重大度にたいして警告バッファーを表示することを意味する。この変数の与えられたより低い重大度レベルは依然として警告バッファーに書き込まれるが、そのバッファーが強制的に表示されることはない。

User Option: warning-minimum-log-level

このユーザーオプションはwarningsバッファー内にログされるべき最小の重大度レベルを指定する。これより低い重大度レベルは完全に無視される。すなわち警告バッファーに書き込まれず表示もされない。デフォルトは:warningであり、これは:debugを除くすべての警告がログされることを意味する。

User Option: warning-suppress-types

このリストは発生時即座に表示するべきではない警告タイプを指定する。このリストの要素はそれぞれシンボルのリストであること。警告タイプの最初の要素がこのリストのいずれかの要素と同一であれば、そのタイプの警告がどこかのウィンドウに警告バッファーをポップアップして表示されることはなくなる(警告バッファーへの警告の書き込みは依然として行われる)。

たとえばこの変数の値が以下のようなリストであれば:

((foo) (bar subtype))

foo(foo)(foo something)(bar subtype other)といったタイプの警告はユーザーに表示されなくなる。

User Option: warning-suppress-log-types

このリストは無視、すなわち警告バッファーにロギングされずユーザーにも表示しない警告タイプを指定する。リストの構造と警告タイプにたいするマッチングは、上述のwarning-suppress-typesの場合と同様。

スタートアップの間にEmacsはサイト単位のinitファイルとユーザーのinitファイル(要約: スタートアップ時のアクション順序を参照)のロードと処理が終わるまで、すべての警告の表示を遅延します。initファイルで警告を発するかもしれないコードの前後で以下のオプションの値をletバインディング(ローカル変数を参照)しても、実際に警告が処理される時点では効果がなくなっており機能しません。したがってスタートアップの間に警告を抑制したければ、initファイルの十分早い段階で上述のオプションの値を変更するか、あるいはafter-init-hookemacs-startup-hookの関数内にletバインディングを行うフォームを配置してください。initファイルを参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.5.4 遅延された警告

コマンド実行中には警告の表示を避けてコマンドの終わりでのみ警告を表示したいことがあるかもしれません。これは関数delay-warningを使用して行うことができます。Emacsはスタートアップの初期ステージの間は自動的にすべての警告メッセージ発行を遅延して、initファイルを処理した後でのみそれらを表示します。

Function: delay-warning type message &optional level buffer-name

この関数はdisplay-warning (警告の基礎を参照)の遅延対応版であり、同じ引数で呼び出される。警告メッセージはdelayed-warnings-listにキューイングされる。

Variable: delayed-warnings-list

この変数の値はカレントのコマンド完了後に表示される警告のリスト。各要素は以下のようなリストでなければならない:

(type message [level [buffer-name]])

これらはdisplay-warningの引数リストと同じ形式、同じ意味である。post-command-hook (コマンドループの概要を参照)の実行直後に、Emacsのコマンドループはこの変数で指定されたすべての警告を表示してから変数をnilにリセットする。

遅延警告メカニズムをよりカスタマイズする必要があるプログラムは変数delayed-warnings-hookを変更することができます:

Variable: delayed-warnings-hook

これは遅延警告を処理して表示するために、post-command-hookの後にEmacsコマンドループが実行するノーマルフック。Emacsはスタートアップ中、およびsite-startファイルとinitファイルをロードした後(要約: スタートアップ時のアクション順序を参照)にもこのフックを実行する。これはそれ以前に発せられた警告は自動的に遅延されるためである。

デフォルト値は2つの関数からなるリスト:

(collapse-delayed-warnings display-delayed-warnings)

関数collapse-delayed-warningsdelayed-warnings-listから重複するエントリーを削除する。関数display-delayed-warningsdelayed-warnings-list内の各要素にたいして順次display-warningを呼び出してから、delayed-warnings-listnilにセットする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.6 不可視のテキスト

invisibleプロパティにより、スクリーン上に表示されないように文字を不可視(invisible)にすることができます。これはテキストプロパティ(テキストのプロパティを参照)、またはオーバーレイプロパティ(オーバーレイを参照)のいずれかで行うことができます。カーソル移動もこれらの文字を部分的に無視します。あるコマンドの後に不可視テキスト範囲内にポイントがあることをコマンドループが検知した場合には、コマンドループはポイントをそのテキストの別サイドへ再配置します。

もっともシンプルなケースでは、非nilinvisibleプロパティにより文字は不可視になります。これがデフォルトのケースであり、もしbuffer-invisibility-specのデフォルト値を変更したくない場合には、これがinvisibleプロパティを機能させる方法です。自身でbuffer-invisibility-specをセットする予定がなければ、invisibleプロパティの値として通常はtを使用するべきです。

より一般的にはどのinvisibleの値がテキストを不可視にするかを制御するために変数buffer-invisibility-specを使用できます。テキストにたいして異なるinvisibleの値を与えることにより、事前に別のサブセットへテキストをクラス分けした後にbuffer-invisibility-specの値を変更して、さまざまなサブセットを可視や不可視にすることができます。

特にデータベース内のエントリーのリストを表示するプログラム内では、buffer-invisibility-specによる可視性の制御は有用です。これによりデータベース内の一部だけを閲覧するフィルターコマンドを簡便に実装することが可能になります。この変数をセットするのは非常に高速であり、バッファー内のすべてのテキストにたいしてプロパティが変更されたかスキャンするよりはるかに高速です。

Variable: buffer-invisibility-spec

この変数はどの種類のinvisibleプロパティが実際に文字を不可視にするかを指定する。この変数はセットすることによりバッファーローカルになる。

t

invisibleプロパティが非nilならその文字は不可視になる。これがデフォルト。

リスト

このリスト内の各要素は不可視性の条件を指定する。ある文字のinvisibleプロパティがこれらの条件のいずれかに適合したら、その文字は不可視になる。このリストは2種類の要素をもつことができる:

atom

invisibleプロパティの値がatom、またはatomをメンバーにもつリストならその文字は不可視になる。比較はeqにより行われる。

(atom . t)

invisibleプロパティの値がatom、またはatomをメンバーにもつリストならその文字は不可視になる。比較はeqにより行われる。さらにそのような文字シーケンスは省略記号(ellipsis)として表示される。

特にbuffer-invisibility-specへの要素の追加と削除のために2つの関数が提供されています。

Function: add-to-invisibility-spec element

この関数は、buffer-invisibility-specに要素elementを追加する。buffer-invisibility-spectなら、これはリスト(t)に変更されてinvisibleプロパティがtのテキストは不可視のまま留まる。

Function: remove-from-invisibility-spec element

この関数はbuffer-invisibility-specから要素elementを削除する。リスト内にelementがなければ何も行わない。

buffer-invisibility-specを使用するための規約として、メジャーモードはbuffer-invisibility-specの要素、およびinvisibleプロパティの値として自身のモード名を使用することになっている。

;; 省略記号を表示したければ:
(add-to-invisibility-spec '(my-symbol . t))
;; 表示したくなければ:
(add-to-invisibility-spec 'my-symbol)

(overlay-put (make-overlay beginning end)
             'invisible 'my-symbol)

;; 不可視状態が終わったら:
(remove-from-invisibility-spec '(my-symbol . t))
;; または各々を:
(remove-from-invisibility-spec 'my-symbol)

以下の関数を使用することにより不可視性をチェックできます:

Function: invisible-p pos-or-prop

この関数はpos-or-propがマーカーか数字の場合には、その位置のテキストがカレントで不可視なら非nilをリターンする。

pos-or-propが別の類のLispオブジェクトなら、テキストプロパティかオーバーレイプロパティとして可能な値を意味すると解釈される。この場合にはbuffer-invisibility-specのカレント値にもとづき、もしその値がテキストを不可視とするようならこの関数は非nilをリターンする。

この関数のリターン値はテキストがディスプレイ上で完全に非表示ならt、省略記号(ellipsis)で置き換えられていればnilでもtでもない値となる。

テキストを操作したりポイントを移動する関数は、通常はそのテキストが不可視かどうかに注意を払わずに、可視と不可視のテキストを同様に処理します。next-lineprevious-lineのようなユーザーレベルの行移動関数はline-move-ignore-invisibleが非nil (デフォルト)なら不可視な改行を無視します。これらの関数は不可視な改行がそのバッファーに存在しないかのように振る舞いますが、それはそう振る舞うように明示的にプログラムされているからです。

あるコマンドが不可視テキストの境界内側のポイントで終了した場合には、メイン編集ループはその不可視テキストの両端のうちのいずれかにポイントを再配置します。そのコマンドの移動関数の全体的な方向と同じになるようにEmacsが再配置の方向を決定します。これに疑問がある場合には、挿入された文字がinvisibleプロパティを継承しないような位置を優先してください。加えてそのテキストが省略記号で置換されずに、コマンドが不可視テキスト内への移動のみを行う場合には、ポイントを1文字余計に移動して目に見えるようカーソルを移動することにより、そのコマンドの移動を反映するよう試みます。

したがってコマンドが(通常のstickinessをもつ)不可視範囲に後方へとポイントを移動すると、Emacsはポイントをその範囲の先頭に後方へと移動します。コマンドが不可視範囲へ前方にポイントを移動した場合には、Emacsは不可視テキストの前にある最初の可視文字に前方へとポイントを移動して、その後さらに前方へ1文字余計に移動します。

これら不可視テキスト中間で終了するポイントにたいするこれらの調整(adjustments)は、disable-point-adjustmentを非nilにセットすることにより無効にできます。コマンド後のポイントの調整を参照してください。

インクリメンタル検索はマッチが不可視テキストを含む場合には、一時的および/または永続的に不可視オーバーレイを可視にすることができます。これを有効にするためには、そのオーバーレイが非nilisearch-open-invisibleプロパティをもつ必要があります。プロパティの値は、そのオーバーレイを引数として呼び出される関数であるべきです。その関数はオーバーレイを永続的に可視にする必要があります。これは検索からのexit時にマッチがそのオーバーレイに重なるときに使用されます。

検索の間にそのようなオーバーレイのinvisible、およびintangibleプロパティを一時的に変更することによりオーバーレイは一時的に可視にされます。特定のオーバーレイにたいして異なる方法でこれを行いたいなら、それをisearch-open-invisible-temporaryプロパティ(関数)に与えてください。その関数は2つの引数により呼び出されます。1つ目はそのオーバーレイ、2つ目はnilならオーバーレイを可視、tなら再び不可視にします。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.7 選択的な表示

選択的表示(selective display)とはスクリーン上で特定の行を隠蔽する関連する機能ペアーを指します。

1つ目の変種は明示的な選択的表示であり、これはLispプログラム内で使用するようにデザインされています。これはテキスト変更により、どの行を隠すかを制御します。この種の隠蔽は現在では時代遅れであ推奨されていません。同じ効果を得るには、かわりにinvisibleプロパティ(不可視のテキストを参照)を使用する必要があります。

2つ目の変種はインデントにもとづいて隠す行の選択を自動的に行います。この変種はユーザーレベルの機能としてデザインされています。

選択的表示を明示的に制御する方法では改行(control-j)を復帰(control-m)に置換します。これにより以前は行末に改行があった行は隠蔽されます。厳密に言うと改行だけが行を分離できるので、これはもはや一時的には行ではなく前の行の一部です。

選択的表示は編集コマンドに直接影響を与えません。たとえばC-f (forward-char)は隠蔽された行へと気軽にポイントを移動します。しかし復帰文字による改行文字の置換は、いくつかの編集コマンドに影響を与えます。たとえばnext-lineは改行だけを検索するために、隠蔽された行をスキップします。選択的表示を使用するモードは改行を考慮するコマンドを定義したり、テキストのどの部分を隠すか制御することもできます。

選択的表示されたバッファーをファイルに書き込む際には、control-mはすべて改行として出力されます。これはファイル内のテキストを読み取る際には、すべて問題なく隠蔽されずに表示されることを意味します。選択的表示はEmacs内でのみ顕在する効果です。

Variable: selective-display

このバッファーローカル変数は選択的表示を有効にする。これは行、または行の一部を隠すことができることを意味する。

  • selective-displayの値がtなら、文字control-mが隠蔽されたテキストの開始をマークする。control-mと後続する行の残りは表示されない。これは明示的な選択的表示である。
  • selective-displayの値が正の整数なら、それより多くの列によるインデントで始まる行は表示されない。

バッファーの一部が隠蔽されている際には垂直移動コマンドはあたかもその部分を存在しないかのように処理して、1回のnext-lineコマンドで任意の行数の隠蔽された行をスキップできる。しかし( forward-charのような)文字移動コマンドは隠蔽された部分をスキップせずに、(注意すれば)隠蔽された部分にたいしてテキストの挿入と削除が可能である。

以下の例ではselective-displayの値の変更によるバッファーfoo外観表示を示す。このバッファーのコンテンツは変更されない。

(setq selective-display nil)
     ⇒ nil

---------- Buffer: foo ----------
1 on this column
 2on this column
  3n this column
  3n this column
 2on this column
1 on this column
---------- Buffer: foo ----------

(setq selective-display 2)
     ⇒ 2

---------- Buffer: foo ----------
1 on this column
 2on this column
 2on this column
1 on this column
---------- Buffer: foo ----------
User Option: selective-display-ellipses

このバッファーローカル変数が非nilなら、Emacsは隠蔽されたテキストを後にともなう行の終端に‘’を表示する。以下は前の例からの継続。

(setq selective-display-ellipses t)
     ⇒ t

---------- Buffer: foo ----------
1 on this column
 2on this column ...
 2on this column
1 on this column
---------- Buffer: foo ----------

省略記号(‘’)にたいして他のテキストを代替えするためにディスプレイテーブルを使用できる。ディスプレイテーブルを参照のこと。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.8 一時的な表示

一時的表示(temporary display)は出力をバッファーに配置して編集用ではなく閲覧用としてユーザーに示すためにLispプログラムにより使用されます。多くのヘルプコマンドはこの機能を使用します。

Macro: with-output-to-temp-buffer buffer-name body…

この関数はbuffer-nameという名前のバッファー(必要なら最初に作成される)にプリントされた任意の出力が挿入されるようアレンジ、さらにバッファーをHelpモードにしてbody内のフォームを実行する(類似する以下のフォームwith-temp-buffer-windowを参照)。最後にそのバッファーはいずれかのウィンドウに表示されるが、そのウィンドウは選択されない。

body内のフォームが出力バッファーのメジャーモードを変更しないため、実行の最後においても依然としてHelpモードにあるなら、with-output-to-temp-bufferは最後にそのバッファーを読み取り専用するとともに、クリック可能なクロスリファレンスとなるように関数名と変数名のスキャンも行う。特にドキュメント文字列内のハイパーリンク上アイテムに関する詳細はTips for Documentation Stringsを参照のこと。

文字列buffer-nameは一時的なバッファーを指定して、これはあらかじめ存在する必要はない。引数はバッファーではなく文字列でなければならない。そのバッファーは最初に消去されて(確認なし)、with-output-to-temp-bufferのexit後は未変更(unmodified)とマークされる。

with-output-to-temp-bufferstandard-outputを一時的バッファーにバインドしてbody内のフォームを評価する。body内のLisp出力関数を使用した出力のデフォルト出力先は、そのバッファーになる(しかしスクリーン表示やエコーエリア内のメッセージは一般的な世界の感覚では“出力”であるものの影響は受けない)。出力関数を参照のこと。

この構構文の振る舞いをカスタマイズするために利用できるフックがいくつかあり、それらは以下にリストしてある。

リターン値はbody内の最後のフォームの値。

---------- Buffer: foo ----------
 This is the contents of foo.
---------- Buffer: foo ----------

(with-output-to-temp-buffer "foo"
    (print 20)
    (print standard-output))
⇒ #<buffer foo>

---------- Buffer: foo ----------

20

#<buffer foo>

---------- Buffer: foo ----------
User Option: temp-buffer-show-function

この変数が非nilなら、with-output-to-temp-bufferはヘルプバッファーを表示する処理を行うためにその関数を呼び出す。この関数は表示すべきバッファーという1つの引数を受け取る。

with-output-to-temp-bufferが通常行うように、save-selected-window内部や選択されたウィンドウ内でバッファーか選択された状態でtemp-buffer-show-hookを実行するのは、この関数にとってよいアイデアである。

Variable: temp-buffer-setup-hook

このノーマルフックはbodyを評価する前にwith-output-to-temp-bufferにより実行される。フック実行時には一時的バッファーがカレントになる。このフックは通常はそのバッファーをHelpモードにするための関数にセットアップされる。

Variable: temp-buffer-show-hook

このノーマルフックは一時的バッファー表示後にwith-output-to-temp-bufferにより実行される。フック実行時には一時的バッファーがカレントになり、それが表示されているウィンドウが選択される。

Macro: with-temp-buffer-window buffer-or-name action quit-function body…

このマクロはwith-output-to-temp-bufferと類似している。with-output-to-temp-buffer構文と同様に、これはプリントされる任意の出力がbuffer-or-nameという名前のバッファーに挿入されるようにアレンジしてbodyを実行して、そのバッファーをいずれかのウィンドウに表示する。しかしwith-output-to-temp-bufferとは異なり、このマクロはそのバッファーを自動的にHelpモードに切り替えない。

引数buffer-or-nameは一時的バッファーを指定する。これはバッファー(既存でなければならない)、または文字列を指定でき、文字列の場合には必要ならその名前のバッファーが作成される。そのバッファーはwith-temp-buffer-windowのexit時には、未変更かつ読み取り専用とマークされる。

このマクロはtemp-buffer-show-functionを呼び出さない。かわりにそのバッファーを表示するためにaction引数をdisplay-buffer (バッファーを表示するウィンドウの選択を参照)に渡す。

引数quit-functionが指定されていなければbody内の最後のフォームの値がリターンされる。指定されている場合には、そのバッファーを表示するウィンドウとbodyの結果という2つの引数で呼び出される。その場合には、最終的なリターン値は何であれquit-functionがリターンした値となる。

このマクロはwith-output-to-temp-bufferにより実行される類似フックのかわりにノーマルフックtemp-buffer-window-setup-hooktemp-buffer-window-show-hookを使用する。

次の2つの構文はwith-temp-buffer-windowとほとんど同じですが、説明している点が異なります:

Macro: with-current-buffer-window buffer-or-name action quit-function &rest body

このマクロはwith-temp-buffer-windowと同様だが、bodyの実行に際してbuffer-or-nameで指定したバッファーをカレントにする点が異なる。

一時バッファーを表示しているウィンドウは以下のモードを使用してそのバッファーにサイズを適合できます:

User Option: temp-buffer-resize-mode

このマイナーモードが有効なときは、一時的バッファーを表示しているウィンドウはバッファーのコンテンツにフィットするように自動的にリサイズされる。

そのバッファーにたいして特別に作成されたウィンドウの場合のみウィンドウはリサイズされる。特に前に別のバッファーを表示していたウィンドウはリサイズされない。デフォルトではこのモードはリサイズにfit-window-to-bufferを使用する(ウィンドウのリサイズを参照)。以下のオプションtemp-buffer-max-heighttemp-buffer-max-widthをカスタマイズして他の関数を指定できる。

display-bufferにたいしてアクションalistのエントリーとして適切なwindow-heightwindow-widthwindow-sizeを供給することによって、このオプションの効果をオーバーライドできる(バッファー表示用のアクションalistを参照)。

User Option: temp-buffer-max-height

このオプションはtemp-buffer-resize-modeが有効な際に一時的バッファーを表示するウィンドウの最大高さ(行数)を指定する。その種のバッファーの高さ選択のために呼び出す関数でもよい。これはバッファーを唯一の引数として受け取り、正の整数をリターンすること。関数の呼び出し時にはリサイズされるウィンドウが選択される。

User Option: temp-buffer-max-width

このオプションはtemp-buffer-resize-modeが有効な際に一時的バッファーを表示するウィンドウの最大幅(列数)を指定する。その種のバッファーの高さ選択のために呼び出す関数でもよい。これはバッファーを唯一の引数として受け取り、正の整数をリターンすること。関数の呼び出し時にはリサイズされるウィンドウが選択される。

以下の関数は一時的な表示にカレントバッファーを使用します:

Function: momentary-string-display string position &optional char message

この関数はカレントバッファー内のpositionstringを瞬間表示(momentarily display)する。これはundoリストやバッファーの変更状態(modification status)に影響を与えない。

瞬間表示は次の入力イベントまで留まる。次の入力イベントがcharならmomentary-string-displayはそれを無視してリターンする。それ以外ならそのイベントは後続の入力として使用するためにバッファリングされる。つまりcharとタイプすると表示からその文字列を単に削除して、(たとえば) charではないC-fとタイプすると表示からその文字列を削除して、その後に(おそらく)ポイントを前方へ移動するだろう。引数charのデフォルトはスペース。

momentary-string-displayのリターン値に意味はない。

文字列stringがコントロール文字を含まなければ、before-stringプロパティでオーバーレイを作成(その後に削除)することで、同じことをより汎用的に行うことができる。オーバーレイのプロパティを参照のこと。

messageが非nilなら、バッファー内にstringが表示されている間はエコーエリアにそれが表示される。nilの場合のデフォルトは、継続するためにはcharをタイプするように告げるメッセージ。

以下の例では最初はポイントは2行目の先頭に置かれている:

---------- Buffer: foo ----------
This is the contents of foo.
∗Second line.
---------- Buffer: foo ----------

(momentary-string-display
  "**** Important Message! ****"
  (point) ?\r
  "Type RET when done reading")
⇒ t

---------- Buffer: foo ----------
This is the contents of foo.
**** Important Message! ****Second line.
---------- Buffer: foo ----------

---------- Echo Area ----------
Type RET when done reading
---------- Echo Area ----------

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.9 オーバーレイ

バッファーのテキストのスクリーン上の見栄えを変更するために、 プレゼンテーション機能としてオーバーレイ(overlay)を使用できます。オーバーレイとは個々のバッファーに属するオブジェクトであり、指定された開始と終了をもっています。確認したりセットすることができるプロパティももっています。それらはオーバーレイされたバッファー部分のテキスト表示に影響を与えます。

バッファーのテキスト編集では、すべてのオーバーレイがそのテキストに留まるように開始と終了が調整されます。オーバーレイ作成時にはオーバーレイの先頭、または同様に終端にテキストが挿入された場合に、それがオーバーレイの内側(または外側)になるべきなのかを指定できます。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.9.1 オーバーレイの管理

このセクションではオーバーレイの作成、削除、移動、およびそれらのコンテンツを調べる関数を説明します。オーバーレイはバッファーのコンテンツの一部とはみなされないため、その変更はバッファーのundoリストに記録されません。

Function: overlayp object

この関数はobjectがオーバーレイならtをリターンする。

Function: make-overlay start end &optional buffer front-advance rear-advance

この関数はbufferに属する、startからendの範囲のオーバーレイを作成してリターンする。startendはいずれもバッファーの位置を指定しなければならず、整数かマーカーを指定できる。bufferが省略されると、そのオーバーレイはカレントバッファーに作成される。

startendが同一のバッファー位置を指定するオーバーレイは空(empty)のオーバーレイとして知られる。startendの間のテキストが削除されれば、非空のオーバーレイも空になり得る。これが発生したとき、デフォルトではオーバーレイは削除されないが、‘evaporate’プロパティを与えることにより削除されるようにできる(evaporate propertyを参照)。

引数front-advancerear-advanceはそれぞれ、先頭(startの前)あるいは終端にテキストが挿入された際に何が起こるかを指定する。どちらもnil (デフォルト)なら、そのオーバーレイは先頭に挿入された任意のテキストを含むように拡張されるが、終端に挿入されたテキストにたいしては拡張されない。front-advanceが非nilなら、オーバーレイの先頭に挿入されたテキストはオーバーレイから除外される。rear-advanceが非nilなら、オーバーレイの終端に挿入されたテキストはオーバーレイに含まれる。

Function: overlay-start overlay

この関数はoverlayが開始する位置を整数でリターンする。

Function: overlay-end overlay

この関数はoverlayが終了する位置を整数でリターンする。

Function: overlay-buffer overlay

この関数はoverlayが所属するバッファーをリターンする。overlayが削除されていたらnilをリターンする。

Function: delete-overlay overlay

この関数は指定されたoverlayを削除する。そのオーバーレイはLispオブジェクトとして存在し続けて、そのプロパティリストは変更されないがバッファーへの所属と表示にたいするすべての効果を失う。

削除済みオーバーレイが永続的に非接続という訳ではない。move-overlayを呼び出すことによりバッファー内の位置を与えることができる。

Function: move-overlay overlay start end &optional buffer

この関数はoverlaybufferに移動して、その境界をバッファー内のstartendに配置する。startendの引数はいずれもバッファーの位置を指定しなければならず、整数かマーカーを指定できる。

bufferが省略された場合、overlayはすでに関連付けられている同じバッファーに留まる。さらにoverlayが以前に削除されている(つまりどのバッファーにも関連付けられていない)場合にはカレントバッファーに所属させる。

リターン値はoverlay

これはオーバーレイの終端位置を変更する唯一の有効な手段となる関数である。

Function: remove-overlays &optional start end name value

この関数はプロパティnameが指定されたvalueをもつような、startendの間のすべてのオーバーレイを削除する。これによりオーバーレイの両端位置が変更されたり分割される可能がある。

nameが省略かnilなら、それは指定されたリージョン内のすべてのオーバーレイを削除することを意味する。startおよび/またはendが省略かnilなら、それぞれバッファーの先頭と終端を意味する。したがって(remove-overlays)はカレントバッファー内のすべてのオーバーレイを削除する。

Function: copy-overlay overlay

この関数はoverlayのコピーをリターンする。このコピーはoverlayと同じ両端位置とプロパティをもつ。しかしオーバーレイの開始と終了にたいするテキスト挿入タイプはデフォルト値にセットされる。

以下にいくつか例を示します:

;; オーバーレイを作成
(setq foo (make-overlay 1 10))
     ⇒ #<overlay from 1 to 10 in display-ja.texi>
(setq selective-display 2)
     ⇒ 2

(overlay-end foo)
     ⇒ 10
(overlay-buffer foo)
     ⇒ #<buffer display-ja.texi>
;; 後でチェック可能なプロパティを付与
(overlay-put foo 'happy t)
     ⇒ t
;; 付与されたか検証
(overlay-get foo 'happy)
     ⇒ t
;; オーバーレイを移動
(move-overlay foo 5 20)
     ⇒ #<overlay from 5 to 20 in display-ja.texi>
(overlay-start foo)
     ⇒ 5
(overlay-end foo)
     ⇒ 20
;; オーバーレイを削除
(delete-overlay foo)
     ⇒ nil
;; 削除の検証
foo
     ⇒ #<overlay in no buffer>
;; 削除済みオーバーレイは位置をもたない
(overlay-start foo)
     ⇒ nil
(overlay-end foo)
     ⇒ nil
(overlay-buffer foo)
     ⇒ nil
;; 削除を取り消す
(move-overlay foo 1 20)
     ⇒ #<overlay from 1 to 20 in display-ja.texi>
;; 結果の検証
(overlay-start foo)
     ⇒ 1
(overlay-end foo)
     ⇒ 20
(overlay-buffer foo)
     ⇒ #<buffer display-ja.texi>
;; 移動や削除によってオーバーレイのプロパティは変更されない
(overlay-get foo 'happy)
     ⇒ t

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.9.2 オーバーレイのプロパティ

オーバーレイプロパティは文字が表示される方法をどちらのソースからも取得できるという点においてテキストプロパティと似ています。しかしほとんどの観点において両者は異なります。これらの比較はテキストのプロパティを参照してください。

テキストプロパティはそのテキストの一部として考えることができます。オーバーレイとそのプロパティは特にテキストの一部とはみなされません。したがってさまざまなバッファーや文字列の間でテキストをコピーすると、テキストプロパティは保持されますがオーバーレイを保持しようとは試みません。バッファーのテキストプロパティの変更はバッファーを変更済みとマークしますが、オーバーレイの移動やプロパティの変更は違います。テキストプロパティの変更とは異なり、オーバーレイプロパティの変更はバッファーのundoリストに記録されません。

複数のオーバーレイが同じ文字にたいしてプロパティ値を指定できるので、Emacsは各オーバーレイにたいして優先度の指定を促します。優先度の値はオーバーラップするオーバーレイのどちらが“勝つ”かを判断するために使用されます。

以下の関数はオーバーレイのプロパティの読み取りとセットを行います:

Function: overlay-get overlay prop

この関数はoverlay内に記録されたプロパティpropの値をリターンする。そのプロパティにたいしてoverlayが何も値を記録していないが、シンボルであるようなcategoryプロパティをもつ場合には、そのシンボルのpropプロパティが使用される。それ以外なら値はnil

Function: overlay-put overlay prop value

この関数はoverlay内に記録されたプロパティpropの値にvalueをセットする。リターン値はvalue

Function: overlay-properties overlay

これはoverlayのプロパティリストのコピーをリターンする。

与えられた文字にたいしてテキストプロパティとオーバーレイプロパティの両方をチェックする関数get-char-propertyも参照してください。テキストプロパティを調べるを参照してください。

多くのオーバーレイプロパティには特別な意味があります。以下はそれらのテーブルです:

priority

このプロパティの値はオーバーレイの優先度を決定する。優先度にたいして値を指定したければnil (か0)、正の整数、あるいは2つの値のコンスセルを使用すること。それ以外のすべての値にたいしては未定義の動作が起こる。

2つ以上のオーバーレイが同じ文字をカバーし、それぞれが同じプロパティに違う値を指定する場合には優先度が重要になる。そのような場合には他よりpriorityの値が大きいほうが他をオーバーライドする(faceプロパティにたいしては、より高い優先度のオーバーレイの値は他の値を完全にはオーバーライドしない; それぞれのface属性にたいしてより高い優先度のface属性が低い優先度のfaceプロパティのface属性をオーバーライドする)。2つのオーバーレイが同じ優先値をもち、一方がもう一方に“ネスト”されている(カバーしているバッファーや文字列位置が小さい)場合には、内側のオーバーレイが外側のオーバーレイより優先される。いずれのオーバーレイも他方にネストされていなければ、どちらのオーバーレイが優先するかを仮定しないこと。

優先度のないオーバーレイをもつかもしれないテキストにLispプログラムが優先度を定義する際には、望ましくない結果が生じるかもしれない。なぜなら優先度のないオーバーレイは、正の優先度をもつすべてのオーバーレイにオーバーライドされてしまうからである。Emacsのほとんどの機能は優先度を指定せずにオーバーレイを使っているため、整数の優先度の使用には注意を要する。整数の優先度を使用することによって他のオーバーレイをオーバーライドしてしまう危険を冒すかわりに、(primary . secondary)という形式の値を優先度にすることができる。ここでprimaryは上述のように使用されるが、primaryにたいするネスト状況の検討においてそれぞれのオーバーレイの間の優先度の解決に失敗した際に用いられるフォールバック値がsecondaryである。特に優先度の値として(nil . n)nに正の整数を指定すると、他のオーバーレイを完全にオーバーライドせずに、必要に応じてオーバーレイを優先度順に並べることができる。

現在のところ、すべてのオーバーレイはテキストプロパティより優先される。

優先度順にオーバーレイを配置する必要がある場合には、overlays-atsorted引数を用いることができる。See オーバーレイにたいする検索を参照のこと。

window

windowプロパティが非nilならオーバーレイはそのウィンドウだけに適用される。

category

オーバーレイがcategoryプロパティをもつなら、それをオーバーレイのカテゴリー(category)と呼ぶ。これはシンボルであること。そのシンボルのプロパティはオーバーレイのプロパティにたいしてデフォルトの役割を果たす。

face

このプロパティはテキストの外観を制御する(フェイスを参照)。プロパティの値は以下のいずれか:

  • フェイス名(シンボルか文字列)。
  • anonymousフェイス: (keyword value …)という形式のプロパティリストでありkeywordはフェイス属性名、valueはその属性の値。
  • フェイスのリスト。リストの要素はそれぞれフェイス名かanonymousフェイスのいずれかであること。これはリストされた各フェイスの属性を集約するフェイスを指定する。このリスト内で先に出現するフェイスが、より高い優先度をもつ。
  • (foreground-color . color-name)(background-color . color-name)という形式のコンスセル。これは(:foreground color-name)(:background color-name)と同じように、フォアグラウンドとバックグラウンドのカラーを指定する。この形式は後方互換性のためだけにサポートされており、使用は避けること。
mouse-face

このプロパティはマウスがオーバーレイ範囲内にあるときに、faceのかわりに使用される。しかしEmacsはこのプロパティに由来するテキストのサイズを変更するようなフェイス属性(:height:weight:slant)をすべて無視する。これらの属性はハイライトされていないテキストでは常に同一である。

display

このプロパティはテキストが表示される方法を変更するさまざまな機能をアクティブにする。たとえばこれはテキストの外観を縦長(taller)や横長(shorter)にしたり、高く(higher)したり低く(lower)したり、イメージによる置き換えを行う。displayプロパティを参照のこと。

help-echo

あるオーバーレイがhelp-echoプロパティをもつなら、そのオーバーレイ内のテキスト上にマウスを移動した際に、Emacsはエコーエリアかツールチップにヘルプ文字列を表示する。詳細はText help-echoを参照のこと。

field

同じfieldプロパティをもつ連続する文字はフィールド(field)を形成する。forward-wordbeginning-of-lineを含むいくつかの移動関数はフィールド境界で移動を停止する。フィールドの定義と使用を参照のこと。

modification-hooks

このプロパティの値はオーバーレイ内の任意の文字の変更、またはオーバーレイの厳密に内側にテキストが挿入された場合に呼び出される関数のリスト。

このフックの関数は各変更の前後両方で呼び出される。これらの関数が受け取った情報を保存して呼び出し間で記録を比較すれば、バッファー内のテキストでどのような変更が行われたかを正確に判断できる。

変更前に呼び出された際にはオーバーレイ、nil、変更されたテキスト範囲の開始と終了という4つの引数を各関数は受け取る。

変更後に呼び出された際にはオーバーレイ、t、変更されたテキスト範囲の開始と終了、およびその範囲により置き換えられた変更前のテキスト長という5つの引数を各関数は受け取る(変更前の長さは挿入では0、削除では削除された文字数であり、変更後の先頭と終端が等しくなる)。

これらの関数が呼び出される際にはinhibit-modification-hooksが、非nilにバインドされる。関数がバッファーを変更した場合には変更にたいして変更フックが実行されるように、inhibit-modification-hooksnilにバインドしたいと思うかもしれない。しかしこれを行うことにより、あなた自身の変更フックが再帰的に呼び出されるかもしれないので、それに確実に備える必要がある。フックの変更を参照のこと。

テキストプロパティもmodification-hooksプロパティをサポートするが詳細は幾分異なる(特殊な意味をもつプロパティを参照)。

insert-in-front-hooks

このプロパティの値はオーバーレイ先頭へのテキスト挿入前後に呼び出される関数のリスト。呼び出し方はmodification-hooksの関数と同様。

insert-behind-hooks

このプロパティの値はオーバーレイ終端へのテキスト挿入前後に呼び出される関数のリスト。呼び出し方はmodification-hooksの関数と同様。

invisible

invisibleプロパティによりオーバーレイ内のテキストを不可視にできる。これはそのテキストがスクリーン上に表示されないことを意味する。詳細は不可視のテキストを下さいのこと。

intangible

オーバーレイのintangibleプロパティは正にintangibleテキストプロパティと同様に機能する。これは時代遅れである。詳細はSee 特殊な意味をもつプロパティを参照のこと。

isearch-open-invisible

このプロパティはインクリメンタル検索(Incremental Search in The GNU Emacs Manualを参照)にたいして最後のマッチがそのオーバーレイに重なる場合に、不可視なオーバーレイを永続的に可視にする方法を告げる。不可視のテキストを参照のこと。

isearch-open-invisible-temporary

このプロパティはインクリメンタル検索にたいして、検索の間に不可視なオーバーレイを一時的に可視にする方法を告げる。不可視のテキストを参照のこと。

before-string

このプロパティの値はオーバーレイ先頭に表示するために追加する文字列。この文字列はいかなる意味においてもバッファー内には出現せずにスクリーン上にのみ表れる。オーバーレイ先頭のテキストが不可視になると、その文字列は表示されなくなることに注意。

after-string

このプロパティの値はオーバーレイ終端に表示するために追加する文字列。この文字列はいかなる意味においてもバッファー内には出現せずにスクリーン上にのみ表れる。オーバーレイ終端のテキストが不可視になると、その文字列は表示されなくなることに注意。

line-prefix

このプロパティは表示時にそれぞれの非継続行の後に追加するディスプレイ仕様(display spec)を指定する。切り詰めを参照のこと。

wrap-prefix

このプロパティは表示時にそれぞれの継続行の前に追加するディスプレイ仕様(display spec)を指定する。切り詰めを参照のこと。

evaporate

このプロパティが非nilの場合には、そのオーバーレイが空(長さが0)になったら自動的に削除される。空のオーバーレイ(empty overlayを参照)にたいして非nilevaporateプロパティを与えた場合には即座に削除される。オーバーレイがこのプロパティをもたなければ、バッファーからオーバーレイの開始位置と終了位置の間のテキストが削除された際に削除されないことに注意。

keymap

このプロパティがnilなら、そのテキスト範囲にたいしてキーマップを指定する。このキーマップはポイントがオーバーレイ内部(境界だ内部か否かの定義にはfront-advanceおよびrear-advanceのプロパティを考慮する)にあるとき使用されて、他のほとんどのキーマップ(アクティブなキーマップを参照)より優先される。

local-map

local-mapプロパティはkeymapプロパティと同様だが、既存のキーマップに付け加えるのではなくバッファーのローカルマップを置き換える点が異なる。これはそのキーマップがマイナーモードキーマップより低い優先度をもつことも意味する。

keymaplocal-mapプロパティはbefore-stringafter-stringdisplayプロパティにより表示された文字列には影響しません。これはポイントがその文字列上にない場合のマウスクリックや、その文字列に関する他のマウスイベントにのみ関係があります。その文字列に特別なマウスイベントをバインドするには、そのイベントをkeymaplocal-mapプロパティに割り当てます。特殊な意味をもつプロパティを参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.9.3 オーバーレイにたいする検索

Function: overlays-at pos &optional sorted

この関数はカレントバッファー内の位置posにある文字をカバーするすべてオーバーレイのリストをリターンする。sortedが非nilならリストは優先度降順、それ以外なら特定の順にはソートされない。オーバーレイがpos、またはそれより前から始まり、かつposの後で終わるなら位置posはオーバーレイに含まれる。

以下はポイント位置の文字にたいしてプロパティpropを指定するオーバーレイのリストをリターンするLisp関数の使用例:

(defun find-overlays-specifying (prop)
  (let ((overlays (overlays-at (point)))
        found)
    (while overlays
      (let ((overlay (car overlays)))
        (if (overlay-get overlay prop)
            (setq found (cons overlay found))))
      (setq overlays (cdr overlays)))
    found))
Function: overlays-in beg end

この関数はbegからendのリージョンと重複(overlap)するオーバーレイのリストをリターンする。オーバーレイがリージョン内の文字を少なくとも1つ含めば、オーバーレイとリージョンは重複している。空のオーバーレイ(empty overlayを参照)がbegにある場合、厳密にはbegbegの間、またはendがバッファーのアクセス可能範囲終端の位置を意味するときにendにある場合には重複している。

Function: next-overlay-change pos

この関数はposの後にあるオーバーレイの開始か終了となるバッファー位置をリターンする。それが存在しなければ(point-max)をリターンする。

Function: previous-overlay-change pos

この関数はposの前にあるオーバーレイの開始か終了となるバッファー位置をリターンする。それが存在しなければ(point-min)をリターンする。

以下に例としてプリミティブ関数next-single-char-property-change (テキストプロパティの検索関数を参照)の単純化(かつ非効率的)したバージョンを示します。これは位置posから前方へ与えられたプロパティpropにたいして、オーバーレイプロパティまたはテキストプロパティのいずれかの値が変化した次の位置を検索します。

(defun next-single-char-property-change (position prop)
  (save-excursion
    (goto-char position)
    (let ((propval (get-char-property (point) prop)))
      (while (and (not (eobp))
                  (eq (get-char-property (point) prop) propval))
        (goto-char (min (next-overlay-change (point))
                        (next-single-property-change (point) prop)))))
    (point)))

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.10 表示されるテキストのサイズ

すべての文字が同じ幅をもつ訳ではありませんが、以下の関数により文字の幅をチェックできます。関連する関数についてはインデント用のプリミティブスクリーン行単位の移動を参照してください。

Function: char-width char

この関数は文字charがカレントバッファーに表示された場合(つまりそのバッファーのディスプレイテーブルがあれば考慮に入れる。ディスプレイテーブルを参照)の幅を列数でリターンする。タブ文字の幅、通常はtab-width (通常の表示の慣習を参照)。

Function: char-uppercase-p char

charがUnicodeに照らして大文字であれば非nilをリターンする。

Function: string-width string &optional from to

この関数は文字列stringがカレントバッファーおよび選択されたウィンドウに表示された場合の幅を列数でリターンする。オプション引数fromtostring内で考慮すべき部分文字列を指定するもので、substringの場合のように解釈される(文字列の作成を参照)。

リターン値は近似値。ディスプレイプロパティやフォント等は無視して構成文字(constituent characters)にたいしてはchar-widthのリターン値、タブ文字は常にtab-width列を占めるものとみなす。これらの理由により、以下で説明するwindow-text-pixel-sizestring-pixel-widthの使用を推奨する。

Function: truncate-string-to-width string width &optional start-column padding ellipsis ellipsis-text-property

この関数はディスプレイ上でwidth列を満たすようにstringを切り詰めて、新たな文字列としてリターンする。

stringwidthに満たなければ、結果はstringと等しい。それ以外の場合には超過した文の文字列は結果から省かれる。string内の複数列文字が列widthを超過する場合には、その文字は結果に含まれない。つまり結果がwidthより短くなりことはあり得るが、超過することはない。

オプション引数start-columnは開始列を指定する(デフォルトは0)。これが非nilなら、その文字列の最初のstart-column列は値から省かれる。string内の1つの複数列文字が列start-columnを超えて跨がるようなら、その文字は結果に含まれない。

オプション引数paddingが非nilなら、結果となる文字列の幅を正確にwidth列に拡張するためにパディング文字が追加される。結果がwidthより短ければ、widthに達するまで必要な個数分のパディング文字が終端に追加される。string内の複数列文字が列start-columnを超える場合には、結果の先頭にもパディング文字が追加される。

ellipsisが非nilの場合には、stringを切り詰める際にstring終端を置き換える文字列であること。この場合にはwidth列に収まるよう、ellipsis用に必要なスペースを開放するために、より多くの文字がstringから削除される。しかしstringの表示幅がellipsisの表示幅より小さければ、ellipsisを結果に追加しない。ellipsisが非nilかつ文字列以外なら、それは変数truncate-string-ellipsisの値を意味する。

オプション引数ellipsis-text-propertyが非nilなら、実際に文字列を切り詰めずに省略記号(ellipsis)を表示するdisplayテキストプロパティ(displayプロパティを参照)でstringの超過部分を隠すことを意味する。

(truncate-string-to-width "\tab\t" 12 4)
     ⇒ "ab"
(truncate-string-to-width "\tab\t" 12 4 ?\s)
     ⇒ "    ab  "

この関数はstringが広すぎる際に適切な切り詰め位置を見つけるためにstring-widthchar-widthが使用するのでstring-widthと同じ問題を抱えている。とりわけstring内で文字合成(character composition)が発生した際には、文字列の表示幅が構成文字の合計幅より短くなるかもしれず、この関数が不正確な結果をリターンするかもしれない。

Function: truncate-string-ellipsis

この関数はtruncate-string-to-widthおよび同様のコンテキストにおいて省略記号(ellipses)として使用する文字列をリターンする。値は変数truncate-string-ellipsisnilでなければその値、すなわち選択されたフレームで表示可能なら単一文字U+2026 HORIZONTAL ELLIPSIS、それ以外なら文字列‘...’。

以下の関数は与えられたウィンドウにあるテキストを表示したときのサイズをピクセル単位でリターンします。この関数はテキストを含むためにウィンドウを十分大きくするためにfit-window-to-bufferfit-frame-to-buffer (ウィンドウのリサイズを参照)により使用されます。

Function: window-text-pixel-size &optional window from to x-limit y-limit mode-lines ignore-line-at-end

この関数はwindowのバッファーのテキストサイズをピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。リターン値は任意のテキスト行の最大ピクセル幅と、すべてのテキスト行の最大ピクセル高さのコンス。この関数はバッファーがテキストの表示を要したり、その他似たような状況において必要となるwindowサイズをLispプログラムが調整できるようにするために存在する。

リターン値にはオプションでサイズが計測された最初の行のバッファー位置を含めることができる(以下参照)。

オプション引数fromが非nilなら、それは考慮すべき最初のテキスト位置を指定する。デフォルトはそのバッファーのアクセス可能な最小の位置。fromtなら、改行文字ではないアクセス可能な最小位置を意味する。fromがコンスセルの場合にはcarがバッファー位置、cdrにはその位置から、サイズを測定するテキストが属する最初のスクリーン行までの垂直オフセットをピクセル単位で指定する(計測はそのスクリーン行の視覚的な先頭から開始されることになる)。この場合にはピクセルの幅と高さ、それにバッファー位置からなるリストが値としてリターンされる。オプション引数toが非nilなら、それは考慮すべき最後のテキスト位置を指定する。デフォルトはそのバッファーのアクセス可能な最大の位置。totなら、改行文字ではないアクセス可能な最大位置を意味する。

オプション引数x-limitが非nilなら、その位置を超えるテキストを指定するような最大X座標を指定する。したがってこれはこの関数がリターンし得る最大のピクセル幅でもある。x-limitnilまたは省略なら、windowのbody(ウィンドウのサイズを参照)のピクセル幅を使用することを意味する。このデフォルト値はウィンドウより長い切り詰められた行のテキストは無視されることを意味する。このデフォルト値はは呼び出し側がwindowの幅の変更を意図しない場合に有用。それ以外なら呼び出し側はここで想定されるwindowのbodyの最大幅を指定すること。特に行の切り詰めが予想される場合に、それらの行のテキストを勘定に入れる必要があるなら、x-limitを大きな値にセットする必要がある。長い行の幅の計算にはいくらかの時間を要するかもしれないので、必要に応じてこの変数を小さくするのはよいアイデアである。これはいずれにせよ切り詰められるような長い行をバッファーが含む場合が特に該当する。

オプション引数y-limitが非nilなら、その値を超えるテキストは無視されるような最大Y座標を指定する。したがってこれは関数がリターンし得る最大のピクセル高さでもある。y-limitnilか省略なら、toで指定したバッファー位置までのすべてのテキスト行を考慮することを意味する。大きなバッファーのピクセル高さの計算には多くの時間を要する可能性があるので、特に呼び出し側がバッファーのサイズを知らない場合におけるこの変数の指定は合理的である。

オプション引数mode-linesnilまたは省略された場合には、リターン値にwindowのモードライ、タブライン、ヘッダーラインの高さを含めないことを意味する。これがシンボルmode-linetab-lineheader-lineのいずれかなら、それらが存在する場合にはリターン値にそのラインの高さだけを含める。これがtの場合には、もし存在すればすべてのラインの高さをリターン値に含める。

オプション引数ignore-line-at-endはリターンするpixel-heightにtoのスクリーン行のテキスト高さを含めるかどうかを制御します。これはあなたのLispプログラムにとって関心があるのは、toのスクリーン行の視覚的な先頭を除外したテキストのサイズだけという場合に役に立つでしょう。

window-text-pixel-sizeはウィンドウ内に表示されているテキスト全体を扱い、個々の行サイズには留意しません。それは以下の関数が行います。

Function: window-lines-pixel-dimensions &optional window first last body inverse left

この関数は指定したwindowに表示された各行のピクセルサイズを計算する。これはwindowのカレントグリフマトリクス( windowにカレントで表示されている各バッファー文字のグリフを格納するマトリクス。グリフを参照)を調べることにより機能する。成功したら各行末文字の右下隅のX座標とY座標を表すコンスペアのリストをリターンする。これらの座標はwindowの左上隅にある原点(0, 0)からピクセル単位で計測される。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。

オプション引数firstが整数なら、リターンするwindowのグリフマトリクスの最初の行のインデックス(0から開始)を示す。windowにヘッダーラインがあればインデックス0の行はヘッダーラインになることに注意。firstnilなら考慮する最初の行はオプション引数bodyの値で判断される。bodyが非nilなら、(もしあれば)ヘッダーラインをすべてスキップしてwindowのbodyの最初の行から開始することを意味する。それ以外ならwindowのグリフマトリクスの最初の行(ヘッダーラインかもしれない)から開始することを意味する。

オプション引数lastが整数なら、リターンするwindowのグリフマトリクスの最後の行のインデックスを示す。lastnilなら考慮する最初の行はオプション引数bodyの値で判断される。bodyが非nilなら、windowのモードラインを省略してwindowのbodyの最後の行を使用することを意味する。それ以外ならwindowのグリフマトリクスの最後の行(モードラインかもしれない)を使用することを意味する。

オプション引数inversenilなら、リターンされる任意の行にたいするYピクセル値がwindowの左エッジ(bodyが非nilなら左bodyエッジ)から、その行の最後のグリフの右エッジまでのピクセル単位の距離を指定することを意味する。非nilinverseは、リターンされる任意の行にたいするYピクセル値がその行の最後のグリフの右エッジから右エッジ(bodyが非nilなら右bodyエッジ)までのピクセル単位の距離を指定することを意味する。これは各行末の未使用スペースの量を判断するために有用。

オプション引数leftが非nilなら各行左端文字の左下隅のX座標とY座標をリターンすることを意味する。これは主に右から左にテキストを表示にたいして使用されるべき値である。

leftが非nilinversenilなら、リターンされる任意の行にたいするYピクセル値がその行の最後(左端)のグリフの左エッジから、windowの右エッジ( bodyが非nilなら右bodyエッジ)までのピクセル単位の距離を指定することを意味する。leftinverseがいずれも非nilなら、リターンされる任意の行にたいするYピクセル値がwindowの左エッジ( bodyが非nilなら左bodyエッジ)から、その行の最後(左端)のグリフの左エッジまでのピクセル単位の距離を指定することを意味する。

この関数はwindowのカレントグリフマトリクスが最新でなければnilをリターンする。これはたとえばコマンドの処理中のようにEmacsがbusyな際に通常は発生する。これは遅延が0秒であるようなアイドルタイマーからこの関数が実行された際に取得され得る値である。

Function: buffer-text-pixel-size &optional buffer-or-name window from to x-limit y-limit

これはwindow-text-pixel-sizeに酷似しているが、そのバッファーがウィンドウに表示されていない際に使用できる(ウィンドウに表示されていればwindow-text-pixel-sizeのほうが高速なのでこの関数を使用するべきではない)。

buffer-or-nameには生きたバッファーか生きたバッファーの名前を指定しなければならず、デフォルトはカレントバッファー。windowは生きたウィンドウでなければならず、デフォルトは選択されたウィンドウ。この関数はあたかもbufferwindowで表示されているかのようにテキストのサイズを算出する。リターン値は全テキスト行の最大pixel-width、およびbuffer-or-nameで指定されたバッファーの全テキスト行のpixel-heightからなるコンス。

オプション引数x-limity-limitは、window-text-pixel-sizeの場合と同じ意味をもつ。

Function: string-pixel-width string

これはwindow-text-pixel-sizeを用いてstringの幅(ピクセル単位)を計算する利便関数である。

Function: line-pixel-height

この関数は選択されたウィンドウのポイント位置にある行の高さをピクセル単位でリターンする。値にはその行の行スペーシングが含まれる(行の高さを参照)。

Function: string-glyph-split string

文字合成(character composition)が効力をもっていれば、たとえばアクセント付き文字、合字、あるいは複雑なテキストシェイプが一部スクリプト用に必要な際に書記素クラスター(grapheme cluster)を形成するよう文字シーケンスを合成できる。これが発生すると単純な方法によって文字が表示列にマップされなくなり、そのような文字列にたいする表示レイアウト、そしてワイド文字列の切り詰めも複雑な処理となり得る。これはそのような処理において一助となる関数である。この関数は引数stringを部分文字列のリストに分割する。この部分文字列はそれぞれ1つの単位として表示されるべき単一の書記素クラスターを生成する。このリストを使用すればLispプログラムは表示において正しい見た目になるよう視覚的に有効にstringの部分文字列を構成したり、リターンされたリストの構成要素の幅を追加してstringの任意の部分文字列の幅を計算する等を行うことができるだろう。

たとえば1つ目のグリフ以外を表示したければ以下のようにすればよい:

(apply #'insert (cdr (string-glyph-split string))))

行番号(Display Custom in The GNU Emacs Manualを参照)とともにバッファーを表示している際には、行番号の表示に必要な幅が解ると便利なときがあります。以下はレイアウト計算用にこの情報を必要とするLispプログラムのための関数です。

Function: line-number-display-width &optional pixelwise

この関数は選択されたウィンドウで行番号の表示に使用される幅をリターンする。オプション引数pixelwiseがシンボルcolumnsなら、リターン値はフレームの正準列(正準文字幅)にたいする浮動小数点数となる。pixelwisetやそれ以外の非nil値なら、値はピクセルで計測した整数となる。pixelwiseが省略かnilなら、値はline-numberフェイスにたいして定義されたフォントによる列数を表す整数となる。この場合には値には番号の表示の間隙を埋めるために使用する2列分は含まれない。選択されたウィンドウに行番号が表示されていなければ、pixelwiseの値にかかわらず値は0になる。別のウィンドウにたいしてこの情報が必要ならwith-selected-windowを使用すること(ウィンドウの選択を参照)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.11 行の高さ

各ディスプレイ行のトータル高さは、その行のコンテンツ高さにディスプレイ上部や下部にオプションで追加される垂直行スペーシングを加えて構成されます。

行のコンテンツ高さは、もしあれば最後の改行を含む、そのディスプレイ行の文字またはイメージの最大高さです(継続されるディスプレイ行には最後の改行が含まれない)。特にこれより大きい高さを指定しなければ、これがデフォルトの行高さになります(これは一般的には対応するフレームのデフォルトのフォント高さに等しい。フレームのフォントを参照)。

より大きい行高さを明示的に指定するためにはディスプレイ行の絶対高さ、または垂直スペースを指定する複数の方法が存在します。しかし何を指定したかに関わらず、実際の行高さがデフォルトの高さより小さくなることはありません。

改行はその改行で終わるディスプレイ行のトータル高さを制御するテキストプロパティとオーバーレイプロパティline-heightをもつことができます。プロパティ値はいずれかの形式をもつことができます:

t

プロパティの値がtなら改行文字はその行の表示高さにたいして効果をもたず、可視なコンテンツだけが高さを決定します。この場合には以下で説明する改行のline-spacingプロパティも無視されます。これはイメージ間に追加のブランク領域をもたない、小さなイメージ(やイメージスライス)にたいして有用です。

(height total)

プロパティの値がこの形式のリストなら、これはディスプレイ行の下部に余分なスペースを追加します。最初にEmacsは、その行の上部の余分なスペースを制御するための高さspecとして、heightを使用します。それから行のトータル高さをtotalにするために、行の下部に必要なスペースを追加します。この場合には、改行にたいするline-spacingプロパティのすべての値は無視されます。

他の種類のプロパティ値は高さspec(height spec)です。これは行の高さを指定する数値に変換されます。高さspecを記述するためには複数の方法があります。以下はそれらが数値に変換される方法です:

integer

高さspecが正の整数なら高さの値はその整数。

float

高さspecが浮動小数点数floatなら高さ数値はそのフレームのデフォルト行高さのfloat倍。

(face . ratio)

高さspecがこのフォーマットのコンスなら、高さ数値はフェイスfaceの高さのratio倍。ratioには任意の型の数値を指定でき、nilは1のratioを意味する。facetならカレントフェイスを参照する。

(nil . ratio)

高さspecがこのフォーマットのコンスなら高さ数値はその行のコンテンツ高さのratio倍。

したがって任意の有効な種々の高さspecによりピクセル単位で高さが決定されます。行のコンテンツ高さがこれより小さければ、Emacsは指定されたトータル高さになるように余分な垂直スペースを行の上部に追加します。

line-heightプロパティを指定しない場合には、その行の高さは行のコンテンツ高さとに行スペーシングを追加して構成されます。Emacsの異なるさまざまな部分のテキストにたいして、行スペーシングを指定する複数の方法が存在します。

グラフィカルなディスプレイではフレームパラメーターline-spacing (レイアウトのパラメーターを参照)を使用することにより、フレーム内のすべての行にたいして行スペーシングを指定できます。しかしline-spacingのデフォルト値が非nilなら、それはそのフレームのフレームパラメーターline-spacingをオーバーライドします。整数は行の下部に配するピクセル数を指定します。浮動小数点数はフレームのデフォルト行高さに相対的にスペーシングを指定します。

バッファーローカル変数line-spacingを通じて、バッファー内のすべての行の行スペーシングを指定できます。整数は行の下部に配するピクセル数を指定します。浮動小数点数はデフォルトフレーム行高さに相対的にスペーシングを指定します。これはそのフレームにたいして指定された行スペーシングをオーバーライドします。

最後に改行は改行で終わるディスプレイ行にたいしてデフォルトフレーム行スペーシングを広くできるテキストプロパティとオーバーレイプロパティline-spacing、および変数line-spacingをもつことができます。その値がバッファーやフレームのデフォルトより大きければ、その改行で終端されるディスプレイ行にはかわりにその値が使用されます(改行にline-heightもあり、line-spacingが無視されるような特別な値のいずれかをもつ場合を除く; 上記参照)。

種々の方法によりこれらのメカニズムは各行のスペーシングにたいするLisp値を指定します。値は高さspecで、これは上述したLisp値に変換されます。しかしこの場合には高さ数値は行高さではなく行スペーシングを指定します。

テキスト端末では行スペーシングは変更できません。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12 フェイス

フェイス(face)とはフォント、フォアグラウンドカラー、バックグラウンドカラー、オプションのアンダーライン等のテキストを表示するためのグラフィカルな属性のコレクションのことです。フェイスはEmacsがバッファー内や、同様にモードラインのようなフレームの他の部分でテキストを表示する方法を制御します。

フェイスを表現する1つの方法として(:foreground "red" :weight bold)のような属性のプロパティリストがあります。このようなリストはanonymousフェイス(anonymous face)と呼ばれます。たとえばfaceテキストプロパティとしてanonymousフェイスを割り当てることができ、Emacsは指定された属性でテキストを表示するでしょう。特殊な意味をもつプロパティを参照してください。

より一般的にはフェイスはフェイス名(face name)を通じて参照されます。これはフェイス属性のセットに関連付けられたLispシンボル29です。名前つきフェイスはdeffaceマクロを使用して定義できます(フェイスの定義を参照)。Emacsにはいくつかの標準名前つきフェイスが同梱されています(基本的なフェイスを参照)。

Emacsのある部分では名前つきフェイスが要求されます(たとえばフェイス属性のための関数に記す関数)。特に明記しないかぎり、名前つきフェイスの参照だけに用語フェイスを使用することにします。

Function: facep object

この関数はobjectが名前つきフェイス(フェイス名の役目をもつLispシンボルか文字列)なら非nil、それ以外ならnilをリターンする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.1 フェイスの属性

フェイス属性(Face attributes)は、フェイスの視覚的外観を決定します。以下はすべてのフェイス属性と、それらの可能な値と効果に関するテーブルです。

以下の値とは別に各フェイス属性は値unspecifiedをもつことができます。この特殊な値はフェイスがその属性を直接指定しないことを意味します。unspecified属性はEmacsにかわりに親フェイス(以下の:inherit属性の記述を参照)を参照して、それに失敗したら基礎フェイス(フェイスの表示を参照)を参照することを指示します(ただしdeffaceにおいてunspecifiedは有効な値ではない)。

フェイスの属性としてresetという値をもつこともできます。これはdefaultフェイスの相当する属性を意味する特別な値です。

defaultフェイスではすべての属性を明示的に指定しなければならずスペシャル値resetは使用できません。

これらの属性のいくつかは特定の種類のディスプレイにおいてのみ意味があります。ディスプレイが特定の属性を処理できなければ、その属性は無視されます。

:family

フォントファミリー名(文字列)。フォントファミリーに関する詳細はFonts in The GNU Emacs Manualを参照のこと。関数font-family-list (以下参照)は利用可能なファミリー名のリストをリターンする。

:foundry

:family属性により指定されるフォントファミリーにたいするフォントfoundry (文字列)。Fonts in The GNU Emacs Manualを参照のこと。

:width

相対的な文字幅。これはシンボルultra-condensedextra-condensedcondensedsemi-condensednormalregularmediumsemi-expandedexpandedextra-expandedultra-expandedのいずれかであること。

:height

フォントの高さ。もっともシンプルなケースでは1/10ポイントを単位とする整数。

値には基礎フェイス(underlying face)にたいして相対的に高さを指定する浮動小数点数、または関数も指定できる(フェイスの表示を参照)。浮動小数点数は基礎フェイスの高さをスケーリングする量を指定する。関数値は基礎フェイスの高さを単一の引数として呼び出されて、新たなフェイスの高さをリターンする。関数が整数を引数として渡された場合には整数をリターンしなければならない。

デフォルトフェイスの高さは整数を使用して指定しなければならない。浮動小数点数や関数は受け入れられない。

:weight

フォントのweight。シンボルultra-boldextra-boldboldsemi-boldnormalsemi-lightlightextra-lightultra-light (太字から細字順)のいずれか。可変輝度テキストをサポートするテキスト端末では、normalより大なweightはより高輝度、小なweightはより低輝度で表示される。

:slant

フォントのslant。シンボルitalicobliquenormalreverse-italicreverse-obliqueのいずれか。可変輝度テキストをサポートするテキスト端末ではslantされたテキストはhalf-brightで表示される。

:foreground

フォアグラウンドカラー(文字列)。値にはシステム定義済みカラー、または16進カラー仕様を指定できる。カラー名を参照のこと。白黒ディスプレイでは特定のグレー色調が点描パターンで実装されている。

:distant-foreground

代替えのフォアグラウンドカラー(文字列)。これは:foregroundと似ているが、使用されるであろうフォアグラウンドカラーがバックグラウンドカラーに近いときのみフォアグラウンドカラーとして使用される点が異なる。これはたとえばテキストをマーク時(リージョンフェイス)に有用。そのテキストがリージョンフェイスとして可視なフォアグラウンドをもつ場合には、そのフォアグラウンドが使用される。フォアグラウンドがリージョンフェイスのバックグラウンドに近ければ、テキストを可読にするために:distant-foregroundが使用される。

:background

バックグラウンドカラー(文字列)。値にはシステム定義済みカラー、または16進カラー仕様を指定できる。カラー名を参照のこと。

:underline

文字にアンダーラインを引くべきか否か、およびその方法。:underline属性として可能な値は以下のとおり:

nil

アンダーラインを引かない。

t

そのフェイスのフォアグラウンドカラーでアンダーラインを引く。

color

文字列colorで指定されたカラーでアンダーラインを引く。

(:color color :style style :position position)

colorは文字列、またはそのフェイスのフォアグラウンドカラーを意味するシンボルforeground-color。属性:colorの省略はフェイスのフォアグラウンドカラーの使用を意味する。styleは直線を意味するline、または波線を意味するwaveいずれかのシンボルであること。属性:styleの省略は直線を意味する。positionが非nilの場合には、アンダーラインをベースラインではなく、そのテキストのディセントに表示することを意味する。数値の場合には、ディセントの上方何ピクセルにアンダーラインを表示するかを指定する。

:overline

文字にオーバーラインを引くべきか否か、およびそのカラー。値がtならフェイスのフォアグラウンドカラーを使用してオーバーラインを引く。値が文字列ならそのカラーを使用してオーバーラインを引く。値nilはオーバーラインを引かないことを意味する。

:strike-through

文字に取り消し線を引くべきか否か、およびそのカラー。値は:overlineで使用される値と同じ。

:box

文字周囲に枠(box)を描画するか否か、そのカラー、枠線の幅、および3D外観。以下は:boxの可能な値と意味:

nil

枠を描画しない。

t

幅1のフォアグラウンドカラーで枠線を描画する。

color

幅1のカラーcolorで枠線を描画する。

(:line-width (vwidth . hwidth) :color color :style style)

このフォームのようなplistによって、枠(box)に関するすべての側面を明示的に指定できる。このplistの任意の要素は省略できる。

vwidthhwidthはそれぞれ、垂直および水平方向に描画する線幅を指定する。デフォルトは(1 . 1)。負の水平または垂直幅-nは、背後にあるテキスト文字の高さや幅の増加を避けるために、テキストスペースを占める幅nの線の描画を意味する。リストのかわりに簡素化のために単一の数値nを指定でき、この場合には((abs n) . n)を指定したのと等しい。

styleは3D枠線を描画するか否かを指定する。released-buttonなら押下された3Dボタンのような外観、pressed-buttonなら押下されていない3Dボタンのような外観、nilflat-button、または省略なら2D枠線が使用される。

colorは描画するカラーを指定する。デフォルトは3D枠線とflat-buttonではフェイスのバックグラウンドカラー、それ以外の枠線ではフェイスのフォアグラウンドカラー。

:inverse-video

文字が反転表示されて表示されるべきか否か。値はt (反転表示する)かnil (反転表示しない)のいずれか。

:stipple

バックグラウンドの点描(ビットマップ)。

値には文字列を指定できる。外部形式Xビットマップデータを含むファイルの名前であること。ファイルは変数x-bitmap-file-pathにリストされるディレクトリー内で検索される。

かわりに(width height data)という形式のリストによりビットマップで直接値を指定できる。ここでwidthheightはピクセル単位によるサイズ、dataは行単位でビットマップのrawビットを含む文字列。各行は文字列内で連続する(width + 7) / 8バイトを占める(最善の結果を得るためにはユニバイト文字列であること)。これは各行が常に少なくとも1バイト全体を占めることを意味する。

値がnilなら点描パターンを使用しないことを意味する。

これは特定のグレー色調を処理するために自動的に使用されるので、通常はstipple属性のセットは必要ない。

:font

そのフェイスの表示に使用されるフォント。値はフォントオブジェクトかフォントセットであること。フォントオブジェクトならASCII文字の表示用フェイスに使用されるフォントを指定する。フォントオブジェクト、フォントスペース、フォントエンティティーに関する情報は低レベルのフォント表現、フォントセットに関する情報はフォントセットを参照のこと。

set-face-attributeset-face-font (フェイス属性のための関数を参照)を使用してこの属性を指定する際にはフォントspec、フォントエンティティー、または文字列を与えることもできる。Emacsはそのような値を適切なフォントオブジェクトに変換して、実際の属性値としてそのフォントオブジェクトを格納する。文字列を指定する場合には、その文字列のコンテンツはフォント名であること(Fonts in The GNU Emacs Manualを参照)。フォント名がワイルドカードを含むXLFDなら、Emacsはそれらのワイルドカードに最初にマッチするフォントを選択する。この属性の指定により:family:foundry:width:height:weight:slantの属性値も変更される。

:inherit

属性を継承するフェイス名、またはフェイス名のリスト。継承フェイス由来の属性は基礎フェイスより高い優先度で、基礎フェイスの場合と同じような方法でマージされる(フェイスの表示を参照)。継承元のフェイスがunspecifiedならEmacsは:inherit属性を決してマージしないのでnilと同様に扱われる。フェイスのリストが使用された場合には、リスト内先頭側フェイスの属性が末尾側フェイスの属性をオーバーライドする。

:extend

そのフェイスが行末を超えて拡張されるか、および行末とウィンドウのエッジの間の空スペースの表示に影響を与えるかどうか。値は行末とウィンドウのエッジの間の空スペースの表示にそのフェイスを使用するならt、使用しなければnil。Emacsが行末を超える空スペースの表示でいくつかのフォントをマージする際に、:extendが非nilのフェイスだけがマージされる。デフォルトではこの属性がセットされているのは少数のフェイス、特にregionだけである。この属性はテーマがフェイスに明示的な値を指定しない際に、値がdeffaceによるフェイスの元定義から継承される点において他の属性とは異なる(フェイスの定義を参照)。

hl-line-modeのようないくつかのモードは、カレント行全体をマークするために:extendプロパティをもつフェイスを使用する。ただしEmacsはバッファー内の最後の文字の後へのポイントの移動を常に許容するので、バッファーが改行文字で終わる場合にはバッファーの最後にある行のような場所にポイントが配置されるかもしれないことに注意。この“行”は実際は存在しない行なのでEmacsがハイライトすることはできない。

Function: font-family-list &optional frame

この関数は利用可能なフォントファミリー名のリストをリターンする。オプション引数frameはそのテキストが表示されるフレームを指定する。これがnilなら選択されたフレームが使用される。

User Option: underline-minimum-offset

この変数はアンダーラインが引かれたテキスト表示時に、ベースラインとアンダーライン間の最小距離をピクセル単位で指定する。

User Option: x-bitmap-file-path

この変数は:stipple属性のビットマップファイルを検索するディレクトリーのリストを指定する。

Function: bitmap-spec-p object

これはobject:stipple (上記参照)での使用に適した有効なビットマップ仕様ならt、それ以外ならnilをリターンする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.2 フェイスの定義

フェイスを定義する通常の方法はdeffaceマクロを通じて定義する方法です。このマクロはフェイス名(シンボル)をデフォルトのフェイスspec(face spec)と関連付けます。フェイスspecとは任意の与えられた端末上でフェイスがどの属性をもつべきかを指定する構文です。たとえばあるフェイスspecは高カラー端末ではあるフォアグラウンドカラーし、低カラー端末では異なるフォアグラウンドカラーを指定するかもしれません。

値がフェイス名であるような変数を作りたがる人がいます。ほとんどの場合には、これは必要ありません。通常の手順はdeffaceでフェイスを定義して、その名前を直接使用することです。

(通常はdeffaceにより)一度フェイスを定義したら、Emacsを再起動する以外にそのフェイスを安全に未定義にすることはできません。

Macro: defface face spec doc [keyword value]…

このマクロはspecによりデフォルトフェイスspecが与えられるような名前つきフェイスとしてfaceを宣言する。シンボルfaceはクォートせずに‘-face’で終わらないこと(冗長かもしれない)。引数docはフェイスにたいするドキュメント文字列。追加のkeyword引数はdefgroupdefcustomの場合と同じ意味をもつ(一般的なキーワードアイテムを参照)。

faceがすでにデフォルトフェイスspecをもつ場合には、このマクロは何も行わない。

デフォルトフェイスspecは何もカスタマイゼーション(カスタマイゼーション設定を参照)の効果がないときのfaceの外観を決定する。faceが(Customテーマやinitファイルから読み込んだカスタマイズにより)すでにカスタマイズ済みなら、その外観はデフォルトフェイスspecのspecをオーバーライドするカスタムフェイスspecにより決定される。しかしその後カスタマイゼーションが削除されたら、faceの外観は再びそのデフォルトフェイスspecにより決定されるだろう。

例外としてC-M-x (eval-defun)、あるいはEmacs LispモードでC-x C-e (eval-last-sexp)によりdeffaceを評価した場合には、これらコマンドの特別な機能によりdeffaceの指示をフェイスが正確に反映するように、そのフェイス上の任意のカスタムフェイス仕様をオーバーライドする。

spec引数は異なる種別の端末上でそのフェイスがどのような外観で表示されるべきかを示すフェイスspec。これは各要素が以下の形式であるようなalistであること

(display . plist)

displayは端末のクラス(以下参照)を指定する。plistはそのような端末上でフェイスがどのような外観かを指定するフェイス属性とその値からなるプロパティリストであること。後方互換性のために(display plist)のように要素を記述することもできる。

specの要素のdisplayの部分は、その要素がマッチする端末を決定する。与えられた端末にたいして複数の要素がマッチした場合には、最初にマッチした要素がその端末にたいして使用される。displayには以下の3つが可能:

default

specのこの要素はどの端末にもマッチしない。かわりにすべての端末に適用されるデフォルトを指定する。この要素が使用する場合には、specの最初の要素でなければならない。この後の要素はこれらのデフォルトの一部、またはすべてをオーバーライドできる。

t

specのこの要素はすべての端末にマッチする。したがってspecの後続要素が使用されることはない。tは通常はspecの最後(か唯一)の要素として使用される。

リスト

displayがリストなら各要素は(characteristic value…)という形式をもつこと。ここでcharacteristicは端末をクラス分けする方法、valuedisplayに適用されるべき可能なクラス分類。characteristicに利用可能な値は:

type

その端末が使用するウィンドウシステムの種類でgraphic (任意のグラフィック対応ディスプレイ)、xpc (MS-DOSコンソール)、w32 (MS Windows 9X/NT/2K/XP)、haiku (Haiku)、pgtk (pure GTK)、またはtty (グラフィック非対応ディスプレイ)のいずれか。window-systemを参照のこと。

class

その端末がサポートするカラーの種類でありcolorgrayscalemonoのいずれか。

background

バックグラウンドの種類でありlightdarkのいずれか。

min-colors

その端末がサポートするべき最小カラー数を表す整数。端末のdisplay-color-cellsの値が少なくとも指定された整数ならその端末にマッチ。

supports

その端末がvalue…で与えられたフェイス属性を表示可能か否か(フェイスの属性を参照)。このテストがどのように行われるかについてのより正確な情報はDisplay Face Attribute Testingを参照のこと。

与えられたcharacteristicにたいしてdisplayの要素が複数のvalueを指定する場合には、いずれの値も許容され得る。displayが複数の要素をもつ場合には、各要素は異なるcharacteristicを指定すること。その端末のそれぞれのcharacteristicはdisplay内で指定された値のいずれか1つとマッチしなければならない。

たとえば以下は標準フェイスhighlightの定義です:

(defface highlight
  '((((class color) (min-colors 88) (background light))
     :background "darkseagreen2")
    (((class color) (min-colors 88) (background dark))
     :background "darkolivegreen")
    (((class color) (min-colors 16) (background light))
     :background "darkseagreen2")
    (((class color) (min-colors 16) (background dark))
     :background "darkolivegreen")
    (((class color) (min-colors 8))
     :background "green" :foreground "black")
    (t :inverse-video t))
  "Basic face for highlighting."
  :group 'basic-faces)

内部的にはEmacsはフェイスのシンボルプロパティface-defface-spec内にそれぞれのフェイスのデフォルトspecを格納します(シンボルのプロパティを参照)。saved-faceプロパティはカスタマイゼーションバッファーを使用してユーザーが保存した任意のフェイスspecを格納します。customized-faceプロパティはカレントセッションにたいしてカスタマイズされた保存されていないフェイスspecを格納します。そしてtheme-faceプロパティはそのフェイスにたいするアクティブなカスタマイゼーションセッティングと、フェイスspecをもつCustomテーマを関連付けるalistです。そのフェイスのドキュメント文字列はface-documentationプロパティ内に格納されます。

フェイスは通常はdeffaceを使用して1回だけ宣言されて、その外観にたいするそれ以上の変更はCustomizeフレームワーク(Customizeユーザーインターフェースかcustom-set-faces関数を通じて。カスタマイゼーションの適用を参照)、またはフェイスリマッピング(フェイスのリマップを参照)により行われます。Lispから直接フェイスspec変更を要する稀な状況ではface-spec-set関数を使用できます。

Function: face-spec-set face spec &optional spec-type

この関数はfaceにたいするフェイスspecとしてspecを適用する。specは上述したdeffaceにたいするフェイスspecであること。

この関数はもしfaceが既存のものでなければ有効なフェイス名としてfaceを定義して、既存フレームのその属性の(再)計算も行う。

オプション引数spec-typeはどのspecをセットするかを決定する。これが省略かnil、またはface-override-specなら、この関数はオーバーライドspec(override spec)をセットする。これは後述するface上の他のすべてのフェイスspecをオーバーライドする。これはCustomのコード外部からこの関数を呼び出す際に有用。spec-typecustomized-facesaved-faceなら、この関数はカスタマイズされたspec、または保存されたカスタムspecをセットする。face-defface-specなら、この関数はデフォルトフェイスspec(deffaceによりセットされるものと同一)をセットする。resetなら、この関数はfaceからすべてのカスタマイゼーションspecとオーバーライドspecをクリアーする(この場合にはspecの値は無視される)。spec-typeの他の任意の値がフェイスspecに及ぼす効果は内部的な使用のために予約済みだが、それでも後述するようにこの関数はface自体の定義を行い属性を再計算する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.3 フェイス属性のための関数

このセクションでは名前つきフェイスの属性に直接アクセスしたり変更する関数を説明します。

Function: face-attribute face attribute &optional frame inherit

この関数はframe上のfaceにたいする属性attributeの値をリターンする。サポートされている属性についてはフェイスの属性See フェイスの属性を参照のこと。

frameが省略かnilなら選択されたフレームを意味する(入力のフォーカスを参照)。frametなら、この関数は新たに作成されるフレームにたいして指定された属性の値、すなわちフェイスのdefface定義(フェイスの定義を参照)の中のフェイスspecを適用する前、またはface-spec-setでセットしたspecの属性の値。。このattributeのデフォルト値は下記のset-face-attributeを使用して何らかの値を指定していなければ通常はunspecified

inheritnilならfaceにより定義される属性だけが考慮されるのでリターンされる値はunspecified、または相対的な値かもしれない。inheritが非nilならfaceattributeの定義が、:inherit属性で指定されたフェイスとマージされる。しかしリターンされる値は依然としてunspecified、または相対的な値かもしれない。inheritがフェイスかフェイスのリストなら、指定された絶対的な値になるまで結果はそのフェイス(1つ以上)と更にマージされる。

リターン値が指定されていて、かつ絶対的であることを保証するためにはinheritにたいしてdefaultの値を使用すること。(常に完全に指定される)defaultフェイスとマージすることにより、すべての未指定や相対的な値は解決されるだろう。

たとえば

(face-attribute 'bold :weight)
     ⇒ bold
Function: face-attribute-relative-p attribute value

この関数はvalueがフェイス属性attributeの値として使用された際に相対的なら非nilをリターンする。これはフェイスリスト内の後続のフェイス、または継承した他のフェイスが由来となる任意の値で完全にオーバーライドするのではなく、それが変更されるであろうことを意味する。

すべての属性にたいしてunspecifiedは相対的な値。:heightにたいしては浮動小数点数と関数値も相対的である。

たとえば:

(face-attribute-relative-p :height 2.0)
     ⇒ t
Function: face-all-attributes face &optional frame

この関数はfaceの属性のalistをリターンする。結果の要素は(attr-name . attr-value)という形式の名前/値ペアー。オプション引数frameはリターンするべきfaceの定義をもつフレームを指定する。省略かnilならリターン値には新たに作成されるフレームにたいするfaceのデフォルト属性、すなわちフェイスのdefface定義の中のフェイスspecを適用する前、またはface-spec-setでセットしたspecの属性の値が記述される。。このattributeのデフォルト値は下記のset-face-attributeを使用して何らかの値を指定していなければ通常はunspecified

Function: merge-face-attribute attribute value1 value2

value1がフェイス属性attributeにたいして相対的な値なら、基礎的な値value2とマージしてリターンする。それ以外の場合にはvalue1がフェイス属性attributeにたいして絶対的な値ならvalue1を変更せずにリターンする。

Emacsは通常は各フレームのフェイス属性を自動的に計算するために、各フェイスのフェイスspecを使用します(フェイスの定義を参照)。関数set-face-attributeは特定またはすべてのフレームのフェイスに直接属性を割り当てることにより、この計算をオーバーライドできます。この関数は主として内部的な使用を意図したものです。

Function: set-face-attribute face frame &rest arguments

この関数はframeにたいするfaceの1つ以上の属性をセットする。この方法で指定された属性はfaceに属するフェイスspec(1つ以上)をオーバーライドする。サポートされている属性についてはフェイスの属性を参照のこと。

余分の引数argumentsはセットするべき属性と値を指定する。これらは(:family:underlineのような)属性名と値が交互になるように構成されていること。つまり、

(set-face-attribute 'foo nil :weight 'bold :slant 'italic)

これは属性:weightbold、属性:slantitalicにセットする。

frametなら、この関数は新たに作成するフレームにデフォルトの属性をセットする。これらはdeffaceによって指定された属性値を効果的にオーバーライドする。framenilの場合には、この関数は既存のフレームすべてにたいして、新たに作成するフレームと同じように属性をセットする。

属性の値をリセットする、つまりそのフェイスが属性の値を独自に指定しないことを示すにはframenilをセットしてこの関数を呼び出すことに加えて、更に属性にたいして特別な値であるunspecified (nilではない!)、frame引数にtをセットしてこの関数を呼び出す必要がある。これは新たにフレームが作成される際のデフォルト属性はdefface内のフェイスspecとマージされるためであり、新たに作成されたフレームのデフォルト属性にunspecifiedをもつことによってdeffaceをオーバーライドできなくなる。この関数にたいして上述した特別な呼び出しを行うことによって、deffaceがオーバーライドされるように調整を行う。

属性と値のペアーは最初に評価される:familyおよび:foundryの属性以外は指定された順に評価されることに注意。これはもし特定の属性を2回以上指定すると、最後に指定した値が使用されること、更にある場合においては異なる属性順によって異なる結果が生成されるかもしれないことをも意味している。たとえば:weightの前に:fontがあると指定したフォントにウェイトの値が適用されるが、:fontの前に:weightがある場合にはそのフェイスのカレントフォントにウェイトの値が適用されて、もしかしたらそのフォントで利用できるもっとも近いウェイトに丸められるかもしれない。

以下のコマンドと関数は主として古いバージョンのEmacsにたいする互換性のために提供されます。これらはset-face-attributeを呼び出すことにより機能します。これらのframe引数にたいする値tnil (や省略)はset-face-attributeface-attributeの場合と同様に処理されます。コマンドがインタラクティブに呼び出されるとミニバッファーを使用して引数を読み取ります。

Command: set-face-foreground face color &optional frame
Command: set-face-background face color &optional frame

これらはそれぞれface:foreground属性、または:background属性にcolorをセットする。

Command: set-face-stipple face pattern &optional frame

これはface:stipple属性にpatternをセットする。

Command: set-face-font face font &optional frame

faceのフォント関連の属性をfont (文字列かフォントオブジェクト)の属性に変更する。font引数でアポートされるフォーマットについてはface-font-attributeを参照のこと。この関数はフェイスの:font属性、および間接的に:family:foundry:width:height:weight:slantの属性もそのフォントで定義された値にセットする。frameが非nilなら、指定したフレームの属性だけを変更する。

Function: set-face-bold face bold-p &optional frame

これはface:weight属性にたいしてbold-pnilならnormal、それ以外ならboldをセットする。

Function: set-face-italic face italic-p &optional frame

これはface:slant属性にたいしてitalic-pnilならnormal、それ以外ならitalicをセットする。

Command: set-face-underline face underline &optional frame

これはface:underline属性にunderlineをセットする。

Command: set-face-inverse-video face inverse-video-p &optional frame

これはface:inverse-video属性にinverse-video-pをセットする。

Command: invert-face face &optional frame

これはフェイスfaceのフォアグラウンドカラーとバックグラウンドカラーを交換する。

Command: set-face-extend face extend &optional frame

これはface:extend属性にextendをセットする。

以下はフェイスの属性を調べる関数です。これらは主として古いバージョンのEmacsとの互換性のために提供されます。これらにたいしてframeを指定しなければ選択されたフレーム、tなら新たなフレームにたいするデフォルトデータを参照します。フェイスがその属性にたいして何の値も定義していなければunspecifiedがリターンされます。inheritnilならそのフェイスにより直接定義された属性だけがリターンされます。inheritが非nilならそのフェイスの:inherit属性により指定される任意のフェイス、inheritがフェイスまたはフェイスのリストなら指定された属性が見つかるまでそれらも考慮します。リターンされる値が常に指定された値であることを保証するためにはinheritに値defaultを使用してください。

Function: face-font face &optional frame character

この関数は指定されたfaceが使用するフォント名をリターンする。

オプション引数frameが指定されたら、そのフレームのfaceのフォント名をリターンする。frameが省略かnilならデフォルトは選択されたフレーム。frametなら、この関数は新たに作成されたフレームがfaceにたいして使用するデフォルトフォントについて報告する。

デフォルトではASCII文字表示用のフォントをリターンするが、framet以外で3つ目のオプション引数characterが与えられた場合には、その文字にたいしてfaceが使用するフォント名をリターンする。

Function: face-foreground face &optional frame inherit
Function: face-background face &optional frame inherit

これらの関数はそれぞれフェイスfaceのフォアグラウンドカラーまたはバックグラウンドカラーを文字列としてリターンする。カラーが未指定ならをリターンする。

Function: face-stipple face &optional frame inherit

この関数はフェイスfaceのバックグラウンド点描パターンの名前、もしなければnilをリターンする。

Function: face-bold-p face &optional frame inherit

この関数はface:weight属性がnormalよりbold寄り(semi-boldboldextra-boldultra-boldのいずれか)なら非nil、それ以外ならnilをリターンする。

Function: face-italic-p face &optional frame inherit

この関数はface:slant属性がitalicobliqueなら非nil、それ以外ならnilをリターンする。

Function: face-underline-p face &optional frame inherit

この関数はフェイスfaceが非nil:underline属性を指定すれば非nilをリターンする。

Function: face-inverse-video-p face &optional frame inherit

この関数はフェイスfaceが非nil:inverse-video属性を指定すれば非nilをリターンする。

Function: face-extend-p face &optional frame inherit

この関数はフェイスfaceが非nil:extend属性を指定すれば非nilをリターンする。inherit引数はface-attributeに渡される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.4 フェイスの表示

Emacsが与えられたテキスト断片を表示する際には、そのテキストの視覚的外観は異なるソースから描画されるフェイスにより決定されるかもしれません。これら種々のソースが特定の文字にいたいして複数のフェイスを指定する場合には、Emacsはそれらのさまざまなフェイスの属性をマージします。以下にEmacsがフェイスをマージする順序を優先度順に記します:

  • そのテキストが特別なグリフで構成される場合には、そのグリフは特定のフェイスを指定できる。グリフを参照のこと。
  • アクティブなリージョンにテキストがある場合には、Emacsはregionフェイスを使用してそれをハイライトする。Standard Faces in The GNU Emacs Manualを参照のこと。
  • nilface属性をもつオーバーレイにテキストがある場合には、Emacsはそのプロパティにより指定されるフェイス(1つ以上)を適用する。そのオーバーレイがmouse-faceプロパティをもち、マウスがそのオーバーレイに十分に近ければEmacsはかわりにmouse-faceで指定されるフェイスかフェイス属性を適用する。オーバーレイのプロパティを参照のこと。

    同一の文字を複数のオーバーレイがカバーする場合には、高優先度のオーバーレイが低優先度のオーバーレイをオーバーライドする。オーバーレイを参照のこと。

  • そのテキストがfacemouse-faceプロパティを含む場合には、Emacsは指定されたフェイスやフェイス属性を適用する。特殊な意味をもつプロパティを参照のこと(これはFont Lockモードのフェイス適用方法。Font Lockモードを参照)。
  • そのテキストが選択されたウィンドウのモードラインにある場合には、Emacsはmode-lineフェイスを適用する。選択されていないウィンドウのモードラインではEmacsはmode-line-inactiveフェイスを使用する。ヘッダーラインにたいしてはEmacsはheader-lineフェイスを適用する。タブラインにたいしては、Emacsはtab-lineフェイスを適用する。
  • before-stringafter-stringプロパティを介したオーバーレイ文字列(オーバーレイのプロパティを参照)、あるいはディスプレイ文字列(その他のディスプレイ仕様を参照)に由来するテキストであり、かつ文字列にfacemouse-faceのプロパティが含まれない、またはそれらのプロパィが何らかのフェイス属性を未定義のままにしているが、バッファーのテキストがフェイスを定義するディスプレイプロパティやオーバーレイプロパティの影響を受ける場合には、Emacsは“基礎”にあるバッファーテキストのフェイスやフェイス属性を適用する。これはたとえオーバーレイ文字列やディスプレイ文字列がマージン内に表示されている場合も同様であることに注意(マージン内への表示を参照)。
  • 先行ステップの間に与えられた属性が指定されなければ、Emacsはdefaultフェイスの属性を適用する。

各ステージにおいてフェイスが有効な:inherit属性をもつ場合には、Emacsは値unspecifiedをもつすべての属性が、親フェイス(1つ以上)由来で描画に使用される対応する値をもつものとして扱います。フェイスの属性を参照してください。親フェイスでも属性がunspecifiedのままかもしれないことに注意してください。その場合にはフェイスマージの次レベルでもその属性はunspecifiedのままです。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.5 フェイスのリマップ

変数face-remapping-alistはあるフェイスの外観のバッファーローカル、またはグローバルな変更にたいして使用されます。たとえばこれはtext-scale-adjustコマンド(Text Scale in The GNU Emacs Manualを参照)の実装に使用されています。

Variable: face-remapping-alist

この変数の値は要素が(face . remapping)という形式をもつalist。これによりEmacsはフェイスfaceをもつ任意のテキストを、通常のfaceの定義ではなくremappingで表示する。

remappingにはテキストプロパティfaceにたいして適切な任意のフェイスspec、すなわちフェイス(フェイス名か属性/値ペアーのプロパティリスト)、またはフェイスのリストのいずれかを指定できる。詳細は特殊な意味をもつプロパティfaceテキストプロパティの記述を参照のこと。remappingはリマップされるフェイスにたいる完全な仕様としての役目をもつ。これは通常のfaceを変更せずに置き換える。

face-remapping-alistがバッファーローカルなら、そのローカル値はそのバッファーだけに効果をもつ。(:filtered (:window param valspec)を使用することにより特定のウィンドウだけに適用されるフェイスを含んだface-remapping-alistでは、そのフェイスはそのフィルター条件にマッチするだけに効果を及ぼす(特殊な意味をもつプロパティを参照)。フェイスのフィルタリングを一時的にオフにするには、face-filters-always-matchを非nil値にバインドすれば、すべてのフェイスフィルターは任意のウィンドウにマッチする。

注意: フェイスのリマッピングは再帰的ではない。remappingが同じフェイス名faceを参照する場合には、直接またはremapping内の他の何らかのフェイスの:inherit属性を通じて、その参照はfaceの通常の定義を使用する。たとえばmode-lineフェイスがface-remapping-alist内の以下のエントリーでリマップされるなら:

(mode-line italic mode-line)

mode-lineフェイスの新たな定義はitalicフェイス、および(リマップされていない)通常mode-lineフェイスの定義から継承される。

以下の関数はface-remapping-alistにたいする高レベルなインターフェースを実装します。ほとんどのLispコードはリマッピングが他の場所に適用されてしまうのを避けるために、face-remapping-alistを直接セットするのではなくこれらの関数を使用するべきです。これらの関数はバッファーローカルなリマッピングを意図しており、すべてが副作用としてface-remapping-alistをバッファーローカルにします。これらは以下の形式のface-remapping-alistエントリーを管理します

  (face relative-spec-1 relative-spec-2 ... base-spec)

上述したようにrelative-spec-Nbase-specはそれぞれフェイス名か属性/値ペアーのプロパティリストです。相対的リマッピング(relative remapping)エントリーrelative-spec-Nはそれぞれ関数face-remap-add-relativeface-remap-remove-relativeにより管理されます。これらはテキストサイズ変更のような単純な変更を意図しています。ベースリマッピング(base remapping)エントリーbase-specは最低の優先度をもち、関数face-remap-set-baseface-remap-reset-baseにより管理されます。これはメジャーモードが制御下のバッファーでフェイスをリマップするために用いることを意図しています。

Function: face-remap-add-relative face &rest specs

この関数はカレントバッファー内のフェイスfaceにたいして、相対的リマッピングとしてspecsを追加する。specsはフェイス名、または属性/値ペアーのプロパティリストのリストであること。

リターン値はcookieとしての役目をもつLispオブジェクト。後でそのリマッピングの削除を要する場合には、引数としてface-remap-remove-relativeにこのオブジェクトを渡すことができる。

;; 'escape-glyph'フェイスを'highlight'と'italic'
;; を組み合わせたフェイスにリマップする
(face-remap-add-relative 'escape-glyph 'highlight 'italic)

;; 'default'フェイスのサイズを50%増加:
(face-remap-add-relative 'default :height 1.5)

バッファーローカルなフェイスのリマップは、基本フェイス(基本的なフェイスを参照)の親フェイスでは動作が不確実であることに注意(これらはモードライン、ヘッダーライン、およびウィンドウやフレームのその他基本的な装飾に用いられるフェイスである)。たとえばmode-line-inactivemode-lineから派生したフェイスだが、mode-lineをリマップしても通常ならmode-line-inactiveには期待した効果は得られないだろう(特にリマップが一部バッファーにたいしてローカルに行われた場合)。かわりにmode-line-inactiveを直接リマップする必要がある。

Function: face-remap-remove-relative cookie

この関数は以前face-remap-add-relativeで追加された相対的リマッピングを削除する。cookieはリマッピングが追加されたときにface-remap-add-relativeがリターンしたLispオブジェクトであること。

Function: face-remap-set-base face &rest specs

この関数はカレントバッファー内のfaceのベースリマッピングをspecsにセットする。specsが空ならface-remap-reset-base(以下参照)を呼び出したようにデフォルトベースリマッピングがリストアされる。これは単一の値nilを含むspecsとは異なることに注意。これは逆の結果をもたらす(faceのグローバル定義は無視される)。

これはグローバルなフェイス定義を継承したデフォルトのbase-specを上書きするので、必要ならそのような継承を追加するのは呼び出し側の責任である。

Function: face-remap-reset-base face

この関数はfaceのベースリマッピングに、faceのグローバル定義から継承したデフォルト値にセットする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.6 フェイスを処理するための関数

以下はフェイスの作成や処理を行う追加の関数です。

Function: face-list

この関数はすべての定義済みフェイス名のリストをリターンする。

Function: face-id face

この関数はフェイスfaceフェイス番号(face number)をリターンする。これはEmacs内部の低レベルでフィエスを一意に識別する番号。フェイス番号によるフェイスの参照を要するのは稀である。しかしmake-glyph-codeglyph-face (グリフを参照)のようなグリフを操作する関数は内部的にフェイス番号にアクセスする。フェイス番号はフェイスシンボルのfaceプロパティの値として格納されることに注意。このフェイスプロパティにあなた自身が値をセットしないことを推奨する。

Function: face-documentation face

この関数はフェイスfaceのドキュメント文字列、指定されていなければnilをリターンする。

Function: face-equal face1 face2 &optional frame

これはフェイスface1とフェイスface2が表示にたいして同じ属性をもつならtをリターンする。

Function: face-differs-from-default-p face &optional frame

これはフェイスfaceの表示がデフォルトフェイスと異なるなら非nilをリターンする。

フェイスエイリアス(face alias)はあるフェイスにたいして等価な名前を提供します。エイリアスシンボルのface-aliasプロパティに対象となるフェイス名を与えることによってフェイスエイリアスを定義できます。以下の例ではmode-lineフェイスにたいするエイリアスとしてmodelineを作成します。

(put 'modeline 'face-alias 'mode-line)
Macro: define-obsolete-face-alias obsolete-face current-face when

このマクロはcurrent-faceのエイリアスとしてobsolete-faceを定義するとともに、将来に削除されるかもしれないことを示すためにobsolete(時代遅れ)とマークする。whenobsolete-faceがobsoleteになる時期を示す文字列であること(通常はバージョン番号文字列)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.7 フェイスの自動割り当て

以下のフックはバッファー内のテキストに自動的にフェイスを割り当てるために使用されます。これはJit-Lockモードの実装の一部でありFont-Lockにより使用されます。

Variable: fontification-functions

この変数は再表示を行う直前にEmacsの再表示により呼び出される関数のリストを保持する。これらはFont Lockが有効でないときでも呼び出される。Font Lockモードが有効なら、この変数は通常は単一の関数jit-lock-functionだけを保持する。

関数はバッファー位置posを単一の引数としてリストされた順に呼び出される。これらはカレントバッファー内のposで開始されるテキストにたいして集合的にフェイスの割り当てを試みること。

関数はfaceプロパティをセットすることにより割り当てるフェイスを記録すること。またフェイスを割り当てたすべてのテキストに非nilfontifiedプロパティも追加すること。このプロパティは再表示にたいして、そのテキストにたいしてそのフェイスがすでに割り当て済みであることを告げる。

posの後の文字がすでに非nilfontifiedプロパティをもつがフォント表示化を要さない場合には、何も行わない関数を追加するのがおそらくよいアイデアである。ある関数が前の関数による割り当てをオーバーライドする場合には、実際に問題となるのは最後の関数終了後のプロパティである。

効率化のために通常は各呼び出しにおいて400から600前後の文字にフェイスを割り当てるように、これらの関数を記述することを推奨する。

非常に長い行がバッファーに含まれていると、これらの関数はあたかもposの周辺部分にナローイングされてlong-line-optimizations-in-fontification-functionsのラベルが付されたバッファーにおいて(ナローイングを参照)、with-restrictionフォームの内部であるかのように呼び出されることに注意。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.8 基本的なフェイス

テキストにたいしてEmacs Lispプログラムが何らかのフェイス割り当てを要する場合には、完全に新たなフェイスを定義するより特定の既存フェイス、またはそれらを継承したフェイスを使用するほうがよいアイデアである場合がしばしばあります。Emacsに特定の外観を与えるために別のユーザーが既存フェイスをカスタマイズしていても、この方法なら追加のカスタマイズなしでプログラムは適合することでしょう。

以下にEmacsが定義する基本フェイス(basic face)のいくつかをリストしました。これらに加えて、ハイライトがFont Lockモードによりまだ処理されていなかったり、いくつかのFont Lockフェイスが使用されていなければ、構文的ハイライトのためにFont Lockフェイスを使うようにしたいと思うかもしれません。Font Lockのためのフェイスを参照してください。

default

属性がすべて指定されたデフォルトフェイス。他のすべてのフェイスは暗にこのフェイスを継承する。未指定(unspecified)な任意の属性は、このフェイスの属性をデフォルトとする(フェイスの属性を参照)。

mode-line-active
mode-line-inactive
header-line
tab-line

モードライン、ヘッダーライン、タブラインに使用される基本フェイス。

tool-bar
tab-bar
fringe
scroll-bar
window-divider
border
child-frame-border

GUIフレームのそれぞれ対応する装飾に使用される基本フェイス。

cursor

テキストカーソルに使用される基本フェイス。

mouse

テキスト上にマウスポインターがある際にマウスセンシティブなテキストの表示に使用される基本フェイス。

bold
italic
bold-italic
underline
fixed-pitch
fixed-pitch-serif
variable-pitch

これらは名前に示されるような属性をもち(boldはboldの:weight属性をもつ)、それ以外のすべての属性は未指定(そのためにdefaultにより与えられる)。

shadow

テキストの淡色表示(dimmed out)用。たとえばこれはミニバッファー内で無視されるファイル名部分に使用される(Minibuffers for File Names in The GNU Emacs Manualを参照)。

link
link-visited

ユーザーを別のバッファーや位置へと送るクリック可能テキストボタン用。

highlight

一時的に強調するべきテキスト範囲用。たとえば一般的にカーソルのハイライトにはmouse-faceプロパティが割り当てられる(特殊な意味をもつプロパティを参照)。

match
isearch
lazy-highlight

それぞれ定型検索(permanent search)のマッチ、インタラクティブ検索のマッチ、カレントのインタラクティブな検索のマッチ以外のlazyハイライトにたいするテキスト用。

error
warning
success

エラー、警告、成功に関するテキスト用。たとえば*Compilation*内のメッセージにたいして使用される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.9 フォントの選択

Emacsがグラフィカルなディスプレイ上で文字を描画可能になる前に、まずその文字にたいするフォント(font)を選択しなければなりません30Fonts in The GNU Emacs Manualを参照してください。Emacsは通常はその文字に割り当てられたフェイス、特にフェイス属性:family:weight:slant:width(フェイスの属性を参照)にもとづいて自動的にフォントを選択します。フォントの選択は表示される文字にも依存します。表示できるのは文字セットが限定されているフォントもいくつかあります。利用可能なフォントがこの要件を完全に満たさなければEmacsはもっとも近いフォント(closest matching font)を探します。このセクション内の変数はEmacsがこの選択を行う方法を制御します。

User Option: face-font-family-alternatives

あるfamilyが指定されたが存在しなければ、この変数は試みるべき代替えのフォントファミリーを指定する。各要素は以下の形式をもつ:

(family alternate-families…)

familyが指定されたが利用できなければ、Emacsはalternate-familiesで与えられるファミリーで存在するものが見つかるまで1つずつファミリーを試みる。

User Option: face-font-selection-order

希望するすべてのフェイス属性(:width:height:weight:slant)に完全にマッチするフォントが存在しなければ、この変数はもっとも近いフォントの選択時に考慮すべきこれらの属性の順序を指定する。値はこれらの属性シンボルを重要度降順で含むリストであること。デフォルトは(:width :height :weight :slant)

フォント選択はまずこのリスト内の最初の属性にたいして利用可能な最適マッチを探す。その後に、この方法で最適なフォントの中から2つ目の属性にたいして最適なマッチを検索、...のように選択を行う。

属性:weight:widthnormalを中心とする範囲のようなシンボリック値をもつ。より極端(normalから離れた)なマッチは、より極端ではない(normalに近い)マッチより幾分優先される。これは可能なかぎり非normalなフェイスが、normalなフェイスとは対照的になることを保証するようにデザインされている。

この変数が違いを生むケースの例はデフォルトフォントに等価なイタリックがない場合である。デフォルトの順ではitalicフェイスはデフォルトのフォントに類似した非イタリックのフォントを使用するだろう。しかし:heightの前に:slantを配置すると、italicフェイスはたとえheightが同じでなくともイタリックフォントを使用するだろう。

User Option: face-font-registry-alternatives

この変数はregistryが指定されたがそれが存在しない場合に試みるべき代替えのフォントレジストリーを指定する。各要素は以下の形式をもつ:

(registry alternate-registries…)

registryが指定されたが利用できなければ、Emacsはalternate-registries内で存在するレジストリーが見つかるまで他のレジストリーを1つずつ試みる。

Emacsがスケーラブルフォントを使用するようにできますがデフォルトではそれらを使用しないようになっています。

User Option: scalable-fonts-allowed

この変数はどのスケーラブルフォントを使用するかを制御する。値nil (デフォルト)はスケーラブルフォントを使用しないことを意味する。tはそのテキストにたいして適切と思われる任意のスケーラブルフォントを使用することを意味する。

それ以外なら値は正規表現のリストであること。その場合には名前がこのリスト内の正規表現にマッチする任意のスケーラブルフォントの使用が有効になる。たとえば、

(setq scalable-fonts-allowed '("iso10646-1$"))

これはレジストリーがiso10646-1のようなスケーラブルフォントの使用を可能にする。

Variable: face-font-rescale-alist

この変数は特定のフォントにたいするスケーリングを指定する。値は以下の形式の要素をもつリストであること

(fontname-regexp . scale-factor)

使用しようとするフォントの名前がfontname-regexpにマッチする場合には、これはファクターscale-factorに対応した同様な大きさのフォントの選択を指示する。特定のフォントが提示する通常のheightやwidthが大きい、または小さい場合にフォントサイズを正規化するためにこの機能を使用できるだろう。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.10 フォントの照会

Function: x-list-fonts name &optional reference-face frame maximum width

この関数はnameにマッチする利用可能なフォント名のリストをリターンする。nameはFontconfig、GTK+、またはXLFDのいずれかのフォーマットによるフォント名を含む文字列であること(Fonts in The GNU Emacs Manualを参照)。XLFD文字列ではワイルドカード文字が使用できる。‘*’文字は任意の部分文字列、‘?’は任意の単一文字にマッチする。フォント名のマッチングではcase(大文字小文字)の違いは無視される。

オプション引数reference-faceframeが指定された場合には、リターンされるリストにはその時点でフレームframe上でのreference-face (フェイス名)と同じサイズのフォントだけが含まれる。

オプション引数maximumはリターンされるフォント数の制限をセットする。これが非nilならリターン値は最初にマッチしたmaximum個のフォントの後が切り捨てられる。maximumに小さい値を指定すれば、そのパターンに多くのフォントがマッチするような場合に関数をより高速にできる。

オプション引数widthは希望するフォントの幅を指定する。これが非nilなら、この関数は文字の幅(平均)がreference-facewidth倍の幅であるようなフォントだけをリターンする。

Function: x-family-fonts &optional family frame

この関数はframe上のファミリーfamilyにたいして利用可能なフォントを記述するリストをリターンする。familyが省略かnilならこのリストはすべてのファミリーに適用されて、それはすなわち利用可能なすべてのフォントを含む。それ以外ならfamilyは文字列であること。これにはワイルドカード‘?’と‘*’を含めることができる。

このリストはframeのあるディスプレイを記述する。frameが省略かnilなら、これは選択されたフレームのディスプレイに適用される(入力のフォーカスを参照)。

このリスト内の各要素は以下の形式のベクターであること:

[family width point-size weight slant
 fixed-p full registry-and-encoding]

最初の5つの要素はフェイス属性に対応する。あるフェイスにたいしてこれらの属性を指定した場合には、そのフォントが使用されるだろう。

最後の3つの要素は、そのフォントに関する追加の情報を与える。そのフォントが固定ピッチ(fixed-pitch)でなければfixed-pは非nilfullはそのフォントのフルネーム、registry-and-encodingはそのフォントのレジストリーとエンコーディングを与える。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.11 フォントセット

フォントセット(fontset)とは、それぞれが文字コードの範囲に割り当てられるフォントのリストのことです。個々のフォントではEmacsがサポートする文字の全範囲を表示できませんが、フォントセットであれば表示することができます。フォントのようにフォントセットは名前をもつことができ、フレームやフェイスにたいしてフォントを指定する際に、フォント名としてフォントセット名を使用できます。以下はLispプログラム制御下でのフォントセット定義に関する情報です。

Function: create-fontset-from-fontset-spec fontset-spec &optional style-variant-p noerror

この関数は仕様文字列fontset-specに応じて新たなフォントセットを定義する。この文字列は以下のような形式であること:

fontpattern, [charset:font]…

カンマの前後の空白文字は無視される。

この文字列の最初の部分fontpatternは、最後の2つのフィールドが‘fontset-alias’であることを除外して標準Xフォント名形式をもつこと。

新たなフォントセットはlong名とshort名という2つの名前をもつ。long名はそれ全体がfontpattern、short名は‘fontset-alias’。いずれの名前でもこのフォントセットを参照できる。同じ名前がすでに存在するフォントセットではnoerrornilならエラーがシグナルされ、noerrorが非nilならこの関数は何も行わない。

オプション引数style-variant-pが非nilなら、そのフォントセットのbold、italic、およびbold-italicも同様に作成するよう指示する。これらの変種フォントセットはshort名をもたずbold、および/またはitalicを示すようにfontpatternを変更して作成したlong名だけをもつ。

仕様文字列はそのフォントセット内でどのフォントを使用するかも宣言する。詳細は以下を参照。

構文‘charset:font’はある特定の文字セットにたいして、(このフォントセット内の)どのフォントを使用するかを指定します。ここでcharsetは文字セットの名前、fontはその文字セットにたいして使用するフォントです。仕様文字列内ではこの構文を任意の回数使用できます。

明示的に指定しなかった残りの文字セットにたいして、Emacsはfontpatternにもとづいてフォントを選択します。これは‘fontset-alias’をその文字セットを命名する値に置き換えます。文字セットASCIIにたいしては、‘fontset-alias’は‘ISO8859-1’に置き換えられます。

加えて後続の複数フィールドがワイルドカードなら、Emacsはそれらを1つのワイルドカードにまとめます。これは自動スケールフォント(auto-scaled fonts)の使用を防ぐためです。フォントを大きくスケーリングすることにより作成されたフォントは編集に使用できず、小さくスケーリングされたフォントは、それ自身のサイズがより小さいフォントを使用する(Emacsが行う方法)ほうがよいので有用ではありません。

つまり以下のようなfontpatternなら

-*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24

ASCIIにたいするフォントspecは以下のようになるでしょう:

-*-fixed-medium-r-normal-*-24-*-ISO8859-1

またChinese GB2312文字にたいするフォントspecは以下のようになるでしょう:

-*-fixed-medium-r-normal-*-24-*-gb2312*-*

上記のフォントspecにマッチするChineseフォントをもっていないかもしれません。ほとんどのXディストリビューションには、familyフィールドに‘song ti’か‘fangsong ti’をもつChineseフォントだけが含まれます。そのような場合には以下のように‘Fontset-n’を指定できます:

Emacs.Fontset-0: -*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24,\
        chinese-gb2312:-*-*-medium-r-normal-*-24-*-gb2312*-*

この場合にはChinese GB2312以外のすべての文にたいするフォントspecはfamilyフィールドに‘fixed’をもち、Chinese GB2312にたいするフォントspecはfamilyフィールドにワイルドカード‘*’をもちます。

Function: set-fontset-font fontset characters font-spec &optional frame add

この関数は指定されたcharactersにたいして、font-specのフォントマッチングを使用するように既存のフォントセットfontsetを変更する。

fontsetnilならこの関数はframeのフォントセット、framenilなら選択されたフレームのフォントセットを変更する。

fontsettならこの関数はshort名が‘fontset-default’であるようなデフォルトフォントセットを変更する。

characters引数はfont-specを使って表示すべき単一の文字を指定する。fromtoが文字であるようなコンスセル(from . to)でもよい。この場合には範囲fromからto (両端を含む)までのすべての文字にたいしてfont-specを使用する。

charactersには文字セット(文字セットを参照)も指定できる。この場合には、その文字セット内のすべての文字にたいしてfont-specを使用する。

charactersにはスクリプト名(char-script-tableを参照)も指定できる。この場合にはスクリプトに属するすべての文字にたいしてfont-specを使用する。

charactersにはnilも指定できる。この場合にはフォント仕様が指定されていないすべての文字にfont-specを使用する。

font-specは関数font-specが作成したfont-specオブジェクトかもしれない(低レベルのフォント表現を参照)。

font-specにはコンスセル(family . registry)を指定できる。ここでfamilyはフォントのファミリー名(先頭にfoundry名が含まれるかもしれない)、registryはフォントのレジストリー名(末尾にエンコーディング名が含まれるかもしれない)。

font-specにはフォント名(文字列)も指定できる。

font-specには、指定されたcharactersにたいするフォントが存在しないことを明示的に指定するnilを指定できる。これはたとえばUnicodeのPUA(Private Use Area)由来のようなグリフをもたない文字のフォントにたいするシステムワイドの高価な検索を避けるために有用。

オプション引数addが非nilなら、以前charactersにセットされたフォントspecにfont-specを追加する方法を指定する。prependならfont-specは既存specの先頭、appendならfont-specは末尾に追加される。デフォルトではfont-specは以前のセットされたfontspecをオーバーライドする。

たとえば以下は文字セットjapanese-jisx0208に属するすえての文字にたいして、ファミリー名が‘Kochi Gothic’であるようなフォントを使用するようにデフォルトフォントセットを変更する。

(set-fontset-font t 'japanese-jisx0208
                  (font-spec :family "Kochi Gothic"))
Function: char-displayable-p char

この関数はEmacsがcharを表示できるようなら非nilをリターンする。またはより正確には選択されたフレームのフォントセットが、charが属する文字セットを表示するためのフォントをもてばtをリターンする。

フォントセットは文字単位でフォントを指定できる。フォントセットがこれを行う場合には、この関数の値は正確ではないかもしれない。

この関数はテキスト端末用のコーディングシステムがその文字をエンコード可能かどうかもチェックするので、利用可能なフォントがなくても非nilをリターンするかもしれない(端末I/Oのエンコーディングを参照)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.12.12 低レベルのフォント表現

通常はフォントを直接扱う必要はありません。これを行う必要がある場合にはこのセクションでその方法を説明します。

Emacs Lispではフォントはフォントオブジェクト(font objects)フォントspec(font specs)フォントエンティティー(font entities)という3つの異なるLispオブジェクトを使用して表現されます。

Function: fontp object &optional type

objectがフォントオブジェクト、フォントspec、フォントエンティティーならt、それ以外ならnilをリターンする。

オプション引数typeが非nilなら、チェックするLispオブジェクトの正確なタイプを決定する。この場合にはtypefont-objectfont-specfont-entityのいずれかであること。

フォントオブジェクトはEmacsがオープンしたフォントを表します。Lispでフォントオブジェクトは変更できませんが調べることはできます。

Function: font-at position &optional window string

ウィンドウwindow内の位置positionにある文字を表示するために使用されているフォントオブジェクトをリターンする。windownilの場合のデフォルトは選択されたウィンドウ。stringnilならpositionはカレントバッファー内の位置を指定する。それ以外ならstringは文字列、positionはその文字列内での位置を指定すること。

フォントspecはフォントを探すために使用できる仕様セットを含むLispオブジェクトです。フォントspec内の仕様にたいして1つ以上のフォントがマッチすることができます。

Function: font-spec &rest arguments

arguments内の仕様を使用して新たなフォントspecをリターンする。これはproperty-valueのペアーであること。可能な仕様は以下のとおり:

:name

XLFD、Fontconfig、GTK+いずれかのフォーマットによるフォント名(文字列)。Fonts in The GNU Emacs Manualを参照のこと。

:family
:foundry
:weight
:slant
:width

これらは同じ名前のフェイス属性と同じ意味をもつ。フェイスの属性を参照のこと。:family:foundryは文字列で、それ以外はシンボル。例の値のように:slantitalic:weightbold:widthnormalかもしれない。

:size

フォントサイズ。非負の整数はピクセル単位、浮動小数点数ならポイントサイズを指定する。

:adstyle

sans’のような、そのフォントにたいするタイポグラフィックスタイル(typographic style)の追加情報。値は文字列かシンボルであること。

:registry

iso8859-1’のようなフォントの文字セットレジストリーとエンコーディング。値は文字列かシンボルであること。

:dpi

フォントがデザインされたインチあたりのドット数による解像度。値は非負の数値でなければならない。

:spacing

フォントのスペーシング(proportional, dual, mono, or charcell)。値は整数(proportionalは0、dualは90、monoは100、charcellは110)、あるいは1文字のシンボル(PDMC)であること。

:avgwidth

1/10ピクセル単位でのフォントの平均幅。値は非負の数値であること。

:script

そのフォントがサポートしなければならないスクリプト(シンボル)。

:lang

そのフォントがサポートするべき言語。値は名前が2文字のISO-639言語名であるようなシンボルであること。Xでは値は(もし空でなければ)フォントのXLFD名の“Additional Style”フィールドにたいしてマッチされる。MS-Windowsではそのspecにマッチするフォントにはその言語にたいして必要なコードページのサポートが要求される。現在のところこのプロパティでは‘ja’、‘ko’、‘zh’というCJK言語の小セットだけがサポートされる。

:otf

複雑なテキストレイアウトを必要とするスクリプトをサポートするGNU/Linux上の‘libotf’のようなライブラリーとともにEmacsがコンパイルされているような場合には、そのフォントはそれらのOpenType機能をサポートするOpenTypeフォントでなければならない。値は以下の形式のリストでなければならない

(script-tag langsys-tag gsub gpos)

ここでscript-tagはOpenTypeスクリプトタグシンボル、langsys-tagはOpenType言語システムタグシンボル(nilならデフォルト言語システムを使用)、gsubはOpenType GSUB機能タグシンボル(何も要求されなければnil)、gposはOpenType GPOS機能タグシンボルのリスト(何も要求されなければnil)。gsubgposがリストなら、そのリスト内のnil要素は、そのフォントが残りすべてのタグシンボルにマッチしてはならないことを意味する。gposは省略可。OpenTypeのスクリプト、言語、機能タグのリストについてはthe list of registered OTF tagsを参照のこと。

:type

文字の描画に使用されるフォントバックエンド(font backend)を指定するシンボル。指定できる値はプラットフォームとビルド時にEmacsがどのようにconfigureされたかに依存する。典型的な値としてはXではftcrhbxfthb、MS-Windowsではharfbuzz、GNUstepではnsなどが含まれる。font-specのように未指定のままだとnilもあり得る。

Function: font-put font-spec property value

フォントspec font-spec内のプロパティpropertyvalueをセットする。propertyには上述のいずれかを指定できる。

フォントエンティティーはオープンする必要がないフォントへの参照です。フォントオブジェクトとフォントspecの中間的な性質をもちフォントspecとは異なり、フォントオブジェクトと同じように単一かつ特定のフォントを参照します。フォントオブジェクトとは異なりフォントエンティティーの作成では、そのフォントのコンテンツはコンピューターへのメモリーにロードされません。Emacsはスケーラブルフォントを参照するために単一のフォントエンティティーから複数の異なるサイズのフォントオブジェクトをオープンするかもしれません。

Function: find-font font-spec &optional frame

この関数はフレームframe上のフォントspec font-specにもっともマッチするフォントエンティティーをリターンする。framenilの場合のデフォルトは選択されたフレーム。

Function: list-fonts font-spec &optional frame num prefer

この関数はフォントspec font-specにマッチするすべてのフォントエンティティーのリストをリターンする。

オプション引数frameが非nilなら、そのフォントが表示されるフレームを指定する。オプション引数numが非nilなら、それはリターンされるリストの最大長を指定する整数だること。オプション引数preferが非nilなら、それはリターンされるリスト順を制御するために使用する別のフォントspecであること。リターンされるフォントspecはそのフォントspecにもっとも近い降順にソートされて格納される。

:font属性の値としてフォントspec、フォントエンティティー、フォント名文字列を渡してset-face-attributeを呼び出すと、Emacsは表示に利用可能なもっともマッチするフォントをオープンします。そしてそのフェイスにたいする:font属性の実際の値として、対応するフォントオブジェクトを格納します。

以下の関数はフォントに関する情報を取得するために使用できます。これらの関数のfont引数にはフォントオブジェクト、フォントエンティティー、またはフォントspecを指定できます。

Function: font-get font property

この関数はfontにたいするフォントプロパティpropertyの値をリターンする。propertyにはfont-specがサポートするもののいずれかを指定できる。

fontがフォントspecであり、そのフォントspecがpropertyを指定しなければリターン値はnilfontがフォントオブジェクトかフォントエンティティーなら、:scriptプロパティにたいする値はそのフォントがサポートするスクリプトのリスト、:otfプロパティにたいする値は(gsub . gpos)のような形式のコンス。ここでgsubgposはそのフォントがサポートするOpenType機能を表す以下のような形式のリスト

((script-tag (langsys-tag feature…) …) …)

where script-tag, langsys-tag, and feature ここでscript-taglangsys-tagfeatureはOpenTypeのレイアウトtagを表すシンボル。

fontがフォントオブジェクトの場合には、fontのフォントバックエンドが非OpenTypeフォントにたいする結合文字(combining characters)をサポートしていればスペシャルプロパティ:combining-capabilityは非nil

Function: font-face-attributes font &optional frame

この関数はfontに対応するフェイス属性のリストをリターンする。オプション引数frameはフォントが表示されるフレームを指定する。これがnilなら選択されたフレームが使用される。リターン値は以下の形式

(:family family :height height :weight weight
   :slant slant :width width)

ここでfamilyheightweightslantwidthの値はフェイス属性の値。fontにより指定されない場合には、いくつかのキー/属性ペアーはこのリストから省略されるかもしれない。

Function: font-xlfd-name font &optional fold-wildcards

この関数はfontにマッチするXLFD((X Logical Font Descriptor))を文字列としてリターンする。XLFDに関する情報はFonts in The GNU Emacs Manualを参照のこと。その名前がXLFD(最大255文字を含むことが可能)にたいして長すぎれば、この関数はnilをリターンする。

オプション引数fold-wildcardsが非nilなら連続するワイルドカードは1つにまとめられる。

以下の2つの関数はフォントに関して重要な情報をリターンします。

Function: font-info name &optional frame

この関数はframeで使用されるような文字列nameで指定されたフォントに関する情報をリターンする。frameが省略かnilの場合のデフォルトは選択されたフレーム。

この関数は[opened-name full-name size height baseline-offset relative-compose default-ascent max-width ascent descent space-width average-width filename capability]という形式のベクターによる値をリターンする。以下はこのベクターの各コンポーネントの意味:

opened-name

フォントのオープンに使用された名前(文字列)。

full-name

フォントの完全名(文字列)。

size

フォントのピクセルサイズ。

height

フォント高さ(ピクセル単位)。

baseline-offset

ASCIIベースラインからのピクセル単位のオフセット(上方が正)。

relative-compose
default-ascent

文字の組み合わせ(compose)の方式を制御する数値。

max-width

フォントの最大のアドバンス幅。

ascent
descent

このフォントのアセント(ascent)とディセント(descent)。これら2つの数値の合計は上述のheightと等しくなること。

space-width

そのフォントのスペース文字の幅(ピクセル単位)。

average-width

そのフォントの文字の平均幅。これが0ならEmacsは表示のテキストレイアウト計算時にかわりにspace-widthの値を使用する。

filename

フォントのファイル名(文字列)。フォントのバックエンドがフォントのファイル名を見つける手段を提供しなければnilもあり得る。

capability

最初の要素がフォントタイプを表すxopentypetruetypetype1pcfbdfのいずれかのシンボルであるようなリスト。OpenTypeフォントでは、フォントによりサポートされる機能GSUBGPOSの2つの要素が含まれる。これらの要素はそれぞれ((script (langsys feature …) …) …)という形式のリストであり、ここでscriptはOpenTypeのscriptタグを表すシンボル、langsysはOpenTypeのlangsysタグを表すシンボル(またはデフォルトのlangsysを表すnil)、そよびfeatureはそれぞれOpenTypeのfeatureタグを表す。

Function: query-font font-object

この関数はfont-objectに関する情報をリターンする(これは引数としてフォント名を文字列で受け取るfont-infoとは対照的)。

この関数は[name filename pixel-size max-width ascent descent space-width average-width capability]という形式のベクターで値をリターンする。以下はこのベクターの各要素の意味:

name

フォント名(文字列)。

filename

フォントのファイル名(文字列)。フォントのバックエンドがフォントのファイル名を見つける手段を提供しなければnilもあり得る。

pixel-size

フォントをオープンするために使用されたフォントのピクセルサイズ。

max-width

フォントの最大のアドバンス幅。

ascent
descent

このフォントのアセント(ascent)とディセント(descent)。これら2つの数値の合計はフォントの高さを与える。

space-width

そのフォントのスペース文字の幅(ピクセル単位)。

average-width

そのフォントの文字の平均幅。これが0ならEmacsは表示のテキストレイアウト計算時にかわりにspace-widthの値を使用する。

capability

最初の要素がフォントタイプを表すxopentypetruetypetype1pcfbdfのいずれかのシンボルであるようなリスト。OpenTypeフォントでは、フォントによりサポートされる機能GSUBGPOSの2つの要素が含まれる。これらの要素はそれぞれ((script (langsys feature …) …) …)という形式のリストであり、ここでscriptはOpenTypeのscriptタグを表すシンボル、langsysはOpenTypeのlangsysタグを表すシンボル(またはデフォルトのlangsysを表すnil)、そよびfeatureはそれぞれOpenTypeのfeatureタグを表す。

以下の4つの関数はさまざまなフェイスにより使用されるフォントに関するサイズ情報をリターンして、Lispプログラム内でのさまざまなレイアウトの検討を可能にします。これらの関数は問い合わせられたフェイスがリマップされていたら、リマップされたフェイスに関する情報をリターンすることによりフェイスのシマップを考慮します。フェイスのリマップを参照してください。

Function: default-font-width

カレントバッファーの選択されたフレームにたいして定義されたデフォルトフェイスで使用されるフォントの平均幅をピクセル単位でリターンする。

Function: default-font-height

この関数は選択されたフレームにたいして定義されたカレントバッファーのデフォルトフェイスで使用されるフォントの高さをピクセル単位でリターンする。

Function: window-font-width &optional window face

この関数はwindow内のfaceで使用されるフォントの平均幅をピクセル単位でリターンする。windowには生きたウィンドウを指定しなければならない。nilか省略ならwindowのデフォルトは選択されたウィンドウ、faceのデフォルトはwindow内のデフォルトフェイス。

Function: window-font-height &optional window face

この関数はwindow内のfaceで使用されるフォントの高さをピクセル単位でリターンする。windowには生きたウィンドウを指定しなければならない。nilか省略ならwindowのデフォルトは選択されたウィンドウ、faceのデフォルトはwindow内のデフォルトフェイス。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.13 フリンジ

グラフィカルなディスプレイではEmacsは各ウィンドウに隣接してフリンジ(fringes)を描画します。これは切り詰め(truncation)、継続(continuation)、水平スクロールを示すビットマップを表示できる側面の細い垂直ストリップです。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.13.1 フリンジのサイズと位置

以下のバッファーローカル変数はバッファーを表示するウィンドウのフリンジの位置と幅を制御します。

Variable: fringes-outside-margins

フリンジは通常はディスプレイマージンとウィンドウテキストの間に表示される。この値が非nilならフリンジはディスプレイマージンの外側に表示される。マージン内への表示を参照のこと。

Variable: left-fringe-width

この変数が非nilなら、それは左フリンジの幅をピクセル単位で指定する。値nilはそのウィンドウのフレームの左フリンジ幅を使用することを意味する。

Variable: right-fringe-width

この変数が非nilなら、それは右フリンジの幅をピクセル単位で指定する。値nilはそのウィンドウのフレームの右フリンジ幅を使用することを意味する。

これらの変数にたいして値を指定しないすべてのバッファーは、フレームパラメーターleft-fringeおよびright-fringeで指定された値を使用します(レイアウトのパラメーターを参照)。

上記の変数はサブルーチンとしてset-window-fringesを呼び出す関数set-window-buffer (バッファーとウィンドウを参照)を通じて実際に効果をもちます。これらの変数のいずれかを変更しても影響を受ける各ウィンドウでset-window-bufferを呼び出さなければ、そのバッファーを表示する既存のウィンドウのフリンジ表示は更新されません。個別のウィンドウでのフリンジ表示を制御するためにset-window-fringesを使用することもできます。

Function: set-window-fringes window left &optional right outside-margins persistent

この関数はウィンドウwindowのフリンジ幅をセットする。windownilなら選択されたウィンドウが使用される。

引数leftは左フリンジ、同様にrightは右フリンジにたいしてピクセル単位で幅を指定する。いずれかにたいする値nilはデフォルトの幅を意味する。outside-marginsが非nilならフリンジをディスプレイマージンの外側に表示することを指定する。

期待する幅のフリンジを収容するのにwindowが十分大きくなければ、windowのフリンジは未変更のままになる。

ここで指定した値は、windowにたいしてkeep-marginsnilか省略したset-window-buffer (バッファーとウィンドウを参照)の呼び出しによって後刻オーバーライドされるかもしれない。しかしオプションの5つ目の引数persistentが非nil、かつ他の引数が成功裏に処理されたら、ここで指定した値は後続のset-window-buffer呼び出しに引き継がれる。これはミニバッファーウィンドウでフリンジを永続的にオフにするために使用できる。例はset-window-scroll-bars (スクロールバーを参照)の説明を参照のこと。

Function: window-fringes &optional window

この関数はウィンドウwindowのフリンジに関する情報をリターンする。windowが省略かnilなら選択されたウィンドウが使用される。値は(left-width right-width outside-margins persistent)という形式。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.13.2 フリンジのインジケーター

フリンジインジケーター(Fringe indicators)は行の切り詰めや継続、バッファー境界などを示すウィンドウフリンジ内に表示される小さいアイコンのことです。

User Option: indicate-empty-lines

これが非nilならEmacsはグラフィカルなディスプレイ上で、バッファー終端にある空行それぞれにたいしてフリンジ内に特別なグリフを表示する。フリンジを参照のこと。この変数はすべてのバッファーにおいて自動的にバッファーローカルになる。

User Option: indicate-buffer-boundaries

このバッファーローカル変数はウィンドウフリンジ内でバッファー境界とウィンドウのスクロールを示す方法を制御する。

Emacsはバッファー境界(そのバッファーの最初の行と最後の行)がスクリーン上に表示された際には、それを三角アイコン(angle icon)で示すことができる。加えてスクリーンより上にテキストが存在すれば上矢印(up-arrow)、スクリーンの下にテキストが存在すれば下矢印(down-arrow)をフリンジ内に表示してそれを示すことができる。

基本的な値として3つの値がある:

nil

これらのフリンジアイコンを何も表示しない。

left

左フリンジに三角アイコンと矢印を表示する。

right

右フリンジに三角アイコンと矢印を表示する。

その他の非alist

左フリンジに三角アイコンを表示して矢印を表示しない。

値がそれ以外ならどのフリンジインジケーターをどこに表示するかを指定するalistであること。alistの各要素は(indicator . position)のような形式をもつ。ここでindicatortopbottomupdown、またはt (指定されていないすべてのアイコンをカバーする)のいずれかでありpositionleftright、またはnilのいずれか。

たとえば((top . left) (t . right))は左フリンジにtop angleビットマップを、右フリンジにbottom angleビットマップと両arrowビットマップを配置する。左フリンジにangleビットマップを表示してarrowビットマップを表示しないようにするには((top . left) (bottom . left))を使用する。

Variable: fringe-indicator-alist

このバッファーローカル変数は論理的ロジカルフリンジインジケーターから、ウィンドウフリンジ内に実際に表示されるビットマップへのマッピングを指定する。値は(indicator . bitmaps)のような要素をもつalist。ここでindicatorは論理的インジケータータイプ、bitmapsはそのインジケーターに使用するフリンジビットマップを指定する。

indicatorはそれぞれ以下のシンボルのいずれかであること:

truncationcontinuation

行の切り詰めと継続に使用される。

updowntopbottomtop-bottom

indicate-buffer-boundariesが非nilの際に使用される。updownは、そのウィンドウ端より上と下にあるバッファー境界を示す。topbottomはバッファーの最上端と最下端のテキスト行を示す。top-bottomはバッファー内にテキスト行1行だけが存在することを示す。

empty-line

indicate-empty-linesが非nilの際に、バッファーの後の空行を示すために使用される。

overlay-arrow

オーバーレイ矢印に使用される(オーバーレイ矢印を参照)。

bitmapsの値にはシンボルのリスト(left right [left1 right1])を指定できる。シンボルleftrightは特定のインジケーターにたいして左および/または右フリンジに表示するビットマップを指定する。left1right1はインジケーターbottomtop-bottomに固有であり、最後の改行をもたない最後のテキスト行を示すために使用される。かわりにbitmapsに左フリンジと右フリンジの両方で使用される単一のシンボルを指定することもできる。

標準のビットマップシンボルのリストと自身で定義する方法についてはフリンジのビットマップを参照のこと。加えてnilは空ビットマップ(表示されないインジケーター)を表す。

fringe-indicator-alistがバッファーローカルな値をもち、論理的インジケーターにたいしてビットマップが定義されていないかビットマップがtならば、fringe-indicator-alistのデフォルト値から対応する値が使用される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.13.3 フリンジのカーソルFrin

ある行がウィンドウと正確に同じ幅なとき、2行を使用するかわりにEmacsは右フリンジ内にカーソルを表示します。フリンジ内のカーソルを表すために使用されるビットマップの違いはカレントバッファーのカーソルタイプに依存します。

User Option: overflow-newline-into-fringe

これが非nilなら、ウィンドウと正確に同じ幅の(最後の改行文字に継続されない)行は継続されない。ポイントが行端に達した際には、カーソルはかわりに右フリンジに表示される。

Variable: fringe-cursor-alist

この変数は論理的カーソルタイプから、右フリンジ内に実際に表示されるフリンジビットマップへのマッピングを指定する。値は各要素が(cursor-type . bitmap)のような形式をもつようなalist。ここでbitmapは使用するフリンジビットマップ、cursor-typeは表示するカーソルタイプ。

cursor-typeはそれぞれboxhollowbarhbarhollow-smallのいずれかであること。最初の4つはフレームパラメーターcursor-typeの場合と同じ意味をもつ(カーソルのパラメーターを参照)。hollow-smallタイプは特定のディスプレイ行にたいして通常のhollow-rectangleが高すぎる際にhollowのかわりに使用される。

bitmapはそれぞれ、その論理的カーソルタイプにたいして表示されるフリンジビットマップを指定するシンボルであること。 詳細はフリンジのビットマップを参照のこと。

fringe-cursor-alistがバッファーローカルな値をもち、カーソルタイプにたいして定義されたビットマップが存在しなければ、fringes-indicator-alistのデフォルト値の対応する値が使用される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.13.4 フリンジのビットマップ

フリンジビットマップ(fringe bitmaps)は行の切り詰めや継続、バッファー境界、オーバーレイ矢印等にたいする論理的フリンジインジケーターを表現する実際のビットマップです。それぞれのビットマップはシンボルにより表されます。 これらのシンボルはフリンジインジケーターからビットマップへのマッピングを行う変数fringe-indicator-alist (フリンジのインジケーターを参照)、およびフリンジカーソルからビットマップへのマッピングを行う変数fringe-cursor-alist (フリンジのカーソルFrinを参照)から参照されます。

Lispプログラムも行内に出現する文字の1つにdisplayプロパティを使用することにより、左フリンジまたは右フリンジ内にビットマップを直接表示することができます。そのような表示指定は以下の形式をもちます

(fringe bitmap [face])

fringeleft-fringeright-fringeいずれかのシンボル、bitmapは表示するビットマップを識別するシンボルです。オプションのfaceはビットマップの表示でフォアグラウンカラーおよびバックグラウンドカラーを使用するフェイスを命名します( faceが指定しないカラーにたいしてはfringeフェイスの属性を使用する)。faceを省略すると、fringeが指定しないカラーにdefaultフェイスの属性を使用することを意味します。defaultフェイスやfringeフェイスの属性に依存しない予測可能な結果を得るために、faceは省略せず常に特定のフェイスを与えることを推奨します。特にビットマップをfringeフェイスで表示したければ、faceとしてfringeを使用してください。

たとえば左フリンジに矢印を表示するためには、warningフェイスを使用して以下のようにできます:

(overlay-put
 (make-overlay (point) (point))
 'before-string (propertize
                 "x" 'display
                 `(left-fringe right-arrow warning)))

以下はEmacsが定義する標準的なフリンジビットマップと、(fringe-indicator-alistfringe-cursor-alistを通じて)Emacs内で現在それらが使用される方法のリストです。

left-arrowright-arrow

切り詰められた行を示すために使用される。

left-curly-arrowright-curly-arrow

継続された行を示すために使用される。

right-triangleleft-triangle

前者はオーバーレイ矢印により使用され、後者は使用されない。

up-arrowdown-arrow
bottom-left-anglebottom-right-angle
top-left-angletop-right-angle
left-bracketright-bracket
empty-line

バッファー境界を示すために使用される。

filled-rectanglehollow-rectangle
filled-squarehollow-square
vertical-barhorizontal-bar

フリンジカーソルの異なるタイプにたいして使用される。

exclamation-markquestion-mark
large-circle

Emacsの中核機能では使用されない。

次のサブセクションではフリンジビットマップを独自に定義する方法を説明します。

Function: fringe-bitmaps-at-pos &optional pos window

この関数はウィンドウwindow内の位置posを含むディスプレイ行のフリンジビットマップをリターンする。リターン値は(left right ov)という形式をもつ。ここでleftは左フリンジ内のフリンジビットマップにたいするシンボル(ビットマップなしならnil)、rightは同様に右フリンジにたいして、ovが非nilなら左フリンジにオーバーレイ矢印が存在することを意味する。

window内でposが可視でなければ値はnilwindownilなら選択されたウィンドウを意味する。posnilならwindow内のポイントの値を意味する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.13.5 フリンジビットマップのカスタマイズ

Function: define-fringe-bitmap bitmap bits &optional height width align

この関数はシンボルbitmapを新たなフリンジビットマップとして定義、またはその名前の既存のビットマップを置き換える。

引数bitsは使用するイメージを指定する。これは各要素(整数)が対応するビットマップの1行を指定する文字列か整数ベクターであること。整数の各ビットはそのビットマップの1ピクセル、低位ビットはそのビットマップの最右ピクセルに対応する(このビットオーダーはXBMイメージと逆順であることに注意。XBMイメージを参照)。

高さは通常はbitsの長さ。しかし非nilheightにより異なる高さを指定できる。幅は通常は8だが非nilwidthにより異なる幅を指定できる。widthは1から16の整数でなければならない。

引数alignはそのビットマップが使用される行範囲に相対的なビットマップの位置を指定する。デフォルトはそのビットマップの中央。指定できる値はtopcenterbottom

align引数にはリスト(align periodic)も指定できて、alignは上述のように解釈される。periodicが非nilなら、それはbits内の行が指定される高さに達するのに十分な回数繰り返されるべきであることを指定する。

Function: destroy-fringe-bitmap bitmap

この関数はbitmapにより識別されるフリンジビットマップを破棄する。bitmapが標準フリンジビットマップを識別する場合には、それを完全に消去するかわりに実際にはそのビットマップの標準定義をリストアする。

Function: set-fringe-bitmap-face bitmap &optional face

これはフリンジビットマップbitmapにたいするフェイスにfaceをセットする。facenilならfringeフェイスを選択する。ビットマップのフェイスはそれを描画するカラーを制御する。

facefringeにマージされるためfaceは通常はフォアグラウンドカラーだけを指定すること。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.13.6 オーバーレイ矢印

オーバーレイ矢印(overlay arrow)は、バッファー内の特定の行にたいしてユーザーに注意を促すために有用です。たとえばデバッガーでのインターフェースに使用されるモードでは、オーバーレイ矢印は実行されているコード行を示します。この機能はオーバーレイ(overlays)にたいして何も行いません(オーバーレイを参照)。

Variable: overlay-arrow-string

この変数は特定の行にたいして注意を喚起するために表示する文字列、または矢印機能が使用されていなければnilを保持する。グラフィカルなディスプレイでは、フリンジが表示されていればこの文字列のコンテンツは無視されて、かわりにフリンジ領域からディスプレイ領域左側にグリフが表示される。

Variable: overlay-arrow-position

この変数はオーバーレイ矢印を表示する箇所を示すマーカーを保持する。これは行の先頭となるポイントであること。非グラフィカルなディスプレイ、あるいは左フリンジが非表示の場合には、その行の先頭に矢印テキストが表示され、矢印テキストが表示されないときに表示されるべきテキストがオーバーレイされる。その矢印は通常は短く行は普通はインデントで開始されるので、上書きが問題となることは通常はない。

オーバーレイ矢印の文字列は、そのバッファーのoverlay-arrow-positionの値がバッファー内を指せば与えられた任意のバッファーで表示される。したがってoverlay-arrow-positionのバッファーローカルなバインディングを作成することにより、複数のオーバーレイ矢印の表示が可能である。しかしこれを達成するためには、overlay-arrow-variable-listを使用するほうが通常はより明快。

before-stringプロパティをもつオーバーレイを作成することにより同様のことを行うことができます。オーバーレイのプロパティを参照してください。

変数overlay-arrow-variable-listを通じて複数のオーバーレイ矢印を定義できます。

Variable: overlay-arrow-variable-list

この変数の値は、それぞれがオーバーレイ矢印の位置を指定する変数のリスト。変数overlay-arrow-positionはこのリスト上にあるために通常の意味をもつ。

このリスト上の各変数は対応するオーバーレイ矢印位置に表示するためのオーバーレイ矢印文字列を指定するoverlay-arrow-stringプロパティ(テキスト端末、あるいは左フリンジが非表示のグラフィカルな端末)、およびフリンジビットマップを指定するoverlay-arrow-bitmapプロパティ(左フリンジがあるグラフィカル端末))をもつことができます。これらのプロパティがセットされていなければデフォルトのフリンジインジケーターoverlay-arrow-stringoverlay-arrowが使用されます。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.14 スクロールバー

フレームパラメーターvertical-scroll-barsはそのフレーム内のウィンドウが垂直スクロールバーをもつべきかと、それらが左か右のいずれかに配置されるべきかを通常は制御します。フレームパラメーターscroll-bar-widthはそれらの幅を指定します(nilはデフォルトを意味する)。

フレームパラメーターhorizontal-scroll-barsはフレーム内のウィンドウが水平スクロールバーをもつかどうかを制御します。フレームパラメーターscroll-bar-heightはそれらの高さを指定します(nilはデフォルトを意味する)。レイアウトのパラメーターを参照のしてください。

水平スクロールバーはすべてのプラットフォームで利用可能ではありません。引数を受け取らない関数horizontal-scroll-bars-available-pは、システム上で水平スクロールバーが利用可能なら非nilをリターンします。

以下の3つの関数は引数として生きたフレームを受け取り、デフォルトは選択されたフレームです。

Function: frame-current-scroll-bars &optional frame

この関数はフレームframeのスクロールバーのタイプを報告する。値はコンスセル(vertical-type . horizontal-type)。ここでvertical-typeleftright、またはnil (スクロールバーなしを意味する)のいずれか。horizontal-typebottomnil (水平スクロールバーなしを意味する)のいずれか。

Function: frame-scroll-bar-width &optional frame

この関数はウィンドウwindowにたいして垂直スクロールバーの幅をピクセル単位でリターンする。

Function: frame-scroll-bar-height &optional frame

この関数はframeの水平スクロールバーの高さをピクセル単位でリターンする。

以下の関数を使用することにより、特定のウィンドウにたいするフレーム固有のセッティングをオーバーライドできます:

Function: set-window-scroll-bars window &optional width vertical-type height horizontal-type persistent

この関数はウィンドウwindowのスクロールバーの幅および/または高さ、およびタイプをセットする。windownilなら選択されたウィンドウが使用される。

widthはピクセル単位で垂直スクロールバーの幅を指定する(nilはそのフレームにたいして指定された幅の使用を意味する)。vertical-typeは垂直スクロールバーをもつかどうか、もつ場合にはその位置を指定する。可能な値はleftrightt (フレームのデフォルトの使用を意味する)、垂直スクロールバーなしならnilのいずれか。

heightはピクセル単位で水平スクロールバーの高さを指定する(nilはそのフレームにたいして指定された高さの使用を意味する)。horizontal-typeは水平スクロールバーをもつかどうかを指定する。可能な値はbottomt (フレームのデフォルトの使用を意味する)、水平スクロールバーなしならnilのいずれか。ミニウィンドウにたいして値tnil、すなわち水平スクロールバーを表示しないことを意味することに注意。ミニウィンドウで水平スクロールバーを表示するためには、明示的にbottomを指定する必要がある。

期待するサイズのスクロールバーを収容するのにwindowが十分大きくなければ、windowのスクロールバーは未変更のままになる。

ここで指定した値はwindowにたいする引数keep-marginsnilか省略したset-window-buffer (バッファーとウィンドウを参照)の呼び出しにより後からオーバーライドされるかもしれない。しかしオプションの1つ目の引数persistentが非nil、かつ他の引数が成功裏に処理されたなら、ここで指定された値は後続のset-window-buffer呼び出しに引き継がれる。

set-window-scroll-barsおよびset-window-fringes (フリンジのサイズと位置を参照)のpersistent引数を使用すれば、以下のスニペットを早期initファイル(early init file)に追加することにより、すべてのミニバッファーウィンドウでスクロールバーおよび/またはフリンジを信頼性をもって永続的にオフにすることができます(initファイルを参照)。

(add-hook 'after-make-frame-functions
          (lambda (frame)
            (set-window-scroll-bars
             (minibuffer-window frame) 0 nil 0 nil t)
            (set-window-fringes
             (minibuffer-window frame) 0 0 nil t)))

以下の4つの関数は引数として生きたウィンドウを受け取り、デフォルトは選択されたウィンドウです。

Function: window-scroll-bars &optional window

この関数は(width columns vertical-type height lines horizontal-type persistent)という形式のリストをリターンする。

widthは垂直スクロールバーの幅に指定された値(nilもあり得る)。columnsは垂直スクロールバーが実際に占有する列数(丸められているかもしれない)。

heightは水平スクロールバーの高さに指定された値(nilもあり得る)。linesは水平スクロールバーが実際に占有する行数(丸められているかもしれない)。

persistentの値は最後に成功裏にset-window-scroll-barsを呼び出した際にwindowに指定した値、そのような呼び出しがなければnil

Function: window-current-scroll-bars &optional window

この関数はウィンドウwindowにたいするスクロールバータイプを報告する。値はコンスセル(vertical-type . horizontal-type)window-scroll-barsとは異なりフレームのデフォルトとscroll-bar-modeを考慮して実際に使用されているスクロールバータイプを報告する。

Function: window-scroll-bar-width &optional window

この関数はwindowの垂直スクロールバーの幅をピクセル単位でリターンする。

Function: window-scroll-bar-height &optional window

この関数は、windowの水平スクロールバーの高さをピクセル単位でリターンする。

set-window-scroll-barsでウィンドウのスクロールバーのセッティングを指定しない場合には、表示されようとするバッファーのバッファーローカル変数vertical-scroll-barhorizontal-scroll-barscroll-bar-widthscroll-bar-heightがウィンドウのスクロールバーを制御します。set-window-bufferはこれらの変数を調べる関数です。あるウィンドウですでに可視なバッファーでこれらを変更した場合には、すでに表示されているのと同じバッファーを指定してset-window-bufferを呼び出すことにより、そのウィンドウに新たな値を記録させることができます。

以下の変数をセット(セットにより自動的にバッファーローカルになる)することにより、特定のバッファーのスクロールバーの外観を制御できます。

Variable: vertical-scroll-bar

この変数は垂直スクロールバーの配置を指定する。可能な値はleftright、そのフレームのデフォルトの使用を意味するt、スクロールバーなしのnilのいずれか。

Variable: horizontal-scroll-bar

この変数は水平スクロールバーの配置を指定する。可能な値はbottom、そのフレームのデフォルトの使用を意味するt、スクロールバーなしのnilのいずれか。

Variable: scroll-bar-width

この変数はそのバッファーの垂直スクロールバーをピクセル単位で量った幅を指定する。値nilはフレームにより指定された値の使用を意味する。

Variable: scroll-bar-height

この変数はそのバッファーの水平スクロールバーをピクセル単位で量った高さを指定する。値nilはフレームにより指定された値の使用を意味する。

最後に変数scroll-bar-modehorizontal-scroll-bar-modeをカスタマイズすることにより、すべてのフレームでのスクロールバーの表示を切り替えることができます。

User Option: scroll-bar-mode

この変数はすべてのフレームに垂直スクロールバーを配置するべきかと、その場所を制御する。可能な値は、スクロールバーなしのnil、左にスクロールバーを配置するleft、右にスクロールバーを配置するrightのいずれか。

User Option: horizontal-scroll-bar-mode

この変数はすべてのフレームに水平スクロールバーを表示するかどうかを制御する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.15 ウィンドウディバイダー

ウィンドウディバイダーとはフレームのウィンドウ間に描画されるバーのことです。右(right)ディバイダーはあるウィンドウと、その右に隣接する任意のウィンドウの間に描画されます。その幅(厚さ)はフレームパラメーターright-divider-widthで指定されます。下(bottom)ディバイダーはあるウィンドウと、その下に隣接するウィンドウやエコーエリアとの間に描画されます。その幅はフレームパラメーターbottom-divider-widthで指定されます。いずれの場合でも幅に0を指定すると、そのようなディバイダーを描画しないことを意味します。レイアウトのパラメーターを参照してください。

技術的には右ディバイダーはそれの左にあるウィンドウに所属して、その幅がそのウィンドウのトータル幅に寄与することを意味します。下ディバイダーは上にあるウィンドウに所属して、その幅がそのウィンドウのトータル高さに寄与することを意味します。ウィンドウのサイズを参照してください。あるウィンドウが右ディバイダーと左ディバイダーの両方をもつ場合には下ディバイダーが優勢になります。これは右ディバイダーが下ディバイダーの上で終端されるのに比べて、下ディバイダーはそのウィンドウの完全なトータル幅で描画されることを意味しています。

ディバイダーはマウスでドラッグできるのでマウスで隣接するウィンドウのサイズを調整するために有用です。これらはスクロールバーやモードラインが表示されていないときに隣接するウィンドウを視覚的に分離する役目もあります。以下の3つのフェイスによりディバイダーの外観をカスタマイズできます:

window-divider

ディバイダーの幅が3ピクセル未満のときは、このフェイスのフォアグラウンドカラーで塗りつぶしで描画される。これより広いディバイダーでは、最初と最後のピクセルを除いた内部にたいしてのみこのフェイスが使用される。

window-divider-first-pixel

これは少なくとも幅が3ピクセルあるディバイダーの最初のピクセルを描画するために使用される。塗りつぶし(solid)の外観を得るためにはwindow-dividerフェイスに使用されるのと同じ値をセットすること。

window-divider-last-pixel

これは少なくとも幅が3ピクセルあるディバイダーの最後のピクセルを描画するために使用される。塗りつぶし(solid)の外観を得るためにはwindow-dividerフェイスに使用されるのと同じ値をセットすること。

以下の2つの関数により特定のウィンドウのディバイダーのサイズを取得できます。

Function: window-right-divider-width &optional window

windowの右ディバイダーの幅(厚さ)をピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。最右ウィンドウにたいするリターン値は常に0。

Function: window-bottom-divider-width &optional window

windowの下ディバイダーの幅(厚さ)をピクセル単位でリターンする。windowは生きたウィンドウでなければならずデフォルトは選択されたウィンドウ。ミニバッファーウィンドウやミニバッファーがないフレームの最下ウィンドウにたいするリターン値は常に0。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.16 displayプロパティ

テキストプロパティ(またはオーバーレイプロパティ)のdisplayはテキストへのイメージ挿入、およびテキスト表示のその他の事相を制御します。同じdisplayプロパティ値内のディスプレイ仕様は、一般的にはそれらがカバーするテキストにたいして並行して適用されます。

複数のソース(オーバーレイおよび/またはテキストプロパティ)がdisplayプロパティにたいして値を指定しますが1つの値だけが効果をもち、それはget-char-propertyのルールにしたがいます。テキストプロパティを調べるを参照してください。

displayプロパティの値はディスプレイ仕様、または複数のディスプレイ仕様を含むリストかベクターであるべきです。

Function: get-display-property position prop &optional object properties

これはベクター、リスト、あるいは単純なプロパティであるかどうかに関係なく、特定のdisplayを取得するために使用できる利便用関数である。これはget-text-property (テキストプロパティを調べるを参照)と似ているが、displayプロパティにたいしてのみ動作する点が異なる。

positionは調べるバッファーまたは文字列内の位置、propはリターンされるdisplayプロパティ。オプション引数objectは文字列かバッファーのいずれかで、デフォルトはカレントバッファー。オプション引数propertiesが非nilならそれはdisplayプロパティでなければならず、その場合にはpositionobjectは無視される(これはたとえばget-char-property (テキストプロパティを調べるを参照)ですでにdisplayプロパティを取得済みな場合に役に立つかもしれない)。

Function: add-display-text-property start end prop value &optional object

startからendのテキストのdisplayプロパティpropvalueを追加する。

リージョン内にdisplayプロパティが非nilのテキストがあれば、それらのプロパティは保たれる。たとえば:

(add-display-text-property 4 8 'height 2.0)
(add-display-text-property 2 12 'raise 0.5)

これを行うと2から4のリージョンのdisplayプロパティはraise、4から8のリージョンのdisplayプロパティにはraiseheightの両方、そして最後の8から12のdisplayプロパティはraiseだけになる。

objectが非nilなら、それは文字列かバッファーであること。nilの場合のデフォルトはカレントバッファー。

いくつかのディスプレイ仕様には、表示時に評価されるLispフォームを含めることができます。これは特定の状況では安全ではないかもしれません(ディスプレイ仕様が何らかの外部のプログラムやエージェントにより生成されたとき等)。(disable-eval spec)のように特別なシンボルdisable-evalで始まるリスト内にディスプレイ仕様をラップすることにより、他のすべてのディスプレイプロパティ機能をサポートしつつ、spec内の任意のLisp評価が無効になります。

このセクションの残りの部分では、複数の種類のディスプレイ仕様とそれらの意味を説明します。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.16.1 テキストを置換するディスプレイ仕様

ある種のディスプレイ仕様は、そのプロパティをもつテキストのかわりに表示する何かを指定します。これらは置換(replacing)ディスプレイ仕様と呼ばれます。Emacsはユーザーにたいして、この方法で置換されたバッファーテキストの中間への対話的なポイント移動を許可しません。

ディスプレイ仕様のリストに1つ以上の置換ディスプレイ仕様が含まれる場合には、最初の置換ディスプレイ仕様が残りをオーバーライドします。置換ディスプレイ仕様は他のほとんどのディスプレイ仕様は置換を許容しないので、それらとは無関係です。

置換ディスプレイ仕様では、そのプロパティをもつテキストとは、displayプロパティとして同一のLispオブジェクトをもつ連続したすべての文字を意味します。これらの文字は単一の単位として置換されます。displayプロパティに異なるLispオブジェクト(eqではないオブジェクト)をもつ2つの文字は個別に処理されます。

以下はこの要点を示すための例です。文字列が置換ディスプレイ仕様としての役割をもち、指定された文字列のプロパティをもつテキストを置換します(その他のディスプレイ仕様を参照)。以下の関数を考えてみてください:

(defun foo ()
  (dotimes (i 5)
    (let ((string (concat "A"))
          (start (+ i i (point-min))))
      (put-text-property start (1+ start) 'display string)
      (put-text-property start (+ 2 start) 'display string))))

この関数はバッファー内の最初の10文字それぞれにたいして文字列"A"であるようなdisplayプロパティを与えますが、これらはすべて同じ文字列オブジェクトを取得しません。最初の2文字は同じ文字列オブジェクトなので1つの‘A’に置換されます。2つの別々のput-text-property呼び出しでそのディスプレイプロパティが割り当てられたという事実は無関係です。同様に次の2文字は2つ目の文字列(concatにより新たに作成された文字列オブジェクト)を取得するので1つの‘A’で置換されて、...となります。したがって10文字は5つのAで表示されます。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.16.2 スペースの指定

指定された幅および/または高さのスペースを表示するためには(space . props)という形式のディスプレイ仕様を使用します。このプロパティを1つ以上の連続する文字にputすることができます。これらすべての文字のかわりに指定された高さと幅のスペースが表示されます。以下はスペースのウェイトを指定するためにprops内で使用できるプロパティです:

:width width

widthが数字なら、それはスペースの幅が通常の文字幅のwidth倍であるべきかを指定する。widthピクセル幅(pixel width)仕様でも可(スペースにたいするピクセル指定を参照)。

:relative-width factor

幅の広さは同じdisplayプロパティをもつ連続する文字のグループ内の最初の文字から計算される必要があることを指定する。スペースの幅はその文字のピクセル幅にfactorを乗じた幅である(テキストモード端末では文字の“ピクセル幅”は通常は1だがTAB文字や2倍の幅をもつCJK文字では1以上になり得る)。

:align-to hpos

スペースがhposに達するほど十分に広くあるべきことを指定する。hposが数字なら通常の文字幅の単位で量られる。hposピクセル幅(pixel width)仕様でも可(スペースにたいするピクセル指定を参照)。

上記プロパティのいずれか1つだけを使用するべきです。以下のプロパティでスペースの高さも指定できます:

:height height

スペースの高さを指定する。heightが数字ならスペースの高さが通常の文字高さのheight倍であるべきことを指定する。heightピクセル高さ仕様(pixel height)でも可(スペースにたいするピクセル指定を参照)。

:relative-height factor

このディスプレイ仕様をもつテキストの通常の高さにfactorを乗じることによりスペースの高さを指定する。

:ascent ascent

ascentの値が非負の100以下の数字ならスペースの高さのascentパーセントをスペースのアセント(ascent: 上方)、すなわちベースラインより上の部分とみなす。ピクセルアセント(pixel ascent)仕様によりアセントをピクセル単位で指定することも可(スペースにたいするピクセル指定を参照)。

:height:relative-heightを両方同時に使用しないでください。

:width:align-toプロパティは非グラフィック端末でサポートされますが、このセクションのその他のスペースプロパティはサポートされません。

スペースプロパティは双方向テキスト表示の並べ替えのためのパラグラフ区切りとして扱われます。詳細は双方向テキストの表示を参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.16.3 スペースにたいするピクセル指定

プロパティ:width:align-to:height:ascentの値は再表示の間に評価される特別な種類の式です。その評価の結果はピクセルの絶対数として使用されます。

以下の式がサポートされています:

  expr ::= num | (num) | unit | elem | pos | image | xwidget | form
  num  ::= integer | float | symbol
  unit ::= in | mm | cm | width | height
  elem ::= left-fringe | right-fringe | left-margin | right-margin
        |  scroll-bar | text
  pos  ::= left | center | right
  form ::= (num . expr) | (op expr ...)
  op   ::= + | -

フォームnumはデフォルトフレームフォントの高さか幅、フォーム(num)は絶対ピクセル数を指定します。numがシンボルsymbolなら、それのバッファーローカルな変数バインディングが使用されます。このバインディングには数字か上述の形式のコンスセル(他にもバッファーローカルなバインディングをもつシンボルがcarであるような他のコンスセルも含む)が可能です。

単位inmmcmはそれぞれインチ、ミリメートル、センチメートルごとのピクセル数を指定します。単位widthheightはそれぞれカレントフェイスのデフォルトの幅と高さに対応します。(image . props)という形式のイメージ仕様は、指定されたイメージの幅や高さに対応します(イメージのディスクリプタを参照)。同様に(xwidget . props)という形式のxwidget仕様は指定されたxwidgetび幅や高さを意味します。埋め込みネイティブウィジェットを参照してください。

要素left-fringeright-fringeleft-marginright-marginscroll-bartextはそのウィンドウの対応する領域の幅を指定します。そのウィンドウで行番号(表示されるテキストのサイズを参照)を表示している際にはテキストエリアの幅は行番号の表示に要するスクリーンスペースで減じられます。

位置leftcenterrightはテキストエリアの左端、中央、右端から相対的に位置を指定するために:align-toとともに使用できます。ウィンドウで行番号を表示していて、バッファーのテキスト(ヘッダーラインではない; 以下参照)のディスプレイプロパティに:align-toが使用されている場合のleftcenterの位置は、行番号の表示に要するスクリーンスペースを考慮したオフセットになります。

(textを除いた)上記ウィンドウ要素は与えられたエリアの左端から相対的に位置を指定するために:align-toとともに使用することもできます。(最初に出現するこれらシンボルのいずれかにより)相対的位置にたいするベースオフセットが一度セットがされると、残りのシンボルは指定されたエリアの幅として解釈されます。たとえば左マージンの中央に位置揃えするには以下のようにします

:align-to (+ left-margin (0.5 . left-margin))

位置揃えにたいしてベースオフセットが何も指定されなければ、テキストエリア左端にたいして常に相対的になります。たとえば‘:align-to 0’はテキストエリアの最初のテキスト行に位置揃えします。ウィンドウで行番号を表示している際には、テキストは行番号表示の終了に使用されるスペースから開始するとみなされます。

(num . expr)という形式の値は、numexprにより生成される値を意味します。たとえば(2 . in)は2インチの幅、(0.5 . image)は指定されたimage (それのイメージspecにより与えられる必要がある)の幅(または高さ)の半分を指定します。

フォーム(+ expr ...)は式の値を合計します。フォーム(- expr ...)は式の値を符号反転または減算します。

ディスプレイ仕様:align-toを使用しているヘッダーラインに表示されているテキストは、display-line-numbers-modeのオンオフや行番号の表示幅の変更時に自動的に再度位置揃えされることはありません。ヘッダーラインのテキストの位置揃え(alignment)を更新してヘッダーラインのテキストとバッファーテキストの位置揃えを保つには、そのバッファーでheader-line-indent-modeをオンにして、ディスプレイ仕様の中でこのモードのheader-line-indentおよびheader-line-indent-widthという2つの変数を使用します。ウィンドウのヘッダーラインを参照してください。以下に単純な例を示します:

(setq header-line-format
      (concat (propertize " "
                          'display
                          '(space :align-to
                                  (+ header-line-indent-width 10)))
              "Column"))

この例ではdisplay-line-numbers-modeのオンオフや行番号の表示幅の変更とは関係なく、ヘッダーラインのテキスト‘Column’をバッファーのテキストの10列目に位置揃えしています。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.16.4 その他のディスプレイ仕様

以下はdisplayテキストプロパティ内で使用できる他のディスプレイ仕様です。

string

このプロパティをもつテキストのかわりにstringを表示する。

再帰的なディスプレイ仕様はサポートされない。つまりstringdisplayプロパティがあっても使用されない。

(image . image-props)

この種のディスプレイ仕様はイメージディスクリプタである(イメージのディスクリプタを参照)。ディスプレイ仕様として使用時には、そのディスプレイ仕様をもつテキストのかわりに表示するイメージを意味する。

(slice x y width height)

この仕様はimageとともに、表示するイメージのスライス(slice: イメージの特定の領域)を指定する。要素yxはイメージ内での左上隅、widthheightはそのスライスの幅と高さを指定する。整数はピクセル数、0.0から1.0までの浮動小数点数はイメージ全体の幅や高さの割合を意味する。

((margin nil) string)

この形式のディスプレイ仕様は、このディスプレイ仕様をもつテキストのかわりにテキストと同じ位置に表示するstringを意味する。これは単にstringを使用するのと同じだが、マージン表示(マージン内への表示を参照)の特殊なケースとして行われる点が異なる。

(left-fringe bitmap [face])
(right-fringe bitmap [face])

テキスト行の任意の文字がこのディスプレイ仕様をもつ場合には、その文字のかわりにその行の左や右のフリンジに表示するbitmapを指定する。オプションのfaceはビットマップ表示にカラーを使用するフェイスを指定する。詳細はフリンジのビットマップを参照のこと。

(space-width factor)

このディスプレイ仕様は、この仕様をもつテキスト内のすべてのスペース文字に効果を及ぼす。これらすべてのスペースは通常の幅のfactor倍の幅で表示される。要素factorは整数か浮動小数点数であること。スペース以外の文字は影響を受けない。特にこれはタブ文字に影響を与えない。

(min-width (width))

このディスプレイ仕様はテキストがwidthより短ければ、終端に空白を追加することで少なくともwidthのスペースを占めるよう保証する。このテキストはパラメーターの識別子を用いて分割される。パラメーターが1要素のリストであるのはこれが理由。たとえば:

(insert (propertize "foo" 'display '(min-width (6.0))))

これにより‘foo’の後にパディングが追加されて、合計幅が通常の文字6つ分の幅になる。影響を受ける文字はdisplayプロパティのリスト(6.0)eqで比較することで識別されることに注意。要素widthはテキストに要求される最小幅を指定する整数または浮動小数点数(スペースにたいするピクセル指定を参照)。

(height height)

このディスプレイ仕様はテキストを高く(taller)、または低く(shorter)する。heightには以下を指定できる:

(+ n)

これはnステップ大きいフォントの使用を意味する。ステップは利用可能なフォントのセットから定義される。利用可能なフォントとは、具体的には、このような場合でなければ、heightを除いてそのテキストに指定されたすべての属性にマッチするフォント。適切なフォントの各サイズは別のステップとして利用可能とみなされる。nは整数であること。

(- n)

これはnステップ小さいフォントの使用を意味する。

factor (数値)

数値factorはデフォルトフォントのfactor倍高いフォントの使用を意味する。

function (シンボル)

高さを計算する関数。この関数はカレントの高さを引数として呼び出されて、使用する新たな高さをリターンすること。

form (上記以外)

heightの値が上記のいずれにもマッチしなければ、それはフォームである。Emacsはheightをカレントで指定されたフォントの高さにバインドして新たな高さを取得するためにフォームを評価する。

(raise factor)

この種のディスプレイ仕様は、その行のベースラインに相対的にテキストを上(raise)、または下(lower)に指定する。これは主に上付き文字と下付き文字を意図している。

factorは影響を受けるテキストの高さにたいする乗数として解釈される数値でなければならない。これが正なら上、負なら下に文字を表示することを意味する。

テキストがraiseより前(左)に指定されたheightディスプレイ仕様をもつ場合には、テキストが上下される量はテキストの高さにもとづくので、上下されるピクセル数にはraiseが効果をもつ。したがって通常のテキスト高さより小さい上付きや下付きで表示したければ、heightの前にraiseを指定することを考慮するべきである。

任意のディスプレイ仕様にたいして条件を作成できます。これを行うには、(when condition . spec)という形式の別リスト内にパッケージします。この場合には、仕様specconditionが非nil値に評価されたときだけ適用されます。この評価の間にobjectは条件つきdisplayプロパティをもつ文字列、またはバッファーにバインドされます。positionbuffer-positionはそれぞれobject内の位置、およびdisplayプロパティが見つかったバッファー位置にバインドされます。objectが文字列の際には両者の位置は異なるかもしれません。

conditionはこのディスプレイ仕様が配置された箇所のテキストを再表示が調べる際だけ評価されるので、この機能は比較的安定した条件にもっとも適していることに注意してください(特定のバッファー位置それぞれにたいして評価ごとに同じ結果を取得する)。同じのテキスト位置にたいする結果が異なる、つまり結果がポイント位置に依存するようなら、この条件仕様はあなたの望むものではないかもしれません。なぜなら再表示は最後の表示サイクル以降に何かが変更されたといなす理由があるバッファーテキストの部分だけを調べるからです。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.16.5 マージン内への表示

バッファーはその左側と右側にディスプレイマージン(display margins)と呼ばれるブランクエリアをもつことができます。それらのエリア内には通常はテキストが出現することはありませんが、displayプロパティを使用してディスプレイマージン内に何かを配置することができます。現在のところマージン内のテキストやイメージをマウスセンシティブにする方法はありません。

マージン内に何かを表示するにはテキストのdisplayプロパティのマージンディスプレイ仕様(margin display specification)で指定します。これは配置したテキストが表示されないことを意味する置換ディスプレイ仕様です。マージン表示は表示されますがそのテキストは表示されません。

マージンディスプレイ仕様とは((margin right-margin) spec)((margin left-margin) spec)のようなものです。ここでspecはマージン内に何を表示するかを告げる別のディスプレイ仕様です。典型的にはこれは表示するテキスト文字列やイメージディスクリプタです。

特定のバッファーテキストに割り当てられたマージンに何かを表示するためには、そのテキストにbefore-stringプロパティをもつオーバーレイをput、before-stringのコンテンツとしてマージンディスプレイ仕様をputします。

マージン内に表示する文字列がフェイスを指定しなければ、テキストエリア内に表示される文字列に準じたいくつかの規則と優先度によりフェイスが決定されることに注意してください(フェイスの表示を参照)。これが望ましくないマージンへのフェイスの“漏洩”をもたらすようなら、文字列が文字列用に明示的なフェイスを確実にもつようにしてください。

ディスプレイマージンが何かを表示可能になる前に、それらに非0の幅を与えなければなりません。これを行う通常の方法は以下の変数をセットする方法です:

Variable: left-margin-width

この変数は左マージンの幅を文字セル(別名は“列”)単位で指定する。これ、すべてのバッファーでバッファーローカルである。値nilは左マージンエリアなしを意味する。

Variable: right-margin-width

この変数は右マージンの幅を文字セル単位で指定する。これはすべてのバッファーでバッファーローカルである。値nilは右マージンエリアなしを意味する。

これらの変数をセットしてもウィンドウには即座には反映されません。これらの変数はウィンドウ内に新たなバッファーを表示する際にチェックされます。したがってset-window-bufferを呼び出すことにより変更を反映することができます。これらの変数を左右のマージンのカレント幅の判定を試みるために使用してはいけません。かわりに関数window-marginsを使用してください。

マージン幅を即座にセットすることもできます。

Function: set-window-margins window left &optional right

この関数はウィンドウwindowのマージン幅、文字セル単位で指定する。引数leftは左マージン、rightは右マージン(デフォルトは0)を制御する。

期待する幅のマージンを収容するのにwindowが十分大きくなければ、windowのマージンは未変更のままになる。

ここで指定した値はwindowにたいする引数keep-marginsnilか省略したset-window-buffer (バッファーとウィンドウを参照)の呼び出しにより後からオーバーライドされるかもしれない。

Function: window-margins &optional window

この関数はwindowの左マージンと右マージンの幅を(left . right)という形式のコンスセルでリターンする。2つのマージンエリアのいずれか一方が存在しなければ幅はnilでリターンされる。2つのマージンがどちらも存在しなければ、この関数は(nil)をリターンする。windownilなら選択されたウィンドウが使用される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17 イメージ

Emacsバッファー内にイメージを表示するためには最初にイメージディスクリプタを作成して、それを表示されるテキストのdisplayプロパティ(displayプロパティを参照)内のディスプレイ指定子として使用しなければなりません。

Emacsはグラフィカルな端末で実行時には、通常はイメージの表示が可能です。テキスト端末、イメージサポートを欠く特定のグラフィカル端末、またはイメージサポートなしでコンパイルされたEmacsではイメージを表示できません。原則的にイメージが表示可能か判断するためには関数display-images-pを使用できます(ディスプレイ機能のテストを参照)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.1 イメージのフォーマット

Emacsはいくつかの異なるフォーマットのイメージを表示できます。これらのイメージフォーマットのいくつかは、特定のサポートライブラリーがインストールされている場合のみサポートされます。いくつかのプラットフォームではEmacsはオンデマンドでサポートライブラリーをロードできます。そのような場合には、それらの動的ライブラリーにたいする既知の名前セットを変更するために変数dynamic-library-alistを使用できます。動的にロードされるライブラリーを参照してください。

サポートされるイメージフォーマット(と要求されるサポートライブラリー)にはPBMとXBM(サポートライブラリーに依存せず常に利用可能)、XPM (libXpm)、GIF (libgiflibungif)、JPEG (libjpeg)、TIFF (libtiff)、PNG (libpng)、SVG (librsvg)、WebP (libwebp)が含まれます。

これらのイメージフォーマットはそれぞれイメージタイプシンボル(image type symbol)に関連付けられます。上記のフォーマットにたいするシンボルは順にpbmxbmxpmgifjpegtiffpngsvgwebpです。

一部のプラットフォームではオプションのライブラリーを何も要求しないイメージサポートが組み込まれており、それにはBMPイメージも含まれています31

さらにImageMagick(libMagickWand)のサポートつきでEmacsをビルドした場合には、EmacsはImageMagickが表示可能なイメージフォーマットを表示できます。ImageMagickイメージを参照してください。ImageMagickを通じて表示されるすべてのイメージはタイプシンボルimagemagickをもちます。

Variable: image-types

この変数はカレント構成で潜在的にサポートされるイメージフォーマットにたいするタイプシンボルのリストを含む。

“潜在的”とはEmacsがそのイメージタイプを知っていることを意味しており、実際に使用可能である必要はない(たとえば動的ライブラリーが利用できないせいかもしれない)。どのイメージタイプが実際に利用できるか知るためにはimage-type-available-pを使用すること。

Function: image-type-available-p type

この関数はタイプtypeのイメージのロードと表示が可能なら非nilをリターンする。typeはイメージタイプシンボルであること。

サポートライブラリーが静的にリンクされたイメージタイプにたいして、この関数は常にtをリターンする。サポートライブラリーが動的にロードされるイメージタイプにたいしてはライブラリーがロード可能ならt、それ以外ならnilをリターンする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.2 イメージのディスクリプタ

イメージディスクリプタ(image descriptor)とは、イメージにたいする基礎的なデータと表示する方法を指定するリストです。これは通常はオーバーレイプロパティかテキストプロパティdisplay(その他のディスプレイ仕様を参照)の値を通じて使用されますが、バッファーにイメージを挿入する便利なヘルパー関数についてはイメージの表示を参照してください。

イメージディスクリプタはそれぞれ(image . props)という形式をもちます。ここでpropsはキーワードシンボルと値のペアーからなるプロパティリストであり、少なくともそのイメージタイプを指定するペアー:type typeを含みます。

イメージのサイズを定義するイメージディスクリプタ:width:height:max-width:max-heightは整数(サイズをピクセルで表現)、あるいは (value . em)という形式をとります。ここでvalueems32によるサイズの長さ。1emはフォント高さと等しく、valueは整数または浮動小数。

以下はすべてのイメージタイプにたいして意味のあるプロパティのリストです(以降のサブセクションで説明するように特定のイメージタイプにたいしてのみ意味があるプロパティも存在する):

:type type

イメージタイプ。 イメージのフォーマットを参照のこと。 すべてのイメージディスクリプタは。このプロパティを含まなければならない。

:file file

これはファイルfileからイメージをロードすることを意味する。fileが絶対ファイル名でなければ、それはimage-load-pathのディレクトリーそれぞれから相対的に展開される(イメージの定義を参照)。

:data data

これはrawイメージデータを指定する。すべてのイメージディスクリプタは:data:fileのいずれかをもたなければならないが両方もつことはできない。

ほとんどのイメージタイプにたいして、:dataプロパティの値はイメージデータを含む文字列であること。いくつかのイメージタイプは:dataをサポートしない。それ以外のイメージタイプにたいしては:data単独では不十分であり、:dataとともに他のイメージプロパティを使用する必要がある。詳細は以下のサブセクションを参照のこと。

:margin margin

これはイメージ周囲に余分なマージンとして何ピクセル追加するかを指定する。値marginは非負の数値か、そのような数値のペアー(x . y)でなければならない。ペアーならxは水平方向に追加するピクセル数、yは垂直方向に追加するピクセル数を指定する。:marginが指定されない場合のデフォルトは0。

:ascent ascent

これはイメージのアセント(ベースラインの上の部分)に使用するイメージの高さの分量を指定する。値ascentは0から100の数値かシンボルcenterでなければならない。

ascentが数値ならアセントに使用するイメージの高さのパーセンテージであること。

ascentcenterなら、イメージにたいしてテキストプロパティやオーバーレイプロパティにより指定される方法で、センターライン(そのイメージ位置にテキストを描画する際の垂直方向のセンターライン)の垂直方向中心にイメージが配置される。

このプロパティが省略された場合のデフォルトは50。

:relief relief

これはイメージ周辺にシャドー矩形を追加する。値reliefはシャドーライン幅をピクセルで指定する。reliefが負ならボタンを押下した状態、それ以外はボタンを押下していない状態のイメージでシャドーを描画する。

:width width, :height height

キーワード:width:heightはイメージのスケーリングに使用される。いずれか一方のみが指定された場合には、アスペクト比を保つためにもう一方が算出される。両方が指定された場合にはアスペクト比は保たれないかもしれない。

:max-width max-width, :max-height max-height

キーワード:max-width:max-heightは、イメージのサイズがこれらの値を超過した場合のスケーリングに使用される。:widthがセットされた場合にはmax-widthより優先されて、:heightがセットされた場合にはmax-heightより優先されるだろうが、それ以外ではこれらのキーワードを望むように混交できる。

:max-width:heightが指定されていて:widthが未指定なら、アスペクト比を維持することにより:max-widthを超える幅が要求されるかもしれない。これが発生した場合には、スケーリングは:max-widthを超過しないアスペクト比を維持できるように、小さい値を使用する。:max-height:widthが指定されていて:heightが未指定のときも同様。たとえば200x100のイメージがあり:widthを400、:max-heightを150に指定すると、アスペクト比を保持しつつ“max”のセッティングを超過しないようにイメージは最終的には300x150になる。このパラメーターの組み合わせは、“可能なかぎり大きく、ただし利用可能なディスプレイエリア以下でこのイメージを表示せよ”のように指示する簡便な手段である。

:scale scale

これは数字であること。1より大きい値は幅および高さを乗じたサイズの増加、小さい値はサイズの減少を意味する。たとえば値0.25はイメージをオリジナルの1/4のサイズにするだろう。このスケーリングにより:max-width:max-heightで指定されたイメージの元のサイズより大きくなる場合でも、結果サイズがこれら2つの値を超過することはない。:scaleおよび:height/:widthの両方が指定されたら、高さ/幅は指定されたスケーリング倍率に調整される。

:rotation angle

ローテーション角度を度数(degree)で指定する。イメージタイプがimagemagickでなければ、90°の倍数のみをサポート。値が正なら時計回り、負なら反時計回り。ローテーションはスケーリングとクロッピング(cropping: 切り取り、抜き出し)の後に行われる。

:flip flip

tならイメージを水平方向に反転(flip)する。現在のところイメージタイプがimagemagickなら効果はない。垂直方向の反転はイメージの180度回転とこの値を切り替えることによって行われている。

:transform-smoothing smooth

これがtならイメージ変換にスムージングを適用、nilならスムージングを適用しない。使用する正確なアルゴリズムはプラットフォームに依存するが、バイリニアフィルタリング(bilinear filtering)と等価であること。スムージングを無効にすると、もっとも近い類似アルゴリズムを使用する。

このプロパティが未指定なら、create-imageはスケーリングするかしないかを指示するために、ユーザーオプションimage-transform-smoothingを使用する。このオプションはnil (スムージングなし)、t (スムージングを使用)、またはイメージオブジェクトを唯一のパラメーターとして呼び出されてniltをリターンする述語関数であること。デフォルトではダウンスケーリングにはスムージングを適用、巨大なアップスケーリングにはスムージングを適用しない。

:index frame

マルチフレームのイメージを参照のこと。

:conversion algorithm

これはイメージを表示する前に適用するべき変換アルゴリズムを指定する。値algorithmは何のアルゴリズムかを指定する。

laplace
emboss

カラーの大きな差異を強調して小さな差異を不鮮明にするラプラスエッジ検出アルゴリズム(Laplace edge detection algorithm)を指定する。無効なボタンのイメージ表示に、これが役立つと考える人もいます。

(edge-detection :matrix matrix :color-adjust adjust)

一般的なエッジ検出アルゴリズムを指定する。matrixは数値からなる9要素のリストかベクターでなければならない。変換されたイメージ内の位置x/yにあるピクセルは、その位置周辺にある元のピクセルから計算される。matrixx/yに近接する各ピクセルにたいして、そのピクセルが変換先ピクセルに影響するファクター(factor: 要因)を指定する。以下のように要素0x-1/y-1にあるピクセルのファクター、要素1x/y-1にあるピクセルにたいするファクター、...を指定する。

  (x-1/y-1  x/y-1  x+1/y-1
   x-1/y    x/y    x+1/y
   x-1/y+1  x/y+1  x+1/y+1)

結果となるピクセルは周辺ピクセルのRGB値を合計したカラーを指定されたファクターで乗じて、その合計をファクター絶対値の合計で除した色強度から計算される。

ラプラスエッジ検出は現在のところは以下のマトリクス

  (1  0  0
   0  0  0
   0  0 -1)

エンボスエッジ検出(Emboss edge-detection)は以下のマトリクスを使用する

  ( 2 -1  0
   -1  0  1
    0  1 -2)
disabled

イメージが無効(disabled)に見えるよう変換することを指定する。

:mask mask

maskheuristic(heuristic bg)なら、フレームのバックグラウンドがイメージ背後に見えるようにイメージのクリッピングマスクを構築する。bgが未指定かtなら、イメージ4隅に最頻するカラーをそのイメージのバックグラウンドカラーとみなしてバックグラウンドカラーを決定する。それ以外ならbgはイメージのバックグラウンドとみなすべきカラーを指定するリスト(red green blue)でなければならない。

masknilなら、イメージがマスクをもつ場合にはマスクを削除する。マスクを含むフォーマットのイメージは:mask nilを指定することにより削除される可能性がある。

:pointer shape

これはマウスポインターがそのイメージ上にある際のポインターシェイプを指定する。利用可能なポインターシェイプについてはポインターの形状を参照のこと。

:map map

これはイメージにホットスポット(hot spots)のイメージマップを関連付ける。

イメージマップは各要素が(area id plist)という形式をもつalist。areaにはrectangle(矩形)、circle(円)、またはpolygon(ポリゴン、多角形)のいずれかを指定する。

rectangleは矩形エリアの左上隅と右下隅のピクセル座標を指定するコンス(rect . ((x0 . y0) . (x1 . y1)))

circleは円の中心と半径を指定するコンス(circle . ((x0 . y0) . r))rは整数か浮動小数点数。

polygonは各ペアーが多角形の1つの頂点を記述するコンス(poly . [x0 y0 x1 y1 ...])

マウスポインターがホットスポット上にある際には、ホットスポットのplistが参照される。これがhelp-echoプロパティを含むならそのホットスポットのツールチップ、pointerプロパティを含む場合はマウスカーソルがホットスポット上にあるときのマウスカーソルのシェイプを指定する。利用可能なポインターシェイプについてはポインターの形状を参照のこと。

マウスポインターがホットスポット上にあるときにマウスをクリックしたときのイベントは、ホットスポットのidとマウスイベントを組み合わせて構成される。たとえばホットスポットのidarea4なら[area4 mouse-1]

このマップの座標はすべての変換(ローテーション、スケーリング等)の後に表示されたイメージを反映する必要があり、更に(デフォルトでは)Emacsの行う自動スケーリングの効果もあるので、イメージ作成時には:scale 1.0を指定するか、マップ要素の計算にimage-compute-scaling-factorの結果を用いる必要があることにも注意。

Function: image-mask-p spec &optional frame

この関数はイメージspecがマスクビットマップをもつならtをリターンする。frameはそのイメージが表示されるフレーム。framenilか省略された場合には選択されたフレームが使用される(入力のフォーカスを参照)。

Function: image-transforms-p &optional frame

この関数はframeがイメージのスケーリングとローテーションをサポートすれば非nilをリターンする。framenilか省略なら選択されたフレームの使用を意味する(入力のフォーカスを参照)。リターンされるリストには何のイメージ変換操作がサポートされるかを示すシンボルが含まれる:

scale

frame:scale:width:height:max-width:max-heightのプロパティを通じたイメージスケーリングをサポートする。

rotate90

frameはローテーション角度が90°の整数倍ならイメージローテーションをサポートする。

イメージ変換がサポートされていなければ:rotation:crop:width:height:scale:max-width:max-heightは(利用可能なら)ImageMagickを通じた場合のみ使用可能(ImageMagickイメージを参照)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.3 XBMイメージ

XBMフォーマットを使用するにはイメージタイプとしてxbmを指定します。このイメージフォーマットは外部ライブラリーを要求せず、このタイプのイメージは常にサポートされます。

xbmイメージタイプにたいして追加のイメージプロパティがサポートされます:

:foreground foreground

foregroundはそのイメージのフォアグラウンドカラーを指定する文字列、またはデフォルトカラーを指定するnilであること。このカラーはXBM内の1の各ピクセルに使用される。デフォルトはフレームのフォアグラウンドカラー。

:background background

backgroundはそのイメージのバックグラウンドカラーを指定する文字列、またはデフォルトカラーを指定するnilであること。このカラーはXBM内の0の各ピクセルに使用される。デフォルトはフレームのバックグラウンドカラー。

外部ファイルのかわりにEmacs内のデータを指定してXBMイメージを指定するには以下の3つのプロパティを使用する:

:data data

dataはイメージのコンテンツを指定する。dataとして使用できる3つのフォーマットが存在する:

  • それぞれがイメージの1ラインを指定するような文字列ベクターかboolベクター。:data-height:data-widthを指定する。
  • XBMファイルに含まれるであろうバイトシーケンスと同じものを含んだ文字列。
  • イメージのビットを含む文字列かboolベクター(終端の使用されない余分なビットを含むかもしれない)。少なくともstride * heightビットを含むこと(strideはイメージ幅以上の8の最小倍数)。この場合にはその文字列がXBMファイル全体ではなく、単にビットだけを含むことを示すとともに、そのイメージのサイズを指定するために:data-height:data-width:strideを指定する必要がある。
:stride stride

各行に格納さたブールベクターのエントリー数(width以上の8の最小倍数)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.4 XPMイメージ

XPMフォーマットを使用するにはイメージタイプにxpmを指定します。xpmイメージタイプでは追加のプロパティ:color-symbolsにも意味があります。

:color-symbols symbols

symbolsは要素が(name . color)という形式をもつようなalistであること。各要素においてnameはイメージファイル内に出現するカラー名、colorはそのカラー名の実際の表示に使用するカラーを指定する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.5 ImageMagickイメージ

ImageMagickのサポートつきのEmacsビルドでは、多くくのイメージフォーマットをロードするためにImageMagickライブラリーを使用できます(File Conveniences in The GNU Emacs Manualを参照)。ImageMagickを通じてロードしたイメージのイメージタイプシンボルは、基礎となる実際のイメージフォーマットとは無関係にimagemagickになります。

ImageMagickサポートをチェックするには以下を使用してください:

(image-type-available-p 'imagemagick)
Function: imagemagick-types

この関数はカレントのImageMagickインストールによりサポートされるイメージファイル拡張子のリストをリターンする。リストの各要素は.bmpイメージはBMPのような、イメージタイプにたいして内部的なImageMagick名を表すシンボル。

User Option: imagemagick-enabled-types

この変数の値はEmacsがImageMagickを使用してレンダリングを試みるかもしれないImageMagickイメージタイプのリスト。リストの各要素はimagemagick-typesがリターンするリスト内のシンボルのいずれか、または等価な文字列。もしくは値tはImageMagickにたいして利用できるすべてのイメージタイプを有効にする。この変数の値とは関係なくimagemagick-types-inhibit (以下参照)が優先される。

User Option: imagemagick-types-inhibit

この変数の値はimagemagick-enabled-typesの値とは無関係に、ImageMagickを使用して決してレンダリングされることのないImageMagickイメージタイプのリスト。値tはImageMagickを完全に無効にする。

Variable: image-format-suffixes

この変数はイメージタイプをファイル名拡張子にマッピングするalist。EmacsはImageMagickライブラリーにイメージのタイプに関するヒントを与えるために、この変数と:formatイメージプロパティ(以下参照)を組み合わせて使用する。各要素は(type extension)という形式をもちtypeはイメージのcontent-typeを指定するシンボル、extensionは関連付けられるファイル名拡張子を指定する文字列。

ImageMagickによりロードされたイメージは、追加で以下のイメージディスクリプタプロパティをサポートします:

:background background

backgroundが非nilなら、カラーを指定する文字列であること。これはイメージが透明度をサポートする場合に、イメージのバックグラウンドカラーとして使用される。値がnilの場合のデフォルトはフレームのバックグラウンドカラー。

:format type

typeimage-format-suffixesで見られるような、イメージのタイプを指定するシンボルであること。これはイメージが関連付けられたファイル名をもたない際に、イメージタイプを検出する助けとなるヒントをImageMagickに提供する。

:crop geometry

geometryの値は(width height x y)という形式のリストであること。widthheightはクロップするイメージの幅と高さを指定する。xが正の数値なら元イメージの左エッジ、負の数値なら右エッジからクロップのオフセットを指定する。yが正の数値なら元イメージの上エッジ、負の数値なら下エッジからクロップのオフセットを指定する。xynilか未指定ならクロップ領域は元イメージの中央になる。

クロップ領域がイメージ外部、またはエッジとオーバーラップする場合には、イメージ外部の全領域を除外するように縮小される。これはwidthheightに大きな値を与えてイメージサイズを増加するために:cropを使用できないことを意味する。

クロッピングはスケーリング後、ローテーション前に行われる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.6 SVGイメージ

SVG (Scalable Vector Graphics: 変倍ベクタ図形)はイメージを指定するためのXMLフォーマットです。SVGイメージは、追加で以下のイメージディスクリプタプロパティをサポートします:

:foreground foreground

foregroundが非nilなら、カラーを指定する文字列であること。これはイメージのフォアグラウンドカラーとして使用される。値がnilの場合のデフォルトはカレントフェイスのフォアグラウンドカラー。

:background background

backgroundが非nilなら、カラーを指定する文字列であること。これはイメージが透明度をサポートする場合に、イメージのバックグラウンドカラーとして使用される。値がnilの場合のデフォルトはカレントフェイスのバックグラウンドカラー。

:css css

cssが非nilなら、イメージ生成時に使用されるデフォルトCSSをオーバーライドするCSSを指定する文字列であること。

SVG library

SVGサポートつきでEmacsがビルドされていれば、以下のsvg.elライブラリー由来の関数でこれらのイメージの作成や操作ができます。

Function: svg-create width height &rest args

指定したサイズで新たにSVGイメージを作成する。argsはplist引数であり、以下を指定できる:

:stroke-width

作成するすべてのラインのデフォルト幅(ピクセル単位)。

:stroke

作成するすべてのラインのデフォルトのストロークカラー。

この関数はSVGオブジェクト (SVGイメージを指定するLispデータ構造)をリターンする。以下の関数はすべてこのブジェクトにたいして機能する。以下の関数の引数svgはこのようなSVGオブジェクトを指定する。

Function: svg-gradient svg id type stops

svgに識別子idでグラデーションを作成する。typeはグラデーションタイプでlinearradialのいずれかを指定する。stopsはパーセント割合/カラーのペアからなるリスト。

以下は最初の赤から25%の緑、最後は青に至る線形グラデーションを作成する:

(svg-gradient svg "gradient1" 'linear
              '((0 . "red") (25 . "green") (100 . "blue")))

作成(およびSVGオブジェクトに挿入)されたグラデーションは、後でシェイプを作成するすべての関数で使用できる。

以下の関数はすべてさまざまな属性のデフォルト値を変更するオプションのキーワードパラメーターを受け取ります。有効な属性には以下が含まれます:

:stroke-width

ラインとソリッドシェイプ枠線の描画幅(ピクセル単位)。

:stroke-color

ラインとソリッドシェイプ枠線の描画カラー。

:fill-color

ラインとソリッドシェイプに使用するカラー。

:id

シェイプの識別子。

:gradient

与えられた場合には以前に定義されたグラデーションオブジェクトの識別子であること。

:clip-path

クリックパスの識別子。

Function: svg-rectangle svg x y width height &rest args

左上隅が位置x/y、サイズがwidth/heightの矩形をsvgに追加する。

(svg-rectangle svg 100 100 500 500 :gradient "gradient1")
Function: svg-circle svg x y radius &rest args

中央が位置x/y、半径がradiusの円をsvgに追加する。

Function: svg-ellipse svg x y x-radius y-radius &rest args

中央が位置x/y、水平半径がx-radius、垂直半径がy-radiusの楕円をsvgに追加する。

Function: svg-line svg x1 y1 x2 y2 &rest args

始点がx1/y1、終点がx2/y2の線をsvgに追加する。

Function: svg-polyline svg points &rest args

points (XとYの位置ペアのリスト)を通過する複数セグメントラライン、いわゆる“ポリゴン(polyline)”をsvgに追加する。

(svg-polyline svg '((200 . 100) (500 . 450) (80 . 100))
              :stroke-color "green")
Function: svg-polygon svg points &rest args

ポリゴン外周の位置XとYのペアからなるリストであるようなpointsにより記述されるポリゴンをsvgに追加する。

(svg-polygon svg '((100 . 100) (200 . 150) (150 . 90))
             :stroke-color "blue" :fill-color "red")
Function: svg-path svg commands &rest args

commandsに応じてsvgにシェイプのアウトラインを追加する。SVG Path Commandsを参照のこと。

デフォルトでは絶対座標。最後(または最初)の位置を基準に相対座標を指定するには、属性:relativetをセットする。この属性は関数や個々のcommandsにたいして指定できる。関数に指定された場合には、すべてのcommandsはデフォルトで相対座標を使用する。個々のcommandsに絶対座標を使用させるなら、:relativenilをセットする。

(svg-path svg
	  '((moveto ((100 . 100)))
	    (lineto ((200 . 0) (0 . 200) (-200 . 0)))
	    (lineto ((100 . 100)) :relative nil))
	  :stroke-color "blue"
	  :fill-color "lightblue"
	  :relative t)
Function: svg-text svg text &rest args

指定したtextsvgに追加する。

(svg-text
 svg "This is a text"
 :font-size "40"
 :font-weight "bold"
 :stroke "black"
 :fill "white"
 :font-family "impact"
 :letter-spacing "4pt"
 :x 300
 :y 400
 :stroke-width 1)
Function: svg-embed svg image image-type datap &rest args

埋め込みの(ラスター)イメージをsvgに追加する。datapnilならimageはファイル名、それ以外ならimageはイメージデータをrawバイトとして含む文字列であること。image-type"image/jpeg"のようなMIMEイメージタイプであること。

(svg-embed svg "~/rms.jpg" "image/jpeg" nil
           :width "100px" :height "100px"
           :x "50px" :y "75px")
Function: svg-embed-base-uri-image svg relative-filename &rest args

svgrelative-filenameにある埋め込み(ラスター)イメージを追加する。relative-filenameはsvgのイメージプロパティ:base-urifile-name-directory内部で検索される。:base-uriは作成する(存在しないかもしれない)svgイメージのファイル名を指定するので、すべての埋め込みファイルは:base-uriファイル名の電子に相対的に検索される。:base-uriが省略された場合には、svgイメージをロードするファイル名を使用する。svg-embedと比較してlibrsvgが処理を直接行うので、:base-uriの使用は巨大なイメージの埋め込みの効率を改善する。

;; Embedding /tmp/subdir/rms.jpg and /tmp/another/rms.jpg
(svg-embed-base-uri-image svg "subdir/rms.jpg"
           :width "100px" :height "100px"
           :x "50px" :y "75px")
(svg-embed-base-uri-image svg "another/rms.jpg"
           :width "100px" :height "100px"
           :x "75px" :y "50px")
(svg-image svg :scale 1.0
           :base-uri "/tmp/dummy"
           :width 175 :height 175)
Function: svg-clip-path svg &rest args

svgにクリッピングパスを追加する。:clip-pathプロパティを通じてシェイプに適用された場合には、クリッピング外部のシェイプ部分は描画されない。

(let ((clip-path (svg-clip-path svg :id "foo")))
  (svg-circle clip-path 200 200 175))
(svg-rectangle svg 50 50 300 300
               :fill-color "red"
               :clip-path "url(#foo)")
Function: svg-node svg tag &rest args

カスタムノードtagsvgに追加する。

(svg-node svg
          'rect
          :width 300 :height 200 :x 50 :y 100 :fill-color "green")
Function: svg-remove svg id

svgから識別子idの要素を取り除く。

Function: svg-image svg

最後にsvg-imageは引数としてSVGを受け取り、insert-imageのような関数での使用に適したイメージオブジェクトをリターンする。

以下は円のイメージを作成して挿入する完全な例です:

(let ((svg (svg-create 400 400 :stroke-width 10)))
  (svg-gradient svg "gradient1" 'linear '((0 . "red") (100 . "blue")))
  (svg-circle svg 200 200 100 :gradient "gradient1"
                  :stroke-color "green")
  (insert-image (svg-image svg)))

SVG Path Commands

SVGパス(SVG paths)によりライン(lines: 線)、カーブ(curves: 曲線)、アーク(arcs: 円弧)、またはその他の基本的なシェイプを組み合わせて複雑なイメージを作成できます。以下に説明する関数でLispプログラムからSVGパスコマンドを呼び出すことができます。

Command: moveto points

pointsの最初のポイントにペンを移動する。それ以降のポイントはラインで接続される。pointsはXY座標ペアのリスト。後続のmovetoコマンドは新たなサブパス(subpath)の開始を表す。

(svg-path svg '((moveto ((200 . 100) (100 . 200) (0 . 100))))
          :fill "white" :stroke "black")
Command: closepath

サブパスの初期ポイントに接続することによりカレントのサブパスを終了する。ラインは接続に沿って描画される。

(svg-path svg '((moveto ((200 . 100) (100 . 200) (0 . 100)))
                (closepath)
                (moveto ((75 . 125) (100 . 150) (125 . 125)))
                (closepath))
          :fill "red" :stroke "black")
Command: lineto points

カレントのポイントからpoints (XY位置ペアのリスト)の最初の要素にラインを描画する。複数ポイントを指定するとポリライン(polyline: 折れ線)を描画する。

(svg-path svg '((moveto ((200 . 100)))
                (lineto ((100 . 200) (0 . 100))))
          :fill "yellow" :stroke "red")
Command: horizontal-lineto x-coordinates

カレントポイントからx-coordinatesの最初の要素へ水平ラインを描画する。通常は無意味だが複数座標の指定は可能。

(svg-path svg '((moveto ((100 . 200)))
                (horizontal-lineto (300)))
          :stroke "green")
Command: vertical-lineto y-coordinates

垂直ラインを描画する。

(svg-path svg '((moveto ((200 . 100)))
                (vertical-lineto (300)))
          :stroke "green")
Command: curveto coordinate-sets

coordinate-setsの最初の要素を使用して、カレントポイントからベジェ曲線(cubic Bézier curve)を描画する。複数の座標セットがあればポリベジェ(polybezier: 複数のベジェ曲線)を描画する。座標セットはそれぞれ(x1 y1 x2 y2 x y)という形式のリストであり、(xy)はカーブの終点。(x1y1)と(x2y2)はそれぞれ先頭ポイントと終点ポイントを制御する。

(svg-path svg '((moveto ((100 . 100)))
                (curveto ((200 100 100 200 200 200)
                          (300 200 0 100 100 100))))
          :fill "transparent" :stroke "red")
Command: smooth-curveto coordinate-sets

coordinate-setsの最初の要素を使用して、カレントポイントから三次ベジェ曲線(cubic Bézier curve)を描画する。複数の座標セットがあればポリベジェ(polybezier: 複数のベジェ曲線)を描画する。座標セットはそれぞれ(x2 y2 x y)という形式のリストであり、(xy)はカーブの終点、(x2y2)は対応するコントロールポイント。前のコマンドがcurvetosmooth-curvetoなら、そのコマンドの2つ目のコントロールポイントのカレントポイントから相対的なリフレクション(reflection)。それ以外なら最初のコントロールポイントはカレントポイントと一致する。

(svg-path svg '((moveto ((100 . 100)))
                (curveto ((200 100 100 200 200 200)))
                (smooth-curveto ((0 100 100 100))))
          :fill "transparent" :stroke "blue")
Command: quadratic-bezier-curveto coordinate-sets

coordinate-setsの最初の要素を使用して、カレントポイントから二次ベジェ曲線(quadratic Bézier curve)を描画する。複数の座標セットがあればポリベジェ(polybezier: 複数のベジェ曲線)を描画する。座標セットはそれぞれ(x1 y1 x y)という形式のリストであり、(xy)はカーブの終点、(x1y1)はコントロールポイント。

(svg-path svg '((moveto ((200 . 100)))
                (quadratic-bezier-curveto ((300 100 300 200)))
                (quadratic-bezier-curveto ((300 300 200 300)))
                (quadratic-bezier-curveto ((100 300 100 200)))
                (quadratic-bezier-curveto ((100 100 200 100))))
          :fill "transparent" :stroke "pink")
Command: smooth-quadratic-bezier-curveto coordinate-sets

coordinate-setsの最初の要素を使用して、カレントポイントから二次ベジェ曲線(quadratic Bézier curve)を描画する。複数の座標セットがあればポリベジェ(polybezier: 複数のベジェ曲線)を描画する。座標セットはそれぞれ(x y)という形式のリストであり、(xy)はカーブの終点。前のコマンドがquadratic-bezier-curvetosmooth-quadratic-bezier-curvetoなら、そのコマンドのコントロールポイントのカレントポイントから相対的なリフレクション(reflection)。それ以外なら最初のコントロールポイントはカレントポイントと一致する。

(svg-path svg '((moveto ((200 . 100)))
                (quadratic-bezier-curveto ((300 100 300 200)))
                (smooth-quadratic-bezier-curveto ((200 300)))
                (smooth-quadratic-bezier-curveto ((100 200)))
                (smooth-quadratic-bezier-curveto ((200 100))))
          :fill "transparent" :stroke "lightblue")
Command: elliptical-arc coordinate-sets

coordinate-setsの最初の要素を使用して、カレントポイントから楕円弧(elliptical arc)を描画する。複数の座標セットがあれば一連の楕円弧を描画する。座標セットはそれぞれ(rx ry x y)という形式のリストであり、(xy)は楕円の終点、(rxry)は楕円の半径。リストに属性を追加できる:

:x-axis-rotation

カレントの座標システムのX軸から相対的にローテートされた楕円X軸の度数角度。

:large-arc

tにセットすると、180°以上のアークスイープ(arc sweep)を描画する。それ以外なら180°以下のアークスイープを描画する。

:sweep

tにセットすると正の角度方向(positive angle direction)、それ以外なら負の角度方向(negative angle direction)にアークを描画する。

(svg-path svg '((moveto ((200 . 250)))
                (elliptical-arc ((75 75 200 350))))
          :fill "transparent" :stroke "red")
(svg-path svg '((moveto ((200 . 250)))
                (elliptical-arc ((75 75 200 350 :large-arc t))))
          :fill "transparent" :stroke "green")
(svg-path svg '((moveto ((200 . 250)))
                (elliptical-arc ((75 75 200 350 :sweep t))))
          :fill "transparent" :stroke "blue")
(svg-path svg '((moveto ((200 . 250)))
                (elliptical-arc ((75 75 200 350 :large-arc t
                                     :sweep t))))
          :fill "transparent" :stroke "gray")
(svg-path svg '((moveto ((160 . 100)))
                (elliptical-arc ((40 100 80 0)))
                (elliptical-arc ((40 100 -40 -70
                                     :x-axis-rotation -120)))
                (elliptical-arc ((40 100 -40 70
                                     :x-axis-rotation -240))))
          :stroke "pink" :fill "lightblue"
          :relative t)

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.7 その他のイメージタイプ

PBMイメージにはイメージタイプpbmを指定します。カラー、グレースケール、およびモノクロのイメージがサポートされます。モノクロのPBMイメージにたいしては、2つの追加イメージプロパティがサポートされます。

:foreground foreground

foregroundはイメージのフォアグラウンドカラーを指定する文字列、またはデフォルトカラーならnilであること。このカラーはPBM内の1であるようなピクセルすべてに使用される。デフォルトはフレームのフォアグラウンドカラー。

:background background

backgroundはイメージのバックグラウンドカラーを指定する文字列、またはデフォルトカラーならnilであること。このカラーはPBM内の0であるようなピクセルすべてに使用される。デフォルトはフレームのバックグラウンドカラー。

Emacsがサポート可能な残りのイメージタイプは以下のとおり:

GIF

イメージタイプgif:indexプロパティをサポートする。マルチフレームのイメージを参照のこと。

JPEG

イメージタイプjpeg

PNG

イメージタイプpng

TIFF

イメージタイプtiff:indexプロパティをサポートする。マルチフレームのイメージを参照のこと。

WebP

イメージタイプwebp


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.8 イメージの定義

関数create-imagedefimagefind-imageはイメージディスクリプタを作成するための便利な手段を提供します。

Function: create-image file-or-data &optional type data-p &rest props

この関数はfile-or-data内のデータを使用するイメージディスクリプタを作成してリターンする。file-or-dataはファイル名、またはイメージデータを含む文字列を指定できる。前者ならdata-pnil、後者なら非nilであること。file-or-dataが相対ファイル名なら、この関数はimage-load-pathにセットされているディレクトリーにたいして検索を行う。

オプション引数typeはイメージタイプを指定するシンボル。typeが省略かnilなら、create-imageはファイル先頭の数バイトかファイル名からイメージタイプの判断を試みる。

残りの引数propsは追加のイメージプロパティを指定する。たとえば、

(create-image "foo.xpm" 'xpm nil :heuristic-mask t)

この関数はそのタイプのイメージがサポートされていなければnil、それ以外ならイメージディスクリプタをリターンする。

Macro: defimage symbol specs &optional doc

このマクロはイメージマクロとしてsymbolを定義する。引数specsはイメージの表示方法を指定するリストである。3つ目の引数docはオプションのドキュメント文字列。

specs内の各要素はプロパティリストの形式をもち、それぞれが少なくとも:typeプロパティと、:file:dataいずれかのプロパティをもつこと。:typeの値はイメージタイプを指定するシンボル、:fileの値はイメージをロードするファイル、:dataの値は実際のイメージデータを含む文字列であること。以下は例:

(defimage test-image
  ((:type xpm :file "~/test1.xpm")
   (:type xbm :file "~/test1.xbm")))

defimageはそれが使用可能か、つまりそのタイプがサポートされているかとファイルが存在するかを確認するために各要素を1つずつテストする。最初に使用可能な引数がsymbol内に格納するイメージディスクリプタを作成するために使用される。

機能する候補がなければsymbolnilとして定義される。

Function: image-property image property

imagepropertyの値をリターンする。プロパティはsetfを使用してセットできる。プロパティにnilをセットすることによりイメージからプロパティを削除できる。

Function: find-image specs

この関数はイメージ仕様specsのリストの1つを満足するイメージを探すための、便利な手段を提供する。

specs内の各仕様はイメージタイプに応じた内容のプロパティリストである。すべての仕様は少なくとも:type type、および:file file:data dataのいずれかのプロパティを含まなければならない。ここでtypexbmのようにイメージタイプを指定するシンボル、fileはイメージをロードするファイル、dataは実際のイメージデータを含む文字列。このリスト内でtypeがサポートされていて、かつfileが存在する最初の仕様が、リターンされるイメージ仕様の構築に使用される。満足する仕様がなければnilがリターンされる。

イメージはimage-load-path内で検索される。

User Option: image-load-path

この変数の値はイメージファイルを検索する場所のリスト。要素が文字列か値が文字列であるような変数シンボルなら、その文字列が検索を行うディレクトリーの名前になる。値がリストであるような変数シンボルの場合、それは検索を行うディレクトリーのリストとなる。

デフォルトではdata-directoryで指定されたディレクトリーのサブディレクトリーimages、次にdata-directoryで指定されたディレクトリー、最後にload-pathで指定されたディレクトリー内を検索する。サブディレクトリーは自動的には検索に含まれないので、イメージファイルをサブディレクトリー内に配置した場合には、サブディレクトリーを明示的に与える必要がある。たとえばdata-directory内でイメージimages/foo/bar.xpmを見つけるには以下のようにそのイメージを指定すること:

(defimage foo-image '((:type xpm :file "foo/bar.xpm")))
Function: image-load-path-for-library library image &optional path no-error

この関数はLispパッケージlibraryにより使用されるイメージにたいして適切な検索パスをリターンする。

この関数はまずimage-load-path (data-directory/imagesを除外)を使用し、次にload-pathの後にlibraryにとって適切なパス(ライブラリーファイル自身にたいする相対パス../../etc/images../etc/imagesを含む)を補い、最後にdata-directory/imagesからimageを検索する。

それからこの関数は先頭にimageが見つかったディレクトリー、その後にload-pathの値が続くディレクトリーのリストをリターンする。pathが与えられたらload-pathのかわりに使用する。

no-errorが非nil、かつ適切なパスが見つからない場合にはエラーをシグナルしない。かわりに前記のディレクトリーリストをリターンするが、イメージのディレクトリーの箇所にnilが出現する点が異なる。

以下はimage-load-path-for-libraryの使用例:

(defvar image-load-path) ; shush compiler
(let* ((load-path (image-load-path-for-library
                    "mh-e" "mh-logo.xpm"))
       (image-load-path (cons (car load-path)
                              image-load-path)))
  (mh-tool-bar-folder-buttons-init))

イメージはimage-scaling-factor変数にもとづいて作成時に自動的にスケーリングされます。この値は浮動小数点数(1より大きい値はサイズの拡大、小さい値はサイズの縮小を意味する)、またはフォントのピクセルサイズにもとづいたスケーリング倍率で計算を行うシンボルautoのいずれかです。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.9 イメージの表示

自分でdisplayプロパティをセットアップしてイメージディスクリプタを使用できますが、このセクションの関数を使用するほうがより簡単です。

Function: insert-image image &optional string area slice inhibit-isearch

この関数はカレントバッファーのポイント位置にimageを挿入する。imageはイメージディスクリプタであること。これはcreate-imageによりリターンされた値、またはdefimageで定義されたシンボルの値を使用できる。引数stringはイメージを保持するためにバッファー内に配置するテキストを指定する。これが省略かnilなら、insert-imageはデフォルトで" "を使用する。

引数areaはマージン内にイメージを置くかどうかを指定する。これがleft-marginなら左マージンにイメージが表示され、right-marginなら右マージンを指定する。areanilか省略なら、イメージはバッファーのテキスト内のポイント位置に表示される。

引数sliceは挿入するイメージのスライスを指定する。slicenilか省略された場に合はイメージ全体が挿入される(ただしイメージの折り返しはサポートされていないのでイメージはウィンドウ右端で切り詰められることに注意)。それ以外では、sliceがリスト(x y width height)ならxyは位置、widthheightは挿入するイメージの領域を指定する。整数値はピクセル単位。0.0から1.0までの浮動小数点数はイメージ全体の幅や高さにたいする割合を指定する。

この関数は内部的にはバッファー内にstringを挿入して、imageを指定するdisplayプロパティを渡す。displayプロパティを参照のこと。デフォルトではそのバッファーでのインタラクティブな検索ではstringを考慮して検索が行われる。この挙動はinhibit-isearchg非nilなら抑制される。

Function: insert-sliced-image image &optional string area rows cols

この関数はinsert-imageと同様にカレントバッファー内にimageを挿入するが、イメージをrowscolsの同一サイズのスライスに分割する点が異なる。

Emacsは各スライスを個別のイメージとして表示して、(巨大な)イメージを表示するバッファーのページングの際にイメージ全体を上下にジャンプするのではなく、より直感的な上下スクロールが可能になる。

Function: put-image image pos &optional string area

この関数はカレントバッファー内のposの前にイメージimageを配置する。引数posは整数かマーカーであること。これはイメージが表示されるべきバッファー位置を指定する。引数string (デフォルトは‘x’)は、代替となるイメージを保持するテキストであること。

引数imageはイメージディスクリプタでなければならず、それはcreate-imageがリターンされたか、あるいはdefimageにより格納されたイメージディスクリプタかもしれない。

引数areaはマージン内にイメージを置くかどうかを指定する。これがleft-marginなら左マージンにイメージが表示され、right-marginなら右マージンを指定する。areanilか省略なら、イメージはバッファーのテキスト内のポイント位置に表示される。

内部的には、この関数はオーバーレイを作成して、値がそのイメージであるようなdisplayプロパティをもつテキストを含む、before-stringプロパティをそのオーバーレイに与えている(ふう! やっと説明できました…)。

Function: remove-images start end &optional buffer

この関数はbufferの位置startendの間のイメージを削除する。bufferが省略かnilならカレントバッファーからイメージを削除する。

これはput-imageが行う方法でbufferに配置されたイメージだけを削除して、insert-imageや他の方法で挿入されたイメージは削除しない。

Function: image-size spec &optional pixels frame

この関数はペアー(width . height)としてイメージのサイズをリターンする。specはイメージspec。pixelsが非nilならピクセル単位、それ以外ならframeのデフォルトの文字サイズ単位で量ったサイズをリターンする(フレームのフォントを参照)。frameはイメージが表示されるフレーム。framenilまたは省略された場合には選択されたフレームを使用する(入力のフォーカスを参照)。

Variable: max-image-size

この変数はEmacsがロードするイメージの最大サイズを定義するために使用される。Emacsはこの制限より大きいイメージのロード(と表示)を拒絶するだろう。

値が整数ならピクセル単位で量ったイメージの最大の高さと幅を直接指定する。浮動小数点数ならフレームの高さと幅にたいする比率として、イメージの最大の高さと幅を指定する。値が数値でなければイメージサイズにたいする明示的な制限は存在しない。

この変数の目的は意図せずEmacsに不当に大きなイメージがロードされるとを防ぐことである。これはイメージの初回ロード時だけ効果がある。イメージが一度イメージキャッシュに置かれると、その後にmax-image-sizeの値が変更されても、そのイメージは常に表示可能である(イメージキャッシュを参照)。

Function: image-at-point-p

この関数はポイントがイメージ上にあればt、それ以外はnilをリターンする。

上記の挿入関数で挿入されたイメージは、表示されたイメージを横断するテキスト(またはオーバーレイ)のプロパティ内にインストールされたローカルキーマップも取得します。このキーマップは以下のコマンドを定義します。

i +

イメージのサイズを拡大する(image-increase-size)。

i -

イメージのサイズを縮小する(image-decrease-size)。

i r

イメージを回転させる(image-rotate)。

i h

水平方向にイメージを反転させる(image-flip-horizontally)。

i v

垂直方向にイメージを反転させる(image-flip-vertically)。

i o

イメージをファイルに保存する(image-save)。

i c

インタラクティブにイメージをクロップする(image-crop)。

i x

インタラクティブにイメージから矩形を切り取る(image-cut)。

これらのイメージ固有なキーバインディングについての詳細は、Image Mode in The GNU Emacs Manualを参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.10 マルチフレームのイメージ

複数のイメージを含むことができるイメージファイルがいくつかあります。わたしたちはこのような場合には、イメージ内に複数の“フレーム”があると表現しています。現在のところEmacsはGIF、TIFF、およびDJVMのような特定のImageMagickフォーマットにたいする複数フレームをサポートします。

フレームは複数のページを表現するため(通常はたとえばマルチフレームTIFFのケースが該当)、あるいはアニメーションを作成するため(通常はマルチフレームGIFファイルのケースが該当)に使用できます。

マルチフレームイメージは、表示されるフレームを指定する整数値(0から数える)が値であるようなプロパティ:indexをもっています。

Function: image-multi-frame-p image

この関数はimageが2つ以上のフレームを含めば非nilをリターンする。実際のリターン値はコンス(nimages . delay)でありnimagesはフレーム数、delayはフレーム間の遅延秒数、イメージが遅延を指定しなければnil。通常はアニメーションを意図されたイメージはフレームの遅延を指定して、複数ページとして扱われることを意図したイメージは指定しない。

Function: image-current-frame image

この関数はimageにたいして0から数えたカレントフレーム番号のインデックスをリターンする。

Function: image-show-frame image n &optional nocheck

この関数はimageをフレーム番号nとスイッチする。nochecknilなら有効範囲外のフレーム番号を範囲終端に置き換える。imageが指定された番号のフレームを含まなければイメージは中抜きの四角(hollow box)で表示される。

Function: image-animate image &optional index limit

この関数はimageをアニメーション表示する。オプションの整数indexは開始するフレームを指定する(デフォルトは0)。オプション引数limitはアニメーションの長さを制御する。これが省略かnilならアニメーション回数は1回、tなら永久にループ表示する。数値ならその秒数後にアニメーションは停止する。

Animation operates by means of a timer. Note that Emacs imposes a アニメーションはタイマーにより処理されます。Emacsは最小のフレーム遅延を0.01秒( image-minimum-frame-delayの値)とすることに注意してください。そのイメージ自身が遅延を指定しなければEmacsはimage-default-frame-delayを使用します。

Function: image-animate-timer image

この関数はもし存在すればimageのアニメーションに責任をもつタイマーをリターンする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.17.11 イメージキャッシュ

Emacsはイメージをより効果的に再表示できるようにイメージをキャッシュします。Emacsがイメージを表示する際には、既存のイメージ仕様が望む仕様とequalなイメージキャッシュを検索します。マッチが見つかったらイメージはキャッシュから表示され、それ以外ではイメージは通常のようにロードされます。

Function: image-flush spec &optional frame

この関数はフレームframeのイメージキャッシュから仕様specのイメージを削除する。イメージ仕様の比較にはequalを使用する。framenilの場合のデフォルトは選択されたフレーム。frametならイメージはすべての既存フレームでフラッシュされる。

Emacsの現実装では各グラフィカル端末はイメージキャッシュを処理して、それはその端末上のすべてのフレームにより共有される(複数の端末を参照)。つまりあるフレームでイメージをリフレッシュすると、同一端末上の他のすべてのフレームでもリフレッシュされる。

image-flushの1つの用途はEmacsにイメージファイルの変更を伝えることです。イメージ仕様が:fileプロパティを含む場合には、そのイメージの初回表示時にファイルコンテンツにもとづいてイメージがキャッシュされます。たとえその後にファイルが変更されても、Emacsはそのイメージの古いバージョンを表示し続けます。image-flushを呼び出すことによりそのイメージはキャッシュからフラッシュされて、イメージの表示が次回必要になった際にEmacsにファイルの再読み込みを強制します。

image-flushの他の用途はメモリー節約です。Lispプログラムでimage-cache-eviction-delay (以下参照)より遥かに短い期間に多数の一時イメージを作成する場合には、Emacsが自動的に行うことを待たずに自身で使用されていないイメージのフラッシュを選択できます。

Function: clear-image-cache &optional filter

この関数はイメージキャッシュ内に格納されたすべてのイメージを削除してイメージキャッシュをクリアーする。filterが省略かnilなら選択されたフレームにたいしてキャッシュをクリアーする。filterがフレームなら、そのフレームにたいしてキャッシュをクリアーする。filtertなら、すべてのイメージキャッシュをクリアーする。それ以外ならfilterはファイル名として解釈されて、すべてのイメージキャッシュからそのファイル名に関連付けられたすべてのイメージを削除する。

イメージキャッシュ内のイメージが指定された期間内に表示されなければ、Emacsはそれをキャッシュから削除して割り当てられたメモリーを解放します。

Variable: image-cache-eviction-delay

この変数は表示されることなくイメージがキャッシュ内に残留できる秒数を指定する。あるイメージがこの秒数の間に表示されなければ、Emacsはそれをイメージキャッシュから削除する。

ある状況下では、もしキャッシュ内のイメージ数が大きくなり過ぎた場合には実際の立ち退き遅延(eviction delay)はこれより短くなり得る。

値がnilなら明示的にキャッシュをクリアーした場合を除き、Emacsはキャッシュからイメージを削除しない。このモードはデバッグ時に有用かもしれない。

Function: image-cache-size

この関数はカレントイメージキャッシュの総バイト数をリターンする。たとえば24ビットカラーでサイズ200x100のイメージのキャッシュサイズは60000バイト。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.18 アイコン

Emacsでは(クリックできる)ボタンや小さい(何かを説明するための)グラフィックスが使える場合があります。Emacsは異なる機能をもつ多種多様なシステムで利用できる、更に好みはユーザーごとにそれぞれ異なることから、Emacsはこれを処理するための機能として、テーマと同じようにカスタマイズでき、優美な装飾とアクセシビリティをもつアイコン(Icon)を提供します。

ここで中心となるのはdefine-iconというマクロです。以下に単純な例を示します:

(define-icon outline-open button
  '((image "right.svg" "open.xpm" "open.pbm" :height line)
    (emoji "▶️")
    (symbol "▶" "➤")
    (text "open" :face icon-button))
  "Icon used for buttons for opening a section in outline buffers."
  :version "29.1"
  :help-echo "Open this section")

実際にどの選択肢が表示されるかはユーザーオプションicon-preference (Icons in The GNU Emacs Manualを参照)の値と、カレントフレームの端末が実際に表示できるかどうかの実行時チェックの結果に依存します。

上記の例はoutline-openをアイコンとして定義するマクロです。これはbuttonと呼ばれるアイコンからプロパティを継承します(バッファーにはクリック可能なボタンとして挿入されることを意図している)。その後にはアイコンタイプ(icon type)のリストと実際のアイコンのシェイプ(形状)が続きます。更にドキュメント文字列や追加の情報とプロパティを含むさまざまキーワードも存在します。

アイコンをインスタンス化するためにはicon-stringを使用します。これはカレントのCustomizeテーマ、ユーザーオプションicon-preference、そして最後にEmacsが実際に何を表示できるかを調べます。icon-preference(image emoji symbol text) (これらすべての形式を許容するアイコン)の場合には、icon-stringはまずEmacsがイメージを表示できるのか、そして異なるイメージフォーマットそれぞれについてサポートしているかどうかをチェックします。これが失敗したら、Emacsは(カレントフレームにおいて)emojiを表示できるかどうかをチェックします。これが失敗すると、対象となるシンボルを表示できるかどうかをチェックして、それが失敗したら平文テキストのバージョンが使用されることになります。

たとえばもしもicon-preferenceimageemojiが含まれていなければ、それらのエントリーはスキップされます。

コードはどんな状況下においても安心してicon-stringを呼び出すことができ、ユーザーが使っているのがグラフィカルな端末とテキスト端末のどちらなのか、あるいはEmacsが何の機能とともにビルドされているかに関わらず、読み取り可能な何かがスクリーン上に表示されることが保証されているのです。

Macro: define-icon name parent specs doc &rest keywords

アイコンname (シンボル)を代替表示specとともに定義する。後でicon-stringを使ってインスタンス化できる。nameは結果となるキーワード名。

結果として得られるアイコンはそのspecをparent、その親、...から継承する。もっとも下位の子孫のspecが優先される。

specsはアイコン仕様のリスト。各仕様の1つ目の要素はタイプ、残りはそのタイプのアイコンに使用される何かしら、その後はキーワードリスト。以下は利用可能なアイコンタイプ:

image

この場合には候補として多くのイメージがリストされているかもしれない。EmacsはカレントのEmacsインスタンスが表示できる最初の候補を選択する。リストされているイメージが絶対ファイル名ならそれを使い、そうでなければimage-load-path (イメージの定義を参照)にリストされたディレクトリーを検索する。

emoji

(恐らくはカラフルな)emoji。

symbol

(モノクロの)シンボル文字。

text

アイコンにはテキスト的なフォールバックも必要である。これは視覚障害者に用いられることもあり得る。icon-preference(text)だけの場合には、すべてのアイコンはテキストに置き換えられる。

アイコン仕様のリストの後にはさまざまなキーワードを続けることができる。たとえば:

(symbol "▶" "➤" :face icon-button)

不明なキーワードは無視される。以下のキーワードが使用できる:

:face

アイコンに使用するフェイス。

:height

imageアイコンにたいしてのみ有効。数値(ピクセル単位で高さを指定)、あるいはシンボルline カレントで選択されているウィンドウのデフォルトの行高さを使用のいずれかを指定できる。

:width

imageアイコンにたいしてのみ有効。数値(ピクセル単位で幅を指定)、あるいはシンボルline (カレントバッファーのデフォルトフェイスのフォントのピクセル幅を使用)のいずれかを指定できる。

docはドキュメント文字列であること。

keywordsはキーワード/値のペアーのリスト。以下のキーワードを指定できる:

:version

このボタンが最初に現れたEmacsの(おおよその)バージョン(このキーワードは必須)。

:group

このアイコンが所属するCustomizationグループ。未指定なら推測。

:help-echo

アイコン上にマウスポインターを置いた際に表示されるヘルプ文字列。

Function: icon-string icon

この関数はカレントバッファーでiconを表示する際に適切な文字列をリターンする。

Function: icon-elements icon

あるいはこの関数によってiconの“分解された”バージョンを取得できる。この関数はキーがstringfaceimageであるようなplist(プロパティリストを参照)をリターンする(imageはアイコンがイメージとして表現される場合のみ与えられる)。これはアイコンをバッファーに直接挿入せずに、まず何らかの事前処理を行う必要があるとき有用かもしれない。

アイコンはM-x customize-iconでカスタマイズできます。たとえばテーマは以下のようにアイコンの変更を指定できます:

(custom-theme-set-icons
  'my-theme
  '(outline-open ((image :height 100)
                  (text " OPEN ")))
  '(outline-close ((image :height 100)
                   (text " CLOSE " :face warning))))

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.19 埋め込みネイティブウィジェット

必要なサポートライブラリーつきでEmacsがビルドされていて、かつグラフィカル端末上で実行されていれば、Emacsバッファー内にGTK+ WebKitウィジェットのようなネイティブウィジェットを表示することができます。Emacsが埋め込みウィジェットを表示可能かテストするには、xwidget-internal機能が利用可能かどうかをチェックします(名前つき機能を参照)。

Emacsバッファー内に埋め込みウィジェットを表示するためには、最初にxwidgetオブジェクトを作成して、テキストプロパティまたはオーバーレイプロパティdisplay内のディスプレイ仕様としてそのオブジェクトを使用します(displayプロパティを参照)。

埋め込みウィジェットは自身に生じた変更をLispコードに通知するイベントを送信できます(Xwidgetイベントを参照)。

Function: make-xwidget type title width height arguments &optional buffer related

これはxwidgetオブジェクトを作成してリターンする。bufferが省略かnilの場合のデフォルトはカレントバッファー。bufferが存在しないバッファーの名前を指定する場合には作成する。typeはxwidgetコンポーネントを識別するもので以下のいずれかが可能:

webkit

WebKitコンポーネント。

引数widthheightはウィジェットのサイズをピクセル単位で指定、titleはウィジェットのタイトルを指定する文字列。relatedはWebKitウィジェットが内部で使用するもので、新たに作成されるウィジェットが設定とサブプロセスを共有する必要がある別のWebKitウィジェットを指定する。

リターンされたxwidgetはそのバッファーとともにkillされる(バッファーのkillを参照)。kill-xwidgetを使ってkillすることもできる。xwidgetが一旦killされてもすべての参照が解放されるまではLispオブジェクトとして存在し続けてdisplayプロパティとして動作するが、生きたxwidgetで実行できるほとんどのアクションは利用できなくなる。

Function: xwidgetp object

この関数はobjectがxwidgetならt、それ以外はnilをリターンする。

Function: xwidget-live-p object

この関数はobjectがkillされていないxwidgetならt、それ以外はnilをリターンする。

Function: kill-xwidget xwidget

この関数はxwidgetをバッファーから削除して、それが保有していたウィンドウシステムのリソースを解放することによってkillする。

Function: xwidget-plist xwidget

この関数はxwidgetのプロパティリストをリターンする。

Function: set-xwidget-plist xwidget plist

この関数はplistで与えられた新たなプロパティリストでxwidgetのプロパティリストを置き換える。

Function: xwidget-buffer xwidget

この関数はxwidgetのバッファーをリターンする。xwidgetがkillされていたらnilをリターンする。

Function: set-xwidget-buffer xwidget buffer

この関数はxwidgetのバッファーをbufferにセットする。

Function: get-buffer-xwidgets buffer

この関数はbufferに関連付けられたxwidgetオブジェクトのリストをリターンする。bufferはバッファーオブジェクトか既存のバッファー名(文字列)を指定できる。bufferにxwidgetが含まれなければ値はnil

Function: xwidget-webkit-goto-uri xwidget uri

この関数は与えられたxwidget内で指定したuriをブラウズ(browse: 閲覧)する。uriはファイルかURLを指定する文字列。

Function: xwidget-webkit-execute-script xwidget script

この関数はxwidgetで指定されるブラウザウィジェットに、scriptで指定するJavaScriptを実行させる。

Function: xwidget-webkit-execute-script-rv xwidget script &optional default

この関数はxwidget-webkit-execute-scriptと同様に指定したscriptを実行するが、スクリプトのリターン値も文字列としてリターンする。この関数はscriptが値をリターンしなければdefaultdefaultが省略されたらnilをリターンする。

Function: xwidget-webkit-get-title xwidget

この関数はxwidgetのタイトルを文字列としてリターンする。

Function: xwidget-resize xwidget width height

この関数は指定したxwidgetwidthxheightのサイズ(ピクセル単位)にリサイズする。

Function: xwidget-size-request xwidget

この関数はxwidgetのサイズを(width height)という形式のリストでリターンする。単位はピクセル。

Function: xwidget-info xwidget

この関数は[type title width height]という形式のベクターでxwidgetの属性をリターンする。属性は通常はxwidgetの作成時にmake-xwidgetで決定される。

Function: set-xwidget-query-on-exit-flag xwidget flag

この関数はEmacsがxwidgetに関連付けられたバッファーのexitやkillの前にユーザーに確認を求めるようにアレンジすることを可能にする。flagが非nilならEmacsはユーザーに確認を求めて、それ以外なら確認を求めない。

Function: xwidget-query-on-exit-flag xwidget

この関数はxwidgetのquery-on-exitフラグのカレントセッティングをtnilのいずれかでリターンする。

Function: xwidget-perform-lispy-event xwidget event frame

入力イベントeventxwidgetに送信する。実行される正確なアクションはプラットフォームに依存する。入力イベントを参照のこと。

オプションとしてframeを介してこのイベントが生成されたフレームを渡すことができる。X11の場合にはframenilかつ選択されたフレームがX-Windowsフレーム以外なら、キーイベント中の修飾キーは考慮しない。

GTKでサポートされているのはキーボードとファンクションキーのイベントのみ。マウス、移動キー、クリックにたいするイベントはLispコードを介さずxwidgetにディスパッチされるため、この関数は呼び出されない。

Function: xwidget-webkit-search query xwidget &optional case-insensitive backwards wrap-around

WebKitウィジェットxwidgetにたいして、文字列queryを問い合わせるインクリメンタル検索を開始する。case-insensitiveは検索でcase(大文字小文字)を区別するかどうか、backwardsはドキュメント先頭から後方に検索を行うかどうか、そしてwrap-aroundは検索をドキュメント終端で終了するかどうかを指定する。

検索クエリーがすでに与えられた状態でこの関数を呼び出すと、既存のクエリーはここで指定したクエリーに置き換えられる。

検索クエリーを停止するにはxwidget-webkit-finish-searchを使用すること。

Function: xwidget-webkit-next-result xwidget

xwidgetの次の検索結果を表示する。xwidget-webkit-searchによる検索クエリーがxwidget内でまだ開始されていなければ、この関数はエラーをシグナルする。

xwidget-webkit-searchの呼び出し時にwrap-aroundが非nilだった場合には、検索がドキュメント終端に達すると先頭から検索を再開する。

Function: xwidget-webkit-previous-result xwidget

xwidgetの前の検索結果を表示する。xwidget-webkit-searchによる検索クエリーがxwidget内でまだ開始されていなければ、この関数はエラーをシグナルする。

xwidget-webkit-searchの呼び出し時にwrap-aroundが非nilだった場合には、検索がドキュメント先頭に達すると終端から検索を再開する。

Function: xwidget-webkit-finish-search xwidget

xwidgetで開始されたxwidget-webkit-searchによる検索操作を終了する。現在進行中のクエリーがなければ、この関数はエラーをシグナルする。

Function: xwidget-webkit-load-html xwidget text &optional base-uri

xwidget (WebKitウィジェット)にtext (文字列)をロードする。text内にあるHTMLマークアップはテキスト描画の際にすべてxwidgetによって処理される。

オプション引数base-uri (文字列)はtextによって参照されるwebリソースの絶対位置を指定する。これはtext内の相対リンクの解決に使用される。

Function: xwidget-webkit-goto-history xwidget rel-pos

WebKitウィジェットxwidgetにナビゲーション履歴でrel-pos番目の要素をロードさせる。

rel-posが0ならカレントページをリロードさせる。

Function: xwidget-webkit-back-forward-list xwidget &optional limit

xwidgetのナビゲーション履歴を両方向にlimit番目のアイテムまでリターンする。limitを指定しない場合のデフォルトは50。

リターン値は(back here forward)という形式のリスト。ここでhereはカレントナビゲーションアイテム、backはカレントナビゲーションアイテムの前にWebKitが記録されたアイテムを含むアイテムリスト、forwardはカレントナビゲーションアイテムの後に記録されたアイテムリスト。backhereforwardnilの場合もあり得る。

herenilなら、記録済みアイテムが存在しないことを意味する。backforwardnilなら、カレントアイテムにたいして前または後に記録された履歴が存在しないことを意味する。

ナビゲーションアイテム自体は(idx title uri)という形式のリスト。ここでidxxwidget-webkit-goto-historyに渡すことができるインデックス、titleは人間が読めるアイテムのタイトル、uriはそのアイテムのURL。ユーザーは特定の履歴アイテムに到達するために手作業によるuriのロードを必要とする理由は通常はない。かわりにインデックスとしてxwidget-webkit-goto-historyidxを渡せばよいからだ。

Function: xwidget-webkit-estimated-load-progress xwidget

WebKitウィジェットxwidgetによってページが完全にロードされて表示されるまでに転送を要する残りのデータ量の推測値をリターンする。

リターン値は0.0から1.0までの浮動小数点数。

Function: xwidget-webkit-set-cookie-storage-file xwidget file

WebKitウィジェットxwidgetにたいしてfileにcookieを格納させる。

fileは絶対ファイル名でなければならない。新しいセッティングはmake-xwidgetの引数relatedとして作成されたxwidget、およびそれらに関連するウィジェットにも影響を及ぼす。

xwidgetや関連するウィジェットにたいして最低でも1回はこの関数を呼び出さなければ、xwidgetはディスクに何のcookieも格納しない。

Function: xwidget-webkit-stop-loading xwidget

ページロード操作の一環となるWebKitウィジェット進行中のデータ転送はすべて終了される。ページがロードされない場合には、この関数は何も行わない。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.20 ボタン

Buttonパッケージはマウスやキーボードコマンドでアクティブ化することができる、ボタン(buttons)の挿入と操作に関する関数を定義します。これらのボタンは典型的には種々のハイパーリンクに使用されます。

本質的にボタンとはバッファー内のテキスト範囲にアタッチされたテキストプロパティやオーバーレイのプロパティのセットです。これらのプロパティはボタンプロパティ(button properties)と呼ばれます。これらのプロパティのうちの1つはアクションプロパティ(action property)であり、これはユーザーがキーボードかマウスを使用してボタンを呼び出した際に呼び出される関数を指定します。アクション関数はボタンを調べ、必要に応じて他のプロパティを使用できます。

いくつかの機能面でButtonパッケージとWidgetパッケージは重複しています。Introduction in The Emacs Widget Libraryを参照してください。Buttonパッケージの利点は、より高速で小さくプログラムにたいしてよりシンプルであることです。ユーザーの観点からは、2つのパッケージが提供するインターフェイスは非常に類似しています。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.20.1 ボタンのプロパティ

ボタンはその外観と振る舞いを定義するプロパティの連想リスト(associated list)をもち、アプリケーションの特別な目的のために他の任意のプロパティを使用できます。以下のプロパティはButtonパッケージにたいして特別な意味をもちます:

action

ユーザーがボタンを呼び出した際に呼び出す関数であり、単一の引数buttonを渡して呼び出される。デフォルトではこれは何も行わないignore

mouse-action

これはactionと似ているが与えられた際には、(RET押下のかわりに)マウスクリックによりボタンが呼び出された場合nactionのかわりに使用される。与えられなければマウスクリックはかわりにactionを使用する。

face

このタイプのボタンが表示される方法を制御するEmacsフェイス。デフォルトはbuttonフェイス。

mouse-face

ボタン上にマウスがある際の外観を制御する追加のフェイス(通常のbuttonフェイスとマージされる)。デフォルトはEmacsの通常のhighlightフェイス。

keymap

そのボタンリージョン(button region)でアクティブなバインディングを定義するボタンのキーマップ。デフォルトは変数button-mapに格納された通常のボタンリージョンキーマップであり、これはボタン呼び出しにたいしてRETmouse-2を定義している。

type

ボタンのタイプ。ボタンのタイプを参照のこと。

help-echo

Emacsのツールチップヘルプシステムが表示する文字列であり、デフォルトは"mouse-2, RET: Push this button"。かわりに表示される文字列をリターンする関数や文字列に評価されるフォーム、あるいはnil。詳細はText help-echoを参照のこと。

関数ならwindowobjectposという3つの引数で呼び出される。2つ目の引数objectはプロパティをもつオーバーレイ(オーバーレイボタンにたいして)、あるいはボタンを含むバッファー(テキストプロパティボタンにたいして)のいずれか。その他の引数はスペシャルテキストプロパティhelp-echoの場合と同じ意味をもつ。

このボタンにたいしてmouse-1クリックが振る舞う方法を定義するfollow-linkプロパティ。クリック可能なテキストの定義を参照のこと。

button

すべてのボタンは非nilbuttonプロパティをもち、これはボタンを含むテキストリージョンを探すのに有用かもしれない(標準的なボタン関数はこれを行う)。

ボタン内のテキストリージョンにたいして定義された他のプロパティも存在しますが、それらは典型的な用途にたいしては一般的には無関係でしょう。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.20.2 ボタンのタイプ

すべてのボタンはボタンのプロパティにたいするデフォルト値を定義するボタンタイプ(button type)をもっています。ボタンタイプは、より汎用的なタイプから特化したタイプへと継承される階層構造で構成されており、特定のタスクにたいして特殊用途のボタンを簡単に定義できます。

Function: define-button-type name &rest properties

name (シンボル)と呼ばれるボタンタイプを定義する。残りの引数はproperty valueペアーのシーケンスを形成する。これはそのタイプのボタンにたいするデフォルトのプロパティ値を指定する(ボタンのタイプはキーワード引数:typeを使用してボタン作成時にそれをtypeプロパティに与えることによりセット可能)。

加えてnameがデフォルトプロパティ値を継承するボタンタイプ指定するためにキーワード引数:supertypeを使用できる。この継承はnameの定義時のみ発生することに注意。その後にsupertypeに行われた変更はsubtypeには反映されない。

define-button-typeを使用してボタンのデフォルトプロパティを定義するのは必須ではありません — 特定のタイプをもたないボタンはビルトインのボタンタイプbuttonを使用します — が推奨しません。これを行うことにより通常はコードがより明快かつ効果的になるからです。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.20.3 ボタンの作成

ボタンはボタン固有の情報を保持するために、オーバーレイプロパティかテキストプロパティを使用してテキストのリージョンに関連付けられます。これらはすべてボタンのタイプ(デフォルトはビルトインのボタンタイプbutton)から初期化されます。すべてのEmacsテキストと同じようにボタンの外観はfaceプロパティにより制御されます。(ボタンタイプbuttonから継承されたfaceプロパティを通じることにより)デフォルトでは典型的なウェブページリンクのようなシンプルなアンダーラインです。

簡便さのために2種類のボタン作成関数があります。1つはバッファーの既存リージョンにボタンプロパティを追加するmake-...buttonと呼ばれる関数、もう1つはボタンテキストを挿入するinsert-...buttonと呼ばれる関数です。

すべてのボタン作成関数は&rest引数のpropertiesを受け取ります。これはボタンに追加するプロパティを指定するproperty valueペアーのシーケンスである必要があります。ボタンのプロパティを参照してください。これに加えて他のプロパティの継承元となるボタンタイプの指定にキーワード引数:typeを使用できます。ボタンのタイプを参照してください。作成の間に明示的に指定されなかったプロパティは、(そのタイプがそのようなプロパティを定義していれば)そのボタンのタイプから継承されます。

以下の関数はボタンプロパティを保持するためにオーバーレイを使用してボタンを追加します(オーバーレイを参照)。

Function: make-button beg end &rest properties

これはカレントバッファー内のbegからendにボタンを作成してリターンする。

Function: insert-button label &rest properties

これはポイント位置にラベルlabelのボタンを挿入してリターンする。

以下の関数も同様ですが、ボタンプロパティを保持するためにテキストプロパティを使用します(テキストのプロパティを参照)。この種のボタンはバッファーにマーカーを追加しないので、非常に多数のボタンが存在してもバッファーでの編集が低速になることはありません。しかしそのテキストに既存のfaceテキストプロパティが存在する場合(たとえばFont Lockモードにより割り当てられたフェイス)には、そのボタンのフェイスは可視にならないかもしれません。これらの関数はいずれも新たなボタンの開始位置をリターンします。

Function: make-text-button beg end &rest properties

これはテキストプロパティを使用してカレントバッファー内のbegからendにボタンを作成する。

Function: insert-text-button label &rest properties

これはテキストプロパティを使用してポイント位置にラベルlabelのボタンを挿入する。

Function: buttonize string callback &optional data

たとえば後でバッファーに挿入されるかもしれないデータ構造の作成時など、即座にバッファーに挿入せずに文字列をボタンにできれば便利なことがある。この関数はstringをそのような文字列にして、ユーザーがそのボタンをクリックした際にはcallbackが呼び出されるようにする。オプションのdataパラメーターはcallbackの呼び出し時にパラメーターとして使用される。nilならかわりにボタンがパラメーターとして使用される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.20.4 ボタンの操作

ボタンのプロパティの取得やセットを行う関数が存在します。これらは何を行うかを判断するためにボタンが呼び出す関数からよく使用される関数です。

buttonパラメーターが指定された場合にはオーバーレイ(オーバーレイボタンの場合)、またはバッファー位置やマーカー(テキストプロパティボタンの場合)いずれかという、特定のボタンを参照するオブジェクトを意味します。そのようなオブジェクトはボタンが関数を呼び出す際に1つ目の引数として渡されます。

Function: button-start button

buttonが開始される位置をリターンする。

Function: button-end button

buttonが終了する位置をリターンする。

Function: button-get button prop

ボタンbuttonpropという名前のプロパティを取得する。

Function: button-put button prop val

buttonpropプロパティにvalをセットする。

Function: button-activate button &optional use-mouse-action

buttonactionプロパティを呼び出す(単一の引数buttonを渡してプロパティの値である関数を呼び出す)。use-mouse-actionが非nilなら、actionのかわりにそのボタンのmouse-actionプロパティの呼び出しを試みる。ボタンがmouse-actionプロパティをもたなければ通常どおりactionを使用する。buttonbutton-dataプロパティが与えられた場合には、action関数の引数としてbuttonのかわりに使用される。

Function: button-label button

buttonのテキストラベルをリターンする。

Function: button-type button

buttonのボタンタイプをリターンする。

Function: button-has-type-p button type

buttonがボタンタイプtype、またはtypeのsubtypeのいずれかをもつならtをリターンする。

Function: button-at pos

カレントバッファー内の位置posにあるボタン、またはnilをリターンする。posにあるボタンがテキストプロパティボタンならリターン値はposを指すマーカー。

Function: button-type-put type prop val

ボタンタイプtypepropプロパティにvalをセットする。

Function: button-type-get type prop

ボタンタイプtypepropという名前のプロパティを取得する。

Function: button-type-subtype-p type supertype

ボタンタイプtypesupertypeのsubtypeならtをリターンする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.20.5 ボタンのためのバッファーコマンド

Emacsバッファー内にボタンの配置や操作を行うコマンドや関数が存在します。

push-buttonはユーザーが実際にボタンを押下(push)するために使用するコマンドであり、そのボタンのオーバーレイプロパティかテキストプロパティを使用することにより、そのボタンのRETmouse-2にデフォルトでバインドされます。ボタン自身の外部で有用なforward-buttonbackward-buttonのようなコマンドは、button-buffer-mapに格納されたキーマップ内で追加で利用可能です。ボタンを使用するモードはそのキーマップの親キーマップとしてbutton-buffer-mapの使用を望むかもしれません。かわりにbutton-modeをオンに切り替えれば、ほぼ同様の効果を得ることができます。これはマイナーモードキーマップとしてbutton-buffer-mapをインストールするだけのマイナーモードです。

ボタンが非nilfollow-linkプロパティをもち、かつmouse-1-click-follows-linkがセットされている場合には、素早いmouse-1クリックによりpush-buttonコマンドもアクティブになるでしょう。クリック可能なテキストの定義を参照してください。

Command: push-button &optional pos use-mouse-action

位置posにあるボタンが指定するアクションを行う。posはバッファー位置、またはマウスイベントのいずれか。use-mouse-actionが非nil、またはposがマウスイベントならactionのかわりにそのボタンのmouse-actionプロパティの呼び出しを試みて、ボタンにmouse-actionプロパティがなければ通常のようにactionを使用する。push-buttonがマウスイベントの結果としてインタラクティブに呼び出されたときはそのマウスイベントの位置、それ以外ではポイントの位置がposのデフォルトになる。posにボタンがなければ何もせずにnilをリターンして、それ以外ならtをリターンする。

Command: forward-button n &optional wrap display-message no-error

次のn番目、nが負なら前のn番目のボタンに移動する。nが0ならポイント位置にある任意のボタンの開始に移動する。wrapが非nilならバッファーの先頭または終端を超えてもう一方の端へ移動を継続する。display-messageが非nilならボタンのhelp-echo文字列が表示される。非nilskipプロパティをもつボタンはすべてスキップされる。見つかったボタンをリターンするか、ボタンが見つからなければエラーをシグナルする。no-errorが非nilなら、エラーをシグナルするかわりにnilをリターンする。

Command: backward-button n &optional wrap display-message no-error

前のn番目、nが負なら次のn番目のボタンに移動する。nが0ならポイント位置にある任意のボタンの開始に移動する。wrapが非nilならバッファーの先頭または終端を超えて、もう一方の端へ移動を継続する。display-messageが非nilならボタンのhelp-echo文字列が表示される。非nilskipプロパティをもつボタンはすべてスキップされる。見つかったボタンをリターンするか、ボタンが見つからなければエラーをシグナルする。no-errorが非nilなら、エラーをシグナルするかわりにnilをリターンする。

Function: next-button pos &optional count-current
Function: previous-button pos &optional count-current

カレントバッファー内の位置posの次(next-buttonの場合)、または前(previous-buttonの場合)のボタンをリターンする。count-currentが非nilなら、次のボタンから検索を開始するかわりにposにある任意のボタンを考慮する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.21 抽象的なディスプレイ

EwocパッケージはLispオブジェクトの構造を表すバッファーテキストを構成して、その構造体の変更にしたがってテキストを更新します。これはデザインパラダイム“model–view–controller”内の“view”コンポーネントと似ています。Ewocは“Emacs’s Widget for Object Collections(オブジェクトコレクション用Emacsウィジェット)”を意味します。

ewocは特定のLispデータを表現するバッファーテキストの構築に要される情報を組織化します。ewocのバッファーテキストは順番に、まず固定されたheaderテキスト、次に一連のデータ要素のテキスト記述(あなたが指定するLispオブジェクト)、最後に固定されたfooterテキストという3つのパートをもっています。具体的にはewocは以下の情報を含んでいます:

  • そのテキストが生成されたバッファー。
  • バッファー内でのそのテキストの開始位置。
  • ヘッダー文字列とフッター文字列。
  • 2重リンクされたノード(nodes)のチェーン。各ノードは以下を含む:
    • データ要素(data element)。単一のLispオブジェクト。
    • そのチェーン内で先行と後続のノードへのリンク。
  • カレントバッファー内にデータ要素値のテキスト表現を挿入する責務をもつpretty-printer関数。

通常はewoc-createによりewocを定義して、その結果のewoc構造体内にノードを構築するためにEwocパッケージ内の別の関数に渡してバッファー内に表示します。バッファー内でこれが一度表示されれば、他の関数はバッファー位置とノードの対応を判断したり、あるノードのテキスト表現から別のノードのテキスト表現への移動等を行います。抽象ディスプレイの関数を参照してください。

ノードは変数が値を保持するのと同じ方法でデータ要素をカプセル化(encapsulate)します。カプセル化は通常はewocへのノード追加の一部として発生します。以下のようにデータ要素値を取得して、その場所に新たな値を配置することができます:

(ewoc-data node)
⇒ value

(ewoc-set-data node new-value)
⇒ new-value

データ要素値として実際の値のコンテナーであるようなLispオブジェクト(リストまたはベクター)、または他の構造体へのインデックスも使用できます。例(抽象ディスプレイの例を参照)では後者のアプローチを使用しています。

データが変更された際にはバッファー内のテキストを更新したいでしょう。ewoc-refresh呼び出しにより全ノード、ewoc-invalidateを使用して特定のノード、またはewoc-mapを使用して述語を満足するすべてのノードを更新できます。あるいはewoc-deleteを使用して無効なノードを削除したり、その場所に新たなノードを追加できます。ewocからのノード削除はバッファーからそれに関連付けられたテキスト記述も同様に削除します。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.21.1 抽象ディスプレイの関数

このセクションでは、ewocnodeは上述(抽象的なディスプレイを参照)の構造体を、dataはデータ要素として使用される任意のLispオブジェクトを意味します。

Function: ewoc-create pretty-printer &optional header footer nosep

これはノード(とデータ要素)をもたない新たなewocを構築してリターンする。pretty-printerは1つの引数を受け取る関数であること。この引数は当該ewoc内で使用を計画する類のデータ要素であり、insertを使用してポイント位置にそのテキスト記述を挿入する(Ewocパッケージの内部的メカニズムと干渉するためにinsert-before-markersは決して使用しない)。

ヘッダー、フッター、およびすべてのノードのテキスト記述の後には、通常は自動的に改行が挿入される。nosepが非nilなら改行は何も挿入されない。これはewoc全体を単一行に表示したり、これらのノードにたいして何も行わないようにpretty-printerをアレンジすることによりノードを不可視にするために有用かもしれない。

ewocは作成時にカレントだったバッファー内のテキストを保守するので、ewoc-create呼び出し前に意図するバッファーへ切り替えること。

Function: ewoc-buffer ewoc

これは、ewocがそのテキストを保守するバッファーをリターンする。

Function: ewoc-get-hf ewoc

これはewocのヘッダーとフッターから作成されたコンスセル(header . footer)をリターンする。

Function: ewoc-set-hf ewoc header footer

これはewocのヘッダーとフッターに文字列headerfooterをセットする。

Function: ewoc-enter-first ewoc data
Function: ewoc-enter-last ewoc data

これらはそれぞれdataを新たなノードにカプセル化して、それをewocのチェーンノードの先頭または終端に配置する。

Function: ewoc-enter-before ewoc node data
Function: ewoc-enter-after ewoc node data

これらはそれぞれdataを新たなノードにカプセル化して、それをewocnodeの前または後に追加する。

Function: ewoc-prev ewoc node
Function: ewoc-next ewoc node

これらはそれぞれewoc内のnodeの前または次のノードをリターンする。

Function: ewoc-nth ewoc n

これはewoc内で0基準のインデックスnで見つかったノードをリターンする。負のnは終端から数えることを意味する。nが範囲外ならewoc-nthnilをリターンする。

Function: ewoc-data node

これはnodeにカプセル化されたデータを抽出してリターンする。

Function: ewoc-set-data node data

これはnodeにカプセル化されるデータとしてdataをセットする。

Function: ewoc-locate ewoc &optional pos guess

これはポイント(指定された場合はpos)を含むewoc内のノードを判断して、そのノードをリターンする。ewocがノードをもたなければ、nilをリターンする。posが最初のノードの前なら最初のノード、最後のノードの後なら最後のノードをリターンする。オプションの3つ目の引数guessは、pos近傍にあると思われるノードであること。これは結果を変更しないが、関数の実行を高速にする。

Function: ewoc-location node

これはnodeの開始位置をリターンする。

Function: ewoc-goto-prev ewoc arg
Function: ewoc-goto-next ewoc arg

これらはそれぞれewoc内の前または次のarg番目のノードにポイントを移動する。すでに最初のノードにポイントがある場合、またはewocが空の場合にはewoc-goto-prevは移動しない。またewoc-goto-nextが最後のノードを超えて移動すると結果はnil。この特殊なケースを除き、これらの関数は移動先のノードをリターンする。

Function: ewoc-goto-node ewoc node

これはewoc内のnodeの開始にポイントを移動する。

Function: ewoc-refresh ewoc

この関数はewocのテキストを再生成する。これはヘッダーとフッターの間のテキスト、すなわちすべてのデータ要素の表現を削除して、各ノードにたいして1つずつ順にpretty-printer関数を呼び出すことによりすることにより機能する。

Function: ewoc-invalidate ewoc &rest nodes

これはewoc-refreshと似ているが、ewoc内のノードセット全体ではなくnodesだけを対象とする点が異なる。

Function: ewoc-delete ewoc &rest nodes

これはewocからnodes内の各要素を削除する。

Function: ewoc-filter ewoc predicate &rest args

これはewoc内の各データ要素にたいしてpredicateを呼び出して、predicatenilをリターンしたノードを削除する。任意のargspredicateに渡すことができる。

Function: ewoc-collect ewoc predicate &rest args

これはewoc内の各データ要素にたいしてpredicateを呼び出して、predicateが非nilをリターンしたノードのリストをリターンする。リスト内の要素はバッファー内での順序になる。任意のargspredicateに渡すことができる。

Function: ewoc-map map-function ewoc &rest args

これはewoc内の各データ要素にたいしてmap-functionを呼び出して、map-functionが非nilをリターンしたノードを更新する。任意のargsmap-functionに渡すことができる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.21.2 抽象ディスプレイの例

以下は3つの整数からなるベクターを表すバッファー内の領域であるカラー構成(color components)表示をewocパッケージ内の関数を使用して、さまざまな方法で実装するシンプルな例です。

(setq colorcomp-ewoc nil
      colorcomp-data nil
      colorcomp-mode-map nil
      colorcomp-labels ["Red" "Green" "Blue"])

(defun colorcomp-pp (data)
  (if data
      (let ((comp (aref colorcomp-data data)))
        (insert (aref colorcomp-labels data) "\t: #x"
                (format "%02X" comp) " "
                (make-string (ash comp -2) ?#) "\n"))
    (let ((cstr (format "#%02X%02X%02X"
                        (aref colorcomp-data 0)
                        (aref colorcomp-data 1)
                        (aref colorcomp-data 2)))
          (samp " (sample text) "))
      (insert "Color\t: "
              (propertize samp 'face
                          `(foreground-color . ,cstr))
              (propertize samp 'face
                          `(background-color . ,cstr))
              "\n"))))

(defun colorcomp (color)
  "新たなバッファー内でCOLORの編集を許可する。
そのバッファーはColor Componentsモードになる。"
  (interactive "sColor (name or #RGB or #RRGGBB): ")
  (when (string= "" color)
    (setq color "green"))
  (unless (color-values color)
    (error "No such color: %S" color))
  (switch-to-buffer
   (generate-new-buffer (format "originally: %s" color)))
  (kill-all-local-variables)
  (setq major-mode 'colorcomp-mode
        mode-name "Color Components")
  (use-local-map colorcomp-mode-map)
  (erase-buffer)
  (buffer-disable-undo)
  (let ((data (apply 'vector (mapcar (lambda (n) (ash n -8))
                                     (color-values color))))
        (ewoc (ewoc-create 'colorcomp-pp
                           "\nColor Components\n\n"
                           (substitute-command-keys
                            "\n\\{colorcomp-mode-map}"))))
    (set (make-local-variable 'colorcomp-data) data)
    (set (make-local-variable 'colorcomp-ewoc) ewoc)
    (ewoc-enter-last ewoc 0)
    (ewoc-enter-last ewoc 1)
    (ewoc-enter-last ewoc 2)
    (ewoc-enter-last ewoc nil)))

この例はcolorcomp-dataの変更して選択プロセスを“完了”して、それらを互いに簡便に結ぶキーマップを定義することにより(言い換えると“model/view/controller”デザインパラダイムのcontroller部分)、“color selection widget”への拡張が可能です。

(defun colorcomp-mod (index limit delta)
  (let ((cur (aref colorcomp-data index)))
    (unless (= limit cur)
      (aset colorcomp-data index (+ cur delta)))
    (ewoc-invalidate
     colorcomp-ewoc
     (ewoc-nth colorcomp-ewoc index)
     (ewoc-nth colorcomp-ewoc -1))))

(defun colorcomp-R-more () (interactive) (colorcomp-mod 0 255 1))
(defun colorcomp-G-more () (interactive) (colorcomp-mod 1 255 1))
(defun colorcomp-B-more () (interactive) (colorcomp-mod 2 255 1))
(defun colorcomp-R-less () (interactive) (colorcomp-mod 0 0 -1))
(defun colorcomp-G-less () (interactive) (colorcomp-mod 1 0 -1))
(defun colorcomp-B-less () (interactive) (colorcomp-mod 2 0 -1))

(defun colorcomp-copy-as-kill-and-exit ()
  "color componentsをkillリングにコピーしてバッファーをkill。
文字列は#RRGGBB(6桁16進が付加されたハッシュ)にフォーマットされる。"
  (interactive)
  (kill-new (format "#%02X%02X%02X"
                    (aref colorcomp-data 0)
                    (aref colorcomp-data 1)
                    (aref colorcomp-data 2)))
  (kill-buffer nil))

(setq colorcomp-mode-map
      (define-keymap :suppress t
        "i" 'colorcomp-R-less
        "o" 'colorcomp-R-more
        "k" 'colorcomp-G-less
        "l" 'colorcomp-G-more
        "," 'colorcomp-B-less
        "." 'colorcomp-B-more
        "SPC" 'colorcomp-copy-as-kill-and-exit))

わたしたちが決して各ノード内のデータを変更していないことに注意してください。それらのデータはewoc作成時にnil、または実際のカラーコンポーネントであるベクターcolorcomp-dataにたいするインデックスに固定されています。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.22 カッコの点滅

このセクションではユーザーが閉カッコを挿入した際に、マッチする開カッコをEmacsが示すメカニズムを説明します。

この変数の値は閉カッコ構文(close parenthesis syntax)の文字が挿入された際に常に呼び出される関数(引数なし)であること。blink-paren-functionの値はnilも可能であり、この場合は何も行わない。

この変数がnilならblink-matching-openは何も行わない。

この変数はギブアップする前にマッチするカッコをスキャンする最大の距離を指定する。

この変数はマッチするカッコを示し続ける秒数を指定する。分数の秒も良好な結果をもたらすことがあるが、デフォルトはすべてのシステムで機能する1である。

この関数はblink-paren-functionのデフォルト値である。この関数は閉カッコ構文の文字の後にポイントがあると仮定して、マッチする開カッコに瞬時適切な効果を適用する。その文字がまだスクリーン上になければ、エコーエリア内にその文字のコンテキストを表示する。長い遅延を避けるために、この関数は文字数blink-matching-paren-distanceより遠くを検索しない。

以下はこの関数を明示的に呼び出す例。

(defun interactive-blink-matching-open ()
  "ポイント前のカッコによるsexp開始を瞬時示す"
  (interactive)
  (let ((blink-matching-paren-distance
         (buffer-size))
        (blink-matching-paren t))
    (blink-matching-open)))

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.23 文字の表示

このセクションでは文字がEmacsにより実際に表示される方法について説明します。文字は通常はグリフ(glyph)として表示されます。グリフとはスクリーン上で1文字の位置を占めるグラフィカルなシンボルであり、その外観はその文字自身に対応します。たとえば文字‘a’ (文字コード97)は‘a’と表示されます。しかしいくつかの文字は特別な方法で表示されます。たとえば改頁文字(文字コード12)は通常は2つのグリフのシーケンス‘^L’で表示されて、改行文字(文字コード10)は新たなスクリーン行を開始します。

ディスプレイテーブル(display table)を定義することにより、各文字が表示される方法を変更できます。これはそれぞれの文字をグリフのシーケンスにマップするテーブルです。ディスプレイテーブルを参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.23.1 通常の表示の慣習

以下は各文字コードの表示にたいする慣習です(ディスプレイテーブルが存在しなければこれらの慣習をオーバーライドできる 。ディスプレイテーブル)を参照)。

  • コード32から126のプリント可能ASCII文字(printable ASCII characters: 数字、英文字、および‘#’のようなシンボル)は文字通りそのまま表示される。
  • タブ文字(文字コード9)は次のタブストップ列まで伸長された空白文字として表示される。Text Display in The GNU Emacs Manualを参照のこと。変数tab-widthはタブストップごとのスペース数を制御する(以下参照)。
  • 改行文字(文字コード10)は特殊効果をもつ。これは先行する行を終端して新たな行を開始する。
  • 非プリント可能ASCII制御文字(ASCII control characters) — 文字コード0から31とDEL文字(文字コード127) — は変数ctl-arrowに応じて2つの方法のいずれかで表示される。この変数が非nil (デフォルト)なら、たとえばDELにたいしては‘^?’のように、これらの文字は1つ目のグリフが‘^’ (‘^’のかわりに使用する文字をディスプレイテーブルで指定できる)のような2つのグリフのシーケンスとして表示される。

    ctl-arrownilなら、これらの文字は8進エスケープとして表示される(以下参照)。

    このルールはバッファー内に復帰文字(CR: carriage return、文字コード13)があればそれにも適用される。しかし復帰文字は通常はバッファーテキスト内には存在しない。これらは行末変換(end-of-line conversion)の一部として除去される(コーディングシステムの基本概念を参照)。

  • rawバイト(raw bytes)とはコード128から255の非ASCII文字である。これらの文字は8進エスケープ(octal escapes)として表示される。これは1つ目が‘\’にたいするASCIIコードのグリフで、残りがその文字のコードを8進で表した数字である(ディスプレイテーブルで‘\’のかわりに使用するグリフを指定できる)。
  • 255を超える非ASCII文字は、端末がサポートしていればそのまま表示される。端末がサポートしない場合には、その文字はグリフなし(glyphless)と呼ばれて、通常はプレースホルダーグリフを使用して表示される。たとえばある文字にたいしてグラフィカル端末がフォントをもたなければ、Emacsは通常は16進文字コードを含むボックスを表示する。グリフなし文字の表示を参照のこと。

上記の表示慣習はたとえディスプレイテーブルがあっても、アクティブディスプレイテーブル内のエントリーがnilであるようなすべての文字にたいして適用されます。したがってディスプレイテーブルのセットアップ時に指定が必要なのは表示において特別な振る舞いを望む文字だけです。

以下の変数はスクリーン上で特定の文字が表示される方法に影響します。これらはその文字が占める列数を変更するのでインデント関数にも影響を与えます。またモードラインが表示される方法にも影響があります。新たな値を使用してモードラインを強制的に再表示するには関数force-mode-line-updateを呼び出してください(モードラインのフォーマットを参照)。

User Option: ctl-arrow

このバッファーローカル変数はコントロール文字が表示される方法を制御する。非nilなら‘^A’のようにカレットとその文字、nilなら‘\001’のようにバックスラッシュと8進3桁のように8進エスケープとして表示される。

User Option: tab-width

このバッファーローカル変数の値はEmacsバッファー内でのタブ文字表示で使用するタブストップ間のスペース数。値は列単位でデフォルトは8。この機能はコマンドtab-to-tab-stopで使用されるユーザー設定可能なタブストップとは完全に無関係であることに注意。調整可能なタブストップを参照のこと。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.23.2 ディスプレイテーブル

ディスプレイテーブルとはサブタイプとしてdisplay-tableをもつ特殊用途の文字テーブル(文字テーブルを参照)であり、文字の通常の表示慣習をオーバーライドするために使用されます。このセクションではディスプレイテーブルオブジェクトの作成と調査、および要素を割り当てる方法について説明します。次のセクション(アクティブなディスプレイテーブルを参照)では標準的なディスプレイテーブルと優先順位について説明します。

Function: make-display-table

これはディスプレイテーブルを作成してリターンする。テーブルは初期状態ではすべての要素にnilをもつ。

ディスプレイテーブルの通常の要素は文字コードによりインデックス付けされます。インデックスcの要素はコードcの表示方法を示します。値はnil (これは通常の表示慣習に応じて文字cを表示することを意味する。通常の表示の慣習を参照)、またはグリフコードのベクター(これらのグリフとして文字cを表示することを意味する。グリフを参照)のいずれかです。

警告: 改行文字の表示を変更するためにディスプレイテーブルを使用すると、バッファー全体が1つの長い行として表示されるでしょう。

ディスプレイテーブルは特殊用途向け6つのエクストラスロット(extra slots)をもつこともできます。以下はそれらの意味についてのテーブルです。nilのスロットは以下で示すそのスロットにたいするデフォルトの使用を意味します。

0

切り詰められたスクリーン行終端のグリフ(デフォルトでは‘$’)。グリフを参照のこと。グラフィカルな端末ではフリンジを無効にしていなれば(Window Fringes in the GNU Emacs Manualを参照)、Emacsはデフォルトでは切り詰められたことをフリンジ内の矢印で示し、ディスプレイテーブルは使用しない。

1

継続行終端のグリフ(デフォルトは‘\’)。グラフィカルな端末ではフリンジを無効にしていなれば、デフォルトではEmacsは継続ををフリンジ内の曲矢印で示し、ディスプレイテーブルは使用しない。

2

8進文字コードとして表示される文字を示すグリフ(デフォルトは‘\’)。

3

コントロール文字を示す(デフォルトは‘^’)。

4

不可視行があることを示すグリフのベクター(デフォルトは‘...’)。選択的な表示を参照のこと。

5

横並びのウィンドウ間のボーダー描画に使用されるグリフ(デフォルトは‘|’)。ウィンドウの分割を参照のこと。これは現在のところテキスト端末でのみ効果がある。グラフィカル端末では垂直スクロールバーがサポートされていて使用中ならスクロールバーが2つのウィンドウを分割する。垂直スクロールバーとディバイダー(ウィンドウディバイダーを参照)がなければ、Emacsは境界を示すために細いラインを使用する。

たとえば以下は関数make-glyph-codeにたいしてctl-arrowに非nilをセットして得られる効果を模倣するディスプレイテーブル(グリフを参照のこと)を構築する例です:

(setq disptab (make-display-table))
(dotimes (i 32)
  (or (= i ?\t)
      (= i ?\n)
      (aset disptab i
            (vector (make-glyph-code ?^ 'escape-glyph)
                    (make-glyph-code (+ i 64) 'escape-glyph)))))
(aset disptab 127
      (vector (make-glyph-code ?^ 'escape-glyph)
              (make-glyph-code ?? 'escape-glyph)))
Function: display-table-slot display-table slot

この関数はdisplay-tableのエクストラスロットslotの値をリターンする。引数slotには0から5の数字(両端を含む)、またはスロット名(シンボル)を指定できる。有効なシンボルはtruncationwrapescapecontrolselective-displayvertical-border

Function: set-display-table-slot display-table slot value

この関数はdisplay-tableのエクストラスロットslotvalueを格納する。引数slotには0から5の数字(両端を含む)、またはスロット名(シンボル)を指定できる。有効なシンボルはtruncationwrapescapecontrolselective-displayvertical-border

Function: describe-display-table display-table

この関数はヘルプバッファーにディスプレイテーブルdisplay-tableの説明を表示する。

Command: describe-current-display-table

このコマンドはヘルプバッファーにカレントディスプレイテーブルの説明を表示する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.23.3 アクティブなディスプレイテーブル

ウィンドウはそれぞれディスプレイテーブルを指定でき、バッファーもそれぞれディスプレイテーブルを指定できます。もしウィンドウにディスプレイテーブルがあれば、それはバッファーのディスプレイテーブルより優先されます。ウィンドウとバッファーがいずれもディスプレイテーブルをもたなければ、Emacsは標準的なディスプレイテーブルの使用を試みます。標準ディスプレイテーブルがnilならEmacsは通常の文字表示慣習(通常の表示の慣習を参照)を使用します(Emacsはディスプレイテーブルの“merge”は行わない; ウィンドウにディスプレイテーブルがあれば、バッファーのディスプレイテーブルと標準ディスプレイテーブルは完全に無視される)。

ディスプレイテーブルはモードラインが表示される方法に影響を与えるので、新たなディスプレイテーブルを使用してモードラインを強制的に再表示するにはforce-mode-line-updateを使用することに注意してください(モードラインのフォーマットを参照)。

Function: window-display-table &optional window

この関数はwindowのディスプレイテーブル、ディスプレイテーブルがなければnilをリターンする。windowのデフォルトは選択されたウィンドウ。

Function: set-window-display-table window table

この関数はwindowのディスプレイテーブルにtableをセットする。引数tableはディスプレイテーブルかnilのいずれかであること。

Variable: buffer-display-table

この変数はすべてのバッファーにおいて自動的にバッファーローカルになる。変数の値はバッファーのディスプレイテーブルを指定する。これがnilならバッファーのディスプレイテーブルは存在しない。

Variable: standard-display-table

この変数の値はウィンドウ内にバッファーを表示する際、ウィンドウディスプレイテーブルとバッファーディスプレイテーブルのいずれも定義されていないとき、またはEmacsがテキストを標準出力やエラーストリームに出力しているときににEmacsが使用する標準ディスプレイテーブル(standard display table)。デフォルトが通常はnilだとしても、curved quotesを表示できない端末でのインタラクティブなセッションでは、デフォルトでcurved quotesをASCII近似文字にマップする。テキストのクォートスタイルを参照のこと。

disp-tableライブラリーでは、標準ディスプレイテーブルを変更するために、いくつかの関数を定義されています。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.23.4 グリフ

グリフ(glyph)とはスクリーン上で1文字を占めるグラフィカルなシンボルです。各グリフはLisp内でグリフコード(glyph code)として表現されます。これは文字と、表示するフェイスをオプションで指定します(フェイスを参照)。ディスプレイテーブル内でのエントリーとしての使用がグリフコードの主な用途です(ディスプレイテーブルを参照)。以下の関数はグリフコードを操作するために使用されます:

Function: make-glyph-code char &optional face

この関数は文字charを表すグリフをフェイスfaceでリターンする。faceが省略かnilならグリフはデフォルトフェイスを使用して、その場合にはグリフコードは整数。faceが非nilならグリフコードが整数オブジェクトである必要はない。

Function: glyph-char glyph

この関数はグリフコードglyphの文字をリターンする。

Function: glyph-face glyph

この関数はグリフコードglyphのフェイス、またはglyphがデフォルトフェイスを使用する場合にはnilをリターンする。

テキスト端末上で実際にどのようにグリフコードを表示するかを変更するためにglyph tableをセットアップできる。この機能は半ば時代遅れであり、かわりにglyphless-char-displayを使用すること(グリフなし文字の表示を参照)。

Variable: glyph-table

この変数の値が非nilなら、それはカレントグリフテーブルである。これは文字端末上でのみ効果があり、グラフィカルディスプレイ上ではすべてのグリフはそのままliteralに表示される。グリフテーブルはg番目の要素がグリフコードgの表示方法を指定するようなベクターであること。ここでgはフェイス未指定なグリフにたいするグリフコード。要素はそれぞれ以下のいずれかであること:

nil

そのグリフをそのままliteralに表示する。

文字列

指定された文字列を端末に送信することによりグリフを表示する。

グリフコード

指定されたグリフコードをかわりに表示する。

グリフテーブルのテーブル長以上の整数グリフコードは、そのままliteralに表示される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.23.5 グリフなし文字の表示

グリフ無し文字(glyphless characters)とはliteralに表示されるのではなく特別な方法、すなわち16進コードを中に含むボックスとして表示される文字です。これらの文字にはグリフが無いと明示的に定義された文字や、利用可能なフォントがない文字(グラフィカルなディスプレイ)、その端末のコーディングシステムではエンコードできない文字(テキスト端末)が同様に含まれます。

glyphless-display-modeはカレントバッファーにとって便利な方法でグリフ無し文字の表示を切り替えるマイナーモードです。このモードが有効だと、グリフ無し文字はそのの頭文字を表示するボックスとして表示されます。

Variable: glyphless-char-display

この変数を使用すれば、よりきめ細かく(かつグローバルな)制御ができる。この変数の値はグリフ無し文字と表示方法を定義する文字テーブル。エントリーはそれぞれ以下の表示メソッドのいずれかでなければならない:

nil

通常の方法でその文字を表示する。

zero-width

その文字を表示しない。

thin-space

グラフィカルな端末では幅が1ピクセル、テキスト端末では幅が1文字の狭いスペース。

empty-box

空のボックスを表示する。

hex-code

その文字のUnicodeコードポイントの16進表記を含むボックスを表示する。

ASCII文字列

その文字列を含むボックスを表示する。文字列には少なくとも6個のASCII文字が含まれていること。例外として文字列に含まれるのが1文字だけの場合には、テキストモード端末ではボックスなしでその文字が表示される。これによって端末が表示できない文字にたいする置換文字として“頭文字”を処理することができる。

コンスセル (graphical . text)

グラフィカルな端末ではgraphical、テキスト端末ではtextをで表示する。graphicaltextはいずれも上述した表示メソッドのいずれかでなければならない。

thin-spaceempty-boxhex-code、およびASCII文字列はglyphless-charフェイスで描画される。テキスト端末ではボックスはsquare brackets ‘[]’でエミュレートされる。

文字テーブルには利用可能なすべてのフォントでも表示できない、またはその端末のコーディングシステムでエンコードできないすべての文字の表示方法を定義する余分なスロットが1つある。その値は上述した表示メソッドのうちzero-width以外のいずれかでなければならない。

アクティブなディスプレイテーブル内に非nilなエントリーをもつ文字では、そのディスプレイテーブルが効果をもつ。この場合にはEmacsはglyphless-char-displayをまったく参照しない。

User Option: glyphless-char-display-control

このユーザーオプションは似かよった文字のグループにたいしてglyphless-char-displayをセットする便利な手段を提供する。Lispコードからこの値を直接セットしてはならない。glyphless-char-display更新するカスタム関数:setを通じた場合のみ値は効果をもつ。

この値は要素が(group . method)であるようなalistであること。ここでgroupは文字のグループを指定するシンボル、methodはそれらを表示する方法を指定するシンボル。

groupは以下のいずれかであること:

c0-control

改行文字とタブ文字を除くU+0000からU+001FまでのASCIIコントロール文字(通常は‘^A’のようなエスケープシーケンスとして表示される。How Text Is Displayed in The GNU Emacs Manualを参照)。

c1-control

U+0080からU+009Fまでの非ASCII、非プリント文字(通常は‘\230’のような8進エスケープシーケンスとして表示される)。

format-control

U+200E LEFT-TO-RIGHT MARKのようなUnicode General Category [Cf]の文字だが、U+00AD SOFT HYPHENのようにグラフィックイメージをもつ文字を除く。

bidi-control

これはformat-controlのサブセットだがU+2069 POP DIRECTIONAL ISOLATEやU+202A LEFT-TO-RIGHT EMBEDDINGのような双方向テキストのフォーマットに関連する文字だけを含む。双方向テキストの表示を参照のこと。

U+200E LEFT-TO-RIGHT MARKのようなUnicode General Category [Cf]の文字だが、U+00AD SOFT HYPHENのようにグラフィックイメージをもつ文字を除く。

variation-selectors

UnicodeのVS-1からVS-256 (U+FE00からU+FE0FとU+E0100からU+E01EF)は同一コードポイントにたいして異なるグリフを選択するために使用される(一般的には絵文字)。

no-font

適切なフォントが存在しない、その端末のコーディングシステムではエンコードできない、あるいはそのテキストモード端末にグリフがない文字。

methodシンボルはzero-widththin-spaceempty-boxhex-codeのいずれかであること。これらは上述のglyphless-char-displayでの場合と同様の意味をもつ。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.24 ビープ

このセクションではユーザーの注意を喚起するために、Emacsでベルを鳴らす方法を説明します。これを行う頻度は控え目にしてください。頻繁なベルは刺激過剰になる恐れがあります。同様にエラーのシグナル時に過度にビープ音を使用しないよう注意してください。

Function: ding &optional do-not-terminate

この関数はビープ音を鳴らす、またはスクリーンをフラッシュする(後述のvisible-bellを参照)。do-not-terminatenilなら、この関数はカレントで実行中のキーボードマクロも終了する。

Function: beep &optional do-not-terminate

これはdingのシノニム。

User Option: visible-bell

この変数はベルを表すためにスクリーンをフラッシュすべきかどうかを決定する。非nilならフラッシュして、nilならフラッシュしない。これはグラフィカルなディスプレイで効果的であり、テキスト端末ではその端末のTermcapエントリーが可視ベル(visible bell) ‘vb’の能力を定義する。

User Option: ring-bell-function

これが非nilならEmacsがどのようにベルを鳴らすかを定義すること。値は引数なしの関数であること。これが非nilならvisible-bellより優先される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.25 ウィンドウシステム

Emacsは複数のウィンドウシステムで機能しますが、特にXウィンドウシステムにおいてもっとも機能します。EmacsとXはどちらも“ウィンドウ”を使用しますが異なる使い方をします。EmacsのフレームはXにおいては単一のウィンドウです。Emacsの個々のウィンドウについては、Xはまったく関知しません。

Variable: window-system

この端末ローカルな変数は、Emacsがフレームを表示するのに何のウィンドウシステムを使用しているかを示す。可能な値は、

x

EmacsはXを使用してフレームを表示している。

w32

EmacsはネイティブMS-Windows GUIを使用してフレームを表示している。

ns

EmacsはNextstepインターフェイスを使用してフレームを表示している(GNUstepとmacOSで使用されている)。

pc

EmacsはMS-DOSのスクリーン直接書き込みを使用してフレームを表示している。

haiku

EmacsはHaikuのをApplication Kit使用してフレームを表示している。

pgtk

Emacsはpure GTKの機能を使用してフレームを表示している。

nil

Emacsは文字ベース端末を使用してフレームを表示している。

Variable: initial-window-system

この変数はスタートアップの間にEmacsが作成する最初のフレームにたいして使用されるwindow-systemの値を保持する(デーモンとしてEmacsを呼び出し時には初期フレームを作成しないので、w32のMS-Windowsを除きinitial-window-systemnildaemon in The GNU Emacs Manualを参照)。

Function: window-system &optional frame

この関数はframeを表示するために使用されているウィンドウシステムを示す名前のシンボルをリターンする。この関数がリターンし得るシンボルのリストは変数window-systemの記述と同様。

テキスト端末とグラフィカルなディスプレイで異なる処理を行うコードを記述したいときは、window-systeminitial-window-systemを述語やブーリーンフラグ変数として使用しないでください。これは与えられたディスプレイタイプでのEmacsの能力指標としてwindow-systemが適していないからです。かわりにdisplay-graphic-p、またはディスプレイ機能のテストで説明しているその他の述語display-*-pを使用してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.26 ツールチップ

ツールチップ(Tooltips)はマウスポインターのカレント位置に関連するヘルプ的なヒント(別名“tips”)の表示に使用される特別なフレームです(フレームを参照)。Emacsはテキストのアクティブ範囲(特殊な意味をもつプロパティを参照)、およびメニューアイテム(拡張メニューアイテムを参照)やツールバーのボタン(ツールバーを参照)のような種々のUI要素に関するヘルプ文字列の表示にツールチップを使用します。

Function: tooltip-mode

Tooltipモードはツールチップの表示を有効にするマイナーモード。このモードをオフにするとツールチップはエコーエリアに表示される。テキストモード(別名“TTY”)のフレームでは、ツールチップは常にエコーエリアに表示される。

GTK+ツールキットかHaikuのウィンドウシステムのサポート付きでEmacsがビルドされた際にはデフォルトではツールキット機能を使用してツールチップを表示して、ツールチップの外観はツールキットのセッティングにより制御されます。ツールキットが提供するツールチップは変数use-system-tooltipsの値をnilに変更して無効にできます。このセクションの残りではEmacs自身が提供する非ツールキットのツールチップを制御する方法を説明します。

ツールチップは独自のパラメーターをもつツールチップフレームと呼ばれる特別なフレームに表示されます(フレームのパラメーターを参照)。他のフレームとは異なり、ツールチップフレームのデフォルトパラメターは特別な変数に格納されています。

User Option: tooltip-frame-parameters

このカスタマイズ可能なオプションはツールチップ表示に使用するデフォルトのフレームパラメーターを保持する。フォントとカラーに関するパラメーターは無視して、tooltipフェイスの対応する属性をかわりに使用する。lefttopのパラメーターが含まれていれば、ツールチップを表示すべきフレームに相対的な絶対座標として使用する(Tooltips in The GNU Emacs Manualに記された変数を使用すればマウスに相対的なツールチップをカスタマイズできる)。lefttopのパラメーターが与えられた場合にはマウスに相対的なオフセットをオーバーラードすることに注意。

tooltipフェイスはツールチップ内に表示されるテキストの見栄えを決定します。デフォルトのフレームフォントより一般的にはサイズの小さい可変ピッチフォントの使用が必要になります。

Variable: tooltip-functions

これはEmacsがツールチップの表示を必要とする際に呼び出す関数のリストであるようなアブノーマルフック。関数はそれぞれ最後のマウス移動イベントであるeventを単一の引数として呼び出される。このリスト上の関数が実際にツールチップを表示するなら非nilをリターンして、残りの関数は呼び出されない。この変数のデフォルト値はtooltip-help-tipsという1つの関数。

tooltip-functionsのリストに配置する関数を独自に記述する場合には、ツールチップの表示をトリガーしたマウスイベントのバッファーを知る必要があるかもしれません。以下はこの情報を提供する関数です。

Function: tooltip-event-buffer event

この関数はeventが発生したバッファーをリターンする。テキストがツールチップをトリガーしたバッファーを取得するために、これをtooltip-functionsの関数の引数で呼び出す。イベントはバッファーではないところ(たとえばツールバー)で発生したかもしれず、そのような場合にはこの関数はnilをリターンする。

ツールチップ表示に関する他の側面は、いくつかのカスタマイズ可能なセッティングにより制御されます。Tooltips in The GNU Emacs Manualを参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

41.27 双方向テキストの表示

Emacsはアラビア語、ペルシア語、ヘブライ語のような水平方向テキストの自然な表示順がR2L(right-to-left: 右から左)に実行されるようなスクリプトで記述されたテキストを表示できます。さらにL2R(right-to-left: 左から右)のテキストに埋め込まれたR2Lスクリプト(例: プログラムソースファイル内のアラビア語やヘブライ語のコメント)は適宜右から左にR2Lに表示される一方、ラテンスクリプト部やR2Lテキストに埋め込まれた数字はL2Rで表示されます。そのようなL2RとR2Lが混交されたテキストを、わたしたちは双方向テキスト(bidirectional text)と呼んでいます。このセクションでは双方向テキストの編集と表示にたいする機能とオプションについて説明します。

テキストはロジカルな順序(または読込順)、すなわち人間が各文字を読み込むであろう順序でテキストをEmacsバッファーや文字列に格納します。R2Lおよび双方向テキストでは、スクリーン上で文字が表示される順序(ビジュアル順と呼ばれる)はロジカル順と同一ではありません。それら各文字のスクリーン位置は文字列やバッファー位置により単調に増加しません。この双方向の並べ替え(bidirectional reordering)を処理を行う際に、EmacsはUnicode双方向アルゴリズム(UBA: Unicode Bidirectional Algorithm)にしたがいます(https://www.unicode.org/reports/tr9/)。EmacsはUnicode Standard v9.0の要件に合致するUBAの“Full Bidirectionality(完全な双方向性)”を提供します。とはいえテキストがパラグラフの基本方向と逆方向なときにEmacsが継続行を表示する方法は、表示するテキストの再並び換えの前に行の折り返しを要求するUBAからは逸脱していることに注意してください。

Variable: bidi-display-reordering

このバッファーローカル変数の値が非nil (デフォルト)なら、Emacsは表示で双方向の並べ替えを行う。この並べ替えはバッファーテキスト、同様に文字列表示やバッファー内のテキストプロパティやオーバーレイプロパティ由来のオーバーレイ文字列に効果を及ぼす(オーバーレイのプロパティおよびdisplayプロパティを参照)。値がnilならEmacsはバッファー内での双方向の並べ替えを行わない。

bidi-display-reorderingのデフォルト値は、モードライン内に表示されるテキスト(モードラインのフォーマットを参照)、およびヘッダー行(ウィンドウのヘッダーラインを参照)を含む、バッファーにより直接提供されない文字列の並べ替えを制御する。

たとえバッファーのbidi-display-reorderingが非nilでも、Emacsがユニバイトバッファーのテキストの並べ替えを行うことはありません。これはユニバイトバッファーに含まれるのが文字ではなくrawバイトであり、並べ替えに要する方向的なプロパティを欠くからです。したがってあるバッファーのテキストが並べ替えられるかどうかテストするには、bidi-display-reorderingのテスト単独では不十分です。正しいテストは以下のようになります:

 (if (and enable-multibyte-characters
          bidi-display-reordering)
     ;; 表示時にバッファーは並べ替えられるだろう
   )

とはいえ親バッファーが並べ替えられた際には、ユニバイト表示やオーバーレイ文字列は並べ替えられます。これはEmacsによりプレーンASCII文字列がユニバイト文字列に格納されるからです。ユニバイト表示やオーバーレイ文字列が非ASCII文字列を含むなら、それらの文字はL2Rの方向をもつとみなされます。

テキストプロパティdisplay、値が文字列であるようなdisplayプロパティによるオーバーレイ、バッファーテキストを置換するその他任意のプロパティにカバーされたテキストは表示時の並べ替えの際には単一の単位として扱われます。つまりこれらのプロパティにカバーされたテキストのchunk全体が一緒に並べ替えられます。さらにそのようなテキストchunk内の文字の双方向的なプロパティは無視されて、Emacsはあたかもそれらがオブジェクト置換文字(Object Replacement Character)として知られる単一文字で置換されたかのように並べ替えます。これはテキスト範囲上にdisplayプロパティを配置することにより、表示時に周辺テキストを並べ替える方法が変更され得ることを意味しています。このような予期せぬ効果を防ぐには、常に周辺テキストと等しい方向のテキストにたいしてそのようなプロパティを配置してください。

双方向テキストのパラグラフはそれぞれ、R2LかL2Rいずれかの基本方向(base direction)をもちます。L2Rパラグラフはウィンドウの左マージンを先頭に表示され、そのテキストが右マージンに達したら切り詰めや継続されます。R2Lパラグラフはウィンドウの右マージンを先頭に表示され、そのテキストが左マージンに達したら切り詰めや継続されます。

EmacsのUBA実装の目的におけるパラグラフの開始および終了の正確な位置は、以下の2つのローカル変数により決定されます(paragraph-startparagraph-separateに効果はないことに注意)。デフォルトではこれらの変数はnilであり、パラグラフは空行(改行を後に併なう0個以上の空白文字)で囲まれます。

Variable: bidi-paragraph-start-re

この変数の値が非nilならパラグラフの開始か2つのパラグラフを分割する行にマッチする正規表現であること。この正規表現は常に改行の後にマッチするので、それをアンカーにする("^"で開始する)のが最善である。

Variable: bidi-paragraph-separate-re

この変数の値が非nilなら2つのパラグラフを分割する行にマッチする正規表現であること。この正規表現は常に改行の後にマッチするので、それをアンカーにする("^"で開始する)のが最善である。

これら2つの変数 のいずれかを変更する場合には、整合性のあるパラグラフの記述を保証するために、通常は両方を変更するべきです。たとえば双方向の並べ替え目的のために各改行を新たなパラグラフの開始とするには両方の変数に"^"をセットしてください。

デフォルトではEmacsはテキスト先頭を調べることにより各パラグラフの基本方向を判断します。基本方向の精細な決定手法はUBAにより指定されており、簡潔に言うとその明示にな方向生をもつそのパラグラフ内の最初の文字がパラグラフの基本方向を決定します。とはいえ、あるバッファーが自身のパラグラフにたいして特定の基本方向の強制を要する場合もあります。たとえばプログラムソースコードを含むバッファーは、すべてのパラグラフがL2Rで表示されるよう強制されるべきでしょう。これを行うために以下の変数を使用できます:

User Option: bidi-paragraph-direction

このバッファーローカル変数の値がright-to-leftleft-to-rightいずれかのシンボルなら、そのバッファー内のすべてのパラグラフがその指定された方向をもつとみなされる。その他すべての値はnil (デフォルト)と等価であり、それは各パラグラフの基本方向が内容により判断されることを意味する。

プログラムソースコードにたいするモードは、これをleft-to-rightにセットすること。Progモードはデフォルトでこれを行うので、Progモードから派生したモードは明示的にセットする必要はない(基本的なメジャーモードを参照)。

Function: current-bidi-paragraph-direction &optional buffer

この関数はbufferという名前のバッファーのポイント位置のパラグラフ方向をリターンする。リターンされる値はleft-to-rightright-to-leftいずれかのシンボルである。bufferが省略またはnilの場合のデフォルトはカレントバッファー。変数bidi-paragraph-directionのバッファーローカル値が非nilなら、リターンされる値はその値と等しくなるだろう。それ以外ならリターンされる値はEmacsにより動的に決定されたパラグラフの方向を反映する。bidi-display-reorderingの値がnilのバッファー、同様にユニバイトバッファーにたいしては、この関数は常にleft-to-rightをリターンする。

バッファーのカレントのスクリーン位置にたいして、ビジュアル順にL2RかR2Lいずれかの方向に厳密なポイント移動を要す場合があります。Emacsはこれを行うためのプリミティブを提供します。

Function: move-point-visually direction

この関数は、カレントで選択されたウィンドウのバッファーにたいしてポイントを、スクリーン上ですぐ右か左のポイントへ移動する。directionが正ならスクリーン位置は右、それ以外ならスクリーン位置は左へ移動するだろう。周囲の双方向コンテキストに依存して、これは潜在的に多くのバッファーのポイントを移動し得ることに注意。スクリーン行終端で呼び出された場合には、この関数はdirectionに応じて適宜、次行か前行の右端か左端のスクリーン位置にポイントを移動する。

この関数は値として新たなバッファー位置をリターンする。

バッファー内で双方向の内容をもつ2つの文字列が並置されているときや、プログラムで1つのテキスト文字列に結合した場合には、双方向の並べ替えは以外かつ不快な効果を与える可能性があります。典型的な問題ケースはBuffer MenuモードやRmail Summaryモードのようにバッファーがスペースや区切り文字分割されたテキストのフィールドのシーケンスで構成されているときです。それはセパレーターとして使用されている区切り文字が弱い方向性をもち、周囲のテキストの方向を採用するためです。結果として双方向の内容のフィールドが後続する数値フィールドは、先行するフィールドヘ左方向に表示され、期待したレイアウトを破壊してしまいます。この問題を回避するための方法がいくつかあります:

  • - 双方向の内容をもち得る各フィールド終端に、スペシャル文字LEFT-TO-RIGHT MARK(略してLRM)のU+200E LEFT-TO-RIGHT MARKを付加する。後述の関数bidi-string-mark-left-to-rightは、この目的に手頃(R2LパラグラフではかわりにRIGHT-TO-LEFT MARK、略してRLMのU+200F RIGHT-TO-LEFT MARKを使用する)。これはUBAにより推奨される解決策の1つである。
  • - フィールドセパレーターにタブ文字を含める。タブ文字は双方向の並べ替えにおいてセグメントセパレーター(segment separator)の役割を演じて、両側のテキストを個別に並べ替えさせる。
  • - displayプロパティ、または(space . PROPS)という形式の値をもつオーバーレイ(スペースの指定を参照)でフィールドを区切る。Emacsはこのdisplay仕様をパラグラフセパレーター(paragraph separator)として扱い両側のテキストを個別に並べ替える。
Function: bidi-string-mark-left-to-right string

この関数は結果を安全に他の文字列に結合できるよう、あるいはこの文字列とスクリーン上で次行となる行に関連するレイアウトを乱すことなくバッファー内の他の文字列に並置できるよう、自身への引数stringを恐らく変更してリターンする。この関数がリターンする文字列がR2Lパラグラフの一部として表示される文字列なら、それは常に後続するテキストの左に出現するだろう。この関数は自身の引数の文字を検証することにより機能して、もしそれらの文字のいずれかがディスプレイ上の並べ替えを発生し得るなら、この関数はその文字列にLRM文字を付加する。付加されたLRM文字はテキストプロパティinvisibletを与えることにより不可視にできる(不可視のテキストを参照)。

並べ替えアルゴリズムはbidi-classプロパティとして格納された文字の双方向プロパティを使用します(文字のプロパティを参照)。Lispプログラムはput-char-code-property関数を呼び出すことにより、これらのプロパティを変更できます。しかしこれを行うにはUBAの完全な理解が要求されるので推奨しません。ある文字の双方向プロパティにたいする任意の変更はグローバルな効果をもちます。これらはEmacsのフレームのすべてのフレームとウィンドウに影響します。

同様にmirroringプロパティは並べ替えられたテキスト内の適切にミラーされた文字の表示に使用されます。Lispプログラムはこのプロパティを変更することにより、ミラーされた表示に影響を与えることができます。繰り返しますがそのような変更はEmacsのすべての表示に影響を与えます。

スペシャル双方向制御文字LEFT-TO-RIGHT OVERRIDE (LRO)とRIGHT-TO-LEFT OVERRIDE (RLO)をテキストに挿入することにより、文字の双方向プロパティをオーバーライドできます。RLOと改行かPOP DIRECTIONAL FORMATTING (PDF)のいずれか先にある文字間のすべての文字は、それらが強いR2Lであるかのように表示されます(反転して表示される)。同様にLROPDFか改行の間のすべての文字は、それらがたとえ強いR2Lであっても強いL2Rであるかのように反転して表示されません

これらのオーバーライドは、あるテキストを並び替えアルゴリズムの影響を受けずに、直接表示順を制御したいときに有用です。しかしこれらはフィッシング(phishing)として知られるような悪意のある用途にも使用されます。特にウェブ上のURLやemailメッセージ内のリンクは真のリンク先はまったく異なるのに、ブラウザによる論理順で解釈される外観を認識不能に操作したり、何らかの著名で安全なリンク先に偽装される可能性があります。

Emacsはアプリケーションが使用するために、双方向プロパティでL2R文字をR2L、またはその逆にするようにオーバーライドされたテキストのインスタンスを検知するプリミティブを提供します。

Function: bidi-find-overridden-directionality from to &optional object

この関数はobjectで指定されたテキストのfrom (含む)とto (含まず)の間のテキストを調べてR2Lの文字であるかのように表示が強制されている双方向プロパティの強いL2R文字、L2Rの文字であるかのように表示が強制されている強いR2L文字の最初の位置をリターンする。指定されたテキストリージョンでそのような文字が見つからなければnilをリターンする。

オプション引数objectは検索するテキストを指定して、デフォルトはカレントバッファー。objectが非nilなら別のバッファーや文字列、またはウィンドウかもしれない。文字列ならこの関数はその文字列を検索する。ウィンドウならこの関数はそのウィンドウが表示するバッファーを検索する。検査したいテキストをもつバッファーが何らかのウィンドウに表示されていれば、この関数にバッファーを渡すのではなくそのウィンドウの指定を推奨する。これはウィンドウ固有のオーバーレイにカバーされたバッファーのテキストでは関数の結果が変化し得るが、関数にウィンドウ固有のオーバーレイを正しく考慮するように指示するからである。

テキストがR2L文字とL2R文字の混交を含み、かつ双方向制御が別の場所にコピーされる際には、その視覚的外見は変化するかもしれず、コピー先の周辺テキストの視覚的外見にも影響するかもしれません。これはUBAで指定される双方向テキストの並び替えでは、コピーされるテキストとそれを取り囲む周辺テキストの両方が非自明かつコンテキスト依存の効果をもつからです。

コピーされるテキストとコピー先周辺のテキストの視覚的外見をLispプロパティが保証することが必要なときがあるかもしれません。この効果を達成するためにLispプログラムは以下の関数を使用できます。

Function: buffer-substring-with-bidi-context start end &optional no-properties

この関数はbuffer-substring (バッファーのコンテンツを調べるを参照)と同様に機能するが、テキストが別の場所にコピーされる際に視覚的外見を保つために必要な双方向制御文字を前や後に付加する点が異なる。オプション引数no-propertiesが非nilなら、それはテキストのコピーからテキストプロパティを削除することを意味する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42 オペレーティングシステムのインターフェース

これはEmacsの開始と終了、オペレーティングシステム内の値へのアクセス、端末の入力と出力に関するチャプターです。

関連する情報はEmacsのビルドを参照してください。端末とスクリーンに関連するオペレーティングシステムの状態に関する追加情報はEmacsのディスプレイ表示を参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.1 Emacsのスタートアップ

このセクションではEmacsが開始時に何を行うか、およびそれらのアクションのカスタマイズ方法を説明します。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.1.1 要約: スタートアップ時のアクション順序

Emacsは起動時に以下の処理を行います(startup.el内のnormal-top-levelを参照):

  1. このload-pathの各ディレクトリー内にあるsubdirs.elという名前のファイルを実行してload-pathにサブディレクトリーを追加する。このファイルは通常はそのディレクトリー内にあるサブディレクトリーをこのリスト変数に追加して、それらを順次スキャンする。ファイルsubdirs.elは通常はEmacsインストール時に自動的に作成される。
  2. load-pathのディレクトリー内で見つかったleim-list.elをすべてロードする。このファイルは入力メソッドの登録を意図している。この検索はユーザーが作成するかもしれない個人的なleim-list.elすべてにたいしてのみ行われる。標準的なEmacsライブラリーを含むディレクトリーはスキップされる(これらは単一のleim-list.elだけに含まれるべきでありEmacs実行形式にコンパイル済)。
  3. 変数before-init-timecurrent-timeの値をセットする(時刻を参照)。これはafter-init-timenilをセットすることによりEmacs初期化時にLispプログラムへの合図も行う。
  4. LANGのような環境変数がそれを要するなら言語環境と端末のコーディングシステムをセットする。
  5. コマンドライン引数にたいして基本的なパースをいくつか行う。
  6. ユーザーの早期initファイルをロードするEarly Init File in The GNU Emacs Manual(を参照)。これはオプション‘-q’、‘-Q’、または‘--batch’が指定されていたら行われない。‘-u’オプションが指定されたらEmacsはかわりにそのユーザーのホームディレクトリー内でinitファイルを探す。
  7. インストール済みのオプションのEmacs Lispパッケージをすべてアクティブ化するために関数package-activate-allを呼び出す。パッケージ化の基礎を参照のこと。しかしpackage-enable-at-startupnil、または‘-q’、‘-Q’、‘--batch’のいずれかのオプションで開始時には、Emacsはパッケージのアクティブ化をしない。後者のケースでパッケージをアクティブ化するには、(たとえば‘--funcall’オプションを通じて)明示的にpackage-activate-allを呼び出すこと。
  8. batchモードで実行されていなければ変数initial-window-systemが指定するウィンドウシステムを初期化する(initial-window-systemを参照)。初期化関数window-system-initializationジェネリック関数generic functionであり、本当の実装はサポートされる各ウィンドウシステムごとに異なる(ジェネリック関数を参照)。initial-window-systemの値がwindowsystemなら、ファイルterm/windowsystem-win.el内で適切な初期化関数の実装が定義されている。このファイルはビルド時にEmacs実行可能形式にコンパイルされているはずである。
  9. ノーマルフックbefore-init-hookを実行する。
  10. それが適切ならグラフィカルなフレームを作成する。グラフィカルなフレーム作成の一環としてinitial-frame-alistdefault-frame-alist (フレームの初期パラメーターを参照)により指定されたウィンドウシステム用のwindow-system-initialization関数を呼び出すことにより、そのウィンドウシステムのグラフィカルなフレームを初期化する。これは(非インタラクティブな)batchモードやデーモンモードでは行われない。
  11. 初期フレームのフェイスを初期化して必要ならメニューバーとツールバーをセットする。グフィカルなフレームがサポートされていたら、たとえカレントフレームがグラフィカルでなくても、後でグラフィカルなフレームが作成されるかもしれないのでツールバーをセットアップする。
  12. リストcustom-delayed-init-variables内のメンバーを再初期化するためにcustom-reevaluate-settingを使用する。これらのメンバーは、デフォルト値がビルド時ではなく実行時のコンテキストに依存する、すべての事前ロード済ユーザーオプションである。custom-initialize-delayを参照のこと。
  13. 存在すればライブラリーsite-startをロードする。これはオプション‘-Q’か‘--no-site-file’が指定された場合は行われない。
  14. ユーザーのinitファイルをロードする(initファイルを参照)。これはオプション‘-q’、‘-Q’、または‘--batch’が指定されていたら行われない。‘-u’オプションが指定されたらEmacsはかわりにそのユーザーのホームディレクトリー内でinitファイルを探す。
  15. 存在すればライブラリーdefaultをロードする。これはinhibit-default-initが非nil、あるいはオプション‘-q’、‘-Q’、または‘--batch’指定された場合には行われない。
  16. もしファイルが存在して読み込み可能なら、abbrev-file-nameで指定されるファイルからユーザーのabbrevをロードする(abbrev-file-nameを参照)。オプション‘--batch’が指定されていたら行われない。
  17. 変数after-init-timecurrent-timeの値をセットする。この変数は事前にnilにセットされている。これをカレント時刻にセットすることが初期化フェーズが終わったことの合図となり、かつbefore-init-timeと共に用いることにより初期化に要した時間の計測手段を提供する。
  18. ノーマルフックafter-init-hookdelayed-warnings-hookを実行する。後者はスタートアップの前ステージの間に発せられたが、自動的に遅延された警告メッセージすべてを表示するフック。
  19. バッファー*scratch*が存在して、まだ(デフォルトであるべき)Fundamentalモードならinitial-major-modeに応じたメジャーモードをセットする。
  20. テキスト端末で開始された場合には、端末固有のLispライブラリー(端末固有の初期化を参照)をロードしてフックtty-setup-hookを実行する。これは--batchモード、またはterm-file-prefixnilなら実行されない。
  21. inhibit-startup-echo-area-messageで抑制していなければエコーエリアに初期メッセージを表示する。
  22. これ以前に処理されていないコマンドラインオプションをすべて処理する。
  23. オプション--batchが指定されていたら、ここでexitする。
  24. *scratch*が存在して空ならばバッファーに(substitute-command-keys initial-scratch-message)を挿入する。
  25. initial-buffer-choiceが文字列ならその名前のファイル(かディレクトリー)をvisitする。関数なら引数なしでその関数を呼び出して、それがリターンしたバッファーを選択する。コマンドライン引数として単一のファイルが与えられた場合にはファイルをvisitして、そのバッファーをinitial-buffer-choiceのそばに表示する。複数のファイルが与えられた場合にはすべてのファイルをvisitして、initial-buffer-choiceのそばに*Buffer List*バッファーを表示する。
  26. emacs-startup-hookを実行する。
  27. initファイルの指定が何であれ、それに応じて選択されたフレームのパラメーターを変更するframe-notice-user-settingsを呼び出す。
  28. window-setup-hookを実行する。このフックとemacs-startup-hookの違いは前述したフレームパラメーターの変更後にこれが実行される点のみ。
  29. copyleftとEmacsの基本的な使い方を含んだ特別なバッファースタートアップスクリーン(startup screen)を表示する。これはinhibit-startup-screeninitial-buffer-choiceが非nil、あるいはコマンドラインオプション‘--no-splash’か‘-Q’が指定されていたら行われない。
  30. デーモンが要求された場合にはserver-startを呼び出す(POSIXシステムではバックグラウンドのデーモンが要求された場合には制御端末からデタッチされる)。Emacs Server in The GNU Emacs Manualを参照のこと。
  31. セッションマネージャーにより開始された場合には、以前のセッションのIDを引数としてemacs-session-restoreを呼び出す。セッションマネージャーを参照のこと。

以下のオプションはスタートアップシーケンスにおけるいくつかの側面に影響を与えます。

User Option: inhibit-startup-screen

この変数が非nilならスタートアップスクリーンを抑制する。この場合にはEmacsは通常は*scratch*バッファーを表示する。しかし以下のinitial-buffer-choiceを参照されたい。

新しいユーザーがcopyleftやEmacsの基本的な使い方に関する情報を入手するのを防げるので、新しいユーザーのinitファイル内や複数ユーザーに影響するような方法でこの変数をセットしてはならない。

inhibit-startup-messageinhibit-splash-screenはこの変数にたいするエイリアス。

User Option: initial-buffer-choice

nilならこの変数はスタートアップ後にスタートアップスクリーンのかわりにEmacsが表示するファイルを指定する文字列であること。この変数が関数ならEmacsはその関数を呼び出して、その関数はその後に表示するバッファーをリターンしなければならない。値がtならEmacsは*scratch*バッファーを表示する。

User Option: inhibit-startup-echo-area-message

この変数はエコーエリアのスタートアップメッセージの表示を制御する。ユーザーのinitファイル内に以下の形式のテキストを追加することによりエコーエリアのスタートアップメッセージを抑制できる:

(setq inhibit-startup-echo-area-message
      "your-login-name")

Emacsはユーザーのinitファイル内で上記のような式を明示的にチェックする。ユーザーのロフイン名はLispの文字列定数としてこの式内に記述されていなければならない。Customizeインターフェイスを使用することもできる。他の方法で同じ値にinhibit-startup-echo-area-messageをセットしてもスタートアップメッセージは抑制されない。この方法により望むならユーザー自身で簡単にメッセージを抑制できるが、単に自分用のiniファイルを別のユーザーにコピーしてもメッセージは抑制されないだろう。

User Option: initial-scratch-message

この変数が非nilなら、Emacsのスタートアップやこのバッファーの再作成の際に*scratch*バッファーに挿入するドキュメントとして扱われる文字列であること。nilなら*scratch*バッファーは空になる。

以下のコマンドラインオプションはスタートアップシーケンスにおけるいくつかの側面に影響を与えます。Initial Options in The GNU Emacs Manualを参照してください。

--no-splash

スプラッシュスクリーンを表示しない。

--batch

対話的な端末なしで実行する。batchモードを参照のこと。

--daemon
--bg-daemon
--fg-daemon

表示の初期化を何も行わず単にサーバーを開始する(“バックグラウンド”のデーモンは自動的にバックグラウンドで実行される)。

--no-init-file
-q

initファイルとdefaultライブラリーをいずれもロードしない。

--no-site-file

site-startライブラリーをロードしない。

--quick
-Q

-q --no-site-file --no-splash’と等価。

--init-directory

Emacsのinitファイルを探す際に使用するディレクトリーを指定する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.1.2 initファイル

Emacsの開始時は通常はユーザーのinitファイル(init file)のロードを試みます。これはユーザーのホームディレクトリー内にある.emacs.emacs.elという名前のファイル、あるいはホームディレクトリーの.emacs.dという名前のサブディレクトリー内にあるinit.elという名前のファイルのいずれかのファイルです。

コマンドラインスイッチ‘-q’、‘-Q’、‘-u’はinitファイルを探すべきか、およびどこで探すべきかを制御します。‘-u user’はそのユーザーではなくuserのinitファイルのロードを指示しますが、‘-q’ (‘-Q’のほうが強力)はinitファイルをロードしないことを指示します。Entering Emacs in The GNU Emacs Manualを参照してください。いずれのオプションも指定されていなければユーザーのホームディレクリーからinitファイルを探すために、Emacsは環境変数LOGNAMEUSER (ほとんどのシステム)、またはUSERNAME (MSシステム)を使用します。この方法によりたとえsuしていたとしても、依然としてEmacsはそのユーザー自身のinitファイルをロードできるのです。これらの環境変数が存在していなくてもEmacsはユーザーIDからユーザーのホームディレクトリーを探します。

Emacsは早期initファイル(early init file)と呼ばれる2つ目のinitファイルが存在すれば、それのロードも試みます。これは~/.emacs.dにあるearly-init.elという名前のファイルです。早期initファイルはスタートアッププロセスのより速いタイミングでロードされるために、通常のinitファイルのロード前に初期化される何かをカスタマイズするために使用できるのが早期initファイルと通常のinitファイルの違いです。たとえばpackage-load-listpackage-enable-at-startupのような変数をセットしてパッケージシステムの初期化プロセスをカスタマイズできます。Package Installation in The GNU Emacs Manualを参照してください。

インストールしたEmacsによってはdefault.elというLispライブラリーのデフォルトinitファイル(default init file)が存在するかもしれません。Emacsはライブラリーの標準検索パスからこのファイルを探します(プログラムがロードを行う方法を参照)。このファイルはEmacsディストリビューション由来ではありません。このファイルはローカルなカスタマイズを意図しています。デフォルトinitファイルが存在する場合には常にこのファイルがEmacs開始時にロードされます。しかしユーザー自身のinitファイルが存在する場合にはそれが最初にロードされます。それによりinhibit-default-initが非nil値にセットされた場合には、Emacsは後続するdefault.elファイルのロードを行いません。batchモードまたは‘-q’ (または‘-Q’)を指定した場合には、Emacsは個人的なinitファイルトでデフォルトinitファイのいずれもロードしません。

サイトのカスタマイズのためのファイルはsite-start.elです。Emacsはユーザーのinitファイルのにこれをロードします。オプション‘--no-site-file’により、このファイルのロードを抑制できます。

User Option: site-run-file

この変数はユーザーのinitファイルの前にロードするサイト用のカスタマイズファイルを指定する。通常の値は"site-start"。実際に効果があるようにこれを変更するには、Emacsのdump前に変更するのが唯一の方法である。

一般的に必要とされる.emacsファイルのカスタマイズ方法についてはInit File Examples in The GNU Emacs Manualを参照のこと。

User Option: inhibit-default-init

この変数が非nilならEmacsがデフォルトの初期化ライブラリーファイルをロードするのを防ぐ。デフォルト値はnil

Variable: before-init-hook

このノーマルフックはすべてのinitファイル(site-start.el、ユーザーのinitファイル、およびdefault.el)のロード直前に一度実行される(実際に効果があるようにこれを変更するにはEmacsのdump前に変更するのが唯一の方法)。

Variable: after-init-hook

このノーマルフックはすべてのinitファイル(site-start.el、ユーザーのinitファイル、およびdefault.el)のロード直後、端末固有ライブラリーのロードとコマンドラインアクション引数の処理の前に一度実行される。

Variable: emacs-startup-hook

このノーマルフックはコマンドライン引数の処理直後に一度実行される。batchモードではEmacsはこのフックを実行しない。

Variable: window-setup-hook

このノーマルフックはemacs-startup-hookと非常に類似している。このフックは若干遅れてフレームパラメーターのセット後に実行されるのが唯一の違い。window-setup-hookを参照のこと。

Variable: user-init-file

この変数はユーザーのinitファイルの絶対ファイル名を保持する。実際にロードされたinitファイルが.emacs.elcのようにコンパイル済なら、値はそれに対応するソースファイルを参照する。

Variable: user-emacs-directory

この変数はEmacsのデフォルトディレクトリーの名前を保持する。~/.emacs.d/および~/.emacsが存在せず${XDG_CONFIG_HOME-'~/.config'}/emacs/が存在すればそのディレクトリーがデフォルト、それ以外ならMS-DOS以外のすべてのプラットフォームでは~/.emacs.d/がデフォルト。ここで${XDG_CONFIG_HOME-'~/.config'}は環境変数XDG_CONFIG_HOMEがセットされていればその値、それ以外なら~/.configを意味する。How Emacs Finds Your Init File in The GNU Emacs Manualを参照のこと。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.1.3 端末固有の初期化

端末タイプはそれぞれ、その端末のタイプでEmacsが実行時にロードする独自のLispライブラリーをもつことができます。そのライブラリーの名前は変数term-file-prefixの値と端末タイプ(環境変数TERMにより指定)を結合することにより構築されます。term-file-prefixは通常は値"term/"をもち変更は推奨しません。連想リストterm-file-aliases内にTERMにマッチするエントリーが存在する場合には、EmacsはTERMのかわりにんその連想値を使用します。Emacsは通常の方法、つまりload-pathのディレクトリーから‘.elc’と‘.el’の拡張子のファイルを検索することにより、このファイルを探します。

端末固有ライブラリーの通常の役割は特殊キーによりEmacsが認識可能なシーケンスを送信可能にすることです。TermcapとTerminfoのエントリーがその端末のすべてのファンクションキーを指定していなければ、input-decode-mapへのセットや追加も必要になるかもしれません。端末の入力を参照してください。

端末タイプにハイフンとアンダースコアーが含まれて、その端末名に等しい名前のライブラリーが見つからないときには、Emacsはその端末名から最後のハイフンまたはアンダースコアー以降を取り除いて再試行します。このプロセスはEmacsがマッチするライブラリーを見つかるか、その名前にハイフンとアンダースコアーが含まれなくなる(つまりその端末固有ファイルが存在しない)まで繰り返されます。たとえば端末名が‘xterm-256color’でterm/xterm-256color.elというライブラリーが存在しなければEmacsはterm/xterm.elのロードを試みます。必要なら端末タイプの完全な名称を見つかるために端末ライブラリーは(getenv "TERM")を評価できます。

initファイルで変数term-file-prefixnilにセットすることにより端末固有ライブラリーのロードを防ぐことができます。

tty-setup-hookを使用することにより、端末固有ライブラリーのいくつかのアクションのアレンジやオーバーライドもできます。これは新たなテキスト端末の初期化後にEmacsが実行するノーマルフックです。自身のライブラリーをもたない端末にたいして初期化を定義するために、このフックを使用することのできるでしょう。フックを参照してください。

User Option: term-file-prefix

この変数の値が非nilならEmacsは以下のように端末固有初期化ファイルをロードする:

(load (concat term-file-prefix (getenv "TERM")))

端末初期化ファイルのロードを望まない場合には変数term-file-prefixnilをセットできる。

MS-DOSではEmacsは環境変数TERMに‘internal’をセットする。

User Option: term-file-aliases

この変数は端末タイプをエイリアスにマップする連想リスト。たとえば("vt102" . "vt100")という形式の要素は‘vt102’というタイプの端末を‘vt100’タイプの端末として扱うことを意味する。

Variable: tty-setup-hook

この変数は新たなテキスト端末の初期化後にEmacsが実行するノーマルフック(これは非ウィンドウのモードでのEmacs開始時とemacsclientのTTY接続作成時に適用される)。(適用可能なら)このフックはユーザーのinitファイルおよび端末固有Lispファイルのロード後に実行されるので、そのファイルにより行われた定義を調整するためにフックを使用できる。

関連する機能についてはwindow-setup-hookを参照のこと。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.1.4 コマンドライン引数

Emacs開始時に種々のアクションをリクエストするためにコマンドライン引数を使用できます。Emacsを使う際にはログイン後に一度だけ起動して同一のEmacsセッション内ですべてを行うのが推奨される方法です(Entering Emacs in The GNU Emacs Manualを参照)。この理由によりコマンドライン引数を頻繁に使うことはないかもしれません。それでもセッションスクリプトからEmacsを呼び出すときやEmacsのデバッグ時にコマンドライン引数が有用になるかもしれません。このセクションではEmacsがコマンドライン引数を処理する方法を説明します。

Function: command-line

この関数はEmacsが呼び出された際のコマンドライン引数を解析、処理、そして(とりわけ)ユーザーのinitファイルをロードしてスタートアップメッセージを表示する。

Variable: command-line-processed

この変数の値は一度コマンドラインが処理されるとtになる。

dump-emacs (Emacsのビルドを参照)を呼び出すことによりEmacsを再dumpする場合には、新たにdumpされたEmacsに新たなコマンドライン引数を処理させるために最初にこの変数にnilをセットしたいと思うかもしれない。

Variable: command-switch-alist

この変数はユーザー定義のコマンドライン引数とそれに関連付けられたハンドラー関数のalist。デフォルトでは空だが望むなら要素を追加できる。

コマンドラインオプション(command-line option)は以下の形式をもつコマンドライン上の引数である:

-option

command-switch-alistの要素は以下のようになる:

(option . handler-function)

CARoptionは文字列でコマンドラインオプションの名前(先頭のハイフンは含む)。handler-functionoptionを処理するために呼び出されて、単一の引数としてオプション名を受け取る。

このオプションはコマンドライン内で引数を併う場合がある。この場合には、handler-functionは残りのコマンドライン引数すべてを変数command-line-args-left (以下参照)で見つけることができる(コマンドライン引数のリスト全体はcommand-line-args)。

command-switch-alistの処理はoption内の等号を特別扱いしないことに注意。つまりコマンドラインに--name=valueのようなオプションがなければ、carが文字通り--name=valuecommand-switch-alistのメンバーでなければこのオプションにマッチしない。そのようなオプションをパースしたければ、かわりにcommand-line-functions (以下参照)を使う必要がある。

コマンドライン引数はstartup.elファイル内のcommand-line-1により解析される。Command Line Arguments for Emacs Invocation in The GNU Emacs Manualも参照のこと。

Variable: command-line-args

この変数の値はEmacsに渡されたコマンドライン引数のリスト。

Variable: command-line-args-left

この変数の値はまだ処理されていないコマンドライン引数のリスト。

Variable: command-line-functions

この変数の値は認識されなかったコマンドライン引数を処理するための関数のリスト。次の引数が処理されてそれに特別な意味がないときは、その都度このリスト内の関数が非nilをリターンするまでリスト内での出現順に呼び出される。

これらの関数は引数なしで呼び出される。関数はその時点で一時的にバインドされている変数argiを通じて検討中のコマンドラインにアクセスできる。残りの引数(カレントの引数含まず)は変数command-line-args-left内にあり。

関数がargi内のその引数を認識して処理したときは引数を処理したと告げるために非nilをリターンすること。後続の引数のいくつかを処理したときはcommand-line-args-leftからそれらを削除してそれを示すことができる。

これらの関数すべてがnilをリターンした場合には引数はvisitすべきファイル名として扱われる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.2 Emacsからの脱出

Emacsから抜け出すには2つの方法があります: 1つ目は永遠にexitするEmacsジョブのkill、2つ目はサスペンドする方法でこれは後からEmacsプロセスに再エンターすることができます(もちろんグラフィカルな環境ではEmacsで特に何もせず単に他のアプリケーションにスイッチして後で望むときにEmacsに戻れる)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.2.1 Emacsのkill

EmacsのkillとはEmacsプロセスの終了を意味します。端末からEmacsを開始した場合には、通常は親プロセスの制御が再開されます。Emacsをkillする低レベルなプリミティブはkill-emacsです。

Command: kill-emacs &optional exit-data restart

このコマンドはフックkill-emacs-hookを呼び出してからEmacsプロセスをexitしてkillする。

exit-dataが整数ならEmacsプロセスのexitステータスとして使用される(これは主にbatch処理で有用。batchモードを参照)。

exit-dataが文字列なら内容は端末の入力バッファーに詰め込まれるので、shell(や何であれ次の入力を読み込むプログラム)が読み込むことができる。

exit-dataが整数や文字列以外、または省略なら成功裏にプログラムが終了したことを示すexitステータス(システム固有)の使用を意味する。

restartが非nilなら最後にexitするだけではなく、カレントで実行中のEmacsプロセスと同じコマンドライン引数で新たなEmacsプロセスを開始する。

関数kill-emacsは通常はより高レベルなコマンドC-x C-c (save-buffers-kill-terminal)を通じて呼び出される。Exiting in The GNU Emacs Manualを参照のこと。これはEmacsがオペレーティングシステムのシグナルSIGTERMSIGHUPを受け取った場合(たとえば制御端末が切断されたとき)や、batchモードで実行中にSIGINTを受け取った場合(batchモードを参照)にも自動的にこれが呼び出される。

Variable: kill-emacs-hook

このノーマルフックはEmacsのkillの前にkill-emacsにより実行される。

kill-emacsはユーザーとの対話が不可能な状況(たとえば端末が切断されたとき)で呼び出されるかもしれないので、このフックの関数はユーザーとの対話を試みるべきではない。Emacsシャットダウン時にユーザーと対話したければ下記のkill-emacs-query-functionsを使用すること。

Emacsをkillしたときには保存されたファイルを除きEmacsプロセス内のすべての情報が失われます。うっかりEmacsをkillすることで大量の作業が失われるので、save-buffers-kill-terminalコマンドは保存を要するバッファーがあったり実行中のサブプロセスがある場合には確認の問い合わせを行います。これはアブノーマルフックkill-emacs-query-functionsも実行します。

User Option: kill-emacs-query-functions

save-buffers-kill-terminalがEmacsをkillする際には標準の質問を尋ねた後、kill-emacsを呼び出す前にこのフック内の関数を呼び出す。関数は出現順に引数なしで呼び出される。関数はそれぞれ追加でユーザーから確認を求めることができる。それらのいずれかがnilをリターンするとsave-buffers-kill-emacsはEmacsをkillせずに、このフック内の残りの関数は実行されない。直接kill-emacsを呼び出すとフックは実行されない。

Command: restart-emacs

このコマンドはsave-buffers-kill-emacsと同じことを行うが、最後にカレントEmacsプロセスをkillするだけではなく、カレントで実行中のEmacsプロセスと同じコマンドライン引数を用いて新たなEmacsプロセスを再起動する点が異なる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.2.2 Emacsのサスペンド

テキスト端末ではEmacsのサスペンドができます。これはEmacsを一時的にストップして上位のプロセスに制御を返します。これは通常はshellです。これにより後で同じEmacsプロセス内の同じバッファー、同じkillリング、同じアンドゥヒストリー、...で編集を再開できます。Emacsを再開するには親shell内で適切なコマンド — 恐らくはfg — を使用します。

そのEmacsセッションが開始された端末デバイス上でのみサスペンドは機能します。そのデバイスのことをセッションの制御端末(controlling terminal)と呼びます。制御端末がグラフィカルな端末ならサスペンドは許されません。グラフィカルな端末ではEmacsで特別なことをせずに単に別のアプリケーションにスイッチできるのでサスペンドは通常は関係ありません。

いくつかのオペレーティングシステム(SIGTSTPのないシステムやMS-DOS)ではジョブの停止はサポートされません。これらのシステムでの停止はEmacsのサブプロセスとして新たなshellを一時的に作成します。Emacsに戻るためにはshellをexitすればよいでしょう。

Command: suspend-emacs &optional string

この関数はEmacsを停止して上位のプロセスに制御を返す。上位プロセスがEmacsを再開する際には、Lispでのsuspend-emacsの呼び出し元にnilをリターンする。

この関数はそのEmacsセッションの制御端末上でのみ機能する。他のTTYデバイスの制御を放棄するにはsuspend-ttyを使用する(下記参照)。そのEmacsセッションが複数の端末を使用する場合にはEmacsのサスペンド前に他のすべての端末からフレームを削除しなければならず、さもないとこの関数はエラーをシグナルする。複数の端末を参照のこと。

stringが非nilなら、その各文字はEmacsの上位shellに端末入力として送信される。string内の文字は上位shellによりエコーされずに結果だけが表示される。

サスペンドする前にsuspend-emacsはノーマルフックsuspend-hookを実行する。ユーザーがEmacs再開後にsuspend-emacsはノーマルフックsuspend-resume-hookを実行する。フックを参照のこと。

再開後の次回再表示では変数no-redraw-on-reenternilならスクリーン全体が再描画される。スクリーンのリフレッシュを参照のこと。

以下はこれらのフックの使用例:

(add-hook 'suspend-hook
          (lambda () (or (y-or-n-p "Really suspend?")
                         (error "Suspend canceled"))))
(add-hook 'suspend-resume-hook (lambda () (message "Resumed!")
                                 (sit-for 2)))

(suspend-emacs "pwd")を評価すると以下を目にするだろう:

---------- Buffer: Minibuffer ----------
Really suspend? y
---------- Buffer: Minibuffer ----------

---------- Parent Shell ----------
bash$ /home/username
bash$ fg

---------- Echo Area ----------
Resumed!

Emacsサスペンド後に‘pwd’がエコーされないことに注意。エコーはされないがshellにより読み取られて実行されている。

Variable: suspend-hook

この変数はEmacsがサスペンド前に実行するノーマルフック。

Variable: suspend-resume-hook

この変数はサスペンド後の再開時にEmacsが実行するノーマルフック。

Function: suspend-tty &optional tty

ttyにEmacsが使用する端末デバイスを指定すると、この関数はそのデバイスを放棄して以前の状態にリストアする。そのデバイスを使用していたフレームは存在を続けるが更新はされず、Emacsはそれらのフレームから入力を読み取らない。ttyには端末オブジェクト、フレーム(そのフレームの端末の意)、nil (選択されたフレームの端末の意)を指定できる。複数の端末を参照のこと。

ttyがサスペンド済みなら何も行わない。

この関数は端末オブジェクトを各関数への引数としてフックsuspend-tty-functionsを実行する。

Function: resume-tty &optional tty

この関数は以前にサスペンドされたデバイスttyを再開する。ここでttysuspend-ttyに指定できる値と同じである。

この関数は端末デバイスの再オープンと再初期化を行い、その端末の選択されたフレームで端末を再描画する。それから端末ブジェクトを各関数への引数としてフックresume-tty-functionsを実行する。

同じデバイスが別のEmacs端末で使用済みなら、この関数はエラーをシグナルする。ttyがサスペンドされていなければ何もしない。

Function: controlling-tty-p &optional tty

この関数はttyがそのEmacsセッションの制御端末なら非nilをリターンする。ttyには端末オブジェクト、フレーム(そのフレームの端末の意)、nil (選択されたフレームの端末の意)を指定できる。

Command: suspend-frame

このコマンドはフレームをサスペンドする。GUIフレームではiconify-frameを呼び出す(フレームの可視性を参照)。テキスト端末上のフレームでは、そのフレームが制御端末デバイス上で表示されていればsuspend-emacs、されていなければsuspend-ttyのいずれかを呼び出す。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.3 オペレーティングシステムの環境

Emacsはさまざまな変数を通じてオペレーティングシステム環境内の変数へのアクセスを提供します。これらの変数にはシステムの名前、ユーザーのUIDなどが含まれます。

Variable: system-configuration

この変数はユーザーのシステムのハードウェアとソフトウェアにたいするGNUの標準コンフィグレーション名(standard GNU configuration name)を保持する。たとえば64ビットGNU/Linuxシステムにたいする典型的な値は‘"x86_64-unknown-linux-gnu"’。

Variable: system-type

この変数の値はEmacs実行中のオペレーティングシステムのタイプを示すシンボル。可能な値は:

aix

IBMのAIX。

berkeley-unix

Berkeley BSDとその変種。

cygwin

MS-Windowsで最上位のPosixレイヤーであるCygwin。

darwin

Darwin (macOS).

gnu

(HURDとMachから構成される)GNUシステム。

gnu/linux

GNU/Linuxシステム — すなわちLinuxカーネルを使用するGNUシステムの変種(これらのシステムは人がしばしば“Linux”と呼ぶシステムだが実際にはLinuxは単なるカーネルであってシステム全体ではない)。

gnu/kfreebsd

FreeBSDカーネルによる(glibcベースの)GNUシステム。

haiku

Beオペレーティングシステムから派生したHaikuオペレーティングシステム。

hpux

ヒューレット・パッカードのHPUXオペレーティングシステム。

nacl

Google Native Client(NaCl)サンドボックスシステム。

ms-dos

MicrosoftのDOS。MS-DOSにたいするDJGPPでコンパイルされたEmacsは、たとえMS-Windows上で実行されていてもsystem-typems-dosにバインドされる。

usg-unix-v

AT&TのUnix System V。

windows-nt

MicrosoftのWindows NT、9X以降。たとえばWindows 10でもsystem-typeの値は常にwindows-nt

わたしたちは絶対に必要になるまでは、より細分化するために新たなシンボルを追加したくありません。実際のところ将来的にはこれらの候補のいくつかを取り除きたいと思っています。system-typeで許されているより細分化する必要がある場合には、たとえば正規表現にたいしてsystem-configurationをテストできます。

Function: system-name

この関数は実行中のマシン名を文字列としてリターンする。

User Option: mail-host-address

この変数が非nilの場合には、emailアドレスを生成するためにsystem-nameのかわりにこの変数が使用される。たとえばこれはuser-mail-addressのデフォルト値の構築時に使用される。ユーザーの識別を参照のこと。

Command: getenv var &optional frame

この関数は環境変数varの値を文字列としてリターンする。varは文字列であること。その環境内でvarが未定義ならgetenvnilをリターンする。varがセットされているがnull(訳注: 空文字列)なら‘""’をリターンする。Emacs内では環境変数とそれらの値のリストは変数process-environment内に保持されている。

(getenv "USER")
     ⇒ "lewis"

shellコマンドprintenvは環境変数のすべて、または一部をプリントする:

bash$ printenv
PATH=/usr/local/bin:/usr/bin:/bin
USER=lewis
TERM=xterm
SHELL=/bin/bash
HOME=/home/lewis
Command: setenv variable &optional value substitute

このコマンドはvariableという名前の環境変数の値にvalueをセットする。variableは文字列であること。内部的にはEmacs Lispは任意の文字列を扱える。しかしvariableは通常はshell識別子として有効、すなわちアルファベットかアンダースコアで始まり、アルファベットか数字またはアンダースコアのシーケンスであること。それ以外ならEmacsのサブプロセスがvariableの値にアクセスを試みるとエラーが発生するかもしれない。valueが省略かnilの場合(またはプレフィクス引数とともにインタラクティブに呼び出された場合)には、setenvはその環境からvariableを削除する。それ以外ならvariableは文字列であること。

オプション引数substituteが非nilなら、value内のすべての環境変数を展開するためにEmacsは関数substitute-env-varsを呼び出す。

setenvprocess-environmentを変更することにより機能する。この変数をletでバインドするのも合理的プラクティスである。

setenvvariableの新たな値、または環境からvariableが削除されていればnilをリターンする。

Macro: with-environment-variables variables body…

このマクロはbodyを実行する際に、variablesに応じて環境変数を一時的にセットする。終了時には以前の値がリストアされる。引数variables(var value)という形式の文字列ペアーのリストであること。ここでvarは環境変数の名前、valueはその変数の値。

(with-environment-variables (("LANG" "C")
                             ("LANGUAGE" "en_US:en"))
  (call-process "ls" nil t))
Variable: process-environment

この変数はそれぞれが1つの環境変数を記す文字列リスト。関数getenvsetenvはこの変数により機能する。

process-environment
⇒ ("PATH=/usr/local/bin:/usr/bin:/bin"
    "USER=lewis"
    "TERM=xterm"
    "SHELL=/bin/bash"
    "HOME=/home/lewis"
    …)

process-environmentに同じ環境変数を指定す複数の要素が含まれる場合には、それらの最初の要素が変数を指定して他は無視される。

Variable: initial-environment

この変数はEmacs開始時にその親プロセスからEmacsが継承した環境変数のリストを保持する。

Variable: path-separator

この変数は、(環境変数で見つけた)検索パス内でディレクトリーを区切る文字を示す文字列を保持する。値はUnixとGNUシステムでは":"、MSシステムでは";"

Function: path-separator

この関数は変数path-separatorの接続ローカル値をリターンする。これはMSシステムかつローカルのdefault-directoryなら";"、UnixおよびGNUのシステムまたはリモートのdefault-directoryなら":"

Function: parse-colon-path path

この関数は環境変数PATHの値のような検索パス文字列を引数に受け取り、セパレーターで分割してディレクトリーのリストをリターンする。このリスト内ではnilはカレントディレクトリーを意味する。この関数の名前からはセパレーターは“コロン”となるが、実際に使用するのは変数path-separatorの値。

(parse-colon-path ":/foo:/bar")
     ⇒ (nil "/foo/" "/bar/")
Variable: invocation-name

この変数はEmacsが呼び出された時のプログラム名を保持する。値は文字列でありディレクトリー名は含まれない。

Variable: invocation-directory

この変数はEmacs実行可能形式が実行されたときに配置されていたディレクトリー名、ディレクトリーが判断できなければnilをリターンする。

Variable: installation-directory

nilならサブディレクトリーlib-srcetcを探すディレクトリーである。インストールされたEmacsなら通常はnil。Emacsが標準のインストール位置にそれらのディレクトリーを見つけられないものの、Emacs実行可能形式を含むディレクトリー(たとえばinvocation-directory)に何らかの関連があるディレクトリーで見つかることができたら非nil

Function: load-average &optional use-float

この関数はカレント、1分、5分、15分のロードアベレージ(load averages: 平均負荷)をリストでリターンする。このロードアベレージはシステム上で実行を試みているプロセス数を示す。

デフォルトでは値はシステムロードアベレージを100倍にした整数だが、use-floatが非nilなら100を乗ずることなくこれらの値は浮動小数点数としてリターンされる。

ロードアベレージ入手が不可能ならこの関数はエラーをシグナルする。いくつかのプラットフォームではロードアベレージへのアクセスにカーネル情報を読み取れるように、通常は推奨されないsetuidかsetgidしたEmacsのインストールを要する。

1分のロードアベレージは利用できるが、5分と15分のアレージは利用できなければ、この関数は利用可能なアベレージを含んだ短縮されたリストをリターンする。

(load-average)
     ⇒ (169 48 36)
(load-average t)
     ⇒ (1.69 0.48 0.36)

shellコマンドのuptimeはこれと類似する情報をリターンする。

Function: emacs-pid

この関数はEmacsプロセスのプロセスIDを整数としてリターンする。

Variable: tty-erase-char

この変数はEmacs開始前にそのシステムの端末ドライバーで選択されていたerase文字を保持する。

Variable: null-device

この変数はシステムのnullデバイスを保持する。値はUnixおよびGNUシステムでは"/dev/null"、MSシステムでは"NUL"

Function: null-device

この関数は変数null-deviceの接続ローカル値をリターンする。これはMSシステムかつローカルのdefault-directoryなら"NUL"、UnixおよびGNUシステムまたはリモートのdefault-directoryなら"/dev/null"


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.4 ユーザーの識別

Variable: init-file-user

この変数はEmacsによりどのユーザーのinitが使用されるべきか — なければnilをリターンする。""はログイン時のオリジナルのユーザーをリターンする。この値は‘-q’や‘-u user’のようなコマンドラインオプションを反映する。

カスタマイズ関連のファイルや、他の類の短いユーザープロファイルをロードするLispパッケージは、それをどこで探すか判断するためにこの変数にしたがうこと。これらのLispパッケージはこの変数内で見つかったユーザー名のプロファイルをロードすること。init-file-usernilなら‘-q’、‘-Q’、または‘-batch’オプションが使用されたことを意味しており、その場合にはLispパッケージはカスタマイズファイルやユーザープロファイルを何もロードするべきではない。

User Option: user-mail-address

これはEmacsを使用中のユーザーの電子メールアドレスを保持する。

Function: user-login-name &optional uid

この関数はユーザーのログイン名をリターンする。これはいずれかがセットされていれば環境変数LOGNAMEUSERを使用する。それ以外なら値は実UIDではなく実効UIDにもとづく。

uid (数字)を指定するとuidに対応するユーザー名、そのようなユーザーが存在しなければnilが結果となる。

Function: user-real-login-name

この関数はEmacsの実UIDに対応するユーザー名をリターンする。これは実効UID、および環境変数LOGNAMEUSERを無視する。

Function: user-full-name &optional uid

この関数はログインユーザーの完全名、環境変数NAMEがセットされていればその値をリターンする。

EmacsプロセスのユーザーIDが既知のユーザーに不一致(かつ与えられたNAMEが未セット)なら結果は"unknown"

uidが非nilなら数字(ユーザーID)か文字列(ログイン名)であること。その場合にはuser-full-nameはそのユーザー名かログイン名に対応する完全名をリターンする。未定義のユーザー名かログイン名を指定するとnilをリターンする。

シンボルuser-login-nameuser-real-login-nameuser-full-nameは変数であると同時に関数でもあります。関数の場合には、その名前の変数と同じ値をリターンします。これらの変数を使えば対応する関数が何をリターンするべきかを告げることによりEmacsを騙すことができます。またフレームタイトルの構築においても、これらの関数は有用です(フレームのタイトルを参照)。

Function: user-real-uid

この関数はユーザーの実UIDをリターンする。 This function returns the real of the user.

Function: user-uid

この関数はユーザーの実効UIDをリターンする。

Function: group-gid

この関数はEmacsプロセスの実効GIDをリターンする。

Function: group-real-gid

この関数はEmacsプロセスの実GIDをリターンする。

Function: system-users

この関数はシステム上のユーザー名をリストする文字列リストをリターンする。この情報をEmacsが取得できなければuser-real-login-nameの値だけを含んだリストをリターンする。

Function: system-groups

この関数はシステム上のグループ名をリストする文字列リストをリターンする。この情報をEmacsが取得できなければリターン値はnil

Function: group-name gid

この関数は数値のグループID gidに対応するグループ名、そのようなグループがなければnilをリターンする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.5 時刻

このセクションではカレント時刻とタイムゾーンを決定する方法を説明します。

current-timefile-attributesのような多くの関数は秒をカウントするLispタイムスタンプ(Lisp timestamp)値をリターンします。この値は1970-01-01 00:00:00 UTC(Coordinated Universal Time: 協定世界時)というエポック(epoch)からの経過秒数をカウントすることにより絶対時刻を表すことができます。通常これらのカウントは閏秒(leap seconds)を無視します。ただしGNUや一部のオペレーティングシステムでは閏秒をカウントするように構成できます。

伝統的なLispタイムスタンプが整数のペアであったとしても、それらの形式は進化しており、プログラムは通常はカレントのデフォルト形式に依存するべきではありません。プログラムに特定のタイムスタンプ形式が必要なら、time-convert関数を使用して必要とする形式に変換できます。時刻の変換を参照してください。

現在のところ3つのLispタイムスタンプ形式があり、それぞれが秒数を表します:

  • 整数。これがもっとも単純な形式だが、小数秒のタイムスタンプは表現できない。
  • 整数のペア(ticks . hz) ( hzは正)。これはticks/hz秒を表し、hzが1なら単なるticksと同時刻。hzにたいして一般的な値はナノ秒解像度クロック用の1000000000。
  • 4つの整数からなるリスト(high low micro pico) (0≤low<65536、0≤micro<1000000、0≤pico<1000000)。これは次式を使用して秒数を表す: high * 2**16 + low + micro * 10**-6 + pico * 10**-12。 current-time-listtの場合には、一部の関数がデフォルトでmicroおよびpicoを0に省略した2つ、または3つの要素のリストをリターンする場合があるかもしれない。現在のすべてのマシンではpicoは1000の倍数だが、より高精度のクロックが利用可能になったらこれは変更されるかもしれない。

関数の引数(format-time-stringtime引数)には、より一般的なtime値(time value)のフォーマット(Lispタイムスタンプ、カレント時刻にたいするnil、秒にたいする有限浮動小数点数、欠落要素を0に切り詰めたタイムスタンプリスト(high low micro) )が許されています。

time値は暦形式や他形式に相互に変換できます。これらの変換のいくつかは利用可能なtime値範囲を制限するオペレーティングシステム関数に依存しており、その制限を超えると‘"Specified time is not representable"’のようなエラーをシグナルします。たとえばあるシステムではエポック以前のタイムスタンプ、あるいは遠い将来の年をサポートしないかもしれません。format-time-stringを使用して可読性のある文字列、time-convertを使用してLispタイムスタンプ、decode-timefloat-timeを使用して別の形式にtime値を変換できます。これらの関数については以降のセクションで説明します。

Function: current-time-string &optional time zone

この関数はカレントの時刻と日付を可読形式の文字列でリターンする。この文字列の先頭部分には曜日、月、日付、時刻がこの順に含まれて、それらが可変長となることはない。これらのフィールドにたいして使用される文字数は常に同じとはいえ、年は正確に4桁とはかぎらず、いつかの将来に終端に追加情報が追加されるかもしれないので、current-time-stringの出力からフィールドを抽出するよりformat-time-stringを使うほうが通常は便利です。

引数timeが与えられたら、それはカレント時刻のかわりにフォーマットする時刻を指定する。オプション引数zoneのデフォルトはカレントのタイムゾーンルール。タイムゾーンのルールを参照のこと。timeの範囲およびzoneの値はオペレーティングシステムが制限する。

(current-time-string)
     ⇒ "Fri Nov  1 15:59:49 2019"
Variable: current-time-list

これは移行支援用のブーリーン変数である。tならcurrent-timeや関連する関数は(high low micro pico))、それ以外なら(ticks . hz)という形式を用いてタイムスタンプをリターンする。現在のところ以前のバージョンのEmacsの挙動と互換性をとるために、この変数のデフォルトはtになっている。この変数のデフォルトはEmacsの将来のバージョンではnilとなり、その後いくつかのバージョンを経た後に削除されるので、開発者はこの変数をnilにセットしてタイムスタンプ関連のコードをテストするようお勧めする。

Function: current-time

この関数はカレント時刻をLispタイムスタンプとしてリターンする。current-time-listnilならタイムスタンプの形式は(ticks . hz) (ticksはクロックチックカウント、hzは1秒当たりのクロックチック)、それ以外の場合にはタイムスタンプは(high low usec psec)という形式のリスト。current-time-listの値に関わらず特定の形式を得るには(time-convert nil t)(time-convert nil 'list)を使うことができる。時刻の変換を参照のこと。

Function: float-time &optional time

この関数はエポックからの経過秒数を浮動小数点数としてリターンする。オプション引数time-valueが与えられた場合には、カレント時刻ではなく変換する時刻を指定する。

警告: 結果は浮動小数点数なので正確ではないかもしれない。正確なタイムスタンプが必要なら使用しないこと。たとえば典型的なシステムにおいては(float-time '(1 . 10))を‘0.1’と表示するが、これは1/10より若干大きい。

time-to-secondsはこの関数のエイリアス。

Function: current-cpu-time

カレントCPU時間を解像度とともにリターンする。値は(CPU-TICKS . TICKS-PER-SEC)のようなペアーとしてリターンされる。CPU-TICKSカウンターはラップアラウンド(wrap around: 最後に達したら最初に戻る)するかもしれないので、時間が経過し過ぎると値の比較は無意味になるだろう。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.6 タイムゾーンのルール

デフォルトのタイムゾーンは環境変数TZにより判断されます。オペレーティングシステムの環境を参照してください。たとえば(setenv "TZ" "UTC0")とすれば万国標準時の使用をEmacsに指示できます。その環境にTZがなければ、Emacsはプラットフォーム依存のデフォルト時刻であるシステムの実時間(system wall clock time)を使用します。

サポートされるTZのセットはシステム依存です。GNUと他の多くのシステムはTZDBタイムゾーンをサポートします。これはたとえば‘"America/New_York"’はニューヨーク市周辺のタイムゾーンを夏時間ヒストリーを指定します。GNUと他の多くのシステムはPOSIXスタイルのTZセッティングをサポートします。これはたとえば‘\"EST+5EDT,M4.1.0/2,M10.5.0/2\"’は1987から2006にニューヨークで使用されたルールを指定します。すべてのシステムは万国標準時(Universal Time)を意味する‘"UTC0"’文字列をサポートします。

ローカル時刻にたいする変換関数は、変換のタイムゾーンと夏時間の履歴を指定するタイムゾーンルール)time zone ruleをオプションとして受け取ります。タイムゾーンルールが省略かnilなら、変換にはデフォルトのタイムゾーン、tなら万国標準時、wallならシステムの実時間(system wall clock time)が使用されます。これが文字列なら変換にはTZにその文字列をセットしたのと等価なタイムゾーンルールが使用されます。(offset abbr) ( offsetは万国標準時刻より進んでいる秒数を与える整数でabbrは文字列)のようなリストなら、変換には与えられたオフセットと省略名の固定タイムゾーンが使用されます。整数offsetの場合には、POSIX互換プラットフォームでは数値省略形のabbr、MS-Windowsでは未指定のabbrのとなるような(offset abbr)であるかのように扱われます。

Function: current-time-zone &optional time zone

この関数はユーザーが居るタイムゾーンを記すリストをリターンする。

値は(offset abbr)という形式をもつ。ここでoffsetは万国標準時刻より進んでいる秒数(グリニッジより東)を与える整数。負の値はグリニッジより西を意味する。2つ目の要素abbrはそのタイムゾーンのを与える省略名の文字列。たとえば‘"CST"’は中国標準時か米国中部標準時のタイムゾーン。夏時間の開始と終了時に、いずれの要素も変化し得る。ユーザーが季節時間調整を用いていないタイムゾーンを指定した場合には、値は時期を通して定数となる。

この値を計算するのに必要なすべての情報をオペレーティングシステムが提供しなければ、このリストの未知の要素はnilになる。

引数timeが与えられたら、それはカレント時刻のかわりに分析するべきtime値を指定する。オプション引数zoneのデフォルトはカレントのタイムゾーンルール。timeの範囲およびzoneの値はオペレーティングシステムが制限する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.7 時刻の変換

以下の関数はtime値(時刻を参照)をLispタイムスタンプや暦情報(calendrical information)に変換したり逆の変換を行います。

秒を数えるために多くのオペレーティングシステムは64ビット符号付き整数を使用しており、過去や未来の時刻を表すことができます。しかしより制限されているオペレーティングシステムもいくつか存在します。たとえば32ビット符号付き整数を使用する旧式のオペレーティングシステムでは、通常は協定世界時で1901-12-13 20:45:52から2038-01-19 03:14:07までの時刻しか扱うことができません。

暦変換関数はたとえグレゴリオ暦導入前の日付や、グレゴリオ暦では誤差が非常大きくなるために天文学や古生物学のような科学分野の一般的慣習としてユリウス暦の年数が使用されるような遠い過去や未来の日付であってもグレゴリオ暦を使用します。伝統的なグレゴリオ年が行うように0年をスキップせずにBCE 1年から年数を数えます。たとえば年数-37はグレゴリオ年のBCE 38年を表します。

Function: time-convert time form

この関数はtime値をLispタイムスタンプに変換する。

form引数はリターンするタイムスタンプ形式を指定する。この関数はformがシンボルintegerなら整数でカウントした秒数をリターンする。正の整数のformはクロック周波数を指定する。その場合にはこの関数は(ticks . form)という整数ペアのタイムスタンプをリターンする。formtなら、この関数はタイムスタンプを適切に表現するような正の整数としてそれを扱う。たとえばtimenilでプラットフォームのタイムスタンプがナノ秒の解像度をもつ場合には1000000000としてそれを扱う。formlistなら、この関数は整数のリスト(high low micro pico)をリターンする。現在のところformnilの場合にはlistのように動作するとしても、Emacsの将来バージョンで変更が予定されているので、呼び出し側がリスト形式のタイムスタンプを必要とする場合には明示的にlistを渡すこと。

timeがtime値でなければ、この関数はエラーをシグナルする。それ以外の場合には、timeを正確に表せなければ負の無限大方向に切り詰めて変換する。formtなら変換は常に正確なので切り詰めは発生せず、リターン値のクロック解像度がtimeの解像度より小さくなることはない。それとは対照的にfloat-timeはエラーをシグナルせずに任意のtime値を変換できるものの、結果は不正確かもしれない。時刻を参照のこと。

この関数は効率化のためにtimeeqな値、あるいはtimeと構造を共有する値をリターンするかもしれない。

(time-convert nil nil)(current-time)と等価だが後者は幾分速い。

(setq a (time-convert nil t))
⇒ (1564826753904873156 . 1000000000)
(time-convert a 100000)
⇒ (156482675390487 . 100000)
(time-convert a 'integer)
⇒ 1564826753
(time-convert a 'list)
⇒ (23877 23681 904873 156000)
Function: decode-time &optional time zone form

この関数はtime値を暦情報に変換する。timeを指定しなければカレント時刻をデコードする。同様にzoneのデフォルトはカレントのタイムゾーンルール。タイムゾーンのルールを参照のこと。timeの範囲およびzoneの値はオペレーティングシステムが制限する。

form引数はリターンされるseconds要素の形式を制御する(以下参照)。リターン値は以下のような9要素のリスト:

(seconds minutes hour day month year dow dst utcoff)

以下は各要素の意味:

seconds

以下で説明する形式による、分秒の秒。

minutes

0から59までの整数で表した時を過ぎた時分秒の分。

hour

0から23までの整数で表した時分秒の時。

day

1から31までの整数で表した年月日の日。

month

1から12までの整数で表した年月日の月。

year

通常は1900より大きい整数で表した年月日の年。

dow

0から6までの整数で表した曜日であり0は日曜日を意味する。

dst

夏時間が有効ならt、無効ならnil、その情報が利用できなければ-1。

utcoff

万国標準時からの秒数、すなわち東グリニッジの秒数を示す整数。

Lispタイムスタンプのseconds要素は非負かつ61より小さいこと。これはは正の閏秒の間以外は60より小さくなる(オペレーティングシステムが閏秒をサポートする場合)。オプションのform引数がtなら、secondstimeと同じ精度を使用する。formintegerならsecondsを整数に切り捨てる。たとえばtimeがタイムスタンプ(1566009571321 . 1000) (閏秒がない通常のシステムでは2019-08-17 02:39:31.321 UTCを表す)なら、(decode-time time t t)((31321 . 1000) 39 2 17 8 2019 6 nil 0)だが(decode-time time t 'integer)(31 39 2 17 8 2019 6 nil 0)をリターンする。formが省略かnilの場合のデフォルトは現在のところintegerだが、このデフォルトはEmacsの将来バージョンで変更されるかもしれないので、呼び出し側は特定の形式が必要ならformを指定すること。

Common Lispに関する注意: Common Lispではdowdstutcoffの意味が異なり、secondは0から59(両端を含む)の整数である。

暦情報の要素にアクセス(や変更)するためのアクセッサとしてdecoded-time-seconddecoded-time-minutedecoded-time-hourdecoded-time-daydecoded-time-monthdecoded-time-yeardecoded-time-weekdaydecoded-time-dstdecoded-time-zoneを使用できる。

Function: encode-time time &rest obsolescent-arguments

これはtimeをLispタイムスタンプに変換する。これはdecode-timeの逆の関数として機能する。

通常だとdecode-time形式でデコードされた時刻を指定する(second minute hour day month year ignored dst zone)がリストの1つ目の引数となる。これらのリスト要素の意味については、decode-timeのテーブルを参照のこと。特にdstはタイムスタンプが繰り返される夏時間(DST: daylight saving time)の期間中のフォールバックにおけるタイムスタンプの解釈法を指定する。dstが-1ならDSTを推測、tnilの場合にはそのDST値をもつタイムスタンプをリターン、そのようなタイムスタンプが存在しなければエラーをシグナルする。残念なことにtnildst値は、たとえばzoneが‘"Europe/Volgograd"’において、その日の02:00にグリニッジ東の標準時を+04:00から+03:00に変更した際の2020-12-27 01:30にたいする2つの標準時タイムスタンプの不明確さといったような、TZDBタイムゾーンがグリニッジを更に超えて西に移動した際における重複したタイムスタンプの不明確さを解消するものではない。このような状況を処理するためには、不明確さを解消するために数値のzoneを使用することができる。

1つ目の引数は(second minute hour day month year)のようなリストでもよい。これは(second minute hour day month year nil -1 nil)のようなリストとして扱われる。

廃れた呼び出し規約として、この関数は6つ以上の引数を受け取ることができる。最初の6つの引数secondminutehourdaymonthyearはデコード済みtimeのほとんどの要素を指定する。7つ目以降の引数があれば、最後の引数はzoneとして使用されれるので、(apply #'encode-time (decode-time ...))は機能する。この廃れた規約においてはdstは-1、zoneのデフォルトはカレントタイムゾーンルール(タイムゾーンのルールを参照)となる。時代遅れな呼び出し側を現代化する際には、9つの要素を含んだより最新の同等リストのdst要素に、nilではなく-1がセットされていることを確認すること。

100未満の年が特別に扱われることはない。これに1900や2000を超える年を意味させたい場合には、encode-timeを呼び出す前に自身でこれらを修正しなければならない。timeの範囲およびzoneの値はオペレーティングシステムが制限する。とはいえエポックから近い将来に渡るタイムスタンプ範囲は常にサポートされる。

encode-time関数はdecode-timeのラフな逆関数として動作する。たとえば以下のように後者の出力を前者に渡すことができる:

(encode-time (decode-time …))

secondsminuteshourdaymonthに範囲外の値を使用することにより単純な日付計算ができる。たとえばdayが0なら与えられたmonthの前月末日になる。失敗する場合もよくあるので、これを行う際には注意すること。たとえば:

;; 現在から1ヶ月後を算出。
;; 期待どおりに動かないかもしれないので注意
(let ((time (decode-time)))
  (setf (decoded-time-month time)
        (+ (decoded-time-month time) 1))
  time)

残念ながらこのコードは月の長さの違いによって結果時刻が不正になったり、夏時間への移行、タイムゾーン変更、閏日や閏秒を考慮しない等で期待どおり動作しないかもしれない。たとえばこのコードを1月30日に実行すれば、encode-timeであれば3月初頭に調整するであろう2月30日という存在しない日付を得ることになる。同様に2096年2月29日に4年を加えた2100年2月29日は存在せず、ニューヨークで3月13日の01:30に1時間を加えるとタイムスタンプとして02:30を得るだろうが、ニューヨークではその日の02:00に03:00へ時刻が飛ぶのでこれも存在しないタイムスタンプを得ることになる。問題のいくつか(すべてではない)を回避するために影響を受ける単位の半ば、たとえば月の加算を行う際にはその月の15日で開始するといったような計算を基にすることができる。別の策としてはcalendartime-dateといったライブラリーを使うことができる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.8 時刻のパースとフォーマット

以下の関数はtime値とテキスト文字列の間で変換と逆変換を行います。time値はLispタイムスタンプ(時刻を参照)、またはデコード済みtime構造(時刻の変換を参照)のいずれかで表現されます。

Function: date-to-time string

この関数はtime文字列stringをパースして対応するLispタイムスタンプをリターンする。引数stringは日時を表現するparse-time-string (以下参照)が認識する形式のいずれかであること。この関数はstringに明示的なタイムゾーン情報が欠落していれば万国標準時(Universal Time)を仮定する。またstringに月、日、時刻がなければ、もっとも過去の値とみなす。timeの範囲およびzoneの値はオペレーティングシステムが制限する。

Function: parse-time-string string

この関数はtime文字列stringをデコード済みtime構造(時刻の変換を参照)にパースする。引数stringはRFC 822(またはそれ以降)やISO 8601に類似した“Fri, 25 Mar 2016 16:24:56 +0100”や“1998-09-12T12:21:54-0200”のような文字列であることが必要だが、この関数は形式が若干不正なtime文字列のパースも同様に試みる。

Function: iso8601-parse string

より厳格な(無効な入力にはエラーを出力する)関数のかわりに、この関数を使用できる。これはISO 8601標準の変種をパースできるので、上述のフォーマットに加えて“1998W45-3” (週番号)や“1998-245” (序数日)のような日付をパースできる。期間(duration)のパースはiso8601-parse-duration、間隔(interval)のパースにはiso8601-parse-intervalがある。これらの関数は最後の関数(それらのうち開始、終了、期間の3つをリターンする)を除いて、すべてデコード済みtime構造をリターンする。

Function: format-time-string format-string &optional time zone

この関数はLispタイムスタンプtime (省略かnilの場合のデフォルトはカレント時刻)をformat-stringに応じて文字列に変換する。この変換にはタイムゾーンルールzone (デフォルトはカレントのタイムゾーンルール)を使用する。タイムゾーンのルールを参照のこと。引数format-stringには、時刻を置換する‘%’シーケンスを含めることができる。以下は‘%’シーケンスは何を意味するかのテーブルである:

%a

曜日の短縮名を意味する。

%A

曜日の完全名を意味する。

%b

月の短縮名を意味する。

%B

月の完全名を意味する。

%c

%x %X’のシノニム。

%C

これは世紀、つまり年を100で除して小数点以下を切り捨てる。デフォルトのフィールド幅は2。

%d

0パディングされた年月日の日。

%D

%m/%d/%y’のシノニム。

%e

ブランクでパディングされた年月日の日。

%F

これは‘%+4Y-%m-%d’のようなISO 8601日付フォーマットと似ているが、‘+’と‘4’を任意のフラグとフィールド幅(6を減じた後)をオーバーライドする点が異なる。

%g

これはカレントのISO週(ISO week)の番号に対応する、世紀部分(00–99)を除いた年を意味する。ISO週は月曜が開始で終了は日曜。ISO週の開始と終了の年が異なる場合に‘%g’が生成する年にたいする規則は複雑であり、ここでは説明しない。しかし一般的には、もし週のうちのほとんどが終了年にあれば‘%g’はその年を生成するだろう。

%G

これはカレントのISO週番号に対応する、世紀を含めた年を意味する。

%h

%b’のシノニム。

%H

時分秒の時(00から23)を意味する。

%I

時分秒の時(01から12)を意味する。

%j

年内の経過日(001から366)を意味する。

%k

ブランクでパディングされた時分秒の時(0から23)を意味する。

%l

ブランクでパディングされた時分秒の時(1から12)を意味する。

%m

年月日の月(01から12)を意味する。

%M

時分秒の分(00から59)を意味する。

%n

改行を意味する。

%N

ナノ秒(000000000–999999999)を意味する。より少ない桁数を求める場合にはミリ秒は‘%3N’、マイクロ秒は‘%6N’を使用する。余分な桁は丸めずに切り捨てられる。

%p

必要に応じて‘AM’か‘PM’を意味する。

%q

これはカレンダーの四半期(1–4)を意味する(訳注: 会計年度で使用される4月1日を年度開始日とする四半期ではなく元旦を年度開始日とする四半期)。

%r

%I:%M:%S %p’のシノニム。

%R

%H:%M’のシノニム。

%s

これはエポック以降の経過秒数を表す整数。

%S

これは秒を意味する(00–59、閏年をサポートするプラットフォームでは00–60)。

%t

タブ文字を意味する。

%T

%H:%M:%S’のシノニム。

%u

これは数字で表した曜日(1から7)で、月曜日が1。

%U

週の開始を日曜日とみなした年内の週(01から52)。

%V

これはISO 8601にたいする年内の週を意味する。

%w

数字で表した曜日(0から6)で日曜日が0。

%W

これは週の開始を月曜日とみなした年内の週(01から52)。

%x

これはlocale固有の意味をもつ。デフォルトlocale(Cという名前のlocale)では‘%D’と等価。

%X

これはlocale固有の意味をもつ。デフォルトlocale(Cという名前のlocale)では‘%T’と等価。

%y

世紀を含まない年(00から99)を意味する。

%Y

世紀を併なう年を意味する。

%Z

タイムゾーンの短縮形(たとえば‘EST’)を意味する。

%z

これはタイムゾーンの数値オフセットを意味する。‘z’の前に1つ、2つ、または3つのコロンを前置できる。単なる‘%z’が‘-0500’を意味する場合には‘%:z’は‘-05:00’、‘%::z’は‘-05:00:00’を意味する。‘%:::z’は‘%::z’と同様だが末尾の‘:00’を無するので、この例では‘-05’を意味する。

%%

これは単独の‘%’を意味する。

%’の直後には1つ以上のフラグ文字を記述してもよい。‘0’は0、‘+’は0をパディングして5桁以上の非負の年の前に‘+’を配置、‘_’は空白によるパディング、‘-’はパディングの抑制、‘^’は英大文字、‘#’は文字のcase(大文字小文字)を反転させる。

これらの‘%’シーケンスすべてにたいしてフィールド幅とパディングのタイプの指定でのきる。これはprintfと同じように機能する。フィールド幅は‘%’シーケンス内の任意のフラグの後に数字として記述するたとえば‘%S’は分内で経過した秒数を指定するが、‘%03S’は3箇所の0、‘%_3S’は3箇所にスペースをパディングすることを意味する。ただの‘%3S’は0でパディングを行う。これは‘%S’が通常において2箇所にパディングする方法だからである。

文字‘E’と‘O’は、‘%’シーケンス内のすべてのフラグとフィールド幅の後に使用されたときは修飾子として作用する。‘E’は日付と時刻にカレントlocaleの“代替”バージョンの使用を指定する。たとえば日本のlocaleでは、%Exでは日本の元号にもとづく日付フォーマットを得られるだろう。‘E’では‘%Ec’、‘%EC’、‘%Ex’、‘%EX’、‘%Ey’、‘%EY’の使用が許されている。

O’は通常の10進数字(訳注: アラビア数字)ではなく、カレントlocaleの数字の代替表現を使用する。これは数字を出力する、ほとんどすべてのアルファベットで使用が許されている。

デバッグプログラム支援のために、認識されない‘%’シーケンスはそれ自体を意味しており、そのまま出力される。将来のEmacsバージョンでは拡張として新たな‘%’シーケンスが認識されるかもしれないので、プログラムはこの挙動に頼るべきではない。

この関数は処理のほとんどを行うためにCライブラリー関数strftimeを使用している(Formatting Calendar Time in The GNU C Library Reference Manualを参照)。その関数とやり取りするために最初にtimezoneを内部形式に変換する。timeの範囲およびzoneの値はオペレーティングシステムが制限する。この関数はformat-stringもエンコードする。strftimeが結果文字列をリターンした後に同じコーディングシステムを使用してformat-time-stringはデコードを行う。

Function: format-seconds format-string seconds

この関数は引数secondsformat-stringに応じた年、日、時、...の文字列に変換する。引数format-stringには変換を制御する‘%’シーケンスを指定することができる。以下のテーブルは‘%’の意味:

%y
%Y

年間365日での年の整数。

%d
%D

年月日の日。

%h
%H

時分秒の時の整数。

%m
%M

時分秒の分の整数。

%s
%S

秒数。オプションの‘,’パラメーターが使用されていたらそれは浮動小数点数であり、‘,’の後の数は使用する小数点以下の桁数を指定する。‘%,2s’は“小数点以下2桁の使用”を意味する。

%z

非プリント制御フラグ。これを使用する際には他の指定はサイズ減少順、すなわち年、日、時刻、分、...のように与えなければならない。最初の非0変換に遭遇するまで‘%z’の左側の結果文字列は生成されない。たとえばemacs-uptime (emacs-uptimeを参照)で使用されるデフォルトフォーマットでは、秒数は常に生成されるが年、日、時、分はそれらが非0の場合のみ生成されるだろう。

%x

%z’と同じ行に作用する非プリント制御フラグだが、末尾にある0値のtime要素のプリントを抑制する。

%%

リテラルの‘%’を生成する。

大文字のフォーマットシーケンスは数字に加えて単位を生成するが、小文字フォーマットは数字だけを生成する。

%’に続けてフィールド幅を指定できる。指定したフ幅より短ければブランクでパディングされる。この幅の前にオプションでピリオドを指定すれば、かわりに0パディングを要求する。たとえば"%.3Y""004 years"を生成するだろう。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.9 プロセッサーの実行時間

EmacsはEmacsプロセスにより使用された経過時間(elapsed time)とプロセッサー時間(processor time)の両方にたいして、それらをリターンする関数とプリミティブをいくつか提供します。

Command: emacs-uptime &optional format

この関数はEmacsのuptime — このEmacsインスタンスが実行してから経過した実世界における稼動時間を表す文字列をリターンする。この文字列はオプション引数formatに応じてformat-secondsによりフォーマットされる。利用できるフォーマット記述子についてはformat-secondsを参照のこと。formatnilか省略された場合のデフォルトは"%Y, %D, %H, %M, %z%S"

インタラクティブに呼び出されるとエコーエリアにuptimeをプリントする。

Function: get-internal-run-time

この関数はEmacsが使用したプロセッサー実行時間をLispタイムスタンプとしてリターンする(時刻を参照)。

この関数がリターンする値にはEmacsがプロセッサーを使用していない時間は含まれないこと、そしてEmacsプロセスが複数のスレッドをもつ場合には、すべてのEmacsスレッドにより使用されたプロセッサー時間の合計値がリターンされることに注意。

システムがプロセッサー実行時間を判断する方法を提供しなければget-internal-run-timecurrent-timeと同じ値をリターンする。

Command: emacs-init-time

この関数はEmacsの初期化(要約: スタートアップ時のアクション順序を参照)にかかった秒数を文字列としてリターンする。インタラクティブに呼び出された場合にはエコーエリアにプリントする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.10 時間の計算

以下の関数はtime値を使用して暦計算を行います(時刻を参照)。これらの関数でtime値を受け取るすべての引数では、他のtime値と同じようにnil値はカレントシステム時刻、有限の数値はエポックからの経過秒数を意味します。

Function: time-less-p t1 t2

これはtime値t1がtime値t2より小ならtをリターンする。

Function: time-equal-p t1 t2

この関数は2つのtime値t1t2等しければtをリターンする。引数のいずれかがNaNの場合は結果はnilとなる。比較という目的のために、nilの引数は無限大の解像度によるカレント時刻を表すので、呼び出し側は任意のタイムスタンプと等しくならない未知のtime値としてnilを使うことができる。したがって一方の引数がnilでもう一方がnilでなければこの関数はnilをリターンする。

Function: time-subtract t1 t2

これは2つのtime値の差t1 - t2をLispタイムスタンプとしてリターンする。結果は正確であり、そのクロック解像度が2つの引数の解像度より劣ることはない。経過秒の単位の差が必要なら、time-convertfloat-timeで変換できる。時刻の変換を参照のこと。

Function: time-add t1 t2

これはtime-subtractのようないくつかの変換ルールを使用して、2つのtime値の和をtime値としてリターンする。ここで引数のうち1つはある時点での時刻ではなく時間差を表すこと(time値は経過秒数という単一の数値であることがよくある)。以下はあるtime値に秒数を加算する方法:

(time-add time seconds)
Function: time-to-days time-value

この関数はAC. 1年元日からtime-valueまでの間の日数をデフォルトタイムゾーンとみなしてリターンする。timeの範囲およびzoneの値はオペレーティングシステムが制限する。

Function: time-to-day-in-year time-value

これはtime-valueに対応する年内の日数をデフォルトタイムゾーンとみなしてリターンする。timeの範囲およびzoneの値はオペレーティングシステムが制限する。

Function: date-leap-year-p year

この関数はyearが閏年ならtをリターンする。

Function: date-days-in-month year month

yearmonthの日数をリターンする。たとえば2020年2月は29日。

Function: date-ordinal-to-time year ordinal

yearの序数日ordinalをデコード済みtime構造体としてリターンする。たとえば2004年の120日目は2004年4月29日。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.11 遅延実行のためのタイマー

将来の特定時刻や特定の長さのアイドル時間経過後に関数を呼び出すためにタイマー(timer)をセットアップできます。タイマーは次回の呼び出し時刻と呼び出す関数についての情報を格納したスペシャルオブジェクトです。

Function: timerp object

この述語関数はobjectがタイマーなら非nilをリターンする。

EmacsはLispプログラム内では、任意の時点ではタイマーを実行できません。サブプロセスからの出力が受け入れ可能なときだけEmacsはタイマーを実行できます。つまり待機中や待機することが可能sit-forread-eventのような特定のプリミティブ関数内部でのみタイマーを実行できます。したがってEmacsがbusyならタイマーの実行は遅延するかもしれません。しかしEmacsがidleなら実行される時刻は非常に正確になります。

quitにより多くのタイマー関数が物事を不整合な状態に放置し得るので、ターマー関数呼び出し前にEmacsはinhibit-quittをバインドします。ほとんどのタイマー関数は多くの作業を行わないので、これは通常は問題にはなりません。しかし実際には実行に長時間を要する関数を呼び出すタイマーが問題となる恐れがあります。タイマー関数がquitを許容する必要があるならwith-local-quitを使用するべきです(quitを参照)。たとえば外部プロセスから出力を受け取るためにタイマー関数がaccept-process-outputを呼び出す場合には、外部プロセスのハング時のC-gを確実に機能させるために、その呼び出しをwith-local-quit内部にラップすべきです。

バッファー内容の変更のためにタイマー関数を呼び出すのは通常は悪いアイデアです。これを行うときには単一のアンドゥエントリーが巨大になるのを防ぐために、通常はバッファーの変更前後でundo-boundaryを呼び出して、タイマーによる変更とユーザーのコマンドによる変更を分離するべきです。

タイマー関数はsit-forのようなEmacsに待機を発生させるような関数(時間の経過や入力の待機を参照)の呼び出しも避けるべきです。その待機中に別のタイマー(同じタイマーとう可能性さえある)が実行され得るので、これは予測不可能な効果を導く恐れがあります。特定時間の経過後に処理される必要があるタイマー関数は、新たなタイマーをスケジュールしてこれを行うことができます。

タイマー関数がリモートファイルを処理する場合には、同一接続ですでに実行中のリモートファイル処理と競合する可能性があります。そのような競合が検出されると、結果はremote-file-errorエラーに格納されます(標準的なエラーを参照)。このようなエラーはタイマー関数のbodyでラップすることで保護する必要があります。

(ignore-error 'remote-file-error
  …)

マッチデータを変更するかもしれない関数を呼び出すタイマー関数はマッチデータの保存とリストアをするべきです。マッチデータの保存とリストアを参照してください。

Command: run-at-time time repeat function &rest args

これは時刻timeに引数argsで関数functionを呼び出すタイマーをセットアップする。repeatが数値(整数か浮動小数点数)ならタイマーはtime後の各repeat秒ごとに再実行されるようスケジュールされる。repeatnilならタイマーは1回だけ実行される。

timeには絶対時刻と相対時刻を指定できる。

絶対時刻は限定された種々フォーマットの文字列を使用して指定でき、すでに経過後の時刻であっても当日の時刻とみなされる。認識される形式は‘xxxx’、‘x:xx’、または‘xx:xx’ (軍用時間)、および‘xxam’、‘xxAM’、‘xxpm’、‘xxPM’、‘xx:xxam’、‘xx:xxAM’、‘xx:xxpm’、‘xx:xxPM’のいずれか。時と分の部分の区切りはコロンのかわりにピリオドも使用できる。

相対時刻は単位を付加した数字を文字列として指定する。たとえば:

1 min

現在時刻から1分後を表す。

1 min 5 sec

現在時刻から65秒後を表す。

1 min 2 sec 3 hour 4 day 5 week 6 fortnight 7 month 8 year

現在時刻から丁度103ヵ月123日10862秒後を表す。

相対time値にたいしてEmacsは月を正確に30日、年を正確に365.25とみなす。

有用なフォーマットのすべてが文字列という訳ではない。timeが数字(整数か浮動小数点数)なら秒で数えた相対時刻を指定する。encode-timeの結果はtimeにたいする絶対時刻の指定にも使用できる。

ほとんどの場合には、repeat最初に呼び出されている際には効果はなくtime単独で時刻を指定する。例外が1つありtimetならエポックからrepeatの倍数秒ごとに毎回そのタイマーが実行される。これはdisplay-timeのような関数にとって有用。たとえば以下はfunctionを“毎分丁度”(‘11:03:00’、‘11:04:00’、...)に実行する:

(run-at-time t 60 function)

タイマーが実行されるべきタイミングでEmacsがCPUタイムを取得できなかった場合(たとえば別プロセス実行中のためシステムがビジーだったり、コンピューターがスリープ中やサスペンド中の場合)には、Emacsが再開されてアイドルになり次第タイマーが実行される。

関数run-at-timeはスケジュール済みの将来の特定アクションを識別するtime値をリターンする。cancel-timer(以下参照)の呼び出しにこの値を使用できる。

Command: run-with-timer secs repeat function &rest args

これは正にrun-at-time と同じだが、これは遅延を秒で指定する際の使用を意図している(パラメーターはrun-at-timeの説明を参照。ただしこの関数はtimesecsとして渡している)。

タイマーのリピートは名目上はrepeat秒ごとに毎回実行されますが、すべてのタイマー呼び出しは遅延する可能性があることを忘れないでください。1つの繰り返しの遅延が次の繰り返しに影響を与えることはありません。たとえば3回分のスケジュール済みのタイマー繰り返しをカバーするほどの計算等によりEmacsがbusyでも、それらは待機を開始して連続してそのタイマー関数が3回呼び出されることになります(それらの間の別のタイマー呼び出しは想定していない)。最後の呼び出しからn秒より短くならずにタイマーを再実行したい場合にはrepeat引数を使用しないでください。タイマー関数は、かわりにそのタイマーを明示的に再スケジュールするべきです。

User Option: timer-max-repeats

この変数の値は以前スケジュールされていた呼び出しが止むを得ずに遅延された際に、タイマー関数がリピートによりまとめて呼び出される最大の回数を指定する

Macro: with-timeout (seconds timeout-forms…) body…

bodyを実行するがseconds秒後に実行を諦める。タイムアップ前にbodyが終了したら、with-timeoutbody内の最後のフォームの値をリターンする。ただしタイムアウトによりbodyの実行が打ち切られた場合には、with-timeouttimeout-formsをすべて実行して最後のフォームの値をリターンする。

このマクロはseconds秒後に実行するタイマーをセットすることにより機能する。その時刻の前にbodyが終了したらそのタイマーを削除して、タイマーが実際に実行されたらbodyの実行を終了してからtimeout-formsを実行する。

Lispプログラムでは待機を行えるプリミティブをプログラムが呼び出している時のみタイマーを実行できるので、bodyが計算途中の間はwith-timeoutは実行を停止できない — そのプログラムがこれらのプリミティブのいずれかを呼び出したときのみ停止できる。そのためbodyで長時間の計算を行う場合ではなく、入力を待機する場合だけwith-timeoutを使用すること。

あまりに長時間応答を待機するのを避けるために、関数y-or-n-p-with-timeoutはタイマーを使用するシンプルな方法を提供します。Yes-or-Noによる問い合わせを参照してください。

Function: cancel-timer timer

これはtimerにたいして要求されたアクションをキャンセルする。ここでtimerはタイマーであること。これは通常は以前にrun-at-timerun-with-idle-timerがリターンしたものである。この関数はこれらの関数の1つの呼び出しの効果をキャンセルする。指定した時刻が到来しても特に何も起きないだろう。

list-timersコマンドはカレントでアクティブなすべてのタイマーをリストします。コマンドc (timer-list-cancel)はポイントのある行のタイマーをキャンセルします。コマンドS (tabulated-list-sort)を使用すれば、列でリストをソートできます。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.12 アイドルタイマー

以下はEmacsの特定の期間アイドル時に実行するタイマーをセットアップする方法です。それらをセットアップする方法とは別にすればアイドルタイマーは通常のタイマーと同様に機能します。

Command: run-with-idle-timer secs repeat function &rest args

Emacsの次回secs秒間アイドル時に実行するタイマーをセットアップする。secsの値には数値、またはcurrent-idle-timeがリターンするタイプの値を指定できる。

repeatnilなら、Emacsが充分長い間アイドルになった初回の1回だけタイマーは実行される。これは大抵はrepeatが非nilの場合であり、そのときはEmacsがsecs秒間アイドルになったときに毎回そのタイマーが実行される。

関数run-with-idle-timercancel-timer呼び出し時に使用できるタイマー値をリターンする。

ユーザー入力の待機時にEmacsはアイドル(idle)となり、ユーザーが何らかの入力を与えるまでアイドルのままとなります(タイムアウト付きで入力を待機していない場合。単一イベントの読み取りを参照)。あるタイマーを5秒間のアイドルにセットすると、Emacsが最初に約5秒間アイドルになったときにタイマーが実行されます。たとえrepeatが非nilでもEmacsがアイドルであり続けるかぎりタイマーが再実行されることはありません。アイドル期間は増加を続けて再び5秒に減少することはないからです。

アイドル時にEmacsはガーベージコレクションや自動保存やサブプロセスからのデータ処理など、さまざまなことを行うことができます。しかしこれらの幕間劇がアイドルのクロックを0にリセットすることはないのでアイドルタイマーと干渉することはありません。600秒にセットされたアイドルタイマーはたとえその10分間にサブプロセスの出力が何回到達しても、たとえガーベージコレクションや自動保存が行われてもユーザーコマンドが最後に終了してから10分経過後に実行されるでしょう。

ユーザーが入力を与えるとEmacsは入力の実行の間は非アイドルになります。それから再びアイドルとなると、繰り返すようにセットアップされたすべてのアイドルタイマーは1つずつ異なる時刻に実行されるでしょう。

実行ごとに特定の量を処理するループを含んだり、(input-pending-p)が非nilのときにexitするアイドルタイマー関数を記述しないでください。このアプローチはとても自然に見えますが2つの問題があります:

  • すべてのプロセスの出力をブロックする(Emacsは待機時のみプロセス出力を受け入れるため)。
  • その時刻の間に実行されるべきすべてのアイドルタイマーをブロックする。

同様にsecs引数がカレントのアイドル期間以下となるような、別のアイドルタイマー(同じアイドルタイマーも含む)をセットアップするアイドルタイマー関数を記述しないでください。そのようなタイマーはほとんど即座に実行されて、Emacsが次回アイドルになるのを待機するかわりに再現なく継続して実行されるでしょう。以下で説明するようにカレントのアイドル期間を適切に増加させて再スケジュールするのが正しいアプローチです。

Function: current-idle-time

この関数はEmacsがアイドルならEmacsがアイドルとなった期間をcurrent-timeで使用するのと同じフォーマットでリターンする(時刻を参照)。

Emacsがアイドルでなければcurrent-idle-timenilをリターンする。これはEmacsがアイドルかどうかテストする手軽な方法である。

current-idle-timeの主な用途はアイドルタイマー関数を少し“休憩”したいときです。そのアイドルタイマー関数はさらに数秒アイドル後に、同じ関数を再呼び出しするために別のタイマーをセットアップできます。以下はその例です:

(defvar my-resume-timer nil
  "Timer for `my-timer-function' to reschedule itself, or nil.")

(defun my-timer-function ()
  ;; my-resume-timerアクティブの間にユーザーがコマンドをタイプ
  ;; したら、次回この関数はそれのメインアイドルタイマーから呼び出され
  ;; my-resume-timerを非アクティブにする
  (when my-resume-timer
    (cancel-timer my-resume-timer))
  ...do the work for a while...
  (when taking-a-break
    (setq my-resume-timer
          (run-with-idle-timer
            ;; カレント値より大きいアイドル
            ;; 期間break-lengthを計算
            (time-add (current-idle-time) break-length)
            nil
            'my-timer-function))))

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.13 端末の入力

このセクションでは端末入力の記録や操作のための関数と変数を説明します。関連する関数についてはEmacsのディスプレイ表示を参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.13.1 入力のモード

Function: set-input-mode interrupt flow meta &optional quit-char

この関数はキーボード入力の読み取りにたいしてモードをセットする。Emacsはinterruptが非nilなら入力割り込み、nilならCBREAKモードを使用する。デフォルトのセッティングはシステムに依存する。いくつかのシステムでは指定に関わらずに常にCBREAKモードを使用する。

EmacsがXと直接通信する際にはこの引数を無視して、それがEmacsの知る通信手段であれば割り込みを使用する。

flowが非nilなら、Emacsは端末への出力にたいしてXON/XOFFフロー制御(C-qC-s)を使用する。これはCBREAK以外では効果がない。

引数metaは127より上の文字コード入力にたいするサポートを制御する。metatならEmacsは8番目のビットがセットされた文字を、必要に応じてデコードする前(端末I/Oのエンコーディングを参照)にメタ文字に変換する。metaがシンボルencodedの場合には、Emacsはまず各バイトの8ビットすべてを使って文字をデコードしてから、デコードされたシングルバイトの8ビット目がセットされていればそれをMeta文字に変換する。最後にmetatnil、あるいはencodedのいずれでもなければ、デコードの前後においてEmacsは入力の8ビットすべてを変更せずに使用する。これはMeta修飾を8ビット目にエンコードしない、8ビット文字セットを使用する端末に適している。

quit-charが非nilならquitに使用する文字を指定する。この文字は通常はC-gquitを参照のこと。

current-input-mode関数はEmacsがカレントで使用する入力モードのセッティングをリターンします。

Function: current-input-mode

この関数はキーボード入力読み取りにたいするカレントのモードをリターンする。これはset-input-modeの引数に対応した(interrupt flow meta quit)という形式のリストをリターンする。

interrupt

Emacsが割り込み駆動の入力(interrupt-driven input)を使用時には非nilnilならEmacsはCBREAKモードを使用している。

flow

Emacsが端末出力にXON/XOFFフロー制御(C-qC-s)を使用していれば非nil。この値はinterruptnilのときのみ意味がある。

meta

Emacsが入力のデコード前に入力文字の8番目のビットをMetaビットとして扱う場合にはt、デコードされたシングルバイト文字の8番目のビットをMetaビットとして扱う場合にはencoded、すべての入力文字の8ビット目をクリアーする場合にはnil。その他の値はEmacsが8ビットすべてを基本的な文字コードとして使用することを意味する。

quit

カレントでEmacsがquitに使用する文字であり通常はC-g


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.13.2 入力の記録

Function: recent-keys &optional include-cmds

この関数はキーボードかマウスからの最後の入力イベント300個を含んだベクターをリターンする。その入力イベントがキーシーケンスに含まれるか否かに関わらずすべての入力イベントが含まれる。つまりキーボードマクロにより生成されたイベントを含まない、最後の入力イベント300個を常に入手することになる(キーボードマクロは、デバッグにとってより興味深いとはいえないので除外されている。そのマクロを呼び出したイベントを確認するだけで充分であるはず)、

include-cmdsが非nilなら、結果ベクター内の完全なキーシーケンスが(nil . COMMAND)という形式の疑似イベントが差し込まれる。ここでCOMMANDはそのキーシーケンスの開始(コマンドループの概要を参照)。

clear-this-command-keys (コマンドループからの情報を参照)を呼び出すと、その直後はこの関数は空のベクターをリターンする。

Command: open-dribble-file filename

この関数はfilenameという名前のdribbleファイル(dribble file)をオープンする。dribbleファイルがオープンされたとき、キーボードとマウス(ただしキーボードマクロ由来は除く)からのそれぞれの入力イベントはそのファイルに書き込まれる。非文字イベントは‘<…>’で囲まれたプリント表現で表される。(パスワードのような)機密情報はdribbleファイルへの記録を終了させることに注意。

引数nilでこの関数を呼び出すことによりファイルはクローズされる。

端末の出力open-termscriptも参照のこと。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.14 端末の出力

端末出力関数は出力をテキスト端末に送信したり、端末に送信した出力を追跡します。変数baud-rateはEmacsが端末の出力スピードをどのように考慮すべきかを指示します。

User Option: baud-rate

この変数はEmacsの認識する端末の出力スピード。この変数をセットしても実際のデータ転送スピードは変化しないが、この値はパディングのような計算に使用される。

これはテキスト端末でスクリーンの一部をスクロールしたり再描画すべきかどうかについての判定にも影響する。グラフィカルな端末での対応する機能については強制的な再表示を参照のこと。

値の単位はボー(baud)。

ネットワークを介して実行中にネットワークの別の部分が違うボーレートで機能している場合には、Emacsがリターンする値はユーザーのローカル端末で使用される値と異なるかもしれません。いくつかのネットワークプロトコルはローカル端末のスピードでリモートマシンと対話するので、Emacsや他のプログラムは正しい値を得ることができますが相手側はそうではありません。Emacsが誤った値をもつ場合には最適よりも劣る判定をもたらします。この問題を訂正するためにはbaud-rateをセットします。

Function: send-string-to-terminal string &optional terminal

この関数はstringを変更せずにterminalへ送信する。string内のコントロール文字は端末依存の効果をもつ(端末上に非ASCIIテキストを表示する必要があるなら明示的なエンコードとデコードに記述した関数のいずれかを使用してエンコードすること)。この関数はテキスト端末だけを操作する。terminalには端末オブジェクト、フレーム、または選択されたフレームの端末を意味するnilを指定できる。batchモードではterminalnilなら、stringstdoutに送信される。

この関数の1つの用途はダウンロード可能なファンクションキー定義をもつ端末上でファンクションキーを定義することである。たとえば以下は(特定の端末で)ファンクションキー4を前方へ4文字移動(そのコンピューターヘ文字C-u C-fを送信)するように定義する方法:

(send-string-to-terminal "\eF4\^U\^F")
     ⇒ nil
Command: open-termscript filename

この関数はEmacsが端末へ送信したすべての文字を記録するtermscriptファイル(termscript file)をオープンする。リターン値はnil。termscriptファイルはEmacsのスクリーン文字化け問題、不正なTermcapエントリーや、実際のEmacsバグより頻繁に発生する望ましくない端末オプションのセッティングの調査に有用。どの文字が実際に出力されるか確信できれば、それらの文字が使用中のTermcap仕様に対応するかどうか確実に判断できる。

(open-termscript "../junk/termscript")
     ⇒ nil

引数nilでこの関数を呼び出すことによりtermscriptファイルはクローズされる。

入力の記録open-dribble-fileも参照のこと。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.15 サウンドの出力

Emacsを使用してサウンドを再生するためには関数play-soundを使用します。特定のシステムだけがサポートされています。実際に処理を行うことができないシステムでplay-soundを呼び出すとエラーが発生します。

サウンドはRIFF-WAVEフォーマット(‘.wav’)かSun Audioフォーマット(‘.au’)で格納されていなければなりません。

Function: play-sound sound

この関数は指定されたサウンドを再生する。引数sound(sound properties...)という形式をもつ。ここでpropertiesはキーワード(特定のシンボルが特別に認識される)とそれに対応する値で交互に構成されている。

以下のテーブルは現在のところsound内で意味をもつキーワードとそれらの意味:

:file file

これは再生するサウンドを含んだファイルを指定する。絶対ファイル名でなければディレクトリーdata-directoryにたいして展開される。

:data data

これはファイルを参照する必要がないサウンドの再生を指定する。値dataはサウンドファイルと同じバイトを含む文字列であること。わたしたちはユニバイト文字列の使用を推奨する。

:volume volume

これはサウンド再生での音の大きさを指定する。0から1までの数値であること。どんな値であれ以前に指定されたボリュームがデフォルトとして使用される。

:device device

これはサウンドを再生するシステムデバイスを文字列で指定する。デフォルトのデバイスはシステム依存。

実際にサウンドを再生する前にplay-soundはリストplay-sound-functions内の関数を呼び出す。関数はそれぞれ1つの引数soundで呼び出される。

Command: play-sound-file file &optional volume device

この関数はオプションでvolumedeviceを指定してサウンドfileを再生する代替インターフェイス。

Variable: play-sound-functions

リストの関数はサウンド再生前に呼び出される。関数はそれぞれサウンドを記述するプロパティリストを単一の引数として呼び出される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.16 X11キーシンボルの処理

システム固有のX11 keysym(key symbol: キーシンボル)を定義するには変数system-key-alistをセットします。

Variable: system-key-alist

この変数の値はシステム固有のkeysymそれぞれにたいして1つの要素をもつようなalistであること。要素はそれぞれ(code . symbol)という形式をもつ。ここでcodeは数字のkeysymコード(ベンダー固有の -2**28), のビットは含まない)、symbolはそのファンクションキーの名前。

たとえば(168 . mute-acute)は数字コード -2**28 + 168のシステム固有キーを定義する(HP Xサーバーで使用される)。

このalistから他のXサーバーのkeysymを除外することは重要ではない。実際に使用中のXサーバーが使用するkeysymが競合しないかぎり無害である。

この変数は常にカレント端末にたいしてローカルでありバッファーローカルにできない。複数の端末を参照のこと。

以下の変数をセットすればEmacsが修飾キーControl、Meta、Alt、Hyper、Superにたいして何のkeysymを使用するべきかを指定できます。

Variable: x-ctrl-keysym
Variable: x-alt-keysym
Variable: x-meta-keysym
Variable: x-hyper-keysym
Variable: x-super-keysym

keysymの名前はそれぞれ修飾子Control、Alt、Meta、Hyper、Superを意味する名前であること。たとえば以下はMeta修飾キーとAlt修飾キーを交換する方法:

(setq x-alt-keysym 'meta)
(setq x-meta-keysym 'alt)

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.17 batchモード

コマンドラインオプション‘-batch’でEmacsを非対話的に実行できます。このモードではEmacsは端末からコマンドを読み取りません。また終端モード(terminal modes)を変更せずに、消去可能なスクリーンへの出力も待ち受けません。これはLispプログラムの実行を指示して終了したらEmacsが終了するというアイデアです。これを行うには‘-l file’によりfileという名前のライブラリーをロードするか、‘-f function’により引数なしでfunctionを呼び出す、または‘--eval=form’で実行するプログラムを指定できます。

通常はエコーエリアに出力したりストリームとしてt (出力ストリームを参照)を指定するmessageprin1等を使用したLispプログラムの出力はbatchモードではEmacsの標準記述子へと送られます(prin1や他のプリント関数は標準記述子に書き込むがmessageは標準エラー記述子に書き込む)。同様に通常はミニバッファーから読み取られる入力は標準入力から読み取られます。つまりEmacsは非インタラクティブなアプリケーションプログラムのように振る舞います(コマンドのエコーのようにEmacsが通常生成するエコーエリアへの出力はすべて抑制される)。

標準出力やエラー記述子に書き込まれる非ASCIIテキストは、locale-coding-systemが非nilならそれを使用してエンコードされます(localeを参照)。coding-system-for-writeを他のコーディングシステムにバインドすればこれをオーバーライドできます(明示的なエンコードとデコードを参照)。

Emacsはbatchモードではgc-cons-percentage変数の値をデフォルトの‘0.1’から‘1.0’まで増加します。これはガーベージコレクションの実行がデフォルトより少なくなる(そしてメモリー消費は多くなる)ことを意味するので、長時間の実行が予想されるbatchジョブではこの制限を元に戻すように調整する必要があります。

Variable: noninteractive

Emacsがbatchモードで実行中ならこの変数は非nil

batchモードでEmacsがエラーのシグナルによりexitすると、Emacsのexitステータスは非0です:

$ emacs -Q --batch --eval '(error "foo")'; echo $?
foo
255

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.18 セッションマネージャー

Emacsはアプリケーションのサスペンドとリスタートに使用されるXセッション管理プロトコル(XSMP: X Session Management Protocol)をサポートしています。Xウィンドウシステムではセッションマネージャー(session manager)と呼ばれるプログラムが実行中アプリケーション追跡の責を負います。Xサーバーのシャットダウン時にセッションマネージャーはアプリケーションに状態を保存するか尋ねて、それらが応答するまでシャットダウンを遅延します。アプリケーションがそのシャットダウンをキャンセルすることもできます。

セッションマネージャーがサスペンドされたセッションをリスタートする際には、これらのアプリケーションにたいして保存された状態をリロードするように個別に指示します。これはリストアする保存済みセッションが何かを指定する特別なコマンドラインオプションを指定することにより行われます。これはEmacsでは‘--smid session’という引数です。

Variable: emacs-save-session-functions

Emacsはemacs-save-session-functionsと呼ばれるフックを介した状態の保存をサポートする。セッションマネージャーがウィンドウシステムのシャットダウンを告げた際にEmacsはこのフックを実行する。これらの関数はカレントバッファーを一時バッファーにセットして引数なしで呼び出される。それぞれの関数はバッファーにLispコードを追加するためにinsertを使用できる。最後にEmacsはセッションファイル(session file)と呼ばれるファイル内にそのバッファーを保存する。

その後でセッションマネージャーがEmacsを再開する際に、Emacsはセッションファイルを自動的にロードする(ロードを参照)。これはスタートアップ中に呼び出されるemacs-session-restoreという名前の関数により処理される。要約: スタートアップ時のアクション順序を参照のこと。

emacs-save-session-functions内の関数が非nilをリターンすると、Emacsはセッションマネージャーにシャットダウンのキャンセルを要求します。

以下はセッションマネージャによりEmacsがリストアされる際に単に*scratch*にテキストを挿入する例です。

(add-hook 'emacs-save-session-functions 'save-yourself-test)

(defun save-yourself-test ()
  (insert
   (format "%S" '(with-current-buffer "*scratch*"
                   (insert "I am restored"))))
  nil)

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.19 デスクトップ通知

Emacsはfreedesktop.orgのDesktop Notifications SpecificationをサポートするシステムとMS-Windowsでは通知(notifications)を送ることができます。この機能をPOSIXホストで使用するにはEmacsがD-Busサポート付きでコンパイルされていて、notificationsライブラリーがロードされていなければなりません。D-Bus in D-Bus integration in Emacsを参照してください。D-Busサポートが利用できるときには以下の関数がサポートされます。

Function: notifications-notify &rest params

この関数は引数paramsで指定された構成したパラメーターによりD-Busを通じてデスクトップに通知を送信する。これらの引数は交互になったキーワードと値のペアーで構成されていること。以下はサポートされているキーワードと値:

:bus bus

D-Busのバス。この引数は:session以外のバスを使用する場合のみ必要。

:title title

通知のタイトル。

:body text

通知のbodyのテキスト。通知サーバーの実装に依存して‘"<b>bold text</b>"’のようなHTMLマークアップ、ハイパーリンク、イメージをテキストに含むことができる。HTML特殊文字は‘"Contact &lt;postmaster@localhost&gt;!"’のようにエンコードしなければならない。

:app-name name

その通知を送信するアプリケーション名。デフォルトはnotifications-application-name

:replaces-id id

この通知が置換する通知のididnotifications-notifyの以前の呼び出し結果でなければならない。

:app-icon icon-file

通知アイコンのファイル名。nilならアイコンは表示されない。デフォルトはnotifications-application-icon

:actions (key title key title ...)

適用されるアクションのリスト。keytitleはどちらも文字列。デフォルトのアクション(通常は通知クリックで呼び出される)は‘"default"’という名前であること。実装がそれを表示しないようにするには自由だがtitleは何でもよい。

:timeout timeout

timeoutは通知が表示されてからその通知が自動的にクローズされるまでのミリ秒での時間。-1なら通知の有効期限は通知サーバーのセッティングに依存して、通知のタイプにより異なるかもしれない。0なら通知は失効しない。デフォルト値は-1。

:urgency urgency

緊急レベル。lownormalcriticalのいずれか。

:action-items

このキーワードが与えられるとアクションのtitle文字列はアイコン名として解釈される。

:category category

通知の種類の文字列。標準のカテゴリーのリストはDesktop Notifications Specificationを参照のこと。

:desktop-entry filename

これは‘"emacs"’のようにプログラムを呼び出すデスクトップファイル名の名前を指定する。

:image-data (width height rowstride has-alpha bits channels data)

これはそれぞれwidth、height、rowstride、およびalpha channel、bits per sample、channels、image dataの有無を記述するrawデータのイメージフォーマット。

:image-path path

これはURI(現在サポートされているのはURIスキーマは‘file://’のみ)、または‘$XDG_DATA_DIRS/icons’にあるfreedesktop.org準拠のアイコンテーマ名のいずれかを表す。

:sound-file filename

通知ポップアップ時に再生するサウンドファイルのパス。

:sound-name name

通知ポップアップ時に再生するfreedesktop.orgサウンド命名仕様準拠のテーマに対応した‘$XDG_DATA_DIRS/sounds’にある名前付きサウンド。アイコン名と同様にサウンドにたいしてのみ。例としては‘"message-new-instant"’。

:suppress-sound

それが可能ならサーバーにすべてのサウンドの再生を抑制させる。

:resident

セットするとアクション呼び出し時にサーバーは通知を自動的に削除しない。ユーザーか送信者により明示的に削除されるまで通知はサーバー内に常駐し続ける。恐らくこのヒントはサーバーが:persistence能力をもつときのみ有用。

:transient

セットするとサーバーはその通知を過渡的なものとして扱い、もしそれが永続的であるべきならサーバーのpersistence能力をバイパスする。

:x position
:y position

その通知がポイントすべきスクリーン上のXとYの座標を指定する。これらの引数は併せて使用しなければならない。

:on-action function

アクション呼び出し時に呼び出す関数。通知idとアクションのkeyは引数としてその関数に渡される。

:on-close function

タイムアウトかユーザーにより通知がクローズされたときに呼び出す関数。通知idとクローズ理由reasonは引数としてその関数に渡される。:

  • 通知が失効した場合はexpired
  • ユーザーが通知を却下したらdismissed
  • notifications-close-notification呼び出しにより通知がクローズされたら close-notification
  • 通知サーバーが理由を提供しなかったらundefined

通知サーバーがどのパラメーターを受け入れるかのチェックはnotifications-get-capabilitiesを通じて行うことができる。

この関数は整数の通知idをリターンする。このidはnotifications-close-notificationや別のnotifications-notify呼び出しの:replaces-id引数で通知アイテムの操作に使用できる。たとえば:

(defun my-on-action-function (id key)
  (message "Message %d, key \"%s\" pressed" id key))
     ⇒ my-on-action-function

(defun my-on-close-function (id reason)
  (message "Message %d, closed due to \"%s\"" id reason))
     ⇒ my-on-close-function

(notifications-notify
 :title "Title"
 :body "This is <b>important</b>."
 :actions '("Confirm" "I agree" "Refuse" "I disagree")
 :on-action 'my-on-action-function
 :on-close 'my-on-close-function)
     ⇒ 22

A message window opens on the desktop.  Press ``I agree''.
     ⇒ Message 22, key "Confirm" pressed
        Message 22, closed due to "dismissed"
Function: notifications-close-notification id &optional bus

この関数は識別子idの通知をクローズする。busはD-Bus接続を表す文字列でありデフォルトは:session

Function: notifications-get-capabilities &optional bus

通知サーバーの能力をシンボルのリストでリターンする。busはD-Bus接続を表す文字列でありデフォルトは:session。以下は期待できる能力:

:actions

サーバーはユーザーにたいする指定されたアクションを提供する。

:body

bodyのテキストをサポートする。

:body-hyperlinks

サーバーは通知内のハイパーリンクをサポートする。

:body-images

サーバーは通知内のイメージをサポートする。

:body-markup

サーバーは通知内のマークアップをサポートする。

:icon-multi

サーバーは与えられたイメージ配列内のすべてのフレームのアニメーションを描画できる。

:icon-static

与えられたイメージ配列内の正確に1フレームの表示をサポートする。この値は、:icon-multiとは相互に排他。

:persistence

サーバーは通知の永続性をサポートする。

:sound

サーバーは通知のサウンドをサポートする。

これらに加えてベンダー固有の能力は:x-gnome-foo-capのように:x-vendorで始まる。

Function: notifications-get-server-information &optional bus

通知サーバーの情報を文字列のリストでリターンする。busはD-Bus接続を表す文字列でありデフォルトは:session。リターンされるリストは(name vendor version spec-version)

name

サーバーのプロダクト名。

vendor

ベンダー名。たとえば‘"KDE"’や‘"GNOME"’。

version

サーバーのバージョン番号。

spec-version

サーバーが準拠する仕様のバージョン。

spec_versionnilならサーバーは‘"1.0"’以前の仕様をサポートする。

EmacsがMS-WindowsでGUIセッションとして実行時には、ネイティブのプリミティブを通じてD-Bus通知の小サブセットをサポートします:

Function: w32-notification-notify &rest params

この関数はparamsの指定にしたがってMS-Windowsのトレー通知(tray notification)を表示する。MS-Windowsトレー通知はタスクバーのの通知エリア内のアイコンからのバルーン内に表示される。

値は以下で説明するw32-notification-closeで通知の削除に使用できる一意な通知ID。関数が失敗するとリターン値はnil

引数paramsはkeyword/valueペアーで指定する。パラメーターはすべてオプションだが何もパラメーターを指定しなければ関数は何もせずにnilをリターンする。

は以下はサポートされるパラメーター:

:icon icon

システムトレーにiconを表示する。iconが文字列ならアイコンをロードするファイル名(Windowsのアイコンファイル.ico)を指定すること。iconが文字列以外、またはこのパラメーターが指定されなければEmacsの標準アイコンが使用される。

:tip tip

通知のツールチップにtipを使用する。tipが文字列なら、通知により追加されたトレーアイコン上にマウスポインターを移動した際に表示されるツールチップのテキスト。tipが文字列以外またはこのパラメーターが指定されていなければ、ツールチップのデフォルトのテキストは‘Emacs notification’。ツールチップのテキストは127文字まで(Windows 2000以前は63文字)。それより長い文字列は切り捨てられる。

:level level

通知の重大度レベルでinfowarningerrorのいずれか。値が与えられた場合には、:titleパラメーターも指定されて、かつ文字列の場合のみ通知アイコンの左に表示されるアイコンを決定する。

:title title

通知のタイトル。titleが文字列ならbodyテキストの直上に大きなフォントで表示される。タイトルのテキストは63文字まで。それより長い文字列は切り捨てられる。

:body body

通知のbody(本文)。bodyが文字列なら通知メッセージのテキストを指定する。テキストを行に分割する方法を制御するには埋め込みの改行を使用する。bodyのテキストは255文字までで、それより長ければ切り捨てられる。D-Busとは異なりbodyテキストはマークアップを含まないプレーンテキストであること。

Windows 2000以前のWindowsでは:icon:tipだけがサポートされることに注意。他のパラメーターを渡すことは可能だが、それらの古いシステムでは無視されるだろう。

一度にアクティブな通知は最大でも常に1つ。新たな通知を表示できるようにするにはw32-notification-closeを呼び出してアクティブな通知を削除しなければならない。

タスクバーから通知とアイコンを削除するには以下の関数を使用します:

Function: w32-notification-close id

この関数は与えられた一意なidでトレー通知を削除する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.20 ファイル変更による通知

いくつかのオペレーティングシステムはファイルやファイル属性の変更にたいするファイルシステムの監視をサポートします。正しく設定されていれば、Emacsはinotifykqueuegfilenotifyw32notifyのようなライブラリーを静的にリンクします。これらのライブラリーによりローカルマシン上でのファイルシステムの監視が有効になります。

リモートマシン上のファイルシステムの監視も可能です。Remote Files in The GNU Emacs Manualを参照してください。これはEmacsにリンク済みのライブラリーのいずれかに依存する訳ではありません。

通知されたファイル変更によりこれらすべてのライブラリーは異なるイベントを発行するので、Emacsはアプリケーションにたいして統一されたインターフェースを提供するライブラリーfilenotifyを提供しています。ファイル通知を受け取りたいLispプログラムは、ネイティブのライブラリーよりこのライブラリーを優先する必要があります:このセクションではfilenotifyライブラリーの関数と変数について説明します。

Function: file-notify-add-watch file flags callback

fileに関するファイルシステムイベントの監視を追加する。これはfileに関するファイルシステムイベントがEmacsに報告されるように取り計らう。

リターン値は追加された監視ディスクリプター(descriptor)。タイプは背景にあるライブラリーに依存しており、以下の例に示すとおり一般的には整数とみなすことはできない。比較にはequalを使用すること。

何らかの理由によりfileが監視不可能なら、この関数はエラーfile-notify-errorをシグナルする。

マウントされたファイルシステムでファイル変更を監視できないことがある。これはこの関数により検出されないので、非nilのリターン値が実際にfileが変更された通知であることを保証するものではない。

fileがシンボリックリンクの場合には、そのリンクのフォローは行わずfileそのものだけを監視する。

flagsは何を監視するかセットするためのコンディションのリスト。以下のシンボルを含めることができる:

change

ファイル内容の変更を監視。

attribute-change

パーミッションや変更時刻のようなファイル属性の変更を監視。

fileがディレクトリーなら、changeはそのディレクトリーでのファイルの作成と削除を監視する。このような場合にファイルの変更もレポートするファイル通知バックエンドもいくつかある。これは再帰的に機能しない。

Emacsは何らかのイベント発生時には以下の形式のeventを単一の引数として関数callbackを呼び出す:

(descriptor action file [file1])

descriptorはこの関数がリターンするオブジェクトと同じ。actionはイベントを示し、以下のシンボルのいずれか:

created

fileが作成された。

deleted

fileが削除された。

changed

fileの内容が変更された。w32notifyライブラリーでは属性の変更でも同様に報告される。

renamed

filefile1にリネームされた。

attribute-changed

fileの属性が変更された。

stopped

fileの監視が中断された。

w32notifyライブラリーはattribute-changedイベントを報告しないことに注意。このライブラリーはパーミッションや変更時刻のようなファイル属性が何か変更された際にはchangedイベントを報告する。同じようにkqueueライブラリーでは、ディレクトリー監視時にはファイル属性変更の報告に信頼性がない。

stoppedイベントはファイル監視の停止を意味する。これはfile-notify-rm-watchの呼び出された(以下参照)、監視中のファイルが削除された、または背後にあるライブラリーから別のエラーが報告されてそれ以上の監視が不可能になった可能性がある。

filefile1はイベントが報告されたファイルの名前。たとえば:

(require 'filenotify)
     ⇒ filenotify

(defun my-notify-callback (event)
  (message "Event %S" event))
     ⇒ my-notify-callback

(file-notify-add-watch
  "/tmp" '(change attribute-change) 'my-notify-callback)
     ⇒ 35025468

(write-region "foo" nil "/tmp/foo")
     ⇒ Event (35025468 created "/tmp/.#foo")
        Event (35025468 created "/tmp/foo")
        Event (35025468 changed "/tmp/foo")
        Event (35025468 deleted "/tmp/.#foo")

(write-region "bla" nil "/tmp/foo")
     ⇒ Event (35025468 created "/tmp/.#foo")
        Event (35025468 changed "/tmp/foo")
        Event (35025468 deleted "/tmp/.#foo")

(set-file-modes "/tmp/foo" (default-file-modes) 'nofollow)
     ⇒ Event (35025468 attribute-changed "/tmp/foo")

アクションrenamedがリターンされるかどうかは使用する監視ライブラリーに依存する。それ以外ではdeletedcreatedのアクションがランダムな順にリターンされる。

(rename-file "/tmp/foo" "/tmp/bla")
     ⇒ Event (35025468 renamed "/tmp/foo" "/tmp/bla")

(delete-file "/tmp/bla")
     ⇒ Event (35025468 deleted "/tmp/bla")
Function: file-notify-rm-watch descriptor

descriptorに指定された既存のファイル監視を削除する。descriptorfile-notify-add-watchがリターンしたオブジェクトであること。

Command: file-notify-rm-all-watches

Removes all existing file notification watches from Emacs.

ファイル監視にもとづくパッケージでは予期せぬ副作用が起こり得るので、このコマンドの使用には注意を要する。これは主にデバッグ目的やEmacsがフリーズした際の使用を意図した関数である。

Function: file-notify-valid-p descriptor

descriptorで指定された監視の有効性をチェックする。descriptorfile-notify-add-watchがリターンしたオブジェクトであること。

監視するファイルやディレクトリーの削除や別の理由による監視スレッドの異常exitにより監視が無効になる可能性がある。file-notify-rm-watchの呼び出しで削除することにより監視も無効になる。

(make-directory "/tmp/foo")
     ⇒ Event (35025468 created "/tmp/foo")

(setq desc
      (file-notify-add-watch
        "/tmp/foo" '(change) 'my-notify-callback))
     ⇒ 11359632

(file-notify-valid-p desc)
     ⇒ t

(write-region "bla" nil "/tmp/foo/bla")
     ⇒ Event (11359632 created "/tmp/foo/.#bla")
        Event (11359632 created "/tmp/foo/bla")
        Event (11359632 changed "/tmp/foo/bla")
        Event (11359632 deleted "/tmp/foo/.#bla")

;; ディレクトリーのファイル削除では監視は無効にならない
(delete-file "/tmp/foo/bla")
     ⇒ Event (11359632 deleted "/tmp/foo/bla")

(write-region "bla" nil "/tmp/foo/bla")
     ⇒ Event (11359632 created "/tmp/foo/.#bla")
        Event (11359632 created "/tmp/foo/bla")
        Event (11359632 changed "/tmp/foo/bla")
        Event (11359632 deleted "/tmp/foo/.#bla")

;; ディレクトリー削除により監視は無効になる
;; 別の監視ディスクリプターからイベントが到着
(delete-directory "/tmp/foo" 'recursive)
     ⇒ Event (35025468 deleted "/tmp/foo")
        Event (11359632 deleted "/tmp/foo/bla")
        Event (11359632 deleted "/tmp/foo")
        Event (11359632 stopped "/tmp/foo")

(file-notify-valid-p desc)
     ⇒ nil

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.21 動的にロードされるライブラリー

ダイナミックにロードされるライブラリー(dynamically loaded library)とは機能が最初に必要になったときにオンデマンドでロードされるライブラリーです。Emacsは自身の機能をサポートするライブラリーのオンデマンドロードのように、それらをサポートします。

Variable: dynamic-library-alist

ダイナミックライブラリーとそれらを実装する外部ライブラリーファイルのalist。

要素はそれぞれ(library files…)という形式のリスト。ここでcarはサポートされた外部ライブラリーを表すシンボル、残りはそのライブラリーにたいして候補となるファイル名を与える文字列。

Emacsはリスト内のファイル出現順でライブラリーのロードを試みる。何も見つからなければEmacsセッションはライブラリーにアクセスできず、それが提供する機能は利用できない。

いくつかのプラットフォーム上におけるイメージのサポートはこの機能を使用している。以下は、S-Windows上でイメージをサポートするためにこの変数をセットする例:

(setq dynamic-library-alist
      '((xpm "libxpm.dll" "xpm4.dll" "libXpm-nox4.dll")
        (png "libpng12d.dll" "libpng12.dll" "libpng.dll"
             "libpng13d.dll" "libpng13.dll")
        (jpeg "jpeg62.dll" "libjpeg.dll" "jpeg-62.dll"
              "jpeg.dll")
        (tiff "libtiff3.dll" "libtiff.dll")
        (gif "giflib4.dll" "libungif4.dll" "libungif.dll")
        (svg "librsvg-2-2.dll")
        (gdk-pixbuf "libgdk_pixbuf-2.0-0.dll")
        (glib "libglib-2.0-0.dll")
        (gobject "libgobject-2.0-0.dll")))

イメージタイプpbmxbmは外部ライブラリーに依存せずEmacsで常に利用可能なので、この変数内にエントリーがないことに注意。

これは外部ライブラリーへのアクセスにたいする一般的な機能を意図したものではないことにも注意。Emacsにとって既知のライブラリーだけがこれを通じてロードできる。

与えられたlibraryがEmacsに静的にリンクされていれば、この変数は無視される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

42.22 セキュリティへの配慮

すべてのアプリケーションと同じように、アクセス等のルールを励行するオペレーティングシステムでは、Emacsを安全な環境で実行できます。注意を払えばEmacsベースのアプリケーションがそのようなルールをチェックするセキュリティ境界の一部になることもできます。Emacsのデフォルトのセッティングでは典型的なソフトウェア開発環境としても良好に機能しますが、アタッカーを含んだ信頼されないユーザーの存在する環境では調整を要します。以下はそのようなアプリケーションを開発する際に助けとなるセキュリティ問題の要覧です。これは完全なものではありません。これはセキュリティチェックリストではなく、セキュリティに関する問題にたいするアイデアを与えることを意図したものです。

ファイルローカル変数

Emacsがvisitするファイルには、そのファイルをvisitするバッファーに効果を及ぼす変数のセッティングを含めることができる。ファイルローカル変数を参照のこと。同じようにディレクトリーはそのディレクトリー内のすべてのファイルに共通なローカル変数を指定できる。ディレクトリーローカル変数を参照のこと。これらの変数の誤用にたいしてたとえEmacsが幾らかの努力を行っているにしても、あるパッケージがあまりに楽観的にsafe-local-variableをセットすることによってセキュリティーホールは簡単に作成されるし、これはあまりに一般的な問題である。ファイルとディレクトリーの両方にたいしてこの機能を無効にするには、enable-local-variablesnilをセットすればよい。

アクセスコントロール

たとえEmacsが通常は背後にあるオペレーティングシステムのアクセスパーミッションを尊重するとしても、あるケースにおいてはアクセスを特別に処理する。たとえばファイル名は独自のアクセスチェックによりファイルを特別に扱うハンドラーをもつことができる。特定のファイル名の“Magic”の作成を参照のこと。さらにバッファーは対応するファイルが書き込み可でも読み取り専用にできるしその逆も可能であり、‘File passwd is write-protected; try to save anyway? (yes or no)’のようなメッセージを結果としてもたらすかもしれない。読み取り専用のバッファーを参照のこと。

認証

Emacsにはread-passwdのようなパスワードを扱う関数がいくつかある。パスワードの読み取りを参照のこと。これらの関数はパスワードを公に喧伝しないにしても、Emacs内部にアクセスする猛者なアタッカーにたいする実装の証左はない。たとえばパスワード使用後にメモリーをクリアーするためにelispコードがclear-stringを使用しても、パスワードの残滓は依然としてガーベージコレクトされたフリーリスト内に存在する。文字列の変更を参照のこと。

コードインジェクション

Emacsは他の多くのアプリケーションにコマンドを送信できる。アプリケーションはこれらのコマンドのオペランドとして送信された文字列はディレクティブとして誤解釈しないこと。たとえばファイルabにリネームするシェルコマンドを使用する際に、単に文字列mv a bを使用しないこと。なぜならファイル名のいずれかが‘-’で始まるかもしれず、‘;’のようなシェルのメタ文字が含まれるかもしれないから。この種の問題の回避のためにshell-quote-argumentのような関数が助けになるとしても、POSIXプラットフォームのshell-quote-argumentはシェルのメタ文字はクォートするが先頭の‘-’のクォートはしない。MS-Windowsでの‘%’にたいするクォートでは名前に‘^’がある環境変数を想定していない。shell引数を参照のこと。通常はサブシェルよりcall-processを使用するほうが安全である。同期プロセスの作成を参照のこと。そしてEmacsのビルトイン関数を使用するほうが安全である。たとえばmvを呼び出すかわりに(rename-file "a" "b" t)を使用する。ファイルの名前と属性の変更を参照のこと。

コーディングシステム

Emacsはアクセスするファイルとネットワークのコーディングシステムを推察する。コーディングシステムを参照のこと。Emacsの推察が誤っていたりネットワークの相手先がEmacsの推察に不同意なら、結果となるコーディングシステムは信頼できないかもしれない。更にその推察が正しいときでさえ、他のプログラムが使用できないバイトをEmacsが使用できる場合がよくある。たとえばEmacsEmacsにとってはnullバイトは他と同じ単なる文字だとしても、他の多くのアプリケーションはnull文字を文字列終端として扱うので、nullバイトを含む文字列やファイルを誤って処理する。

Environment and configuration variables

POSIXはEmacsの挙動に影響し得る環境変数をいくつか指定する。ASCII英大文字、数字、アンダースコアだけから構成される名前をもつ任意の環境変数がEmacsの内部の動作に影響を及ぼし得る。Emacsはその種のEMACSLOADPATHのような変数をいくつか使用する。See ライブラリー検索を参照のこと。Emacsが呼び出すかもしれないユーティリティーすべてにたいして標準の挙動を得るためには、いくつかの環境変数(PATHPOSIXLY_CORRECTSHELLTMPDIR)が正しく設定されていることを要するシステムがいくつかある。TZのような一見は無害な変数でさえセキュリティに影響し得る。オペレーティングシステムの環境を参照のこと。

Emacsにはカスタマイズと同義な変数が他にある。たとえば変数shell-file-nameに非標準的な動作を行うシェルを指定すれば、Emacsベースのアプリケーションはご堂する可能性がある。

Installation

Emacsのインストールの際にインストール先のディレクトリー階層が信頼できないユーザーに変更可能なら、そのアプリケーションは信頼できない。これはEmacsが使用するプログラムや読み書きするファイルのディレクトリー階層にも適用される。

Network access

Emacsでは多くの場合にネットワークにアクセスするので、通常行うようなネットワークアクセスを回避したいと思うかもしれない。たとえばtramp-modenilにセットしていなければ、特定の構文を使用するファイル名はネットワークファイルとして解釈されて、ネットワーク越しに取得される。The Tramp Manual in The Tramp Manualを参照のこと。

Race conditions

Emacsアプリケーションには、他のアプリケーションが行う競合状態に関するものと同種の問題がある。たとえば(file-readable-p "foo.txt")tをリターンしたときでさえ、file-readable-pの呼び出しからその時点の間に別のアプリケーションがファイルの権限を変更したために読み取りできないかもしれない。アクセシビリティのテストを参照のこと。

Resource limits

Emacsがメモリーや他のオペレーティングシステムのリソースを使い切ったときには、通常は完了まで実行される計算が異常終了でトップレベルに戻るかもしれないので挙動の信頼性が減少し得る。これにより通常は完了する操作をEmacsが放棄するかもしれない。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

43 配布用Lispコードの準備

Emacs Lispコードをユーザーに配布するために、Emacsは標準的な方法を提供します。パッケージ(package)はユーザーが簡単にダウンロード、インストール、アンインストール、および更新できるような方法でフォーマットと同梱された1つ以上のファイルのコレクションです。

以降のセクションではパッケージを作成する方法、およびそれを他の人がダウンロードできるようにパッケージアーカイブ(package archive)に配置する方法を説明します。パッケージングシステムのユーザーレベル機能の説明はPackages in The GNU Emacs Manualを参照してください。

これらのセクションは主にパッケージアーカイブのメンテナー向けであり、情報の多くはパッケージ作成者(これらのアーカイブを介して配布されるコードを記述した人)には関係ありません。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

43.1 パッケージ化の基礎

パッケージはシンプルパケージ(simple package)複数ファイルパッケージ(multi-file package)のいずれかです。シンプルパッケージは単一のEmacs Lispファイル内に格納される一方、複数ファイルパッケージはtarファイル(複数のLispファイルとマニュアルのような非Lispファイルが含まれる可能性がある)に格納されます。

通常の使い方ではシンプルパッケージと複数ファイルパッケージとの違いは比較的重要ではありません。Package Menuインターフェースでは、それらの間に差異はありません。しかし以降のセクションで説明するように作成する手順は異なります。

パッケージ(シンプルか複数ファイル)はそれぞれ特定の属性(attributes)をもっています:

Name

短い単語(たとえば‘auctex’)。これは通常はそのプログラム内でシンボルプレフィクスとしても使用される(Emacs Lispコーディング規約を参照)。

Version

関数version-to-listが理解できる形式のバージョン番号(たとえば‘11.86’)。パッケージの各リリースではユーザーがパッケージアーカイブの問い合わせでアップグレードとして認識できるようにバージョン番号のアップも行うこと。

Brief description

そのパッケージがPackage Menuにリストされる際にが表示される。理想的には36文字以内の単一行であること。

Long description

これはC-h P (describe-package)により作成されたバッファーに表示されて、その後にそのパッケージの簡単な説明(brief description)とインストール状態(installation status)が続く。これには通常はパッケージの能力とインストール後に使用を開始する方法を複数行に渡って完全に記述すること。

Dependencies

そのパッケージが依存する他のパッケージ(恐らく最低のバージョン番号を含む)。このリストは空でもよく、その場合にはパッケージに依存パッケージがないことを意味する。それ以外ならパッケージをインストールすることにより依存パッケージも自動的かつ再帰的にインストールされる。依存パッケージのいずれかが見つからなければパッケージをインストールすることはできない。

コマンドpackage-install-file、またはPackage Menuのいずれかを介したパッケージのインストールでは、package-user-dirname-versionという名前のサブディレクトリーが作成されます。ここでnameはパッケージ名、versionはバージョン番号です(たとえば~/.emacs.d/elpa/auctex-11.86/)。わたしたちはこれをパッケージのコンテンツディレクトリー(content directory)と呼んでいます。これはEmacsがパッケージのコンテンツ(シンプルパッケージでは単一のLispファイル、または複数ファイルパッケージから抽出されたファイル)を配置する場所です。

その後にEmacsはautoloadマジックコメント(autoloadを参照)にたいしてコンテンツディレクトリー内のすべてのLispファイルを検索します。これらのautoload定義はコンテンツディレクトリーのname-autoloads.elという名前のファイルに保存されます。これらは通常はパッケージ内で定義された主要なユーザーコマンドのautoloadに使用されますが、auto-mode-alistへの要素の追加(Emacsがメジャーモードを選択する方法を参照)等の別のタスクを行うこともできます。パッケージは通常はその中で定義された関数と変数のすべてをautoloadしないことに注意してください — 通常はそのパッケージの使用を開始するために呼び出される一握りのコマンドだけがautoloadされます。それからEmacsはそのパッケージ内のすべてのLispファイルをバイトコンパイルします。

インストール後はインストールされたパッケージはロード済み(loaded)になります。Emacsはload-pathにコンテンツディレクトリーを追加してname-autoloads.el内のautoload定義を評価します。

Emacsのスタートアップ時には、カレントセッションでインストール済みパッケージを利用可能にするために、自動的に関数package-activate-allを呼び出します。これは早期initファイルロード後、かつ通常initファイルロード後に行われます(要約: スタートアップ時のアクション順序を参照)。早期initファイルでユーザーオプションpackage-enable-at-startupnilにセットされている場合には、パッケージは自動的に利用可能にはなりません。

Function: package-activate-all

この関数はカレントセッションでパッケージを利用可能にする。ユーザーオプションpackage-load-listは利用可能にするパッケージを指定する。デフォルトではインストール済みのパッージすべてが利用可能になる。Package Installation in The GNU Emacs Manualを参照のこと。

ほとんどの場合には、スタートアップの間に自動的に行われるのでpackage-activate-allを呼び出す必要はないはずである。単に早期initファイル内にpackage-activate-allの前に実行される必要のあるコードを配置するとともに、package-activate-allの後に実行される必要のあるコードを主linitファイルに配置することを確実に行なえばよい(Init File in The GNU Emacs Manualを参照)。

Command: package-initialize &optional no-activate

この関数は何のパッケージがインストール済みかに関するEmacsの内部レコードを初期化してからpackage-activate-allを呼び出す。

オプション引数no-activateが非nilなら、インストール済みパッケージを実際に利用可能にせずにこのレコードを更新する。これは内部でのみ使用される。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

43.2 単純なパッケージ

シンプルパッケージは単一のEmacs Lispソースファイルで構成されます。このファイルはEmacs Lispライブラリーのヘッダー規約に準拠していなればなりません(Emacsライブラリーのヘッダーの慣習を参照)。以下の例に示すようにパッケージの属性は種々のヘッダーから取得されます:

;;; superfrobnicator.el --- Frobnicate and bifurcate flanges  -*- lexical-binding:t -*-

;; Copyright (C) 2022 Free Software Foundation, Inc.

;; Author: J. R. Hacker <jrh@example.com>
;; Version: 1.3
;; Package-Requires: ((flange "1.0"))
;; Keywords: multimedia, hypermedia
;; URL: https://example.com/jrhacker/superfrobnicate

…

;;; Commentary:

;; This package provides a minor mode to frobnicate and/or
;; bifurcate any flanges you desire.  To activate it, just type
…

;;;###autoload
(define-minor-mode superfrobnicator-mode
…

そのパッケージの名前は1行目のファイル名の拡張子を除いた部分と同じです。ここでは‘superfrobnicator’です。

brief description(簡単な説明)も1行目から取得されます。ここでは‘Frobnicate and bifurcate flanges’です(訳注: ‘flangeをフロブニケートして二股化する’のフロブニケートとはある技術にたいする無目的で非生産的な具体的行為を意味する)。

バージョン番号は、もしあれば‘Package-Version’ヘッダー、それ以外は‘Version’ヘッダーから取得されます。これらのヘッダーのいずれかが提供されていなればなりません。ここでのバージョン番号は1.3です。

そのファイルに‘;;; Commentary:’セクションがあれば、そのセクションは長い説明(long description)として使用されます(その説明を表示する際にはEmacsは‘;;; Commentary:’の行とコメント内のコメント文字列を省略する)。

そのファイルに‘Package-Requires’ヘッダーがあればパッケージの依存関係(package dependencies)として使用されます。上の例ではパッケージはバージョン1.0以上の‘flange’パッケージに依存します。‘Package-Requires’ヘッダーの説明はEmacsライブラリーのヘッダーの慣習を参照してください。このヘッダーが省略された場合にはパッケージに依存関係はありません。

ヘッダー‘Keywords’と‘URL’はオプションですが含めることを推奨します。コマンドdescribe-packageは出力にリンクを追加するためにこれらを使用します。‘Keywords’ヘッダーにはfinder-known-keywordsリストからの標準的キーワードを少なくとも1つ含めるべきです。

ファイルにはパッケージ化の基礎で説明したように1つ以上のautoloadマジックコメントも含めるべきです。上の例ではマジックコメントによりsuperfrobnicator-modeが自動ロードされます。

パッケージアーカイブに単一ファイルのパッケージを追加する方法はパッケージアーカイブの作成と保守を参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

43.3 複数ファイルのパッケージ

複数ファイルパッケージは単一ファイルパッケージより作成の手軽さが少し劣りますが、より多くの機能を提供します。複数ファイルパッケージには複数のEmacs Lispファイル、Infoマニュアル、および(イメージのような)他のファイルタイプを含めることができます。

インストールに先立ち複数パッケージはファイルとしてパッケージアーカイブに含まれます。このtarファイルはname-version.tarという名前でなければなりません。ここでnameはパッケージ名、versionはバージョン番号です。tarのコンテンツは一度解凍されたなら、コンテンツディレクトリcontent directory)であるname-versionという名前のディレクトリーにすべて解凍されなければなりません(パッケージ化の基礎を参照)。このコンテンツディレクトリーのサブディレクトリーにもファイルが抽出されるかもしれません。

このコンテンツディレクトリー内のファイルのうち1つはname-pkg.elという名前のファイルでなければなりません。このファイルには、以下で説明する関数define-packageの呼び出しから構成される単一のLispフォームを含まなければなりません。これはパッケージの属性、簡単な説明(brief description)、必要条件(requirements)を定義します。

たとえば、複数ファイルパッケージとしてsuperfrobnicatorのバージョン1.3を配布する場合のtarファイルはsuperfrobnicator-1.3.tarになります。これのコンテンツはsuperfrobnicator-1.3に解凍されて、そのうちの1つはファイルsuperfrobnicator-pkg.elになるでしょう。

Function: define-package name version &optional docstring requirements

この関数はパッケージを定義する。nameはパッケージの名前(文字列)、versionは関数version-to-listが理解できる形式のバージョン(文字列)、docstringは簡単な説明(brief description)。

requirementsは必要となるパッケージとバージョン番号。このリスト内の各要素は(dep-name dep-version)という形式であること。ここでdep-nameはその依存するパッケージ名が名前であるようなシンボル、dep-versionは依存するパッケージのバージョン番号(文字列)。

コンテンツディレクトリーにREADMEという名前のファイルがあれば、(すべての‘;;; Commentary:’セクションをオーバーライドして)長い説明(long description)として使用されます。

コンテンツディレクトリーにdirという名前のファイルがあれば、install-infoで作成されるInfoディレクトリーファイル名とみなされます。Invoking install-info in Texinfoを参照してください。関係のあるInfoファイルもコンテンツディレクトリー内に解凍される必要があります。この場合には、パッケージがアクティブ化されたときにEmacsが自動的にInfo-directory-listにコンテンツディレクトリーを追加します。

パッケージ内に.elcファイルを含めないでください。これらはパッケージのインストール時に作成されます。ファイルがバイトコンパイルされる順序を制御する方法は存在しないことに注意してください。

name-autoloads.elという名前のファイルを含めてはなりません。このファイルはパッケージのautoload定義のために予約済みです(パッケージ化の基礎を参照)。これはパッケージのインストール時にパッケージ内のすべてのLispファイルからautoloadマジックコメントを検索する際に自動的に作成されます。

複数パッケージファイルが、(イメージのような)補助的なデータファイルを含む場合には、パッケージ内のLispファイルは変数load-file-nameを通じてそれらのファイルを参照できます(ロードを参照)。以下は例です:

(defconst superfrobnicator-base (file-name-directory load-file-name))

(defun superfrobnicator-fetch-image (file)
  (expand-file-name file superfrobnicator-base))

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

43.4 パッケージアーカイブの作成と保守

Package Menuを通じてパッケージアーカイブ(package archives)からユーザーはパッケージをダウンロードできます。このようなアーカイブは変数package-archivesで指定されます。この変数のデフォルト値はGNU ELPAnon-GNU ELPAでホストされるアーカイブのリストです。このセクションではパッケージアーカイブのセットアップと保守の方法について説明します。

User Option: package-archives

この変数の値はEmacsパッケージマネージャーが認識するパッケージアーカイブのリスト。

このalistの要素はそれぞれが1つのアーカイブに対応する(id . location)という形式であること。ここでidはパッケージ名(文字列)、locationは文字列であるようなベースロケーション(base location)

ベースロケーションが‘http:’か‘https:’で始まる場合にはHTTP(S)のURLとして扱われて、(デフォルトのGNUアーカイブのように)HTTP(S)を介してこのアーカイブからパッケージがダウンロードされる。

それ以外ならベースロケーションはディレクトリー名であること。この場合にはEmacsは通常のファイルアクセスを通じて、そのアーカイブからパッケージを取得する。localのようなアーカイブは主としてテストに有用。

パッケージアーカイブはパッケージ、および関連するファイルが格納された単なるディレクトリーです。HTTPを介してそのアーカイブに到達できるようにしたければ、このディレクトリーがウェブサーバーにアクセスできなければなりません。アーカイブウェブサーバーとのインターフェイスを参照してください。

手軽なのはpackage-xを通じてパッケージアーカイブのセットアップと更新を行う方法です。これはEmacsに含まれていますがデフォルトではロードされません。ロードするにはM-x load-library RET package-x RET、または(require 'package-x)をinitファイルに追加します。Lisp Libraries in The GNU Emacs Manualを参照してください。

アーカイブ作成後に、それがpackage-archives内になければPackage Menuインターフェースからアクセスできないことを忘れないでください。

公的なパッケージアーカイブの保守には責任が併ないます。アーカイブからEmacsユーザーがパッケージをインストールする際には、それらのパッケージはそのユーザーの権限において任意のコードを実行できるようになります(これはパッケージにたいしてだけでなく一般的なEmacsコードにたいしても真といえる)。そのためアーカイブの保守を保つとともにホスティングシステムが安全であるよう維持するべきです。

暗号化されたキーを使用してパッケージにサイン(sign)するのがパッケージのセキュリティーを向上する1つの方法です。gpgのprivateキーとpublicキーを生成してあれば以下のようにそのパッケージにサインするためにgpgを使用できます:

gpg -ba -o file.sig file

単一ファイルパッケージにたいしては、fileはそのパッケージのLispファイルです。複数ファイルパッケージではそのパッケージのtarファイルです。同じ方法によりアーカイブのコンテンツファイルにもサインできます。これを行うにはパッケージと同じディレクトリーで.sigファイルを利用可能できるようにしてください。ダウンロードする人にたいしても、https://pgp.mit.edu/のようなキーサーバーにアップロードすることによりpublicキーを利用できるようにするべきです。その人がアーカイブからパッケージをインストールする際には署名の検証にpublicキーを使用できます。

これらの方法についての完全な説明はマニュアルの範囲を超えます。暗号化キーとサインに関する詳細はGnuPG in The GNU Privacy Guard Manual、Emacsに付属するGNU Privacy GuardへのインターフェースについてはEasyPG in Emacs EasyPG Assistant Manualを参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

43.5 アーカイブウェブサーバーとのインターフェイス

パッケージアーカイブへのアクセスを提供するウェブサーバーは、以下のクエリーをサポートしなければなりません:

archive-contents

アーカイブ内容を記述するlispフォーム。このフォームはリストの最初の要素がアーカイブバージョンであることを除けば’package-desc’構造(package.elを参照)のリストである。

<package name>-readme.txt

パッケージの長い説明(long description)をリターンする。

<file name>.sig

そのファイルの署名をリターンする。

<file name>

そのファイルをリターンする。これは複数ファイルパッケージではtarball、シンプルパッケージでは単一ファイルかもしれない。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Appendix A Emacs 28 Antinews

時代に逆らって生きるユーザーのために、以下はEmacsバージョン28.2へのダウングレードに関する情報です。Emacs 29.1機能の不在による結果としての偉大なる単純さをぜひ堪能してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Appendix B GNU Free Documentation License

Version 1.3, 3 November 2008
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
https://fsf.org/

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
  1. PREAMBLE

    The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

    This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

    We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

  2. APPLICABILITY AND DEFINITIONS

    This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.

    A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

    A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

    The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

    The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.

    A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”.

    Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.

    The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text.

    The “publisher” means any person or entity that distributes copies of the Document to the public.

    A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition.

    The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

  3. VERBATIM COPYING

    You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

    You may also lend copies, under the same conditions stated above, and you may publicly display copies.

  4. COPYING IN QUANTITY

    If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

    If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

    If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

    It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

  5. MODIFICATIONS

    You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

    1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
    2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
    3. State on the Title page the name of the publisher of the Modified Version, as the publisher.
    4. Preserve all the copyright notices of the Document.
    5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
    6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
    7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice.
    8. Include an unaltered copy of this License.
    9. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
    10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
    11. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
    12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
    13. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version.
    14. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section.
    15. Preserve any Warranty Disclaimers.

    If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles.

    You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

    You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

    The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

  6. COMBINING DOCUMENTS

    You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

    The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

    In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements.”

  7. COLLECTIONS OF DOCUMENTS

    You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

    You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

  8. AGGREGATION WITH INDEPENDENT WORKS

    A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.

    If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

  9. TRANSLATION

    Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

    If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

  10. TERMINATION

    You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License.

    However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

    Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

    Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it.

  11. FUTURE REVISIONS OF THIS LICENSE

    The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See https://www.gnu.org/licenses/.

    Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document.

  12. RELICENSING

    “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable works thus published on the MMC site.

    “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization.

    “Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document.

    An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.

    The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing.

ADDENDUM: How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

  Copyright (C)  year  your name.
  Permission is granted to copy, distribute and/or modify this document
  under the terms of the GNU Free Documentation License, Version 1.3
  or any later version published by the Free Software Foundation;
  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
  Texts.  A copy of the license is included in the section entitled ``GNU
  Free Documentation License''.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with…Texts.” line with this:

    with the Invariant Sections being list their titles, with
    the Front-Cover Texts being list, and with the Back-Cover Texts
    being list.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Appendix C GNU General Public License

Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. https://fsf.org/

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.

Preamble

The GNU General Public License is a free, copyleft license for software and other kinds of works.

The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program—to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.

To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.

Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.

For the developers’ and authors’ protection, the GPL clearly explains that there is no warranty for this free software. For both users’ and authors’ sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.

Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users’ freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.

Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free.

The precise terms and conditions for copying, distribution and modification follow.

TERMS AND CONDITIONS

  1. Definitions.

    “This License” refers to version 3 of the GNU General Public License.

    “Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.

    “The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations.

    To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work.

    A “covered work” means either the unmodified Program or a work based on the Program.

    To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.

    To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.

    An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.

  2. Source Code.

    The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work.

    A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.

    The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.

    The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work’s System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.

    The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.

    The Corresponding Source for a work in source code form is that same work.

  3. Basic Permissions.

    All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.

    You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.

    Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary.

  4. Protecting Users’ Legal Rights From Anti-Circumvention Law.

    No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.

    When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work’s users, your or third parties’ legal rights to forbid circumvention of technological measures.

  5. Conveying Verbatim Copies.

    You may convey verbatim copies of the Program’s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.

    You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.

  6. Conveying Modified Source Versions.

    You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:

    1. The work must carry prominent notices stating that you modified it, and giving a relevant date.
    2. The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”.
    3. You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
    4. If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.

    A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation’s users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.

  7. Conveying Non-Source Forms.

    You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:

    1. Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
    2. Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
    3. Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
    4. Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
    5. Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.

    A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.

    A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.

    “Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.

    If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).

    The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.

    Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.

  8. Additional Terms.

    “Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.

    When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.

    Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:

    1. Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
    2. Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
    3. Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
    4. Limiting the use for publicity purposes of names of licensors or authors of the material; or
    5. Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
    6. Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.

    All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.

    If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.

    Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.

  9. Termination.

    You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).

    However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

    Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

    Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.

  10. Acceptance Not Required for Having Copies.

    You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.

  11. Automatic Licensing of Downstream Recipients.

    Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License.

    An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party’s predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.

    You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.

  12. Patents.

    A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor’s “contributor version”.

    A contributor’s “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.

    Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor’s essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.

    In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.

    If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient’s use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.

    If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.

    A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.

    Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.

  13. No Surrender of Others’ Freedom.

    If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.

  14. Use with the GNU Affero General Public License.

    Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.

  15. Revised Versions of this License.

    The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

    Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.

    If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Program.

    Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.

  16. Disclaimer of Warranty.

    THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  17. Limitation of Liability.

    IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

  18. Interpretation of Sections 15 and 16.

    If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.

END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.

one line to give the program's name and a brief idea of what it does.
Copyright (C) year name of author

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see https://www.gnu.org/licenses/.

Also add information on how to contact you by electronic and paper mail.

If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:

program Copyright (C) year name of author
This program comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’.
This is free software, and you are welcome to redistribute it
under certain conditions; type ‘show c’ for details.

The hypothetical commands ‘show w’ and ‘show c’ should show the appropriate parts of the General Public License. Of course, your program’s commands might be different; for a GUI interface, you would use an “about box”.

You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see https://www.gnu.org/licenses/.

The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read https://www.gnu.org/licenses/why-not-lgpl.html.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Appendix D ヒントと規約

このチャプターでではEmacs Lispの追加機能については説明しません。かわりに以前のチャプターで説明した機能を効果的に使う方法、およびEmacs Lispプログラマーがしたがうべき慣習を説明します。

以降で説明する慣習のいくつかはLispファイルのvisit時にコマンドM-x checkdoc RETを実行することにより自動的にチェックできます。これはすべての慣習はチェックできませんし、与えられた警告すべてが必ずしも問題に対応する訳ではありませんが、それらすべてを検証することには価値があります。カレントバッファーの慣習をチェックするにはコマンドM-x checkdoc-current-buffer RET、(たとえばM-x compile RETで実行するコマンドとともに)batchモードでファイルをチェックしたければcheckdoc-fileをかわりに使用してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

D.1 Emacs Lispコーディング規約

以下は幅広いユーザーを意図したEmacs Lispコードを記述する際にしたがうべき慣習です:

  • 単なるパッケージのロードがEmacsの編集の挙動を変更するべききではない。コマンド、その機能を有効や無効にするコマンド、その呼び出しが含まれる。

    この慣習はカスタム定義を含むすべてのファイルに必須である。そのようなファイルを慣習にしたがうために修正するのが非互換の変更を要するなら、構うことはないから非互換の修正を行うこと。先送りにしてはならない。

  • 他のLispプログラムと区別するための短い単語を選択すること。あなたのプログラム内のグローバルなシンボルすべて、すなわち変数、定数、関数の名前はその選択したプレフィクスで始まること。そのプレフィクスと名前の残りの部分はハイフン‘-’で区切る。Emacs Lisp内のすべてのグローバル変数は同じネームスペース、関数はすべて別のネームスペースを共有するので、これの実践は名前の競合を回避する33。他のパッケージから使用されることを意図しない場合にはプレフィクスと名前を2つのハイフンで区切ること。

    ユーザーの使用を意図したコマンド名では、何らかの単語がそのパッケージ名のプレフィクスの前にあると便利なことがある。たとえばわたしちの慣習ではオブジェクトをリストするコマンドの名前なら‘list-something’、すなわち‘frob’と呼ばれるパッケージのグローバルシンボルが‘frob-’で始まれば‘list-frobs’というコマンドをもつかもしれない。さらに関数や変数等を定義する構文が‘define-’で始まればより良く機能するので、名前内でそれらの後に名前プレフィクスを置くこと。

    この勧告はcopy-listのようなEmacs Lisp内のプリミティブではなく、伝統的なLispプリミティブにさえ適用される。信じようと信じまいとcopy-listを定義する尤もらしい方法は複数あるのだ。安全第一である。かわりにfoo-copy-listmylib-copy-listのような名前を生成するために、あなたの名前プレフィクスを追加しよう。

    twiddle-filesのような特定の名前でEmacsに追加されるべきだと考えている関数を記述する場合には、プログラム内でそれを名前で呼び出さないこと。プログラム内ではそれをmylib-twiddle-filesで呼び出して、わたしたちがそれをEmacsに追加するため提案メールを、‘bug-gnu-emacs@gnu.org’に送信すること。もし追加することになったときに、わたしたちは十分容易にその名前を変更できるだろう。

    1つのプレフィクスで十分でなければ、それらに意味があるかぎり、あなたのパッケージは2つか3つの一般的なプレフィクス候補を使用できる。

  • 新しいコードではlexical-bindingを有効にすること、まだ有効にされていない既存のEmacs Lispコードではlexical-bindingを有効にするよう変換することを推奨する。レキシカルバインディングの使用を参照のこと。
  • 個々のLispファイルすべての終端にprovide呼出を配置すること。名前つき機能を参照のこと。
  • 事前に他の特定のLispプログラムのロードを要するファイルはファイル先頭のコメントでそのように告げるべきである。また、それらが確実にロードされるようにrequireを使用すること。名前つき機能を参照のこと。
  • ファイルfooが別のファイルbar内で定義されたマクロを使用するが、bar内の他の関数や変数を何も使用しない場合にはfooに以下の式を含めること:
    (eval-when-compile (require 'bar))
    

    これはfooのバイトコンパイル直前にbarをロードするようEmacsに告げるので、そのマクロはコンパイル中は利用可能になる。eval-when-compileの使用によりコンパイル済みバージョンのfoo中古ならbarのロードを避けられる。これはファイル内の最初のマクロ呼び出しの前に呼び出すこと。マクロとバイトコンパイルを参照のこと。

  • 実行時に本当に必要でなければ、追加ライブラリーのロードを避けること。あなたのファイルが単に他のいくつかのライブラリーなしでは機能しないなら、トップレベルでそのライブラリーを単にrequireしてこれを行うこと。しかしあなたのファイルがいくつかの独立した機能を含み、それらの1つか2つだけが余分なライブラリーを要するなら、トップレベルではなく関連する関数内部へのrequireの配置を考慮すること。または必要時に余分のライブラリーをロードするためにautoloadステートメントを使用すること。この方法ではあなたのファイルの該当部分を使用しない人は、余分なライブラリーをロードする必要がなくなる。
  • Common Lisp拡張が必要なら古いclライブラリーではなく、cl-libライブラリーを使うこと。clライブラリーは非推奨でありEmacsの将来バージョンでは削除されるだろう。
  • メジャーモードを定義する際にはメジャーモードの慣習にしたがってほしい。メジャーモードの慣習を参照のこと。
  • マイナーモードを定義する際にはマイナーモードの慣習にしたがってほしい。マイナーモード記述の規約を参照のこと。
  • ある関数の目的が特定の条件の真偽を告げることであるなら、(述語である“predicate”を意味する) ‘p’で終わる名前を与えること。その名前が1単語なら単に‘p’、複数単語なら‘-p’を追加する。例はframepframe-live-p。変数が述語関数でないなら、この-pサフィックスの使用を避けるよう推奨する。かわりに-flagサフィックスやis-fooのような名前を使用すること。
  • ある変数の目的が単一の関数の格納にあるなら、‘-function’で終わる名前を与えること。ある変数の目的が関数のリストの格納にあるなら(たとえばその変数がフックなら)、フックの命名規約にしたがってほしい。フックを参照のこと。
  • unload-featureを使用することで、通常は機能のロードにより行われる(フックへの関数追加のような)変更がアンドゥされる。しかしfeatureのロードが何か特殊で複雑なことを行う場合には、feature-unload-functionという名前の関数を定義して、そのような特別な変更をアンドゥさせることができる。この関数が存在する場合には、unload-featureは自動的にそれを実行する。アンロードを参照のこと。
  • Emacsのプリミティブにエイリアスを定義するのは悪いアイデアである。かわりに通常は標準の名前を使用すること。エイリアスが有用になるかもしれないケースは後方互換性や可搬性を向上させる場合である。
  • パッケージで別のバージョンのEmacsにたいする互換性のためにエイリアスや新たな関数の定義が必要なら、別のバージョンにあるそのままの名前ではなくパッケージのプレフィクスを名前に付加すること。以下はそのような互換性問題を多く提供するGnusでの例。
    (defalias 'gnus-point-at-bol
      (if (fboundp 'point-at-bol)
          'point-at-bol
        'line-beginning-position))
    
  • Emacsのプリミティブの再定義やadviseは悪いアイデアである。これは特定のプログラムには正しいことを行うが結果として他のプロラムが破壊されるかもしれない。
  • 同様にあるLispパッケージで別のLispパッケージ内の関数にadviseするのも悪いアイデアである。
  • ライブラリやパッケージでのeval-after-loadwith-eval-after-loadの使用を避けること(ロードのためのフックを参照)。この機能は個人的なカスタマイズを意図している。Lispプログラム内でこれを使用すると別のLisp内ではそれが見えず、その挙動を変更するために不明瞭になる。これは別のパッケージ内の関数へのadviseと同様にデバッグの障害になる。
  • Emacsの標準的な関数やライブラリープログラムの何かをファイルが置換するなら、そのファイル冒頭の主要コメントでどの関数が置換されるか、置換によりオリジナルと挙動がどのように異なるかを告げること。
  • 関数や変数を定義するコンストラクターは関数ではなくマクロにして名前は‘define-’で始まること。そのマクロは定義される名前を1つ目の引数で受け取ること。これは自動的に定義を探す種々のツールの助けとなる。マクロ自身の中でその名前を構築するのは、それらのツールを混乱させるので避けること。
  • 別のいくつかのシステムでは‘*’が先頭や終端にある変数名を選択する慣習がある。Emacs Lispではその慣習を使用しないので、あなたのプログラム内でそれを使用しないでほしい(Emacsでは特別な目的をもつバッファーだけにそのような名前を使用する)。すべてのライブラリーが同じ慣習を使用するなら人はEmacsがより整合性があることを見い出すだろう。
  • Emacs LispソースファイルのデフォルトのファイルコーディングシステムはUTFである(テキストの表現方法を参照)。あなたのプログラムがUTF-8以外の文字を含むような稀なケースでは、ソースファイル内の‘-*-’行かローカル変数リスト内で適切なコーディングシステムを指定すること。Local Variables in Files in The GNU Emacs Manualを参照のこと。
  • デフォルトのインデントパラメーターでファイルをインデントすること。
  • 自分で行に閉カッコを配置するのを習慣としてはならない。Lispプログラマーはこれに当惑させられる。
  • コピーを配布する場合は著作権表示と複製許可表示を配置してほしい。Emacsライブラリーのヘッダーの慣習を参照のこと。
  • ファイルやディレクトリーの名前を保持する変数(およびそれらをリターンする関数)では名前にpathを使うことを避けて、かわりにfilefile-namedirectoryを優先して使用すること。なぜならGNUコーディング規約では検索パス(ディレクトリー名のリスト)だけにpathという用語を用いることになっており、Emacsはそれを遵守するからである。

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

D.2 キーバインディング規約

  • Dired、Info、Compilation、Occurなどの多くのメジャーモードではハイパーリンクを含む読み取り専用テキストを処理するようデザインされている。そのようなメジャーモードはリンクをフォローするようにmouse-2RETを再定義すること。そのリンクがmouse-1-click-follows-linkにしたがうようにfollow-link条件もセットアップすること。クリック可能なテキストの定義を参照のこと。そのようなクリック可能リンクを実装する簡便な手法についてはボタンを参照のこと。
  • Lispプログラム内のキーとしてC-c letterを定義してはならない。C-cとアルファベット(ASCIIおよび非ASCIIの大文字と小文字の両方)からなるシーケンスはユーザー用に予約済みである。これらはユーザー用として唯一予約されたシーケンスなので阻害してはならない。

    すべてのメジャーモードがこの慣習を尊重するよう変更するには多大な作業を要する。この慣習を捨て去ればそのような作業は不要になりユーザーは不便になるだろう。この慣習を遵守してほしい。

  • 修飾キーなしのF5からF9までのファンクションキーもユーザー定義用に予約済み。
  • 後にコントロールキーか数字が続くC-cシーケンスはメジャーモード用に予約済みである。
  • 後に{}<>:;が続くC-cシーケンスもメジャーモード用に予約済み。
  • 後に他のASCII区切り文字やシンボル文字が続くC-cシーケンスはマイナーモードに割り当てられている。メジャーモード内でのそれらの使用は絶対禁止ではないが、もしそれを行えばそのメジャーモードがマイナーモードにより時々シャドーされるかもしれない。
  • 後にプレフィクス文字(C-cを含む)が続くC-hをバインドしてはならない。C-hをバインドしなければ、そのプレフィクス文字をもつサブコマンドをリストするためのヘルプ文字として自動的に利用可能になる。
  • 別のESCが後に続く場合を除きESCで終わるキーシーケンスをバインドしてはならない(つまりESC ESCで終わるキーシーケンスのバインドはOK)。

    このルールの理由は任意のコンテキストにおける非プレフィクスであるようなESCのバインディングは、そのコンテキストにおいてファンクションキーとなるようなエスケープシーケンスの認識を阻害するからである。

  • 同様にC-gは一般的にはキーシーケンスのキャンセルに使用されるので、C-gで終わるキーシーケンスをバインドしてはならない。
  • 一時的なモードやユーザーが出入り可能な状態のような動作は、すべてエスケープ手段としてESC ESCESC ESC ESCを定義すること。

    通常のEmacsコマンドを受け入れる状態、より一般的には後にファンクションキーか矢印キーが続くESC内のような状態は潜在的な意味をもつのでESC ESCを定義してはならない。なぜならそれはESCの後のエスケープシーケンスの認識を阻害するからである。これらの状態においては、エスケープ手段としてESC ESC ESCを定義すること。それ以外ならかわりにESC ESCを定義すること。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

D.3 Emacsプログラミングのヒント

以下の慣習にしたがうことによりあなたのプログラムが実行時によりEmacsに適合するようになります。

  • プログラム内でnext-lineprevious-lineを使用してはならない。ほとんど常にforward-lineのほうがより簡便であり、より予測可能かつ堅牢である。テキスト行単位の移動を参照のこと。
  • あなたのプログラム内でマークのセットが意図した機能でないなら、マークをセットする関数を呼び出してはならない。マークはユーザーレベルの機能なので、ユーザーの益となる値を提供する場合を除きマークの変更は間違いである。マークを参照のこと。

    特に以下の関数は使用しないこと:

    • beginning-of-bufferend-of-buffer
    • replace-stringreplace-regexp
    • insert-fileinsert-buffer

    インタラクティブなユーザーを意図した別の機能がないのにポイントの移動、特定の文字列の置換、またはファイルやバッファーのコンテンツを挿入したいだけなら単純な1、2行のLispコードでそれらの関数を置き換えられる。

  • ベクターを使用する特別な理由がある場合を除きベクターではなくリストを使用すること。Lispではベクターよりリストを操作する機能のほうが多く、リストを処理するほうが通常は簡便である。

    要素の挿入や削除がなく(これはリストだけで可能)、ある程度のサイズがあって、(先頭か末尾から検索しない)ランダムアクセスがあるテーブルではベクターが有利。

  • エコーエリア内にメッセージを表示する推奨方法はprincではなくmessage関数。エコーエリアを参照のこと。
  • エラーコンディションに遭遇したときは関数error (またはsignal)を呼び出すこと。関数errorはリターンしない。エラーをシグナルする方法を参照のこと。

    エラーの報告にmessagethrowsleep-forbeepを使用しないこと。

  • エラーメッセージは大文字で始まり、ピリオドや他の区切り文字で終わらないこと。

    たとえdebug-on-errornilであっても、ユーザーにエラーの発生元を伝えることが有用な場合もある。そのような場合には、エラーメッセージに小文字のLispシンボルを前置できる。たとえばエラーメッセージ“Invalid input”を“some-function: Invalid input”となるように拡張できる。

  • ミニバッファー内でyes-or-no-py-or-n-pで答えを求める質問を行う場合には大文字で始めて‘?’で終わること。
  • ミニバッファーのプロンプトでデフォルト値を示すときは、カッコ内に単語‘default’を配置すること。これは以下のようになる:
    Enter the answer (default 42):
    
  • interactiveで引数リストを生成するLisp式を使用する場合には、リージョンやポジションの引数にたいして正しいデフォルト値を生成しようと試みではならない。それらの引数が指定されていなければかわりにnilを提供して、引数がnilのときに関数のbodyでデフォルト値を計算すること。たとえば以下のように記述する:
    (defun foo (pos)
      (interactive
       (list (if specified specified-pos)))
      (unless pos (setq pos default-pos))
      ...)
    

    以下のようにはしない:

    (defun foo (pos)
      (interactive
       (list (if specified specified-pos
                 default-pos)))
      ...)
    

    これはそのコマンドを繰り返す場合に、そのときの状況にもとづいてデフォルト値が再計算されるからである。

    interactiveの‘d’、‘m’、‘r’指定を使用する際にはコマンドを繰り返すときの引数値の再計算にたいして特別な段取りを行うので、このような注意事項を採用する必要はない。

  • 実行に長時間を要する多くのコマンドは開始時に‘Operating...’、完了時に‘Operating...done’のような何らかのメッセージを表示すること。これらのメッセージのスタイルは‘...’の周囲にスペースを置かず、‘done’の後にピリオドを置かないよう一定に保ってほしい。そのようなメッセージを生成する簡便な方法は処理の進捗レポートを参照のこと。
  • 再帰編集の使用を避けること。かわりにRmailのeコマンドが行うように、元のローカルキーマップに戻るよう定義したコマンドを含んだ新たなローカルキーマップを使用するか、単に別のバッファーにスイッチしてユーザーが自身で戻れるようにすること。再帰編集を参照のこと。

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

D.4 コンパイル済みコードを高速化ためのヒント

以下はバイトコンパイル済みLispプログラムの実行速度を改善する方法です。

  • 時間がどこで消費されているか見つかるためにプログラムのプロファイルを行う。プロファイリングを参照のこと。
  • 可能なら常に再帰ではなく繰り返しを使用する。Emacs Lispではコンパイル済み関数が別のコンパイル済み関数を呼び出すときでさえ関数呼び出しは低速である。
  • プリミティブのリスト検索関数memqmemberassqassocは明示的な繰り返しより更に高速である。これらの検索プリミティブを使用できるようにデータ構造を再配置することにも価値が有り得る。
  • 特定のビルトイン関数は通常の関数呼び出しの必要を回避するようにバイトコンパイル済みコードでは特別に扱われる。別の候補案のかわりにこれらの関数を使用するのは良いアイデアである。コンパイラーにより特別に扱われる関数かどうかを確認するにはbyte-compileプロパティを調べればよい。そのプロパティが非nilならその関数は特別に扱われる。

    たとえば以下を入力するとarefが特別にコンパイルされえることが示される(配列を操作する関数を参照):

    (get 'aref 'byte-compile)
         ⇒ byte-compile-two-args
    

    この場合(および他の多くの場合)には、最初にbyte-compileプロパティを定義するbytecompライブラリーをロードしなければならない。

  • プログラム内で実行時間のある程度を占める小さい関数を呼び出すなら関数をinlineにする。これにより関数呼び出しのオーバーヘッドがなくなる。関数のinline化はプログラム変更の自由度を減少させるのでユーザーがスピードを気にするに足るほど低速であり、inline化により顕著に速度が改善されるのでなければ行ってはならない。インライン関数Inliを参照のこと。

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

D.5 コンパイラー警告を回避するためのヒント

  • 以下のようにダミーのdefvar定義を追加して未定義のフリー変数に関するコンパイラーの警告の回避を試みる:
    (defvar foo)
    

    このような定義はファイル内での変数fooの使用にたいしてコンパイラーが警告しないようにする以外に影響はない。

  • 同様にdeclare-functionステートメントを使用して、定義されるこが既知な未定義関数に関するコンパイラーの警告の回避を試みる(コンパイラーへの定義済み関数の指示を参照)。
  • 特定のファイルから多くの関数、マクロ、変数を使用する場合には、それらに関するコンパイラー警告を回避するために、以下のようにパッケージにrequireを追加できる(requireを参照):
    (require 'foo)
    

    何らかののファイルのマクロだけが必要ならコンパイル時だけrequireできる(コンパイル中の評価を参照)。たとえば、

    (eval-when-compile
      (require 'foo))
    
  • ある関数内で変数をバインドして別の関数内で使用やセットする場合には、その変数が定義をもたなければ別関数に関してコンパイラーは警告を行う。しかしその変数が短い名前をもつ場合には、Lispパッケージは短い変数名を定義するべきではないので定義の追加により不明瞭になるかもしれない。行うべき正しい方法はパッケージ内の他の関数や変数に使用されている名前プレフィクスで始まるように変数をリネームすることである。
  • 警告を回避する最後の手段は通常なら間違いであるが、その使用法では間違いではないと解っている何かを行う際にはwith-no-warningsの内側に置くこと。コンパイラーのエラーを参照のこと。

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

D.6 ドキュメント文字列のヒント

以下はドキュメント文字列記述に関するいくつかのヒントと慣習です。コマンドM-x checkdoc-minor-modeを実行すれば慣習の多くをチェックできます。

  • ユーザーが理解することを意図したすべての関数、コマン、変数はドキュント文字列をもつこと。
  • Lispプログラムの内部的な変数とサブルーチンは同様にドキュメント文字列をもつことができる。ドキュメント文字列は実行中のEmacs内で非常に僅かなスペースしか占めない。
  • 80列スクリーンのEmacsウィンドウに適合するようにドキュメント文字列をフォーマットすること。ほとんどの行を60文字以下に短くするのは良いアイデアである。最初の行は67文字以下にすること。さもないとaproposの出力で見栄えが悪くなる。

    見栄えがよくなるならそのテキストをフィルできる。Emacs Lispモードはemacs-lisp-docstring-fill-columnで指定された幅にドキュメント文字列をフィルする。しかしドキュメント文字列の行ブレークを注意深く調整すればドキュメント文字列の可読性をより向上できることがある。ドキュメント文字列が長い場合にはセクション間に空行を使用すること。

  • ドキュンメント文字列の最初の行は、それ自身が要約となるような1つか2つの完全なセンテンスから成り立つこと。M-x aproposは最初の行だけを表示するので、その行のコンテンツが自身で完結していなければ結果の見栄えは悪くなる。特に最初の行は大文字で始めてピリオドで終わること。

    関数では最初の行は“その関数は何を行うのか?”、変数にたいしては最初の行は“その値は何を意味するのか?”という問いに簡略に答えること。

    ドキュメント文字列を1行に制限しないこと。その関数や変数の使用法の詳細を説明する必要に応じてその分の行数を使用すること。テキストの残りの部分にたいしても完全なセンテンスを使用してほしい。

  • ユーザーが無効化されたコマンドの使用を試みる際には、Emacsはそれのドキュメント文字列の最初のパラグラフ(最初の空行までのすべて)だけを表示する。もし望むなら、その表示をより有用になるように最初の空行の前に何の情報を含めるか選択できる。
  • 最初の行ではその関数のすべての重要な引数と、関数呼び出しで記述される順にそれらに言及すること。その関数が多くの引数をもつなら最初の行でそれらすべてに言及するのは不可能である。この場合にはもっとも重要な引数を含む最初の引数数個について最初の行で言及すること。
  • ある関数のドキュメント文字列がその関数の引数の値に言及する際には、引数を大文字にした名前が引数の値であるかのように使用すること。つまり関数evalのドキュメント文字列では最初の引数の名前がformなので‘FORM’で参照する:
    Evaluate FORM and return its value.
    

    同様にリストやベクターのサブユニットへの分解で、それらのいくつかを異なるように示すような際にはメタ構文変数(metasyntactic variables)を大文字で記述すること。以下の例の‘KEY’と‘VALUE’はこれの実践例:

    The argument TABLE should be an alist whose elements
    have the form (KEY . VALUE).  Here, KEY is ...
    
  • ドキュメント文字列内でLispシンボルに言及する際にはcase(大文字小文字)を絶対に変更しないこと。そのシンボルの名前がfooなら“Foo”ではなく“foo”(“Foo”は違うシンボル)。

    これは関数の引数の値の記述ポリシーと反するように見えるかもしれないが矛盾は実際には存在しない。引数のvalueはその関数が値の保持に使用するsymbolと同じではない。

    これによりセンテンス先頭に小文字を置くことになり、それが煩しいならセンテンス開始がシンボルにならないようにセンテンスを書き換えること。

  • ドキュメント文字列の開始と終了に空白文字を使用しないこと。
  • ソースコード内の後続行のテキスト、最初の行と揃うようにドキュメント文字列の後続行をインデントしてはならない。これはソースコードでは見栄えがよいがユーザーがドキュメトを閲覧する際は奇妙な見栄えになる。開始のダブルクォーテーションの前のインデントは文字列の一部には含まれないことを忘れないこと!
  • ドキュメントにおいてASCIIのアポストロフィやグレイブアクセントを表示する必要がある際には、ドキュメントの文字列リテラルに‘\\='’や‘\\=`’を使えば文字はそのまま表示される。
  • ドキュメント文字列ではLispシンボルではないような式はそれら自身を表しているかもしれないのでクォートしてはならない。たとえば‘Return the list `(NAME TYPE RANGE)' ...’や‘Return the list \\='(NAME TYPE RANGE) ...’ではなく‘Return the list (NAME TYPE RANGE) ...’と記述すること。
  • ドキュメント文字列がLispシンボルを参照する際には、それがプリントされるとき(通常は小文字を意味する)のように前にグレイブアクセント‘`’、後にアポストロフィー‘'’を記述すること。例外が2つある。tnilは前後の区切り記号を記述しない。たとえば:
    CODE can be `lambda', nil, or t.
    

    これらのドキュメント文字列をEmacsが表示する際には、文字の表示がサポートされていれば通常は‘`’ (グレイブアクセント)に‘’ (左シングルクォーテーションマーク)、‘'’ (アポストロフィー)に‘’ (右シングルクォーテーションマーク)を表示することに注意。ドキュメント内でのキーバインディングの置き換えを参照のこと。 (このセクションの以前のバージョンでは、doc文字列で非ASCIIのシングルクォーテーションマークを推奨するバージョンがありましたが、このような文字をサポートしない端末におけるヘルプ文字列の表示が破壊されるので現在は推奨されていません。)

    Helpモードはシングルクォートされたシンボル名がドキュメント文字列で使用されている際には、それが関数と変数のいずれかの定義をもっていれば自動的にハイパーリンクを作成する。これらの機能を使用するために何か特別なことを行う必要はない。しかしあるシンボルが関数と変数の両方の定義をもち一方だけを参照したい場合には、そのシンボル名の直前に‘variable’、‘option’、‘function’、‘command’の単語のいずれかを記述してそれを指定できる(これらの指示語の識別では大文字小文字に差はない)。たとえば以下を記述すると

    This function sets the variable `buffer-file-name'.
    

    これのハイパーリンクはbuffer-file-nameの変数のドキュメントだけを参照して関数のドキュメントは参照しない。

    あるシンボルが関数および/または変数の定義をもつがドキュメントしているシンボルの使用とそれらが無関係なら、すべてのハイパーリンク作成を防ぐためにシンボル名の前に単語‘symbol’か‘program’を記述できる。たとえば、

    If the argument KIND-OF-RESULT is the symbol `list',
    this function returns a list of all the objects
    that satisfy the criterion.
    

    これは無関係な関数listのドキュメントにハイパーリンクを作成しない。

    変数ドキュメントがない変数には、通常はハイパーリンクは作成されない。そのような変数の前に単語‘variable’と‘option’のいずれかを記述すればハイパーリンクの作成を強制できる。

    フェイスにたいするハイパーリンクはフェイスの前か後に単語‘face’があれば作成される。この場合にはたとえそのシンボルが変数や関数として定義されていてもフェイスのドキュメントだけが表示される。

    Infoドキュメントにハイパーリンクを作成するには、‘info node’、‘Info node’、‘info anchor’、‘Info anchor’のいずれかの後Infoのノード(かアンカー)をシングルクォートして記述する。Infoファイル名のデフォルトは‘emacs’。たとえば、

    See Info node `Font Lock' and Info node `(elisp)Font Lock Basics'.
    

    manページにハイパーリンクを作成するには‘Man page’,‘man page’、‘man page for’のいずれかの後にシングルクォートされた名前記述する。たとえば、

    See the man page `chmod(1)' for details.
    

    manページInfoドキュメントのほうが常に好ましいので、リンク可能なInfoマニュアルがあるならリンクすること。たとえばchmodはGNU Coreutilsマニュアルにドキュメントされているので、manページよりそれにリンクするほうがよい。

    カスタマイゼーショングループをリンクするには、‘customization group’を前置してシングルクォートしたグループ名を記述する(各単語の先頭文字のcaseは区別しない)。たとえば、

    See the customization group `whitespace' for details.
    

    最後にURLのハイパーリンクを作成するには‘URL’の後にURLをシングルクォートして記述する。たとえば、

    The GNU project website has more information (see URL
    `https://www.gnu.org/').
    
  • ドキュメント文字列内に直接キーシーケンスを記述しないこと。かわりに、それらを表すために‘\\[…]’構文を使用すること。たとえば‘C-f’と記述するかわりに‘\\[forward-char]’と記述する。Emacsがドキュメント文字列を表示する際には何であれカレントでforward-charにバインドされたキーに置き換える(これは通常は‘C-f’だがユーザーがキーバインディングを変更していれば何か他の文字かもしれない)。ドキュメント内でのキーバインディングの置き換えを参照のこと。
  • メジャーモードのドキュメント文字列ではグローバルマップではなく、そのモードのローカルマップを参照したいだろう。したがってどのキーマップを使用するか指定するために、ドキュメント文字列内で一度‘\\<…>’構文を使用する。最初に‘\\[…]’を使用する前にこれを行うこと。‘\\<…>’の内部のテキストはメジャーモードにたいするローカルキーマップを含む変数名であること。

    \\[…]’を使用するたびに、僅かだがドキュメント文字列の表示が低速になる。これらを大量に使用すると僅かな低速化が積み重なり、特に低速なシステムでは有意なものとなるかもしれない。したがってこれらの過度な使用は推奨しない(同一ドキュメント内で同じコマンドへの複数参照の使用を避けるよう試みる等)。

  • 一貫性を保つために関数のドキュメント文字列の最初のセンテンス内の動詞は、命令形で表すこと。たとえば“Return the cons of A and B.”、好みによっては“Returns the cons of A and B.”を使用する。通常は最初のパラグラフの残りの部分にたいして同様に行っても見栄えがよい。各センテンスが叙実的で適切な主題をもつなら後続のパラグラフの見栄えはよくなる。
  • yes-or-no述語であるような関数のドキュメント文字列は、何が真を構成するか明示的に示すために、“Return t if”のような単語で始まること。単語“return”は小文字の“t”で開始される幾分紛らわしい可能性のあるセンテンスを避ける。
  • ドキュメント文字列は受動態ではなく能動態、未来形ではなく現在形で記述すること。たとえば“A list containing A and B will be returned.”ではなく、“Return a list containing A and B.”と記述すること。
  • 不必要な“cause”(や同等の単語)の使用を避けること。“Cause Emacs to display text in boldface”ではなく、単に“Display text in boldface”と記述すること。
  • 多くの人にとってなじみがなくtypoと間違えるであろうから、“iff”(“if and only if”を意味する数学用語)の使用を避けること。ほとんどの場合には、その意味は単なる“if”で明快である。それ以外ではその意味を伝える代替えフレーズを探すよう試みること。
  • “for example(たとえば)”に“e.g.”、“that is(つまり)”に“i.e.”、“number(数値)”に“no.”、“compare(比較)”/“see also(参照)”に“cf.”、“with respect to(に関しては)”にたいする“w.r.t.”のような略語の使用は可能なかぎり避けるよう努力すること。ほとんど常に展開されたバージョンのほうが読み易い34
  • 特定のモードや状況でのみコマンドに意味がある際にはドキュメント文字列内でそれに言及すること。たとえばdired-find-fileのドキュメントは:
    In Dired, visit the file or directory named on this line.
    
  • ユーザーがセットしたいと望むかもしれないオプションを表す変数を定義する際にはdefcustomを使用すること。グローバル変数の定義を参照のこと。
  • yes-or-noフラグであるような変数のドキュメント文字列は、すべての非nil値が等価であることを明確にして、nilと非nilが何を意味するかを明示的に示すために“Non-nil means”のような単語で始めること。
  • ドキュメント文字列内の開カッコで始まる行は、以下のように開カッコの前へのバックスラッシュの記述を考慮すること:
    The argument FOO can be either a number
    \(a buffer position) or a string (a file name).
    

    これは‘(’をdefunの開始として扱う27.1より古いバージョンのEmacsでのバグを回避する(Defuns in The GNU Emacs Manualを参照)。コードを古いバージョンのEmacsで編集する誰かをあなたが予期せぬのなら、この回避策は必要ない。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

D.7 コメント記述のヒント

コメントにたいして以下の慣習を推奨します:

;

1つのセミコロン‘;’で始まるコメントはソースコードの右側の同じ列にすべて揃えられる。そのようなコメントは通常はその行のコードがどのように処理を行うかを説明する。たとえば:

(setq base-version-list                 ; There was a base
      (assoc (substring fn 0 start-vn)  ; version to which
             file-version-assoc-list))  ; this looks like
                                        ; a subversion.
;;

2つのセミコロン‘;;’で始まるコメントはコードと同じインデントレベルで揃えられる。そのようなコメントは通常はその後の行の目的や、その箇所でのプログラムの状態を説明する。たとえば:

(prog1 (setq auto-fill-function
             …
             …
  ;; Update mode line.
  (force-mode-line-update)))

わたしたちは通常は関数の外側のコメントにも2つのセミコロンを使用する。

;; This Lisp code is run in Emacs when it is to operate as
;; a server for other processes.

関数がドキュメント文字列をもたなければ、かわりにその関数の直前にその関数が何を行うかと、正しく呼び出す方法を説明する2つのセミコロンのコメントをもつこと。各引数の意味と引数で可能な値をその関数が解釈する方法を正確に説明すること。しかしそのようなコメントはドキュメント文字列に変換するほうがはるかに優れている。

;;;

3つ(かそれ以上)のセミコロン‘;;;’で始まるコメントは左マージンから始まる。わたしたちはOutlineマイナーモードのheading(ヘッダー)とみなされるべきコメントにそれらを使用している。デフォルトでは少なくとも(後に1つの空白文字と非空白文字が続く)3つのセミコロンはsectionのヘッダーとみなして、2つ以下のセミコロンで始まるものはみなさない。

(歴史的に3連セミコロンのコメントは関数内の行のコメントアウトに使用されたきたが、この用途では2つだけのセミコロン使用を推奨し、3連セミコロンの使用は推奨しない。これは2連セミコロンを使用して関数全体をコメントアウトする際にも適用される。)

セミコロン3つはトップレベルのセクション、4つはサブセクション、5つはサブサブセクション、のように使用される。

ライブラリーは通常はトップレベルのセクションを少なくとも4つもつ。たとえばこれらのセクションすべてが隠されているときは:

;;; backquote.el --- implement the ` Lisp construct...
;;; Commentary:...
;;; Code:...
;;; backquote.el ends here

(テキストが後続することがあってはならない最後の行は、ある意味セクションヘッダーではない。これは最終的にはファイル終端をマークする。)

長いライブラリーではコードを複数セクションに分割するのが賢明である。これは‘Code:’セクションを複数のサブセクションに分割することで行うことができる。長い間、これが推奨される唯一のアプローチであったとはいえ、多くの人が複数のトップレベルセクションの使用を選択してきた。あなたはいずれかのスタイルを選択できる。

トップレベルのコードセクションの複数使用には、ネスティングレベルの追加導入を避けるという利点があるが、それはすべてのコードが‘Code’という名前のセクションに含まれていないという不体裁な結果をも意味する。これを避けるためには、そのセクション内部にコードを何も配置しないこと。この方法により、それをセクションヘッダーではなくセパレーターとみなすことができる。

この問題に対象するためにヘッダーをコロンや他の句読点で終了させないことを最後に推奨しておく。歴史的な理由により‘Code:’と‘Commentary:’のヘッダーはコロンで終わるが、何にせよ他のヘッダーに同じことを行わないことをお勧めする。

一般的に言うとコマンドM-; (comment-dwim)は適切なタイプのコメントを自動的に開始するか、セミコロンの数に応じて既存のコメントを正しい位置にインデントします。Manipulating Comments in The GNU Emacs Manualを参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

D.8 Emacsライブラリーのヘッダーの慣習

Emacsにはセクションに分割してそれの記述者のような情報を与えるために、Lispライブラリー内で特別なコメントを使用する慣習があります。それらのアイテムにたいして標準的なフォーマットを使用すれば、ツール(や人)が関連する情報を抽出するのが簡単になります。このセクションでは以下の例を出発点にこれらの慣習を説明します。

;;; foo.el --- Support for the Foo programming language  -*- lexical-binding: t; -*-

;; Copyright (C) 2010-2021 Your Name

;; Author: Your Name <yourname@example.com>
;; Maintainer: Someone Else <someone@example.com>
;; Created: 14 Jul 2010
;; Keywords: languages
;; URL: https://example.com/foo

;; This file is not part of GNU Emacs.

;; This file is free software…
…
;; along with this file.  If not, see <https://www.gnu.org/licenses/>.

一番最初の行は以下のフォーマットをもつべきです:

;;; filename --- description  -*- lexical-binding: t; -*-

この説明は1行に収まる必要があります。そのファイルで更に変数をセットするために‘-*-’指定が必要なら、lexical-bindingの後に配置してください。これにより最初の行が長くなりすぎるようなら、そのファイル終端でLocal Variablesセクションを使用してください。

著作権表示には、(あなたがそのファイルを記述したなら)通常はあなたの名前をリストします。あなたの作業の著作権を主張する雇用者がいる場合には、かわりに彼らをリストする必要があるかもしれません。Emacsディストリビューションにあなたのファイルが受け入れられていなければ、著作権者をFree Software Foundation(またはそのファイルがGNU Emacsの一部)だと告知しないでください。著作権とライセンス通知の形式に関するより詳細な情報はthe guide on the GNU websiteを参照してください。

著作権表示の後は、それぞれが‘;; header-name:’で始まる複数のヘッダーコメント(header comment)を記述します。以下は慣習的に利用できるheader-nameのテーブルです:

Author

このヘッダーは少なくともそのライブラリーの主要な作者の名前とemailアドレスを示す。複数の作者がいる場合には前に;;とタブか少なくとも2つのスペースがある継続行で彼らをリストする。わたしたちは‘<…>’という形式で連絡用emailアドレスを含めることを推奨する。たとえば:

;; Author: Your Name <yourname@example.com>
;;      Someone Else <someone@example.com>
;;      Another Person <another@example.com>
Maintainer

このヘッダーはAuthorヘッダーと同じフォーマット。これは現在そのファイルを保守(バグレポートへの応答等)をする人(か人々)をリストする。

MaintainerヘッダーがなければAuthorヘッダーの人(複数可)がMaintainerとみなされる。Emacs内のいくつかのファイルは、そのファイルのオリジナル作者がもはや責任をもっておらずEmacsの一部として保守されていることを意味するために、Maintainerに‘emacs-devel@gnu.org’を使用している。

Created

このオプションの行はファイルのオリジナルの作成日付を与えるもので歴史的な興味のためだけに存在する。

Version

個々のLispプログラムにたいしてバージョン番号を記録したいならこの行に配置する。Emacsとともに配布されたLispファイルはEmacsのバージョン番号自体が同じ役割を果たすので一般的には‘Version’ヘッダーをもたない。複数ファイルのコレクションを配布する場合には、各ファイルではなく主となるファイルにバージョンを記述することを推奨する。

Keywords

この行はヘルプコマンドfinder-by-keywordでリストするキーワード。意味のあるキーワードのリストの確認にこのコマンドを使用してほしい。コマンドM-x checkdoc-package-keywords RETfinder-known-keywordsにないすべてのキーワードを探して表示する。変数checkdoc-package-keywords-flagを非nilにセットすると、checkdocコマンドはチェックにキーワード検証を含める。

このフィールドはトピックでパッケージを探す人が、あなたのパッケージを見つける手段となる。キーワードを分割するにはスペースとカンマの両方を使用できる。

人はしばしばこのフィールドを単にFinder(訳注: finder-by-keywordがオープンするバッファー)に関連したキーワードではなくパッケージを説明する任意のキーワードを記述する箇所だとみなすのは不運なことだ。

URL
Homepage

この行はライブラリーのウェブサイトを示す。

Package-Version

Version’がパッケージマネージャーによる使用に適切でなければ、パッケージは‘Package-Version’を定義でき、かわりにこれが使用される。これは‘Version’がRCSやversion-to-listでパース不能な何かであるようなら手軽である。パッケージ化の基礎を参照のこと。

Package-Requires

これが存在する場合にはカレントパッケージが正しく動作するために依存するパッケージを示す。パッケージ化の基礎を参照のこと。これは(パッケージの完全なセットがダウンロードされることを確実にするために)ダウンロード時と、(すべての依存パッケージがあるときだけパッケージがアクティブになることを確実にするために)アクティブ化の両方でパッケージマネージャーにより使用される。

このフォーマットは単一行からなるリストのリスト。サブリストのcarはそれぞれパッケージの名前(シンボル)、cadrversion-to-listでパース可能な許容し得る最小のバージョン番号(文字列)。バージョンが欠落したエントリー(単なるシンボルやある要素のサブリストであるようなエントリー)はバージョンが"0"のエントリーと等価。たとえば:

;; Package-Requires: ((gnus "1.0") (bubbles "2.7.2") cl-lib (seq))

パッケージのコードは自動的に、実行中のEmacsのカレントのバージョン番号をもつ‘emacs’という名前のパッケージを定義する。これはパッケージが要求するEmacsの最小のバージョンに使用できる。

ほぼすべてのLispライブラリーは‘Author’と‘Keywords’のヘッダーコメント行をもつべきです。適切なら他のものを使用してください。ヘッダー行内で別のヘッダー行の名前も使用できます。これらは標準的な意味をもたないので害になることを行うことはできません。

わたしたちはライブラリーファイルのコンテンツを分割するために追加の提携コメントを使用します。これらは空行で他のものと分離されている必要があります。以下はそれらのテーブルです:

;;; Commentary:

これはライブラリーが機能する方法を説明する、概論コメントを開始する。これは複製許諾の直後にあり‘Change Log’、‘History’、‘Code’のコメント行で終端されていること。このテキストはFinderパッケージで使用されるのでそのコンテキスト内で有意であること。

;;; Change Log:

これは時間とともにそのファイルに加えられたオプションの変更ログを開始する。このセクションに過剰な情報を配置してはならない。(Emacsが行うように)バージョンコントロールシステムの詳細ログや個別のChangeLogファイルに留めるほうがよい。‘History’は‘Change Log’の代替え。

;;; Code:

これはプログラムの実際のコードを開始する。

;;; filename ends here

これはフッター行(footer line)。これはそのファイルの終端にある。これの目的はフッター行の欠落から、人がファイルの切り詰められたバージョンを検知することを可能にする。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Appendix E GNU Emacsの内部

このチャプターでは実行可能なEmacs実行可能形式を事前ロードされたLispライブラリーとともにダンプする方法、ストレージが割り当てられる方法、およびCプログラマーが興味をもつかもしれないGNU Emacsの内部的な側面のいくつかを説明します。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.1 Emacsのビルド

このセクションではEmacs実行可能形式のビルドに関するステップの説明をします。makefileがこれらすべてを自動的に行うので、Emacsをビルドやインストールをするためにこの題材を知る必要はありません。この情報はEmacs開発者に適しています。

EmacsのビルドにはGNU Makeのバージョン3.81以降が必要です。

srcディレクトリー内のCソースファイルをコンパイルすることにより、temacsと呼ばれる実行可能形式ファイルが生成されます。これはbare impure Emacs(裸で不純なEmacs)とも呼ばれます。これにはEmacs LispインタープリターとI/Oルーチンが含まれますが編集コマンドは含まれません。

コマンドtemacs -l loaduptemacsを実行してloadup.elをロードするように計らいます。loadupライブラリーは通常のEmacs編集環境をセットアップする追加のLispライブラリーをロードします。このステップの後にはEmacs実行可能形式はbare(裸)ではなくなります。

標準的なLispファイルのロードには若干の時間を要するので、ユーザーが直接temacs実行可能形式を実行することは通常はありません。そのかわり、Emacsビルドの最終ステップの1つとしてコマンド‘temacs -batch -l loadup --temacs=dump-methodが実行されます。特別なオプション--temacstemacsにたいして、この後に続けてEmacsを実行した際に開始がより高速になるように、標準のすべての事前ロードされるLispの関数と変数の記録方法を指示します。オプション--temacsには引数dump-methodが必要であり、以下のいずれかを指定できます:

pdump

ダンプファイル(dump file)に事前ロードLispデータを記録する。このメソッドはEmacsの開始時にロードされることになる追加データファイルを生成する。生成されたダンプファイルは通常はemacs.pdmpと呼ばれて、Emacsのexec-directoryにインストールされる(ヘルプ関数を参照)。これはモダンなシステムにおいてセキュリティとプライバシーを強化するために使用されるさまざまなメモリーレイアウト技術を妨害する可能性のある、メモリー割り当ての特別なテクニックの使用をEmacsに要求しないので、もっとも好ましいメソッドの1つ。

pbootstrap

pdump’と同様だが、以前のEmacsバイナリおよびバイトコンパイル済みLispファイル*.elcが存在しないときに、Emacsのブートストラップ(bootstrapping)の間に使用される。この場合には、生成されるダンプファイルは通常はbootstrap-emacs.pdmp

dump

このメソッドはすべての標準Lispファイルがすでに事前ロード済みのemacsという実行可能プログラムをtemacsにダンプさせる(‘-batch’引数はtemacsにその端末上のすべてのデータ初期化の試みを抑制するので、ダンプされたEmacsの端末情報テーブルは空になる)。このメソッドは実行中プロセスからプログラムファイルを生成するため、プログラムを実行(exec)してプロセスを開始することとある意味で反対なことからunexecとして知られている。このメソッドは伝統的にEmacsの状態を保存する手段だったが、今や非推奨となった。

bootstrap

dump’と同様だが、unexecメソッドでEmacsをブートストラップする際に使用する。

インストールされるEmacsは、ダンプされたemacs実行可能形式です(pureなEmacsとも呼ばれる)。Emacsのビルドにポータブルダンパーを使用した場合には、emacs実行可能形式は実際にはtemacsの正確なコピーであり、対応機種emacs.pdmpファイルも同様にインストールされます。変数preloaded-file-listにはダンプファイルやダンプされたEmacs実行可能形式に記録された事前ロード済みLispファイルのリストが格納されます。新たなオペレーティングシステムにEmacsをポートする際に、そのOSが何の種類のダンプも実装していなければEmacsは起動時に毎回loadup.elをロードしなければなりません。

ダンプされたemacsにはデフォルトではビルド時刻やホスト名のような詳細が記録されます。これらの詳細を抑制するためにconfigureのオプションに--disable-build-detailsを使用すれば、同一のソースからEmacsを2回ビルドしてインストールする際に同一のEmacsのコピーが生成される可能性が高くなります。

site-load.elという名前のライブラリーを記述することにより、事前ロードするファイルを追加指定できます。追加するファイルを保持するために純粋(pure)なスペースnバイトを追加するように、以下の定義

#define SITELOAD_PURESIZE_EXTRA n

でEmacsをリビルドする必要があるでしょう。src/puresize.hを参考にしてください(十分大きくなるまで20000ずつ増加させる)。しかし追加ファイルの事前ロードの優位はマシンの高速化により減少します。現代的なマシンでは通常はお勧めしません。

loadup.elsite-load.elを読み込んだ後にSnarf-documentationを呼び出すことにより、それらが格納された場所のファイルetc/DOC内にあるプリミティブと事前ロードされる関数(と変数)のドキュメント文字列を探します(Accessing Documentationを参照)。

site-init.elという名前のライブラリー名に配置することにより、ダンプ直前に実行する他のLisp式を指定できます。このファイルはドキュメント文字列を見つけた後に実行されます。

関数や変数の定義を事前ロードしたい場合には、それを行うために3つの方法があります。それらにより定義ロードしてその後のEmacs実行時にドキュメント文字列をアクセス可能にします:

  • etc/DOCの生成時にそれらのファイルをスキャンするよう計らいsite-load.elでロードする。
  • ファイルをsite-init.elでロードしてEmacsインストール時にLispファイルのインストール先ディレクトリーにファイルをコピーする。
  • それらの各ファイルでローカル変数としてbyte-compile-dynamic-docstringsnil値を指定してsite-load.elsite-init.elでロードする(この手法にはEmacsが毎回そのドキュメント文字列用のスペースを確保するという欠点がある)。

通常の未変更のEmacsでユーザーが期待する何らかの機能を変更するような何かをsite-load.elsite-init.el内に配置することはお勧めしません。あなたのサイトで通常の機能をオーバーライドしなければならないと感じた場合には、default.elでそれを行えばユーザーが望む場合にあなたの変更をオーバーライドできます。要約: スタートアップ時のアクション順序を参照してください。site-load.elsite-init.elのいずれかがload-pathを変更する場合には変更はダンプ後に失われます。ライブラリー検索を参照してください。load-pathを永続的に変更するにはconfigure--enable-locallisppathオプションを指定してください。

事前ロード可能なパッケージでは、その後のEmacsスタートアップまで特定の評価の遅延が必要(または便利)なことがあります。そのようなケースの大半はカスタマイズ可能な変数の値に関するものです。たとえばtutorial-directoryは事前ロードされるstartup.el内で定義される変数です。これのデフォルト値はdata-directoryにもとづいてセットされます。この変数はEmacsダンプ時ではなくスタート時にdata-directoryの値を必要とします。なぜならEmacs実行可能形式はダンプされたものなので、恐らく異なる場所にインストールされるからです。

Function: custom-initialize-delay symbol value

この関数は次回のEmacs開始までsymbolの初期化を遅延する。通常はカスタマイズ可能変数の:initializeプロパティとしてこの関数を指定することにより使用する(引数valueはフォームCustom由来の互換性のためだけに提供されており使用しない)。

custom-initialize-delayが提供するより一般的な機能を要する稀なケースではbefore-init-hookを使用できます(要約: スタートアップ時のアクション順序を参照)。

Function: dump-emacs-portable to-file &optional track-referrers

この関数はpdumpメソッドを使用して、Emacsのカレント状態をダンプファイルto-fileにダンプする。ダンプファイルは通常はemacs-name.dmpと呼ばれる。ここでemacs-nameはEmacsの実行可能形式ファイル名。オプション引数track-referrersが非nilなら、ポータブルダンパーはpdumpメソッドでは未サポートのオブジェクトタイプの出所追跡の助けとなる追加情報を維持する。

多くのプラットフォームでポータブルダンパーのコードが実行可能だとしても、それが生成するダンプファイルに可搬性はない(ダンプしたEmacs実行可能形式だけがロードできる)。

すでにダンプ済みのEmacs内でこの関数を使用する場合には‘-batch’オプションでEmacsを実行しなければならない。

ダンプ済みのEmacsに‘.el’ファイルが含まれていて、かつその‘.el’ファイルには通常はロード時に実行されるコードがある場合には、ダンプ後にEmacsを起動する際にそのコードは実行されないだろう。この問題を回避するために、after-pdump-load-hookフックに関数を配置することができる。このフックはEmacs起動時に実行される。

Function: dump-emacs to-file from-file

この関数はunexecメソッドを使用して、Emacsのカレント状態を実行可能ファイルto-fileにダンプする。これはfrom-file (通常はファイルtemacs)からシンボルを取得する。

この関数をすでにダンプ済みのEmacsで使用することはできない。この関数は非推奨であり、Emacsはデフォルトではunexecサポートなしでビルドされているので利用できない。

Function: pdumper-stats

カレントのEmacsセッションの状態がダンプファイルからリストアされると、この関数はダンプファイルに関する情報とEmacs状態のリストアに要した時間をリターンする。値は((dumped-with-pdumper . t) (load-time . time)  (dump-file-name . file))のようなalist。ここでfileはダンプファイル名、timeはダンプファイルから状態をリストアするのに要した秒数。カレントセッションがダンプファイルからリストアされたものでなければ値はnil


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.2 純粋ストレージ

Emacs Lispはユーザー作成Lispオブジェクトにたいして、通常ストレージ(normal storage)純粋ストレージ(pure storage)という2種のストレージをもちます。通常ストレージはEmacsセッションが維持される間に新たにデータが作成される場所です。純粋ストレージは事前ロードされた標準Lispファイル内の特定のデータのために使用されます。このデータは実際のEmacs使用中に決して変更されるべきではないデータです。

純粋ストレージはtemacsが標準的な事前ローLispライブラリーのロード中にのみ割り当てられます。ファイルemacsではこのメモリースペースは読み取り専用とマークされるのでマシン上で実行中のすべてのEmacsジョブで共有できます。純粋ストレージは拡張できません。Emacsのコンパイル時に固定された量が割り当てられて、それが事前ロードされるライブラリーにたいして不足ならtemacsはそれに収まらない部分を動的メモリーに割り当てます。Emacsをpdumpメソッド(Emacsのビルドを参照)を使用してダンプする場合には純粋ストレージのオーバーフローは特に重要ではありません(単に事前ロード済みのライブラリーのいくつかが別のEmacsジョブで共有できないことを意味する)。しかしEmacsを時代遅れとなったunexecメソッドでダンプする場合には結果イメージは動作するでしょうが、この状況ではメモリーリークとなるのでガーベージコレクション(ガーベージコレクションを参照)は無効です。そのような通常なら発生しないオーバーフローは、あなたが事前ロードライブラリの追加や標準的な事前ロードライブラリに追加を試みないかぎり発生しません。Emacsがunexecを使用してダンプされていたら、Emacsは開始時にオーバーフローに関する警告を表示するでしょう。これが発生したらファイルsrc/puresize.h内のコンパイルパラメーターをSYSTEM_PURESIZE_EXTRAを増やしてEmacsをリビルドする必要があります。

Function: purecopy object

この関数は純粋ストレージにobjectのコピーを作成してリターンする。これは同じ文字で新たに文字列を作成することにより文字列をコピーするが、純粋ストレージではテキストプロパティはない。これはベクターとコンスセルのコンテンツを再帰的にコピーする。シンボルのような他のオブジェクトのコピーは作成しないが未変更でリターンする。マーカーのコピーを試みるとエラーをシグナルする。

この関数はEmacsのビルド中とダンプ中を除き何もしない。通常は事前ロードされるLispファイル内でのみ呼び出される。

Variable: pure-bytes-used

この変数の値は、これまでに割り当てられた純粋ストレージのバイト数。ダンプされたEmacsでは通常は利用可能な純粋ストレージの総量とほとんど同じであり、もしそうでないならわたしたちは事前割り当てをもっと少なくするだろう。

Variable: purify-flag

この変数はdefunが純粋ストレージにその関数定義のコピーを作成するべきか否かを判断する。これが非nilならその関数の定義は純粋ストレージにコピーされる。

このフラグはEmacsのビルド用の基本的な関数の初回ロード中はtとなる。実行可能形式としてEmacsをダンプすることにより、ダンプ前後の実際の値とは無関係に常にこの変数にnilが書き込まれる。

実行中のEmacsでこのフラグを変更しないこと。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.3 ガーベージコレクション

プログラムがリストを作成するときや、(ライブライのロード等により)ユーザーが新しい関数を定義する際には、そのデータは通常ストレージに配置されます。通常ストレージが少なくなるとEmacsはもっとメモリーを割り当てるようにオペレーティングシステムに要求します。シンボル、コンスセル、小さいベクター、マーカー等のような別のタイプのLispオブジェクトはメモリー内の個別のブロックに隔離されます(大きいベクター、長い文字列、バッファー、および他の特定の編集タイプは非常に巨大であり1つのオブジェクトにたいして個別のブロックが割り当てられて、小さな文字列は8kバイトのブロック、小さいベクターは4kバイトのブロックにパックされる)。

基本的なベクター以上のマーカー、オーバーレイ、バッファーのような多くのオブジェクトが、あたかもベクターであるかのように管理されています。対応するCデータ構造体にはunion vectorlike_headerフィールドが含まれ、そのメンバーsizeにはenum pvec_typeで列挙されたサブタイプ、その構造体が含むLisp_Objectフィールドの数に関する情報、および残りのデータのサイズが含まれます。この情報は、オブジェクトのメモリーフットプリントの計算に必要であり、ベクターブロックの繰り返し処理の際のベクター割り当てコードにより使用されます。

しばらくの間いくつかのストレージを使用して、(たとえば)バッファーのkillやあるオブジェクトを指す最後のポインターの削除によりそれを解放するのは非常に一般的です。この放棄されたストレージを再利用するためにEmacsはガーベージコレクター(garbage collector)を提供します。ガーベージコレクターは本質的には、いまだにLispプログラムからアクセス可能なすべてのLispオブジェクトを検索、マークすることにより動作します。これを開始するにはすべてのシンボル、それらの値と関連付けられている関数定義、現在スタック上にあるすべてのデータをアクセス可能であると仮定します。別のアクセス可能オブジェクトを介して間接的に到達できるすべてのオブジェクトもアクセス可能とみなされますが計算は“保守的”に行われるので、アクセス可能なオブジェクトの個数はいくらか過大に評価されるかもしれません。 accessible, but this calculation is done , so it may slightly overestimate how many objects that are accessible.

マーキングが終了してもマークされないオブジェクトはすべてガーベージ(garbage: ごみ)です。Lispプログラムかユーザーの行為かに関わらず、それらに到達する手段はもはや存在しないので参照することは不可能です。誰もそれを失うことはないので、それらのスペースは再利用されることになります。ガーベージコレクターの2つ目ののフェーズ(sweep: スイープ、一掃)ではそれらの再利用を計らいます(がマーキングは“保守的”に行われるのですべてのスイープが一度ですべての未使用オブジェクトをガーベージコレクトする保証はない)。

スイープフェーズは将来の割り当て用に、シンボルやマーカーと同様に未使用のコンスセルをフリーリスト(free list)上に配置します。これはアクセス可能な文字列は少数の8kブロックを占有するように圧縮して、その後に他の8kブロックを解放します。ベクターブロックから到達不可能はベクターは可能なかぎり最大のフリーエリアを作成するために統合して、フリーエリアが完全な4kブロックに跨がるようならブロックは解放されます。それ以外ならフリーエリアはフリーリスト配列に記録されます。これは各エントリーが同サイズのエリアのフリーリストに対応します。巨大なベクター、バッファー、その他の巨大なオブジェクトは個別に割り当てと解放が行われます。

Common Lispに関する注意: 他のLispと異なりGNU Emacs Lispはフリーリストが空のときにガーベージコレクターを呼び出さない。かわりに単にオペレーティングシステムに更なるストレージの割り当てを要求して、gc-cons-thresholdバイトを使い切るまで処理を継続する。

これは特定のLispプログラムの範囲の実行直前に明示的にガーベージコレクターを呼び出せば、その範囲の実行中はガーベージコレクターが実行されないだろうと確信できることを意味する(そのプログラム範囲が2回目のガーベージコレクションを強制するほど多くのスペースを使用しないという前提)。

Command: garbage-collect

このコマンドはガーベージコレクションを実行して使用中のスペース量の情報をリターンする(前回のガーベージコレクション以降にgc-cons-thresholdバイトより多いLispデータを使用した場合には自然にガーベージコレクションが発生することもあり得る)。

garbage-collectは使用中のスペース量の情報をリストでリターンする。これの各エントリーは‘(name size used)’という形式をもつ。このエントリーでnameはそのエントリーが対応するオブジェクトの種類を記述するシンボル、sizeはそれが使用するバイト数、usedはヒープ内で生きていることが解ったオブジェクトの数、オプションのfreeは生きていないがEmacsが将来の割り当て用に保持しているオブジェクトの数。全体的な結果は以下のようになる:

((conses cons-size used-conses free-conses)
 (symbols symbol-size used-symbols free-symbols)
 (strings string-size used-strings free-strings)
 (string-bytes byte-size used-bytes)
 (vectors vector-size used-vectors)
 (vector-slots slot-size used-slots free-slots)
 (floats float-size used-floats free-floats)
 (intervals interval-size used-intervals free-intervals)
 (buffers buffer-size used-buffers)
 (heap unit-size total-size free-size))

以下は例:

(garbage-collect)
      ⇒ ((conses 16 49126 8058) (symbols 48 14607 0)
                 (strings 32 2942 2607)
                 (string-bytes 1 78607) (vectors 16 7247)
                 (vector-slots 8 341609 29474) (floats 8 71 102)
                 (intervals 56 27 26) (buffers 944 8)
                 (heap 1024 11715 2678))

以下は各要素を説明するためのテーブル。最後のheapエントリーはオプションであり、背景にあるmalloc実装がmallinfo関数を提供する場合のみ与えられることに注意。

cons-size

コンスセルの内部的サイズ(sizeof (struct Lisp_Cons))。

used-conses

使用中のコンスセルの数。

free-conses

オペレーティングシステムから取得したスペースにあるがカレントで未使用のコンスセルの数。

symbol-size

シンボルの内部的サイズ(sizeof (struct Lisp_Symbol))。

used-symbols

使用中のシンボルの数。

free-symbols

オペレーティングシステムから取得したスペースにあるがカレントで未使用のシンボルの数。

string-size

文字列ヘッダーの内部的サイズ(sizeof (struct Lisp_String))。

used-strings

使用中の文字列ヘッダーの数。

free-strings

オペレーティングシステムから取得したスペースにあるがカレントで未使用の文字列ヘッダーの数。

byte-size

これは利便性のために使用されるものでsizeof (char)と同じ。

used-bytes

すべての文字列データの総バイト数。

vector-size

長さ1のベクターのヘッダーを含めたバイトサイズ。

used-vectors

ベクターブロックから割り当てられたベクターブロック数。

slot-size

ベクタースロットの内部的なサイズで常にsizeof (Lisp_Object)と等しい。

used-slots

全使用済みベクターのスロット数。スロット数にはプラットフォームに応じてベクターのヘッダーに由来する一部、またはすべてのオーバーヘッドが含まれるかもしれない。

free-slots

すべてのベクターブロックのフリースロットの数。

float-size

浮動小数点数オブジェクトの内部的なサイズ(sizeof (struct Lisp_Float))。(ネイティブプラットフォームのfloatdoubleと混同しないこと。)

used-floats

使用中の浮動小数点数の数。

free-floats

オペレーティングシステムから取得したスペースにあるがカレントで未使用の浮動小数点数の数。

interval-size

インターバルオブジェクト(interval object)の内部的なサイズ(sizeof (struct interval))。

used-intervals

使用中のインターバルの数。

free-intervals

オペレーティングシステムから取得したスペースにあるがカレントで未使用のインターバルの数。

buffer-size

バッファーの内部的なサイズ(sizeof (struct buffer))。(buffer-size関数がリターンする値と混同しないこと。)

used-buffers

使用中のバッファーオブジェクトの数。これにはユーザーからは不可視のkillされたバッファー、つまりリストall_buffers内のバッファーすべてが含まれる。

unit-size

ヒープスペースを計る単位であり常に1024バイトと等しい。

total-size

unit-size単位での総ヒープサイズ。

free-size

unit-size単位でのカレントで未使用のヒープスペース。

純粋スペース(純粋ストレージを参照)内にオーバーフローがあり、かつEmacsが(時代遅れとなった)unexecメソッド(Emacsのビルドを参照)を使用してダンプされていたら、この場合は実際にガーベージコレクションを行うことは不可能なのでgarbage-collectnilをリターンする。

User Option: garbage-collection-messages

この変数が非nilならEmacsはガーベージコレクションの最初と最後にメッセージを表示する。デフォルト値はnil

Variable: post-gc-hook

これはガーベージコレクションの終わりに実行されるノーマルフック。ガーベージコレクションはこのフックの関数の実行中は抑制されるので慎重に記述すること。

User Option: gc-cons-threshold

この変数の値は別のガーベージコレクションをトリガーするために、ガーベージコレクション後にLispオブジェクト用に割り当てなければならないストレージのバイト数。特定のオブジェクトタイプに関する情報を取得するために、garbage-collectがリターンした結果を使用できる。バッファーのコンテンツに割り当てられたスペースは勘定に入らない。

threshold(しきい値)の初期値はGC_DEFAULT_THRESHOLDであり、これはalloc.c内で定義されている。これはword_size単位で定義されているので、デフォルトの32ビット設定では400,000、64ビット設定では800,000になる。大きい値を指定するとガーベージコレクションの頻度が下る。これはガーベージコレクションにより費やされる時間を減少させる(のでガーベージコレクションが滅多に発生しないサイクル間ではLispプログラムは高速に実行されるだろう)が、メモリーの総使用量は増大する。大量のLispデータを作成するプログラムにおいて、特に高速な実行を要する場合にはこれを行いたいと思うかもしれない。ただしわたしたちは長期間に渡るthresholdの増加は推奨しないし、満足できる速さでプログラムが実行できる以上にの値には決してセットしないことをお勧める。必要以上に大きいthresholdを用いることによってシステムレベルでメモリーが逼迫する可能性があること、更にガーベージコレクションの各サイクルにより時間を要することにもなるので避けるべきである。

GC_DEFAULT_THRESHOLDの1/10まで下げた小さな値を指定することにより、より頻繁にガーベージコレクションを発生させることができる。この最小値より小さい値は後続のガーベージコレクションで、garbage-collectがthresholdを最小値に戻すときまでしか効果をもたないだろう。

User Option: gc-cons-percentage

この変数の値はガーベージコレクション発生するまでのコンス(訳注: これはgc-cons-thresholdgc-cons-percentageの‘-cons-’のことで、これらの変数が定義されているalloc.c内ではLisp方言での‘cons’をより一般化したメモリー割り当てプロセスのことを指す模様)の量をカレントヒープサイズにたいする割り合いで指定する。この条件とgc-cons-thresholdを並行して適用して、条件が両方満足されたときだけガーベージコレクションが発生する。

ヒープサイズ増加にともないガーベージコレクションの処理時間は増大する。したがってガーベージコレクションの頻度割合を減らすのが望ましいことがある。

gc-cons-thresholdと同じように必要以上に増加させず、長期間増加したままにしないこと。

gc-cons-thresholdおよびgc-cons-percentageを介した制御は単なる近似です。たとえEmacsが定期的にしきい値(threshold)の枯渇をチェックしていても、効率上の理由によりヒープ、またはgc-cons-thresholdgc-cons-percentageの変更のそれぞれにたいして、その後即座にガーベージコレクターをトリガーする訳ではありません。更にしきい値計算の効率化のために、Emacsはヒープ内のカレントでアクセス可能なオブジェクトを計数してヒープサイズを近似します。

garbage-collectがリターンする値はデータ型に分類されたLispデータのメモリー使用量を記述します。それとは対照的に関数memory-limitはEmacsがカレントで使用中の総メモリー量の情報を提供します。

Function: memory-limit

この関数はEmacsがカレントで使用中の仮想メモリーの総バイト数を1024で除してリターンする。あるアクションがメモリー使用にどのよな効果を及ぼすかについて概観を得るためにこの関数を使用できる。

Variable: memory-full

この変数はLispオブジェクト用のメモリーが不足に近い状態ならt、それ以外ならnil

Function: memory-use-counts

これはそのEmacsセッションで作成されたオブジェクト数をカウントしたリスト。これらのカウンターはそれぞれ特定の種類のオブジェクトを数える。詳細はドキュメント文字列を参照のこと。

Function: memory-info

この関数はシステムメモリーのトータル量とフリーな量をリターンする。サポートされないシステムでは値はnilかもしれない。

default-directoryがリモートホスト上を指している場合には、そのホストのメモリー情報がリターンされる。

Variable: gcs-done

この変数はそのEmacsセッションでそれまでに行われたガーベージコレクションの合計回数。

Variable: gc-elapsed

この変数はそのEmacsセッションでガーベージコレクションの間に費やされた経過時間を浮動小数点数で表した総秒数。

Function: memory-report

Emacsがどこでメモリーを使用(種々の変数、バッファー、キャッシュ)しているかが確認できれば便利なときがあるかもしれない。このコマンドはその概要を提供する(‘"*Memory Report*"’という)バッファーを新たにオープンすることに加えて、“最大”のバッファーおよび変数をリストする。

ここでのデータは変数サイズを計算する同質的な方法が究極的に存在しないために近似値である。たとえば2つの変数がデータ構造を共有するかもしれず、その場合には2回カウントされるだろうが、このコマンドは依然としてEmacsが使用する有用なメモリーの高レベル概要を与えるかもしれない。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.4 スタックに割り当てられたオブジェクト

上述のガーベージコレクターはLispプログラムから可視なデータ、同様にLispインタープリターが内部的に使用するほとんどのデータの管理に使用されます。インタプリターのCスタックを使用して一時的に内部オブジェクトを割り当てることが有用なときがあります。割り当てとガーベージコレクターによる解放は、ヒープメモリーよりスタック割り当てを使用するほうが通常は高速なので、これはパフォーマンスの改善の助けになります。これには解放後にそのようなオブジェクトを使用することにより未定義の挙動を引き起こすという欠点があるので、使用においては熟考するとともにGC_CHECK_MARKED_OBJECTS機能(src/alloc.cを参照)を使用して慎重にデバッグするべきです。特にスタックに割り当てられたオブジェクトはユーザーのLispコードからは決して可視にならないようにする必要があります。

現在のことろコンスセルと文字列をこの方法で割り当てできます。これはblock寿命をもつ名前つきLisp_Objectを定義するAUTO_CONSAUTO_STRINGのようなCマクロで実装されています。これらのオブジェクトはガーベージコレクターでは解放されません。かわりにこれらは自動記憶期間(automatic storage duration)をもちます。つまりそれらはすべてローカル変数のように割り当てられて、そのオブジェクトを定義するCブロックの実行の最後に自動的に解放されます。

性能的な理由によりスタックに割り当てられる文字列はASCII文字に限定されており、それらの多くが不変です。つまりそれらにたいしてASETを呼び出すと未定義の挙動を引き起こします。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.5 メモリー使用量

以下の関数と変数はEmacsが行なったメモリー割り当ての総量に関する情報をデータ型ごとに分類して提供します。これらの関数や変数とgarbage-collectがリターンする値との違いに注意してください。garbage-collectはカレントで存在するオブジェクトを計数しますが、以下の関数や変数はすでに解放されたオブジェクトを含めて割り当てのすべての数やサイズを計数します。

Variable: cons-cells-consed

そのEmacsセッションでそれまでに割り当てられたコンスセルの総数。

Variable: floats-consed

そのEmacsセッションでそれまでに割り当てられた浮動小数点数の総数。

Variable: vector-cells-consed

そのEmacsセッションでそれまでに割り当てられたベクターセルの総数。これにはマーカー、オーバーレイのようなベクター様のオブジェクトに加えてユーザーには不可視な特定のオブジェクトが含まれる。

Variable: symbols-consed

そのEmacsセッションでそれまでに割り当てられたシンボルの総数。

Variable: string-chars-consed

そのEmacsセッションでそれまでに割り当てられた文字列の文字の総数。

Variable: intervals-consed

そのEmacsセッションでそれまでに割り当てられたインターバルの総数。

Variable: strings-consed

そのEmacsセッションでそれまでに割り当てられた文字列の総数。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.6 C方言

EmacsのC部分はC99にたいして可搬性があります。‘<stdalign.h>’や‘_Noreturn’のようなC11固有の機能は通常はconfigure時に行われるチェックなしでは使用しておらず、Emacsのビルド手順は必要なら代替えの実装を提供します。無名な構造体や共用体のようないくつかのC11機能はエミュレートが非常に困難なので完全に無視しています。

そう遠くない将来のある時点で基本となるC方言は間違いなくC11に変更されるでしょう。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.7 Emacsプリミティブの記述

LispプリミティブとはCで実装されたLisp関数です。Lispから呼び出せるようにC関数インターフェースの詳細はCのマクロで処理されます。新たなCコードの記述のしかたを真に理解するにはソースを読むのが唯一の方法ですが、ここではいくつかの事項について説明します。

スペシャルフォームの例として以下はeval.corです(通常の関数は同様の一般的な外観をもつ)。

DEFUN ("or", For, Sor, 0, UNEVALLED, 0,
       doc: /* Eval args until one of them yields non-nil,
then return that value.
The remaining args are not evalled at all.
If all args return nil, return nil.
usage: (or CONDITIONS...)  */)
  (Lisp_Object args)
{
  Lisp_Object val = Qnil;

  while (CONSP (args))
    {
      val = eval_sub (XCAR (args));
      if (!NILP (val))
        break;
      args = XCDR (args);
      maybe_quit ();
    }

  return val;
}

ではDEFUNマクロの引数について詳細に説明しましょう。以下はそれらのテンプレートです:

DEFUN (lname, fname, sname, min, max, interactive, doc)
lname

これは関数名として定義するLispシンボル名。上記例ではor

fname

これは関数のC関数名。これはCコードでその関数を呼び出すために使用される名前。名前は慣習として‘F’の後にLisp名をつけて、Lisp名のすべてのダッシュ(‘-’)をアンダースコアに変更する。つまりCコードから呼び出す場合にはForを呼び出す。

sname

これはLispでその関数を表すsubrオブジェクト用にデータ保持のための構造体に使用されるC変数名。この構造体はそのシンボルを作成してそれの定義にsubrオブジェクトを格納する初期化ルーチンでLispシンボル名を伝達する。慣習により常にfnameの‘F’を‘S’に置き換えた名前になる。

min

これは関数が要求する引数の最小個数。関数orは最小で0個の引数を受け入れる。

max

これは関数が受け入れる引数の最大個数が定数なら引数の最大個数。あるいはUNEVALLEDなら未評価の引数を受け取るスペシャルフォーム、MANYなら評価される引数の個数に制限がないことを意味する(&restと等価)。UNEVALLEDMANYはいずれもマクロ。maxが数字ならminより大きく8より小さいこと。

interactive

これはLisp関数でinteractiveの引数として使用されるようなインタラクティブ仕様(文字列)である(interactiveの使用を参照)。orの場合は0 (nullポインター)でありorがインタラクティブに呼び出せないことを示す。値""はインタラクティブに呼び出し時に、関数が引数を受け取るべきではないことを示す。値が‘"(’で始まる場合には、その文字列はLispフォームとして評価される。たとえば:

DEFUN ("foo", Ffoo, Sfoo, 0, 3,
       "(list (read-char-by-name \"Insert character: \")\
              (prefix-numeric-value current-prefix-arg)\
              t)",
       doc: /* … */)
doc

これはドキュメント文字列。複数行を含むために特別なことを要しないので、これにはCの文字列構文ではなくCコメント構文を使用する。‘doc:’の後のコメントはドキュメント文字列として認識される。コメントの開始と終了の区切り文字‘/*’と‘*/’はドキュメント文字列の一部にはならない。

ドキュメント文字列の最後の行がキーワード‘usage:’で始まる場合には、その行の残りの部分は引数リストをドキュメント化するためのものとして扱われる。この方法によりCコード内で使用される引数名とは異なる引数名をドキュメント文字列内で使用することができる。その関数の引数の個数に制限がなければ‘usage:’は必須。

プロットフォームにたいして1つといったように、複数の定義をもつプリミティブがいくつかある(たとえばx-create-frame)。このような場合には各定義に同じドキュメント文字列を記述するよりも、ただ1つの定義が実際のドキュメントをもつようにしたほうがよい。他の定義はDOCファイルをパースする関数から無視される、‘SKIP’で始まるプレースホルダーをもつ。

Lispコードでのドキュメント文字列にたいするすべての通常ルール(ドキュメント文字列のヒントを参照)はCコードのドキュメント文字列にも適用される。

以下のようにドキュメント文字列の後に、そのプリミティブを実装するC関数にたいするC関数属性のリストがあるかもしれない:

DEFUN ("bar", Fbar, Sbar, 0, UNEVALLED, 0
       doc: /* … */
       attributes: attr1 attr2 …)

後に続けることにより複数の属性を指定できる。現在のところ以下の属性が認識される:

noreturn

決してリターンしないC関数を宣言する。これはC11のキーワード_Noreturn、GCCの属性__attribute__ ((__noreturn__))に対応している(Function Attributes in Using the GNU Compiler Collectionを参照)。

const

引数以外の値を検査せず、リターン値以外に影響しない関数を宣言する。これはGCCの属性__attribute__ ((__const__))に対応している。

noinline

これは関数がインラインとみなされることを抑止するGCCの属性__attribute__ ((__noinline__))に対応している。これはたとえばスタックベースの変数にたいするリンク時の最適化の効果を取り消すために必要になるかもしれない。

DEFUNマクロ呼び出しの後には、そのC関数にたいする引数リストを引数のタイプを含めて記述しなければなりません。そのプリミティブがLispで固定された最大個数をもつ引数を受け入れるなら、Lisp引数それぞれにたいして1つのC引数をもち、各引数のタイプはLisp_Objectでなければなりません(ファイルlisp.hではタイプLisp_Objectの値を作成する種々のマクロと関数が宣言されている)。プリミティブがスペシャルフォームなら、評価されないタイプLisp_Objectの単一のLisp引数を含むLispリストを受け取らなければなりません。プリミティブのLispの最大引数個数に上限がない場合には正確に2つのC引数をもたなければなりません。1つ目はLisp引数の個数、2つ目はそれらの値を含むブロックのアドレスです。これらはそれぞれptrdiff_tLisp_Object *のタイプをもちます。Lisp_Objectは任意のデータ型と任意のLispオブジェクトを保持できるので、実行時のみ実際のデータ型を判断できます。特定のタイプの引数だけを受け入れるプリミティブを記述したい場合は、適切な述語を使用してタイプを明確にチェックしなければなりません(型のための述語を参照)。

関数For自体ではローカル変数argsはEmacsのスタックマーキングによるガーベージコレクターが制御するオブジェクトを参照します。ガーベージコレクターはたとえCのLisp_Objectスタック変数から到達可能なオブジェクトを回収しなくても、文字列コンテンツやバッファーのテキストのようなオブジェクトの何らかのコンポーネントを移動するかもしれません。したがってこれらのコンポーネントにアクセスする関数はLispの評価を行なった後に、それらのアドレスの再取得に留意しなければなりません。これはコードが文字列コンテンツやバッファーテキストにたいするCポインターを維持するかわりに、バッファーや文字列の位置を維持して、Lispの評価を行なった後にその位置からCポインターを再計算する必要があることを意味しています。Lisp評価は直接と間接を問わず、eval_subFevalの呼び出しを通じて発生する可能性があります。

ループ内部のmaybe_quit呼び出しに注意してください。この関数はユーザーがC-gを渡したかどうかをチェックして、もしそうなら処理をabortします。多数の繰り返しを要する可能性があるすべてのループ内でこれを行うべきです。この場合には引数のリストは非常に長くなるかもしれません。これはEmacsの応答性とユーザーエクスペリエンスを向上させます。

Emacsが一度ダンプされた後に変数に何か書き込まれているときには、その静的変数やグローバル変数にCの初期化を使用してはなりません。初期化されたこれらの変数はEmacsのダンプの結果として、(特定のオペレーティングシステムでは)読み取り専用となるメモリーエリアに割り当てられます。純粋ストレージを参照してください。

C関数の定義だけではLispプリミティブを利用可能にするのに十分ではありません。そのプリミティブにたいしてLispシンボルを作成して関数セルに適切なsubrオブジェクトを格納しなければなりません。このコードは以下のようになるでしょう:

defsubr (&sname);

ここでsnameDEFUNの3つ目の引数として使用する名前です。

すでにLispプリミティブが定義されたファイルにプリミティブを追加する場合には、(そのファイル終端付近にある)syms_of_somethingという名前の関数を探してdefsubrの呼び出しを追加してください。ファイルにこの関数がない、または新たなファイルを作成する場合にはsyms_of_filename (例: syms_of_myfile)を追加します。それからemacs.cでそれらの関数が呼び出されるすべての箇所を探してsyms_of_filenameの呼び出しを追加してください。

関数syms_of_filenameはLisp変数として可視となるすべてのC変数を定義する場所でもあります。DEFVAR_LISPはタイプLisp_ObjectのC変数をLispから可視にします。DEFVAR_INTはタイプintのC変数を常に整数となる値をもつようにしてLispから可視にします。DEFVAR_BOOLはタイプintのC変数を常にtnilのいずれかとなる値をもつようにしてLispから可視にします。DEFVAR_BOOLで定義された変数はバイトコンパイラーに使用されるリストbyte-boolean-varsに自動的に追加されることに注意してください。

これらのマクロはすべて3つの引数を期待します:

lname

Lispプログラムが使用する変数名。

vname

Cソース内の変数名。

doc

Cコメントとしての変数用のドキュメント。詳細はドキュメントの基礎を参照のこと。

慣例として“ネイティブ”なタイプ(intbool)の変数の定義時には、Cの変数名はLisp変数の-_で置換されます。変数がタイプLisp_Objectをもつ際には、Cの変数名にVも前置します。たとえば

DEFVAR_INT ("my-int-variable", my_int_variable,
           doc: /* An integer variable.  */);

DEFVAR_LISP ("my-lisp-variable", Vmy_lisp_variable,
           doc: /* A Lisp variable.  */);

Lispではシンボルの値ではなくシンボル自身の参照を要する状況が存在します。1つは変数の値の一時的なオーバーライドであり、これはLispではletで行われます。これはCソースでは、specbindを使用して対応する定数シンボルを定義することにより行われます。慣例によりQmy_lisp_variableVmy_lisp_variableに対応します。これを定義するにはDEFSYMマクロを使用します。たとえば

DEFSYM (Qmy_lisp_variable, "my-lisp-variable");

実際にバインディングを行うには:

specbind (Qmy_lisp_variable, Qt);

Lispシンボルではクォートの使用が必要な場合がありますが、Cで同様の効果を達成するためには対応する定数シンボルQmy_lisp_variableを使用します。たとえばLispでバッファーローカル変数(バッファーローカル変数を参照)を作成する際には以下のように記述します:

(make-variable-buffer-local 'my-lisp-variable)

C側の対応するコードは、以下のようにDEFSYMと組み合わせてFmake_variable_buffer_localを使用します。

DEFSYM (Qmy_lisp_variable, "my-lisp-variable");
Fmake_variable_buffer_local (Qmy_lisp_variable);

Cで定義されたLisp変数をdefcustomで宣言された変数のように振る舞わせたい場合には、cus-start.elに適切なエントリーを追加します。使用するフォーマットの説明はカスタマイゼーション変数の定義を参照してください。

タイプLisp_ObjectのファイルをスコープとするC変数を直接定義する場合には、以下のようにsyms_of_filename内でstaticproを呼び出してガーベージコレクションから保護しなければなりません:

staticpro (&variable);

以下はより複雑な引数をもつ別の関数例です。これはwindow.cからのコードであり、Lispオブジェクトを操作するためのマクロと関数の使用を示すものです。

DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
       Scoordinates_in_window_p, 2, 2, 0,
       doc: /* Return non-nil if COORDINATES are in WINDOW.
  …
  or `right-margin' is returned.  */)
  (register Lisp_Object coordinates, Lisp_Object window)
{
  struct window *w;
  struct frame *f;
  int x, y;
  Lisp_Object lx, ly;

  w = decode_live_window (window);
  f = XFRAME (w->frame);
  CHECK_CONS (coordinates);
  lx = Fcar (coordinates);
  ly = Fcdr (coordinates);
  CHECK_NUMBER (lx);
  CHECK_NUMBER (ly);
  x = FRAME_PIXEL_X_FROM_CANON_X (f, lx) + FRAME_INTERNAL_BORDER_WIDTH (f);
  y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly) + FRAME_INTERNAL_BORDER_WIDTH (f);

  switch (coordinates_in_window (w, x, y))
    {
    case ON_NOTHING:            /* NOT in window at all.  */
      return Qnil;
    case ON_MODE_LINE:          /* In mode line of window.  */
      return Qmode_line;
    case ON_SCROLL_BAR:         /* On scroll-bar of window.  */
      /* Historically we are supposed to return nil in this case.  */
      return Qnil;

    default:
      emacs_abort ();
    }
}

CコードはCで記述されていなければ名前で呼び出すことはできないことに注意してください。Lispで記述された関数を呼び出すには関数funcallをCで具現化したFfuncallを使用します。Lisp関数funcallは個数制限なしの引数を受け付けるので、Cでの引数はLispレベルでの引数個数とそれらの値を含む1次元配列という2個の引数になります。Lispレベルでの1つ目の引数は呼び出す関数、残りはそれに渡す引数です。

C関数call0call1call2、...は個数が固定された引数でLisp関数を手軽に呼び出す便利な方法を提供します。これらはFfuncallを呼び出すことにより機能します。

eval.cは例を探すのに適したファイルです。lisp.hには重要なマクロと関数の定義がいくつか含まれています。

副作用がない関数や純粋関数を定義したら、side-effect-freepureのプロパティに非nilを与えてください(シンボルの標準的なプロパティを参照)。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.8 動的にロードされるモジュールの記述

このセクションでがEmacsのモジュールAPI、およびEmacs用の拡張モジュール記述の一部としてそれらを使用する方法について説明します。モジュールAPIはCプログラム言語で定義されているので、このセクション内の記述と例はモジュールがCで記述されていると仮定します。別のプログラム言語ではCコード呼び出しのための適切なバインディングやインターフェースと機能の使用が必要になるでしょう。EmacsのCコードにはC99以降のコンパイラー(C方言を参照)が必要であり、このセクションもこの標準にしたがいます。

モジュールの記述とEmacsへの統合には以下のタスクが含まれます:

  • モジュール用の初期化コードの記述。
  • 1つ以上のモジュール関数の記述。
  • Emacsとモジュール間での値とオブジェクトのやり取り。
  • エラーコンディションと非ローカル脱出のハンドリング。

以下のサクセクションこれらのタスクとAPI自体の詳細を説明します。

モジュールを一度記述したら共有ライブラリーを生成するために、背景のプラットドームの慣習に応じてモジュールをコンパイルします。その後でload-path (ライブラリー検索を参照)に言及されたディレクトリー内(Emacsが共有ライブラリーを探す場所)にそれを配置します。

EmacsダイナミックモジュールAPIにたいしてモジュールの適合性を検証したければ--module-assertionsオプションでEmacsを呼び出します。Initial Options in The GNU Emacs Manualを参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.8.1 モジュールの初期化コード

ヘッダーファイルemacs-module.hのインクルードとGPL互換性シンボル(GPL compatibility symbol)によりモジュールの記述を始めましょう:

#include <emacs-module.h>

int plugin_is_GPL_compatible;

Emacsインストールの一部としてシステムのインクルードツリーにemacs-module.hファイルがインストールされます。かわりにEmacsのソースツリー内で見つけることもできます。

次にモジュール用の初期化関数を記述します。

Function: int emacs_module_init (struct emacs_runtime *runtime)

Emacsはモジュールをロードする際にこの関数を呼び出す。モジュールがemacs_module_initという名前の関数をエクスポートしていなければモジュールはエラーをシグナルする。この初期化関数は初期化成功時には0、それ以外は非0をリターンすること。後者の場合にはEmacsはエラーをシグナルして、モジュールのロードは失敗する。初期化中にユーザーがC-gを押下すると、Emacsは初期化関数のリターン値を無視してquitする(quitを参照)(必要なら初期化関数内でユーザーのquitをcatchできる。should_quitを参照)。

引数runtimeは2つのパブリックなフィールドを含むCのstructへのポインター、sizeはその構造体のバイトサイズ、get_environmentはEmacsの環境オブジェクトとそのインターフェースにモジュール初期化関数をアクセス可能にする関数へのポインターを提供する。

初期化関数はモジュールに必要な初期化は何であれすべて行うこと。さらに以下のタスクを行うことができる:

互換性の検証

モジュールにコンパイルされたruntime構造体のsizeメンバーの値を比較することにより、モジュールをロードするEmacs実行可能形式がモジュールと互換性があるか検証できる。

int
emacs_module_init (struct emacs_runtime *runtime)
{
  if (runtime->size < sizeof (*runtime))
    return 1;
}

モジュールに渡されたruntimeオブジェクトのsizeが期待する値より小さければ、ロードしようとしているモジュールがEmacsの新しい(最近の)バージョン向けにコンパイルされていることを意味する(そのモジュールはEmacsのバイナリーとは非互換かもしれない)。

さらにモジュールは期待しているモジュールAPIの互換性も検証できる。以下の例では上述のemacs_module_init関数の一部であることを仮定している:

  emacs_env *env = runtime->get_environment (runtime);
  if (env->size < sizeof (*env))
    return 2;

これはAPI環境(environment)へのポインターの取得用に構造体runtime (sizeフィールドに構造体のバイトサイズも保有するCstruct )で提供されるポインターを使用してget_environment関数を呼び出す。

最後にEmacsから渡された環境のサイズと既知のサイズを比較することによって、以下のように古いバージョンのEmacsで動作するモジュールを記述できる:

  emacs_env *env = runtime->get_environment (runtime);
  if (env->size >= sizeof (struct emacs_env_26))
    emacs_version = 26;  /* Emacs 26 or later.  */
  else if (env->size >= sizeof (struct emacs_env_25))
    emacs_version = 25;
  else
    return 2; /* Unknown or unsupported version.  */

新しいバージョンのEmacsではメンバーを環境に常に追加して削除は決して行わないので、新たなEmacsのリリースではサイズは増加するだけであることにより機能する。与えられたバージョンのEmacsにたいして、そのバージョンに存在するモジュールAPIは新しいバージョンのものと等しいので、その部分だけを使用できる。

emacs-module.hはプリプロセッサマクロEMACS_MAJOR_VERSIONを定義する。これはヘッダーがサポートするEmacsの最新バージョンとなる整数リテラルに展開される。バージョンの情報を参照のこと。EMACS_MAJOR_VERSIONはコンパイル時の定数であり、モジュールをロードしたカレントで実行中のEmacsのバージョンを表さないことに注意。emacs-module.hやEmacsの種々なバージョンにたいして互換性をもたせたければ、EMACS_MAJOR_VERSIONにもとづいた条件コンパイルを使用できる。

モジュールが処理全体を初期化関数内で行い、Lispオブジェクトにアクセスしたり環境構造体を通じてアクセス可能なEmacs関数を使用することがない場合を除いて、モジュールの互換性検証を常に行うことを推奨する。

Lispシンボルへのモジュール関数のバインド

これはLispコードが名前で呼び出せるようにモジュール関数に名前を与える。これを行う方法については以下のモジュール関数の記述で説明する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.8.2 モジュール関数の記述

Emacsモジュールを記述する主な理由は、そのモジュールをロードしたLispプログラムが追加の関数を利用できるようにするためです。このサブセクションでは、そのようなモジュール関数(module functions)の記述方法を説明します。

モジュール関数は以下のような一般的なフォームとシグネチャをもっています:

Function: emacs_value emacs_function (emacs_env *env, ptrdiff_t nargs, emacs_value *args, void *data)

The env argument provides a pointer to the API environment, needed to access Emacs objects and functions. The nargs argument is the required number of arguments, which can be zero (see make_function below for more flexible specification of the argument number), and args is a pointer to the array of the function arguments. The argument data points to additional data required by the function, which was arranged when make_function (see below) was called to create an Emacs function from emacs_function.

モジュール関数はEmacsとモジュール間でLispオブジェクトをやり取りするためにタイプemacs_valueを使用する(Lisp・モジュール間の値変換を参照)。以下で説明するAPIと以降のサブセクションではCの基本データ型と、それらに対応するemacs_valueオブジェクトの慣習にたいする機能を提供する。

モジュール関数は常に値をリターンする。関数が正常にリターンすると、それに呼び出されたLispコードは関数がリターンしたemacs_value値に対応するLispオブジェクトを目にすることになる。しかしユーザーがC-gをタイプしたり、モジュール関数やその呼び出し先がエラーをシグナルしたり非ローカルなexit (モジュールでの非ローカル脱出を参照)を行なった場合には、Emacsはリターン値を無視してLispコードが同じ状況に遭遇した際のようにquitやthrrowを行う。

ヘッダーemacs-module.hは関数ポインターからモジュール関数へのエイリアス型としてemacs_function型をを提供する。

モジュール関数用のCコード記述後には、そこからmake_functionを使用してLisp関数オブジェクトを作成する必要があります。make_function関数へのポインターは環境内で提供されます(環境へのポインターはget_environmentがリターンすることを思い出してほしい)。これは通常はAPIのモジュール初期化関数(module initialization functionを参照)の内部で互換性検証後に行われます。

Function: emacs_value make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity, emacs_function func, const char *docstring, void *data)

これはC関数funcが作成した上記emacs_functionで説明したシグネチャをもつEmacs関数をリターンする。引数min_aritymax_arityは、funcが受け付ける引数の最大個数と最小個数を指定する。引数max_arityは特別な値emacs_variadic_functionをもつことができる。これはLispの&restキーワードのように、関数の受け付ける引数の個数を無制限にする(引数リストの機能を参照)。

引数datafuncの呼び出し時に任意の追加データを渡すための手段である。make_functionに渡されたポインターが何であれ、それは変更されずにfuncに渡される。

引数docstringはその関数用のドキュメント文字列を指定する。これはASCII文字列かUTF-8にエンコードされた非ASCII文字列、またはNULLポインターのいずれかであること。後者の場合には関数がドキュメントをもたないことを意味する。ドキュメント文字列はadvertised-calling-conventionを指定する行で終端できる。関数のドキュメント文字列を参照のこと。

すべてのモジュール関数は1つ目の引数として環境へのポインターを受け取らなければならないので、make_functionは任意のモジュール関数から呼び出され得るが、モジュールが一度ロードされればすべてのモジュール関数がEmacsに既知となるように、通常はこれをモジュール初期化関数で行うことを望むだろう。

最後にLispコードが関数を名前で呼び出せるようにLisp関数をシンボルにバインドする必要があります。これを行うにはモジュールAPI関数intern (internを参照)を使用します。この関数のポインターもモジュール関数がアクセス可能な環境内で提供されています。

上述のステップを組み合わせて、モジュール初期化関数の中で以下のようにC用にアレンジしたコードmodule_funcが、Lispからmodule-funcとして呼び出し可能になります:

 emacs_env *env = runtime->get_environment (runtime);
 emacs_value func = env->make_function (env, min_arity, max_arity,
                                        module_func, docstring, data);
 emacs_value symbol = env->intern (env, "module-func");
 emacs_value args[] = {symbol, func};
 env->funcall (env, env->intern (env, "defalias"), 2, args);

env->internの呼び出しによりシンボルmodule-funcはEmacsが知ることとなり、それから関数をこのシンボルにバインドするためにEmacsからdefaliasを呼び出します。defaliasのかわりにfsetの使用も可能なことに注意してください。両者の違いはdefaliasに説明があります。

emacs_module_init関数(module initialization functionを参照)を含むモジュール関数は、直接間接を問わずEmacsから呼び出されていれば、何らかの生きたemacs_envポインターによる環境関数呼び出しにより、Emacsだけと対話する可能性があります。言い換えると、モジュール関数によるLisp関数やEmacsプリミティブを呼び出し、emacs_valueとCデータタイプ(Lisp・モジュール間の値変換を参照)の間の変換、あるいは別の方法によるEmacsとの対話を行いたい場合には、Emacsからのemacs_module_initやモジュール関数への呼び出しのいくつかがコールスタック上になければなりません。モジュール関数はガーベージコレクションの間はEmacsと対話しないかもしれません。ガーベージコレクションを参照してください。モジュール関数はEmacsが作成したLispインタープリタースレッド(メインスレッドを含む)とだけ対話するかもしれません。スレッドを参照してください。コマンドラインオプション--module-assertionsは、上記の要件にたいする違反のいくつかを検知できます。Initial Options in The GNU Emacs Manualを参照してください。

モジュールAPIの使用により、より複雑な関数やデータ型(インライン関数、マクロ等)の定義が可能になります。ただしCの結果コードは扱いにくく、可読性も低下します。したがって関数やデータ構造を作成するモジュールコードを可能なかぎり最小限に留めるとともに、残りの部分をモジュールに付属するLispパッケージに付託することを推奨します。なぜならこれらの追加タスクをLispで行うのはより用意であり、より可読性の高いコードが生成されるでしょう。たとえば上記のようにモジュール関数module-funcが定義されていれば、以下のようなシンプルなLispラッパーによってマクロmodule-macroを作成するのも1つの方法です:

(defmacro module-macro (&rest args)
  "Documentation string for the macro."
  (module-func args))

モジュールに同梱されるLispパッケージは、Emacsにパッケージがロードされる際にloadプリミティブ(Emacsのダイナミックモジュールを参照)を使用してモジュールをロードできます。

デフォルトではmake_functionにより作成したモジュール関数は非インタラクティブです。これらをインタラクティブにするために、以下の関数を使用できます。

Function: void make_interactive (emacs_env *env, emacs_value function, emacs_value spec)

このEmacs 28以降で利用可能になった関数はインタラクティブ仕様specを使用して、関数functionをインタラクティブにする。Emacsはspecinteractiveフォームの引数のように解釈する。interactiveの使用interactiveにたいするコード文字を参照のこと。functionmake_functionがリターンするEmacsモジュール関数であること。

モジュール関数のインタラクティブ仕様を取得するためのネイティブなモジュールサポートは存在しないことに注意。これを行うためにはinteractive-formを使用する。interactiveの使用を参照のこと。一度make_interactiveを使用してモジュール関数をインタラクティブにした後に、非インタラクティブにすることはできない。

モジュール関数オブジェクト(例: make_functionがリターンしたオブジェクト)がガーベージコレクトされた際に何らかのコードを実行したい場合には、関数ファイナライザー(function finalizer)をインストールできます。関数ファイナライザーはEmacs 28以降で利用できます。たとえばmake_functiondata引数にヒープ割り当てした構造体を渡した場合には、構造体の割り当て解放にファイナライザーを使用できます。(libc)Basic Allocation(libc)Freeing after Mallocを参照してください。ファイナライザー関数は以下のsignatureをもちます:

void finalizer (void *data)

ここでdatamake_function呼び出し時にdataに渡された値です。ファイナライザーがEmacsと相互作用する手段は何もないことに注意してください。

make_function呼びの直後には、新たに作成された関数はファイナライザーをもちません。ファイナライザーを望む場合には、ファイナライザーを追加するためにset_function_finalizerを使用します。

Function: void emacs_finalizer (void *ptr)

ヘッダーemacs-module.hはEmacsファイナライザー関数にたいするエイリアスタイプとしてタイプemacs_finalizerを提供する。

Function: emacs_finalizer get_function_finalizer (emacs_env *env, emacs_value arg)

このEmacs 28以降で利用可能になった関数は、argにより示されるモジュール関数に関連付けられた関数ファイナライザーをリターンする。argはモジュール関数、すなわちmake_functionがリターンするオブジェクトを参照しなければならない。その関数に関連付けられたファイナライザーがなければ、NULLをリターンする。

Function: void set_function_finalizer (emacs_env *env, emacs_value arg, emacs_finalizer fin)

このEmacs 28以降で利用可能になった関数は、argで示されるモジュール関数に関連付けられる関数ファイナライザーにfinをセットする。argはモジュール関数、すなわちmake_functionがリターンするオブジェクトを参照しなければならない。finにはargの関数ファイナライザーをクリアーするNULL、あるいはargにより示されるオブジェクトのガーベージコレクト時に呼び出される関数へのポインターを指定できる。関数ごとに最大で1つの関数ファイナライザーをセットできる。argがすでにファイナライザーを所有する場合にはfinで置き換えられる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.8.3 Lisp・モジュール間の値変換

非常に少数の例外を除くほとんどのモジュールでは、モジュールを呼び出すLispプログラムとの間でモジュール関数への引数やリターン値の受け渡しでデータのやり取りが必要になります。この目的にたいしてモジュールAPIemacs_valueタイプを提供しています。これはAPIを通じたやり取りにおいてEmacsのLispオブジェクトを表現するタイプであり、EmacsのCプリミティブ(Emacsプリミティブの記述を参照)で使用されるLisp_Objectタイプと機能的には等価です。このセクションではLispの基本データ型に対応するemacs_valueオブジェクトの作成を可能とするモジュールAPIの部分と、Lispオブジェクトに対応するemacs_valueオブジェクト内のCデータへのアクセス方法について説明します。

以下で説明するすべての関数は、実際にはすべてのモジュール関数が受け取る環境へのポインターを介して提供される関数ポインター(function pointers)です。したがってモジュールのコードでは以下のように環境ポインターを通じてこれらの関数を呼び出す必要があります:

emacs_env *env;  /* the environment pointer */
env->some_function (arguments…);

emacs_envポインターは通常はモジュール関数の1つ目の引数、モジュール初期化関数内で環境が必要な場合にはget_environmentの呼び出しから取得できます。

以下で説明するもののほとんどはEmacs 25で利用可能になった関数であり、Emacs 25はダイナミックモジュールを最初にサポートした最初のEmacsリリースです。それ以降のリリースで利用可能になったいくつかの関数につていは、それらをサポートする最初のEmacsバージョンを付記します。

以下のAPI関数はemacs_valueオブジェクトから種々のCデータ型を抽出します。これらすべては引数のemacs_valueオブジェクトがその関数の期待するタイプでなければ、エラーコンディションwrong-type-argumentをraiseします(型のための述語を参照)。Emacsモジュール内でエラーをシグナルする方法、およびEmacsにエラーが報告される前にモジュール内部でエラーコンディションをcatchする方法の詳細はモジュールでの非ローカル脱出を参照してください。emacs_valueのタイプ取得にはAPI関数type_ofを使用できます(type_ofを参照)。

Function: intmax_t extract_integer (emacs_env *env, emacs_value arg)

この関数はargで指定されたLisp整数の値をリターンする。リターン値のCデータ型intmax_tはCコンパイラーがサポートする最大の整数型であり、一般的にはlong longargの値がintmax_tに収まらなければ、関数はエラーシンボルoverflow-errorを使用してエラーをシグナルする。

Function: bool extract_big_integer (emacs_env *env, emacs_value arg, int *sign, ptrdiff_t *count, emacs_limb_t *magnitude)

このEmacs 27から利用可能になった関数は、argの整数値を抽出する。argの値は整数(fixnumかbignum)でなければならない。signNULL以外なら、argの符号(-1、0、+1)を*signに格納する。マグニチュード(magnitude: 大きさ)は次のようにmagnitudeに格納される。countmagnitudeがいずれも非NULLなら、magnitudeは少なくとも*count unsigned long要素の配列を指さなければならない。magnitudeargのマグニチュードを保持するのに十分大きければ、この関数はmagnitude配列にリトルエンディアン形式でマグニチュードを書き込み、配列の要素数を*countに格納してtrueをリターンする。magnitudeの大きさが十分でなければ、必要な配列サイズを*countに格納,エラーをシグナルしてfalseをリターンする。countが非NULLかつmagnitudeNULLなら、必要となる配列サイズを*countに格納してtrueをリターンする。

Emacsは*countに要求される最大値がmin (PTRDIFF_MAX, SIZE_MAX) / sizeof (emacs_limb_t)を超えないことを保証するので、magnitude配列の割り当てではサイズ計算で整数のオーバーフローを心配せずにmalloc (*count * sizeof *magnitude)を使用できる。

Type alias: emacs_limb_t

これは大きい整数向け変換関数のマグニチュード配列の要素タイプとして使用される符号なし整数タイプ。このタイプは一意なオブジェクト表現をもつ(パディングビットがない)ことが保証されている。

Macro: EMACS_LIMB_MAX

これはemacs_limb_tにたいして可能な最大値を指定する定数式に展開されるマクロ。この式は#if内での利用に適する。

Function: double extract_float (emacs_env *env, emacs_value arg)

この関数はargで指定されたLisp浮動小数の値をCのdouble値としてリターンする。

Function: struct timespec extract_time (emacs_env *env, emacs_value arg)

このEmacs 27から利用可能になった関数はargをEmacs Lispのtime値として解釈して、それに対応するstruct timespecをリターンする。時刻を参照のこと。struct timespecはナノ秒の精度のタイムスタンプを表す。以下のメンバーをもつ:

time_t tv_sec

整数秒。

long tv_nsec

ナノ秒としての小数秒数。extract_timeがリターンするタイムスタンプでは常に非負かつ十億未満(tv_nsecのタイプがlongであることをPOSIXがが要求しているとしても、非標準的なプラットフォームではlong longである)。

(libc)Elapsed Timeを参照のこと。

timeがナノ秒より高い精度をもつ場合には、この関数はナノ秒の精度へ負の無限大方向に切り詰める。struct timespecが(ナノ秒に切り詰めた)timeを表現できなければ、この関数はエラーをシグナルする。たとえばtime_tが32ビット整数タイプなら100億秒というtime値はエラーをシグナルするが、600ピコ秒のtime値は0に切り詰められるだろう。

struct timespecで表現できないtime値を処理する必要があったり、より高い精度が必要ならLisp関数encode-timeを呼び出してリターン値を処理すればよい。時刻の変換を参照のこと。

Function: bool copy_string_contents (emacs_env *env, emacs_value arg, char *buf, ptrdiff_t *len)

これはargで指定されたLisp文字列をUTF-8にエンコードしたテキストをbufが指すchar配列に格納する。bufは少なくとも終端のnullバイトを含む*lenバイトを保持するために十分なスペースをもつこと。引数lenNULLポインターであってはならない。この関数の呼び出し時にはbufのバイトサイズを指定する値を指していること。

*lenで指定されたバッファーサイズが文字列のテキストを保持するために十分大きければ、関数は終端のnullバイト含む実際にコピーされる*lenバイトをbufにコピーしてtrueをリターンする。バッファーが小さすぎる場合には、関数はエラーコンディションargs-out-of-rangeをraiseするとともに、必要なバイト数を*lenに格納してfalseをリターンする。保留中のエラーコンディションのハンドル方法はモジュールでの非ローカル脱出を参照のこと。

引数bufNULLポインターでもよく、この場合には関数はargのコンテンツの格納に必要なバイト数を*lenに格納してtrueをリターンする。これは特定の文字列を格納するために必要なbufサイズを決定する手段となり得る。1回目はbufNULLcopy_string_contentsを呼び出して、関数により*lenに格納されたバイト数の保持に十分なメモリーを割り当ててから、実際にテキストのコピーを行うために非NULLbufで関数を再び呼び出す。

Function: emacs_value vec_get (emacs_env *env, emacs_value vector, ptrdiff_t index)

この関数はvectorindexの要素をリターンする。ベクターの最初の要素のindexは0。indexの値が無効ならこの関数はエラーコンディションargs-out-of-rangeをraiseする。関数のリターン値からCデータを抽出するためには、ベクターの当該要素に格納されたLispデータタイプに応じて、ここで説明している他の抽出関数を使用すればよい。

Function: ptrdiff_t vec_size (emacs_env *env, emacs_value vector)

この関数はvector内の要素数をリターンする。

Function: void vec_set (emacs_env *env, emacs_value vector, ptrdiff_t index, emacs_value value)

この関数はvectorのインデックスindexの要素にvalueを格納する。indexの値が無効ならこの関数はエラーコンディションargs-out-of-rangeをraiseする。

以下はCの基本データ型からemacs_valueオブジェクトを作成するAPI関数です。これらはすべて作成したemacs_valueオブジェクトをリターンします。

Function: emacs_value make_integer (emacs_env *env, intmax_t n)

この関数は引数n (整数)を受け取り対応するemacs_valueオブジェクトをリターンする。nの値がmost-negative-fixnummost-positive-fixnumの内外いずれであるかに応じてfixnumかbignumのいずれかをリターンする(整数の基礎を参照)。nの値をEmacs整数で表現できない、すなわちmost-negative-fixnummost-positive-fixnumの範囲外(整数の基礎を参照)ならエラーコンディションoverflow-errorをraiseする。

Function: emacs_value make_big_integer (emacs_env *env, int sign, ptrdiff_t count, const emacs_limb_t *magnitude)

このEmacs 27から利用可能になった関数は任意のサイズの整数の引数を受け取り、それに対応するemacs_valueオブジェクトをリターンする。sign引数はリターン値の符号を与える。signが0以外なら、magnitudeはリターン値のマグニチュードをリトルエンディアンで指定する、少なくともcount個の要素数の配列を指さなければならない。

以下は与えられた整数の次の確率的素数を計算するためにGNU Multiprecision Library (GMP)を使用する例です。GMPの概要は(gmp)TopmagnitudeとGMPのmpz_t値との間の変換方法については(gmp)Integer Import and Exportを参照してください。

#include <emacs-module.h>
int plugin_is_GPL_compatible;

#include <assert.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <gmp.h>

static void
memory_full (emacs_env *env)
{
  static const char message[] = "Memory exhausted";
  emacs_value data = env->make_string (env, message,
                                       strlen (message));
  env->non_local_exit_signal
    (env, env->intern (env, "error"),
     env->funcall (env, env->intern (env, "list"), 1, &data));
}

enum
{
  order = -1, endian = 0, nails = 0,
  limb_size = sizeof (emacs_limb_t),
  max_nlimbs = ((SIZE_MAX < PTRDIFF_MAX ? SIZE_MAX : PTRDIFF_MAX)
                / limb_size)
};

static bool
extract_big_integer (emacs_env *env, emacs_value arg, mpz_t result)
{
  ptrdiff_t nlimbs;
  bool ok = env->extract_big_integer (env, arg, NULL, &nlimbs, NULL);
  if (!ok)
    return false;
  assert (0 < nlimbs && nlimbs <= max_nlimbs);
  emacs_limb_t *magnitude = malloc (nlimbs * limb_size);
  if (magnitude == NULL)
    {
      memory_full (env);
      return false;
    }
  int sign;
  ok = env->extract_big_integer (env, arg, &sign, &nlimbs, magnitude);
  assert (ok);
  mpz_import (result, nlimbs, order, limb_size, endian, nails, magnitude);
  free (magnitude);
  if (sign < 0)
    mpz_neg (result, result);
  return true;
}

static emacs_value
make_big_integer (emacs_env *env, const mpz_t value)
{
  size_t nbits = mpz_sizeinbase (value, 2);
  int bitsperlimb = CHAR_BIT * limb_size - nails;
  size_t nlimbs = nbits / bitsperlimb + (nbits % bitsperlimb != 0);
  emacs_limb_t *magnitude
    = nlimbs <= max_nlimbs ? malloc (nlimbs * limb_size) : NULL;
  if (magnitude == NULL)
    {
      memory_full (env);
      return NULL;
    }
  size_t written;
  mpz_export (magnitude, &written, order, limb_size, endian, nails, value);
  assert (written == nlimbs);
  assert (nlimbs <= PTRDIFF_MAX);
  emacs_value result = env->make_big_integer (env, mpz_sgn (value),
                                              nlimbs, magnitude);
  free (magnitude);
  return result;
}

static emacs_value
next_prime (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
            void *data)
{
  assert (nargs == 1);
  mpz_t p;
  mpz_init (p);
  extract_big_integer (env, args[0], p);
  mpz_nextprime (p, p);
  emacs_value result = make_big_integer (env, p);
  mpz_clear (p);
  return result;
}

int
emacs_module_init (struct emacs_runtime *runtime)
{
  emacs_env *env = runtime->get_environment (runtime);
  emacs_value symbol = env->intern (env, "next-prime");
  emacs_value func
    = env->make_function (env, 1, 1, next_prime, NULL, NULL);
  emacs_value args[] = {symbol, func};
  env->funcall (env, env->intern (env, "defalias"), 2, args);
  return 0;
}
Function: emacs_value make_float (emacs_env *env, double d)

この関数はdoubleの引数dを受け取り対応するEmacs浮動小数点値をリターンする。

Function: emacs_value make_time (emacs_env *env, struct timespec time)

このEmacs 27から利用可能になった関数はstruct timespecの引数timeを受け取り、(ticks . hz)というペアーとしてそれに対応するEmacsタイムスタンプをリターンする。リターン値は正確にtimeと同一のタイムスタンプを表す。つまりすべての入力値は表現可能であり、精度を失うことは決してない。time.tv_secおよびtime.tv_nsecは任意の値をとり得る。特にtimeが正規化されている必要はない。これはtime.tv_nsecが負、あるいは999,999,999より大きくなり得ることを意味する。

Function: emacs_value make_string (emacs_env *env, const char *str, ptrdiff_t len)

この関数はstrが指す、終端のnullバイトを含まないバイト長がlenであるようなCテキスト文字列からEmacs文字列を作成する。strの元文字列はASCII文字列かUTF-8にエンコードされた非ASCII文字列が可能であり、文字列には埋め込みのnullバイトを含むことができ、str[len]にあるnullバイトで終端される必要はない。lenが負、またはEmacs文字列の最大長を超過する場合には、この関数はエラーコンディションoverflow-errorをraiseする。lenが0ならstrNULLでもよいが、そうでなければ有効なメモリーを指していなければならない。非0のlenでは、make_stringは一意でmutableな文字列オブジェクトをリターンする。

Function: emacs_value make_unibyte_string (emacs_env *env, const char *str, ptrdiff_t len)

この関数はmake_stringと似ているがC文字列のバイト値にたいする制限がなく、Emacsにユニバイト形式でバイナリーデータを渡すために使用できる。

このAPIはたとえばconslistによるリスト作成(コンスセルおよびリストの構築を参照)、carcdrによるリストメンバーの抽出(リスト要素へのアクセスを参照)、vectorによるベクター作成(ベクターのための関数を参照)等のようなLispデータ構造を操作する関数は提供しません。これらにたいしてはたいおう するLisp関数を呼び出すために、次のサブセクションで説明するinternfuncallを使用します。

emacs_valueオブジェクトのライフタイムはかなり短いのが普通です。このライフタイムはオブジェクトの作成に使用されたemacs_envポインターがスコープ外になると終了します。emacs_valueが望む間は行き続けるようなグローバル参照(global references)を作成を要する場合もあるかもしれません。そのようなオブジェクトの管理には以下の2つの関数を使用します。

Function: emacs_value make_global_ref (emacs_env *env, emacs_value value)

この関数はvalueのグローバル参照をリターンする。

Function: void free_global_ref (emacs_env *env, emacs_value global_value)

この関数は以前にmake_global_refで作成したglobal_valueを解放する。global_valueはこの呼び出し後は無効になる。モジュールのコードではmake_global_refと対応するfree_global_refの呼び出しそれぞれをペアーとすること。

後でモジュール関数に渡す必要があるCデータ構造体を追跡するための代替え手段はユーザーポインター(user pointer)オブジェクトの作成です。ユーザーポインター(またはuser-ptr )はCポインターをカプセル化したLispオブジェクトであり、関連付けられたファイナライザー(オブジェクトがガーベージコレクトされる際に呼び出される。ガーベージコレクションを参照)をもつことができます。モジュールAPIuser-ptrオブジェクトの作成やアクセスを行う関数を提供します。これらの関数はuser-ptrオブジェクトを表現しないemacs_valueで呼び出されるとエラーコンディションwrong-type-argumentをraiseします。

Function: emacs_value make_user_ptr (emacs_env *env, emacs_finalizer fin, void *ptr)

この関数はCポインターptrをラップしたuser-ptrオブジェクトを作成してリターンする。ファイナライザー関数finNULL (ファイナライザーなし)、または以下のシグネチャをもつ関数のいずれか:

typedef void (*emacs_finalizer) (void *ptr);

finNULLポインターでなければ、user-ptrオブジェクトがガーベージコレクトされる際にptrを引数として呼び出される。Emacsの応答性を維持するためにGCは短時間で終了しなければならないので、ファイナライザーでは高価なコードの実行は行ってはならない。

Function: void * get_user_ptr (emacs_env *env, emacs_value arg)

この関数はargで表されるLispオブジェクトからCポインターを抽出する。

Function: void set_user_ptr (emacs_env *env, emacs_value arg, void *ptr)

この関数はargで表されるuser-ptrオブジェクトに埋め込まれたCポインターにptrをセットする。

Function: emacs_finalizer get_user_finalizer (emacs_env *env, emacs_value arg)

この関数はargで表されるuser-ptrオブジェクトのファイナライザー、ファイナライザーがなければNULLをリターンする。

Function: void set_user_finalizer (emacs_env *env, emacs_value arg, emacs_finalizer fin)

この関数はargで表されるuser-ptrオブジェクトのファイナライザーをfinに変更する。finNULLならuser-ptrオブジェクトのファイナライザーはなくなる。

emacs_finalizerタイプはユーザーポインターと関数ファイナライザーの両方にたいして機能することに注意してください。Module Function Finalizersを参照してください。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.8.4 その他の便利なモジュール用関数

このサブセクションではモジュールAPIが提供する便利な関数をいくつか説明します。前のサブセクションで説明した関数と同じようにこれらの関数は実際には関数ポインターであり、emacs_envポインターを介して呼び出す必要があります。Emacs 25以降に導入された関数の説明はそれらが利用可能になった最初のバージョンを付記します。

Function: bool eq (emacs_env *env, emacs_value a, emacs_value b)

この関数はabが表すLispオブジェクトが等しければtrue、それ以外ならfalseをリターンする。これはLisp関数eq (同等性のための述語を参照)と同じだが、引数が表すオブジェクトのinternの要否を無視する。

等価性に関する他の述語はAPI関数には存在しないので、より複雑な等価性のテストを行うためには、以下で説明するinternfuncallを使う必要がある。

Function: bool is_not_nil (emacs_env *env, emacs_value arg)

このえ関数はargで表されるLispオブジェクトをテストして非nilならtrue、それ以外はfalseをリターンする。

等価性をテストするたにinternを使ってnilを表すemacs_valueを取得して、上述のeqを使用すれば自身で等価性テストを実装できることに注意。しかしこの関数を使用するほうが簡便だろう。

Function: emacs_value type_of (emacs_env *env, emacs_value arg)

この関数はシンボルを表す値(文字列はstring、整数はinteger、プロセスならprocess等)としてargのタイプをリターンする。型のための述語を参照のこと。オブジェクトのタイプにコードが依存する必要があれば、既知のタイプシンボルと比較するためにinterneqを使用できる。

Function: emacs_value intern (emacs_env *env, const char *name)

この関数は名前がname (null終端されたASCII文字列であること)であるような、internされたEmacsシンボルをリターンする。すでに存在していなれば新たにシンボルを作成する。

この関数は以下で説明するfuncallと共に用いることにより、Lispで呼び出し可能なEmcas関数(名前が純粋なASCII文字列である場合にかぎる)純粋なASCII文字列であるようなを呼び出す手段を提供する。たとえば以下はより協力なEmacsのintern関数(シンボルの作成とinternを参照)を呼び出すことにより、名前name_strが非ASCIIであるようなシンボルをinternする方法:

emacs_value fintern = env->intern (env, "intern");
emacs_value sym_name =
  env->make_string (env, name_str, strlen (name_str));
emacs_value symbol = env->funcall (env, fintern, 1, &sym_name);
Function: emacs_value funcall (emacs_env *env, emacs_value func, ptrdiff_t nargs, emacs_value *args)

この関数はargsが指す配列のnargs個の引数を渡してfuncの指定先を呼び出す。引数funcは(上述のinternがリターンした)関数シンボル、make_functionがリターンしたモジュール関数(モジュール関数の記述を参照)、Cで記述されたサブルーチン等。nargsが0ならargsNULLポインターでもよい。

この関数はfuncがリターンした値をリターンする。

モジュールに長時間実行される可能性のあるコードが含まれる場合には、たとえばC-gをタイプする(quitを参照)等によりユーザーがquitを望むかどうかをコード内でときどきチェックするのはよいアイデアです。Emacs 26.1から利用可能になった以下の関数は、この目的のために提供されました。

Function: bool should_quit (emacs_env *env)

この関数はユーザーがquitを望むようならtrueをリターンする。この場合にはモジュール関数は実行中の処理をabortして可能なかぎり速やかにリターンすることを推奨する。ほとんどの場合はprocess_inputを使用すること。

ユーザーがquitを望むかどうかをチェックすることに加えて入力イベントを処理するには、Emacs 27.1以降で利用可能になった以下の関数を使用してください。

Function: enum emacs_process_input_result process_input (emacs_env *env)

この関数は保留中の入力イベントを処理する。ユーザーがquitを望んでいたり、シグナル処理中にエラーが発生したらemacs_process_input_quitをリターンする。この場合にはモジュール関数は行っているすべての処理をabortして可能なかぎり即座にリターンすることを推奨する。モジュールコードが実行を継続できるなら、process_inputemacs_process_input_continueをリターンする。env内に保留中の非ローカルexitが存在しない場合のみ、リターン値はemacs_process_input_continueprocess_input呼び出し後にモジュールが継続する場合には、変数値やバッファーコンテンツのとうなグローバル状態は任意の手段で変更され得る。

Function: int open_channel (emacs_env *env, emacs_value pipe_process)

このEmacs 28以降で利用可能になった関数は、既存のpipeプロセスへのチャンネルをオープンする。pipe_processmake-pipe-processが作成した既存のpipeプロセスを参照しなければならない。Pipe Processesを参照のこと。成功すると、そのpipeへの書き込みに使用できる新たなファイルデスクリプターを値としてリターンする。他のすべてのモジュール関数と異なり、アクティブなモジュール環境がなくても、任意のスレッドがリターンしたファイルデスクリプターを使用できる。このファイルデスクリプターへの書き込みにはwrite関数を使用できる。使用後にはcloseを使用してファイルデスクリプターをクローズする。(libc)Low-Level I/Oを参照のこと。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.8.5 モジュールでの非ローカル脱出

Emacs Lispは非ローカル脱出(nonlocal exits)をサポートしており、これによりプログラムの制御はプログラムのあるポイントから別の離れたポイントに転送されます。非ローカル脱出を参照してください。したがってモジュールから呼び出されたLisp関数はsignalthrowを呼び出して非ローカルにexitするかもしれず、そのような非ローカル脱出をモジュール関数は正しくハンドルしなければなりません。このようなハンドリングはCプログラムがリソースを自動的に解放せず、このような場合には別のクリーンアップを行うために必要になります。モジュールコードは自身でこれを行わなければなりません。そのための機能をモジュールAPIは提供しており、このサブセクションではそれを説明します。これらは一般的にはEmacs 25以降で利用可能です。これ以降のリリースで利用可能になったものについては、APIに含まれるようになった最初のEmacsのバージョンを付記します。

モジュール関数から呼び出されたLispコードがエラーをシグナルしたりthrowを行う際には、非ローカル脱出はtrapされて保留中のexitと関連するデータは環境内に格納されます。環境内で非ローカル脱出が保留中の際には、環境へのポインターで呼び出されたすべてのモジュールAPI関数は何も処理を行わずに即座にリターンします(関数non_local_exit_checknon_local_exit_getnon_local_exit_clearはこのルールの例外)。モジュール関数が何も行わずにEmacsにリターンすれば、保留中の非ローカル脱出にたいしてEmacsがエラーをシグナルしたり、対応するcatchへのthrowという対処を行うでしょう。

したがって特別なことな何も行わずに、何事もなかったかのようにコードの残りを実行するのが、モジュール関数での非ローカル脱出にけるもっともシンプルな“ハンドリング”です。しかしこれは2つのクラスの問題を引き起こすかもしれません:

  • - 期待する値を生成することなくAPI関数は即座にリターンするので、初期化や定義が行われていない値をモジュール関数が使用するかもしれない。
  • - リソースを解放する機会がないかもしれないのでモジュールがリソースをリークするかもしれない。

したがってモジュール関数は以下に説明する関数を使用して、非ローカル脱出のコンディションのチェックとリカバリングを行うことを推奨します。

Function: enum emacs_funcall_exit non_local_exit_check (emacs_env *env)

この関数はenvに格納された非ローカル脱出のコンディションをリターンする。可能な値は:

emacs_funcall_exit_return

最後のAPI関数は正常にexitした。

emacs_funcall_exit_signal

最後のAPI関数はエラーをシグナルした。

emacs_funcall_exit_throw

最後のAPI関数はthrowを通じてexitした。

Function: enum emacs_funcall_exit non_local_exit_get (emacs_env *env, emacs_value *symbol, emacs_value *data)

この関数はnon_local_exit_checkが行うようにenvに格納された非ローカル脱出の種別をリターンするが、もしあれば非ローカル脱出に関する完全な情報もリターンする。リターン値がemacs_funcall_exit_signalなら関数は*symbolにエラーシンボル、*dataにエラーデータを格納する(エラーをシグナルする方法を参照)。リターン値がemacs_funcall_exit_throwなら関数は*symbolcatchされたたタグシンボル、*datathrowされた値を格納する。リターン値がemacs_funcall_exit_returnなら関数はこれらの引数が指すメンモリー内に何も格納しない。

何らかのリソースの割り当て前や解放を要するリソースの割り当て後、あるいは失敗がそれ以上の処理が不可能もしくは実行不能を意味するような場合のように、非ローカル脱出が問題になるようならチェックするべきです。

モジュール関数が保留中の非ローカル脱出を一度検知すれば、(必要なローカルクリーンアップの実施後に)Emacsにリターンしたり、非ローカル脱出からのリカバリーを試みることができます。以下のAPI関数はこれらのタスクの助けとなるでしょう。

Function: void non_local_exit_clear (emacs_env *env)

この関数は保留中の非ローカル脱出のコンディションとenv由来のデータをクリアーする。これの呼び出し後にはモジュールAPI関数は通常どおり機能するだろう。モジュール関数が呼び出したLisp関数の非ローカル脱出からリカバーして継続可能な場合、あるいは以下の2つの関数のいずれか(非ローカル脱出が保留中の際に他のAPI関数に意図した動作を行わせたい場合にはそれらのAPI関数も)を呼び出す前にもこの関数を使用すること

Function: void non_local_exit_throw (emacs_env *env, emacs_value tag, emacs_value value)

この関数はtagで表されるLispのcatchシンボルにリターン値としてvalueを渡してthrowを行う。モジュール関数は一般的にはこの関数の呼び出し後は即座にリターンすること。この関数は呼び出されたAPI関数やLisp関数のいずれかから非ローカル脱出を再throwしたい際の1つの手段である。

Function: void non_local_exit_signal (emacs_env *env, emacs_value symbol, emacs_value data)

この関数はエラーシンボルsymbolで表されるエラーを、指定したエラーデータdataとともにシグナルする。モジュール関数はこの関数の呼び出し後は即座にリターンすること。この関数はたとえばモジュール関数からEmacsにエラーをシグナルする際に有用かもしれない。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.9 オブジェクトの内部

Emacs Lispは豊富なデータタイプのセットを提供します。コンスセル、整数、文字列のようにこれらのいくつかは、ほとんどすべてのLisp方言で一般的です。マーカやバッファーのようなそれ以外のものはLisp内でエディターコマンドを記述するための基本的サポートを提供するために極めて特別かつ必要なものです。そのような種々のオブジェクトタイプを実装してインタープリターのサブシステムとの間でオブジェクトを渡す効果的な方法を提供するために、Cデータ構造体セットとそれらすべてにたいするポインターを表すタグ付きポインター(tagged pointer)と呼ばれる特別なタイプが存在します。

Cではタグ付きポインターはタイプLisp_Objectのオブジェクトです。そのようなタイプの初期化された変数は基本的なデータタイプである整数、シンボル、文字列、コンスセル、浮動小数点数、ベクター類似オブジェクトのいずれかを値として常に保持します。これらのデータタイプのそれぞれは対応するタグ値をもちます。すべてのタグはenum Lisp_Typeにより列挙されており、Lisp_Objectの3ビットのビットフィールドに配置されます。残りのビットはそれ自身の値です。整数は即値(値ビットで直接表される)、他のすべてのオブジェクトはヒープに割り当てられた対応するオブジェクトへのCポインターで表されます。Lisp_Objectのサイズはプラットフォームと設定に依存します。これは通常は背景プラットフォームのポインターと同一(32ビットマシンなら32ビット、64ビットマシンなら64ビット)ですがLisp_Objectが64ビットでも、すべてのポインターが32ビットのような特別な構成もあります。後者はLisp_Objectにたいして64ビットのlong longタイプを使用することにより、32ビットシステム上のLisp整数にたいする値範囲の制限を乗り越えるためにデザインされたトリックです。

以下のCデータ構造体は整数ではない基本的なデータタイプを表すためにlisp.hで定義されています:

struct Lisp_Cons

コンスセル。リストを構築するために使用されるオブジェクト。

struct Lisp_String

文字列。文字シーケンスを表す基本的オブジェクト。

struct Lisp_Vector

配列。インデックスによりアクセスできる固定サイズのLispオブジェクトのセット。

struct Lisp_Symbol

シンボル。一般的に識別子として使用される一意な名前のエンティティ。

struct Lisp_Float

Floating-point value.

これらのタイプは内部的タイプシステムのファーストクラスの市民です。タグスペースは限られているので他のすべてのタイプはLisp_Vectorlikeのサブクラスです。サブタイプのベクターはenum pvec_typeにより列挙されておりウィンドウ、バッファー、フレーム、プロセスのようなほとんどすべての複雑なオブジェクトはこのカテゴリーに分類されます。

Lisp_Vectorlikeのいくつかのサブタイプを説明します。バッファーオブジェクトは表示や編集を行うテキストを表します。ウィンドウはバッファーを表示したり、同一フレーム上で再帰的に他のウィンドウを配置するためのコンテナーとして使用される表示構造の一部です(Emacs Lispのウィンドウオブジェクトと、のようなユーザーインターフェースシステムに管理されるエンティティとしてのウィンドウを混同しないこと。Emacsの用語では後者はフレームと呼ばれる)。最後にプロセスオブジェクトはサブプロセスの管理に使用されます。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.9.1 バッファーの内部

Cでバッファーを表すために2つの構造体(buffer.hを参照)が使用されます。buffer_text構造体にはバッファーのテキストを記述するフィールドが含まれます。buffer構造体は他のフィールドを保持します。インダイレクトバッファーの場合には、2つ以上のbuffer構造体が同じbuffer_text構造体を参照します。

以下にstruct buffer_text内のフィールドをいくつか示します:

beg

バッファーコンテンツのアドレス。バッファーコンテンツは途中にギャップをもつcharの線形C配列。

gpt
gpt_byte

バッファーのギャップの文字位置とバイト位置。バッファーのギャップを参照のこと。

z
z_byte

バッファーテキストの終端の文字位置とバイト位置。

gap_size

バッファーのギャップのサイズ。バッファーのギャップを参照のこと。

modiff
save_modiff
chars_modiff
overlay_modiff

これらのフィールドは、そのバッファーで行われたバッファー変更イベントの数をカウントする。modiffはバッファー変更イベントのたびに増分されて、それ以外では決して変化しない。save_modiffにはバッファーが最後にvisitや保存されたときのmodiffの値が含まれる。chars_modiffはバッファー内の文字にたいする変更だけをカウントして、(テキストプロパティのように)その他すべての種類の変更を無視する。overlay_modiffはバッファーのオーバーレイにたいする変更だけをカウントする。

beg_unchanged
end_unchanged

最後の再表示完了以降に未変更だと解っているテキスト、開始と終了の箇所での文字数。

unchanged_modified
overlay_unchanged_modified

それぞれ最後に再表示が完了した後のmodiffoverlay_modiffの値。これらのカレント値がmodiffoverlay_modiffとマッチしたら、それはbeg_unchangedend_unchangedに有用な情報が含まれないことを意味する。

markers

このバッファーを参照するマーカー。これは実際には単一のマーカーであり、自身のマーカーチェーン (リンクリスト)内の一連の要素がバッファー内のテキストを参照する他のマーカーになる。

intervals

そのバッファーのテキストプロパティを記録するインターバルツリー。

struct bufferのいくつかのフィールドを以下に示します:

header

タイプunion vectorlike_headerのヘッダーは、すべてのベクター類似のオブジェクトに共通。

own_text

構造体struct buffer_textは通常はバッファーのコンテンツを保持する。このフィールドはインダイレクトバッファーでは使用されない。

text

そのバッファーのbuffer_text構造体へのポインター。通常のバッファーでは上述のown_textフィールド。インダイレクトバッファーではベースバッファーのown_textフィールド。

next

killされたバッファーを含むすべてのバッファーのチェーン内において次のバッファーへのポインター。このチェーンはkillされたバッファーを正しく回収するために割り当てとガーベージコレクションのためだけに使用される。

pt
pt_byte

バッファー内のポイントの文字位置とバイト位置。

begv
begv_byte

そのバッファー内のアクセス可能範囲の先頭位置の文字位置とバイト位置。

zv
zv_byte

そのバッファー内のアクセス可能範囲の終端位置の文字位置とバイト位置。

base_buffer

インダイレクトバッファーではベースバッファーのポイント。通常のバッファーではnull。

local_flags

このフィールドはバッファー内でローカルな変数にたいしてそれを示すフラグを含む。そのような変数はCコードではDEFVAR_PER_BUFFERを使用して宣言され、それらのバッファーローカルなバインディングはバッファー構造体自身内のフィールドに格納される(これらのフィールドのいくつかはこのテーブル内で説明している)。

modtime

visitされているファイルの変更時刻。これはファイルの書き込みと読み込み時にセットされる。そのバッファーをファイルに書き込む前にファイルがディスク上で変更されていないことを確認するために、このフィールドとそのファイルの変更時刻を比較する。バッファーの変更を参照のこと。

auto_save_modified

そのバッファーが最後に自動保存されたときの時刻。

last_window_start

そのバッファーが最後にウィンドウに表示されたときのバッファー内でのwindow-start位置。

clip_changed

このフラグはバッファーでのナローイングが変更されているかを示す。ナローイングを参照のこと。

prevent_redisplay_optimizations_p

このフラグはバッファーの表示において再表示最適化が使用されるべきではないことを示す。

inhibit_buffer_hooks

このフラグはそのバッファーではフックkill-buffer-hookkill-buffer-query-functions (バッファーのkillを参照)、buffer-list-update-hook (バッファーリストを参照)が実行されないことを示す。このフラグはバッファー作成時にセットされて(バッファーの作成を参照)、内部バッファーやwith-temp-buffer (Current Buffer)が作成するバッファーの速度低下を防ぐ。

name

バッファーを命名するLisp文字列。一意であることが保証されている。バッファーの名前を参照のこと。このフィールドと以降のフィールドは以下のようにBVARを介するアクセス以外の方法で直接アクセスするべきではないことを示すためにC構造体定義内の名前の最後に_をもつ:

  Lisp_Object buf_name = BVAR (buffer, name);
save_length

そのバッファーがvisitしているファイルを最後に読み込み、または保存したときの長さ。2つの特別な値をもつことができる。-1はそのバッファーで自動保存がオフであること、-2はバッファーのテキストが大量に減少するようなら自動保存をオフに切り替えないことを意味する。インダイレクトバッファーは決して保存されることはないので、保存に関して、このフィールドとその他のフィールドはbuffer_text構造体で維持されない

directory

相対ファイル名を展開するディレクトリー。これはバッファーローカル変数default-directoryの値(ファイル名を展開する関数を参照)。

filename

そのバッファーがvisitしているファイルの名前。これはバッファーローカル変数buffer-file-nameの値(バッファーのファイル名を参照)。

undo_list
backed_up
auto_save_file_name
auto_save_file_format
read_only
file_format
file_truename
invisibility_spec
display_count
display_time

これらのフィールドは自動的にバッファーローカル(バッファーローカル変数を参照)になるLisp変数の値を格納する。これらに対応する変数は名前に追加のプレフィクスbuffer-がつき、アンダースコアがダッシュで置換される。たとえばundo_listbuffer-undo-listの値を格納する。

mark

そのバッファーにたいするマーク。マークはマーカーなのでリストmarkers内にも含まれる。マークを参照のこと。

local_var_alist

この連想リストはバッファーのバッファーローカル変数のバインディングを記述する。これにはバッファーオブジェクト内に特別なスロットをもつ、ビルトインのバッファーローカルなバインディングは含まれない(このテーブルではそれらのスロットは省略している)。バッファーローカル変数を参照のこと。

major_mode

そのバッファーのメジャーモードを命名するシンボル(例: lisp-mode)。

mode_name

そのメジャーモードの愛称(例: "Lisp")。

keymap
abbrev_table
syntax_table
category_table
display_table

これらのフィールドはバッファーのローカルキーマップ(キーマップを参照)、abbrevテーブル(abbrevテーブルを参照)、構文テーブル(構文テーブルを参照)、カテゴリーテーブル(カテゴリーを参照)、ディスプレイテーブル(ディスプレイテーブルを参照)を格納する。

downcase_table
upcase_table
case_canon_table

これらのフィールドはテキストを小文字、大文字、およびcase-fold検索でのテキストの正規化の変換テーブルを格納する。caseテーブルを参照のこと。

minor_modes

そのバッファーのマイナーモードのalist。

pt_marker
begv_marker
zv_marker

これらのフィールドはインダイレクトバッファー、またはインダイレクトバッファーのベースバッファーであるようなバッファーでのみ使用される。これらはそれぞれバッファーがカレントでないときにバッファーにたいするptbegvzvを記録するマーカーを保持する。

mode_line_format
header_line_format
case_fold_search
tab_width
fill_column
left_margin
auto_fill_function
truncate_lines
word_wrap
ctl_arrow
bidi_display_reordering
bidi_paragraph_direction
selective_display
selective_display_ellipses
overwrite_mode
abbrev_mode
mark_active
enable_multibyte_characters
buffer_file_coding_system
cache_long_line_scans
point_before_scroll
left_fringe_width
right_fringe_width
fringes_outside_margins
scroll_bar_width
indicate_empty_lines
indicate_buffer_boundaries
fringe_indicator_alist
fringe_cursor_alist
scroll_up_aggressively
scroll_down_aggressively
cursor_type
cursor_in_non_selected_windows

これらのフィールドは自動的にバッファーローカル(バッファーローカル変数を参照)になるLisp変数の値を格納する。これらに対応する変数は名前のアンダースコアがダッシュで置換される。たとえばmode_line_formatmode-line-formatの値を格納する。

overlays

そのバッファーのオーバーレイを含んだインターバルツリー(interval tree: 区間木)。

last_selected_window

これは最後に選択されていたときにそのバッファーを表示していたウィンドウ、またはそのウィンドウがすでにそのバッファーを表示していなければnil


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.9.2 ウィンドウの内部

ウィンドウのフィールドには以下が含まれます(完全なリストはwindow.hstruct windowを参照):

frame

そのウィンドウがあるフレーム(Lispオブジェクト)。

mini

そのウィンドウがミニバッファーウィンドウ、ミニバッファーかエコーエリアを表示しているウィンドウなら非0。

pseudo_window_p

そのウィンドウが疑似ウィンドウ(pseudo window)なら非0。疑似ウィンドウとはメニューバーかツールバーの表示に使用されているウィンドウ(自身のメニューバーやツールバーを表示しないツールキットをEmacsが使用している場合)、タブバー、またはツールチップフレーム上でツールチップを表示しているウィンドウのいずれか。一般的には疑似ウィンドウはLispコードからアクセスできない。

parent

Emacsは内部的にウィンドウをツリーにアレンジする。ウィンドウの兄弟グループは、そのエリアがすべての兄弟を含むような親ウィンドウをもつ。このフィールドはツリー内でのウィンドウの親をLispオブジェクトとして指す。これはツリーのルートウィンドウとミニバッファーウィンドウでは常にnil

親ウィンドウはバッファーを表示せず、子ウィンドウ形成を除いて表示では少ししか役割を果たさない。Emacs Lispプログラムは親ウィンドウを直接操作できない。Emacs Lispプログラムでは実際にバッファーを表示するツリーの子ノードのウィンドウにたいして操作を行う。

contents

リーフウィンドウ(leaf window)およびツールチップを表示中のウィンドウでは、そのウィンドウが表示しているLispオブジェクトとしてのバッファー、内部ウィンドウ(“親”ウィンドウ)では最初の子ウィンドウ、メニューバーやツールバーを表示している疑似ウィンドウではnil、削除されたウィンドウでもnil

next
prev

そのウィンドウの次の兄弟と前の兄弟(Lispオブジェクト)。自身のグループ内でそのウィンドウが右端か下端ならnextnil。自身のグループ内でそのウィンドウが左端か上端ならprevnil。兄弟が左右あるいは上下であるかは兄弟の親のhorizontalフィールドで判断される。これが非0なら兄弟は水平に配置されている。

特別なケースとしてミニバッファーのみのフレームやミニバッファーなしのフレームでなければ、フレームのルートウィンドウのnextは、そのフレームのミニバッファーウィンドウを指す。そのようなフレームのミニバッファーウィンドウのprevは、そのフレームのルートウィンドウを指す。それ以外の場合にはルートウィンドウのnextフィールド、および(もしあれば)ミニバッファーのprevフィールドはnil

left_col

そのウィンドウの左端をウィンドウのネイティブフレームの最左列(列0)から相対的に数えた列数。

top_line

そのウィンドウの上端をウィンドウのネイティブフレームの最上行(行0)から相対的に数えた行数。

pixel_left
pixel_top

そのウィンドウの左側上端をウィンドウのネイティブフレームの左上隅(0, 0)から相対的に計測したピクセル数。

total_cols
total_lines

列数または行数で数えた、そのウィンドウの幅または高さの合計。値にはスクロールバーとフリンジ、ディバイダー、および/または(もしあれば)ウィンドウ右側のセパレーターラインが含まれる。

pixel_width;
pixel_height;

ピクセルで計測したウィンドウの幅または高さの合計。

start

そのウィンドウ内に表示されるバッファーで、ウィンドウに最初(ロジカル順。双方向テキストの表示を参照)に表示される文字の位置を指すマーカー。

pointm

これはウィンドウが選択されているときのカレントバッファーのポイント値。選択されていなければ前の値が保たれる。

old_pointm

最後の再表示時のpointmの値。

force_start

このフラグが非nilならLispプログラムによりそのウィンドウが明示的にスクロールされたことを示し、再表示のためにウィンドウのstartの値がセットされる。これはポイントがスクリーン外の場合の次回再表示に影響を与える。影響とはポイント周辺のテキストを表示するためにウィンドウをスクロールするかわりに、スクリーン上にある位置にポイントを移動するというものである。

optional_new_start

これはforce_startと同様だが、次回表示ではポイントが可視の場合のみしたがう。

start_at_line_beg

nilstartのカレント値がウィンドウ選択時に先頭行だったことを意味する。

use_time

これはウィンドウが最後に選択された時刻。関数get-lru-windowはこの値を使用する。

sequence_number

そのウィンドウ作成時に割り当てられた一意な番号。

last_modified

前回のそのウィンドウの再表示完了時のウィンドウのバッファーのmodiffフィールド。

last_overlay_modified

前回のウィンドウの再表示完了時のウィンドウのバッファーのoverlay_modiffフィールド。

last_point

前回のウィンドウの再表示完了時のウィンドウのバッファーのポイント値。

last_had_star

非0値はウィンドウが最後に更新されたとき、そのウィンドウのバッファーが変更されたことを意味する。

vertical_scroll_bar_type
horizontal_scroll_bar_type

そのウィンドウの垂直スクロールバーおよび水平スクロールバーのタイプ。

scroll_bar_width
scroll_bar_height

そのウィンドウの垂直スクロールバーの幅および水平スクロールバーの高さ(ピクセル単位)。

left_margin_cols
right_margin_cols

そのウィンドウの左マージンと右マージンの幅。値0はマージンがないことを意味する。

left_fringe_width
right_fringe_width

そのウィンドウの左フリンジと右フリンジのピクセル幅。値-1はフレームの値の使用を意味する。

fringes_outside_margins

非0値はディスプレイマージン外側のフリンジ、それ以外ならフリンジはマージンとテキストの間にあることを意味する。

window_end_pos

これはzから、そのウィンドウのカレントマトリクス内の最後のグリフのバッファー位置を減じて算出される。この値はwindow_end_validが非0のときだけ有効である。

window_end_bytepos

window_end_posに対応するバイト位置。

window_end_vpos

window_end_posを含む行のウィンドウに相対的な垂直位置。

window_end_valid

このフィールドはwindow_end_posおよびwindow_end_vposが真に有効なら非0値にセットされる。これは重要な再表示が先に割り込んだ場合には、window_end_posを算出した表示がスクリーン上に出現しなくなるので0になる。

cursor

そのウィンドウ内でカーソルがどこにあるかを記述する構造体。

last_cursor_vpos

最後の再表示完了時にカーソルを表示していた行の、ウィンドウに相対的な垂直位置。

phys_cursor

そのウィンドウのカーソルが物理的にどこにあるかを記述する構造体。

phys_cursor_type
phys_cursor_height
phys_cursor_width

そのウィンドウの最後の表示でのカーソルのタイプ、高さ、幅。

phys_cursor_on_p

このフィールドはカーソルが物理的にオンなら非0。

cursor_off_p

非0はそのウィンドウのカーソルが論理的にオフであることを意味する。これはカーソルの点滅に使用される。

last_cursor_off_p

このフィールドは最後の再表示時のcursor_off_pの値を含む。

must_be_updated_p

これはウィンドウを更新しなければならないとき、再表示の間は1にセットされる。

hscroll

これはウィンドウ内の表示が左へ水平スクロールされている列数。通常は0。カレント行だけが水平スクロールされている際には、カレント行がどれだけ左へ水平スクロールされているかを示す。

min_hscroll

set-window-hscrollを通じてユーザーがセットするhscrollの最小値(水平スクロールを参照)。カレント行だけが水平スクロールされている際には、カレント行以外の行がどれだけ左へ水平スクロールされているかを示す。

vscroll

ピクセル単位での垂直スクロール量。これは通常は0。

dedicated

そのウィンドウがそれのバッファー専用(dedicated)なら非nil

combination_limit

このウィンドウの組み合わせ限界は親ウィンドウにとってのみ意味がある。これがtならそのウィンドウの削除は許されず、そのウィンドウの他の兄弟と子ウィンドウを再組み合わせする。

window_parameters

そのウィンドウのパラメーターのalist。

display_table

そのウィンドウのディスプレイテーブル、何も指定されていなければnil

update_mode_line

非0はウィンドウのモードラインの更新が必要なことを意味する。

mode_line_height
header_line_height

モードラインおよびヘッダーラインのピクセル高さ、不明なら-1。

base_line_number

そのバッファーの特定の位置の行番号か0。これはモードラインでポイントの行番号を表示するために使用される。

base_line_pos

行番号が既知であるバッファー位置、不明なら0。これが-1なら、そのウィンドウがバッファーを表示するかぎり行番号は表示されない。

column_number_displayed

そのウィンドウのモードラインに表示されているカレント列番号、列番号が表示されていなければ-1。

current_matrix
desired_matrix

そのウィンドウのカレント、および望まれる表示を記述するグリフ。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.9.3 プロセスの内部

プロセスのフィールドには以下が含まれます(完全なリストはprocess.hstruct Lisp_Processの定義を参照):

name

プロセス名(Lisp文字列)。

command

そのプロセスの開始に使用されたコマンド引数を含むリスト。ネットワークプロセスとシリアルプロセスではプロセスが実行中ならnil、停止していたらt

filter

そのプロセスから出力を受け取るために使用されるLisp関数。

sentinel

そのプロセスの状態が変化したら常に呼び出されるLisp関数。

buffer

そのプロセスに関連付けられたバッファー。

pid

オペレーティングシステムのプロセスID (整数)。ネットワークプロセスやシリアルプロセスのような疑似プロセスでは値0を使用する。

childp

フラグ。実際に子プロセスならt。ネットワークプロセスやシリアルプロセスではmake-network-processmake-serial-processにもとづくplist。

mark

そのプロセスの出力からバッファーに挿入された終端位置を示すマーカー。常にではないがこれはバッファー終端であることが多い。

kill_without_query

これが非0ならプロセス実行中にEmacsをkillしてもプロセスのkillにたいして確認を求めない。

raw_status

システムコールwaitがリターンするrawプロセス状態。

status

process-statusがリターンするようなプロセス状態。Lispシンボル、コンスセル、またはリストのいずれか。

tick
update_tick

これら2つのフィールドが等しくないなら、センチネル実行かプロセスバッファーへのメッセージ挿入によりプロセスの状態変更が報告される必要がある。

pty_flag

そのサブプロセスがptyを使用して対話する場合は非0。パイプを使用する場合には0。

infd

そのプロセスからの入力にたいするファイルディクリプター。

outfd

そのプロセスへの出力にたいするファイルディクリプター。

tty_name

そのサブプロセスが使用する端末の名前、パイプを使用する場合にはnil

decode_coding_system

そのプロセスからの入力のデコーディングにたいするコーディングシステム。

decoding_buf

デコーディング用の作業バッファー。

decoding_carryover

デコーディングでのキャリーオーバーのサイズ。

encode_coding_system

そのプロセスからの出力のエンコーディングにたいするコーディングシステム。

encoding_buf

エンコーディング用の作業バッファー。

inherit_coding_system_flag

プロセス出力のデコードに使用されるコーディングシステムからプロセスバッファーのcoding-systemをセットするフラグ。

type

プロセスのタイプを示すrealnetworkserialのいずれかのシンボル。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

E.10 Cの整数型

以下はEmacsのCソースコード内で整数タイプを使用する際のガイドラインです。これらのガイドラインはときに相反するアドバイスを与えることがありますが一般的な常識に沿ったものがアドバイスです。

  • 任意の制限の使用を避ける。たとえばsの長さをintの範囲に収めることが要求されるのでなければint len = strlen (s);を使用しないこと。
  • 符号付き整数の算術演算のオーバーフローのラップアラウンドを前提としてはならない。Emacsのポート対象先によっては成立しない。実際には符号付き整数のオーバーフローは未定義であり、コアダンプや早晩に非論理的な振る舞いさえ起こし得る。符号なし整数のオーバーフローは2のべき乗の剰余に確実にラップアラウンドされることが保証されている。
  • 符号なしタイプと符号付きタイプを組み合わせるとコードが混乱するので符号なしタイプより符号付きタイプを優先すること。他のガイドラインの多くはタイプが符号付きだとみなしている。符号なしタイプを要する稀なケースでは、符号付きの符号なし版(ptrdiff_tのかわりにsize_tintptr_tのかわりにuintptr_t)にたいして同様のアドバイスを適用できる。
  • 0から0x3FFFFFまでの範囲ではEmacs文字コードにはintを優先すること。より一般的には、たとえばスクリーン列数のようにint範囲と既知である整数にはintを優先すること。
  • サイズ(たとえばすべての個別のCオブジェクトの最大サイズや、すべてのC配列の最大要素数にバインドされる整数)にたいしてはptrdiff_tを優先すること。これは符号付きタイプにたいするEmacsの一般的な優先事項である。ptrdiff_tの使用によりオブジェクトはPTRDIFF_MAXに制限されるが、より大きいオブジェクトはポインター減算を破壊するかもしれず結局のところ問題を起こす可能性があるので、これは一方的に制限を課すものではない。
  • ssize_t関連の制限をもつ低レベルAPIト対話する際を除いてssize_tを避けること。これは典型的なプラトフォームではptrdiff_tと等価だとしても、ssize_tは範囲が狭いときがあり使用によりサイズ関連の計算がオーバーフローするかもしれない。同じくptrdiff_tはより一般的で標準化されており、標準的なprintfフォーマットをもち、Emacsの内部的なサイズオーバーフローのチェックの基礎である。ssize_tを使用する際にはPOSIXガ-からSSIZE_MAXの範囲の値にたいするサポートだけを要求することに注意してほしい。
  • 通常はポインターの内部表現や与えられた任意のタイミングで存在可能なオブジェクト数や割り当て可能な総バイト数にのみバインドされる整数にはintptr_tを優先すること。しかしページ境界を横切る可能性のあるポインター演算を表す場合にはuintptr_tを優先すること。たとえば32ビットのアドレス空間をもつマシンでの配列は0x7fffffff/0x80000000境界を横断する可能性があり、(intptr_t) 0x7fffffffに1を加算することによって整数のオーバーフローが発生し得る。
  • Emacs Lispのfixnumへの変換や逆変換を表す値ではfixnum演算がEMACS_INTにもとづくのでEmacsで定義されたタイプEMACS_INTを優先すること。
  • (ファイルサイズやエポック以降の経過秒数等の)システム値を表す際には、(off_ttime_t等の)システムタイプを優先すること。安全だと解っていなければシステムタイプが符号付きだと仮定してはならない。たとえばoff_tは常に符号付きだがtime_tは符号付きである必要はない。
  • 符号付き整数かもしれない値を表す場合にはintmax_tを優先すること。printf族の関数は"%"PRIdMAXのようなフォーマットを使用してこのような値をプリントできる。
  • ブーリーンにはboolfalsetrueを使用すること。boolの使用によりプログラムの可読性が増して、intを使用するより若干高速になる。int01を使用しても大丈夫だが旧スタイルは段階的に廃止される。boolを使用する際にはboolの代替実装の制限を尊重すること。特にブーリーンのビットフィールドは、boolではなくbool_bfタイプであること。そうすれば標準のGCCでObjective Cをコンパイルするときでさえ正しく機能する。
  • ビットフィールドではintは可搬性に劣るので、intよりunsigned intsigned intを優先すること。単一ビットのビットフィールドの値は0か1なのでunsigned intbool_bfを使用すること。

[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Appendix F 標準的なエラー

以下は標準的なEmacsにおける、より重要なエラーシンボルを概念別にグループ分けしたリストです。このリストには各シンボルのメッセージ、およびエラーを発生し得る方法へのクロスリファレンスが含まれています。

これらのエラーシンボルはそれぞれ、親となるエラーコンディションのセットをシンボルのリストとして保持します。通常このリストにはエラーシンボル自身とシンボルerrorが含まれます。このリストはerrorより狭義ですが、単一のエラーシンボルより広義であるような中間的なクラス分けのための追加シンボルを含む場合があります。たとえばファイルアクセスでのすべてのエラーはコンディションfile-errorをもちます。ここでわたしたちが、特定のエラーシンボルにたいする追加エラーコンディションに言及していなければ、それがないことを意味しています。

特別な例外としてエラーシンボルquitminibuffer-quitは、quitはエラーはみなさないという理由から、コンディションerrorをもっていません。

これらのエラーシンボルのほとんどはC(主にdata.c)で定義されていますが、いくつかはLispで定義されています。たとえばファイルuserlock.elではfile-lockedfile-supersessionのエラーが定義されています。Emacsとともに配布される専門的なLispライブラリーのいくつかは、それら自身のエラーシンボルを定義しています。それらのすべてをここではリストしません。

エラーの発生とそれを処理する方法についてはエラーを参照してください。

error

メッセージは‘error’。エラーを参照のこと。

quit

メッセージは‘Quit’。quitを参照のこと。

minibuffer-quit

メッセージは‘Quit’。これはquitのサブカテゴリー。quitを参照のこと。

args-out-of-range

メッセージは‘Args out of range’。これはシーケンス、バッファー、その他コンテナー類似オブジェクトにたいして範囲を超えた要素にアクセスを試みたときに発生する。シーケンス、配列、ベクターテキストを参照のこと。

arith-error

メッセージは‘Arithmetic error’。これは0による整数除算を試みたときに発生する。数値の変換算術演算を参照のこと。

beginning-of-buffer

メッセージは‘Beginning of buffer’。文字単位の移動を参照のこと。

buffer-read-only

メッセージは‘Buffer is read-only’。読み取り専用のバッファーを参照のこと。

circular-list

メッセージは‘List contains a loop’。これは循環構造に遭遇時に発生する。循環オブジェクトの読み取り構文を参照のこと。

cl-assertion-failed

メッセージは‘Assertion failed’。これはcl-assertマクロのテスト失敗時に発生する。Assertions in Common Lisp Extensionsを参照のこと。

coding-system-error

メッセージは‘Invalid coding system’。Lispでのコーディングシステムを参照のこと。

cyclic-function-indirection

メッセージは‘Symbol's chain of function indirections contains a loop’。See シンボル関数インダイレクションを参照のこと。

cyclic-variable-indirection

メッセージは‘Symbol's chain of variable indirections contains a loop’。See 変数のエイリアスを参照のこと。

dbus-error

メッセージは‘D-Bus error’。Errors and Events in D-Bus integration in Emacsを参照のこと。

end-of-buffer

メッセージは‘End of buffer’。文字単位の移動を参照のこと。

end-of-file

メッセージは‘End of file during parsing’。これはファイルI/OではなくLispリーダーに属するのでfile-errorのサブカテゴリーではないことに注意のこと。入力関数を参照のこと。

file-already-exists

これはfile-errorのサブカテゴリー。ファイルへの書き込みを参照のこと。

permission-denied

これはこれは何らかの理由により、EmacsによるファイルやディレクトリーへのアクセスをOSが拒否する際に発生するfile-errorのサブカテゴリー。

file-date-error

これはfile-errorのサブカテゴリー。これはcopy-fileを試行して出力ファイルの最終変更時刻のセットに失敗したときに発生する。ファイルの名前と属性の変更を参照のこと。

file-error

このエラーメッセージは、通常はエラーコンディションfile-errorが与えられたときはデータアイテムだけから構築されるので、エラー文字列とサブカテゴリーはここにリストしない。つまりエラー文字列は特に関連しない。しかしこれらのエラーシンボルはerror-messageプロパティをもち、何もデータが与えられなければerror-message使用されるファイルを参照のこと。

file-missing

これはfile-errorのサブカテゴリー。これは存在しないファイルの処理を試みた際に発生する。ファイルの名前と属性の変更を参照のこと。

compression-error

これは圧縮ファイルの処理の問題を起因とするfile-errorのサブカテゴリー。プログラムがロードを行う方法を参照のこと。

file-locked

これはfile-errorのサブカテゴリー。ファイルのロックを参照のこと。

file-supersession

これはfile-errorのサブカテゴリー。バッファーの変更時刻を参照のこと。

file-notify-error

これはfile-errorのサブカテゴリー。ファイル変更による通知を参照のこと。

remote-file-error

これはリモートファイルへのアクセスにおける問題の結果であり、file-errorのサブカテゴリー。Remote Files in The GNU Emacs Manualを参照のこと。このエラーは一般的にリモートファイルへのアクセス試行と別のリモートファイル操作の衝突によりタイマー、プロセスフィルター、プロセスセンチネル、スペシャルイベントにおいて頻出する。一般的にはバグレポートの記述するのが良いアイデアである。Bugs in The GNU Emacs Manualを参照のこと。

ftp-error

これはftpを使用したリモートファイルへのアクセスの問題を起因とするremote-file-errorのサブカテゴリー。Remote Files in The GNU Emacs Manualを参照のこと。

invalid-function

メッセージは‘Invalid function’。シンボル関数インダイレクションを参照のこと。

invalid-read-syntax

メッセージは通常は‘Invalid read syntax’。プリント表現と読み取り構文を参照のこと。このエラーは後の式が続くようなテキストがある際の、eval-expressionのようなコマンドでもraiseされ得る。この場合にはメッセージは‘Trailing garbage following expression’。

invalid-regexp

メッセージは‘Invalid regexp’。正規表現を参照のこと。

mark-inactive

メッセージは‘The mark is not active now’。マークを参照のこと。

no-catch

メッセージは‘No catch for tag’。明示的な非ローカル脱出: catchthrowを参照のこと。

range-error

メッセージはArithmetic range error

overflow-error

メッセージは‘Arithmetic overflow error’。これはrange-errorのサブカテゴリー。これはリミットinteger-widthを超過する整数で発生し得る。整数の基礎を参照のこと。

scan-error

メッセージは‘Scan error’。これは特定の構文解析関数が無効な構文やマッチしないカッコを見つけたときに発生する。慣習的に人間が可読なエラーメッセージ、移動を妨害する開始位置、妨害の終了位置という3つの引数でraiseされる。釣り合いのとれたカッコを越えた移動式のパースを参照のこと。

search-failed

メッセージは‘Search failed’。検索とマッチングを参照のこと。

setting-constant

メッセージは‘Attempt to set a constant symbol’。これはniltmost-positive-fixnummost-negative-fixnumおよびキーワードシンボルへの値の割り当て時に発生する。これはenable-multibyte-charactersや何らかの理由により値の直接割り当てが許されていないインボルへの値の割り当て時にも発生する。変更不可な変数を参照のこと。

text-read-only

メッセージは‘Text is read-only’。これはbuffer-read-onlyのサブカテゴリー。特殊な意味をもつプロパティを参照のこと。

undefined-color

メッセージは‘Undefined color’。カラー名を参照のこと。

user-error

メッセージは空文字列。エラーをシグナルする方法を参照のこと。

user-search-failed

これは‘search-failed’と似ているが、‘user-error’のようにデバッガーをトリガーしない。エラーをシグナルする方法検索とマッチングを参照のこと。これはInfoファイル内での検索に使用される。Search Text in Infoを参照のこと。

void-function

メッセージは‘Symbol's function definition is void’。関数セルの内容へのアクセスを参照のこと。

void-variable

メッセージは‘Symbol's value as variable is void’。変数の値へのアクセスを参照のこと。

wrong-number-of-arguments

メッセージは‘Wrong number of arguments’。リストフォームの分類を参照のこと。

wrong-type-argument

メッセージは‘Wrong type argument’。型のための述語を参照のこと。

unknown-image-type

メッセージは‘Cannot determine image type’. See イメージ

inhibited-interaction

メッセージは‘User interaction while inhibited’。このエラーはinhibit-interactionが非nilの場合に( read-from-minibufferのような)ユーザー対話関数が呼び出されるとシグナルされる。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Appendix G 標準的なキーマップ

このセクションでは、より一般的なキーマップをリストします。これらの多くはEmacsの初回起動時に存在しますが、それらのいくつかは各機能へのアクセス時にロードされます。

他にもより特化された多くのキーマップがあります。それらは特にメジャーモードやマイナーモードに関連付けられています。ミニバッファーはいくつかのキーマップを使用します(補完を行うミニバッファーコマンドを参照)。キーマップの詳細についてはキーマップを参照してください。

2C-mode-map

プレフィクスC-x 6のサブコマンドにたいするsparseキーマップ。
Two-Column Editing in The GNU Emacs Manualを参照のこと。

abbrev-map

プレフィクスC-x aのサブコマンドにたいするsparseキーマップ。
Defining Abbrevs in The GNU Emacs Manualを参照のこと。

button-buffer-map

バッファーを含むバッファーに有用なsparseキーマップ。
これを親キーマップとして使用したいと思うかもしれない。ボタンを参照のこと。

button-map

ボタンにより使用されるsparseキーマップ。

ctl-x-4-map

プレフィックスC-x 4のサブコマンドのsparseキーマップ。

ctl-x-5-map

プレフィックスC-x 5のサブコマンドのsparseキーマップ。

ctl-x-map

C-xコマンドにたいする完全なキーマップ。

ctl-x-r-map

プレフィクスC-x rのサブコマンドにたいするsparseキーマップ。
Registers in The GNU Emacs Manualを参照のこと。

esc-map

ESC(またはMeta)コマンドにたいする完全なキーマップ。

function-key-map

すべてのlocal-function-key-mapのインスタンスの親キーマップ(local-function-key-mapを参照)。

global-map

デフォルトのグローバルキーバインディングを含む完全なキーマップ。
モードでこのグローバルマップを変更しないこと。

goto-map

プレフィクスキーM-gにたいして使用されるsparseキーマップ。

help-map

ヘルプ文字C-hに後続するキーにたいするsparseキーマップ。
ヘルプ関数を参照のこと。

Helper-help-map

ヘルプユーティリティパッケージにより使用される完全なキーマップ。
これは値セルと関数セルに同じキーマップをもつ。

input-decode-map

キーパッドとファンクションキーの変換にたいするキーマップ。
存在しなければ空のsparseキーマップを含む。イベントシーケンス変換のためのキーマップを参照のこと。

key-translation-map

キー変換にたいするキーマップ。local-function-key-mapと異なり通常のキーバインディングをオーバーライドする。イベントシーケンス変換のためのキーマップを参照のこと。

kmacro-keymap

プレフィクス検索C-x C-kに後続するキーにたいするsparseキーマップ。
Keyboard Macros in The GNU Emacs Manualを参照のこと。

local-function-key-map

キーシーケンスを優先する代替えに変換するキーマップ。
存在しなければ空のsparseキーマップが含まれる。イベントシーケンス変換のためのキーマップを参照のこと。

menu-bar-file-menu
menu-bar-edit-menu
menu-bar-options-menu
global-buffers-menu-map
menu-bar-tools-menu
menu-bar-help-menu

これらのキーマップはメニューバー内のメインとなるトップレベルメニューを表示する。
これらのいくつかはサブメニューを含む。たとえばEditメニューはmenu-bar-search-menuを含む等。メニューバーを参照のこと。

minibuffer-inactive-mode-map

ミニバッファーが非アクティブ時に使用される完全なキーマップ。
Editing in the Minibuffer in The GNU Emacs Manualを参照のこと。

mode-line-coding-system-map
mode-line-input-method-map
mode-line-column-line-number-mode-map

これらのキーマップはモードライン内の種々のエリアを制御する。
モードラインのフォーマットを参照のこと。

mode-specific-map

C-cに後続する文字にたいするキーマップ。これはグローバルキーマップ内にあることに注意。これは実際にはモード固有のものではない。プフィクスキーC-cの使用方法を主に記述するC-h b (display-bindings)内で有益なのでこの名前が選ばれた。

mouse-appearance-menu-map

S-mouse-1キーにたいして使用されるsparseキーマップ。

mule-keymap

プレフィクスキーC-x RETにたいして使用されるグローバルキーマップ。

narrow-map

プレフィクスC-x nのサブコマンドにたいするsparseキーマップ。

prog-mode-map

Progモードにより使用されるキーマップ。
基本的なメジャーモードを参照のこと。

query-replace-map
multi-query-replace-map

query-replaceでの応答と関連するコマンド、y-or-n-pmap-y-or-n-pにたいしても使用されるsparseキーマップ。このマップを使用する関数はプレフィクスキーを使用せず一度に1つのイベントを照会する。複数バッファーの置換ではmulti-query-replace-mapquery-replace-mapを拡張する。query-replace-mapを参照のこと。

search-map

検索関連コマンドにたいしてグローバルバインディングを提供するsparseキーマップ。

special-mode-map

Specialモードにより使用されるキーマップ。
基本的なメジャーモードを参照のこと。

tab-prefix-map

タブバー関連コマンド用のプレフィックスキーC-x tにたいして使用されるグローバルキーマップ。
Tab Bars in The GNU Emacs Manualを参照のこと。

tab-bar-map

タブバーのコンテンツを定義するキーマップ。
Tab Bars in The GNU Emacs Manualを参照のこと。

tool-bar-map

ツールバーのコンテンツを定義するキーマップ。
ツールバーを参照のこと。

universal-argument-map

C-u処理中に使用されるsparseキーマップ。
プレフィクスコマンド引数を参照のこと。

vc-prefix-map

プレフィクスキーC-x vにたいして使用されるグローバルキーマップ。

x-alternatives-map

グラフィカルなフレームでの特定キーのマップに使用されるsparseキーマップ。
関数x-setup-function-keysはこれを使用する。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Appendix H 標準的なフック

以下はEmacsで適切なタイミングで呼び出す関数を提供するためのいくつかのフック関数のリストです。

これらの変数のほとんどは‘-hook’で終わる名前をもちます。これらはノーマルフック(normal hooks)と呼ばれておりrun-hooksにより実行されます。そのようなフックの値は関数のリストです。これらの関数は引数なしで呼び出されて値は完全に無視されます。そのようなフック上に新たに関数を配置するためにはadd-hookを呼び出す方法を推奨します。フック使用についての詳細はフックを参照してください。

-functions’で終わる名前の変数は通常はアブノーマルフック(abnormal hooks)です(古いコードの中には非推奨の‘-hooks’サフィクスを使用するものもある)。これらの値は関数のリストですが関数は特殊な方法で呼び出されます。それらは引数を渡されたり、あるいはリターン値が使用されます。‘-function’で終わる名前の変数は値として単一の関数をもちます。

以下のリストはすべてを網羅したリストではなく、より一般的なフックだけをカバーしています。たとえばメジャーモードはそれぞれ‘modename-mode-hook’という名前のフックを定義します。メジャーモードは自身が行う最後のこととしてrun-mode-hooksでこのノーマルフックを実行します。モードフックを参照してください。ほとんどのマイナーモードにもフックがあります。

特別な機能によりファイルがロードされたときに評価する式を指定できます(ロードのためのフックを参照)。この機能は正確にはフックではありませんが同様のことを行います。

activate-mark-hook
deactivate-mark-hook

マークを参照のこと。

after-change-functions
before-change-functions
first-change-hook

フックの変更を参照のこと。

after-change-major-mode-hook
change-major-mode-after-body-hook

モードフックを参照のこと。

after-init-hook
before-init-hook
emacs-startup-hook
window-setup-hook

initファイルを参照のこと。

after-insert-file-functions
write-region-annotate-functions
write-region-post-annotation-function

ファイルのフォーマット変換を参照のこと。

after-make-frame-functions
before-make-frame-hook
server-after-make-frame-hook

フレームの作成を参照のこと。

after-save-hook
before-save-hook
write-contents-functions
write-file-functions

バッファーの保存を参照のこと。

after-setting-font-hook

フレームのフォント変更後に実行されるフック。

auto-save-hook

See 自動保存を参照のこと。

before-hack-local-variables-hook
hack-local-variables-hook

ファイルローカル変数を参照のこと。

buffer-access-fontify-functions

テキストプロパティのlazyな計算を参照のこと。

buffer-list-update-hook

バッファーリスト変更時に実行されるフック(バッファーリストを参照)。

buffer-quit-function

カレントバッファーをquitするために呼び出されるフック。

change-major-mode-hook

バッファーローカルなバインディングの作成と削除を参照のこと。

comint-password-function

これは派生モードにたいして、ユーザーにプロンプト表示せずに、背後にあるコマンドインタープリター用にパスワードを供給することを許可するアブノーマルフック。

command-line-functions

コマンドライン引数を参照のこと。

delayed-warnings-hook

コマンドループはpost-command-hook(以下参照)の直後にこれを実行する。

focus-in-hook
focus-out-hook

入力のフォーカスを参照のこと。

delete-frame-functions
after-delete-frame-functions

フレームの削除を参照のこと。

delete-terminal-functions

複数の端末を参照のこと。

pop-up-frame-function
split-window-preferred-function

バッファー表示の追加オプションを参照のこと。

echo-area-clear-hook

エコーエリアのカスタマイズを参照のこと。

find-file-hook
find-file-not-found-functions

ファイルをvisitする関数を参照のこと。

font-lock-extend-after-change-region-function

バッファー変更後のリージョンのフォント化を参照のこと。

font-lock-extend-region-functions

複数行のFont Lock構造を参照のこと。

font-lock-fontify-buffer-function
font-lock-fontify-region-function
font-lock-mark-block-function
font-lock-unfontify-buffer-function
font-lock-unfontify-region-function

Font Lockのその他の変数を参照のこと。

fontification-functions

Automatic Face Assignmentを参照のこと。

frame-auto-hide-function

ウィンドウのquitを参照のこと。

quit-window-hook

ウィンドウのquitを参照のこと。

kill-buffer-hook
kill-buffer-query-functions

バッファーのkillを参照のこと。

kill-emacs-hook
kill-emacs-query-functions

Emacsのkillを参照のこと。

menu-bar-update-hook

メニューバーを参照のこと。

minibuffer-setup-hook
minibuffer-exit-hook

ミニバッファー、その他の事項を参照のこと。

mouse-leave-buffer-hook

ウィンドウ内でユーザーがマウスクリック時に実行されるフック。

mouse-position-function

マウスの位置を参照のこと。

prefix-command-echo-keystrokes-functions

(C-uのような)プレフィクスコマンドにより実行されるアブノーマルフックであり、カレントのプレフィクス状態を記述する文字列をリターンすること。たとえばC-uは‘C-u-’や‘C-u 1 2 3-’を生成する。フック関数はそれぞれ引数なしで呼び出されてカレントのプレフィクス状態を記述する文字列、プレフィクス状態がなければnilをリターンすること。プレフィクスコマンド引数を参照のこと。

prefix-command-preserve-state-hook

プレフィクスコマンドが次のコマンドにカレントのプレフィクスコマンドを渡すことによりプレフィクスを確保する必要はある際にフックが実行される。たとえばC-uはユーザーがC-u -C-uの後に数字をタイプした際には、その状態を次のコマンドに渡す必要がある。

pre-redisplay-functions

フックはそれぞれのウィンドウで再表示の直前に実行される。強制的な再表示を参照のこと。

post-command-hook
pre-command-hook

コマンドループの概要を参照のこと。

post-gc-hook

ガーベージコレクションを参照のこと。

post-self-insert-hook

キーマップとマイナーモードを参照のこと。

suspend-hook
suspend-resume-hook
suspend-tty-functions
resume-tty-functions

Emacsのサスペンドを参照のこと。

syntax-begin-function
syntax-propertize-extend-region-functions
syntax-propertize-function
font-lock-syntactic-face-function

構文的なFont Lock構文プロパティを参照のこと。

temp-buffer-setup-hook
temp-buffer-show-function
temp-buffer-show-hook

一時的な表示を参照のこと。

tty-setup-hook

端末固有の初期化を参照のこと。

window-configuration-change-hook
window-scroll-functions
window-size-change-functions

ウィンドウのスクロールと変更のためのフックを参照のこと。


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Index

Jump to:   "   #   $   %   &   '   (   )   *   +   ,   -   .   /   0   1   2   3   :   ;   <   =   >   ?   @   [   \   ]   ^   `   |  
A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z  
Index Entry  Section

"
"’ in printing 20.5 出力関数
"’ in strings 2.4.8.1 文字列の構文

#
##’ read syntax 2.4.4 シンボル型
#$ 17.3 ドキュメント文字列とコンパイル
#'’ syntax 13.7 無名関数
#(’ read syntax 2.4.8.4 文字列内のテキストプロパティ
#:’ read syntax 2.4.4 シンボル型
#@count 17.3 ドキュメント文字列とコンパイル
#n#’ read syntax 2.6 循環オブジェクトの読み取り構文
#n=’ read syntax 2.6 循環オブジェクトの読み取り構文
#^’ read syntax 2.4.10 文字テーブル型

$
$’ in display 41.3 切り詰め
$’ in regexp 35.3.1.1 正規表現内の特殊文字

%
% 3.6 算術演算
%’ in format 4.7 文字列のフォーマット

&
&’ in replacement 35.6.1 マッチしたテキストの置換
&optional 13.2.3 引数リストの機能
&rest 13.2.3 引数リストの機能

'
'’ for quoting 10.3 クォート

(
(’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
(…)’ in lists 2.4.6 コンスセルとリスト型
(?:’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文

)
)’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文

*
* 3.6 算術演算
*’ in interactive 22.2.1 interactiveの使用
*’ in regexp 35.3.1.1 正規表現内の特殊文字
* in rx 35.3.3.1 rxによるregexpの構築
** in rx 35.3.3.1 rxによるregexpの構築
*? in rx 35.3.3.1 rxによるregexpの構築
*scratch* 24.2.2 Emacsがメジャーモードを選択する方法

+
+ 3.6 算術演算
+’ in regexp 35.3.1.1 正規表現内の特殊文字
+ in rx 35.3.3.1 rxによるregexpの構築
+? in rx 35.3.3.1 rxによるregexpの構築

,
, (with backquote) 10.4 バッククォート
,@ (with backquote) 10.4 バッククォート

-
- 3.6 算術演算
--disable-build-details option to configure E.1 Emacsのビルド
--enable-locallisppath option to configure E.1 Emacsのビルド
--temacs option, and dumping method E.1 Emacsのビルド
–enable-profiling option of configure 19.5 プロファイリング

.
.’ in lists 2.4.6.2 ドットペア表記
.’ in regexp 35.3.1.1 正規表現内の特殊文字
.#, lock file names 26.5 ファイルのロック
.emacs 42.1.2 initファイル

/
/ 3.6 算術演算
/= 3.4 数値の比較
/dev/tty 40.19 シリアルポートとの対話

0
0+ in rx 35.3.3.1 rxによるregexpの構築

1
1+ 3.6 算術演算
1+ in rx 35.3.3.1 rxによるregexpの構築
1- 3.6 算術演算
1value 19.4 カバレッジテスト

2
2C-mode-map 23.6 プレフィクスキー
2D box 41.12.1 フェイスの属性

3
3D box 41.12.1 フェイスの属性

:
: in rx 35.3.3.1 rxによるregexpの構築
:deferred, JSONRPC keyword 33.32.4 遅延されたJSONRPCリクエスト
:documentation 13.2.4 関数のドキュメント文字列
:equal 37.5 tree-sitterノードにたいするパターンマッチング
:match 37.5 tree-sitterノードにたいするパターンマッチング
:notification-dispatcher 33.32.1 概観
:pred 37.5 tree-sitterノードにたいするパターンマッチング
:repeat 23.4 キーマップの作成
:request-dispatcher 33.32.1 概観

;
;’ for commenting 2.3 コメント

<
< 3.4 数値の比較
<= 3.4 数値の比較

=
= 3.4 数値の比較
= in rx 35.3.3.1 rxによるregexpの構築

>
> 3.4 数値の比較
>= 3.4 数値の比較
>= in rx 35.3.3.1 rxによるregexpの構築

?
?’ in character constant 2.4.3.1 基本的な文字構文
? in minibuffer 21.2 ミニバッファーでのテキスト文字列の読み取り
?’ in regexp 35.3.1.1 正規表現内の特殊文字
? in rx 35.3.3.1 rxによるregexpの構築
?? in rx 35.3.3.1 rxによるregexpの構築

@
@’ in interactive 22.2.1 interactiveの使用

[
[’ in regexp 35.3.1.1 正規表現内の特殊文字
[…] (Edebug) 19.2.15.2 仕様リスト

\
\’ in character constant 2.4.3.2 一般的なエスケープ構文
\’ in display 41.3 切り詰め
\’ in printing 20.5 出力関数
\’ in regexp 35.3.1.1 正規表現内の特殊文字
\’ in replacement 35.6.1 マッチしたテキストの置換
\’ in strings 2.4.8.1 文字列の構文
\’ in symbols 2.4.4 シンボル型
\'’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\( in strings 31.2.6 釣り合いのとれたカッコを越えた移動
\<’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\=’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\>’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\a 2.4.3.1 基本的な文字構文
\b 2.4.3.1 基本的な文字構文
\b’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\B’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\e 2.4.3.1 基本的な文字構文
\f 2.4.3.1 基本的な文字構文
\n 2.4.3.1 基本的な文字構文
\n’ in print 20.6 出力に影響する変数
\n’ in replacement 35.6.1 マッチしたテキストの置換
\r 2.4.3.1 基本的な文字構文
\s 2.4.3.1 基本的な文字構文
\s’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\S’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\t 2.4.3.1 基本的な文字構文
\v 2.4.3.1 基本的な文字構文
\w’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\W’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\_<’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\_>’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
\`’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文

]
]’ in regexp 35.3.1.1 正規表現内の特殊文字

^
^’ in interactive 22.2.1 interactiveの使用
^’ in regexp 35.3.1.1 正規表現内の特殊文字

`
` 10.4 バッククォート
‘ (list substitution) 10.4 バッククォート

|
|’ in regexp 35.3.1.3 正規表現内のバッククラッシュ構文
| in rx 35.3.3.1 rxによるregexpの構築

A
abbrev 38 abbrevとabbrev展開
abbrev properties 38.6 abbrevプロパティ
abbrev table properties 38.7 abbrevテーブルのプロパティ
abbrev tables 38.1 abbrevテーブル
abbrev tables in modes 24.2.1 メジャーモードの慣習
abbrev-all-caps 38.4 略語の照会と展開
abbrev-expand-function 38.4 略語の照会と展開
abbrev-expansion 38.4 略語の照会と展開
abbrev-file-name 38.3 ファイルへのabbrevの保存
abbrev-get 38.6 abbrevプロパティ
abbrev-insert 38.4 略語の照会と展開
abbrev-map Appendix G 標準的なキーマップ
abbrev-minor-mode-table-alist 38.5 標準abbrevテーブル
abbrev-prefix-mark 38.4 略語の照会と展開
abbrev-put 38.6 abbrevプロパティ
abbrev-start-location 38.4 略語の照会と展開
abbrev-start-location-buffer 38.4 略語の照会と展開
abbrev-symbol 38.4 略語の照会と展開
abbrev-table-get 38.7 abbrevテーブルのプロパティ
abbrev-table-name-list 38.1 abbrevテーブル
abbrev-table-p 38.1 abbrevテーブル
abbrev-table-put 38.7 abbrevテーブルのプロパティ
abbreviate-file-name 26.9.3 ディレクトリーの名前
abbreviated file names 26.9.3 ディレクトリーの名前
abbrevs, looking up and expanding 38.4 略語の照会と展開
abbrevs-changed 38.3 ファイルへのabbrevの保存
abnormal hook 24.1 フック
abort-recursive-edit 22.13 再帰編集
aborting 22.13 再帰編集
abs 3.4 数値の比較
absolute edges 30.3.1 フレームのレイアウト
absolute file name 26.9.2 絶対ファイル名と相対ファイル名
absolute frame edges 30.3.1 フレームのレイアウト
absolute frame position 30.3.1 フレームのレイアウト
absolute position 30.3.1 フレームのレイアウト
accept input from processes 40.9.4 プロセスの出力を受け取る
accept-change-group 33.33 グループのアトミックな変更
accept-process-output 40.9.4 プロセスの出力を受け取る
access control list 26.6.5 拡張されたファイル属性
access minibuffer contents 21.12 ミニバッファーのコンテンツ
access-file 26.6.1 アクセシビリティのテスト
accessibility of a file 26.6.1 アクセシビリティのテスト
accessible portion (of a buffer) 31.4 ナローイング
accessible-keymaps 23.17 キーマップのスキャン
accessing documentation strings 25.2 ドキュメント文字列へのアクセス
accessing hash tables 8.2 ハッシュテーブルへのアクセス
accessing plist properties 5.9.2 プロパティリストと外部シンボル
ACL entries 26.6.5 拡張されたファイル属性
acos 3.9 標準的な数学関数
action (button property) 41.20.1 ボタンのプロパティ
action alist for buffer display 29.13.3 バッファー表示用のアクションalist
action function, for buffer display 29.13.2 バッファー表示用のアクション関数
action, customization keyword 15.4.4 型キーワード
activate-change-group 33.33 グループのアトミックな変更
activate-mark-hook 32.7 マーク
active display table 41.23.3 アクティブなディスプレイテーブル
active keymap 23.7 アクティブなキーマップ
active keymap, controlling 23.9 アクティブなキーマップの制御
active minibuffer 21.1 ミニバッファーの概要
active-minibuffer-window 21.11 ミニバッファーのウィンドウ
ad-activate 13.12.4 古いdefadviceを使用するコードの改良
adaptive-fill-first-line-regexp 33.13 Adaptive Fillモード
adaptive-fill-function 33.13 Adaptive Fillモード
adaptive-fill-mode 33.13 Adaptive Fillモード
adaptive-fill-regexp 33.13 Adaptive Fillモード
add-display-text-property 41.16 displayプロパティ
add-face-text-property 33.19.2 テキストプロパティの変更
add-function 13.12.1 アドバイスを操作するためのプリミティブ
add-hook 24.1.2 フックのセット
add-name-to-file 26.7 ファイルの名前と属性の変更
add-text-properties 33.19.2 テキストプロパティの変更
add-to-history 21.4 ミニバッファーのヒストリー
add-to-invisibility-spec 41.6 不可視のテキスト
add-to-list 5.5 リスト変数の変更
add-to-ordered-list 5.5 リスト変数の変更
add-variable-watcher 12.9 変数が変更されたときに実行される関数。
address field of register 2.4.6 コンスセルとリスト型
adjust-window-trailing-edge 29.5 ウィンドウのリサイズ
adjusting point 22.6 コマンド後のポイントの調整
advertised binding 25.3 ドキュメント内でのキーバインディングの置き換え
advertised-calling-convention (declare spec) 13.15 declareフォーム
advice, add and remove 13.12.1 アドバイスを操作するためのプリミティブ
advice-add 13.12.2 名前つき関数にたいするアドバイス
advice-eval-interactive-spec 13.12.1 アドバイスを操作するためのプリミティブ
advice-function-mapc 13.12.1 アドバイスを操作するためのプリミティブ
advice-function-member-p 13.12.1 アドバイスを操作するためのプリミティブ
advice-mapc 13.12.2 名前つき関数にたいするアドバイス
advice-member-p 13.12.2 名前つき関数にたいするアドバイス
advice-remove 13.12.2 名前つき関数にたいするアドバイス
advices, porting from defadvice 13.12.4 古いdefadviceを使用するコードの改良
advising functions 13.12 Emacs Lisp関数にたいするアドバイス
advising named functions 13.12.2 名前つき関数にたいするアドバイス
AEAD cipher 33.28 GnuTLS暗号化
affixation-function, in completion 21.6.7 プログラムされた補完
after-change notifier, for tree-sitter parse-tree 37.2 tree-sitterパーサーの使用
after-change-functions 33.34 フックの変更
after-change-major-mode-hook 24.2.6 モードフック
after-delete-frame-functions 30.7 フレームの削除
after-find-file 26.1.2 visitのためのサブルーチン
after-focus-change-function 30.10 入力のフォーカス
after-init-hook 42.1.2 initファイル
after-init-time 42.1.1 要約: スタートアップ時のアクション順序
after-insert-file-functions 26.13.3 漸次仕様
after-load-functions 16.10 ロードのためのフック
after-make-frame-functions 30.1 フレームの作成
after-pdump-load-hook E.1 Emacsのビルド
after-revert-hook 27.3 リバート
after-save-hook 26.2 バッファーの保存
after-setting-font-hook Appendix H 標準的なフック
after-string (overlay property) 41.9.2 オーバーレイのプロパティ
alias, for coding systems 34.10.1 コーディングシステムの基本概念
alias, for faces 41.12.6 フェイスを処理するための関数
alias, for functions 13.4 関数の定義
alias, for variables 12.15 変数のエイリアス
aligning header line, when line numbers are displayed 41.16.3 スペースにたいするピクセル指定
alist 5.8 連想リスト
alist vs. plist 5.9.1 プロパティリストと連想リスト
alist-get 5.8 連想リスト
all-completions 21.6.1 基本的な補完関数
all-threads 39.1 基本的なスレッド関数
allow-no-window, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
alnum character class, regexp 35.3.1.2 文字クラス
alpha character class, regexp 35.3.1.2 文字クラス
alpha, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
alpha-background, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
alt characters 2.4.3.5 その他の文字修飾ビット
alternatives, defining 22.2.5 コマンド候補からの選択
always 13.5 関数の呼び出し
amalgamating commands, and undo 33.9 アンドゥ
amalgamating-undo-limit 33.9 アンドゥ
ancestor directory of file 26.10 ディレクトリーのコンテンツ
and 11.3 組み合わせ条件の構築
and in rx 35.3.3.1 rxによるregexpの構築
animation 41.17.10 マルチフレームのイメージ
annotation-function, in completion 21.6.7 プログラムされた補完
anonymous face 41.12 フェイス
anonymous function 13.7 無名関数
anonymous node, tree-sitter 37.1 Tree-sitter Language Grammar
any in rx 35.3.3.1 rxによるregexpの構築
anychar in rx 35.3.3.1 rxによるregexpの構築
anything in rx 35.3.3.1 rxによるregexpの構築
apostrophe for quoting 10.3 クォート
apostrophe, quoting in documentation strings D.6 ドキュメント文字列のヒント
append 5.4 コンスセルおよびリストの構築
append-to-file 26.4 ファイルへの書き込み
apply 13.5 関数の呼び出し
apply, and debugging 19.1.11 デバッガの内部
apply-partially 13.5 関数の呼び出し
applying customizations 15.5 カスタマイゼーションの適用
apropos 25.6 ヘルプ関数
archive web server 43.5 アーカイブウェブサーバーとのインターフェイス
aref 6.3 配列を操作する関数
args, customization keyword 15.4.2 複合型
argument 13.1 関数とは?
argument binding 13.2.3 引数リストの機能
argument lists, features 13.2.3 引数リストの機能
arguments for shell commands 40.2 shell引数
arguments, interactive entry 22.2.1 interactiveの使用
arguments, reading 21 ミニバッファー
argv 42.1.4 コマンドライン引数
arith-error example 11.7.3.3 エラーを処理するコードの記述
arith-error in division 3.6 算術演算
arithmetic operations 3.6 算術演算
arithmetic shift 3.8 整数にたいするビット演算
array 6.2 配列
array elements 6.3 配列を操作する関数
arrayp 6.3 配列を操作する関数
ascii character class, regexp 35.3.1.2 文字クラス
ASCII character codes 2.4.3 文字型
ASCII control characters 41.23.1 通常の表示の慣習
ascii-case-table 4.10 caseテーブル
aset 6.3 配列を操作する関数
ash 3.8 整数にたいするビット演算
asin 3.9 標準的な数学関数
ask-user-about-lock 26.5 ファイルのロック
ask-user-about-supersession-threat 28.6 バッファーの変更時刻
asking the user questions 21.7 Yes-or-Noによる問い合わせ
assoc 5.8 連想リスト
assoc-default 5.8 連想リスト
assoc-delete-all 5.8 連想リスト
assoc-string 4.5 文字および文字列の比較
association list 5.8 連想リスト
assq 5.8 連想リスト
assq-delete-all 5.8 連想リスト
asynchronous native compilation, disable 18.2 ネイティブコンパイル関数
asynchronous subprocess 40.4 非同期プロセスの作成
atan 3.9 標準的な数学関数
atom 5.2 リストのための述語
atomic changes 33.33 グループのアトミックな変更
atomic windows 29.18 アトミックウィンドウ
atoms 2.4.6 コンスセルとリスト型
attributes of text 33.19 テキストのプロパティ
Auto Fill mode 33.14 オートfill
auto-coding-alist 34.10.5 デフォルトのコーディングシステム
auto-coding-functions 34.10.5 デフォルトのコーディングシステム
auto-coding-regexp-alist 34.10.5 デフォルトのコーディングシステム
auto-fill-chars 33.14 オートfill
auto-fill-function 33.14 オートfill
auto-hide-function, a frame parameter 30.4.3.6 フレームとの相互作用のためのパラメーター
auto-hscroll-mode 29.23 水平スクロール
auto-lower, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
auto-mode-alist 24.2.2 Emacsがメジャーモードを選択する方法
auto-raise, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
auto-raise-tool-bar-buttons 23.18.6 ツールバー
auto-resize-tool-bars 23.18.6 ツールバー
auto-save-default 27.2 自動保存
auto-save-file-name-p 27.2 自動保存
auto-save-file-name-transforms 27.2 自動保存
auto-save-hook 27.2 自動保存
auto-save-interval 27.2 自動保存
auto-save-list-file-name 27.2 自動保存
auto-save-list-file-prefix 27.2 自動保存
auto-save-mode 27.2 自動保存
auto-save-timeout 27.2 自動保存
auto-save-visited-file-name 27.2 自動保存
auto-selection of window 29.25 マウスによるウィンドウの自動選択
auto-window-vscroll 29.22 割り合いによる垂直スクロール
autoload 16.5 autoload
autoload 16.5 autoload
autoload by prefix 16.5.1 プレフィックスによるautoload
autoload cookie 16.5 autoload
autoload cookie, and safe values of variable 12.12 ファイルローカル変数
autoload errors 16.5 autoload
autoload object 13.1 関数とは?
autoload, when to use 16.5.2 autoloadを使用するケース
autoload-compute-prefixes 16.5.1 プレフィックスによるautoload
autoload-do-load 16.5 autoload
autoloadp 16.5 autoload
automatic face assignment 41.12.7 フェイスの自動割り当て
automatically buffer-local 12.11.1 バッファーローカル変数の概要

B
back-to-indentation 33.17.6 インデントにもとづくモーションコマンド
background-color, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
background-mode, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
backing store 30.26 ディスプレイ機能のテスト
backquote (list substitution) 10.4 バッククォート
backquote-style patterns 11.4.3 バッククォートスタイルパターン
backref in rx 35.3.3.1 rxによるregexpの構築
backslash in character constants 2.4.3.2 一般的なエスケープ構文
backslash in regular expressions 35.3.1.3 正規表現内のバッククラッシュ構文
backslash in strings 2.4.8.1 文字列の構文
backslash in symbols 2.4.4 シンボル型
backspace 2.4.3.1 基本的な文字構文
backtrace 19.1.11 デバッガの内部
backtrace buffer 19.1.8 バックトレース
backtrace from emacsclient’s --eval 19.1.1 エラーによるデバッガへのエンター
backtrace of thread 39.4 スレッドリスト
backtrace-debug 19.1.11 デバッガの内部
backtrace-frame 19.1.11 デバッガの内部
backtrace-on-redisplay-error 19.1.2 再表示エラーのデバッグ
backtracking 19.2.15.3 仕様でのバックトレース
backtracking and POSIX regular expressions 35.5 POSIX正規表現の検索
backtracking and regular expressions 35.3.1.1 正規表現内の特殊文字
backup file 27.1 ファイルのバックアップ
backup files, rename or copy 27.1.2 リネームかコピーのどちらでバックアップするか?
backup-buffer 27.1.1 バックアップファイルの作成
backup-by-copying 27.1.2 リネームかコピーのどちらでバックアップするか?
backup-by-copying-when-linked 27.1.2 リネームかコピーのどちらでバックアップするか?
backup-by-copying-when-mismatch 27.1.2 リネームかコピーのどちらでバックアップするか?
backup-by-copying-when-privileged-mismatch 27.1.2 リネームかコピーのどちらでバックアップするか?
backup-directory-alist 27.1.1 バックアップファイルの作成
backup-enable-predicate 27.1.1 バックアップファイルの作成
backup-file-name-p 27.1.4 バックアップファイルの命名
backup-inhibited 27.1.1 バックアップファイルの作成
backups and auto-saving 27 バックアップと自動保存
backward-button 41.20.5 ボタンのためのバッファーコマンド
backward-char 31.2.1 文字単位の移動
backward-delete-char-untabify 33.6 テキストの削除
backward-delete-char-untabify-method 33.6 テキストの削除
backward-list 31.2.6 釣り合いのとれたカッコを越えた移動
backward-prefix-chars 36.5 モーションと構文
backward-sexp 31.2.6 釣り合いのとれたカッコを越えた移動
backward-to-indentation 33.17.6 インデントにもとづくモーションコマンド
backward-up-list 31.2.6 釣り合いのとれたカッコを越えた移動
backward-word 31.2.2 単語単位の移動
backward-word-strictly 31.2.2 単語単位の移動
balance-windows 29.5 ウィンドウのリサイズ
balance-windows-area 29.5 ウィンドウのリサイズ
balanced parenthesis motion 31.2.6 釣り合いのとれたカッコを越えた移動
balancing parentheses 41.22 カッコの点滅
balancing window sizes 29.5 ウィンドウのリサイズ
bare symbol 9.6 位置をもつシンボル
bare-symbol 9.6 位置をもつシンボル
barf-if-buffer-read-only 28.7 読み取り専用のバッファー
base 64 encoding 33.25 Base 64エンコーディング
base buffer 28.11 インダイレクトバッファー
base coding system 34.10.1 コーディングシステムの基本概念
base direction of a paragraph 41.27 双方向テキストの表示
base for reading an integer 3.1 整数の基礎
base location, package archive 43.4 パッケージアーカイブの作成と保守
base remapping, faces 41.12.5 フェイスのリマップ
base type, in bindat specification 40.20.1 データレイアウトの記述
base64-decode-region 33.25 Base 64エンコーディング
base64-decode-string 33.25 Base 64エンコーディング
base64-encode-region 33.25 Base 64エンコーディング
base64-encode-string 33.25 Base 64エンコーディング
base64url-encode-region 33.25 Base 64エンコーディング
base64url-encode-string 33.25 Base 64エンコーディング
basic code (of input character) 22.7.1 キーボードイベント
basic faces 41.12.8 基本的なフェイス
batch mode 42.17 batchモード
batch-byte-compile 17.2 バイトコンパイル関数
batch-native-compile 18.1 ネイティブコンパイル関数
baud, in serial connections 40.19 シリアルポートとの対話
baud-rate 42.14 端末の出力
beep 41.24 ビープ
before point, insertion 33.4 テキストの挿入
before-change-functions 33.34 フックの変更
before-hack-local-variables-hook 12.12 ファイルローカル変数
before-init-hook 42.1.2 initファイル
before-init-time 42.1.1 要約: スタートアップ時のアクション順序
before-make-frame-hook 30.1 フレームの作成
before-revert-hook 27.3 リバート
before-save-hook 26.2 バッファーの保存
before-string (overlay property) 41.9.2 オーバーレイのプロパティ
beginning of line 31.2.4 テキスト行単位の移動
beginning of line in regexp 35.3.1.1 正規表現内の特殊文字
beginning-of-buffer 31.2.3 バッファー終端への移動
beginning-of-defun 31.2.6 釣り合いのとれたカッコを越えた移動
beginning-of-defun-function 31.2.6 釣り合いのとれたカッコを越えた移動
beginning-of-line 31.2.4 テキスト行単位の移動
bell 41.24 ビープ
bell character 2.4.3.1 基本的な文字構文
benchmark.el 19.5 プロファイリング
benchmarking 19.5 プロファイリング
best practices Appendix D ヒントと規約
bidi-display-reordering 41.27 双方向テキストの表示
bidi-find-overridden-directionality 41.27 双方向テキストの表示
bidi-paragraph-direction 41.27 双方向テキストの表示
bidi-paragraph-separate-re 41.27 双方向テキストの表示
bidi-paragraph-start-re 41.27 双方向テキストの表示
bidi-string-mark-left-to-right 41.27 双方向テキストの表示
bidirectional class of characters 34.6 文字のプロパティ
bidirectional display 41.27 双方向テキストの表示
bidirectional reordering 41.27 双方向テキストの表示
big endian, in bindat specification 40.20.1 データレイアウトの記述
bignum range 3.1 整数の基礎
bignump 3.3 数値のための述語
binary coding system 34.10.1 コーディングシステムの基本概念
binary I/O in batch mode 20.3 入力関数
bindat computed types 40.20.3 高度なデータレイアウト仕様
bindat functions 40.20.2 バイトのunpackとpackを行う関数
bindat packing and unpacking into arbitrary types 40.20.3 高度なデータレイアウト仕様
bindat type expression 40.20.1 データレイアウトの記述
bindat types 40.20.1 データレイアウトの記述
bindat, define new type forms 40.20.3 高度なデータレイアウト仕様
bindat-defmacro 40.20.3 高度なデータレイアウト仕様
bindat-get-field 40.20.2 バイトのunpackとpackを行う関数
bindat-ip-to-string 40.20.2 バイトのunpackとpackを行う関数
bindat-length 40.20.2 バイトのunpackとpackを行う関数
bindat-pack 40.20.2 バイトのunpackとpackを行う関数
bindat-type 40.20.1 データレイアウトの記述
bindat-unpack 40.20.2 バイトのunpackとpackを行う関数
binding arguments 13.2.3 引数リストの機能
binding local variables 12.3 ローカル変数
binding of a key 23.2 キーマップの基礎
bitmap-spec-p 41.12.1 フェイスの属性
bitmaps, fringe 41.13.4 フリンジのビットマップ
bitwise arithmetic 3.8 整数にたいするビット演算
blink-cursor-alist 30.4.3.9 カーソルのパラメーター
blink-matching-delay 41.22 カッコの点滅
blink-matching-open 41.22 カッコの点滅
blink-matching-paren 41.22 カッコの点滅
blink-matching-paren-distance 41.22 カッコの点滅
blink-paren-function 41.22 カッコの点滅
blinking parentheses 41.22 カッコの点滅
bobp 33.1 ポイント近傍のテキストを調べる
body height of a window 29.4 ウィンドウのサイズ
body of a window 29.1 Emacsウィンドウの基本概念
body of function 13.2.1 ラムダ式の構成要素
body size of a window 29.4 ウィンドウのサイズ
body width of a window 29.4 ウィンドウのサイズ
body-function, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
bol in rx 35.3.3.1 rxによるregexpの構築
bolp 33.1 ポイント近傍のテキストを調べる
bool-vector 6.7 ブールベクター
bool-vector length 6.1 シーケンス
bool-vector-count-consecutive 6.7 ブールベクター
bool-vector-count-population 6.7 ブールベクター
bool-vector-exclusive-or 6.7 ブールベクター
bool-vector-intersection 6.7 ブールベクター
bool-vector-not 6.7 ブールベクター
bool-vector-p 6.7 ブールベクター
bool-vector-set-difference 6.7 ブールベクター
bool-vector-subsetp 6.7 ブールベクター
bool-vector-union 6.7 ブールベクター
Bool-vectors 6.7 ブールベクター
boolean 1.3.2 nilt
booleanp 1.3.2 nilt
bootstrapping Emacs E.1 Emacsのビルド
border-color, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
border-width, a frame parameter 30.4.3.4 レイアウトのパラメーター
bos in rx 35.3.3.1 rxによるregexpの構築
bot in rx 35.3.3.1 rxによるregexpの構築
bottom dividers 41.15 ウィンドウディバイダー
bottom-divider, prefix key 22.8.1 キーシーケンス入力
bottom-divider-width, a frame parameter 30.4.3.4 レイアウトのパラメーター
bottom-visible, a frame parameter 30.4.3.7 マウスドラッグのパラメーター
boundp 12.4 変数がvoidのとき
bow in rx 35.3.3.1 rxによるregexpの構築
box diagrams, for lists 2.4.6.1 ボックスダイアグラムによるリストの描写
break 19.1 Lispデバッガ
breakpoints (Edebug) 19.2.6.1 Edebugのブレークポイント
bucket (in obarray) 9.3 シンボルの作成とintern
buffer 28 バッファー
buffer boundaries, indicating 41.13.2 フリンジのインジケーター
buffer contents 33 テキスト
buffer display 29.13 適切なウィンドウへのバッファーの表示
buffer display action alist 29.13.3 バッファー表示用のアクションalist
buffer display action function 29.13.2 バッファー表示用のアクション関数
buffer display action functions, precedence 29.13.5 アクション関数の優先順
buffer display conventions 29.13.6 バッファー表示の思想
buffer display display action 29.13.1 バッファーを表示するウィンドウの選択
buffer file name 28.4 バッファーのファイル名
buffer gap 28.13 バッファーのギャップ
buffer input stream 20.2 入力ストリーム
buffer internals E.9.1 バッファーの内部
buffer list 28.8 バッファーリスト
buffer modification 28.5 バッファーの変更
buffer names 28.3 バッファーの名前
buffer output stream 20.4 出力ストリーム
buffer point changed by Edebug 19.2.14.2 Edebugの表示の更新
buffer portion as string 33.2 バッファーのコンテンツを調べる
buffer position 31 ポジション
buffer text notation 1.3.6 バッファーテキストの表記
buffer, read-only 28.7 読み取り専用のバッファー
buffer-access-fontified-property 33.19.7 テキストプロパティのlazyな計算
buffer-access-fontify-functions 33.19.7 テキストプロパティのlazyな計算
buffer-auto-save-file-format 26.13.2 ラウンドトリップ仕様
buffer-auto-save-file-name 27.2 自動保存
buffer-backed-up 27.1.1 バックアップファイルの作成
buffer-base-buffer 28.11 インダイレクトバッファー
buffer-button-map 41.20.5 ボタンのためのバッファーコマンド
buffer-chars-modified-tick 28.5 バッファーの変更
buffer-disable-undo 33.10 アンドゥリストの保守
buffer-display-count 29.11 バッファーとウィンドウ
buffer-display-table 41.23.3 アクティブなディスプレイテーブル
buffer-display-time 29.11 バッファーとウィンドウ
buffer-enable-undo 33.10 アンドゥリストの保守
buffer-end 31.1 ポイント
buffer-end in rx 35.3.3.1 rxによるregexpの構築
buffer-file-coding-system 34.10.2 エンコーディングとI/O
buffer-file-format 26.13.2 ラウンドトリップ仕様
buffer-file-name 28.4 バッファーのファイル名
buffer-file-name 28.4 バッファーのファイル名
buffer-file-number 28.4 バッファーのファイル名
buffer-file-truename 28.4 バッファーのファイル名
buffer-hash 33.26 チェックサムとハッシュ
buffer-invisibility-spec 41.6 不可視のテキスト
buffer-list 28.8 バッファーリスト
buffer-list, a frame parameter 30.4.3.5 バッファーのパラメーター
buffer-list-update-hook 28.8 バッファーリスト
buffer-list-update-hook Appendix H 標準的なフック
buffer-list-update-hook in temporary buffers 28.2 カレントバッファー
buffer-live-p 28.10 バッファーのkill
buffer-local variables 12.11 バッファーローカル変数
buffer-local variables in modes 24.2.1 メジャーモードの慣習
buffer-local-boundp 12.11.2 バッファーローカルなバインディングの作成と削除
buffer-local-restore-state 24.3.3 マイナーモードの定義
buffer-local-set-state 24.3.3 マイナーモードの定義
buffer-local-value 12.11.2 バッファーローカルなバインディングの作成と削除
buffer-local-variables 12.11.2 バッファーローカルなバインディングの作成と削除
buffer-match-p 28.8 バッファーリスト
buffer-modified-p 28.5 バッファーの変更
buffer-modified-tick 28.5 バッファーの変更
buffer-name 28.3 バッファーの名前
buffer-name-history 21.4 ミニバッファーのヒストリー
buffer-narrowed-p 31.4 ナローイング
buffer-offer-save 28.10 バッファーのkill
buffer-predicate, a frame parameter 30.4.3.5 バッファーのパラメーター
buffer-quit-function Appendix H 標準的なフック
buffer-read-only 28.7 読み取り専用のバッファー
buffer-save-without-query 28.10 バッファーのkill
buffer-saved-size 27.2 自動保存
buffer-size 31.1 ポイント
buffer-stale-function 27.3 リバート
buffer-start in rx 35.3.3.1 rxによるregexpの構築
buffer-string 33.2 バッファーのコンテンツを調べる
buffer-substring 33.2 バッファーのコンテンツを調べる
buffer-substring-no-properties 33.2 バッファーのコンテンツを調べる
buffer-substring-with-bidi-context 41.27 双方向テキストの表示
buffer-swap-text 28.12 2つのバッファー間でのテキストの交換
buffer-text-pixel-size 41.10 表示されるテキストのサイズ
buffer-undo-list 33.9 アンドゥ
bufferp 28.1 バッファーの基礎
bufferpos-to-filepos 34.1 テキストの表現方法
buffers to display on frame 30.4.3.5 バッファーのパラメーター
buffers without undo information 28.3 バッファーの名前
buffers, controlled in windows 29.11 バッファーとウィンドウ
buffers, creating 28.9 バッファーの作成
buffers, killing 28.10 バッファーのkill
bugs 1.1 注意事項
bugs in this manual 1.1 注意事項
build details E.1 Emacsのビルド
building Emacs E.1 Emacsのビルド
building lists 5.4 コンスセルおよびリストの構築
built-in function 13.1 関数とは?
bump-use-time, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
bury-buffer 28.8 バッファーリスト
butlast 5.3 リスト要素へのアクセス
button (button property) 41.20.1 ボタンのプロパティ
button buffer commands 41.20.5 ボタンのためのバッファーコマンド
button properties 41.20.1 ボタンのプロパティ
button types 41.20.2 ボタンのタイプ
button-activate 41.20.4 ボタンの操作
button-at 41.20.4 ボタンの操作
button-down event 22.7.6 ボタンダウンイベント
button-end 41.20.4 ボタンの操作
button-face, customization keyword 15.4.4 型キーワード
button-get 41.20.4 ボタンの操作
button-has-type-p 41.20.4 ボタンの操作
button-label 41.20.4 ボタンの操作
button-map 41.20.1 ボタンのプロパティ
button-prefix, customization keyword 15.4.4 型キーワード
button-put 41.20.4 ボタンの操作
button-start 41.20.4 ボタンの操作
button-suffix, customization keyword 15.4.4 型キーワード
button-type 41.20.4 ボタンの操作
button-type-get 41.20.4 ボタンの操作
button-type-put 41.20.4 ボタンの操作
button-type-subtype-p 41.20.4 ボタンの操作
buttonize 41.20.3 ボタンの作成
buttons in buffers 41.20 ボタン
byte compilation 17 バイトコンパイル
byte compiler warnings, how to avoid D.5 コンパイラー警告を回避するためのヒント
byte packing and unpacking 40.20 バイト配列のpackとunpack
byte to string 34.3 テキスト表現の変換
byte-boolean-vars 12.16 値を制限された変数
byte-boolean-vars E.7 Emacsプリミティブの記述
byte-code 17 バイトコンパイル
byte-code function 17.7 バイトコード関数オブジェクト
byte-code object 17.7 バイトコード関数オブジェクト
byte-code-function-p 13.1 関数とは?
byte-compile 17.2 バイトコンパイル関数
byte-compile and byte-optimize, advising 13.12.5 アドバイスとバイトコード
byte-compile-debug 17.2 バイトコンパイル関数
byte-compile-dynamic 17.4 個々の関数のダイナミックロード
byte-compile-dynamic-docstrings 17.3 ドキュメント文字列とコンパイル
byte-compile-error-on-warn 17.6 コンパイラーのエラー
byte-compile-file 17.2 バイトコンパイル関数
byte-compiler errors 17.6 コンパイラーのエラー
byte-compiler warnings 17.6 コンパイラーのエラー
byte-compiling macros 14.3 マクロとバイトコンパイル
byte-compiling require 16.7 名前つき機能
byte-recompile-directory 17.2 バイトコンパイル関数
byte-to-position 34.1 テキストの表現方法
byte-to-string 34.3 テキスト表現の変換
bytes 4 文字列と文字
bytesize, in serial connections 40.19 シリアルポートとの対話

C
C programming language E.6 C方言
C-c 23.6 プレフィクスキー
C-g 22.11 quit
C-h 23.6 プレフィクスキー
C-M-x 19.2.2 Edebugのためのインストルメント
C-x 23.6 プレフィクスキー
C-x 4 23.6 プレフィクスキー
C-x 5 23.6 プレフィクスキー
C-x 6 23.6 プレフィクスキー
C-x C-a C-m 19.2.3 Edebugの実行モード
C-x RET 23.6 プレフィクスキー
C-x t 23.6 プレフィクスキー
C-x v 23.6 プレフィクスキー
C-x X = 19.2.13 カバレッジテスト
caaaar 5.3 リスト要素へのアクセス
caaadr 5.3 リスト要素へのアクセス
caaar 5.3 リスト要素へのアクセス
caadar 5.3 リスト要素へのアクセス
caaddr 5.3 リスト要素へのアクセス
caadr 5.3 リスト要素へのアクセス
caar 5.3 リスト要素へのアクセス
cadaar 5.3 リスト要素へのアクセス
cadadr 5.3 リスト要素へのアクセス
cadar 5.3 リスト要素へのアクセス
caddar 5.3 リスト要素へのアクセス
cadddr 5.3 リスト要素へのアクセス
caddr 5.3 リスト要素へのアクセス
cadr 5.3 リスト要素へのアクセス
calendrical computations 42.10 時間の計算
calendrical information 42.7 時刻の変換
call stack 19.1.11 デバッガの内部
call-interactively 22.3 インタラクティブな呼び出し
call-process 40.3 同期プロセスの作成
call-process, command-line arguments from minibuffer 40.2 shell引数
call-process-region 40.3 同期プロセスの作成
call-process-shell-command 40.3 同期プロセスの作成
call-shell-region 40.3 同期プロセスの作成
called-interactively-p 22.4 インタラクティブな呼び出しの区別
calling a function 13.5 関数の呼び出し
cancel-change-group 33.33 グループのアトミックな変更
cancel-debug-on-entry 19.1.4 関数呼び出しによるデバッガへのエンター
cancel-debug-on-variable-change 19.1.5 変数の変更時にデバッガにエンターする。
cancel-timer 42.11 遅延実行のためのタイマー
canonical character height 30.3.2 フレームのフォント
canonical character width 30.3.2 フレームのフォント
capitalization 4.9 Lispでの大文字小文字変換
capitalize 4.9 Lispでの大文字小文字変換
capitalize-region 33.18 大文字小文字の変更
capitalize-word 33.18 大文字小文字の変更
caption bar 30.3.1 フレームのレイアウト
capturing, tree-sitter node 37.5 tree-sitterノードにたいするパターンマッチング
car 5.3 リスト要素へのアクセス
car-safe 5.3 リスト要素へのアクセス
case conversion in buffers 33.18 大文字小文字の変更
case conversion in Lisp 4.9 Lispでの大文字小文字変換
case in replacements 35.6.1 マッチしたテキストの置換
case-fold, text property 21.2 ミニバッファーでのテキスト文字列の読み取り
case-fold-search 35.2 検索と大文字小文字
case-replace 35.2 検索と大文字小文字
case-table-p 4.10 caseテーブル
catch 11.7.1 明示的な非ローカル脱出: catchthrow
catch-all 24.7.2 パーサーベースのインデント
categories of characters 36.8 カテゴリー
category (overlay property) 41.9.2 オーバーレイのプロパティ
category (text property) 33.19.4 特殊な意味をもつプロパティ
category in rx 35.3.3.1 rxによるregexpの構築
category set 36.8 カテゴリー
category table 36.8 カテゴリー
category, regexp search for 35.3.1.3 正規表現内のバッククラッシュ構文
category-docstring 36.8 カテゴリー
category-set-mnemonics 36.8 カテゴリー
category-table 36.8 カテゴリー
category-table-p 36.8 カテゴリー
cdaaar 5.3 リスト要素へのアクセス
cdaadr 5.3 リスト要素へのアクセス
cdaar 5.3 リスト要素へのアクセス
cdadar 5.3 リスト要素へのアクセス
cdaddr 5.3 リスト要素へのアクセス
cdadr 5.3 リスト要素へのアクセス
cdar 5.3 リスト要素へのアクセス
cddaar 5.3 リスト要素へのアクセス
cddadr 5.3 リスト要素へのアクセス
cddar 5.3 リスト要素へのアクセス
cdddar 5.3 リスト要素へのアクセス
cddddr 5.3 リスト要素へのアクセス
cdddr 5.3 リスト要素へのアクセス
cddr 5.3 リスト要素へのアクセス
cdr 5.3 リスト要素へのアクセス
cdr-safe 5.3 リスト要素へのアクセス
ceiling 3.5 数値の変換
centering point 29.21 テキスト的なスクロール
change hooks 33.34 フックの変更
change hooks for a character 33.19.4 特殊な意味をもつプロパティ
change load-path at configure time E.1 Emacsのビルド
change-major-mode-after-body-hook 24.2.6 モードフック
change-major-mode-hook 12.11.2 バッファーローカルなバインディングの作成と削除
changing key bindings 23.12 キーバインディングの変更
changing text properties 33.19.2 テキストプロパティの変更
changing to another buffer 28.2 カレントバッファー
changing window size 29.5 ウィンドウのリサイズ
char in rx 35.3.3.1 rxによるregexpの構築
char-after 33.1 ポイント近傍のテキストを調べる
char-before 33.1 ポイント近傍のテキストを調べる
char-category-set 36.8 カテゴリー
char-charset 34.7 文字セット
char-code-property-description 34.6 文字のプロパティ
char-displayable-p 41.12.11 フォントセット
char-equal 4.5 文字および文字列の比較
char-from-name 34.5 文字コード
char-or-string-p 4.2 文字列のための述語
char-property-alias-alist 33.19.1 テキストプロパティを調べる
char-script-table 34.6 文字のプロパティ
char-syntax 36.3 構文テーブルの関数
char-table length 6.1 シーケンス
char-table-extra-slot 6.6 文字テーブル
char-table-p 6.6 文字テーブル
char-table-parent 6.6 文字テーブル
char-table-range 6.6 文字テーブル
char-table-subtype 6.6 文字テーブル
char-tables 6.6 文字テーブル
char-to-string 4.6 文字および文字列の変換
char-uppercase-p 41.10 表示されるテキストのサイズ
char-width 41.10 表示されるテキストのサイズ
char-width-table 34.6 文字のプロパティ
character alternative (in regexp) 35.3.1.1 正規表現内の特殊文字
character arrays 4 文字列と文字
character case 4.9 Lispでの大文字小文字変換
character categories 36.8 カテゴリー
character class in rx 35.3.3.1 rxによるregexpの構築
character class in rx 35.3.3.1 rxによるregexpの構築
character classes in regexp 35.3.1.2 文字クラス
character code conversion 34.10.1 コーディングシステムの基本概念
character codepoint 34.1 テキストの表現方法
character codes 34.5 文字コード
character event 22.7.1 キーボードイベント
character insertion 33.5 ユーザーレベルの挿入コマンド
character printing 25.5 ヘルプメッセージの文字記述
character properties 34.6 文字のプロパティ
character set, searching 34.8 文字セットのスキャン
character sets 34.7 文字セット
character to string 4.6 文字および文字列の変換
character translation tables 34.9 文字の変換
character width on display 41.10 表示されるテキストのサイズ
characterp 34.5 文字コード
characters 4 文字列と文字
characters for interactive codes 22.2.2 interactiveにたいするコード文字
characters, multi-byte 34 非ASCII文字
characters, representation in buffers and strings 34.1 テキストの表現方法
charset 34.7 文字セット
charset, coding systems to encode 34.10.3 Lispでのコーディングシステム
charset, text property on buffer text 34.10.7 明示的なエンコードとデコード
charset, text property on strings 34.10.7 明示的なエンコードとデコード
charset-after 34.8 文字セットのスキャン
charset-list 34.7 文字セット
charset-plist 34.7 文字セット
charset-priority-list 34.7 文字セット
charsetp 34.7 文字セット
charsets supported by a coding system 34.10.3 Lispでのコーディングシステム
check-coding-system 34.10.3 Lispでのコーディングシステム
check-coding-systems-region 34.10.3 Lispでのコーディングシステム
check-declare-directory 13.16 コンパイラーへの定義済み関数の指示
check-declare-file 13.16 コンパイラーへの定義済み関数の指示
checkdoc Appendix D ヒントと規約
checkdoc-current-buffer Appendix D ヒントと規約
checkdoc-file Appendix D ヒントと規約
checkdoc-minor-mode D.6 ドキュメント文字列のヒント
checkdoc-package-keywords D.8 Emacsライブラリーのヘッダーの慣習
checkdoc-package-keywords-flag D.8 Emacsライブラリーのヘッダーの慣習
child frames 30.14 子フレーム
child process 40 プロセス
child window 29.2 ウィンドウとフレーム
child-frame-border-width, a frame parameter 30.4.3.4 レイアウトのパラメーター
child-frame-parameters, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
choice, customization types 15.4.3 リストへのスプライス
cipher, AEAD 33.28 GnuTLS暗号化
cipher, symmetric 33.28 GnuTLS暗号化
circular list 5.1 リストとコンスセル
circular structure, read syntax 2.6 循環オブジェクトの読み取り構文
cl 1.2 Lispの歴史
CL note—allocate more storage E.3 ガーベージコレクション
CL note—case of letters 2.4.4 シンボル型
CL note—default optional arg 13.2.3 引数リストの機能
CL note—interning existing symbol 9.3 シンボルの作成とintern
CL note—lack union, intersection 5.7 集合としてのリストの使用
CL note—no continuable errors 11.7.3.1 エラーをシグナルする方法
CL note—no setf functions 12.17.2 新たなsetfフォーム
CL note—only throw in Emacs 11.7.1 明示的な非ローカル脱出: catchthrow
CL note—rplaca vs setcar 5.6 既存のリスト構造の変更
CL note—special forms compared 10.2.7 スペシャルフォーム
CL note—symbol in obarrays 9.3 シンボルの作成とintern
cl-call-next-method 13.8 ジェネリック関数
cl-defgeneric 13.8 ジェネリック関数
cl-defmethod 13.8 ジェネリック関数
cl-next-method-p 13.8 ジェネリック関数
cl-old-struct-compat-mode 7.2 後方互換
classification of file types 26.6.2 ファイル種別の区別
classifying events 22.7.14 イベントの分類
clean-mode 24.2 メジャーモード
cleanup forms 11.7.4 非ローカル脱出のクリーンアップ
clear-abbrev-table 38.1 abbrevテーブル
clear-image-cache 41.17.11 イメージキャッシュ
clear-message-function 41.4.1 エコーエリアへのメッセージの表示
clear-string 4.4 文字列の変更
clear-this-command-keys 22.5 コマンドループからの情報
clear-visited-file-modtime 28.6 バッファーの変更時刻
click event 22.7.4 クリックイベント
clickable buttons in buffers 41.20 ボタン
clickable text 33.19.8 クリック可能なテキストの定義
clipboard 30.20 ウィンドウシステムによる選択
clipboard support (for MS-Windows) 30.20 ウィンドウシステムによる選択
clone-indirect-buffer 28.11 インダイレクトバッファー
clone-of, a window parameter 29.27 ウィンドウのパラメーター
CLOS 13.8 ジェネリック関数
closepath 41.17.6 SVGイメージ
closure 13.10 クロージャ
closures, example of using 12.10.3 レキシカルバインディング
clrhash 8.2 ハッシュテーブルへのアクセス
coded character set 34.7 文字セット
codepoint, largest value 34.5 文字コード
codes, interactive, description of 22.2.2 interactiveにたいするコード文字
codespace 34.1 テキストの表現方法
coding conventions in Emacs Lisp D.1 Emacs Lispコーディング規約
coding standards Appendix D ヒントと規約
coding system 34.10 コーディングシステム
coding system for operation 34.10.6 単一の操作にたいするコーディングシステムの指定
coding system, automatically determined 34.10.5 デフォルトのコーディングシステム
coding system, validity check 34.10.3 Lispでのコーディングシステム
coding systems for encoding a string 34.10.3 Lispでのコーディングシステム
coding systems for encoding region 34.10.3 Lispでのコーディングシステム
coding systems, priority 34.10.6 単一の操作にたいするコーディングシステムの指定
coding-system-aliases 34.10.1 コーディングシステムの基本概念
coding-system-change-eol-conversion 34.10.3 Lispでのコーディングシステム
coding-system-change-text-conversion 34.10.3 Lispでのコーディングシステム
coding-system-charset-list 34.10.3 Lispでのコーディングシステム
coding-system-eol-type 34.10.3 Lispでのコーディングシステム
coding-system-for-read 34.10.6 単一の操作にたいするコーディングシステムの指定
coding-system-for-write 34.10.6 単一の操作にたいするコーディングシステムの指定
coding-system-get 34.10.1 コーディングシステムの基本概念
coding-system-list 34.10.3 Lispでのコーディングシステム
coding-system-p 34.10.3 Lispでのコーディングシステム
coding-system-priority-list 34.10.6 単一の操作にたいするコーディングシステムの指定
coding-system-require-warning 34.10.6 単一の操作にたいするコーディングシステムの指定
collapse-delayed-warnings 41.5.4 遅延された警告
color names 30.23 カラー名
color-dark-p 30.23 カラー名
color-defined-p 30.23 カラー名
color-gray-p 30.23 カラー名
color-name-to-rgb 30.23 カラー名
color-supported-p 30.23 カラー名
color-values 30.23 カラー名
colors on text terminals 30.24 テキスト端末のカラー
column width 30.3.2 フレームのフォント
column-0 24.7.2 パーサーベースのインデント
columns 33.16 列を数える
COM1 40.19 シリアルポートとの対話
combine-after-change-calls 33.34 フックの変更
combine-and-quote-strings 40.2 shell引数
combine-change-calls 33.34 フックの変更
combining conditions 11.3 組み合わせ条件の構築
command 13.1 関数とは?
command descriptions 1.3.7.1 関数の説明例
command history 22.15 コマンドのヒストリー
command in keymap 23.10 キーの照合
command loop 22 コマンドループ
command loop variables 22.5 コマンドループからの情報
command loop, recursive 22.13 再帰編集
command-completion-default-include-p 22.3 インタラクティブな呼び出し
command-debug-status 19.1.11 デバッガの内部
command-error-function 11.7.3.2 Emacsがエラーを処理する方法
command-execute 22.3 インタラクティブな呼び出し
command-history 22.15 コマンドのヒストリー
command-line 42.1.4 コマンドライン引数
command-line arguments 42.1.4 コマンドライン引数
command-line options 42.1.4 コマンドライン引数
command-line-args 42.1.4 コマンドライン引数
command-line-args-left 42.1.4 コマンドライン引数
command-line-functions 42.1.4 コマンドライン引数
command-line-processed 42.1.4 コマンドライン引数
command-query 22.14 コマンドの無効化
command-remapping 23.14 コマンドのリマップ
command-switch-alist 42.1.4 コマンドライン引数
commandp 22.3 インタラクティブな呼び出し
commandp example 21.6.4 高レベルの補完関数
commands, defining 22.2 コマンドの定義
commands, mode-specific 22.2.4 コマンドにたいするモード指定
commands, specify as mode-specific 22.2.4 コマンドにたいするモード指定
comment style 36.2.2 構文フラグ
comment syntax 36.2.1 構文クラスのテーブル
comment-auto-fill-only-comments 33.14 オートfill
comment-end 24.7.2 パーサーベースのインデント
comment-end-can-be-escaped 36.6.5 パースを制御するためのパラメーター
comment-start 24.7.2 パーサーベースのインデント
commentary, in a Lisp library D.8 Emacsライブラリーのヘッダーの慣習
comments 2.3 コメント
comments, Lisp convention for D.7 コメント記述のヒント
Common Lisp 1.2 Lispの歴史
comp-native-version-dir 16.3 ライブラリー検索
compare tree-sitter syntax nodes 37.4 ノード情報へのアクセス
compare-buffer-substrings 33.3 テキストの比較
compare-strings 4.5 文字および文字列の比較
comparing buffer text 33.3 テキストの比較
comparing file modification time 28.6 バッファーの変更時刻
comparing numbers 3.4 数値の比較
comparing time values 42.10 時間の計算
compatibility, between modules and Emacs E.8.1 モジュールの初期化コード
compilation (Emacs Lisp) 17 バイトコンパイル
compilation functions 17.2 バイトコンパイル関数
compilation to native code (Emacs Lisp) 18 Lispからネイティブコードへのコンパイル
compile-defun 17.2 バイトコンパイル関数
compile-time constant 17.5 コンパイル中の評価
compiled function 17.7 バイトコード関数オブジェクト
compiled-function-p 13.1 関数とは?
compiler errors 17.6 コンパイラーのエラー
compiler macro 13.15 declareフォーム
compiler macros, advising 13.12.5 アドバイスとバイトコード
compiling tree-sitter queries 37.5 tree-sitterノードにたいするパターンマッチング
complete key 23.2 キーマップの基礎
completing-read 21.6.2 補完とミニバッファー
completing-read-function 21.6.2 補完とミニバッファー
completion 21.6 補完
completion styles 21.6.6 補完変数
completion table 21.6.1 基本的な補完関数
completion table, modifying 21.6.1 基本的な補完関数
completion tables, combining 21.6.1 基本的な補完関数
completion, file name 26.9.6 ファイル名の補完
completion-at-point 21.6.8 通常バッファーでの補完
completion-at-point-functions 21.6.8 通常バッファーでの補完
completion-auto-help 21.6.3 補完を行うミニバッファーコマンド
completion-boundaries 21.6.1 基本的な補完関数
completion-category-overrides 21.6.6 補完変数
completion-extra-properties 21.6.6 補完変数
completion-ignore-case 21.6.1 基本的な補完関数
completion-ignored-extensions 26.9.6 ファイル名の補完
completion-in-region 21.6.8 通常バッファーでの補完
completion-regexp-list 21.6.1 基本的な補完関数
completion-styles 21.6.6 補完変数
completion-styles-alist 21.6.6 補完変数
completion-table-case-fold 21.6.1 基本的な補完関数
completion-table-dynamic 21.6.7 プログラムされた補完
completion-table-in-turn 21.6.1 基本的な補完関数
completion-table-merge 21.6.1 基本的な補完関数
completion-table-subvert 21.6.1 基本的な補完関数
completion-table-with-cache 21.6.7 プログラムされた補完
completion-table-with-predicate 21.6.1 基本的な補完関数
completion-table-with-quoting 21.6.1 基本的な補完関数
completion-table-with-terminator 21.6.1 基本的な補完関数
complex arguments 21 ミニバッファー
complex command 22.15 コマンドのヒストリー
composite type, in bindat specification 40.20.1 データレイアウトの記述
composite types (customization) 15.4.2 複合型
composition (text property) 33.19.4 特殊な意味をもつプロパティ
composition property, and point display 22.6 コマンド後のポイントの調整
compute-motion 31.2.5 スクリーン行単位の移動
computed documentation string 13.2.4 関数のドキュメント文字列
concat 4.3 文字列の作成
concatenating bidirectional strings 41.27 双方向テキストの表示
concatenating lists 5.6.3 リストを再配置する関数
concatenating strings 4.3 文字列の作成
concurrency 39 スレッド
cond 11.2 条件
condition name 11.7.3.4 エラーシンボルとエラー条件
condition-case 11.7.3.3 エラーを処理するコードの記述
condition-case-unless-debug 11.7.3.3 エラーを処理するコードの記述
condition-mutex 39.3 条件変数
condition-name 39.3 条件変数
condition-notify 39.3 条件変数
condition-variable-p 39.3 条件変数
condition-wait 39.3 条件変数
conditional evaluation 11.2 条件
conditional selection of windows 29.10 ウィンドウのサイクル順
confirm-kill-processes 40.11 exit前の問い合わせ
connection local profiles 12.14.1 接続ローカルなプロファイル
connection local variables 12.14 接続ローカル変数
connection local variables, applying 12.14.2 接続ローカル変数の適用
connection-local-criteria-alist 12.14.1 接続ローカルなプロファイル
connection-local-default-application 12.14.2 接続ローカル変数の適用
connection-local-get-profile-variables 12.14.1 接続ローカルなプロファイル
connection-local-profile-alist 12.14.1 接続ローカルなプロファイル
connection-local-profile-name-for-setq 12.14.2 接続ローカル変数の適用
connection-local-set-profile-variables 12.14.1 接続ローカルなプロファイル
connection-local-set-profiles 12.14.1 接続ローカルなプロファイル
cons 5.4 コンスセルおよびリストの構築
cons cells 5.4 コンスセルおよびリストの構築
cons-cells-consed E.5 メモリー使用量
consing 5.4 コンスセルおよびリストの構築
consp 5.2 リストのための述語
constant variables 12.2 変更不可な変数
constant variables 12.5 グローバル変数の定義
constrain-to-field 33.19.9 フィールドの定義と使用
content directory, package 43.1 パッケージ化の基礎
context menus, for a major mode 24.2.1 メジャーモードの慣習
context-menu-functions 24.2.1 メジャーモードの慣習
continuation lines 41.3 切り詰め
continue-process 40.8 プロセスへのシグナルの送信
control character key constants 23.13 低レベルなキーバインディング
control character printing 25.5 ヘルプメッセージの文字記述
control characters 2.4.3.3 コントロール文字構文
control characters in display 41.23.1 通常の表示の慣習
control characters, reading 22.8.5 クォートされた文字の入力
control structures 11 制御構造
control-ja.texi.po 12.5 グローバル変数の定義
Control-X-prefix 23.6 プレフィクスキー
controller part, model/view/controller 41.21.2 抽象ディスプレイの例
controlling terminal 42.2.2 Emacsのサスペンド
controlling-tty-p 42.2.2 Emacsのサスペンド
conventions for writing major modes 24.2.1 メジャーモードの慣習
conventions for writing minor modes 24.3.1 マイナーモード記述の規約
conversion of strings 4.6 文字および文字列の変換
convert buffer position to file byte 34.1 テキストの表現方法
convert file byte to buffer position 34.1 テキストの表現方法
convert sequence to another type 6.1 シーケンス
convert-standard-filename 26.9.7 標準的なファイル名
converting file names from/to MS-Windows syntax 26.9 ファイルの名前
converting numbers 3.5 数値の変換
coordinate, relative to frame 29.24 座標とウィンドウ
Coordinated Universal Time 42.5 時刻
coordinates-in-window-p 29.24 座標とウィンドウ
copy-abbrev-table 38.1 abbrevテーブル
copy-alist 5.8 連想リスト
copy-category-table 36.8 カテゴリー
copy-directory 26.11 ディレクトリーの作成・コピー・削除
copy-file 26.7 ファイルの名前と属性の変更
copy-hash-table 8.4 ハッシュテーブルのためのその他関数
copy-keymap 23.4 キーマップの作成
copy-marker 32.3 マーカーを作成する関数
copy-overlay 41.9.1 オーバーレイの管理
copy-region-as-kill 33.8.2 kill用の関数
copy-sequence 6.1 シーケンス
copy-syntax-table 36.3 構文テーブルの関数
copy-tree 5.4 コンスセルおよびリストの構築
copying alists 5.8 連想リスト
copying bidirectional text, preserve visual order 41.27 双方向テキストの表示
copying files 26.7 ファイルの名前と属性の変更
copying lists 5.4 コンスセルおよびリストの構築
copying sequences 6.1 シーケンス
copying strings 4.3 文字列の作成
copying vectors 6.5 ベクターのための関数
copysign 3.2 浮動小数点数の基礎
copy_string_contents E.8.3 Lisp・モジュール間の値変換
cos 3.9 標準的な数学関数
count-lines 31.2.4 テキスト行単位の移動
count-loop 1.3.7.1 関数の説明例
count-screen-lines 31.2.5 スクリーン行単位の移動
count-words 31.2.4 テキスト行単位の移動
counting columns 33.16 列を数える
counting set bits 3.8 整数にたいするビット演算
coverage testing 19.4 カバレッジテスト
coverage testing (Edebug) 19.2.13 カバレッジテスト
create subprocess 40.1 サブプロセスを作成する関数
create-file-buffer 26.1.2 visitのためのサブルーチン
create-fontset-from-fontset-spec 41.12.11 フォントセット
create-image 41.17.8 イメージの定義
create-lockfiles 26.5 ファイルのロック
creating buffers 28.9 バッファーの作成
creating hash tables 8.1 ハッシュテーブルの作成
creating keymaps 23.4 キーマップの作成
creating markers 32.3 マーカーを作成する関数
creating strings 4.3 文字列の作成
creating tree-sitter parsers 37.2 tree-sitterパーサーの使用
creating, copying and deleting directories 26.11 ディレクトリーの作成・コピー・削除
cryptographic hash 33.26 チェックサムとハッシュ
cryptographic hash 33.28 GnuTLS暗号化
ctl-arrow 41.23.1 通常の表示の慣習
ctl-x-4-map 23.6 プレフィクスキー
ctl-x-5-map 23.6 プレフィクスキー
ctl-x-map 23.6 プレフィクスキー
ctl-x-r-map Appendix G 標準的なキーマップ
curly quotes 25.4 テキストのクォートスタイル
curly quotes D.6 ドキュメント文字列のヒント
curly quotes, in formatted messages 4.7 文字列のフォーマット
current binding 12.3 ローカル変数
current buffer 28.2 カレントバッファー
current buffer mark 32.7 マーク
current buffer point and mark (Edebug) 19.2.14.2 Edebugの表示の更新
current buffer position 31.1 ポイント
current command 22.5 コマンドループからの情報
current stack frame 19.1.8 バックトレース
current-active-maps 23.7 アクティブなキーマップ
current-bidi-paragraph-direction 41.27 双方向テキストの表示
current-buffer 28.2 カレントバッファー
current-case-table 4.10 caseテーブル
current-column 33.16 列を数える
current-cpu-time 42.5 時刻
current-fill-column 33.12 fillのマージン
current-frame-configuration 30.13 フレーム構成
current-global-map 23.9 アクティブなキーマップの制御
current-idle-time 42.12 アイドルタイマー
current-indentation 33.17.1 インデント用のプリミティブ
current-input-method 34.11 入力メソッド
current-input-mode 42.13.1 入力のモード
current-justification 33.11 fill
current-kill 33.8.5 低レベルのkillリング
current-left-margin 33.12 fillのマージン
current-local-map 23.9 アクティブなキーマップの制御
current-message 41.4.1 エコーエリアへのメッセージの表示
current-minibuffer-command 22.5 コマンドループからの情報
current-minor-mode-maps 23.9 アクティブなキーマップの制御
current-prefix-arg 22.12 プレフィクスコマンド引数
current-thread 39.1 基本的なスレッド関数
current-time 42.5 時刻
current-time-list 42.5 時刻
current-time-string 42.5 時刻
current-time-zone 42.6 タイムゾーンのルール
current-window-configuration 29.26 ウィンドウの構成
current-word 33.2 バッファーのコンテンツを調べる
currying 13.5 関数の呼び出し
cursor 29.19 ウィンドウとポイント
cursor (text property) 33.19.4 特殊な意味をもつプロパティ
cursor position for display properties and overlays 33.19.4 特殊な意味をもつプロパティ
cursor, and frame parameters 30.4.3.9 カーソルのパラメーター
cursor, fringe 41.13.3 フリンジのカーソルFrin
cursor-color, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
cursor-face (text property) 33.19.4 特殊な意味をもつプロパティ
cursor-face-highlight-mode 33.19.4 特殊な意味をもつプロパティ
cursor-face-highlight-nonselected-window 33.19.4 特殊な意味をもつプロパティ
cursor-in-echo-area 41.4.4 エコーエリアのカスタマイズ
cursor-in-non-selected-windows 30.4.3.9 カーソルのパラメーター
cursor-intangible (text property) 33.19.4 特殊な意味をもつプロパティ
cursor-intangible-mode 33.19.4 特殊な意味をもつプロパティ
cursor-sensor-functions (text property) 33.19.4 特殊な意味をもつプロパティ
cursor-sensor-inhibit 33.19.4 特殊な意味をもつプロパティ
cursor-sensor-mode 33.19.4 特殊な意味をもつプロパティ
cursor-type 30.4.3.9 カーソルのパラメーター
cursor-type 30.4.3.9 カーソルのパラメーター
cursor-type, a frame parameter 30.4.3.9 カーソルのパラメーター
curved quotes 25.4 テキストのクォートスタイル
curved quotes D.6 ドキュメント文字列のヒント
curved quotes, in formatted messages 4.7 文字列のフォーマット
curveto 41.17.6 SVGイメージ
custom ‘%’-sequence in format 4.8 カスタムフォーマット文字列
custom format string 4.8 カスタムフォーマット文字列
custom themes 15.6 Customテーマ
custom-add-frequent-value 15.3 カスタマイゼーション変数の定義
custom-group property 15.2 カスタマイゼーショングループの定義
custom-initialize-delay E.1 Emacsのビルド
custom-known-themes 15.6 Customテーマ
custom-reevaluate-setting 15.3 カスタマイゼーション変数の定義
custom-set-faces 15.5 カスタマイゼーションの適用
custom-set-variables 15.5 カスタマイゼーションの適用
custom-theme-p 15.6 Customテーマ
custom-theme-set-faces 15.6 Customテーマ
custom-theme-set-variables 15.6 Customテーマ
custom-unlispify-remove-prefixes 15.2 カスタマイゼーショングループの定義
custom-variable-history 21.4 ミニバッファーのヒストリー
custom-variable-p 15.3 カスタマイゼーション変数の定義
customizable variables, how to define 15.3 カスタマイゼーション変数の定義
customization groups, defining 15.2 カスタマイゼーショングループの定義
customization item 15 カスタマイゼーション設定
customization keywords 15.1 一般的なキーワードアイテム
customization types 15.4 カスタマイゼーション型
customization types, define new 15.4.5 新たな型の定義
customize-package-emacs-version-alist 15.1 一般的なキーワードアイテム
customized-face (face symbol property) 41.12.2 フェイスの定義
cycle-sort-function, in completion 21.6.7 プログラムされた補完
cyclic ordering of windows 29.10 ウィンドウのサイクル順
cygwin-convert-file-name-from-windows 26.9 ファイルの名前
cygwin-convert-file-name-to-windows 26.9 ファイルの名前

D
dangling symlinks, testing for existence 26.6.1 アクセシビリティのテスト
data layout specification 40.20.1 データレイアウトの記述
data type 2 Lispのデータ型
data-directory 25.6 ヘルプ関数
database access, SQLite 33.29 データベース
database object 33.29 データベース
datagrams 40.16 データグラム
date-days-in-month 42.10 時間の計算
date-leap-year-p 42.10 時間の計算
date-ordinal-to-time 42.10 時間の計算
date-to-time 42.8 時刻のパースとフォーマット
deactivate-mark 32.7 マーク
deactivate-mark 32.7 マーク
deactivate-mark-hook 32.7 マーク
debug 19.1.10 デバッガの呼び出し
debug-allow-recursive-debug 19.1.1 エラーによるデバッガへのエンター
debug-allow-recursive-debug 19.1.9 デバッガのコマンド
debug-ignored-errors 19.1.1 エラーによるデバッガへのエンター
debug-on-entry 19.1.4 関数呼び出しによるデバッガへのエンター
debug-on-error 19.1.1 エラーによるデバッガへのエンター
debug-on-error use 11.7.3.2 Emacsがエラーを処理する方法
debug-on-event 19.1.1 エラーによるデバッガへのエンター
debug-on-message 19.1.1 エラーによるデバッガへのエンター
debug-on-next-call 19.1.11 デバッガの内部
debug-on-quit 19.1.3 無限ループのデバッグ
debug-on-signal 19.1.1 エラーによるデバッガへのエンター
debug-on-variable-change 19.1.5 変数の変更時にデバッガにエンターする。
debugger 19.1.11 デバッガの内部
debugger command list 19.1.9 デバッガのコマンド
debugger for Emacs Lisp 19.1 Lispデバッガ
debugger, explicit entry 19.1.6 明示的なデバッガへのエントリー
debugger-bury-or-kill 19.1.7 デバッガの使用
debugger-stack-frame-as-list 19.1.11 デバッガの内部
debugging changes to variables 19.1.5 変数の変更時にデバッガにエンターする。
debugging errors 19.1.1 エラーによるデバッガへのエンター
debugging font-lock 24.6.4 Font Lockのその他の変数
debugging invalid Lisp syntax 19.3 無効なLisp構文のデバッグ
debugging lisp programs 19 Lispプログラムのデバッグ
debugging redisplay errors 19.1.2 再表示エラーのデバッグ
debugging specific functions 19.1.4 関数呼び出しによるデバッガへのエンター
declare 13.15 declareフォーム
declare 13.15 declareフォーム
declare-function 13.16 コンパイラーへの定義済み関数の指示
declare-function 13.16 コンパイラーへの定義済み関数の指示
declaring functions 13.16 コンパイラーへの定義済み関数の指示
decode process output 40.9.3 プロセス出力のデコード
decode-char 34.7 文字セット
decode-coding-inserted-region 34.10.7 明示的なエンコードとデコード
decode-coding-region 34.10.7 明示的なエンコードとデコード
decode-coding-string 34.10.7 明示的なエンコードとデコード
decode-time 42.7 時刻の変換
decoding file formats 26.13 ファイルのフォーマット変換
decoding in coding systems 34.10.7 明示的なエンコードとデコード
decrement field of register 2.4.6 コンスセルとリスト型
dedicated window 29.15 専用のウィンドウ
dedicated, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
def-edebug-elem-spec 19.2.15.2 仕様リスト
def-edebug-spec 19.2.15.1 マクロ呼び出しのインストルメント
defadvice 13.12.4 古いdefadviceを使用するコードの改良
defalias 13.4 関数の定義
defalias-fset-function property 13.4 関数の定義
default argument string 22.2.2 interactiveにたいするコード文字
default character height 30.3.2 フレームのフォント
default character size 30.3.2 フレームのフォント
default character width 30.3.2 フレームのフォント
default coding system 34.10.5 デフォルトのコーディングシステム
default coding system, functions to determine 34.10.5 デフォルトのコーディングシステム
default filter function of a process 40.9.2 プロセスのフィルター関数
default font 30.3.2 フレームのフォント
default height of character 30.3.2 フレームのフォント
default init file 42.1.2 initファイル
default key binding 23.3 キーマップのフォーマット
default sentinel function of a process 40.10 センチネル: プロセス状態の変更の検知
default value 12.11.3 バッファーローカル変数のデフォルト値
default value of char-table 6.6 文字テーブル
default width of character 30.3.2 フレームのフォント
default-boundp 12.11.3 バッファーローカル変数のデフォルト値
default-directory 26.9.4 ファイル名を展開する関数
default-file-modes 26.7 ファイルの名前と属性の変更
default-font-height 41.12.12 低レベルのフォント表現
default-font-width 41.12.12 低レベルのフォント表現
default-frame-alist 30.4.2 フレームの初期パラメーター
default-input-method 34.11 入力メソッド
default-justification 33.11 fill
default-minibuffer-frame 30.9 ミニバッファーとフレーム
default-process-coding-system 34.10.5 デフォルトのコーディングシステム
default-text-properties 33.19.1 テキストプロパティを調べる
default-toplevel-value 12.11.3 バッファーローカル変数のデフォルト値
default-value 12.11.3 バッファーローカル変数のデフォルト値
default.el 42.1.1 要約: スタートアップ時のアクション順序
defconst 12.5 グローバル変数の定義
defcustom 15.3 カスタマイゼーション変数の定義
deferred evaluation 10.6 遅延されたLazy評価
defface 41.12.2 フェイスの定義
defgroup 15.2 カスタマイゼーショングループの定義
defimage 41.17.8 イメージの定義
define customization group 15.2 カスタマイゼーショングループの定義
define customization options 15.3 カスタマイゼーション変数の定義
define hash comparisons 8.3 ハッシュの比較の定義
define image 41.17.8 イメージの定義
define new bindat type forms 40.20.3 高度なデータレイアウト仕様
define new customization types 15.4.5 新たな型の定義
define-abbrev 38.2 abbrevの定義
define-abbrev-table 38.1 abbrevテーブル
define-advice 13.12.2 名前つき関数にたいするアドバイス
define-alternatives 22.2.5 コマンド候補からの選択
define-button-type 41.20.2 ボタンのタイプ
define-category 36.8 カテゴリー
define-derived-mode 24.2.4 派生モードの定義
define-error 11.7.3.4 エラーシンボルとエラー条件
define-error 11.7.3.4 エラーシンボルとエラー条件
define-fringe-bitmap 41.13.5 フリンジビットマップのカスタマイズ
define-generic-mode 24.2.8 ジェネリックモード
define-globalized-minor-mode 24.3.3 マイナーモードの定義
define-hash-table-test 8.3 ハッシュの比較の定義
define-icon 41.18 アイコン
define-inline 13.14 インライン関数Inli
define-key 23.13 低レベルなキーバインディング
define-key-after 23.13 低レベルなキーバインディング
define-keymap 23.4 キーマップの作成
define-minor-mode 24.3.3 マイナーモードの定義
define-multisession-variable 12.18 マルチセッション変数
define-obsolete-face-alias 41.12.6 フェイスを処理するための関数
define-obsolete-function-alias 13.13 関数の陳腐化の宣言
define-obsolete-variable-alias 12.15 変数のエイリアス
define-package 43.3 複数ファイルのパッケージ
define-prefix-command 23.6 プレフィクスキー
define-short-documentation-group 25.7 ドキュメントのグループ
defined-colors 30.23 カラー名
defining a function 13.4 関数の定義
defining abbrevs 38.2 abbrevの定義
defining commands 22.2 コマンドの定義
defining customization variables in C E.7 Emacsプリミティブの記述
defining faces 41.12.2 フェイスの定義
defining functions dynamically 13.4 関数の定義
defining Lisp variables in C E.7 Emacsプリミティブの記述
defining macros 14.4 マクロの定義
defining menus 23.18.1 メニューの定義
defining tokens, SMIE 24.7.1.4 トークンの定義
defining-kbd-macro 22.16 キーボードマクロ
definition-prefixes 16.5.1 プレフィックスによるautoload
definitions of symbols 9.2 シンボルの定義
defmacro 14.4 マクロの定義
defsubr, Lisp symbol for a primitive E.7 Emacsプリミティブの記述
defsubst 13.14 インライン関数Inli
deftheme 15.6 Customテーマ
defun 13.4 関数の定義
DEFUN, C macro to define Lisp primitives E.7 Emacsプリミティブの記述
defun-prompt-regexp 31.2.6 釣り合いのとれたカッコを越えた移動
defvar 12.5 グローバル変数の定義
defvar-keymap 23.4 キーマップの作成
defvar-local 12.11.2 バッファーローカルなバインディングの作成と削除
defvaralias 12.15 変数のエイリアス
DEFVAR_INT, DEFVAR_LISP, DEFVAR_BOOL, DEFSYM E.7 Emacsプリミティブの記述
delay-mode-hooks 24.2.6 モードフック
delay-warning 41.5.4 遅延された警告
delayed warnings 41.5.4 遅延された警告
delayed-warnings-hook 41.5.4 遅延された警告
delayed-warnings-hook Appendix H 標準的なフック
delayed-warnings-list 41.5.4 遅延された警告
delete 5.7 集合としてのリストの使用
delete-and-extract-region 33.6 テキストの削除
delete-auto-save-file-if-necessary 27.2 自動保存
delete-auto-save-files 27.2 自動保存
delete-backward-char 33.6 テキストの削除
delete-before, a frame parameter 30.4.3.6 フレームとの相互作用のためのパラメーター
delete-blank-lines 33.7 ユーザーレベルの削除コマンド
delete-by-moving-to-trash 26.7 ファイルの名前と属性の変更
delete-by-moving-to-trash 26.11 ディレクトリーの作成・コピー・削除
delete-char 33.6 テキストの削除
delete-directory 26.11 ディレクトリーの作成・コピー・削除
delete-dups 5.7 集合としてのリストの使用
delete-exited-processes 40.5 プロセスの削除
delete-field 33.19.9 フィールドの定義と使用
delete-file 26.7 ファイルの名前と属性の変更
delete-frame 30.7 フレームの削除
delete-frame event 22.7.12 その他のシステムイベント
delete-frame-functions 30.7 フレームの削除
delete-horizontal-space 33.7 ユーザーレベルの削除コマンド
delete-indentation 33.7 ユーザーレベルの削除コマンド
delete-minibuffer-contents 21.12 ミニバッファーのコンテンツ
delete-old-versions 27.1.3 番号つきバックアップファイルの作成と削除
delete-other-frames 30.7 フレームの削除
delete-other-windows 29.8 ウィンドウの削除
delete-other-windows, a window parameter 29.27 ウィンドウのパラメーター
delete-overlay 41.9.1 オーバーレイの管理
delete-process 40.5 プロセスの削除
delete-region 33.6 テキストの削除
delete-selection, symbol property 32.7 マーク
delete-selection-helper 32.7 マーク
delete-selection-pre-hook 32.7 マーク
delete-terminal 30.2 複数の端末
delete-terminal-functions 30.2 複数の端末
delete-to-left-margin 33.12 fillのマージン
delete-trailing-whitespace 33.7 ユーザーレベルの削除コマンド
delete-window 29.8 ウィンドウの削除
delete-window, a window parameter 29.27 ウィンドウのパラメーター
delete-window-choose-selected 29.8 ウィンドウの削除
delete-windows-on 29.8 ウィンドウの削除
deleting files 26.7 ファイルの名前と属性の変更
deleting frames 30.7 フレームの削除
deleting list elements 5.7 集合としてのリストの使用
deleting previous char 33.6 テキストの削除
deleting processes 40.5 プロセスの削除
deleting text vs killing 33.6 テキストの削除
deleting whitespace 33.7 ユーザーレベルの削除コマンド
deleting windows 29.8 ウィンドウの削除
delq 5.7 集合としてのリストの使用
dependencies 43.1 パッケージ化の基礎
derived mode 24.2.4 派生モードの定義
derived-mode-p 24.2.4 派生モードの定義
describe characters and events 25.5 ヘルプメッセージの文字記述
describe-bindings 23.17 キーマップのスキャン
describe-buffer-case-table 4.10 caseテーブル
describe-categories 36.8 カテゴリー
describe-current-display-table 41.23.2 ディスプレイテーブル
describe-display-table 41.23.2 ディスプレイテーブル
describe-mode 24.2.3 メジャーモードでのヘルプ入手
describe-prefix-bindings 25.6 ヘルプ関数
describe-syntax 36.3 構文テーブルの関数
description for interactive codes 22.2.2 interactiveにたいするコード文字
description format 1.3.7 説明のフォーマット
deserializing 40.20 バイト配列のpackとunpack
desktop notifications 42.19 デスクトップ通知
desktop save mode 24.8 Desktop Saveモード
desktop-buffer-mode-handlers 24.8 Desktop Saveモード
desktop-save-buffer 24.8 Desktop Saveモード
destroy-fringe-bitmap 41.13.5 フリンジビットマップのカスタマイズ
destructive list operations 5.6 既存のリスト構造の変更
destructuring with pcase patterns 11.4.4 pcaseパターンによる分解
detect-coding-region 34.10.3 Lispでのコーディングシステム
detect-coding-string 34.10.3 Lispでのコーディングシステム
deterministic build E.1 Emacsのビルド
device names 22.5 コマンドループからの情報
device-class 22.5 コマンドループからの情報
diagrams, boxed, for lists 2.4.6.1 ボックスダイアグラムによるリストの描写
dialog boxes 30.18 ダイアログボックス
digit-argument 22.12 プレフィクスコマンド引数
ding 41.24 ビープ
dir-locals-class-alist 12.13 ディレクトリーローカル変数
dir-locals-directory-cache 12.13 ディレクトリーローカル変数
dir-locals-file 12.13 ディレクトリーローカル変数
dir-locals-set-class-variables 12.13 ディレクトリーローカル変数
dir-locals-set-directory-class 12.13 ディレクトリーローカル変数
direct save protocol 30.22 ドラッグアンドドロップ
direction, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
directional overrides 41.27 双方向テキストの表示
directory file name 26.9.3 ディレクトリーの名前
directory local variables 12.13 ディレクトリーローカル変数
directory name 26.9.3 ディレクトリーの名前
directory part (of file name) 26.9.1 ファイル名の構成要素
directory-abbrev-alist 26.9.3 ディレクトリーの名前
directory-empty-p 26.10 ディレクトリーのコンテンツ
directory-file-name 26.9.3 ディレクトリーの名前
directory-files 26.10 ディレクトリーのコンテンツ
directory-files-and-attributes 26.10 ディレクトリーのコンテンツ
directory-files-no-dot-files-regexp 26.10 ディレクトリーのコンテンツ
directory-files-recursively 26.10 ディレクトリーのコンテンツ
directory-name-p 26.9.3 ディレクトリーの名前
directory-oriented functions 26.10 ディレクトリーのコンテンツ
dired-kept-versions 27.1.3 番号つきバックアップファイルの作成と削除
disable asynchronous native compilation 18.2 ネイティブコンパイル関数
disable-command 22.14 コマンドの無効化
disable-point-adjustment 22.6 コマンド後のポイントの調整
disable-theme 15.6 Customテーマ
disabled 22.14 コマンドの無効化
disabled command 22.14 コマンドの無効化
disabled-command-function 22.14 コマンドの無効化
disabling multibyte 34.2 マルチバイト文字の無効化
disabling undo 33.10 アンドゥリストの保守
disassemble 17.8 逆アセンブルされたバイトコード
disassembled byte-code 17.8 逆アセンブルされたバイトコード
discard-input 22.8.6 その他のイベント入力の機能
discarding input 22.8.6 その他のイベント入力の機能
dispatch of methods for generic function 13.8 ジェネリック関数
display (overlay property) 41.9.2 オーバーレイのプロパティ
display (text property) 41.16 displayプロパティ
display action 29.13.1 バッファーを表示するウィンドウの選択
display area 30.3.1 フレームのレイアウト
display feature testing 30.26 ディスプレイ機能のテスト
display margins 41.16.5 マージン内への表示
display message in echo area 41.4.1 エコーエリアへのメッセージの表示
display name on X 30.2 複数の端末
display origin 30.3.1 フレームのレイアウト
display properties, and bidi reordering of text 41.27 双方向テキストの表示
display property 41.16 displayプロパティ
display property, and point display 22.6 コマンド後のポイントの調整
display property, unsafe evaluation 41.16 displayプロパティ
display specification 41.16 displayプロパティ
display table 41.23.2 ディスプレイテーブル
display, a frame parameter 30.4.3.1 基本パラメーター
display, abstract 41.21 抽象的なディスプレイ
display, arbitrary objects 41.21 抽象的なディスプレイ
display-backing-store 30.26 ディスプレイ機能のテスト
display-buffer 29.13.1 バッファーを表示するウィンドウの選択
display-buffer-alist 29.13.1 バッファーを表示するウィンドウの選択
display-buffer-at-bottom 29.13.2 バッファー表示用のアクション関数
display-buffer-base-action 29.13.1 バッファーを表示するウィンドウの選択
display-buffer-below-selected 29.13.2 バッファー表示用のアクション関数
display-buffer-fallback-action 29.13.1 バッファーを表示するウィンドウの選択
display-buffer-full-frame 29.13.2 バッファー表示用のアクション関数
display-buffer-in-atom-window 29.18 アトミックウィンドウ
display-buffer-in-child-frame 29.13.2 バッファー表示用のアクション関数
display-buffer-in-direction 29.13.2 バッファー表示用のアクション関数
display-buffer-in-previous-window 29.13.2 バッファー表示用のアクション関数
display-buffer-in-side-window 29.17.1 サイドウィンドウへのバッファーの表示
display-buffer-no-window 29.13.2 バッファー表示用のアクション関数
display-buffer-overriding-action 29.13.1 バッファーを表示するウィンドウの選択
display-buffer-pop-up-frame 29.13.2 バッファー表示用のアクション関数
display-buffer-pop-up-window 29.13.2 バッファー表示用のアクション関数
display-buffer-reuse-mode-window 29.13.2 バッファー表示用のアクション関数
display-buffer-reuse-window 29.13.2 バッファー表示用のアクション関数
display-buffer-same-window 29.13.2 バッファー表示用のアクション関数
display-buffer-use-least-recent-window 29.13.2 バッファー表示用のアクション関数
display-buffer-use-some-frame 29.13.2 バッファー表示用のアクション関数
display-buffer-use-some-window 29.13.2 バッファー表示用のアクション関数
display-color-cells 30.26 ディスプレイ機能のテスト
display-color-p 30.26 ディスプレイ機能のテスト
display-completion-list 21.6.3 補完を行うミニバッファーコマンド
display-delayed-warnings 41.5.4 遅延された警告
display-graphic-p 30.26 ディスプレイ機能のテスト
display-grayscale-p 30.26 ディスプレイ機能のテスト
display-images-p 30.26 ディスプレイ機能のテスト
display-message-or-buffer 41.4.1 エコーエリアへのメッセージの表示
display-mm-dimensions-alist 30.26 ディスプレイ機能のテスト
display-mm-height 30.26 ディスプレイ機能のテスト
display-mm-width 30.26 ディスプレイ機能のテスト
display-monitor-attributes-list 30.2 複数の端末
display-monitors-changed-functions 30.2 複数の端末
display-mouse-p 30.26 ディスプレイ機能のテスト
display-pixel-height 30.26 ディスプレイ機能のテスト
display-pixel-width 30.26 ディスプレイ機能のテスト
display-planes 30.26 ディスプレイ機能のテスト
display-popup-menus-p 30.26 ディスプレイ機能のテスト
display-save-under 30.26 ディスプレイ機能のテスト
display-screens 30.26 ディスプレイ機能のテスト
display-selections-p 30.26 ディスプレイ機能のテスト
display-sort-function, in completion 21.6.7 プログラムされた補完
display-start position 29.20 ウィンドウの開始位置と終了位置
display-supports-face-attributes-p 30.26 ディスプレイ機能のテスト
display-table-slot 41.23.2 ディスプレイテーブル
display-type, a frame parameter 30.4.3.1 基本パラメーター
display-visual-class 30.26 ディスプレイ機能のテスト
display-warning 41.5.1 警告の基礎
displaying a buffer 29.13 適切なウィンドウへのバッファーの表示
displaying faces 41.12.4 フェイスの表示
displays, multiple 30.2 複数の端末
distance between strings 4.5 文字および文字列の比較
distinguish interactive calls 22.4 インタラクティブな呼び出しの区別
dlet 12.3 ローカル変数
dnd-begin-drag-files 30.22 ドラッグアンドドロップ
dnd-begin-file-drag 30.22 ドラッグアンドドロップ
dnd-begin-text-drag 30.22 ドラッグアンドドロップ
dnd-direct-save 30.22 ドラッグアンドドロップ
dnd-protocol-alist 30.22 ドラッグアンドドロップ
do-auto-save 27.2 自動保存
DOC (documentation) file 25.1 ドキュメントの基礎
doc, customization keyword 15.4.4 型キーワード
doc-directory 25.2 ドキュメント文字列へのアクセス
Document Object Model 33.30.1 ドキュメントオブジェクトモデル
documentation 25.2 ドキュメント文字列へのアクセス
documentation conventions 25.1 ドキュメントの基礎
documentation for major mode 24.2.3 メジャーモードでのヘルプ入手
documentation groups 25.7 ドキュメントのグループ
documentation notation 1.3.3 評価の表記
documentation string of function 13.2.4 関数のドキュメント文字列
documentation strings 25 ドキュメント
documentation strings, conventions and tips D.6 ドキュメント文字列のヒント
documentation, keys in 25.3 ドキュメント内でのキーバインディングの置き換え
documentation-property 25.2 ドキュメント文字列へのアクセス
dolist 11.5 繰り返し
dolist-with-progress-reporter 41.4.2 処理の進捗レポート
DOM 33.30.1 ドキュメントオブジェクトモデル
dom-node 33.30.1 ドキュメントオブジェクトモデル
dotimes 11.5 繰り返し
dotimes-with-progress-reporter 41.4.2 処理の進捗レポート
dotted list 5.1 リストとコンスセル
dotted lists (Edebug) 19.2.15.2 仕様リスト
dotted pair notation 2.4.6.2 ドットペア表記
double-click events 22.7.7 リピートイベント
double-click-fuzz 22.7.7 リピートイベント
double-click-time 22.7.7 リピートイベント
double-quote in strings 2.4.8.1 文字列の構文
down-list 31.2.6 釣り合いのとれたカッコを越えた移動
downcase 4.9 Lispでの大文字小文字変換
downcase-region 33.18 大文字小文字の変更
downcase-word 33.18 大文字小文字の変更
downcasing in lookup-key 22.8.1 キーシーケンス入力
download-callback xwidget events 22.7.11 Xwidgetイベント
download-started xwidget events 22.7.11 Xwidgetイベント
drag and drop 30.22 ドラッグアンドドロップ
drag and drop protocols, X 30.22 ドラッグアンドドロップ
drag and drop, other formats 30.22 ドラッグアンドドロップ
drag and drop, X 30.22 ドラッグアンドドロップ
drag event 22.7.5 ドラッグイベント
drag-internal-border, a frame parameter 30.4.3.7 マウスドラッグのパラメーター
drag-n-drop event 22.7.12 その他のシステムイベント
drag-with-header-line, a frame parameter 30.4.3.7 マウスドラッグのパラメーター
drag-with-mode-line, a frame parameter 30.4.3.7 マウスドラッグのパラメーター
drag-with-tab-line, a frame parameter 30.4.3.7 マウスドラッグのパラメーター
dribble file 42.13.2 入力の記録
drop target, in drag-and-drop operations 30.22 ドラッグアンドドロップ
dump file E.1 Emacsのビルド
dump-emacs E.1 Emacsのビルド
dump-emacs-portable E.1 Emacsのビルド
dumping Emacs E.1 Emacsのビルド
dynamic binding 12.10 変数のバインディングのスコーピングルール
dynamic binding, temporarily 12.3 ローカル変数
dynamic extent 12.10 変数のバインディングのスコーピングルール
dynamic let-binding 12.3 ローカル変数
dynamic libraries 42.21 動的にロードされるライブラリー
dynamic loading of documentation 17.3 ドキュメント文字列とコンパイル
dynamic loading of functions 17.4 個々の関数のダイナミックロード
dynamic modules 16.11 Emacsのダイナミックモジュール
dynamic modules, writing E.8 動的にロードされるモジュールの記述
dynamic scope 12.10 変数のバインディングのスコーピングルール
dynamic-library-alist 42.21 動的にロードされるライブラリー

E
eager macro expansion 16.1 プログラムがロードを行う方法
early init file 42.1.2 initファイル
early-init.el 42.1.2 initファイル
easy-menu-define 23.18.8 easy-menu
easy-mmode-define-minor-mode 24.3.3 マイナーモードの定義
echo area 41.4 エコーエリア
echo area customization 41.4.4 エコーエリアのカスタマイズ
echo-area-clear-hook 41.4.4 エコーエリアのカスタマイズ
echo-keystrokes 41.4.4 エコーエリアのカスタマイズ
edebug 19.2.6.3 ソースブレークポイント
Edebug debugging facility 19.2 Edebug
Edebug execution modes 19.2.3 Edebugの実行モード
edebug overwrites buffer point position 19.2.14.2 Edebugの表示の更新
Edebug specification list 19.2.15.2 仕様リスト
edebug, failure to instrument 19.2.2 Edebugのためのインストルメント
edebug-after-instrumentation-function 19.2.16 Edebugのオプション
edebug-all-defs 19.2.16 Edebugのオプション
edebug-all-forms 19.2.16 Edebugのオプション
edebug-backtrace-hide-instrumentation 19.2.5 その他のEdebugコマンド
edebug-backtrace-show-instrumentation 19.2.5 その他のEdebugコマンド
edebug-behavior-alist 19.2.16 Edebugのオプション
edebug-continue-kbd-macro 19.2.16 Edebugのオプション
edebug-defun 19.2.2 Edebugのためのインストルメント
edebug-display-freq-count 19.2.13 カバレッジテスト
edebug-eval-macro-args 19.2.15.1 マクロ呼び出しのインストルメント
edebug-eval-macro-args 19.2.16 Edebugのオプション
edebug-eval-top-level-form 19.2.2 Edebugのためのインストルメント
edebug-global-break-condition 19.2.16 Edebugのオプション
edebug-initial-mode 19.2.16 Edebugのオプション
edebug-max-depth 19.2.14.1 停止するかどうかのチェック
edebug-new-definition-function 19.2.16 Edebugのオプション
edebug-on-error 19.2.16 Edebugのオプション
edebug-on-quit 19.2.16 Edebugのオプション
edebug-print-circle 19.2.11 Edebugでのプリント
edebug-print-circle 19.2.16 Edebugのオプション
edebug-print-length 19.2.11 Edebugでのプリント
edebug-print-length 19.2.16 Edebugのオプション
edebug-print-level 19.2.11 Edebugでのプリント
edebug-print-level 19.2.16 Edebugのオプション
edebug-print-trace-after 19.2.12 トレースバッファー
edebug-print-trace-before 19.2.12 トレースバッファー
edebug-remove-instrumentation 19.2.2 Edebugのためのインストルメント
edebug-save-displayed-buffer-points 19.2.16 Edebugのオプション
edebug-save-windows 19.2.16 Edebugのオプション
edebug-set-global-break-condition 19.2.6.2 グローバルなブレーク条件
edebug-set-initial-mode 19.2.3 Edebugの実行モード
edebug-setup-hook 19.2.16 Edebugのオプション
edebug-sit-for-seconds 19.2.3 Edebugの実行モード
edebug-sit-for-seconds 19.2.16 Edebugのオプション
edebug-sit-on-break 19.2.16 Edebugのオプション
edebug-temp-display-freq-count 19.2.13 カバレッジテスト
edebug-test-coverage 19.2.16 Edebugのオプション
edebug-trace 19.2.16 Edebugのオプション
edebug-trace 19.2.12 トレースバッファー
edebug-tracing 19.2.12 トレースバッファー
edebug-unwrap-results 19.2.16 Edebugのオプション
edge detection, images 41.17.2 イメージのディスクリプタ
edit distance between strings 4.5 文字および文字列の比較
edit-and-eval-command 21.3 ミニバッファーでのLispオブジェクトの読み取り
editing types 2.5 編集用の型
editor command loop 22 コマンドループ
eight-bit, a charset 34.7 文字セット
electric-future-map 1.3.7.2 変数の説明例
element (of list) 5 リスト
elements of sequences 6.1 シーケンス
elliptical-arc 41.17.6 SVGイメージ
elp.el 19.5 プロファイリング
elt 6.1 シーケンス
Emacs event standard notation 25.5 ヘルプメッセージの文字記述
Emacs process run time 42.9 プロセッサーの実行時間
emacs, a charset 34.7 文字セット
emacs-build-number 1.4 バージョンの情報
emacs-build-time 1.4 バージョンの情報
emacs-init-time 42.9 プロセッサーの実行時間
emacs-internal coding system 34.10.1 コーディングシステムの基本概念
emacs-lisp-docstring-fill-column D.6 ドキュメント文字列のヒント
emacs-major-version 1.4 バージョンの情報
emacs-minor-version 1.4 バージョンの情報
emacs-pid 42.3 オペレーティングシステムの環境
emacs-repository-branch 1.4 バージョンの情報
emacs-repository-version 1.4 バージョンの情報
emacs-save-session-functions 42.18 セッションマネージャー
emacs-session-restore 42.18 セッションマネージャー
emacs-startup-hook 42.1.2 initファイル
emacs-uptime 42.9 プロセッサーの実行時間
emacs-version 1.4 バージョンの情報
emacs-version 1.4 バージョンの情報
emacsclient, getting a backtrace 19.1.1 エラーによるデバッガへのエンター
EMACSLOADPATH environment variable 16.3 ライブラリー検索
emacs_finalizer E.8.2 モジュール関数の記述
emacs_funcall_exit, enumeration E.8.5 モジュールでの非ローカル脱出
emacs_funcall_exit_return E.8.5 モジュールでの非ローカル脱出
emacs_funcall_exit_signal E.8.5 モジュールでの非ローカル脱出
emacs_funcall_exit_throw E.8.5 モジュールでの非ローカル脱出
emacs_function E.8.2 モジュール関数の記述
EMACS_LIMB_MAX E.8.3 Lisp・モジュール間の値変換
emacs_module_init 16.11 Emacsのダイナミックモジュール
emacs_module_init E.8.1 モジュールの初期化コード
emacs_value data type E.8.3 Lisp・モジュール間の値変換
emacs_variadic_function E.8.2 モジュール関数の記述
embedded language, tree-sitter 37.6 複数言語ののパース
embedded widgets 41.19 埋め込みネイティブウィジェット
empty file name 26.9.2 絶対ファイル名と相対ファイル名
empty file name, and file-exists-p 26.6.1 アクセシビリティのテスト
empty file names, and expand-file-name 26.9.4 ファイル名を展開する関数
empty lines, indicating 41.13.2 フリンジのインジケーター
empty list 2.4.6.1 ボックスダイアグラムによるリストの描写
empty overlay 41.9.1 オーバーレイの管理
empty region 32.8 リージョン
emulation-mode-map-alists 23.9 アクティブなキーマップの制御
enable-command 22.14 コマンドの無効化
enable-connection-local-variables 12.14.2 接続ローカル変数の適用
enable-dir-local-variables 12.13 ディレクトリーローカル変数
enable-local-eval 12.12 ファイルローカル変数
enable-local-variables 12.12 ファイルローカル変数
enable-multibyte-characters 34.1 テキストの表現方法
enable-multibyte-characters 34.2 マルチバイト文字の無効化
enable-recursive-minibuffers 21.13 再帰的なミニバッファー
enable-theme 15.6 Customテーマ
encapsulation, ewoc 41.21 抽象的なディスプレイ
encode-char 34.7 文字セット
encode-coding-region 34.10.7 明示的なエンコードとデコード
encode-coding-string 34.10.7 明示的なエンコードとデコード
encode-time 42.7 時刻の変換
encoding file formats 26.13 ファイルのフォーマット変換
encoding in coding systems 34.10.7 明示的なエンコードとデコード
encrypted network connections 40.14 ネットワーク接続
end of line in regexp 35.3.1.1 正規表現内の特殊文字
end-of-buffer 31.2.3 バッファー終端への移動
end-of-defun 31.2.6 釣り合いのとれたカッコを越えた移動
end-of-defun-function 31.2.6 釣り合いのとれたカッコを越えた移動
end-of-file 20.3 入力関数
end-of-line 31.2.4 テキスト行単位の移動
end-of-line conversion 34.10.1 コーディングシステムの基本概念
end-session event 22.7.12 その他のシステムイベント
endianness, in bindat specification 40.20.1 データレイアウトの記述
ensure-empty-lines 33.5 ユーザーレベルの挿入コマンド
ensure-list 5.4 コンスセルおよびリストの構築
environment 10.1 評価の概要
environment variable access 42.3 オペレーティングシステムの環境
environment variables, subprocesses 40.1 サブプロセスを作成する関数
eobp 33.1 ポイント近傍のテキストを調べる
EOL conversion 34.10.1 コーディングシステムの基本概念
eol conversion of coding system 34.10.3 Lispでのコーディングシステム
eol in rx 35.3.3.1 rxによるregexpの構築
eol type of coding system 34.10.3 Lispでのコーディングシステム
eolp 33.1 ポイント近傍のテキストを調べる
eos in rx 35.3.3.1 rxによるregexpの構築
eot in rx 35.3.3.1 rxによるregexpの構築
eow in rx 35.3.3.1 rxによるregexpの構築
epoch 42.5 時刻
eq 2.8 同等性のための述語
eq E.8.4 その他の便利なモジュール用関数
eql 3.4 数値の比較
equal 2.8 同等性のための述語
equal-including-properties 2.8 同等性のための述語
equality 2.8 同等性のための述語
erase-buffer 33.6 テキストの削除
error 11.7.3.1 エラーをシグナルする方法
error cleanup 11.7.4 非ローカル脱出のクリーンアップ
error debugging 19.1.1 エラーによるデバッガへのエンター
error description 11.7.3.3 エラーを処理するコードの記述
error display 41.4 エコーエリア
error handler 11.7.3.3 エラーを処理するコードの記述
error in debug 19.1.10 デバッガの呼び出し
error message notation 1.3.5 エラーメッセージ
error name 11.7.3.4 エラーシンボルとエラー条件
error symbol 11.7.3.4 エラーシンボルとエラー条件
error-conditions 11.7.3.4 エラーシンボルとエラー条件
error-message-string 11.7.3.3 エラーを処理するコードの記述
errors 11.7.3 エラー
ESC 23.11 キー照合のための関数
esc-map 23.6 プレフィクスキー
ESC-prefix 23.6 プレフィクスキー
escape (ASCII character) 2.4.3.1 基本的な文字構文
escape characters 20.6 出力に影響する変数
escape characters in printing 20.5 出力関数
escape sequence 2.4.3.1 基本的な文字構文
eval 10.5 evalについて
eval during compilation 17.5 コンパイル中の評価
eval in rx 35.3.3.1 rxによるregexpの構築
eval, and debugging 19.1.11 デバッガの内部
eval-and-compile 17.5 コンパイル中の評価
eval-buffer 10.5 evalについて
eval-buffer (Edebug) 19.2.2 Edebugのためのインストルメント
eval-defun (Edebug) 19.2.2 Edebugのためのインストルメント
eval-defun, and defcustom forms 15.3 カスタマイゼーション変数の定義
eval-defun, and defface forms 41.12.2 フェイスの定義
eval-defun, and explicit entry to debugger 19.1.6 明示的なデバッガへのエントリー
eval-expression (Edebug) 19.2.2 Edebugのためのインストルメント
eval-expression, and lexical-binding 12.10.4 レキシカルバインディングの使用
eval-expression-debug-on-error 19.1.1 エラーによるデバッガへのエンター
eval-expression-print-length 20.6 出力に影響する変数
eval-expression-print-level 20.6 出力に影響する変数
eval-last-sexp, and defface forms 41.12.2 フェイスの定義
eval-last-sexp, and defvar forms 12.5 グローバル変数の定義
eval-minibuffer 21.3 ミニバッファーでのLispオブジェクトの読み取り
eval-region 10.5 evalについて
eval-region (Edebug) 19.2.2 Edebugのためのインストルメント
eval-when-compile 17.5 コンパイル中の評価
evaluated expression argument 22.2.2 interactiveにたいするコード文字
evaluation 10 評価
evaluation list group 19.2.10 評価リストバッファー
evaluation notation 1.3.3 評価の表記
evaluation of buffer contents 10.5 evalについて
evaluation of special forms 10.2.7 スペシャルフォーム
evaporate (overlay property) 41.9.2 オーバーレイのプロパティ
even-window-sizes 29.13.4 バッファー表示の追加オプション
event printing 25.5 ヘルプメッセージの文字記述
event translation 22.8.3 入力イベントの変更と変換
event type 22.7.14 イベントの分類
event, reading only one 22.8.2 単一イベントの読み取り
event-basic-type 22.7.14 イベントの分類
event-click-count 22.7.7 リピートイベント
event-convert-list 23.13 低レベルなキーバインディング
event-end 22.7.15 マウスイベントへのアクセス
event-modifiers 22.7.14 イベントの分類
event-start 22.7.15 マウスイベントへのアクセス
eventp 22.7 入力イベント
events 22.7 入力イベント
ewoc 41.21 抽象的なディスプレイ
ewoc-buffer 41.21.1 抽象ディスプレイの関数
ewoc-collect 41.21.1 抽象ディスプレイの関数
ewoc-create 41.21.1 抽象ディスプレイの関数
ewoc-data 41.21.1 抽象ディスプレイの関数
ewoc-delete 41.21.1 抽象ディスプレイの関数
ewoc-enter-after 41.21.1 抽象ディスプレイの関数
ewoc-enter-before 41.21.1 抽象ディスプレイの関数
ewoc-enter-first 41.21.1 抽象ディスプレイの関数
ewoc-enter-last 41.21.1 抽象ディスプレイの関数
ewoc-filter 41.21.1 抽象ディスプレイの関数
ewoc-get-hf 41.21.1 抽象ディスプレイの関数
ewoc-goto-next 41.21.1 抽象ディスプレイの関数
ewoc-goto-node 41.21.1 抽象ディスプレイの関数
ewoc-goto-prev 41.21.1 抽象ディスプレイの関数
ewoc-invalidate 41.21.1 抽象ディスプレイの関数
ewoc-locate 41.21.1 抽象ディスプレイの関数
ewoc-location 41.21.1 抽象ディスプレイの関数
ewoc-map 41.21.1 抽象ディスプレイの関数
ewoc-next 41.21.1 抽象ディスプレイの関数
ewoc-nth 41.21.1 抽象ディスプレイの関数
ewoc-prev 41.21.1 抽象ディスプレイの関数
ewoc-refresh 41.21.1 抽象ディスプレイの関数
ewoc-set-data 41.21.1 抽象ディスプレイの関数
ewoc-set-hf 41.21.1 抽象ディスプレイの関数
examining text properties 33.19.1 テキストプロパティを調べる
examining the interactive form 22.2.1 interactiveの使用
examining windows 29.11 バッファーとウィンドウ
examples of using interactive 22.2.3 interactiveの使用例
excess close parentheses 19.3.2 過剰な閉カッコ
excess open parentheses 19.3.1 過剰な開カッコ
excursion 31.3 エクスカーション
exec-directory 40.1 サブプロセスを作成する関数
exec-path 40.1 サブプロセスを作成する関数
exec-path 40.1 サブプロセスを作成する関数
exec-suffixes 40.1 サブプロセスを作成する関数
executable-find 26.6.6 標準的な場所へのファイルの配置
execute program 40.1 サブプロセスを作成する関数
execute with prefix argument 22.3 インタラクティブな呼び出し
execute-extended-command 22.3 インタラクティブな呼び出し
execute-extended-command-for-buffer 22.3 インタラクティブな呼び出し
execute-kbd-macro 22.16 キーボードマクロ
executing-kbd-macro 22.16 キーボードマクロ
execution order of buffer display action functions 29.13.5 アクション関数の優先順
execution speed D.4 コンパイル済みコードを高速化ためのヒント
exit 22.13 再帰編集
exit recursive editing 22.13 再帰編集
exit-minibuffer 21.10 ミニバッファーのコマンド
exit-recursive-edit 22.13 再帰編集
exiting Emacs 42.2 Emacsからの脱出
exp 3.9 標準的な数学関数
expand-abbrev 38.4 略語の照会と展開
expand-file-name 26.9.4 ファイル名を展開する関数
expanding abbrevs 38.4 略語の照会と展開
expansion of file names 26.9.4 ファイル名を展開する関数
expansion of macros 14.2 マクロ呼び出しの展開
explicit selective display 41.7 選択的な表示
explicit-name, a frame parameter 30.4.3.1 基本パラメーター
explore tree-sitter syntax tree 37.1 Tree-sitter Language Grammar
expression 10.1 評価の概要
expt 3.9 標準的な数学関数
extended file attributes 26.6.5 拡張されたファイル属性
extended menu item 23.18.1.2 拡張メニューアイテム
extended-command-history 21.4 ミニバッファーのヒストリー
extent 12.10 変数のバインディングのスコーピングルール
external border 30.3.1 フレームのレイアウト
external menu bar 30.3.1 フレームのレイアウト
external tool bar 30.3.1 フレームのレイアウト
external-debugging-output 20.4 出力ストリーム
extra node, tree-sitter 37.4 ノード情報へのアクセス
extra slots of char-table 6.6 文字テーブル
extra-keyboard-modifiers 22.8.3 入力イベントの変更と変換
extract_big_integer E.8.3 Lisp・モジュール間の値変換
extract_float E.8.3 Lisp・モジュール間の値変換
extract_integer E.8.3 Lisp・モジュール間の値変換
extract_time E.8.3 Lisp・モジュール間の値変換

F
face (button property) 41.20.1 ボタンのプロパティ
face (non-removability of) 41.12.2 フェイスの定義
face (overlay property) 41.9.2 オーバーレイのプロパティ
face (text property) 33.19.4 特殊な意味をもつプロパティ
face alias 41.12.6 フェイスを処理するための関数
face attributes 41.12.1 フェイスの属性
face attributes, access and modification 41.12.3 フェイス属性のための関数
face codes of text 33.19.4 特殊な意味をもつプロパティ
face merging 41.12.4 フェイスの表示
face name 41.12 フェイス
face number 41.12.6 フェイスを処理するための関数
face property of face symbols 41.12.6 フェイスを処理するための関数
face remapping 41.12.5 フェイスのリマップ
face spec 41.12.2 フェイスの定義
face-all-attributes 41.12.3 フェイス属性のための関数
face-attribute 41.12.3 フェイス属性のための関数
face-attribute-relative-p 41.12.3 フェイス属性のための関数
face-background 41.12.3 フェイス属性のための関数
face-bold-p 41.12.3 フェイス属性のための関数
face-defface-spec (face symbol property) 41.12.2 フェイスの定義
face-differs-from-default-p 41.12.6 フェイスを処理するための関数
face-documentation 25.2 ドキュメント文字列へのアクセス
face-documentation 41.12.6 フェイスを処理するための関数
face-documentation (face symbol property) 41.12.2 フェイスの定義
face-equal 41.12.6 フェイスを処理するための関数
face-extend-p 41.12.3 フェイス属性のための関数
face-filters-always-match 33.19.4 特殊な意味をもつプロパティ
face-font 41.12.3 フェイス属性のための関数
face-font-family-alternatives 41.12.9 フォントの選択
face-font-registry-alternatives 41.12.9 フォントの選択
face-font-rescale-alist 41.12.9 フォントの選択
face-font-selection-order 41.12.9 フォントの選択
face-foreground 41.12.3 フェイス属性のための関数
face-id 41.12.6 フェイスを処理するための関数
face-inverse-video-p 41.12.3 フェイス属性のための関数
face-italic-p 41.12.3 フェイス属性のための関数
face-list 41.12.6 フェイスを処理するための関数
face-name-history 21.4 ミニバッファーのヒストリー
face-remap-add-relative 41.12.5 フェイスのリマップ
face-remap-remove-relative 41.12.5 フェイスのリマップ
face-remap-reset-base 41.12.5 フェイスのリマップ
face-remap-set-base 41.12.5 フェイスのリマップ
face-remapping-alist 41.12.5 フェイスのリマップ
face-spec-set 41.12.2 フェイスの定義
face-stipple 41.12.3 フェイス属性のための関数
face-underline-p 41.12.3 フェイス属性のための関数
facep 41.12 フェイス
faces 41.12 フェイス
faces for font lock 24.6.7 Font Lockのためのフェイス
faces, automatic choice 41.12.7 フェイスの自動割り当て
false 1.3.2 nilt
fboundp 13.9 関数セルの内容へのアクセス
fceiling 3.7 丸め処理
feature-unload-function 16.9 アンロード
featurep 16.7 名前つき機能
features 16.7 名前つき機能
features 16.7 名前つき機能
fetch-bytecode 17.4 個々の関数のダイナミックロード
ffloor 3.7 丸め処理
field (overlay property) 41.9.2 オーバーレイのプロパティ
field (text property) 33.19.4 特殊な意味をもつプロパティ
field name, tree-sitter 37.1 Tree-sitter Language Grammar
field numbers in format spec 4.7 文字列のフォーマット
field width 4.7 文字列のフォーマット
field-beginning 33.19.9 フィールドの定義と使用
field-end 33.19.9 フィールドの定義と使用
field-is 24.7.2 パーサーベースのインデント
field-string 33.19.9 フィールドの定義と使用
field-string-no-properties 33.19.9 フィールドの定義と使用
fields 33.19.9 フィールドの定義と使用
fifo data structure 6.8 オブジェクト用固定長リングの管理
file accessibility 26.6.1 アクセシビリティのテスト
file age 26.6.4 ファイルの属性
file attributes 26.6.4 ファイルの属性
file classification 26.6.2 ファイル種別の区別
file contents, and default coding system 34.10.5 デフォルトのコーディングシステム
file format conversion 26.13 ファイルのフォーマット変換
file hard link 26.7 ファイルの名前と属性の変更
file local variables 12.12 ファイルローカル変数
file local variables 42.22 セキュリティへの配慮
file locks 26.5 ファイルのロック
file mode specification error 24.2.2 Emacsがメジャーモードを選択する方法
file modes 26.6.1 アクセシビリティのテスト
file modes and MS-DOS 26.6.1 アクセシビリティのテスト
file modes, setting 26.7 ファイルの名前と属性の変更
file modification time 26.6.4 ファイルの属性
file name abbreviations 26.9.3 ディレクトリーの名前
file name completion subroutines 26.9.6 ファイル名の補完
file name handler 26.12 特定のファイル名の“Magic”の作成
file name of buffer 28.4 バッファーのファイル名
file name of directory 26.9.3 ディレクトリーの名前
file name, and default coding system 34.10.5 デフォルトのコーディングシステム
file names 26.9 ファイルの名前
file names in directory 26.10 ディレクトリーのコンテンツ
file names, trailing whitespace 26.6 ファイルの情報
file notifications 42.20 ファイル変更による通知
file open error 26.1.2 visitのためのサブルーチン
file permissions 26.6.1 アクセシビリティのテスト
file permissions, setting 26.7 ファイルの名前と属性の変更
file with multiple names 26.7 ファイルの名前と属性の変更
file, ancestor directory of 26.10 ディレクトリーのコンテンツ
file, information about 26.6 ファイルの情報
file-accessible-directory-p 26.6.1 アクセシビリティのテスト
file-acl 26.6.5 拡張されたファイル属性
file-already-exists 26.7 ファイルの名前と属性の変更
file-attributes 26.6.4 ファイルの属性
file-backup-file-names 27.1.4 バックアップファイルの命名
file-chase-links 26.6.3 本当の名前
file-coding-system-alist 34.10.5 デフォルトのコーディングシステム
file-directory-p 26.6.2 ファイル種別の区別
file-equal-p 26.6.3 本当の名前
file-error 16.1 プログラムがロードを行う方法
file-executable-p 26.6.1 アクセシビリティのテスト
file-exists-p 26.6.1 アクセシビリティのテスト
file-expand-wildcards 26.10 ディレクトリーのコンテンツ
file-extended-attributes 26.6.5 拡張されたファイル属性
file-has-changed-p 26.6.4 ファイルの属性
file-in-directory-p 26.10 ディレクトリーのコンテンツ
file-local-copy 26.12 特定のファイル名の“Magic”の作成
file-local-name 26.12 特定のファイル名の“Magic”の作成
file-local-variables-alist 12.12 ファイルローカル変数
file-locked 26.5 ファイルのロック
file-locked-p 26.5 ファイルのロック
file-modes 26.6.1 アクセシビリティのテスト
file-modes-number-to-symbolic 26.7 ファイルの名前と属性の変更
file-modes-symbolic-to-number 26.7 ファイルの名前と属性の変更
file-name encoding, MS-Windows 34.10.2 エンコーディングとI/O
file-name-absolute-p 26.9.2 絶対ファイル名と相対ファイル名
file-name-all-completions 26.9.6 ファイル名の補完
file-name-as-directory 26.9.3 ディレクトリーの名前
file-name-base 26.9.1 ファイル名の構成要素
file-name-case-insensitive-p 26.6.3 本当の名前
file-name-coding-system 34.10.2 エンコーディングとI/O
file-name-completion 26.9.6 ファイル名の補完
file-name-concat 26.9.3 ディレクトリーの名前
file-name-directory 26.9.1 ファイル名の構成要素
file-name-extension 26.9.1 ファイル名の構成要素
file-name-handler-alist 26.12 特定のファイル名の“Magic”の作成
file-name-history 21.4 ミニバッファーのヒストリー
file-name-nondirectory 26.9.1 ファイル名の構成要素
file-name-parent-directory 26.9.3 ディレクトリーの名前
file-name-quote 26.9.4 ファイル名を展開する関数
file-name-quoted-p 26.9.4 ファイル名を展開する関数
file-name-sans-extension 26.9.1 ファイル名の構成要素
file-name-sans-versions 26.9.1 ファイル名の構成要素
file-name-split 26.9.1 ファイル名の構成要素
file-name-unquote 26.9.4 ファイル名を展開する関数
file-name-with-extension 26.9.1 ファイル名の構成要素
file-newer-than-file-p 26.6.4 ファイルの属性
file-newest-backup 27.1.4 バックアップファイルの命名
file-nlinks 26.6.4 ファイルの属性
file-notify-add-watch 42.20 ファイル変更による通知
file-notify-rm-all-watches 42.20 ファイル変更による通知
file-notify-rm-watch 42.20 ファイル変更による通知
file-notify-valid-p 42.20 ファイル変更による通知
file-ownership-preserved-p 26.6.1 アクセシビリティのテスト
file-precious-flag 26.2 バッファーの保存
file-readable-p 26.6.1 アクセシビリティのテスト
file-regular-p 26.6.2 ファイル種別の区別
file-relative-name 26.9.2 絶対ファイル名と相対ファイル名
file-remote-p 26.12 特定のファイル名の“Magic”の作成
file-selinux-context 26.6.5 拡張されたファイル属性
file-supersession 28.6 バッファーの変更時刻
file-symlink-p 26.6.2 ファイル種別の区別
file-truename 26.6.3 本当の名前
file-writable-p 26.6.1 アクセシビリティのテスト
filepos-to-bufferpos 34.1 テキストの表現方法
fill-column 33.12 fillのマージン
fill-context-prefix 33.13 Adaptive Fillモード
fill-forward-paragraph-function 33.11 fill
fill-individual-paragraphs 33.11 fill
fill-individual-varying-indent 33.11 fill
fill-nobreak-predicate 33.12 fillのマージン
fill-paragraph 33.11 fill
fill-paragraph-function 33.11 fill
fill-prefix 33.12 fillのマージン
fill-region 33.11 fill
fill-region-as-paragraph 33.11 fill
fill-separate-heterogeneous-words-with-space 33.11 fill
fillarray 6.3 配列を操作する関数
filling text 33.11 fill
filling, automatic 33.14 オートfill
filter function 40.9.2 プロセスのフィルター関数
filter multibyte flag, of process 40.9.3 プロセス出力のデコード
filter-buffer-substring 33.2 バッファーのコンテンツを調べる
filter-buffer-substring-function 33.2 バッファーのコンテンツを調べる
filter-buffer-substring-functions 33.2 バッファーのコンテンツを調べる
filtering killed text 33.8.2 kill用の関数
filtering sequences 6.1 シーケンス
find file in path 26.6.6 標準的な場所へのファイルの配置
find library 16.3 ライブラリー検索
find-auto-coding 34.10.5 デフォルトのコーディングシステム
find-backup-file-name 27.1.4 バックアップファイルの命名
find-buffer-visiting 28.4 バッファーのファイル名
find-charset-region 34.8 文字セットのスキャン
find-charset-string 34.8 文字セットのスキャン
find-coding-systems-for-charsets 34.10.3 Lispでのコーディングシステム
find-coding-systems-region 34.10.3 Lispでのコーディングシステム
find-coding-systems-string 34.10.3 Lispでのコーディングシステム
find-file 26.1.1 ファイルをvisitする関数
find-file-hook 26.1.1 ファイルをvisitする関数
find-file-literally 26.1.1 ファイルをvisitする関数
find-file-literally 26.1.1 ファイルをvisitする関数
find-file-name-handler 26.12 特定のファイル名の“Magic”の作成
find-file-noselect 26.1.1 ファイルをvisitする関数
find-file-not-found-functions 26.1.1 ファイルをvisitする関数
find-file-other-window 26.1.1 ファイルをvisitする関数
find-file-read-only 26.1.1 ファイルをvisitする関数
find-file-wildcards 26.1.1 ファイルをvisitする関数
find-font 41.12.12 低レベルのフォント表現
find-image 41.17.8 イメージの定義
find-operation-coding-system 34.10.5 デフォルトのコーディングシステム
find-word-boundary-function-table 31.2.2 単語単位の移動
finding files 26.1 ファイルのvisit
finding windows 29.10 ウィンドウのサイクル順
first-change-hook 33.34 フックの変更
first-sibling 24.7.2 パーサーベースのインデント
fit-frame-to-buffer 29.5 ウィンドウのリサイズ
fit-frame-to-buffer 29.5 ウィンドウのリサイズ
fit-frame-to-buffer-margins 29.5 ウィンドウのリサイズ
fit-frame-to-buffer-margins, a frame parameter 30.4.3.3 サイズのパラメーター
fit-frame-to-buffer-sizes 29.5 ウィンドウのリサイズ
fit-frame-to-buffer-sizes, a frame parameter 30.4.3.3 サイズのパラメーター
fit-window-to-buffer 29.5 ウィンドウのリサイズ
fit-window-to-buffer-horizontally 29.5 ウィンドウのリサイズ
fixed-size window 29.4 ウィンドウのサイズ
fixnump 3.3 数値のための述語
fixup-whitespace 33.7 ユーザーレベルの削除コマンド
flags in format specifications 4.7 文字列のフォーマット
flatten-tree 5.4 コンスセルおよびリストの構築
float 3.5 数値の変換
float-e 3.9 標準的な数学関数
float-output-format 20.6 出力に影響する変数
float-pi 3.9 標準的な数学関数
float-time 42.5 時刻
floating-point functions 3.9 標準的な数学関数
floatp 3.3 数値のための述語
floats-consed E.5 メモリー使用量
floor 3.5 数値の変換
flowcontrol, in serial connections 40.19 シリアルポートとの対話
flush-standard-output 20.5 出力関数
flushing input 22.8.6 その他のイベント入力の機能
fmakunbound 13.9 関数セルの内容へのアクセス
fn in function’s documentation string 16.5 autoload
focus event 22.7.10 フォーカスイベント
focus-follows-mouse 30.10 入力のフォーカス
focus-in-hook Appendix H 標準的なフック
focus-out-hook Appendix H 標準的なフック
follow links 33.19.8 クリック可能なテキストの定義
follow-link (button property) 41.20.1 ボタンのプロパティ
follow-link (text or overlay property) 33.19.8 クリック可能なテキストの定義
following-char 33.1 ポイント近傍のテキストを調べる
font and color, frame parameters 30.4.3.10 フォントとカラーのパラメーター
font backend 41.12.12 低レベルのフォント表現
font entity 41.12.12 低レベルのフォント表現
font information for layout 41.12.12 低レベルのフォント表現
font lock faces 24.6.7 Font Lockのためのフェイス
Font Lock mode 24.6 Font Lockモード
font lookup 41.12.10 フォントの照会
font object 41.12.12 低レベルのフォント表現
font property 41.12.12 低レベルのフォント表現
font registry 41.12.12 低レベルのフォント表現
font selection 41.12.9 フォントの選択
font spec 41.12.12 低レベルのフォント表現
font, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
font-at 41.12.12 低レベルのフォント表現
font-backend, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
font-face-attributes 41.12.12 低レベルのフォント表現
font-family-list 41.12.1 フェイスの属性
font-get 41.12.12 低レベルのフォント表現
font-info 41.12.12 低レベルのフォント表現
font-lock-add-keywords 24.6.3 検索ベースのフォント化のカスタマイズ
font-lock-bracket-face 24.6.7 Font Lockのためのフェイス
font-lock-builtin-face 24.6.7 Font Lockのためのフェイス
font-lock-comment-delimiter-face 24.6.7 Font Lockのためのフェイス
font-lock-comment-face 24.6.7 Font Lockのためのフェイス
font-lock-constant-face 24.6.7 Font Lockのためのフェイス
font-lock-debug-fontify 24.6.1 Font Lockの基礎
font-lock-defaults 24.6.1 Font Lockの基礎
font-lock-delimiter-face 24.6.7 Font Lockのためのフェイス
font-lock-doc-face 24.6.7 Font Lockのためのフェイス
font-lock-doc-markup-face 24.6.7 Font Lockのためのフェイス
font-lock-ensure &optional beg end 24.6.1 Font Lockの基礎
font-lock-ensure-function 24.6.4 Font Lockのその他の変数
font-lock-escape-face 24.6.7 Font Lockのためのフェイス
font-lock-extend-after-change-region-function 24.6.9.2 バッファー変更後のリージョンのフォント化
font-lock-extra-managed-props 24.6.4 Font Lockのその他の変数
font-lock-face (text property) 33.19.4 特殊な意味をもつプロパティ
font-lock-flush &optional beg end 24.6.1 Font Lockの基礎
font-lock-flush-function 24.6.4 Font Lockのその他の変数
font-lock-fontify-buffer 24.6.1 Font Lockの基礎
font-lock-fontify-buffer-function 24.6.4 Font Lockのその他の変数
font-lock-fontify-region beg end &optional loudly 24.6.1 Font Lockの基礎
font-lock-fontify-region-function 24.6.4 Font Lockのその他の変数
font-lock-function-call-face 24.6.7 Font Lockのためのフェイス
font-lock-function-name-face 24.6.7 Font Lockのためのフェイス
font-lock-ignore 24.6.3 検索ベースのフォント化のカスタマイズ
font-lock-keyword-face 24.6.7 Font Lockのためのフェイス
font-lock-keywords 24.6.2 検索ベースのフォント化
font-lock-keywords-case-fold-search 24.6.2 検索ベースのフォント化
font-lock-keywords-only 24.6.8 構文的なFont Lock
font-lock-mark-block-function 24.6.4 Font Lockのその他の変数
font-lock-misc-punctuation-face 24.6.7 Font Lockのためのフェイス
font-lock-multiline 24.6.9.1 複数行のFont Lock
font-lock-negation-char-face 24.6.7 Font Lockのためのフェイス
font-lock-number-face 24.6.7 Font Lockのためのフェイス
font-lock-operator-face 24.6.7 Font Lockのためのフェイス
font-lock-preprocessor-face 24.6.7 Font Lockのためのフェイス
font-lock-property-name-face 24.6.7 Font Lockのためのフェイス
font-lock-property-use-face 24.6.7 Font Lockのためのフェイス
font-lock-punctuation-face 24.6.7 Font Lockのためのフェイス
font-lock-remove-keywords 24.6.3 検索ベースのフォント化のカスタマイズ
font-lock-string-face 24.6.7 Font Lockのためのフェイス
font-lock-syntactic-face-function 24.6.8 構文的なFont Lock
font-lock-syntax-table 24.6.8 構文的なFont Lock
font-lock-type-face 24.6.7 Font Lockのためのフェイス
font-lock-unfontify-buffer 24.6.1 Font Lockの基礎
font-lock-unfontify-buffer-function 24.6.4 Font Lockのその他の変数
font-lock-unfontify-region beg end 24.6.1 Font Lockの基礎
font-lock-unfontify-region-function 24.6.4 Font Lockのその他の変数
font-lock-variable-name-face 24.6.7 Font Lockのためのフェイス
font-lock-variable-use-face 24.6.7 Font Lockのためのフェイス
font-lock-warning-face 24.6.7 Font Lockのためのフェイス
font-put 41.12.12 低レベルのフォント表現
font-spec 41.12.12 低レベルのフォント表現
font-xlfd-name 41.12.12 低レベルのフォント表現
fontification-functions 41.12.7 フェイスの自動割り当て
fontifications with tree-sitter, overview 24.6.10 パーサーベースのFont Lock
fontified (text property) 33.19.4 特殊な意味をもつプロパティ
fontp 41.12.12 低レベルのフォント表現
fontset 41.12.11 フォントセット
foo 1.3.7.1 関数の説明例
for 14.5.2 マクロ引数の多重評価
force coding system for operation 34.10.6 単一の操作にたいするコーディングシステムの指定
force entry to debugger 19.1.6 明示的なデバッガへのエントリー
force-mode-line-update 24.4.1 モードラインの基礎
force-window-update 41.2 強制的な再表示
forcing redisplay 41.2 強制的な再表示
foreground-color, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
form 10.1 評価の概要
form, self-evaluating 10.2.1 自己評価を行うフォーム
format 4.7 文字列のフォーマット
format definition 26.13.2 ラウンドトリップ仕様
format of gnutls cryptography inputs 33.28.1 GnuTLS暗号化入力のフォーマット
format of keymaps 23.3 キーマップのフォーマット
format specification 4.7 文字列のフォーマット
format, customization keyword 15.4.4 型キーワード
format-alist 26.13.2 ラウンドトリップ仕様
format-find-file 26.13.2 ラウンドトリップ仕様
format-insert-file 26.13.2 ラウンドトリップ仕様
format-message 4.7 文字列のフォーマット
format-mode-line 24.4.8 モードラインのフォーマットのエミュレート
format-network-address 40.18 その他のネットワーク機能
format-prompt 21.2 ミニバッファーでのテキスト文字列の読み取り
format-seconds 42.8 時刻のパースとフォーマット
format-spec 4.8 カスタムフォーマット文字列
format-time-string 42.8 時刻のパースとフォーマット
format-write-file 26.13.2 ラウンドトリップ仕様
formatting numbers for rereading later 4.7 文字列のフォーマット
formatting strings 4.7 文字列のフォーマット
formatting time values 42.8 時刻のパースとフォーマット
formfeed 2.4.3.1 基本的な文字構文
forms for cleanup 11.7.4 非ローカル脱出のクリーンアップ
forms for control structures 11 制御構造
forms for handling errors 11.7.3.3 エラーを処理するコードの記述
forms for nonlocal exits 11.7.1 明示的な非ローカル脱出: catchthrow
forms for sequential execution 11.1 順序
forms, backquote 10.4 バッククォート
forms, conditional 11.2 条件
forms, function call 10.2.5 関数フォームの評価
forms, iteration 11.5 繰り返し
forms, list 10.2.3 リストフォームの分類
forms, macro call 10.2.6 Lispマクロの評価
forms, quote 10.3 クォート
forms, special 10.2.7 スペシャルフォーム
forms, symbol 10.2.2 シンボルのフォーム
forward-button 41.20.5 ボタンのためのバッファーコマンド
forward-char 31.2.1 文字単位の移動
forward-comment 36.6.1 パースにもとづくモーションコマンド
forward-line 31.2.4 テキスト行単位の移動
forward-list 31.2.6 釣り合いのとれたカッコを越えた移動
forward-sexp 31.2.6 釣り合いのとれたカッコを越えた移動
forward-to-indentation 33.17.6 インデントにもとづくモーションコマンド
forward-word 31.2.2 単語単位の移動
forward-word-strictly 31.2.2 単語単位の移動
frame 30 フレーム
frame configuration 30.13 フレーム構成
frame creation 30.1 フレームの作成
frame geometry 30.3 フレームのジオメトリー
frame height ratio 30.4.3.3 サイズのパラメーター
frame interaction parameters 30.4.3.6 フレームとの相互作用のためのパラメーター
frame layout 30.3.1 フレームのレイアウト
frame layout parameters 30.4.3.4 レイアウトのパラメーター
frame parameters 30.4 フレームのパラメーター
frame parameters for windowed displays 30.4.3 ウィンドウフレームパラメーター
frame position 30.3 フレームのジオメトリー
frame position 30.3.3 フレームの位置
frame position 30.4.3.2 位置のパラメーター
frame position changes, a hook 30.3.3 フレームの位置
frame size 30.3 フレームのジオメトリー
frame size 30.3.4 フレームのサイズ
frame stacking order 30.12 フレームのraise、lower、re-stack
frame title 30.6 フレームのタイトル
frame visibility 30.11 フレームの可視性
frame width ratio 30.4.3.3 サイズのパラメーター
frame without a minibuffer 30.9 ミニバッファーとフレーム
frame Z-order 30.12 フレームのraise、lower、re-stack
frame, which buffers to display 30.4.3.5 バッファーのパラメーター
frame-alpha-lower-limit 30.4.3.10 フォントとカラーのパラメーター
frame-ancestor-p 30.14 子フレーム
frame-auto-hide-function 29.16 ウィンドウのquit
frame-char-height 30.3.2 フレームのフォント
frame-char-width 30.3.2 フレームのフォント
frame-current-scroll-bars 41.14 スクロールバー
frame-edges 30.3.1 フレームのレイアウト
frame-first-window 29.2 ウィンドウとフレーム
frame-focus-state 30.10 入力のフォーカス
frame-geometry 30.3.1 フレームのレイアウト
frame-height 30.3.4 フレームのサイズ
frame-inherited-parameters 30.1 フレームの作成
frame-inhibit-implied-resize 30.3.5 フレームの暗黙的なリサイズ
frame-inner-height 30.3.4 フレームのサイズ
frame-inner-width 30.3.4 フレームのサイズ
frame-list 30.8 すべてのフレームを探す
frame-list-z-order 30.8 すべてのフレームを探す
frame-live-p 30.7 フレームの削除
frame-monitor-attributes 30.2 複数の端末
frame-native-height 30.3.4 フレームのサイズ
frame-native-width 30.3.4 フレームのサイズ
frame-old-selected-window 29.28 ウィンドウのスクロールと変更のためのフック
frame-outer-height 30.3.4 フレームのサイズ
frame-outer-width 30.3.4 フレームのサイズ
frame-parameter 30.4.1 フレームパラメーターへのアクセス
frame-parameters 30.4.1 フレームパラメーターへのアクセス
frame-parent 30.14 子フレーム
frame-pointer-visible-p 30.16 マウスの位置
frame-position 30.3.3 フレームの位置
frame-predicate, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
frame-relative coordinate 29.24 座標とウィンドウ
frame-resize-pixelwise 30.3.4 フレームのサイズ
frame-restack 30.12 フレームのraise、lower、re-stack
frame-root-window 29.2 ウィンドウとフレーム
frame-scroll-bar-height 41.14 スクロールバー
frame-scroll-bar-width 41.14 スクロールバー
frame-selected-window 29.3 ウィンドウの選択
frame-size-changed-p 30.3.4 フレームのサイズ
frame-terminal 30 フレーム
frame-text-height 30.3.4 フレームのサイズ
frame-text-width 30.3.4 フレームのサイズ
frame-title-format 30.6 フレームのタイトル
frame-visible-p 30.11 フレームの可視性
frame-width 30.3.4 フレームのサイズ
frame-window-state-change 29.28 ウィンドウのスクロールと変更のためのフック
framep 30 フレーム
frames, scanning all 30.8 すべてのフレームを探す
frameset 33.21 レジスター
free list E.3 ガーベージコレクション
free variable 12.10.5 レキシカルバインディングへの変換
free variable, byte-compiler warning 17.6 コンパイラーのエラー
free_global_ref E.8.3 Lisp・モジュール間の値変換
frequency counts 19.2.13 カバレッジテスト
frexp 3.2 浮動小数点数の基礎
fringe bitmaps 41.13.4 フリンジのビットマップ
fringe bitmaps, customizing 41.13.5 フリンジビットマップのカスタマイズ
fringe cursors 41.13.3 フリンジのカーソルFrin
fringe indicators 41.13.2 フリンジのインジケーター
fringe-bitmaps-at-pos 41.13.4 フリンジのビットマップ
fringe-cursor-alist 41.13.3 フリンジのカーソルFrin
fringe-indicator-alist 41.13.2 フリンジのインジケーター
fringes 41.13 フリンジ
fringes, and empty line indication 41.13.2 フリンジのインジケーター
fringes-outside-margins 41.13.1 フリンジのサイズと位置
front-sticky text property 33.19.6 テキストプロパティの粘着性
fround 3.7 丸め処理
fset 13.9 関数セルの内容へのアクセス
ftp-login 11.7.4 非ローカル脱出のクリーンアップ
ftruncate 3.7 丸め処理
full keymap 23.3 キーマップのフォーマット
full-height window 29.4 ウィンドウのサイズ
full-width window 29.4 ウィンドウのサイズ
fullboth frames 30.4.3.3 サイズのパラメーター
fullheight frames 30.4.3.3 サイズのパラメーター
fullscreen, a frame parameter 30.4.3.3 サイズのパラメーター
fullscreen-restore, a frame parameter 30.4.3.3 サイズのパラメーター
fullwidth frames 30.4.3.3 サイズのパラメーター
func-arity 13.1 関数とは?
funcall 13.5 関数の呼び出し
funcall E.8.4 その他の便利なモジュール用関数
funcall, and debugging 19.1.11 デバッガの内部
funcall-interactively 22.3 インタラクティブな呼び出し
function 13.7 無名関数
function aliases 13.4 関数の定義
function call 10.2.5 関数フォームの評価
function call debugging 19.1.4 関数呼び出しによるデバッガへのエンター
function cell 9.1 シンボルの構成要素
function cell in autoload 16.5 autoload
function declaration 13.16 コンパイラーへの定義済み関数の指示
function definition 13.3 関数の命名
function descriptions 1.3.7.1 関数の説明例
function form evaluation 10.2.5 関数フォームの評価
function groups 25.7 ドキュメントのグループ
function input stream 20.2 入力ストリーム
function invocation 13.5 関数の呼び出し
function keys 22.7.2 ファンクションキー
function name 13.3 関数の命名
function not known to be defined, compilation warning 17.6 コンパイラーのエラー
function output stream 20.4 出力ストリーム
function quoting 13.7 無名関数
function safety 13.17 安全に関数を呼び出せるかどうかの判断
function’s documentation string 13.2.4 関数のドキュメント文字列
function-alias-p 13.4 関数の定義
function-documentation 25.2 ドキュメント文字列へのアクセス
function-documentation property 25.1 ドキュメントの基礎
function-get 9.4.1 シンボルのプロパティへのアクセス
function-history (function symbol property) 16.8 どのファイルで特定のシンボルが定義されているか
function-key-map 23.15 イベントシーケンス変換のためのキーマップ
function-put 9.4.1 シンボルのプロパティへのアクセス
functionals 13.5 関数の呼び出し
functionp 13.1 関数とは?
functions in modes 24.2.1 メジャーモードの慣習
functions, making them interactive 22.2 コマンドの定義
fundamental-mode 24.2 メジャーモード
fundamental-mode-abbrev-table 38.5 標準abbrevテーブル
future history in minibuffer input 21.2 ミニバッファーでのテキスト文字列の読み取り

G
gamma correction 30.4.3.10 フォントとカラーのパラメーター
gap-position 28.13 バッファーのギャップ
gap-size 28.13 バッファーのギャップ
garbage collection E.3 ガーベージコレクション
garbage collection protection E.7 Emacsプリミティブの記述
garbage-collect E.3 ガーベージコレクション
garbage-collection-messages E.3 ガーベージコレクション
gc-cons-percentage E.3 ガーベージコレクション
gc-cons-threshold E.3 ガーベージコレクション
gc-elapsed E.3 ガーベージコレクション
gcs-done E.3 ガーベージコレクション
generalized variable 12.17 ジェネリック変数
generate-new-buffer 28.9 バッファーの作成
generate-new-buffer-name 28.3 バッファーの名前
generated-autoload-file 16.5 autoload
generators 11.6 ジェネレーター
generic commands 22.2.5 コマンド候補からの選択
generic functions 13.8 ジェネリック関数
generic mode 24.2.8 ジェネリックモード
gensym 9.3 シンボルの作成とintern
geometry specification 30.4.4 ジオメトリー
get 9.4.1 シンボルのプロパティへのアクセス
get node, tree-sitter 37.3 ノードの取得
get, defcustom keyword 15.3 カスタマイゼーション変数の定義
get-buffer 28.3 バッファーの名前
get-buffer-create 28.9 バッファーの作成
get-buffer-process 40.9.1 プロセスのバッファー
get-buffer-window 29.11 バッファーとウィンドウ
get-buffer-window-list 29.11 バッファーとウィンドウ
get-buffer-xwidgets 41.19 埋め込みネイティブウィジェット
get-byte 34.5 文字コード
get-char-code-property 34.6 文字のプロパティ
get-char-property 33.19.1 テキストプロパティを調べる
get-char-property-and-overlay 33.19.1 テキストプロパティを調べる
get-charset-property 34.7 文字セット
get-device-terminal 30.2 複数の端末
get-display-property 41.16 displayプロパティ
get-file-buffer 28.4 バッファーのファイル名
get-internal-run-time 42.9 プロセッサーの実行時間
get-largest-window 29.10 ウィンドウのサイクル順
get-load-suffixes 16.2 ロードでの拡張子
get-lru-window 29.10 ウィンドウのサイクル順
get-mru-window 29.10 ウィンドウのサイクル順
get-pos-property 33.19.1 テキストプロパティを調べる
get-process 40.6 プロセスの情報
get-register 33.21 レジスター
get-text-property 33.19.1 テキストプロパティを調べる
get-unused-category 36.8 カテゴリー
get-variable-watchers 12.9 変数が変更されたときに実行される関数。
get-window-with-predicate 29.10 ウィンドウのサイクル順
getenv 42.3 オペレーティングシステムの環境
gethash 8.2 ハッシュテーブルへのアクセス
get_function_finalizer E.8.2 モジュール関数の記述
get_user_finalizer E.8.3 Lisp・モジュール間の値変換
get_user_ptr E.8.3 Lisp・モジュール間の値変換
GID 42.4 ユーザーの識別
global binding 12.3 ローカル変数
global break condition 19.2.6.2 グローバルなブレーク条件
global keymap 23.7 アクティブなキーマップ
global variable 12.1 グローバル変数
global-abbrev-table 38.5 標準abbrevテーブル
global-buffers-menu-map Appendix G 標準的なキーマップ
global-disable-point-adjustment 22.6 コマンド後のポイントの調整
global-key-binding 23.13 低レベルなキーバインディング
global-map 23.9 アクティブなキーマップの制御
global-minor-modes 24.3 マイナーモード
global-mode-string 24.4.4 モードラインで使用される変数
global-set-key 23.13 低レベルなキーバインディング
global-unset-key 23.13 低レベルなキーバインディング
glyph 41.23.4 グリフ
glyph code 41.23.4 グリフ
glyph-char 41.23.4 グリフ
glyph-face 41.23.4 グリフ
glyph-table 41.23.4 グリフ
glyphless characters 41.23.5 グリフなし文字の表示
glyphless-char face 41.23.5 グリフなし文字の表示
glyphless-char-display 41.23.5 グリフなし文字の表示
glyphless-char-display-control 41.23.5 グリフなし文字の表示
glyphless-display-mode 41.23.5 グリフなし文字の表示
GNU ELPA 43.4 パッケージアーカイブの作成と保守
gnutls cryptographic functions 33.28.2 GnuTLS暗号化関数
gnutls cryptography inputs format 33.28.1 GnuTLS暗号化入力のフォーマット
gnutls-ciphers 33.28.2 GnuTLS暗号化関数
gnutls-digests 33.28.2 GnuTLS暗号化関数
gnutls-hash-digest 33.28.2 GnuTLS暗号化関数
gnutls-hash-mac 33.28.2 GnuTLS暗号化関数
gnutls-macs 33.28.2 GnuTLS暗号化関数
gnutls-symmetric-decrypt 33.28.2 GnuTLS暗号化関数
gnutls-symmetric-encrypt 33.28.2 GnuTLS暗号化関数
goto-char 31.2.1 文字単位の移動
goto-history-element 21.10 ミニバッファーのコマンド
goto-line-history 21.4 ミニバッファーのヒストリー
goto-map 23.6 プレフィクスキー
grammar, SMIE 24.7.1.3 言語の文法の定義
grand-parent 24.7.2 パーサーベースのインデント
grapheme cluster 41.10 表示されるテキストのサイズ
graphical display 30 フレーム
graphical terminal 30 フレーム
grave accent, quoting in documentation strings D.6 ドキュメント文字列のヒント
great-grand-parent 24.7.2 パーサーベースのインデント
group in rx 35.3.3.1 rxによるregexpの構築
group, customization keyword 15.1 一般的なキーワードアイテム
group-function, in completion 21.6.7 プログラムされた補完
group-gid 42.4 ユーザーの識別
group-n in rx 35.3.3.1 rxによるregexpの構築
group-name 42.4 ユーザーの識別
group-real-gid 42.4 ユーザーの識別
groups of functions 25.7 ドキュメントのグループ
gui-get-selection 30.20 ウィンドウシステムによる選択
gui-set-selection 30.20 ウィンドウシステムによる選択
guidelines for buffer display 29.13.6 バッファー表示の思想
gv-define-expander 12.17.2 新たなsetfフォーム
gv-define-setter 12.17.2 新たなsetfフォーム
gv-define-simple-setter 12.17.2 新たなsetfフォーム
gv-letplace 12.17.2 新たなsetfフォーム

H
hack-connection-local-variables 12.14.2 接続ローカル変数の適用
hack-connection-local-variables-apply 12.14.2 接続ローカル変数の適用
hack-dir-local-variables 12.13 ディレクトリーローカル変数
hack-dir-local-variables-non-file-buffer 12.13 ディレクトリーローカル変数
hack-local-variables 12.12 ファイルローカル変数
hack-local-variables-hook 12.12 ファイルローカル変数
Hamming weight 3.8 整数にたいするビット演算
handle Lisp errors 11.7.3.3 エラーを処理するコードの記述
handle-focus-in 30.10 入力のフォーカス
handle-shift-selection 32.7 マーク
handle-switch-frame 30.10 入力のフォーカス
handling errors 11.7.3.3 エラーを処理するコードの記述
hardening 42.22 セキュリティへの配慮
has error, tree-sitter node 37.4 ノード情報へのアクセス
hash code 8.3 ハッシュの比較の定義
hash notation 2.1 プリント表現と読み取り構文
hash table access 8.2 ハッシュテーブルへのアクセス
hash tables 8 ハッシュテーブル
hash, cryptographic 33.26 チェックサムとハッシュ
hash, cryptographic 33.28 GnuTLS暗号化
hash-table-count 8.4 ハッシュテーブルのためのその他関数
hash-table-p 8.4 ハッシュテーブルのためのその他関数
hash-table-rehash-size 8.4 ハッシュテーブルのためのその他関数
hash-table-rehash-threshold 8.4 ハッシュテーブルのためのその他関数
hash-table-size 8.4 ハッシュテーブルのためのその他関数
hash-table-test 8.4 ハッシュテーブルのためのその他関数
hash-table-weakness 8.4 ハッシュテーブルのためのその他関数
hashing 9.3 シンボルの作成とintern
header comments D.8 Emacsライブラリーのヘッダーの慣習
header line (of a window) 24.4.7 ウィンドウのヘッダーライン
header line alignment when line numbers are displayed 41.16.3 スペースにたいするピクセル指定
header-line, prefix key 22.8.1 キーシーケンス入力
header-line-format 24.4.7 ウィンドウのヘッダーライン
header-line-format, a window parameter 29.27 ウィンドウのパラメーター
header-line-format, and :align-to 41.16.3 スペースにたいするピクセル指定
header-line-indent 24.4.7 ウィンドウのヘッダーライン
header-line-indent-mode 24.4.7 ウィンドウのヘッダーライン
header-line-indent-width 24.4.7 ウィンドウのヘッダーライン
height of a line 41.11 行の高さ
height of a window 29.4 ウィンドウのサイズ
height spec 41.11 行の高さ
height, a frame parameter 30.4.3.3 サイズのパラメーター
help for major mode 24.2.3 メジャーモードでのヘルプ入手
help functions 25.6 ヘルプ関数
help-buffer 25.6 ヘルプ関数
help-char 25.6 ヘルプ関数
help-command 25.6 ヘルプ関数
help-echo (button property) 41.20.1 ボタンのプロパティ
help-echo (overlay property) 41.9.2 オーバーレイのプロパティ
help-echo (text property) 33.19.4 特殊な意味をもつプロパティ
help-echo event 22.7.12 その他のシステムイベント
help-echo text, avoid command-key substitution 33.19.4 特殊な意味をもつプロパティ
help-echo, customization keyword 15.4.4 型キーワード
help-echo-inhibit-substitution (text property) 33.19.4 特殊な意味をもつプロパティ
help-event-list 25.6 ヘルプ関数
help-form 25.6 ヘルプ関数
help-key-binding (face) 25.3 ドキュメント内でのキーバインディングの置き換え
help-map 25.6 ヘルプ関数
help-setup-xref 25.6 ヘルプ関数
help-window-select 25.6 ヘルプ関数
Helper-describe-bindings 25.6 ヘルプ関数
Helper-help 25.6 ヘルプ関数
Helper-help-map 25.6 ヘルプ関数
hex numbers 3.1 整数の基礎
hidden buffers 28.3 バッファーの名前
history list 21.4 ミニバッファーのヒストリー
history of commands 22.15 コマンドのヒストリー
history-add-new-input 21.4 ミニバッファーのヒストリー
history-delete-duplicates 21.4 ミニバッファーのヒストリー
history-length 21.4 ミニバッファーのヒストリー
HOME environment variable 40.1 サブプロセスを作成する関数
hook variables, list of Appendix H 標準的なフック
hooks 24.1 フック
hooks for changing a character 33.19.4 特殊な意味をもつプロパティ
hooks for loading 16.10 ロードのためのフック
hooks for motion of point 33.19.4 特殊な意味をもつプロパティ
hooks for text changes 33.34 フックの変更
hooks for window operations 29.28 ウィンドウのスクロールと変更のためのフック
horizontal combination 29.2 ウィンドウとフレーム
horizontal position 33.16 列を数える
horizontal scrolling 29.23 水平スクロール
horizontal-lineto 41.17.6 SVGイメージ
horizontal-scroll-bar 41.14 スクロールバー
horizontal-scroll-bar, prefix key 22.8.1 キーシーケンス入力
horizontal-scroll-bar-mode 41.14 スクロールバー
horizontal-scroll-bars, a frame parameter 30.4.3.4 レイアウトのパラメーター
horizontal-scroll-bars-available-p 41.14 スクロールバー
host language, tree-sitter 37.6 複数言語ののパース
how to visit files 26.1.1 ファイルをvisitする関数
HTML DOM 33.30.1 ドキュメントオブジェクトモデル
hyper characters 2.4.3.5 その他の文字修飾ビット
hyperlinks in documentation strings D.6 ドキュメント文字列のヒント

I
icon keywords 41.18 アイコン
icon types 41.18 アイコン
icon-elements 41.18 アイコン
icon-left, a frame parameter 30.4.3.2 位置のパラメーター
icon-name, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
icon-string 41.18 アイコン
icon-title-format 30.6 フレームのタイトル
icon-top, a frame parameter 30.4.3.2 位置のパラメーター
icon-type, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
iconified frame 30.11 フレームの可視性
iconify-child-frame 30.14 子フレーム
iconify-frame 30.11 フレームの可視性
iconify-frame event 22.7.12 その他のシステムイベント
identical-contents objects, and byte-compiler 2.8 同等性のための述語
identity 13.5 関数の呼び出し
idle timers 42.12 アイドルタイマー
idleness 42.12 アイドルタイマー
IEEE floating point 3.2 浮動小数点数の基礎
if 11.2 条件
if-let 11.2 条件
ignore 13.5 関数の呼び出し
ignore-error 11.7.3.3 エラーを処理するコードの記述
ignore-errors 11.7.3.3 エラーを処理するコードの記述
ignore-window-parameters 29.27 ウィンドウのパラメーター
ignored-local-variable-values 12.12 ファイルローカル変数
ignored-local-variables 12.12 ファイルローカル変数
image animation 41.17.10 マルチフレームのイメージ
image cache 41.17.11 イメージキャッシュ
image descriptor 41.17.2 イメージのディスクリプタ
image formats 41.17.1 イメージのフォーマット
image frames 41.17.10 マルチフレームのイメージ
image maps 41.17.2 イメージのディスクリプタ
image slice 41.17.9 イメージの表示
image types 41.17.1 イメージのフォーマット
image-animate 41.17.10 マルチフレームのイメージ
image-animate-timer 41.17.10 マルチフレームのイメージ
image-at-point-p 41.17.9 イメージの表示
image-cache-eviction-delay 41.17.11 イメージキャッシュ
image-cache-size 41.17.11 イメージキャッシュ
image-crop 41.17.9 イメージの表示
image-current-frame 41.17.10 マルチフレームのイメージ
image-cut 41.17.9 イメージの表示
image-decrease-size 41.17.9 イメージの表示
image-default-frame-delay 41.17.10 マルチフレームのイメージ
image-flip-horizontally 41.17.9 イメージの表示
image-flip-vertically 41.17.9 イメージの表示
image-flush 41.17.11 イメージキャッシュ
image-format-suffixes 41.17.5 ImageMagickイメージ
image-increase-size 41.17.9 イメージの表示
image-load-path 41.17.8 イメージの定義
image-load-path-for-library 41.17.8 イメージの定義
image-mask-p 41.17.2 イメージのディスクリプタ
image-minimum-frame-delay 41.17.10 マルチフレームのイメージ
image-multi-frame-p 41.17.10 マルチフレームのイメージ
image-property 41.17.8 イメージの定義
image-rotate 41.17.9 イメージの表示
image-save 41.17.9 イメージの表示
image-scaling-factor 41.17.8 イメージの定義
image-show-frame 41.17.10 マルチフレームのイメージ
image-size 41.17.9 イメージの表示
image-transforms-p 41.17.2 イメージのディスクリプタ
image-type-available-p 41.17.1 イメージのフォーマット
image-types 41.17.1 イメージのフォーマット
ImageMagick images 41.17.5 ImageMagickイメージ
imagemagick-enabled-types 41.17.5 ImageMagickイメージ
imagemagick-types 41.17.5 ImageMagickイメージ
imagemagick-types-inhibit 41.17.5 ImageMagickイメージ
images in buffers 41.17 イメージ
images, support for more formats 41.17.5 ImageMagickイメージ
Imenu 24.5 Imenu
imenu-add-to-menubar 24.5 Imenu
imenu-case-fold-search 24.5 Imenu
imenu-create-index-function 24.5 Imenu
imenu-extract-index-name-function 24.5 Imenu
imenu-generic-expression 24.5 Imenu
imenu-prev-index-position-function 24.5 Imenu
imenu-syntax-alist 24.5 Imenu
implicit progn 11.1 順序
implied frame resizing 30.3.5 フレームの暗黙的なリサイズ
implied resizing of frame 30.3.5 フレームの暗黙的なリサイズ
in in rx 35.3.3.1 rxによるregexpの構築
inactive minibuffer 21.1 ミニバッファーの概要
inc 14.1 単純なマクロの例
indefinite extent 12.10 変数のバインディングのスコーピングルール
indent-according-to-mode 33.17.2 メジャーモードが制御するインデント
indent-code-rigidly 33.17.3 リージョン全体のインデント
indent-for-tab-command 33.17.2 メジャーモードが制御するインデント
indent-line-function 33.17.2 メジャーモードが制御するインデント
indent-region 33.17.3 リージョン全体のインデント
indent-region-function 33.17.3 リージョン全体のインデント
indent-relative 33.17.4 前行に相対的なインデント
indent-relative-first-indent-point 33.17.4 前行に相対的なインデント
indent-rigidly 33.17.3 リージョン全体のインデント
indent-tabs-mode 33.17.1 インデント用のプリミティブ
indent-to 33.17.1 インデント用のプリミティブ
indent-to-left-margin 33.12 fillのマージン
indentation 33.17 インデント
indentation rules, for parser-based indentation 24.7.2 パーサーベースのインデント
indentation rules, SMIE 24.7.1.6 インデントルールの指定
indicate-buffer-boundaries 41.13.2 フリンジのインジケーター
indicate-empty-lines 41.13.2 フリンジのインジケーター
indicators, fringe 41.13.2 フリンジのインジケーター
indirect buffers 28.11 インダイレクトバッファー
indirect specifications 19.2.15.2 仕様リスト
indirect-function 10.2.4 シンボル関数インダイレクション
indirect-variable 12.15 変数のエイリアス
indirection for functions 10.2.4 シンボル関数インダイレクション
infinite loops 19.1.3 無限ループのデバッグ
infinity 3.2 浮動小数点数の基礎
information of node, syntax trees 37.4 ノード情報へのアクセス
inheritance, for faces 41.12.1 フェイスの属性
inheritance, keymap 23.5 継承とキーマップ
inheritance, syntax table 36.1 構文テーブルの概念
inheritance, text property 33.19.6 テキストプロパティの粘着性
inhibit asynchronous native compilation 18.2 ネイティブコンパイル関数
inhibit-default-init 42.1.2 initファイル
inhibit-double-buffering, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
inhibit-eol-conversion 34.10.6 単一の操作にたいするコーディングシステムの指定
inhibit-field-text-motion 31.2.2 単語単位の移動
inhibit-file-name-handlers 26.12 特定のファイル名の“Magic”の作成
inhibit-file-name-operation 26.12 特定のファイル名の“Magic”の作成
inhibit-interaction 21.14 対話の抑止
inhibit-isearch (text property) 33.19.4 特殊な意味をもつプロパティ
inhibit-iso-escape-detection 34.10.3 Lispでのコーディングシステム
inhibit-local-variables-regexps 12.12 ファイルローカル変数
inhibit-local-variables-regexps 24.2.2 Emacsがメジャーモードを選択する方法
inhibit-message 41.4.1 エコーエリアへのメッセージの表示
inhibit-message 41.4.1 エコーエリアへのメッセージの表示
inhibit-message-regexps 41.4.1 エコーエリアへのメッセージの表示
inhibit-modification-hooks 33.34 フックの変更
inhibit-null-byte-detection 34.10.3 Lispでのコーディングシステム
inhibit-point-motion-hooks 33.19.4 特殊な意味をもつプロパティ
inhibit-quit 22.11 quit
inhibit-read-only 28.7 読み取り専用のバッファー
inhibit-read-only (text property) 33.19.4 特殊な意味をもつプロパティ
inhibit-same-window, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
inhibit-splash-screen 42.1.1 要約: スタートアップ時のアクション順序
inhibit-startup-echo-area-message 42.1.1 要約: スタートアップ時のアクション順序
inhibit-startup-message 42.1.1 要約: スタートアップ時のアクション順序
inhibit-startup-screen 42.1.1 要約: スタートアップ時のアクション順序
inhibit-switch-frame, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
inhibit-x-resources 30.25 Xリソース
init file 42.1.2 initファイル
init-file-user 42.4 ユーザーの識別
init.el 42.1.2 initファイル
initial-buffer-choice 42.1.1 要約: スタートアップ時のアクション順序
initial-environment 42.3 オペレーティングシステムの環境
initial-frame-alist 30.4.2 フレームの初期パラメーター
initial-major-mode 24.2.2 Emacsがメジャーモードを選択する方法
initial-scratch-message 42.1.1 要約: スタートアップ時のアクション順序
initial-window-system 41.25 ウィンドウシステム
initial-window-system, and startup 42.1.1 要約: スタートアップ時のアクション順序
initialization of Emacs 42.1.1 要約: スタートアップ時のアクション順序
initialize, defcustom keyword 15.3 カスタマイゼーション変数の定義
initiating drag-and-drop 30.22 ドラッグアンドドロップ
initiating drag-and-drop, low-level 30.22 ドラッグアンドドロップ
inline completion 21.6.8 通常バッファーでの補完
inline functions 13.14 インライン関数Inli
inline-const-p 13.14 インライン関数Inli
inline-const-val 13.14 インライン関数Inli
inline-error 13.14 インライン関数Inli
inline-letevals 13.14 インライン関数Inli
inline-quote 13.14 インライン関数Inli
inner edges 30.3.1 フレームのレイアウト
inner frame 30.3.1 フレームのレイアウト
inner height 30.3.1 フレームのレイアウト
inner size 30.3.1 フレームのレイアウト
inner width 30.3.1 フレームのレイアウト
innermost containing parentheses 36.6.3 パーサー状態
input devices 22.5 コマンドループからの情報
input events 22.7 入力イベント
input events, prevent recording 22.8.6 その他のイベント入力の機能
input focus 30.10 入力のフォーカス
input methods 34.11 入力メソッド
input modes 42.13.1 入力のモード
input stream 20.2 入力ストリーム
input-decode-map 23.15 イベントシーケンス変換のためのキーマップ
input-method-alist 34.11 入力メソッド
input-method-function 22.8.4 入力メソッドの呼び出し
input-pending-p 22.8.6 その他のイベント入力の機能
insecure text 33.27 不審なテキスト
insert 33.4 テキストの挿入
insert-abbrev-table-description 38.1 abbrevテーブル
insert-and-inherit 33.19.6 テキストプロパティの粘着性
insert-before-markers 33.4 テキストの挿入
insert-before-markers-and-inherit 33.19.6 テキストプロパティの粘着性
insert-behind-hooks (overlay property) 41.9.2 オーバーレイのプロパティ
insert-behind-hooks (text property) 33.19.4 特殊な意味をもつプロパティ
insert-buffer 33.5 ユーザーレベルの挿入コマンド
insert-buffer-substring 33.4 テキストの挿入
insert-buffer-substring-as-yank 33.8.3 yank
insert-buffer-substring-no-properties 33.4 テキストの挿入
insert-button 41.20.3 ボタンの作成
insert-char 33.4 テキストの挿入
insert-default-directory 21.6.5 ファイル名の読み取り
insert-directory 26.10 ディレクトリーのコンテンツ
insert-directory-program 26.10 ディレクトリーのコンテンツ
insert-file-contents 26.3 ファイルからの読み込み
insert-file-contents-literally 26.3 ファイルからの読み込み
insert-for-yank 33.8.3 yank
insert-image 41.17.9 イメージの表示
insert-in-front-hooks (overlay property) 41.9.2 オーバーレイのプロパティ
insert-in-front-hooks (text property) 33.19.4 特殊な意味をもつプロパティ
insert-into-buffer 33.4 テキストの挿入
insert-register 33.21 レジスター
insert-sliced-image 41.17.9 イメージの表示
insert-text-button 41.20.3 ボタンの作成
inserting killed text 33.8.4 yank用の関数
insertion before point 33.4 テキストの挿入
insertion of text 33.4 テキストの挿入
insertion type of a marker 32.5 マーカーの挿入タイプ
inside comment 36.6.3 パーサー状態
inside string 36.6.3 パーサー状態
inspection of tree-sitter parse tree nodes 37.1 Tree-sitter Language Grammar
installation-directory 42.3 オペレーティングシステムの環境
instrumenting for Edebug 19.2.2 Edebugのためのインストルメント
int-to-string 4.6 文字および文字列の変換
intangible (overlay property) 41.9.2 オーバーレイのプロパティ
intangible (text property) 33.19.4 特殊な意味をもつプロパティ
integer range 3.1 整数の基礎
integer to decimal 4.6 文字および文字列の変換
integer to hexadecimal 4.7 文字列のフォーマット
integer to octal 4.7 文字列のフォーマット
integer to string 4.6 文字および文字列の変換
integer types (C programming language) E.10 Cの整数型
integer-or-marker-p 32.2 マーカーのための述語
integer-width 3.1 整数の基礎
integerp 3.3 数値のための述語
integers 3 数値
integers in specific radix 3.1 整数の基礎
interaction parameters between frames 30.4.3.6 フレームとの相互作用のためのパラメーター
interactive 22.2.1 interactiveの使用
interactive call 22.3 インタラクティブな呼び出し
interactive code description 22.2.2 interactiveにたいするコード文字
interactive completion 22.2.2 interactiveにたいするコード文字
interactive function 22.2 コマンドの定義
interactive spec, using 22.2.1 interactiveの使用
interactive specification in primitives E.7 Emacsプリミティブの記述
interactive, examples of using 22.2.3 interactiveの使用例
interactive-form 22.2.1 interactiveの使用
interactive-form property 22.2 コマンドの定義
interactive-form, symbol property 22.2.1 interactiveの使用
interactive-only property 22.2 コマンドの定義
intern 9.3 シンボルの作成とintern
intern E.8.4 その他の便利なモジュール用関数
intern-soft 9.3 シンボルの作成とintern
internal menu bar 30.3.1 フレームのレイアウト
internal representation of characters 34.1 テキストの表現方法
internal tool bar 30.3.1 フレームのレイアウト
internal windows 29.1 Emacsウィンドウの基本概念
internal-border-width, a frame parameter 30.4.3.4 レイアウトのパラメーター
internals, of buffer E.9.1 バッファーの内部
internals, of process E.9.3 プロセスの内部
internals, of window E.9.2 ウィンドウの内部
interning 9.3 シンボルの作成とintern
interpreter 10 評価
interpreter 10 評価
interpreter-mode-alist 24.2.2 Emacsがメジャーモードを選択する方法
interprogram-cut-function 33.8.5 低レベルのkillリング
interprogram-paste-function 33.8.5 低レベルのkillリング
interrupt Lisp functions 22.11 quit
interrupt-process 40.8 プロセスへのシグナルの送信
interrupt-process-functions 40.8 プロセスへのシグナルの送信
intersection in rx 35.3.3.1 rxによるregexpの構築
intersection of sequences 6.1 シーケンス
intervals 33.19.10 なぜテキストプロパティはインターバルではないのか
intervals-consed E.5 メモリー使用量
invalid prefix key error 23.12 キーバインディングの変更
invalid-function 10.2.4 シンボル関数インダイレクション
invalid-read-syntax 2.1 プリント表現と読み取り構文
invalid-regexp 35.3.1.3 正規表現内のバッククラッシュ構文
invert-face 41.12.3 フェイス属性のための関数
invisible (overlay property) 41.9.2 オーバーレイのプロパティ
invisible (text property) 33.19.4 特殊な意味をもつプロパティ
invisible frame 30.11 フレームの可視性
invisible text 41.6 不可視のテキスト
invisible-p 41.6 不可視のテキスト
invisible/intangible text, and point 22.6 コマンド後のポイントの調整
invocation-directory 42.3 オペレーティングシステムの環境
invocation-name 42.3 オペレーティングシステムの環境
invoking input method 22.8.4 入力メソッドの呼び出し
invoking lisp debugger 19.1.10 デバッガの呼び出し
is this call interactive 22.4 インタラクティブな呼び出しの区別
isnan 3.2 浮動小数点数の基礎
ISO 8601 date/time strings 42.8 時刻のパースとフォーマット
ISO week, in time formatting 42.8 時刻のパースとフォーマット
iso8601-parse 42.8 時刻のパースとフォーマット
is_not_nil E.8.4 その他の便利なモジュール用関数
italic text 41.12.1 フェイスの属性
iter-close 11.6 ジェネレーター
iter-defun 11.6 ジェネレーター
iter-do 11.6 ジェネレーター
iter-lambda 11.6 ジェネレーター
iter-next 11.6 ジェネレーター
iter-yield 11.6 ジェネレーター
iter-yield-from 11.6 ジェネレーター
iteration 11.5 繰り返し
iteration over vector or string 6.1 シーケンス

J
JavaScript Object Notation 33.31 JSON値の解析と生成
javascript-callback xwidget events 22.7.11 Xwidgetイベント
jit-lock functions, debugging 24.6.4 Font Lockのその他の変数
jit-lock-debug-mode 24.6.4 Font Lockのその他の変数
jit-lock-register 24.6.4 Font Lockのその他の変数
jit-lock-unregister 24.6.4 Font Lockのその他の変数
joining lists 5.6.3 リストを再配置する関数
JSON 33.31 JSON値の解析と生成
JSON remote procedure call protocol 33.32 JSONRPCによる対話
json-available-p 33.31 JSON値の解析と生成
json-insert 33.31 JSON値の解析と生成
json-parse-buffer 33.31 JSON値の解析と生成
json-parse-string 33.31 JSON値の解析と生成
json-serialize 33.31 JSON値の解析と生成
JSONRPC 33.32 JSONRPCによる対話
JSONRPC application interfaces 33.32.1 概観
JSONRPC connection initargs 33.32.2 プロセスベースのJSONRPC接続
JSONRPC deferred requests 33.32.4 遅延されたJSONRPCリクエスト
JSONRPC object format 33.32.3 JSONRPCのJSONオブジェクトフォーマット
JSONRPC process-based connections 33.32.2 プロセスベースのJSONRPC接続
jsonrpc-async-request 33.32.1 概観
jsonrpc-connection 33.32.1 概観
jsonrpc-connection-ready-p 33.32.4 遅延されたJSONRPCリクエスト
jsonrpc-connection-receive 33.32.1 概観
jsonrpc-connection-send 33.32.1 概観
jsonrpc-error 33.32.1 概観
jsonrpc-lambda 33.32.3 JSONRPCのJSONオブジェクトフォーマット
jsonrpc-notify 33.32.1 概観
jsonrpc-process-connection 33.32.2 プロセスベースのJSONRPC接続
jsonrpc-request 33.32.1 概観
jsonrpc-running-p 33.32.1 概観
jsonrpc-shutdown 33.32.1 概観
jumbled display of bidirectional text 41.27 双方向テキストの表示
just-one-space 33.7 ユーザーレベルの削除コマンド
justify-current-line 33.11 fill

K
kbd 23.1 キーシーケンス
kbd-macro-termination-hook 22.16 キーボードマクロ
keep-ratio, a frame parameter 30.4.3.6 フレームとの相互作用のためのパラメーター
kept-new-versions 27.1.3 番号つきバックアップファイルの作成と削除
kept-old-versions 27.1.3 番号つきバックアップファイルの作成と削除
key 23.1 キーシーケンス
key binding 23.2 キーマップの基礎
key binding, conventions for D.2 キーバインディング規約
key lookup 23.10 キーの照合
key sequence 23.1 キーシーケンス
key sequence error 23.12 キーバインディングの変更
key sequence input 22.8.1 キーシーケンス入力
key substitution sequence 25.3 ドキュメント内でのキーバインディングの置き換え
key translation function 23.15 イベントシーケンス変換のためのキーマップ
key-binding 23.13 低レベルなキーバインディング
key-description 25.5 ヘルプメッセージの文字記述
key-translate 22.8.3 入力イベントの変更と変換
key-translation-map 23.15 イベントシーケンス変換のためのキーマップ
key-valid-p 23.1 キーシーケンス
keyboard events 22.7.1 キーボードイベント
keyboard events in strings 22.7.17 文字列内へのキーボードイベントの配置
keyboard events, data in 22.7.15 マウスイベントへのアクセス
keyboard input 22.8 入力の読み取り
keyboard input decoding on X 34.12 locale
keyboard macro execution 22.3 インタラクティブな呼び出し
keyboard macro termination 41.24 ビープ
keyboard macro, terminating 22.8.6 その他のイベント入力の機能
keyboard macros 22.16 キーボードマクロ
keyboard macros (Edebug) 19.2.3 Edebugの実行モード
keyboard-coding-system 34.10.8 端末I/Oのエンコーディング
keyboard-quit 22.11 quit
keyboard-translate 23.13 低レベルなキーバインディング
keyboard-translate-table 22.8.3 入力イベントの変更と変換
keymap 23 キーマップ
keymap (button property) 41.20.1 ボタンのプロパティ
keymap (overlay property) 41.9.2 オーバーレイのプロパティ
keymap (text property) 33.19.4 特殊な意味をもつプロパティ
keymap entry 23.10 キーの照合
keymap format 23.3 キーマップのフォーマット
keymap in keymap 23.10 キーの照合
keymap inheritance 23.5 継承とキーマップ
keymap inheritance from multiple maps 23.5 継承とキーマップ
keymap of character 33.19.4 特殊な意味をもつプロパティ
keymap of character (and overlays) 41.9.2 オーバーレイのプロパティ
keymap prompt string 23.3 キーマップのフォーマット
keymap-global-lookup 23.11 キー照合のための関数
keymap-global-set 23.16 キーのバインドのためのコマンド
keymap-global-unset 23.16 キーのバインドのためのコマンド
keymap-local-lookup 23.11 キー照合のための関数
keymap-local-set 23.16 キーのバインドのためのコマンド
keymap-local-unset 23.16 キーのバインドのためのコマンド
keymap-lookup 23.11 キー照合のための関数
keymap-parent 23.5 継承とキーマップ
keymap-prompt 23.18.1 メニューの定義
keymap-set 23.12 キーバインディングの変更
keymap-set 23.12 キーバインディングの変更
keymap-set-after 23.18.7 メニューの変更
keymap-unset 23.12 キーバインディングの変更
keymap-unset 23.12 キーバインディングの変更
keymapp 23.3 キーマップのフォーマット
keymaps for translating events 23.15 イベントシーケンス変換のためのキーマップ
keymaps in modes 24.2.1 メジャーモードの慣習
keymaps, scanning 23.17 キーマップのスキャン
keymaps, standard Appendix G 標準的なキーマップ
keys in documentation strings 25.3 ドキュメント内でのキーバインディングの置き換え
keys, reserved D.2 キーバインディング規約
keystroke 23.1 キーシーケンス
keyword symbol 12.2 変更不可な変数
keywordp 12.2 変更不可な変数
kill command repetition 22.5 コマンドループからの情報
kill ring 33.8 killリング
kill-all-local-variables 12.11.2 バッファーローカルなバインディングの作成と削除
kill-append 33.8.5 低レベルのkillリング
kill-buffer 28.10 バッファーのkill
kill-buffer-hook 28.10 バッファーのkill
kill-buffer-hook in temporary buffers 28.2 カレントバッファー
kill-buffer-query-functions 28.10 バッファーのkill
kill-buffer-query-functions in temporary buffers 28.2 カレントバッファー
kill-emacs 42.2.1 Emacsのkill
kill-emacs-hook 42.2.1 Emacsのkill
kill-emacs-query-functions 42.2.1 Emacsのkill
kill-local-variable 12.11.2 バッファーローカルなバインディングの作成と削除
kill-new 33.8.5 低レベルのkillリング
kill-process 40.8 プロセスへのシグナルの送信
kill-read-only-ok 33.8.2 kill用の関数
kill-region 33.8.2 kill用の関数
kill-ring 33.8.6 killリングの内部
kill-ring-max 33.8.6 killリングの内部
kill-ring-yank-pointer 33.8.6 killリングの内部
kill-xwidget 41.19 埋め込みネイティブウィジェット
killing buffers 28.10 バッファーのkill
killing Emacs 42.2.1 Emacsのkill
kinship, syntax tree nodes 37.3 ノードの取得
kmacro-keymap Appendix G 標準的なキーマップ

L
labeled narrowing 31.4 ナローイング
labeled restriction 31.4 ナローイング
lambda 13.7 無名関数
lambda expression 13.2 ラムダ式
lambda in debug 19.1.10 デバッガの呼び出し
lambda in keymap 23.10 キーの照合
lambda list 13.2.1 ラムダ式の構成要素
lambda-list (Edebug) 19.2.15.2 仕様リスト
language argument, for tree-sitter 37.1 Tree-sitter Language Grammar
language grammar version, compatibility 37.1 Tree-sitter Language Grammar
language grammar, for tree-sitter 37.1 Tree-sitter Language Grammar
language-change event 22.7.12 その他のシステムイベント
largest fixnum 3.1 整数の基礎
largest window 29.10 ウィンドウのサイクル順
last 5.3 リスト要素へのアクセス
last visible position in a window 29.20 ウィンドウの開始位置と終了位置
last-abbrev 38.4 略語の照会と展開
last-abbrev-location 38.4 略語の照会と展開
last-abbrev-text 38.4 略語の照会と展開
last-buffer 28.8 バッファーリスト
last-coding-system-used 34.10.2 エンコーディングとI/O
last-command 22.5 コマンドループからの情報
last-command-event 22.5 コマンドループからの情報
last-event-device 22.5 コマンドループからの情報
last-event-frame 22.5 コマンドループからの情報
last-input-event 22.8.6 その他のイベント入力の機能
last-kbd-macro 22.16 キーボードマクロ
last-nonmenu-event 22.5 コマンドループからの情報
last-prefix-arg 22.12 プレフィクスコマンド引数
last-repeatable-command 22.5 コマンドループからの情報
lax-plist-get 5.9.2 プロパティリストと外部シンボル
lax-plist-put 5.9.2 プロパティリストと外部シンボル
layout of frame 30.3.1 フレームのレイアウト
layout on display, and bidirectional text 41.27 双方向テキストの表示
layout parameters of frames 30.4.3.4 レイアウトのパラメーター
lazy evaluation 10.6 遅延されたLazy評価
lazy loading 17.4 個々の関数のダイナミックロード
lazy-completion-table 21.6.1 基本的な補完関数
ldexp 3.2 浮動小数点数の基礎
leaf node, of tree-sitter parse tree 37.3 ノードの取得
leap seconds 42.5 時刻
least recently used window 29.10 ウィンドウのサイクル順
left and right window decorations 29.1 Emacsウィンドウの基本概念
left position ratio 30.4.3.2 位置のパラメーター
left, a frame parameter 30.4.3.2 位置のパラメーター
left-fringe, a frame parameter 30.4.3.4 レイアウトのパラメーター
left-fringe, prefix key 22.8.1 キーシーケンス入力
left-fringe-width 41.13.1 フリンジのサイズと位置
left-margin 33.12 fillのマージン
left-margin, prefix key 22.8.1 キーシーケンス入力
left-margin-width 41.16.5 マージン内への表示
length 6.1 シーケンス
length< 6.1 シーケンス
length= 6.1 シーケンス
length> 6.1 シーケンス
let 12.3 ローカル変数
let* 12.3 ローカル変数
let-alist 5.8 連想リスト
letrec 12.3 ローカル変数
Levenshtein distance 4.5 文字および文字列の比較
lexical binding 12.10 変数のバインディングのスコーピングルール
lexical binding (Edebug) 19.2.9 評価
lexical comparison of strings 4.5 文字および文字列の比較
lexical environment 12.10.3 レキシカルバインディング
lexical scope 12.10 変数のバインディングのスコーピングルール
lexical-binding 12.10.4 レキシカルバインディングの使用
library 16 ロード
library compilation 17.2 バイトコンパイル関数
library header comments D.8 Emacsライブラリーのヘッダーの慣習
library search 16.3 ライブラリー検索
libxml-available-p 33.30 HTMLとXMLの解析
libxml-parse-html-region 33.30 HTMLとXMLの解析
libxml-parse-xml-region 33.30 HTMLとXMLの解析
line end conversion 34.10.1 コーディングシステムの基本概念
line height 30.3.2 フレームのフォント
line height 41.11 行の高さ
line number 31.2.4 テキスト行単位の移動
line truncation 41.3 切り詰め
line wrapping 41.3 切り詰め
line-beginning-position 31.2.4 テキスト行単位の移動
line-end in rx 35.3.3.1 rxによるregexpの構築
line-end-position 31.2.4 テキスト行単位の移動
line-height (text property) 33.19.4 特殊な意味をもつプロパティ
line-height (text property) 41.11 行の高さ
line-move-ignore-invisible 41.6 不可視のテキスト
line-number-at-pos 31.2.4 テキスト行単位の移動
line-number-display-width 41.10 表示されるテキストのサイズ
line-pixel-height 41.10 表示されるテキストのサイズ
line-prefix 41.3 切り詰め
line-spacing 41.11 行の高さ
line-spacing (text property) 33.19.4 特殊な意味をもつプロパティ
line-spacing (text property) 41.11 行の高さ
line-spacing, a frame parameter 30.4.3.4 レイアウトのパラメーター
line-start in rx 35.3.3.1 rxによるregexpの構築
lines 31.2.4 テキスト行単位の移動
lines in region 31.2.4 テキスト行単位の移動
lineto 41.17.6 SVGイメージ
link, customization keyword 15.1 一般的なキーワードアイテム
linked list 2.4.6 コンスセルとリスト型
linking files 26.7 ファイルの名前と属性の変更
Lisp debugger 19.1 Lispデバッガ
Lisp expression motion 31.2.6 釣り合いのとれたカッコを越えた移動
Lisp history 1.2 Lispの歴史
Lisp library 16 ロード
Lisp nesting error 10.5 evalについて
Lisp object 2 Lispのデータ型
Lisp objects, stack-allocated E.4 スタックに割り当てられたオブジェクト
Lisp package 43 配布用Lispコードの準備
Lisp printer 20.5 出力関数
Lisp reader 20.1 読み取りとプリントの概念
Lisp timestamp 42.5 時刻
lisp variables defined in C, restrictions 12.16 値を制限された変数
lisp-directory 16.3 ライブラリー検索
lisp-indent-function property 14.6 マクロのインデント
lisp-mode-abbrev-table 38.5 標準abbrevテーブル
lisp-mode-autoload-regexp 16.5 autoload
lisp-mode.el 24.2.9 メジャーモードの例
lispref/text-ja.texi.po D.6 ドキュメント文字列のヒント
lispref/text-ja.texi.po D.6 ドキュメント文字列のヒント
list 5.4 コンスセルおよびリストの構築
list all coding systems 34.10.3 Lispでのコーディングシステム
list elements 5.3 リスト要素へのアクセス
list form evaluation 10.2.3 リストフォームの分類
list in keymap 23.10 キーの照合
list length 6.1 シーケンス
list modification 5.5 リスト変数の変更
list motion 31.2.6 釣り合いのとれたカッコを越えた移動
list of threads 39.4 スレッドリスト
list predicates 5.2 リストのための述語
list reverse 6.1 シーケンス
list structure 2.4.6 コンスセルとリスト型
list structure 5.1 リストとコンスセル
list to vector 6.1 シーケンス
list, replace element 5.6.1 setcarによるリスト要素の変更
list-buffers-directory 28.4 バッファーのファイル名
list-charset-chars 34.7 文字セット
list-fonts 41.12.12 低レベルのフォント表現
list-load-path-shadows 16.3 ライブラリー検索
list-multisession-values 12.18 マルチセッション変数
list-processes 40.6 プロセスの情報
list-system-processes 40.12 別のプロセスへのアクセス
list-threads 39.4 スレッドリスト
list-timers 42.11 遅延実行のためのタイマー
listify-key-sequence 22.8.6 その他のイベント入力の機能
listing all buffers 28.8 バッファーリスト
listp 5.2 リストのための述語
lists 5 リスト
lists and cons cells 5.1 リストとコンスセル
lists as sets 5.7 集合としてのリストの使用
literal evaluation 10.2.1 自己評価を行うフォーム
literal in rx 35.3.3.1 rxによるregexpの構築
literate programming 33.17.2 メジャーモードが制御するインデント
little endian, in bindat specification 40.20.1 データレイアウトの記述
live buffer 28.10 バッファーのkill
live node, tree-sitter 37.4 ノード情報へのアクセス
live windows 29.1 Emacsウィンドウの基本概念
ln 26.7 ファイルの名前と属性の変更
load 16.1 プログラムがロードを行う方法
load error with require 16.7 名前つき機能
load errors 16.1 プログラムがロードを行う方法
load, customization keyword 15.1 一般的なキーワードアイテム
load-average 42.3 オペレーティングシステムの環境
load-changed xwidget event 22.7.11 Xwidgetイベント
load-committed’ in xwidgets 22.7.11 Xwidgetイベント
load-file 16.1 プログラムがロードを行う方法
load-file-name 16.1 プログラムがロードを行う方法
load-file-rep-suffixes 16.2 ロードでの拡張子
load-finished’ in xwidgets 22.7.11 Xwidgetイベント
load-history 16.8 どのファイルで特定のシンボルが定義されているか
load-in-progress 16.1 プログラムがロードを行う方法
load-library 16.1 プログラムがロードを行う方法
load-path 16.3 ライブラリー検索
load-prefer-newer 16.2 ロードでの拡張子
load-read-function 16.1 プログラムがロードを行う方法
load-redirected’ in xwidgets 22.7.11 Xwidgetイベント
load-started’ in xwidgets 22.7.11 Xwidgetイベント
load-suffixes 16.2 ロードでの拡張子
load-theme 15.6 Customテーマ
loaddefs-generate 16.5 autoload
loading 16 ロード
loading and configuring features 16.7 名前つき機能
loading hooks 16.10 ロードのためのフック
loading language grammar for tree-sitter 37.1 Tree-sitter Language Grammar
loading, and non-ASCII characters 16.4 非ASCII文字のロード
loadup.el E.1 Emacsのビルド
local binding 12.3 ローカル変数
local keymap 23.7 アクティブなキーマップ
local part of remote file name 26.12 特定のファイル名の“Magic”の作成
local variables 12.3 ローカル変数
local variables, killed by major mode 12.11.2 バッファーローカルなバインディングの作成と削除
local, defcustom keyword 15.3 カスタマイゼーション変数の定義
local-abbrev-table 38.5 標準abbrevテーブル
local-function-key-map 23.15 イベントシーケンス変換のためのキーマップ
local-key-binding 23.13 低レベルなキーバインディング
local-map (overlay property) 41.9.2 オーバーレイのプロパティ
local-map (text property) 33.19.4 特殊な意味をもつプロパティ
local-minor-modes 24.3 マイナーモード
local-set-key 23.13 低レベルなキーバインディング
local-unset-key 23.13 低レベルなキーバインディング
local-variable-if-set-p 12.11.2 バッファーローカルなバインディングの作成と削除
local-variable-p 12.11.2 バッファーローカルなバインディングの作成と削除
locale 34.12 locale
locale-coding-system 34.12 locale
locale-dependent string comparison 4.5 文字および文字列の比較
locale-dependent string equivalence 4.5 文字および文字列の比較
locale-info 34.12 locale
locate file in path 26.6.6 標準的な場所へのファイルの配置
locate-dominating-file 26.10 ディレクトリーのコンテンツ
locate-file 26.6.6 標準的な場所へのファイルの配置
locate-library 16.3 ライブラリー検索
locate-user-emacs-file 26.9.7 標準的なファイル名
lock file 26.5 ファイルのロック
lock-buffer 26.5 ファイルのロック
lock-file-mode 26.5 ファイルのロック
lock-file-name-transforms 26.5 ファイルのロック
log 3.9 標準的な数学関数
logand 3.8 整数にたいするビット演算
logb 3.2 浮動小数点数の基礎
logcount 3.8 整数にたいするビット演算
logging echo-area messages 41.4.3 *Messages*へのメッセージのロギング
logical arithmetic 3.8 整数にたいするビット演算
logical lines, moving by 31.2.4 テキスト行単位の移動
logical order 41.27 双方向テキストの表示
logical shift 3.8 整数にたいするビット演算
logior 3.8 整数にたいするビット演算
lognot 3.8 整数にたいするビット演算
logxor 3.8 整数にたいするビット演算
looking up abbrevs 38.4 略語の照会と展開
looking up fonts 41.12.10 フォントの照会
looking-at 35.4 正規表現の検索
looking-at-p 35.4 正規表現の検索
looking-back 35.4 正規表現の検索
lookup tables 8 ハッシュテーブル
lookup-key 23.13 低レベルなキーバインディング
loops, infinite 19.1.3 無限ループのデバッグ
low-level key bindings 23.13 低レベルなキーバインディング
lower case 4.9 Lispでの大文字小文字変換
lower-frame 30.12 フレームのraise、lower、re-stack
lowering a frame 30.12 フレームのraise、lower、re-stack
LRO 41.27 双方向テキストの表示
lru-frames, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
lru-time, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
lsh 3.8 整数にたいするビット演算
lwarn 41.5.1 警告の基礎

M
M-g 23.6 プレフィクスキー
M-s 23.6 プレフィクスキー
M-S-x 22.3 インタラクティブな呼び出し
M-X 22.3 インタラクティブな呼び出し
M-x 22.3 インタラクティブな呼び出し
Maclisp 1.2 Lispの歴史
macro 13.1 関数とは?
macro argument evaluation 14.5.2 マクロ引数の多重評価
macro call 14.2 マクロ呼び出しの展開
macro call evaluation 10.2.6 Lispマクロの評価
macro caveats 14.5 マクロ使用に関する一般的な問題
macro compilation 17.2 バイトコンパイル関数
macro descriptions 1.3.7.1 関数の説明例
macro expansion 14.2 マクロ呼び出しの展開
macro, how to define 14.4 マクロの定義
macroexpand 14.2 マクロ呼び出しの展開
macroexpand-1 14.2 マクロ呼び出しの展開
macroexpand-all 14.2 マクロ呼び出しの展開
macrop 14.1 単純なマクロの例
macros 14 マクロ
macros, at compile time 17.5 コンパイル中の評価
magic autoload comment 16.5 autoload
magic file names 26.12 特定のファイル名の“Magic”の作成
magic-fallback-mode-alist 24.2.2 Emacsがメジャーモードを選択する方法
magic-mode-alist 24.2.2 Emacsがメジャーモードを選択する方法
mail-host-address 42.3 オペレーティングシステムの環境
main window 29.17 サイドウィンドウ
main window of a frame 29.17 サイドウィンドウ
main-thread 39.1 基本的なスレッド関数
major mode 24.2 メジャーモード
major mode command 24.2 メジャーモード
major mode conventions 24.2.1 メジャーモードの慣習
major mode hook 24.2.1 メジャーモードの慣習
major mode keymap 23.7 アクティブなキーマップ
major mode, automatic selection 24.2.2 Emacsがメジャーモードを選択する方法
major mode, developing with tree-sitter 37.7 tree-sitterを用いるメジャーモードの開発
major-mode 24.2 メジャーモード
major-mode-restore 24.2 メジャーモード
major-mode-suspend 24.2 メジャーモード
make-abbrev-table 38.1 abbrevテーブル
make-auto-save-file-name 27.2 自動保存
make-backup-file-name 27.1.4 バックアップファイルの命名
make-backup-file-name-function 27.1.1 バックアップファイルの作成
make-backup-files 27.1.1 バックアップファイルの作成
make-bool-vector 6.7 ブールベクター
make-button 41.20.3 ボタンの作成
make-byte-code 17.7 バイトコード関数オブジェクト
make-category-set 36.8 カテゴリー
make-category-table 36.8 カテゴリー
make-char-table 6.6 文字テーブル
make-composed-keymap 23.5 継承とキーマップ
make-condition-variable 39.3 条件変数
make-directory 26.11 ディレクトリーの作成・コピー・削除
make-display-table 41.23.2 ディスプレイテーブル
make-empty-file 26.11 ディレクトリーの作成・コピー・削除
make-finalizer 2.4.20 ファイナライザー型
make-frame 30.1 フレームの作成
make-frame-invisible 30.11 フレームの可視性
make-frame-on-display 30.2 複数の端末
make-frame-on-monitor 30.2 複数の端末
make-frame-visible 30.11 フレームの可視性
make-frame-visible event 22.7.12 その他のシステムイベント
make-glyph-code 41.23.4 グリフ
make-hash-table 8.1 ハッシュテーブルの作成
make-help-screen 25.6 ヘルプ関数
make-indirect-buffer 28.11 インダイレクトバッファー
make-keymap 23.4 キーマップの作成
make-list 5.4 コンスセルおよびリストの構築
make-local-variable 12.11.2 バッファーローカルなバインディングの作成と削除
make-marker 32.3 マーカーを作成する関数
make-multisession 12.18 マルチセッション変数
make-mutex 39.2 ミューテックス
make-nearby-temp-file 26.9.5 一意なファイル名の生成
make-network-process 40.17.1 make-network-process
make-obsolete 13.13 関数の陳腐化の宣言
make-obsolete-generalized-variable 12.17.2 新たなsetfフォーム
make-obsolete-variable 12.15 変数のエイリアス
make-overlay 41.9.1 オーバーレイの管理
make-pipe-process 40.4 非同期プロセスの作成
make-process 40.4 非同期プロセスの作成
make-progress-reporter 41.4.2 処理の進捗レポート
make-record 7.1 レコード関数
make-ring 6.8 オブジェクト用固定長リングの管理
make-serial-process 40.19 シリアルポートとの対話
make-sparse-keymap 23.4 キーマップの作成
make-string 4.3 文字列の作成
make-symbol 9.3 シンボルの作成とintern
make-symbolic-link 26.7 ファイルの名前と属性の変更
make-syntax-table 36.3 構文テーブルの関数
make-temp-file 26.9.5 一意なファイル名の生成
make-temp-name 26.9.5 一意なファイル名の生成
make-text-button 41.20.3 ボタンの作成
make-thread 39.1 基本的なスレッド関数
make-translation-table 34.9 文字の変換
make-translation-table-from-alist 34.9 文字の変換
make-translation-table-from-vector 34.9 文字の変換
make-variable-buffer-local 12.11.2 バッファーローカルなバインディングの作成と削除
make-vector 6.5 ベクターのための関数
make-vtable 24.2.7 Tabulated Listモード
make-xwidget 41.19 埋め込みネイティブウィジェット
make_big_integer E.8.3 Lisp・モジュール間の値変換
make_float E.8.3 Lisp・モジュール間の値変換
make_function E.8.2 モジュール関数の記述
make_global_ref E.8.3 Lisp・モジュール間の値変換
make_integer E.8.3 Lisp・モジュール間の値変換
make_interactive E.8.2 モジュール関数の記述
make_string E.8.3 Lisp・モジュール間の値変換
make_time E.8.3 Lisp・モジュール間の値変換
make_unibyte_string E.8.3 Lisp・モジュール間の値変換
make_user_ptr E.8.3 Lisp・モジュール間の値変換
making backup files 27.1.1 バックアップファイルの作成
making buttons 41.20.3 ボタンの作成
makunbound 12.4 変数がvoidのとき
malicious use of directional overrides 41.27 双方向テキストの表示
managing overlays 41.9.1 オーバーレイの管理
manipulating buttons 41.20.4 ボタンの操作
map-char-table 6.6 文字テーブル
map-charset-chars 34.7 文字セット
map-keymap 23.17 キーマップのスキャン
map-y-or-n-p 21.8 複数の問いを尋ねる
mapatoms 9.3 シンボルの作成とintern
mapbacktrace 19.1.11 デバッガの内部
mapc 13.6 関数のマッピング
mapcan 13.6 関数のマッピング
mapcar 13.6 関数のマッピング
mapconcat 13.6 関数のマッピング
maphash 8.2 ハッシュテーブルへのアクセス
mapped frame 30.11 フレームの可視性
mapping functions 13.6 関数のマッピング
margins, display 41.16.5 マージン内への表示
margins, filling 33.12 fillのマージン
mark 32.7 マーク
mark excursion 31.3 エクスカーション
mark ring 32.7 マーク
mark, the 32.7 マーク
mark-active 32.7 マーク
mark-even-if-inactive 32.7 マーク
mark-marker 32.7 マーク
mark-ring 32.7 マーク
mark-ring-max 32.7 マーク
marker argument 22.2.2 interactiveにたいするコード文字
marker creation 32.3 マーカーを作成する関数
marker garbage collection 32.1 マーカーの概要
marker information 32.4 マーカーからの情報
marker input stream 20.2 入力ストリーム
marker output stream 20.4 出力ストリーム
marker relocation 32.1 マーカーの概要
marker, how to move position 32.6 マーカー位置の移動
marker-buffer 32.4 マーカーからの情報
marker-insertion-type 32.5 マーカーの挿入タイプ
marker-position 32.4 マーカーからの情報
markerp 32.2 マーカーのための述語
markers 32 マーカー
markers as numbers 32.1 マーカーの概要
markers, predicates for 32.2 マーカーのための述語
match 24.7.2 パーサーベースのインデント
match data 35.6 マッチデータ
match, customization keyword 15.4.4 型キーワード
match-alternatives, customization keyword 15.4.2 複合型
match-beginning 35.6.2 単純なマッチデータへのアクセス
match-buffers 28.8 バッファーリスト
match-data 35.6.3 マッチデータ全体へのアクセス
match-end 35.6.2 単純なマッチデータへのアクセス
match-inline, customization keyword 15.4.4 型キーワード
match-string 35.6.2 単純なマッチデータへのアクセス
match-string-no-properties 35.6.2 単純なマッチデータへのアクセス
match-substitute-replacement 35.6.1 マッチしたテキストの置換
matching, structural 11.4.3 バッククォートスタイルパターン
mathematical functions 3.9 標準的な数学関数
max 3.4 数値の比較
max-char 34.5 文字コード
max-image-size 41.17.9 イメージの表示
max-lisp-eval-depth 10.5 evalについて
max-mini-window-height 21.11 ミニバッファーのウィンドウ
maximal-match in rx 35.3.3.1 rxによるregexpの構築
maximize-window 29.5 ウィンドウのリサイズ
maximized frames 30.4.3.3 サイズのパラメーター
maximizing windows 29.5 ウィンドウのリサイズ
maximum fixnum 3.1 整数の基礎
maximum value of character codepoint 34.5 文字コード
maximum value of sequence 6.1 シーケンス
maximum-scroll-margin 29.21 テキスト的なスクロール
maybe_quit, use in Lisp primitives E.7 Emacsプリミティブの記述
md5 33.26 チェックサムとハッシュ
MD5 checksum 33.26 チェックサムとハッシュ
MD5 checksum 33.28 GnuTLS暗号化
measuring resource usage 19.5 プロファイリング
member 5.7 集合としてのリストの使用
member-ignore-case 5.7 集合としてのリストの使用
membership in a list 5.7 集合としてのリストの使用
memory allocation E.3 ガーベージコレクション
memory usage 19.5 プロファイリング
memory usage E.5 メモリー使用量
memory-full E.3 ガーベージコレクション
memory-info E.3 ガーベージコレクション
memory-limit E.3 ガーベージコレクション
memory-report E.3 ガーベージコレクション
memory-use-counts E.3 ガーベージコレクション
memq 5.7 集合としてのリストの使用
memql 5.7 集合としてのリストの使用
menu bar 23.18.5 メニューバー
menu bar keymaps Appendix G 標準的なキーマップ
menu definition example 23.18.4 メニューの例
menu item 23.18.1 メニューの定義
menu keymaps 23.18 メニューキーアップ
menu modification 23.18.7 メニューの変更
menu prompt string 23.18.1 メニューの定義
menu separators 23.18.1.3 メニューセパレーター
menu-bar, prefix key 22.8.1 キーシーケンス入力
menu-bar-file-menu Appendix G 標準的なキーマップ
menu-bar-final-items 23.18.5 メニューバー
menu-bar-help-menu Appendix G 標準的なキーマップ
menu-bar-lines, a frame parameter 30.4.3.4 レイアウトのパラメーター
menu-bar-options-menu Appendix G 標準的なキーマップ
menu-bar-tools-menu Appendix G 標準的なキーマップ
menu-bar-update-hook 23.18.5 メニューバー
menu-item 23.18.1.2 拡張メニューアイテム
menu-prompt-more-char 23.18.3 メニューとキーボード
menus, popup 30.17 ポップアップメニュー
merge-face-attribute 41.12.3 フェイス属性のための関数
message 41.4.1 エコーエリアへのメッセージの表示
message digest 33.26 チェックサムとハッシュ
message, finding what causes a particular message 19.1.1 エラーによるデバッガへのエンター
message-box 41.4.1 エコーエリアへのメッセージの表示
message-log-max 41.4.3 *Messages*へのメッセージのロギング
message-or-box 41.4.1 エコーエリアへのメッセージの表示
message-truncate-lines 41.4.4 エコーエリアのカスタマイズ
messages-buffer 41.4.3 *Messages*へのメッセージのロギング
messages-buffer-name 41.4.3 *Messages*へのメッセージのロギング
meta character key constants 23.13 低レベルなキーバインディング
meta character printing 25.5 ヘルプメッセージの文字記述
meta characters 2.4.3.4 メタ文字構文
meta characters lookup 23.3 キーマップのフォーマット
meta-prefix-char 23.11 キー照合のための関数
min 3.4 数値の比較
min-height, a frame parameter 30.4.3.3 サイズのパラメーター
min-margins, a window parameter 29.27 ウィンドウのパラメーター
min-width, a frame parameter 30.4.3.3 サイズのパラメーター
minibuffer 21 ミニバッファー
minibuffer completion 21.6.2 補完とミニバッファー
minibuffer contents, accessing 21.12 ミニバッファーのコンテンツ
minibuffer history 21.4 ミニバッファーのヒストリー
minibuffer input 22.13 再帰編集
minibuffer input, and command-line arguments 40.2 shell引数
minibuffer input, reading lisp objects 21.3 ミニバッファーでのLispオブジェクトの読み取り
minibuffer input, reading text strings 21.2 ミニバッファーでのテキスト文字列の読み取り
minibuffer window 29.1 Emacsウィンドウの基本概念
minibuffer window, and next-window 29.10 ウィンドウのサイクル順
minibuffer windows 21.11 ミニバッファーのウィンドウ
minibuffer, a frame parameter 30.4.3.5 バッファーのパラメーター
minibuffer-allow-text-properties 21.2 ミニバッファーでのテキスト文字列の読み取り
minibuffer-auto-raise 30.12 フレームのraise、lower、re-stack
minibuffer-beginning-of-buffer-movement 21.6.3 補完を行うミニバッファーコマンド
minibuffer-complete 21.6.3 補完を行うミニバッファーコマンド
minibuffer-complete-and-exit 21.6.3 補完を行うミニバッファーコマンド
minibuffer-complete-word 21.6.3 補完を行うミニバッファーコマンド
minibuffer-completion-confirm 21.6.3 補完を行うミニバッファーコマンド
minibuffer-completion-help 21.6.3 補完を行うミニバッファーコマンド
minibuffer-completion-predicate 21.6.3 補完を行うミニバッファーコマンド
minibuffer-completion-table 21.6.3 補完を行うミニバッファーコマンド
minibuffer-confirm-exit-commands 21.6.3 補完を行うミニバッファーコマンド
minibuffer-contents 21.12 ミニバッファーのコンテンツ
minibuffer-contents-no-properties 21.12 ミニバッファーのコンテンツ
minibuffer-default-add-function 21.4 ミニバッファーのヒストリー
minibuffer-default-prompt-format 21.2 ミニバッファーでのテキスト文字列の読み取り
minibuffer-depth 21.13 再帰的なミニバッファー
minibuffer-exit, a frame parameter 30.4.3.6 フレームとの相互作用のためのパラメーター
minibuffer-exit-hook 21.15 ミニバッファー、その他の事項
minibuffer-frame-alist 30.4.2 フレームの初期パラメーター
minibuffer-help-form 21.15 ミニバッファー、その他の事項
minibuffer-history 21.4 ミニバッファーのヒストリー
minibuffer-inactive-mode 21.15 ミニバッファー、その他の事項
minibuffer-inactive-mode-map Appendix G 標準的なキーマップ
minibuffer-less frame 30.3.1 フレームのレイアウト
minibuffer-local-completion-map 21.6.3 補完を行うミニバッファーコマンド
minibuffer-local-filename-completion-map 21.6.3 補完を行うミニバッファーコマンド
minibuffer-local-map 21.2 ミニバッファーでのテキスト文字列の読み取り
minibuffer-local-must-match-map 21.6.3 補完を行うミニバッファーコマンド
minibuffer-local-ns-map 21.2 ミニバッファーでのテキスト文字列の読み取り
minibuffer-local-shell-command-map 21.6.5 ファイル名の読み取り
minibuffer-message 21.15 ミニバッファー、その他の事項
minibuffer-message (text property) 33.19.4 特殊な意味をもつプロパティ
minibuffer-message-timeout 21.15 ミニバッファー、その他の事項
minibuffer-only frame 30.3.1 フレームのレイアウト
minibuffer-only frame 30.4.2 フレームの初期パラメーター
minibuffer-prompt 21.12 ミニバッファーのコンテンツ
minibuffer-prompt-end 21.12 ミニバッファーのコンテンツ
minibuffer-prompt-properties 21.2 ミニバッファーでのテキスト文字列の読み取り
minibuffer-prompt-width 21.12 ミニバッファーのコンテンツ
minibuffer-scroll-window 21.15 ミニバッファー、その他の事項
minibuffer-selected-window 21.15 ミニバッファー、その他の事項
minibuffer-setup-hook 21.15 ミニバッファー、その他の事項
minibuffer-window 21.11 ミニバッファーのウィンドウ
minibuffer-window-active-p 21.11 ミニバッファーのウィンドウ
minibuffer-with-setup-hook 21.15 ミニバッファー、その他の事項
minibufferp 21.15 ミニバッファー、その他の事項
minimal-match in rx 35.3.3.1 rxによるregexpの構築
minimize-window 29.5 ウィンドウのリサイズ
minimized frame 30.11 フレームの可視性
minimizing windows 29.5 ウィンドウのリサイズ
minimum fixnum 3.1 整数の基礎
minimum value of sequence 6.1 シーケンス
minor mode 24.3 マイナーモード
minor mode conventions 24.3.1 マイナーモード記述の規約
minor-mode-alist 24.4.4 モードラインで使用される変数
minor-mode-key-binding 23.11 キー照合のための関数
minor-mode-list 24.3 マイナーモード
minor-mode-map-alist 23.9 アクティブなキーマップの制御
minor-mode-overriding-map-alist 23.9 アクティブなキーマップの制御
mirroring of characters 34.6 文字のプロパティ
missing node, tree-sitter 37.4 ノード情報へのアクセス
mkdir 26.11 ディレクトリーの作成・コピー・削除
mod 3.6 算術演算
mode 24 メジャーモードとマイナーモード
mode bits 26.6.1 アクセシビリティのテスト
mode help 24.2.3 メジャーモードでのヘルプ入手
mode hook 24.2.1 メジャーモードの慣習
mode line 24.4 モードラインのフォーマット
mode line construct 24.4.2 モードラインのデータ構造
mode loading 24.2.1 メジャーモードの慣習
mode variable 24.3.1 マイナーモード記述の規約
mode, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
mode-class (property) 24.2.1 メジャーモードの慣習
mode-line, prefix key 22.8.1 キーシーケンス入力
mode-line-buffer-identification 24.4.4 モードラインで使用される変数
mode-line-client 24.4.4 モードラインで使用される変数
mode-line-coding-system-map Appendix G 標準的なキーマップ
mode-line-column-line-number-mode-map Appendix G 標準的なキーマップ
mode-line-compact 24.4.1 モードラインの基礎
mode-line-end-spaces 24.4.4 モードラインで使用される変数
mode-line-format 24.4.3 モードライン制御のトップレベル
mode-line-format, a window parameter 29.27 ウィンドウのパラメーター
mode-line-frame-identification 24.4.4 モードラインで使用される変数
mode-line-front-space 24.4.4 モードラインで使用される変数
mode-line-input-method-map Appendix G 標準的なキーマップ
mode-line-misc-info 24.4.4 モードラインで使用される変数
mode-line-modes 24.4.4 モードラインで使用される変数
mode-line-modified 24.4.4 モードラインで使用される変数
mode-line-mule-info 24.4.4 モードラインで使用される変数
mode-line-percent-position 24.4.4 モードラインで使用される変数
mode-line-position 24.4.4 モードラインで使用される変数
mode-line-position-column-format 24.4.4 モードラインで使用される変数
mode-line-position-column-line-format 24.4.4 モードラインで使用される変数
mode-line-position-line-format 24.4.4 モードラインで使用される変数
mode-line-process 24.4.4 モードラインで使用される変数
mode-line-remote 24.4.4 モードラインで使用される変数
mode-line-window-selected-p 24.4.1 モードラインの基礎
mode-name 24.4.4 モードラインで使用される変数
mode-specific commands 22.2.4 コマンドにたいするモード指定
mode-specific-map 23.6 プレフィクスキー
model/view/controller 41.21 抽象的なディスプレイ
modification flag (of buffer) 28.5 バッファーの変更
modification of lists 5.6.3 リストを再配置する関数
modification time of buffer 28.6 バッファーの変更時刻
modification time of file 26.6.4 ファイルの属性
modification-hooks (overlay property) 41.9.2 オーバーレイのプロパティ
modification-hooks (text property) 33.19.4 特殊な意味をもつプロパティ
modifier bits (of input character) 22.7.1 キーボードイベント
modifiers of events 22.8.3 入力イベントの変更と変換
modify a list 5.5 リスト変数の変更
modify-all-frames-parameters 30.4.1 フレームパラメーターへのアクセス
modify-category-entry 36.8 カテゴリー
modify-frame-parameters 30.4.1 フレームパラメーターへのアクセス
modify-syntax-entry 36.3 構文テーブルの関数
modifying strings 4.4 文字列の変更
module API E.8 動的にロードされるモジュールの記述
module functions E.8.2 モジュール関数の記述
module initialization E.8.1 モジュールの初期化コード
module runtime environment E.8.1 モジュールの初期化コード
module values, conversion E.8.3 Lisp・モジュール間の値変換
module-file-suffix 16.11 Emacsのダイナミックモジュール
module-load 16.11 Emacsのダイナミックモジュール
modulus 3.6 算術演算
momentary-string-display 41.8 一時的な表示
monitor change functions 30.2 複数の端末
most recently selected windows 29.3 ウィンドウの選択
most recently used window 29.10 ウィンドウのサイクル順
most-negative-fixnum 3.1 整数の基礎
most-positive-fixnum 3.1 整数の基礎
motion based on parsing 36.6.1 パースにもとづくモーションコマンド
motion by chars, words, lines, lists 31.2 モーション
motion event 22.7.8 モーションイベント
mouse click event 22.7.4 クリックイベント
mouse drag event 22.7.5 ドラッグイベント
mouse dragging parameters 30.4.3.7 マウスドラッグのパラメーター
mouse events, data in 22.7.15 マウスイベントへのアクセス
mouse events, in special parts of window or frame 22.8.1 キーシーケンス入力
mouse events, repeated 22.7.7 リピートイベント
mouse motion events 22.7.8 モーションイベント
mouse pointer shape 30.19 ポインターの形状
mouse position 30.16 マウスの位置
mouse position list 22.7.4 クリックイベント
mouse position list, accessing 22.7.15 マウスイベントへのアクセス
mouse tracking 30.15 マウスの追跡
mouse wheel event 22.7.4 クリックイベント
mouse, a face 30.4.3.10 フォントとカラーのパラメーター
mouse, availability 30.26 ディスプレイ機能のテスト
mouse-1 33.19.8 クリック可能なテキストの定義
mouse-1-click-follows-link 33.19.8 クリック可能なテキストの定義
mouse-2 D.2 キーバインディング規約
mouse-absolute-pixel-position 30.16 マウスの位置
mouse-action (button property) 41.20.1 ボタンのプロパティ
mouse-appearance-menu-map Appendix G 標準的なキーマップ
mouse-autoselect-window 29.25 マウスによるウィンドウの自動選択
mouse-color, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
mouse-face (button property) 41.20.1 ボタンのプロパティ
mouse-face (overlay property) 41.9.2 オーバーレイのプロパティ
mouse-face (text property) 33.19.4 特殊な意味をもつプロパティ
mouse-fine-grained-tracking 22.7.8 モーションイベント
mouse-leave-buffer-hook Appendix H 標準的なフック
mouse-movement-p 22.7.14 イベントの分類
mouse-on-link-p 33.19.8 クリック可能なテキストの定義
mouse-pixel-position 30.16 マウスの位置
mouse-position 30.16 マウスの位置
mouse-position-function 30.16 マウスの位置
mouse-wheel-down-event 22.7.12 その他のシステムイベント
mouse-wheel-frame, a frame parameter 30.4.3.6 フレームとの相互作用のためのパラメーター
mouse-wheel-left-event 22.7.12 その他のシステムイベント
mouse-wheel-right-event 22.7.12 その他のシステムイベント
mouse-wheel-up-event 22.7.12 その他のシステムイベント
move to beginning or end of buffer 31.2.3 バッファー終端への移動
move-frame-functions 30.3.3 フレームの位置
move-marker 32.6 マーカー位置の移動
move-overlay 41.9.1 オーバーレイの管理
move-point-visually 41.27 双方向テキストの表示
move-to-column 33.16 列を数える
move-to-left-margin 33.12 fillのマージン
move-to-window-group-line 31.2.5 スクリーン行単位の移動
move-to-window-group-line-function 31.2.5 スクリーン行単位の移動
move-to-window-line 31.2.5 スクリーン行単位の移動
movemail 40.1 サブプロセスを作成する関数
moveto 41.17.6 SVGイメージ
moving across syntax classes 36.5 モーションと構文
moving markers 32.6 マーカー位置の移動
MS-DOS and file modes 26.6.1 アクセシビリティのテスト
MS-Windows file-name syntax 26.9 ファイルの名前
mule-keymap 23.6 プレフィクスキー
multi-file package 43.3 複数ファイルのパッケージ
multi-frame images 41.17.10 マルチフレームのイメージ
multi-message-max 41.4.1 エコーエリアへのメッセージの表示
multi-message-timeout 41.4.1 エコーエリアへのメッセージの表示
multi-mode indentation 33.17.2 メジャーモードが制御するインデント
multi-monitor 30.2 複数の端末
multi-query-replace-map 35.7 検索と置換
multi-tty 30.2 複数の端末
multibyte characters 34 非ASCII文字
multibyte text 34.1 テキストの表現方法
multibyte-char-to-unibyte 34.3 テキスト表現の変換
multibyte-string-p 34.1 テキストの表現方法
multibyte-syntax-as-symbol 36.6.5 パースを制御するためのパラメーター
multiline font lock 24.6.9 複数行のFont Lock構造
multiple languages, parsing with tree-sitter 37.6 複数言語ののパース
multiple terminals 30.2 複数の端末
multiple windows 29.1 Emacsウィンドウの基本概念
multiple X displays 30.2 複数の端末
multiple yes-or-no questions 21.8 複数の問いを尋ねる
multiple-dispatch methods 13.8 ジェネリック関数
multiple-frames 30.6 フレームのタイトル
multisession variable 12.18 マルチセッション変数
multisession-delete 12.18 マルチセッション変数
multisession-directory 12.18 マルチセッション変数
multisession-edit-mode 12.18 マルチセッション変数
multisession-storage 12.18 マルチセッション変数
multisession-value 12.18 マルチセッション変数
mutable lists 5.6 既存のリスト構造の変更
mutable objects 2.9 可変性
mutex-lock 39.2 ミューテックス
mutex-name 39.2 ミューテックス
mutex-unlock 39.2 ミューテックス
mutexp 39.2 ミューテックス

N
n-p-gp 24.7.2 パーサーベースのインデント
name, a frame parameter 30.4.3.1 基本パラメーター
named function 13.3 関数の命名
named node, tree-sitter 37.1 Tree-sitter Language Grammar
named-let 12.3 ローカル変数
namespace etiquette 9.5 ショートハンド
namespaces 9.5 ショートハンド
namespacing 9.5 ショートハンド
naming backup files 27.1.4 バックアップファイルの命名
NaN 3.2 浮動小数点数の基礎
narrow-map Appendix G 標準的なキーマップ
narrow-to-page 31.4 ナローイング
narrow-to-region 31.4 ナローイング
narrowing 31.4 ナローイング
native code 18 Lispからネイティブコードへのコンパイル
native compilation 18 Lispからネイティブコードへのコンパイル
native compilation, prevent writing *.eln files 18 Lispからネイティブコードへのコンパイル
native edges 30.3.1 フレームのレイアウト
native frame 30.3.1 フレームのレイアウト
native height 30.3.1 フレームのレイアウト
native position 30.3.1 フレームのレイアウト
native size 30.3.1 フレームのレイアウト
native width 30.3.1 フレームのレイアウト
native-comp-async-jobs-number 18.2 ネイティブコンパイル関数
native-comp-async-query-on-exit 18.2 ネイティブコンパイル関数
native-comp-async-report-warnings-errors 18.2 ネイティブコンパイル関数
native-comp-available-p 18.1 ネイティブコンパイル関数
native-comp-debug 18.2 ネイティブコンパイル関数
native-comp-eln-load-path 16.3 ライブラリー検索
native-comp-enable-subr-trampolines 18.2 ネイティブコンパイル関数
native-comp-jit-compilation 18.2 ネイティブコンパイル関数
native-comp-limple-mode 18.1 ネイティブコンパイル関数
native-comp-speed 18.2 ネイティブコンパイル関数
native-comp-verbose 18.1 ネイティブコンパイル関数
native-comp-verbose 18.2 ネイティブコンパイル関数
native-compilation functions 18.1 ネイティブコンパイル関数
native-compilation variables 18.2 ネイティブコンパイル関数
native-compile 18.1 ネイティブコンパイル関数
native-compile, a Lisp feature 18 Lispからネイティブコードへのコンパイル
native-compile-async 18.1 ネイティブコンパイル関数
natnump 3.3 数値のための述語
natural numbers 3.3 数値のための述語
nbutlast 5.3 リスト要素へのアクセス
nconc 5.6.3 リストを再配置する関数
negative infinity 3.2 浮動小数点数の基礎
negative-argument 22.12 プレフィクスコマンド引数
nest frame 30.14 子フレーム
network byte ordering, in Bindat specification 40.20.1 データレイアウトの記述
network connection 40.14 ネットワーク接続
network connection, encrypted 40.14 ネットワーク接続
network servers 40.15 ネットワークサーバー
network service name, and default coding system 34.10.5 デフォルトのコーディングシステム
network-coding-system-alist 34.10.5 デフォルトのコーディングシステム
network-interface-info 40.18 その他のネットワーク機能
network-interface-list 40.18 その他のネットワーク機能
network-lookup-address-info 40.18 その他のネットワーク機能
network-stream-use-client-certificates 40.14 ネットワーク接続
new file message 26.1.2 visitのためのサブルーチン
newline 2.4.3.1 基本的な文字構文
newline 33.5 ユーザーレベルの挿入コマンド
newline and Auto Fill mode 33.5 ユーザーレベルの挿入コマンド
newline in print 20.5 出力関数
newline in strings 2.4.8.1 文字列の構文
newline-and-indent 33.17.2 メジャーモードが制御するインデント
next input 22.8.6 その他のイベント入力の機能
next-button 41.20.5 ボタンのためのバッファーコマンド
next-char-property-change 33.19.3 テキストプロパティの検索関数
next-complete-history-element 21.10 ミニバッファーのコマンド
next-frame 30.8 すべてのフレームを探す
next-history-element 21.10 ミニバッファーのコマンド
next-matching-history-element 21.10 ミニバッファーのコマンド
next-overlay-change 41.9.3 オーバーレイにたいする検索
next-property-change 33.19.3 テキストプロパティの検索関数
next-screen-context-lines 29.21 テキスト的なスクロール
next-single-char-property-change 33.19.3 テキストプロパティの検索関数
next-single-property-change 33.19.3 テキストプロパティの検索関数
next-window 29.10 ウィンドウのサイクル順
nil 1.3.2 nilt
nil as a list 2.4.6.1 ボックスダイアグラムによるリストの描写
nil in keymap 23.10 キーの照合
nil input stream 20.2 入力ストリーム
nil output stream 20.4 出力ストリーム
nlistp 5.2 リストのための述語
no-accept-focus, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
no-byte-compile 17 バイトコンパイル
no-catch 11.7.1 明示的な非ローカル脱出: catchthrow
no-conversion coding system 34.10.1 コーディングシステムの基本概念
no-delete-other-windows, a window parameter 29.27 ウィンドウのパラメーター
no-focus-on-map, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
no-indent 24.7.2 パーサーベースのインデント
no-native-compile 18 Lispからネイティブコードへのコンパイル
no-node 24.7.2 パーサーベースのインデント
no-other-frame, a frame parameter 30.4.3.6 フレームとの相互作用のためのパラメーター
no-other-window, a window parameter 29.27 ウィンドウのパラメーター
no-redraw-on-reenter 41.1 スクリーンのリフレッシュ
no-self-insert property 38.2 abbrevの定義
no-special-glyphs, a frame parameter 30.4.3.4 レイアウトのパラメーター
node types, in a syntax tree 37.1 Tree-sitter Language Grammar
node, ewoc 41.21 抽象的なディスプレイ
node-is 24.7.2 パーサーベースのインデント
nodes, by field name 37.3 ノードの取得
nodes, by kinship 37.3 ノードの取得
nodes, by position 37.3 ノードの取得
non-ASCII characters 34 非ASCII文字
non-ASCII characters in loaded files 16.4 非ASCII文字のロード
non-ASCII text in key bindings 23.16 キーのバインドのためのコマンド
non-capturing group 35.3.1.3 正規表現内のバッククラッシュ構文
non-GNU ELPA 43.4 パッケージアーカイブの作成と保守
non-greedy repetition characters in regexp 35.3.1.1 正規表現内の特殊文字
nondirectory part (of file name) 26.9.1 ファイル名の構成要素
noninteractive 42.17 batchモード
nonl in rx 35.3.3.1 rxによるregexpの構築
nonlocal exits 11.7 非ローカル脱出
nonlocal exits, cleaning up 11.7.4 非ローカル脱出のクリーンアップ
nonlocal exits, in modules E.8.5 モジュールでの非ローカル脱出
nonprinting characters, reading 22.8.5 クォートされた文字の入力
non_local_exit_check E.8.5 モジュールでの非ローカル脱出
non_local_exit_clear E.8.5 モジュールでの非ローカル脱出
non_local_exit_get E.8.5 モジュールでの非ローカル脱出
non_local_exit_signal E.8.5 モジュールでの非ローカル脱出
non_local_exit_throw E.8.5 モジュールでの非ローカル脱出
noreturn 19.4 カバレッジテスト
normal hook 24.1 フック
normal-auto-fill-function 33.14 オートfill
normal-backup-enable-predicate 27.1.1 バックアップファイルの作成
normal-mode 24.2.2 Emacsがメジャーモードを選択する方法
not 11.3 組み合わせ条件の構築
not in rx 35.3.3.1 rxによるregexpの構築
not recording input events 22.8.6 その他のイベント入力の機能
not-modified 28.5 バッファーの変更
not-newline in rx 35.3.3.1 rxによるregexpの構築
not-word-boundary in rx 35.3.3.1 rxによるregexpの構築
notation 1.3.3 評価の表記
notifications, on desktop 42.19 デスクトップ通知
notifications-close-notification 42.19 デスクトップ通知
notifications-get-capabilities 42.19 デスクトップ通知
notifications-get-server-information 42.19 デスクトップ通知
notifications-notify 42.19 デスクトップ通知
notifiers, tree-sitter 37.2 tree-sitterパーサーの使用
nreverse 6.1 シーケンス
ns-appearance, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
ns-transparent-titlebar, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
ntake 5.3 リスト要素へのアクセス
nth 5.3 リスト要素へのアクセス
nth-sibling 24.7.2 パーサーベースのインデント
nthcdr 5.3 リスト要素へのアクセス
null 5.2 リストのための述語
null bytes, and decoding text 34.10.3 Lispでのコーディングシステム
null-device 42.3 オペレーティングシステムの環境
null-device 42.3 オペレーティングシステムの環境
num-input-keys 22.8.1 キーシーケンス入力
num-nonmacro-input-events 22.8.2 単一イベントの読み取り
num-processors 40.6 プロセスの情報
number comparison 3.4 数値の比較
number conversions 3.5 数値の変換
number of bignum bits, limit on 3.1 整数の基礎
number-or-marker-p 32.2 マーカーのための述語
number-sequence 5.4 コンスセルおよびリストの構築
number-to-string 4.6 文字および文字列の変換
numbered backups 27.1.3 番号つきバックアップファイルの作成と削除
numberp 3.3 数値のための述語
numbers 3 数値
numeric prefix argument 22.12 プレフィクスコマンド引数
numeric prefix argument usage 22.2.2 interactiveにたいするコード文字
numerical RGB color specification 30.23 カラー名

O
obarray 9.3 シンボルの作成とintern
obarray 9.3 シンボルの作成とintern
obarray in completion 21.6.1 基本的な補完関数
object 2 Lispのデータ型
object internals E.9 オブジェクトの内部
object to string 20.5 出力関数
object-intervals 33.19.1 テキストプロパティを調べる
objects with identical contents, and byte-compiler 2.8 同等性のための述語
obsolete (declare spec) 13.15 declareフォーム
obsolete functions 13.13 関数の陳腐化の宣言
oclosure-define 13.11 オープンクロージャ
oclosure-interactive-form 22.2.1 interactiveの使用
oclosure-lambda 13.11 オープンクロージャ
oclosure-type 13.11 オープンクロージャ
oclosures 13.11 オープンクロージャ
octal character code 2.4.3.2 一般的なエスケープ構文
octal character input 22.8.5 クォートされた文字の入力
octal escapes 41.23.1 通常の表示の慣習
octal numbers 3.1 整数の基礎
old advices, porting 13.12.4 古いdefadviceを使用するコードの改良
old-selected-frame 29.28 ウィンドウのスクロールと変更のためのフック
old-selected-window 29.28 ウィンドウのスクロールと変更のためのフック
one-or-more in rx 35.3.3.1 rxによるregexpの構築
one-window-p 29.10 ウィンドウのサイクル順
only-global-abbrevs 38.2 abbrevの定義
opacity, frame 30.4.3.10 フォントとカラーのパラメーター
opacity, frame 30.4.3.10 フォントとカラーのパラメーター
open closures 13.11 オープンクロージャ
open-dribble-file 42.13.2 入力の記録
open-network-stream 40.14 ネットワーク接続
open-paren-in-column-0-is-defun-start 31.2.6 釣り合いのとれたカッコを越えた移動
open-termscript 42.14 端末の出力
OpenType font 41.12.12 低レベルのフォント表現
open_channel E.8.4 その他の便利なモジュール用関数
operating system environment 42.3 オペレーティングシステムの環境
operating system signal 42.2.1 Emacsのkill
operations (property) 26.12 特定のファイル名の“Magic”の作成
operations on images 41.17.9 イメージの表示
opt in rx 35.3.3.1 rxによるregexpの構築
optimize regexp 35.3.4 正規表現の関数
option descriptions 1.3.7.2 変数の説明例
optional arguments 13.2.3 引数リストの機能
optional in rx 35.3.3.1 rxによるregexpの構築
options on command line 42.1.4 コマンドライン引数
options, defcustom keyword 15.3 カスタマイゼーション変数の定義
or 11.3 組み合わせ条件の構築
or in rx 35.3.3.1 rxによるregexpの構築
ordering of windows, cyclic 29.10 ウィンドウのサイクル順
origin of display 30.3.1 フレームのレイアウト
other-buffer 28.8 バッファーリスト
other-window 29.10 ウィンドウのサイクル順
other-window, a window parameter 29.27 ウィンドウのパラメーター
other-window-scroll-buffer 29.21 テキスト的なスクロール
outdated node, tree-sitter 37.4 ノード情報へのアクセス
outer border 30.3.1 フレームのレイアウト
outer edges 30.3.1 フレームのレイアウト
outer frame 30.3.1 フレームのレイアウト
outer height 30.3.1 フレームのレイアウト
outer position 30.3.1 フレームのレイアウト
outer size 30.3.1 フレームのレイアウト
outer width 30.3.1 フレームのレイアウト
outer-window-id, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
output from processes 40.9 プロセスからの出力の受信
output stream 20.4 出力ストリーム
output variables, overriding 20.7 出力変数のオーバーライド
output-controlling variables 20.6 出力に影響する変数
overall prompt string 23.3 キーマップのフォーマット
overflow-newline-into-fringe 41.13.3 フリンジのカーソルFrin
overlay properties 41.9.2 オーバーレイのプロパティ
overlay, empty 41.9.1 オーバーレイの管理
overlay-arrow-position 41.13.6 オーバーレイ矢印
overlay-arrow-string 41.13.6 オーバーレイ矢印
overlay-arrow-variable-list 41.13.6 オーバーレイ矢印
overlay-buffer 41.9.1 オーバーレイの管理
overlay-end 41.9.1 オーバーレイの管理
overlay-get 41.9.2 オーバーレイのプロパティ
overlay-properties 41.9.2 オーバーレイのプロパティ
overlay-put 41.9.2 オーバーレイのプロパティ
overlay-start 41.9.1 オーバーレイの管理
overlayp 41.9.1 オーバーレイの管理
overlays 41.9 オーバーレイ
overlays, managing 41.9.1 オーバーレイの管理
overlays, searching for 41.9.3 オーバーレイにたいする検索
overlays-at 41.9.3 オーバーレイにたいする検索
overlays-in 41.9.3 オーバーレイにたいする検索
overlined text 41.12.1 フェイスの属性
override existing functions 13.4 関数の定義
override redirect frames 30.4.3.8 ウィンドウ管理のパラメーター
override spec (for a face) 41.12.2 フェイスの定義
override-redirect, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
overrides, in output functions 20.7 出力変数のオーバーライド
overriding bidirectional properties 41.27 双方向テキストの表示
overriding-local-map 23.9 アクティブなキーマップの制御
overriding-local-map-menu-flag 23.9 アクティブなキーマップの制御
overriding-terminal-local-map 23.9 アクティブなキーマップの制御
overwrite-mode 33.5 ユーザーレベルの挿入コマンド

P
package 43 配布用Lispコードの準備
package archive 43.4 パッケージアーカイブの作成と保守
package archive security 43.4 パッケージアーカイブの作成と保守
package attributes 43.1 パッケージ化の基礎
package autoloads 43.1 パッケージ化の基礎
package dependencies 43.1 パッケージ化の基礎
package name 43.1 パッケージ化の基礎
package signing 43.4 パッケージアーカイブの作成と保守
package version 43.1 パッケージ化の基礎
package-activate-all 43.1 パッケージ化の基礎
package-archives 43.4 パッケージアーカイブの作成と保守
package-initialize 43.1 パッケージ化の基礎
package-version, customization keyword 15.1 一般的なキーワードアイテム
packing 40.20 バイト配列のpackとunpack
padding 4.7 文字列のフォーマット
page-delimiter 35.8 編集で使用される標準的な正規表現
paragraph-separate 35.8 編集で使用される標準的な正規表現
paragraph-separate, and bidirectional display 41.27 双方向テキストの表示
paragraph-start 35.8 編集で使用される標準的な正規表現
paragraph-start, and bidirectional display 41.27 双方向テキストの表示
parameters for moving frames with the mouse 30.4.3.7 マウスドラッグのパラメーター
parameters for resizing frames with the mouse 30.4.3.7 マウスドラッグのパラメーター
parameters of initial frame 30.4.2 フレームの初期パラメーター
parent 24.7.2 パーサーベースのインデント
parent directory of file 26.10 ディレクトリーのコンテンツ
parent frames 30.14 子フレーム
parent of char-table 6.6 文字テーブル
parent process 40 プロセス
parent window 29.2 ウィンドウとフレーム
parent window 29.2 ウィンドウとフレーム
parent-bol 24.7.2 パーサーベースのインデント
parent-frame, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
parent-frame, a frame parameter 30.4.3.6 フレームとの相互作用のためのパラメーター
parent-is 24.7.2 パーサーベースのインデント
parenthesis 2.4.6 コンスセルとリスト型
parenthesis depth 36.6.4 低レベルのパース
parenthesis matching 41.22 カッコの点滅
parenthesis mismatch, debugging 19.3 無効なLisp構文のデバッグ
parity, in serial connections 40.19 シリアルポートとの対話
parse state for a position 36.6.2 ある位置のパース状態を調べる
parse string, tree-sitter 37.2 tree-sitterパーサーの使用
parse-colon-path 42.3 オペレーティングシステムの環境
parse-partial-sexp 36.6.4 低レベルのパース
parse-sexp-ignore-comments 36.6.5 パースを制御するためのパラメーター
parse-sexp-lookup-properties 36.4 構文プロパティ
parse-time-string 42.8 時刻のパースとフォーマット
parser state 36.6.3 パーサー状態
parser-based font-lock 24.6.10 パーサーベースのFont Lock
parser-based indentation 24.7.2 パーサーベースのインデント
parsing buffer text 36 構文テーブル
parsing expressions 36.6 式のパース
parsing html 33.30 HTMLとXMLの解析
parsing multiple languages with tree-sitter 37.6 複数言語ののパース
parsing xml 33.30 HTMLとXMLの解析
parsing, control parameters 36.6.5 パースを制御するためのパラメーター
partial application of functions 13.5 関数の呼び出し
partial-width windows 41.3 切り詰め
passwords, reading 21.9 パスワードの読み取り
PATH environment variable 40.1 サブプロセスを作成する関数
path-separator 42.3 オペレーティングシステムの環境
path-separator 42.3 オペレーティングシステムの環境
pattern matching with tree-sitter nodes 37.5 tree-sitterノードにたいするパターンマッチング
pattern matching, programming style 11.4 パターンマッチングによる条件
pattern syntax, tree-sitter query 37.5 tree-sitterノードにたいするパターンマッチング
patterns, tree-sitter, in string form 37.5 tree-sitterノードにたいするパターンマッチング
PBM 41.17.7 その他のイメージタイプ
pcase 11.4.1 pcaseマクロ
pcase 11.4 パターンマッチングによる条件
pcase pattern 11.4.1 pcaseマクロ
pcase, defining new kinds of patterns 11.4.2 pcaseの拡張
pcase-defmacro 11.4.2 pcaseの拡張
pcase-dolist 11.4.4 pcaseパターンによる分解
pcase-lambda 11.4.4 pcaseパターンによる分解
pcase-let 11.4.4 pcaseパターンによる分解
pcase-let* 11.4.4 pcaseパターンによる分解
pcase-setq 11.4.4 pcaseパターンによる分解
pdumper-stats E.1 Emacsのビルド
peculiar error 11.7.3.4 エラーシンボルとエラー条件
peeking at input 22.8.6 その他のイベント入力の機能
percent symbol in mode line 24.4.2 モードラインのデータ構造
perform-replace 35.7 検索と置換
performance analysis 19.5 プロファイリング
performance analysis (Edebug) 19.2.13 カバレッジテスト
permanent local variable 12.11.2 バッファーローカルなバインディングの作成と削除
permanently-enabled-local-variables 12.12 ファイルローカル変数
permissions, file 26.6.1 アクセシビリティのテスト
permissions, file 26.7 ファイルの名前と属性の変更
persistent window parameters 29.27 ウィンドウのパラメーター
phishing using directional overrides 41.27 双方向テキストの表示
physical lines, moving by 31.2.4 テキスト行単位の移動
piece of advice 13.12 Emacs Lisp関数にたいするアドバイス
pinch event 22.7.12 その他のシステムイベント
pipe, when to use for subprocess communications 40.4 非同期プロセスの作成
pixel height of a window 29.4 ウィンドウのサイズ
pixel width of a window 29.4 ウィンドウのサイズ
pixel-fill-region 33.11 fill
pixel-fill-width 33.11 fill
pixel-resolution wheel events 22.7.12 その他のシステムイベント
pixelwise, resizing windows 29.5 ウィンドウのリサイズ
place form 12.17 ジェネリック変数
play-sound 42.15 サウンドの出力
play-sound-file 42.15 サウンドの出力
play-sound-functions 42.15 サウンドの出力
plist 5.9 プロパティリスト
plist access 5.9.2 プロパティリストと外部シンボル
plist vs. alist 5.9.1 プロパティリストと連想リスト
plist-get 5.9.2 プロパティリストと外部シンボル
plist-member 5.9.2 プロパティリストと外部シンボル
plist-put 5.9.2 プロパティリストと外部シンボル
plistp 5.9 プロパティリスト
plugin_is_GPL_compatible 16.11 Emacsのダイナミックモジュール
point 31.1 ポイント
point 31.1 ポイント
point excursion 31.3 エクスカーション
point excursion 31.3 エクスカーション
point in rx 35.3.3.1 rxによるregexpの構築
point in window 29.19 ウィンドウとポイント
point with narrowing 31.1 ポイント
point-entered (text property) 33.19.4 特殊な意味をもつプロパティ
point-left (text property) 33.19.4 特殊な意味をもつプロパティ
point-marker 32.3 マーカーを作成する関数
point-max 31.1 ポイント
point-max-marker 32.3 マーカーを作成する関数
point-min 31.1 ポイント
point-min-marker 32.3 マーカーを作成する関数
pointer (text property) 33.19.4 特殊な意味をもつプロパティ
pointer shape 30.19 ポインターの形状
pointers 2.4.6 コンスセルとリスト型
polymorphism 13.8 ジェネリック関数
pop 5.3 リスト要素へのアクセス
pop-mark 32.7 マーク
pop-to-buffer 29.12 ウィンドウ内のバッファーへの切り替え
pop-up-frame-alist 29.13.4 バッファー表示の追加オプション
pop-up-frame-function 29.13.4 バッファー表示の追加オプション
pop-up-frame-parameters, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
pop-up-frames 29.13.4 バッファー表示の追加オプション
pop-up-frames, replacement for 29.13.4 バッファー表示の追加オプション
pop-up-windows 29.13.4 バッファー表示の追加オプション
pop-up-windows, replacement for 29.13.4 バッファー表示の追加オプション
popcount 3.8 整数にたいするビット演算
port number, and default coding system 34.10.5 デフォルトのコーディングシステム
pos-bol 31.2.4 テキスト行単位の移動
pos-eol 31.2.4 テキスト行単位の移動
pos-visible-in-window-group-p 29.20 ウィンドウの開始位置と終了位置
pos-visible-in-window-group-p-function 29.20 ウィンドウの開始位置と終了位置
pos-visible-in-window-p 29.20 ウィンドウの開始位置と終了位置
position (in buffer) 31 ポジション
position argument 22.2.2 interactiveにたいするコード文字
position in window 29.19 ウィンドウとポイント
position of frame 30.3 フレームのジオメトリー
position of frame 30.3.3 フレームの位置
position of mouse 30.16 マウスの位置
position-bytes 34.1 テキストの表現方法
position-symbol 9.6 位置をもつシンボル
positive infinity 3.2 浮動小数点数の基礎
posix-looking-at 35.5 POSIX正規表現の検索
posix-search-backward 35.5 POSIX正規表現の検索
posix-search-forward 35.5 POSIX正規表現の検索
posix-string-match 35.5 POSIX正規表現の検索
posn-actual-col-row 22.7.15 マウスイベントへのアクセス
posn-area 22.7.15 マウスイベントへのアクセス
posn-at-point 22.7.15 マウスイベントへのアクセス
posn-at-x-y 22.7.15 マウスイベントへのアクセス
posn-col-row 22.7.15 マウスイベントへのアクセス
posn-image 22.7.15 マウスイベントへのアクセス
posn-object 22.7.15 マウスイベントへのアクセス
posn-object-width-height 22.7.15 マウスイベントへのアクセス
posn-object-x-y 22.7.15 マウスイベントへのアクセス
posn-point 22.7.15 マウスイベントへのアクセス
posn-string 22.7.15 マウスイベントへのアクセス
posn-timestamp 22.7.15 マウスイベントへのアクセス
posn-window 22.7.15 マウスイベントへのアクセス
posn-x-y 22.7.15 マウスイベントへのアクセス
posnp 22.7.15 マウスイベントへのアクセス
post-command-hook 22.1 コマンドループの概要
post-gc-hook E.3 ガーベージコレクション
post-self-insert-hook 33.5 ユーザーレベルの挿入コマンド
pp 20.5 出力関数
pre-command-hook 22.1 コマンドループの概要
pre-redisplay-function 41.2 強制的な再表示
pre-redisplay-functions 41.2 強制的な再表示
precedence of buffer display action functions 29.13.5 アクション関数の優先順
preceding-char 33.1 ポイント近傍のテキストを調べる
precision in format specifications 4.7 文字列のフォーマット
predicates for lists 5.2 リストのための述語
predicates for markers 32.2 マーカーのための述語
predicates for numbers 3.3 数値のための述語
predicates for strings 4.2 文字列のための述語
predicates for syntax tree nodes 37.4 ノード情報へのアクセス
preedit-text event 22.7.12 その他のシステムイベント
prefer-utf-8 coding system 34.10.1 コーディングシステムの基本概念
prefix argument 22.12 プレフィクスコマンド引数
prefix argument unreading 22.8.6 その他のイベント入力の機能
prefix command 23.6 プレフィクスキー
prefix key 23.6 プレフィクスキー
prefix, defgroup keyword 15.2 カスタマイゼーショングループの定義
prefix-arg 22.12 プレフィクスコマンド引数
prefix-command-echo-keystrokes-functions Appendix H 標準的なフック
prefix-command-preserve-state-hook Appendix H 標準的なフック
prefix-help-command 25.6 ヘルプ関数
prefix-numeric-value 22.12 プレフィクスコマンド引数
preloaded Lisp files E.1 Emacsのビルド
preloaded-file-list E.1 Emacsのビルド
preloading additional functions and variables E.1 Emacsのビルド
prepare-change-group 33.33 グループのアトミックな変更
preserve-size, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
preserving window sizes 29.6 ウィンドウサイズの保持
pretty-printer 20.5 出力関数
prev-adaptive-prefix 24.7.2 パーサーベースのインデント
prev-line 24.7.2 パーサーベースのインデント
prev-sibling 24.7.2 パーサーベースのインデント
prevent warnings in init files 41.5.3 警告のためのオプション
preventing backtracking 19.2.15.2 仕様リスト
preventing prefix key 23.10 キーの照合
preventing quitting 22.11 quit
previous complete subexpression 36.6.3 パーサー状態
previous-button 41.20.5 ボタンのためのバッファーコマンド
previous-char-property-change 33.19.3 テキストプロパティの検索関数
previous-complete-history-element 21.10 ミニバッファーのコマンド
previous-frame 30.8 すべてのフレームを探す
previous-history-element 21.10 ミニバッファーのコマンド
previous-matching-history-element 21.10 ミニバッファーのコマンド
previous-overlay-change 41.9.3 オーバーレイにたいする検索
previous-property-change 33.19.3 テキストプロパティの検索関数
previous-single-char-property-change 33.19.3 テキストプロパティの検索関数
previous-single-property-change 33.19.3 テキストプロパティの検索関数
previous-window 29.10 ウィンドウのサイクル順
previous-window, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
primary selection 30.20 ウィンドウシステムによる選択
primitive 13.1 関数とは?
primitive function 2.4.15 プリミティブ関数型
primitive function internals E.7 Emacsプリミティブの記述
primitive type 2 Lispのデータ型
primitive-undo 33.9 アンドゥ
prin1 20.5 出力関数
prin1-to-string 20.5 出力関数
princ 20.5 出力関数
print 20.5 出力関数
print example 20.4 出力ストリーム
print name cell 9.1 シンボルの構成要素
print-charset-text-property 20.6 出力に影響する変数
print-circle 20.6 出力に影響する変数
print-continuous-numbering 20.6 出力に影響する変数
print-escape-control-characters 20.6 出力に影響する変数
print-escape-multibyte 20.6 出力に影響する変数
print-escape-newlines 20.6 出力に影響する変数
print-escape-nonascii 20.6 出力に影響する変数
print-gensym 20.6 出力に影響する変数
print-integers-as-characters 20.6 出力に影響する変数
print-length 20.6 出力に影響する変数
print-level 20.6 出力に影響する変数
print-number-table 20.6 出力に影響する変数
print-quoted 20.6 出力に影響する変数
print-symbols-bare 9.6 位置をもつシンボル
print-unreadable-function 20.6 出力に影響する変数
printable ASCII characters 41.23.1 通常の表示の慣習
printable-chars 34.6 文字のプロパティ
printed representation 2.1 プリント表現と読み取り構文
printed representation for characters 2.4.3.1 基本的な文字構文
printing 20.1 読み取りとプリントの概念
printing (Edebug) 19.2.11 Edebugでのプリント
printing circular structures 19.2.11 Edebugでのプリント
printing limits 20.6 出力に影響する変数
printing notation 1.3.4 プリントの表記
priority (overlay property) 41.9.2 オーバーレイのプロパティ
priority order of coding systems 34.10.6 単一の操作にたいするコーディングシステムの指定
process 40 プロセス
process creation 40.1 サブプロセスを作成する関数
process filter 40.9.2 プロセスのフィルター関数
process filter multibyte flag 40.9.3 プロセス出力のデコード
process information 40.6 プロセスの情報
process input 40.7 プロセスへの入力の送信
process internals E.9.3 プロセスの内部
process output 40.9 プロセスからの出力の受信
process sentinel 40.10 センチネル: プロセス状態の変更の検知
process signals 40.8 プロセスへのシグナルの送信
process-adaptive-read-buffering 40.9 プロセスからの出力の受信
process-attributes 40.12 別のプロセスへのアクセス
process-buffer 40.9.1 プロセスのバッファー
process-coding-system 40.6 プロセスの情報
process-coding-system-alist 34.10.5 デフォルトのコーディングシステム
process-command 40.6 プロセスの情報
process-connection-type 40.4 非同期プロセスの作成
process-contact 40.6 プロセスの情報
process-datagram-address 40.16 データグラム
process-environment 42.3 オペレーティングシステムの環境
process-error-pause-time 40.4 非同期プロセスの作成
process-exit-status 40.6 プロセスの情報
process-file 40.3 同期プロセスの作成
process-file-return-signal-string 40.3 同期プロセスの作成
process-file-shell-command 40.3 同期プロセスの作成
process-file-side-effects 40.3 同期プロセスの作成
process-filter 40.9.2 プロセスのフィルター関数
process-get 40.6 プロセスの情報
process-id 40.6 プロセスの情報
process-kill-buffer-query-function 40.9.1 プロセスのバッファー
process-lines 40.3 同期プロセスの作成
process-lines-ignore-status 40.3 同期プロセスの作成
process-list 40.6 プロセスの情報
process-live-p 40.6 プロセスの情報
process-mark 40.9.1 プロセスのバッファー
process-name 40.6 プロセスの情報
process-plist 40.6 プロセスの情報
process-put 40.6 プロセスの情報
process-query-on-exit-flag 40.11 exit前の問い合わせ
process-running-child-p 40.7 プロセスへの入力の送信
process-send-eof 40.7 プロセスへの入力の送信
process-send-region 40.7 プロセスへの入力の送信
process-send-string 40.7 プロセスへの入力の送信
process-sentinel 40.10 センチネル: プロセス状態の変更の検知
process-status 40.6 プロセスの情報
process-thread 40.9.5 プロセスとスレッド
process-tty-name 40.6 プロセスの情報
process-type 40.6 プロセスの情報
processes, threads 40.9.5 プロセスとスレッド
processing of errors 11.7.3.2 Emacsがエラーを処理する方法
processor run time 42.9 プロセッサーの実行時間
processp 40 プロセス
process_input E.8.4 その他の便利なモジュール用関数
profile 19.5 プロファイリング
profiler-report 19.5 プロファイリング
profiler-start 19.5 プロファイリング
profiler-stop 19.5 プロファイリング
profiling 19.5 プロファイリング
prog-first-column 33.17.2 メジャーモードが制御するインデント
prog-indentation-context 33.17.2 メジャーモードが制御するインデント
prog-mode 24.2.5 基本的なメジャーモード
prog-mode, and bidi-paragraph-direction 41.27 双方向テキストの表示
prog-mode-hook 24.2.5 基本的なメジャーモード
prog-mode-map Appendix G 標準的なキーマップ
prog1 11.1 順序
prog2 11.1 順序
progn 11.1 順序
program arguments 40.1 サブプロセスを作成する関数
program directories 40.1 サブプロセスを作成する関数
program name, and default coding system 34.10.5 デフォルトのコーディングシステム
programmed completion 21.6.7 プログラムされた補完
programming conventions D.3 Emacsプログラミングのヒント
programming types 2.4 プログラミングの型
progress reporting 41.4.2 処理の進捗レポート
progress-reporter-done 41.4.2 処理の進捗レポート
progress-reporter-force-update 41.4.2 処理の進捗レポート
progress-reporter-update 41.4.2 処理の進捗レポート
prompt for file name 21.6.5 ファイル名の読み取り
prompt string (of menu) 23.18.1 メニューの定義
prompt string of keymap 23.3 キーマップのフォーマット
proper list 5.1 リストとコンスセル
proper-list-p 5.2 リストのための述語
properties of text 33.19 テキストのプロパティ
propertize 33.19.2 テキストプロパティの変更
property category of text character 33.19.4 特殊な意味をもつプロパティ
property list 5.9 プロパティリスト
property list cell 9.1 シンボルの構成要素
property lists vs association lists 5.9.1 プロパティリストと連想リスト
protect C variables from garbage collection E.7 Emacsプリミティブの記述
protected forms 11.7.4 非ローカル脱出のクリーンアップ
provide 16.7 名前つき機能
provide-theme 15.6 Customテーマ
providing features 16.7 名前つき機能
pseudo window E.9.2 ウィンドウの内部
pty, when to use for subprocess communications 40.4 非同期プロセスの作成
pure function 13.1 関数とは?
pure property 9.4.2 シンボルの標準的なプロパティ
pure storage E.2 純粋ストレージ
pure-bytes-used E.2 純粋ストレージ
purecopy E.2 純粋ストレージ
purify-flag E.2 純粋ストレージ
push 5.5 リスト変数の変更
push-button 41.20.5 ボタンのためのバッファーコマンド
push-mark 32.7 マーク
put 9.4.1 シンボルのプロパティへのアクセス
put-char-code-property 34.6 文字のプロパティ
put-charset-property 34.7 文字セット
put-image 41.17.9 イメージの表示
put-text-property 33.19.2 テキストプロパティの変更
puthash 8.2 ハッシュテーブルへのアクセス

Q
quadratic-bezier-curveto 41.17.6 SVGイメージ
quantify node, tree-sitter 37.5 tree-sitterノードにたいするパターンマッチング
queries, compiling 37.5 tree-sitterノードにたいするパターンマッチング
query 24.7.2 パーサーベースのインデント
query functions, tree-sitter 37.5 tree-sitterノードにたいするパターンマッチング
query, tree-sitter 37.5 tree-sitterノードにたいするパターンマッチング
query-font 41.12.12 低レベルのフォント表現
query-replace-history 21.4 ミニバッファーのヒストリー
query-replace-map 35.7 検索と置換
querying the user 21.7 Yes-or-Noによる問い合わせ
question mark in character constant 2.4.3.1 基本的な文字構文
quietly-read-abbrev-file 38.3 ファイルへのabbrevの保存
quit-flag 22.11 quit
quit-process 40.8 プロセスへのシグナルの送信
quit-restore, a window parameter 29.27 ウィンドウのパラメーター
quit-restore-window 29.16 ウィンドウのquit
quit-window 29.16 ウィンドウのquit
quit-window-hook 29.16 ウィンドウのquit
quitting 22.11 quit
quitting from infinite loop 19.1.3 無限ループのデバッグ
quitting windows 29.16 ウィンドウのquit
quote 10.3 クォート
quote character 36.6.3 パーサー状態
quote special characters in regexp 35.3.4 正規表現の関数
quoted character input 22.8.5 クォートされた文字の入力
quoted-insert suppression 23.12 キーバインディングの変更
quoting and unquoting command-line arguments 40.2 shell引数
quoting characters in printing 20.5 出力関数
quoting using apostrophe 10.3 クォート

R
radio, customization types 15.4.2 複合型
radix for reading an integer 3.1 整数の基礎
raise-frame 30.12 フレームのraise、lower、re-stack
raising a frame 30.12 フレームのraise、lower、re-stack
random 3.10 乱数
random numbers 3.10 乱数
rassoc 5.8 連想リスト
rassq 5.8 連想リスト
rassq-delete-all 5.8 連想リスト
raw prefix argument 22.12 プレフィクスコマンド引数
raw prefix argument usage 22.2.2 interactiveにたいするコード文字
raw syntax descriptor 36.7 構文テーブルの内部
raw-text coding system 34.10.1 コーディングシステムの基本概念
re-builder 35.3 正規表現
re-search-backward 35.4 正規表現の検索
re-search-forward 35.4 正規表現の検索
read 20.3 入力関数
read command name 22.3 インタラクティブな呼び出し
read file names 21.6.5 ファイル名の読み取り
read input 22.8 入力の読み取り
read syntax 2.1 プリント表現と読み取り構文
read syntax for characters 2.4.3.1 基本的な文字構文
read-answer 21.8 複数の問いを尋ねる
read-answer-short 21.8 複数の問いを尋ねる
read-buffer 21.6.4 高レベルの補完関数
read-buffer-completion-ignore-case 21.6.4 高レベルの補完関数
read-buffer-function 21.6.4 高レベルの補完関数
read-char 22.8.2 単一イベントの読み取り
read-char-choice 22.8.2 単一イベントの読み取り
read-char-choice-use-read-key 22.8.2 単一イベントの読み取り
read-char-exclusive 22.8.2 単一イベントの読み取り
read-char-from-minibuffer 21.8 複数の問いを尋ねる
read-circle 20.3 入力関数
read-coding-system 34.10.4 ユーザーが選択したコーディングシステム
read-color 21.6.4 高レベルの補完関数
read-command 21.6.4 高レベルの補完関数
read-directory-name 21.6.5 ファイル名の読み取り
read-event 22.8.2 単一イベントの読み取り
read-expression-history 21.4 ミニバッファーのヒストリー
read-extended-command-predicate 22.2.4 コマンドにたいするモード指定
read-extended-command-predicate 22.3 インタラクティブな呼び出し
read-file-modes 26.7 ファイルの名前と属性の変更
read-file-name 21.6.5 ファイル名の読み取り
read-file-name-completion-ignore-case 21.6.5 ファイル名の読み取り
read-file-name-function 21.6.5 ファイル名の読み取り
read-from-minibuffer 21.2 ミニバッファーでのテキスト文字列の読み取り
read-from-string 20.3 入力関数
read-hide-char 21.9 パスワードの読み取り
read-input-method-name 34.11 入力メソッド
read-kbd-macro 25.5 ヘルプメッセージの文字記述
read-key 22.8.2 単一イベントの読み取り
read-key-sequence 22.8.1 キーシーケンス入力
read-key-sequence-vector 22.8.1 キーシーケンス入力
read-minibuffer 21.3 ミニバッファーでのLispオブジェクトの読み取り
read-minibuffer-restore-windows 21.2 ミニバッファーでのテキスト文字列の読み取り
read-multiple-choice 22.8.2 単一イベントの読み取り
read-no-blanks-input 21.2 ミニバッファーでのテキスト文字列の読み取り
read-non-nil-coding-system 34.10.4 ユーザーが選択したコーディングシステム
read-number-history 21.4 ミニバッファーのヒストリー
read-only (text property) 33.19.4 特殊な意味をもつプロパティ
read-only buffer 28.7 読み取り専用のバッファー
read-only buffers in interactive 22.2.1 interactiveの使用
read-only character 33.19.4 特殊な意味をもつプロパティ
read-only variables 12.2 変更不可な変数
read-only-mode 28.7 読み取り専用のバッファー
read-passwd 21.9 パスワードの読み取り
read-positioning-symbols 20.3 入力関数
read-quoted-char 22.8.5 クォートされた文字の入力
read-quoted-char quitting 22.11 quit
read-regexp 21.2 ミニバッファーでのテキスト文字列の読み取り
read-regexp-case-fold-search 21.2 ミニバッファーでのテキスト文字列の読み取り
read-regexp-defaults-function 21.2 ミニバッファーでのテキスト文字列の読み取り
read-shell-command 21.6.5 ファイル名の読み取り
read-string 21.2 ミニバッファーでのテキスト文字列の読み取り
read-string-from-buffer 21.2 ミニバッファーでのテキスト文字列の読み取り
read-symbol-shorthands 9.5 ショートハンド
read-variable 21.6.4 高レベルの補完関数
read-variable, history list 21.4 ミニバッファーのヒストリー
readable syntax 20.3 入力関数
readablep 20.3 入力関数
reading 20.1 読み取りとプリントの概念
reading a single event 22.8.2 単一イベントの読み取り
reading from files 26.3 ファイルからの読み込み
reading from minibuffer with completion 21.6.2 補完とミニバッファー
reading grammar definition, tree-sitter 37.1 Tree-sitter Language Grammar
reading interactive arguments 22.2.2 interactiveにたいするコード文字
reading numbers in hex, octal, and binary 3.1 整数の基礎
reading order 41.27 双方向テキストの表示
reading symbols 9.3 シンボルの作成とintern
real-last-command 22.5 コマンドループからの情報
rear-nonsticky text property 33.19.6 テキストプロパティの粘着性
rear-nonsticky, and cursor-intangible property 33.19.4 特殊な意味をもつプロパティ
rearrangement of lists 5.6.3 リストを再配置する関数
rebinding 23.12 キーバインディングの変更
recent-auto-save-p 27.2 自動保存
recent-keys 42.13.2 入力の記録
recenter 29.21 テキスト的なスクロール
recenter-positions 29.21 テキスト的なスクロール
recenter-redisplay 29.21 テキスト的なスクロール
recenter-top-bottom 29.21 テキスト的なスクロール
recenter-window-group 29.21 テキスト的なスクロール
recenter-window-group-function 29.21 テキスト的なスクロール
recombining windows 29.9 ウィンドウの再結合
record 7.1 レコード関数
record command history 22.3 インタラクティブな呼び出し
recording input 42.13.2 入力の記録
recordp 7.1 レコード関数
records 7 レコード
rectangle, as contents of a register 33.21 レジスター
recursion 11.5 繰り返し
recursion-depth 22.13 再帰編集
recursive command loop 22.13 再帰編集
recursive editing level 22.13 再帰編集
recursive evaluation 10.1 評価の概要
recursive minibuffers 21.13 再帰的なミニバッファー
recursive traverse of directory tree 26.10 ディレクトリーのコンテンツ
recursive-edit 22.13 再帰編集
redefine existing functions 13.4 関数の定義
redirect-frame-focus 30.10 入力のフォーカス
redisplay 41.2 強制的な再表示
redisplay errors 19.1.2 再表示エラーのデバッグ
redo 33.9 アンドゥ
redraw-display 41.1 スクリーンのリフレッシュ
redraw-frame 41.1 スクリーンのリフレッシュ
reducing sequences 6.1 シーケンス
reference to free variable, compilation warning 17.6 コンパイラーのエラー
references, following D.2 キーバインディング規約
refresh the screen 41.1 スクリーンのリフレッシュ
regex in rx 35.3.3.1 rxによるregexpの構築
regexp 35.3 正規表現
regexp alternative 35.3.1.3 正規表現内のバッククラッシュ構文
regexp grouping 35.3.1.3 正規表現内のバッククラッシュ構文
regexp in rx 35.3.3.1 rxによるregexpの構築
regexp searching 35.4 正規表現の検索
regexp stack overflow 35.3.5 正規表現にまつわるトラブル
regexp syntax 35.3.1 正規表現の構文
regexp syntax 35.3.3 rx構造化Rgexp表記
regexp, special characters in 35.3.1.1 正規表現内の特殊文字
regexp-history 21.4 ミニバッファーのヒストリー
regexp-opt 35.3.4 正規表現の関数
regexp-opt-charset 35.3.4 正規表現の関数
regexp-opt-depth 35.3.4 正規表現の関数
regexp-quote 35.3.4 正規表現の関数
regexp-unmatchable 35.3.4 正規表現の関数
regexps used standardly in editing 35.8 編集で使用される標準的な正規表現
region 32.8 リージョン
region argument 22.2.2 interactiveにたいするコード文字
region-beginning 32.8 リージョン
region-end 32.8 リージョン
register preview 33.21 レジスター
register-alist 33.21 レジスター
register-definition-prefixes 16.5.1 プレフィックスによるautoload
register-read-with-preview 33.21 レジスター
registers 33.21 レジスター
regular expression 35.3 正規表現
regular expression problems 35.3.5 正規表現にまつわるトラブル
regular expression searching 35.4 正規表現の検索
regular expressions, developing 35.3 正規表現
reindent-then-newline-and-indent 33.17.2 メジャーモードが制御するインデント
relative file name 26.9.2 絶対ファイル名と相対ファイル名
relative remapping, faces 41.12.5 フェイスのリマップ
remainder 3.6 算術演算
remapping commands 23.14 コマンドのリマップ
remhash 8.2 ハッシュテーブルへのアクセス
remote-file-name-inhibit-cache 26.12 特定のファイル名の“Magic”の作成
remote-file-name-inhibit-locks 26.5 ファイルのロック
remove 5.7 集合としてのリストの使用
remove-from-invisibility-spec 41.6 不可視のテキスト
remove-function 13.12.1 アドバイスを操作するためのプリミティブ
remove-hook 24.1.2 フックのセット
remove-images 41.17.9 イメージの表示
remove-list-of-text-properties 33.19.2 テキストプロパティの変更
remove-overlays 41.9.1 オーバーレイの管理
remove-text-properties 33.19.2 テキストプロパティの変更
remove-variable-watcher 12.9 変数が変更されたときに実行される関数。
removing from sequences 6.1 シーケンス
removing from sequences 6.1 シーケンス
remq 5.7 集合としてのリストの使用
rename-auto-save-file 27.2 自動保存
rename-buffer 28.3 バッファーの名前
rename-file 26.7 ファイルの名前と属性の変更
rendering html 33.30 HTMLとXMLの解析
reordering, of bidirectional text 41.27 双方向テキストの表示
reordering, of elements in lists 5.6.3 リストを再配置する関数
reparent frame 30.14 子フレーム
repeat events 22.7.7 リピートイベント
repeat in rx 35.3.3.1 rxによるregexpの構築
repeat-mode 23.4 キーマップの作成
repeatable key bindings 23.4 キーマップの作成
repeated loading 16.6 多重ロード
replace bindings 23.12 キーバインディングの変更
replace characters 33.20 文字コードの置き換え
replace characters in region 33.20 文字コードの置き換え
replace characters in string 33.20 文字コードの置き換え
replace list element 5.6.1 setcarによるリスト要素の変更
replace matched text 35.6.1 マッチしたテキストの置換
replace part of list 5.6.2 リストのCDRの変更
replace-buffer-contents 33.23 バッファーテキストの置換
replace-buffer-in-windows 29.11 バッファーとウィンドウ
replace-match 35.6.1 マッチしたテキストの置換
replace-re-search-function 35.7 検索と置換
replace-regexp-in-region 35.7 検索と置換
replace-regexp-in-string 35.7 検索と置換
replace-region-contents 33.23 バッファーテキストの置換
replace-search-function 35.7 検索と置換
replace-string-in-region 35.7 検索と置換
replacement after search 35.7 検索と置換
replacing display specs 41.16.1 テキストを置換するディスプレイ仕様
require 16.7 名前つき機能
require, customization keyword 15.1 一般的なキーワードアイテム
require-final-newline 26.2 バッファーの保存
require-theme 15.6 Customテーマ
requiring features 16.7 名前つき機能
reserved keys D.2 キーバインディング規約
reset, face attribute value 41.12.1 フェイスの属性
resize window 29.5 ウィンドウのリサイズ
resize-mini-frames 21.11 ミニバッファーのウィンドウ
resize-mini-windows 21.11 ミニバッファーのウィンドウ
rest arguments 13.2.3 引数リストの機能
restacking a frame 30.12 フレームのraise、lower、re-stack
restart-emacs 42.2.1 Emacsのkill
restore-buffer-modified-p 28.5 バッファーの変更
restricted-sexp, customization types 15.4.2 複合型
restriction (in a buffer) 31.4 ナローイング
resume (cf. no-redraw-on-reenter) 41.1 スクリーンのリフレッシュ
resume-tty 42.2.2 Emacsのサスペンド
resume-tty-functions 42.2.2 Emacsのサスペンド
rethrow a signal 11.7.3.3 エラーを処理するコードの記述
retrieve node, tree-sitter 37.3 ノードの取得
retrieving tree-sitter nodes 37.3 ノードの取得
return (ASCII character) 2.4.3.1 基本的な文字構文
return value 13.1 関数とは?
reusable-frames, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
reverse 6.1 シーケンス
reversing a list 6.1 シーケンス
reversing a string 6.1 シーケンス
reversing a vector 6.1 シーケンス
revert-buffer 27.3 リバート
revert-buffer-function 27.3 リバート
revert-buffer-in-progress-p 27.3 リバート
revert-buffer-insert-file-contents-function 27.3 リバート
revert-without-query 27.3 リバート
reverting buffers 27.3 リバート
rgb value 30.23 カラー名
right dividers 41.15 ウィンドウディバイダー
right-divider, prefix key 22.8.1 キーシーケンス入力
right-divider-width, a frame parameter 30.4.3.4 レイアウトのパラメーター
right-fringe, a frame parameter 30.4.3.4 レイアウトのパラメーター
right-fringe, prefix key 22.8.1 キーシーケンス入力
right-fringe-width 41.13.1 フリンジのサイズと位置
right-margin, prefix key 22.8.1 キーシーケンス入力
right-margin-width 41.16.5 マージン内への表示
right-to-left text 41.27 双方向テキストの表示
ring data structure 6.8 オブジェクト用固定長リングの管理
ring-bell-function 41.24 ビープ
ring-copy 6.8 オブジェクト用固定長リングの管理
ring-elements 6.8 オブジェクト用固定長リングの管理
ring-empty-p 6.8 オブジェクト用固定長リングの管理
ring-insert 6.8 オブジェクト用固定長リングの管理
ring-insert-at-beginning 6.8 オブジェクト用固定長リングの管理
ring-length 6.8 オブジェクト用固定長リングの管理
ring-p 6.8 オブジェクト用固定長リングの管理
ring-ref 6.8 オブジェクト用固定長リングの管理
ring-remove 6.8 オブジェクト用固定長リングの管理
ring-resize 6.8 オブジェクト用固定長リングの管理
ring-size 6.8 オブジェクト用固定長リングの管理
risky, defcustom keyword 15.3 カスタマイゼーション変数の定義
risky-local-variable-p 12.12 ファイルローカル変数
RLO 41.27 双方向テキストの表示
rm 26.7 ファイルの名前と属性の変更
root window 29.2 ウィンドウとフレーム
root window of atomic window 29.18 アトミックウィンドウ
round 3.5 数値の変換
rounding in conversions 3.5 数値の変換
rounding without conversion 3.7 丸め処理
rplaca 5.6 既存のリスト構造の変更
rplacd 5.6 既存のリスト構造の変更
run time stack 19.1.11 デバッガの内部
run-at-time 42.11 遅延実行のためのタイマー
run-hook-with-args 24.1.1 フックの実行
run-hook-with-args-until-failure 24.1.1 フックの実行
run-hook-with-args-until-success 24.1.1 フックの実行
run-hooks 24.1.1 フックの実行
run-mode-hooks 24.2.6 モードフック
run-with-idle-timer 42.12 アイドルタイマー
run-with-timer 42.11 遅延実行のためのタイマー
running a hook when a window gets selected 29.3 ウィンドウの選択
rx 35.3.3.2 rxのregexpを使用する関数とマクロ
rx 35.3.3 rx構造化Rgexp表記
rx-define 35.3.3.3 新たなrxフォームの定義
rx-let 35.3.3.3 新たなrxフォームの定義
rx-let-eval 35.3.3.3 新たなrxフォームの定義
rx-to-string 35.3.3.2 rxのregexpを使用する関数とマクロ

S
S-expression 10.1 評価の概要
safe local variable 12.12 ファイルローカル変数
safe, defcustom keyword 15.3 カスタマイゼーション変数の定義
safe-length 5.3 リスト要素へのアクセス
safe-local-eval-forms 12.12 ファイルローカル変数
safe-local-variable, property of variable 12.12 ファイルローカル変数
safe-local-variable-p 12.12 ファイルローカル変数
safe-local-variable-values 12.12 ファイルローカル変数
safe-magic (property) 26.12 特定のファイル名の“Magic”の作成
safely encode a string 34.10.3 Lispでのコーディングシステム
safely encode characters in a charset 34.10.3 Lispでのコーディングシステム
safely encode region 34.10.3 Lispでのコーディングシステム
safety of functions 13.17 安全に関数を呼び出せるかどうかの判断
same-window-buffer-names, replacement for 29.13.4 バッファー表示の追加オプション
same-window-regexps, replacement for 29.13.4 バッファー表示の追加オプション
save abbrevs in files 38.3 ファイルへのabbrevの保存
save-abbrevs 38.3 ファイルへのabbrevの保存
save-buffer 26.2 バッファーの保存
save-buffer-coding-system 34.10.2 エンコーディングとI/O
save-current-buffer 28.2 カレントバッファー
save-excursion 31.3 エクスカーション
save-mark-and-excursion 31.3 エクスカーション
save-match-data 35.6.4 マッチデータの保存とリストア
save-restriction 31.4 ナローイング
save-selected-window 29.3 ウィンドウの選択
save-some-buffers 26.2 バッファーの保存
save-some-buffers-default-predicate 26.2 バッファーの保存
save-window-excursion 29.26 ウィンドウの構成
saved-face (face symbol property) 41.12.2 フェイスの定義
SaveUnder feature 30.26 ディスプレイ機能のテスト
saving buffers 26.2 バッファーの保存
saving text properties 26.13 ファイルのフォーマット変換
saving window information 29.26 ウィンドウの構成
scalable fonts 41.12.9 フォントの選択
scalable-fonts-allowed 41.12.9 フォントの選択
scan-lists 36.6.1 パースにもとづくモーションコマンド
scan-sexps 36.6.1 パースにもとづくモーションコマンド
scanning expressions 36.6 式のパース
scanning for character sets 34.8 文字セットのスキャン
scanning keymaps 23.17 キーマップのスキャン
scope 12.10 変数のバインディングのスコーピングルール
scoping rule 12.10 変数のバインディングのスコーピングルール
screen layout 2.5.7 フレーム構成型
screen lines, moving by 31.2.5 スクリーン行単位の移動
screen of terminal 29.1 Emacsウィンドウの基本概念
screen refresh 41.1 スクリーンのリフレッシュ
screen-gamma, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
script symbols 34.6 文字のプロパティ
scroll bar events, data in 22.7.16 スクロールバーイベントへのアクセス
scroll bars 41.14 スクロールバー
scroll-bar-background, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
scroll-bar-event-ratio 22.7.16 スクロールバーイベントへのアクセス
scroll-bar-foreground, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
scroll-bar-height 41.14 スクロールバー
scroll-bar-height, a frame parameter 30.4.3.4 レイアウトのパラメーター
scroll-bar-mode 41.14 スクロールバー
scroll-bar-scale 22.7.16 スクロールバーイベントへのアクセス
scroll-bar-width 41.14 スクロールバー
scroll-bar-width, a frame parameter 30.4.3.4 レイアウトのパラメーター
scroll-command property 29.21 テキスト的なスクロール
scroll-conservatively 29.21 テキスト的なスクロール
scroll-down 29.21 テキスト的なスクロール
scroll-down-aggressively 29.21 テキスト的なスクロール
scroll-down-command 29.21 テキスト的なスクロール
scroll-error-top-bottom 29.21 テキスト的なスクロール
scroll-left 29.23 水平スクロール
scroll-margin 29.21 テキスト的なスクロール
scroll-other-window 29.21 テキスト的なスクロール
scroll-other-window-down 29.21 テキスト的なスクロール
scroll-preserve-screen-position 29.21 テキスト的なスクロール
scroll-right 29.23 水平スクロール
scroll-step 29.21 テキスト的なスクロール
scroll-up 29.21 テキスト的なスクロール
scroll-up-aggressively 29.21 テキスト的なスクロール
scroll-up-command 29.21 テキスト的なスクロール
scrolling textually 29.21 テキスト的なスクロール
search-backward 35.1 文字列の検索
search-failed 35.1 文字列の検索
search-forward 35.1 文字列の検索
search-map 23.6 プレフィクスキー
search-spaces-regexp 35.4 正規表現の検索
searching 35 検索とマッチング
searching active keymaps for keys 23.8 アクティブなキーマップの検索
searching and case 35.2 検索と大文字小文字
searching and replacing 35.7 検索と置換
searching for overlays 41.9.3 オーバーレイにたいする検索
searching for regexp 35.4 正規表現の検索
searching text properties 33.19.3 テキストプロパティの検索関数
secondary selection 30.20 ウィンドウシステムによる選択
secondary storage 26.8 ファイルと二次媒体
secure-hash 33.26 チェックサムとハッシュ
secure-hash-algorithms 33.26 チェックサムとハッシュ
security 42.22 セキュリティへの配慮
security vulnerabilities in text 33.27 不審なテキスト
security, and display specifications 41.16 displayプロパティ
seed, for random number generation 3.10 乱数
select safe coding system 34.10.4 ユーザーが選択したコーディングシステム
select window hooks 29.3 ウィンドウの選択
select-frame 30.10 入力のフォーカス
select-frame-set-input-focus 30.10 入力のフォーカス
select-safe-coding-system 34.10.4 ユーザーが選択したコーディングシステム
select-safe-coding-system-accept-default-p 34.10.4 ユーザーが選択したコーディングシステム
select-safe-coding-system-function 34.10.4 ユーザーが選択したコーディングシステム
select-window 29.3 ウィンドウの選択
selected frame 30.10 入力のフォーカス
selected window 29.3 ウィンドウの選択
selected-frame 30.10 入力のフォーカス
selected-window 29.3 ウィンドウの選択
selected-window-group 29.3 ウィンドウの選択
selected-window-group-function 29.3 ウィンドウの選択
selecting a buffer 28.2 カレントバッファー
selecting a font 41.12.9 フォントの選択
selecting a window 29.3 ウィンドウの選択
selection (for window systems) 30.20 ウィンドウシステムによる選択
selection-coding-system 30.20 ウィンドウシステムによる選択
selective-display 41.7 選択的な表示
selective-display-ellipses 41.7 選択的な表示
selectively disabling font-lock fontifications 24.6.3 検索ベースのフォント化のカスタマイズ
self-evaluating form 10.2.1 自己評価を行うフォーム
self-insert-and-exit 21.10 ミニバッファーのコマンド
self-insert-command 33.5 ユーザーレベルの挿入コマンド
self-insert-command override 23.12 キーバインディングの変更
self-insert-command, minor modes 24.3.2 キーマップとマイナーモード
self-insert-uses-region-functions 33.5 ユーザーレベルの挿入コマンド
self-insertion 33.5 ユーザーレベルの挿入コマンド
SELinux context 26.6.5 拡張されたファイル属性
send-string-to-terminal 42.14 端末の出力
sending signals 40.8 プロセスへのシグナルの送信
sentence-end 35.8 編集で使用される標準的な正規表現
sentence-end 35.8 編集で使用される標準的な正規表現
sentence-end-double-space 33.11 fill
sentence-end-without-period 33.11 fill
sentence-end-without-space 33.11 fill
sentinel (of process) 40.10 センチネル: プロセス状態の変更の検知
seq in rx 35.3.3.1 rxによるregexpの構築
seq library 6.1 シーケンス
seq-concatenate 6.1 シーケンス
seq-contains-p 6.1 シーケンス
seq-count 6.1 シーケンス
seq-difference 6.1 シーケンス
seq-do 6.1 シーケンス
seq-doseq 6.1 シーケンス
seq-drop 6.1 シーケンス
seq-drop-while 6.1 シーケンス
seq-elt 6.1 シーケンス
seq-empty-p 6.1 シーケンス
seq-every-p 6.1 シーケンス
seq-filter 6.1 シーケンス
seq-find 6.1 シーケンス
seq-group-by 6.1 シーケンス
seq-intersection 6.1 シーケンス
seq-into 6.1 シーケンス
seq-keep 6.1 シーケンス
seq-length 6.1 シーケンス
seq-let 6.1 シーケンス
seq-map 6.1 シーケンス
seq-map-indexed 6.1 シーケンス
seq-mapcat 6.1 シーケンス
seq-mapn 6.1 シーケンス
seq-max 6.1 シーケンス
seq-min 6.1 シーケンス
seq-partition 6.1 シーケンス
seq-position 6.1 シーケンス
seq-positions 6.1 シーケンス
seq-random-elt 6.1 シーケンス
seq-reduce 6.1 シーケンス
seq-remove 6.1 シーケンス
seq-remove-at-position 6.1 シーケンス
seq-set-equal-p 6.1 シーケンス
seq-setq 6.1 シーケンス
seq-some 6.1 シーケンス
seq-sort 6.1 シーケンス
seq-sort-by 6.1 シーケンス
seq-split 6.1 シーケンス
seq-subseq 6.1 シーケンス
seq-take 6.1 シーケンス
seq-take-while 6.1 シーケンス
seq-union 6.1 シーケンス
seq-uniq 6.1 シーケンス
seqp 6.1 シーケンス
sequence 6 シーケンス、配列、ベクター
sequence destructuring 6.1 シーケンス
sequence destructuring 6.1 シーケンス
sequence functions in seq 6.1 シーケンス
sequence in rx 35.3.3.1 rxによるregexpの構築
sequence iteration 6.1 シーケンス
sequence length 6.1 シーケンス
sequence maximum 6.1 シーケンス
sequence minimum 6.1 シーケンス
sequence reverse 6.1 シーケンス
sequencep 6.1 シーケンス
sequences, generalized 6.1 シーケンス
sequences, intersection of 6.1 シーケンス
sequences, union of 6.1 シーケンス
sequencing 11.1 順序
sequencing pattern 11.4.1 pcaseマクロ
sequential execution 11.1 順序
serial connections 40.19 シリアルポートとの対話
serial-process-configure 40.19 シリアルポートとの対話
serial-term 40.19 シリアルポートとの対話
serializing 40.20 バイト配列のpackとunpack
server-after-make-frame-hook 30.1 フレームの作成
session file 42.18 セッションマネージャー
session manager 42.18 セッションマネージャー
set 12.8 変数の値のセット
set, defcustom keyword 15.3 カスタマイゼーション変数の定義
set-advertised-calling-convention 13.13 関数の陳腐化の宣言
set-after, defcustom keyword 15.3 カスタマイゼーション変数の定義
set-auto-coding 34.10.5 デフォルトのコーディングシステム
set-auto-mode 24.2.2 Emacsがメジャーモードを選択する方法
set-binary-mode 20.3 入力関数
set-buffer 28.2 カレントバッファー
set-buffer-auto-saved 27.2 自動保存
set-buffer-major-mode 24.2.2 Emacsがメジャーモードを選択する方法
set-buffer-modified-p 28.5 バッファーの変更
set-buffer-multibyte 34.4 表現の選択
set-case-syntax 4.10 caseテーブル
set-case-syntax-delims 4.10 caseテーブル
set-case-syntax-pair 4.10 caseテーブル
set-case-table 4.10 caseテーブル
set-category-table 36.8 カテゴリー
set-char-table-extra-slot 6.6 文字テーブル
set-char-table-parent 6.6 文字テーブル
set-char-table-range 6.6 文字テーブル
set-charset-priority 34.7 文字セット
set-coding-system-priority 34.10.6 単一の操作にたいするコーディングシステムの指定
set-default 12.11.3 バッファーローカル変数のデフォルト値
set-default-file-modes 26.7 ファイルの名前と属性の変更
set-default-toplevel-value 12.11.3 バッファーローカル変数のデフォルト値
set-display-table-slot 41.23.2 ディスプレイテーブル
set-face-attribute 41.12.3 フェイス属性のための関数
set-face-background 41.12.3 フェイス属性のための関数
set-face-bold 41.12.3 フェイス属性のための関数
set-face-extend 41.12.3 フェイス属性のための関数
set-face-font 41.12.3 フェイス属性のための関数
set-face-foreground 41.12.3 フェイス属性のための関数
set-face-inverse-video 41.12.3 フェイス属性のための関数
set-face-italic 41.12.3 フェイス属性のための関数
set-face-stipple 41.12.3 フェイス属性のための関数
set-face-underline 41.12.3 フェイス属性のための関数
set-file-acl 26.7 ファイルの名前と属性の変更
set-file-extended-attributes 26.7 ファイルの名前と属性の変更
set-file-modes 26.7 ファイルの名前と属性の変更
set-file-selinux-context 26.7 ファイルの名前と属性の変更
set-file-times 26.7 ファイルの名前と属性の変更
set-fontset-font 41.12.11 フォントセット
set-frame-configuration 30.13 フレーム構成
set-frame-font 30.3.2 フレームのフォント
set-frame-height 30.3.4 フレームのサイズ
set-frame-parameter 30.4.1 フレームパラメーターへのアクセス
set-frame-position 30.3.3 フレームの位置
set-frame-selected-window 29.3 ウィンドウの選択
set-frame-size 30.3.4 フレームのサイズ
set-frame-width 30.3.4 フレームのサイズ
set-frame-window-state-change 29.28 ウィンドウのスクロールと変更のためのフック
set-fringe-bitmap-face 41.13.5 フリンジビットマップのカスタマイズ
set-input-method 34.11 入力メソッド
set-input-mode 42.13.1 入力のモード
set-keyboard-coding-system 34.10.8 端末I/Oのエンコーディング
set-keymap-parent 23.5 継承とキーマップ
set-left-margin 33.12 fillのマージン
set-mark 32.7 マーク
set-marker 32.6 マーカー位置の移動
set-marker-insertion-type 32.5 マーカーの挿入タイプ
set-match-data 35.6.3 マッチデータ全体へのアクセス
set-message-function 41.4.1 エコーエリアへのメッセージの表示
set-message-functions 41.4.1 エコーエリアへのメッセージの表示
set-minibuffer-message 41.4.1 エコーエリアへのメッセージの表示
set-minibuffer-window 21.11 ミニバッファーのウィンドウ
set-mouse-absolute-pixel-position 30.16 マウスの位置
set-mouse-pixel-position 30.16 マウスの位置
set-mouse-position 30.16 マウスの位置
set-multi-message 41.4.1 エコーエリアへのメッセージの表示
set-network-process-option 40.17.2 ネットワークのオプション
set-process-buffer 40.9.1 プロセスのバッファー
set-process-coding-system 40.6 プロセスの情報
set-process-datagram-address 40.16 データグラム
set-process-filter 40.9.2 プロセスのフィルター関数
set-process-plist 40.6 プロセスの情報
set-process-query-on-exit-flag 40.11 exit前の問い合わせ
set-process-sentinel 40.10 センチネル: プロセス状態の変更の検知
set-process-thread 40.9.5 プロセスとスレッド
set-process-window-size 40.9.1 プロセスのバッファー
set-register 33.21 レジスター
set-right-margin 33.12 fillのマージン
set-standard-case-table 4.10 caseテーブル
set-syntax-table 36.3 構文テーブルの関数
set-terminal-coding-system 34.10.8 端末I/Oのエンコーディング
set-terminal-parameter 30.5 端末のパラメーター
set-text-properties 33.19.2 テキストプロパティの変更
set-transient-map 23.9 アクティブなキーマップの制御
set-transient-map-timeout 23.9 アクティブなキーマップの制御
set-visited-file-modtime 28.6 バッファーの変更時刻
set-visited-file-name 28.4 バッファーのファイル名
set-window-buffer 29.11 バッファーとウィンドウ
set-window-combination-limit 29.9 ウィンドウの再結合
set-window-configuration 29.26 ウィンドウの構成
set-window-dedicated-p 29.15 専用のウィンドウ
set-window-display-table 41.23.3 アクティブなディスプレイテーブル
set-window-fringes 41.13.1 フリンジのサイズと位置
set-window-group-start 29.20 ウィンドウの開始位置と終了位置
set-window-group-start-function 29.20 ウィンドウの開始位置と終了位置
set-window-hscroll 29.23 水平スクロール
set-window-margins 41.16.5 マージン内への表示
set-window-next-buffers 29.14 ウィンドウのヒストリー
set-window-parameter 29.27 ウィンドウのパラメーター
set-window-point 29.19 ウィンドウとポイント
set-window-prev-buffers 29.14 ウィンドウのヒストリー
set-window-scroll-bars 41.14 スクロールバー
set-window-start 29.20 ウィンドウの開始位置と終了位置
set-window-vscroll 29.22 割り合いによる垂直スクロール
set-xwidget-buffer 41.19 埋め込みネイティブウィジェット
set-xwidget-plist 41.19 埋め込みネイティブウィジェット
set-xwidget-query-on-exit-flag 41.19 埋め込みネイティブウィジェット
setcar 5.6.1 setcarによるリスト要素の変更
setcdr 5.6.2 リストのCDRの変更
setenv 42.3 オペレーティングシステムの環境
setf 12.17.1 setfマクロ
setopt 12.8 変数の値のセット
setplist 9.4.1 シンボルのプロパティへのアクセス
setq 12.8 変数の値のセット
setq-connection-local 12.14.2 接続ローカル変数の適用
setq-default 12.11.3 バッファーローカル変数のデフォルト値
setq-local 12.11.2 バッファーローカルなバインディングの作成と削除
sets 5.7 集合としてのリストの使用
setting modes of files 26.7 ファイルの名前と属性の変更
setting-constant error 12.2 変更不可な変数
set_function_finalizer E.8.2 モジュール関数の記述
set_user_finalizer E.8.3 Lisp・モジュール間の値変換
set_user_ptr E.8.3 Lisp・モジュール間の値変換
severity level 41.5.1 警告の基礎
sexp 10.1 評価の概要
sexp motion 31.2.6 釣り合いのとれたカッコを越えた移動
SHA hash 33.26 チェックサムとハッシュ
SHA hash 33.28 GnuTLS暗号化
sha1 33.26 チェックサムとハッシュ
shaded, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
shadowed Lisp files 16.3 ライブラリー検索
shadowing of variables 12.3 ローカル変数
shared structure, read syntax 2.6 循環オブジェクトの読み取り構文
shell command arguments 40.2 shell引数
shell-command-history 21.4 ミニバッファーのヒストリー
shell-command-to-string 40.3 同期プロセスの作成
shell-quote-argument 40.2 shell引数
shift-selection, and interactive spec 22.2.1 interactiveの使用
shift-translation 22.8.1 キーシーケンス入力
shortdoc-add-function 25.7 ドキュメントのグループ
shorthands 9.5 ショートハンド
should_quit E.8.4 その他の便利なモジュール用関数
show image 41.17.9 イメージの表示
show-help-function 33.19.4 特殊な意味をもつプロパティ
shr-insert-document 33.30 HTMLとXMLの解析
shrink-window-if-larger-than-buffer 29.5 ウィンドウのリサイズ
shy groups 35.3.1.3 正規表現内のバッククラッシュ構文
sibling window 29.2 ウィンドウとフレーム
side effect 10.1 評価の概要
side windows 29.17 サイドウィンドウ
side, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
side-effect-free property 9.4.2 シンボルの標準的なプロパティ
SIGHUP 42.2.1 Emacsのkill
SIGINT 42.2.1 Emacsのkill
signal 11.7.3.1 エラーをシグナルする方法
signal-process 40.8 プロセスへのシグナルの送信
signal-process-functions 40.8 プロセスへのシグナルの送信
signaling errors 11.7.3.1 エラーをシグナルする方法
signals 40.8 プロセスへのシグナルの送信
SIGTERM 42.2.1 Emacsのkill
SIGTSTP 42.2.2 Emacsのサスペンド
sigusr1 event 22.7.12 その他のシステムイベント
sigusr2 event 22.7.12 その他のシステムイベント
simple package 43.2 単純なパッケージ
sin 3.9 標準的な数学関数
single file package 43.2 単純なパッケージ
single-function hook 24.1 フック
single-key-description 25.5 ヘルプメッセージの文字記述
sit-for 22.10 時間の経過や入力の待機
site-init.el E.1 Emacsのビルド
site-lisp directories 16.3 ライブラリー検索
site-load.el E.1 Emacsのビルド
site-run-file 42.1.2 initファイル
site-start.el 42.1.1 要約: スタートアップ時のアクション順序
size of frame 30.3 フレームのジオメトリー
size of image 41.17.9 イメージの表示
size of text on display 41.10 表示されるテキストのサイズ
size of window 29.4 ウィンドウのサイズ
skip-chars-backward 31.2.7 文字のスキップ
skip-chars-forward 31.2.7 文字のスキップ
skip-syntax-backward 36.5 モーションと構文
skip-syntax-forward 36.5 モーションと構文
skip-taskbar, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
skipping characters 31.2.7 文字のスキップ
skipping characters of certain syntax 36.5 モーションと構文
skipping comments 36.6.5 パースを制御するためのパラメーター
sleep-for 22.10 時間の経過や入力の待機
slice, image 41.17.9 イメージの表示
slot, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
small-temporary-file-directory 26.9.5 一意なファイル名の生成
smallest fixnum 3.1 整数の基礎
SMIE 24.7.1 SMIE: 無邪気なインデントエンジン
SMIE grammar 24.7.1.3 言語の文法の定義
SMIE lexer 24.7.1.4 トークンの定義
smie-bnf->prec2 24.7.1.2 演算子順位文法
smie-close-block 24.7.1.1 SMIEのセットアップと機能
smie-config 24.7.1.9 インデントのカスタマイズ
smie-config-guess 24.7.1.9 インデントのカスタマイズ
smie-config-local 24.7.1.9 インデントのカスタマイズ
smie-config-save 24.7.1.9 インデントのカスタマイズ
smie-config-set-indent 24.7.1.9 インデントのカスタマイズ
smie-config-show-indent 24.7.1.9 インデントのカスタマイズ
smie-down-list 24.7.1.1 SMIEのセットアップと機能
smie-merge-prec2s 24.7.1.2 演算子順位文法
smie-prec2->grammar 24.7.1.2 演算子順位文法
smie-precs->prec2 24.7.1.2 演算子順位文法
smie-rule-bolp 24.7.1.7 インデントルールにたいするヘルパー関数
smie-rule-hanging-p 24.7.1.7 インデントルールにたいするヘルパー関数
smie-rule-next-p 24.7.1.7 インデントルールにたいするヘルパー関数
smie-rule-parent 24.7.1.7 インデントルールにたいするヘルパー関数
smie-rule-parent-p 24.7.1.7 インデントルールにたいするヘルパー関数
smie-rule-prev-p 24.7.1.7 インデントルールにたいするヘルパー関数
smie-rule-separator 24.7.1.7 インデントルールにたいするヘルパー関数
smie-rule-sibling-p 24.7.1.7 インデントルールにたいするヘルパー関数
smie-setup 24.7.1.1 SMIEのセットアップと機能
smooth-curveto 41.17.6 SVGイメージ
smooth-quadratic-bezier-curveto 41.17.6 SVGイメージ
snap-width, a frame parameter 30.4.3.7 マウスドラッグのパラメーター
Snarf-documentation 25.2 ドキュメント文字列へのアクセス
sort 6.1 シーケンス
sort-columns 33.15 テキストのソート
sort-fields 33.15 テキストのソート
sort-fold-case 33.15 テキストのソート
sort-lines 33.15 テキストのソート
sort-numeric-base 33.15 テキストのソート
sort-numeric-fields 33.15 テキストのソート
sort-pages 33.15 テキストのソート
sort-paragraphs 33.15 テキストのソート
sort-regexp-fields 33.15 テキストのソート
sort-subr 33.15 テキストのソート
sorting lists 6.1 シーケンス
sorting sequences 6.1 シーケンス
sorting text 33.15 テキストのソート
sorting vectors 6.1 シーケンス
sound 42.15 サウンドの出力
source breakpoints 19.2.6.3 ソースブレークポイント
space (ASCII character) 2.4.3.1 基本的な文字構文
space display spec, and bidirectional text 41.27 双方向テキストの表示
spaces, pixel specification 41.16.3 スペースにたいするピクセル指定
spaces, specified height or width 41.16.2 スペースの指定
sparse keymap 23.3 キーマップのフォーマット
SPC in minibuffer 21.2 ミニバッファーでのテキスト文字列の読み取り
special events 22.9 スペシャルイベント
special form descriptions 1.3.7.1 関数の説明例
special forms 10.2.7 スペシャルフォーム
special forms for control structures 11 制御構造
special modes 24.2.1 メジャーモードの慣習
special read syntax 2.2 特別な読み取り構文
special variables 12.10.4 レキシカルバインディングの使用
special-event-map 23.9 アクティブなキーマップの制御
special-form-p 10.2.7 スペシャルフォーム
special-mode 24.2.5 基本的なメジャーモード
special-mode-map Appendix G 標準的なキーマップ
special-variable-p 12.10.4 レキシカルバインディングの使用
Specified time is not representable 42.5 時刻
specify coding system 34.10.6 単一の操作にたいするコーディングシステムの指定
specify color 30.23 カラー名
speedups D.4 コンパイル済みコードを高速化ためのヒント
splicing (with backquote) 10.4 バッククォート
split-height-threshold 29.13.4 バッファー表示の追加オプション
split-root-window-below 29.7 ウィンドウの分割
split-root-window-right 29.7 ウィンドウの分割
split-string 4.3 文字列の作成
split-string-and-unquote 40.2 shell引数
split-string-default-separators 4.3 文字列の作成
split-string-shell-command 40.2 shell引数
split-width-threshold 29.13.4 バッファー表示の追加オプション
split-window 29.7 ウィンドウの分割
split-window, a window parameter 29.27 ウィンドウのパラメーター
split-window-below 29.7 ウィンドウの分割
split-window-keep-point 29.7 ウィンドウの分割
split-window-preferred-function 29.13.4 バッファー表示の追加オプション
split-window-right 29.7 ウィンドウの分割
split-window-sensibly 29.13.4 バッファー表示の追加オプション
splitting windows 29.7 ウィンドウの分割
sqlite-available-p 33.29 データベース
sqlite-close 33.29 データベース
sqlite-columns 33.29 データベース
sqlite-commit 33.29 データベース
sqlite-execute 33.29 データベース
sqlite-finalize 33.29 データベース
sqlite-load-extension 33.29 データベース
sqlite-mode-open-file 33.29 データベース
sqlite-more-p 33.29 データベース
sqlite-next 33.29 データベース
sqlite-open 33.29 データベース
sqlite-pragma 33.29 データベース
sqlite-rollback 33.29 データベース
sqlite-select 33.29 データベース
sqlite-transaction 33.29 データベース
sqlite-version 33.29 データベース
sqlitep 33.29 データベース
sqrt 3.9 標準的な数学関数
stable sort 6.1 シーケンス
stack allocated Lisp objects E.4 スタックに割り当てられたオブジェクト
stack frame 19.1.8 バックトレース
stack overflow in regexp 35.3.5 正規表現にまつわるトラブル
standalone-parent 24.7.2 パーサーベースのインデント
standard abbrev tables 38.5 標準abbrevテーブル
standard colors for character terminals 30.4.3.10 フォントとカラーのパラメーター
standard error process 40.4 非同期プロセスの作成
standard errors Appendix F 標準的なエラー
standard hooks Appendix H 標準的なフック
standard regexps used in editing 35.8 編集で使用される標準的な正規表現
standard syntax table 36.1 構文テーブルの概念
standard-case-table 4.10 caseテーブル
standard-category-table 36.8 カテゴリー
standard-display-table 41.23.3 アクティブなディスプレイテーブル
standard-input 20.3 入力関数
standard-output 20.6 出力に影響する変数
standard-syntax-table 36.1 構文テーブルの概念
standard-translation-table-for-decode 34.9 文字の変換
standard-translation-table-for-encode 34.9 文字の変換
standards of coding style Appendix D ヒントと規約
start-file-process 40.4 非同期プロセスの作成
start-file-process-shell-command 40.4 非同期プロセスの作成
start-process 40.4 非同期プロセスの作成
start-process, command-line arguments from minibuffer 40.2 shell引数
start-process-shell-command 40.4 非同期プロセスの作成
STARTTLS network connections 40.14 ネットワーク接続
startup of Emacs 42.1.1 要約: スタートアップ時のアクション順序
startup screen 42.1.1 要約: スタートアップ時のアクション順序
startup-redirect-eln-cache 18.1 ネイティブコンパイル関数
startup.el 42.1.1 要約: スタートアップ時のアクション順序
statement object 33.29 データベース
staticpro, protection from GC E.7 Emacsプリミティブの記述
stderr stream, use for debugging 20.4 出力ストリーム
sticky text properties 33.19.6 テキストプロパティの粘着性
sticky, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
stop points 19.2.1 Edebugの使用
stop-process 40.8 プロセスへのシグナルの送信
stopbits, in serial connections 40.19 シリアルポートとの対話
stopping an infinite loop 19.1.3 無限ループのデバッグ
stopping on events 19.2.6.2 グローバルなブレーク条件
storage of vector-like Lisp objects E.3 ガーベージコレクション
store-match-data 35.6.3 マッチデータ全体へのアクセス
store-substring 4.4 文字列の変更
stream (for printing) 20.4 出力ストリーム
stream (for reading) 20.2 入力ストリーム
strike-through text 41.12.1 フェイスの属性
string 4.3 文字列の作成
string creation 4.3 文字列の作成
string equality 4.5 文字および文字列の比較
string in keymap 23.10 キーの照合
string input stream 20.2 入力ストリーム
string length 6.1 シーケンス
string modification 4.4 文字列の変更
string predicates 4.2 文字列のための述語
string reverse 6.1 シーケンス
string search 35.1 文字列の検索
string to number 4.6 文字および文字列の変換
string to object 20.3 入力関数
string to vector 6.1 シーケンス
string, number of bytes 34.1 テキストの表現方法
string, writing a doc string 25.1 ドキュメントの基礎
string-as-multibyte 34.4 表現の選択
string-as-unibyte 34.4 表現の選択
string-bytes 34.1 テキストの表現方法
string-chars-consed E.5 メモリー使用量
string-chop-newline 4.3 文字列の作成
string-clean-whitespace 4.3 文字列の作成
string-collate-equalp 4.5 文字および文字列の比較
string-collate-lessp 4.5 文字および文字列の比較
string-distance 4.5 文字および文字列の比較
string-end in rx 35.3.3.1 rxによるregexpの構築
string-equal 4.5 文字および文字列の比較
string-equal-ignore-case 4.5 文字および文字列の比較
string-fill 4.3 文字列の作成
string-glyph-split 41.10 表示されるテキストのサイズ
string-greaterp 4.5 文字および文字列の比較
string-lessp 4.5 文字および文字列の比較
string-limit 4.3 文字列の作成
string-lines 4.3 文字列の作成
string-match 35.4 正規表現の検索
string-match-p 35.4 正規表現の検索
string-or-null-p 4.2 文字列のための述語
string-pad 4.3 文字列の作成
string-pixel-width 41.10 表示されるテキストのサイズ
string-prefix-p 4.5 文字および文字列の比較
string-replace 35.7 検索と置換
string-search 4.5 文字および文字列の比較
string-start in rx 35.3.3.1 rxによるregexpの構築
string-suffix-p 4.5 文字および文字列の比較
string-to-char 4.6 文字および文字列の変換
string-to-int 4.6 文字および文字列の変換
string-to-multibyte 34.3 テキスト表現の変換
string-to-number 4.6 文字および文字列の変換
string-to-syntax 36.7 構文テーブルの内部
string-to-unibyte 34.3 テキスト表現の変換
string-trim 4.3 文字列の作成
string-trim-left 4.3 文字列の作成
string-trim-right 4.3 文字列の作成
string-version-lessp 4.5 文字および文字列の比較
string-width 41.10 表示されるテキストのサイズ
string< 4.5 文字および文字列の比較
string= 4.5 文字および文字列の比較
stringp 4.2 文字列のための述語
strings 4 文字列と文字
strings with keyboard events 22.7.17 文字列内へのキーボードイベントの配置
strings, formatting them 4.7 文字列のフォーマット
strings-consed E.5 メモリー使用量
structural matching 11.4.3 バッククォートスタイルパターン
sub-sequence 6.1 シーケンス
submatch in rx 35.3.3.1 rxによるregexpの構築
submatch-n in rx 35.3.3.1 rxによるregexpの構築
submenu 23.18.2 メニューとマウス
subprocess 40 プロセス
subr 13.1 関数とは?
subr-arity 13.1 関数とは?
subrp 13.1 関数とは?
subst-char-in-region 33.20 文字コードの置き換え
subst-char-in-string 33.20 文字コードの置き換え
substitute characters 33.20 文字コードの置き換え
substitute-command-keys 25.3 ドキュメント内でのキーバインディングの置き換え
substitute-in-file-name 26.9.4 ファイル名を展開する関数
substitute-key-definition 23.12 キーバインディングの変更
substitute-key-definition 23.13 低レベルなキーバインディング
substitute-quotes 25.3 ドキュメント内でのキーバインディングの置き換え
substituting keys in documentation 25.3 ドキュメント内でのキーバインディングの置き換え
substring 4.3 文字列の作成
substring-no-properties 4.3 文字列の作成
subtype of char-table 6.6 文字テーブル
success handler 11.7.3.3 エラーを処理するコードの記述
suggestions 1.1 注意事項
super characters 2.4.3.5 その他の文字修飾ビット
support for touchscreens 22.7.9 タッチスクリーンのイベント
suppress-keymap 23.12 キーバインディングの変更
surrogate minibuffer frame 30.9 ミニバッファーとフレーム
suspend (cf. no-redraw-on-reenter) 41.1 スクリーンのリフレッシュ
suspend evaluation 22.13 再帰編集
suspend major mode temporarily 24.2 メジャーモード
suspend-emacs 42.2.2 Emacsのサスペンド
suspend-frame 42.2.2 Emacsのサスペンド
suspend-hook 42.2.2 Emacsのサスペンド
suspend-resume-hook 42.2.2 Emacsのサスペンド
suspend-tty 42.2.2 Emacsのサスペンド
suspend-tty-functions 42.2.2 Emacsのサスペンド
suspending Emacs 42.2.2 Emacsのサスペンド
suspicious text 33.27 不審なテキスト
suspicious text strings 33.27 不審なテキスト
SVG images 41.17.6 SVGイメージ
SVG object 41.17.6 SVGイメージ
svg path commands 41.17.6 SVGイメージ
svg-circle 41.17.6 SVGイメージ
svg-clip-path 41.17.6 SVGイメージ
svg-create 41.17.6 SVGイメージ
svg-ellipse 41.17.6 SVGイメージ
svg-embed 41.17.6 SVGイメージ
svg-embed-base-uri-image 41.17.6 SVGイメージ
svg-gradient 41.17.6 SVGイメージ
svg-image 41.17.6 SVGイメージ
svg-line 41.17.6 SVGイメージ
svg-node 41.17.6 SVGイメージ
svg-path 41.17.6 SVGイメージ
svg-polygon 41.17.6 SVGイメージ
svg-polyline 41.17.6 SVGイメージ
svg-rectangle 41.17.6 SVGイメージ
svg-remove 41.17.6 SVGイメージ
svg-text 41.17.6 SVGイメージ
swap text between buffers 28.12 2つのバッファー間でのテキストの交換
switch-to-buffer 29.12 ウィンドウ内のバッファーへの切り替え
switch-to-buffer-in-dedicated-window 29.12 ウィンドウ内のバッファーへの切り替え
switch-to-buffer-obey-display-actions 29.12 ウィンドウ内のバッファーへの切り替え
switch-to-buffer-other-frame 29.12 ウィンドウ内のバッファーへの切り替え
switch-to-buffer-other-window 29.12 ウィンドウ内のバッファーへの切り替え
switch-to-buffer-preserve-window-point 29.12 ウィンドウ内のバッファーへの切り替え
switch-to-next-buffer 29.14 ウィンドウのヒストリー
switch-to-prev-buffer 29.14 ウィンドウのヒストリー
switch-to-prev-buffer-skip 29.14 ウィンドウのヒストリー
switch-to-prev-buffer-skip-regexp 29.14 ウィンドウのヒストリー
switches on command line 42.1.4 コマンドライン引数
switching to a buffer 29.12 ウィンドウ内のバッファーへの切り替え
sxhash-eq 8.3 ハッシュの比較の定義
sxhash-eql 8.3 ハッシュの比較の定義
sxhash-equal 8.3 ハッシュの比較の定義
symbol 9 シンボル
symbol components 9.1 シンボルの構成要素
symbol equality 9.3 シンボルの作成とintern
symbol evaluation 10.2.2 シンボルのフォーム
symbol forms 10.2.2 シンボルのフォーム
symbol function indirection 10.2.4 シンボル関数インダイレクション
symbol in keymap 23.10 キーの照合
symbol name hashing 9.3 シンボルの作成とintern
symbol property 9.4 シンボルのプロパティ
symbol that evaluates to itself 12.2 変更不可な変数
symbol with constant value 12.2 変更不可な変数
symbol with position 9.6 位置をもつシンボル
symbol, where defined 16.8 どのファイルで特定のシンボルが定義されているか
symbol-end in rx 35.3.3.1 rxによるregexpの構築
symbol-file 16.8 どのファイルで特定のシンボルが定義されているか
symbol-function 13.9 関数セルの内容へのアクセス
symbol-name 9.3 シンボルの作成とintern
symbol-plist 9.4.1 シンボルのプロパティへのアクセス
symbol-start in rx 35.3.3.1 rxによるregexpの構築
symbol-value 12.7 変数の値へのアクセス
symbol-with-pos-p 9.6 位置をもつシンボル
symbol-with-pos-pos 9.6 位置をもつシンボル
symbolic links 26.6.2 ファイル種別の区別
symbolic links 26.6.2 ファイル種別の区別
symbolic shorthands 9.5 ショートハンド
symbolp 9 シンボル
symbols-consed E.5 メモリー使用量
symbols-with-pos-enabled 9.6 位置をもつシンボル
symmetric cipher 33.28 GnuTLS暗号化
synchronized multisession variables 12.18 マルチセッション変数
synchronous subprocess 40.3 同期プロセスの作成
syntactic font lock 24.6.8 構文的なFont Lock
syntax class 36.2 構文記述子
syntax class table 36.2.1 構文クラスのテーブル
syntax code 36.7 構文テーブルの内部
syntax descriptor 36.2 構文記述子
syntax entry, setting 36.3 構文テーブルの関数
syntax error (Edebug) 19.2.15.3 仕様でのバックトレース
syntax flags 36.2.2 構文フラグ
syntax for characters 2.4.3.1 基本的な文字構文
syntax highlighting and coloring 24.6 Font Lockモード
syntax in rx 35.3.3.1 rxによるregexpの構築
syntax of regular expressions 35.3.1 正規表現の構文
syntax table 36 構文テーブル
syntax table example 24.2.9 メジャーモードの例
syntax table internals 36.7 構文テーブルの内部
syntax tables (accessing elements of) 36.7 構文テーブルの内部
syntax tables in modes 24.2.1 メジャーモードの慣習
syntax tree nodes, by field name 37.3 ノードの取得
syntax tree nodes, by kinship 37.3 ノードの取得
syntax tree nodes, by position 37.3 ノードの取得
syntax tree nodes, retrieving from other nodes 37.3 ノードの取得
syntax tree, concrete 37.1 Tree-sitter Language Grammar
syntax tree, from parsing program source 37 プログラムソースの解析
syntax tree, retrieving nodes 37.3 ノードの取得
syntax trees, node information 37.4 ノード情報へのアクセス
syntax-after 36.7 構文テーブルの内部
syntax-class 36.7 構文テーブルの内部
syntax-class-to-char 36.7 構文テーブルの内部
syntax-ppss 36.6.2 ある位置のパース状態を調べる
syntax-ppss-context 36.6.3 パーサー状態
syntax-ppss-flush-cache 36.6.2 ある位置のパース状態を調べる
syntax-ppss-toplevel-pos 36.6.3 パーサー状態
syntax-propertize-extend-region-functions 36.4 構文プロパティ
syntax-propertize-function 36.4 構文プロパティ
syntax-table 36.3 構文テーブルの関数
syntax-table (text property) 36.4 構文プロパティ
syntax-table-p 36.1 構文テーブルの概念
system abbrev 38 abbrevとabbrev展開
system processes 40.12 別のプロセスへのアクセス
system tooltips 41.26 ツールチップ
system type and name 42.3 オペレーティングシステムの環境
system-configuration 42.3 オペレーティングシステムの環境
system-groups 42.4 ユーザーの識別
system-key-alist 42.16 X11キーシンボルの処理
system-messages-locale 34.12 locale
system-name 42.3 オペレーティングシステムの環境
system-time-locale 34.12 locale
system-type 42.3 オペレーティングシステムの環境
system-users 42.4 ユーザーの識別

T
t 1.3.2 nilt
t input stream 20.2 入力ストリーム
t output stream 20.4 出力ストリーム
tab (ASCII character) 2.4.3.1 基本的な文字構文
tab bar 30.3.1 フレームのレイアウト
tab deletion 33.6 テキストの削除
TAB in minibuffer 21.2 ミニバッファーでのテキスト文字列の読み取り
tab-always-indent 33.17.2 メジャーモードが制御するインデント
tab-bar mouse events 22.7.4 クリックイベント
tab-bar, prefix key 22.8.1 キーシーケンス入力
tab-bar-lines, a frame parameter 30.4.3.4 レイアウトのパラメーター
tab-bar-map Appendix G 標準的なキーマップ
tab-first-completion 33.17.2 メジャーモードが制御するインデント
tab-line, prefix key 22.8.1 キーシーケンス入力
tab-line-format, a window parameter 29.27 ウィンドウのパラメーター
tab-prefix-map 23.6 プレフィクスキー
tab-stop-list 33.17.5 調整可能なタブストップ
tab-to-tab-stop 33.17.5 調整可能なタブストップ
tab-width 41.23.1 通常の表示の慣習
tabs stops for indentation 33.17.5 調整可能なタブストップ
Tabulated List mode 24.2.7 Tabulated Listモード
tabulated-list-clear-all-tags 24.2.7 Tabulated Listモード
tabulated-list-delete-entry 24.2.7 Tabulated Listモード
tabulated-list-entries 24.2.7 Tabulated Listモード
tabulated-list-format 24.2.7 Tabulated Listモード
tabulated-list-get-entry 24.2.7 Tabulated Listモード
tabulated-list-get-id 24.2.7 Tabulated Listモード
tabulated-list-gui-sort-indicator-asc 24.2.7 Tabulated Listモード
tabulated-list-gui-sort-indicator-desc 24.2.7 Tabulated Listモード
tabulated-list-header-overlay-p 24.2.7 Tabulated Listモード
tabulated-list-init-header 24.2.7 Tabulated Listモード
tabulated-list-mode 24.2.7 Tabulated Listモード
tabulated-list-padding 24.2.7 Tabulated Listモード
tabulated-list-print 24.2.7 Tabulated Listモード
tabulated-list-printer 24.2.7 Tabulated Listモード
tabulated-list-put-tag 24.2.7 Tabulated Listモード
tabulated-list-revert-hook 24.2.7 Tabulated Listモード
tabulated-list-set-col 24.2.7 Tabulated Listモード
tabulated-list-sort-key 24.2.7 Tabulated Listモード
tabulated-list-tty-sort-indicator-asc 24.2.7 Tabulated Listモード
tabulated-list-tty-sort-indicator-desc 24.2.7 Tabulated Listモード
tabulated-list-use-header-line 24.2.7 Tabulated Listモード
tag on run time stack 11.7.1 明示的な非ローカル脱出: catchthrow
tag, customization keyword 15.1 一般的なキーワードアイテム
take 5.3 リスト要素へのアクセス
tan 3.9 標準的な数学関数
TCP 40.14 ネットワーク接続
temacs E.1 Emacsのビルド
TEMP environment variable 26.9.5 一意なファイル名の生成
temp-buffer-max-height 41.8 一時的な表示
temp-buffer-max-width 41.8 一時的な表示
temp-buffer-resize-mode 41.8 一時的な表示
temp-buffer-setup-hook 41.8 一時的な表示
temp-buffer-show-function 41.8 一時的な表示
temp-buffer-show-hook 41.8 一時的な表示
temp-buffer-window-setup-hook 41.8 一時的な表示
temp-buffer-window-show-hook 41.8 一時的な表示
temporary buffer display 41.8 一時的な表示
temporary display 41.8 一時的な表示
temporary file on a remote host 26.9.5 一意なファイル名の生成
temporary files 26.9.5 一意なファイル名の生成
temporary-file-directory 26.9.5 一意なファイル名の生成
temporary-file-directory 26.9.5 一意なファイル名の生成
TERM environment variable 42.1.3 端末固有の初期化
term-file-aliases 42.1.3 端末固有の初期化
term-file-prefix 42.1.3 端末固有の初期化
Termcap 42.1.3 端末固有の初期化
terminal 30 フレーム
terminal input 42.13 端末の入力
terminal input modes 42.13.1 入力のモード
terminal output 42.14 端末の出力
terminal parameters 30.5 端末のパラメーター
terminal screen 29.1 Emacsウィンドウの基本概念
terminal type 2.5.5 端末型
terminal-coding-system 34.10.8 端末I/Oのエンコーディング
terminal-list 30.2 複数の端末
terminal-live-p 30 フレーム
terminal-local variables 30.2 複数の端末
terminal-name 30.2 複数の端末
terminal-parameter 30.5 端末のパラメーター
terminal-parameters 30.5 端末のパラメーター
terminal-specific initialization 42.1.3 端末固有の初期化
terminology, for tree-sitter functions 37.3 ノードの取得
termscript file 42.14 端末の出力
terpri 20.5 出力関数
test-completion 21.6.1 基本的な補完関数
testcover-mark-all 19.4 カバレッジテスト
testcover-next-mark 19.4 カバレッジテスト
testcover-start 19.4 カバレッジテスト
testing types 2.7 型のための述語
text 33 テキスト
text area 30.3.1 フレームのレイアウト
text area of a window 29.1 Emacsウィンドウの基本概念
text comparison 4.5 文字および文字列の比較
text conversion of coding system 34.10.3 Lispでのコーディングシステム
text deletion 33.6 テキストの削除
text height of a frame 30.3.4 フレームのサイズ
text insertion 33.4 テキストの挿入
text near point 33.1 ポイント近傍のテキストを調べる
text parsing 36 構文テーブル
text properties 33.19 テキストのプロパティ
text properties in files 26.13 ファイルのフォーマット変換
text properties in the mode line 24.4.6 モードラインでのプロパティ
text properties, changing 33.19.2 テキストプロパティの変更
text properties, examining 33.19.1 テキストプロパティを調べる
text properties, read syntax 2.4.8.4 文字列内のテキストプロパティ
text properties, searching 33.19.3 テキストプロパティの検索関数
text representation 34.1 テキストの表現方法
text size of a frame 30.3.4 フレームのサイズ
text terminal 30 フレーム
text width of a frame 30.3.4 フレームのサイズ
text-char-description 25.5 ヘルプメッセージの文字記述
text-mode 24.2.5 基本的なメジャーモード
text-mode-abbrev-table 38.5 標準abbrevテーブル
text-properties-at 33.19.1 テキストプロパティを調べる
text-property-any 33.19.3 テキストプロパティの検索関数
text-property-default-nonsticky 33.19.6 テキストプロパティの粘着性
text-property-not-all 33.19.3 テキストプロパティの検索関数
text-property-search-backward 33.19.3 テキストプロパティの検索関数
text-property-search-forward 33.19.3 テキストプロパティの検索関数
text-quoting-style 25.4 テキストのクォートスタイル
text-quoting-style 25.4 テキストのクォートスタイル
text-terminal focus notification 30.10 入力のフォーカス
textsec-check 33.27 不審なテキスト
textsec-suspicious (face) 33.27 不審なテキスト
textsec-suspicious-p 33.27 不審なテキスト
textual order 11 制御構造
textual scrolling 29.21 テキスト的なスクロール
theme-face (face symbol property) 41.12.2 フェイスの定義
thing-at-point 33.2 バッファーのコンテンツを調べる
thing-at-point-provider-alist 33.2 バッファーのコンテンツを調べる
this-command 22.5 コマンドループからの情報
this-command-keys 22.5 コマンドループからの情報
this-command-keys-shift-translated 22.8.1 キーシーケンス入力
this-command-keys-vector 22.5 コマンドループからの情報
this-original-command 22.5 コマンドループからの情報
thread backtrace 39.4 スレッドリスト
thread list 39.4 スレッドリスト
thread--blocker 39.1 基本的なスレッド関数
thread-join 39.1 基本的なスレッド関数
thread-last-error 39.1 基本的なスレッド関数
thread-list-refresh-seconds 39.4 スレッドリスト
thread-live-p 39.1 基本的なスレッド関数
thread-name 39.1 基本的なスレッド関数
thread-signal 39.1 基本的なスレッド関数
thread-yield 39.1 基本的なスレッド関数
threadp 39.1 基本的なスレッド関数
threads 39 スレッド
three-step-help 25.6 ヘルプ関数
throw 11.7.1 明示的な非ローカル脱出: catchthrow
throw example 22.13 再帰編集
thunk 10.6 遅延されたLazy評価
thunk-delay 10.6 遅延されたLazy評価
thunk-force 10.6 遅延されたLazy評価
thunk-let 10.6 遅延されたLazy評価
thunk-let* 10.6 遅延されたLazy評価
tiled windows 29.1 Emacsウィンドウの基本概念
time calculations 42.10 時間の計算
time conversion 42.7 時刻の変換
time formatting 42.8 時刻のパースとフォーマット
time of day 42.5 時刻
time parsing 42.8 時刻のパースとフォーマット
time value 42.5 時刻
time zone rule 42.6 タイムゾーンのルール
time zone rules 42.6 タイムゾーンのルール
time zone, current 42.6 タイムゾーンのルール
time-add 42.10 時間の計算
time-convert 42.7 時刻の変換
time-equal-p 42.10 時間の計算
time-less-p 42.10 時間の計算
time-subtract 42.10 時間の計算
time-to-day-in-year 42.10 時間の計算
time-to-days 42.10 時間の計算
timer-max-repeats 42.11 遅延実行のためのタイマー
timerp 42.11 遅延実行のためのタイマー
timers 42.11 遅延実行のためのタイマー
timestamp of a mouse event 22.7.15 マウスイベントへのアクセス
timestamp, Lisp 42.5 時刻
timing programs 19.5 プロファイリング
tips for writing Lisp Appendix D ヒントと規約
title bar 30.3.1 フレームのレイアウト
title, a frame parameter 30.4.3.1 基本パラメーター
TLS network connections 40.14 ネットワーク接続
TMP environment variable 26.9.5 一意なファイル名の生成
TMPDIR environment variable 26.9.5 一意なファイル名の生成
toggle-enable-multibyte-characters 34.2 マルチバイト文字の無効化
tool bar 23.18.6 ツールバー
tool-bar mouse events 22.7.4 クリックイベント
tool-bar-add-item 23.18.6 ツールバー
tool-bar-add-item-from-menu 23.18.6 ツールバー
tool-bar-border 23.18.6 ツールバー
tool-bar-button-margin 23.18.6 ツールバー
tool-bar-button-relief 23.18.6 ツールバー
tool-bar-lines, a frame parameter 30.4.3.4 レイアウトのパラメーター
tool-bar-local-item-from-menu 23.18.6 ツールバー
tool-bar-map 23.18.6 ツールバー
tool-bar-position, a frame parameter 30.4.3.4 レイアウトのパラメーター
tooltip face 41.26 ツールチップ
tooltip for help strings 33.19.4 特殊な意味をもつプロパティ
tooltip frames 41.26 ツールチップ
tooltip window 29.1 Emacsウィンドウの基本概念
tooltip-event-buffer 41.26 ツールチップ
tooltip-frame-parameters 41.26 ツールチップ
tooltip-functions 41.26 ツールチップ
tooltip-help-tips 41.26 ツールチップ
tooltip-mode 41.26 ツールチップ
tooltips 41.26 ツールチップ
top and bottom window decorations 29.1 Emacsウィンドウの基本概念
top frame 30.12 フレームのraise、lower、re-stack
top position ratio 30.4.3.2 位置のパラメーター
top, a frame parameter 30.4.3.2 位置のパラメーター
top-level 22.13 再帰編集
top-level default value 12.11.3 バッファーローカル変数のデフォルト値
top-level form 16 ロード
top-level frame 30 フレーム
top-visible, a frame parameter 30.4.3.7 マウスドラッグのパラメーター
total height of a window 29.4 ウィンドウのサイズ
total pixel height of a window 29.4 ウィンドウのサイズ
total pixel width of a window 29.4 ウィンドウのサイズ
total width of a window 29.4 ウィンドウのサイズ
touch point, in touchscreen events 22.7.9 タッチスクリーンのイベント
touch-end event 22.7.12 その他のシステムイベント
touchscreen events 22.7.9 タッチスクリーンのイベント
touchscreen-begin event 22.7.9 タッチスクリーンのイベント
touchscreen-end event 22.7.9 タッチスクリーンのイベント
touchscreen-update event 22.7.9 タッチスクリーンのイベント
tq-close 40.13 トランザクションキュー
tq-create 40.13 トランザクションキュー
tq-enqueue 40.13 トランザクションキュー
trace buffer 19.2.12 トレースバッファー
tracing Lisp programs 19 Lispプログラムのデバッグ
track-mouse 30.15 マウスの追跡
tracking frame size changes 30.3.4 フレームのサイズ
trailing blanks in file names 26.6 ファイルの情報
trampolines, in native compilation 18.2 ネイティブコンパイル関数
transaction queue 40.13 トランザクションキュー
transcendental functions 3.9 標準的な数学関数
transient keymap 23.9 アクティブなキーマップの制御
transient-mark-mode 32.7 マーク
translate-region 33.20 文字コードの置き換え
translate-upper-case-key-bindings 22.8.1 キーシーケンス入力
translating input events 22.8.3 入力イベントの変更と変換
translation keymap 23.15 イベントシーケンス変換のためのキーマップ
translation tables 34.9 文字の変換
translation-table-for-input 34.9 文字の変換
transparency, frame 30.4.3.10 フォントとカラーのパラメーター
transparency, frame 30.4.3.10 フォントとカラーのパラメーター
transpose-regions 33.22 テキストの交換
trash 26.7 ファイルの名前と属性の変更
trash 26.11 ディレクトリーの作成・コピー・削除
tray notifications, MS-Windows 42.19 デスクトップ通知
tree-sitter extra node 37.4 ノード情報へのアクセス
tree-sitter fontifications, overview 24.6.10 パーサーベースのFont Lock
tree-sitter host and embedded languages 37.6 複数言語ののパース
tree-sitter missing node 37.4 ノード情報へのアクセス
tree-sitter narrowing 37.2 tree-sitterパーサーの使用
tree-sitter node field name 37.1 Tree-sitter Language Grammar
tree-sitter node that has error 37.4 ノード情報へのアクセス
tree-sitter nodes, comparing 37.4 ノード情報へのアクセス
tree-sitter outdated node 37.4 ノード情報へのアクセス
tree-sitter parse string 37.2 tree-sitterパーサーの使用
tree-sitter parse tree, leaf node 37.3 ノードの取得
tree-sitter parse-tree, update and after-change callback 37.2 tree-sitterパーサーの使用
tree-sitter parser, creating 37.2 tree-sitterパーサーの使用
tree-sitter parser, using 37.2 tree-sitterパーサーの使用
tree-sitter patterns as strings 37.5 tree-sitterノードにたいするパターンマッチング
tree-sitter query pattern syntax 37.5 tree-sitterノードにたいするパターンマッチング
tree-sitter, find node 37.3 ノードの取得
tree-sitter, live parsing node 37.4 ノード情報へのアクセス
treesit-available-p 37 プログラムソースの解析
treesit-beginning-of-defun 31.2.6 釣り合いのとれたカッコを越えた移動
treesit-buffer-root-node 37.3 ノードの取得
treesit-buffer-too-large 37.2 tree-sitterパーサーの使用
treesit-check-indent 24.7.2 パーサーベースのインデント
treesit-defun-at-point 37.7 tree-sitterを用いるメジャーモードの開発
treesit-defun-name 37.7 tree-sitterを用いるメジャーモードの開発
treesit-defun-name-function 37.7 tree-sitterを用いるメジャーモードの開発
treesit-defun-tactic 31.2.6 釣り合いのとれたカッコを越えた移動
treesit-defun-type-regexp 31.2.6 釣り合いのとれたカッコを越えた移動
treesit-end-of-defun 31.2.6 釣り合いのとれたカッコを越えた移動
treesit-explore-mode 37.1 Tree-sitter Language Grammar
treesit-extra-load-path 37.1 Tree-sitter Language Grammar
treesit-filter-child 37.3 ノードの取得
treesit-font-lock-feature-list 24.6.10 パーサーベースのFont Lock
treesit-font-lock-recompute-features 24.6.10 パーサーベースのFont Lock
treesit-font-lock-rules 24.6.10 パーサーベースのFont Lock
treesit-font-lock-settings 24.6.10 パーサーベースのFont Lock
treesit-fontify-with-override 24.6.10 パーサーベースのFont Lock
treesit-indent-function 24.7.2 パーサーベースのインデント
treesit-induce-sparse-tree 37.3 ノードの取得
treesit-inspect-mode 37.1 Tree-sitter Language Grammar
treesit-language-abi-version 37.1 Tree-sitter Language Grammar
treesit-language-at 37.6 複数言語ののパース
treesit-language-at-point-function 37.6 複数言語ののパース
treesit-language-available-p 37.1 Tree-sitter Language Grammar
treesit-library-abi-version 37.1 Tree-sitter Language Grammar
treesit-load-language-error 37.1 Tree-sitter Language Grammar
treesit-load-name-override-list 37.1 Tree-sitter Language Grammar
treesit-major-mode-setup 37.7 tree-sitterを用いるメジャーモードの開発
treesit-max-buffer-size 37.2 tree-sitterパーサーの使用
treesit-node-at 37.3 ノードの取得
treesit-node-buffer 37.4 ノード情報へのアクセス
treesit-node-check 37.4 ノード情報へのアクセス
treesit-node-child 37.3 ノードの取得
treesit-node-child-by-field-name 37.3 ノードの取得
treesit-node-child-count 37.4 ノード情報へのアクセス
treesit-node-children 37.3 ノードの取得
treesit-node-descendant-for-range 37.3 ノードの取得
treesit-node-end 37.4 ノード情報へのアクセス
treesit-node-eq 37.4 ノード情報へのアクセス
treesit-node-field-name 37.4 ノード情報へのアクセス
treesit-node-field-name-for-child 37.4 ノード情報へのアクセス
treesit-node-first-child-for-pos 37.3 ノードの取得
treesit-node-index 37.4 ノード情報へのアクセス
treesit-node-language 37.4 ノード情報へのアクセス
treesit-node-next-sibling 37.3 ノードの取得
treesit-node-on 37.3 ノードの取得
treesit-node-outdated 37.3 ノードの取得
treesit-node-p 37.4 ノード情報へのアクセス
treesit-node-parent 37.3 ノードの取得
treesit-node-parser 37.4 ノード情報へのアクセス
treesit-node-prev-sibling 37.3 ノードの取得
treesit-node-start 37.4 ノード情報へのアクセス
treesit-node-text 37.4 ノード情報へのアクセス
treesit-node-top-level 37.3 ノードの取得
treesit-node-type 37.4 ノード情報へのアクセス
treesit-parent-until 37.3 ノードの取得
treesit-parent-while 37.3 ノードの取得
treesit-parse-string 37.2 tree-sitterパーサーの使用
treesit-parser-add-notifier 37.2 tree-sitterパーサーの使用
treesit-parser-buffer 37.2 tree-sitterパーサーの使用
treesit-parser-create 37.2 tree-sitterパーサーの使用
treesit-parser-delete 37.2 tree-sitterパーサーの使用
treesit-parser-included-ranges 37.6 複数言語ののパース
treesit-parser-language 37.2 tree-sitterパーサーの使用
treesit-parser-list 37.2 tree-sitterパーサーの使用
treesit-parser-notifiers 37.2 tree-sitterパーサーの使用
treesit-parser-p 37.2 tree-sitterパーサーの使用
treesit-parser-remove-notifier 37.2 tree-sitterパーサーの使用
treesit-parser-root-node 37.3 ノードの取得
treesit-parser-set-included-ranges 37.6 複数言語ののパース
treesit-pattern-expand 37.5 tree-sitterノードにたいするパターンマッチング
treesit-query-capture 37.5 tree-sitterノードにたいするパターンマッチング
treesit-query-compile 37.5 tree-sitterノードにたいするパターンマッチング
treesit-query-error 37.5 tree-sitterノードにたいするパターンマッチング
treesit-query-expand 37.5 tree-sitterノードにたいするパターンマッチング
treesit-query-language 37.5 tree-sitterノードにたいするパターンマッチング
treesit-query-range 37.6 複数言語ののパース
treesit-query-string 37.5 tree-sitterノードにたいするパターンマッチング
treesit-query-validate 37.5 tree-sitterノードにたいするパターンマッチング
treesit-range-invalid 37.6 複数言語ののパース
treesit-range-rules 37.6 複数言語ののパース
treesit-range-settings 37.6 複数言語ののパース
treesit-ready-p 37.7 tree-sitterを用いるメジャーモードの開発
treesit-search-forward 37.3 ノードの取得
treesit-search-forward-goto 37.3 ノードの取得
treesit-search-subtree 37.3 ノードの取得
treesit-simple-imenu-settings 24.5 Imenu
treesit-simple-indent-presets 24.7.2 パーサーベースのインデント
treesit-simple-indent-rules 24.7.2 パーサーベースのインデント
treesit-update-ranges 37.6 複数言語ののパース
triple-click events 22.7.7 リピートイベント
true 1.3.2 nilt
true list 5.1 リストとコンスセル
truename (of file) 26.6.3 本当の名前
truncate 3.5 数値の変換
truncate-lines 41.3 切り詰め
truncate-partial-width-windows 41.3 切り詰め
truncate-string-ellipsis 41.10 表示されるテキストのサイズ
truncate-string-to-width 41.10 表示されるテキストのサイズ
truth value 1.3.2 nilt
try-completion 21.6.1 基本的な補完関数
tty-color-alist 30.24 テキスト端末のカラー
tty-color-approximate 30.24 テキスト端末のカラー
tty-color-clear 30.24 テキスト端末のカラー
tty-color-define 30.24 テキスト端末のカラー
tty-color-mode, a frame parameter 30.4.3.10 フォントとカラーのパラメーター
tty-color-translate 30.24 テキスト端末のカラー
tty-erase-char 42.3 オペレーティングシステムの環境
tty-menu-calls-mouse-position-function 30.16 マウスの位置
tty-setup-hook 42.1.3 端末固有の初期化
tty-top-frame 30.12 フレームのraise、lower、re-stack
turn multibyte support on or off 34.2 マルチバイト文字の無効化
two’s complement 3.1 整数の基礎
type 2 Lispのデータ型
type (button property) 41.20.1 ボタンのプロパティ
type checking 2.7 型のための述語
type checking internals E.7 Emacsプリミティブの記述
type of node, tree-sitter 37.1 Tree-sitter Language Grammar
type predicates 2.7 型のための述語
type, defcustom keyword 15.4 カスタマイゼーション型
type-error, customization keyword 15.4.4 型キーワード
type-of 2.7 型のための述語
type_of E.8.4 その他の便利なモジュール用関数
typographic conventions 1.3.1 Lispの歴史
TZ, environment variable 42.6 タイムゾーンのルール

U
UBA 41.27 双方向テキストの表示
UDP 40.14 ネットワーク接続
UID 42.4 ユーザーの識別
umask 26.7 ファイルの名前と属性の変更
unassigned character codepoints 34.6 文字のプロパティ
unbalanced parentheses 19.3 無効なLisp構文のデバッグ
unbinding keys 23.16 キーのバインドのためのコマンド
unbury-buffer 28.8 バッファーリスト
undecided coding system 34.10.1 コーディングシステムの基本概念
undecided coding-system, when decoding 34.10.7 明示的なエンコードとデコード
undecided coding-system, when encoding 34.10.7 明示的なエンコードとデコード
undecorated, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
undefined 23.11 キー照合のための関数
undefined in keymap 23.10 キーの照合
undefined key 23.2 キーマップの基礎
underline-minimum-offset 41.12.1 フェイスの属性
underlined text 41.12.1 フェイスの属性
undo avoidance 33.20 文字コードの置き換え
undo in temporary buffers 28.2 カレントバッファー
undo-amalgamate-change-group 33.33 グループのアトミックな変更
undo-ask-before-discard 33.10 アンドゥリストの保守
undo-auto-amalgamate 33.9 アンドゥ
undo-auto-current-boundary-timer 33.9 アンドゥ
undo-boundary 33.9 アンドゥ
undo-in-progress 33.9 アンドゥ
undo-limit 33.10 アンドゥリストの保守
undo-outer-limit 33.10 アンドゥリストの保守
undo-strong-limit 33.10 アンドゥリストの保守
unexec E.1 Emacsのビルド
unexec E.1 Emacsのビルド
unhandled-file-name-directory 26.12 特定のファイル名の“Magic”の作成
unibyte buffers, and bidi reordering 41.27 双方向テキストの表示
unibyte text 34.1 テキストの表現方法
unibyte-char-to-multibyte 34.3 テキスト表現の変換
unibyte-string 34.1 テキストの表現方法
Unicode 34.1 テキストの表現方法
unicode bidirectional algorithm 41.27 双方向テキストの表示
unicode character escape 2.4.3.2 一般的なエスケープ構文
unicode general category 34.6 文字のプロパティ
unicode, a charset 34.7 文字セット
unicode-category-table 34.6 文字のプロパティ
unintern 9.3 シンボルの作成とintern
uninterned symbol 9.3 シンボルの作成とintern
uninterned symbol, and generating Lisp code 9.3 シンボルの作成とintern
union of sequences 6.1 シーケンス
unique file names 26.9.5 一意なファイル名の生成
Universal Time 42.5 時刻
universal-argument 22.12 プレフィクスコマンド引数
universal-argument-map Appendix G 標準的なキーマップ
unless 11.2 条件
unload-feature 16.9 アンロード
unload-feature-special-hooks 16.9 アンロード
unloading packages 16.9 アンロード
unloading packages, preparing for D.1 Emacs Lispコーディング規約
unlock-buffer 26.5 ファイルのロック
unmapped frame 30.11 フレームの可視性
unmatchable in rx 35.3.3.1 rxによるregexpの構築
unnumbered group 35.3.1.3 正規表現内のバッククラッシュ構文
unpacking 40.20 バイト配列のpackとunpack
unread-command-events 22.8.6 その他のイベント入力の機能
unsafep 13.17 安全に関数を呼び出せるかどうかの判断
unspecified, face attribute value 41.12.1 フェイスの属性
unsplittable, a frame parameter 30.4.3.5 バッファーのパラメーター
unused lexical variable 12.10.5 レキシカルバインディングへの変換
unwind-protect 11.7.4 非ローカル脱出のクリーンアップ
unwinding 11.7.4 非ローカル脱出のクリーンアップ
up-list 31.2.6 釣り合いのとれたカッコを越えた移動
upcase 4.9 Lispでの大文字小文字変換
upcase-initials 4.9 Lispでの大文字小文字変換
upcase-region 33.18 大文字小文字の変更
upcase-word 33.18 大文字小文字の変更
update callback, for tree-sitter parse-tree 37.2 tree-sitterパーサーの使用
upper case 4.9 Lispでの大文字小文字変換
upper case key sequence 22.8.1 キーシーケンス入力
uptime of Emacs 42.9 プロセッサーの実行時間
use time of window 29.3 ウィンドウの選択
use-empty-active-region 32.8 リージョン
use-frame-synchronization, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
use-global-map 23.9 アクティブなキーマップの制御
use-hard-newlines 33.11 fill
use-local-map 23.9 アクティブなキーマップの制御
use-package 16.7 名前つき機能
use-region-p 32.8 リージョン
use-system-tooltips 41.26 ツールチップ
user errors, signaling 11.7.3.1 エラーをシグナルする方法
user groups 42.4 ユーザーの識別
user identification 42.4 ユーザーの識別
user options, how to define 15.3 カスタマイゼーション変数の定義
user pointer object 16.11 Emacsのダイナミックモジュール
user pointer, using in module functions E.8.3 Lisp・モジュール間の値変換
user signals 22.7.12 その他のシステムイベント
user-defined error 11.7.3.4 エラーシンボルとエラー条件
user-emacs-directory 42.1.2 initファイル
user-error 11.7.3.1 エラーをシグナルする方法
user-full-name 42.4 ユーザーの識別
user-full-name 42.4 ユーザーの識別
user-init-file 42.1.2 initファイル
user-login-name 42.4 ユーザーの識別
user-login-name 42.4 ユーザーの識別
user-mail-address 42.4 ユーザーの識別
user-position, a frame parameter 30.4.3.2 位置のパラメーター
user-ptr object 16.11 Emacsのダイナミックモジュール
user-ptrp 16.11 Emacsのダイナミックモジュール
user-real-login-name 42.4 ユーザーの識別
user-real-login-name 42.4 ユーザーの識別
user-real-uid 42.4 ユーザーの識別
user-size, a frame parameter 30.4.3.3 サイズのパラメーター
user-uid 42.4 ユーザーの識別
UTC 42.5 時刻
utf-8-emacs coding system 34.10.1 コーディングシステムの基本概念
utility functions for parser-based indentation 24.7.2 パーサーベースのインデント

V
valid windows 29.1 Emacsウィンドウの基本概念
validity of coding system 34.10.3 Lispでのコーディングシステム
value cell 9.1 シンボルの構成要素
value of expression 10 評価
value of function 13.1 関数とは?
values 10.5 evalについて
variable 12 変数
variable aliases 12.15 変数のエイリアス
variable definition 12.5 グローバル変数の定義
variable descriptions 1.3.7.2 変数の説明例
variable pitch tables 24.2.7 Tabulated Listモード
variable watchpoints 12.9 変数が変更されたときに実行される関数。
variable with constant value 12.2 変更不可な変数
variable write debugging 19.1.5 変数の変更時にデバッガにエンターする。
variable, buffer-local 12.11 バッファーローカル変数
variable-documentation property 25.1 ドキュメントの基礎
variable-width spaces 41.16.2 スペースの指定
variant coding system 34.10.1 コーディングシステムの基本概念
vc-mode 24.4.4 モードラインで使用される変数
vc-prefix-map 23.6 プレフィクスキー
vc-responsible-backend 26.6.3 本当の名前
vconcat 6.5 ベクターのための関数
vector 6.5 ベクターのための関数
vector (type) 6.4 ベクター
vector evaluation 10.2.1 自己評価を行うフォーム
vector length 6.1 シーケンス
vector reverse 6.1 シーケンス
vector to list 6.1 シーケンス
vector-cells-consed E.5 メモリー使用量
vector-like objects, storage E.3 ガーベージコレクション
vectorp 6.5 ベクターのための関数
vec_get E.8.3 Lisp・モジュール間の値変換
vec_set E.8.3 Lisp・モジュール間の値変換
vec_size E.8.3 Lisp・モジュール間の値変換
verify-visited-file-modtime 28.6 バッファーの変更時刻
version number (in file name) 26.9.1 ファイル名の構成要素
version, customization keyword 15.1 一般的なキーワードアイテム
version-control 27.1.3 番号つきバックアップファイルの作成と削除
vertical combination 29.2 ウィンドウとフレーム
vertical fractional scrolling 29.22 割り合いによる垂直スクロール
vertical scroll position 29.22 割り合いによる垂直スクロール
vertical tab 2.4.3.1 基本的な文字構文
vertical-line, prefix key 22.8.1 キーシーケンス入力
vertical-lineto 41.17.6 SVGイメージ
vertical-motion 31.2.5 スクリーン行単位の移動
vertical-scroll-bar 41.14 スクロールバー
vertical-scroll-bar, prefix key 22.8.1 キーシーケンス入力
vertical-scroll-bars, a frame parameter 30.4.3.4 レイアウトのパラメーター
view part, model/view/controller 41.21 抽象的なディスプレイ
view-register 33.21 レジスター
virtual buffers 28.12 2つのバッファー間でのテキストの交換
visibility, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
visible frame 30.11 フレームの可視性
visible-bell 41.24 ビープ
visible-frame-list 30.8 すべてのフレームを探す
visited file 28.4 バッファーのファイル名
visited file mode 24.2.2 Emacsがメジャーモードを選択する方法
visited-file-modtime 28.6 バッファーの変更時刻
visiting files 26.1 ファイルのvisit
visiting files, functions for 26.1.1 ファイルをvisitする関数
visual lines, moving by 31.2.5 スクリーン行単位の移動
visual order 41.27 双方向テキストの表示
visual order, preserve when copying bidirectional text 41.27 双方向テキストの表示
visual-order cursor motion 41.27 双方向テキストの表示
void function 10.2.4 シンボル関数インダイレクション
void function cell 13.9 関数セルの内容へのアクセス
void variable 12.4 変数がvoidのとき
void-function 13.9 関数セルの内容へのアクセス
void-text-area-pointer 30.19 ポインターの形状
void-variable error 12.4 変数がvoidのとき

W
w32-collate-ignore-punctuation 4.5 文字および文字列の比較
w32-notification-close 42.19 デスクトップ通知
w32-notification-notify 42.19 デスクトップ通知
wait-for-wm, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
waiting 22.10 時間の経過や入力の待機
waiting for command key input 22.8.6 その他のイベント入力の機能
waiting-for-user-input-p 40.10 センチネル: プロセス状態の変更の検知
walk-windows 29.10 ウィンドウのサイクル順
warn 41.5.1 警告の基礎
warning options 41.5.3 警告のためのオプション
warning type 41.5.1 警告の基礎
warning variables 41.5.2 警告のための変数
warning-fill-column 41.5.2 警告のための変数
warning-fill-prefix 41.5.2 警告のための変数
warning-levels 41.5.2 警告のための変数
warning-minimum-level 41.5.3 警告のためのオプション
warning-minimum-log-level 41.5.3 警告のためのオプション
warning-prefix-function 41.5.2 警告のための変数
warning-series 41.5.2 警告のための変数
warning-suppress-log-types 41.5.3 警告のためのオプション
warning-suppress-types 41.5.3 警告のためのオプション
warning-type-format 41.5.2 警告のための変数
warnings 41.5 警告のレポート
warnings, delayed 41.5.4 遅延された警告
warnings, suppressing during startup 41.5.3 警告のためのオプション
watch, for filesystem events 42.20 ファイル変更による通知
watchpoints for Lisp variables 12.9 変数が変更されたときに実行される関数。
webkit browser widget 41.19 埋め込みネイティブウィジェット
wheel-down event 22.7.12 その他のシステムイベント
wheel-up event 22.7.12 その他のシステムイベント
when 11.2 条件
when-let 11.2 条件
where was a symbol defined 16.8 どのファイルで特定のシンボルが定義されているか
where-is-internal 23.17 キーマップのスキャン
while 11.5 繰り返し
while-let 11.2 条件
while-no-input 22.8.6 その他のイベント入力の機能
while-no-input-ignore-events 22.8.6 その他のイベント入力の機能
whitespace 2.4.3.1 基本的な文字構文
wholenump 3.3 数値のための述語
widen 31.4 ナローイング
widening 31.4 ナローイング
width of a window 29.4 ウィンドウのサイズ
width, a frame parameter 30.4.3.3 サイズのパラメーター
window 29.1 Emacsウィンドウの基本概念
window (overlay property) 41.9.2 オーバーレイのプロパティ
window auto-selection 29.25 マウスによるウィンドウの自動選択
window body 29.1 Emacsウィンドウの基本概念
window body height 29.4 ウィンドウのサイズ
window body size 29.4 ウィンドウのサイズ
window body width 29.4 ウィンドウのサイズ
window buffer change 29.28 ウィンドウのスクロールと変更のためのフック
window change functions 29.28 ウィンドウのスクロールと変更のためのフック
window combination 29.2 ウィンドウとフレーム
window combination limit 29.9 ウィンドウの再結合
window configuration (Edebug) 19.2.14.2 Edebugの表示の更新
window configuration change 29.28 ウィンドウのスクロールと変更のためのフック
window configurations 29.26 ウィンドウの構成
window decorations 29.1 Emacsウィンドウの基本概念
window dividers 41.15 ウィンドウディバイダー
window end position 29.20 ウィンドウの開始位置と終了位置
window excursions 31.3 エクスカーション
window header line 24.4.7 ウィンドウのヘッダーライン
window height 29.4 ウィンドウのサイズ
window history 29.14 ウィンドウのヒストリー
window in direction 29.2 ウィンドウとフレーム
window internals E.9.2 ウィンドウの内部
window layout in a frame 2.5.6 ウィンドウ構成型
window layout, all frames 2.5.7 フレーム構成型
window manager interaction, and frame parameters 30.4.3.8 ウィンドウ管理のパラメーター
window order by time of last use 29.3 ウィンドウの選択
window ordering, cyclic 29.10 ウィンドウのサイクル順
window parameters 29.27 ウィンドウのパラメーター
window pixel height 29.4 ウィンドウのサイズ
window pixel width 29.4 ウィンドウのサイズ
window point 29.19 ウィンドウとポイント
window point internals E.9.2 ウィンドウの内部
window position 29.19 ウィンドウとポイント
window position 29.24 座標とウィンドウ
window position on display 30.4.3.2 位置のパラメーター
window positions and window managers 30.4.3.2 位置のパラメーター
window resizing 29.5 ウィンドウのリサイズ
window selected within a frame 29.3 ウィンドウの選択
window selection change 29.28 ウィンドウのスクロールと変更のためのフック
window size 29.4 ウィンドウのサイズ
window size change 29.28 ウィンドウのスクロールと変更のためのフック
window size on display 30.4.3.3 サイズのパラメーター
window size, changing 29.5 ウィンドウのリサイズ
window splitting 29.7 ウィンドウの分割
window start position 29.20 ウィンドウの開始位置と終了位置
window state 29.26 ウィンドウの構成
window state change 29.28 ウィンドウのスクロールと変更のためのフック
window state change flag 29.28 ウィンドウのスクロールと変更のためのフック
window that satisfies a predicate 29.10 ウィンドウのサイクル順
window top line 29.20 ウィンドウの開始位置と終了位置
window tree 29.2 ウィンドウとフレーム
window use time 29.3 ウィンドウの選択
window width 29.4 ウィンドウのサイズ
window, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
window-absolute-body-pixel-edges 29.24 座標とウィンドウ
window-absolute-pixel-edges 29.24 座標とウィンドウ
window-absolute-pixel-position 29.24 座標とウィンドウ
window-adjust-process-window-size-function 40.9.1 プロセスのバッファー
window-at 29.24 座標とウィンドウ
window-at-side-p 29.2 ウィンドウとフレーム
window-atom, a window parameter 29.27 ウィンドウのパラメーター
window-atom-root 29.18 アトミックウィンドウ
window-body-edges 29.24 座標とウィンドウ
window-body-height 29.4 ウィンドウのサイズ
window-body-pixel-edges 29.24 座標とウィンドウ
window-body-size 29.4 ウィンドウのサイズ
window-body-width 29.4 ウィンドウのサイズ
window-bottom-divider-width 41.15 ウィンドウディバイダー
window-buffer 29.11 バッファーとウィンドウ
window-buffer-change-functions 29.28 ウィンドウのスクロールと変更のためのフック
window-bump-use-time 29.3 ウィンドウの選択
window-child 29.2 ウィンドウとフレーム
window-combination-limit 29.9 ウィンドウの再結合
window-combination-limit 29.9 ウィンドウの再結合
window-combination-resize 29.9 ウィンドウの再結合
window-combined-p 29.2 ウィンドウとフレーム
window-configuration-change-hook 29.28 ウィンドウのスクロールと変更のためのフック
window-configuration-equal-p 29.26 ウィンドウの構成
window-configuration-frame 29.26 ウィンドウの構成
window-configuration-p 29.26 ウィンドウの構成
window-current-scroll-bars 41.14 スクロールバー
window-dedicated-p 29.15 専用のウィンドウ
window-display-table 41.23.3 アクティブなディスプレイテーブル
window-edges 29.24 座標とウィンドウ
window-end 29.20 ウィンドウの開始位置と終了位置
window-font-height 41.12.12 低レベルのフォント表現
window-font-width 41.12.12 低レベルのフォント表現
window-frame 29.2 ウィンドウとフレーム
window-fringes 41.13.1 フリンジのサイズと位置
window-full-height-p 29.4 ウィンドウのサイズ
window-full-width-p 29.4 ウィンドウのサイズ
window-group-end 29.20 ウィンドウの開始位置と終了位置
window-group-end-function 29.20 ウィンドウの開始位置と終了位置
window-group-start 29.20 ウィンドウの開始位置と終了位置
window-group-start-function 29.20 ウィンドウの開始位置と終了位置
window-header-line-height 24.4.7 ウィンドウのヘッダーライン
window-header-line-height 29.4 ウィンドウのサイズ
window-height, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
window-hscroll 29.23 水平スクロール
window-id, a frame parameter 30.4.3.8 ウィンドウ管理のパラメーター
window-in-direction 29.2 ウィンドウとフレーム
window-largest-empty-rectangle 29.24 座標とウィンドウ
window-left-child 29.2 ウィンドウとフレーム
window-line-height 29.20 ウィンドウの開始位置と終了位置
window-lines-pixel-dimensions 41.10 表示されるテキストのサイズ
window-list 29.2 ウィンドウとフレーム
window-live-p 29.1 Emacsウィンドウの基本概念
window-main-window 29.17.2 サイドウィンドウのオプションと関数
window-make-atom 29.18 アトミックウィンドウ
window-margins 41.16.5 マージン内への表示
window-max-chars-per-line 29.4 ウィンドウのサイズ
window-min-height 29.4 ウィンドウのサイズ
window-min-height 29.4 ウィンドウのサイズ
window-min-height, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
window-min-size 29.4 ウィンドウのサイズ
window-min-width 29.4 ウィンドウのサイズ
window-min-width 29.4 ウィンドウのサイズ
window-min-width, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
window-minibuffer-p 21.11 ミニバッファーのウィンドウ
window-mode-line-height 29.4 ウィンドウのサイズ
window-next-buffers 29.14 ウィンドウのヒストリー
window-next-sibling 29.2 ウィンドウとフレーム
window-old-body-pixel-height 29.28 ウィンドウのスクロールと変更のためのフック
window-old-body-pixel-width 29.28 ウィンドウのスクロールと変更のためのフック
window-old-buffer 29.28 ウィンドウのスクロールと変更のためのフック
window-old-pixel-height 29.28 ウィンドウのスクロールと変更のためのフック
window-old-pixel-width 29.28 ウィンドウのスクロールと変更のためのフック
window-parameter 29.27 ウィンドウのパラメーター
window-parameters 29.27 ウィンドウのパラメーター
window-parameters, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
window-parent 29.2 ウィンドウとフレーム
window-persistent-parameters 29.27 ウィンドウのパラメーター
window-pixel-edges 29.24 座標とウィンドウ
window-pixel-height 29.4 ウィンドウのサイズ
window-pixel-width 29.4 ウィンドウのサイズ
window-point 29.19 ウィンドウとポイント
window-point-insertion-type 29.19 ウィンドウとポイント
window-preserve-size 29.6 ウィンドウサイズの保持
window-preserved-size 29.6 ウィンドウサイズの保持
window-preserved-size, a window parameter 29.27 ウィンドウのパラメーター
window-prev-buffers 29.14 ウィンドウのヒストリー
window-prev-sibling 29.2 ウィンドウとフレーム
window-resizable 29.5 ウィンドウのリサイズ
window-resize 29.5 ウィンドウのリサイズ
window-resize-pixelwise 29.5 ウィンドウのリサイズ
window-right-divider-width 41.15 ウィンドウディバイダー
window-scroll-bar-height 41.14 スクロールバー
window-scroll-bar-width 41.14 スクロールバー
window-scroll-bars 41.14 スクロールバー
window-scroll-functions 29.28 ウィンドウのスクロールと変更のためのフック
window-selection-change-functions 29.28 ウィンドウのスクロールと変更のためのフック
window-setup-hook 42.1.2 initファイル
window-side, a window parameter 29.27 ウィンドウのパラメーター
window-sides-reversed 29.17.2 サイドウィンドウのオプションと関数
window-sides-slots 29.17.2 サイドウィンドウのオプションと関数
window-sides-vertical 29.17.2 サイドウィンドウのオプションと関数
window-size, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
window-size-change-functions 29.28 ウィンドウのスクロールと変更のためのフック
window-size-fixed 29.6 ウィンドウサイズの保持
window-slot, a window parameter 29.27 ウィンドウのパラメーター
window-start 29.20 ウィンドウの開始位置と終了位置
window-state-change-functions 29.28 ウィンドウのスクロールと変更のためのフック
window-state-change-hook 29.28 ウィンドウのスクロールと変更のためのフック
window-state-get 29.26 ウィンドウの構成
window-state-put 29.26 ウィンドウの構成
window-swap-states 29.26 ウィンドウの構成
window-system 41.25 ウィンドウシステム
window-system 41.25 ウィンドウシステム
window-system window 29.1 Emacsウィンドウの基本概念
window-system-initialization 42.1.1 要約: スタートアップ時のアクション順序
window-tab-line-height 29.4 ウィンドウのサイズ
window-text-pixel-size 41.10 表示されるテキストのサイズ
window-toggle-side-windows 29.17.2 サイドウィンドウのオプションと関数
window-top-child 29.2 ウィンドウとフレーム
window-total-height 29.4 ウィンドウのサイズ
window-total-size 29.4 ウィンドウのサイズ
window-total-width 29.4 ウィンドウのサイズ
window-tree 29.2 ウィンドウとフレーム
window-use-time 29.3 ウィンドウの選択
window-valid-p 29.1 Emacsウィンドウの基本概念
window-vscroll 29.22 割り合いによる垂直スクロール
window-width, a buffer display action alist entry 29.13.3 バッファー表示用のアクションalist
windowp 29.1 Emacsウィンドウの基本概念
windows, controlling precisely 29.11 バッファーとウィンドウ
windows, recombining 29.9 ウィンドウの再結合
with-case-table 4.10 caseテーブル
with-coding-priority 34.10.6 単一の操作にたいするコーディングシステムの指定
with-connection-local-application-variables 12.14.2 接続ローカル変数の適用
with-connection-local-variables 12.14.2 接続ローカル変数の適用
with-current-buffer 28.2 カレントバッファー
with-current-buffer-window 41.8 一時的な表示
with-delayed-message 41.4.2 処理の進捗レポート
with-demoted-errors 11.7.3.3 エラーを処理するコードの記述
with-environment-variables 42.3 オペレーティングシステムの環境
with-eval-after-load 16.10 ロードのためのフック
with-existing-directory 26.6.1 アクセシビリティのテスト
with-file-modes 26.7 ファイルの名前と属性の変更
with-help-window 25.6 ヘルプ関数
with-local-quit 22.11 quit
with-mutex 39.2 ミューテックス
with-no-warnings 17.6 コンパイラーのエラー
with-output-to-string 20.5 出力関数
with-output-to-temp-buffer 41.8 一時的な表示
with-restriction 31.4 ナローイング
with-selected-frame 29.3 ウィンドウの選択
with-selected-window 29.3 ウィンドウの選択
with-silent-modifications 28.5 バッファーの変更
with-silent-modifications, and changes in text properties 33.19.2 テキストプロパティの変更
with-sqlite-transaction 33.29 データベース
with-suppressed-warnings 17.6 コンパイラーのエラー
with-syntax-table 36.3 構文テーブルの関数
with-temp-buffer 28.2 カレントバッファー
with-temp-buffer-window 41.8 一時的な表示
with-temp-file 26.4 ファイルへの書き込み
with-temp-message 41.4.1 エコーエリアへのメッセージの表示
with-timeout 42.11 遅延実行のためのタイマー
with-undo-amalgamate 33.9 アンドゥ
without-restriction 31.4 ナローイング
word-boundary in rx 35.3.3.1 rxによるregexpの構築
word-end in rx 35.3.3.1 rxによるregexpの構築
word-search-backward 35.1 文字列の検索
word-search-backward-lax 35.1 文字列の検索
word-search-forward 35.1 文字列の検索
word-search-forward-lax 35.1 文字列の検索
word-search-regexp 35.1 文字列の検索
word-start in rx 35.3.3.1 rxによるregexpの構築
words in region 31.2.4 テキスト行単位の移動
words-include-escapes 31.2.2 単語単位の移動
wrap-prefix 41.3 切り詰め
write-abbrev-file 38.3 ファイルへのabbrevの保存
write-char 20.5 出力関数
write-contents-functions 26.2 バッファーの保存
write-file 26.2 バッファーの保存
write-file-functions 26.2 バッファーの保存
write-region 26.4 ファイルへの書き込み
write-region 26.8 ファイルと二次媒体
write-region-annotate-functions 26.13.3 漸次仕様
write-region-inhibit-fsync 26.4 ファイルへの書き込み
write-region-post-annotation-function 26.13.3 漸次仕様
writing a documentation string 25.1 ドキュメントの基礎
writing buffer display actions 29.13.6 バッファー表示の思想
writing emacs modules E.8 動的にロードされるモジュールの記述
writing Emacs primitives E.7 Emacsプリミティブの記述
writing module functions E.8.2 モジュール関数の記述
writing to files 26.4 ファイルへの書き込み
wrong-number-of-arguments 13.2.3 引数リストの機能
wrong-type-argument 2.7 型のための述語

X
X display names 30.2 複数の端末
X Window System 41.25 ウィンドウシステム
x-alt-keysym 42.16 X11キーシンボルの処理
x-alternatives-map Appendix G 標準的なキーマップ
x-begin-drag 30.22 ドラッグアンドドロップ
x-bitmap-file-path 41.12.1 フェイスの属性
x-close-connection 30.2 複数の端末
x-color-defined-p 30.23 カラー名
x-color-values 30.23 カラー名
x-ctrl-keysym 42.16 X11キーシンボルの処理
x-defined-colors 30.23 カラー名
x-display-color-p 30.26 ディスプレイ機能のテスト
x-display-list 30.2 複数の端末
x-dnd-direct-save-function 30.22 ドラッグアンドドロップ
x-dnd-disable-motif-protocol 30.22 ドラッグアンドドロップ
x-dnd-known-types 30.22 ドラッグアンドドロップ
x-dnd-save-direct 30.22 ドラッグアンドドロップ
x-dnd-save-direct-immediately 30.22 ドラッグアンドドロップ
x-dnd-test-function 30.22 ドラッグアンドドロップ
x-dnd-types-alist 30.22 ドラッグアンドドロップ
x-dnd-use-offix-drop 30.22 ドラッグアンドドロップ
x-dnd-use-unsupported-drop 30.22 ドラッグアンドドロップ
x-double-buffered-p 30.11 フレームの可視性
x-family-fonts 41.12.10 フォントの照会
x-focus-frame 30.10 入力のフォーカス
x-get-resource 30.25 Xリソース
x-hyper-keysym 42.16 X11キーシンボルの処理
x-list-fonts 41.12.10 フォントの照会
x-meta-keysym 42.16 X11キーシンボルの処理
x-open-connection 30.2 複数の端末
x-parse-geometry 30.4.4 ジオメトリー
x-pointer-shape 30.19 ポインターの形状
x-popup-dialog 30.18 ダイアログボックス
x-popup-menu 30.17 ポップアップメニュー
x-pre-popup-menu-hook 30.17 ポップアップメニュー
x-resource-class 30.25 Xリソース
x-resource-name 30.25 Xリソース
x-sensitive-text-pointer-shape 30.19 ポインターの形状
x-server-vendor 30.26 ディスプレイ機能のテスト
x-server-version 30.26 ディスプレイ機能のテスト
x-setup-function-keys Appendix G 標準的なキーマップ
x-stretch-cursor 30.4.3.9 カーソルのパラメーター
x-super-keysym 42.16 X11キーシンボルの処理
X11 keysyms 42.16 X11キーシンボルの処理
XBM 41.17.3 XBMイメージ
xdigit character class, regexp 35.3.1.2 文字クラス
XDS 30.22 ドラッグアンドドロップ
XML DOM 33.30.1 ドキュメントオブジェクトモデル
xor 11.3 組み合わせ条件の構築
XPM 41.17.4 XPMイメージ
xwidget 41.19 埋め込みネイティブウィジェット
xwidget callbacks 22.7.11 Xwidgetイベント
xwidget property list 41.19 埋め込みネイティブウィジェット
xwidget type 2.5.16 Xwidget型
xwidget-buffer 41.19 埋め込みネイティブウィジェット
xwidget-display-event event 22.7.11 Xwidgetイベント
xwidget-event event 22.7.11 Xwidgetイベント
xwidget-info 41.19 埋め込みネイティブウィジェット
xwidget-live-p 41.19 埋め込みネイティブウィジェット
xwidget-perform-lispy-event 41.19 埋め込みネイティブウィジェット
xwidget-plist 41.19 埋め込みネイティブウィジェット
xwidget-query-on-exit-flag 41.19 埋め込みネイティブウィジェット
xwidget-resize 41.19 埋め込みネイティブウィジェット
xwidget-size-request 41.19 埋め込みネイティブウィジェット
xwidget-view type 2.5.16 Xwidget型
xwidget-webkit-back-forward-list 41.19 埋め込みネイティブウィジェット
xwidget-webkit-estimated-load-progress 41.19 埋め込みネイティブウィジェット
xwidget-webkit-execute-script 41.19 埋め込みネイティブウィジェット
xwidget-webkit-execute-script-rv 41.19 埋め込みネイティブウィジェット
xwidget-webkit-finish-search 41.19 埋め込みネイティブウィジェット
xwidget-webkit-get-title 41.19 埋め込みネイティブウィジェット
xwidget-webkit-goto-history 41.19 埋め込みネイティブウィジェット
xwidget-webkit-goto-uri 41.19 埋め込みネイティブウィジェット
xwidget-webkit-load-html 41.19 埋め込みネイティブウィジェット
xwidget-webkit-next-result 41.19 埋め込みネイティブウィジェット
xwidget-webkit-previous-result 41.19 埋め込みネイティブウィジェット
xwidget-webkit-search 41.19 埋め込みネイティブウィジェット
xwidget-webkit-set-cookie-storage-file 41.19 埋め込みネイティブウィジェット
xwidget-webkit-stop-loading 41.19 埋め込みネイティブウィジェット
xwidgetp 41.19 埋め込みネイティブウィジェット

Y
y-or-n-p 21.7 Yes-or-Noによる問い合わせ
y-or-n-p-with-timeout 21.7 Yes-or-Noによる問い合わせ
yank 33.8.4 yank用の関数
yank suppression 23.12 キーバインディングの変更
yank-excluded-properties 33.8.3 yank
yank-handled-properties 33.8.3 yank
yank-media-handler 30.21 メディアのyank
yank-pop 33.8.4 yank用の関数
yank-transform-functions 33.8.3 yank
yank-undo-function 33.8.4 yank用の関数
yanking and text properties 33.8.3 yank
yes-or-no questions 21.7 Yes-or-Noによる問い合わせ
yes-or-no-p 21.7 Yes-or-Noによる問い合わせ

Z
z-group, a frame parameter 30.4.3.2 位置のパラメーター
Z-order 30.12 フレームのraise、lower、re-stack
zero-or-more in rx 35.3.3.1 rxによるregexpの構築
zero-or-one in rx 35.3.3.1 rxによるregexpの構築
zerop 3.3 数値のための述語
zlib-available-p 33.24 圧縮されたデータの処理
zlib-decompress-region 33.24 圧縮されたデータの処理

Jump to:   "   #   $   %   &   '   (   )   *   +   ,   -   .   /   0   1   2   3   :   ;   <   =   >   ?   @   [   \   ]   ^   `   |  
A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z  

[Top] [Contents] [Index] [ ? ]

Footnotes

(1)

副文字テーブル(sub-char-tables)に使用される‘#^^’を目にすることがあるかもしれません。

(2)

これはCommon LispやCのような言語が定数にたいして指定する挙動であり、プログラムによるimmutableオブジェクト変更の試みにエラーのシグナルを要求するJavaScriptやPythonのようなインタープリターとは異なる。理想的にはEmacs Lispインタープリターは後者を目指して進化するであろう。

(3)

照合ルールとlocaleにたいする依存関係についての詳細はThe Unicode Collation Algorithmを参照のこと。GNU Cライブラリー(glibcとも呼ばれる)のような一部の標準CライブラリーはUCA(Unicode Collation Algorithm: Unicode照合アルゴリズム)の大部分を実装しており、関連のあるlocaleデータやCLDR(Common Locale Data Repository: 共通ロケールデータレポジトリ)を使用する。

(4)

これは真リスト(true list)と呼ばれることもありますが、このマニュアルでは一般的にこの用語を使用しません。

(5)

リストの最後に要素を追加するための、これと完全に同等な方法はありません。listnameをコピーすることにより新しいリストを作成してから、neweltをそのリストの最後に追加する(append listname (list newelt))を使用することができます。すべてのCDRを辿って終端のnilを置き換える、(nconc listname (list newelt))を使用することもできます。コピーも変更も行なわずにリストの先頭に要素を追加するconsと比較してみてください。

(6)

ここでの“キー(key)”の使い方は、用語“キーシーケンス(key sequence)”とは関係ありません。キーはテーブルにあるアイテムを探すために使用される値という意味です。この場合、テーブルはalistでありalistはアイテムに関連付けられます。

(7)

S式(S-expression)、短くはsexpという言葉でも呼ばれることがありますが、わたしたちはこのマニュアル内では通常はこの用語は使用しません。

(8)

“環境”にたいするこの定義は、プログラムの結果に影響し得るすべてのデータを特に意図したものではありません。

(9)

正確に言うとデフォルトのダイナミックスコープ(dynamic scoping)のルールでは、値セルは常にその変数のカレント値を保持しますが、レキシカルスコープ(lexical scoping)では異なります。詳細は変数のバインディングのスコーピングルールを参照してください。

(10)

これにはいくつか例外があります。たとえばレキシカルバインディングは、Lispデバッガーからもアクセスできます。

(11)

MS-DOS版のEmacsはDOSファイルシステムの制限により、かわりに_dir-locals.elという名前を使用します。

(12)

lexical-bindingを用いたコードでのみ機能します。

(13)

これはカリー化(currying)と関連しますが異なる機能です。カーリングは複数の引数を受け取る関数を、関数チェーンとして呼び出せるような1つの引数を取る個々の関数に変換するような方法です。

(14)

funcが受け取ることができる引数の個数に制限がない場合には、新たな関数が受け取ることができる引数の個数も無制限になるので、このようなケースではapply-partiallyは新たな関数が受け取ることができる引数の個数を減らしません。

(15)

ビルトイン関数とは異なり、このバージョンでは任意個数の引数を許容することに注意してください。

(16)

いくつかの要素は実際に2つの引数を提供します。

(17)

ボタンダウンはドラッグの保守的なアンチテーゼです。
訳注: 原文は“Button-down is the conservative antithesis of drag.”。
ちなみにIT用語で使用される前は"button-down"はボタンダウンシャツを表すとともに「保守的、堅苦しい」という意味もあり、一方の"drag"はIT用語として使用される前から「引っ張る、引きずる」という意味で用いられてきましたが「本来は異性が着る洋服」という意味もあります。

(18)

これはテキスト端末のようなツールキットを使用しないメニューにたいして要求されます。

(19)

MS-WindowsバージョンのEmacsはCygwin環境用にコンパイルされており、2つのファイル名構文の変換にcygwin-convert-file-name-to-windowscygwin-convert-file-name-from-windowsを使用できます。

(20)

EmacsはGNUの慣習に則りパス名(pathname)ではなくファイル名(file name)という用語を使用する。わたしたちがパス(path)という用語を用いるのは検索パス(ディレクトリーのリスト)にたいしてだけである。

(21)

PGTKのフレームではfullheightfullwidthの値をセットしても効果はない。

(22)

Haikuで子フレームが可視なのは親フレームがアクティブなときだけであり、これはHaikuウィンドウシステムの制限によるものです。同じ制限により子フレームはトップレベルの親、すなわち階層上一番上位にある親をもたないフレームの上でのみ表示が保証されています。

(23)

RFC(Request for Commentsの略)とは標準を記述するナンバーが付与されたインターネット情報提供ドキュメントです。RFCは通常は自身が先駆的に活動する技術エキスパートによって記述され、伝統として現実的で経験主導で記述されます。

(24)

この内部表現は任意のUnicodeコードポイントを表すための、UTF-8と呼ばれるUnicode標準によるエンコーディングの1つにもとづいたものですが、8ビットrawバイトおよびUnicodeに統一されていない文字を使用する追加のコードポイントを表現するためにEmacsはUTF-8を拡張しています。

(25)

Unicode仕様ではこれらのタグ名を‘<..>’カッコ内に記述しますがEmacsでのタグ名にはカッコは含まれません。Unicodeでの‘<small>’指定はEmacsでは‘small’となります。

(26)

これは非欲張りな演算子でもっと簡単に記述できるかもしれませんが(どうやって?)、例が面白くなくなるでしょう。

(27)

regexp-optの結果が絶対的にもっとも効率的であるという保証はないことに注意してください。手作業でチューニングした正規表現のほうがわずかに効率的なこともありますが、これに努力する価値はほとんどないでしょう。

(28)

他のシステムではEmacsはlsのLispエミュレーションを使用します。ディレクトリーのコンテンツを参照してください。

(29)

後方互換のため、フェイス名の指定に文字列も使用できます。これは同名のLispシンボルと等価です。

(30)

このコンテキストでは用語fontはFont Lock(Font Lockモードを参照)にたいして何も行いません。

(31)

MS-Windowsではw32-use-native-image-APIが非nilにセットされている必要があります。

(32)

タイポグラフィではemはタイプの高さに相当する距離のこと。たとえば12ポイントタイプの1emは12ポイントと同じ。これの使用により距離とタイプの比率が保たれる。

(33)

Common Lispスタイルのパッケージシステムの恩恵はコストを上回るとは考えられない。

(34)

わたしたちは時折これを使用しますが、やりすぎないでください。


[Top] [Contents] [Index] [ ? ]

Table of Contents


[Top] [Contents] [Index] [ ? ]

Short Table of Contents


[Top] [Contents] [Index] [ ? ]

About This Document

This document was generated on October 20, 2023 using texi2any.

The buttons in the navigation panels have the following meaning:

Button Name Go to From 1.2.3 go to
[ << ] FastBack Beginning of this chapter or previous chapter 1
[ < ] Back Previous section in reading order 1.2.2
[ Up ] Up Up section 1.2
[ > ] Forward Next section in reading order 1.2.4
[ >> ] FastForward Next chapter 2
[Top] Top Cover (top) of document  
[Contents] Contents Table of contents  
[Index] Index Index  
[ ? ] About About (help)  

where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:


This document was generated on October 20, 2023 using texi2any.