You can implement special handling for a class of file names. You must supply a regular expression to define the class of names (all those which match the regular expression), plus a handler that implements all the primitive Emacs file operations for file names that do match.
The value of file-name-handler-alist
is a list of handlers,
together with regular expressions that decide when to apply each
handler. Each element has the form (regexp
. handler)
. If a file name matches regexp, then all work
on that file is done by calling handler.
All the Emacs primitives for file access and file name transformation
check the given file name against file-name-handler-alist
, and
call handler to do the work if appropriate. The first argument
given to handler is the name of the primitive; the remaining
arguments are the arguments that were passed to that primitive. (The
first of these arguments is typically the file name itself.) For
example, if you do this:
(file-exists-p filename)
and filename has handler handler, then handler is called like this:
(funcall handler 'file-exists-p filename)
Here are the primitives that you can handle in this way:
add-name-to-file
,copy-file
,delete-directory
,delete-file
,directory-file-name
,directory-files
,dired-compress-file
,dired-uncache
,expand-file-name
,file-accessible-directory-p
,file-attributes
,file-directory-p
,file-executable-p
,file-exists-p
,file-local-copy
,file-modes
,file-name-all-completions
,file-name-as-directory
,file-name-completion
,file-name-directory
,file-name-nondirectory
,file-name-sans-versions
,file-newer-than-file-p
,file-readable-p
,file-symlink-p
,file-writable-p
,insert-directory
,insert-file-contents
,load
,make-directory
,make-symbolic-link
,rename-file
,set-file-modes
,set-visited-file-modtime
,unhandled-file-name-directory
,verify-visited-file-modtime
,write-region
.
The handler function must handle all of the above operations, and possibly others to be added in the future. Therefore, it should always reinvoke the ordinary Lisp primitive when it receives an operation it does not recognize. Here's one way to do this:
(defun my-file-handler (operation &rest args) ;; First check for the specific operations ;; that we have special handling for. (cond ((eq operation 'insert-file-contents) ...) ((eq operation 'write-region) ...) ... ;; Handle any operation we don't know about. (t (let (file-name-handler-alist) (apply operation args)))))
The function file-local-copy
copies file filename to the
local site, if it isn't there already. If filename specifies a
"magic" file name which programs outside Emacs cannot directly read or
write, this copies the contents to an ordinary file and returns that
file's name.
If filename is an ordinary file name, not magic, then this function
does nothing and returns nil
.
The function unhandled-file-name-directory
is used to get a
non-magic directory name from an arbitrary file name. It uses the
directory part of the specified file name if that is not magic.
Otherwise, it asks the file name's handler what to do.