"Различайся, спасай или убивай" при уничтожении буферов в Emacs
При попытке уничтожить буфер, содержащий изменения в Emacs, отображается сообщение: "Буфер [буфер] изменен; уничтожить в любом случае? (Да или нет)".
Вместо этого я хотел бы, чтобы Emacs спросил меня, хочу ли я: 1. Просмотреть различия в том, что изменилось, 2. Сохранить буфер, 3. Убить буфер.
Как?
2 ответа
Ответ заключается в использовании совета, потому что перехваты обычно запускаются, когда уничтожение буферов запускается после запроса "изменение буфера", который вы хотите изменить.
Следующий совет делает то, что вы хотите (я думаю). Пара заметок:
- При запуске diff исходный буфер помечается как неизмененный, но вам действительно нужно его сохранить.
- Другой буфер в diff не удаляется
(defadvice kill-buffer (around my-kill-buffer-check activate)
"Prompt when a buffer is about to be killed."
(let* ((buffer-file-name (buffer-file-name))
backup-file)
;; see 'backup-buffer
(if (and (buffer-modified-p)
buffer-file-name
(file-exists-p buffer-file-name)
(setq backup-file (car (find-backup-file-name buffer-file-name))))
(let ((answer (completing-read (format "Buffer modified %s, (d)iff, (s)ave, (k)ill? " (buffer-name))
'("d" "s" "k") nil t)))
(cond ((equal answer "d")
(set-buffer-modified-p nil)
(let ((orig-buffer (current-buffer))
(file-to-diff (if (file-newer-than-file-p buffer-file-name backup-file)
buffer-file-name
backup-file)))
(set-buffer (get-buffer-create (format "%s last-revision" (file-name-nondirectory file-to-diff))))
(buffer-disable-undo)
(insert-file-contents file-to-diff nil nil nil t)
(set-buffer-modified-p nil)
(setq buffer-read-only t)
(ediff-buffers (current-buffer) orig-buffer)))
((equal answer "k")
(set-buffer-modified-p nil)
ad-do-it)
(t
(save-buffer)
ad-do-it)))
ad-do-it)))
Вы захотите написать некоторый код для включения в списки kill-buffer-hooks и write-file-functions. Концептуально, что вы хотите сделать, это
- проверить, был ли изменен буфер
- показать свое сообщение и получить ответ, и делать то, что просили
- затем очистите измененный флаг, чтобы обычный kill-buffer не возвращался, и повторите запрос.