(defvar compilation-error-list nil
"List of error message descriptors for visiting erring functions.
-Each error descriptor is a cons (or nil). Its car is a marker
-pointing to an error message. If its cdr is a marker, it points to
-the text of the line the message is about. If its cdr is a cons, that
-cons's car is the name of the file the message is about, and its cdr
-is the number of the line the message is about. Or its cdr may be nil
-if that error is not interesting.
+Each error descriptor is a cons (or nil). Its car is a marker pointing to
+an error message. If its cdr is a marker, it points to the text of the
+line the message is about. If its cdr is a cons, that cons's car is a cons
+\(DIRECTORY . FILE\), specifying the file the message is about, and its cdr
+is the number of the line the message is about. Or its cdr may be nil if
+that error is not interesting.
The value may be t instead of a list; this means that the buffer of
error messages should be reparsed the next time the list of errors is wanted.
(compilation-next-error (- n)))
-(defun compile-file-of-error (data)
+;; Given an elt of `compilation-error-list', return an object representing
+;; the referenced file which is equal to (but not necessarily eq to) what
+;; this function would return for another error in the same file.
+(defsubst compilation-error-filedata (data)
(setq data (cdr data))
(if (markerp data)
- (buffer-file-name (marker-buffer data))
+ (marker-buffer data)
(car data)))
+;; Return a string describing a value from compilation-error-filedata.
+;; This value is not necessarily useful as a file name, but should be
+;; indicative to the user of what file's errors are being referred to.
+(defsubst compilation-error-filedata-file-name (filedata)
+ (if (bufferp filedata)
+ (buffer-file-name filedata)
+ (car filedata)))
+
(defun compilation-next-file (n)
"Move point to the next error for a different file than the current one."
(interactive "p")
(setq compilation-last-buffer (current-buffer))
(let ((reversed (< n 0))
- errors file)
+ errors filedata)
(if (not reversed)
(setq errors (or (compile-error-at-point)
(setq errors (cdr errors))))
(while (> n 0)
- (setq file (compile-file-of-error (car errors)))
-
- ;; Skip past the other errors for this file.
- (while (string= file
- (compile-file-of-error
- (car (or errors
- (if reversed
- (error "%s the first erring file" file)
- (let ((compilation-error-list nil))
- ;; Parse some more.
- (compile-reinitialize-errors nil nil 2)
- (setq errors compilation-error-list)))
- (error "%s is the last erring file" file)))))
+ (setq filedata (compilation-error-filedata (car errors)))
+
+ ;; Skip past the following errors for this file.
+ (while (equal filedata
+ (compilation-error-filedata
+ (car (or errors
+ (if reversed
+ (error "%s the first erring file"
+ (compilation-error-filedata-file-name
+ filedata))
+ (let ((compilation-error-list nil))
+ ;; Parse some more.
+ (compile-reinitialize-errors nil nil 2)
+ (setq errors compilation-error-list)))
+ (error "%s is the last erring file"
+ (compilation-error-filedata-file-name
+ filedata))))))
(setq errors (cdr errors)))
(setq n (1- n)))
(or (markerp (cdr next-error))
;; This error has a filename/lineno pair.
;; Find the file and turn it into a marker.
- (let* ((fileinfo
- (cons (file-name-directory (car (cdr next-error)))
- (file-name-nondirectory
- (car (cdr next-error)))))
+ (let* ((fileinfo (car (cdr next-error)))
(buffer (compilation-find-file (cdr fileinfo)
(car fileinfo)
(car next-error))))
;; Extract the file name and line number from the error message.
(let ((beginning-of-match (match-beginning 0)) ;looking-at nukes
(filename
- (save-excursion
- (goto-char (match-end (nth 1 alist)))
- (skip-chars-backward " \t")
- (let ((name (buffer-substring (match-beginning (nth 1 alist))
- (point))))
- (expand-file-name name default-directory))))
+ (cons default-directory
+ (buffer-substring (match-beginning (nth 1 alist))
+ (match-end (nth 1 alist)))))
(linenum (save-restriction
(narrow-to-region
(match-beginning (nth 2 alist))