Как автоматически сохранять буферы, когда Emacs теряет фокус?

26

Недавно у меня был пользователь Sublime Text, который некоторое время пробовал Emacs, и он был заинтересован в том, чтобы получить такое же поведение самосохранения в Emacs.

По сути, он хотел, чтобы все буферы были сохранены всякий раз, когда кадр терял фокус (действительно сохраненный, а не просто резервный файл). Это включает в себя переключение окон на совершенно другое приложение.

Я не смог найти ни одного события, которое было вызвано при переключении на другое приложение. Есть ли такое событие или есть другой способ добиться того же поведения?

Обратите внимание, что решение, основанное на времени, не было удовлетворительным, и ни одно из них не было режимом автоматического резервного копирования по умолчанию. Он специально хотел, чтобы буферы были сохранены (как в save-buffer) для всех файлов.

b4hand
источник

Ответы:

29

К сожалению, это точное поведение невозможно в Emacs <= 24.3, но вы можете сохранить изменения окна / буфера, используя defadvice(как подробно описано в блоге bbatsov ):

(defadvice switch-to-buffer (before save-buffer-now activate)
  (when (and buffer-file-name (buffer-modified-p)) (save-buffer)))
(defadvice other-window (before other-window-now activate)
  (when (and buffer-file-name (buffer-modified-p)) (save-buffer)))

В Emacs 24.4 вы также сможете сэкономить на потере фокуса кадра благодаря новым хукам фокусировки : (add-hook 'focus-out-hook 'save-buffer)(для сохранения активного буфера) или (add-hook 'focus-out-hook (lambda () (save-some-buffers t)))(для сохранения всех открытых буферов).

shosti
источник
1
Не могли бы вы немного рассказать о defadviceверсии на случай, если сообщение в блоге выйдет из строя или что-то еще? Благодарность!
Тихон Джелвис
К сожалению, это решение сохраняет текущий видимый буфер, а не все буферы.
b4hand
1
@ b4hand: Извините, не понял, чего вы хотели. Ответ обновлен.
Шости
1
@shosti Кстати, спасибо, что нашли для меня ссылку на блог bbatsov. Я действительно нашел это решение раньше, но не смог найти его снова. Я собирался включить это в качестве одного из нерабочих решений в моем вопросе.
b4hand
2
Мне нравится делать это таким образом, чтобы избежать разрушения минибуфера (простите за форматирование): (add-hook 'focus-out-hook (lambda () (flet ((message (format &rest args) nil)) (save-some-buffers t))))
Андреас
6

Есть focus-autosave-modeсейчас. Это доступно через MELPA. Почему бы не дать ему возможность взломать за тебя?

Марк Карпов
источник
Привет, Как это работает? Я установил его, но он не работает.
Asme Just
@AsmeJust, я сейчас не пользуюсь, попробуйте спросить о его трекере здесь: github.com/vifon/focus-autosave-mode.el/issues
Марк Карпов
Вы в настоящее время используете альтернативу или что-то подобное?
Asme Just
Нет, сейчас я не использую ничего подобного.
Марк Карпов
Но вы все еще используете Emacs, верно?
Asme Just
3
(add-to-list 'focus-out-hook (lambda () (save-some-buffers t nil)))

Это сохранит все несохраненные буферы, посещающие файл, на emacs 24.4

Лукаш Грюнер
источник
2
Не используйте add-to-listна крючке, используйте add-hook. Ответ Шости уже содержит правильную форму этого фрагмента.
Жиль "ТАК - перестань быть злым"
1

Для странников, которые натыкаются на это, я использую эту форму:

(eval-when-compile (require 'cl-lib))
;; [...]
(add-hook 'focus-out-hook
  (lambda ()
    (cl-letf (((symbol-function 'message) #'format))
      (save-some-buffers t))))

Использование cl-letfпредотвращает раздражающие (No files need saving)сообщения от засорения вашей эхо-области.

PythonNut
источник