谁在Emacs中的文件上设置修改后的标志?

时间:2012-10-05 09:37:15

标签: emacs elisp

在过去的几年中,我一直在慢慢增长我的Emacs配置,添加点点滴滴,添加新模式等。大约一年前,一个问题开始经常发生:一些代码设置修改后的位我的缓冲区。它实际上没有改变任何东西,它只是设置这个标志。有点烦人,因为每次运行compilesave-some-buffers时,我必须手动丢弃这些缓冲区中的更改以重置修改后的位。如何找到有问题的代码?

2 个答案:

答案 0 :(得分:4)

与phils相反,我希望你的modified -p标志不是由set-buffer-modified-p设置的,而是由缓冲区的实际更改设置的。这是可能的原因是文本属性被Emacs视为属于缓冲区的内容,因此更改它们会设置modified-p标志,甚至在许多情况下结果是不可见的,即使它是可见的,它也是通常不被用户视为修改(用户通常理解为“当我保存缓冲区时会影响文件”)。

因此,设置text-properties的大多数代码都需要注意以后重置modified-p标志。最好的方法是将包含设置属性的代码包装在with-silent-modification

尝试追踪罪魁祸首的一种方法是尝试撤消修改(例如使用C-/),但当然,如果修改不可见,撤消它也将不可见。因此,您可能希望查看C-h v buffer-undo-list RET,这是用于跟踪修改的内部数据。幸运的是,不仅是modified-p设置,还有undo-list,该列表将告诉你改变了什么。例如,该列表可能看起来像(nil (nil face nil 12345708 . 12345713)),这意味着更改是将face属性设置为位置12345708和12345713之间的新值,并且该属性的旧值为{{1} (这是上面的第3个nil)。有时用nil查看受影响的位置就足以找出应该责怪谁。 Othertimes查看M-: (goto-char 12345708) RET,它为您提供了设置的新值,更有用。

答案 1 :(得分:3)

如果某些内容确实明确地将缓冲区设置为已修改而没有更改任何内容,那么我猜它应该调用set-buffer-modified-p

我原本打算为debug-on-entry建议set-buffer-modified-p,但粗略测试表明这种情况一般都具有极大的破坏性,因此您可以通过这种方式指出您感兴趣的缓冲区:

(defvar my-debug-set-buffer-modified-p-buffers nil)

(defadvice set-buffer-modified-p
  (before my-debug-set-buffer-modified-p-advice)
  (when (memq (current-buffer) my-debug-set-buffer-modified-p-buffers)
    (debug)))
(ad-activate 'set-buffer-modified-p)

(defun my-debug-set-buffer-modified-p (buffer)
  (interactive (list (current-buffer)))
  (if (memq buffer my-debug-set-buffer-modified-p-buffers)
      (progn (setq my-debug-set-buffer-modified-p-buffers
                   (delq buffer my-debug-set-buffer-modified-p-buffers))
             (message "Disabled for %s" buffer))
    (add-to-list 'my-debug-set-buffer-modified-p-buffers buffer)
    (message "Enabled for %s" buffer)))