[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この章では、 稼動中のEmacs実行可能形式を どのようにEmacs Lispライブラリをプリロードしたままダンプするのか、 どのように記憶領域を割りつけるのか、 そして、 Cのプログラマが興味をもつようなGNU Emacsのいくつかの内部構造について 述べます。
B.1 Emacsを作る | EmacsにLispライブラリをプリロードさせる方法。 | |
B.2 純粋記憶領域 | プリロードしたLisp関数を共有する小細工。 | |
B.3 ガベージ・コレクション | 使われないLispオブジェクトの空間を回収する。 | |
B.4 Emacsのプリミティブを書く | CでEmacsのコードを書く。 | |
B.5 オブジェクトの内部構造 |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
この節では、 Emacsの実行可能形式を作るときに起きている諸段階について説明します。 この種のことはメークファイルが自動的に行なってくれるので、 Emacsを作ってインストールするときに知っておく必要はありません。 この情報はEmacsの保守に関係あります。
`src'ディレクトリでCのソース・ファイルをコンパイルすると、 `temacs'という実行可能ファイルができますが、 これをbare impure Emacsといいます。 これにはEmacs LispインタプリタとI/Oルーチンがありますが、 編集コマンドはついていません。
コマンド`temacs -l loadup'では、 本当に実行ができるEmacs実行可能ファイルをつくるのに、 `temacs'を使います。 この引数は`temacs'に、 ファイル`loadup.el'中で指定したLispファイル群を評価させる、 ということを指示しています。 このファイル群で通常のEmacs編集環境を準備すると、 Emacsはbareではなくなりますが、まだimpureではあります。
標準Lispファイル群の読込みには相当時間がかかります。 幸運にも、 Emacsを起動するたびにこれを繰り返すことはありません。 `temacs'は、 このファイル群をプリロードした`emacs'という実行可能プログラムを ダンプすることができます。 `emacs'はもうこのファイルのロードがいらないので、 とても速く立ち上がります。 普通にインストールされるのはこちらのEmacsです。
`emacs'を作るには、 コマンド`temacs -batch -l loadup dump'を使います。 この`-batch'で`temacs'が 端末のデータを初期化しないようにしています。 これでダンプ後のEmacsの端末情報が空のままになります。 引数`dump'で`loadup.el'にしたがって`emacs'という 新しい実行可能ファイルをダンプしています。
オペレーティング・システムによっては、 ダンプのできないことがあります。 こういうシステムでは、 Emacsを使うたびに、 `temacs -l loadup'というコマンドで始める必要があります。 これにはけっこう時間がかかりますが、 Emacsを立ち上げるのは高々日に1回か、 ログ・アウトしないなら週に1回でしょうから、 この時間もそれほど深刻な問題ではありません。
`site-load.el'ライブラリを書いて
プリロードするファイルを追加することができます。
追加ファイル用の場所をあけるために、
`src/puresize.h'中のPURESIZE
の値を
増やす必要があることもあります
(十分な大きさになるまで20000ずつ増やしてみてください)。
しかしながら、
追加ファイルのプリロードの利点はマシンが速くなるにつれて減ってきています。
最近のマシンではだいたい、
そんなに得策ではありません。
ダンプ前に実行するほかのLisp式を`site-init.el'という ライブラリに書いて指定します。 しかしながら、 ユーザが通常の無修正のEmacsに期待する振舞いを変更する場合は、 ユーザが望むときに優先できるように`default.el'に置く方が いいでしょう。See section 立ち上がりの際の一連の動作一覧。
`loadup.el'が新しい実行可能ファイルをダンプする前に、
Snarf-documentation
を呼び出して(see section 説明文字列へのアクセス)、
プリミティブ関数とプリロードした関数(と変数)を定義したファイルから
説明文字列を探し出します。
`emacs'実行可能ファイルを小さくするために、
説明文字列は実行可能ファイルから取り除かれます。See section 説明文字列の基礎。
この関数は、 Emacsの現在の状態を実行可能ファイルto-fileにダンプします。 これは(通常はファイル`temacs'の) from-fileからシンボルを取ります。
すでにダンプしてしまったEmacsでこの関数を使う場合、
まずcommand-line-processed
をnil
にしなければ
うまくいきません。See section コマンド行引数。
この関数は、 走行中のEmacsのバージョン番号を示す文字列を返します。 バグ報告にこの文字列を含めると役に立ちます。
(emacs-version) ⇒ "GNU Emacs 19.29.1 (i386-debian-linux) \ of Tue Jun 6 1995 on balloon" |
対話的に呼び出されると、この関数は、エコー領域に同じ情報を印字します。
この変数の値は、ローカルなサイトでEmacsが作られた時刻です。
emacs-build-time ⇒ "Tue Jun 6 14:55:57 1995" |
この変数の値は、走行中のEmacsのバージョン番号です。
これは"19.29.1"
といった文字列になります。
以下の二つの変数はEmacsのバージョン19.23まではなかったため、 今のところそれほど役には立ちませんが、 私たちは将来これが役に立つであろうことを期待しています。
整数で表わしたEmacsの主バージョン番号です。 Emacsバージョン19.29では19という値になります。
整数で表わしたEmacsの副バージョン番号です。 Emacsバージョン19.29では29という値になります。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Emacs Lispには、 ユーザの作るLispオブジェクト用に 通常記憶領域(normal storage)と純粋記憶領域(pure storage) の2種類の記憶領域があります。 通常記憶領域はEmacsの各セッションで作られた新しいデータの すべてを保持する領域です。 通常記憶領域については次節を参照してください。 純粋記憶領域はプリロードされる標準Lispファイル中のデータで、 実際のEmacsの使用中に変化することのないものにたいして使われます。
純粋記憶領域は、
`temacs'が標準のLispライブラリをプリロードするときに
割りつけられます。
ファイル`emacs'中で、
これは(オペレーティング・システムが許すかぎり)読出し専用なので、
マシンで同時に走る全Emacsジョブでメモリ空間を共有することができます。
純粋記憶領域は、Emacsのコンパイル時に固定量が割りつけられ、
拡張することはできません。
プリロード・ライブラリで足りなくなると`temacs'は落ちてしまいます。
こうなると、
ファイル`src/puresize.h'のPURESIZE
という
コンパイル時パラメータを増やすしかありません。
追加のライブラリをプリロードするか、
標準のライブラリに機能を追加するのでないかぎり、
こうなることはまずありません。
この関数は、純粋記憶領域中のobjectの複製を作り、それを返します。 文字列は、同じ文字群をもつものを純粋記憶領域中にただ新しく作ることで 複製を行ないます。 ベクタとコンス・セルの内容は、再帰的に複製します。 マーカを複製するよう要求すると、エラーを通知します。
Emacsが作られダンプされた後、この関数は、空操作になります。 通常は、ファイル`emacs/lisp/loaddefs.el'だけで呼び出されますが、 プリロードすると決めた場合にはこれを呼び出しているパッケージも少しあります。
この変数の値は、これまで割りつけられた純粋記憶領域のバイト数です。 普通ダンプ後のEmacsで、 この数は存在する純粋記憶領域の総量に非常に近くなります。 もしそうでないときには、割りつける量を少なくできます。
この変数は、
defun
が純粋記憶領域に関数定義の複製を
作るべきか否かを定めます。
非nil
の場合、
関数定義は純粋記憶領域に複製されます。
(これらの関数を共有可能で回収不能であるようにするため)
最初Emacsを作るときに基本的な全関数をロードする間、
このフラグはt
になっています。
実行可能なプログラムとしてEmacsのダンプを行なうと、
ダンプ前や後の値にかかわらず常にnil
に設定されます。
Emacsの走行中にこのフラグを変更してはいけません。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プログラムがリストを作ったり、 (ライブラリをロードして)ユーザが新しい関数を定義したり場合、 それらは通常記憶領域に置かれます。 通常記憶領域が足りなくなった場合、 Emacsはオペレーティング・システムに それ以上のメモリを1kバイトのブロックで 割りつけるよう要求します。 割りつけられたブロックは、それぞれある1種類の型用に用いられます。 つまり、シンボル、コンス・セル、 マーカなどはメモリ中の異なるブロックにわけられることになります (ベクタ、長い文字列、 バッファおよびそれ以外の一部の非常に大きな編集用の型は、 各オブジェクトごとに割りつけられ、 短い文字列は8kバイトのブロックに詰められます)。
記憶領域をある期間だけ用いて、その後(たとえば)バッファをkillしたり、 オブジェクトに対する最後のポインタを消去したりすることにより、 開放することは、 非常に一般的なことです。 Emacsでは、この放棄された記憶領域を再生する ガベージ・コレクタ(garbage collector)が提供されています (この名前は伝統的なもので、 この機能の直感的なたとえとしては「ゴミ再利用」"garbage recycler"の方が いいかもしれません)。
ガベージ・コレクタは、 Lispプログラムから用いることのできるすべてのLispオブジェクトをスキャンし、 印をつけることで処理を行ないます。 はじめにすべてのシンボル、 その値と対応する関数定義、 現在スタック上に存在するデータは用いられているものであると仮定します。 これらを通して間接的に到達可能なオブジェクトも すべて用いられているという刻印を押します。
印づけが終わったとき、 刻印のないものはすべてガベージです。 Lispプログラムやユーザが何をしようとも、 もはやここへ到達する方法がないため、 ここを使うことは不可能です。 この空間は再利用してもほかと影響しません。 ガベージ・コレクタの第2の「掃き出し」("sweep")段階では、 この場所の再利用を行ないます。
この「掃き出し」段階において、
用いられてないコンス・セル、シンボル、マーカは、
将来の割りつけ用にフリーリスト(free list)につなげられます。
使用中の文字列はなるべく少ない8kブロックに収まるようまず圧縮され、
その後、空いた8kブロックは解放します。
ベクタ、バッファ、ウィンドウ、そのほか大きなオブジェクトは、
個々にmalloc
とfree
を用いて割りつけと解放を行ないます。
Common Lisp注意書き:ほかのLispと異なり、GNU Emacs Lispでは フリーリストが空になった場合にガベージ・コレクタは呼ばれません。 そのかわり、GNU Emacs Lispは、 ただ単にオペレーティング・システムへもっと多くの記憶領域を割りつけするよう要求し、
gc-cons-threshold
バイト使われるまで処理を続けます。これは、陽にガベージ・コレクタを呼び出すことによって、 Lispプログラムのある部分を実行中にガベージ・コレクタが動かないことを (プログラムの一部が次のガベージ・コレクションを引き起こすほど 大きな空間を消費しないことを前提にして)保証できます。
このコマンドはガベージ・コレクションを行ない、
用いられている記憶領域の量に関する情報を返します
(ガベージ・コレクションは、
前のガベージ・コレクションからgc-cons-threshold
バイト以上Lispデータが用られた場合、
自動的に行なわれます)。
garbage-collect
は以下の情報を含むリストを返します。
((used-conses . free-conses) (used-syms . free-syms) (used-markers . free-markers) used-string-chars used-vector-slots (used-floats . free-floats)) (garbage-collect) ⇒ ((3435 . 2332) (1688 . 0) (57 . 417) 24510 3839 (4 . 1)) |
次の表は各要素の説明です。
使用中のコンス・セルの個数。
オペレーティング・システムから空間を得てはいるが、 今のところ使われていないコンス・セルの個数。
使用中のシンボルの個数。
オペレーティング・システムから空間を得てはいるが、 今のところ使われていないシンボルの個数。
使用中のマーカの個数。
オペレーティング・システムから空間を得てはいるが、 今のところ使われていないマーカの個数。
文字数で測った全文字列の長さの合計。
既存のベクタの要素数の合計。
使用中の浮動小数点数の個数。
オペレーティング・システムから空間を得てはいるが、 今のところ使われていない浮動小数点数の個数。
この変数の値は、ガベージ・コレクションが行なわれた後、 次のガベージ・コレクションが自動的に呼ばれるまでに用いることのできる、 記憶領域のバイト数です。 コンス・セルは8バイト、 文字列は1文字当り1バイト足す数バイトのオーバーヘッド、 などのように数えます。 バッファの内容は勘定に入れません。 それ以降は、 次にLisp評価子を呼び出すときをのぞき、 この閾値をこえるまでガベージ・コレクションがおこりません。
この閾値の初期値は300,000です。 もし大きな値を設定すると、ガベージ・コレクションは起こりにくくなります。 ガベージ・コレクションに使われる時間は減りますが、 メモリの総使用量は増加します。 多量のLispデータを作るようなプログラムを使う場合には、 このようにしたくなるかもしれません。
ガベージ・コレクションの回数を増やすため、
10,000以上の小さな値に設定することもできます。
これを10,000以下の値に設定しても、次のガベージ・コレクションまでしか効果はありません。
そのときにgarbage-collect
はこれを10,000に戻します。
この関数は、 Emacsが割りつけた最後のバイトのアドレスを1024で割ったものです。 1024で割っているのは値がLisp整数の範囲に収まるようにするためです。
メモリ使用量により影響を受ける動作の決定にこれを使うことができます。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Lispプリミティブとは、Cで実装したLisp関数のことです。 LispでCの関数が呼び出せるようにするインタフェースの詳細を、 Cのマクロで扱っています。 Cのコードの書きかたを本当に理解する唯一の方法は、 ソースを読むことですが、 ここではある程度の情報を示しておきます。
特殊形式の例としてor
の定義を`eval.c'から取りました
(通常の関数も同様に一般的な形をしています)。
DEFUN ("or", For, Sor, 0, UNEVALLED, 0, "Eval args until one of them yields non-nil, then 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) |
これはLispシンボルの名前で、定義する関数の名前となります。
前の例の場合これはor
です。
これは、この関数に対するCの関数名です。
これはCコードからこの関数を呼ぶ際、用いられる名前です。
慣例として名前はLisp名の先頭に`F'をつけ、
Lisp名におけるダッシュ(-
)をすべてアンダースコアに変えたものです。
したがって、
Cコードからこの関数を呼ぶ場合、
それはFor
を呼ぶことになります。
引数はLisp_Object
でなくてはいけないことを覚えておいてください。
型Lisp_Object
を作るさまざまなマクロと関数は、
ファイル`lisp.h'で宣言されています。
これは、 Lispでの関数を表現するsubrオブジェクトのデータを保持する 構造体に用いるCの変数名です。 この構造体は、 シンボルを生成しsubrオブジェクトを定義に格納する初期化ルーチンに、 Lispシンボル名を渡します。 この名前は 慣例としてfnameの`F'を`S'に置き換えたものとなります。
これは、与えられなくてはいけない最小の引数の数です。
関数or
の場合、引数のない場合を許しています。
これは、固定の最大値があれば、関数が受けつける引数の最大個数です。
または、
引数を評価しないことを示すUNEVALLED
か、
(&rest
と等価な)
任意個の評価される引数をもつことを示すMANY
をもつことになります。
UNEVALLED
とMANY
は両方ともマクロです。
maxが数の場合、minより小さかったり、
7より大きかったりしてはいけません。
これは、
Lisp関数のinteractive
への引数に用いる文字列と
同じ interactive 指示です。
or
の場合、これは0(ヌル・ポインタ)で、
or
を対話的に呼ぶことはできないことを示します。
値""
は、
対話的に呼んだ場合に引数をとらない関数を示します。
これは説明文字列です。 各行末で`\n\'を書かなければならない点を除いて、 Lispで定義する関数の説明文字列と同じように書きます。 特に、1行目は一つの文にしてください。
DEFUN
マクロ呼びだしの後で、
すべてのCの関数にあるような引数名リストと、
その後に普通のCの引数宣言を書かなくてはなりません。
引数の最大個数が固定の関数は、
各Lispの引数に対してCの全引数をLisp_Object
型として
宣言しなくてはいけません。
Lisp関数に引数の数の上限がないとき、
Cの実装ではちょうど二つの引数を取ります。
1番目がLisp引数の個数で、
2番目が引数の値を格納したブロックのアドレスです。
これらの型はそれぞれint
とLisp_Object *
です。
関数For
中で
マクロGCPRO1
とUNGCPRO
の使い方に
注目してください。
GCPRO1
は変数をガベージ・コレクタから保護するのに使います。
これは、
ガベージ・コレクタがこの変数の中を見て、
この内容がアクセス可能なオブジェクトであると
みなすようにします。
これはFeval
を呼び出す場合や、
Feval
を直接間接に呼び出すもののうちのいずれかを呼び出す場合には
常に必要となります。
このような場合、
(そのような関数の呼出しの後で)再び
参照しようとしているLispオブジェクトも全部保護しなければなりません。
UNGCPRO
は現在の関数で保護している変数の保護を取消します。
これは陽にそうする必要があります。
ほとんどのデータ型については、 オブジェクトへのポインタを少なくとも一つ保護すれば十分です。 オブジェクトが再利用されるまでは、 そこへのポインタはずっと有効なままです。 ガベージ・コレクタが移動させてしまうので、文字列について、 これはあてはまりません。 ガベージ・コレクタが文字列を移動するとき、 わかる範囲のすべてのポインタのさしかえを行ないますが、 それ以外のポインタは無効になります。 したがって、 ガベージ・コレクションが起こりうる場所以降のすべての 文字列へのポインタを保護しなければなりません。
マクロGCPRO1
は局所変数を1個保護します。
2個保護したいときは、
GCPRO2
を使います。
GCPRO1
を繰り返してもうまくいきません。
なおマクロGCPRO3
とGCPRO4
もあります。
このマクロ群は暗にgcpro1
といった局所変数を使います。
これはstruct gcpro
型で陽に宣言しなければなりません。
したがって、
GCPRO2
を使うときはgcpro1
とgcpro2
を宣言します。
残念ながら、ここでトリッキーな詳細について説明することはできません。
いったんダンプしてしまったEmacsでは、 (いったんEmacsをダンプしたからにはもう書き変えないという場合以外) 静的変数や外部変数でCの初期値を使ってはいけません。 ダンプ後のEmacsで、初期値のある変数は、 (あるオペレーティング・システムで) 読出し専用のメモリ領域に割りつけられるためです。
関数の中では、静的な変数を使ってはいけません。
静的変数はファイルのトップ・レベルに置いてください。
これは、あるオペレーティング・システムにおいて
キーワードのstatic
を空マクロとして定義するために
そうする必要があります
(この定義は、初期化の有無にかかわらず、そのようなシステムに
おいて静的に宣言した全変数がダンプ後に読出し専用になってしまうために、
使われています)。
Cの関数を定義するだけではLispプリミティブは有効になりません。 プリミティブのLispシンボルを生成し、 関数セルに適切なsubrオブジェクトを格納する必要があります。 これは以下のようなコードになります。
defsubr (&subr-structure-name); |
ここでsubr-structure-nameはDEFUN
の第3引数にした
(訳注: subrオブジェクトの)変数名です。
すでに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
のどちらかを値に取るように見えるCのint
型変数を作ります。
次に、より複雑な引数をもつ別の関数を示します。 これはXウィンドウ・システム用のコードからのもので、 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 POSITIONS is in WINDOW.\n\ \(POSITIONS is a list, (SCREEN-X SCREEN-Y)\)\n\ Returned value is list of positions expressed\n\ relative to window upper left corner.") (coordinate, window) register Lisp_Object coordinate, window; { register Lisp_Object xcoord, ycoord; if (!CONSP (coordinate)) wrong_type_argument (Qlistp, coordinate); CHECK_WINDOW (window, 2); xcoord = Fcar (coordinate); ycoord = Fcar (Fcdr (coordinate)); CHECK_NUMBER (xcoord, 0); CHECK_NUMBER (ycoord, 1); if ((XINT (xcoord) < XINT (XWINDOW (window)->left)) || (XINT (xcoord) >= (XINT (XWINDOW (window)->left) + XINT (XWINDOW (window)->width)))) return Qnil; XFASTINT (xcoord) -= XFASTINT (XWINDOW (window)->left); if (XINT (ycoord) == (screen_height - 1)) return Qnil; if ((XINT (ycoord) < XINT (XWINDOW (window)->top)) || (XINT (ycoord) >= (XINT (XWINDOW (window)->top) + XINT (XWINDOW (window)->height)) - 1)) return Qnil; XFASTINT (ycoord) -= XFASTINT (XWINDOW (window)->top); return (Fcons (xcoord, Fcons (ycoord, Qnil))); } |
Cで定義してある関数以外は、
Cのコードから関数名での呼出しができないことに注意してください。
Lispで書いた関数を呼び出すには、
Lisp関数funcall
の本体であるFfuncall
を使います。
Lisp関数のfuncall
は引数を無制限に受けつけるので、
CではLispレベルでの引数の個数と、
その値を格納した1次元配列の二つの引数を受けつけます。
Lispレベルでの最初の引数は呼び出そうとするLispの関数で、
残りはそれへの引数です。
Ffuncall
は評価子を呼び出すことがあるので、
Ffuncall
のまわりではポインタを保護する必要があります。
Cの関数call0
、call1
、call2
などによって、
一定個数の引数でLisp関数を手軽に呼び出すことができます。
これはFfuncall
の呼出しによるものです。
例になるものを探すには、`eval.c'は大変適したファイルです。 `lisp.h'には、 いくつか重要なマクロの定義や関数(訳注: の宣言)があります。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
GNU Emacs Lispは、多くの異なる型を扱います。 実際のデータはヒープに格納され、 プログラムは唯一ポインタを通し、 そのデータに対しアクセスします。 ポインタはほとんどの実装において32ビットの幅をもちます。 オペレーティング・システムと、 Emacsをコンパイルするマシンの型によって、 3ビットにオブジェクトの型を示すタグを用い、 残りの28ビットくらいでオブジェクトを指します (原著では 「オブジェクトを指すのに24ビットから26ビット分ぐらいを用い、 残りの6ビットから8ビットをオブジェクトの型を示すタグとして用います。」 としている)。
Lispオブジェクトに対するアクセスは、
すべてタグのつけられたポインタで表わすため、
どんなオブジェクトであってもオブジェクトのLispデータ型を決めることは
常に可能です。
Cのデータ型Lisp_Object
は、
どんな型のLispオブジェクトでも保持することができます。
普通の変数は、Lisp_Object
型なので、
どんなLisp値でもとることができます。
実際のデータ型は実行時に決定できます。
関数引数も同様です。
ある型の引数のみを受け取る関数が必要な場合、
適切な述語を用い、明示的に型の検査を行なう必要があります
(see section 型述語)。
B.5.1 バッファの内部構造 | ||
B.5.2 ウィンドウの内部構造 | ||
B.5.3 プロセスの内部構造 |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
おのおののバッファは、 Lispプログラマが直接アクセスすることのできないフィールドがあります。 ここではCのコードで使う名前でこれらを解説します。 LispプログラムからはLispプリミティブでアクセス可能なフィールドが、 数多くあります。
name
バッファ名は、バッファを名づける文字列です。 これは一意であることが保証されています。See section バッファの名前。
save_modified
このフィールドには、 バッファを最後にセーブした時刻を、 整数で格納します。See section バッファの変更。
modtime
このフィールドは、読み込んでいるファイルの修正時刻を格納します。 これはそのファイルが書かれるか読まれるかしたときに設定されます。 バッファがファイルに書かれるたびに、 このフィールドは ファイルの修正時刻と比較されます。See section バッファの変更。
auto_save_modified
このフィールドは、 バッファが最後に自動セーブされた時刻を格納します。
last_window_start
このフィールドは、
バッファのwindow-start
位置、すなわち、
最後にバッファがウィンドウに表示された際、
その表示を開始したバッファ中の位置を格納します。
undo_list
このフィールドは、 バッファのundoリストを指します。See section 取り消し。
syntax_table
(原著ではsyntax_table_v
としています)
このフィールドは、
バッファに対する構文テーブルを格納します。See section 構文テーブル。
downcase_table
このフィールドは、 テキストを小文字に変換するときの変換テーブルを格納します。See section 大文字小文字変換のカスタマイズ。
upcase_table
このフィールドは、 テキストを大文字に変換するときの変換テーブルを格納します。See section 大文字小文字変換のカスタマイズ。
case_canon_table
このフィールドは、 case-fold検索でテキストを正準化するときの 変換テーブルを格納します。See section 大文字小文字変換のカスタマイズ。
case_eqv_table
このフィールドは、 case-fold検索の等価テーブルを格納します。See section 大文字小文字変換のカスタマイズ。
display_table
このフィールドは、
バッファの表示テーブルか、
それが存在しない場合は、
nil
を格納します。See section 表示テーブル。
markers
このフィールドは、 現在、バッファの中を指すすべてのマーカの連鎖を格納します。 バッファのテキストを消去したり バッファのギャップを移動したりした場合には これらの各マーカを検査し、 多分更新をしなくてはいけません。
backed_up
このフィールドは、 このバッファに読み込んでいるファイルのバックアップをとったか否かを示すフラグです。
mark
このフィールドは、
バッファに対するマークを格納します。
マークはマーカですから、
マークはリストmarkers
にも含まれます。See section マーク。
mark_active
このフィールドは、
バッファのマークがアクティブなら非nil
です。
local_var_alist
このフィールドは、バッファ・オブジェクトの特別な場所 (ここでは説明を省きます)に存在するローカル変数以外の、 バッファのローカル変数と、それに対応する値とを含む 連想リストを格納します。See section バッファローカルな変数。
base_buffer
このフィールドは、
バッファの基本バッファ
(もし間接バッファなら)かnil
を保持します。
keymap
このフィールドは、 バッファのローカル・キーマップを保持します。See section キーマップ。
overlay_center
このフィールドは、 現在のオーバレイの中央位置を保持します。See section オーバレイ。
overlays_before
このフィールドは、 このバッファの現在のオーバレイの中央位置かその前で終わる オーバレイのリストを保持します。 終了位置の逆順で整列してあります。
overlays_after
このフィールドは、 このバッファの現在のオーバレイの中央位置よりも、 後ろで終わるオーバレイのリストを保持します。 先頭位置の昇順に整列してあります。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ウィンドウは、アクセス可能な以下のフィールドがあります。
frame
ウィンドウのあるフレーム。
mini_p
もしこのウィンドウがミニバッファのウィンドウならば非nil
。
buffer
ウィンドウが表示しているバッファ。 これはウィンドウの存在期間中に変更されることがしばしばです。
dedicated
もしこのウィンドウがそのバッファ専用ならば非nil
。
pointm
これは、ウィンドウが選択されている場合、カレント・バッファのポイントです。 選択されていない場合、前の値を保持します。
start
ウィンドウに表示される最初の文字のバッファ中の位置。
force_start
もしこのフラグが非nil
ならば、
Lispプログラムが陽にウィンドウをスクロールしたことを示します。
ポイントが画面からはずれた場合、
これは次の再表示で何がおきるかに影響します。
ポイントのまわりのテキストを見せるためにウィンドウをスクロールする代わりに、
画面上のある場所にポイントを動かします。
last_modified
最後にウィンドウの再表示を行なったときの、
ウィンドウのバッファのmodified
フィールド。
last_point
最後にウィンドウの再表示を行なったときの、 ウィンドウのバッファのポイントの値。
left
これは、ウィンドウの左端の桁位置です (画面の左端は桁0です)。
top
これは、ウィンドウの上端の行位置です (画面の上端は行0です)。
height
ウィンドウの高さ(行数)。
width
ウィンドウの幅(桁数)。
next
これは、同胞
(訳注: slibing)
の連鎖の中で次に位置するウィンドウです。
同胞のグループで最も右あるいは下のウィンドウでは、nil
です。
prev
これは、同胞の連鎖の中で前に位置するウィンドウです。
同胞のグループで最も左あるいは上のウィンドウでは、nil
です。
parent
Emacsは内部的にウィンドウの木をもっています。 同胞の各グループには、同胞全部を含んだ親ウィンドウがあります。 このフィールドはその親ウィンドウを指します。
親ウィンドウはバッファの表示をしません。 そして子ウィンドウの形状のほかは、 表示に際した役割をそれほどもおってはいません。 Emacs Lispプログラムでは親ウィンドウにアクセスすることは通常できません。 プログラム上は、実際にバッファを表示する、 木の葉にあたるウィンドウだけを操作します。
hscroll
これは、 ウィンドウ中の表示が水平方向に左にスクロールされるときの桁数です。 通常は0です。
use_time
これは、ウィンドウが最後に選択された時刻です。
このフィールドはget-lru-window
で用いられます。
display_table
ウィンドウの表示テーブルか、
もしそれがなければnil
。
update_mode_line
非nil
はウィンドウのモード行の更新が必要なことを意味します。
base_line_number
バッファ上のある位置の行番号またはnil
。
これはモード行にポイントの行番号を表示するときに使います。
base_line_pos
行番号のわかっているバッファ上の位置、あるいは不明な場合はnil
。
region_showing
もしこのウィンドウでリージョン(かその一部分)が強調表示しているなら、
このフィールドはリージョンの一端となるマークの位置。
さもなくばこのフィールドはnil
。
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
プロセスのフィールドは、以下のとおり。
name
プロセスの名前の文字列。
command
プロセスを始動したときのコマンド引数を格納するリスト。
filter
バッファのかわりに、 プロセスからの出力を受け取るのに用いられる関数。
sentinel
プロセスがシグナルを受け取ったときに呼ばれる関数か、nil
。
buffer
プロセスに対応したバッファ。
pid
プロセスのUnixプロセスIDの整数。
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
もしサブプロセスとの通信にPTYを使うなら非nil
、
もしパイプを使うのならnil
。
infd
プロセスからの入力ファイル記述子。
outfd
プロセスへの出力ファイル記述子。
subtty
子プロセスが使う端末のファイル記述子
(システムによっては記録する必要がないので、値はnil
です)。
tty_name
サブプロセスの使っている端末の名前か、または、
パイプを使っている場合はnil
。
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Yasutaka SHINDOH on September, 29 2006 using texi2html 1.76.