2011-02-26

Visiting a file which has auto save data

Has it ever happened to you that you had to open a file that had autosave data next to it in a #filename.ext# file? Emacs shows a warning, namely:

filename.ext has auto save data; consider M-x recover-this-file

The warning is fine and all, but what was driving me nuts was the 1 second delay that I had to wait to see the contents of the file (at least in GNU Emacs 23.2.1). The delay could be skipped by pressing a key, but that is also annoying. This happens again and again if you close the file and open it again, which is even more annoying.

This only ends if you manually delete the save-file, or you save your original file to make it newer then the save-file. Let me remind you that just pressing C-x-C-s only works if you have modified the buffer. Also if for some reason the save-file modification time is in the future, then this technique doesn't work at all, you have to manually remove the save-file.

A quick, but ugly solution:

Adding this code to your .emacs removes the 1-second delay when you open a file which has save data. The warning message is still displayed. The code was tested in GNU Emacs 23.2.1.

(defadvice after-find-file (around dont-wait activate)
  "Don't do delays (this advice temporarely overrides the sit-for function)"
  (flet ((sit-for (&rest dummy) t))
    ad-do-it
  )
)

Explanation:

The code that prints the warning message can be found in files.el, on line 2137. The code that waits for the 1 second delay is on line 2153. It calls the sit-for' function. Even if I could control all the parameters of this function, getting the not-serious variable to become true (non-nil), and showing the warning message at the same time is not possible because of the way the code is built.

So the only solution is to modify the function after-find-file. copy-pasting the defun into my .emacs, and just removing the call to the sit-for function would work, because it overwrites the function-cell of the global symbol after-find-file, but this is probably not compatible with different versions of emacs.

A slightly cleaner way to patch existing functions is to use advices. You can learn about advices in the Advising Functions' chapter in the ELISP reference manual. I used an around-advice which lets me write code around the original function definition.

The modification that has to be done is to temporarily rebind the sit-for function to do nothing while the after-find-file function is running. The let special form does temporary rebinding, but it doesn't rebind the function cell of symbol. On the other hand flet lets you make temporary function definitions. Here I define a function that takes any number of arguments, and just returns true. in the body of the flet I write ad-do-it as a placeholder for the original function. After the closing parenthesis of the flet macro the local binding to the dummy function disappears, and the sit-for function again works as expected.

Related Work:

A different solution to killing the 1-second delay, is to disable the find-file warning messages. This solution is hinted at by emacswiki - Autosave, but no explicit solution is given. An explicit solution which overrides the NOWARN argument of the find-file-noselect function (which is called by find-file), using an around-advice, is like this:

(defadvice find-file-noselect (around nowarn activate)
  "Turn off warnings"
  (ad-set-arg 1 t)
  ad-do-it
)

It is sensible to force the user to choose between restoring the autosave or not. The warning message is very easy to ignore, and it is even more easier to ignore if the delay is missing. A way to force the user to decide between restoring the auto save data or not is found here: http://osdir.com/ml/help-gnu-emacs-gnu/2009-07/msg00114.html. This doesn't solve the problem that when the user explicitly chooses not to restore the auto save data, and doesn't update the original file, he is going to be asked again the next time he opens this file. Also, using that code does not eliminate the delay, which becomes completely useless as an attention-raising tool when combined with that code. Both my code and the linked code can be used at the same time to solve this.

Another way to provide an obvious visual feedback, and to force the user to recover a file with autosave data is to use this: http://osdir.com/ml/help-gnu-emacs-gnu/2009-07/msg00150.html.

Punctuation marks following links that I don't control are backup links in case the original goes down. I hate link rot.