]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/grep.el
Merge from emacs--rel--22
[gnu-emacs] / lisp / progmodes / grep.el
index 0aba9d42b84633f1b3f0a38a90539653270b985c..91518641938b65a1aa54c31dfb2ee71b9b8c7d9e 100644 (file)
@@ -1,7 +1,7 @@
 ;;; grep.el --- run Grep as inferior of Emacs, parse match messages
 
 ;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;;   2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+;;   2001, 2002, 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
 
 ;; Author: Roland McGrath <roland@gnu.org>
 ;; Maintainer: FSF
@@ -11,7 +11,7 @@
 
 ;; GNU Emacs is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
@@ -150,12 +150,15 @@ The following place holders should be present in the string:
        ("asm" . "*.[sS]")
        ("m" .  "[Mm]akefile*")
        ("l" . "[Cc]hange[Ll]og*")
+       ("tex" . "*.tex")
+       ("texi" . "*.texi")
        )
   "*Alist of aliases for the FILES argument to `lgrep' and `rgrep'."
   :type 'alist
   :group 'grep)
 
-(defcustom grep-find-ignored-directories '("CVS" ".hg" "{arch}")
+(defcustom grep-find-ignored-directories '("CVS" ".svn" "{arch}" ".hg" "_darcs"
+                                          ".git" ".bzr")
   "*List of names of sub-directories which `rgrep' shall not recurse into."
   :type '(repeat string)
   :group 'grep)
@@ -232,8 +235,7 @@ See `compilation-error-screen-columns'"
 ;; override compilation-last-buffer
 (defvar grep-last-buffer nil
   "The most recent grep buffer.
-A grep buffer becomes most recent when its process is started
-or when it is used with \\[grep-next-match].
+A grep buffer becomes most recent when you select Grep mode in it.
 Notice that using \\[next-error] or \\[compile-goto-error] modifies
 `complation-last-buffer' rather than `grep-last-buffer'.")
 
@@ -282,13 +284,13 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
      (": \\(.+\\): \\(?:Permission denied\\|No such \\(?:file or directory\\|device or address\\)\\)$"
       1 grep-error-face)
      ;; remove match from grep-regexp-alist before fontifying
-     ("^Grep started.*"
+     ("^Grep[/a-zA-z]* started.*"
       (0 '(face nil message nil help-echo nil mouse-face nil) t))
-     ("^Grep finished \\(?:(\\(matches found\\))\\|with \\(no matches found\\)\\).*"
+     ("^Grep[/a-zA-z]* finished \\(?:(\\(matches found\\))\\|with \\(no matches found\\)\\).*"
       (0 '(face nil message nil help-echo nil mouse-face nil) t)
       (1 compilation-info-face nil t)
       (2 compilation-warning-face nil t))
-     ("^Grep \\(exited abnormally\\|interrupt\\|killed\\|terminated\\)\\(?:.*with code \\([0-9]+\\)\\)?.*"
+     ("^Grep[/a-zA-z]* \\(exited abnormally\\|interrupt\\|killed\\|terminated\\)\\(?:.*with code \\([0-9]+\\)\\)?.*"
       (0 '(face nil message nil help-echo nil mouse-face nil) t)
       (1 grep-error-face)
       (2 grep-error-face nil t))
@@ -313,17 +315,7 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
 This gets tacked on the end of the generated expressions.")
 
 ;;;###autoload
-(defvar grep-program
-  ;; Currently zgrep has trouble.  It runs egrep instead of grep,
-  ;; and it doesn't pass along long options right.
-  "grep"
-  ;; (if (equal (condition-case nil    ; in case "zgrep" isn't in exec-path
-  ;;            (call-process "zgrep" nil nil nil
-  ;;                          "foo" null-device)
-  ;;          (error nil))
-  ;;        1)
-  ;;     "zgrep"
-  ;;   "grep")
+(defvar grep-program "grep"
   "The default grep program for `grep-command' and `grep-find-command'.
 This variable's value takes effect when `grep-compute-defaults' is called.")
 
@@ -334,10 +326,10 @@ This variable's value takes effect when `grep-compute-defaults' is called.")
 
 ;;;###autoload
 (defvar grep-find-use-xargs nil
-  "Whether \\[grep-find] uses the `xargs' utility by default.
-
-If nil, it uses `find -exec'; if `gnu', it uses `find -print0' and `xargs -0';
-if not nil and not `gnu', it uses `find -print' and `xargs'.
+  "Non-nil means that `grep-find' uses the `xargs' utility by default.
+If `exec', use `find -exec'.
+If `gnu', use `find -print0' and `xargs -0'.
+Any other non-nil value means to use `find -print' and `xargs'.
 
 This variable's value takes effect when `grep-compute-defaults' is called.")
 
@@ -351,6 +343,12 @@ This variable's value takes effect when `grep-compute-defaults' is called.")
 (defvar grep-regexp-history nil)
 (defvar grep-files-history '("ch" "el"))
 
+(defvar grep-host-defaults-alist nil
+  "Default values depending on target host.
+`grep-compute-defaults' returns default values for every local or
+remote host `grep' runs.  These values can differ from host to
+host.  Once computed, the default values are kept here in order
+to avoid computing them again.")
 
 ;;;###autoload
 (defun grep-process-setup ()
@@ -379,111 +377,196 @@ Set up `compilation-exit-message-function' and run `grep-setup-hook'."
 
 (defun grep-probe (command args &optional func result)
   (equal (condition-case nil
-            (apply (or func 'call-process) command args)
+            (apply (or func 'process-file) command args)
           (error nil))
         (or result 0)))
 
 ;;;###autoload
 (defun grep-compute-defaults ()
-  (unless (or (not grep-use-null-device) (eq grep-use-null-device t))
-    (setq grep-use-null-device
-         (with-temp-buffer
-           (let ((hello-file (expand-file-name "HELLO" data-directory)))
-             (not
-              (and (if grep-command
-                       ;; `grep-command' is already set, so
-                       ;; use that for testing.
-                       (grep-probe grep-command
-                                   `(nil t nil "^English" ,hello-file)
-                                   #'call-process-shell-command)
-                     ;; otherwise use `grep-program'
-                     (grep-probe grep-program
-                                 `(nil t nil "-nH" "^English" ,hello-file)))
-                   (progn
-                     (goto-char (point-min))
-                     (looking-at
-                      (concat (regexp-quote hello-file)
-                              ":[0-9]+:English")))))))))
-  (unless (and grep-command grep-find-command
-              grep-template grep-find-template)
-    (let ((grep-options
-          (concat (if grep-use-null-device "-n" "-nH")
-                  (if (grep-probe grep-program
-                                  `(nil nil nil "-e" "foo" ,null-device)
-                                  nil 1)
-                      " -e"))))
-      (unless grep-command
-       (setq grep-command
-             (format "%s %s " grep-program grep-options)))
-      (unless grep-template
-       (setq grep-template
-             (format "%s <C> %s <R> <F>" grep-program grep-options)))
-      (unless grep-find-use-xargs
-       (setq grep-find-use-xargs
-             (if (and
+  ;; Keep default values.
+  (unless grep-host-defaults-alist
+    (add-to-list
+     'grep-host-defaults-alist
+     (cons nil
+          `((grep-command ,grep-command)
+            (grep-template ,grep-template)
+            (grep-use-null-device ,grep-use-null-device)
+            (grep-find-command ,grep-find-command)
+            (grep-find-template ,grep-find-template)
+            (grep-find-use-xargs ,grep-find-use-xargs)
+            (grep-highlight-matches ,grep-highlight-matches)))))
+  (let* ((host-id
+         (intern (or (file-remote-p default-directory 'host) "localhost")))
+        (host-defaults (assq host-id grep-host-defaults-alist))
+        (defaults (assq nil grep-host-defaults-alist)))
+    ;; There are different defaults on different hosts.  They must be
+    ;; computed for every host once.
+    (setq grep-command
+         (or (cadr (assq 'grep-command host-defaults))
+             (cadr (assq 'grep-command defaults)))
+
+         grep-template
+          (or (cadr (assq 'grep-template host-defaults))
+             (cadr (assq 'grep-template defaults)))
+
+         grep-use-null-device
+         (or (cadr (assq 'grep-use-null-device host-defaults))
+             (cadr (assq 'grep-use-null-device defaults)))
+
+         grep-find-command
+         (or (cadr (assq 'grep-find-command host-defaults))
+             (cadr (assq 'grep-find-command defaults)))
+
+         grep-find-template
+         (or (cadr (assq 'grep-find-template host-defaults))
+             (cadr (assq 'grep-find-template defaults)))
+
+         grep-find-use-xargs
+         (or (cadr (assq 'grep-find-use-xargs host-defaults))
+             (cadr (assq 'grep-find-use-xargs defaults)))
+
+         grep-highlight-matches
+         (or (cadr (assq 'grep-highlight-matches host-defaults))
+             (cadr (assq 'grep-highlight-matches defaults))))
+
+    (unless (or (not grep-use-null-device) (eq grep-use-null-device t))
+      (setq grep-use-null-device
+           (with-temp-buffer
+             (let ((hello-file (expand-file-name "HELLO" data-directory)))
+               (not
+                (and (if grep-command
+                         ;; `grep-command' is already set, so
+                         ;; use that for testing.
+                         (grep-probe grep-command
+                                     `(nil t nil "^English" ,hello-file)
+                                     #'call-process-shell-command)
+                       ;; otherwise use `grep-program'
+                       (grep-probe grep-program
+                                   `(nil t nil "-nH" "^English" ,hello-file)))
+                     (progn
+                       (goto-char (point-min))
+                       (looking-at
+                        (concat (regexp-quote hello-file)
+                                ":[0-9]+:English")))))))))
+    (unless (and grep-command grep-find-command
+                grep-template grep-find-template)
+      (let ((grep-options
+            (concat (if grep-use-null-device "-n" "-nH")
+                    (if (grep-probe grep-program
+                                    `(nil nil nil "-e" "foo" ,null-device)
+                                    nil 1)
+                        " -e"))))
+       (unless grep-command
+         (setq grep-command
+               (format "%s %s " grep-program grep-options)))
+       (unless grep-template
+         (setq grep-template
+               (format "%s <C> %s <R> <F>" grep-program grep-options)))
+       (unless grep-find-use-xargs
+         (setq grep-find-use-xargs
+               (cond
+                ((and
                   (grep-probe find-program `(nil nil nil ,null-device "-print0"))
                   (grep-probe "xargs" `(nil nil nil "-0" "-e" "echo")))
-                 'gnu)))
-      (unless grep-find-command
-       (setq grep-find-command
-             (cond ((eq grep-find-use-xargs 'gnu)
-                    (format "%s . -type f -print0 | xargs -0 -e %s"
-                            find-program grep-command))
-                   (grep-find-use-xargs
-                    (format "%s . -type f -print | xargs %s"
-                            find-program grep-command))
-                   (t (cons (format "%s . -type f -exec %s {} %s \\;"
-                                    find-program grep-command null-device)
-                            (+ 22 (length grep-command)))))))
-      (unless grep-find-template
-       (setq grep-find-template
-             (let ((gcmd (format "%s <C> %s <R>"
-                                 grep-program grep-options)))
+                 'gnu)
+                (t
+                 'exec))))
+       (unless grep-find-command
+         (setq grep-find-command
                (cond ((eq grep-find-use-xargs 'gnu)
-                      (format "%s . <X> -type f <F> -print0 | xargs -0 -e %s"
-                              find-program gcmd))
-                     (grep-find-use-xargs
-                      (format "%s . <X> -type f <F> -print | xargs %s"
-                              find-program gcmd))
-                     (t (format "%s . <X> -type f <F> -exec %s {} %s \\;"
-                                find-program gcmd null-device))))))))
-  (unless (or (not grep-highlight-matches) (eq grep-highlight-matches t))
-    (setq grep-highlight-matches
-         (with-temp-buffer
-           (and (grep-probe grep-program '(nil t nil "--help"))
-                (progn
-                  (goto-char (point-min))
-                  (search-forward "--color" nil t))
-                t)))))
+                      (format "%s . -type f -print0 | xargs -0 -e %s"
+                              find-program grep-command))
+                     ((eq grep-find-use-xargs 'exec)
+                      (let ((cmd0 (format "%s . -type f -exec %s"
+                                          find-program grep-command)))
+                        (cons
+                         (format "%s {} %s %s"
+                                 cmd0 null-device
+                                 (shell-quote-argument ";"))
+                         (1+ (length cmd0)))))
+                     (t
+                      (format "%s . -type f -print | xargs %s"
+                              find-program grep-command)))))
+       (unless grep-find-template
+         (setq grep-find-template
+               (let ((gcmd (format "%s <C> %s <R>"
+                                   grep-program grep-options)))
+                 (cond ((eq grep-find-use-xargs 'gnu)
+                        (format "%s . <X> -type f <F> -print0 | xargs -0 -e %s"
+                                find-program gcmd))
+                       ((eq grep-find-use-xargs 'exec)
+                        (format "%s . <X> -type f <F> -exec %s {} %s %s"
+                                find-program gcmd null-device
+                                (shell-quote-argument ";")))
+                       (t
+                        (format "%s . <X> -type f <F> -print | xargs %s"
+                                find-program gcmd))))))))
+    (unless (or (not grep-highlight-matches) (eq grep-highlight-matches t))
+      (setq grep-highlight-matches
+           (with-temp-buffer
+             (and (grep-probe grep-program '(nil t nil "--help"))
+                  (progn
+                    (goto-char (point-min))
+                    (search-forward "--color" nil t))
+                  t))))
+
+    ;; Save defaults for this host.
+    (setq grep-host-defaults-alist
+         (delete (assq host-id grep-host-defaults-alist)
+                 grep-host-defaults-alist))
+    (add-to-list
+     'grep-host-defaults-alist
+     (cons host-id
+          `((grep-command ,grep-command)
+            (grep-template ,grep-template)
+            (grep-use-null-device ,grep-use-null-device)
+            (grep-find-command ,grep-find-command)
+            (grep-find-template ,grep-find-template)
+            (grep-find-use-xargs ,grep-find-use-xargs)
+            (grep-highlight-matches ,grep-highlight-matches))))))
+
+(defun grep-tag-default ()
+  (or (and transient-mark-mode mark-active
+          (/= (point) (mark))
+          (buffer-substring-no-properties (point) (mark)))
+      (funcall (or find-tag-default-function
+                  (get major-mode 'find-tag-default-function)
+                  'find-tag-default))
+      ""))
 
 (defun grep-default-command ()
-  (let ((tag-default
-         (shell-quote-argument
-          (or (funcall (or find-tag-default-function
-                           (get major-mode 'find-tag-default-function)
-                           'find-tag-default))
-              "")))
+  "Compute the default grep command for C-u M-x grep to offer."
+  (let ((tag-default (shell-quote-argument (grep-tag-default)))
+       ;; This a regexp to match single shell arguments.
+       ;; Could someone please add comments explaining it?
        (sh-arg-re "\\(\\(?:\"\\(?:[^\"]\\|\\\\\"\\)+\"\\|'[^']+'\\|[^\"' \t\n]\\)+\\)")
        (grep-default (or (car grep-history) grep-command)))
-    ;; Replace the thing matching for with that around cursor.
+    ;; In the default command, find the arg that specifies the pattern.
     (when (or (string-match
               (concat "[^ ]+\\s +\\(?:-[^ ]+\\s +\\)*"
                       sh-arg-re "\\(\\s +\\(\\S +\\)\\)?")
               grep-default)
              ;; If the string is not yet complete.
              (string-match "\\(\\)\\'" grep-default))
-      (unless (or (not (stringp buffer-file-name))
-                 (when (match-beginning 2)
-                   (save-match-data
-                     (string-match
-                      (wildcard-to-regexp
-                       (file-name-nondirectory
-                        (match-string 3 grep-default)))
-                      (file-name-nondirectory buffer-file-name)))))
-       (setq grep-default (concat (substring grep-default
-                                             0 (match-beginning 2))
-                                  " *."
-                                  (file-name-extension buffer-file-name))))
+      ;; Maybe we will replace the pattern with the default tag.
+      ;; But first, maybe replace the file name pattern.
+      (condition-case nil
+         (unless (or (not (stringp buffer-file-name))
+                     (when (match-beginning 2)
+                       (save-match-data
+                         (string-match
+                          (wildcard-to-regexp
+                           (file-name-nondirectory
+                            (match-string 3 grep-default)))
+                          (file-name-nondirectory buffer-file-name)))))
+           (setq grep-default (concat (substring grep-default
+                                                 0 (match-beginning 2))
+                                      " *."
+                                      (file-name-extension buffer-file-name))))
+       ;; In case wildcard-to-regexp gets an error
+       ;; from invalid data.
+       (error nil))
+      ;; Now replace the pattern with the default tag.
       (replace-match tag-default t t grep-default 1))))
 
 
@@ -508,6 +591,9 @@ or \\<grep-mode-map>\\[compile-goto-error] in the grep \
 output buffer, to go to the lines
 where grep found matches.
 
+For doing a recursive `grep', see the `rgrep' command.  For running
+`grep' in a specific directory, see `lgrep'.
+
 This command uses a special history list for its COMMAND-ARGS, so you can
 easily repeat a grep command.
 
@@ -553,7 +639,7 @@ easily repeat a find command."
        (read-string
         "compile.el: No `grep-find-command' command available. Press RET.")
        (list nil))))
-  (when (and grep-find-command command-args)
+  (when command-args
     (let ((null-device nil))           ; see grep
       (grep command-args))))
 
@@ -584,22 +670,18 @@ substitution string.  Note dynamic scoping of variables.")
          (setq command
                (replace-match
                 (or (if (symbolp (cdr kw))
-                        (eval (cdr kw))
+                        (symbol-value (cdr kw))
                       (save-match-data (eval (cdr kw))))
                     "")
                 t t command))))))
 
 (defun grep-read-regexp ()
   "Read regexp arg for interactive grep."
-  (let ((default
-         (or (funcall (or find-tag-default-function
-                          (get major-mode 'find-tag-default-function)
-                          'find-tag-default))
-             "")))
+  (let ((default (grep-tag-default)))
     (read-string
      (concat "Search for"
             (if (and default (> (length default) 0))
-                (format " (default %s): " default) ": "))
+                (format " (default \"%s\"): " default) ": "))
      nil 'grep-regexp-history default)))
 
 (defun grep-read-files (regexp)
@@ -621,7 +703,9 @@ substitution string.  Note dynamic scoping of variables.")
                      (cdr alias)))
               (and fn
                    (let ((ext (file-name-extension fn)))
-                     (and ext (concat "*." ext))))))
+                     (and ext (concat "*." ext))))
+              (car grep-files-history)
+              (car (car grep-files-aliases))))
         (files (read-string
                 (concat "Search for \"" regexp
                         "\" in files"
@@ -633,15 +717,15 @@ substitution string.  Note dynamic scoping of variables.")
             files))))
 
 ;;;###autoload
-(defun lgrep (regexp &optional files)
-  "Run grep, searching for REGEXP in FILES in current directory.
+(defun lgrep (regexp &optional files dir)
+  "Run grep, searching for REGEXP in FILES in directory 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, allow user to edit the constructed
-shell command line before it is executed.
-With two \\[universal-argument] prefixes, edit and run grep shell command.
+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-command'.
 
 Collect output in a buffer.  While grep runs asynchronously, you
 can use \\[next-error] (M-x next-error), or \\<grep-mode-map>\\[compile-goto-error]
@@ -660,13 +744,16 @@ This command shares argument histories with \\[rgrep] and \\[grep]."
        (list nil
             (read-string "grep.el: No `grep-template' available. Press RET.")))
       (t (let* ((regexp (grep-read-regexp))
-               (files (grep-read-files regexp)))
-          (list regexp files))))))
+               (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
@@ -676,25 +763,30 @@ This command shares argument histories with \\[rgrep] and \\[grep]."
              (setq command
                    (read-from-minibuffer "Confirm: "
                                          command nil nil 'grep-history))
-           (push command grep-history))))
+           (add-to-history 'grep-history command))))
       (when command
-       ;; 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)))))
+       (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)
-  "Recusively grep for REGEXP in FILES in directory tree rooted at 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, allow user to edit the constructed
-shell command line before it is executed.
-With two \\[universal-argument] prefixes, edit and run grep-find shell command.
+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]
@@ -721,29 +813,41 @@ This command shares argument histories with \\[lgrep] and \\[grep-find]."
     (if (null files)
        (if (not (string= regexp grep-find-command))
            (compilation-start regexp 'grep-mode))
-      (let* ((default-directory (file-name-as-directory (expand-file-name dir)))
-            (command (grep-expand-template
-                      grep-find-template
-                      regexp
-                      (concat "\\( -name "
-                              (mapconcat #'shell-quote-argument
-                                         (split-string files)
-                                         " -o -name ")
-                              " \\)")
-                      default-directory
+      (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 "\\( -path '*/"
-                                   (mapconcat #'identity
+                           (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 '*/")
-                                   "' \\) -prune -o ")))))
+                                              " -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))
-           (push command grep-find-history))
-         (compilation-start command 'grep-mode))))))
+           (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)))))))
 
 
 (provide 'grep)