Emacsでファイルを編集する場合、実際にはそのファイルをビジットしているバッファを操作していることになります。つまり、ファイルの内容がバッファにコピーされ、そのコピーを編集しているということです。バッファへの変更は、バッファを保存するまでファイルには反映されません。保存とは、バッファの内容をファイルにコピーすることを意味します。ファイルをビジットしていないバッファであっても、ある意味では
buffer-local write-contents-functions
フックの関数を用いて「保存」することが可能です。
この関数は、バッファが前回のアクセスまたは保存以降に変更されている場合、その内容を訪問済みファイルに保存します。それ以外の場合は、何も行いません。
save-buffer はバックアップファイルの作成を担当します。通常、backup-option は nil であり、save-buffer
はファイルにアクセスしてからの初回保存である場合にのみバックアップファイルを作成します。backup-option のその他の値は、別の状況でバックアップファイルの作成を要求します:
save-buffer関数は、次にバッファが保存される際にこのバージョンのファイルをバックアップ対象としてマークします。
save-buffer関数は保存前にファイルの以前のバージョンを無条件にバックアップします。
このコマンドは、変更された一部のファイル参照バッファを保存します。通常は、各バッファについてユーザーに確認を求めます。ただし、save-silently-p が nil
以外の場合は、ユーザーに確認することなくすべてのファイル参照バッファを保存します。
オプションの pred 引数は、どのバッファについて問い合わせるか(または save-silently-p が nil
でない場合にサイレントに保存するか)を制御する述語を提供します。pred が nil である場合、pred の代わりに save-some-buffers-default-predicate の値を使用することを意味します。結果が
nil である場合、ファイル訪問バッファについてのみ問い合わせることを意味します。t である場合は、特定のその他の非ファイルバッファ(バッファローカル値が nil ではなく buffer-offer-save
であるもの)の保存も提供することを意味します(バッファの削除 を参照)。非ファイルバッファの保存に ‘yes’ と指定したユーザーには、使用するファイル名の指定が求められます。save-buffers-kill-emacs 関数は、pred
に値 t を渡します。
述語が t でも nil
でもない場合、それは引数を取らない関数である必要があります。各バッファにおいて、そのバッファの保存を提案するかどうかを判定するためにこの関数が呼び出されます。特定のバッファで
nil 以外の値を返した場合、そのバッファの保存を提案することを意味します。
この関数は、現在のバッファをファイル filename
に書き込み、バッファがそのファイルを参照するように設定し、未変更としてマークします。その後、filename に基づいてバッファの名前を変更し、一意なバッファ名にするために、必要に応じて
‘<2>’
のような文字列を付加します。これらの処理の大部分は、set-visited-file-name(バッファファイル名 を参照)および save-buffer を呼び出すことで行われます。
confirm が nil
でない場合、既存のファイルを上書きする前に確認を求めることになります。対話操作では、ユーザーがプレフィックス引数を指定しない限り、確認が必要です。
filename がディレクトリ名(ディレクトリ名を参照)の場合、write-file にはディレクトリ filename
内で参照されているファイルの名前が使用されます。バッファがファイルを参照していない場合は、代わりにバッファ名が使用されます。
バッファを保存すると、複数のフックが実行されます。また、フォーマット変換も行われます(ファイルフォーマット変換を参照)。なお、以下で説明するこれらのフックはsave-bufferによってのみ実行され、バッファの内容をファイルに書き出す他のプリミティブや関数では実行されません。特に自動保存(自動保存を参照)では、これらのフックは実行されません。
この変数の値は、バッファを訪問済みファイルに書き出す前に呼び出される関数のリストです。これらの関数のいずれかがnil以外の値を返した場合、そのファイルは既に書き出されたものとみなされ、残りの関数は呼び出されず、ファイル書き込み用の通常のコードも実行されません。
write-file-functions 内の関数が nil
以外を返す場合、(適切であれば)バックアップファイルを作成する責任を負います。そのためには、以下のコードを実行してください。
(or buffer-backed-up (backup-buffer))
backup-buffer が返すファイルモードの値を保存し(nil でない場合)、それを書き込むファイルのモードビットの設定に利用するとよいでしょう。通常、save-buffer はこの処理を行います。バックアップファイルの作成を参照してください。
write-file-functions
のフック関数は、(必要に応じて)データのエンコードも担当します。適切な符号化方式と改行変換(Lispにおける符号化方式を参照)を選択し、エンコードを行い(明示的なエンコードとデコードを参照)、last-coding-system-used に使用した符号化方式を設定します(エンコードとI/Oを参照)。
このフックをバッファ内でローカルに設定した場合、それはファイル、あるいはバッファの内容が取得された方法に関連付けられているものとみなされます。そのため、この変数は永続的なローカル変数としてマークされ、メジャーモードを変更してもバッファローカルな値は変更されません。一方で、set-visited-file-name
を呼び出すとリセットされます。これが意図した動作でない場合は、代わりに write-contents-functions を使用することを検討してください。
これは通常のフックではありませんが、add-hook や remove-hook を使用してリストを操作できます。フックを参照してください。
これは write-file-functions
と同様に動作しますが、特定の訪問済みファイルやその位置ではなく、バッファの内容に関連するフックを対象としており、ファイルを全く訪問していないバッファに対して任意の保存処理を作成する際に利用できます。こうしたフックは通常、メジャーモードによって、この変数のバッファローカルなバインディングとして設定されます。この変数は、設定されるたびに自動的にバッファローカルになります。新しいメジャーモードに切り替えると常にこの変数はリセットされますが、set-visited-file-name を呼び出してもリセットされません。
このフック内の関数のいずれかが nil
以外を返す場合、そのファイルは既に書き込まれたものとみなされ、残りの関数および write-file-functions 内の関数は呼び出されません。
このフックを使用して、ファイルを参照しないバッファ(例えば特殊モードのバッファ)を保存する場合、関数が正常に保存できず nil 値を返した際、save-buffer
が続けてバッファを保存するファイルをユーザーに促す点に留意してください。これが望ましくない場合は、関数がエラーを発生させて失敗するようにすることを検討してください。
この通常のフックは、通常の手順で保存される場合でも、前述のフックのいずれかによって保存される場合でも、バッファが訪問済みファイルに保存される前に実行されます。例えば、copyright.el プログラムはこのフックを使用して、保存対象のファイルの著作権表示に現在の年が含まれていることを確認します。
この通常のフックは、バッファが visited ファイルに保存された後に実行されます。
この変数が nil 以外の場合、save-buffer
は、新しいファイルを本来のファイル名ではなく一時ファイル名で書き込んで保存し、エラーがないことが確認された後に意図したファイル名にリネームすることで、I/Oエラーを防ぎます。この手順により、ディスク容量不足などでファイルが無効になるといった問題を回避できます。
副作用として、バックアップは必然的にコピーによって作成されます。名前変更によるバックアップか、コピーによるバックアップか?を参照してください。しかし同時に、貴重なファイルを保存すると、保存先のファイルと他のファイル名との間のすべてのハードリンクが必ず切れてしまいます。
一部のモードでは、特定のバッファにおいて、この変数にnil以外のバッファローカルな値が設定されます。
This variable determines whether files may be written out that do not end with a newline. If the value of the variable is
t, then save-buffer
silently adds a newline at the end of the buffer whenever it does not
already end in one. If the value is visit, Emacs
adds a missing newline just after it visits the file. If the value is visit-save, Emacs adds a missing newline both on
visiting and on saving. For any other non-nil
value, save-buffer asks the user whether to add a
newline each time the case arises.
変数の値が nil の場合、save-buffer では改行が全く追加されません。nil
がデフォルト値ですが、一部のメジャーモードでは特定のバッファにおいてこれを t に設定しています。
関数 set-visited-file-name も参照してください(バッファファイル名 を参照)。