X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/9b19858ed7a0fbd27702f9ba616f3307c97f910c..7c511b96e0cc692a4b772fe34ed7470b4020c20e:/lisp/progmodes/grep.el diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index a871380d06..7a13ddba6e 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -1,7 +1,7 @@ ;;; 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 ;; 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) +(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. @@ -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." - :type 'boolean :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) + (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) @@ -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)) + ("^\\(.+?\\)[:(]+\\([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'.") @@ -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) - (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.") @@ -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'." + (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) @@ -378,15 +421,26 @@ Set up `compilation-exit-message-function' and run `grep-setup-hook'." (format "%s -type f -print | xargs %s " find-program gcmd)) (t (format "%s -type f -exec %s {} %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. @@ -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)))) - (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 \\\\[compile-goto-error] in the grep \ +or \\\\[compile-goto-error] in the grep \ 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))) -;;;###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)) @@ -457,25 +510,6 @@ temporarily highlight in visited source lines." (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. @@ -583,5 +617,5 @@ those sub directories of DIR." (provide 'grep) -;;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d +;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d ;;; grep.el ends here