Emacs find-grep-dired then automatically isearch-forward on given regexp

1.7k views Asked by At

I commonly do find-grep-dired to find an expression in a project directory. That gives me a nice dired view of all the files that contain that expression. But my next step is invariably to open one of those files and do an isearch-forward with the same search expression. How can I save myself from typing in the search words twice each time (or more than twice if there are multiple files I want to edit)?

3

There are 3 answers

2
Joseph Gay On BEST ANSWER

This should work for you:

  1. Run find-grep-dired as usual
  2. Press * t (dired-toggle-marks) to mark all files.
  3. Press A to start dired-do-search. When prompted, instead of typing, press M-p, this will bring up your find-grep regexp since both functions use the same prompting history list
  4. You will be taken to the first match in the first file. Here's the fun part, simply press M-, to go to the next match spanning all of your matched files.
  5. Profit? (sorry, couldn't resist)

And if you want it all in one shot, here you go:

(defun find-grep-dired-do-search (dir regexp)
  "First perform `find-grep-dired', and wait for it to finish.
Then, using the same REGEXP as provided to `find-grep-dired',
perform `dired-do-search' on all files in the *Find* buffer."
  (interactive "DFind-grep (directory): \nsFind-grep (grep regexp): ")
  (find-grep-dired dir regexp)
  (while (get-buffer-process (get-buffer "*Find*"))
    (sit-for 1))
  (with-current-buffer "*Find*"
    (dired-toggle-marks)
    (dired-do-search regexp)))
1
Oleg Pavliv On

You can store the search string you use in find-grep-dired in the kill ring (C-SPACE C-a M-w). Then you do the search in the files using the string from the kill ring (C-s M-y). M-y will yank the last string of killed text.

You can display other (useful) bindings for isearch-forward using C-h k C-s.

4
Trey Jackson On

How about a different approach? Try using M-x igrep-find from the igrep.el package.

By default it searches for all occurrences of the pattern, but you could change the behavior to just find the first such occurrence with:

(setq igrep-options "-i -m 1")   ;; I like -i for case-insensitivity

This will result in a compilation style buffer (named *igrep*) with a single line for each file, and when you click on the line (or do C-x `), you'll automatically be put on the line which has the match. Plus, you can see the matching line in the *igrep* buffer.

Obviously, if you want to see more than one match per file, change the number after the -m, or omit that part altogether.