Subject: Re: bug#5314: 23.1; Inconsistent treatment of auto-save files

From: Uday S Reddy <[email-masked]>
Date: Wed, 6 Jan 2010 02:14:37 +0000

Stefan Monnier writes:

> [ Always glad to see people from my field participate in Emacs
> development. ]

Same here!  I didn't realize it was you.  Nice to know!

> Could you try and provide a more precise recipe?

I sent a follow-up today with more specific info, but perhaps it
didn't reach you.  Here it is again:

-----
With an old auto-save file on the disk, the following sequence done on
a buffer seems to always return nil:

  (progn (insert "x") (recent-auto-save-p))

Killing the buffer in this case does not affect the old auto-save
file.

The following sequence seems to always return t

  (progn (set-buffer-modified-p t) (recent-auto-save-p))

Killing the buffer in this case deletes the old auto-save file.

So, it appears that recent-auto-save-p and kill-buffer are consistent
with each other.  But their behaviour is paradoxical with regard to
set-buffer-modified-p.
----

VM, being a mail client, doesn't allow typing into buffers.
(set-buffer-modified-p t) is the main way of recording that changes
have been made.

VM's quit routine had the following series of operations:

      (set-buffer-modified-p nil)
      (delete-auto-save-file-if-necessary)
      (kill-buffer (current-buffer)))

This might have worked in some old version of Emacs.  But, at present,
the delete-..-if-necessary doesn't do anything because the buffer has
been set to be unmodified.  (This is reasonable behaviour for the
delete-..-if-necessary function, but it doesn't follow from the
documented description of it.)

I tried switching the order of the first two operations.  Then I
discovered that non-recent auto-save files were getting deleted as
well. 

If Emacs knows enough to keep track of which auto-save files were
written by "this Emacs" (as indicated in the documentation of
delete-...-if-necessary), then I think it should always delete those
auto-save files and nothing else.  In that case, both the orders of
the VM's quit routine would work fine.  At the moment, neither one
does!

> Or maybe the old auto-save file was overwritten by a new auto-save file
> before you killed the buffer?  It does sound like a likely reason.
> And indeed it's a problem, tho I'm not sure how to best fix it:
> - We could try and rename the old auto-save file before saving the new one
>   and let recover-file choose among the various possible auto-save files.
> - Maybe make it harder for the user to start modifying the buffer when
>   there's an old auto-save file (e.g. make the buffer read-only and
>   warn/prompt when the user tries to C-x C-q).
> - Prompt just before saving the new auto-save file so the user
>   gets a chance to prevent the old auto-save from being overwritten.
> - Disable auto-saving when there's an old auto-save file (together with
>   an appropriate warning, in the same way as we disable auto-saving when
>   the file/buffer got much smaller).

VM uses the second solution.  For Emacs, the last solution would be
the best.  In fact, I always assumed that Emacs was using the last
solution. 

> > If the buffer-modified-p is nil, then even recent auto-save files seem
> > to be left lying around.  This is the opposite problem of that in
> > point 1.
> 
> I cannot reproduce this either.  Do you have a recipe?

Visit a file, type some stuff, run do-auto-save, eval
(set-buffer-modified-p nil) and then kill the buffer.  The auto-save
file would still be there.

> > 4. The Elisp manual descriptions for
> > delete-auto-save-file-if-necessary and
> > recent-auto-save-p need to be similarly modified.
> 
> Just to be sure: do you want to change the doc because you don't like
> the behavior it describes, or because it doesn't match the behavior
> you see?
> 
> We clearly would rather fix the code to match the doc if the doc
> describes the behavior we want.

If you can change the code to match the doc, that would be perfect.
That would mean that the "this Emacs" idea has to be taken seriously.
No guess work.  If two concurrent Emacs sessions are editing the same
file and end up over-writing each other's auto-save files, then each
Emacs session should only delete the version of the auto-save file it
created!  It is a bit ambitious, but doable.

Cheers,
Uday