Initial Commit
[temp.git] / site-lisp / cedet-1.0pre4 / eieio / lmcompile.el
blob2729cac8f7b24f46998dd964c4e35515cba436f1
1 ;;; lmcompile.el --- highlight compile error lines
3 ;;
4 ;; Author: Eric M. Ludlam <eludlam@mathworks.com>
5 ;; Maintainer: Eric M. Ludlam <eludlam@mathworks.com>
6 ;; Keywords: lisp
7 ;;
8 ;; Copyright (C) 2003, 2004, 2005 Eric M. Ludlam
9 ;;
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)
13 ;; any later version.
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.
25 ;;; Commentary:
27 ;; This package uses the compile package, and the linemark package to
28 ;; highlight all lines showing errors.
30 ;;; Notes:
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)
35 (require 'linemark)
37 ;;; Code:
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
45 :type marker
46 :documentation
47 "Marker pointing to the source of the match.")
48 (errmsg :initarg :errmsg
49 :type string
50 :documentation
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)
61 args)))
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
66 (call-next-method)
68 ;; Add a tool tip
69 (when (and active-p
70 (slot-boundp e 'overlay)
71 (oref e overlay)
72 (slot-boundp e 'errmsg)
75 (linemark-overlay-put (oref e overlay)
76 'help-echo
77 (oref e errmsg))
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))
85 (foundgroup nil)
86 (lmg linemark-groups))
87 (while (and (not foundgroup) lmg)
88 (if (string= name (object-name-string (car lmg)))
89 (setq foundgroup (car lmg)))
90 (setq lmg (cdr lmg)))
91 (if foundgroup
92 (setq newgroup foundgroup)
93 (setq linemark-groups (cons newgroup linemark-groups))
94 newgroup)))
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."
102 (interactive)
103 (mapcar (lambda (e) (linemark-delete e))
104 (oref lmcompile-error-group marks)))
106 ;; Compatibility
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")
116 ;;;###autoload
117 (defun lmcompile-do-highlight ()
118 "Do compilation mode highlighting.
119 Works on grep, compile, or other type mode."
120 (interactive)
122 ;; Flush out the old
123 (lmcompile-clear)
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)
131 (let ((marks
132 (save-excursion
133 (set-buffer compilation-last-buffer)
134 compilation-error-list))
136 (while marks
137 (let (errmark
138 file
139 line
140 (face nil)
141 (case-fold-search t)
142 (entry nil)
143 (txt nil)
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))
153 (car 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))))
165 (save-excursion
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
171 ;; found eventually.
172 (when (or (file-exists-p file) (bufferp (marker-buffer (cdr (car marks)))))
174 (condition-case nil
175 (save-excursion
176 (set-buffer (marker-buffer errmark))
177 (save-excursion
178 (goto-char errmark)
180 (setq face (cond
181 ((re-search-forward "error" (point-at-eol) t)
182 'linemark-stop-face)
183 ((re-search-forward "warning" (point-at-eol) t)
184 'linemark-caution-face)
186 'linemark-go-face)))))
187 (error nil))
189 (condition-case nil
190 (save-excursion
191 (set-buffer (marker-buffer errmark))
192 (save-excursion
193 (goto-char 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))))
203 (error nil))
205 (setq entry
206 (linemark-add-entry
207 lmcompile-error-group
208 :filename file
209 :line line
210 :errormarker errmark
211 :face face
212 :errmsg txt
216 (setq marks (cdr marks)))))
218 (provide 'lmcompile)
220 ;;; lmcompile.el ends here