1 ;;; lmcompile.el --- highlight compile error lines
4 ;; Author: Eric M. Ludlam <eludlam@mathworks.com>
5 ;; Maintainer: Eric M. Ludlam <eludlam@mathworks.com>
8 ;; Copyright (C) 2003, 2004, 2005 Eric M. Ludlam
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
27 ;; This package uses the compile package, and the linemark package to
28 ;; highlight all lines showing errors.
32 ;; Thanks to Markus Gritsch for adding support for grep-buffers, where
33 ;; no file is associated with a buffer. (Similar work in linemark.el)
38 (defclass lmcompile-linemark-group
(linemark-group)
41 "Linemark Group for compile error highlights.")
43 (defclass lmcompile-linemark-entry
(linemark-entry)
44 ((errormarker :initarg
:errormarker
47 "Marker pointing to the source of the match.")
48 (errmsg :initarg
:errmsg
51 "The match text of the error in question.")
53 "Linemark Group for one compile error highlight.
54 Tracks additional information about the error.")
56 (defmethod linemark-new-entry ((g linemark-group
) &rest args
)
57 "Create a new entry for G using init ARGS."
58 (let ((f (plist-get args
:filename
))
59 (l (plist-get args
:line
)))
60 (apply 'lmcompile-linemark-entry
(format "%s %d" f l
)
63 (defmethod linemark-display ((e lmcompile-linemark-entry
) active-p
)
64 "Set object E to be active or inactive."
65 ;; Do the rest of our work
70 (slot-boundp e
'overlay
)
72 (slot-boundp e
'errmsg
)
75 (linemark-overlay-put (oref e overlay
)
81 (defun lmcompile-create-group (name)
82 "Create a group object for tracking linemark entries.
83 Do not permit multiple groups with the same NAME."
84 (let ((newgroup (lmcompile-linemark-group name
))
86 (lmg linemark-groups
))
87 (while (and (not foundgroup
) lmg
)
88 (if (string= name
(object-name-string (car lmg
)))
89 (setq foundgroup
(car lmg
)))
92 (setq newgroup foundgroup
)
93 (setq linemark-groups
(cons newgroup linemark-groups
))
96 (defvar lmcompile-error-group
97 (linemark-new-group 'lmcompile-linemark-group
"compiler errors")
98 "The LMCOMPILE error group object.")
100 (defun lmcompile-clear ()
101 "Flush all compile error entries."
103 (mapcar (lambda (e) (linemark-delete e
))
104 (oref lmcompile-error-group marks
)))
107 (if (fboundp 'compile-reinitialize-errors
)
108 (defalias 'lmcompile-reinitialize-errors
'compile-reinitialize-errors
)
109 ;; Newer versions of Emacs:
110 (defun lmcompile-reinitialize-errors (&rest foo
)
111 "Find out what this should be."
112 (error "Need replacement for `compile-reinitialize-errors")
117 (defun lmcompile-do-highlight ()
118 "Do compilation mode highlighting.
119 Works on grep, compile, or other type mode."
125 ;; Set the buffer appropriately
126 (setq compilation-last-buffer
(compilation-find-buffer))
128 ;; Get the list of errors to be activated.
129 (lmcompile-reinitialize-errors nil
)
133 (set-buffer compilation-last-buffer
)
134 compilation-error-list
))
146 (setq errmark
(car (car marks
)))
147 (if (listp (cdr (car marks
)))
148 (progn ; So a list containing filename, linenumber, ... like (grep) provides is used.
149 (setq file
(nth 1 (car marks
)))
150 (setq line
(nth 2 (car marks
)))
152 (setq file
(concat (car (cdr file
))
155 ;; In case file contains an absolute path, the above doesn't work, at least not on Win32. Use this version.
156 ;; Originally suggested by: Markus Gritsch
157 (if (not (file-exists-p file
))
158 (setq file
(car (nth 1 (car marks
))))))
160 (progn ; Otherwise we assume that we have a marker, which works also on buffers which have no file associated.
161 (setq file
(buffer-name (marker-buffer (cdr (car marks
)))))
163 (setq line
(save-excursion
164 (set-buffer (marker-buffer (cdr (car marks
))))
166 (goto-char (cdr (car marks
)))
167 (count-lines 1 (1+ (point))))))))
169 ;; We've got the goods, lets add in an entry.
170 ;; If we can't find the file, skip it. It'll be
172 (when (or (file-exists-p file
) (bufferp (marker-buffer (cdr (car marks
)))))
176 (set-buffer (marker-buffer errmark
))
181 ((re-search-forward "error" (point-at-eol) t
)
183 ((re-search-forward "warning" (point-at-eol) t
)
184 'linemark-caution-face
)
186 'linemark-go-face
)))))
191 (set-buffer (marker-buffer errmark
))
194 (setq txt
(buffer-substring-no-properties
195 (point-at-bol) (point-at-eol)))
196 ;; Strip positional information
197 (while (string-match "[0-9]:" txt
)
198 (setq txt
(substring txt
(match-end 0))))
199 ;; Strip leading whitespace (if any)
200 (when (string-match "^\\s-++" txt
)
201 (setq txt
(substring txt
(match-end 0))))
207 lmcompile-error-group
216 (setq marks
(cdr marks
)))))
220 ;;; lmcompile.el ends here