Next: , Previous: Visiting Files, Up: Files


25.2 Saving Buffers

When you edit a file in Emacs, you are actually working on a buffer that is visiting that file—that is, the contents of the file are copied into the buffer and the copy is what you edit. Changes to the buffer do not change the file until you save the buffer, which means copying the contents of the buffer into the file.

— Command: save-buffer &optional backup-option

This function saves the contents of the current buffer in its visited file if the buffer has been modified since it was last visited or saved. Otherwise it does nothing.

save-buffer is responsible for making backup files. Normally, backup-option is nil, and save-buffer makes a backup file only if this is the first save since visiting the file. Other values for backup-option request the making of backup files in other circumstances:

— Command: save-some-buffers &optional save-silently-p pred

This command saves some modified file-visiting buffers. Normally it asks the user about each buffer. But if save-silently-p is non-nil, it saves all the file-visiting buffers without querying the user.

The optional pred argument controls which buffers to ask about. If it is nil, that means to ask only about file-visiting buffers. If it is t, that means also offer to save certain other non-file buffers—those that have a non-nil buffer-local value of buffer-offer-save. (A user who says ‘yes’ to saving a non-file buffer is asked to specify the file name to use.) The save-buffers-kill-emacs function passes the value t for pred.

If pred is neither t nor nil, then it should be a function of no arguments. It will be called in each buffer to decide whether to offer to save that buffer. If it returns a non-nil value in a certain buffer, that means do offer to save that buffer.

— Command: write-file filename &optional confirm

This function writes the current buffer into file filename, makes the buffer visit that file, and marks it not modified. Then it renames the buffer based on filename, appending a string like ‘<2>’ if necessary to make a unique buffer name. It does most of this work by calling set-visited-file-name (see Buffer File Name) and save-buffer.

If confirm is non-nil, that means to ask for confirmation before overwriting an existing file.

Saving a buffer runs several hooks. It also performs format conversion (see Format Conversion), and may save text properties in “annotations” (see Saving Properties).

— Variable: write-file-hooks

The value of this variable is a list of functions to be called before writing out a buffer to its visited file. If one of them returns non-nil, the file is considered already written and the rest of the functions are not called, nor is the usual code for writing the file executed.

If a function in write-file-hooks returns non-nil, it is responsible for making a backup file (if that is appropriate). To do so, execute the following code:

          (or buffer-backed-up (backup-buffer))
     

You might wish to save the file modes value returned by backup-buffer and use that to set the mode bits of the file that you write. This is what save-buffer normally does.

The hook functions in write-file-hooks are also responsible for encoding the data (if desired): they must choose a suitable coding system (see Lisp and Coding Systems), perform the encoding (see Explicit Encoding), and set last-coding-system-used to the coding system that was used (see Encoding and I/O).

Do not make this variable buffer-local. To set up buffer-specific hook functions, use write-contents-hooks instead.

Even though this is not a normal hook, you can use add-hook and remove-hook to manipulate the list. See Hooks.

— Variable: local-write-file-hooks

This works just like write-file-hooks, but it is intended to be made buffer-local in particular buffers, and used for hooks that pertain to the file name or the way the buffer contents were obtained.

The variable is marked as a permanent local, so that changing the major mode does not alter a buffer-local value. This is convenient for packages that read “file” contents in special ways, and set up hooks to save the data in a corresponding way.

— Variable: write-contents-hooks

This works just like write-file-hooks, but it is intended for hooks that pertain to the contents of the file, as opposed to hooks that pertain to where the file came from. Such hooks are usually set up by major modes, as buffer-local bindings for this variable.

This variable automatically becomes buffer-local whenever it is set; switching to a new major mode always resets this variable. When you use add-hooks to add an element to this hook, you should not specify a non-nil local argument, since this variable is used only buffer-locally.

— Variable: after-save-hook

This normal hook runs after a buffer has been saved in its visited file. One use of this hook is in Fast Lock mode; it uses this hook to save the highlighting information in a cache file.

— Variable: file-precious-flag

If this variable is non-nil, then save-buffer protects against I/O errors while saving by writing the new file to a temporary name instead of the name it is supposed to have, and then renaming it to the intended name after it is clear there are no errors. This procedure prevents problems such as a lack of disk space from resulting in an invalid file.

As a side effect, backups are necessarily made by copying. See Rename or Copy. Yet, at the same time, saving a precious file always breaks all hard links between the file you save and other file names.

Some modes give this variable a non-nil buffer-local value in particular buffers.

— User Option: require-final-newline

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 file whenever the buffer being saved does not already end in one. If the value of the variable is non-nil, but not t, then save-buffer asks the user whether to add a newline each time the case arises.

If the value of the variable is nil, then save-buffer doesn't add newlines at all. nil is the default value, but a few major modes set it to t in particular buffers.

See also the function set-visited-file-name (see Buffer File Name).