Emacs auto-save on switch buffer
Question
Call me lame, but I'm tired of my subconscious C-x C-s
nervous twitch. I am switching buffers often enough and I think I would like to save a certain buffer as soon as I switch to another. I have not had the time yet to learn Emacs-Lisp basics.
Any hints on how to do this, or better solutions?
(On a related note, I found an autosave workaround that can save the current buffer as soon as you are idle for a given amount of time.)
Solution
To expand on Seth's answer, I'd do this:
(defadvice switch-to-buffer (before save-buffer-now activate)
(when buffer-file-name (save-buffer)))
(defadvice other-window (before other-window-now activate)
(when buffer-file-name (save-buffer)))
(defadvice other-frame (before other-frame-now activate)
(when buffer-file-name (save-buffer)))
The check for buffer-file-name
avoids saving buffers w/out files. You need to figure out all the entry points you use for switching buffers that you care about (I'd also advise other-window
).
OTHER TIPS
I'm kind of new to emacs lisp myself but this works in my testing:
(defadvice switch-to-buffer (before save-buffer-now)
(save-buffer))
(ad-activate 'switch-to-buffer)
It's kind of annoying though because it's called after EVERY buffer (like scratch). So, consider this answer a hint.
When you want to disable it, you'll need to call:
(ad-disable-advice 'switch-to-buffer 'before 'save-buffer-now)
(ad-activate 'switch-to-buffer)
A couple of ideas.
First, if you find yourself invoking a command like save with a sufficiently high frequency, you might consider a shorter key binding for the command. For example, I also found myself having the same "twitch," so now I use f2
instead of C-x C-s
for saving edits.
The function that I bind to f2
saves every unsaved buffer unconditionally. You might find it useful:
(defun force-save-all ()
"Unconditionally saves all unsaved buffers."
(interactive)
(save-some-buffers t))
(global-set-key [f2] 'force-save-all)
Now, on to the main issue. You could try something like this (notice that force-save-all
is called):
(defun my-switch-to-buffer (buffer)
(interactive (list (read-buffer "Switch to buffer: " (cadr buffer-name-history) nil)))
(force-save-all)
(switch-to-buffer buffer))
(global-set-key "\C-xb" 'my-switch-to-buffer)
Of course, you could also bind the switch buffer functionality to another key, like a function key, so that it's a one press operation.
I thought that @seth had a great idea about using advice, but I noticed that the ELisp manual suggests that advice not be used for key bindings. I'm not quite sure why this is the case, but that's what the manual suggests FYI.