29

I recently had a Sublime Text user try out Emacs for a while, and he was interested in getting the same auto-save behavior in Emacs.

Basically, he wanted all buffers to be saved whenever the frame lost focus (really saved, not just backed-up). This includes when switching windows to a completely different application.

I could not find any event that was triggered when switching to a different application. Is there such an event or is there another way to achieve the same behavior?

Note a time based solution was not satisfactory, and neither was the default auto backup behavior. He specifically wanted the buffers to be saved (as in save-buffer) for all files.

b4hand
  • 1,995
  • 1
  • 19
  • 31

4 Answers4

33

Unfortunately, this exact behavior isn't possible in Emacs <= 24.3, but you can save on window/buffer change using defadvice (as detailed on bbatsov's blog):

(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)))

In Emacs 24.4, you will also be able to save on frame focus loss thanks to the new focus hooks: (add-hook 'focus-out-hook 'save-buffer) (to save the active buffer) or (add-hook 'focus-out-hook (lambda () (save-some-buffers t))) (to save all open buffers).

skrat
  • 133
  • 6
shosti
  • 5,048
  • 26
  • 33
  • 1
    Could you expand a bit on the `defadvice` version, in case the blog post goes down or something? Thanks! – Tikhon Jelvis Sep 25 '14 at 18:35
  • Unfortunately, that solution on saves the currently visible buffer, not *all* buffers. – b4hand Sep 25 '14 at 18:45
  • 1
    @b4hand: Sorry, didn't realize that's what you wanted. Answer updated. – shosti Sep 25 '14 at 18:47
  • 1
    @shosti By the way, thanks for finding that link to bbatsov's blog for me. I had actually found that solution before, but couldn't find it again. I was going to include that as one of the non-working solutions in my question. – b4hand Sep 25 '14 at 20:24
  • 3
    I like doing it this way to avoid trashing the minibuffer (pardon the formatting): ```(add-hook 'focus-out-hook (lambda () (flet ((message (format &rest args) nil)) (save-some-buffers t)))) ``` – Andreas Oct 16 '14 at 06:19
6

There is focus-autosave-mode now. It's available via MELPA. Why not give it a chance to do the hacking for you‽

Mark Karpov
  • 4,893
  • 1
  • 24
  • 53
4
(add-to-list 'focus-out-hook (lambda () (save-some-buffers t nil)))

This will save all unsaved buffers visiting file, on emacs 24.4

Łukasz Gruner
  • 1,008
  • 8
  • 16
1

For wanderers who stumble on this, I use this form:

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

The use of cl-letf keeps the annoying (No files need saving) messages from clogging your echo area.

PythonNut
  • 10,243
  • 2
  • 29
  • 75