]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/compile.el
Merge branch 'emacs-25-merge'
[gnu-emacs] / lisp / progmodes / compile.el
index 5d3b6878a70601c5c9f5bca1f7f42473e92feddb..f13906680cf7ff88a87465a6c9aae9b929611feb 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  -*- lexical-binding:t -*-
 
-;; Copyright (C) 1985-1987, 1993-1999, 2001-2014 Free Software
+;; Copyright (C) 1985-1987, 1993-1999, 2001-2015 Free Software
 ;; Foundation, Inc.
 
 ;; Authors: Roland McGrath <roland@gnu.org>,
@@ -145,7 +145,7 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
      " in line \\([0-9]+\\) of file \\([^ \n]+[^. \n]\\)\\.? " 2 1)
 
     (ant
-     "^[ \t]*\\[[^] \n]+\\][ \t]*\\([^: \n]+\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\):\\)?\
+     "^[ \t]*\\[[^] \n]+\\][ \t]*\\(\\(?:[A-Za-z]:\\\\\\)?[^: \n]+\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\):\\)?\
 \\( warning\\)?" 1 (2 . 4) (3 . 5) (6))
 
     (bash
@@ -167,7 +167,7 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
 
     (cucumber
      "\\(?:^cucumber\\(?: -p [^[:space:]]+\\)?\\|#\\)\
-\\(?: \\)\\([^\(].*\\):\\([1-9][0-9]*\\)" 1 2)
+\\(?: \\)\\([^(].*\\):\\([1-9][0-9]*\\)" 1 2)
 
     (msft
      ;; Must be before edg-1, so that MSVC's longer messages are
@@ -216,7 +216,7 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
     ;; due to matching filenames via \\(.*?\\).  This might be faster.
     (maven
      ;; Maven is a popular free software build tool for Java.
-     "\\([^ \n]\\(?:[^\n :]\\| [^-/\n]\\|:[^ \n]\\)*?\\):\\[\\([0-9]+\\),\\([0-9]+\\)\\] " 1 2 3)
+     "\\(\\[WARNING\\] *\\)?\\([^ \n]\\(?:[^\n :]\\| [^-/\n]\\|:[^ \n]\\)*?\\):\\[\\([0-9]+\\),\\([0-9]+\\)\\] " 2 3 4 (1))
 
     (jikes-line
      "^ *\\([0-9]+\\)\\.[ \t]+.*\n +\\(<-*>\n\\*\\*\\* \\(?:Error\\|Warnin\\(g\\)\\)\\)"
@@ -230,7 +230,7 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
      1 2 3 (4 . 5))
 
     (ruby-Test::Unit
-     "^[\t ]*\\[\\([^\(].*\\):\\([1-9][0-9]*\\)\\(\\]\\)?:in " 1 2)
+     "^[\t ]*\\[\\([^(].*\\):\\([1-9][0-9]*\\)\\(\\]\\)?:in " 1 2)
 
     (gnu
      ;; The first line matches the program name for
@@ -255,7 +255,7 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
      ;; 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 -, or a colon followed by a space.
-     ;; 
+     ;;
      ;; The "in \\|from " exception was added to handle messages from Ruby.
      ,(rx
        bol
@@ -377,7 +377,7 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?"
      3 4 5 (1 . 2))
 
     (sun-ada
-     "^\\([^, \n\t]+\\), line \\([0-9]+\\), char \\([0-9]+\\)[:., \(-]" 1 2 3)
+     "^\\([^, \n\t]+\\), line \\([0-9]+\\), char \\([0-9]+\\)[:., (-]" 1 2 3)
 
     (watcom
      "^[ \t]*\\(\\(?:[a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)): ?\
@@ -477,7 +477,29 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?"
      ;;
      "^\\([^ \t\r\n(]+\\) (\\([0-9]+\\):\\([0-9]+\\)) "
      1 2 3)
-    (guile-file "^In \\(.+\\):\n" 1)
+
+    ;; Guile compilation yields file-headers in the following format:
+    ;;
+    ;;   In sourcefile.scm:
+    ;;
+    ;; We need to catch those, but we also need to be aware that Emacs
+    ;; byte-compilation yields compiler headers in similar form of
+    ;; those:
+    ;;
+    ;;   In toplevel form:
+    ;;   In end of data:
+    ;;
+    ;; We want to catch the Guile file-headers but not the Emacs
+    ;; byte-compilation headers, because that will cause next-error
+    ;; and prev-error to break, because the files "toplevel form" and
+    ;; "end of data" does not exist.
+    ;;
+    ;; To differentiate between these two cases, we require that the
+    ;; file-match must always contain an extension.
+    ;;
+    ;; We should also only treat this as "info", not "error", because
+    ;; we do not know what lines will follow.
+    (guile-file "^In \\(.+\\..+\\):\n" 1 nil nil 0)
     (guile-line "^ *\\([0-9]+\\): *\\([0-9]+\\)" nil 1 2)
     )
   "Alist of values for `compilation-error-regexp-alist'.")
@@ -650,11 +672,11 @@ The value nil as an element means to try the default directory."
 Sometimes it is useful for files to supply local values for this variable.
 You might also use mode hooks to specify it in certain modes, like this:
 
-    (add-hook 'c-mode-hook
+    (add-hook \\='c-mode-hook
        (lambda ()
         (unless (or (file-exists-p \"makefile\")
                     (file-exists-p \"Makefile\"))
-          (set (make-local-variable 'compile-command)
+          (set (make-local-variable \\='compile-command)
                (concat \"make -k \"
                        (if buffer-file-name
                          (shell-quote-argument
@@ -929,7 +951,7 @@ from a different message."
 (defvar compilation--previous-directory-cache nil
   "A pair (POS . RES) caching the result of previous directory search.
 Basically, this pair says that calling
-   (previous-single-property-change POS 'compilation-directory)
+   (previous-single-property-change POS \\='compilation-directory)
 returned RES, i.e. there is no change of `compilation-directory' between
 POS and RES.")
 (make-variable-buffer-local 'compilation--previous-directory-cache)
@@ -945,7 +967,7 @@ POS and RES.")
    (t (setq compilation--previous-directory-cache nil))))
 
 (defun compilation--previous-directory (pos)
-  "Like (previous-single-property-change POS 'compilation-directory), but faster."
+  "Like (previous-single-property-change POS \\='compilation-directory), but faster."
   ;; This avoids an N² behavior when there's no/few compilation-directory
   ;; entries, in which case each call to previous-single-property-change
   ;; ends up having to walk very far back to find the last change.
@@ -969,19 +991,12 @@ POS and RES.")
                     (cons (copy-marker pos) (if prev (copy-marker prev))))
               prev)
              ((and prev (= prev cache))
-              (if cache
-                  (set-marker (car compilation--previous-directory-cache) pos)
-                (setq compilation--previous-directory-cache
-                      (cons (copy-marker pos) nil)))
+              (set-marker (car compilation--previous-directory-cache) pos)
               (cdr compilation--previous-directory-cache))
              (t
-              (if cache
-                  (progn
-                    (set-marker cache pos)
-                    (setcdr compilation--previous-directory-cache
-                            (copy-marker prev)))
-                (setq compilation--previous-directory-cache
-                      (cons (copy-marker pos) (if prev (copy-marker prev)))))
+              (set-marker cache pos)
+              (setcdr compilation--previous-directory-cache
+                      (copy-marker prev))
               prev))))
       (if (markerp res) (marker-position res) res))))
 
@@ -1116,7 +1131,9 @@ If SCREEN is non-nil, columns are screen columns, otherwise, they are
 just char-counts."
   (setq col (- col compilation-first-column))
   (if screen
-      (move-to-column (max col 0))
+      ;; Presumably, the compilation tool doesn't know about our current
+      ;; `tab-width' setting, so it probably assumed 8-wide TABs (bug#21038).
+      (let ((tab-width 8)) (move-to-column (max col 0)))
     (goto-char (min (+ (line-beginning-position) col) (line-end-position)))))
 
 (defun compilation-internal-error-properties (file line end-line col end-col type fmts)
@@ -1468,9 +1485,9 @@ Additionally, with universal prefix arg, compilation buffer will be in
 comint mode, i.e. interactive.
 
 To run more than one compilation at once, start one then rename
-the \`*compilation*' buffer to some other name with
+the `*compilation*' buffer to some other name with
 \\[rename-buffer].  Then _switch buffers_ and start the new compilation.
-It will create a new \`*compilation*' buffer.
+It will create a new `*compilation*' buffer.
 
 On most systems, termination of the main compilation process
 kills its subprocesses.
@@ -1673,17 +1690,22 @@ Returns the compilation buffer created."
                (list "TERM=emacs"
                      (format "TERMCAP=emacs:co#%d:tc=unknown:"
                              (window-width))))
-             ;; Set the EMACS variable, but
-             ;; don't override users' setting of $EMACS.
-             (unless (getenv "EMACS")
-               (list "EMACS=t"))
-             (list "INSIDE_EMACS=t")
+             (list (format "INSIDE_EMACS=%s,compile" emacs-version))
              (copy-sequence process-environment))))
        (set (make-local-variable 'compilation-arguments)
             (list command mode name-function highlight-regexp))
        (set (make-local-variable 'revert-buffer-function)
             'compilation-revert-buffer)
-       (and outwin (set-window-start outwin (point-min)))
+       (and outwin
+            ;; Forcing the window-start overrides the usual redisplay
+            ;; feature of bringing point into view, so setting the
+            ;; window-start to top of the buffer risks losing the
+            ;; effect of moving point to EOB below, per
+            ;; compilation-scroll-output, if the command is long
+            ;; enough to push point outside of the window.  This
+            ;; could happen, e.g., in `rgrep'.
+            (not compilation-scroll-output)
+            (set-window-start outwin (point-min)))
 
        ;; Position point as the user will see it.
        (let ((desired-visible-point
@@ -1982,6 +2004,12 @@ Runs `compilation-mode-hook' with `run-mode-hooks' (which see).
        compilation-page-delimiter)
   ;; (set (make-local-variable 'compilation-buffer-modtime) nil)
   (compilation-setup)
+  ;; Turn off deferred fontifications in the compilation buffer, if
+  ;; the user turned them on globally.  This is because idle timers
+  ;; aren't re-run after receiving input from a subprocess, so the
+  ;; buffer is left unfontified after the compilation exits, until
+  ;; some other input event happens.
+  (set (make-local-variable 'jit-lock-defer-time) nil)
   (setq buffer-read-only t)
   (run-mode-hooks 'compilation-mode-hook))
 
@@ -2286,6 +2314,7 @@ looking for the next message."
   (or (compilation-buffer-p (current-buffer))
       (error "Not in a compilation buffer"))
   (or pt (setq pt (point)))
+  (compilation--ensure-parse pt)
   (let* ((msg (get-text-property pt 'compilation-message))
          ;; `loc', `msg', and `last' are used by the compilation-loop macro.
         (loc (and msg (compilation--message->loc msg)))
@@ -2298,7 +2327,8 @@ looking for the next message."
                                                    (line-beginning-position)))
          (unless (setq msg (get-text-property (max (1- pt) (point-min))
                                                'compilation-message))
-           (setq pt (next-single-property-change pt 'compilation-message nil
+           (setq pt (compilation-next-single-property-change
+                      pt 'compilation-message nil
                                                  (line-end-position)))
            (or (setq msg (get-text-property pt 'compilation-message))
                (setq pt (point)))))
@@ -2309,7 +2339,6 @@ looking for the next message."
                                "No more %ss yet"
                              "Moved past last %s")
                            (point-max))
-        (compilation--ensure-parse pt)
        ;; Don't move "back" to message at or before point.
        ;; Pass an explicit (point-min) to make sure pt is non-nil.
        (setq pt (previous-single-property-change
@@ -2516,9 +2545,9 @@ displays at the top of the window; there is no arrow."
                             (- 1 compilation-context-lines))
                            (point)))
     ;; If there is no left fringe.
-    (if (equal (car (window-fringes)) 0)
-       (set-window-start w (save-excursion
-                             (goto-char mk)
+    (when (equal (car (window-fringes w)) 0)
+      (set-window-start w (save-excursion
+                            (goto-char mk)
                            (beginning-of-line 1)
                            (point)))))
     (set-window-point w mk))
@@ -2565,7 +2594,7 @@ and overlay is highlighted between MK and END-MK."
        (goto-char mk)))
     (if end-mk
         (push-mark end-mk t)
-      (if mark-active (setq mark-active)))
+      (if mark-active (setq mark-active nil)))
     ;; If hideshow got in the way of
     ;; seeing the right place, open permanently.
     (dolist (ov (overlays-at (point)))