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

1. はじめに

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版です。

1.1 警告  Flaws and a request for help.
1.2 Lispの歴史  Emacs Lisp is descended from Maclisp.
1.3 表記法  How the manual is formatted.
1.4 版情報  Which Emacs version is running?
1.5 謝辞  The authors, editors, and sponsors of this manual.


1.1 警告

本書は、数多くの草稿を重ねてきました。 ほぼ完璧に近いはずですが、誤りは皆無ではありません。 ふれていない話題も少なからずあります。 (大部分の個別のモードのような)副次的と捉えている話題や、 まだ執筆していない話題もあります。 完全にはこれらに対処しきれませんので、 意図的に省いたことがらもあります。 たとえば、VMSにおける利用方法に関する情報です。

本書で取り上げたことがらに関しては、本書は完璧であるべきですから、 例題や記述内容から章や節の構成順序といったことまで、 広く意見を求めています。 混乱を招くような記述や、本書でふれていないことがらを 学ぶためにソースや実験で調べる必要があるときには、 本書を改訂すべきなのでしょう。 そのときは、ぜひ、教えてください。

本書を読むときには、訂正箇所をみつけたらすぐ送ってくださるようにお願いします。 1つの関数や一連の関数向けに、簡素で実用に即した例を思い付いたならば、 それを書き上げて、送ってください。 章/節/関数の名前を適宜入れてください。 それから、どの版に対する意見かも書いてください。

意見や訂正は、下記へメイルしてください。

 
bug-lisp-manual@gnu.org

ここに蓄積されたメイルは、誰かが改訂作業を始めるまでは、読み出しません。 改訂までに、数か月、ときには、数年経過することもあります。 ですから、返事がないと憤慨しないでください。 あなたのメイルは、そのうち処理されます。 Emacs保守グループに迅速に連絡したい場合には、 bug-gnu-emacs@gnu.orgにメイルしてください。


1.2 Lispの歴史

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 section `Common Lisp Extension' in Common Lisp Extensions

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


1.3 表記法

本節では、本書で用いる表記法を説明します。 本節を読み飛ばして、あとで参照してもかまいません。

1.3.1 用語  Explanation of terms we use in this manual.
1.3.2 nilt  How the symbols nil and t are used.
1.3.3 評価の表記法  The format we use for examples of evaluation.
1.3.4 結果表示の表記法  The format we use when examples print text.
1.3.5 エラーメッセージ  The format we use for examples of errors.
1.3.6 バッファ内のテキストの表記法  The format we use for buffer contents in examples.
1.3.7 記述形式  Notation for describing functions, variables, etc.


1.3.1 用語

本書では、『Lispリーダ』および『Lispプリンタ』という言葉で、 Lispオブジェクトのテキスト表現を実際のLispオブジェクトに変換する Lisp内部のルーティン群、および、逆の変換を行うルーティン群を指します。 詳しくは、See section 2.1 表示表現と入力構文。 本書の読者を『プログラマ』と考えて『読者』と呼びます。 『ユーザー』とは作者自身を含めたLispプログラムを使う人のことです。

Lispコードの例は、(list 1 2 3)という形式で、 このフォントで記します。 メタな変数の名前や説明対象の関数に対する引数の名前は、 first-numberという形式で、このフォントで書きます。


1.3.2 nilt

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では、niltは特別なシンボルであり、 評価するとそれ自身になります。 そのため、これらをプログラム内で定数として使うとき、 これらをクォートする必要はありません。 これらの値を変更しようとすると、エラーsetting-constantになります。 コロン(`:')で始まる名前のシンボルも同様です。 See section 10.2 変更不可能な変数


1.3.3 評価の表記法

評価可能なLisp式をフォーム(form、形式)と呼びます。 フォームを評価すると、Lispオブジェクトである結果を生じます。 本書の例題では、これを`=>'で表します。

 
(car '(1 2))
     => 1

これは、『(car '(1 2))を評価すると1になる』と読みます。

フォームがマクロ呼び出しの場合には、 Lispが評価すべき新たなフォームに展開します。 展開結果を`==>'で表します。 展開したフォームの評価結果を示す場合もあれば、 示さない場合もあります。

 
(third '(a b c))
     ==> (car (cdr (cdr '(a b c))))
     => c

あるフォームを説明するときに、 同一の結果を生じる別のフォームを示すことがあります。 2つのまったく等価なフォームを`=='で表します。

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


1.3.4 結果表示の表記法

本書の数多くの例題は、評価するとテキストを表示します。 (`*scratch*'バッファのような)Lisp対話バッファで例題のコードを 実行すると、表示テキストはバッファに挿入されます。 (関数eval-regionで評価するなどの) 別の手段で例題を実行すると、表示テキストはエコー領域に表示されます。 エコー領域に表示されるテキストは、1行に切り詰められていることに 注意してください。

本書の例題では、表示場所には無関係に、 表示テキストを`-|'で表します。 フォームを評価した結果返される値(ここではbar)は、 後続の行に分けて書きます。

 
(progn (print 'foo) (print 'bar))
     -| foo
     -| bar
     => bar


1.3.5 エラーメッセージ

エラーを通知する例題もあります。 これは、通常、エコー領域にエラーメッセージを表示します。 エラーメッセージは、`error-->'で始まる行に示します。 エコー領域には、`error-->'は表示されないことに注意してください。

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


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

バッファ内のテキストを修正する例題もあります。 このような場合、『実行前』と『実行後』のテキストを示します。 それらの例題では、バッファ名を含めたダッシュから成る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.3.7 記述形式

関数、変数、マクロ、コマンド、ユーザーオプション、 スペシャルフォームは、本書では統一した形式で記述します。 第1行目は、それぞれの名前と、引数があれば引数群です。 関数、変数、マクロ、コマンド、ユーザーオプションの分類を行頭に書きます。 これに説明文が続き、場合によっては例題も示します。

1.3.7.1 関数の記述例  A description of an imaginary function, foo.
1.3.7.2 変数の記述例  A description of an imaginary variable,
electric-future-map.


1.3.7.1 関数の記述例

関数の記述では、まず始めに説明対象の関数名があります。 同じ行には、引数名の並びも続きます。 これらの名前は、説明文の中で引数の値を参照するために使います。

引数ならびにキーワード&optionalが現れていれば、 それ以降の引数を省略できることを示します(省略した引数の値はnil)。 関数を呼び出すときに&optionalを書いてはいけません。

キーワード&rest (このあとには1つの引数名だけが続く)は、 残りの引数が何個でもよいことを示します。 直後にある1つの引数名は、変数としての値を持ち、 その値は残りのすべての引数のリストです。 関数を呼び出すときに&restを書いてはいけません。

では、仮想的な関数fooの記述を以下に示します。

Function: foo integer1 &optional integer2 &rest integers
関数fooは、integer2からinteger1を引き算し、 残りのすべての引数を減算結果に加える。 integer2を指定しないと、デフォルトでは、数19から引き算する。

 
(foo 1 5 3 9)
     => 16
(foo 5)
     => 14

より一般的には、つぎのとおり。

 
(foo w x y...)
==
(+ (- x w) y...)

integerinteger1bufferなどの)型名を名前とする引数は、 その型の値であると仮定します。 (buffersのように)型を複数形にした場合には、 しばしば、その型のオブジェクトのリストを意味します。 objectという名前の引数は、任意の型でかまいません。 (Emacsオブジェクトの型の一覧については、see section 2. Lispのデータ型)。 (new-fileなどの)その他の名前の引数は、関数の説明文の中で言及します。 複数の関数の引数に共通する特徴について、 節の始めで説明する場合もあります。

&optional&restについての詳しい説明は、 See section 11.2 ラムダ式

コマンド、マクロ、スペシャルフォームの記述も同じ形式ですが、 「関数」のかわりに 「コマンド」、「マクロ」、「スペシャルフォーム」のいずれかです。 コマンドは、対話的に呼び出せる単なる関数です。 マクロは関数とは違った方法で引数を処理します(引数を評価しない)が、 同じ方法で引数を記します。

スペシャルフォームの記述では、省略可能な引数や繰り返される引数を 示すために、より複雑な記法を使います。 というのは、引数並びを個々の引数に分離する方法が複雑だからです。 `[optional-arg]'は、 optional-argが省略可能であることを示します。 また、`repeated-args...'は、0個以上の引数を示します。 いくつかの引数をリスト構造の内側にまとめるときには、 括弧を使います。

Special Form: count-loop (var [from to [inc]]) body...
この仮想的なスペシャルフォームは、 フォーム群bodyを実行してから変数varを増やすことを 反復するループを実現する。 最初は、変数の値はfromである。 以降の反復では、変数を1(あるいは、指定があればincだけ)増やす。 vartoに等しくなると、 bodyを実行せずにループから抜ける。 例を示す。

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

fromtoを省略すると、 ループ開始前にvarnilを束縛し、 各反復の開始時にvarnil以外であるとループから抜け出る。

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

このスペシャルフォームでは、引数fromtoは省略できるが、 両者を同時に指定するか、同時に省略すること。 これらを指定した場合、incを指定してもよい。 これらの引数は、引数varとともにリストにまとめる。 これはbodyと区別するためであり、 bodyは残りのフォームの要素すべてを含む。


1.3.7.2 変数の記述例

変数(variable)は、値を保持するための名前です。 ユーザーはどんな変数でも設定できますが、 ユーザーが変更可能な特定の変数群があり、 それらをユーザーオプション(user options)と呼びます。 普通の変数もユーザーオプションも関数の記述と同じ形式で示しますが、 それらに引数はありません。

仮想的な変数electric-future-mapの記述例を示します。

Variable: electric-future-map
この変数の値は、Electric Command Futureモードで使用する 完全なキーマップである。 このマップに含まれる関数は、まだ実行していないコマンドの編集を可能にする。

ユーザーオプションの記述も同じ形式ですが、 「変数」のかわりに「ユーザーオプション」です。


1.4 版情報

これらの機構は、使用中の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"

対話的に呼び出すと、この関数は同じ情報をエコー領域に表示する。

Variable: emacs-build-time
この変数の値は、ローカルのサイトでEmacsを構築した日時を示す。 3つの整数から成るリストであり、 current-timeと同様のもの(see section 37.5 時刻)。

 
emacs-build-time
     => (13623 62065 344633)

Variable: emacs-version
この変数の値は、実行中のEmacsの版番号。 "20.3.1"のような文字列である。 この文字列の最後の数字は、Emacsのリリース版番号の一部ではなく、 特定のディレクトリでEmacsを構築するたびに増える。

つぎの2つの変数は、Emacs 19.23以降に存在します。

Variable: emacs-major-version
Emacsのメジャー版番号を表す整数。 Emacs 20.3では、値は20。

Variable: emacs-minor-version
Emacsのマイナ版番号を表す整数。 Emacs 20.3では、値は3。


1.5 謝辞

本書は、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。


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

This document was generated by Akihiro Sagawa on January, 21 2003 using texi2html