過去数年の間に、私はEmacs構成をゆっくりと成長させ、ビットを追加し、新しいモードを追加しました。約1年前、問題が定期的に発生し始めました。コードによって、変更されたビットがバッファーに設定されています。実際には何も変更せず、このフラグを設定するだけです。実行するたびに、compile
またはsave-some-buffers
変更されたビットをリセットするためにこれらのバッファの変更を手動で破棄する必要があるため、少し面倒です。問題のあるコードを見つけるにはどうすればよいですか?
2 に答える
philsとは異なり、modified-pフラグはset-buffer-modified-p
、ではなく、バッファへの実際の変更によって設定されると思います。これが可能な理由は、text-propertiesがEmacsによってバッファーのコンテンツに属するものとして扱われるため、それらを変更すると、modified-pフラグが設定されます。多くの場合、結果は非表示であり、表示されていても表示されます。通常、ユーザーは変更として認識しません(ユーザーは通常、「バッファーを保存するときにファイルに影響を与える」などのように理解します)。
したがって、text-propertiesを設定するコードのほとんどは、後でmodified-pフラグをリセットするように注意する必要があります。これを行う最良の方法は、通常、プロパティを設定するコードを。内にラップすることですwith-silent-modification
。
犯人を突き止める1つの方法は、変更を元に戻すことです(たとえば、を使用C-/
)。ただし、もちろん、変更が表示されていない場合、元に戻すことも表示されません。したがって、代わりC-h v buffer-undo-list RET
に、変更を追跡するために使用される内部データを確認することをお勧めします。運が良ければ、modified-pセットだけでなく、undo-listも設定され、そのリストから何が変更されたかがわかります。たとえば、そのリストは次のようになります(nil (nil face nil 12345708 . 12345713))
。これは、変更によってface
プロパティが位置12345708と12345713の間の新しい値に設定され、そのプロパティの古い値がnil
(上記の3番目nil
)であったことを意味します。影響を受けた位置をで見るだけで、M-: (goto-char 12345708) RET
誰が責任を負うべきかを理解できる場合があります。時々見てM-: (get-text-property 12345708 'face) RET
設定された新しい値を提供する、はより便利です。
何も変更せずにバッファを変更済みとして明示的に設定している場合は、 を呼び出す必要があると思います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)))