;;; 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
: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.
: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
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)
+;;;###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';
:type 'boolean
:group 'grep)
+(defcustom grep-error-screen-columns nil
+ "*If non-nil, column numbers in grep hits are screen columns.
+See `compilation-error-screen-columns'"
+ :type '(choice (const :tag "Default" nil)
+ integer)
+ :version "21.4"
+ :group 'grep)
+
;;;###autoload
(defcustom grep-setup-hook nil
"List of hook functions run by `grep-process-setup' (see `run-hooks')."
(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)
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]+\\)[:) \t]" 1 2)
+ '(("^\\(.+?\\)[:( \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'.")
("^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.")
+;;;###autoload
(defvar grep-program
;; Currently zgrep has trouble. It runs egrep instead of grep,
;; and it doesn't pass along long options right.
"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.")
+;;;###autoload
(defvar grep-find-use-xargs nil
"Whether \\[grep-find] uses the `xargs' utility by default.
This variable's value takes effect when `grep-compute-defaults' is called.")
;; History of grep commands.
+;;;###autoload
(defvar grep-history nil)
+;;;###autoload
(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'."
+ (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)
(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
(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)
- ;; 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.
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),
-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.
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))
(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.
(provide 'grep)
-;;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d
+;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d
;;; grep.el ends here