unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Tino Calancha <tino.calancha@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 27940@debbugs.gnu.org, jidanni@jidanni.org
Subject: bug#27940: Recursively delete dir34? (yes, no, all, quit)
Date: Fri, 04 Aug 2017 23:33:51 +0900	[thread overview]
Message-ID: <871sorz9kg.fsf@calancha-pc> (raw)
In-Reply-To: <834ltnxzyz.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 04 Aug 2017 15:46:28 +0300")

Eli Zaretskii <eliz@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@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






  reply	other threads:[~2017-08-04 14:33 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-03 23:26 bug#27940: Recursively delete dir34? (yes, no, all, quit) 積丹尼 Dan Jacobson
2017-08-04  8:25 ` Tino Calancha
2017-08-04  8:31   ` Eli Zaretskii
2017-08-04  9:29     ` Tino Calancha
2017-08-04  9:37       ` Tino Calancha
2017-08-04 12:46       ` Eli Zaretskii
2017-08-04 14:33         ` Tino Calancha [this message]
2017-08-04 14:54           ` Eli Zaretskii
2017-08-06  4:52             ` Tino Calancha
     [not found]               ` <87k22e9obk.fsf@ctlt579.codethink.co.uk>
2017-08-09  5:54                 ` Tino Calancha
2017-10-15 14:17                   ` Noam Postavsky
2017-10-16  5:20                     ` Tino Calancha
2017-10-16 10:36                       ` Noam Postavsky
2017-10-16 10:43                         ` Tino Calancha
2017-10-17 12:40                           ` Noam Postavsky
     [not found]         ` <<871sorz9kg.fsf@calancha-pc>
     [not found]           ` <<83tw1nwfhp.fsf@gnu.org>
2017-08-04 15:51             ` Drew Adams
2017-08-04 16:18               ` Tino Calancha
2017-08-04 16:22                 ` Drew Adams
2017-08-04 16:34                   ` Tino Calancha
     [not found] <<87o9rwxmfz.fsf@jidanni.org>

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=871sorz9kg.fsf@calancha-pc \
    --to=tino.calancha@gmail.com \
    --cc=27940@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=jidanni@jidanni.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).