]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/grep.el
(compilation-start): In the no-async-subprocesses branch, call
[gnu-emacs] / lisp / progmodes / grep.el
index ea5fd421fe5ea36aec2fef4e8af6606cc571739e..94937ba1e87bcf9aa382ac2efa92d9378bc02190 100644 (file)
@@ -1,6 +1,6 @@
 ;;; grep.el --- run compiler as inferior of Emacs, parse error messages
 
-;; Copyright (C) 1985, 86, 87, 93, 94, 95, 96, 97, 98, 1999, 2001, 2002
+;; Copyright (C) 1985, 86, 87, 93, 94, 95, 96, 97, 98, 1999, 2001, 02, 2004
 ;;  Free Software Foundation, Inc.
 
 ;; Author: Roland McGrath <roland@gnu.org>
@@ -157,8 +157,9 @@ The following place holders should be present in the string:
     (define-key map " " 'scroll-up)
     (define-key map "\^?" 'scroll-down)
 
-    (define-key map [remap next-line] 'compilation-next-error)
-    (define-key map [remap previous-line] 'compilation-previous-error)
+    ;; This is intolerable -- rms
+;;;    (define-key map [remap next-line] 'compilation-next-error)
+;;;    (define-key map [remap previous-line] 'compilation-previous-error)
 
     (define-key map "\r" 'compile-goto-error)  ;; ?
     (define-key map "n" 'next-error-no-select)
@@ -193,6 +194,8 @@ The following place holders should be present in the string:
   "Keymap for grep buffers.
 `compilation-minor-mode-map' is a cdr of this.")
 
+(defalias 'kill-grep 'kill-compilation)
+
 ;;;; TODO --- refine this!!
 
 ;;; (defcustom grep-use-compilation-buffer t
@@ -212,12 +215,39 @@ 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'.")
 
-;; Note: the character class after the optional drive letter does not
-;; include a space to support file names with blanks.
 (defvar grep-regexp-alist
-  '(("\\([a-zA-Z]?:?[^:(\t\n]+\\)[:( \t]+\\([0-9]+\\)[:) \t]" 1 2))
+  '(("^\\(.+?\\)[:( \t]+\\([0-9]+\\)[:) \t]" 1 2)
+    ("^Binary file \\(.+\\) matches$" 1 nil nil 1))
   "Regexp used to match grep hits.  See `compilation-error-regexp-alist'.")
 
+(defvar grep-error "grep hit"
+  "Message to print when no matches are found.")
+
+;; Reverse the colors because grep hits are not errors (though we jump there
+;; with `next-error'), and unreadable files can't be gone to.
+(defvar grep-hit-face  compilation-info-face
+  "Face name to use for grep hits.")
+
+(defvar grep-error-face        compilation-error-face
+  "Face name to use for grep error messages.")
+
+(defvar grep-mode-font-lock-keywords
+   '(;; Command output lines.
+     ("^\\([A-Za-z_0-9/\.+-]+\\)[ \t]*:" 1 font-lock-function-name-face)
+     (": \\(.+\\): \\(?:Permission denied\\|No such \\(?:file or directory\\|device or address\\)\\)$"
+      1 grep-error-face)
+     ;; remove match from grep-regexp-alist before fontifying
+     ("^Grep finished \\(?:(\\(matches found\\))\\|with \\(no matches found\\)\\).*"
+      (0 '(face nil message nil help-echo nil mouse-face nil) t)
+      (1 grep-hit-face nil t)
+      (2 grep-error-face nil t))
+     ("^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)))
+   "Additional things to highlight in grep output.
+This gets tacked on the end of the generated expressions.")
+
 (defvar grep-program
   ;; Currently zgrep has trouble.  It runs egrep instead of grep,
   ;; and it doesn't pass along long options right.
@@ -250,9 +280,7 @@ 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 `compilation-window-height'.
-Sets `grep-last-buffer' and runs `grep-setup-hook'."
-  (setq grep-last-buffer (current-buffer))
+Set up `compilation-exit-message-function' and run `grep-setup-hook'."
   (set (make-local-variable 'compilation-exit-message-function)
        (lambda (status code msg)
         (if (eq status 'exit)
@@ -263,13 +291,6 @@ Sets `grep-last-buffer' and runs `grep-setup-hook'."
                   (t
                    (cons msg code)))
           (cons msg code))))
-  (if grep-window-height
-      (set (make-local-variable 'compilation-window-height)
-          grep-window-height))
-  (set (make-local-variable 'compile-auto-highlight)
-       grep-auto-highlight)
-  (set (make-local-variable 'compilation-scroll-output)
-       grep-scroll-output)
   (run-hooks 'grep-setup-hook))
 
 (defun grep-compute-defaults ()
@@ -317,7 +338,7 @@ Sets `grep-last-buffer' and runs `grep-setup-hook'."
              'gnu)))
   (unless grep-find-command
     (setq grep-find-command
-         (cond ((eq grep-find-use-xargs 'gnu)
+          (cond ((eq grep-find-use-xargs 'gnu)
                 (format "%s . -type f -print0 | xargs -0 -e %s"
                         find-program grep-command))
                (grep-find-use-xargs
@@ -401,15 +422,20 @@ temporarily highlight in visited source lines."
 
   ;; Setting process-setup-function makes exit-message-function work
   ;; even when async processes aren't supported.
-  (let* ((compilation-process-setup-function 'grep-process-setup)
-        (buf (compile-internal (if (and grep-use-null-device null-device)
-                                   (concat command-args " " null-device)
-                                 command-args)
-                               "No more grep hits" "grep"
-                               ;; Give it a simpler regexp to match.
-                               nil grep-regexp-alist
-                               nil nil nil nil nil nil
-                               highlight-regexp grep-mode-map)))))
+  (let ((compilation-process-setup-function 'grep-process-setup))
+    (compilation-start (if (and grep-use-null-device null-device)
+                          (concat command-args " " null-device)
+                        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-face)
+       grep-hit-face)
+  (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 ()
@@ -442,11 +468,17 @@ easily repeat a find command."
    (progn
      (unless grep-find-command
        (grep-compute-defaults))
-     (list (read-from-minibuffer "Run find (like this): "
-                                grep-find-command nil nil
-                                'grep-find-history))))
-  (let ((null-device nil))             ; see grep
-    (grep command-args)))
+     (if grep-find-command
+        (list (read-from-minibuffer "Run find (like this): "
+                                    grep-find-command nil nil
+                                     'grep-find-history))
+       ;; No default was set
+       (read-string
+        "compile.el: No `grep-find-command' command available. Press RET.")
+       (list nil))))
+  (when (and grep-find-command command-args)
+    (let ((null-device nil))           ; see grep
+      (grep command-args))))
 
 (defun grep-expand-command-macros (command &optional regexp files dir excl case-fold)
   "Patch grep COMMAND replacing <D>, etc."
@@ -530,5 +562,5 @@ those sub directories of DIR."
 
 (provide 'grep)
 
+;;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d
 ;;; grep.el ends here