Emacs Lisp has two ways to work with a file. It can visit the file in a buffer, which is what editing commands do, or it can read and write the bytes directly with functions such as insert-file-contents and write-region. This page lists both, then the functions for file names, attributes, directories, copying and temporary files, and the mechanism that lets all of them work on remote files.
Visiting and saving
| Function | Use |
|---|---|
find-file-noselect FILENAME &optional NOWARN RAWFILE WILDCARDS | visit a file and return its buffer without showing it. If the file is already visited, the existing buffer is returned. |
find-file-literally | visit a file with no decoding, no format conversion and no hooks (a command) |
save-buffer | save the current buffer to its file (a command; it makes the backup first) |
write-file | save under another name and visit that |
insert-file-contents FILENAME &optional VISIT BEG END REPLACE | insert the contents after point and return (ABSOLUTE-NAME LENGTH). Point stays before the inserted text. A non-nil VISIT marks the buffer as visiting the file. REPLACE non-nil replaces the buffer text with the minimum change; the value if-regular (Emacs 30) erases the buffer, instead of signalling an error, when the file is not a regular file. |
insert-file-contents-literally | the same with no decoding |
write-region START END FILENAME &optional APPEND VISIT LOCKNAME MUSTBENEW | write a part of the buffer, or a string when START is a string. START nil means the whole buffer. APPEND adds to the file; a number gives an offset. MUSTBENEW excl signals an error if the file exists. |
with-temp-file FILE &rest BODY | macro: run BODY in a temporary buffer and write the buffer to FILE afterwards |
with-temp-buffer | macro for reading: (with-temp-buffer (insert-file-contents file) (buffer-string)) |
(defun my-read-file (file)
(with-temp-buffer
(insert-file-contents file)
(buffer-string)))
(with-temp-file "/tmp/out.txt"
(insert "hello\n"))
Visiting a file runs hooks. find-file-hook is run after the file is read and its mode chosen. Before saving, before-save-hook runs, and then the abnormal hook write-file-functions: if a function in it returns non-nil, it is taken to have written the file and the rest is skipped. after-save-hook runs last. The mode of the buffer is chosen from auto-mode-alist (Commands and modes).
Backups, auto-save and locks
| Variable | Effect |
|---|---|
make-backup-files | non-nil makes a backup, NAME~, the first time a buffer is saved |
backup-directory-alist | an alist of (REGEXP . DIRECTORY) that moves backups of matching files to another directory |
version-control | t makes numbered backups (NAME.~1~), never makes plain ones, nil follows the existing files |
delete-old-versions, kept-old-versions, kept-new-versions | how many numbered backups to keep |
backup-by-copying | copy instead of renaming the original |
auto-save-default | whether visited files are auto-saved to #NAME#; auto-save-visited-mode saves into the real file instead |
create-lockfiles | whether Emacs writes a lock, a symbolic link named .#NAME, while a buffer is modified; lock-buffer and unlock-buffer do it explicitly |
File names
| Function | Result for "/home/ann/notes.tar.gz" unless said |
|---|---|
expand-file-name NAME &optional DIR | an absolute name. A leading ~ is the home directory, ~user that user’s, and a relative name is taken from DIR or default-directory. . and .. are resolved, symbolic links are not. |
file-name-directory | "/home/ann/"; nil when there is no directory part |
file-name-nondirectory | "notes.tar.gz" |
file-name-extension | "gz"; with a second argument t, ".gz" |
file-name-sans-extension | "/home/ann/notes.tar" |
file-name-base | "notes.tar", the name without directory and extension |
file-name-with-extension FILE EXT | replace or add an extension (Emacs 28); the dot in EXT is optional |
file-name-concat DIR &rest COMPONENTS | join with / where needed; empty and nil parts are ignored (Emacs 28) |
file-relative-name FILE &optional DIR | the name relative to DIR |
abbreviate-file-name | shorten with ~ and directory-abbrev-alist |
directory-file-name, file-name-as-directory | remove, or add, the trailing slash |
file-truename | the true name, with all symbolic links resolved |
file-name-absolute-p | true for names that begin with / or ~ |
The variable default-directory is buffer-local and holds the directory used for relative names. user-emacs-directory is the directory of the user’s Emacs files, and locate-user-emacs-file gives a name inside it (or in the older location, if the file exists there). temporary-file-directory is where temporary files are made.
Quoting and remote names
A name that begins with /: is quoted: the rest is taken as a literal local name, even if it looks like a remote name or a handler pattern. file-name-quote adds the prefix and file-name-unquote removes it. Each primitive calls a file name handler first when the name matches a regular expression in file-name-handler-alist, an alist of (REGEXP . HANDLER). TRAMP uses this for names such as /ssh:user@host:/path: the handler does the work over the connection. This is why code that should work remotely uses process-file and not call-process (Processes).
| Function | Use |
|---|---|
file-remote-p FILE &optional IDENTIFICATION | a string that identifies the remote part, or nil for a local name |
file-local-name FILE | the name on the remote machine, without the prefix |
find-file-name-handler | the handler for a name and an operation |
file-name-case-insensitive-p | whether names in the directory ignore case |
File attributes
| Function | Use |
|---|---|
file-exists-p | the name exists, whatever it is |
file-readable-p, file-writable-p, file-executable-p | access for the current user |
file-directory-p, file-regular-p | a directory, or a plain file |
file-symlink-p | the target of a symbolic link as a string, otherwise nil |
file-attributes FILE &optional ID-FORMAT | a list: type, link count, user, group, access time, modification time, status change time, size, mode string, a flag, inode, device |
file-attribute-type, -link-number, -user-id, -group-id, -access-time, -modification-time, -status-change-time, -size, -modes, -inode-number, -device-number | accessors for the list; the size of a file is (file-attribute-size (file-attributes f)) |
file-modes, set-file-modes | read or set the permission bits as an integer, for example #o644 |
file-newer-than-file-p A B | true when A is newer than B, or B does not exist |
Directories
| Function | Use |
|---|---|
directory-files DIR &optional FULL MATCH NOSORT COUNT | the names in a directory, sorted; . and .. are included unless MATCH excludes them |
directory-files-recursively DIR REGEXP &optional INCLUDE-DIRECTORIES PREDICATE FOLLOW-SYMLINKS | all files below DIR whose names match REGEXP, as full names |
file-expand-wildcards PATTERN &optional FULL | expand a shell-style pattern such as "~/src/*.el" |
make-directory DIR &optional PARENTS | create; a non-nil PARENTS also creates missing parents |
delete-directory DIR &optional RECURSIVE TRASH | remove; the directory must be empty unless RECURSIVE |
directory-empty-p | true when it has no files (Emacs 28) |
make-temp-file PREFIX &optional DIR-FLAG SUFFIX TEXT | create a new file, or a directory when DIR-FLAG is non-nil, with a unique name in temporary-file-directory, and return its name |
make-nearby-temp-file | the same, in a directory on the same machine as default-directory |
(directory-files-recursively "~/.emacs.d" "\\.el\\'")
(make-temp-file "demo-" nil ".txt" "first line\n")
Copying, renaming and deleting
| Function | Use |
|---|---|
copy-file OLD NEW &optional OK-IF-EXISTS KEEP-TIME PRESERVE-UID-GID PRESERVE-PERMISSIONS | copy; an existing NEW is an error unless OK-IF-EXISTS is non-nil (a number asks) |
copy-directory | copy a directory, optionally with its contents |
rename-file OLD NEW &optional OK-IF-EXISTS | rename or move; it copies and deletes across file systems |
delete-file FILE &optional TRASH | delete; TRASH moves it to the system trash when delete-by-moving-to-trash allows |
add-name-to-file OLD NEW | make a hard link |
make-symbolic-link TARGET LINKNAME | make a symbolic link |
Finding files and watching them
| Function | Use |
|---|---|
locate-library NAME | the file that load would load (Packages and autoloads) |
locate-file FILENAME PATH &optional SUFFIXES PREDICATE | search a list of directories, trying each suffix |
executable-find COMMAND | the full name of a program found on exec-path |
locate-dominating-file FILE NAME | the nearest parent directory that contains NAME |
file-notify-add-watch FILE FLAGS CALLBACK | watch a file or directory. FLAGS is a list of change, attribute-change. The callback receives an event (DESCRIPTOR ACTION FILE [FILE1]), where ACTION is created, deleted, changed, renamed and so on. file-notify-rm-watch stops it. |
Coding systems of files
When Emacs reads a file it decodes the bytes, and it encodes again on writing. Binding coding-system-for-read or coding-system-for-write to a coding system, such as utf-8-unix or binary, forces the choice for one operation. This is the usual way to read or write bytes:
(let ((coding-system-for-read 'binary))
(insert-file-contents-literally "photo.jpg"))
The variable buffer-file-coding-system is the coding used to save a buffer. A format (format-alist) is a second conversion, applied after decoding, for files such as enriched text.
Not described
Known, not yet covered
- Reference: the file-name handler operations (the list of primitives that a handler can intercept) and TRAMP’s own methods and syntax are not described.
- Reference: the rules for choosing the coding system (
file-coding-system-alist, detection and the coding cookie) are covered only for the cookie, on File structure. - Reference: file locks (the format of the lock file), the form of auto-save file names,
auto-mode-alist(see Commands and modes), file modes of newly created files (default-file-modes,set-file-times) and file-local variables are named only.
See also
- Processes –
process-fileand remote programs - Minibuffer –
read-file-name - Buffers and text – the buffer that a file is read into
- Files – the manual chapter
- File Names – the manual section on name functions