diff options
| author | Lars Ingebrigtsen | 2021-08-23 15:56:50 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2021-08-23 15:56:54 +0200 |
| commit | 591b8bd87a30bda3dad680752b7f63da8b5b74bd (patch) | |
| tree | 847301e45c0c58a4242da2ba9a706277e5193e4d | |
| parent | f00af4be3d8c14fc83925dcd244701c0dce7604a (diff) | |
| download | emacs-591b8bd87a30bda3dad680752b7f63da8b5b74bd.tar.gz emacs-591b8bd87a30bda3dad680752b7f63da8b5b74bd.zip | |
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).
| -rw-r--r-- | doc/emacs/files.texi | 7 | ||||
| -rw-r--r-- | etc/NEWS | 12 | ||||
| -rw-r--r-- | lisp/cus-start.el | 2 | ||||
| -rw-r--r-- | lisp/files.el | 9 | ||||
| -rw-r--r-- | src/buffer.c | 49 | ||||
| -rw-r--r-- | test/src/buffer-tests.el | 63 |
6 files changed, 112 insertions, 30 deletions
diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 9aae0e9a0b3..9338e77859a 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi | |||
| @@ -1191,6 +1191,13 @@ visited file. (You can inhibit this by setting the variable | |||
| 1191 | file name with @kbd{C-x C-w} or @code{set-visited-file-name} renames | 1191 | file name with @kbd{C-x C-w} or @code{set-visited-file-name} renames |
| 1192 | any auto-save file to go with the new visited name. | 1192 | any auto-save file to go with the new visited name. |
| 1193 | 1193 | ||
| 1194 | @vindex kill-buffer-delete-auto-save-files | ||
| 1195 | Killing a buffer, by default, doesn't remove the buffer's auto-save | ||
| 1196 | file. If @code{kill-buffer-delete-auto-save-files} is non-@code{nil}, | ||
| 1197 | killing a buffer that has an auto-save file will make Emacs prompt the | ||
| 1198 | user for whether the auto-save file should be deleted. (This is | ||
| 1199 | inhibited is @code{delete-auto-save-files} is @code{nil}.) | ||
| 1200 | |||
| 1194 | @node Auto Save Control | 1201 | @node Auto Save Control |
| 1195 | @subsection Controlling Auto-Saving | 1202 | @subsection Controlling Auto-Saving |
| 1196 | 1203 | ||
| @@ -3824,12 +3824,22 @@ whenever the protected form terminates without error, with the | |||
| 3824 | specified variable bound to the the value of the protected form. | 3824 | specified variable bound to the the value of the protected form. |
| 3825 | 3825 | ||
| 3826 | +++ | 3826 | +++ |
| 3827 | ** 'The 'uniquify' argument in 'auto-save-file-name-transforms' can be a symbol. | 3827 | ** The 'uniquify' argument in 'auto-save-file-name-transforms' can be a symbol. |
| 3828 | If this symbol is one of the members of 'secure-hash-algorithms', | 3828 | If this symbol is one of the members of 'secure-hash-algorithms', |
| 3829 | Emacs constructs the nondirectory part of the auto-save file name by | 3829 | Emacs constructs the nondirectory part of the auto-save file name by |
| 3830 | applying that 'secure-hash' to the buffer file name. This avoids any | 3830 | applying that 'secure-hash' to the buffer file name. This avoids any |
| 3831 | risk of excessively long file names. | 3831 | risk of excessively long file names. |
| 3832 | 3832 | ||
| 3833 | +++ | ||
| 3834 | ** New user option 'kill-buffer-delete-auto-save-files'. | ||
| 3835 | If non-nil, killing a buffer that has an auto-save file will prompt | ||
| 3836 | the user for whether that buffer should be deleted. (Note that | ||
| 3837 | 'delete-auto-save-files', if non-nil, was previously documented to | ||
| 3838 | result in deletion of auto-save files when killing a buffer without | ||
| 3839 | unsaved changes, but this has apparently not worked for several | ||
| 3840 | decades, so the documented semantics of this variable has been changed | ||
| 3841 | to match the behaviour.) | ||
| 3842 | |||
| 3833 | --- | 3843 | --- |
| 3834 | ** New user option 'etags-xref-prefer-current-file'. | 3844 | ** New user option 'etags-xref-prefer-current-file'. |
| 3835 | When non-nil, matches for identifiers in the file visited by the | 3845 | When non-nil, matches for identifiers in the file visited by the |
diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 19975307894..1a3e5682bba 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el | |||
| @@ -171,6 +171,8 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of | |||
| 171 | (const :tag "Right to Left" right-to-left) | 171 | (const :tag "Right to Left" right-to-left) |
| 172 | (const :tag "Dynamic, according to paragraph text" nil)) | 172 | (const :tag "Dynamic, according to paragraph text" nil)) |
| 173 | "24.1") | 173 | "24.1") |
| 174 | (delete-auto-save-files auto-save boolean) | ||
| 175 | (kill-buffer-delete-auto-save-files auto-save boolean "28.1") | ||
| 174 | ;; callint.c | 176 | ;; callint.c |
| 175 | (mark-even-if-inactive editing-basics boolean) | 177 | (mark-even-if-inactive editing-basics boolean) |
| 176 | ;; callproc.c | 178 | ;; callproc.c |
diff --git a/lisp/files.el b/lisp/files.el index e519a8ea8b6..bd87b995756 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -42,15 +42,6 @@ | |||
| 42 | "Finding files." | 42 | "Finding files." |
| 43 | :group 'files) | 43 | :group 'files) |
| 44 | 44 | ||
| 45 | |||
| 46 | (defcustom delete-auto-save-files t | ||
| 47 | "Non-nil means delete auto-save file when a buffer is saved or killed. | ||
| 48 | |||
| 49 | Note that the auto-save file will not be deleted if the buffer is killed | ||
| 50 | when it has unsaved changes." | ||
| 51 | :type 'boolean | ||
| 52 | :group 'auto-save) | ||
| 53 | |||
| 54 | (defcustom directory-abbrev-alist | 45 | (defcustom directory-abbrev-alist |
| 55 | nil | 46 | nil |
| 56 | "Alist of abbreviations for file directories. | 47 | "Alist of abbreviations for file directories. |
diff --git a/src/buffer.c b/src/buffer.c index 7e4c84911bb..7ba0c8bc2a6 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -1768,6 +1768,7 @@ cleaning up all windows currently displaying the buffer to be killed. */) | |||
| 1768 | /* Run hooks with the buffer to be killed as the current buffer. */ | 1768 | /* Run hooks with the buffer to be killed as the current buffer. */ |
| 1769 | { | 1769 | { |
| 1770 | ptrdiff_t count = SPECPDL_INDEX (); | 1770 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1771 | bool modified; | ||
| 1771 | 1772 | ||
| 1772 | record_unwind_protect_excursion (); | 1773 | record_unwind_protect_excursion (); |
| 1773 | set_buffer_internal (b); | 1774 | set_buffer_internal (b); |
| @@ -1782,9 +1783,12 @@ cleaning up all windows currently displaying the buffer to be killed. */) | |||
| 1782 | return unbind_to (count, Qnil); | 1783 | return unbind_to (count, Qnil); |
| 1783 | } | 1784 | } |
| 1784 | 1785 | ||
| 1786 | /* Is this a modified buffer that's visiting a file? */ | ||
| 1787 | modified = !NILP (BVAR (b, filename)) | ||
| 1788 | && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b); | ||
| 1789 | |||
| 1785 | /* Query if the buffer is still modified. */ | 1790 | /* Query if the buffer is still modified. */ |
| 1786 | if (INTERACTIVE && !NILP (BVAR (b, filename)) | 1791 | if (INTERACTIVE && modified) |
| 1787 | && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)) | ||
| 1788 | { | 1792 | { |
| 1789 | AUTO_STRING (format, "Buffer %s modified; kill anyway? "); | 1793 | AUTO_STRING (format, "Buffer %s modified; kill anyway? "); |
| 1790 | tem = do_yes_or_no_p (CALLN (Fformat, format, BVAR (b, name))); | 1794 | 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. */) | |||
| 1792 | return unbind_to (count, Qnil); | 1796 | return unbind_to (count, Qnil); |
| 1793 | } | 1797 | } |
| 1794 | 1798 | ||
| 1799 | /* Delete the autosave file, if requested. */ | ||
| 1800 | if (modified | ||
| 1801 | && kill_buffer_delete_auto_save_files | ||
| 1802 | && delete_auto_save_files | ||
| 1803 | && !NILP (Frecent_auto_save_p ())) | ||
| 1804 | { | ||
| 1805 | tem = do_yes_or_no_p (build_string ("Delete auto-save file? ")); | ||
| 1806 | if (!NILP (tem)) | ||
| 1807 | call0 (intern ("delete-auto-save-file-if-necessary")); | ||
| 1808 | } | ||
| 1809 | |||
| 1795 | /* If the hooks have killed the buffer, exit now. */ | 1810 | /* If the hooks have killed the buffer, exit now. */ |
| 1796 | if (!BUFFER_LIVE_P (b)) | 1811 | if (!BUFFER_LIVE_P (b)) |
| 1797 | return unbind_to (count, Qt); | 1812 | return unbind_to (count, Qt); |
| @@ -1888,24 +1903,6 @@ cleaning up all windows currently displaying the buffer to be killed. */) | |||
| 1888 | replace_buffer_in_windows_safely (buffer); | 1903 | replace_buffer_in_windows_safely (buffer); |
| 1889 | Vinhibit_quit = tem; | 1904 | Vinhibit_quit = tem; |
| 1890 | 1905 | ||
| 1891 | /* Delete any auto-save file, if we saved it in this session. | ||
| 1892 | But not if the buffer is modified. */ | ||
| 1893 | if (STRINGP (BVAR (b, auto_save_file_name)) | ||
| 1894 | && BUF_AUTOSAVE_MODIFF (b) != 0 | ||
| 1895 | && BUF_SAVE_MODIFF (b) < BUF_AUTOSAVE_MODIFF (b) | ||
| 1896 | && BUF_SAVE_MODIFF (b) < BUF_MODIFF (b) | ||
| 1897 | && NILP (Fsymbol_value (intern ("auto-save-visited-file-name")))) | ||
| 1898 | { | ||
| 1899 | Lisp_Object delete; | ||
| 1900 | delete = Fsymbol_value (intern ("delete-auto-save-files")); | ||
| 1901 | if (! NILP (delete)) | ||
| 1902 | internal_delete_file (BVAR (b, auto_save_file_name)); | ||
| 1903 | } | ||
| 1904 | |||
| 1905 | /* Deleting an auto-save file could have killed our buffer. */ | ||
| 1906 | if (!BUFFER_LIVE_P (b)) | ||
| 1907 | return Qt; | ||
| 1908 | |||
| 1909 | if (b->base_buffer) | 1906 | if (b->base_buffer) |
| 1910 | { | 1907 | { |
| 1911 | INTERVAL i; | 1908 | INTERVAL i; |
| @@ -6366,6 +6363,18 @@ nil NORECORD argument since it may lead to infinite recursion. */); | |||
| 6366 | Vbuffer_list_update_hook = Qnil; | 6363 | Vbuffer_list_update_hook = Qnil; |
| 6367 | DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook"); | 6364 | DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook"); |
| 6368 | 6365 | ||
| 6366 | DEFVAR_BOOL ("kill-buffer-delete-auto-save-files", | ||
| 6367 | kill_buffer_delete_auto_save_files, | ||
| 6368 | doc: /* If non-nil, offer to delete any autosave file when killing a buffer. | ||
| 6369 | |||
| 6370 | If `delete-auto-save-files' is nil, any autosave deletion is inhibited. */); | ||
| 6371 | kill_buffer_delete_auto_save_files = 0; | ||
| 6372 | |||
| 6373 | DEFVAR_BOOL ("delete-auto-save-files", delete_auto_save_files, | ||
| 6374 | doc: /* Non-nil means delete auto-save file when a buffer is saved. | ||
| 6375 | This is the default. If nil, auto-save file deletion is inhibited. */); | ||
| 6376 | delete_auto_save_files = 1; | ||
| 6377 | |||
| 6369 | defsubr (&Sbuffer_live_p); | 6378 | defsubr (&Sbuffer_live_p); |
| 6370 | defsubr (&Sbuffer_list); | 6379 | defsubr (&Sbuffer_list); |
| 6371 | defsubr (&Sget_buffer); | 6380 | defsubr (&Sget_buffer); |
diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el index 118311c4d26..059926ff46b 100644 --- a/test/src/buffer-tests.el +++ b/test/src/buffer-tests.el | |||
| @@ -1420,4 +1420,67 @@ with parameters from the *Messages* buffer modification." | |||
| 1420 | (remove-overlays) | 1420 | (remove-overlays) |
| 1421 | (should (= (length (overlays-in (point-min) (point-max))) 0)))) | 1421 | (should (= (length (overlays-in (point-min) (point-max))) 0)))) |
| 1422 | 1422 | ||
| 1423 | (ert-deftest test-kill-buffer-auto-save-default () | ||
| 1424 | (let ((file (make-temp-file "ert")) | ||
| 1425 | auto-save) | ||
| 1426 | (should (file-exists-p file)) | ||
| 1427 | ;; Always answer yes. | ||
| 1428 | (cl-letf (((symbol-function #'yes-or-no-p) (lambda (_) t))) | ||
| 1429 | (unwind-protect | ||
| 1430 | (progn | ||
| 1431 | (find-file file) | ||
| 1432 | (auto-save-mode t) | ||
| 1433 | (insert "foo\n") | ||
| 1434 | (should buffer-auto-save-file-name) | ||
| 1435 | (setq auto-save buffer-auto-save-file-name) | ||
| 1436 | (do-auto-save) | ||
| 1437 | (should (file-exists-p auto-save)) | ||
| 1438 | (kill-buffer (current-buffer)) | ||
| 1439 | (should (file-exists-p auto-save))) | ||
| 1440 | (ignore-errors (delete-file file)) | ||
| 1441 | (when auto-save | ||
| 1442 | (ignore-errors (delete-file auto-save))))))) | ||
| 1443 | |||
| 1444 | (ert-deftest test-kill-buffer-auto-save-delete () | ||
| 1445 | (let ((file (make-temp-file "ert")) | ||
| 1446 | auto-save) | ||
| 1447 | (should (file-exists-p file)) | ||
| 1448 | (setq kill-buffer-delete-auto-save-files t) | ||
| 1449 | ;; Always answer yes. | ||
| 1450 | (cl-letf (((symbol-function #'yes-or-no-p) (lambda (_) t))) | ||
| 1451 | (unwind-protect | ||
| 1452 | (progn | ||
| 1453 | (find-file file) | ||
| 1454 | (auto-save-mode t) | ||
| 1455 | (insert "foo\n") | ||
| 1456 | (should buffer-auto-save-file-name) | ||
| 1457 | (setq auto-save buffer-auto-save-file-name) | ||
| 1458 | (do-auto-save) | ||
| 1459 | (should (file-exists-p auto-save)) | ||
| 1460 | ;; This should delete the auto-save file. | ||
| 1461 | (kill-buffer (current-buffer)) | ||
| 1462 | (should-not (file-exists-p auto-save))) | ||
| 1463 | (ignore-errors (delete-file file)) | ||
| 1464 | (when auto-save | ||
| 1465 | (ignore-errors (delete-file auto-save))))) | ||
| 1466 | ;; Answer no to deletion. | ||
| 1467 | (cl-letf (((symbol-function #'yes-or-no-p) | ||
| 1468 | (lambda (prompt) | ||
| 1469 | (not (string-search "Delete auto-save file" prompt))))) | ||
| 1470 | (unwind-protect | ||
| 1471 | (progn | ||
| 1472 | (find-file file) | ||
| 1473 | (auto-save-mode t) | ||
| 1474 | (insert "foo\n") | ||
| 1475 | (should buffer-auto-save-file-name) | ||
| 1476 | (setq auto-save buffer-auto-save-file-name) | ||
| 1477 | (do-auto-save) | ||
| 1478 | (should (file-exists-p auto-save)) | ||
| 1479 | ;; This should not delete the auto-save file. | ||
| 1480 | (kill-buffer (current-buffer)) | ||
| 1481 | (should (file-exists-p auto-save))) | ||
| 1482 | (ignore-errors (delete-file file)) | ||
| 1483 | (when auto-save | ||
| 1484 | (ignore-errors (delete-file auto-save))))))) | ||
| 1485 | |||
| 1423 | ;;; buffer-tests.el ends here | 1486 | ;;; buffer-tests.el ends here |