2012-10-05 48 views
0

在過去的幾年中,我一直在慢慢地增長Emacs配置,增加點點滴滴,添加新模式等等。大約一年前,一個問題開始經常發生:有些代碼將修改位設置在我的緩衝區。它實際上並沒有改變任何東西,它只是設置這個標誌。這是有點煩人,因爲每次我運行compilesave-some-buffers我必須手動放棄這些緩衝區中的更改重置修改的位。我怎樣才能找到有問題的代碼?誰在我的Emacs文件上設置修改標誌?

回答

3

如果真的是明確地將緩衝區設置爲修改而不更改任何內容,那麼我想它應該調用set-buffer-modified-p

我本來要建議debug-on-entryset-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))) 
4

相反菲爾斯,我希望修改後的p標誌不是由set-buffer-modified-p設置的,而是由緩衝區的實際更改設置的。這是可能的原因是Emacs將文本屬性視爲屬於緩衝區的內容,因此更改它們會設置修改的p標誌,即使在很多情況下,結果也是不可見的,即使它可見也是如此一般不會被用戶認爲是修改(用戶通常理解爲「保存緩衝區時會影響文件」)。

因此,大部分設置文本屬性的代碼都需要小心重置修改後的p標誌。做到這一點的最佳方式通常是將設置屬性的代碼包裝在with-silent-modification中。

單向嘗試追蹤罪魁禍首是試圖撤消修改(例如使用C-/),但當然,如果修改不可見,撤銷它也將不可見。因此,您可能需要查看C-h v buffer-undo-list RET這是用於跟蹤修改的內部數據。幸運的是,不僅是修改過的p集,還有撤銷列表,並且該列表將告訴您發生了什麼變化。例如,該列表可能看起來像(nil (nil face nil 12345708 . 12345713)),這意味着更改是將face屬性設置爲位置12345708和12345713之間的新值,並且該屬性的舊值爲nil(即上面的第3個nil)。有時用M-: (goto-char 12345708) RET查看受影響的職位就足以找出責任人。正在尋找M-: (get-text-property 12345708 'face) RET的時候,它給了你設定的新的價值,更有用。

+0

我完全同意 - 如果我的回答實際上顯示罪魁禍首,我會非常驚訝。不過,這似乎值得把它作爲一個可能的原因來消除;我想不出一個明顯的方式來調試替代:) – phils

+0

@phils你會走出很遠的一個肢體,不同意維護者! :) –

相關問題