如何使emacs将其备份文件与符号链接一起保存?

如何使emacs将其备份文件与符号链接一起保存?,emacs,Emacs,我在某些位置有文件: location_a/doc.tex location_a/doc.cls ... 我想通过符号链接在另一个目录中处理它们: work_directory/doc.tex -> location_a/doc.tex work_directory/doc.cls -> location_a/doc.cls work_directory/doc.pdf work_directory/doc.log ... 但是,当我在工作目录中运行emacs doc.tex并进

我在某些位置有文件:

location_a/doc.tex
location_a/doc.cls
...
我想通过符号链接在另一个目录中处理它们:

work_directory/doc.tex -> location_a/doc.tex
work_directory/doc.cls -> location_a/doc.cls
work_directory/doc.pdf
work_directory/doc.log
...
但是,当我在工作目录中运行
emacs doc.tex
并进行一些编辑时,emacs会在
位置\u a/doc.tex
创建一个备份文件。不过,我希望备份文件存储在工作目录中。我不希望在
位置\u a
中创建任何新文件


如何使emacs做到这一点?

这比看起来更为棘手,因为
备份缓冲区
坚持在调用任何备份文件名施工机械(如
生成备份文件名功能
)之前跟踪缓冲区文件名的链接。结果是,除了重新定义备份缓冲区(这是一段相当复杂的代码)之外,Emacs无法自定义此行为

我提出的一个折衷解决方案是在
备份缓冲区
周围安装一个“建议”,在评估
备份缓冲区
时临时禁用
文件跟踪链接
。这允许备份文件位于符号链接所在的目录中。但是,它也会使Emacs通过重命名原始符号链接来创建备份,将
工作目录/doc.tex
作为指向
位置/doc.tex
!幸运的是,通过将
复制到
t
来设置
备份,这很容易防止

这是代码。警告一句:虽然我已经尝试验证它是否有效,但我不能保证它不会产生不良的副作用,如上面对备份机制的干扰,该机制要求通过复制进行备份。然而,它也可以很好地工作——只是在使用它时要小心

(require 'cl)  ; for flet
(defadvice backup-buffer (around disable-chase-links)
  (flet ((file-chase-links (file) file))
    ad-do-it))
(ad-activate 'backup-buffer)

这比看起来更为棘手,因为
备份缓冲区
坚持在调用任何备份文件名施工机械(如
使备份文件名功能
)之前跟踪缓冲区文件名的链接。结果是,除了重新定义备份缓冲区(这是一段相当复杂的代码)之外,Emacs无法自定义此行为

我提出的一个折衷解决方案是在
备份缓冲区
周围安装一个“建议”,在评估
备份缓冲区
时临时禁用
文件跟踪链接
。这允许备份文件位于符号链接所在的目录中。但是,它也会使Emacs通过重命名原始符号链接来创建备份,将
工作目录/doc.tex
作为指向
位置/doc.tex
!幸运的是,通过将
复制到
t
来设置
备份,这很容易防止

这是代码。警告一句:虽然我已经尝试验证它是否有效,但我不能保证它不会产生不良的副作用,如上面对备份机制的干扰,该机制要求通过复制进行备份。然而,它也可以很好地工作——只是在使用它时要小心

(require 'cl)  ; for flet
(defadvice backup-buffer (around disable-chase-links)
  (flet ((file-chase-links (file) file))
    ad-do-it))
(ad-activate 'backup-buffer)

为了好玩,让我描述一种完全不同的方法,基于目录变量

简言之,您将在
工作目录中放入一个名为
.dir locals.el
的文件,其中包含:

((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)))))))))))
这在某种程度上滥用了备份目录
,并安装了本地版本 在
工作目录/
中的所有文件中使用它。本地版本将确保所有备份文件都保存在
工作目录中

为了实现这一目标,我们需要两件事:

  • 将类似于
    ”((“.path/to/work directory/”)的内容作为本地值
  • 确保此路径相对于
    位置\u a/
第二点的原因是,如其他地方所述,
backup buffer
的起点实际上是解决符号链接后实际文件的位置。我们不能简单地放置绝对路径,而不改变备份文件的形状(对于备份目录的绝对路径,备份文件名对完整路径进行编码,这样就不会发生冲突)

注:

  • 您需要确保特定的局部变量记录在
    安全局部变量值中。因为它是一种通用形式,所以它是一次性的工作(第一次被问及它时只需点击“!”)
  • 这假设
    find file visit truename
    设置为nil,但如果不是这样,我想您不会问这个问题:)
该方法的优点:

  • 不需要建议(这总是一件好事)
  • 虽然它假定您的Emacs支持目录变量,但它还是相当可移植的
  • 您可以保持灵活性,仅在需要时才将其放置到位
该方法的缺点:

  • 显然,您可能需要在多个地方复制
    .dir locals.el
还请注意,如果您希望采用一次性方法,可以使其更简单,例如:

((nil . ((backup-directory-alist (("." . "../path/to/work-directory"))))))

实际上,您可以自己计算相对名称,一劳永逸。

为了好玩,让我描述一种基于目录变量的完全不同的方法

简言之,您将在
工作目录中放入一个名为
.dir locals.el
的文件,其中包含:

((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)))))))))))
这在某种程度上滥用了备份目录
,并安装了本地版本 在
工作目录/
中的所有文件中使用它。本地版本将确保所有备份文件都保存在
工作目录中

为了实现这一目标,我们需要两件事:

  • 将类似于
    ”((“.path/to/work directory/”)的内容作为本地值
  • 确保此路径相对于
    位置_