付録
−−− 詳細ノード一覧 −−−
以下は、上にあげたノードの下位ノードです。 直接移動できるように掲載しておきます。
導入
慣習
nil
and t
are used.
ヒントと慣習
記述形式
Lispデータ型
プログラミング向けの型
リスト型
編集向けの型
数
文字列と文字
format
: Emacs's analogue of printf
.
リスト
既存リスト構造の変更
シーケンス、配列、ベクトル
シンボル
評価
フォームの種類
制御構造
if
, cond
.
and
, or
, not
.
while
loops.
非ローカル脱出
エラー
変数
スコープルールと変数束縛
バッファローカルな変数
関数
ラムダ式
マクロ
ロード
load
function and others.
バイトコンパイル
関数のアドバイス
defadvice
.
defadvice
as fset
is to defun
.
Lispプログラムのデバッグ
Lispデバッガ
debug
.
不正なLisp構文のデバッグ
Lispオブジェクトの読み取りと表示
ミニバッファ
補完
コマンドループ
コマンドの定義
interactive
.
キーマップ
メジャーモードとマイナモード
メジャーモード
マイナモード
モード行の書式
説明文
ファイル
ファイルを訪問する
ファイルに関する情報
ファイル名
バックアップと自動保存
revert-buffer
, and how to customize
what it does.
バックアップファイル
バッファ
ウィンドウ
フレーム
バッファ内の位置
移動
マーカ
テキスト
キルリング
字下げ
テキスト属性
探索と一致
正規表現
構文テーブル
構文記述子
略語と略語の展開
プロセス
プロセスからの出力を受け取る
オペレーティングシステムとのインターフェイス
Emacsの始動
.emacs
).
Emacsから抜ける
Emacsの画面表示
GNU Emacsの内部
オブジェクトの内部
1991年6月 バージョン2.0
Copyright © 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA 1 何人も、以下の内容を変更しないでそのまま複写する場合に限り、 本使用許諾書を複製したり頒布することができます。
ほとんどのソフトウェアの使用許諾は、ソフトウェアを共有し、 変更するユーザの自由を奪うことを意図しています。 それに対して、我々のGNU一般公有使用許諾は、 フリー・ソフトウェアを共有したり変更する自由をユーザに保証するためのもの、 即ちフリー・ソフトウェアがそのユーザ全てにとって フリーであることを保証するためのものです。 本使用許諾は、Free Software Foundationのほとんど全てのソフトウェアに 適用されるだけでなく、 プログラムの作成者が本使用許諾に依るとした場合のそのプログラムにも 適用することができます。 (その他の Free Software Foundation のソフトウェアのいくつかは、 本許諾書ではなく、GNUライブラリ一般公有使用許諾で保護されます。) あなたは自分のプログラムにもこれを適用できます。
我々がフリー・ソフトウェアについて言う場合は 自由のことに言及しているのであって、価格のことではありません。 我々の一般公有使用許諾の各条項は、次の事柄を確実に実現することを 目的として立案されています。
このようなユーザの権利を守るために、我々は、 何人もこれらの権利を否定したり、あるいは放棄するように ユーザに求めることはできないという制限条項を設ける必要があります。 これらの制限条項は、ユーザが、フリー・ソフトウェアの複製物を 頒布したり変更しようとする場合には、そのユーザ自身が守るべき義務ともなります。
例えば、あなたがフリー・ソフトウェアの複製物を頒布する場合、 有償か無償かにかかわらず、 あなたは自分の持っている権利を全て相手に与えなければなりません。 あなたは、相手もまたソース・コードを受け取ったり入手できるということを 認めなければなりません。 さらにあなたは、彼らが自分たちの権利を知るように、 これらの条項を知らしめなければなりません。
我々は次の2つの方法でユーザの権利を守ります。 (1)ソフトウェアに著作権を主張し、 (2)本使用許諾の条項の下で ソフトウェアを複製・頒布・変更する権利をユーザに与えます。
また、各作成者や我々自身を守るために、 本フリー・ソフトウェアが無保証であることを 全ての人々が了解している必要があります。 さらに、他の誰かによって変更されたソフトウェアが頒布された場合、 受領者はそのソフトウェアがオリジナル・バージョンではないということを 知らされる必要があります。 それは、他人の関与によって原開発者に対する評価が 影響されないようにするためです。
最後に、どのフリー・プログラムもソフトウェア特許に絶えず脅かされています。 我々は、フリー・プログラムの再頒布者が個人的に特許権を取得し、 事実上そのプログラムを自分の財産にしてしまうという危険を 避けたいと願っています。 これを防ぐために我々は、いずれの特許も、 誰でも自由に使用できるように使用許諾されるべきか、 あるいは何人に対しても全く使用させないかの、 いずれかにすべきであることを明らかにしてきました。
複写・頒布・変更に対する正確な条項と条件を次に示します。
複製、頒布、変更以外の行為は本使用許諾の対象としません。 それらは本使用許諾の範囲外です。 「プログラム」を実行させる行為に関して制約はありません。 「プログラム」の出力は、 (「プログラム」を実行させて作成させたかどうかとは無関係に) その内容が「プログラム生成物」である場合に限り本使用許諾の対象となります。 これが当てはまるかどうかは、「プログラム」が何をするものかに依ります。
複製物の引き渡しに要する実費は請求することができます。 また、あなた独自の保証を行なう場合はそれを有償とすることができます。
これらの要件は変更された作成物にも全て適用されます。 その変更版の或る部分が「プログラム」の派生物ではなく、 しかもそれ自体独立で異なる作成物だと合理的に考えられる場合、 あなたがそれらを別の作成物として頒布した時は、 本使用許諾とその条項はそれらの部分には適用されません。 しかし、それらを「プログラム生成物」の一部として頒布する場合は、 全体が本使用許諾の条項に従って頒布されなければならず、 使用許諾を受ける他の全ての者に対する許諾も プログラム全体にわたって与えられなければならず、 結果として、誰が書いたかにかかわらず、 全ての部分に本使用許諾が適用されなければなりません。
このように、本条項の意図するところは、 完全にあなたによって書かれた作成物について、権利を要求したり、 あなたと権利関係を争うことではありません。 むしろその目的は、作成物が「プログラム生成物」 である場合にその派生物や集合物の頒布を規制することにあります。
さらに、「プログラム」(又は「プログラム生成物」)と 「プログラム生成物」とはならない他のプログラムとを、 単に保管や頒布のために同一の媒体上にまとめて記録したとしても、 本使用許諾は他のプログラムには適用されません。
なお、ソース・コードとは、変更作業に適した記述形式を指します。 また、実行可能形式のファイルに対応するソース・コード一式とは、 それに含まれる全モジュールに対応する全てのソース・コード、 及びあらゆる関連のインタフェース定義ファイル、 及び実行を可能にするコンパイルとインストールの制御に関する記述を指します。 特別な例外として、実行可能なファイルが動作するオペレーティング・システムの 主要な構成要素(コンパイラ、カーネルなど)と共に (ソース・コード又はバイナリのどちらかで)頒布されているものについては、 その構成要素自体が実行形式に付随していない場合に限り、 頒布されるソース・コードに含める必要はありません。
実行可能形式またはオブジェクト・コードの頒布が、 指示された場所からの複製のためのアクセス権の賦与である場合、 同じ場所からのソース・コードの複製のための同等なアクセス権を賦与すれば、 たとえ第三者にオブジェクト・コードと共にソースの複製を強いなくとも、 ソース・コードを頒布したものとみなします。
本条項の或る部分が何らかの特別な状況下で無効または適用不可能になった場合、 本条項のその他の残りの部分が適用されるように意図されており、また、 本条項は全体としてその他の状況に当てはまるように意図されています。
本条項の目的は、特許やその他の財産権を侵害したり、 そのような権利に基づく主張の妥当性を争うようにあなたに 勧めることではありません。 本条項の唯一の目的は、フリー・ソフトウェアの頒布システムの完全性を守ることで、 それは公有使用許諾の実践によって履行されます。 多くの人々が、このシステムの一貫した適用を信頼して、 このシステムを通じて頒布されている幅広い範囲のソフトウェアに惜しみない貢献を してくれました。 作成者や寄贈者が他の何らかのシステムを通じてソフトウェアを 頒布したいと決めることは彼らの自由意志であり、 使用許諾を受ける者はその選択を強いることはできません。
本条項は、本使用許諾の他の条項の意味内容が何であるかを 完全に明らかにすることを意図しています。
各バージョンは、バージョン番号によって区別します。 「プログラム」中に本使用許諾のバージョン番号の指定がある場合は、 その指定されたバージョンか、又はその後にFree Software Foundationから 公表されているいずれかのバージョンから1つを選択して、 その条項と条件に従ってください。 「プログラム」中に本使用許諾のバージョン番号の指定がない場合は、 Free Software Foundation が公表したどのバージョンでも選択することができます。
英文文書(GNU General Public License)を正式文書とする。 この和文文書は弁護士の意見を採り入れて、 できるだけ正確に英文文書を翻訳したものであるが、 法律的に有効な契約書ではない。
いかなる媒体でも次の条件がすべて満たされている場合に限り、 本和文文書をそのまま複写し配布することを許可する。 また、あなたは第三者に対して本許可告知と同一の許可を与える場合に限り、 再配布することが許可されています。
あなたが新しくプログラムを作成し、それを公用に供したい場合は、 プログラムをフリー・ソフトウェアにして、 全ての人々が以上の各条項に従ってこれを再頒布や変更をすることが できるようにするのが最良の方法です。
そうするためには、プログラムに以下の表示をしてください。 その場合、無保証であるということを最も効果的に伝えるために、 ソース・ファイルの冒頭にその全文を表示すれば最も安全ですが、 その他の方法で表示する場合でも、「著作権表示」と全文を読み出す為の アドレスへのポインタだけはファイル上に表示しておいてください。
プログラム名とどんな動作をするものかについての簡単な説明の行 Copyright(C) 19○○年、著作権者名 本プログラムはフリー・ソフトウェアです。 あなたは、Free Software Foundationが公表したGNU 一般公有使用許諾の 「バージョン2」或いはそれ以降の各バージョンの中からいずれかを選択し、 そのバージョンが定める条項に従って本プログラムを 再頒布または変更することができます。 本プログラムは有用とは思いますが、頒布にあたっては、 市場性及び特定目的適合性についての暗黙の保証を含めて、 いかなる保証も行ないません。 詳細についてはGNU 一般公有使用許諾書をお読みください。 あなたは、本プログラムと一緒にGNU一般公有使用許諾の写しを 受け取っているはずです。 そうでない場合は、
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA 2 へ手紙を書いてください。
また、ユーザが電子メイルや書信であなたと連絡をとる方法についての情報も 書き添えてください。
プログラムが対話的に動作する場合は、 対話モードで起動した時に次のような短い告知文が表示されるようにしてください。
Gnomovision バージョン69、Copyright(C)19○○年 著作権者名 Gnomovision は完全に無保証です。詳細は show w とタイプしてください。 これはフリー・ソフトウェアなので、特定の条件の下でこれを再頒布する ことができます。詳細は show c とタイプしてください。
上記のshow w
やshow c
は各々、
本一般公有使用許諾の関連する部分を表示するコマンドを指します。
もちろん、あなたが使うこれらのコマンドはshow w
やshow c
といった
呼び名でなくても構いません。
さらに、それらのコマンドはあなたのプログラムに合わせる為に、
マウスでクリックしたりメニュー形式にすることもできます。
また、必要と認めた場合には、あなたの雇い主 (あなたがプログラマとして働いている場合)や在籍する学校から、 そのプログラムに対する「著作権放棄」を認めた署名入りの書面を入手してください。 ここにその文例を載せます。名前は変えてください。
Yoyodyne, Inc. は、James Hacker が開発したプログラム`Gnomovision' (コンパイラにつなげるプログラム)についての著作権法上の全ての権利を放棄する。 Ty Coon の署名, 1 April 1989 Ty Coon, 副社長
本一般公有使用許諾は、あなたのプログラムを財産権の対象となっている 他のプログラムに組み込むことは認めていません。 あなたのプログラムがサブルーチン・ライブラリであって、 あなたがそのライブラリを財産権の対象となっている他のアプリケーションと リンクさせることによって、さらに有用なものにしようとする場合には、 本使用許諾書の代わりに、GNUライブラリ一般公有使用許諾書に従ってください。
GNU Emacsテキストエディタの大部分は、 Emacs Lispと呼ばれるプログラム言語で記述してあります。 Emacs Lispで新たなコードを書いて、 それをエディタの拡張としてインストールできます。 しかし、Emacs Lispは、単なる『拡張言語』ではありません。 それ自身、れっきとしたプログラム言語です。 他のプログラム言語でできることは、Emacs Lispでできます。
Emacs Lispは、エディタで使うために設計してあるため、 ファイル、バッファ、ディスプレイ、サブプロセスなどを扱う機能に加えて、 テキストを走査し解析する特別な機能もあります。 Emacs Lispは編集機構に密に組み込まれています。 このため、編集コマンドはLispプログラムからも呼び出せる関数ですし、 カスタマイズのためのパラメータは普通のLisp変数です。
本書は、Emacs Lispを完全に記述することを目指しています。 初心者向けの入門には、Free Software Foundation刊、 Bob ChassellのAn Introduction to Emacs Lisp Programming 3 をご覧ください。 本書では、Emacsの操作を熟知しているものと仮定します。 操作に関する基本的な情報は、The GNU Emacs Manual 4 を参照してください。
おおまかにいえば、始めのほうの章では、 多くのプログラム言語に見られる機能に相当するEmacs Lispの機能を説明し、 あとのほうの章では、 Emacs Lispに特有の機能や編集に特化した機能を説明します。
本書は、2.5版です。
本書は、数多くの草稿を重ねてきました。 ほぼ完璧に近いはずですが、誤りは皆無ではありません。 ふれていない話題も少なからずあります。 (大部分の個別のモードのような)副次的と捉えている話題や、 まだ執筆していない話題もあります。 完全にはこれらに対処しきれませんので、 意図的に省いたことがらもあります。 たとえば、VMSにおける利用方法に関する情報です。
本書で取り上げたことがらに関しては、本書は完璧であるべきですから、 例題や記述内容から章や節の構成順序といったことまで、 広く意見を求めています。 混乱を招くような記述や、本書でふれていないことがらを 学ぶためにソースや実験で調べる必要があるときには、 本書を改訂すべきなのでしょう。 そのときは、ぜひ、教えてください。
意見や訂正は、下記へメイルしてください。
bug-lisp-manual@gnu.org
ここに蓄積されたメイルは、誰かが改訂作業を始めるまでは、読み出しません。
改訂までに、数か月、ときには、数年経過することもあります。
ですから、返事がないと憤慨しないでください。
あなたのメイルは、そのうち処理されます。
Emacs保守グループに迅速に連絡したい場合には、
bug-gnu-emacs@gnu.org
にメイルしてください。
Lisp(LISt Processing language、リスト処理言語)は、 人工知能の研究向けに1950年代末にMITで初めて開発されました。 Lisp言語はとても強力なので、 エディタコマンドを記述するなどの他の目的にも理想的なのです。
長年にわたって何ダースものLispが実装されており、 それぞれが独自の特徴を有しています。 その多くは、1960年代のMITのMACプロジェクトで開発されたMaclispの 影響を受けています。 最終的には、Maclispの系統の実装者達は共同して、 Common Lispと呼ばれるLispシステムの規格を開発しました。 そうこうするうちに、MITのGerry SussmanとGuy Steeleは、 単純化してあるが非常に強力なSchemeと呼ばれるLispの方言を開発しました。
GNU EmacsはMaclispの影響を強く受けていますが、 Common Lispからの影響は少ないです。 Common Lispを知っている読者は、 Common Lispとの多くの類似点に気づかれるでしょう。 しかしながら、Common Lispの多くの機能は、 省いてあるか、単純化してあります。 これは、GNU Emacsが必要とするメモリ量を削減するためです。 ときには、劇的に単純化してあるために、 Common Lispユーザーは混乱するかもしれません。 GNU Emacs LispとCommon Lispとの相違点は、 ことあるごとに指摘するつもりです。 Common Lispを知らない読者は、何も心配することはありません。 本書は自己完結しています。
cl
ライブラリにより、Common Lispをかなりエミュレートできます。
See Top。
Emacs LispはSchemeの影響をまったく受けていません。 しかし、GNUプロジェクトには、Guileと呼ばれるSchemeの実装があります。 拡張が必要なすべての新たなGNUソフトウェアではGuileを使います。
本節では、本書で用いる表記法を説明します。 本節を読み飛ばして、あとで参照してもかまいません。
nil
and t
are used.
本書では、『Lispリーダ』および『Lispプリンタ』という言葉で、 Lispオブジェクトのテキスト表現を実際のLispオブジェクトに変換する Lisp内部のルーティン群、および、逆の変換を行うルーティン群を指します。 詳しくは、See Printed Representation。 本書の読者を『プログラマ』と考えて『読者』と呼びます。 『ユーザー』とは作者自身を含めたLispプログラムを使う人のことです。
Lispコードの例は、(list 1 2 3)
という形式で、
このフォントで記します。
メタな変数の名前や説明対象の関数に対する引数の名前は、
first-numberという形式で、このフォントで書きます。
nil
とt
Lispでは、シンボルnil
には3つの異なる意味があります。
まず、nil
という名前のシンボルです。
2つめは、真理値の偽(false)です。
3つめは、空リスト、つまり、要素数が0個のリストです。
変数として使った場合、nil
の値はつねにnil
です。
Lispリーダにとっては、()
とnil
は同一です。
どちらも、同じオブジェクト、シンボルnil
を表します。
シンボルを異なった書き方にするのは、完全に人間向けです。
()
やnil
をLispリーダが読み取ったあとでは、
プログラマが実際にどちらの表記を用いたかわかりません。
本書では、空リストを強調するときには()
を使い、
真理値の偽を強調するときにはnil
を使います。
これは、Lispプログラムでも使うとよい慣習です。
(cons 'foo ()) ; 空リストであることを強調する (not nil) ; 真理値の偽であることを強調する
真理値の真を必要とする場面では、
nil
以外の値は、真(true)であるとみなします。
しかし、真を表す望ましい書き方はt
です。
真を表す値が必要なとき、
適当な判断基準がない場合にはt
を使います。
シンボルt
の値はつねにt
です。
Emacs Lispでは、nil
とt
は特別なシンボルであり、
評価するとそれ自身になります。
そのため、これらをプログラム内で定数として使うとき、
これらをクォートする必要はありません。
これらの値を変更しようとすると、エラーsetting-constant
になります。
コロン(:
)で始まる名前のシンボルも同様です。
See Constant Variables。
評価可能なLisp式をフォーム(form、形式)と呼びます。
フォームを評価すると、Lispオブジェクトである結果を生じます。
本書の例題では、これを=>
で表します。
(car '(1 2)) => 1
これは、『(car '(1 2))
を評価すると1になる』と読みます。
フォームがマクロ呼び出しの場合には、
Lispが評価すべき新たなフォームに展開します。
展開結果を==>
で表します。
展開したフォームの評価結果を示す場合もあれば、
示さない場合もあります。
(third '(a b c)) ==> (car (cdr (cdr '(a b c)))) => c
あるフォームを説明するときに、
同一の結果を生じる別のフォームを示すことがあります。
2つのまったく等価なフォームを==
で表します。
(make-sparse-keymap) == (list 'keymap)
本書の数多くの例題は、評価するとテキストを表示します。
(*scratch*
バッファのような)Lisp対話バッファで例題のコードを
実行すると、表示テキストはバッファに挿入されます。
(関数eval-region
で評価するなどの)
別の手段で例題を実行すると、表示テキストはエコー領域に表示されます。
エコー領域に表示されるテキストは、1行に切り詰められていることに
注意してください。
本書の例題では、表示場所には無関係に、
表示テキストを-|
で表します。
フォームを評価した結果返される値(ここではbar
)は、
後続の行に分けて書きます。
(progn (print 'foo) (print 'bar)) -| foo -| bar => bar
エラーを通知する例題もあります。
これは、通常、エコー領域にエラーメッセージを表示します。
エラーメッセージは、error-->
で始まる行に示します。
エコー領域には、error-->
は表示されないことに注意してください。
(+ 23 'x) error--> Wrong type argument: number-or-marker-p, x
バッファ内のテキストを修正する例題もあります。
このような場合、『実行前』と『実行後』のテキストを示します。
それらの例題では、バッファ名を含めたダッシュから成る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 ----------
関数、変数、マクロ、コマンド、ユーザーオプション、 スペシャルフォームは、本書では統一した形式で記述します。 第1行目は、それぞれの名前と、引数があれば引数群です。 これに説明文が続き、場合によっては例題も示します。
foo
.
electric-future-map
.
関数の記述では、まず始めに説明対象の関数名があります。 同じ行には、引数名の並びも続きます。 これらの名前は、説明文の中で引数の値を参照するために使います。
引数ならびにキーワード&optional
が現れていれば、
それ以降の引数を省略できることを示します(省略した引数の値はnil
)。
関数を呼び出すときに&optional
を書いてはいけません。
キーワード&rest
(このあとには1つの引数名だけが続く)は、
残りの引数が何個でもよいことを示します。
直後にある1つの引数名は、変数としての値を持ち、
その値は残りのすべての引数のリストです。
関数を呼び出すときに&rest
を書いてはいけません。
では、仮想的な関数foo
の記述を以下に示します。
foo integer1 &optional integer2 &rest integers | Function |
関数foo は、integer2からinteger1を引き算し、
残りのすべての引数を減算結果に加える。
integer2を指定しないと、デフォルトでは、数19から引き算する。
(foo 1 5 3 9) => 16 (foo 5) => 14 より一般的には、つぎのとおり。 (foo w x y...) == (+ (- x w) y...) |
(integer、integer1、bufferなどの)型名を名前とする引数は、 その型の値であると仮定します。 (buffersのように)型を複数形にした場合には、 しばしば、その型のオブジェクトのリストを意味します。 objectという名前の引数は、任意の型でかまいません。 (Emacsオブジェクトの型の一覧については、see Lisp Data Types)。 (new-fileなどの)その他の名前の引数は、関数の説明文の中で言及します。 複数の関数の引数に共通する特徴について、 節の始めで説明する場合もあります。
&optional
と&rest
についての詳しい説明は、
See Lambda Expressions。
コマンド、マクロ、スペシャルフォームの記述も同じ形式ですが、 「関数」のかわりに 「コマンド」、「マクロ」、「スペシャルフォーム」のいずれかです。 コマンドは、対話的に呼び出せる単なる関数です。 マクロは関数とは違った方法で引数を処理します(引数を評価しない)が、 同じ方法で引数を記します。
スペシャルフォームの記述では、省略可能な引数や繰り返される引数を
示すために、より複雑な記法を使います。
というのは、引数並びを個々の引数に分離する方法が複雑だからです。
[optional-arg]
は、
optional-argが省略可能であることを示します。
また、repeated-args...
は、0個以上の引数を示します。
いくつかの引数をリスト構造の内側にまとめるときには、
括弧を使います。
count-loop (var [from to [inc]]) body... | Special Form |
この仮想的なスペシャルフォームは、
フォーム群bodyを実行してから変数varを増やすことを
反復するループを実現する。
最初は、変数の値はfromである。
以降の反復では、変数を1(あるいは、指定があればincだけ)増やす。
varがtoに等しくなると、
bodyを実行せずにループから抜ける。
例を示す。
(count-loop (i 0 10) (prin1 i) (princ " ") (prin1 (aref vector i)) (terpri)) fromとtoを省略すると、
ループ開始前にvarに (count-loop (done) (if (pending) (fixit) (setq done t))) このスペシャルフォームでは、引数fromとtoは省略できるが、 両者を同時に指定するか、同時に省略すること。 これらを指定した場合、incを指定してもよい。 これらの引数は、引数varとともにリストにまとめる。 これはbodyと区別するためであり、 bodyは残りのフォームの要素すべてを含む。 |
変数(variable)は、値を保持するための名前です。 ユーザーはどんな変数でも設定できますが、 ユーザーが変更可能な特定の変数群があり、 それらをユーザーオプション(user options)と呼びます。 普通の変数もユーザーオプションも関数の記述と同じ形式で示しますが、 それらに引数はありません。
仮想的な変数electric-future-map
の記述例を示します。
electric-future-map | Variable |
この変数の値は、Electric Command Futureモードで使用する 完全なキーマップである。 このマップに含まれる関数は、まだ実行していないコマンドの編集を可能にする。 |
ユーザーオプションの記述も同じ形式ですが、 「変数」のかわりに「ユーザーオプション」です。
これらの機構は、使用中のEmacsの版に関する情報を提供します。
emacs-version | コマンド |
この関数は、実行中のEmacsの版を記述した文字列を返す。
この文字列はバグの報告に含めると有益である。
(emacs-version) => "GNU Emacs 20.3.5 (i486-pc-linux-gnulibc1, X toolkit) of Sat Feb 14 1998 on psilocin.gnu.org" 対話的に呼び出すと、この関数は同じ情報をエコー領域に表示する。 |
emacs-build-time | Variable |
この変数の値は、ローカルのサイトでEmacsを構築した日時を示す。
3つの整数から成るリストであり、
current-time と同様のもの(see Time of Day)。
emacs-build-time => (13623 62065 344633) |
emacs-version | Variable |
この変数の値は、実行中のEmacsの版番号。
"20.3.1" のような文字列である。
この文字列の最後の数字は、Emacsのリリース版番号の一部ではなく、
特定のディレクトリでEmacsを構築するたびに増える。
|
つぎの2つの変数は、Emacs 19.23以降に存在します。
emacs-major-version | Variable |
Emacsのメジャー版番号を表す整数。 Emacs 20.3では、値は20。 |
emacs-minor-version | Variable |
Emacsのマイナ版番号を表す整数。 Emacs 20.3では、値は3。 |
本書は、Robert Krawitz、Bil Lewis、Dan LaLiberte、 Richard M. Stallman、Chris Welty、GNUマニュアルプロジェクトのボランティア による何年にもわたる努力で執筆されました。 Computational Logic社のWarren A. Hunt, Jr.が手配した 国防省Advanced Research Projects Agency、ARPA Order 6082の援助のもと、 Robert J. Chassellは本書のレビューと編集に協力してくれました。
以下の方々が訂正を送ってくれました。 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、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、Skip Montanaro、John Gardiner Myers、Thomas A. Peterson、 Francesco Potorti、Friedrich Pukelsheim、Arnold D. Robbins、Raul Rockwell、Per Starback、Shinichirou Sugou、Kimmo Suominen、Edward Tharp、 Bill Trost、Rickard Westman、Jean White、Matthew Wilding、Carl Witty、 Dale Worley、Rusty Wright、David D. Zuhn。
Lispオブジェクト(object)とは、 Lispプログラムが使用し操作するデータのことです。 型(type)やデータ型(data type)とは、ここでは、 可能なオブジェクトの集合を意味します。
各オブジェクトは、少なくとも、1つの型に属します。 同じ型のオブジェクトは、構造に類似性があり、普通、同じ文脈で使われます。 型は互いに重複していてもよく、オブジェクトは複数の型に属することができます。 そのため、オブジェクトが特定の型に属するかどうかは判断できますが、 オブジェクトの型を『1つ』に限定することはできません。
Emacsには少数の基本オブジェクト型を組み込んであります。 これらの型は他のすべてのオブジェクト型を構成するもとであり、 基本型(primitive types)と呼びます。 各オブジェクトはたった1つの基本型に属します。 基本型には、 整数(integer)、浮動小数点数(float)、 コンス(cons)、シンボル(symbol)、 文字列(string)、ベクトル(vector)、subr、 バイトコード関数(byte-code function)、 ならびに、編集に関連するバッファ(buffer)などの 特別な型があります。 (see Editing Types。)
各基本型には、その型に属するオブジェクトであるかどうかを検査する 対応するLisp関数があります。
Lispオブジェクトは型を自己記述(self-typing)するという点で、 Lispは他の多くの言語とは異なります。 つまり、オブジェクトの基本型は、オブジェクト自体に暗に含まれています。 たとえば、オブジェクトがベクトルであれば、それを数と扱うことはありません。 Lispには、ベクトルは数ではないとわかっているのです。
多くの言語では、プログラマは各変数のデータ型を宣言する必要があります。 型はコンパイラが知っているのであって、データの中には入っていません。 このような型宣言はEmacs Lispには存在しません。 Lisp変数はどんな型の値でも保持でき、 変数に入れた値と型を記録しています。
本章では、GNU Emacs Lispの各標準型の表示表現と入力構文を説明します。 これらの型の使用方法の詳細は、あとの章に譲ります。
オブジェクトの表示表現(printed representation)とは、
Lispプリンタ(関数prin1
)がそのオブジェクトを出力表示するときの
書式です。
オブジェクトの入力構文(read syntax)とは、
Lispリーダ(関数read
)がそのオブジェクトを入力として受理する書式です。
See Read and Print。
ほとんどのオブジェクトには1つ以上の可能な入力構文があります。 ある種の型のオブジェクトには入力構文はありませんが、 そのような型のオブジェクトをLispプログラムに直接入力する意味がないからです。 このような場合を除くと、 オブジェクトの表示表現はそのオブジェクトの入力構文でもあります。
他の言語では、式はテキストであって、これ以外の形はありません。 Lispでは、式はとにかくLispオブジェクトであって、 オブジェクトの入力構文であるテキストは副次的なものです。 この違いを強調する必要はありませんが、 このことを心に留めておかないと混乱することがあります。
各型には表示表現があります。
入力構文のない型もあります。
たとえば、バッファ型には入力構文はありません。
このような型のオブジェクトはハッシュ記法(hash notation)で表示します。
つまり、文字列#<
のあとに説明用の文字列
(典型的には型名にオブジェクトの名前を続けたもの)を続け、
対応する>
で閉じます。
ハッシュ記法を読み取ることはできませんから、
Lispリーダが#<
に出会うとエラーinvalid-read-syntax
を
通知します。
(current-buffer) => #<buffer objects.texi>
読者が対話的に式を評価するとき、
Lispインタープリタは、まず、
式のテキスト表現を読み取ってLispオブジェクトを生成し、
そのオブジェクトを評価します(see Evaluation)。
しかしながら、評価と読み取りは別々の動作です。
読み取りでは、読み取ったテキストが表すLispオブジェクトを返します。
このオブジェクトを、のちに評価する場合もありますが、
評価しない場合もあります。
オブジェクトを読み取る基本関数read
については、
See Input Functions。
コメント(comment)は、プログラム内に書かれたテキストであり、
プログラムを読む人間のためだけにあり、
プログラムの意味にはまったく影響しません。
Lispでは、文字列や文字定数の外にあるセミコロン(;
)で
コメントを始めます。
コメントは行末までです。
Lispリーダは、コメントを破棄します。
コメントは、
Lispシステム内部でプログラムを表すLispオブジェクトの一部にはなりません。
#@count
という書き方は、
後続のcount個の文字を飛び越します。
これは、プログラムで生成したバイナリデータを含むコメントに便利です。
Emacs Lispのバイトコンパイラは、出力ファイルにこのようなコメントを使います
(see Byte Compilation)。
しかしながら、ソースファイル向きではありません。
コメントの体裁に関する慣習については、See Comment Tips。
Emacs Lispには、大きく2種類の型があります。 Lispのプログラミングに関わるものと、編集に関わるものです。 前者は、さまざまな形でLispの多くの実装に見られます。 後者は、Emacs Lispに固有です。
t
or nil
.
Emacs Lispにおける整数の値の範囲は、ほとんどの計算機では、
-134217728から134217727(28ビット長。つまり
から
です。
(計算機によっては、より広い範囲になる。)
Emacs Lispの算術演算関数は、桁溢れ(オーバフロー)を
検査しないことを覚えておいてください。
したがって、ほとんどの計算機では、
(1+ 134217727)
は-134217728となります。
整数の入力構文は、(10を基数とした)数字の並びであり、
先頭に符号があってもよく、また、最後にピリオドがあってもかまいません。
Lispインタープリタが生成する表示表現では、
先頭の+
や最後の.
はありません。
-1 ; 整数 -1 1 ; 整数 1 1. ; これも整数 1 +1 ; これも整数 1 268435457 ; 28ビット長整数では、これも整数 1
より詳しくは、See Numbers。
Emacsは浮動小数点数を扱えます (ただし、コンパイル時のオプションで使用不可にできる)。 浮動小数点数の範囲は、計算機に依存します。
浮動小数点数の表示表現には、
小数点(に続けて1桁以上の小数部分)または指数、
あるいは、その両方が必要です。
たとえば、1500.0
、15e2
、15.0e2
、
1.5e3
、.15e4
は、同じ1500という値の
浮動小数点数を書く5つの方法です。
どれも、まったく等価です。
詳しくは、See Numbers。
Emacs Lispにおける文字(character)は、 整数以外の何物でもありません。 いいかえれば、文字はその文字コードで表現されます。 たとえば、文字Aは整数 65と表現されます。
プログラムで個々の文字を独立に使うことはあまりありません。 文字を並べた文字列(strings)として扱うことが断然多いのです。 See String Type。
文字列内、バッファ内、ファイル内の文字は、 現時点では、0から524287までの範囲、19ビット長に制限されます。 しかし、この範囲の値すべてが正しい文字コードではありません。 0から127までのコードはASCIIコードです。 それ以外は、非ASCIIです(see Non-ASCII Characters)。 キーボード入力を表す文字は、コントロール、メタ、シフトなどの 修飾キーを符号化するために、範囲がより広くなります。
文字は、実際には整数ですから、文字の表示表現は10進数です。 また、文字の入力構文として10進数も可能ですが、 Lispプログラムでこのように文字を書くのは最悪です。 Emacs Lispに用意してある文字向けの特別な入力構文を つねに使うべきです。 これらの構文は疑問符で始まります。
英数字向けの普通の入力構文は、疑問符に続けて1つの英数字を書きます。
したがって、文字Aは?A
、文字Bは?B
、
文字aは?a
と書きます。
たとえば、つぎのとおりです。
?Q => 81 ?q => 113
同じ入力構文を句読点文字にも使えますが、
\
を追加して、Lispコードを編集するEmacsコマンドが混乱しないように
することがよいでしょう。
たとえば、空白文字は?\
と書きます。
文字\
は、クォートするために2つめの\
を使う必要があり
?\\
です。
コントロールg、バックスペース、タブ、改行、
垂直タブ、ページ送り、復帰、エスケープは、
それぞれ、?\a
、?\b
、?\t
、?\n
、?\v
、
?\f
、?\r
、?\e
と書きます。
つまり、つぎのとおりです。
?\a => 7 ; C-g ?\b => 8 ; バックスペース、 <BS>、C-h ?\t => 9 ; タブ、 <TAB>、C-i ?\n => 10 ; 改行、C-j ?\v => 11 ; 垂直タブ、C-k ?\f => 12 ; ページ送り文字、C-l ?\r => 13 ; 復帰、<RET>, C-m ?\e => 27 ; エスケープ文字、<ESC>、C-[ ?\\ => 92 ; バックスラッシュ文字、\
バックスラッシュで始まる系列は エスケープシーケンス(escape sequences)とも呼びます。 バックスラッシュが、エスケープ文字の役割を果たすからです。 この使い方は、文字<ESC>とは関係ありません。
コントロール文字は別の入力構文でも表現できます。
疑問符に続けてバックスラッシュ、カレット(^
)、そして、
対応するコントロールでない文字を大文字か小文字で書きます。
たとえば、?\^I
も?\^i
も、
値が9である文字C-iの正しい入力構文です。
カレットのかわりに、C-
を使ってもかまいません。
ですから、?\C-i
は、?\^I
や?\^i
と等価です。
?\^I => 9 ?\C-I => 9
文字列やバッファ内ではASCIIのコントロール文字だけが許されますが、
キーボード入力においてはC-
で任意の文字をコントロール文字にできます。
これらの非ASCIIコントロール文字の文字コードは、
対応する非コントロール文字の文字コードと
のビットを含みます。
普通の端末では、非ASCIIコントロール文字を生成する手立てはありませんが、
Xウィンドウシステムや他のウィンドウシステムでは、
簡単に生成できます。
歴史的な理由で、 Emacsは<DEL>文字を?に対応したコントロール文字として扱います。
?\^? => 127 ?\C-? => 127
その結果、今のところ、
Xウィンドウシステムのもとでは意味のある文字Control-?を
\C-
では表現できません。
ファイルや文字列に現れるコントロール文字を表現するには、
^
構文を勧めます。
キーボード入力のコントロール文字には、C-
構文が好ましいです。
どちらを使ってもプログラムの意味には影響しませんが、
それを読む人には理解の手助けになるかもしれません。
メタ文字(meta character)は、 <META>修飾キーを使って打った文字です。 そのような文字を表す整数は、(ほとんどの計算機では負の数になる) のビットがセットされています。 上位のビットをメタや他の修飾子に用いることで、 基本となる文字コードの範囲をできるだけ大きくします。
文字列では、メタ文字を表すASCII文字には のビットを付加します。 つまり、文字列に収められるメタ文字のコードは128から255の範囲であり、 任意のASCII文字のメタ変種を使えます。 (Emacs 18やそれ以前では、この方式を文字列の外にある文字にも使っていた。)
メタ文字の入力構文には\M-
を使います。
たとえば、?\M-A
はM-Aです。
\M-
と一緒に8進文字コードも使えますし(下記参照)、
\C-
や文字向けの他の構文も使えます。
したがって、M-Aは?\M-A
と書いたり?\M-\101
と書けます。
同様に、C-M-bは?\M-\C-b
、
?\C-\M-b
、?\M-\002
と書けます。
図形文字の大文字小文字は、その文字コードで示されます。
たとえば、ASCIIではa
とA
の文字を区別します。
しかし、ASCIIではコントロール文字の大文字小文字を表現できません。
Emacsでは、コントロール文字を打つときに使ったシフトキーを表すために
のビットを付加します。
このような区別はX端末や他の特別な端末を使っている場合に限り可能です。
普通の端末ではこのような区別を計算機に送れません。
Xウィンドウシステムでは、
文字に設定可能な修飾ビットが他に3つあります。
ハイパー(hyper)、スーパー(super)、アルト(alt)です。
これらの修飾ビットの構文は、
\H-
、\s-
、\A-
です。
(これらのプレフィックスでは、大文字小文字を区別する。)
したがって、?\H-\M-\A-x
はAlt-Hyper-Meta-xを表します。
文字向けのもっとも汎用の入力構文では、
文字コードを8進数や16進数で表現します。
8進数を使うには、順に、
疑問符、バックスラッシュ、(3桁までの)8進数字文字コードを書きます。
たとえば、?\101
は文字Aを表し、
?\001
は文字C-aを表し、?\002
は文字C-bを表します。
この構文で任意のASCII文字を表現できますが、
ASCIIでの表現よりも8進数値で表現することが重要な場合に限るべきです。
?\012 => 10 ?\n => 10 ?\C-j => 10 ?\101 => 65 ?A => 65
16進数を使うには、順に、疑問符、バックスラッシュ、
x
、16進数字文字コードを書きます。
16進数の桁数はいくつでもよいので、任意の文字コードを表現できます。
したがって、?\x41
は文字Aを表し、
?\x1
は文字C-aを表し、
?\x8e0
は
特別なエスケープの意味を持たないどんな文字のまえにもバックスラッシュを
付けることができ、しかも、無害です。
したがって、?\+
は?+
に等価です。
ほとんどの文字のまえにバックスラッシュを付ける理由はありません。
しかしながら、Lispコードを編集するEmacsコマンドが混乱しないように、
()\|;'`"#.,
のいずれかの文字のまえにはバックスラッシュを付けるべきです。
空白、タブ、改行、ページ送りのような白文字のまえにも
バックスラッシュを付けるべきです。
しかしながら、タブなどの実際の白文字のかわりに、
\t
などの読みやすいエスケープシーケンスを使ったほうが明確です。
GNU Emacs Lispにおけるシンボル(symbol)は、 名前を持ったオブジェクトです。 シンボル名は、シンボルの表示表現としての役割があります。 普通の使い方では、名前は一意です。 つまり、2つのシンボルが同じ名前を持つことはありません。
シンボルは、変数としての役割、関数名としての役割、 あるいは、属性リストを保持する役割を果たします。 また、他のすべてのLispオブジェクトと区別するためだけの役割を 果たすこともあり、データ構造の内部にそのようなシンボルが存在することを 正確に認識できます。 ある場面においては、普通、これらのうちの1つの使い方をします。 しかし、ある1つのシンボルに対してすべての使い方をしてもかまいません。
シンボル名には、どんな文字でも含められます。
ほとんどのシンボル名は、英文字、数字、-+=*/
の句読点文字で書かれます。
そのような名前では、特別な書き方は必要ありません。
名前が数に見えなければ、名前を構成する文字はなんでもよいのです。
(名前が数に見えるときには、
名前の先頭に\
を書いてシンボルであると強制する。)
_~!@$%^&:<>{}
の文字はあまり使われませんが、
これらにも特別な書き方は必要ありません。
これら以外の文字は、バックスラッシュでエスケープすれば、
シンボル名に含められます。
文字列におけるバックスラッシュの用法とは対照的に、
シンボル名におけるバックスラッシュは、直後の1文字をクォートするだけです。
たとえば、文字列では\t
はタブ文字を表しますが、
シンボル名では英文字t
をクォートするだけです。
名前にタブ文字を含むシンボルを書くには、
実際に(バックスラッシュの直後に)タブを使う必要があります。
しかし、そのようなことをするのは皆無でしょう。
Common Lispに関した注意:
Common Lispでは、小文字を明示的にエスケープしない限り、
小文字をつねに大文字に『変換』する。
Emacs Lispでは、大文字と小文字を区別する。
シンボル名の例をいくつかあげましょう。
5番目の例の+
は、数として読まれるのを防ぐために
エスケープしてあることに注意してください。
6番目の例では、これは必要ありません。
なぜなら、名前の残りの部分が数としては不正だからです。
foo ;foo
という名前のシンボル FOO ;FOO
という名前のシンボル、foo
とは別 char-to-string ;char-to-string
という名前のシンボル 1+ ;1+
という名前のシンボル ; (整数の+1
ではない) \+1 ;+1
という名前のシンボル ; (読みにくい名前) \(*\ 1\ 2\) ;(* 1 2)
という名前のシンボル(悪い名前) +-*/_~!@$%^&=:<>{} ;+-*/_~!@$%^&=:<>{}
という名前のシンボル ; これらの文字をエスケープする必要はない
シーケンス(sequence)とは、 要素の順序集合を表現するLispオブジェクトです。 Emacs Lispには2種類のシーケンス、つまり、リストと配列があります。 したがって、リスト型や配列型のオブジェクトは、 シーケンス型でもあると考えられます。
配列はさらに、文字列、ベクトル、文字テーブル、ブールベクトルに細分されます。
ベクトルは任意の型の要素を保持できますが、
文字列の要素は文字である必要があり、
ブールベクトルの要素はt
かnil
のいずれかである必要があります。
バッファ内の文字のように、
文字列内の文字はテキスト属性を持てます(see Text Properties)。
ベクトルとブールベクトル
5
では、それらの要素が文字であったとしても、
テキスト属性を扱えません。
文字テーブルは、ベクトルに似ていますが、正しい文字コードで添字付けします。
リスト、文字列、および、その他の配列型は別のものですが、
それらには重要な類似性があります。
たとえば、それらすべてに長さlがあり、
それらのすべての要素は0からl-1で添字付けできます。
シーケンス関数と呼ばれるいくつかの関数は、
任意のシーケンス型を扱います。
たとえば、シーケンスから指定した添字の要素を取り出すには、
関数elt
を使います。
See Sequences Arrays Vectors。
一般には、同一のシーケンスを二度読み取ることは不可能です。
というのは、読むたびにつねに新たにシーケンスを作成するからです。
シーケンスの入力構文を二度読むと、
同じ内容の2つのシーケンスを得ることになります。
1つ例外があります。
空リスト()
は、つねに同じオブジェクトnil
を表します。
コンスセル(cons cell)とは、 CARスロットおよびCDRスロットと呼ばれる 2つのポインタから成るオブジェクトです。 各スロットは、任意のLispオブジェクトを指すことができます。 また、現在CARスロットが指しているオブジェクトがなんであれ、 『コンスセルのCARは』といったいい方をします。 CDRについても同様です。
リスト(list)はコンスセルが連なったものであり、 各コンスセルのCDRスロットは、 後続のコンスセルを指すか空リストを指します。 リストに作用する関数については、See Lists。 ほとんどのコンスセルは、リストの一部分として使われるので、 リスト構造(list structure)という用語は、 コンスセルから成る任意の構造のことを意味します。
CARやCDRという名称は、Lispの歴史に由来します。
最初のLispはIBM 704で動作していました。
この計算機では、ワードを2つの部分、『番地』(address)部分、
『減数』(decrement)部分と呼ばれるものに分けていました。
CARはレジスタの番地部分の内容(Contents of Address Register)を
取り出す命令であり、
CDRはレジスタの減数部分の内容(Contents of Decrement Register)を
取り出す命令でした。
一方、『コンスセル』という名称は、
これらを作成する関数cons
からきています。
この関数名は、その目的、セルを作る(construction of cells)からきています。
コンスセルはLispの核心なので、 『コンスセルではないオブジェクト』に対する名称もあります。 これらのオブジェクトをアトム(atoms)と呼びます。
リストの入力構文と表示表現は同一です。 開き括弧で始まり、任意個の要素、閉じ括弧で終えます。
読み取り時には、括弧の内側の各オブジェクトが、
リストの各要素になります。
つまり、これらの要素からなるコンスセルを作ります。
コンスセルのCARスロットで要素を指します。
同じコンスセルのCDRスロットで、
リスト上のつぎの要素を保持している、
リストのつぎのコンスセルを指します。
最後のコンスセルのCDRスロットはnil
を指します。
リストは、コンスセルを1対の箱で表して図示できます。
(Lispリーダがこのような図表示を読むことはない。
人間や計算機が理解できるテキスト表記と違い、
箱を用いた図表示は人間だけが理解できる。)
つぎの図は、3つの要素から成るリスト(rose violet buttercup)
を表します。
--- --- --- --- --- --- | | |--> | | |--> | | |--> nil --- --- --- --- --- --- | | | | | | --> rose --> violet --> buttercup
この図で、各箱は、任意のLispオブジェクトを指すことができるスロットを表します。 箱の対でコンスセルを表します。 各矢印は、アトムや他のコンスセルであるLispオブジェクトを指すポインタです。
この例では、最初のコンスセルのCARを表す最初の箱は、
rose
(シンボル)を指しています。
あるいは、rose
(シンボル)を『含んでいる』ともいいます。
最初のコンスセルのCDRを表す2番目の箱は、
つぎの1対の箱、2番目のコンスセルを指しています。
2番目のコンスセルのCARはviolet
であり、
このコンスセルのCDRは3番目のコンスセルです。
3番目の(最後の)コンスセルのCDRは、nil
です。
同じリスト(rose violet buttercup)
を
別の方法で図表示するとつぎのようになります。
--------------- ---------------- ------------------- | car | cdr | | car | cdr | | car | cdr | | rose | o-------->| violet | o-------->| buttercup | nil | | | | | | | | | | --------------- ---------------- -------------------
内部に要素を持たないリストは、空リスト(empty list)です。
これはシンボルnil
と同一です。
いいかえれば、nil
はシンボルでもありリストでもあります。
Lispの構文で書き表したリストの例を示します。
(A 2 "A") ; 3要素のリスト () ; 要素を持たないリスト(空リスト) nil ; 要素を持たないリスト(空リスト) ("A ()") ; 文字列"A ()"
だけの1要素のリスト (A ()) ;A
と空リストから成る2要素のリスト (A nil) ; 上と同じ ((A B C)) ; 1要素のリスト ; (その要素は3要素のリスト)
リスト(A ())
や、これと同じ(A nil)
を
箱と矢印で書くとつぎのようになります。
--- --- --- --- | | |--> | | |--> nil --- --- --- --- | | | | --> A --> nil
ドット対記法(dotted pair notation)とは、
CARとCDRを明示したコンスセルを表すもう1つの構文です。
この構文では、(a . b)
で、
CARがオブジェクトaであり
CDRがオブジェクトbであるコンスセルを表します。
したがって、ドット対記法は、リストの構文よりさらに汎用性があります。
ドット対記法では、リスト(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)
という構文は不正です。
これが意味することはなにもありません。
たとえあったとしても、CDRをviolet
用にすでに使っているコンスセルの
CDRにbuttercup
を置けということになります。
リスト(rose violet)
は、(rose . (violet))
に等価であり、
つぎのように図示できます。
--- --- --- --- | | |--> | | |--> nil --- --- --- --- | | | | --> rose --> violet
同様に、3要素のリスト(rose violet buttercup)
は、
(rose . (violet . (buttercup)))
に等価です。
連想リスト(association list)、すなわち、alistは、 各要素がコンスセルであるように特別に構成したリストのことです。 各要素では、CARをキー(key)と考え、 CDRを連想値(associated value)と考えます。 (場合によっては、連想値を、CDRのCARに保持することもある。) 連想リストはスタックとして使われることがままあります。 というのは、リストの先頭に対応関係を追加/削除するのが簡単だからです。
たとえば、
(setq alist-of-colors '((rose . red) (lily . white) (buttercup . yellow)))
は、変数alist-of-colors
に、3要素の連想リストを設定します。
最初の要素では、rose
がキーであり、red
が値です。
連想リストとそれらを操作する関数について詳しい説明は、 See Association Lists。
配列(array)は、任意のLispオブジェクトを指すための 任意個のスロットから成り、メモリの連続した場所に取ります。 配列のどの要素を参照しても、ほぼ同じ時間かかります。 一方、リストの要素を参照するときには、 リスト内の要素の位置に比例した時間が必要です。 (リストの末尾の要素を参照するには、 リストの先頭の要素を参照するより時間がかかる。)
Emacsには、4つの配列型、つまり、 文字列、ベクトル、ブールベクトル、文字テーブルがあります。
文字列は文字の配列であり、
ベクトルは任意のオブジェクトの配列です。
ブールベクトルは、t
やnil
だけを保持できます。
これらの種類の配列は、最大の整数値までなら、任意の長さにできます。
文字テーブルは、正しい文字コードで添字付けする疎な配列であり、
任意のオブジェクトを保持できます。
配列の最初の要素は0で添字付けする、 2番目の要素は1で添字付けする、というようになります。 これをゼロ原点(zero-origin)の添字付けと呼びます。 たとえば、4つの要素からなる配列の添字は、0、1、2、そして、3です。 最大の添字は、配列の長さより1だけ小さくなります。 いったん配列を作成すると、その長さは固定されます。
Emacs Lispのすべての配列は1次元です。 (多くの他のプログラム言語では多次元配列を扱えるが、 それは本質的ではない。 配列の配列を作れば同じ効果を得られる。) 配列のそれぞれの型に応じて、専用の入力構文があります。 詳しくは、以下を参照してください。
配列型はシーケンス型に含まれ、 配列型は、文字型、ベクトル型、ブールベクトル型、文字テーブル型を含みます。
文字列(string)とは文字の配列です。 テキストエディタということから予想されるように、 Emacsではさまざまな目的に文字列を使います。 たとえば、Lispシンボルの名前として、 ユーザーへのメッセージとして、 バッファから取り出したテキストを表現するためなどです。 Lispの文字列は定数です。 つまり、文字列を評価すると同じ文字列になります。
文字列を操作する関数については、See Strings and Characters。
文字列の入力構文は、"like this"
のように、
ダブルクォートで始めて、任意個の文字を書き、ダブルクォートで終えます。
文字列の中にダブルクォートを含めるには、
バックスラッシュを直前に置きます。
つまり、"\""
は、ダブルクォート1個だけから成る文字列です。
同様に、バックスラッシュを含めるには、
"this \\ is a single embedded backslash"
のように、
バックスラッシュを直前に置きます。
文字列の入力構文において、改行文字は特別ではありません。
ダブルクォートのあいだに改行を書けば、
改行は文字列の文字になります。
一方、エスケープした改行、つまり、\
を直前に書くと、
文字列の一部にはなりません。
すなわち、Lispリーダは、文字列を読む際にエスケープした改行を無視します。
エスケープした空白\
も、同様に無視します。
"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."
非ASCIIである国際化文字を文字列に含めるには、 その文字をそのまま書きます。 Emacsの文字列(および、バッファ)では、 非ASCIIの表現方法が2つあります。 ユニバイトとマルチバイトです。 マルチバイトバッファやマルチバイト文字列、あるいは、 マルチバイトとして訪問しているファイルなどの マルチバイトのソースから文字列定数を読み取るときには、 文字をマルチバイト文字として読み取り、 マルチバイト文字列にします。 ユニバイトのソースから文字列定数を読み取るときには、 文字をユニバイト文字として読み取り、 文字列はユニバイトになります。
マルチバイトの非ASCII文字は、
必要な桁数の16進エスケープ\xnnnnnnn
を用いて
書くこともできます。
(マルチバイトの非ASCII文字のコードは、256より大きい。)
16進数字として正しくない文字で16進エスケープを終端します。
16進数字の文字があとに続く場合には、\
(バックスラッシュと空白)と
書いて16進エスケープを終端します。
たとえば、\x8e0\
は、グレーブアクセント付きのa
を表します。
文字列定数内の\
は、バックスラッシュ+改行と同じです。
文字列内の文字には含まれませんが、先行する16進エスケープを終えます。
マルチバイトの16進エスケープを使うと、 文字列はマルチバイトになります。 ユニバイトの非ASCIIを文字コードで表現することもできますが、 文字コードは128(8進0200)から255(8進0377)の範囲である必要があります。 こうすると、文字列はユニバイトになります。
2種類のテキストの表現方法について詳しくは、See Text Representations。
文字定数と同じバックスラッシュのエスケープシーケンスを文字列定数でも
使えます(ただし、文字定数を開始する疑問符は書かない)。
たとえば、コンマと空白で区切った非印字文字のタブとC-aを
含む文字列を書くには、"\t, \C-a"
のようにします。
文字の入力構文については、See Character Type。
しかしながら、バックスラッシュのエスケープシーケンスすべてが、 文字列において正しいとは限りません。 文字列に含めることが可能なコントロール文字は、 ASCIIコントロール文字に限ります。 文字列では、ASCIIコントロール文字の大文字小文字を区別しません。
正確にいえば、文字列はメタ文字を保持できません。
しかし、文字列をキー列として使う場合には、
文字列内のASCII文字のメタ変種を表現するための
特別な慣習があります。
文字列定数内でメタ文字を表すために\M-
の構文を使うと、
文字列内のその文字に
のビットを設定します。
define-key
やlookup-key
に文字列を使うと、
このコードは、等価なメタ文字に変換されます。
See Character Type。
文字列では、ハイパー、スーパー、アルトの修飾子を保持できません。
文字列は、文字そのものに加えて、文字の属性も保持できます。 このため、特別なことをしなくても、 文字列とバッファのあいだでテキストをコピーするプログラムは、 テキスト属性をコピーできます。 テキスト属性の意味については、See Text Properties。 テキスト属性付きの文字列には、特別な入力構文があります。
#("characters" property-data...)
ここで、property-dataは0個以上のつぎのような3つ組みです。
beg end plist
3つ組みの要素、begとendは整数であり、 文字列内の添字の範囲を表します。 plistはその範囲の属性リストです。 たとえば、
#("foo bar" 0 3 (face bold) 3 4 nil 4 7 (face italic))
は、最初の3文字がface
属性としてbold
を持ち、
最後の3文字がface
属性としてitalic
を持つ、
foo bar
という文字列を表します。
(4番目の文字にはテキスト属性はなく、その属性リストはnil
。
デフォルトでは、範囲に含まれない文字には属性はないので、
属性リストがnil
であるような範囲を言及する必要はない。)
ベクトル(vector)は、任意の型の要素から成る1次元配列です。 ベクトルの任意の要素を参照しても、それに必要な時間は一定です。 (リストでは、ある要素を参照するために必要な時間は、 リストの先頭からの距離に比例する。)
ベクトルの表示表現は、開き角括弧、要素、閉じ角括弧です。 これは、入力構文でもあります。 数や文字列と同様に、ベクトルは評価時には定数です。
[1 "two" (three)] ; 3要素のベクトル => [1 "two" (three)]
ベクトルに作用する関数については、See Vectors。
文字テーブル(char-table)は、 任意の型の要素から成る1次元配列であり、 文字コードで添字付けします。 文字テーブルには、文字コードに情報を与えるための多くの操作を簡単にする 付加的な機能があります。 たとえば、文字テーブルは、情報を継承するための親、 デフォルト値、特定目的向けの少数の追加スロットを持てます。 文字テーブルでは、文字集合全体に対して1つの値を指定することもできます。
文字テーブルの表示表現はベクトルに似ていますが、
先頭に#^
が余分に付きます。
文字テーブルを操作する特別の関数については、See Char-Tables。 文字テーブルはつぎのように使います。
ブールベクトル(bool-vector)は、
t
かnil
だけの要素から成る1次元配列です。
ブールベクトルの表示表現は文字列に似ていますが、
#&
と長さで始まります。
これに続く文字列定数が、ブールベクトルの実際の内容を
ビットマップで表します。
つまり、文字列の『各文字』は8ビット長のデータであり、
ブールベクトルのつぎの8個の要素を表します
(1はt
を表し、0はnil
を表す)。
文字の最下位ビットが、ブールベクトルの小さい添字に対応します。
長さが8の倍数でない場合には、
表示表現には余計な要素が含まれますが、余計な部分に意味はありません。
(make-bool-vector 3 t) => #&3"\007" (make-bool-vector 3 nil) => #&3"\0" ;; 最初の3ビットだけを使っているので、以下はすべて同じ (equal #&3"\377" #&3"\007") => t
他のプログラム言語の関数が実行可能であるように、
Lisp関数(Lisp function)は実行可能なコードです。
しかしながら、Lispにおいては、関数は基本Lispオブジェクトであり、
そのテキスト表現は副次的なものです。
これらのLispオブジェクトはラムダ式です。
つまり、先頭要素がシンボルlambda
であるリストです
(see Lambda Expressions)。
ほとんどのプログラム言語では、名前のない関数を書くことは不可能です。 Lispでは、本質的には、関数に名前はありません。 ラムダ式のことを無名関数(anonymous function)とも呼びます (see Anonymous Functions)。 Lispにおける名前付き関数は、実際には、 関数セルに正しい関数を収めたシンボルです (see Defining Functions)。
多くの場合、LispプログラムのLisp式中に関数名を書くと関数が呼ばれます。
しかし、実行時に関数オブジェクトを構成したり取得して、
基本関数funcall
やapply
で、それを呼び出すことができます。
See Calling Functions。
Lispマクロ(Lisp macro)は、
Lisp言語を拡張するユーザー定義の構造です。
関数に似たオブジェクトで表現しますが、引数渡しの意味は異なります。
Lispマクロは、リストの最初の要素がシンボルmacro
であり、
リストのCDRがlambda
シンボルを
含むLisp関数オブジェクトであるフォームです。
Lispマクロオブジェクトは、通常、組み込み関数defmacro
で
定義しますが、
Emacsにとっては、macro
で始まるリストはマクロです。
マクロの書き方の説明は、See Macros。
警告:
Lispマクロとキーボードマクロ
(see Keyboard Macros)は、まったく別のものです。
単に『マクロ』といった場合には、Lispマクロを意味するのであって、
キーボードマクロのことではありません。
基本関数型(primitive function)は、 Lispから呼び出し可能な関数ですが、C言語で書いてあります。 基本関数のことをsubrとか 組み込み関数(built-in functions)とも呼びます。 (『subr』は『subroutine』からきている。) ほとんどの基本関数は、呼び出すときにすべての引数を評価します。 引数すべてを評価しない基本関数をスペシャルフォーム(special form)と 呼びます(see Special Forms)。
関数を呼び出す側からすれば、関数が基本関数かどうかは関係ありません。 しかし、Lispで書いた関数で基本関数を再定義しようとすると、 問題があります。 というのは、基本関数はCのコードから直接呼ばれるからです。 再定義した関数をLispから呼び出す場合には新しい定義を使いますが、 Cのコードは組み込みの定義を使い続けるでしょう。 したがって、基本関数を再定義しないでください。
関数(function)という用語で、 LispやCで書かれたEmacsのすべての関数を指します。 Lispで書いた関数に関しては、See Function Type。
基本関数には入力構文はなく、 サブルーティン名を含むハッシュ記法で表示します。
(symbol-function 'car) ; シンボルの関数セルを参照する => #<subr car> (subrp (symbol-function 'car)) ; 基本関数か? => t ; そのとおり
バイトコンパイラは、バイトコード関数オブジェクト (byte-code function objects)を作り出します。 内部的には、バイトコード関数オブジェクトはベクトルによく似ています。 しかしながら、評価過程においては、関数呼び出しのように見えるときには、 このデータ型を特別に扱います。 バイトコンパイラについては、See Byte Compilation。
バイトコード関数オブジェクトの表示表現と入力構文は、
ベクトルに似ていますが、開き角括弧[
のまえに#
が付きます。
自動ロードオブジェクト(autoload object)は、
先頭要素がシンボルautoload
であるリストです。
実際の定義のかわりにシンボルの関数定義として使われ、
必要なときにロードすべき実際の定義を収めたLispコードファイルを示します。
自動ロードオブジェクトには、ファイル名に加えて、
実際の関数定義に関する他の情報も入っています。
ファイルをロードし終えると、 シンボルには、自動ロードオブジェクトではない新たな関数定義が入ります。 この新たな定義を始めからあったかのように呼び出します。 ユーザーの視点からは、ロードしたファイル内の関数定義を使って、 予想どおりに関数呼び出しが行われます。
自動ロードオブジェクトは、普通、関数autoload
で作ります。
この関数は、シンボルの関数セルにオブジェクトを格納します。
より詳しくは、See Autoload。
前節の型は一般のプログラム向けに使うもので、 そのほとんどは、ほんどのLisp方言に共通しています。 Emacs Lispには、編集に関連した目的向けにいくつかのデータ型があります。
バッファ(buffer)は、編集可能なテキストを保持するオブジェクトです (see Buffers)。 ほとんどのバッファは、ディスクファイル(see Files)の内容を保持して 編集できるようにしますが、他の目的に使われるものもあります。 ほとんどのバッファは、ユーザーが見るためのものであり、 ある期間、ウィンドウ(see Windows)に表示されます。 しかし、バッファがいずれかのウィンドウに必ずしも表示される必要はありません。
バッファの内容は文字列によく似ていますが、 Emacs Lispにおいては、バッファは文字列のようには使われず、 適用可能な操作も異なります。 たとえば、既存のバッファにテキストを効率よく挿入できますが、 文字列にテキストを『挿入』するには、 部分文字列を連結する必要があり、まったく新しい文字列オブジェクトになります。
各バッファには、ポイント(point)と呼ばれる特別な箇所があります (see Positions)。 どんなときにも、1つのバッファがカレントバッファ(current buffer)です。 ほとんどの編集コマンドは、カレントバッファのポイント付近の内容に作用します。 多くのEmacsの標準関数は、カレントバッファ内にある文字を操作したり検査します。 本書には、これらの関数の説明にあてた章が1つあります(see Text)。
各バッファに関連付けられたデータ構造には、つぎのものがあります。
ローカルキーマップと変数リストには、 それぞれ、グローバルな束縛や値に優先するものが入っています。 これらは、プログラムを変更せずに、各バッファごとに、 プログラムのふるまいをカスタマイズするために使われます。
バッファは間接(indirect)でもよく、その場合、 別のバッファとテキストを共有しつつ異なった表示を行えます。 See Indirect Buffers。
バッファには入力構文はありません。 バッファ名を含んだハッシュ記法で表示します。
(current-buffer) => #<buffer objects.texi>
マーカ(marker)は、特定のバッファ内の位置を表します。 したがって、マーカには2つの構成要素、つまり、 バッファを示すものと位置を示すものがあります。 バッファ内のテキストを変更すると、 マーカがバッファ内の同じ2つの文字のあいだをつねに指すことを保証するように、 位置の値を更新します。
マーカには入力構文はありません。 バッファ内の文字位置とバッファ名を含んだハッシュ記法で表示します。
(point-marker) => #<marker at 10779 in objects.texi>
マーカの検査、作成、コピー、移動の方法については、See Markers。
ウィンドウ(window)は、 Emacsがバッファを表示するために使用する端末画面の部分のことです。 各ウィンドウには、対応付けられたバッファが1つあり、 そのバッファの内容をウィンドウに表示しています。 一方、あるバッファが、1つのウィンドウや複数のウィンドウに表示されることもあり、 どのウィンドウにも表示されないこともあります。
同時に複数のウィンドウが存在できますが、 どんなときにも1つのウィンドウだけが選択されたウィンドウ (selected window)です。 これは、Emacsがコマンドを受け付け可能なときにカーソルを(通常)表示する ウィンドウです。 選択されたウィンドウは、通常、カレントバッファを表示しますが、 これは必須ではありません。
画面上のウィンドウはフレームにまとめられています。 各ウィンドウは、たった1つのフレームに属します。 See Frame Type。
ウィンドウには入力構文はありません。 ウィンドウ番号と表示中のバッファ名を含んだハッシュ記法で表示します。 ウィンドウ番号は、ウィンドウを一意に識別するためにあります。 これは、ウィンドウが表示しているバッファは頻繁に変わるからです。
(selected-window) => #<window 1 on objects.texi>
ウィンドウを操作する関数の説明は、See Windows。
フレーム(frame)は、画面上の矩形領域であって、 1つ以上のEmacsウィンドウを含みます。 フレームには最初は1つのウィンドウ (とミニバッファウィンドウ)が含まれますが、 これを左右や上下に小さなウィンドウに分割できます。
フレームには入力構文はありません。 フレームのタイトルとメモリ内のアドレス (フレームを一意に識別するのに有用)を含んだハッシュ記法で表示します。
(selected-frame) => #<frame emacs@psilocin.gnu.org 0xdac80>
フレームを操作する関数の説明は、See Frames。
ウィンドウ構成(window configuration)は、 フレーム内のウィンドウの位置/サイズ/内容に関する情報を記録し、 同じ配置のウィンドウをあとで再度作成できるようにします。
ウィンドウ構成には入力構文はありません。
表示表現は、#<window-configuration>
のようになります。
ウィンドウ構成に関連した関数の説明は、See Window Configurations。
フレーム構成(frame configuration)は、
すべてのフレームのウィンドウの位置/サイズ/内容に関する情報の記録です。
これは、実際には、リストのCARがframe-configuration
であり、
リストのCDRが連想リストであるリストです。
連想リストの各要素で、そのCARに現れるフレーム1個を記述します。
フレーム構成に関連した関数の説明は、See Frame Configurations。
単語プロセス(process)は、通常、実行中のプログラムを意味します。 Emacs自身、この種のプロセスとして実行されています。 しかし、Emacs Lispでは、プロセスとは、 Emacsプロセスが作成したサブプロセスを表すLispオブジェクトのことです。 Emacsのサブプロセスで実行される、シェル、GDB、ftp、コンパイラなどの プログラムは、Emacsの能力を拡張します。
Emacsサブプロセスは、Emacsからテキスト入力を受け取り、 さらに処理できるようにEmacsにテキスト出力を返します。 Emacsはサブプロセスにシグナルを送ることもできます。
プロセスオブジェクトに入力構文はありません。 プロセス名を含んだハッシュ記法で表示します。
(process-list) => (#<process shell>)
プロセスを作成したり削除したり、プロセスに関する情報を返したり、 プロセスへ入力やシグナルを送ったり、プロセスから出力を受け取る 関数に関する情報は、See Processes。
ストリーム(stream)は、文字を出し入れする対象、
つまり、入力用に文字を供給したり、出力として文字を受け取ったりといった
ことに使えるオブジェクトです。
多くの異なる型をこのように使えます。
マーカ、バッファ、文字列、関数です。
ほとんどの場合、入力ストリーム(文字の供給源)は、
キーボード、バッファ、ファイルから文字を取得します。
出力ストリーム(文字の消費先)は、*Help*
バッファなどのバッファや
エコー領域に文字を送ります。
オブジェクトnil
は、他の意味に加えて、
ストリームとしても使えます。
変数standard-input
やstandard-output
の値になります。
また、オブジェクトt
も、
ミニバッファ(see Minibuffers)を使う入力ストリームや
エコー領域への出力(see The Echo Area)を意味します。
ストリームには表示形式も入力構文もなく、その基本型で表示します。
構文解析関数や表示関数を含むストリームに関連した関数の説明は、 See Read and Print。
キーマップ(keymap)は、ユーザーが打ったキーをコマンドに対応付けます。
この対応付けは、ユーザーのコマンド入力をどのように実行するかを制御します。
キーマップは、実際には、リストであり、
そのCARはシンボルkeymap
です。
キーマップの作成、プレフィックスキーの扱い方、 グローバルやローカルなキーマップ、キーバインディングの変更に関する情報は、 See Keymaps。
オーバレイ(overlay)は、バッファのある部分に作用する属性を指定します。 各オーバレイは、バッファの指定した範囲に作用し、 属性リスト(属性名と値の要素を交互に繰り返すリスト)を含んでいます。 オーバレイ属性は、 バッファの一部を一時的に異なった方式で表示するために使われます。 オーバレイ属性に入力構文はなく、 バッファ名と位置範囲を含んだハッシュ記法で表示します。
オーバレイの作成と使用法については、See Overlays。
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に加える (setq list (cons x list))) ((listp x) ;; Xがリストならば、その要素をLISTに追加する (setq list (append x list))) (t ;; シンボルとリストだけを扱う (error "Invalid argument %s in add-on" x))))
定義済みの型述語を、アルファベット順に、参照先を併記してあげておきます。
atom
arrayp
bool-vector-p
bufferp
byte-code-function-p
case-table-p
char-or-string-p
char-table-p
commandp
consp
display-table-p
floatp
frame-configuration-p
frame-live-p
framep
functionp
integer-or-marker-p
integerp
keymapp
listp
markerp
wholenump
nlistp
numberp
number-or-marker-p
overlayp
processp
sequencep
stringp
subrp
symbolp
syntax-table-p
user-variable-p
vectorp
window-configuration-p
window-live-p
windowp
オブジェクトの型を調べるもっとも一般的な方法は、
関数type-of
を呼び出すことです。
各オブジェクトはたった1つの基本型に属することを思い出してください。
type-of
はどの1つかを教えてくれます(see Lisp Data Types)。
しかし、type-of
は、基本型以外についてはなにも知りません。
多くの場合、type-of
より型述語を使うほうが便利でしょう。
type-of object | Function |
この関数は、objectの基本型を示すシンボルを返す。
その値は、
symbol 、
integer 、float 、string 、cons 、vector 、
char-table 、bool-vector 、subr 、
compiled-function 、marker 、overlay 、window 、
buffer 、frame 、process 、window-configuration の
シンボルのうちの1つ。
(type-of 1) => integer (type-of 'nil) => symbol (type-of '()) ; |
2つのオブジェクトの同値関係を調べる2つの関数を説明します。 文字列などの特定のオブジェクトが同値であるかを調べる関数群もあります。 これらの述語については、データ型を述べている適切な章を参照してください。
eq object1 object2 | Function |
この関数は、object1とobject2が
同一オブジェクトであればt を返し、さもなければnil を返す。
『同一オブジェクト』とは、
一方を変更すると、他方にも同じ変更が反映されることを意味する。
(eq 'foo 'foo) => t (eq 456 456) => t (eq "asdf" "asdf") => nil (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 関数 (eq (make-symbol "foo") 'foo) => nil |
equal object1 object2 | Function |
この関数は、 object1とobject2が等しい要素を持てば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 文字列の比較では大文字小文字を区別するが、テキスト属性は考慮しない。 つまり、文字列内の文字だけを比較する。 文字列の内容がすべてASCIIでなければ、 ユニバイト文字列とマルチバイト文字列が等しいことはない (see Text Representations)。 (equal "asdf" "ASDF") => nil たとえ内容が同じであっても、
異なる2つのバッファが |
equal
の検査は再帰で実装されているので、
リストに循環があると無限再帰を引き起こし(エラーになり)ます。
GNU Emacsでは2種類の数値データを扱えます。
整数(integers)と浮動小数点数(floating point numbers)です。
整数は、-3、0、7、13、511のようなちょうどの数です。
これらの値は正確です。
浮動小数点数は、-4.5、0.0、2.71828のように小数部がある数です。
これらは指数表記で表します。
たとえば、1.5e2は150に等しいのです。
この例のe2
は10の2乗を表し、それを1.5倍します。
浮動小数点数の値は厳密ではありません。
これらの精度には定まった限界があります。
整数の値の範囲は計算機に依存します。 最小の範囲は、-134217728から134217727まで(28ビット長、つまり から これより広い範囲を扱える計算機もあります。 本章の多くの例題では、整数は28長ビットであると仮定します。
Lispリーダは、 先頭に符号があってもよく、最後にピリオドがあってもよい、 数字の列として整数を読み取ります。
1 ; 整数1 1. ; 整数1 +1 ; これも整数1 -1 ; 整数-1 268435457 ; 桁溢れのため、これも整数1 0 ; 整数0 -0 ; 整数0
整数を扱うさまざまな関数を理解するには、 特にビット演算(see Bitwise Operations)を理解するには、 数を2進表現で考えるとよいです。
28ビット長の2進表現では、10進整数5はつぎのようになります。
0000 0000 0000 0000 0000 0000 0101
(4ビットのまとまりごとに空白を1個、 8ビットのまとまりごとに空白を2個挿入して、読みやすくする。)
整数-1はつぎのようになります。
1111 1111 1111 1111 1111 1111 1111
-1は、28個の1で表現されます。 (これを2の補数(two's complement)表記と呼ぶ。)
負の数-5は、-1から4を引いて作れます。 10進数4は、2進表記では100です。 したがって、-5は、つぎのようになります。
1111 1111 1111 1111 1111 1111 1011
この実装では、28ビット長の2進整数の最大値は、 10進で134,217,727になります。 2進表記では、つぎのようになります。
0111 1111 1111 1111 1111 1111 1111
算術関数は、整数がその範囲外に出たかどうか検査しないので、 134,217,727に1を足すと、値は負の数-134,217,728になります。
(+ 1 134217727) => -134217728 => 1000 0000 0000 0000 0000 0000 0000
本章で述べる多くの関数は、数の引数としてマーカを受け付けます。 (see Markers)。 そのような関数の実際の引数は数かマーカであるので、 それらの引数をしばしばnumber-or-markerという名前で書きます。 引数の値がマーカであるときには、その位置の値を使いバッファは無視します。
浮動小数点数は、整数ではない数を表現するのに便利です。
浮動小数点数の正確な範囲は計算機に依存します。
使用している計算機のC言語のデータ型double
の範囲と同じです。
浮動小数点数の入力構文は、小数点(に続けて1桁以上の小数部)または指数、
あるいは、その両方が必要です。
たとえば、1500.0
、15e2
、15.0e2
、
1.5e3
、.15e4
は、同じ1500という値の
浮動小数点数を書き表す5つの方法です。
どれも、まったく等価です。
負の浮動小数点数を書くには、-1.0
のようにマイナス符号を使います。
現代の計算機はIEEEの浮動小数点数規格に基づいています。
この規格では、浮動小数点数の値には正の無限大と負の無限大があります。
また、NaNすなわち『非数値』(not-a-number)と呼ばれる値の種類もあります。
算術関数は、正しい答えがないときには、このような値を返します。
たとえば、(sqrt -1.0)
はNaNを返します。
実用的には、Emacs Lispでは異なるNaNの値に重要な違いはなく、
特定の場面で正確にはどのNaNの値を使うかの規則もないので、
Emacs Lispではそれらを区別しようとはしません。
浮動小数点数の入力構文はつぎのとおりです。
1.0e+INF
-1.0e+INF
0.0e+NaN
。
さらに、IEEEの浮動小数点数では値-0.0
を普通のゼロと区別します
(しかし、equal
と=
は、これらを等しい値と扱う)。
浮動小数点数の2進指数を取り出すには(あるいは、整数の対数を予測するには)、
logb
を使います。
logb number | Function |
この関数はnumberの2進指数を返す。
より正確には、その値はnumberの2を底とする対数を整数に切り下げたもの。
(logb 10) => 3 (logb 10.0e20) => 69 |
本節の関数は、引数が数であるか、とか、特定の種類の数であるか検査します。
関数integerp
とfloatp
は
引数として任意の型のLispオブジェクトを取ります
(さもないと、述語の利用価値がない)。
しかし、述語zerop
の引数には数が必要です。
Predicates on Markersの
integer-or-marker-p
とnumber-or-marker-p
も
参照してください。
floatp object | Function |
この述語は、引数が浮動小数点数かどうか調べ、
そうならばt を返し、さもなければnil を返す。
Emacs 18以前の版には |
integerp object | Function |
この述語は、引数が整数かどうか調べ、
そうならばt を返し、さもなければnil を返す。
|
numberp object | Function |
この述語は、引数が数(整数か浮動小数点数)かどうか調べ、
そうならばt を返し、さもなければnil を返す。
|
wholenump object | Function |
(『whole-number-p』からきている名前の)述語wholenump は、
引数が非負整数かどうか調べ、
そうならばt を返し、さもなければnil を返す。
0は非負整数として扱う。
|
zerop number | Function |
この述語は、引数が0かどうか調べ、
そうならばt を返し、さもなければnil を返す。
引数は数であること。
つぎの2つのフォームは等価。
|
2つの数が数値的に等しいかどうか調べるには、普通、
eq
ではなく=
を使うべきです。
数値的には等しい多くの異なる浮動小数点数が存在しえます。
それらの比較にeq
を使うと、
2つの値が同一オブジェクトかどうか調べることになります。
対照的に、=
はオブジェクトの数値だけを比較します。
現時点では、Emacs Lispにおいて、各整数値は一意なLispオブジェクトです。
したがって、整数に限ればeq
は=
と等価です。
未知の値と整数を比較するためにeq
を使うと便利な場面があります。
というのは、eq
は任意の型の引数を受け付けるので、
eq
は未知の値が数でなくてもエラーを報告しないからです。
対照的に、=
は、引数が数やマーカでないと、エラーを通知します。
しかしながら、Emacsの将来の版で整数の表現方法を変更する場合に備えて、
整数を比較するときであっても、可能ならば、=
を使うほうがよいでしょう。
equal
で数を比較したほうが便利なこともあります。
equal
は、2つの数が同じデータ型
(どちらも整数であるか、どちらも浮動小数点数である)で、
同じ値であれば、2つの数を等しいと扱います。
一方、=
は、整数と浮動小数点数が等しいことを扱えます。
別のことがらもあります。 浮動小数点数演算は厳密ではないので、 2つの浮動小数点数が等しいかどうか調べるのは正しくありません。 普通、近似的に等しいことを調べるほうがよいのです。 つぎの関数はそのようにします。
(defvar fuzz-factor 1.0e-6) (defun approx-equal (x y) (or (and (= x 0) (= y 0)) (< (/ (abs (- x y)) (max (abs x) (abs y))) fuzz-factor)))
Common Lispに関した注意:Common Lispでは、数の比較にはつねに
=
を使う必要がある。 というのは、Common Lispでは複数ワードの整数を実装しているため、 2つの異なる整数オブジェクトが同じ数値を表すことがありえる。 Emacs Lispでは、整数値の範囲が制限されているため、 任意の値の整数オブジェクトはそれぞれ1つしかない。
= number-or-marker1 number-or-marker2 | Function |
この関数は、引数が数値的に等しいか調べ、
そうならばt を返し、さもなければnil を返す。
|
/= number-or-marker1 number-or-marker2 | Function |
この関数は、引数が数値的に等しいか調べ、
等しくなければt を返し、等しければnil を返す。
|
< number-or-marker1 number-or-marker2 | Function |
この関数は、第1引数が第2引数より小さいか調べ、
そうならばt を返し、さもなければnil を返す。
|
<= number-or-marker1 number-or-marker2 | Function |
この関数は、第1引数が第2引数より小さいか、あるいは、等しいか調べ、
そうならばt を返し、さもなければnil を返す。
|
> number-or-marker1 number-or-marker2 | Function |
この関数は、第1引数が第2引数より大きいか調べ、
そうならばt を返し、さもなければnil を返す。
|
>= number-or-marker1 number-or-marker2 | Function |
この関数は、第1引数が第2引数より大きいか、あるいは、等しいか調べ、
そうならばt を返し、さもなければnil を返す。
|
max number-or-marker &rest numbers-or-markers | Function |
この関数は、引数の中で最大のものを返す。
(max 20) => 20 (max 1 2.5) => 2.5 (max 1 3 2.5) => 3 |
min number-or-marker &rest numbers-or-markers | Function |
この関数は、引数の中で最小のものを返す。
(min -4 1) => -4 |
abs number | Function |
この関数は、numberの絶対値を返す。 |
整数を浮動小数点数に変換するには、
関数float
を使います。
float number | Function |
この関数は、浮動小数点数に変換したnumberを返す。
numberがすでに浮動小数点数ならば、
float はnumberを変更せずに返す。
|
浮動小数点数を整数に変換する関数は4つあります。 これらの関数は、整数も引数に取りますが、整数引数は変更せずに返します。
truncate number | Function |
これは、0に向けて切り捨てて整数に変換したnumberを返す。 |
floor number &optional divisor | Function |
これは、(負の無限大に向けて)切り下げて整数に変換したnumberを返す。
divisorを指定すると、切り下げるまえに
numberをdivisorで除算する。
これには、 |
ceiling number | Function |
これは、(正の無限大に向けて)切り上げて整数に変換したnumberを返す。 |
round number | Function |
これは、もっとも近い整数に丸めて整数に変換したnumberを返す。 2つの整数に等距離にある値を丸める場合には、 使用している計算機に依存して、ゼロに近いほうの整数を選ぶか偶数を選ぶ。 |
Emacs Lispには、伝統的な四則演算、加算、減算、乗算、除算があります。 除算関数を補う、余りと剰余の関数もあります。 Lispの伝統でもあり、また、多用するので、1を加算したり減算する関数もあります。
これらの関数は、%
を除いて、引数が1つでも浮動小数点数であると、
浮動小数点数を返します。
Emacs Lispでは、算術関数は桁溢れ(オーバフロー)を検査しないことに
注意してください。
つまり、読者の計算機に依存しますが、
(1+ 134217727)
を評価すると-134217728になる場合もあります。
1+ number-or-marker | Function |
この関数は、number-or-marker足す1を返す。
(setq foo 4) => 4 (1+ foo) => 5 この関数はC言語の演算子 foo => 4 変数を増加するには、つぎのように (setq foo (1+ foo)) => 5 |
1- number-or-marker | Function |
この関数は、number-or-marker引く1を返す。 |
+ &rest numbers-or-markers | Function |
この関数は、引数をすべて加算する。
引数を指定しないと+ は0を返す。
(+) => 0 (+ 1) => 1 (+ 1 2 3 4) => 10 |
- &optional number-or-marker &rest more-numbers-or-markers | Function |
関数- は、2つの役割、つまり、符号反転と減算を果たす。
- に1つの引数を指定すると、
その値は、引数の符号を反転したものである。
複数個の引数を指定すると、- は、
number-or-markerからmore-numbers-or-markersの1つ1つを減算する。
引数を指定しないと結果は0である。
(- 10 1 2 3 4) => 0 (- 10) => -10 (-) => 0 |
* &rest numbers-or-markers | Function |
この関数は、引数をすべて掛け合わせた乗算結果を返す。
引数を指定しないと* は1を返す。
(*) => 1 (* 1) => 1 (* 1 2 3 4) => 24 |
/ dividend divisor &rest divisors | Function |
この関数は、dividendをdivisorで除し商を返す。
追加の引数divisorsを指定してあると、
dividendをdivisorsの1つ1つで除す。
各引数は数かマーカである。
すべての引数が整数である場合、結果も整数となる。
つまり、結果は切り捨てになる。
ほとんどの計算機では各除算の結果は0に向けて切り捨てになるが、
負の引数を別の方法で丸める計算機もある。
これは、Lisp関数 整数を0で除算すると、エラー (/ 6 2) => 3 (/ 5 2) => 2 (/ 5.0 2) => 2.5 (/ 5 2.0) => 2.5 (/ 5.0 2.0) => 2.5 (/ 25 3 2) => 4 (/ -17 6) => -2 原理的には、 |
% dividend divisor | Function |
この関数は、dividendをdivisorで除したあとの整数の余りを返す。
引数は整数かマーカである必要がある。
負の引数では、余りは原理的に計算機依存である。 実用上、すべての既知の計算機は同じようにふるまう。 divisorが0であると (% 9 4) => 1 (% -9 4) => -1 (% 9 -4) => 1 (% -9 -4) => -1 2つの任意の整数dividendとdivisorにおいて、 (+ (% dividend divisor) (* (/ dividend divisor) divisor)) は、つねにdividendに等しい。 |
mod dividend divisor | Function |
この関数は、dividendのdivisorによる剰余を返す。
いいかえれば、dividendをdivisorで除した余りを返す。
ただし、その符号はdivisorと同じ。
引数は数かマーカである必要がある。
divisorが0であると (mod 9 4) => 1 (mod -9 4) => 3 (mod 9 -4) => -3 (mod -9 -4) => -1 (mod 5.5 2.5) => .5 2つの任意の整数dividendとdivisorにおいて、 (+ (mod dividend divisor) (* (floor dividend divisor) divisor)) は、つねにdividendに等しい。
ただし、どちらかの引数が浮動小数点数の場合には、
丸め誤差の範囲内で等しい。
|
関数、ffloor
、fceiling
、fround
、ftruncate
は、
浮動小数点数引数を受け取り、その値に近い整数を値とする浮動小数点数を返します。
ffloor
は、もっとも近いより小さな整数を返します。
fceiling
は、もっとも近いより大きな整数を返します。
ftruncate
は、0に向けて切り捨てたもっとも近い整数を返します。
fround
は、もっとも近い整数を返します。
ffloor float | Function |
この関数は、floatをこれより小さな整数値に切り下げ、 その値を浮動小数点数として返す。 |
fceiling float | Function |
この関数は、floatをこれより大きな整数値に切り上げ、 その値を浮動小数点数として返す。 |
ftruncate float | Function |
この関数は、floatを0に向けて整数値に切り捨て、 その値を浮動小数点数として返す。 |
fround float | Function |
この関数は、floatをもっとも近い整数値に丸め、 その値を浮動小数点数として返す。 |
計算機内部では、整数は2進数、つまり、 ビット(bit、各桁は0か1)列で表現されます。 ビット演算は、そのようなビット列の各ビットごとに作用します。 たとえば、シフト(shifting)は、ビット列を全体として左や右に 1桁以上移動して、その『移動後の』パターンを結果とします。
Emacs Lispにおけるビット演算は整数に限ります。
lsh integer1 count | Function |
論理シフト(logical shift)の略からきているlsh は、
integer1のビット列をcount桁左へ、
あるいは、countが負ならば右へずらし、空いたビットには0を詰める。
countが負であれば、lsh は最左(最上位)ビットに0を詰め、
integer1が負であっても結果は正になる。
これと対照的なのが下のash 。
(lsh 5 1) => 10 ;; 10進数5は、 10進数10になる 00000101 => 00001010 (lsh 7 1) => 14 ;; 10進数7は、10進数14になる 00000111 => 00001110 例からわかるように、ビットパターンを1桁左へずらすと、 もとの数値の2倍の数になる。 ビットパターンを2桁左へずらすと、(8ビット長の2進数では)つぎのようになる。 (lsh 3 2) => 12 ;; 10進数3は、10進数12になる 00000011 => 00001100 一方、右へずらすとつぎのようになる。 (lsh 6 -1) => 3 ;; 10進数6は、10進数3になる 00000110 => 00000011 (lsh 5 -1) => 2 ;; 10進数5は、10進数2になる 00000101 => 00000010 例からわかるように、ビットパターンを1桁右へずらすと、 正の整数の数を2で除して切り下げる。 Emacs Lispのすべての算術関数と同様に、
関数 (lsh 134217727 1) ; 左シフト => -2 28ビット長の実装の2進数では、引数はつぎのようになっている。 ;; 10進数134,217,727 0111 1111 1111 1111 1111 1111 1111 これを左へずらすと、つぎのようになる ;; 10進数-2 1111 1111 1111 1111 1111 1111 1110 |
ash integer1 count | Function |
ash (算術シフト(arithmetic shift))は、
integer1のビットをcount桁左へ、あるいは、
countが負ならば右へずらす。
したがって、 (ash -6 -1) => -3 ;; 10進数-6は、10進数-3になる 1111 1111 1111 1111 1111 1111 1010 => 1111 1111 1111 1111 1111 1111 1101 対照的に、 (lsh -6 -1) => 134217725 ;; 10進数-6は、10進数134,217,725になる 1111 1111 1111 1111 1111 1111 1010 => 0111 1111 1111 1111 1111 1111 1101 他の例を以下にしめす。 ; 28ビット2進値 (lsh 5 2) ; 5 = 0000 0000 0000 0000 0000 0000 0101 => 20 ; = 0000 0000 0000 0000 0000 0001 0100 (ash 5 2) => 20 (lsh -5 2) ; -5 = 1111 1111 1111 1111 1111 1111 1011 => -20 ; = 1111 1111 1111 1111 1111 1110 1100 (ash -5 2) => -20 (lsh 5 -2) ; 5 = 0000 0000 0000 0000 0000 0000 0101 => 1 ; = 0000 0000 0000 0000 0000 0000 0001 (ash 5 -2) => 1 (lsh -5 -2) ; -5 = 1111 1111 1111 1111 1111 1111 1011 => 4194302 ; = 0011 1111 1111 1111 1111 1111 1110 (ash -5 -2) ; -5 = 1111 1111 1111 1111 1111 1111 1011 => -2 ; = 1111 1111 1111 1111 1111 1111 1110 |
logand &rest ints-or-markers | Function |
この関数は引数の『論理積』を返す。
つまり、すべての引数のn番目のビットが1である場合に限り、
結果のn番目のビットも1になる。
たとえば、4ビットの2進数で考えると、 13と12の『論理積』は12になる。 つまり、1101に1100を組み合わせると1100になる。 どちらの2進数も最左の2ビットは1なので、戻り値の最左の2ビットも1になる。 しかし、最右の2ビットは、一方の引数ではそれぞれが0なので、 戻り値の最右の2ビットも0になる。 したがって、つぎのとおり。 (logand 13 12) => 12
; 28ビット2進値 (logand 14 13) ; 14 = 0000 0000 0000 0000 0000 0000 1110 ; 13 = 0000 0000 0000 0000 0000 0000 1101 => 12 ; 12 = 0000 0000 0000 0000 0000 0000 1100 (logand 14 13 4) ; 14 = 0000 0000 0000 0000 0000 0000 1110 ; 13 = 0000 0000 0000 0000 0000 0000 1101 ; 4 = 0000 0000 0000 0000 0000 0000 0100 => 4 ; 4 = 0000 0000 0000 0000 0000 0000 0100 (logand) => -1 ; -1 = 1111 1111 1111 1111 1111 1111 1111 |
logior &rest ints-or-markers | Function |
この関数は引数の『論理和』を返す。
つまり、少なくともどれか1つの引数のn番目のビットが1である場合に限り、
結果のn番目のビットも1になる。
引数を指定しないと0を返すが、これはこの演算の恒等元である。
logior に引数を1つだけ指定するとその引数を返す。
; 28ビット2進値 (logior 12 5) ; 12 = 0000 0000 0000 0000 0000 0000 1100 ; 5 = 0000 0000 0000 0000 0000 0000 0101 => 13 ; 13 = 0000 0000 0000 0000 0000 0000 1101 (logior 12 5 7) ; 12 = 0000 0000 0000 0000 0000 0000 1100 ; 5 = 0000 0000 0000 0000 0000 0000 0101 ; 7 = 0000 0000 0000 0000 0000 0000 0111 => 15 ; 15 = 0000 0000 0000 0000 0000 0000 1111 |
logxor &rest ints-or-markers | Function |
この関数は引数の『排他的論理和』を返す。
つまり、引数のn番目のビットが1であるものが奇数個の場合に限り、
結果のn番目のビットも1になる。
引数を指定しないと0を返すが、これはこの演算の恒等元である。
logxor に引数を1つだけ指定するとその引数を返す。
; 28ビット2進値 (logxor 12 5) ; 12 = 0000 0000 0000 0000 0000 0000 1100 ; 5 = 0000 0000 0000 0000 0000 0000 0101 => 9 ; 9 = 0000 0000 0000 0000 0000 0000 1001 (logxor 12 5 7) ; 12 = 0000 0000 0000 0000 0000 0000 1100 ; 5 = 0000 0000 0000 0000 0000 0000 0101 ; 7 = 0000 0000 0000 0000 0000 0000 0111 => 14 ; 14 = 0000 0000 0000 0000 0000 0000 1110 |
lognot integer | Function |
この関数は引数の論理的な補数を返す。
つまり、integerのn番目のビットが0である場合に限り、
結果のn番目のビットは1になる。
(lognot 5) => -6 ;; 5 = 0000 0000 0000 0000 0000 0000 0101 ;; becomes ;; -6 = 1111 1111 1111 1111 1111 1111 1010 |
これらの数学関数は浮動小数点数に加えて整数も引数として受け付けます。
sin arg | Function |
cos arg | Function |
tan arg | Function |
これらは普通の三角関数であり、引数は弧度法で表す。 |
asin arg | Function |
(asin arg) の値は-pi/2からpi/2までの数であり、
その正弦(sin)はargに等しい。
しかし、argが([-1, 1]の)範囲を越えていると結果はNaN。
|
acos arg | Function |
(acos arg) の値は0からpiまでの数であり、
その余弦(cos)はargに等しい。
しかし、argが([-1, 1]の)範囲を越えていると結果はNaN。
|
atan arg | Function |
(atan arg) の値は-pi/2からpi/2までの数であり、
その正接(tan)はargに等しい。
|
exp arg | Function |
これは指数関数であり、 のarg乗を返す。 は数学の基本定数であり、自然対数の底とも呼ぶ。 |
log arg &optional base | Function |
この関数はargのbaseを底とする対数を返す。 baseを指定しなければ、底として を使う。 argが負であると結果はNaN。 |
log10 arg | Function |
この関数はargの10を底とする対数を返す。
argが負であると結果はNaN。
少なくとも誤差を考慮すれば、
(log10 x) == (log x 10) 。
|
expt x y | Function |
この関数はxのy乗を返す。 どちらの引数も整数でありyが正ならば、結果は整数。 この場合、結果は整数値の可能な範囲に切り詰められる。 |
sqrt arg | Function |
この関数はargの平方根を返す。 argが負であると値はNaN。 |
決定論的な計算機プログラムは真の乱数を発生できません。 しかし、ほとんどの目的には疑似乱数(pseudo-random numbers)で十分です。 一連の疑似乱数を決定論的な方法で生成します。 それらの数は真の乱数ではありませんが、 乱数列のある種の性質に似た性質があります。 たとえば、疑似乱数列でもすべての可能な数がしばしば等しく生起します。
Emacsでは、疑似乱数は『種』となる数から生成します。
指定した任意の種から始めても、関数random
は同じ数の列を生成します。
Emacsはつねに同じ種の値で計算し始めるため、
それぞれのEmacsの実行でもrandom
は実際には同じ数の列を生成します。
たとえば、あるオペレーティングシステムで、
Emacs開始直後にrandom
を呼ぶとつねに-1457731を返し、
つぎに呼ぶとつねに-7692030を返します。
このような再現性はデバッグには有利です。
予測不可能な乱数が必要ならば(random t)
を実行します。
これは、現在時刻とEmacsプロセスのID番号に基づいて、
新たな種の値を選びます。
random &optional limit | Function |
この関数は疑似乱数の整数を返す。
繰り返し呼び出すと一連の疑似乱数の整数を返す。
limitが正整数ならば、非負でlimit未満になるように値を選ぶ。 limitが
|
Emacs Lispの文字列は文字の順序列を保持している配列です。 文字列は、シンボル、バッファ、ファイルのそれぞれの名前として、 ユーザーへメッセージを送るため、 バッファ間でコピーするテキストを保持するため、 その他さまざまな目的に使われます。 文字列はとても重要なので、 Emacs Lispには文字列を操作する関数が数多くあります。 Emacs Lispのプログラムでは、個々の文字よりも文字列を多用します。
キーボード文字イベントを表す文字列に関する特別な配慮については、 See Strings of Events。
format
: Emacs's analogue of printf
.
Emacs Lispの文字列は文字の順序列を保持している配列です。 Emacs Lispでは文字を整数で表現します。 整数が文字であるかどうかは、その使われ方からしか判断できません。 したがって、文字列は、実際には、整数群を保持しているのです。
(任意の配列と同様に)文字列の長さは固定されていて、 文字列をいったん作成すると変更できません。 Lispの文字列は特別な文字コードで終端されるのではありません。 (対照的に、C言語の文字列はASCIIコード0で終端される。)
文字列は配列ですからシーケンスでもあり、
一般の配列関数やシーケンス関数で文字列を操作できます。
(see Sequences Arrays Vectors。)
たとえば、関数aref
とaset
(see Array Functions)を
用いて、文字列内の個々の文字を参照したり変更できます。
Emacs文字列(およびバッファ)内の非ASCII文字のテキスト表現は 2種類あります。 ユニバイトとマルチバイトです(see Text Representations)。 ASCII文字は、文字列内ではつねに1バイトを占めます。 実際、すべてがASCII文字である文字列では、2つの表現に違いはありません。 ほとんどのLispプログラムでは、 読者はこれらの2つの表現を考慮する必要はないでしょう。
キー列を文字列として表現することがあります。 文字列がキー列を表す場合、128から255の範囲にある文字列の要素は、 その範囲の文字コードとしてではなく、 (非常に大きな整数になる)メタ文字を表現します。
文字列は、ハイパー、スーパー、アルトの修飾子を持つ文字を保持できません。 文字列はASCIIコントロール文字を保持できますが、 それ以外のコントロール文字を保持できません。 文字列では、ASCIIコントロール文字の大文字小文字を区別できません。 キー列などのそのような文字をシーケンスに収めるには、 文字列のかわりにベクトルを使う必要があります。 キーボード入力文字に対するメタなどの修飾子の表現については、 See Character Type。
文字列は正規表現を保持するのにも便利です。
文字列に対して正規表現の一致を取ることもできます(see Regexp Search)。
関数match-string
(see Simple Match Data)と
replace-match
(see Replacing Match)は、
正規表現の一致に基づいて文字列を分解したり変更するのに便利です。
バッファと同様に、文字列は、 文字そのものに加えて文字列内の文字に対するテキスト属性を保持できます。 See Text Properties。 文字列からバッファや他の文字列へテキストをコピーするすべてのLisp基本関数は、 コピーする文字の属性もコピーします。
文字列を表示したりバッファへコピーする関数については、See Text。 文字と文字列の構文については、Character TypeとSee String Type。 テキスト表現を変換したり、文字コードを符号化/復号化する関数については、 See Non-ASCII Characters。
一般のシーケンスや配列に対する述語について詳しくは、 Sequences Arrays VectorsとSee Arrays。
stringp object | Function |
この関数は、objectが文字列ならばt を返し、
さもなければnil を返す。
|
char-or-string-p object | Function |
この関数は、objectが文字列か文字(つまり、整数)ならば
t を返し、さもなければnil を返す。
|
以下の関数は、新たに文字列を作成したり、 文字列を連結したり分解して文字列を作成します。
make-string count character | Function |
この関数は、文字characterをcount回繰り返して作成した文字列を返す。
countが負であるとエラーを通知する。
(make-string 5 ?x) => "xxxxx" (make-string 0 ?x) => "" この関数に対比するものに、
|
string &rest characters | Function |
これは、複数個の文字群charactersが入った文字列を返す。
(string ?a ?b ?c) => "abc" |
substring string start &optional end | Function |
この関数は、stringのstartから
end(の直前)までの範囲にある文字から成る新たな文字列を返す。
先頭の文字を0で添字付けする。
(substring "abcdefg" 0 3) => "abc" ここで、 負の数は文字列の末尾から数える。 したがって、-1は文字列の最後の文字の添字である。 たとえば、 (substring "abcdefg" -3 -1) => "ef" この例では、 添字に (substring "abcdefg" -3 nil) => "efg" 引数endを省略することは、 (substring "abcdefg" 0) => "abcdefg" しかし、このような目的には stringからコピーした文字にテキスト属性があれば、 新たな文字列にもそのテキスト属性をコピーする。 see Text Properties。
(substring [a b (c) "d"] 1 3) => [b (c)] startやendが整数でも この関数と対照的なのが |
concat &rest sequences | Function |
この関数は、渡した引数の文字から成る
(テキスト属性があればそれも含めて)新たな文字列を返す。
引数は、文字列、数のリスト、数のベクトルである。
引数自身は変更しない。
concat に引数を指定しないと空文字列を返す。
(concat "abc" "-def")
=> "abc-def"
(concat "abc" (list 120 121) [122])
=> "abcxyz"
;;
関数 引数が(整数のシーケンスではなく)整数であると、
その整数の表示表現を構成する文字列に変換する。
この機能を使わないでほしい。
削除する予定である。
読者がこの機能を使っていたら、今すぐプログラムを直すこと! (concat 137) => "137" (concat 54 321) => "54321" 他の連結関数については、
Mapping Functionsの |
split-string string separators | Function |
stringを正規表現separatorsの一致箇所で区切って
部分文字列に分解する。
separatorsに一致するそれぞれの部分が分割箇所を定義する。
分割箇所のあいだにある部分文字列をリストにまとめ、これを値とする。
separatorsがnil である(つまり、省略する)と、
デフォルトは"[ \f\t\n\r\v]+" である。
たとえば、つぎのようになる。 (split-string "Soup is good food" "o") => ("S" "up is g" "" "d f" "" "d") (split-string "Soup is good food" "o+") => ("S" "up is g" "d f" "d") 文字列の先頭や末尾で一致した場合には、 リストの先頭や末尾に空文字列は現れない。 (split-string "out to moo" "o+") => ("ut t" " m") 空の一致箇所は、それらが連続していない限り分割点になる。 (split-string "Soup is good food" "o*") =>("S" "u" "p" " " "i" "s" " " "g" "d" " " "f" "d") (split-string "Nice doggy!" "") =>("N" "i" "c" "e" " " "d" "o" "g" "g" "y" "!") |
既存の文字列の内容を変更するもっとも基本的な方法は、
aset
(see Array Functions)を使うことです。
(aset string idx char)
は、
stringの添字idx位置にcharを格納します。
各文字は1バイト以上を占めます。
charが必要とするバイト数が指定した添字位置の文字が占めるバイト数と
異なる場合には、aset
はエラーを通知します。
より強力な関数はstore-substring
です。
store-substring string idx obj | Function |
この関数は、文字列stringの添字idx位置から始まる部分にobjを
格納することで、文字列stringの内容の一部分を変更する。
引数objは文字であるか(より小さな)文字列。
既存の文字列の長さを変更することは不可能なので、 新たな文字に必要なバイト数がstringの当該箇所の文字のバイト数と 異なるなどして、 objがstringの実際の長さに収まらないときにはエラーである。 |
char-equal character1 character2 | Function |
この関数は、引数が同じ文字を表していればt を返し、
さもなければnil を返す。
case-fold-search がnil 以外であると、
この関数は大文字小文字の違いを区別しない。
(char-equal ?x ?x) => t (let ((case-fold-search nil)) (char-equal ?x ?X)) => nil |
string= string1 string2 | Function |
この関数は、2つの文字列の各文字が正確に一致すればt を返す。
大文字小文字を区別する。
(string= "abc" "abc") => t (string= "abc" "ABC") => nil (string= "ab" "ABC") => nil 関数 文字列に非ASCII文字が含まれ、 一方がユニバイトであり他方がマルチバイトである場合、 それらが等しいことはない。 see Text Representations。 |
string-equal string1 string2 | Function |
string-equal はstring= の別名。
|
string< string1 string2 | Function |
この関数は2つの文字列を1文字ずつ比較する。
まず、文字列を走査し、対応する文字同士の対で一致しないものを探す。
そのような対の文字の小さいほうがstring1の文字であるならば、
string1が小さく、この関数はt を返す。
文字の小さいほうがstring2の文字であるならば、
string1が大きく、この関数はnil を返す。
2つの文字列が完全に一致する場合、値はnil である。
文字の対は、それらの文字コードで比較する。 ASCII文字集合では、小文字は大文字より大きな数値であり、 数字文字や多くの句読点文字は大文字より小さな数値であることに注意。 ASCII文字はどんな非ASCII文字よりも小さい。 ユニバイト非ASCII文字はマルチバイト非ASCII文字よりもつねに小さい。 (see Text Representations)。 (string< "abc" "abd") => t (string< "abd" "abc") => nil (string< "123" "abc") => t 文字列の長さが異なりstring1の長さまで一致する場合、
結果は (string< "" "abc") => t (string< "ab" "abc") => t (string< "abc" "") => nil (string< "abc" "ab") => nil (string< "" "") => nil |
string-lessp string1 string2 | Function |
string-lessp はstring< の別名。
|
compare-strings string1 start1 end1 string2 start2 end2 &optional ignore-case | Function |
この関数は、string1の指定部分とstring2の指定部分を比較する。
string1の指定部分は、
添字start1位置から始まり添字end1位置までである
(デフォルトは文字列の末尾)。
string2の指定部分は、
添字start2位置から始まり添字end2位置までである
(デフォルトは文字列の末尾)。
どちらの文字列も比較のためにマルチバイトに変換するので
(see Text Representations)、
ユニバイト文字列とマルチバイトが等しくなる場合もある。
ignore-caseが 2つの文字列の指定部分が一致すれば、値は |
assoc-ignore-case key alist | Function |
この関数は、assoc と同様に動作するが、
keyは文字列である必要があり、
compare-strings を用いて比較する点が異なる。
大文字小文字を区別しないで比較する。
|
assoc-ignore-representation key alist | Function |
この関数は、assoc と同様に動作するが、
keyは文字列である必要があり、
compare-strings を用いて比較する点が異なる。
大文字小文字を区別して比較する。
|
バッファ内のテキストを比較する
Comparing Textのcompare-buffer-substrings
も参照してください。
文字列に対して正規表現の一致を取る関数string-match
は、
ある種の文字列比較に使えます。
See Regexp Search。
本節では、文字や文字列と整数のあいだの変換関数について説明します。
format
とprin1-to-string
(see Output Functions)は、
Lispオブジェクトを文字列に変換するために使えます。
read-from-string
(see Input Functions)は、
Lispオブジェクトの文字列表現をオブジェクトに『変換』できます。
関数string-make-multibyte
とstring-make-unibyte
は、
文字列のテキスト表現を変換します(see Converting Representations)。
テキスト文字と一般の入力イベントのテキスト表現を生成する関数
(single-key-description
とtext-char-description
)については、
See Documentation。
これらの関数は、主に、ヘルプメッセージの作成に使います。
char-to-string character | Function |
この関数は、1つの文字characterだけを含む新たな文字列を返す。
関数string のほうがより汎用であるので、
この関数はほぼ廃れている。
see Creating Strings。
|
string-to-char string | Function |
この関数は、stringの先頭文字を返す。
文字列が空であると関数は0を返す。
文字列stringの先頭文字が、ASCIIコードが0のナル文字であるときも、
値は0である。
(string-to-char "ABC") => 65 (string-to-char "xyz") => 120 (string-to-char "") => 0 (string-to-char "\000") => 0 この関数は、存続させるほど有用でなければ、将来、取り除くかもしれない。 |
number-to-string number | Function |
この関数は、numberの表示表現である文字列を返す。
numberは整数か浮動小数点数。
引数が負であれば値の文字列は符号で始まる。
(number-to-string 256) => "256" (number-to-string -23) => "-23" (number-to-string -23.5) => "-23.5"
|
string-to-number string &optional base | Function |
この関数は、string内の文字群が表す数値を返す。
baseがnil 以外ならば、これを基数として整数に変換する。
baseがnil ならば10を基数とする。
浮動小数点数の変換はつねに10を基数とする。
浮動小数点数に対しては別の基数を実装していない。
作業量も多くそのわりには有用とも思えないからである。
解析するとき、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
|
文字列へ/から変換するその他の関数を以下にあげておきます。
concat
concat
は、ベクトルやリストを文字列へ変換する。
see Creating Strings。
vconcat
vconcat
は、文字列をベクトルへ変換する。
see Vector Functions。
append
append
は、文字列をリストへ変換する。
see Building Lists。
書式付け(formatting)とは、 定数文字列内のさまざま部分を計算値で置き換えた文字列を作ることです。 この文字列は、文字列自体に加えて、 他の値をどのように表示するかも制御します。 この文字列を書式付け文字列(format string)と呼びます。
書式付けは、表示するメッセージを計算する場合に便利です。
実際、関数message
と関数error
には、
ここで説明するのと同じ書式付け機能があります。
それらとformat
との違いは、
書式付けした結果をどのように利用するかです。
format string &rest objects | Function |
この関数は、stringをコピーし、 コピー内の書式付け指定を対応するobjectsの表現で置き換えた 新たな文字列を返す。 引数objectsは書式付けすべき計算値である。 |
書式付け指定は%
で始まる文字の列です。
したがって、string内に%d
があると、
関数format
はそれを書式付けすべき値の1つ
(引数objectsの1つ)の表示表現で置き換えます。
たとえば、つぎのとおりです。
(format "The value of fill-column is %d." fill-column) => "The value of fill-column is 72."
stringに2個以上の書式付け指定がある場合、 書式付け指定はobjectsの後続の値に対応します。 つまり、stringの最初の書式付け指定は最初の値を使い、 2番目の書式付け指定は2番目の値を使い、といった具合です。 (値が対応しない)余計な書式付け指定は、 予測不可能なふるまいを引き起こします。 余計な値は無視します。
特定の書式付け指定は、特定の型の値を必要とします。 要求に適合しない値を読者が指定するとエラーを通知します。
有効な書式付け指定をつぎに示します。
%s
prin1
ではなくprinc
を用いる。see Output Functions)
表示表現で置き換える。
したがって、文字列は"
文字なしでその内容を表示し、
シンボルは\
文字なしで表示する。
対応するオブジェクトがなければ空文字列を使う。
%S
prin1
を用いる。see Output Functions)
表示表現で置き換える。
したがって、文字列は"
文字で囲んで表示し、
シンボルは特別な文字のまえには\
文字を付けて表示する。
対応するオブジェクトがなければ空文字列を使う。
%o
%d
%x
%c
%e
%f
%g
%%
%
を入れる。
この書式付け指定は、値を使わない点で特別である。
たとえば、(format "%% %d" 30)
は"% 30"
を返す。
上記以外の書式付け文字は、エラーInvalid format operation
になります。
例をいくつか示します。
(format "The name of this buffer is %s." (buffer-name)) => "The name of this buffer is strings.texi." (format "The buffer object prints as %s." (current-buffer)) => "The buffer object prints as strings.texi." (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 "%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
は、どんな幅を指定しても、
オブジェクトの表示表現を切り詰めることはありません。
つまり、情報を失うことなく、数前置子を使って最小の桁幅を指定できます。
つぎの3つの例において、%7s
は最小幅7を指定します。
最初の例では、%7s
に置き換わる文字列は3文字ですから、
パディングとして空白4個を挿入します。
2番目の例では、文字列"specification"
は13文字幅ですが切り詰めません。
3番目の例では、右側にパディングします。
(format "The word `%7s' actually has %d letters in it." "foo" (length "foo")) => "The word ` foo' actually has 3 letters in it." (format "The word `%7s' actually has %d letters in it." "specification" (length "specification")) => "The word `specification' actually has 13 letters in it." (format "The word `%-7s' actually has %d letters in it." "foo" (length "foo")) => "The word `foo ' actually has 3 letters in it."
大文字小文字変換関数は、1文字や文字列内の大文字小文字を変更します。
関数は、通常、アルファベット文字
(非ASCII文字のアルファベットに加えて、
A
からZ
とa
からz
)だけを変換します。
それ以外の文字は変わりません。
(大文字小文字テーブルを指定して異なる大文字小文字変換を指定できる。
see Case Tables)
これらの関数は、引数として渡した文字列は変更しません。
以下の例では、文字X
とx
を使います。
ASCIIコードは、それぞれ、88と120です。
downcase string-or-char | Function |
この関数は、文字や文字列を小文字に変換する。
(downcase "The cat in the hat") => "the cat in the hat" (downcase ?X) => 120 |
upcase string-or-char | Function |
この関数は、文字や文字列を大文字に変換する。
(upcase "The cat in the hat") => "THE CAT IN THE HAT" (upcase ?x) => 88 |
capitalize string-or-char | Function |
この関数は、文字列や文字をキャピタライズ(先頭文字だけを大文字に)する。
string-or-charが文字列ならば、
この関数は、string-or-charのコピーの各単語をキャピタライズしたものを
内容とする新たな文字列を作成して返す。
つまり、各単語の先頭文字だけを大文字にして残りを小文字にする。
単語の定義は、現在の構文テーブル(See Syntax Class Table)において 単語構成文字に分類された文字が連続した列である。
(capitalize "The cat in the hat") => "The Cat In The Hat" (capitalize "THE 77TH-HATTED CAT") => "The 77th-Hatted Cat" (capitalize ?x) => 88 |
upcase-initials string | Function |
この関数は、string内の単語の先頭文字だけを大文字にし、
先頭文字以外の文字は変更しない。
この関数は、stringのコピーの各単語の先頭文字を大文字に変換したものを
内容とする新たな文字列を返す。
単語の定義は、現在の構文テーブル(See Syntax Class Table)において 単語構成文字に分類された文字が連続した列である。 (upcase-initials "The CAT in the hAt") => "The CAT In The HAt" |
文字列を比較する関数については、See Text Comparison。 これらは、大文字小文字を区別しないものもあれば、 場合によって大文字小文字を区別しないものもある。
特別な大文字小文字テーブル(case table)をインストールすれば、 大文字小文字変換をカスタマイズできます。 大文字小文字テーブルは、大文字と小文字の対応関係を指定します。 このテーブルは、Lispオブジェクトの大文字小文字変換関数(前節参照)と バッファ内のテキストに作用する大文字小文字変換関数(see Case Changes)の 両方に影響します。 各バッファごとに大文字小文字テーブルがあります。 新たなバッファの大文字小文字テーブルを初期化するために使う 標準の大文字小文字テーブルもあります。
大文字小文字テーブルは、サブタイプがcase-table
である
文字テーブル(see Char-Tables)です。
この文字テーブルは、各文字を対応する小文字に対応付けます。
これには3つの追加スロットがあり、関連するテーブルを保持します。
単純な場合、必要なことは、小文字への対応付けを指定するだけです。 関連する3つのテーブルはこの対応付けから自動的に計算されます。
言語によっては、大文字と小文字の対応関係が1対1でないことがあります。 2つの異なる小文字が同じ大文字に対応することがあります。 このような場合、大文字から小文字への対応付けと、 小文字から大文字への対応付けの両方を指定する必要があります。
追加のテーブルcanonicalize(正則)は、各文字を正則文字に対応付けます。
2つの任意の文字が大文字小文字変換で関連付けられている場合、
その2つの文字は同一の正則文字を持ちます。
たとえば、a
とA
は、大文字小文字変換で関連付けられているので、
これらは同一の正則文字を持つはずです
(両方の文字に対してa
であるか、両方の文字に対してA
である)。
追加のテーブルequivalences(同値)は、
同じ正則クラス(同一の正則文字を持つ文字群)の文字を巡回して対応付けます。
(普通のASCIIでは、a
をA
に対応付け、
A
をa
に対応付ける。
各正則クラスについても同様。)
大文字小文字テーブルを作成するときには、
canonicalize(正則)にはnil
を指定できます。
そうすると、Emacsはこのスロットを小文字と大文字の対応付けから埋めます。
equivalences(同値)にもnil
を指定できます。
そうすると、Emacsはこのスロットをcanonicalize(正則)から埋めます。
実際に使用している大文字小文字テーブルでは、
これらの要素はnil
以外です。
canonicalize(正則)を指定せずに
equivalences(同値)を指定しないでください、
つぎに、大文字小文字テーブルを操作する関数を示します。
case-table-p object | Function |
この述語は、objectが正しい
大文字小文字テーブルならばnil 以外を返す。
|
set-standard-case-table table | Function |
この関数は、tableを標準の大文字小文字テーブルとし、 これ以降に作成する任意のバッファに使用できるようにする。 |
standard-case-table | Function |
これは、標準の大文字小文字テーブルを返す。 |
current-case-table | Function |
この関数は、カレントバッファの大文字小文字テーブルを返す。 |
set-case-table table | Function |
これは、カレントバッファの大文字小文字テーブルをtableとする。 |
以下の3つ関数は、非ASCII文字集合を定義するパッケージ向けの 便利なサブルーティンです。 これらは、指定した大文字小文字テーブルcase-tableを変更します。 さらに、標準の構文テーブルも変更します。 See Syntax Tables。 普通、標準の大文字小文字テーブルを変更するためにこれらの関数を使います。
set-case-syntax-pair uc lc case-table | Function |
この関数は対応する大文字と小文字を指定する。 |
set-case-syntax-delims l r case-table | Function |
この関数は、文字lとrを 大文字小文字不変区切りの対応する対にする。 |
set-case-syntax char syntax case-table | Function |
この関数は、charを構文syntaxの大文字小文字不変にする。 |
describe-buffer-case-table | コマンド |
このコマンドは、カレントバッファの大文字小文字テーブルの内容を記述する。 |
リスト(list)は、0個以上の(任意のLispオブジェクトの)要素の列を 表現します。 リストとベクトルの重要な相違点は、 複数のリストがそれらの構造の一部を共有できることです。 さらに、リスト全体をコピーすることなく、 リストに要素を追加したり削除できることです。
Lispのリストは基本データ型ではありません。 リストはコンスセル(cons cells)で構成されます。 コンスセルはドット対を表現するデータオブジェクトです。 ドット対は2つのLispオブジェクトを保持、つまり、『指し』ます。 その2つのLispオブジェクトの一方をCAR、他方をCDRといいます。 これらの名前は歴史的なものです。 See Cons Cell Type。 CDRは『クダー』と読みます。
リストはコンスセルを連ねたものであり、
リストの各要素ごとにコンスセルが1つあります。
慣習として、コンスセルのCARはリストの要素であり、
CDRはリストを繋ぐために使います。
つまり、各コンスセルのCDRは後続のコンスセルです。
最後のコンスセルのCDRはnil
です。
CARとCDRの非対称性は単なる慣習によるものです。
コンスセルのレベルでは、CARとCDRには同じ性質があります。
ほとんどのコンスセルはリストの一部として使われるので、 リスト構造(list structure)という用語は、 コンスセルで構成した任意の構造を意味するようになりました。
シンボルnil
は、シンボルであるとともにリストでもあるとみなします。
これは要素を持たないリストです。
慣習として、シンボルnil
のCDR(およびCAR)は
nil
であるとみなします。
空でない任意のリストlのCDRは、 lの先頭要素を除くすべての要素を含んだリストです。
コンスセルは1対の箱で図示できます。
最初の箱はCARを表し、2番目の箱はCDRを表します。
つぎは、2つのコンスセルから成る
2要素のリスト(tulip lily)
を図示したものです。
--------------- --------------- | car | cdr | | car | cdr | | tulip | o---------->| lily | nil | | | | | | | --------------- ---------------
各1対の箱がコンスセルを表します。
各箱は、Lispオブジェクトを『参照する』、『指す』、『含む』のです。
(これらの用語は同義語。)
最初のコンスセルのCARを表す最初の箱は、
シンボルtulip
を含みます。
最初のコンスセルのCDR箱から2番目のコンスセルへ向かう矢印は、
最初のコンスセルのCDRが2番目のコンスセルであることを表します。
同じリストは、つぎのような別の箱記法でも図示できます。
--- --- --- --- | | |--> | | |--> nil --- --- --- --- | | | | --> tulip --> lily
つぎは、より複雑で、最初の要素が2要素リストであるような 3要素リストを図示したものです。
--- --- --- --- --- --- | | |--> | | |--> | | |--> nil --- --- --- --- --- --- | | | | | | | --> oak --> maple | | --- --- --- --- --> | | |--> | | |--> nil --- --- --- --- | | | | --> pine --> needles
同じリストを最初の箱記法で表現するとつぎのようになります。
-------------- -------------- -------------- | car | cdr | | car | cdr | | car | cdr | | o | o------->| oak | o------->| maple | nil | | | | | | | | | | | -- | --------- -------------- -------------- | | | -------------- ---------------- | | car | cdr | | car | cdr | ------>| pine | o------->| needles | nil | | | | | | | -------------- ----------------
コンスセルとリストの入力構文と表示表現、および、 『箱と矢印』によるリストの図示については、See Cons Cell Type
以下の述語は、Lispオブジェクトが、アトムであるか、
コンスセル、つまり、リストであるか、
特別なオブジェクトnil
であるか調べます。
(これらの多く述語は、それぞれ残りの述語で定義可能である。
しかし、多用するため、これらすべてを用意しておく価値がある。)
consp object | Function |
この関数は、objectがコンスセルならばt を返し、
さもなければnil を返す。
nil はコンスセルではないが、空リストである。
|
atom object | Function |
この関数は、objectがアトムならばt を返し、
さもなければnil を返す。
コンスセルを除くすべてのオブジェクトはアトムである。
シンボルnil はアトムでもありリストでもある。
このようなLispオブジェクトはnil だけである。
(atom object) == (not (consp object)) |
listp object | Function |
この関数は、objectがコンスセルかnil ならばt を返す。
さもなければnil を返す。
(listp '(1)) => t (listp '()) => t |
nlistp object | Function |
この関数は、listp の反対である。
objectがリストでなければt を返す。
さもなければnil を返す。
(listp object) == (not (nlistp object)) |
null object | Function |
この関数は、objectがnil ならばt を返し、
さもなければnil を返す。
この関数は、not と同一であるが、意図を明確にするために、
objectをリストと考えるときにはnull を使い、
objectを真理値と考えるときにはnot を使う
(Combining Conditionsのnot を参照)
(null '(1)) => nil (null '()) => t |
car cons-cell | Function |
この関数は、コンスセルcons-cellの最初のポインタが指す値を返す。
別のいい方をすれば、cons-cellのCARを返す。
特別な場合として、cons-cellが (car '(a b c)) => a (car '()) => nil |
cdr cons-cell | Function |
この関数は、コンスセルcons-cellの2番目のポインタが指す値を返す。
別のいい方をすれば、cons-cellのCDRを返す。
特別な場合として、cons-cellが (cdr '(a b c)) => (b c) (cdr '()) => nil |
car-safe object | Function |
この関数は、コンスセルのCARを取り出すが、
他のデータ型に対するエラーを回避する。
objectがコンスセルならばobjectのCARを返すが、
さもなければnil を返す。
これはcar と対照的であり、
car はobjectがリストでないとエラーを通知する。
(car-safe object) == (let ((x object)) (if (consp x) (car x) nil)) |
cdr-safe object | Function |
この関数は、コンスセルのCDRを取り出すが、
他のデータ型に対するエラーを回避する。
objectがコンスセルならばobjectのCDRを返すが、
さもなければnil を返す。
これはcdr と対照的であり、
cdr はobjectがリストでないとエラーを通知する。
(cdr-safe object) == (let ((x object)) (if (consp x) (cdr x) nil)) |
nth n list | Function |
この関数は、listのn番目の要素を返す。
要素は0から数えるので、listのCARは要素番号0。
listの長さがnかそれ未満であると、値はnil になる。
nが負であると、 (nth 2 '(1 2 3 4)) => 3 (nth 10 '(1 2 3 4)) => nil (nth -3 '(1 2 3 4)) => 1 (nth n x) == (car (nthcdr n x)) 関数 |
nthcdr n list | Function |
この関数は、listのn番目のCDRを返す。
いいかえれば、listの始めのn個のリンクを飛び越えて、
そのあとにあるものを返す。
nが0か負であると、 (nthcdr 1 '(1 2 3 4)) => (2 3 4) (nthcdr 10 '(1 2 3 4)) => nil (nthcdr -3 '(1 2 3 4)) => (1 2 3 4) |
safe-length list | Function |
この関数は、エラーや無限ループを回避して、listの長さを返す。
listが実際にはリストでない場合には、 |
循環はないと思われるリストの長さを計算するもっとも一般的な方法は、
length
です。
See Sequence Functions。
caar cons-cell | Function |
これは(car (car cons-cell)) と同じ。
|
cadr cons-cell | Function |
これは(car (cdr cons-cell)) や
(nth 1 cons-cell) と同じ。
|
cdar cons-cell | Function |
これは(cdr (car cons-cell)) と同じ。
|
cddr cons-cell | Function |
これは(cdr (cdr cons-cell)) や
(nthcdr 2 cons-cell) と同じ。
|
リストはLispの中核なので、多くの関数はリストを構築します。
cons
は基本的なリスト構築関数です。
しかし、Emacsのソースコードでは、cons
よりlist
を
多用していることは興味深いことです。
cons object1 object2 | Function |
この関数は、新たなリスト構造を構築するために使う基本関数。
object1をCAR、object2をCDRとする
新たなコンスセルを作成し、このコンスセルを返す。
引数object1とobject2はどんなLispオブジェクトでもよいが、
ほとんどの場合、object2はリストである。
(cons 1 '(2)) => (1 2) (cons 1 '()) => (1) (cons 1 2) => (1 . 2)
(setq list (cons newelt list)) この例における |
list &rest objects | Function |
この関数は、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 |
make-list length object | Function |
この関数は、すべての要素が同一の値objectであり
長さがlengthのリストを作成する。
make-string と比較してほしい(see Creating Strings)。
(make-list 3 'pigs) => (pigs pigs pigs) (make-list 0 'pigs) => nil |
append &rest sequences | Function |
この関数はsequencesのすべての要素から成るリストを返す。
sequencesは、リスト、ベクトル、ブールベクトル、文字列のいずれかであるが、
普通、最後の要素はリストである。
最後の引数を除いてすべての引数をコピーするので、どの引数も変更しない
(コピーせずにリストを繋ぐ方法については、
Rearrangementのnconc を参照。)
一般には、 関数 |
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
を導入するまでは、
リストをコピーする普通の方法でした。
See Sequences Arrays Vectors。
append
の引数にベクトルと文字列を使った例をつぎに示します。
(append [a b] "cd" nil) => (a b 99 100)
apply
(see Calling Functions)の助けを借りれば、
リストのリストの中にあるすべてのリストを連結できます。
(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になります。
reverse list | Function |
この関数は、listの要素を逆順にした新たなリストを作成する。
もとの引数listは変更しない。
(setq x '(1 2 3 4)) => (1 2 3 4) (reverse x) => (4 3 2 1) x => (1 2 3 4) |
基本関数setcar
やsetcdr
を使って、
コンスセルのCARやCDRの内容を変更できます。
これらは、既存のリスト構造を変更するので、
『破壊的』な操作と呼びます。
Common Lispに関した注意:Common Lispでは、 リスト構造を変更するには
rplaca
やrplacd
を使う。 これらはsetcar
やsetcdr
と同様に構造を変更する。 しかし、Common Lispの関数はコンスセルを返すが、setcar
やsetcdr
は新たなCARやCDRを返す。
setcar
によるリスト要素の変更コンスセルのCARを変更するには、setcar
を使います。
リストに対して使用すると、
setcar
はリストの1つの要素を別の要素に置き換えます。
setcar cons object | Function |
この関数は、consの新たなCARとしてobjectを格納し、
以前のCARを置き換える。
いいかえれば、consのCARスロットがobjectを指すように変更する。
この関数は値objectを返す。
たとえば、つぎのようになる。
(setq x '(1 2)) => (1 2) (setcar x 4) => 4 x => (4 2) |
コンスセルが複数のリストの共有構造の一部であるときには、 コンスセルに新たなCARを格納すると、 そのような各リストの1つの要素を変更することになります。
;; 共有部分がある2つのリストを作る (setq x1 '(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)
変数x1
とx2
に入っている共有部分を持つ2つのリストを図示すると
つぎのようになります。
b
を置き換えるとなぜ両者が変更されるのかわかるでしょう。
--- --- --- --- --- --- 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---- | | | --------------
CDRを修正するもっとも低レベルの基本関数はsetcdr
です。
setcdr cons object | Function |
この関数は、consの新たなCDRとしてobjectを格納し、 以前のCDRを置き換える。 いいかえれば、consのCDRスロットがobjectを指すように変更する。 この関数は値objectを返す。 |
リストのCDRを別のリストで置き換える例を示します。 リストの最初の要素以外は取り除かれ、 要素の別のシーケンスになります。 最初の要素は変更されません。 というのは、それはリストのCARの中にあり、 CDRからは辿れないからです。
(setq x '(1 2 3)) => (1 2 3) (setcdr x '(4)) => (4) x => (1 4)
リスト内のコンスセル群のCDRを変更することで、
リストの中ほどの要素を削除できます。
つぎの例は、リスト(a b c)
の最初のコンスセルのCDRを変更することで、
このリストの第2要素b
を削除します。
(setq x1 '(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番目のコンスセルはまだ存在していて、
そのCARもまだb
ですが、このリストの一部ではありません。
CDRを変更して新たな要素を挿入するのも同様に簡単です。
(setq x1 '(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------ | | | ---------------
以下は、リストを構成するコンスセルのCDRを変更することで、 『破壊的に』リストの順序を変更する関数です。 これらの関数を『破壊的』と呼ぶのは、 渡された引数であるもとのリストのコンスセルを繋ぎ換えて新たなリストに 変えるからです。
nconc &rest lists | Function |
この関数は、listsのすべての要素を入れたリストを返す。
append (see Building Lists)と異なり、
listsをコピーしない。
そのかわりに、各listsの最後のCDRを後続のリストを指すように変更する。
listsの最後は変更しない。
たとえば、つぎのようになる。
(setq x '(1 2 3)) => (1 2 3) (nconc x '(4 5)) => (1 2 3 4 5) x => (1 2 3 4 5)
(setq x '(1 2 3)) => (1 2 3) (nconc x 'z) => (1 2 3 . z) x => (1 2 3 . z) しかしながら、すべての引数は(最後のものを除いて)リストである必要がある。 よくある落し穴は、 (defun add-foo (x) ; この関数は引数の先頭に
(nconc '(foo) x)) ;
|
nreverse list | Function |
この関数は、listの要素の順番を逆順にする。
reverse と異なり、nreverse は
リストを構成するコンスセルのCDRを逆向きにして引数を変えてしまう。
listの最後にあったコンスセルは戻り値の最初のコンスセルになる。
たとえば、つぎのようになる。 (setq x '(1 2 3 4)) => (1 2 3 4) x => (1 2 3 4) (nreverse x) => (4 3 2 1) ;; 先頭にあったコンスセルは、今、最後になっている x => (1) 混乱を避けるために、 (setq x (nreverse x))
もとのリストの先頭 逆順にしたリスト ------------- ------------- ------------ | car | cdr | | car | cdr | | car | cdr | | a | nil |<-- | b | o |<-- | c | o | | | | | | | | | | | | | | ------------- | --------- | - | -------- | - | | | | ------------- ------------ |
sort list predicate | Function |
この関数は、破壊的にではあるが、
listを順序を保ってソートしたリストを返す。
要素の比較にはpredicateを使う。
順序を保ったソートとは、同じソートキーを持つ要素の相対順序を、
ソート実行前後で変更しないソートである。
異なる基準でつぎつぎにソートするときには、
順序を保つことは重要である。
引数predicateは、2つの引数を取る関数である必要がある。
この関数は、listの2つの要素で呼び出される。
昇順のソートでは、predicateは、
第1引数が第2引数より『小さい』ときに 比較関数predicateは、少なくとも単一の
ソートする際、listのコンスセルのCARは変更しない。
list内の要素 (setq nums '(1 3 2 6 5 4 0)) => (1 3 2 6 5 4 0) (sort nums '<) => (0 1 2 3 4 5 6) nums => (1 2 3 4 5 6) 警告: (setq nums (sort nums '<)) ソートを行う他の関数については、see Sorting。
|
リストで、数学の順序のない集合を表現できます。
つまり、リストに現れる要素を集合の要素と考え、
リスト内での順序は無視します。
2つの集合の和集合を作るには、
(要素が重複することを気にしなければ)append
を使います。
集合向けの他の有用な関数には、memq
やdelq
、および、
これらのequal
版であるmember
やdelete
があります。
Common Lispに関した注意:Common Lispには、集合演算向けに (要素の重複を避ける)関数
union
とintersection
があるが、 GNU Emacs Lispにはない。 必要ならば、読者みずからLispでこれらを書ける。
memq object list | Function |
この関数は、objectがlistの要素かどうか調べる。
そうならば、
memq はobjectが最初に現れるところから始まるリストを返す。
さもなければnil を返す。
memq の文字q は、リストの要素に対するobjectの比較に
eq を使うことを意味する。
たとえば、
(memq 'b '(a b c b a)) => (b c b a) (memq '(2) '((1) (2))) ; |
delq object list | Function |
この関数は、listからobjectにeq であるすべての要素を
破壊的に削除する。
delq の文字q は、memq と同様に、
リストの要素に対するobjectの比較にeq を使うことを意味する。
|
delq
がリストの先頭から要素を削除する場合には、
単にリストを辿って削除した要素のつぎから始まる部分リストを返します。
(delq 'a '(a b c)) == (cdr '(a b c))
リストの中ほどの要素を削除する場合には、 削除にはCDRの変更を伴います(see Setcdr)。
(setq sample-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 'c sample-list)
は、
3番目の要素を切り取ってsample-list
を変更しますが、
(delq 'a sample-list)
では、
なにも切り取らずに単に短いリストを返すことに注意してください。
引数listを保持していた変数が、実行後には少ない要素を持つと仮定したり、
もとのリストを保持し続けていると仮定したりしないでください!
そのかわりに、delq
の結果を保存して、それを使ってください。
多くの場合、つぎのように、
もとのリストを保持していた変数に結果を保存し直します。
(setq flowers (delq 'rose flowers))
つぎの例では、delq
が一致を取ろうとしている(4)
と
sample-list
の(4)
とはeq
ではありません。
(delq '(4) sample-list) => (a c (4))
つぎの2つの関数は、memq
やdelq
に似ていますが、
比較にはeq
のかわりにequal
を使います。
See Equality Predicates。
member object list | Function |
関数member は、equal を使ってobjectと要素を比較して、
objectがlistの要素かどうか調べる。
objectが要素であれば、
member はlist内でそれが最初に現れるところから始まるリストを返す。
さもなければnil を返す。
(member '(2) '((1) (2))) ; |
delete object list | Function |
この関数は、listからobjectにequal であるすべての要素を
破壊的に削除する。
member がmemeq に対応するように、delq に対応する。
member と同様に、
要素とobjectとの比較にはequal を使う。
一致する要素をみつけると、delq と同様に要素を削除する。
たとえば、つぎのとおり。
(delete '(2) '((2) (1) (2))) => ((1)) |
Common Lispに関した注意:GNU Emacs Lispの関数
member
と関数delete
は Maclispから受け継いだものであり、Common Lispからではない。 Common Lisp版では要素の比較にはequal
を使わない。
変数に格納したリストに要素を追加する別の方法については、
Setting Variablesの関数add-to-list
を参照してください。
連想リスト(association list)、略してalistは、 キーから値への対応付けを記録しています。 これは連想(associations)と呼ばれるコンスセルのリストです。 各コンスセルのCARはkeyであり、 CDRは連想値(associated value)です。 6
連想リストの例を示します。
キーpine
を値cones
に、キーoak
を値acorns
に、
キーmaple
を値seeds
に対応付けています。
'((pine . cones) (oak . acorns) (maple . seeds))
連想リスト内の連想値は任意のLispオブジェクトでよく、キーもそうです。
たとえば、つぎの連想リストでは、シンボルa
に数1
を、
文字列"b"
にリスト(2 3)
を対応付けています。
リスト(2 3)
は連想リストの要素のCDRです。
((a . 1) ("b" 2 3))
要素のCDRのCARに連想値を格納するように 連想リストを設計したほうがよい場合もあります。 つぎのようにします。
'((rose red) (lily white) (buttercup yellow))
ここで、red
はrose
に対応付けた値と考えます。
この種の連想リストの利点の1つは、関連する別の情報を、
他の項目から成るリストでさえも、CDRのCDRに格納できることです。
1つの欠点は、rassq
(下記参照)を使って
指定した値を含む要素を探せないことです。
これらの条件が重要でない場合には、1つの連想リストに関する限り、
一貫性があればどちらを選ぶかは好みの問題です。
上に示した連想リストは、要素のCDRに連想値が収めてあると
考えることもできます。
rose
の連想値はリスト(red)
になります。
連想リストはスタックなどに置くような情報の記録に使います。 というには、リストの先頭に新たな連想を追加するのが簡単だからです。 指定したキーに対する連想を連想リストから探すとき、 それらが複数個存在する場合には、最初にみつかったものを返します。
Emacs Listでは、連想リストの要素がコンスセルでなくても エラーではありません。 連想リスト探索関数はそのような要素を単に無視します。 他の多くのLispでは、そのような場面ではエラーを通知します。
属性リストもいろいろな意味で連想リストに類似しています。 属性リストは、キーが一度しか現れない連想リストのようにふるまいます。 属性リストと連想リストの比較については、See Property Lists。
assoc key alist | Function |
この関数は、alist内のkeyに対する最初の連想を返す。
keyと連想リストの各要素との比較には、
equal (see Equality Predicates)を用いる。
alistの中にCARがkeyにequal である連想が
存在しなければ、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-ignore-representation
とassoc-ignore-case
は
assoc
に似ていますが、
それらは比較にcompare-strings
を使う点が異なります。
See Text Comparison。
rassoc value alist | Function |
この関数は、alistの中でvalueを値とする最初の連想を返す。
alistの中にCDRがvalueにequal である連想が
存在しなければ、nil を返す。
|
assq key alist | Function |
この関数は、alist内のkeyに対する最初の連想を返すという意味で
assoc に似ているが、equal のかわりにeq で比較する。
alist内の連想のCARがkeyにeq であるものが存在しないと、
assq はnil を返す。
この関数はassoc より多用される。
というのは、eq はequal より高速であり、
ほとんどの連想リストではキーとしてシンボルを使うからである。
(setq trees '((pine . cones) (oak . acorns) (maple . seeds))) => ((pine . cones) (oak . acorns) (maple . seeds)) (assq 'pine trees) => (pine . cones) 一方で、キーがシンボルではない連想リストでは、
(setq leaves '(("simple leaves" . oak) ("compound leaves" . horsechestnut))) (assq "simple leaves" leaves) => nil (assoc "simple leaves" leaves) => ("simple leaves" . oak) |
rassq value alist | Function |
この関数は、alistの中でvalueを値とする最初の連想を返す。
alistの中にCDRがvalueにeq である連想が
存在しなければ、nil を返す。
たとえばつぎのとおり。 (setq trees '((pine . cones) (oak . acorns) (maple . seeds))) (rassq 'acorns trees) => (oak . acorns) (rassq 'spores trees) => nil
(setq colors '((rose red) (lily white) (buttercup yellow))) (rassq 'white colors) => nil この場合、連想 (lily white) == (lily . (white)) |
assoc-default key alist test default | Function |
この関数は、keyに一致するものをalistから探す。
alistの各要素について、(アトムならば)要素とkeyを、
あるいは、(コンスならば)要素のCARとkeyを比較する。
比較にはこれらを2つの引数としてtestを呼び出す。
引数を渡す順序はこの順なので、
正規表現(see Regexp Search)を収めた連想リストに対して
string-match を使うと有益な結果を得られる。
testを省略したりnil であると、比較にはequal を用いる。
上の条件で連想リストの要素がkeyに一致するならば、
keyに一致する連想リストの要素が存在しなければ、
|
copy-alist alist | Function |
この関数は、alistを2レベルの深さまでコピーしたものを返す。
各連想ごとに新たなコピーを作るので、
新たな連想リストの連想を変更しても、もとの連想リストは変更しない。
(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 この例は、 (setcdr (assq 3 copy) '("Martian Vacuum Pine")) (cdr (assq 3 needles-per-cluster)) => ("Pitch Pine") |
シーケンス(sequence)型とは、Lispの2つの異なる型の和であることを 思い出してください。 いいかえれば、任意のリストはシーケンスであり、 任意の配列もシーケンスです。 すべてのシーケンスに共通する性質は、 それぞれ、要素の順序付けた集まりであるということです。
配列(array)は、各要素ごとに1つ1つスロットを用意してある 単一の基本オブジェクトです。 すべての要素は一定時間内に参照できますが、既存の配列の長さは変更できません。 文字列、ベクトル、文字テーブル、ブールベクトルは、配列型の4つの型です。
リストは、要素を並べたものですが、 単一の基本オブジェクトではありません。 コンスセルから作られていて、1つの要素あたり1つのセルがあります。 n番目の要素を探すには、n個のコンスセルを調べる必要があるので、 リストの先頭から遠い要素を参照するには余計に時間がかかります。 しかし、リストには要素を追加したり削除したりできます。
以下の図は、これらの型の関係を示します。
┌────────────────────────┐ │ シーケンス │ │┌───┐ ┌───────────────┐ │ ││ │ │ │ │ ││リスト│ │ 配列 │ │ ││ │ │ ┌────┐ ┌───┐ │ │ ││ │ │ │ │ │ | │ │ │└───┘ │ │ベクトル│ │文字列| │ │ │ │ │ │ │ | │ │ │ │ └────┘ └───┘ │ │ │ │ ┌────┐ ┌────┐ │ │ │ │ │文字 │ │ブール │ │ │ │ │ │テーブル│ │ベクトル│ │ │ │ │ └────┘ └────┘ │ │ │ └───────────────┘ │ └────────────────────────┘
ベクトルやリストの要素は、どんなLispオブジェクトでもかまいません。 文字列の要素はすべて文字です。
Emacs Lispでは、シーケンス(sequence)とはリストか配列のことです。 すべてのシーケンスに共通する性質は、 要素の順序付けた集まりであるということです。 本節では任意のシーケンスを受け付ける関数を説明します。
sequencep object | Function |
objectが、リスト、ベクトル、あるいは、文字列ならばt を返し、
さもなければnil を返す。
|
length sequence | Function |
この関数はsequence内の要素の個数を返す。
sequenceが(最後のCDRがnil ではないため)
リストではないコンスセルであると、
エラーwrong-type-argument を通知する。
関連する関数 (length '(1 2 3)) => 3 (length ()) => 0 (length "foobar") => 6 (length [1 2 3]) => 3 (length (make-bool-vector 5 nil)) => 5 |
elt sequence index | Function |
この関数はindexで添字付けされるsequenceの要素を返す。
indexの正当な値は、0からsequenceの長さより1小さい範囲の
整数である。
sequenceがリストである場合には、
範囲外のindexに対してはnil を返す。
さもなければエラーargs-out-of-range を引き起こす。
(elt [1 2 3 4] 2) => 3 (elt '(1 2 3 4) 2) => 3 ;; この関数は、 |
copy-sequence sequence | Function |
sequenceのコピーを返す。
コピーは、もとのシーケンスと同じ型のオブジェクトであり、
同じ要素が同じ順序で入っている。
コピーに新たな要素を格納しても、もとのsequenceには影響せず、
その逆もそうである。
しかし、新たなシーケンスの要素はコピーしていない。
つまり、それらはもとの要素と同一( シーケンスがテキスト属性を持つ文字列である場合には、 コピーの中の属性リストそのものもコピーであり、 もとの属性リストを共有するのではない。 しかし、属性の実際の値は共有される。 シーケンスをコピーする別の方法については、
Building Listsの (setq bar '(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 ;; 1つのシーケンスの1つの要素を置き換える (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)] |
配列(array)オブジェクトには、配列の要素と呼ばれる Lispオブジェクトを保持するためのスロットがいくつかあります。 配列の任意の要素は一定時間で参照できます。 一方、リストの要素の参照には、 リスト内でのその要素の位置に比例した時間が必要です。
Emacsには4つの型の配列があり、すべて1次元です。 文字列(strings)、ベクトル(vectors)、 ブールベクトル(bool-vectors)、文字テーブル(char-tables)です。 ベクトルは汎用の配列であり、 その要素は任意のLispオブジェクトでかまいません。 文字列は特化された配列であり、その要素は文字(つまり、0から255までの整数)で ある必要があります。 配列のそれぞれの型には、独自の入力構文があります。 String TypeとSee Vector Type。
配列の4つの型すべてには、以下の性質があります。
aref
やaset
で行う
(see Array Functions)。
文字テーブル以外の配列を作成するときには、 その長さを指定する必要があります。 文字テーブルの長さは指定できません。 というのは、その長さは文字コードの範囲で決まるからです。
原理的には、テキスト文字の配列が必要ならば文字列かベクトルを使います。 実用上は、以下の4つの理由から、そのような場合には文字列を使います。
一方、(キー列のような)キーボード入力文字の配列には、 ベクトルが必要です。 というのは、キーボード入力文字の多くは、文字列に納まる範囲外だからです。 See Key Sequence Input。
本節では任意の配列型を受け付ける関数を説明します。
arrayp object | Function |
この関数はobjectが配列
(つまり、ベクトル、文字列、ブールベクトル、あるいは、文字テーブル)ならば、
t を返す。
(arrayp [a]) => t (arrayp "asdf") => t (arrayp (syntax-table)) ;; 文字テーブル => t |
aref array index | Function |
この関数はarrayのindex番目の要素を返す。
最初の要素の添字は0。
(setq primes [2 3 5 7 11 13])
=> [2 3 5 7 11 13]
(aref primes 4)
=> 11
(aref "abcdefg" 1)
=> 98 ;
Sequence Functionsの関数elt も参照。
|
aset array index object | Function |
この関数は配列arrayのindex番目の要素にobjectを設定する。
objectを返す。
(setq w [foo bar baz]) => [foo bar baz] (aset w 0 'fu) => fu w => [fu bar baz] (setq x "asdfasfd") => "asdfasfd" (aset x 3 ?Z) => 90 x => "asdZasfd" arrayが文字列であり、かつ、objectが文字でなければ、
結果はエラー |
fillarray array object | Function |
この関数は、配列arrayをobjectで埋め、
arrayの各要素がobjectとなるようにする。
arrayを返す。
(setq a [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 "When in the course") => "When in the course" (fillarray s ?-) => "------------------" arrayが文字列であり、かつ、objectが文字でなければ、
結果はエラー |
配列であることが既知のオブジェクトに対しては、
汎用のシーケンス関数copy-sequence
やlength
がしばしば有用です。
See Sequence Functions。
Lispの配列は、ほとんどの言語の配列と同様に、 その要素を一定時間で参照可能なメモリのブロックです。 ベクトル(vector)は指定長の汎用配列です。 その要素はどんなLispオブジェクトでもかまいません。 (対照的に、文字列は要素としては文字だけを保持する。) Emacsでは、オブジェクト配列obarray(シンボルのベクトル)、 キーマップ(コマンドのベクトル)の一部にベクトルを使っています。 これらは、内部的には、バイトコード関数の表現の一部にも使っています。 そのような関数を表示すると、その中にベクトルがあるのがわかります。
Emacs Lispでは、ベクトルの要素の添字は0から始まります。
ベクトルは要素を角括弧で囲んで表示します。
したがって、要素がシンボルa
、b
、a
であるベクトルは、
[a b a]
と表示されます。
Lispへの入力では同じようにベクトルを書きます。
文字列や数と同様に、評価上、ベクトルは定数とみなします。 それを評価した結果は、同じベクトルです。 この評価では、ベクトルの要素を評価したり調べたりはしません。
以下は、これらの原理を例示するものです。
(setq avector [1 two '(three) "four" [five]]) => [1 two (quote (three)) "four" [five]] (eval avector) => [1 two (quote (three)) "four" [five]] (eq avector (eval avector)) => t
ベクトルに関連した関数はつぎのとおりです。
vectorp object | Function |
この関数は、objectがベクトルならばt を返す。
(vectorp [a]) => t (vectorp "asdf") => nil |
vector &rest objects | Function |
この関数は、引数objectsを要素とするベクトルを作成しそれを返す。
(vector 'foo 23 [bar baz] "rats") => [foo 23 [bar baz] "rats"] (vector) => [] |
make-vector length object | Function |
この関数は、各要素をobjectに初期化した
length個の要素から成る新たなベクトルを返す。
(setq sleepy (make-vector 9 'Z)) => [Z Z Z Z Z Z Z Z Z] |
vconcat &rest sequences | Function |
この関数は、sequencesのすべての要素を入れた新たなベクトルを返す。
引数sequencesは、リスト、ベクトル、文字列を含む任意の配列でよい。
sequencesを指定しないと空ベクトルを返す。
その値は、既存のベクトルと (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)] 関数 関数 他の連結関数については、
Mapping Functionsの |
関数append
は、ベクトルを同じ要素から成るリストへ変換する便利な方法です
(see Building Lists)。
(setq avector [1 two (quote (three)) "four" [five]]) => [1 two (quote (three)) "four" [five]] (append avector nil) => (1 two (quote (three)) "four" [five])
文字テーブルはベクトルによく似ていますが、
文字コードで添字付けする点が異なります。
修飾子を伴わない任意の正当な文字コードは、文字テーブルの添字に使えます。
文字テーブルの要素は、任意の配列のように、aref
やaset
で
参照できます。
さらに、文字テーブルでは、
特定の文字コードには対応しない追加データを保持するための追加スロットを
保持できます。
評価時には、文字テーブルは定数です。
各文字テーブルには、シンボルであるサブタイプ(subtype)があります。
サブタイプには2つの目的があります。
異なる使い方をする文字テーブルを区別するためと、
追加スロットの個数を制御するためです。
たとえば、表示テーブルはサブタイプがdisplay-table
である
文字テーブルであり、
構文テーブルはサブタイプがsyntax-table
である文字テーブルです。
正当なサブタイプには、char-table-extra-slots
属性があるはずで、
その値は0から10までの整数です。
この整数が文字テーブルの追加スロットの個数を指定します。
文字テーブルは、別の文字テーブルである親を持てます。
その場合、特定の文字cに対する文字テーブルの指定がnil
のときには、
親において指定された値を継承します。
いいかえれば、char-table自体にnil
を指定してあると、
(aref char-table c)
は、
char-tableの親の値を返します。
文字テーブルは、デフォルト値も持てます。
その場合、文字テーブルが指定する値がnil
であると、
(aref char-table c)
はデフォルト値を返します。
make-char-table subtype &optional init | Function |
サブタイプがsubtypeである新たに作成した文字テーブルを返す。
各要素をinitで初期化する。
なお、initのデフォルトはnil である。
文字テーブル作成後には、文字テーブルのサブタイプは変更できない。
文字テーブルの長さを指定する引数はない。 なぜなら、すべての文字テーブルでは、 任意の正当な文字コードを添字として使えるからである。 |
char-table-p object | Function |
この関数は、objectが文字テーブルならばt を返し、
さもなければnil を返す。
|
char-table-subtype char-table | Function |
この関数はchar-tableのサブタイプを表すシンボルを返す。 |
set-char-table-default char-table new-default | Function |
この関数はchar-tableのデフォルト値をnew-defaultにする。
文字テーブルのデフォルト値を参照するための特別な関数はない。
それには |
char-table-parent char-table | Function |
この関数はchar-tableの親を返す。
親は、nil であるか他の文字テーブルである。
|
set-char-table-parent char-table new-parent | Function |
この関数はchar-tableの親をnew-parentにする。 |
char-table-extra-slot char-table n | Function |
この関数はchar-tableの追加スロットnの内容を返す。 文字テーブル内の追加スロットの個数はそのサブタイプで決まる。 |
set-char-table-extra-slot char-table n value | Function |
この関数はchar-tableの追加スロットnにvalueを格納する。 |
文字テーブルでは、1つの文字コードに対して1つの要素値を指定できます。 また、文字集合全体に対して1つの値を指定することもできます。
char-table-range char-table range | Function |
これは、char-tableにおいて文字範囲rangeに指定されている値を返す。
rangeとして可能なものは以下のとおり。
|
set-char-table-range char-table range value | Function |
この関数は文字範囲rangeに対するchar-tableの値を設定する。
rangeとして可能なものは以下のとおり。
|
map-char-table function char-table | Function |
この関数は、char-tableの各要素についてfunctionを呼び出す。
functionをキーと値の2つの引数で呼び出す。
キーはchar-table-range に対する可能なrange引数であり、
正当な文字か汎用文字である。
値は(char-table-range char-table key) である。
全体として、functionに渡すキー・値の対は、 char-tableに格納されたすべての値を表す。 戻り値はつねに (let (accumulator) (map-char-table #'(lambda (key value) (setq accumulator (cons (list key value) accumulator))) (syntax-table)) accumulator) => ((475008 nil) (474880 nil) (474752 nil) (474624 nil) ... (5 (3)) (4 (3)) (3 (3)) (2 (3)) (1 (3)) (0 (3))) |
ブールベクトルはベクトルによく似ていますが、
t
とnil
の値だけを保存できる点が異なります。
ブールベクトルの要素にnil
以外の値を保存しようとすると、
その効果はt
を保存することになります。
すべての配列と同様に、ブールベクトルの添字は0から始まり、
ブールベクトルをいったん作成すると長さは変更できません。
評価時には、ブールベクトルは定数です。
ブールベクトルを操作する特別な関数は2つあります。 それに加えて、他の種類の配列を扱う関数でも操作できます。
make-bool-vector length initial | Function |
initialに初期化した長さlengthの新たなブールベクトルを返す。 |
bool-vector-p object | Function |
objectがブールベクトルであればt を返し、
さもなければnil を返す。
|
シンボル(symbol)とは、一意な名前が付いたオブジェクトです。 本章では、シンボル、その構成要素、属性リスト、作成方法とインターン方法に ついて説明します。 シンボルの変数としての使用方法、関数名としての使用方法について説明した 別の章もあります。 VariablesとSee Functions。 シンボルの正確な入力構文については、See Symbol Type。
symbolp
で、任意のLispオブジェクトがシンボルかどうか調べられます。
symbolp object | Function |
この関数は、objectがシンボルならばt を返し、
さもなければnil を返す。
|
各シンボルには4つの構成要素(つまり、『セル』)があり、 それぞれで別のオブジェクトを参照します。
symbol-name
を参照。
symbol-value
を参照。
symbol-function
を参照。
symbol-plist
を参照。
表示名セルはつねに文字列を保持していて、変更できません。 他の3つのセルには、任意の指定したLispオブジェクトを個別に設定できます。
表示名セルは、シンボルの名前である文字列を保持しています。 シンボルはテキスト上はその名前で表現されるので、 2つのシンボルが同じ名前を持たないことが重要です。 Lispリーダがこのことを保証します。 シンボルを読み取るたびに、新たにシンボルを作成するまえに、 指定した名前のシンボルが存在するかどうか調べます。 (GNU Emacs Lispでは、これにはハッシュアルゴリズムと オブジェクト配列obarrayを使う。 see Creating Symbols。)
普通の使い方では、関数セルには関数(see Functions)や
マクロ(see Macros)が入っていて、
Lispインタープリタはそのように仮定します(see Evaluation)。
シンボルの関数セルには、
キーボードマクロ(see Keyboard Macros)、キーマップ(see Keymaps)、
自動ロードオブジェクト(see Autoloading)が入っていることもあります。
『関数foo
』といった場合、実際には、シンボルfoo
の関数セルに
入っている関数を意味します。
必要な場合に限って区別します。
属性リストセルは、通常、正しい形式の属性リスト(see Property Lists)が 入っている必要があり、さまざまな関数がそのように仮定しています。
関数セルや値セルは空(void)でもかまいません。
つまり、セルはどんなオブジェクトも指していません。
(このことは、シンボルvoid
を保持しているとか、
シンボルnil
を保持しているのとは違う。)
空である関数セルや値セルを参照すると、
その結果はSymbol's value as variable is void
(「変数としてのシンボルの値は空」)のようなエラーになります。
4つの関数、symbol-name
、symbol-value
、
symbol-plist
、symbol-function
は、
シンボルの4つのセルの内容を返します。
以下に、シンボルbuffer-file-name
の
4つのセルの内容を表示する例を示します。
(symbol-name 'buffer-file-name) => "buffer-file-name" (symbol-value 'buffer-file-name) => "/gnu/elisp/symbols.texi" (symbol-plist 'buffer-file-name) => (variable-documentation 29529) (symbol-function 'buffer-file-name) => #<subr buffer-file-name>
このシンボルは、カレントバッファで訪問しているファイルの名前を保持するので、
値セルの内容は本書Emacs Lispマニュアルの本章のソースファイルの名前です。
属性リストセルには、リスト(variable-documentation 29529)
が入っていて、
ドキュメント関数に対してファイルDOC-version
のどこに
変数buffer-file-name
の説明文字列が入っているか伝えます。
(29529は、当該説明文字列の開始位置を表す
DOC-version
の先頭からのオフセット。
Documentation Basicsを参照。)
関数セルには、ファイルの名前を返す関数が入っています。
buffer-file-name
は基本関数の名前です。
これには入力構文はなく、
ハッシュ記法(see Primitive Function Type)で表示されています。
Lispで書いた関数を表すシンボルでは、
このセルにラムダ式(あるいはバイトコードオブジェクト)が入っています。
Lispにおける定義(definition)とは、 特定のシンボルをどのように使うかを意思表示するスペシャルフォームです。 Emacs Lispでは、シンボルを変数と定義したり、 関数(あるいはマクロ)と定義したり、あるいは、それらを独立に定義できます。
定義を行う構文では、典型的には、値を指定したり、 シンボルを特定の使い方をすると指定したりし、 さらに、そのような使い方をしたときの意味を表すための説明文字列を指定します。 したがって、シンボルを変数として定義するときには、 変数に初期値を与え、その変数の説明文字列を指定できます。
defvar
とdefconst
は、シンボルをグローバル変数として定義する
スペシャルフォームです。
これらはDefining Variablesで詳しく説明してあります。
カスタマイズ可能なようにユーザーオプション用の変数を定義するには、
defcustom
(see Customization)を使います。
defun
は、シンボルを関数として定義し、
ラムダ式を作ってシンボルの関数セルに格納します。
したがって、このラムダ式がシンボルの関数定義になります。
(用語『関数定義』は、関数セルの内容を意味し、
defun
がシンボルに関数としての定義を与えることからきている。)
defsubst
とdefalias
は、関数を定義する別の2つの方法です。
See Functions。
defmacro
は、シンボルをマクロとして定義します。
マクロオブジェクトを作ってシンボルの関数セルに格納します。
シンボルは、マクロか関数のいずれかであって、
同時に両方にはならないことに注意してください。
というのは、マクロ定義も関数定義も関数セルに収められ、
そのセルにはどんなときでもたった1つのLispオブジェクトしか
保持できないからです。
See Macros。
Emacs Lispでは、シンボルを変数や関数として使うための
定義は必須ではありません。
したがって、シンボルをあらかじめ定義しようがしまいが、
setq
を使ってシンボルをグローバル変数にできます。
定義の真の目的は、プログラマに対する指針であり、プログラミングツールなのです。
これらは、コードを読むプログラマに対して、
特定のシンボルを変数として使うのか関数として使うのか、
その意図を伝えます。
さらに、etags
やmake-docfile
などのユーティリティは、
定義を認識してタグテーブルやファイルDOC-version
に
適切な情報を追加します。
See Accessing Documentation。
GNU Emacs Lispにおいて、どのようにシンボルを作成するかを理解するには、 Lispがそれらをどのように読むかを知る必要があります。 Lispは、同じ文字群を読み取るたびに、同じシンボルをみつけることを保証する 必要があります。 これに失敗すると完全に混乱します。
Lispリーダがシンボルに出会うと、名前の文字群をすべて読み取ります。 そして、これらの文字群を『ハッシュ化』して、 オブジェクト配列(obarray)と呼ばれる表の添字を探します。 ハッシュ化は効率的に探索する手法です。 たとえば、Jan Jonesを電話番号簿の表紙から1ページずつ順に探すかわりに、 Jのページから探し始めます。 これは単純なハッシュ化です。 オブジェクト配列の各要素は、 あるハッシュコードを有するすべてのシンボルを格納した バケット(bucket)です。 ある名前を探すには、その名前のハッシュコードに対応するバケット内の すべてのシンボルを調べるだけで十分です。
目的の名前のシンボルがみつかれば、リーダはそのシンボルを使います。 オブジェクト配列に目的の名前のシンボルがなければ、 リーダは新たなシンボルを作成し、それをオブジェクト配列に追加します。 ある名前のシンボルを探したり追加することをシンボルを インターン(interning)するといい、 そのシンボルをインターンしたシンボル(interned symbol)と呼びます。
インターンすることで、各オブジェクト配列には 特定の名前のシンボルが1個だけあることを保証します。 他の似たような名前のシンボルが存在しても、 同じオブジェクト配列には入っていません。 したがって、同じオブジェクト配列を使って読む限り、 リーダは同じ名前に対して同じシンボルを得ることができます。
すべてのシンボルがオブジェクト配列に入っているとは限りません。 実際、どのオブジェクト配列にも属さないシンボルがいくつかあります。 これらをインターンしてないシンボル(uninterned symbols)と呼びます。 インターンしてないシンボルにも、他のシンボルと同様に4つのセルがあります。 しかし、それを参照する手段は、他のオブジェクトを介して探すか、 変数の値として探すしかありません。
Emacs Lispでは、オブジェクト配列は実際にはベクトルです。
ベクトルの各要素はバケットです。
その値は、そのバケットにハッシュ化される名前のインターンしたシンボルであるか、
そのバケットが空ならば0です。
インターンした各シンボルには、バケットのつぎのシンボルを指す
(ユーザーには見えない)内部的なリンクがあります。
このリンクは見えないので、mapatoms
(下記)を使う以外には、
オブジェクト配列内のすべてのシンボルを探す方法はありません。
バケット内でのシンボルの順序は関係ありません。
空のオブジェクト配列では、各要素は0です。
(make-vector length 0)
でオブジェクト配列を作成できます。
これは、オブジェクト配列を作成する唯一の正当な方法です。
長さとして素数を用いると、ハッシュ化の結果がよい傾向があります。
2の巾より1小さい長さもよい結果になります。
読者自身でオブジェクト配列にシンボルを入れないでください。
うまくいきません。
オブジェクト配列にシンボルを正しく入れられるのはintern
だけです。
Common Lispに関した注意:
Common Lispでは、1つのシンボルを複数のオブジェクト配列に入れることができる。
下記の関数のほとんどは、引数に名前を取り、
場合によってはオブジェクト配列を引数に取ります。
名前が文字列でなかったり、オブジェクト配列がベクトルでないと、
エラーwrong-type-argument
を通知します。
symbol-name symbol | Function |
この関数は、symbolの名前を表す文字列を返す。
たとえば、つぎのとおり。
(symbol-name 'foo) => "foo" 警告: |
make-symbol name | Function |
この関数は、name(文字列であること)を名前とする
新たに割り付けたインターンしていないシンボルを返す。
その値と関数定義は空であり、属性リストはnil である。
以下の例では、sym の値はfoo とeq ではない。
なぜなら、名前はfoo ではあるが、
インターンしていない別のシンボルであるため。
(setq sym (make-symbol "foo")) => foo (eq sym 'foo) => nil |
intern name &optional obarray | Function |
この関数は、nameを名前とするインターンしたシンボルを返す。
そのようなシンボルがオブジェクト配列obarrayに存在しなければ、
intern は新たなものを作成し、それをオブジェクト配列に追加してから、
それを返す。
obarrayを省略すると、グローバル変数obarray の値を使う。
(setq sym (intern "foo")) => foo (eq sym 'foo) => t (setq sym1 (intern "foo" other-obarray)) => foo (eq sym 'foo) => nil |
Common Lispに関した注意:Common Lispでは、既存のシンボルをオブジェクト配列にインターンできる。 Emacs Lispでは、これはできない。 なぜなら、
intern
の引数は文字列である必要があり、 シンボルではない。
intern-soft name &optional obarray | Function |
この関数は、obarray内のnameを名前とするシンボルを返す。
ただし、その名前のシンボルがobarrayになければnil を返す。
したがって、intern-soft を用いて、指定した名前のシンボルが
インターンされているかどうか調べられる。
obarrayを省略すると、グローバル変数obarray の値を使う。
(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 |
obarray | Variable |
この変数は、intern やread が使う標準のオブジェクト配列。
|
mapatoms function &optional obarray | Function |
この関数は、オブジェクト配列obarrayの各シンボルについて、
1回ずつfunctionを呼び出す。
そして、nil を返す。
obarrayを省略すると、通常のシンボル向けの標準のオブジェクト配列である
obarray の値をデフォルトにする。
(setq count 0) => 0 (defun count-syms (s) (setq count (1+ count))) => count-syms (mapatoms 'count-syms) => nil count => 1871
|
unintern symbol &optional obarray | Function |
この関数は、オブジェクト配列obarrayからsymbolを削除する。
symbol が実際にはオブジェクト配列内になければ、
unintern はなにもしない。
obarrayがnil であると、現在のオブジェクト配列を使う。
symbolのシンボルのかわりに文字列を指定すると、
それはシンボルの名前を表す。
そして、
|
属性リスト(property list、略してplist)とは、 シンボルの属性リストセルに格納された対になった要素から成るリストです。 各対は、属性名(通常、シンボル)を属性、すなわち、属性値に対応付けます。 属性リストは、一般に、シンボルに関する情報を記録します。 変数としての説明文字列、定義されているファイルの名前、 言語理解システムにおいては(語を表す)シンボルの文法クラスなどです。
文字列内やバッファ内の文字位置も属性リストを持てます。 See Text Properties。
属性リスト内の属性名と属性値は、任意のLispオブジェクトでかまいませんが、
普通、属性名はシンボルです。
属性リスト関数は、eq
を使って属性名を比較します。
コンパイラをロードした際のシンボルprogn
の属性リストをつぎに示します。
(lisp-indent-function 0 byte-compile byte-compile-progn)
ここで、lisp-indent-function
やbyte-compile
は属性名であり、
他の2つの要素は対応する属性値です。
連想リスト(see Association Lists)は、 属性リストに非常によく似ています。 連想リストと異なり、属性名は一意である必要があるので、 属性リスト内での対の出現順序は関係ありません。
さまざまなLisp関数やLisp変数に情報を付加するには、
属性リストは連想リストより優れています。
読者のプログラムで1つの連想リストにすべての連想を入れておいたとすると、
1つの連想を探すたびに、リスト全体を探索する必要があります。
これには時間がかかります。
一方、同じ情報を関数名や変数自身の属性リストに保持しておけば、
各探索では1つの属性リストを走査するだけでよく、
属性リストは、普通、短いものです。
このため、変数の説明文字列をvariable-documentation
という名前の
属性に記録しているのです。
同様に、バイトコンパイラも、
特別な処理が必要な関数を属性を使って記録しています。
しかしながら、連想リストにもそれ独自の利点があります。 読者のアプリケーションに依存しますが、 属性を更新するより、連想リストの先頭に連想を追加するほうが速いです。 あるシンボルのすべての属性は同一の属性リストに格納してあるので、 1つの属性名を異なる目的に使うと衝突します。 (この理由から、プログラムで普通に使う 変数名や関数名の接頭辞で始まる属性名を選ぶなどして、 一意な属性名を選ぶのがよい。) 連想リストは、リストの先頭に要素を追加し、先頭から要素を削除するので、 スタックのように使えます。 属性リストでは、これは不可能です。
symbol-plist symbol | Function |
この関数はsymbolの属性リストを返す。 |
setplist symbol plist | Function |
この関数は、symbolの属性リストを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) 普通の使い方を意図していない特別なオブジェクト配列内のシンボルに対しては、 属性リストセルの非標準な使い方にも意味があろう。 実際、略語機構(see Abbrevs)ではそのようにしている。 |
get symbol property | Function |
この関数は、symbolの属性リストから
propertyという名前の属性の値を探す。
そのような属性がなければ、nil を返す。
つまり、nil という値と属性の欠如を区別できない。
名前propertyは既存の属性名と 例については、 |
put symbol property value | Function |
この関数は、symbolの属性リストにおいて、
属性名propertyの古い属性値をvalueで置き換える。
関数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)) |
シンボル以外の場所に保存した属性リストの操作に便利な2つの関数があります。
plist-get plist property | Function |
これは、属性リストplistに保存されている属性propertyの値を返す。
たとえば、つぎのとおり。
(plist-get '(foo 4) 'foo) => 4 |
plist-put plist property value | Function |
これは、属性リストplistに、
propertyの値としてvalueを格納する。
これはplistを破壊的に変更するか、あるいは、
古いものを変更せずに新たなリスト構造を構築する。
関数は変更した属性リストを返すので、
plistを保持していたところへ保存し直せる。
たとえば、つぎのとおり。
(setq my-plist '(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)) |
つぎのようにして、plist-put
を用いてput
を定義できます。
(defun put (symbol prop value) (setplist symbol (plist-put (symbol-plist symbol) prop value)))
Emacs Lispにおける式の評価(evaluation)は、
Lispインタープリタ(Lisp interpreter)が行います。
これは、入力としてLispオブジェクトを受け取り、
式としての値を計算するプログラムです。
計算方法は、本章で述べる規則に従ってオブジェクトのデータ型に依存します。
インタープリタは、読者のプログラムのある部分を評価するために
自動的に動作しますが、Lisp基本関数eval
を介して
インタープリタを明示的に呼ぶ出すこともできます。
評価することを意図したLispオブジェクトを 式(expression)とかフォーム(form)と呼びます。 式はデータオブジェクトであり単なるテキストではないという事実は、 Lisp様言語と典型的なプログラム言語との基本的な違いの1つです。 どんなオブジェクトでも評価できますが、実用上は、 数、シンボル、リスト、文字列を評価することが多いのです。
Lisp式を読み取りその式を評価することはとても一般的なことですが、
読み取りと評価は別々の動作であり、それぞれを別々に実行することもできます。
読み取り自体では、なにも評価しません。
Lispオブジェクトの表示表現をオブジェクトそのものに変換します。
このオブジェクトを評価すべきフォームとするか、
まったく別の目的に使うかは、read
の呼び出し側で決まります。
評価とコマンドキーの解釈を混同しないでください。
エディタコマンドループは、有効なキーマップを用いて
キーボード入力をコマンド(対話的に呼び出し可能な関数)に変換し、
call-interactively
を使ってコマンドを起動します。
コマンドがLispで書いてあれば、
コマンド自体の実行には評価が関わってきますが、
そのことは、コマンドキーの解釈自体には含まれていません。
評価は再帰的な処理です。
つまり、フォームの評価では、
eval
を呼び出してそのフォームの一部分を評価することもあります。
たとえば、関数呼び出しの評価においては、まず、
関数呼び出しの各引数を評価してから、関数本体の各フォームを評価します。
(car x)
の評価を考えてみましょう。
まず最初にx
を再帰的に評価する必要があります。
その値を関数car
の引数として渡せるようにするのです。
関数呼び出しの評価においては、最終的に指定した関数を呼び出します。 See Functions。 関数の実行そのものも、関数定義を評価する場合もあります。 あるいは、関数はC言語で実装されたLisp基本関数かもしれませんし、 バイトコード関数かもしれません(see Byte Compilation)。
フォームの評価は、環境(environment)と呼ばれる文脈において 行われます。 環境とは、すべてのLisp変数の現在値と束縛です 7。 フォームが新たな束縛を作らずに変数を参照する場合には、 現在の環境におけるその変数の束縛の値を使います。 See Variables。
フォームを評価すると、変数(see Local Variables)を束縛して、
再帰的評価のための新たな環境を作ることがあります。
これらの環境は一時的なもので、そのフォームの評価を完了すると
消えてしまいます。
フォームは恒久的な変更を行ってもかまいません。
このような変更を副作用(side effects)と呼びます。
副作用を持つフォームの例は、(setq foo 1)
です。
フォームの各種類ごとの評価の意味の詳細は、 以下で説明します(see Forms)。
評価することを意図したLispオブジェクトをフォーム(form)と呼びます。 Emacsがどのようにフォームを評価するかは、そのデータ型に依存します。 Emacsには、評価方法が異なる3種類のフォームがあります。 シンボル、リスト、および、『その他すべての型』です。 本節では、3種類すべてについて1つ1つ説明します。 まず、自己評価型フォームである『その他すべての型』から説明します。
自己評価型フォーム(self-evaluating form)とは、
リストでもシンボルでもない任意のフォームのことです。
自己評価型フォームはそれ自身に評価され、
評価結果は評価されるオブジェクトと同じものです。
つまり、数25は25と評価され、
文字列"foo"
は文字列"foo"
と評価されます。
同様に、ベクトルを評価してもベクトルの個々の要素を評価することはありません。
その内容をまったく変更することなく、同じベクトルを返します。
'123 ; 評価していない数 => 123 123 ; 普通どおり評価。結果は同じ => 123 (eval '123) ; 『手で』評価。結果は同じ => 123 (eval (eval '123)) ; 2回評価してもなにも変わらない => 123
Lispコードにおいては、数、文字、文字列、さらにベクトルでさえも、 それらが自己評価型である事実を利用して書くのが普通です。 しかし、入力構文を持たない型については、このようにしません。 というのは、それらをテキストとして書く方法がないからです。 そのような型を含むLisp式を構成するには、Lispプログラムを使います。
;; バッファオブジェクトを含む式を作る (setq print-exp (list 'print (current-buffer))) => (print #<buffer eval.texi>) ;; それを評価する (eval print-exp) -| #<buffer eval.texi> => #<buffer eval.texi>
シンボルを評価するときには、シンボルを変数として扱います。 その結果は、値があれば、変数の値です。 (値セルが空であり)値がなければ、エラーを通知します。 変数の使い方について詳しくは、See Variables。
つぎの例では、setq
を使ってシンボルの値を設定します。
そのあとでシンボルを評価すると、setq
で保存した値を取り出せます。
(setq a 123) => 123 (eval 'a) => 123 a => 123
シンボルnil
とt
は特別に扱い、
nil
の値はつねにnil
であり、
t
の値はつねにt
です。
これらに別の値を設定したり、別の値を束縛することはできません。
したがって、eval
はこれらを他のシンボルと同様に扱いますが、
これら2つのシンボルは自己評価型フォームのようにふるまいます。
:
で始まる名前のシンボルも同じ意味で自己評価型であり、
同様に、その値を変更できません。
See Constant Variables。
フォームが空ではないリストならば、その最初の要素に依存して、 関数呼び出し、マクロ呼び出し、スペシャルフォームのいずれかです。 これらの3種類のフォームは、以下に説明するように、異なる方法で評価されます。 リストの残りの要素は、関数、マクロ、スペシャルフォームの 引数(arguments)になります。
空ではないリストを評価する最初の手順は、 その先頭要素を調べることです。 この要素は、それだけで、空ではないリストのフォームの種類を決定し、 リストの残りをどのように処理するかを決定します。 SchemeなどのLispの一部の方言と違って、先頭要素は評価しません。
リストの先頭要素がシンボルであると、 評価処理ではシンボルの関数セルを調べ、 もとのシンボルのかわりにその内容を使います。 その内容が別のシンボルであると、 シンボルの関数間接(symbol function indirection)と呼ばれる この処理をシンボルでないものを得るまで繰り返します。 シンボルの関数セルに格納された関数名としてのシンボルの使い方について 詳しくは、See Function Names。
この処理の結果、無限ループになる場合もあります。
つまり、シンボルの関数セルが同じシンボルを指している場合です。
あるいは、シンボルの関数セルが空の場合もありえます。
その場合、サブルーティンsymbol-function
は、
エラーvoid-function
を通知します。
いずれの場合でもなければ、最終的にはシンボルでないものを取得し、
それは関数などの適切なオブジェクトであるはずです。
より正確にいえば、Lisp関数(ラムダ式)、バイトコード関数、
基本関数、Lispマクロ、スペシャルフォーム、自動ロードオブジェクトの
いずれかを取得しているはずです。
これらの各種類ごとに、以下の1つ1つの節で説明します。
オブジェクトがこれらのいずれの型でもない場合には、
エラーinvalid-function
を通知します。
つぎの例は、シンボルの関数間接の処理を図示したものです。
fset
を使ってシンボルの関数セルに設定し、
symbol-function
を使って関数セルの内容を取り出します
(see Function Cells)。
具体的には、シンボルcar
をfirst
の関数セルに格納し、
シンボルfirst
をerste
の関数セルに格納します。
;; このような関数セルのリンクを作る ;; ------------- ----- ------- ------- ;; | #<subr car> | <-- | car | <-- | first | <-- | erste | ;; ------------- ----- ------- -------
(symbol-function 'car)
=> #<subr car>
(fset 'first 'car)
=> car
(fset 'erste 'first)
=> first
(erste '(1 2 3)) ; erste
が指す関数を呼び出す
=> 1
一方、つぎの例では、シンボルの関数間接を使わずに関数を呼び出します。 というのは、先頭引数はLispの無名関数であって、 シンボルではないからです。
((lambda (arg) (erste arg)) '(1 2 3)) => 1
関数を実行することは、その本体を評価することです。
この過程では、erste
を呼び出すときにシンボルの関数間接が関わります。
組み込み関数indirect-function
は、
明示的にシンボルの関数間接を行う簡単な方法です。
indirect-function function | Function |
この関数は、関数としてのfunctionの意味を返す。
functionがシンボルであればfunctionの関数定義を探し、
その値から再度繰り返す。
functionがシンボルでなければfunctionそのものを返す。
Lispで (defun indirect-function (function) (if (symbolp function) (indirect-function (symbol-function function)) function)) |
評価すべきリストの先頭要素が、Lisp関数オブジェクト、
バイトコードオブジェクト、基本関数オブジェクトの場合、
そのリストは関数呼び出し(function call)です。
たとえば、つぎは、関数+
の呼び出しです。
(+ 1 x)
関数呼び出しを評価する最初の手順は、
リストの残りの要素を左から右へ順に評価することです。
その結果は実引数の値になり、1つの値がリストの1つの要素に対応します。
つぎの手順は、引数のリストで関数を呼び出すことで、
実質的には、関数apply
(see Calling Functions)を使います。
関数がLispで書いてあれば、関数の引数変数を束縛するために引数を使います
(see Lambda Expressions)。
そして、関数本体のフォーム群を順番に評価し、
本体の最後のフォームの値が関数呼び出しの値になります。
評価すべきリストの先頭要素がマクロオブジェクトの場合、 そのリストはマクロ呼び出し(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のマクロに関する完全な記述は、See Macros。
スペシャルフォーム(special form)は、 その引数を評価しないように特別な印が付いた基本関数です。 ほとんどのスペシャルフォームは、制御構造を定義したり、 変数を束縛したりします。 これらはどれも関数ではできないことです。
各スペシャルフォームには、どの引数は評価し、 どの引数は評価せずに使うかといったそれぞれに独自の規則があります。 特定の引数を評価するかどうかは、他の引数の評価結果に依存することもあります。
以下に、Emacs Lispのすべてのスペシャルフォームをアルファベット順に、 参照箇所とともにあげておきます。
and
catch
cond
condition-case
defconst
defmacro
defun
defvar
function
if
interactive
let
let*
or
prog1
prog2
progn
quote
save-current-buffer
save-excursion
save-restriction
save-window-excursion
setq
setq-default
track-mouse
unwind-protect
while
with-output-to-temp-buffer
Common Lispに関した注意:GNU Emacs LispとCommon Lispのスペシャルフォームを比較してみる。
setq
、if
、および、catch
は、Emacs Lispでも Common Lispでもスペシャルフォームである。defun
は、Emacs Lispではスペシャルフォームであるが、 Common Lispではマクロである。save-excursion
は、Emacs Lispではスペシャルフォームであるが、 Common Lispには存在しない。throw
は、Common Lispでは(複数の値を返す必要があるため) スペシャルフォームであるが、 Emacs Lispでは(複数の値はないため)関数である。
自動ロード(autoload)は、 関数やマクロの関数定義をEmacsにまだロードしていなくても、 関数やマクロを呼び出せるようにする機構です。 定義を収めたファイルを指定します。 シンボルの関数定義に自動ロードオブジェクトあるとき、 そのシンボルを関数として呼び出すと、指定したファイルを自動的にロードします。 そうしてから、当該ファイルからロードした実際の定義を呼び出します。 See Autoload。
スペシャルフォームquote
は、単一の引数を
評価せずに書かれたとおりに返します。
これは、自己評価型オブジェクトではない
定数シンボルや定数リストをプログラム内に書く手段です。
(数、文字列、ベクトルなどの自己評価型オブジェクトをクォートする必要はない。)
quote object | Special Form |
このフォームはobjectを評価せずに返す。 |
quote
はプログラム内で頻繁に使うので、
Lispには便利な入力構文が用意してあります。
アポストロフ文字('
)に続けた(入力構文で書いた)Lispオブジェクトは、
先頭要素がquote
であり2番目の要素がそのオブジェクトである
リストに展開されます。
したがって、入力構文'x
は、(quote x)
の省略形です。
quote
を使った式の例をいくつかあげておきます。
(quote (+ 1 2)) => (+ 1 2) (quote foo) => foo 'foo => foo ''foo => (quote foo) '(quote foo) => (quote foo) ['foo] => [(quote foo)]
他のクォートの書き方には、function
(see Anonymous Functions)が
あります。
これは、Lispで書いた無名ラムダ式をコンパイルするようにします。
また、`
(see Backquote)は、
リストの一部分をクォートし、他の部分は計算結果で置き換えるために使います。
ほとんどの場合、実行中のプログラムにフォームが現れると
フォームは自動的に評価されます。
稀なことですが、実行時に計算したフォームを評価するように
コードを書く必要があるかもしれません。
たとえば、編集中のテキストからフォームを読み取ったり、
属性リストからフォームを取り出した場合などです。
このような場合には、関数eval
を使います。
本節で説明した関数や変数は、フォームを評価したり、 評価処理に制限を課したり、最後の戻り値を記録したりします。 ファイルをロードしても評価が行われます(see Loading)。
注意:
データ構造の中に関数を格納して
それをfuncall
やapply
で呼び出すほうが、
データ構造の中に式を格納してそれを評価するより、
一般に明確で柔軟性があります。
関数を使うとそれらに引数として情報を渡すことができます。
eval form | Function |
この関数は、式を評価する基本的な関数である。
formを現在の環境において評価し、その結果を返す。
評価処理はオブジェクトの型に依存する(see Forms)。
(setq foo 'bar) => bar (setq bar 'baz) => baz ;;
|
eval-region start end &optional stream read-function | コマンド |
この関数は、カレントバッファのstartとendで指定した
リージョン内のフォーム群を評価する。
リージョンからフォームを読み取り、
それらに対してeval を呼び出すことを
リージョンの末尾に達するまで、あるいは、処理されないエラーが通知されるまで
繰り返す。
streamが read-functionが
|
eval-current-buffer &optional stream | コマンド |
これはeval-region と同様だが、バッファ全体に作用する。
|
max-lisp-eval-depth | Variable |
この変数は、
(エラーメッセージ"Lisp nesting exceeds max-lisp-eval-depth" で)
エラーを通知までのeval 、apply 、funcall の呼び出しの
最大の深さを制限する。
この制限、および、これを超えたときのエラーは、
不正に定義された関数によってLispが無限に再帰することを防止する
1つの方法である。
深さ制限は、Lispコードによる明示的な呼び出しに加えて、
Lisp式で書かれた関数の呼び出しや関数呼び出しの引数や関数本体のフォームの
再帰的な評価などの内部的な この変数のデフォルト値は300。 これに100未満の値を設定すると、指定した値に達するとLispは100に設定し直す。 Lispデバッガに入ったとき、 制限に近い場合にはデバッガ自身が実行できることを保証するために値を増やす。
|
values | Variable |
この変数の値は、
バッファから式を読み取り、評価し、結果を表示するEmacsの標準コマンドが行った
すべての式の戻り値のリストである。
リストの順序は、最新のものが最初にくる。
(setq x 1) => 1 (list 'A (1+ 2) auto-save-default) => (A 3 t) values => ((A 3 t) 1 ...) この変数は、最近評価したフォームの値を参照するのに便利である。
;; もっとも最近の評価結果を参照する (nth 0 values) => (A 3 t) ;; こうすると、新たな要素が追加され、 ;; すべての要素が1つうしろへさがる (nth 1 values) => (A 3 t) ;; この例を実行するまえの最新のもののつぎの要素を取得する (nth 3 values) => 1 |
Lispプログラムは、式、すなわち、フォーム(forms、see Forms)から 成ります。 フォームを制御構造(control structures)で囲むことで、 フォームの実行順序を制御します。 制御構造はスペシャルフォームであり、 その内側にあるフォームの実行をいつ行うか、行わないか、 何回行うかを制御します。
もっとも単純な実行順序は逐次実行です。 最初のフォームaを実行し、 それからつぎのフォームbを実行し、といった具合です。 関数の本体やLispコードのファイルのトップレベルに複数のフォームを順に書くと、 このようになります。 つまり、書かれている順番にフォームを実行します。 これをテキスト上の順序(textual order)と呼びます。 たとえば、関数本体が2つのフォームaとbから成る場合、 関数を評価すると、まずaを評価し、つぎにbを評価して、 関数の値はbの値になります。
明示的な制御構造により、逐次実行以外の実行順序が可能になります。
Emacs Lispには数種類の制御構造があり、 逐次実行の変形、条件付き実行、繰り返し実行、 (制御された)ジャンプなどです。 これらすべては、以下に説明します。 組み込みの制御構造はスペシャルフォームです。 というのは、それらのサブフォームは必ずしも評価しませんし、 逐次評価するわけでもないからです。 マクロを使えば、独自の制御構造の構文を定義できます(see Macros)。
if
, cond
, when
, unless
.
and
, or
, not
.
while
loops.
現れる順番にフォームを評価することは、
1つのフォームから別のフォームへ制御を移すもっとも一般的な方法です。
関数本体などのある種の文脈では、自動的にこのようになります。
それ以外では、これを行う制御構造の構文を使う必要があります。
progn
がその制御構造で、Lispのもっとも単純な制御構造です。
スペシャルフォームprogn
はつぎのような形です。
(progn a b c ...)
これは、フォーム、a、b、c、…をこの順に評価します。
これらのフォームをprogn
フォームの本体と呼びます。
本体の最後のフォームの値が、progn
全体の値になります。
初期のころのLispでは、progn
は、
2つ以上のフォームを逐次実行しそれらの最後の値を使う唯一の方法でした。
しかし、プログラマは、(当時は)1つのフォームしか許されていない
関数の本体では、
progn
を使う必要がしばしばあることに気づきました。
そのため、関数本体を『暗黙のprogn
』にしたのです。
つまり、実際のprogn
の本体のように、
複数のフォームを許すようにしたのです。
多くの他の制御構造も、同様に、暗黙のprogn
です。
その結果、progn
は、かつてほどは多用されません。
現在では、unwind-protect
、and
、or
の内側や、
if
のthen部分で必要とされるのがほとんどです。
progn forms... | Special Form |
このスペシャルフォームは、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つの制御構造も同様にフォームを逐次評価しますが、 返す値が異なります。
prog1 form1 forms... | Special Form |
このスペシャルフォームは、form1、formsのフォームすべてを
テキスト上の順に評価し、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" 変数のリストから先頭要素を取り除き、取り除いた要素を返すにはつぎのように書く。 (prog1 (car x) (setq x (cdr x))) |
prog2 form1 form2 forms... | Special Form |
このスペシャルフォームは、form1、form2、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" |
条件付き制御構造は、選択肢を選びます。
Emacs Lispには、4つの条件付きフォームがあります。
他の言語のものとほとんど同じif
、
if
の変形であるwhen
やunless
、
一般化したcase文であるcond
です。
if condition then-form else-forms... | Special Form |
if は、conditionをもとにして、
then-formかelse-formsを選ぶ。
conditionがnil 以外に評価されると、
then-formを評価し、その結果を返す。
さもなければ、else-formsをテキスト上の順に評価し、
その最後のものの値を返す。
(if のelse部分は、暗黙のprogn の例である。
see Sequencing。)
conditionが値
(if nil (print 'true) 'very-false) => very-false |
when condition then-forms... | Macro |
これはif の変形であり、else-formsがなく、
then-formsは複数のフォームでもよい。
特に、
(when condition a b c) は、つぎとまったく等価である。 (if condition (progn a b c) nil) |
unless condition forms... | Macro |
これはthen-formがないif の変形である。
(unless condition a b c) は、つぎとまったく等価である。 (if condition nil a b c) |
cond clause... | Special Form |
cond は任意個数の選択肢から1つを選ぶ。
cond の各節clauseはリストである必要がある。
このリストのCARがcondition(条件)である。
残りの要素は、あれば、body-forms(本体フォーム)である。
つまり、各節はつぎのようになる。
(condition body-forms...)
conditionの値が 各conditionが 節clauseは、つぎの形式でもよい。 (condition) この場合、conditionが 以下の例には4つの節があり、
(cond ((numberp x) x) ((stringp x) x) ((bufferp x) (setq temporary-hack x) ; 1つの節に (buffer-name x)) ; 複数個の本体フォーム ((symbolp x) (symbol-value x))) 最後の節を除くそれよりまえの節がどれも成功しないときには、
最後の節を実行したいことがしばしばある。
これを行うには、 たとえば、つぎのとおり。 (cond ((eq a 'hack) 'foo) (t "default")) => "default" この式は、 |
任意の条件付き構造は、cond
やif
で表現できます。
したがって、どちらを使うかは好みの問題です。
たとえば、つぎのとおりです。
(if a b c) == (cond (a b) (t c))
本節では、if
やcond
とともに用いて複雑な条件を表現するために
しばしば使われる3つの構造を説明します。
and
やor
の構造は、
複数の条件付き構造の一種として単独で使うこともできます。
not condition | Function |
この関数は、conditionが偽であるかどうか調べる。
conditionがnil であればt を返し、
さもなければnil を返す。
関数not はnull と同一であるが、
空リストかどうか調べる場合には、null を使うことを勧める。
|
and conditions... | Special Form |
スペシャルフォームand は、
すべてのconditionsが真であるかどうか調べる。
conditionsを1つ1つ書かれた順に評価して調べる。
conditionsのどれかが conditionsすべてが 例を示そう。
最初の条件は整数1を返し、これは (and (print 1) (print 2) nil (print 3)) -| 1 -| 2 => nil
(if (and (consp foo) (eq (car foo) 'x)) (message "foo is a list starting with x"))
(and arg1 arg2 arg3) == (if arg1 (if arg2 arg3)) == (cond (arg1 (cond (arg2 arg3)))) |
or conditions... | Special Form |
スペシャルフォームor は、
conditionsの少なくとも1つが真であるかどうか調べる。
conditionsを1つ1つ書かれた順に評価して調べる。
conditionsのどれかが conditionsすべてが たとえば、つぎの式は、 (or (eq x nil) (eq x 0))
(or arg1 arg2 arg3) == (cond (arg1) (arg2) (arg3))
(if arg1 arg1 (if arg2 arg2 arg3)) これは完全には同一ではない。
というのは、arg1やarg2を2度評価するからである。
一方、 |
繰り返しとは、プログラムのある部分を何度も実行することです。
たとえば、リストの各要素や0からnの各整数について
1回ずつある計算を行いたい場合です。
Emacs Lispでこれを行うには、スペシャルフォームwhile
を使います。
while condition forms... | Special Form |
while は、まずconditionを評価する。
結果がnil 以外であれば、formsをテキスト上の順で評価する。
そして、conditionを評価し直し、その結果がnil 以外であれば、
再度formsを評価する。
この処理をconditionがnil に評価されるまで繰り返す。
繰り返し回数に制限はない。
ループは、conditionが フォーム (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 終了検査のまえに各繰り返しごとに実行したいことがあれば、
以下のように、それらと終了検査を (while (progn (forward-line 1) (not (looking-at "^$")))) これは、1行先へ移動し、空行に達するまで、移動を繰り返す。
この |
非ローカル脱出(nonlocal exit)とは、 プログラムのある場所から別の離れた場所へ制御を移すことです。 Emacs Lispでは、エラーの結果として非ローカル脱出が発生します。 非ローカル脱出は、明示的な制御にも使えます。 非ローカル脱出は、脱出対象の構造で作成したすべての変数束縛を解きます。
catch
とthrow
ほとんどの制御構造は、その構造内での制御の流れだけに影響します。
関数throw
は、通常のプログラム実行のこのような規則の例外です。
つまり、要求に従って非ローカルな脱出を行います。
(ほかにも例外はあるが、それらはエラー処理のためだけである。)
throw
はcatch
の内側で使い、
その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
を探します。
つまり、catch
の第1引数が
throw
に指定されたものにeq
であるcatch
を探します。
そのようなcatch
が複数個ある場合には、
もっとも内側のものを優先します。
したがって、上の例では、throw
はfoo
を指定し、
foo-outer
のcatch
は同じシンボルを指定しているので、
そのcatch
を使います
(ただし、これらのあいだには他の一致するcatch
がないとして)。
throw
の実行により、
対応するcatch
までのすべてのLispの構造を抜け出します。
これには関数呼び出しも含みます。
let
や関数呼び出しなどの束縛を作る構造からもこのように抜け出すので、
通常どおり抜け出す場合と同様に束縛を解きます
(see Local Variables)。
同様に、throw
は、save-excursion
(see Excursions)で
保存したバッファや位置情報、
save-restriction
で保存したナロイング状態、
save-window-excursion
(see Window Configurations)で保存した
ウィンドウの選択状態も復元します。
さらに、スペシャルフォームunwind-protect
で設定した後始末を
このフォームから抜け出すときに実行します(see Cleanups)。
throw
は、テキスト上で、
ジャンプ先であるcatch
の内側に現れる必要はありません。
throw
は、catch
内から呼ばれた別の関数からも戻ることもできます。
throw
の実行が、
時間的にcatch
に入ったあとで、かつ、それから抜けるまえである限り、
throw
は対応するcatch
を参照できます。
エディタコマンドループ(see Recursive Editing)から抜ける
exit-recursive-edit
などのコマンドで
throw
を使えるのは、このような理由からです。
Common Lispに関した注意:Common Lispを含むほとんどの他のLispには、 非逐次的に制御を移す方法がいくつかある。 たとえば、
return
、return-from
、go
。 Emacs Lispにはthrow
しかない。
catch tag body... | Special Form |
catch は、関数throw 向けに戻り位置を確立する。
その戻り位置は、tagによって他の戻り位置と区別される。
tagは、nil 以外ならば任意のLispオブジェクトでよい。
引数tagは、戻り位置を確立するまえに、通常どおり評価される。
戻り位置を確立してから、 bodyの内側で、tagと同じ値を指定した |
throw tag value | Function |
throw の目的は、
catch でまえもって確立しておいた戻り位置へ復帰することである。
引数tagは、さまざまな既存の戻り位置から選ぶために使う。
tagは、catch で指定した値とeq である必要がある。
tagに複数の戻り位置が一致する場合には、もっとも内側のものを使う。
引数valueは、対応する タグtagである有効な戻り位置がなければ、
|
catch
とthrow
の例catch
とthrow
の使い方の1つは、
2重のループからの脱出です。
(ほとんどの言語では、これを『go to』で行うであろう。)
ここでは、iとjを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
以外を返すと、
ただちに止まってiとjのリストを返します。
foo
がつねにnil
を返すと、
catch
は通常どおりに戻って、その値はnil
です。
というのは、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
で確立したものに戻ります。
したがって、catch2
は値yes
で通常どおり戻り、
この値が表示されます。
最後に、外側のcatch
の2番目の本体フォーム、
つまり、'no
が評価され、外側のcatch
から戻ります。
今度は、catch2
に指定する引数を変更してみます。
(defun catch2 (tag) (catch tag (throw 'hack 'yes))) => catch2 (catch 'hack (print (catch2 'quux)) 'no) => yes
ここでも2つの戻り位置がありますが、
今度は外側のものだけがタグhack
です。
内側のものはタグquux
です。
したがって、throw
により、外側のcatch
が値yes
を返します。
関数print
はけっして呼ばれず、
本体フォーム'no
もけっして評価されません。
Emacs Lispが、なんらかの理由で評価できないフォームを評価しようとしたときには、 Emacs Lispはエラー(error)を通知(signals)します。
エラーが通知されると、Emacsのデフォルトの動作は、 エラーメッセージを表示し、現在のコマンドの実行を終了します。 バッファの末尾でC-fを打ったときなどのように、 これはほとんどの場合、適切なことです。
複雑なプログラムでは、単に終了するだけでは満足できないこともあります。
たとえば、プログラムではデータ構造に一時的な変更を加えていたり、
プログラム終了時には削除する必要がある一時的なバッファを作成するでしょう。
そのような場合には、unwind-protect
を使って、
エラー発生時に評価される後始末式(cleanup expressions)を
確立しておきます。
(see Cleanups。)
場合によっては、サブルーティンでエラーが発生しても、
プログラムの実行を継続したいこともあるでしょう。
このような場合には、condition-case
を使って、
エラー状態から制御を回復するための
エラーハンドラ(error handlers)を確立しておきます。
エラー処理を用いてプログラムのある場所から別の場所へ制御を移す、
という誘惑には耐えてください。
そのかわりにcatch
とthrow
を使いましょう。
See Catch and Throw。
ほとんどのエラーは、他の目的で呼び出したLisp関数の内部で『自動的』に
通知されます。
整数のCARを計算しようとしたり、
バッファの末尾で1文字進めようとしたりしたときなどです。
関数error
や関数signal
で、
明示的にエラーを通知することもできます。
ユーザーがC-gを打ったときに発生する中断は、 エラーとは考えませんが、エラーのように扱います。
error format-string &rest args | Function |
この関数は、format-stringとargsに
format (see String Conversion)を適用して作った
エラーメッセージを伴ったエラーを通知する。
(error "That is an error -- try something else") error--> That is an error -- try something else (error "You have committed %d errors" 10) error--> You have committed 10 errors
警告: |
signal error-symbol data | Function |
この関数は、error-symbolという名前のエラーを通知する。
引数dataは、エラーの状況に関連したLispオブジェクトのリストである。
引数error-symbolは、エラーシンボル(error symbol)である
必要がある。
つまり、属性 dataのオブジェクトの個数と重要性はerror-symbolに依存する。
たとえば、エラー error-symbolとdataの両者は、
任意のエラーハンドラで利用できる。
関数 (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" |
Common Lispに関した注意:
Emacsには、Common lispの継続可能なエラーの概念に相当するものはない。
エラーが通知されると、signal
は、
エラーに対する有効なハンドラ(handler)を探します。
ハンドラは、Lispプログラムの一部でエラーが発生した場合に
実行されるように指定されたLisp式の列です。
エラーに対して適用可能なハンドラがあると、
そのハンドラが実行され、ハンドラに続いて制御は復旧します。
ハンドラは、そのハンドラを設定したcondition-case
の環境で実行されます。
condition-case
の内側で呼び出された関数はすべて終了しているので、
ハンドラからそれらへ戻ることはできません。
エラーに適用可能なハンドラがなければ、 現在のコマンドは終了し、制御はエディタコマンドループへ戻ります。 というのは、コマンドループには、 すべての種類のエラーに対する暗黙のハンドラがあるからです。 コマンドループのハンドラは、エラーシンボルと関連するデータを使って エラーメッセージを表示します。
明示的なハンドラがないエラーは、Lispデバッガを呼び出すこともあります。
変数debug-on-error
(see Error Debugging)が
nil
以外であると、デバッガが有効になります。
エラーハンドラと違って、デバッガはエラーの環境で実行されるので、
エラー時の変数の正確な値を調べることができます。
エラーを通知することの普通の効果は、
実行中のコマンドを終了し、Emacsのエディタコマンドループにただちに戻ります。
読者のプログラムの一部で発生したエラーを捕捉するようにするには、
スペシャルフォームcondition-case
を使ってエラーハンドラを設定します。
単純な例はつぎのようになります。
(condition-case nil (delete-file filename) (error nil))
これはfilenameという名前のファイルを削除しますが、
エラーが発生するとどんなエラーでも捕捉してnil
を返します。
condition-case
の第2引数を
保護されたフォーム(protected form)と呼びます。
(上の例では、保護されたフォームはdelete-file
の呼び出し。)
このフォームの実行を開始するとエラーハンドラが有効になり、
このフォームから戻るとエラーハンドラは取り除かれます。
そのあいだは、つねにエラーハンドラは有効です。
特に、このフォームから呼び出される関数の実行中、
それらのサブルーティンの実行中などには、エラーハンドラは有効です。
これは大切なことで、厳密にいえば、
エラーが通知されるのは、保護されたフォームから呼び出された
(signal
やerror
を含む)Lisp基本関数の実行中であって、
保護されたフォームそのものからではないからです。
保護されたフォームのうしろにある引数は、ハンドラです。
各ハンドラは1つ以上の(シンボルである)条件名
(condition names)を列挙し、処理するエラーを指定します。
エラーが通知されたときのエラーシンボルも条件名のリストを定義します。
それらに共通の条件名があるとき、
エラーハンドラがエラーに適用されます。
上の例では、1つのハンドラがあり、条件名は1つ、error
を指定しています。
この条件名はすべてのエラーを意味します。
適用可能なハンドラの探索では、
もっとも最近に確立されたハンドラから始めて、
確立されたすべてのハンドラを調べます。
したがって、フォームcondition-case
が2つ入れ子になっていて
同じ名前のハンドラを確立していると、内側のものが実際に処理を受け持ちます。
フォームcondition-case
でエラーが処理されるときには、
debug-on-error
でエラーによりデバッガを起動するように指定してあっても
デバッガは実行されません。
See Error Debugging。
condition-case
で捕捉されるエラーをデバッグしたいときには、
変数debug-on-signal
にnil
以外の値を設定します。
エラーを処理できる場合には、制御はハンドラに移ります。
こうするまえに、Emacsは、抜け出し対象となる束縛作成構造が設定した
すべての変数束縛を解き、抜け出し対象となるフォームunwind-protect
すべての後始末を実行します。
ハンドラに制御が移ると、ハンドラの本体を実行します。
ハンドラ本体の実行を完了すると、
フォームcondition-case
から戻ります。
ハンドラを実行するまえに保護されたフォームから完全に抜けているので、
ハンドラでは、エラー発生時点から再開したり、
保護されたフォームの内側で作られた変数束縛を調べたりすることはできません。
ハンドラでできることは、後始末をして先へ進むことだけです。
condition-case
構造は、insert-file-contents
の呼び出しで
ファイルのオープンに失敗するなどの予測可能なエラーを捕捉するために
しばしば使われます。
プログラムがユーザーから読み取った式を評価する場合のように、
まったく予測不可能なエラーを捕捉するためにも使われます。
エラー通知とエラー処理は、throw
とcatch
に多少似ていますが、
それらはまったく別の機能です。
catch
ではエラーを捕捉できませんし、
エラーハンドラではthrow
を処理できません
(しかしながら、適切なcatch
がないthrow
を使うと、
処理できるエラーを通知する)。
condition-case var protected-form handlers... | Special Form |
このスペシャルフォームは、protected-formの実行中は
エラーハンドラhandlersを確立する。
protected-formがエラーなしに完了すると、
その戻り値がフォームcondition-case の値になる。
この場合、condition-case はなんの効果もない。
フォームcondition-case で違いがでるのは、
protected-formの実行中にエラーが起こった場合である。
各handlersは、 (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)がある。
そのシンボルの属性 ハンドラの本体の実行を完了すると、
引数varは変数である。
varが |
error-message-string error-description | Function |
この関数は、指定したエラー記述に対するエラーメッセージ文字列を返す。 エラーに対する普通のエラーメッセージを表示して、 エラーを処理したい場合に便利である。 |
ゼロ除算の結果であるエラーを処理するcondition-case
の使用例を示します。
ハンドラはエラーメッセージを(ベルを鳴らさずに)表示して、
大きな数を返します。
(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
を指定しているので、
ゼロ除算エラーだけを処理します。
少なくともこのcondition-case
では他の種類のエラーは処理しません。
したがって、つぎのようになります
(safe-divide nil 3) error--> Wrong type argument: number-or-marker-p, nil
以下は、error
で通知されるエラーも含めて、
すべての種類のエラーを捕捉する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
エラーを通知するときには、読者が意図するエラーの種類を指定する エラーシンボル(error symbol)を指定します。 各エラーには、それを分類する一意な名前があります。 これは、Emacs Lisp言語で定義されたエラーを細分類したものです。
これらの細分類は、エラー条件(error conditions)と呼ばれる
より大きなクラスの階層にまとめられています。
エラー条件は、条件名(condition names)で識別します。
もっとも細かい分類は、エラーシンボルそのものです。
各エラーシンボルは条件名でもあります。
より大きなクラスを表す条件名error
もあります。
これはすべての種類のエラーを表します。
したがって、各エラーには、1つ以上の条件名があります。
つまり、error
、error
とは別のエラーシンボル、あるいは、
その中間の分類に属するものです。
あるシンボルがエラーシンボルであるためには、そのシンボルには、
条件名のリストを与える属性error-conditions
があることが必要です。
このリストは、そのエラーが属するエラー条件を定義します。
(エラーシンボルそのものと、シンボルerror
は、
つねにこのリストの要素であること。)
したがって、条件名の階層は、
エラーシンボルの属性error-conditions
で定義されます。
error-conditions
リストに加えて、
エラーシンボルには、属性error-message
も必要です。
この属性の値は、そのエラーが処理されないときに表示される文字列です。
属性error-message
があるのに、それが文字列でなければ、
エラーメッセージpeculiar error
を使います。
以下に、新たなエラーシンボルnew-error
の定義方法を示します。
(put 'new-error 'error-conditions '(error my-own-errors new-error)) => (error my-own-errors new-error) (put 'new-error 'error-message "A new error") => "A new error"
このエラーには、3つの条件名があります。
もっとも細かい分類であるnew-error
、
それより大きな分類とであると考えているmy-own-error
、
もっとも大きな分類であるerror
です。
エラー文字列は大文字で始めるべきですが、ピリオドで終えません。 これは、Emacsの他の慣習と整合をとるためです。
普通、Emacs自身がnew-error
を通知することはありえません。
つぎのように、読者のコードで明示的に
signal
(see Signaling Errors)を呼んだときだけです。
(signal 'new-error '(x y)) error--> A new error: x, y
このエラーは、3つの条件名のどれでも処理できます。
つぎの例は、new-error
と
クラスmy-own-errors
の任意の他のエラーを処理します。
(condition-case foo (bar nil t) (my-own-errors nil))
エラーを分類する重要な方法は、それらの条件名によることです。
つまり、エラーに一致するハンドラを探すために条件名を使います。
エラーシンボルは、意図したエラーメッセージと条件名のリストを指定する
簡便な方法を提供するだけです。
signal
に、1つのエラーシンボルではなく、
条件名のリストを指定するのではわずらわしいでしょう。
一方、条件名なしにエラーシンボルだけを使うのでは、
condition-case
の能力をいちじるしく損ないます。
条件名があることで、エラーハンドラを書くときにさまざまなレベルに
一般化してエラーを分類できるのです。
エラーシンボルだけを使ったのでは、
最細分類以外のレベルを削除してしまうことになります。
すべての標準エラー名とそれらの条件名については、 See Standard Errors。
unwind-protect
構造は、データ構造を一時的に整合性のない状態に
するときには本質的です。
この構造により、エラーや非ローカル脱出が起こったときに、
データの整合性を回復できます。
unwind-protect body cleanup-forms... | Special Form |
unwind-protect は、bodyからどのように制御が離れた場合にも
cleanup-formsの実行を保証して、bodyを実行する。
bodyは通常どおり完了するか、
throw を実行してunwind-protect から脱出するか、
エラーを引き起こす。
いずれの場合でも、cleanup-formsは評価される。
フォームbodyが正常に終了すると、
フォーム |
たとえば、表示しないバッファを一時的に作成し、 終了前に確実にそれを消去したいとしましょう。
(save-excursion (let ((buffer (get-buffer-create " *temp*"))) (set-buffer buffer) (unwind-protect body (kill-buffer buffer))))
変数buffer
を使わずに(kill-buffer (current-buffer))
と
書くだけで十分だと考えるかもしれません。
しかし、別のバッファに切り替えたあとでbodyでエラーが発生した場合には、
上の方法はより安全です。
(あるいは、bodyの周りに別のsave-excursion
を書いて、
一時バッファを消去するときに、それがカレントバッファになることを
保証する。)
Emacsには、上のようなコードに展開されるwith-temp-buffer
という
標準マクロがあります(see Current Buffer)。
本書で定義しているマクロのいくつかでは、
このようにunwind-protect
を使っています。
ファイルftp.el
から持ってきた実際の例を示しましょう。
リモートの計算機への接続を確立するプロセス(see Processes)を作ります。
関数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)))))
この例には、小さなバグが1つあります。
ユーザーがC-gを打って中断しようとして、かつ、
関数ftp-setup-buffer
の終了後に
変数process
を設定するまえに実際に中断が行われると、
プロセスは消去されません。
このバグを直す簡単な方法はありませんが、
少なくとも、ほとんど起こりえません。
変数(variable)は、プログラムにおいて値を表すために使う名前です。 ほとんどすべてのプログラム言語には、ある種の変数があります。 Lispプログラムのテキストでは、シンボルの構文を使って変数を書きます。
ほとんどのプログラム言語と違って、Lispでは、 プログラムはLispオブジェクトで表現し、テキスト表現は副次的なものです。 変数として使うLispオブジェクトはシンボルです。 シンボル名が変数名であり、変数の値はシンボルの値セルに格納されています。 変数としてのシンボルの使い方は、関数名としての使い方とは独立しています。 See Symbol Components。
Lispプログラムを構成するLispオブジェクト群は、 プログラムのテキスト表現を決定します。 つまり、Lispオブジェクト群に対する単なる入力構文です。 これは、たとえば、Lispプログラムのテキスト表現では、 変数を表現するシンボルの入力構文で変数を書く理由です。
変数を使うもっとも簡単な方法は、 グローバルに(globally、大局的に)使うことです。 つまり、どんなときにも変数にはたった1つの値だけがあり、 (少なくともここでは)Lispシステム全体にその値が有効になります。 新たな値を設定するまで、その値が有効であり続けます。 新たな値で古い値を置き換えると、変数には古い値の痕跡はなにも残りません。
シンボルの値はsetq
で指定します。
たとえば、
(setq x '(a b))
は、変数x
に値(a b)
を与えます。
setq
は、最初の引数、つまり、変数の名前を評価せず、
新しい値である第2引数を評価することに注意してください。
変数にいったん値を与えれば、 式としてシンボルそのものを使うことによりその値を参照できます。 つまり、つぎのとおりです。
x => (a b)
ただし、上に示したフォームsetq
を実行してあると仮定します。
同じ変数に値を設定し直すと、 新しい値で古い値を置き換えます。
x => (a b) (setq x 4) => 4 x => 4
Emacs Lispには、通常それ自身に評価されるある種のシンボルがあります。
:
で始まる名前の任意の変数、および、nil
とt
です。
これらのシンボルを再束縛することはできず、
それらの値を変更することもできません。
nil
やt
を設定しようとしたり束縛しようとすると、
エラーsetting-constant
を通知します。
:
で始まる名前のシンボルに関してもそうですが、
そのようなシンボルにそれ自身を設定することはできます。
nil == 'nil => nil (setq nil 500) error--> Attempt to set constant symbol: nil
keyword-symbols-constant-flag | Variable |
この変数がnil であると、
: で始まる名前の変数を望みの値に設定したり束縛したりできる。
これは、そのようなことを行う古いLispプログラムの実行を可能にするためである。
|
グローバル変数は、 明示的に新しい値で置き換えない限り存続する値を持ちます。 一時的にしか存在しない変数値、 つまり、プログラムのある部分を完了するまでのみ存在する変数値を 作れると便利なことがあります。 このような値をローカル(local、局所的)と呼び、 そのように使われる変数をローカル変数(local variables)と呼びます。
たとえば、関数を呼び出したとき、その引数変数は、
関数を抜けるまで存続する新たなローカルな値を受け取ります。
スペシャルフォームlet
は、指定した変数の新たなローカル値を
明示的に確立します。
これらはフォームlet
を抜けるまで存続します。
ローカル値を確立すると、 変数の以前の値(あるいは値がないこと)を保存します。 ローカル値の存続期間が終了すると、以前の値を復元します。 この期間は、以前の値を隠して(shadowed)いて 以前の値は見えません。 グローバル値でもローカル値でも隠せます(see Scope)。
変数がローカルなときに(setq
などで)その変数を設定すると、
ローカル値を置き換えます。
隠されているグローバル値や以前のローカル値を変更しません。
このふるまいをモデル化するために、
変数のローカル値に加えて変数のローカル束縛(local binding)を
考えます。
ローカル束縛とは、ローカル値を保持する概念的な場所です。
関数やlet
などのスペシャルフォームに入るたびに
ローカル束縛を作成します。
関数やフォームlet
から抜けるとローカル束縛を削除します。
ローカル束縛が存続する限り、変数の値はそこに保持されています。
ローカル束縛が存在するときにsetq
やset
を使うと、
ローカル束縛の中に別の値を格納します。
新たな束縛を作るのではありません。
グローバル値を保持する概念的な場所を グローバル束縛(global binding)ともいいます。
変数には一度に複数のローカル束縛がありえます
(たとえば、同じ変数を束縛する入れ子になったフォームlet
があるとき)。
そのような場合、既存のもっとも最近に作成されたローカル束縛が、
変数の現在の束縛(current binding)です。
(この規則を動的スコープ(dynamic scoping)と呼びます。
see Variable Scoping)
ローカル束縛がまったくなければ、変数のグローバル束縛が現在の束縛です。
現在の束縛のことを強調して既存の最ローカル束縛と呼ぶこともあります。
シンボルの通常の評価では、その現在の束縛の値を返します。
スペシャルフォームlet
やlet*
は、
ローカル束縛を作るためにあります。
let (bindings...) forms... | Special Form |
このスペシャルフォームは、bindingsに従って変数を束縛し、
formsのすべてをテキスト上の順に評価する。
let フォームは、formsの最後のフォームの値を返す。
bindingsのおのおのは、(i)シンボルであるか、
(ii)フォーム bindingsのvalue-form群すべてを現れる順に評価してから、
シンボルにそれらの値を束縛する。
例をつぎに示す。
(setq Y 2) => 2 (let ((Y 1) (Z Y)) (list Y Z)) => (1 2) |
let* (bindings...) forms... | Special Form |
このスペシャルフォームはlet に似ているが、
変数のローカル値を計算し終えた直後にその変数を束縛し、
つぎの変数のローカル値の計算に進む。
したがって、bindings内の式では、このlet* フォーム内で
まえにあるシンボルを参照できる。
つぎの例を上のlet の例と比較してほしい。
(setq Y 2)
=> 2
(let* ((Y 1)
(Z Y)) ; 設定し終えたばかりの
|
以下にローカル束縛を作成するその他の機能の完全な一覧をあげておきます。
変数は、バッファローカルな束縛(see Buffer-Local Variablesや フレームローカルな束縛(see Frame-Local Variables)を持つことができます。 少数の変数は、端末にローカルな束縛(see Multiple Displays) を持つこともできます。 この種の束縛は普通のローカル束縛と同じように働きますが、 これらはEmacsの『どの部分』にいるかに依存したローカル化であり、 時間的なローカル化ではありません。
max-specpdl-size | Variable |
この変数は、("Variable binding depth exceeds max-specpdl-size" を
伴った)エラーを通知するまでに許される、
ローカル変数束縛と
unwind-protect による後始末(see Nonlocal Exits)の
全体の個数の制限を定義する。
この制限、および、これを超えたときのエラーは、 不正に定義された関数によってLispが無限に再帰することを防止する 1つの方法である。 デフォルト値は600である。 Lispデバッガに入ったとき、 制限に近い場合にはデバッガ自身が実行できることを保証するために値を増やす。 |
シンボルにグローバル変数としての値を一度も与えていないとき、
そのシンボルのグローバル値は空(void)であるといいます。
いいかえれば、シンボルの値セルにはどんなLispオブジェクトも入っていません。
シンボルを評価しようとすると、値ではなくエラーvoid-variable
を得ます。
nil
という値は空とは異なることに注意してください。
シンボルnil
はLispオブジェクトであり、他のオブジェクトと同様に
変数の値になりえます。
それは値なのです。
空な変数はいかなる値も持たないのです。
変数に値を与えたあとでは、makunbound
を使って
再度その変数を空にできます。
makunbound symbol | Function |
この関数は、symbolの現在の変数束縛を空にする。
これ以降に変数としてこのシンボルの値を使おうとすると、
再度設定していない限り、エラーvoid-variable を通知する。
(makunbound 'x) ; 変数
symbolがローカルに束縛されていると、
(setq x 1) ; グローバル束縛に値を入れる
=> 1
(let ((x 2)) ; ローカルに束縛する
(makunbound 'x) ; ローカル束縛を空にする
x)
error--> Symbol's value as variable is void: x
x ; グローバル束縛は変更されていない
=> 1
(let ((x 2)) ; ローカルに束縛する
(let ((x 3)) ; もう一度
(makunbound 'x) ; もっとも内側のローカル束縛を空にする
x)) ; 参照するが、それは空
error--> Symbol's value as variable is void: x
(let ((x 2))
(let ((x 3))
(makunbound 'x)) ; 内側の束縛を空にし、それを削除する
x) ; 外側の
|
makunbound
で空にした変数は、
一度も値を受け取ったことがなく、そのために空である変数と区別できません。
変数が現在、空であるかどうかは関数boundp
を使って調べられます。
boundp variable | Function |
boundp は、(シンボル)variableが空でなければ、
より正確にいえば、現在の束縛が空でなければt を返す。
さもなければnil を返す。
(boundp 'abracadabra) ; 空で始める => nil (let ((abracadabra 5)) ; ローカルに束縛する (boundp 'abracadabra)) => t (boundp 'abracadabra) ; グローバルにはまだ空である => nil (setq abracadabra 5) ; グローバルに空でなくする => 5 (boundp 'abracadabra) => t |
スペシャルフォームdefconst
やdefvar
の変数定義を使って、
シンボルをグローバル変数として使う意図を表明できます。
Emacs Lispでは、定義には3つの目的があります。
まず、コードを読む人向けに、特定のシンボルを(変数として)特定目的に
使う意図があることを知らせます。
第2に、Lispシステムに対しては、値と説明文字列を提供して
これらのことを伝えます。
第3に、プログラム内の関数や変数のデータベースを作成する
etags
やmake-docfile
などのユーティリティに情報を提供します。
defconst
とdefvar
の違いは、主に好みの問題であり、
値が変更されるかどうかを人に伝えます。
Emacs Lispは、defconst
やdefvar
の宣言に基づいて
変数の使い方を制限することはしません。
しかしながら、初期化に関しては違いがあります。
defconst
は無条件に変数を初期化しますが、
defvar
は変数が空である場合にのみ初期化します。
defvar symbol [value [doc-string]] | Special Form |
このスペシャルフォームは、symbolを変数として定義し、
初期値や説明文字列を設定する。
この定義は、コードを読む人向けに、
値を設定したり変更する変数としてsymbolを使うことを伝える。
symbolは評価されないことに注意。
定義するシンボルは、defvar に明示的に現れる必要がある。
symbolの値が空でありvalueを指定してあると、
symbolにカレントバッファでバッファローカルな束縛がある場合には、
emacs-lispモードにおいてC-M-x( doc-stringがあれば、それは変数の説明文を指定する。
(説明文を指定できるのは、変数定義の主な利点の1つである。)
説明文はシンボルの属性 doc-stringの最初の文字が いくつか例をあげる。
つぎのフォームは (defvar foo) => foo つぎの例は、 (defvar bar 23 "The normal weight of a bar.") => bar つぎの例は、 (defvar bar (1+ nil) "*The normal weight of a bar.") => bar bar => 23 つぎの例は、スペシャルフォーム (defvar symbol value doc-string) == (progn (if (not (boundp 'symbol)) (setq symbol value)) (if 'doc-string (put 'symbol 'variable-documentation 'doc-string)) 'symbol) フォーム |
defconst symbol [value [doc-string]] | Special Form |
このスペシャルフォームは、symbolを変数として定義し初期化する。
この定義は、コードを読む人向けに、
symbolはこれ以降標準のグローバル値を持ち、
ユーザーや他のプログラムが変更すべきでないことを伝える。
symbolは評価されないことに注意。
定義するシンボルは、defconst に明示的に現れる必要がある。
つぎの例では、 (defconst pi 3.1415 "Pi to five places.") => pi (setq pi 3) => pi pi => 3 |
user-variable-p variable | Function |
この関数は、variableがユーザーオプション、つまり、
カスタマイズのためにユーザーが設定することを意図した変数であると、
t を返し、さもなければnil を返す。
(ユーザーオプション向け以外の変数は、Lispプログラムの内部目的用にあり、
それらについてユーザーが知る必要はない。)
ユーザーオプション変数は、
属性 |
ユーザーオプション変数に属性variable-interactive
があると、
コマンドset-variable
はその属性値を使って、
変数の新しい値の読み取りを制御します。
この属性値は、interactive
の引数(see Using Interactive)
のように使われます。
しかしながら、この機能はdefcustom
(see Customization)により
ほとんど廃れています。
警告:
変数にローカル束縛があるときに
スペシャルフォームdefconst
やdefvar
を使うと、
ローカル束縛の値を変更し、グローバル束縛は変更しない。
これは望む効果ではない。
これを防ぐには、これらのスペシャルフォームはファイルのトップレベルで使う。
そうすれば、普通は有効なローカル束縛はない。
さらに、変数のローカル束縛を作るまえに、
確実にファイルをロードしておく。
(内部に束縛を含むようなキーマップなどの)複雑な値を保持する変数を
定義し初期化するときには、つぎのように、
値の計算全体をdefvar
の内部に入れておくのが最良です。
(defvar my-mode-map (let ((map (make-sparse-keymap))) (define-key map "\C-c\C-a" 'my-command) ... map) docstring)
この方法には、いくつかの利点があります。
まず、ファイルのロード中にユーザーが中断した場合、
変数は初期化されないか正しく初期化されるかのいずれかであり、
その中間状態ということはありません。
第2に、変数をすでに初期化したあとにファイルをロードし直しても、
変数を変更しません。
(キーをバインドし直すなどの)内容の一部を変更するために
ユーザーがフックを実行した場合などには、これは重要です。
第3に、C-M-xでフォームdefvar
を評価すると、
マップを完全に初期化し直せます。
フォームdefvar
の内側に多くのコードを置くことには、欠点が1つあります。
変数の名前を指定した行から説明文字列が離れすぎてしまうことです。
つぎのようにしてこれを安全に防げます。
(defvar my-mode-map nil docstring) (if my-mode-map nil (let ((map (make-sparse-keymap))) (define-key my-mode-map "\C-c\C-a" 'my-command) ... (setq my-mode-map map)))
これには、defvar
の内側に初期化を入れたときと同じ利点がありますが、
変数を再初期化するには、各フォームそれぞれについて
C-M-xを打つ必要があります。
しかし、つぎのようなコードは書かないでください。
(defvar my-mode-map nil docstring) (if my-mode-map nil (setq my-mode-map (make-sparse-keymap)) (define-key my-mode-map "\C-c\C-a" 'my-command) ...)
このコードでは、変数を設定してから変更しますが、
それを複数の手順で行います。
setq
の直後にユーザーが中断すると、
変数は正しく初期化されておらず、空でもnil
でもありません。
こうなったときにファイルを再ロードしても変数を初期化できません。
変数は不完全な状態のままです。
変数を参照する普通の方法は、
変数を指名するシンボルを書くことです(see Symbol Forms)。
これには、プログラムを書くときに変数名を指定する必要があります。
読者は、普通このようにするでしょう。
場合によっては、実行時にどの変数を参照するか選ぶ必要があり、
そのときにはsymbol-value
を使います。
symbol-value symbol | Function |
この関数はsymbolの値を返す。
これは、シンボルのもっとも内側のローカル束縛の値、あるいは、
ローカル束縛がなければグローバル値である。
(setq abracadabra 5) => 5 (setq foo 9) => 9 ;; ここで、 symbolの現在の束縛が空であると、
エラー |
変数の値を変更する普通の方法は、スペシャルフォームsetq
を使うことです。
実行時に選択する変数を計算する必要があるときには、
関数set
を使います。
setq [symbol form]... | Special Form |
このスペシャルフォームは、変数の値を変更するもっとも一般的な方法である。
各symbolに、対応するformの評価結果である新たな値を与える。
シンボルの既存の際、ローカルの束縛を変更する。
フォーム (setq x (1+ 2)) => 3 x ; 最初のformを評価して最初のsymbolに設定し、 つぎに、2番目のformを評価して2番目のsymbolに設定し、 といった具合になることに注意。 (setq x 10 ; |
set symbol value | Function |
この関数は、symbolの値としてvalueを設定し、valueを返す。
set は関数なので、symbolとして書いた式は、
設定するシンボルを得るために評価される。
変数の既存の最ローカルの束縛に設定する。 隠されている束縛には影響しない。 (set one 1) error--> Symbol's value as variable is void: one (set 'one 1) => 1 (set 'two 'one) => one (set two 2) ; symbol(の評価結果)が実際にはシンボルでないと、
エラー (set '(x y) 'z) error--> Wrong type argument: symbolp, (x y) 論理的には、 Common Lispに関した注意: |
変数に設定する別の関数は、リストに既存でない要素を追加するように 設計されたものです。
add-to-list symbol element | Function |
この関数は、elementが変数symbolの値のリストのメンバでなければ、
elementと変数symbolの値をコンスした値を
変数symbolに設定する。
リストを変更してもしなくても結果のリストを返す。
呼び出すまえに、symbolの値はリストであるほうがよい。
引数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)
に等価な式はつぎのとおりです。
(or (member value var) (setq var (cons value var)))
あるシンボルfoo
は、さまざまなローカルな変数束縛を持つことができます。
Lispプログラムの異なる場所で確立されたものや
グローバル束縛です。
もっとも最近に確立した束縛が他のものに優先します。
Emacs Lispのローカル束縛は、無限のスコープ(indefinite scope)と 動的存続期間(dynamic extent)を持ちます。 スコープ(scope)とは、ソースコードのテキスト上の どこから束縛を参照できるかを表します。 無限のスコープとは、プログラムのどこからでも変数束縛を参照できることを 意味します。 存続期間(extent)とは、プログラムの実行にしたがって、 いつ束縛が存在するかを表します。 動的存続期間とは、束縛を作成した構造が有効である限り、 束縛が存続することを意味します。
動的存続期間と無限のスコープの組み合せを 動的スコープ(dynamic scoping)と呼びます。 対照的に、ほとんどのプログラム言語は、 レキシカルスコープ(lexical scoping)を用います。 つまり、ローカル変数の参照は、 その変数を束縛する関数やブロックのテキスト上で内側にある必要があります。
Common Lispに関した注意:
Common Lispでは、『スペシャル』と宣言した変数は、
Emacs Lispのすべての変数と同様に、動的スコープである。
Emacs Lispでは、 ローカル変数束縛は無限のスコープ(indefinite scope)です。 つまり、プログラムテキスト上のどの関数からでも、 ある変数束縛を参照できるのです。 つぎの関数定義を考えてみましょう。
(defun binder (x) ;x
は、binder
で束縛 (foo 5)) ;foo
は別の関数 (defun user () ;x
は、user
において『自由』 (list x))
テキスト上のスコープを用いる言語では、
binder
内のx
の束縛を、user
で参照することはできません。
なぜなら、user
は、テキスト上で関数binder
の内側にはないからです。
しかしながら、動的スコープのEmacs Lispでは、
状況に応じて、binder
内で確立したx
の束縛を
user
から参照してもしなくてもよいのです。
binder
をまったく呼び出さずに、直接user
を呼び出したときには、
とにかくみつかったx
の束縛を使うが、
それはbinder
のものではありえない。
foo
をつぎのように定義してbinder
を呼び出したときには、
binder
が作った束縛をuser
で見える。
(defun foo (lose) (user))
foo
をつぎのように定義してbinder
を呼び出したときには、
binder
が作った束縛はuser
では見えない。
(defun foo (x) (user))
ここで、binder
がfoo
を呼び出すと、
foo
はx
を束縛する。
(foo
の束縛はbinder
の束縛を隠す(shadow)という。)
したがって、user
は、binder
の束縛ではなく、
foo
の束縛を参照することになる。
Emacs Lispで動的スコープを使うのは、 テキスト上のスコープの単純な実装は遅いからです。 さらに、すべてのLispシステムは、少なくともオプションとして、 動的スコープを使えるようにする必要があります。 テキスト上のスコープが標準であると、 特定の変数に対して動的スコープを指定する方法が必要になります。 Emacsで両方のスコープを使えるようにしてもよいのですが、 動的スコープだけだと実装がより簡単になります。
存続期間(Extent)とは、プログラムの実行中において、 変数名が有効である期間を指します。 Emacs Lispでは、束縛を作ったフォームを実行している期間中だけ、 変数は有効です。 これを動的存続期間(dynamic extent)と呼びます。 CやPascalなどのほとんどの言語の『ローカル』変数や『自動』変数も 動的存続期間です。
動的存続期間とは別のものに無限の存続期間(indefinite extent)があります。 つまり、変数束縛は、その束縛を作ったフォームから抜けても存続するのです。 たとえば、Common LispやSchemeにはこれがありますが、Emacs Lispにはありません。
これを説明するために、つぎの関数make-add
を考えます。
この関数は、nに自身の引数mを加算する関数を返します。
この関数はCommon Lispでは動作しますが、Emacs Lispではだめです。
というのは、make-add
の呼び出しを抜けると、
変数nは実引数2に束縛されなくなるからです。
(defun make-add (n) (function (lambda (m) (+ n m)))) ; 関数を返す => make-add (fset 'add2 (make-add 2)) ; 関数add2
を ;(make-add 2)
を使って定義する => (lambda (m) (+ n m)) (add2 4) ; 4に2を加算してみる error--> Symbol's value as variable is void: n
Lispの方言のいくつかには『クロージャ』(closure)があります。 それは関数のようなオブジェクトですが、追加の変数束縛を記録します。 Emacs Lispにはクロージャはありません。
(Emacs Lispの実際の動作とは異なるが)単純な実装例が、 動的束縛を理解する助けになるでしょう。 この技法を深い束縛(ディープバインディング、deep binding)と呼び、 初期のLispシステムで使われていました。
変数・値の対である束縛のスタックがあるとしましょう。
関数やフォームlet
に入ると、
引数やローカル変数の束縛をスタックに積みます。
束縛を作った構造から抜けるとそれらの束縛を取りさります。
変数の値は、スタックの先頭から底へ向けてその変数の束縛を探索します。 その束縛から得る値が変数の値になります。 変数に設定するには、現在の束縛を探して、その束縛に新たな値を格納します。
これからわかるように、関数の束縛は、その関数の実行中には、 たとえ別の関数を呼び出していても、存続しています。 これが束縛の存続が動的であるという理由です。 また、その束縛が有効である期間中ならば、同じ変数を使えば他の関数からも 束縛を参照できるのです。 これがスコープが無限であるという理由です。
GNU Emacs Lispにおいて、変数のスコープの実際の実装には、 浅い束縛(シャローバインディング、shallow binding)と呼ばれる 技法を用いています。 各変数には現在値を保存しておく標準の場所、シンボルの値セルがあります。
浅い束縛では、変数の設定は値セルに値を格納することで動作します。 新たな束縛を作成すると(以前の束縛に属する)古い値をスタックに積み、 新たなローカル値を値セルに格納します。 束縛を解くときには、古い値をスタックから取り出して値セルに格納します。
浅い束縛を用いる理由は、束縛を探索する必要がないため、 深い束縛と同じ結果を持ちながら高速に動作するからです。
ある関数で変数を束縛し別の関数でそれを使うことは、強力な技法ですが、 なんの制限もせずに使うとプログラムを理解し難いものにしてしまいます。 この技法を見通しよく使うための2つの方法があります。
他のプログラマに対して、彼らがそのような変数を目にするまえに、 そのような変数の使い方がわかるようなコメントを書き、 他の場所では使わないように助言しておく。
case-fold-search
は、
『nil
以外であれば探索時に大文字小文字を区別しない』と定義されている。
さまざまな探索関数や置換関数が、この変数を直接に、あるいは、
サブルーティンを介して参照するが、
この変数を束縛したり設定したりしない。
こうしておいて別のプログラムで変数を束縛するが、 それにどのような効果があるか確実に知ってから行える。
いずれの場合でも、変数はdefvar
で定義するべきです。
これは、関数間での変数の使い方を見るように伝えることで、
他人が読者のプログラムを理解するのを助けます。
また、バイトコンパイラからの警告も防ぎます。
変数名が衝突しないようにも注意しましょう。
x
のような短い名前を使わないでください。
グローバルとローカルの変数束縛は、 ほとんどのプログラム言語にいろいろな形であります。 Emacsには、あまり普通でない追加の種類の変数束縛があります。 1つのバッファだけに適用されるバッファローカルな束縛、 1つのフレームだけに適用されるフレームローカルな束縛です。 異なるバッファやフレームごとに変数に異なる値があるということは、 重要なカスタマイズ技法です。
本節では、バッファローカルな束縛を説明します。 フレームローカルな束縛については、つぎの節と See Frame-Local Variables。 (各端末にローカルな束縛を持つ変数も少数ある。 see Multiple Displays。)
バッファローカルな変数には、特定のバッファに関連したバッファローカルな 束縛があります。 この束縛は、そのバッファがカレントバッファであるときに有効になります。 さもなければなんの効果もありません。 バッファローカルな束縛が有効なときに変数に設定すると、 新しい値はその束縛に入り、他の束縛は変更されません。 つまり、その変更は、変更を行ったバッファだけで見ることができるのです。
変数の通常の束縛、つまり、特定のバッファに関連していない束縛を デフォルトの束縛(default binding)と呼びます。 多くの場合、これはグローバル束縛です。
変数は、あるバッファ群ではバッファローカルな束縛を持ち、 他のバッファではそのような束縛を持たないようにできます。 変数に対する独自の束縛を持たないバッファすべてでは、 デフォルトの束縛を共有します。 (これには、新たに作成されるバッファも含む。) バッファローカルな束縛を持たないバッファで変数に設定すると、 (状況を複雑にするフレームローカルな束縛はないと仮定して) デフォルトの束縛を使います。 したがって、新たな値はデフォルトの束縛を見るバッファすべてで見えます。
バッファローカルな束縛のもっとも一般的な使い方は、
メジャーモードでコマンドのふるまいを制御する変数に変更することです。
たとえば、CモードやLispモードでは、変数paragraph-start
を設定して、
空行だけが段落を区切るように指定します。
これには、CモードやLispモードになったバッファでは、
変数をバッファローカルにしてから、
そのモード用の新たな値を変数に設定するのです。
See Major Modes。
バッファローカルな束縛を作る普通の方法は、
make-local-variable
です。
メジャーモードのコマンドは典型的にこれを使います。
これはカレントバッファだけに影響します。
(これから作成するものも含めて)他のすべてのバッファは、
それ専用のバッファローカルな束縛を明示的に与えない限り、
デフォルト値を共有し続けます。
より強力な操作は、make-variable-buffer-local
を呼び出して
変数を自動的にバッファローカルにするように印を付けることです。
これは、これから作成するものも含めたバッファすべてで、
変数をバッファローカルにすると考えることができます。
より正確には、変数がカレントバッファにローカルでなければ、
自動的に変数をカレントバッファにローカルにするように設定する効果があります。
すべてのバッファは通常どおり変数のデフォルト値を共有して始まりますが、
変数に設定するとカレントバッファにバッファローカルな束縛を作ります。
新たな値はバッファローカルな束縛に格納され、デフォルトの束縛は変更しません。
つまり、どのバッファでもデフォルト値をsetq
では変更できません。
デフォルト値を変更する唯一の方法は、setq-default
を使うことです。
警告:
複数のバッファにおいて変数にバッファローカルな値があるときに、
変数をlet
で束縛してから、
別の束縛が有効である別のバッファに切り替えてlet
を抜けると、
Emacsをとても混乱させることになる。
こうすると、バッファローカルな束縛とデフォルトの束縛を混ぜ合わせてしまう。
混乱を避けるために、このような変数の使い方は避けてください。
別のバッファに切り替える各コード部分をsave-excursion
で囲めば、
このような問題はありません。
(setq foo 'b) (set-buffer "a") (make-local-variable 'foo) (setq foo 'a) (let ((foo 'temp)) (set-buffer "b") body...) foo => 'a ; バッファa
の古いバッファローカルな値が ; 現在のデフォルト値 (set-buffer "a") foo => 'temp ; 消えているべきローカルなlet
の値が ; バッファa
の現在のバッファローカルな値
しかし、つぎに示すようにsave-excursion
を使えば、この問題を回避できます。
(let ((foo 'temp)) (save-excursion (set-buffer "b") body...))
body内でのfoo
への参照は、
バッファb
のバッファローカルな束縛を使います。
ファイルでローカル変数の値を指定していると、 そのファイルを訪問したときに、それらはバッファローカルな値になります。 See File Variables。
make-local-variable variable | コマンド |
この関数は、カレントバッファにおいて、
variable(シンボル)のバッファローカルな束縛を作る。
他のバッファは影響されない。
返す値はvariable。
variableのバッファローカルな値は、 variableの以前と同じ値で始まる。 variableが空であれば、空のままである。 ;; バッファ 変数の 変数が端末にローカルなときには、この関数はエラーを通知する。 そのような変数は、同時にバッファローカルな束縛を持てない。 See Multiple Displays。 注意: |
make-variable-buffer-local variable | コマンド |
この関数は、variable(シンボル)を
自動的にバッファローカルにするように印を付け、
これ以降にその変数に設定しようとすると、
その時点のカレントバッファにローカルにする。
この機能の重要な点は、
( 返す値はvariableである。 警告: 2つのバッファが同じ束縛を共有しないことが重要な場面では、
|
local-variable-p variable &optional buffer | Function |
これは、variableがバッファbuffer
(デフォルトはカレントバッファ)において
バッファローカルであればt を返し、
さもなければnil を返す。
|
buffer-local-variables &optional buffer | Function |
この関数は、バッファbufferのバッファローカルな変数を
記述したリストを返す。
(bufferを省略するとカレントバッファを使う。)
バッファローカルな変数とその値を入れた要素から成る連想リスト
(see Association Lists)を返す。
しかし、bufferにおける変数のバッファローカルな束縛が空であると、
変数は結果のリストに直接現れる。
(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") ... ;; 続いて、組み込みでないバッファローカルな変数 ;; これはバッファローカルで、かつ、空 foobar ;; これはバッファローカルで、かつ、空ではない (bind-me . 69)) このリストのコンスセルのCDRに新たな値を格納しても、 変数のバッファローカルな値を変更しないことに注意してほしい。 |
kill-local-variable variable | コマンド |
この関数は、カレントバッファにおけるvariable(シンボル)の
バッファローカルな束縛を(あれば)削除する。
その結果、このバッファでは、variableのデフォルトの束縛が
見えるようになる。
典型的には、variableの値が変わる。
なぜなら、デフォルト値は、削除したバッファローカルな値とは
普通は異なるからである。
自動的にバッファローカルにする印が付いた変数のバッファローカルな束縛を 削除すると、カレントバッファではデフォルト値が見えるようになる。 しかし、変数に再度設定すると、それに対するバッファローカルな束縛が 再度作成される。
この関数がコマンドであるのは、 対話的にバッファローカルな変数を作るのが有用なように、 対話的にバッファローカルな変数を削除するのが有用な場合があるからである。 |
kill-all-local-variables | Function |
この関数は、カレントバッファにおいて、
『恒久的』と印付けしてある変数を除いて、
すべてのバッファローカルな変数束縛を削除する。
その結果、バッファでは、ほとんどの変数のデフォルト値が見えるようになる。
この関数は、バッファに属する他のある種の情報もリセットする。
つまり、ローカルキーマップに この関数が最初に行うことは、
ノーマルフック 各メジャーモードコマンドはこの関数を呼び出すことから始める。 つまり、基本(fundamental)モードに切り替え、 それ以前のメジャーモードのほとんどの効果を消しさる。 この処理を保証するために、メジャーモードで設定する変数には、 恒久的の印を付けないこと。
|
change-major-mode-hook | Variable |
関数kill-all-local-variables は、最初にこのノーマルフックを実行する。
このフックはメジャーモードに対して、
ユーザーが別のメジャーモードに切り替えていた場合には、
なにか特別なことを行う情報を提供する。
最良の結果を得るためには、この変数をバッファローカルにしておくと
その役目を終えると変数は消えてしまい、それ以降のメジャーモードに干渉しない。
see Hooks。
|
バッファローカル変数は、
変数名(シンボル)の属性permanent-local
がnil
以外であると、
恒久的(permanent)です。
恒久的なローカル変数は、編集作業の文脈ではなく、
どのファイルを訪問中であるとかどのように保存するとかに関連する情報に
適しています。
バッファローカルな束縛がある変数のグローバル値を、 デフォルト値とも呼びます。 カレントバッファや選択したフレームに変数の独自の束縛がない場合に、 グローバル値を使うからです。
関数default-value
と関数setq-default
は、
カレントバッファにバッファローカルな束縛があるかどうかに関わらず、
変数のデフォルト値を参照したり変更したりします。
たとえば、setq-default
を使って、
ほとんどのバッファのparagraph-start
のデフォルト値を変更できます。
この変数のバッファローカルな値があるCモードやLispモードのバッファで
行ってもこれは動作します。
スペシャルフォームdefvar
やdefconst
も、
バッファローカルやフレームローカルな値ではなく、
(変数に設定する場合には)デフォルト値を設定します。
default-value symbol | Function |
この関数は、symbolのデフォルト値を返す。
この値は、この変数に対して独自の値を持たないバッファやフレームで見える
値である。
symbolがバッファローカルでなければ、
これは、symbol-value (see Accessing Variables)と等価。
|
default-boundp symbol | Function |
関数default-boundp は、
symbolのデフォルト値が空でないことを調べる。
(default-boundp 'foo) がnil を返せば、
(default-value 'foo) はエラーになる。
|
setq-default [symbol form]... | Special Form |
このスペシャルフォームは、各symbolに、
対応するformの評価結果である新たなデフォルト値を与える。
symbolは評価しないが、formは評価する。
フォームsetq-default の値は、最後のformの値である。
symbolがカレントバッファでバッファローカルではなく、かつ、
自動的にバッファローカルにする印が付いていなければ、
;; バッファ |
set-default symbol value | Function |
この関数はsetq-default に似ているが、
symbolは普通どおりに評価される引数である。
(set-default (car '(a b c)) 23) => 23 (default-value 'a) => 23 |
変数にバッファローカルな束縛があるように、
変数にはフレームローカルな束縛もあります。
これらの束縛は1つのフレームに属し、
そのフレームを選択しているときに有効になります。
フレームローカルな束縛は、実際にはフレームパラメータです。
特定のフレームでフレームローカルな束縛を作るには
modify-frame-parameters
を呼び出し、
パラメータ名として変数名を指定します。
特定の変数に対するフレームローカルな束縛を有効にするには、
関数make-variable-frame-local
を呼び出します。
make-variable-frame-local variable | コマンド |
variableに対してフレームローカルな束縛を使うようにする。
この関数そのものはvariableに対してフレームローカルな束縛を作成しない。
しかし、フレームパラメータとしてvariableの値を持つフレームが
すでに存在すれば、その値は自動的にフレームローカルな束縛になる。
変数が端末にローカルであると、この関数はエラーを通知する。 そのような変数はフレームローカルな束縛を同時には持てないからである。 see Multiple Displays。 Emacsで特別に実装されている少数の変数は(普通) バッファローカルになることができるが、フレームローカルにはならない。 |
バッファローカルな束縛はフレームローカルな束縛に優先します。
変数foo
を考えてみましょう。
カレントバッファにfoo
のバッファローカルな束縛があると、
その束縛が有効になります。
選択したフレームにfoo
のフレームローカルな束縛があると、
その束縛が有効になります。
さもなければ、foo
のデフォルトの束縛が有効になります。
つぎに例を示します。
まず、foo
の束縛を準備しておきます。
(setq f1 (selected-frame)) (make-variable-frame-local 'foo) ;;b1
において、foo
のバッファローカルな束縛を作る (set-buffer (get-buffer-create "b1")) (make-local-variable 'foo) (setq foo '(b 1)) ;; 新しいフレームでfoo
のフレームローカルな束縛を作る ;; そのフレームをf2
に格納する (setq f2 (make-frame)) (modify-frame-parameters f2 '((foo . (f 2))))
では、さまざまな文脈でfoo
を調べてみましょう。
バッファb1
がカレントバッファであれば、
選択したフレームに関係なく、
b1
のバッファローカルな束縛が有効になっています。
(select-frame f1) (set-buffer (get-buffer-create "b1")) foo => (b 1) (select-frame f2) (set-buffer (get-buffer-create "b1")) foo => (b 1)
さもなければ、フレームの束縛を使う可能性があります。
フレームf2
を選択していると、
そのフレームローカルな束縛が有効になります。
(select-frame f2) (set-buffer (get-buffer "*scratch*")) foo => (f 2)
カレントバッファにもフレームにも束縛がなければ、 デフォルトの束縛を使います。
(select-frame f1) (set-buffer (get-buffer "*scratch*")) foo => nil
変数の有効な束縛がフレームローカルな束縛であるとき、
変数に設定するとその束縛を変更します。
frame-parameters
でその結果を見ることができます。
(select-frame f2) (set-buffer (get-buffer "*scratch*")) (setq foo 'nobody) (assq 'foo (frame-parameters f2)) => (foo . nobody)
フレームに分類されるものでローカルな束縛というアイデアを考察しています。
たとえば、すべてのカラーフレーム、暗い背景色のすべてのフレームなどです。
この機能が本当に有用なのか明らかでないので、それらをまだ実装してはいません。
after-make-frame-hook
に関数を追加して、
各フレームの適切な状態に応じたフレームパラメータを設定すれば、
同じような結果を得られます。
ウィンドウローカルな束縛を実装することも可能です。 これが有用である多くの状況を知りませんが、 バッファローカルな束縛を持つ間接バッファ(see Indirect Buffers)で、 そのような状況をより堅牢に扱えると思います。
これら2種類のローカル束縛のいずれかを必要とする十分な数のアプリケーションが みつかれば、Emacsの将来の版でそのような束縛を提供するでしょう。
Lispプログラムは、主にLisp関数から構成されます。 本章では、関数とはなにか、引数をどのように受け取るのか、 どのように関数を定義するのかを説明します。
一般的には、関数とは、引数(arguments)と呼ばれる値を与えられ、 計算を行うための規則です。 この計算結果を関数の値と呼びます。 計算では副作用、つまり、変数の値やデータ構造の内容に継続する変更 を伴うこともできます。
Emacs Lispの関数や関数のようなオブジェクトに関する重要な用語をあげておきます。
car
やappend
などのCで書いた
Lispから呼び出し可能な関数である。
これらの関数は、組み込み関数とかsubrsとも呼ぶ。
(スペシャルフォームは基本関数とも考えられる。)
関数を基本関数として実装する理由は、
それが基本的なものである、
それがオペレーティングシステムの機能に対する
低レベルのインターフェイスを提供する、
あるいは、高速に動作する必要があるからである。
基本関数を変更したり追加する唯一の方法は、
Cソースを変更してエディタを再コンパイルすることである。
see Writing Emacs Primitives。
command-execute
が起動できるオブジェクトであり、
キー列に対して定義できる。
いくつかの関数はコマンドである。
Lispで書いた関数に対話宣言(see Defining Commands)が含まれているとき、
その関数はコマンドである。
そのような関数は、他の関数と同様にLisp式から呼び出すことができる。
その場合、関数がコマンドであるという事実は関係ない。
キーボードマクロ(文字列かベクトル)もコマンドであるが、
それらは関数ではない。
シンボルの関数定義がコマンドであれば、シンボルはコマンドである。
そのようなシンボルは、M-xで起動できる。
シンボルの定義が関数であれば、シンボルは関数でもある。
functionp object | Function |
この関数は、objectが、なんらかの関数、スペシャルフォーム、
マクロであれば、t を返す。
|
subrp object | Function |
この関数は、objectが組み込み関数(つまり、Lisp基本関数)であれば
t を返す。
(subrp 'message) ;
|
byte-code-function-p object | Function |
この関数は、objectがバイトコード関数であればt を返す。
たとえば、つぎのとおり。
(byte-code-function-p (symbol-function 'next-line)) => t |
Lispで書いた関数はつぎのようなリストです。
(lambda (arg-variables...) [documentation-string] [interactive-declaration] body-forms...)
このようなリストをラムダ式(lambda expression)と呼びます。 Emacs Lispでは、これは式として正しいもので、 それ自身に評価されます。 Lispの他の方言では、ラムダ式は正しい式ではありません。 いずれの場合でも、その主な用途は式として評価することではなく、 関数として呼び出すことです。
ラムダ式の先頭要素は、つねにシンボルlambda
です。
このシンボルは、リストが関数を表すことを示します。
関数はlambda
で始まると定義してあるのは、
他の目的向けの他のリストが誤って正しい関数とならないようにするためです。
第2要素は、シンボルのリスト、つまり、引数変数名です。 これをラムダリスト(lambda list)と呼びます。 Lisp関数が呼ばれると、引数値をラムダリストの変数に対応させ、 指定した値を持つローカル束縛になります。 See Local Variables。
説明文字列は、関数定義の内側にあるLisp文字列オブジェクトであり、 Emacsのヘルプ機能に対して関数を記述します。 See Function Documentation。
対話宣言は、(interactive code-string)
の形式のリストです。
この宣言は、関数が対話的に使われたときに、
どのように引数を与えるかを指定します。
この宣言を有する関数をコマンド(commands)と呼びます。
コマンドは、M-xで呼び出したり、キーにバインドできます。
このように呼ばれることを意図していない関数には、
対話宣言を付けてはいけません。
対話宣言の書き方については、See Defining Commands。
残りの要素は、関数の本体(body)です。 関数の動作を行うLispコードです (Lispプログラマとしては、『評価するべきLispフォームのリスト』という)。 関数が返す値は、本体の最後の要素が返す値です。
つぎの関数を考えてみましょう。
(lambda (a b c) (+ a b c))
この関数を呼び出すには、つぎのように式のCARにこの関数を書きます。
((lambda (a b c) (+ a b c)) 1 2 3)
この呼び出しは、変数a
には1、変数b
には2、
変数c
には3を束縛し、ラムダ式の本体を評価します。
本体の評価ではこれらを加算し、結果6を生じます。
したがって、この関数呼び出しは6を返します。
つぎの例のように、他の関数呼び出しの結果が引数になることもあります。
((lambda (a b c) (+ a b c)) 1 (* 2 3) (- 5 4))
これは、引数、1
、(* 2 3)
、(- 5 4)
を
左から右へ順に評価します。
そして、引数値、1、6、1にラムダ式を適用し、値8を生じます。
このようにフォームのCARとしてラムダ式を書くのは、
あまり便利ではありません。
スペシャルフォームlet
(see Local Variables)を使って、
ローカル変数を作ってそれらに値を与えても、同じ結果を得られます。
さらに、let
は見通しがよく使いやすいです。
実用上、ラムダ式は、シンボルの関数定義として格納して名前付き関数を作るか、
他の関数に引数として渡します(see Anonymous Functions)。
しかしながら、スペシャルフォームlet
がなかった初期のLispでは、
ラムダ式を明示的に呼び出すことはとても便利でした。
その頃では、ラムダ式はローカル変数を束縛し初期化する唯一の方法でした。
単純な関数の例(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]) ; 残りの引数
角括弧は、&optional
や&rest
の節や
それに続く変数は省略できることを示します。
関数呼び出し時には、各required-varsに1つの実引数が必要です。
0個以上のoptional-varsにも実引数が必要ですが、
ラムダリストに&rest
がない限り、
optional-varsの個数を超える実引数は指定できません。
&rest
があれば、任意個の余分な実引数を指定できます。
&optional
や&rest
に対応する実引数を省略すると、
それらのデフォルトはnil
です。
関数では、nil
を明示した引数と省略した引数とを区別する方法はありません。
しかしながら、関数本体でnil
を適切な意味ある値の省略と
みなすことは自由です。
substring
はそのようにしています。
substring
の第3引数がnil
であると、
指定した文字列の長さを使うことを意味します。
Common Lispに関した注意:Common Lispでは、省略可能引数を省略したときのデフォルト値を関数で指定できる。 Emacs Lispではつねに
nil
を使う。 Emacs Lispには、明示的に引数を指定したかどうか調べる 『supplied-p』変数はない。
たとえば、引数リストはつぎのようになります。
(a b &optional c d &rest e)
これは、a
とb
に最初の2つの実引数を束縛し、これらは必須です。
さらに1個か2個の引数を指定すると、
それらは、それぞれc
とd
に束縛します。
最初の4個よりあとの引数はリストにまとめ、
e
にそのリストを束縛します。
引数が2個だけであると、c
はnil
です。
引数が2個か3個だけであると、d
はnil
です。
引数が4個以下であると、e
はnil
です。
省略可能な引数のあとに必須引数を指定する方法はありませんし、
それには意味がありません。
なぜそうなのかを理解するために、上の例で、
c
は省略可能であり、d
は必須であるとしましょう。
3つの実引数を指定したとき、どの引数を3番目と考えるのでしょう?
同様に、&rest
のうしろに余分に(必須、もしくは省略可能な)引数が
あっても意味がありません。
引数リストと正しい呼び出しの例をあげます。
((lambda (n) (1+ n)) ; 1個が必須 1) ; 引数は1個だけ => 2 ((lambda (n &optional n1) ; 1個は必須、1個は省略可 (if n1 (+ n n1) (1+ n))) ; 引数は1個か2個 1 2) => 3 ((lambda (n &rest ns) ; 1個は必須、あとは残り全部 (+ n (apply '+ ns))) ; 引数は1個以上いくつでもよい 1 2 3 4 5) => 15
ラムダ式には、ラムダリストの直後に 説明文字列(documentation string)があってもかまいません。 この文字列は関数の実行には影響しません。 コメントのようなものですが、Lisp内部に現れる系統的なコメントであり、 Emacsのヘルプ機能が使用します。 documentation-stringの参照方法については、See Documentation。
読者のプログラムの関数すべてに、 たとえ内部的に使用されるものであっても説明文字列を与えることはよいことです。 説明文字列はコメントに似ていますが、参照するのはもっと簡単です。
説明文字列の先頭行は、その1行で完結しているべきです。
というのは、apropos
は先頭行だけを表示するからです。
関数の機能をまとめた1つか2つの文にしましょう。
説明文字列の先頭は、ソースファイル上では普通字下げしてあるでしょうが、 それらの空白は文字列を始めるダブルクォートのまえにありますから、 それらは文字列の一部ではありません。 説明文字列の残りの行を字下げして、 プログラムソース上でテキスト行が揃うようにする人もいます。 しかし、それはまちがいです。 後続の行の字下げは文字列の内側にあります。 ソースファイルで綺麗に見えても、 ヘルプコマンドの表示では不恰好になります。
関数の必須の構成要素(本体)があとに続くのに、 説明文字列を省略できるのを不思議に思うかもしれません。 文字列を評価すると、副作用なしに、その文字列を返すので、 それが本体の最後のフォームでなければ、なんの効果もありません。 したがって、実用上、本体の最初のフォームと 説明文字列を混同することはありません。 本体のフォームが文字列だけであると、 それは戻り値でもあり説明文字列でもあります。
ほとんどの計算機言語では、各関数には名前があります。
名前のない関数という考えは本質的ではありません。
Lispでは、もっとも厳密にいえば、関数には名前はありません。
関数は、先頭要素が単にlambda
であるリスト、
バイトコード関数オブジェクト、あるいは、基本関数のsubrオブジェクトです。
しかしながら、シンボルは関数の名前として働きます。 シンボルの関数セル(function cell、see Symbol Components)に 関数を入れると、このようになります。 そうすると、シンボルそのものは正当な呼び出し可能な関数となり、 関数セルが参照するリストやsubrオブジェクトと等価になります。 関数セルの内容をシンボルの関数定義(function definition)とも呼びます。 シンボルのかわりにシンボルの関数定義を使う処理を シンボルの関数間接(symbol function indirection)と呼びます。 See Function Indirection。
実用上、ほとんどすべての関数には、このようにして名前が付いていて、
その名前で参照します。
たとえば、シンボルcar
は、
その関数セルに基本関数のsubrオブジェクト#<subr car>
が格納してあるので、
その動作を行う関数として動作します。
関数に名前を与えるのは、Lisp式からその名前で参照できると便利だからです。
#<subr car>
のような基本関数のsubrオブジェクトでは、
名前はそれらを参照する唯一の方法です。
そのようなオブジェクトには入力構文はありません。
Lispで書いた関数では、明示的なラムダ式より名前を使うほうがより便利です。
また、関数に名前があればそれを参照できます。
つまり、再帰呼び出しができます。
関数の名前をその定義そのものに書くことは、
関数定義がそれ自身を指すようにする
(これは不可能ではないにしても、実用上はさまざまな欠点がある)よりは、
とても便利です。
関数を指名するシンボルで関数をしばしば識別します。
たとえば、しばしば『関数car
』といって、
シンボルcar
と関数定義である基本関数のsubrオブジェクトとを区別しません。
ほとんどの目的には、区別する必要はありません。
たとえそうであっても、関数に一意な名前は必要ないことを
心に留めておいてください。
関数オブジェクトは普通1つのシンボルの関数セルだけに現れますが、
これは単なる便法です。
fset
を使って、複数のシンボルに格納するのは簡単です。
そうすると、各シンボルは同じ関数を同等に指名します。
関数名として使うシンボルは、変数としても使えます。 シンボルのこれら2つの使い方は独立していて衝突しません。 (SchemeなどのLispの方言のなかには、 シンボルの値とその関数定義を区別しないものもある。 変数としてのシンボルの値は、その関数定義でもある。) シンボルに関数定義を与えていないと、そのシンボルを関数としては使えません。 これは、シンボルに変数としての値があるかどうかには関係しません。
関数を作成するときには、普通、関数に名前を与えます。
これを関数を定義すると呼び、
スペシャルフォームdefun
で行います。
defun name argument-list body-forms | Special Form |
defun は、新たにLisp関数を定義する普通の方法である。
これは、シンボルnameをつぎのような関数として定義する。
(lambda argument-list . body-forms)
前述(see Lambda Expressions)のように、
argument-listは引数名のリストであり、
キーワード 同一のシンボルnameを変数として使っていても衝突はない。 というのは、シンボルの値セルは関数セルとは独立だからである。 see Symbol Components。 例を示そう。 (defun foo () 5) => foo (foo) => 5 (defun bar (a &optional b &rest c) (list a b c)) => bar (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 a word." (interactive) (backward-word 1) (forward-word 1) (backward-char 1) (capitalize-word 1)) => capitalize-backwards 既存の関数を意図せずに再定義しないように注意すること。
|
defalias name definition | Function |
このスペシャルフォームは、
シンボルnameを定義definition(任意の正しいLisp関数)とする
関数として定義する。
一方、他の目的で関数定義を操作するプログラムでは、
そのような記録を保持しない |
defun
のように関数を定義し、かつ、
Lispコンパイラに関数定義を展開するように指示する
defsubst
も参照してください。
See Inline Functions。
関数を定義することは、全体の半分でしかありません。 関数を呼ぶまでは、つまり、実行を命じなければ、関数はなにもしません。 関数呼び出しは起動(invocation)ともいいます。
関数を起動するもっとも一般的な方法は、リストを評価することです。
たとえば、リスト(concat "a" "b")
を評価すると、
関数concat
を引数"a"
と"b"
で呼び出します。
評価についてはSee Evaluation。
読者のプログラムで式としてリストを書くときには、
呼び出す関数名を読者のプログラムに書きます。
つまり、プログラムを書くときに、
どの関数をどれだけの引数で呼び出すかを指定できることを意味します。
これが、普通にしたいことでしょう。
呼び出す関数を実行時に計算する必要がある場合もあるでしょう。
それには、関数funcall
を使います。
渡す引数の個数を実行時に決定する必要があるときには、
apply
を使います。
funcall function &rest arguments | Function |
funcall は、functionをargumentsで呼び出し、
functionがなにを返そうともそれを返す。
引数functionは、Lisp関数か基本関数である必要がある。
スペシャルフォームやマクロは許されない。
それらには、『未評価』の引数式を与えたときだけ意味があるからである。
(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 &rest arguments | Function |
apply は、funcall のように、
functionをargumentsで呼び出すが、1点だけ異なる。
argumentsの最後はオブジェクトのリストであり、
functionにはこれを、単一のリストではなく、個々の引数として渡す。
これを、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)
|
Lisp関数にとっては、引数として関数を受け取ったり、
データ構造(特に、フック変数や属性リスト)内の関数を探して
funcall
やapply
を使ってそれを呼び出すことは一般的です。
関数引数を受け付ける関数を
しばしばファンクショナル(functionals)と呼びます。
場合によっては、ファンクショナルを呼び出すときには、 引数としてなにもしない関数(no-op)を指定できると有用です。 つぎのものは、2種類のなにもしない関数です。
identity arg | Function |
この関数はargを返し、副作用を持たない。 |
ignore &rest args | Function |
この関数は引数を無視し、nil を返す。
|
マップ関数(mapping function)は、
リストや他の集まりの各要素に指定した関数を適用します。
Emacs Lispにはそのような関数がいくつかあります。
mapcar
とmapconcat
はリストを走査するもので、ここで説明します。
オブジェクト配列obarray内のシンボルについて
マップする関数mapatoms
については、
See Creating Symbols。
これらのマップ関数では、文字テーブルは扱えません。
というのは、文字テーブルは疎な配列であり、その添字範囲も非常に大きいからです。
文字テーブルの疎な性質を考慮して文字テーブルについてマップするには、
関数map-char-table
(see Char-Tables)を使います。
mapcar function sequence | Function |
mapcar は、sequenceの各要素に順にfunctionを適用し、
結果のリストを返す。
引数sequenceは文字テーブル以外の任意の種類のシーケンスでよい。 つまり、リスト、ベクトル、ブールベクトル、あるいは、文字列である。 結果はつねにリストである。 結果の長さはsequenceの長さと同じである。
|
mapconcat function sequence separator | Function |
mapconcat は、sequenceの各要素にfunctionを適用する。
それらの結果は、文字列である必要があり、連結される。
mapconcat は、結果の文字列のあいだに文字列separatorを挿入する。
普通、separatorは、空白やコンマ、その他の句読点を含む。
引数functionは、引数を1つ取る関数であり、 文字列を返す必要がある。 引数sequenceは、文字テーブル以外の任意の種類のシーケンスでよい。 つまり、リスト、ベクトル、ブールベクトル、あるいは、文字列である。 (mapconcat 'symbol-name '(The cat in the hat) " ") => "The cat in the hat" (mapconcat (function (lambda (x) (format "%c" (1+ x)))) "HAL-8000" "") => "IBM.9111" |
Lispでは、関数とは、lambda
で始まるリスト、
そのようなリストをコンパイルしたバイトコード関数、
あるいは、基本関数のsubrオブジェクトです。
名前は『余分』なのです。
普通の関数はdefun
で定義し、そのとき名前を与えますが、
明示的なラムダ式、つまり、無名関数を使ったほうがより簡素な場合もあります。
そのようなリストは、関数名を使える場面ならば、どこでも使えます。
そのようなリストをどんな方法で作っても、正しい関数となります。 つぎのようにしてもかまわないのです。
(setq silly (append '(lambda (x)) (list (list '+ (* 3 4) 'x)))) => (lambda (x) (+ 12 x))
これは、(lambda (x) (+ 12 x))
のようなリストを計算し、
その値をsilly
の値(関数定義ではない!)とします。
この関数はつぎのように呼び出せます。
(funcall silly 1) => 13
((silly 1)
と書いても動作しない。
なぜなら、この関数は、silly
の関数定義ではないからである。
silly
には関数定義を与えてなく、
変数としての値を与えただけである。)
ほとんどの場合、無名関数は読者のプログラムに現れる定数です。
たとえば、関数mapcar
の引数の1つに渡したいときなどです。
mapcar
は、リストの各要素に指定した関数を適用します。
第3引数に関数を取る関数change-property
を定義します。
(defun change-property (symbol prop function) (let ((value (get symbol prop))) (put symbol prop (funcall function value))))
ここで、数を2倍する関数を渡してchange-property
を使う
関数を定義します。
(defun double-property (symbol prop) (change-property symbol prop '(lambda (x) (* 2 x))))
このような場合、つぎのように、無名関数をクォートするには、
単純なクォートのかわりにスペシャルフォームfunction
を使います。
(defun double-property (symbol prop) (change-property symbol prop (function (lambda (x) (* 2 x)))))
quote
のかわりにfunction
を使った場合に違いがでるのは、
関数double-property
をコンパイルしたときです。
たとえば、double-property
の2番目の定義をコンパイルすると、
無名関数もコンパイルされます。
一方、普通のquote
を使った最初の定義をコンパイルすると、
change-property
へ渡す引数は、書いたとおりのリストです。
(lambda (x) (* x 2))
Lispコンパイラは、このリストが関数に見えたとしても、
このリストを関数とはみなしません。
というのは、コンパイラにはchange-property
がリストになにを行うか
わからないからです。
たぶん、第3要素のCARがシンボル*
か
どうか調べればよいのでしょう!
function
を使うと、コンパイラに対して先へ進んで
定数の関数をコンパイルしても安全であることを伝えます。
関数名をクォートするときにquote
のかわりにfunction
を
書くこともありますが、この用法はコメントのようなものです。
(function symbol) == (quote symbol) == 'symbol
入力構文#'
は、function
の省略形です。
たとえば、
#'(lambda (x) (* x x))
は、つぎと等価です。
(function (lambda (x) (* x x)))
function function-object | Special Form |
このスペシャルフォームは、function-objectを評価せずに
function-objectを返す。
この意味ではquote に等価である。
しかし、これは、Emacs Lispコンパイラに対しては注意書きとして働き、
function-objectを関数としてのみ使う意図があり、
したがって、コンパイルしても安全であることを意味する。
Quotingのquote と比較してほしい。
|
function
と無名関数を用いた実際的な例は、
Accessing Documentationのdocumentation
を参照してください。
シンボルの関数定義(function definition)とは、
シンボルの関数セルに格納されたオブジェクトです。
ここで説明する関数は、シンボルの関数セルを参照したり、調べたり、
設定したりします。
Function Indirectionの関数indirect-function
も参照してください。
symbol-function symbol | Function |
これは、symbolの関数セルのオブジェクトを返す。
シンボルの関数セルが空であると、エラーvoid-function を通知する。
この関数は、返すオブジェクトが正しい関数であるかどうか検査しない。 (defun bar (n) (+ n 2)) => bar (symbol-function 'bar) => (lambda (n) (+ n 2)) (fset 'baz 'bar) => bar (symbol-function 'baz) => bar |
シンボルに一度も関数定義を与えていないと、
そのシンボルの関数セルは空(void)であるといいます。
いいかえれば、関数セルにはどんなLispオブジェクトも入っていません。
そのようなシンボルを関数として呼び出そうとすると、
エラーvoid-function
を通知します。
空(void)は、nil
やシンボルvoid
と違うことに注意してください。
シンボルnil
もvoid
もLispオブジェクトであり、
それらは他のオブジェクトと同様に関数セルに格納できます
(そして、それらをdefun
で定義しておけば、正しい関数である)。
空の関数セルには、どんなオブジェクトも含まれていません。
シンボルの関数定義が空かどうかはfboundp
で調べることができます。
シンボルに関数定義を与えたあとでも、
fmakunbound
を使ってふたたび空にできます。
fboundp symbol | Function |
この関数は、シンボルの関数セルにオブジェクトが入っていればt を返し、
さもなければnil を返す。
オブジェクトが正しい関数であるかどうか検査しない。
|
fmakunbound symbol | Function |
この関数はsymbolの関数セルを空にする。
これ以降にこのセルを参照しようとすると、
エラーvoid-function を引き起こす。
(Void Variablesのmakunbound も参照)。
(defun foo (x) x) => foo (foo 1) =>1 (fmakunbound 'foo) => foo (foo 1) error--> Symbol's function definition is void: foo |
fset symbol definition | Function |
この関数は、symbolの関数セルにdefinitionを格納する。
結果はdefinitionである。
通常、definitionは関数か関数名であるべきだが、
そうであるかどうか検査しない。
引数symbolは通常どおり評価される引数である。
この関数の普通の3つの使い方はつぎのとおり。
これらの使用例を示す。 ;; |
既存の関数定義を拡張する関数を書くときには、 つぎのような常套句を使うこともあります。
(fset 'old-foo (symbol-function 'foo)) (defun foo () "Just like old-foo, except more so." (old-foo) (more-so))
foo
が自動ロードと定義されていると、これは正しく動作しません。
そのような場合には、foo
がold-foo
を呼び出すと、
Lispはファイルをロードしてold-foo
を定義しようとします。
しかし、これはold-foo
ではなくfoo
を定義するので、
正しい結果を得られません。
この問題を回避する唯一の方法は、
foo
の古い定義を移すまえに、確実にファイルをロードしておくことです。
しかし、別の箇所で定義された関数を再定義するLispファイルに対しては、 いずれにしても、これではモジュール化も見通しもよくありません。 アドバイズ機能(see Advising Functions)を使えば、見通しがよくなります。
defun
のかわりにdefsubst
を使うことで、
インライン関数(inline function)を定義できます。
インライン関数は、1つの点を除いて、普通の関数と同様に動作します。
そのような関数の呼び出しをコンパイルすると、
関数定義は呼び出し側で展開されます。
関数を展開すると明示的な呼び出しが高速になります。 しかし、それには欠点もあります。 その1つは、柔軟性を減らすことです。 関数の定義を変更しても、コンパイルし直すまでは、 すでに展開された呼び出しは古い定義を使い続けます。 関数を再定義できる柔軟性はEmacsでは重要な機能ですから、 速度が本当に重要でなければ、関数を展開すべきではありません。
別の欠点は、大きな関数を展開すると、コンパイルした関数のサイズが ファイル内でもメモリ上でも増加します。 インライン関数のスピードの利点は、小さな関数でもっとも大きいので、 一般には大きな関数を展開すべきではありません。
インライン関数が実行するのと同じコードに展開するようにマクロを定義する
ことも可能です。
(see Macros。)
しかし、マクロは式で直接使った場合に制限されます。
マクロは、apply
やmapcar
などで呼び出せません。
さらに、普通の関数をマクロに変換するには、多少の作業が必要です。
普通の関数をインライン関数に変換するのはとても簡単です。
単に、defun
をdefsubst
で置き換えるだけです。
インライン関数の各引数は、ちょうど1回だけ評価されるので、
マクロのように本体で引数を何回使うかを考慮する必要はありません。
(see Argument Evaluation。)
インライン関数は、マクロと同様に、 同じファイル内の定義位置よりうしろで使われ展開されます。
関数呼び出しと関数定義に関連したいくつかの関数の一覧をあげておきます。 これらは別の場所で説明してありますが、相互参照をあげておきます。
apply
autoload
call-interactively
commandp
documentation
eval
funcall
function
ignore
indirect-function
interactive
interactive-p
mapatoms
mapcar
map-char-table
mapconcat
undefined
マクロ(macros)により、 新たな制御構造の構文を定義したり、他の言語の機能を定義したりできます。 マクロは関数のように定義しますが、値の計算方法を指示するかわりに、 値を計算するための別のLisp式の計算方法を指示します。 この式をマクロの展開形(expansion)と呼びます。
マクロでこのようなことができるのは、 関数が評価済みの引数を操作するのに対して、 マクロは引数の未評価の式を操作するからです。 そのため、これらの引数の式やその一部を含む展開形を構築できるのです。
実行速度のために普通の関数でできることにマクロを使うのであれば、 そのかわりにインライン関数を使うことを考えてください。
C言語の演算子++
のように、
変数の値を増加させるLispの構文を定義したいとしましょう。
(inc x)
のように書いて、
(setq x (1+ x))
のような効果を得たいのです。
これを行うマクロ定義はつぎのようになります。
(defmacro inc (var) (list 'setq var (list '1+ var)))
これを(inc x)
のように呼び出すと、
引数varはシンボルx
になります。
関数のようにx
の値ではありません。
マクロの本体では、これを使って展開形(setq x (1+ x))
を構築します。
マクロ定義がこの展開形を返すと、
Lispはそれを評価することに進み、x
を増やします。
マクロ呼び出しはマクロ名で始まるリストであり、 関数呼び出しとほとんど同じに見えます。 リストの残りの要素はマクロの引数です。
マクロ呼び出しの評価は、関数呼び出しの評価のように始められますが、 1つだけ重要な違いがあります。 マクロの引数は、マクロ呼び出しに現れた実際の引数です。 マクロ定義に渡すまえに、それらを評価しません。 一方、関数の引数は、関数呼び出しのリストの要素を評価した結果です。
引数を得ると、Lispは関数定義を起動するのと同様にマクロ定義を起動します。
マクロの引数変数は、マクロ呼び出しの引数値や
&rest
引数の場合にはそれらのリストに束縛されます。
そうして、マクロ本体を実行し、関数本体と同様に値を返します。
マクロと関数の重要な違いの2つめは、 マクロ本体が返した値はマクロ呼び出しの値ではないことです。 戻り値は値を計算するためのかわりの式であり、 これをマクロの展開形(expansion)といいます。 Lispインタープリタは、マクロから戻ってくると、 ただちに展開形を評価することへ進みます。
展開形は、通常どおりに評価されるので、 展開形から他のマクロを呼び出してもかまいません。 同一のマクロを呼び出してもかまいませんが、 それは一般的ではありません。
macroexpand
を呼ぶと、指定したマクロの展開形を調べることができます。
macroexpand form &optional environment | Function |
この関数は、formがマクロ呼び出しならば、それを展開する。
その結果がまた別のマクロ呼び出しであれば、さらに展開する。
マクロ呼び出しでない結果を得るまでこれを繰り返す。
それが、macroexpand が返す値である。
formが始めからマクロ呼び出しでなければ、
与えられたとおりのものを返す。
関数 environmentを指定すると、 それは、現在定義済みのマクロを隠すマクロ定義の連想リストを表す。 バイトコンパイルではこの機能を使う。 (defmacro inc (var)
(list 'setq var (list '1+ var)))
=> inc
(macroexpand '(inc r))
=> (setq r (1+ r))
(defmacro inc2 (var1 var2)
(list 'progn (list 'inc var1) (list 'inc var2)))
=> inc2
(macroexpand '(inc2 r s))
=> (progn (inc r) (inc s)) ; ここでは
|
なぜ、マクロの展開形をわざわざ計算してから展開形を評価するのか、
疑問に思うかもしれません。
なぜ、マクロ本体で望みの結果を直接出さないのでしょう?
その理由には、コンパイルが関係しています。
コンパイルするLispプログラムにマクロ呼び出しが現れると、 Lispコンパイラは、インタープリタがするのと同様にマクロ定義を呼び出し、 その展開形を受け取ります。 この展開形を評価するかわりに、コンパイラは、 展開形がプログラムに直接現れたかのようにそれをコンパイルします。 その結果、コンパイル済みのコードは、マクロが意図した値と副作用を生じ、 かつ、実行速度はコンパイルした速度になるのです。 マクロ本体そのもので値と副作用を計算したのでは、 このように動作しません。 コンパイル時に計算してしまい、それでは意味がありません。
マクロ呼び出しが正しくコンパイルされるためには、
それらの呼び出しをコンパイルするときに、
Lisp内でマクロが定義済みである必要があります。
コンパイラには、読者がこのようにすることを補佐する機能があります。
コンパイル対象のファイルにフォームdefmacro
が含まれていると、
そのファイルの残りをコンパイルするあいだは、
一時的にマクロを定義します。
この機能が動作するためには、
defmacro
を同じファイルの最初に利用する箇所よりまえに
入れておく必要があります。
ファイルをバイトコンパイルすると、
そのファイルのトップレベルにあるrequire
の呼び出しを実行します。
これは、ファイルを正しくコンパイルするために必要なパッケージを表します。
コンパイル中に必要なマクロ定義が使えることを保証する1つの方法は、
それらのマクロを定義するファイルを
require
に指定しておくことです(see Named Features)。
コンパイル済みのプログラムを実行するときに、
マクロを定義したファイルをロードしてしまうことを避けるには、
require
の呼び出しの周りにeval-when-compile
を書いておきます
(see Eval During Compile)。
Lispのマクロは、そのCARがmacro
であるリストです。
そのCDRは関数であるべきです。
マクロの展開は、マクロ呼び出しの未評価の引数式に
(apply
で)関数を適用して動作します。
無名関数のように無名Lispマクロを使うことも可能ですが、
けっしてしないでしょう。
mapcar
のようなファンクショナルに無名マクロを渡す意味がないからです。
実用上は、すべてのLispマクロには名前があり、
普通、スペシャルフォームdefmacro
で定義します。
defmacro name argument-list body-forms... | Special Form |
defmacro は、シンボルnameをつぎのようなマクロとして定義する。
(macro lambda argument-list . body-forms) (このリストのCDRは関数、つまり、ラムダ式であることに注意。)
このマクロオブジェクトは、nameの関数セルに格納される。
フォーム argument-listの形式と意味は、関数のそれと同じであり、
キーワード |
マクロでは、定数部分と非定数部分を組み合わせた大きなリスト構造を
構築する必要がしばしばあります。
これを簡単に行うためには、
(通常、バッククォート(backquote)と呼ばれる)`
構文を
使います。
バッククォートにより、リストの要素を選択に評価しつつ、
リストをクォートできます。
もっとも単純な場合、これはスペシャルフォームquote
(see Quoting)と
等価です。
たとえば、つぎの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)
バッククォートの引数の内側にある特別な印,
は、
値が定数ではないことを表します。
バッククォートは、リスト構造の中の,
の引数を評価し、
値で置き換えます。
(list 'a 'list 'of (+ 2 3) 'elements) => (a list of 5 elements) `(a list of ,(+ 2 3) elements) => (a list of 5 elements)
,
による置き換えは、リスト構造の深いレベルでも許されます。
たとえば、つぎのとおりです。
(defmacro t-becomes-nil (variable) `(if (eq ,variable t) (setq ,variable nil))) (t-becomes-nil foo) == (if (eq foo t) (setq foo nil))
特別な印,@
を使って、
評価結果を結果となるリストに繋ぎ合わせる(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)
19.29版よりまえのEmacsの旧版では、
`
の構文は異なっていて、
バッククォート構文全体を囲む括弧の余分なレベルが必要でした。
同様に、,
や,@
の置換でも、
,
や,@
、および後続の式を囲む括弧の余分なレベルが1つ必要でした。
古い構文では、`
、 ,
、,@
と後続の式とのあいだには
空白が必要でした。
この構文も受け付けますが、これはEmacsの旧版との互換性のためであり、 新しいプログラムでは使わないことを勧めます。
マクロ展開に関する基本的事実には、直観的でない結果があります。 本節では、問題を引き起こしかねない重要な結果を説明し、 問題を回避するための規則を説明します。
マクロを定義するときには、展開形を実行するときに、 引数が何回評価かされるかに注意を払う必要があります。 つぎの(繰り返しを行う)マクロで、この問題を示しましょう。 このマクロで、Pascalにあるような単純な『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))." (list 'let (list (list var init)) (cons 'while (cons (list '<= var final) (append body (list (list 'inc var))))))) => for (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 "%d %d" i square)) (inc i))) -|1 1 -|2 4 -|3 9 => nil
このマクロの引数、from
、to
、do
は、
『シンタックスシュガー』であり、完全に無視します。
(from
、to
、do
などの)余分な単語を
マクロ呼び出しのこの引数位置に書けるようにするのです。
バッククォートを使って単純化した等価な定義をつぎに示します。
(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回だけ評価するような展開形を生成して、 上のような問題を回避するように手立てします。
(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))))
残念なことに、この修正は、 次節に説明する別の問題を引き起こします。
for
の新しい定義には、新たな問題があります。
ユーザーが予期していないローカル変数max
を導入しているのです。
これは、つぎのような場合、問題を引き起こします。
(let ((max 0)) (for x from 0 to 10 do (let ((this (frob x))) (if (< max this) (setq max this)))))
for
の本体内でのmax
の参照は、
ユーザーが束縛したmax
を参照するものと期待されていますが、
実際にはfor
が作った束縛を使います。
これを修正するには、max
のかわりに、
インターンしてないシンボル(see Creating Symbols)を使います。
インターンしてないシンボルは、他のシンボルと同様に、
束縛したり参照したりできますが、for
で作ったので、
ユーザープログラムには現れていないことがわかっています。
インターンしてないので、ユーザーがプログラムのあとの部分で
参照する方法もありません。
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)))))
これは、max
という名前のインターンしてないシンボルを作成し、
もとの式に現れていたインターンしたシンボルmax
のかわりに
展開形内部で使います。
eval
(see Eval)を呼び出すなどして、
マクロ定義そのものの中でマクロ引数の式を評価すると、
別の問題を生じます。
引数でユーザーの変数を参照する場合、
ユーザーがマクロ引数の1つと同じ名前を使っていると、
問題になります。
マクロ本体の内側では、マクロ引数の束縛が最ローカルな束縛ですから、
そのフォームの内側からの参照は、この束縛を使います。
例を示しましょう。
(defmacro foo (a) (list 'setq (eval a) t)) => foo (setq x 'b) (foo x) ==> (setq b t) => t ;b
を設定する ;; しかし (setq a 'c) (foo a) ==> (setq a t) => t ;c
ではなくa
を設定する
ユーザーの引数の名前がa
かx
かで違いがでます。
というのは、マクロ引数の変数a
とa
が衝突するからです。
マクロ定義内でeval
を呼び出したときの別の問題点は、
コンパイルしたプログラムでは、意図した動作をしないだろうということです。
バイトコンパイラは、プログラムをコンパイル中にマクロ定義を実行しますから、
(eval
で参照したい)プログラムそのものの計算は行われず、
そのローカル変数の束縛も存在しません。
これらの問題を回避するには、 マクロ展開の計算過程では、引数の式を評価しないことです。 そのかわりに、マクロ展開では式の置換を使って、 展開時にその値が計算されるようにします。 このようにすれば、本章の他の例題は動作します。
関数を解釈実行しているときには、マクロ呼び出しを評価するたびに展開しますが、 コンパイルした関数では、(コンパイル時に)1回だけ展開します。 この違いが問題になることもあります。 マクロ定義に副作用があると、 マクロを何回展開したかに依存して動作が異なります。
したがって、マクロ展開の計算では、 本当になにをしているのか理解していない限り、副作用は避けてください。
特別な種類の副作用の1つ、つまり、 Lispオブジェクトを構築することは回避できません。 ほとんどすべてのマクロ展開では、リストを構築し、 それがマクロの重要な点でもあります。 これは、通常、安全ですが、 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)
が作られます。
したがって、2つの呼び出しのあいだで副作用が残ることはありません。
initialize
をコンパイルしてあると、
マクロempty-object
はコンパイル時に展開され、
1つの『定数』(nil)
を作りますが、
これは、initialize
を呼び出すたびに、
再利用され変更されてしまいます。
このような病的な場面を回避する1つの方法は、
empty-object
を、メモリ割り付けではなく、
ある種の定数と考えることです。
'(nil)
のような定数にsetcar
は使わないでしょうから、
(empty-object)
も自然にそのように使わないでしょう。
本章では、カスタマイズのためのユーザーオプションの宣言方法、 および、それらを分類するカスタマイズグループの宣言方法を説明します。 フェイスの定義(see Defining Faces)に加えて、 カスタマイズの両方の種類を含めて、 カスタマイズ項目(customization item)という用語を使います。
(変数やグループ、フェイスの)すべての種類のカスタマイズ宣言では、 さまざまな情報を指定するためのキーワード引数を受け付けます。 本節では、全種類に適用できるキーワードを説明します。
:tag
を除くこれらのキーワードすべては、各項目で複数回使えます。
キーワードのそれぞれの使用には、独立の効果があります。
キーワード:tag
は例外です。
任意の項目には名前を1つしか表示できないからです。
:tag name
:group group
defgroup
の中で:group
を使うと、
新たなグループをgroupの下位グループにする。
このキーワードを複数回使うと、
1つの項目を複数のグループに入れることができる。
それらのグループのどれを表示しても、この項目が表示される。
これを多用しすぎないように注意すること!
:link link-data
link-dataとして使えるものは3種類ある。
(custom-manual info-node)
"(emacs)Top"
のようなノード名を指定する文字列。
リンクは、カスタマイズバッファでは[manual]
のように表示される。
(info-link info-node)
custom-manual
と同様であるが、
カスタマイズバッファに現れるリンクはinfoのノード名になる。
(url-link url)
link-dataの先頭要素のうしろに:tag name
を使うことで、
カスタマイズバッファに使うテキストを指定できる。
たとえば、(info-link :tag "foo" "(emacs)Top")
とすると、
バッファではfoo
と表示されるEmacsマニュアルへのリンクを作れる。
1つの項目に複数個の外部リンクがあってもよいが、
ほとんどの項目には外部リンクはない。
:load file
load-library
でロードする。
:require feature
require
を呼び出す。
:require
を使うもっとも一般的な理由は、
変数がマイナモードなどの機能をオンにするとき、
そのモードを実装するコードをロードしてないと、
変数にはなんの効果もないからである。
Emacs Lispの各パッケージには、 そのパッケージのすべてのオプション、フェイス、他のグループを含んだ 1つの主要なカスタマイズグループがあるべきです。 パッケージに少数のオプションやフェイスしかなければ、 それらを1つのグループにまとめます。 12個を超えるオプションやフェイスがある場合には、 それらを下位グループに構造化して、 下位グループすべてをパッケージの主カスタマイズグループに入れておきます。 パッケージの主グループに下位グループとともにいくつかのオプションやフェイスを 入れておくのもよいでしょう。
パッケージの主グループや単一のグループは、
標準カスタマイズグループの1つかそれ以上のメンバであるべきです。
(それらの完全な一覧を表示するにはM-x customizeを使う。)
それらの中から1個か数個を選び(多すぎないこと)、
キーワード:group
を使って、それぞれに読者のグループを追加します。
新たなカスタマイズグループは、defgroup
で宣言します。
defgroup group members doc [keyword value]... | Macro |
membersを含むカスタマイズグループとしてgroupを宣言する。
シンボルgroupをクォートしないこと。
引数docは、グループの説明文字列を指定する。
引数membersは、グループのメンバとなる
カスタマイズ項目の初期集合を指定するリストである。
しかし、ほとんどの場合、membersは membersでグループのメンバを指定する場合には、
各要素は 共通のキーワード(see Common Keywords)に加えて、
|
接頭辞を取りさる機能は、現在、オフにしてあります。
つまり、:prefix
は、現在、なんの効果もありません。
このようにしたのは、指定した接頭辞を取りさると、
オプション名がしばしば混乱するからです。
さまざまなグループのdefgroup
定義を書く人は、
論理的と考えられるとき、つまり、ライブラリに共通の接頭辞があるときには
キーワード:prefix
を追加するので、このようになるのです。
:prefix
を使ってよい結果を得るには、
グループ内の特定の項目とそれらの名前と説明文字列に関して、
特定の接頭辞を取りさった場合の効果を調べる必要があります。
その結果、テキストがわかり難ければ、
その場面では、:prefix
を使うべきではないのでしょう。
カスタマイズグループすべてを調べ直して、
わかり難くなる結果をもたらす:prefix
指定を削除し、
この機能をオンにすることは、誰かが頑張れば、可能です。
defcustom
を使って、ユーザーが編集可能な変数を宣言します。
defcustom option default doc [keyword value]... | Macro |
カスタマイズ可能なユーザーオプション変数としてoptionを宣言する。
optionをクォートしないこと。
引数docは変数の説明文字列を指定する。
optionが空であると、 |
defcustom
では、つぎの追加キーワードも使えます。
:type type
:options list
これは、現時点では、型がhook
のときだけ意味を持つ。
その場合、listの要素は、フックの値の要素として使える関数であること。
ユーザーはこれらの関数以外も使えるが、便利な選択肢として提示する。
:version version
(defcustom foo-max 34 "*Maximum number of foo's allowed." :type 'integer :group 'foo :version "20.3")
:set setfunction
set-default
。
:get getfunction
default-value
。
:initialize function
defcustom
を評価したときに変数の初期化に使う関数。
この関数は、2つの引数、つまり、シンボルと値を取ること。
このように使うことを意図した定義済みの関数がいくつかある。
custom-initialize-set
:set
関数を使って変数を初期化するが、
変数の値が空でないときには再初期化しない。
これは:initialize
のデフォルト。
custom-initialize-default
custom-initialize-set
に似ているが、
変数の:set
関数のかわりに関数set-default
を使って変数を設定する。
変数の:set
関数がマイナモードをオン/オフする場合には、
普通はこれを選ぶ。
これを選ぶと、変数を定義してもマイナモード関数を呼び出さないが、
変数をカスタマイズするとマイナモード関数を呼び出す。
custom-initialize-reset
:set
関数を使う。
変数の値が空でない場合には、(:get
で得られる)現在値で
:set
関数を呼び出して、変数をリセットする。
custom-initialize-changed
:set
関数を使う。
さもなければ、set-default
を使う。
:require
オプションは、
特定の機能をオンにするようなオプションには便利です。
パッケージがオプション変数の値を検査するように書かれていたとしても、
パッケージをロードするようにする必要があります。
これを:require
で行えるのです。
See Common Keywords。
ライブラリparen.el
からとった例をつぎに示します。
(defcustom show-paren-mode nil "Toggle Show Paren mode...." :set (lambda (symbol value) (show-paren-mode (or value 0))) :initialize 'custom-initialize-default :type 'boolean :group 'paren-showing :require 'paren)
内部的には、defcustom
は、
デフォルト値を与える式は属性standard-value
を使って記録し、
ユーザーがカスタマイズバッファで保存した値は
属性saved-value
を使って記録しています。
属性saved-value
は実際にはリストであり、
そのCARが値に評価される式です。
defcustom
でユーザーオプションを定義するときには、
そのカスタマイズ型(customization type)を定義する必要があります。
これはLispオブジェクトであり、
(1)どのような値が正しいものであり、
(2)編集用にカスタマイズバッファに表示する方法、
を示します。
カスタマイズ型は、defcustom
内の:type
キーワードで指定します。
:type
の引数は評価されます。
実行時に型が変わるものはほとんど使い途がないので、
普通、クォートした型を指定します。
たとえば、つぎのとおりです。
(defcustom diff-command "diff" "*The command to use to run diff." :type '(string) :group 'diff)
一般に、カスタマイズ型はリストであり、 その先頭要素はシンボルで、次節以降で定義するカスタマイズ型名の1つです。 このシンボルのあとには、シンボルに依存した数個の引数が続きます。 型シンボルとその引数のあいだには、 キーワード・値の対を書くこともできます (see Type Keywords)。
型シンボルには、引数を取らないものもあります。
これらを単純型(simple types)と呼びます。
単純型では、キーワード・値の対を指定しなければ、
型シンボルを囲む括弧を省略できます。
たとえば、カスタマイズ型としてのstring
は、
(string)
と等価です。
本節では、すべての単純型を説明します。
sexp
sexp
を使うことができる。
integer
number
string
"
で区切ったり、\
でクォートしない。
regexp
string
と同様であるが、
文字列は正規表現である必要がある。
character
file
(file :must-match t)
directory
hook
defcustom
で:options
キーワードを使用できる。
see Variable Definitions。
symbol
function
variable
face
boolean
nil
かt
である必要がある。
choice
とconst
を同時に使うと(次節参照)、
値はnil
かt
である必要があることを指定し、
さらに、どちらの値がどの選択肢に合うかを記述するテキストを
指定できることに注意。
単純型が適切でない場合には、 他の型から新たな型を作り上げる複合型を使えます。 これには、いくつかの方法があります。
(restricted-sexp :match-alternatives criteria)
nil
かnil
以外を返す。
リスト内の述語がオブジェクトに対してnil
以外を返せば
そのオブジェクトを受理することを意味する。
'object
。
リスト内のこの種の要素は、
objectそのものが受理できる値であることを意味する。
たとえば、
(restricted-sexp :match-alternatives (integerp 't 'nil))
は、整数、t
、nil
が正しい値である。
カスタマイズバッファでは、すべての正しい値はその入力構文で表示し、
ユーザーはそれらをテキストとして編集する。
(cons car-type cdr-type)
(cons string symbol)
は、
("foo" . foo)
などの値に一致するカスタマイズ型である。
カスタマイズバッファでは、
CARとCDRは、
それらに指定した型に応じて別々に表示され、個別に編集できる。
(list element-types...)
たとえば、(list integer string function)
は、
3要素のリストを意味し、
第1要素は整数、第2要素は文字列、第3要素は関数であることを指定する。
カスタマイズバッファでは、
各要素は、それらに指定した型に応じて別々に表示され、個別に編集できる。
(vector element-types...)
list
と同様だが、値はリストではなくベクトルである必要がある。
その要素はlist
の場合と同じ。
(choice alternative-types...)
(choice integer string)
は、整数か文字列を許す。
カスタマイズバッファでは、ユーザーはメニューを使って選択肢を選び、 その選択肢において普通の方法で値を編集する。
通常、このメニューの選択肢名は、選択肢から自動的に決定されるが、
選択肢に:tag
キーワードを含めることで、
メニューに異なる名前を指定できる。
たとえば、整数が空白の個数を表し、文字列がそのまま使うテキストを表す場合には、
つぎのようにカスタマイズ型を書く。
(choice (integer :tag "Number of spaces") (string :tag "Literal text"))
そうすると、メニューには、
Number of spaces
とLiteral Text
が表示される。
const
以外のnil
が正当な値ではない選択肢では、
そのような選択肢には:value
キーワードを使って
正当なデフォルト値を指定すること。
See Type Keywords。
(const value)
const
の主な用途はchoice
の内側である。
たとえば、(choice integer (const nil))
は、整数かnil
を許す。
choice
の内側では、const
にしばしば:tag
を使う。
たとえば、
(choice (const :tag "Yes" t) (const :tag "No" nil) (const :tag "Ask" foo))
は、t
は『yes』(はい)、nil
は『no』(いいえ)、
foo
は『ask』(問い合わせる)を意味する変数を記述する。
(other value)
other
は、主に、choice
の最後の要素として使うことである。
たとえば、
(choice (const :tag "Yes" t) (const :tag "No" nil) (other :tag "Ask" foo))
は、t
は『yes』(はい)、nil
は『no』(いいえ)、
それ以外は『ask』(問い合わせる)を意味することを示す。
ユーザーが選択肢のメニューからAsk
を選ぶと、値foo
を指定する。
しかし、(t
でもnil
でもfoo
でもない)それ以外の値は、
foo
と同様にAsk
と表示される。
(function-item function)
const
と同様だが、関数であるような値に使う。
これは、関数名に加えて説明文字列を表示する。
説明文字列は、:doc
に指定したものか、
functionそのものの説明文字列である。
(variable-item variable)
const
と同様だが、変数名であるような値に使う。
これは、変数名に加えて説明文字列を表示する。
説明文字列は、:doc
に指定したものか、
variableそのものの説明文字列である。
(set elements...)
(repeat element-type)
[INS]
や[DEL]
ボタンを伴って、
要素のリストとして表示される。
:inline
機能により、可変個数の要素をリストやベクトルの
途中に繋ぎ合わせることができます。
list
やvector
の要素型に現れる
set
型、choice
型、repeat
型の中に使います。
通常、list
やvector
のおのおのの要素型は、
リストやベクトルのたった1つの要素を記述します。
したがって、要素型がrepeat
であると、
1要素として表示される長さを指定しないリストを指定します。
しかし、要素型に:inline
を使うと、
これに一致する値は、:inline
を含むシーケンスに直接に併合されます。
たとえば、3要素のリストに一致すると、
それがシーケンス全体の3つの要素になります。
これはバッククォート構文の,@
の使い方に似ています。
たとえば、先頭要素がt
であり、
残りがfoo
かbar
の0個以上の繰り返しであるリストを指定するには、
つぎのカスタマイズ型を使います。
(list (const t) (set :inline t foo bar))
これは、(t)
、(t foo)
、(t bar)
、(t foo bar)
などの
値に一致します。
要素型がchoice
であるときには、
choice
そのものには:inline
を使いませんが、
choice
の選択肢(のどれか)に:inline
を使います。
たとえば、ファイル名で始まりシンボルt
か2つの文字列が続くような
リストに一致するようにするには、
つぎのカスタマイズ型を使います。
(list file (choice (const t) (list :inline t string string)))
ユーザーが最初の選択肢を選ぶと、全体としてのリストは2要素になり、
第2要素はt
です。
ユーザーが2番目の選択肢を選ぶと、
全体としてのリストは3要素になり、
第2要素と第3要素は文字列である必要があります。
型名のシンボルのあとに、カスタマイズ型内にキーワード・引数の対を指定できます。 使えるキーワードとその意味を以下に示します。
:value default
choice
の内側の選択肢として現れる型に使う。
これは、カスタマイズバッファのメニューでユーザーがこの選択肢を選ぶと、
使用するデフォルト値をまず指定する。
もちろん、オプションの実際の値がこの選択肢に合えば、 defaultではなく実際の値が表示される。
選択肢の値としてnil
が不正であるときには、
:value
で正当なデフォルトを指定することが本質的である。
:format format-string
%
を使える。
%[button%]
:action
属性は、ユーザーがボタンを起動したらなにを行うかを指定する。
その値は2つの引数、つまり、ボタンが現れるウィジェットとイベント
を取る関数であること。
異なるアクションを有する異なるボタンを指定する方法はない。
%{sample%}
:sample-face
で指定した特別なフェイスでsampleを表示する。
%v
%d
%h
%d
と同様だが、説明文字列が1行を超えるときには、
説明文字列全体を表示するか先頭行だけを表示するかを
制御するアクティブフィールドを追加する。
%t
:tag
キーワードで指定する。
%%
%
をそのまま表示する。
:action action
:button-face face
%[...%]
で表示するボタンテキストに
フェイスface(フェイス名かフェイス名のリスト)を使う。
:button-prefix prefix
:button-suffix suffix
nil
:tag tag
:doc doc
:format
の値を指定し、かつ、
その値の中で%d
や%h
を使う必要がある。
型に対して説明文字列を指定するのは、
:choice
の選択肢や他の複合型の一部の意味について
より多くの情報をユーザーに与えるためである。
:help-echo motion-doc
widget-forward
やwidget-backward
でこの項目に移動すると、
エコー領域に文字列motion-docを表示する。
:match function
nil
以外を返すこと。
Lispコードのファイルをロードするとは、 その内容をLispオブジェクトの形でLisp環境に取り込むことです。 Emacsは、ファイルを探してオープンし、テキストを読み取り、 各フォームを評価し、そしてファイルをクローズします。
ロード関数は、関数eval-current-buffer
がバッファ内の
すべての式を評価するように、ファイル内のすべての式を評価します。
異なる点は、ロード関数は、Emacsバッファ内のテキストではなく
ディスク上のファイル内のテキストを読み取って評価することです。
ロードするファイルには、Lisp式のソースコードかバイトコンパイル済みコードが 入っている必要があります。 ファイルの各フォームをトップレベルのフォーム(top-level form)と 呼びます。 ロード可能なファイル内のフォーム向けの特別な書式はありません。 ファイル内のどんなフォームでも、バッファに直接打ち込んで評価できます。 (もちろん、ほとんどのコードはこのようにして試したはず。) ほとんどの場合、フォームは関数定義や変数定義です。
Lispコードを収めたファイルをしばしばライブラリ(library)と呼びます。 したがって、『rmailライブラリ』は、rmailモード用のコードを収めたファイルです。 同様に、『Lispライブラリディレクトリ』は、 Lispコードを収めたファイルのディレクトリです。
load
function and others.
Emacs Lispには、ロードのためのインターフェイスがいくつかあります。
たとえば、autoload
は、
ファイルで定義された関数向けに場所を確保するオブジェクトを作成します。
自動ロードする関数を呼び出すと、
ファイルの実際の定義を得るためにファイルをロードします(see Autoload)。
require
は、ファイルをすでにロードしていなければロードします
(see Named Features)。
これらの機構はすべて、最終的には、関数load
を呼び出して動作します。
load filename &optional missing-ok nomessage nosuffix must-suffix | Function |
この関数は、Lispコードのファイルを探してオープンし、
その中のフォームすべてを評価してから、ファイルをクローズする。
ファイルを探すために、
省略可能な引数nosuffixが 省略可能な引数must-suffixが filenameが
(コンパイルしていない)ソースファイルをロードするときには、
Emacsがファイルを訪問する場合と同様に、
nomessageが ファイルをロード中に処理できないエラーに出会うと、ロードを終了する。
変数 ファイルを正しくロードできると |
load-file filename | コマンド |
このコマンドはファイルfilenameをロードする。
filenameが相対ファイル名であると、
現在のデフォルトディレクトリを仮定する。
load-path を使わず、接尾辞も付加しない。
ロードするファイル名を正確に指定したい場合にこのコマンドを使う。
|
load-library library | コマンド |
このコマンドは、libraryという名前のライブラリをロードする。
load と等価であるが、引数を対話的に読み取る点が異なる。
|
load-in-progress | Variable |
Emacsがファイルをロード処理中であると、
この変数はnil 以外であり、さもなければnil である。
|
load-read-function | Variable |
この変数は、load やeval-region が、
read のかわりに使う、式を読み取る関数を指定する。
その関数はread と同様に引数を1つとること。
通常、この変数の値は 注意: |
Emacs構築時のload
の使い方についての情報は、
See Building Emacs。
EmacsがLispライブラリをロードするときには、
変数load-path
で指定したディレクトリ群でライブラリを探します。
load-path | User Option |
この変数の値は、load でファイルをロードするときに探索する
ディレクトリのリストである。
各要素は、(ディレクトリ名である)文字列か
(カレント作業ディレクトリを表す)nil である。
|
load-path
の値は、環境変数EMACSLOADPATH
があれば、
それで初期化します。
さもなければ、デフォルト値は、
Emacsを構築したときにemacs/src/paths.h
で指定したものです。
そして、リスト内のディレクトリのサブディレクトリをリストに追加して
拡張します。
EMACSLOADPATH
の構文はPATH
と同じです。
:
(オペレーティングシステムによっては;
)で
ディレクトリ名を区切ります。
デフォルトのカレントディレクトリには.
を使います。
csh
の.login
ファイルで環境変数EMACSLOADPATH
を
指定する例はつぎのとおりです。
setenv EMACSLOADPATH .:/user/bil/emacs:/usr/local/share/emacs/20.3/lisp
sh
を使っている場合はつぎのようにします。
export EMACSLOADPATH EMACSLOADPATH=.:/user/bil/emacs:/usr/local/share/emacs/20.3/lisp
.emacs
ファイルで、
デフォルトのload-path
の先頭に複数のディレクトリを追加するには、
つぎのようなコードを書きます。
(setq load-path (append (list nil "/user/bil/emacs" "/usr/local/lisplib" "~/emacs") load-path))
この例では、Lispコードを、まずカレント作業ディレクトリで探索し、
続いて、/user/bil/emacs
ディレクトリ、
/usr/local/lisplib
ディレクトリ、~/emacs
ディレクトリ、
さらに、標準のディレクトリで探索します。
Emacsのダンプには、load-path
の特別な値を使います。
ダンプ終了時にload-path
の値が未変更(つまり、同じ特別な値)であれば、
ダンプ版Emacsは起動時に、上に述べたように、普通のload-path
の値を
使います。
しかし、ダンプ終了時にload-path
の値が別の値であれば、
ダンプ版Emacsの実行でもその(別の)値を使います。
したがって、site-init.el
やsite-load.el
で
少数のライブラリをロードするために
一時的にload-path
を変更したい場合には、
load
の呼び出しをlet
で囲んで
load-path
をローカルに束縛するべきです。
システムにインストールしたEmacsを実行中は、
load-path
のデフォルト値には、2つの特別なディレクトリ
(とそれらのサブディレクトリ)が含まれます。
"/usr/local/share/emacs/version/site-lisp"
と
"/usr/local/share/emacs/site-lisp"
です。 前者は、Emacsの特定の版向けにローカルにインストールしたパッケージ用です。 後者は、Emacsの任意の版向けにローカルにインストールしたパッケージ用です。
Emacsのある版向けのパッケージが別の版ではトラブルを引き起こす理由は いくつかあります。 Emacsの互換性のない変更のために更新を必要とするパッケージもあります。 予告なしに変更される可能性のある明文化していない Emacsの内部データに依存するものもあります。 Emacsの新しい版では、パッケージの特定の版と一体になっているものもあり、 その版だけで使うべきです。
Emacsは、起動すると、ディレクトリのサブディレクトリを捜し出して、
それらをload-path
に追加します。
直下のサブディレクトリも複数レベル下のサブディレクトリも
load-path
に追加します。
しかし、サブディレクトリすべてを含むわけではありません。
英数字で始まらない名前のサブディレクトリは除外します。
RCS
という名前のサブディレクトリも除外します。
また、.nosearch
という名前のファイルを置いた
サブディレクトリも除外します。
これらの方法を用いれば、site-lisp
ディレクトリ下の
特定のサブディレクトリの探索を防げます。
Emacsを構築したディレクトリでEmacsを起動すると、
つまり、正式にインストールしてない実行形式を起動すると、
load-path
には、普通、2つのディレクトリを追加します。
主構築ディレクトリのサブディレクトリ、lisp
とsite-lisp
です。
(どちらも、絶対ファイル名で表される。)
locate-library library &optional nosuffix path interactive-call | コマンド |
このコマンドは、ライブラリlibraryの正確なファイル名を探す。
load と同様にライブラリを探索する。
引数nosuffixの意味はload と同じであり、
指定した名前libraryに接尾辞.elc や.el を付加しない。
pathが
|
Emacs Lispプログラムが非ASCII文字の文字列定数を含む場合、 Emacs内部では、それらはユニバイト文字列かマルチバイト文字列で表現できます (see Text Representations)。 どちらの表現形式を用いるかは、 どのようにファイルをEmacsに読み込んだかに依存します。 マルチバイト表現へ復号化して読んだ場合には、 Lispプログラムのテキストはマルチバイトテキストになり、 その文字列定数はマルチバイト文字列になります。 (たとえば)Lantin-1文字を含むファイルを復号化せずに読むと、 プログラムテキストはユニバイトテキストになり、 その文字列定数はユニバイト文字列になります。 See Coding Systems。
結果をより予測可能にするために、
オプション--unibyte
を指定して起動した場合であっても、
Lispファイルをロードするときには、
Emacsはつねにマルチバイト表現に復号化します。
つまり、非ASCII文字の文字列定数はマルチバイト文字列に変換します。
唯一の例外は、特定のファイルで無変換を指定した場合だけです。
Emacsをこのように設計したのは、
Emacsの起動方法によらずに、
Lispプログラムが予測可能な結果をもたらすようにするためです。
さらに、こうすることで、ユニバイト動作のEmacsであっても、
マルチバイトテキストを使うことに依存したプログラムが動作します。
もちろん、そのようなプログラムは、
default-enable-multibyte-characters
を検査して適切に表現を変換して、
ユーザーがユニバイトテキストとマルチバイトテキストのどちらを
好んでいるか調べるように設計すべきです。
Emacs Lispのほとんどのプログラムでは、
非ASCII文字列はマルチバイト文字列であるということに
気づかないでしょう。
というのは、それらをユニバイトバッファに挿入すると
自動的にユニバイトに変換するからです。
しかしながら、これで違いがでるならば、
Lispファイルの先頭行のコメントに-*-unibyte: t;-*-
と書くことで、
特定のLispファイルをユニバイトと解釈するように強制できます。
このように指定すると、マルチバイト動作のEmacsであっても、
そのファイルを無条件にユニバイトと解釈します。
自動ロード(autoload)機能により、 関数やマクロを定義しているファイルをロードしていなくても、 関数やマクロをLispに登録できます。 関数を初めて呼び出すと、 適切なファイルを読み込んで実際の定義と関連する他のコードを インストールしてから、すでにロードしてあったかのように実際の定義を実行します。
関数を自動的にロードするように設定する方法は2つあります。
autoload
を呼び出すか、あるいは、
ソース内の実際の定義のまえに特別な『マジック』コメントを書きます。
autoload
は自動ロードを行う低レベルの基本関数です。
任意のLispプログラムでいつでもautoload
を呼び出せます。
マジックコメントは、Emacsで使うパッケージ向けに
関数を自動的にロードするように設定するとても便利な方法です。
これらのコメントそのものはなにもしませんが、
コマンドupdate-file-autoloads
に対する指針として働きます。
このコマンドは、autoload
の呼び出しを作成し、
Emacs構築時にそれらを実行するように設定します。
autoload function filename &optional docstring interactive type | Function |
この関数は、functionという名前の関数(やマクロ)を
filenameから自動的にロードするように定義する。
文字列filenameは、functionの実際の定義を取得するために
ロードするファイルを指定する。
filenameにディレクトリ名や接尾辞 引数docstringは、関数に対する説明文字列である。
通常、これは関数定義そのものの説明文字列と同一であること。
interactiveが 普通の関数と同様に、マクロやキーマップも自動的にロードできる。
functionが実際にはマクロならば、typeには 自動ロードと指定したキーマップは、
プレフィックスキーのバインディングがシンボルfunctionであるときに、
キーを探す過程で自動的にロードする。
キーマップのこれ以外の参照方法では、自動的にロードしない。
特に、変数名がシンボルfunctionと同じであっても、
Lispプログラムで変数の値からキーマップを取得して
functionが自動ロードオブジェクトではない
空でない関数定義を有する場合には、
(autoload filename docstring interactive type) たとえばつぎのとおり。 (symbol-function 'run-prolog) => (autoload "prolog" 169681 t nil) この場合、 |
自動ロード対象のファイルでは、通常、他の定義や
複数の機能を提供したり必要としたりします。
(その内容の評価中のエラーなどで)ファイルを完全にロードできないと、
ロード中に行った関数定義やprovide
の呼び出しをもとに戻します。
そのファイルから自動ロードする任意の関数をつぎに呼び出そうとしたときに、
そのファイルを再度ロードすることを保証するためです。
こうしておかないと、
自動ロードをアボートしたファイルで関数が定義されても、
そのファイルのうしろの部分で定義される
その関数に必要なサブルーティンが必ずしもロードされないために
その関数が動作しない可能性があるからです。
自動ロード対象のファイルで必要なLisp関数やマクロの定義に失敗すると、
"Autoloading failed to define function function-name"
を
伴ったエラーを通知します。
自動ロードを指定するマジックコメントは、
;;;###autoload
だけを書いた行であり、
自動ロード対象のソースファイル上で実際の関数定義の直前に必要です。
コマンドM-x update-file-autoloadsは、
対応するautoload
呼び出しをloaddefs.el
に書き込みます。
Emacs構築時にはloaddefs.el
をロードするので、
autoload
を呼び出します。
M-x update-directory-autoloadsはもっと強力で、
カレントディレクトリのすべてのファイルに対する自動ロード情報を更新します。
同じマジックコメントは、任意の種類のフォームをloaddefs.el
に
コピーできます。
マジックコメントに続くフォームが関数定義でない場合、
そのフォームをそのままコピーします。
構築時にはフォームを実行しても、
ファイルのロード時にはそのフォームを実行しないように
マジックコメントを使うこともできます。
そうするには、マジックコメントと同じ行にそのフォームを書きます。
するとそれはコメントなので、ソースファイルをロードするときにはなにもしません。
一方、M-x update-file-autoloadsはそのフォームをloaddefs.el
に
コピーするので、Emacs構築時には実行されるのです。
つぎの例は、マジックコメントを使って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." t)
ダブルクォートの直後にバックスラッシュや改行を書く慣習は、
loaddefs.el
などの
あらかじめロードするLispファイルの中だけで使うものです。
これは、make-docfile
に対して、
説明文字列をetc/DOC
ファイルに書くように指示します。
See Building Emacs。
1つのEmacsセッションにおいて、あるファイルを複数回ロードできます。 たとえば、バッファ内の関数定義を編集して、 関数定義を書き直してインストールし直したあとで、 もとの版に戻したいこともあるでしょう。 これには、もとのファイルを再ロードすればよいのです。
ファイルをロードしたり再ロードするとき、
関数load
やload-library
は、
コンパイルしていないファイルではなく、
バイトコンパイル済みのファイルを自動的にロードすることに注意してください。
ファイルを書き直して保存してから再インストールする場合、
新しい版をバイトコンパイルする必要があります。
さもないと、Emacsは、新しいコンパイルしていないファイルではなく、
バイトコンパイル済みの古いファイルをロードしてしまいます。
そのような場合、ファイルをロードすると、
(compiled; note, source is newer)
とメッセージを表示して、
再コンパイルするように忠告してきます。
Lispライブラリファイルにフォームを書くときには、
ファイルを複数回ロードする可能性があることを忘れないでください。
たとえば、ライブラリを再ロードするたびに
各変数を再初期化すべきかどうか考えましょう。
defvar
は、初期化済みの変数の値を変更しません。
(see Defining Variables。)
連想リストに要素を追加するもっとも簡単な方法はつぎのとおりです。
(setq minor-mode-alist (cons '(leif-mode " Leif") minor-mode-alist))
しかし、これでは、ライブラリを再ロードすると、 複数の要素を追加してしまいます。 これを避けるにはつぎのようにします。
(or (assq 'leif-mode minor-mode-alist) (setq minor-mode-alist (cons '(leif-mode " Leif") minor-mode-alist)))
リストに要素を1回だけ追加するには、
add-to-list
(see Setting Variables)も使えます。
ライブラリをすでにロードしたかどうか明示的に調べたいこともあるでしょう。 ライブラリ内で以前ロードされたかどうか検査する方法の1つは、 つぎのとおりです。
(defvar foo-was-loaded nil) (unless foo-was-loaded execute-first-time-only (setq foo-was-loaded t))
ライブラリで名前付き機能を提供するためにprovide
を使っていれば、
ファイルの始めのほうでfeaturep
を使って、
provide
を以前呼び出したかどうか検査できます。
provide
とrequire
は、
ファイルを自動的にロードするためのautoload
の代替手段です。
それらは指定した機能(features)という考え方で動作します。
自動ロードは特定の関数を呼び出すことで起動しますが、
機能はその名前でプログラムが最初に要求したときにロードします。
機能名は、関数や変数などの集合を表すシンボルです。 それらを定義するファイルでは、その機能を提供(provide)します。 それらを使う別のプログラムでは、 その機能を要求(require)することで、 それらが定義されることを確実にします。 こうすると、未ロードであれば定義しているファイルをロードします。
機能を要求するには、機能名を引数にしてrequire
を呼び出します。
require
は、グローバル変数features
を調べて、
目的の機能がすでに提供されているかどうか調べます。
提供されていなければ、適当なファイルから機能をロードします。
このファイルでは、トップレベルでprovide
を呼び出して、
features
に機能を追加するべきです。
そうしないと、require
はエラーを通知します。
たとえば、emacs/lisp/prolog.el
には、
つぎのコードのようなrun-prolog
の定義が入っています。
(defun run-prolog () "Run an inferior Prolog process, with I/O via buffer *prolog*." (interactive) (require 'comint) (switch-to-buffer (make-comint "prolog" prolog-program-name)) (inferior-prolog-mode))
(require 'comint)
は、ファイルcomint.el
が未ロードであると、
そのファイルをロードします。
これにより、make-comint
が定義済みであることを保証します。
普通、機能には、その機能を提供するファイル名からとった名前を付けますから、
require
にファイル名を指定する必要はありません。
comint.el
ファイルには、つぎのトップレベルの式が入っています。
(provide 'comint)
これにより、グローバル変数features
のリストに
comint
が追加されるので、
これ以降に(require 'comint)
を実行しても、
なにもしないでよいことになります。
ファイルのトップレベルでrequire
を使うと、
そのファイルをロードする場合と同様に、
そのファイルをバイトコンパイルするとき(see Byte Compilation)にも
require
には効果があります。
要求したパッケージに、
バイトコンパイラが知っている必要があるマクロが入っている場合です。
トップレベルのrequire
の呼び出しは、
バイトコンパイル中に評価されますが、
provide
の呼び出しは評価しません。
したがって、つぎの例のように、
同じ機能に対するprovide
に続けてrequire
を書くことで、
バイトコンパイルするまえに定義のファイルをロードすることを確実にできます。
(provide 'my-feature) ; バイトコンパイラは無視し、
; load
は評価する
(require 'my-feature) ; バイトコンパイラは評価する
コンパイラはprovide
を無視し、
続くrequire
の処理では当該ファイルをロードします。
ファイルのロード時にはprovide
の呼び出しを実行するので、
そのあとのrequire
の呼び出しは、
ファイルをロードするときにはなにもしません。
provide feature | Function |
この関数は、機能featureをロードし終えたこと、あるいは、
ロード中であることを現在のEmacsセッション内で宣言する。
つまり、featureに関連した機能が他のLispプログラムから利用できることを
意味する。
features => (bar bish) (provide 'foo) => foo features => (foo bar bish) 自動ロードによってファイルをロードしているとき、
その内容を評価することでエラーになってロードを中止すると、
ロード中に行われた関数定義や |
require feature &optional filename | Function |
この関数は((featurep feature) を使って)
現在のEmacsセッション内にfeatureが存在するかどうか調べる。
引数featureはシンボルであること。
機能が存在していなければ、 featureを提供するファイルのロードに失敗すると、
|
featurep feature | Function |
この関数は、現在のEmacsセッションでfeatureが提供されていれば
(つまり、featureがfeatures のメンバであれば)
t を返す。
|
features | Variable |
この変数の値は、
現在のEmacsセッションにロード済みの機能を表すシンボルのリストである。
各シンボルは、provide を呼び出すことでこのリストに追加される。
リストfeatures 内の要素の順番は関係ない。
|
ライブラリでロードした関数や変数を捨てさって
他のLispオブジェクト向けにメモリを回収することができます。
そうするには関数unload-feature
を使います。
unload-feature feature &optional force | コマンド |
このコマンドは、featureを提供するライブラリをアンロードする。
つまり、当該ライブラリにおいて、defun 、defalias 、
defsubst 、defmacro 、defconst 、defvar 、
defcustom で定義した関数、マクロ、変数すべてを未定義にする。
そうして、これらのシンボルに以前設定してあった自動ロードの設定を復元する。
(ロード時に、これらをシンボルの属性autoload に保存している。)
以前の定義に復元するまえに、 これらの処置でも誤動作防止には不十分であるときには、
ライブラリで明示的なアンロードフックを定義できる。
通常、 |
関数unload-feature
はLispで書いてあり、
その動作はload-history
に基づきます。
load-history | Variable |
この変数の値は、ライブラリ名をそのライブラリが定義する関数や変数の名前、
そのライブラリが提供する機能、そのライブラリが要求する機能に対応付ける
連想リストである。
各要素はリストであり、1つ1つが1つのライブラリを記述する。 リストのCARは文字列であり、ライブラリ名である。 リストの残りは、以下の種類のオブジェクトから成る。
|
コマンドeval-region
はload-history
を更新しますが、
訪問先ファイルに対応する要素に、定義されるシンボルを追加するのであって、
要素を置き換えるのではありません。
あらかじめロード済みのライブラリは、load-history
に寄与しません。
loadhist-special-hooks | Variable |
この変数は、ライブラリ内で定義された関数を削除するために ライブラリをアンロードするまえに走査するフックのリストを保持する。 |
eval-after-load
を呼び出すと、
特定のライブラリをロードする/してあるときに実行するコードを指定できます。
eval-after-load library form | Function |
この関数は、ライブラリlibraryをロードする/してあるときに、
ライブラリlibraryのロードの最後にformを評価するように設定する。
libraryをすでにロードしてあると、
この関数はformをただちに評価する。
ライブラリ名libraryは formでエラーが発生してもロード処理をもとに戻さないが、 formの残りは実行しない。 |
一般に、よく設計されたLispプログラムはこの機能を使うべきではありません。
Lispライブラリを見通しよくモジュール化して扱うには、
(1)ライブラリの(外部から使うことを意図した)変数を調べて設定し、
(2)ライブラリの関数を呼び出すことです。
(1)を行いたければ、すぐにしてかまいません。
ライブラリをロードするまで待つ必要はありません。
(2)を行うには、ライブラリをロードする必要があります
(require
で行うことが好ましい)。
広く使われるプログラムに対する設計基準に合わなくても、
個人のカスタマイズでeval-after-load
を使うのはかまいません。
after-load-alist | Variable |
特定のライブラリをロードする/してあるときに評価する式の連想リスト。
各要素はつぎのとおり。
(filename forms...) 関数 |
Emacs Lispには、Lispで書いた関数を より効率よく実行可能なバイトコード(byte-code)と呼ばれる 特別な表現に変換するコンパイラ(compiler)があります。 コンパイラはLispの関数定義をバイトコードで置き換えます。 バイトコード関数を呼び出すと、 バイトコードインタープリタ(byte-code interpreter)が その定義を評価します。
(真のコンパイル済みコードのように)計算機ハードウェアが直接実行するかわりに、 バイトコードインタープリタがバイトコンパイル済みのコードを評価するので、 バイトコードは、再コンパイルせずに計算機から計算機に移せます。 しかしながら、真のコンパイル済みコードほど速くはありません。
EmacsバイトコンパイラがLispファイルをコンパイルするときには、
--unibyte
を指定してEmacsを起動したとしても、
ファイルで特に指定しなければ、
つねにファイルをマルチバイトテキストとして読みます。
コンパイルしても、コンパイルせずに同じファイルを実行した場合と同じ結果を
得るようにするためです。
See Loading Non-ASCII。
一般に、Emacsの任意の版は、それよりまえの版でバイトコンパイルしたコードを 実行できますが、その逆は真ではありません。 Emacs 19.29では互換性のない大きな変更を行いましたから、 それ以降の版でコンパイルしたファイルは、 特別なオプションを指定しない限り、それ以前の版ではまったく動きません。 さらに、Emacs 19.29では、キーボード文字の修飾ビットを変更しました。 その結果、19.29よりまえの版でコンパイルしたファイルは、 修飾ビットを含む文字定数を使っているとそれ以降の版では動作しません。
バイトコンパイル中に生起するエラーについては、 See Compilation Errors。
バイトコンパイルした関数は、Cで書いた基本関数ほど効率よくはありませんが、 Lispで書いた版よりはよほど速く動きます。 例を示しましょう。
(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 (silly-loop 100000) => ("Fri Mar 18 17:25:57 1994" "Fri Mar 18 17:26:28 1994") ; 31秒 (byte-compile 'silly-loop) => [コンパイルしたコードは省略] (silly-loop 100000) => ("Fri Mar 18 17:26:52 1994" "Fri Mar 18 17:26:58 1994") ; 6秒
この例では、解釈実行するコードでは実行に31秒必要でしたが、 バイトコンパイルしたコードでは6秒でした。 この結果は代表的なのもですが、実際の結果は大きく変動します。
関数byte-compile
で、
個々の関数定義やマクロ定義をバイトコンパイルできます。
byte-compile-file
で1つのファイル全体をコンパイルしたり、
byte-recompile-directory
やbatch-byte-compile
で
複数個のファイルをコンパイルできます。
バイトコンパイラは、
各ファイルに対するエラーメッセージや警告メッセージを
*Compile-Log*
と呼ばれるバッファに出力します。
読者のプログラムに関してここに報告されたことがらは、
問題点を指摘しますが、必ずしもエラーとは限りません。
バイトコンパイルする可能性のあるファイルにマクロ呼び出しを書くときには 注意してください。 マクロ呼び出しはコンパイル時に展開されるので、 正しくコンパイルするためにはマクロは定義済みである必要があります。 詳しくは、See Compiling Macros。
通常、ファイルをコンパイルしてもファイルの内容を評価したり、
ファイルをロードしません。
しかし、ファイルのトップレベルに書いたrequire
は実行します。
コンパイル時に必要なマクロ定義が存在することを保証する1つの方法は、
それらを定義するファイルを要求(require
)することです
(see Named Features)。
コンパイルしたプログラムを実行するときに
マクロ定義ファイルのロードを防ぐには、
require
の呼び出しの周りにeval-when-compile
を書きます
(see Eval During Compile)。
byte-compile symbol | Function |
この関数は、symbolの関数定義をバイトコンパイルし、
以前の定義をコンパイルしたもので置き換える。
symbolの関数定義は、関数の実際のコードであること。
つまり、コンパイラは、別のシンボルへの間接参照を辿らない。
byte-compile は、symbolのコンパイル済みの新たな定義を返す。
symbolの定義がバイトコード関数オブジェクトであると、
(defun factorial (integer) "Compute factorial of INTEGER." (if (= 1 integer) 1 (* integer (factorial (1- integer))))) => factorial (byte-compile 'factorial) => #[(integer) "^H\301U\203^H^@\301\207\302^H\303^HS!\"\207" [integer 1 * factorial] 4 "Compute factorial of INTEGER."] 結果は、バイトコード関数オブジェクトである。 この文字列には実際のバイトコードが入っている。 その各文字は、命令や命令のオペランドである。 ベクトルには、特別な命令に符号化される特定の基本関数を除いて、 関数が使うすべての定数、変数名、関数名が入っている。 |
compile-defun | コマンド |
このコマンドはポイントを含むdefun を読み取り、
それをコンパイルして、結果を評価する。
実際に関数定義であるdefun でこのコマンドを使うと、
その関数をコンパイルしたものをインストールすることになる。
|
byte-compile-file filename | コマンド |
この関数は、filenameという名前のLispコードのファイルを
コンパイルしバイトコードのファイルにする。
出力ファイルの名前は、接頭辞.el を.elc に換えて作る。
filenameが.el で終っていないときには、
filenameの末尾に.elc を付加する。
入力ファイルから一度に1つずつフォームを読みながらコンパイルを行う。 それが関数定義やマクロ定義であると、 コンパイルした関数定義やマクロ定義を書き出す。 他のフォームは一塊にして、各塊をコンパイルして書き出し、 ファイルを読むとコンパイルしたコードが実行されるようにする。 入力ファイルを読むときにすべてのコメントを捨てる。 このコマンドは % ls -l push* -rw-r--r-- 1 lewis 791 Oct 5 20:31 push.el (byte-compile-file "~/emacs/push.el") => t % ls -l push* -rw-r--r-- 1 lewis 791 Oct 5 20:31 push.el -rw-rw-rw- 1 lewis 638 Oct 8 20:25 push.elc |
byte-recompile-directory directory flag | コマンド |
この関数は、directoryにある再コンパイルが必要な
個々の.el ファイルを再コンパイルする。
ファイルを再コンパイルする必要があるのは、
.elc ファイルが存在しても.el ファイルより古い場合である。
このコマンドの戻り値は予測できない。 |
batch-byte-compile | Function |
この関数は、コマンド行に指定したファイル群に対して
byte-compile-file を実行する。
この関数はEmacsをバッチモードで実行しているときにだけ使うこと。
完了するとEmacsを終了するからである。
1つのファイルでエラーが発生しても、後続のファイルの処理には影響しないが、
エラーを起こしたファイルに対する出力ファイルは生成せず、
Emacsのプロセスは0以外の状態コードで終了する。
% emacs -batch -f batch-byte-compile *.el |
byte-code code-string data-vector max-stack | Function |
この関数はバイトコードを実際に解釈実行する。
バイトコンパイルした関数は、実際には、
byte-code を呼び出すような本体として定義される。
この関数を読者自身で呼び出さないこと。
この関数の正しい呼び出しを生成する方法はバイトコンパイラだけが知っている。
Emacs 18版では、バイトコードは関数 |
バイトコンパイルしたファイルからロードした関数や変数では、 それらの説明文字列は、必要に応じてそのファイルを動的に参照します。 これはEmacs内のメモリを節約しロード処理も速くなります。 というのは、ファイルのロード処理で説明文字列を処理する必要がないからです。 説明文字列を実際に参照するのは遅くなりますが、 普通、ユーザーをいらいらさせるほとではありません。
説明文字列を動的に参照することには欠点があります。
読者のサイトでEmacsを通常の手順でインストールした場合には、 これらの問題は普通起こらないはずです。 新版のインストールには別のディレクトリを使いますから、 旧版をインストールしてある限り、そのファイル群は意図した場所に 無変更で残っているはずです。
しかしながら、読者自身がEmacsを構築して、 構築したディレクトリからEmacsを使う場合、 Lispファイルを編集して再コンパイルすると、 しばしばこの問題を経験するでしょう。 そのような場合には、再コンパイルしたあとでファイルを再ロードすれば 問題を解決できます。
旧版ではこの機能を使えないので、
Emacsの(19.29以降の)最近の版でバイトコンパイルしたファイルは
旧版ではロードできません。
byte-compile-dynamic-docstrings
にnil
を設定すれば、
コンパイル時にこの機能をオフにできます。
Emacsの旧版にロードできるようにファイルをコンパイルできるのです。
すべてのファイルをこのようにコンパイルしたり、あるいは、
この変数をファイルにローカルな束縛に指定して1つのソースファイルだけを
このようにコンパイルしたりもできます。
そのようにする1つの方法は、つぎの文字列をファイルの先頭行に追加することです。
-*-byte-compile-dynamic-docstrings: nil;-*-
byte-compile-dynamic-docstrings | Variable |
これがnil 以外であると、
バイトコンパイラは、説明文字列を動的にロードするように設定した
コンパイル済みファイルを生成する。
|
説明文字列を動的に扱う場合、
コンパイル済みのファイルではLispリーダの特別な構文#@count
を
使います。
この構文は後続のcount文字を読み飛ばします。
また、#$
という構文も使います。
これは、『文字列としてのこのファイルの名前』を表します。
Lispのソースファイルでは、これらの構文を使わないのが最良です。
これらは人が読むファイル向けに設計したものではないからです。
ファイルをコンパイルするとき、 動的関数ロード(dynamic function loading、 遅延ロード(lazy loading)ともいう)機能を指定できます。 動的関数ロードでは、ロードするときにファイル内の関数定義をすべて 読むわけではありません。 そのかわりに、各関数定義には、 そのファイルを指す埋め草が入っています。 それぞれの関数を初めて呼び出したときに、 その完全な定義をファイルから読み取り、埋め草を置き換えます。
動的関数ロードの利点は、ファイルをロードするよりかなり速いことです。 ユーザーが呼び出せる数多くの別々の関数を収めたファイルにおいては、 それらの1つだけを使って残りのものを使わないのであれば、 これは有利なことです。 キーボードコマンドを提供する特別なモードには、 しばしばこのような使い方のパターンがあります。 ユーザーがモードを起動しても、提供するコマンドの一部しか使わないのです。
動的関数ロードの機能には、ある種の欠点もあります。
Emacsのファイル群をインストールした普通の状況では、 このような問題は起きないはずです。 しかし、Lispファイルを読者が変更すると起こりえます。 これらの問題を回避するもっとも簡単な方法は、 再コンパイルするたびに新たにコンパイルしたファイルを ただちに再ロードすることです。
バイトコンパイラは、コンパイル時に変数byte-compile-dynamic
が
nil
以外であれば、動的関数ロードの機能を使います。
動的ロードは特定のファイルで必要なだけですから、
この変数をグローバルに設定しないでください。
そのかわりにファイルにローカルな変数束縛を使って
特定のソースファイルだけでこの機能をオンにします。
たとえば、ソースファイルの先頭行につぎのテキストを書けば、
そのようにできます。
-*-byte-compile-dynamic: t;-*-
byte-compile-dynamic | Variable |
これがnil 以外であると、
バイトコンパイラは、動的関数ロードを使うように設定した
コンパイル済みのファイルを生成する。
|
fetch-bytecode function | Function |
functionを完全にロードしていないと、 バイトコンパイルしたファイルからただちにfunctionの定義をロードする。 引数functionは、バイトコード関数オブジェクトか関数名である。 |
プログラムのコンパイル時に評価されるようなコードを書くための機能です。
eval-and-compile body | Special Form |
このフォームは、コンパイルしたり実行したり
(コンパイルしてあってもしてなくても)するときに
bodyを評価するように印を付ける。
bodyを別のファイルに収め、そのファイルを |
eval-when-compile body | Special Form |
このフォームは、コンパイルしたプログラムをロードするときではなく、
プログラムのコンパイル時にbodyを評価するように印を付ける。
コンパイラが評価した結果は、コンパイルしたプログラム内に定数として現れる。
ソースファイルをコンパイルせずにロードすると、
bodyを普通どおり評価する。
Common Lispに関した注意: |
バイトコンパイルした関数は、特別なデータ型、 バイトコード関数オブジェクト(byte-code function objects)です。
内部的には、バイトコード関数オブジェクトはベクトルによく似ています。
しかし、評価時にこのデータ型が呼び出すべき関数として現れると、
特別に扱います。
バイトコード関数オブジェクトの表示表現はベクトルに似ていますが、
開き角括弧[
のまえに余分に#
が付きます。
バイトコード関数オブジェクトには、少なくとも4つの要素が必要です。 最大個数に制限はありませんが、最初の6つ個の要素にだけ 普通の用途があります。 つぎのとおりです。
nil
。
説明文字列がファイルに収めてあれば、値は数かリストである。
実際の説明文字列を取得するには関数documentation
を使う
(see Accessing Documentation)。
nil
。
バイトコード関数オブジェクトの例を表示表現でつぎに示します。
#[(&optional arg) "^H\204^F^@\301^P\302^H[!\207" [arg 1 forward-sexp] 2 254435 "p"]
バイトコードオブジェクトを作る基本的な方法は、
make-byte-code
を使うことです。
make-byte-code &rest elements | Function |
この関数は、elementsを要素とする バイトコード関数オブジェクトを作成し返す。 |
バイトコード関数の要素を自分で作ったりしないでください。 それらに整合性がないと、 その関数を呼び出すとEmacsがクラッシュすることもあります。 これらのオブジェクトの作成は、バイトコンパイラに任せるべきです。 バイトコンパイラは整合した要素を作成します(と期待する)。
バイトコードオブジェクトの要素はaref
で参照できます。
同じ要素群のベクトルをvconcat
で作ることもできます。
人間はバイトコードを書きません。 それはバイトコンパイラの仕事です。 しかし、好奇心を満たすために逆アセンブラを用意してあります。 逆アセンブラはバイトコンパイルしたコードを人が読める形式に変換します。
バイトコードインタープリタは、単純なスタックマシンとして実装してあります。 値を自前のスタックに積み、計算に使うためにスタックから取り出し、 計算結果そのものはスタックにまた積みます。 バイトコード関数から戻るときには、スタックから値を取り出して 関数値としてその値を返します。
スタックに加えて、変数とスタックのあいだで値を転送することで、 バイトコード関数は、普通のLisp変数を使ったり、 束縛したり、値を設定できます。
disassemble object &optional stream | コマンド |
この関数はobjectの逆アセンブルしたコードを出力する。
streamを指定すると、そこへ出力する。
さもなければ、逆アセンブルしたコードはストリームstandard-output へ
出力する。
引数objectは関数名かラムダ式である。
特別な例外として、この関数を対話的に使うと、
|
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: (integer) 0 constant 1 ; スタックに1を積む 1 varref integer ; 環境からinteger
の値を取得し、 ; スタックに積む 2 eqlsign ; スタックの先頭から2つの値を ; 取りさって比較し、 ; 結果をスタックに積む 3 goto-if-nil 10 ; スタックの先頭から値を取りさり ; 検査する。nil
ならば10へ飛び、 ; さもなければつぎへ進む 6 constant 1 ; スタックに1を積む 7 goto 17 ; 17へ飛ぶ(この場合、関数は1を返す) 10 constant * ; スタックにシンボル*
を積む 11 varref integer ; スタックにinteger
の値を積む 12 constant factorial ; スタックにfactorial
を積む 13 varref integer ; スタックにinteger
の値を積む 14 sub1 ; スタックからinteger
を取りさり、 ; 減した新たな値をスタックに積む ; スタックの現在の内容はつぎのとおり ; -integer
を減らした値 ; -factorial
; -integer
の値 ; -*
15 call 1 ; スタックの最初(先頭)要素を使って ; 関数factorial
を呼び出す ; 戻り値をスタックに積む ; スタックの現在の内容はつぎのとおり ; -factorial
の ; 再帰呼び出しの結果 ; -integer
の値 ; -*
16 call 2 ; スタックの最初の要素の2つ ; (先頭の2つ)を引数として ; 関数*
を呼び出し ; 結果をスタックに積む 17 return ; スタックの先頭要素を返す => nil
関数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: (n) 0 constant current-time-string ;current-time-string
を ; スタックの先頭に積む 1 call 0 ; 引数なしでcurrent-time-string
を ; 呼び出し、結果をスタックに積む 2 varbind t1 ; スタックから値を取りさり、 ;t1
に束縛する 3 varref n ; 環境からn
の値を取得し、 ; 値をスタックに積む 4 sub1 ; スタックの先頭から1を引く 5 dup ; スタックの先頭の値を複製する ; つまり、スタックの先頭の値を ; コピーして、それをスタックに積む 6 varset n ; スタックの先頭から値を取りさり、 ; 値をn
に束縛する ; つまり、dup varset
は ; スタックの先頭の値を取りさらずに ;n
にコピーする 7 constant 0 ; スタックに0を積む 8 gtr ; スタックから2つの値を取りさり、 ; nが0より大きいか調べ、 ; 結果をスタックに積む 9 goto-if-nil-else-pop 17 ;n
<= 0ならば17へ飛ぶ ; (whileループから抜ける) ; さもなければ、スタックの先頭から ; 値を取りさり、つぎへ進む 12 constant nil ; スタックにnil
を積む ; (これはループの本体) 13 discard ; ループの本体の結果を捨てる ; (whileループは副作用のために ; つねに評価される) 14 goto 3 ; whileループの先頭へ飛ぶ 17 discard ; スタックの先頭の値を取りさって、 ; whileループの結果を捨てる。 ; これは、9での飛び越しのために ; 取りさっていない値nil
18 varref t1 ;t1
の値をスタックに積む 19 constant current-time-string ;current-time-string
を ; スタックに積む 20 call 0 ; ふたたびcurrent-time-string
を ; 呼び出す 21 list2 ; スタックの先頭から2つの値を取りさり ; それらのリストを作り、 ; リストをスタックに積む 22 unbind 1 ; ローカルの環境のt1
の束縛を解く 23 return ; スタックの先頭の値を返す => nil
アドバイス(advice)機能により、関数の既存の定義に追加できます。 これは、Emacsの他の部分で定義された関数を ライブラリにおいてカスタマイズする見通しのよい方法です。 関数全体を再定義するよりも見通しがよいのです。
各関数は、個別に定義した複数のアドバイス断片を持てます。 それぞれのアドバイス断片は、明示的に有効にしたり無効にできます。 任意の関数の有効にしたアドバイス断片が実際にその効果を発揮するのは、 当該関数のアドバイスを活性にしたときか 当該関数をのちに定義したり再定義したときです。
使用上の注意:
アドバイスは、既存関数の既存の呼び出しのふるまいを変更するのに有用である。
新たな呼び出しやキーバインドの新たなふるまいが必要な場合には、
既存関数を使う新たな関数(や新たなコマンド)を定義するほうが
見通しがよい。
defadvice
.
defadvice
as fset
is to defun
.
コマンドnext-line
は、ポイントを垂直に複数行移動します。
標準バインドはC-nです。
バッファの最終行で使うと、
(next-line-add-newlines
がnil
以外の場合)
このコマンドは行を作るために改行を挿入し、その行に移動します。
同様な機能をprevious-line
に追加したいとします。
つまり、バッファの先頭に新たな行を挿入し、その行へ移動するのです。
どのようにすればよいでしょう?
当該関数を再定義すればできますが、それではモジュール性がよくありません。 アドバイス機能が見通しのよい代替方法を提供します。 既存の関数定義を実際に変更したりその定義を参照することなく、 関数定義に読者のコードを実質的に追加できます。 つぎのように行います。
(defadvice previous-line (before next-line-at-end (arg)) "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
に対するアドバイス断片を定義します。
このアドバイス断片にはnext-line-at-end
という名前が付きます。
シンボルbefore
により、
previous-line
の通常の定義を実行するまえに実行する
事前アドバイス(before-advice)であることを意味します。
(arg)
は、アドバイス断片がどのように関数の引数を参照するかを指定します。
このアドバイス断片が実行されると、必要な場面では新たに行を作りますが、 その行へはポイントを移動しません。 これはアドバイスを書く正しいやりかたです。 というのは、通常の定義がこのあとに実行され、新たに挿入した行へ移動します。
アドバイスを定義しても関数previous-line
をただちには変更しません。
つぎのようにアドバイスを活性にすると変わります。
(ad-activate 'previous-line)
これにより、関数previous-line
に対して定義してある
アドバイスを使い始めます。
これ以降、C-pやM-xでユーザーが起動したのか
Lispから呼ばれたのかに関わらず、
この関数を起動すると、まずアドバイスを実行してから
関数の通常の定義を実行します。
この例は、アドバイスの1つのクラスである事前アドバイスの例であり、 関数の元定義のまえに実行されます。 他に2つのアドバイスクラスがあります。 元定義のあとに実行される事後アドバイス(after-advice)と 元定義の起動を包み込む式を指定する包囲アドバイス(around-advice)です。
アドバイス断片を定義するには、マクロdefadvice
を使います。
defadvice
の呼び出しはつぎのような構文です。
defun
やdefmacro
の構文を基にしていますが、
追加部分があります。
(defadvice function (class name [position] [arglist] flags...) [documentation-string] [interactive-form] body-forms...)
ここで、functionはアドバイス対象となる関数 (やマクロやスペシャルフォーム)です。 以後、アドバイスする対象を単に『関数』と書きますが、 これにはつねにマクロやスペシャルフォームを含みます。
classはアドバイスのクラスを指定し、
before
、after
、around
のいずれかです。
事前アドバイス(before
)は関数そのもののまえに実行されます。
事後アドバイス(after
)は関数そのもののあとに実行されます。
包囲アドバイス(around
)は関数自身の実行を包み込みます。
事後アドバイスと包囲アドバイスでは、
ad-return-value
に設定することで戻り値を変更できます。
ad-return-value | Variable |
アドバイスを実行しているとき、 関数の元定義の実行を完了したあとでは、この変数はその戻り値を保持する。 すべてのアドバイスを完了すると、最終的には、この値を呼び出し側へ返す。 事後アドバイスと包囲アドバイスでは、この変数に別の値を設定することで 戻り値を変更できる。 |
引数nameはアドバイスの名前であり、nil
以外のシンボルです。
アドバイス名は、functionの特定クラスのすべてのアドバイス断片から
1つのアドバイス断片を一意に識別します。
名前でアドバイス断片を参照でき、
それを再定義したり有効にしたり無効にできます。
通常の関数定義の引数リストのかわりに、 アドバイス定義では異なる情報を必要とします。
省略可能なpositionは、指定したclassの
現在のアドバイスリストのどこに新たなアドバイスを置くかを指定します。
first
、last
、あるいは、
0から数え始める位置を指定する数である必要があります
(first
は0と等価)。
位置を指定しないとデフォルトはfirst
です。
当該クラスの既存位置の範囲を超えている場合には、
先頭か末尾のどちらか近いほうになります。
既存のアドバイス断片を再定義する場合には、値positionは無視されます。
省略可能なarglistは、 アドバイスが使う引数リストを定義するために使います。 これは、アドバイスを実行するために生成される結合定義 (see Combined Definition)の引数リストになります。 その結果、アドバイスの式では、 引数の値を参照するためにこのリストの引数変数を使えます。
この引数リストは、関数の実際の呼び出し方を扱えるように、 もとの関数の引数リストと互換性がある必要があります。 2つ以上のアドバイス断片で引数リストを指定している場合、 すべてのアドバイスクラスの中で最初のもの(位置が最小のもの)を使います。
残りの要素flagsは、このアドバイス断片の使い方に関する情報を指定する シンボルです。 正しいシンボルとそれらの意味はつぎのとおりです。
activate
functionが未定義(未定義のアドバイス(forward advice)と呼ぶ状況)
であるとこのフラグにはなんの効果もない。
というのは、未定義関数のアドバイスは活性にできないからである。
しかし、functionを定義するとそのアドバイスは自動的に活性にされる。
protect
unwind-protect
の中に後始末として置かれ、
それよりまえに実行されるコードでエラーが発生したりthrow
を使っても
実行される。
see Cleanups。
compile
activate
とともに指定しないと、このフラグは無視する。
see Combined Definition。
disable
preactivate
defadvice
をコンパイルしたりマクロ展開したときに、
functionに対するアドバイスを活性にする。
これにより現在のアドバイスの状態に応じたアドバイス定義をコンパイルし、
必要に応じて使われるようになる。
このdefadvice
をバイトコンパイルする場合にのみ意味を持つ。
省略可能なdocumentation-stringは、
このアドバイス断片の説明文字列になります。
functionに対するアドバイスが活性であると、
(documentation
が返す)functionの説明文は、
関数の元定義の説明文字列とfunctionのアドバイスすべての説明文字列の
合成になります。
省略可能なinteractive-formは、 元関数の対話的ふるまいを変更するために指定します。 2つ以上のアドバイス断片でinteractive-formを指定している場合、 すべてのアドバイスの中で最初のもの(位置が最小のもの)が優先します。
空リストでもかまわないbody-formsは、アドバイスの本体です。 アドバイスの本体では、引数、戻り値、束縛環境を参照/変更したり、 いかなる種類の副作用を起こせます。
警告:
マクロをアドバイスする場合、
マクロはプログラムのコンパイル時に展開されるのであって、
コンパイルしたプログラムの実行時に展開されるのではないことに注意。
アドバイスが使用するすべてのサブルーティンは、
バイトコンパイラがマクロを展開するときに必要になる。
包囲アドバイスにより、関数の元定義を包み込むLisp式を書けます。
関数の元定義を実行する場所を特別なシンボルad-do-it
で指定します。
包囲アドバイスの本体に現れたこのシンボルは、
元定義(と内側の包囲アドバイス本体)のフォームを含んだprogn
で
置き換えられます。
例を示しましょう。
(defadvice foo (around foo-around) "Ignore case in `foo'." (let ((case-fold-search t)) ad-do-it))
これは、foo
の元定義を実行するときに
大文字小文字を区別しないで探索することを保証します。
ad-do-it | Variable |
これは実際には変数ではないが、包囲アドバイス内では変数のように用いる。 関数の元定義と『より内側の』包囲アドバイスを実行する場所を指定する。 |
包囲アドバイスでad-do-it
を用いなければ、関数の元定義を実行しません。
これは、元定義を完全に無効にする手段です。
(さらに、内側の包囲アドバイス断片も無効にする。)
マクロdefadvice
はdefun
に似ていて、
アドバイスのコードやアドバイスに関する他のすべての情報を
ソースコードで明示します。
関数ad-add-advice
を用いると、
その詳細を計算で求めたアドバイスを作成できます。
ad-add-advice function advice class position | Function |
ad-add-advice を呼び出すと、
関数functionに対するクラスclassのアドバイス断片として
adviceを追加する。
引数adviceはつぎの形式である。
(name protected enabled definition) ここで、protectedとenabledはフラグであり、
definitionはアドバイスの動作を指定する式である。
enabledが functionに指定したクラスclassのアドバイス断片がすでにあると、
positionは新しいアドバイス断片をリストのどこに置くかを指定する。
positionの値は、 functionに同じ名前のアドバイス断片adviceがすでにあると、 引数positionは無視され、古いアドバイス断片を新しいもので置き換える。 |
デフォルトでは、アドバイスを定義してもその効果は発揮されません。
アドバイスした関数のアドバイスを活性にして始めて効果を発揮します。
defadvice
でフラグactivate
を指定すれば、
関数にアドバイスを定義したときに活性にできます。
しかし、普通は、関数ad-activate
や以下の活性化コマンドを
呼び出すことで、関数のアドバイスを活性にします。
アドバイスの定義操作と活性化操作を区別することで、 アドバイスを追加するたびに関数を再定義することなる、 関数に複数のアドバイス断片を効率よく追加できます。 さらに重要なことは、関数を実際に定義するまえでも 関数にアドバイスを定義できることです。
関数のアドバイスを初めて活性にすると、 関数の元定義を保存してから、関数に対する有効なアドバイス断片すべてを 元定義と結合して新たな定義を作り出します。 (現在無効にしてあるアドバイス断片は使用しない。 see Enabling Advice。) この定義をインストールし、 以下に述べる条件に応じてバイトコンパイルする場合もあります。
アドバイスを活性にするコマンドすべてにおいて、
compileがt
であると、
アドバイスを実装する結合定義をコンパイルします。
ad-activate function &optional compile | コマンド |
このコマンドはfunctionに対するアドバイスを活性にする。 |
関数のアドバイスがすでに活性になっているアドバイスを 活性にしても意味があります。 当該関数のアドバイスを活性にしたあとでアドバイスを変更した場合、 その変更が効果を持つようにする操作になります。
ad-deactivate function | コマンド |
このコマンドはfunctionのアドバイスを不活性にする。 |
ad-activate-all &optional compile | コマンド |
このコマンドはすべての関数に対するアドバイスを活性にする。 |
ad-deactivate-all | コマンド |
このコマンドはすべての関数に対するアドバイスを不活性にする。 |
ad-activate-regexp regexp &optional compile | コマンド |
このコマンドはregexpに一致する名前のすべてのアドバイス断片を活性にする。 より正確には、regexpに一致する名前のアドバイス断片を持つ任意の 関数のすべてのアドバイスを活性にする。 |
ad-deactivate-regexp regexp | コマンド |
このコマンドはregexpに一致する名前の すべてのアドバイス断片を不活性にする。 より正確には、regexpに一致する名前のアドバイス断片を持つ任意の 関数のすべてのアドバイスを不活性にする。 |
ad-update-regexp regexp &optional compile | コマンド |
このコマンドはregexpに一致する名前のアドバイス断片を活性にするが、
すでにアドバイスが活性になっている関数に対するものだけである。
関数に対するアドバイスの再活性化は、 アドバイスを活性にしたあとに行った当該アドバイスの変更すべて (有効にしたり無効にしたアドバイス断片を含む。 see Enabling Advice)が効果を持つようにするのに便利である。 |
ad-start-advice | コマンド |
関数を定義したり再定義したときにアドバイスを自動的に活性にする。 このモードをオンにすると、アドバイスを定義するとただちに効果を持つようになる。 |
ad-stop-advice | コマンド |
関数を定義したり再定義してもアドバイスを自動的には活性にしない。 |
ad-default-compilation-action | User Option |
この変数は、関数に対するアドバイスを活性にした結果作られる 結合定義をコンパイルするかどうか制御する。 |
『予約活性』(see Preactivation)中にアドバイス定義を作成すると
その定義はすでにコンパイルされているはずです。
というのは、preactivate
フラグを指定したdefadvice
を
含むファイルをバイトコンパイル中にそれが定義されたはずだからです。
各アドバイス断片には、
それを有効にするか無効にするかを指定するフラグがあります。
アドバイス断片を有効にしたり無効にすることで、
アドバイス断片を未定義にしたり再定義することなくオン/オフできます。
たとえば、関数foo
に対するアドバイス断片my-advice
を
無効にするには、つぎのようにします。
(ad-disable-advice 'foo 'before 'my-advice)
この関数自身は、アドバイス断片の有効化フラグを変更するだけです。
アドバイスした関数でこの変更の効果を発揮するには、
foo
のアドバイスを再度活性にする必要があります。
(ad-activate 'foo)
ad-disable-advice function class name | コマンド |
このコマンドはfunctionに対するクラスclass内の nameで指名したアドバイス断片を無効にする。 |
ad-enable-advice function class name | コマンド |
このコマンドはfunctionに対するクラスclass内の nameで指名したアドバイス断片を有効にする。 |
正規表現を用いて、さまざまな関数に対する 多数のアドバイス断片を一度に無効にすることもできます。 この場合も、当該関数のアドバイスを再度活性にすることで、 その効果が発揮されます。
ad-disable-regexp regexp | コマンド |
このコマンドは、すべての関数のすべてのクラスの regexpに一致するアドバイス断片すべてを無効にする。 |
ad-enable-regexp regexp | コマンド |
このコマンドは、すべての関数のすべてのクラスの regexpに一致するアドバイス断片すべてを有効にする。 |
アドバイスを実行するための結合定義を作成することは、 ある程度手間がかかります。 ライブラリで多数の関数をアドバイスしていると、 ライブラリのロードが遅くなります。 そのような場合、あらかじめ適切な結合定義を作成する 予約活性(preactivation)を使えます。
予約活性を使うには、defadvice
でアドバイスを定義するときに
フラグpreactivate
を指定します。
このようなdefadvice
の呼び出しでは、
(有効か無効に関わらず)このアドバイス断片と
当該関数に対して現在有効になっている他のアドバイスを元定義
に結合した定義を作成します。
defadvice
をコンパイルすると、その結合定義もコンパイルします。
のちに関数のアドバイスを活性にしたとき、 関数に対する有効にしたアドバイスがこの結合定義の作成に 使用したものに一致すると既存の結合定義を使います。 そのため、新たに結合定義を作成する必要がなくなります。 したがって、予約活性はけっしてまちがった結果を生じませんが、 予約活性に用いたアドバイスと活性にした有効なアドバイスが一致しないと 利点はなくなります。
不一致のために予約活性が正しく動作していない兆候の例を示します。
features
の値にbyte-compile
が含まれる。
関数自体が定義されるまえであってもコンパイル済みの予約活性したアドバイスは 正しく動作します。 しかし、予約活性したアドバイスをコンパイルするときには 関数は定義済みである必要があります。
予約活性したアドバイスが使われない理由を調べるよい方法はありません。
できることは、
関数のアドバイスを活性にするまえに、
(関数trace-function-background
で)
関数ad-cache-id-verification-code
をトレースすることです。
活性にしたあと、当該関数に対してad-cache-id-verification-code
が
返した値を調べます。
verified
ならば予約活性したアドバイスが使われています。
これ以外の値は、アドバイスが不適切と判断された理由に関する情報を
与えます。
警告:
予約活性が失敗する場合が1つ知られている。
現在のアドバイスの状態に一致しなくても、
あらかじめ作成した結合定義を使ってしまう。
これは、同一関数に対する同じクラスの同一名称であるが異なるアドバイス断片を
2つのパッケージで定義している場合に発生する。
このようなことは避けること。
アドバイス断片の本体からアドバイスする関数の引数を参照する もっとも簡単な方法は、関数定義で用いているものと同じ名前を使うことです。 これには、元関数の引数の変数名を知る必要があります。
多くの場合、この単純な方法で十分ですが、欠点もあります。 アドバイス内に引数名を直接書き込むために、堅牢ではありません。 関数の元定義が変更されると、アドバイスは動作しません。
他の方法は、アドバイスそのものに引数リストを指定することです。 これは関数の元定義の引数名を知る必要はありませんが、制約もあります。 関数に対するすべてのアドバイスで同一の引数リストを使う必要があります。 なぜなら、すべてのアドバイスに実際に使われる引数リストは、 当該関数のアドバイス断片の最初のものだからです。
より堅牢な方法は、活性にするときに、 つまり、アドバイスを結合した定義を作成するときに 適切なフォームに展開されるマクロを使うことです。 参照用マクロは、関数の引数変数への実引数の分配方法に依存しない 実引数の位置で参照します。 Emacs Lispにおいては、引数の意味は引数リスト内での位置で決まるため、 これは堅牢です。
ad-get-arg position | Macro |
位置positionにある実引数を返す。 |
ad-get-args position | Macro |
位置positionから始まる実引数のリストを返す。 |
ad-set-arg position value | Macro |
位置positionにある実引数の値を設定する。 |
ad-set-args position value-list | Macro |
位置positionから始まる実引数のリストにvalue-listを設定する。 |
例を示します。
関数foo
の定義はつぎのとおりであり、
(defun foo (x y &optional z &rest r) ...)
つぎのように呼ばれるとします。
(foo 0 1 2 3 4 5 6)
そうすると、foo
の本体では、
xは0、yは1、zは2、rは(3 4 5 6)
です。
このとき、ad-get-arg
やad-get-args
は、つぎの値を返します。
(ad-get-arg 0) => 0 (ad-get-arg 1) => 1 (ad-get-arg 2) => 2 (ad-get-arg 3) => 3 (ad-get-args 2) => (2 3 4 5 6) (ad-get-args 4) => (4 5 6)
この例では、引数に値を設定できます。
(ad-set-arg 5 "five")
の効果は、6番目の引数を"five"
に変更します。
foo
の本体を実行するまえにこのアドバイスが実行されると、
本体内ではrは(3 4 "five" 6)
になります。
つぎは引数リストを変更する例です。
(ad-set-args 0 '(5 4 3 2 1 0))
foo
の本体を実行するまえにこのアドバイスが実行されると、
foo
の本体内では、
xは5、yは4、zは3、rは(2 1 0)
になります。
これらの引数参照は、実際にはLispマクロとしての実装ではありません。 アドバイス機構で特別に実装してあります。
アドバイス機能が結合定義を作成するとき、
元関数の引数リストを知る必要があります。
基本関数に対しては、これはつねに可能とは限りません。
アドバイスが引数リストを決定できないときには、
(&rest ad-subr-args)
を使います。
これはつねに動作しますが、
引数値のリストを作成するために効率的ではありません。
ad-define-subr-args
を使って、
基本関数に対する適当な引数名を宣言できます。
ad-define-subr-args function arglist | Function |
この関数は、関数functionの引数リストとして arglistを使うことを指定する。 |
たとえば、
(ad-define-subr-args 'fset '(sym newdef))
は、関数fset
の引数リストを指定します。
関数には、n個の事前アドバイス(before-advice)、 m個の包囲アドバイス(around-advice)、 k個の事後アドバイス(after-advice)があるとします。 保護したアドバイス断片はないと仮定すると、 関数のアドバイスを実装するために作成される結合定義は つぎのようになります。
(lambda arglist [ [advised-docstring] [(interactive ...)] ] (let (ad-return-value) before-0-body-form... .... before-n-1-body-form... around-0-body-form... around-1-body-form... .... around-m-1-body-form... (setq ad-return-value apply original definition to arglist) other-around-m-1-body-form... .... other-around-1-body-form... other-around-0-body-form... after-0-body-form... .... after-k-1-body-form... ad-return-value))
マクロはマクロとして再定義します。
つまり、結合定義の先頭にmacro
を追加します。
元関数やアドバイス断片のどれかに対話宣言があれば、
対話宣言フォームが入ります。
対話的な基本関数をアドバイスした場合には、
特別な方法を使います。
つまり、基本関数をcall-interactively
で呼び出して、
基本関数自身が引数を読み取るようにします。
この場合、アドバイスからは引数を参照できません。
各クラスのさまざまなアドバイスの本体フォームは、 それらの指定された順に組み立てられます。 包囲アドバイスl(around-advice l)のフォーム群は、 包囲アドバイスl - 1(around-advice l - 1)の フォームの1つに入ります。
包囲アドバイスのもっとも内側では、
元定義をarglistに適用
しますが、そのフォームは元関数の種類に依存します。
変数ad-return-value
には、その戻り値が設定されます。
この変数はすべてのアドバイス断片から見えるので、
アドバイスした関数から実際に戻るまえに、
これを参照したり変更できます。
保護したアドバイス断片を含むアドバイスした関数の構造も同じです。
唯一の違いは、フォームunwind-protect
により、
アドバイス断片でエラーを起こしたり非ローカル脱出を行っても、
保護したアドバイスが実行されることを保証します。
包囲アドバイスを1つでも保護していると、その結果として、
包囲アドバイス全体が保護されます。
Emacs Lispプログラムの問題点を調べるには、 問題が発生したときにどのようにプログラムを使っているかに依存して、 3つの方法があります。
他の有用なデバッグツールは、ドリブルファイルです。 ドリブルファイルをオープンしてあると、 Emacsはすべてのキーボード入力をこのファイルにコピーします。 あとでこのファイルを調べれば、どんな入力があったかわかります。 See Terminal Input。
端末設定に関した問題を解決するには、
関数open-termscript
が有用です。
See Terminal Output。
通常のLispデバッガは、フォームの評価を一時停止する機能を提供します。 評価を一時停止しているあいだ(ブレーク(break)と呼ばれる状態)は、 実行時スタックを調べたり、ローカルやグローバル変数の値を調べたり、 それらの値を変更できます。 ブレークは再帰編集なので、Emacsの通常の編集機能すべてを使えます。 デバッガを再帰的に起動するようなプログラムを実行することさえできます。 See Recursive Editing。
debug
.
デバッガへ入るもっとも重要な時期は、Lispエラーが発生したときです。 これにより、エラーの直接原因を調べることができます。
しかし、デバッガに入るのは、エラーの通常の帰結ではありません。
多くのコマンドは
(バッファの末尾でC-fを使うなどの)不適切に起動されると
しばしばLispエラーを生じますが、
通常の編集ではそのたびにデバッガに入ったのではとても不便です。
そのため、エラーによってデバッガに入りたい場合には、
変数debug-on-error
にnil
以外を設定します。
(コマンドtoggle-debug-on-error
はこれを簡単に行う。)
debug-on-error | User Option |
この変数は、エラーが通知され処理されないときに
デバッガを呼び出すかどうか決定する。
debug-on-error がt であると、
すべての種類のエラー(debug-ignored-errors に指定したものを除く)
はデバッガを呼び出す。
nil であるとデバッガを呼び出さない。
その値はデバッガを呼び出すエラー条件のリストでもよい。
たとえば、リスト この変数が |
debug-ignored-errors | User Option |
この変数は、デバッガに入らないエラーの種類を指定する。
その値はエラー条件シンボルや正規表現のリストである。
エラーにこれらの条件シンボルが含まれるか
エラーメッセージが正規表現の1つに一致する場合には、
debug-on-error の値に関わらず
当該エラーではデバッガに入らない。
この変数の通常の値は、
編集ではしばしば発生するが、Lispプログラムのバグではほとんど発生しないような
エラー群のリストである。
しかし、『ほとんど』は『けっして』ではない。
このリストに一致するようなエラーで読者のプログラムが失敗する場合、
エラーをデバッグするにはこのリストを変更する必要がある。
もっとも簡単な方法は、 |
debug-on-signal | User Option |
通常、condition-case で捕捉したエラーは、
たとえdebug-on-error がnil 以外であっても、
けっしてデバッガを起動しない。
いいかえれば、デバッガを起動するまえに、
condition-case はエラー処理の機会を得るのである。
警告: 警告: |
ファイル.emacs
をロード中に発生するエラーをデバッグするには、
オプション--debug-init
を使います。
これにより、.emacs
のロード中はdebug-on-error
をt
に束縛し、
初期化ファイルでのエラーを捕捉するcondition-case
を迂回します。
読者のファイル.emacs
でdebug-on-error
を設定しても、
その効果は.emacs
のロードを終ると持続しません。
(これはコマンド行オプション--debug-init
の実装における
好ましくない特性である。)
.emacs
でdebug-on-error
を恒久的に設定する最良の方法は、
つぎのように、after-init-hook
を用いることです。
(add-hook 'after-init-hook '(lambda () (setq debug-on-error t)))
プログラムが無限にループし戻ってこないときには、 まず、ループを停止する必要があります。 ほとんどのオペレーティングシステムでは、 中断を意味するC-gを使います。
普通に中断したのでは、
プログラムが無限ループした理由に関する情報は得られません。
より詳しい情報を得るには、
変数debug-on-quit
にnil
以外を設定します。
C-gによる中断はエラーとは扱わないため、
C-gの処理に関してdebug-on-error
はなんの効果もありません。
同様に、debug-on-quit
はエラーに関してなんの効果もありません。
無限ループの途中でデバッガを起動できれば、 デバッガでステップ実行コマンドを使って先へ進めます。 ループひとまわりをステップ実行すれば、 問題を解決するに十分な情報を得られるはずです。
debug-on-quit | User Option |
この変数は、quit が通知され処理されなかった場合に、
デバッガを呼び出すかどうかを決定する。
debug-on-quit がnil 以外である場合、
(C-gを打って)中断するとデバッガを呼び出す。
debug-on-quit がnil であると、
中断してもデバッガを呼び出さない。
see Quitting。
|
プログラムの途中で発生する問題点を調べるための1つの有用な技法は、 ある関数を呼び出すたびにデバッガに入ることです。 問題を生じる関数に対してこのようにしておき、 当該関数をステップ実行するか、あるいは、 問題が発生する直前に呼ばれる関数に対してこのようにしておき、 その関数の呼び出しを終えてから、呼び出し側をステップ実行します。
debug-on-entry function-name | コマンド |
この関数は、function-nameが呼び出されるたびに
デバッガを起動するようにする。
当該関数の定義の最初のフォームとして
フォーム(debug 'debug) を挿入することでこれを行う。
Lispコードで定義した任意の関数は、 解釈実行コードであろうとコンパイル済みのコードであろうと、 関数に入るときにブレークするようにできる。 関数がコマンドであると、Lispから呼ばれたときや 対話的に呼ばれたときに(引数を読み取ってから)デバッガに入る。 (Cで書いた)基本関数は、この方法ではデバッグできない。
注意: (defun fact (n) (if (zerop n) 1 (* n (fact (1- n))))) => fact (debug-on-entry 'fact) => fact (fact 3) ------ Buffer: *Backtrace* ------ Entering: * fact(3) eval-region(4870 4878 t) byte-code("...") eval-last-sexp(nil) (let ...) eval-insert-last-sexp(nil) * call-interactively(eval-insert-last-sexp) ------ Buffer: *Backtrace* ------ (symbol-function 'fact) => (lambda (n) (debug (quote debug)) (if (zerop n) 1 (* n (fact (1- n))))) |
cancel-debug-on-entry function-name | コマンド |
この関数は、function-nameに対するdebug-on-entry の効果
(呼び出し時にブレークする)を取り消す。
対話的に呼び出すと、
ミニバッファでfunction-nameを問い合わせる。
function-nameがnil であったり空文字列であると、
すべての関数について、呼び出し時にブレークすることを取り消す。
呼び出し時にブレークする設定をしていない関数に対して
|
読者のプログラムに式(debug)
を書くと、
その箇所でデバッガを呼び出すことができます。
つまり、ソースファイルを訪問して適当な箇所にテキスト(debug)
を挿入し、
C-M-xと打ちます。
警告:
一時的なデバッグ目的でこれを行う場合には、
ファイルを保存するまえにこの挿入箇所をもとに戻すこと!
(debug)
を挿入する箇所は、
余分なフォームを評価してもその値を無視できる場所でなければなりません。
((debug)
の値が無視されないと、
プログラムの実行を変えてしまう!)
もっとも適した一般的な場所はprogn
や暗黙のprogn
の内側です
(see Sequencing)。
デバッガに入ると、それまで選択していたバッファをあるウィンドウに、
*Backtrace*
という名前のバッファを別のウィンドウに表示します。
バックトレースバッファでは、各行は現在実行中のLisp関数の各レベルです。
このバッファの先頭には、デバッガを起動するに至った理由
(エラーで起動されたときにはエラーメッセージと関連データ)
を表すメッセージがあります。
バックトレースバッファは読み出し専用であり、 各文字をデバッガコマンドであると定義した 特別なメジャーモード、debuggerモードを使います。 Emacsの通常の編集コマンドも使えます。 したがって、エラー発生時に編集していたバッファを調べるためにウィンドウを 切り替えたり、バッファを切り替えたり、ファイルを訪れたり、 その他のどんな編集でもできます。 しかし、デバッガは再帰編集レベル(see Recursive Editing)であるので、 デバッグを終えるときには、バックトレースバッファに戻ってから デバッガを(コマンドqで)終了するのが賢い方法です。 デバッガを終了すると、再帰編集から抜けバックトレースバッファを削除します。
バックトレースバッファでは、実行中の関数とその引数の値を表示します。 また、スタックフレームを記述する行へポイントを移動することで スタックフレームを指定できます。 (スタックフレームとは、Lispインタープリタが関数の起動に関する情報を 記録しておく場所である。) ポイントがある行に対応するフレームをカレントフレーム(current frame)と 呼びます。 デバッガのある種のコマンドはカレントフレームに作用します。
デバッガ自身はバイトコンパイルしたものを実行する必要があります。 というのは、デバッガ自身が使用するスタックフレームのサイズを 仮定しているからです。 解釈実行だとこの仮定が成り立ちません。
デバッガ内(debuggerモード)では、 通常のカーソル移動コマンドに加えて以下の特別なコマンドを使えます。 (ウィンドウやバッファの切り替えなどのEmacsの通常の機能も使えることに留意。)
デバッガコマンドのもっとも重要な使い方はステップ実行であり、 これにより制御の流れを調べることです。 デバッガは、解釈実行版の関数の制御構造をステップ実行できますが、 バイトコンパイルした関数ではできません。 バイトコンパイルした関数をステップ実行したい場合には、 同じ関数を解釈実行版の定義に置き換える必要があります。 (これには、関数のソースを訪れて、その定義内でC-M-xと打つ。)
debuggerモードのコマンド一覧を以下に示します。
継続が可能なのは、
関数呼び出し時や終了時、明示的な起動、中断によりデバッガに入った場合である。
エラーが原因でデバッガが起動されたときには継続できない。
このようにしてデバッガを起動した関数呼び出しのスタックフレームには
自動的に印が付き、そのスタックから抜けるとデバッガがふたたび呼び出される。
この印を消すにはコマンドuを使う。
*Debugger-record*
での評価結果も保存する。
C-gでデバッガへ入ったが、
実際には中断したいのであってデバッグはしたくない場合には
コマンドqを使う。
(bで指定したりdでフレームに入ることで)
Lispの呼び出しフレームから抜けでたためにデバッガが起動された場合に、
コマンドrは有用である。
コマンドrで指定した値は、当該フレームの値として使われる。
このコマンドは、debug
を呼び出してその戻り値を使う場合にも有用である。
さもなければ、rはcと同じ効果であり、指定した戻り値は関係ない。
エラーでデバッガに入った場合にはrは使えない。
ここでは、デバッガを起動するために使われる関数debug
の詳細を述べます。
debug &rest debugger-args | Function |
この関数はデバッガに入る。
*Backtrace* (あるいはデバッガの第2レベルに再帰的に入ると
*Backtrace*<2> など)という名前のバッファに切り替え、
Lisp関数の呼び出しスタックに関する情報でこのバッファを満たす。
そして再帰編集に入りdebuggerモードのバックトレースバッファを表示する。
debuggerモードのコマンドcやrで再帰編集から抜けだし、
debugger-argsの使い途は、
|
本節では、デバッガが内部的に使用する関数や変数について述べます。
debugger | Variable |
この変数の値は、デバッガを起動するために呼び出す関数である。
その値は、可変個数の引数を取る関数(あるいは典型的には関数名)であること。
その関数でなんらかのデバッガに入ると仮定する。
この変数のデフォルト値はdebug 。
Lispが関数に渡す最初の引数で、呼び出した理由を表す。
引数の規約は |
backtrace | コマンド |
この関数は、現在活性なLisp関数呼び出しのトレースを表示する。
これは、debug がバッファ*Backtrace* を
満たすために用いる関数である。
どの関数呼び出しが活性であるかを
判断するためにスタックを参照する必要があるためCで書いてある。
戻り値はつねにnil 。
以下の例では、Lisp式で明示的に (with-output-to-temp-buffer "backtrace-output" (let ((var 1)) (save-excursion (setq var (eval '(progn (1+ var) (list 'testing (backtrace)))))))) => nil ----------- Buffer: backtrace-output ------------ backtrace() (list ...computing arguments...) (progn ...) eval((progn (1+ var) (list (quote testing) (backtrace)))) (setq ...) (save-excursion ...) (let ...) (with-output-to-temp-buffer ...) eval-region(1973 2142 #<buffer *scratch*>) byte-code("... for eval-print-last-sexp ...") eval-print-last-sexp(nil) * call-interactively(eval-print-last-sexp) ----------- Buffer: backtrace-output ------------ 文字 |
debug-on-next-call | Variable |
この変数がnil 以外であると、
つぎにeval 、apply 、funcall を呼び出すまえに
デバッガを呼び出すことを指定する。
デバッガに入るとdebug-on-next-call をnil に設定する。
デバッガのコマンドdは、この変数を設定することで動作する。 |
backtrace-debug level flag | Function |
この関数は、levelの深さのスタックフレームに
値flagに応じてフレームから抜け出るときのデバッガ呼び出しの印を付ける。
flagがnil 以外であると、
のちに当該フレームから抜けるとデバッガに入る。
非ローカルな脱出で当該フレームから抜けるときにもデバッガに入る。
この関数はデバッガのみが使用する。 |
command-debug-status | Variable |
この変数は、現在の対話的コマンドのデバッグ状況を記録する。
コマンドが対話的に呼び出されるたびに、
この変数はnil に束縛される。
デバッガはこの変数に設定することで、
同じコマンドの起動中にデバッガが将来起動された場合に備えて
情報を残すことができる。
デバッガにとっては、通常のグローバル変数ではなくこの変数を使う利点は、 以降のコマンド起動にデータが繰り越さないことである。 |
backtrace-frame frame-number | Function |
関数backtrace-frame は、Lispデバッガで使うことを意図している。
深さframe-numberのスタックフレームで進行中の計算に関する情報を返す。
当該フレームで引数の評価を完了していなければ(あるいはスペシャルフォーム)、
値は 当該フレームで引数の評価を完了し関数を呼び出していれば、
値は 戻り値において、functionは評価したリストのCARであるか、
マクロ呼び出しでは frame-numberが範囲外であると、 |
edebugはEmacs Lispプログラムのソースレベルデバッガであり、 つぎのことを行えます。
以下の最初の3つの節では、edebugを使うのに十分な情報を与えます。
edebugでLispプログラムをデバッグするには、
デバッグしたいLispコードをまず処置(instrument)しておく必要があります。
これを行う簡単な方法は、関数やマクロの定義にポイントを移動してから、
C-u C-M-x(前置引数を指定したeval-defun
)を実行します。
コードを処置する別の方法については、See Instrumenting。
関数をいったん処置しておけば、当該関数を呼び出すとedebugを活性にします。 edebugが活性になると実行を停止し、 読者が選択したedebugの実行モードに応じて、 関数をステップ実行したりデバッグコマンドを検査しながら 表示を更新しつつ実行を継続します。 デフォルトの実行モードはステップ実行であり、 いったん実行を停止します。 See Edebug Execution Modes。
edebugでは、デバッグ中のLispコードのソースを 表示したEmacsバッファを読者は見ます。 このバッファをソースコードバッファと呼びます。 このバッファは一時的に読み出し専用です。
左端の矢印は、関数の実行中の行を表します。 ポイントの初期位置は関数の実行中の行にありますが、 読者自身がポイントを移動すると変わります。
(以下の)fac
の定義を処置してから(fac 3)
を実行したとすると、
つぎのようになります。
ポイントはif
のまえの開き括弧にあります。
(defun fac (n) =>-!-(if (< 0 n) (* n (fac (1- n))) 1))
edebugが関数内で実行を停止できる箇所を停止位置(stop point)と呼びます。
これらは、リストである各部分式の前後と各変数参照のうしろにあります。
関数fac
の中にある停止位置をピリオドで示します。
(defun fac (n) .(if .(< 0 n.). .(* n. .(fac (1- n.).).). 1).)
ソースコードバッファでは、Emacsのlispモードのコマンドに加えて
edebugの特別なコマンドを使えます。
たとえば、つぎの停止位置まで実行するには
edebugコマンド<SPC>を打ちます。
fac
に入ったあとで<SPC>を1回打つと、
つぎのような表示になります。
(defun fac (n) =>(if -!-(< 0 n) (* n (fac (1- n))) 1))
式のうしろでedebugが実行を停止すると、 式の値をエコー領域に値を表示します。
多用される他のコマンドには、 停止位置にブレークポイントを設定するb、 ブレークポイントに達するまで実行するg、 edebugを終了してトップレベルのコマンドループへ戻るqがあります。 edebugのコマンド一覧を表示するには?を打ちます。
Lispコードのデバッグにedebugを使うためには、 コードをまず処置する必要があります。 コードを処置すると、適当な箇所でedebugを起動する追加のコードを挿入します。
いったん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-region
、eval-current-buffer
、eval-buffer
も
それらが評価する定義を処置します。
同様に、edebug-all-forms
は、
定義以外のフォームであってもeval-region
が
任意のフォームを処置するかどうか制御します。
これは、ミニバッファでのロードや評価には適用されません。
コマンドM-x edebug-all-formsはこのオプションをトグルします。
別のコマンドM-x edebug-eval-top-level-formは、
edebug-all-defs
とedebug-all-forms
の値に関わらず
任意のトップレベルのフォームを処置するために使えます。
edebugが動作中は、
コマンドI(edebug-instrument-callee
)で、
ポイントのうしろのフォームから呼ばれる関数やマクロの定義を
処置済みでなければ処置できます。
これは、edebugが当該関数のソースを探せる場合にのみ可能です。
edebugをロード後には、
eval-region
は、処置していないものも含めて、
評価した各定義の位置を記録しています。
関数を処置後に呼び出してステップ実行する
コマンドi(see Jumping)も参照してください。
edebugは、標準のスペシャルフォームすべて、
式を引数とするinteractive
フォーム、
無名ラムダ式、他の定義フォームをどのように処置するかわかっています。
edebugは、マクロ呼び出しを引数に持つユーザー定義マクロをどのように
処置すべきかわかりませんから、読者がそれを指示する必要があります。
詳しくは、See Instrumenting Macro Calls。
edebugは、あるセッションで初めてコードを処置する場合、
フックedebug-setup-hook
を実行してから
それにnil
を設定します。
これを利用すると、読者が使用するパッケージに対応した
edebug用仕様(see Instrumenting Macro Calls)を
edebugを使用する場合にのみロードするようにできます。
定義から処置を取り除くには、
処置しないような方法でその定義を単に再評価するだけです。
けっして処置せずにフォームを評価する方法は2つあります。
ファイルをload
するか、
ミニバッファでeval-expression
(M-:)を使います。
edebugが処置中に構文エラーを検出すると、
コードのエラー箇所にポイントを置いて、
エラーinvalid-read-syntax
を通知します。
edebugの内側で使える他の評価関数についてはSee Edebug Eval。
edebugには読者がデバッグしているプログラムを実行するための 実行モードが複数あります。 これらをedebugの実行モードと呼びます。 これらをメジャーモードやマイナモードと混同しないでください。 edebugの実行モードは、停止するまでにどの程度edebugが実行を継続するか、 たとえば、各停止位置で停止するのかつぎのブレークポイントまで継続するのか、 また、停止するまでに評価の進行状況をどの程度edebugが表示するのかを 決定します。
通常、あるモードにおいて、 プログラムを継続するコマンドを打つことでedebugの実行モードを指定します。 以下にそれらのコマンドの一覧を示します。 Sを除くすべてのコマンドは、 少なくともある程度プログラムの実行を再開します。
プログラムをいっさい実行せずに、
edebugコマンドの入力を待つ(edebug-stop
)。
つぎに出会う停止位置で止まる(edebug-step-mode
)。
式のうしろでつぎに出会う停止位置で止まる
(edebug-next-mode
)。
Edebug Miscのedebug-forward-sexp
も参照。
edebugの各停止位置で1秒間休止する
(edebug-trace-mode
)。
各停止位置で表示を更新するが休止しない
(edebug-Trace-fast-mode
)。
つぎのブレークポイントまで実行する
(edebug-go-mode
)。
see Breakpoints。
各ブレークポイントで1秒間休止してから継続する
(edebug-continue-mode
)。
各ブレークポイントへポイントを移動するが休止しない
(edebug-Continue-fast-mode
)。
ブレークポイントを無視する
(edebug-Go-nonstop-mode
)。
Sや編集コマンドを打てば停止できる。
一般に、上記一覧の上にある実行モードほど下にあるものに比べると プログラムをゆっくり実行、つまり、早く停止します。
実行中やトレース中には、edebugコマンドをなにか打てば実行に割り込めます。 edebugはつぎの停止位置でプログラムを止め、 読者が打ったコマンドを実行します。 たとえば、実行中にtを打てば、つぎの停止位置でトレースモードに 切り替わります。 単に実行を停止するにはSを使います。
読者の関数が入力を読み取る場合、実行に割り込むつもりで打った文字を 関数が読み取ってしまうかもしれません。 読者のプログラムがいつ入力するかに注意していれば、 このような意図しない結果を避けることができます。
本節で述べたコマンドを含むキーボードマクロは動作しません。
つまり、プログラムを再開するためにedebugから抜けると
キーボードマクロの制御を失ってしまいます。
これを修正するのは簡単ではありません。
また、edebugの外側でキーボードマクロを定義したり実行しても、
edebug内のコマンドにはなんの影響もありません。
これは普通は利点です。
しかし、オプションedebug-continue-kbd-macro
(see Edebug Options)も参照してください。
edebugの新たなレベルに入ると、変数edebug-initial-mode
の値を
実行モードの初期値とします。
デフォルトでは、これはステップ実行モードを指定します。
処置した関数を1つのコマンドから複数回呼び出すなどして
edebugの同一レベルに再度入ることができることに注意してください。
本節で述べるコマンドは、指定した位置に達するまで実行します。 iを除くすべてのものは、停止する場所に一時的なブレークポイントを 設定してから実行モードに移行します。 意図したブレークポイントより先に別のブレークポイントに達しても 実行を停止します。 ブレークポイントについて詳しくはSee Breakpoints。
非ローカル脱出は、読者が意図したプログラムの停止すべき 一時的なブレークポイントを迂回するため、 これらのコマンドは非ローカル脱出があると意図したように動作しません。
edebug-goto-here
)。
edebug-forward-sexp
)。
コマンドhは、一時的なブレークポイントを使って、 ポイント位置付近の停止位置まで進みます。 ブレークポイントについて詳しくはSee Breakpoints。
コマンドfは、プログラムの式1つ分先へ進みます。 より正確には、C-M-fによる移動箇所へ一時的なブレークポイントを設定し、 プログラムがブレークポイントで停止するような実行モードで実行します。
前置引数nを指定すると、 ポイント位置からn個先のS式に一時的なブレークポイントを設定します。 囲んでいるリストの残り要素数がnより少なければ、 囲んでいる式の末尾で停止します。
C-M-fの移動先はプログラムが実際に停止するであろう箇所です。
これが正しくない場合もあり、たとえば、cond
では正しくありません。
コマンドfは、柔軟性のために、
停止位置ではなくポイント位置でforward-sexp
を使います。
現在の停止位置から式1つだけ実行したい場合には、
まずwと打ってポイントを停止位置に移動してからfを打ちます。
コマンドoは式から『出る』まで実行します。 ポイントを含むS式の末尾に一時的なブレークポイントを置きます。 このS式が関数定義そのものである場合には、 oは定義の最後のS式の手前まで実行します。 現在この箇所にいた場合には、関数から戻ってから停止します。 いいかえれば、最後のS式のあとに位置していない限り、 このコマンドは現在実行中の関数から抜けません。
コマンドiは、 ポイント位置のあとにあるリストフォームから呼ばれる関数やマクロへ進み、 最初に出会った停止位置で止まります。 そのフォームはこれから評価されるフォームである必要はありません。 しかし、評価されるフォームが関数呼び出しである場合には、 引数を評価するまえにこのコマンドを使うことを覚えておいてください。 さもないとこのコマンドを使う時期が遅すぎます。
コマンドiは、呼び出す関数やマクロが処置されていないと それらを処置します。 これは便利ですが、それらの関数やマクロは、明示的に処置を取り除かない限り、 処置したままになります。
edebugの他のコマンドを以下に示します。
edebug-help
)。
abort-recursive-edit
)。
top-level
)。
edebugのすべての動作中のレベルを含めて、すべての再帰編集レベルから抜ける。
しかし、フォームunwind-protect
やcondition-case
で保護した
処置済みのコードがあるとデバッガを再開する。
top-level-nonstop
)。
edebug-previous-result
)。
edebug-backtrace
)。
edebugのバックトレースバッファでは、 標準のデバッガのようにはデバッガのコマンドを使えない。
実行を継続するとバックトレースバッファは自動的に削除される。
edebugの再帰編集から、edebugを再帰的に活性にするコマンドを起動できます。 edebugが活性であるときにはいつでもqでトップレベルへ戻るか、 C-]で1つの再帰編集レベルを抜けることができます。 保留している評価すべてのバックトレースはdで表示できます。
edebugのステップ実行モードは、つぎの停止位置に達すると実行を停止します。 edebugが実行を止める方法は3つあります。 ブレークポイント、グローバルブレーク条件、ソースのブレークポイントです。
edebugを使用中には、読者がテスト中のプログラムにブレークポイント (breakpoint)、つまり、実行を停止すべき箇所を設定できます。 Using Edebugで定義した任意の停止位置にブレークポイントを設定できます。 ブレークポイントの設定や解除において対象となる停止位置は、 ソースコードバッファのポイント位置かそのあとにある停止位置です。 ブレークポイントに関するedebugコマンドはつぎのとおりです。
edebug-set-breakpoint
)。
前置引数を指定すると、一時的なブレークポイントになる
(そこでプログラムが停止すると解除される)。
edebug-unset-breakpoint
)。
nil
以外の値に評価される場合にのみ
プログラムを停止する条件付きブレークポイントを設定する
(edebug-set-conditional-breakpoint
)。
前置引数を指定すると、一時的なブレークポイントになる。
edebug-next-breakpoint
)。
edebug内では、bでブレークポイントを設定し、 uで解除できます。 まず目的のedegugの停止位置にポイント位置を移動し、 bを打ってその箇所にブレークポイントを設定したり、 uを打ってその箇所のブレークポイントを解除します。 設定されていないブレークポイントを解除しても、なにも起こりません。
定義を再評価したり再処置すると、その中のブレークポイントすべてを解除します。
条件付きブレークポイント(conditional breakpoint)は、
プログラムがこの箇所に達するたびに条件を検査します。
条件を評価中に発生するどんなエラーも無視し、
nil
として扱います。
条件付きブレークポイントを設定するにはxを使い、
条件式はミニバッファで指定します。
すでに条件付きブレークポイントを設定してある停止位置に
条件付きブレークポイントを設定し直すと、
それまでの条件式がミニバッファに入るので編集できます。
ブレークポイントを設定するコマンドに前置引数を指定すると、 条件付き/無条件ブレークポイントを一時的なものにできます。 一時的ブレークポイントでプログラムが停止すると、 そのブレークポイントは自動的に解除されます。
edebugのモードが非停止実行でなければ、 edebugはブレークポイントでつねに停止するか休止します。 非停止実行モードでは、ブレークポイントを完全に無視します。
ブレークポイントの場所を確認するには、コマンドBを使います。 同じ関数内のポイント箇所のうしろにあるブレークポイントか、 後続のものがなければ最初のブレークポイントにポイント位置を移動します。 このコマンドは実行を継続しません。 バッファ内で単にポイントを移動するだけです。
グローバルブレーク条件(global break condition)は、
指定した条件が満たされると、その場所に関わらず、実行を停止させます。
edebugは各停止位置においてグローバルブレーク条件を評価します。
これがnil
以外の値であると、
ブレークポイントに達したかのように、
実行モードに依存して実行を停止するか休止します。
条件の評価中にエラーが発生しても実行は停止しません。
条件式はedebug-global-break-condition
に保存されます。
コマンドXで新たな条件式を指定できます
(edebug-set-global-break-condition
)。
グローバルブレーク条件は、読者のコードのどこでイベントが発生するかを
調べるもっとも簡単な方法ですが、コードの実行速度をかなり遅くします。
ですから、使用しない場合には条件をnil
に再設定すべきです。
定義内のすべてのブレークポイントは、定義を処置し直すたびに失われます。
ブレークポイントを失いたくない場合には、
ソース上のブレークポイント(source breakpoint)を指定できます。
これはソースコード上で関数edebug
を呼び出すだけです。
もちろん、条件付けして呼び出せます。
たとえば、関数fac
において、引数がゼロの場合に停止するには、
以下に示すように最初の行を挿入します。
(defun fac (n) (if (= n 0) (edebug)) (if (< 0 n) (* n (fac (1- n))) 1))
関数fac
を処置してこの関数を呼び出すと、
edebug
の呼び出しはブレークポイントのように動作します。
実行モードに応じて、edebugはその箇所で停止するか休止します。
edebug
を呼び出したコードが処置済みでなければ、
この関数はdebug
を呼び出します。
Emacsは、通常、エラーが通知されてもcondition-case
で処理されなかった
場合、エラーメッセージを表示します。
edebugが活性であり処置済みのコードを実行していると、
edebugは処理されなかったエラーすべてに反応します。
この動作をedebug-on-error
とedebug-on-quit
で
カスタマイズできます。
See Edebug Options。
edebugがエラーに反応すると、 エラーを起こすまえ出会った最後の停止位置を表示します。 この位置は、実際にエラーを起こした処置してない関数の呼び出し位置である 場合もあります。 未束縛な変数のエラーでは、最後の停止位置は、 当該変数の参照位置からかなり離れている場合があります。 そのような場合には、完全なバックトレースを表示したいでしょう (see Edebug Misc)。
edebugが活性なときにdebug-on-error
やdebug-on-quit
を変更しても、
edebugが不活性になったときにそれらの変更を取り消してしまいます。
さらに、edebugの再帰編集中は、これらの変数はedebugの外側での値に
束縛されます。
これらのedebugのコマンドは、edebugに入るまえのバッファやウィンドウの 状態を調べるものです。 外部ウィンドウ構成は、edebugの外側でのウィンドウの集まりや内容に 関するものです。
edebug-view-outside
)。
edebug-bounce-point
)。
前置引数nは、かわりに休止秒数を指定する。
edebug-where
)。
同じバッファを表示している別のウィンドウでこのコマンドを使うと、
それ以後、そのウィンドウに現在の定義が表示されるようになる。
edebug-toggle-save-windows
)。
前置引数を指定すると選択したウィンドウだけの保存/復元をトグルする。 ソースコードバッファを表示していないウィンドウを指定するには、 グローバルキーマップのC-x X Wを使う必要がある。
vで外部ウィンドウ構成を見ることができます。 あるいは、(edebugの外側での)カレントバッファが表示されていなくても pでカレントバッファのポイント位置を見ることができます。 ポイント位置を移動したら、 wでソースコードバッファの停止位置へ戻れます。
外部ウィンドウ構成を保存しないようにWを使うたびに、
edebugは保存しておいた外部ウィンドウ構成を破棄します。
そのため、保存するように戻しても、
(プログラムを続行することで)edebugを抜けると、
現在のウィンドウ構成は変更されません。
しかし、*edebug*
と*edebug-trace*
の自動再表示は、
十分なウィンドウが開いてないと、
読者が見たいバッファと衝突するかもしれません。
edebugの内側では、edebugが動作していないがごとく式を評価できます。 edebugは、式の評価と表示に対して見えないようにします。 edebugが明示的に保存/復元する場合を除いて、 副作用を持つ式の評価も期待どおり動作します。 この処理に関して詳しくはSee The Outside Context。
edebug-eval-expression
)。
つまり、edebugは評価への干渉を最小限にとどめようとする。
edebug-eval-last-sexp
)。
edebugはcl.el
(版2.03以降)内の構文
lexical-let
、macrolet
、symbol-macrolet
で
作成されるレキシカル(テキスト上の)束縛を参照する式の評価を扱えます。
*edebug*
と呼ばれる評価リストバッファを使って、
式を対話的に評価できます。
さらに、edebugが表示を更新するたびに自動的に評価される
式の評価リストを設定することもできます。
*edebug*
へ切り替える
(edebug-visit-eval-list
)。
バッファ*edebug*
では、以下の特別なコマンドに加えて
lisp対話モード
(see Lisp Interaction)
のコマンドも使えます。
edebug-eval-print-last-sexp
)。
edebug-eval-last-sexp
)。
edebug-update-eval-list
)。
edebug-delete-eval-item
)。
edebug-where
)。
*scratch*
で行うのと同様に、
評価リストウィンドウではC-jやC-x C-eで式を評価できますが、
それらはedebugの外側の文脈で評価されます。
実行を継続すると、対話的に入力した式(やその結果)は破棄されますが、 実行を停止するたびに評価される式から成る評価リスト(evaluation list) を設定できます。
これを行うには、評価リストバッファにて、 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*
は削除され、
つぎに必要なときに再度作成されます。
読者のプログラムの式が循環したリスト構造を含む値を作り出す場合、 edebugがそれを出力しようとするとエラーになります。
循環構造を扱う1つの方法は、出力を切り詰めるために
print-length
やprint-level
を設定することです。
edebugが読者のためにこれを行います。
それらがnil
であると、
edebugはprint-length
とprint-level
を50に束縛します。
(実際は、edebugが使う値は
e-debug-print-length
とe-debug-print-level
が指定する。)
See Output Variables。
edebug-print-length | User Option |
nil 以外であると、edebugが結果を出力するときには、
これをprint-length に束縛する。
デフォルト値は50 。
|
edebug-print-level | User Option |
nil 以外であると、edebugが結果を出力するときには、
これをprint-level に束縛する。
デフォルト値は50 。
|
パッケージcust-print
を使えば、
循環構造や要素を共有する構造をより的確に出力することもできます。
cust-print
をロードしてedebugでのみこの特別な出力を使うようにするには、
単にコマンドM-x edebug-install-custom-printを使うだけです。
標準の出力関数に戻すには、M-x edebug-uninstall-custom-printを使います。
循環構造を作るコードの例を示します。
(setq a '(x y)) (setcar a a)
特別な出力ではこれをResult: #1=(#1# y)
と出力します。
#1=
の記法は、これに続く構造に1
というラベルを付けます。
また、#1#
の記法はすでにラベル付けした構造を参照します。
この記法は、リストやベクトルの任意の共有された要素に使われます。
edebug-print-circle | User Option |
nil 以外であると、edebugが結果を出力するときには、
これをprint-circle に束縛する。
デフォルト値はnil 。
|
他のプログラムでもこの特別な出力を使えます。
詳しくは、cust-print.el
を参照してください。
edebugは、実行トレースを*edebug-trace*
というバッファに保存することで
それらを記録できます。
これは、関数名とそれらの引数、戻り値から成る
関数呼び出しとその戻りの記録です。
トレース記録を有効にするには、
edebug-trace
にnil
以外の値を設定します。
トレースバッファを作成することとトレース実行モードとは 同じではありません(see Edebug Execution Modes)。
トレース記録を有効にしていると、
各関数へ入るときと出るときに、トレースバッファに行が追加されます。
関数へ入るときの記録は、::::{
に関数名と引数値が続きます。
関数から出るときの記録は、::::}
に関数名とその結果が続きます。
入るときの:
の個数は、再帰の深さを表します。
関数呼び出しの対応する開始や対応する終了を探すために
トレースバッファでは中括弧を使えます。
関数edebug-print-trace-before
とedebug-print-trace-after
を
再定義すれば、関数へ入ったときと出るときのトレース記録をカスタマイズできます。
edebug-tracing string body... | Macro |
このマクロはフォームbodyの周りにトレース情報を追加する。
引数stringは、トレースバッファに入れるテキストを指定する。
すべての引数を評価する。
edebug-tracing はbodyの最後のフォームの値を返す。
|
edebug-trace format-string &rest format-args | Function |
この関数はトレースバッファにテキストを挿入する。
テキストは(apply 'format format-string format-args) で
計算する。
区切りとして改行も挿入する。
|
edebug-tracing
とedebug-trace
は、
edebugが活性でない場合であっても呼ばれるとトレースバッファに行を挿入します。
トレースバッファにテキストを挿入するとき、
挿入した最後の行が見えるようにウィンドウをスクロールします。
edebugでは、初歩的なカバレッジテストや実行頻度を表示できます。
カバレッジテストでは、各式の結果を以前の結果と比較します。 現在のEmacsセッションでカバレッジテストを始めて以降、 プログラムの各フォームが異なる2つの値を返せば、 当該フォームを『カバーした』とみなします。 したがって、読者のプログラムについてカバレッジテストを行うには、 さまざまな条件でそれを実行して正しく動作しているか注意します。 読者が各フォームが異なる2つの値を返すように試行し終れば、 edebugはそのように通知します。
カバレッジテストは実行速度を遅くするので、
edebug-test-coverage
がnil
以外の場合にのみテストします。
すべての処置済み関数の実行に関する頻度数計測は、
非停止実行モードであってもカバレッジテストのオン/オフに関わらず行います。
ある定義に関するカバレッジテストと頻度数計測を表示するには M-x edebug-display-freq-countを使います。
edebug-display-freq-count | コマンド |
このコマンドは、現在の定義の各行について頻度数データを表示する。
頻度数は、コードの各行のあとにコメント行として表示され、
コマンド 式の頻度数に続く文字 ある定義に関する頻度数計測とカバレッジデータをクリアするには、
|
たとえば、edebug-test-coverage
をt
とし、
ソース上のブレークポイントを設定して(fac 5)
を評価すると、
ブレークポイントに達したときの頻度数データはつぎのようになります。
(defun fac (n) (if (= n 0) (edebug)) ;#6 1 0 =5 (if (< 0 n) ;#5 = (* n (fac (1- n))) ;# 5 0 1)) ;# 0
コメント行は、fac
が6回呼ばれたことを表します。
最初のif
文は、5回とも同じ結果を返したのです。
2番目のif
についても同じです。
fac
の再帰呼び出しは1度も戻っていません。
edebugは、読者がデバッグ中のプログラムに対しては透過であるように努めますが、 完全にうまくいくとは限りません。 また、eで読者が式を評価するときや評価リストバッファでも、 外側の文脈を一時的に復元して透過であるように努めます。 本節では、edebugが復元する文脈について正確に説明し、 edebugが透過にならない場合についても説明します。
edebugに入ると、トレース情報を作るのかプログラムを停止するのかを 決定するまえであってもある種のデータを保存/復元する必要が つねにあります。
max-lisp-eval-depth
とmax-specpdl-size
を一度増加する。
しかし、こうしてもedebugを使うときにスタックを使い切ってしまうことがある。
executing-macro
は
edebug-continue-kbd-macro
に束縛される。
edebugが(トレースモードなどで)なにかを表示する必要があると、 edebugの『外側』の現在のウィンドウ構成を保存します (see Window Configurations)。 (プログラムを続行して)edebugを抜けるときには、 以前のウィンドウ構成を復元します
Emacsは休止するときにのみ表示を更新します。 通常、プログラムを続行しても、休止したり入力を読むことなく ブレークポイントやステップ実行によりedebugへ戻ります。 そのような場合、Emacsには(edebugの)『外側』のようすを再表示する 機会が与えられません。 見かけ上、ウィンドウの表示は直前にedebugが活性であったときと同じになります。
なにかを表示するためにedebugに入っても以下のデータを保存/復元しますが、 エラーや中断が起こると、故意に復元しないものもあります。
edebug-save-windows
がnil
以外ならば、
外側でのウィンドウ構成を保存/復元する
(see Edebug Display Update)。
エラーや中断が起こるとウィンドウ構成は復元されない。
しかし、save-excursion
を使っていれば、
エラーや中断が起こっても、
外側で選択していたウィンドウは選択される。
edebug-save-windows
の値がリストであると、
リストに指定したウィンドウのみを保存/復元する。
ソースコードバッファのウィンドウ開始位置やスクロールは復元しないが、 これは、edebug内での表示が統一されるようにするためである。
edebug-save-displayed-buffer-points
がnil
以外であれば、
表示されている各バッファのポイント位置の値を保存/復元する。
overlay-arrow-position
とoverlay-arrow-string
は、
保存/復元される。
そのため、同じバッファで再帰編集からedebugを起動しても安全である。
cursor-in-echo-area
はnil
にローカルに束縛する。
edebugに入ってユーザーコマンドを読み取るとき、 以下のデータを保存し(のちに復元し)ます。
last-command
、this-command
、last-command-char
、
last-input-char
、last-input-event
、
last-command-event
、last-event-frame
、
last-nonmenu-event
、track-mouse
。
edebug内で使ったコマンドは、edebugの外側でのこれらの変数には影響しない。
this-command-keys
が返すキー列は
edebug内でコマンドを実行すると変更されてしまい、
Lispからキー列を設定し直す方法はない。
edebugはunread-command-events
の値を保存/復元できない。
この変数に変な値が入っているときにedebugに入ると、
読者がデバッグするプログラムの実行に干渉することがある。
command-history
に追加される。
これにより実行結果を変更することはほとんどない。
recursive-edit
は
standard-output
とstandard-input
をnil
に束縛するが、
edebugは評価中にはそれらを一時的に復元する。
defining-kbd-macro
は
edebug-continue-kbd-macro
に束縛される。
edebugがLispマクロを呼び出す式を処置するとき、 それを正しく行うにはマクロに関する余分な情報を必要とします。 マクロ呼び出しのどの部分式が評価されるフォームであるかを 明確に判定する方法がないからです。 (マクロ本体で明示的に評価されるか、 結果の展開形が評価されるときか、あるいは、さらにあと)
したがって、edebugが出会う各マクロについて、
当該マクロの呼び出し形式を記述するedebug用仕様を定義する必要があります。
これには、def-edebug-spec
を使います。
def-edebug-spec macro specification | マクロ |
マクロmacroの呼び出しのどの式が評価されるかを指定する。
単純なマクロでは、specificationは
マクロ定義の仮引数リストに似ているが、
その指定はマクロ引数よりも汎用性がある。
引数macroはマクロ名だけでなく任意のシンボルでよい。 |
例題マクロfor
(see Argument Evaluation)の
edebug用仕様の等価な定義例2つを示します。
(def-edebug-spec for (symbolp "from" form "to" form "do" &rest form)) (def-edebug-spec for (symbolp ['from form] ['to form] ['do body]))
specificationに指定するものとその引数の処理方法は次表のとおりです。
t
0
マクロ呼び出しの引数のあるものは評価し別のものは評価しない場合には、
edebug用仕様に仕様リスト(specification list)が必要になります。
複数の引数に一致する仕様リストの要素もありますが、
後続の要素の処理を修飾する要素もあります。
後者は仕様キーワード(specification keyword)と呼ばれ、
(&optional
のように)&
で始まるシンボルです。
仕様リストには、それ自体がリストである引数に一致する部分リストや グループ化に使うベクトルを含んでもかまいません。 部分リストやグループは仕様リストを階層に分けます。 仕様キーワードはそれらを含む部分リストやグループの残りに適用されます。
仕様リストに選択肢や繰り返しが含まれる場合、 実際のマクロ呼び出しに一致させるにはバックトラックが必要な場合もあります。 詳しくはSee Backtracking。
edebug用仕様では、正規表現による一致と文脈自由文法の構文を使えます。 対応した括弧に囲まれた部分リスト、フォームの再帰的処理、 間接仕様による再帰です。
仕様リストの要素に指定できるものとそれらの意味を以下に示します。
sexp
form
place
setf
構文のように値を格納する場所。
body
&rest form
の省略形。
以下の&rest
を参照。
function-form
function
ではなくquote
でクォートされるときに有用である。
というのは、ラムダ式の本体をいずれかの方法で処置するからである。
lambda-expr
&optional
数個の省略可能な要素に省略不可な要素を続けるには、
[&optional specs...]
を使う。
数個の要素がすべて一致するかまったく一致しないことを指定するには、
&optional [specs...]
を使う。
以下のdefun
の例を参照。
&rest
数個の要素のみを繰り返すには[&rest specs...]
を使う。
各繰り返しですべてが一致するような数個の要素を指定するには、
&rest [specs...]
を使う。
&or
&or
は失敗。
&or
に続く各要素は1つの選択肢を表す。
複数の要素を1つの選択肢としてグループにまとめるには、
それらを[...]
で囲む。
¬
&or
を使ったかように後続の要素を選択肢として一致させるが、
どれかが一致すると仕様は失敗。
どれにも一致しなければ、仕様¬
は成功。
&define
&define
はリスト仕様の最初の要素である必要がある。
nil
gate
let
を参照。
その他のシンボル
シンボルにedebug用仕様があれば、
この間接仕様は、シンボルのかわりに使われる仕様リストであるか、
引数を処理するために呼び出される関数であること。
仕様は、マクロ向けにdef-edebug-spec
で定義した仕様であってもよい。
以下のdefun
の例を参照。
さもなければ、シンボルは述語であること。
述語は引数で呼び出され、述語がnil
を返すと仕様は失敗する。
いずれの場合でも、当該引数は処置されない。
適当な述語には、symbolp
、integerp
、
stringp
、vectorp
、atom
がある。
[elements...]
"string"
'symbol
と等価であるが、
文字列のほうが望ましい。
(vector elements...)
(elements...)
部分リスト仕様はドット対リストでもよく、その場合、
対応するリスト引数はドット対リストである。
あるいは、ドット対リスト仕様の最後のCDRは
((spec . [(more specs...)])
などの
グループや間接仕様を介した)
別の部分リスト仕様であってもよいが、
それらの要素はドット対ではないリスト引数に一致する。
これは、以下のバッククォートの例のような再帰仕様に有用である。
このような再帰を終らせるうえの仕様nil
も参照。
(specs . nil)
や
(specs . (sublist-elements...))
のような部分リスト仕様は
(specs sublist-elements...)
と等価であることに注意。
&define
のうしろに追加できる仕様の一覧を以下に示します。
以下のdefun
の例を参照してください。
name
定義フォームには単一の名前フィールドがある必要はなく、
複数の名前フィールドを持っていてもよい。
:name
:name
に続く要素はシンボルであること。
定義に対する追加の名前要素として使う。
定義の名前に一意で静的な要素を追加するために使う。
複数あってもよい。
arg
&
で始まるシンボル)は許されない。
lambda-list
def-body
body
に似ているが、
定義本体は定義に関連した情報を調べる異なるedebug呼び出しで処置する必要がある。
定義内のフォームの最上位レベルのリストにはdef-body
を使う。
def-form
def-body
に似ているが、
フォームのリストではなく単一のフォームに一致するものに使う。
特別な場合として、def-form
は
フォームを実行したときにトレース情報を出力しないことを意味する。
以下のinteractive
の例を参照。
仕様の一致がある箇所で失敗しても、 必ずしも構文エラーが通知されるとは限りません。 そのかわりに、選択肢すべてを試し尽くすまでバックトラックします。 最終的に、引数リストの各要素は仕様内のいずれかの要素に一致する必要があり、 仕様内の各必須要素はいずれかの引数に一致する必要があります。
構文エラーを検出しても、より高いレベルの選択肢を使い切るまでは報告されず、
実際のエラー箇所から離れた箇所にポイントが置かれます。
しかし、エラー発生時にバックトラックが禁止されていれば、
ただちにエラーが報告されます。
さまざまな状況でバックトラックが自動的に再許可されることに注意してください。
&optional
や&rest
や&or
で新たに選択肢が指定されたり、
部分リストやグループや間接仕様を処理し始めると、
自動的に再許可されます。
バックトラックの許可/禁止の効果は、
現在処理しているレベルやそれより低いレベルに限定されます。
任意のフォーム仕様(つまり、form
、body
、def-form
、
def-body
)の一致処理中には、バックトラックを禁止します。
これらの仕様は任意のフォームに一致するので、
エラーはより上のレベルではなくフォーム自身にあるはずです。
また、クォートしたシンボルや文字列の仕様に一致すると
バックトラックを禁止します。
というのは、通常、これは構造を認識したことを意味するからです。
しかし、すべてが同一シンボルで始まる選択肢を指定する場合には、
["foo" &or [first case] [second case] ...]
のように、
そのシンボルを選択肢から括り出せばバックトラックするようにできます。
多くの場合では、バックトラックを自動的に禁止するこれらの2つの方法で十分ですが、
仕様gate
を使ってバックトラックを明示的に禁止すると有用な場合もあります。
上位の選択肢が適用できないとわかっている場合に有用です。
仕様let
の例を参照してください。
以下の例を参考にするとedebug用仕様を理解しやすいでしょう。
スペシャルフォームlet
には束縛と本体の並びがあります。
各束縛は、シンボル、あるいは、シンボルと省略可能な式から成る部分リストです。
以下のedebug用仕様では、部分リストの内側にあるgate
で、
部分リストを一度みつけるとバックトラックを禁止していることに
注意してください。
(def-edebug-spec let ((&rest &or symbolp (gate symbolp &optional form)) body))
edebugは、defun
とdefmacro
、
および、対応する引数リストと仕様interactive
に対しては、
以下のedebug用仕様を使います。
式の引数は実際には関数本体の外側で評価されるので、
対話宣言フォームを特別扱いする必要があります。
(def-edebug-spec defmacro defun) ; 仕様defun
の間接参照 (def-edebug-spec defun (&define name lambda-list [&optional stringp] ; あれば、説明文字列に一致する [&optional ("interactive" interactive)] def-body)) (def-edebug-spec lambda-list (([&rest arg] [&optional ["&optional" arg &rest arg]] &optional ["&rest" arg] ))) (def-edebug-spec interactive (&optional &or stringp def-form)) ;def-form
を参照
以下のバッククォートに対する仕様は、
ドット対リストの一致の仕方と再帰を終らせるnil
の使い方を示します。
また、ベクトルの要素の一致の仕方も示します。
(edebugが実際に定義している仕様では、
失敗の可能性がある非常に深い再帰をもたらすためドット対リストを扱わない。)
(def-edebug-spec ` (backquote-form)) ; わかりやすいように別名を付ける (def-edebug-spec backquote-form (&or ([&or "," ",@"] &or ("quote" backquote-form) form) (backquote-form . [&or nil backquote-form]) (vector &rest backquote-form) sexp))
以下のオプションはedebugの動作に影響します。
edebug-setup-hook | User Option |
edebugを使うまえに呼び出す関数群。
新たな値に設定されるたびに、edebugはこれらの関数を呼び出し、
そのあとでedebug-setup-hook をnil に再設定する。
これを用いて、edebugを使用する場合にのみ、
使用するパッケージに対応するedebug用仕様をロードできる。
see Instrumenting。
|
edebug-all-defs | User Option |
これがnil 以外であると、
defun やdefmacro のような定義フォームを普通に評価すると、
edebug用にそれらを処置する。
これは、eval-defun 、eval-region 、eval-buffer 、
eval-current-buffer にも適用される。
このオプションの値をトグルするにはコマンドM-x edebug-all-defsを使う。 see Instrumenting。 |
edebug-all-forms | User Option |
これがcodenil以外であると、コマンドeval-defun 、
eval-region 、eval-buffer 、eval-current-buffer は、
定義しないフォームの場合であってもすべてのフォームを処置する。
これは、ロードやミニバッファでの評価には適用されない。
このオプションの値をトグルするにはコマンドM-x edebug-all-formsを使う。 see Instrumenting。 |
edebug-save-windows | User Option |
これがnil 以外であると、edebugはウィンドウ構成を保存/復元する。
これには時間がかかるので、読者のプログラムがウィンドウ構成に
依存しないのならば、この変数はnil に設定しておくほうがよい。
値がリストであると、リスト内のウィンドウのみを保存/復元する。 edebugのコマンドWを使ってこの変数を対話的に変更できる。 see Edebug Display Update。 |
edebug-save-displayed-buffer-points | User Option |
これがnil 以外であると、edebugは表示されているすべてのバッファの
ポイントを保存/復元する。
選択していないウィンドウに表示されたバッファのポイントを変更する コードをデバッグ中には、別のバッファのポイントを保存/復元する必要がある。 edebugやユーザーが当該ウィンドウを選択すると、 そのバッファのポイントはウィンドウのポイント位置に移動する。 すべてのバッファでポイントを保存/復元するには 各ウィンドウを2度選択する必要があるため手間がかかる。 そのため、必要な場合にのみこの機能を有効にする。 see Edebug Display Update。 |
edebug-initial-mode | User Option |
この変数がnil 以外であれば、
edebugが初めて動作するときの初期の動作モードを指定する。
可能な値は、
step 、next 、go 、Go-nonstop , trace 、
Trace-fast 、continue 、Continue-fast 。
デフォルト値は |
edebug-trace | User Option |
nil 以外であると、関数へ入るときと出るときのトレースを表示することを
意味する。
トレース出力は、*edebug-trace* という名前のバッファに、
関数へ入るときと出るときを各行に再帰の深さで字下げして表示する。
デフォルト値は |
edebug-test-coverage | User Option |
nil 以外であれば、edebugはデバッグ対象のすべての式のカバレッジ
テストを行う。
see Coverage Testing。
|
edebug-continue-kbd-macro | User Option |
nil 以外であれば、
edebugの外側で実行するキーボードマクロを定義したり実行する。
デバッグしないので注意してこのオプションを使うこと。
|
edebug-on-error | User Option |
debug-on-error の以前の値がnil であると、
edebugはdebug-on-error にこの値を束縛する。
see Trapping Errors。
|
edebug-on-quit | User Option |
debug-on-quit の以前の値がnil であると、
edebugはdebug-on-quit にこの値を束縛する。
see Trapping Errors。
|
edebugが動作中にedebug-on-error
やedebug-on-quit
の値を
変更しても、新たなコマンドでedebugをつぎに起動するまでは
これらの値は使用されない。
edebug-global-break-condition | User Option |
nil 以外であると、各停止位置で検査される式である。
結果がnil 以外であるとブレークする。
エラーは無視する。
see Global Break Condition。
|
Lispリーダは不正な構文を報告しますが、どこに問題があるかは報告できません。 たとえば、式を評価中のエラー『End of file during parsing』 (構文解析中にファイルの終り)は、開き括弧(あるいは開き角括弧)が 多すぎることを表します。 Lispリーダは括弧が対応していないことをファイルの末尾で検出しますが、 どこに閉じ括弧があるべきかは判断できません。 同様に、『Invalid read syntax: ")"』(不正な構文:")")は 閉じ括弧が多すぎるか開き括弧が足りないことを表しますが、 どこに括弧が足りないかは判断できません。 それでは、どこを変更すべきかどのように調べるのでしょう?
問題が単純な括弧の非対応でなければ、 各関数定義の先頭でC-M-eを試し、 関数定義の末尾に移動するかどうかをみるのは有用な技法です。 正しく移動しなければ、その関数に問題があります。
Lispによくある構文エラーは括弧の非対応なので、 これらの場面について詳しい助言を述べておきます。 (さらに、対応括弧表示モードをオンにしてポイントを移動すると非対応を 探しやすい。)
最初の手順は、括弧が対応していない関数定義を探すことです。
開き括弧が過剰であれば、ファイルの末尾に閉じ括弧を挿入し
C-M-b(backward-sexp
)を打ちます。
こうすると、括弧が対応していない関数定義の先頭へ移動します。
(そうしたら、C-<SPC> C-_ C-u C-<SPC>と打って、
当該箇所にマークを設定してから閉じ括弧の挿入を取り消し、
最終的にマークへ戻る。)
つぎの手順は、なにが悪いか正確に判断することです。
プログラムを調べる以外にこれを確実に行う方法はありませんが、
しばしば、既存の字下げが括弧のありかたを予想する鍵になります。
これを利用するもっとも簡単な方法はC-M-qで字下げし直し、
どのようになるか見ることです。
まだやらないでください!
まず読み進んてください。
これを行うまえに、関数定義に充分な数の閉じ括弧があることを確認してください。 さもないと、C-M-qがエラーになったり、 ファイルの末尾までを字下げし直してしまいます。 ですから、関数定義の末尾へ移動して閉じ括弧を挿入しておきます。 C-M-eを使って移動しないでください。 というのは、関数定義の括弧の対応が取れていないと失敗するからです。
関数定義の先頭へ移動してC-M-qを打ちます。 通常、ある場所から関数の末尾までの行が右へずれます。 その場所の近くで、閉じ括弧が足りなかったり開き括弧が多すぎるのです。 (しかし、これが正しいと仮定してはならない。 コードを調べて確認すること。) 不具合箇所がみつかったならば、 意図した括弧に対しては古い字下げが適しているでしょうから C-_でC-M-qをアンドゥします。
問題を解決できたと思ったら、再度C-M-qを使います。 古い字下げが意図した括弧の入れ子に対応していて、 必要な括弧を挿入できているならば、 C-M-qはなにも変えないはずです。
過剰な閉じ括弧に対処するには、まず、ファイルの先頭に開き括弧を挿入し、 その括弧のまえでC-M-fを打って、 括弧が対応していない関数定義の末尾を探します。 (そして、C-<SPC> C-_ C-u C-<SPC>と打って、 当該箇所にマークを設定して開き括弧の挿入をアンドゥし、 最終的にマークへ戻る。)
その関数定義の先頭でC-M-fと打って、 実際に対応している閉じ括弧を探します。 これにより、関数定義が終るべき場所より手前の箇所に移動するはずです。 この付近に余分な閉じ括弧がみつかることもあるでしょう。
その場所に問題がなければ、つぎにすべきことは、 関数定義の先頭でC-M-qと打つことです。 ある範囲の行が左にずれるでしょう。 もしそうならば、開き括弧が足りないか余分な閉じ括弧は、 そのような行の先頭付近にあるでしょう。 (しかし、これが正しいと仮定してはならない。 コードを調べて確認すること。) 不具合箇所がみつかったならば、 意図した括弧に対しては古い字下げが適しているでしょうから C-_でC-M-qをアンドゥします。
問題を解決できたと思ったら、再度C-M-qを使います。 古い字下げが意図した括弧の入れ子に対応していて、 必要な括弧を挿入できているならば、 C-M-qはなにも変えないはずです。
バイトコンパイル時にエラーが発生したときは、
通常、読者がコンパイルしているプログラムの不正な構文に原因があります。
コンパイラはバッファ*Compile-Log*
に適切なエラーメッセージを
表示してから停止します。
メッセージにはエラーとなった関数の名前があったりなかったりします。
いずれにしても、つぎのようにしてファイルのどこでエラーが生じたかを調べます。
まず、バッファ *Compiler Input*
に切り替えます。
(バッファ名が空白で始まり、そのため、
M-x list-buffersでは表示されないことに注意。)
このバッファにはコンパイルしたプログラムが入っていて、
ポイント位置はバイトコンパイラがどこまで読み取ったかを表します。
エラーの原因が不正なLisp構文であるならば、
ポイント位置が不正構文を検出した箇所を正確に表します。
エラー原因が近くにあるとは限りません!
エラーを探すために前節の方法を使ってください。
正しく読み取ったフォームのコンパイル中にエラーを検出したときには、 ポイントはそのフォームの末尾に位置しています。 この場合、この方法ではエラー箇所を正確に判別できませんが、 どの関数を確認すべきかを示しています。
表示(printing)とは Lispオブジェクトをテキスト表現へ変換する操作であり、 読み取り(reading)は逆の変換操作です。 これには、Lisp Data Typesで述べた表示表現と入力構文を用います。
本章では、読み取りや表示を行うLisp関数について述べます。 また、(読み取るときに)テキストをどこから得たり、 (表示するときに)どこへ出すかを指定する ストリーム(stream)についても述べます。
Lispオブジェクトの読み取りとは、
テキスト表現のLisp式を解析して対応するLispオブジェクトを生成することを
意味します。
これにより、プログラムはLispコードのファイルからLispへ取り込まれます。
テキストをオブジェクトの入力構文(read syntax)と呼びます。
たとえば、テキスト(a . 5)
は、
CARがa
でありCDRが数5であるコンスセルの入力構文です。
Lispオブジェクトの表示とは、
オブジェクトを表現するテキストを生成することを意味します。
つまり、オブジェクトをその表示表現
(see Printed Representation)に変換します。
上に述べたコンスセルを表示するとテキスト(a . 5)
を生成します。
読み取りと表示は、多かれ少なかれ、逆操作です。
与えられたテキスト断片を読み取ることで得られたオブジェクトを表示すると、
しばしば、同じテキストを生成します。
オブジェクトを表示することによって得られたテキストを読み取ると、
通常、似たようなオブジェクトを生成します。
たとえば、シンボルfoo
を表示するとテキストfoo
を生成し、
そのテキストを読み取るとシンボルfoo
が返されます。
要素がa
とb
であるリストを表示すると
テキスト(a b)
を生成し、
そのテキストを読み取ると
要素がa
とb
である(もとと同じではないが)リストを生成します。
しかし、これら2つの操作は厳密には逆操作ではありません。 3種類の例外があります。
#
で始まるテキストとして表示されるが、
これを読み取ろうとするとエラーになる。
これらのデータ型を読み取る方法は存在しない。
1
と01
は同じ整数を表し、
(a b)
と(a . (b))
は同じリストを表す。
読み取りではいずれの表現も受け付けるが、
表示では1つの表現を選ぶ。
テキストを読み取るほとんどのLisp関数は、 ストリーム(stream)を引数として受け付けます。 入力ストリームは、読み取るべきテキストの文字をどこからどのように得るのかを 指定します。 入力ストリームとして使える型は以下のとおりです。
t
t
を使うと、ミニバッファから読み取ることを意味する。
実際には、ミニバッファを表示しユーザーが指定したテキストから成る文字列を作り、
それを入力ストリームとして使う。
nil
nil
を指定すると、
standard-input
の値をかわりに使うことを意味する。
その値はデフォルト入力ストリームであり、
nil
以外の入力ストリームであること。
バッファであるストリームからの読み取りの例を 読み取り前後のポイント位置を含めて示します。
---------- 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
を返します。
get-file-char | Function |
この関数は、関数load で開いた入力ファイルから読み取るための
入力ストリームとして内部的に使われる。
読者はこの関数を使ってはならない。
|
本節では読み取りに関係するLisp関数や変数について述べます。
以下の関数では、streamは入力ストリーム(前節参照)を表します。
streamがnil
であったり省略すると、
standard-input
の値をデフォルトにします。
読み取り中に閉じていないリストやベクトル、文字列に出会うと、
エラーend-of-file
を通知します。
read &optional stream | Function |
この関数はstreamから1つのLisp式のテキスト表現を読み取り、 それをLispオブジェクトとして返す。 これは基本的なLisp入力関数である。 |
read-from-string string &optional start end | Function |
この関数は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) |
standard-input | Variable |
この変数はデフォルトの入力ストリーム、
つまり、引数streamがnil である場合にread が使う
ストリームを保持する。
|
出力ストリームは表示で生成した文字群をどのように扱うかを指定します。 ほとんどの表示関数は省略可能な引数として出力ストリームを受け付けます。 出力ストリームとして使える型は以下のとおりです。
t
nil
nil
を指定すると、
standard-output
の値をかわりに使うことを意味する。
その値はデフォルト出力ストリームであり、
nil
以外であること。
正当な出力ストリームの多くは、入力ストリームとしても正当です。 入力ストリームと出力ストリームの違いは、 オブジェクト型の違いというよりは、 読者が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
の先頭にコンスします
(see Building Lists)。
終了後には、リストがすべての出力文字を保持していますが逆順です。
(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
を呼び出してリストを文字列に変換し、
内容を読みやすいようにしました。
本節ではLispオブジェクトを表示する、 つまり、オブジェクトを表示表現に変換するLisp関数について述べます。
Emacsの表示関数のなかには、正しく読み取れるように
クォート文字を出力に追加するものがあります。
使用されるクォート文字は"
と\
です。
これらは、文字列とシンボルを区別したり、
文字列やシンボル内の句読点文字を読み取るときに区切り文字として扱うこと
を防ぎます。
詳しくはSee Printed Representation。
出力関数を選べば、クォートのありなしを指定できます。
テキストをLispシステムへ読み取る意図がある場合には、 曖昧さを避けるためにクォート文字付きで表示するべきです。 Lispプログラマに対してLispオブジェクトを明確に記述する場合も同様です。 しかし、人間向けの見やすい出力が目的であれば、 クォートせずに表示するのが普通はよいでしょう。
Lispオブジェクトはそれ自身を参照できます。
自己参照しているオブジェクトを普通の方法で表示するには
無限のテキストが必要であり、
そのような試みは無限再帰をもたらします。
Emacsはそのような再帰を検出し、
すでに表示したオブジェクトを再帰的に表示するかわりに
#level
を表示します。
たとえば、#0
は、現在の表示操作においてレベル0のオブジェクトを
再帰的に参照することを示します。
(setq foo (list nil)) => (nil) (setcar foo foo) => (#0)
以下の関数では、streamは出力ストリームを表します。
(出力ストリームについては前節を参照。)
streamがnil
であったり省略すると、
standard-output
の値をデフォルトにします。
print object &optional stream | Function |
関数print は便利な表示方法である。
オブジェクトobjectの表示表現を
ストリームstreamに出力し、
objectの前後に改行を1つずつ表示する。
クォート文字を使う。
print はobjectを返す。
たとえばつぎのとおり。
(progn (print 'The\ cat\ in) (print "the hat") (print " came back")) -| -| The\ cat\ in -| -| "the hat" -| -| " came back" -| => " came back" |
prin1 object &optional stream | Function |
この関数はオブジェクト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" |
princ object &optional stream | Function |
この関数はオブジェクトobjectの表示表現を
ストリームstreamに出力する。
objectを返す。
この関数は、 (progn (princ 'The\ cat) (princ " in the \"hat\"")) -| The cat in the "hat" => " in the \"hat\"" |
terpri &optional stream | Function |
この関数はストリームstreamに改行を出力する。 関数名は『terminate print』の略。 |
write-char character &optional stream | Function |
この関数は文字characterをストリームstreamへ出力する。 characterを返す。 |
prin1-to-string object &optional noescape | Function |
この関数は同じ引数に対してprin1 が表示するであろう
テキストから成る文字列を返す。
(prin1-to-string 'foo) => "foo" (prin1-to-string (mark-marker)) => "#<marker at 2773 in strings.texi>" noescapeが (prin1-to-string "foo") => "\"foo\"" (prin1-to-string "foo" t) => "foo" 文字列としてのLispオブジェクトの表示表現を得るための別の方法については、
String Conversionの |
with-output-to-string body... | Macro |
このマクロは、standard-output を文字列への出力と設定して
フォームbodyを実行する。
そして、その文字列を返す。
たとえば、カレントバッファの名前が (with-output-to-string (princ "The buffer is ") (princ (buffer-name))) は |
standard-output | Variable |
この変数の値はデフォルトの出力ストリーム、つまり、
引数streamがnil の場合に表示関数が用いるストリーム。
|
print-escape-newlines | Variable |
この変数がnil 以外であると、
文字列内の改行文字を\n 、ページ送り文字を\f と表示する。
通常、これらの文字は実際の改行やページ送りとして表示される。
この変数は、クォート付きで表示する表示関数 (prin1 "a\nb") -| "a -| b" => "a b" (let ((print-escape-newlines t)) (prin1 "a\nb")) -| "a\nb" => "a b" 2番目の式では、 |
print-escape-nonascii | Variable |
この変数がnil 以外であると、
クォート付きで表示する出力関数prin1 やprint は、
文字列内のユニバイト非ASCII文字を無条件で
バックスラッシュ列として表示する。
これらの関数は、出力ストリームがマルチバイトバッファや マルチバイトバッファのマーク位置であると、 この変数の値に関係なくユニバイト非ASCII文字に対して バックスラッシュ列を用いる。 |
print-escape-multibyte | Variable |
この変数がnil 以外であると、
クォート付きで表示する表示関数prin1 やprint は、
文字列内のマルチバイト非ASCII文字を無条件で
バックスラッシュ列として表示する。
これらの関数は、出力ストリームがユニバイトバッファや ユニバイトバッファのマーク位置であると、 この変数の値に関係なくマルチバイト非ASCII文字に対して バックスラッシュ列を用いる。 |
print-length | Variable |
この変数の値は、任意のリスト、ベクトル、ブールベクトルを表示するときの
最大要素数である。
表示するオブジェクトがこれより多くの要素を持つと、
「…」で省略する。
値が (setq print-length 2) => 2 (print '(1 2 3 4 5)) -| (1 2 ...) => (1 2 ...) |
print-level | Variable |
この変数の値は、表示するときの括弧や角括弧の入れ子の最大の深さ。
この制限を越える任意のリストやベクトルは「…」で省略する。
値がnil (デフォルト)であると無制限。
|
ミニバッファ(minibuffer)は、単純な数値前置引数ではなく、 より複雑な引数を読み取るためにEmacsのコマンドが使う特別なバッファです。 これらの引数には、ファイル名、バッファ名、 (M-xでの)コマンド名があります。 ミニバッファは、エコー領域と同様に、フレームの最下行に表示されますが、 引数を読み取るときにのみ表示されます。
ほとんどの意味において、ミニバッファはEmacsの普通のバッファです。
編集コマンドなどのバッファ内でのほとんどの操作は、
ミニバッファでも普通に動作します。
しかし、バッファを操作するコマンドの多くは、
ミニバッファには適用できません。
ミニバッファの名前はつねに*Minibuf-number
という形式であって、
変更できません。
ミニバッファはミニバッファ専用の特別なウィンドウだけに表示されます。
これらのウィンドウはつねにフレームの最下行に現れます。
(ミニバッファを持たないフレームや、
ミニバッファ用ウィンドウのみの特殊なフレームもある。
Minibuffers and Framesを参照。)
ミニバッファ用のウィンドウは通常は1行だけです。 ウィンドウサイズを変更するコマンドで一時的に大きさを変えられますが、 ミニバッファから抜けると通常サイズに戻ります。 ミニバッファ用ウィンドウのサイズを恒久的に変更するには、 ミニバッファを使っていないときに、フレームの別のウィンドウにおいて ウィンドウサイズを変更するコマンドを使います。 ミニバッファだけを持つフレームの場合、 フレームのサイズを変更すればミニバッファのサイズを変更できます。
すでにミニバッファが活性であるときにコマンドがミニバッファを使用することを
再帰ミニバッファと呼びます。
最初のミニバッファの名前は *Minibuf-0*
です。
再帰ミニバッファは、名前の最後の数を増やして命名します。
(名前は空白で始まるため、通常のバッファの一覧には表示されない。)
再帰ミニバッファの中で、もっとも内側の(つまりもっとも再帰が深い)ものが
活性なミニバッファです。
これを単にミニバッファと呼びます。
変数enable-recursive-minibuffers
を設定すれば、
再帰ミニバッファを許可したり禁止できます。
あるいは、コマンドシンボルにこの名前の属性を入れます
(see Minibuffer Misc)。
他のバッファと同様に、ミニバッファは 複数のローカルキーマップ(see Keymaps)を使うことがあります。 これらには、さまざまな終了コマンドや補完コマンド(see Completion) が含まれます。
minibuffer-local-map
は(補完なしの)普通の入力用。
minibuffer-local-ns-map
も同様だが、
<RET>と同様に<SPC>で抜ける。
これは主にMocklisp互換用に使われる。
minibuffer-local-completion-map
は弱い補完用。
minibuffer-local-completion-map
は強い補完や慎重な補完用。
多くの場合、テキストを文字列として読み取るためにミニバッファを使います。
Lispオブジェクトのテキスト表現を読み取るためにも使えます。
ミニバッファでの入力のもっとも基本的な関数は
read-from-minibuffer
であり、どちらの目的にも使えます。
多くの場合、Lisp関数の途中でミニバッファの入力関数を呼ぶべきではありません。
そのかわりに、interactive
の指定で、
コマンドの引数を読み取る操作の一部として
すべてのミニバッファ入力を行います。
See Defining Commands。
read-from-minibuffer prompt-string &optional initial-contents keymap read hist default inherit-input-method | Function |
この関数は、ミニバッファから入力を得るもっとも汎用の方法である。
デフォルトでは、任意のテキストを受け取り文字列として返す。
しかし、readがnil 以外であれば、
read を用いてテキストを
Lispオブジェクトへ変換する(see Input Functions)。
この関数がまず行うことは、ミニバッファを活性にし、 プロンプトprompt-stringとともに表示することである。 prompt-stringは文字列であること。 これで、ユーザーはミニバッファでテキストを編集できるようになる。 ユーザーがミニバッファを抜けるコマンドを打つと、
引数defaultは、履歴コマンドで使うデフォルト値を指定する。
これは文字列か keymapが 引数histは、ミニバッファでの入力を保存し履歴コマンドを使用可能に
するために用いる履歴リスト変数を指定する。
デフォルトは 変数 引数inherit-input-methodが initial-contentsが文字列であれば、
あるいは、initial-contentsは、
使用上の注意: |
read-string prompt &optional initial history default inherit-input-method | Function |
この関数はミニバッファから文字列を読み取り、それを返す。
引数promptとinitialは、
read-from-minibuffer と同様に使われる。
使用するキーマップはminibuffer-local-map である。
省略可能な引数historyは、 この関数は関数 (read-string prompt initial history default inherit) == (let ((value (read-from-minibuffer prompt initial nil nil history default inherit))) (if (equal value "") default value)) |
minibuffer-allow-text-properties | Variable |
この変数がnil であると、
read-from-minibuffer はミニバッファで指定されたすべての
テキスト属性を返すまえに取り除く。
すべてのミニバッファがread-from-minibuffer を使うので、
この変数はすべてのミニバッファ入力に適用される。
この変数の値に関わらず、 補完関数は無条件にテキスト属性を廃棄することに注意。 |
minibuffer-local-map | Variable |
ミニバッファから読み取るときのデフォルトのローカルキーマップ。
デフォルトでは、以下のバインディングである。
|
read-no-blanks-input prompt &optional initial inherit-input-method | Function |
この関数はミニバッファから文字列を読み取るが、
入力には白文字を許さず、白文字は入力を終らせる。
引数prompt、initial、inherit-input-methodは、
read-from-minibuffer と同様に使われる。
これは関数 (read-no-blanks-input prompt initial) == (read-from-minibuffer prompt initial minibuffer-local-ns-map) |
minibuffer-local-ns-map | Variable |
この組み込み変数は、関数read-no-blanks-input が
ミニバッファ用のローカルキーマップとして使うキーマップである。
デフォルトでは、minibuffer-local-map のバインディングに加えて
以下のバインディングである。
|
本節では、ミニバッファでLispオブジェクトを読み取る関数について述べます。
read-minibuffer prompt &optional initial | Function |
この関数はミニバッファを用いてLispオブジェクトを読み取り、
それを評価せずに返す。
引数promptとinitialは、
read-from-minibuffer と同様に使われる。
これは関数 (read-minibuffer prompt initial) == (read-from-minibuffer prompt initial nil t) 初期入力として文字列 (read-minibuffer "Enter an expression: " (format "%s" '(testing))) ;; 以下のようにミニバッファが表示される ---------- Buffer: Minibuffer ---------- Enter an expression: (testing)-!- ---------- Buffer: Minibuffer ---------- デフォルトとして初期入力を使うには、ユーザーはただちに<RET>を打てばよい。 あるいは、入力を編集する。 |
eval-minibuffer prompt &optional initial | Function |
この関数はミニバッファを用いてLisp式を読み取り、
それを評価してその結果を返す。
引数promptとinitialは、
read-from-minibuffer と同様に使われる。
この関数は (eval-minibuffer prompt initial) == (eval (read-minibuffer prompt initial)) |
edit-and-eval-command prompt form | Function |
この関数はミニバッファを用いてLisp式を読み取り、それを評価する。
このコマンドとeval-minibuffer との違いは、
初期フォームformを省略できないことであり、
このフォームをテキスト文字列としではなく表示表現に
変換するLispオブジェクトとして扱うことである。
prin1 を用いて表示するので、
これが文字列であると初期テキストにはダブルクォート文字(" )が現れる。
see Output Functions。
以下の例では、すでに正しいフォームである 初期テキストの式をユーザーに提示する。 (edit-and-eval-command "Please edit: " '(forward-word 1)) ;; 上の式を評価後には、ミニバッファは以下のようになる ---------- Buffer: Minibuffer ---------- Please edit: (forward-word 1)-!- ---------- Buffer: Minibuffer ---------- ただちに<RET>を打つと、
ミニバッファから抜けて式を評価するので、
ポイントを1単語分先へ進めることになる。
この例では、 |
ミニバッファ履歴リスト(minibuffer history list)は ミニバッファでの以前の入力を記録し、 ユーザーがそれらを手軽に再利用できるようにします。 履歴リストは実際にはシンボルでありリストではありません。 最新のものが先頭にある(以前の入力の)文字列のリストを値とする変数です。
異なる種類の入力に用いる多くの別々の履歴リストがあります。 ミニバッファを利用するたびに適した履歴リストを指定するのは、 Lispプログラマの責任です。
基本的なミニバッファ入力関数
read-from-minibuffer
とcompleting-read
の両者は、
読者が指定する履歴リストを省略可能な引数histとして受け付けます。
指定可能な値はつぎのとおりです。
startposを指定した場合、整合性を保つために、 履歴リストの当該要素をミニバッファの初期内容にも指定すること。
histを指定しなければ、
デフォルトの履歴リストminibuffer-history
を用いる。
その他の標準的な履歴リストについては以下を参照。
読者が独自の履歴リスト変数を作成してもよい。
初めて使用するまえに単にnil
で初期化しておく。
read-from-minibuffer
とcompleting-read
の両者は
履歴リストに新たな要素を自動的に追加し、
リスト上の要素を再利用するためのコマンドをユーザーに提供する。
履歴リストを使うために読者のプログラムで行うべきことは、
履歴リストを初期化し必要なときにその名前を入力関数に渡すだけである。
ミニバッファ入力関数が履歴リストを使用していないときには、
履歴リストを変更しても安全である。
標準的なミニバッファ履歴リスト変数を以下にあげておく。
minibuffer-history | Variable |
ミニバッファの履歴入力用のデフォルトの履歴リスト。 |
query-replace-history | Variable |
query-replace (および同様のコマンド)の引数用の履歴リスト。
|
file-name-history | Variable |
ファイル名引数用の履歴リスト。 |
buffer-name-history | Variable |
バッファ名引数用の履歴リスト。 |
regexp-history | Variable |
正規表現引数用の履歴リスト。 |
extended-command-history | Variable |
拡張コマンド名である引数用の履歴リスト。 |
shell-command-history | Variable |
シェルコマンドである引数用の履歴リスト。 |
read-expression-history | Variable |
Lisp式として評価する引数用の履歴リスト。 |
補完(completion)とは、
名前の省略から始まる名前の残り部分を補充する機能です。
ユーザー入力を正しい名前のリストと比較し、
すでにユーザーが入力したものに名前が
どの程度一致するかを決定することで補完します。
たとえば、C-x b(switch-to-buffer
)と打って、
切り替えたいバッファ名の始めの数文字を打って
<TAB>(minibuffer-complete
)を打つと、
Emacsは可能な限りその名前を補充します。
Emacsの標準のコマンドは、 シンボル、ファイル、バッファ、プロセスの名前を補完できます。 本節の関数を用いれば、その他の種類の名前の補完も実装できます。
関数try-completion
は補完のための基本関数です。
与えられた文字列の集まりから
初期文字列にもっとも適合する最長のものを返します。
関数completing-read
は補完のための上位レベルの
インターフェイスを提供します。
completing-read
の呼び出しには、
正しい名前のリストを決定する方法を指定します。
この関数は、補完に有用なコマンドを数個のキーにバインドした
ローカルキーマップを使うミニバッファを活性にします。
その他の関数は、特定の種類の名前を補完して読み取るために
単純化したインターフェイスを提供します。
2つの関数try-completion
とall-completions
は、
それ自身ではミニバッファを使いません。
これらについて本章で述べるのは、
ミニバッファを使う上位レベルの補完機能と同列にしておくためです。
try-completion string collection &optional predicate | Function |
この関数は、collectionにあるstringを補完する
共通の最長な部分文字列を返す。
collectionの値は、連想リスト、オブジェクト配列、あるいは、
実質的な文字列の集まりを返す関数(下記参照)であること。
補完では、collectionで指定した各補完候補と
stringを比較する。
補完候補の先頭部分がstringに等しければ、
その補完候補は一致するという。
一致する補完候補がなければ、 collectionが連想リスト(see Association Lists)であると、 連想リストの要素のCAR群が補完候補の集まりになる。 collectionがオブジェクト配列(see Creating Symbols)であると、
オブジェクト配列内のすべてのシンボルの名前が補完候補の集まりになる。
グローバル変数 新たなオブジェクト配列を作成する唯一の正しい方法は、
まず空で作成してから 引数predicateが collectionには、関数であるシンボルを使うこともできる。
その関数には補完処理を完遂する責任がある。
以下の最初の例では、
文字列 (try-completion "foo" '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4))) => "fooba" (try-completion "foo" '(("barfoo" 2) ("foo" 3))) => t つぎの例では、 (try-completion "forw" obarray) => "forward" 最後の例は、述語 (defun test (s) (> (length (car s)) 6)) => test (try-completion "foo" '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4)) 'test) => "foobar" |
all-completions string collection &optional predicate nospace | Function |
この関数はstringの補完すべてのリストを返す。
この関数の引数は、try-completion のものと同じである。
collectionが関数であると、
string、predicate、 nospaceが
(defun test (s) (> (length (car s)) 6)) => test (all-completions "foo" '(("foobar1" 1) ("barfoo" 2) ("foobaz" 3) ("foobar2" 4)) 'test) => ("foobar1" "foobar2") |
completion-ignore-case | Variable |
この変数の値がnil 以外であると、
Emacsは補完において大文字小文字を区別しない。
|
本節ではミニバッファからの補完による読み取り用の 基本インターフェイスについて述べます。
completing-read prompt collection &optional predicate require-match initial hist default inherit-input-method | Function |
この関数は、与えられた補完でユーザーを補佐して
ミニバッファで文字列を読み取る。
文字列であるプロンプトpromptでミニバッファを活性にする。
実際の補完は、collectionとpredicateを
関数 require-matchが しかし、require-matchの値に関わらず、
空の入力はつねに許される。
その場合、 ミニバッファが空の状態で<RET>を打つと、
ユーザーは空入力で抜けることができる。
そうすると、 関数 引数histは、入力を保存しミニバッファ履歴コマンドで
使う履歴リスト変数を指定する。
デフォルトは initialが 引数inherit-input-methodが 組み込み変数
(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>を打つと、
関数 |
本節では、補完を行うためにミニバッファで用いられるキーマップ、 コマンド、ユーザーオプションについて述べます。
minibuffer-local-completion-map | Variable |
completing-read は、
補完候補の1つと完全に一致しなくてもよい場合に
ローカルキーマップとしてこの値を使う。
デフォルトでは、このキーマップのバインディングはつぎのとおり。
他の文字は |
minibuffer-local-must-match-map | Variable |
completing-read は、
補完候補の1つと完全に一致する必要がある場合に
ローカルキーマップとしてこの値を使う。
そのため、ミニバッファから無条件に抜けるコマンドexit-minibuffer に
バインドしたキーはない。
デフォルトでは、このキーマップのバインディングはつぎのとおり。
他の文字は |
minibuffer-completion-table | Variable |
この変数の値は、ミニバッファでの補完に用いられる
連想リストやオブジェクト配列である。
これは、completing-read がtry-completion に渡すものを
保持したグローバル変数である。
minibuffer-complete-word などの
ミニバッファ補完コマンドで使用される。
|
minibuffer-completion-predicate | Variable |
この変数の値は、completing-read が
try-completion へ渡す述語である。
この変数は、他のミニバッファ補完関数でも使われる。
|
minibuffer-complete-word | コマンド |
この関数は、ミニバッファの内容を多くても1単語分補完する。 ミニバッファの内容に対応する補完がたった1つであっても、 単語構成文字ではない文字以降は補充しない。 see Syntax Tables。 |
minibuffer-complete | コマンド |
この関数は、ミニバッファの内容を可能な限り補完する。 |
minibuffer-complete-and-exit | コマンド |
この関数は、確認が必要でないとき、つまり、
minibuffer-completion-confirm がnil であるときには、
ミニバッファの内容を補完後に抜ける。
確認が必要であるときには、
このコマンドをただちに繰り返すことで確認をとる。
このコマンドは、連続して2回呼ばれると、
確認しないようにプログラムしてある。
|
minibuffer-completion-confirm | Variable |
この変数の値がnil 以外の場合、
Emacsはミニバッファから抜けるまえに補完を確認してくる。
関数minibuffer-complete-and-exit は、
抜けるまえにこの変数の値を検査する。
|
minibuffer-completion-help | コマンド |
この関数は、ミニバッファの現在の内容に対する補完のリストを作る。
引数collectionとして変数minibuffer-completion-table の値を、
引数predicateとしてminibuffer-completion-predicate の値を
用いてall-completions を呼び出すことで動作する。
補完のリストは、*Completions* という名前のバッファに
テキストとして表示される。
|
display-completion-list completions | Function |
この関数は、通常はバッファであるストリームstandard-output に
completionsを表示する。
(ストリームについては詳しくはsee Read and Print。)
引数completionsは、普通は、all-completions が
返した補完のリストであるが、そうでなくてもよい。
各要素は、シンボルか文字列であり、その場合、そのまま表示される。
各要素が2つの文字列から成るリストである場合、
文字列を連結したものを表示する。
この関数は、 (with-output-to-temp-buffer "*Completions*" (display-completion-list (all-completions (buffer-string) my-alist))) |
completion-auto-help | User Option |
この変数がnil 以外であると、
つぎの補充文字が一意に決まらない場合には、
自動的に補完のリストを表示する。
|
本節では、特定の種類の名前を補完付きで読み取るための 高レベルの便利な関数について述べます。
多くの場合、これらの関数をLisp関数の途中では呼び出さないでください。
可能な場合には、interactive
の指定で、
コマンドの引数を読み取る操作の一部としてすべてのミニバッファ入力を
行ってください。
See Defining Commands。
read-buffer prompt &optional default existing | Function |
この関数はバッファ名を読み取り、文字列として返す。
引数defaultはデフォルトの名前を表し、
ユーザーがミニバッファから空で抜け出したときに返される値である。
nil 以外であるときには、文字列かバッファであること。
これはプロンプトとして現れるが、
ミニバッファには初期入力として挿入されない。
existingが 以下の例では、ユーザーは (read-buffer "Buffer name? " "foo" t) ;; 上の式を評価すると、ミニバッファは空で ;; つぎのようなプロンプトが表示される ---------- Buffer: Minibuffer ---------- Buffer name? (default foo) -!- ---------- Buffer: Minibuffer ---------- ;; ユーザーはminibuffer.t <RET>と打つ => "minibuffer.texi" |
read-buffer-function | Variable |
この変数は、バッファ名の読み取り方を指定する。
たとえば、この変数にiswitchb-read-buffer を設定すると、
バッファ名を読み取るためにread-buffer を呼び出す
すべてのEmacsコマンドは、
バッファ名を読むためにパッケージiswitchb を使うようになる。
|
read-command prompt &optional default | Function |
この関数はコマンド名を読み取り、Lispシンボルとして返す。
引数promptは、read-from-minibuffer と同様に使われる。
なんであってもcommandp がt を返せばコマンドであり、
commandp がt を返すシンボルはコマンド名であることに注意。
see Interactive Call。
引数defaultは、ユーザー入力が空だった場合に返したい値を指定する。
これは、シンボルか文字列であること。
文字列であると、 (read-command "Command name? ") ;; 上の式を評価後には、ミニバッファは空で ;; つぎのようなプロンプトが表示される ---------- Buffer: Minibuffer ---------- Command name? ---------- Buffer: Minibuffer ---------- ユーザーがforward-c <RET>と打つと、
この関数は 関数 (read-command prompt) == (intern (completing-read prompt obarray 'commandp t nil)) |
read-variable prompt &optional default | Function |
この関数はユーザー変数の名前を読み取り、シンボルとして返す。
引数defaultは、ユーザー入力が空だった場合に返したい値を指定する。
これは、シンボルか文字列であること。
文字列であると、 (read-variable "Variable name? ") ;; 上の式を評価後には、ミニバッファは空で ;; つぎのようなプロンプトが表示される ---------- Buffer: Minibuffer ---------- Variable name? -!- ---------- Buffer: Minibuffer ---------- ユーザーがfill-p <RET>と打つと、
この関数は (read-variable prompt) == (intern (completing-read prompt obarray 'user-variable-p t nil)) |
read-coding-system
や
read-non-nil-coding-system
も参照してください。
ここでは、ファイル名を読み取るように設計された高レベルの 別の補完関数について述べます。 デフォルトディレクトリの自動挿入などの特別な機能を提供します。
read-file-name prompt &optional directory default existing initial | Function |
この関数は、promptをプロンプトとし、
補完を行ってミニバッファでファイル名を読み取る。
defaultがnil 以外であると、
ユーザーが単に<RET>を打つと、この関数はdefaultを返す。
defaultが正しいかどうかは検査せず、
それがなんであれ、ユーザーがミニバッファを空で抜けるとそれを返す。
existingが 引数directoryは、相対ファイル名の補完に用いるディレクトリを指定する。
initialを指定すると、
(directoryがあればそれを挿入後に)バッファに
挿入される初期ファイル名になる。
この場合、ポイントはinitialの先頭に置かれる。
initialのデフォルトは 例を示す。 (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>と打つと、
|
insert-default-directory | User Option |
この変数はread-file-name が使う。
その値は、read-file-name が、
デフォルトディレクトリの名前と(あれば)初期ファイル名を
ミニバッファに入れて動作を開始するかどうかを制御する。
この変数の値がnil であると、
read-file-name は
(引数initialで初期入力を指定しない限り)
ミニバッファに初期入力を入れない。
その場合でも、相対ファイル名の補完には
デフォルトディレクトリを使うが表示はしない。
例を示す。 ;; デフォルトディレクトリを入れて始める (let ((insert-default-directory t)) (read-file-name "The file is ")) ---------- Buffer: Minibuffer ---------- The file is ~lewis/manual/-!- ---------- Buffer: Minibuffer ---------- ;; ミニバッファは空であり、プロンプトのみ (let ((insert-default-directory nil)) (read-file-name "The file is ")) ---------- Buffer: Minibuffer ---------- The file is -!- ---------- Buffer: Minibuffer ---------- |
意図した補完候補を持った連想リストやオブジェクト配列を 作成することが困難な場合もあります。 そのような場合、与えられた文字列に対する補完を計算する 独自の関数を与えることができます。 これをプログラム補完(programmed completion)と呼びます。
この機能を使うには、completing-read
の引数collectionに
関数定義を持つシンボルを渡します。
関数completing-read
は、
try-completion
やall-completions
に
読者の補完関数を渡すようにして、読者の関数にすべてを任せます。
補完関数はつぎの3つの引数を受け取ります。
nil
。
読者の関数では、各補完候補についてこの述語を呼び出し、
nil
が返されたら当該候補を無視する。
3つの操作型に対応してフラグの値は3つあります。
nil
はtry-completion
を指定する。
補完関数は、指定された文字列の補完を返すこと。
あるいは、文字列が一意に完全に一致する場合にはt
を返し、
文字列の補完がまったくなければnil
を返す。
文字列が一意に完全に一致する場合であっても、
より長い候補に一致する場合には、
この関数はt
ではなく文字列を返すこと。
t
はall-completions
を指定する。
補完関数は、指定された文字列に対する補完のリストを返すこと。
lambda
は、完全な一致を指定する。
補完関数は、指定された文字列が候補に完全に一致する場合にはt
を返し、
さもなければnil
を返すこと。
補完関数collectionには関数シンボルに加えて、 ラムダ式(関数であるリスト)も許すほうが 一貫性があって見通しがよいはずですが、それは不可能です。 リストには補完候補表としての意味がすでにあり、連想リストがそれです。 関数としての可能性もある通常の連想リストの扱いに失敗するようでは、 信頼性がなくなります。 そのため、読者が補完に使用したい関数は、 シンボルに入れておく必要があるのです。
Emacsは、ファイル名の補完にはプログラム補完を用います。 See File Name Completion。
本節ではユーザーにyes/noを問い合わせるための関数について述べます。
関数y-or-n-p
には、1文字で答えます。
誤った答えでも重大な問題に至らないような問い合わせに便利です。
yes-or-no-p
には3文字か4文字で答える必要があるため、
より重要な問い合わせに適しています。
これらの関数がマウスを使って起動されたコマンドから呼ばれると、
より正確には、last-nonmenu-event
(see Command Loop Info)が
nil
かリストであると、
関数は問い合わせのための対話ボックスやポップアップメニューを使います。
さもなければ、キーボード入力を使います。
呼び出しにおいてlast-nonmenu-event
に適切な値を束縛することで
マウスかキーボード入力の使用を強制できます。
厳密にいえば、yes-or-no-p
はミニバッファを使いますが、
y-or-n-p
は使いません。
ですが、両者をここで説明しておきます。
y-or-n-p prompt | Function |
この関数はユーザーに問い合わせ、エコー領域で入力を待ちます。
ユーザーがyを打てばt を返し、
nを打てばnil を返します。
さらに、<SPC>を「y」、<DEL>を「n」ともみなします。
C-]をC-gのように『中断』ともみなします。
というのは、問い合わせはミニバッファを使っているようにみえるので、
これから抜けるためにユーザーがC-]を使いそうだからである。
応答は1文字であり、<RET>で終える必要はない。
大文字と小文字は同じ意味である。
『問い合わせ』では、エコー領域にpromptを表示し、
文字列 応答は編集できないので、この関数は実際にはミニバッファを使わない。 ミニバッファが使うのと同じ画面領域を使う エコー領域(see The Echo Area)を実際には使う。 問い合わせ中は、カーソルはエコー領域に移動する。 応答とその意味は、
たとえ 以下の例では、ユーザーはまずqを打つが、これは正しくない。 つぎのプロンプトに対して、ユーザーはyを打つ。 (y-or-n-p "Do you need a lift? ") ;; 上の式を評価後には、エコー領域には ;; つぎのプロンプトが表示される ---------- Echo area ---------- Do you need a lift? (y or n) ---------- Echo area ---------- ;; ユーザーがqを打つと、つぎのようになる ---------- Echo area ---------- Please answer y or n. Do you need a lift? (y or n) ---------- Echo area ---------- ;; ユーザーが正しい応答を打つと ;; 問い合わせのうしろに表示される ---------- Echo area ---------- Do you need a lift? (y or n) y ---------- Echo area ---------- ここでは、エコー領域のメッセージを複数行示したが、 実際には、1度に1つのメッセージだけが表示される。 |
y-or-n-p-with-timeout prompt seconds default-value | Function |
y-or-n-p と同様だが、ユーザーがseconds秒以内に答えないと、
入力を待たずにdefault-valueを返す。
これにはタイマを使う。
Timersを参照。
引数secondsは整数でも浮動小数点でもよい。
|
yes-or-no-p prompt | Function |
この関数はユーザーに問い合わせ、ミニバッファでの入力を仮定する。
ユーザーがyes を入力するとt を返し、
no を入力するとnil を返す。
応答を終えるためにユーザーは<RET>を打つ必要がある。
大文字と小文字は同じ意味である。
例を示す。 (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>を打つが、
この関数は完全な単語 ---------- Buffer: minibuffer ---------- Please answer yes or no. Do you really want to remove everything? (yes or no) ---------- Buffer: minibuffer ---------- |
各バッファについて『バッファを保存するか』などの
一連の単純な問い合わせをする場合には、
個々に問い合わせるかわりに
map-y-or-n-p
を用いてまとめて問い合わせるべきです。
map-y-or-n-p prompter actor list &optional help action-alist | Function |
この関数は、各問について1文字の応答をエコー領域から読み取ることで、
ユーザーに一連の問い合わせを行う。
listの値は、問い合わせ対象のオブジェクトを指定する。
オブジェクトのリストであるか、生成関数であること。
関数である場合、それは引数なしで呼ばれ、
つぎの問い合わせ対象のオブジェクトを返すか、
問い合わせの終了を意味する 引数prompterは、各問い合わせをどのように問うかを指定する。 prompterが文字列であると、問い合わせ文はつぎのように計算される。 (format prompter object) ここで、objectは(listから得た) 問い合わせ対象のオブジェクトである。 文字列でなければ、prompterは
1引数(問い合わせ対象のオブジェクト)の関数であり、
問い合わせ文を返す。
値が文字列であれば、それがユーザーへの問い合わせ文になる。
関数は、(ユーザーに問い合わせずに)
当該オブジェクトを処理することを意味する 引数actorは、ユーザーの応答に対してどのように動作するかを指定する。 これは1引数の関数であり、ユーザーが「はい」と答えたオブジェクトで 呼ばれる。 引数は、つねにlistから得たオブジェクトである。 引数helpを指定する場合、つぎの形のリストであること。 (singular plural action) ここで、 singularは操作対象のオブジェクトを 記述する単数形の名詞を含んだ文字列であり、 pluralは対応する複数形の名詞であり、 actionは動作を記述する他動詞であること。 helpを指定しないと、デフォルトは
各問い合わせでは、ユーザーは当該対象オブジェクトに対する操作に
y、Y、SPCで答える。
n、N、<DEL>は、そのオブジェクトを無視する。
!はそのオブジェクトを含めて後続のものも処理する。
<ESC>やqは(後続のオブジェクトをすべて無視して)抜ける。
.(ピリオド)は現在の対象オブジェクトを処理してから抜ける。
C-hはヘルプメッセージを表示する。
これらは、 action-alistを使って、
可能な応答とそれらの意味を追加指定することもできる。
これは、 ユーザーがcharで答えると、
|
別のプログラムへ渡すパスワードを読み取るには、
関数read-passwd
を使います。
read-passwd prompt &optional confirm default | Function |
この関数は、プロンプトpromptを表示してパスワードを読み取る。
ユーザーが入力するパスワードは表示せず、
そのかわりにパスワードの各文字ごとに. を表示する。
省略可能な引数confirmが 省略可能な引数defaultは、ユーザーが空のパスワードを
入力したときに返すデフォルトのパスワードを指定する。
defaultが |
本節では、ミニバッファに関係する他の基本関数や変数について述べます。
exit-minibuffer | コマンド |
このコマンドは活性なミニバッファから抜ける。 通常、ミニバッファのローカルキーマップでキーにバインドされる。 |
self-insert-and-exit | コマンド |
このコマンドは(Command Loop Infoのlast-command-char にある)
最新のキーボード入力文字を活性なミニバッファに挿入してから抜ける。
|
previous-history-element n | コマンド |
このコマンドは、ミニバッファの内容を n番目まえの(古い)履歴要素の値で置き換える。 |
next-history-element n | コマンド |
このコマンドは、ミニバッファの内容を n番目先のより新しい履歴要素の値で置き換える。 |
previous-matching-history-element pattern | コマンド |
このコマンドは、ミニバッファの内容を pattern(正規表現)に一致するまえの(古い)履歴要素の値で置き換える。 |
next-matching-history-element pattern | コマンド |
このコマンドは、ミニバッファの内容を pattern(正規表現)に一致するつぎの(新しい)履歴要素の値で置き換える。 |
minibuffer-prompt | Function |
この関数は、現在活性なミニバッファのプロンプト文字列を返す。
活性なミニバッファがなければnil を返す。
|
minibuffer-prompt-width | Function |
この関数は、現在活性なミニバッファのプロンプト文字列の表示幅を返す。 活性なミニバッファがなければ0を返す。 |
minibuffer-setup-hook | Variable |
ミニバッファに入るたびに実行されるノーマルフック。 see Hooks。 |
minibuffer-exit-hook | Variable |
ミニバッファから抜けるたびに実行されるノーマルフック。 see Hooks。 |
minibuffer-help-form | Variable |
この変数の現在値は、
ミニバッファの内側でhelp-form のローカルな束縛に使われる。
(see Help Functions)。
|
active-minibuffer-window | Function |
この関数は、現在活性なミニバッファのウィンドウを返す。
あるいは、活性なミニバッファがなければnil を返す。
|
minibuffer-window &optional frame | Function |
この関数は、フレームframeで使われるミニバッファ用ウィンドウを返す。
frameがnil であると、カレントフレームを意味する。
フレームで使うミニバッファ用ウィンドウは、
そのフレームの一部である必要はない。
ミニバッファを持たないフレームでは、
他のフレームのミニバッファ用ウィンドウを使う。
|
window-minibuffer-p window | Function |
この関数は、windowがミニバッファ用ウィンドウであると
nil 以外を返す。
|
与えられたウィンドウがミニバッファ用であるかどうかを調べるために、
(minibuffer-window)
の戻り値と比較するのは正しくありません。
というのは、フレームが複数個あると
複数のミニバッファ用ウィンドウがあるからです。
minibuffer-window-active-p window | Function |
この関数は、ミニバッファ用ウィンドウwindowが活性であると
nil 以外を返す。
|
minibuffer-scroll-window | Variable |
この変数の値がnil 以外であると、
値はウィンドウオブジェクトであること。
ミニバッファで関数scroll-other-window が呼ばれると、
scroll-other-window はこのウィンドウをスクロールする。
|
最後に、再帰ミニバッファ(see Recursive Editing)を扱う 関数と変数について述べます。
minibuffer-depth | Function |
この関数は、活性なミニバッファの現在の深さを非負整数で返す。 活性なミニバッファがなければ0を返す。 |
enable-recursive-minibuffers | User Option |
この変数がnil 以外であると、
ミニバッファ用ウィンドウが活性であっても、
(find-file などの)ミニバッファを使うコマンドを起動できる。
そのような起動では、新たなミニバッファに対する再帰編集レベルが作られる。
内側の(深い)ミニバッファを編集中には、
外側の(浅い)レベルのミニバッファは見えない。
この変数が |
コマンド名にnil
以外の
属性enable-recursive-minibuffers
があると、
当該コマンドをミニバッファから起動したときでさえ、
当該コマンドはミニバッファを使って引数を読み取れます。
ミニバッファコマンドnext-matching-history-element
(ミニバッファでは通常M-s)は、この機能を使っています。
読者がEmacsを起動すると、Emacsはほぼただちにエディタコマンドループ (editor command loop)に入ります。 このループは、キー列を読み取り、それらの定義を実行し、結果を表示します。 本章では、これがどのように行われるのか、および、 Lispプログラムからこれを行うためのサブルーティンについて述べます。
コマンドループがまず始めに行うことはキー列、
つまり、コマンドへ変換されるイベント列を読むことです。
これには関数read-key-sequence
を呼び出します。
読者のLispコードでもこの関数を呼び出せます(see Key Sequence Input)。
Lispプログラムでは、read-event
(see Reading One Event)で
低レベルの入力を行ったり、
discard-input
(see Event Input Misc)で
処理待ち中の入力を破棄できます。
キー列は現在活性なキーマップを介してコマンドに変換されます。
この処理方法についてはSee Key Lookup。
この結果は、キーボードマクロであるか、
対話的に呼び出し可能な関数であるはずです。
キーがM-xであると、別のコマンドの名前を読み取り、
そのコマンドを呼び出します。
これはコマンドexecute-extended-command
(see Interactive Call)で
処理されます。
コマンドを実行するには、まず、その引数を読む必要があります。
これは、command-execute
(see Interactive Call)を呼び出して
行います。
Lispで書かれたコマンドでは、
interactive
指定が引数の読み方を指示します。
前置引数(see Prefix Command Arguments)を使ったり、
プロンプトを表示してミニバッファ(see Minibuffers)から読みます。
たとえば、コマンドfind-file
には、
ミニバッファからファイル名を読むことを指示した
interactive
指定があります。
コマンドの関数本体ではミニバッファを使いません。
このコマンドをLispコードから関数として呼び出す場合、
通常のLisp関数の引数としてファイル名文字列を指定する必要があります。
コマンドが文字列やベクトル(つまり、キーボードマクロ)である場合、
execute-kbd-macro
を用いてそれらを実行します。
読者自身がこの関数を呼び出してもかまいません(see Keyboard Macros)。
動作中のコマンドの実行を止めるには、C-gを打ちます。 この文字は中断(quitting)を引き起こします(see Quitting)。
pre-command-hook | Variable |
エディタコマンドループは、各コマンドのまえにこのノーマルフックを実行する。
その際、this-command にはこれから実行するコマンドが保持され、
last-command には直前のコマンドがある。
see Hooks。
|
post-command-hook | Variable |
エディタコマンドループは、
(中断やエラーのために完了しなかったコマンドを含めて)
各コマンドのあとにこのノーマルフックを実行する。
初めてコマンドループに入ったときにも実行する。
その際、this-command には実行し終えたばかりのコマンドがあり、
last-command にはその前のコマンドがある。
see Hooks。
|
pre-command-hook
やpost-command-hook
の実行中は、
中断を禁止します。
これらのフックの1つを実行中にエラーが起きると、
エラーの無限ループを防ぐために、
フックの実行を終了しフック変数をnil
にします。
Lisp関数の本体に、スペシャルフォームinteractive
を呼び出す
フォームがトップレベルにあると、Lisp関数はコマンドになります。
このフォームは実際に呼び出されてもなにもしませんが、
このフォームがあることで、対話的に呼び出せることを表します。
その引数が、対話的呼び出しにおける引数の読み方を制御します。
interactive
.
interactive
の使い方本節では、Lisp関数を対話的に呼び出し可能なコマンドにするフォーム
interactive
の書き方について述べます。
interactive arg-descriptor | Special Form |
このスペシャルフォームは、これを含む関数がコマンドであり、
(M-xや当該関数にバインドしたキー列を入力することで)
対話的に呼び出せることを宣言する。
引数arg-descriptorは、コマンドを対話的に呼び出したときに
コマンドに対する引数の計算方法を宣言する。
他の関数と同様に、コマンドはLispプログラムからも呼び出せるが、 その場合、呼び出し側が引数を渡し、arg-descriptorにはなんの効果もない。 フォーム |
引数arg-descriptorには3つの可能性があります。
nil
。
この場合、コマンドは引数なしで呼ばれる。
コマンドが1つ以上の引数を必要とする場合、これはただちにエラーになる。
この式が(ミニバッファを使うことを含めて)キーボード入力を読む場合には、 入力を読むまえのポイントの整数値やマークは、 入力を読んだあとでは正しくない可能性があることに留意すること。 カレントバッファがサブプロセスの出力を受け取る可能性があるからである。 コマンドが入力を待っているあいだにサブプロセスの出力が到着すると、 ポイントやマークを再配置する可能性がある。
してはいけないことの例を示す。
(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)))
(interactive "bFrobnicate buffer: ")
コード文字b
は、補完を用いて既存のバッファ名を読むことを指示する。
バッファ名は、コマンドに渡される唯一の引数である。
文字列の残りはプロンプトである。
文字列内に改行文字があると、それはプロンプトを終える。 その部分で文字列が終らないときには、 文字列の残りの部分には、別の引数を指定するコード文字やプロンプトがある。 このようにして、何個の引数でも指定できる。
プロンプトの文字列では、プロンプト内の(第1引数から始まる)
まえの引数値を含めるために%
を使える。
これはformat
(see Formatting Strings)を用いて行う。
たとえば、既存バッファの名前を読み、
続けてそのバッファに与える新たな名前を読むにはつぎのようにする。
(interactive "bBuffer to rename: \nsRename buffer %s to: ")
文字列の最初の文字が*
である場合、
バッファが読み出し専用であるとエラーを通知する。
文字列の最初の文字が@
であり、
コマンドを起動したキー列にマウスイベントが含まれる場合、
コマンドを実行するまえに
それらのイベントの最初のものに関連したウィンドウを選択する。
*
と@
は同時に使え、その順序は関係ない。
引数の実際の読み取りはプロンプトの
(*
でも@
でもない最初の文字で始まる)残りの部分で制御される。
interactive
のコード文字以下に述べるコード文字の説明では、 つぎに定義するいくつかのキーワードを含みます。
completing-read
を使って引数を読むため、
<TAB>、<SPC>、<RET>は名前を補完する
(see Completion)。
?は補完候補のリストを表示する。
コード文字はプロンプト文字列を使わないが、
この文字が文字列の最後の文字でない場合には改行を続けること。
以下に、interactive
に使うコード文字を説明します。
*
@
a
fboundp
を満たすシンボル)。
「既存」、「補完」、「プロンプト」。
b
B
c
C
commandp
を満たすシンボル)。
「既存」、「補完」、「プロンプト」。
d
D
default-directory
(see System Environment)。
「既存」、「補完」、「デフォルト」、「プロンプト」。
e
e
はリストであるイベントを取得するので、
読者はリスト内のデータを調べられる。
see Input Events。
「入出力なし」。
1つのコマンドの対話指定で複数回e
を使える。
コマンドを起動したキー列がn個のリストであるイベントである場合、
n番目のe
は、n番目のそのようなイベントを与える。
e
では、
ファンクションキーやASCII文字などのリストでないイベントは数えない。
f
default-directory
。
「既存」、「補完」、「デフォルト」、「プロンプト」。
F
i
nil
を与える。
「入出力なし」。
k
この種の入力は、describe-key
やglobal-set-key
などの
コマンドで使われる。
K
k
と同様に動作するが、
キー列の最後の入力イベントに対しては、
未定義キーを定義済みのものに変換するために(必要なときに)普通使われる
変換処理を抑制する。
m
M
n
N
p
p
は小文字。)
「入出力なし」。
P
P
は大文字。)
「入出力なし」。
r
s
S
v
user-variable-p
を満たす)。
see High-Level Completion。
「既存」、「補完」、「プロンプト」。
x
X
z
nil
。
see Coding Systems。
「補完」、「既存」、「プロンプト」。
Z
Z
は引数の値にnil
を与える。
「補完」、「既存」、「プロンプト」。
interactive
の使用例ここではinteractive
の例を示します。
(defun foo1 () ;foo1
は引数なし (interactive) ; 2単語分先へ進める (forward-word 2)) => foo1 (defun foo2 (n) ;foo2
は1引数 (interactive "p") ; 数値前置引数 (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
コマンドループでは、キー列をコマンドへ変換し終えると、
関数command-execute
を用いてそのコマンドを起動します。
コマンドが関数であれば、command-execute
は引数を読み取り、
コマンドを呼び出すcall-interactively
を呼びます。
読者自身がこれらの関数を呼び出してもかまいません。
commandp object | Function |
objectが対話的呼び出しに適していれば、
つまり、objectがコマンドであればt を返す。
さもなければnil を返す。
対話的呼び出しが可能なオブジェクトには、
(キーボードマクロとして扱われる)文字列やベクトル、
トップレベルで シンボルの関数定義が キーやキーマップはコマンドではない。 それらはコマンドを探すために使われる(see Keymaps)。
|
call-interactively command &optional record-flag keys | Function |
この関数は、対話的呼び出し可能な関数commandを
その対話指定に従って引数を読み取り呼び出す。
commandが関数でなかったり、
対話的に呼び出せない(つまり、コマンドでない)場合には、
エラーを通知する。
キーボードマクロ(文字列やベクトル)はコマンドとみなすが、
それらは関数でないため、この関数はキーボードマクロを受け付けない。
record-flagが もし引数keysを指定すると、コマンドがそれを起動したイベントを 問い合わせたときに与えるイベント列を指定する。 |
command-execute command &optional record-flag keys | Function |
この関数はcommandを実行する。
引数commandはcommandp を満たすこと。
つまり、対話的呼び出し可能な関数かキーボードマクロであること。
シンボルは、その関数定義を使って処理する。
もし引数keysを指定すると、コマンドがそれを起動したイベントを 問い合わせたときに与えるイベント列を指定する。 |
execute-extended-command prefix-argument | コマンド |
この関数はcompleting-read (see Completion)を使って
ミニバッファでコマンド名を読む。
そしてcommand-execute を使って指定されたコマンドを実行する。
コマンドが返した値がexecute-extended-command の値になる。
コマンドが前置引数を必要とする場合、prefix-argumentの値を受け取る。
(execute-extended-command 1) ---------- Buffer: Minibuffer ---------- 1 M-x forward-word RET ---------- Buffer: Minibuffer ---------- => t |
interactive-p | Function |
この関数は、これ(interactive-p の呼び出し)を含んだ関数が
call-interactively で対話的に呼び出されるとt を返す。
(Lispからcall-interactively が呼び出されても、
エディタコマンドループが直接呼び出しても違いはない。)
これを含んだ関数がLispの評価(あるいはapply やfuncall )で
呼び出された場合は、対話的呼び出しではない。
|
interactive-p
のもっとも一般的な用途は、
情報メッセージを表示するかどうか決めることです。
特別な例外として、キーボードマクロを実行中にはいつでも、
interactive-p
はnil
を返します。
これは情報メッセージを省いてマクロの実行を速くするためです。
つぎのように使います。
(defun foo () (interactive) (when (interactive-p) (message "foo"))) => foo (defun bar () (interactive) (setq foobar (list (foo) (interactive-p)))) => bar ;; M-x fooと打つ -| foo ;; M-x barと打つ ;; これはなにも表示しない foobar => (nil t)
この種のことを行う別の方法は、コマンドを
対話的呼び出しではnil
以外の値になる引数print-message
を
取るようにし、その引数がnil
以外になるようなinteractive
指定を
使うことです。
つぎのようにします。
(defun foo (&optional print-message) (interactive "p") (when print-message (message "foo")))
p
で与えられる数値前置引数はけっしてnil
になりません。
エディタコマンドループは、自身や実行中のコマンドのために 状態記録を数個のLisp変数に設定します。
last-command | Variable |
この変数は、コマンドループが(現在のコマンドの)まえに実行したコマンドの
名前を記録する。
通常、この値は関数定義を持つシンボルであるが、保証はしない。
コマンドが後続のコマンドに対する前置引数を指定する場合を除いて、
コマンドからコマンドループへ戻ると この変数は現在の端末に対してつねにローカルであり、 バッファに対してローカルにはならない。 see Multiple Displays。 |
real-last-command | Variable |
last-command と同様にEmacsがこの変数に設定するが、
Lispプログラムではけっして変更しない。
|
this-command | Variable |
この変数は、エディタコマンドループが
いま実行しているコマンドの名前を記録する。
last-command と同様に、通常は関数定義を持つシンボルである。
コマンドループは、コマンドを実行する直前にこの変数に設定し、
コマンドが終了すると(コマンドが後続のコマンドに対する
前置引数を指定する場合を除いて)
この値を 後続のコマンドに対するフラグとして
実行中にこの変数に設定するコマンドもある。
特に、テキストをキルする関数群は |
特定のコマンドがエラーを起こした場合に
直前のコマンドとは認識されたくない場合には、
読者はそのコマンドがそれを防ぐように書く必要があります。
1つの方法は、以下に示すように、
コマンドの始めでthis-command
にt
を設定し、
コマンドの終りでthis-command
に正しい値を戻します。
(defun foo (args...) (interactive ...) (let ((old-this-command this-command)) (setq this-command t) ...do the work... (setq this-command old-this-command)))
let
でthis-command
を束縛しません。
というのは、エラーがあるとlet
は古い値を復元するからです。
これこそがここでは避けたいlet
の機能です。
this-command-keys | Function |
この関数は、現在のコマンドに対して直前のコマンドが生成した前置引数を含めて、
現在のコマンドを起動したキー列を含んだ文字列かベクトルを返す。
すべてのイベントが文字であれば、値は文字列である。
see Input Events。
(this-command-keys) ;; C-u C-x C-eを使ってこの式を評価する => "^U^X^E" |
this-command-keys-vector | Function |
this-command-keys と同様だが、つねにベクトルでイベントを返すため、
文字列に入力イベントを保持する際の複雑さを扱う必要がない
(see Strings of Events)。
|
last-nonmenu-event | Variable |
この変数は、マウスメニューによるイベントを考慮せずに、
キー列として読んだ最後の入力イベントを保持する。
この変数の1つの用途は、
メニューをポップアップする位置を |
last-command-event | Variable |
last-command-char | Variable |
この変数には、コマンドの一部としてコマンドループが
読んだ最後の入力イベントが設定される。
この変数の主な用途は、どの文字を挿入すべきかを決定するために
self-insert-command が使うことである。
last-command-event ;; C-u C-x C-eを使ってこの式を評価する => 5 C-eのASCIIコードは5なので、値は5である。 Emacs 18版との互換性のために別名 |
last-event-frame | Variable |
この変数は、最後の入力イベントを振り向けたフレームを記録する。 通常これは、イベントが生成されたときに選択されていたフレームであるが、 そのフレームが入力フォーカスを別のフレームに振り向けていると、 この値はイベントを振り向けた先のフレームである。 see Input Focus。 |
Emacsのコマンドループは、キーボードやマウスのユーザーの操作を表す 入力イベント(input event)列を読みます。 キーボード操作に対するイベントは、文字かシンボルです。 マウスイベントはつねにリストです。 本節では、入力イベントの表現方法やその意味を詳しく説明します。
eventp object | Function |
この関数は、objectが入力イベントであるかイベント型であると
nil 以外を返す。
任意のシンボルがイベントやイベント型として使われることに注意。
|
キーボードからは2種類の入力があります。 普通のキーとファンクションキーです。 普通のキーは文字に対応します。 それらが生成するイベントは、Lispでは文字として表現されます。 文字イベントのイベント型は文字自身(整数)です。 Classifying Eventsを参照してください。
入力文字イベントは、0から524287までの基本コード(basic code)と 以下の修飾ビット(modifier bit)の任意の組み合わせです。
C-aなどのASCIIコントロール文字には 独自の特別な基本コードがあるため、 Emacsはそれを表すための特別なビットを必要としない。 つまり、C-aのコードは単に1である。
しかし、コントロールキーを使った%などの
ASCIIにないコントロールとの組み合わせを打った場合、
得られる数値は%のコードに
を加えたものである
(端末で非ASCIIのコントロール文字を扱えるとして)。
英文字では、基本コードそのものが大文字か小文字かを表す。 数字文字と区切り文字では、 シフトキーは異なる基本コードのまったく異なる文字を選ぶ。 可能な限りASCII文字集合ですませるために、 これらの文字に対しては、Emacsはビット を使わない。
しかし、ASCIIではC-AとC-aを区別できないため、
Emacsは、C-Aではビット
を使うが、C-aではこのビットを使わない。
読者のプログラム内では、
特定の修飾ビットの値を明示することは避けるのが最良です。
文字の修飾ビットを検査するには、
関数event-modifiers
(see Classifying Events)を使います。
キーバインディングを作るときには、
(\C-
、\M-
などの)修飾ビットを伴う文字の
入力表現を使います。
define-key
でキーバインディングを作るときには、
文字の指定には(control hyper ?x)
のようなリストを使います
(see Changing Key Bindings)。
関数event-convert-list
は、そのようなリストを
イベント型に変換します(see Classifying Events)。
ほとんどのキーボードには、ファンクションキー(function key)、
つまり、文字ではない名前や記号のキーがあります。
Emacs Lispでは、ファンクションキーはシンボルで表現されます。
シンボルの(小文字の)名前がファンクションキーのラベルです。
たとえば、<F1>というラベルのキーを押すと、
入力ストリームにはシンボルf1
が置かれます。
ファンクションキーイベントのイベント型は、イベントシンボルそれ自身です。 See Classifying Events。
ファンクションキーに対するシンボル命名慣習の特例を以下に示します。
backspace
, tab
, newline
, return
, delete
ASCIIでは、C-iと<TAB>は同じ文字である。
これらを区別できる端末では、前者を整数9、後者をシンボルtab
と
表現することで、EmacsはLispプログラムに区別を伝える。
ほとんどの場面では、これら2つを区別しても有用ではない。
そのため、通常、function-key-map
(see Translating Input)は、
tab
を9に対応付けるようには設定してある。
したがって、文字コード9(文字C-i)に対するキーバインディングは
tab
にも適用される。
この種の他のシンボルについても同様である。
関数read-char
も同様にこれらのイベントを文字に変換する。
ASCIIでは、<BS>は実際にはC-hである。
しかし、backspace
は文字コード127(<DEL>)に変換され、
文字コード8(<BS>)には変換されない。
ほとんどのユーザーはこれを好む。
left
, up
, right
, down
kp-add
, kp-decimal
, kp-divide
, ...
kp-0
, kp-1
, ...
kp-f1
, kp-f2
, kp-f3
, kp-f4
kp-home
, kp-left
, kp-up
, kp-right
, kp-down
home
、left
、...のキーに変換する。
kp-prior
, kp-next
, kp-end
, kp-begin
, kp-insert
, kp-delete
ファンクションキーにも<ALT>、<CTRL>、<HYPER>、 <META>、<SHIFT>、<SUPER>の修飾キーを使えます。 それらを表現するには、シンボル名に接頭辞を付けます。
A-
C-
H-
M-
S-
s-
したがって、<META>を押し下げた<F3>キーのシンボルはM-f3
です。
複数の接頭辞を使うときには、アルファベット順に書くことを勧めますが、
キーバインディングの探索関数や修飾関数の引数では関係ありません。
Emacsでは4種類のマウスイベント、つまり、クリックイベント、ドラッグイベント、 ボタン押し下げイベント、モーションイベントを扱えます。 すべてのマウスイベントは、リストで表現します。 リストのCARはイベント型であり、 どの修飾キーとともにどのマウスボタンを使ったかを表します。 イベント型では、ダブル(連続2回)/トリプル(連続3回)の 押し下げも区別できます(see Repeat Events)。 リストの残りの要素は、位置情報と時間情報です。
キーの探索では、イベント型のみが意味を持ちます。
型が同じであれば、異なるイベントでも同じコマンドを実行します。
コマンドでは、対話指定コードe
を用いてイベントの完全な値を参照できます。
See Interactive Codes。
マウスイベントで始まるキー列は、カレントバッファのキーマップではなく、 マウスが入っているウィンドウのバッファのキーマップを用いて読まれます。 つまり、あるウィンドウ内でクリックしても、 当該ウィンドウやバッファを選択するとは限らず、 その動作はキー列のコマンドバインディングで完全に制御されます。
ユーザーがマウスのボタンを同じ場所で押し下げてから離すと、 クリック(click)イベントが生成されます。 マウスクリックイベントはつぎの形式です。
(event-type (window buffer-pos (x . y) timestamp) click-count)
通常の各要素の意味はつぎのとおりです。
mouse-1
、mouse-2
、...の1つである。
ファンクションキーの場合と同様に、
アルト、コントロール、ハイパー、メタ、シフト、スーパーの
修飾キーを表す接頭辞A-
、C-
、H-
、M-
、
S-
、s-
も使える。
このシンボルはイベントのイベント型としての役割も果たす。
キーバインディングはイベント型でイベントを指定する。
したがって、mouse-1
に対するキーバインディングは、
イベント型event-typeがmouse-1
であるすべてのイベントに適用される。
(0 . 0)
とした
クリック位置のピクセル単位の座標。
モード行やスクロールバーなどのスクリーンの特別な部分で発生したイベントでは、 buffer-pos、xとyの意味は少々異なります。
スクロールバーの内側でのクリックでは、
buffer-posはシンボルvertical-scroll-bar
か
horizontal-scroll-bar
であり、
(x . y)
は(portion . whole)
に
置き換えられます。
ここで、portionはスクロールバーの先頭や左端からのクリック位置、
wholeはスクロールバー全体の長さです。
モード行やウィンドウwindowを右隣のものと区切る
縦方向の区切り行の内側では、
buffer-posはシンボルmode-line
かvertical-line
です。
モード行では、yは意味のあるデータではありません。
縦方向の区切り行では、xは意味のあるデータではありません。
1つの特別な場面では、 buffer-posは単一のシンボルではなく(上に述べた1つの)シンボルを 含んだリストになります。 イベントに対する仮想的なプレフィックスキーを入力ストリームに挿入すると このようになります。 See Key Sequence Input。
Emacsには、ドラッグイベントがあります。 ユーザーがマウスボタンを押し下げてから、 ボタンを離すまえに別の文字位置へマウスを動かすと ドラッグ(drag)イベントが発生します。 マウスのすべてのイベントのように、Lispではドラッグイベントは リストとして表現されます。 つぎのように、リストは開始マウス位置と終了位置を記録しています。
(event-type (window1 buffer-pos1 (x1 . y1) timestamp1) (window2 buffer-pos2 (x2 . y2) timestamp2) click-count)
ドラッグイベントでは、シンボルevent-typeの名前には
接頭辞drag-
が付きます。
たとえば、ボタン2を押し下げてマウスをドラッグすると
イベントdrag-mouse-2
が生成されます。
イベントの2番目と3番目の要素は、ドラッグの開始位置と終了位置を与えます。
なお、データにはクリックイベントと同じ意味があります(see Click Events)。
ドラッグイベントかどうかを区別せずに、
マウスの任意のイベントの2番目の要素は同じ方法で参照できます。
接頭辞drag-
は、
C-
やM-
のような修飾キー接頭辞に続きます。
read-key-sequence
が、
キーバインディングを持たないドラッグイベントを受け取り、かつ、
それに対応するクリックイベントにはバインディングがある場合、
ドラッグイベントの開始位置をクリック位置とするクリックイベントに変換します。
つまり、望まなければ、読者はクリックイベントとドラッグイベントを区別する
必要がありません。
クリックイベントとドラッグイベントは、 ユーザーがマウスボタンを離したときに発生します。 ボタンを離すまではクリックとドラッグを区別する方法がないため、 ボタンを離すまで発生しえません。
ボタンを押し下げたらただちに動作を始めたい場合には、
読者はボタン押し下げ(button-down)イベントを処理する必要があります。
8
ボタンを押し下げるとただちに発生します。
それらは、シンボルevent-typeの名前に
接頭辞down-
があることを除けば、
クリックイベント(see Click Events)とまったく同じリストで表現されます。
接頭辞down-
は、C-
やM-
のような修飾キー接頭辞に続きます。
関数read-key-sequence
は、
コマンドバインディングを持たないボタン押し下げイベントを無視します。
したがって、Emacsのコマンドループもそれらを無視します。
つまり、読者がボタン押し下げイベントでなにかをしたいのでなければ、
読者はボタン押し下げイベントを定義する必要はありません。
ボタン押し下げイベントを定義する理由は、
ボタンが離されるまで(モーションイベントを読んで)マウスの動きを
追跡するためです。
See Motion Events。
マウスを動かさずに同一のマウスボタンを素早く連続して押し下げると、 Emacsは2回目以降の押し下げに対して 特別な繰り返し(repeat)マウスイベントを生成します。
もっとも一般的な繰り返しイベントはダブルクリック(double-click) イベントです。 ボタンを2回クリックすると、Emcasはダブルクリックイベントを生成します。 (他のすべてのクリックイベントのように)読者がボタンを離したときに イベントが生成されます。
ダブルクリックイベントのイベント型には、接頭辞double-
が含まれます。
したがって、<meta>を押し下げて2番目のボタンをダブルクリックすると、
LispプログラムにはM-double-mouse-2
が送られます。
ダブルクリックイベントにバインディングがなければ、
対応する普通のクリックイベントを用いて実行します。
したがって、実際に利用したくない限りは、
読者はダブルクリック機能に注意する必要はありません。
ユーザーがダブルクリックすると、Emacsはまず普通のクリックイベントを生成し、 つぎにダブルクリックイベントを生成します。 したがって、ダブルクリックイベントのコマンドバインディングでは、 すでに普通のクリックコマンドが動作済みであると仮定して設計する必要があります。 普通のクリックの結果をもとに望みのダブルクリックの結果を得るようにします。
普通のクリックの意味にダブルクリックの意味を 『追加』するようにすると便利です。 ダブルクリックのユーザーインターフェイスはこのようにすることを勧めます。
ボタンをクリックして、ふたたびボタンを押し下げてそのままマウスを動かすと、
最終的にボタンを離した時点で、ダブルドラッグ(double-drag)イベントが
生成されます。
そのイベント型にはdrag
のかわりにdouble-drag
が含まれます。
ダブルドラッグイベントにバインディングがなければ、
Emacsは普通のドラッグイベントとしてバインディングを探します。
ダブルクリックイベントやダブルドラッグイベントを生成するまえに、
ユーザーがボタンを2回目に押し下げたとき、
Emacsはダブルダウン(double-down)イベントを生成します。
このイベント型にはdown
のかわりにdouble-down
が含まれます。
ダブルダウンイベントにバインディングがなければ、
Emacsは普通のボタン押し下げイベントとしてバインディングを探します。
どちらでもバインディングがみつからなければ、ダブルダウンイベントは無視します。
まとめると、ボタンをクリックしてただちに再度ボタンを押し下げると、 Emacsは、はじめのクリックに対してボタン押し下げイベントと クリックイベントを生成し、 再度ボタンを押し下げるとダブルダウンイベントを生成し、 最後にダブルクリックイベントかダブルドラッグイベントを生成します。
ボタンを2回クリックしてから再度押し下げる操作を素早く行うと、
Emacsは、トリプルダウン(triple-down)イベントに続けて
トリプルクリック(triple-click)イベントか
トリプルドラッグ(triple-drag)イベントを生成します。
これらのイベント型にはdouble
のかわりにtriple
が含まれます。
トリプルのイベントにバインディングがなければ、
Emacsは対応するダブルのイベントを使います。
ボタンを3回以上クリックしてから再度押し下げると、 3回目以降の押し下げに対するイベントはすべてトリプルのイベントです。 Emacsは、クアドラプル(4回)、クインタプル(5回)、…などの イベントは生成しません。 しかし、イベントリストを調べれば、ボタンを何回押したか正確にわかります。
event-click-count event | Function |
この関数は、イベントeventにおいてボタンが連続して押された回数を返す。 eventが、ダブルダウンイベント、ダブルクリックイベント、 ダブルドラッグイベントであると、値は2である。 eventがトリプルのイベントであると、値は3かそれ以上である。 eventが(繰り返しイベントではない)普通のマウスイベントであると、 値は1である。 |
double-click-time | Variable |
繰り返しイベントが生成されるためには、
同じスクリーン位置において連続してマウスボタンを押し下げ、しかも、
各押し下げの間隔はdouble-click-time の値未満(ミリ秒)である必要がある。
double-click-time にnil を設定すると、
連続したクリックの検出を禁止する。
t を設定すると時間制限をなくし、
Emacsは連続したクリックの検出を位置だけで行う。
|
Emacsは、ボタン操作を伴わないマウスの移動を表す マウスモーション(mouse motion)イベントを生成することがあります。 マウスモーションイベントはつぎのようなリストで表現されます。
(mouse-movement (window buffer-pos (x . y) timestamp))
リストの2番目の要素は、クリックイベント(see Click Events)と同様に、 マウスの現在位置を表します。
スペシャルフォームtrack-mouse
により、
その本体の内側ではモーションイベントの生成を可能にできます。
フォームtrack-mouse
の外側では、
Emacsはマウスの移動のみに対するイベントを生成しないので、
それらのイベントは現れません。
See Mouse Tracking。
ウィンドウシステムは、どのウィンドウにキーボード入力を与えるかを ユーザーが制御するための一般的な方法を提供します。 ウィンドウを選ぶことをフォーカス(focus)と呼びます。 ユーザーがEmacsのフレームを切り替える操作を行うと、 フォーカスイベント(focus event)が生成されます。 グローバルキーマップにあるフォーカスイベントの普通の定義は、 Emcasの新たなフレームを選択するようになっていて、 これはユーザーが期待することです。 See Input Focus。
Lispでは、フォーカスイベントはつぎのようなリストで表現されます。
(switch-frame new-frame)
ここで、new-frameは切り替え先のフレームです。
Xのほとんどのウィンドウマネージャは、 マウスをウィンドウへ入れるだけで当該ウィンドウにフォーカスが設定される ようになっています。 フレームにマウスが入るとカーソルの形状を変更するので、 Emacsでもそのようにします。 しかし、Lispプログラムにとっては、 なんらかの入力が到着するまではフォーカスの変更について知る必要がありません。 そのため、ユーザーが実際にキーボードのキーを打つか 新たなフレームでマウスボタンを押し下げたときだけ、 Emacsはフォーカスイベントを生成します。 フレーム間でマウスを動かしただけでは、フォーカスイベントは生成されません。
キー列の途中にフォーカスイベントが現れると、キー列を乱します。 そのため、Emacsはキー列の途中にはフォーカスイベントを生成しません。 ユーザーがキー列の途中で、つまり、 プレフィックスキーのあとでフォーカスを変更すると、 複数イベントのキー列のまえかうしろにフォーカスイベントを移動し、 途中には現れないようにEmacsはイベントの順序を並び替えます。
ウィンドウシステム内で起きたことを表す他のイベントもあります。
(delete-frame (frame))
イベントdelete-frame
の標準定義はフレームframeの削除である。
(iconify-frame (frame))
ignore
である。
というのは、フレームはすでにアイコンになっているので、
Emacsが行うことはなにもないからである。
このイベント型の目的は、
必要ならばその種のイベントを読者が追跡できるようにしておくことである。
(make-frame-visible (frame))
ignore
である。
というのは、フレームはすでに見えるようになっているので、
Emacsが行うことはなにもないからである。
(mouse-wheel position delta)
要素deltaはホイールの回転方向と回転量である。 その絶対値はホイールを回すごとに増加する数である。 負のdeltaは、逆転、つまり、ユーザーへ近付く方向への回転を表し、 正のdeltaは、順転、つまり、ユーザーから遠ざかる方向への回転を表す。
要素positionはイベントの発生位置を表し、 マウスクリックイベントで使われる形式と同じである。
この種のイベントは、ある種のシステムでのみ生成される。
(drag-n-drop position files)
要素positionはイベントの発生位置を表し、 マウスクリックイベントで使われる形式と同じであり、 要素filesはドラッグ&ドロップされたファイル名のリストである。 このイベントを扱う通常の処理は、それらのファイルを訪問することである。
現状では、この種のイベントは、ある種のシステムでのみ生成される。
これらのイベントがキー列の途中、つまり、 プレフィックスキーのうしろに現れると、 複数イベントのキー列のまえかうしろに当該イベントを移動し、 途中には現れないようにEmacsはイベントの順序を並び替えます。
ユーザーが同じ場所でマウスの左ボタンを押し下げてから離すと、 つぎのようなイベント列が生成されます。
(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番目のボタンをウィンドウのモード行で押し下げ、 マウスを別のウィンドウへドラッグすると、 つぎのような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))
各イベントにはイベント型(event type)があって、 キーバインディング処理のためにイベントを分類します。 キーボードイベントでは、イベント型はイベントの値に等しいです。 したがって、文字に対するイベント型は文字であり、 ファンクションキーに対するイベント型はシンボルそのものです。 リストであるイベントでは、イベント型はリストのCARにあるシンボルです。 したがって、イベント型はつねにシンボルか文字です。
イベント型が同じであるイベントは、キーバインディングに関する限り同じです。 つまり、それらは同じコマンドを実行します。 しかし、これは、それらが必ずしも同じことを行うという意味ではありません。 イベント全体を調べてなにを行うかを決定するコマンドもあります。 たとえば、マウスイベントの生起位置を使って、 バッファのどの部分を処理するかを決めるコマンドもあります。
イベントをおおまかに分類すると有用な場合もあります。 たとえば、他の修飾キーやマウスボタンには関係なしに、 <META>キーが使われているイベントかどうか調べたいことがあるでしょう。
関数event-modifiers
やevent-basic-type
は、
そのような情報を便利に与えるためのものです。
event-modifiers event | Function |
この関数は、eventにある修飾子のリストを返す。
修飾子はシンボルであり、shift 、control 、
meta 、alt 、hyper 、super である。
さらに、マウスイベントシンボルの修飾子リストには、
必ず、click 、drag 、down の1つが含まれる。
引数eventは、イベントオブジェクト全体であるか、単なるイベント型である。 例を示す。 (event-modifiers ?a) => nil (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) クリックイベントに対する修飾子リストには |
event-basic-type event | Function |
この関数は、eventにあるキーやマウスボタンを返す。
たとえばつぎのとおり。
(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 |
mouse-movement-p object | Function |
この関数は、objectがマウス移動のイベントならばnil 以外を返す。
|
event-convert-list list | Function |
この関数は、修飾子名と基本イベント型のリストを
それらが示すイベント型に変換する。
たとえばつぎのとおり。
(event-convert-list '(control ?a)) => 1 (event-convert-list '(control meta ?a)) => -134217727 (event-convert-list '(control super f1)) => C-s-f1 |
本節では、マウスボタンイベントやモーションイベント内のデータを 参照するための便利な関数について述べます。
つぎの2つの関数は、以下の形式のリストであるマウスボタンイベントの 開始位置や終了位置を返します。
(window buffer-position (x . y) timestamp)
event-start event | Function |
イベントeventの開始位置を返す。
eventがクリックイベントやボタン押し下げイベントであると、 イベントの位置を返す。 eventがドラッグイベントであると、ドラッグの開始位置を返す。 |
event-end event | Function |
イベントeventの終了位置を返す。
eventがドラッグイベントであると、 ユーザーがマウスボタンを離したときの位置を返す。 eventがクリックイベントかボタン押し下げイベントであると、 実際の値は開始位置であり、 その種のイベントにある唯一の位置情報である。 |
つぎの5つの関数は、上に述べた位置情報のリストを引数として、 そのさまざまな部分を返す。
posn-window position | Function |
position内のウィンドウを返す。 |
posn-point position | Function |
positionのバッファ内位置を返す。 これは整数である。 |
posn-x-y position | Function |
position内のピクセル単位のxy座標を
コンスセル(x . y) として返す。
|
posn-col-row position | Function |
positionの(文字単位の)行(row)とコラム(col)の座標を
コンスセル(col . row) として返す。
これらは実際にはposition内のxとyの値から計算される。
|
posn-timestamp position | Function |
position内の時刻情報を返す。 |
つぎの関数はスクロールバーでのイベントを解読するのに便利です。
scroll-bar-event-ratio event | Function |
スクロールバー内でのイベントから、スクロールバーに対する縦方向の位置を返す。
その値は2つの整数を含むコンスセル(portion . whole) であり、
その比は位置の割合を表す。
|
scroll-bar-scale ratio total | Function |
この関数は(実質的には)ratioにtotalを掛け、
結果を整数に丸める。
引数ratioは数ではなく(num . denom) であり、
典型的にはscroll-bar-event-ratio が返す値である。
この関数はスクロールバー内での位置を バッファ内での位置へ換算するのに便利である。 つぎのように行う。 (+ (point-min) (scroll-bar-scale (posn-x-y (event-start event)) (- (point-max) (point-min)))) スクロールバー内でのイベントには、 xy座標のかわりに比を表す2つの整数があることに注意。 |
文字列が使われるほとんどの場面では、 文字列にはテキスト文字、つまり、 バッファやファイルにある文字と同じ種類のものが入っていると考えています。 文字列にはキーボード文字が入っているとみなして使うLispプログラムもあります。 たとえば、文字列には、キー列やキーボードマクロの定義が入っているのです。 しかし、キーボード文字を文字列に保持するのは複雑であり、 それは歴史的な互換性を保つためにするのであり、 また、つねに可能とは限りません。
新しいプログラムでは、キーボードイベントを文字列に保持しないで、 このような複雑さを避けるように推奨します。 つぎのようにします。
lookup-key
やdefine-key
に対する
引数以外にも使うつもりならば、文字列のかわりにベクトルを使う。
たとえば、read-key-sequence
のかわりにread-key-sequence-vector
を
this-command-keys
のかわりにthis-command-keys-vector
を使う。
define-key
に直接渡す場合であっても、ベクトルで書く。
listify-key-sequence
(see Event Input Misc)を使って、
それをリストに変換しておく。
複雑さの原因は、キーボード入力に含まれる修飾ビットにあります。 メタ修飾子以外の修飾ビットを文字列に入れることは不可能であり、 メタ修飾子は特別な場合として唯一許されているのです。
初期のGNU Emacsでは、メタ文字を128から255の範囲のコードで表現していました。
その当時、基本文字コードは0から127でしたから、
キーボード文字のすべてのコードは文字列に収まったのです。
多くのLispプログラムでメタ文字を表すために文字列定数内で\M-
を使い、
特に、define-key
や類似の関数に対する引数に使われ、
キー列やイベント列はつねに文字列で表現されていました。
127を超える大きな基本文字コードと追加の修飾ビットを扱えるようにしたとき、 メタ文字の表現方法を変更せざるをえませんでした。 現在、メタ修飾子を表す文字内のビットは であり、そのような数を文字列に入れることはできません。
文字列定数で\M-
を使っているプログラムを扱えるように、
文字列にメタ文字を入れるための特別な規則があります。
以下は、文字列を入力文字の列として解釈するための規則です。
キーボード入力文字の文字列を作るread-key-sequence
などの関数は
つぎの規則に従います。
つまり、文字列に収まらないイベントであるときには、
文字列のかわりにベクトルを作ります。
読者が文字列で\M-
の入力構文を使うと、
それらは128から255の範囲のコードになります。
対応するキーボードイベントを文字列に保存するように変更したときに得られる
コードと同じです。
したがって、文字列内のメタイベントは、それらがどのように文字列に
収められたかに関わらず、整合性のある動作をします。
しかし、本節のはじめに述べた推奨方法に従ってこれらのことがらを避けるほうが、 ほとんどのプログラムはよりよく動作するでしょう。
エディタコマンドループは、
関数read-key-sequence
を使ってキー列を読み取ります。
なお、関数read-key-sequence
は関数read-event
を使います。
これらやイベント入力を扱う他の関数は、Lispプログラムからも使えます。
Temporary Displaysのmomentary-string-display
、
および、Waitingのsit-for
を参照してください。
端末の入力モードの制御や端末入力のデバッグに関する関数や変数については、
See Terminal Input。
入力イベントを読むときにそれらを変換したり修正する機能については、
See Translating Input。
上位レベルの入力機能については、Minibuffersを参照してください。
コマンドループは、read-key-sequence
を呼ぶことで
キー列の入力を読み取ります。
Lispプログラムからこの関数を呼び出してもよく、
たとえば、describe-key
は、
説明対象とするキーを読むためにこの関数を使います。
read-key-sequence prompt | Function |
この関数は、キー列を読み取り文字列かベクトルとして返す。
完全なキー列を収集し終えるまで、
つまり、現在活性なキーマップにおいて、非プレフィックスコマンドを
指定するのに十分になるまで、イベントを読み続ける。
イベントがすべて文字であり、かつ、それらが文字列に収まるならば、
引数promptは、プロンプトとしてエコー領域に表示する文字列であるか、
あるいは、プロンプトを表示しないことを意味する 以下の例では、プロンプト (read-key-sequence "?") ---------- Echo Area ---------- ?C-x C-f ---------- Echo Area ---------- => "^X^F" 関数 |
read-key-sequence-vector prompt | Function |
これはread-key-sequence と同様であるが、
つねにベクトルとしてキー列を返し、文字列としてはけっして返さない。
see Strings of Events。
|
入力文字が大文字であって、それらにキーバインディングがないとき、
対応する小文字にキーバインディングがあれば、
read-key-sequence
は文字を小文字に変換します。
lookup-key
はこのような変換を行わないことに注意してください。
関数read-key-sequence
は、ある種のマウスイベントも変換します。
バインディングのないドラッグイベントをクリックイベントに変換したり、
バインディングのないボタン押し下げイベントを完全に無視します。
さらに、フォーカスイベントとその他のウィンドウイベントを並び替えて、
それらが他のイベントのキー列の途中に現れないようにします。
マウスイベントが、モード行やスクロールバーなどのウィンドウの特別な部分で
生起しても、特別なイベント型はなく、マウスボタンや修飾キーの
組み合わせを普通どおりに表したシンボルです。
ウィンドウのどの部分かに関する情報は、
イベント内の別の部分、つまり、座標に入っています。
しかし、read-key-sequence
は、その情報を
シンボルmode-line
、vertical-line
、horizontal-scroll-bar
、
vertical-scroll-bar
を用いた仮想的な『プレフィックスキー』に変換します。
ウィンドウの特別な部分におけるマウスクリックの意味は、
これらの仮想的なプレフィックスキーを用いてキー列を定義することで
定義できます。
たとえば、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))]
num-input-keys | Variable |
この変数の値は、現在のEmacsセッションにおいて、 これまでに処理されたキー列の個数である。 これには、端末から読み取ったキー列、および、 実行したキーボードマクロから読み取ったキー列が含まれる。 |
num-nonmacro-input-events | Variable |
この変数は、端末からこれまでに受け取った入力イベントの総個数を保持する。 キーボードマクロで生成されたものは含まない。 |
コマンド入力用の最低レベルの関数は、単一イベントを読み取る関数です。
read-event &optional prompt suppress-input-method | Function |
この関数は、必要ならばイベントの到着を待って、
コマンド入力のつぎのイベントを読み取って返す。
イベントは、ユーザーか(実行中の)キーボードマクロから直接得る。
promptが suppress-input-methodが 変数
(read-event) => right |
read-char | Function |
この関数はコマンド入力の文字を読み取りそれを返す。
文字を得るまで、文字以外のイベントはすべて破棄する。
最初の例では、ユーザーは文字1(ASCIIコード49)を打つ。
2番目の例は、 (read-char) => 49 ;; これを評価するために読者はM-:を使うと仮定する (symbol-function 'foo) => "^[:(read-char)^M1" (execute-kbd-macro 'foo) -| 49 => nil |
read-event
は、あれば現在の入力方式も起動します。
input-method-function
がnil
以外であれば、
それは関数であるはずです。
read-event
が修飾ビットのない(<SPC>を含む)印字文字を読み取ると、
引数としてイベントを渡してその関数を呼び出します。
input-method-function | Variable |
これがnil 以外であると、その値は現在の入力方式関数を指定する。
注意: |
入力方式関数は、入力として使われるイベントのリストを返すべきです。
(リストがnil
であると入力がなかったことを意味し、
read-event
は別のイベントを待つ。)
これらのイベントは、
unread-command-events
内のイベントよりまえに処理されます。
入力方式関数が返したイベントは、それらが修飾ビットがない印字文字であっても、
入力方式関数に再度渡されることはありません。
入力方式関数がread-event
やread-key-sequence
を呼び出すときには、
input-method-function
をnil
に束縛して
再帰呼び出しを防ぐべきです。
キー列の2番目以降のイベントを読むときには、入力方式関数を呼び出しません。
したがって、それらの文字は、入力方式処理の対象ではありません。
入力方式の処理では、
overriding-local-map
とoverriding-terminal-local-map
の値を
検査するのがよいです。
これらの変数のいずれかがnil
以外であるときには、
入力方式ではその引数をリストに入れ、
それ以上処理せずにそのリストを返すべきです。
ユーザーに文字入力を促して、コントロール文字やメタ文字を
文字そのものや文字の8進数コードで手軽に入力できるようにするには、
関数read-quoted-char
を使います。
コマンドquoted-insert
は、この関数を使っています。
read-quoted-char &optional prompt | Function |
この関数はread-char に似ているが、
最初に読んだ文字が8進数字文字(0-7)であると、
任意個数の8進数字文字を読み取り(8進数字文字以外が現れると止める)、
その数値の文字コードが表す文字を返す。
最初の文字を読むと中断を抑制するので、 ユーザーはC-gを入力できる。 see Quitting。 promptを与えると、それはユーザーへのプロンプトを表す文字列を指定する。
プロンプト文字列はつねにエコー領域に表示され、あとに つぎの例では、ユーザーは8進数177(10進数では127)を打つ。 (read-quoted-char "What character") ---------- Echo Area ---------- What character-177 ---------- Echo Area ---------- => 127 |
本節では、イベントを処理せずに『まえもって覗き見』する方法、
処理待ちの入力の有無の検査方法、処理待ちの入力の破棄方法について述べます。
関数read-passwd
も参照してください(see Reading a Password)。
unread-command-events | Variable |
この変数は、コマンド入力として読まれることを
待っているイベントのリストを保持する。
イベントはリストに現れる順に使われ、使われると1つ1つ取り除かれる。
関数でイベントを読んだあとにそれを使わない場面があるため、 この変数が必要になる。 この変数にイベントを保存すると、 コマンドループやコマンド入力を読む関数によって通常どおり処理される。 たとえば、数値前置引数を実現する関数は、任意個数の数字文字を読み取る。 数字文字でないイベントをみつけたら、そのイベントを読み戻して、 コマンドループが通常どおりに読めるようにする必要がある。 同様に、インクリメンタルサーチでは、この機能を使って 探索においては意味を持たないイベントを読み戻す。 なぜなら、そのようなイベントは探索を終了させ、 通常どおり実行される必要があるからである。
もっとも最近に読み戻したイベントが最初に再度読まれるように、 普通はこのリストの先頭にイベントを追加する。 |
listify-key-sequence key | Function |
この関数は、文字列やベクトルであるkeyを個々のイベントのリストに変換する。
この結果はunread-command-events に入れられる。
|
unread-command-char | Variable |
この変数は、コマンド入力として読まれる文字を保持する。
値「-1」は、『空』を意味する。
この変数はほとんど廃れており、
かわりに |
input-pending-p | Function |
この関数は、現在、コマンド入力があるかどうかを調べる。
ただちに返るが、入力があれば値t を、
さもなければnil を返す。
入力がないのにt を返すことが稀にある。
|
last-input-event | Variable |
last-input-char | Variable |
この変数は、コマンドの一部として、あるいは、Lispプログラムが明示的に
読み取った最後の端末入力イベントを記録する。
以下の例で、Lispプログラムは文字1(ASCIIコード49)を読む。
それが (progn (print (read-char)) (print last-command-event) last-input-event) -| 49 -| 5 => 49 Emacs 18版との互換性のために、別名 |
discard-input | Function |
この関数は端末入力バッファの内容を廃棄し、
定義中のキーボードマクロを取り消す。
これはnil を返す。
以下の例で、フォームを評価しはじめてから、ユーザーは何文字か打つ。
(progn (sleep-for 2) (discard-input)) => nil |
特殊イベントは、読まれるとただちに非常に低レベルで処理されます。
関数read-event
はこれらのイベントをそれ自身で処理してしまい、
それらを返すことはありません。
このように処理されるイベントは表示されることはなく、
キー列に組み込まれることもなく、
last-command-event
や(this-command-keys)
の値に
現れることもありません。
特殊イベントが数値引数を破棄することはなく、
unread-command-events
で読み戻すことはできません。
特殊イベントがキーボードマクロに現れることはなく、
読者がキーボードマクロを定義しているときに、
特殊イベントがキーボードマクロに記録されることはありません。
しかし、それらのイベントは、
読まれた直後にはlast-input-event
に現れますから、
これからイベントの定義で実際のイベントを見ることができます。
iconify-frame
、make-frame-visible
、delete-frame
の
イベント型は、通常このように処理されます。
特殊イベントをどのように処理するか、
どのイベントが特殊イベントであるかを定義する
キーマップは変数special-event-map
にあります(see Active Keymaps)。
待機関数は、指定時間経過するか入力がくるまで待つように設計してあります。
たとえば、ユーザーに表示を眺める時間を与えるために
計算途中で休止したいでしょう。
sit-for
は、休止してスクリーンを更新し、
入力がくるとただちに戻ります。
一方、sleep-for
はスクリーンを更新せずに休止します。
sit-for seconds &optional millisec nodisp | Function |
この関数は(処理待ちのユーザーからの入力がなければ)再表示を行い、
seconds秒休止するか、入力がくるまで待つ。
入力がこずに(Event Input Miscのinput-pending-p を参照)
指定時間だけ休止した場合は、戻り値はt である。
さもなければ、戻り値はnil である。
引数secondsは整数である必要はない。
それが浮動小数点数であると、 省略可能な引数millisecは、ミリ秒単位の追加待ち時間を指定する。 これはsecondsで指定した時間に加えられる。 秒未満を扱えないシステムでは、 millisecに0以外を指定するとエラーになる。 入力がくると再表示をつねに取り止め、
再表示開始まえに入力がくると、いっさい再表示しない。
したがって、処理待ちの入力があると、再表示を強制する方法はない。
しかし、処理待ちの入力がなければ、 nodispが フレームをアイコンにしたりアイコンにしたフレームを開くと
イベントが生成されるため、
|
sleep-for seconds &optional millisec | Function |
この関数は表示を更新せずに単にseconds秒だけ休止する。
入力にはいっさい注意を払わない。
nil を返す。
引数secondsは整数である必要はない。
それが浮動小数点数であると、 省略可能な引数millisecは、ミリ秒単位の追加待ち時間を指定する。 これはsecondsで指定した時間に加えられる。 秒未満を扱えないシステムでは、 millisecに0以外を指定するとエラーになる。 遅延を保証したい場合に |
現在時刻を取得する関数についてはSee Time of Day。
Lisp関数が動作中にC-gを打つと、 Emacsがなにを行っていても中断を引き起こします。 つまり、もっとも内側の活性なコマンドループに制御が戻ります。
コマンドループがキーボード入力を待っているときにC-gを打っても、
中断を引き起こさずに、普通の入力文字として動作します。
もっとも単純な場合、C-gはコマンドkeyboard-quit
を実行しますが、
その効果は中断を引き起こすことですから、読者には区別できないはずです。
しかし、プレフィックスキーに続けてC-gを打つと、
それらは組み合わされて未定義キーになります。
その効果は、前置引数を含めてプレフィックスキーを取り消します。
ミニバッファでは、C-gには別の定義があって、 ミニバッファを強制終了させます。 つまり、ミニバッファから抜け出て中断します。 (単に中断したのでは、ミニバッファ内で コマンドループに戻るだけである。) コマンドループで入力を読んでいるときにC-gで直接中断しない理由は、 このようにミニバッファでその意味を再定義できるようにするためです。 ミニバッファでは、プレフィックスキーに続くC-gは再定義してなく、 プレフィックスキーと前置引数を取り消すという通常の効果を持ちます。 C-gがつねに直接中断するのでは、このようにすることさえ不可能です。
C-gが直接に中断するときには、
変数quit-flag
にt
を設定します。
Emacsはこの変数を適切なときに検査しnil
でないと中断します。
したがって、quit-flag
にnil
以外を設定すると
中断を引き起こします。
Cのコードのレベルでは、どこでも中断できるわけではありません。
quit-flag
を検査している特別な箇所だけです。
このようにするのは、それ以外の箇所で中断すると
Emacsの内部状態に矛盾をきたす可能性があるからです。
中断は安全な場所まで延期されるので、
中断によってEmcasがクラッシュすることはありません。
read-key-sequence
やread-quoted-char
などのある種の関数は、
入力を待っている場合であっても中断を完全に抑制します。
中断するかわりに、C-gは入力として働きます。
read-key-sequence
の場合、コマンドループにおいて
C-gの特別なふるまいをもたらします。
read-quoted-char
の場合、
C-qでC-gをクォートできるようになります。
変数inhibit-quit
にnil
以外の値を束縛することで
Lisp関数のある部分において中断を抑制できます。
そうすると、C-gはそれでもいつもどおり
quit-flag
をt
にしますが、
その通常の結果である中断は抑制されます。
最終的にフォームlet
の終りで束縛が解除されるなどして
inhibit-quit
が再度nil
になります。
その時点でもquit-flag
がnil
以外であると
要求した中断がただちに起こります。
このふるまいは、プログラムの『臨界領域』では
中断が起こらないことを保証する理想的なものです。
(read-quoted-char
などの)ある種の関数では、
C-gは特別に処理され中断を引き起こしません。
inhibit-quit
にt
を束縛して入力を読み取り、
inhibit-quit
が再度nil
になるまえに
quit-flag
をnil
にすることでそのようにします。
これをread-quoted-char
の定義の以下の抜粋で示しましょう。
最初の入力文字のあとで通常の中断を許す方法も示しています。
(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))
quit-flag | Variable |
inhibit-quit がnil であれば、
この変数がnil 以外であるとEmacsはただちに中断する。
C-gは、inhibit-quit に関わらず、
通常、quit-flag にnil 以外を設定する。
|
inhibit-quit | Variable |
この変数は、quit-flag がnil 以外の値に設定されたときに
Emacsが中断すべきかどうかを決定する。
inhibit-quit がnil 以外であると、
quit-flag に特別な意味はない。
|
keyboard-quit | コマンド |
この関数は(signal 'quit nil) でquit 条件を通知する。
これは中断と同じことを行う。
(Errorsのsignal を参照。)
|
中断として使うC-g以外の特殊文字を使えます。
Terminal Inputの関数set-input-mode
を参照してください。
Emacsのほとんどのコマンドは、前置引数(prefix argument)、
つまりコマンド自身のまえに指定された数を利用できます。
(前置引数とプレフィックスキーを混同しないこと。)
前置引数はつねに値で表現され、
nil
であると現在は前置引数がないことを表します。
各コマンドは、前置引数を使ってもよいし、無視してもかまいません。
前置引数には2つの表現方法があります。 生(raw)と数値(numeric)です。 エディタコマンドループでは、内部的には生の表現を使い、 その情報を保持するLisp変数もそのようにしますが、 コマンドではどちらの表現を要求してもかまいません。
生の前置引数の値にはつぎの可能性があります。
nil
。
その数値としての値は1であるが、
多くのコマンドではnil
と整数1を区別する。
-
。
数字文字なしにM--やC-u -を打ったことを表す。
これに等価な数値は-1であるが、
整数-1とシンボル-
を区別するコマンドもある。
いろいろな前置引数でつぎの関数を呼び出す例を示します。
(defun display-prefix (arg) "Display the value of the raw prefix arg." (interactive "P") (message "%s" arg))
以下は、生の前置引数で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-arg
とcurrent-prefix-arg
を使います。
他のコマンド向けに前置引数を設定するuniversal-argument
などの
コマンドは、前置引数をprefix-arg
に保持します。
対照的に、current-prefix-arg
には
現在のコマンドに対して前置引数を運ぶ役割があり、
この変数に設定しても以後のコマンドに対する前置引数には
なんの効果もありません。
通常、コマンドは、interactive
宣言により、
「生」か「数値」のいずれの表現の前置引数を使うか指定します。
(See Using Interactive。)
あるいは、変数current-prefix-arg
にある前置引数の値を
関数から直接見てもかまいませんが、
これは見通しのよい方法ではありません。
prefix-numeric-value arg | Function |
この関数は、有効な生の前置引数の値argからそれに等価な数値を返す。
引数は、シンボル、数、リストのいずれかである。
それがnil であると、戻り値は1である。
- であると、戻り値は-1である。
数であると、その数を返す。
リストであると、リストの(数であるはずの)CARを返す。
|
current-prefix-arg | Variable |
この変数は、現在のコマンドに対する生の前置引数を保持する。
コマンドが直接この変数を調べてもよいが、
前置引数を参照する普通の方法は(interactive "P") を使うことである。
|
prefix-arg | Variable |
この変数の値は、つぎの編集コマンド向けの生の前置引数である。
後続のコマンド向けの前置引数を指定するuniversal-argument などの
コマンドは、この変数に設定することで動作する。
|
last-prefix-arg | Variable |
まえのコマンドで使われた生の前置引数の値。 |
つぎのコマンドは、後続のコマンド向けの前置引数を設定するためのものです。 それ以外の目的には呼ばないでください。
universal-argument | コマンド |
このコマンドは入力を読み取り、後続のコマンド向けの前置引数を指定する。 なにをしているか理解していない限り、読者自身でこのコマンドを呼ばないこと。 |
digit-argument arg | コマンド |
このコマンドは、後続のコマンド向けの前置引数に追加する。 引数argは、このコマンドが呼び出されるまえの生の前置引数であり、 前置引数を更新する計算に使われる。 なにをしているか理解していない限り、読者自身でこのコマンドを呼ばないこと。 |
negative-argument arg | コマンド |
このコマンドは、後続のコマンド向けの数値前置引数に追加する。 引数argは、このコマンドが呼び出されるまえの生の前置引数であり、 その値の符号を変えて新たな前置引数とする。 なにをしているか理解していない限り、読者自身でこのコマンドを呼ばないこと。 |
Emacsが動作を始めると、Emacsのコマンドループに自動的に入ります。 このトップレベルのコマンドループからはけっして抜けることはなく、 Emacsが動いている限り動作し続けます。 Lispプログラムからコマンドループを起動することもできます。 そうすると、活性なコマンドループが複数作られることになるので、 それを再帰編集(recursive editing)と呼びます。 再帰編集レベルには、それを起動したコマンドを一時休止させ、 当該コマンドを再開するまでユーザーにどんな編集でも許す効果があります。
再帰編集中に利用可能なコマンドは、トップレベルのコマンドループと 同じものでありキーマップで定義されます。 再帰編集を抜けるための数個の特別なコマンドがあり、 完了すると再帰編集レベルから抜ける別のコマンドもあります。 (再帰編集を抜けるコマンドはつねに利用可能であるが、 再帰編集中でないとなにも行わない。)
再帰編集を含むすべてのコマンドループでは、 コマンドループから実行したコマンドのエラーによって コマンドループから抜け出さないように汎用目的のエラーハンドラを設定します。
ミニバッファでの入力は、特別な種類の再帰編集です。 これには、ミニバッファやミニバッファ用ウィンドウを表示するなどの特別な 処理がありますが、読者が考えるよりは少ないのです。 ミニバッファでは特別なふるまいをするキーもありますが、 それらはミニバッファのローカルマップによるものです。 ウィンドウを切り替えると、Emacsの普通のコマンドを使えます。
再帰編集レベルを起動するには、関数recursive-edit
を呼び出します。
この関数にはコマンドループが含まれています。
さらに、exit
を伴ったcatch
の呼び出しもあり、
これにより、exit
へ投げることで
再帰編集レベルから抜け出せるようになっています
(see Catch and Throw)。
t
以外の値を投げると、recursive-edit
は、
呼び出し側の関数へ普通に戻ります。
コマンドC-M-c(exit-recursive-edit
)は、これを行います。
値t
を投げるとrecursive-edit
に中断を引き起こし、
1つ上のレベルのコマンドループへ制御を戻します。
これを強制終了(aborting)と呼び、
C-](abort-recursive-edit
)で行えます。
ミニバッファを使う場合を除いて、ほとんどのアプリケーションでは 再帰編集を使うべきではありません。 カレントバッファのメジャーモードを 一時的な特別なメジャーモードに変更するほうが、 一般にはユーザーにとってより便利です。 ただし、当該メジャーモードには、 まえのモードに戻るコマンドを用意しておきます。 (rmailのコマンドeは、この方式を使っている。) あるいは、『再帰的に』編集する別のテキストをユーザーに与えたい場合には、 特別なモードの新たなバッファを作成してそれを選択します。 当該モードには、処理を終えてまえのバッファに戻るコマンドを 定義しておきます。 (rmailのコマンドmは、このようにする。)
再帰編集はデバッグに便利です。
ブレークポイントの一種として関数定義に
debug
の呼び出しを挿入しておくと、
その箇所に達したときにいろいろと調べられます。
debug
は再帰編集を起動しますが、デバッガとしての機能も提供します。
query-replace
でC-rを打ったり、
C-x q(kbd-macro-query
)を使ったときにも
再帰編集レベルが使われます。
recursive-edit | Function |
この関数はエディタコマンドループを起動する。
Emacsの初期化過程で自動的に呼び出され、ユーザーが編集できるようにする。
Lispプログラムから呼ばれると、再帰編集レベルに入る。
以下の例では、関数 (defun simple-rec () (forward-word 1) (message "Recursive edit in progress") (recursive-edit) (forward-word 1)) => simple-rec (simple-rec) => nil |
exit-recursive-edit | コマンド |
この関数は、(ミニバッファでの入力を含む)もっとも内側の再帰編集から抜ける。
その関数定義は実質的には(throw 'exit nil) である。
|
abort-recursive-edit | コマンド |
この関数は、再帰編集から抜けたあとでquit を通知することで、
(ミニバッファでの入力を含む)もっとも内側の再帰編集を
要請したコマンドを強制終了する。
その関数定義は実質的には(throw 'exit t) である。
see Quitting。
|
top-level | コマンド |
この関数は、すべての再帰編集を抜ける。 すべての計算を抜け出てメインのコマンドループへ直接戻るため、値は返さない。 |
recursion-depth | Function |
この関数は再帰編集の現在の深さを返す。 活性な再帰編集がなければ0を返す。 |
コマンドを禁止するとは、 コマンドを実行するまえにユーザーの確認を必要とするように コマンドに印を付けることです。 コマンドを禁止するのは、 初心者に混乱をもたらす可能性のあるコマンドに対してや、 コマンドの誤用を防ぐためです。
コマンドを禁止する低レベルの機構は、
コマンドのLispシンボルにnil
以外の属性disabled
を入れることです。
これらの属性は、通常、ユーザーの.emacs
ファイルにて
つぎのようなLisp式で設定します。
(put 'upcase-region 'disabled t)
数個のコマンドにはデフォルトでこれらの属性がありますから、
.emacs
ファイルで属性を取り除きます。
属性disabled
の値は文字列であり、
コマンドを禁止したことを表すメッセージです。
たとえばつぎのとおりです。
(put 'delete-region 'disabled "Text deleted this way cannot be yanked back!\n")
禁止したコマンドを対話的に起動するとどうなるかについて 詳しくはSee Disabling。 コマンドを禁止しても、Lispプログラムから関数として呼び出すことには なんの影響もありません。
enable-command command | コマンド |
これ以降、特別な確認なしにcommandを実行可能にする。
さらに(ユーザーが了承すれば)ユーザーの.emacs ファイルを変更して、
将来のセッションでもそのようにする。
|
disable-command command | コマンド |
これ以降、commandの実行には特別な確認を必要とするようにする。
さらに(ユーザーが了承すれば)ユーザーの.emacs ファイルを変更して、
将来のセッションでもそのようにする。
|
disabled-command-hook | Variable |
禁止したコマンドをユーザーが対話的に起動したとき、
禁止したコマンドのかわりにこのノーマルフックを実行する。
フック関数では、this-command-keys を使って
コマンドを実行するためにユーザーがなにを入力したかを調べ、
コマンドそのものを探し出せる。
see Hooks。
デフォルトでは、 |
コマンドループでは、実行した複雑なコマンドの履歴を管理していて、
それらのコマンドを簡単に繰り返せるようにしています。
複雑なコマンドとは、ミニバッファを使って引数を読むコマンドです。
これには、任意のM-xコマンド、任意のM-:コマンド、
ミニバッファから引数を読み取るinteractive
指定を持つ任意のコマンドが
含まれます。
コマンド自身の実行中に明示的にミニバッファを使っても、
複雑なコマンドとはみなしません。
command-history | Variable |
この変数の値は、最近使った複雑なコマンドのリストであり、
各要素は評価すべきフォームを表す。
編集セッション中は、すべての複雑なコマンドを集積するが、
(変数history-length で指定される)最大サイズに達すると
新しい要素を追加するたびに古い要素を削除する。
command-history => ((switch-to-buffer "chistory.texi") (describe-key "^X^[") (visit-tags-table "~/emacs/src/") (find-tag "repeat-complex-command")) |
この履歴リストは、実際にはミニバッファ履歴(see Minibuffer History) の特別な場合です。 要素は文字列ではなく式なのです。
まえのコマンドを編集したり取り出すための専用コマンドがたくさんあります。
コマンドrepeat-complex-command
とlist-command-history
は、
ユーザーマニュアル
(see Repetition)に説明してあります。
ミニバッファ内では、通常のミニバッファ履歴コマンドを使えます。
キーボードマクロは、 コマンドとみなせる入力イベントのまとまった列であり、 キーの定義から構成されます。 Lispにおけるキーボードマクロの表現は、 イベントを含んだ文字列やベクトルです。 キーボードマクロとLispマクロ(see Macros)を混同しないでください。
execute-kbd-macro kbdmacro &optional count | Function |
この関数はキーボードマクロkbdmacroをイベント列として実行する。
kbdmacroが文字列かベクトルであると、
その中のイベントをユーザーが入力した場合とまったく同様に実行する。
列は単一のキーイベントである必要はない。
通常、キーボードマクロの定義は、複数のキー列を連結したものである。
kbdmacroがシンボルであると、 kbdmacroのかわりにその関数定義を用いる。 それがさらに別のシンボルであると、この処理を繰り返す。 最終的な結果は、文字列かベクトルであること。 結果がシンボルでも文字列でもベクトルでもないと、 エラーを通知する。 引数countは繰り返し回数であり、
kbdmacroをその回数だけ実行する。
countを省略するか
|
executing-macro | Variable |
この変数は、現在実行中のキーボードマクロの定義である
文字列やベクトルを保持する。
これがnil であると、現在実行中のマクロはない。
コマンドでこの変数を検査することで、
マクロ実行で起動されたときのふるまいを変更できる。
読者自身はこの変数に設定しないこと。
|
defining-kbd-macro | Variable |
この変数は、キーボードマクロを定義中かどうかを表す。
コマンドでこの変数を検査することで、マクロ定義中のふるまいを変更できる。
コマンドstart-kbd-macro とend-kbd-macro がこの変数に設定する。
読者自身は設定しないこと。
この変数は現在の端末に対してつねにローカルであり、 バッファに対してローカルにはならない。 see Multiple Displays。 |
last-kbd-macro | Variable |
この変数は、もっとも最近に定義されたキーボードマクロの定義である。
その値は、文字列かベクトル、あるいは、nil である。
この変数は現在の端末に対してつねにローカルであり、 バッファに対してローカルにはならない。 see Multiple Displays。 |
入力イベントとコマンドとのバインディング(対応)は、 キーマップ(keymap)と呼ばれるデータ構造に記録されています。 キーマップの各バインディング(あるいはバインド(bind))は、 個々のイベント型を別のキーマップかコマンドに対応付けます。 イベント型のバインディングがキーマップであると、 後続の入力イベントを探すためにそのキーマップを使います。 コマンドがみつかるまで、これを繰り返します。 この処理全体をキー探索(key lookup)と呼びます。
キーマップ(keymap)は、イベント型を定義に対応させる表です。 (この定義は任意のLispオブジェクトであるが、 コマンドループによる実行においては、特定の型のみが意味を持つ)。 与えられたイベント(あるいはイベント型)とキーマップから、 Emacsはイベントの定義を得ることができます。 イベントは、文字、ファンクションキー、マウス操作です (see Input Events)。
ある単位を構成する入力イベントの列をキー列(key sequence)、 あるいは、略してキー(key)と呼びます。 単一イベントから成る列はつねにキー列であり、複数イベント列もキー列です。
キーマップは、任意のキー列に対するバインディング、 つまり、定義を決定します。 キー列が単一イベントから成るとき、 そのバインディングはキーマップ内の当該イベントの定義です。 複数のイベントから成るキー列のバインディングは、 繰り返し処理で探します。 つまり、最初のイベントのバインディングを探すと、 それはキーマップであるはずです。 続いて、そのキーマップから2番目のイベントのバインディングを探します。 これをキー列のすべてのイベントを使い尽くすまで行います
キー列のバインディングがキーマップであると、
そのキー列をプレフィックスキー(prefix key)と呼びます。
さもなければ、(追加できるイベントがないので)
完全なキー(complete key)と呼びます。
バインディングがnil
であると、キーは未定義であるといいます。
プレフィックスキーの例は、C-c、C-x、C-x 4です。
定義されている完全なキーの例は、X、<RET>、C-x 4 C-fです。
未定義な完全なキーの例は、C-x C-gとC-c 3です。
詳しくは、See Prefix Keys。
キー列のバインディングを探す際の規則では、 (最後のイベントのまえまでにみつかる)途中のバインディングは すべてキーマップであると仮定します。 これが満たされないと、イベントの列があるまとまりを構成せず、 1つのキー列になりません。 いいかえれば、有効なキー列の末尾からいくつかのイベントを取りさると、 つねにプレフィックスキーになる必要があります。 たとえば、C-f C-nはキー列ではありません。 C-fはプレフィックスキーではないので、 C-fで始まる列はキー列ではありません。
複数イベントから成るキー列の候補は、 プレフィックスキーのバインディングに依存します。 したがって、キーマップが異なればそれらは異なり、 バインディングを変更するとそれらは変わります。 しかし、単一イベントから成る列は、プレフィックスに依存しないので、 つねにキー列です。
ある時点には、複数個の主キーマップが活性です。 つまり、キーバインディングの探索に使われます。 それらは、 すべてのバッファが共有するグローバルマップ(global map)、 特定のメジャーモードに関連付けられたローカルマップ(local keymap)、 現在オンにしてあるマイナモードに属する マイナモードキーマップ(minor mode keymaps)です。 (すべてのマイナモードにキーマップがあるわけではない。) ローカルキーマップのバインディングは、 対応するグローバルなバインディングを隠します(つまり優先する)。 マイナモードキーマップは、ローカルとグローバルの両方のキーマップを隠します。 詳しくはSee Active Keymaps。
キーマップは、そのCARがシンボルkeymap
であるリストです。
リストの残りの要素がキーマップのキーバインディングを定義します。
オブジェクトがキーマップであるかどうか検査するには、
関数keymapp
(下記参照)を使います。
キーマップでは、シンボルkeymap
のうしろに、
さまざまな種類の要素が現れます。
(type . binding)
(t . binding)
vector
キーマップにベクトルがあると、ベクトルの要素がnil
であっても
ベクトルが各ASCII文字のバインディングをつねに定義する。
そのようなnil
のバインディングは、
ASCII文字に対しては
キーマップのデフォルトのキーバインディングを無効にする。
しかし、ASCII文字以外のイベントに対しては、
デフォルトのバインディングが意味を持つ。
nil
のバインディングが
低優先順位のキーマップを隠すことはない。
つまり、ローカルマップがnil
のバインディングを与えると、
Emacsはグローバルマップのバインディングを使う。
string
キーマップは、メタ文字に対するバインディングを直接には記録していません。
そのかわりに、キー探索においては、メタ文字は2文字から成る列とみなし、
先頭文字は<ESC>(あるいは、meta-prefix-char
の現在値)です。
つまり、キーM-aは実際には<ESC> aと表現され、
そのグローバルなバインディングは
esc-map
のaでみつかります(see Prefix Keys)。
Lispモードに対するローカルキーマップの例を示します。 これは疎なキーマップです。 <DEL>、<TAB>、C-c C-l、M-C-q、M-C-xに対する バインディングを定義しています。
lisp-mode-map => (keymap ;; <TAB> (9 . lisp-indent-line) ;; <DEL> (127 . backward-delete-char-untabify) (3 keymap ;; C-c C-l (12 . run-lisp)) (27 keymap ;; M-C-qは<ESC> C-qとみなされる (17 . indent-sexp) ;; M-C-xは<ESC> C-xとみなされる (24 . lisp-send-defun)))
keymapp object | Function |
この関数は、objectがキーマップであればt を返し、
さもなければnil を返す。
より正確には、この関数は、
そのCARがkeymap であるリストかどうかを検査する。
(keymapp '(keymap)) => t (keymapp (current-global-map)) => t |
ここでは、キーマップを作成するための関数について述べます。
make-keymap &optional prompt | Function |
この関数は新たに完全なキーマップ
(つまり、すべてのASCII文字に対する定義を収めた
長さ128のベクトル)を作成しそれを返す。
新たなキーマップでは、すべてのASCII文字に対するバインディングは
nil であり、それ以外の種類のイベントに対するバインディングはない。
(make-keymap) => (keymap [nil nil nil ... nil nil]) promptを指定すると、 それはキーマップに対する全面プロンプト文字列になる。 全面プロンプト文字列はメニューキーマップ (see Menu Keymaps)に有用である。 |
make-sparse-keymap &optional prompt | Function |
この関数は、新たに空の疎なキーマップを作成しそれを返す。
新たなキーマップにはイベントに対するバインディングはいっさいない。
引数promptは、make-keymap の場合同様、
プロンプト文字列を指定する。
(make-sparse-keymap) => (keymap) |
copy-keymap keymap | Function |
この関数は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 |
キーマップでは、親キーマップ(parent keymap)と呼ぶ別のキーマップの バインディングを継承できます。 そのようなキーマップはつぎのようになります。
(keymap bindings... . parent-keymap)
このキーマップは、キーを探索する時点において parent-keymapが有するすべてのバインディングを継承しますが、 それらにはbindingsが追加されたり優先します。
define-key
や他のキーバインディング関数でparent-keymapの
バインディングを変更すると、それらの変更は、
bindingsで隠されない限り継承側のキーマップからも見えます。
その逆は真ではありません。
define-key
で継承側のキーマップを修正すると、
それはbindingsに影響するだけでparent-keymapには影響しません。
親キーマップを用いたキーマップを作成する正しい方法は、
set-keymap-parent
を使うことです。
親キーマップを用いたキーマップを直接作成するようなコードがある場合には、
set-keymap-parent
を用いるようにプログラムを変更してください。
keymap-parent keymap | Function |
この関数は、キーマップkeymapの親キーマップを返す。
keymapに親がなければkeymap-parent はnil を返す。
|
set-keymap-parent keymap parent | Function |
キーマップkeymapの親キーマップとしてparentを設定し、
parentを返す。
parentがnil であると、
この関数はkeymapに親キーマップをいっさい与えない。
keymapに(プレフィックスキー用のバインディングである) サブマップがあれば、それらもparentが指定するプレフィックスキーを 反映する新たな親マップを受け取る。 |
text-mode-map
からキーマップを継承する方法を示します。
(let ((map (make-sparse-keymap))) (set-keymap-parent map text-mode-map) map)
プレフィックス(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に対する
グローバルキーマップである。
このキーマップは実際にはグローバルでありモード固有ではないが、
その名前は、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に対して使われる
グローバルキーマップである。
vc-prefix-map
は、プレフィックスキーC-x vに対して使われる
グローバルキーマップである。
facemenu-keymap
は、プレフィックスキーM-gに対して使われる
グローバルキーマップである。
プレフィックスキーのキーマップバインディングは、
当該プレフィックスキーに続くイベントを探すために使われます。
(その関数定義がキーマップであるシンボルでもよい。
効果は同じであるが、シンボルはプレフィックスキーに対する名前として働く。)
したがって、C-xのバインディングは
シンボルControl-X-prefix
であり、
その関数セルがコマンドC-x用のキーマップを保持している。
(ctl-x-map
の値も同じキーマップである。)
プレフィックスキーの定義は、任意の活性なキーマップにあってかまいません。 プレフィックスキーとしてのC-c、C-x、C-h、<ESC>の 定義はグローバルマップにあるので、これらのプレフィックスキーは つねに利用できます。 メジャーモードやマイナモードでは、 プレフィックスキーの定義をローカルキーマップや マイナモードキーマップに入れることで、 キーをプレフィックスとして再定義できます。 See Active Keymaps。
複数の活性なキーマップにおいて、キーがプレフィックスと定義されていると、 さまざまな定義は実質的には併合されます。 マイナモードキーマップで定義されたコマンドが最優先で、 つぎにローカルマップのプレフィックス定義、 そしてグローバルマップのプレフィックス定義が続きます。
以下の例では、ローカルキーマップにおいて、
C-pをC-xに等価なプレフィックスキーにします。
続いてC-p C-fのバインディングを
C-x C-fのように関数find-file
にします。
キー列C-p 6はどの活性なキーマップでもみつかりません。
(use-local-map (make-sparse-keymap)) => nil (local-set-key "\C-p" ctl-x-map) => nil (key-binding "\C-p\C-f") => find-file (key-binding "\C-p6") => nil
define-prefix-command symbol | Function |
この関数は、symbolをプレフィックスキーの
バインディングとして使えるように準備する。
つまり、完全なキーマップを作成し、
symbolの関数定義にそのキーマップを保存する。
以後、symbolにキー列をバインドすると、
当該キー列をプレフィックスキーに入る。
この関数は、変数としてのsymbolにも値としてキーマップを設定する。 symbolを返す。 |
Emacsには、通常、たくさんのキーマップがあります。 ある時点では、それらの数個が活性になっていて、 ユーザー入力の解釈に関与します。 それらは、グローバルキーマップ、カレントバッファのローカルキーマップ、 オンになっているマイナモードのキーマップです。
グローバルキーマップ(global keymap)は、
C-fのようなカレントバッファに依存せずに
定義されたキーのバインディングを保持します。
変数global-map
はこのキーマップを保持していて、
このキーマップはつねに活性です。
各バッファには別のキーマップ、つまり、
バッファのローカルキーマップ(local keymap)があり、
キーに対する新しい定義や無効にする定義を保持しています。
カレントバッファのローカルキーマップは、
overriding-local-map
で無効にしない限り、つねに活性です。
テキスト属性により、バッファの特定部分に対する
代替ローカルマップを指定できます。
Special Propertiesを参照してください。
各マイナモードもキーマップを持てます。 その場合、マイナモードがオンであると当該キーマップは活性です。
変数overriding-local-map
がnil
以外であると、
バッファのローカルキーマップとそのすべてのマイナモードキーマップに
取ってかわるローカルキーマップを指定します。
キーが入力されるとどのコマンドを実行するかを決定するために、 すべての活性なキーマップを一緒に使います。 Emacsは、キーマップの1つでバインディングがみつかるまで、 優先順位が高いほうからこれらのキーマップを1つ1つ探索します。 1つのキーマップで探索する処理のことを キー探索(key lookup)といいます。 Key Lookupを参照してください。
通常、Emacsはまずminor-mode-map-alist
で指定される順に
マイナモードキーマップでキーを探します。
キーに対するバインディングがなければ、
Emacsはローカルキーマップで探します。
そこにもバインディングがなければ、
Emacsはグローバルキーマップで探します。
しかし、overriding-local-map
がnil
以外であれば、
Emacsはまずそのキーマップで探してから、
グローバルキーマップで探します。
同じメジャーモードを使う各バッファは、通常、同じローカルキーマップを
使うので、キーマップはモードにローカルであると考えることができます。
(たとえばlocal-set-key
を使って)バッファのローカルキーマップを
修正すると、当該キーマップを共有している別のバッファでも
その修正が見えます。
Lispモードや他の数個のメジャーモードで使われるローカルキーマップは、
それらのモードがまだ使われていなくても存在します。
そのようなローカルキーマップは、lisp-mode-map
などの変数の値です。
使用頻度の低いほとんどのメジャーモードでは、
セッションで始めてそのモードを使ったときに
ローカルキーマップを作成します。
ミニバッファにもローカルキーマップがあります。 それにはさまざまな補完コマンドや脱出コマンドが含まれます。 See Intro to Minibuffers。
Emacsには、別の用途のキーマップもあります。
read-key-sequence
でイベントを変換するためのものです。
See Translating Input。
標準的なキーマップの一覧についてはSee Standard Keymaps。
global-map | Variable |
この変数は、Emacsがキーボード入力をコマンドに対応させるための
デフォルトのグローバルキーマップを保持する。
グローバルキーマップは、通常、このキーマップである。
デフォルトのグローバルキーマップは、
すべての印字文字にself-insert-command をバインドする
完全なキーマップである。
グローバルマップのバインディングを修正することは実用的ですが、 この変数には、動作開始時のキーマップ以外の値は設定しないこと。 |
current-global-map | Function |
この関数は、現在のグローバルキーマップを返す。
global-map を変更していなければ、
これはglobal-map の値と同じである。
(current-global-map) => (keymap [set-mark-command beginning-of-line ... delete-backward-char]) |
current-local-map | Function |
この関数は、カレントバッファのローカルキーマップを返す。
なければnil を返す。
つぎの例では、(lisp対話モードを使っている)バッファ*scratch* の
キーマップは疎なキーマップであり、
ASCIIコード27の<ESC>に対する指定も別の疎なキーマップである。
(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-minor-mode-maps | Function |
この関数は、現在オンになっているマイナモードのキーマップのリストを返す。 |
use-global-map keymap | Function |
この関数は、キーマップkeymapを新たな現在のグローバルキーマップとする。
これはnil を返す。
グローバルキーマップを変更することは、とうてい普通のことではない。 |
use-local-map keymap | Function |
この関数は、キーマップkeymapをカレントバッファの
新たなローカルキーマップとする。
keymapがnil であると、
バッファにはローカルキーマップがなくなる。
use-local-map はnil を返す。
ほとんどのメジャーモードコマンドは、この関数を使う。
|
minor-mode-map-alist | Variable |
この変数は、変数の値に応じて活性になっている/いないキーマップを
記述する連想リストである。
その要素はつぎの形である。
(variable . keymap) 変数variableの値が
複数のマイナモードキーマップが活性な場合、
それらの優先順位は、 マイナモードについて詳しくはKeymaps and Minor Modesを参照。
|
minor-mode-overriding-map-alist | Variable |
この変数は、メジャーモードから特定のマイナモード向けのキーバインディングを
無効にするためのものである。
この連想リストの要素は、minor-mode-map-alist の要素と同じ形で、
(variable . keymap) である。
|
overriding-local-map | Variable |
nil 以外の値であると、この変数は、
バッファのローカルキーマップ、ならびに、すべてのマイナモードキーマップの
かわりに用いるキーマップを保持する。
このキーマップは、現在のグローバルキーマップを除く、
他のすべての活性なキーマップを無効にする。
|
overriding-terminal-local-map | Variable |
nil 以外であると、この変数は、
overriding-local-map 、および、バッファのローカルキーマップと
すべてのマイナモードキーマップのかわりに用いるキーマップを保持する。
この変数はつねに現在の端末に対してローカルであり、 バッファに対してローカルにはならない。 see Multiple Displays。 これはインクリメンタルサーチモードの実装に使われている。 |
overriding-local-map-menu-flag | Variable |
この変数がnil 以外であれば、
overriding-local-map やoverriding-terminal-local-map の値は、
メニューバーの表示に影響する。
デフォルト値はnil であり、
そのため、それらのマップはメニューバーには影響しない。
これら2つのキーマップ変数は、メニューバーの表示に影響しないときであっても、 メニューバーを用いて入力したキー列の実行には影響することに注意してほしい。 そのため、メニューバーのキー列が到着したら、 そのキー列を探索し実行するまえに、これらの変数をクリアすべきである。 これらの変数を使うモードでは、典型的にはつぎのようにする。 つまり、モードで処理できないイベントは『読み戻し』てモードから抜ける。 |
special-event-map | Variable |
この変数は特殊イベント用のキーマップを保持する。
イベント型のバインディングがこのキーマップにあれば、
そのイベントは特殊イベントであり、
read-event が当該イベントのバインディングを直接実行する。
see Special Events。
|
キー探索(key lookup)とは、 与えられたキーマップからキー列のバインディングを捜し出す処理です。 バインディングを実際に実行することは、キー探索ではありません。
キー探索では、キー列の各イベントのイベント型のみを使い、
イベントの他の部分は無視します。
実際、キー探索に使われるキー列では、
マウスイベント全体(リスト)ではなく
そのイベント型(シンボル)のみを指定します。
See Input Events。
そのような『キー列』は、command-execute
の動作には不十分ですが、
キーの探索や再バインディングには十分です。
キー列が複数のイベントから構成される場合、 キー探索ではイベントを順番に処理します。 先頭のイベントのバインディングを探しますが、 それはキーマップであるはずです。 続いて、そのキーマップから2番目のイベントのバインディングを探します。 これをキー列のすべてのイベントを使い尽くすまで行います。 (このように探した最後のイベントに対するバインディングは、 キーマップであたっりそうでないかもしれない。) つまり、キー探索処理は、 キーマップから単一イベントを探索するという単純な処理として定義できます。 これがどのように行われるかは、 キーマップ内のイベントに対応付けられたオブジェクトの型に依存します。
キーマップでイベント型を探してみつかった値のことを
キーマップ項目(keymap entry)という単語で表します。
(これには、メニューキーバインディングにある
項目文字列や他の追加要素を含まない。
というのは、lookup-key
や他のキー探索関数は、
それらを戻り値として返さないからである。)
キーマップ項目として任意のLispオブジェクトをキーマップに保存できますが、
キー探索においてそのすべてが意味を持つとは限りません。
意味のある種類のキー項目をつぎに示します。
nil
nil
は、探索に使ったここまでのイベントが
未定義キーを構成することを意味する。
キーマップにイベント型が記載されてなく、かつ、
デフォルトのバインディングもない場合には、
そのイベント型に対しては、バインディングがnil
であるのと等価。
keymap
であれば、
そのリストはキーマップであり、キーマップとして扱われる(上記参照)。
lambda
であれば、
そのリストはラムダ式である。
これはコマンドとみなされ、そのように扱われる(上記参照)。
(othermap . othertype)
キー探索中に間接項目に出会うと、 othertypeのバインディングをothermapで探しそれを用いる。
この機能により、あるキーを別のキーに対する別名として定義できる。
たとえば、CARがesc-map
と呼ばれるキーマップであり
CDRが32(<SPC>の文字コード)である項目は、
『Meta-<SPC>のグローバルバインディングを
それがなんであれ使う』という意味になる。
キーマップやキーボードマクロ(文字列やベクトル)は正しい関数ではないので、
関数定義としてキーマップ、文字列、ベクトルを持つシンボルは、
正しい関数ではない。
しかし、キーバインディングとしては正しい。
定義がキーボードマクロである場合には、そのシンボルは
command-execute
の引数としても正しい
(see Interactive Call)。
シンボルundefined
について特記しておく。
これは、キーを未定義として扱うことを意味する。
正確には、キーは定義されており、
そのバインディングはコマンドundefined
である。
しかし、そのコマンドは、未定義キーに対して自動的に行われることと
同じことを行う。
つまり、(ding
を呼び出して)ベルを鳴らすが、
エラーは通知しない。
undefined
は、グローバルキーバインディングを無効にして
キーをローカルに『未定義』にするためにローカルキーマップで使われる。
nil
のローカルバインディングでは、
グローバルバインディングを無効にしないため、こうはならない。
まとめると、キー項目は、キーマップ、コマンド、キーボードマクロ、
これら3つのいずれかになるシンボル、間接項目、nil
です。
2つの文字をコマンドに、1つを別のキーマップに対応付ける
疎なキーマップの例を示します。
このキーマップは、emacs-lisp-mode-map
の通常の値です。
ここで、それぞれ、9は<TAB>、
127は<DEL>、27は<ESC>、17はC-q、
24はC-xの文字コードであることに注意してください。
(keymap (9 . lisp-indent-line) (127 . backward-delete-char-untabify) (27 keymap (17 . indent-sexp) (24 . eval-defun)))
ここでは、キー探索に関わる関数や変数について述べます。
lookup-key keymap key &optional accept-defaults | Function |
この関数はキーマップkeymapにおけるkeyの定義を返す。
本章で述べる他の関数は、lookup-key を用いてキーを探す。
例を示す。
(lookup-key (current-global-map) "\C-x\C-f") => find-file (lookup-key (current-global-map) "\C-x\C-f12345") => 2 文字列やベクトルであるkeyが、 keymapで指定されたプレフィックスキーに対して正しいキー列でなければ、 keyは『長すぎる』のであって、 1つのキー列に収まらない余分なイベントが末尾にある。 その場合、戻り値は数であり、 完全なキーを構成するkeyの先頭からのイベント数を表す。 accept-defaultsが keyにメタ文字が含まれる場合、
当該文字は暗黙のうちに2文字の列、
つまり、 (lookup-key (current-global-map) "\M-f") => forward-word (lookup-key (current-global-map) "\ef") => forward-word
|
undefined | コマンド |
キーを未定義にするためにキーマップで使われる。
ding を呼び出すが、エラーにはならない。
|
key-binding key &optional accept-defaults | Function |
この関数は、すべての活性なキーマップを試して
keyに対するバインディングを返す。
キーマップでkeyが未定義であると結果はnil 。
引数accept-defaultsは、 keyが文字列でもベクトルでもないとエラーを通知する。 (key-binding "\C-x\C-f") => find-file |
local-key-binding key &optional accept-defaults | Function |
この関数は、現在のローカルキーマップから
keyに対するバインディングを返す。
未定義ならばnil を返す。
引数accept-defaultsは、 |
global-key-binding key &optional accept-defaults | Function |
この関数は、現在のグローバルキーマップから
keyに対するバインディングを返す。
未定義ならばnil を返す。
引数accept-defaultsは、 |
minor-mode-key-binding key &optional accept-defaults | Function |
この関数は、すべてのオンになっているマイナモードにおける
keyのバインディングのリストを返す。
より正確には、対(modename . binding) を要素とする
連想リストを返す。
ここで、modenameはマイナモードをオンにする変数であり、
bindingは当該モードにおけるkeyのバインディングである。
keyにマイナモードでのバインディングがなければ、
値はnil である。
最初にみつかったバインディングがプレフィックスの定義 (キーマップかキーマップとしてのシンボル)でなければ、 残りのマイナモードからのバインディングは完全に隠されてしまうので それらは省略する。 同様に、プレフィックスバインディングに 続く非プレフィックスバインディングも省略する。 引数accept-defaultsは、 |
meta-prefix-char | Variable |
この変数は、メタプレフィックス文字の文字コードである。
メタ文字をキーマップで探索するために2文字列に変換するときに使われる。
結果が有用であるためには、
この値はプレフィックスイベント(see Prefix Keys)であるべきである。
デフォルト値は27、<ESC>のASCIIコードである。
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 ; デフォルト値に戻す! |
キーを再バインドするには、キーマップにおける当該項目を変更します。
グローバルキーマップでバインディングを変更すると、
その変更はすべてのバッファで効果を発揮します
(ただし、ローカルキーマップでグローバルバインディングを
隠しているバッファでは直接の効果はない)。
カレントバッファのローカルキーマップで変更すると、
通常、同じメジャーモードを使っているすべてのバッファに影響します。
関数global-set-key
やlocal-set-key
は、
これらの操作を行うための便利なインターフェイスです
(see Key Binding Commands)。
より汎用の関数define-key
を使うこともできますが、
変更対象のキーマップを明示する必要があります。
キー列の再バインドを書くときには、
コントロール文字やメタ文字向けの
特別なエスケープシーケンスを使うのがよいです(see String Type)。
構文\C-
は後続の文字がコントロール文字であること、
構文\M-
は後続の文字がメタ文字であることを意味します。
したがって、文字列"\M-x"
は単一のM-xを含むと読まれ、
"\C-f"
は単一のC-fを含むと読まれ、
"\M-\C-x"
や"\C-\M-x"
はいずれも単一のC-M-xを
含むと読まれます。
同じエスケープシーケンスは、
ベクトルでも使え、文字列が許されない他の場面でも使えます。
たとえば、[?\C-\H-x home]
です。
See Character Type。
キーを定義したり探索する関数では、
ベクトルで表したキー列内のイベント型に対して別の構文、
つまり、修飾子名と1つの基本イベント(文字やファンクションキー名)
から成るリストを受け付けます。
たとえば、(control ?a)
は?\C-a
に等価であり、
(hyper control left)
はC-H-left
に等価です。
このようなリストの利点の1つは、
コンパイル済みのファイルに修飾ビットの数値が現れないことです。
以下の関数では、keymapがキーマップでなかったり、 keyがキー列を表す文字列やベクトルでないと、エラーを通知します。 リストであるイベントの省略形としてイベント型(シンボル)を使えます。
define-key keymap key binding | Function |
この関数は、キーマップkeymapにおいて
キーkeyに対するバインディングを設定する。
(keyが複数イベントの場合、
keymapから辿った別のキーマップが実際には変更される。)
引数bindingは任意のLispオブジェクトであるが、
ある種の型のものだけが意味を持つ。
(意味のある型の一覧については、Key Lookupを参照。)
define-key が返す値はbindingである。
keyのおのおののプレフィックスはプレフィックスキーである
(キーマップにある)か未定義であること。
さもなければ、エラーを通知する。
keyのプレフィックスに未定義なものがあると、
keymapにkeyのバインディングがなければ、 新たなバインディングをkeymapの先頭に追加する。 キーマップ内のバインディングの順序は多くの場合関係ないが、 メニューキーマップでは意味を持つ(see Menu Keymaps)。 |
疎なキーマップを作成し、そこにバインディングを作る例を示します。
(setq map (make-sparse-keymap)) => (keymap) (define-key map "\C-f" 'forward-char) => forward-char map => (keymap (6 . forward-char)) ;; C-x用の疎なサブマップを作り、 ;; そこにfのバインディングを入れる (define-key map "\C-xf" 'forward-word) => forward-word map => (keymap (24 keymap ; C-x (102 . forward-word)) ; f (6 . forward-char)) ; C-f ;; C-pをctl-x-map
にバインドする (define-key map "\C-p" ctl-x-map) ;;ctl-x-map
=> [nil ... find-file ... backward-kill-sentence] ;;ctl-x-map
で、C-fをfoo
にバインドする (define-key map "\C-p\C-f" 'foo) => 'foo map => (keymap ;foo
はctl-x-map
の中にある (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-fとデフォルトのグローバルキーマップ内の
C-x C-fの両方のバインディングを変更する効果がある
ことに注意してください。
substitute-key-definition olddef newdef keymap &optional oldmap | Function |
この関数は、keymap内のolddefにバインドされたキーの
olddefをnewdefに置き換える。
いいかえると、olddefに出会うたびにそれをnewdefに置き換える。
関数はnil を返す。
たとえば、Emacsの標準のバインディングであると、 つぎの例はC-x C-fを再定義する。 (substitute-key-definition 'find-file 'find-file-read-only (current-global-map)) oldmapが (substitute-key-definition 'delete-backward-char 'my-funny-delete my-map global-map) では、グローバルには標準の削除コマンドにバインドされているキーに対しては、
変更前後のキーマップを以下に示す。 (setq map '(keymap (?1 . olddef-1) (?2 . olddef-2) (?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)) |
suppress-keymap keymap &optional nodigits | Function |
この関数は、完全なキーマップkeymapの内容を変更し、
すべての印字文字を未定義にする。
より正確には、それらにコマンドundefined をバインドする。
これにより、通常のテキストの挿入を不可能にする。
suppress-keymap はnil を返す。
nodigitsが 関数 この関数はkeymapを変更するため、
読者は、通常、新たに作成したキーマップに対して使うであろう。
ある目的で使用中の既存のキーマップを操作すると、
問題を引き起こすことがある。
たとえば、 多くの場合、テキストの挿入が必要なくバッファを読み出し専用で使う
rmailやdiredなどのモードのローカルキーマップの初期化に
(setq dired-mode-map (make-keymap)) (suppress-keymap dired-mode-map) (define-key dired-mode-map "r" 'dired-rename-file) (define-key dired-mode-map "\C-d" 'dired-flag-file-deleted) (define-key dired-mode-map "d" 'dired-flag-file-deleted) (define-key dired-mode-map "v" 'dired-view-file) (define-key dired-mode-map "e" 'dired-find-file) (define-key dired-mode-map "f" 'dired-find-file) ... |
本節では、キーのバインディングを変更する
便利で対話的なインターフェイスについて述べます。
これらは、define-key
を呼び出して動作します。
単純なカスタマイズのために
ファイル.emacs
でglobal-set-key
をしばしば使います。
たとえば、
(global-set-key "\C-x\C-\\" 'next-line)
や
(global-set-key [?\C-x ?\C-\\] 'next-line)
や
(global-set-key [(control ?x) (control ?\\)] 'next-line)
は、1行下がるようにC-x C-\を再定義します。
(global-set-key [M-mouse-1] 'mouse-set-point)
は、メタキーを押し下げながらマウスの第1ボタン(左端)をクリックすると クリック位置にポイントを設定するように再定義します。
global-set-key key definition | コマンド |
この関数は、現在のグローバルキーマップにおいて
keyのバインディングをdefinitionと設定する。
(global-set-key key definition) == (define-key (current-global-map) key definition) |
global-unset-key key | コマンド |
この関数は、現在のグローバルキーマップから
keyのバインディングを削除する。
この関数の1つの用途は、 keyに非プレフィックスのバインディングがあると再定義できないため、 keyをプレフィックスとして使う長いキーを定義する前準備である。 たとえば、つぎのとおり。 (global-unset-key "\C-l") => nil (global-set-key "\C-l\C-l" 'redraw-display) => nil この関数は単に (global-unset-key key) == (define-key (current-global-map) key nil) |
local-set-key key definition | コマンド |
この関数は、現在のローカルキーマップにおいて
keyのバインディングをdefinitionと設定する。
(local-set-key key definition) == (define-key (current-local-map) key definition) |
local-unset-key key | コマンド |
この関数は、現在のローカルキーマップから
keyのバインディングを削除する。
(local-unset-key key) == (define-key (current-local-map) key nil) |
本節では、ヘルプ情報を表示するために 現在のキーマップをすべて走査する関数について述べます。
accessible-keymaps keymap &optional prefix | Function |
この関数は、keymapから(0個以上のプレフィックスキーにより)辿れる
すべてのキーマップのリストを返す。
その値は、(key . map) の形の要素から成る
連想リストである。
ここで、keyはプレフィックスキーであり、
keymap内でのその定義はmapである。
連想リスト内での要素の順番は、keyの長さが増える順である。
指定したキーマップkeymapはプレフィックスのイベントなしに参照できるので、
最初の要素はつねに prefixを与える場合、それはプレフィックスキー列であること。
すると、 つぎの例では、返された連想リストにおいては、
(accessible-keymaps (current-local-map)) =>(("" keymap (27 keymap ; Note this keymap for <ESC> is repeated below. (83 . center-paragraph) (115 . center-line)) (9 . tab-to-tab-stop)) ("^[" keymap (83 . center-paragraph) (115 . foo))) つぎの例では、C-hは、
疎なキーマップ (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) ...)) 実際に表示されるキーマップはこれらだけとは限らない。 |
where-is-internal command &optional keymap firstonly noindirect | Function |
この関数は、コマンドwhere-is
(see Help)が使う
サブルーティンである。
キーマップにおいてcommandにバインドされた
(任意長の)キー列のリストを返す。
引数commandは任意のオブジェクトであり、
キーマップ項目とは keymapが 通常、keymapに対する式には firstonlyが noindirectが (where-is-internal 'describe-function) => ("\^hf" "\^hd") |
describe-bindings &optional prefix | コマンド |
この関数は、現在のすべてのキーバインディングの一覧を作成し、
*Help* という名前のバッファに表示する。
テキストはモードごとにまとめられ、
マイナモード、メジャーモード、グローバルバインディングの順である。
prefixが 一覧では、メタ文字は、<ESC>に続けて対応する非メタ文字で表す。 連続したASCIIコードの一連の文字が同じ定義である場合には、
それらをまとめて |
キーマップは、キーボードのキーやマウスボタンに対するバインディングに加えて メニューも定義できます。
キーマップに全面プロンプト文字列(overall prompt string)、
つまり、キーマップの要素として文字列が現れれば、
メニューとして使えます。
その文字列でメニューの目的を記述します。
プロンプト文字列を持ったキーマップを作成するもっとも簡単な方法は、
make-keymap
やmake-sparse-keymap
(see Creating Keymaps)を
呼ぶときに、引数として文字列を指定します。
メニュー上での項目の順番は、
キーマップ内のバインディングの順番と同じです。
define-key
は、新たなバインディングを先頭に追加するので、
順番を気にするのならば、メニューの底の項目から始めて
上の項目へ向かってメニュー項目の定義を入れます。
既存のメニューに項目を追加する場合には、
define-key-after
(see Modifying Menus)を使って
メニュー内での位置を指定できます。
メニューキーマップのバインディングを定義する単純で旧式の方法は つぎのとおりです。
(item-string . real-binding)
CARのitem-stringは、メニューに表示される文字列です。 3単語までの短いものにし、対応するコマンドの動作を記述します。
つぎのように、ヘルプ文字列となる2つめの文字列も指定できます。
(item-string help-string . real-binding)
現状では、Emacsは実際にはhelp-stringを使いません。 real-bindingを取り出すためにhelp-stringを無視する方法を 知っているだけです。 将来、ユーザーの要望に応じてメニュー項目に対する追加説明として help-stringを使うかもしれません。
define-key
に関する限り、
item-stringとhelp-stringは
イベントのバインディングの一部分です。
しかし、lookup-key
はreal-bindingのみを返し、
キーの実行にはreal-bindingのみが使われます。
real-bindingがnil
であると、
item-stringはメニューに現れますが、それは選択できません。
real-bindingがシンボルであり、
その属性menu-enable
がnil
以外であると、
当該属性は、メニュー項目を活性にするかどうかを制御する式です。
Emacsは、メニューを表示するためにキーマップを使うたびに、
その式を評価し、式の値がnil
以外である場合に限り、
当該メニュー項目をオンにします。
メニュー項目がオフであると、『薄く』表示し、それは選択できません。
メニューバーでは、読者がメニューを見るたびにどの項目がオンであるかを
再計算しません。
Xツールキットがあらかじめメニューの木構造全体を必要とするからです。
メニューバーの再計算を強制するには、
force-mode-line-update
を呼び出します。
(see Mode Line Format)。
メニュー項目には、同じコマンドを起動する等価なキーボードのキー列が (あれば)表示されていることに気づいたと思います。 再計算の時間を節約するために、 メニューの表示では、この情報をつぎのように バインディングの部分リストに隠し持っています。
(item-string [help-string] (key-binding-data) . real-binding)
読者は、メニュー項目にこれらの部分リストを入れないでください。 それらはメニューの表示で自動的に計算されます。 冗長になるので、項目の文字列には、等価なキーボード入力を 含めないでください。
拡張形式のメニュー項目は、より柔軟性があり、
単純な形式より見通しがよい代替方法です。
それらは、シンボルmenu-item
で始まるリストから成ります。
選択不可の文字列を定義するには、項目をつぎのようにします。
(menu-item item-name)
ここで、文字列item-nameは区切り行を表す複数個のダッシュから成ります。
選択可能な実際のメニュー項目を定義するには、 拡張形式の項目はつぎのようになります。
(menu-item item-name real-binding . item-property-list)
ここで、item-nameは、メニュー項目の文字列に評価される式です。 つまり、(項目の)文字列は定数である必要はありません。 3番目の要素item-property-listは実行すべきコマンドです。 リストの残りitem-property-listは、 他の情報を含んだ属性リストの形式です。 指定できる属性はつぎのとおりです。
:enable FORM
nil
以外だとオン)。
:visible FORM
nil
以外だと含める)。
項目を含めない場合、当該項目が定義されていないかのようにメニューを表示する。
:help help
:button (type . selected)
:toggle
か:radio
であり、
どちらであるかを指定する。
CDRのselectedはフォームであること。
その評価結果が、現在ボタンが選択されているかどうかを決定する。
トグル(toggle)は、selectedの値に応じて
『on』か『off』と書かれるメニュー項目である。
コマンド自身では、selectedがnil
ならば
selectedにt
を設定し、
t
ならばnil
を設定すること。
以下は、debug-on-error
が定義されていれば
debug-on-error
をオン/オフするメニュー項目の書き方である。
(menu-item "Debug on Error" toggle-debug-on-error :button (:toggle . (and (boundp 'debug-on-error) debug-on-error))
これは、変数debug-on-error
をオン/オフするコマンドとして
toggle-debug-on-error
が定義されているので動作する。
ラジオボタン(radio button)はメニュー項目のグループであり、
ある時点ではそれらのうちの1つだけを『選択』できる。
どれを選択しているかを表す変数が必要である。
グループ内の各ラジオボタンに対するフォームselectedは、
当該変数の値が当該ボタンを選択している値かどうかを検査する。
ボタンをクリックすると、クリックしたボタンが選択されるように
当該変数に設定すること。
:key-sequence key-sequence
まちがったキー列を指定しても、その効果はない。
メニューにkey-sequenceを表示するまえに、
Emacsはkey-sequenceがこのメニュー項目に実際に等価かどうか調べる。
:key-sequence nil
しかし、ユーザーがこの項目の定義に対してキー列を再バインドすると、
Emacsは属性:keys
を無視して等価なキーボード入力を探す。
:keys string
\\[...]
の書き方を使える。
:filter filter-fn
『同じ』コマンドを使いながらオン条件が異なるメニュー項目を
作れると便利なことがあります。
現状のEmacsでこれを行う最良の方法は、拡張メニュー項目を使うことです。
この機能がなかった頃には、コマンドの別名を定義し、
それをメニュー項目で使うことで可能でした。
異なるオン条件でtoggle-read-only
を
使う2つの別名の作り方を以下に示します。
(defalias 'make-read-only 'toggle-read-only) (put 'make-read-only 'menu-enable '(not buffer-read-only)) (defalias 'make-writable 'toggle-read-only) (put 'make-writable 'menu-enable 'buffer-read-only)
メニューに別名を使うときには、
(典型的にはメニュー以外にはキーバインディングがない)別名ではなく
『本物の』コマンド名に対する等価なキーバインディングを
表示しするのがしばしば有用です。
これを行うには、別名のシンボルには
nil
以外の属性menu-alias
を与えます。
(put 'make-read-only 'menu-alias t) (put 'make-writable 'menu-alias t)
こうすると、make-read-only
とmake-writable
のメニュー項目には
toggle-read-only
に対するキーバインディングが表示されます。
メニューキーマップがメニューを表示するようにする普通の方法は、 メニューキーマップをプレフィックスキーの定義にすることです。 (Lispプログラムから明示的にメニューをポップアップして、 ユーザーの選択を受け取れる。 Pop-Up Menusを参照。)
プレフィックスキーがマウスイベントで終っていると、 Emacsはメニューをポップアップすることでメニューキーマップを扱います。 これで、ユーザーはマウスで選択できるようになります。 ユーザーがメニュー項目をクリックすると、 当該メニュー項目をバインディングとする文字やシンボルが イベントとして生成されます。 (メニューが複数レベルになっていたりメニューバーから開いたときには、 メニュー項目は一連のイベントを生成する。)
メニューの開始にはボタン押し下げイベントを使うのがしばしば最良です。 そうすると、ユーザーはボタンを離すことでメニュー項目を選べます。
明示的に配置すれば、1つのキーマップをメニューペインとして表示できます。
それには、各ペインに対するキーマップを作成し、
つぎに、メニューのメインのキーマップにおいて、
(各ペインの)各キーマップに対するバインディングを作ります。
なお、これらのバインディングには、
@
で始まる項目文字列を指定します。
項目文字列の残りの部分がペインの名前になります。
この例についてはファイルlisp/mouse.el
を参照してください。
@
で始まらない項目文字列の他の普通のバインディングは
1つのペインにまとめられ、サブマップに対して明示的に作られた
他のペインとともに表示されます。
Xツールキットのメニューにはペインはありませんが、
そのかわりに、サブメニューがあります。
項目文字列が@
で始まるかどうかに関わらず、
入れ子になった各キーマップがサブメニューになります。
Emacsのツールキット版では、項目文字列の先頭の@
に関して特別なことは、
@
がメニュー項目に表示されないことです。
個別のキーマップからも複数ペインやサブメニューを作成できます。 プレフィックスキーの完全な定義は、 さまざまな活性のキーマップ(マイナモード、ローカル、グローバル)が与える 定義を併合することで得られます。 これらのキーマップのうち複数個がメニューであるとき、 そのおのおのが別々のペイン(Xツールキットを使わないEmacs)や 別々のサブメニュー(Xツールキットを使ったEmacs)になります。 See Active Keymaps。
キーボードイベント(文字や関数)で終るプレフィックスキーに、 メニューキーマップであるような定義があると、 ユーザーはメニュー項目を選ぶためにキーボードを使えます。
Emacsはメニューの選択項目(バインディングの項目文字列)を
エコー領域に表示します。
それらが1行に収まらなければ、
ユーザーは<SPC>を打つことで選択項目のつぎの行を見ることができます。
<SPC>を連続して使うと最終的にはメニューの最後に達し、
そうするとメニューの先頭に戻ります。
(変数menu-prompt-more-char
に、このために用いる文字を指定する。
デフォルトは<SPC>。)
ユーザーは、メニューから望みの項目をみつけたら、 対応する文字、つまり、その項目のバインディングを持つ文字を打ちます。
Emacs類似エディタにおけるこのようなメニューの使い方は、 システムHierarkeyに触発されたからです。
menu-prompt-more-char | Variable |
この変数は、メニューのつぎの行を見るために使う文字を指定する。 初期値は、<SPC>の文字コードの32である。 |
以下に、メニューキーマップの完全な定義の例を示します。
これは、メニューバーのメニューTools
の
サブメニューPrint
の定義であり、
単純なメニュー項目を使います
(see Simple Menu Items)。
まず、キーマップを作成し名前を与えます。
(defvar menu-bar-print-menu (make-sparse-keymap "Print"))
つぎに、メニュー項目を定義します。
(define-key menu-bar-print-menu [ps-print-region] '("Postscript Print Region" . ps-print-region-with-faces)) (define-key menu-bar-print-menu [ps-print-buffer] '("Postscript Print Buffer" . ps-print-buffer-with-faces)) (define-key menu-bar-print-menu [separator-ps-print] '("--")) (define-key menu-bar-print-menu [print-region] '("Print Region" . print-region)) (define-key menu-bar-print-menu [print-buffer] '("Print Buffer" . print-buffer))
バインディングが『作られる対象』のシンボルに注意してください。
定義されるキー列の角括弧の内側に現れています。
そのシンボルはコマンド名に等しい場合もあればそうでない場合もあります。
これらのシンボルは『ファンクションキー』として扱われますが、
キーボード上の本物のファンクションキーではありません。
それらはメニュー項目の機能には影響ありませんが、
ユーザーがメニューから選ぶとそれらはエコー領域に『表示』され、
where-is
やapropos
の出力にも現れます。
定義が("--")
であるようなバインディングは区切り行です。
実際のメニュー項目のように、区切りにもキーシンボルがあり、
例ではseparator-ps-print
です。
1つのメニューに複数の区切りがある場合、
それらはすべて異なるキーシンボルでなければなりません。
つぎには、メニュー内の2つのコマンドのオン条件を定義するコードです。
(put 'print-region 'menu-enable 'mark-active) (put 'ps-print-region-with-faces 'menu-enable 'mark-active)
つぎは、このメニューを親メニューの項目に現れるようにする方法です。
(define-key menu-bar-tools-menu [print] (cons "Print" menu-bar-print-menu))
ここで使っているのは、サブメニューのキーマップ、つまり、
変数menu-bar-print-menu
の値であって、
変数そのものではないことに注意してください。
menu-bar-print-menu
はコマンドではないので、
このシンボルを親メニューの項目に使っても意味がありません。
同じ印刷メニューをマウスクリックに対応付けたければ、 つぎのようにしてできます。
(define-key global-map [C-S-down-mouse-1] menu-bar-print-menu)
つぎのようにして、print-region
に対して拡張メニュー項目
(see Extended Menu Items)を使うこともできます。
(define-key menu-bar-print-menu [print-region] '(menu-item "Print Region" print-region :enable (mark-active)))
拡張メニュー項目では、オン条件はメニュー項目自体の内側に指定します。 マークがないときにはメニューからこの項目が消えるようにするには つぎのようにします。
(define-key menu-bar-print-menu [print-region] '(menu-item "Print Region" print-region :visible (mark-active)))
ほとんどのウィンドウシステムでは、
各フレームにメニューバー(menu bar)、
つまり、フレームの先頭に水平方向に延びているメニューを恒久的に表示できます。
メニューバーの項目は、すべての活性なキーマップで定義された
疑似『ファンクションキー』menu-bar
のサブコマンドです。
メニューバーに項目を追加するには、
読者独自の疑似『ファンクションキー』を考え(これをkeyとする)、
キー列[menu-bar key]
に対するバインディングを作ります。
多くの場合、バインディングはメニューキーマップであって、
メニューバーの項目上でボタンを押すと別のメニューへ至るようにします。
メニューバーに対する同じ疑似ファンクションキーを 複数の活性なキーマップで定義していても、1つの項目だけが表示されます。 ユーザーがメニューバーの当該項目をクリックすると、 当該項目のすべてのサブコマンド、つまり、 グローバルのサブコマンド、ローカルのサブコマンド、 マイナモードのサブコマンドを含む1つの複合メニューが表示されます。
メニューバーの内容を決定する際には、
通常、変数overriding-local-map
は無視されます。
つまり、overriding-local-map
がnil
であるときに
活性になるキーマップからメニューバーを計算します。
See Active Keymaps。
フレームにメニューバーを表示するには、
フレームのパラメータmenu-bar-lines
が0より大きい必要があります。
Emacsはメニューバーそのものには1行だけ使います。
読者が2行以上を指定すると、
残りの行はフレームのウィンドウとメニューバーを区切る行になります。
menu-bar-lines
の値には1か2を勧めます。
See Window Frame Parameters。
メニューバーの項目の設定例を示します。
(modify-frame-parameters (selected-frame) '((menu-bar-lines . 2))) ;; (プロンプト文字列を持つ)メニューキーマップを作り ;; それをメニューバーの項目の定義にする (define-key global-map [menu-bar words] (cons "Words" (make-sparse-keymap "Words"))) ;; このメニュー内のサブコマンドを定義する (define-key global-map [menu-bar words forward] '("Forward word" . forward-word)) (define-key global-map [menu-bar words backward] '("Backward word" . backward-word))
グローバルキーマップに作ったメニューバー項目を
ローカルキーマップで取り消すには、
ローカルキーマップの当該疑似ファンクションキーのバインディングを
undefined
で再バインドします。
たとえば、つぎのようにしてdiredはメニューバーの項目Edit
を抑制します。
(define-key dired-mode-map [menu-bar edit] 'undefined)
edit
は、メニューバー項目Edit
に対して
グローバルキーマップで使う疑似ファンクションキーです。
グローバルなメニューバー項目を抑制する主な理由は、
モード固有の項目向けに場所を確保するためです。
menu-bar-final-items | Variable |
通常、メニューバーは、グローバルな項目に
ローカルキーマップで定義された項目を続けて表示する。
この変数は、通常の順ではなくメニューバーの底に表示する項目に
対する疑似ファンクションキーのリストを保持する。
デフォルト値は |
menu-bar-update-hook | Variable |
このノーマルフックは、 ユーザーがメニューバーをクリックするたびに、 サブメニューを表示するまえに実行される。 これを用いて、内容が変化するサブメニューを更新できる。 |
既存のメニューに新たな項目を挿入するとき、
メニューの既存の項目の特定の場所に挿入したいでしょう。
define-key
で項目を追加すると、通常、メニューの先頭に入ります。
メニューのそれ以外の場所に挿入するには、
define-key-after
を使います。
define-key-after map key binding after | Function |
keyに対するバインディングbindingをmap内に作る。
ただし、map内でのバインディングの位置は、
イベントafterに対するバインディングのあとにする。
引数keyは長さ1、つまり、1要素のみのベクトルか文字列であること。
しかし、afterは1つのイベント型、つまり、
シンボルか文字であり列ではないこと。
新たなバインディングはafterに対するバインディングのうしろに入る。
afterがt であると、新たなバインディングは最後、
つまり、キーマップの末尾に入る。
例を示す。 (define-key-after my-menu [drink] '("Drink" . drink-command) 'eat) これは、疑似ファンクションキー<DRINK>に対するバインディングを作り、 <EAT>に対するバインディングのあとに入れる。 shellモードのメニュー (define-key-after (lookup-key shell-mode-map [menu-bar signals]) [work] '("Work" . work-command) 'break) |
モード(mode)とは、Emacsをカスタマイズする定義の集まりであり、 読者は編集中にそれをオン/オフできます。 モードには2種類あります。 メジャーモード(major mode)は、互いに排他的で、 特定種類のテキストの編集に使います。 マイナモード(minor mode)は、 ユーザーがそれぞれを独立にオンにできる機能を提供します。
本章では、メジャーモードやマイナモードの書き方、 それらをモード行に表示する方法、 ユーザーが指定したフックをモードがどのように実行するかについて述べます。 キーマップや構文テーブルなどの関連事項については、 KeymapsやSyntax Tablesを参照してください。
メジャーモードは、特定種類のテキストの編集向けにEmacsを特化します。 各バッファには、ある時点では1つのメジャーモードしかありません。
もっとも特化されていないメジャーモードは、
基本(fundamental)モードです。
このモードには、モードに固有な定義や変数の設定がありません。
そのため、Emacsの各コマンドはデフォルトのふるまいをし、
各オプションもデフォルトの状態です。
他のすべてのメジャーモードでは、さまざまなキーやオプションを再定義します。
たとえば、lisp対話モードでは、
C-j(eval-print-last-sexp
)や
<TAB>(lisp-indent-line
)など他のキーに対しても
特別なキーバインディングがあります。
読者の特別な編集作業を補佐するために一群の編集コマンドを書く必要がある場合、 新たなメジャーモードを作ることは一般にはよいことです。 実際、メジャーモードを書くことは (マイナモードを書くことはしばしば難しくなるが、 それに対比すれば)簡単です。
新たなモードが既存のモードに類似していても、
既存のモードを2つの目的を果たすように修正するのは
賢いことではありません。
そのようにすると、使い難く保守し難くなるからです。
そのかわりに、既存のメジャーモードの定義をコピーし名前変えてから、
コピーを変更します。
あるいは、派生モード (derived mode)
(see Derived Modes)を定義します。
たとえば、emacs/lisp/rmailedit.el
にあるrmail編集モードは、
テキスト(text)モードに非常によく似たメジャーモードですが、
追加コマンドが3つあります。
そのような定義がテキスト(text)モードとの違いになるのですが、
rmail編集モードはテキスト(text)モードから派生したものです。
rmail編集モードは、バッファのメジャーモードを一時的に変更して バッファを別の方法(rmailのコマンドではなく Emacsの普通のコマンド)で編集できるようにする例題です。 そのような場合、一時的なメジャーモードには、普通、 バッファの通常のモード(この場合にはrmailモード)に戻る コマンドがあります。 読者は、再帰編集の中で一時的に再定義し、 ユーザーが再帰編集を抜けるともとに戻す方法に魅了されるかもしれません。 しかし、これを複数のバッファで行うと、 再帰編集はもっとも最近に入った再帰からまず抜けるので、 ユーザーの選択に制約を課すことになり悪い方法です。 別のメジャーモードを使えばこのような制約を回避できます。 See Recursive Editing。
標準のGNU Emacs Lispのライブラリのディレクトリには、
text-mode.el
、texinfo.el
、lisp-mode.el
、
c-mode.el
、rmail.el
などのファイルに
いくつかのメジャーモードのコードが収めてあります。
モードの書き方を理解するためにこれらのライブラリを調べられます。
テキスト(text)モードは、基本(fundamental)モードについで、
もっとも単純なメジャーモードです。
rmailモードは複雑な特化されたモードです。
既存のメジャーモードのコードでは、 ローカルキーマップや構文テーブルの初期化、グローバルな名前、フックなどの さまざまなコーディング上の慣習を踏襲しています。 読者が新たなメジャーモードを定義するときには、 これらの慣習に従ってください。
-mode
で終ること。
このコマンドが、キーマップ、構文テーブル、
既存バッファにバッファローカルな変数を設定するが、
バッファの内容は変更しないこと。
describe-mode
)を使うと、
この説明文字列を表示する。
説明文字列では、\[command]
、\{keymap}
、
\<keymap>
の特別な書き方を使え、
これらはユーザー独自のキーバインディングに自動的に置き換えられる。
see Keys in Documentation。
kill-all-local-variables
の呼び出しから始めること。
それ以前に有効であったメジャーモードのバッファローカルな変数に
対処するためである。
major-mode
にメジャーモードコマンドのシンボルを設定すること。
これにより、describe-mode
が表示すべき説明文を捜し出す。
mode-name
にモードの『愛称』を文字列として設定すること。
この文字列がモード行に現れる。
use-local-map
を呼び出して、
そのローカルキーマップを設定すること。
詳しくは、see Active Keymaps。
このキーマップは、modename-mode-map
という名前の
グローバル変数に恒久的に保持すること。
通常、モードを定義するライブラリでこの変数に設定する。
モードのキーマップ変数に設定するコードの書き方に関する助言については see Tips for Defining。
メジャーモードにおいては、そのモードによく適合した形で 『同じ仕事』を行うコマンドであるならば、 標準的な意味を持つキー列に当該コマンドを再バインドしても合理的である。 たとえば、プログラム言語編集用のメジャーモードでは、 C-M-aを当該言語にうまく適合した方法で 『関数の先頭へ移動する』コマンドに再定義する。
テキスト挿入を許さないdiredやrmailなどのメジャーモードでは、 英文字や他の印字文字を編集コマンドとして再定義するのも合理的である。 diredもrmailもこうしている。
modename-mode-syntax-table
という名前の変数に保持すること。
see Syntax Tables。
modename-mode-abbrev-table
という名前の変数に保持すること。
see Abbrev Tables。
font-lock-defaults
(see Font Lock Mode)に設定して、
フォントロック(font-lock)モードに対して強調表示の方法を指定すること。
imenu-generic-expression
か
imenu-create-index-function
(see Imenu)に設定して、
iメニューがどのようにバッファ内の定義や節を探すべきかを指定すること。
defvar
かdefcustom
を使い、
それらに値が設定されている場合には再初期化しないようにする。
(再初期化するとユーザーのカスタマイズを廃棄してしまう。)
make-variable-buffer-local
ではなく
make-local-variable
で行う。
前者の関数は、すべてのバッファにおいてそれ以降に設定される当該変数を
バッファローカルにしてしまい、
このモードを使わないバッファにも影響する。
モードにそのような大局的な効果があるのは望ましくない。
see Buffer-Local Variables。
単一のLispパッケージ内のみにおいて使われる変数に対しては、
必要ならば、make-variable-buffer-local
を使ってもよい。
modename-mode-hook
という名前の
モードフック(mode hook)があること。
モードコマンドは、最後にrun-hooks
を用いてフックを実行すること。
see Hooks。
indented-text-mode
は、
indented-text-mode-hook
に加えてtext-mode-hook
も実行する。
自前のフックを実行する直前(つまり設定が終ったあと)
にこれらの他のフックを実行するか、より初期の段階で実行してもよい。
change-major-mode-hook
(see Creating Buffer-Local)
のバッファローカルな値を設定しておく。
mode-class
に値special
を設定しておくこと。
(put 'funny-mode 'mode-class 'special)
これは、カレントバッファがfunnyモードのときに新たなバッファを 作成しても、新しいバッファではfunnyモードを継承しないようにEmacsに指示する。 dired、rmail、バッファ一覧などのモードではこの機能を使っている。
auto-mode-alist
に追加する。
モードコマンドを自動ロードと定義する場合、
autoload
を呼び出している同じファイルに
そのような要素を追加しておくこと。
そうでなければ、モード定義を収めたファイルに当該要素を入れるだけで十分である。
see Auto Major Mode。
.emacs
に書けるように、
autoload
の例、
auto-mode-alist
への追加方法の例を記載すること。
基本(fundamental)モードを除くと、
テキスト(text)モードはもっとも単純なモードです。
上に述べた慣習の例示として、text-mode.el
の抜粋をあげておきます。
;; モード固有の構文テーブルを作る (defvar text-mode-syntax-table nil "Syntax table used while in text mode.") (if text-mode-syntax-table () ; 構文テーブルが既存ならば変更しない (setq text-mode-syntax-table (make-syntax-table)) (modify-syntax-entry ?\" ". " text-mode-syntax-table) (modify-syntax-entry ?\\ ". " text-mode-syntax-table) (modify-syntax-entry ?' "w " text-mode-syntax-table)) (defvar text-mode-abbrev-table nil "Abbrev table used while in text mode.") (define-abbrev-table 'text-mode-abbrev-table ()) (defvar text-mode-map nil) ; モード固有のキーマップを作る (if text-mode-map () ; キーマップが既存ならば変更しない (setq text-mode-map (make-sparse-keymap)) (define-key text-mode-map "\t" 'indent-relative) (define-key text-mode-map "\es" 'center-line) (define-key text-mode-map "\eS" 'center-paragraph))
つぎは、テキスト(text)モードのメジャーモード関数の完全な定義です。
(defun text-mode () "Major mode for editing text intended for humans to read.... Special commands: \\{text-mode-map} Turning on text-mode runs the hook `text-mode-hook'." (interactive) (kill-all-local-variables) (use-local-map text-mode-map) (setq local-abbrev-table text-mode-abbrev-table) (set-syntax-table text-mode-syntax-table) (make-local-variable 'paragraph-start) (setq paragraph-start (concat "[ \t]*$\\|" page-delimiter)) (make-local-variable 'paragraph-separate) (setq paragraph-separate paragraph-start) (setq mode-name "Text") (setq major-mode 'text-mode) (run-hooks 'text-mode-hook)) ; 最後に、フックによるモードの ; カスタマイズをユーザーに許す
3つのlispモード(lispモード、emacs-lispモード、lisp対話モード)には、
テキスト(text)モードより多くの機能があり、
それに応じてコードもより複雑です。
これらのモードの書き方を例示する
lisp-mode.el
からの抜粋をあげておきます。
;; モード固有の構文テーブルを作成する
(defvar lisp-mode-syntax-table nil "")
(defvar emacs-lisp-mode-syntax-table nil "")
(defvar lisp-mode-abbrev-table nil "")
(if (not emacs-lisp-mode-syntax-table) ; 構文テーブルが既存ならば
; 変更しない
(let ((i 0))
(setq emacs-lisp-mode-syntax-table (make-syntax-table))
;; 0までの文字に、単語構成文字ではないが
;; シンボル名構成文字であるクラスを設定する
;; (文字0は、ASCII文字集合では48
)
(while (< i ?0)
(modify-syntax-entry i "_ " emacs-lisp-mode-syntax-table)
(setq i (1+ i)))
...
;; 他の文字の構文を設定する
(modify-syntax-entry ? " " emacs-lisp-mode-syntax-table)
(modify-syntax-entry ?\t " " emacs-lisp-mode-syntax-table)
...
(modify-syntax-entry ?\( "() " emacs-lisp-mode-syntax-table)
(modify-syntax-entry ?\) ")( " emacs-lisp-mode-syntax-table)
...))
;; lispモード向けの略語表を作る
(define-abbrev-table 'lisp-mode-abbrev-table ())
3つのlispモードは多くのコードを共有しています。 つぎの関数はさまざまな変数に設定します。 lispモードの各メジャーモード関数が呼び出します。
(defun lisp-mode-variables (lisp-syntax) (cond (lisp-syntax (set-syntax-table lisp-mode-syntax-table))) (setq local-abbrev-table lisp-mode-abbrev-table) ...
forward-paragraph
などの関数は、
変数paragraph-start
の値を使います。
Lispのコードは普通のテキストとは異なるので、
Lispを扱えるように変数paragraph-start
を特別に設定する必要があります。
また、Lispではコメントの字下げは特殊な形なので、
各lispモードには独自のモード固有のcomment-indent-function
が必要です。
これらの変数に設定するコードが、
lisp-mode-variables
の残りの部分です。
(make-local-variable 'paragraph-start) (setq paragraph-start (concat page-delimiter "\\|$" )) (make-local-variable 'paragraph-separate) (setq paragraph-separate paragraph-start) ... (make-local-variable 'comment-indent-function) (setq comment-indent-function 'lisp-comment-indent))
各lispモードでは、キーマップが多少異なります。
たとえば、lispモードではC-c C-zをrun-lisp
にバインドしますが、
他のlispモードではそうしません。
つぎのコードは、共通するコマンドを設定します。
(defvar shared-lisp-mode-map () "Keymap for commands shared by all sorts of Lisp modes.") (if shared-lisp-mode-map () (setq shared-lisp-mode-map (make-sparse-keymap)) (define-key shared-lisp-mode-map "\e\C-q" 'indent-sexp) (define-key shared-lisp-mode-map "\177" 'backward-delete-char-untabify))
つぎはlispモード向けのキーマップを設定するコードです。
(defvar lisp-mode-map () "Keymap for ordinary Lisp mode....") (if lisp-mode-map () (setq lisp-mode-map (make-sparse-keymap)) (set-keymap-parent lisp-mode-map shared-lisp-mode-map) (define-key lisp-mode-map "\e\C-x" 'lisp-eval-defun) (define-key lisp-mode-map "\C-c\C-z" 'run-lisp))
最後に、emacs-lispモードのメジャーモード関数の完全な定義を示します。
(defun lisp-mode ()
"Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp.
Commands:
Delete converts tabs to spaces as it moves back.
Blank lines separate paragraphs. Semicolons start comments.
\\{lisp-mode-map}
Note that `run-lisp' may be used either to start an inferior Lisp job
or to switch back to an existing one.
Entry to this mode calls the value of `lisp-mode-hook'
if that value is non-nil."
(interactive)
(kill-all-local-variables)
(use-local-map lisp-mode-map) ; モードのキーマップを選択する
(setq major-mode 'lisp-mode) ; これによりdescribe-mode
は
; 説明文を探し出せる
(setq mode-name "Lisp") ; モード行に表示される
(lisp-mode-variables t) ; さまざまな変数を定義する
(setq imenu-case-fold-search t)
(set-syntax-table lisp-mode-syntax-table)
(run-hooks 'lisp-mode-hook)) ; フックによるモードの
; カスタマイズをユーザーに許す
Emacsは、ファイル名やファイル自体の情報をもとに、 当該ファイルを訪問するときの新しいバッファに対する メジャーモードを自動的に選択します。 また、ファイル内のテキストで指定されたローカル変数も処理します。
fundamental-mode | コマンド |
基本(fundamental)モードは、特化してないメジャーモードである。
他のメジャーモードは、実質的には、このモードとの対比で定義されている。
つまり、基本(fundamental)モードから始めて、
それらのメジャーモードではなにを変更するかを定義している。
関数fundamental-mode はフックを実行しないため、
読者はカスタマイズできない。
(Emacsの基本(fundamental)モードのふるまいを変えたければ、
Emacsの大局的な状態を変える必要がある。)
|
normal-mode &optional find-file | コマンド |
この関数は、カレントバッファに対して
適切なメジャーモードとバッファローカルな変数を確立する。
この関数はまずset-auto-mode を呼び出し、
続いて、ファイルのローカル変数を必要に応じて解析、束縛、評価するために
hack-local-variables を実行する。
読者が対話的に
|
enable-local-variables | User Option |
この変数は、訪問したファイル内のローカル変数リストを処理するかどうかを
制御する。
値t は、ローカル変数リストを無条件に処理することを意味する。
nil は、それらを無視することを意味する。
それ以外の値であると、各ファイルごとにユーザーに問い合わせる。
デフォルト値はt である。
|
ignored-local-variables | Variable |
この変数は、ファイルのローカル変数リストで設定してはならない 変数のリストを保持する。 それらの変数に対して指定した値は無視される。 |
このリストに加えて、
属性risky-local-variable
がnil
以外の値である変数も無視されます。
enable-local-eval | User Option |
この変数は、訪問したファイル内のローカル変数リストのEval: を
処理するかどうかを制御する。
値t は、それらを無条件に処理することを意味する。
nil は、それらを無視することを意味する。
それ以外の値であると、各ファイルごとにユーザーに問い合わせる。
デフォルト値はmaybe である。
|
set-auto-mode | Function |
この関数は、カレントバッファに対して適切なメジャーモードを選択する。
-*- 行の値、
(auto-mode-alist を使って)訪問したファイルの名前、
(interpreter-mode-alist を使って)#! 行、
ファイルのローカル変数リストをもとに決定する。
しかし、この関数はファイルの末尾付近にある
ローカル変数mode: は調べないが、
関数hack-local-variables は調べる。
See Choosing Modes。
|
default-major-mode | User Option |
この変数は、新たなバッファに対するデフォルトのメジャーモードを保持する。
標準値はfundamental-mode である。
|
set-buffer-major-mode buffer | Function |
この関数はバッファbufferのメジャーモードを
default-major-mode の値とする。
この変数がnil であると、
(適切ならば)カレントバッファのメジャーモードを使う。
バッファを作成する低レベルの基本関数ではこの関数を使わないが、
|
initial-major-mode | Variable |
この変数の値は、最初のバッファ*scratch* のメジャーモードを決定する。
値は、メジャーモードコマンドのシンボルであること。
デフォルト値は、lisp-interaction-mode である。
|
auto-mode-alist | Variable |
この変数は、ファイル名のパターン(正規表現、see Regular Expressions)と
対応するメジャーモードの連想リストを保持する。
通常、ファイル名パターンでは.el や.c などの接尾辞を調べるが、
そうでなくてもよい。
連想リストの通常の要素は
(regexp . mode-function) の形である。
たとえばつぎのとおり。 (("\\`/tmp/fol/" . text-mode) ("\\.texinfo\\'" . texinfo-mode) ("\\.texi\\'" . texinfo-mode) ("\\.el\\'" . emacs-lisp-mode) ("\\.c\\'" . c-mode) ("\\.h\\'" . c-mode) ...) 展開したファイル名(see File Name Expansion)がregexpに一致する
ファイルを訪問すると、
(setq auto-mode-alist
(append
;; ドットで始まる(ディレクトリ名付きの)ファイル名
'(("/\\.[^/]*\\'" . fundamental-mode)
;; ドットのないファイル名
("[^\\./]*\\'" . fundamental-mode)
;;
|
interpreter-mode-alist | Variable |
この変数は、#! 行でコマンドインタープリタを指定している
スクリプトに対して用いるメジャーモードを指定する。
この値は、(interpreter . mode) の形の要素から成る
リストであること。
たとえば、デフォルトには("perl" . perl-mode) の要素がある。
各要素は、ファイルが指定するインタープリタがinterpreterに
一致したらモードmodeを使うことを意味する。
interpreterの値は、実際には正規表現である。
|
hack-local-variables &optional force | Function |
この関数は、カレントバッファの内容に指定されたローカル変数を
必要に応じて、解析、束縛、評価する。
|
関数describe-mode
は、メジャーモードに関する情報を
得るために使います。
通常、C-h mで呼び出されます。
関数describe-mode
はmajor-mode
の値を使いますが、
そのために各メジャーモード関数が
変数major-mode
に設定する必要があるのです。
describe-mode | コマンド |
この関数は、現在のメジャーモードの説明文を表示する。
関数 |
major-mode | Variable |
この変数は、カレントバッファのメジャーモードに対するシンボルを保持する。
このシンボルは、当該メジャーモードに切り替えるためのコマンドを
関数定義として持つこと。
関数describe-mode は、
メジャーモードの説明文として当該関数の説明文字列を使う。
|
既存のメジャーモードを用いて新たなメジャーモードを定義できると便利です。
これを行う簡単な方法はdefine-derived-mode
を使うことです。
define-derived-mode variant parent name docstring body... | Macro |
これは、nameをモード名を表す文字列として使って
variantをメジャーモードコマンドとして定義する。
新たなコマンドvariantは、関数parentを呼び出してから 親モードの特定の機能を無効にするように定義される。
さらに、bodyでparentの他の部分を無効にする方法を指定できる。
コマンドvariantは、 引数docstringは、新たなモードに対する説明文字列を指定する。
docstringを省略すると、
仮想的な例を示す。 (define-derived-mode hypertext-mode text-mode "Hypertext" "Major mode for hypertext. \\{hypertext-mode-map}" (setq case-fold-search nil)) (define-key hypertext-mode-map [down-mouse-3] 'do-hyper-link) |
マイナモード(minor mode)は、メジャーモードの選択とは独立に ユーザーがオン/オフできる機能を提供します。 マイナモードは、個別にも組み合わせてもオンにできます。 マイナモードは、長すぎますが『汎用的に使えるオプション機能のモード』と 命名したようがよいかもしれません。
マイナモードは、普通、1つのメジャーモードを変更するだけではありません。 たとえば、自動詰め込みモード(auto-fillモード)は、 テキスト挿入を許す任意のメジャーモードで使えます。 汎用的であるためには、マイナモードは メジャーモードが行うこととは実質的に独立である必要があります。
マイナモードは、メジャーモードに比べて、実装するのがしばしば困難です。 1つの理由は、任意の順でマイナモードをオン/オフできるようにする 必要があるからです。 マイナモードは、メジャーモードや他のオンになっているマイナモードとは 無関係にその望みの効果を発揮できる必要があります。
しばしば、マイナモードを実装するうえでもっとも大きな問題は、 Emacsの残りの部分に対して必要なフックを探すことです。 マイナモードキーマップにより、従来に比べて簡単になります。
メジャーモードに対するのと同じように、 マイナモードを書くうえでの慣習があります。 メジャーモードの慣習には、マイナモードにも適用されるものがあります。 つまり、モードを初期化する関数の名前、 グローバルシンボルの名前、キーマップやその他のテーブルや表の使い方です。
それらに加えて、マイナモードに固有な慣習もあります。
-mode
で終ること。
これをモード変数(mode variable)と呼ぶ。
マイナモードコマンドは、この変数を
(オフにするにはnil
、オンにするにはそれ以外に)設定
すること。
可能ならば、変数に設定すると 自動的にモードがオン/オフされるようにモードを実装する。 そうすると、マイナモードコマンドは、 変数に設定する以外にはなにもしないでよくなる。
この変数は、モード行にマイナモード名を表示するために
minor-mode-alist
でも使われる。
マイナモードキーマップを活性にしたり非活性にしたりもする。
各コマンドやフックもこの変数の値を検査する。
各バッファごとに別々にマイナモードをオンにしたい場合には、 この変数をバッファローカルにする。
当該コマンドは、省略可能な引数を1つ受け取ること。
引数がnil
であればモードをトグル
(オンであればオフに、オフであればオンに)する。
さもなければ、引数が、正整数、nil
以外のシンボル、
-
、あるいは、CARがそのような整数やシンボルであるようなリストの
場合にはモードをオンにする。
それ以外ではモードをオフにする。
transient-mark-mode
の定義から引用した例を示す。
モードのふるまいをオン/オフする変数としての
transient-mark-mode
の使い方、
および、生の前置引数に基づいたマイナモードの
オン/オフ/トグルの仕方を示す。
(setq transient-mark-mode (if (null arg) (not transient-mark-mode) (> (prefix-numeric-value arg) 0)))
minor-mode-alist
に追加する
(see Mode Line Variables)。
この要素はつぎの形のリストであること。
(mode-variable string)
ここで、mode-variableはマイナモードのオン/オフを制御する変数であり、 stringはモード行でモードを表す短い空白で始まる文字列である。 同時に複数のモードを表示できるように、これらの文字列は短いこと。
minor-mode-alist
に要素を追加するときには、
重複を防ぐために既存の要素を検査するassq
を使うこと。
たとえばつぎのとおり。
(or (assq 'leif-mode minor-mode-alist) (setq minor-mode-alist (cons '(leif-mode " Leif") minor-mode-alist)))
このリストに要素を1回だけ追加するならばadd-to-list
も使えます
(see Setting Variables)。
各マイナモードは、モードがオンのときに活性になる独自のキーマップを持てます。
マイナモード向けのキーマップを設定するには、
minor-mode-map-alist
に要素を追加します。
See Active Keymaps。
マイナモードキーマップの1つの用途は、
ある種の自己挿入文字のふるまいを変更して、
自己挿入に加えてなにかを行わせるようにすることです。
一般に、self-insert-command
をカスタマイズする機構は
(略語モードや自動詰め込みモード向けに設計された)特別な場合に限られるので、
このようなことを行う唯一の方法です。
(標準のself-insert-command
の定義を読者独自の定義で置き換えないこと。
エディタコマンドループはこの関数を特別扱いしている。)
マイナモードでバインドしているキー列は、C-cで始まり、 {、}、<、>、:、;以外の 句読点文字の1つが続くようにします。 (除外した句読点文字はメジャーモード向けに予約されている。)
パッケージeasy-mmodeは、マイナモードを実装する便利な方法を提供します。 これを使うと、単純なマイナモードを1つの自己完結した定義に指定できます。
easy-mmode-define-minor-mode mode doc &optional init-value mode-indicator keymap | Macro |
このマクロは、mode(シンボル)という名前の新しいマイナモードを定義する。
このマクロは、マイナモードをトグルする modeという名前のコマンドを定義し、 その説明文字列をdocとする。 また、modeという名前の変数も定義する。
この変数はモードのオン/オフにしたがって 文字列mode-indicatorは、モードがオンのときにモード行に
表示される文字列である。
それが 省略可能な引数keymapは、マイナモードのキーマップを指定する。 これは、値がキーマップであるような変数の名前か、 つぎの形のバインディングを指定した連想リストであること。 (key-sequence . definition) |
easy-mmode-define-minor-mode
を使った例を示します。
(easy-mmode-define-minor-mode hungry-mode "Toggle Hungry mode. With no argument, this command toggles the mode. Non-null prefix argument turns on the mode. Null prefix argument turns off the mode. When Hungry mode is enabled, the control delete key gobbles all preceding whitespace except the last. See the command \\[hungry-electric-delete]." ;; 初期値 nil ;; モード行への表示 " Hungry" ;; マイナモードのバインディング '(("\C-\^?" . hungry-electric-delete) ("\C-\M-\^?" . (lambda () (interactive) (hungry-electric-delete t)))))
これは、『hungryモード』という名前のマイナモードを定義します。
モードをトグルするコマンドの名前はhungry-mode
、
モードのオン/オフを表す変数の名前はhungry-mode
、
モードがオンのときに活性なキーマップを保持する
変数の名前はhungry-mode-map
です。
C-<DEL>とC-M-<DEL>に対するキーバインディングで
キーマップを初期化します。
Emacsの(ミニバッファ専用ウィンドウを除く)各ウィンドウにはモード行があって、 ウィンドウに表示しているバッファに関する状態情報を表示しています。 モード行には、バッファ名、対応するファイル、再帰編集の深さ、 メジャーモードとマイナモードなどのバッファに関する情報が含まれます。
本節では、モード行の内容の制御方法について述べます。 モード行に表示される情報のほとんどは オンになっているメジャーモードとマイナモードに関係するので、 本章に含めます。
mode-line-format
は、カレントバッファのモード行に表示する
雛型を保持しているバッファローカルな変数です。
同一バッファに対するすべてのウィンドウは同じmode-line-format
を使い、
それらのモード行は(スクロールの割合や行やコラム位置を除いて)
同じように表示されます。
ウィンドウのモード行は、通常、ウィンドウに別のバッファを表示したときや、
バッファの変更状態がnil
からt
へあるいはその逆の変化をしたときに
更新されます。
mode-line-format
(see Mode Line Variables)が参照する
変数を修正したり、テキストの表示方法に影響するその他の変数やデータ構造
(see Display)を変更したときには、新しい情報を表示したり
新たな方法で表示するためにモード行の更新を強制できます。
force-mode-line-update | Function |
カレントバッファのモード行の更新を強制する。 |
モード行は、通常、反転表示されます。
Inverse Videoのmode-line-inverse-video
を参照してください。
モード行の内容は、バッファローカルな変数mode-line-format
に
保持されたリスト、文字列、シンボル、数から成るデータ構造で制御されます。
このデータ構造をモード行構成(mode line construct)と呼びます。
これは単純なモード行構成から再帰的に構築します。
同じデータ構造はフレームタイトル(see Frame Titles)を
構築するためにも使われます。
mode-line-format | Variable |
この変数の値は、モード行全体の書式に責任を持つモード行構成である。 この変数の値は、モード行のテキストを作るためにどの変数を使うか、 それらはモード行のどこに現れるかを制御する。 |
モード行構成は、定まったテキストの文字列のように単純でもかまいませんが、 普通は、テキストを作るための別の変数の使い方を指定します。 それらの変数の多くはそれ自身、それらの値として モード行構成を持つように定義されています。
mode-line-format
のデフォルト値は、
mode-name
やminor-mode-alist
などの変数の値を使います。
多くの目的には、mode-line-format
が参照するいくつかの変数を
変えるだけで十分です。
モード行構成は、リスト、シンボル、文字列のいずれかです。 その値がリストであれば、その各要素はリスト、シンボル、文字列のいずれかです。
string
%
記法を除いて、モード行にそのまま表示される。
%
のうしろの10進数は、右側に空白を埋める
(つまりデータは左端に揃えられる)ときのフィールド幅を指定する。
see %-Constructs。
symbol
t
やnil
のシンボル、および、シンボルの値が空のものは
無視する。
例外が1つある:
symbolの値が文字列であると、%
記法を処理せずに
文字列をそのまま表示する。
(string rest...) or (list rest...)
(symbol then else)
nil
以外であると、
2番目の要素thenをモード行構成として再帰的に処理する。
symbolの値がnil
であると、
3番目の要素elseをモード行構成として再帰的に処理する。
elseは省略してもよいが、その場合、
symbolの値がnil
であるところの要素はモード行に表示されない。
(width rest...)
たとえば、ウィンドウの上端より上にバッファの何割があるかを表示するには、
(-3 "%p")
のようなリストを使う。
読者がmode-line-format
自体を変更するときには、
新しい値では、デフォルト値(see Mode Line Variables)に現れる
ものと同じ変数を使い、それらの値をコピーして使ったり、
別の書式で情報を表示したりしないでください。
こうしておけば、それらの変数に対する変更を介した
ユーザーや(display-time
やメジャーモードなどの)Lispプログラムが行った
カスタマイズが効果を発揮できます。
ホスト名やデフォルトディレクトリを含んだ
shell-mode
に有用な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 " %[(" 'mode-name 'mode-line-process 'minor-mode-alist "%n" ")%]--" '(which-func-mode ("" which-func-format "--")) '(line-number-mode "L%l--") '(column-number-mode "C%c--") '(-3 . "%p") "-%-"))
(変数line-number-mode
、column-number-mode
、
which-func-mode
は特定のマイナモードをオンにする。
通常どおり、これらの変数の名前はマイナモードコマンドの名前でもある。)
本節では、mode-line-format
の標準値でモード行のテキストに
含められる変数について述べます。
これらの変数に関しては、本来特別なことはありません。
別の変数を使うようにmode-line-format
を変更すれば、
別の変数でもモード行において同じ効果を発揮します。
mode-line-mule-info | Variable |
この変数は、言語環境、バッファのコーディングシステム、 現在の入力方式に関する情報を表示するモード行構成の値を保持する。 see Non-ASCII Characters。 |
mode-line-modified | Variable |
この変数は、カレントバッファが変更されたかどうかを表示する
モード行構成の値を保持する。
この変数を変更してもモード行の更新を強制しない。 |
mode-line-frame-identification | Variable |
この変数はカレントフレームを識別する。
複数のフレームを表示できるウィンドウシステムを使用している場合には
デフォルト値は" " であり、
ある時点で1つのフレームしか表示できない普通の端末を使用している場合には
"-%F " である。
|
mode-line-buffer-identification | Variable |
この変数はウィンドウに表示しているバッファを識別する。
デフォルト値は("%12b") であり、
空白で埋めて最低12コラムでバッファ名を表示する。
|
global-mode-string | Variable |
この変数は、デフォルトでモード行のバッファ名の直後に現れる
モード行指定を保持する。
コマンドdisplay-time は、
global-mode-string が時刻と負荷情報を含んだ
変数display-time-string を参照するように設定する。
|
mode-name | Variable |
このバッファローカルな変数は、 カレントバッファのメジャーモードの『愛称』を保持する。 各メジャーモードは、モード行にモード名が現れるようにこの変数に設定すること。 |
minor-mode-alist | Variable |
この変数は、モード行にマイナモードがオンであることを表示する方法を
指定する要素からなる連想リストを保持する。
minor-mode-alist の各要素は、2要素リストであること。
(minor-mode-variable mode-line-string) より一般的には、mode-line-stringはどのようなモード行指定でもよい。
それは、minor-mode-variableの値が
minor-mode-alist => ((vc-mode vc-mode) (abbrev-mode " Abbrev") (overwrite-mode overwrite-mode) (auto-fill-function " Fill") (defining-kbd-macro " Def") (isearch-mode isearch-mode))
|
mode-line-process | Variable |
このバッファローカルな変数は、
サブプロセスとの通信用に使われているモードの処理状態に関する
モード行の情報を保持する。
メジャーモード名の直後に空白で区切らずに表示される。
たとえば、バッファ*shell* におけるこの変数の値は(":%s") であり、
シェルがその状態をメジャーモードとともに(Shell: run) のように
表示できる。
通常、この変数はnil である。
|
default-mode-line-format | Variable |
この変数は、mode-line-format を変更していないバッファの
デフォルトのmode-line-format の値を保持する。
これは(default-value 'mode-line-format) と同じである。
("-" mode-line-mule-info mode-line-modified mode-line-frame-identification mode-line-buffer-identification " " global-mode-string " %[(" mode-name mode-line-process minor-mode-alist "%n" ")%]--" (which-func-mode ("" which-func-format "--")) (line-number-mode "L%l--") (column-number-mode "C%c--") (-3 . "%p") "-%-") |
vc-mode | Variable |
各バッファにおいてバッファローカルな変数vc-mode は、
バッファで訪問したファイルが版管理されているか、
そうならばその方式を記録している。
版管理されていない場合はその値はnil 、
さもなければモード行に表示される文字列である。
|
%
記法以下は、認識される%
記法とその意味の表です。
%%
以外の記法では、
最大表示文字数を指定する10進数を%
のあとに追加できます。
%b
buffer-name
で得られたカレントバッファ名。
see Buffer Names。
%f
buffer-file-name
で得られた訪問したファイルの名前。
see Buffer File Name。
%F
%c
%l
%*
%
(buffer-read-only
を参照)、*
(buffer-modified-p
を参照)、-
。
see Buffer Modification。
%+
*
(buffer-modified-p
を参照)、%
(buffer-read-only
を参照)、-
。
%*
との違いは、変更された読み出し専用バッファに対してのみである。
see Buffer Modification。
%&
*
、さもなければ-
である。
%s
process-status
で得たカレントバッファに属するサブプロセスの状態。
see Process Information。
%t
%p
Top
、Bottom
、All
のいずれかである。
%P
Top
を加えたもの、
あるいは、Bottom
、All
のいずれかである。
%n
Narrow
、さもなければなにもなし。
(Narrowingのnarrow-to-region
を参照)。
%[
[
。
see Recursive Editing。
%]
]
。
%%
%
。
%
記法を許す文字列に%
をそのまま含めるための方法である。
%-
つぎの2つの%
記法はまだ使えますが、
変数mode-name
やglobal-mode-string
を
使って同じ効果を得られるのでこれらは廃れた記法です。
%m
mode-name
の値。
%M
global-mode-string
の値。
現在、display-time
はglobal-mode-string
の値を変更する。
iメニュー(Imenu)とは、ユーザーが バッファ内の定義や節の一覧からその1つを選ぶと バッファ内の当該箇所へ直接移動できる機能です。 iメニューは、 バッファ内の定義や部分の名前や位置を表すバッファインデックスを 構築しておくことで動作し、 当該箇所へ移動するためにユーザーがそれらの1つを選べるようにします。 本節ではメジャーモードに対するiメニューをカスタマイズする方法を説明します。
普通のもっとも単純な方法は、
変数imenu-generic-expression
に設定することです。
imenu-generic-expression | Variable |
この変数がnil 以外であると、
iメニュー向けの定義を探すための正規表現を指定する。
もっとも単純な場合、要素はつぎのような形である。
(menu-title regexp subexp) ここで、menu-titleが リストの2番目の要素regexpは正規表現 (see Regular Expressions)であり、 これに一致した箇所がバッファインデックスに現れる定義になる。 3番目の要素subexpは、 定義の名前に一致するregexpの部分式である。 要素はつぎの形でもよい。 (menu-title regexp index function arguments...) この要素に一致するものは、バッファインデックスの特別な項目になり、 ユーザーが当該項目を選ぶと、 item-name、バッファ位置、argumentsを引数として functionを呼び出す。 emacs-lispモード向けには、patternはつぎのようになる。 ((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)) この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。 |
imenu-case-fold-search | Variable |
この変数は、imenu-generic-expressionとの一致に際して
大文字小文字を区別するかどうかを制御する。
デフォルトはt であり、大文字小文字を区別せずに一致をとる。
この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。 |
imenu-syntax-alist | Variable |
この変数は、imenu-generic-expression を処理中に
カレントバッファの構文テーブルに優先する
構文テーブルの変更部分の連想リストである。
各要素はつぎの形であること。
(characters . syntax-description) CARのcharactersは、文字か文字列である。
それらの文字は、指定した構文syntax-descriptionであることを意味する。
これは この機能は典型的には、
通常のシンボル構成文字を単語構成文字として扱い、
(setq imenu-syntax-alist '(("_$" . "w"))) こうすると、 この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。 |
メジャーモードのiメニューをカスタマイズする別の方法は、
変数imenu-prev-index-position-function
や
imenu-extract-index-name-function
に設定することです。
imenu-prev-index-position-function | Variable |
この変数がnil 以外であると、その値は、
バッファインデックスに置くつぎの定義を
ファイルで後向きに探すための関数であること。
その関数は、バッファインデックスの項目に対応する箇所にポイントを置くこと。
項目がみつからなければ この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。 |
imenu-extract-index-name-function | Variable |
この関数がnil 以外であると、その値は、
ポイントが変数imenu-prev-index-position-function が返した
定義の部分にあると仮定して、当該定義の名前を返す関数であること。
この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。 |
メジャーモードのiメニューをカスタマイズする最後の方法は、
変数imenu-create-index-function
に設定することです。
imenu-create-index-function | Variable |
この関数は、バッファインデックスの作成に使う関数を指定する。
その関数は引数なしで、カレントバッファに対するインデックスを返すこと。
save-excursion の内側から呼ばれるので、
その関数がポイントをどこに置こうと関係ない。
デフォルト値は、インデックスの連想リストを生成するために
この変数に設定すると、 カレントバッファにおいてバッファローカルな変数になる。 |
imenu-index-alist | Variable |
この変数は、カレントバッファに対するインデックスの連想リストを保持する。
この変数に設定すると、
カレントバッファにおいてバッファローカルな変数になる。
連想リストの単純な要素は 特別な要素は (funcall function index-name position arguments...) 入れ子になった部分連想リストの要素は
|
フォントロック(font-lock)モードとは、
バッファ内の特定部分に対して、それらの構文上の役割に応じた
属性face
を自動的に付加する機能のことです。
バッファを解析する方法はメジャーモードに依存しますが、
ほとんどのメジャーモードでは、
どの文脈でどのフェイスを使うかを指示する条件を定義します。
本節では、特定の言語向けに、いいかえれば、
特定のメジャーモード向けに
フォントロックをカスタマイズする方法を説明します。
フォントロック(font-lock)モードは、強調表示すべきテキストを
2つの方法で、つまり、構文テーブルに基づいた構文解析、あるいは、
(通常、正規表現による)探索で探します。
構文解析による処理を最初に行ってコメントや文字列定数を探し、
font-lock-comment-face
やfont-lock-string-face
(see Faces for Font Lock)を使ってそれらを強調表示します。
探索による処理がこれに続きます。
フォントロック(font-lock)モードがテキストを強調表示する方法を
制御する変数がいくつかあります。
しかし、メジャーモードでこれらの変数を直接に設定するべきではありません。
そのかわりに、バッファローカルな
変数font-lock-defaults
に設定すべきです。
フォントロック(font-lock)モードがオンになると、
この変数に設定された値を使って他のすべての変数に設定します。
font-lock-defaults | Variable |
この変数はメジャーモードがバッファローカルな変数として設定し、
当該モードにおいてテキストをどのように表示するかを指定する。
値はつぎの形であること。
(keywords keywords-only case-fold syntax-alist syntax-begin other-vars...) 最初の要素keywordsは、
間接的に 2番目の要素keywords-onlyは、
変数 3番目の要素case-foldは、
4番目の要素syntax-alistが 5番目の要素syntax-beginは、
other-vars以降の要素は、
|
フォントロック(font-lock)モードのカスタマイズにおいて
もっとも重要な変数はfont-lock-keywords
です。
探索に基づく表示方法の選択における探索条件を指定します。
font-lock-keywords | Variable |
この変数の値は、強調表示するべきキーワードのリストである。 このリストに正規表現を書く場合には注意すること。 貧弱な書き方をしたパターンであると、動作を劇的に遅くする! |
font-lock-keywords
の各要素は、
特定のテキストの探し方と
当該テキストをどのように強調表示するか指定します。
フォントロック(font-lock)モードは、
font-lock-keywords
の要素を1つ1つ処理し、
各要素において、それに一致するものすべてを探して処理します。
通常、すでに表示方法を選択済みのテキスト部分については、
それ以降の要素に一致しても表示方法を変えません。
しかし、highlighterの要素overrideを使って、
異なるふるまいを指定できます。
font-lock-keywords
の各要素はつぎのいずれかの形です。
regexp
font-lock-keyword-face
を使って強調表示する。
;; 孤立したfoo
の出現は ;;font-lock-keyword-face
で強調表示する。 "\\<foo\\>"
関数regexp-opt
(see Syntax of Regexps)は、
異なる複数個のキーワードに一致する最適な正規表現を
計算するのに有用である。
function
font-lock-keyword-face
を使って強調表示する。
functionは、探索限界を引数として呼び出される。
みつかればnil
以外を返すとともに
みつけた部分を表すマッチデータを設定する。
(matcher . match)
;;fubar
の各出現のbar
を ;;font-lock-keyword-face
で強調表示 ("fu\\(bar\\)" . 1)
正規表現matcherを作るためにregexp-opt
を使った場合、
matchの値を計算するには
regexp-opt-depth
(see Syntax of Regexps)を使える。
(matcher . facename)
;;fubar
の出現は、fubar-face
の値で ;; 表されたフェイスを使って強調表示 ("fubar" . fubar-face)
(matcher . highlighter)
(subexp facename override laxmatch)
CARのsubexpは、 強調表示すべき一致部分の部分式を指定する整数 (0は一致部分全体を意味する)である。 2番目の要素facenameは、上に述べたようにフェイスを指定する。
highlighterの最後の2つの要素、
overrideとlaxmatchはフラグである。
overrideがt
であると、当該要素は、
font-lock-keywords
のまえの要素で決定済みの
表示方法に優先することを表す。
keep
であると、他の要素では表示方法が決定していない
各文字の表示方法を表す。
prepend
であると、
属性face
の先頭にフェイスfacenameを追加する。
append
であると、
属性face
の末尾にフェイスfacenameを追加する。
laxmatchがnil
以外であると、
matcherで一致したものの中にsubexp番目の部分式が
なくてもエラーとしないことを意味する。
この種の要素とその動作の例を示す。
;;foo
やbar
の出現の表示方法がすでに決まっていても ;;foo-bar-face
で強調表示する ;;foo-bar-face
の値はフェイスであること ("foo\\|bar" 0 foo-bar-face t) ;; 関数fubar-match
がみつけた各出現内の最初の部分式を ;;fubar-face
の値が表すフェイスで強調表示する (fubar-match 1 fubar-face)
(matcher highlighters...)
(eval . form)
font-lock-keywords
のこの値が
始めて使われたときに評価すべき式である。
その値は、この表にあげた形の1つであること。
警告:
font-lock-keywords
の要素は、
行をまたがって一致するように設計しないこと。
そのような処理は信頼性がない。
font-lock-fontify-buffer
は、行にまたがるパターンを正しく扱えるが、
読者がバッファを編集したときの更新処理では、
一度に1行ずつ処理するために正しく扱えない。
本節では、font-lock-defaults
を用いてメジャーモードで
設定できる他の変数について述べます。
font-lock-keywords-only | Variable |
nil 以外であると、フォントロック(font-lock)モードは、
構文に基づいてコメントや文字列を強調表示すべきでないことを意味する。
font-lock-keywords に基づく強調表示のみを行う。
|
font-lock-keywords-case-fold-search | Variable |
nil 以外であると、font-lock-keywords の
正規表現探索では大文字小文字を区別しないことを意味する。
|
font-lock-syntax-table | Variable |
この変数は、コメントや文字列の表示方法に用いる 構文テーブルを指定する。 |
font-lock-beginning-of-syntax-function | Variable |
この変数がnil 以外であると、
ポイントを構文上の『トップレベル』で文字列やコメントの外側に
後方移動する関数であること。
フォントロック(font-lock)モードは、
構文に基づく処理において正しい結果を得るために
必要に応じてこの関数を使う。
関数は引数なしで呼び出される。
ポイントを構文ブロックの先頭に置くこと。
典型的な値は、
値が |
font-lock-mark-block-function | Variable |
この変数がnil 以外であると、
コマンドM-g M-g(font-lock-fontify-block )による
再表示のためにテキストの括られた範囲を選ぶために
引数なしで呼ばれ関数であること。
関数は、選んだ範囲にリージョンを設定すること。
正しい結果を得られるように大きめのテキスト範囲を選ぶのがよいが、
再表示処理が遅くならないように大きすぎないこと。
典型的な値は、プログラム向けモードでは |
多くのメジャーモードでは、3段階の表示方法を提供します。
font-lock-defaults
のkeywordsに
シンボルのリストを使って複数レベルを定義できます。
各シンボルは1つのレベルの表示方法を指定します。
どのレベルを選ぶかはユーザーの責任です。
指定したレベルのシンボルの値はfont-lock-keywords
の初期化に使われます。
表示方法のレベルを定義する際の慣習をあげておきます。
関数宣言、(includeやimportなどの)ファイル指定、文字列、
コメントを強調表示する。
速さが肝心であり、重要な構文やトップレベルの構成要素のみを強調表示する。
レベル1に加えて、キーワードのようにふるまう型名を含む
当該言語のすべてのキーワード、名前付き定数。
(構文的な、あるいは、意味的な)すべてのキーワードを
適切に強調表示するのが目的。
レベル2に加えて、
関数や変数宣言で定義されたシンボル、適切なすべての組み込み関数の名前。
フォントロック(font-lock)モードでは任意のフェイスを使えますが、
フォントロック(font-lock)モード向けに特別に定義さたフェイスがあります。
これらのシンボルのおのおのは、フェイス名でもあり、
シンボル自身をデフォルト値とする変数でもあります。
つまり、font-lock-comment-face
のデフォルト値は、
font-lock-comment-face
です。
これは、
フェイス名を値に持つような式を書くfont-lock-keywords
などの場面で、
font-lock-comment-face
と書けることを意味します。
font-lock-comment-face
font-lock-string-face
font-lock-keyword-face
for
やif
のように構文的に重要な名前に使われる。
font-lock-builtin-face
font-lock-function-name-face
font-lock-variable-name-face
font-lock-type-face
font-lock-constant-face
font-lock-warning-face
;;;###autoload
や
Cの#error
指定に使われる。
フォントロック(font-lock)モードは、
属性syntax-table
を自動更新するためにも使えます。
1つの構文テーブルだけでは十分でないような言語において有用です。
font-lock-syntactic-keywords | Variable |
この変数は構文的なフォントロックをオンにし制御する。
その値はつぎの形の要素からなるリストであること。
(matcher subexp syntax override laxmatch) この要素の各部分には、つぎの (matcher subexp facename override laxmatch) しかし、属性 |
フック(hook)とは、既存のプログラムから特定の場面で
呼び出される(1つか一連の)関数を収めた変数です。
Emacsは、カスタマイズのためにフックを用意しています。
ほとんどの場合、フックはファイル.emacs
で設定しますが、
Lispプログラムが行ってもかまいません。
標準のフック関数一覧については、See Standard Hooks。
Emacsの多くのフックはノーマルフック(normal hook)です。
これらの変数は、引数なしで呼び出される関数のリストを保持しています。
フック名が-hook
で終っていると、ノーマルフックを意味します。
読者がそれらを単一の方法で使えるように、
可能な限りノーマルフックにするように心掛けています。
各メジャーモード関数は、
その初期化の最終段階でモードフック(mode hook)と呼ばれる
ノーマルフックを実行すると期待されます。
これにより、モードがすでに設定したバッファローカルな変数を上書きすることで、
ユーザーがモードのふるまいをカスタマイズしやすくしています。
しかし、フックは別の場面でも使われています。
たとえば、フックsuspend-hook
は、
Emacsが自身を一時休止する直前に実行されます。
(see Suspending Emacs)。
ノーマルフックにフック関数を追加する推奨方法は、
add-hook
(下記参照)を呼ぶことです。
フック関数は、funcall
(see What Is a Function)が
受け付けるならばどんな種類の関数でもかまいません。
ほとんどのノーマルフック変数は最初は空ですが、
add-hook
はその扱い方を知っています。
フック変数の名前が-hook
で終らない場合、
それがアブノーマルフック(abnormal hook)であることを表します。
読者は、そのようなフックの正しい使い方を説明書で調べるべきです。
変数名が-functions
や-hooks
で終っていると、
その値は関数のリストですが、
それらの関数を引数ありで呼び出したり、
関数の戻り値をどこかで使うという意味でアブノーマル(異常)なのです。
リストに関数を追加するにはadd-hook
を使えますが、
関数を書くときには注意する必要があります。
(これらの変数のうち、実際にはノーマルフックであるものもある。
ノーマルフックには-hook
を使うという慣習を
確立するまえに命名したものである。)
変数名が-function
で終っていると、
その値は、関数のリストではなく、1つの関数です。
lisp対話モードで自動詰め込み(auto-fill)モードをオンにするために モードフックを使った例を示します。
(add-hook 'lisp-interaction-mode-hook 'turn-on-auto-fill)
適当な時期に、Emacsは関数run-hooks
を使って
特定のフックを実行します。
この関数は、add-hook
で追加されたフック関数を呼び出します。
run-hooks &rest hookvar | Function |
この関数は複数個のフック変数名を引数にとり、各フックを順に実行する。
各引数hookvarは、フック変数のシンボルであること。
これらの引数は、指定された順に処理される。
フック変数が 例として、 (run-hooks 'emacs-lisp-mode-hook) |
run-hook-with-args hook &rest args | Function |
この関数は、フック関数に引数を渡すアブノーマルフックを実行する方法である。 各フック関数に引数argsを渡して呼び出す。 |
run-hook-with-args-until-failure hook &rest args | Function |
この関数は、フック関数に引数を渡すアブノーマルフックを実行するが、
フック関数が失敗するとただちに止める方法である。
フック関数がnil を返すまで、
各フック関数に引数argsを渡して呼び出す。
nil が返ってくるとnil で戻る。
さもなければ、nil 以外の値を返す。
|
run-hook-with-args-until-success hook &rest args | Function |
この関数は、フック関数に引数を渡すアブノーマルフックを実行するが、
フック関数が成功するとただちに止める方法である。
フック関数がnil 以外を返すまで、
各フック関数に引数argsを渡して呼び出す。
nil 以外が返ってくると
最後に呼び出したフック関数の戻り値を返す。
|
add-hook hook function &optional append local | Function |
この関数はフック変数hookに関数functionを追加する
手軽な方法である。
引数functionは、正しい個数の引数をとる任意の正しいLisp関数であること。
たとえば、
(add-hook 'text-mode-hook 'my-text-hook-function) は、
フック関数は実行順序に依存しないように設計するのが最良である。
実行順序に依存すると『トラブルを呼び込む』ようなものである。
しかし、順序は予測できる。
通常、functionはフックリストの先頭に置かれるので、
(ほかに localが |
remove-hook hook function &optional local | Function |
この関数は、フック変数hookからfunctionを取り除く。
localが |
make-local-hook hook | Function |
この関数は、フック変数hook をカレントバッファにバッファローカルにする。
フック変数がバッファローカルであると、
バッファローカルなフック関数とグローバルなフック関数を持つことができ、
run-hooks はそれらすべてを実行する。
この関数は、バッファローカルな値の要素を フック変数に対して |
GNU Emacs Lispには、便利なオンラインのヘルプ機能があります。 そのほとんどは、関数や変数に付随した説明文字列から取り出したものです。 本章では、説明文を参照するプログラムの書き方に加えて、 読者のLispプログラムに適切な説明文字列を書く方法を説明します。
Emacsの説明文字列は、Emacsマニュアルと同じものではないことに注意願います。 マニュアルには言語texinfoで書いた独自のソースファイルがありますが、 説明文字列は関数や変数の定義の中で指定されています。 説明文字列を集めても、よいマニュアルとは構成が違いますので、 マニュアルとしては十分ではありません。
説明文字列は、文字列に対するLisp構文、 つまり、文字列のテキストをダブルクォートで囲って書きます。 これは、説明文字列が実際にはLispの文字列オブジェクトだからです。 関数や変数の定義の正しい箇所に文字列を書くと、 説明文としての役割を果たします。 関数定義においては、説明文字列は引数のつぎにあります。 変数定義においては、変数の初期値のつぎにあります。
説明文字列を書くときには、
最初の1行は1つの(あるいは2つの)完全な文にしてください。
apropos
などのある種のコマンドは、
複数行にまたがる説明文字列の最初の1行だけを表示するからです。
また、説明文字列の2行目以降を字下げしないでください。
字下げがあると、
C-h f(describe-function
)や
C-h v(describe-variable
)で説明文字列を表示すると
不恰好になります。
See Documentation Tips。
説明文字列には、特別な部分文字列、つまり、 説明文を表示するときに現在のキーマップからキーバインディングを探す ことを表すものがあります。 これにより、ユーザーがキーバインディングを変更していても 説明文字列から関連するコマンドのキーを参照できます。 (see Accessing Documentation)。
Emacs Lispでは、説明文字列はその説明対象である関数や変数を介して参照します。
documentation
がその取り出し方を知っている。
variable-documentation
で収められている。
関数documentation-property
がその取り出し方を知っている。
場所を節約するために、あらかじめロード済みの関数や変数
(基本関数や自動ロード対象の関数を含む)に対する説明文は、
Emacs本体にではなく、ファイルemacs/etc/DOC-version
に
収めてあります。
Emacsセッションの最中にバイトコンパイル済みのファイルから
ロードされる関数や変数の説明文字列は、当該ファイルに収めてあります
(see Docs and Compilation)。
Emacs内部のデータ構造では、説明文字列のかわりに、
ファイル内の位置を表す整数かファイル名と整数を含むリストで表します。
関数documentation
やdocumentation-property
は、
この情報を用いて適切なファイルから説明文字列を取り出します。
この処理はユーザーには見えません。
説明文字列の利用に関する情報は、 Helpを参照してください。
ディレクトリemacs/lib-src
には、
ファイルemacs/etc/DOC-version
を美しく印刷するための
コマンドが2つあります。
sorted-doc
とdigest-doc
です。
documentation-property symbol property &optional verbatim | Function |
この関数は、シンボルsymbolの属性リストに
属性propertyで記録されている説明文字列を返す。
必要ならばファイルからテキストを取り出し、
実際のキーバインディングに置き換えるために
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 function &optional verbatim | Function |
この関数は、関数functionの説明文字列を返す。
必要ならばファイルからテキストを取り出す。
続いて、(verbatimがnil ならば)
実際の(現在の)キーバインディングを含んだ値を返すために
substitute-command-keys を実行する。
関数 |
2つの関数documentation
とdocumentation-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 (function (lambda (s) ;; Print description of symbol. (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 (user-variable-p s) "Option " "Variable") (or (documentation-property s 'variable-documentation) "not documented"))))))) sym-list) ;; パターンに一致するシンボルのリストを作る (mapatoms (function (lambda (sym) (if (string-match pattern (symbol-name sym)) (setq sym-list (cons sym sym-list)))))) ;; データを表示する (with-output-to-temp-buffer "*Help*" (mapcar describe-func (sort sym-list 'string<)) (print-help-return-message))))
関数describe-symbols
はapropos
のように動作しますが、
より多くの情報を提供します。
(describe-symbols "goal") ---------- Buffer: *Help* ---------- goal-column Option *Semipermanent goal column for vertical motion, as set by ... 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, 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'. temporary-goal-column Variable Current goal column for vertical motion. It is the column where point was at the start of current run of vertical motion commands. When the `track-eol' feature is doing its job, the value is 9999. ---------- Buffer: *Help* ----------
Snarf-documentation filename | Function |
この関数は、実行可能なEmacsをダンプする直前の
Emacsの初期化処理中にのみ使われる。
ファイルfilenameに格納された説明文字列のファイル内位置を探し出し、
それらの情報を実際の文字列のかわりに
メモリ内の関数定義や変数の属性リストに記録する。
see Building Emacs。
Emacsはファイルfilenameをディレクトリ |
doc-directory | Variable |
この変数は、組み込みであったりあらかじめロード済みの関数や変数の
説明文字列を収めたファイル"DOC-version" を置いた
ディレクトリの名前を保持する。
ほとんどの場合、これは Emacsの古い版では、この目的には |
説明文字列からキー列を参照するときには、
現在の活性なキーバインディングを使うべきです。
これは以下に述べる特別なテキスト列でできます。
普通の方法で説明文字列を参照すると、
これらの特別な列は現在のキーバインディング情報で置き換えられます。
置き換えはsubstitute-command-keys
を呼び出して行います。
読者自身がこの関数を使うこともできます。
特別な列とその意味を以下にあげます。
\[command]
M-x command
を表す。
\{mapvar}
describe-bindings
を使って作成する。
\<mapvar>
\[command]
に
対するキーマップとしてmapvarの値を指定する。
\=
\=
は破棄する。
したがって、\=\[
は\[
という出力になり、
\=\=
は\=
という出力になる。
注意:
Emacs Lispでは、文字列内の\
は、2つ続けて書くこと。
substitute-command-keys string | Function |
この関数は、stringから上記の特別な列を探し、 それらをそれらが意味するものに置き換え、結果を文字列で返す。 これにより、説明文の表示では、 ユーザー独自のカスタマイズしたキーバインディングを実際に参照できる。 |
特別な列の例を示します。
(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 " (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."
これらの関数は、イベント、キー列、文字をテキスト表記に変換します。 これらの表記は、メッセージに文字やキー列をテキストとして含めるのに有用です。 というのは、非印字文字や白文字を印字文字の列に変換するからです。 白文字でない印字文字は文字そのもので表記します。
key-description sequence | Function |
この関数は、sequenceの入力イベントに対する
Emacsの標準表記を含んだ文字列を返す。
引数sequenceは、文字列、ベクトル、リストである。
正しいイベントについて詳しくはsee Input Events。
下記のsingle-key-description の例を参照。
|
single-key-description event | Function |
この関数は、eventをキーボード入力向けのEmacsの標準表記で
表した文字列を返す。
普通の印字文字はそのまま現れるが、
コントロール文字はC- で始まる文字列に、
メタ文字はM- で始まる文字列に、
空白、タブなどは、SPC 、TAB などとなる。
ファンクションキーのシンボルはそれ自身が現れる。
リストであるイベントはリストのCARのシンボルの名前が現れる。
(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 'C-mouse-1) => "C-mouse-1" |
text-char-description character | Function |
この関数は、characterを
テキストに現れる文字向けのEmacsの標準表記で表した文字列を返す。
single-key-description に似ているが、
コントロール文字は、始めにカレットを付けて表現する点が異なる
(Emacsのバッファでは、コントロールは普通このように表示される)。
(text-char-description ?\C-c) => "^C" (text-char-description ?\M-m) => "M-m" (text-char-description ?\C-\M-m) => "M-^M" |
read-kbd-macro string | Function |
この関数は、キーボードマクロの処理に主に使われるが、
key-description に対するおおまかな逆変換にも使える。
空白で区切ったキーの表記を収めた文字列で、この関数を呼び出す。
対応するイベントを収めた文字列かベクトルを返す。
(指定したイベントに依存して、正しい単一のキー列であったりなかったりする。
see Keymap Terminology。)
|
Emacsにはさまざまオンラインヘルプ関数があり、 それらはすべてプレフィックスC-hのサブコマンドとして使えます。 それらについて詳しくは、 Helpを参照してください。 ここでは、同じ情報を得るプログラムレベルのインターフェイスを説明します。
apropos regexp &optional do-all | コマンド |
この関数は、正規表現regexpに一致する名前を持つすべてのシンボルを探し、
それらのリストを返す(see Regular Expressions)。
さらに、バッファ*Help* に、各シンボルについて、
シンボルとその説明文字列の始めの部分から取り出した1行の説明文を表示する。
do-allが つぎの例では、 (apropos "exec") => (Buffer-menu-execute command-execute exec-directory exec-path execute-extended-command execute-kbd-macro executing-kbd-macro executing-macro) |
help-map | Variable |
この変数の値は、ヘルプキーC-hに続く文字向けのローカルキーマップである。 |
help-command | プレフィックスコマンド |
このシンボルは関数ではない。
その関数定義セルは、help-map として知られるキーマップを保持している。
help.el での定義はつぎのとおりである。
(define-key global-map "\C-h" 'help-command) (fset 'help-command help-map) |
print-help-return-message &optional function | Function |
この関数は、ヘルプコマンドのあとでそれ以前のウィンドウの状態に復元する
方法を述べた文字列を作成する。
メッセージを作成後、functionがnil 以外であれば、
メッセージをfunctionに適用する。
さもなければ、メッセージをエコー領域に表示するためにmessage を呼び出す。
この関数は、スペシャルフォーム |
help-char | Variable |
この変数の値はヘルプ文字、つまり、
Emacsがヘルプを意味すると認識する文字である。
デフォルトでは、その値はC-hを表す8である。
help-form がnil 以外のLisp式であると、
Emacsがこの文字を読み取るとその式を評価し、
その結果が文字列であれば結果をウィンドウに表示する。
通常、 ヘルプ文字は、プレフィックスキーのうしろでも特別である。
プレフィックスのサブコマンドとしてのバインディングがないと、
プレフィックスキーのすべてのサブコマンドの一覧を表示する
|
help-event-list | Variable |
この変数の値は、別の『ヘルプ文字』として動作するイベント型のリストである。
これらのイベントはhelp-char で指定されたイベントと
まったく同様に扱われる。
|
help-form | Variable |
この変数がnil 以外であると、その値は、
help-char を読むたびに評価すべきフォームである。
フォームを評価すると文字列を生成すれば、その文字列が表示される。
ミニバッファに入ると、この変数は |
prefix-help-command | Variable |
この変数はプレフィックスキーに対するヘルプを表示する関数を保持する。
ユーザーがプレフィックスキーに続けてヘルプ文字や
当該プレフィックスのあとではバインディングを持たない文字を打つと
その関数が呼ばれる。
この変数のデフォルト値はdescribe-prefix-bindings である。
|
describe-prefix-bindings | Function |
この関数は、もっとも最近のキー列のプレフィックスキーの
すべてのサブコマンドの一覧を表示するためにdescribe-bindings を呼び出す。
プレフィックスの説明には、当該キー列の最後のイベント以外のすべてが含まれる。
(最後のイベントはヘルプ文字であると仮定する。)
|
つぎの2つの関数は、『エレクトリック』モードのように
制御を放棄せずにヘルプを提供したいモードのためです。
それらの名前は、普通のヘルプ関数と区別するためにHelper
で始まります。
Helper-describe-bindings | コマンド |
このコマンドは、ローカルキーマップとグローバルキーマップの両者の
すべてのキーバインディングの一覧を収めたヘルプバッファを表示した
ウィンドウをポップアップする。
describe-bindings を呼び出すことで動作する。
|
Helper-help | コマンド |
このコマンドはカレントモードについてのヘルプを提供する。
ミニバッファにおいてHelp (Type ? for further options) のメッセージで
ユーザーに問い合わせ、キーバインディングの意味やモードの目的を
調べることを補佐する。
nil を返す。
このコマンドは、キーマップ |
data-directory | Variable |
この変数は、Emacsとともに配布された特定の説明文やテキストファイルを
Emacsが探すためのディレクトリの名前を保持する。
Emacsの古い版では、この目的にはexec-directory を用いていた。
|
make-help-screen fname help-line help-text help-map | Macro |
このマクロは、サブコマンドの一覧を表示するプレフィックスキーのように
動作するfnameという名前のコマンドのヘルプを定義する。
起動されると、fnameはウィンドウにhelp-textを表示し、 help-mapに従ってキー列を読み実行する。 文字列help-textは、help-mapが提供する バインディングを記述するべきである。 コマンドfnameは、help-textの表示をスクロールすることで、 それ自身では少数のイベントを扱うように定義される。 fnameがそれらの特殊イベントの1つを読み取ると、 スクロールしてつぎのイベントを読み取る。 読み取ったイベントが、扱えるものでなく、 help-mapにバインディングがあれば、 当該キーのバインディングを実行して戻る。 help-lineは、help-map内の選択項目を1行にまとめたものであること。
Emacsの現在の版では、この引数はオプション このマクロは、C-h C-hのバインディングである
コマンド |
three-step-help | User Option |
この変数がnil 以外であると、
make-help-screen で定義されたコマンドは、
まず文字列help-lineをエコー領域に表示し、
ユーザーがヘルプ文字を再度打った場合にのみより長い文字列を表示する。
|
Emacsでは、ファイルやディレクトリを 探したり、作成したり、眺めたり、保存したり、その他のことをできます。 本章では、Emacs Lispのファイル関連の関数のほとんどについて説明しますが、 他の一部はBuffersで、バックアップや自動保存に関することは Backups and Auto-Savingで説明します。
ファイル関数の多くは、ファイル名の引数を1つないし複数個取ります。
ファイル名は実際には文字列です。
これらのほとんどの関数では、expand-file-name
を呼び出して
ファイル名引数を展開することで~
や
(../
を含む)相対ファイル名を正しく処理します。
これらの関数は、$HOME
などの環境変数置換は認識しません。
See File Name Expansion。
ファイルを訪問するとは、ファイルをバッファに読み込むことです。 いったんこうすると、バッファはそのファイルを 訪問している(visiting)といい、 そのファイルをバッファの『訪問しているファイル』と呼びます。
ファイルとバッファは2つの異なるものです。 ファイルは、コンピュータ内に(読者が削除しない限り)恒久的に 記録されている情報です。 一方、バッファはEmacs内部にある情報であり、 編集セッションを終了する(あるいはバッファを削除する)と消えてしまいます。 通常、バッファにはファイルからコピーした情報があります。 つまり、バッファはそのファイルを訪問しているのです。 読者は、バッファ内のコピーを編集コマンドで修正するのです。 バッファに対するそのような変更では、ファイルは変更しません。 したがって、変更を恒久的なものにするには、 読者はバッファを保存(save)する、つまり、 バッファの変更した内容をファイルにコピーし戻す必要があります。
ファイルとバッファの区別にも関わらず、 バッファを意味してファイルといったり、その逆のいい方をしばしばします。 もちろん、『同じ名前のファイルにただちに保存するつもりでバッファを 編集している』とはいわずに『ファイルを編集している』といいます。 しばしば、人間は明確に区別する必要はありません。 しかし、コンピュータプログラムを扱ううえでは、 区別を心得ておくことがよいのです。
本節では、ファイルを訪問するために通常使う関数について述べます。
歴史的な理由で、これらの関数はvisit-
でなくfind-
という
名前で始まります。
バッファで訪問したファイルの名前を参照するための関数や変数、ならびに、
訪問したファイルの名前で既存バッファを探すための関数や変数については、
See Buffer File Name。
Lispプログラムにおいて、ファイルの内容を変更せずにその内容を調べたいときには、
もっとも速い方法は一時的なバッファでinsert-file-contents
を
使うことです。
ファイルを訪問する必要はありませんし、それには余計に時間がかかります。
See Reading from Files。
find-file filename | コマンド |
このコマンドはファイルfilenameを訪問したバッファを選択する。
そのようなバッファが既存ならば当該バッファを使う。
さもなければ、新たなバッファを作成してファイルを読み込む。
当該バッファを返す。
関数 (switch-to-buffer (find-file-noselect filename)) (Displaying Buffersの
|
find-file-noselect filename &optional nowarn rawfile | Function |
この関数は、ファイルを訪問するすべての関数の基である。
ファイルfilenameを訪問した/するバッファを探し/作成し、
当該バッファを返す。
そのようなバッファが既存ならば当該バッファを使う。
さもなければ、新たなバッファを作成してファイルを読み込む。
必要に応じて、バッファをカレントバッファにしたり
ウィンドウに表示できるが、この関数はそこまでは行わない。
省略可能な引数nowarnが 関数 省略可能な引数rawfileが 関数 (find-file-noselect "/etc/fstab") => #<buffer fstab> |
find-file-other-window filename | コマンド |
このコマンドは、選択しているウィンドウ以外のウィンドウにおいて、
ファイルfilenameを訪問したバッファを選択する。
別の既存ウィンドウを使うか、ウィンドウを分割する。
Displaying Buffersを参照。
このコマンドが対話的に呼び出されると、 filenameを問い合わせる。 |
find-file-read-only filename | コマンド |
このコマンドは、find-file のようにファイルfilenameを訪問した
バッファを選択するが、当該バッファは読み出し専用となる。
See Read Only Buffers。
このコマンドが対話的に呼び出されると、 filenameを問い合わせる。 |
view-file filename | コマンド |
このコマンドは、閲覧(view)モードでfilenameを訪問し、
閲覧(view)モードを抜けるとそれ以前のバッファに戻る。
閲覧(view)モードは、ファイルを素早く眺めるためのコマンドを与えるが
テキストの変更は許さないマイナモードである。
閲覧(view)モードに入ると、ノーマルフックview-mode-hook を実行する。
see Hooks。
|
find-file-hooks | Variable |
この変数の値は、ファイルを訪問後に呼び出される関数のリストである。
ファイルにローカル変数指定(があれば)は、
フックを実行するまえに処理される。
フック関数が実行されときには、
ファイルを訪問したバッファはカレントバッファになっている。
この変数はノーマルフックのように動作するが、 改名すべきではないと考えている。 see Hooks。 |
find-file-not-found-hooks | Variable |
この変数の値は、find-file やfind-file-noselect に
存在しないファイルを与えたときに呼び出される関数のリストである。
find-file-noselect は、ファイルが存在しないことがわかると
ただちにこれらの関数を呼び出す。
nil 以外の値が返されるまで、リストに現れる順に呼び出す。
buffer-file-name は設定済みである。
関数の値を使い、しかも、一部の関数だけを呼び出すので、 これはノーマルフックではない。 |
関数find-file-noselect
は、ユーザーのLispコードでも有用な
2つの重要なサブルーティン、create-file-buffer
と
after-find-file
を使います。
本節ではそれらの使い方を説明します。
create-file-buffer filename | Function |
この関数は、filenameを訪問するのに適するように命名した
バッファを作成しそれを返す。
(ディレクトリを除外した)filenameが使用中の名前でなければ、
それを名前とする。
さもなければ、未使用の名前を得るために<2> などの文字列を付加する。
Creating Buffersも参照。
注意: (create-file-buffer "foo") => #<buffer foo> (create-file-buffer "foo") => #<buffer foo<2>> (create-file-buffer "foo") => #<buffer foo<3>> この関数は |
after-find-file &optional error warn | Function |
この関数は、バッファのメジャーモードを設定し、
ローカル変数を解析する(see Auto Major Mode)。
find-file-noselect や
デフォルトの復元処理関数(see Reverting)から呼ばれる。
ディレクトリはあるのにファイルが存在しないために
ファイルの読み込みがエラーになった場合には、
呼び出し側はerrorの値として warnが
|
Emacsでファイルを編集するときには、 ファイルを訪問したバッファを実際には扱っています。 つまり、ファイルの内容はバッファにコピーされ、 そのコピーを編集しているのです。 バッファを変更しても、当該バッファを保存(save)するまで、 つまり、バッファの内容をファイルへコピーするまでは、 ファイルを変更しません。
save-buffer &optional backup-option | コマンド |
この関数は、最後に訪問/保存してからカレントバッファが変更されていれば、
カレントバッファの内容を訪問しているファイルへ保存する。
|
save-some-buffers &optional save-silently-p exiting | コマンド |
このコマンドは、ファイルを訪問している変更されたバッファを保存する。
通常、各バッファについてユーザーに問い合わせる。
しかし、save-silently-pがnil 以外であると、
ユーザーに問い合わせずにファイルを訪問しているバッファをすべて保存する。
省略可能な引数exitingが |
write-file filename | コマンド |
この関数は、カレントバッファをファイルfilenameに保存し、
当該ファイルを訪問しているバッファとし、さらに未変更という印を付ける。
続いて、バッファ名を一意にするために必要ならば<2> のような
文字列を付加して、バッファをfilenameに基づいた名前に改名する。
この処理のほとんどは、set-visited-file-name (see Buffer File Name)
とsave-buffer を呼び出して行う。
|
バッファを保存すると、いくつかのフックを実行します。 また、書式変換(see Format Conversion)を行い、 テキスト属性を『注記』(annotations)(see Saving Properties)に 保存することもあります。
write-file-hooks | Variable |
この変数の値は、バッファを訪問しているファイルに書き出すまえに
呼ばれる関数のリストである。
それらの1つがnil 以外を返すと、すでにファイルに書き出したとみなして
残りの関数を呼び出さず、ファイルに書き出すための通常のコードも実行しない。
(or buffer-backed-up (backup-buffer))
この変数をバッファローカルにはしないこと。
バッファ固有のフック関数を指定するには、
かわりに これはノーマルフックではないが、
|
local-write-file-hooks | Variable |
これはwrite-file-hooks のように働くが、
特定のバッファにバッファローカルにするように意図してあり、
ファイル名に関するフックやバッファ内容を得た方法に関する
フックとして使われる。
変数は恒久的にバッファローカルと印が付いているので、 メジャーモードを変更してもバッファローカルな値は変更されない。 これは、『ファイル』の内容を特別な方法で読み込み、 対応した方法でデータを保存するフックを設定するようなパッケージには便利である。 |
write-contents-hooks | Variable |
この変数はwrite-file-hooks のように働くが、
ファイルの場所に関するフックではなく、
ファイルの内容に関するフックであると意図されている。
そのようなフックは、この変数のバッファローカルな束縛として
メジャーモードが通常設定する。
この変数に設定すると自動的にバッファローカルになる。
このフックに要素を追加するために |
after-save-hook | Variable |
このノーマルフックは、バッファを訪問したファイルに 保存し終えてから実行される。 このフックの用途の1つは高速ロック(fast-lock)モードである。 このフックを使って強調表示情報をキャッシュファイルに保存する。 |
file-precious-flag | Variable |
この変数がnil 以外ならば、
save-buffer は保存処理中の入出力エラーに備えて対処する。
つまり、目的の名前のファイルにではなく一時的な名前の新規ファイルに書き出し、
エラーがないことを確認してから目的の名前に改名する。
これにより、不正なファイルに起因する問題からディスク容量の不足といった
問題を回避できる。
副作用として、バックアップも必然的にコピーして行う。 see Rename or Copy。 それと同時に、大事な(precious)ファイルとして保存すると、 読者が保存したファイルと別のファイル名とのあいだの ハードリンクをつねに切ってしまう。 特定のバッファではこの変数に |
require-final-newline | User Option |
この変数は、改行で終らないファイルを書き出すかどうかを決定する。
この変数の値がt であると、save-buffer は、
保存するバッファが改行で終っていないと黙ってファイルの末尾に改行を追加する。
この変数の値がt ではないnil 以外であると、
save-buffer は、必要な場面では
改行を追加するかどうかユーザーに問い合わせる。
この変数の値が |
関数set-visited-file-name
(see Buffer File Name)も
参照してください。
関数insert-file-contents
を使って
ディスクからファイルをバッファへコピーできます。
ユーザーレベルのコマンドinsert-file
はマークを設定するので
Lispプログラムでは使わないでください。
insert-file-contents filename &optional visit beg end replace | Function |
この関数は、ファイルfilenameの内容をカレントバッファの
ポイントのうしろに挿入する。
絶対ファイル名と挿入したデータの長さから成るリストを返す。
filenameが読み込めるファイルの名前でないと、エラーを通知する。
関数 visitが begとendが (insert-file-contents filename nil 0 500) はファイルの最初の500文字を挿入する。 引数replaceが replaceとvisitが |
insert-file-contents-literally filename &optional visit beg end replace | Function |
この関数はinsert-file-contents のように動作するが、
書式を変換しない(see Format Conversion)、
文字コードを変換しない(see Coding Systems)、
find-file-hooks を実行しない、自動的に解凍しないなどが異なる。
|
別のプログラムが読めるようにファイル名を別のプロセスに渡すには、
関数file-local-copy
を使います。
Magic File Namesを参照してください。
関数append-to-file
やwrite-region
を使って、
バッファの内容やその一部をディスク上のファイルへ直接書き出せます。
訪問しているファイルには、これらの関数で書き出さないでください。
訪問の機構に混乱をきたすことがあります。
append-to-file start end filename | コマンド |
この関数は、カレントバッファのstartからendで
区切られる領域の内容をファイルfilenameの末尾に追加する。
当該ファイルが存在しなければ作成する。
この関数はnil を返す。
書き込めないファイルをfilenameに指定したり、 ファイルを作成できないディレクトリ上の存在しないファイルを filenameに指定するとエラーを通知する。 |
write-region start end filename &optional append visit confirm | コマンド |
この関数は、カレントバッファのstartからendで
区切られる領域の内容をfilenameで指定したファイルに書き出す。
startが文字列であると、
appendが confirmが visitが visitが文字列であると、訪問するファイルの名前を指定する。
このようにして、データを1つのファイル(filename)に書き出す一方で、
バッファは別のファイル(visit)を訪問していると設定できる。
引数visitはエコー領域のメッセージに使われ、
ファイルのロックにも使われる。
visitは 関数 通常、 |
with-temp-file file body... | Macro |
マクロwith-temp-file は、一時的なバッファをカレントバッファとして
フォームbodyを評価する。
そして最後にバッファの内容をファイルfileに書き出す。
終了すると一時的なバッファを削除し、
フォームwith-temp-file のまえにカレントバッファであったバッファに戻る。
bodyの最後のフォームの値を返す。
|
2人のユーザーが同時に同じファイルを編集すると、互いに干渉し合います。 Emacsは、ファイルが変更されるとファイルロック(file lock)を 記録することで、このような状況が発生しないように努めます。 すると、Emacsは別のEmacsがロックしているファイルを訪問した バッファを変更しようとする最初の試みを検出でき、 ユーザーにどうすべきかを問い合わせます。
複数の計算機がファイルシステムを共有している場合には、 ファイルロックには完全な信頼性はありません。 ファイルロックが働かないと、 2人のユーザーが同時に変更する可能性がありますが、 それでも、Emacsは2番目に保存したユーザーに警告できます。 また、ディスク上で変更されたファイルを訪問しているバッファの変更を 検出することで、同時編集のある場面を捕捉できます。 Modification Timeを参照してください。
file-locked-p filename | Function |
ファイルfilenameがロックされていなければ、この関数はnil を返す。
このEmacsプロセスがロックしているときにはt を返す。
他のEmacsがロックしている場合には、ロックしているユーザーの名前を返す。
(file-locked-p "foo") => nil |
lock-buffer &optional filename | Function |
この関数は、カレントバッファが変更されていれば ファイルfilenameをロックする。 引数filenameのデフォルトは、 カレントバッファで訪問しているファイルである。 カレントバッファがファイルを訪問していなかったり、 未変更ならばなにもしない。 |
unlock-buffer | Function |
この関数は、バッファが変更されていれば、 カレントバッファで訪問しているファイルのロックを解除する。 バッファが未変更ならばファイルをロックしていないはずであり、 この関数はなにもしない。 カレントバッファがファイルを訪問していなければ、 やはりなにもしない。 |
ask-user-about-lock file other-user | Function |
この関数は、別のユーザーother-userがロックしている
ファイルfileをユーザーが変更しようとしたときに呼び出される。
この関数のデフォルトの定義は、ユーザーになにをすべきか
問い合わせることである。
この関数の戻り値がEmacsのつぎの動作を決定する。
読者は、関数 |
本節に述べる関数はすべて、ファイル名を表す文字列に作用します。
すべての関数の名前は単語file
で始まり、
それらの引数は、特に断らないかぎり、
既存のファイルやディレクトリである必要があります。
これらの関数は、特別な方法でファイル参照のパーミッションを検査します。
file-exists-p filename | Function |
ファイルfilenameが存在すれば、この関数はt を返す。
これは必ずしもファイルを読めることは意味せず、
単にファイルの属性を調べられるだけである。
(UNIXでは、ファイルが存在し、かつ、
それを収めたディレクトリに対する実行パーミッションがあれば、
ファイル自体のパーミッションに関係なくこのようになる。)
ファイルが存在しなかったり、ファイルの属性を探す権限がなければ、
この関数は |
file-readable-p filename | Function |
ファイルfilenameが存在しそれを読むことができるならば、
この関数はt を返す。
さもなければnil を返す。
(file-readable-p "files.texi") => t (file-exists-p "/usr/spool/mqueue") => t (file-readable-p "/usr/spool/mqueue") => nil |
file-executable-p filename | Function |
ファイルfilenameが存在しそれを実行できるならば、
この関数はt を返す。
さもなければnil を返す。
ファイルがディレクトリである場合、実行パーミッションは、
ディレクトリ内のファイルの存在やその属性を検査でき、
それらのファイルのモードが許せばオープンできることを意味する。
|
file-writable-p filename | Function |
ファイルfilenameに書き出したり作成できるならば、
この関数はt を返し、さもなければnil を返す。
ファイルに書き出せるのは、ファイルが存在し書ける場合である。
作成できるのは、ファイルは存在しないが
指定したディレクトリが存在しそのディレクトリに書ける場合である。
以下の3番目の例では、 (file-writable-p "~/foo") => t (file-writable-p "/foo") => nil (file-writable-p "~/no-such-dir/foo") => nil |
file-accessible-directory-p dirname | Function |
ディレクトリdirnameの既存ファイルをオープンするパーミッションがあれば、
この関数はt を返す。
さもなければ(あるいは当該ディレクトリが存在しなければ)nil を返す。
dirnameの値はディレクトリ名である。
例: (file-accessible-directory-p "/foo") => nil から、 |
access-file filename string | Function |
この関数は、ファイルfilenameを読むためにオープンし、
クローズしてからnil を返す。
しかし、オープンに失敗するとstringをエラーメッセージのテキストとした
エラーを通知する。
|
file-ownership-preserved-p filename | Function |
もしファイルfilenameを削除して改めて作成しても
ファイルの所有者が変更されなければ、この関数はt を返す。
|
file-newer-than-file-p filename1 filename2 | Function |
ファイルfilename1がfilename2より新しければ、
この関数はt を返す。
filename1が存在しなければnil を返す。
filename2が存在しなければt を返す。
以下の例で、ファイル (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
|
本節ではさまざまな種類のファイル、つまり、 ディレクトリ、シンボリックリンク、普通のファイルを区別する方法を 説明します。
file-symlink-p filename | Function |
ファイルfilenameがシンボリックリンクであると、
関数file-symlink-p は当該リンクが指すファイルの名前を返す。
これは、テキストファイル、ディレクトリ、別のシンボリックリンク、
存在しないファイルの名前のいずれかである。
ファイルfilenameがシンボリックリンクでない
(あるいは当該ファイルが存在しない)場合、
(file-symlink-p "foo") => nil (file-symlink-p "sym-link") => "foo" (file-symlink-p "sym-link2") => "sym-link" (file-symlink-p "/bin") => "/pub/bin" |
file-directory-p filename | Function |
ファイルfilenameが既存ディレクトリの名前であるとt を返し、
さもなければnil を返す。
(file-directory-p "~rms") => t (file-directory-p "~rms/lewis/files.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 |
file-regular-p filename | Function |
ファイルfilenameが存在しそれが普通のファイル
(ディレクトリでもシンボリックリンクでも名前付きパイプでも
端末でもその他の入出力装置でもない)であれば、
この関数はt を返す。
|
ファイルの実名(truename)とは、
シンボリックリンクをすべて辿り尽くしてから、
要素として現れる.
や..
を簡略化して得られる名前です。
厳密にいえば、ファイルが一意の実名を持つ必要はありません。
ファイルの異なる実名の個数は、当該ファイルに対するハードリンクの個数に
等しいのです。
それでも、実名はシンボリックリンクによる名前の変動を取り除くため、
実名は有用です。
file-truename filename | Function |
関数file-truename はファイルfilenameの実名を返す。
これはシンボリックリンクをすべて辿り尽くして得られる名前である。
引数は絶対ファイル名であること。
|
関連情報については、See Buffer File Name。
本節では、ファイルの内容以外の詳しい情報を得るための関数を説明します。 この情報には、参照パーミッションを制御するモードビット、 所有者とグループの番号、名前の個数、iノード番号、サイズ、 参照時刻と更新時刻が含まれます。
file-modes filename | Function |
この関数はfilenameのモードビットを整数で返す。
モードビットはファイルのパーミッションとも呼ばれ、
UNIX流の参照制御を指定する。
最下位ビットが1であると、当該ファイルはすべてのユーザーが実行でき、
2番目の下位ビットが1であると、当該ファイルはすべてのユーザーが書ける
といった具合である。
戻り値の最大値は4095(8進数7777)であり、これは、 だれもが読み/書き/実行でき、 所有者とグループの両者にビットSUIDが設定してあり、 スティッキービットも設定されていることを意味する。 (file-modes "~/junk/diffs") => 492 ; 10進整数 (format "%o" 492) => "754" ; 8進数に変換 (set-file-modes "~/junk/diffs" 438) => nil (format "%o" 438) => "666" ; 8進数に変換 % ls -l diffs -rw-rw-rw- 1 lewis 0 3063 Oct 30 16:00 diffs |
file-nlinks filename | Function |
この関数は、ファイルfilenameの
名前(つまりハードリンク)の個数を返す。
ファイルが存在しなければ、この関数はnil を返す。
シンボリックリンクはそれが指すファイルの名前とはみなさないので、
シンボリックリンクはこの関数には効果を持たない。
% ls -l foo* -rw-rw-rw- 2 rms 4 Aug 19 01:27 foo -rw-rw-rw- 2 rms 4 Aug 19 01:27 foo1 (file-nlinks "foo") => 2 (file-nlinks "doesnt-exist") => nil |
file-attributes filename | Function |
この関数はファイルfilenameの属性のリストを返す。
オープンできないファイルを指定するとnil を返す。
リストの要素は順につぎのとおりである。
たとえば、 (file-attributes "files.texi") => (nil 1 2235 75 (8489 20284) (8489 20284) (8489 20285) 14906 "-rw-rw-rw-" nil 129500 -32252) この意味はつぎのとおりである。
|
本節の関数は、ファイルを改名/コピー/削除/リンクしたり、 ファイルのモードを設定するためのものです。
引数newnameをとる関数では、 newnameで指定したファイルが既存の場合、 関数の動作は引数ok-if-already-existsの値に依存します。
nil
であると、
エラーfile-already-exists
を通知する。
add-name-to-file oldname newname &optional ok-if-already-exists | Function |
この関数は、oldnameで指定したファイルに
追加の名前newnameを与える。
つまり、newnameはoldnameへの新たな『ハードリンク』になる。
つぎの例では、2つのファイル % ls -li fo* 81908 -rw-rw-rw- 1 rms 29 Aug 18 20:32 foo 84302 -rw-rw-rw- 1 rms 24 Aug 18 20:31 foo3
(add-name-to-file "foo" "foo2") => nil % ls -li fo* 81908 -rw-rw-rw- 2 rms 29 Aug 18 20:32 foo 81908 -rw-rw-rw- 2 rms 29 Aug 18 20:32 foo2 84302 -rw-rw-rw- 1 rms 24 Aug 18 20:31 foo3 最後につぎの式を評価し (add-name-to-file "foo" "foo3" t) ファイル一覧を表示し直す。
今度は、1つのファイルに3つの名前 (add-name-to-file "foo1" "foo3") => nil % ls -li fo* 81908 -rw-rw-rw- 3 rms 29 Aug 18 20:32 foo 81908 -rw-rw-rw- 3 rms 29 Aug 18 20:32 foo2 81908 -rw-rw-rw- 3 rms 29 Aug 18 20:32 foo3 1つのファイルに複数の名前を許さないオペレーティングシステムでは、
この関数は意味がない。
File Attributesの |
rename-file filename newname &optional ok-if-already-exists | コマンド |
このコマンドは、ファイルfilenameをnewnameと改名する。
filenameにfilename以外の名前があれば、
それらの名前は存在し続ける。
実際、 対話的に呼び出されると、この関数は ミニバッファでfilenameとnewnameを聞く。 また、newnameが既存であると確認を求める。 |
copy-file oldname newname &optional ok-if-exists time | コマンド |
このコマンドはファイルoldnameをnewnameへコピーする。
oldnameが存在しないとエラーを通知する。
timeが 対話的に呼び出されると、この関数は ミニバッファでoldnameとnewnameを聞く。 また、newnameが既存であると確認を求める。 |
delete-file filename | コマンド |
このコマンドは、シェルコマンドrm filename と同様に
ファイルfilenameを削除する。
ファイルに複数の名前があると、他の名前では存在し続ける。
ファイルが存在しなかったり削除できないと、
エラー |
make-symbolic-link filename newname &optional ok-if-exists | コマンド |
このコマンドは、filenameに対するシンボリックリンクnewnameを
作成する。
これはシェルコマンドln -s filename newname と同じである。
対話的に呼び出されると、この関数は ミニバッファでfilenameとnewnameを聞く。 また、newnameが既存であると確認を求める。 |
define-logical-name name string | Function |
この関数は論理名nameに値stringを定義する。 VMSでのみ使える。 |
set-file-modes filename mode | Function |
この関数はfilenameのモードビットを mode(整数であること)と設定する。 modeの下位12ビットのみを使う。 |
set-default-file-modes mode | Function |
この関数は、Emacsやそのサブプロセスが作成する新規ファイルの
デフォルトのファイルモードを設定する。
Emacsが作成する各ファイルは最初このモードになる。
UNIXでは、デフォルトのモードは『umask』の値の1の補数である。
引数modeは整数であること。 ほとんどのシステムでは、modeの下位9ビットのみが意味を持つ。 既存ファイルの変更を保存することはファイルの作成とはみなさないため、 ファイルのモードは変わらず、デフォルトのファイルモードを使わない。 |
default-file-modes | Function |
この関数は、現在のデフォルトのファイルモードの値を返す。 |
MS-DOSでは、『実行可能』ファイルモードビットのようなものはありません。
そのためEmacsは、.com
、.bat
、.exe
のいずれかで
終る名前のファイルを実行可能であるとみなします。
これは、file-modes
やfile-attributes
が返す値に反映されます。
他の場面と同様にEmacsでは、一般にファイルはその名前で参照します。 Emacsではファイル名は文字列で表します。 ファイルを操作する関数はすべてファイル名引数を仮定します。
ファイル自体の操作に加えて、Emacs Lispプログラムは ファイルの名前そのものを操作する必要があります。 つまり、ファイル名を分解したり、関連するファイル名を作成するために その一部を使います。 本節ではファイル名を操作する方法を説明します。
本節の関数は実際にはファイルを参照しませんから、 既存のファイルやディレクトリを表さないファイル名を操作できます。
VMSでは、これらの関数はすべて、VMSのファイル名構文と UNIXの構文の両方を理解します。 つまり、標準LispライブラリはUNIX構文でファイル名を指定でき、 変更せずにVMS上で正しく動作します。 MS-DOSやMS-Windowsでは、これらの関数は、 UNIX構文に加えてMS-DOSやMS-Windowsのファイル名構文を理解します。
オペレーティングシステムは、一連のファイルをディレクトリにまとめます。 ファイルを指定するには、ディレクトリと当該ディレクトリ内のファイルの名前を 指定する必要があります。 そのためEmacsは、ファイル名には2つの部分、 ディレクトリ名(directory name)部分と 非ディレクトリ名(nondirectory name)部分 (つまりディレクトリ内のファイル名)があるとみなします。 どちらかの部分は空でもかまいません。 これらの2つの部分を連結するともとのファイル名になります。
UNIXでは、ディレクトリ部分は最後のスラッシュまでを含んだ部分であり、 非ディレクトリ部分は残りの部分です。 VMSの構文規則は複雑です。
ある種の目的のために、非ディレクトリ部分をさらに 名前だけの部分と版番号(version number)に分けます。 UNIXでは、バックアップファイルだけにそれらの名前に版番号があります。 VMSでは各ファイルに版番号がありますが、 ほとんどの場合、Emacsで実際に使うファイル名では版番号を省略します。 そのため、Emacsで版番号が見えるのは多くの場合ディレクトリ一覧です。
file-name-directory filename | Function |
この関数はfilenameのディレクトリ部分
(ディレクトリ部分がなければnil )を返す。
UNIXでは、この関数はスラッシュで終る文字列を返す。
VMSでは、: 、] 、> のいずれかで終る文字列を返す。
(file-name-directory "lewis/foo") ; UNIXの例 => "lewis/" (file-name-directory "foo") ; UNIXの例 => nil (file-name-directory "[X]FOO.TMP") ; VMSの例 => "[X]" |
file-name-nondirectory filename | Function |
この関数はfilenameの非ディレクトリ部分を返す。
(file-name-nondirectory "lewis/foo") => "foo" (file-name-nondirectory "foo") => "foo" ;; つぎの例はVMSでのみ正確である (file-name-nondirectory "[X]FOO.TMP") => "FOO.TMP" |
file-name-sans-versions filename | Function |
この関数は、filenameから版番号、バックアップ版番号、
末尾のティルダをすべて削除したものを返す。
(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" ;; つぎの例はVMSでのみ正確である (file-name-sans-versions "foo;23") => "foo" |
file-name-sans-extension filename | Function |
この関数は、filenameからあれば『拡張子』を除いたものを返す。
ファイル名の拡張子とは、
名前の最後の部分にある. で始まる部分である。
たとえばつぎのとおりである。
(file-name-sans-extension "foo.lose.c") => "foo.lose" (file-name-sans-extension "big.hack/foo") => "big.hack/foo" |
ディレクトリ名(directory name)とはディレクトリの名前です。 ディレクトリはファイルの一種であり、ファイル名を持ちますが、 それはディレクトリ名に関連付けられますが同一ではありません。 (これはUNIXの通常の用語と同じではない。) 同じものに対するこれらの異なる2つの名前は、構文の変換で関連付けます。 UNIXではこれは簡単であり、ディレクトリ名はスラッシュで終りますが、 ファイルとしてのディレクトリの名前にはスラッシュはありません。 VMSでは、関係はより複雑です。
ディレクトリ名とそのファイルとしての名前との違いはわずかですが重大です。 Emacsの変数や関数引数がディレクトリ名と記述されているときには、 ディレクトリのファイルとしての名前は受け付けません。
つぎの2つの関数はディレクトリ名とファイルとしての名前を相互に変換します。
これらは、$HOME
などの環境変数置換や
~
や..
などの構造にはなにも特別なことはしません。
file-name-as-directory filename | Function |
この関数は、オペレーティングシステムが
ディレクトリ名と解釈する表現で表したfilenameの文字列を返す。
UNIXでは、文字列に(最後にスラッシュがなければ)スラッシュを
付加することを意味する。
VMSでは、[X]Y.DIR.1 の形の文字列を[X.Y] の形に変換する。
(file-name-as-directory "~rms/lewis") => "~rms/lewis/" |
directory-file-name dirname | Function |
この関数は、オペレーティングシステムが
ファイルの名前と解釈する表現で表したdirnameの文字列を返す。
UNIXでは、文字列の最後のスラッシュを取り除くことを意味する。
VMSでは、[X.Y] の形の文字列を[X]Y.DIR.1 の形に変換する。
(directory-file-name "~lewis/") => "~lewis" |
シンボリックリンクを介して通常参照されるディレクトリには ディレクトリ名の省略形が有用です。 ユーザーはリンクの名前をディレクトリの『名前』としばしばみなし、 ディレクトリの『本当の』名前を見るのをわずらわしく思うことがあります。 リンク名を『本当の』名前の省略形と定義しておくと、 Emacsはユーザーに省略形を表示します。
directory-abbrev-alist | Variable |
変数directory-abbrev-alist は、
ディレクトリに使う省略形の連想リストを保持する。
各要素は(from . to) の形であり、
ディレクトリ名にfromが現れるとこれをtoに置き換えることを指示する。
文字列fromは実際には正規表現であり、つねに^ で始まること。
関数abbreviate-file-name がこれらの置換を行う。
ファイル ファイルシステム (("^/home/fsf" . "/fsf") ("^/home/gp" . "/gp") ("^/home/gd" . "/gd")) |
ディレクトリ名をその省略形に変換するには、つぎの関数を使います。
abbreviate-file-name dirname | Function |
この関数は、directory-abbrev-alist の省略形を引数に適用し、
ユーザーのホームディレクトリを~ に置き換える。
|
ファイルシステム内のすべてのディレクトリは、
ルートディレクトリから始まる木を形作ります。
ファイル名では、木のルートから始まるすべてのディレクトリ名を指定できて、
これを絶対(absolute)ファイル名と呼びます。
あるいは、デフォルトディレクトリを基準に
木の中でのファイルの位置を指定することもでき、
これを相対(relative)ファイル名と呼びます。
UNIXでは、絶対ファイル名はスラッシュかティルダ(~
)で始まり、
相対ファイル名はそれらでは始まりません。
VMSでの規則は複雑です。
file-name-absolute-p filename | Function |
この関数は、ファイルfilenameが絶対ファイル名であればt を返し、
さもなければnil を返す。
VMS上では、この関数はUNIXの構文とVMSの構文の両方を理解する。
(file-name-absolute-p "~rms/foo") => t (file-name-absolute-p "rms/foo") => nil (file-name-absolute-p "/user/rms/foo") => t |
ファイル名の展開(expansion)とは、
相対ファイル名を絶対ファイル名に変換することです。
これはデフォルトディレクトリを基準に行うので、
展開すべきファイル名に加えて、デフォルトディレクトリの名前も
指定する必要があります。
また、展開では、./
やname/../
のような冗長部分を
取り除いてファイル名を単純にします。
expand-file-name filename &optional directory | Function |
この関数は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" (expand-file-name "$HOME/foo") => "/xcssun/users/rms/lewis/$HOME/foo"
(expand-file-name "bar/../foo") => "/xcssun/users/rms/lewis/foo"
|
file-relative-name filename directory | Function |
この関数は展開の逆操作を行う。
つまり、directoryを基準に解釈すると
filenameと等価になる相対名を返す。
絶対ファイル名が装置名で始まるシステムもある。
そのようなシステムでは、directoryとfilenameが
2つの異なる装置名で始まると、
filenameに等価なdirectoryを基準にした相対名はない。
そのような場合、 (file-relative-name "/foo/bar" "/foo/") => "bar" (file-relative-name "/foo/bar" "/hack/") => "/foo/bar" |
default-directory | Variable |
このバッファローカルな変数の値は、
カレントバッファのデフォルトディレクトリである。
これは絶対ディレクトリ名であること。
~ で始まってもよい。
この変数は各バッファにおいてバッファローカルである。
UNIXでは、この値はつねにスラッシュで終る文字列である。 default-directory => "/user/lewis/manual/" |
substitute-in-file-name filename | Function |
この関数は、filename内の環境変数の参照を
環境変数の値で置き換える。
UNIXのシェルの構文規則に従って、
$ は環境変数の値に置換するための接頭辞である。
環境変数名は、 ここでは、環境変数 (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"
;;
VMSでは、 |
一時的なファイルに書く必要があるプログラムもあります。 そのようなファイル向けの名前を作る通常の方法はつぎのとおりです。
(make-temp-name (expand-file-name name-of-application temporary-file-directory))
make-temp-name
の仕事は、
異なる2人のユーザーや異なる2つのジョブがまったく同じファイル名を
使わないようにすることです。
この例では、変数temporary-file-directory
を使って
一時的なファイルを置く場所を決めています。
すべてのEmacs Lispプログラムでは、
すべての一時的なファイル向けのディレクトリを指定する
一意な方法をユーザーに提供するために、
この目的にはtemporary-file-directory
を使うべきです。
make-temp-name string | Function |
この関数は、一意なファイル名として使える文字列を生成する。
名前はstringで始まり、各Emacsジョブごとに異なる数を含む。
(make-temp-name "/tmp/foo") => "/tmp/foo232J6v" 同じEmacsで動作している異なるライブラリのあいだで衝突しないように、
|
temporary-file-directory | Variable |
この変数は、一時的なファイルを作成するためのディレクトリ名を指定する。
その値はディレクトリ名(see Directory Names)であるべきだが、
Lispプログラムにとっては、
その値がディレクトリのファイルとしての名前であっても処理できるほうがよい。
この値をexpand-file-name の第2引数に使うと、
そのようにできる。
デフォルト値は、読者のオペレーティングシステムにおいて
合理的な方法で決定される。
GNUとUNIXシステムでは、環境変数 読者が一時的なファイル名を選ぶために |
本節では、ファイル名の補完向けの低レベルのサブルーティンについて述べます。 他の補完関数については、Completionを参照してください。
file-name-all-completions partial-filename directory | Function |
この関数は、ディレクトリdirectoryにおいて
partial-filenameで始まる名前のファイルに対する
すべての補完候補から成るリストを返す。
候補の順番はディレクトリ内でのファイルの順番であり、
それは予測できず有用な情報はなにもない。
引数partial-filenameは、ディレクトリ部分やスラッシュを いっさい含まないファイル名であること。 directoryが絶対名でないと、 カレントバッファのデフォルトディレクトリをdirectoryのまえに補う。 つぎの例で、カレントデフォルトディレクトリは (file-name-all-completions "f" "") => ("foo" "file~" "file.c.~2~" "file.c.~1~" "file.c") (file-name-all-completions "fo" "") => ("foo") |
file-name-completion filename directory | Function |
この関数は、ディレクトリdirectoryにおいてファイル名filenameを
補完する。
ディレクトリdirectoryにおいてfilenameで始まる
すべてのファイル名に共通な最長の文字列を返す。
filenameで始まるものがたった1つであり完全に一致すると、
この関数は つぎの例で、カレントデフォルトディレクトリには
(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 |
completion-ignored-extensions | User Option |
file-name-completion は、このリスト内のいずれかの文字列で終る
名前のファイルを通常無視する。
補完候補すべてがこれらの接頭辞の1つで終る場合や、
補完候補すべてを含んだバッファが表示されている場合には無視しない。
典型的な値はつぎのとおりである。 completion-ignored-extensions => (".o" ".elc" "~" ".dvi") |
Lispプログラムで使われるほとんどのファイル名は、
ユーザーが入力したものです。
しかし、Lispプログラムでは、
特定目的の標準ファイル名を指定する必要がある場合があります。
典型的には、各ユーザーごとのカスタマイズ情報を保持するものです。
たとえば、省略形の定義は(デフォルトでは)
ファイル~/.abbrev_defs
に保存されます。
パッケージcompletion
は、
補完情報をファイル~/.completions
に保存します。
これらは、Emacsで特定目的に使われる多くの標準ファイル名のうちの2つです。
さまざまなのオペレーティングシステムには、
正しいファイル名やユーザーのプロフィールデータに使うファイル名に
独自の慣習があります。
標準ファイル名を使用するファイルを読み込むLispプログラムでは、
各システムごとに当該システムに適したファイル名を使うべきです。
関数convert-standard-filename
は、これを簡単にします。
convert-standard-filename filename | Function |
この関数は、ファイル名filenameを使用しているオペレーティングシステム の慣習に従うように変換し、新たな文字列として結果を返す。 |
Lispプログラムにおいて標準ファイル名を指定する推奨方法は、
GNUとUNIXシステムの慣習に従った名前を選ぶことです。
つまり、ピリオドで始まる非ディレクトリ部分を選び、
それを直接使うかわりにconvert-standard-filename
に渡します。
パッケージcompletion
からの例をつぎに示します。
(defvar save-completions-file-name (convert-standard-filename "~/.completions") "*The file name to save completions to.")
GNUとUNIXシステム、および、他のいくつかのシステムでは、
convert-standard-filename
は引数を未変更で返します。
別のシステムでは、システムの慣習に従うように名前を変更します。
たとえば、MS-DOSではこの関数は、先頭の.
を_
に、
.
がどこにもなければ名前の途中の_
を.
に、
8文字目のうしろに.
がなければ.
を挿入し、
.
以降の3文字よりうしろを切り詰めるなどを行います。
(これ以外にも変更する。)
したがって、.abbrev_defs
は_abbrev.def
となり、
.completions
は_complet.ion
となります。
ディレクトリは、さまざまな名前で入れた別のファイルを 収めているファイルの一種です。 ディレクトリは、ファイルシステムの機能です。
Emacsは、ディレクトリ内のファイル名をLispのリストとして一覧にしたり、
シェルコマンドls
を使ってバッファに名前を表示できます。
後者の場合、コマンドls
に渡したオプションに応じて、
各ファイルに関する情報も表示できます。
directory-files directory &optional full-name match-regexp nosort | Function |
この関数は、ディレクトリdirectory内の
ファイルの名前から成るリストを返す。
デフォルトでは、リストはアルファベット順になる。
full-nameが match-regexpが nosortが (directory-files "~lewis") => ("#foo#" "#foo.el#" "." ".." "dired-mods.el" "files.texi" "files.texi.~1~") directoryが読めないディレクトリの名前であるとエラーを通知する。 |
file-name-all-versions file dirname | Function |
この関数は、ディレクトリdirname内のfileという名前の ファイルのすべての版から成るリストを返す。 |
insert-directory file switches &optional wildcard full-directory-p | Function |
この関数は、ls にswitchesを渡して表示した
ディレクトリfileの一覧を(カレントバッファに)挿入する。
ポイントは挿入したテキストのうしろに置かれる。
引数fileは、ディレクトリ名であるか
ワイルドカードを含んだファイル指定である。
wildcardが full-directory-pが この関数は、変数 |
insert-directory-program | Variable |
この変数の値は、関数insert-directory で
ディレクトリ一覧を生成するために実行するプログラムである。
|
Emacs Lispのほとんどのファイル操作関数は、
ディレクトリであるファイルに使うとエラーになります。
たとえば、delete-file
ではディレクトリを削除できません。
これらの特別な関数はディレクトリを作成したり削除するためのものです。
make-directory dirname | Function |
この関数はdirnameという名前のディレクトリを作る。 |
delete-directory dirname | Function |
この関数は、ディレクトリdirnameを削除する。
関数delete-file は、ディレクトリであるファイルには使えない。
ディレクトリにはdelete-directory を使う必要がある。
ディレクトリ内にファイルがあると、delete-directory は
エラーを通知する。
|
特定のファイル名を特別に扱うことができます。 これをそれらの名前をマジック(magic)にするといいます。 この機能の主な用途はリモートファイル名 (see Remote Files) を実装することです。
マジックファイル名の種類を定義するには、 名前のクラス(正規表現に一致するものすべて)を定義する正規表現と、 それに一致するファイルに対する Emacsの基本ファイル操作を実装するハンドラを指定する必要があります。
変数file-name-handler-alist
は、
ハンドラと当該ハンドラの適用を決定する正規表現からなるリストを保持します。
各要素の形はつぎのとおりです。
(regexp . handler)
Emacsのすべてのファイル操作基本関数とファイル名変換基本関数は、
指定された名前をfile-name-handler-alist
に対して検査します。
ファイル名がregexpに一致すると、
基本関数はhandlerを呼び出して当該ファイルを処理します。
handlerに与える最初の引数は基本関数の名前です。 残りの引数は当該操作に渡されるべき引数です。 (それらの引数の最初のものは典型的にはファイル名自身である。) たとえば、つぎのようにした場合、
(file-exists-p filename)
filenameにハンドラhandlerがあると、 handlerはつぎのように呼び出されます。
(funcall handler 'file-exists-p filename)
つぎは、マジックファイル名のハンドラが処理すべき操作です。
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-handlers
と
inhibit-file-name-operation
を使ってこれを行う方法を示すものです。
それらを上に示したとおりに使うように注意してください。
複数のハンドラがあったり、
2つのファイルを扱う操作において各ファイルにハンドラがある場合には、
この詳細は重要です。
inhibit-file-name-handlers | Variable |
この変数は、特定操作については 現在適用を禁止されているハンドラのリストを保持する。 |
inhibit-file-name-operation | Variable |
特定のハンドラにおいて現在禁止されている操作。 |
find-file-name-handler file operation | Function |
この関数はファイル名fileに対するハンドラ関数を返す。
ハンドラがなければnil を返す。
引数operationは、ファイルに対して適用する操作であること。
つまり、ハンドラを呼び出すときに第1引数として渡される値。
当該操作はinhibit-file-name-operation と比較する必要がある。
|
file-local-copy filename | Function |
この関数は、ファイルfilenameがマジックでない普通のファイルでなければ、
filenameをマジックでない普通のファイルにコピーする。
filenameが、 Emacsの外側のプログラムからは直接読んだり書けないマジックファイル名であると、 この関数は普通のファイルにコピーしてそのファイルの名前を返す。 filenameが普通のファイル名でマジックでなければ、
この関数はなにもせずに |
unhandled-file-name-directory filename | Function |
この関数は、マジックではないディレクトリの名前を返す。
filenameがマジックでなければ、
filenameのディレクトリ部分を使う。
マジックファイル名であると、ファイル名ハンドラを起動し、
当該ハンドラがどんな値を返すか決定する。
これは実行中のサブプロセスに有用である。 各サブプロセスには、カレントディレクトリとしてマジックでないディレクトリが 必要であり、この関数はそれを扱うのによい方法である。 |
変数format-alist
は、
Emacsバッファ内のデータ(テキスト、テキスト属性、その他の情報)を
ファイル内でテキスト表現する方法を記述した
ファイル書式(file format)のリストを定義します。
Emacsはファイルを読み書きするときに必要ならば書式変換を行います。
format-alist | Variable |
このリストは、各ファイル書式の定義を含んだリストである。 |
各書式定義はつぎの形のリストです。
(name doc-string regexp from-fn to-fn modify mode-fn)
書式定義の各要素の意味はつぎのとおりです。
シェルコマンドは文字列で表現し、 Emacsは変換を行うために当該コマンドをフィルタとして実行する。
from-fnが関数であると、 バッファの変換すべき部分を指定するbeginとendの2つの引数で 呼ばれる。 当該関数はその場で編集してテキストを変換すること。 これによりテキストの長さが変わる可能性があるので、 from-fnは変更部分の末尾位置を返すこと。
from-fnの責任の1つは、
ファイルの先頭がregexpで始まらないように保証することである。
さもないと、再度呼び出される可能性がある。
to-fnが文字列であるとそれはシェルコマンドであり、 Emacsは変換を行うために当該コマンドをフィルタとして実行する。
to-fnが関数であると、 バッファの変換すべき部分を指定するbeginとendの2つの引数で 呼ばれる。 変換を行うには2つの方法がある。
(position . string)
の形の要素から成り、
positionは書き出すべきテキスト内での相対位置を指定する整数、
stringはそこに追加すべき注記である。
to-fnがリストを返すときには、
リストはpositionの順にソートしてあること。
write-region
がバッファからファイルへ実際に書き出すとき、
指定された注記を対応する位置に埋め込む。
これらすべては、バッファを変更せずに行われる。
t
、
注記のリストを返す場合にはnil
である。
関数insert-file-contents
は、指定されたファイルを読み込むときに
ファイル書式を自動的に認識します。
ファイルの先頭のテキストを書式定義の正規表現に対して検査して、
一致がみつかれば当該書式の復号化関数を呼び出します。
そして、既知の書式について再度調べ直します。
適用できる書式がなくなるまで検査し続けます。
関数find-file-noselect
やこれを使うコマンドでファイルを訪問すると、
(insert-file-contents
を呼び出すので)同様に変換を行います。
さらに、この関数は、復号した各書式についてモード関数を呼び出します。
バッファローカルな変数buffer-file-format
に
書式名のリストを保存します。
buffer-file-format | Variable |
この変数は、訪問したファイルの書式を記述している。 より正確には、カレントバッファのファイルを訪問する過程で 復号したファイル書式名のリストである。 この変数は、すべてのバッファにおいてつねにバッファローカルである。 |
write-region
がデータをファイルに書き出すときには、まず、
buffer-file-format
で指定された書式の符号化関数を
リストに現れる順に呼び出します。
format-write-file file format | コマンド |
このコマンドは、カレントバッファの内容を書式formatにて ファイルfileに書き出す。 さらに、当該書式をバッファを将来保存するときのデフォルトとする。 引数formatは、書式名のリストである。 |
format-find-file file format | コマンド |
このコマンドは、ファイルfileを探し、
それを書式formatに従って変換する。
さらに、当該書式をバッファをのちに保存するときのデフォルトとする。
引数formatは、書式名のリストである。
formatが |
format-insert-file file format &optional beg end | コマンド |
このコマンドは、ファイルfileの内容を書式formatに従って
変換して挿入する。
begとendがnil 以外であると、
それらは、insert-file-contents (see Reading from Files)と同様に、
読み込むべきファイルの部分を指定する。
戻り値は、 引数formatは、書式名のリストである。
formatが |
auto-save-file-format | Variable |
この変数は、自動保存に対して使用する書式を指定する。
その値は、buffer-file-format の値のように、書式名のリストであるが、
buffer-file-format のかわりに
自動保存ファイルを書くために使われる。
この変数は、すべてのバッファにおいてつねにバッファローカルである。
|
バックアップファイルと自動保存ファイルは、 クラッシュやユーザー自身の誤りから Emacsがユーザーを保護するための2つの方式です。 自動保存により、現在の編集セッションにおいて、 まえの時点でのテキストを確保します。 バックアップファイルにより、現在のセッション以前の ファイル内容を確保します。
revert-buffer
, and how to customize what it does.
バックアップファイル(backup file)とは、 読者が編集中のファイルの古い内容のコピーです。 バッファを訪問しているファイルに初めて保存するときに、 Emacsはバックアップファイルを作成します。 通常これは、バックアップファイルは 現在の編集セッションよりまえのファイルの内容を保持することを意味します。 バックアップファイルの内容は、通常、それが作られると変更されません。
訪問したファイルを新たな名前に改名することで 通常バックアップは作られます。 訪問したファイルをコピーしてバックアップファイルを作るように 指示することもできます。 どちらを選ぶかによって、複数の名前を持つファイルでは違いがでます。 また、編集したファイルの所有者が元所有者と同じであるか、 それとも編集したユーザーが所有者になるかにも影響します。
デフォルトでは、Emacsは各編集ファイルに1つのバックアップファイルを作ります。 番号付きのバックアップファイルを作るように指示することもでき、 そうすると、新たなバックアップファイルごとに新たな名前が付きます。 古い番号付きバックアップファイルは必要なくなれば削除できますし、 Emacsがそれらを自動的に削除することも可能です。
backup-buffer | Function |
この関数は、必要ならば、カレントバッファで訪問しているファイルの
バックアップを作成する。
バッファを初めて保存するまえにsave-buffer がこの関数を呼び出す。
|
buffer-backed-up | Variable |
このバッファローカルな変数は、
当該バッファのもとで当該バッファのファイルの
バックアップを作成済みかどうかを表す。
nil 以外であれば、バックアップファイルは作成済みであることを表す。
さもなければ、(バックアップがオンになっていれば)つぎに保存するときに
ファイルのバックアップを作成するべきであることを表す。
これは恒久的にバッファローカルであり、
kill-local-variables によって変更されない。
|
make-backup-files | User Option |
この変数は、バックアップファイルを作成するかどうかを決定する。
nil 以外であると、backup-inhibited がnil ならば(下記参照)
Emacsは初めて保存するときに各ファイルのバックアップを作成する。
つぎの例は、rmailのバッファでのみ変数 (add-hook 'rmail-mode-hook (function (lambda () (make-local-variable 'make-backup-files) (setq make-backup-files nil)))) |
backup-enable-predicate | Variable |
この変数の値は、ファイルをバックアップすべきかどうかを決定する
ために特定の場面で呼び出される関数である。
当該関数は、調べるべきファイルの名前を引数にとる。
当該関数がnil を返すと、当該ファイルのバックアップは禁止である。
さもなければ、本節の他の変数が、
バックアップするかどうかやバックアップ方法を指定する。
デフォルト値はつぎのとおりである。 (lambda (name) (or (< (length name) 5) (not (string-equal "/tmp/" (substring name 0 5))))) |
backup-inhibited | Variable |
この変数がnil 以外であると、バックアップを禁止する。
この変数は、訪問したファイルの名前に対するbackup-enable-predicate の
検査結果を記録している。
訪問したファイルに基づいてバックアップを禁止する
他の機構でもこの変数を使える。
たとえば、VCはこの変数にnil 以外を設定し、
版管理システムで管理されているファイルに対してバックアップの作成を禁止する。
これは恒久的にバッファローカルであり、
メジャーモードを変更しても値は失われない。
メジャーモードはこの変数に設定するべきではなく、
かわりに、 |
Emacsは2つの方法でバックアップファイルを作れます。
最初の改名による方式がデフォルトです。
変数backup-by-copying
がnil
以外であると、
2番目の方式、つまり、元ファイルをコピーしてから
バッファの新たな内容で上書きすることを指示します。
変数file-precious-flag
がnil
以外であっても
(その主目的の副作用として)同じ効果があります。
See Saving Buffers。
backup-by-copying | Variable |
この変数がnil 以外であると、
Emacsはつねにコピーしてバックアップファイルを作る。
|
つぎの2つの変数がnil
以外であると、
特定の場面では2番目の方式を使うことになります。
これらの変数は、特別な場面に該当しないファイルの扱い方には影響しません。
backup-by-copying-when-linked | Variable |
この変数がnil 以外の場合、Emacsは、
複数の名前(ハードリンク)を持つファイルはコピーしてバックアップする。
この変数は |
backup-by-copying-when-mismatch | Variable |
この変数がnil 以外の場合、Emacsは、
改名するとファイルの所有者やグループを変更してしまう場合に
コピーしてバックアップする。
改名してもファイルの所有者やグループを変更しなければ、 この値は効果を持たない。 つまり、ユーザーが所有しているファイルであり、 そのグループが当該ユーザーが新規作成するファイルのデフォルトに一致する 場合である。 この変数は |
ファイル名がfoo
であると、
その番号付きバックアップファイルの名前はvを整数として
foo.~v~
となります。
つまり、foo.~1~
、foo.~2~
、foo.~3~
、...、
foo.~259~
といった具合です。
version-control | User Option |
この変数は、番号なしの1つのバックアップファイルを作るのか
複数の番号付きバックアップファイルを作るのかを制御する。
|
番号付きバックアップファイルを使うと、 最終的には非常に多くのバックアップファイルができてしまい、 それらは削除しなければなりません。 Emacsはそれらを自動的に削除したり、 削除するかどうかユーザーに問い合わせることができます。
kept-new-versions | User Option |
この変数の値は、新たに番号付きバックアップを作成したときに 保存すべき最新のバックアップの個数である。 新たに作成したバックアップも数える。 デフォルト値は2である。 |
kept-old-versions | User Option |
この変数の値は、新たに番号付きバックアップを作成したときに 保存すべき最古のバックアップの個数である。 デフォルト値は2である。 |
1、2、3、5、7と番号が付いたバックアップがあり、
これらのどちらの変数の値も2であるとすると、
最古のものとして1と2の番号が付いたバックアップを保存し、
最新のものとして5と7の番号が付いたバックアップを保存する。
関数find-backup-file-name
(see Backup Names)は、
どの番号のバックアップを削除すべきかを決定する責任があるが、
それ自身はそれらを削除しない。
delete-old-versions | User Option |
この変数がnil 以外であると、
ファイルを保存すると黙って範囲外のバックアップを削除する。
さもなければ、それを削除するかどうかユーザーに問い合わせる。
|
dired-kept-versions | User Option |
この変数は、diredのコマンド.(dired-clean-directory )で
最新のバックアップを何個保存するかを指定する。
これは、新たなバックアップファイルの作成を指示したときに
kept-new-versions が指定することと同じである。
デフォルト値は2である。
|
本節の関数は、それらを再定義することでバックアップファイルの命名方法を カスタマイズできるため、ここで述べることにします。 どれか1つを変更すると、残りのものも変更する必要があるでしょう。
backup-file-name-p filename | Function |
この関数は、filenameがバックアップファイルの名前である
可能性があるとnil 以外の値を返す。
filenameという名前のファイルが存在する必要はなく、
この関数は単に名前だけを検査する。
(backup-file-name-p "foo") => nil (backup-file-name-p "foo~") => 3 この関数の標準定義はつぎのとおりである。 (defun backup-file-name-p (file) "Return non-nil if FILE is a backup file \ name (numeric or not)..." (string-match "~$" file)) したがって、ファイル名が カスタマイズのために再定義しやすいように、 この単純な式を独立した関数にしてある。 |
make-backup-file-name filename | Function |
この関数は、ファイルfilenameに対する
番号なしバックアップファイルに使う名前を表す文字列を返す。
UNIXでは、単にfilenameの末尾にティルダを付加したものである。
ほとんどのオペレーティングシステムでは、 この関数の標準定義はつぎのとおりである。 (defun make-backup-file-name (file) "Create the non-numeric backup file name for FILE...." (concat file "~")) この関数を再定義すれば、バックアップファイルの命名方法を変更できる。
つぎの例では、ティルダに加えて先頭に (defun make-backup-file-name (filename) (expand-file-name (concat "." (file-name-nondirectory filename) "~") (file-name-directory filename))) (make-backup-file-name "backups.texi") => ".backups.texi~" diredコマンドを含めてEmacsには、
バックアップファイルは |
find-backup-file-name filename | Function |
この関数は、filenameに対する新たなバックアップファイルの
ファイル名を計算する。
さらに、削除すべき既存のバックアップファイルも計算する。
find-backup-file-name は、
CARに新たなバックアップファイルの名前、
CDRに削除すべきバックアップファイルのリストを持つリストを返す。
2つの変数、 つぎの例の値では、 (find-backup-file-name "~rms/foo") => ("~rms/foo.~5~" "~rms/foo.~3~") |
file-newest-backup filename | Function |
この関数は、filenameの最新のバックアップファイルの名前を返す。
当該ファイルにバックアップファイルがなければnil を返す。
ファイルを比較するコマンドのなかには、 最新のバックアップファイルと自動的に比較できるように この関数を使うものがある。 |
Emacsは編集中のすべてのファイルを定期的に保存します。 これを自動保存(auto-savign)と呼びます。 自動保存により、システムがクラッシュしても、 一定量以上の作業を失わないようにします。 デフォルトでは、300打鍵ごと、あるいは、30秒間なにもしないと自動保存します。 ユーザー向けの自動保存に関する情報については、 See Auto Save。 ここでは、自動保存を実装するための関数と それらを制御する変数について述べます。
buffer-auto-save-file-name | Variable |
このバッファローカルな変数は、カレントバッファの自動保存に
用いるファイル名である。
当該バッファを自動保存しない場合にはnil である。
buffer-auto-save-file-name => "/xcssun/users/rms/lewis/#files.texi#" |
auto-save-mode arg | コマンド |
引数なしに対話的に呼ばれると、
このコマンドは自動保存機能をトグルする。
つまり、カレントバッファの自動保存がオンであるとオフにし、
オフならばオンにする。
引数argを指定すると、
argの値がt 、空でないリスト、正整数のいずれかであれば、
このコマンドは自動保存をオンにする。
さもなければ自動保存をオフにする。
|
auto-save-file-name-p filename | Function |
この関数は、filenameが自動保存ファイルの名前でありえれば、
nil 以外を返す。
この関数は自動保存ファイルの名前の慣習に基づいて動作する。
名前がハッシュマーク(# )で始まりかつ終っていれば、
自動保存ファイルの名前である可能性がある。
引数filenameにはディレクトリ部分を含まないこと。
(make-auto-save-file-name) => "/xcssun/users/rms/lewis/#files.texi#" (auto-save-file-name-p "#files.texi#") => 0 (auto-save-file-name-p "files.texi") => nil この関数の標準定義はつぎのとおりである。 (defun auto-save-file-name-p (filename) "Return non-nil if FILENAME can be yielded by..." (string-match "^#.*#$" filename)) この関数は、自動保存ファイルの名前の慣習を変更したい場合に
当該関数をカスタマイズできるようにするためである。
当該関数を再定義した場合には、関数 |
make-auto-save-file-name | Function |
この関数は、カレントバッファの自動保存に使うファイル名を返す。
その名前は、単にファイル名の前後にハッシュマーク(# )を
付加するだけである。
この関数は変数auto-save-visited-file-name (下記参照)を
調べないため、読者はこの関数を呼び出すまえにその変数を検査しておくこと。
(make-auto-save-file-name) => "/xcssun/users/rms/lewis/#backup.texi#" この関数の標準定義はつぎのとおりである。 (defun make-auto-save-file-name () "Return file name to use for auto-saves \ of current buffer...." (if buffer-file-name (concat (file-name-directory buffer-file-name) "#" (file-name-nondirectory buffer-file-name) "#") (expand-file-name (concat "#%" (buffer-name) "#")))) 自動保存ファイルの名前の慣習をカスタマイズするために
関数を再定義できるように1つの関数にしてある。
関数 |
auto-save-visited-file-name | Variable |
この変数がnil 以外であると、
Emacsは訪問しているファイルにバッファを自動保存する。
つまり、読者が編集しているファイルと同じファイルに自動保存を行う。
通常、この変数はnil であり、自動保存ファイルには
make-auto-save-file-name で作成した別の名前がある。
この変数の値を変更しても、
バッファの自動保存をつぎにオンにするまで、この値は効果を発揮しない。
自動保存がすでにオンであると、
|
recent-auto-save-p | Function |
カレントバッファに最後に読み込んだり保存してから以降に自動保存していると、
この関数はt を返す。
|
set-buffer-auto-saved | Function |
この関数は、カレントバッファに自動保存済みであると印を付ける。
バッファのテキストが再度変更されない限り、バッファは自動保存されない。
この関数はnil を返す。
|
auto-save-interval | User Option |
この変数の値は、つぎの自動保存までに Emacsがキーボードから読み取る文字の個数である。 これだけの文字を読み取ると、自動保存をオンにしてあるすべてのバッファを 自動保存する。 |
auto-save-timeout | User Option |
この変数の値は、自動保存を引き起こすまでのなにもしていない期間の秒数である。 この時間だけユーザーがなにもしないと、 Emacsは自動保存する必要があるバッファを自動保存する。 (実際には、カレントバッファの大きさに依存した係数を指定時間に掛ける。) |
auto-save-hook | Variable |
このノーマルフックは、自動保存を行う直前に毎回実行される。 |
auto-save-default | User Option |
この変数がnil 以外であると、
ファイルを訪問しているバッファはデフォルトで自動保存をオンにする。
さもなければ、そうしない。
|
do-auto-save &optional no-message current-only | コマンド |
この関数は、自動保存する必要があるすべてのバッファを自動保存する。
自動保存がオンになっていて、かつ、以前の自動保存からあとで
変更されているすべてのバッファを自動保存する。
通常、バッファを自動保存すると、
自動保存を実行中にはエコー領域にメッセージ current-onlyが |
delete-auto-save-file-if-necessary | Function |
この関数は、delete-auto-save-files がnil 以外であると、
カレントバッファの自動保存ファイルを削除する。
バッファを保存するたびに呼び出される。
|
delete-auto-save-files | Variable |
この変数は、関数delete-auto-save-file-if-necessary が使う。
nil 以外であると、Emacsは(訪問しているファイルに)実際に
保存すると自動保存ファイルを削除する。
これによりディスクスペースを節約し、読者のディレクトリを整頓できる。
|
rename-auto-save-file | Function |
この関数は、訪問しているファイルの名前が変更されていると、 カレントバッファの自動保存ファイルの名前を修正する。 さらに、既存の自動保存ファイルも改名する。 訪問しているファイルの名前が変更されていなければ、 この関数はなにもしない。 |
buffer-saved-size | Variable |
このバッファローカルな変数の値は、
最後に読み込んだり保存したり自動保存したときの
カレントバッファの長さである。
サイズの大幅な変更を検知すると自動保存をオフにするために使われる。
この変数が-1であると、 大幅に削除したために一時的に自動保存をオフにしたことを意味する。 明示的にバッファを保存すると、この変数に正の値が保存され、 自動保存が再度オンになる。 自動保存をオフにしたりオンにしても、この変数が変更される。 |
auto-save-list-file-name | Variable |
この変数は(nil 以外であると)、
すべての自動保存ファイルの名前を記録するファイルを指定する。
Emacsが自動保存を行うたびに、
自動保存がオンである各バッファに関する2行をこのファイルに書き出す。
1行目は訪問しているファイルの名前を与え(訪問していなければ空)、
2行目は自動保存ファイルの名前を与える。
Emacsが正常に終ると、このファイルは削除される。
Emacsがクラッシュしたら、失われてしまう作業内容を含んでいるかもしれない
自動保存ファイルを探すために読者はこのファイルを調べられる。
コマンド このファイルのデフォルト名は、
読者のホームディレクトリにあり |
ファイルを大幅に変更したあとで、そのような変更をやめたい場合には、
コマンドrevert-buffer
でファイルのまえの版を読み込めます。
See Reverting。
revert-buffer &optional ignore-auto noconfirm | コマンド |
このコマンドは、バッファのテキストを
ディスク上の訪問しているファイルのテキストで置き換える。
これにより、ファイルを訪問したり保存してから行った変更をすべて取り消せる。
デフォルトでは、最後の自動保存ファイルが
訪問しているファイルよりも新しい場合には、
通常、バッファを変更するまえに 復元作業では、
|
以下の変数を典型的にはバッファローカルな変数として設定することで
revert-buffer
の動作をカスタマイズできます。
revert-without-query | Variable |
この変数は、問い合わせずに復元すべきファイルのリストを保持する。
値は、正規表現のリストである。
ファイル名がこれらの正規表現の1つに一致すると、
ディスク上のファイルが変更されていて当該バッファが未変更であれば、
revert-buffer はユーザーに確認せずに当該ファイルを復元する。
|
revert-buffer-function | Variable |
この変数の値は、このバッファを復元するために使う関数である。
nil 以外であれば、復元を行う引数なしの関数として呼び出される。
値がnil であると、復元操作は通常の方法で行われる。
diredモードなどのモードでは、 編集中のテキストはファイルの内容ではなく 別の方法で再生成されたものなので、 この変数のバッファローカルな値には内容を再生成する関数を指定すること。 |
revert-buffer-insert-file-contents-function | Variable |
この変数の値がnil 以外であると、
このバッファを復元するときに更新内容を挿入するために使われる関数である。
当該関数は2つの引数をとる。
第1引数は、使用するファイル名である。
第2引数は、ユーザーが自動保存ファイルを
読むように指示しているとt である。
|
before-revert-hook | Variable |
このノーマルフックは、revert-buffer-function がnil である
場合にのみ、変更内容を実際に挿入するまえにrevert-buffer が実行する。
フォントロック(font-lock)モードはこのフックを使って、 バッファ内容をこれ以上強調表示しないことを記録する。 |
after-revert-hook | Variable |
このノーマルフックは、revert-buffer-function がnil である
場合にのみ、変更内容を実際に挿入したあとにrevert-buffer が実行する。
フォントロック(font-lock)モードはこのフックを使って、 更新されたバッファ内容に対するフォントを再計算する。 |
バッファ(buffer)は、編集するテキストを収めている Lispオブジェクトです。 バッファは、訪問しているファイルのテキストを保持するために使われますが、 ファイルを訪問していないバッファもあります。 一度に複数のバッファが存在してかまいませんが、 ある時点ではたった1つのバッファがカレントバッファ (current buffer)として区別されます。 ほとんどの編集コマンドは、カレントバッファの内容に作用します。 カレントバッファを含む各バッファは、ウィンドウに表示されることも されないこともあります。
Emacsの編集においてバッファとは、 異なる名前を持ち編集可能なテキストを保持するオブジェクトです。 バッファは、Lispプログラムには特別なデータ型として見えます。 バッファの内容は拡張可能な文字列であると考えることができます。 つまり、バッファのどの部分ででも挿入や削除を行えるのです。 See Text。
Lispのバッファオブジェクトには、さまざまな情報が含まれています。 変数を介してプログラマが直接参照できる情報もあれば、 特別目的の関数のみを介して参照できる情報もあります。 たとえば、訪問しているファイルの名前は、変数を介して直接参照できますが、 ポイントの値は基本関数を介してのみ参照できます。
直接参照可能なバッファに固有の情報は、
バッファローカル(buffer-local)な変数束縛、
つまり、特定のバッファでのみ有効な変数に保持されています。
この機能により、各バッファでは特定の変数の値を優先できます。
ほとんどのメジャーモードでは、このようにして、
fill-column
やcomment-column
などの変数を優先させます。
バッファローカルな変数とそれらに関する関数について詳しくは、
Buffer-Local Variablesを参照してください。
バッファで訪問しているファイルに関する関数や変数については、 Visiting FilesとSaving Buffersを参照してください。 ウィンドウにバッファを表示することに関する関数や変数については、 Buffers and Windowsを参照してください。
bufferp object | Function |
この関数は、objectがバッファであればt を返し、
さもなければnil を返す。
|
一般に、Emacsセッションには多くのバッファがあります。 いつの時点でも、それらの1つをカレントバッファ (current buffer)として区別します。 バッファ内のテキストを検査したり変更する基本関数は 暗黙のうちにカレントバッファに作用するため、 ほとんどの編集はカレントバッファに対して行われます (see Text)。 通常、スクリーン上で選択されたウィンドウに表示されているバッファが カレントバッファですが、つねにそうとは限りません。 Lispプログラムでは、スクリーン上の表示は変えずに、 任意のバッファの内容を操作するために 一時的に当該バッファをカレントバッファにできます。
Lispプログラムでカレントバッファを指定するには、
set-buffer
を呼び出します。
新たに指定し直すまで指定したバッファがカレントバッファであり続けます。
編集コマンドがエディタコマンドループへ戻ると、
コマンドループは、混乱を避けるために、選択されているウィンドウに
表示されているバッファをカレントバッファとします。
つまり、Emacsがコマンドを読むときにカーソルがあるバッファが
コマンドが適用されるバッファです。
(See Command Loop。)
したがって、set-buffer
は、
ユーザーが編集できるように別のバッファへ切り替える方法にはなりません。
これには、Displaying Buffersで述べている関数を使う必要があります。
しかし、別のカレントバッファに替えるLisp関数では、
コマンドループがカレントバッファを
あとで戻すということに依存してはいけません。
Emacs Lispで書かれた編集コマンドは、コマンドループに加えて
別のプログラムからも呼ばれます。
サブルーティンがカレントバッファを替えないほうが
(それがサブルーティンの目的でなければ)、
呼び出し側にとっては便利です。
したがって、関数の実行が終るともとのカレントバッファに戻す
フォームsave-current-buffer
や
save-excursion
(see Excursions)の内側で、
普通はset-buffer
を使います。
例として、(説明文字列を簡略にして)コマンドappend-to-buffer
のコードを示します。
(defun append-to-buffer (buffer start end) "Append to specified buffer the text of the region. ..." (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
でもとのカレントバッファから
指定された(いまはカレント)バッファに文字列をコピーします。
内容を付加したバッファがどれかのウィンドウに表示されていると、 つぎに表示を更新したときに変更されたテキストが表示されます。 それ以外では、スクリーン上でただちには変更を見ることはできません。 コマンドの実行中にはバッファが一時的にカレントバッファになりますが、 それによりそのバッファが表示されるわけではありません。
バッファローカルな束縛を持つ変数を(let
や関数の引数で)
ローカルに束縛する場合には、ローカルな束縛の有効範囲の開始時と終了時には、
同じバッファが必ずカレントバッファであるようにします。
さもないと、あるバッファでは変数を束縛し、
別のバッファではその束縛を解除してしまうことがあります。
これには2つの方法があります。
単純な場合には、束縛の有効範囲内で
カレントバッファが替わらないを確認します。
さもなければ、save-current-buffer
やsave-excursion
を使って、
始めにカレントバッファであったバッファが、
変数束縛が解除されるときにはつねにカレントバッファであるようにします。
set-buffer
でもとのカレントバッファに戻すのでは信頼性がありません。
正しくないバッファがカレントバッファであるときに
中断が起きると戻せないからです。
してはいけないことをつぎに示します。
(let (buffer-read-only (obuf (current-buffer))) (set-buffer ...) ... (set-buffer obuf))
つぎのようにsave-current-buffer
を使えば、
通常の評価に加えて、中断、エラー、throw
も扱えます。
(let (buffer-read-only) (save-current-buffer (set-buffer ...) ...))
current-buffer | Function |
この関数はカレントバッファを返す。
(current-buffer) => #<buffer buffers.texi> |
set-buffer buffer-or-name | Function |
この関数は、buffer-or-nameをカレントバッファにする。
この関数は現在選択されているウィンドウやその他のウィンドウに
当該バッファを表示しないので、ユーザーが当該バッファを見られるとは限らない。
しかし、Lispプログラムはいずれにしても当該バッファを操作できる。
この関数はbuffer-or-nameで指定されるバッファを返す。 buffer-or-nameが既存のバッファを指定しなければ、エラーを通知する。 |
save-current-buffer body... | Special Form |
マクロsave-current-buffer は、
カレントバッファの識別子を保存し、フォームbodyを評価し、
最後にもとのカレントバッファに戻す。
戻り値は、bodyの最後のフォームの値である。
throw やエラー(see Nonlocal Exits)による異常終了であっても
カレントバッファは戻される。
|
with-current-buffer buffer body... | Macro |
マクロwith-current-buffer は、
カレントバッファの識別子を保存し、
bufferをカレントバッファにし、フォームbodyを評価し、
最後にもとのカレントバッファに戻す。
戻り値は、bodyの最後のフォームの値である。
throw やエラー(see Nonlocal Exits)による異常終了であっても
カレントバッファは戻される。
|
with-temp-buffer body... | Macro |
マクロwith-temp-buffer は、
一時的なバッファをカレントバッファとして
フォームbodyを評価する。
カレントバッファの識別子を保存し、
一時的なバッファを作成してそれをカレントバッファにし、
フォームbodyを評価し、
最後にもとのカレントバッファに戻すとともに一時的なバッファを削除する。
戻り値は、bodyの最後のフォームの値である。
最後のフォームとして
|
with-temp-file
も参照してください。
各バッファには、文字列で一意な名前があります。 バッファに作用するほとんどの関数は、 引数としてバッファかバッファ名を受け付けます。 buffer-or-nameという名前の引数はこの種のものであり、 当該引数が文字列でもバッファでもないとエラーを通知します。 bufferという名前の引数は 実際のバッファオブジェクトである必要があり、名前ではだめです。
短命で一般にはユーザーが関心を示さないバッファの名前は空白で始まり、
コマンドlist-buffers
やbuffer-menu
はそれらを表示しません。
さらに、空白で始まる名前のバッファでは、
アンドゥ情報の記録も最初は禁止してあります。
Undoを参照してください。
buffer-name &optional buffer | Function |
この関数は、bufferの名前を文字列で返す。
bufferを指定しないと、デフォルトはカレントバッファである。
(buffer-name) => "buffers.texi" (setq foo (get-buffer "temp")) => #<buffer temp> (kill-buffer foo) => nil (buffer-name foo) => nil foo => #<killed buffer> |
rename-buffer newname &optional unique | コマンド |
この関数は、カレントバッファをnewnameと改名する。
newnameが文字列でなかったり、
当該名のバッファがすでに存在していると、エラーを通知する。
関数はnewnameを返す。
通常、newnameがすでに使われていると、
このコマンドの1つの用途は、
バッファ |
get-buffer buffer-or-name | Function |
この関数は、buffer-or-nameで指定したバッファを返す。
buffer-or-nameが文字列であり、
そのような名前のバッファが存在しなければnil を返す。
buffer-or-nameがバッファであればそれ自身を返す。
(これは有用ではないので、普通、引数は名前である。)
例を示す。
(setq b (get-buffer "lewis")) => #<buffer lewis> (get-buffer b) => #<buffer lewis> (get-buffer "Frazzle-nots") => nilCreating Buffersの関数 get-buffer-create も参照。
|
generate-new-buffer-name starting-name | Function |
この関数は、新たなバッファ向けの一意な名前を返すが、バッファは作成しない。
名前はstarting-nameで始まり、
<...> で囲った数を追加することで、
どのバッファでも現在使っていない名前を作成する。
Creating Buffersの関連する関数generate-new-buffer を参照。
|
バッファファイル名(buffer file name)とは、
当該バッファで訪問しているファイルの名前です。
バッファでファイルを訪問していないときには、
バッファファイル名はnil
です。
ほとんどの場面で、バッファ名は
バッファファイル名の非ディレクトリ部分と同じですが、
バッファファイル名とバッファ名は別のものであり個別に設定できます。
See Visiting Files。
buffer-file-name &optional buffer | Function |
この関数は、bufferで訪問しているファイルの
絶対ファイル名を返す。
bufferがファイルを訪問していなければ、
buffer-file-name はnil を返す。
bufferを指定しないと、
デフォルトはカレントバッファである。
(buffer-file-name (other-buffer)) => "/usr/user/lewis/manual/files.texi" |
buffer-file-name | Variable |
このバッファローカルな変数は、
カレントバッファで訪問しているファイルの名前を保持する。
あるいは、ファイルを訪問していなければnil である。
これは恒久的にバッファローカルであり、
kill-local-variables に影響されない。
buffer-file-name => "/usr/user/lewis/manual/buffers.texi" 他のさまざまなことを行わずにこの変数の値だけを変更することは危険である。
通常、 |
buffer-file-truename | Variable |
このバッファローカルな変数は、
カレントバッファで訪問しているファイルの実名を保持する。
あるいは、ファイルを訪問していなければnil である。
これは恒久的にバッファローカルであり、
kill-local-variables に影響されない。
see Truenames。
|
buffer-file-number | Variable |
このバッファローカルな変数は、
カレントバッファで訪問しているファイルの
ファイル番号とディレクトリ装置番号を保持する。
あるいは、ファイルを訪問していなければnil である。
これは恒久的にバッファローカルであり、
kill-local-variables に影響されない。
この値は、通常、 |
get-file-buffer filename | Function |
この関数は、ファイルfilenameを訪問しているバッファを返す。
そのようなバッファが存在しなければnil を返す。
引数filenameは文字列であり、
展開(see File Name Expansion)してから
すべてのバッファの訪問しているファイル名と比較する。
(get-file-buffer "buffers.texi") => #<buffer buffers.texi> 稀れな状況では、複数のバッファが同じ名前のファイルを訪問している場合がある。 そのような場合、この関数はバッファリストで最初にみつかったバッファを返す。 |
set-visited-file-name filename &optional no-query along-with-file | コマンド |
filenameが空でない文字列であると、
この関数はカレントバッファで訪問しているファイルの名前を
filenameに変える。
(ファイルを訪問していないバッファでは、
当該バッファに訪問しているファイル名を指定する。)
バッファをつぎに保存すると、指定した新たなファイルに保存される。
このコマンドは、バッファに変更済みと印を付ける。
変更まえの訪問しているファイルの内容とバッファ内容が一致していたとしても
(Emacsにとっては)
バッファ内容はfilenameの内容と一致しないからである。
filenameが 通常、この関数は、指定したファイルが既存の場合には
ユーザーに確認をとる。
no-queryが along-with-fileが 関数 |
list-buffers-directory | Variable |
このバッファローカルな変数は、 訪問しているファイル名を持たないバッファに対して、 バッファ一覧において訪問しているファイル名を表示する部分に 表示する文字列を指定する。 diredのバッファはこの変数を使う。 |
Emacsは、各バッファごとに当該バッファのテキストを変更したかどうかを
記録する変更フラグ(modified flag)と呼ばれるフラグを保持しています。
バッファの内容が変わるたびにこのフラグはt
に設定され、
保存するたびにnil
に設定されます。
つまり、このフラグは未保存の変更があるかどうかを表します。
このフラグの値は通常モード行(see Mode Line Variables)に表示され、
保存(see Saving Buffers)と
自動保存(see Auto-Saving)を制御します。
このフラグを明示的に設定するLispプログラムもあります。
たとえば、関数set-visited-file-name
はこのフラグをt
に設定します。
ファイルを訪問してから変更していなくても、
バッファのテキストが新たな訪問しているファイルとは一致しないからです。
バッファの内容を変更する関数についてはTextに述べてあります。
buffer-modified-p &optional buffer | Function |
この関数は、最後にファイルから読み込んだり保存してから
バッファbufferが変更されていればt を返し、
さもなければnil を返す。
bufferを指定しないとカレントバッファを調べる。
|
set-buffer-modified-p flag | Function |
この関数は、flagがnil 以外であれば
カレントバッファは変更されていると印を付け、
nil ならば未変更であると印を付ける。
この関数を呼び出した別の効果として、
カレントバッファのモード行を無条件に再表示する。
実際、関数 (set-buffer-modified-p (buffer-modified-p)) |
not-modified | コマンド |
このコマンドは、カレントバッファを未変更であり
保存する必要がないと印を付ける。
前置引数を指定すると、バッファに変更されていると印を付け、
以降の適当な場面で保存される。
エコー領域にメッセージを表示するので、
プログラムからこの関数を使わないこと。
かわりに |
buffer-modified-tick &optional buffer | Function |
この関数は、bufferの変更回数を返す。
変更回数はバッファを変更するたびに増やされる。
bufferがnil であると(あるいは省略すると)、
カレントバッファを使う。
|
ファイルを訪問してそのバッファで変更したとします。 そのあいだに、ディスク上の当該ファイル自身も変更されたとします。 ここでバッファを保存すると、ファイルの変更内容を上書きしてしまいます。 たしかにこれを望む場合もあるでしょうが、 普通は重要な情報を失うことになります。 そのため、Emacsは、ファイルに保存するまえに、 以下に述べる関数を用いてファイルの更新時刻を検査します。
verify-visited-file-modtime buffer | Function |
この関数は、bufferに記録してある
訪問しているファイルの更新時刻と、
オペレーティングシステムが記録している
ファイルの実際の更新時刻を比較する。
Emacsが当該ファイルを訪問したり保存してから
他のプロセスが当該ファイルに書いていない限り、
2つの時刻は同じはずである。
実際の更新時刻とEmacsに記録している更新時刻が同じならば |
clear-visited-file-modtime | Function |
この関数は、カレントバッファで訪問しているファイルの
最終更新時刻の記録を破棄する。
その結果、つぎにこのバッファを保存しようとしても、
ファイルの更新時刻のと不一致を報告しない。
この関数は、 |
visited-file-modtime | Function |
この関数は、
バッファに記録されているファイルの最終更新時刻を
(high . low) の形のリストで返す。
(これはfile-attributes が時刻を返すために使う形と同じである。
File Attributesを参照。)
|
set-visited-file-modtime &optional time | Function |
この関数は、timeがnil 以外であるときには、
バッファに記録してあるファイルの最終更新時刻を
timeで指定された時刻にする。
さもなければ、訪問しているファイルの最終更新時刻にする。
timeが この関数は、ファイルから普通に読み込んだのではないバッファや ファイル自体が明確な理由で変更された場合に有用である。 |
ask-user-about-supersession-threat filename | Function |
この関数は、ファイルfilenameを訪問している廃れたバッファを
変更しようとしたときにどのように処理すべきかをユーザーに問い合わせる
ために用いる。
廃れたバッファ(obsolete buffer)とは、
未変更のバッファではあるが、対応するディスク上のファイルが
バッファの最終更新時刻よりも新しいものである。
つまり、別のプログラムが当該ファイルを変更した可能性があることを意味する。
ユーザーの応答に依存して、関数は正常に戻る。
その場合、バッファは変更できる。
あるいは、データ この関数は、適切な場面でEmacsが自動的に呼び出す。
これを再定義することでEmacsをカスタマイズできるようにしている。
標準定義についてはファイル |
バッファが読み出し専用(read-only)であると、 スクロールしたりナロイングしてその内容を眺めることはできますが、 その内容は変更できません。
読み出し専用バッファは、2種類の場面で使われます。
ここでの目的は、バッファを編集してファイルに保存しようとしても それに失敗するか望ましくないことであることをユーザーに伝えることである。 それにも関わらずバッファのテキストを変更したいユーザーは、 読み出し専用フラグをC-x C-qでクリアすれば編集できる。
これらのモードの特別なコマンドは、
それら自身がテキストを変更する場面では、
(let
で)buffer-read-only
にnil
を束縛したり、
inhibit-read-only
にt
を束縛する。
buffer-read-only | Variable |
このバッファローカルな変数は、
バッファが読み出し専用であるかどうかを指定する。
この変数がnil 以外であると、バッファは読み出し専用である。
|
inhibit-read-only | Variable |
この変数がnil 以外であると、
読み出し専用バッファや読み出し専用文字を変更できる。
バッファ内の読み出し専用文字とは
(テキスト属性やオーバレイ属性の)
属性read-only がnil 以外の文字である。
テキスト属性について詳しくは、see Special Properties。
重ね合わせとそれらの属性について詳しくは、see Overlays。
|
toggle-read-only | コマンド |
このコマンドは、カレントバッファが読み出し専用かどうかを変更する。
対話的な使用を意図しており、プログラムからは使わないこと。
プログラムの任意の箇所で、読み出し専用フラグを
オンにしたいかオフにしたいかを読者は知っているはずであり、
そうすれば、読者はbuffer-read-only を
t かnil の正しい値に明示的に設定できる。
|
barf-if-buffer-read-only | Function |
この関数は、カレントバッファが読み出し専用であると
エラーbuffer-read-only を通知する。
カレントバッファが読み出し専用であるときに
エラーを通知する別の方法については、see Interactive Call。
|
バッファリスト(buffer list)は、
すべてのバッファのリストです。
バッファを作成すると当該バッファはこのリストに追加され、
削除するとこのリストから取り除かれます。
リスト内のバッファの順序は、各バッファが選択されているウィンドウに
どの程度最近に表示されたかを主な基準にしています。
バッファが選択されるとリストの先頭に移動し、
隠されると(下記のbury-buffer
を参照)末尾に移動します。
other-buffer
をはじめとするいくつかの関数が、この順序を使います。
ユーザーに表示するバッファ一覧もこの順序を反映しています。
Emacs基本バッファリストに加えて、
各フレームには独自のバッファリストがあります。
そのリストでは、
当該フレームでもっとも最近に選択されたバッファから順に
当該フレームで選択されたバッファが先にきます。
(この順番は、フレームのフレームパラメータbuffer-list
に入っている。
Window Frame Parametersを参照。)
当該フレームで選択されたことがないバッファは、
Emacs基本バッファリストでの順にうしろに続きます。
buffer-list &optional frame | Function |
この関数は、空白で始まる名前のバッファを含めて、
すべてのバッファを含んだバッファリストを返す。
要素は実際にバッファであり、それらの名前ではない。
frameがフレームであると、
この関数はフレームframeのバッファリストを返す。
frameが (buffer-list) => (#<buffer buffers.texi> #<buffer *Minibuf-1*> #<buffer buffer.c> #<buffer *Help*> #<buffer TAGS>) ;; ミニバッファの名前は空白で始まることに注意 (mapcar (function buffer-name) (buffer-list)) => ("buffers.texi" " *Minibuf-1*" "buffer.c" "*Help*" "TAGS") |
buffer-list
が返すリストは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
(see Parameter Access)で、
フレームのフレームパラメータbuffer-list
に設定します。
other-buffer &optional buffer visible-ok frame | Function |
この関数は、バッファリストからbuffer以外の最初のバッファを返す。
通常、当該バッファは、bufferを除いて
(frameか現在選択されているフレームで)
もっとも最近に選択されたバッファである。
空白で始まる名前のバッファは完全に除外する。
bufferを指定しないと(あるいはバッファでないと)、
frameに visible-okが 適当なバッファが存在しない場合には、
バッファ |
bury-buffer &optional buffer-or-name | コマンド |
この関数は、バッファリストの他のバッファの順序は変えずに
buffer-or-nameを末尾に置く。
この結果、当該バッファは、other-buffer が返す候補としては
もっとも可能性が低くなる。
buffer-or-nameが すべてのウィンドウに表示している特定のバッファを置き換えるには、
|
本節では、バッファを作成するための2つの基本関数を説明します。
get-buffer-create
は、指定した名前のバッファが
存在しなければバッファを作成します。
generate-new-buffer
は、つねに新たなバッファを作成し、
それに一意な名前を与えます。
バッファを作成するために読者が使える他の関数には、
with-output-to-temp-buffer
(see Temporary Displays)、
create-file-buffer
(see Visiting Files)があります。
サブプロセスを開始してもバッファを作ります(see Processes)。
get-buffer-create name | Function |
この関数は、nameという名前のバッファを返す。
その名前のバッファが存在すれば、当該バッファを返す。
さもなければ、新たなバッファを作成する。
バッファはカレントバッファにはならない。
この関数は、どのバッファがカレントバッファであるかは変更しない。
nameが文字列でないとエラーを通知する。 (get-buffer-create "foo") => #<buffer foo> 新たなバッファのメジャーモードは基本(fundamental)モードに設定される。
変数 |
generate-new-buffer name | Function |
この関数は、新たに作成した空のバッファを返すが、
それをカレントバッファにはしない。
nameという名前のバッファが存在しなければ、
新たなバッファの名前はnameである。
その名前が使われている場合には、
この関数は、nを整数として<n> の形の接尾辞を
nameに付加する。
nを2から始めて順に使える名前を探す。
nameが文字列でないとエラーを通知する。 (generate-new-buffer "bar") => #<buffer bar> (generate-new-buffer "bar") => #<buffer bar<2>> (generate-new-buffer "bar") => #<buffer bar<3>> 新たなバッファのメジャーモードは基本(fundamental)モードに設定される。
変数 |
バッファを削除するとは、Emacsに当該バッファの名前を忘れさせ、 それが使っていた場所を他の目的に使えるようにすることです。
削除されたバッファを表すバッファオブジェクトは、
それを指すものが存在する限り存在し続けますが、
それをカレントバッファにしたり表示できないように特別な印が付いています。
削除されたバッファの識別子は残っているので、
異なる2つのバッファを削除しても、
eq
に関する限りそれらは区別できるのです。
カレントバッファやウィンドウに表示しているバッファを削除すると、 そのかわりにEmacsは別のバッファを選択したり表示します。 つまり、バッファを削除すると一般にはカレントバッファが 替わりうることを意味します。 したがって、バッファを削除するときには、 (削除するバッファがカレントバッファではないことがわかっていない限り) カレントバッファを替える可能性についてあらかじめ注意しておく必要があります。 See Current Buffer。
複数の間接バッファの基底バッファであるバッファを削除すると、 間接バッファも自動的に削除されます。
削除されたバッファのbuffer-name
はnil
です。
これを使えばバッファが削除されているかどうか調べられます。
(defun buffer-killed-p (buffer) "Return t if BUFFER is killed." (not (buffer-name buffer)))
kill-buffer buffer-or-name | コマンド |
この関数はバッファbuffer-or-nameを削除し、
当該バッファが使用していたすべてのメモリを他の目的に使えるように解放したり、
オペレーティングシステムに返すために解放する。
この関数はnil を返す。
当該バッファを 当該バッファがファイルを訪問していて、かつ、未保存の変更があれば、
削除済みのバッファを削除してもなんの効果もない。 (kill-buffer "foo.unchanged") => nil (kill-buffer "foo.changed") ---------- Buffer: Minibuffer ---------- Buffer foo.changed modified; kill anyway? (yes or no) yes ---------- Buffer: Minibuffer ---------- => nil |
kill-buffer-query-functions | Variable |
未保存の変更を確認したあとで、kill-buffer は、
リストkill-buffer-query-functions の関数を現れる順に
引数なしで呼び出す。
これらの関数が呼び出されるときには、
削除対象のバッファがカレントバッファである。
これらの関数でさまざまな非標準的な理由から
ユーザーの確認をとることが目的である。
いずれかがnil を返すと、kill-buffer はバッファを削除しない。
|
kill-buffer-hook | Variable |
これは、kill-buffer が問い合わせをすべて完了し
バッファを実際に削除する直前に実行されるノーマルフックである。
フック関数を実行するときには、削除対象のバッファがカレントバッファである。
see Hooks。
|
buffer-offer-save | Variable |
この変数が特定のバッファでnil 以外であると、
save-buffers-kill-emacs とsave-some-buffers に対して
ファイルを訪問しているバッファと同様に
当該バッファを保存する機会を与えるように指示する。
変数buffer-offer-save に
設定すると自動的にバッファローカルになる。
|
間接バッファ(indirect buffer)は、 間接バッファの基底バッファ(base buffer)と呼ばれる 他のバッファのテキストを共有します。 ある意味で、バッファにおいて ファイルのシンボリックリンクに相当するものです。 基底バッファそのものは間接バッファであってはなりません。
間接バッファのテキストは、その基底バッファのテキストとつねに同一です。 どれかを編集して変更すると、別のものでただちに見えます。 これには、文字そのものに加えてテキスト属性も含みます。
しかし、それ以外に関しては、間接バッファと その基底バッファは完全に別のものです。 別の名前を持ち、ポイントの値も別であり、異なったナロイングをでき、 (いずれかのバッファでテキストを挿入したり削除すると マーカと重ね合わせは再配置されるが)マーカやオーバレイも異なり、 異なるメジャーモードを持ち、バッファローカルな変数も異なります。
間接バッファはファイルを訪問できませんが、その基底バッファでは訪問できます。 間接バッファを保存しようとすると、実際にはその基底バッファを保存します。
間接バッファを削除しても、その基底バッファには影響ありません。 基底バッファを削除すると、その間接バッファを実質的には削除することになり、 間接バッファをカレントバッファにはけっしてできなくなります。
make-indirect-buffer base-buffer name | コマンド |
base-bufferを基底バッファとするnameという名前の
間接バッファを作成する。
引数base-bufferは、バッファか文字列である。
base-bufferが間接バッファであると、 その基底バッファを新たなバッファの基底バッファとして用いる。 |
buffer-base-buffer buffer | Function |
この関数はbufferの基底バッファを返す。
bufferが間接バッファでなければ、値はnil である。
さもなければ、値は間接バッファではない別のバッファである。
|
本章では、Emacsのウィンドウに関したほとんどの関数と変数について述べます。 ウィンドウにどのようにテキストが表示されるかに関しては、 Displayを参照してください。
Emacsのウィンドウ(window)は、 バッファを表示するスクリーン上の物理的な領域のことです。 この用語は、Emacs Lispにおいて、当該物理領域を表す Lispオブジェクトを意味するためにも使います。 どちらの意味かは文脈から明らかなはずです。
Emacsではウィンドウをフレームにまとめています。 フレームは、Emacsが使えるスクリーンの領域を表します。 各フレームには少なくとも1つのウィンドウがつねにありますが、 フレームは上下や左右に重なり合わない複数のEmacsのウィンドウに分割できます。
ある時点では、各フレームにはフレームの選択されているウィンドウと
区別されるウィンドウがたった1つだけあります。
フレームのカーソルはそのようなウィンドウに現れます。
ある時点では、1つのフレームが選択されているフレームであり、
当該フレームで選択されているウィンドウが選択されているウィンドウです。
選択されているウィンドウのバッファが、
(set-buffer
を使った場合を除いて)普通はカレントバッファです。
See Current Buffer。
実用上、ウィンドウは、それがフレームに表示されている期間だけ存在します。 フレームからいったん取りさると、(ウィンドウへの参照が残っているとしても) ウィンドウは実質的には削除され使えません。 保存したウィンドウ構成を復元する以外に、 スクリーンから消えたウィンドウを戻す方法はありません。 (see Deleting Windows。)
各ウィンドウにはつぎの属性があります。
複数のバッファを同時に見られるようにユーザーは複数のウィンドウを作ります。 さまざまな理由でLispライブラリは複数のウィンドウを使いますが、 そのほとんどは、関連する情報を表示するためです。 たとえば、rmailでは、あるウィンドウのサマリバッファで移動すると、 別のウィンドウでは対応するメッセージを表示します。
Emacsにおける『ウィンドウ』の意味は、 Xのような汎用目的のウィンドウシステムにおける意味に似ていますが、 同一ではありません。 Xウィンドウシステムは、スクリーン上にXのウィンドウを配置します。 Emacsは、1つか複数のXのウィンドウをフレームとして使い、 それらをEmacsのウィンドウに分割します。 文字端末でEmacsを使うと、 Emacsは端末のクリーン全体を1つのフレームとして扱います。
ほとんどのウィンドウシステムは、任意に重ね合わさったウィンドウを扱えます。 対照的に、Emacsのウィンドウはタイル型です。 つまり、互いに重なり合うことはなく、 スクリーンやフレームの全面に敷き詰められます。 Emacsが新たなウィンドウを作成する方法や ウィンドウサイズの変更方法に起因するのですが、 Emacsのフレームを任意の形にウィンドウで敷き詰めることは、 実際には必ずしも可能であるとは限りません。 Splitting WindowsとSee Size of Window。
ウィンドウのバッファの内容がどのようにウィンドウに表示されるかについては、 See Display。
windowp object | Function |
この関数は、objectがウィンドウであればt を返す。
|
ここで述べる関数は、ウィンドウを2つに分割するための基本関数です。
上位レベルの2つの関数、pop-to-buffer
とdisplay-buffer
も
ウィンドウを分割しますが、
つねに分割するとは限りません(see Displaying Buffers)。
ここに述べる関数は、引数にはバッファを受け付けません。 分割されたウィンドウの2つの『部分』には、分割前に表示されていたのと 同じバッファが始めは表示されます。
split-window &optional window size horizontal | コマンド |
この関数はwindowを2つのウィンドウに分割する。
もとのウィンドウwindowは、選択されているウィンドウであり続けるが、
以前のスクリーン領域の一部を占めるだけである。
残りの部分は新たに作成されたウィンドウが占め、
そのウィンドウがこの関数の値として返される。
horizontalが windowを省略したり つぎの例では、50行×80コラムのスクリーン上の1つのウィンドウを分割する。 (setq w (selected-window)) => #<window 8 on windows.texi> (window-edges) ; 順に => (0 0 80 50) ; 左端-上端-右端-下端 ;; 作成したウィンドウを返す (setq w2 (split-window w 15)) => #<window 28 on windows.texi> (window-edges w2) => (0 15 80 50) ; 下側のウィンドウの上端は15行目 (window-edges w) => (0 0 80 15) ; 上側のウィンドウ スクリーンはつぎのようになる。 ┌──────┐ │ │ 0行目 │ w │ │ │ ├──────┤ │ │15行目 │ w2 │ │ │ └──────┘ 50行目 コラム0 コラム80 つぎに上側のウィンドウを左右に分割する。 (setq w3 (split-window w 35 t)) => #<window 32 on windows.texi> (window-edges w3) => (35 0 80 15) ; 左端は35コラム目 (window-edges w) => (0 0 35 15) ; 右端は35コラム目 (window-edges w2) => (0 15 80 50) ; 下側のウィンドウは未変更 スクリーンはつぎのようになる。 コラム35 ┌─┬────┐ │ │ │ 0行目 │w│ w3 │ │ │ │ ├─┴────┤ │ │15行目 │ w2 │ │ │ └──────┘ 50行目 コラム0 コラム80 通常、Emacsは左右に並んだウィンドウの境界を
スクロールバー(see Scroll Bars)か
文字 |
split-window-vertically size | コマンド |
この関数は、選択されているウィンドウを上下に2つに分割する。
上側が選択されているウィンドウのままで、size行の大きさになる。
(sizeが負であると、下側のウィンドウが- size行になり、
上側のウィンドウは残りになる。
しかし、それでも上側が選択されているウィンドウである。)
この関数は (defun split-window-vertically (&optional arg) "Split current window into two windows, ..." (interactive "P") (split-window nil (and arg (prefix-numeric-value arg)))) |
split-window-horizontally size | コマンド |
この関数は、選択されているウィンドウを左右に2つに分割し、
選択されているウィンドウにはsizeコラム残す。
この関数は (defun split-window-horizontally (&optional arg) "Split selected window into two windows, side by side..." (interactive "P") (split-window nil (and arg (prefix-numeric-value arg)) t)) |
one-window-p &optional no-mini all-frames | Function |
この関数は、ウィンドウがたった1つしかなければnil 以外を返す。
引数no-miniがnil 以外であると、
ミニバッファが活性であってもそれを数えないことを意味する。
さもなければ、ミニバッファが活性であればそれも総ウィンドウ個数に数えて
1と比較する。
引数all-framesは、どのフレームを対象にするかを指定する。 指定できる値とその意味はつぎのとおりである。
|
ウィンドウを削除するある種の関数を呼び出して ウィンドウを削除しない限り、 ウィンドウはそのフレームに表示され続けます。 削除されたウィンドウがスクリーンに現れることはありませんが、 それを参照するものがある限りLispオブジェクトととしては 存在し続けます。 保存したウィンドウ構成(see Window Configurations)を復元する以外には、 ウィンドウの削除は取り消せません。 ウィンドウ構成を復元すると、 その構成に含まれないウィンドウはすべて削除されます。
ウィンドウを削除すると、それが使っていた場所は 近接する兄弟ウィンドウの1つに与えられます。
window-live-p window | Function |
この関数は、windowが削除されているとnil を返し、
さもなければt を返す。
警告: |
delete-window &optional window | コマンド |
この関数は、ディスプレイからwindowを取りさり、nil を返す。
windowを省略すると、選択されているウィンドウを削除する。
delete-window を呼び出したときにたった1つのウィンドウしかないと
エラーを通知する。
|
delete-other-windows &optional window | コマンド |
この関数は、windowのフレームにある他のウィンドウを削除して
windowを当該フレームで唯一のウィンドウにする。
windowを省略したりnil であると、
選択されているウィンドウをデフォルトで使う。
これは |
delete-windows-on buffer &optional frame | コマンド |
この関数は、bufferを表示しているすべてのウィンドウを削除する。
bufferを表示しているウィンドウがなければなにもしない。
引数frameは、どのフレームを対象にするかを指定する。
この関数は、すべてのウィンドウを走査する他の関数と同じようには
frameを使わない。
特に、
この関数はつねに |
ウィンドウを選択すると、当該ウィンドウのバッファがカレントバッファになり、 カーソルがそのウィンドウに現れます。
selected-window | Function |
この関数は、選択されているウィンドウを返す。 カーソルが表示され多くのコマンドが作用するウィンドウがそれである。 |
select-window window | Function |
この関数は、windowを選択されているウィンドウにする。
すると、カーソルは(再表示すると)windowに現れる。
windowに表示されているバッファがただちにカレントバッファになる。
戻り値はwindowである。 (setq w (next-window)) (select-window w) => #<window 65 on windows.texi> |
save-selected-window forms... | Macro |
このマクロは、選択されているウィンドウを記録して、
formsを順に実行し、
もとの選択されているウィンドウに戻す。
このマクロは、ウィンドウサイズ、配置、内容に関して いっさいなにも保存したり復元しないので、 formsがそれらを変更するとその変更は持続する。 ある時点で、各フレームにはフレームの選択されているウィンドウがある。 このマクロは、選択されているウィンドウだけを保存し、 他のフレームについてはなにも保存しない。 formsが別のフレームを選択して そのフレームの選択されているウィンドウを変更すると、その変更は持続する。 |
以下の関数は、さまざま条件でスクリーン上のウィンドウの1つを選びます。
get-lru-window &optional frame | Function |
この関数は、もっとも昔に『使われた』
(つまり選択されていた)ウィンドウを返す。
選択されているウィンドウはつねにもっとも最近に使われたウィンドウである。
ウィンドウがたった1つであると、 選択されているウィンドウが もっとも昔に使われたウィンドウであることもありうる。 新たに作成されたウィンドウは、選択されるまではもっとも昔に 使われたウィンドウになる。 ミニバッファ用ウィンドウは候補にはならない。 引数frameは、どのウィンドウを対象とするかを制御する。
|
get-largest-window &optional frame | Function |
この関数は、もっとも大きな領域(高さ×幅)のウィンドウを返す。
左右に並んだウィンドウがなければ、
これがもっとも行数を持つウィンドウである。
ミニバッファ用ウィンドウは候補にはならない。
同じ大きさのウィンドウが2つある場合、 この関数は、選択されているウィンドウから始めて ウィンドウの巡回順序(次節参照)で最初のウィンドウを返す。 引数frameは、ウィンドウのどのような集まりを対象にするかを指定する。
うえの |
つぎのウィンドウを選択するためにコマンドC-x o(other-window
)を
使うと、スクリーン上のすべてのウィンドウをある巡回順序で巡ります。
ウィンドウのある構成において、この順序は変わりません。
これをウィンドウの巡回順序(cyclic ordering of windows)と呼びます。
この順番は一般に上から下、左から右になります。 しかし、ウィンドウを分割した順番に依存して、 下や右が最初になることもあります。
最初に上下に分割してつぎに左右に分割すると、 順番は、フレームの上側で左から右、フレームのその下では左から右 といった具合になります。 最初に左右に分割すると、 順番は、フレームの左側で上から下といった具合になります。 一般に、ウィンドウ木のあるレベルで分割された各兄弟の中では、 順番は、左から右、あるいは、上から下になります。
next-window &optional window minibuf all-frames | Function |
この関数は、ウィンドウの巡回順序においてwindowのつぎの
ウィンドウを返す。
これは、windowが選択されているときに
C-x oが選択するであろうウィンドウである。
windowが唯一の可視ウィンドウであると、
この関数はwindowを返す。
windowを省略すると、デフォルトは選択されているウィンドウである。
引数minibufの値は、ミニバッファを
ウィンドウの順序に含めるかどうかを決定する。
minibufが minibufが minibufが 引数all-framesは、どのフレームを対象にするかを指定する。 可能な値とその意味を以下に示す。
つぎの例では、2つのウィンドウがあり、
どちらもバッファ (selected-window) => #<window 56 on windows.texi> (next-window (selected-window)) => #<window 52 on windows.texi> (next-window (next-window (selected-window))) => #<window 56 on windows.texi> |
previous-window &optional window minibuf all-frames | Function |
この関数は、ウィンドウの巡回順序においてwindowのまえの
ウィンドウを返す。
他の引数は、next-window と同様に、
どのようなウィンドウを巡回に含めるかを指定する。
|
other-window count | コマンド |
この関数は、ウィンドウの巡回順序においてcount番目うしろの
ウィンドウを選択する。
countが負であると、巡回順序において
-count番目まえのウィンドウに戻る。
この関数はnil を返す。
対話的に呼び出すと、countは数値前置引数である。 |
walk-windows proc &optional minibuf all-frames | Function |
この関数は、各ウィンドウごとに当該ウィンドウを唯一の引数として
procを呼び出してすべてのウィンドウを巡る。
省略可能な引数minibufとall-framesは、
走査するウィンドウの集まりを指定する。
詳しくは上記の |
本節では、ウィンドウを調べたり、 正確に制御してウィンドウにバッファを表示する低レベルの関数について述べます。 使用するウィンドウを探したりそれにバッファを指定する関連する関数については、 そこに述べた関数は本節の関数より簡単に使えますが、 それらはウィンドウを選んだり作ったりするときに発見的手法を使います。 完全に制御する必要があるときには、本節の関数を使います。
set-window-buffer window buffer-or-name | Function |
この関数は、windowの内容としてbuffer-or-nameを表示するようにする。
この関数はnil を返す。
これは、ウィンドウに表示するバッファを切り替える
もっとも基本の基本関数であり、
他の切り替え関数はこの関数を呼び出す。
(set-window-buffer (selected-window) "foo") => nil |
window-buffer &optional window | Function |
この関数は、windowに表示しているバッファを返す。
windowを省略すると、この関数は選択されているウィンドウのバッファを返す。
(window-buffer) => #<buffer windows.texi> |
get-buffer-window buffer-or-name &optional all-frames | Function |
この関数は、現在buffer-or-nameを表示しているウィンドウを返す。
そのようなウィンドウがなければnil を返す。
そのようなウィンドウが複数ある場合、
ウィンドウの巡回順序において選択されているウィンドウから始めて
最初にみつかったウィンドウを返す。
see Cyclic Window Ordering。
引数all-framesは、どのウィンドウを対象とするかを制御する。
|
get-buffer-window-list buffer-or-name &optional minibuf all-frames | Function |
この関数は、現在buffer-or-nameを表示している
すべてのウィンドウのリストを返す。
省略可能な2つの引数は、 引数all-framesは、どのウィンドウを対象とするかを制御する。
|
buffer-display-time | Variable |
この変数は、バッファがウィンドウで見えるようになった最後の時刻を記録する。
この変数は各バッファでつねにバッファローカルであり、
set-window-buffer は、呼ばれるたびに
指定されたバッファのこの変数に(current-time) を設定する
(see Time of Day)。
バッファが初めて作られると、buffer-display-time は値nil で始まる。
|
本節では、ウィンドウを自動的に選びそれに指定したバッファを表示する
便利な関数について述べます。
これらの関数は、ある状況では、既存のウィンドウを分割します。
ウィンドウを選ぶ際の発見的手法を制御する変数についても述べます。
より正確に制御するための低レベルの関数については、
これらの関数はすべてset-window-buffer
を呼び出して動作します。
バッファをカレントバッファにしてLispプログラムで参照したり変更できるように
するためには、本節の関数を使わないでください。
これらはその目的には強力すぎます。
ウィンドウのバッファの表示をユーザーにとっては迷惑で驚くようなものに
変更してしまうからです。
そのかわりに、ウィンドウのバッファの表示には影響せずに
バッファをプログラムから参照するためにカレントバッファにする
set-buffer
とsave-current-buffer
(see Current Buffer)を
使います。
switch-to-buffer buffer-or-name &optional norecord | コマンド |
この関数は、buffer-or-nameをカレントバッファにし、
さらに、選択されているウィンドウに当該バッファを表示する。
つまり、人間が当該バッファを見ることができるようになり、
以降のキーボードコマンドは当該バッファに適用される。
buffer-or-nameをカレントバッファにするが
選択されているウィンドウには表示しないset-buffer と比較してほしい。
see Current Buffer。
buffer-or-nameが既存のバッファを指定しなければ、
その名前の新たなバッファが作成される。
新たなバッファのメジャーモードは変数 通常、指定したバッファはバッファリスト
(選択されているフレームのバッファリストとフレーム独立のバッファリストの
両方)の先頭に置かれる。
これは、 関数 |
switch-to-buffer-other-window buffer-or-name &optional norecord | コマンド |
この関数は、buffer-or-nameをカレントバッファにし、
現在選択されていないウィンドウに当該バッファを表示する。
そして当該ウィンドウを選択する。
バッファの扱い方はswitch-to-buffer と同じである。
現在選択されているウィンドウは、この処理には絶対に使わない。 それが唯一のウィンドウである場合には、この目的のために ウィンドウを分割して別のウィンドウを作る。 選択されているウィンドウがすでに当該バッファを表示している場合には、 当該ウィンドウはそのまま表示し続けるが、それにも関わらず、 表示するために別のウィンドウを探す。 この関数は、norecordが |
pop-to-buffer buffer-or-name &optional other-window norecord | Function |
この関数は、buffer-or-nameをカレントバッファにし、
以前には選択されていない別のウィンドウで当該バッファに切り替える。
そのウィンドウがそのフレームの選択されているウィンドウになる。
変数
変数 other-windowが
buffer-or-nameが文字列であり既存のバッファを指定しない場合、
その名前のバッファを作成する。
新たなバッファのメジャーモードは変数 この関数は、norecordが |
replace-buffer-in-windows buffer | コマンド |
この関数は、bufferを表示しているすべてのウィンドウにおいて
bufferを別のバッファに切り替える。
別のバッファはother-buffer で選ぶ。
この関数の普通の用途は、別のバッファがどれになるか気にしない場合である。
つまり、bufferが表示されていないことを保証したい場合である。
この関数は |
本節では、バッファを表示するためのウィンドウを選ぶための基本的な機能、
display-buffer
について述べます。
上位レベルの関数やコマンドはすべてこのサブルーティンを使います。
ここでは、display-buffer
の使い方とカスタマイズ方法を説明します。
display-buffer buffer-or-name &optional not-this-window frame | コマンド |
このコマンドは、pop-to-buffer のように、
buffer-or-nameをあるウィンドウに表示するが、
そのウィンドウを選択しないので当該バッファもカレントバッファにならない。
この関数は、選択されているウィンドウを変えない。
not-this-windowが
引数frameが
|
pop-up-windows | User Option |
この変数は、display-buffer が新たにウィンドウを作るかどうかを制御する。
nil 以外であり、かつ、ウィンドウがたった1つである場合、
そのウィンドウを分割する。
nil であると、display-buffer は
単一のウィンドウを分割せずにそれ全体を使う。
|
split-height-threshold | User Option |
この変数は、ウィンドウが複数ある場合に
display-buffer がどの時点でウィンドウを分割するかを決定する。
display-buffer は、最大ウィンドウの行数が
この変数による指定行数より大きければ、最大ウィンドウをつねに分割する。
最大ウィンドウがこれだけ大きくない場合には、
それが唯一のウィンドウであり、かつ、pop-up-windows がnil 以外
の場合にのみ最大ウィンドウを分割する。
|
pop-up-frames | User Option |
この変数は、display-buffer が新たなフレームを作るかどうかを制御する。
nil 以外であると、display-buffer は、
すべての可視フレームから指定されたバッファをすでに表示している
既存のウィンドウを探す。
そのようなウィンドウがあれば、そのウィンドウを返す。
さもなければ、新たなフレームを作る。
変数pop-up-frames がnil 以外であると、
変数pop-up-windows とsplit-height-threshold は影響しない。
詳しくは、see Frames。 |
pop-up-frame-function | Variable |
この変数は、pop-up-frames がnil 以外であるときに
どのように新たなフレームを作るかを指定する。
その値は引数なしの関数であること。
|
pop-up-frame-alist | Variable |
この変数は、display-buffer が新たにフレームを作るときに
使用するフレームパラメータを指定する連想リストを保持する。
フレームパラメータに関して詳しくは、
see Frame Parameters。
|
special-display-buffer-names | User Option |
特別に表示すべきバッファのバッファ名のリスト。
バッファ名がこのリストにあると、
display-buffer は当該バッファを特別に扱う。
デフォルトでは、特別に表示するとは、 専用のフレームにバッファを表示することである。 リストの要素が文字列でなくリストであると、 リストのCARがバッファ名であり、 リストの残りはフレームの作成方法を指定する。 それは、フレームパラメータを指定する連想リストであるか、 関数とそれに渡す引数である。 (関数の第1引数はつねに表示すべきバッファである。 そのあとにリスト内の引数が続く。) |
special-display-regexps | User Option |
特別に表示すべきバッファを指定する正規表現のリスト。
バッファ名がこのリストのいずれかの正規表現に一致すると、
display-buffer は当該バッファを特別に扱う。
デフォルトでは、特別に表示するとは、 専用のフレームにバッファを表示することである。 リストの要素が文字列でなくリストであると、
リストのCARが正規表現であり、
リストの残りはフレームの作成方法を指定する。
上記の |
special-display-function | Variable |
この変数は、バッファを特別に表示するために呼び出す関数を保持する。
引数としてバッファを受け取り、
当該バッファを表示したウィンドウを返すこと。
この関数のデフォルト値は |
special-display-popup-frame buffer | Function |
この関数は、bufferをそれ専用のフレームに表示する。
あるフレームのウィンドウにbufferがすでに表示されている場合、
当該ウィンドウを使うために当該フレームを可視にし手前に持ってくる。
さもなければ、buffer用にフレームを作成する。
この関数は、bufferを表示している既存のウィンドウのフレームで 当該バッファだけを表示しているかどうかに関わらず、 既存の当該ウィンドウを使う。 しかし、bufferを作るまえに読者の初期化ファイルで上記の変数に設定 しているときには、当該ウィンドウは以前にこの関数が作成したものであろう。 |
special-display-frame-alist | User Option |
この変数は、special-display-popup-frame がフレームを作るときに
使用するフレームパラメータを保持する。
|
same-window-buffer-names | User Option |
選択されているウィンドウに表示すべきバッファのバッファ名のリスト。
バッファ名がこのリストにあると、
display-buffer は選択されているウィンドウで当該バッファに切り替える。
|
same-window-regexps | User Option |
選択されているウィンドウに表示すべきバッファを指定する正規表現のリスト。
バッファ名がこのリストのいずれかの正規表現に一致すると、
display-buffer は選択されているウィンドウで当該バッファに切り替える。
|
display-buffer-function | Variable |
この変数は、display-buffer のふるまいをカスタマイズする
もっとも柔軟な方法である。
nil 以外であると、display-buffer が処理を依頼するために
呼び出す関数であること。
その関数は、display-buffer が受け取るのと同じ2つの引数を受け付けること。
その関数は、ウィンドウを選ぶか作成し、指定されたバッファを表示し、
当該ウィンドウを返すこと。
このフックは、上に述べた他のオプションやフックすべてに優先する。 |
ウィンドウにはそのバッファ『専用』と印を付けられます。
そうすると、display-buffer
は他のバッファを表示するために
当該ウィンドウを使わないようにします。
window-dedicated-p window | Function |
この関数は、windowに専用と印が付いていればt を返し、
さもなければnil を返す。
|
set-window-dedicated-p window flag | Function |
この関数は、flagがnil 以外であるとwindowに専用の印を付け、
さもなければ専用の印を消す。
|
各ウィンドウには、同じバッファを表示している 別のウィンドウのポイントの値とは独立な独自のポイントの値があります。 これにより、あるバッファを複数のウィンドウに表示しても有用なのです。
ユーザーにとっては、ポイントとはカーソルが置かれた箇所であり、 別のバッファに切り替えるとそのバッファのポイント位置に カーソルが移動します。
window-point window | Function |
この関数は、windowの現在のポイント位置を返す。
選択されていないウィンドウでは、
当該ウィンドウを選択したときになるであろう
(ウィンドウのバッファの)ポイント値である。
windowが選択されているウィンドウであり、かつ、 そのバッファがカレントバッファであれば、 戻り値は当該バッファのポイントと同じである。 厳密にいえば、すべてのフォーム |
set-window-point window position | Function |
この関数は、windowのバッファ内の位置positionを windowのポイント位置とする。 |
各ウィンドウには、バッファのどの箇所から表示を始めるかを指定する バッファ内位置を追跡するために使うマーカがあります。 この位置をウィンドウの表示開始(display-start)位置 (あるいは単に開始(start)位置)と呼びます。 この位置の直後にある文字が、ウィンドウの左上隅に現れます。 この位置は、通常、テキスト行の先頭にありますが、必須ではありません。
window-start &optional window | Function |
この関数は、ウィンドウwindowの表示開始位置を返す。
windowがnil であると、
選択されているウィンドウを使う。
たとえばつぎのとおりである。
(window-start) => 7058 新たにウィンドウを作成したり異なるバッファをウィンドウに表示すると、 表示開始位置は、当該バッファの最近に使われた表示開始位置になるか、 バッファに表示開始位置がなければ1になる。 再表示するとウィンドウ開始位置は (それ以前の再表示で明示的に位置を指定していなければ)、 ポイントがスクリーンに現れるように更新される。 再表示以外には、ウィンドウ開始位置を自動的に変更しない。 ポイントを移動しても、つぎの再表示までは、 連動してウィンドウ開始位置が変更されると期待しないこと。
|
window-end &optional window update | Function |
この関数は、ウィンドウwindowの表示の末尾の位置を返す。
windowがnil であると、選択されているウィンドウを使う。
バッファのテキストを変更したりポイントを移動しただけでは、
windowの最後の再表示が途中で止められて完了していないと、 当該ウィンドウの表示の末尾の位置はEmacsにはわからない。 updateが |
set-window-start window position &optional noforce | Function |
この関数は、windowの表示開始位置を
windowのバッファ内の位置positionとする。
これはpositionを返す。
表示ルーティンは、バッファを表示するときには
ポイント位置が可視であることを強要する。
通常、表示ルーティンは、ポイントを可視にするために必要なときには
表示開始位置を(つまりウィンドウをスクロールして)変更する。
しかし、noforceに たとえば、ポイントが1にあるときに ウィンドウの開始位置を2にしたとすると、 ポイントはウィンドウの上端より『上』になる。 表示ルーティンは、再表示時にポイントが1のままであると 自動的にポイントを移動する。 以下に例を示す。 ;; 式 noforceが |
pos-visible-in-window-p &optional position window | Function |
この関数は、window内のpositionがスクリーン上で
現在可視なテキストの範囲内にあればt を返す。
positionがスクリーンの上下端からはみ出す場合にはnil を返す。
引数positionのデフォルトはポイントの現在位置であり、
windowのデフォルトは選択されているウィンドウである。
例を示す。
(or (pos-visible-in-window-p (point) (selected-window)) (recenter 0)) 関数 |
垂直スクロールとは、ウィンドウ内のテキストを上向きや下向きに動かすことです。
ウィンドウの表示開始位置の値を変更することで動作します。
ポイントがスクリーン内に留まるようにwindow-point
の
値を変更することもあります。
コマンドscroll-up
やscroll-down
の
方向を示す『up』(上向き)と『down』(下向き)は、
ウィンドウを見ているときのバッファ内のテキストの移動方向を表します。
テキストは縦に長い紙に(横書きで)書いてあり、
スクロールコマンドはその紙を上下に動かすと想像してください。
したがって、バッファの中ほどのテキストを見ているときに
scroll-down
を繰り返し呼び出すと、
最終的にはバッファの先頭を見ることになります。
逆の慣習の名前を使うべきだと主張する人々もいます。 彼らは、固定されたテキストのうえをウィンドウが動いていると想像するのです。 すると、『下向き』のコマンドはバッファの末尾に移動することになります。 この見方は、ウィンドウとバッファ内のテキストとの実際の関係に よく適合しているのですが、ユーザーはそのように考えないようです。 端末上ではウィンドウは動きませんし、スクロールコマンドは 明らかにテキストをスクリーン上で上下に動かしています。 ユーザーの視点に合う名称を選んだのです。
カレントバッファと選択されているウィンドウに
表示されているバッファとが異なる場合には、
(scroll-other-window
以外の)スクロール関数の結果は予測できません。
See Current Buffer。
scroll-up &optional count | コマンド |
この関数は、選択されているウィンドウのテキストを
上向きにcount行だけスクロールする。
countが負であると、実際のスクロール方向は下向きである。
countが
|
scroll-down &optional count | コマンド |
この関数は、選択されているウィンドウのテキストを
下向きにcount行だけスクロールする。
countが負であると、実際のスクロール方向は上向きである。
countが
|
scroll-other-window &optional count | コマンド |
この関数は、別のウィンドウのテキストを上向きに
count行だけスクロールする。
countの値が負であったりnil であると、
scroll-up と同様に扱う。
変数 ミニバッファが活性であると、
右下隅のウィンドウが選択されているウィンドウであるときには、
つぎのウィンドウはミニバッファ用ウィンドウである。
この場合、 |
other-window-scroll-buffer | Variable |
この変数がnil 以外であると、
scroll-other-window がスクロールするバッファを指定する。
|
scroll-margin | User Option |
このオプションは、スクロール時の余白の大きさ、 つまり、ポイントとウィンドウの上端や下端とのあいだにある最低行数を指定する。 ウィンドウの上端や下端からこの行数以内にポイントが移動するたびに、 (可能ならば)ウィンドウを自動的にスクロールして、 ポイントを余白の外側でウィンドウの中央近くに移動する。 |
scroll-conservatively | User Option |
この変数は、ポイントがスクリーンからはみ出したとき (あるいはスクロール時の余白に入ったとき)に どのように自動的にスクロールするかを制御する。 値が0であると、ウィンドウの縦方向でポイントが中央にくるように テキストをスクロールして再表示する。 値が正の整数nであると、 ウィンドウをどちらかの方向に最大n行だけスクロールすると ポイントが見えるようになるときには、そのようにスクロールして再表示する。 さもなければ、ポイントが中央にくるようにする。 デフォルト値は0である。 |
scroll-step | User Option |
この変数は、scroll-conservatively の古い変種である。
違いは、値がnであると正確にn行だけのスクロールを許すことである。
この機能はscroll-margin では働かない。
デフォルト値は0である。
|
scroll-preserve-screen-position | User Option |
このオプションがnil 以外であると、
スクロール関数は、可能ならばカーソルの垂直方向の位置を
変えないようにポイントを移動する。
|
next-screen-context-lines | User Option |
この変数の値は、1画面分スクロールしたときに連続して残っている行数である。
たとえば、引数nil のscroll-up は、
ウィンドウの下端にあるこの行数だけの行が上端にくるようにスクロールする。
デフォルト値は2 である。
|
recenter &optional count | コマンド |
この関数は、選択されているウィンドウをスクロールして
ポイント位置にあるテキストがウィンドウ内の垂直方向の指定位置にくるようにする。
countが非負の数であると、ポイント位置にある行を
ウィンドウの上端からcount行下にくるようにする。
countが負の数であると、ウィンドウの下端から数え、
-1はウィンドウの使用可能な最後の行を表す。
countが countが
引数が0であると、
(defun line-to-top-of-window () "Scroll current line to top of window. Replaces three keystroke sequence C-u 0 C-l." (interactive) (recenter 0)) (global-set-key [kp-multiply] 'line-to-top-of-window) |
英文は『内側のループ』では左から右へ『外側のループ』では上から下へと読むので、
水平スクロールは垂直スクロールには似ていません。
垂直スクロールでは表示するテキストの連続部分を選びますが、
水平スクロールでは各行の一部がスクリーンからはみ出すことになります。
そのため、水平スクロールの量は、バッファ内の位置ではなく、
コラム数で指定します。
これは、window-start
が返す表示開始位置とはなんの関係もありません。
通常、水平スクロールは行われません。 つまり、左端のコラムはウィンドウの左端にあります。 この状態で右向きにスクロールしても、 それによって見えてくるスクリーンの左側にはなにもないので意味がありません。 ですから、これは禁止されます。 左向きへのスクロールは許されて、 テキストの先頭コラムはウィンドウの端からはみ出し、 それまで切り詰められていた右側のコラムが見えるようになります。 左向きの水平スクロール量が0でなければ、 右向きへスクロールして戻せますが、 これは全体としての水平スクロール量が0になるまでです。 左向きスクロールの限界はありませんが、 最終的にはテキストすべてが左端からはみ出してしまいます。
scroll-left count | コマンド |
この関数は、選択されているウィンドウをcountコラムだけ
左向きに(countが負ならば右向きに)スクロールする。
戻り値は、変更後の左向き水平スクロール量の総量であり、
window-hscroll (下記参照)が返す値と同じである。
|
scroll-right count | コマンド |
この関数は、選択されているウィンドウをcountコラムだけ
右向きに(countが負ならば左向きに)スクロールする。
戻り値は、変更後の左向き水平スクロール量の総量であり、
window-hscroll (下記参照)が返す値と同じである。
可能なだけウィンドウを右向きにスクロールしてしまうと、 通常の状態、つまり、左向き水平スクロール量が0になり、 それ以降、右向きスクロールは効果がなくなる。 |
window-hscroll &optional window | Function |
この関数は、windowの左向き水平スクロール量の総量、
つまり、windowのテキストが左端を超えてスクロールされたコラム数を返す。
値はけっして負にはならない。 windowが水平方向にスクロールされていなければ (これが通常の状態)0である。 windowが (window-hscroll) => 0 (scroll-left 5) => 5 (window-hscroll) => 5 |
set-window-hscroll window columns | Function |
この関数は、windowのスクロールされている左端からのコラム数を
columnsの値とする。
引数columnsは0か正であること。
さもないと0と仮定する。
戻り値は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)))))
Emacsのウィンドウは矩形であり、そのサイズ情報は
高さ(行数)と幅(各行の文字数)から成ります。
モード行は高さに含みます。
しかし、スクロールバーや左右のウィンドウを隔てる文字|
のコラムは
幅には含みません。
つぎの3つの関数は、ウィンドウのサイズ情報を返します。
window-height &optional window | Function |
この関数は、モード行を含むwindowの行数を返す。
windowがフレーム全体を占める場合、この値は典型的には、
当該フレームにおけるframe-height の値より1小さい
(最後の行はミニバッファ用につねに確保してあるため)。
windowが (window-height) => 23 (split-window-vertically) => #<window 4 on windows.texi> (window-height) => 11 |
window-width &optional window | Function |
この関数は、windowのコラム数を返す。
windowがフレーム全体を占める場合、この値は、
当該フレームにおけるframe-width の値と同じである。
この幅には、ウィンドウのスクロールバーや
左右のウィンドウを隔てる文字| のコラムは含まない。
windowが (window-width) => 80 |
window-edges &optional window | Function |
この関数は、windowの四隅の座標から成るリストを返す。
windowがnil であると、選択されているウィンドウを使う。
list内の順番は 左右に隣り合ったウィンドウがある場合、
右隣にウィンドウがあるウィンドウの右端の値には、
ウィンドウを隔てる区切りの幅が含まれる。
この区切りは、文字 典型的な24行の端末でウィンドウが1つの場合に得られる結果を示す。 (window-edges (selected-window)) => (0 0 80 23) 下端が23行目であるのは、最下行はエコー領域だからである。 windowがフレームの左上隅にあると、
bottomは 0 _______ 0 | | | | | | | | xxxxxxxxx 4 7 左右に隣り合ったウィンドウがあるときには、 フレームの右端にないウィンドウの最後のコラムは区切りである。 区切りは、ウィンドウの幅では1コラムか2コラム占める。 左側の区切りは左隣のウィンドウに属するので、 ウィンドウには左側の区切りは含まれない。 つぎの例では、フレームは7コラム幅であるとする。
すると、左側のウィンドウの四隅は ___ ___ | | | | | | xxxxxxxxx 0 34 7 |
ウィンドウサイズ関数は2つに大別できます。 ウィンドウサイズを変える上位レベルのコマンドと ウィンドウサイズを調べる下位レベルの関数です。 Emacsでは重なり合ったウィンドウやウィンドウのあいだに隙間を許さないので、 1つのウィンドウの大きさを変えると別のウィンドウにも影響します。
enlarge-window size &optional horizontal | コマンド |
この関数は、隣り合うウィンドウから場所を奪って、
選択されているウィンドウをsize行高くする。
1つのウィンドウから場所を奪い取り、奪い尽くすと別のウィンドウから取る。
場所を奪われたウィンドウがwindow-min-height 行未満になると、
そのウィンドウは消える。
horizontalが 指定した大きさがウィンドウのフレームの大きさを超える場合、 この関数は、ウィンドウがフレームの高さ(あるいは幅)全体を占めるようにする。 sizeが負であると、この関数は-size行/コラムだけ
ウィンドウを縮める。
ウィンドウが(
|
enlarge-window-horizontally columns | コマンド |
この関数は、選択されているウィンドウをcolumnsコラム広くする。
(defun enlarge-window-horizontally (columns) (enlarge-window columns t)) |
shrink-window size &optional horizontal | コマンド |
この関数はenlarge-window に似ているが引数sizeの符号を変えて、
選択されているウィンドウを縮めて指定行数(コラム数)を
他のウィンドウに与える。
ウィンドウがwindow-min-height やwindow-min-width 未満に縮むと、
そのウィンドウは消える。
sizeが負であると、ウィンドウは -size行/コラムだけ伸びる。 |
shrink-window-horizontally columns | コマンド |
この関数は、選択されているウィンドウをcolumnsコラム狭くする。
つぎのように定義できる。
(defun shrink-window-horizontally (columns) (shrink-window columns t)) |
shrink-window-if-larger-than-buffer window | コマンド |
このコマンドは、バッファの全内容を表示するに十分なだけの大きさに
windowを縮めるが、window-min-height 行未満にはしない。
しかし、バッファの全テキストを表示するにはウィンドウが小さすぎる場合や、 内容の一部がスクロールでスクリーンからはみ出している場合や、 ウィンドウの幅がフレームの幅と同じでない場合や、 ウィンドウがフレームの唯一のウィンドウである場合には、 このコマンドはなにもしない。 |
つぎの2つの変数は、ウィンドウサイズを変える関数に最小の高さと幅を課します。
window-min-height | User Option |
この変数の値は、ウィンドウが自動的に削除されるまでに
どの程度までウィンドウが短くなりうるかを決定する。
ウィンドウをwindow-min-height 行未満に小さくすると自動的に削除され、
これより短いウィンドウは作成できない。
絶対的な最小の高さは2行(モード行に1行、バッファの表示に1行)である。
ウィンドウサイズを変える処理では、この変数が2未満であると2に設定し直す。
デフォルト値は4である。
|
window-min-width | User Option |
この変数の値は、ウィンドウが自動的に削除されるまでに
どの程度までウィンドウが狭くなりうるかを決定する。
ウィンドウをwindow-min-width コラム未満に小さくすると自動的に削除され、
これより狭いウィンドウは作成できない。
絶対的な最小の幅は1であり、それ未満は無視する。
デフォルト値は10である。
|
本節では、スクリーン座標をウィンドウに関連付ける方法を述べます。
window-at x y &optional frame | Function |
この関数は、フレームframeにおいて指定したカーソル位置を含んでいる
ウィンドウを返す。
座標xとyは、フレームの左上隅から文字単位で数える。
座標が範囲外であるとwindow-at はnil を返す。
frameを省略すると、選択されているフレームを使う。 |
coordinates-in-window-p coordinates window | Function |
この関数は、指定したフレーム位置がウィンドウwindowの中に
入るかどうかを検査する。
引数coordinatesは、
関数 |
ウィンドウ構成(window configuration)は、 1つのフレームの全体の配置、つまり、 すべてのウィンドウ、それらの大きさ、表示しているバッファ、 各バッファの表示位置、ポイントとマークの値を記録します。 保存しておいたウィンドウ構成を復元すれば、 まえとまったく同じ配置に戻せます。
1つのフレームではなくすべてのフレームを記録するには、 ウィンドウ構成のかわりにフレーム構成を使います。 See Frame Configurations。
current-window-configuration | Function |
この関数は、選択されているフレームの現在のウィンドウ構成を表す
新たなオブジェクトを返す。
ウィンドウ構成には、ウィンドウの個数、それらの大きさとカレントバッファ、
どのウィンドウが選択されているウィンドウであるか、
各ウィンドウが表示しているバッファ、表示開始位置、
ポイントとマークの位置が含まれる。
window-min-height 、window-min-width 、
minibuffer-scroll-window の値も含む。
例外はカレントバッファのポイントであり、その値は保存されない。
|
set-window-configuration configuration | Function |
この関数は、configurationで指定される
ウィンドウとバッファの構成に復元する。
引数configurationは、
current-window-configuration が返した値であること。
configurationを作成したフレームにおいて、
そのフレームが選択されているかどうかに関わらず、この構成を復元する。
set-window-configuration は、新たな構成が古いものと
実際に異なるのかどうか識別する方法を知らないため、
ウィンドウサイズの変更とつねにみなして
window-size-change-functions (see Window Hooks)の
実行を引き起こす。
configurationを保存したフレームがなくなっていると、
この関数は、3つの変数、
(let ((config (current-window-configuration))) (unwind-protect (progn (split-window-vertically nil) ...) (set-window-configuration config))) |
save-window-excursion forms... | Special Form |
このスペシャルフォームは、ウィンドウ構成を記録し、
formsを順に評価し、もとのウィンドウ構成に復元する。
ウィンドウ構成には、ポイントの値と可視なバッファの部分が含まれる。
また、選択されているウィンドウも含む。
しかし、これにはカレントバッファのポイント値は含まれないため、
ポイント位置を保存したい場合にはsave-excursion も使う。
戻り値は、formsの最後のフォームの値である。 例を示す。 (split-window) => #<window 25 on control.texi> (setq w (selected-window)) => #<window 19 on control.texi> (save-window-excursion (delete-other-windows w) (switch-to-buffer "foo") 'do-something) => do-something ;; スクリーンはここでふたたび分割される |
window-configuration-p object | Function |
この関数は、objectがウィンドウ構成であればt を返す。
|
compare-window-configurations config1 config2 | Function |
この関数は、ウィンドウの構造を基に2つのウィンドウ構成を比較する。
ポイントとマークの値、保存されたスクロール位置は無視するので、
それらが異なっていてもt を返す。
関数 |
ウィンドウ構成の内部を調べる基本関数には意味があるでしょうが、 実装してありません。 実装するだけの価値があるほど有用なのかはっきりしないのです。
本節では、ウィンドウにバッファの別の部分を表示したり
別のバッファを表示するたびに、
Lispプログラムが動作する方法を述べます。
変更できる動作は3種類、ウィンドウをスクロールするとき、
ウィンドウでバッファを切り替えるとき、
ウィンドウサイズを変えるときです。
最初の2つの動作ではwindow-scroll-functions
を実行し、
3つ目はwindow-size-change-functions
を実行します。
これらのフックの模範的な使用例は遅延ロック(lazy-lock)モードの
実装の中にあります。
Support Modesを参照してください。
window-scroll-functions | Variable |
この変数は、スクロールによりウィンドウを再表示するまえに
Emacsが呼び出すべき関数のリストを保持する。
各関数はウィンドウと新たな表示開始位置の2つの引数で呼ばれるため、
これはノーマルフックではない。
ウィンドウに別のバッファを表示する場合でも これらの関数が実行される。 これらの関数で |
window-size-change-functions | Variable |
この変数は、いかなる理由であれウィンドウサイズが変わるときに
呼び出される関数のリストを保持する。
関数は、再表示のたびにサイズ変更が起きたフレームごとに呼ばれる。
各関数はフレームを唯一の引数として受け取る。 当該フレームで大きさが変更されたウィンドウを探す直接的な方法や 正確な方法はない。 しかし、サイズ変更関数が呼ばれるたびに 既存のウィンドウとそれらの大きさを記録すれば、 現在の大きさと以前の大きさを比較できる。 ウィンドウを作成したり削除してもサイズ変更とみなすので、 これらの関数が呼び出される。 フレームの大きさが変わると既存のウィンドウの大きさも変わるので、 これもサイズ変更とみなす。 これらの関数で |
redisplay-end-trigger-functions | Variable |
このアブノーマルフックは、ウィンドウの再表示において、
指定された終了トリガ位置を超えて伸びるテキストを使うたびに実行される。
終了トリガ位置は関数set-window-redisplay-end-trigger で設定する。
フック関数は2つの引数、ウィンドウと終了トリガ位置で呼ばれる。
終了トリガ位置としてnil を保存するとこの機能をオフにし、
フックを実行直後にトリガ値は自動的にnil に再設定される。
|
set-window-redisplay-end-trigger window position | Function |
この関数は、windowの終了トリガ位置をpositionとする。 |
window-redisplay-end-trigger window | Function |
この関数は、windowの現在の終了トリガ位置を返す。 |
window-configuration-change-hook | Variable |
このノーマルフックは、 既存のフレームのウィンドウの構成を変更するたびに呼び出される。 これには、ウィンドウの分割や削除、ウィンドウサイズの変更、 ウィンドウに別のバッファを表示することが含まれる。 このフックを実行するときには、 ウィンドウの構成が変更されたフレームが選択されているフレームである。 |
フレーム(frame)とは、1つかそれ以上のEmacsのウィンドウを 収めているスクリーン上の矩形です。 フレームには最初は1つのウィンドウ(およびミニバッファ用ウィンドウ)が ありますが、それを上下や左右に小さなウィンドウに分割できます。
Emacsを文字端末で実行すると、 1つの端末フレーム(terminal frame)を使います。 別のフレームを作成すると、もちろん端末画面上では、 Emacsは一度に1つのフレームしか表示しません。
EmacsがXウィンドウのような対応しているウィンドウシステムと 直接通信しているときには、端末フレームは使いません。 そのかわりに、1つのウィンドウフレーム(window frame)で始まりますが、 いくつでもフレームを作れますし、ウィンドウシステムでは普通のことですが、 Emacsはそのようなフレームを同時に複数表示できます。
framep object | Function |
この関数は、objectがフレームならばt を返し、
さもなければnil を返す。
|
Emacsの再表示の制御に関連する情報についてはSee Display。
新たなフレームを作成するには、関数make-frame
を呼び出します。
make-frame &optional alist | Function |
この関数は新たなフレームを作成する。
対応しているウィンドウシステムを使っていれば、ウィンドウフレームを作る。
さもなければ端末フレームを作る。
引数alistはフレームパラメータを指定する連想リストである。
alistで指定していないパラメータは、
変数 指定可能なパラメータは、Emacsがフレームの表示に使う ウィンドウシステムの種類に原理的には依存します。 指定可能な各パラメータの説明は、see Window Frame Parameters。 |
before-make-frame-hook | Variable |
make-frame がフレームを実際に作成する直前に実行するノーマルフック。
|
after-make-frame-hook | Variable |
make-frame がフレームを作成後に実行するアブノーマルフック。
after-make-frame-hook の各関数は、1つの引数、
つまり、作成したばかりのフレームを受け取る。
|
1つのEmacsは複数のXディスプレイと通信できます。
Emacsは始めは1つのディスプレイ、つまり、
環境変数DISPLAY
かオプション--display
(see Initial Options)で決まる
ものを使います。
別のディスプレイに接続するには、
コマンドmake-frame-on-display
を使うか、
フレームを作るときにフレームパラメータdisplay
を指定します。
Emacsは各Xサーバーを別々の端末として扱い、 それらのおのおのには選択されているフレームと ミニバッファ用ウィンドウがあります。
少数のLisp変数は端末にローカル(terminal-local)です。
つまり、各端末ごとに別々の束縛があります。
ある時点で有効な束縛は、選択されているフレームが属する端末のものです。
このような変数には、default-minibuffer-frame
、
defining-kbd-macro
、last-kbd-macro
、
system-key-alist
があります。
これらはつねに端末にローカルであり、
バッファローカル(see Buffer-Local Variables)や
フレームローカルにはけっしてなりません。
1つのXサーバーは複数のスクリーンを扱えます。
ディスプレイ名host:server.screen
には3つの部分があり、
最後の部分で指定したサーバーのスクリーン番号を指定します。
1つのサーバーに属する2つのスクリーンを使うと、
Emacsはそれらの名前の類似性からそれらが1つのキーボードを共有していると判断し、
それらのスクリーンを1つの端末として扱います。
make-frame-on-display display &optional parameters | コマンド |
新たなフレームをディスプレイdisplay上に作成する。
他のフレームパラメータはparametersから得る。
引数displayを除けばmake-frame (see Creating Frames)と
同様である。
|
x-display-list | Function |
Emacsが接続しているXディスプレイを表すリストを返す。 リストの要素は文字列であり、それぞれはディスプレイ名である。 |
x-open-connection display &optional xrm-string | Function |
この関数はXディスプレイdisplayとの接続を開く。
当該ディスプレイ上にフレームは作らないが、
これにより当該ディスプレイと通信可能かどうか検査できる。
省略可能な引数xrm-stringが "*BorderWidth: 3\n*InternalBorder: 2\n" see Resources。 |
x-close-connection display | Function |
この関数はディスプレイdisplayとの接続を閉じる。 これを行うまえに、 まず当該ディスプレイ上に作ったフレームをすべて削除しておくこと。 |
フレームには、その見ためやふるまいを制御する多くのパラメータがあります。 フレームのパラメータの種類は、使用する表示機構に依存します。
フレームパラメータはウィンドウシステム向けです。
端末フレームにはごく少数のパラメータがありますが、
そのほとんどは互換性のためであり、
height
、width
、name
、title
、
buffer-list
、buffer-predicate
のパラメータだけが意味を持ちます。
これらの関数は、フレームのパラメータの値を読んだり変更するためのものです。
frame-parameters frame | Function |
関数frame-parameters は、
frameのすべてのパラメータとそれらの値から成る連想リストを返す。
|
modify-frame-parameters frame alist | Function |
この関数は、alistの要素に基づいてフレームframeの
パラメータを変更する。
alistの各要素は(parm . value) の形であり、
parmはパラメータを表すシンボルである。
alistに指定しないパラメータの値は変更されない。
|
読者のファイル.emacs
でinitial-frame-alist
に設定すれば、
起動時の初期フレームのパラメータを指定できます。
initial-frame-alist | Variable |
この変数の値は、初期フレームを作るときに
使用するパラメータの値から成る連想リストである。
この変数を指定すれば初期フレームの見ためを指定できるが、
それ以降に作成するフレームには影響しない。
各要素はつぎの形である。
(parameter . value) Emacsは読者のファイル これらの設定がフレームの大きさと位置や見ために関するものであると、 指定とは違うフレームが現れてから指定したものに変わるのを目にする。 これがわずらわしい場合には、Xリソースにも同じ大きさと位置や見ためを指定する。 Xリソースはフレームを作成するまえに適用される。 see Resources X。 Xリソースの設定は、典型的にはすべてのフレームに適用される。
初期フレームだけに特定のXリソースを指定し、
それ以降のフレームに適用したくない場合には、つぎのようにする。
パラメータを |
これらのパラメータにミニバッファ専用のフレームを作る
(minibuffer . nil)
を指定しているのに
ミニバッファ専用フレームを作っていないと、Emacsがそれを作成します。
minibuffer-frame-alist | Variable |
この変数の値は、初期のミニバッファ専用フレームを作るときに使用する パラメータの連想リストである。 初期フレームのパラメータからミニバッファ専用フレームが 必要であると判断するとそれを作る。 |
default-frame-alist | Variable |
これは、Emacsのすべてのフレーム、つまり、 初期フレームとそれ以降のフレームのフレームパラメータのデフォルト値を 指定する連想リストである。 Xウィンドウシステムを使っているときには、多くの場合、 Xリソースによっても同じ結果を得られる。 |
special-display-frame-alist
も
参照してください。
Emacsを起動するときにウィンドウの見ためを指定するオプションを使うと、
それらはdefault-frame-alist
に要素を追加することで効果を発揮します。
1つの例外は-geometry
で、指定位置はinitial-frame-alist
に
追加されます。
See Command Arguments。
フレームのパラメータの種類は、使用する表示機構に依存します。
ウィンドウフレームにおいて特別な意味を持つパラメータの一覧をつぎに示します。
これらのうち、name
、title
、height
、
width
、buffer-list
、buffer-predicate
は
端末フレームでも意味を持ちます。
display
DISPLAY
と同様に、
"host:dpy.screen"
の形の文字列であること。
title
title
がnil
以外であると、
フレーム向けのウィンドウシステムの枠にタイトルが現れる。
また、mode-line-frame-identification
に%F
(see %-Constructs)を使っていれば、
当該フレームのモード行にもタイトルが現れる。
Emacsがウィンドウシステムを使っていない場合には、
これは普通はモード行に表示され一度に1つのフレームだけを表示できる。
see Frame Titles。
name
title
を指定しないかnil
であると、
フレーム名はフレームタイトルのデフォルトになる。
name
を指定しないと、Emacsが自動的にフレーム名を設定する
(see Frame Titles)。
フレームを作るときにフレーム名を明示的に指定すると、
その名前は(Emacsの実行形式ファイルの名前のかわりに)
フレーム向けのXリソースを探すためにも使われる。
left
(+ pos)
の形のリストである。
負の数-posや(- pos)
の形のリストは、
実際には、スクリーンの右端を基準にしたウィンドウの右端位置を指定する。
posの正の値は左へ向けて数える。
注意:
パラメータが負の整数-posであると、
posは正である。
プログラムが指定した位置を無視するウィンドウマネージャもある。
指定した位置が無視されないように保証したい場合には、
パラメータuser-position
にもnil
以外の値を指定する。
top
(+ pos)
の形のリストである。
負の数-posや(- pos)
の形のリストは、
実際には、スクリーンの下端を基準にしたウィンドウの下端位置を指定する。
posの正の値は上へ向けて数える。
注意:
パラメータが負の整数-posであると、
posは正である。
プログラムが指定した位置を無視するウィンドウマネージャもある。
指定した位置が無視されないように保証したい場合には、
パラメータuser-position
にもnil
以外の値を指定する。
icon-left
icon-top
user-position
left
とtop
でスクリーン上の位置を指定して
フレームを作るときに、このパラメータは指定位置が、
(利用者がなんらかの方法で与えた)ユーザー指定のものなのか、
(プログラムが選んだ)プログラム指定のものなのかを指定する。
nil
以外の値であるとユーザー指定の位置であることを意味する。
ウィンドウマネージャはユーザー指定の位置を一般に尊重し、
プログラム指定の位置も尊重するものもある。
しかしその多くはプログラム指定の位置を無視し、
デフォルトに基づいてウィンドウを配置したり、
マウスでユーザーに配置させる。
twm
を含むウィンドウマネージャには、
プログラム指定の位置に従うかそれらを無視するかを
ユーザーが指定できるものもある。
make-frame
を呼び出すときには、
パラメータleft
とtop
の値がユーザーの希望を表す場合には
このパラメータの値にはnil
以外を指定すること。
さもなければnil
を指定する。
height
frame-pixel-height
を呼び出す。
Size and Positionを参照。)
width
frame-pixel-width
を呼び出す。
Size and Positionを参照。)
window-id
minibuffer
t
はあることを表し、nil
はないことを表す。
only
は、このフレームがミニバッファだけであることを表す。
(別のフレームの)値がミニバッファだけであると、
新たなフレームはそのミニバッファを使う。
buffer-predicate
nil
でなければ、
関数other-buffer
が(選択されているフレームから)この述語を使用して、
どのバッファにするかを決定する。
other-buffer
は各バッファごとにバッファを引数としてこの述語を呼び出す。
この述語がnil
以外を返すと当該バッファを選ぶ。
buffer-list
font
auto-raise
nil
以外であるとそのようにする)。
auto-lower
nil
以外であるとそのようにする)。
vertical-scroll-bars
left
、right
、あるいは
スクロールバーなしを意味するnil
。
horizontal-scroll-bars
nil
以外だと付ける)。
(水平スクロールバーはいまのところ実装してない。)
scroll-bar-width
icon-type
nil
以外の値はデフォルトのビットマップアイコン
(gnuの絵)を指定する。
nil
はテキストのアイコンを指定する。
icon-name
nil
であると、フレームのタイトルを使う。
foreground-color
フレームパラメータforeground-color
に設定したときには、
それに対応してフェイスを更新するために
frame-update-face-colors
を呼び出すこと。
background-color
フレームパラメータbackground-color
に設定したときには、
それに対応してフェイスを更新するために
frame-update-face-colors
を呼び出すこと。
see Face Functions。
background-mode
dark
かlight
である。
mouse-color
cursor-color
border-color
display-type
color
、grayscale
、mono
のいずれかである。
cursor-type
bar
、box
、
(bar . width)
のいずれかである。
シンボルbox
は、ポイント直後の文字に重なる通常の黒い箱型の
カーソルを指定し、これがデフォルトである。
シンボルbar
は、カーソルとして文字のあいだに縦棒を置く指定である。
(bar . width)
は、ピクセル幅widthの縦棒を指定する。
border-width
internal-border-width
unsplittable
nil
以外であると、このフレームのウィンドウをけっして自動的に分割しない。
visibility
nil
、可視を表すt
、
アイコンになっていることを表すicon
の3の可能性がある。
see Visibility of Frames。
menu-bar-lines
フレームパラメータleft
、top
、height
、width
を
使って、フレームのサイズや位置を読み取ったり変更できます。
指定しなかった大きさと位置のパラメータは、
ウィンドウマネージャが通常どおりに選びます。
以下はサイズや位置を操作する特別な機能です。
set-frame-position frame left top | Function |
この関数は、フレームframeの左上隅の位置を
left(左端)とtop(上端)にする。
これらの引数は、スクリーンの左上隅からピクセル単位で数える。
パラメータ値が負であると、スクリーンの下端から測ってウィンドウの下端を 位置決めしたり、スクリーンの右端から測ってウィンドウの右端を位置決めする。 つねに左端や上端から測った値にして、負の値はフレームを スクリーンの上端や左端から部分的にはみ出して位置決めする 意味にするほうがよいかもしれないが、 現状ではそのように変えるのは不適当と思われる。 |
frame-height &optional frame | Function |
frame-width &optional frame | Function |
この関数は、フレームframeの高さや幅を行単位やコラム単位で返す。 frameを指定しないと、選択されているフレームを使う。 |
screen-height | Function |
screen-width | Function |
これらの関数はframe-height やframe-width の古い別名である。
文字端末を使っている場合、通常、フレームの大きさは
端末スクリーンの大きさと同じである。
|
frame-pixel-height &optional frame | Function |
frame-pixel-width &optional frame | Function |
これらの関数は、フレームframeの高さや幅をピクセル単位で返す。 frameを指定しないと、選択されているフレームを使う。 |
frame-char-height &optional frame | Function |
frame-char-width &optional frame | Function |
これらの関数は、フレーム内の文字の高さや幅をピクセル単位で返す。 frameを指定しないと、選択されているフレームを使う。 |
set-frame-size frame cols rows | Function |
この関数は、フレームframeの大きさを文字単位で指定する。
colsとrowsは、新たな幅と高さを指定する。
ピクセル単位で大きさを指定するには、
|
set-frame-height frame lines &optional pretend | Function |
この関数は、フレームframeの高さをlines行に変える。
それに合わせてframe内の既存のウィンドウの大きさは比例して変わる。
pretendが |
set-frame-width frame width &optional pretend | Function |
この関数は、フレームframeの幅を設定する。
引数pretendはset-frame-height と同じ意味を持つ。
|
set-screen-height
とset-screen-width
の古い関数は、
複数フレームを扱えないEmacsの版でスクリーンの高さや幅を
指定するために使われていました。
これらはほぼ廃れていますが、まだ動作します。
これらは選択されているフレームに適用されます。
x-parse-geometry geom | Function |
関数x-parse-geometry は、Xウィンドウの標準のジオメトリ文字列を
make-frame の引数の一部に使えるように連想リストに変換する。
この連想リストは、geomで指定されているパラメータとその値を記述する。
各要素は 大きさを表すパラメータでは、その値は整数であること。
位置を表すパラメータでは、右端や下端の位置を表す値もあるので、
例を示す。 (x-parse-geometry "35x70+0-0") => ((height . 70) (width . 35) (top - 0) (left . 0)) |
各フレームにはパラメータname
があります。
これは、典型的にはウィンドウシステムがフレームの先頭に表示する
フレームタイトルのデフォルトにもなります。
フレーム属性name
に設定することで明示的に名前を指定できます。
通常は名前を明示的に指定しないでしょうから、
変数frame-title-format
に保持してある雛型から
Emacsが自動的にフレーム名を計算します。
Emacsは、フレームを再表示するたびに名前を再計算します。
frame-title-format | Variable |
この変数は、読者がフレーム名を明示的に指定しなかったときの
フレーム向けの名前の計算方法を指定する。
変数の値は実際には、mode-line-format のようなモード行構成である。
see Mode Line Data。
|
icon-title-format | Variable |
この変数は、フレームタイトルを明示的に指定しなかったときの アイコンにしたフレーム向けの名前の計算方法を指定する。 これはアイコンそのものに現れる。 |
multiple-frames | Variable |
この変数はEmacsが自動的に設定する。
(ミニバッファ専用のフレームや不可視フレームを数えずに)
複数個のフレームがあるとこの値がt である。
frame-title-format のデフォルト値ではmultiple-frames を使っており、
複数のフレームがあるときに限りフレームタイトルにバッファ名が入るようにする。
|
フレームを明示的に削除(delete)しない限り、 フレームは見える可能性があります。 フレームを削除するとスクリーンに表示できなくなりますが、 それを参照するものがなくならない限りLispオブジェクトとしては存在し続けます。 保存したフレーム構成(see Frame Configurations)を復元する以外には、 フレームの削除を取り消すことはできません。 これはウィンドウと同様です。
delete-frame &optional frame | コマンド |
この関数はフレームframeを削除する。 デフォルトでは、frameは選択されているフレームである。 |
frame-live-p frame | Function |
関数frame-live-p は、フレームframeが削除されていなければ
nil 以外を返す。
|
ウィンドウを削除するコマンドを与えるウィンドウマネージャもあります。
それらは、ウィンドウを操作しているプログラムに特別なメッセージを
送ることで動作します。
Emacsがそのようなコマンドを受け取ると、
イベントdelete-frame
を生成します。
このイベントの普通の定義は、関数delete-frame
を呼び出すコマンドです。
See Misc Events。
frame-list | Function |
関数frame-list は、削除されていないすべてのフレームから成るリストを返す。
これは、バッファに対するbuffer-list に相当する。
得られるリストは新たに作成したものであり、
このリストを変更してもEmacs内部にはなんの効果もない。
|
visible-frame-list | Function |
この関数は、現在可視のフレームだけのリストを返す。 see Visibility of Frames。 (選択されているフレームだけが実際に表示されている場合でも、 端末フレームはすべてつねに『可視』とみなす。) |
next-frame &optional frame minibuf | Function |
関数next-frame により、
任意の位置から始めてすべてのフレームを便利に巡回できる。
巡回順の中でframeの『つぎ』のフレームを返す。
frameを省略したりnil であると、
デフォルトでは選択されているフレームを使う。
第2引数minibufは、対象とするフレームを指定する。
|
previous-frame &optional frame minibuf | Function |
next-frame と同様であるが、すべてのフレームを逆方向に巡回する。
|
next-window
とprevious-window
も
参照してください。
各ウィンドウはある1つのフレームだけの一部であり、
window-frame
で当該フレームを得られます。
window-frame window | Function |
この関数は、windowが属するフレームを返す。 |
フレーム内のミニバッファ用以外のすべてウィンドウには、 巡回順序がついています。 その順序は、フレームの左上隅の先頭のウィンドウから始まって、 右下隅のウィンドウ(フレームにミニバッファがあれば、 これはつねにミニバッファ用ウィンドウ)に達するまで下向き右向きに進み、 そして先頭へ戻ります。
frame-top-window frame | Function |
この関数は、フレームframeのもっとも上端のもっとも左端の 先頭のウィンドウを返す。 |
ある時点では、各フレームではたった1つのフレームが
当該フレームで選択されているのです。
このような区別の意味は、
フレームを選択するとそのようなウィンドウも選択されるということです。
フレームで現在選択されているフレームは
frame-selected-window
で得られます。
frame-selected-window frame | Function |
この関数は、フレームframeで選択されている frame内のウィンドウを返す。 |
逆に、select-window
でEmacsのウィンドウを選ぶと、
それがそのフレームで選択されているウィンドウになります。
see Selecting Windows。
指定したフレームのウィンドウの1つを返す別の関数は
minibuffer-window
です。
See Minibuffer Misc。
通常、各フレームにはそれ独自のミニバッファ用ウィンドウが底にあり、
フレームが選択されているときにはいつもそれが使われます。
フレームにミニバッファがあれば、minibuffer-window
(see Minibuffer Misc)でそれを得られます。
しかし、ミニバッファのないフレームを作ることもできます。
そのようなフレームでは、別のフレームのミニバッファ用ウィンドウを
使う必要があります。
そのようなフレームを作成するときには、
使用する(他のフレームの)ミニバッファを明示的に指定できます。
そうしないと、変数default-minibuffer-frame
の値で指定される
フレームのミニバッファを使います。
その値は、ミニバッファを有したフレームである必要があります。
ミニバッファ専用のフレームを使うときは、
ミニバッファで入力するときにそのフレームが
自動的に手前にくるようにしたいでしょう。
そうしたい場合には、変数minibuffer-auto-raise
にt
に設定します。
See Raising and Lowering。
default-minibuffer-frame | Variable |
この変数は、デフォルトで使うミニバッファ用ウィンドウのフレームを指定する。 この変数は現在の端末につねにローカルであり、 バッファローカルにはなりえない。 see Multiple Displays。 |
ある時点では、Emacsの1つのフレームが選択されているフレーム (selected frame)です。 選択されているウィンドウは選択されているフレームの中につねにあります。
selected-frame | Function |
この関数は選択されているフレームを返す。 |
マウスが入っているウィンドウにキーボード入力を振り向ける ウィンドウシステムやウィンドウマネージャがあります。 ウィンドウにフォーカスを置くために、 明示的にクリックしたりコマンドを必要とするものもあります。 いずれであっても、Emacsはどのフレームにフォーカスがあるかを 自動的に追跡します。
Lispプログラムからは、関数select-frame
を呼ぶことで、
『一時的に』フレームを切り替えることもできます。
これは、ウィンドウシステムのフォーカスは変えません。
というよりは、プログラムで指定するまで
ウィンドウシステムの制御を回避します。
文字端末を使っているときには、
選択されているフレームのみが端末に実際に表示されます。
フレームを切り替える唯一の方法はswitch-frame
であり、
それ以降にswitch-frame
を呼び出すまで切り替えた効果は持続します。
初期フレーム以外の各端末フレームには番号が付いていて、
選択されているフレームの番号がモード行内のバッファ名のまえに現れます
(see Mode Line Variables)。
select-frame frame | Function |
この関数はフレームframeを選択し、 Xサーバーのフォーカスを一時的に無視する。 frameを選択している状態は、 ユーザーが別のフレームを選択する動作を行うか 再度この関数が呼ばれるまで持続する。 |
サーバーやウィンドウマネジャーの要請にしたがって
フレームを選択するようにして、
Emacsはウィンドウシステムと協調します。
必要なときにはfocusイベントと呼ばれる特別な入力イベントを
生成することでこのようにします。
コマンドループはhandle-switch-frame
を呼び出すことで
イベントfocusを処理します。
See Focus Events。
handle-switch-frame frame | コマンド |
この関数は、フレームframeを選択することでフォーカスイベントを
処理する。
フォーカスイベントは、通常、このコマンドを起動することで処理される。 それ以外の理由ではこれを呼び出さないこと。 |
redirect-frame-focus frame focus-frame | Function |
この関数は、フォーカスをframeからfocus-frameへ振り向ける。
つまり、以降の打鍵やイベントは、focusではなく、
focus-frameが受け取ることになる。
そのようなイベントのあとでは、
last-event-frame の値はfocus-frameになる。
また、focusを指定したイベントswitch-frame は、
focus-frameを選ぶことになる。
focus-frameが フォーカスの振り向けの用途の1つは、 ミニバッファを持たないフレームのためである。 これらのフレームでは、別のフレームのミニバッファを使う。 別のフレームのミニバッファを活性にすると、 フォーカスを当該フレームへ振り向ける。 これにより、ミニバッファを活性にしたフレームにマウスが入っていても、 ミニバッファのフレームにフォーカスを置ける。 フレームを選択してもフォーカスの振り向けを変更する。
フレーム これは、フォーカスを自分自身へ振り向けているフレームは、
フォーカスを振り向けていないフレームとは異なる扱いを受けることを意味する。
|
focus-follows-mouse | User Option |
このオプションは、ユーザーがマウスを動かしたときに
ウィンドウマネージャがフォーカスを移動するかどうかをEmacsに伝える。
nil 以外であるとフォーカスが移動することを意味する。
その場合、コマンドother-frame は、
新たに選択されたフレームに適合するような位置にマウスを移動する。
|
ウィンドウフレームは、可視、 不可視、アイコンになっているのいずれかです。 フレームが可視であると、その内容を見ることができます。 アイコンになっているとフレームの内容はスクリーンで見えませんが、 アイコンは見えます。 フレームが不可視であると、それはスクリーン上に見えず アイコンでもありません。
端末フレームは選択されているものだけが表示されるので、 端末フレームでは可視性は意味がありません。
make-frame-visible &optional frame | コマンド |
この関数は、フレームframeを可視にする。 frameを省略すると、選択されているフレームを可視にする。 |
make-frame-invisible &optional frame | コマンド |
この関数は、フレームframeを不可視にする。 frameを省略すると、選択されているフレームを不可視にする。 |
iconify-frame &optional frame | コマンド |
この関数は、フレームframeをアイコンにする。 frameを省略すると、選択されているフレームをアイコンにする。 |
frame-visible-p frame | Function |
この関数は、フレームframeの可視性を返す。
その値は、frameが可視ならばt 、
不可視ならばnil 、アイコンになっていればicon である。
|
フレームの可視性は、フレームパラメータとしても得られます。 フレームパラメータとして読んだり変更できます。 See Window Frame Parameters。
ユーザーは、ウィンドウマネージャを用いて フレームをアイコンにしたりアイコンを開けます。 これは、Emacsが制御できるレベルよりしたで行われますが、 Emacsはそのような変更を追跡できるようにイベントを提供します。 See Misc Events。
ほとんどのウィンドウシステムでは、机のたとえを使います。 つまり、スクリーンの面に垂直な方向を概念的な3軸目と考えて、 ウィンドウは積み重なっていて、 もっとも手前からもっとも奥に順序がついています。 2つのウィンドウが重なり合っているところでは、 手前のものがそのしたのものを隠しています。 もっとも奥にあるウィンドウであっても、 それに重なるウィンドウがなければ見ることができます。
ウィンドウのこのような順序は固定されていません。 実際、ユーザーは順序を頻繁に変更します。 ウィンドウを手前に置く(raising)とは、 ウィンドウを積み重ねのもっとも上に移動することです。 ウィンドウを奥に置く(lowering)とは、 ウィンドウを積み重ねのもっとも下に移動することです。 この移動は概念的な3軸目に限り、 スクリーン上でのウィンドウの位置は変えません。
Emacsのフレームを表すウィンドウは、つぎの関数で 手前へ置いたり奥へ置けます。
raise-frame &optional frame | コマンド |
この関数は、フレームframeを手前に置く (デフォルトは選択されているフレーム)。 |
lower-frame &optional frame | コマンド |
この関数は、フレームframeを奥に置く (デフォルトは選択されているフレーム)。 |
minibuffer-auto-raise | User Option |
これがnil 以外であると、ミニバッファが活性になると
ミニバッファ用ウィンドウがあるフレームを手前に置く。
|
フレームパラメータを使うと、フレームが
選択されると自動的に手前に置いたり(auto-raise
)、
選択を止めると奥へ置け(auto-lower
)ます。
See Window Frame Parameters。
フレーム構成(frame configuration)は、 現在のフレームの配置、それらのすべての属性、それぞれのウィンドウ構成を 記録したものです。 (see Window Configurations。)
current-frame-configuration | Function |
この関数は、現在のフレームの配置とそれらの内容を記述した フレーム構成のリストを返す。 |
set-frame-configuration configuration | Function |
この関数は、configurationで記述されたフレームの状態に復元する。 |
マウスを追跡(track)できると有用なことがあります。 つまり、マウスがどこにあるかを表す指示子を表示して マウスの移動に従って指示子を動かすのです。 効率よくマウスを追跡するには、マウスが実際に移動するまで待つ手段が必要です。
マウスを追跡する便利な方法は、マウスの移動を表すイベントを待つことです。 そうすれば、そのようなイベントを待てばマウスの移動を待てます。 さらに、発生しうるそれ以外の種類のイベントを扱うのも簡単です。 普通はマウスを永遠に追跡し続けたいのではなく ボタンを離すなどの別のイベントを待ちたいのでしょうから、 これは有用です。
track-mouse body... | Special Form |
このスペシャルフォームは、マウスモーションイベントを生成するようにして
bodyを実行する。
典型的にはbodyではread-event を使って
モーションイベントを読み、それに従って表示を変更する。
マウスモーションイベントの形式については、
see Motion Events。
|
マウスの移動を追跡する普通の目的は、 現在の位置でボタンを押したり離すとなにが起こるかを スクリーン上に示すことです。
多くの場面では、テキスト属性mouse-face
(see Special Properties)
を使えば、マウスを追跡する必要はなくなります。
これはとても低いレベルで動作し、
Lispレベルでマウスを追跡するより滑らかに動作します。
関数mouse-position
とset-mouse-position
で、
マウスの現在位置を参照できます。
mouse-position | Function |
この関数は、マウスの位置を表すものを返す。
その値は(frame x . y) の形であり、
xとyはフレームframeの内側の左上隅を基準にした
文字数で数えた位置を表す整数である。
|
set-mouse-position frame x y | Function |
この関数は、フレームframe内でxとyの位置にマウスを移動する。 引数xとyは整数であり、 フレームframeの内側の左上隅を基準にした文字数で数えた位置である。 frameが不可視であると、この関数はなにもしない。 戻り値には意味はない。 |
mouse-pixel-position | Function |
この関数はmouse-position に似ているが、
文字単位ではなくピクセル単位で座標を返す。
|
set-mouse-pixel-position frame x y | Function |
この関数はset-mouse-position のようにマウスを移動するが、
xとyは文字単位でなくピクセル単位である。
これらの座標はフレームの内側にある必要はない。
frameが不可視であると、この関数はなにもしない。 戻り値には意味はない。 |
ウィンドウシステムを使っているときには、 ユーザーがマウスで選択できるように Lispプログラムからメニューをポップアップできます。
x-popup-menu position menu | Function |
この関数はポップアップメニューを表示し、
ユーザーが行った選択を表す指示子を返す。
引数positionは、スクリーンのどこにメニューを置くかを指定する。 それはマウスのボタンイベント(ユーザーがボタンを押した場所にメニューを置く)か つぎの形のリストでもよい。 ((xoffset yoffset) window) ここで、xoffsetとyoffsetは ウィンドウwindowのフレームの左上隅から測ったピクセル単位の座標である。 positionが 引数menuは、メニューに表示するものを指定する。 それはキーマップかキーマップのリストである(see Menu Keymaps)。 あるいは、つぎの形でもよい。 (title pane1 pane2...) ここで、各ペインはつぎの形のリストである。 (title (line . item)...) 各lineは文字列であり、 各itemは対応するlineが選ばれたときに返される値であること。 |
使用上の注意:
メニューキーマップで定義したプレフィックスキーでできることには、
メニューを表示するためにx-popup-menu
を使わないこと。
メニューキーマップを使ってメニューを実装すると、
C-h cやC-h aで当該メニューの個々の項目を見ることができ、
それらに対するヘルプを提供できる。
x-popup-menu
を呼び出すコマンドを定義してメニューを実装すると、
ヘルプ機能には当該コマンドの内側でなにがなされるかわからないので、
メニューの項目に対するヘルプを提供できない。
マウスの移動でサブメニューを切り替えられるメニューバーの機構では、
x-popup-menu
を呼び出すコマンドの定義を調べられません。
したがって、x-popup-menu
を使ってサブメニューを実装すると、
それらはメニューバーに適応した動作をできません。
このために、メニューバーのすべてのサブメニューは、
親メニュー内のメニューキーマップとして実装してあり、
x-popup-menu
は使っていません。
See Menu Bar。
メニューバーに内容が変化するサブメニューを使いたいときでも、
メニューキーマップを使って実装するべきです。
内容を変えるには、必要に応じてメニューキーの内容を更新するために
menu-bar-update-hook
にフック関数を追加します。
対話ボックスはポップアップメニューの変形です。
少々異なって見えますが、フレームの中央につねに現れ、
たった1つのレベルで1つのペインです。
対話ボックスの主な用途は、
ユーザーが『yes』、『no』、および他の少数の選択肢で答えるような
問い合わせを行うためです。
関数y-or-n-p
とyes-or-no-p
は、
マウスクリックで起動されたコマンドから呼ばれると
キーボードではなく対話ボックスを使います。
x-popup-dialog position contents | Function |
この関数は、対話ボックスを表示し、
ユーザーが選んだ選択肢を表す指示子を返す。
引数contentsは表示する選択肢を指定し、つぎの形である。
(title (string . value)...) これは、 戻り値は、選ばれた選択肢のvalueである。 リストの要素は、 リストに 対話ボックスはフレームの中央につねに現れ、
引数positionはそのフレームを指定する。
可能な値は 場合によっては、Emacsは本当の対話ボックスを表示できない。 そのときにはフレームの中央にポップアップメニューで同じ項目を表示する。 |
これらの変数は、Xウィンドウシステムを使っているときに さまざまな場面で使用するマウスポインタの形状を指定します。
x-pointer-shape
x-sensitive-text-pointer-shape
これらの変数は、新たに作成したフレームに影響します。 既存のフレームには通常は影響しません。 しかし、フレームのマウスの表示色を設定すると、 これらの変数の現在値に基づいてポインタ形状も更新します。 See Window Frame Parameters。
これらのポインタ形状の指定に使える値は、
ファイルlisp/term/x-win.el
で定義してあります。
それらの一覧を見るには
M-x apropos <RET> x-pointer <RET>を使います。
Xサーバーは、アプリケーションプログラムのあいだでデータを 転送するためのセレクション(selection)の集まりを記録します。 さまざまなセレクションは、Emacsではシンボルで表した セレクション型(selection type)で区別されます。 Emacsを含むXクライアントは、任意の型のセレクションを読んだり設定できます。
x-set-selection type data | Function |
この関数は、Xサーバーに『セレクション』を設定する。
これは2つの引数、セレクション型typeと
それに割り当てる値dataを取る。
dataがnil であると、当該セレクションを削除することを意味する。
さもなければdataは、文字列、
整数(あるいは2つの数のコンスセルかリスト)、
オーバレイ、同じバッファを指す2つのマーカのコンスセルのいずれかである。
オーバレイやマーカの対は、
オーバレイのテキストやマーカのあいだのテキストを表す。
引数dataは、ベクトルではない正しいセレクション値のベクトルでもよい。 可能な各typeには型に依存した独自のセレクション値がある。
typeの普通の値は |
x-get-selection &optional type data-type | Function |
この関数は、Emacsや他のXクライアントが設定したセレクションを参照する。
これは2つの引数、typeとdata-typeを取る。
セレクション型typeのデフォルトはPRIMARY である。
引数data-typeは、他のXクライアントから得た生データを
Lispデータに変換するために使用するデータ変換の書式を指定する。
意味のある値は、 |
Xサーバーには、アプリケーションのあいだで移動するテキストや他のデータを 保存できる番号付きのカットバッファ(cut buffer)の集まりもあります。 カットバッファは廃れているとみなされますが、 それらを使っているXクライアント向けにEmacsはカットバッファを扱えます。
x-get-cut-buffer n | Function |
この関数は、番号nのカットバッファの内容を返す。 |
x-set-cut-buffer string | Function |
Emacsが連続したキルをキルリングで順に下向きに移動するのと同様に、 この関数は一連のカットバッファの値を順に下向きに移動してから 文字列stringを最初のカットバッファ(番号0)に保存する。 |
selection-coding-system | Variable |
この変数は、セレクション、クリップボード、カットバッファを
読み書きするときに使うコーディングシステムを指定する。
see Coding Systems。
デフォルトはcompound-text である。
|
x-list-font pattern &optional face frame maximum | Function |
この関数は、パターンpatternに一致する
利用可能なフォント名のリストを返す。
省略可能な引数faceとframeを指定すると、
frameで現在オンになっているfaceと同じサイズのフォントに
リストを制限する。
引数patternは文字列であること。
これはワイルドカード文字を含んでいてもよい。
faceとframeを指定するときには、 faceはフェイス名(シンボル)であり、frameはフレームであること。 省略可能な引数maximumは、返すフォントの個数を制限する。
これが |
フォントセット(fontset)は、フォントのリストであって、 各フォントが文字コードのある範囲に割り付けられています。 個々のフォントだけでは、Emacsが扱う文字集合の範囲全体を表示できませんが、 フォントセットならば可能です。 フォントセットにはフォントと同様に名前があり、 フレームやフェイス向けに『フォント』を指定するときの フォント名のかわりにフォントセット名を使えます。 ここでは、Lispプログラムの制御のもとにフォントセットを定義することに 関する情報を述べます。
create-fontset-from-fontset-spec fontset-spec &optional style-variant-p noerror | Function |
この関数は、指定文字列fontset-specに従って
新たなフォントセットを定義する。
文字列はつぎの形であること。
fontpattern, [charsetname:fontname]... コンマの前後の白文字は無視する。 文字列の始めの部分fontpatternは、
最後の2つのフィールドが 新たなフォントセットには2つの名前、つまり、長い名前と短い名前がある。
長い名前はfontpatternそのものである。
短い名前は 省略可能な引数style-variant-pが 指定文字列ではフォントセットで使うフォントも指定する。 詳しくは下記参照。 |
charset:font
という構成は、
特定の1つの文字集合向けに(このフォントセットで)使うフォントを指定します。
ここで、charsetは文字集合の名前であり、
fontはその文字集合に使うフォントです。
この構成は、指定文字列で何回でも使えます。
明示してない残りの文字集合向けには、
fontpatternに基づいてEmacsがフォントを選びます。
つまり、fontset-alias
を1つの文字集合を指名する値で置き換えます。
ASCII文字集合向けには、
fontset-alias
をISO8859-1
で置き換えます。
これに加えて、いくつか連続したフィールドがワイルドカードであるなら、 Emacsはそれらを1つのワイルドカードにまとめます。 これは、自動的に拡大縮小したフォントの使用を避けるためです。 大きめのフォントを縮小したフォントは編集には使えません。 また、小さめのフォントを拡大したフォントも有用ではありません。 というのは、Emacsがそうするように、 もともと小さなフォントを使うほうがよいからです。
したがって、fontpatternがつぎのようであると、
-*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24
ASCII文字に対するフォント指定はつぎのようになります。
-*-fixed-medium-r-normal-*-24-*-ISO8859-1
また、Chinese GB2312文字に対するフォント指定はつぎのようになります。
-*-fixed-medium-r-normal-*-24-*-gb2312*-*
上のフォント指定に一致する中国語フォントがないかもしれません。
多くのXの配布には、familyフィールドが
song ti
かfangsong ti
の中国語フォントだけが含まれています。
そういった場合、Fontset-n
をつぎのように指定します。
Emacs.Fontset-0: -*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24,\ chinese-gb2312:-*-*-medium-r-normal-*-24-*-gb2312*-*
そうすると、Chinese GB2312の文字を除くフォント指定では
familyフィールドがfixed
となり、
Chinese GB2312の文字に対するフォント指定では
familyフィールドが*
となります。
x-color-defined-p color &optional frame | Function |
この関数は、表示色名が意味のあるものかどうかを報告する。
意味があればt を返し、さもなければnil を返す。
引数frameは、どのフレームで調べるかを指定する。
frameを省略したりnil であると、選択されているフレームを使う。
この関数では、読者が使用しているディスプレイで 当該表示色を実際に表示できるかどうかはわからない。 どんな種類のディスプレイでも定義されていればどんな表示色でも 問い合わせることができ、なんらかの結果を得られる。 Xサーバーはこのように動作するのである。 読者のディスプレイで表示色colorを使えるかどうかを 検査する近似方法はつぎのとおりである。 (defun x-color-supported-p (color &optional frame) (and (x-color-defined-p color frame) (or (x-display-color-p frame) (member color '("black" "white")) (and (> (x-display-planes frame) 1) (equal color "gray"))))) |
x-color-values color &optional frame | Function |
この関数は、表示色colorが理想的にはどのように見えるかを記述した値を返す。
colorが定義されていれば、その値は、赤の分量、緑の分量、青の分量を表す
3つの整数のリストである。
各整数の範囲は原理的には0から65535であるが、
実際には65280を超えることはないようである。
colorが定義されていなければ、値はnil である。
(x-color-values "black") => (0 0 0) (x-color-values "white") => (65280 65280 65280) (x-color-values "red") => (65280 0 0) (x-color-values "pink") => (65280 49152 51968) (x-color-values "hungry") => nil フレームframeのディスプレイに対する表示色の値を返す。
frameを省略したり |
x-get-resource attribute class &optional component subclass | Function |
関数x-get-resource は、
Xウィンドウのデフォルトのデータベースからリソースの値を取り出す。
リソースは、keyとclassの組み合わせで添字付けされる。
この関数は 省略可能な引数componentとsubclassは、それぞれ、
キーとクラスに追加される。
2つを指定するかまったく指定しないこと。
これらを指定すると、
キーは |
x-resource-class | Variable |
この変数は、x-get-resource が探すアプリケーション名を指定する。
デフォルト値は"Emacs" である。
x-get-resource を呼び出す周りでこの変数に別の文字列を束縛すれば、
『Emacs』以外のアプリケーション名でXリソースを探せる。
|
See Resources X。
本節では、Emacsが使っているXディスプレイの能力や製造元に関する情報を
得るために使う関数について述べます。
これらの関数のそれぞれには、どのディスプレイを対象にするか
引数displayで指定できます。
引数displayは、ディスプレイ名か
フレーム(が表示されいるディスプレイを意味する)のいずれかです。
引数displayを省略したりnil
であると、
選択されているフレームのディスプレイを使うことを意味します。
x-display-screens &optional display | Function |
この関数は、ディスプレイに対応付けられているスクリーンの個数を返す。 |
x-server-version &optional display | Function |
この関数は、ディスプレイで動作中のXサーバーの版番号のリストを返す。 |
x-server-vendor &optional display | Function |
この関数は、Xサーバーソフトウェアの提供業者を返す。 |
x-display-pixel-height &optional display | Function |
この関数はスクリーンのピクセル単位の高さを返す。 |
x-display-mm-height &optional display | Function |
この関数はスクリーンのミリメートル単位の高さを返す。 |
x-display-pixel-width &optional display | Function |
この関数はスクリーンのピクセル単位の幅を返す。 |
x-display-mm-width &optional display | Function |
この関数はスクリーンのミリメートル単位の幅を返す。 |
x-display-backing-store &optional display | Function |
この関数は、スクリーンのバッキングストア機能を返す。
その値は、always 、when-mapped 、not-useful のシンボルの
いずれかである。
|
x-display-save-under &optional display | Function |
この関数は、ディスプレイにセーブアンダー機能があればnil 以外を返す。
|
x-display-planes &optional display | Function |
この関数は、ディスプレイのプレイン数を返す。 |
x-display-visual-class &optional display | Function |
この関数は、スクリーンのビジュアルクラスを返す。
その値は、static-gray 、gray-scale 、
static-color 、pseudo-color 、true-color 、
direct-color のシンボルのいずれかである。
|
x-display-grayscale-p &optional display | Function |
この関数は、スクリーンで白黒の濃淡を表示できるとt を返す。
|
x-display-color-p &optional display | Function |
この関数は、スクリーンがカラースクリーンならばt を返す。
|
x-display-color-cells &optional display | Function |
この関数はスクリーンで使えるカラーセルの個数を返す。 |
バッファ内位置(position)は、 バッファ内のテキストの文字を添字付けします。 より正確にいえば、バッファ内位置は2つの文字のあいだの箇所 (あるいは、先頭文字ではそのまえ、最後の文字ではそのうしろ)を識別して、 指定位置のまえやうしろの文字を指定できるようにします。 しかし、しばしば位置『にある』文字といいますが、 これは位置の直後の文字を意味します。
バッファ内位置は、通常、1から始まる整数で表しますが、 マーカ(marker)で表すこともできます。 マーカは特別なオブジェクトであり、 テキストを挿入したり削除しても 同じ周りの文字に留まるように自動的に再配置されます。 See Markers。
ポイント(point)は、 自己挿入文字やテキスト挿入関数を含む多くの編集コマンドが使う バッファ内の特別な位置です。 他のコマンドは、バッファ内の別の箇所で編集したり挿入できるように ポイントをテキスト内で移動します。
他のバッファ内位置と同様に、ポイントは文字そのものではなく、 2つの文字のあいだの箇所 (あるいは、先頭文字ではそのまえ、最後の文字ではそのうしろ)を指定します。 通常、端末では、ポイントの直後の文字に重ねてカーソルを表示します。 ポイントはカーソルがある文字のまえに実際にはあります。
ポイントの値は、1からバッファのサイズ足す1です。 ナロイング(see Narrowing)していると、 ポイントはバッファの参照可能な (バッファの端を含むかもしれない)範囲内に制限されます。
各バッファには独自のポイント値があり、 それは他のバッファのポイント値とは独立です。 各ウィンドウにも独自のポイント値があり、 同じバッファを表示している他のウィンドウのポイント値とは独立です。 このようなわけで、同じバッファを表示しているさまざまなウィンドウで 異なるポイント値を持てるのです。 1つのウィンドウだけにバッファが表示されているときには、 バッファのポイントとウィンドウのポイントは、通常、同じ値であり、 それらを区別することはほとんど重要ではありません。 詳しくは、See Window Point。
point | Function |
この関数はカレントバッファのポイント値を整数で返す。
(point) => 175 |
point-min | Function |
この関数は、カレントバッファで参照可能なポイント値の最小値を返す。 これは通常1であるが、 ナロイングしているときには、ナロイングした領域の開始位置である。 (see Narrowing。) |
point-max | Function |
この関数は、カレントバッファで参照可能なポイント値の最大値を返す。
ナロイングしていなければ、これは(1+ (buffer-size)) である。
ナロイングしているときには、ナロイングした領域の終了位置である。
(see Narrowing。)
|
buffer-end flag | Function |
この関数は、flagが1未満であれば(point-min) を返し、
さもなければ(point-max) を返す。
引数flagは整数であること。
|
buffer-size | Function |
この関数は、カレントバッファ内の総文字数を返す。
ナロイング(see Narrowing)していなければ、
point-max はこの値より1大きな値を返す。
(buffer-size) => 35 (point-max) => 36 |
移動関数は、現在のポイント値やバッファの先頭や末尾を基準にして、 あるいは、選択されているウィンドウの端を基準にして、 ポイント値を変更します。 See Point。
これらの関数は、文字数に基づいてポイントを移動します。
goto-char
が基本になる基本関数であり、他の関数はこれを使っています。
goto-char position | コマンド |
この関数は、カレントバッファのポイント位置を値positionとする。
positionが1未満であると、バッファの先頭にポイントを移動する。
positionがバッファの長さより大きい場合には、
バッファの末尾にポイントを移動する。
ナロイングしている場合であっても、
positionはバッファの先頭から数えるが、
参照可能部分の外側にはポイントは移動できない。
positionが範囲外であると、
この関数を対話的に呼び出すと、 前置引数があればpositionは数値前置引数である。 さもなければミニバッファから読む。
|
forward-char &optional count | コマンド |
この関数は、前方へ、つまり、バッファの末尾に向けて
(countが負であれば、後方へ、つまり、バッファの先頭へ向けて)
count文字分ポイントを移動する。
バッファの先頭や末尾を越えて
(ナロイングしているときには参照可能部分を越えて)
ポイントを移動しようとすると、
beginning-of-buffer かend-of-buffer のエラーコードで
エラーを通知する。
対話的に呼び出されると、countは数値前置引数である。 |
backward-char &optional count | コマンド |
この関数は、後方へ、つまり、バッファの先頭に向けて
(countが負であれば、前方へ、つまり、バッファの末尾へ向けて)
count文字分ポイントを移動する。
バッファの先頭や末尾を越えて
(ナロイングしているときには参照可能部分を越えて)
ポイントを移動しようとすると、
beginning-of-buffer かend-of-buffer のエラーコードで
エラーを通知する。
対話的に呼び出されると、countは数値前置引数である。 |
これらの単語を解析する関数は、 当該文字が単語の一部かどうかを判定するために構文テーブルを使います。 See Syntax Tables。
forward-word count | コマンド |
この関数は、前方へ(countが負ならば後方へ)
count単語分ポイントを移動する。
『1単語分移動する』とは、
単語構成文字を越えてから単語区切り文字(あるいはバッファの参照可能部分の
境界)に出会うまでポイントを移動することを意味する。
バッファの境界で止まらず(最後の単語は除く)に
count単語分移動できると、値は 対話的に呼び出されると、countは数値前置引数である。 |
backward-word count | コマンド |
この関数はforward-word と同様であるが、
前方へではなく後方へ単語の先頭に出会うまで移動する。
対話的に呼び出されると、countは数値前置引数である。 この関数は、プログラムではほとんど使われない。
負の引数で |
words-include-escapes | Variable |
この変数は、forward-word とそれを使うもののふるまいに影響する。
nil 以外であると、『エスケープ』や『文字クォート』の
構文クラスに属する文字も単語の一部とみなす。
さもなければ、単語の一部とはみなさない。
|
バッファの先頭にポイントを移動するには、つぎのように書きます。
(goto-char (point-min))
同様に、バッファの末尾に移動するには、つぎのようにします。
(goto-char (point-max))
上のことを行うためにユーザーが使うコマンドが2つあります。 これらはマークを設定してエコー領域にメッセージを表示するので、 これらをLispプログラムからは使わないように警告しておきます。
beginning-of-buffer &optional n | コマンド |
この関数は、バッファ(あるいはナロイングしているときには参照可能部分)
の先頭にポイントを移動し、移動前の位置にマークを設定する。
nがnil 以外であると、
バッファの先頭から10分のnの箇所にポイントを移動する。
対話的に呼び出すと、前置引数があればnは数値前置引数である。
さもなければnのデフォルトは 警告: |
end-of-buffer &optional n | コマンド |
この関数は、バッファ(あるいはナロイングしているときには参照可能部分)
の末尾にポイントを移動し、移動前の位置にマークを設定する。
nがnil 以外であると、
バッファの末尾から10分のnの箇所にポイントを移動する。
対話的に呼び出すと、前置引数があればnは数値前置引数である。
さもなければnのデフォルトは 警告: |
テキスト行とは、改行文字で区切られたバッファの部分です。 改行文字はまえの行に属するとみなします。 最初のテキスト行がバッファの先頭から始まり、 バッファの末尾の文字が改行であってもなくても、 最後のテキスト行はバッファの末尾で終ります。 バッファをテキスト行に分割することは、 ウィンドウの幅、表示上の行の継続、タブやコントロール文字の表示方法には 影響されません。
goto-line line | コマンド |
この関数は、バッファの先頭を1行目と数えてline行目の先頭に
ポイントを移動する。
lineが1未満であると、バッファの先頭へポイントを移動する。
lineがバッファ内の行数より大きいと、
バッファの末尾、つまり、バッファの最後の行の末尾にポイントを移動する。
これは、goto-line が行頭にポイントを移動しない唯一の場面である。
ナロイングしているときでも、
lineはバッファの先頭から数えるが、
参照可能部分の外側にはポイントは移動しない。
したがって、行番号が参照不可な部分を指定するときには、
対話的に呼び出すと、 前置引数があればlineは数値前置引数である。 さもなければlineをミニバッファから読む。 |
beginning-of-line &optional count | コマンド |
この関数は、現在行の先頭にポイントを移動する。
引数countがnil でも1でもないと、
count-1行だけ前方へ移動してから行頭に移動する。
バッファ(ナロイングしているときには参照可能部分)の末尾に達すると ポイントをそこへ移動する。 エラーは通知しない。 |
end-of-line &optional count | コマンド |
この関数は、現在行の末尾にポイントを移動する。
引数countがnil でも1でもないと、
count-1行だけ前方へ移動してから行末に移動する。
バッファ(ナロイングしているときには参照可能部分)の末尾に達すると ポイントをそこへ移動する。 エラーは通知しない。 |
forward-line &optional count | コマンド |
この関数は、count行前方の行頭にポイントを移動する。
countが負であると、
-count行後方の行頭にポイントを移動する。
countが0であると、現在行の先頭にポイントを移動する。
指定行数だけ移動するまえに バッファ(ナロイングしているときには参照可能部分)の先頭や末尾に達すると ポイントをそこへ移動する。 エラーは通知しない。
対話的に呼び出すと、countは数値前置引数である。 |
count-lines start end | Function |
この関数は、カレントバッファのstartとendの
あいだの部分にある行の行数を返す。
startとendが等しければ0を返す。
さもなければ、startとendが同じ行にある場合であっても
少なくとも1を返す。
というのは、それらのあいだのテキストは孤立しているとみなされ、
空でなければ少なくとも1行はあるはずだからである。
(defun current-line () "Return the vertical position of point..." (+ (count-lines (window-start) (point)) (if (= (current-column) 0) 1 0) -1)) |
bolp
やeolp
も参照してください。
これらの関数はポイントを移動しませんが、ポイントがすでに行の先頭や末尾に
あるかどうかを検査します。
前節の行単位の関数は、改行文字で区切られたテキスト行だけを数えます。 対照的に、これらの関数は、スクリーン上にどのようにテキストが現れるかで 定義されるスクリーン上の行を数えます。 テキスト行が選択されているウィンドウの幅に収まるだけ短ければ、 1テキスト行は1スクリーン行ですが、 しかし、それ以外では1テキスト行は複数のスクリーン行を占めます。
テキスト行を複数のスクリーン行に継続せずに
スクリーン上で切り詰める場合もあります。
このような場合、vertical-motion
は、
forward-line
によく似たポイントの移動を行います。
See Truncation。
与えられた文字列の幅は、各文字の見ためを制御するフラグに依存するので、
vertical-motion
は、
テキストを収めたバッファや選択されているウィンドウ
(その幅や切り詰めフラグ、ウィンドウごとに異なりうる表示テーブルが
あるため)に依存して、特定のテキスト部分に対して異なったふるまいをします。
See Usual Display。
これらの関数は、スクリーン行がどこで区切れるかを決定するためにテキストを走査 するので、走査する量に比例して時間がかかります。 読者がこれらを多用する意図があるときには、 読者のコードの効率を改善するキャッシュをEmacsが提供します。 See cache-long-line-scans。
vertical-motion count &optional window | Function |
この関数は、ポイントを含むスクリーン行から
countスクリーン行数だけ下向きにポイントを移動する。
countが負であると上向きに移動する。
ウィンドウwindowは、
幅、水平スクロール、表示テーブルなどのパラメータを得るために使われる。
しかし、windowに別のバッファが表示されているとしても、
|
move-to-window-line count | コマンド |
この関数は、選択されているウィンドウに現在表示されているテキストに
基づいてポイントを移動する。
ウィンドウの先頭からcountスクリーン行の先頭にポイントを移動する。
countが負であると、底(あるいはバッファの末尾がスクリーンの
底より上にある場合にはバッファの最終行)から数えて
-countスクリーン行位置を指定する。
countが 対話的に呼び出されると、countは数値前置引数である。 戻り値は、ウィンドウの先頭行を0と数えて、移動先の行のウィンドウ行番号である。 |
compute-motion from frompos to topos width offsets window | Function |
この関数は、スクリーン上での位置を計算しながらカレントバッファを走査する。
バッファ内位置fromがスクリーン座標fromposに対応すると仮定して、
fromから前方へ向けてtoかtoposのどちらかに
達するまでバッファを走査する。
バッファ内の終了位置とスクリーン座標を返す。
座標引数fromposとtoposは、
引数widthは、テキストを表示できるコラム数であり、
これは継続行の扱いに影響する。
読者が選んだウィンドウに対して 引数offsetsは、 ウィンドウwindowは、使用する表示テーブルを指定するためだけに使われる。
windowに表示されているバッファに関わらず、
戻り値は、5要素のリストである。 (pos vpos hpos prevhpos contin) ここで、posは走査を終えたバッファ内位置であり、 vposは垂直方向のスクリーン位置、 hposは水平方向のスクリーン位置である。 結果のprevhposは、posから1文字分戻った箇所の水平位置である。
この文字のあとで最終行が継続しているときには、
結果のcontinは たとえば、あるウィンドウのlineスクリーン行のcolコラムに
対応するバッファ内位置を探すには、
fromとしてウィンドウの表示開始位置、
fromposとしてウィンドウの左上隅の座標を渡します。
toにはバッファの (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)))) ミニバッファに対して |
ここでは、釣り合った括弧で囲まれた式 (Emacs内でそれらを単位に移動するときにはS式(sexps)とも呼ばれる)を 扱う関数について述べます。 構文テーブルは、これらの関数がさまざまな文字を どのように解釈するかを制御します。 Syntax Tablesを参照してください。 S式やその一部を走査する下位レベルの基本関数については、 See Parsing Expressions。 ユーザーレベルのコマンドに関しては、 List Commandsを参照してください。
forward-list arg | コマンド |
この関数は、釣り合った括弧で囲まれたものをarg個前方へ飛び越えて移動する。 (単語や文字列のクォート対などの他の構文要素は無視する。) |
backward-list arg | コマンド |
この関数は、釣り合った括弧で囲まれたものをarg個後方へ飛び越えて移動する。 (単語や文字列のクォート対などの他の構文要素は無視する。) |
up-list arg | コマンド |
この関数は、前方へ向けてarg個の括弧のレベルを抜ける。 負の引数では後方へ向けて浅いレベルへ移動する。 |
down-list arg | コマンド |
この関数は、前方へ向けてarg個の括弧のレベルだけ深く入る。 負の引数では後方へ向けて括弧の深い(-arg)レベルへ移動する。 |
forward-sexp arg | コマンド |
この関数は、arg個の釣り合った式を前方へ向けて飛び越えて移動する。
釣り合った式には、括弧で区切られたものに加えて、
単語や文字列定数などの他の種類も含まれる。
たとえばつぎのとおり。
---------- Buffer: foo ---------- (concat-!- "foo " (car x) y z) ---------- Buffer: foo ---------- (forward-sexp 3) => nil ---------- Buffer: foo ---------- (concat "foo " (car x) y-!- z) ---------- Buffer: foo ---------- |
backward-sexp arg | コマンド |
この関数は、arg個の釣り合った式を後方へ向けて飛び越えて移動する。 |
beginning-of-defun arg | コマンド |
この関数は、前方へ向けてarg個目の関数定義の先頭へ移動する。 argが負であると、後方へ向けて、 関数定義の末尾ではなく関数定義の先頭へ移動する。 |
end-of-defun arg | コマンド |
この関数は、前方へ向けてarg個目の関数定義の末尾へ移動する。 argが負であると、後方へ向けて、 関数定義の先頭ではなく関数定義の末尾へ移動する。 |
defun-prompt-regexp | User Option |
この変数がnil 以外であると、
関数定義を始める開き括弧のまえに現れうるテキストを指定する正規表現を保持する。
つまり、関数定義は、
行の先頭がこの正規表現に一致するテキストで始まり、
それに開き括弧の構文に属する文字が続く行で始まる。
|
つぎの2つの関数は、指定した種類の文字を飛び越えてポイントを移動します。 たとえば、白文字を飛び越すためにこれらはしばしば使われます。 関連する関数については、Motion and Syntaxを参照してください。
skip-chars-forward character-set &optional limit | Function |
この関数は、指定した文字の集まりを飛び越えて、
カレントバッファ内で前方にポイントを移動する。
ポイントのあとの文字を調べ、
その文字がcharacter-setに一致するとポイントを進める。
これをcharacter-setに一致しない文字に達するまで繰り返す。
この関数は飛び越えた文字の個数を返す。
引数character-setは、正規表現の limitを指定すると(数かマーカであること)、 ポイントを移動できるバッファ内の最大位置を指定する。 ポイントは、limitで止まるかlimitに達するまえに止まる。 つぎの例では、ポイントは最初は ---------- Buffer: foo ---------- I read "-!-The cat in the hat comes back" twice. ---------- Buffer: foo ---------- (skip-chars-forward "a-zA-Z ") => nil ---------- Buffer: foo ---------- I read "The cat in the hat-!- comes back" twice. ---------- Buffer: foo ---------- |
skip-chars-backward character-set &optional limit | Function |
この関数は、limitに達するまで、
後方へ向かってcharacter-setに一致する文字を飛び越えてポイントを移動する。
これはskip-chars-forward と同様であるが、移動方向が異なる。
移動距離を表す値を返す。 それは0以下の整数である。 |
プログラムの局所的な部分で『一時的に』ポイントを移動したり、
一時的にバッファを切り替えられるとしばしば有用です。
これをエクスカージョン(excursion、周遊)と呼び、
スペシャルフォームsave-excursion
で行います。
この構文は、カレントバッファとそのポイントやマーカの値を保存し、
エクスカージョンの完了後にそれらを復元します。
ウィンドウの構成を保存したり復元するフォームは、 別のところで述べてあります (Window Configurationsとsee Frame Configurations)。
save-excursion forms... | Special Form |
スペシャルフォームsave-excursion は、
カレントバッファの識別子とそのポイントやマーカの値を保存し、
formsを評価し、最後に、
バッファと保存しておいたポイントやマーカの値を復元する。
throw やエラーによる異常脱出(see Nonlocal Exits)であっても、
これらの保存した値を復元する。
スペシャルフォーム
同様に、
(save-excursion forms) == (let ((old-buf (current-buffer)) (old-pnt (point-marker)) (old-mark (copy-marker (mark-marker)))) (unwind-protect (progn forms) (set-buffer old-buf) (goto-char old-pnt) (set-marker (mark-marker) old-mark))) |
警告:
保存されたポイント値の箇所に
普通にテキストを挿入すると、すべてのマーカを再配置するように
保存されたポイント値を再配置する。
したがって、保存されたポイント値が復元されると、
ポイントは挿入されたテキストのまえに普通どおりにくる。
save-excursion
はマーカの位置を保存しますが、
バッファを変更する関数がdeactivate-mark
を行うことを防ぎませんから、
コマンドが終了するとマーカが不活性になってしまいます。
See The Mark。
ナロイング(narrowing)とは、 Emacsの編集コマンドが参照できるテキストを バッファの制限された文字の範囲に限定することです。 参照できるテキストのことをバッファの 参照可能部分(accessible portion)と呼びます。
ナロイングは、参照可能部分の先頭と末尾になる2つのバッファ内位置で指定します。 ほとんどの編集コマンドやほとんどのEmacs基本関数にとっては、 これらの位置はバッファの先頭や末尾の値を置き換えることになります。 ナロイングしていると、参照可能部分の外側のテキストは表示されませんし、 ポイントは参照可能部分の外側へは移動できません。
通常はバッファの先頭から数える位置や行番号などの値は ナロイングしていても同様に数えますが、 それらを使う関数は参照できないテキストを操作することを拒否します。
バッファを保存するコマンドはナロイングの影響を受けません。 つまり、ナロイングに関係なくバッファ全体を保存します。
narrow-to-region start end | コマンド |
この関数は、カレントバッファのstartで始まりendで終る部分を
参照可能部分にする。
どちらの引数も文字の位置であること。
対話的に呼び出されると、startとendは 現在のリージョンの境界(ポイントとマークの小さいほうがさきにくる)である。 |
narrow-to-page move-count | コマンド |
このコマンドは、カレントバッファの参照可能部分を
現在のページのみを含むようにする。
省略可能な第1引数move-countがnil 以外であると、
move-countページだけ前方か後方へ移動してから
1ページ分にナロイングする。
変数page-delimiter がページの開始箇所と終了箇所を指定する
(see Standard Regexps)。
対話的に呼び出されると、move-countは数値前置引数である。 |
widen | コマンド |
この関数は、カレントバッファのナロイングを解除し、
全体を参照できるようにする。
これをワイドニング(widening)と呼ぶ。
これはつぎの式と等価である。
(narrow-to-region 1 (1+ (buffer-size))) |
save-restriction body... | Special Form |
このスペシャルフォームは、現在の参照可能部分の境界を保存し、
フォームbodyを評価し、最後に、保存した境界を復元して
まえと同じナロイング状態(あるいはナロイングなし)に復元する。
throw やエラーによる異常脱出(see Nonlocal Exits)であっても、
ナロイング状態を復元する。
注意: bodyでカレントバッファを切り替えても
スペシャルフォーム この方法は、bodyでさらにナロイングしても正しい結果を生じる。
しかし、bodyでワイドニングして保存されているナロイングの範囲外を
変更すると (let ((beg (point-min-marker)) (end (point-max-marker))) (unwind-protect (progn body) (save-excursion (set-buffer (marker-buffer beg)) (narrow-to-region beg end))))
---------- 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 ---------- |
マーカ(marker)とは、バッファ内位置をそれを取り巻くテキストを 基準に指定するために使われるLispオブジェクトです。 テキストが挿入されたり削除されると、 バッファの先頭からマーカまでの距離は自動的に変更され、 マーカは同じ前後の文字のあいだに留まります。
マーカは、バッファとそのバッファ内での位置を指定します。 マーカは、位置を必要とする関数に対して位置を表すものとして使えます。 バッファ内の位置について詳しくはSee Positions。
マーカには2つの属性、つまり、マーカ位置とマーカバッファがあります。 マーカ位置は、当該バッファ内の位置としてのマーカに (その時点で)等価な整数です。 しかし、マーカの生存期間中、マーカ位置の値はしばしば変化します。 バッファにテキストを挿入したり削除すると、マーカは再配置されます。 これは、バッファの任意の箇所で挿入したり削除したとしても、 2つの文字のあいだに置かれたマーカが 同じ文字のあいだに留まるようにするためです。 再配置によって、マーカに等価な整数は変わります。
マーカ位置の周りのテキストを削除すると、
削除されたテキストの前後の文字のあいだにマーカは留まります。
マーカの位置にテキストを挿入すると、
insert-before-markers
(see Insertion)で挿入しない限り、
マーカの挿入型(insertion type)(see Marker Insertion Types)に
依存して、マーカは挿入されたテキストのまえかうしろに留まります。
バッファに対する挿入や削除では、 すべてのマーカを検査し、必要ならばマーカを再配置する必要があります。 マーカを多数抱えるバッファでは、このために処理が遅くなります。 そのため、マーカが不要であると確信したときには、 マーカがどこも指さないようにしておくのがよいです。 参照されていないマーカは最終的には(ガベッジコレクションで)回収されますが、 それまでは、マーカがどこかを指していると処理時間を浪費します。
マーカ位置にはよく算術演算を施すので、
(+
や-
を含む)ほとんどの算術演算は
引数としてマーカを受け付けます。
そのような場合、マーカはその現在位置を表します。
マーカを作って位置を設定し、ポイントをマーカへ移動する例を示します。
;; どこも指していない新しいマーカを作る (setq m1 (make-marker)) => #<marker in no buffer> ;; マーカm1の位置をカレントバッファの ;; 99番目と100番目の文字のあいだにする (set-marker m1 100) => #<marker at 100 in markers.texi> ;; バッファの先頭に1文字挿入する (goto-char (point-min)) => 1 (insert "Q") => nil ;; それにしたがってm1
が更新される m1 => #<marker at 101 in markers.texi> ;; 同じ位置を指す2つのマーカはeq
ではないが ;;equal
である (setq m2 (copy-marker m1)) => #<marker at 101 in markers.texi> (eq m1 m2) => nil (equal m1 m2) => t ;; マーカを使い終ったら、どこも指していないようにする (set-marker m1 nil) => #<marker in no buffer>
オブジェクトがマーカであるかどうかや、 オブジェクトが整数かマーカであるかどうかを検査できます。 マーカと整数の両者を扱う算術関数に関連して、 後者の検査は有用です。
markerp object | Function |
この関数は、objectがマーカであればt を返し、
さもなければnil を返す。
多くの関数がマーカや整数を受け付けるが、
整数はマーカではないことに注意すること。
|
integer-or-marker-p object | Function |
この関数は、objectが整数かマーカであるとt を返し、
さもなければnil を返す。
|
number-or-marker-p object | Function |
この関数は、objectが数(整数か浮動小数点数)かマーカであると
t を返し、さもなければnil を返す。
|
新たにマーカを作成するときには、そのマーカが、 どこも指していない、現在のポイント位置を指している、 バッファの参照可能部分の先頭や末尾を指している、 別のマーカと同じ箇所を指しているのいずれかにできます。
make-marker | Function |
この関数は、どこも指していない新たに作成したマーカを返す。
(make-marker) => #<marker in no buffer> |
point-marker | Function |
この関数は、カレントバッファの現在のポイント位置を
指す新たに作成したマーカを返す。
see Point。
例については、下記のcopy-marker を参照。
|
point-min-marker | Function |
この関数は、バッファの参照可能部分の先頭を指す新たに作成したマーカを返す。 ナロイングしていなければ、これはバッファの先頭である。 see Narrowing。 |
point-max-marker | Function |
この関数は、バッファの参照可能部分の末尾を指す新たに作成したマーカを返す。
ナロイングしていなければ、これはバッファの末尾である。
see Narrowing。
本章のソースファイル(の原文)を入れたバッファでの
この関数と (point-min-marker) => #<marker at 1 in markers.texi> (point-max-marker) => #<marker at 15573 in markers.texi> (narrow-to-region 100 200) => nil (point-min-marker) => #<marker at 100 in markers.texi> (point-max-marker) => #<marker at 200 in markers.texi> |
copy-marker marker-or-integer &optional insertion-type | Function |
引数としてマーカを渡されると、copy-marker は、
marker-or-integerが指すのと同じ
バッファとバッファ内位置を指す新たなマーカを返す。
引数として整数を渡されると、copy-marker は、
カレントバッファで位置marker-or-integerを指す新たなマーカを返す。
新たなマーカの挿入型は引数insertion-typeで指定する。 see Marker Insertion Types。 渡された整数引数が1未満であると、 (copy-marker 0) => #<marker at 1 in markers.texi> (copy-marker 20000) => #<marker at 7572 in markers.texi> marker-or-integerがマーカでも整数でもないと、エラーを通知する。 |
2つの異なるマーカが、同じバッファの同じバッファ内位置であるか、
どちらもどこも指していないときには、
両者を(eq
ではないが)equal
とみなします。
(setq p (point-marker)) => #<marker at 2139 in markers.texi> (setq q (copy-marker p)) => #<marker at 2139 in markers.texi> (eq p q) => nil (equal p q) => t
本節では、マーカオブジェクトの構成要素を参照する関数について述べます。
marker-position marker | Function |
この関数は、markerが指す位置を返す。
あるいは、markerがどこも指していなければnil を返す。
|
marker-buffer marker | Function |
この関数は、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.texi> (marker-buffer m) => #<buffer markers.texi> (marker-position m) => 3770 |
マーカが指す箇所に直接テキストを挿入すると、
マーカの再配置方法には2つの可能性、つまり、
挿入したテキストのまえに留まるか、あとにくるかのどちらかです。
マーカの挿入型(insertion type)を設定することで、
あるマーカではどちらを選ぶか指定できます。
insert-before-markers
を使うとマーカの挿入型は無視され、
マーカは挿入したテキストのうしろにつねに再配置されることに注意してください。
set-marker-insertion-type marker type | Function |
この関数は、マーカmarkerの挿入型をtypeとする。
typeがt であると、
テキストが挿入されるとmarkerはその位置へ進む。
typeがnil であると、
テキストが挿入されてもmarkerはその位置へ進まない。
|
marker-insertion-type marker | Function |
この関数は、markerの現在の挿入型を報告する。 |
本節では、既存のマーカの位置を変更する方法について述べます。 これを行うときには、読者のプログラムの外側で 当該マーカが使われているかどうか、 使われているときには移動による効果はなにかを確実に理解してください。 さもないと、Emacsの別の部分で混乱を生じるかもしれません。
set-marker marker position &optional buffer | Function |
この関数は、bufferにおいてmarkerをpositionへ移動する。
bufferを与えないと、デフォルトはカレントバッファである。
positionが1未満であると、
戻り値はmarkerである。 (setq m (point-marker)) => #<marker at 4714 in markers.texi> (set-marker m 55) => #<marker at 55 in markers.texi> (setq b (get-buffer "foo")) => #<buffer foo> (set-marker m 0 b) => #<marker at 1 in foo> |
move-marker marker position &optional buffer | Function |
これはset-marker の別名である。
|
各バッファの1つの特別なマーカをマーク(mark)として区別します。
これは、kill-region
やindent-rigidly
などのコマンド向けに
ユーザーのために位置を記録するものです。
Lispプログラムでは、ユーザーが使う可能性のある値だけをマークに設定し、
プログラムの内部向けにはけっしてマークを使いません。
たとえば、コマンドreplace-regexp
は、
置換を行うまえのポイント値をマークに設定します。
置換を完了したあとに、ユーザーが手軽にまえの位置に戻れるようにするためです。
多くのコマンドは、対話的に呼ばれるとポイントとマークのあいだの
テキストに作用するように設計されています。
読者がそのようなコマンドを書くときには、
マークを直接検査しないでください。
そのかわりに、r
を指定したinteractive
を使います。
こうすると、
対話的に呼ばれるとポイントとマークの値がコマンドの引数に与えられますが、
別のLispプログラムからは引数を明示できます。
See Interactive Codes。
各バッファには、他のバッファのマークの値とは独立な 独自のマークの値があります。 バッファが作成されると、マークは存在しますがどこも指さない状態です。 これを『バッファのマークは欠如している』状態とみなします。
バッファでいったんマークが『存在』するようになれば、
マークが存在しなくなることは普通はありません。
しかし、暫定マーク(transient-mark)モードをオンにすると、
マークが不活性になることはあります。
すべてのバッファでつねにバッファローカルな変数mark-active
が
マークが活性かどうかを表します。
その値がnil
以外であるとマークは活性です。
コマンドでdeactivate-mark
にnil
以外の値を設定すると、
エディタコマンドループに戻ったときにマークを不活性にするようにできます
(ただし、暫定マーク(transient-mark)モードがオンの場合に限る)。
暫定マーク(transient-mark)モードを使う主な目的は、 マークが活性であるとこのモードはリージョンを強調表示するからです。 See Display。
マークに加えて、各バッファにはマークリング(mark ring)、
つまり、マークの以前の値を保持したリストがあります。
編集コマンドがマークを変更すると、
通常、編集コマンドはマークの古い値をマークリングに保存します。
変数mark-ring-max
で、マークリングに収める要素の最大個数を指定します。
リストがこの長さに達すると、新たな要素を加えるたびに古い要素を削除します。
mark &optional force | Function |
この関数は、カレントバッファのマーク位置を整数で返す。
マークが不活性であると、通常、 |
mark-marker | Function |
この関数は、カレントバッファのマークを返す。
これは、Emacs内部のマーク位置を記録したマーカそのものであり、コピーではない。
したがって、このマーカの位置を変更すると、マークの位置に直接影響する。
この効果を望まない限り、そのようにしないこと。
(setq m (mark-marker)) => #<marker at 3420 in markers.texi> (set-marker m 100) => #<marker at 100 in markers.texi> (mark-marker) => #<marker at 100 in markers.texi> 他のマーカと同様に、このマーカは任意のバッファでポイントを指すようにできる。 マークが指しているバッファ以外のバッファ内位置を指すことは勧めない。 そのようにすると、一貫性はあるが妙な結果を生じる。 |
set-mark position | Function |
この関数は、位置positionにマークを設定し、マークを活性にする。
マークの古い値はマークリングに保存しない。
注意: Emacs Lispの初心者プログラマは、誤った目的にマークを使いがちである。 マークはユーザーの便宜のための位置を保存する。 編集コマンドは、 コマンドのユーザーレベルの機能の一部としてマークを変更する以外には、 マークを変更してはならない。 (変更する場合には、その効果を明文化しておくべきである。) Lispプログラムの内部で使う位置を記録するには、Lisp変数に保存する。 たとえばつぎのようにする。 (let ((beg (point))) (forward-line 1) (delete-region beg (point))). |
push-mark &optional position nomsg activate | Function |
この関数は、カレントバッファのマークをpositionとし、
以前のマークのコピーをmark-ring へ入れる。
positionがnil であると、ポイントの値を使う。
push-mark はnil を返す。
関数 nomsgが |
pop-mark | Function |
この関数は、mark-ring から先頭要素を取り出し、
そのマークをカレントバッファの実際のマークとする。
バッファのポイントは移動しない。
また、mark-ring が空であるとなにもしない。
マークを不活性にする。
戻り値に意味はない。 |
transient-mark-mode | User Option |
この変数がnil 以外であると
暫定マーク(transient-mark)モードがオンであるが、
バッファを変更する各基本関数はdeactivate-mark に設定する。
つまり、バッファを変更するコマンドは、通常、マークを不活性にする。
|
mark-even-if-inactive | User Option |
これがnil 以外であると、
LispプログラムやEmacsユーザーは、マークが不活性であってもマークを使える。
このオプションは、暫定マーク(transient-mark)モードのふるまいに影響する。
このオプションがnil 以外であると、
マークが不活性になるとリージョンの強調表示を止めるが、
マークを使うコマンドはマークが活性であるものとして動作する。
|
deactivate-mark | Variable |
編集コマンドがこの変数にnil 以外を設定すると、
エディタコマンドループは(暫定マーク(transient-mark)モードがオンであると)
コマンドから戻るとマークを不活性にする。
コマンドが終了したらマークを不活性にするために、
バッファを変更するすべての基本関数はdeactivate-mark に設定する。
|
deactivate-mark | Function |
この関数は、暫定マーク(transient-mark)モードが オンであるとマークを不活性にする。 さもなければなにもしない。 |
mark-active | Variable |
この変数がnil 以外であると、マークは活性である。
この変数は各バッファにおいてつねにバッファローカルである。
|
activate-mark-hook | Variable |
deactivate-mark-hook | Variable |
これらのノーマルフックは、それぞれ、
マークが活性になったとき、不活性になったときに実行される。
マークが活性でありリージョンが変更されたときには、
フックactivate-mark-hook はコマンドの終りでも実行される。
|
mark-ring | Variable |
このバッファローカルな変数の値は、
カレントバッファで保存したマークを最新のものから順に並べたリストである。
mark-ring => (#<marker at 11050 in markers.texi> #<marker at 10832 in markers.texi> ...) |
mark-ring-max | User Option |
この変数の値は、mark-ring の最大の大きさである。
これより多くのマークをmark-ring に積むと、
push-mark は新しいものを追加するときに古いものを削除する。
|
ポイントとマークのあいだのテキストをリージョン(region)といいます。 さまざまな関数がポイントとマークで区切られたテキストに作用しますが、 リージョンそのものに特に関連した関数だけについてここで述べます。
region-beginning | Function |
この関数は、リージョンの先頭の位置を(整数で)返す。
これは、ポイントかマークの小さいほうの位置である。
マークがどこも指していなければ、エラーを通知する。 |
region-end | Function |
この関数は、リージョンの末尾の位置を(整数で)返す。
これは、ポイントかマークの大きいほうの位置である。
マークがどこも指していなければ、エラーを通知する。 |
関数region-beginning
やregion-end
を使う必要がある
プログラムはほとんどないはずです。
リージョンに作用するように設計されたコマンドは、
普通、r
を指定したinteractive
を使って
リージョンの先頭と末尾をみつけます。
これにより、Lispプログラムからは引数として境界を明示的に指定できます。
(See Interactive Codes。)
本章では、バッファ内のテキストを扱う関数について述べます。 それらのほとんどは、カレントバッファ内のテキストを 調べたり挿入したり削除しますが、しばしばポイント付近で行います。 多くは対話的に使えます。 テキストを変更するすべての関数は、変更を取り消せます(see Undo)。
テキスト関連の多くの関数は、startとendという名前の引数で渡された
2つのバッファ内位置で定義されるテキストの領域に作用します。
これらの引数は、マーカ(see Markers)であるか
文字の位置を表す数値(see Positions)である必要があります。
これらの引数の順番は関係なく、startが領域の終了位置で
endが開始位置であってもまったく問題ありません。
たとえば、(delete-region 1 10)
と(delete-region 10 1)
は同値です。
startやendがバッファの参照可能部分の外側にあると
エラーargs-out-of-range
を通知します。
対話的な呼び出しでは、ポイントとマークをこれらの引数として使います。
本章では、バッファ内の文字を(関係あるときには) それらのテキスト属性を含めて『テキスト』と呼びます。
多くの関数は、ポイント付近の文字を調べるためのものです。
ここでは、数個の単純な関数について述べます。
Regexp Searchのlooking-at
も参照してください。
char-after &optional position | Function |
この関数は、カレントバッファ内の位置positionにある
(つまり直後の)文字を返す。
positionがバッファの先頭のまえや末尾のうしろにあるなどして
この目的に適した範囲の外側にあると、値はnil である。
positionのデフォルトはポイントである。
つぎの例では、バッファの最初の文字は (char-to-string (char-after 1)) => "@" |
char-before &optional position | Function |
この関数は、カレントバッファ内の位置positionのまえにある文字を返す。
positionがバッファの先頭のまえや末尾のうしろにあるなどして
この目的に適した範囲の外側にあると、値はnil である。
positionのデフォルトはポイントである。
|
following-char | Function |
この関数は、カレントバッファのポイントのうしろにある文字を返す。
これは(char-after (point)) と同様である。
しかし、ポイントがバッファの末尾にあると、
following-char は0を返す。
ポイントはつねに文字のあいだにあり、
端末のカーソルはポイントの直後の文字に重ねて表示されることに注意してほしい。
したがって、 つぎの例では、ポイントは ---------- Buffer: foo ---------- Gentlemen may cry ``Pea-!-ce! Peace!,'' but there is no peace. ---------- Buffer: foo ---------- (char-to-string (preceding-char)) => "a" (char-to-string (following-char)) => "c" |
preceding-char | Function |
この関数は、カレントバッファのポイントのまえの文字を返す。
例については上記のfollowing-char を参照。
ポイントがバッファの先頭にあると、preceding-char は0を返す。
|
bobp | Function |
この関数は、ポイントがバッファの先頭にあるとt を返す。
ナロイングしていると、これはバッファの参照可能部分の先頭を意味する。
Pointのpoint-min も参照。
|
eobp | Function |
この関数は、ポイントがバッファの末尾にあるとt を返す。
ナロイングしていると、これはバッファの参照可能部分の末尾を意味する。
Pointのpoint-max も参照。
|
bolp | Function |
この関数は、ポイントが行頭にあるとt を返す。
see Text Lines。
バッファ(あるいはその参照可能部分)の先頭は、
つねに行頭とみなす。
|
eolp | Function |
この関数は、ポイントが行末にあるとt を返す。
see Text Lines。
バッファ(あるいはその参照可能部分)の末尾は、
つねに行末とみなす。
|
本節では、Lispプログラムでバッファ内の任意の部分のテキストを文字列に変換する ための2つの関数について述べます。
buffer-substring start end | Function |
この関数は、カレントバッファのstartとendの位置で定義される
領域のテキストのコピーを含んだ文字列を返す。
引数がバッファの参照可能部分の内側の位置でないと、
buffer-substring はエラーargs-out-of-range を通知する。
startがendより小さい必要はなく、引数の順番はどちらでもよい。 しかし、ほとんどの場合、小さい引数を先に書く。 コピーされるテキストにテキスト属性がある場合、 テキスト属性もそれが属する文字とともに文字列へコピーされる。 see Text Properties。 しかし、バッファのオーバレイ(see Overlays)とそれらの属性は 無視されコピーされない。 ---------- 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 " |
buffer-substring-no-properties start end | Function |
この関数はbuffer-substring と同様であるが、
テキスト属性をコピーせずに文字だけをコピーする点が異なる。
see Text Properties。
|
buffer-string | Function |
この関数は、カレントバッファの参照可能部分全体の内容を文字列として返す。
これは、つぎと等価である。
(buffer-substring (point-min) (point-max)) ---------- Buffer: foo ---------- This is the contents of buffer foo ---------- Buffer: foo ---------- (buffer-string) => "This is the contents of buffer foo " |
thing-at-point thing | Function |
ポイントの周りやそのうしろにあるthingを文字列として返す。
引数thingは、構文上の要素の種類を指定するシンボルである。
可能な値は、 ---------- 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 |
この関数により、バッファ内のテキストの部分同士を 文字列にコピーせずに比較できます。
compare-buffer-substrings buffer1 start1 end1 buffer2 start2 end2 | Function |
この関数は、同一バッファ内の2つの部分文字列、あるいは、
異なる2つのバッファの部分文字列を比較する。
始めの3つの引数は、バッファとそのバッファ内の2つの位置を与え、
1つの部分文字列を指定する。
残りの3つの引数も同様にして別の部分文字列を指定する。
カレントバッファを表すために、
buffer1とbuffer2のいずれか、あるいは、
両方にnil を指定できる。
始めの文字列のほうが小さければ値は負であり、 始めのほうが大きければ値は正であり、等しければ0である。 結果の絶対値は、部分文字列の中で最初に異なる文字の添字足す1である。 この関数は、 カレントバッファにはテキスト (compare-buffer-substring nil 6 11 nil 16 21) => 2 |
挿入(insertion)とは、バッファに新たなテキストを追加することです。 挿入されたテキストはポイント位置に、つまり、 ポイントのまえの文字とポイントのあとの文字のあいだに入ります。 挿入されたテキストのまえにポイントを留める関数もあれば、 そのうしろに留める関数もあります。 前者をポイントのうしろへ挿入と呼び、 後者をポイントのまえへ挿入と呼びます。
挿入により、挿入箇所よりうしろの位置を指すマーカは再配置されて
同じ周りの文字に留まります(see Markers)。
マーカが挿入箇所を指している場合には、
マーカの挿入型(see Marker Insertion Types)に依存して、
挿入するとマーカが再配置されたりされなかったりします。
insert-before-markers
などの特定の特殊な関数は、
マーカの挿入型に関わらず、
挿入されたテキストのうしろを指すように
そのようなすべてのマーカを再配置します。
カレントバッファが読み出し専用であると、挿入関数はエラーを通知します。
これらの関数は、テキストの文字群をそれらの属性とともに 文字列からバッファへコピーします。 挿入された文字群は、コピーされるまえとまったく同じ属性を持ちます。 対照的に、文字列やバッファの一部ではない孤立した引数として 指定された文字群は、周りのテキストからテキスト属性を継承します。
挿入関数は、文字列由来やバッファ由来のテキストの場合には、 マルチバイトバッファへ挿入するために ユニバイトからマルチバイトへテキストを変換し、逆向きの変換も行います。 しかし、カレントバッファがたとえマルチバイトバッファであっても、 128から255のユニバイト文字コードはマルチバイト文字には変換しません。 See Converting Representations。
insert &rest args | Function |
この関数は、文字列や文字群argsをカレントバッファのポイント位置に挿入し、
ポイントを先へ進める。
いいかえれば、ポイントのまえにテキストを挿入する。
argsが文字列でも文字でもないと、エラーを通知する。
値はnil である。
|
insert-before-markers &rest args | Function |
この関数は、文字列や文字群argsをカレントバッファのポイント位置に挿入し、
ポイントを先へ進める。
argsが文字列でも文字でもないと、エラーを通知する。
値はnil である。
挿入箇所を指していたマーカを挿入されたテキストのうしろを指すように再配置 する点で、この関数は他の挿入関数と異なる。 挿入箇所でオーバレイが始まるときには、 挿入されたテキストはオーバレイの範囲外に出る。 空でないオーバレイが挿入箇所で終るときには、 挿入されたテキストはオーバレイの範囲内に入る。 |
insert-char character &optional count inherit | Function |
この関数は、カレントバッファのポイントのまえに
文字characterをcount個挿入する。
引数countは数(nil は1を意味する)であり、
characterは文字であること。
値はnil である。
この関数は、カレントバッファがたとえマルチバイトバッファであっても、 128から255のユニバイト文字コードはマルチバイト文字には変換しない。 see Converting Representations。 inheritが |
insert-buffer-substring from-buffer-or-name &optional start end | Function |
この関数は、バッファfrom-buffer-or-name(既存であること)の部分を
カレントバッファのポイントのまえへ挿入する。
挿入されるテキストはstartからendまでの領域である。
(これらの引数のデフォルトは、当該バッファの参照可能部分の先頭と末尾である。)
この関数はnil を返す。
この例では、バッファ ---------- 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 ---------- |
挿入に加えて周りのテキストからテキスト属性を継承する他の関数については、 See Sticky Properties。 字下げ関数が挿入した白文字もテキスト属性を継承します。
本節では、テキストを挿入する上位レベルのコマンドについて述べます。 これらはLispプログラムでも有用ですが主にユーザー向けのコマンドです。
insert-buffer from-buffer-or-name | コマンド |
このコマンドは、from-buffer-or-name(既存であること)の全内容を
カレントバッファのポイントのうしろに挿入する。
挿入されたテキストのうしろにマークを置く。
値はnil である。
|
self-insert-command count | コマンド |
このコマンドは、最後に打たれた文字を挿入する。
ポイントのまえにcount回挿入してnil を返す。
ほとんどの印字文字はこのコマンドにバインドされている。
普通の状況では、self-insert-command は
Emacsにおいてもっとも頻繁に呼び出される関数であるが、
プログラムではキーマップに登録する以外にはほとんど使わない。
対話的に呼ばれると、countは数値前置引数である。 このコマンドは、挿入した文字が空白や改行であると、
このコマンドは、略語(abbrev)モードがオンであり、かつ、 挿入した文字が単語構成構文でないと、略語展開を行う。 (Abbrevsとsee Syntax Class Table。) 挿入した文字が閉じ括弧構文であるときに
|
newline &optional number-of-newlines | コマンド |
このコマンドは、カレントバッファのポイントのまえに改行を挿入する。
number-of-newlinesを指定すると、その個数だけ改行文字を挿入する。
この関数は、現在のコラム番号が このコマンドは、左端の余白が0以外であるとその分だけ字下げする。 see Margins。 戻り値は |
split-line | コマンド |
このコマンドは、行のポイントのうしろの部分を垂直に降ろして
変更前の真下に行を移動することで現在行を分割する。
関数indent-to を用いて、降ろした行の先頭に必要に応じて白文字を挿入する。
プログラムではまったくこの関数を使わない。 |
overwrite-mode | Variable |
この変数は、上書き(overwrite)モードがオンかどうかを制御する。
この値は、overwrite-mode-textual 、overwrite-mode-binary 、
nil のいずれかであること。
overwrite-mode-textual は、テキストの上書きモード
(改行とタブを特別に扱う)を指定し、
overwrite-mode-binary は、バイナリの上書きモード
(改行やタブも他の文字と同様に扱う)を指定する。
|
削除とは、バッファ内のテキストのある部分をキルリング (see The Kill Ring)に保存せずに取りさることです。 削除したテキストはヤンクはできませんが、 アンドゥ機構(see Undo)を使って再度挿入できます。 特別な場合にはキルリングにテキストを保存する削除関数もあります。
すべての削除関数はカレントバッファに作用し、nil
の値を返します。
erase-buffer | コマンド |
この関数は、カレントバッファから全テキストを削除して空にする。
バッファが読み出し専用であると、エラーbuffer-read-only を通知する。
さもなければ、いっさい確認を取らずにテキストを削除する。
nil を返す。
バッファから多量のテキストを削除すると、通常、
『バッファが縮小した』としてそのバッファの自動保存を禁止する。
しかし、 |
delete-region start end | コマンド |
このコマンドは、startとendで定義されるカレントバッファの
テキストを削除する。
戻り値はnil である。
削除された領域の内側にポイントがあると、
その値は削除後にはstartになる。
さもなければ、マーカと同様にポイントは
周りのテキストに留まるように再配置される。
|
delete-char count &optional killp | コマンド |
このコマンドは、ポイントの直後の、あるいは、
countが負であるとポイントの直前のcount個の文字を削除する。
killpがnil 以外であると、
削除した文字をキルリングに保存する。
対話的に呼ばれると、countは数値前置引数であり、 killpは未処理の前置引数である。 つまり、前置引数を指定すると、テキストをキルリングに保存する。 前置引数を指定しないと1文字だけを削除するが、 キルリングには保存しない。 戻り値はつねに |
delete-backward-char count &optional killp | コマンド |
このコマンドは、ポイントの直前の、あるいは、
countが負であるとポイントの直後のcount個の文字を削除する。
killpがnil 以外であると、
削除した文字をキルリングに保存する。
対話的に呼ばれると、countは数値前置引数であり、 killpは未処理の前置引数である。 つまり、前置引数を指定すると、テキストをキルリングに保存する。 前置引数を指定しないと1文字だけを削除するが、 キルリングには保存しない。 戻り値はつねに |
backward-delete-char-untabify count &optional killp | コマンド |
このコマンドは、タブを空白にかえながら後向きにcount個の文字を削除する。
つぎに削除する文字がタブであると、まずタブを配置を保つだけの等価な個数の
空白に置換してから、タブのかわりにそれらの空白を削除する。
killpがnil 以外であると、このコマンドは
削除した文字をキルリングに保存する。
countが正である場合に限って、タブを空白に変換する。 countが負であると、ポイントのうしろのちょうど -count個の文字を削除する。 対話的に呼ばれると、countは数値前置引数であり、 killpは未処理の前置引数である。 つまり、前置引数を指定すると、テキストをキルリングに保存する。 前置引数を指定しないと1文字だけを削除するが、 キルリングには保存しない。 戻り値はつねに |
backward-delete-char-untabify-method | User Option |
このオプションは、backward-delete-char-untabify での
白文字の扱い方を指定する。
可能な値は、タブを空白に変換してから空白を削除することを意味する
デフォルトのuntabify 、
1回の呼び出しでポイントのまえにある白文字をすべて削除することを意味する
hungry 、
白文字に対して特別なことをしないことを意味するnil である。
|
本節では、テキストを削除する上位レベルのコマンドについて述べます。 これらはLispプログラムでも有用ですが主にユーザー向けのコマンドです。
delete-horizontal-space | コマンド |
この関数は、ポイントの周りの空白やタブをすべて削除する。
nil を返す。
つぎの例では、毎回ポイントを2番目と3番目の文字のあいだに置いて、
各行につき1回ずつ ---------- 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 ---------- |
delete-indentation &optional join-following-p | コマンド |
この関数は、ポイントがある行をそのまえの行に連結する。
連結箇所の白文字は削除し、場合によっては空白1個に置き換える。
join-following-pがnil 以外であると、
delete-indentation は、この行を後続の行に連結する。
関数はnil を返す。
詰め込み接頭辞があり、かつ、連結対象の2番目の行が
その接頭辞で始まっている場合には、
以下の例では、ポイントは ---------- 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 | Function |
この関数は、文脈に応じて、
ポイントを囲む白文字すべてを1つの空白に置換するかまったくなくす。
nil を返す。
行の先頭や末尾では、空白の適切な量は0である。 閉じ括弧構文の文字のまえや、 開き括弧構文や式前置子構文の文字のうしろでも空白はないほうが適している。 それ以外では、空白1個が適している。 see Syntax Class Table。 以下の例では、最初の行の単語 ---------- 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 ---------- |
just-one-space | コマンド |
このコマンドは、ポイントの周りのすべての空白やタブを1個の空白に置き換える。
nil を返す。
|
delete-blank-lines | コマンド |
この関数は、ポイントを囲む空行を削除する。
前後に複数の空行がある空行にポイントがある場合、
1つの空行を残してそれ以外はすべて削除する。
孤立した1つの空行にポイントがある場合には、その行を削除する。
空行でない行にポイントがある場合には、
その行のうしろにある空行をすべて削除する。
空行とは、タブや空白のみから成る行と定義する。
|
キル関数は削除関数のようにテキストを削除しますが、
ユーザーがヤンク(yank)で再度挿入できるように保存します。
これらの関数の多くは、その名前にkill-
があります。
対照的に、delete-
で始まる名前の関数は、
ヤンクできるようにテキストを保存しません(アンドゥはできる)。
それらは『削除』関数です。
キルコマンドの多くは主に対話的に使うものであり、 ここではそれらについては述べません。 ここで述べるのは、そのようなコマンドを書くために使う関数についてです。 これらの関数は読者がテキストをキルするコマンドを書くために使えます。 Lisp関数において内部目的のためにテキストを削除する必要があるときには、 キルリングの内容を乱さないように普通は削除関数を用いるべきです。 See Deletion。
キルしたテキストはあとでヤンクできるように
キルリング(kill ring)に保存されます。
これは、最後にキルしたテキストだけでなく、
最近キルしたものを多数保持するリストです。
これを『リング』と呼ぶのは、
要素が循環しているようにヤンクが扱うからです。
このリストは変数kill-ring
に保持されていて、
リスト向けの通常の関数で操作できますが、
本節で述べるように、それをリングとして扱う特別な関数もあります。
単語『キル』の使い方が不適当だと考える人々がいます。 『キル』したものを特に破壊しない操作を表すために使っているからです。 日常生活に照らしてみると、死は恒久的であり『キル』したものが 生き返ることはありません。 したがって、別の隠喩も提案されています。 たとえば、原稿を鋏で切り貼りすることに慣れていた前計算機世代の人々には 『カットリング』のほうが意味が通じるでしょう。 しかし、いまさら用語を変更するのは困難です。
キルリングは、もっとも最近にキルされたものを先頭にして、 キルされたテキストを文字列としてリストに記録します。 たとえば、短いキルリングはつぎのようになります。
("some text" "a different piece of text" "even older text")
リストの長さがkill-ring-max
に達すると、
新たな項目を追加すると自動的に最後の項目を削除します。
キルコマンドが他のコマンドと混在する場合、 各キルコマンドはキルリングに新たな項目を追加します。 連続した複数のキルコマンドは、キルリングに1つの項目を作りあげ、 それを1個としてヤンクできます。 2番目以降の連続したキルコマンドは、最初のキルコマンドが作った 項目にテキストを追加していきます。
ヤンクでは、キルリングの1つの項目をリングの『先頭』として区別します。 リングの別の項目を『先頭』と指定することでリングを『回転』する コマンドもあります。
kill-region
は、テキストをキルするための普通のサブルーティンです。
この関数を呼び出す任意のコマンドは『キルコマンド』です
(その名前にはkill
があるはず)。
kill-region
は、新たにキルされたテキストを
キルリングの先頭に新たな項目として追加したり、
もっとも最近の項目に加えます。
まえのコマンドがキルコマンドであるかどうかを
(last-command
を使って)自動的に判定し、
もしそうならば、キルされたテキストをもっとも最近の項目に加えます。
kill-region start end | コマンド |
この関数は、startとendで定義される領域のテキストをキルする。
テキストは削除されるが、テキスト属性とともにキルリングに保存される。
値はつねにnil である。
対話的に呼ばれると、startとendはポイントとマークである。 バッファが読み出し専用であると、
|
kill-read-only-ok | User Option |
このオプションがnil 以外であると、
kill-region は、バッファが読み出し専用であってもエラーとしない。
そのかわりに、キルリングを更新しバッファは変更せずに戻る。
|
copy-region-as-kill start end | コマンド |
このコマンドは、startとendで定義される領域を
(テキスト属性とともに)キルリングに保存するが、
バッファからテキストを削除しない。
nil を返す。
また、カーソルを一時的に移動してコピーしたテキストの範囲を示すか、
あるいは、エコー領域にメッセージを表示する。
このコマンドは Emacs 18版でも使うつもりがない限り、
Lispプログラムからは |
ヤンク(yank)とは、キルリングからまえにキルされたテキストの項目を 再度挿入することです。
yank &optional arg | コマンド |
このコマンドは、キルリングの先頭項目のテキストを
ポイントのまえに挿入する。
そのテキストの先頭にマークを末尾にポイントを置く。
argがリスト(対話的な呼び出しではユーザーが数字文字なしに
C-uを打ったとき)であると、 argが数であると、
|
yank-pop arg | コマンド |
このコマンドは、キルリングからヤンクした項目を
キルリングの別の項目で置き換える。
これは argが キルリング内でのキルの順番は、 最古のもののつぎに最新のものがあり、 最新のもののまえに最古のものがあるように折り返されている。 戻り値はつねに |
これらの関数と変数は、下位レベルでキルリングを参照するためのものですが、 Lispプログラムで使っても便利です。 これらはウィンドウシステムのセレクション(see Window System Selections) との相互作用の面倒をみてくれるからです。
current-kill n &optional do-not-move | Function |
関数current-kill は、キルリングの『先頭』として区別する
ヤンクポインタを(新しいキルから古いキルへ向けて)n個分回転し、
リングのその位置のテキストを返す。
省略可能な第2引数do-not-moveが nが0であると、もっとも最近のキルを要求することを表し、
|
kill-new string | Function |
この関数は、テキストstringを新たな項目として
キルリングの先頭に置く。
必要ならば最古の項目を破棄する。
interprogram-cut-function (下記参照)の値も起動する。
|
kill-append string before-p | Function |
この関数は、キルリングの先頭項目にテキストstringを追加する。
通常、stringはその項目の末尾に加わるが、
before-pがnil 以外であるとその項目の先頭に加わる。
この関数は、interprogram-cut-function (下記参照)の値も起動する。
|
interprogram-paste-function | Variable |
この変数は、ウィンドウシステムを使っているときに
別のプログラムからキルされたテキストを転送する方法を提供する。
その値は、nil であるか、引数なしの関数であること。
値が関数であると、
『もっとも最近のキル』を得るために このフックの普通の用途は、 セレクションが別のアプリケーションに属する場合であっても、 ウィンドウシステムの一次セレクションを もっとも最近のキルとして得ることである。 see Window System Selections。 |
interprogram-cut-function | Variable |
この変数は、ウィンドウシステムを使っているときに
キルされたテキストを別のプログラムへ転送する方法を提供する。
その値は、nil であるか、引数なしの関数であること。
値が関数であると、 このフックの普通の用途は、 新たにキルされたテキストを ウィンドウシステムの一次セレクションにすることである。 see Window System Selections。 |
変数kill-ring
は、文字列のリストの形でキルリングの内容を保持します。
もっとも最近のキルがつねにリストの先頭にあります。
変数kill-ring-yank-pointer
は、
CARがつぎにヤンクすべきテキストであるような
キルリングリストの項目を指しています。
この変数がリングの『先頭』を識別するといいます。
kill-ring-yank-pointer
を別の項目へ動かすことを
キルリングを回転すると呼びます。
ヤンクポインタを動かす関数は、
リストの末尾からリストの先頭へ折り返しその逆も行うので、
キルリングを『リング』と呼ぶのです。
リングの回転は仮想的なものであり、
kill-ring
の値は変更しません。
kill-ring
もkill-ring-yank-pointer
もLisp変数であり、
それらの値は普通のリストです。
kill-ring-yank-pointer
の名前の単語『ポインタ』は、
つぎのヤンクコマンドで使うリストの項目を識別することが
変数の目的であることを表します。
kill-ring-yank-pointer
の値は、キルリングリストの
1つの項目とつねにeq
です。
これが識別する項目は、その項目のCARです。
キルリングを変更するキルコマンドも、
kill-ring
の値をこの変数の値とします。
その効果は、新たにキルされたテキストが先頭にくるように
リングを回転することです。
キルリング("some text" "a different piece of text" "yet older text")
の
第2項目を変数kill-ring-yank-pointer
が指しているようすをつぎに示します。
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
)を使うと
この状態になります。
kill-ring | Variable |
この変数は、もっとも最近にキルされたものを最初にして キルされたテキストを順に並べたリストを保持する。 |
kill-ring-yank-pointer | Variable |
この変数の値は、キルリングのどの要素が
ヤンクするためのリングの『先頭』であるかを表す。
より正確には、その値はkill-ring のリストの一部であり、
そのCARはC-yがヤンクするキルされた文字列である。
|
kill-ring-max | User Option |
この変数の値は、末尾の要素が破棄されるまでに
キルリングが増大できる最大の長さである。
kill-ring-max のデフォルト値は30である。
|
ほとんどのバッファには、バッファのテキストに対する変更をアンドゥ(もとに戻す)
できるようにすべての変更を記録する
アンドゥリスト(undo list)があります。
(アンドゥリストのないバッファは、
Emacsがアンドゥは有用ではないと仮定する特殊目的のバッファである。)
バッファのテキストを変更するすべての基本関数は、
変数buffer-undo-list
に収めたアンドゥリストの先頭に
自動的に要素を追加します。
buffer-undo-list | Variable |
この変数の値は、カレントバッファのアンドゥリストである。
値t はアンドゥ情報の記録を禁止する。
|
アンドゥリストの要素として可能なものをつぎに示します。
position
(beg . end)
(text . position)
(abs position)
である。
(t high . low)
primitive-undo
はこれらの値を用いて、
バッファを再度未変更と印を付けるかどうか判定する。
ファイルの更新時刻がこれに一致するときにのみ再度未変更とする。
(nil property value beg . end)
(put-text-property beg end property value)
(marker . adjustment)
nil
undo-boundary | Function |
この関数は、アンドゥリストに境界要素を置く。
アンドゥコマンドはそのような境界で停止し、
連続したアンドゥコマンドはよりまえの境界までアンドゥする。
この関数はnil を返す。
エディタコマンドループは、 各キー列を実行するまえにアンドゥの境界を自動的に作る。 したがって、各アンドゥは、1つのコマンドの効果を普通は取り消す。 自己挿入の入力文字は例外である。 コマンドループはそのような最初の文字に境界を作り、 つぎの19個の連続する自己挿入の入力文字では境界を作らず、 20番目で境界を作るということを自己挿入の入力文字が続く限り行う。 別のバッファでアンドゥ可能な変更を行うたびに バッファのすべての変更で境界を追加する。 これは、各コマンドが変更した箇所で各バッファに境界を作ることを 保証するためである。 1つのコマンドの効果を複数に分けるためにこの関数を直接呼ぶことは有用である。
たとえば、 |
primitive-undo count list | Function |
これは、アンドゥリストの要素をアンドゥする基本的な関数である。
listの先頭のcount個の要素をアンドゥし、listの残りを返す。
この関数をLispで書くこともできるが、Cで書いたほうが便利である。
|
本節では、指定されたバッファでアンドゥ情報の記録をオン/オフする 方法について述べます。 また、アンドゥリストが大きくなりすぎないように 自動的に切り詰める方法についても説明します。
新たに作成されたバッファのアンドゥ情報の記録は普通は始めオンですが、
バッファ名が空白で始まる場合は最初からオフです。
つぎの2つの関数を使うか、読者自身がbuffer-undo-list
に設定すれば、
アンドゥ記録を明示的にオン/オフできます。
buffer-enable-undo &optional buffer-or-name | コマンド |
このコマンドは、バッファbuffer-or-nameでのアンドゥ記録をオンにし、
以降の変更を取り消せるようにする。
引数を指定しないと、カレントバッファを使う。
当該バッファでアンドゥ記録がすでにオンであると、
この関数はなにもしない。
nil を返す。
対話的に呼ばれると、buffer-or-nameはカレントバッファである。 他のバッファを指定できない。 |
buffer-disable-undo &optional buffer | コマンド |
buffer-flush-undo &optional buffer | コマンド |
この関数はバッファbufferのアンドゥリストを破棄し、
以降のアンドゥ情報の記録をオフにする。
その結果、これ以前の変更も以降の変更も取り消すことはできない。
bufferのアンドゥリストがすでにオフであると、
この関数にはなんの効果もない。
この関数は 名前 |
編集を続けるにしたがってアンドゥリストはどんどん長くなります。
これらがメモリを使い尽くさないように、
読者が設定した上限サイズにガベッジコレクションが切り詰めます。
(この目的においてアンドゥリストの『サイズ』は、
リストを構成するコンスセルの個数と削除された文字列の和である。)
2つの変数undo-limit
とundo-strong-limit
は、
許容できるサイズの範囲を制御します。
undo-limit | Variable |
これはアンドゥリストの許容できるサイズの緩い制限である。 このサイズを越える位置にある変更グループは保持される最古のものである。 |
undo-strong-limit | Variable |
これはアンドゥリストの許容できるサイズの上限である。 このサイズを越える位置にある変更グループは (これより古いものも含めて)削除される。 例外が1つあり、最新の変更グループは それがどれほど大きくてもけっして破棄しない。 |
詰め込み(fill)とは、指定されている最大幅
(を越えず)にほぼ収まるように(行分け位置を移動して)
行の長さを調整することです。
さらに、行を幅揃え(justify)することもできます。
つまり、左右の両端や片側の余白をきちんと揃えるため
空白を挿入することです。
幅は変数fill-column
で制御します。
読みやすいように、行は70コラム程度に収めるべきです。
テキストを挿入するにつれて自動的にテキストを詰め込むには、 自動詰め込み(auto-fill)モード(see Auto Filling)を使いますが、 既存のテキストを変更しても正しくない詰め込み状態のまま放置されます。 したがって、そのようなテキストは明示的に詰め込む必要があります。
本節のほとんどの関数が返す値には意味はありません。
詰め込みを行うすべての関数は、現在の左端余白、現在の右端余白、
現在の幅揃えスタイルに注意をはらいます(see Margins)。
現在の幅揃えスタイルがnone
であると、
詰め込み関数は実際にはなにもしません。
詰め込み関数には引数justifyを取るものもあります。
それがnil
以外であると、幅揃えの種類を指示します。
特定の幅揃えスタイルを指示するものは、
left
、right
、full
、center
です。
それがt
であると、
テキストの当該部分には現在の幅揃えスタイルを用いることを意味します
(下記のcurrent-justification
を参照)。
これ以外の値はfull
として扱います。
対話的に詰め込み関数を呼ぶときに前置引数を使うと、
justifyとして値full
を暗に指示します。
fill-paragraph justify | コマンド |
このコマンドは、ポイントがある段落、あるいは、ポイントのあとの段落を詰め込む。
justifyがnil 以外であると、各行の幅揃えも行う。
段落の境界を探すために普通の段落移動コマンドを用いる。
see Paragraphs。
|
fill-region start end &optional justify nosqueeze to-eop | コマンド |
このコマンドは、startからendの領域内の各段落を詰め込む。
justifyがnil 以外であれば、幅揃えも行う。
nosqueezeが 変数 |
fill-individual-paragraphs start end &optional justify mail-flag | コマンド |
このコマンドは、領域内の各段落を各段落の詰め込み接頭辞に従って詰め込む。
したがって、段落の行が空白で字下げされていると、
詰め込んだあとの段落も同じように字下げされる。
最初の2つの引数startとendは、
詰め込むべき範囲の先頭と末尾である。
3番目と4番目の引数、justifyとmail-flagは省略できる。
justifyが 通常、 |
fill-individual-varying-indent | User Option |
この変数は、上に述べたように
fill-individual-paragraphs の動作を変える。
|
fill-region-as-paragraph start end &optional justify nosqueeze squeeze-after | コマンド |
このコマンドは、テキストの領域を1つの段落とみなして詰め込む。
領域に複数の段落があると、段落のあいだの空行は取りさる。
justifyがnil 以外であると幅揃えも行う。
対話的な呼び出しでは、前置引数で幅揃えを指示する。 nosqueezeが 適応型詰め込み(adaptive-fill)モードでは、
デフォルトの詰め込み接頭辞を選ぶために
このコマンドは |
justify-current-line how eop nosqueeze | コマンド |
このコマンドは、現在行の単語のあいだに空白を挿入し、
ちょうどfill-column コラムで行が終るようにする。
nil を返す。
引数howが eopが nosqueezeが |
default-justification | User Option |
この変数の値は、テキスト属性で幅揃えスタイルを指定していない
テキストに対して用いる幅揃えスタイルを指定する。
可能な値は、left 、right 、full 、center 、
none である。
デフォルト値はleft である。
|
current-justification | Function |
この関数は、ポイントの周りのテキストを詰め込むときに使う 正しい幅揃えスタイルを返す。 |
sentence-end-double-space | User Option |
この変数がnil 以外であると、
直後に1つの空白を従えたピリオドを文末とみなさず、
詰め込み関数はそのような箇所で行分けしない。
|
fill-paragraph-function | Variable |
この変数は、段落の詰め込みに優先する方法をメジャーモードに与える。
値がnil 以外であると、
fill-paragraph は詰め込み処理のためにこの関数を呼び出す。
関数がnil 以外の値を返すと、
fill-paragraph は処理が完了したとみなして戻り値をただちに返す。
この機能の普通の用途は、 プログラム言語向けのモードでコメントを詰め込むためである。 この関数で普通の方法で詰め込む必要がある場合には、つぎのようにする。 (let ((fill-paragraph-function nil)) (fill-paragraph arg)) |
use-hard-newlines | Variable |
この変数がnil 以外であると、
詰め込み関数は、テキスト属性hard を持つ改行を削除しない。
これらの『ハード改行』は段落の区切りとして働く。
|
fill-prefix | User Option |
このバッファローカルな変数は、普通のテキスト行の先頭に現れ、
詰め込み時には無視すべきテキストの文字列(詰め込み接頭辞)を指定する。
詰め込み接頭辞で始まらない行は段落の開始行とみなすため、
詰め込み接頭辞のあとに余分に白文字があるとそれらも段落の開始行とみなす。
詰め込み接頭辞で始まりそのあとに余分な白文字がない行は、
いっしょに詰め込める普通のテキスト行である。
左端余白がある場合には、左端余白のあとに詰め込み接頭辞が続く。 |
fill-column | User Option |
このバッファローカルな変数は、詰め込んだ行の最大幅を指定する。
この値は整数であり、コラム数であること。
自動詰め込み(auto-fill)モード(see Auto Filling)を含めて
すべての詰め込み/幅揃え/中央揃えを行うコマンドは、
この変数に影響される。
特に他人のために書いているテキストでは、
|
default-fill-column | Variable |
この変数の値は、バッファでfill-column の値を設定していない場合の
fill-column のデフォルト値である。
これは(default-value 'fill-column) と同じである。
|
set-left-margin from to margin | コマンド |
fromからtoまでのテキストの
属性left-margin を値marginにする。
自動詰め込み(auto-fill)モードがオンであると、
このコマンドは、当該領域を再詰め込みして新たな余白に適合するようにする。
|
set-right-margin from to margin | コマンド |
fromからtoまでのテキストの
属性right-margin を値marginにする。
自動詰め込み(auto-fill)モードがオンであると、
このコマンドは、当該領域を再詰め込みして新たな余白に適合するようにする。
|
current-left-margin | Function |
この関数は、ポイントの周りのテキストを詰め込むときに使う
正しい左端余白の値を返す。
その値は、現在行の最初の文字の属性left-margin の値(なければ0)
と変数left-margin の値の和である。
|
current-fill-column | Function |
この関数は、ポイントの周りのテキストを詰め込むときに使う
正しい詰め込み幅を返す。
その値は、変数fill-column の値から
ポイント直後の文字の属性right-margin の値を引いたものである。
|
move-to-left-margin &optional n force | コマンド |
この関数は、ポイントを現在行の左端余白へ移動する。
移動先のコラム位置は関数current-left-margin を呼び出して決定する。
引数nがnil 以外であると、
move-to-left-margin はn-1先の行へまず移動する。
forceが |
delete-to-left-margin from to | Function |
この関数は、fromからtoまでのテキストから
左端余白分の字下げを取りさる。
削除する字下げ量は、current-left-margin を呼び出して決定する。
この関数が白文字以外を削除することは絶対にない。
|
indent-to-left-margin | Function |
これは、基本(fundamental)モード、テキスト(text)モードなどが使う
デフォルトのindent-line-function である。
その効果は、変数left-margin の値で指定した位置から
現在行が始まるように字下げを調整することである。
それには白文字の挿入や削除が伴う。
|
left-margin | Variable |
この変数は、左端余白コラムの起点を指定する。 基本(fundamental)モードでは、C-jがこのコラム位置に字下げする。 この変数に設定すると自動的にバッファローカルになる。 |
fill-nobreak-predicate | Variable |
この変数は、特定の箇所では行分けしない方法をメジャーモードに提供する。
その値は関数であること。
この関数は、引数なしで行分け予定箇所にポイントを置いて呼び出される。
この関数がnil 以外を返すと、当該箇所では行分けしない。
|
適応型詰め込みモード(adaptive-fill)では、 詰め込むべき各段落のテキストから自動的に詰め込み接頭辞を選びます。
adaptive-fill-mode | User Option |
この変数がnil 以外であると、
適応型詰め込みモード(adaptive-fill)がオンである。
デフォルトではt である。
|
fill-context-prefix from to | Function |
この関数は適応型詰め込みモード(adaptive-fill)の中核を実装するものであり、 fromからtoのあいだのテキストに基づいて詰め込み接頭辞を選ぶ。 以下に述べる変数に基づいて、段落の最初の2行を調べてこれを行う。 |
adaptive-fill-regexp | User Option |
この変数は、適応型詰め込みモード(adaptive-fill)を制御する 正規表現を保持する。 適応型詰め込みモード(adaptive-fill)では、 行の(あれば)左端余白の白文字のうしろから始まるテキストに対して この正規表現の一致を試みる。 一致した文字群が当該行の詰め込み接頭辞の候補になる。 |
adaptive-fill-first-line-regexp | User Option |
1行だけの段落において、詰め込み接頭辞の候補がこの正規表現に一致するか、
comment-start-skip に一致すると、その候補を使う。
さもなければ、同じ幅に相当する白文字をかわりに使う。
1行だけの段落から選んだ詰め込み接頭辞が後続の行の段落の始まりである場合には、 1行だけの段落からはけっして詰め込み接頭辞を選ばない。 |
adaptive-fill-function | User Option |
この変数に関数を指定することで、
詰め込み接頭辞のより複雑な自動選択方法を指定できる。
この関数は、adaptive-fill-regexp の一致に失敗したときに、
行の左端余白のうしろにポイントを置いて呼び出され、
当該行に基づいて適切な詰め込み接頭辞を返すこと。
それがnil を返すと、当該行には詰め込み接頭辞がないことを意味する。
|
自動詰め込み(auto-filling)モードは、テキストを挿入するにつれて 自動的に行を詰め込むマイナモードです。 本節では、自動詰め込み(auto-filling)モードが使うフックについて述べます。 既存のテキストを詰め込んだり幅揃えするために 明示的に呼び出す関数については、Fillingを参照してください。
自動詰め込み(auto-filling)モードでは、 テキストの一部を再詰め込む際の 余白や幅揃えスタイルを変更するための関数も使えるようにします。 See Margins。
auto-fill-function | Variable |
この変数の値は、
自己挿入される空白や改行のあとで呼び出されるべき
(引数なしの)関数であること。
これがnil であると、そのような場合に特別なことを行わない。
自動詰め込み(auto-filling)モードがオンであると、
Emacsの古い版では、この変数を |
normal-auto-fill-function | Variable |
この変数は、自動詰め込み(auto-filling)モードがオンになったとき/であるときに
auto-fill-function として用いる関数を指定する。
メジャーモードでは、この変数のバッファローカルな値に設定することで
自動詰め込み(auto-filling)モードのふるまいを変更できる。
|
本節で述べるソート関数すべては、バッファ内のテキストを並べ替えます。
これは、リスト内の要素の順番を並べ替える関数sort
(see Rearrangement)と対照的です。
これらの関数が返す値には意味はありません。
sort-subr reverse nextrecfun endrecfun &optional startkeyfun endkeyfun | Function |
この関数は、バッファ内のテキストをレコードに分割してソートする
汎用のテキストソートルーティンである。
本節のコマンドのほとんどは、この関数を用いる。
通常、レコードをソートキーの昇順に並べ替える。
関数
;; 説明文字列の始めの2行は、ユーザーが見るときには ;; 実質的には1行であることに注意 (defun sort-lines (reverse beg end) "Sort lines in region alphabetically;\ argument means descending order. Called from a program, there are three arguments: REVERSE (non-nil means reverse order),\ BEG and END (region to sort). The variable `sort-fold-case' determines\ whether alphabetic case affects the sort order. (interactive "P\nr") (save-excursion (save-restriction (narrow-to-region beg end) (goto-char (point-min)) (sort-subr reverse 'forward-line 'end-of-line)))) ここで、 関数 (sort-subr reverse (function (lambda () (while (and (not (eobp)) (looking-at paragraph-separate)) (forward-line 1)))) 'forward-paragraph)
|
sort-fold-case | User Option |
この変数がnil 以外であると、
sort-subr や他のバッファソート関数は、
文字列の比較において大文字小文字を区別しない。
|
sort-regexp-fields reverse record-regexp key-regexp start end | コマンド |
このコマンドは、startとendのあいだの領域を
record-regexpとkey-regexpの指定に従って
アルファベット順にソートする。
reverseが負の整数であると、逆順にソートする。
アルファベット順のソートとは、 最初の文字同士、2番目の文字同士といった具合に 2つのソートキーを比較することである。 不一致がみつかると、ソートキーが等しくないことを意味し、 最初の不一致箇所の文字が小さいほうのソートキーが小さい。 個々の文字は、Emacsの文字集合における文字コードの数値に従って比較する。 引数record-regexpの値は、バッファをソートレコードに
分割する方法を指定する。
各レコードの末尾において、この正規表現を探索し
それに一致したテキストをつぎのレコードとする。
たとえば、正規表現 引数key-regexpの値は、 レコードのどの部分がソートキーであるかを指定する。 key-regexpは、レコード全体かその一部分に一致する。 後者の場合、レコードの残りの部分は、レコードの並び替え順序には影響しないが、 レコードをその新たな位置に移動するときにいっしょに移動される。 引数key-regexpで record-regexpの部分式に一致したテキストを参照してもよいし、 独立した正規表現でもよい。 key-regexpにはつぎの可能性がある。
たとえば、領域内のすべての行を各行の (sort-regexp-fields nil "^.*$" "\\<f\\w*\\>" (region-beginning) (region-end))
|
sort-lines reverse start end | コマンド |
このコマンドは、startとendのあいだの領域の行を
アルファベット順にソートする。
reverseがnil 以外であると、逆順にソートする。
|
sort-paragraphs reverse start end | コマンド |
このコマンドは、startとendのあいだの領域の段落を
アルファベット順にソートする。
reverseがnil 以外であると、逆順にソートする。
|
sort-pages reverse start end | コマンド |
このコマンドは、startとendのあいだの領域のページを
アルファベット順にソートする。
reverseがnil 以外であると、逆順にソートする。
|
sort-fields field start end | コマンド |
このコマンドは、startとendのあいだの領域の行を 各行のfield番目のフィールド同士をアルファベット順に比較してソートする。 フィールドは白文字で区切られ、1から数える。 fieldが負であると、 行末から-field番目のフィールドでソートする。 このコマンドは、表をソートするのに有用である。 |
sort-numeric-fields field start end | コマンド |
このコマンドは、startとendのあいだの領域の行を 各行のfield番目のフィールド同士を数値として比較してソートする。 領域内の各行の指定したフィールドには数があること。 フィールドは白文字で区切られ、1から数える。 fieldが負であると、 行末から-field番目のフィールドでソートする。 このコマンドは、表をソートするのに有用である。 |
sort-columns reverse &optional beg end | コマンド |
このコマンドは、startとendのあいだの領域の行を
特定範囲のコラムをアルファベット順に比較してソートする。
begとendのコラム位置は、ソート対象のコラムの範囲を区切る。
reverseが このコマンドの普通でない点は、 位置begを含む行全体と位置endを含む行全体も ソート対象の領域に含まれることである。
|
コラム関数は、(バッファの先頭から文字を数えた)文字位置を (スクリーンの行頭から文字を数えた)コラム位置に変換します。
これらの関数は、各文字をそれがスクリーン上で占めるコラム数を基に数える。
つまり、ctl-arrow
の値に依存してコントロール文字は、
2コラムか4コラム占めると数え、
タブ文字は、タブの開始コラムとtab-width
の値に依存する
コラム数を占めると数えることを意味します。
See Usual Display。
コラム番号の計算では、ウィンドウの幅や水平スクロール量を無視します。 その結果、コラム値は任意の大きさになりえます。 最初の(スクリーン左端の)コラムの番号は0です。
current-column | Function |
この関数は、左端を0としてコラム数で数えたポイントの水平位置を返す。
コラム位置は、現在行の先頭からポイント位置までの文字すべての
表示上の表記の幅の総和である。
|
move-to-column column &optional force | Function |
この関数は、ポイントを現在行のcolumnへ移動する。
columnの計算では、現在行の先頭からポイント位置までの
文字すべての表示上の表記の幅を考慮する。
コラムcolumnが行末を越える場合、ポイントを行末へ移動する。 columnが負であると、ポイントを行頭へ移動する。 コラムcolumnがタブなどの複数コラムを占める文字の中ほどにあるために
そこへ移動できない場合には、
ポイントを当該文字の末尾へ移動する。
しかし、forceが コラムcolumnに到達できるほど行が長くない場合にも 引数forceには効果がある。 そのような場合、指定コラムに達するように行末に白文字を追加する。 columnが整数でないと、エラーを通知する。 戻り値は、実際の移動先のコラム番号である。 |
字下げ関数は、行頭の空白を調べたり、そこへ移動したり、 変更するために使います。 行の他の白文字を変更するものもあります。 コラム関数と字下げ関数は左端を0と数えます。
本節では、字下げを数えたり挿入するために使われる基本関数について述べます。 後続の節の関数群は、これらの基本関数を使っています。 関連する関数については、See Width。
current-indentation | Function |
この関数は、現在行の字下げを返す。 これは最初の白文字以外の文字の水平位置である。 行全体が白文字や空である場合には、行末の水平位置を返す。 |
indent-to column &optional minimum | コマンド |
この関数は、ポイント位置からcolumnに達するまでタブや空白で字下げする。
minimumを指定しnil 以外であると、
columnを越える場合であっても最低minimum個の空白を挿入する。
さもなければ、ポイントがcolumnを越えている場合には、
この関数はなにもしない。
戻り値は、挿入した字下げが終る箇所のコラムである。
挿入された白文字は周りの文字(普通は、まえの文字)からテキスト属性を継承する。 see Sticky Properties。 |
indent-tabs-mode | User Option |
この変数がnil 以外であると、
字下げ関数は空白に加えてタブも挿入する。
さもなければ、空白のみを挿入する。
この変数に設定すると、カレントバッファでバッファローカルになる。
|
各メジャーモードの重要な機能は、 キー<TAB>を編集対象の言語に適した字下げにカスタマイズすることです。 本節では、キー<TAB>の機構とそれを制御する方法について述べます。 本節の関数は、予測できない値を返します。
indent-line-function | Variable |
この変数の値は、現在行を字下げするために
<TAB>(やさまざまなコマンド)が使う関数である。
コマンドindent-according-to-mode は、
この関数を呼ぶこと以上のことはしない。
lispモードでは値はシンボル |
indent-according-to-mode | コマンド |
このコマンドは、現在のメジャーモードに適した方法で現在行を字下げするために
indent-line-function で指定される関数を呼び出す。
|
indent-for-tab-command | コマンド |
このコマンドは、現在行を字下げするために
indent-line-function で指定される関数を呼び出すが、
その関数がindent-to-left-margin であると、
かわりにinsert-tab を呼び出す。
(これはタブ文字を挿入する単純なコマンドである。)
|
newline-and-indent | コマンド |
この関数は、改行を挿入してから、
(改行を挿入したばかりの行に続く)新たな行を
メジャーモードに基づいて字下げする。
現在の |
reindent-then-newline-and-indent | コマンド |
このコマンドは、現在行を字下げし直し、ポイント位置に改行を挿入し、
(改行を挿入したばかりの行に続く)新たな行を字下げする。
このコマンドは、 |
本節では、領域内のすべての行を字下げするコマンドについて述べます。 これらは予測できない値を返します。
indent-region start end to-column | コマンド |
このコマンドは、start(を含めて)と
end(を含めない)のあいだで始まる空でない各行を字下げする。
to-columnがnil であると、
indent-region は、現在のモードの字下げ関数、
つまり、indent-line-function の値を呼び出して、
空でない各行を字下げする。
to-columnが 詰め込み接頭辞がある場合、
|
indent-region-function | Variable |
この変数の値は、indent-region の短縮版として利用可能な関数である。
領域の開始位置と終了位置の2つの引数をとる。
領域の行を1つ1つ字下げする場合と同じ結果を生じるが、
より速く動作することを意図してこの関数を設計するべきである。
値が 短縮版関数はCモードやlispモードのようなモードで有用である。
そのようなモードでは、 引数to-columnに |
indent-rigidly start end count | コマンド |
このコマンドは、start(を含めて)と
end(を含めない)のあいだで始まる行すべてを
コラム数countだけ字下げする。
これは、領域を1つの塊として動かしてその領域の『形を保つ』。
このコマンドは、字下げしていないテキストの領域だけでなく、
整形済みの領域を字下げするためにも有用である。
たとえば、countが3であると、 このコマンドは指定した領域内の各行の行頭に3コラムの字下げを追加する。 メイル(mail)モードでは、C-c C-y( |
indent-code-rigidly start end columns &optional nochange-regexp | Function |
この関数はindent-rigidly と同様であるが、
文字列やコメントで始まる行を変更しない点が異なる。
さらに、(nochange-regexpが |
本節では、先行する行の内容に基づいて現在行を字下げする2つの コマンドについて述べます。
indent-relative &optional unindented-ok | コマンド |
このコマンドは、空白でないまえの行のつぎの字下げ位置のコラムに
達するまで、ポイント位置に白文字を挿入する。
字下げ位置とは、白文字に続く白文字以外の文字である。
つぎの字下げ位置とは、現在行のポイントのコラム位置より大きな
最初の字下げ位置のことである。
たとえば、テキスト行の白文字以外の最初の文字より左側で、
その下の行にポイントがあると、
白文字を挿入してそのコラム位置にポイントを移動する。
空白でないまえの行に、つぎの字下げ位置(つまり、ポイント位置より
大きなコラム)がないと、
つぎの例では、ポイントは2行目の行頭にある。 This line is indented twelve spaces. -!-The quick brown fox jumped. 式 This line is indented twelve spaces. -!-The quick brown fox jumped. つぎの例では、ポイントは This line is indented twelve spaces. The quick brown fox jum-!-ped. 式 This line is indented twelve spaces. The quick brown fox jum -!-ped. |
indent-relative-maybe | コマンド |
このコマンドは、引数unindented-okにt を指定して
indent-relative を呼び出すことで、
まえの行と同様に字下げする。
戻り値は予測できない。
空行でないまえの行に現在のコラム位置を越える字下げ位置がなければ、 このコマンドはなにもしない。 |
本節では、ユーザー指定の『タブストップ』の機構と、 それを使ったり設定するための機構について説明します。 『タブストップ』という名前を使うのは、 この機構がタイプライタのタブストップに似た機能だからです。 この機能は、適切な個数の空白とタブ文字を挿入して つぎのタブストップのコラムへ到達しますが、 バッファ内のタブ文字の表示に影響することはありません (see Usual Display)。 テキスト(text)モードなどの少数のメジャーモードでのみ、 入力としての文字<TAB>がこのタブストップ機能を使います。
tab-to-tab-stop | コマンド |
このコマンドは、tab-stop-list で定義されたつぎのタブストップコラムまで、
ポイントのまえに空白やタブを挿入する。
このリストで現在のコラム番号より大きな要素を探し、
その要素を字下げ位置のコラムとして使う。
そのような要素がなければ、このコマンドはないもしない。
|
tab-stop-list | User Option |
この変数は、tab-to-tab-stops が使うタブストップコラムのリストである。
それらの要素は、昇順の整数であること。
タブストップコラムの間隔は、等間隔である必要はない。
タブストップを対話的に編集するにはM-x edit-tab-stopsを使う。 |
これらのコマンドは、主に対話的に使うもので、 テキストの字下げに基づいて動作します。
back-to-indentation | コマンド |
このコマンドは、現在行(ポイントが位置する行)の
白文字でない最初の文字へポイントを移動する。
nil を返す。
|
backward-to-indentation arg | コマンド |
このコマンドは、arg行だけポイントを後方へ移動してから、
当該行の白文字でない最初の文字へポイントを移動する。
nil を返す。
|
forward-to-indentation arg | コマンド |
このコマンドは、arg行だけポイントを前方へ移動してから、
当該行の白文字でない最初の文字へポイントを移動する。
nil を返す。
|
ここに述べる大文字小文字の変更コマンドは、 カレントバッファのテキストに作用します。 文字列や文字の大文字小文字を変換する関数については、 See Case Conversion。 どの文字が大文字でどの文字が小文字であり、それらをどのように変換するかを カスタマイズする方法については、See Case Tables。
capitalize-region start end | コマンド |
この関数は、startとendで定義される領域内の
すべての単語をキャピタライズ(大文字で始まるように)する。
つまり、各単語の最初の文字を大文字に、残りの文字を小文字に変換する。
この関数はnil を返す。
領域の端が単語の途中にあると、 その単語の領域内の部分を1つの単語とみなす。
---------- Buffer: foo ---------- This is the contents of the 5th foo. ---------- Buffer: foo ---------- (capitalize-region 1 44) => nil ---------- Buffer: foo ---------- This Is The Contents Of The 5th Foo. ---------- Buffer: foo ---------- |
downcase-region start end | コマンド |
この関数は、startとendで定義される領域内の
すべての文字を小文字に変換する。
この関数はnil を返す。
|
upcase-region start end | コマンド |
この関数は、startとendで定義される領域内の
すべての文字を大文字に変換する。
この関数はnil を返す。
|
capitalize-word count | コマンド |
この関数は、ポイントのうしろのcount個の単語を
キャピタライズ(大文字で始まるように)し、ポイントをそれらの末尾に移動する。
つまり、各単語の最初の文字を大文字に、残りの文字を小文字に変換する。
countが負であると、まえの-count個の単語を
大文字で始まるようにするが、ポイントは移動しない。
値はnil である。
ポイントが単語の途中にあると、単語を前方へ移動するときには ポイントよりまえにある単語の部分を無視する。 単語の残りの部分を1つの単語として扱う。
|
downcase-word count | コマンド |
この関数は、ポイントのうしろのcount個の単語を
すべて小文字に替え、ポイントをそれらの末尾に移動する。
countが負であると、まえの-count個の単語を
変換するが、ポイントは移動しない。
値はnil である。
|
upcase-word count | コマンド |
この関数は、ポイントのうしろのcount個の単語を
すべて大文字に替え、ポイントをそれらの末尾に移動する。
countが負であると、まえの-count個の単語を
変換するが、ポイントは移動しない。
値はnil である。
|
シンボルの属性リスト(see Property Lists)のように、
バッファや文字列の各文字にはテキスト属性リスト
(text property list)を持てます。
この属性は、(本節の原文のタイトルの)文字T
や
foo
の最初のo
のような特定の箇所の特定の文字に属します。
同じ文字が異なる箇所に現れるとき、
一般にはそれぞれに異なる属性を持てます。
各属性には、名前と値があります。 どちらも任意のLispオブジェクトでかまいませんが、 名前は普通はシンボルです。 属性リストを参照する普通の方法では、 名前を指定してそれに対応する値を問い合わせます。
文字に属性category
があるとき、
それを文字のカテゴリ(category)といいます。
それはシンボルであるべきです。
そのシンボルの属性が、文字の属性のデフォルトとして働きます。
文字列とバッファのあいだでテキストをコピーすると、
文字とともにその属性も保たれます。
substring
、insert
、buffer-substring
などの
さまざまな関数がそうします。
テキスト属性を調べるもっとも簡単な方法は、
特定の文字の特定の属性の値を問い合わせることです。
それには、get-text-property
を使います。
文字の属性リスト全体を取得するにはtext-properties-at
を使います。
複数の文字の属性を一度に調べるための関数については、
See Property Search。
これらの関数は、文字列とバッファの両方を扱えます。 文字列内の位置は0から始まり、 バッファ内の位置は1から始まることに注意してください。
get-text-property pos prop &optional object | Function |
この関数は、object(バッファか文字列)内の位置posの
うしろの1文字の属性propの値を返す。
引数objectは省略でき、
デフォルトはカレントバッファである。
その文字に属性propがなくてもシンボルであるカテゴリがあれば、
|
get-char-property pos prop &optional object | Function |
この関数はget-text-property に似ているが、
まずオーバレイを調べてからテキスト属性を調べる。
see Overlays。
引数objectは、文字列、バッファ、ウィンドウのいずれかである。 ウィンドウであると、そのウィンドウに表示しているバッファの テキスト属性とオーバレイを対象にするが、 対象となるオーバレイはそのウィンドウに対して活性なものだけである。 objectがバッファであると、テキスト属性に加えて そのバッファのすべてのオーバレイを対象にする。 objectが文字列であると、 文字列にはオーバレイはないので、テキスト属性のみを対象にする。 |
text-properties-at position &optional object | Function |
この関数は、文字列やバッファであるobject内の
位置positionにある1文字の属性リスト全体を返す。
objectがnil であると、デフォルトはカレントバッファである。
|
default-text-properties | Variable |
この変数は、テキスト属性のデフォルト値を与える属性リストを保持する。
直接的にもカテゴリシンボルを介して間接的にも
文字に属性の値が指定されていないと、
このリストに収めた値をかわりに使う。
つぎに例を示す。
(setq default-text-properties '(foo 69)) ;; 位置1の文字に属性がないことを保証する (set-text-properties 1 2 nil) ;; 問い合わせたときに見えるのはデフォルト値である (get-text-property 1 'foo) => 69 |
属性を変更する基本関数は、バッファや文字列の指定した範囲に作用します。
関数set-text-properties
(本節の最後)は、
その範囲のテキストの属性リスト全体を設定します。
これは、名前で指定した特定の属性のみを追加/変更/削除するのに
しばしば有用です。
テキスト属性はバッファ(や文字列)の一部分であるとみなされ、 スクリーン上でのバッファの見た目に影響するので、 バッファのテキスト属性を変更すると、 バッファには変更済みの印を付けます。 バッファのテキスト属性の変更もアンドゥ(see Undo)できます。
put-text-property start end prop value &optional object | Function |
この関数は、文字列やバッファであるobject内の
startとendのあいだのテキストの属性propの値を
valueとする。
objectがnil であると、デフォルトはカレントバッファである。
|
add-text-properties start end props &optional object | Function |
この関数は、文字列やバッファであるobject内の
startとendのあいだのテキストの
テキスト属性に追加/上書きする。
objectがnil であると、デフォルトはカレントバッファである。
引数propsで追加する属性を指定する。 これは属性リスト(see Property Lists)の形であること。 つまり、属性名とその値を交互に並べたリストであること。 この関数が属性の値をどれか実際に変更したならば、戻り値は たとえば、テキストのある範囲の属性 (add-text-properties start end '(comment t face highlight)) |
remove-text-properties start end props &optional object | Function |
この関数は、文字列やバッファであるobject内の
startとendのあいだのテキストから
指定したテキスト属性を削除する。
objectがnil であると、デフォルトはカレントバッファである。
引数propsで削除する属性を指定する。
これは属性リスト(see Property Lists)の形であること。
つまり、属性名とその値を交互に並べたリストであること。
ただし、意味があるのは名前のみであり、その値は無視する。
たとえば、属性 (remove-text-properties start end '(face nil)) この関数が属性の値をどれか実際に変更したならば、戻り値は 特定のテキストからすべてのテキスト属性を削除するには、
新たな属性リストとして |
set-text-properties start end props &optional object | Function |
この関数は、文字列やバッファであるobject内の
startとendのあいだのテキストのテキスト属性を完全に置き換える。
objectがnil であると、
デフォルトはカレントバッファである。
引数propsは新たな属性リストである。 これは、属性名とその値を交互に並べたリストであること。
propsが (set-text-properties start end nil) |
バッファからテキストをコピーするがその属性はコピーしない
関数buffer-substring-no-properties
(see Buffer Contents)も
参照してください。
テキスト属性の典型的な用途では、 ほとんどの場合多くの連続した文字の1つの属性には同じ値があります。 1つずつ文字を調べるようにプログラムするよりは、 同じ属性値を持つテキストの塊を処理するほうがとても速いです。
このために使える関数をここで説明します。
これらは属性値の比較にeq
を使います。
objectのデフォルトは、すべての場合でカレントバッファです。
高い効率のためには、これらの関数に引数limitを使うことが重要であり、 1つの属性を探す関数には特にあてはまります。 さもないと、読者が望む属性が変更されないような場合、 それらの関数はバッファの末尾まで走査して長い時間を費すことになります。
これらの関数はポイントを移動しませんが、そのかわりに
位置(あるいはnil
)を返します。
位置はつねに2つの文字のあいだにあることに注意してください。
これらの関数が返す位置は、異なる属性を持つ2つの文字のあいだです。
next-property-change pos &optional object limit | Function |
この関数は、文字列やバッファであるobject内の位置posから
テキスト属性のいずれかが異なるまでテキストを走査し、その変化する位置を返す。
いいかえれば、posの直後の文字のテキスト属性とは異なる
属性を持つposのあとにある最初の文字の位置を返す。
limitが limitが バッファからすべての属性が同じであるテキストの塊を 走査する方法の例をつぎに示す。 (while (not (eobp)) (let ((plist (text-properties-at (point))) (next-change (or (next-property-change (point) (current-buffer)) (point-max)))) ポイントからnext-changeまでのテキストを処理する... (goto-char next-change))) |
next-single-property-change pos prop &optional object limit | Function |
この関数は、文字列やバッファであるobject内の位置posから
属性propが異なるまでテキストを走査し、その変化する位置を返す。
いいかえれば、posの直後の文字の属性propとは異なる
属性propをもつposのあとにある最初の文字の位置を返す。
limitが limitが |
previous-property-change pos &optional object limit | Function |
これはnext-property-change と同様であるが、
前方へではなくposから後方へ走査する。
値がnil 以外であると、それはposより小さいか等しい位置である。
値がposに等しいのは、limitがposに等しい場合のみである。
|
previous-single-property-change pos prop &optional object limit | Function |
これはnext-single-property-change と同様であるが、
前方へではなくposから後方へ走査する。
値がnil 以外であると、それはposより小さいか等しい位置である。
値がposに等しいのは、limitがposに等しい場合のみである。
|
next-char-property-change position &optional limit | Function |
これはnext-property-change と同様であるが、
テキスト属性に加えてオーバレイも対象にする。
この関数はカレントバッファにのみ作用するため、
objectを表す引数はない。
どちらかの属性が異なるつぎの位置を返す。
|
previous-char-property-change position &optional limit | Function |
これはnext-char-property-change と同様であるが、
前方へではなくposから後方へ走査する。
|
text-property-any start end prop value &optional object | Function |
startとendのあいだに属性propの値がvalueである
文字が1つでもあれば、この関数はnil 以外を返す。
より正確には、そのような最初の文字の位置を返す。
さもなければnil を返す。
省略可能な5番目の引数objectは、走査すべき文字列やバッファを指定する。 位置はobjectに相対である。 objectのデフォルトはカレントバッファである。 |
text-property-not-all start end prop value &optional object | Function |
startとendのあいだに属性propの値がvalueでない
文字が1つでもあれば、この関数はnil 以外を返す。
より正確には、そのような最初の文字の位置を返す。
さもなければnil を返す。
省略可能な5番目の引数objectは、走査すべき文字列やバッファを指定する。 位置はobjectに相対である。 objectのデフォルトはカレントバッファである。 |
特別な組み込みの意味を持つテキスト属性名の一覧を以下に示します。 以降の節では、詰め込みや属性の継承を制御する特別な属性名も示します。 それ以外の名前には標準的な意味はないので、 読者はそれらを好きなように使ってかまいません。
category
category
があるとき、
これを文字のカテゴリ(category)と呼ぶ。
これはシンボルであること。
そのシンボルの属性が、文字の属性のデフォルトとして働く。
face
face
を使う。
その値はフェイス名かフェイス名のリストである。
詳しくは、see Faces。
属性値がリストであると、その要素は、
(foreground-color . color-name)
や
(background-color . color-name)
の形でもよい。
これらの要素は、前景色だけや背景色だけを指定する。
したがって、使用する各色を表すフェイスを作成する必要はない。
テキストの内容に基づいて属性face
を自動的に更新する方法に関しては、
see Font Lock Mode。
mouse-face
face
のかわりに
属性mouse-face
が使われる。
この目的において『近く』とは、
文字とマウスの位置のあいだの
属性mouse-face
の値が同じであるすべてのテキストである。
local-map
local-map
を用いることで、
バッファ内のテキストの一部分に対して別のキーマップを指定できる。
ポイントのうしろの文字のこの属性の値がnil
以外であると、
バッファのローカルマップのかわりにその値をキー探索に使う。
属性値がシンボルであると、シンボルの関数定義をキーマップとして使う。
see Active Keymaps。
syntax-table
syntax-table
は、構文テーブルがこの文字に指定するものに優先する。
see Syntax Properties。
read-only
read-only
があると、その文字を変更できない。
変更するどのようなコマンドもエラーになる。
挿入されるテキストがスティッキ性のために属性read-only
を
継承する場合には、読み出し専用文字のつぎにテキストを挿入するとエラーになる。
したがって、スティッキ性を制御することで、
読み出し専用テキストのつぎへのテキスト挿入を許すかどうかを制御できる。
see Sticky Properties。
属性を変更するとバッファを変更したとみなすため、
特別なトリックを知らない限り、属性をread-only
を削除できない。
つまり、inhibit-read-only
にnil
以外の値を束縛して、
属性を削除する。
see Read Only Buffers。
invisible
invisible
がnil
以外であると、
その文字はスクリーンに表示されない。
詳しくは、see Invisible Text。
intangible
intangible
のnil
でない同じ値があると、
それらのあいだにポイントを置けなくなる。
前方に向けてこれらの文字の中にポイントを移動しようとすると、
ポイントは実際にはそれらの末尾へ移動する。
後方に向けてこれらの文字の中にポイントを移動しようとすると、
ポイントは実際にはそれらの先頭へ移動する。
変数inhibit-point-motion-hooks
がnil
以外であると、
属性intangible
は無視される。
modification-hooks
modification-hooks
がある場合、それは関数のリストであること。
その文字の変更にはそれらの関数すべてが呼び出される。
各関数は2つの引数、つまり、バッファの変更対象部分の先頭と末尾を受け取る。
1つの操作で変更される一連の文字に同じ変更フック関数が現れる場合、
関数が実際に何回呼ばれるか予測できないことに注意してほしい。
insert-in-front-hooks
insert-behind-hooks
insert-in-front-hooks
と
まえの文字の属性insert-behind-hooks
に指定されている
関数群を呼び出す。
これらの関数は2つの引数、つまり、挿入されたテキストの先頭と末尾を受け取る。
これらの関数が呼ばれるのは、実際の挿入操作を終えてからである。
バッファ内のテキストを変更するときに呼び出される他のフックについては、
Change Hooksも参照。
point-entered
point-left
point-entered
とpoint-left
は、
ポイント移動を報告するフック関数を保持する。
ポイントが動くたびに、Emacsはこれらの2つの属性値、つまり、
point-left
と
point-entered
を比較する。
これら2つの値が異なれば、
ポイントの古い値と新しい値の2つの引数で(nil
でなければ)
それぞれを呼び出す。
同じことを移動前後のポイントのまえの文字についても行う。
その結果、(同じかもしれない)point-left
の関数を2回、かつ/あるいは、
(同じかもしれない)point-entered
の関数を2回実行する。
いずれにしても、point-left
の関数が最初に呼ばれ、
そのあとでpoint-entered
の関数が呼ばれる。
これらの関数では、char-after
を使って
ポイントを移動せずにさまざまな箇所の文字を調べられる。
ポイントの値が実際に変わったときにのみ、これらのフック関数が実行される。
inhibit-point-motion-hooks | Variable |
この変数がnil 以外であると、
point-left とpoint-entered のフック関数は実行されなくなり、
属性intangible の効果もなくなる。
この変数はグローバルに設定せずに、let で束縛すること。
|
これらのテキスト属性は、詰め込みコマンドのふるまいに影響します。 これらは整形済みのテキストを表現するために使われます。 FillingとSee Margins。
hard
use-hard-newlines
が
nil
以外の場合にのみ効果を持つ。
right-margin
left-margin
justification
自己挿入文字は、通常、先行する文字と同じ属性を持ちます。 これを属性の継承(inheritance)と呼びます。
Lispプログラムでは、挿入基本関数を選べば、
継承して挿入したり継承せずに挿入できます。
insert
などの普通のテキスト挿入関数は、
いかなる属性も継承しません。
これらは、挿入する文字列の属性をそのまま持ったテキストを挿入し、
それ以外の属性はありません。
キルリングなどのある文脈から別の文脈へテキストをコピーするプログラムには、
これは正しい動作です。
継承して挿入するには、本節で述べる特別な基本関数を使います。
自己挿入文字はこれらの基本関数を使っているので、属性を継承します。
継承して挿入するとき、どの属性を継承するかは、
2つの特別な属性front-sticky
とrear-nonsticky
に依存します。
文字のうしろに挿入すると、その文字の後続スティッキ(rear-sticky) である属性を継承します。 文字のまえに挿入すると、その文字の先行スティッキ(front-sticky) である属性を継承します。 デフォルトでは、テキスト属性は先行スティッキではなく後続スティッキです。 したがって、デフォルトでは、まえの文字のすべての属性を継承して、 うしろの文字からはなにも継承しません。 特定の属性のスティッキ性を指定することで、異なるふるまいを指定できます。
文字の属性front-sticky
がt
であると、
その文字のすべての属性は先行スティッキです。
属性front-sticky
がリストであると、
リストに現れる名前のその文字の属性は先行スティッキです。
たとえば、文字の属性front-sticky
の値が(face read-only)
であると、
この文字のまえに挿入するとこの文字の属性face
とread-only
を
継承しますが、それ以外には継承しません。
rear-nonsticky
は反対の働きをします。
すべての属性はデフォルトでは後続スティッキですから、
属性rear-nonsticky
はどの属性が
後続スティッキでないかを指定します。
文字の属性rear-nonsticky
がt
であると、
その文字には後続スティッキである属性はありません。
属性rear-nonsticky
がリストであると、
リストに名前が現れない限り、
属性は後続スティッキです。
継承するようにテキストを挿入すると、 まえの文字からは後続スティッキであるすべての属性を継承し、 うしろの文字からは先行スティッキであるすべての属性を継承します。 両側の文字に異なるスティッキ性の同じ属性がある場合には、 まえの文字の属性が優先します。
属性を継承してテキストを挿入する関数はつぎのとおりです。
insert-and-inherit &rest strings | Function |
関数insert と同様に文字列stringsを挿入するが、
前後のテキストから任意のスティッキ性の属性を継承する。
|
insert-before-markers-and-inherit &rest strings | Function |
関数insert-before-markers と同様に文字列stringsを挿入するが、
前後のテキストから任意のスティッキ性の属性を継承する。
|
継承しない普通の挿入関数については、See Insertion。
つぎの2つのフックを使って、 テキスト属性を(テキストそのものとともに)ファイルに保存しておき、 ファイルを訪問したり挿入するときに同じテキスト属性を復元できます。
write-region-annotate-functions | Variable |
この変数の値は、ファイルへ書き込むテキストに対する注記の形で
テキスト属性を符号化するためにwrite-region が呼び出す関数の
リストである。
see Writing to Files。
リスト内の各関数は2つの引数、つまり、 書き込む領域の先頭と末尾で呼び出される。 これらの関数はバッファの内容を変更しないこと。 そのかわりに、バッファのテキストに加えてファイルに書き込むべき 注記を表すリストを返すべきである。 各関数は、 これらの関数が返す各リストは、positionの昇順になっている必要がある。
複数の関数があると、
|
after-insert-file-functions | Variable |
この変数は、insert-file-contents がファイルの内容を挿入してから
呼び出す関数のリストを保持する。
これらの関数は挿入されたテキストで注記を走査し、
それらが表すテキスト属性にそれらを変換する。
各関数は1つの引数、つまり、挿入されたテキストの長さで呼ばれ、 ポイントは挿入されたテキストの先頭を表す。 関数は当該テキストで注記を走査して注記を削除し、 注記が指定するテキスト属性を作成する。 関数は、変更を反映した挿入されたテキストの更新された長さを返すこと。 関数が返した値がつぎの関数の引数になる。 これらの関数は、挿入されたテキストの先頭にポイントをつねに戻すこと。
|
これらのフックを使ってファイルにテキスト属性を保存したり復元する Lispプログラムを書いて、さまざまなデータ書式を試して よいものをみつけるようにお願いします。 最終的には、Emacsに取り込める良質で汎用の拡張を ユーザーが作り出すことを願っています。
テキスト属性の名前や値として任意のLispオブジェクトを 処理しないように忠告しておきます。 そのような汎用のプログラムは書くのが難しく動作が遅くなりがちです。 そのかわりに、適当に柔軟性があり符号化が難しくないデータ型の集合を選びます。
関連する機能については、See Format Conversion。
バッファ内のすべてのテキストのテキスト属性を計算するかわりに、 必要になった時点でテキストの一部分のテキスト属性を計算するようにできます。
バッファからテキスト属性とともにテキストを取り出す基本関数は、
buffer-substring
です。
属性を調べるまえに、この関数はアブノーマルフック
buffer-access-fontify-functions
を実行します。
buffer-access-fontify-functions | Variable |
この変数は、テキスト属性を計算する関数のリストを保持する。
buffer-substring がバッファの一部分からテキストとテキスト属性を
コピーするまえに、この関数はこのリスト内の関数すべてを呼び出す。
各関数は、バッファの参照される範囲を指定する2つの引数を受け取る。
(バッファはつねにカレントバッファである。)
|
関数buffer-substring-no-properties
は
テキスト属性を無視するので、これらの関数を呼び出しません。
バッファの同じ部分に対してフック関数が複数回呼び出されるのを防ぐには、
変数buffer-access-fontified-property
を使います。
buffer-access-fontified-property | Variable |
この変数の値がnil 以外であると、
それはテキスト属性の名前として使われるシンボルである。
そのテキスト属性に対するnil 以外の値は、
『この文字の他のテキスト属性はすでに計算済みである』ことを意味する。
この機能を使う普通の方法は、
|
バッファ内にクリック可能なテキスト(clickable text)を設定するには 2つの方法があります。 これは典型的には2つの部分から成ります。 つまり、マウスが重なるとテキストを強調表示し、 テキストのその部分をクリックすると マウスボタンがなんらかの処理を行うようにします。
強調表示はテキスト属性mouse-face
で行います。
diredでの方法を例として示します。
(condition-case nil (if (dired-move-to-filename) (put-text-property (point) (save-excursion (dired-move-to-end-of-filename) (point)) 'mouse-face 'highlight)) (error nil))
put-text-property
の最初の2つの引数は、
テキストの先頭と末尾を指定します。
このテキストをクリックしたときにマウスになにかをさせるようにする
普通の方法は、メジャーモードのキーマップでmouse-2
を定義することです。
クリック可能なテキストをクリックしたかどうかの検査は、
コマンド定義で行われます。
diredではつぎのようにしています。
(defun dired-mouse-find-file-other-window (event) "In dired, visit the file or directory name you click on." (interactive "e") (let (file) (save-excursion (set-buffer (window-buffer (posn-window (event-end event)))) (save-excursion (goto-char (posn-point (event-end event))) (setq file (dired-get-filename)))) (select-window (posn-window (event-end event))) (find-file-other-window (file-name-sans-versions file t))))
外側のsave-excursion
は、カレントバッファが変わることを防ぎます。
内側のは、クリックしたバッファのポイントを恒久的に変更することを防ぎます。
この例では、diredは関数dired-get-filename
を用いて、
イベントの位置に基づいて訪問すべきファイルを決定します。
メジャーモードのマウスコマンドを定義するかわりに、
テキスト属性local-map
を使って、
クリック可能なテキストそのものにキーバインディングを定義することもできます。
(let ((map (make-sparse-keymap))) (define-key-binding map [mouse-2] 'operate-this-button) (put-text-property (point) (save-excursion (dired-move-to-end-of-filename) (point)) 'local-map map))
この方法では、テキストのさまざまなクリック可能な部分に 異なるコマンドを定義できます。 さらに、バッファの残りの部分に対しては、 メジャーモードの定義(やグローバルな定義)がそのまま有効です。
バッファ内のテキストに属性を付加できるエディタのなかには、 ユーザーにテキスト内の『範囲』を指定させ、 その範囲に属性を付加するものがあります。 このようなエディタでは、ユーザーやプログラマが 個々の範囲の先頭と末尾を決定できます。 テキスト変更に伴うある種の矛盾するようなふるまいを避けるために、 熟考の結果Emacs Lispでは別の種類のインターフェイスを提供することにしました。
複数の範囲に細分することが意味を持つならば、 ある属性の1つの範囲があるだけのバッファと、 その同じテキストをその同じ属性の2つの範囲にしてあるバッファとを 区別できるはずです。
1つの範囲だけを持つバッファにおいて、そのテキストの一部をキルしたとします。 バッファに残っているテキストは1つの範囲であり、 キルリング(とアンドゥリスト)内のコピーは1つの別の範囲になります。 そしてキルされたテキストをヤンクして戻すと、 同じ属性を持つ2つの範囲ができます。 つまり、編集すると、1つの範囲と2つの範囲の区別を保存できなくなります。
テキストを挿入すると2つの範囲を融合することで この問題を『修正』したとします。 バッファにもともと1つの範囲しかなければ、うまくいきます。 しかし、同じ属性の範囲が連続して2つある場合に、 一方の範囲をキルしてからヤンクして戻したとします。 別の場面では救いになる同じ属性の範囲を融合する機能が、 ここではトラブルを引き起こします。 つまり、ヤンクすると1つの範囲になってしまいます。 ここでも、編集すると、1つの範囲と2つの範囲の区別を保存できなくなります。
2つの範囲の境界にテキストを挿入する場合でも、 満足できる解決方法がない問題を提起します。
しかし、『この文字の属性はなにか』といった形の問いに対して 一貫したふるまいをするような編集にするのは簡単です。 そのために、これらが唯一の意味ある問いかけであると判断したのです。 範囲の先頭と末尾を問うようなものは実装してありません。
実用上は、明示的な範囲の境界のかわりに、 テキスト属性を探索する関数を普通は使えます。 それらの関数は、可能な場合にはつねに範囲は融合されると仮定して 範囲の境界を探すと考えることができます。 See Property Search。
Emacsには表示機能として明示的な範囲もあります。 Overlaysを参照してください。
つぎの関数は、指定した領域内の文字をそれらの文字コードに基づいて置き換えます。
subst-char-in-region start end old-char new-char &optional noundo | Function |
この関数は、カレントバッファのstartとendで定義される領域の
すべての文字old-charを文字new-charに置き換える。
noundoが
---------- 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 ---------- |
translate-region start end table | Function |
この関数は、バッファのstartとendのあいだの文字に変換表を適用する。
変換表tableは文字列であり、
|
レジスタは、Emacsの編集においてさまざまな種類の値を保持できる変数の一種です。 各レジスタには1文字の名前が付いています。 すべてのASCII文字とそれらのメタ変種(ただしC-gを除く)を レジスタの名前に使えます。 したがって、255個のレジスタを使えます。 Emacs Lispでは、レジスタ名でレジスタを区別します。
register-alist | Variable |
この変数は、(name . contents) の形の要素の連想リストである。
通常、使用中のEmacsの各レジスタに対して1つの要素がある。
オブジェクトnameは、レジスタを識別する文字(整数)である。 |
レジスタの内容(contents)に可能な型はいくつかあります。
insert-register
がレジスタ内で数をみつけると10進数に変換する。
(window-configuration position)
(frame-configuration position)
本節の関数は、明記してない場合には予測できない値を返します。
get-register reg | Function |
この関数は、レジスタregの内容、
あるいは、内容がなければnil を返す。
|
set-register reg value | Function |
この関数は、レジスタregの内容をvalueとする。 レジスタには任意の値を設定できるが、他のレジスタ関数は 特定のデータ型を期待する。 戻り値はvalueである。 |
view-register reg | コマンド |
このコマンドは、レジスタregになにが入っているかを表示する。 |
insert-register reg &optional beforep | コマンド |
このコマンドはレジスタregの内容をカレントバッファに挿入する。
通常、このコマンドは挿入したテキストのまえにポイントを置き、
そのあとにマークを置く。
しかし、省略可能な2番目の引数beforepが レジスタに矩形領域が含まれる場合、 ポイント位置に矩形領域の左上隅がくるように挿入される。 つまり、テキストは現在行とそのしたの連続する行に挿入される。 保存したテキスト(文字列)や矩形領域(リスト)以外がレジスタに入っていると、 現状では有用なことは起こらない。 将来これは変更されるであろう。 |
つぎのサブルーティンは転置コマンドで使われます。
transpose-regions start1 end1 start2 end2 &optional leave-markers | Function |
この関数は、バッファの重なり合わない2つの部分を入れ換える。
引数start1とend1で一方の部分の境界を指定し、
引数start2とend2で他方の部分の境界を指定する。
通常、 |
これらのフックにより、すべてのバッファ (それらをバッファローカルにしておけば特定のバッファ)における すべての変更を知るようにできます。 テキストの特定部分の変更を検出する方法については、 Special Propertiesも参照してください。
これらのフックに使う関数において正規表現を使う場合には、 マッチデータを保存し復元する必要があります。 さもないと、それらを呼び出す編集操作と奇妙な干渉を引き起こします。
before-change-functions | Variable |
この変数は、バッファを変更するまえに呼び出すべき関数のリストを保持する。 各関数は2つの引数、つまり、整数で表した変更対象の領域の先頭と末尾を受け取る。 変更対象のバッファはつねにカレントバッファである。 |
after-change-functions | Variable |
この変数は、バッファを変更したあとに呼び出すべき関数のリストを保持する。
各関数は3つの引数、つまり、変更されたばかりの領域の先頭と末尾、
変更前に存在していたテキストの長さを受け取る。
3つの引数はすべて整数である。
変更対象のバッファはつねにカレントバッファである。
古いテキストの長さは、変更前のそのテキストの先頭と末尾の バッファ内位置の差である。 変更済みのテキストの長さは、単純に始めの2つの引数の差である。 |
combine-after-change-calls body... | Macro |
このマクロは通常どおりbodyを実行するが、
一連の変更に対して安全と思えるときには、
after-change-functions の関数を一度だけ呼び出す。
プログラムからバッファの同じ部分でテキスト変更を複数回行う場合、
プログラムの当該部分の周りでマクロ 警告: 注意: |
before-change-function | Variable |
この廃れた変数は、任意のバッファの変更を行うまえに
呼ばれる1つの関数を保持する
(nil ならばそのような関数はなし)。
before-change-functions の関数と同様に呼ばれる。
|
after-change-function | Variable |
この廃れた変数は、任意のバッファの変更を行ったあとに
呼ばれる1つの関数を保持する
(nil ならばそのような関数はなし)。
after-change-functions の関数と同様に呼ばれる。
|
上の4つの変数は、これらの関数が実行中には一時的にnil
に束縛されます。
つまり、これらの関数の1つがバッファを変更しても、
その変更ではこれらの関数を呼び出しません。
フック関数においてこれらの関数を実行するような変更を行いたい場合には、
フック関数でこれらの変数をそれらの通常の値に束縛し直します。
この保護的な機構の1つの不便な帰結は、
after-change-functions
やbefore-change-functions
には、
その変数の値を変更する関数を持てないことです。
しかし、これは本当の制限ではありません。
それらの関数で実行すべき関数のリストを変更したければ、
単純に1つの定まった関数をフックに追加し、
その関数では呼び出すべき別の関数を指定する別の変数を調べます。
つぎのようにします。
(setq my-own-after-change-functions nil) (defun indirect-after-change-function (beg end len) (let ((list my-own-after-change-functions)) (while list (funcall (car list) beg end len) (setq list (cdr list))))) (add-hooks 'after-change-functions 'indirect-after-change-function)
first-change-hook | Variable |
この変数は、未変更状態のバッファを変更するたびに実行される ノーマルフックである。 |
本章では、非ASCIIに関連する特別なことがらと それらが文字列やバッファにどのように保存されるかについて述べます。
Emacsには2つのテキスト表現、つまり、 文字列やバッファでテキストを表す方法が2つあります。 これらは、ユニバイト(unibyte)と マルチバイト(multibyte)と呼ばれます。 各文字列や各バッファでは、これらの2つの表現の一方を使います。 ほとんどの目的には、Emacsがこれらのあいだで適切に変換するので、 読者はこれらの表現に関しては無視できます。 Lispプログラムでは、これらの違いに注意する必要がしばしばあります。
ユニバイト表現では、各文字は1バイトを占め、
そのため、可能な文字コードの範囲は0から255です。
コード0から127はASCII文字です。
コード128から255は非ASCII文字集合の1つ
(変数nonascii-insert-offset
に設定して文字集合を選べる)
に使われます。
マルチバイト表現では、1文字は1バイト以上を占め、 そのため、Emacsの文字コードの範囲全体を格納できるのです。 マルチバイト文字の最初のバイトはつねに128から159(8進数で0200から0237)の 範囲にあります。 これらの値をリーディングコード(leading code)と呼びます。 マルチバイト文字の2バイト以降はつねに160から255(8進数で0240から0377)の 範囲にあります。 これらの値をトレイリングコード(trailing code)と呼びます。
バッファでは、変数enable-multibyte-characters
の
バッファローカルな値が使用する表現を指定します。
文字列の表現は、文字列を作成するときの文字列の内容に基づいて決定されます。
enable-multibyte-characters | Variable |
この変数は、バッファのテキスト表現を指定する。
これがnil 以外であると、バッファはマルチバイトテキストを保持する。
さもなければユニバイトテキストを保持する。
この変数に直接設定することはできない。
そのかわりに、バッファの表現を変更するには、
関数 |
default-enable-multibyte-characters | Variable |
この変数の値は、
(default-value 'enable-multibyte-characters) に完全に等価であり、
この変数に設定するとデフォルト値を変更する。
バッファのenable-multibyte-characters のローカルな束縛に設定することは
許されていないが、デフォルト値を変更することは可能であり、
そうしても既存のバッファには影響しないので理にかなっている。
コマンド行オプション |
multibyte-string-p string | Function |
文字列stringにマルチバイト文字が含まれるとt を返す。
|
Emacsはユニバイトテキストをマルチバイトに変換できます。 マルチバイトテキストをユニバイトにも変換できますが、 この変換では情報が欠落します。 バッファにテキストを挿入するとき、あるいは、 複数の文字列から1つの文字列にテキストを収めるときに、 一般にこれらの変換が行われます。 文字列の内容をどちらかの表現に明示的にも変換できます。
Emacsは、文字列を作成するときにはその内容に基づいて 文字列の表現を選びます。 一般則は、ユニバイトテキストを他のマルチバイトテキストに組み入れるときには ユニバイトテキストをマルチバイトテキストに変換します。 マルチバイト表現のほうが汎用であり、 ユニバイトテキストのどんな文字でも保持できるからです。
バッファにテキストを挿入するときには、Emacsは、
当該バッファのenable-multibyte-characters
の指定に従った
バッファの表現にテキストを変換します。
特に、ユニバイトバッファにマルチバイトテキストを挿入するときには、
マルチバイトテキスト内のすべての文字を一般には保存できなくても、
Emacsはテキストをユニバイトに変換します。
自然な代替案はバッファ内容をマルチバイトに変換することですが、
これは受け入れられません。
バッファの表現はユーザーが選択したものであり自動的には無視できないからです。
ユニバイトテキストをマルチバイトテキストに変換しても
ASCII文字は無変更であり、128から159も同様です。
160から255の非ASCIIについては、
各文字にnonascii-insert-offset
の値を加算することで変換します。
この変数に設定すると、ユニバイト文字がどの文字集合に対応するかを指定できます
(see Character Sets)。
たとえば、nonascii-insert-offset
が
(- (make-char 'latin-iso8859-1) 128)
の2048であると、
非ASCIIのユニバイトはLatin 1に対応します。
(- (make-char 'greek-iso8859-7) 128)
の2688であると、
ギリシャ文字に対応します。
マルチバイトテキストをユニバイトに変換するのは簡単で、
各文字コードと255の論理積をとります。
nonascii-insert-offset
に
文字集合の始まりに対応する合理的な値が設定されていれば、
この変換は逆変換になります。
つまり、ユニバイトテキストをマルチバイトに変換し、
それをユニバイトに戻すともとのユニバイトテキストになります。
nonascii-insert-offset | Variable |
この変数は、ユニバイトテキストをマルチバイトに変換するときに
非ASCII文字に加算する値を指定する。
これは、128から255のユニバイトの非ASCIIの範囲の文字を挿入する
self-insert-command にも適用される。
しかし、関数insert-char はこの変換を行わない。
文字集合csを選択する正しい値は、
|
nonascii-translation-table | Variable |
この変数は、nonascii-insert-offset のより一般的な代替を提供する。
128から255の範囲の各コードをマルチバイト文字に変換する方法を
独立して指定するために使える。
その値はベクトルかnil であること。
これがnil 以外であると、nonascii-insert-offset に優先する。
|
string-make-unibyte string | Function |
この関数は、stringのテキストがすでにユニバイトでなければ ユニバイト表現に変換してから結果を返す。 stringがユニバイトであれば無変更で返す。 |
string-make-multibyte string | Function |
この関数は、stringのテキストがすでにマルチバイトでなければ マルチバイト表現に変換してから結果を返す。 stringがマルチバイトであれば無変更で返す。 |
既存のバッファや文字列がユニバイトであるときに マルチバイトとして調べたり、その逆のように調べるのが 有用なこともあります
set-buffer-multibyte multibyte | Function |
カレントバッファの表現方法を設定する。
multibyteがnil 以外であると、バッファはマルチバイトになる。
multibyteがnil であると、バッファはユニバイトになる。
この関数は、バイト列としてみたバッファ内容を変更しない。 その結果、文字として見たときの内容を変更できる。 マルチバイト表現では1文字とみなされる2バイトの列は、 ユニバイト表現では2文字になる。 この関数は、 |
string-as-unibyte string | Function |
この関数は、各バイトを1文字とみなして
stringと同じバイトの文字列を返す。
つまり、値にはstringより多くの文字が含まれることがある。
stringがすでにユニバイトであると、 値はstringそのものである。 |
string-as-multibyte string | Function |
この関数は、マルチバイトの各列を1文字とみなして
stringと同じバイトの文字列を返す。
つまり、値にはstringより少ない文字が含まれることがある。
stringがすでにマルチバイトであると、 値はstringそのものである。 |
ユニバイトとマルチバイトのテキスト表現では、 異なる文字コードを使っています。 ユニバイト表現において正しい文字コードは0から255の範囲であり、 これらの値は1バイトに収まります。 マルチバイト表現において正しい文字コードは0から524287の範囲ですが、 この範囲のすべての値が正しいとは限りません。 特に、値128から255は (『生のバイト』にはありうる。see Explicit Encoding)、 マルチバイトテキストでは正しくありません。 0から127のASCIIコードのみが、どちらの表現でも完全に正しいのです。
char-valid-p charcode | Function |
この関数は、charcodeが2つのテキスト表現のどちらか一方で
正しければt を返す。
(char-valid-p 65) => t (char-valid-p 256) => nil (char-valid-p 2248) => t |
Emacsは文字をさまざまな文字集合(character set)に分類します。 文字集合にはシンボルである名前があります。 各文字はたった1つの文字集合に属します。
一般に、異なる文字体系ごとに1つの文字集合があります。
たとえば、latin-iso8859-1
は1つの文字集合であり、
greek-iso8859-7
は別の文字集合であり、
ascii
も別の文字集合です。
Emacsの1つの文字集合には最大9025個の文字を保持できます。
したがって、論理的には1つの文字集合にまとめられる文字群を、
複数の文字集合に分割する場合もあります。
たとえば、Big 5として一般には知られている中国文字の1つの集合は、
Emacsの2つの文字集合、chinese-big5-1
とchinese-big5-2
に
分割されます。
charsetp object | Function |
objectが文字集合の名前のシンボルであればt を返す。
さもなければnil を返す。
|
charset-list | Function |
この関数は、定義されているすべての文字集合の名前のリストを返す。 |
char-charset character | Function |
この関数は文字characterが属する文字集合の名前を返す。 |
マルチバイト表現では、各文字は1バイトかそれ以上のバイトを占めます。 各文字集合には、通常は1バイト長か2バイト長の 導入列(introduction sequence)があります (例外:ASCIIの導入列は0バイト長である)。 導入列は、文字集合の任意の文字のバイト列の始まりです。 文字のバイト列の残りの部分は、同じ文字集合内で他の文字とその文字を区別します。 文字集合に依存して、区別するためのバイトは1バイトか2バイトです。 そのようなバイト数を文字集合の次元(dimension)と呼びます。
charset-dimension charset | Function |
この関数は、文字集合charsetの次元を返す。 現在、次元はつねに1か2である。 |
文字集合の導入列のバイト長を判定するもっとも簡単な方法はつぎのとおりです。
(- (char-bytes (make-char charset)) (charset-dimension charset))
本節の関数は、文字とそれを表現するために用いられるバイト値のあいだの 変換を行います。 ほとんどの目的に関しては、Emacsが必要に応じて自動的に行うため、 文字を表現するためのバイト列を扱う必要はありません。
char-bytes character | Function |
この関数は、文字characterを表現するために必要なバイト数を返す。
これは、文字characterが属する文字集合だけに依存し、
その文字集合(see Character Sets)の次元とその導入列の和に等しい。
(char-bytes 2248) => 2 (char-bytes 65) => 1 (char-bytes 192) => 1 マルチバイト表現とユニバイト表現のどちらに対しても この関数で正しい結果を得られるのは、 2つの表現で用いられる非ASCII文字コードに重なりがないからである。 |
split-char character | Function |
文字characterの文字集合の名前に続けて、
その文字集合でcharacterを識別する1バイトか2バイトの値(整数)から
成るリストを返す。
バイト値の個数はその文字集合の次元である。
(split-char 2248) => (latin-iso8859-1 72) (split-char 65) => (ascii 65) ユニバイトの非ASCII文字は、
文字集合 (split-char 192) => (ascii 192) |
make-char charset &rest byte-values | Function |
この関数は、文字集合charsetにおいて
byte-valuesで識別される文字を返す。
これは、split-char のほぼ逆関数にあたる。
通常、文字集合charsetの次元に応じて、
1つか2つのbyte-valuesを指定する。
たとえばつぎのとおり。
(make-char 'latin-iso8859-1 72) => 2248 |
byte-valuesを指定せずにmake-char
を呼び出すと、
その結果は文字集合charsetを代表する
汎用文字(generic character)である。
汎用文字は整数であるが、文字としてバッファに挿入するには
正しくないものである。
1つの文字集合全体を表すためにchar-table-range
で使える
(see Char-Tables)。
char-valid-p
は汎用文字に対してはnil
を返す。
たとえばつぎのとおり。
(make-char 'latin-iso8859-1) => 2176 (char-valid-p 2176) => nil (split-char 2176) => (latin-iso8859-1 0)
バッファや文字列の一部分にどの文字集合が現れるかを 調べられると有用なことがあります。 その1つの用途は、当該テキストすべてを表現する能力がある コーディングシステム(see Coding Systems)を探すことです。
find-charset-region beg end &optional translation | Function |
この関数は、カレントバッファのbegとendのあいだに
現れる文字集合のリストを返す。
省略可能な引数translationは、
テキストを走査するときに使用する変換表を指定する
(see Translation of Characters)。
これが |
find-charset-string string &optional translation | Function |
この関数は、文字列stringに現れる文字集合のリストを返す。
省略可能な引数translationは変換表を指定する。
上記の |
変換表(translation table)は、文字群を文字群へ対応付けます。 これらの表は、符号化と復号化、他の目的に使われます。 独自の変換表を指定するコーディングシステムもあります。 他のすべてのコーディングシステムに適用される デフォルトの変換表もあります。
make-translation-table translations | Function |
この関数は、引数translationsに基づいた変換表を返す。
引数translationsの各要素は、
(from . to) の形であり、
文字fromをtoへ変換することを意味する。
1つの文字集合全体を同じ次元の別の文字集合へ対応付けることも可能である。 それには、fromに(文字集合を表す)汎用文字を指定する (see Splitting Characters)。 この場合、toも、同じ次元の別の文字集合の汎用文字であること。 こうすると、この変換表は、fromの文字集合の各文字を toの文字集合の対応する文字へ変換する。 |
復号化では、もとの復号化結果の文字に変換表による変換を適用します。
コーディングシステムに属性character-translation-table-for-decode
が
あれば、これは使用する変換表を指定します。
さもなければ、standard-character-translation-table-for-decode
が
nil
以外であれば、復号化ではその表を使います。
符号化では、バッファ内の文字に変換表による変換を適用し、
変換結果を実際に符号化します。
コーディングシステムに属性character-translation-table-for-encode
が
あれば、これは使用する変換表を指定します。
さもなければ、変数standard-character-translation-table-for-encode
が
使用する変換表を指定します。
standard-character-translation-table-for-decode | Variable |
これは、変換表を指定しないコーディングシステムに対する 復号化時のデフォルトの変換表である。 |
standard-character-translation-table-for-encode | Variable |
これは、変換表を指定しないコーディングシステムに対する 符号化時のデフォルトの変換表である。 |
Emacsがファイルを読み書きしたり、 Emacsがサブプロセスへテキストを送ったり サブプロセスからテキストを受け取るときには、 コーディングシステム(coding system)で指定される 文字コード変換と行末変換を行います。
文字コード変換(character code conversion)とは、 Emacsの内部で使用する符号と他の符号とのあいだでの変換のことです。 Emacsでは、相互に変換できる多くの異なる符号を扱えます。 たとえば、Emacsは、Latin 1、Latin 2、Latin 3、Latin 4、Latin 5、 ISO 2022のいくつかの変種を相互に変換できます。 同じ文字集合に対する異なる符号を扱うこともできます。 たとえば、キリル(ロシア語)文字に対しては ISO、Alternativnyj、KOI8の3つのコーディングシステムがあります。
ほとんどのコーディングシステムでは変換する文字コードを特定しますが、 指定せずにデータに基づいて発見的手法で選ぶものもあります。
行末変換(end of line conversion)は、 ファイル内の行の終りを表すさまざまなシステムで 使われている3つの異なる慣習を扱います。 UNIXの慣習では、行送り文字(改行文字とも呼ぶ)を使います。 DOSの慣習では、行末には復帰と行送りの2文字の列を使います。 Macの慣習では、復帰のみを使います。
latin-1
のような基底コーディングシステム(base coding system)
では、行末変換を指定せずにデータに基づいて選びます。
latin-1-unix
、latin-1-dos
、latin-1-mac
のような
変種コーディングシステム(variant coding system)では、
明示的に行末変換も指定します。
ほとんどの基底コーディングシステムには、
-unix
、-dos
、-mac
を付加して作られる名前の
対応する3つの変種があります。
コーディングシステムraw-text
は
文字コード変換を行わない特別なもので、
このコーディングシステムで訪問したバッファはユニバイトバッファになります。
行末変換も指定しないので内容に基づいて決定でき、
行末変換を指定する3つの変種もあります。
no-conversion
はraw-text-unix
に等価であり、
文字コードも行末も変換しないことを指定します。
コーディングシステムemacs-mule
は、
Emacs内部での符号でデータを表現することを指定します。
これは、コード変換を行わないという意味ではraw-text
に似ていますが、
結果がマルチバイトデータになる点が異なります。
coding-system-get coding-system property | Function |
この関数は、コーディングシステムcoding-systemの指定した属性を返す。
コーディングシステムのほとんどの属性は内部目的用であるが、
読者が有用と思うものが1つ、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 属性 |
コーディングシステムの主目的は、ファイルの読み書きに使うことです。
関数insert-file-contents
はファイルのデータを復号化するために
コーディングシステムを使い、
write-region
はバッファ内容を符号化するために
コーディングシステムを使います。
使用するコーディングシステムを明示する(see Specifying Coding Systems)
こともできるし、
デフォルトの機構(see Default Coding Systems)を暗に使うこともできます。
しかし、これらの方式ではすべきことを完全に指定しきれないこともあります。
たとえば、undefined
のようなコーディングシステムを選んで、
データに基づいて文字コード変換を行うようにするかもしれません。
そのような場合、コーディングシステムの選択は
入出力操作によって完了します。
しばしば、選択されたコーディングシステムをあとで知りたくなります。
buffer-file-coding-system | Variable |
この変数は、カレントバッファで訪問するときに使用した
コーディングシステムを記録する。
これは、バッファを保存したり、
write-region でバッファの一部を書くときに使われる。
これらの操作において、ユーザーに別のコーディングシステムを指定するように
問い合わせた場合には、buffer-file-coding-system は
指定された別のコーディングシステムに更新される。
|
save-buffer-coding-system | Variable |
この変数は、write-region には使わないが、
バッファを保存するために使うコーディングシステムを指定する。
バッファを保存する際に、ユーザーに別のコーディングシステムを指定するように
問い合わせ、かつ、save-buffer-coding-system を用いている場合には、
これは指定された別のコーディングシステムに更新される。
|
last-coding-system-used | Variable |
ファイルやサブプロセスに対する入出力操作では、
使用したコーディングシステム名をこの変数に設定する。
明示的に符号化/復号化する関数(see Explicit Encoding)も
この変数に設定する。
警告: |
変数selection-coding-system
は、
ウィンドウシステムのセレクションを符号化する方法を指定します。
See Window System Selections。
コーディングシステムを扱うLispの機能について述べます。
coding-system-list &optional base-only | Function |
この関数は、すべてのコーディングシステム名(シンボル)のリストを返す。
base-onlyがnil 以外であると、
値には基底コーディングシステムのみを含める。
さもなければ、値には変種コーディングシステムも含まれる。
|
coding-system-p object | Function |
この関数は、objectがコーディングシステム名であるとt を返す。
|
check-coding-system coding-system | Function |
この関数は、coding-systemの正当性を調べる。
正しいものならばcoding-systemを返す。
さもなければ、条件coding-system-error 付きのエラーを通知する。
|
coding-system-change-eol-conversion coding-system eol-type | Function |
この関数は、coding-systemに類似のコーディングシステムを返すが、
eol-type で指定された行末変換のものである。
eol-typeは、unix 、dos 、mac 、nil の
いずれかであること。
nil であると、返されたコーディングシステムは、
データから行末変換を決定する。
|
coding-system-change-text-conversion eol-coding text-coding | Function |
この関数は、行末変換にeol-codingを使い、
テキストの変換にtext-codingを使っているコーディングシステムを返す。
text-codingがnil であると、
undecided かeol-codingに応じたundecided の変種の1つを返す。
|
find-coding-systems-region from to | Function |
この関数は、fromとtoのあいだのテキストの符号化に使用できる
コーディングシステムのリストを返す。
リスト内のすべてのコーディングシステムは、当該部分のテキストの
どんなマルチバイト文字も安全に符号化できる。
テキストにマルチバイト文字が含まれない場合、
関数はリスト |
find-coding-systems-string string | Function |
この関数は、文字列stringのテキストの符号化に使用できる
コーディングシステムのリストを返す。
リスト内のすべてのコーディングシステムは、stringの
どんなマルチバイト文字も安全に符号化できる。
テキストにマルチバイト文字が含まれない場合、
これはリスト(undecided) を返す。
|
find-coding-systems-for-charsets charsets | Function |
この関数は、リストcharsets内のすべての文字集合の符号化に使用できる コーディングシステムのリストを返す。 |
detect-coding-region start end &optional highest | Function |
この関数は、startからendまでのテキストを復号化する
もっともらしいコーディングシステムを選ぶ。
このテキストは『生のバイト』(see Explicit Encoding)であること。
この関数は、通常、走査したテキストの復号化を扱える
コーディングシステムのリストを返す。
それらは優先順位の降順に並ぶ。
しかし、highestが 領域にASCII文字だけが含まれる場合、
値は |
detect-coding-string string highest | Function |
この関数はdetect-coding-region と同様であるが、
バッファ内のバイトのかわりに文字列stringの内容に作用する。
|
サブプロセスとの入出力に使用されるコーディングシステムを 調べたり設定する方法については、See Process Information。
select-safe-coding-system from to &optional preferred-coding-system | Function |
この関数はfromとtoのあいだのテキストを符号化する
コーディングシステムを選ぶが、
必要ならばユーザーに問い合わせる。
省略可能な引数preferred-coding-systemは、
最初に試すコーディングシステムを指定する。
それが指定領域のテキストを処理できるならば、それを使う。
この引数を省略すると、
領域内にpreferred-coding-systemで符号化できない マルチバイト文字がある場合、 この関数は、当該テキストを符号化可能なコーディングシステム一覧から ユーザーに選択してもらい、ユーザーが選択したものを返す。 特殊機能: |
補完を用いてユーザーにコーディングシステムを指定させるために使える 2つの関数はつぎのとおりです。 See Completion。
read-coding-system prompt &optional default | Function |
この関数は、文字列promptをプロンプトとして ミニバッファを使ってコーディングシステムを読み取り、 コーディングシステム名をシンボルとして返す。 ユーザーの入力が空であると、 defaultは返すべきコーディングシステムを指定する。 それはシンボルか文字列であること。 |
read-non-nil-coding-system prompt | Function |
この関数は、文字列promptをプロンプトとして ミニバッファを使ってコーディングシステムを読み取り、 コーディングシステム名をシンボルとして返す。 ユーザーが空を入力しようとすると再度問い合わせる。 see Coding Systems。 |
本節では、特定のファイルや特定のサブプログラムを実行するときの デフォルトのコーディングシステムを指定する変数と、 それらを使った入出力操作を行う関数について述べます。
これらの変数の目的は、読者が望むデフォルトをいったんこれらに設定しておけば、
再度変更する必要がないようにすることです。
Lispプログラムの特定の操作向けに特定のコーディングシステムを指定するには、
これらの変数を変更しないでください。
かわりに、coding-system-for-read
やcoding-system-for-write
を
使って上書きします(see Specifying Coding Systems)。
file-coding-system-alist | Variable |
この変数は、特定のファイルの読み書きに使用する
コーディングシステムを指定する連想リストである。
各要素は(pattern . coding) の形であり、
patternは特定のファイル名に一致する正規表現である。
patternに一致するファイル名に当該要素を適用する。
要素のCDR、codingはコーディングシステムであるか、 2つのコーディングシステムを収めたコンスセルであるか、 関数シンボルであること。 codingがコーディングシステムであると、 ファイルの読み書きの両方にそのコーディングシステムを使う。 codingが2つのコーディングシステムを収めたコンスセルであると、 そのCARは復号化に使うコーディングシステムを指定し、 そのCDRは符号化に使うコーディングシステムを指定する。 codingが関数シンボルであると、 その関数は、コーディングシステムか、 2つのコーディングシステムを収めたコンスセルを返すこと。 その値は上に述べたように使われる。 |
process-coding-system-alist | Variable |
この変数は、サブプロセスで実行しているプログラムに依存して
サブプロセスに使うコーディングシステムを指定する連想リストである。
file-coding-system-alist と同様に働くが、
patternはサブプロセスを始めるために用いたプログラム名に対して
一致を取る点が異なる。
この連想リストに指定したコーディングシステムは、
サブプロセスとの入出力に使用するコーディングシステムの初期化に用いれるが、
set-process-coding-system を使って、
あとで別のコーディングシステムを指定できる。
|
警告:
データからコーディングシステムを決定するundecided
のような
コーディングシステムは、非同期サブプロセスの出力に対しては
完全に信頼性のある動作はできない。
これは、Emacsが非同期サブプロセスの出力が
到着するたびに一塊で処理するからである。
コーディングシステムが文字コード変換や行末変換を未指定にしていると、
Emacsは1つの塊から正しい変換を検出しようと試みるが、
これがつねに動作するとは限らない。
したがって、非同期サブプロセスでは、可能な限り
文字コード変換と行末変換の両方を指定したコーディングシステムを使います。
つまり、undecided
やlatin-1
などではなく、
latin-1-unix
のようなものを使います。
network-coding-system-alist | Variable |
この変数は、ネットワークストリームに使用するコーディングシステムを
指定する連想リストである。
file-coding-system-alist と同様に働くが、
要素内のpatternはポート番号か正規表現である点が異なる。
それが正規表現であると、ネットワークストリームを開くために
使用したネットワークサービス名に対して一致をとる。
|
default-process-coding-system | Variable |
この変数は、なにも指定されていないサブプロセス(やネットワークストリーム)
の入出力に使用するコーディングシステムを指定する。
値は、 |
find-operation-coding-system operation &rest arguments | Function |
この関数は、argumentsを指定してoperationを行うときに
(デフォルトで)使用されるコーディングシステムを返す。
その値はつぎの形である。
(decoding-system encoding-system) 第1要素decoding-systemは (operationが復号化を行う場合には)復号化に用いる コーディングシステムであり、 encoding-systemは (operationが符号化を行う場合には)符号化に用いる コーディングシステムである。 引数operationは、Emacsの入出力基本関数の
残りの引数は、これらの入出力基本関数に指定するであろう引数と同じであること。
基本関数に依存して、引数の1つを対象として選ぶ。
たとえば、operationがファイル入出力を行う場合、
ファイル名を指定する引数が対象である。
サブプロセスの基本関数では、プロセス名が対象である。
この関数は、operationに応じて当該対象を
|
変数coding-system-for-read
と/やcoding-system-for-write
を
束縛することで、特定の1つの操作向けのコーディングシステムを指定できます。
coding-system-for-read | Variable |
この変数がnil 以外であると、
ファイルを読むときや同期プロセスからの入力に用いる
コーディングシステムを指定する。
これは非同期プロセスやネットワークストリームにも適用されるが、
異なった方法で適用される。
サブプロセスを開始したりネットワークストリームを開いたときの
この変数の正しい使い方は、特定の入出力操作に対して
;; 文字コード変換せずにファイルから読む ;; CRLFが行末を表すと仮定する (let ((coding-system-for-write 'emacs-mule-dos)) (insert-file-contents filename)) その値が |
coding-system-for-write | Variable |
これはcoding-system-for-read と同様に働くが、
入力ではなく出力に適用される点が異なる。
ファイル、サブプロセス、ネットワーク接続へ書くことに影響する。
|
inhibit-eol-conversion | Variable |
この変数がnil 以外であると、
コーディングシステムでなにが指定されていようと行末変換を行わない。
これは、Emacsの入出力とサブプロセスのすべての基本関数、
明示的な符号化/復号化関数(see Explicit Encoding)に適用される。
|
Emacsへ/からテキストを転送するすべての操作には、 テキストを符号化したり復号化するコーディングシステムを使う能力があります。 本節に述べる関数を用いてテキストを明示的に符号化したり復号化できます。
符号化の結果と復号化する入力は、通常のEmacsのテキストではありません。
それらは『生のバイト』、つまり、外部ファイルと同じ方法で
テキストを表現するバイト列です。
バッファに生のバイトが収められている場合、
set-buffer-multibyte
(see Selecting a Representation)を用いて
バッファはユニバイト表現であると印を付けるのがもっとも自然ですが、
これは必須ではありません。
バッファの内容が単に一時的に生のバイトであるときには、
バッファはマルチバイトのままにしておきます。
バッファ内容を復号化すれば正しくなります。
明示的に復号化するためにバッファに生のバイトを入れる普通の方法は、
insert-file-contents-literally
(see Reading from Files)で
ファイルから読むか、
find-file-noselect
でファイルを訪問するときに引数rawfileに
nil
以外を指定します。
テキストの明示的な符号化で得た結果である生のバイトを使う普通の方法は、
ファイルやプロセスへそれらをコピーします。
たとえば、write-region
(see Writing to Files)でそれらを書くには、
coding-system-for-write
にno-conversion
を束縛して
write-region
の符号化を抑制します。
生のバイトには、正しいマルチバイト文字に 余分なトレイリングコードが付いたように見える長すぎるバイト列が 含まれる場合があります。 ほとんどの目的には、バッファや文字列のそのような列をEmacsは1文字として扱い、 その文字コードを調べるとマルチバイト文字の列に対応した値を得るはずです。 余分なバイト列は無視されます。 このふるまいは透明性がよくありませんが、 生のバイトはEmacsの限定された場面でのみ使われ、実用上の問題は回避できます。
encode-coding-region start end coding-system | Function |
この関数は、コーディングシステムcoding-systemに従って startからendのテキストを符号化する。 符号化結果はバッファ内のもとのテキストを置き換える。 符号化結果は『生のバイト』であるが、 マルチバイトであったバッファはマルチバイトのままである。 |
encode-coding-string string coding-system | Function |
この関数は、コーディングシステムcoding-systemに従って 文字列stringのテキストを符号化する。 符号化したテキストを含む新たな文字列を返す。 符号化結果は『生のバイト』のユニバイト文字列である。 |
decode-coding-region start end coding-system | Function |
この関数は、コーディングシステムcoding-systemに従って startからendのテキストを復号化する。 復号化結果はバッファ内のもとのテキストを置き換える。 明示的な復号化が有用であるためには、 復号化前のテキストは『生のバイト』であること。 |
decode-coding-string string coding-system | Function |
この関数は、コーディングシステムcoding-systemに従って 文字列stringのテキストを復号化する。 復号化したテキストを含む新たな文字列を返す。 明示的な復号化が有用であるためには、 復号化前のstringの内容は『生のバイト』であること。 |
Emacsは、コーディングシステムを用いてキーボード入力を復号化したり、
端末出力を符号化できます。
Latin-1などの特定の符号を用いてテキストを送信したり表示する
端末に対しては、これは有用です。
Emacsは、端末に対する符号化や復号化では
last-coding-system-used
に設定しません。
keyboard-coding-system | Function |
この関数は、キーボード入力の復号化に用いている
コーディングシステムを返す。
コーディングシステムを使用していなければnil を返す。
|
set-keyboard-coding-system coding-system | Function |
この関数は、キーボード入力の復号化に使用するコーディングシステムとして
coding-systemを指定する。
coding-systemがnil であると、
キーボード入力に復号化を用いないことを意味する。
|
terminal-coding-system | Function |
この関数は、端末出力の符号化に用いている
コーディングシステムを返す。
コーディングシステムを使用していなければnil を返す。
|
set-terminal-coding-system coding-system | Function |
この関数は、端末出力の符号化に使用するコーディングシステムとして
coding-systemを指定する。
coding-systemがnil であると、
端末出力に符号化を用いないことを意味する。
|
MS-DOSやMS-Windows上のEmacsは、 特定のファイル名をテキストファイルやバイナリファイルとして認識します。 『バイナリファイル』とは、必ずしも文字を意味しないバイト値のファイルです。 Emacsは、バイナリファイルに対しては行末変換や文字コード変換を行いません。 一方、その名前から『テキストファイル』と印が付いた 新規ファイルを作成すると、EmacsはDOSの行末変換を行います。
buffer-file-type | Variable |
この変数は、各バッファで自動的にバッファローカルになり、
バッファで訪問したファイルのファイル型を記録する。
バッファがbuffer-file-coding-system で
コーディングシステムを指定しない場合、
バッファ内容を書き出すときに用いるコーディングシステムを
この変数を用いて決定する。
テキストに対してはnil 、バイナリに対してt であること。
これがt であると、コーディングシステムはno-conversion である。
さもなければ、undecided-dos を用いる。
通常、この変数はファイルを訪問すると設定される。
いかなる変換も行わずにファイルを訪問すると |
file-name-buffer-file-type-alist | User Option |
この変数は、テキスト/バイナリファイルを認識するための連想リストを保持する。
各要素は(regexp . type)の形である。
ここで、regexpはファイル名に対して一致をとり、
typeは、テキストファイルではnil 、
バイナリファイルではt 、あるいは、
どちらであるかを計算するために呼び出す関数である。
それが関数であると、1つの引数(ファイル名)で呼ばれ、
t かnil を返すこと。
MS-DOSやMS-Windowsで動作しているEmacsは、
この連想リストを調べて、ファイルを読む際に使用する
コーディングシステムを決定する。
テキストファイルでは 指定したファイルがこの連想リストの要素に一致しないと、
|
default-buffer-file-type | User Option |
この変数は、file-name-buffer-file-type-alist が指定しない型の
ファイルの扱い方を指定する。
この変数が |
入力方式(input method)は、 キーボードから非ASCII文字を入力する簡便な方法を提供します。 プログラムが読み取るための非ASCII文字の符号変換を行う コーディングシステムと異なり、 入力方式は人間向けのコマンドを提供します。 (テキストを入力するための入力方式の使い方については、 see Input Methods。) 入力方式の定義方法については本書ではまだ明文化してありませんが、 ここではそれらの使い方について述べます。
各入力方式には名前があります。 それは現在のところ文字列ですが、 将来は入力方式名としてシンボルも使えるようになります。
current-input-method | Variable |
この変数は、カレントバッファで現在活性な入力方式の名前を保持する。
(この変数に設定すると自動的にバッファローカルになる。)
nil であると、バッファでは入力方式が活性ではない。
|
default-input-method | Variable |
この変数は、入力方式を選ぶコマンド向けのデフォルトの入力方式を保持する。
current-input-method と異なり、この変数は通常はグローバルである。
|
set-input-method input-method | Function |
この関数は、カレントバッファにおいて
入力方式input-methodを活性にする。
default-input-method にもinput-methodを設定する。
input-methodがnil であると、
この関数はカレントバッファの入力方式を不活性にする。
|
read-input-method-name prompt &optional default inhibit-null | Function |
この関数は、プロンプトpromptを用いてミニバッファで入力方式名を読む。
defaultがnil 以外であると、
ユーザーが空の入力をするとデフォルトでこれを返す。
しかし、inhibit-nullがnil 以外であると、
空の入力はエラーを通知する。
戻り値は文字列である。 |
input-method-alist | Variable |
この変数は、使用可能なすべての入力方式を定義する。
各要素は1つの入力方式を定義し、つぎの形であること。
(input-method language-env activate-func title description args...) ここで、input-methodは入力方式名であり文字列である。 language-envも別の文字列であり当該入力方式を 推奨する言語環境の名前である。 (これは説明文目的のためだけである。) titleは、この入力方式が活性である場合に モード行に表示される文字列である。 descriptionはこの入力方式と何向きであるかを 説明する文字列である。 activate-funcは、この入力方式を活性にするために呼び出す関数である。 argsがあればactivate-funcへの引数として渡される。 つまり、activate-funcの引数はinput-methodとargsである。 |
入力方式に対する基本的なインターフェイスは
変数input-method-function
を介して行います。
See Reading One Event。
GNU Emacsにはバッファから指定したテキストを探す方法が2つあります。 文字列そのものを正確に探索するのと正規表現の探索です。 正規表現の探索のあとでは、 正規表現全体やそのさまざまな部分に一致したテキストを表す マッチデータ(match data)を調べることができます。
query-replace
.
skip-chars...
などの関数もある種の探索を行います。
See Skipping Characters。
これらは、バッファ内のテキストを探索するための基本関数です。
これらはプログラムで使うことを意図していますが、
対話的に呼び出すこともできます。
その場合、探索文字列を問い合わせてきますが、
limitとnoerrorはnil
に、repeatは1に設定されます。
これらの探索関数は、バッファがマルチバイトであると 探索文字列をマルチバイトに変換します。 バッファがユニバイトであると探索文字列をユニバイトに変換します。 See Text Representations。
search-forward string &optional limit noerror repeat | コマンド |
この関数は、ポイントから前方へ向けて文字列stringに
ちょうど一致するものを探す。
それに成功すれば、ポイントをみつけた出現箇所の末尾に移動し、
ポイントの新たな値を返す。
一致がみつからなければ、戻り値と副作用はnoerrorに依存する(下記参照)。
つぎの例では、ポイントは始めは行頭にある。
そして ---------- Buffer: foo ---------- -!-The quick brown fox jumped over the lazy dog. ---------- Buffer: foo ---------- (search-forward "fox") => 20 ---------- Buffer: foo ---------- The quick brown fox-!- jumped over the lazy dog. ---------- Buffer: foo ---------- 引数limitは探索の上限を指定する。
(カレントバッファ内の位置であること。)
その位置を越える箇所での一致は受け入れない。
limitを省略したり 探索に失敗した場合の動作は、noerrorの値に依存する。
noerrorが repeatを指定してあると(正の数であること)、 その回数だけ探索を繰り返す(一致箇所の末尾を新たな探索の開始位置とする)。 連続してこれらの探索に成功すると関数は成功し、 ポイントを移動してその新たな値を返す。 さもなければ探索は失敗である。 |
search-backward string &optional limit noerror repeat | コマンド |
この関数は、ポイントから後方へ向けてstringを探索する。
search-forward と同様であるが、後方へ向けて探索し
一致箇所の先頭にポイントを置く点が異なる。
|
word-search-forward string &optional limit noerror repeat | コマンド |
この関数は、ポイントから前方へ向けてstringに一致する『単語』を探索する。
一致をみつけると、一致箇所の末尾にポイントを設定し
ポイントの新たな値を返す。
単語の一致では、stringを単語の列とみなし、
それらを区切る句読点は無視する。
バッファ内の同じ単語の列を探す。
バッファ内の各単語は別々になっている必要があるが
(単語 つぎの例では、ポイントは始めはバッファの先頭にある。
探索するとポイントは ---------- Buffer: foo ---------- -!-He said "Please! Find the ball boy!" ---------- Buffer: foo ---------- (word-search-forward "Please find the ball, boy.") => 35 ---------- Buffer: foo ---------- He said "Please! Find the ball boy-!-!" ---------- Buffer: foo ---------- limitが noerrorが repeatが |
word-search-backward string &optional limit noerror repeat | コマンド |
この関数はポイントから後方へ向けてstringに一致する単語を探索する。
この関数はword-search-forward と同様であるが、
後方へ向けて探索し一致箇所の先頭にポイントを置く点が異なる。
|
正規表現(regular expression、略してregexp)は、 文字列の(無限の可能性もある)集合を表すパターンです。 正規表現への一致を探すことは、非常に強力な操作です。 本節では、正規表現の書き方を説明します。 続く節では、それらを探索する方法を説明します。
正規表現では、数個の文字が特別な構成であり、残りは普通です。
普通の文字は、その文字だけに一致する単純な正規表現です。
特別な文字は、.
、*
、+
、
?
、[
、]
、^
、$
、\
であり、
将来新たな文字が定義されることはありません。
正規表現に現れるこれら以外の文字は、
まえに\
がない限り普通の文字です。
たとえば、f
は特別な文字ではないので普通の文字です。
ですから、f
は文字列f
だけに一致する正規表現です。
(これは文字列ff
には一致しない。)
同様に、o
はo
だけに一致する正規表現です。
任意の2つの正規表現aとbを連結できます。 その結果は、aが文字列の始めの部分に一致し、かつ、 bがその文字列の残りに一致するときにその文字列に一致する 正規表現になります。
簡単な例として、正規表現 f
とo
を連結して
正規表現fo
を得られます。
これは文字列fo
だけに一致します。
これは明らかですね。
より強力なことをするには、特別な文字の1つを使う必要があります。
それらの一覧を以下に示します。
.
(ピリオド)
a.b
のような正規表現を作れる。
これは、a
で始まりb
で終る任意の3文字の文字列に一致する。
*
o*
は(o
が存在しない場合も含めて)
任意個のo
に一致する。
*
はつねに先行する最小の正規表現に適用される。
したがって、fo*
はfo
を繰り返すのではなく、
o
を繰り返す。
この正規表現はf
、fo
、foo
などに一致する。
*
を用いた構成の一致を処理するときには、
ただちに得られる限りの反復回数に展開される。
そうしてから、残りのパターンを処理する。
一致に失敗するとバックトラック(後戻り)が発生して、
*
を用いた構成の反復回数を減らして
パターンの残りの部分が一致できるようにする。
たとえば、文字列caaar
に対して
ca*ar
を一致させることを考えてみる。
始めに、a*
を3つのa
すべてに一致させようとする。
しかし、残りのパターンがar
なのにr
しか残っていないため、
この試みは失敗する。
そこで、つぎはa*
をa
2つだけに一致させる。
こうすると、残りの正規表現も正しく一致する。
入れ子にした反復演算子がバックトラックのループを指定する場合、
それはとても遅くなる。
たとえば、正規表現\(x+y*\)*a
を
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz
の列に一致させると
最終的に失敗するまで何時間も費してしまう。
遅さの原因は、Emacsは35個のx
をグループに分ける各方法を
すべて試してからでないとそれらが一致しないことを結論できないからである。
読者の正規表現が素早く動作することを保証するために、
入れ子になった繰り返しを注意深く調べること。
+
*
に似た後置演算子だが、
直前の正規表現に1回以上一致する必要がある。
たとえば、ca+r
は、文字列car
やcaaaar
には一致するが、
文字列cr
には一致ない。
一方、ca*r
の場合は、上記の3つすべてに一致する。
?
*
に似た後置演算子だが、
直前の正規表現に1回だけ一致するか、あるいは、1回も一致しない。
たとえば、ca?r
は、car
やcr
に一致するが、
他のものには一致しない。
[ ... ]
[
で始まり]
で終る文字選択を表す。
もっとも単純な場合は、
この2つの中括弧のあいだにある文字の1つ1つがこの文字選択に一致する。
したがって、[ad]
は、a
1文字かd
1文字のどちらにも一致する。
[ad]*
は、a
とd
だけから成る
(空の文字列を含む)任意の文字列に一致する。
このことから、c[ad]*r
は、
cr
、car
、cdr
、caddaar
などに一致することがわかる。
文字選択には、文字範囲の指定を含めることもでき、
始めの文字と終りの文字のあいだに-
を書く。
つまり、[a-z]
はすべてのASCII小英文字に一致する。
範囲指定と個々の文字を自由に織り混ぜてよく、
[a-z$%.]
のように書ける。
これは、任意のASCII小英文字、$
、%
、ピリオドに一致する。
正規表現[\200-\377]
で
すべての非ASCII文字につねに一致するとは限らない。
ユニバイト(see Text Representations)のバッファや文字列を
探索するときにはうまく働くが、マルチバイトのバッファや文字列では
多くの非ASCII文字のコードは8進数0377より大きいために働かない。
しかし、正規表現[^\000-\177]
は、
ASCII文字のみを除外しているため、
マルチバイト表現でもユニバイト表現でもすべての非ASCII文字に一致する。
範囲指定の始めと終りは同じ文字集合(see Character Sets)に
属している必要がある。
したがって、[a-\x8e0]
は正しくない。
a
はASCII文字集合に属し、
文字0x8e0(グレーブアクセント付きa
)は
EmacsのLatin-1の文字集合に属しているからである。
正規表現の普通の特別な文字は、文字選択の内側では特別ではないことに注意。
文字選択の内側では、まったく別の文字の集まり、
]
、-
、^
が特別である。
文字選択に]
を含めるには、
]
を最初の文字として指定する必要がある。
たとえば、[]a]
は、]
やa
に一致する。
-
を含めるには、-
を文字選択の最初の文字か
最後の文字として書くか、範囲指定のあとに置く。
したがって、[]-]
は、]
と-
の両方に一致する。
文字選択に^
を含めるには、^
を文字選択の2番目以降に置く。
[^ ... ]
[^
は文字選択の補集合の始まりを意味し、
指定した文字を除く任意の文字に一致する。
すなわち、[^a-z0-9A-Z]
は、
英文字と数字文字を除くすべての文字に一致する。
^
は文字選択の先頭になければ文字選択では特別な意味を持たない。
^
に続く文字は先頭にあるものとして扱われる
(いいかえれば、ここでは-
や]
は特別な意味を持たない)。
文字選択の補集合は、一致しない文字として改行を指定しない限り、
改行にも一致する。
この点は、grep
のようなプログラムでの正規表現の扱い方と対照的である。
^
^foo
は、行頭にあるfoo
に一致する。
バッファのかわりに文字列と一致を取るときには、
^
は文字列の先頭や改行文字\n
のうしろに一致する。
$
^
と同様だが行末のみに一致する。
したがって、x+$
は、
行末にある1文字以上のx
から成る文字列に一致する。
バッファのかわりに文字列と一致を取るときには、
$
は文字列の末尾や改行文字\n
のまえに一致する。
\
\
を含む)特別な文字をクォートする(意味を抑える)ことと、
特別な構成を導入することである。
\
は特別な文字をクォートするので、
\$
は文字$
だけに一致する正規表現、
\[
は文字[
だけに一致する正規表現、
といった具合になる。
\
にはLisp文字列の入力構文(see String Type)でも
特別な意味があり、\
でクォートする必要があることに注意してほしい。
たとえば、文字\
に一致する正規表現は\\
である。
文字群\\
を含むLisp文字列を書くには、各\
をクォートするために
\
が必要である。
したがって、\
に一致する正規表現の入力構文は"\\\\"
である。
注意:
従来との互換性のために、
特別な文字がそれらの特別な意味をなしえない文脈で使われた場合には、
普通の文字として扱われる。
たとえば、*foo
では、*
の対象となる正規表現が直前にないため、
*
は普通の文字として扱われる。
このようなふるまいに依存することはよいことではない。
特別な文字は書く位置に関係なくクォートするべきである。
多くの場合、任意の文字を伴う\
はその文字だけに一致します。
しかし、いくつか例外があって、
\
で始まる2文字列が特別な意味を持つ場合があります。
(2文字目にくる文字は、
単独で使った場合にはつねに普通の文字として扱われる。)
以下に\
の構成を示します。
\|
\|
をあいだに伴った2つの正規表現aとbは、
aかbのいずれかに一致する文字列に一致する正規表現となる。
したがって、foo\|bar
は、foo
やbar
に一致するが、
それ以外の文字列には一致しない。
\|
は、周囲にある適用しうる正規表現の中でも最大のものに適用される。
\|
によるグループ化を制限するのは、
これを囲む\( ... \)
によるグループ化だけである。
何度\|
を使っても処理できるだけの十分なバックトラック能力がある。
\( ... \)
\|
を括る。
したがって、\(foo\|bar\)x
は、
foox
かbarx
のいずれかに一致する。
*
、+
、?
を適用できるように、
複雑な正規表現を括る。
したがって、ba\(na\)*
は、
bananana
のように、(0個以上の)任意個の
文字列na
に一致する。
最後の使い方は、括弧によるグループ化という考え方から
派生したものではない。
同一の\( ... \)
構成に与えた2つめの別の機能である。
実用上、これら2つの意味が混同されることはないからである。
この機能をつぎに説明する。
\digit
\( ... \)
に一致したテキストと
同じテキストに一致する。
いいかえれば、一致を処理するときには、
\( ... \)
構成の末尾に達すると、
この構成に一致したテキストの始めと終りを記録する。
そして、正規表現のそれよりうしろでは、
『d番目に現れた\( ... \)
に一致したテキスト』という意味で
それがなんであろうと\
に続けて数字dを使える。
1つの正規表現内に現れる最初の9個の\( ... \)
に一致する文字列には、
正規表現中で開き括弧が現れた順に、1から9までの番号を割り振る。
そのため、\1
から\9
で、
対応する\( ... \)
に一致したテキストを参照できる。
たとえば、\(.*\)\1
は、改行を含まない文字列で、かつ、
前半と後半が同一である文字列に一致する。
\(.*\)
は前半部分に一致し、それはどのようなものでもかまわない。
一方、それに続く\1
は、
前半部分とまったく同じテキストに一致しなければならない。
\w
\W
\scode
w
は単語構成要素を、
-
は白文字を、(
は開き括弧を表すといった具合である。
白文字の構文を表すには、-
か空白のいずれかを使う。
構文コードとそれらを表す文字の一覧については、
see Syntax Class Table。
\Scode
つぎの正規表現は空の文字列に一致します。 つまりこれらは文字を使用しませんが、 これらが一致するかどうか文脈に依存します。
\`
\'
\=
\b
\bfoo\b
は、単語として独立して現れるfoo
に一致する。
\bballs?\b
は、単語として独立して現れる
ball
やballs
に一致する。
\b
は、
バッファの先頭や末尾にあるテキストとは無関係に、
バッファの先頭や末尾にも一致する。
\B
\<
\<
はバッファの先頭にも一致するが、単語構成文字が続く場合に限る。
\>
\>
はバッファの末尾にも一致するが、
単語構成文字で終了している場合に限る。
任意の文字列が正しい正規表現ではありません。
たとえば、([]]
のような少数の例外を除けば)
角括弧が対応していない文字列は正しくありませんし、
1つの\
で終る文字列も正しくありません。
不正な正規表現を探索関数に渡すと、
エラーinvalid-regexp
が通知されます。
regexp-quote string | Function |
この関数は、stringだけに正確に一致する正規表現の文字列を返す。
これにより、正規表現を必要とする関数を呼び出すときに
この文字列だけに正確に一致できる。
(regexp-quote "^The cat$") => "\\^The cat\\$"
(re-search-forward (concat "\\s-" (regexp-quote string) "\\s-")) |
regexp-opt strings &optional paren | Function |
この関数は、文字列stringsのいずれかに一致する
効率よい正規表現を返す。
これは、たとえばフォントロック(font-lock)モードなどで、
可能な限り高速な一致や探索を行う必要がある場合に有用である。
省略可能な引数parenが つぎの (defun regexp-opt (strings paren) (let ((open-paren (if paren "\\(" "")) (close-paren (if paren "\\)" ""))) (concat open-paren (mapconcat 'regexp-quote strings "\\|") close-paren))) |
regexp-opt-depth regexp | Function |
この関数は、varregexp内のグループ化構文(括弧で括った式)の 総個数を返す。 |
ここでは、任意個数の白文字を伴った文末を認識するために
Emacsで使われている複雑な正規表現について述べます。
それは変数sentence-end
の値です。
まず、タブ文字と空白を区別するためにLisp構文の文字列として
正規表現を示します。
文字列定数はダブルクォートで始まり終ります。
\"
は文字列の一部としてのダブルクォート、
\\
は文字列の一部としてのバックスラッシュ、
\t
はタブ、\n
は改行を表します。
"[.?!][]\"')}]*\\($\\| $\\|\t\\| \\)[ \t\n]*"
対照的に、変数sentence-end
を評価するとつぎのように
なっているはずです。
sentence-end => "[.?!][]\"')}]*\\($\\| $\\| \\| \\)[ ]*"
この出力では、タブと改行はそれ自身として現れています。
この正規表現には、連続してつぎのような4つの部分が含まれています。
[.?!]
[]\"')}]*
\"
は、文字列内のダブルクォートを表すLisp構文である。
最後の*
は、直前の正規表現(この場合は文字選択)を
0回以上繰り返すことを表す。
\\($\\| $\\|\t\\| \\)
[ \t\n]*
GNU Emacsでは、正規表現に一致するつぎの部分を
インクリメンタルにもそうでなくも探せます。
インクリメンタルサーチコマンドについては、
Regexp Searchを
参照してください。
ここでは、プログラムで有用な探索関数のみについて述べます。
基本的なものはre-search-forward
です。
これらの探索関数は、バッファがマルチバイトであれば 正規表現をマルチバイトに変換します。 バッファがユニバイトであれば、正規表現をユニバイトに変換します。 See Text Representations。
re-search-forward regexp &optional limit noerror repeat | コマンド |
この関数は、カレントバッファにおいて前方へ向けて
正規表現regexpに一致するテキストの文字列を探索する。
関数はregexpに一致しないテキストはすべて飛び越え、
みつけた一致箇所の末尾へポイントを置く。
ポイントの新たな値を返す。
limitが repeatを指定してあると(正の数であること)、 その回数だけ探索を繰り返す(一致箇所の末尾を新たな探索の開始位置とする)。 連続してこれらの探索に成功すると関数は成功し、 ポイントを移動してその新たな値を返す。 さもなければ探索は失敗である。 関数が失敗した場合の動作は、noerrorの値に依存する。
noerrorが つぎの例では、ポイントは始めは ---------- Buffer: foo ---------- I read "-!-The cat in the hat comes back" twice. ---------- Buffer: foo ---------- (re-search-forward "[a-z]+" nil t 5) => 27 ---------- Buffer: foo ---------- I read "The cat in the hat-!- comes back" twice. ---------- Buffer: foo ---------- |
re-search-backward regexp &optional limit noerror repeat | コマンド |
この関数は、カレントバッファにおいて後方へ向けて
正規表現regexpに一致するテキストの文字列を探索し、
みつけた一致箇所の先頭へポイントを置く。
この関数は
|
string-match regexp string &optional start | Function |
この関数は、文字列stringにおいて正規表現regexpに一致した
最初の箇所の添字を返す。
あるいは、一致がなければnil を返す。
startがnil 以外であると、
stringの指定した添字から探索を始める。
たとえばつぎのとおりである。 (string-match "quick" "The quick brown fox jumped quickly.") => 4 (string-match "quick" "The quick brown fox jumped quickly." 8) => 27 文字列の最初の文字の添字は0であり、 2番目の文字の添字は1であるといった具合になる。 この関数から戻ったあとでは、
一致箇所を越えた最初の文字の添字は (string-match "quick" "The quick brown fox jumped quickly." 8) => 27 (match-end 0) => 32 |
looking-at regexp | Function |
この関数は、カレントバッファ内のポイントの直後のテキストが
正規表現regexpに一致するかどうかを調べる。
ここで『直後』とは、開始位置は固定されていて、
ポイントのうしろの最初の文字で始まる場合にのみ探索は成功する。
結果は、一致すればt であり、さもなければnil である。
この関数はポイントを移動しないが、マッチデータを更新する。
つぎの例では、ポイントは ---------- Buffer: foo ---------- I read "-!-The cat in the hat comes back" twice. ---------- Buffer: foo ---------- (looking-at "The cat in the hat$") => t |
普通の正規表現関数は、\|
や反復構文を扱うために必要なときには
バックトラックしますが、これを行い続けるのは
なんらかの一致をみつけるまでです。
みつけてしまえば、それらは成功してみつけた最初の一致を報告します。
本節では、正規表現の一致に関するPOSIX規格で規定された 完全なバックトラックを行う代替の探索関数について述べます。 それらはすべての可能性を試し尽くしすべての一致箇所を探し終える までバックトラックを継続してます。 そのため、POSIXで要求されるとおりの最長の一致を報告できるのです。 これは動作がとても遅いですから、最長一致が本当に必要な場合に限って これらの関数を使ってください。
posix-search-forward regexp &optional limit noerror repeat | Function |
これはre-search-forward と同様であるが、
正規表現の一致に関するPOSIX規格で規定された完全なバックトラックを行う。
|
posix-search-backward regexp &optional limit noerror repeat | Function |
これはre-search-backward と同様であるが、
正規表現の一致に関するPOSIX規格で規定された完全なバックトラックを行う。
|
posix-looking-at regexp | Function |
これはlooking-at と同様であるが、
正規表現の一致に関するPOSIX規格で規定された完全なバックトラックを行う。
|
posix-string-match regexp string &optional start | Function |
これはstring-match と同様であるが、
正規表現の一致に関するPOSIX規格で規定された完全なバックトラックを行う。
|
perform-replace from-string replacements query-flag regexp-flag delimited-flag &optional repeat-count map | Function |
この関数は、query-replace と関連するコマンドの中身である。
from-stringの出現を探しだし、それらの一部やすべてを置き換える。
query-flagがnil であると、すべての出現を置換する。
さもなければ、1つ1つユーザーにどうするかを問い合わせる。
regexp-flagが 引数replacementsは、出現を置き換えるものを指定する。 それが文字列であれば、その文字列を使う。 文字列のリストでもよく、要素を巡回して使う。 repeat-countが 通常、キーマップ |
query-replace-map | Variable |
この変数は、y-or-n-p やmap-y-or-n-p に加えて、
query-replace や関連する関数に対する
正しいユーザー応答を定義する特別なキーマップを保持する。
2つの意味で普通のものではない。
|
query-replace-map
向けの意味のある『バインディング』をつぎに示します。
query-replace
と関連するものだけに意味のあるものもあります。
act
skip
exit
act-and-exit
act-and-show
automatic
backup
edit
delete-and-edit
recenter
quit
y-or-n-p
と関連する関数でのみ、この応答を用いる。
help
Emacsは、正規表現の探索中に捜し出したテキスト断片の開始/終了位置を 記録しています。 つまり、たとえば、rmailメッセージ内で日付のような複雑なパターンを 探索してから、パターンの制御をもとに一致した一部分を取り出せるのです。
マッチデータは、通常、もっとも最近に行った探索のみを記述するので、 あとで使用したい探索とそのマッチデータを使うあいだに、 不注意に別の探索を行わないように注意してください。 あいだで探索を行う必要がある場合には、その周りで マッチデータを保存/復元してそれらが上書きされないようにします。
この関数は、最後の探索で一致したテキストをreplacementで置換します。
replace-match replacement &optional fixedcase literal string subexp | Function |
この関数は、最後の探索で一致したバッファ内(あるいは文字列string)の
テキストを置換する。
当該テキストをreplacementで置き換える。
バッファで最後に探索を行った場合には、
stringに 文字列で探索した場合には、stringに同じ文字列を渡すこと。
そうすると、 fixedcaseが
literalが
subexpが |
本節では、最後の探索や一致操作において なにに一致したのかを調べるためのマッチデータの使い方を説明します。
一致したテキスト全体や正規表現の括弧で括った特定の部分式に一致した テキストを調べることができます。 以下の関数の引数countでどれかを指定します。 countがゼロであれば、一致全体を調べることになります。 countが正であれば、望みの部分式を指定します。
正規表現の部分式は、エスケープした括弧\(...\)
でグループ化した
式であることに注意してください。
count番目の部分式は、正規表現全体の先頭から
\(
の出現を数えてみつけます。
最初の部分式は1、つぎは2、といった具合です。
部分式は正規表現だけにあります。
単純な文字列探索のあとでは、利用可能な情報は一致全体に関するものだけです。
探索に失敗すると、マッチデータを変更することもしないこともあります。 過去には探索に失敗しても変更しなかったのですが、 将来そうなります。
match-string count &optional in-string | Function |
この関数は、最後の探索や一致操作で一致したテキストを文字列として返す。
countがゼロであるとテキスト全体を返す。
countが正であれば、count番目の括弧で囲んだ部分式に対応する
部分のみを返す。
countが範囲を越えていたり、当該部分式に一致するものがない場合には、
値はnil である。
最後の探索や一致操作を |
match-string-no-properties count | Function |
この関数はmatch-string と同様であるが、
結果にはテキスト属性を含まない。
|
match-beginning count | Function |
この関数は、最後の正規表現探索やその部分式に一致したテキストの開始位置を返す。
countがゼロであると、値は一致全体の開始位置である。 さもなければ、countは正規表現内の部分式を指定し、 関数の値は当該部分式に一致した部分の開始位置である。 一致に利用されなかった選択肢 |
match-end count | Function |
この関数は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
)であり、
最初の部分式の一致箇所の先頭は13番目の文字(c
)です。
(list (re-search-forward "The \\(cat \\)") (match-beginning 0) (match-beginning 1)) => (9 9 13) ---------- Buffer: foo ---------- I read "The cat -!-in the hat comes back" twice. ^ ^ 9 13 ---------- Buffer: foo ----------
(この例では、返される添字はバッファ内位置であり、 バッファの最初の文字を1と数える。)
関数match-data
とset-match-data
は、
マッチデータ全体を一度に読んだり書いたりします。
match-data | Function |
この関数は、最後の探索で一致したテキストに関するすべての情報を収めた
新たに構築したリストを返す。
要素0が式全体に一致した部分の先頭位置であり、
要素1が式全体に一致した部分の終了位置である。
つぎの2つの要素は最初の部分式に一致した部分の先頭/終了位置、
といった具合である。
一般に、要素
は(match-beginning n) に対応し、
要素
は(match-end n) に対応する。
バッファで行った一致ではすべての要素はマーカか 探索関数の呼び出しとその探索結果としてのマッチデータを参照するための
(match-data) => (#<marker at 9 in foo> #<marker at 17 in foo> #<marker at 13 in foo> #<marker at 17 in foo>) |
set-match-data match-list | Function |
この関数は、match-listの要素からマッチデータを設定する。
match-listは、以前にmatch-data の呼び出しで得たリストであること。
match-listが存在しないバッファを指していても、エラーにはならない。 無意味な情報をマッチデータに設定するが、害にはならない。
|
探索を行う可能性がある関数を呼び出す場合、 あとで使うためにそれ以前の探索によるマッチデータを保存したいときには、 当該関数の呼び出しの周りでマッチデータを保存し復元する必要があります。 つぎの例は、マッチデータを保存し損なった場合に生じる問題点を 示しています。
(re-search-forward "The \\(cat \\)")
=> 48
(foo) ; foo
はさらに
; 探索する
(match-end 0)
=> 61 ; 予期しない結果。48でない!
マッチデータの保存と復元はsave-match-data
で行えます。
save-match-data body... | Macro |
このマクロは、周りのマッチデータを保存し復元して、 bodyを実行する。 |
スペシャルフォームsave-match-data
の効果をまねるために
match-data
とともにset-match-data
を使うこともできます。
つぎのようにします。
(let ((data (match-data))) (unwind-protect ... ; もとのマッチデータを変更しても大丈夫 (set-match-data data)))
プロセスフィルタ関数(see Filter Functions)や プロセスの番兵(see Sentinels)を実行するときには、 Emacsは自動的にマッチデータを保存し復元します。
デフォルトでは、Emacsの探索は探索対象テキストの大文字小文字を区別しません。
FOO
を探す指定を行うと、
Foo
やfoo
にも一致するとみなします。
これは、正規表現にも適用されます。
したがって、[aB]
は、a
やA
やb
やB
に一致します。
この機能を望まないときには、
変数case-fold-search
にnil
を設定します。
すると、すべての文字は大文字小文字を保ってそのとおりに一致します。
これはバッファローカルな変数ですから、
変数を変更してもカレントバッファだけに影響します。
(see Intro to Buffer-Local。)
あるいは、default-case-fold-search
の値を変更します。
これは、case-fold-search
を書き変えていないバッファ向けの
デフォルト値です。
ユーザーレベルのインクリメンタルサーチ機能では、 大文字小文字の区別は異なった扱い方をします。 小英文字を与えるとその大文字にも一致しますが、 大英文字を与えると大文字のみに一致します。 しかし、これはLispコードで使用している探索関数には まったく関係ありません。
case-replace | User Option |
この変数は、置換関数が大文字小文字を保存するかどうかを決定する。
変数がnil であると、置換テキストをそのまま使うことを意味する。
nil 以外の値であると、置換対象のテキストに応じて
置換テキストの大文字小文字を変換することを意味する。
この変数が実際に効果を発揮するのは関数 |
case-fold-search | User Option |
このバッファローカルな変数は、
大文字小文字を区別して探索するかどうかを決定する。
変数がnil であると大文字小文字を区別する。
さもなければ大文字小文字を区別しない。
|
default-case-fold-search | Variable |
この変数の値は、case-fold-search を書き変えていないバッファ向けの
デフォルト値である。
これは(default-value 'case-fold-search) と同じである。
|
本節では、編集上の特定目的に用いられる正規表現を保持している 変数について述べます。
page-delimiter | Variable |
これは、ページを区切る行頭を記述した正規表現である。
デフォルト値は、"^\014" (つまり、"^^L" すなわち"^\C-l" )
である。
これはページ送り文字で始まる行に一致する。
|
つぎの2つの正規表現は、つねに行の先頭から一致が
始まると仮定してはいけません。
一致の開始位置を固定する^
を使うべきではありません。
ほとんどの場合、段落コマンドは行の先頭でのみ一致を検査しますから、
^
は不必要であることを意味します。
幅0以外の左端余白があると、段落コマンドは左端余白のうしろからの一致を
受け入れます。
そのような場合、^
は誤りです。
しかし、左端余白をけっして使わないモードならば、
^
は無害です。
paragraph-separate | Variable |
これは、段落を区切る行の始まりを認識するための正規表現である。
(これを変更したら、paragraph-start も変更すること。)
デフォルト値は"[ \t\f]*$" であり、
(左端余白に続く)空白やタブやページ送りだけから成る行に一致する。
|
paragraph-start | Variable |
これは、段落を始める行や区切る行の始まりを認識するための正規表現である。
デフォルト値は"[ \t\n\f]" であり、
(左端余白に続く)空白やタブやページ送りだけから成る行に一致する。
|
sentence-end | Variable |
これは、文末を記述する正規表現である。
(これに関わらず、段落の区切りも文末である。)
デフォルト値はつぎのとおりである。
"[.?!][]\"')}]*\\($\\| $\\|\t\\| \\)[ \t\n]*" これは、ピリオド、疑問符、感嘆符のいずれかのあとに 閉じ括弧文字が続き(なくてもよい)、 タブや空白や改行が続くことを意味する。 この正規表現の詳しい説明は、Regexp Exampleを参照。 |
構文テーブル(syntax table)は、 各文字の構文的なテキスト上の機能を指定します。 この情報は、構文解析関数や複雑な移動を行うコマンドなどが 単語やシンボルなどの構文要素がどこで始まりどこで終るかを調べるために使います。 現在の構文テーブルが、本章の関数に加えて、 単語単位の移動関数(see Word Motion)、 リスト単位の移動関数(see List Motion)の意味を制御します。
構文テーブルは文字テーブル(see Char-Tables)です。 cで添字付けられる要素は、コードがcである文字について記述します。 要素の値は、当該文字の構文上の機能を符号化したリストです。
構文テーブルは、テキスト内を動き回るためにのみ使われ、 EmacsのLispリーダはこれを使いません。 Emacs LispがLisp式を読むときには、組み込みの構文規則を使います。 (入力構文を再定義する方法を与えるLispシステムもあるが、 単純であるようにEacs Lispではこの機能を省くことにした。)
各バッファには独自のメジャーモードがあり、
各メジャーモードはさまざまな文字の構文クラスを独自に扱います。
たとえば、lispモードでは文字;
はコメントを始めますが、
Cモードでは文を終らせます。
このような多様性を扱うために、
Emacsは各バッファごとにローカルな構文テーブルを選びます。
典型的には、各メジャーモードに独自の構文テーブルがあり、
そのモードを使っているバッファに当該構文テーブルをインストールします。
この構文テーブルを変更すると、
同じモードのバッファだけでなく将来そのモードになったバッファでも
構文を変更してしまいます。
類似したモードでは1つの構文テーブルを共有することがあります。
構文テーブルの設定方法の例については、See Example Major Modes。
構文テーブルでは、標準の構文テーブルから文字のデータを継承し、 一方でその他の文字に独自の指定を行えます。 構文クラスの『継承』とは、 『標準の構文テーブルから当該文字の構文を引き継ぐ』ことです。 ある文字に対して標準の構文を変更すると、 それを継承するすべての構文テーブルに影響します。
syntax-table-p object | Function |
この関数は、objectが構文テーブルならばt を返す。
|
本節では、文字の構文を指定する構文クラスと構文フラグ、
それらを構文記述子(syntax descriptor)としてどのように
表現するかについて述べます。
構文記述子はLisp文字列であり、
望みの構文を指定するためにmodify-syntax-entry
に渡します。
構文テーブルは、各文字の構文クラスを指定します。 ある構文テーブルでの文字のクラスと 他の構文テーブルでの当該文字のクラスとのあいだにはなんの関係も必要ありません。
各クラスはニーモニック文字(指定子)で区別します。 ニーモニック文字は、 クラスを指定する必要があるときにクラス名として働きます。 通常、指定子の文字は当該クラスによく現れるものです。 しかしながら、指定子としての意味は不変で、その文字の現在の構文とは独立です。
構文記述子は、構文クラス、(括弧のクラスの場合にのみ使われる) 釣り合う文字、フラグを指定するLisp文字列です。 最初の文字は、構文クラスを指定する文字(指定子)です。 2番目の文字はその文字に釣り合う文字ですが、使用しない場合には空白です。 そのあとに望みのフラグが続きます。 釣り合う文字やフラグが必要なければ、文字1つだけで十分です。
たとえば、Cモードにおける文字*
の構文記述子は
. 23
(句読点、釣り合う文字なし、
コメント開始の2番目の文字、コメント終了の最初の文字)であり、
/
は. 14
(句読点、釣り合う文字なし、
コメント開始の最初の文字、コメント終了の2番目の文字)です。
以下の一覧は、構文クラス、そのクラスを表す文字(指定子)、 そのクラスの意味、その使用例です。
@w{白文字(whitespace character)} | 構文クラス |
白文字( か- で指定)は、
シンボルや単語を互いに区切る。
典型的には、白文字には他の構文上の意味はなく、
複数個の白文字は1つの白文字と構文的には等価である。
ほとんどすべてのメジャーモードでは、
空白、タブ、改行、ページ送りは白文字である。
|
@w{単語構成文字(word constituent)} | 構文クラス |
単語構成文字(w で指定)は普通の英単語の一部分であり、
典型的には、プログラムの変数やコマンド名に使われる。
すべての大英文字、小英文字、数字文字は、典型的には単語構成文字である。
|
@w{シンボル構成文字(symbol constituent)} | 構文クラス |
シンボル構成文字(_ で指定)は、
単語構成文字に加えて、変数やコマンド名に使われる追加の文字である。
たとえば、英単語の一部分ではないがシンボル名に使える特定の文字を指定
するために、Lispモードではシンボル構成文字クラスを使う。
このような文字は$&*+-_<> である。
標準のCでは、単語構成文字でなくてシンボルに使える唯一の文字は
下線(_ )である。
|
@w{句読点文字(punctuation character)} | 構文クラス |
句読点文字(. で指定)は、
英文の句読点として使われたり、
プログラム言語でシンボルを区切るために使われる文字である。
emacs-lispモードを含むほとんどのプログラム言語向けモードでは、
シンボル構成文字でも単語構成文字でもない少数の文字には別の用途があるため、
このクラスの文字はない。
|
@w{開き括弧文字(open parenthesis character)} | 構文クラス |
@w{閉じ括弧文字(close parenthesis character)} | 構文クラス |
開き/閉じ括弧文字は、文や式を囲む相異なる対として使われる文字である。
そのようなグループ化は、開き括弧文字で始まり閉じ括弧文字で終る。
各開き括弧文字は特定の閉じ括弧文字に対応し、その逆もいえる。
Emacsは、通常、閉じ括弧文字を挿入すると
対応する開き括弧文字を短時間指し示す。
see Blinking。
開き括弧文字クラスは 英文向けのテキスト(text)モードとCモードでは、
括弧の対は、 |
@w{文字列クォート(string quote)} | 構文クラス |
文字列クォート文字(" で指定)は、
LispやCを含む多くの言語で文字列定数を区切るために使われる。
同じ文字列クォート文字が文字列の最初と最後に現れる。
Emacsの構文解析機能では、文字列を1つの字句とみなす。 文字列内の文字の普通の構文的な意味は抑制される。 lisp向けのモードには文字列クォート文字が2つ、
ダブルクォート( 英文はプログラム言語ではないので、英文には文字列クォート文字はない。 英文でも引用符は用いるが、その内側の文字の普通の構文的な属性を 抑制したくないのである。 |
@w{エスケープ(escape)} | 構文クラス |
エスケープ文字(\ で指定)は、
Cの文字列や文字定数で使われるようなエスケープシーケンスを開始する。
CとLispでは、文字\ はこのクラスに属する。
(Cではこの文字は文字列の内側だけで使われるが、
Cモードでつねにこのように扱っても問題ないことがわかった。)
|
@w{文字クォート(character quote)} | 構文クラス |
文字クォート文字(/ で指定)は、
後続の1文字をクォートし、通常の構文上の意味を抑制する。
直後の1文字のみに影響するという点で、エスケープ文字と異なる。
このクラスは、TeXモードのバックスラッシュに使われる。 |
@w{対になった区切り(paired delimiter)} | 構文クラス |
対になった区切り文字($ )は文字列クォート文字と同様であるが、
区切り文字のあいだにある文字の構文上の属性を抑制しない点が異なる。
現在、対になった区切りはTeXモードのみで使い、
数学モードに出入りする$ である。
|
@w{式前置子(expression prefix)} | 構文クラス |
式前置演算子(' )は、式のまえに現れると
式の一部であるとみなされる構文上の演算子に使われる。
lisp向けのモードでは、(クォートする)アポストロフ' 、
(マクロで使う)コンマ, 、
(ある種のデータの入力構文に使われる)# の文字がそうである。
|
@w{コメント開始(comment starter)} | 構文クラス |
@w{コメント終了(comment ender)} | 構文クラス |
コメント開始文字とコメント終了文字は、
さまざまな言語でコメントを区切るために用いられる。
これらのクラスは、それぞれ、< と> で指定する。
英文にはコメント文字はない。
Lispでは、セミコロン( |
@w{継承(inherit)} | 構文クラス |
この構文クラスは特定の構文を指定しない。
標準の構文テーブルで当該文字の構文を探す指定である。
この構文クラスは@ で指定する。
|
@w{汎用コメント区切り(generic comment delimiter)} | 構文クラス |
汎用コメント区切り文字は、特別な種類のコメントを
始めて終える文字である。
任意の汎用コメント区切り文字は
任意の汎用コメント区切り文字に対応するが、
普通のコメント開始文字/コメント終了文字には対応しない。
汎用コメント区切り文字同士のみで対応する。
この構文クラスは、主にテキスト属性 |
@w{汎用文字列区切り(generic string delimiter)} | 構文クラス |
汎用文字列区切り文字は、文字列を始めて終える。
このクラスは文字列クォートクラスと異なり、
汎用文字列区切りは他の汎用文字列区切りに対応し、
普通の文字列クォート文字には対応しない。
この構文クラスは、主にテキスト属性 |
構文テーブルの各文字には、構文クラスに加えて、フラグも指定できます。
文字1
、2
、3
、4
、b
、p
で
表現される6つの可能なフラグがあります。
p
を除くすべてのフラグは、複数の文字から成るコメント区切りの記述に
使います。
数字フラグは、当該文字のクラスで表される構文上の属性に加えて、
コメント列の一部分でもあることを示します。
フラグはクラスや他のフラグとは独立であり、
Cモードの*
のような文字のためにあります。
Cモードの*
は、句読点文字であるとともに、
コメント開始列の2番目の文字/*
でもあり、
コメント終了列の最初の文字*/
でもあります。
文字cに対して可能なフラグとそれらの意味を以下に示します。
1
は、cが2文字のコメント開始列を始めることを意味する。
2
は、cがそのような列の2番目の文字であることを意味する。
3
は、cが2文字のコメント終了列を始めることを意味する。
4
は、cがそのような列の2番目の文字であることを意味する。
b
は、コメント区切りとしてのcが
もう1つの『b』形式のコメントに属することを意味する。
Emacsでは、任意の1つの構文テーブルで2つの形式のコメントを同時に扱える。 これはC++のためである。 コメント構文の各形式には、独自の開始列と独自の終了列がある。 各コメントはどちらか1つの形式である必要がある。 したがって、『b』形式のコメント開始列で始まるものは、 『b』形式のコメント終了列で終る必要がある。
2つのコメント開始列は同じ文字で始まる必要があり、2文字目のみが異なる。
『b』形式のコメント開始列の2番目の文字にフラグb
を付ける。
(1文字か2文字の)コメント終了列は、
その最初の文字にフラグb
が付いていると『b』形式に適用する。
さもなければ『a』形式に適用する。
C++向けの適切なコメント構文の設定はつぎのとおりである。
/
124b
*
23
>b
これは4つのコメント区切り列を定義する。
/*
*
にはフラグb
がないので、
これは『a』形式のコメント開始列である。
//
/
にはフラグb
があるので、
これは『b』形式のコメント開始列である。
*/
*
にはフラグb
がないので、
これは『a』形式のコメント終了列である。
b
があるので、
これは『b』形式のコメント終了列である。
p
は、Lisp構文向けの追加の『前置文字』を示す。
これらの文字は式のあいだに現れるときには白文字として扱う。
式の内側に現れると、それらの通常の構文コードに従って扱われる。
関数backward-prefix-chars
は後方へ向けて移動するときには、
構文クラスが式前置子('
)である文字に加えて
これらの文字も飛び越す。
see Motion and Syntax。
本節では、構文テーブルを作成/参照/変更するための関数について述べます。
make-syntax-table | Function |
この関数は、新たな構文テーブルを作成する。
英文字やコントロール文字の構文は標準の構文テーブルから継承する。
他の文字の構文は標準の構文テーブルからコピーする。
ほとんどのメジャーモードの構文テーブルはこのように作成する。 |
copy-syntax-table &optional table | Function |
この関数は、構文テーブルtableのコピーを作成しそれを返す。
tableを指定しないと(あるいはnil )、
現在の構文テーブルのコピーを返す。
tableが構文テーブルでないとエラーを通知する。
|
modify-syntax-entry char syntax-descriptor &optional table | コマンド |
この関数は、文字charの構文指定を
構文記述子syntax-descriptorとする。
構文テーブルtableにおいてのみ構文を変更し、
他の構文テーブルは変更しない。
tableのデフォルトはカレントバッファの構文テーブルである。
syntax-descriptorで望みの構文を指定する。
これは、クラス指定子で始まり、
必要に応じて釣り合う文字とフラグを含む文字列である。
see Syntax Descriptors。
この関数はつねに 構文記述子の最初の文字が12個の構文クラス指定子の1つでないとエラーを通知する。 charが文字でなくてもエラーを通知する。
|
char-syntax character | Function |
この関数は、文字characterの構文クラスを指定子で表したもので返す。
これは構文クラスのみを返し、釣り合う文字や構文フラグは返さない。
charが文字でないとエラーを通知する。 つぎの例はCモードにあてはまる。
最初の例は、空白の構文クラスが(空白で表現される)白文字であることを示す。
2番目の例は、 (string (char-syntax ?\ )) => " " (string (char-syntax ?/)) => "." (string (char-syntax ?\()) => "(" ここでは、 |
set-syntax-table table | Function |
この関数は、tableをカレントバッファの構文テーブルにする。 tableを返す。 |
syntax-table | Function |
この関数は、現在の構文テーブル、つまり、 カレントバッファの構文テーブルを返す。 |
言語の構文を指定するに十分なほど構文テーブルに柔軟性がないときには、
バッファ内の特定の文字の出現に対して構文テーブルに優先する
テキスト属性syntax-table
を指定できます。
See Text Properties。
テキスト属性syntax-table
の正しい値はつぎのとおりです。
(syntax-code . matching-char)
nil
nil
であると、通常どおり、
現在の構文テーブルから文字の構文を判定する。
parse-sexp-lookup-properties | Variable |
これがnil 以外であると、
構文を解析する関数は、テキスト属性による構文指定に注意を払う。
さもなければ、現在の構文テーブルのみを用いる。
|
本節では、特定の構文クラスを持つ文字を越えて移動するための 関数について述べます。
skip-syntax-forward syntaxes &optional limit | Function |
この関数は、syntaxesで指定される構文クラスを持つ文字を越えて ポイントを前方へ向けて移動する。 バッファの末尾、(指定されていれば)limitの位置、 飛び越さない文字のいずれかに出会うと停止する。 戻り値は移動距離であり非負整数である。 |
skip-syntax-backward syntaxes &optional limit | Function |
この関数は、syntaxesで指定される構文クラスである文字を越えて
ポイントを後方へ向けて移動する。
バッファの先頭、(指定されていれば)limitの位置、
飛び越さない文字のいずれかに出会うと停止する。
戻り値は移動距離である。 それはゼロか負の整数である。 |
backward-prefix-chars | Function |
この関数は、式前置子構文の文字を飛び越えてポイントを後方へ向けて移動する。
式前置子クラスやフラグp を持つ文字を飛び越す。
|
ここでは、括弧が対になっているS式(sexp)とも呼ばれる 釣り合った式を解析したり走査する関数について述べます。 構文テーブルで文字の解釈を制御することで、 LispモードではLispの式に対して、CモードではCの式に対して これらの関数を用いることができます。 釣り合った式を飛び越えて移動するための便利な上位レベルの関数については、 See List Motion。
parse-partial-sexp start limit &optional target-depth stop-before state stop-comment | Function |
この関数は、カレントバッファのstartから始まるS式を解析するが、
limitを越えては走査しない。
位置limitで止まるか、
以下に述べる条件が満たされると解析を停止し、当該箇所にポイントを置く。
ポイントを置いた箇所での解析状況を表す値を返す。
stateが 3番目の引数target-depthが 4番目の引数stop-beforeが 5番目の引数stateは9要素のリストであり、
以下に述べるようにこの関数の値と同じ形である。
(9番目の最後の要素は省いてもよい。)
結果は、解析の最終状態を記述した9要素のリストである。
引数stateでは、要素0、3、4、5、7は重要である。 この関数は、入れ子にあった括弧を持つ言語向けに 字下げを計算するためにしばしば用いられる。 |
scan-lists from count depth | Function |
この関数は、位置fromから前方へ向けてcount個の
釣り合った括弧のグループを走査する。
走査を停止した位置を返す。
countが負であると、後方へ向けて走査する。
depthが0以外であると、括弧の深さをその値から数え始める。
停止箇所の候補位置は、括弧の深さが0になる箇所である。
走査がバッファ(あるいはその参照可能部分)の先頭や末尾に達し、
深さが0でないと、エラーを通知する。
深さは0であるが指定個数だけ数えてない場合には、 |
scan-sexps from count | Function |
この関数は、位置fromから前方へ向けてcount個のS式を走査する。
走査を終えた位置を返す。
countが負であると、後方へ向けて移動する。
走査が括弧によるグループの途中で
バッファ(あるいはその参照可能部分)の先頭や末尾に達すると、
エラーを通知する。
指定個数だけ数えるまえに括弧によるグループのあいだで
先頭や末尾に達した場合は |
parse-sexp-ignore-comments | Variable |
値がnil 以外であると、
本節の関数やforward-sexp は、コメントを白文字として扱う。
Emacsの古い版では、コメントの終了が |
forward-comment
を使うと、
1つのコメントや複数のコメントを飛び越えて前後に移動できます。
forward-comment count | Function |
この関数は、ポイントを前方へ向けて(countが負ならば後方へ向けて) count個のコメントを飛び越えて移動する。 コメントか白文字以外のものに出会うと停止し、当該箇所にポイントを置く。 count個だけ数えたあとにももちろん停止する。 |
ポイントに続くすべてのコメントと白文字を飛び越えるには、
(forward-comment (buffer-size))
を使います。
バッファ内のコメントの個数は(buffer-size)
を越えるはずがないので、
引数に使うには(buffer-size)
はよいものです。
Emacsのほとんどのメジャーモードにはそれ独自の構文テーブルがあります。 それらのいくつかをつぎに示します。
standard-syntax-table | Function |
この関数は、基本(fundamental)モードで使用する構文テーブルである 標準の構文テーブルを返す。 |
text-mode-syntax-table | Variable |
この変数の値は、テキスト(text)モードで使用する構文テーブルである。 |
c-mode-syntax-table | Variable |
この変数の値は、Cモードのバッファ向けの構文テーブルである。 |
emacs-lisp-mode-syntax-table | Variable |
この変数の値は、編集コマンドがemacs-lispモードで使用する構文テーブルである。
(これはLispの関数read にはなんの効果もない。)
|
Lispプログラムでは普通は構文テーブルの要素を直接には操作しません。 Lispレベルの構文テーブル関数は、 普通は構文記述子(see Syntax Descriptors)を操作します。 ですが、内部形式を明文化しておきます。
構文テーブルの各要素は、(syntax-code . matching-char)
の
形のコンスセルです。
CARのsyntax-codeは、構文クラスと構文フラグを符号化する整数です。
釣り合う文字を指定してあると、
CDRのmatching-charはnil
以外です。
つぎの表は、各構文クラスに対応するsyntax-codeの値です。
整数 クラス | 整数 クラス |
整数 クラス
| |
0 whitespace | 5 close parenthesis |
10 character quote
| |
白文字 | 閉じ括弧 |
文字クォート
| |
1 punctuation | 6 expression prefix |
11 comment-start
| |
句読点 | 式前置子 |
コメント開始
| |
2 word | 7 string quote |
12 comment-end
| |
単語 | 文字列クォート |
コメント終了
| |
3 symbol | 8 paired delimiter |
13 inherit
| |
シンボル | 対になった区切り |
継承
| |
4 open parenthesis | 9 escape |
14 comment-fence
| |
開き括弧 | エスケープ |
コメント区切り
| |
15 string-fence
| |||
文字列区切り
|
たとえば、(
の普通の構文値は、(4 . 41)
です。
(41は)
の文字コード。)
フラグは、最下位ビットから16番目のビットから始まる上位ビットに符号化します。 つぎの表は、各構文フラグとそれに対応する2の巾です。
フラグ 2の巾 | フラグ 2の巾 |
フラグ 2の巾
| |
1 (lsh 1 16)
|
3 (lsh 1 18)
|
p (lsh 1 20)
| |
2 (lsh 1 17)
|
4 (lsh 1 19)
|
b (lsh 1 21)
|
カテゴリ(category)は、文字を構文的に分類する別の方法です。 必要に応じて複数のカテゴリを定義できて、 そうすると各文字に1つか複数のカテゴリを独立に設定できます。 構文クラスと異なり、カテゴリは互いに排他的ではありません。 1つの文字が複数のカテゴリに属することは普通にあります。
各バッファにはカテゴリテーブル(category table)があり、 どのカテゴリが定義済みでどの文字がどのカテゴリに属するかを記録しています。 各カテゴリテーブルはそれ独自のカテゴリ群を定義しますが、 それらは標準のカテゴリテーブルをコピーして普通は初期化されます。 そのため、すべてのモードで標準のカテゴリを使えます。
各カテゴリには名前があり、それは
から~
までの
範囲のASCII印字文字です。
define-category
でカテゴリを定義するときにその名前を指定します。
カテゴリテーブルは実際には文字テーブル(see Char-Tables)です。
カテゴリテーブルの添字cの要素は、
カテゴリ集合(category set)です。
これはブールベクトルであり、文字cが属するカテゴリ群を表します。
このカテゴリ集合において、添字catの要素がt
であると、
catは集合の要素であることを意味し、
当該文字cはカテゴリcatに属することを意味します。
define-category char docstring &optional table | Function |
この関数は、名前をchar、説明文字列をdocstringとして
新たなカテゴリを定義する。
新たなカテゴリは、カテゴリテーブルtableに対して定義される。 tableのデフォルトは、カレントバッファのカテゴリテーブルである。 |
category-docstring category &optional table | Function |
この関数は、カテゴリテーブルtableのカテゴリcategoryの
説明文字列を返す。
(category-docstring ?a) => "ASCII" (category-docstring ?l) => "Latin" |
get-unused-category table | Function |
この関数は、カテゴリテーブルtableで現在定義されていない
新たなカテゴリ名(文字)を返す。
tableにおいて可能なすべてのカテゴリが使用済みであるとnil を返す。
|
category-table | Function |
この関数は、カレントバッファのカテゴリテーブルを返す。 |
category-table-p object | Function |
この関数は、objectがカテゴリテーブルであるとt を返し、
さもなければnil を返す。
|
standard-category-table | Function |
この関数は、標準のカテゴリテーブルを返す。 |
copy-category-table &optional table | Function |
この関数は、カテゴリテーブルtableのコピーを作成しそれを返す。
tableを指定しない(あるいはnil )と、
現在のカテゴリテーブルのコピーを返す。
tableがカテゴリテーブルでないとエラーを通知する。
|
set-category-table table | Function |
この関数は、カレントバッファのカテゴリテーブルをtableとする。 tableを返す。 |
make-category-set categories | Function |
この関数は、新たなカテゴリ集合、つまり、
文字列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" |
char-category-set char | Function |
この関数は、文字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" |
category-set-mnemonics category-set | Function |
この関数は、カテゴリ集合category-setを
この集合に属するすべてのカテゴリの名前からなる文字列に変換する。
(category-set-mnemonics (char-category-set ?a)) => "al" |
modify-category-entry character category &optional table reset | Function |
この関数は、カテゴリテーブルtable(デフォルトはカレントバッファの
カテゴリテーブル)内の文字characterのカテゴリ集合を変更する。
普通、カテゴリ集合にcategoryを追加して変更する。
しかし、resetが |
略語(abbrev)とは、より長い文字列へ展開される文字の列のことです。 ユーザーが略語の文字列を挿入すると、その展開形に自動的に置換されます。 これにより打鍵量を省けます。
現在有効な略語の集まりは、略語表(abbrev table)に記録されています。 各バッファにはローカルな略語表がありますが、 通常、同じメジャーモードのすべてのバッファは1つの略語表を共有します。 グローバルな略語表もあります。 通常、両方を使います。
略語表は、各略語に対するシンボルを収めたオブジェクト配列として表現されます。 シンボルの名前が略語です。 その値は展開形であり、その関数定義は展開を行うフック関数です。 その属性リストのセルには略語を展開した回数である利用回数が入ります。 それらのシンボルは、通常のオブジェクト配列にはインターンされませんから、 Lisp式を読み取った結果には、それらはけっして現れません。 実際、略語を扱うコード以外では、それらはけっして使われません。 したがって、それらをかなり非標準的に使っても安全です。 See Creating Symbols。
ユーザーレベルの略語コマンドについては、 Abbrevsを参照してください。
略語(abbrev)モードは、変数abbrev-mode
の値で制御される
マイナモードです。
abbrev-mode | Variable |
この変数の値がnil 以外であると、
バッファに略語が挿入されると自動的に展開するようになる。
値がnil であると、略語を定義することはできるが、
自動的には展開されない。
この変数は設定されると自動的にバッファローカルになる。 |
default-abbrev-mode | Variable |
これは、abbrev-mode を上書きしていないバッファ向けの
abbrev-mode の値である。
これは(default-value 'abbrev-mode) と同じである。
|
本節では、略語表の作成方法と扱い方について述べます。
make-abbrev-table | Function |
この関数は、新たな空の略語表、つまり、 シンボルを含まないオブジェクト配列を作成して返す。 ベクトルはゼロで埋められる。 |
clear-abbrev-table table | Function |
この関数は、略語表table内のすべての略語を未定義にして略語表を空にする。
関数はnil を返す。
|
define-abbrev-table tabname definitions | Function |
この関数は、tabname(シンボル)を略語表の名前として定義する。
つまり、この変数としての値は略語表になる。
definitionsに従って略語表に略語を定義する。
ここで、definitionsは
(abbrevname expansion hook usecount) の形の
要素から成るリストである。
戻り値はつねにnil である。
|
abbrev-table-name-list | Variable |
その値が略語表であるシンボルのリストである。
define-abbrev-table は、新たな略語表の名前をこのリストに追加する。
|
insert-abbrev-table-description name &optional human | Function |
この関数は、nameで指名される略語表の記述をポイントのまえに挿入する。
引数nameは、その値が略語表であるシンボルである。
戻り値はつねにnil である。
humanが |
これらの関数は、指定した略語表に略語を定義します。
define-abbrev
は下位レベルの基本的な関数ですが、
add-abbrev
はユーザーに情報を問い合わせるコマンドが使います。
add-abbrev table type arg | Function |
この関数は、ユーザーからの情報に基づいて
略語表tableに略語を追加する。
引数typeは、この略語の種類を英語で表した文字列である
(典型的には、"global" や"mode-specific" 。)
この文字列はユーザーへのプロンプトに使われる。
引数argは、展開形の単語数である。
戻り値は、新たな略語を内部的に表現するシンボルであるか、
既存の略語を再定義することをユーザーが拒否したときには |
define-abbrev table name expansion hook | Function |
この関数は、略語表tableにおいて、
略語nameをexpansionに展開するように定義し、
hookを呼び出すように定義する。
戻り値は、Emacs内部で略語を表現するシンボルを返すが、
その名前はnameである。
引数nameは文字列であること。
引数expansionは、普通は、目的の展開形(文字列)であるが、
略語を未定義にするには 引数hookは、関数か 略語の利用回数は0に初期化される。 |
only-global-abbrevs | User Option |
この変数がnil 以外であると、
ユーザーはグローバルな略語だけを使う意図があることを表す。
モード固有の略語を定義するコマンドに対して、
グローバルな略語を定義するように指示する。
この変数は本節の関数のふるまいを変えることはないが、
それらを呼び出す側でこの変数を検査している。
|
略語定義を保存したファイルは、実際には、Lispコードのファイルです。
略語は、同じ内容の同じ略語表を定義するLispプログラムの形で保存されます。
したがって、ファイルはload
(see How Programs Do Loading)で
ロードできます。
しかし、関数quietly-read-abbrev-file
がより便利なインターフェイスを
提供します。
save-some-buffers
などのユーザーレベルの機能では、
ここに述べた変数の制御のもとで、略語をファイルに自動的に保存できます。
abbrev-file-name | User Option |
これは、略語を読み込んだり保存するデフォルトのファイル名である。 |
quietly-read-abbrev-file filename | Function |
この関数は、write-abbrev-file で書いておいた
ファイルfilenameから、略語定義を読み取る。
filenameがnil であると、
abbrev-file-name で指定されるファイルを使う。
save-abbrevs にt を設定して、変更は保存されるようにする。
この関数はいっさいメッセージを表示しない。
|
save-abbrevs | User Option |
save-abbrev がnil 以外の値であると、
Emacsはファイルを保存するときに略語も保存する。
abbrev-file-name が略語を保存するファイルを指定する。
|
abbrevs-changed | Variable |
略語を定義したり変更すると、この変数はnil 以外に設定される。
これは、読者の略語を保存する機会を与えるために、
Emacsのさまざまなコマンドに対するフラグとして働く。
|
write-abbrev-file filename | コマンド |
ロードすると同じ略語を定義するようなLispプログラムの形で、
ファイルfilenameにすべての略語表のすべての略語定義を保存する。
この関数はnil を返す。
|
通常、略語は、self-insert-command
を含む特定の対話的なコマンドに
よって展開されます。
本節では、データのやりとりに使う変数に加えて、そのようなコマンドを書くために
使用するサブルーティンについて述べます。
abbrev-symbol abbrev &optional table | Function |
この関数は、名前abbrevの略語を表すシンボルを返す。
そのような略語が定義されていなければ、戻り値はnil である。
省略可能な第2引数tableは、探索対象の略語表である。
tableがnil であると、
この関数は、まずカレントバッファのローカルな略語表を試し、
つぎにグローバルな略語表を試す。
|
abbrev-expansion abbrev &optional table | Function |
この関数は、abbrevが
(カレントバッファで使用される略語表での定義どおりに)
展開されるであろう文字列を返す。
省略可能な引数tableは、abbrev-symbol と同様に、
使用する略語表を指定する。
|
expand-abbrev | コマンド |
このコマンドは、ポイントのまえの略語をあれば展開する。
略語の直後にポイントがない場合、このコマンドはなにもしない。
このコマンドは、展開を行えばt を返し、
さもなければnil を返す。
|
abbrev-prefix-mark &optional arg | コマンド |
現在のポイント位置を略語の開始位置としてマークする。
つぎにexpand-abbrev を呼び出すと、
通常どおりにポイントのまえの単語を使うかわりに、
ここから(その時点での)ポイントまでのテキストを略語として展開する。
|
abbrev-all-caps | User Option |
これがnil 以外であると、
大文字だけで入力された略語を大文字だけで展開する。
さもなければ、大文字だけで入力された略語は、
展開形の各単語を大文字で始めるように展開される。
|
abbrev-start-location | Variable |
これは、expand-abbrev がつぎに展開する略語の開始位置として使う
バッファ内位置である。
(nil であると、そのかわりにポイントのまえの単語を使う意味である。)
expand-abbrev が呼び出されるたびに、
abbrev-start-location はnil に設定される。
この変数は、abbrev-prefix-mark でも設定される。
|
abbrev-start-location-buffer | Variable |
この変数の値は、abbrev-start-location が設定されたバッファである。
別のバッファで略語を展開しようとするとabbrev-start-location は
クリアされる。
この変数はabbrev-prefix-mark が設定する。
|
last-abbrev | Variable |
これは、もっとも最近に略語展開されたabbrev-symbol
(略語を表すシンボル)である。
この情報は、コマンドunexpand-abbrev 向けに
expand-abbrev が残す
(see Expanding Abbrevs)
。
|
last-abbrev-location | Variable |
これは、もっとも最近に略語展開した箇所である。
これは、コマンドunexpand-abbrev 向けに
expand-abbrev が残した情報を保持する。
|
last-abbrev-text | Variable |
これは、もっとも最近に略語展開したときの(あれば)大文字小文字変換後の
展開形のテキストである。
略語展開を取り消すと、この値はnil である。
これは、コマンドunexpand-abbrev 向けに
expand-abbrev が残した情報を保持する。
|
pre-abbrev-expand-hook | Variable |
これは、任意の略語を展開する直前に順に実行される関数を 収めたノーマルフックである。 see Hooks。 ノーマルフックなので、フック関数は引数を受け取らない。 しかし、バッファでポイントのまえを調べることで 展開すべき略語をみつけることができる。 |
以下のコード例は、pre-abbrev-expand-hook
の使い方を示します。
ユーザーが略語を句読点文字で終えると、フック関数が確認を求めます。
したがって、このフックにより、ユーザーは展開の可否を決定でき、
了承しなかったときには展開を止められます。
(add-hook 'pre-abbrev-expand-hook 'query-if-not-space) ;; この関数は、pre-abbrev-expand-hook
が起動する ;; ユーザーが略語を空白で終えると、この関数はなにもしない ;; (つまり、略語を展開できるように戻る) ;; ユーザーがその他の文字を入力したら、 ;; この関数は展開するかどうかを問い合わせる ;; ユーザーがプロンプトにyで答えたら、 ;; (関数not
を使っているので)この関数はnil
を返すが ;; 問題ない。戻り値は展開には影響しない (defun query-if-not-space () (if (/= ?\ (preceding-char)) (if (not (y-or-n-p "Do you want to expand this abbrev? ")) (error "Not expanding this abbrev"))))
Emacsにあらかじめロードされるメジャーモード向けの 略語表を保持する変数一覧を示します。
global-abbrev-table | Variable |
これは、モードに依存しない略語向けの略語表である。 これに定義された略語は、すべてのバッファに適用される。 各バッファにはローカルな略語表もあり、 それらの略語定義はグローバルな略語表の略語定義に優先する。 |
local-abbrev-table | Variable |
このバッファローカルな変数の値は カレントバッファの(モード固有の)略語表である。 |
fundamental-mode-abbrev-table | Variable |
これは、基本(fundamental)モードで使われるローカルな略語表である。 いいかえれば、基本(fundamental)モードであるすべてのバッファの ローカルな略語表である。 |
text-mode-abbrev-table | Variable |
これは、テキスト(text)モードで使われるローカルな略語表である。 |
lisp-mode-abbrev-table | Variable |
これは、lispモードとemacs-lispモードで使われるローカルな略語表である。 |
オペレーティングシステムの用語では、 プロセス(process)とは、プログラムを実行する空間のことです。 Emacsはプロセスとして動いています。 Emacs Lispのプログラムでは、 独自のプロセスとして他のプログラムを起動できます。 それらは、Emacsプロセスのサブプロセス(subprocess)とか 子プロセス(child process)と呼ばれ、 Emacsプロセスはそれらの親プロセス(parent process)です。
Emacsのサブプロセスは、それを作成する方法に依存して、 同期(synchronous)であるか非同期(asynchronous)です。 同期サブプロセスを作成すると、 Lispプログラムは実行を継続するまえにそのサブプロセスの終了を待ちます。 非同期サブプロセスを作成すると、それはLispプログラムと並行して動作します。 この種のサブプロセスは、Emacs内部ではやはり『プロセス』と呼ばれる Lispオブジェクトで表現されます。 Lispプログラムはこのオブジェクトを用いて サブプロセスと通信したりそれを制御できます。 たとえば、シグナルを送ったり、状態情報を取得したり、 プロセスからの出力を受け取ったり、プロセスへ入力を送れます。
processp object | Function |
この関数は、objectがプロセスであればt を返し、
さもなければnil を返す。
|
プログラムを実行するために新たなサブプロセスを作る関数が3つあります。
その1つstart-process
は、非同期プロセスを作成して
プロセスオブジェクトを返します(see Asynchronous Processes)。
残りの2つ、call-process
とcall-process-region
は
同期プロセスを作成しますが、プロセスオブジェクトは返しません
(see Synchronous Processes)。
同期/非同期プロセスについては以下の節に述べます。 3つの関数の呼び出し方は類似しているので、 ここではそれらに共通な引数について述べます。
いずれの場合でも、関数の引数programは、
実行すべきプログラムを指定します。
そのファイルがみつからなかったり実行できないと、
エラーを通知します。
ファイル名が相対名であると、
変数exec-path
は探索すべきディレクトリのリストを保持しています。
Emacsは起動時に環境変数PATH
の値に基づいてexec-path
を
初期化します。
~
、.
、..
のファイル名の標準的な書き方は、
exec-path
でも普通どおりに解釈されますが、
($HOME
などの)環境変数の置換は認識しません。
それにはsubstitute-in-file-name
を使います
(see File Name Expansion)。
サブプロセスを作成する各関数には、
プログラムの標準出力の受け取り場所を指定する
引数buffer-or-nameがあります。
これはバッファかバッファ名である必要があります。
バッファ名であると、そのバッファが既存でなければ新たに作成します。
nil
でもかまいませんが、その場合、
フィルタ関数で処理しない限り出力を破棄します。
(Filter Functionsとsee Read and Print)。
通常、複数のプロセスの出力を同じバッファへは送らないようにします。
それらの出力がでたらめに混ざってしまうからです。
サブプロセスを作成する3つの関数すべてに、
&rest
引数であるargsがあります。
argsはすべてが文字列である必要があり、
それぞれを区切ってコマンド行引数としてprogramに与えられます。
引数全体を指定されたプログラムへ直接渡すため、
これらの引数ではワイルドカード文字や他のシェル構文の特別な意味はありません。
注意:
引数programにはプログラムの名前だけを指定し、
コマンド行引数はいっさい指定しない。
コマンド行引数はargsで与えること。
サブプロセスのカレントディレクトリは
default-directory
の値で決まります(see File Name Expansion)。
サブプロセスはEmacsから環境変数を継承しますが、
優先するものをprocess-environment
で指定できます。
See System Environment。
exec-directory | Variable |
この変数の値は、Emaccsが起動することを意図した
GNU Emacsとともに配布されたプログラム群を収めたディレクトリ名
(文字列)である。
プログラムmovemail はそのようなプログラムの例であり、
inboxから新たなメイルを取り出すためにrmailが利用する。
|
exec-path | User Option |
この変数の値は、サブプロセスで実行するプログラムを探索する
ディレクトリのリストである。
各要素はディレクトリ名(文字列)であるか、
デフォルトディレクトリ(つまりdefault-directory の値)
を意味するnil である。
引数programが絶対ファイル名でないと、
|
Lispプログラムから、
ユーザーが指定したファイル名を含んだコマンドを指定して
シェルを実行する必要がときどきあります。
これらのプログラムでは、任意の正しいファイル名を扱える必要があります。
しかし、シェルは、特定の文字がファイル名として現れると特別に扱うので、
そのような文字がシェルに混乱をもたらします。
そのような文字を扱うには、関数shell-quote-argument
を使います。
shell-quote-argument argument | Function |
この関数は、argumentを実際の内容とする
シェル構文で表した引数を文字列で返す。
この戻り値をシェルコマンドに連結し、
実行のためにシェルに渡しても問題を生じないはずである。
この関数が行うことの詳細は読者のオペレーティングシステムに依存する。 この関数は通常のシェル構文に合うように設計してある。 非標準のシェルを使う場合には、この関数を再定義する必要があろう。 MS-DOSでは、この関数はargumentを無変更で返す。 MS-DOSのシェルにはクォートの機能がないため、 これは本当は正しいことではないが最良のことである。 ;; つぎの例はGNUとUNIXシステムのふるまいである (shell-quote-argument "foo > bar") => "foo\\ \\>\\ bar" シェルコマンドを作る (concat "diff -c " (shell-quote-argument oldfile) " " (shell-quote-argument newfile)) |
同期プロセス(synchronous process)を作成すると、
Emacsは実行を続行するまえにそのプロセスが終了するのを待ちます。
diredはその例です。
ls
を同期プロセスで実行し、その出力を少々修正します。
プロセスは同期なので、Emacsがなにかを行おうとするまえに
ディレクトリ一覧全部がバッファに届きます。
Emacsは同期サブプロセスの終了を待ちますが、
ユーザーはC-gと打って中断できます。
C-gはまずシグナルSIGINT
でサブプロセスをキルしようとしますが、
中断を完了するまえにサブプロセスが終了するのを待ちます。
その期間にユーザーがさらにC-gを打つと、
SIGKILL
でサブプロセスを即座にキルし、ただちに中断を完了します。
See Quitting。
同期サブプロセス作成関数は、 そのプロセスがどのように終了したかを表すものを返します。
同期サブプロセスからの出力は、ファイルから読むテキストと同様に、
コーディングシステムを用いて一般には復号化します。
call-process-region
がサブプロセスへ送る入力は、
ファイルへ書くテキストと同様に、
コーディングシステムを用いて符号化します。
See Coding Systems。
call-process program &optional infile destination display &rest args | Function |
この関数は、別のプロセスでprogramを呼び出し、
それが終了するのを待つ。
infileが
displayが 残りの引数argsは、プログラムに対する コマンド行引数を指定する文字列である。 (待たないように指示しない限り) つぎの例では、バッファ (call-process "pwd" nil t) => nil ---------- Buffer: foo ---------- /usr/user/lewis/manual ---------- Buffer: foo ---------- (call-process "grep" nil "bar" nil "lewis" "/etc/passwd") => nil ---------- Buffer: bar ---------- lewis:5LTsHm66CSWKg:398:21:Bil Lewis:/user/lewis:/bin/csh ---------- Buffer: bar ----------
(call-process insert-directory-program nil t nil switches (if full-directory-p (concat (file-name-as-directory file) ".") file)) |
call-process-region start end program &optional delete destination display &rest args | Function |
この関数は、programを動かすプロセスの標準入力として
startとendのあいだのテキストを送る。
deleteがnil 以外であると、送ったテキストを削除する。
これは、カレントバッファに送った入力のかわりに出力を挿入することを
意味するdestinationがt であるときに有用である。
引数destinationとdisplayは、
サブプロセスからの出力をどのように扱い、
出力か到着するたびに表示を更新するかどうかを制御する。
詳しくは、上記の 残りの引数argsは、プログラムに対する コマンド行引数を指定する文字列である。
つぎの例では、
バッファ ---------- Buffer: foo ---------- input-!- ---------- Buffer: foo ---------- (call-process-region 1 6 "cat" nil t) => nil ---------- Buffer: foo ---------- inputinput-!- ---------- Buffer: foo ---------- コマンド (call-process-region
start end
shell-file-name ; プログラムの名前
nil ; リージョンを削除しない
buffer ; 出力は
|
shell-command-to-string command | Function |
この関数は、シェルコマンドとしてcommand(文字列)を実行し、 コマンドの出力を文字列として返す。 |
非同期プロセスを作成すると、Emacsとサブプロセスの両者は ただちに動作を継続します。 そしてプロセスはEmacsと並行に動作し、 両者は以下の節に述べる関数を用いて互いに通信できます。 しかし、通信は部分的に非同期です。 特定の関数を呼び出したときにだけEmacsはプロセスへデータを送り、 Emacsが入力待ちか時間待ちをしているときにだけ プロセスからの出力を受け取れます。
ここでは、非同期プロセスの作成方法について述べます。
start-process name buffer-or-name program &rest args | Function |
この関数は、新たな非同期サブプロセスを作成し、
そのプロセスでプログラムprogramを走らせる。
Lispにおいて新たなサブプロセスを表すプロセスオブジェクトを返す。
引数nameはプロセスオブジェクトの名前を指定する。
その名前のプロセスがすでに存在すると、
名前を一意にするために(<1> などを付加して)nameを修正する。
バッファbuffer-or-nameは、そのプロセスに対応付けるバッファである。
残りの引数argsは、プログラムに対する コマンド行引数を指定する文字列である。 つぎの例では、最初のプロセスは動き始めると
100秒間(休止ではなく)動作する。
そのあいだに2番目のプロセスを動かし始めると、
一意であるためにそれには名前 (start-process "my-process" "foo" "sleep" "100") => #<process my-process> (start-process "my-process" "foo" "ls" "-l" "/user/lewis/bin") => #<process my-process<1>> ---------- Buffer: foo ---------- total 2 lrwxrwxrwx 1 lewis 14 Jul 22 10:12 gnuemacs --> /emacs -rwxrwxrwx 1 lewis 19 Jul 30 21:02 lemon Process my-process<1> finished Process my-process finished ---------- Buffer: foo ---------- |
start-process-shell-command name buffer-or-name command &rest command-args | Function |
この関数はstart-process と同様であるが、
指定したコマンドを実行するためにシェルを用いる点が異なる。
引数commandはシェルコマンドの名前であり、
command-argsはそのシェルコマンドに対する引数である。
変数shell-file-name は、使用するシェルを指定する。
|
process-connection-type | Variable |
この変数は、非同期サブプロセスとの通信に用いる装置の型を制御する。
これがnil 以外であると疑似端末PTYを利用できる場合にはそれを用る。
さもなければパイプを用いる。
シェル(shell)モードなどのユーザーに見えるプロセス向けには、 パイプでは不可能なプロセスとその子プロセスとのあいだで ジョブ制御(C-c、C-zなど)を許すので 疑似端末PTYが望ましい。 プログラムの内部目的向けに使われるサブプロセスでは、 効率的なパイプを用いるほうがよい。 また、多くのシステムでは疑似端末PTYの総数には制約があり、 それらを浪費しないほうがよい。
(let ((process-connection-type nil)) ; パイプを使う (start-process ...)) サブプロセスが実際にはパイプか疑似端末PTYのどちらを
使っているかを調べるには、関数 |
プロセスを削除するとは、サブプロセスからEmacsをただちに切り離し、 サブプロセスを活性なプロセスリストから取り除くことです。 サブプロセスへシグナルを送ってサブプロセスを終了させますが、 ただちに終了するとは保証されません。 プロセスオブジェクトを指すLispオブジェクトがある限り、 プロセスオブジェクトは存在し続けます。 プロセスマークは以前と同様に同じ場所 (プロセスからの出力をバッファに挿入した箇所)を指し続けます。
プロセスはいつでも明示的に削除できます。 プロセスは終了後に自動的に削除されますが、 終了後ただちにではありません。 終了したプロセスが自動的に削除されるまえに明示的に削除しても無害です。
delete-exited-processes | User Option |
この変数は、(exit を呼び出すかシグナルのために)終了した
プロセスの自動削除を制御する。
nil であると、ユーザーがlist-processes を
実行するまで存在し続ける。
さもなければ、終了後にただちに削除する。
|
delete-process name | Function |
この関数は、nameに対応付けられたプロセスを
シグナルSIGHUP でキルし削除する。
引数は、プロセス、プロセス名、バッファ、バッファ名のいずれかである。
(delete-process "*shell*") => nil |
process-kill-without-query process &optional do-query | Function |
この関数は、Emacsを終了するときにプロセスprocessが動作中であると、
ユーザーに問い合わせるかどうかを指定する。
do-queryがnil であると、プロセスを黙って削除する。
さもなければ、Emacsはプロセスのキルに関して問い合わせる。
問い合わせるようにしてあったプロセスであると戻り値は (process-kill-without-query (get-process "shell")) => t |
プロセスに関する情報を返す関数がいくつかあります。
list-processes
は対話的利用のためにあります。
list-processes | コマンド |
このコマンドは、活性なすべてのプロセスの一覧を表示する。
さらに、Exited やSignaled である状態の
プロセスをすべて削除する。
nil を返す。
|
process-list | Function |
この関数は、削除されていないすべてのプロセスのリストを返す。
(process-list) => (#<process display-time> #<process shell>) |
get-process name | Function |
この関数はnameという名前のプロセスを返す。
あるいは、そのようなプロセスがなければnil を返す。
nameが文字列でないとエラーを通知する。
(get-process "shell") => #<process shell> |
process-command process | Function |
この関数は、プロセスprocessを始動するために実行したコマンドを返す。
これは文字列のリストであり、
最初の文字列は実行されたプログラム、
残りの文字列はそのプログラムに与えた引数である。
(process-command (get-process "shell")) => ("/bin/csh" "-i") |
process-id process | Function |
この関数は、プロセスprocessのプロセス番号PIDを返す。 これは同じ計算機上で動いている他のすべてのプロセスと プロセスprocessを区別するための整数である。 プロセスのPIDは、プロセスを始動したときに オペレーティングシステムのカーネルが選び、 プロセスが終了するまで変わらない。 |
process-name process | Function |
この関数はプロセスprocessの名前を返す。 |
process-contact process | Function |
この関数は、通常の子プロセスに対してはt を返し、
ネットワーク接続に対しては(hostname service) を返す
(see Network)。
|
process-status process-name | Function |
この関数は、process-nameの状態をシンボルとして返す。
引数process-nameは、プロセス、バッファ、プロセス名(文字列)、
バッファ名(文字列)のいずれかであること。
実際のサブプロセスに対して可能な値はつぎのとおり。
(process-status "shell") => run (process-status (get-buffer "*shell*")) => run x => #<process xx<1>> (process-status x) => exit ネットワーク接続では、 |
process-exit-status process | Function |
この関数は、プロセスprocessの終了状態か、
プロセスをキルしたシグナル番号を返す。
(どちらであるかを判定するには、process-status の結果を用いる。)
processが終了していないと値は0である。
|
process-tty-name process | Function |
この関数は、プロセスprocessがEmacsとの通信に用いている端末名を返す。
あるいは、端末のかわりにパイプを用いていればnil を返す
(Asynchronous Processesのprocess-connection-type を参照)。
|
process-coding-system process | Function |
この関数は、プロセスprocessからの出力を
復号化するために用いているコーディングシステムと、
processへの入力を符号化するために用いている
コーディングシステムを記述するコンスセルを返す。
(coding-system-for-decoding . coding-system-for-encoding) |
set-process-coding-system process decoding-system encoding-system | Function |
この関数は、プロセスprocessからの以降の出力および入力に用いる コーディングシステムを指定する。 サブプロセスから出力の復号化にはdecoding-systemを使い、 サブプロセスの入力の符号化にはencoding-systemを使う。 |
本節の関数を用いてEmacsが入力を送ると、 非同期プロセスは入力を受け取ります。 入力の送先であるプロセスと、送るべき入力データを指定する必要があります。 そのデータは、サブプロセスの『標準入力』に現れます。
疑似端末PTYのバッファ付き入力の容量に上限がある オペレーティングシステムもあります。 そのようなシステムでは、Emacsは他の文字に混ぜて定期的にEOFを送り、 文字が流れるように強制します。 ほとんどのプログラムでは、このようなEOFは無害なはずです。
ファイルに書き込むテキストと同様に、
サブプロセスの入力は、サブプロセスがそれを受け取るまえに
コーディングシステムを用いて普通は符号化されます。
set-process-coding-system
で
使用するコーディングシステムを指定できます
(see Process Information)。
さもなければ、coding-system-for-write
が
nil
以外であればこれを使います。
それ以外ではデフォルトの機構で決まるものを使います
(see Default Coding Systems)。
process-send-string process-name string | Function |
この関数は、文字列stringの内容を
標準入力としてプロセスprocess-nameに送る。
引数process-nameは、プロセスかプロセス名であること。
これがnil であると、カレントバッファのプロセスを用いる。
関数は (process-send-string "shell<1>" "ls\n") => nil ---------- Buffer: *shell* ---------- ... introduction.texi syntax-tables.texi~ introduction.texi~ text.texi introduction.txt text.texi~ ... ---------- Buffer: *shell* ---------- |
process-send-region process-name start end | コマンド |
この関数は、startとendで定義される領域内のテキストを
標準入力としてプロセスprocess-nameへ送る。
process-nameはプロセスかプロセス名であること。
(nil であると、カレントバッファのプロセスを使う。)
startとendのどちらかが カレントバッファ内の位置を表す整数でもマーカでもないと、 エラーを通知する。 (どちらが大きな数であるかは重要ではない。) |
process-send-eof &optional process-name | Function |
この関数は、プロセスprocess-nameが入力で
「ファイルの終りEOF」を見るようにする。
EOFはそれまでに送ったテキストのあとにある。
process-nameを指定しなかったり 関数はprocess-nameを返す。 (process-send-eof "shell") => "shell" |
サブプロセスにシグナルを送ることは、
サブプロセスの動作に割り込む一方法です。
それぞれ独自の意味を持つ異なるシグナルがいくつかあります。
一連のシグナルとそれらの名前は、オペレーティングシステムが定義します。
たとえば、シグナルSIGINT
は、ユーザーがC-cを打った、
あるいは、それと同様なことが起こったことを意味します。
各シグナルには、サブプロセスに対する標準的な効果があります。 ほとんどのシグナルはサブプロセスをキルしますが、 その実行を一時停止したり再開するものもあります。 プログラムがシグナルを処理している場合には、 シグナルの効果を一般的に述べることはできません。
本節の関数を呼び出してシグナルを明示的に送ることができます。
また、Emacsは特定の場面で自動的にシグナルを送ります。
バッファを削除すると、そのバッファに対応付けられているすべての
プロセスにシグナルSIGHUP
を送ります。
Emacsを終了するときには、動作しているすべてのサブプロセスに
シグナルSIGHUP
を送ります。
(SIGHUP
は、ユーザーが電話を切ったことを普通は表すシグナル。)
シグナルを送る各関数は、省略可能な2つの引数、 process-nameとcurrent-groupを受け付けます。
引数process-nameは、プロセス、プロセス名、nil
のいずれかです。
これがnil
であると、カレントバッファに対応付けられているプロセスが
デフォルトになります。
process-nameがプロセスを指定しないとエラーを通知します。
引数current-groupは、Emacsのサブプロセスとして
ジョブ制御可能なシェルを実行しているときに違いが現れるフラグです。
これがnil
以外であると、
Emacsがサブプロセスとの通信に用いている端末の現在のプロセスグループに
シグナルを送ります。
プロセスがジョブ制御可能なシェルであると、
これはシェルの現在のサブジョブ
10
であることを意味します。
nil
であると、Emacsのサブプロセスの直接のプロセスグループに
シグナルを送ります。
プロセスがジョブ制御可能なシェルであると、これはシェルそのものです。
オペレーティングシステムはパイプではプロセスグループを扱わないため、
サブプロセスとの通信にパイプを用いている場合には、
フラグcurrent-groupには効果はありません。
同じ理由で、パイプを用いている場合には
ジョブ制御可能なシェル(のジョブ制御機能)は働きません。
Asynchronous Processesの
process-connection-type
を参照してください。
interrupt-process &optional process-name current-group | Function |
この関数は、プロセスprocess-nameに
シグナルSIGINT を送って割り込む。
Emacsの外側では、『割り込み文字』(普通、C-cであるシステムもあり、
その他のシステムではDEL )を打つとこのシグナルを送る。
引数current-groupがnil 以外であると、
この関数は、Emacsがサブプロセスと通信している端末上で
『C-cを打つ』と考えることができる。
|
kill-process &optional process-name current-group | Function |
この関数は、プロセスprocess-nameに
シグナルSIGKILL を送ってキルする。
このシグナルはサブプロセスを即座にキルし、
サブプロセスはこれを処理できない。
|
quit-process &optional process-name current-group | Function |
この関数は、プロセスprocess-nameにシグナルSIGQUIT を送る。
このシグナルは、『中断文字』
(Emacsの外側では普通はC-bやC-\)が
送るシグナルと同じものである。
|
stop-process &optional process-name current-group | Function |
この関数は、プロセスprocess-nameに
シグナルSIGTSTP を送って一時停止させる。
その実行を再開させるにはcontinue-process を使う。
Emacsの外側でジョブ制御可能なシステムでは、
『一時停止文字』(普通はC-z)が普通はこのシグナルを送る。
current-groupが |
continue-process &optional process-name current-group | Function |
この関数は、プロセスprocessに
シグナルSIGTCONT を送って実行を再開させる。
以前に一時停止させられたprocessを再開する。
|
signal-process pid signal | Function |
この関数は、必ずしもEmacsの子プロセスではない プロセスpidにシグナルを送る。 引数signalは、送るべきシグナルを整数で指定する。 |
サブプロセスが標準出力に書く出力を受け取る方法は2つあります。 プロセスに対応付けられたバッファに出力を挿入するか、 あるいは、フィルタ関数(filter function)と呼ばれる関数を 出力に対して作用させます。 プロセスにバッファもフィルタ関数もなければ、その出力は破棄します。
サブプロセスからの出力は、Emacsが待っている、つまり、
端末入力を読んでいるとき、
sit-for
やsleep-for
を実行中のとき(see Waiting)、
accept-process-output
(see Accepting Output)を実行中のときに
だけ到着します。
これにより、並行プログラムを普通は悩ますような
タイミングエラーの問題を最小に抑えます。
たとえば、安全にプロセスを作成してから、
バッファかフィルタ関数を指定できます。
この処理の途中で待つような基本関数を呼び出さなければ、
出力は到着しません。
ファイルから読むテキストと同様に、
サブプロセスの出力は、バッファやフィルタ関数が受け取るまえに
コーディングシステムを用いて普通は復号化します。
set-process-coding-system
で
使用するコーディングシステムを指定できます
(see Process Information)。
さもなければ、coding-system-for-read
が
nil
以外であればこれを使います。
それ以外ではデフォルトの機構で決まるものを使います
(see Default Coding Systems)。
警告:
データからコーディングシステムを決定するundecided
のような
コーディングシステムは、非同期サブプロセスの出力に対しては
完全に信頼性のある動作はできない。
これは、Emacsが非同期サブプロセスの出力が
到着するたびに一塊で処理するからである。
Emacsは1つの塊から正しい変換を検出しようと試みるが、
これがつねに動作するとは限らない。
したがって、可能な限り
文字コード変換と行末変換の両方を指定したコーディングシステムを使う。
つまり、undecided
やlatin-1
などではなく、
latin-1-unix
のようなものを使う。
プロセスには対応付けられたバッファが(普通は)あります。 そのバッファはEmacsの普通のバッファであり、2つの目的に使われます。 プロセスからの出力を保存することと、 プロセスがキルされたことを判定するためです。 バッファを用いてそれを操作しているプロセスを識別することもできます。 普通は1つのバッファに1つのプロセスを対応付けるからです。 プロセスの多くの応用では、プロセスへ送る入力を編集するために バッファを使いますが、これはEmacs Lispに組み込まれたことではありません。
プロセスにフィルタ関数(see Filter Functions)がなければ、
その出力は対応付けられたバッファに挿入されます。
出力の挿入位置はprocess-mark
で決定され、
process-mark
は挿入したばかりのテキストの末尾を
指すように更新されます。
process-mark
は普通はバッファの末尾にありますが、
つねにそうであるとは限りません。
process-buffer process | Function |
この関数は、プロセスprocessに対応付けられているバッファを返す。
(process-buffer (get-process "shell")) => #<buffer *shell*> |
process-mark process | Function |
この関数は、プロセスprocessからの出力を挿入する箇所を指定する
processのプロセスマーカを返す。
processにバッファがなければ、
バッファにプロセス出力を挿入する際には、 挿入箇所を決定するためにこのマーカを使用し、 挿入したテキストの末尾を指すようにこのマーカを更新する。 これにより、出力の連続した塊を順に挿入できるのである。 バッファに出力を直接挿入する場合と同様に、
フィルタ関数はこのマーカを扱うべきである。
プロセスへ送るためにユーザーがプロセスバッファに 入力することが予想されるときは、 プロセスマーカは新たな入力とそれ以前の出力を区切る。 |
set-process-buffer process buffer | Function |
この関数は、プロセスprocessにバッファbufferを対応付ける。
bufferがnil であると、
プロセスに対応付けられたバッファはない。
|
get-buffer-process buffer-or-name | Function |
この関数はbuffer-or-nameに対応付けられたプロセスを返す。
バッファに複数のプロセスが対応付けられている場合には、
それらの1つを選ぶ。
(現状では、もっとも最近に作られたプロセスを選ぶ。)
同じバッファに複数のプロセスを対応付けることは一般にはよくない。
(get-buffer-process "*shell*") => #<process shell> プロセスのバッファを削除すると、
サブプロセスにシグナル |
プロセスのフィルタ関数(filter function)は、 対応付けられたプロセスからの標準出力を受け取る関数です。 プロセスにフィルタがあると、そのプロセスからのすべての出力は フィルタに渡されます。 プロセスにフィルタがない場合に限って、 プロセスからの出力向けにプロセスバッファを直接使います。
フィルタ関数は、Emacsがなにかを待っているときにのみ呼ばれます。
そのような期間にのみプロセスの出力が到着するからです。
Emacsが待つのは、端末入力を読んでいるとき、
sit-for
やsleep-for
を実行中のとき(see Waiting)、
accept-process-output
(see Accepting Output)を実行中のときです。
フィルタ関数は2つの引数、 対応付けられたプロセスとそのプロセスから受け取ったばかりの出力である文字列を 受け取ります。 関数は出力に対してなにを行ってもかまいません。
フィルタ関数の内側では中断は普通は禁止されています。
さもないと、コマンドレベルで打ったC-gの効果や、
ユーザーコマンドを中断するために打ったC-gの効果は予測できません。
フィルタ関数の内側で中断を行いたい場合には、
inhibit-quit
にnil
を束縛します。
See Quitting。
フィルタ関数の実行中にエラーが発生するとそのエラーは自動的に捕捉され、
フィルタ関数を始動したときに動いていた
プログラムの実行を停止しないようにします。
しかし、debug-on-error
がnil
以外であると、
エラーを捕捉しません。
これにより、Lispデバッガでフィルタ関数をデバッグできます。
See Debugger。
多くのフィルタ関数は、ときどきあるいはつねに、
プロセスのバッファにテキストを挿入します。
これはフィルタ関数がないときのEmacsの動作を模倣するものです。
そのようなフィルタ関数では、対象のバッファに挿入するために
set-buffer
を使う必要があります。
カレントバッファをなかば恒久的に切り替えないように、
これらのフィルタ関数はカレントバッファを記録/復元する必要があります。
プロセスマーカを更新し、必要に応じてポイントの値も更新します。
これらはつぎのように行います。
(defun ordinary-insertion-filter (proc string) (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))))))
カレントバッファを記録/復元するためにsave-excursion
ではなく
with-current-buffer
を使うのは、
2番目のgoto-char
の呼び出しで行うポイントの移動効果を
有効にするためです。
新たにテキストが到着するたびにプロセスバッファが見えるように
フィルタ関数で強制するには、
つぎのような行をwith-current-buffer
の直前に入れます。
(display-buffer (process-buffer proc))
ポイント位置に関わらずに新たな出力の末尾にポイントを移動するには、
変数moving
を削除して、
無条件にgoto-char
を呼び出します。
Emacsの初期の版では、正規表現を探索したり一致処理するフィルタ関数では、 マッチデータを明示的に保存/復元する必要がありました。 今のEmacsは、フィルタ関数に対してはこれを自動的に行いますから、 フィルタ関数で明示的に行う必要はありません。 See Match Data。
プロセスのバッファに出力を書き込むフィルタ関数は、
そのバッファが有効であるかどうかを検査するべきです。
無効なバッファに挿入しようとするとエラーになります。
バッファが無効であれば、
式(buffer-name (process-buffer process))
を実行するとnil
を返します。
関数に渡される出力は任意のサイズの塊できます。 同じ出力を2回生成するプログラムは、 あるときには一度に200文字の塊を1つ送る場合もあれば、 40文字の塊を5つ送る場合もあります。 サブプロセスの出力から特定のテキスト文字列を探すフィルタでは、 そのような文字列が2つかそれ以上の出力の塊に分割される場合も 扱えるようにします。
set-process-filter process filter | Function |
この関数は、プロセスprocessにフィルタ関数filterを指定する。
filterがnil であると、プロセスにフィルタはない。
|
process-filter process | Function |
この関数は、プロセスprocessのフィルタ関数を返す。
あるいは、フィルタ関数がなければnil を返す。
|
フィルタ関数の使用例をつぎに示します。
(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[8] % " "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 ")
非同期サブプロセスからの出力は、 Emacsが時間待ちや端末入力などの なんらかの外部事象を待っているときにのみ到着します。 Lispプログラムから特定の場面で出力の到着を明示的に許したり、 プロセスの出力が到着するのを待つことができると有用なことがあります。
accept-process-output &optional process seconds millisec | Function |
この関数は、Emacsにプロセスからの未処理の出力を読み取ることを許す。
その出力は、対応付けられたバッファに挿入されるか、
フィルタ関数に与えられる。
processがnil 以外であると、
この関数は、processからなんらかの出力を得るまで戻らない。
引数secondsとmillisecは、時間切れを指定する。
前者は秒単位の時間、後者はミリ秒単位の時間を指定する。
指定された2つの時間は合計され、
任意のサブプロセスの出力を受け取ったどうかに関わらず、
その時間だけ経過すると 引数secondsは整数である必要はない。 浮動小数点数であると、この関数は秒未満の時間も待つ。 秒未満を扱えないシステムもある。 そのようなシステムでは、secondsを切り下げる。 すべてのオペレーティングシステムで秒未満を扱えるわけではない。 扱えないシステムでmillisecにゼロ以外を指定すると エラーになる。 関数 |
プロセスの番兵(process sentinel)は、 プロセスを終了/一時停止/継続させる (Emacsが送ったかプロセス自身の動作によって生起した)シグナルを含めて 対応付けられたプロセスの状態が任意の理由で変化したときに 呼び出される関数です。 プロセスの番兵は、プロセスが終了しても呼び出されます。 番兵は2つの引数、事象が発生したプロセスと 事象の種類を記述する文字列を受け取ります。
事象を記述する文字列はつぎのとおりです。
"finished\n"
.
"exited abnormally with code exitcode\n"
.
"name-of-signal\n"
.
"name-of-signal (core dumped)\n"
.
番兵はEmacsが(たとえば、端末入力や時間経過、プロセスの出力を)
待っているときにのみ実行されます。
他のLispプログラムの実行途中で無秩序に番兵を実行した場合に起こる
タイミングエラーを回避するためです。
sit-for
やsleep-for
(see Waiting)、あるいは、
accept-process-output
(see Accepting Output)を
呼び出すとプログラムは待ちに入り、番兵が動けることになります。
Emacsは、コマンドループで入力を読むときにも番兵の実行を許します。
番兵の内側では中断は普通は禁止されています。
さもないと、コマンドレベルで打ったC-gの効果や、
ユーザーコマンドを中断するために打ったC-gの効果は予測できません。
番兵の内側で中断を行いたい場合には、
inhibit-quit
にnil
を束縛します。
See Quitting。
プロセスのバッファに出力を書き込む番兵は、
そのバッファが有効であるかどうかを検査するべきです。
無効なバッファに挿入しようとするとエラーになります。
バッファが無効であれば、
式(buffer-name (process-buffer process))
を実行するとnil
を返します。
番兵の実行中にエラーが発生するとそのエラーは自動的に捕捉され、
番兵を始動したときに動いていた
プログラムの実行を停止しないようにします。
しかし、debug-on-error
がnil
以外であると、
エラーを捕捉しません。
これにより、Lispデバッガで番兵をデバッグできます。
See Debugger。
Emacsの初期の版では、正規表現を探索したり一致処理する番兵では、 マッチデータを明示的に保存/復元する必要がありました。 今のEmacsは、番兵に対してはこれを自動的に行いますから、 番兵で明示的に行う必要はありません。 See Match Data。
set-process-sentinel process sentinel | Function |
この関数は、プロセスprocessに番兵sentinelを対応付ける。
sentinelがnil であると、プロセスに番兵はない。
番兵がない場合のデフォルトのふるまいは、
プロセス状態が変化するとプロセスのバッファにメッセージを挿入する。
(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> |
process-sentinel process | Function |
この関数は、プロセスprocessの番兵を返すか、
番兵がなければnil を返す。
|
waiting-for-user-input-p | Function |
番兵やフィルタ関数が動作中にこの関数を呼び出すと、
番兵やフィルタ関数を呼び出したときにEmacsがユーザーからの
キーボード入力を待ってるとnil 以外を返し、
それ以外ではnil を返す。
|
トランザクションを用いたサブプロセスとの通信に
トランザクションキュー(transaction queue)を使えます。
まずtq-create
を用いて、
指定したプロセスとの通信用トランザクションキューを作成します。
そして、トランザクションを送るためにtq-enqueue
を呼び出します。
tq-create process | Function |
この関数は、プロセスprocessとの通信用トランザクションキューを 作成して返す。 引数processは、バイトストリームを送受信できる機能を 有するサブプロセスであること。 つまり、子プロセスであるか、別のマシン上の可能性もある サーバーへのTCP接続である。 |
tq-enqueue queue question regexp closure fn | Function |
この関数はキューqueueにトランザクションを送る。
キューを指定することは、
通信相手のサブプロセスを指定する効果がある。
引数questionは、トランザクションを始める送出メッセージである。 引数fnは、対応する応答が戻ってきたときに呼び出す関数である。 その関数は2つの引数、closureと受け取った応答で呼び出される。 引数regexpは、1つの応答だけに一致する正規表現である。
|
tq-close queue | Function |
未処理のトランザクションすべてが完了するのを待ち、 接続や子プロセスを終了して、 トランザクションキューqueueを終える。 |
トランザクションキューはフィルタ関数を用いて実装してあります。 See Filter Functions。
Emacs Lispプログラムは、同一マシンや別のマシン上の他のプロセスに対して
TCPネットワーク接続を開くことができます。
ネットワーク接続は、サブプロセスと同様にLispが扱い、
プロセスオブジェクトとして表現されます。
しかし、通信相手のプロセスはEmacsプロセスの子プロセスではありませんから、
キルしたりシグナルを送ることはできません。
データの送受信のみが可能です。
delete-process
は接続を閉じますが、
もう一方の端のプロセスをキルしません。
そのプロセスは、接続が閉じた場合の動作を判断する必要があります。
ネットワーク接続を表すプロセスオブジェクトと
サブプロセスを表すプロセスオブジェクトとは、
関数process-status
を使って区別できます。
この関数は、ネットワーク接続に対しては
open
かclosed
をつねに返し、
本当のサブプロセスに対してはこれらのいずれの値もけっして返しません。
See Process Information。
open-network-stream name buffer-or-name host service | Function |
この関数は、ホストのサーバーに対するTCP接続を開く。
接続を表すプロセスオブジェクトを返す。
引数nameは、プロセスオブジェクトに付ける名前を指定する。 必要に応じて一意にするために修正される。 引数buffer-or-nameは、接続に対応付けるバッファである。
出力を扱うフィルタ関数を指定しない限り、
接続からの出力はそのバッファに挿入される。
buffer-or-nameが 引数hostとserviceは、接続先を指定する。 hostはホスト名(文字列)であり、 serviceは定義済みのネットワークサービス(文字列)か ポート番号(整数)である。 |
本章は、Emacsの起動と終了、 オペレーティングシステムの環境に収められた値の参照方法、 端末入出力とフロー制御についてです。
関連情報についてはSee Building Emacs。 また、端末やスクリーンに関係する オペレーティングシステムの状態情報については、 Displayも参照してください。
本節では、Emacsが起動時になにを行うか、および、 それらをカスタマイズする方法について述べます。
.emacs
).
Emacsが始動したときに行う(startup.el
での)
処理の順序はつぎのとおりです。
load-path
にある各ディレクトリファイルにおいて
subdirs.el
という名前のファイルを実行することで
load-path
にサブディレクトリを追加する。
LANG
などの環境変数で要求されていれば、
言語環境と端末のコーディングシステムを設定する。
term/windowsystem-win.el
である。
before-init-hook
を実行する。
-no-site-file
が指定されていなければ、
ライブラリsite-start
をロードする。
このライブラリの名前は普通はsite-start.el
である。
-q
や-batch
が指定されていなければ、
ファイル~/.emacs
をロードする。
オプション-u
で、~
のかわりに用いるホームディレクトリを持つ
他のユーザー名を指定できる。
inhibit-default-init
がnil
以外でなければ、
ライブラリdefault
をロードする。
(コマンド行で-q
を指定したり、
-batch
モードでは、これを行わない。)
ライブラリのファイル名は普通はdefault.el
である。
after-init-hook
を実行する。
*scratch*
がカレントバッファであり
基本(fundamental)モードであるならば、
initial-major-mode
に従ってメジャーモードを設定する。
inhibit-startup-echo-area-message
で抑制していなければ、
初期メッセージをエコー領域に表示する。
term-setup-hook
を実行する。
frame-notice-user-settings
を呼び出す。
window-setup-hook
を実行する。
see Window Systems。
inhibit-startup-message
の値がnil
であり、
バッファが空であれば、
コピーレフト/無保証/基本的な利用情報を表示する。
inhibit-startup-message | User Option |
この変数は、(無保証などの)初期の始動メッセージを禁止する。
これがnil 以外であるとメッセージを表示しない。
始動メッセージの内容に十分慣れたら、 読者個人の初期化ファイルで設定できるようにこの変数がある。 新規ユーザーが受け取るはずである情報を隠してしまうため、 新規ユーザーの初期化ファイルや複数のユーザーに影響するような方法で この変数に設定しないこと。 |
inhibit-startup-echo-area-message | User Option |
この変数は、エコー領域に表示する始動メッセージを制御する。
個人のファイル.emacs につぎのフォームを追加することで
エコー領域の始動メッセージを抑制できる。
(setq inhibit-startup-echo-area-message "your-login-name") Emacsは、読者のファイル このように、望むならば自身のためにメッセージを簡単に禁止できるが、
読者の |
.emacs
読者がEmacsを始動すると、Emacsは読者のホームディレクトリから
ファイル.emacs
を普通はロードしようとします。
このファイルが存在すれば、これにはLispコードを入れておく必要があります。
コマンド行オプション-q
と-u
は、
初期化ファイルの使い方に影響します。
-q
は初期化ファイルをロードしないように指示し、
-u
は読者の初期化ファイルのかわりに指定したユーザーの初期化ファイルを
ロードするように指示します。
See Entering Emacs。
デフォルトの初期化ファイルをサイトごとに持てます。
これはdefault.el
という名前のライブラリです。
Emacsは、ライブラリを探索する標準パスから
ファイルdefault.el
を探します
(see How Programs Do Loading)。
Emacsの配布には、このファイルは付属していません。
ローカルなカスタマイズのためにサイトで用意します。
バッチモードや-q
を指定してある場合を除いて、
デフォルトの初期化ファイルが存在すると、
読者がEmacsを始動するたびにそれをロードします。
しかし、存在するなら、個人の初期化ファイルをさきにロードします。
そこでinhibit-default-init
にnil
以外の値を設定してあると、
Emacsはそのあとファイルdefault.el
をロードしません。
サイトごとのカスタマイズ向けの別のファイルはsite-start.el
です。
Emacsはユーザーの初期化ファイルをロードするまえに
このファイルをロードします。
このファイルのロードを禁止するには
オプション-no-site-file
を使います。
site-run-file | Variable |
この変数は、ユーザーの初期化ファイルよりさきに
ロードするべきサイトごとのカスタマイズファイルを指定する。
普通の値は"site-start" である。
実際に効果があるようにこれを変更する唯一の方法は、
Emacsをダンプするまえに行うことである。
|
読者のファイル.emacs
に大量のコードがある場合には、
something.el
という名前の別のファイルへコピーして、
それをバイトコンパイルし(see Byte Compilation)、
読者のファイル.emacs
では、load
(see Loading)で
そのファイルをロードするようにします。
読者のファイル.emacs
でよく使われるであろう
さまざまなカスタマイズを行う方法の例については、
See Init Examples。
inhibit-default-init | User Option |
この変数は、読者のEmacsセッションにおいては、
デフォルトの初期化ライブラリファイルをロードしないようにする。
その値がnil 以外であるとデフォルトライブラリをロードしない。
デフォルト値はnil である。
|
before-init-hook | Variable |
すべての初期化ファイル
(ユーザーの初期化ファイル、
default.el と/あるいはsite-start.el )を
ロードする直前に一度だけ実行するノーマルフック。
(実際の効果があるようにこれを変更する唯一の方法は、
Emacsをダンプするまえに行うことである。)
|
after-init-hook | Variable |
すべての初期化ファイル
(ユーザーの初期化ファイル、
default.el と/あるいはsite-start.el )をロード直後、
端末固有の初期化のまえに一度だけ実行するノーマルフック。
|
端末の各種類ごとに、Emacsがその種類の端末で動作するときに
Emacsがロードする専用Lispライブラリを持てます。
ライブラリ名は、変数term-file-prefix
の値と
端末種類を連結して作ります。
通常、term-file-prefix
の値は"term/"
であり、
これを変更することは勧めません。
Emacsは通常どおり、load-path
のディレクトリ群において
.elc
と.el
の接尾辞でファイルを探します。
端末固有ライブラリの普通の機能は、
Emacsが識別可能なキー列を送るように特別なキーを設定することです。
端末のすべてのファンクションキーがtermcapに入っていない場合には、
function-key-map
を設定したり追加する必要もあります。
端末種類の名前にハイフンが含まれる場合、
ライブラリ名を選ぶうえでは、最初のハイフンよりまえの名前の部分が有効です。
したがって、aaa-48
とaaa-30-rv
のどちらも
ライブラリterm/aaa
を使います。
必要ならば、ライブラリでは(getenv "TERM")
を評価することで
端末種類の完全な名前を得ることができます。
読者のファイル.emacs
で
変数term-file-prefix
にnil
を設定すると、
端末固有ライブラリをロードしないようにできます。
この機能は、読者独自のカスタマイズを試すときに有用です。
変数term-setup-hook
に設定すれば、
端末固有ライブラリの特定の動作に優先できます。
これは、読者のファイル.emacs
と端末固有ライブラリの両者を
ロードしたあとの初期化後にEmacsが実行するノーマルフックです。
端末専用ライブラリがない端末向けの初期化を定義するために
この変数を使えます。
See Hooks。
term-file-prefix | Variable |
変数term-file-prefix がnil 以外であると、
Emacsは、つぎのように端末固有の初期化ファイルをロードする。
(load (concat term-file-prefix (getenv "TERM"))) 端末固有の初期化ファイルをロードしたくない場合には、
読者のファイル |
term-setup-hook | Variable |
この変数は、読者のファイル.emacs 、
(あれば)デフォルトの初期化ファイル、
端末固有のLispファイルをロードしたあとにEmacsが実行する
ノーマルフックである。
端末固有ファイルの定義に優先するために |
関連する機能については、
Window Systemsのwindow-setup-hook
を参照してください。
Emacsを始動するときにコマンド行引数を使ってさまざまな動作を要求できます。 一日に一度より多くEmacsを始動する必要はないでしょうし、 しばしばEmacsセッションをそれより長く動かし続けるでしょうから、 コマンド行引数はほとんど使いません。 実際、コマンド行引数を使う癖は避けたほうがよいです。 そのような癖をつけると、Emacsを必要以上に終了したり再始動するからです。 これらのオプションは2つの理由で存在します。 (別のプログラムから起動される)他のエディタと互換性があるようにするのと、 シェルスクリプトから特定のLispプログラムを実行できるようにするためです。
本節では、Emacsがコマンド行引数を処理する方法と、 それらをカスタマイズする方法について述べます。
command-line | Function |
この関数は、Emacsを呼び出すときに指定されたコマンド行引数を解析して処理し、
ユーザーのファイル.emacs をロードし始動メッセージを表示する。
|
command-line-processed | Variable |
この変数の値は、コマンド行引数を一度処理し終えるとt である。
|
command-switch-alist | Variable |
この変数の値は、ユーザー定義のコマンド行オプションの連想リストである。
この変数は、読者が要素を追加できるように存在する。
コマンド行オプション(command line option)は、 つぎの形のコマンド行の引数である。 -option
(option . handler-function) handler-functionは、オプションoptionを処理するために呼ばれ、 オプション名を唯一の引数として受け取る。 コマンド行のオプションには引数が続く場合もある。
そのような場合、handler-functionは
変数 コマンド行引数は、ファイル |
command-line-args | Variable |
この変数の値は、Emacsに渡されたコマンド行引数のリストである。 |
command-line-functions | Variable |
この変数の値は、認識できないコマンド行引数を処理する関数のリストである。
つぎに処理する引数に特別な意味がないと、
このリストの関数をnil 以外の値を返すまで現れる順に呼び出す。
これらの関数は引数なしで呼び出される。
これらの関数では、呼び出し時に束縛される変数 関数が これらの関数すべてが |
Emacsから抜けるには2つの方法があります。 Emacsを終了するためにEmacsジョブをキルするか、 あとでEmacsを継続できるように休止します。 実用上は、ログアウトするとき以外にはEmacsをほとんど終了しないでしょう。 Emacsを休止するほうが一般的です。
Emacsを終了するとは、Emacsプロセスの実行を終らせることを意味します。
親プロセスが普通は制御を取り戻します。
Emacsを終了するための下位の基本関数はkill-emacs
です。
kill-emacs &optional exit-data | Function |
この関数は、Emacsプロセスを終了しEmacsを終える。
exit-dataが整数であると、Emacsプロセスの終了状態として使われる。 (これは主にバッチ処理で有用である。 Batch Modeを参照。) exit-dataが文字列であると、 その内容を端末入力バッファへ詰め込み、 シェル(やつぎに入力を読むプログラム)がそれらを読み取れるようにする。 |
保存済みのファイルを除くEmacsプロセス内のすべての情報は、
Emacsを終了すると失われます。
Emacsを不注意に終了すると多くの作業を失うことになるので、
保存する必要があるバッファがあったり動作中のサブプロセスがあると、
Emacsは確認を求めます。
これは関数save-buffers-kill-emacs
が行います。
kill-emacs-query-functions | Variable |
標準的な問い合わせをしたあとで、
save-buffers-kill-emacs は、
リストkill-emacs-query-functions 内の関数を
現れる順に引数なしで呼び出す。
これらの関数では、ユーザーにさらなる確認を求めることができる。
これらのどれかがnil を返すと、Emacsは終了しない。
|
kill-emacs-hook | Variable |
この変数はノーマルフックである。
save-buffers-kill-emacs がファイルをすべて保存し確認し終えると、
このフックの関数群を実行する。
|
Emacsを休止するとは、Emacsを一時的に停止し、
普通はシェルである親プロセスに制御を戻すことです。
これにより、あとで同じEmacsプロセスで、つまり、同じバッファ群、
同じキルリング、同じアンドゥ履歴などで編集を再開できます。
Emacsを再開するには、親シェルにおいて
ほとんどの場合fg
などの適切なコマンドを使います。
ジョブの休止を扱えないオペレーティングシステムもあります。 そのようなシステムでは、『休止』はEmacsのサブプロセスとして 一時的に新たなシェルを実際には作成します。 そのシェルを終了するとEmacsに戻ります。
ウィンドウシステムを使っている場合には、 Emacsジョブを再開する親プロセスがいないかもしれませんし、 別のウィンドウへ移動すれば別のジョブへ入力できますから、 Emacsの休止は有用ではありません。 したがって、Emacsがウィンドウシステムを使っている場合には、 休止できません。
suspend-emacs string | Function |
この関数は、Emacsを休止し、親プロセスへ制御を戻す。
親プロセスがEmacsを再開した場合にのみ、
suspend-emacs はLisp内の呼び出し側へnil を返す。
stringが 休止するまえに、 ユーザーがEmacsを再開すると、 再開後のつぎの再表示では、
変数 つぎの例では、Emacsを休止しても (suspend-emacs) => nil (add-hook 'suspend-hook (function (lambda () (or (y-or-n-p "Really suspend? ") (error "Suspend cancelled"))))) => (lambda nil (or (y-or-n-p "Really suspend? ") (error "Suspend cancelled"))) (add-hook 'suspend-resume-hook (function (lambda () (message "Resumed!")))) => (lambda nil (message "Resumed!")) (suspend-emacs "pwd") => nil ---------- Buffer: Minibuffer ---------- Really suspend? y ---------- Buffer: Minibuffer ---------- ---------- Parent Shell ---------- lewis@slug[23] % /user/lewis/manual lewis@slug[24] % fg ---------- Echo Area ---------- Resumed! |
suspend-hook | Variable |
この変数は、休止するまえに実行されるノーマルフックである。 |
suspend-resume-hook | Variable |
この変数は、再開後に実行されるノーマルフックである。 |
Emacsでは、さまざまな関数を介して オペレーティングシステム環境の変数を参照できます。 これらの変数には、システムの名前、ユーザーの識別番号UIDなどが 含まれます。
system-configuration | Variable |
この変数は、読者のシステムのハードウェア/ソフトウェア構成に対する
GNUの構成名を文字列で保持している。
この文字列の一部分を検査する簡便な方法は
string-match を使うことである。
|
system-type | Variable |
この変数の値は、Emacsが動作している
オペレーティングシステムの種類を表すシンボルである。
つぎに可能な値の一覧を示す。
絶対に必要でない限り、細分類のために新たなシンボルを追加したくない! |
system-name | Function |
この関数は読者が使っているマシンの名前を返す。
(system-name) => "www.gnu.org" |
シンボルsystem-name
は、関数としても変数としても使えます。
実際、関数としては、変数system-name
が現在保持している値を返します。
したがって、Emacsが読者のシステム名に関して混乱している場合には、
変数system-name
に設定できます。
変数はフレームタイトルの作成にも有用です(see Frame Titles)。
mail-host-address | Variable |
この変数がnil 以外であると、system-name のかわりに
電子メイルアドレスの生成に使われる。
たとえば、user-mail-address のデフォルト値の作成に使われる。
see User Identification。
(これはEmacsの始動時に行われるため、
Emacsをダンプしたときの値が実際に使われる値である。
see Building Emacs)。
|
getenv var | Function |
この関数は、環境変数varの値を文字列で返す。
Emacs内部では、環境変数の値はLisp変数process-environment に
保持されている。
(getenv "USER") => "lewis" lewis@slug[10] % printenv PATH=.:/user/lewis/bin:/usr/bin:/usr/local/bin USER=lewis TERM=ibmapa16 SHELL=/bin/csh HOME=/user/lewis |
setenv variable value | コマンド |
このコマンドは、環境変数variableに値valueを設定する。
どちらの引数も文字列である。
この関数はprocess-environment を修正することで動作する。
この変数をlet で束縛しても十分に実用的である。
|
process-environment | Variable |
この変数は、各要素が1つの環境変数を記述する文字列のリストである。
関数getenv とsetenv は、この変数を用いて動作する。
process-environment => ("l=/usr/stanford/lib/gnuemacs/lisp" "PATH=.:/user/lewis/bin:/usr/class:/nfsusr/local/bin" "USER=lewis" "TERM=ibmapa16" "SHELL=/bin/csh" "HOME=/user/lewis") |
path-separator | Variable |
この変数は、(環境変数などで)探索パスを
区切る文字を指定する文字列を保持する。
UNIXとGNUシステムではその値は":" であり、
MS-DOSとWidows NTでは";" である。
|
invocation-name | Variable |
この変数は、起動したEmacsのプログラム名を保持する。 値は文字列であり、ディレクトリ名は含まない。 |
invocation-directory | Variable |
この変数は、起動したEmacsの実行形式のディレクトリを保持する。
ディレクトリを判別できない場合にはnil である。
|
installation-directory | Variable |
nil 以外であると、サブディレクトリlib-src とetc を
探すためのディレクトリである。
Emacsがこれらのディレクトリを標準のインストールディレクトリで
みつけられなくてもEmacsの実行形式になんらかの意味で
関連するディレクトリでみつけられれば、nil 以外である。
|
load-average &optional use-float | Function |
この関数は、1分間/5分間/15分間のロードアベレッジ
(負荷平均)をリストで返す。
デフォルトでは、これらの値は、動作しようとしてるプロセスの平均個数を表す
システムのロードアベレッジを100倍した整数である。
use-floatが (load-average) => (169 48 36) (load-average t) => (1.69 0.48 0.36) lewis@rocky[5] % uptime 11:55am up 1 day, 19:37, 3 users, load average: 1.69, 0.48, 0.36 |
emacs-pid | Function |
この関数は、Emacsプロセスのプロセス番号IDを返す。 |
tty-erase-char | Variable |
この変数は、Emacsが始動するまえに システムの端末ドライバが選んでいた消去文字を保持する。 |
setprv privilege-name &optional setp getprv | Function |
この関数は、(UNIX上には存在しない)VMS基本操作を設定/再設定する。
最初の引数は文字列で表した基本操作の名前である。
第2引数setpはt かnil であり、
基本操作をオンにするかオフにするかを表す。
デフォルトはnil である。
関数は、成功すればt を返し、さもなければnil を返す。
第3引数getprvが |
init-file-user | Variable |
この変数は、Emacsが使用すべきユーザー初期化ファイルを指定する。
あるいは、そのようなものがなければnil である。
この値は、-q や-u user の
コマンド行オプションを反映する。
カスタマイズファイルや他の種類のユーザープロフィールを
ロードするLispパッケージは、それらを探す場所を判断するために
この変数に従うこと。
この変数のユーザー名のカスタマイズをロードするべきである。
|
user-mail-address | Variable |
これは、Emacsを使用しているユーザーの通常の電子メイルアドレスを保持する。
Emacsは通常、読者の初期化ファイルを読み取ったあと、
この変数が未設定であるとデフォルト値を設定する。
したがって、デフォルト値を使いたくない場合には、
読者のファイル~/.emacs で別の値に設定できる。
|
user-login-name &optional uid | Function |
uidを指定しないと、
この関数はログインしたユーザー名を返す。
環境変数LOGNAME が設定されていればその値を使う。
さもなければ、環境変数USER が設定されていればその値を使う。
さもなければ、実UIDではなく実効UIDに基づいた値である。
UIDを指定すると、値は(整数である)UIDに 対応するユーザー名である。 (user-login-name) => "lewis" |
user-real-login-name | Function |
この関数は、Emacsの実UIDに対応するユーザー名を返す。
これは、実効UIDや環境変数LOGNAME とUSER を無視する。
|
user-full-name &optional uid | Function |
この関数は、ログインしたユーザーの氏名を返す。
あるいは、環境変数NAME が設定してあればその値を返す。
(user-full-name) => "Bil Lewis" uidが |
シンボルuser-login-name
、user-real-login-name
、
user-full-name
は、関数でもある変数です。
関数としては、その変数が保持する値と同じ値を返します。
これらの変数により、関数として返す値を指定しておくことで
Emacsを『ごまかせ』ます。
これらの変数は、フレームタイトルの作成にも有用です
(see Frame Titles)。
user-real-uid | Function |
この関数は、ユーザーの実UIDを返す。
(user-real-uid) => 19 |
user-uid | Function |
この関数は、ユーザーの実効UIDを返す。 |
本節では、現在時刻と時刻帯(タイムゾーン)を調べる方法を説明します。
current-time-string &optional time-value | Function |
この関数は、人間向けの文字列で現在時刻と日付を返す。
文字列の書式は不変であり、各部分の文字数はつねに同じなので、
各部分を取り出すのにsubstring を使っても問題ない。
将来、文字列の末尾に追加情報を付加することもあるので、
文字列の末尾からではなく先頭から文字を数えるほうがよい。
引数time-valueを指定すると、
それは現在時刻のかわりに書式付けする時刻を指定する。
引数は、最初の2つの要素が整数であるリストであること。
したがって、 (current-time-string) => "Wed Oct 14 22:21:05 1987" |
current-time | Function |
この関数は、システムの時刻の値を
3つの整数のリスト(high low microsec) で返す。
整数highとlowを組み合わせると
1970年1月1日0:00からの経過秒数を与える。
つまり、経過秒数は
第3要素microsecは、現在の秒内のミリ秒を表す (返す時間精度が秒のシステムでは0)。 最初の2つの要素は、関数 |
current-time-zone &optional time-value | Function |
この関数は、ユーザーの地域の時刻帯を記述するリストを返す。
値は、 値を計算するために必要な情報をオペレーティングシステムから得られないと
リストのどちらの要素も 引数time-valueを指定すると、
現在時刻のかわりに分析すべき時刻を指定する。
引数は、2つの整数を収めたコンスセルであるか、
最初の2つの要素が整数であるリストであること。
したがって、 |
これらの関数は、時刻の値(2つか3つの整数から成るリスト)を
文字列や日時情報に変換します。
日時情報を時刻の値に変換する関数もあります。
時刻の値は、関数current-time
(see Time of Day)や
file-attributes
(see File Attributes)で得られます。
多くのオペレーティングシステムでは、時刻の値を32ビットに制限しています。 これらのシステムでは、典型的には協定世界時1901年12月13日20:45:52から 2038年1月19日03:14:07までしか表現できません。 しかし、より大きな時刻の値を扱い、 より広い範囲の過去から未来を表現できるシステムもあります。
時刻変換関数は、グレゴリオ暦を導入するまえであっても つねにグレゴリオ暦を使います。 紀元前1年からの経過年数を数え、通常のグレゴリオ暦のように0年を飛ばしません。 たとえば、-37年は、グレゴリオ暦紀元前38年を表します。
format-time-string format-string time | Function |
この関数は、timeをformat-stringに従って文字列に変換する。
引数format-stringには、時刻のさまざまな部分で置き換えられる
% 列を含んでよい。
% 列の意味を以下に示す。
これらの たとえば、 |
decode-time time | Function |
この関数は、時刻の値を日時情報に変換する。
戻り値は、つぎの9要素のリストである。
(seconds minutes hour day month year dow dst zone) 各要素の意味はつぎのとおりである。
Common Lispに関した注意: |
encode-time seconds minutes hour day month year &optional ...zone | Function |
この関数はdecode-time の逆である。
7項目から成る日時情報を時刻の値に変換する。
引数の意味については、上記decode-time の一覧を参照。
100未満の年は普通の年として扱う。
それらを1900年代として扱いたい場合には、
省略可能な引数zoneのデフォルトは、
現在の時刻帯とその夏時間制の規則である。
指定する場合には、(
(apply 'encode-time (decode-time ...)) 引数sec、minute、hour、day、monthの 値が範囲外になるようにすると単純な日時演算を行える。 たとえば、0日はその月のまえの日を意味する。 オペレーティングは可能な時刻の値の範囲を制限する。 その範囲を越える時刻を符号化しようとするとエラーになる。 |
未来のある時刻に関数を呼び出したり、 ある一定期間なにもしないでいたら関数を呼び出すために タイマを設定できます。
Emacsは、Lispプログラムの任意の箇所ではタイマを実行できません。
サブプロセスからの出力を受け取るときにだけタイマを実行できます。
つまり、待つことが可能なsit-for
やread-event
などの
基本関数の内側や(入力を)待っているあいだに実行できます。
したがって、Emacsが忙しいとタイマの実行が遅れることがあります。
しかし、Emacsが暇ならば、タイマの実行はとても正確です。
run-at-time time repeat function &rest args | Function |
この関数は、時刻timeに引数argsで
関数functionを呼び出すように予約する。
引数functionはのちに呼び出される関数であり、
引数argsはそれを呼び出すときに与える引数である。
時刻timeは文字列で指定する。
絶対時刻をさまざまな書式で指定できる。 この関数は、よく使われる日時の書式を受け付けるように努める。 正しい書式にはつぎの2つを含む。 year-month-day hour:min:sec timezone hour:min:sec timezone month/day/year ここで、どちらの例のフィールドもすべて数である。
相対時刻を指定するには、単位を伴った数字を使う。 たとえばつぎのとおり。
timeが数(整数か浮動小数点数)であれば、 秒単位の相対時刻を指定する。 引数repeatは、呼び出しをどの程度頻繁に繰り返すかを指定する。
repeatが ほとんどの場合、最初の呼び出しではrepeatの効果はなく、
timeだけが時刻を指定する。
1つ例外があり、timeが 関数 |
with-timeout (seconds timeout-forms...) body... | Macro |
bodyを実行するが、seconds秒でその実行を諦める。
時間が切れるまえにbodyが終了すると
with-timeout はbodyの最後のフォームの値を返す。
しかし、時間が切れるとbodyの実行を取り止め、
with-timeout はtimeout-formsをすべて実行し、
それらの最後の値を返す。
このマクロは、seconds秒後に動作するタイマを設定することで動作する。 その時間内にbodyが終了すれば、タイマを取り消す。 タイマが実際に動作するとbodyの実行を終了させてから、 timeout-formsを実行する。 プログラムから待つことが可能な基本関数を呼び出したときにのみ、
タイマはLispプログラム内で実行可能なため、
|
関数y-or-n-p-with-timeout
は、
応答を長く待ちすぎないようにタイマを使った単純な例です。
See Yes-or-No Queries。
run-with-idle-timer secs repeat function &rest args | Function |
Emacsがsecs秒間なにもしないときに実行するタイマを設定する。
secsの値は整数でも浮動小数点数でもよい。
repeatが 関数 |
Emacsがユーザー入力を待ち始めると『アイドル状態』になり、
なにか入力がくるまでアイドル状態のままです。
5秒間のアイドル状態で動作するタイマがあったとすると、
Emacsがアイドルになってから約5秒後にそのタイマが実行されます。
しかしrepeatが真(nil
以外)であったとしても、
そのタイマはEmacsがアイドル状態であり続ける限りは再実行されません。
アイドル状態の期間は単調に増加するので、再度5秒後には戻りません。
Emacsがアイドル状態のときにはさまざまなことを行います。 ガベッジコレクション、自動保存、サブプロセスからのデータの処理です。 しかし、アイドル状態中のこれらの動作はアイドルタイマに干渉しません。 アイドル状態の時間を0にしないからです。 600秒に設定されたアイドルタイマは、 最後のユーザーコマンドを終了してから10分後に実行されます。 たとえその10分間に、サブプロセスの出力を何千回も受け取ろうが、 ガベッジコレクションや自動保存を行ったとしてもです。
ユーザーが入力を与えると、その入力を実行中はEmacsは非アイドル状態です。 そして再度アイドル状態になり、 繰り返すように設定されたアイドルタイマを1つずつそれ以降に実行します。
cancel-timer timer | Function |
タイマtimerの予約を取り消す。
timerは、以前にrun-at-time や
run-with-idle-timer が返した値であること。
これは、run-at-time の呼び出しの効果を取り消し、
その時刻になってもなにも特別なことは起こらない。
|
本節では、端末入力を記録したり処理する関数や変数について述べます。 関連する関数についてはDisplayを参照してください。
set-input-mode interrupt flow meta quit-char | Function |
この関数は、キーボード入力を読み取るモードを設定する。
interruptがnil 以外であると、
Emacsは入力割り込みを用いる。
nil であると、CBREAKモードを用いる。
デフォルトの設定はシステムに依存する。
この指定に関わらずつねにCBREAKモードを用いるシステムもある。
EmacsがXと直接通信しているときは、 通信方法が割り込みであると承知していると この引数を無視して割り込みを使う。 flowが 引数metaは、文字コードが127を越える入力文字の扱い方を制御する。
metaが quit-charが |
関数current-input-mode
は、Emacsが現在使用している
入力モードの設定を返します。
current-input-mode | Function |
この関数は、キーボード入力を読み取るための現在のモードを返す。
set-input-mode の引数に対応する
(interrupt flow meta quit) の形の
リストを返す。
各要素の意味はつぎのとおりである。
|
本節では、入力イベントをキー列の一部になるまえに別の
入力イベントに変換する機能について述べます。
これらの機能は、ここに述べる順に各イベントに適用されます。
つまり、各イベントはまずextra-keyboard-modifiers
に従って修正され、
つぎに(適切ならば)keyboard-translate-table
を介して変換され、
最後に指定されているキーボードコーディングシステムで復号化されます。
キー列の一部として読み取られるイベントであると、
読み取られるキー列に追加され、それを含む部分キー列を
まずfunction-key-map
で検査してから、
つぎにkey-translation-map
で検査します。
extra-keyboard-modifiers | Variable |
この変数は、Lispプログラムがキーボード上の
修飾キーを『押す』ことができるようにする。
ユーザーがキーボードのキーを打つたびに、 ビットマスクで指定した修飾キーが押し下げられているかのように キーを修正する。 ウィンドウシステムを使っているときには、 プログラムは任意の修飾キーを『押す』ことができる。 さもなければ、<CTL>と<META>のキーのみを 仮想的に押すことができる。 |
keyboard-translate-table | Variable |
この変数は、キーボード文字の変換表である。
これにより、コマンドのバインディングを変更せずに、
キーボードのキー配置を変更できる。
その値は普通は文字テーブルであるか、あるいは、nil である。
つぎの例では、 (defun evade-flow-control () "Replace C-s with C-\ and C-q with C-^." (interactive) (setq keyboard-translate-table (make-char-table 'keyboard-translate-table nil)) ;; C-sとC-\を入れ換える (aset keyboard-translate-table ?\034 ?\^s) (aset keyboard-translate-table ?\^s ?\034) ;; C-qとC-^を入れ換える (aset keyboard-translate-table ?\036 ?\^q) (aset keyboard-translate-table ?\^q ?\036)) この変換は、端末から読み取った文字に最初に行われる変換である。
|
keyboard-translate from to | Function |
この関数は、文字コードfromを文字コードtoに変換するように
keyboard-translate-table を変更する。
必要ならばキーボード変換表を作成する。
|
残りの変換機能は、読み取ったキー列の部分列を変換します。
それらはread-key-sequence
に実装されていて、
read-event
で読む入力には効果はありません。
function-key-map | Variable |
この変数は、普通の文字端末上のファンクションキーが
送出する文字の列を記述したキーマップを保持する。
このキーマップは他のキーマップと同じ構造であるが、使い方が異なる。
キー列のバインディングではなく、
読み取りつつあるキー列を変換する方法を指定する。
たとえば、端末VT100は、キーパッドのキー<PF1>を押すと
<ESC> O Pを送出する。
したがって、Emacsではこの列を1つのイベント つまり、C-c <PF1>を打つと
文字の列C-c <ESC> O Pが送出される。
のちに関数 マイナモード/ローカル/グローバルのキーマップに矛盾するような
|
key-translation-map | Variable |
この変数は、function-key-map と同様に
入力イベントを別の入力イベントへ変換するために用いる別のキーマップである。
function-key-map とは2つの意味で異なる。
|
キーの『変換として』キー列のかわりに関数を用いると、
function-key-map
やkey-translation-map
は
単なる配置替え以上のことに使えます。
その関数で当該キーの変換を計算するのです。
キー変換関数は1つの引数を受け取ります。
その引数は、read-key-sequence
で指定されたプロンプトか、
エディタコマンドループがキー列を読み取っている場合にはnil
です。
多くの場合、プロンプトの値は無視できます。
関数自身が入力を読むときには、 後続のイベントを変更することもできます。 たとえば、後続の文字をハイパー文字にするC-c hの定義は つぎのようになります。
(defun hyperify (prompt) (let ((e (read-event))) (vector (if (numberp e) (logior (lsh 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))))) (define-key function-key-map "\C-ch" 'hyperify)
set-keyboard-coding-system
を用いた
キーボード文字集合の復号化を有効にしているときには、
上に述べた変換を終えてから復号化を行います。
See Specifying Coding Systems。
Emacsの将来の版では、他の変換のまえに復号化を行うでしょう。
recent-keys | Function |
この関数は、キーボードやマウスからの最近の100個の入力イベントを収めた ベクトルを返す。 キー列として使われたかどうかに関わらず、すべてのイベントを含む。 したがって、キーボードマクロで生成したイベントを数えずに 最後の100個のイベントをつねに得ることになる。 (キーボードマクロで生成したイベントを省くのは、 それらはデバッグにはあまり役立たないからである。 キーボードマクロを起動したイベントが見えれば十分なはずである。) |
open-dribble-file filename | コマンド |
この関数は、filenameという名前のドリブルファイル
(dribble file)をオープンする。
ドリブルファイルをオープンしていると、
(キーボードマクロを除く)キーボードやマウスからの各入力イベントを
そのファイルに書き出す。
文字でないイベントは、その表示表現を<...> で囲って表す。
ドリブルファイルをクローズするには、
引数に この関数は、バグ報告のために Emacsのバグを引き起こす入力を記録するために普通は使う。 (open-dribble-file "~/dribble") => nil |
関数open-termscript
(see Terminal Output)も
参照してください。
端末出力関数は、端末に出力を送ったり、
端末へ送った出力を記録します。
変数baud-rate
は、Emacsが考えている端末の出力速度を表します。
baud-rate | Variable |
この変数の値は、Emacsが関知する端末の出力速度である。
この変数に設定しても実際のデータ転送速度を変更しないが、
その値はパディングなどの計算に用いられる。
また、ウィンドウシステムを使っている場合であっても、
スクリーンのどの部分をスクロールするか、
あるいは、再描画するかの決定に影響する。
(このような決定を調整する方法を与えるために、
ウィンドウシステムには真の『出力速度』はないがこのように設計した。)
値の単位はボー(baud)である。 |
ネットワーク経由で使い、
ネットワークの異なる部分が異なる速度で動いているときには、
Emacsが返す値はローカル端末で使っている場合の値と異なるかもしれません。
リモートマシンへの通信速度でローカル端末と通信する
ネットワークプロトコルもあり、
そのような場合、Emacsや他のプログラムは正しい値を得られます。
その他の場合では正しい値を得られません。
Emacsの値がまちがっているときには、
あまり最適でない決定をくだすでしょう。
この問題を修正するには、baud-rate
に設定します。
baud-rate | Function |
この廃れた関数は、変数baud-rate の値を返す。
|
send-string-to-terminal string | Function |
この関数は、なにも変更せずに文字列stringを端末へ送る。
string内のコントロール文字は、端末に依存する効果を持つ。
この関数の1つの用途は、ファンクションキーの定義を ダウンロード可能な端末のファンクションキーを定義することである。 たとえば、ファンクションキー4を(文字の列C-u C-fを 計算機に送って)4文字進めると定義にするには、 特定の端末ではつぎのようにする。 (send-string-to-terminal "\eF4\^U\^F") => nil |
open-termscript filename | コマンド |
この関数は、Emacsが端末へ送出するすべての文字を記録する
タームスクリプトファイル(termscript file)を
オープンするために使う。
関数はnil を返す。
タームスクリプトファイルは、
Emacsがスクリーンを乱してしまう問題、
誤ったtermcap定義やEmacsの実際のバグではない端末の望ましくない設定の
問題を調べるのに有用である。
どのような文字の列が実際に出力されるか確信できれば、
それらが使用中のtermcapのどの定義に対応するか調べられる。
Terminal Inputのopen-dribble-file も参照。
(open-termscript "../junk/termscript") => nil |
システム固有のX11のキーシンボル(keysym)を定義するには、
変数system-key-alist
に設定します。
system-key-alist | Variable |
この変数の値は、各要素がシステム固有の
各キーシンボルに対応する連想リストであること。
要素は(code . symbol) の形である。
ここで、codeは(『提供業者固有の』ビット
含まない)数値のキーシンボルコードであり、
symbolはファンクションキーの名前である。
たとえば、 実際に使用しているXサーバーのキーシンボルと衝突しなければ、 他のXサーバー向けのキーシンボルを連想リストから省かなくても問題ない。 変数は現在の端末につねにローカルであり、 バッファローカルにはなりえない。 see Multiple Displays。 |
本節では、
『Emacsがなぜコマンド文字集合の中からフロー制御文字を使うのか?』という
質問に答えたいと思います。
この話題に関する別の視点については、
配布に含まれるファイルemacs/INSTALL
の中の
フロー制御に関する記述を読んでください。
termcapの定義とDECの端末集線器については、
emacs/etc/TERMS
を参照してください。
ある時期には、ほとんどの端末ではフロー制御を行っておらず、
C-s
とC-qをフロー制御に用いるものもありませんでした。
したがって、コマンド文字としてC-s
とC-qを選ぶことは
自然であり議論の余地はありませんでした。
キーに割り付けるべきコマンドがたくさんあったので、
ほとんどすべてのASCIIコントロール文字に意味を与えました。
のちに、フロー制御にこれらの文字を必要とする端末が導入されたのです。 それらはフルスクリーンエディタ向きの端末ではなかったので、 Emacsの保守陣はそれらを無視しました。 後年、C-sとC-qによるフロー制御が 端末で広く使われるようになりましたが、当時はそれはオプションでした。 Emacsユーザーの多くはフロー制御をオフにして、 フロー制御のために無意味なキーバインディングに 替えようとはしなかったのです。
Emacsと端末や集線器の製造業者のどちらの使い方が『正しい』でしょう?
この問に簡単な答えはありません。
C-sとC-qで引き起こされる問題を解消するのに 気が進まないのは、C-sとC-qであることに理由がないからです。 文字ストリームに透過な別の(実用上一般的ではないが) フロー制御技術があります。 さらに、それらをフロー制御に使うのは正式な規格ではありません。 興味深いことですが、(1970年ころの)紙テープパンチャ付きの テレタイプモデル33では、計算機からパンチャをオン/オフするために C-sとC-qを送っていました!
ウィンドウシステムやPC端末エミュレータが文字端末を置き換えるようになり
フロー制御の問題は徐々に解消しつつあります。
しばらくは、読者が望むならEmacsはフロー制御を
オンにする手軽な方法を提供します。
関数enable-flow-control
を呼び出すのです。
enable-flow-control | コマンド |
この関数は、出力のフロー制御にC-sとC-qを
使うようにするとともに、keyboard-translate-table
(see Translating Input)を用いて
C-\とC-^をそれらのかわりに使えるようにする。
|
読者のファイル.emacs
で関数enable-flow-control-on
を使えば、
特定の種類の端末で自動的にフロー制御をオンにできます。
enable-flow-control-on &rest termtypes | Function |
この関数は、端末の種類がtermtypesの1つであると、
フロー制御をオンにしC-\とC-^をかわりに使う。
たとえば、つぎのように使う。
(enable-flow-control-on "vt200" "vt300" "vt101" "vt131") |
enable-flow-control
が行う処理はつぎのとおりです。
(set-input-mode nil t)
で
端末入力をCBREAKモードに設定し、
オペレーティングシステムにフロー制御を行うように指示する。
keyboard-translate-table
を設定する。
非常に下位レベルであることを除けば、
EmacsはC-sやC-qを打ったと考えるので、
たとえ他のコマンドに対してもC-\やC-^を打ったとしても
実質的にはC-sやC-qを打ったことになる。
see Translating Input。
端末側がフロー制御文字を発行するのであれば、
カーネルのフロー制御処理をオンにすれば、
その端末に対する普通のパディングより少なくしても動作するはずです。
termcapの定義をカスタマイズしてパディング量を減らします。
あるいは、baud-rate
に小さめの値を設定すると、
パディングの必要量の計算にEmacsは低い速度を使います。
See Terminal Output。
コマンド行オプション-batch
は、
Emacsを非対話的に実行します。
このモードでは、Emacsは端末からコマンドを読まず、
端末のモードを変更せず、スクリーンに出力もしません。
これは、実行するLispプログラムを指定できるようにするためです。
それが終るとEmacsも終了します。
実行すべきプログラムは、
fileという名前のライブラリをロードする-l file
、
および、
引数なしで関数functionを呼び出す-f function
で
指定します。
バッチモードでは、ストリームとしてt
を指定した
message
やprin1
などでエコー領域に
表示されるLispプログラムの出力は、
Emacsの標準エラー記述子へ出力されます。
したがって、Emacsは非対話的な
アプリケーションプログラムのようにふるまいます。
(コマンドの表示などのEmacs自身がエコー領域に出力するものは
完全に抑制される。)
noninteractive | Variable |
この変数は、Emacsがバッチモードで動作しているとnil 以外である。
|
本章では、Emacsがユーザーに提示する画面表示に関連する さまざまな機能について述べます。
関数redraw-frame
は、指定したフレーム(see Frames)の
内容全体を再表示します。
redraw-frame frame | Function |
この関数は、フレームframeをクリアしてから再表示する。 |
より強力なのはredraw-display
です。
redraw-display | コマンド |
この関数は、すべての可視フレームをクリアしてから再表示する。 |
ユーザー入力の処理のほうが再表示より絶対的に優先します。 入力があるときにこれらの関数を呼び出してもただちにはなにもしませんが、 入力をすべて処理し終えてから再表示します。
通常、Emacsを停止したり再開しても スクリーン全体を再表示します。 Emacsのようなディスプレイ向けプログラムと通常の逐次表示向けに、 表示内容を個別に記録できる端末エミュレータもあります。 そのような端末を使っているときには、 再開時の再表示を禁止した場合もあります。
no-redraw-on-reenter | Variable |
この変数は、停止後に再開したあとで、
スクリーン全体を再表示するかどうかを制御する。
nil 以外であると再描画の必要はないことを意味し、
nil であると再描画が必要であることを意味する。
デフォルトはnil である。
|
テキスト行がウィンドウの右端を越えていると、
その行をつぎのスクリーン行へ継続するか、
スクリーン行1行に切り詰めます。
長いテキスト行を表示するために使われる追加のスクリーン行を
継続行と呼びます。
通常、ウィンドウの最右端のコラムに現れる$
で切り詰めたことを示し、
\
でつぎの行に『折り返した』こと、
つまり、継続している行であることを示します。
(表示テーブルで別の文字を指定できる。
Display Tablesを参照。)
継続することと詰め込みは別のことです。 継続はスクリーン上だけのことであり、バッファ内容は変わりません。 また、継続では単語の境界ではなく、正確にスクリーンの右端で 行を分けます。 See Filling。
truncate-lines | User Option |
このバッファローカルな変数は、
ウィンドウの右端を越える行をどのように表示するかを制御する。
デフォルトはnil であり継続を意味する。
値がnil 以外であると、そのような行を切り詰める。
変数 |
default-truncate-lines | User Option |
この変数は、truncate-lines のバッファローカルな値を持たない
バッファ向けのtruncate-lines のデフォルト値である。
|
truncate-partial-width-windows | User Option |
この変数は、左右に並んだウィンドウ(see Splitting Windows)において、
ウィンドウの右端を越える行の表示を制御する。
nil 以外であると、そのような行を切り詰める。
さもなければ、truncate-lines に従って表示する。
|
ウィンドウで水平方向にスクロールしている(see Horizontal Scrolling)と、 強制的に切り詰めます。
継続や切り詰めを表す文字は、表示テーブルを使って変更できます。 See Display Tables。
バッファにとても長い行があるときにそれらの表示に継続行を使うと、
それによりEmacsの再表示が遅くなります。
コラム計算や字下げ関数も遅くなります。
そのような場合には、cache-long-line-scans
にt
を
設定するのがよいです。
cache-long-line-scans | Variable |
この変数がnil 以外であると、
字下げ/移動関数とEmacsの再表示において、
バッファを走査した結果をキャッシュし、
バッファが変更されていないときには
キャッシュを調べてバッファの対象領域の再走査を回避する。
キャッシュするようにすると、短い行の処理が多少遅くなる。 この変数は、すべてのバッファで自動的にバッファローカルである。 |
エコー領域(echo area)は、
基本関数message
でメッセージを表示したり、
打鍵を表示するために使われます。
(活性な)ミニバッファはエコー領域と
同じスクリーン上の位置に現れますが、
エコー領域とミニバッファは同じものではありません。
GNU Emacs マニュアルには、
エコー領域とミニバッファがスクリーンの同じ箇所を使う際の
衝突を回避する規則が述べてあります
(see Minibuffer)。
エラーメッセージもエコー領域に現れます。
See Errors。
エコー領域に表示するには、
ストリーム(see Output Functions)として
t
を指定したLisp表示関数を使うか、あるいはつぎのようにします。
message string &rest arguments | Function |
この関数は、エコー領域に1行のメッセージを表示する。
引数stringは、言語Cのprintf の制御文字列と同様である。
書式指定について詳しくは、String Conversionの
format を参照。
message は構築した文字列を返す。
バッチモードでは、 stringが (message "Minibuffer depth is %d." (minibuffer-depth)) -| Minibuffer depth is 0. => "Minibuffer depth is 0." ---------- Echo Area ---------- Minibuffer depth is 0. ---------- Echo Area ---------- |
message-or-box string &rest arguments | Function |
この関数はmessage と同様にメッセージを表示するが、
エコー領域のかわりに対話ボックスを使うこともある。
この関数がマウスを用いて起動されたコマンドから呼ばれたとき、
より正確には、last-nonmenu-event (see Command Loop Info)が
nil かリストのいずれかであると、
メッセージを表示するために対話ボックスかポップアップメニューを用いる。
さもなければエコー領域を用いる。
(これは、同様な決定をくだすy-or-n-p の判定条件と同じである。
see Yes-or-No Queries。)
呼び出しの周りで |
message-box string &rest arguments | Function |
この関数はmessage と同様にメッセージを表示するが、
可能な限り対話ボックス(やポップアップメニュー)を使う。
対話ボックスやポップアップメニューを扱えない端末などで
これらを使用できない場合には、
message-box はmessage と同様にエコー領域を使う。
|
current-message | Function |
この関数は、エコー領域に現在表示されているメッセージを返す。
なければnil を返す。
|
cursor-in-echo-area | Variable |
この変数は、エコー領域にメッセージを表示しているときに
カーソルをどこに表示するかを制御する。
nil 以外であると、メッセージの末尾にカーソルを表示する。
さもなければ、エコー領域にではなく、ポイント位置にカーソルを表示する。
この値は普通は |
echo-area-clear-hook | Variable |
このノーマルフックは、(message nil) や他の理由で
エコー領域をクリアするたびに実行される。
|
エコー領域に表示したほとんどすべてのメッセージは
バッファ*Messages*
にも記録されます。
message-log-max | User Option |
この変数は、バッファ*Messages* に保持する行数を指定する。
値t は、保持する行数を制限しないことを意味する。
値nil は、メッセージをまったく記録しないことを意味する。
メッセージを表示しつつそれを記録しないようにするには
つぎのようにする。
(let (message-log-max) (message ...)) |
echo-keystrokes | Variable |
この変数は、コマンド文字を表示するまでの経過時間を決定する。
この値は整数であり、表示し始めるまでに待つ秒数を指定する。
ユーザーが(C-xなどの)プレフィックスキーを打ってから
つぎを打つまでにこの秒数だけ遅れがあると、
プレフィックスキーをエコー領域に表示する。
(いったんキー列の表示を始めると、
同じキー列の以降の文字すべてを表示する。)
値がゼロであると、コマンド入力を表示しない。 |
属性invisible
で文字群を不可視にできます。
つまり、それらをスクリーンに表示されないようにするのです。
テキスト属性(see Text Properties)か
オーバレイの属性(see Overlays)を使います。
もっとも単純な場合、
属性invisible
がnil
以外であると文字は見えなくなります。
これはデフォルトの場合、つまり、
buffer-invisibility-spec
のデフォルト値を変更していない場合であり、
このようにして属性invisible
は動作します。
より一般的には、変数buffer-invisibility-spec
を使って、
属性invisible
のどの値のものを不可視なテキストにするかを制御できます。
つまり、invisible
の異なる値を与えて
テキストをあらかじめいくつかのグループに分類しておき、
そのあとでbuffer-invisibility-spec
の値を変更して
さまざまなグループを可視/不可視にします。
buffer-invisibility-spec
で可視性を制御することは、
データベースの項目の一覧を表示するようなプログラムで特に有用です。
データベースの特定の項目だけを見るための
便利なフィルタコマンドを実装できます。
この変数に設定するのはとても速くでき、
変更すべき属性を探すためにバッファ内の全テキストを走査するよりも速いのです。
buffer-invisibility-spec | Variable |
この変数は、属性invisible のどの種類を実際に
不可視な文字にするかを指定する。
|
buffer-invisibility-spec
に要素を追加したり削除するために
2つの関数が特別にあります。
add-to-invisibility-spec element | Function |
(リストにelementが既存でなければ)
buffer-invisibility-spec に要素elementを追加する。
|
remove-from-invisibility-spec element | Function |
buffer-invisibility-spec から要素elementを削除する。
|
buffer-invisibility-spec
の使い方の慣習の1つに、
メジャーモードでは
buffer-invisibility-spec
の1要素と属性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)
普通、テキストを操作したりポイントを移動するコマンドは、
テキストの可視性に注意しません。
ユーザーレベルの移動コマンドは、
line-move-ignore-invisible
がnil
以外であれば
不可視な改行を明示的に無視しますが、
それはそのように明示的にプログラムしてあるからにすぎません。
インクリメンタルサーチでは、
不可視なテキストを含む一致箇所では、
不可視なオーバレイを一時的にあるいは恒久的に可視にできます。
これを可能にするには、オーバレイの属性isearch-open-invisible
が
nil
以外である必要があります。
その属性の値は、オーバレイを引数として呼ばれる関数である必要があります。
その関数がオーバレイを恒久的に可視にします。
その関数は、探索から抜けるときに一致箇所が
オーバレイにまたがっているときに使われます。
探索中には、そのようなオーバレイは、
それらの属性invisible
とintangible
を一時的に変更することで
一時的に可視にされます。
特定のオーバレイに対して異なる扱いをしたければ、
属性isearch-open-invisible-temporary
に関数を与えておきます。
その関数は2つの引数で呼ばれます。
第1引数はオーバレイ、
第2引数は、オーバレイを可視にするt
、あるいは、
オーバレイを再度不可視にするnil
です。
選択表示とは、 スクリーン上の特定の行を隠すための関連する機能対を指します。
最初の変種は、明示的な選択表示で、 Lispプログラムで使用するために設計されています。 テキストを変更することでどの行を隠すかを制御します。 テキストを不可視にする機能(see Invisible Text)は、 この機能で部分的に置き換えてあります。
2番目の変種は、字下げに基づいて自動的に隠す行を選択します。 この変種は、ユーザーレベルの機能であるように設計されています。
明示的な選択表示を制御するには、 改行(コントロールJ)を復帰(コントロールM)に置き換えます。 置換前の改行に続いていたそれまでの行は見えなくなります。 厳密にいえば、改行だけが行を区切るため、 一時的にはもう行ではなくなっているのです。 つまり、先行する行の一部になっているのです。
選択表示は、編集コマンドに直接には影響しません。
たとえば、C-f(forward-char
)は
躊躇なく不可視なテキストの中へポイントを移動します。
しかし、改行文字を復帰文字に置換すると
影響を受ける編集コマンドもあります。
たとえば、next-line
は、
改行だけを探すため不可視な行を飛び越してしまいます。
選択表示を使用するモードでは、
改行を考慮するようにコマンドを定義したり、
テキストの一部を可視/不可視にするコマンドを定義できます。
選択表示しているバッファをファイルに書き出すときには、 すべてのコントロールM(復帰)は改行として出力されます。 つまり、つぎにファイルを読み込むと不可視なものはなく、 普通に見えるのです。 選択表示の効果は、Emacsの内側だけで見えるのです。
selective-display | Variable |
このバッファローカルな変数は、選択表示をオンにする。
つまり、行や行の一部を不可視にできる。
バッファのある部分が不可視であると、
垂直方向に移動するコマンドは、
その部分が存在しないがごとく動作し、
1つのコマンド つぎの例では、 (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 ---------- |
selective-display-ellipses | Variable |
このバッファローカルな変数がnil 以外であると、
不可視なテキストが続く行末に... を表示する。
つぎの例は、上の例の続きである。
(setq selective-display-ellipses t) => t ---------- Buffer: foo ---------- 1 on this column 2on this column ... 2on this column 1 on this column ---------- Buffer: foo ---------- 表示テーブルを使って |
オーバレイ矢印(overlay arrow)は、 バッファの特定の行にユーザーの注意を向けるために有用です。 たとえば、デバッガとのインターフェイスを取るためのモードでは、 オーバレイ矢印で実行するコードの行を示します。
overlay-arrow-string | Variable |
この変数は、特定の行に注意を向けるために表示する文字列を保持する。
矢印機能を使っていなければnil である。
|
overlay-arrow-position | Variable |
この変数は、オーバレイ矢印を表示する箇所を表すマーカを保持する。
行頭を指すこと。
矢印のテキストはその行の先頭に現れ、
その場所に本来現れるべきテキストを隠す。
矢印は普通は短く、行には字下げがあるので、
重要なものは普通はなにも上書きされない。
オーバレイ文字列は、マーカが指すバッファでのみ表示される。 したがって、ある時点では、1つのバッファだけにオーバレイ矢印を表示できる。 |
同様のことは、属性before-string
のオーバレイを
作成してもできます。
See Overlay Properties。
一時的な表示は、 出力をバッファに置き編集目的にではなく ユーザーに読むように提示するために Lispプログラムが使います。
with-output-to-temp-buffer buffer-name forms... | Special Form |
この関数は、buffer-nameという名前のバッファに
formsの任意の出力が挿入されるように準備して
formsを実行する。
そのバッファは適当なウィンドウに表示されるが、
そのバッファは選択されない。
文字列buffer-nameは、既存である必要はない一時的なバッファを指定する。
引数は、バッファではなく文字列であること。
(問い合わせずに)はじめにバッファを消去し、
formsの最後のフォームの値を返す。 ---------- 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 ---------- |
temp-buffer-show-function | Variable |
この変数がnil 以外であると、
ヘルプバッファを表示するために
with-output-to-temp-buffer がこの値を関数として呼び出す。
関数は1つの引数、つまり、表示すべきバッファを受け取る。
この関数では、
|
temp-buffer-show-hook | Variable |
このノーマルフックは、ヘルプバッファを表示後に
with-output-to-temp-buffer が実行する。
フックを実行するときには、
ヘルプバッファがカレントバッファであり、
それを表示しているウィンドウが選択されているウィンドウである。
|
momentary-string-display string position &optional char message | Function |
この関数は、カレントバッファ内の位置positionに
文字列stringを瞬間的に表示する。
アンドゥリストやバッファの変更状態には影響しない。
瞬間的な表示は、つぎの入力イベントまで持続する。
つぎの入力イベントがcharであると、
文字列stringにコントロール文字が含まれなければ、
属性 messageが つぎの例では、ポイントは始めは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 ---------- |
ユーザーに提示するためにスクリーン上でのバッファのテキストの見た目を 変えるためにオーバレイ(overlay)を使えます。 オーバレイは、特定のバッファに属するオブジェクトであり、 指定された開始位置と終了位置があります。 また、調べたり設定できる属性もあります。 これらの属性は、オーバレイの内側のテキストの表示に影響します。
オーバレイ属性はある意味でテキスト属性に似ていて、 どちらの属性でも文字の表示方法を変更できます。 しかし、多くの点で異なります。 テキスト属性は、テキストの一部であるとみなされますが、 オーバレイはテキストの一部とはみなしません。 したがって、さまざまなバッファや文字列のあいだでテキストをコピーしても テキスト属性は保存されますが、オーバレイは保存されません。 バッファ内のテキスト属性を変更するとバッファを変更済みと印を付けますが、 オーバレイを移動したりその属性を変更しても バッファの変更とは考えません。 テキスト属性の変更と異なり、 オーバレイの変更はバッファのアンドゥリストには記録されません。 比較のためにSee Text Properties。
priority
priority
の値の大きなものが他に優先し、
そのフェイス属性が他の低い順位の属性のフェイス属性に優先する。
現在、すべてのオーバレイ属性はテキスト属性に優先する。
負の優先順位の意味を決めかねているので、負の優先順位は避けてほしい。
window
window
がnil
以外であると、
オーバレイをそのウィンドウだけに適用する。
category
category
があると、
それをオーバレイのカテゴリ(category)と呼ぶ。
これはシンボルであること。
シンボルの属性がオーバレイの属性のデフォルトの役割を果たす。
face
属性値がリストであると、その要素は、
(foreground-color . color-name)
か
(background-color . color-name)
の形でもよい。
これらの要素は、前景色だけや背景色だけを指定する。
したがって、使用する各色を表すフェイスを作成する必要はない。
mouse-face
face
のかわりに使われる。
modification-hooks
フック関数は、各変更の前後に呼び出される。 関数が受け取った情報を保存し呼び出しごとに比較すれば バッファテキストにどのような変更が行われたかを正確に判定できる。
変更前に呼ばれるときには、各関数は4つの引数を受け取る。
オーバレイ、nil
、変更対象のテキスト範囲の先頭と末尾である。
変更後に呼ばれるときには、各関数は5つの引数を受け取る。
オーバレイ、t
、変更済みのテキスト範囲の先頭と末尾、
その範囲の変更前のテキストの長さである。
(挿入では変更前の長さはゼロである。
削除では変更前の長さは削除された文字数であり、
変更後の先頭位置と末尾位置は同じである。)
insert-in-front-hooks
modification-hooks
の関数群と同じである。
insert-behind-hooks
modification-hooks
の関数群と同じである。
invisible
invisible
は、オーバレイ内のテキストを不可視にする。
つまり、それらはスクリーン上に現れない。
詳しくは、see Invisible Text。
intangible
intangible
は、オーバレイにおいて
テキスト属性intangible
と同様に働く。
詳しくは、see Special Properties。
isearch-open-invisible
isearch-open-invisible-temporary
before-string
after-string
evaporate
nil
以外であると、
オーバレイが空に(つまり覆う文字がなく)なると、
自動的にオーバレイを削除する。
local-map
nil
以外であると、当該部分のテキストに対する
キーマップを指定する。
ポイントの直後の文字がオーバレイに入っていると、
属性の値はバッファローカルなキーマップに置き換わる。
see Active Keymaps。
つぎは、オーバレイの属性を読み書きするための関数です。
overlay-get overlay prop | Function |
この関数は、オーバレイoverlayに記録されている
属性propの値をあれば返す。
overlayにそのような属性に対する値が記録されていなくても、
属性category がありそれがシンボルであれば、
そのシンボルの属性propを使う。
さもなければ値はnil である。
|
overlay-put overlay prop value | Function |
この関数は、オーバレイoverlayに属性propの値として valueを設定する。 valueを返す。 |
与えられた文字のオーバレイ属性とテキスト属性の両方を調べる 関数codeget-char-propertyも参照してください。 See Examining Properties。
本節では、オーバレイを作成、削除、移動したり、 それらの内容を調べる関数について述べます。
make-overlay start end &optional buffer front-advance rear-advance | Function |
この関数は、バッファbufferに属する
startからendまでを覆うオーバレイを作成しそれを返す。
startとendのどちらもバッファ内位置を指定する
整数かマーカであること。
bufferを省略すると、カレントバッファにオーバレイを作成する。
引数front-advanceとrear-advanceは、 オーバレイの開始位置と終了位置における挿入型を指定する。 see Marker Insertion Types。 |
overlay-start overlay | Function |
この関数は、オーバレイoverlayの開始位置を整数で返す。 |
overlay-end overlay | Function |
この関数は、オーバレイoverlayの終了位置を整数で返す。 |
overlay-buffer overlay | Function |
この関数は、オーバレイoverlayが属するバッファを返す。 |
delete-overlay overlay | Function |
この関数は、オーバレイoverlayを削除する。
Lispオブジェクトとしてはオーバレイは存在し続けるが、
それが属したバッファとの対応付けは消失し、
表示上の効果もなくなる。
削除したオーバレイは恒久的に無意味ではない。
|
move-overlay overlay start end &optional buffer | Function |
この関数は、オーバレイoverlayをバッファbufferに移し、
startからendを覆うようにする。
startとendのどちらもバッファ内位置を指定し、
整数かマーカである。
bufferを省略すると、オーバレイは同じバッファに留まる。
戻り値はoverlayである。 これは、オーバレイの端を変更する唯一の正しい方法である。 オーバレイのマーカを手で修正しようとしないこと。 他の重要なデータ構造を更新しそこない、 いくつかのオーバレイを『失う』ことにもなりかねない。 |
overlays-at pos | Function |
この関数は、カレントバッファの位置posを覆うすべての オーバレイのリストを返す。 このリスト内の順番に意味はない。 オーバレイが位置posかそのまえで始まり、かつ、 位置posかそのうしろで終るときに、 オーバレイは位置posを覆う。 |
overlays-in beg end | Function |
この関数は、begからendまでの領域と 重なり合っているすべてのオーバレイのリストを返す。 『重なり合っている』とは、 少なくとも1文字がオーバレイに覆われていて、かつ、 その文字が指定された領域に入っていることを意味する。 しかし、空のオーバレイであっても それがbegにあるかbegとendのあいだにあれば、 空のオーバレイも結果に含まれる。 |
next-overlay-change pos | Function |
この関数は、位置posのうしろにある オーバレイのつぎの開始位置か終了位置を返す。 |
previous-overlay-change pos | Function |
この関数は、位置posのまえにある オーバレイのまえの開始位置か終了位置を返す。 |
すべての文字が同じ表示幅ではありませんから、 これらの関数で文字の表示幅を検査できます。 関連する関数については、Primitive IndentとSee Screen Lines
char-width char | Function |
この関数は、文字charを選択されているウィンドウで カレントバッファに表示した場合のコラム幅を返す。 |
string-width string | Function |
この関数は、文字列stringを選択されているウィンドウで カレントバッファに表示した場合のコラム幅を返す。 |
truncate-string-to-width string width &optional start-column padding | Function |
この関数は、幅widthに収まる文字列stringの部分を
新たな文字列として返す。
stringが幅widthに満たない場合、 stringの終りで結果は終る。 string内の1つの複数コラム文字がコラムwidthを越える場合には、 その文字は結果に含めない。 したがって、結果はwidthより短くなりえるがそれを越えることはない。 省略可能な引数start-columnは、開始コラムを指定する。
これが 省略可能な引数paddingが (truncate-string-to-width "\tab\t" 12 4) => "ab" (truncate-string-to-width "\tab\t" 12 4 ?\ ) => " ab " |
フェイス(face)とは、図形的な属性、つまり、 フォント、前景色、背景色、下線 の名前付きの集合体です。 フェイスはスクリーン上のテキストの表示を制御します。
各フェイスには固有のフェイス番号(face number)があり、 Emacs内部の下位レベルでフェイスを区別するために使われます。 しかし、ほとんどの目的には、 Lispプログラムでは名前でフェイスを参照できます。
facep object | Function |
この関数は、objectがフェイスを指名するシンボル
(あるいは、フェイスデータを記録するために内部的に使われる種類のベクトル)
であるとt を返す。
さもなければnil を返す。
|
各フェイス名はすべてのフレームで有効であり、 デフォルトではすべてのフレームで同じ意味を持ちます。 しかし、望みの1つのフレームで特定のフェイス名に 特定の意味を持たせることもできます。
defface
.
つぎの表はすべての標準フェイスとその用途です。
default
modeline
region
secondary-selection
highlight
underline
bold
italic
bold-italic
新たなフェイスを定義する方法は、defface
を使うことです。
これは、カスタマイズバッファ
(see Easy Customization)
を用いてユーザーがカスタマイズできる
カスタマイズ項目(see Customization)の一種を作成します。
defface face spec doc [keyword value]... | Macro |
specに従ったデフォルトを持つカスタマイズ可能なフェイスとして
faceを宣言する。
シンボルfaceをクォートしないこと。
引数docは、フェイスの説明文字列を指定する。
specの目的は、異なる種類の端末でフェイスがどのような
見た目になるかを指定することである。
specの要素のdisplay部分は、要素を適用するフレームを決定する。 specの1つより多くの要素が指定されたフレームに一致する場合、 そのフレームに一致した最初の要素だけを用いる。 displayには2つの可能性がある。
|
標準フェイスregion
をdefface
で
定義するとつぎのようになります。
(defface region ((((class color) (background dark)) (:background "blue")) (t (:background "gray"))) "Used for displaying the region.")
内部的にはdefface
は、
defface
に指定されたフェイス属性の記録には
シンボルの属性face-defface-spec
、
カスタマイズバッファでユーザーが保存した属性の記録には
saved-face
、
説明文字列の記録にはface-documentation
を使います。
frame-background-mode | User Option |
このオプションがnil 以外であると、
フェイスの定義を解釈する際に用いる背景の型を指定する。
これがdark であると、
実際の背景色に関わらずEmacsはすべてのフレームの背景は暗いとみなす。
これがlight であると、
Emacsはすべてのフレームの背景は明るいとみなす。
|
テキストの表示に使用するフェイスを指定する方法はつぎのとおりです。
face
を持てる。
それがある場合、そのフェイスで表示される。
see Special Properties。
文字に属性mouse-face
がある場合は、
マウスが文字に『十分近い』ときには属性face
のかわりにそれを使う。
face
やmouse-face
を持てる。
そのオーバレイが覆うすべてのテキストに適用される。
region-face
を参照)
で強調表示する。
ある文字に対してこれらのさまざまな指定が 1つより多くのフェイスを指定する場合、 Emacsは指定されたさまざまなフェイスの属性を併合します。 特別な字形のフェイスが最初です。 適切ならば、つぎはリージョンの強調表示のフェイスです。 そのつぎはオーバレイのフェイスの属性、 さらにテキスト属性のフェイスが続き、 最後はデフォルトのフェイスです。
複数のオーバレイが1つの文字を覆う場合、 高い優先順位のオーバレイが低いものに優先します。 See Overlays。
フォントや表示色のような属性がうえのどれでも指定されていない場合には、 フレーム独自のフォントや表示色を使います。
フェイスの属性で指定できるのは、フォント、前景色、背景色、下線です。
フェイスでは値nil
を指定することでこれらを未指定にできます。
以下は、フェイスを作成したり変更する基本関数です。
make-face name | Function |
この関数は、すべての属性をnil とした
nameという名前の新たなフェイスを定義する。
nameという名前のフェイスが既存ならばなにもしない。
|
face-list | Function |
この関数は、定義済みのすべてのフェイス名のリストを返す。 |
copy-face old-face new-name &optional frame new-frame | Function |
この関数は、既存のold-faceという名前のフェイスのコピーとして
フェイスnew-nameを定義する。
new-nameが既存でなければ、フェイスnew-nameを作成する。
省略可能な引数フレームframeを指定すると、 この関数はそのフレームだけに適用する。 さもなければ、各フレームにおいて個別に、 そのフレームのold-faceの属性を 同じフレームのnew-faceにコピーする。 省略可能な引数フレームnew-frameを指定すると、
|
以下の関数を使って既存のフレームの属性を変更できます。 フレームframeを指定すると、そのフレームだけに影響します。 さもなければ、新たなフレームに適用されるデフォルトに加えて すべてのフレームに影響します。
set-face-foreground face color &optional frame | Function |
set-face-background face color &optional frame | Function |
これらの関数は、フェイスfaceの前景色(あるいは背景色)として
colorを設定する。
引数colorは、表示色名の文字列であること。
白黒スクリーンでは、濃淡は点猫パターンで実現する。 |
set-face-stipple face pattern &optional frame | Function |
この関数は、フェイスfaceの背景点猫パターンとして
patternを設定する。
引数patternは、Xサーバーで定義された背景点猫パターンの名前であること。
あるいは、点猫を使わないことを意味するnil であること。
白黒階調の特定の濃淡を扱うために自動的に点猫パターンを使うため、 普通は点猫パターンに注意する必要はない。 |
set-face-font face font &optional frame | Function |
この関数は、フェイスfaceのフォントを設定する。 引数fontは、読者のシステムの正しいフォント名か Emacsのフォントセット名(see Fontsets)の文字列であること。 フォントを明示的に設定するとつねに正確にそれを使うため、 太字(bold)や斜体(italic)の属性の効果は消失することに注意。 |
set-face-bold-p face bold-p &optional frame | Function |
この関数は、フェイスfaceの太字(bold)の属性を設定する。
nil 以外は太字あり、nil は太字なしを意味する。
|
set-face-italic-p face italic-p &optional frame | Function |
この関数は、フェイスfaceの斜体(italic)の属性を設定する。
nil 以外は斜体あり、nil は斜体なしを意味する。
|
set-face-underline-p face underline-p &optional frame | Function |
この関数は、フェイスfaceの下線の属性を設定する。
nil 以外は下線あり、nil は下線なしを意味する。
|
invert-face face &optional frame | Function |
フェイスfaceの前景色と背景色を入れ換える。 フェイスに前景色と背景色の両者が設定されていないと、 その前景色と背景色にはデフォルトの背景色と前景色を設定する。 |
つぎの関数は、フェイスの属性を調べます。 フレームframeを指定しない場合、 新たなフレーム向けのデフォルトのデータを参照します。
face-foreground face &optional frame | Function |
face-background face &optional frame | Function |
この関数は、フェイスfaceの前景色(あるいは背景色)を 文字列で返す。 |
face-stipple face &optional frame | Function |
この関数は、フェイスfaceの背景点猫パターンの名前を返す。
なければnil を返す。
|
face-font face &optional frame | Function |
この関数はフェイスfaceのフォントの名前を返す。 |
face-bold-p face &optional frame | Function |
この関数はフェイスfaceの太字(bold)属性を返す。 |
face-italic-p face &optional frame | Function |
この関数はフェイスfaceの斜体(italic)属性を返す。 |
face-underline-p face &optional frame | Function |
この関数はフェイスfaceの下線属性を返す。 |
face-id face | Function |
この関数はフェイスfaceのフェイス番号を返す。 |
face-documentation face | Function |
この関数はフェイスfaceの説明文字列を返す。
なければnil を返す。
|
face-equal face1 face2 &optional frame | Function |
この関数は、フェイスface1とface2が
表示上の同じ属性を持てばt を返す。
|
face-differs-from-default-p face &optional frame | Function |
この関数は、フェイスfaceの表示がデフォルトのフェイスの表示と
異なる場合にはt を返す。
フェイスの各属性がデフォルトフェイスの対応する属性に等しいか
(デフォルトから継承すること意味する)nil であると、
フェイスはデフォルトのフェイスと『等しい』とみなす。
|
region-face | Variable |
この変数の値は、リージョンが活性(暫定マーク(transient-mark)モードのみ)
の場合にリージョン内の文字の表示に使用するフェイス番号を指定する。
リージョン内の文字では、これが指定するフェイスが
テキスト属性やオーバレイのすべてのフェイスに優先する。
暫定マーク(transient-mark)モードについて詳しくは、see The Mark。
通常、値は |
frame-update-face-colors frame | Function |
この関数は、フレームframeの前景色や背景色を変更後に フレームframe上のフェイスの表示を更新する。 |
本節では、ユーザーが閉じ括弧を挿入したときに Emacsが対応する開き括弧を指し示す機構について述べます。
blink-paren-function | Variable |
この変数の値は、閉じ括弧構文の文字が挿入されるたびに
呼び出される(引数なしの)関数であること。
blink-paren-function の値がnil であると、なにもしない。
|
blink-matching-paren | User Option |
この変数がnil であると、blink-matching-open はなにもしない。
|
blink-matching-paren-distance | User Option |
この変数は、対応する括弧の走査を諦めるまでの最大距離を指定する。 |
blink-matching-delay | User Option |
この関数は、対応する括弧にカーソルを留める秒数を指定する。 秒未満を指定してもしばしば結果は良好であるが、 デフォルトはすべてのシステムで動作する1である。 |
blink-matching-open | コマンド |
この関数は、blink-paren-function のデフォルト値である。
閉じ括弧構文の文字のうしろにポイントがあることを仮定し、
カーソルを対応する開き括弧へ一時的に移動する。
その文字がスクリーン上になければ、
その文字が現れる文脈をエコー領域に表示する。
遅れが大きくならないように、
blink-matching-paren-distance 文字より離れては探さない。
つぎは、この関数を明示的に呼び出す例である。 (defun interactive-blink-matching-open () "Indicate momentarily the start of sexp before point." (interactive) (let ((blink-matching-paren-distance (buffer-size)) (blink-matching-paren t)) (blink-matching-open))) |
inverse-video | User Option |
この変数は、スクリーン上のすべてのテキストに
反転表示を使うかどうかを制御する。
nil 以外は使うことを意味し、
nil は使わないことを意味する。
デフォルトはnil である。
|
mode-line-inverse-video | User Option |
この変数は、モード行に反転表示を使うかどうかを制御する。
nil 以外であると、モード行を反転表示する。
さもなければ、テキストと同様にモード行を普通に表示する。
デフォルトはt である。
ウィンドウフレームでは、
|
通常の画面表示慣習は、各文字コードをどのように表示するかを定義します。 表示テーブル(see Display Tables)を設定すれば、 これらの慣習を無効にできます。 通常の画面表示慣習をつぎに示します。
tab-width
で決定される位置まで空白として表示する。
ctl-arrow
の値に従って2つの表示方法の一方を使う。
ctl-arrow
がnil
以外であると、
これらのコードを2つの字形列に対応付け、
最初の字形は^
のASCIIコードである。
(表示テーブルで^
のかわりに使う字形を指定できる。)
さもなければ、これらは128から255の範囲のコードと同様に対応付ける。
\
のASCIIコード、
残りは文字コードを8進数表示した数字文字である。
(表示テーブルで\
のかわりに使う字形を指定できる。)
通常の画面表示慣習は、たとえ表示テーブルがあっても、
活性な表示テーブルにおいてその文字に対する項目がnil
であるような
文字すべてに適用されます。
したがって、表示テーブルを設定するときには、
特別なふるまいをさせたい文字だけを指定すればよいのです。
これらの変数は、特定の文字群のスクリーンへの表示方法に影響します。
これらは文字が占めるコラム数を変化させるので、
字下げ関数にも影響します。
これらの変数は、モード行の表示方法にも影響します。
新たな値を用いてモード行の再表示を強制したいときには、
関数force-mode-line-update
(see Mode Line Format)を
呼び出します。
ctl-arrow | User Option |
このバッファローカルな変数は、
コントロール文字の表示方法を制御する。
nil 以外であると、^A のように
カレットに続けて文字を表示する。
nil であると、\001 のように
バックスラッシュに続けて3桁の8進数字で表示する。
|
default-ctl-arrow | Variable |
この変数の値は、ctl-arrow を書き換えていないバッファ向けの
ctl-arrow のデフォルト値である。
see Default Value。
|
tab-width | User Option |
この変数の値は、Emacsのバッファ内のタブ文字の表示に使う
タブストップの間隔である。
デフォルトは8である。
この機能は、コマンドtab-to-tab-stop で設定する
ユーザー設定可能なタブストップとはまったく独立であることに注意。
see Indent Tabs。
|
表示テーブル(display table)機能を使って、 すべての可能な文字コードのスクリーンへの表示方法を制御できます。 これは、ASCII文字集合にない文字を用いる ヨーロッパの言語を表示するのに有用です。
表示テーブルは、各文字コードを字形(glyph)の列に対応付けます。 各字形は、スクリーン上で1文字を占める像です。 字形テーブル(glyph table)を使えば、 読者の端末に各字形を表示する方法を定義することもできます。
表示テーブルは、モード行の表示方法にも影響します。
新たな表示テーブルを用いてモード行の再表示を強制したいときには、
関数force-mode-line-update
(see Mode Line Format)を
呼び出します。
表示テーブルは、実際にはサブタイプがdisplay-table
である
文字テーブル(see Char-Tables)です。
make-display-table | Function |
表示テーブルを作成して返す。
テーブルのすべての要素の初期値はnil である。
|
表示テーブルの通常の要素は、文字コードで添字付けします。
添字cの要素は、文字コードcの表示方法を指定します。
値はnil
であるか、字形の値のベクトル(see Glyphs)です。
要素がnil
であると、その文字を通常の画面表示慣習
(see Usual Display)に従って表示する指定です。
表示テーブルを使って改行文字の表示を変更すると、 バッファ全体は長い1つの『行』として表示されます。
表示テーブルには6つの『追加スロット』もあり、
それらは特別な目的を果たします。
それらの意味をつぎに示します。
スロットの内容がnil
であると、
そのスロットに対して以下に述べる
デフォルトを使うことを意味します。
$
)。
see Glyphs。
\
)。
\
)。
^
)。
...
)。
see Selective Display。
|
)。
see Splitting Windows。
たとえば、ctl-arrow
にnil
以外の値を設定した効果を
模倣する表示テーブルの作成方法をつぎに示します。
(setq disptab (make-display-table)) (let ((i 0)) (while (< i 32) (or (= i ?\t) (= i ?\n) (aset disptab i (vector ?^ (+ i 64)))) (setq i (1+ i))) (aset disptab 127 (vector ?^ ??)))
display-table-slot display-table slot | Function |
この関数は表示テーブルdisplay-tableの
追加スロットslotの値を返す。
引数slotは0から5までの数であるか、
スロット名(シンボル)であること。
正しいシンボルは、truncation 、wrap 、
escape 、control 、selective-display 、
vertical-border である。
|
set-display-table-slot display-table slot value | Function |
この関数は表示テーブルdisplay-tableの
追加スロットslotに値valueを保存する。
引数slotは0から5までの数であるか、
スロット名(シンボル)であること。
正しいシンボルは、truncation 、wrap 、
escape 、control 、selective-display 、
vertical-border である。
|
各ウィンドウに表示テーブルを指定でき、 各バッファにも表示テーブルを指定できます。 バッファbがウィンドウwに表示されているとき、 ウィンドウwに表示テーブルがあればそれを使って表示します。 さもなければ、バッファbに表示テーブルがあればそれを使います。 それ以外では、標準の表示テーブルがあればそれを使います。 選択されている表示テーブルを活性な表示テーブルと呼びます。
window-display-table window | Function |
この関数は、ウィンドウwindowの表示テーブルを返す。
windowに表示テーブルが割り付けられていなければnil を返す。
|
set-window-display-table window table | Function |
この関数は、ウィンドウwindowの表示テーブルとして
tableを設定する。
引数tableは、表示テーブルであるかnil であること。
|
buffer-display-table | Variable |
この変数はすべてのバッファで自動的にバッファローカルである。
バッファでの値は、そのバッファに対して用いる表示テーブルを指定する。
それがnil であると、バッファに表示テーブルを
割り付けていないことを意味する。
|
standard-display-table | Variable |
この変数の値はデフォルトの表示テーブルであり、
ウィンドウに表示テーブルがなく
そのウィンドウのバッファにも表示テーブルがない場合に使われる。
この変数はデフォルトではnil である。
|
特定のウィンドウにおいて使用する表示テーブルがない場合には、
つまり、ウィンドウで未指定であり、そのバッファでも未指定であり、
standard-display-table
がnil
である場合には、
そのウィンドウ内のすべての文字コードには通常の画面表示慣習を使います。
See Usual Display。
字形(glyph)は、文字を一般化したものです。 スクリーン上で1文字を占める像を表します。 文字と同様に、字形はLispでは整数で表現します。
字形としての各整数の意味は、字形テーブルで定義されます。
これは変数glyph-table
の値です。
glyph-table | Variable |
この変数の値は、現在の字形テーブルである。
これはベクトルであること。
g番目の要素は、字形コードgを定義する。
値がベクトルではなくnil であると、
すべての字形は単純(下記参照)である。
|
字形テーブルの要素として可能な型はつぎのとおりです。
nil
字形コードが字形テーブルの長さに等しいか大きいと、 そのコードは自動的に単純とします。
本節では、ユーザーの注意を引くためにEmacsにベルを鳴らせる (あるいはスクリーンを点滅させる)方法について述べます。 ベルを鳴らす頻度はなるべく控えめにしてください。 頻繁にベルが鳴るとわずらわしいものです。 エラーを通知するほうがふさわしいときには、 単にベルを鳴らさないように注意してください。 (see Errors。)
ding &optional do-not-terminate | Function |
この関数は、ベルを鳴らすかスクリーンを点滅する
(下記のvisible-bell を参照)。
また、do-not-terminateがnil であると
現在実行中のキーボードマクロを終了する。
|
beep &optional do-not-terminate | Function |
ding の同義語。
|
visible-bell | User Option |
この変数は、ベルを鳴らすかわりにスクリーンを点滅させるかどうかを決定する。
nil 以外であると点滅するを意味し、
nil であると点滅しないを意味する。
これは、ウィンドウシステムを用いている場合か、
端末のtermcapの定義にビジュアルベル機能(vb )がある
文字端末で有効である。
|
ring-bell-function | Variable |
これがnil 以外であると、
Emacsに『ベルを鳴らす』方法を指定する。
この値は、引数なしの関数であること。
|
Emacsはいくつかのウィンドウシステムで、 特にXウィンドウシステムで動作します。 EmacsもXも用語『ウィンドウ』を使いますが、用法は異なります。 Emacsの1つのフレームは、Xでは1つのウィンドウです。 Emacsの個々のウィンドウについては、Xはまったくわかりません。
window-system | Variable |
この変数は、Emacsが動作しているウィンドウシステムの種類を
Lispプログラムに伝える。
可能な値はつぎのとおりである。
|
window-setup-hook | Variable |
この変数は、Emacsが初期化ファイルを処理したあとに実行する
ノーマルフックである。
読者のファイル.emacs 、(あれば)デフォルトの初期化ファイル、
端末固有のLispコードをすべてロードし、
フックterm-setup-hook を実行し終えてから、
このフック実行する。
このフックは内部目的用であり、 ウィンドウシステムとの通信を設定し、最初のウィンドウを作成する。 ユーザーが干渉すべきではない。 |
カレンダーや日誌を個人の好みに合わせるための カスタマイズ項目がたくさんあります。
変数view-diary-entries-initially
にt
を設定しておくと、
カレンダーを呼び出すと現在の日に対する日誌記録を自動的に表示できます。
その日がウィンドウで見える場合に限って日誌記録が表示されます。
つぎの行、
(setq view-diary-entries-initially t) (calendar)
を個人のファイル.emacs
に入れておくと、
Emacsを起動するたびに、カレンダーと日誌の両者のウィンドウを表示します。
同様に、変数view-calendar-holidays-initially
に
t
を設定しておくと、
カレンダーに入ると自動的に3か月分の祝祭日一覧を表示します。
祝祭日一覧は別のウィンドウに現れます。
変数mark-diary-entries-in-calendar
にt
を設定すると、
日誌に入れてある日付に印を付けられます。
カレンダーのウィンドウ内容を再計算するときにこの効果が現れます。
これらの日付に印を付ける方法は2つあります。
ディスプレイで使えるならばフェイス(see Faces)を変更するか、
日付にプラス記号(+
)を付加します。
同様に、変数mark-holidays-in-calendar
にt
を設定すると、
フェイスを変えるかアスタリスク(*
)を付加することで
祝祭日に印を付けられます。
変数calendar-holiday-marker
は、
祝祭日の日付にどのように印を付けるかを指定します。
その値は、日付に付加する文字か日付の表示に使うフェイス名です。
同様に、変数diary-entry-marker
は、
日誌に入っている日付にどのように印を付けるかを指定します。
カレンダー(calendar)モードは、このような目的のために
holiday-face
とdiary-face
という名前のフェイスを作成します。
Emacsが端末で複数のフェイスを扱える場合には、
これらの変数のデフォルト値はこれらのシンボルです。
変数calendar-load-hook
は、
(カレンダーを実際に表示し始めるまえに)カレンダーパッケージを初めて
ロードしたときに実行されるノーマルフックです。
カレンダーを開始するとノーマルフックinitial-calendar-window-hook
を
実行します。
カレンダーの表示を再計算してもこのフックは実行されません。
しかし、コマンドqでカレンダーを抜けてから再度カレンダーに入ると
このフックを再度実行します。
変数today-visible-calendar-hook
は、
今日の日付がウィンドウで見えるときに
カレンダーバッファにカレンダーの準備を終えてから実行される
ノーマルフックです。
このフックの1つの用途は、今日の日付をアスタリスクで置き換えることです。
それにはフック関数calendar-star-date
を使います。
(add-hook 'today-visible-calendar-hook 'calendar-star-date)
他の標準的なフック関数は、フェイスを変更するかアスタリスクを付加することで 現在の日付に印を付けます。 つぎのように使います。
(add-hook 'today-visible-calendar-hook 'calendar-mark-today)
変数calendar-today-marker
は、
今日の日付の印の付け方を指定します。
その値は、日付に付加する文字か日付の表示に使うフェイス名です。
この目的のためにcalendar-today-face
という名前のフェイスがあります。
Emacsが端末で複数のフェイスを扱える場合には、
この変数のデフォルト値はこのシンボルです。
同様なノーマルフックtoday-invisible-calendar-hook
は、
現在の日付がウィンドウで見えないときに実行されます。
Emacsは、複数のリストの中の1つのリストに入っている項目群で
定義される祝祭日を把握しています。
これらの祝祭日のリストに祝祭日を追加したり削除して
個人の目的に合うようにカスタマイズできます。
Emacsが使用する祝祭日のリストは、
一般祝祭日(general-holidays
)、
地域祝祭日(local-holidays
)、
キリスト教祝祭日(christian-holidays
)、
ヘブライ(ユダヤ教)祝祭日(hebrew-holidays
)、
イスラム(回教徒)祝祭日(islamic-holidays
)、
その他の祝祭日(other-holidays
)です。
一般祝祭日は、デフォルトでは、合州国に共通の祝祭日です。
これらの祝祭日を削除するには、general-holidays
にnil
を設定します。
デフォルトの地域祝祭日はありません(サイトによってはある)。
以下に述べるように、
変数local-holidays
に祝祭日の任意のリストを設定できます。
デフォルトでは、Emacsが承知している宗教のすべての祝祭日が
Emacsに入っているのではなく、世俗的なカレンダーに共通するものだけです。
宗教上の祝祭日を網羅的に入れるには、
all-christian-calendar-holidays
、
all-hebrew-calendar-holidays
、
all-islamic-calendar-holidays
の変数のいずれか(あるいは、すべて)に
t
を設定します。
宗教上の祝祭日を削除するには、対応する
christian-holidays
、hebrew-holidays
、
islamic-holidays
の変数のいずれか(あるいは、すべて)に
nil
を設定します。
変数other-holidays
には、祝祭日の任意のリストを設定できます。
このリストは、普通は空ですが、個人的な使用を意図しています。
リスト(general-holidays
、local-holidays
、
christian-holidays
、hebrew-holidays
、
islamic-holidays
、other-holidays
)のおのおのは、
祝祭日(あるいは祝祭日のリスト)を記述する
祝祭日形式(holiday form)から成るリストです。
可能な祝祭日形式の一覧をつぎに示します。 月と日は1から数えますが、『曜日』は日曜日を0と数えます。 要素stringは、文字列で表した祝祭日の名称です。
(holiday-fixed month day string)
(holiday-float month dayname k string)
(holiday-hebrew month day string)
(holiday-islamic month day string)
(holiday-julian month day string)
(holiday-sexp sexp string)
year
を使い、祝祭日の日付を返す。
あるいは、その年に該当する祝祭日がなければnil
を返す。
sexpの値は、(month day year)
の形の
リストで表した日付であること。
(if condition holiday-form)
(function [args])
たとえば、フランスで7月14日に祝われる革命記念日(Bastille Day)を 扱えるようにするにはつぎのようにします。
(setq other-holidays '((holiday-fixed 7 14 "Bastille Day")))
祝祭日形式 (holiday-fixed 7 14 "Bastille Day")
は、
7の月(7月)の14日目を指定します。
多くの祝祭日は、特定の月の特定の週にあります。 バージン諸島で4月の第4月曜日に祝われる ハリケーン祈願日(Hurricane Supplication Day)を記述する 祝祭日形式はつぎのようになります。
(holiday-float 8 1 4 "Hurricane Supplication Day")
ここで、8は8月、1は月曜日(日曜日は0、火曜日は2といった具合)、4は その月の4回目(1は最初、2は2回目、-1は最後、-2は最後の1つまえ といった具合)を意味します。
ヘブライ暦、イスラム暦、ユリウス暦の固定した日付の祝祭日も指定できます。 たとえば、
(setq other-holidays '((holiday-hebrew 10 2 "Last day of Hanukkah") (holiday-islamic 3 12 "Mohammed's Birthday") (holiday-julian 4 2 "Jefferson's Birthday")))
は、ハヌカー祭の最終日(ヘブライ暦の月はニサンNisanを1と数える)、 イスラムが祝うモハメッドの誕生日 (イスラム暦の月はムハラMuharramを1と数える)、 ユリウス暦の1743年4月2日のトーマスジェファーソンの誕生日を 追加します。
条件付きの祝祭日を含めるには、Emacs Lispのif
やholiday-sexp
を
使います。
たとえば、アメリカ大統領選挙は、4で割り切れる年の11月の第1月曜日の
あとの最初の火曜日に行われます。
(holiday-sexp (if (= 0 (% year 4)) (calendar-gregorian-from-absolute (1+ (calendar-dayname-on-or-before 1 (+ 6 (calendar-absolute-from-gregorian (list 11 1 year)))))) "US Presidential Election"))
あるいは、
(if (= 0 (% displayed-year 4)) (fixed 11 (extract-calendar-day (calendar-gregorian-from-absolute (1+ (calendar-dayname-on-or-before 1 (+ 6 (calendar-absolute-from-gregorian (list 11 1 displayed-year))))))) "US Presidential Election"))
特別な計算を必要とする祝祭日は、これまでの形式にあてはまりません。
そのような場合、計算を行うLisp関数を書く必要があります。
たとえば、日食月食を含めるには、
other-holidays
に(eclipses)
を追加して、
以下のような形でカレンダーウィンドウの見えている範囲の期間内の
対応するグレゴリオ暦の日付の(空である可能性もある)リストを
返すEmacs Lisp関数(eclipses)
を書きます。
(((6 27 1991) "Lunar Eclipse") ((7 11 1991) "Solar Eclipse") ... )
日誌、モード行、メッセージに現れる日付の表示方法は、
calendar-date-display-form
を設定することでカスタマイズできます。
この変数は、
文字列で表した数字が入ったmonth
、day
、year
の各変数と、
英字の文字列が入ったmonthname
とdayname
の各変数を
用いた式のリストを保持しています。
アメリカスタイルでは、このリストのデフォルト値はつぎのようになります。
((if dayname (concat dayname ", ")) monthname " " day ", " year)
一方、ヨーロッパスタイルでは、この値のデフォルトはつぎのようになります。
((if dayname (concat dayname ", ")) day " " monthname " " year)
ISO規格の日付の表記法はつぎのとおりです。
(year "-" month "-" day)
典型的なアメリカの書式はつぎのとおりです。
(month "/" day "/" (substring year -2))
カレンダーと日誌はデフォルトではアメリカスタイル、
つまり、12時制で時刻を表示します。
ヨーロッパスタイルやアメリカ軍の24時制を好むならば、
変数calendar-time-display-form
を変更します。
この変数は、
文字列で表した数字が入った12-hours
、24-hours
、
minutes
の各変数と、
英字の文字列が入ったam-pm
とtime-zone
の各変数を
用いた式のリストを保持しています。
calendar-time-display-form
のデフォルト値はつぎのとおりです。
(12-hours ":" minutes am-pm (if time-zone " (") time-zone (if time-zone ")"))
つぎの値では、ヨーロッパスタイルの時刻になります。
(24-hours ":" minutes (if time-zone " (") time-zone (if time-zone ")"))
Emacsは、標準時間と夏時間の違いを理解しています。 つまり、日出入時刻、夏至冬至、春分秋分、朔弦望ではその違いを考慮します。 夏時間の規則は、地域ごと、年ごとに変わりえます。 正しく扱うためには、どの規則が適用されるかをEmacsが知っている必要があります。
読者の居住地域に適用される規則を記録している オペレーティングシステムもあります。 これらのシステム上では、Emacsは自動的にシステムから必要な情報を得られます。 この情報の一部やすべてが欠落していると、 GNU世界の中心であるマサチューセッツ州ケンブリッジで 現在使用している規則で補います。
デフォルトで選んだ規則が読者の地域に適切でないときには、
変数calendar-daylight-savings-starts
と
calendar-daylight-savings-ends
に設定してEmacsに伝えます。
これらの値は、変数year
を使ったLisp式である必要があります。
これらの式を評価すると、夏時間を開始/終了するグレゴリオ暦の日付を表す
(month day year)
の形のリストに
なる必要があります。
夏時間をとらない場合には、値はnil
であるべきです。
Emacsは、これらの式を用いて夏時間の開始と終了を判定し、 祝祭日や太陽/月に関する時刻を補正します。
マサチューセッツ州ケンブリッジに対する値は、つぎのとおりです。
(calendar-nth-named-day 1 0 4 year) (calendar-nth-named-day -1 0 10 year)
つまり、指定されたyear
年の4月の最初の日曜日と
その年の10月の最後の日曜日です。
10月1日に夏時間を始めると変更したとすると、
変数calendar-daylight-savings-starts
に
つぎのように設定します。
(list 10 1 year)
より複雑な例として、ヘブライ暦のニサンの初日に夏時間が始まるとしましょう。
calendar-daylight-savings-starts
には、
つぎの値を設定します。
(calendar-gregorian-from-absolute (calendar-absolute-from-hebrew (list 1 1 (+ year 3760))))
これは、ニサンはヘブライ暦の最初の月であり、 ヘブライ暦年とグレゴリオ暦年はニサンで3760年違うからです。
読者の地域で夏時間をとっていなかったり、
つねに標準時間を望む場合には、
calendar-daylight-savings-starts
と
calendar-daylight-savings-ends
にnil
を設定します。
変数calendar-daylight-time-offset
は、
夏時間と標準時間の分で計った差を指定します。
ケンブリッジに対する値は60です。
変数calendar-daylight-savings-starts-time
と
calendar-daylight-savings-ends-time
は、
夏時間と標準時間との移行が行われる
地方時の真夜中の0時からの経過分を指定します。
ケンブリッジでは、どちらの変数の値も120です。
通常、日誌用バッファのウィンドウのモード行には、
日誌記録の日付に一致する祝祭日があれば表示されます。
祝祭日を検査する処理には数秒を要するので、
祝祭日情報を含めると日誌用バッファの表示に遅れが生じます。
祝祭日情報をなくして日誌用バッファの表示を速くしたい場合には、
変数holidays-in-diary-buffer
にnil
を設定します。
変数number-of-diary-entries
は、
一度に表示する日誌記録の日数を制御します。
これは、view-diary-entries-initially
がt
であるときの
最初の表示に影響します。
たとえば、デフォルト値は1で、現在の日付の日誌記録のみを表示します。
値が2であると、現在とつぎの日付の日誌記録を表示します。
この値は7要素のベクトルでもかまいません。
たとえば、値が[0 2 2 2 2 4 1]
であると、
日曜日には日誌記録をなにも表示せず、
月曜日から木曜日には現在とつぎの日付の日誌記録を表示し、
金曜日には金曜日から月曜日の日誌記録を表示し、
土曜日にはその日だけの日誌記録を表示します。
変数print-diary-entries-hook
は、
日誌用バッファで現在見えている日誌記録のみを収めた一時的なバッファの
準備ができると実行されるノーマルフックです。
(他の関係ない日誌記録は一時的なバッファには入っていない。
日誌用バッファではそれらは隠されている。)
このフックのデフォルト値は、コマンドlpr-buffer
で印刷します。
別のコマンドで印刷したい場合には、単にこのフックの値を変更します。
別の用途は、たとえば、行を日付と時刻で並び替えることです。
diary-date-forms
に設定すれば、
目的に合うように個人の日誌ファイル内の日付の書式を
アメリカスタイルやヨーロッパスタイルにカスタマイズできます。
この変数は、日付を認識するパターンのリストです。
各パターンは、正規表現(see Regular Expressions)や
month
、day
、year
、monthname
、
dayname
のシンボルを要素とするリストです。
これらの要素すべては、日誌ファイル内の特定種類のテキストに一致する
パターンとして働きます。
全体として日付パターンとして一致するには、
すべての要素が順に一致する必要があります。
日付パターンの正規表現は、*
を単語構成文字に変更した
標準の構文テーブルを用いて通常どおりに一致をとります。
month
、day
、year
、monthname
、dayname
の
シンボルは、対象にしている月、日、年、月の名前、曜日です。
数に一致するシンボルは、数の先頭にある0を許します。
名前に一致するシンボルは、3文字の省略形や大文字で始まることを許します。
日誌記録では*
は『任意の日』『任意に月』などを表し、
対象とする日付に関係なく一致するべきなので、
すべてのシンボルは*
に一致できます。
アメリカスタイルのdiary-date-forms
のデフォルト値はつぎのとおりです。
((month "/" day "[^/0-9]") (month "/" day "/" year "[^0-9]") (monthname " *" day "[^,0-9]") (monthname " *" day ", *" year "[^0-9]") (dayname "\\W"))
リスト内の日付パターンは、互いに排他的であり、
日誌記録の日付と1つの白文字以外には他の部分に一致してはいけません。
互いに排他的であるためには、
パターンは日付を終える白文字を越えて日誌記録本文に一致する必要があります。
それには、日付パターンの最初の要素はbackup
である必要があります。
これにより、日付を認識する処理では、
一致し終えてから日誌記録の現在の単語の先頭に戻ります。
たとえbackup
を使ったとしても、
日付パターンは日誌本体の最初の単語を越えて一致してはいけません。
ヨーロッパスタイルのdiary-date-forms
のデフォルト値は、
つぎのとおりです。
((day "/" month "[^/0-9]") (day "/" month "/" year "[^0-9]") (backup day " *" monthname "\\W+\\<[^*0-9]") (day " *" monthname " *" year "[^0-9]") (dayname "\\W"))
ここでは、3番目のパターンでbackup
を使っています。
4番目のパターンと区別するために、
日付のつぎの単語の一部と一致する必要があるからです。
日誌ファイルには、世界標準のグレゴリオ暦日付に加えて、 ヘブライ暦日付やイスラム暦日付を入れることもできます。 しかし、そのような記録の認識には時間がかかり、 ほとんどの人はそれらを使わないので、 それらは明示的にオンにする必要があります。 日誌でヘブライ暦日付の日誌記録を認識できるように望むなら、 たとえば、つぎのようにする必要があります。
(add-hook 'nongregorian-diary-listing-hook 'list-hebrew-diary-entries) (add-hook 'nongregorian-diary-marking-hook 'mark-hebrew-diary-entries)
イスラム暦日付の日誌記録を望むなら、つぎのようにします。
(add-hook 'nongregorian-diary-listing-hook 'list-islamic-diary-entries) (add-hook 'nongregorian-diary-marking-hook 'mark-islamic-diary-entries)
ヘブライ暦日付やイスラム暦日付の日誌記録は、
グレゴリオ暦日付と同じ形式ですが、
ヘブライ暦日付のまえにはH
、
イスラム暦日付のまえにはI
がある点が異なります。
さらに、ヘブライ暦やイスラム暦の月は、最初の3文字で一意に決まらないため、
月の省略形は使えません。
たとえば、ヘブライ暦日付Heshvan 25の日誌記録はつぎのようになります。
HHeshvan 25 Happy Hebrew birthday!
これはヘブライ暦日付Heshvan 25に対する任意の日誌に現れます。 イスラム暦日付Dhu al-Qada 25に一致する日誌記録はつぎのようになります。
IDhu al-Qada 25 Happy Islamic birthday!
グレゴリオ暦日付の日誌記録では、
ヘブライ暦日付とイスラム暦日付の記録は、
それらの前にアンパサンド(&
)があると印付けされません。
ヘブライ暦やイスラム暦において 指定した日付や似た日付に一致する日誌記録を作成するための カレンダーのコマンド一覧をつぎに示します。
insert-hebrew-diary-entry
)。
insert-monthly-hebrew-diary-entry
)。
この日誌記録は、選択した日付のヘブライ暦の月内の日と同じ
任意の日付に一致する。
insert-yearly-hebrew-diary-entry
)。
この日誌記録は、選択した日付のヘブライ暦の月とその月内の日と同じ
任意の日付に一致する。
insert-islamic-diary-entry
)。
insert-monthly-islamic-diary-entry
)。
insert-yearly-islamic-diary-entry
)。
これらのコマンドは、日誌記録の対応する普通のコマンドと同様に働きます。 カレンダーウィンドウにおいてポイントがある日付に作用し、 日誌記録の日付に関する部分のみを挿入します。 日誌記録の本文は自分で入力する必要があります。
日誌表示は、日誌用バッファを準備してからフックdiary-display-hook
を
実行することで動作します。
このフックのデフォルト値(simple-diary-display
)は、
関係ない日誌記録を隠してからバッファを表示します。
しかし、つぎのようにフックを指定すると
(add-hook 'diary-display-hook 'fancy-diary-display)
装飾日誌表示を行えます。 日誌記録と祝祭日を表示専用の特別なバッファにコピーして表示します。 別のバッファにコピーするので、表示テキストが綺麗になるように変更できます。 たとえば、日付順に記録をソートするなどです。
単純な日誌表示では、print-diary-entries
でバッファ内容を印刷できます。
1週間分の毎日の日誌を印刷するには、
その週の日曜日にポイントを置いて7 dと打ってから
M-x print-diary-entriesを行います。
祝祭日が入っていると表示が遅くなりますが、
変数holidays-in-diary-buffer
にnil
を設定すると速くできます。
通常、装飾日誌用バッファでは、
たとえ祝祭日であっても日誌記録がない日は表示しません。
そのような日を装飾日誌用バッファに表示するには、
変数diary-list-include-blanks
にt
を設定します。
装飾日誌表示を使うときには、
ノーマルフックlist-diary-entries-hook
を使って
各日誌記録を時刻でソートできます。
つぎのようにします。
(add-hook 'list-diary-entries-hook 'sort-diary-entries t)
これは、各日ごとに認識できる時刻で始まる日誌記録をソートします。 各日の先頭には時刻のついていない日誌項目がきます。
装飾日誌表示には、取り込んだ日誌ファイルを処理する能力もあります。 これにより、グループのメンバは、グループに共通な行事を記述した 日誌ファイルを共有できます。 つぎのような行を日誌ファイルに書きます。
#include "filename"
そうすると、ファイルfilenameから 日誌記録を装飾日誌用バッファに取り込みます。 取り込み機構は再帰的ですから、 取り込んだファイル内で別のファイルを取り込むことができます。 もちろん、取り込みが循環しないように注意してください。 取り込み機能をオンにするにはつぎのようにします。
(add-hook 'list-diary-entries-hook 'include-other-diary-files) (add-hook 'mark-diary-entries-hook 'mark-included-diary-files)
通常の日誌表示は個人の日誌ファイルの記録を直接表示するため、 取り込み機構は装飾日誌表示でのみ動作します。
S式を使った日誌記録は、
複雑な条件で適用される日誌記録を作る以上のことができます。
装飾日誌表示を使っている場合には、S式日誌項目は、
日付に依存した記録テキストを生成できます。
たとえば、記念日の記録では、テキストに何回目の記念日であるかを入れられます。
したがって、つぎの日誌記録の%d
は年齢で置き換えられます。
%%(diary-anniversary 10 31 1948) Arthur's birthday (%d years old)
つまり、装飾日誌用バッファでは、1990年10月31日の項目はつぎのようになります。
Arthur's birthday (42 years old)
日誌ファイルにつぎの項目が入っていると、
%%(diary-anniversary 10 31 1948) Arthur's %d%s birthday
装飾日誌用バッファでは、1990年10月31日の項目はつぎのようになります。
Arthur's 42nd birthday
同様に、周期的な日誌項目では繰り返し回数を計算できます。
%%(diary-cyclic 50 1 1 1990) Renew medication (%d%s time)
は、1990年9月8日の装飾日誌表示ではつぎのようになります。
Renew medication (5th time)
当日の日誌項目としてだけでなく、 それよりまえの日の日誌項目にも含めるためのS式日誌項目があります。 たとえば、記念日の1週間前に督促がほしいときには、 つぎのようにします。
%%(diary-remind '(diary-anniversary 12 22 1968) 7) Ed's anniversary
すると、装飾日誌には、12月15日と12月22日に
Ruth & Ed's anniversary
と表示されます。
関数diary-date
は、整数や整数のリストやt
で指定した
月、日、年の組み合わせで表される日付に適用されます。
たとえば、
%%(diary-date '(10 11 12) 22 t) Rake leaves
により、装飾日誌には、各年の10月22日、11月22日、12月22日には
Rake leaves
と表示されます。
関数diary-float
により、
11月の第3金曜日とか4月の最後の火曜日といった
日付に適用する日誌記録を記述できます。
パラメータは、月month、曜日dayname、添字nです。
日曜日をdayname=0、月曜日をdayname=1、…として、
month月のn番目の曜日daynameに項目が現れます。
nが負であると、month月の月末から数えます。
monthは、月のリストでも、1つの月でも、全部の月を指定するt
でも
かまいません。
省略可能なパラメータdayを指定して、
month月のn番目の曜日daynameの
前後のday日を指定できます。
nが正だとdayのデフォルトは1であり、
nが負だとdayのデフォルトはmonth月の月末です。
たとえば、
%%(diary-float t 1 -1) Pay rent
は、装飾日誌に各月の最後の月曜日に
Pay rent
を表示します。
S式日誌項目の一般性により、アルゴリズムで日誌項目を指定できます。
S式日誌項目には、項目を当該日に適用するどうかを計算する式を含められます。
その値がnil
以外であると、その項目を当該日に適用します。
その式では、対象とする日付を知るために変数date
を使えます。
この変数の値は、グレゴリオ暦で表した
リスト(month day year)
です。
毎月のウィークデイである21日か、 21日が週末の場合にはそのまえの金曜日に給料を支払われるとしましょう。 そのような日付に一致するS式日誌項目はつぎのように書けます。
&%%(let ((dayname (calendar-day-of-week date)) (day (car (cdr date)))) (or (and (= day 21) (memq dayname '(1 2 3 4 5))) (and (memq day '(19 20)) (= dayname 5))) ) Pay check deposited
以下のS式日誌項目は、日付に依存して変わるテキストを 日誌項目に入れる機能を(装飾日誌表示で)利用できます。
%%(diary-sunrise-sunset)
%%(diary-phases-of-moon)
%%(diary-day-of-year)
%%(diary-iso-date)
%%(diary-julian-date)
%%(diary-astro-day-number)
%%(diary-hebrew-date)
%%(diary-islamic-date)
%%(diary-french-date)
%%(diary-mayan-date)
したがって、
&%%(diary-hebrew-date)
を含んだ日誌項目は、装飾日誌表示を使っていると、
毎日の日誌表示に対応するヘブライ暦の日付を含めることになります。
(単純な日誌表示では、行&%%(diary-hebrew-date)
は
すべての日付の日誌に現れるが、特別なことはなにもしない。)
つぎの関数は、ある標準的な方法でヘブライ暦に基づく S式日誌項目を構成するために使えます。
%%(diary-rosh-hodesh)
%%(diary-parasha)
%%(diary-sabbath-candles)
%%(diary-omer)
%%(diary-yahrzeit month day year) name
Emacsにどのように約束の警告表示を行わせ、 どの程度前から行わせるかは、つぎの変数に設定することで正確に指定できます。
appt-message-warning-time
appt-audible
nil
以外であると、Emacsは約束の警告表示として端末のベルを鳴らす。
デフォルトはt
。
appt-visible
nil
以外であると、Emacsは約束のメッセージをエコー領域に表示する。
デフォルトはt
。
appt-display-mode-line
nil
以外であると、Emacsは約束までの残り分数をモード行に表示する。
デフォルトはt
。
appt-msg-window
nil
以外であると、
Emacsは約束のメッセージを別のウィンドウに表示する。
デフォルトはt
。
appt-disp-window-function
appt-delete-window-function
appt-display-duration
本章では、Emacs Lispの機能についてさらに述べることはしません。 かわりに、前章までに述べてきた機能を効率よく使うための助言や Emacs Lispプログラマが従うべき慣習について述べます。
ここでは、読者が広く使われることを意図した Emacs Lispコードを書く場合に従うべき慣習について述べます。
Emacs Lispでは基本関数ではないがLispの伝統的な基本関数の名前にさえも
この勧告は適用される。
たとえcopy-list
にさえもである。
信じるかどうかは別にして、
copy-list
のもっともらしい定義方法は複数ある。
安全であるためには、読者の接頭辞を付けて
foo-copy-list
やmylib-copy-list
のような名前にする。
読者が、twiddle-files
のような特定の名前でEmacsに
追加すべき関数を書いた場合には、読者のプログラムでは
その名前で呼ばないようにする。
読者のプログラムではmylib-twiddle-files
としておき、
Emacsに名前を追加するように提案するメイルを
bug-gnu-emacs@gnu.org
へ送る。
われわれがそのようにすることを決定したときには、
名前をとても簡単に変更できる。
1つの接頭辞では不十分な場合には、 意味がある限りは、 2つか3つの共通する別の接頭辞を読者のパッケージで使ってもよい。
接頭辞とシンボル名の残りの部分とはハイフン-
で分ける。
これはEmacs自身やほとんどのEmacs Lispプログラムと一貫性がある。
provide
の呼び出しがあるとしばしば有用である。
require
を使う。
(eval-when-compile (require 'bar))
(さらに、require
が働くように、
ライブラリbarには(provide 'bar)
があること。)
この式により、fooをバイトコンパイルするときに
barをロードすることになる。
さもないと、必要なマクロをロードせずにfooをコンパイルする危険を侵し、
正しく動作しないコンパイル済みコードを生成することになる。
see Compiling Macros。
eval-when-compile
を使うことで、
fooのコンパイル済みの版を使うときには
barをロードしない。
p
で終る名前を付ける。
名前が1単語である場合にはp
だけを付加する。
複数の単語であれば-p
を付加する。
たとえば、framep
やframe-live-p
である。
-flag
で終る名前を付ける。
かわりに、C-cのあとにコントロール文字か数字文字か特定の句読点文字が続く キー列を定義する。 これらのキー列は、メジャーモード用に予約してある。
Emacsのすべてのモードをこの慣習に従うように変換するのは たいへんな作業量であった。 この慣習を捨てさるとその作業をむだにしてしまい、ユーザーにも不便である。
この規則の理由は、任意の文脈において <ESC>に対するプレフィックスでないバインディングがあることで、 エスケープシーケンスをその文脈におけるファンクションキーと 認識することを防げる。
Emacsの普通のコマンドを受け付ける状態、、あるいは、 より一般的には<ESC>に続けてファンクションキーや矢印キーが 意味を持つ可能性がある任意の状態では、 <ESC>に続くエスケープシーケンスの認識を妨げる <ESC> <ESC>を定義するべきではない。 そのような状態では、脱出手段として<ESC> <ESC> <ESC>を 定義する。 さもなければ脱出手段として<ESC> <ESC>を定義する。
whatever-mode
という
名前のコマンドを用意し、自動ロード(see Autoload)するようにする。
パッケージをロードしただけでは見ためには効果がない、
つまり、その機能をオンにしないようにパッケージを設計すること。
ユーザーはコマンドを起動してその機能をオンにする。
next-line
やprevious-line
を使わないこと。
ほとんどの場合、forward-line
のほうがより便利であり、
予測可能で堅牢でもある。
see Text Lines。
特に、以下のいずれの関数も使わないこと。
beginning-of-buffer
, end-of-buffer
replace-string
, replace-regexp
対話的なユーザー向けの他の機能を必要とせずに 単にポイントを移動したり特定の文字列を置換するには、 これらの関数は1行か2行の単純なLispコードで置き換えられる。
(リストだけが許す)要素を挿入したり削除する必要がないのであれば、 ある程度のサイズがあり (先頭から末尾に向けての探索ではなく)ランダムに参照する表には ベクトルのほうが適している。
princ
ではなく関数message
を使うことである。
see The Echo Area。
error
(あるいはsignal
)を呼び出す。
関数error
は戻ってこない。
see Signaling Errors。
エラーを報告するために、
message
、throw
、sleep-for
、beep
は使わないこと。
Operating...
のメッセージを表示し、
終了時にはそれをOperating...done
と変える。
これらのメッセージの形を同じにしておくこと。
...
の周りに空白はなく、末尾にピリオドもない。
edit-options
のようにする。
別のバッファに切り替え、戻るのはユーザーに任せる。
see Recursive Editing。
*
で始めたり終える慣習があるシステムもある。
Emacs Lispではこの慣習を使わないので、読者のプログラムでも使わないこと。
(Emacsでは、特別な目的のバッファにのみそのような名前を使う。)
すべてのライブラリで同じ慣習を使うと、
ユーザーにはEmacsがより整合して見える。
defvar
の定義を追加して、
コンパイル時の未定義な自由変数に対する警告を避けるように努めること。
ある関数で変数を束縛しその変数を別の関数で使ったり設定すると、 その変数を定義しない限りコンパイラは後者の関数について警告を出す。 しかし、しばしばこれらの変数は短い名前で、 Lispパッケージでそのような変数名を定義すべきかどうか明らかでない。 したがって、そのような変数の名前は、 読者のパッケージの他の関数や変数に使っている接頭辞で 始まる名前に改名すべきである。
indent-sexp
)で字下げすること。
;; Copyright (C) year name ;; 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 2 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, write to the Free ;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, ;; MA 02111-1307 USA
読者がフリーソフトウェアファウンデーションに著作権を委譲する契約を
結んでいるときには、
nameとしてFree Software Foundation, Inc.
を使う。
さもなければ読者自身の名前を使う。
バイトコンパイルしたLispプログラムの実行速度を改良する方法を示します。
profile
やライブラリelp
で、
読者のプログラムを計測する。
操作方法についてはファイルprofile.el
とelp.el
を参照。
memq
、member
、assq
、assoc
のリスト探索基本関数を
使うほうが明示的な繰り返しよりも速い。
これらの探索基本関数の1つを使えるようにデータ構造を変更する価値はある。
byte-compile
を調べる。
属性がnil
以外であれば、その関数は特別に扱われる。
たとえば、つぎの入力は、aref
が特別にコンパイルされることを示す
(see Array Functions)。
(get 'aref 'byte-compile) => byte-compile-two-args
説明文字列を書くうえでのヒントや慣習を述べます。 コマンドM-x checkdoc-minor-modeを実行して、 これらの慣習の多くを確認できます。
説明文字列には、関数や変数の使い方の詳細を述べる追加の行があってよい。 それらの行も完全な文から成るべきであるが、見ためをよくするために 適当に詰めてよい。
しかし、説明文字列全体を単純に整形するよりは、 注意深く行分けすると読みやすくなる。 説明文字列が長い場合には、話題ごとに空行で区切る。
*
で始める。
変数の値が、長いリストや関数であるとき、あるいは、
初期化ファイルでのみ設定するような変数であるときには、
その説明文字列を*
で始めないこと。
see Defining Variables。
nil
以外の値はすべて同値であることを明らかにし、
nil
とnil
以外の意味を明確に示すこと。
/
の説明文字列では、
その第2引数の名前はdivisor
なので、DIVISOR
と表す。
また、リストやベクトルを(その一部が変化するかもしれない)構成部分に 分解したものを示すときなどのメタ変数には、すべて大文字を使う。
variable
、option
、function
、command
の
いずれかの単語を書くだけでどちらであるかを指定できる。
(これらの単語を認識するときには大文字小文字は区別しない。)
たとえばつぎのように書くと、
This function sets the variable `buffer-file-name'.
ハイパーリンクは、変数buffer-file-name
の説明文字列を指し、
その関数の説明文字列は指さない。
シンボルに関数定義や変数定義があっても、
説明文字列でのシンボルの使い方には無関係な場合には、
シンボルの名前のまえに単語symbol
を書けば、
ハイパーリンクを作らないようにできる。
たとえば、つぎのようにすると、
If the argument KIND-OF-RESULT is the symbol `list', this function returns a list of all the objects that satisfy the criterion.
ここではlist
の関数/変数定義は無関係なので、
関数list
の説明文字列を指すハイパーリンクは作られない。
\\[...]
の書き方を使う。
たとえば、C-f
と書くかわりに、\\[forward-char]
と書く。
Emacsが説明文字列を表示するときに、
forward-char
に現在バインドされているキーにEmacsが置き換える。
(普通はC-f
であるが、ユーザーがキーバインディングを変更していれば、
別の文字になる。)
see Keys in Documentation。
\\<...>
を
説明文字列の中に書く。
最初に\\[...]
を使うまえにこうしておくこと。
\\<...>
の内側のテキストは、
メジャーモード向けのローカルキーマップを保持する変数の名前であること。
説明文字列の表示を遅くしてしまうので、
\\[...]
を何回も使うのは実用的ではない。
したがって、読者のメジャーモードのもっとも重要なコマンドの記述にこれを使い、
モードのキーマップの残りを表示するには\\{...}
を使う。
コメントを置く場所とそれらの字下げ方法については以下のような慣習を推奨します。
;
;
で始まるコメントは、
ソースコードの右側で同じコラム位置に揃えること。
そのようなコメントは、その行のコードの動作を説明する。
lispモードやその関連するモードでは、
コマンドM-;(indent-for-comment
)で
自動的に右側の正しい位置に;
を挿入したり、
そのようなコメントが既存ならば整列できる。
つぎとその下の例は、Emacsのソースから持ってきたものである。
(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
;;
;;
で始まるコメントは、
その部分のコードの字下げに揃えること。
そのようなコメントは、その後続の行の目的や
その箇所でのプログラムの状態を記述する。
(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.
3つのセミコロンで始まるコメントの別の使い方は、 関数内の行をコメントにする場合である。 そのような行が左端に留まるように3つのセミコロンを使うのである。
(defun foo (a) ;;; This is no longer necessary. ;;; (force-mode-line-update) (message "Finished with %s" a))
;;;;
;;;;
で始まるコメントは、
左端に揃えて、プログラムの主要な部分のヘッダに使う。
たとえばつぎのとおり。
;;;; The kill ring
M-;(indent-for-comment
)や
<TAB>(lisp-indent-line
)などの
Emacsのlispモードの字下げコマンドは、
これらの慣習にしたがって自動的にコメントを字下げします。
See Comments。
Emacsには、コメントをいくつかの部分に分けて作者などの情報を与えるために、 Lispライブラリの特別なコメントに対する慣習があります。 本節ではそれらの慣習について述べます。 まず、例を示します。
;;; lisp-mnt.el --- minor mode for Emacs Lisp maintainers ;; Copyright (C) 1992 Free Software Foundation, Inc. ;; Author: Eric S. Raymond <esr@snark.thyrsus.com> ;; Maintainer: Eric S. Raymond <esr@snark.thyrsus.com> ;; Created: 14 Jul 1992 ;; Version: 1.2 ;; Keywords: docs ;; This file is part of GNU Emacs. ... ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA.
最初の行はつぎの形式であるべきです。
;;; filename --- description
この記述は1行で完全になるようにします。
著作権表示のあとには、;; header-name:
で始まる
いくつかのヘッダコメント(header comment)行が続きます。
header-nameに使う可能性のある慣習の一覧を以下に示します。
Author
複数の作者がいる場合には、以下のように、
;;
とタブ文字で始めた継続行に
その人達を列挙する。
;; Author: Ashwin Ram <Ram-Ashwin@cs.yale.edu> ;; Dave Sill <de5@ornl.gov> ;; Dave Brennan <brennan@hal.com> ;; Eric Raymond <esr@snark.thyrsus.com>
Maintainer
Author
)のように1人の氏名とアドレス、
アドレスのみ、文字列FSF
のいずれかを書く。
保守者行(Maintainer
)がない場合には、
作者行の人達が保守していると仮定する。
上の例は、保守者行が冗長であり、少々いんちきである。
作者行(Author
)と保守者行(Maintainer
)の考えは、
手作業で名前を探さずに『保守者にメイルを送る』ようなLisp関数を
作れるようにするためである。
ネットワークアドレスに加えて人の氏名も書く場合には、
ネットワークアドレスを<...>
で必ず囲むこと。
Created
Version
Adapted-By
Keywords
finder-by-keyword
向けの
キーワードを書く。
意味のあるキーワードを理解するためにこのコマンドを試してほしい。
この部分は重要である。 人々が特定の話題で探して読者のパッケージをみつけるであろう。 キーワードは空白やカンマで区切る。
ほとんどのLispライブラリには、
Author
とKeywords
のヘッダコメント行が必要です。
残りのものは必要に応じて使います。
別の名前のヘッダ行があってもかまいません。
それらには標準的な意味はありませんが、害になることもありません。
ライブラリファイルの内容を分割するために形式を定めたコメントも使います。 それらを以下に示します。
;;; Commentary:
Change Log
、History
、Code
のいずれかのコメント行で終る。
このテキストはパッケージfinderが使うので、
その文脈で意味があるようにすること。
;;; Documentation
;;; Commentary:
のかわりに使っているファイルもあるが、
;;; Commentary:
のほうが好ましい。
;;; Change Log:
ChangeLog
に収めてあり、
ソースファイルには収めない。
それらのファイルには;;; Change Log:
行はない。
;;; Code:
;;; filename ends here
本章では、Lispライブラリをあらかじめロードした実用的なEmacsの実行形式の ダンプ方法、メモリ領域の割り当て方、 Cプログラマに興味があるようなGNU Emacsの内部について述べます。
本節では、Emacsの実行形式を構築する手順を説明します。 メイクファイルが自動的にこれらすべてを行うので、 Emacsを構築してインストールするために本節のことがらを 読者が知っている必要はありません。 本節の内容は、Emacsの保守者向けです。
ディレクトリsrc
のCソースファイル群をコンパイルすると、
temacs
と呼ばれる実行形式ファイルが作られます。
これは裸のインピュアEmacs(bare impure Emacs)とも呼びます。
これには、Emacs Lispインタープリタと入出力ルーティンが含まれますが、
編集コマンドは入っていません。
コマンドtemacs -l loadup
で、
実用的なEmacsの実行形式を作るためにtemacs
を使います。
これらの引数は、temacs
に対して
ファイルloadup.el
で指定したLispファイル群を評価するように指示します。
これらのファイルはEmacsの通常の編集環境を作り上げ、
その結果、Emacsは裸ではありませんがまだインピュアです。
標準のLispファイル群をロードするにはかなり時間が必要です。
しかし、読者がEmacsを実行するたびにこれを行う必要はありません。
temacs
は、必要なファイルをあらかじめロードしたemacs
という
実行形式プログラムとしてダンプできます。
emacs
はファイル群をロードする必要がないので素早く起動します。
これが通常インストールされるEmacsの実行形式です。
emacs
を作るにはコマンドtemacs -batch -l loadup dump
を使います。
ここでの-batch
の目的は、
temacs
が端末に関するデータを初期化しないようにするためです。
これにより、ダンプしたEmacsでは端末情報の表が空であることを保証できます。
引数dump
は、emacs
という名前の新たな実行形式を
ダンプするようにloadup.el
に指示します。
ダンプできないオペレーティングシステムもあります。
そのようなシステムでは、Emacsを使うたびに
コマンドtemacs -l loadup
でEmacsを起動する必要があります。
これにはかなり時間がかかりますが、多くても1日に1回、あるいは、
ログアウトしなのであれば週に1回Emacsを起動する必要があるだけでしょうから、
余分な時間は重大問題にはならないでしょう。
あらかじめロードしておく追加のファイルは、
それらをロードするsite-load.el
という名前のライブラリを
書くことで指定できます。
追加データのための領域を確保するために
src/puresize.h
のPURESIZE
の値を増やす必要があるかもしれません。
(十分な大きさになるまで20000ずつ増やして試すこと。)
しかし、マシンが速くなればなるほど、あらかじめロードしておくファイルを
追加することの利点は減少します。
最近のマシンでは、このようにする必要はないでしょう。
loadup.el
がsite-load.el
を読み終えると、
Snarf-documentation
(see Accessing Documentation)を呼び出して、
基本関数やあらかじめロードした関数(および変数)の説明文字列を
それらの説明文字列を格納したファイルetc/DOC
から探します。
ダンプする直前に実行すべきList式を指定するには、
site-init.el
という名前のライブラリにそれらのLisp式を入れておきます。
このファイルは、説明文字列を探し終えてから実行されます。
関数定義や変数定義をあらかじめロードしたいときには、 それを行ってあとでEmacsを実行したときにそれらの説明文字列を 参照できるようにする方法が3つあります。
etc/DOC
を作成するときに
それらのファイルが走査されるようにしておき、
site-load.el
でそれらのファイルをロードする。
site-init.el
でファイルをロードし、
Emacsをインストールするときにそれらのファイルを
Lispファイル向けのインストールディレクトリへコピーする。
byte-compile-dynamic-docstrings
の値にnil
以外を指定し、
site-load.el
かsite-init.el
でそれらのファイルをロードする。
(これには、それらの説明文字列がつねにEmacsの領域を占めてしまう
欠点がある。)
無変更の普通のEmacsにユーザーが期待する機能を変更するようなものを
site-load.el
やsite-init.el
に入れることは勧められません。
読者のサイトでは普通の機能に優先させるべきであると思うときには、
default.el
でそれを行います。
そうすれば、ユーザーは好みに応じて読者が行った変更を無効にできます。
See Start-up Summary。
dump-emacs to-file from-file | Function |
この関数は、Emacsの現在の状態を
実行形式ファイルto-fileへダンプする。
from-file(これは普通は実行形式ファイルtemacs )から
シンボルを取り出す。
すでにダンプしたEmacsでこの関数を使うときには、
|
Emacs Lispでは、ユーザーが作成したLispオブジェクト向けに 2種類のメモリ、普通メモリ(normal storage)と ピュアメモリ(pure storage)を使います。 普通メモリは、Emacsセッション中に新たに作成されるすべてのデータを置く場所です。 普通メモリに関する情報は以下の節を参照してください。 ピュアメモリは、あらかじめロードした標準Lispファイル群の特定のデータ、 つまり、Emacsの実行中にけっして変化しないデータを収めるために使います。
ピュアメモリは、temacs
があらかじめロードする標準Lispライブラリを
ロードしている最中にのみ割り当てられます。
ファイルemacs
では読み出し専用
(これができるオペレーティングシステムでは)と印が付けられ、
当該マシンで同時に実行されているすべてのEmacsのジョブで
メモリ領域を共有できるようにします。
ピュアメモリは拡張できません。
Emacsをコンパイルしたときに固定サイズが割り当てられ、
あらかじめロードするライブラリに対して十分な大きさがないと
temacs
はクラッシュします。
その場合には、ファイルsrc/puresize.h
のコンパイルパラメータ
PURESIZE
を増やす必要があります。
あらかじめロードするライブラリを追加したり標準機能に機能を追加しなければ、
そのようなことは普通は起こらないはずです。
purecopy object | Function |
この関数は、ピュアメモリ内にobjectをコピーしそれを返す。
文字列のコピーでは、ピュアメモリ内に同じ文字の新たな文字列を単純に作る。
ベクトルやコンスセルの内容は再帰的にコピーする。
シンボルなどの他のオブジェクトはコピーせずに無変更でそれらを返す。
マーカをコピーしようとするとエラーを通知する。
この関数は、Emacsを構築してダンプするとき以外ではなにもしない。
普通はファイル |
pure-bytes-used | Variable |
この変数の値は、割り当て済みのピュアメモリのバイト数である。 典型的には、ダンプしたEmacsでは この値は利用可能なピュアメモリの総量にとても近い。 そうでない場合には、あらかじめロードしたライブラリが少ないのであろう。 |
purify-flag | Variable |
この変数は、defun が関数定義をピュアメモリに
コピーすべきかどうかを決定する。
nil 以外であると、関数定義をピュアメモリにコピーする。
Emacsを構築中の初期段階ですべての基本的な関数をロード中には
(これらの関数を共有してガベッジコレクションの対象にしないように)、
このフラグは 実行中のEmacsでこのフラグを変更するべきではない。 |
プログラムがリストを作成したり、(ライブラリをロードするなどして) ユーザーが新たに関数を定義すると、 それらのデータは普通メモリへ置かれます。 普通メモリが足りなくなると、Emacsはオペレーティングシステムに 1kバイトの倍数のブロックでメモリ割り当てを要求します。 各ブロックは1つの種類のLispオブジェクトに使いますから、 シンボル、コンスセル、マーカなどはメモリの異なるブロックに分離されます。 (ベクトル、長い文字列、バッファ、特定の編集向けデータ型などの 比較的大きなものは各オブジェクトごとに独立のブロックを割り当てるが、 短い文字列は8kバイトのブロックに詰め込む。)
あるメモリ部分をしばらく使ってから、 (たとえば)バッファを削除したり オブジェクトに対する最後の参照を削除するなどして 当該メモリを解放することはよくあることです。 Emacsには、このような放置されたメモリを回収する ガベッジコレクタ(garbage collector)があります。 (この名前は伝統的だが、 『ガベッジリサイクル』のほうがこの機能を直観的に表すかもしれない。)
ガベッジコレクタは、Lispプログラムから現時点で参照可能な すべてのLispオブジェクトを探して印を付けることで動作します。 まず、すべてのシンボル、それらの値、それらに関連付けられた関数定義、 および、スタック上の任意のデータは参照可能であると仮定します。 参照可能なオブジェクトから間接的に辿れる任意のオブジェクトも 参照可能です。
印付けが終ったときには、無印であるすべてのオブジェクトは ゴミ(ガベッジ)です。 Lispプログラムやユーザーがなにをしようと、 無印のオブジェクトに辿り着く方法はないのでそれらを参照することは不可能です。 無印のオブジェクトを使っているものはいないので、 それらのメモリ領域は再利用できます。 ガベッジコレクタの2段目の動作(『掃く』(sweep))は、 無印のオブジェクトのメモリ領域を再利用できるようにすることです。
掃き作業では、未使用のコンスセルを自由リスト(free list)に入れて、
将来の割り当てに備えます。
シンボルやマーカについても同様です。
参照可能な文字列は8kバイトのブロックより小さな領域を占めるように詰め込み、
不要になった8kバイトのブロックは解放します。
ベクトル、バッファ、ウィンドウ、他の大きなオブジェクトは、
malloc
やfree
を使って個別に割り当てたり解放します。
Common Lispに関した注意:他のLispと異なり、GNU Emacs Lispでは、 自由リストが空になってもガベッジコレクタを呼び出さない。 そのかわりに、オペレーティングシステムにメモリ割り当てを単純に要求し、
gc-cons-threshold
バイトを使い尽くすまでは処理を継続する。つまり、ガベッジコレクタを明示的に呼び出した直後のLispプログラムの部分では、 (プログラムのその部分で2度目にガベッジコレクタを呼び出すほど 多くのメモリを使わないと仮定すれば) その部分を実行中にはガベッジコレクタが呼ばれないことを保証できるのである。
garbage-collect | コマンド |
このコマンドはガベッジコレクタを実行し、
使用中のメモリ量に関する情報を返す。
(まえのガベッジコレクタの起動後に
gc-cons-threshold バイト以上のLispデータを使うと
自発的なガベッジコレクタの起動を引き起こす。)
((used-conses . free-conses) (used-syms . free-syms) (used-miscs . free-miscs) used-string-chars used-vector-slots (used-floats . free-floats) (used-intervals . free-intervals)) 例を示す。 (garbage-collect) => ((106886 . 13184) (9769 . 0) (7731 . 4651) 347543 121628 (31 . 94) (1273 . 168)) 各要素の意味はつぎのとおりである。
|
garbage-collection-messages | User Option |
この変数がnil 以外であると、
Emacsはガベッジコレクションの始まりと終りにメッセージを表示する。
デフォルト値はnil であり、そのようなメッセージを表示しない。
|
gc-cons-threshold | User Option |
この変数の値は、ガベッジコレクションのあとで
つぎにガベッジコレクションを起こすまでに
Lispオブジェクトに割り当てるべきメモリバイト数である。
コンスセルは8バイト、
文字列は1文字1バイトと数バイトのオーバヘッドといった具合である。
バッファの内容に割り当てたメモリ量は数えない。
この閾値を越えてもただちにつぎのガベッジコレクションは起こらず、
つぎにLispのエバリュエータが呼ばれときに起きる。
最初の閾値は400,000である。 より大きな値を指定すると、ガベッジコレクションの起動回数が少なくなる。 ガベッジコレクションに費す時間を減少できるが、 全体のメモリ使用量を増加させる。 大量のLispデータを作成するようなプログラムを実行するときに設定する。 10,000までの小さな値を指定すると、
ガベッジコレクションの回数を増やせる。
10,000未満の値が意味を持つのはつぎにガベッジコレクションが起きるまでである。
|
garbage-collect
が返す値は、データ型ごとのLispデータのメモリ使用量です。
対照的に、関数memory-limit
は、
Emacsが現在使用中のメモリ総量に関する情報を与えます。
memory-limit | Function |
この関数は、Emacsが最後に割り当てた最終バイトのアドレスを
1024で割ったものを返す。
値を1024で割るのは、Lispの整数に収めるためである。
読者の操作がメモリ使用量にどのように影響するかを調べるのに使える。 |
これらの変数は、Emacsが割り当てたデータ型ごとのメモリ総量に関する
情報を与えます。
これらと(garbage-collect)
が返す値との違いに注意してください。
(garbage-collect)
の値は現存するオブジェクトを数えますが、
これらの変数は、すでに解放したオブジェクトを含めて
割り当てたオブジェクトの個数やサイズを数えます。
cons-cells-consed | Variable |
このEmacsセッションでこれまでに割り当てたコンスセルの総数。 |
floats-consed | Variable |
このEmacsセッションでこれまでに割り当てた浮動小数点数の総数。 |
vector-cells-consed | Variable |
このEmacsセッションでこれまでに割り当てたベクトルセルの総数。 |
symbols-consed | Variable |
このEmacsセッションでこれまでに割り当てたシンボルの総数。 |
string-chars-consed | Variable |
このEmacsセッションでこれまでに割り当てた文字列の総文字数。 |
misc-objects-consed | Variable |
このEmacsセッションでこれまでに割り当てたその他のオブジェクトの総数。 マーカやオーバレイ、ユーザーに見えないある種のオブジェクトを含む。 |
intervals-consed | Variable |
このEmacsセッションでこれまでに割り当てたインターバルの総数。 |
Lisp基本関数は、Cで実装したLisp関数です。 Lispから呼び出すためのCの関数とのインターフェイスの詳細は、 数個のCのマクロで処理しています。 新たにCのコードを書く方法をほんとうに理解する唯一の方法は、 ソースを読むことですが、ここではその一部を説明します。
スペシャルフォームの例は、eval.c
から引用したor
の定義です。
(普通の関数も同じように見える。)
DEFUN ("or", For, Sor, 0, UNEVALLED, 0, "Eval args until one of them yields non-nil; return that value.\n\ The remaining args are not evalled at all.\n\ If all args return nil, return nil.") (args) Lisp_Object args; { register Lisp_Object val; Lisp_Object args_left; struct gcpro gcpro1; if (NULL (args)) return Qnil; args_left = args; GCPRO1 (args_left); do { val = Feval (Fcar (args_left)); if (!NULL (val)) break; args_left = Fcdr (args_left); } while (!NULL (args_left)); UNGCPRO; return val; }
マクロDEFUN
の引数の詳しい説明から始めます。
その雛型はつぎのとおりです。
DEFUN (lname, fname, sname, min, max, interactive, doc)
or
である。
F
を付けるが、
Lispでの名前のダッシュ(-
)はすべて下線に置き換える。
したがって、Cのコードからこの関数を呼び出すには、For
を呼び出す。
引数はLisp_Object
型である必要があることに注意してほしい。
ファイルlisp.h
では、
Lisp_Object
型の値を作成するためのさまざまなマクロや関数を宣言してある。
F
をS
に置き換えたものである。
or
は最小0個の引数を許す。
UNEVALLED
、
評価済みの引数を何個でも受け取ることを表すMANY
(&rest
に等価)でもよい。
UNEVALLED
もMANY
もマクロである。
maxが数であるときには、
それはminより小さくなく、かつ、7より大きくないこと。
interactive
の引数に使う文字列である。
or
の場合には0(空ポインタ)であり、
or
は対話的に呼び出せないことを表す。
値""
は、対話的に呼び出されると
この関数は引数を受け取らないことを表す。
\n\
と書く必要があることを除けば、
Lispで定義する関数の説明文字列のように書く。
特に、最初の行は1つの文であること。
マクロDEFUN
の呼び出しのあとには、
Cの関数に必須な引数名の並びを書き、引数に対する普通のCの宣言を続けます。
引数の最大個数が固定されている関数では、
各Lisp引数向けにCの引数宣言を書き、
それらをすべてLisp_Object
型にします。
Lisp関数に引数の個数に上限がないとき、
それを実装するCの関数は実際には2つの引数を受け取ります。
第1引数はLisp引数の個数であり、
第2引数はそれらの値を収めたブロックのアドレスです。
引数の型はint
とLisp_Object *
です。
関数For
自身の内側では、
マクロGCPRO1
とUNGCPRO
を使っていることに注意してください。
GCPRO1
は、ガベッジコレクションから変数を『保護』するために使います。
つまり、ガベッジコレクタに対してこの変数を調べてその内容を
参照可能なオブジェクトとみなすように指示します。
Feval
やFeval
を直接/間接的に呼び出すものを呼ぶときには、
このようにする必要があります。
そのような場面では、再度参照する意図がある任意のLispオブジェクトは
保護する必要があります。
UNGCPRO
は、この関数での変数の保護を取り消します。
これは明示的に行う必要があります。
ほとんどのデータ型では、少なくともそのオブジェクトへの1つのポインタを 保護すれば十分であり、そのオブジェクトに循環がない限り、 そのオブジェクトへのすべてのポインタは正しく保たれます。 文字列にはこれはあてはまりません。 ガベッジコレクタがそれらを移動するからです。 ガベッジコレクタが文字列を移動すると、 それに対する既知のポインタをすべて再配置し、 それ以外のポインタは不正になります。 したがって、ガベッジコレクタが動く可能性のある任意の部分では、 文字列へのすべてのポインタを保護する必要があります。
マクロGCPRO1
は1つのローカル変数のみを保護します。
2つ保護したい場合にはかわりにGCPRO2
を使います。
GCPRO1
を繰り返しても働きません。
GCPRO3
やGCPRO4
のマクロもあります。
これらのマクロはgcpro1
などのローカル変数を暗黙のうちに使いますが、
読者はこれらを型struct gcpro
で明示的に宣言する必要があります。
したがって、GCPRO2
を使う場合には、
gcpro1
とgcpro2
を宣言する必要があります。
残念ですが、ここではすべての詳細は説明しきれません。
Emacsをいったんダンプしたあとでも静的やグローバルな変数に書き込むのであれば、 それらの変数にはCの初期化構文を使ってはいけません。 初期化構文を伴うそれらの変数は、Emacsをダンプすると (オペレーティングシステムによっては)その結果として 読み出し専用のメモリ領域に割り当てられます。 See Pure Storage。
関数の内側では静的変数を使わずに、
すべての静的変数はファイルのトップレベルに置きます。
オペレーティングシステムによっては
Emacsはキーワードstatic
を空のマクロと定義することもあるので、
これは必要なことなのです。
(このような定義を使うのは、そのようなシステムは、
初期化構文があろうとなかろうと静的と宣言した変数を
ダンプ後には読み出し専用にしてしまうからである。)
Cの関数を定義しただけではLisp基本関数としては使えません。 基本関数に対するLispシンボルを作成し、 その関数セルに適切なsubrオブジェクトを保存する必要があります。 そのコードはつぎのようになります。
defsubr (&subr-structure-name);
ここで、subr-structure-nameはDEFUN
の第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から見えるLisp_Object
型のCの変数を作ります。
DEFVAR_INT
は、Lispからはつねに整数を値として見える
int
型のCの変数を作ります。
DEFVAR_BOOL
は、Lispからはt
かnil
を値として見える
int
型のCの変数を作ります。
ファイルだけに有効な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, "xSpecify coordinate pair: \nXExpression which evals to window: ", "Return non-nil if COORDINATES is in WINDOW.\n\ COORDINATES is a cons of the form (X . Y), X and Y being distances\n\ ... If they are on the border between WINDOW and its right sibling,\n\ `vertical-line' is returned.") (coordinates, window) register Lisp_Object coordinates, window; { int x, y; CHECK_LIVE_WINDOW (window, 0); CHECK_CONS (coordinates, 1); x = XINT (Fcar (coordinates)); y = XINT (Fcdr (coordinates)); switch (coordinates_in_window (XWINDOW (window), &x, &y)) { case 0: /* NOT in window at all. */ return Qnil; case 1: /* In text part of window. */ return Fcons (make_number (x), make_number (y)); case 2: /* In mode line of window. */ return Qmode_line; case 3: /* On right border of window. */ return Qvertical_line; default: abort (); } }
Cのコードでは、関数がCで定義されていない限り、
関数をその名前で呼び出せないことに注意してください。
Lispで書かれた関数を呼び出す方法は、Lispの関数funcall
を
内蔵するFfuncall
を使うことです。
Lisp関数funcall
は任意個数の引数を受け付けるので、
Cでは2つの引数、Lispレベルの引数の個数と
それらの値を収めた一次元の配列を受け取ります。
Lispレベルの最初の引数は呼び出すべきLisp関数であり、
残りはそれに渡す引数です。
Ffuncall
はエバリュエータを呼び出すので、
Ffuncall
を呼び出す周りでは、
ガベッジコレクションからポインタを保護する必要があります。
Cの関数、call0
、call1
、call2
などは、
固定個数の引数を受け取るLisp関数を簡便に呼び出す手軽な方法です。
これらはFfuncall
を呼び出して動作します。
eval.c
は例を調べるにはとてもよいファイルです。
lisp.h
には重要なマクロや関数の定義が入っています。
GNU Emacs Lispは、さまざまな型のデータを扱います。 実際のデータはヒープに保存されていて、 プログラムはポインタを介してそれらを参照します。 ほとんどの実装では、ポインタは32ビット長です。 Emacsをコンパイルしたオペレーティングシステムやマシンの種類に依存しますが、 オブジェクトのアドレスには28ビットを使い、 残りのビットはガベッジコレクションの印や オブジェクトの型を表す識別子であるタグに使います。
Lispオブジェクトはタグ付ポインタとして表現しますから、
任意のオブジェクトのLispデータ型を判定することが可能です。
CのデータLisp_Object
は、任意のデータ型のLispオブジェクトを保持できます。
普通の変数はLisp_Object
型ですから、
Lispの任意の値の任意の型を保持できます。
実際のデータ型は、実行中にのみ判定できます。
関数引数についても同じことがいえます。
特定の型の引数のみを受け付る関数が必要な場合には、
適切な述語(see Type Predicates)
を使って型を明示的に検査する必要があります。
バッファには、Lispプログラマが直接には参照できないフィールドがあります。 それらをCのコードで使っている名前で以下に述べます。 多くはLisp基本関数を介してLispプログラムから間接的に参照できます。
name
save_modified
modtime
auto_save_modified
last_window_start
window-start
(表示開始)位置を保持する。
undo_list
syntax_table_v
downcase_table
upcase_table
case_canon_table
case_eqv_table
display_table
nil
である。
see Display Tables。
markers
backed_up
mark
markers
にも含まれている。
see The Mark。
mark_active
nil
以外である。
local_var_alist
base_buffer
nil
を保持する。
keymap
overlay_center
overlays_before
overlays_after
enable_multibyte_characters
enable-multibyte-characters
の
バッファローカルな値を保持しており、
t
かnil
である。
ウィンドウには以下のような参照可能なフィールドがあります。
frame
mini_p
nil
以外。
buffer
dedicated
nil
以外である。
pointm
start
force_start
nil
以外であると、
Lispプログラムが明示的にウィンドウをスクロールしたことを表す。
ポイントがスクリーンからはみ出しているとつぎの再表示の動作に影響する。
ポイントの周りのテキストをウィンドウに表示するようにスクロールするかわりに、
スクリーン上に位置するようにポイントを移動する。
last_modified
modified
である。
last_point
left
top
height
width
next
nil
である。
prev
nil
である。
parent
親ウィンドウはバッファを表示せず、
その子ウィンドウの形以外には、表示に関してはなんの役割も持たない。
Emacs Lispプログラムでは親ウィンドウを参照せず、
バッファを実際に表示する木の葉にあるウィンドウを操作する。
hscroll
use_time
get-lru-window
がこのフィールドを使う。
display_table
nil
である。
update_mode_line
nil
以外であると、ウィンドウのモード行を更新する必要があることを表す。
base_line_number
nil
。
これは、モード行にポイント位置の行番号を表示するために使われる。
base_line_pos
nil
である。
region_showing
nil
である。
プロセスにはつぎのようなフィールドがあります。
name
command
filter
nil
。
sentinel
nil
。
buffer
pid
childp
nil
以外である。
ネットワーク接続であるとnil
以外。
mark
kill_without_query
nil
以外であると、このプロセスが動作中にEmacsを終了しようとしても
プロセスをキルすることに関して確認を求めない。
raw_status_low
raw_status_high
wait
で返されるプロセス状態の各16ビットを記録する。
status
process-status
が返すべきプロセス状態。
tick
update_tick
pty_flag
nil
以外であり、
パイプを使用している場合にはnil
である。
infd
outfd
subtty
nil
である。)
tty_name
nil
である。
以下は、概念ごとにまとめた標準Emacsのエラーシンボルの完全な一覧です。
一覧には、各シンボルの(シンボルの属性error-message
にある)メッセージと
そのようなエラーが生起する場面の記述への相互参照を示しました。
各エラーシンボルには、属性error-conditions
があり、
これはシンボルのリストです。
通常、このリストは、エラーシンボルそのものとシンボルerror
を含みます。
しばしば、追加のシンボルも含みます。
それらは中間的な分類種別であり、error
より細分化したものですが、
エラーシンボルそのものよりは大分類です。
たとえば、ファイル参照に関するすべてのエラーには、
条件file-error
が入っています。
以下で、特定のエラーシンボルにおいて追加のシンボルを言及していないときには、
そのエラーには追加シンボルがないことを意味します。
特別な例外ですが、エラーシンボルquit
には
条件error
がありません。
これは、中断(quit)をエラーとみなさないからです。
エラーが生起する場面とその処理方法については、See Errors。
シンボル
error
"error"
quit
"Quit"
args-out-of-range
"Args out of range"
arith-error
"Arithmetic error"
/
と%
を参照。
beginning-of-buffer
"Beginning of buffer"
buffer-read-only
"Buffer is read-only"
cyclic-function-indirection
"Symbol's chain of function indirections\
contains a loop"
end-of-buffer
"End of buffer"
end-of-file
"End of file during parsing"
file-error
ではないことに注意。file-already-exists
file-error
。file-date-error
file-error
の小分類。
copy-file
で、
出力ファイルの最終更新日付の設定に失敗すると生起する。file-error
file-error
があると、
データ項目のみからエラーメッセージを作るからである。file-locked
file-error
。file-supersession
file-error
。invalid-function
"Invalid function"
invalid-read-syntax
"Invalid read syntax"
invalid-regexp
"Invalid regexp"
mark-inactive
"Mark inactive"
no-catch
"No catch for tag"
scan-error
"Scan error"
search-failed
"Search failed"
setting-constant
"Attempt to set a constant symbol"
nil
やt
、および、
:
で始まる任意のシンボルは変更できない。undefined-color
"Undefined color"
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"
arith-error
の特別な場合に分類された以下の種類のエラーは、
数学関数を不正に使ったときに特定のシステムで生起します。
domain-error
"Arithmetic domain error"
overflow-error
"Arithmetic overflow error"
range-error
"Arithmetic range error"
singularity-error
"Arithmetic singularity error"
underflow-error
"Arithmetic underflow error"
以下は、各バッファにおいて、自動的にバッファローカルになる Emacsの汎用目的の変数一覧です。 ほとんどのものは、設定したときにだけバッファローカルになります。 これらのごく少数は、各バッファでつねにローカルになります。 多くのLispパッケージで内部使用向けにこのような変数を定義しますが、 それらすべてをここに示すことはしていません。
abbrev-mode
auto-fill-function
buffer-auto-save-file-name
buffer-backed-up
buffer-display-count
buffer-display-table
buffer-file-format
buffer-file-name
buffer-file-number
buffer-file-truename
buffer-file-type
buffer-invisibility-spec
buffer-offer-save
buffer-read-only
buffer-saved-size
buffer-undo-list
cache-long-line-scans
case-fold-search
ctl-arrow
comment-column
default-directory
defun-prompt-regexp
enable-multibyte-characters
fill-column
goal-column
left-margin
local-abbrev-table
local-write-file-hooks
major-mode
mark-active
mark-ring
minor-modes
mode-line-buffer-identification
mode-line-format
mode-line-modified
mode-line-process
mode-name
overwrite-mode
paragraph-separate
paragraph-start
point-before-scroll
require-final-newline
selective-display
selective-display-ellipses
tab-width
truncate-lines
vc-mode
以下のシンボルは、さまざまなキーマップの名前として使われています。 これらの一部はEmacsの始動時に存在しますが、 他のものは関連するモードを使ったときにのみロードされます。 以下は、完全な一覧ではありません。
これらのマップのほとんどすべては、ローカルマップとして使われます。 もちろん、存在するモードの中で、グローバルキーマップを変更するのは Vipモードと端末(terminal)モードだけです。
Buffer-menu-mode-map
c-mode-map
command-history-map
ctl-x-4-map
ctl-x-5-map
ctl-x-map
debugger-mode-map
dired-mode-map
dired-mode
バッファで使う完全なキーマップ。
edit-abbrevs-map
edit-abbrevs
で使う疎なキーマップ。
edit-tab-stops-map
edit-tab-stops
で使う疎なキーマップ。
electric-buffer-menu-mode-map
electric-history-map
emacs-lisp-mode-map
facemenu-menu
facemenu-background-menu
facemenu-face-menu
facemenu-foreground-menu
facemenu-indentation-menu
facemenu-justification-menu
facemenu-special-menu
function-key-map
fundamental-mode-map
Helper-help-map
Info-edit-map
Info-mode-map
isearch-mode-map
key-translation-map
function-key-map
と違って、
もとのキーバインディングに優先する。
see Translating Input。
lisp-interaction-mode-map
lisp-mode-map
menu-bar-edit-menu
menu-bar-files-menu
menu-bar-help-menu
menu-bar-mule-menu
menu-bar-search-menu
menu-bar-tools-menu
mode-specific-map
display-bindings
)において、
ユーザーに有益なようにこの名前を選んだ。
occur-mode-map
query-replace-map
query-replace
やその関連コマンドの応答用に使うキーマップ。
y-or-n-p
やmap-y-or-n-p
もこれを使う。
このマップを使う関数は、プレフィックスキーを使わない。
一度に1つのイベントを探す。
text-mode-map
view-mode-map
以下は、Emacsから適切な場面に呼び出される関数を 読者が指定するためのフック変数の一覧です。
これらのほとんどの変数の名前は-hook
で終ります。
これらは、run-hooks
で実行される
ノーマルフック(normal hooks)です。
そのようなフックの値は関数のリストです。
関数は引数なしで呼び出され、その値は完全に無視します。
このようなフックに新たな関数を追加する推奨方法は、
add-hook
を呼び出すことです。
フックの使い方について詳しくは、See Hooks。
-hooks
や-functions
で終る名前の変数は、
普通、アブノーマルフック(abnormal hooks)です。
それらの値も関数のリストですが、
それらの関数は特別な方法(引数を渡したり、戻り値を使用したり)で
呼び出されます。
これらの変数のごく少数は実際にはノーマルフックですが、
ノーマルフックの名前を-hook
で終えるという慣行を
確立するまえに命名したものです。
-function
で終る名前の変数では、その値は1つの関数です。
(Emacsの旧版では、ノーマルフックでないにも関わらず、
-hook
で終る名前の変数があった。
しかしながら、それらはすべて改名した。)
activate-mark-hook
after-change-function
after-change-functions
after-init-hook
after-insert-file-functions
after-make-frame-hook
after-revert-hook
after-save-hook
auto-fill-function
auto-save-hook
before-change-function
before-change-functions
before-init-hook
before-make-frame-hook
before-revert-hook
blink-paren-function
buffer-access-fontify-functions
c-mode-hook
calendar-load-hook
change-major-mode-hook
command-history-hook
command-line-functions
comment-indent-function
deactivate-mark-hook
diary-display-hook
diary-hook
dired-mode-hook
disabled-command-hook
echo-area-clear-hook
edit-picture-hook
electric-buffer-menu-mode-hook
electric-command-history-hook
electric-help-mode-hook
emacs-lisp-mode-hook
find-file-hooks
find-file-not-found-hooks
first-change-hook
fortran-comment-hook
fortran-mode-hook
ftp-setup-write-file-hooks
ftp-write-file-hook
indent-mim-hook
initial-calendar-window-hook
kill-buffer-hook
kill-buffer-query-functions
kill-emacs-hook
kill-emacs-query-functions
LaTeX-mode-hook
ledit-mode-hook
lisp-indent-function
lisp-interaction-mode-hook
lisp-mode-hook
list-diary-entries-hook
local-write-file-hooks
m2-mode-hook
mail-mode-hook
mail-setup-hook
mark-diary-entries-hook
medit-mode-hook
menu-bar-update-hook
minibuffer-setup-hook
minibuffer-exit-hook
news-mode-hook
news-reply-mode-hook
news-setup-hook
nongregorian-diary-listing-hook
nongregorian-diary-marking-hook
nroff-mode-hook
outline-mode-hook
plain-TeX-mode-hook
post-command-hook
pre-abbrev-expand-hook
pre-command-hook
print-diary-entries-hook
prolog-mode-hook
protect-innocence-hook
redisplay-end-trigger-functions
rmail-edit-mode-hook
rmail-mode-hook
rmail-summary-mode-hook
scheme-indent-hook
scheme-mode-hook
scribe-mode-hook
shell-mode-hook
shell-set-directory-error-hook
suspend-hook
suspend-resume-hook
temp-buffer-show-function
term-setup-hook
terminal-mode-hook
terminal-mode-break-hook
TeX-mode-hook
text-mode-hook
today-visible-calendar-hook
today-invisible-calendar-hook
vi-mode-hook
view-hook
window-configuration-change-hook
window-scroll-functions
window-setup-hook
window-size-change-functions
write-contents-hooks
write-file-hooks
write-region-annotate-functions
"
、表示: Output Functions
"
、文字列: Syntax for Strings
#$
: Docs and Compilation
#@count
: Docs and Compilation
$
、画面表示: Truncation
$
、正規表現: Syntax of Regexps
%
: Arithmetic Operations
%
、書式付け: Formatting Strings
&define
(edebug)
: Specification List
¬
(edebug)
: Specification List
&optional
: Argument List
&optional
(edebug)
: Specification List
&or
(edebug)
: Specification List
&rest
: Argument List
&rest
(edebug)
: Specification List
&
、置換: Replacing Match
'
によるクォート: Quoting
(...)
、リスト: Cons Cell Type
(
、正規表現: Syntax of Regexps
)
、正規表現: Syntax of Regexps
*
: Arithmetic Operations
*scratch*
: Auto Major Mode
*
、正規表現: Syntax of Regexps
*
、対話指定: Using Interactive
+
: Arithmetic Operations
+
、正規表現: Syntax of Regexps
,
(バッククォート)
: Backquote
,@
(バッククォートとの組み合わせ)
: Backquote
-
: Arithmetic Operations
.emacs
: Init File
.emacs
のカスタマイズ: Major Mode Conventions
.
、リスト: Dotted Pair Notation
.
、正規表現: Syntax of Regexps
/
: Arithmetic Operations
/=
: Comparison of Numbers
1+
: Arithmetic Operations
1-
: Arithmetic Operations
2C-mode-map
: Prefix Keys
;
、コメント内: Comments
<
: Comparison of Numbers
<=
: Comparison of Numbers
=
: Comparison of Numbers
>
: Comparison of Numbers
>=
: Comparison of Numbers
?
、正規表現: Syntax of Regexps
?
、文字定数: Character Type
@
、対話指定: Using Interactive
[
、正規表現: Syntax of Regexps
\'
、正規表現: Syntax of Regexps
\<
、正規表現: Syntax of Regexps
\=
、正規表現: Syntax of Regexps
\>
、正規表現: Syntax of Regexps
\`
、正規表現: Syntax of Regexps
\a
: Character Type
\b
: Character Type
\B
、正規表現: Syntax of Regexps
\b
、正規表現: Syntax of Regexps
\e
: Character Type
\f
: Character Type
\n
: Character Type
\n
、置換: Replacing Match
\n
、表示: Output Variables
\r
: Character Type
\S
、正規表現: Syntax of Regexps
\s
、正規表現: Syntax of Regexps
\t
: Character Type
\v
: Character Type
\W
、正規表現: Syntax of Regexps
\w
、正規表現: Syntax of Regexps
\
、シンボル内: Symbol Type
\
、画面表示: Truncation
\
、正規表現: Syntax of Regexps
\
、置換: Replacing Match
\
、表示: Output Functions
\
、文字定数: Character Type
\
、文字列: Syntax for Strings
]
、正規表現: Syntax of Regexps
^
、正規表現: Syntax of Regexps
`
: Backquote
abbrev-all-caps
: Abbrev Expansion
abbrev-expansion
: Abbrev Expansion
abbrev-file-name
: Abbrev Files
abbrev-mode
: Abbrev Mode
abbrev-prefix-mark
: Abbrev Expansion
abbrev-start-location
: Abbrev Expansion
abbrev-start-location-buffer
: Abbrev Expansion
abbrev-symbol
: Abbrev Expansion
abbrev-table-name-list
: Abbrev Tables
abbreviate-file-name
: Directory Names
abbrevs-changed
: Abbrev Files
abort-recursive-edit
: Recursive Editing
abs
: Comparison of Numbers
accept-process-output
: Accepting Output
access-file
: Testing Accessibility
accessible-keymaps
: Scanning Keymaps
acos
: Math Functions
activate-mark-hook
: The Mark
active-minibuffer-window
: Minibuffer Misc
ad-activate
: Activation of Advice
ad-activate-all
: Activation of Advice
ad-activate-regexp
: Activation of Advice
ad-add-advice
: Computed Advice
ad-deactivate
: Activation of Advice
ad-deactivate-all
: Activation of Advice
ad-deactivate-regexp
: Activation of Advice
ad-default-compilation-action
: Activation of Advice
ad-define-subr-args
: Subr Arguments
ad-disable-advice
: Enabling Advice
ad-disable-regexp
: Enabling Advice
ad-do-it
: Around-Advice
ad-enable-advice
: Enabling Advice
ad-enable-regexp
: Enabling Advice
ad-get-arg
: Argument Access in Advice
ad-get-args
: Argument Access in Advice
ad-return-value
: Defining Advice
ad-set-arg
: Argument Access in Advice
ad-set-args
: Argument Access in Advice
ad-start-advice
: Activation of Advice
ad-stop-advice
: Activation of Advice
ad-update-regexp
: Activation of Advice
adaptive-fill-first-line-regexp
: Adaptive Fill
adaptive-fill-function
: Adaptive Fill
adaptive-fill-mode
: Adaptive Fill
adaptive-fill-regexp
: Adaptive Fill
add-abbrev
: Defining Abbrevs
add-hook
: Hooks
add-name-to-file
: Changing Files
add-text-properties
: Changing Properties
add-to-invisibility-spec
: Invisible Text
add-to-list
: Setting Variables
after-change-function
: Change Hooks
after-change-functions
: Change Hooks
after-find-file
: Subroutines of Visiting
after-init-hook
: Init File
after-insert-file-functions
: Saving Properties
after-load-alist
: Hooks for Loading
after-make-frame-hook
: Creating Frames
after-revert-hook
: Reverting
after-save-hook
: Saving Buffers
after-string
(オーバレイ属性)
: Overlay Properties
all-christian-calendar-holidays
: Holiday Customizing
all-completions
: Basic Completion
all-hebrew-calendar-holidays
: Holiday Customizing
all-islamic-calendar-holidays
: Holiday Customizing
and
: Combining Conditions
append
: Building Lists
append-to-file
: Writing to Files
apply
: Calling Functions
apply
とデバッグ: Internals of Debugger
appt-audible
: Appt Customizing
appt-delete-window-function
: Appt Customizing
appt-disp-window-function
: Appt Customizing
appt-display-duration
: Appt Customizing
appt-display-mode-line
: Appt Customizing
appt-message-warning-time
: Appt Customizing
appt-msg-window
: Appt Customizing
appt-visible
: Appt Customizing
apropos
: Help Functions
aref
: Array Functions
arith-error
、除算: Arithmetic Operations
arith-error
の例: Handling Errors
arrayp
: Array Functions
aset
: Array Functions
ash
: Bitwise Operations
asin
: Math Functions
ask-user-about-lock
: File Locks
ask-user-about-supersession-threat
: Modification Time
assoc
: Association Lists
assoc-default
: Association Lists
assoc-ignore-case
: Text Comparison
assoc-ignore-representation
: Text Comparison
assq
: Association Lists
atan
: Math Functions
atom
: List-related Predicates
auto-fill-function
: Auto Filling
auto-mode-alist
: Auto Major Mode
auto-save-default
: Auto-Saving
auto-save-file-format
: Format Conversion
auto-save-file-name-p
: Auto-Saving
auto-save-hook
: Auto-Saving
auto-save-interval
: Auto-Saving
auto-save-list-file-name
: Auto-Saving
auto-save-mode
: Auto-Saving
auto-save-timeout
: Auto-Saving
auto-save-visited-file-name
: Auto-Saving
autoload
: Autoload
back-to-indentation
: Motion by Indent
backtrace
: Internals of Debugger
backtrace-debug
: Internals of Debugger
backtrace-frame
: Internals of Debugger
backup-buffer
: Making Backups
backup-by-copying
: Rename or Copy
backup-by-copying-when-linked
: Rename or Copy
backup-by-copying-when-mismatch
: Rename or Copy
backup-enable-predicate
: Making Backups
backup-file-name-p
: Backup Names
backup-inhibited
: Making Backups
backward-char
: Character Motion
backward-delete-char-untabify
: Deletion
backward-delete-char-untabify-method
: Deletion
backward-list
: List Motion
backward-prefix-chars
: Motion and Syntax
backward-sexp
: List Motion
backward-to-indentation
: Motion by Indent
backward-word
: Word Motion
barf-if-buffer-read-only
: Read Only Buffers
batch-byte-compile
: Compilation Functions
baud-rate
: Terminal Output
beep
: Beeping
before-change-function
: Change Hooks
before-change-functions
: Change Hooks
before-init-hook
: Init File
before-make-frame-hook
: Creating Frames
before-revert-hook
: Reverting
before-string
(オーバレイ属性)
: Overlay Properties
beginning-of-buffer
: Buffer End Motion
beginning-of-defun
: List Motion
beginning-of-line
: Text Lines
blink-matching-delay
: Blinking
blink-matching-open
: Blinking
blink-matching-paren
: Blinking
blink-matching-paren-distance
: Blinking
blink-paren-function
: Blinking
bobp
: Near Point
bold
(フェイス名)
: Standard Faces
bold-italic
(フェイス名)
: Standard Faces
bolp
: Near Point
bool-vector-p
: Bool-Vectors
boundp
: Void Variables
buffer-access-fontified-property
: Lazy Properties
buffer-access-fontify-functions
: Lazy Properties
buffer-auto-save-file-name
: Auto-Saving
buffer-backed-up
: Making Backups
buffer-base-buffer
: Indirect Buffers
buffer-disable-undo
: Maintaining Undo
buffer-display-table
: Active Display Table
buffer-display-time
: Buffers and Windows
buffer-enable-undo
: Maintaining Undo
buffer-end
: Point
buffer-file-coding-system
: Encoding and I/O
buffer-file-format
: Format Conversion
buffer-file-name
: Buffer File Name
buffer-file-number
: Buffer File Name
buffer-file-truename
: Buffer File Name
buffer-file-type
: MS-DOS File Types
buffer-flush-undo
: Maintaining Undo
buffer-invisibility-spec
: Invisible Text
buffer-list
: The Buffer List
buffer-local-variables
: Creating Buffer-Local
Buffer-menu-mode-map
: Standard Keymaps
buffer-modified-p
: Buffer Modification
buffer-modified-tick
: Buffer Modification
buffer-name
: Buffer Names
buffer-name-history
: Minibuffer History
buffer-offer-save
: Killing Buffers
buffer-read-only
: Read Only Buffers
buffer-saved-size
: Auto-Saving
buffer-size
: Point
buffer-string
: Buffer Contents
buffer-substring
: Buffer Contents
buffer-substring-no-properties
: Buffer Contents
buffer-undo-list
: Undo
bufferp
: Buffer Basics
bury-buffer
: The Buffer List
byte-code
: Compilation Functions
byte-code-function-p
: What Is a Function
byte-compile
: Compilation Functions
byte-compile-dynamic
: Dynamic Loading
byte-compile-dynamic-docstrings
: Docs and Compilation
byte-compile-file
: Compilation Functions
byte-recompile-directory
: Compilation Functions
C-M-x
: Instrumenting
c-mode-map
: Standard Keymaps
c-mode-syntax-table
: Standard Syntax Tables
caar
: List Elements
cache-long-line-scans
: Truncation
cadr
: List Elements
calendar-date-display-form
: Date Display Format
calendar-daylight-savings-ends
: Daylight Savings
calendar-daylight-savings-ends-time
: Daylight Savings
calendar-daylight-savings-starts
: Daylight Savings
calendar-daylight-savings-starts-time
: Daylight Savings
calendar-daylight-time-offset
: Daylight Savings
calendar-holiday-marker
: Calendar Customizing
calendar-holidays
: Holiday Customizing
calendar-load-hook
: Calendar Customizing
calendar-mark-today
: Calendar Customizing
calendar-star-date
: Calendar Customizing
calendar-time-display-form
: Time Display Format
calendar-today-marker
: Calendar Customizing
call-interactively
: Interactive Call
call-process
: Synchronous Processes
call-process-region
: Synchronous Processes
cancel-debug-on-entry
: Function Debugging
cancel-timer
: Timers
capitalize
: Case Conversion
capitalize-region
: Case Changes
capitalize-word
: Case Changes
car
: List Elements
car-safe
: List Elements
case-fold-search
: Searching and Case
case-replace
: Searching and Case
case-table-p
: Case Tables
catch
: Catch and Throw
category
(オーバレイ属性)
: Overlay Properties
category
(テキスト属性)
: Special Properties
category-docstring
: Categories
category-set-mnemonics
: Categories
category-table
: Categories
category-table-p
: Categories
cdar
: List Elements
cddr
: List Elements
cdr
: List Elements
cdr-safe
: List Elements
ceiling
: Numeric Conversions
change-major-mode-hook
: Creating Buffer-Local
char-after
: Near Point
char-before
: Near Point
char-bytes
: Splitting Characters
char-category-set
: Categories
char-charset
: Character Sets
char-equal
: Text Comparison
char-or-string-p
: Predicates for Strings
char-syntax
: Syntax Table Functions
char-table-extra-slot
: Char-Tables
char-table-p
: Char-Tables
char-table-parent
: Char-Tables
char-table-range
: Char-Tables
char-table-subtype
: Char-Tables
char-to-string
: String Conversion
char-valid-p
: Character Codes
char-width
: Width
charset-dimension
: Chars and Bytes
charset-list
: Character Sets
charsetp
: Character Sets
check-coding-system
: Lisp and Coding Systems
checkdoc-minor-mode
: Documentation Tips
christian-holidays
: Holiday Customizing
cl
: Lisp History
cl-specs.el
: Instrumenting
cl.el
(edebug)
: Instrumenting
clear-abbrev-table
: Abbrev Tables
clear-visited-file-modtime
: Modification Time
throw
のみ: Catch and Throw
rplaca
とsetcar
: Modifying Lists
set
はローカル: Setting Variables
union
とintersection
の欠落: Sets And Lists
eq
: Comparison of Numbers
coding-system-change-eol-conversion
: Lisp and Coding Systems
coding-system-change-text-conversion
: Lisp and Coding Systems
coding-system-for-read
: Specifying Coding Systems
coding-system-for-write
: Specifying Coding Systems
coding-system-get
: Coding System Basics
coding-system-list
: Lisp and Coding Systems
coding-system-p
: Lisp and Coding Systems
combine-after-change-calls
: Change Hooks
command-debug-status
: Internals of Debugger
command-execute
: Interactive Call
command-history
: Command History
command-history-map
: Standard Keymaps
command-line
: Command Line Arguments
command-line-args
: Command Line Arguments
command-line-functions
: Command Line Arguments
command-line-processed
: Command Line Arguments
command-switch-alist
: Command Line Arguments
commandp
: Interactive Call
commandp
の例: High-Level Completion
compare-buffer-substrings
: Comparing Text
compare-strings
: Text Comparison
compare-window-configurations
: Window Configurations
compile-defun
: Compilation Functions
completing-read
: Minibuffer Completion
completion-auto-help
: Completion Commands
completion-ignore-case
: Basic Completion
completion-ignored-extensions
: File Name Completion
compute-motion
: Screen Lines
concat
: Creating Strings
cond
: Conditionals
condition-case
: Handling Errors
cons
: Building Lists
cons-cells-consed
: Memory Usage
consp
: List-related Predicates
continue-process
: Signals to Processes
Control-X-prefix
: Prefix Keys
convert-standard-filename
: Standard File Names
coordinates-in-window-p
: Coordinates and Windows
copy-alist
: Association Lists
copy-category-table
: Categories
copy-face
: Face Functions
copy-file
: Changing Files
copy-keymap
: Creating Keymaps
copy-marker
: Creating Markers
copy-region-as-kill
: Kill Functions
copy-sequence
: Sequence Functions
copy-syntax-table
: Syntax Table Functions
cos
: Math Functions
count-lines
: Text Lines
count-loop
: A Sample Function Description
create-file-buffer
: Subroutines of Visiting
create-fontset-from-fontset-spec
: Fontsets
ctl-arrow
: Usual Display
ctl-x-4-map
: Prefix Keys
ctl-x-5-map
: Prefix Keys
ctl-x-map
: Prefix Keys
current-buffer
: Current Buffer
current-case-table
: Case Tables
current-column
: Columns
current-fill-column
: Margins
current-frame-configuration
: Frame Configurations
current-global-map
: Active Keymaps
current-indentation
: Primitive Indent
current-input-method
: Input Methods
current-input-mode
: Input Modes
current-justification
: Filling
current-kill
: Low-Level Kill Ring
current-left-margin
: Margins
current-local-map
: Active Keymaps
current-message
: The Echo Area
current-minor-mode-maps
: Active Keymaps
current-prefix-arg
: Prefix Command Arguments
current-time
: Time of Day
current-time-string
: Time of Day
current-time-zone
: Time of Day
current-window-configuration
: Window Configurations
cursor-in-echo-area
: The Echo Area
cust-print
: Printing in Edebug
data-directory
: Help Functions
deactivate-mark
: The Mark
deactivate-mark-hook
: The Mark
debug
: Invoking the Debugger
debug-ignored-errors
: Error Debugging
debug-on-entry
: Function Debugging
debug-on-error
: Error Debugging
debug-on-error
の利用: Processing of Errors
debug-on-next-call
: Internals of Debugger
debug-on-quit
: Infinite Loops
debug-on-signal
: Error Debugging
debugger
: Internals of Debugger
debugger-mode-map
: Standard Keymaps
decode-coding-region
: Explicit Encoding
decode-coding-string
: Explicit Encoding
decode-time
: Time Conversion
def-edebug-spec
: Instrumenting Macro Calls
defadvice
: Defining Advice
defalias
: Defining Functions
default
(フェイス名)
: Standard Faces
default-abbrev-mode
: Abbrev Mode
default-boundp
: Default Value
default-buffer-file-type
: MS-DOS File Types
default-case-fold-search
: Searching and Case
default-ctl-arrow
: Usual Display
default-directory
: File Name Expansion
default-enable-multibyte-characters
: Text Representations
default-file-modes
: Changing Files
default-fill-column
: Margins
default-frame-alist
: Initial Parameters
default-input-method
: Input Methods
default-justification
: Filling
default-major-mode
: Auto Major Mode
default-minibuffer-frame
: Minibuffers and Frames
default-mode-line-format
: Mode Line Variables
default-process-coding-system
: Default Coding Systems
default-text-properties
: Examining Properties
default-truncate-lines
: Truncation
default-value
: Default Value
default.el
: Start-up Summary
defconst
: Defining Variables
defcustom
: Variable Definitions
defface
: Defining Faces
defgroup
: Group Definitions
define-abbrev
: Defining Abbrevs
define-abbrev-table
: Abbrev Tables
define-category
: Categories
define-derived-mode
: Derived Modes
define-key
: Changing Key Bindings
define-key-after
: Modifying Menus
define-logical-name
: Changing Files
define-prefix-command
: Prefix Keys
defining-kbd-macro
: Keyboard Macros
defmacro
: Defining Macros
defsubst
: Inline Functions
defun
: Defining Functions
defun-prompt-regexp
: List Motion
defvar
: Defining Variables
delete
: Sets And Lists
delete-auto-save-file-if-necessary
: Auto-Saving
delete-auto-save-files
: Auto-Saving
delete-backward-char
: Deletion
delete-blank-lines
: User-Level Deletion
delete-char
: Deletion
delete-directory
: Create/Delete Dirs
delete-exited-processes
: Deleting Processes
delete-file
: Changing Files
delete-frame
: Deleting Frames
delete-frame
イベント: Misc Events
delete-horizontal-space
: User-Level Deletion
delete-indentation
: User-Level Deletion
delete-old-versions
: Numbered Backups
delete-other-windows
: Deleting Windows
delete-overlay
: Managing Overlays
delete-process
: Deleting Processes
delete-region
: Deletion
delete-to-left-margin
: Margins
delete-window
: Deleting Windows
delete-windows-on
: Deleting Windows
delq
: Sets And Lists
describe-bindings
: Scanning Keymaps
describe-buffer-case-table
: Case Tables
describe-mode
: Mode Help
describe-prefix-bindings
: Help Functions
detect-coding-region
: Lisp and Coding Systems
detect-coding-string
: Lisp and Coding Systems
diary-anniversary
: Sexp Diary Entries
diary-astro-day-number
: Sexp Diary Entries
diary-cyclic
: Sexp Diary Entries
diary-date
: Sexp Diary Entries
diary-date-forms
: Diary Customizing
diary-day-of-year
: Sexp Diary Entries
diary-display-hook
: Fancy Diary Display
diary-entry-marker
: Calendar Customizing
diary-float
: Sexp Diary Entries
diary-french-date
: Sexp Diary Entries
diary-hebrew-date
: Sexp Diary Entries
diary-islamic-date
: Sexp Diary Entries
diary-iso-date
: Sexp Diary Entries
diary-julian-date
: Sexp Diary Entries
diary-list-include-blanks
: Fancy Diary Display
diary-mayan-date
: Sexp Diary Entries
diary-omer
: Sexp Diary Entries
diary-parasha
: Sexp Diary Entries
diary-phases-of-moon
: Sexp Diary Entries
diary-remind
: Sexp Diary Entries
diary-rosh-hodesh
: Sexp Diary Entries
diary-sabbath-candles
: Sexp Diary Entries
diary-sunrise-sunset
: Sexp Diary Entries
diary-yahrzeit
: Sexp Diary Entries
digit-argument
: Prefix Command Arguments
ding
: Beeping
directory-abbrev-alist
: Directory Names
directory-file-name
: Directory Names
directory-files
: Contents of Directories
dired-kept-versions
: Numbered Backups
dired-mode-map
: Standard Keymaps
disable-command
: Disabling Commands
disabled
: Disabling Commands
disabled-command-hook
: Disabling Commands
disassemble
: Disassembly
discard-input
: Event Input Misc
display-buffer
: Choosing Window
display-buffer-function
: Choosing Window
display-completion-list
: Completion Commands
display-table-slot
: Display Table Format
do-auto-save
: Auto-Saving
doc-directory
: Accessing Documentation
documentation
: Accessing Documentation
documentation-property
: Accessing Documentation
DOC
(説明文)ファイル: Documentation Basics
double-click-time
: Repeat Events
down-list
: List Motion
downcase
: Case Conversion
downcase-region
: Case Changes
downcase-word
: Case Changes
drag-n-drop
イベント: Misc Events
dump-emacs
: Building Emacs
easy-mmode-define-minor-mode
: Easy-Mmode
echo-area-clear-hook
: The Echo Area
echo-keystrokes
: The Echo Area
edebug
: Source Breakpoints, Edebug
edebug-all-defs
: Edebug Options
edebug-all-forms
: Edebug Options
edebug-continue-kbd-macro
: Edebug Options
edebug-display-freq-count
: Coverage Testing
edebug-eval-top-level-form
: Instrumenting
edebug-global-break-condition
: Edebug Options
edebug-initial-mode
: Edebug Options
edebug-on-error
: Edebug Options
edebug-on-quit
: Edebug Options
edebug-print-circle
: Printing in Edebug
edebug-print-length
: Printing in Edebug
edebug-print-level
: Printing in Edebug
edebug-print-trace-after
: Trace Buffer
edebug-print-trace-before
: Trace Buffer
edebug-save-displayed-buffer-points
: Edebug Options
edebug-save-windows
: Edebug Options
edebug-set-global-break-condition
: Global Break Condition
edebug-setup-hook
: Edebug Options
edebug-test-coverage
: Edebug Options
edebug-trace
: Edebug Options, Trace Buffer
edebug-tracing
: Trace Buffer
edebug-unwrap
: Specification List
edit-abbrevs-map
: Standard Keymaps
edit-and-eval-command
: Object from Minibuffer
edit-tab-stops-map
: Standard Keymaps
electric-buffer-menu-mode-map
: Standard Keymaps
electric-future-map
: A Sample Variable Description
electric-history-map
: Standard Keymaps
elp.el
: Compilation Tips
elt
: Sequence Functions
emacs-build-time
: Version Info
emacs-lisp-mode-map
: Standard Keymaps
emacs-lisp-mode-syntax-table
: Standard Syntax Tables
emacs-major-version
: Version Info
emacs-minor-version
: Version Info
emacs-pid
: System Environment
emacs-version
: Version Info
emacs/etc/DOC-version
: Documentation Basics
EMACSLOADPATH
環境変数: Library Search
enable-command
: Disabling Commands
enable-flow-control
: Flow Control
enable-flow-control-on
: Flow Control
enable-local-eval
: Auto Major Mode
enable-local-variables
: Auto Major Mode
enable-multibyte-characters
: Text Representations
enable-recursive-minibuffers
: Minibuffer Misc
encode-coding-region
: Explicit Encoding
encode-coding-string
: Explicit Encoding
encode-time
: Time Conversion
end-of-buffer
: Buffer End Motion
end-of-defun
: List Motion
end-of-file(ファイルの終り)
: Input Functions
end-of-line
: Text Lines
enlarge-window
: Resizing Windows
enlarge-window-horizontally
: Resizing Windows
eobp
: Near Point
eolp
: Near Point
eq
: Equality Predicates
equal
: Equality Predicates
erase-buffer
: Deletion
error
: Signaling Errors
error-conditions
: Error Symbols
error-message-string
: Handling Errors
error
、デバッグ: Invoking the Debugger
esc-map
: Prefix Keys
ESC-prefix
: Prefix Keys
etc/DOC-version
: Documentation Basics
eval
: Eval
eval-after-load
: Hooks for Loading
eval-and-compile
: Eval During Compile
eval-current-buffer
: Eval
eval-current-buffer
(edebug)
: Instrumenting
eval-defun
(edebug)
: Instrumenting
eval-expression
(edebug)
: Instrumenting
eval-minibuffer
: Object from Minibuffer
eval-region
: Eval
eval-region
(edebug)
: Instrumenting
eval-when-compile
: Eval During Compile
eval
とデバッグ: Internals of Debugger
evaporate
(オーバレイ属性)
: Overlay Properties
event-basic-type
: Classifying Events
event-click-count
: Repeat Events
event-convert-list
: Classifying Events
event-end
: Accessing Events
event-modifiers
: Classifying Events
event-start
: Accessing Events
eventp
: Input Events
exec-directory
: Subprocess Creation
exec-path
: Subprocess Creation
execute-extended-command
: Interactive Call
execute-kbd-macro
: Keyboard Macros
executing-macro
: Keyboard Macros
exit
: Recursive Editing
exit-minibuffer
: Minibuffer Misc
exit-recursive-edit
: Recursive Editing
exp
: Math Functions
expand-abbrev
: Abbrev Expansion
expand-file-name
: File Name Expansion
expt
: Math Functions
extended-command-history
: Minibuffer History
extra-keyboard-modifiers
: Translating Input
face
(オーバレイ属性)
: Overlay Properties
face
(テキスト属性)
: Special Properties
face-background
: Face Functions
face-bold-p
: Face Functions
face-differs-from-default-p
: Face Functions
face-documentation
: Face Functions
face-equal
: Face Functions
face-font
: Face Functions
face-foreground
: Face Functions
face-id
: Face Functions
face-italic-p
: Face Functions
face-list
: Face Functions
face-stipple
: Face Functions
face-underline-p
: Face Functions
facemenu-background-menu
: Standard Keymaps
facemenu-face-menu
: Standard Keymaps
facemenu-foreground-menu
: Standard Keymaps
facemenu-indentation-menu
: Standard Keymaps
facemenu-justification-menu
: Standard Keymaps
facemenu-keymap
: Prefix Keys
facemenu-menu
: Standard Keymaps
facemenu-special-menu
: Standard Keymaps
facep
: Faces
fancy-diary-display
: Fancy Diary Display
fboundp
: Function Cells
fceiling
: Rounding Operations
feature-unload-hook
: Unloading
featurep
: Named Features
features
: Named Features
fetch-bytecode
: Dynamic Loading
ffloor
: Rounding Operations
file-accessible-directory-p
: Testing Accessibility
file-already-exists
: Changing Files
file-attributes
: File Attributes
file-coding-system-alist
: Default Coding Systems
file-directory-p
: Kinds of Files
file-error
: How Programs Do Loading
file-executable-p
: Testing Accessibility
file-exists-p
: Testing Accessibility
file-local-copy
: Magic File Names
file-locked
: File Locks
file-locked-p
: File Locks
file-modes
: File Attributes
file-name-absolute-p
: Relative File Names
file-name-all-completions
: File Name Completion
file-name-all-versions
: Contents of Directories
file-name-as-directory
: Directory Names
file-name-buffer-file-type-alist
: MS-DOS File Types
file-name-completion
: File Name Completion
file-name-directory
: File Name Components
file-name-history
: Minibuffer History
file-name-nondirectory
: File Name Components
file-name-sans-extension
: File Name Components
file-name-sans-versions
: File Name Components
file-newer-than-file-p
: Testing Accessibility
file-newest-backup
: Backup Names
file-nlinks
: File Attributes
file-ownership-preserved-p
: Testing Accessibility
file-precious-flag
: Saving Buffers
file-readable-p
: Testing Accessibility
file-regular-p
: Kinds of Files
file-relative-name
: File Name Expansion
file-supersession
: Modification Time
file-symlink-p
: Kinds of Files
file-truename
: Truenames
file-writable-p
: Testing Accessibility
fill-column
: Margins
fill-context-prefix
: Adaptive Fill
fill-individual-paragraphs
: Filling
fill-individual-varying-indent
: Filling
fill-nobreak-predicate
: Margins
fill-paragraph
: Filling
fill-paragraph-function
: Filling
fill-prefix
: Margins
fill-region
: Filling
fill-region-as-paragraph
: Filling
fillarray
: Array Functions
find-backup-file-name
: Backup Names
find-charset-region
: Scanning Charsets
find-charset-string
: Scanning Charsets
find-coding-systems-for-charsets
: Lisp and Coding Systems
find-coding-systems-region
: Lisp and Coding Systems
find-coding-systems-string
: Lisp and Coding Systems
find-file
: Visiting Functions
find-file-hooks
: Visiting Functions
find-file-name-handler
: Magic File Names
find-file-noselect
: Visiting Functions
find-file-not-found-hooks
: Visiting Functions
find-file-other-window
: Visiting Functions
find-file-read-only
: Visiting Functions
find-operation-coding-system
: Default Coding Systems
first-change-hook
: Change Hooks
fixup-whitespace
: User-Level Deletion
float
: Numeric Conversions
floatp
: Predicates on Numbers
floats-consed
: Memory Usage
floor
: Numeric Conversions
fmakunbound
: Function Cells
focus-follows-mouse
: Input Focus
following-char
: Near Point
font-lock-beginning-of-syntax-function
: Other Font Lock Variables
font-lock-builtin-face
: Faces for Font Lock
font-lock-comment-face
: Faces for Font Lock
font-lock-constant-face
: Faces for Font Lock
font-lock-defaults
: Font Lock Basics
font-lock-function-name-face
: Faces for Font Lock
font-lock-keyword-face
: Faces for Font Lock
font-lock-keywords
: Search-based Fontification
font-lock-keywords-case-fold-search
: Other Font Lock Variables
font-lock-keywords-only
: Other Font Lock Variables
font-lock-mark-block-function
: Other Font Lock Variables
font-lock-string-face
: Faces for Font Lock
font-lock-syntactic-keywords
: Syntactic Font Lock
font-lock-syntax-table
: Other Font Lock Variables
font-lock-type-face
: Faces for Font Lock
font-lock-variable-name-face
: Faces for Font Lock
font-lock-warning-face
: Faces for Font Lock
foo
: A Sample Function Description
for
: Argument Evaluation
force-mode-line-update
: Mode Line Format
format
: Formatting Strings
format-alist
: Format Conversion
format-find-file
: Format Conversion
format-insert-file
: Format Conversion
format-time-string
: Time Conversion
format-write-file
: Format Conversion
forward-char
: Character Motion
forward-comment
: Parsing Expressions
forward-line
: Text Lines
forward-list
: List Motion
forward-sexp
: List Motion
forward-to-indentation
: Motion by Indent
forward-word
: Word Motion
frame-background-mode
: Defining Faces
frame-char-height
: Size and Position
frame-char-width
: Size and Position
frame-height
: Size and Position
frame-list
: Finding All Frames
frame-live-p
: Deleting Frames
frame-parameters
: Parameter Access
frame-pixel-height
: Size and Position
frame-pixel-width
: Size and Position
frame-selected-window
: Frames and Windows
frame-title-format
: Frame Titles
frame-top-window
: Frames and Windows
frame-update-face-colors
: Face Functions
frame-visible-p
: Visibility of Frames
frame-width
: Size and Position
framep
: Frames
fround
: Rounding Operations
fset
: Function Cells
ftp-login
: Cleanups
ftruncate
: Rounding Operations
funcall
: Calling Functions
funcall
とデバッグ: Internals of Debugger
function
: Anonymous Functions
function-key-map
: Translating Input
functionp
: What Is a Function
fundamental-mode
: Auto Major Mode
fundamental-mode-abbrev-table
: Standard Abbrev Tables
fundamental-mode-map
: Standard Keymaps
garbage-collect
: Garbage Collection
garbage-collection-messages
: Garbage Collection
gc-cons-threshold
: Garbage Collection
general-holidays
: Holiday Customizing
generate-new-buffer
: Creating Buffers
generate-new-buffer-name
: Buffer Names
get
: Symbol Plists
get-buffer
: Buffer Names
get-buffer-create
: Creating Buffers
get-buffer-process
: Process Buffers
get-buffer-window
: Buffers and Windows
get-buffer-window-list
: Buffers and Windows
get-char-property
: Examining Properties
get-file-buffer
: Buffer File Name
get-file-char
: Input Streams
get-largest-window
: Selecting Windows
get-lru-window
: Selecting Windows
get-process
: Process Information
get-register
: Registers
get-text-property
: Examining Properties
get-unused-category
: Categories
getenv
: System Environment
global-abbrev-table
: Standard Abbrev Tables
global-key-binding
: Functions for Key Lookup
global-map
: Active Keymaps
global-mode-string
: Mode Line Variables
global-set-key
: Key Binding Commands
global-unset-key
: Key Binding Commands
glyph-table
: Glyphs
goto-char
: Character Motion
goto-line
: Text Lines
hack-local-variables
: Auto Major Mode
handle-switch-frame
: Input Focus
hebrew-holidays
: Holiday Customizing
help-char
: Help Functions
help-command
: Help Functions
help-event-list
: Help Functions
help-form
: Help Functions
help-map
: Help Functions
Helper-describe-bindings
: Help Functions
Helper-help
: Help Functions
Helper-help-map
: Standard Keymaps
highlight
(フェイス名)
: Standard Faces
holidays-in-diary-buffer
: Diary Customizing
HOME
、環境変数: Subprocess Creation
icon-title-format
: Frame Titles
iconify-frame
: Visibility of Frames
iconify-frame
イベント: Misc Events
identity
: Calling Functions
if
: Conditionals
ignore
: Calling Functions
ignored-local-variables
: Auto Major Mode
imenu-case-fold-search
: Imenu
imenu-create-index-function
: Imenu
imenu-extract-index-name-function
: Imenu
imenu-generic-expression
: Imenu
imenu-index-alist
: Imenu
imenu-prev-index-position-function
: Imenu
imenu-syntax-alist
: Imenu
inc
: Simple Macro
include-other-diary-files
: Fancy Diary Display
indent-according-to-mode
: Mode-Specific Indent
indent-code-rigidly
: Region Indent
indent-for-tab-command
: Mode-Specific Indent
indent-line-function
: Mode-Specific Indent
indent-region
: Region Indent
indent-region-function
: Region Indent
indent-relative
: Relative Indent
indent-relative-maybe
: Relative Indent
indent-rigidly
: Region Indent
indent-tabs-mode
: Primitive Indent
indent-to
: Primitive Indent
indent-to-left-margin
: Margins
indirect-function
: Function Indirection
Info-edit-map
: Standard Keymaps
Info-mode-map
: Standard Keymaps
inhibit-default-init
: Init File
inhibit-eol-conversion
: Specifying Coding Systems
inhibit-file-name-handlers
: Magic File Names
inhibit-file-name-operation
: Magic File Names
inhibit-point-motion-hooks
: Special Properties
inhibit-quit
: Quitting
inhibit-read-only
: Read Only Buffers
inhibit-startup-echo-area-message
: Start-up Summary
inhibit-startup-message
: Start-up Summary
init-file-user
: User Identification
initial-calendar-window-hook
: Calendar Customizing
initial-frame-alist
: Initial Parameters
initial-major-mode
: Auto Major Mode
input-method-alist
: Input Methods
input-method-function
: Reading One Event
input-pending-p
: Event Input Misc
insert
: Insertion
insert-abbrev-table-description
: Abbrev Tables
insert-and-inherit
: Sticky Properties
insert-before-markers
: Insertion
insert-before-markers-and-inherit
: Sticky Properties
insert-behind-hooks
(オーバレイ属性)
: Overlay Properties
insert-behind-hooks
(テキスト属性)
: Special Properties
insert-buffer
: Commands for Insertion
insert-buffer-substring
: Insertion
insert-char
: Insertion
insert-default-directory
: Reading File Names
insert-directory
: Contents of Directories
insert-directory-program
: Contents of Directories
insert-file-contents
: Reading from Files
insert-file-contents-literally
: Reading from Files
insert-hebrew-diary-entry
: Hebrew/Islamic Entries
insert-in-front-hooks
(オーバレイ属性)
: Overlay Properties
insert-in-front-hooks
(テキスト属性)
: Special Properties
insert-islamic-diary-entry
: Hebrew/Islamic Entries
insert-monthly-hebrew-diary-entry
: Hebrew/Islamic Entries
insert-monthly-islamic-diary-entry
: Hebrew/Islamic Entries
insert-register
: Registers
insert-yearly-hebrew-diary-entry
: Hebrew/Islamic Entries
insert-yearly-islamic-diary-entry
: Hebrew/Islamic Entries
installation-directory
: System Environment
int-to-string
: String Conversion
intangible
(オーバレイ属性)
: Overlay Properties
intangible
(テキスト属性)
: Special Properties
integer-or-marker-p
: Predicates on Markers
integerp
: Predicates on Numbers
interactive
: Using Interactive
interactive-p
: Interactive Call
interactive
の使用例: Interactive Examples
intern
: Creating Symbols
intern-soft
: Creating Symbols
interpreter-mode-alist
: Auto Major Mode
interprogram-cut-function
: Low-Level Kill Ring
interprogram-paste-function
: Low-Level Kill Ring
interrupt-process
: Signals to Processes
intervals-consed
: Memory Usage
invalid-function
: Function Indirection
invalid-read-syntax
: Printed Representation
invalid-regexp
: Syntax of Regexps
inverse-video
: Inverse Video
invert-face
: Face Functions
invisible
(オーバレイ属性)
: Overlay Properties
invisible
(テキスト属性)
: Special Properties
invocation-directory
: System Environment
invocation-name
: System Environment
isearch-mode-map
: Standard Keymaps
islamic-holidays
: Holiday Customizing
italic
(フェイス名)
: Standard Faces
just-one-space
: User-Level Deletion
justify-current-line
: Filling
kept-new-versions
: Numbered Backups
kept-old-versions
: Numbered Backups
key-binding
: Functions for Key Lookup
key-description
: Describing Characters
key-translation-map
: Translating Input
keyboard-coding-system
: Terminal I/O Encoding
keyboard-quit
: Quitting
keyboard-translate
: Translating Input
keyboard-translate-table
: Translating Input
keymap-parent
: Inheritance and Keymaps
keymapp
: Format of Keymaps
keyword-symbols-constant-flag
: Constant Variables
kill-all-local-variables
: Creating Buffer-Local
kill-append
: Low-Level Kill Ring
kill-buffer
: Killing Buffers
kill-buffer-hook
: Killing Buffers
kill-buffer-query-functions
: Killing Buffers
kill-emacs
: Killing Emacs
kill-emacs-hook
: Killing Emacs
kill-emacs-query-functions
: Killing Emacs
kill-local-variable
: Creating Buffer-Local
kill-new
: Low-Level Kill Ring
kill-process
: Signals to Processes
kill-read-only-ok
: Kill Functions
kill-region
: Kill Functions
kill-ring
: Internals of Kill Ring
kill-ring-max
: Internals of Kill Ring
kill-ring-yank-pointer
: Internals of Kill Ring
lambda
、キーマップ: Key Lookup
lambda
、デバッグ: Invoking the Debugger
last-abbrev
: Abbrev Expansion
last-abbrev-location
: Abbrev Expansion
last-abbrev-text
: Abbrev Expansion
last-coding-system-used
: Encoding and I/O
last-command
: Command Loop Info
last-command-char
: Command Loop Info
last-command-event
: Command Loop Info
last-event-frame
: Command Loop Info
last-input-char
: Event Input Misc
last-input-event
: Event Input Misc
last-kbd-macro
: Keyboard Macros
last-nonmenu-event
: Command Loop Info
last-prefix-arg
: Prefix Command Arguments
left-margin
: Margins
length
: Sequence Functions
let
: Local Variables
let*
: Local Variables
line-move-ignore-invisible
: Invisible Text
lisp-interaction-mode-map
: Standard Keymaps
lisp-mode-abbrev-table
: Standard Abbrev Tables
lisp-mode-map
: Standard Keymaps
lisp-mode.el
: Example Major Modes
list
: Building Lists
list-buffers-directory
: Buffer File Name
list-diary-entries-hook
: Fancy Diary Display
list-hebrew-diary-entries
: Hebrew/Islamic Entries
list-islamic-diary-entries
: Hebrew/Islamic Entries
list-processes
: Process Information
listify-key-sequence
: Event Input Misc
listp
: List-related Predicates
ln
: Changing Files
load
: How Programs Do Loading
load-average
: System Environment
load-file
: How Programs Do Loading
load-history
: Unloading
load-in-progress
: How Programs Do Loading
load-library
: How Programs Do Loading
load-path
: Library Search
load-read-function
: How Programs Do Loading
loadhist-special-hooks
: Unloading
loadup.el
: Building Emacs
local-abbrev-table
: Standard Abbrev Tables
local-holidays
: Holiday Customizing
local-key-binding
: Functions for Key Lookup
local-map
(オーバレイ属性)
: Overlay Properties
local-map
(テキスト属性)
: Special Properties
local-set-key
: Key Binding Commands
local-unset-key
: Key Binding Commands
local-variable-p
: Creating Buffer-Local
local-write-file-hooks
: Saving Buffers
locate-library
: Library Search
lock-buffer
: File Locks
log
: Math Functions
log10
: Math Functions
logand
: Bitwise Operations
logb
: Float Basics
logior
: Bitwise Operations
lognot
: Bitwise Operations
logxor
: Bitwise Operations
looking-at
: Regexp Search
lookup-key
: Functions for Key Lookup
lookup-key
における小文字への変換: Key Sequence Input
lower-frame
: Raising and Lowering
lsh
: Bitwise Operations
macroexpand
: Expansion
mail-host-address
: System Environment
major-mode
: Mode Help
make-abbrev-table
: Abbrev Tables
make-auto-save-file-name
: Auto-Saving
make-backup-file-name
: Backup Names
make-backup-files
: Making Backups
make-bool-vector
: Bool-Vectors
make-byte-code
: Byte-Code Objects
make-category-set
: Categories
make-char
: Splitting Characters
make-char-table
: Char-Tables
make-directory
: Create/Delete Dirs
make-display-table
: Display Table Format
make-face
: Face Functions
make-frame
: Creating Frames
make-frame-invisible
: Visibility of Frames
make-frame-on-display
: Multiple Displays
make-frame-visible
: Visibility of Frames
make-frame-visible
イベント: Misc Events
make-help-screen
: Help Functions
make-indirect-buffer
: Indirect Buffers
make-keymap
: Creating Keymaps
make-list
: Building Lists
make-local-hook
: Hooks
make-local-variable
: Creating Buffer-Local
make-marker
: Creating Markers
make-overlay
: Managing Overlays
make-sparse-keymap
: Creating Keymaps
make-string
: Creating Strings
make-symbol
: Creating Symbols
make-symbolic-link
: Changing Files
make-syntax-table
: Syntax Table Functions
make-temp-name
: Unique File Names
make-translation-table
: Translation of Characters
make-variable-buffer-local
: Creating Buffer-Local
make-variable-frame-local
: Frame-Local Variables
make-vector
: Vector Functions
makunbound
: Void Variables
map-char-table
: Char-Tables
map-y-or-n-p
: Multiple Queries
mapatoms
: Creating Symbols
mapcar
: Mapping Functions
mapconcat
: Mapping Functions
mark
: The Mark
mark-active
: The Mark
mark-diary-entries-hook
: Fancy Diary Display
mark-diary-entries-in-calendar
: Calendar Customizing
mark-even-if-inactive
: The Mark
mark-hebrew-diary-entries
: Hebrew/Islamic Entries
mark-holidays-in-calendar
: Calendar Customizing
mark-included-diary-files
: Fancy Diary Display
mark-islamic-diary-entries
: Hebrew/Islamic Entries
mark-marker
: The Mark
mark-ring
: The Mark
mark-ring-max
: The Mark
marker-buffer
: Information from Markers
marker-insertion-type
: Marker Insertion Types
marker-position
: Information from Markers
markerp
: Predicates on Markers
match-beginning
: Simple Match Data
match-data
: Entire Match Data
match-end
: Simple Match Data
match-string
: Simple Match Data
match-string-no-properties
: Simple Match Data
max
: Comparison of Numbers
max-lisp-eval-depth
: Eval
max-specpdl-size
: Local Variables
member
: Sets And Lists
memory-limit
: Garbage Collection
memq
: Sets And Lists
menu-bar-edit-menu
: Standard Keymaps
menu-bar-files-menu
: Standard Keymaps
menu-bar-final-items
: Menu Bar
menu-bar-help-menu
: Standard Keymaps
menu-bar-mule-menu
: Standard Keymaps
menu-bar-search-menu
: Standard Keymaps
menu-bar-tools-menu
: Standard Keymaps
menu-bar-update-hook
: Menu Bar
menu-item
: Extended Menu Items
menu-prompt-more-char
: Keyboard Menus
message
: The Echo Area
message-box
: The Echo Area
message-log-max
: The Echo Area
message-or-box
: The Echo Area
meta-prefix-char
: Functions for Key Lookup
min
: Comparison of Numbers
minibuffer-allow-text-properties
: Text from Minibuffer
minibuffer-auto-raise
: Raising and Lowering
minibuffer-complete
: Completion Commands
minibuffer-complete-and-exit
: Completion Commands
minibuffer-complete-word
: Completion Commands
minibuffer-completion-confirm
: Completion Commands
minibuffer-completion-help
: Completion Commands
minibuffer-completion-predicate
: Completion Commands
minibuffer-completion-table
: Completion Commands
minibuffer-depth
: Minibuffer Misc
minibuffer-exit-hook
: Minibuffer Misc
minibuffer-frame-alist
: Initial Parameters
minibuffer-help-form
: Minibuffer Misc
minibuffer-history
: Minibuffer History
minibuffer-local-completion-map
: Completion Commands
minibuffer-local-map
: Text from Minibuffer
minibuffer-local-must-match-map
: Completion Commands
minibuffer-local-ns-map
: Text from Minibuffer
minibuffer-prompt
: Minibuffer Misc
minibuffer-prompt-width
: Minibuffer Misc
minibuffer-scroll-window
: Minibuffer Misc
minibuffer-setup-hook
: Minibuffer Misc
minibuffer-window
: Minibuffer Misc
minibuffer-window-active-p
: Minibuffer Misc
minor-mode-alist
: Mode Line Variables
minor-mode-key-binding
: Functions for Key Lookup
minor-mode-map-alist
: Active Keymaps
minor-mode-overriding-map-alist
: Active Keymaps
misc-objects-consed
: Memory Usage
mod
: Arithmetic Operations
mode-class
属性: Major Mode Conventions
mode-line-buffer-identification
: Mode Line Variables
mode-line-format
: Mode Line Data
mode-line-format
、シェルモード: Mode Line Data
mode-line-frame-identification
: Mode Line Variables
mode-line-inverse-video
: Inverse Video
mode-line-modified
: Mode Line Variables
mode-line-mule-info
: Mode Line Variables
mode-line-process
: Mode Line Variables
mode-name
: Mode Line Variables
mode-specific-map
: Prefix Keys
modeline
(フェイス名)
: Standard Faces
modification-hooks
(オーバレイ属性)
: Overlay Properties
modification-hooks
(テキスト属性)
: Special Properties
modify-category-entry
: Categories
modify-frame-parameters
: Parameter Access
modify-syntax-entry
: Syntax Table Functions
momentary-string-display
: Temporary Displays
mouse-face
(オーバレイ属性)
: Overlay Properties
mouse-face
(テキスト属性)
: Special Properties
mouse-movement-p
: Classifying Events
mouse-pixel-position
: Mouse Position
mouse-position
: Mouse Position
mouse-wheel
イベント: Misc Events
move-marker
: Moving Markers
move-overlay
: Managing Overlays
move-to-column
: Columns
move-to-left-margin
: Margins
move-to-window-line
: Screen Lines
movemail
: Subprocess Creation
mule-keymap
: Prefix Keys
multibyte-string-p
: Text Representations
multiple-frames
: Frame Titles
narrow-to-page
: Narrowing
narrow-to-region
: Narrowing
natnump
: Predicates on Numbers
nconc
: Rearrangement
negative-argument
: Prefix Command Arguments
network-coding-system-alist
: Default Coding Systems
newline
: Commands for Insertion
newline-and-indent
: Mode-Specific Indent
next-char-property-change
: Property Search
next-frame
: Finding All Frames
next-history-element
: Minibuffer Misc
next-matching-history-element
: Minibuffer Misc
next-overlay-change
: Managing Overlays
next-property-change
: Property Search
next-screen-context-lines
: Vertical Scrolling
next-single-property-change
: Property Search
next-window
: Cyclic Window Ordering
nil
: Constant Variables
nil
、キーマップ: Key Lookup
nil
、リスト: Cons Cell Type
nil
とリスト: Cons Cells
nil
の使い方: nil and t
nil
出力ストリーム: Output Streams
nil
入力ストリーム: Input Streams
nlistp
: List-related Predicates
no-catch
: Catch and Throw
no-redraw-on-reenter
: Refresh Screen
nonascii-insert-offset
: Converting Representations
nonascii-translation-table
: Converting Representations
nongregorian-diary-listing-hook
: Hebrew/Islamic Entries
nongregorian-diary-marking-hook
: Hebrew/Islamic Entries
noninteractive
: Batch Mode
normal-auto-fill-function
: Auto Filling
normal-mode
: Auto Major Mode
not
: Combining Conditions
not-modified
: Buffer Modification
nreverse
: Rearrangement
nth
: List Elements
nthcdr
: List Elements
null
: List-related Predicates
num-input-keys
: Key Sequence Input
num-nonmacro-input-events
: Key Sequence Input
number-of-diary-entries
: Diary Customizing
number-or-marker-p
: Predicates on Markers
number-to-string
: String Conversion
numberp
: Predicates on Numbers
obarray
: Creating Symbols
occur-mode-map
: Standard Keymaps
one-window-p
: Splitting Windows
only-global-abbrevs
: Defining Abbrevs
open-dribble-file
: Recording Input
open-network-stream
: Network
open-termscript
: Terminal Output
or
: Combining Conditions
other-buffer
: The Buffer List
other-holidays
: Holiday Customizing
other-window
: Cyclic Window Ordering
other-window-scroll-buffer
: Vertical Scrolling
overlay-arrow-position
: Overlay Arrow
overlay-arrow-string
: Overlay Arrow
overlay-buffer
: Managing Overlays
overlay-end
: Managing Overlays
overlay-get
: Overlay Properties
overlay-put
: Overlay Properties
overlay-start
: Managing Overlays
overlays-at
: Managing Overlays
overlays-in
: Managing Overlays
overriding-local-map
: Active Keymaps
overriding-local-map-menu-flag
: Active Keymaps
overriding-terminal-local-map
: Active Keymaps
overwrite-mode
: Commands for Insertion
page-delimiter
: Standard Regexps
paragraph-separate
: Standard Regexps
paragraph-start
: Standard Regexps
parse-partial-sexp
: Parsing Expressions
parse-sexp-ignore-comments
: Parsing Expressions
parse-sexp-lookup-properties
: Syntax Properties
path-separator
: System Environment
PATH
、環境変数: Subprocess Creation
perform-replace
: Search and Replace
plist-get
: Other Plists
plist-put
: Other Plists
point
: Point
point-entered
(テキスト属性)
: Special Properties
point-left
(テキスト属性)
: Special Properties
point-marker
: Creating Markers
point-max
: Point
point-max-marker
: Creating Markers
point-min
: Point
point-min-marker
: Creating Markers
pop-mark
: The Mark
pop-to-buffer
: Displaying Buffers
pop-up-frame-alist
: Choosing Window
pop-up-frame-function
: Choosing Window
pop-up-frames
: Choosing Window
pop-up-windows
: Choosing Window
pos-visible-in-window-p
: Window Start
posix-looking-at
: POSIX Regexps
posix-search-backward
: POSIX Regexps
posix-search-forward
: POSIX Regexps
posix-string-match
: POSIX Regexps
posn-col-row
: Accessing Events
posn-point
: Accessing Events
posn-timestamp
: Accessing Events
posn-window
: Accessing Events
posn-x-y
: Accessing Events
post-command-hook
: Command Overview
pre-abbrev-expand-hook
: Abbrev Expansion
pre-command-hook
: Command Overview
preceding-char
: Near Point
prefix-arg
: Prefix Command Arguments
prefix-help-command
: Help Functions
prefix-numeric-value
: Prefix Command Arguments
previous-char-property-change
: Property Search
previous-frame
: Finding All Frames
previous-history-element
: Minibuffer Misc
previous-matching-history-element
: Minibuffer Misc
previous-overlay-change
: Managing Overlays
previous-property-change
: Property Search
previous-single-property-change
: Property Search
previous-window
: Cyclic Window Ordering
primitive-undo
: Undo
prin1
: Output Functions
prin1-to-string
: Output Functions
princ
: Output Functions
print
: Output Functions
print-diary-entries
: Diary Customizing
print-diary-entries-hook
: Diary Customizing
print-escape-multibyte
: Output Variables
print-escape-newlines
: Output Variables
print-escape-nonascii
: Output Variables
print-help-return-message
: Help Functions
print-length
: Output Variables
print-level
: Output Variables
priority
(オーバレイ属性)
: Overlay Properties
process-buffer
: Process Buffers
process-coding-system
: Process Information
process-coding-system-alist
: Default Coding Systems
process-command
: Process Information
process-connection-type
: Asynchronous Processes
process-contact
: Process Information
process-environment
: System Environment
process-exit-status
: Process Information
process-filter
: Filter Functions
process-id
: Process Information
process-kill-without-query
: Deleting Processes
process-list
: Process Information
process-mark
: Process Buffers
process-name
: Process Information
process-send-eof
: Input to Processes
process-send-region
: Input to Processes
process-send-string
: Input to Processes
process-sentinel
: Sentinels
process-status
: Process Information
process-tty-name
: Process Information
processp
: Processes
profile.el
: Compilation Tips
prog1
: Sequencing
prog2
: Sequencing
progn
: Sequencing
provide
: Named Features
pure-bytes-used
: Pure Storage
purecopy
: Pure Storage
purify-flag
: Pure Storage
push-mark
: The Mark
put
: Symbol Plists
put-text-property
: Changing Properties
query-replace-history
: Minibuffer History
query-replace-map
: Search and Replace
quietly-read-abbrev-file
: Abbrev Files
quit-flag
: Quitting
quit-process
: Signals to Processes
quote
: Quoting
quoted-insert
の抑制: Changing Key Bindings
raise-frame
: Raising and Lowering
random
: Random Numbers
rassoc
: Association Lists
rassq
: Association Lists
re-search-backward
: Regexp Search
re-search-forward
: Regexp Search
read
: Input Functions
read-buffer
: High-Level Completion
read-buffer-function
: High-Level Completion
read-char
: Reading One Event
read-coding-system
: User-Chosen Coding Systems
read-command
: High-Level Completion
read-event
: Reading One Event
read-expression-history
: Minibuffer History
read-file-name
: Reading File Names
read-from-minibuffer
: Text from Minibuffer
read-from-string
: Input Functions
read-input-method-name
: Input Methods
read-kbd-macro
: Describing Characters
read-key-sequence
: Key Sequence Input
read-key-sequence-vector
: Key Sequence Input
read-minibuffer
: Object from Minibuffer
read-no-blanks-input
: Text from Minibuffer
read-non-nil-coding-system
: User-Chosen Coding Systems
read-only
(テキスト属性)
: Special Properties
read-passwd
: Reading a Password
read-quoted-char
: Quoted Character Input
read-quoted-char
の中断: Quitting
read-string
: Text from Minibuffer
read-variable
: High-Level Completion
real-last-command
: Command Loop Info
recent-auto-save-p
: Auto-Saving
recent-keys
: Recording Input
recenter
: Vertical Scrolling
recursion-depth
: Recursive Editing
recursive-edit
: Recursive Editing
redirect-frame-focus
: Input Focus
redisplay-end-trigger-functions
: Window Hooks
redraw-display
: Refresh Screen
redraw-frame
: Refresh Screen
regexp-history
: Minibuffer History
regexp-opt
: Syntax of Regexps
regexp-opt-depth
: Syntax of Regexps
regexp-quote
: Syntax of Regexps
region
(フェイス名)
: Standard Faces
region-beginning
: The Region
region-end
: The Region
region-face
: Face Functions
register-alist
: Registers
reindent-then-newline-and-indent
: Mode-Specific Indent
remove-from-invisibility-spec
: Invisible Text
remove-hook
: Hooks
remove-text-properties
: Changing Properties
rename-auto-save-file
: Auto-Saving
rename-buffer
: Buffer Names
rename-file
: Changing Files
replace-buffer-in-windows
: Displaying Buffers
replace-match
: Replacing Match
require
: Named Features
require-final-newline
: Saving Buffers
require
によるロードエラー: Named Features
reverse
: Building Lists
revert-buffer
: Reverting
revert-buffer-function
: Reverting
revert-buffer-insert-file-contents-function
: Reverting
revert-without-query
: Reverting
ring-bell-function
: Beeping
rm
: Changing Files
round
: Numeric Conversions
rplaca
: Modifying Lists
rplacd
: Modifying Lists
run-at-time
: Timers
run-hook-with-args
: Hooks
run-hook-with-args-until-failure
: Hooks
run-hook-with-args-until-success
: Hooks
run-hooks
: Hooks
run-with-idle-timer
: Timers
safe-length
: List Elements
same-window-buffer-names
: Choosing Window
same-window-regexps
: Choosing Window
save-abbrevs
: Abbrev Files
save-buffer
: Saving Buffers
save-buffer-coding-system
: Encoding and I/O
save-current-buffer
: Current Buffer
save-excursion
: Excursions
save-match-data
: Saving Match Data
save-restriction
: Narrowing
save-selected-window
: Selecting Windows
save-some-buffers
: Saving Buffers
save-window-excursion
: Window Configurations
scan-lists
: Parsing Expressions
scan-sexps
: Parsing Expressions
screen-height
: Size and Position
screen-width
: Size and Position
scroll-bar-event-ratio
: Accessing Events
scroll-bar-scale
: Accessing Events
scroll-conservatively
: Vertical Scrolling
scroll-down
: Vertical Scrolling
scroll-left
: Horizontal Scrolling
scroll-margin
: Vertical Scrolling
scroll-other-window
: Vertical Scrolling
scroll-preserve-screen-position
: Vertical Scrolling
scroll-right
: Horizontal Scrolling
scroll-step
: Vertical Scrolling
scroll-up
: Vertical Scrolling
search-backward
: String Search
search-failed
: String Search
search-forward
: String Search
secondary-selection
(フェイス名)
: Standard Faces
select-frame
: Input Focus
select-safe-coding-system
: User-Chosen Coding Systems
select-window
: Selecting Windows
selected-frame
: Input Focus
selected-window
: Selecting Windows
selection-coding-system
: Window System Selections
selective-display
: Selective Display
selective-display-ellipses
: Selective Display
self-insert-and-exit
: Minibuffer Misc
self-insert-command
: Commands for Insertion
self-insert-command
、マイナモード: Keymaps and Minor Modes
self-insert-command
の無効化: Changing Key Bindings
send-string-to-terminal
: Terminal Output
sentence-end
: Standard Regexps
sentence-end-double-space
: Filling
sequencep
: Sequence Functions
set
: Setting Variables
set-auto-mode
: Auto Major Mode
set-buffer
: Current Buffer
set-buffer-auto-saved
: Auto-Saving
set-buffer-major-mode
: Auto Major Mode
set-buffer-modified-p
: Buffer Modification
set-buffer-multibyte
: Selecting a Representation
set-case-syntax
: Case Tables
set-case-syntax-delims
: Case Tables
set-case-syntax-pair
: Case Tables
set-case-table
: Case Tables
set-category-table
: Categories
set-char-table-default
: Char-Tables
set-char-table-extra-slot
: Char-Tables
set-char-table-parent
: Char-Tables
set-char-table-range
: Char-Tables
set-default
: Default Value
set-default-file-modes
: Changing Files
set-display-table-slot
: Display Table Format
set-face-background
: Face Functions
set-face-bold-p
: Face Functions
set-face-font
: Face Functions
set-face-foreground
: Face Functions
set-face-italic-p
: Face Functions
set-face-stipple
: Face Functions
set-face-underline-p
: Face Functions
set-file-modes
: Changing Files
set-frame-configuration
: Frame Configurations
set-frame-height
: Size and Position
set-frame-position
: Size and Position
set-frame-size
: Size and Position
set-frame-width
: Size and Position
set-input-method
: Input Methods
set-input-mode
: Input Modes
set-keyboard-coding-system
: Terminal I/O Encoding
set-keymap-parent
: Inheritance and Keymaps
set-left-margin
: Margins
set-mark
: The Mark
set-marker
: Moving Markers
set-marker-insertion-type
: Marker Insertion Types
set-match-data
: Entire Match Data
set-mouse-pixel-position
: Mouse Position
set-mouse-position
: Mouse Position
set-process-buffer
: Process Buffers
set-process-coding-system
: Process Information
set-process-filter
: Filter Functions
set-process-sentinel
: Sentinels
set-register
: Registers
set-right-margin
: Margins
set-screen-height
: Size and Position
set-screen-width
: Size and Position
set-standard-case-table
: Case Tables
set-syntax-table
: Syntax Table Functions
set-terminal-coding-system
: Terminal I/O Encoding
set-text-properties
: Changing Properties
set-visited-file-modtime
: Modification Time
set-visited-file-name
: Buffer File Name
set-window-buffer
: Buffers and Windows
set-window-configuration
: Window Configurations
set-window-dedicated-p
: Choosing Window
set-window-display-table
: Active Display Table
set-window-hscroll
: Horizontal Scrolling
set-window-point
: Window Point
set-window-redisplay-end-trigger
: Window Hooks
set-window-start
: Window Start
setcar
: Setcar
setcdr
: Setcdr
setenv
: System Environment
setplist
: Symbol Plists
setprv
: System Environment
setq
: Setting Variables
setq-default
: Default Value
setting-constant
: Constant Variables
shell-command-history
: Minibuffer History
shell-command-to-string
: Synchronous Processes
shell-quote-argument
: Shell Arguments
shrink-window
: Resizing Windows
shrink-window-horizontally
: Resizing Windows
shrink-window-if-larger-than-buffer
: Resizing Windows
signal
: Signaling Errors
signal-process
: Signals to Processes
simple-diary-display
: Fancy Diary Display
sin
: Math Functions
single-key-description
: Describing Characters
sit-for
: Waiting
site-init.el
: Building Emacs
site-load.el
: Building Emacs
site-run-file
: Init File
site-start.el
: Start-up Summary
skip-chars-backward
: Skipping Characters
skip-chars-forward
: Skipping Characters
skip-syntax-backward
: Motion and Syntax
skip-syntax-forward
: Motion and Syntax
sleep-for
: Waiting
Snarf-documentation
: Accessing Documentation
sort
: Rearrangement
sort-columns
: Sorting
sort-diary-entries
: Fancy Diary Display
sort-fields
: Sorting
sort-fold-case
: Sorting
sort-lines
: Sorting
sort-numeric-fields
: Sorting
sort-pages
: Sorting
sort-paragraphs
: Sorting
sort-regexp-fields
: Sorting
sort-subr
: Sorting
special
: Major Mode Conventions
special-display-buffer-names
: Choosing Window
special-display-frame-alist
: Choosing Window
special-display-function
: Choosing Window
special-display-popup-frame
: Choosing Window
special-display-regexps
: Choosing Window
special-event-map
: Active Keymaps
split-char
: Splitting Characters
split-height-threshold
: Choosing Window
split-line
: Commands for Insertion
split-string
: Creating Strings
split-window
: Splitting Windows
split-window-horizontally
: Splitting Windows
split-window-vertically
: Splitting Windows
sqrt
: Math Functions
standard-case-table
: Case Tables
standard-category-table
: Categories
standard-character-translation-table-for-decode
: Translation of Characters
standard-character-translation-table-for-encode
: Translation of Characters
standard-display-table
: Active Display Table
standard-input
: Input Functions
standard-output
: Output Variables
standard-syntax-table
: Standard Syntax Tables
start-process
: Asynchronous Processes
start-process-shell-command
: Asynchronous Processes
startup.el
: Start-up Summary
stop-process
: Signals to Processes
store-match-data
: Entire Match Data
store-substring
: Modifying Strings
string
: Creating Strings
string-as-multibyte
: Selecting a Representation
string-as-unibyte
: Selecting a Representation
string-chars-consed
: Memory Usage
string-equal
: Text Comparison
string-lessp
: Text Comparison
string-make-multibyte
: Converting Representations
string-make-unibyte
: Converting Representations
string-match
: Regexp Search
string-to-char
: String Conversion
string-to-int
: String Conversion
string-to-number
: String Conversion
string-width
: Width
string<
: Text Comparison
string=
: Text Comparison
stringp
: Predicates for Strings
subrp
: What Is a Function
subst-char-in-region
: Substitution
substitute-command-keys
: Keys in Documentation
substitute-in-file-name
: File Name Expansion
substitute-key-definition
: Changing Key Bindings
substring
: Creating Strings
suppress-keymap
: Changing Key Bindings
suspend-emacs
: Suspending Emacs
suspend-hook
: Suspending Emacs
suspend-resume-hook
: Suspending Emacs
switch-to-buffer
: Displaying Buffers
switch-to-buffer-other-window
: Displaying Buffers
symbol-function
: Function Cells
symbol-name
: Creating Symbols
symbol-plist
: Symbol Plists
symbol-value
: Accessing Variables
symbolp
: Symbols
symbols-consed
: Memory Usage
syntax-table
: Syntax Table Functions
syntax-table
(テキスト属性)
: Syntax Properties
syntax-table-p
: Syntax Basics
system-configuration
: System Environment
system-key-alist
: Special Keysyms
system-name
: System Environment
system-type
: System Environment
t
: Constant Variables
tab-stop-list
: Indent Tabs
tab-to-tab-stop
: Indent Tabs
tab-width
: Usual Display
tan
: Math Functions
temacs
: Building Emacs
temp-buffer-show-function
: Temporary Displays
temp-buffer-show-hook
: Temporary Displays
temporary-file-directory
: Unique File Names
term-file-prefix
: Terminal-Specific
term-setup-hook
: Terminal-Specific
terminal-coding-system
: Terminal I/O Encoding
TERM
、環境変数: Terminal-Specific
terpri
: Output Functions
text-char-description
: Describing Characters
text-mode-abbrev-table
: Standard Abbrev Tables
text-mode-map
: Standard Keymaps
text-mode-syntax-table
: Standard Syntax Tables
text-properties-at
: Examining Properties
text-property-any
: Property Search
text-property-not-all
: Property Search
thing-at-point
: Buffer Contents
this-command
: Command Loop Info
this-command-keys
: Command Loop Info
this-command-keys-vector
: Command Loop Info
three-step-help
: Help Functions
throw
: Catch and Throw
throw
の例: Recursive Editing
TMPDIR
、環境変数: Unique File Names
TMP
、環境変数: Unique File Names
today-invisible-calendar-hook
: Calendar Customizing
today-visible-calendar-hook
: Calendar Customizing
toggle-read-only
: Read Only Buffers
top-level
: Recursive Editing
tq-close
: Transaction Queues
tq-create
: Transaction Queues
tq-enqueue
: Transaction Queues
track-mouse
: Mouse Tracking
transient-mark-mode
: The Mark
translate-region
: Substitution
transpose-regions
: Transposition
truncate
: Numeric Conversions
truncate-lines
: Truncation
truncate-partial-width-windows
: Truncation
truncate-string-to-width
: Width
try-completion
: Basic Completion
tty-erase-char
: System Environment
type-of
: Type Predicates
t
と真: nil and t
t
出力ストリーム: Output Streams
t
入力ストリーム: Input Streams
undefined
: Functions for Key Lookup
undefined
、キーマップ: Key Lookup
underline
(フェイス名)
: Standard Faces
undo-boundary
: Undo
undo-limit
: Maintaining Undo
undo-strong-limit
: Maintaining Undo
unhandled-file-name-directory
: Magic File Names
unintern
: Creating Symbols
universal-argument
: Prefix Command Arguments
unless
: Conditionals
unload-feature
: Unloading
unlock-buffer
: File Locks
unread-command-char
: Event Input Misc
unread-command-events
: Event Input Misc
unwind-protect
: Cleanups
up-list
: List Motion
upcase
: Case Conversion
upcase-initials
: Case Conversion
upcase-region
: Case Changes
upcase-word
: Case Changes
update-directory-autoloads
: Autoload
update-file-autoloads
: Autoload
use-global-map
: Active Keymaps
use-hard-newlines
: Filling
use-local-map
: Active Keymaps
user-full-name
: User Identification
user-login-name
: User Identification
user-mail-address
: User Identification
user-real-login-name
: User Identification
user-real-uid
: User Identification
user-uid
: User Identification
user-variable-p
: Defining Variables
values
: Eval
variable-documentation
: Documentation Basics
variable-interactive
: Defining Variables
vc-mode
: Mode Line Variables
vc-prefix-map
: Prefix Keys
vconcat
: Vector Functions
vector
: Vector Functions
vector-cells-consed
: Memory Usage
vectorp
: Vector Functions
verify-visited-file-modtime
: Modification Time
version-control
: Numbered Backups
vertical-motion
: Screen Lines
view-calendar-holidays-initially
: Calendar Customizing
view-diary-entries-initially
: Calendar Customizing
view-file
: Visiting Functions
view-mode-map
: Standard Keymaps
view-register
: Registers
visible-bell
: Beeping
visible-frame-list
: Finding All Frames
visited-file-modtime
: Modification Time
void-function
: Function Cells
void-variable
: Void Variables
waiting-for-user-input-p
: Sentinels
walk-windows
: Cyclic Window Ordering
when
: Conditionals
where-is-internal
: Scanning Keymaps
while
: Iteration
wholenump
: Predicates on Numbers
widen
: Narrowing
window
(オーバレイ属性)
: Overlay Properties
window-at
: Coordinates and Windows
window-buffer
: Buffers and Windows
window-configuration-change-hook
: Window Hooks
window-configuration-p
: Window Configurations
window-dedicated-p
: Choosing Window
window-display-table
: Active Display Table
window-edges
: Size of Window
window-end
: Window Start
window-frame
: Frames and Windows
window-height
: Size of Window
window-hscroll
: Horizontal Scrolling
window-live-p
: Deleting Windows
window-min-height
: Resizing Windows
window-min-width
: Resizing Windows
window-minibuffer-p
: Minibuffer Misc
window-point
: Window Point
window-redisplay-end-trigger
: Window Hooks
window-scroll-functions
: Window Hooks
window-setup-hook
: Window Systems
window-size-change-functions
: Window Hooks
window-start
: Window Start
window-system
: Window Systems
window-width
: Size of Window
windowp
: Basic Windows
with-current-buffer
: Current Buffer
with-output-to-string
: Output Functions
with-output-to-temp-buffer
: Temporary Displays
with-temp-buffer
: Current Buffer
with-temp-file
: Writing to Files
with-timeout
: Timers
word-search-backward
: String Search
word-search-forward
: String Search
words-include-escapes
: Word Motion
write-abbrev-file
: Abbrev Files
write-char
: Output Functions
write-contents-hooks
: Saving Buffers
write-file
: Saving Buffers
write-file-hooks
: Saving Buffers
write-region
: Writing to Files
write-region-annotate-functions
: Saving Properties
wrong-number-of-arguments
: Argument List
wrong-type-argument
: Type Predicates
x-close-connection
: Multiple Displays
x-color-defined-p
: Color Names
x-color-values
: Color Names
x-display-backing-store
: Server Data
x-display-color-cells
: Server Data
x-display-color-p
: Server Data
x-display-grayscale-p
: Server Data
x-display-list
: Multiple Displays
x-display-mm-height
: Server Data
x-display-mm-width
: Server Data
x-display-pixel-height
: Server Data
x-display-pixel-width
: Server Data
x-display-planes
: Server Data
x-display-save-under
: Server Data
x-display-screens
: Server Data
x-display-visual-class
: Server Data
x-get-cut-buffer
: Window System Selections
x-get-resource
: Resources
x-get-selection
: Window System Selections
x-list-font
: Font Names
x-open-connection
: Multiple Displays
x-parse-geometry
: Size and Position
x-pointer-shape
: Pointer Shapes
x-popup-dialog
: Dialog Boxes
x-popup-menu
: Pop-Up Menus
x-resource-class
: Resources
x-sensitive-text-pointer-shape
: Pointer Shapes
x-server-vendor
: Server Data
x-server-version
: Server Data
x-set-cut-buffer
: Window System Selections
x-set-selection
: Window System Selections
y-or-n-p
: Yes-or-No Queries
y-or-n-p-with-timeout
: Yes-or-No Queries
yank
: Yank Commands
yank-pop
: Yank Commands
yes-or-no-p
: Yes-or-No Queries
zerop
: Predicates on Numbers
|
、正規表現: Syntax of Regexps
delete-frame
: Misc Events
drag-n-drop
: Misc Events
iconify-frame
: Misc Events
make-frame-visible
: Misc Events
mouse-wheel
: Misc Events
エスケープ(escape)
: Syntax Class Table
.emacs
: Major Mode Conventions
lambda
: Key Lookup
nil
: Key Lookup
undefined
: Key Lookup
'
: Quoting
コメント開始(comment starter)
: Syntax Class Table
コメント終了(comment ender)
: Syntax Class Table
mode-line-format
: Mode Line Data
シンボル構成文字(symbol constituent)
: Syntax Class Table
error
: Invoking the Debugger
lambda
: Invoking the Debugger
require
: Named Features
(...)
: Cons Cell Type
.
: Dotted Pair Notation
nil
: Cons Cell Type
progn
: Sequencing
$
: Truncation
\
: Truncation
開き括弧文字(open parenthesis character)
: Syntax Class Table
EMACSLOADPATH
: Library Search
HOME
: Subprocess Creation
PATH
: Subprocess Creation
TERM
: Terminal-Specific
TMP
: Unique File Names
TMPDIR
: Unique File Names
句読点文字(punctuation character)
: Syntax Class Table
継承(inherit)
: Syntax Class Table
no-redraw-on-reenter
を参照 ): Refresh Screen
式前置子(expression prefix)
: Syntax Class Table
arith-error
: Arithmetic Operations
$
: Syntax of Regexps
(
: Syntax of Regexps
)
: Syntax of Regexps
*
: Syntax of Regexps
+
: Syntax of Regexps
.
: Syntax of Regexps
?
: Syntax of Regexps
[
: Syntax of Regexps
\
: Syntax of Regexps
\'
: Syntax of Regexps
\<
: Syntax of Regexps
\=
: Syntax of Regexps
\>
: Syntax of Regexps
\`
: Syntax of Regexps
\B
: Syntax of Regexps
\b
: Syntax of Regexps
\S
: Syntax of Regexps
\s
: Syntax of Regexps
\W
: Syntax of Regexps
\w
: Syntax of Regexps
]
: Syntax of Regexps
^
: Syntax of Regexps
|
: Syntax of Regexps
mode-class
: Major Mode Conventions
対になった区切り(paired delimiter)
: Syntax Class Table
単語構成文字(word constituent)
: Syntax Class Table
&
: Replacing Match
\
: Replacing Match
\n
: Replacing Match
no-redraw-on-reenter
を参照 ): Refresh Screen
白文字(whitespace character)
: Syntax Class Table
汎用コメント区切り(generic comment delimiter)
: Syntax Class Table
汎用文字列区切り(generic string delimiter)
: Syntax Class Table
文字クォート(character quote)
: Syntax Class Table
?
: Character Type
\
: Character Type
"
: Syntax for Strings
\
: Syntax for Strings
文字列クォート(string quote)
: Syntax Class Table
閉じ括弧文字(close parenthesis character)
: Syntax Class Table
commandp
: High-Level Completion
interactive
: Interactive Examples
throw
: Recursive Editing
user-variable-p
: High-Level Completion
access-file
: Testing Accessibility
add-to-invisibility-spec
: Invisible Text
after-make-frame-hook
: Creating Frames
assoc-default
: Association Lists
assoc-ignore-case
: Text Comparison
assoc-ignore-representation
: Text Comparison
backward-delete-char-untabify-method
: Deletion
before-make-frame-hook
: Creating Frames
bool-vector-p
: Bool-Vectors
buffer-display-time
: Buffers and Windows
buffer-file-coding-system
: Encoding and I/O
buffer-name-history
: Minibuffer History
caar
: List Elements
cadr
: List Elements
cdar
: List Elements
cddr
: List Elements
char-bytes
: Splitting Characters
char-charset
: Character Sets
char-table-extra-slot
: Char-Tables
char-table-p
: Char-Tables
char-table-parent
: Char-Tables
char-table-range
: Char-Tables
char-table-subtype
: Char-Tables
char-width
: Width
charset-dimension
: Chars and Bytes
charset-list
: Character Sets
charsetp
: Character Sets
check-coding-system
: Lisp and Coding Systems
checkdoc-minor-mode
: Documentation Tips
coding-system-change-eol-conversion
: Lisp and Coding Systems
coding-system-change-text-conversion
: Lisp and Coding Systems
coding-system-for-read
: Specifying Coding Systems
coding-system-for-write
: Specifying Coding Systems
coding-system-get
: Coding System Basics
coding-system-list
: Lisp and Coding Systems
coding-system-p
: Lisp and Coding Systems
combine-after-change-calls
: Change Hooks
compare-strings
: Text Comparison
condition
: Conditionals
current-input-method
: Input Methods
current-message
: The Echo Area
decode-coding-region
: Explicit Encoding
decode-coding-string
: Explicit Encoding
default-enable-multibyte-characters
: Text Representations
default-input-method
: Input Methods
default-process-coding-system
: Default Coding Systems
defcustom
: Variable Definitions
defface
: Defining Faces
defgroup
: Group Definitions
delete-old-versions
: Numbered Backups
detect-coding-region
: Lisp and Coding Systems
detect-coding-string
: Lisp and Coding Systems
display-table-slot
: Display Table Format
easy-mmode-define-minor-mode
: Easy-Mmode
echo-area-clear-hook
: The Echo Area
enable-multibyte-characters
: Text Representations
encode-coding-region
: Explicit Encoding
encode-coding-string
: Explicit Encoding
face-bold-p
: Face Functions
face-documentation
: Face Functions
face-italic-p
: Face Functions
file-coding-system-alist
: Default Coding Systems
fill-nobreak-predicate
: Margins
find-charset-region
: Scanning Charsets
find-charset-string
: Scanning Charsets
find-coding-systems-for-charsets
: Lisp and Coding Systems
find-coding-systems-region
: Lisp and Coding Systems
find-coding-systems-string
: Lisp and Coding Systems
find-operation-coding-system
: Default Coding Systems
focus-follows-mouse
: Input Focus
frame-background-mode
: Defining Faces
frame-update-face-colors
: Face Functions
functionp
: What Is a Function
help-event-list
: Help Functions
inhibit-eol-conversion
: Specifying Coding Systems
input-method-alist
: Input Methods
insert-file-contents-literally
: Reading from Files
keyboard-coding-system
: Terminal I/O Encoding
keyword-symbols-constant-flag
: Constant Variables
last-coding-system-used
: Encoding and I/O
last-prefix-arg
: Prefix Command Arguments
loadhist-special-hooks
: Unloading
make-bool-vector
: Bool-Vectors
make-char
: Splitting Characters
make-char-table
: Char-Tables
map-char-table
: Char-Tables
marker-insertion-type
: Marker Insertion Types
menu-bar-mule-menu
: Standard Keymaps
minor-mode-overriding-map-alist
: Active Keymaps
mode-line-frame-identification
: Mode Line Variables
mode-line-mule-info
: Mode Line Variables
multibyte-string-p
: Text Representations
network-coding-system-alist
: Default Coding Systems
next-char-property-change
: Property Search
nonascii-insert-offset
: Converting Representations
nonascii-translation-table
: Converting Representations
num-nonmacro-input-events
: Key Sequence Input
overlays-in
: Managing Overlays
parse-sexp-lookup-properties
: Syntax Properties
previous-char-property-change
: Property Search
print-escape-multibyte
: Output Variables
print-escape-nonascii
: Output Variables
process-coding-system
: Process Information
process-coding-system-alist
: Default Coding Systems
process-contact
: Process Information
read-coding-system
: User-Chosen Coding Systems
read-input-method-name
: Input Methods
read-non-nil-coding-system
: User-Chosen Coding Systems
read-passwd
: Reading a Password
real-last-command
: Command Loop Info
redisplay-end-trigger-functions
: Window Hooks
regexp-opt
: Syntax of Regexps
regexp-opt-depth
: Syntax of Regexps
remove-from-invisibility-spec
: Invisible Text
ring-bell-function
: Beeping
safe-length
: List Elements
save-buffer-coding-system
: Encoding and I/O
save-current-buffer
: Current Buffer
scroll-conservatively
: Vertical Scrolling
scroll-margin
: Vertical Scrolling
scroll-preserve-screen-position
: Vertical Scrolling
select-safe-coding-system
: User-Chosen Coding Systems
selection-coding-system
: Window System Selections
set-buffer-multibyte
: Selecting a Representation
set-char-table-default
: Char-Tables
set-char-table-extra-slot
: Char-Tables
set-char-table-parent
: Char-Tables
set-char-table-range
: Char-Tables
set-display-table-slot
: Display Table Format
set-face-bold-p
: Face Functions
set-face-italic-p
: Face Functions
set-input-method
: Input Methods
set-keyboard-coding-system
: Terminal I/O Encoding
set-marker-insertion-type
: Marker Insertion Types
set-process-coding-system
: Process Information
set-terminal-coding-system
: Terminal I/O Encoding
set-window-redisplay-end-trigger
: Window Hooks
shell-command-to-string
: Synchronous Processes
split-char
: Splitting Characters
split-string
: Creating Strings
store-substring
: Modifying Strings
string
: Creating Strings
string-as-multibyte
: Selecting a Representation
string-as-unibyte
: Selecting a Representation
string-make-multibyte
: Converting Representations
string-make-unibyte
: Converting Representations
string-width
: Width
terminal-coding-system
: Terminal I/O Encoding
truncate-string-to-width
: Width
tty-erase-char
: System Environment
when
: Conditionals
window-configuration-change-hook
: Window Hooks
window-redisplay-end-trigger
: Window Hooks
with-current-buffer
: Current Buffer
with-output-to-string
: Output Functions
with-temp-buffer
: Current Buffer
with-temp-file
: Writing to Files
【注意】
現在、このバージョン2の発行者(FSF)住所は、正式に新しい住所の
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
に変わっている。
【注意】現在、このバージョン2の発行者(FSF)住所は、 正式に新しい住所の 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA に変わっている。
【訳注】日本語訳: 『Emacs Lispプログラミング入門』、アスキー出版局、ISBN 4-7561-1805-4
【訳注】日本語訳: 『GNU Emacsマニュアル』、アスキー出版局、ISBN 4-7561-3002-X
【訳注】ベクトルのみの誤り?
この『キー』の使い方は、『キー列』とは無関係。 キーとは、表の項目を探すために使う値を意味する。 ここでは、表は連想リストであり、項目は連想リストの連想値である。
『環境』のこの定義は、プログラムの結果に影響する すべてのデータを含むことは意図していない。
「ボタン押し下げ」は、「ドラッグ」の対句。
rightは垂直の区切り行やスクロールバーを含むが、
(window-width)
はそれらを含まないため、
完全に等しくはない。
【訳注】シェルのもとで動いているプロセス群
【訳注】協定世界時。旧グリニッジ標準時に相当。
【訳注】fortnightは2週間のこと。
omer: 過ぎ越しの祝い(Passover)の二日目から七週の祭(Shabuoth)の前日 までの49日間