From a8dce73ca0ae1482dbfb8c10a82f51529fbe1226 Mon Sep 17 00:00:00 2001 From: Allen Li Date: Fri, 12 Mar 2021 00:07:22 -0800 Subject: [PATCH] find-dired: Add command editing like rgrep The original find-dired does not allow for constructing queries like find . -maxdepth 3 \( OTHER-ARGS \) -ls * lisp/find-dired.el (find-dired): Added command editing and confirmation. --- lisp/find-dired.el | 79 +++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 25 deletions(-) diff --git a/lisp/find-dired.el b/lisp/find-dired.el index adc5672eca..d263bef706 100644 --- a/lisp/find-dired.el +++ b/lisp/find-dired.el @@ -151,13 +151,16 @@ find-dired-refine-function (defvar find-args nil "Last arguments given to `find' by \\[find-dired].") -;; History of find-args values entered in the minibuffer. -(defvar find-args-history nil) +(defvar find-args-history nil + "History list for args provided to `find-dired'.") + +(defvar find-dired-history nil + "History list for `find-dired'.") (defvar dired-sort-inhibit) ;;;###autoload -(defun find-dired (dir args) +(defun find-dired (dir &optional args confirm) "Run `find' and go into Dired mode on a buffer of the output. The command run (after changing into DIR) is essentially @@ -166,11 +169,29 @@ find-dired except that the car of the variable `find-ls-option' specifies what to use in place of \"-ls\" as the final argument. +With \\[universal-argument] prefix, you can edit the constructed shell command line +before it is executed. +With two \\[universal-argument] prefixes, directly edit and run `grep-find-command'. + Collect output in the \"*Find*\" buffer. To kill the job before -it finishes, type \\[kill-find]." - (interactive (list (read-directory-name "Run find in directory: " nil "" t) - (read-string "Run find (with args): " find-args - '(find-args-history . 1)))) +it finishes, type \\[kill-find]. + +When called programmatically and ARGS is nil, DIR is expected to +specify a command to run. + +If CONFIRM is non-nil, the user will be given an opportunity to edit the +command before it's run." + (interactive + (cond + ((and grep-find-command (equal current-prefix-arg '(16))) + (list (read-from-minibuffer "Run: " (cons (format "%s . -ls" find-program) + (+ (length find-program) 3)) + nil nil 'find-dired-history))) + (t (let* ((dir (read-directory-name "Run find in directory: " nil "" t)) + (args (read-string "Run find (with args): " find-args + '(find-args-history . 1))) + (confirm (equal current-prefix-arg '(4)))) + (list dir args confirm))))) (let ((dired-buffers dired-buffers)) ;; Expand DIR ("" means default-directory), and make sure it has a ;; trailing slash. @@ -199,23 +220,31 @@ find-dired (kill-all-local-variables) (setq buffer-read-only nil) (erase-buffer) - (setq default-directory dir - find-args args ; save for next interactive call - args (concat find-program " . " - (if (string= args "") - "" - (concat - (shell-quote-argument "(") - " " args " " - (shell-quote-argument ")") - " ")) - (if (string-match "\\`\\(.*\\) {} \\(\\\\;\\|\\+\\)\\'" - (car find-ls-option)) - (format "%s %s %s" - (match-string 1 (car find-ls-option)) - (shell-quote-argument "{}") - find-exec-terminator) - (car find-ls-option)))) + (setq default-directory dir) + (if (null args) + (setq args dir) + (setq find-args args ; save for next interactive call + args (concat find-program " . " + (if (string= args "") + "" + (concat + (shell-quote-argument "(") + " " args " " + (shell-quote-argument ")") + " ")) + (if (string-match "\\`\\(.*\\) {} \\(\\\\;\\|\\+\\)\\'" + (car find-ls-option)) + (format "%s %s %s" + (match-string 1 (car find-ls-option)) + (shell-quote-argument "{}") + find-exec-terminator) + (car find-ls-option))))) + (if confirm + (setq args + (read-from-minibuffer "Confirm: " + args nil nil 'find-dired-history)) + (add-to-history 'find-dired-history args)) + ;; Start the find process. (shell-command (concat args "&") (current-buffer)) (dired-mode dir (cdr find-ls-option)) @@ -393,7 +422,7 @@ find-dired-sentinel ;; will stay around until M-x `list-processes'. (delete-process proc) (force-mode-line-update)))) - (message "find-dired %s finished." buf)))) + (message "find-dired %s finished." buf)))) (defun find-dired-sort-by-filename () "Sort entries in *Find* buffer by file name lexicographically." -- 2.30.2