- (let* ((regexp
- (if current-prefix-arg
- grep-tree-last-regexp
- (let* ((default (current-word))
- (spec (read-string
- (concat "Search for"
- (if (and default (> (length default) 0))
- (format " (default %s): " default) ": ")))))
- (if (equal spec "") default spec))))
- (files
- (read-string (concat "Search for \"" regexp "\" in files (default " grep-tree-last-files "): ")))
- (dir
- (read-directory-name "Base directory: " nil default-directory t)))
- (list regexp files dir)))
- (unless grep-tree-command
- (grep-compute-defaults))
- (unless (and (stringp files) (> (length files) 0))
- (setq files grep-tree-last-files))
- (when files
- (setq grep-tree-last-files files)
- (let ((mf (assoc files grep-tree-files-aliases)))
- (if mf
- (setq files (cdr mf)))))
- (let ((command-args (grep-expand-command-macros
- grep-tree-command
- (setq grep-tree-last-regexp regexp)
- (and files (concat "-name '" files "'"))
- (if subdirs
- (if (stringp subdirs)
- subdirs
- (mapconcat 'identity subdirs " "))
- nil) ;; we change default-directory to dir
- (and grep-tree-ignore-CVS-directories "-path '*/CVS' -prune -o ")
- grep-tree-ignore-case))
- (default-directory (file-name-as-directory (expand-file-name dir)))
- (null-device nil)) ; see grep
- (grep command-args regexp)))
+ (progn
+ (grep-compute-defaults)
+ (cond
+ ((and grep-command (equal current-prefix-arg '(16)))
+ (list (read-from-minibuffer "Run: " grep-command
+ nil nil 'grep-history)
+ nil))
+ ((not grep-template)
+ (list nil
+ (read-string "grep.el: No `grep-template' available. Press RET.")))
+ (t (let* ((regexp (grep-read-regexp))
+ (files (grep-read-files regexp))
+ (dir (read-directory-name "In directory: "
+ nil default-directory t)))
+ (list regexp files dir))))))
+ (when (and (stringp regexp) (> (length regexp) 0))
+ (let ((command regexp))
+ (if (null files)
+ (if (string= command grep-command)
+ (setq command nil))
+ (setq dir (file-name-as-directory (expand-file-name dir)))
+ (setq command (grep-expand-template
+ grep-template
+ regexp
+ files))
+ (when command
+ (if (equal current-prefix-arg '(4))
+ (setq command
+ (read-from-minibuffer "Confirm: "
+ command nil nil 'grep-history))
+ (add-to-history 'grep-history command))))
+ (when command
+ (let ((default-directory dir))
+ ;; Setting process-setup-function makes exit-message-function work
+ ;; even when async processes aren't supported.
+ (compilation-start (if (and grep-use-null-device null-device)
+ (concat command " " null-device)
+ command) 'grep-mode))
+ (if (eq next-error-last-buffer (current-buffer))
+ (setq default-directory dir))))))
+
+
+
+;;;###autoload
+(defun rgrep (regexp &optional files dir)
+ "Recursively grep for REGEXP in FILES in directory tree rooted at DIR.
+The search is limited to file names matching shell pattern FILES.
+FILES may use abbreviations defined in `grep-files-aliases', e.g.
+entering `ch' is equivalent to `*.[ch]'.
+
+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 a buffer. While find runs asynchronously, you
+can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error]
+in the grep output buffer, to go to the lines where grep found matches.
+
+This command shares argument histories with \\[lgrep] and \\[grep-find]."
+ (interactive
+ (progn
+ (grep-compute-defaults)
+ (cond
+ ((and grep-find-command (equal current-prefix-arg '(16)))
+ (list (read-from-minibuffer "Run: " grep-find-command
+ nil nil 'grep-find-history)
+ nil))
+ ((not grep-find-template)
+ (list nil nil
+ (read-string "grep.el: No `grep-find-template' available. Press RET.")))
+ (t (let* ((regexp (grep-read-regexp))
+ (files (grep-read-files regexp))
+ (dir (read-directory-name "Base directory: "
+ nil default-directory t)))
+ (list regexp files dir))))))
+ (when (and (stringp regexp) (> (length regexp) 0))
+ (if (null files)
+ (if (not (string= regexp grep-find-command))
+ (compilation-start regexp 'grep-mode))
+ (setq dir (file-name-as-directory (expand-file-name dir)))
+ (let ((command (grep-expand-template
+ grep-find-template
+ regexp
+ (concat (shell-quote-argument "(")
+ " -name "
+ (mapconcat #'shell-quote-argument
+ (split-string files)
+ " -o -name ")
+ " "
+ (shell-quote-argument ")"))
+ dir
+ (and grep-find-ignored-directories
+ (concat (shell-quote-argument "(")
+ ;; we should use shell-quote-argument here
+ " -path "
+ (mapconcat #'(lambda (dir)
+ (shell-quote-argument
+ (concat "*/" dir)))
+ grep-find-ignored-directories
+ " -o -path ")
+ " "
+ (shell-quote-argument ")")
+ " -prune -o ")))))
+ (when command
+ (if current-prefix-arg
+ (setq command
+ (read-from-minibuffer "Confirm: "
+ command nil nil 'grep-find-history))
+ (add-to-history 'grep-find-history command))
+ (let ((default-directory dir))
+ (compilation-start command 'grep-mode))
+ ;; Set default-directory if we started rgrep in the *grep* buffer.
+ (if (eq next-error-last-buffer (current-buffer))
+ (setq default-directory dir)))))))