the fringe, pointing to the current error message. If the window has
no left fringe, such as on a text terminal, these commands scroll the
window so that the current message is at the top of the window. If
-you change the variable @code{compilation-context-lines} to an integer
-value @var{n}, these commands scroll the window so that the current
-error message is @var{n} lines from the top, whether or not there is a
-fringe; the default value, @code{nil}, gives the behavior described
-above.
+you change the variable @code{compilation-context-lines} to @code{t},
+a visible arrow is inserted before column zero instead. If you change
+the variable to an integer value @var{n}, these commands scroll the
+window so that the current error message is @var{n} lines from the
+top, whether or not there is a fringe; the default value, @code{nil},
+gives the behavior described above.
@vindex compilation-error-regexp-alist
@vindex grep-regexp-alist
;;;###autoload
(defcustom compilation-search-path '(nil)
"List of directories to search for source files named in error messages.
-Elements should be directory names, not file names of
-directories. The value nil as an element means the error
-message buffer `default-directory'."
+Elements should be directory names, not file names of directories.
+The value nil as an element means to try the default directory."
:type '(repeat (choice (const :tag "Default" nil)
(string :tag "Directory"))))
(defcustom compilation-context-lines nil
"Display this many lines of leading context before the current message.
-If nil and the left fringe is displayed, don't scroll the
+If nil or t, and the left fringe is displayed, don't scroll the
compilation output window; an arrow in the left fringe points to
-the current message. If nil and there is no left fringe, the message
-displays at the top of the window; there is no arrow."
- :type '(choice integer (const :tag "No window scrolling" nil))
+the current message. With no left fringe, If nil, the message
+scrolls to the top of the window; there is no arrow. If t, don't
+scroll the compilation output window at all; an arrow before
+column zero points to the current message."
+ :type '(choice integer
+ (const :tag "Scroll window when no fringe" nil)
+ (const :tag "No window scrolling" t))
:version "22.1")
(defsubst compilation-set-window (w mk)
- "Align the compilation output window W with marker MK near top."
- (if (integerp compilation-context-lines)
- (set-window-start w (save-excursion
- (goto-char mk)
- (compilation-beginning-of-line
- (- 1 compilation-context-lines))
- (point)))
+ "Maybe align the compilation output window W with marker MK near top."
+ (cond ((integerp compilation-context-lines)
+ (set-window-start w (save-excursion
+ (goto-char mk)
+ (compilation-beginning-of-line
+ (- 1 compilation-context-lines))
+ (point))))
+ ((eq compilation-context-lines t))
;; If there is no left fringe.
- (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))
+ ((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))))
+
+(defvar-local overlay-arrow-overlay nil
+ "Overlay with the before-string property of `overlay-arrow-string'.
+
+When non-nil, this overlay causes redisplay to display `overlay-arrow-string'
+at the overlay's start position.")
+
+(defun compilation-set-overlay-arrow (w)
+ "Set up, or switch off, the overlay-arrow for window W."
+ (with-current-buffer (window-buffer w)
+ (if (and (eq compilation-context-lines t)
+ (equal (car (window-fringes w)) 0)) ; No left fringe
+ ;; Insert a "=>" before-string overlay at the beginning of the
+ ;; line pointed to by `overlay-arrow-position'.
+ (cond
+ ((overlayp overlay-arrow-overlay)
+ (when (not (eq (overlay-start overlay-arrow-overlay)
+ overlay-arrow-position))
+ (if overlay-arrow-position
+ (progn
+ (move-overlay overlay-arrow-overlay
+ overlay-arrow-position overlay-arrow-position)
+ (setq overlay-arrow-string "=>")
+ (overlay-put overlay-arrow-overlay
+ 'before-string overlay-arrow-string))
+ (delete-overlay overlay-arrow-overlay)
+ (setq overlay-arrow-overlay nil))))
+
+ (overlay-arrow-position
+ (setq overlay-arrow-overlay
+ (make-overlay overlay-arrow-position overlay-arrow-position))
+ (setq overlay-arrow-string "=>")
+ (overlay-put overlay-arrow-overlay 'before-string overlay-arrow-string)))
+
+ ;; `compilation-context-lines' isn't t, or we've got a left
+ ;; fringe, so remove any overlay arrow.
+ (when (overlayp overlay-arrow-overlay)
+ (setq overlay-arrow-string "")
+ (delete-overlay overlay-arrow-overlay)
+ (setq overlay-arrow-overlay nil)))))
(defvar next-error-highlight-timer)
(highlight-regexp (with-current-buffer (marker-buffer msg)
;; also do this while we change buffer
(goto-char (marker-position msg))
- (and w (compilation-set-window w msg))
+ (and w (progn (compilation-set-window w msg)
+ (compilation-set-overlay-arrow w)))
compilation-highlight-regexp)))
;; Ideally, the window-size should be passed to `display-buffer'
;; so it's only used when creating a new window.
'(nil (allow-no-window . t))))))
(with-current-buffer (marker-buffer marker)
(goto-char marker)
- (and w (compilation-set-window w marker)))
+ (and w (progn (compilation-set-window w marker)
+ (compilation-set-overlay-arrow w))))
(let* ((name (read-file-name
(format "Find this %s in (default %s): "
compilation-error filename)