Emacs auto-save
[The code you’re looking for is at the end of the post :)]
Following up on my previous post on auto-save…
GNU Emacs is one of the oldest programs existing, and it has had an auto-save-mode for god knows how many decades now, but it doesn’t quite do what I want. Like this other user, I was annoyed that it saves to a different file (/dir/filename
is saved to /dir/#filename#
while the file is being edited), and still requires you to save the file when you quit Emacs or close the buffer, thus making it not auto-save at all, but merely a backup facility guarding against Emacs crashes.
Someone at Emacswiki’s AutoSave page suggested M-x run-with-idle-timer RET SECONDS RET save-buffer RET
, but I tried that for a while and it is really not a good idea; it tries to save every buffer, even those not associated with files, like completion buffers. I considered trying to figure out how to make it run on only buffers associated with files, but then I realised that it would probably be better to modify the built-in auto-save mechanism do what I want, instead of rolling my own new one, because that was smart about things like this.
C-h f auto-save-mode
is actually quite sparse compared to the usual Emacs documentation. Anyway, I figured out with a bit of looking in the source files that I could edit make-auto-save-file-name
function to modify what filename it used for auto-saves. On a bit more thought, I realised that it is usually never necessary to edit Emacs functions; you can always use hooks (or, in rare cases, advice). So this works: (add-hook 'auto-save-hook 'save-buffer)
. Yeah, it will still be saving the file in the #filename#, but it will be saving it to your file too. Actually I then realised I don’t need that either. Doing M-x apropos-variable RET auto-save RET
gives several variables including:
auto-save-file-name-transforms Variable: Transforms to apply to buffer file name before making auto-save file name. auto-save-timeout Variable: *Number of seconds idle time before auto-save. auto-save-visited-file-name Variable: Non-nil says auto-save a buffer in the file it is visiting, when practical.
and setting auto-save-visited-file-name to t
seemed to do what I want. Until I actually tried to use it, and discovered that whoever added that feature probably hasn’t actually used it at all — it asks a “File has changed on buffer, really edit it? (y/n/r/h)” each time it auto-saves and you try to continue editing. You could turn on auto-revert-mode to make that problem go away, but I’m unsure if that’s a good idea: sometimes I overwrite files by mistake (gcc hello.c -o hello.c
) and having Emacs not auto-revert is very helpful in those cases. So I’ll stick with my earlier idea, which works perfectly, after being fixed by Bryan Murdock:
(defun save-buffer-if-visiting-file (&optional args)
"Save the current buffer only if it is visiting a file"
(interactive)
(if (buffer-file-name)
(save-buffer args)))
(add-hook 'auto-save-hook 'save-buffer-if-visiting-file)
Bryan Murdock also posted it.
Leave a Reply