aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTino Calancha2017-08-06 13:46:51 +0900
committerTino Calancha2017-08-06 13:46:51 +0900
commitcbea38e5c4af5386192fb9a48ef4fca5080d6561 (patch)
treee27b535d8e51591be70045289240380d2be6d4d9
parent785a4a1d52fd7da3f3169fda26841341667c1661 (diff)
downloademacs-cbea38e5c4af5386192fb9a48ef4fca5080d6561.tar.gz
emacs-cbea38e5c4af5386192fb9a48ef4fca5080d6561.zip
dired-do-delete: Allow to delete dirs recursively without prompts
* lisp/dired.el (dired-delete-file): Accept 2 additional answers: 'all', to delete all directories recursively and no prompt anymore. 'quit', to cancel 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.
-rw-r--r--doc/emacs/dired.texi8
-rw-r--r--etc/NEWS4
-rw-r--r--lisp/dired.el66
3 files changed, 60 insertions, 18 deletions
diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi
index 150ac8427ab..c1cc2f8cf96 100644
--- a/doc/emacs/dired.texi
+++ b/doc/emacs/dired.texi
@@ -236,6 +236,14 @@ Dired cannot delete directories that are nonempty. If the variable
236@code{dired-recursive-deletes} is non-@code{nil}, then Dired can 236@code{dired-recursive-deletes} is non-@code{nil}, then Dired can
237delete nonempty directories including all their contents. That can 237delete nonempty directories including all their contents. That can
238be somewhat risky. 238be somewhat risky.
239Even if you have set @code{dired-recursive-deletes} to @code{nil},
240you might want sometimes to delete recursively directories
241without being asked for confirmation for all of them. This is handy
242when you have marked many directories for deletion and you are very
243sure that all of them can safely being deleted. For every nonempty
244directory you are asked for confirmation; if you answer @code{all},
245then all the remaining directories will be deleted without more
246questions.
239 247
240@vindex delete-by-moving-to-trash 248@vindex delete-by-moving-to-trash
241 If you change the variable @code{delete-by-moving-to-trash} to 249 If you change the variable @code{delete-by-moving-to-trash} to
diff --git a/etc/NEWS b/etc/NEWS
index b72793dec08..b47bf959bed 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -611,6 +611,10 @@ paragraphs, for the purposes of bidirectional display.
611** Dired 611** Dired
612 612
613+++ 613+++
614*** You can answer 'all' in 'dired-do-delete' to delete recursively all
615remaining directories without more prompts.
616
617+++
614*** Dired supports wildcards in the directory part of the file names. 618*** Dired supports wildcards in the directory part of the file names.
615 619
616+++ 620+++
diff --git a/lisp/dired.el b/lisp/dired.el
index d04bd6fe037..0bad2562eb4 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -2981,6 +2981,14 @@ Any other value means to ask for each directory."
2981;; Match anything but `.' and `..'. 2981;; Match anything but `.' and `..'.
2982(defvar dired-re-no-dot "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*") 2982(defvar dired-re-no-dot "^\\([^.]\\|\\.\\([^.]\\|\\..\\)\\).*")
2983 2983
2984(defconst dired-delete-help
2985 "Type:
2986`yes' to delete recursively the current directory,
2987`no' to skip to next,
2988`all' to delete all remaining directories with no more questions,
2989`quit' to exit,
2990`help' to show this help message.")
2991
2984;; Delete file, possibly delete a directory and all its files. 2992;; Delete file, possibly delete a directory and all its files.
2985;; This function is useful outside of dired. One could change its name 2993;; This function is useful outside of dired. One could change its name
2986;; to e.g. recursive-delete-file and put it somewhere else. 2994;; to e.g. recursive-delete-file and put it somewhere else.
@@ -2996,23 +3004,40 @@ its possible values is:
2996 3004
2997TRASH non-nil means to trash the file instead of deleting, provided 3005TRASH non-nil means to trash the file instead of deleting, provided
2998`delete-by-moving-to-trash' (which see) is non-nil." 3006`delete-by-moving-to-trash' (which see) is non-nil."
2999 ;; This test is equivalent to 3007 ;; This test is equivalent to
3000 ;; (and (file-directory-p fn) (not (file-symlink-p fn))) 3008 ;; (and (file-directory-p fn) (not (file-symlink-p fn)))
3001 ;; but more efficient 3009 ;; but more efficient
3002 (if (not (eq t (car (file-attributes file)))) 3010 (if (not (eq t (car (file-attributes file))))
3003 (delete-file file trash) 3011 (delete-file file trash)
3004 (if (and recursive 3012 (let* ((valid-answers (list "yes" "no" "all" "quit" "help"))
3005 (directory-files file t dired-re-no-dot) ; Not empty. 3013 (answer "")
3006 (or (eq recursive 'always) 3014 (input-fn (lambda ()
3007 (yes-or-no-p (format "Recursively %s %s? " 3015 (setq answer
3008 (if (and trash 3016 (completing-read
3009 delete-by-moving-to-trash) 3017 (format "Recursively %s %s? [yes, no, all, quit, help] "
3010 "trash" 3018 (if (and trash
3011 "delete") 3019 delete-by-moving-to-trash)
3012 (dired-make-relative file))))) 3020 "trash"
3013 (if (eq recursive 'top) (setq recursive 'always)) ; Don't ask again. 3021 "delete")
3014 (setq recursive nil)) 3022 (dired-make-relative file))
3015 (delete-directory file recursive trash))) 3023 valid-answers nil t))
3024 (when (string= answer "help")
3025 (setq answer "")
3026 (with-help-window "*Help*"
3027 (with-current-buffer "*Help*" (insert dired-delete-help))))
3028 answer)))
3029 (if (and recursive
3030 (directory-files file t dired-re-no-dot) ; Not empty.
3031 (eq recursive 'always))
3032 (if (eq recursive 'top) (setq recursive 'always)) ; Don't ask again.
3033 ;; Otherwise prompt user:
3034 (while (string= "" answer) (funcall input-fn))
3035 (pcase answer
3036 ('"all" (setq recursive 'always dired-recursive-deletes recursive))
3037 ('"yes" (if (eq recursive 'top) (setq recursive 'always)))
3038 ('"no" (setq recursive nil))
3039 ('"quit" (keyboard-quit))))
3040 (delete-directory file recursive trash))))
3016 3041
3017(defun dired-do-flagged-delete (&optional nomessage) 3042(defun dired-do-flagged-delete (&optional nomessage)
3018 "In Dired, delete the files flagged for deletion. 3043 "In Dired, delete the files flagged for deletion.
@@ -3061,6 +3086,9 @@ non-empty directories is allowed."
3061 (let* ((files (mapcar #'car l)) 3086 (let* ((files (mapcar #'car l))
3062 (count (length l)) 3087 (count (length l))
3063 (succ 0) 3088 (succ 0)
3089 ;; Bind `dired-recursive-deletes' so that we can change it
3090 ;; locally according with the user answer within `dired-delete-file'.
3091 (dired-recursive-deletes dired-recursive-deletes)
3064 (trashing (and trash delete-by-moving-to-trash))) 3092 (trashing (and trash delete-by-moving-to-trash)))
3065 ;; canonicalize file list for pop up 3093 ;; canonicalize file list for pop up
3066 (setq files (nreverse (mapcar #'dired-make-relative files))) 3094 (setq files (nreverse (mapcar #'dired-make-relative files)))
@@ -3070,6 +3098,7 @@ non-empty directories is allowed."
3070 (if trashing "Trash" "Delete") 3098 (if trashing "Trash" "Delete")
3071 (dired-mark-prompt arg files))) 3099 (dired-mark-prompt arg files)))
3072 (save-excursion 3100 (save-excursion
3101 (catch '--delete-cancel
3073 (let ((progress-reporter 3102 (let ((progress-reporter
3074 (make-progress-reporter 3103 (make-progress-reporter
3075 (if trashing "Trashing..." "Deleting...") 3104 (if trashing "Trashing..." "Deleting...")
@@ -3087,6 +3116,7 @@ non-empty directories is allowed."
3087 (dired-fun-in-all-buffers 3116 (dired-fun-in-all-buffers
3088 (file-name-directory fn) (file-name-nondirectory fn) 3117 (file-name-directory fn) (file-name-nondirectory fn)
3089 #'dired-delete-entry fn)) 3118 #'dired-delete-entry fn))
3119 (quit (throw '--delete-cancel (message "OK, canceled")))
3090 (error ;; catch errors from failed deletions 3120 (error ;; catch errors from failed deletions
3091 (dired-log "%s\n" err) 3121 (dired-log "%s\n" err)
3092 (setq failures (cons (car (car l)) failures))))) 3122 (setq failures (cons (car (car l)) failures)))))
@@ -3097,7 +3127,7 @@ non-empty directories is allowed."
3097 (format "%d of %d deletion%s failed" 3127 (format "%d of %d deletion%s failed"
3098 (length failures) count 3128 (length failures) count
3099 (dired-plural-s count)) 3129 (dired-plural-s count))
3100 failures)))) 3130 failures)))))
3101 (message "(No deletions performed)"))) 3131 (message "(No deletions performed)")))
3102 (dired-move-to-filename)) 3132 (dired-move-to-filename))
3103 3133