]> git.eshelyaron.com Git - emacs.git/commitdiff
Add new variable 'kill-buffer/delete-auto-save-files'
authorLars Ingebrigtsen <larsi@gnus.org>
Mon, 23 Aug 2021 13:56:50 +0000 (15:56 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Mon, 23 Aug 2021 13:56:54 +0000 (15:56 +0200)
* 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).

doc/emacs/files.texi
etc/NEWS
lisp/cus-start.el
lisp/files.el
src/buffer.c
test/src/buffer-tests.el

index 9aae0e9a0b3445c338efca06cb27dcdae18ca49b..9338e77859aa1892a38cc62a1474a1081e4b5721 100644 (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
 
index aefe582ad7cc27ccfd1d19e82e20ddadeca05d8a..b008c46291c0fafa0d7cb61fc6b62a96758da654 100644 (file)
--- a/etc/NEWS
+++ b/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
index 19975307894267952d0188a020c8dca6e9de6f69..1a3e5682bbab053b2515387af9b5da0575a51950 100644 (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
index e519a8ea8b6aff719f41230e313aeb2cd7746257..bd87b995756b8d18826c936e064afc83e9846935 100644 (file)
   "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.
index 7e4c84911bb93f875698b7ddd7f9fa100f2d338c..7ba0c8bc2a6d2bc7ccbc699a503882dcf116eace 100644 (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);
index 118311c4d267fe3541ebab88160469777627937e..059926ff46bfbd1aa487292d5940f62f8a584c2b 100644 (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