]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/grep.el
(gdb-flush-pending-output): New variable.
[gnu-emacs] / lisp / progmodes / grep.el
index a871380d06f5c1dc0ff86902d6c52bc2d2127c4f..7a13ddba6edf0c172af2c651e6b845981bd4f01e 100644 (file)
@@ -1,7 +1,7 @@
 ;;; grep.el --- run compiler as inferior of Emacs, parse error messages
 
 ;;; grep.el --- run compiler as inferior of Emacs, parse error messages
 
-;; Copyright (C) 1985, 86, 87, 93, 94, 95, 96, 97, 98, 1999, 2001, 02, 2004
-;;  Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+;;   2001, 2002, 2004  Free Software Foundation, Inc.
 
 ;; Author: Roland McGrath <roland@gnu.org>
 ;; Maintainer: FSF
 
 ;; Author: Roland McGrath <roland@gnu.org>
 ;; Maintainer: FSF
@@ -64,6 +64,26 @@ will be parsed and highlighted as soon as you try to move to them."
   :version "21.4"
   :group 'grep)
 
   :version "21.4"
   :group 'grep)
 
+(defcustom grep-highlight-matches 'auto-detect
+  "If t, use special markers to highlight grep matches.
+
+Some grep programs are able to surround matches with special
+markers in grep output.  Such markers can be used to highlight
+matches in grep mode.
+
+This option sets the environment variable GREP_COLOR to specify
+markers for highlighting and GREP_OPTIONS to add the --color
+option in front of any explicit grep options before starting
+the grep.
+
+The default value of this variable is set up by `grep-compute-defaults';
+call that function before using this variable in your program."
+  :type '(choice (const :tag "Do not highlight matches with grep markers" nil)
+                (const :tag "Highlight matches with grep markers" t)
+                (other :tag "Not Set" auto-detect))
+  :version "21.4"
+  :group 'grep)
+
 (defcustom grep-scroll-output nil
   "*Non-nil to scroll the *grep* buffer window as output appears.
 
 (defcustom grep-scroll-output nil
   "*Non-nil to scroll the *grep* buffer window as output appears.
 
@@ -95,7 +115,6 @@ necessary if the grep program used supports the `-H' option.
 
 The default value of this variable is set up by `grep-compute-defaults';
 call that function before using this variable in your program."
 
 The default value of this variable is set up by `grep-compute-defaults';
 call that function before using this variable in your program."
-  :type 'boolean
   :type '(choice (const :tag "Do Not Append Null Device" nil)
                 (const :tag "Append Null Device" t)
                 (other :tag "Not Set" auto-detect))
   :type '(choice (const :tag "Do Not Append Null Device" nil)
                 (const :tag "Append Null Device" t)
                 (other :tag "Not Set" auto-detect))
@@ -166,6 +185,7 @@ See `compilation-error-screen-columns'"
   (let ((map (cons 'keymap compilation-minor-mode-map)))
     (define-key map " " 'scroll-up)
     (define-key map "\^?" 'scroll-down)
   (let ((map (cons 'keymap compilation-minor-mode-map)))
     (define-key map " " 'scroll-up)
     (define-key map "\^?" 'scroll-down)
+    (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
 
     ;; This is intolerable -- rms
 ;;;    (define-key map [remap next-line] 'compilation-next-error)
 
     ;; This is intolerable -- rms
 ;;;    (define-key map [remap next-line] 'compilation-next-error)
@@ -230,6 +250,14 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
   '(("^\\(.+?\\)[:( \t]+\
 \\([0-9]+\\)\\([.:]?\\)\\([0-9]+\\)?\
 \\(?:-\\(?:\\([0-9]+\\)\\3\\)?\\.?\\([0-9]+\\)?\\)?[:) \t]" 1 (2 . 5) (4 . 6))
   '(("^\\(.+?\\)[:( \t]+\
 \\([0-9]+\\)\\([.:]?\\)\\([0-9]+\\)?\
 \\(?:-\\(?:\\([0-9]+\\)\\3\\)?\\.?\\([0-9]+\\)?\\)?[:) \t]" 1 (2 . 5) (4 . 6))
+    ("^\\(.+?\\)[:(]+\\([0-9]+\\)\\([:)]\\).*?\\(\033\\[01;41m\\)\\(.*?\\)\\(\033\\[00m\\)"
+     1 2
+     ;; Calculate column positions (beg . end) of first grep match on a line
+     ((lambda ()
+        (setq compilation-error-screen-columns nil)
+        (- (match-beginning 5) (match-end 3) 8))
+      .
+      (lambda () (- (match-end 5) (match-end 3) 8))))
     ("^Binary file \\(.+\\) matches$" 1 nil nil 1))
   "Regexp used to match grep hits.  See `compilation-error-regexp-alist'.")
 
     ("^Binary file \\(.+\\) matches$" 1 nil nil 1))
   "Regexp used to match grep hits.  See `compilation-error-regexp-alist'.")
 
@@ -257,7 +285,16 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
      ("^Grep \\(exited abnormally\\) with code \\([0-9]+\\).*"
       (0 '(face nil message nil help-echo nil mouse-face nil) t)
       (1 compilation-warning-face)
      ("^Grep \\(exited abnormally\\) with code \\([0-9]+\\).*"
       (0 '(face nil message nil help-echo nil mouse-face nil) t)
       (1 compilation-warning-face)
-      (2 compilation-line-face)))
+      (2 compilation-line-face))
+     ;; Highlight grep matches and delete markers
+     ("\\(\033\\[01;41m\\)\\(.*?\\)\\(\033\\[00m\\)"
+      (2 compilation-column-face)
+      ((lambda (p))
+       (progn
+        ;; Delete markers with `replace-match' because it updates
+        ;; the match-data, whereas `delete-region' would render it obsolete.
+        (replace-match "" t t nil 3)
+        (replace-match "" t t nil 1)))))
    "Additional things to highlight in grep output.
 This gets tacked on the end of the generated expressions.")
 
    "Additional things to highlight in grep output.
 This gets tacked on the end of the generated expressions.")
 
@@ -300,6 +337,12 @@ This variable's value takes effect when `grep-compute-defaults' is called.")
 (defun grep-process-setup ()
   "Setup compilation variables and buffer for `grep'.
 Set up `compilation-exit-message-function' and run `grep-setup-hook'."
 (defun grep-process-setup ()
   "Setup compilation variables and buffer for `grep'.
 Set up `compilation-exit-message-function' and run `grep-setup-hook'."
+  (unless (or (not grep-highlight-matches) (eq grep-highlight-matches t))
+    (grep-compute-defaults))
+  (when (eq grep-highlight-matches t)
+    ;; Modify `process-environment' locally bound in `compilation-start'
+    (setenv "GREP_OPTIONS" (concat (getenv "GREP_OPTIONS") " --color=always"))
+    (setenv "GREP_COLOR" "01;41"))
   (set (make-local-variable 'compilation-exit-message-function)
        (lambda (status code msg)
         (if (eq status 'exit)
   (set (make-local-variable 'compilation-exit-message-function)
        (lambda (status code msg)
         (if (eq status 'exit)
@@ -378,15 +421,26 @@ Set up `compilation-exit-message-function' and run `grep-setup-hook'."
                   (format "%s <D> <X> -type f <F> -print | xargs %s <R>"
                           find-program gcmd))
                  (t (format "%s <D> <X> -type f <F> -exec %s <R> {} %s \\;"
                   (format "%s <D> <X> -type f <F> -print | xargs %s <R>"
                           find-program gcmd))
                  (t (format "%s <D> <X> -type f <F> -exec %s <R> {} %s \\;"
-                            find-program gcmd null-device)))))))
+                            find-program gcmd null-device))))))
+  (unless (or (not grep-highlight-matches) (eq grep-highlight-matches t))
+    (setq grep-highlight-matches
+         (with-temp-buffer
+           (and (equal (condition-case nil
+                           (call-process grep-program nil t nil "--help")
+                         (error nil))
+                       0)
+                (progn
+                  (goto-char (point-min))
+                  (search-forward "--color" nil t))
+                t)))))
 
 (defun grep-default-command ()
   (let ((tag-default
 
 (defun grep-default-command ()
   (let ((tag-default
-        (funcall (or find-tag-default-function
-                     (get major-mode 'find-tag-default-function)
-                     ;; We use grep-tag-default instead of
-                     ;; find-tag-default, to avoid loading etags.
-                     'grep-tag-default)))
+         (shell-quote-argument
+          (or (funcall (or find-tag-default-function
+                           (get major-mode 'find-tag-default-function)
+                           'find-tag-default))
+              "")))
        (sh-arg-re "\\(\\(?:\"\\(?:[^\"]\\|\\\\\"\\)+\"\\|'[^']+'\\|[^\"' \t\n]\\)+\\)")
        (grep-default (or (car grep-history) grep-command)))
     ;; Replace the thing matching for with that around cursor.
        (sh-arg-re "\\(\\(?:\"\\(?:[^\"]\\|\\\\\"\\)+\"\\|'[^']+'\\|[^\"' \t\n]\\)+\\)")
        (grep-default (or (car grep-history) grep-command)))
     ;; Replace the thing matching for with that around cursor.
@@ -408,13 +462,13 @@ Set up `compilation-exit-message-function' and run `grep-setup-hook'."
                                              0 (match-beginning 2))
                                   " *."
                                   (file-name-extension buffer-file-name))))
                                              0 (match-beginning 2))
                                   " *."
                                   (file-name-extension buffer-file-name))))
-      (replace-match (or tag-default "") t t grep-default 1))))
+      (replace-match tag-default t t grep-default 1))))
 
 ;;;###autoload
 (defun grep (command-args &optional highlight-regexp)
   "Run grep, with user-specified args, and collect output in a buffer.
 While grep runs asynchronously, you can use \\[next-error] (M-x next-error),
 
 ;;;###autoload
 (defun grep (command-args &optional highlight-regexp)
   "Run grep, with user-specified args, and collect output in a buffer.
 While grep runs asynchronously, you can use \\[next-error] (M-x next-error),
-or \\<grep-minor-mode-map>\\[compile-goto-error] in the grep \
+or \\<grep-mode-map>\\[compile-goto-error] in the grep \
 output buffer, to go to the lines
 where grep found matches.
 
 output buffer, to go to the lines
 where grep found matches.
 
@@ -448,7 +502,6 @@ temporarily highlight in visited source lines."
                         command-args)
                       'grep-mode nil highlight-regexp)))
 
                         command-args)
                       'grep-mode nil highlight-regexp)))
 
-;;;###autoload (autoload 'grep-mode "grep" nil t)
 (define-compilation-mode grep-mode "Grep"
   "Sets `grep-last-buffer' and `compilation-window-height'."
   (setq grep-last-buffer (current-buffer))
 (define-compilation-mode grep-mode "Grep"
   "Sets `grep-last-buffer' and `compilation-window-height'."
   (setq grep-last-buffer (current-buffer))
@@ -457,25 +510,6 @@ temporarily highlight in visited source lines."
   (set (make-local-variable 'compilation-error-regexp-alist)
        grep-regexp-alist))
 
   (set (make-local-variable 'compilation-error-regexp-alist)
        grep-regexp-alist))
 
-;; This is a copy of find-tag-default from etags.el.
-;;;###autoload
-(defun grep-tag-default ()
-  (save-excursion
-    (while (looking-at "\\sw\\|\\s_")
-      (forward-char 1))
-    (when (or (re-search-backward "\\sw\\|\\s_"
-                                 (save-excursion (beginning-of-line) (point))
-                                 t)
-             (re-search-forward "\\(\\sw\\|\\s_\\)+"
-                                (save-excursion (end-of-line) (point))
-                                t))
-      (goto-char (match-end 0))
-      (buffer-substring (point)
-                       (progn (forward-sexp -1)
-                              (while (looking-at "\\s'")
-                                (forward-char 1))
-                              (point))))))
-
 ;;;###autoload
 (defun grep-find (command-args)
   "Run grep via find, with user-specified args COMMAND-ARGS.
 ;;;###autoload
 (defun grep-find (command-args)
   "Run grep via find, with user-specified args COMMAND-ARGS.
@@ -583,5 +617,5 @@ those sub directories of DIR."
 
 (provide 'grep)
 
 
 (provide 'grep)
 
-;;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d
+;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d
 ;;; grep.el ends here
 ;;; grep.el ends here