2つの機能のうち最も汎用的なものは、変数 format-alist によって制御されます。これは
ファイル形式
仕様のリストであり、Emacsバッファ内のデータに対してファイル内で使用されるテキスト表現を記述したものです。読み取りと書き込みの記述がペアになっており、そのためこれを「ラウンドトリップ」仕様と呼んでいます(ペアになっていない仕様については、Piecemeal
Specification を参照してください)。
このリストには、定義済みの各ファイル形式に対するフォーマット定義が1つずつ含まれています。各フォーマット定義は、次のような形式のリストとなっています。
(name doc-string regexp from-fn to-fn modify mode-fn preserve)
フォーマット定義における各要素の意味は以下の通りです。
このフォーマットの名称。
フォーマット用のドキュメント文字列。
この形式で表現されたファイルを認識するために使用される正規表現。nil
の場合、この形式が自動的に適用されることはありません。
この形式のデータをデコードする(ファイルデータを通常のEmacsデータ表現に変換する)シェルコマンドまたは関数。
シェルコマンドは文字列として表現され、Emacsはそのコマンドをフィルタとして実行して変換を行います。
from-fn が関数である場合、バッファの変換対象箇所を指定する2つの引数 begin と end を渡して呼び出されます。この関数は、テキストをその場で編集することで変換を行う必要があります。これによりテキストの長さが変わる可能性があるため、from-fn は変更後の終了位置を返す必要があります。
from-fn の責務の一つは、ファイルの先頭がもはや regexp と一致しないようにすることです。そうでないと、再度呼び出される可能性が高くなります。また、from-fn ではデコード対象以外のバッファやファイルを参照してはなりません。さもないと、フォーマットに使用される内部バッファが上書きされる恐れがあります。
データをこの形式でエンコードする――つまり、通常のEmacsのデータ表現をこの形式に変換する――シェルコマンドまたは関数。
to-fn が文字列の場合はシェルコマンドであり、Emacs はそのコマンドをフィルタとして実行して変換を行います。
to-fn が関数である場合、バッファのどの部分を変換するかを指定する begin と end、およびどのバッファを指定する buffer という3つの引数で呼び出されます。変換を行う方法は2通りあります:
(position
. string) 形式の要素のリストであり、position は書き込むテキスト内での相対位置を指定する整数、string はそこに追加するアノテーションです。to-fn
がリストを返す際は、位置順にソートされている必要があります。
write-region
が実際にバッファ内のテキストをファイルに書き出す際、指定されたアノテーションを対応する位置に挿入します。これらすべては、バッファを変更することなく行われます。
to-fn には、エンコード対象以外のバッファやファイルを含めてはなりません。さもないと、フォーマットに使用される内部バッファが上書きされる可能性があります。
フラグ。エンコーディング関数がバッファを変更する場合は t、アノテーションのリストを返す方式の場合は
nil。
この形式から変換されたファイルを開いた後に呼び出すマイナーモード関数。この関数は整数 1 という1つの引数で呼び出され、これによりマイナーモード関数は当該モードを有効にします。
フラグ。format-write-file が buffer-file-format からこのフォーマットを削除すべきでない場合に t。
insert-file-contents
関数は、指定されたファイルを読み込む際にファイル形式を自動的に認識します。ファイル先頭のテキストを形式定義の正規表現と照合し、一致が見つかった場合はその形式のデコード関数を呼び出します。その後、既知のすべての形式を改めて照合します。いずれの形式も該当しなくなるまで、この照合を繰り返します。
find-file-noselect
やそれを利用するコマンドを用いてファイルにアクセスする場合も、同様に変換が行われます(insert-file-contents
を呼び出すためです)。また、デコードする各フォーマットのモード関数も呼び出されます。フォーマット名のリストは、バッファローカル変数 buffer-file-format に格納されます。
この変数は、参照先ファイルのフォーマットを示します。より正確には、現在のバッファのファイルを参照する過程でデコードされたファイルフォーマット名のリストです。すべてのバッファにおいて、常にバッファローカルです。
write-region がファイルにデータを書き込む際は、まず buffer-file-format
に列挙されている形式のエンコーディング関数を、リストの出現順に呼び出します。
このコマンドは、現在のバッファ内容を、フォーマット名のリストである format に基づく形式でファイル
file に書き込みます。format
から実際のフォーマットを構築し、format にまだ含まれていない場合は、buffer-file-format の値から得られる要素を、nil 以外の preserve
フラグ(前述)と共に追記します。その後、このフォーマットで buffer-file-format
を更新し、今後の保存時のデフォルトとします。format 引数を除けば、このコマンドは write-file と同様です。特に、confirm は
write-file の対応する引数と同じ意味を持ち、同様のインタラクティブな処理が行われます。write-file の定義
を参照してください。
このコマンドはファイル file を探し、フォーマット format に従って変換します。また、後でバッファが保存される場合に備えて、format をデフォルトに設定します。
引数 format はフォーマット名のリストです。format が nil の場合、変換は行われません。対話的に
format に対して RET とだけ入力すると、nil が指定されます。
このコマンドは、ファイル file の内容を、フォーマット format に従って変換して挿入します。beg と end が nil 以外の場合、insert-file-contents と同様に、ファイルのどの部分を読み込むかを指定します(ファイルからの読み込み を参照)。
戻り値は insert-file-contents
が返すものと同様で、絶対ファイル名と(変換後の)挿入データの長さのリストとなります。
引数 format はフォーマット名のリストです。format が nil の場合、変換は行われません。対話的に
format に対して RET とだけ入力すると、nil が指定されます。
この変数は、自動保存に使用するフォーマットを指定します。値は buffer-file-format
の値と同様にフォーマット名のリストですが、自動保存ファイルの書き込みには buffer-file-format の代わりに使用されます。値がデフォルトの t
の場合、自動保存は同じバッファ内での通常の保存と同じフォーマットを使用します。この変数は、すべてのバッファにおいて常にバッファローカルです。