2つの関数 buffer-name と buffer-file-name は、ファイルとバッファの違いを示します。次の式 (buffer-name) を評価すると、バッファの名前がエコーエリアに表示されます。(buffer-file-name)
を評価すると、バッファが参照するファイルの名前がエコーエリアに表示されます。通常、(buffer-name) が返す名前はそれが参照するファイルの名前と同じであり、(buffer-file-name) が返す名前はファイルのフルパス名となります。
ファイルとバッファは、それぞれ異なるものです。ファイルとは、コンピュータに永続的に記録された情報のことです(削除しない限り)。一方、バッファとはEmacs内部にある情報であり、編集セッションの終了時(またはバッファを破棄したとき)に消滅します。通常、バッファにはファイルからコピーした情報が含まれており、このときバッファはそのファイルを参照していると言います。このコピーこそが、作業や修正の対象となるものです。バッファへの変更は、バッファを保存するまでファイルには反映されません。バッファを保存すると、バッファの内容がファイルにコピーされ、それによって永続的に保存されます。
GNU EmacsのInfoでこれを読んでいる場合は、以下の各式の後にカーソルを置き、C-x C-eと入力することで評価できます。
(buffer-name) (buffer-file-name)
Infoでこれを行うと、(buffer-name)を評価して返される値は"*info*"となり、(buffer-file-name)を評価して返される値はnilとなります。
一方で、この文書を書いている時点では、(buffer-name)を評価して返される値は"introduction.texinfo"であり、(buffer-file-name)を評価して返される値は"/gnu/work/intro/introduction.texinfo"です。
前者はバッファ名、後者はファイル名です。Infoでは、バッファ名は"*info*"となります。Infoはいかなるファイルも指していないため、(buffer-file-name)を評価した結果はnilとなります。記号nilはラテン語の「何もない」に由来しており、この場合はバッファがいかなるファイルとも関連付けられていないことを意味します。(Lispでは、nilも「偽」という意味で用いられ、空リスト()の同義語となります。)
書き込み中のバッファ名は"introduction.texinfo"です。それが指しているファイルの名前は"/gnu/work/intro/introduction.texinfo"です。
(式中の括弧は、Lispインタプリタに buffer-name と buffer-file-name
を関数として扱うよう指示するものです。括弧がない場合、インタプリタはこれらのシンボルを変数として評価しようとします。変数を参照してください。)
ファイルとバッファの区別はあるものの、バッファのことを指してファイルと言ったり、その逆を言ったりする場面によく遭遇します。実際、ほとんどの人は「まもなくファイルに保存するバッファを編集している」と言うのではなく、「ファイルを編集している」と言います。文脈からすれば、相手が何を意味しているのかはほぼ常に明確です。しかし、コンピュータプログラムを扱う際には、コンピュータは人間ほど賢くないため、この区別を念頭に置いておくことが重要です。
ちなみに、「バッファ」という言葉は、衝突の衝撃を和らげるクッションという意味に由来しています。初期のコンピュータにおいて、バッファはファイルとコンピュータの中央処理装置とのやり取りを緩衝する役割を果たしていました。ファイルを保持するドラムやテープと、中央処理装置は、それぞれ動作速度が異なり、断続的に動作する、全く性質の異なる装置でした。バッファがあることで、これらが効果的に連携することが可能になったのです。やがてバッファは、仲介役や一時的な保管場所から、実際に処理が行われる場所へと発展していきました。この変遷は、小さな港町が大都市へと成長した過程に似ています。かつては単に、船に積み込まれる前に貨物を一時的に保管する場所に過ぎませんでしたが、やがてそれ自体が商業・文化の中心地となったのです。
すべてのバッファがファイルに関連付けられているわけではありません。例えば、*scratch* バッファはどのファイルにもアクセスしません。同様に、*Help* バッファもどのファイルにも関連付けられていません。
昔は、~/.emacs ファイルがなく、ファイル名を指定せずに emacs コマンドだけを入力して Emacs を起動すると、*scratch* バッファが表示された状態で Emacs
が起動していました。現在では、スプラッシュ画面が表示されます。スプラッシュ画面に表示されているコマンドのいずれかを実行するか、ファイルを開くか、あるいは
q を押してスプラッシュ画面を終了し、*scratch* バッファに移動することができます。
*scratch* バッファに切り替え、(buffer-name) と入力してその後ろにカーソルを置き、さらに C-x
C-e と入力して式を評価します。"*scratch*"
という名前が返され、エコーエリアに表示されます。"*scratch*"
はバッファの名前です。*scratch* バッファで (buffer-file-name) と入力してそれを評価すると、Info で (buffer-file-name) を評価したときと同様に、nil がエコーエリアに表示されます。
ちなみに、*scratch* バッファにいて、式が返す値をエコー領域ではなく *scratch* バッファ自体に表示させたい場合は、C-x C-e ではなく C-u C-x C-e と入力してください。これにより、式の後に返された値が表示されるようになります。バッファは次のようになります。
(buffer-name)"*scratch*"
Infoは読み取り専用であり、バッファの内容を変更することはできないため、Infoではこのような操作はできません。しかし、編集可能なバッファであればどれでも同様の操作が可能です。また、コードやドキュメント(本書など)を作成する際、この機能は非常に重宝します。