I am looking for a command M-x find
in Emacs, which behave exactly like M-x grep
(allows to modify the command, prints the output nicely including links to the found files, ...) and which executes find . -iname '*|*'
(with the cursor placed at the vertical bar -- for inserting a search pattern -- if not too complicated to implement). Has anyone implemented this before? [I am aware of M-x find-grep
]

- 6,546
- 10
- 48
- 102
3 Answers
Let's start with M-xfind-dired
that does almost what you want: it reads directory from minibuffer, defaulting to current directory, and then reads other find
arguments. The result is opened in dired
mode, and I think it's as nicely as it can get (if you think that dired
is too verbose, check out dired-details
and maybe dired-details+
packages at MELPA).
Now let's make it start with -iname **
with a cursor between the stars when it's asking for options. Looking at find-dired
source, we can see that it uses the value of find-args
as an initial input argument to read-string
. This argument is obsolete and deprecated but awfully useful. One of its features (as we read in read-from-minibuffer
description) is providing a default point position when a cons of a string and an integer is given.
(defun marius/find-dired ()
(interactive)
(let ((find-args '("-iname '**'" . 10)))
(call-interactively 'find-dired)))
We added single quotes around stars in '**'
because the arguments are subject to shell expansion.
Instead of reading our own arguments from the minibuffer, we just
rebind find-args
and delegate all the rest to find-dired
. Normally
find-dired
remembers last arguments you enter in find-args
so they
become the new default. Rebinding it with let
ensures that this
modification from our call to find-dired
will be thrown away, so
regular find-dired
will use the arguments given to the latest
regular find-dired
. It probably doesn't matter if you don't use regular find-dired
. If you want find arguments given to our wrapper to be used by regular find-dired
, use the following definition instead:
(defun marius/find-dired ()
(interactive)
(setq find-args '("-iname '**'" . 10))
(call-interactively 'find-dired))

- 20,999
- 2
- 37
- 69
I think that find-dired
fulfills your requirements (except it doesn't initialize the command with "-iname" and lets you enter it).
For example:
- M-x
find-dired
RET (executefind-dired
) - C-j (accept default directory :
.
) -iname "*.foo"
RET (enter command-line arguments)
Results are presented in a dired
buffer.

- 19,520
- 4
- 51
- 74
You can start with:
(defun eab/find-grep ()
(interactive)
(let ((grep-host-defaults-alist nil)
(grep-find-command
`(,"find . -iname '**' -type f -print0 | xargs -0 -e grep -nH -m 1 -e \"^\"" . 17)))
(call-interactively 'find-grep)))
Also I use:
(defun eab/grep ()
(interactive)
(let ((grep-host-defaults-alist nil)
(grep-command
`(,(concat "grep -i -nH -e *."
(ignore-errors
(file-name-extension buffer-file-name))) . 16)))
(call-interactively 'grep)))
EDIT: Now grep-find-command is for searching only first line of each file by default.

- 2,340
- 15
- 26