diff options
| author | Tino Calancha | 2017-08-09 14:47:15 +0900 |
|---|---|---|
| committer | Tino Calancha | 2017-08-09 14:48:49 +0900 |
| commit | da4438e14f1c55808937872b6d651a807404daa2 (patch) | |
| tree | a7b3a8d1f8425b56071759d5b3507e1378afa585 | |
| parent | 9ecbdeeaa845a75c63210057a8a554eedc9387bf (diff) | |
| download | emacs-da4438e14f1c55808937872b6d651a807404daa2.tar.gz emacs-da4438e14f1c55808937872b6d651a807404daa2.zip | |
dired-delete-file: Dont't ask for empty dirs
* lisp/dired.el (dired--yes-no-all-quit-help): New defun.
(dired-delete-file): Use it. Dont't ask for empty dirs (Bug#27940).
* test/lisp/dired-tests.el (dired-test-with-temp-dirs):
New auxiliar macro.
(dired-test-bug27940): Add new test.
| -rw-r--r-- | lisp/dired.el | 71 | ||||
| -rw-r--r-- | test/lisp/dired-tests.el | 85 |
2 files changed, 123 insertions, 33 deletions
diff --git a/lisp/dired.el b/lisp/dired.el index 2e5b847f9b2..0455f3d1378 100644 --- a/lisp/dired.el +++ b/lisp/dired.el | |||
| @@ -2989,6 +2989,29 @@ Any other value means to ask for each directory." | |||
| 2989 | `quit' to exit, | 2989 | `quit' to exit, |
| 2990 | `help' to show this help message.") | 2990 | `help' to show this help message.") |
| 2991 | 2991 | ||
| 2992 | (defun dired--yes-no-all-quit-help (prompt &optional help-msg) | ||
| 2993 | "Ask a question with valid answers: yes, no, all, quit, help. | ||
| 2994 | PROMPT must end with '? ', for instance, 'Delete it? '. | ||
| 2995 | If optional arg HELP-MSG is non-nil, then is a message to show when | ||
| 2996 | the user answers 'help'. Otherwise, default to `dired-delete-help'." | ||
| 2997 | (let ((valid-answers (list "yes" "no" "all" "quit")) | ||
| 2998 | (answer "") | ||
| 2999 | (input-fn (lambda () | ||
| 3000 | (read-string | ||
| 3001 | (format "%s [yes, no, all, quit, help] " prompt))))) | ||
| 3002 | (setq answer (funcall input-fn)) | ||
| 3003 | (when (string= answer "help") | ||
| 3004 | (with-help-window "*Help*" | ||
| 3005 | (with-current-buffer "*Help*" | ||
| 3006 | (insert (or help-msg dired-delete-help))))) | ||
| 3007 | (while (not (member answer valid-answers)) | ||
| 3008 | (unless (string= answer "help") | ||
| 3009 | (beep) | ||
| 3010 | (message "Please answer `yes' or `no' or `all' or `quit'") | ||
| 3011 | (sleep-for 2)) | ||
| 3012 | (setq answer (funcall input-fn))) | ||
| 3013 | answer)) | ||
| 3014 | |||
| 2992 | ;; Delete file, possibly delete a directory and all its files. | 3015 | ;; Delete file, possibly delete a directory and all its files. |
| 2993 | ;; This function is useful outside of dired. One could change its name | 3016 | ;; This function is useful outside of dired. One could change its name |
| 2994 | ;; to e.g. recursive-delete-file and put it somewhere else. | 3017 | ;; to e.g. recursive-delete-file and put it somewhere else. |
| @@ -3009,39 +3032,21 @@ TRASH non-nil means to trash the file instead of deleting, provided | |||
| 3009 | ;; but more efficient | 3032 | ;; but more efficient |
| 3010 | (if (not (eq t (car (file-attributes file)))) | 3033 | (if (not (eq t (car (file-attributes file)))) |
| 3011 | (delete-file file trash) | 3034 | (delete-file file trash) |
| 3012 | (let* ((valid-answers (list "yes" "no" "all" "quit" "help")) | 3035 | (let* ((empty-dir-p (null (directory-files file t dired-re-no-dot)))) |
| 3013 | (answer "") | 3036 | (if (and recursive (not empty-dir-p)) |
| 3014 | (input-fn | 3037 | (unless (eq recursive 'always) |
| 3015 | (lambda () | 3038 | (let ((prompt |
| 3016 | (setq answer | 3039 | (format "Recursively %s %s? " |
| 3017 | (read-string | 3040 | (if (and trash delete-by-moving-to-trash) |
| 3018 | (format "Recursively %s %s? [yes, no, all, quit, help] " | 3041 | "trash" |
| 3019 | (if (and trash | 3042 | "delete") |
| 3020 | delete-by-moving-to-trash) | 3043 | (dired-make-relative file)))) |
| 3021 | "trash" | 3044 | (pcase (dired--yes-no-all-quit-help prompt) ; Prompt user. |
| 3022 | "delete") | 3045 | ('"all" (setq recursive 'always dired-recursive-deletes recursive)) |
| 3023 | (dired-make-relative file)))) | 3046 | ('"yes" (if (eq recursive 'top) (setq recursive 'always))) |
| 3024 | (when (string= answer "help") | 3047 | ('"no" (setq recursive nil)) |
| 3025 | (with-help-window "*Help*" | 3048 | ('"quit" (keyboard-quit))))) |
| 3026 | (with-current-buffer "*Help*" (insert dired-delete-help)))) | 3049 | (setq recursive nil)) ; Empty dir or recursive is nil. |
| 3027 | answer))) | ||
| 3028 | (if (and recursive | ||
| 3029 | (directory-files file t dired-re-no-dot) ; Not empty. | ||
| 3030 | (eq recursive 'always)) | ||
| 3031 | (if (eq recursive 'top) (setq recursive 'always)) ; Don't ask again. | ||
| 3032 | ;; Otherwise prompt user: | ||
| 3033 | (funcall input-fn) | ||
| 3034 | (while (not (member answer valid-answers)) | ||
| 3035 | (unless (string= answer "help") | ||
| 3036 | (beep) | ||
| 3037 | (message "Please answer `yes' or `no' or `all' or `quit'") | ||
| 3038 | (sleep-for 2)) | ||
| 3039 | (funcall input-fn)) | ||
| 3040 | (pcase answer | ||
| 3041 | ('"all" (setq recursive 'always dired-recursive-deletes recursive)) | ||
| 3042 | ('"yes" (if (eq recursive 'top) (setq recursive 'always))) | ||
| 3043 | ('"no" (setq recursive nil)) | ||
| 3044 | ('"quit" (keyboard-quit)))) | ||
| 3045 | (delete-directory file recursive trash)))) | 3050 | (delete-directory file recursive trash)))) |
| 3046 | 3051 | ||
| 3047 | (defun dired-do-flagged-delete (&optional nomessage) | 3052 | (defun dired-do-flagged-delete (&optional nomessage) |
diff --git a/test/lisp/dired-tests.el b/test/lisp/dired-tests.el index 981afdd929e..3c460d0151e 100644 --- a/test/lisp/dired-tests.el +++ b/test/lisp/dired-tests.el | |||
| @@ -358,5 +358,90 @@ | |||
| 358 | (should (equal "subdir" (dired-get-filename 'local t)))) | 358 | (should (equal "subdir" (dired-get-filename 'local t)))) |
| 359 | (delete-directory top-dir t)))) | 359 | (delete-directory top-dir t)))) |
| 360 | 360 | ||
| 361 | |||
| 362 | (defmacro dired-test-with-temp-dirs (just-empty-dirs &rest body) | ||
| 363 | "Helper macro for Bug#27940 test." | ||
| 364 | (declare (indent 1) (debug body)) | ||
| 365 | (let ((dir (make-symbol "dir")) | ||
| 366 | (ignore-funcs (make-symbol "ignore-funcs"))) | ||
| 367 | `(let* ((,dir (make-temp-file "bug27940" t)) | ||
| 368 | (dired-deletion-confirmer (lambda (_) "yes")) ; Suppress prompts. | ||
| 369 | (inhibit-message t) | ||
| 370 | (default-directory ,dir)) | ||
| 371 | (dotimes (i 5) (make-directory (format "empty-dir-%d" i))) | ||
| 372 | (unless ,just-empty-dirs | ||
| 373 | (dotimes (i 5) (make-directory (format "non-empty-%d/foo" i) 'parents))) | ||
| 374 | (make-directory "zeta-empty-dir") | ||
| 375 | (unwind-protect | ||
| 376 | (progn | ||
| 377 | ,@body) | ||
| 378 | (delete-directory ,dir t) | ||
| 379 | (kill-buffer (current-buffer)))))) | ||
| 380 | |||
| 381 | (ert-deftest dired-test-bug27940 () | ||
| 382 | "Test for http://debbugs.gnu.org/27940 ." | ||
| 383 | ;; If just empty dirs we shouln't be prompted. | ||
| 384 | (dired-test-with-temp-dirs | ||
| 385 | 'just-empty-dirs | ||
| 386 | (let (asked) | ||
| 387 | (advice-add 'dired--yes-no-all-quit-help | ||
| 388 | :override | ||
| 389 | (lambda (_) (setq asked t) "") | ||
| 390 | '((name . dired-test-bug27940-advice))) | ||
| 391 | (dired default-directory) | ||
| 392 | (dired-toggle-marks) | ||
| 393 | (dired-do-delete nil) | ||
| 394 | (unwind-protect | ||
| 395 | (progn | ||
| 396 | (should-not asked) | ||
| 397 | (should-not (dired-get-marked-files))) ; All dirs deleted. | ||
| 398 | (advice-remove 'dired--yes-no-all-quit-help 'dired-test-bug27940-advice)))) | ||
| 399 | ;; Answer yes | ||
| 400 | (dired-test-with-temp-dirs | ||
| 401 | nil | ||
| 402 | (advice-add 'dired--yes-no-all-quit-help :override (lambda (_) "yes") | ||
| 403 | '((name . dired-test-bug27940-advice))) | ||
| 404 | (dired default-directory) | ||
| 405 | (dired-toggle-marks) | ||
| 406 | (dired-do-delete nil) | ||
| 407 | (unwind-protect | ||
| 408 | (should-not (dired-get-marked-files)) ; All dirs deleted. | ||
| 409 | (advice-remove 'dired--yes-no-all-quit-help 'dired-test-bug27940-advice))) | ||
| 410 | ;; Answer no | ||
| 411 | (dired-test-with-temp-dirs | ||
| 412 | nil | ||
| 413 | (advice-add 'dired--yes-no-all-quit-help :override (lambda (_) "no") | ||
| 414 | '((name . dired-test-bug27940-advice))) | ||
| 415 | (dired default-directory) | ||
| 416 | (dired-toggle-marks) | ||
| 417 | (dired-do-delete nil) | ||
| 418 | (unwind-protect | ||
| 419 | (should (= 5 (length (dired-get-marked-files)))) ; Just the empty dirs deleted. | ||
| 420 | (advice-remove 'dired--yes-no-all-quit-help 'dired-test-bug27940-advice))) | ||
| 421 | ;; Answer all | ||
| 422 | (dired-test-with-temp-dirs | ||
| 423 | nil | ||
| 424 | (advice-add 'dired--yes-no-all-quit-help :override (lambda (_) "all") | ||
| 425 | '((name . dired-test-bug27940-advice))) | ||
| 426 | (dired default-directory) | ||
| 427 | (dired-toggle-marks) | ||
| 428 | (dired-do-delete nil) | ||
| 429 | (unwind-protect | ||
| 430 | (should-not (dired-get-marked-files)) ; All dirs deleted. | ||
| 431 | (advice-remove 'dired--yes-no-all-quit-help 'dired-test-bug27940-advice))) | ||
| 432 | ;; Answer quit | ||
| 433 | (dired-test-with-temp-dirs | ||
| 434 | nil | ||
| 435 | (advice-add 'dired--yes-no-all-quit-help :override (lambda (_) "quit") | ||
| 436 | '((name . dired-test-bug27940-advice))) | ||
| 437 | (dired default-directory) | ||
| 438 | (dired-toggle-marks) | ||
| 439 | (let ((inhibit-message t)) | ||
| 440 | (dired-do-delete nil)) | ||
| 441 | (unwind-protect | ||
| 442 | (should (= 6 (length (dired-get-marked-files)))) ; All empty dirs but zeta-empty-dir deleted. | ||
| 443 | (advice-remove 'dired--yes-no-all-quit-help 'dired-test-bug27940-advice)))) | ||
| 444 | |||
| 445 | |||
| 361 | (provide 'dired-tests) | 446 | (provide 'dired-tests) |
| 362 | ;; dired-tests.el ends here | 447 | ;; dired-tests.el ends here |