Package: emacs;
Reported by: 積丹尼 Dan Jacobson <jidanni <at> jidanni.org>
Date: Fri, 4 Aug 2017 00:38:01 UTC
Severity: wishlist
Done: Tino Calancha <tino.calancha <at> gmail.com>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Tino Calancha <tino.calancha <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: 27940 <at> debbugs.gnu.org, jidanni <at> jidanni.org Subject: bug#27940: Recursively delete dir34? (yes, no, all, quit) Date: Fri, 04 Aug 2017 23:33:51 +0900
Eli Zaretskii <eliz <at> gnu.org> writes: > Shouldn't the valid-answers be "yes" and "no", not "y" and "n", for > backward compatibility? Yes, they should. > >> + (completing-read (format "Recursively %s %s? [y, n, !, q] " > > Maybe the "!" and "q" parts should be explained? Or maybe just use > "yes", "no", "all", and "quite", which are self-explanatory? Look the updated patch; it's a mix: 1. uses 'yes', 'no' 2. '!', 'q', 'help' This is similar like `query-replace' does (there is used '!', 'q', and '?'). With 'help', a Help buffer is shown with a help message. > > This warrants a NEWS entry, I think. I also wonder whether we should > describe this in the user manual, under "Dired Deletion". I did. --8<-----------------------------cut here---------------start------------->8--- commit a883db5e05364bd7a76138642d39b296266ff0a1 Author: Tino Calancha <tino.calancha <at> gmail.com> Date: Fri Aug 4 23:26:30 2017 +0900 dired-do-delete: Allow to delete dirs recursively without prompts * lisp/dired.el (dired-delete-file): Accept 2 additional answers: '!', to delete all directories recursively and no prompt anymore. 'q', to cancel the directory deletions (Bug#27940). Show help message when user inputs 'help'. (dired-do-flagged-delete): Bind locally dired-recursive-deletes so that we can overwrite its global value. Wrapp the loop within a catch '--delete-cancel to catch when the user abort the directtry deletion. * doc/emacs/dired.texi (Dired Deletion): Update manual. * etc/NEWS (Changes in Specialized Modes and Packages in Emacs 26.1): Announce this change. diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index 150ac8427a..5eb066d927 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -236,6 +236,14 @@ Dired Deletion @code{dired-recursive-deletes} is non-@code{nil}, then Dired can delete nonempty directories including all their contents. That can be somewhat risky. +Even if you have set @code{dired-recursive-deletes} to @code{nil}, +you might want sometimes to delete recursively directories +without being asked for confirmation for all of them. This is handy +when you have marked many directories for deletion and you are very +sure that all of them can safely being deleted. For every nonempty +directory you are asked for confirmation; if you answer @code{!}, +then all the remaining directories will be deleted without more +questions. @vindex delete-by-moving-to-trash If you change the variable @code{delete-by-moving-to-trash} to diff --git a/etc/NEWS b/etc/NEWS index b72793dec0..dcac7d5e41 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -611,6 +611,10 @@ paragraphs, for the purposes of bidirectional display. ** Dired +++ +*** You can answer '!' in 'dired-do-delete' to delete recursively all +remaining directories without more prompts. + ++++ *** Dired supports wildcards in the directory part of the file names. +++ diff --git a/lisp/dired.el b/lisp/dired.el index 24759c6c9b..133fd2e719 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2975,6 +2975,14 @@ dired-recursive-deletes ;; Match anything but `.' and `..'. (defvar dired-re-no-dot "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*") +(defconst dired-delete-help + "Type: +`yes' to delete recursively the current directory, +`no' to skip to next, +`!' to delete all remaining directories with no more questions, +`q' to exit, +`help' to show this help message.") + ;; Delete file, possibly delete a directory and all its files. ;; This function is useful outside of dired. One could change its name ;; to e.g. recursive-delete-file and put it somewhere else. @@ -2990,23 +2998,40 @@ dired-delete-file TRASH non-nil means to trash the file instead of deleting, provided `delete-by-moving-to-trash' (which see) is non-nil." - ;; This test is equivalent to - ;; (and (file-directory-p fn) (not (file-symlink-p fn))) - ;; but more efficient - (if (not (eq t (car (file-attributes file)))) - (delete-file file trash) - (if (and recursive - (directory-files file t dired-re-no-dot) ; Not empty. - (or (eq recursive 'always) - (yes-or-no-p (format "Recursively %s %s? " - (if (and trash - delete-by-moving-to-trash) - "trash" - "delete") - (dired-make-relative file))))) - (if (eq recursive 'top) (setq recursive 'always)) ; Don't ask again. - (setq recursive nil)) - (delete-directory file recursive trash))) + ;; This test is equivalent to + ;; (and (file-directory-p fn) (not (file-symlink-p fn))) + ;; but more efficient + (if (not (eq t (car (file-attributes file)))) + (delete-file file trash) + (let* ((valid-answers (list "yes" "no" "!" "q" "help")) + (answer "") + (input-fn (lambda () + (setq answer + (completing-read + (format "Recursively %s %s? [yes, no, !, q, help] " + (if (and trash + delete-by-moving-to-trash) + "trash" + "delete") + (dired-make-relative file)) + valid-answers nil t)) + (when (string= answer "help") + (setq answer "") + (with-help-window "*Help*" + (with-current-buffer "*Help*" (insert dired-delete-help)))) + answer))) + (if (and recursive + (directory-files file t dired-re-no-dot) ; Not empty. + (eq recursive 'always)) + (if (eq recursive 'top) (setq recursive 'always)) ; Don't ask again. + ;; Otherwise prompt user: + (while (string= "" answer) (funcall input-fn)) + (pcase answer + ('"!" (setq recursive 'always dired-recursive-deletes recursive)) + ('"yes" (if (eq recursive 'top) (setq recursive 'always))) + ('"no" (setq recursive nil)) + ('"q" (keyboard-quit)))) + (delete-directory file recursive trash)))) (defun dired-do-flagged-delete (&optional nomessage) "In Dired, delete the files flagged for deletion. @@ -3055,6 +3080,9 @@ dired-internal-do-deletions (let* ((files (mapcar #'car l)) (count (length l)) (succ 0) + ;; Bind `dired-recursive-deletes' so that we can change it + ;; locally according with the user answer within `dired-delete-file'. + (dired-recursive-deletes dired-recursive-deletes) (trashing (and trash delete-by-moving-to-trash))) ;; canonicalize file list for pop up (setq files (nreverse (mapcar #'dired-make-relative files))) @@ -3064,6 +3092,7 @@ dired-internal-do-deletions (if trashing "Trash" "Delete") (dired-mark-prompt arg files))) (save-excursion + (catch '--delete-cancel (let ((progress-reporter (make-progress-reporter (if trashing "Trashing..." "Deleting...") @@ -3081,6 +3110,7 @@ dired-internal-do-deletions (dired-fun-in-all-buffers (file-name-directory fn) (file-name-nondirectory fn) #'dired-delete-entry fn)) + (quit (throw '--delete-cancel (message "OK, canceled"))) (error ;; catch errors from failed deletions (dired-log "%s\n" err) (setq failures (cons (car (car l)) failures))))) @@ -3091,8 +3121,7 @@ dired-internal-do-deletions (format "%d of %d deletion%s failed" (length failures) count (dired-plural-s count)) - failures)))) + failures))))) (message "(No deletions performed)"))) (dired-move-to-filename)) --8<-----------------------------cut here---------------end--------------->8--- In GNU Emacs 26.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.11) of 2017-08-04 Repository revision: d32d8d0ceaa05939bbf56a246707aed05a53385c
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.