Add new variable 'kill-buffer/delete-auto-save-files'

* doc/emacs/files.texi (Auto Save Files): Document it.
* lisp/cus-start.el (standard): Add customize form.

* lisp/files.el (delete-auto-save-files): Move definition to C
(since it's used in the C layer).

* src/buffer.c (Fkill_buffer): Use the new variable (and remove
the old code that apparently didn't trigger for
kill-buffer/delete-auto-save-files.
(syms_of_buffer): Add new variable
kill-buffer-delete-auto-save-files and move definition of
delete-auto-save-files here (bug#21612).
This commit is contained in:
Lars Ingebrigtsen 2021-08-23 15:56:50 +02:00
parent f00af4be3d
commit 591b8bd87a
6 changed files with 112 additions and 30 deletions

View file

@ -1191,6 +1191,13 @@ visited file. (You can inhibit this by setting the variable
file name with @kbd{C-x C-w} or @code{set-visited-file-name} renames
any auto-save file to go with the new visited name.
@vindex kill-buffer-delete-auto-save-files
Killing a buffer, by default, doesn't remove the buffer's auto-save
file. If @code{kill-buffer-delete-auto-save-files} is non-@code{nil},
killing a buffer that has an auto-save file will make Emacs prompt the
user for whether the auto-save file should be deleted. (This is
inhibited is @code{delete-auto-save-files} is @code{nil}.)
@node Auto Save Control
@subsection Controlling Auto-Saving

View file

@ -3824,12 +3824,22 @@ whenever the protected form terminates without error, with the
specified variable bound to the the value of the protected form.
+++
** 'The 'uniquify' argument in 'auto-save-file-name-transforms' can be a symbol.
** The 'uniquify' argument in 'auto-save-file-name-transforms' can be a symbol.
If this symbol is one of the members of 'secure-hash-algorithms',
Emacs constructs the nondirectory part of the auto-save file name by
applying that 'secure-hash' to the buffer file name. This avoids any
risk of excessively long file names.
+++
** New user option 'kill-buffer-delete-auto-save-files'.
If non-nil, killing a buffer that has an auto-save file will prompt
the user for whether that buffer should be deleted. (Note that
'delete-auto-save-files', if non-nil, was previously documented to
result in deletion of auto-save files when killing a buffer without
unsaved changes, but this has apparently not worked for several
decades, so the documented semantics of this variable has been changed
to match the behaviour.)
---
** New user option 'etags-xref-prefer-current-file'.
When non-nil, matches for identifiers in the file visited by the

View file

@ -171,6 +171,8 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
(const :tag "Right to Left" right-to-left)
(const :tag "Dynamic, according to paragraph text" nil))
"24.1")
(delete-auto-save-files auto-save boolean)
(kill-buffer-delete-auto-save-files auto-save boolean "28.1")
;; callint.c
(mark-even-if-inactive editing-basics boolean)
;; callproc.c

View file

@ -42,15 +42,6 @@
"Finding files."
:group 'files)
(defcustom delete-auto-save-files t
"Non-nil means delete auto-save file when a buffer is saved or killed.
Note that the auto-save file will not be deleted if the buffer is killed
when it has unsaved changes."
:type 'boolean
:group 'auto-save)
(defcustom directory-abbrev-alist
nil
"Alist of abbreviations for file directories.

View file

@ -1768,6 +1768,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
/* Run hooks with the buffer to be killed as the current buffer. */
{
ptrdiff_t count = SPECPDL_INDEX ();
bool modified;
record_unwind_protect_excursion ();
set_buffer_internal (b);
@ -1782,9 +1783,12 @@ cleaning up all windows currently displaying the buffer to be killed. */)
return unbind_to (count, Qnil);
}
/* Is this a modified buffer that's visiting a file? */
modified = !NILP (BVAR (b, filename))
&& BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
/* Query if the buffer is still modified. */
if (INTERACTIVE && !NILP (BVAR (b, filename))
&& BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
if (INTERACTIVE && modified)
{
AUTO_STRING (format, "Buffer %s modified; kill anyway? ");
tem = do_yes_or_no_p (CALLN (Fformat, format, BVAR (b, name)));
@ -1792,6 +1796,17 @@ cleaning up all windows currently displaying the buffer to be killed. */)
return unbind_to (count, Qnil);
}
/* Delete the autosave file, if requested. */
if (modified
&& kill_buffer_delete_auto_save_files
&& delete_auto_save_files
&& !NILP (Frecent_auto_save_p ()))
{
tem = do_yes_or_no_p (build_string ("Delete auto-save file? "));
if (!NILP (tem))
call0 (intern ("delete-auto-save-file-if-necessary"));
}
/* If the hooks have killed the buffer, exit now. */
if (!BUFFER_LIVE_P (b))
return unbind_to (count, Qt);
@ -1888,24 +1903,6 @@ cleaning up all windows currently displaying the buffer to be killed. */)
replace_buffer_in_windows_safely (buffer);
Vinhibit_quit = tem;
/* Delete any auto-save file, if we saved it in this session.
But not if the buffer is modified. */
if (STRINGP (BVAR (b, auto_save_file_name))
&& BUF_AUTOSAVE_MODIFF (b) != 0
&& BUF_SAVE_MODIFF (b) < BUF_AUTOSAVE_MODIFF (b)
&& BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
&& NILP (Fsymbol_value (intern ("auto-save-visited-file-name"))))
{
Lisp_Object delete;
delete = Fsymbol_value (intern ("delete-auto-save-files"));
if (! NILP (delete))
internal_delete_file (BVAR (b, auto_save_file_name));
}
/* Deleting an auto-save file could have killed our buffer. */
if (!BUFFER_LIVE_P (b))
return Qt;
if (b->base_buffer)
{
INTERVAL i;
@ -6366,6 +6363,18 @@ nil NORECORD argument since it may lead to infinite recursion. */);
Vbuffer_list_update_hook = Qnil;
DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");
DEFVAR_BOOL ("kill-buffer-delete-auto-save-files",
kill_buffer_delete_auto_save_files,
doc: /* If non-nil, offer to delete any autosave file when killing a buffer.
If `delete-auto-save-files' is nil, any autosave deletion is inhibited. */);
kill_buffer_delete_auto_save_files = 0;
DEFVAR_BOOL ("delete-auto-save-files", delete_auto_save_files,
doc: /* Non-nil means delete auto-save file when a buffer is saved.
This is the default. If nil, auto-save file deletion is inhibited. */);
delete_auto_save_files = 1;
defsubr (&Sbuffer_live_p);
defsubr (&Sbuffer_list);
defsubr (&Sget_buffer);

View file

@ -1420,4 +1420,67 @@ with parameters from the *Messages* buffer modification."
(remove-overlays)
(should (= (length (overlays-in (point-min) (point-max))) 0))))
(ert-deftest test-kill-buffer-auto-save-default ()
(let ((file (make-temp-file "ert"))
auto-save)
(should (file-exists-p file))
;; Always answer yes.
(cl-letf (((symbol-function #'yes-or-no-p) (lambda (_) t)))
(unwind-protect
(progn
(find-file file)
(auto-save-mode t)
(insert "foo\n")
(should buffer-auto-save-file-name)
(setq auto-save buffer-auto-save-file-name)
(do-auto-save)
(should (file-exists-p auto-save))
(kill-buffer (current-buffer))
(should (file-exists-p auto-save)))
(ignore-errors (delete-file file))
(when auto-save
(ignore-errors (delete-file auto-save)))))))
(ert-deftest test-kill-buffer-auto-save-delete ()
(let ((file (make-temp-file "ert"))
auto-save)
(should (file-exists-p file))
(setq kill-buffer-delete-auto-save-files t)
;; Always answer yes.
(cl-letf (((symbol-function #'yes-or-no-p) (lambda (_) t)))
(unwind-protect
(progn
(find-file file)
(auto-save-mode t)
(insert "foo\n")
(should buffer-auto-save-file-name)
(setq auto-save buffer-auto-save-file-name)
(do-auto-save)
(should (file-exists-p auto-save))
;; This should delete the auto-save file.
(kill-buffer (current-buffer))
(should-not (file-exists-p auto-save)))
(ignore-errors (delete-file file))
(when auto-save
(ignore-errors (delete-file auto-save)))))
;; Answer no to deletion.
(cl-letf (((symbol-function #'yes-or-no-p)
(lambda (prompt)
(not (string-search "Delete auto-save file" prompt)))))
(unwind-protect
(progn
(find-file file)
(auto-save-mode t)
(insert "foo\n")
(should buffer-auto-save-file-name)
(setq auto-save buffer-auto-save-file-name)
(do-auto-save)
(should (file-exists-p auto-save))
;; This should not delete the auto-save file.
(kill-buffer (current-buffer))
(should (file-exists-p auto-save)))
(ignore-errors (delete-file file))
(when auto-save
(ignore-errors (delete-file auto-save)))))))
;;; buffer-tests.el ends here