;;; 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>
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
;; 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
- ("\\([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
- ("\\([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
- ("\\([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
- ("\\([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.
;; 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.
'(
;; 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.
'(
;; 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.
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.
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
(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.
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))
- (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.
\`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.
(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.
(if (not no-async)
(let* ((process-environment
(append
+ compilation-environment
(if (and (boundp 'system-uses-terminfo)
system-uses-terminfo)
(list "TERM=dumb" "TERMCAP="
;; 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)))
(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'.")
(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
- (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 [menu-bar compilation-menu]
+ (define-key map [menu-bar compilation]
(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]
- '("----" . 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]
+ (define-key map [menu-bar compilation 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))
- (define-key map [menu-bar compilation-menu compilation-mode-recompile]
+ (define-key map [menu-bar compilation compilation-mode-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.
-`compilation-minor-mode-map' is a cdr of this.")
+`compilation-minor-mode-map' is a parent of this.")
(put 'compilation-mode 'mode-class 'special)
(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."
(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
-(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.
-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'."
- (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
-(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.
-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'."
- (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."
(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)
(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
(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)
(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.
-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.
(provide 'compile)
+;;; arch-tag: 12465727-7382-4f72-b234-79855a00dd8c
;;; compile.el ends here