Subject: bug#46884: 27.1; Cannot run find-dired with -maxdepth

From: Allen Li <[email-masked]>
Date: Sat, 25 Jun 2022 20:54:40 -0700

I don't, but I rewrote it from scratch with a different approach.

In short, introduce a command that allows running an arbitrary find
command, and rewrite the existing find-dired on top of said command.

This hopefully sidesteps any bikeshedding.  If anyone wants any particular
command API, they can write their own command on top.  For one-off usage,
the user can build their command manually.

On Sun, Jun 19, 2022 at 4:55 PM Lars Ingebrigtsen <[email-masked]> wrote:

> Juri Linkov <[email-masked]> writes:
>
> >> Here's a second patch which I've tested by running once each for zero,
> >> one, and two prefix args.
> >> If the approach looks good, I will test more, cleanup, update the
> >> NEWS, docs, etc.
> >
> > Thanks, I've tested the second patch, and see no problems with it.
> > Only noticed that the docstring of `find-dired' mentions
> `grep-find-command'
> > instead of `find-dired'.
>
> (I'm going through old bug reports that unfortunately weren't resolved
> at the time.)
>
> Allen, do you have an updated version of the patch?
>
> --
> (domestic pets only, the antidote for overdose, milk.)
>    bloggy blog: http://lars.ingebrigtsen.no
>
From e2a9609eece317148c0d11bd5e68d541ff7060fb Mon Sep 17 00:00:00 2001
From: Allen Li <[email-masked]>
Date: Sat, 25 Jun 2022 20:17:57 -0700
Subject: [PATCH 1/2] find-dired: Factor out find-dired--escaped-ls-option

Deduplicate this logic for other future find-dired commands.

* lisp/find-dired.el (find-dired--escaped-ls-option): New function.
(find-dired): Use find-dired--escaped-ls-option.
---
 lisp/find-dired.el | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/lisp/find-dired.el b/lisp/find-dired.el
index 61e626080e..bbdf452208 100644
--- a/lisp/find-dired.el
+++ b/lisp/find-dired.el
@@ -209,13 +209,7 @@ find-dired
 			  " " 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))))
+		       (find-dired--escaped-ls-option)))
     ;; Start the find process.
     (shell-command (concat args "&") (current-buffer))
     (dired-mode dir (cdr find-ls-option))
@@ -256,6 +250,16 @@ find-dired
       (move-marker (process-mark proc) (point) (current-buffer)))
     (setq mode-line-process '(":%s"))))
 
+(defun find-dired--escaped-ls-option ()
+  "Return the car of `find-ls-option' escaped for a shell command."
+  (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)))
+
 (defun kill-find ()
   "Kill the `find' process running in the current buffer."
   (interactive)
-- 
2.36.1

From a9bc9b1c963d6b66085d264aa8907a31faeb7f90 Mon Sep 17 00:00:00 2001
From: Allen Li <[email-masked]>
Date: Sat, 25 Jun 2022 20:43:29 -0700
Subject: [PATCH 2/2] find-dired: Add find-dired-with-command

Add a command that runs and sets up the find-dired buffer with an
arbitrary find command.  Also rewrite the existing find-dired commands
using it.

The set of commands possible with find-dired is limited; the new
command allows users to run the full set of commands, but also leaves
the responsibility to the user to construct the command manually.

* lisp/find-dired.el (find-command-history): New var.
(find-dired-with-command): New command.
(find-dired): Rewritten with new command.
---
 etc/NEWS           |  7 +++++++
 lisp/find-dired.el | 52 +++++++++++++++++++++++++++++++++-------------
 2 files changed, 45 insertions(+), 14 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 01354a65f0..dab762889d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1381,6 +1381,13 @@ doesn't work on other systems.  Also see etc/PROBLEMS.
 These are used to alter an URL before using it.  By default it removes
 the common "utm_" trackers from URLs.
 
+** Find-Dired
+
+*** New command 'find-dired-with-command'.
+This enables users to run 'find-dired' with an arbitrary command,
+enabling running commands previously unsupported and also enabling new
+commands to be built on top.
+
 ** Gnus
 
 +++
diff --git a/lisp/find-dired.el b/lisp/find-dired.el
index bbdf452208..974cefdd18 100644
--- a/lisp/find-dired.el
+++ b/lisp/find-dired.el
@@ -154,6 +154,9 @@ find-args
 ;; History of find-args values entered in the minibuffer.
 (defvar find-args-history nil)
 
+(defvar find-command-history nil
+  "History of commands passed interactively to `find-dired-with-command'.")
+
 (defvar dired-sort-inhibit)
 
 ;;;###autoload
@@ -171,6 +174,37 @@ find-dired
   (interactive (list (read-directory-name "Run find in directory: " nil "" t)
 		     (read-string "Run find (with args): " find-args
 				  '(find-args-history . 1))))
+  (setq find-args args	      ; save for next interactive call
+	args (concat find-program " . "
+		     (if (string= args "")
+			 ""
+		       (concat
+			(shell-quote-argument "(")
+			" " args " "
+			(shell-quote-argument ")")
+			" "))
+		     (find-dired--escaped-ls-option)))
+  (find-dired-with-command dir args))
+
+;;;###autoload
+(defun find-dired-with-command (dir command)
+  "Run `find' and go into Dired mode on a buffer of the output.
+The user-supplied command is run after changing into DIR and should look like
+
+    find . GLOBALARGS \\( ARGS \\) -ls
+
+The car of the variable `find-ls-option' specifies what to
+use in place of \"-ls\" as the starting input.
+
+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 command: "
+                                  (cons (concat find-program
+                                                " . \\(  \\) "
+                                                (find-dired--escaped-ls-option))
+                                        (+ 1 (length find-program) (length " . \\( ")))
+				  find-command-history)))
   (let ((dired-buffers dired-buffers))
     ;; Expand DIR ("" means default-directory), and make sure it has a
     ;; trailing slash.
@@ -199,19 +233,9 @@ 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 ")")
-			  " "))
-		       (find-dired--escaped-ls-option)))
+    (setq default-directory dir)
     ;; Start the find process.
-    (shell-command (concat args "&") (current-buffer))
+    (shell-command (concat command "&") (current-buffer))
     (dired-mode dir (cdr find-ls-option))
     (let ((map (make-sparse-keymap)))
       (set-keymap-parent map (current-local-map))
@@ -220,7 +244,7 @@ find-dired
     (setq-local dired-sort-inhibit t)
     (setq-local revert-buffer-function
                 (lambda (_ignore-auto _noconfirm)
-                  (find-dired dir find-args)))
+                  (find-dired-with-command dir command)))
     ;; Set subdir-alist so that Tree Dired will work:
     (if (fboundp 'dired-simple-subdir-alist)
 	;; will work even with nested dired format (dired-nstd.el,v 1.15
@@ -240,7 +264,7 @@ find-dired
     ;; Make second line a ``find'' line in analogy to the ``total'' or
     ;; ``wildcard'' line.
     (let ((point (point)))
-      (insert "  " args "\n")
+      (insert "  " command "\n")
       (dired-insert-set-properties point (point)))
     (setq buffer-read-only t)
     (let ((proc (get-buffer-process (current-buffer))))
-- 
2.36.1