]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/grep.el
(etags-tags-completion-table): Use progress reporter.
[gnu-emacs] / lisp / progmodes / grep.el
index 1916bde9ea11ea94d4a8944114a5303e8a4a8d8c..4d9e05109a831d4ceb83f7c09daaae2d3e0e8052 100644 (file)
@@ -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.
 
@@ -74,6 +94,7 @@ than the begining."
   :version "21.4"
   :group 'grep)
 
   :version "21.4"
   :group 'grep)
 
+;;;###autoload
 (defcustom grep-command nil
   "The default grep command for \\[grep].
 If the grep program used supports an option to always include file names
 (defcustom grep-command nil
   "The default grep command for \\[grep].
 If the grep program used supports an option to always include file names
@@ -94,12 +115,12 @@ 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))
   :group 'grep)
 
   :type '(choice (const :tag "Do Not Append Null Device" nil)
                 (const :tag "Append Null Device" t)
                 (other :tag "Not Set" auto-detect))
   :group 'grep)
 
+;;;###autoload
 (defcustom grep-find-command nil
   "The default find command for \\[grep-find].
 The default value of this variable is set up by `grep-compute-defaults';
 (defcustom grep-find-command nil
   "The default find command for \\[grep-find].
 The default value of this variable is set up by `grep-compute-defaults';
@@ -164,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)
@@ -223,10 +245,28 @@ or when it is used with \\[grep-next-match].
 Notice that using \\[next-error] or \\[compile-goto-error] modifies
 `complation-last-buffer' rather than `grep-last-buffer'.")
 
 Notice that using \\[next-error] or \\[compile-goto-error] modifies
 `complation-last-buffer' rather than `grep-last-buffer'.")
 
+;;;###autoload
 (defvar grep-regexp-alist
   '(("^\\(.+?\\)[:( \t]+\
 \\([0-9]+\\)\\([.:]?\\)\\([0-9]+\\)?\
 \\(?:-\\(?:\\([0-9]+\\)\\3\\)?\\.?\\([0-9]+\\)?\\)?[:) \t]" 1 (2 . 5) (4 . 6))
 (defvar grep-regexp-alist
   '(("^\\(.+?\\)[:( \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
+     ((lambda ()
+        (setq compilation-error-screen-columns nil)
+        (- (match-beginning 5) (match-end 3) 8))
+      .
+      (lambda () (- (match-end 5) (match-end 3) 8)))
+     nil nil
+     (4 (list 'face nil 'invisible t 'intangible t))
+     (5 (list 'face compilation-column-face))
+     (6 (list 'face nil 'invisible t 'intangible t))
+     ;; highlight other matches on the same line
+     ("\\(\033\\[01;41m\\)\\(.*?\\)\\(\033\\[00m\\)"
+      nil nil
+      (1 (list 'face nil 'invisible t 'intangible t))
+      (2 (list 'face compilation-column-face) t)
+      (3 (list 'face nil 'invisible t 'intangible t))))
     ("^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'.")
 
@@ -258,6 +298,7 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
    "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.")
 
+;;;###autoload
 (defvar grep-program
   ;; Currently zgrep has trouble.  It runs egrep instead of grep,
   ;; and it doesn't pass along long options right.
 (defvar grep-program
   ;; Currently zgrep has trouble.  It runs egrep instead of grep,
   ;; and it doesn't pass along long options right.
@@ -272,10 +313,12 @@ This gets tacked on the end of the generated expressions.")
   "The default grep program for `grep-command' and `grep-find-command'.
 This variable's value takes effect when `grep-compute-defaults' is called.")
 
   "The default grep program for `grep-command' and `grep-find-command'.
 This variable's value takes effect when `grep-compute-defaults' is called.")
 
+;;;###autoload
 (defvar find-program "find"
   "The default find program for `grep-find-command'.
 This variable's value takes effect when `grep-compute-defaults' is called.")
 
 (defvar find-program "find"
   "The default find program for `grep-find-command'.
 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.
 
 (defvar grep-find-use-xargs nil
   "Whether \\[grep-find] uses the `xargs' utility by default.
 
@@ -285,12 +328,21 @@ if not nil and not `gnu', it uses `find -print' and `xargs'.
 This variable's value takes effect when `grep-compute-defaults' is called.")
 
 ;; History of grep commands.
 This variable's value takes effect when `grep-compute-defaults' is called.")
 
 ;; History of grep commands.
+;;;###autoload
 (defvar grep-history nil)
 (defvar grep-history nil)
+;;;###autoload
 (defvar grep-find-history nil)
 
 (defvar grep-find-history nil)
 
+;;;###autoload
 (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)
@@ -303,6 +355,7 @@ Set up `compilation-exit-message-function' and run `grep-setup-hook'."
           (cons msg code))))
   (run-hooks 'grep-setup-hook))
 
           (cons msg code))))
   (run-hooks 'grep-setup-hook))
 
+;;;###autoload
 (defun grep-compute-defaults ()
   (unless (or (not grep-use-null-device) (eq grep-use-null-device t))
     (setq grep-use-null-device
 (defun grep-compute-defaults ()
   (unless (or (not grep-use-null-device) (eq grep-use-null-device t))
     (setq grep-use-null-device
@@ -368,15 +421,24 @@ 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
         (funcall (or find-tag-default-function
                      (get major-mode 'find-tag-default-function)
 
 (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)))
+                     '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.
@@ -404,7 +466,7 @@ Set up `compilation-exit-message-function' and run `grep-setup-hook'."
 (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),
 (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.
 
@@ -438,7 +500,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))
@@ -447,24 +508,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.
-(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.
@@ -572,5 +615,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