]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/grep.el
Merge from emacs-24
[gnu-emacs] / lisp / progmodes / grep.el
index c8a0dc449dfc2dac8dd2766211ea239e5dc2ab93..fd48adc70c654477737059997c402fd5d9d7e569 100644 (file)
@@ -1,10 +1,9 @@
-;;; grep.el --- run `grep' and display the results
+;;; grep.el --- run `grep' and display the results  -*- lexical-binding:t -*-
 
 
-;; Copyright (C) 1985-1987, 1993-1999, 2001-2013 Free Software
-;; Foundation, Inc.
+;; Copyright (C) 1985-1987, 1993-1999, 2001-2014 Free Software Foundation, Inc.
 
 ;; Author: Roland McGrath <roland@gnu.org>
 
 ;; Author: Roland McGrath <roland@gnu.org>
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: tools, processes
 
 ;; This file is part of GNU Emacs.
 ;; Keywords: tools, processes
 
 ;; This file is part of GNU Emacs.
@@ -77,11 +76,10 @@ in grep buffers, so if you have globally disabled font-lock-mode,
 you will not get highlighting.
 
 This option sets the environment variable GREP_COLORS to specify
 you will not get highlighting.
 
 This option sets the environment variable GREP_COLORS to specify
-markers for highlighting and GREP_OPTIONS to add the --color
-option in front of any explicit grep options before starting
-the grep.
+markers for highlighting and adds the --color option in front of
+any explicit grep options before starting the grep.
 
 
-When this option is `auto', grep uses `--color=auto' to highlight
+When this option is `auto', grep uses `--color' to highlight
 matches only when it outputs to a terminal (when `grep' is the last
 command in the pipe), thus avoiding the use of any potentially-harmful
 escape sequences when standard output goes to a file or pipe.
 matches only when it outputs to a terminal (when `grep' is the last
 command in the pipe), thus avoiding the use of any potentially-harmful
 escape sequences when standard output goes to a file or pipe.
@@ -97,7 +95,7 @@ To change the default value, use Customize or call the function
   :type '(choice (const :tag "Do not highlight matches with grep markers" nil)
                 (const :tag "Highlight matches with grep markers" t)
                 (const :tag "Use --color=always" always)
   :type '(choice (const :tag "Do not highlight matches with grep markers" nil)
                 (const :tag "Highlight matches with grep markers" t)
                 (const :tag "Use --color=always" always)
-                (const :tag "Use --color=auto" auto)
+                (const :tag "Use --color" auto)
                 (other :tag "Not Set" auto-detect))
   :set 'grep-apply-setting
   :version "22.1"
                 (other :tag "Not Set" auto-detect))
   :set 'grep-apply-setting
   :version "22.1"
@@ -246,6 +244,7 @@ See `compilation-error-screen-columns'"
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map compilation-minor-mode-map)
     (define-key map " " 'scroll-up-command)
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map compilation-minor-mode-map)
     (define-key map " " 'scroll-up-command)
+    (define-key map [?\S-\ ] 'scroll-down-command)
     (define-key map "\^?" 'scroll-down-command)
     (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
 
     (define-key map "\^?" 'scroll-down-command)
     (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
 
@@ -344,22 +343,17 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
 ;;;###autoload
 (defconst grep-regexp-alist
   '(
 ;;;###autoload
 (defconst grep-regexp-alist
   '(
-    ;; Rule to match column numbers is commented out since no known grep
-    ;; produces them
-    ;; ("^\\(.+?\\)\\(:[ \t]*\\)\\([1-9][0-9]*\\)\\2\\(?:\\([1-9][0-9]*\\)\\(?:-\\([1-9][0-9]*\\)\\)?\\2\\)?"
-    ;;  1 3 (4 . 5))
-    ;; Note that we want to use as tight a regexp as we can to try and
-    ;; handle weird file names (with colons in them) as well as possible.
-    ;; E.g. we use [1-9][0-9]* rather than [0-9]+ so as to accept ":034:"
-    ;; in file names.
-    ("^\\(.+?\\)\\(:[ \t]*\\)\\([1-9][0-9]*\\)\\2"
-     1 3
+    ;; Use a tight regexp to handle weird file names (with colons
+    ;; in them) as well as possible.  E.g., use [1-9][0-9]* rather
+    ;; than [0-9]+ so as to accept ":034:" in file names.
+    ("^\\(.*?[^/\n]\\):[ \t]*\\([1-9][0-9]*\\)[ \t]*:"
+     1 2
      ;; Calculate column positions (col . end-col) of first grep match on a line
      ((lambda ()
        (when grep-highlight-matches
          (let* ((beg (match-end 0))
                 (end (save-excursion (goto-char beg) (line-end-position)))
      ;; Calculate column positions (col . end-col) of first grep match on a line
      ((lambda ()
        (when grep-highlight-matches
          (let* ((beg (match-end 0))
                 (end (save-excursion (goto-char beg) (line-end-position)))
-                (mbeg (text-property-any beg end 'font-lock-face 'match)))
+                (mbeg (text-property-any beg end 'font-lock-face grep-match-face)))
            (when mbeg
              (- mbeg beg)))))
       .
            (when mbeg
              (- mbeg beg)))))
       .
@@ -367,7 +361,7 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
        (when grep-highlight-matches
          (let* ((beg (match-end 0))
                 (end (save-excursion (goto-char beg) (line-end-position)))
        (when grep-highlight-matches
          (let* ((beg (match-end 0))
                 (end (save-excursion (goto-char beg) (line-end-position)))
-                (mbeg (text-property-any beg end 'font-lock-face 'match))
+                (mbeg (text-property-any beg end 'font-lock-face grep-match-face))
                 (mend (and mbeg (next-single-property-change mbeg 'font-lock-face nil end))))
            (when mend
              (- mend beg)))))))
                 (mend (and mbeg (next-single-property-change mbeg 'font-lock-face nil end))))
            (when mend
              (- mend beg)))))))
@@ -409,7 +403,9 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies
       (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t)
       (1 grep-error-face)
       (2 grep-error-face nil t))
       (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t)
       (1 grep-error-face)
       (2 grep-error-face nil t))
-     ("^.+?-[0-9]+-.*\n" (0 grep-context-face)))
+     ;; "filename-linenumber-" format is used for context lines in GNU grep,
+     ;; "filename=linenumber=" for lines with function names in "git grep -p".
+     ("^.+?[-=][0-9]+[-=].*\n" (0 grep-context-face)))
    "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.")
 
@@ -420,8 +416,9 @@ This variable's value takes effect when `grep-compute-defaults' is called.")
 
 ;;;###autoload
 (defvar find-program (purecopy "find")
 
 ;;;###autoload
 (defvar find-program (purecopy "find")
-  "The default find program for `grep-find-command'.
-This variable's value takes effect when `grep-compute-defaults' is called.")
+  "The default find program.
+This is used by commands like `grep-find-command', `find-dired'
+and others.")
 
 ;;;###autoload
 (defvar xargs-program (purecopy "xargs")
 
 ;;;###autoload
 (defvar xargs-program (purecopy "xargs")
@@ -463,10 +460,6 @@ Set up `compilation-exit-message-function' and run `grep-setup-hook'."
     ;; `setenv' modifies `process-environment' let-bound in `compilation-start'
     ;; Any TERM except "dumb" allows GNU grep to use `--color=auto'
     (setenv "TERM" "emacs-grep")
     ;; `setenv' modifies `process-environment' let-bound in `compilation-start'
     ;; Any TERM except "dumb" allows GNU grep to use `--color=auto'
     (setenv "TERM" "emacs-grep")
-    (setenv "GREP_OPTIONS"
-           (concat (getenv "GREP_OPTIONS")
-                   " --color=" (if (eq grep-highlight-matches 'always)
-                                   "always" "auto")))
     ;; GREP_COLOR is used in GNU grep 2.5.1, but deprecated in later versions
     (setenv "GREP_COLOR" "01;31")
     ;; GREP_COLORS is used in GNU grep 2.5.2 and later versions
     ;; GREP_COLOR is used in GNU grep 2.5.1, but deprecated in later versions
     (setenv "GREP_COLOR" "01;31")
     ;; GREP_COLORS is used in GNU grep 2.5.2 and later versions
@@ -566,7 +559,13 @@ This function is called from `compilation-filter-hook'."
     (unless (and grep-command grep-find-command
                 grep-template grep-find-template)
       (let ((grep-options
     (unless (and grep-command grep-find-command
                 grep-template grep-find-template)
       (let ((grep-options
-            (concat (if grep-use-null-device "-n" "-nH")
+            (concat (and grep-highlight-matches
+                         (grep-probe grep-program
+                                     `(nil nil nil "--color" "x" ,null-device)
+                                     nil 1)
+                         (if (eq grep-highlight-matches 'always)
+                             "--color=always " "--color "))
+                    (if grep-use-null-device "-n" "-nH")
                     (if (grep-probe grep-program
                                     `(nil nil nil "-e" "foo" ,null-device)
                                     nil 1)
                     (if (grep-probe grep-program
                                     `(nil nil nil "-e" "foo" ,null-device)
                                     nil 1)
@@ -586,7 +585,7 @@ This function is called from `compilation-filter-hook'."
                  'exec-plus)
                 ((and
                   (grep-probe find-program `(nil nil nil ,null-device "-print0"))
                  'exec-plus)
                 ((and
                   (grep-probe find-program `(nil nil nil ,null-device "-print0"))
-                  (grep-probe xargs-program `(nil nil nil "-0" "-e" "echo")))
+                  (grep-probe xargs-program `(nil nil nil "-0" "echo")))
                  'gnu)
                 (t
                  'exec))))
                  'gnu)
                 (t
                  'exec))))
@@ -596,7 +595,7 @@ This function is called from `compilation-filter-hook'."
                       ;; Windows shells need the program file name
                       ;; after the pipe symbol be quoted if they use
                       ;; forward slashes as directory separators.
                       ;; Windows shells need the program file name
                       ;; after the pipe symbol be quoted if they use
                       ;; forward slashes as directory separators.
-                      (format "%s . -type f -print0 | \"%s\" -0 -e %s"
+                      (format "%s . -type f -print0 | \"%s\" -0 %s"
                               find-program xargs-program grep-command))
                      ((memq grep-find-use-xargs '(exec exec-plus))
                       (let ((cmd0 (format "%s . -type f -exec %s"
                               find-program xargs-program grep-command))
                      ((memq grep-find-use-xargs '(exec exec-plus))
                       (let ((cmd0 (format "%s . -type f -exec %s"
@@ -621,7 +620,7 @@ This function is called from `compilation-filter-hook'."
                                (format "%s " null-device)
                              "")))
                  (cond ((eq grep-find-use-xargs 'gnu)
                                (format "%s " null-device)
                              "")))
                  (cond ((eq grep-find-use-xargs 'gnu)
-                        (format "%s . <X> -type f <F> -print0 | \"%s\" -0 -e %s"
+                        (format "%s . <X> -type f <F> -print0 | \"%s\" -0 %s"
                                 find-program xargs-program gcmd))
                        ((eq grep-find-use-xargs 'exec)
                         (format "%s . <X> -type f <F> -exec %s {} %s%s"
                                 find-program xargs-program gcmd))
                        ((eq grep-find-use-xargs 'exec)
                         (format "%s . <X> -type f <F> -exec %s {} %s%s"
@@ -801,27 +800,26 @@ substitution string.  Note dynamic scoping of variables.")
 
 (defun grep-expand-template (template &optional regexp files dir excl)
   "Patch grep COMMAND string replacing <C>, <D>, <F>, <R>, and <X>."
 
 (defun grep-expand-template (template &optional regexp files dir excl)
   "Patch grep COMMAND string replacing <C>, <D>, <F>, <R>, and <X>."
-  (let ((command template)
-       (cf case-fold-search)
-       (case-fold-search nil))
+  (let* ((command template)
+         (env `((cf . ,case-fold-search)
+                (excl . ,excl)
+                (dir . ,dir)
+                (files . ,files)
+                (regexp . ,regexp)))
+         (case-fold-search nil))
     (dolist (kw grep-expand-keywords command)
       (if (string-match (car kw) command)
          (setq command
                (replace-match
                 (or (if (symbolp (cdr kw))
     (dolist (kw grep-expand-keywords command)
       (if (string-match (car kw) command)
          (setq command
                (replace-match
                 (or (if (symbolp (cdr kw))
-                        (symbol-value (cdr kw))
-                      (save-match-data (eval (cdr kw))))
+                        (eval (cdr kw) env)
+                      (save-match-data (eval (cdr kw) env)))
                     "")
                 t t command))))))
 
 (defun grep-read-regexp ()
                     "")
                 t t command))))))
 
 (defun grep-read-regexp ()
-  "Read regexp arg for interactive grep."
-  (let ((default (grep-tag-default)))
-    (read-regexp
-     (concat "Search for"
-            (if (and default (> (length default) 0))
-                (format " (default \"%s\"): " default) ": "))
-     default 'grep-regexp-history)))
+  "Read regexp arg for interactive grep using `read-regexp'."
+  (read-regexp "Search for" 'grep-tag-default 'grep-regexp-history))
 
 (defun grep-read-files (regexp)
   "Read files arg for interactive grep."
 
 (defun grep-read-files (regexp)
   "Read files arg for interactive grep."
@@ -902,7 +900,7 @@ This command shares argument histories with \\[rgrep] and \\[grep]."
                (confirm (equal current-prefix-arg '(4))))
           (list regexp files dir confirm))))))
   (when (and (stringp regexp) (> (length regexp) 0))
                (confirm (equal current-prefix-arg '(4))))
           (list regexp files dir confirm))))))
   (when (and (stringp regexp) (> (length regexp) 0))
-    (unless (and dir (file-directory-p dir) (file-readable-p dir))
+    (unless (and dir (file-accessible-directory-p dir))
       (setq dir default-directory))
     (let ((command regexp))
       (if (null files)
       (setq dir default-directory))
     (let ((command regexp))
       (if (null files)
@@ -983,7 +981,7 @@ to specify a command to run."
                (confirm (equal current-prefix-arg '(4))))
           (list regexp files dir confirm))))))
   (when (and (stringp regexp) (> (length regexp) 0))
                (confirm (equal current-prefix-arg '(4))))
           (list regexp files dir confirm))))))
   (when (and (stringp regexp) (> (length regexp) 0))
-    (unless (and dir (file-directory-p dir) (file-readable-p dir))
+    (unless (and dir (file-accessible-directory-p dir))
       (setq dir default-directory))
     (if (null files)
        (if (not (string= regexp (if (consp grep-find-command)
       (setq dir default-directory))
     (if (null files)
        (if (not (string= regexp (if (consp grep-find-command)
@@ -997,9 +995,10 @@ to specify a command to run."
                      regexp
                      (concat (shell-quote-argument "(")
                              " " find-name-arg " "
                      regexp
                      (concat (shell-quote-argument "(")
                              " " find-name-arg " "
-                             (mapconcat #'shell-quote-argument
-                                        (split-string files)
-                                        (concat " -o " find-name-arg " "))
+                             (mapconcat
+                              #'shell-quote-argument
+                              (split-string files)
+                              (concat " -o " find-name-arg " "))
                              " "
                              (shell-quote-argument ")"))
                      dir
                              " "
                              (shell-quote-argument ")"))
                      dir
@@ -1055,7 +1054,7 @@ to specify a command to run."
              (setq default-directory dir)))))))
 
 ;;;###autoload
              (setq default-directory dir)))))))
 
 ;;;###autoload
-(defun zrgrep (regexp &optional files dir confirm grep-find-template)
+(defun zrgrep (regexp &optional files dir confirm template)
   "Recursively grep for REGEXP in gzipped FILES in tree rooted at DIR.
 Like `rgrep' but uses `zgrep' for `grep-program', sets the default
 file name to `*.gz', and sets `grep-highlight-matches' to `always'."
   "Recursively grep for REGEXP in gzipped FILES in tree rooted at DIR.
 Like `rgrep' but uses `zgrep' for `grep-program', sets the default
 file name to `*.gz', and sets `grep-highlight-matches' to `always'."
@@ -1090,10 +1089,8 @@ file name to `*.gz', and sets `grep-highlight-matches' to `always'."
             (list regexp files dir confirm grep-find-template)))))))
   ;; Set `grep-highlight-matches' to `always'
   ;; since `zgrep' puts filters in the grep output.
             (list regexp files dir confirm grep-find-template)))))))
   ;; Set `grep-highlight-matches' to `always'
   ;; since `zgrep' puts filters in the grep output.
-  (let ((grep-highlight-matches 'always))
-    ;; `rgrep' uses the dynamically bound value `grep-find-template'
-    ;; from the argument `grep-find-template' whose value is computed
-    ;; in the `interactive' spec.
+  (let ((grep-find-template template)
+        (grep-highlight-matches 'always))
     (rgrep regexp files dir confirm)))
 
 ;;;###autoload
     (rgrep regexp files dir confirm)))
 
 ;;;###autoload