Hi Sandip,

a really nifty idea which could be enhanced with a general package - i have
written long time before - to highlight not only the current error in the
compilation-buffer (like the standard compile.el package does) but also the
related code-line in the source-buffer.

Your nifty idea (but somehow long winded code) could be written much smaller
if using in combination with my package - see below.

First here comes a rewritten version of your function:

,----
| (defun animate-compilation-messages1 ()
|   (interactive)
|   (if compilation-last-buffer
|       (let ((number-of-errors (length (save-excursion
|                                         (set-buffer compilation-last-buffer)
|                                         compilation-error-list))))
|       (dotimes (i number-of-errors)
|           (next-error)
|           (sit-for 3))
|         (message "Done"))))
`----

This displays the error-message not in the echo-area but walks through the
compilation-buffer itself. But maybe this should be made customizable because
displaying the error-message in the minibuffer or as tool-tip can make sense
if the compilation-window has been deleted to get more space for the
source-buffer?! So the code could first check if the compilation-window is
visible.... 

Anyway, here comes the code which enables highlighting (customizable! See
option compilation-highlight-source a.o.) both error-message and related
code-line:

,----
| ;; enhancement of next-error: with this advice it highlights the error-line in
| ;; the sourcebuffer.
| (defvar compilation-source-overlay (make-overlay 1 1)
|   "Internal overlay used for the source-line in the source-buffer")
| 
| (defcustom compilation-highlight-source '(secondary-selection . any-command)
|   "*If not nil then highlight the source-line in the source-buffer.
| Then you must define the face for the source-line and when the unhighlighting
| of the source-line should be done.
| The value is either nil or a cons where the car is the face for the
| source-line and the cdr is one of the following symbols:
| - any-command: Any command will unhighlight the source-line \(default)
| - window: Any command that scrolls the source-line outside the visible
|   portion of the buffer will unhighlight it
| - line: Any command that moves point out of the source-line unhighlights it.
| - after-change: The first buffer-change will unhighlight the source-line."
|   :group 'compilation
|   :set '(lambda (symbol value)
|           (set symbol value)
|           (if (and (consp value) (or (featurep 'xemacs)
|                                      (facep (car value))))
|               (overlay-put compilation-source-overlay 'face (car value))))
|   :type '(radio (const :tag "No highlighting of source-line" :value nil)
|                 (cons :tag "Highlight source-line"
|                       (face :tag "Face for the highligthing")
|                       (radio :tag "Unhighlight source-line"
|                              (const :tag "After any command"
|                                     :value any-command)
|                              (const :tag "After scrolling out of the window"
|                                     :value window)
|                              (const :tag "After moving point out of the source-line"
|                                     :value line)
|                              (const :tag "After first change in the buffer"
|                                     :value after-change)))))
| 
| (defvar compilation-error-overlay (make-overlay 1 1)
|   "Internal overlay used for the error-line in the compilation-buffer")
| 
| (defcustom compilation-highlight-error 'secondary-selection
|   "*If not nil and a face then highlight the error-line in the
| compilation-buffer with this face."
|   :group 'compilation
|   :set '(lambda (symbol value)
|           (set symbol value)
|           (if (and value (or (featurep 'xemacs)
|                              (facep value)))
|               (overlay-put compilation-error-overlay 'face value)))
|   :type '(radio (const :tag "No highlighting of error-line" :value nil)
|                 (face :tag "Face for the error-line")))
| 
| (defvar compilation-highlight-error-activated nil
|   "If non-nil then the adviced version of `compilation-goto-locus' highlights
| the ERROR and SOURCE lines, depending on `compilation-highlight-error' and
| `compilation-highlight-source', respectively. This is not an user-option but
| it should only be set temporally \(with `let') to non-nil to activate this
| mechanism during evaluation of a function or expression. The adviced version
| of `next-error' does this for example.")
| 
| ;; for Emacs < 20 and XEmacs
| (if (not (fboundp 'line-beginning-position))
|     (defun line-beginning-position ()
|       (if (featurep 'xemacs)
|           (point-at-bol)
|         (save-excursion 
|           (beginning-of-line)) (point))))
| 
| (if (not (fboundp 'line-end-position))
|     (defun line-end-position ()
|       (if (featurep 'xemacs)
|           (point-at-eol)
|         (save-excursion 
|           (end-of-line)) (point))))
| 
| 
| (defadvice compilation-goto-locus (after highlight activate compile)
|   "If `compilation-highlight-error' is non-nil, highlight the ERROR line.
| If `compilation-highlight-source' is non-nil, highlight the SOURCE line.
| \(This is only effective when `compilation-highlight-error-activated' is
| non-nil, as when `next-error's highlight advice binds it.)"
|   (if compilation-highlight-error-activated
|       (let ((error-marker (car (ad-get-arg 0))) ; (car NEXT-ERROR)
|             (source-marker (cdr (ad-get-arg 0)))) ; (cdr NEXT-ERROR)
|         (when compilation-highlight-error
|           (save-excursion
|             (set-buffer (marker-buffer error-marker))
|             (goto-char (marker-position error-marker))
|             (move-overlay compilation-error-overlay
|                           (line-beginning-position)
|                           (line-end-position)
|                           (current-buffer))))
|         (when compilation-highlight-source
|           (save-excursion
|             (set-buffer (marker-buffer source-marker))
|             (goto-char (marker-position source-marker))
|             (move-overlay compilation-source-overlay
|                           (line-beginning-position)
|                           (line-end-position)
|                           (current-buffer)))
|           (if (equal (cdr compilation-highlight-source) 'after-change)
|               (progn
|                 ;; because this is an after advice, we are here always in the
|                 ;; source-buffer, so we can here make the hook local.
|                 (make-local-hook 'after-change-functions)
|                 (add-hook 'after-change-functions
|                           'compilation-unhighlight-source-after-change nil t))
|             (add-hook 'post-command-hook 'compilation-unhighlight-source))))))
| 
| (defadvice next-error(around highlight activate)
|   "If `compilation-highlight-error' is non-nil, highlight the ERROR line.
| If `compilation-highlight-source' is non-nil, highlight the SOURCE line."
|   (let ((compilation-highlight-error-activated t))
|     ad-do-it))
| 
| (defconst compilation-next-error-caller-list
|   '(compile-mouse-goto-error
|     compile-goto-error
|     next-error
|     previous-error
|     first-error)
|   "List of functions in compile.el which uses `next-error' to jump to the
| source-line of the error")
| 
| (defun compilation-unhighlight-source ()
|   "Delete `compilation-source-overlay' depending on the value of
| `compilation-highlight-source' \('after-change is not handled here but with
| `compilation-unhighlight-source-after-change')."
|   (if (and (overlay-buffer compilation-source-overlay)
|            ;; we must not calling the following unhighlighting code if the
|            ;; last event was a mouse-movement (maybe track-mouse it t) or if
|            ;; `this-command' is one of the next-error callers because then the
|            ;; highlighting would be deleted immediatelly after highlighting it
|            ;; if `compilation-highlight-source' is 'any-command or 'window
|            (if (not (featurep 'xemacs))
|                (not (equal (event-basic-type last-command-event) 'mouse-movement))
|              t)
|            (not (member this-command compilation-next-error-caller-list)))
|       (let ((unhighlight (cdr compilation-highlight-source)))
|         (when (or (not unhighlight)
|                   (equal unhighlight 'any-command)
|                   (and (equal unhighlight 'window)
|                        (not (pos-visible-in-window-p (overlay-start
|                                                       compilation-source-overlay)
|                                                      (get-buffer-window
|                                                       (overlay-buffer
|                                                        compilation-source-overlay)
|                                                       'visible))))
|                   (and (equal unhighlight 'line)
|                        (save-excursion
|                          (set-buffer (overlay-buffer compilation-source-overlay))
|                          (or (< (point) (overlay-start compilation-source-overlay))
|                              (> (point) (overlay-end compilation-source-overlay))))))
|           (delete-overlay compilation-source-overlay)
|           (remove-hook 'post-command-hook 'compilation-unhighlight-source)))))
| 
| (defun compilation-unhighlight-source-after-change (&rest args)
|   "Delete `compilation-source-overlay' after a buffer change. This hook is
| only added to `after-change-functions' after `compilation-goto-locus' if the
| cdr of `compilation-highlight-source' is 'after-change. This hook removes
| itself from `after-change-functions'."
|   (when (overlay-buffer compilation-source-overlay)
|     (delete-overlay compilation-source-overlay)
|     (remove-hook 'after-change-functions
|                  'compilation-unhighlight-source-after-change t)))
`----

Enjoy it and maybe enhance your nifty command with this...

Klaus

On Sat, 22 Feb 2003, Sandip Chitale wrote:

>  Folks,
>   
>      I had brought up this issue earlier...I took a first crack at
>  it.....
>  It is still rough but with some expert help this could be completed...
>  Especially I need help with save-excursion and buffer selection etc...
>   
>  For now -
>   
>  1. Compile any java class such that it results in error messages
>  2. Switch to the *compilation* buffer
>  3. Invoke the following function animate-messages
>   
>  (defun animate-messages()
>    "Animate messages in *compilation* buffer."
>    (interactive)
>    (let* (
>    (errorMarker (compilation-next-error-locus 1 t t))
>    (compilation-error-overlay)
>    )
>      (while errorMarker
>        (let (
>       (nextErrorMarker (compilation-next-error-locus 1 nil t))
>       (errorBufferMarker (car errorMarker))
>       errorString
>       errorBegin
>       errorEnd
>       )
>   (save-excursion
>     (setq errorBegin (marker-position errorBufferMarker))
>     (if nextErrorMarker
>         (setq errorEnd (marker-position (car nextErrorMarker)))
>       (setq errorEnd (point-max))
>       )
>     (setq errorString (buffer-substring errorBegin errorEnd))
>     )
>   (save-excursion
>     (if (not (eq (current-buffer) (marker-buffer (cdr errorMarker))))
>         (switch-to-buffer (marker-buffer (cdr errorMarker)))
>       )
>     (goto-char (marker-position (cdr errorMarker)))
>     (if compilation-error-overlay
>         (move-overlay compilation-error-overlay (line-beginning-position)
>  (line-end-position))
>       (setq compilation-error-overlay
>      (make-overlay (line-beginning-position) (line-end-position)))
>       )
>     (overlay-put compilation-error-overlay 'face 'underline)
>     (message errorString)
>     (sit-for 3)
>     )
>   (setq errorMarker (compilation-next-error-locus 1 nil t))
>   )
>        )
>      (if compilation-error-overlay
>   (delete-overlay compilation-error-overlay)
>        )
>      (message "Done.")
>      )
>    )
>   
>  [NOTE: The above works for grep output also.]
>   
>  4. This should animate the error messages i.e.
>   
>      i. move the point to the location of error
>      ii. temporarily underline the line
>      iii. echo the error message in mini-buffer
>   
>  What I want to do eventually is to hook this function to compilation
>  finish hook.
>  When there are compilation error messages the error messages are shown
>  in the
>  buffer with some overlay. The help-echo text property is used to show
>  the error meesage
>  in mini-buffer.
>   
>  A background compilation may be invoked every so often or on demand
>  basis...
>   
>  enjoy,
>  sandip

-- 
Klaus Berndl                    mailto: [EMAIL PROTECTED]
sd&m AG                         http://www.sdm.de
software design & management    
Thomas-Dehler-Str. 27, 81737 München, Germany
Tel +49 89 63812-392, Fax -220

Reply via email to