]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/compile.el
Add arch taglines
[gnu-emacs] / lisp / progmodes / compile.el
index c06d01594bd34e85b5401c577c653bdb2b680df1..8f88bae612e52028df9eecc84e9057afa43788a2 100644 (file)
@@ -1,6 +1,6 @@
 ;;; compile.el --- run compiler as inferior of Emacs, parse error messages
 
 ;;; compile.el --- run compiler as inferior of Emacs, parse error messages
 
-;; Copyright (C) 1985, 86, 87, 93, 94, 95, 96, 97, 98, 1999, 2001
+;; Copyright (C) 1985, 86, 87, 93, 94, 95, 96, 97, 98, 1999, 2001, 2003
 ;;  Free Software Foundation, Inc.
 
 ;; Author: Roland McGrath <roland@gnu.org>
 ;;  Free Software Foundation, Inc.
 
 ;; Author: Roland McGrath <roland@gnu.org>
@@ -50,7 +50,7 @@
                 integer)
   :group 'compilation)
 
                 integer)
   :group 'compilation)
 
-(defcustom compile-auto-highlight nil
+(defcustom compile-auto-highlight t
   "*Specify how many compiler errors to highlight (and parse) initially.
 \(Highlighting applies to an error message when the mouse is over it.)
 If this is a number N, all compiler error messages in the first N lines
   "*Specify how many compiler errors to highlight (and parse) initially.
 \(Highlighting applies to an error message when the mouse is over it.)
 If this is a number N, all compiler error messages in the first N lines
@@ -66,75 +66,6 @@ will be parsed and highlighted as soon as you try to move to them."
                 (integer :tag "First N lines"))
   :group 'compilation)
 
                 (integer :tag "First N lines"))
   :group 'compilation)
 
-;;; This has to be here so it can be called
-;;; by the following defcustoms.
-(defun grep-compute-defaults ()
-  (unless (or (not grep-use-null-device) (eq grep-use-null-device t))
-    (setq grep-use-null-device
-         (with-temp-buffer
-           (let ((hello-file (expand-file-name "HELLO" data-directory)))
-             (not
-              (and (equal (condition-case nil
-                              (if grep-command
-                                  ;; `grep-command' is already set, so
-                                  ;; use that for testing.
-                                  (call-process-shell-command
-                                   grep-command nil t nil
-                                   "^English" hello-file)
-                                ;; otherwise use `grep-program'
-                                (call-process grep-program nil t nil
-                                              "-nH" "^English" hello-file))
-                            (error nil))
-                          0)
-                   (progn
-                     (goto-char (point-min))
-                     (looking-at
-                      (concat (regexp-quote hello-file)
-                              ":[0-9]+:English")))))))))
-  (unless grep-command
-    (setq grep-command
-         (let ((required-options (if grep-use-null-device "-n" "-nH")))
-           (if (equal (condition-case nil ; in case "grep" isn't in exec-path
-                          (call-process grep-program nil nil nil
-                                        "-e" "foo" null-device)
-                        (error nil))
-                      1)
-               (format "%s %s -e " grep-program required-options)
-             (format "%s %s " grep-program required-options)))))
-  (unless grep-find-use-xargs
-    (setq grep-find-use-xargs
-         (if (and
-               (equal (call-process "find" nil nil nil
-                                    null-device "-print0")
-                      0)
-               (equal (call-process "xargs" nil nil nil
-                                    "-0" "-e" "echo")
-                    0))
-             'gnu)))
-  (unless grep-find-command
-    (setq grep-find-command
-         (cond ((eq grep-find-use-xargs 'gnu)
-                (format "%s . -type f -print0 | xargs -0 -e %s"
-                        find-program grep-command))
-               (grep-find-use-xargs
-                (format "%s . -type f -print | xargs %s"
-                         find-program grep-command))
-               (t (cons (format "%s . -type f -exec %s {} %s \\;"
-                                find-program grep-command null-device)
-                        (+ 22 (length grep-command)))))))
-  (unless grep-tree-command
-    (setq grep-tree-command
-         (let* ((glen (length grep-program))
-                (gcmd (concat grep-program " <C>" (substring grep-command glen))))
-           (cond ((eq grep-find-use-xargs 'gnu)
-                  (format "%s <D> <X> -type f <F> -print0 | xargs -0 -e %s <R>"
-                          find-program gcmd))
-                 (grep-find-use-xargs
-                  (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)))))))
-
 (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
@@ -143,14 +74,12 @@ include it when specifying `grep-command'.
 
 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 'string
-  :get '(lambda (symbol)
-         (or grep-command
-             (progn (grep-compute-defaults) grep-command)))
+  :type '(choice string
+                (const :tag "Not Set" nil))
   :group 'compilation)
 
 (defcustom grep-use-null-device 'auto-detect
   :group 'compilation)
 
 (defcustom grep-use-null-device 'auto-detect
-  "If non-nil, append the value of `null-device' to grep commands.
+  "If t, append the value of `null-device' to `grep' commands.
 This is done to ensure that the output of grep includes the filename of
 any match in the case where only a single file is searched, and is not
 necessary if the grep program used supports the `-H' option.
 This is done to ensure that the output of grep includes the filename of
 any match in the case where only a single file is searched, and is not
 necessary if the grep program used supports the `-H' option.
@@ -158,20 +87,17 @@ 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
 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
-  :get '(lambda (symbol)
-         (if (and grep-use-null-device (not (eq grep-use-null-device t)))
-             (progn (grep-compute-defaults) grep-use-null-device)
-           grep-use-null-device))
+  :type '(choice (const :tag "Do Not Append Null Device" nil)
+                (const :tag "Append Null Device" t)
+                (other :tag "Not Set" auto-detect))
   :group 'compilation)
 
 (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';
 call that function before using this variable in your program."
   :group 'compilation)
 
 (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';
 call that function before using this variable in your program."
-  :type 'string
-  :get (lambda (symbol)
-        (or grep-find-command
-            (progn (grep-compute-defaults) grep-find-command)))
+  :type '(choice string
+                (const :tag "Not Set" nil))
   :group 'compilation)
 
 (defcustom grep-tree-command nil
   :group 'compilation)
 
 (defcustom grep-tree-command nil
@@ -184,11 +110,9 @@ The following place holders should be present in the string:
  <F> - find options to limit the files matched
  <C> - place to put -i if case insensitive grep
  <R> - the regular expression searched for."
  <F> - find options to limit the files matched
  <C> - place to put -i if case insensitive grep
  <R> - the regular expression searched for."
-  :type 'string
+  :type '(choice string
+                (const :tag "Not Set" nil))
   :version "21.4"
   :version "21.4"
-  :get (lambda (symbol)
-        (or grep-tree-command
-            (progn (grep-compute-defaults) grep-tree-command)))
   :group 'compilation)
 
 (defcustom grep-tree-files-aliases '(
   :group 'compilation)
 
 (defcustom grep-tree-files-aliases '(
@@ -325,26 +249,26 @@ or when it is used with \\[next-error] or \\[compile-goto-error].")
     ;; GNU utilities with precise locations (line and columns),
     ;; possibly ranges:
     ;;  foo.c:8.23-9.1: error message
     ;; GNU utilities with precise locations (line and columns),
     ;; possibly ranges:
     ;;  foo.c:8.23-9.1: error message
-    ("\\([a-zA-Z][-a-zA-Z._0-9]+: ?\\)\
+    ("\\([a-zA-Z][-a-zA-Z._0-9]+\\): ?\
 \\([0-9]+\\)\\.\\([0-9]+\\)\
 -\\([0-9]+\\)\\.\\([0-9]+\\)\
 :" 1 2 3) ;; When ending points are supported, add line = 4 and col = 5.
     ;;  foo.c:8.23-45: error message
 \\([0-9]+\\)\\.\\([0-9]+\\)\
 -\\([0-9]+\\)\\.\\([0-9]+\\)\
 :" 1 2 3) ;; When ending points are supported, add line = 4 and col = 5.
     ;;  foo.c:8.23-45: error message
-    ("\\([a-zA-Z][-a-zA-Z._0-9]+: ?\\)\
+    ("\\([a-zA-Z][-a-zA-Z._0-9]+\\): ?\
 \\([0-9]+\\)\\.\\([0-9]+\\)\
 -\\([0-9]+\\)\
 :" 1 2 3) ;; When ending points are supported, add line = 2 and col = 4.
     ;;  foo.c:8-45.3: error message
 \\([0-9]+\\)\\.\\([0-9]+\\)\
 -\\([0-9]+\\)\
 :" 1 2 3) ;; When ending points are supported, add line = 2 and col = 4.
     ;;  foo.c:8-45.3: error message
-    ("\\([a-zA-Z][-a-zA-Z._0-9]+: ?\\)\
+    ("\\([a-zA-Z][-a-zA-Z._0-9]+\\): ?\
 \\([0-9]+\\)\
 -\\([0-9]+\\)\\.\\([0-9]+\\)\
 :" 1 2 nil) ;; When ending points are supported, add line = 2 and col = 4.
     ;;  foo.c:8.23: error message
 \\([0-9]+\\)\
 -\\([0-9]+\\)\\.\\([0-9]+\\)\
 :" 1 2 nil) ;; When ending points are supported, add line = 2 and col = 4.
     ;;  foo.c:8.23: error message
-    ("\\([a-zA-Z][-a-zA-Z._0-9]+: ?\\)\
+    ("\\([a-zA-Z][-a-zA-Z._0-9]+\\): ?\
 \\([0-9]+\\)\\.\\([0-9]+\\)\
 :" 1 2 3)
     ;;  foo.c:8-23: error message
 \\([0-9]+\\)\\.\\([0-9]+\\)\
 :" 1 2 3)
     ;;  foo.c:8-23: error message
-    ("\\([a-zA-Z][-a-zA-Z._0-9]+: ?\\)\
+    ("\\([a-zA-Z][-a-zA-Z._0-9]+\\): ?\
 \\([0-9]+\\)\
 -\\([0-9]+\\)\
 :" 1 2 nil);; When ending points are supported, add line = 3.
 \\([0-9]+\\)\
 -\\([0-9]+\\)\
 :" 1 2 nil);; When ending points are supported, add line = 3.
@@ -513,6 +437,14 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2)
     ;; in unnamed entity at line 4 char 8 of file:///home/reto/test/group.xml
     ("Warning:.*\n.* line \\([0-9]+\\) char \\([0-9]+\\) of file://\\(.+\\)"
      3 1 2)
     ;; in unnamed entity at line 4 char 8 of file:///home/reto/test/group.xml
     ("Warning:.*\n.* line \\([0-9]+\\) char \\([0-9]+\\) of file://\\(.+\\)"
      3 1 2)
+
+    ;; See http://ant.apache.org/faq.html
+    ;; Ant Java: works for jikes
+    ("^\\s-*\\[[^]]*\\]\\s-*\\(.+\\):\\([0-9]+\\):\\([0-9]+\\):[0-9]+:[0-9]+:" 1 2 3)
+
+    ;; Ant Java: works for javac
+    ("^\\s-*\\[[^]]*\\]\\s-*\\(.+\\):\\([0-9]+\\):" 1 2)
+
     )
 
   "Alist that specifies how to match errors in compiler output.
     )
 
   "Alist that specifies how to match errors in compiler output.
@@ -528,6 +460,8 @@ subexpression.")
   '(
     ;; Matches lines printed by the `-w' option of GNU Make.
     (".*: Entering directory `\\(.*\\)'$" 1)
   '(
     ;; Matches lines printed by the `-w' option of GNU Make.
     (".*: Entering directory `\\(.*\\)'$" 1)
+    ;; Matches lines made by Emacs byte compiler.
+    ("^Entering directory `\\(.*\\)'$" 1)
     )
   "Alist specifying how to match lines that indicate a new current directory.
 Note that the match is done at the beginning of lines.
     )
   "Alist specifying how to match lines that indicate a new current directory.
 Note that the match is done at the beginning of lines.
@@ -540,6 +474,8 @@ The default value matches lines printed by the `-w' option of GNU Make.")
   '(
     ;; Matches lines printed by the `-w' option of GNU Make.
     (".*: Leaving directory `\\(.*\\)'$" 1)
   '(
     ;; Matches lines printed by the `-w' option of GNU Make.
     (".*: Leaving directory `\\(.*\\)'$" 1)
+    ;; Matches lines made by Emacs byte compiler.
+    ("^Leaving directory `\\(.*\\)'$" 1)
     )
 "Alist specifying how to match lines that indicate restoring current directory.
 Note that the match is done at the beginning of lines.
     )
 "Alist specifying how to match lines that indicate restoring current directory.
 Note that the match is done at the beginning of lines.
@@ -625,7 +561,7 @@ This variable's value takes effect when `grep-compute-defaults' is called.")
 (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.
 
-If nil, it uses `grep -exec'; if `gnu', it uses `find -print0' and `xargs -0';
+If nil, it uses `find -exec'; if `gnu', it uses `find -print0' and `xargs -0';
 if not nil and not `gnu', it uses `find -print' and `xargs'.
 
 This variable's value takes effect when `grep-compute-defaults' is called.")
 if not nil and not `gnu', it uses `find -print' and `xargs'.
 
 This variable's value takes effect when `grep-compute-defaults' is called.")
@@ -665,6 +601,12 @@ This should be a function of three arguments: process status, exit status,
 and exit message; it returns a cons (MESSAGE . MODELINE) of the strings to
 write into the compilation buffer, and to put in its mode line.")
 
 and exit message; it returns a cons (MESSAGE . MODELINE) of the strings to
 write into the compilation buffer, and to put in its mode line.")
 
+(defvar compilation-environment nil
+  "*List of environment variables for compilation to inherit.
+Each element should be a string of the form ENVVARNAME=VALUE.
+This list is temporarily prepended to `process-environment' prior to
+starting the compilation process.")
+
 ;; History of compile commands.
 (defvar compile-history nil)
 ;; History of grep commands.
 ;; History of compile commands.
 (defvar compile-history nil)
 ;; History of grep commands.
@@ -716,9 +658,11 @@ and move to the source code that caused it.
 Interactively, prompts for the command if `compilation-read-command' is
 non-nil; otherwise uses `compile-command'.  With prefix arg, always prompts.
 
 Interactively, prompts for the command if `compilation-read-command' is
 non-nil; otherwise uses `compile-command'.  With prefix arg, always prompts.
 
-To run more than one compilation at once, start one and rename the
-\`*compilation*' buffer to some other name with \\[rename-buffer].
-Then start the next one.
+To run more than one compilation at once, start one and rename
+the \`*compilation*' buffer to some other name with
+\\[rename-buffer].  Then start the next one.  On most systems,
+termination of the main compilation process kills its
+subprocesses.
 
 The name used for the buffer is actually whatever is returned by
 the function in `compilation-buffer-name-function', so you can set that
 
 The name used for the buffer is actually whatever is returned by
 the function in `compilation-buffer-name-function', so you can set that
@@ -757,6 +701,103 @@ original use.  Otherwise, it recompiles using `compile-command'."
                    (cons msg code)))
           (cons msg code)))))
 
                    (cons msg code)))
           (cons msg code)))))
 
+(defun grep-compute-defaults ()
+  (unless (or (not grep-use-null-device) (eq grep-use-null-device t))
+    (setq grep-use-null-device
+         (with-temp-buffer
+           (let ((hello-file (expand-file-name "HELLO" data-directory)))
+             (not
+              (and (equal (condition-case nil
+                              (if grep-command
+                                  ;; `grep-command' is already set, so
+                                  ;; use that for testing.
+                                  (call-process-shell-command
+                                   grep-command nil t nil
+                                   "^English" hello-file)
+                                ;; otherwise use `grep-program'
+                                (call-process grep-program nil t nil
+                                              "-nH" "^English" hello-file))
+                            (error nil))
+                          0)
+                   (progn
+                     (goto-char (point-min))
+                     (looking-at
+                      (concat (regexp-quote hello-file)
+                              ":[0-9]+:English")))))))))
+  (unless grep-command
+    (setq grep-command
+         (let ((required-options (if grep-use-null-device "-n" "-nH")))
+           (if (equal (condition-case nil ; in case "grep" isn't in exec-path
+                          (call-process grep-program nil nil nil
+                                        "-e" "foo" null-device)
+                        (error nil))
+                      1)
+               (format "%s %s -e " grep-program required-options)
+             (format "%s %s " grep-program required-options)))))
+  (unless grep-find-use-xargs
+    (setq grep-find-use-xargs
+         (if (and
+               (equal (call-process "find" nil nil nil
+                                    null-device "-print0")
+                      0)
+               (equal (call-process "xargs" nil nil nil
+                                    "-0" "-e" "echo")
+                     0))
+             'gnu)))
+  (unless grep-find-command
+    (setq grep-find-command
+         (cond ((eq grep-find-use-xargs 'gnu)
+                (format "%s . -type f -print0 | xargs -0 -e %s"
+                        find-program grep-command))
+               (grep-find-use-xargs
+                (format "%s . -type f -print | xargs %s"
+                         find-program grep-command))
+               (t (cons (format "%s . -type f -exec %s {} %s \\;"
+                                find-program grep-command null-device)
+                        (+ 22 (length grep-command)))))))
+  (unless grep-tree-command
+    (setq grep-tree-command
+         (let* ((glen (length grep-program))
+                (gcmd (concat grep-program " <C>" (substring grep-command glen))))
+           (cond ((eq grep-find-use-xargs 'gnu)
+                  (format "%s <D> <X> -type f <F> -print0 | xargs -0 -e %s <R>"
+                          find-program gcmd))
+                 (grep-find-use-xargs
+                  (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)))))))
+
+(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)))
+       (sh-arg-re "\\(\\(?:\"\\(?:[^\"]\\|\\\\\"\\)+\"\\|'[^']+'\\|[^\"' \t\n]\\)+\\)")
+       (grep-default (or (car grep-history) grep-command)))
+    ;; Replace the thing matching for with that around cursor.
+    (when (or (string-match
+              (concat "[^ ]+\\s +\\(?:-[^ ]+\\s +\\)*"
+                      sh-arg-re "\\(\\s +\\(\\S +\\)\\)?")
+              grep-default)
+             ;; If the string is not yet complete.
+             (string-match "\\(\\)\\'" grep-default))
+      (unless (or (not (stringp buffer-file-name))
+                 (when (match-beginning 2)
+                   (save-match-data
+                     (string-match
+                      (wildcard-to-regexp
+                       (file-name-nondirectory
+                        (match-string 3 grep-default)))
+                      (file-name-nondirectory buffer-file-name)))))
+       (setq grep-default (concat (substring grep-default
+                                             0 (match-beginning 2))
+                                  " *."
+                                  (file-name-extension buffer-file-name))))
+      (replace-match (or tag-default "") t t grep-default 1))))
+
 ;;;###autoload
 (defun grep (command-args)
   "Run grep, with user-specified args, and collect output in a buffer.
 ;;;###autoload
 (defun grep (command-args)
   "Run grep, with user-specified args, and collect output in a buffer.
@@ -773,28 +814,16 @@ tag the cursor is over, substituting it into the last grep command
 in the grep command history (or into `grep-command'
 if that history list is empty)."
   (interactive
 in the grep command history (or into `grep-command'
 if that history list is empty)."
   (interactive
-   (let (grep-default (arg current-prefix-arg))
+   (progn
      (unless (and grep-command
                  (or (not grep-use-null-device) (eq grep-use-null-device t)))
        (grep-compute-defaults))
      (unless (and grep-command
                  (or (not grep-use-null-device) (eq grep-use-null-device t)))
        (grep-compute-defaults))
-     (when arg
-       (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))))
-        (setq grep-default (or (car grep-history) grep-command))
-        ;; Replace the thing matching for with that around cursor
-        (when (string-match "[^ ]+\\s +\\(-[^ ]+\\s +\\)*\\(\"[^\"]+\"\\|[^ ]+\\)\\(\\s-+\\S-+\\)?" grep-default)
-          (unless (or (match-beginning 3) (not (stringp buffer-file-name)))
-            (setq grep-default (concat grep-default "*."
-                                       (file-name-extension buffer-file-name))))
-          (setq grep-default (replace-match (or tag-default "")
-                                            t t grep-default 2)))))
-     (list (read-from-minibuffer "Run grep (like this): "
-                                (or grep-default grep-command)
-                                nil nil 'grep-history))))
+     (let ((default (grep-default-command)))
+       (list (read-from-minibuffer "Run grep (like this): "
+                                  (if current-prefix-arg
+                                      default grep-command)
+                                  nil nil 'grep-history
+                                  (if current-prefix-arg nil default))))))
 
   ;; Setting process-setup-function makes exit-message-function work
   ;; even when async processes aren't supported.
 
   ;; Setting process-setup-function makes exit-message-function work
   ;; even when async processes aren't supported.
@@ -862,10 +891,10 @@ easily repeat a find command."
                                  (or regexp "") command t t))
   command)
 
                                  (or regexp "") command t t))
   command)
 
-;;;###autoload
 (defvar grep-tree-last-regexp "")
 (defvar grep-tree-last-files (car (car grep-tree-files-aliases)))
 
 (defvar grep-tree-last-regexp "")
 (defvar grep-tree-last-files (car (car grep-tree-files-aliases)))
 
+;;;###autoload
 (defun grep-tree (regexp files dir &optional subdirs)
   "Grep for REGEXP in FILES in directory tree rooted at DIR.
 Collect output in a buffer.
 (defun grep-tree (regexp files dir &optional subdirs)
   "Grep for REGEXP in FILES in directory tree rooted at DIR.
 Collect output in a buffer.
@@ -904,7 +933,7 @@ those sub directories of DIR."
     (setq files grep-tree-last-files))
   (when files
     (setq grep-tree-last-files files)
     (setq files grep-tree-last-files))
   (when files
     (setq grep-tree-last-files files)
-    (let ((mf (assoc files match-files-aliases)))
+    (let ((mf (assoc files grep-tree-files-aliases)))
       (if mf
          (setq files (cdr mf)))))
   (let ((command-args (grep-expand-command-macros
       (if mf
          (setq files (cdr mf)))))
   (let ((command-args (grep-expand-command-macros
@@ -915,7 +944,7 @@ those sub directories of DIR."
                           (if (stringp subdirs)
                               subdirs
                             (mapconcat 'identity subdirs " "))
                           (if (stringp subdirs)
                               subdirs
                             (mapconcat 'identity subdirs " "))
-                        nil)  ;; we change default-directory to dir 
+                        nil)  ;; we change default-directory to dir
                       (and grep-tree-ignore-CVS-directories "-path '*/CVS' -prune -o ")
                       grep-tree-ignore-case))
        (default-directory dir)
                       (and grep-tree-ignore-CVS-directories "-path '*/CVS' -prune -o ")
                       grep-tree-ignore-case))
        (default-directory dir)
@@ -941,9 +970,9 @@ Likewise if `compilation-buffer-name-function' is non-nil.
 If current buffer is in Compilation mode for the same mode name
 return the name of the current buffer, so that it gets reused.
 Otherwise, construct a buffer name from MODE-NAME."
 If current buffer is in Compilation mode for the same mode name
 return the name of the current buffer, so that it gets reused.
 Otherwise, construct a buffer name from MODE-NAME."
-  (cond (name-function 
+  (cond (name-function
         (funcall name-function mode-name))
         (funcall name-function mode-name))
-       (compilation-buffer-name-function 
+       (compilation-buffer-name-function
         (funcall compilation-buffer-name-function mode-name))
        ((and (eq major-mode 'compilation-mode)
              (equal mode-name (nth 2 compilation-arguments)))
         (funcall compilation-buffer-name-function mode-name))
        ((and (eq major-mode 'compilation-mode)
              (equal mode-name (nth 2 compilation-arguments)))
@@ -956,7 +985,8 @@ Otherwise, construct a buffer name from MODE-NAME."
                                 &optional name-of-mode parser
                                 error-regexp-alist name-function
                                 enter-regexp-alist leave-regexp-alist
                                 &optional name-of-mode parser
                                 error-regexp-alist name-function
                                 enter-regexp-alist leave-regexp-alist
-                                file-regexp-alist nomessage-regexp-alist)
+                                file-regexp-alist nomessage-regexp-alist
+                                no-async)
   "Run compilation command COMMAND (low level interface).
 ERROR-MESSAGE is a string to print if the user asks to see another error
 and there are no more errors.  The rest of the arguments, 3-10 are optional.
   "Run compilation command COMMAND (low level interface).
 ERROR-MESSAGE is a string to print if the user asks to see another error
 and there are no more errors.  The rest of the arguments, 3-10 are optional.
@@ -973,9 +1003,13 @@ NOMESSAGE-REGEXP-ALIST is the nomessage regexp alist to use.
 \`compilation-buffer-name-function', `compilation-enter-directory-regexp-alist',
 \`compilation-leave-directory-regexp-alist', `compilation-file-regexp-alist',
 \ and `compilation-nomessage-regexp-alist', respectively.
 \`compilation-buffer-name-function', `compilation-enter-directory-regexp-alist',
 \`compilation-leave-directory-regexp-alist', `compilation-file-regexp-alist',
 \ and `compilation-nomessage-regexp-alist', respectively.
-For arg 7-10 a value `t' means an empty alist.
+For arg 7-10 a value t means an empty alist.
+
+If NO-ASYNC is non-nil, start the compilation process synchronously.
 
 Returns the compilation buffer created."
 
 Returns the compilation buffer created."
+  (unless no-async
+    (setq no-async (not (fboundp 'start-process))))
   (let (outbuf)
     (save-excursion
       (or name-of-mode
   (let (outbuf)
     (save-excursion
       (or name-of-mode
@@ -1033,8 +1067,7 @@ Returns the compilation buffer created."
          (goto-char (point-max)))
       ;; Pop up the compilation buffer.
       (setq outwin (display-buffer outbuf nil t))
          (goto-char (point-max)))
       ;; Pop up the compilation buffer.
       (setq outwin (display-buffer outbuf nil t))
-      (save-excursion
-       (set-buffer outbuf)
+      (with-current-buffer outbuf
        (compilation-mode name-of-mode)
        ;; In what way is it non-ergonomic ?  -stef
        ;; (toggle-read-only 1) ;;; Non-ergonomic.
        (compilation-mode name-of-mode)
        ;; In what way is it non-ergonomic ?  -stef
        ;; (toggle-read-only 1) ;;; Non-ergonomic.
@@ -1068,9 +1101,10 @@ Returns the compilation buffer created."
        (if compilation-process-setup-function
            (funcall compilation-process-setup-function))
        ;; Start the compilation.
        (if compilation-process-setup-function
            (funcall compilation-process-setup-function))
        ;; Start the compilation.
-       (if (fboundp 'start-process)
+       (if (not no-async)
            (let* ((process-environment
                    (append
            (let* ((process-environment
                    (append
+                    compilation-environment
                     (if (and (boundp 'system-uses-terminfo)
                              system-uses-terminfo)
                         (list "TERM=dumb" "TERMCAP="
                     (if (and (boundp 'system-uses-terminfo)
                              system-uses-terminfo)
                         (list "TERM=dumb" "TERMCAP="
@@ -1126,19 +1160,27 @@ exited abnormally with code %d\n"
        ;; If window is alone in its frame, aside from a minibuffer,
        ;; don't change its height.
        (not (eq window (frame-root-window (window-frame window))))
        ;; If window is alone in its frame, aside from a minibuffer,
        ;; don't change its height.
        (not (eq window (frame-root-window (window-frame window))))
-       ;; This save-excursion prevents us from changing the current buffer,
-       ;; which might not be the same as the selected window's buffer.
-       (save-excursion
-        (let ((w (selected-window)))
-          (unwind-protect
-              (progn
-                (select-window window)
-                (enlarge-window (- compilation-window-height
-                                   (window-height))))
-            ;; The enlarge-window above may have deleted W, if
-            ;; compilation-window-height is large enough.
-            (when (window-live-p w)
-              (select-window w)))))))
+       ;; This save-current-buffer prevents us from changing the current
+       ;; buffer, which might not be the same as the selected window's buffer.
+       (save-current-buffer
+        (save-selected-window
+          (select-window window)
+          (enlarge-window (- compilation-window-height
+                             (window-height)))))))
+
+(defvar compilation-menu-map
+  (let ((map (make-sparse-keymap "Errors")))
+    (define-key map [stop-subjob]
+      '("Stop Compilation" . kill-compilation))
+    (define-key map [compilation-mode-separator2]
+      '("----" . nil))
+    (define-key map [compilation-mode-first-error]
+      '("First Error" . first-error))
+    (define-key map [compilation-mode-previous-error]
+      '("Previous Error" . previous-error))
+    (define-key map [compilation-mode-next-error]
+      '("Next Error" . next-error))
+    map))
 
 (defvar compilation-minor-mode-map
   (let ((map (make-sparse-keymap)))
 
 (defvar compilation-minor-mode-map
   (let ((map (make-sparse-keymap)))
@@ -1150,6 +1192,9 @@ exited abnormally with code %d\n"
     (define-key map "\M-p" 'compilation-previous-error)
     (define-key map "\M-{" 'compilation-previous-file)
     (define-key map "\M-}" 'compilation-next-file)
     (define-key map "\M-p" 'compilation-previous-error)
     (define-key map "\M-{" 'compilation-previous-file)
     (define-key map "\M-}" 'compilation-next-file)
+    ;; Set up the menu-bar
+    (define-key map [menu-bar compilation]
+      (cons "Errors" compilation-menu-map))
     map)
   "Keymap for `compilation-minor-mode'.")
 
     map)
   "Keymap for `compilation-minor-mode'.")
 
@@ -1162,50 +1207,30 @@ exited abnormally with code %d\n"
     (define-key map "\M-{" 'compilation-previous-file)
     (define-key map "\M-}" 'compilation-next-file)
     ;; Set up the menu-bar
     (define-key map "\M-{" 'compilation-previous-file)
     (define-key map "\M-}" 'compilation-next-file)
     ;; Set up the menu-bar
-    (define-key map [menu-bar errors-menu]
-      (cons "Errors" (make-sparse-keymap "Errors")))
-    (define-key map [menu-bar errors-menu stop-subjob]
-      '("Stop" . comint-interrupt-subjob))
-    (define-key map [menu-bar errors-menu compilation-mode-separator2]
-      '("----" . nil))
-    (define-key map [menu-bar errors-menu compilation-mode-first-error]
-      '("First Error" . first-error))
-    (define-key map [menu-bar errors-menu compilation-mode-previous-error]
-      '("Previous Error" . previous-error))
-    (define-key map [menu-bar errors-menu compilation-mode-next-error]
-      '("Next Error" . next-error))
+    (define-key map [menu-bar compilation]
+      (cons "Errors" compilation-menu-map))
     map)
   "Keymap for `compilation-shell-minor-mode'.")
 
 (defvar compilation-mode-map
     map)
   "Keymap for `compilation-shell-minor-mode'.")
 
 (defvar compilation-mode-map
-  (let ((map (cons 'keymap compilation-minor-mode-map)))
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map compilation-minor-mode-map)
     (define-key map " " 'scroll-up)
     (define-key map "\^?" 'scroll-down)
     ;; Set up the menu-bar
     (define-key map " " 'scroll-up)
     (define-key map "\^?" 'scroll-down)
     ;; Set up the menu-bar
-    (define-key map [menu-bar compilation-menu]
+    (define-key map [menu-bar compilation]
       (cons "Compile" (make-sparse-keymap "Compile")))
       (cons "Compile" (make-sparse-keymap "Compile")))
-
-    (define-key map [menu-bar compilation-menu compilation-mode-kill-compilation]
-      '("Stop Compilation" . kill-compilation))
-    (define-key map [menu-bar compilation-menu compilation-mode-separator2]
+    (define-key map [menu-bar compilation compilation-separator2]
       '("----" . nil))
       '("----" . nil))
-    (define-key map [menu-bar compilation-menu compilation-mode-first-error]
-      '("First Error" . first-error))
-    (define-key map [menu-bar compilation-menu compilation-mode-previous-error]
-      '("Previous Error" . previous-error))
-    (define-key map [menu-bar compilation-menu compilation-mode-next-error]
-      '("Next Error" . next-error))
-    (define-key map [menu-bar compilation-menu compilation-separator2]
-      '("----" . nil))
-    (define-key map [menu-bar compilation-menu compilation-mode-grep]
+    (define-key map [menu-bar compilation compilation-mode-grep]
       '("Search Files (grep)" . grep))
       '("Search Files (grep)" . grep))
-    (define-key map [menu-bar compilation-menu compilation-mode-recompile]
+    (define-key map [menu-bar compilation compilation-mode-recompile]
       '("Recompile" . recompile))
       '("Recompile" . recompile))
-    (define-key map [menu-bar compilation-menu compilation-mode-compile]
+    (define-key map [menu-bar compilation compilation-mode-compile]
       '("Compile..." . compile))
     map)
   "Keymap for compilation log buffers.
       '("Compile..." . compile))
     map)
   "Keymap for compilation log buffers.
-`compilation-minor-mode-map' is a cdr of this.")
+`compilation-minor-mode-map' is a parent of this.")
 
 (put 'compilation-mode 'mode-class 'special)
 
 
 (put 'compilation-mode 'mode-class 'special)
 
@@ -1230,8 +1255,11 @@ Runs `compilation-mode-hook' with `run-hooks' (which see)."
   (run-hooks 'compilation-mode-hook))
 
 (defun compilation-revert-buffer (ignore-auto noconfirm)
   (run-hooks 'compilation-mode-hook))
 
 (defun compilation-revert-buffer (ignore-auto noconfirm)
-  (if (or noconfirm (yes-or-no-p (format "Restart compilation? ")))
-      (apply 'compile-internal compilation-arguments)))
+  (if buffer-file-name
+      (let (revert-buffer-function)
+       (revert-buffer ignore-auto noconfirm preserve-modes))
+    (if (or noconfirm (yes-or-no-p (format "Restart compilation? ")))
+       (apply 'compile-internal compilation-arguments))))
 
 (defun compilation-setup ()
   "Prepare the buffer for the compilation parsing commands to work."
 
 (defun compilation-setup ()
   "Prepare the buffer for the compilation parsing commands to work."
@@ -1245,63 +1273,30 @@ Runs `compilation-mode-hook' with `run-hooks' (which see)."
   (make-local-variable 'compilation-error-screen-columns)
   (setq compilation-last-buffer (current-buffer)))
 
   (make-local-variable 'compilation-error-screen-columns)
   (setq compilation-last-buffer (current-buffer)))
 
-(defvar compilation-shell-minor-mode nil
-  "Non-nil when in `compilation-shell-minor-mode'.
-In this minor mode, all the error-parsing commands of the
-Compilation major mode are available but bound to keys that don't
-collide with Shell mode.")
-(make-variable-buffer-local 'compilation-shell-minor-mode)
-
-(or (assq 'compilation-shell-minor-mode minor-mode-alist)
-    (setq minor-mode-alist
-         (cons '(compilation-shell-minor-mode " Shell-Compile")
-               minor-mode-alist)))
-(or (assq 'compilation-shell-minor-mode minor-mode-map-alist)
-    (setq minor-mode-map-alist (cons (cons 'compilation-shell-minor-mode
-                                          compilation-shell-minor-mode-map)
-                                    minor-mode-map-alist)))
-
-(defvar compilation-minor-mode nil
-  "Non-nil when in `compilation-minor-mode'.
-In this minor mode, all the error-parsing commands of the
-Compilation major mode are available.")
-(make-variable-buffer-local 'compilation-minor-mode)
-
-(or (assq 'compilation-minor-mode minor-mode-alist)
-    (setq minor-mode-alist (cons '(compilation-minor-mode " Compilation")
-                                minor-mode-alist)))
-(or (assq 'compilation-minor-mode minor-mode-map-alist)
-    (setq minor-mode-map-alist (cons (cons 'compilation-minor-mode
-                                          compilation-minor-mode-map)
-                                    minor-mode-map-alist)))
-
 ;;;###autoload
 ;;;###autoload
-(defun compilation-shell-minor-mode (&optional arg)
+(define-minor-mode compilation-shell-minor-mode
   "Toggle compilation shell minor mode.
 With arg, turn compilation mode on if and only if arg is positive.
   "Toggle compilation shell minor mode.
 With arg, turn compilation mode on if and only if arg is positive.
-See `compilation-mode'.
+In this minor mode, all the error-parsing commands of the
+Compilation major mode are available but bound to keys that don't
+collide with Shell mode.  See `compilation-mode'.
 Turning the mode on runs the normal hook `compilation-shell-minor-mode-hook'."
 Turning the mode on runs the normal hook `compilation-shell-minor-mode-hook'."
-  (interactive "P")
-  (if (setq compilation-shell-minor-mode (if (null arg)
-                                      (null compilation-shell-minor-mode)
-                                    (> (prefix-numeric-value arg) 0)))
-      (let ((mode-line-process))
-       (compilation-setup)
-       (run-hooks 'compilation-shell-minor-mode-hook))))
+  nil " Shell-Compile" nil
+  :group 'compilation
+  (let (mode-line-process)
+    (compilation-setup)))
 
 ;;;###autoload
 
 ;;;###autoload
-(defun compilation-minor-mode (&optional arg)
+(define-minor-mode compilation-minor-mode
   "Toggle compilation minor mode.
 With arg, turn compilation mode on if and only if arg is positive.
   "Toggle compilation minor mode.
 With arg, turn compilation mode on if and only if arg is positive.
-See `compilation-mode'.
+In this minor mode, all the error-parsing commands of the
+Compilation major mode are available.  See `compilation-mode'.
 Turning the mode on runs the normal hook `compilation-minor-mode-hook'."
 Turning the mode on runs the normal hook `compilation-minor-mode-hook'."
-  (interactive "P")
-  (if (setq compilation-minor-mode (if (null arg)
-                                      (null compilation-minor-mode)
-                                    (> (prefix-numeric-value arg) 0)))
-      (let ((mode-line-process))
-       (compilation-setup)
-       (run-hooks 'compilation-minor-mode-hook))))
+  nil " Compilation" nil
+  :group 'compilation
+  (let ((mode-line-process))
+    (compilation-setup)))
 
 (defun compilation-handle-exit (process-status exit-status msg)
   "Write msg in the current buffer and hack its mode-line-process."
 
 (defun compilation-handle-exit (process-status exit-status msg)
   "Write msg in the current buffer and hack its mode-line-process."
@@ -1429,7 +1424,18 @@ Does NOT find the source line like \\[next-error]."
                          (if (> (- n) i)
                              (error "Moved back past first error")
                            (nth (+ i n) compilation-old-error-list)))
                          (if (> (- n) i)
                              (error "Moved back past first error")
                            (nth (+ i n) compilation-old-error-list)))
-                     (let ((compilation-error-list (cdr errors)))
+                     (save-excursion
+                       (while (and (> n 0) errors)
+                         ;; Discard the current error and any previous.
+                         (while (and errors (>= (point) (car (car errors))))
+                           (setq errors (cdr errors)))
+                         ;; Now (car errors) is the next error.
+                         ;; If we want to move down more errors,
+                         ;; put point at this one and start again.
+                         (setq n (1- n))
+                         (if (and errors (> n 0))
+                             (goto-char (car (car errors))))))
+                     (let ((compilation-error-list errors))
                        (compile-reinitialize-errors nil nil n)
                        (if compilation-error-list
                            (nth (1- n) compilation-error-list)
                        (compile-reinitialize-errors nil nil n)
                        (if compilation-error-list
                            (nth (1- n) compilation-error-list)
@@ -1582,6 +1588,7 @@ Does NOT find the source line like \\[next-error]."
            (let ((inhibit-read-only t)
                  (buffer-undo-list t)
                  deactivate-mark
            (let ((inhibit-read-only t)
                  (buffer-undo-list t)
                  deactivate-mark
+                  (buffer-was-modified (buffer-modified-p))
                  (error-list compilation-error-list))
              (while error-list
                (save-excursion
                  (error-list compilation-error-list))
              (while error-list
                (save-excursion
@@ -1589,7 +1596,8 @@ Does NOT find the source line like \\[next-error]."
                                       (progn (end-of-line) (point))
                                       '(mouse-face highlight help-echo "\
 mouse-2: visit this file and line")))
                                       (progn (end-of-line) (point))
                                       '(mouse-face highlight help-echo "\
 mouse-2: visit this file and line")))
-               (setq error-list (cdr error-list))))
+               (setq error-list (cdr error-list)))
+              (set-buffer-modified-p buffer-was-modified))
            )))))
 
 (defun compile-mouse-goto-error (event)
            )))))
 
 (defun compile-mouse-goto-error (event)
@@ -1743,11 +1751,15 @@ See variables `compilation-parse-errors-function' and
                           (consp argp))))
 ;;;###autoload (define-key ctl-x-map "`" 'next-error)
 
                           (consp argp))))
 ;;;###autoload (define-key ctl-x-map "`" 'next-error)
 
-(defun previous-error ()
+(defun previous-error (argp)
   "Visit previous compilation error message and corresponding source code.
   "Visit previous compilation error message and corresponding source code.
-This operates on the output from the \\[compile] command."
-  (interactive)
-  (next-error -1))
+
+A prefix ARGP specifies how many error messages to move;
+negative means move forward to next error messages.
+
+This operates on the output from the \\[compile] and \\[grep] commands."
+  (interactive "P")
+  (next-error (- (prefix-numeric-value argp))))
 
 (defun first-error ()
   "Reparse the error message buffer and start at the first error.
 
 (defun first-error ()
   "Reparse the error message buffer and start at the first error.
@@ -2372,4 +2384,5 @@ An error message with no file name and no file name has been seen earlier"))
 
 (provide 'compile)
 
 
 (provide 'compile)
 
+;;; arch-tag: 12465727-7382-4f72-b234-79855a00dd8c
 ;;; compile.el ends here
 ;;; compile.el ends here