]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/compile.el
(c-forward-label): Fix for QT macros.
[gnu-emacs] / lisp / progmodes / compile.el
index f02a77564196990cb39f78a69b740afc89144714..2405efb2ba33a0cf63dc2a81c177fefb7b114c38 100644 (file)
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,9 +22,7 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
@@ -73,6 +71,7 @@
 ;;; Code:
 
 (eval-when-compile (require 'cl))
+(require 'tool-bar)
 
 (defvar font-lock-extra-managed-props)
 (defvar font-lock-keywords)
@@ -236,8 +235,13 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
      ;; times of the form "HH:MM:SS" where MM is taken as a line number, so
      ;; the last line tries to rule out message where the info after the
      ;; line number starts with "SS".  --Stef
+
+     ;; The core of the regexp is the one with *?.  It says that a file name
+     ;; can be composed of any non-newline char, but it also rules out some
+     ;; valid but unlikely cases, such as a trailing space or a space
+     ;; followed by a -.
      "^\\(?:[[:alpha:]][-[:alnum:].]+: ?\\)?\
-\\([0-9]*[^0-9\n]\\(?:[^\n ]\\| [^-\n]\\)*?\\): ?\
+\\([0-9]*[^0-9\n]\\(?:[^\n ]\\| [^-/\n]\\)*?\\): ?\
 \\([0-9]+\\)\\(?:\\([.:]\\)\\([0-9]+\\)\\)?\
 \\(?:-\\([0-9]+\\)?\\(?:\\3\\([0-9]+\\)\\)?\\)?:\
 \\(?: *\\(\\(?:Future\\|Runtime\\)?[Ww]arning\\|W:\\)\\|\
@@ -289,6 +293,10 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
      " at \\([^ \n]+\\) line \\([0-9]+\\)\\(?:[,.]\\|$\\| \
 during global destruction\\.$\\)" 1 2)
 
+    (php
+     "\\(?:Parse\\|Fatal\\) error: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)"
+     2 3 nil nil)
+
     (rxp
      "^\\(?:Error\\|Warnin\\(g\\)\\):.*\n.* line \\([0-9]+\\) char\
  \\([0-9]+\\) of file://\\(.+\\)"
@@ -313,6 +321,11 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?"
     (sun-ada
      "^\\([^, \n\t]+\\), line \\([0-9]+\\), char \\([0-9]+\\)[:., \(-]" 1 2 3)
 
+    (watcom
+     "\\(\\(?:[a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)): ?\
+\\(?:\\(Error! E[0-9]+\\)\\|\\(Warning! W[0-9]+\\)\\):"
+     1 2 nil (4))
+
     (4bsd
      "\\(?:^\\|::  \\|\\S ( \\)\\(/[^ \n\t()]+\\)(\\([0-9]+\\))\
 \\(?:: \\(warning:\\)?\\|$\\| ),\\)" 1 2 nil (3))
@@ -346,7 +359,7 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?"
      (0 'default t)
      (1 compilation-error-face prepend) (2 compilation-line-face prepend))
 
-    (compilation-perl--Pod::Checker
+    (perl--Pod::Checker
      ;; podchecker error messages, per Pod::Checker.
      ;; The style is from the Pod::Checker::poderror() function, eg.
      ;; *** ERROR: Spurious text after =cut at line 193 in file foo.pm
@@ -364,14 +377,14 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?"
      "^\\*\\*\\* \\(?:ERROR\\|\\(WARNING\\)\\).* \\(?:at\\|on\\) line \
 \\([0-9]+\\) \\(?:.* \\)?in file \\([^ \t\n]+\\)"
      3 2 nil (1))
-    (compilation-perl--Test
+    (perl--Test
      ;; perl Test module error messages.
      ;; Style per the ok() function "$context", eg.
      ;; # Failed test 1 in foo.t at line 6
      ;;
      "^# Failed test [0-9]+ in \\([^ \t\r\n]+\\) at line \\([0-9]+\\)"
      1 2)
-    (compilation-perl--Test2
+    (perl--Test2
      ;; Or when comparing got/want values,
      ;; # Test 2 got: "xx" (t-compilation-perl-2.t at line 10)
      ;;
@@ -382,7 +395,7 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?"
      "^\\(.*NOK.*\\)?# Test [0-9]+ got:.* (\\([^ \t\r\n]+\\) at line \
 \\([0-9]+\\))"
      2 3)
-    (compilation-perl--Test::Harness
+    (perl--Test::Harness
      ;; perl Test::Harness output, eg.
      ;; NOK 1# Test 1 got: "1234" (t/foo.t at line 46)
      ;;
@@ -393,7 +406,7 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?"
      ;;
      "^.*NOK.* \\([^ \t\r\n]+\\) at line \\([0-9]+\\)"
      1 2)
-    (compilation-weblint
+    (weblint
      ;; The style comes from HTML::Lint::Error::as_string(), eg.
      ;; index.html (13:1) Unknown element <fdjsk>
      ;;
@@ -762,7 +775,10 @@ from a different message."
 (defun compilation-auto-jump (buffer pos)
   (with-current-buffer buffer
     (goto-char pos)
-    (compile-goto-error)))
+    (let ((win (get-buffer-window buffer 0)))
+      (if win (set-window-point win pos)))
+    (if compilation-auto-jump-to-first-error
+       (compile-goto-error))))
 
 ;; This function is the central driver, called when font-locking to gather
 ;; all information needed to later jump to corresponding source code.
@@ -1025,11 +1041,10 @@ to a function that generates a unique name."
    (list
     (let ((command (eval compile-command)))
       (if (or compilation-read-command current-prefix-arg)
-         (read-from-minibuffer "Compile command: "
-                               command nil nil
-                               (if (equal (car compile-history) command)
-                                   '(compile-history . 1)
-                                 'compile-history))
+         (read-shell-command "Compile command: " command
+                              (if (equal (car compile-history) command)
+                                  '(compile-history . 1)
+                                'compile-history))
        command))
     (consp current-prefix-arg)))
   (unless (equal command (eval compile-command))
@@ -1054,8 +1069,13 @@ original use.  Otherwise, recompile using `compile-command'."
 
 Setting it causes the Compilation mode commands to put point at the
 end of their output window so that the end of the output is always
-visible rather than the beginning."
-  :type 'boolean
+visible rather than the beginning.
+
+The value `first-error' stops scrolling at the first error, and leaves
+point on its location in the *compilation* buffer."
+  :type '(choice (const :tag "No scrolling" nil)
+                (const :tag "Scroll compilation output" t)
+                (const :tag "Stop scrolling at the first error" first-error))
   :version "20.3"
   :group 'compilation)
 
@@ -1093,7 +1113,7 @@ Otherwise, construct a buffer name from MODE-NAME."
        (compilation-error (replace-regexp-in-string "^No more \\(.+\\)s\\.?"
                                                     "\\1" error-message)))
     (compilation-start command nil name-function highlight-regexp)))
-(make-obsolete 'compile-internal 'compilation-start)
+(make-obsolete 'compile-internal 'compilation-start "22.1")
 
 ;;;###autoload
 (defun compilation-start (command &optional mode name-function highlight-regexp)
@@ -1139,13 +1159,8 @@ Returns the compilation buffer created."
                  (error nil))
              (error "Cannot have two processes in `%s' at once"
                     (buffer-name)))))
-      (buffer-disable-undo (current-buffer))
       ;; first transfer directory from where M-x compile was called
       (setq default-directory thisdir)
-      ;; Remember the original dir, so we can use it when we recompile.
-      ;; default-directory' can't be used reliably for that because it may be
-      ;; affected by the special handling of "cd ...;".
-      (set (make-local-variable 'compilation-directory) thisdir)
       ;; Make compilation buffer read-only.  The filter can still write it.
       ;; Clear out the compilation buffer.
       (let ((inhibit-read-only t)
@@ -1161,14 +1176,22 @@ Returns the compilation buffer created."
        (erase-buffer)
        ;; Select the desired mode.
        (if (not (eq mode t))
-           (funcall mode)
+            (progn
+              (buffer-disable-undo)
+              (funcall mode))
          (setq buffer-read-only nil)
          (with-no-warnings (comint-mode))
          (compilation-shell-minor-mode))
+        ;; Remember the original dir, so we can use it when we recompile.
+        ;; default-directory' can't be used reliably for that because it may be
+        ;; affected by the special handling of "cd ...;".
+        ;; NB: must be fone after (funcall mode) as that resets local variables
+        (set (make-local-variable 'compilation-directory) thisdir)
        (if highlight-regexp
            (set (make-local-variable 'compilation-highlight-regexp)
                 highlight-regexp))
-        (if compilation-auto-jump-to-first-error
+        (if (or compilation-auto-jump-to-first-error
+               (eq compilation-scroll-output 'first-error))
             (set (make-local-variable 'compilation-auto-jump-to-next) t))
        ;; Output a mode setter, for saving and later reloading this buffer.
        (insert "-*- mode: " name-of-mode
@@ -1223,40 +1246,80 @@ Returns the compilation buffer created."
            (funcall compilation-process-setup-function))
        (compilation-set-window-height outwin)
        ;; Start the compilation.
-       (let ((proc
-              (if (eq mode t)
-                  ;; comint uses `start-file-process'.
-                  (get-buffer-process
-                   (with-no-warnings
-                     (comint-exec
-                      outbuf (downcase mode-name)
-                      (if (file-remote-p default-directory)
-                          "/bin/sh"
-                        shell-file-name)
-                      nil `("-c" ,command))))
-                (start-file-process-shell-command (downcase mode-name)
-                                                  outbuf command))))
-         ;; Make the buffer's mode line show process state.
-         (setq mode-line-process '(":%s"))
-         (set-process-sentinel proc 'compilation-sentinel)
-         (set-process-filter proc 'compilation-filter)
-         ;; Use (point-max) here so that output comes in
-         ;; after the initial text,
-         ;; regardless of where the user sees point.
-         (set-marker (process-mark proc) (point-max) outbuf)
-         (when compilation-disable-input
-           (condition-case nil
-               (process-send-eof proc)
-             ;; The process may have exited already.
-             (error nil)))
-         (setq compilation-in-progress
-               (cons proc compilation-in-progress))))
+       (if (fboundp 'start-process)
+           (let ((proc
+                  (if (eq mode t)
+                      ;; comint uses `start-file-process'.
+                      (get-buffer-process
+                       (with-no-warnings
+                         (comint-exec
+                          outbuf (downcase mode-name)
+                          (if (file-remote-p default-directory)
+                              "/bin/sh"
+                            shell-file-name)
+                          nil `("-c" ,command))))
+                    (start-file-process-shell-command (downcase mode-name)
+                                                      outbuf command))))
+             ;; Make the buffer's mode line show process state.
+             (setq mode-line-process
+                   (list (propertize ":%s" 'face 'compilation-warning)))
+             (set-process-sentinel proc 'compilation-sentinel)
+             (unless (eq mode t)
+               ;; Keep the comint filter, since it's needed for proper handling
+               ;; of the prompts.
+               (set-process-filter proc 'compilation-filter))
+             ;; Use (point-max) here so that output comes in
+             ;; after the initial text,
+             ;; regardless of where the user sees point.
+             (set-marker (process-mark proc) (point-max) outbuf)
+             (when compilation-disable-input
+               (condition-case nil
+                   (process-send-eof proc)
+                 ;; The process may have exited already.
+                 (error nil)))
+             (setq compilation-in-progress
+                   (cons proc compilation-in-progress)))
+         ;; No asynchronous processes available.
+         (message "Executing `%s'..." command)
+         ;; Fake modeline display as if `start-process' were run.
+         (setq mode-line-process
+               (list (propertize ":run" 'face 'compilation-warning)))
+         (force-mode-line-update)
+         (sit-for 0)                   ; Force redisplay
+         (save-excursion
+           ;; Insert the output at the end, after the initial text,
+           ;; regardless of where the user sees point.
+           (goto-char (point-max))
+           (let* ((buffer-read-only nil) ; call-process needs to modify outbuf
+                  (status (call-process shell-file-name nil outbuf nil "-c"
+                                        command)))
+             (cond ((numberp status)
+                    (compilation-handle-exit
+                     'exit status
+                     (if (zerop status)
+                         "finished\n"
+                       (format "exited abnormally with code %d\n" status))))
+                   ((stringp status)
+                    (compilation-handle-exit 'signal status
+                                             (concat status "\n")))
+                   (t
+                    (compilation-handle-exit 'bizarre status status)))))
+         ;; Without async subprocesses, the buffer is not yet
+         ;; fontified, so fontify it now.
+         (let ((font-lock-verbose nil)) ; shut up font-lock messages
+           (font-lock-fontify-buffer))
+         (set-buffer-modified-p nil)
+         (message "Executing `%s'...done" command)))
       ;; Now finally cd to where the shell started make/grep/...
-      (setq default-directory thisdir))
-    (if (buffer-local-value 'compilation-scroll-output outbuf)
-       (save-selected-window
-         (select-window outwin)
-         (goto-char (point-max))))
+      (setq default-directory thisdir)
+      ;; The following form selected outwin ever since revision 1.183,
+      ;; so possibly messing up point in some other window (bug#1073).
+      ;; Moved into the scope of with-current-buffer, though still with
+      ;; complete disregard for the case when compilation-scroll-output
+      ;; equals 'first-error (martin 2008-10-04).
+      (when compilation-scroll-output
+       (goto-char (point-max))))
+
     ;; Make it so the next C-x ` will use this buffer.
     (setq next-error-last-buffer outbuf)))
 
@@ -1275,17 +1338,52 @@ Returns the compilation buffer created."
             (enlarge-window (- height (window-height))))))))
 
 (defvar compilation-menu-map
-  (let ((map (make-sparse-keymap "Errors")))
+  (let ((map (make-sparse-keymap "Errors"))
+       (opt-map (make-sparse-keymap "Skip")))
     (define-key map [stop-subjob]
-      '("Stop Compilation" . kill-compilation))
+      '(menu-item "Stop Compilation" kill-compilation
+                 :help "Kill the process made by the M-x compile or M-x grep commands"))
+    (define-key map [compilation-mode-separator3]
+      '("----" . nil))
+    (define-key map [compilation-next-error-follow-minor-mode]
+      '(menu-item
+       "Auto Error Display" next-error-follow-minor-mode
+       :help "Display the error under cursor when moving the cursor"
+       :button (:toggle . next-error-follow-minor-mode)))
+    (define-key map [compilation-skip]
+      (cons "Skip Less Important Messages" opt-map))
+    (define-key opt-map [compilation-skip-none]
+      '(menu-item "Don't Skip Any Messages"
+                 (lambda ()
+                   (interactive)
+                   (customize-set-variable 'compilation-skip-threshold 0))
+                 :help "Do not skip any type of messages"
+                 :button (:radio . (eq compilation-skip-threshold 0))))
+    (define-key opt-map [compilation-skip-info]
+      '(menu-item "Skip Info"
+                 (lambda ()
+                   (interactive)
+                   (customize-set-variable 'compilation-skip-threshold 1))
+                 :help "Skip anything less than warning"
+                 :button (:radio . (eq compilation-skip-threshold 1))))
+    (define-key opt-map [compilation-skip-warning-and-info]
+      '(menu-item "Skip Warnings and Info"
+                 (lambda ()
+                   (interactive)
+                   (customize-set-variable 'compilation-skip-threshold 2))
+                 :help "Skip over Warnings and Info, stop for errors"
+                 :button (:radio . (eq compilation-skip-threshold 2))))
     (define-key map [compilation-mode-separator2]
       '("----" . nil))
     (define-key map [compilation-first-error]
-      '("First Error" . first-error))
+      '(menu-item "First Error" first-error
+                 :help "Restart at the first error, visit corresponding source code"))
     (define-key map [compilation-previous-error]
-      '("Previous Error" . previous-error))
+      '(menu-item "Previous Error" previous-error
+                 :help "Visit previous `next-error' message and corresponding source code"))
     (define-key map [compilation-next-error]
-      '("Next Error" . next-error))
+      '(menu-item "Next Error" next-error
+                 :help "Visit next `next-error' message and corresponding source code"))
     map))
 
 (defvar compilation-minor-mode-map
@@ -1299,6 +1397,8 @@ Returns the compilation buffer created."
     (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 "g" 'recompile) ; revert
+    (define-key map "q" 'quit-window)
     ;; Set up the menu-bar
     (define-key map [menu-bar compilation]
       (cons "Errors" compilation-menu-map))
@@ -1343,6 +1443,8 @@ Returns the compilation buffer created."
     (define-key map "\M-}" 'compilation-next-file)
     (define-key map "\t" 'compilation-next-error)
     (define-key map [backtab] 'compilation-previous-error)
+    (define-key map "g" 'recompile) ; revert
+    (define-key map "q" 'quit-window)
 
     (define-key map " " 'scroll-up)
     (define-key map "\^?" 'scroll-down)
@@ -1356,15 +1458,42 @@ Returns the compilation buffer created."
     (define-key map [menu-bar compilation compilation-separator2]
       '("----" . nil))
     (define-key map [menu-bar compilation compilation-grep]
-      '("Search Files (grep)..." . grep))
+      '(menu-item "Search Files (grep)..." grep
+                 :help "Run grep, with user-specified args, and collect output in a buffer"))
     (define-key map [menu-bar compilation compilation-recompile]
-      '("Recompile" . recompile))
+      '(menu-item "Recompile" recompile
+       :help "Re-compile the program including the current buffer"))
     (define-key map [menu-bar compilation compilation-compile]
-      '("Compile..." . compile))
+      '(menu-item "Compile..." compile
+                 :help "Compile the program including the current buffer.  Default: run `make'"))
     map)
   "Keymap for compilation log buffers.
 `compilation-minor-mode-map' is a parent of this.")
 
+(defvar compilation-mode-tool-bar-map
+  ;; When bootstrapping, tool-bar-map is not properly initialized yet,
+  ;; so don't do anything.
+  (when (keymapp (butlast tool-bar-map))
+    (let ((map (butlast (copy-keymap tool-bar-map)))
+         (help (last tool-bar-map))) ;; Keep Help last in tool bar
+      (tool-bar-local-item
+       "left-arrow" 'previous-error-no-select 'previous-error-no-select map
+       :rtl "right-arrow"
+       :help "Goto previous error")
+      (tool-bar-local-item
+       "right-arrow" 'next-error-no-select 'next-error-no-select map
+       :rtl "left-arrow"
+       :help "Goto next error")
+      (tool-bar-local-item
+       "cancel" 'kill-compilation 'kill-compilation map
+       :enable '(let ((buffer (compilation-find-buffer)))
+                 (get-buffer-process buffer))
+       :help "Stop compilation")
+      (tool-bar-local-item
+       "refresh" 'recompile 'recompile map
+       :help "Restart compilation")
+      (append map help))))
+
 (put 'compilation-mode 'mode-class 'special)
 
 ;;;###autoload
@@ -1380,6 +1509,9 @@ Runs `compilation-mode-hook' with `run-mode-hooks' (which see).
   (interactive)
   (kill-all-local-variables)
   (use-local-map compilation-mode-map)
+  ;; Let windows scroll along with the output.
+  (set (make-local-variable 'window-point-insertion-type) t)
+  (set (make-local-variable 'tool-bar-map) compilation-mode-tool-bar-map)
   (setq major-mode 'compilation-mode
        mode-name (or name-of-mode "Compilation"))
   (set (make-local-variable 'page-delimiter)
@@ -1535,7 +1667,15 @@ Turning the mode on runs the normal hook `compilation-minor-mode-hook'."
     ;; Prevent that message from being recognized as a compilation error.
     (add-text-properties omax (point)
                         (append '(compilation-handle-exit t) nil))
-    (setq mode-line-process (format ":%s [%s]" process-status (cdr status)))
+    (setq mode-line-process
+         (let ((out-string (format ":%s [%s]" process-status (cdr status)))
+               (msg (format "%s %s" mode-name
+                            (replace-regexp-in-string "\n?$" "" (car status)))))
+           (message "%s" msg)
+           (propertize out-string
+                       'help-echo msg 'face (if (> exit-status 0)
+                                                'compilation-error
+                                              'compilation-info))))
     ;; Force mode line redisplay soon.
     (force-mode-line-update)
     (if (and opoint (< opoint omax))
@@ -1567,14 +1707,22 @@ Turning the mode on runs the normal hook `compilation-minor-mode-hook'."
 
 (defun compilation-filter (proc string)
   "Process filter for compilation buffers.
-Just inserts the text, but uses `insert-before-markers'."
-  (if (buffer-name (process-buffer proc))
-      (with-current-buffer (process-buffer proc)
-       (let ((inhibit-read-only t))
-         (save-excursion
-           (goto-char (process-mark proc))
-           (insert-before-markers string)
-           (run-hooks 'compilation-filter-hook))))))
+Just inserts the text, and runs `compilation-filter-hook'."
+  (when (buffer-live-p (process-buffer proc))
+    (with-current-buffer (process-buffer proc)
+      (let ((inhibit-read-only t)
+            ;; `save-excursion' doesn't use the right insertion-type for us.
+            (pos (copy-marker (point) t)))
+        (unwind-protect
+            (progn
+              (goto-char (process-mark proc))
+              ;; We used to use `insert-before-markers', so that windows with
+              ;; point at `process-mark' scroll along with the output, but we
+              ;; now use window-point-insertion-type instead.
+              (insert string)
+              (set-marker (process-mark proc) (point))
+              (run-hooks 'compilation-filter-hook))
+          (goto-char pos))))))
 
 ;;; test if a buffer is a compilation buffer, assuming we're in the buffer
 (defsubst compilation-buffer-internal-p ()
@@ -1618,14 +1766,19 @@ Just inserts the text, but uses `insert-before-markers'."
 
 (defun compilation-next-error (n &optional different-file pt)
   "Move point to the next error in the compilation buffer.
+This function does NOT find the source line like \\[next-error].
 Prefix arg N says how many error messages to move forwards (or
 backwards, if negative).
-Does NOT find the source line like \\[next-error]."
+Optional arg DIFFERENT-FILE, if non-nil, means find next error for a
+file that is different from the current one.
+Optional arg PT, if non-nil, specifies the value of point to start
+looking for the next message."
   (interactive "p")
   (or (compilation-buffer-p (current-buffer))
       (error "Not in a compilation buffer"))
   (or pt (setq pt (point)))
   (let* ((msg (get-text-property pt 'message))
+         ;; `loc' is used by the compilation-loop macro.
         (loc (car msg))
         last)
     (if (zerop n)
@@ -1931,13 +2084,17 @@ and overlay is highlighted between MK and END-MK."
 \f
 (defun compilation-find-file (marker filename directory &rest formats)
   "Find a buffer for file FILENAME.
+If FILENAME is not found at all, ask the user where to find it.
+Pop up the buffer containing MARKER and scroll to MARKER if we ask
+the user where to find the file.
 Search the directories in `compilation-search-path'.
 A nil in `compilation-search-path' means to try the
 \"current\" directory, which is passed in DIRECTORY.
 If DIRECTORY is relative, it is combined with `default-directory'.
 If DIRECTORY is nil, that means use `default-directory'.
-If FILENAME is not found at all, ask the user where to find it.
-Pop up the buffer containing MARKER and scroll to MARKER if we ask the user."
+FORMATS, if given, is a list of formats to reformat FILENAME when
+looking for it: for each element FMT in FORMATS, this function
+attempts to find a file whose name is produced by (format FMT FILENAME)."
   (or formats (setq formats '("%s")))
   (let ((dirs compilation-search-path)
         (spec-dir (if directory
@@ -2159,7 +2316,8 @@ The file-structure looks like this:
   ;; compilations, to set the beginning of "this compilation", it's a good
   ;; place to reset compilation-auto-jump-to-next.
   (set (make-local-variable 'compilation-auto-jump-to-next)
-       compilation-auto-jump-to-first-error))
+       (or compilation-auto-jump-to-first-error
+          (eq compilation-scroll-output 'first-error))))
 
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.gcov\\'" . compilation-mode))