;;; compile.el --- run compiler as inferior of Emacs, parse error messages
-;; Copyright (C) 1985-1987, 1993-1999, 2001-2013 Free Software
+;; Copyright (C) 1985-1987, 1993-1999, 2001-2014 Free Software
;; Foundation, Inc.
;; Authors: Roland McGrath <roland@gnu.org>,
;; Daniel Pfeiffer <occitan@esperanto.org>
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
;; Keywords: tools, processes
;; This file is part of GNU Emacs.
"Directory to restore to when doing `recompile'.")
(defvar compilation-directory-matcher
- '("\\(?:Entering\\|Leavin\\(g\\)\\) directory `\\(.+\\)'$" (2 . 1))
+ '("\\(?:Entering\\|Leavin\\(g\\)\\) directory [`']\\(.+\\)'$" (2 . 1))
"A list for tracking when directories are entered or left.
If nil, do not track directories, e.g. if all file names are absolute. The
first element is the REGEXP matching these messages. It can match any number
you may also want to change `compilation-page-delimiter'.")
(defvar compilation-page-delimiter
- "^\\(?:\f\\|.*\\(?:Entering\\|Leaving\\) directory `.+'\n\\)+"
+ "^\\(?:\f\\|.*\\(?:Entering\\|Leaving\\) directory [`'].+'\n\\)+"
"Value of `page-delimiter' in Compilation mode.")
(defvar compilation-mode-font-lock-keywords
(file-exists-p \"Makefile\"))
(set (make-local-variable 'compile-command)
(concat \"make -k \"
- (file-name-sans-extension buffer-file-name))))))"
+ (if buffer-file-name
+ (shell-quote-argument
+ (file-name-sans-extension buffer-file-name))))))))"
:type 'string
:group 'compilation)
;;;###autoload(put 'compile-command 'safe-local-variable (lambda (a) (and (stringp a) (or (not (boundp 'compilation-read-command)) compilation-read-command))))
(eq (car face) 'face)
(or (symbolp (cadr face))
(stringp (cadr face))))
- (put-text-property
- (match-beginning mn) (match-end mn)
- 'font-lock-face (cadr face))
+ (compilation--put-prop mn 'font-lock-face (cadr face))
(add-text-properties
(match-beginning mn) (match-end mn)
(nthcdr 2 face)))
(move-marker compilation--parsed limit)
(goto-char start)
(forward-line 0) ;Not line-beginning-position: ignore (comint) fields.
+ (while (and (not (bobp))
+ (get-text-property (1- (point)) 'compilation-multiline))
+ (forward-line -1))
(with-silent-modifications
(compilation--parse-region (point) compilation--parsed)))))
nil)
"\\\\\\(.\\)" "\\1"
(substring command (1+ (match-beginning 1))
(1- (match-end 1)))))
- (t (substitute-env-vars (match-string 1 command)))))
+ ;; Try globbing as well (bug#15417).
+ (t (let* ((substituted-dir
+ (substitute-env-vars (match-string 1 command)))
+ ;; FIXME: This also tries to expand `*' that were
+ ;; introduced by the envvar expansion!
+ (expanded-dir
+ (file-expand-wildcards substituted-dir)))
+ (if (= (length expanded-dir) 1)
+ (car expanded-dir)
+ substituted-dir)))))
(erase-buffer)
;; Select the desired mode.
(if (not (eq mode t))
(format "%s started at %s\n\n"
mode-name
(substring (current-time-string) 0 19))
- ;; The command could be split into several lines, see
- ;; `rgrep' for example. We want to display it as one
- ;; line.
- (apply 'concat (split-string command (regexp-quote "\\\n") t))
- "\n")
+ command "\n")
(setq thisdir default-directory))
(set-buffer-modified-p nil))
;; Pop up the compilation buffer.
;; http://lists.gnu.org/archive/html/emacs-devel/2007-11/msg01638.html
- (setq outwin (display-buffer outbuf))
+ (setq outwin (display-buffer outbuf '(nil (allow-no-window . t))))
(with-current-buffer outbuf
(let ((process-environment
(append
(list command mode name-function highlight-regexp))
(set (make-local-variable 'revert-buffer-function)
'compilation-revert-buffer)
- (set-window-start outwin (point-min))
+ (and outwin (set-window-start outwin (point-min)))
;; Position point as the user will see it.
(let ((desired-visible-point
(point-max)
;; Normally put it at the top.
(point-min))))
- (if (eq outwin (selected-window))
- (goto-char desired-visible-point)
+ (goto-char desired-visible-point)
+ (when (and outwin (not (eq outwin (selected-window))))
(set-window-point outwin desired-visible-point)))
;; The setup function is called before compilation-set-window-height
;; so it can set the compilation-window-height buffer locally.
(if compilation-process-setup-function
(funcall compilation-process-setup-function))
- (compilation-set-window-height outwin)
+ (and outwin (compilation-set-window-height outwin))
;; Start the compilation.
(if (fboundp 'start-process)
(let ((proc
(defun compile-goto-error (&optional event)
"Visit the source for the error message at point.
-Use this command in a compilation log buffer. Sets the mark at point there."
+Use this command in a compilation log buffer."
(interactive (list last-input-event))
(if event (posn-set-point (event-end event)))
(or (compilation-buffer-p (current-buffer))
(if (get-text-property (point) 'compilation-directory)
(dired-other-window
(car (get-text-property (point) 'compilation-directory)))
- (push-mark)
(setq compilation-current-error (point))
(next-error-internal)))
All arguments are markers. If END-MK is non-nil, mark is set there
and overlay is highlighted between MK and END-MK."
;; Show compilation buffer in other window, scrolled to this error.
- (let* ((from-compilation-buffer (eq (window-buffer (selected-window))
+ (let* ((from-compilation-buffer (eq (window-buffer)
(marker-buffer msg)))
;; Use an existing window if it is in a visible frame.
(pre-existing (get-buffer-window (marker-buffer msg) 0))
;; the error location if the two buffers are in two
;; different frames. So don't do it if it's not necessary.
pre-existing
- (display-buffer (marker-buffer msg))))
+ (display-buffer (marker-buffer msg) '(nil (allow-no-window . t)))))
(highlight-regexp (with-current-buffer (marker-buffer msg)
;; also do this while we change buffer
- (compilation-set-window w msg)
+ (goto-char (marker-position msg))
+ (and w (compilation-set-window w msg))
compilation-highlight-regexp)))
;; Ideally, the window-size should be passed to `display-buffer'
;; so it's only used when creating a new window.
- (unless pre-existing (compilation-set-window-height w))
+ (when (and (not pre-existing) w)
+ (compilation-set-window-height w))
(if from-compilation-buffer
;; If the compilation buffer window was selected,
(while (null buffer) ;Repeat until the user selects an existing file.
;; The file doesn't exist. Ask the user where to find it.
(save-excursion ;This save-excursion is probably not right.
- (let ((pop-up-windows t))
- (compilation-set-window (display-buffer (marker-buffer marker))
- marker)
+ (let ((w (let ((pop-up-windows t))
+ (display-buffer (marker-buffer marker)
+ '(nil (allow-no-window . t))))))
+ (with-current-buffer (marker-buffer marker)
+ (goto-char marker)
+ (and w (compilation-set-window w marker)))
(let* ((name (read-file-name
(format "Find this %s in (default %s): "
compilation-error filename)