* bug#46884: 27.1; Cannot run find-dired with -maxdepth
@ 2021-03-03 1:12 Allen Li
2021-03-03 1:20 ` bug#46884: [PATCH] " Allen Li
2021-03-03 1:34 ` bug#46884: [External] : bug#46884: " Drew Adams
0 siblings, 2 replies; 29+ messages in thread
From: Allen Li @ 2021-03-03 1:12 UTC (permalink / raw
To: 46884
Due to how find-dired handles is args, it is not possible to pass
-maxdepth to the find command. For reference, find-dired runs the find
command liks this:
find . \( ARGS \) -ls
-maxdepth must be used like this:
find . -maxdepth 3 \( ARGS \) -ls
In GNU Emacs 27.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.22, cairo version 1.17.3)
of 2020-08-28 built on juergen
Windowing system distributor 'The X.Org Foundation', version 11.0.12010000
System Description: Arch Linux
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-03 1:12 bug#46884: 27.1; Cannot run find-dired with -maxdepth Allen Li
@ 2021-03-03 1:20 ` Allen Li
2021-03-03 3:38 ` Allen Li
2021-03-03 6:15 ` Eli Zaretskii
2021-03-03 1:34 ` bug#46884: [External] : bug#46884: " Drew Adams
1 sibling, 2 replies; 29+ messages in thread
From: Allen Li @ 2021-03-03 1:20 UTC (permalink / raw
To: 46884
[-- Attachment #1.1: Type: text/plain, Size: 348 bytes --]
Some additional context: I'm not asking for find-dired to support -maxdepth
necessarily, but the way find-dired is structured makes it impossible to
reuse any of the code to write a command that could support -maxdepth.
I attached a patch pulling most of the find-dired logic into a
find-dired-unescaped function so that it can be readily reused.
[-- Attachment #1.2: Type: text/html, Size: 398 bytes --]
[-- Attachment #2: 0001-find-dired-Split-out-find-dired-unescaped.patch --]
[-- Type: text/x-patch, Size: 3184 bytes --]
From 7c2335ff5140a13578b03d3b147381c111bdd528 Mon Sep 17 00:00:00 2001
From: Allen Li <darkfeline@felesatra.moe>
Date: Tue, 2 Mar 2021 14:24:16 -0800
Subject: [PATCH] find-dired: Split out find-dired-unescaped
The original find-dired does not allow for constructing queries like
find . -maxdepth 3 \( OTHER-ARGS \) -ls
It also makes the find-dired logic essential impossible to reuse.
The new find-dired-unescaped can by used to construct more interesting
queries.
* lisp/find-dired.el (find-dired-unescaped): Added new function.
(find-dired): Rewritten to use find-dired-unescaped.
---
etc/NEWS | 4 ++++
lisp/find-dired.el | 30 +++++++++++++++++++++---------
2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS
index 73f136cfa7..3a3a086373 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -653,6 +653,10 @@ keys, add the following to your init file:
(global-set-key "\C-x\C-j" nil)
(global-set-key "\C-x4\C-j" nil)
+---
+*** New function 'find-dired-unescaped' enables user code to run more
+complicated find commands.
+
** Change Logs and VC
*** More VC commands can be used from non-file buffers.
diff --git a/lisp/find-dired.el b/lisp/find-dired.el
index adc5672eca..f0aa764471 100644
--- a/lisp/find-dired.el
+++ b/lisp/find-dired.el
@@ -171,6 +171,25 @@ 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))))
+ (find-dired-with-args dir (if (string= args "")
+ ""
+ (concat
+ (shell-quote-argument "(")
+ " " args " "
+ (shell-quote-argument ")")
+ " "))))
+
+;;;###autoload
+(defun find-dired-unescaped (dir args)
+ "Run `find' and go into Dired mode on a buffer of the output.
+The command run (after changing into DIR) is essentially
+
+ find . ARGS -ls
+
+except that the car of the variable `find-ls-option' specifies what to
+use in place of \"-ls\" as the final argument.
+
+This function can be used to build more specialized commands using `find-dired'."
(let ((dired-buffers dired-buffers))
;; Expand DIR ("" means default-directory), and make sure it has a
;; trailing slash.
@@ -200,15 +219,8 @@ find-dired
(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 ")")
- " "))
+ args
(if (string-match "\\`\\(.*\\) {} \\(\\\\;\\|\\+\\)\\'"
(car find-ls-option))
(format "%s %s %s"
@@ -393,7 +405,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.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* bug#46884: [External] : bug#46884: 27.1; Cannot run find-dired with -maxdepth
2021-03-03 1:12 bug#46884: 27.1; Cannot run find-dired with -maxdepth Allen Li
2021-03-03 1:20 ` bug#46884: [PATCH] " Allen Li
@ 2021-03-03 1:34 ` Drew Adams
1 sibling, 0 replies; 29+ messages in thread
From: Drew Adams @ 2021-03-03 1:34 UTC (permalink / raw
To: Allen Li, 46884@debbugs.gnu.org
> Due to how find-dired handles is args, it is not
> possible to pass -maxdepth to the find command.
I'm not sure this is germane, but FWIW, my mini-library
`find-dired+.el' enhances `find-dired' by providing
optional args, and two of those specify the min and max
depth limits.
If this is relevant, and corresponds to the requested
feature, Emacs could be improved similarly.
Maybe give it a try, and see if it offers what you
request.
https://www.emacswiki.org/emacs/download/find-dired%2b.el
Here's the doc string;
,----
| find-dired is an interactive compiled Lisp function in
| 'find-dired+.el'.
|
| (find-dired DIR ARGS &optional DEPTH-LIMITS EXCLUDED-PATHS)
|
| Run `find' and put its output in a buffer in Dired Mode.
| Then run `find-dired-hook' and `dired-after-readin-hook'.
| The `find' command run (after changing into DIR) is essentially this,
| where LS-SWITCHES is `(car find-ls-option)':
|
| find . \( ARGS \) LS-SWITCHES
|
| Optional args:
|
| * DEPTH-LIMITS: Minimum and maximum depths: (MIN-DEPTH MAX-DEPTH).
| * EXCLUDED-PATHS: Strings matching paths to be excluded.
| Uses `find' switch `-path'.
|
| When both optional args are non-nil, the `find' command run is this:
|
| find . -mindepth MIN-DEPTH -maxdepth MAX-DEPTH
| \( -path EXCLUDE1 -o -path EXCLUDE2 ... \)
| -prune -o \( ARGS \) LS-SWITCHES
|
| where EXCLUDE1, EXCLUDE2... are the EXCLUDED-PATHS, but shell-quoted.
`----
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-03 1:20 ` bug#46884: [PATCH] " Allen Li
@ 2021-03-03 3:38 ` Allen Li
2021-03-03 6:28 ` Eli Zaretskii
2021-03-03 6:15 ` Eli Zaretskii
1 sibling, 1 reply; 29+ messages in thread
From: Allen Li @ 2021-03-03 3:38 UTC (permalink / raw
To: 46884
[-- Attachment #1.1: Type: text/plain, Size: 1330 bytes --]
On Wed, Mar 3, 2021 at 1:20 AM Allen Li <darkfeline@felesatra.moe> wrote:
>
> Some additional context: I'm not asking for find-dired to support
-maxdepth necessarily, but the way find-dired is structured makes it
impossible to reuse any of the code to write a command that could support
-maxdepth.
>
> I attached a patch pulling most of the find-dired logic into a
find-dired-unescaped function so that it can be readily reused.
I made a mistake in my initial analysis. find (at least the version I have)
allows one to pass global options such as -maxdepth like so:
find . \( -maxdepth 3 ARGS \) -ls
However, find will print a warning message as this usage is not recommended.
Also, I realized that my previous patch, while functional, is awkward since
it exists solely to allow users to specify global options
(based on the discussion on #27456, I believe all other find functionality
should be possible with find-dired).
I have made a new patch adding an optional parameter to find-dired for
passing such global options to find.
Aside: there is a discussion at #32668 about adding a similar command line
editing feature like rgrep
I'm not fond of that as it is impossible to use programmatically and
interacts poorly (read: not at all)
with `repeat-complex-command'
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27456
[-- Attachment #1.2: Type: text/html, Size: 1818 bytes --]
[-- Attachment #2: 0001-find-dired-Add-global-args-to-find-dired.patch --]
[-- Type: text/x-patch, Size: 2418 bytes --]
From 3831be3067f97734137134e40e3e4467abd49816 Mon Sep 17 00:00:00 2001
From: Allen Li <darkfeline@felesatra.moe>
Date: Tue, 2 Mar 2021 14:24:16 -0800
Subject: [PATCH] find-dired: Add global-args to find-dired
The original find-dired does not allow for constructing queries like
find . -maxdepth 3 \( OTHER-ARGS \) -ls
* lisp/find-dired.el (find-dired): Added optional parameter.
---
etc/NEWS | 4 ++++
lisp/find-dired.el | 10 ++++++----
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS
index 73f136cfa7..40f79f8232 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -653,6 +653,10 @@ keys, add the following to your init file:
(global-set-key "\C-x\C-j" nil)
(global-set-key "\C-x4\C-j" nil)
+---
+*** Optional 'global-args' parameter added to 'find-dired'.
+This allows passing find global options like -maxdepth.
+
** Change Logs and VC
*** More VC commands can be used from non-file buffers.
diff --git a/lisp/find-dired.el b/lisp/find-dired.el
index adc5672eca..fc35cccddd 100644
--- a/lisp/find-dired.el
+++ b/lisp/find-dired.el
@@ -157,14 +157,15 @@ find-args-history
(defvar dired-sort-inhibit)
;;;###autoload
-(defun find-dired (dir args)
+(defun find-dired (dir args &optional global-args)
"Run `find' and go into Dired mode on a buffer of the output.
The command run (after changing into DIR) is essentially
- find . \\( ARGS \\) -ls
+ find . GLOBAL-ARGS \\( ARGS \\) -ls
except that the car of the variable `find-ls-option' specifies what to
-use in place of \"-ls\" as the final argument.
+use in place of \"-ls\" as the final argument. GLOBAL-ARGS is empty
+when called interactively.
Collect output in the \"*Find*\" buffer. To kill the job before
it finishes, type \\[kill-find]."
@@ -202,6 +203,7 @@ find-dired
(setq default-directory dir
find-args args ; save for next interactive call
args (concat find-program " . "
+ (if global-args global-args "")
(if (string= args "")
""
(concat
@@ -393,7 +395,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.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-03 1:20 ` bug#46884: [PATCH] " Allen Li
2021-03-03 3:38 ` Allen Li
@ 2021-03-03 6:15 ` Eli Zaretskii
1 sibling, 0 replies; 29+ messages in thread
From: Eli Zaretskii @ 2021-03-03 6:15 UTC (permalink / raw
To: Allen Li; +Cc: 46884
> From: Allen Li <darkfeline@felesatra.moe>
> Date: Wed, 3 Mar 2021 01:20:45 +0000
>
> I attached a patch pulling most of the find-dired logic into a find-dired-unescaped function so that it can be
> readily reused.
Thanks, but I think a better way for adding such a feature to
find-dired would be to introduce an additional defcustom, by default
nil, that will specify 'find' options to be inserted into the 'find'
command line between "." and "\( ARGS \)". This would allow users to
specify any switch, not just -maxdepth.
Bonus points for arranging for prompting the user to supply those
options to 'find' when find-dired is invoked with a prefix argument,
so that one-off uses of such options could be easier and more
lightweight.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-03 3:38 ` Allen Li
@ 2021-03-03 6:28 ` Eli Zaretskii
2021-03-03 8:22 ` Allen Li
0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2021-03-03 6:28 UTC (permalink / raw
To: Allen Li; +Cc: 46884
> From: Allen Li <darkfeline@felesatra.moe>
> Date: Wed, 3 Mar 2021 03:38:49 +0000
>
> -(defun find-dired (dir args)
> +(defun find-dired (dir args &optional global-args)
> "Run `find' and go into Dired mode on a buffer of the output.
> The command run (after changing into DIR) is essentially
>
> - find . \\( ARGS \\) -ls
> + find . GLOBAL-ARGS \\( ARGS \\) -ls
>
> except that the car of the variable `find-ls-option' specifies what to
> -use in place of \"-ls\" as the final argument.
> +use in place of \"-ls\" as the final argument. GLOBAL-ARGS is empty
> +when called interactively.
This is okay, IMO, but it would be better to allow the user to specify
GLOBAL-ARGS interactively if the user invokes the command with a
prefix argument.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-03 6:28 ` Eli Zaretskii
@ 2021-03-03 8:22 ` Allen Li
2021-03-03 8:55 ` Eli Zaretskii
` (2 more replies)
0 siblings, 3 replies; 29+ messages in thread
From: Allen Li @ 2021-03-03 8:22 UTC (permalink / raw
To: Eli Zaretskii; +Cc: 46884
[-- Attachment #1: Type: text/plain, Size: 1708 bytes --]
On Wed, Mar 3, 2021 at 6:28 AM Eli Zaretskii <eliz@gnu.org> wrote:
> > From: Allen Li <darkfeline@felesatra.moe>
> > Date: Wed, 3 Mar 2021 03:38:49 +0000
> >
> > -(defun find-dired (dir args)
> > +(defun find-dired (dir args &optional global-args)
> > "Run `find' and go into Dired mode on a buffer of the output.
> > The command run (after changing into DIR) is essentially
> >
> > - find . \\( ARGS \\) -ls
> > + find . GLOBAL-ARGS \\( ARGS \\) -ls
> >
> > except that the car of the variable `find-ls-option' specifies what to
> > -use in place of \"-ls\" as the final argument.
> > +use in place of \"-ls\" as the final argument. GLOBAL-ARGS is empty
> > +when called interactively.
>
> This is okay, IMO, but it would be better to allow the user to specify
> GLOBAL-ARGS interactively if the user invokes the command with a
> prefix argument.
>
How would that interact with find-args-history? I could create a separate
history variable, but then it's annoying how the two histories are
separate, as args and global-args together form one query. I decided to
punt on that issue until someone actually has a use case for providing
global-args interactively. I would use global-args infrequently enough
that I would rather call find-dired via M-x and iterate on getting the
command right that way, than try to call find-dired interactively
repeatedly with a universal prefix arg and navigating the history for both
the completing-reads for args and global-args separately. Or I would add
the -maxdepth flag to the args and tolerate the warning in the output.
Actually, my current use case is calling find-dired from Emacs Lisp code
(not interactively) where I want to avoid the warning.
[-- Attachment #2: Type: text/html, Size: 2152 bytes --]
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-03 8:22 ` Allen Li
@ 2021-03-03 8:55 ` Eli Zaretskii
2021-03-04 4:50 ` Allen Li
2021-03-03 9:03 ` Juri Linkov
2021-03-03 15:42 ` bug#46884: [External] : " Drew Adams
2 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2021-03-03 8:55 UTC (permalink / raw
To: Allen Li; +Cc: 46884
> From: Allen Li <darkfeline@felesatra.moe>
> Date: Wed, 3 Mar 2021 08:22:23 +0000
> Cc: 46884@debbugs.gnu.org
>
> This is okay, IMO, but it would be better to allow the user to specify
> GLOBAL-ARGS interactively if the user invokes the command with a
> prefix argument.
>
> How would that interact with find-args-history?
Sorry, I don't understand the question. What does prefix arg have to
do with history? Maybe I'm missing something.
> Actually, my current use case is calling find-dired from
> Emacs Lisp code (not interactively) where I want to avoid the warning.
I understand, but my hope is we could come up with something slightly
more general than just your use case.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-03 8:22 ` Allen Li
2021-03-03 8:55 ` Eli Zaretskii
@ 2021-03-03 9:03 ` Juri Linkov
2021-03-03 15:42 ` bug#46884: [External] : " Drew Adams
2 siblings, 0 replies; 29+ messages in thread
From: Juri Linkov @ 2021-03-03 9:03 UTC (permalink / raw
To: Allen Li; +Cc: 46884
> This is okay, IMO, but it would be better to allow the user to specify
> GLOBAL-ARGS interactively if the user invokes the command with a
> prefix argument.
>
> How would that interact with find-args-history?
It could interact the same way as 'C-u rgrep' interacts with grep-find-history.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [External] : bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-03 8:22 ` Allen Li
2021-03-03 8:55 ` Eli Zaretskii
2021-03-03 9:03 ` Juri Linkov
@ 2021-03-03 15:42 ` Drew Adams
2021-03-03 16:20 ` Eli Zaretskii
2 siblings, 1 reply; 29+ messages in thread
From: Drew Adams @ 2021-03-03 15:42 UTC (permalink / raw
To: Allen Li, Eli Zaretskii; +Cc: 46884@debbugs.gnu.org
>> This is okay, IMO, but it would be better to allow
>> the user to specify GLOBAL-ARGS interactively if
>> the user invokes the command with a prefix argument.
>
> ... I would rather call find-dired via M-x and iterate
> on getting the command right that way, than try to call
> find-dired interactively repeatedly with a universal
> prefix arg...
I guess no one has bothered to try the code I provided...
I agree with Allen about not providing special
interactive support for things like max-depth.
`find-dired' has the property that what you specify
is available as default for the next time you use it.
That helps with this question of interactive support,
I think.
Remember that `find' pretty much has its own language.
Users of `find' generally need to be familiar with
that language, more or less. Emacs can provide some
convenience, however.
The code I pointed to already does what this bug
requests, I think - does it not? And it does so for
`find-dired', `find-name-dired', `find-grep-dired',
and a new command, `find-time-dired'.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [External] : bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-03 15:42 ` bug#46884: [External] : " Drew Adams
@ 2021-03-03 16:20 ` Eli Zaretskii
0 siblings, 0 replies; 29+ messages in thread
From: Eli Zaretskii @ 2021-03-03 16:20 UTC (permalink / raw
To: Drew Adams; +Cc: 46884, darkfeline
> From: Drew Adams <drew.adams@oracle.com>
> CC: "46884@debbugs.gnu.org" <46884@debbugs.gnu.org>
> Date: Wed, 3 Mar 2021 15:42:59 +0000
>
> I agree with Allen about not providing special
> interactive support for things like max-depth.
There was never such a suggestion. It's a misunderstanding if you
think such a proposal was on the table.
> `find-dired' has the property that what you specify
> is available as default for the next time you use it.
> That helps with this question of interactive support,
> I think.
Assuming the user invokes the command several times in the same
session. But that isn't a given, not at all. For one-off
invocations, having to set a variable is a nuisance. Compare with
"C-x d", for example.
> Remember that `find' pretty much has its own language.
> Users of `find' generally need to be familiar with
> that language, more or less.
I _am_ familiar with that language. So for me and others like me,
being able to specify command-line options in one-off invocations is a
boon.
Of course, if I'm the only one interested in such a feature, so be it.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-03 8:55 ` Eli Zaretskii
@ 2021-03-04 4:50 ` Allen Li
2021-03-04 9:35 ` Juri Linkov
2021-03-04 13:53 ` bug#46884: [PATCH] " Eli Zaretskii
0 siblings, 2 replies; 29+ messages in thread
From: Allen Li @ 2021-03-04 4:50 UTC (permalink / raw
To: Eli Zaretskii; +Cc: 46884
Eli Zaretskii <eliz@gnu.org> writes:
>> From: Allen Li <darkfeline@felesatra.moe>
>>
>> This is okay, IMO, but it would be better to allow the user to specify
>> GLOBAL-ARGS interactively if the user invokes the command with a
>> prefix argument.
>>
>> How would that interact with find-args-history?
>
> Sorry, I don't understand the question. What does prefix arg have to
> do with history? Maybe I'm missing something.
Currently, `find-dired' stores the `completing-read' history for `args' in
`find-args-history'. It also stores the value for `args' in `find-args'
to use as the default for the next `find-dired' interactive call.
If we were to make `global-args' accessible interactively, how would the
history for it be stored? The obvious solution would be to add a
completing-read for `global-args' and create `find-global-args-history'
and `find-global-args' variables to be treated similarly to
`find-args-history' and `find-args' are now.
There are two issues with this.
First, consider what the user would do if they want to repeat a
`find-dired' with `global-args' three calls in the past:
C-u M-x find-dired RET
some/directory RET
M-p M-p M-p RET ; going back three items in the history for args
M-p M-p M-p RET ; going back three items in the history for global-args
This is a poor user experience.
Second, if the user mistakenly omits the C-u, then they might run a
previous command without the global-args that were supplied.
Consider if the user runs find-dired like so:
C-u M-x find-dired RET
some/dir RET
-some -query RET
-maxdepth 3 RET
Then the user wants to repeat the query for another directory:
M-x find-dired RET
other/dir RET
M-p RET ; get previous input, M-p can be omitted since there's a default
Because the user didn't supply the C-u, the "-maxdepth 3" is omitted.
Even though it was the user's intent to repeat the last query, the user
is now running a fundamentally different query. Again, this is a poor
user experience.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-04 4:50 ` Allen Li
@ 2021-03-04 9:35 ` Juri Linkov
2021-03-05 3:21 ` Allen Li
2021-03-04 13:53 ` bug#46884: [PATCH] " Eli Zaretskii
1 sibling, 1 reply; 29+ messages in thread
From: Juri Linkov @ 2021-03-04 9:35 UTC (permalink / raw
To: Allen Li; +Cc: 46884
> Second, if the user mistakenly omits the C-u, then they might run a
> previous command without the global-args that were supplied.
>
> Consider if the user runs find-dired like so:
>
> C-u M-x find-dired RET
> some/dir RET
> -some -query RET
> -maxdepth 3 RET
>
> Then the user wants to repeat the query for another directory:
>
> M-x find-dired RET
> other/dir RET
> M-p RET ; get previous input, M-p can be omitted since there's a default
>
> Because the user didn't supply the C-u, the "-maxdepth 3" is omitted.
> Even though it was the user's intent to repeat the last query, the user
> is now running a fundamentally different query. Again, this is a poor
> user experience.
Shouldn't it be compatible with 'rgrep', so 'C-u M-x find-dired' will read
the whole constructed command line where the user can add more args,
and 'C-u C-u M-x find-dired' will rerun the same command in another directory.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-04 4:50 ` Allen Li
2021-03-04 9:35 ` Juri Linkov
@ 2021-03-04 13:53 ` Eli Zaretskii
1 sibling, 0 replies; 29+ messages in thread
From: Eli Zaretskii @ 2021-03-04 13:53 UTC (permalink / raw
To: Allen Li; +Cc: 46884
> From: Allen Li <darkfeline@felesatra.moe>
> Cc: 46884@debbugs.gnu.org
> Date: Wed, 03 Mar 2021 20:50:23 -0800
>
> Eli Zaretskii <eliz@gnu.org> writes:
> >> From: Allen Li <darkfeline@felesatra.moe>
> >>
> >> This is okay, IMO, but it would be better to allow the user to specify
> >> GLOBAL-ARGS interactively if the user invokes the command with a
> >> prefix argument.
> >>
> >> How would that interact with find-args-history?
> >
> > Sorry, I don't understand the question. What does prefix arg have to
> > do with history? Maybe I'm missing something.
>
> Currently, `find-dired' stores the `completing-read' history for `args' in
> `find-args-history'. It also stores the value for `args' in `find-args'
> to use as the default for the next `find-dired' interactive call.
>
> If we were to make `global-args' accessible interactively, how would the
> history for it be stored?
Just take what the user types for global-args and add it to the
history, I'd say. I think this would solve all the problems you
mention. Or what am I missing?
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-04 9:35 ` Juri Linkov
@ 2021-03-05 3:21 ` Allen Li
2021-03-05 7:27 ` Eli Zaretskii
0 siblings, 1 reply; 29+ messages in thread
From: Allen Li @ 2021-03-05 3:21 UTC (permalink / raw
To: Juri Linkov; +Cc: 46884
Juri Linkov <juri@linkov.net> writes:
> Shouldn't it be compatible with 'rgrep', so 'C-u M-x find-dired' will read
> the whole constructed command line where the user can add more args,
> and 'C-u C-u M-x find-dired' will rerun the same command in another directory.
The way rgrep works right now is very different from how find-dired
works right now:
(rgrep REGEXP &optional FILES DIR CONFIRM)
"When called programmatically and FILES is nil, REGEXP is expected
to specify a command to run."
For comparison:
(find-dired DIR ARGS)
I guess we could make ARGS optional and overload DIR to take a command?
What do you think, Eli?
The new signature would look like:
(find-dired DIR &optional ARGS CONFIRM)
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-05 3:21 ` Allen Li
@ 2021-03-05 7:27 ` Eli Zaretskii
2021-03-12 8:08 ` Allen Li
0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2021-03-05 7:27 UTC (permalink / raw
To: Allen Li; +Cc: 46884, juri
> From: Allen Li <darkfeline@felesatra.moe>
> Cc: Eli Zaretskii <eliz@gnu.org>, 46884@debbugs.gnu.org
> Date: Thu, 04 Mar 2021 19:21:39 -0800
>
> For comparison:
>
> (find-dired DIR ARGS)
>
> I guess we could make ARGS optional and overload DIR to take a command?
> What do you think, Eli?
>
> The new signature would look like:
>
> (find-dired DIR &optional ARGS CONFIRM)
Sounds fine, I think, but could you post a more detailed proposal, or
show a patch to that effect?
Thanks.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-05 7:27 ` Eli Zaretskii
@ 2021-03-12 8:08 ` Allen Li
2021-03-12 15:49 ` bug#46884: [External] : " Drew Adams
2021-03-13 9:46 ` Eli Zaretskii
0 siblings, 2 replies; 29+ messages in thread
From: Allen Li @ 2021-03-12 8:08 UTC (permalink / raw
To: Eli Zaretskii; +Cc: 46884, Juri Linkov
[-- Attachment #1.1: Type: text/plain, Size: 636 bytes --]
Attached patch, does this approach look good?
On Fri, Mar 5, 2021 at 7:27 AM Eli Zaretskii <eliz@gnu.org> wrote:
> > From: Allen Li <darkfeline@felesatra.moe>
> > Cc: Eli Zaretskii <eliz@gnu.org>, 46884@debbugs.gnu.org
> > Date: Thu, 04 Mar 2021 19:21:39 -0800
> >
> > For comparison:
> >
> > (find-dired DIR ARGS)
> >
> > I guess we could make ARGS optional and overload DIR to take a command?
> > What do you think, Eli?
> >
> > The new signature would look like:
> >
> > (find-dired DIR &optional ARGS CONFIRM)
>
> Sounds fine, I think, but could you post a more detailed proposal, or
> show a patch to that effect?
>
> Thanks.
>
[-- Attachment #1.2: Type: text/html, Size: 1138 bytes --]
[-- Attachment #2: 0001-find-dired-Add-global-args-to-find-dired.patch --]
[-- Type: text/x-patch, Size: 2418 bytes --]
From 3831be3067f97734137134e40e3e4467abd49816 Mon Sep 17 00:00:00 2001
From: Allen Li <darkfeline@felesatra.moe>
Date: Tue, 2 Mar 2021 14:24:16 -0800
Subject: [PATCH] find-dired: Add global-args to find-dired
The original find-dired does not allow for constructing queries like
find . -maxdepth 3 \( OTHER-ARGS \) -ls
* lisp/find-dired.el (find-dired): Added optional parameter.
---
etc/NEWS | 4 ++++
lisp/find-dired.el | 10 ++++++----
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS
index 73f136cfa7..40f79f8232 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -653,6 +653,10 @@ keys, add the following to your init file:
(global-set-key "\C-x\C-j" nil)
(global-set-key "\C-x4\C-j" nil)
+---
+*** Optional 'global-args' parameter added to 'find-dired'.
+This allows passing find global options like -maxdepth.
+
** Change Logs and VC
*** More VC commands can be used from non-file buffers.
diff --git a/lisp/find-dired.el b/lisp/find-dired.el
index adc5672eca..fc35cccddd 100644
--- a/lisp/find-dired.el
+++ b/lisp/find-dired.el
@@ -157,14 +157,15 @@ find-args-history
(defvar dired-sort-inhibit)
;;;###autoload
-(defun find-dired (dir args)
+(defun find-dired (dir args &optional global-args)
"Run `find' and go into Dired mode on a buffer of the output.
The command run (after changing into DIR) is essentially
- find . \\( ARGS \\) -ls
+ find . GLOBAL-ARGS \\( ARGS \\) -ls
except that the car of the variable `find-ls-option' specifies what to
-use in place of \"-ls\" as the final argument.
+use in place of \"-ls\" as the final argument. GLOBAL-ARGS is empty
+when called interactively.
Collect output in the \"*Find*\" buffer. To kill the job before
it finishes, type \\[kill-find]."
@@ -202,6 +203,7 @@ find-dired
(setq default-directory dir
find-args args ; save for next interactive call
args (concat find-program " . "
+ (if global-args global-args "")
(if (string= args "")
""
(concat
@@ -393,7 +395,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.1
^ permalink raw reply related [flat|nested] 29+ messages in thread
* bug#46884: [External] : bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-12 8:08 ` Allen Li
@ 2021-03-12 15:49 ` Drew Adams
2021-03-13 0:42 ` Allen Li
2021-03-13 9:46 ` Eli Zaretskii
1 sibling, 1 reply; 29+ messages in thread
From: Drew Adams @ 2021-03-12 15:49 UTC (permalink / raw
To: Allen Li, Eli Zaretskii; +Cc: 46884@debbugs.gnu.org, Juri Linkov
> Attached patch, does this approach look good?
What did you find wrong or missing with the
code I cited? It accepts DEPTH-LIMITS and
EXCLUDED-PATHS as optional args.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [External] : bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-12 15:49 ` bug#46884: [External] : " Drew Adams
@ 2021-03-13 0:42 ` Allen Li
2021-03-13 1:09 ` Drew Adams
0 siblings, 1 reply; 29+ messages in thread
From: Allen Li @ 2021-03-13 0:42 UTC (permalink / raw
To: Drew Adams; +Cc: Phil Sainty, 46884@debbugs.gnu.org, Juri Linkov
Drew Adams <drew.adams@oracle.com> writes:
>> Attached patch, does this approach look good?
>
> What did you find wrong or missing with the
> code I cited? It accepts DEPTH-LIMITS and
> EXCLUDED-PATHS as optional args.
Personally, I find it weirdly specialized and incomplete. There are
many global options beside -mindepth and -maxdepth; your version
supports none of those options. There is also no need to support
EXCLUDED-PATHS separately; that can already be accomplished with the
current find-dired API. I prefer a more flexible, general API, which is
the current rgrep approach proposed by Juri and Phil on another bug [1].
There's also another bug open which can be closed if we adopt the rgrep
approach [2].
[1]: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27456
[2]: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=32668
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [External] : bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-13 0:42 ` Allen Li
@ 2021-03-13 1:09 ` Drew Adams
0 siblings, 0 replies; 29+ messages in thread
From: Drew Adams @ 2021-03-13 1:09 UTC (permalink / raw
To: Allen Li; +Cc: Phil Sainty, 46884@debbugs.gnu.org, Juri Linkov
> > What did you find wrong or missing with the
> > code I cited? It accepts DEPTH-LIMITS and
> > EXCLUDED-PATHS as optional args.
>
> Personally, I find it weirdly specialized and incomplete.
I see. It has the merit, at least, of having
actually been requested by users (of find-dired+).
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-12 8:08 ` Allen Li
2021-03-12 15:49 ` bug#46884: [External] : " Drew Adams
@ 2021-03-13 9:46 ` Eli Zaretskii
2021-03-13 9:58 ` Andreas Schwab
2021-03-13 21:38 ` Allen Li
1 sibling, 2 replies; 29+ messages in thread
From: Eli Zaretskii @ 2021-03-13 9:46 UTC (permalink / raw
To: Allen Li; +Cc: 46884, juri
> From: Allen Li <darkfeline@felesatra.moe>
> Date: Fri, 12 Mar 2021 08:08:55 +0000
> Cc: Juri Linkov <juri@linkov.net>, 46884@debbugs.gnu.org
>
> Attached patch, does this approach look good?
I guess my suggestion to additionally allow specification of
GLOBAL-ARGS interactively (via prefix arg) got voted down?
> +---
> +*** Optional 'global-args' parameter added to 'find-dired'.
> +This allows passing find global options like -maxdepth.
"find" should be in quotes: 'find'
> @@ -202,6 +203,7 @@ find-dired
> (setq default-directory dir
> find-args args ; save for next interactive call
> args (concat find-program " . "
> + (if global-args global-args "")
'concat' knows how to handle nil arguments, so you don't need the
empty string alternative here. Just (if global-args global-args)
should do.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-13 9:46 ` Eli Zaretskii
@ 2021-03-13 9:58 ` Andreas Schwab
2021-03-13 21:38 ` Allen Li
1 sibling, 0 replies; 29+ messages in thread
From: Andreas Schwab @ 2021-03-13 9:58 UTC (permalink / raw
To: Eli Zaretskii; +Cc: Allen Li, 46884, juri
On Mär 13 2021, Eli Zaretskii wrote:
>> +---
>> +*** Optional 'global-args' parameter added to 'find-dired'.
>> +This allows passing find global options like -maxdepth.
>
> "find" should be in quotes: 'find'
>
>> @@ -202,6 +203,7 @@ find-dired
>> (setq default-directory dir
>> find-args args ; save for next interactive call
>> args (concat find-program " . "
>> + (if global-args global-args "")
>
> 'concat' knows how to handle nil arguments, so you don't need the
> empty string alternative here. Just (if global-args global-args)
> should do.
aka (or global-args) aka global-args
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1
"And now for something completely different."
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-13 9:46 ` Eli Zaretskii
2021-03-13 9:58 ` Andreas Schwab
@ 2021-03-13 21:38 ` Allen Li
2021-03-13 21:53 ` Juri Linkov
1 sibling, 1 reply; 29+ messages in thread
From: Allen Li @ 2021-03-13 21:38 UTC (permalink / raw
To: Eli Zaretskii; +Cc: 46884, Juri Linkov
[-- Attachment #1: Type: text/plain, Size: 1052 bytes --]
Sorry, I attached the wrong patch, here's the one for the rgrep approach.
On Sat, Mar 13, 2021 at 9:46 AM Eli Zaretskii <eliz@gnu.org> wrote:
>
> > From: Allen Li <darkfeline@felesatra.moe>
> > Date: Fri, 12 Mar 2021 08:08:55 +0000
> > Cc: Juri Linkov <juri@linkov.net>, 46884@debbugs.gnu.org
> >
> > Attached patch, does this approach look good?
>
> I guess my suggestion to additionally allow specification of
> GLOBAL-ARGS interactively (via prefix arg) got voted down?
>
> > +---
> > +*** Optional 'global-args' parameter added to 'find-dired'.
> > +This allows passing find global options like -maxdepth.
>
> "find" should be in quotes: 'find'
>
> > @@ -202,6 +203,7 @@ find-dired
> > (setq default-directory dir
> > find-args args ; save for next interactive call
> > args (concat find-program " . "
> > + (if global-args global-args "")
>
> 'concat' knows how to handle nil arguments, so you don't need the
> empty string alternative here. Just (if global-args global-args)
> should do.
[-- Attachment #2: 0001-find-dired-Add-command-editing-like-rgrep.patch --]
[-- Type: text/x-patch, Size: 4937 bytes --]
From a8dce73ca0ae1482dbfb8c10a82f51529fbe1226 Mon Sep 17 00:00:00 2001
From: Allen Li <darkfeline@felesatra.moe>
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
^ permalink raw reply related [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-13 21:38 ` Allen Li
@ 2021-03-13 21:53 ` Juri Linkov
2021-03-14 0:40 ` Allen Li
0 siblings, 1 reply; 29+ messages in thread
From: Juri Linkov @ 2021-03-13 21:53 UTC (permalink / raw
To: Allen Li; +Cc: 46884
> Sorry, I attached the wrong patch, here's the one for the rgrep approach.
Thanks, I tried it, but for some reason 'C-u C-u find-dired RET'
doesn't work. Maybe because it uses 'grep-find-command' that is nil?
> +With two \\[universal-argument] prefixes, directly edit and run `grep-find-command'.
> ...
> + ((and grep-find-command (equal current-prefix-arg '(16)))
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-13 21:53 ` Juri Linkov
@ 2021-03-14 0:40 ` Allen Li
2021-03-18 18:52 ` Juri Linkov
0 siblings, 1 reply; 29+ messages in thread
From: Allen Li @ 2021-03-14 0:40 UTC (permalink / raw
To: Juri Linkov; +Cc: 46884
[-- Attachment #1: Type: text/plain, Size: 734 bytes --]
On Sat, Mar 13, 2021 at 9:53 PM Juri Linkov <juri@linkov.net> wrote:
>
> > Sorry, I attached the wrong patch, here's the one for the rgrep approach.
>
> Thanks, I tried it, but for some reason 'C-u C-u find-dired RET'
> doesn't work. Maybe because it uses 'grep-find-command' that is nil?
First patch was to outline intent to Eli; I didn't test it which was
an oversight on my part.
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.
>
> > +With two \\[universal-argument] prefixes, directly edit and run `grep-find-command'.
> > ...
> > + ((and grep-find-command (equal current-prefix-arg '(16)))
[-- Attachment #2: 0001-find-dired-Add-command-editing-like-rgrep.patch --]
[-- Type: text/x-patch, Size: 10268 bytes --]
From be97868f05c2bda95ab3c2d6348478d5d0306014 Mon Sep 17 00:00:00 2001
From: Allen Li <darkfeline@felesatra.moe>
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 | 211 ++++++++++++++++++++++++++-------------------
1 file changed, 121 insertions(+), 90 deletions(-)
diff --git a/lisp/find-dired.el b/lisp/find-dired.el
index adc5672eca..e4d2a5ba11 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,93 +169,121 @@ 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))))
- (let ((dired-buffers dired-buffers))
- ;; Expand DIR ("" means default-directory), and make sure it has a
- ;; trailing slash.
- (setq dir (file-name-as-directory (expand-file-name dir)))
- ;; Check that it's really a directory.
- (or (file-directory-p dir)
- (error "find-dired needs a directory: %s" dir))
- (pop-to-buffer-same-window (get-buffer-create "*Find*"))
-
- ;; See if there's still a `find' running, and offer to kill
- ;; it first, if it is.
- (let ((find (get-buffer-process (current-buffer))))
- (when find
- (if (or (not (eq (process-status find) 'run))
- (yes-or-no-p
- (format-message "A `find' process is running; kill it? ")))
- (condition-case nil
- (progn
- (interrupt-process find)
- (sit-for 1)
- (delete-process find))
- (error nil))
- (error "Cannot have two processes in `%s' at once" (buffer-name)))))
-
- (widen)
- (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))))
- ;; Start the find process.
- (shell-command (concat args "&") (current-buffer))
- (dired-mode dir (cdr find-ls-option))
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map (current-local-map))
- (define-key map "\C-c\C-k" 'kill-find)
- (use-local-map map))
- (setq-local dired-sort-inhibit t)
- (setq-local revert-buffer-function
- `(lambda (ignore-auto noconfirm)
- (find-dired ,dir ,find-args)))
- ;; 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
- ;; and later)
- (dired-simple-subdir-alist)
- ;; else we have an ancient tree dired (or classic dired, where
- ;; this does no harm)
- (setq-local dired-subdir-alist
- (list (cons default-directory (point-min-marker)))))
- (setq-local dired-subdir-switches find-ls-subdir-switches)
- (setq buffer-read-only nil)
- ;; Subdir headlerline must come first because the first marker in
- ;; subdir-alist points there.
- (insert " " dir ":\n")
- ;; Make second line a ``find'' line in analogy to the ``total'' or
- ;; ``wildcard'' line.
- (let ((point (point)))
- (insert " " args "\n")
- (dired-insert-set-properties point (point)))
- (setq buffer-read-only t)
- (let ((proc (get-buffer-process (current-buffer))))
- (set-process-filter proc #'find-dired-filter)
- (set-process-sentinel proc #'find-dired-sentinel)
- ;; Initialize the process marker; it is used by the filter.
- (move-marker (process-mark proc) (point) (current-buffer)))
- (setq mode-line-process '(":%s"))))
+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
+ ((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 (command)
+ (if (null args)
+ (setq command dir
+ dir default-directory)
+ (setq find-args args ; save for next interactive call
+ command (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 command
+ (read-from-minibuffer "Confirm: "
+ command nil nil 'find-dired-history))
+ (add-to-history 'find-dired-history command))
+ (let ((dired-buffers dired-buffers))
+ ;; Expand DIR ("" means default-directory), and make sure it has a
+ ;; trailing slash.
+ (setq dir (file-name-as-directory (expand-file-name dir)))
+ ;; Check that it's really a directory.
+ (or (file-directory-p dir)
+ (error "find-dired needs a directory: %s" dir))
+ (pop-to-buffer-same-window (get-buffer-create "*Find*"))
+
+ ;; See if there's still a `find' running, and offer to kill
+ ;; it first, if it is.
+ (let ((find (get-buffer-process (current-buffer))))
+ (when find
+ (if (or (not (eq (process-status find) 'run))
+ (yes-or-no-p
+ (format-message "A `find' process is running; kill it? ")))
+ (condition-case nil
+ (progn
+ (interrupt-process find)
+ (sit-for 1)
+ (delete-process find))
+ (error nil))
+ (error "Cannot have two processes in `%s' at once" (buffer-name)))))
+
+ (widen)
+ (kill-all-local-variables)
+ (setq buffer-read-only nil)
+ (erase-buffer)
+ (setq default-directory dir)
+
+ ;; Start the find process.
+ (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))
+ (define-key map "\C-c\C-k" 'kill-find)
+ (use-local-map map))
+ (setq-local dired-sort-inhibit t)
+ (setq-local revert-buffer-function
+ `(lambda (ignore-auto noconfirm)
+ (find-dired ,dir ,find-args)))
+ ;; 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
+ ;; and later)
+ (dired-simple-subdir-alist)
+ ;; else we have an ancient tree dired (or classic dired, where
+ ;; this does no harm)
+ (setq-local dired-subdir-alist
+ (list (cons default-directory (point-min-marker)))))
+ (setq-local dired-subdir-switches find-ls-subdir-switches)
+ (setq buffer-read-only nil)
+ ;; Subdir headlerline must come first because the first marker in
+ ;; subdir-alist points there.
+ (insert " " dir ":\n")
+ ;; Make second line a ``find'' line in analogy to the ``total'' or
+ ;; ``wildcard'' line.
+ (let ((point (point)))
+ (insert " " command "\n")
+ (dired-insert-set-properties point (point)))
+ (setq buffer-read-only t)
+ (let ((proc (get-buffer-process (current-buffer))))
+ (set-process-filter proc #'find-dired-filter)
+ (set-process-sentinel proc #'find-dired-sentinel)
+ ;; Initialize the process marker; it is used by the filter.
+ (move-marker (process-mark proc) (point) (current-buffer)))
+ (setq mode-line-process '(":%s")))))
(defun kill-find ()
"Kill the `find' process running in the current buffer."
@@ -393,7 +424,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
^ permalink raw reply related [flat|nested] 29+ messages in thread
* bug#46884: [PATCH] 27.1; Cannot run find-dired with -maxdepth
2021-03-14 0:40 ` Allen Li
@ 2021-03-18 18:52 ` Juri Linkov
2022-06-19 23:55 ` bug#46884: " Lars Ingebrigtsen
0 siblings, 1 reply; 29+ messages in thread
From: Juri Linkov @ 2021-03-18 18:52 UTC (permalink / raw
To: Allen Li; +Cc: 46884
> First patch was to outline intent to Eli; I didn't test it which was
> an oversight on my part.
>
> 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'.
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: 27.1; Cannot run find-dired with -maxdepth
2021-03-18 18:52 ` Juri Linkov
@ 2022-06-19 23:55 ` Lars Ingebrigtsen
2022-06-26 3:54 ` Allen Li
0 siblings, 1 reply; 29+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-19 23:55 UTC (permalink / raw
To: Juri Linkov; +Cc: Eli Zaretskii, 46884, Allen Li
Juri Linkov <juri@linkov.net> 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
^ permalink raw reply [flat|nested] 29+ messages in thread
* bug#46884: 27.1; Cannot run find-dired with -maxdepth
2022-06-19 23:55 ` bug#46884: " Lars Ingebrigtsen
@ 2022-06-26 3:54 ` Allen Li
2022-06-27 7:46 ` Lars Ingebrigtsen
0 siblings, 1 reply; 29+ messages in thread
From: Allen Li @ 2022-06-26 3:54 UTC (permalink / raw
To: Lars Ingebrigtsen; +Cc: Eli Zaretskii, 46884, Juri Linkov
[-- Attachment #1.1: Type: text/plain, Size: 1161 bytes --]
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 <larsi@gnus.org> wrote:
> Juri Linkov <juri@linkov.net> 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
>
[-- Attachment #1.2: Type: text/html, Size: 1751 bytes --]
[-- Attachment #2: 0001-find-dired-Factor-out-find-dired-escaped-ls-option.patch --]
[-- Type: text/x-patch, Size: 1794 bytes --]
From e2a9609eece317148c0d11bd5e68d541ff7060fb Mon Sep 17 00:00:00 2001
From: Allen Li <darkfeline@felesatra.moe>
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
[-- Attachment #3: 0002-find-dired-Add-find-dired-with-command.patch --]
[-- Type: text/x-patch, Size: 4959 bytes --]
From a9bc9b1c963d6b66085d264aa8907a31faeb7f90 Mon Sep 17 00:00:00 2001
From: Allen Li <darkfeline@felesatra.moe>
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
^ permalink raw reply related [flat|nested] 29+ messages in thread
* bug#46884: 27.1; Cannot run find-dired with -maxdepth
2022-06-26 3:54 ` Allen Li
@ 2022-06-27 7:46 ` Lars Ingebrigtsen
0 siblings, 0 replies; 29+ messages in thread
From: Lars Ingebrigtsen @ 2022-06-27 7:46 UTC (permalink / raw
To: Allen Li; +Cc: Eli Zaretskii, 46884, Juri Linkov
Allen Li <darkfeline@felesatra.moe> writes:
> 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.
Thanks; pushed to Emacs 29 (with some whitespace changes).
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2022-06-27 7:46 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-03 1:12 bug#46884: 27.1; Cannot run find-dired with -maxdepth Allen Li
2021-03-03 1:20 ` bug#46884: [PATCH] " Allen Li
2021-03-03 3:38 ` Allen Li
2021-03-03 6:28 ` Eli Zaretskii
2021-03-03 8:22 ` Allen Li
2021-03-03 8:55 ` Eli Zaretskii
2021-03-04 4:50 ` Allen Li
2021-03-04 9:35 ` Juri Linkov
2021-03-05 3:21 ` Allen Li
2021-03-05 7:27 ` Eli Zaretskii
2021-03-12 8:08 ` Allen Li
2021-03-12 15:49 ` bug#46884: [External] : " Drew Adams
2021-03-13 0:42 ` Allen Li
2021-03-13 1:09 ` Drew Adams
2021-03-13 9:46 ` Eli Zaretskii
2021-03-13 9:58 ` Andreas Schwab
2021-03-13 21:38 ` Allen Li
2021-03-13 21:53 ` Juri Linkov
2021-03-14 0:40 ` Allen Li
2021-03-18 18:52 ` Juri Linkov
2022-06-19 23:55 ` bug#46884: " Lars Ingebrigtsen
2022-06-26 3:54 ` Allen Li
2022-06-27 7:46 ` Lars Ingebrigtsen
2021-03-04 13:53 ` bug#46884: [PATCH] " Eli Zaretskii
2021-03-03 9:03 ` Juri Linkov
2021-03-03 15:42 ` bug#46884: [External] : " Drew Adams
2021-03-03 16:20 ` Eli Zaretskii
2021-03-03 6:15 ` Eli Zaretskii
2021-03-03 1:34 ` bug#46884: [External] : bug#46884: " Drew Adams
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.