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:
parent
f00af4be3d
commit
591b8bd87a
6 changed files with 112 additions and 30 deletions
|
@ -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
|
||||
|
||||
|
|
12
etc/NEWS
12
etc/NEWS
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
49
src/buffer.c
49
src/buffer.c
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue