How do I make emacs save its backup files alongside symbolic links?
I have files in some location:
location_a/doc.tex
location_a/doc.cls
...
I want to work on them in another directory via symbolic links:
work_directory/doc.tex -> location_a/doc.tex
work_directory/doc.cls -> location_a/doc.cls
work_directory/doc.pdf
work_directory/doc.log
...
However, when I run emacs doc.tex
in the work directory and do some editing, emacs creates a backup file at location_a/doc.tex~
. I want the backup file to be stored in the work directory, though. I don't want any new files created in location_a
.
How can I make emacs do that?
This is trickier than it seems it should be because backup-buffer
insists on chasing the links of the buffer file name before calling any backup file name construction machinery, such as make-backup-file-name-function
. The result is that Emacs allows no way to customize this behavior, short of redefining backup-buffer
, which is a fairly complicated piece of code.
A compromise solution I came up with is to install an "advice" around backup-buffer
that temporarily disables file-chase-links
while backup-buffer
is being evaluated. This allows the backup file to be in the directory where the symlink resides. However, it also causes Emacs to create the backup by renaming the original symlink, leaving one with work_directory/doc.tex~
being a symlink that points to location_a/doc.tex
! Fortunately, this is easy to prevent by setting backup-by-copying
to t
.
Here is the code. A word of warning: while I have tried it to verify that it works, I cannot guarantee that it will not have an undesirable side effect, like the above interference with the backup mechanism that required backup-by-copying
. However, it might also work just fine - just be careful when using it.
(require 'cl) ; for flet
(defadvice backup-buffer (around disable-chase-links)
(flet ((file-chase-links (file) file))
ad-do-it))
(ad-activate 'backup-buffer)
For the fun of it, let me describe a radically different approach, based on directory variables.
In short, you would put in your work-directory/
a file named .dir-locals.el
containing:
((nil . ((eval . (set (make-local-variable 'backup-directory-alist)
(list (cons "."
(file-relative-name
(file-name-directory (buffer-file-name))
(file-name-directory (file-truename
(buffer-file-name)))))))))))
What this does is abusing somewhat the backup-directory-alist
, and install a local version of it for all your files in work-directory/
. That local version will in turn make sure that any backup file is kept within work-directory
.
In order to achieve that, we need 2 things:
'(("." . "path/to/work-directory/"))
as the local value location_a/
The reason for the second point is that as noted elsewhere, the starting point of backup-buffer
is indeed the location of the actual file, once symlinks are resolved. And we can't simply put the absolute path without having backup files changing shape (in case of absolute path for the backup directory, the backup filenames encode the complete path, so that there is no collision)
Notes:
safe-local-variable-values
. Since it's a generic form, it's a one time job though (just hit "!" the first time you're asked about it) find-file-visit-truename
is set to nil, but I guess you wouldn't ask that question if that was not the case :) Pros of the approach:
Cons of the approach:
.dir-locals.el
in several places Also note that if you wanted a one-shot approach, you could make it much simpler, such as:
((nil . ((backup-directory-alist (("." . "../path/to/work-directory"))))))
where you actually compute the relative name yourself, once and for all.
链接地址: http://www.djcxy.com/p/38556.html上一篇: Emacs和符号链接