Mercurial > emacs
annotate lisp/progmodes/flymake.el @ 57972:fc790bd5db8f
(align-areas): Delete whitespace before reindenting, so
that tabs are never placed after spaces.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Sat, 06 Nov 2004 12:04:55 +0000 |
parents | 4bac9c04ed9e |
children | 287d0425c18a |
rev | line source |
---|---|
55822 | 1 ;;; flymake.el -- a universal on-the-fly syntax checker |
2 | |
3 ;; Copyright (C) 2003 Free Software Foundation | |
4 | |
5 ;; Author: Pavel Kobiakov <pk_at_work@yahoo.com> | |
6 ;; Maintainer: Pavel Kobiakov <pk_at_work@yahoo.com> | |
7 ;; Version: 0.3 | |
8 ;; Keywords: c languages tools | |
9 | |
10 ;; This file is part of GNU Emacs. | |
11 | |
12 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
13 ;; it under the terms of the GNU General Public License as published by | |
14 ;; the Free Software Foundation; either version 2, or (at your option) | |
15 ;; any later version. | |
16 | |
17 ;; GNU Emacs is distributed in the hope that it will be useful, | |
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 ;; GNU General Public License for more details. | |
21 | |
22 ;; You should have received a copy of the GNU General Public License | |
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
25 ;; Boston, MA 02111-1307, USA. | |
26 | |
27 ;;; Commentary: | |
28 ;; | |
29 ;; Flymake is a minor Emacs mode performing on-the-fly syntax | |
30 ;; checks using the external syntax check tool (for C/C++ this | |
31 ;; is usually the compiler) | |
32 | |
33 ;;; Code: | |
34 | |
35 ;;;_* Provide | |
36 (provide 'flymake) | |
37 | |
38 ;;;; [[ Overlay compatibility | |
39 (autoload 'make-overlay "overlay" "Overlay compatibility kit." t) | |
40 (autoload 'overlayp "overlay" "Overlay compatibility kit." t) | |
41 (autoload 'overlays-in "overlay" "Overlay compatibility kit." t) | |
42 (autoload 'delete-overlay "overlay" "Overlay compatibility kit." t) | |
43 (autoload 'overlay-put "overlay" "Overlay compatibility kit." t) | |
44 (autoload 'overlay-get "overlay" "Overlay compatibility kit." t) | |
45 ;;;; ]] | |
46 | |
47 ;;;; [[ cross-emacs compatibility routines | |
48 (defvar flymake-emacs | |
49 (cond | |
50 ((string-match "XEmacs" emacs-version) 'xemacs) | |
51 (t 'emacs) | |
52 ) | |
53 "Currently used emacs flavor" | |
54 ) | |
55 | |
56 (defun flymake-makehash(&optional test) | |
57 (cond | |
58 ((equal flymake-emacs 'xemacs) (if test (make-hash-table :test test) (make-hash-table))) | |
57847
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
59 (t (makehash test)) |
55822 | 60 ) |
61 ) | |
62 | |
63 (defun flymake-time-to-float(&optional tm) | |
64 "Convert `current-time` to a float number of seconds." | |
65 (multiple-value-bind (s0 s1 s2) (or tm (current-time)) | |
66 (+ (* (float (ash 1 16)) s0) (float s1) (* 0.0000001 s2))) | |
67 ) | |
68 (defun flymake-float-time() | |
69 (cond | |
70 ((equal flymake-emacs 'xemacs) (flymake-time-to-float (current-time))) | |
71 (t (float-time)) | |
72 ) | |
73 ) | |
74 | |
75 (defun flymake-replace-regexp-in-string(regexp rep str) | |
76 (cond | |
77 ((equal flymake-emacs 'xemacs) (replace-in-string str regexp rep)) | |
78 (t (replace-regexp-in-string regexp rep str)) | |
79 ) | |
80 ) | |
81 | |
82 (defun flymake-split-string-remove-empty-edges(str pattern) | |
83 "split, then remove first and/or last in case it's empty" | |
84 (let* ((splitted (split-string str pattern))) | |
85 (if (and (> (length splitted) 0) (= 0 (length (elt splitted 0)))) | |
86 (setq splitted (cdr splitted)) | |
87 ) | |
88 (if (and (> (length splitted) 0) (= 0 (length (elt splitted (1- (length splitted)))))) | |
89 (setq splitted (reverse (cdr (reverse splitted)))) | |
90 ) | |
91 splitted | |
92 ) | |
93 ) | |
94 (defun flymake-split-string(str pattern) | |
95 (cond | |
96 ((equal flymake-emacs 'xemacs) (flymake-split-string-remove-empty-edges str pattern)) | |
57696
fbcb259c5936
* progmodes/flymake.el (flymake-split-string): Use
Masatake YAMATO <jet@gyve.org>
parents:
55843
diff
changeset
|
97 (t (flymake-split-string-remove-empty-edges str pattern)) |
55822 | 98 ) |
99 ) | |
100 | |
101 (defun flymake-get-temp-dir() | |
102 (cond | |
103 ((equal flymake-emacs 'xemacs) (temp-directory)) | |
104 (t temporary-file-directory) | |
105 ) | |
106 ) | |
107 | |
108 (defun flymake-line-beginning-position() | |
109 (save-excursion | |
110 (beginning-of-line) | |
111 (point) | |
112 ) | |
113 ) | |
114 | |
115 (defun flymake-line-end-position() | |
116 (save-excursion | |
117 (end-of-line) | |
118 (point) | |
119 ) | |
120 ) | |
121 | |
122 (defun flymake-popup-menu(pos menu-data) | |
123 (cond | |
124 ((equal flymake-emacs 'xemacs) | |
125 (let* ((x-pos (nth 0 (nth 0 pos))) | |
126 (y-pos (nth 1 (nth 0 pos))) | |
127 (fake-event-props '(button 1 x 1 y 1))) | |
128 (setq fake-event-props (plist-put fake-event-props 'x x-pos)) | |
129 (setq fake-event-props (plist-put fake-event-props 'y y-pos)) | |
130 (popup-menu (flymake-make-xemacs-menu menu-data) (make-event 'button-press fake-event-props)) | |
131 ) | |
132 ) | |
133 (t (x-popup-menu pos (flymake-make-emacs-menu menu-data))) | |
134 ) | |
135 ) | |
136 | |
137 (defun flymake-make-emacs-menu(menu-data) | |
138 (let* ((menu-title (nth 0 menu-data)) | |
139 (menu-items (nth 1 menu-data)) | |
140 (menu-commands nil)) | |
141 | |
142 (setq menu-commands (mapcar (lambda (foo) | |
143 (cons (nth 0 foo) (nth 1 foo))) | |
144 menu-items)) | |
145 (list menu-title (cons "" menu-commands)) | |
146 ) | |
147 ) | |
148 | |
149 (defun flymake-nop() | |
150 ) | |
151 | |
152 (defun flymake-make-xemacs-menu(menu-data) | |
153 (let* ((menu-title (nth 0 menu-data)) | |
154 (menu-items (nth 1 menu-data)) | |
155 (menu-commands nil)) | |
156 (setq menu-commands (mapcar (lambda (foo) | |
157 (vector (nth 0 foo) (or (nth 1 foo) '(flymake-nop)) t)) | |
158 menu-items)) | |
159 (cons menu-title menu-commands) | |
160 ) | |
161 ) | |
162 | |
163 (defun flymake-xemacs-window-edges(&optional window) | |
164 (let ((edges (window-pixel-edges window)) | |
165 tmp) | |
166 (setq tmp edges) | |
167 (setcar tmp (/ (car tmp) (face-width 'default))) | |
168 (setq tmp (cdr tmp)) | |
169 (setcar tmp (/ (car tmp) (face-height 'default))) | |
170 (setq tmp (cdr tmp)) | |
171 (setcar tmp (/ (car tmp) (face-width 'default))) | |
172 (setq tmp (cdr tmp)) | |
173 (setcar tmp (/ (car tmp) (face-height 'default))) | |
174 edges | |
175 ) | |
176 ) | |
177 | |
178 (defun flymake-current-row() | |
179 "return current row in current frame" | |
180 (cond | |
181 ((equal flymake-emacs 'xemacs) (count-lines (window-start) (point))) | |
182 (t (+ (car (cdr (window-edges))) (count-lines (window-start) (point)))) | |
183 ) | |
184 ) | |
185 | |
186 (defun flymake-selected-frame() | |
187 (cond | |
188 ((equal flymake-emacs 'xemacs) (selected-window)) | |
189 (t (selected-frame)) | |
190 ) | |
191 ) | |
192 | |
193 ;;;; ]] | |
194 | |
195 (defcustom flymake-log-level -1 | |
196 "Logging level, only messages with level > flymake-log-level will not be logged | |
197 -1 = NONE, 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG" | |
198 :group 'flymake | |
199 :type 'integer | |
200 ) | |
201 | |
202 (defun flymake-log(level text &rest args) | |
203 "Log a message with optional arguments" | |
204 (if (<= level flymake-log-level) | |
205 (let* ((msg (apply 'format text args))) | |
206 (message msg) | |
207 ;(with-temp-buffer | |
208 ; (insert msg) | |
209 ; (insert "\n") | |
210 ; (flymake-save-buffer-in-file (current-buffer) "d:/flymake.log" t) ; make log file name customizable | |
211 ;) | |
212 ) | |
213 ) | |
214 ) | |
215 | |
216 (defun flymake-ins-after(list pos val) | |
217 "insert val into list after position pos" | |
218 (let ((tmp (copy-sequence list))) ; (???) | |
219 (setcdr (nthcdr pos tmp) (cons val (nthcdr (1+ pos) tmp))) | |
220 tmp | |
221 ) | |
222 ) | |
223 | |
224 (defun flymake-set-at(list pos val) | |
225 "set val at position pos in list" | |
226 (let ((tmp (copy-sequence list))) ; (???) | |
227 (setcar (nthcdr pos tmp) val) | |
228 tmp | |
229 ) | |
230 ) | |
231 | |
232 (defvar flymake-pid-to-names(flymake-makehash) | |
233 "pid -> source buffer name, output file name mapping" | |
234 ) | |
235 | |
236 (defun flymake-reg-names(pid source-buffer-name) | |
237 "Save into in pid map" | |
238 (unless (stringp source-buffer-name) | |
239 (error "invalid buffer name") | |
240 ) | |
241 (puthash pid (list source-buffer-name) flymake-pid-to-names) | |
242 ) | |
243 | |
244 (defun flymake-get-source-buffer-name(pid) | |
245 "Return buffer name stored in pid map" | |
246 (nth 0 (gethash pid flymake-pid-to-names)) | |
247 ) | |
248 | |
249 (defun flymake-unreg-names(pid) | |
250 "Delete pid->buffer name mapping" | |
251 (remhash pid flymake-pid-to-names) | |
252 ) | |
253 | |
254 (defun flymake-get-buffer-var(buffer var-name) | |
255 "switch to buffer if necessary and return local variable var" | |
256 (unless (bufferp buffer) | |
257 (error "invalid buffer") | |
258 ) | |
259 | |
260 (if (eq buffer (current-buffer)) | |
261 (symbol-value var-name) | |
262 ;else | |
263 (save-excursion | |
264 (set-buffer buffer) | |
265 (symbol-value var-name) | |
266 ) | |
267 ) | |
268 ) | |
269 | |
270 (defun flymake-set-buffer-var(buffer var-name var-value) | |
271 "switch to buffer if necessary and set local variable var-name to var-value" | |
272 (unless (bufferp buffer) | |
273 (error "invalid buffer") | |
274 ) | |
275 | |
276 (if (eq buffer (current-buffer)) | |
277 (set var-name var-value) | |
278 ;else | |
279 (save-excursion | |
280 (set-buffer buffer) | |
281 (set var-name var-value) | |
282 ) | |
283 ) | |
284 ) | |
285 | |
286 (defvar flymake-buffer-data(flymake-makehash) | |
287 "data specific to syntax check tool, in name-value pairs" | |
288 ) | |
289 (make-variable-buffer-local 'flymake-buffer-data) | |
290 (defun flymake-get-buffer-data(buffer) | |
291 (flymake-get-buffer-var buffer 'flymake-buffer-data) | |
292 ) | |
293 (defun flymake-set-buffer-data(buffer data) | |
294 (flymake-set-buffer-var buffer 'flymake-buffer-data data) | |
295 ) | |
296 (defun flymake-get-buffer-value(buffer name) | |
297 (gethash name (flymake-get-buffer-data buffer)) | |
298 ) | |
299 (defun flymake-set-buffer-value(buffer name value) | |
300 (puthash name value (flymake-get-buffer-data buffer)) | |
301 ) | |
302 | |
303 (defvar flymake-output-residual nil | |
304 "" | |
305 ) | |
306 (make-variable-buffer-local 'flymake-output-residual) | |
307 (defun flymake-get-buffer-output-residual(buffer) | |
308 (flymake-get-buffer-var buffer 'flymake-output-residual) | |
309 ) | |
310 (defun flymake-set-buffer-output-residual(buffer residual) | |
311 (flymake-set-buffer-var buffer 'flymake-output-residual residual) | |
312 ) | |
313 | |
314 (defcustom flymake-allowed-file-name-masks '((".+\\.c$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) | |
315 (".+\\.cpp$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) | |
316 (".+\\.xml$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name) | |
317 (".+\\.html?$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name) | |
318 (".+\\.cs$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) | |
319 (".+\\.pl$" flymake-perl-init flymake-simple-cleanup flymake-get-real-file-name) | |
320 (".+\\.h$" flymake-master-make-header-init flymake-master-cleanup flymake-get-real-file-name) | |
321 (".+\\.java$" flymake-simple-make-java-init flymake-simple-java-cleanup flymake-get-real-file-name) | |
322 (".+[0-9]+\\.tex$" flymake-master-tex-init flymake-master-cleanup flymake-get-real-file-name) | |
323 (".+\\.tex$" flymake-simple-tex-init flymake-simple-cleanup flymake-get-real-file-name) | |
324 (".+\\.idl$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) | |
325 ; (".+\\.cpp$" 1) | |
326 ; (".+\\.java$" 3) | |
327 ; (".+\\.h$" 2 (".+\\.cpp$" ".+\\.c$") | |
328 ; ("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2)) | |
329 ; (".+\\.idl$" 1) | |
330 ; (".+\\.odl$" 1) | |
331 ; (".+[0-9]+\\.tex$" 2 (".+\\.tex$") | |
332 ; ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 )) | |
333 ; (".+\\.tex$" 1) | |
334 ) | |
335 "*Files syntax checking is allowed for" | |
336 :group 'flymake | |
337 :type '(repeat (string symbol symbol symbol)) | |
338 ) | |
339 | |
340 (defun flymake-get-file-name-mode-and-masks(file-name) | |
341 "return the corresponding entry from flymake-allowed-file-name-masks" | |
342 (unless (stringp file-name) | |
343 (error "invalid file-name") | |
344 ) | |
345 (let ((count (length flymake-allowed-file-name-masks)) | |
346 (idx 0) | |
347 (mode-and-masks nil)) | |
348 (while (and (not mode-and-masks) (< idx count)) | |
349 (if (string-match (nth 0 (nth idx flymake-allowed-file-name-masks)) file-name) | |
350 (setq mode-and-masks (cdr (nth idx flymake-allowed-file-name-masks))) | |
351 ) | |
352 (setq idx (1+ idx)) | |
353 ) | |
354 (flymake-log 3 "file %s, init=%s" file-name (car mode-and-masks)) | |
355 mode-and-masks | |
356 ) | |
357 ) | |
358 | |
359 (defun flymake-can-syntax-check-file(file-name) | |
360 "Determine whether we can syntax check file-name: nil if cannot, non-nil if can" | |
361 (if (flymake-get-init-function file-name) | |
362 t | |
363 ;else | |
364 nil | |
365 ) | |
366 ) | |
367 | |
368 (defun flymake-get-init-function(file-name) | |
369 "return init function to be used for the file" | |
370 (let* ((init-f (nth 0 (flymake-get-file-name-mode-and-masks file-name)))) | |
371 ;(flymake-log 0 "calling %s" init-f) | |
372 ;(funcall init-f (current-buffer)) | |
57847
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
373 init-f |
55822 | 374 ) |
375 ) | |
376 | |
377 (defun flymake-get-cleanup-function(file-name) | |
378 "return cleanup function to be used for the file" | |
379 (nth 1 (flymake-get-file-name-mode-and-masks file-name)) | |
380 ) | |
381 | |
382 (defun flymake-get-real-file-name-function(file-name) | |
383 "" | |
384 (or (nth 2 (flymake-get-file-name-mode-and-masks file-name)) 'flymake-get-real-file-name) | |
385 ) | |
386 | |
387 (defcustom flymake-buildfile-dirs '("." ".." "../.." "../../.." "../../../.." "../../../../.." "../../../../../.." "../../../../../../.." "../../../../../../../.." "../../../../../../../../.." "../../../../../../../../../.." "../../../../../../../../../../..") | |
388 "dirs to look for buildfile" | |
389 :group 'flymake | |
390 :type '(repeat (string)) | |
391 ) | |
392 | |
393 (defvar flymake-find-buildfile-cache (flymake-makehash 'equal)) | |
394 (defun flymake-get-buildfile-from-cache(dir-name) | |
395 (gethash dir-name flymake-find-buildfile-cache) | |
396 ) | |
397 (defun flymake-add-buildfile-to-cache(dir-name buildfile) | |
398 (puthash dir-name buildfile flymake-find-buildfile-cache) | |
399 ) | |
400 (defun flymake-clear-buildfile-cache() | |
401 (clrhash flymake-find-buildfile-cache) | |
402 ) | |
403 | |
404 (defun flymake-find-buildfile(buildfile-name source-dir-name dirs) | |
405 "find buildfile (i.e. Makefile, build.xml, etc.) starting from current directory. Return its path or nil if not found" | |
406 (if (flymake-get-buildfile-from-cache source-dir-name) | |
407 (progn | |
408 (flymake-get-buildfile-from-cache source-dir-name) | |
409 ) | |
410 ;else | |
411 (let* ((buildfile-dir nil) | |
412 (buildfile nil) | |
413 (dir-count (length dirs)) | |
414 (dir-idx 0) | |
415 (found nil)) | |
416 | |
417 (while (and (not found) (< dir-idx dir-count)) | |
418 | |
419 (setq buildfile-dir (concat source-dir-name (nth dir-idx dirs))) | |
420 (setq buildfile (concat buildfile-dir "/" buildfile-name)) | |
421 | |
422 (when (file-exists-p buildfile) | |
423 (setq found t) | |
424 ) | |
425 | |
426 (setq dir-idx (1+ dir-idx)) | |
427 ) | |
428 (if found | |
429 (progn | |
430 (flymake-log 3 "found buildfile at %s/%s" buildfile-dir buildfile-name) | |
431 (flymake-add-buildfile-to-cache source-dir-name buildfile-dir) | |
432 buildfile-dir | |
433 ) | |
434 ;else | |
435 (progn | |
436 (flymake-log 3 "buildfile for %s not found" source-dir-name) | |
437 nil | |
438 ) | |
439 ) | |
440 ) | |
441 ) | |
442 ) | |
443 | |
444 (defun flymake-fix-path-name(name) | |
445 "replace all occurences of '\' with '/'" | |
446 (when name | |
447 (let* ((new-name (flymake-replace-regexp-in-string "[\\]" "/" (expand-file-name name))) | |
448 (last-char (elt new-name (1- (length new-name))))) | |
449 (setq new-name (flymake-replace-regexp-in-string "\\./" "" new-name)) | |
450 (if (equal "/" (char-to-string last-char)) | |
451 (setq new-name (substring new-name 0 (1- (length new-name)))) | |
452 ) | |
453 new-name | |
454 ) | |
455 ) | |
456 ) | |
457 | |
458 (defun flymake-same-files(file-name-one file-name-two) | |
459 "t if file-name-one and file-name-two actually point to the same file" | |
460 (equal (flymake-fix-path-name file-name-one) (flymake-fix-path-name file-name-two)) | |
461 ) | |
462 | |
463 (defun flymake-ensure-ends-with-slash(path) | |
464 (if (not (= (elt path (1- (length path))) (string-to-char "/"))) | |
465 (concat path "/") | |
466 ;else | |
467 path | |
468 ) | |
469 ) | |
470 | |
471 (defun flymake-get-common-path-prefix(string-one string-two) | |
472 "return common prefix for two paths" | |
473 (when (and string-one string-two) | |
474 (let* ((slash-pos-one -1) | |
475 (slash-pos-two -1) | |
476 (done nil) | |
477 (prefix nil)) | |
478 | |
479 (setq string-one (flymake-ensure-ends-with-slash string-one)) | |
480 (setq string-two (flymake-ensure-ends-with-slash string-two)) | |
481 | |
482 (while (not done) | |
483 (setq slash-pos-one (string-match "/" string-one (1+ slash-pos-one))) | |
484 (setq slash-pos-two (string-match "/" string-two (1+ slash-pos-two))) | |
485 | |
486 (if (and slash-pos-one slash-pos-two | |
487 (= slash-pos-one slash-pos-two) | |
488 (string= (substring string-one 0 slash-pos-one) (substring string-two 0 slash-pos-two))) | |
489 (progn | |
490 (setq prefix (substring string-one 0 (1+ slash-pos-one))) | |
491 ) | |
492 ;else | |
493 (setq done t) | |
494 ) | |
495 ) | |
496 prefix | |
497 ) | |
498 ) | |
499 ) | |
500 | |
501 (defun flymake-build-relative-path(from-dir to-dir) | |
502 "return rel: from-dir/rel == to-dir" | |
503 (if (not (equal (elt from-dir 0) (elt to-dir 0))) | |
504 (error "first chars in paths %s, %s must be equal (same drive)" from-dir to-dir) | |
505 ;else | |
506 (let* ((from (flymake-ensure-ends-with-slash (flymake-fix-path-name from-dir))) | |
507 (to (flymake-ensure-ends-with-slash (flymake-fix-path-name to-dir))) | |
508 (prefix (flymake-get-common-path-prefix from to)) | |
509 (from-suffix (substring from (length prefix))) | |
510 (up-count (length (flymake-split-string from-suffix "[/]"))) | |
511 (to-suffix (substring to (length prefix))) | |
512 (idx 0) | |
513 (rel nil)) | |
514 | |
515 (if (and (> (length to-suffix) 0) (equal "/" (char-to-string (elt to-suffix 0)))) | |
516 (setq to-suffix (substring to-suffix 1)) | |
517 ) | |
518 | |
519 (while (< idx up-count) | |
520 (if (> (length rel) 0) | |
521 (setq rel (concat rel "/")) | |
522 ) | |
523 (setq rel (concat rel "..")) | |
524 (setq idx (1+ idx)) | |
525 ) | |
526 (if (> (length rel) 0) | |
527 (setq rel (concat rel "/")) | |
528 ) | |
529 (if (> (length to-suffix) 0) | |
530 (setq rel (concat rel to-suffix)) | |
531 ) | |
532 | |
533 (or rel "./") | |
534 ) | |
535 ) | |
536 ) | |
537 | |
538 (defcustom flymake-master-file-dirs '("." "./src" "./UnitTest") | |
539 "dirs where to llok for master files" | |
540 :group 'flymake | |
541 :type '(repeat (string)) | |
542 ) | |
543 | |
544 (defcustom flymake-master-file-count-limit 32 | |
545 "max number of master files to check" | |
546 :group 'flymake | |
547 :type 'integer | |
548 ) | |
549 | |
550 (defun flymake-find-possible-master-files(file-name master-file-dirs masks) | |
551 "find (by name and location) all posible master files, which are .cpp and .c for and .h. | |
552 Files are searched for starting from the .h directory and max max-level parent dirs. | |
553 File contents are not checked." | |
554 (let* ((dir-idx 0) | |
555 (dir-count (length master-file-dirs)) | |
556 (files nil) | |
557 (done nil) | |
558 (masks-count (length masks))) | |
559 | |
560 (while (and (not done) (< dir-idx dir-count)) | |
561 (let* ((dir (concat (flymake-fix-path-name (file-name-directory file-name)) "/" (nth dir-idx master-file-dirs))) | |
562 (masks-idx 0)) | |
563 (while (and (file-exists-p dir) (not done) (< masks-idx masks-count)) | |
564 (let* ((mask (nth masks-idx masks)) | |
565 (dir-files (directory-files dir t mask)) | |
566 (file-count (length dir-files)) | |
567 (file-idx 0)) | |
568 | |
569 (flymake-log 3 "dir %s, %d file(s) for mask %s" dir file-count mask) | |
570 (while (and (not done) (< file-idx file-count)) | |
571 (when (not (file-directory-p (nth file-idx dir-files))) | |
572 (setq files (cons (nth file-idx dir-files) files)) | |
573 (when (>= (length files) flymake-master-file-count-limit) | |
574 (flymake-log 3 "master file count limit (%d) reached" flymake-master-file-count-limit) | |
575 (setq done t) | |
576 ) | |
577 ) | |
578 (setq file-idx (1+ file-idx)) | |
579 ) | |
580 ) | |
581 (setq masks-idx (1+ masks-idx)) | |
582 ) | |
583 ) | |
584 (setq dir-idx (1+ dir-idx)) | |
585 ) | |
586 (when files | |
587 (setq flymake-included-file-name (file-name-nondirectory file-name)) | |
588 (setq files (sort files 'flymake-master-file-compare)) | |
589 (setq flymake-included-file-name nil) | |
590 ) | |
591 (flymake-log 3 "found %d possible master file(s)" (length files)) | |
592 files | |
593 ) | |
594 ) | |
595 | |
596 (defvar flymake-included-file-name nil ; this is used to pass a parameter to a sort predicate below | |
597 "" | |
598 ) | |
599 | |
600 (defun flymake-master-file-compare(file-one file-two) | |
601 "used in sort to move most possible file names to the beginning of the list (File.h -> File.cpp moved to top" | |
602 (and (equal (file-name-sans-extension flymake-included-file-name) | |
603 (file-name-sans-extension (file-name-nondirectory file-one))) | |
604 (not (equal file-one file-two)) | |
605 ) | |
606 ) | |
607 | |
608 (defcustom flymake-check-file-limit 8192 | |
609 "max number of chars to look at when checking possible master file" | |
610 :group 'flymake | |
611 :type 'integer | |
612 ) | |
613 | |
614 (defun flymake-check-patch-master-file-buffer(master-file-temp-buffer | |
615 master-file-name patched-master-file-name | |
616 source-file-name patched-source-file-name | |
617 include-dirs regexp-list) | |
618 "check whether master-file-name is indeed a master file for source-file-name. | |
619 For .cpp master file this means it includes source-file-name (.h). | |
620 If yes, patch a copy of master-file-name to include patched-source-file-name instead of source-file-name. | |
621 Whenether a buffer for master-file-name exists, use it as a source instead of reading master file from disk" | |
622 (let* ((found nil) | |
623 (regexp (format (nth 0 regexp-list) ; "[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" | |
624 (file-name-nondirectory source-file-name))) | |
625 (path-idx (nth 1 regexp-list)) | |
626 (name-idx (nth 2 regexp-list)) | |
627 (inc-path nil) | |
628 (inc-name nil) | |
629 (search-limit flymake-check-file-limit)) | |
630 (save-excursion | |
631 (unwind-protect | |
632 (progn | |
633 (set-buffer master-file-temp-buffer) | |
634 (when (> search-limit (point-max)) | |
635 (setq search-limit (point-max)) | |
636 ) | |
637 (flymake-log 3 "checking %s against regexp %s" master-file-name regexp) | |
638 (goto-char (point-min)) | |
639 (while (and (< (point) search-limit) (re-search-forward regexp search-limit t)) | |
640 (let* ((match-beg (match-beginning name-idx)) | |
641 (match-end (match-end name-idx))) | |
642 | |
643 (flymake-log 3 "found possible match for %s" (file-name-nondirectory source-file-name)) | |
644 (setq inc-path (match-string path-idx)) | |
645 (setq inc-name (match-string name-idx)) | |
646 (when (string= inc-name (file-name-nondirectory source-file-name)) | |
647 (flymake-log 3 "inc-path=%s inc-name=%s" inc-path inc-name) | |
648 (when (flymake-check-include source-file-name inc-path inc-name include-dirs) | |
649 (setq found t) | |
650 ; replace-match is not used here as it fails in xemacs with | |
651 ; 'last match not a buffer' error as check-includes calls replace-in-string | |
652 (flymake-replace-region (current-buffer) match-beg match-end | |
653 (file-name-nondirectory patched-source-file-name)) | |
654 ) | |
655 ) | |
656 (forward-line 1) | |
657 ) | |
658 ) | |
659 (when found | |
660 (flymake-save-buffer-in-file (current-buffer) patched-master-file-name) | |
661 ) | |
662 ) | |
663 ;+(flymake-log 3 "killing buffer %s" (buffer-name master-file-temp-buffer)) | |
664 (kill-buffer master-file-temp-buffer) | |
665 ) | |
666 ) | |
667 ;+(flymake-log 3 "check-patch master file %s: %s" master-file-name found) | |
668 (when found | |
669 (flymake-log 2 "found master file %s" master-file-name) | |
670 ) | |
671 found | |
672 ) | |
673 ) | |
674 | |
675 (defun flymake-replace-region(buffer beg end rep) | |
676 "replace text in buffer in region (beg; end) with rep" | |
677 (save-excursion | |
678 (delete-region beg end) | |
679 (goto-char beg) | |
680 (insert rep) | |
681 ) | |
682 ) | |
683 | |
684 (defun flymake-read-file-to-temp-buffer(file-name) | |
685 "isert contents of file-name into newly created temp buffer" | |
686 (let* ((temp-buffer (get-buffer-create (generate-new-buffer-name (concat "flymake:" (file-name-nondirectory file-name)))))) | |
687 (save-excursion | |
688 (set-buffer temp-buffer) | |
689 (insert-file-contents file-name) | |
690 ) | |
691 temp-buffer | |
692 ) | |
693 ) | |
694 | |
695 (defun flymake-copy-buffer-to-temp-buffer(buffer) | |
696 "copy contents of buffer into newly created temp buffer" | |
697 (let ((contents nil) | |
698 (temp-buffer nil)) | |
699 (save-excursion | |
700 (set-buffer buffer) | |
701 (setq contents (buffer-string)) | |
702 | |
703 (setq temp-buffer (get-buffer-create (generate-new-buffer-name (concat "flymake:" (buffer-name buffer))))) | |
704 (set-buffer temp-buffer) | |
705 (insert contents) | |
706 ) | |
707 temp-buffer | |
708 ) | |
709 ) | |
710 | |
711 (defun flymake-check-include(source-file-name inc-path inc-name include-dirs) | |
712 "t if source-file-name is the one found via include dirs using inc-path and inc-name" | |
713 (if (file-name-absolute-p inc-path) | |
714 (flymake-same-files source-file-name (concat inc-path "/" inc-name)) | |
715 ;else | |
716 (let* ((count (length include-dirs)) | |
717 (idx 0) | |
718 (file-name nil) | |
719 (found nil)) | |
720 (while (and (not found) (< idx count)) | |
721 (setq file-name (concat (file-name-directory source-file-name) "/" (nth idx include-dirs))) | |
722 (if (> (length inc-path) 0) | |
723 (setq file-name (concat file-name "/" inc-path)) | |
724 ) | |
725 (setq file-name (concat file-name "/" inc-name)) | |
726 (when (flymake-same-files source-file-name file-name) | |
727 (setq found t) | |
728 ) | |
729 (setq idx (1+ idx)) | |
730 ) | |
731 found | |
732 ) | |
733 ) | |
734 ) | |
735 | |
736 (defun flymake-find-buffer-for-file(file-name) | |
737 "buffer if there exists a buffer visiting file-name, nil otherwise" | |
738 (let ((buffer-name (get-file-buffer file-name))) | |
739 (if buffer-name | |
740 (get-buffer buffer-name) | |
741 ) | |
742 ) | |
743 ) | |
744 | |
745 (defun flymake-create-master-file(source-file-name patched-source-file-name get-incl-dirs-f create-temp-f masks include-regexp-list) | |
746 "save source-file-name with a different name, find master file, patch it and save it to." | |
747 (let* ((possible-master-files (flymake-find-possible-master-files source-file-name flymake-master-file-dirs masks)) | |
748 (master-file-count (length possible-master-files)) | |
749 (idx 0) | |
750 (temp-buffer nil) | |
751 (master-file-name nil) | |
752 (patched-master-file-name nil) | |
753 (found nil)) | |
754 | |
755 (while (and (not found) (< idx master-file-count)) | |
756 (setq master-file-name (nth idx possible-master-files)) | |
757 (setq patched-master-file-name (funcall create-temp-f master-file-name "flymake_master")) | |
758 (if (flymake-find-buffer-for-file master-file-name) | |
759 (setq temp-buffer (flymake-copy-buffer-to-temp-buffer (flymake-find-buffer-for-file master-file-name))) | |
760 ;else | |
761 (setq temp-buffer (flymake-read-file-to-temp-buffer master-file-name)) | |
762 ) | |
763 (setq found | |
764 (flymake-check-patch-master-file-buffer | |
765 temp-buffer | |
766 master-file-name | |
767 patched-master-file-name | |
768 source-file-name | |
769 patched-source-file-name | |
770 (funcall get-incl-dirs-f (file-name-directory master-file-name)) | |
771 include-regexp-list)) | |
772 (setq idx (1+ idx)) | |
773 ) | |
774 (if found | |
775 (list master-file-name patched-master-file-name) | |
776 ;else | |
777 (progn | |
778 (flymake-log 3 "none of %d master file(s) checked includes %s" master-file-count | |
779 (file-name-nondirectory source-file-name)) | |
780 nil | |
781 ) | |
782 ) | |
783 ) | |
784 ) | |
785 | |
786 (defun flymake-save-buffer-in-file(buffer file-name) | |
787 (or buffer | |
788 (error "invalid buffer") | |
789 ) | |
790 (save-excursion | |
791 (save-restriction | |
792 (set-buffer buffer) | |
793 (widen) | |
794 (make-directory (file-name-directory file-name) 1) | |
795 (write-region (point-min) (point-max) file-name nil 566) | |
796 ) | |
797 ) | |
798 (flymake-log 3 "saved buffer %s in file %s" (buffer-name buffer) file-name) | |
799 ) | |
800 | |
801 (defun flymake-save-string-to-file(file-name data) | |
802 "save string data to file file-name" | |
803 (write-region data nil file-name nil 566) | |
804 ) | |
805 | |
806 (defun flymake-read-file-to-string(file-name) | |
807 "read file contents and return them as a string" | |
808 (with-temp-buffer | |
809 (insert-file-contents file-name) | |
810 (buffer-substring (point-min) (point-max)) | |
811 ) | |
812 ) | |
813 | |
814 (defun flymake-process-filter(process output) | |
815 "flymake process filter: parse output, highlight err lines" | |
816 (let* ((pid (process-id process)) | |
817 (source-buffer (get-buffer (flymake-get-source-buffer-name pid)))) | |
818 | |
819 (flymake-log 3 "received %d byte(s) of output from process %d" (length output) pid) | |
820 (when source-buffer | |
821 (flymake-parse-output-and-residual source-buffer output) | |
822 ) | |
823 ) | |
824 ) | |
825 | |
826 (defun flymake-process-sentinel(process event) | |
827 "Sentinel for syntax check buffers" | |
828 (if (memq (process-status process) '(signal exit)) | |
829 (let*((exit-status (process-exit-status process)) | |
830 (command (process-command process)) | |
831 (pid (process-id process)) | |
832 (source-buffer (get-buffer (flymake-get-source-buffer-name pid))) | |
833 (cleanup-f (flymake-get-cleanup-function (buffer-file-name source-buffer)))) | |
834 | |
835 (flymake-log 2 "process %d exited with code %d" pid exit-status) | |
836 (condition-case err | |
837 (progn | |
838 (flymake-log 3 "cleaning up using %s" cleanup-f) | |
839 (funcall cleanup-f source-buffer) | |
840 | |
841 (flymake-unreg-names pid) | |
842 (delete-process process) | |
843 | |
844 (when source-buffer | |
845 (save-excursion | |
846 (set-buffer source-buffer) | |
847 | |
848 (flymake-parse-residual source-buffer) | |
57847
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
849 (flymake-post-syntax-check source-buffer exit-status command) |
55822 | 850 (flymake-set-buffer-is-running source-buffer nil) |
851 ) | |
852 ) | |
853 ) | |
854 (error | |
855 (let ((err-str (format "Error in process sentinel for buffer %s: %s" | |
856 source-buffer (error-message-string err)))) | |
857 (flymake-log 0 err-str) | |
858 (flymake-set-buffer-is-running source-buffer nil) | |
859 ) | |
860 ) | |
861 ) | |
862 ) | |
863 ) | |
864 ) | |
865 | |
57847
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
866 (defun flymake-post-syntax-check(source-buffer exit-status command) |
55822 | 867 "" |
868 (flymake-set-buffer-err-info source-buffer (flymake-get-buffer-new-err-info source-buffer)) | |
869 (flymake-set-buffer-new-err-info source-buffer nil) | |
870 | |
871 (flymake-set-buffer-err-info source-buffer (flymake-fix-line-numbers | |
872 (flymake-get-buffer-err-info source-buffer) | |
873 1 | |
874 (flymake-count-lines source-buffer))) | |
875 (flymake-delete-own-overlays source-buffer) | |
876 (flymake-highlight-err-lines source-buffer (flymake-get-buffer-err-info source-buffer)) | |
877 | |
878 (let ((err-count (flymake-get-err-count (flymake-get-buffer-err-info source-buffer) "e")) | |
879 (warn-count (flymake-get-err-count (flymake-get-buffer-err-info source-buffer) "w"))) | |
880 | |
881 (flymake-log 2 "%s: %d error(s), %d warning(s) in %.2f second(s)" | |
882 (buffer-name source-buffer) err-count warn-count | |
883 (- (flymake-float-time) (flymake-get-buffer-check-start-time source-buffer))) | |
884 (flymake-set-buffer-check-start-time source-buffer nil) | |
885 (if (and (equal 0 err-count) (equal 0 warn-count)) | |
886 (if (equal 0 exit-status) | |
887 (flymake-report-status source-buffer "" "") ; PASSED | |
888 ;else | |
889 (if (not (flymake-get-buffer-check-was-interrupted source-buffer)) | |
890 (flymake-report-fatal-status (current-buffer) "CFGERR" | |
891 (format "Configuration error has occured while running %s" command)) | |
892 ;else | |
893 (flymake-report-status source-buffer nil "") ; "STOPPED" | |
894 ) | |
895 ) | |
896 ;else | |
897 (flymake-report-status source-buffer (format "%d/%d" err-count warn-count) "") | |
898 ) | |
899 ) | |
900 ) | |
901 | |
902 (defun flymake-parse-output-and-residual(source-buffer output) | |
903 "split output into lines, merge in residual if necessary" | |
904 (save-excursion | |
905 (set-buffer source-buffer) | |
906 (let* ((buffer-residual (flymake-get-buffer-output-residual source-buffer)) | |
907 (total-output (if buffer-residual (concat buffer-residual output) output)) | |
908 (lines-and-residual (flymake-split-output total-output)) | |
909 (lines (nth 0 lines-and-residual)) | |
910 (new-residual (nth 1 lines-and-residual))) | |
911 | |
912 (flymake-set-buffer-output-residual source-buffer new-residual) | |
913 (flymake-set-buffer-new-err-info source-buffer (flymake-parse-err-lines | |
914 (flymake-get-buffer-new-err-info source-buffer) | |
915 source-buffer lines)) | |
916 ) | |
917 ) | |
918 ) | |
919 | |
920 (defun flymake-parse-residual(source-buffer) | |
921 "parse residual if it's non empty" | |
922 (save-excursion | |
923 (set-buffer source-buffer) | |
924 (when (flymake-get-buffer-output-residual source-buffer) | |
925 (flymake-set-buffer-new-err-info source-buffer (flymake-parse-err-lines | |
926 (flymake-get-buffer-new-err-info source-buffer) | |
927 source-buffer | |
928 (list (flymake-get-buffer-output-residual source-buffer)))) | |
929 (flymake-set-buffer-output-residual source-buffer nil) | |
930 ) | |
931 ) | |
932 ) | |
933 | |
934 (defvar flymake-err-info nil | |
935 "sorted list of line numbers and lists of err info in the form (file, err-text)." | |
936 ) | |
937 (make-variable-buffer-local 'flymake-err-info) | |
938 (defun flymake-get-buffer-err-info(buffer) | |
939 (flymake-get-buffer-var buffer 'flymake-err-info) | |
940 ) | |
941 (defun flymake-set-buffer-err-info(buffer err-info) | |
942 (flymake-set-buffer-var buffer 'flymake-err-info err-info) | |
943 ) | |
944 (defun flymake-er-make-er(line-no line-err-info-list) | |
945 (list line-no line-err-info-list) | |
946 ) | |
947 (defun flymake-er-get-line(err-info) | |
948 (nth 0 err-info) | |
949 ) | |
950 (defun flymake-er-get-line-err-info-list(err-info) | |
951 (nth 1 err-info) | |
952 ) | |
953 | |
954 (defvar flymake-new-err-info nil | |
955 "the same as flymake -err-info, effective when a syntax check is in progress" | |
956 ) | |
957 (make-variable-buffer-local 'flymake-new-err-info) | |
958 (defun flymake-get-buffer-new-err-info(buffer) | |
959 (flymake-get-buffer-var buffer 'flymake-new-err-info) | |
960 ) | |
961 (defun flymake-set-buffer-new-err-info(buffer new-err-info) | |
962 (flymake-set-buffer-var buffer 'flymake-new-err-info new-err-info) | |
963 ) | |
964 | |
965 ;; getters/setters for line-err-info: (file, line, type, text). | |
966 (defun flymake-ler-make-ler(file line type text &optional full-file) | |
967 (list file line type text full-file) | |
968 ) | |
969 (defun flymake-ler-get-file(line-err-info) | |
970 (nth 0 line-err-info) | |
971 ) | |
972 (defun flymake-ler-get-line(line-err-info) | |
973 (nth 1 line-err-info) | |
974 ) | |
975 (defun flymake-ler-get-type(line-err-info) | |
976 (nth 2 line-err-info) | |
977 ) | |
978 (defun flymake-ler-get-text(line-err-info) | |
979 (nth 3 line-err-info) | |
980 ) | |
981 (defun flymake-ler-get-full-file(line-err-info) | |
982 (nth 4 line-err-info) | |
983 ) | |
984 (defun flymake-ler-set-file(line-err-info file) | |
985 (flymake-ler-make-ler file | |
986 (flymake-ler-get-line line-err-info) | |
987 (flymake-ler-get-type line-err-info) | |
988 (flymake-ler-get-text line-err-info) | |
989 (flymake-ler-get-full-file line-err-info)) | |
990 ) | |
991 (defun flymake-ler-set-full-file(line-err-info full-file) | |
992 (flymake-ler-make-ler (flymake-ler-get-file line-err-info) | |
993 (flymake-ler-get-line line-err-info) | |
994 (flymake-ler-get-type line-err-info) | |
995 (flymake-ler-get-text line-err-info) | |
996 full-file) | |
997 ) | |
998 (defun flymake-ler-set-line(line-err-info line) | |
999 (flymake-ler-make-ler (flymake-ler-get-file line-err-info) | |
1000 line | |
1001 (flymake-ler-get-type line-err-info) | |
1002 (flymake-ler-get-text line-err-info) | |
1003 (flymake-ler-get-full-file line-err-info)) | |
1004 ) | |
1005 | |
1006 (defun flymake-get-line-err-count(line-err-info-list type) | |
1007 "return number of errors of specified type - e or w" | |
1008 (let* ((idx 0) | |
1009 (count (length line-err-info-list)) | |
1010 (err-count 0)) | |
1011 | |
1012 (while (< idx count) | |
1013 (when (equal type (flymake-ler-get-type (nth idx line-err-info-list))) | |
1014 (setq err-count (1+ err-count)) | |
1015 ) | |
1016 (setq idx (1+ idx)) | |
1017 ) | |
1018 err-count | |
1019 ) | |
1020 ) | |
1021 | |
1022 (defun flymake-get-err-count(err-info-list type) | |
1023 "return number of errors of specified type for the err-info-list" | |
1024 (let* ((idx 0) | |
1025 (count (length err-info-list)) | |
1026 (err-count 0)) | |
1027 (while (< idx count) | |
1028 (setq err-count (+ err-count (flymake-get-line-err-count (nth 1 (nth idx err-info-list)) type))) | |
1029 (setq idx (1+ idx)) | |
1030 ) | |
1031 err-count | |
1032 ) | |
1033 ) | |
1034 | |
1035 (defun flymake-fix-line-numbers(err-info-list min-line max-line) | |
1036 "replace line-numbers < min-line with min-line and > max-line with max-line - as some compilers might report line number outside the file being compiled" | |
1037 (let* ((count (length err-info-list)) | |
1038 (err-info nil) | |
1039 (line 0)) | |
1040 (while (> count 0) | |
1041 (setq err-info (nth (1- count) err-info-list)) | |
1042 (setq line (flymake-er-get-line err-info)) | |
1043 (when (or (< line min-line) (> line max-line)) | |
1044 (setq line (if (< line min-line) min-line max-line)) | |
1045 (setq err-info-list (flymake-set-at err-info-list (1- count) | |
1046 (flymake-er-make-er line | |
1047 (flymake-er-get-line-err-info-list err-info)))) | |
1048 ) | |
1049 (setq count (1- count)) | |
1050 ) | |
1051 ) | |
1052 err-info-list | |
1053 ) | |
1054 | |
1055 (defun flymake-highlight-err-lines(buffer err-info-list) | |
1056 "highlight err-lines in buffer using info from err-info-list" | |
1057 (save-excursion | |
1058 (set-buffer buffer) | |
1059 (let* ((idx 0) | |
1060 (count (length err-info-list))) | |
1061 (while (< idx count) | |
1062 (flymake-highlight-line (car (nth idx err-info-list)) (nth 1 (nth idx err-info-list))) | |
1063 (setq idx (1+ idx)) | |
1064 ) | |
1065 ) | |
1066 ) | |
1067 ) | |
1068 | |
1069 (defun flymake-overlay-p(ov) | |
1070 "Determine whether overlay was created by flymake" | |
1071 (and (overlayp ov) (overlay-get ov 'flymake-overlay)) | |
1072 ) | |
1073 | |
1074 (defun flymake-make-overlay(beg end tooltip-text face mouse-face) | |
1075 "Allocate a flymake overlay in range beg end" | |
1076 (when (not (flymake-region-has-flymake-overlays beg end)) | |
1077 (let ((ov (make-overlay beg end nil t t))) | |
1078 (overlay-put ov 'face face) | |
1079 (overlay-put ov 'mouse-face mouse-face) | |
1080 (overlay-put ov 'help-echo tooltip-text) | |
1081 (overlay-put ov 'flymake-overlay t) | |
1082 (overlay-put ov 'priority 100) | |
1083 ;+(flymake-log 3 "created overlay %s" ov) | |
1084 ov | |
1085 ) | |
1086 (flymake-log 3 "created an overlay at (%d-%d)" beg end) | |
1087 ) | |
1088 ) | |
1089 | |
1090 (defun flymake-delete-own-overlays(buffer) | |
1091 "Delete all flymake overlays in buffer" | |
1092 (save-excursion | |
1093 (set-buffer buffer) | |
1094 (let ((ov (overlays-in (point-min) (point-max)))) | |
1095 (while (consp ov) | |
1096 (when (flymake-overlay-p (car ov)) | |
1097 (delete-overlay (car ov)) | |
1098 ;+(flymake-log 3 "deleted overlay %s" ov) | |
1099 ) | |
1100 (setq ov (cdr ov)) | |
1101 ) | |
1102 ) | |
1103 ) | |
1104 ) | |
1105 | |
1106 (defun flymake-region-has-flymake-overlays(beg end) | |
1107 "t if specified regions has at least one flymake overlay, nil otrherwise" | |
1108 (let ((ov (overlays-in beg end)) | |
1109 (has-flymake-overlays nil)) | |
1110 (while (consp ov) | |
1111 (when (flymake-overlay-p (car ov)) | |
1112 (setq has-flymake-overlays t) | |
1113 ) | |
1114 (setq ov (cdr ov)) | |
1115 ) | |
1116 ) | |
1117 ) | |
1118 | |
1119 (defface flymake-errline-face | |
1120 ;+ '((((class color)) (:foreground "OrangeRed" :bold t :underline t)) | |
1121 ;+ '((((class color)) (:underline "OrangeRed")) | |
1122 '((((class color)) (:background "LightPink")) | |
1123 (t (:bold t))) | |
1124 "Face used for marking error lines" | |
1125 :group 'flymake | |
1126 ) | |
1127 | |
1128 (defface flymake-warnline-face | |
1129 '((((class color)) (:background "LightBlue2")) | |
1130 (t (:bold t))) | |
1131 "Face used for marking warning lines" | |
1132 :group 'flymake | |
1133 ) | |
1134 | |
1135 | |
1136 (defun flymake-highlight-line(line-no line-err-info-list) | |
1137 "highlight line line-no in current buffer, perhaps use text from line-err-info-list to enhance highlighting" | |
1138 (goto-line line-no) | |
1139 (let* ((line-beg (flymake-line-beginning-position)) | |
1140 (line-end (flymake-line-end-position)) | |
1141 (beg line-beg) | |
1142 (end line-end) | |
1143 (tooltip-text (flymake-ler-get-text (nth 0 line-err-info-list))) | |
1144 (face nil)) | |
1145 | |
1146 (goto-char line-beg) | |
1147 (while (looking-at "[ \t]") | |
1148 (forward-char) | |
1149 ) | |
1150 | |
1151 (setq beg (point)) | |
1152 | |
1153 (goto-char line-end) | |
1154 (while (and (looking-at "[ \t\r\n]") (> (point) 1)) | |
1155 (backward-char) | |
1156 ) | |
1157 | |
1158 (setq end (1+ (point))) | |
1159 | |
1160 (when (<= end beg) | |
1161 (setq beg line-beg) | |
1162 (setq end line-end) | |
1163 ) | |
1164 (when (= end beg) | |
1165 (goto-char end) | |
1166 (forward-line) | |
1167 (setq end (point)) | |
1168 ) | |
1169 (if (> (flymake-get-line-err-count line-err-info-list "e") 0) | |
1170 (setq face 'flymake-errline-face) | |
1171 ;else | |
1172 (setq face 'flymake-warnline-face) | |
1173 ) | |
1174 (flymake-make-overlay beg end tooltip-text face nil) | |
1175 ) | |
1176 ) | |
1177 | |
1178 (defun flymake-parse-err-lines(err-info-list source-buffer lines) | |
1179 "parse err lines, store info in err-info-list" | |
1180 (let* ((count (length lines)) | |
1181 (idx 0) | |
1182 (line-err-info nil) | |
1183 (real-file-name nil) | |
1184 (source-file-name (buffer-file-name source-buffer)) | |
1185 (get-real-file-name-f (flymake-get-real-file-name-function source-file-name))) | |
1186 | |
1187 (while (< idx count) | |
1188 (setq line-err-info (flymake-parse-line (nth idx lines))) | |
1189 (when line-err-info | |
1190 (setq real-file-name (funcall get-real-file-name-f source-buffer (flymake-ler-get-file line-err-info))) | |
1191 (setq line-err-info (flymake-ler-set-full-file line-err-info real-file-name)) | |
1192 | |
1193 (if (flymake-same-files real-file-name source-file-name) | |
1194 (setq line-err-info (flymake-ler-set-file line-err-info nil)) | |
1195 ;else | |
1196 (setq line-err-info (flymake-ler-set-file line-err-info (file-name-nondirectory real-file-name))) | |
1197 ) | |
1198 | |
1199 (setq err-info-list (flymake-add-err-info err-info-list line-err-info)) | |
1200 ) | |
1201 (flymake-log 3 "parsed '%s', %s line-err-info" (nth idx lines) (if line-err-info "got" "no")) | |
1202 (setq idx (1+ idx)) | |
1203 ) | |
1204 err-info-list | |
1205 ) | |
1206 ) | |
1207 | |
1208 (defun flymake-split-output(output) | |
1209 "split output into lines, return last one as residual if it does not end with newline char. Returns ((lines) residual)" | |
1210 (when (and output (> (length output) 0)) | |
1211 (let* ((lines (flymake-split-string output "[\n\r]+")) | |
1212 (complete (equal "\n" (char-to-string (aref output (1- (length output)))))) | |
1213 (residual nil)) | |
1214 (when (not complete) | |
1215 (setq residual (car (last lines))) | |
1216 (setq lines (butlast lines)) | |
1217 ) | |
1218 (list lines residual) | |
1219 ) | |
1220 ) | |
1221 ) | |
1222 | |
57847
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1223 (defun flymake-reformat-err-line-patterns-from-compile-el(original-list) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1224 "grab error line patterns from original list in compile.el format, convert to flymake internal format" |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1225 (let* ((converted-list '())) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1226 (mapcar |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1227 (lambda (item) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1228 (setq item (cdr item)) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1229 (let ((regexp (nth 0 item)) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1230 (file (nth 1 item)) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1231 (line (nth 2 item)) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1232 (col (nth 3 item)) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1233 end-line) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1234 (if (consp file) (setq file (car file))) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1235 (if (consp line) (setq end-line (cdr line) line (car line))) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1236 (if (consp col) (setq col (car col))) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1237 |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1238 (when (not (functionp line)) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1239 (setq converted-list (cons (list regexp file line col) converted-list)) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1240 ) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1241 ) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1242 ) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1243 original-list |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1244 ) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1245 converted-list |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1246 ) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1247 ) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1248 |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1249 (require 'compile) |
55822 | 1250 (defvar flymake-err-line-patterns ; regexp file-idx line-idx col-idx (optional) text-idx(optional), match-end to end of string is error text |
1251 (append | |
1252 '( | |
1253 ; MS Visual C++ 6.0 | |
1254 ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \: \\(\\(error\\|warning\\|fatal error\\) \\(C[0-9]+\\):[ \t\n]*\\(.+\\)\\)" | |
1255 1 3 nil 4) | |
1256 ; jikes | |
1257 ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[0-9]+\:[0-9]+\:[0-9]+\: \\(\\(Error\\|Warning\\|Caution\\|Semantic Error\\):[ \t\n]*\\(.+\\)\\)" | |
1258 1 3 nil 4) | |
1259 ; MS midl | |
1260 ("midl[ ]*:[ ]*\\(command line error .*\\)" | |
1261 nil nil nil 1) | |
1262 ; MS C# | |
1263 ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\),[0-9]+)\: \\(\\(error\\|warning\\|fatal error\\) \\(CS[0-9]+\\):[ \t\n]*\\(.+\\)\\)" | |
1264 1 3 nil 4) | |
1265 ; perl | |
1266 ("\\(.*\\) at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]" 2 3 nil 1) | |
1267 ; LaTeX warnings (fileless) ("\\(LaTeX \\(Warning\\|Error\\): .*\\) on input line \\([0-9]+\\)" 20 3 nil 1) | |
1268 ; ant/javac | |
1269 (" *\\(\\[javac\\]\\)? *\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[ \t\n]*\\(.+\\)" | |
1270 2 4 nil 5) | |
1271 ) | |
57847
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1272 ;; compilation-error-regexp-alist) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1273 (flymake-reformat-err-line-patterns-from-compile-el compilation-error-regexp-alist-alist)) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1274 "patterns for matching error/warning lines, (regexp file-idx line-idx err-text-idx). Use flymake-reformat-err-line-patterns-from-compile-el to add patterns from compile.el" |
55822 | 1275 ) |
1276 ;(defcustom flymake-err-line-patterns | |
1277 ; '( | |
1278 ; ; MS Visual C++ 6.0 | |
1279 ; ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \: \\(\\(error\\|warning\\|fatal error\\) \\(C[0-9]+\\):[ \t\n]*\\(.+\\)\\)" | |
1280 ; 1 3 4) | |
1281 ; ; jikes | |
1282 ; ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[0-9]+\:[0-9]+\:[0-9]+\: \\(\\(Error\\|Warning\\|Caution\\):[ \t\n]*\\(.+\\)\\)" | |
1283 ; 1 3 4)) | |
1284 ; "patterns for matching error/warning lines, (regexp file-idx line-idx err-text-idx)" | |
1285 ; :group 'flymake | |
1286 ; :type '(repeat (string number number number)) | |
1287 ;) | |
1288 | |
1289 (defun flymake-parse-line(line) | |
1290 "parse line to see whether it's an error of warning, return it's components or nil for no match" | |
1291 (let ((raw-file-name nil) | |
1292 (line-no 0) | |
1293 (err-type "e") | |
1294 (err-text nil) | |
1295 (count (length flymake-err-line-patterns)) | |
1296 (idx 0) | |
1297 (matched nil)) | |
1298 (while (and (< idx count) (not matched)) | |
1299 (when (string-match (car (nth idx flymake-err-line-patterns)) line) | |
1300 (let* ((file-idx (nth 1 (nth idx flymake-err-line-patterns))) | |
1301 (line-idx (nth 2 (nth idx flymake-err-line-patterns)))) | |
1302 | |
1303 (setq raw-file-name (if file-idx (match-string file-idx line) nil)) | |
1304 (setq line-no (if line-idx (string-to-int (match-string line-idx line)) 0)) | |
1305 (setq err-text (if (> (length (nth idx flymake-err-line-patterns)) 4) | |
1306 (match-string (nth 4 (nth idx flymake-err-line-patterns)) line) | |
1307 (flymake-patch-err-text (substring line (match-end 0))))) | |
1308 (or err-text (setq err-text "<no error text>")) | |
1309 (if (and err-text (string-match "^[wW]arning" err-text)) | |
1310 (setq err-type "w") | |
1311 ) | |
1312 (flymake-log 3 "parse line: file-idx=%s line-idx=%s file=%s line=%s text=%s" file-idx line-idx | |
1313 raw-file-name line-no err-text) | |
1314 (setq matched t) | |
1315 ) | |
1316 ) | |
1317 (setq idx (1+ idx)) | |
1318 ) | |
1319 (if matched | |
1320 (flymake-ler-make-ler raw-file-name line-no err-type err-text) | |
1321 ; else | |
1322 () | |
1323 ) | |
1324 ) | |
1325 ) | |
1326 | |
1327 (defun flymake-find-err-info(err-info-list line-no) | |
1328 "find (line-err-info-list pos) for specified line-no" | |
1329 (if err-info-list | |
1330 (let* ((line-err-info-list nil) | |
1331 (pos 0) | |
1332 (count (length err-info-list))) | |
1333 | |
1334 (while (and (< pos count) (< (car (nth pos err-info-list)) line-no)) | |
1335 (setq pos (1+ pos)) | |
1336 ) | |
1337 (when (and (< pos count) (equal (car (nth pos err-info-list)) line-no)) | |
1338 (setq line-err-info-list (flymake-er-get-line-err-info-list (nth pos err-info-list))) | |
1339 ) | |
1340 (list line-err-info-list pos) | |
1341 ) | |
1342 ;else | |
1343 '(nil 0) | |
1344 ) | |
1345 ) | |
1346 | |
1347 (defun flymake-line-err-info-is-less-or-equal(line-one line-two) | |
1348 (or (string< (flymake-ler-get-type line-one) (flymake-ler-get-type line-two)) | |
1349 (and (string= (flymake-ler-get-type line-one) (flymake-ler-get-type line-two)) | |
1350 (not (flymake-ler-get-file line-one)) (flymake-ler-get-file line-two) | |
1351 ) | |
1352 (and (string= (flymake-ler-get-type line-one) (flymake-ler-get-type line-two)) | |
1353 (or (and (flymake-ler-get-file line-one) (flymake-ler-get-file line-two)) | |
1354 (and (not (flymake-ler-get-file line-one)) (not (flymake-ler-get-file line-two))) | |
1355 ) | |
1356 ) | |
1357 ) | |
1358 ) | |
1359 | |
1360 (defun flymake-add-line-err-info(line-err-info-list line-err-info) | |
1361 "insert new err info favoring sorting: err-type e/w, filename nil/non-nill" | |
1362 (if (not line-err-info-list) | |
1363 (list line-err-info) | |
1364 ;else | |
1365 (let* ((count (length line-err-info-list)) | |
1366 (idx 0)) | |
1367 (while (and (< idx count) (flymake-line-err-info-is-less-or-equal (nth idx line-err-info-list) line-err-info)) | |
1368 (setq idx (1+ idx)) | |
1369 ) | |
1370 (cond ((equal 0 idx) (setq line-err-info-list (cons line-err-info line-err-info-list))) | |
1371 (t (setq line-err-info-list (flymake-ins-after line-err-info-list (1- idx) line-err-info))) | |
1372 ) | |
1373 line-err-info-list | |
1374 ) | |
1375 ) | |
1376 ) | |
1377 | |
1378 (defun flymake-add-err-info(err-info-list line-err-info) | |
1379 "add error info (file line type text) to err info list preserving sort order" | |
1380 (let* ((count (length err-info-list)) | |
1381 (line-no (if (flymake-ler-get-file line-err-info) 1 (flymake-ler-get-line line-err-info))) | |
1382 (info-and-pos (flymake-find-err-info err-info-list line-no)) | |
1383 (exists (car info-and-pos)) | |
1384 (pos (nth 1 info-and-pos)) | |
1385 (line-err-info-list nil) | |
1386 (err-info nil)) | |
1387 | |
1388 (if exists | |
1389 (setq line-err-info-list (flymake-er-get-line-err-info-list (car (nthcdr pos err-info-list)))) | |
1390 ) | |
1391 (setq line-err-info-list (flymake-add-line-err-info line-err-info-list line-err-info)) | |
1392 | |
1393 (setq err-info (flymake-er-make-er line-no line-err-info-list)) | |
1394 (cond (exists (setq err-info-list (flymake-set-at err-info-list pos err-info))) | |
1395 ((equal 0 pos) (setq err-info-list (cons err-info err-info-list))) | |
1396 (t (setq err-info-list (flymake-ins-after err-info-list (1- pos) err-info))) | |
1397 ) | |
1398 err-info-list | |
1399 ) | |
1400 ) | |
1401 | |
1402 (defun flymake-get-project-include-dirs-imp(basedir) | |
1403 "include dirs for the project current file belongs to" | |
1404 (if (flymake-get-project-include-dirs-from-cache basedir) | |
1405 (progn | |
1406 (flymake-get-project-include-dirs-from-cache basedir) | |
1407 ) | |
1408 ;else | |
1409 (let* ((command-line (concat "make -C\"" basedir "\" DUMPVARS=INCLUDE_DIRS dumpvars")) | |
1410 (output (shell-command-to-string command-line)) | |
1411 (lines (flymake-split-string output "\n")) | |
1412 (count (length lines)) | |
1413 (idx 0) | |
1414 (inc-dirs nil)) | |
1415 (while (and (< idx count) (not (string-match "^INCLUDE_DIRS=.*" (nth idx lines)))) | |
1416 (setq idx (1+ idx)) | |
1417 ) | |
1418 (when (< idx count) | |
1419 (let* ((inc-lines (flymake-split-string (nth idx lines) " *-I")) | |
1420 (inc-count (length inc-lines))) | |
1421 (while (> inc-count 0) | |
1422 (when (not (string-match "^INCLUDE_DIRS=.*" (nth (1- inc-count) inc-lines))) | |
1423 (setq inc-dirs (cons (flymake-replace-regexp-in-string "\"" "" (nth (1- inc-count) inc-lines)) inc-dirs)) | |
1424 ) | |
1425 (setq inc-count (1- inc-count)) | |
1426 ) | |
1427 ) | |
1428 ) | |
1429 (flymake-add-project-include-dirs-to-cache basedir inc-dirs) | |
1430 inc-dirs | |
1431 ) | |
1432 ) | |
1433 ) | |
1434 | |
1435 (defcustom flymake-get-project-include-dirs-function 'flymake-get-project-include-dirs-imp | |
1436 "function used to get project inc dirs, one paramater: basedir name" | |
1437 :group 'flymake | |
1438 :type 'function | |
1439 ) | |
1440 | |
1441 (defun flymake-get-project-include-dirs(basedir) | |
1442 (funcall flymake-get-project-include-dirs-function basedir) | |
1443 ) | |
1444 | |
1445 (defun flymake-get-system-include-dirs() | |
1446 "system include dirs - from the 'INCLUDE' env setting" | |
1447 (let* ((includes (getenv "INCLUDE"))) | |
1448 (if includes (flymake-split-string includes path-separator) nil) | |
1449 ) | |
1450 ) | |
1451 | |
1452 (defvar flymake-project-include-dirs-cache (flymake-makehash 'equal)) | |
1453 (defun flymake-get-project-include-dirs-from-cache(base-dir) | |
1454 (gethash base-dir flymake-project-include-dirs-cache) | |
1455 ) | |
1456 (defun flymake-add-project-include-dirs-to-cache(base-dir include-dirs) | |
1457 (puthash base-dir include-dirs flymake-project-include-dirs-cache) | |
1458 ) | |
1459 (defun flymake-clear-project-include-dirs-cache() | |
1460 (clrhash flymake-project-include-dirs-cache) | |
1461 ) | |
1462 | |
1463 (defun flymake-get-include-dirs(base-dir) | |
1464 "dirs to use when resolving local filenames" | |
1465 (let* ((include-dirs (append '(".") (flymake-get-project-include-dirs base-dir) (flymake-get-system-include-dirs)))) | |
1466 include-dirs | |
1467 ) | |
1468 ) | |
1469 | |
1470 (defun flymake-find-file(rel-file-name include-dirs) | |
1471 "iterate through include-dirs, return first 'include-dir/rel-file-name' that exists, or just rel-file-name if not" | |
1472 (let* ((count (length include-dirs)) | |
1473 (idx 0) | |
1474 (found nil) | |
1475 (full-file-name rel-file-name)) | |
1476 | |
1477 (while (and (not found) (< idx count)) | |
1478 (let* ((dir (nth idx include-dirs))) | |
1479 (setq full-file-name (concat dir "/" rel-file-name)) | |
1480 (when (file-exists-p full-file-name) | |
57847
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1481 (setq found t) |
55822 | 1482 ) |
1483 ) | |
1484 (setq idx (1+ idx)) | |
1485 ) | |
1486 (if found | |
1487 full-file-name | |
1488 ;else | |
1489 rel-file-name | |
1490 ) | |
1491 ) | |
1492 ) | |
1493 | |
1494 (defun flymake-restore-formatting(source-buffer) | |
1495 "Remove any formatting made by flymake" | |
1496 ) | |
1497 | |
1498 (defun flymake-get-program-dir(buffer) | |
1499 "dir to start profram in" | |
1500 (unless (bufferp buffer) | |
1501 (error "invlid buffer") | |
1502 ) | |
1503 (save-excursion | |
1504 (set-buffer buffer) | |
1505 default-directory | |
1506 ) | |
1507 ) | |
1508 | |
1509 (defun flymake-safe-delete-file(file-name) | |
1510 (when (and file-name (file-exists-p file-name)) | |
1511 (delete-file file-name) | |
1512 (flymake-log 1 "deleted file %s" file-name) | |
1513 ) | |
1514 ) | |
1515 | |
1516 (defun flymake-safe-delete-directory(dir-name) | |
1517 (condition-case err | |
1518 (progn | |
1519 (delete-directory dir-name) | |
1520 (flymake-log 1 "deleted dir %s" dir-name) | |
1521 ) | |
1522 (error | |
1523 (flymake-log 1 "failed to delete dir %s, error ignored" dir-name) | |
1524 ) | |
1525 ) | |
1526 ) | |
1527 | |
1528 (defcustom flymake-compilation-prevents-syntax-check t | |
1529 "if non-nil, syntax check won't be started in case compilation is running" | |
1530 :group 'flymake | |
1531 :type 'boolean | |
1532 ) | |
1533 | |
1534 (defun flymake-start-syntax-check(buffer) | |
1535 "start syntax checking for buffer" | |
1536 (unless (bufferp buffer) | |
1537 (error "expected a buffer") | |
1538 ) | |
1539 (save-excursion | |
1540 (set-buffer buffer) | |
1541 (flymake-log 3 "flymake is running: %s" (flymake-get-buffer-is-running buffer)) | |
1542 (when (and (not (flymake-get-buffer-is-running buffer)) | |
1543 (flymake-can-syntax-check-file (buffer-file-name buffer))) | |
1544 (when (or (not flymake-compilation-prevents-syntax-check) | |
1545 (not (flymake-compilation-is-running))) ;+ (flymake-rep-ort-status buffer "COMP") | |
1546 (flymake-clear-buildfile-cache) | |
1547 (flymake-clear-project-include-dirs-cache) | |
1548 | |
1549 (flymake-set-buffer-check-was-interrupted buffer nil) | |
1550 (flymake-set-buffer-data buffer (flymake-makehash 'equal)) | |
1551 | |
1552 (let* ((source-file-name (buffer-file-name buffer)) | |
1553 (init-f (flymake-get-init-function source-file-name)) | |
1554 (cleanup-f (flymake-get-cleanup-function source-file-name)) | |
1555 (cmd-and-args (funcall init-f buffer)) | |
1556 (cmd (nth 0 cmd-and-args)) | |
1557 (args (nth 1 cmd-and-args)) | |
1558 (dir (nth 2 cmd-and-args))) | |
1559 (if (not cmd-and-args) | |
1560 (progn | |
1561 (flymake-log 0 "init function %s for %s failed, cleaning up" init-f source-file-name) | |
1562 (funcall cleanup-f buffer) | |
1563 ) | |
1564 ;else | |
1565 (progn | |
1566 (flymake-set-buffer-last-change-time buffer nil) | |
1567 (flymake-start-syntax-check-process buffer cmd args dir) | |
1568 ) | |
1569 ) | |
1570 ) | |
1571 ) | |
1572 ) | |
1573 ) | |
1574 ) | |
1575 | |
1576 (defun flymake-start-syntax-check-process(buffer cmd args dir) | |
1577 "start syntax check-process" | |
1578 | |
1579 (let* ((process nil)) | |
1580 (condition-case err | |
1581 (progn | |
1582 (when dir | |
1583 (let ((default-directory dir)) | |
1584 (flymake-log 3 "starting process on dir %s" default-directory) | |
1585 ) | |
1586 ) | |
1587 (setq process (get-process (apply 'start-process "flymake-proc" nil cmd args))) | |
1588 (set-process-sentinel process 'flymake-process-sentinel) | |
1589 (set-process-filter process 'flymake-process-filter) | |
1590 | |
1591 (flymake-reg-names (process-id process) (buffer-name buffer)) | |
1592 | |
1593 (flymake-set-buffer-is-running buffer t) | |
1594 (flymake-set-buffer-last-change-time buffer nil) | |
1595 (flymake-set-buffer-check-start-time buffer (flymake-float-time)) | |
1596 | |
1597 (flymake-report-status buffer nil "*") | |
1598 (flymake-log 2 "started process %d, command=%s, dir=%s" | |
1599 (process-id process) (process-command process) default-directory) | |
1600 process | |
1601 ) | |
1602 (error | |
57847
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1603 (let* ((err-str (format "Failed to launch syntax check process '%s' with args %s: %s" |
55822 | 1604 cmd args (error-message-string err))) |
1605 (source-file-name (buffer-file-name buffer)) | |
1606 (cleanup-f (flymake-get-cleanup-function source-file-name))) | |
1607 (flymake-log 0 err-str) | |
1608 (funcall cleanup-f buffer) | |
1609 (flymake-report-fatal-status buffer "PROCERR" err-str) | |
1610 ) | |
1611 ) | |
1612 ) | |
1613 ) | |
1614 ) | |
1615 | |
1616 (defun flymake-kill-process(pid &optional rest) | |
1617 "kill process pid" | |
1618 (signal-process pid 9) | |
1619 (let* ((buffer-name (flymake-get-source-buffer-name pid))) | |
1620 (when (and buffer-name (get-buffer buffer-name)) | |
1621 (flymake-set-buffer-check-was-interrupted (get-buffer buffer-name) t) | |
1622 ) | |
1623 ) | |
1624 (flymake-log 1 "killed process %d" pid) | |
1625 ) | |
1626 | |
1627 (defun flymake-stop-all-syntax-checks() | |
1628 "kill all syntax check processes" | |
1629 (interactive) | |
1630 (let ((pids (copy-hash-table flymake-pid-to-names))) | |
1631 (maphash 'flymake-kill-process pids) | |
1632 ) | |
1633 ) | |
1634 | |
1635 (defun flymake-compilation-is-running() | |
1636 (and (boundp 'compilation-in-progress) | |
1637 compilation-in-progress) | |
1638 ) | |
1639 | |
1640 (defun flymake-compile() | |
1641 "kill all flymake syntax checks, start compilation" | |
1642 (interactive) | |
1643 (flymake-stop-all-syntax-checks) | |
1644 (call-interactively 'compile) | |
1645 ) | |
1646 | |
1647 (defvar flymake-is-running nil | |
1648 "t if flymake syntax check process is running for the current buffer" | |
1649 ) | |
1650 (make-variable-buffer-local 'flymake-is-running) | |
1651 (defun flymake-get-buffer-is-running(buffer) | |
1652 (flymake-get-buffer-var buffer 'flymake-is-running) | |
1653 ) | |
1654 (defun flymake-set-buffer-is-running(buffer is-running) | |
1655 (flymake-set-buffer-var buffer 'flymake-is-running is-running) | |
1656 ) | |
1657 | |
1658 (defvar flymake-timer nil | |
1659 "timer for starting syntax checks" | |
1660 ) | |
1661 (make-variable-buffer-local 'flymake-timer) | |
1662 (defun flymake-get-buffer-timer(buffer) | |
1663 (flymake-get-buffer-var buffer 'flymake-timer) | |
1664 ) | |
1665 (defun flymake-set-buffer-timer(buffer timer) | |
1666 (flymake-set-buffer-var buffer 'flymake-timer timer) | |
1667 ) | |
1668 | |
1669 (defvar flymake-last-change-time nil | |
1670 "time of last buffer change" | |
1671 ) | |
1672 (make-variable-buffer-local 'flymake-last-change-time) | |
1673 (defun flymake-get-buffer-last-change-time(buffer) | |
1674 (flymake-get-buffer-var buffer 'flymake-last-change-time) | |
1675 ) | |
1676 (defun flymake-set-buffer-last-change-time(buffer change-time) | |
1677 (flymake-set-buffer-var buffer 'flymake-last-change-time change-time) | |
1678 ) | |
1679 | |
1680 (defvar flymake-check-start-time nil | |
1681 "time at which syntax check was started") | |
1682 (make-variable-buffer-local 'flymake-check-start-time) | |
1683 (defun flymake-get-buffer-check-start-time(buffer) | |
1684 (flymake-get-buffer-var buffer 'flymake-check-start-time) | |
1685 ) | |
1686 (defun flymake-set-buffer-check-start-time(buffer check-start-time) | |
1687 (flymake-set-buffer-var buffer 'flymake-check-start-time check-start-time) | |
1688 ) | |
1689 | |
1690 (defvar flymake-check-was-interrupted nil | |
1691 "t if syntax check was killed by flymake-compile" | |
1692 ) | |
1693 (make-variable-buffer-local 'flymake-check-was-interrupted) | |
1694 (defun flymake-get-buffer-check-was-interrupted(buffer) | |
1695 (flymake-get-buffer-var buffer 'flymake-check-was-interrupted) | |
1696 ) | |
1697 (defun flymake-set-buffer-check-was-interrupted(buffer interrupted) | |
1698 (flymake-set-buffer-var buffer 'flymake-check-was-interrupted interrupted) | |
1699 ) | |
1700 | |
1701 (defcustom flymake-no-changes-timeout 0.5 | |
1702 "time to wait after last change before starting compilation" | |
1703 :group 'flymake | |
1704 :type 'number | |
1705 ) | |
1706 | |
1707 (defun flymake-on-timer-event(buffer) | |
1708 "start a syntax check for buffer if necessary" | |
1709 ;+(flymake-log 3 "timer: running=%s, time=%s, cur-time=%s" (flymake-get-buffer-is-running buffer) (flymake-get-buffer-last-change-time buffer) (flymake-float-time)) | |
1710 | |
1711 (when (and (bufferp buffer) (not (flymake-get-buffer-is-running buffer))) | |
1712 (save-excursion | |
1713 (set-buffer buffer) | |
1714 (when (and (flymake-get-buffer-last-change-time buffer) | |
1715 (> (flymake-float-time) (+ flymake-no-changes-timeout (flymake-get-buffer-last-change-time buffer)))) | |
1716 (flymake-set-buffer-last-change-time buffer nil) | |
1717 (flymake-log 3 "starting syntax check as more than 1 second passed since last change") | |
1718 (flymake-start-syntax-check buffer) | |
1719 ) | |
1720 ) | |
1721 ) | |
1722 ) | |
1723 | |
1724 (defun flymake-start-syntax-check-for-current-buffer() | |
1725 "run flymake-start-syntax-check for current buffer if it isn't already running" | |
1726 (interactive) | |
1727 (flymake-start-syntax-check (current-buffer)) | |
1728 ) | |
1729 | |
1730 (defun flymake-current-line-no() | |
1731 "return number of current line in current buffer" | |
1732 (interactive) | |
1733 (let ((beg (point-min)) | |
1734 (end (if (= (point) (point-max)) (point) (1+ (point))))) | |
1735 (count-lines beg end) | |
1736 ) | |
1737 ) | |
1738 | |
1739 (defun flymake-get-line-count(buffer) | |
1740 "return number of lines in buffer" | |
1741 (unless (bufferp buffer) | |
1742 (error "invalid buffer") | |
1743 ) | |
1744 (save-excursion | |
1745 (set-buffer buffer) | |
1746 (count-lines (point-min) (point-max)) | |
1747 ) | |
1748 ) | |
1749 | |
1750 (defun flymake-count-lines(buffer) | |
1751 "return number of lines in buffer" | |
1752 (save-excursion | |
1753 (set-buffer buffer) | |
1754 (count-lines (point-min) (point-max)) | |
1755 ) | |
1756 ) | |
1757 | |
1758 (defun flymake-get-point-pixel-pos() | |
1759 "return point position in pixels: (x, y)" | |
1760 (let ((mouse-pos (mouse-position)) | |
1761 (pixel-pos nil) | |
1762 (ret nil)) | |
1763 (if (car (cdr mouse-pos)) | |
1764 (progn | |
1765 (set-mouse-position (flymake-selected-frame) (current-column) (flymake-current-row)) | |
1766 (setq pixel-pos (mouse-pixel-position)) | |
1767 (set-mouse-position (car mouse-pos) (car (cdr mouse-pos)) (cdr (cdr mouse-pos))) | |
1768 (setq ret (list (car (cdr pixel-pos)) (cdr (cdr pixel-pos)))) | |
1769 ) | |
1770 ;else | |
1771 (progn | |
1772 (setq ret '(0 0)) | |
1773 ) | |
1774 ) | |
1775 (flymake-log 3 "mouse pos is %s" ret) | |
1776 ret | |
1777 ) | |
1778 ) | |
1779 | |
1780 (defun flymake-display-err-menu-for-current-line() | |
1781 "Display a menu with errors/warnings for current line if it has errors and/or warnings" | |
1782 (interactive) | |
1783 (let* ((line-no (flymake-current-line-no)) | |
1784 (line-err-info-list (nth 0 (flymake-find-err-info (flymake-get-buffer-err-info (current-buffer)) line-no))) | |
1785 (menu-data (flymake-make-err-menu-data line-no line-err-info-list)) | |
1786 (choice nil) | |
1787 (mouse-pos (flymake-get-point-pixel-pos)) | |
1788 (moved-mouse-pos (list (car mouse-pos) (+ 10 (car (cdr mouse-pos))))) | |
1789 (menu-pos (list (flymake-get-point-pixel-pos) (selected-window)))) | |
1790 (if menu-data | |
1791 (progn | |
1792 (setq choice (flymake-popup-menu menu-pos menu-data)) | |
1793 (flymake-log 3 "choice=%s" choice) | |
1794 (when choice | |
1795 (eval choice) | |
1796 ) | |
1797 ) | |
1798 ;else | |
1799 (flymake-log 1 "no errors for line %d" line-no) | |
1800 ) | |
1801 ) | |
1802 ) | |
1803 | |
1804 (defun flymake-make-err-menu-data(line-no line-err-info-list) | |
1805 "Make a (menu-title (item-title item-action)*) list with errors/warnings from line-err-info" | |
1806 (let* ((menu-items nil)) | |
1807 (when line-err-info-list | |
1808 (let* ((count (length line-err-info-list)) | |
1809 (menu-item-text nil)) | |
1810 (while (> count 0) | |
1811 (setq menu-item-text (flymake-ler-get-text (nth (1- count) line-err-info-list))) | |
1812 (let* ((file (flymake-ler-get-file (nth (1- count) line-err-info-list))) | |
1813 (full-file (flymake-ler-get-full-file (nth (1- count) line-err-info-list))) | |
1814 (line (flymake-ler-get-line (nth (1- count) line-err-info-list)))) | |
1815 (if file | |
1816 (setq menu-item-text (concat menu-item-text " - " file "(" (format "%d" line) ")")) | |
1817 ) | |
1818 (setq menu-items (cons (list menu-item-text | |
1819 (if file (list 'flymake-goto-file-and-line full-file line) nil)) | |
1820 menu-items)) | |
1821 ) | |
1822 (setq count (1- count)) | |
1823 ) | |
1824 (flymake-log 3 "created menu-items with %d item(s)" (length menu-items)) | |
1825 ) | |
1826 ) | |
1827 (if menu-items | |
1828 (let* ((menu-title (format "Line %d: %d error(s), %d warning(s)" line-no | |
1829 (flymake-get-line-err-count line-err-info-list "e") | |
1830 (flymake-get-line-err-count line-err-info-list "w")))) | |
1831 (list menu-title menu-items) | |
1832 ) | |
1833 ;else | |
1834 nil | |
1835 ) | |
1836 ) | |
1837 ) | |
1838 | |
1839 (defun flymake-goto-file-and-line(file line) | |
1840 "try to get buffer for file and goto line line in it" | |
1841 (if (not (file-exists-p file)) | |
1842 (flymake-log 1 "file %s does not exists" file) | |
1843 ;else | |
1844 (progn | |
1845 (find-file file) | |
1846 (goto-line line) | |
1847 ) | |
1848 ) | |
1849 ) | |
1850 ;; flymake minor mode declarations | |
1851 | |
1852 (defvar flymake-mode nil) | |
1853 (make-variable-buffer-local 'flymake-mode) | |
1854 | |
1855 (defvar flymake-mode-line nil | |
1856 "" | |
1857 ) | |
1858 (make-variable-buffer-local 'flymake-mode-line) | |
1859 (defun flymake-get-buffer-mode-line(buffer) | |
1860 (flymake-get-buffer-var buffer 'flymake-mode-line) | |
1861 ) | |
1862 (defun flymake-set-buffer-mode-line(buffer mode-line-string) | |
1863 (flymake-set-buffer-var buffer 'flymake-mode-line mode-line-string) | |
1864 ) | |
1865 | |
1866 (defvar flymake-mode-line-e-w nil) | |
1867 (make-variable-buffer-local 'flymake-mode-line-e-w) | |
1868 (defun flymake-get-buffer-mode-line-e-w(buffer) | |
1869 (flymake-get-buffer-var buffer 'flymake-mode-line-e-w) | |
1870 ) | |
1871 (defun flymake-set-buffer-mode-line-e-w(buffer e-w) | |
1872 (flymake-set-buffer-var buffer 'flymake-mode-line-e-w e-w) | |
1873 ) | |
1874 | |
1875 (defvar flymake-mode-line-status nil) | |
1876 (make-variable-buffer-local 'flymake-mode-line-status) | |
1877 (defun flymake-get-buffer-mode-line-status(buffer) | |
1878 (flymake-get-buffer-var buffer 'flymake-mode-line-status) | |
1879 ) | |
1880 (defun flymake-set-buffer-mode-line-status(buffer status) | |
1881 (flymake-set-buffer-var buffer 'flymake-mode-line-status status) | |
1882 ) | |
1883 | |
1884 (defun flymake-report-status(buffer e-w &optional status) | |
1885 "show status in the mode line" | |
1886 (when (bufferp buffer) | |
1887 (save-excursion | |
1888 (set-buffer buffer) | |
1889 (when e-w | |
1890 (flymake-set-buffer-mode-line-e-w buffer e-w) | |
1891 ) | |
1892 (when status | |
1893 (flymake-set-buffer-mode-line-status buffer status) | |
1894 ) | |
1895 (let* ((mode-line " Flymake")) | |
1896 (when (> (length (flymake-get-buffer-mode-line-e-w buffer)) 0) | |
1897 (setq mode-line (concat mode-line ":" (flymake-get-buffer-mode-line-e-w buffer))) | |
1898 ) | |
1899 (setq mode-line (concat mode-line (flymake-get-buffer-mode-line-status buffer))) | |
1900 (flymake-set-buffer-mode-line buffer mode-line) | |
1901 (force-mode-line-update) | |
1902 ) | |
1903 ) | |
1904 ) | |
1905 ) | |
1906 | |
1907 (defun flymake-display-warning(warning) | |
1908 "display a warning to the user" | |
1909 (message-box warning) | |
1910 ) | |
1911 | |
1912 (defcustom flymake-gui-warnings-enabled t | |
1913 "enables/disables gui warnings" | |
1914 :group 'flymake | |
1915 :type 'boolean | |
1916 ) | |
1917 | |
1918 (defun flymake-report-fatal-status(buffer status warning) | |
1919 "display a warning and switch flymake mode OFF" | |
1920 (when flymake-gui-warnings-enabled | |
1921 (flymake-display-warning (format "Flymake: %s. Flymake will be switched OFF" warning)) | |
1922 ) | |
1923 (save-excursion | |
1924 (set-buffer buffer) | |
1925 (flymake-mode 0) | |
1926 (flymake-log 0 "switched OFF Flymake mode for buffer %s due to fatal status %s, warning %s" | |
1927 (buffer-name buffer) status warning) | |
1928 ) | |
1929 ) | |
1930 | |
1931 (defun flymake-mode(&optional arg) | |
1932 "toggle flymake-mode" | |
1933 (interactive) | |
57847
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1934 (let ((old-flymake-mode flymake-mode) |
4bac9c04ed9e
2004-11-2 Pavel Kobiakov <pk_at_work@yahoo.com>
Masatake YAMATO <jet@gyve.org>
parents:
57696
diff
changeset
|
1935 (turn-on nil)) |
55822 | 1936 |
1937 (setq turn-on | |
1938 (if (null arg) | |
1939 (not flymake-mode) | |
1940 ;else | |
1941 (> (prefix-numeric-value arg) 0)) | |
1942 ) | |
1943 | |
1944 (if turn-on | |
1945 (if (flymake-can-syntax-check-file (buffer-file-name)) | |
1946 (flymake-mode-on) | |
1947 ;else | |
1948 (flymake-log 2 "flymake cannot check syntax in buffer %s" (buffer-name)) | |
1949 ) | |
1950 ;else | |
1951 (flymake-mode-off) | |
1952 ) | |
1953 (force-mode-line-update) | |
1954 ) | |
1955 ) | |
1956 | |
1957 ;;;###autoload | |
1958 (unless (assq 'flymake-mode minor-mode-alist) | |
1959 (setq minor-mode-alist (cons '(flymake-mode flymake-mode-line) minor-mode-alist)) | |
1960 ) | |
1961 | |
1962 ;;;###autoload | |
1963 (defun flymake-mode-on() | |
1964 "turn flymake mode on" | |
1965 (when (not flymake-mode) | |
1966 (make-local-variable 'after-change-functions) | |
1967 (setq after-change-functions (cons 'flymake-after-change-function after-change-functions)) | |
1968 (add-hook 'after-save-hook 'flymake-after-save-hook) | |
1969 (add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook) | |
1970 ;+(add-hook 'find-file-hooks 'flymake-find-file-hook) | |
1971 | |
1972 (flymake-report-status (current-buffer) "" "") | |
1973 | |
1974 (flymake-set-buffer-timer (current-buffer) (run-at-time nil 1 'flymake-on-timer-event (current-buffer))) | |
1975 | |
1976 (setq flymake-mode t) | |
1977 (flymake-log 1 "flymake mode turned ON for buffer %s" (buffer-name (current-buffer))) | |
1978 (when flymake-start-syntax-check-on-find-file | |
1979 (flymake-start-syntax-check-for-current-buffer) ; will be started by on-load hook | |
1980 ) | |
1981 ) | |
1982 ) | |
1983 | |
1984 ;;;###autoload | |
1985 (defun flymake-mode-off() | |
1986 "turn flymake mode off" | |
1987 (when flymake-mode | |
1988 (setq after-change-functions (delq 'flymake-after-change-function after-change-functions)) | |
1989 (remove-hook 'after-save-hook (function flymake-after-save-hook) t) | |
1990 (remove-hook 'kill-buffer-hook (function flymake-kill-buffer-hook) t) | |
1991 ;+(remove-hook 'find-file-hooks (function flymake-find-file-hook) t) | |
1992 | |
1993 (flymake-delete-own-overlays (current-buffer)) | |
1994 | |
1995 (when (flymake-get-buffer-timer (current-buffer)) | |
1996 (cancel-timer (flymake-get-buffer-timer (current-buffer))) | |
1997 (flymake-set-buffer-timer (current-buffer) nil) | |
1998 ) | |
1999 | |
2000 (flymake-set-buffer-is-running (current-buffer) nil) | |
2001 | |
2002 (setq flymake-mode nil) | |
2003 (flymake-log 1 "flymake mode turned OFF for buffer %s" (buffer-name (current-buffer))) | |
2004 ) | |
2005 ) | |
2006 | |
2007 (defcustom flymake-start-syntax-check-on-newline t | |
2008 "start syntax check if newline char was added/removed from the buffer" | |
2009 :group 'flymake | |
2010 :type 'boolean | |
2011 ) | |
2012 | |
2013 (defun flymake-after-change-function(start stop len) | |
2014 "Start syntax check for current buffer if it isn't already running" | |
2015 ;+(flymake-log 0 "setting change time to %s" (flymake-float-time)) | |
2016 (let((new-text (buffer-substring start stop))) | |
2017 (when (and flymake-start-syntax-check-on-newline (equal new-text "\n")) | |
2018 (flymake-log 3 "starting syntax check as new-line has been seen") | |
2019 (flymake-start-syntax-check-for-current-buffer) | |
2020 ) | |
2021 (flymake-set-buffer-last-change-time (current-buffer) (flymake-float-time)) | |
2022 ) | |
2023 ) | |
2024 | |
2025 (defun flymake-after-save-hook() | |
2026 (if (local-variable-p 'flymake-mode (current-buffer)) ; (???) other way to determine whether flymake is active in buffer being saved? | |
2027 (progn | |
2028 (flymake-log 3 "starting syntax check as buffer was saved") | |
2029 (flymake-start-syntax-check-for-current-buffer) ; no more mode 3. cannot start check if mode 3 (to temp copies) is active - (???) | |
2030 ) | |
2031 ) | |
2032 ) | |
2033 | |
2034 (defun flymake-kill-buffer-hook() | |
2035 (when (flymake-get-buffer-timer (current-buffer)) | |
2036 (cancel-timer (flymake-get-buffer-timer (current-buffer))) | |
2037 (flymake-set-buffer-timer (current-buffer) nil) | |
2038 ) | |
2039 ) | |
2040 | |
2041 (defcustom flymake-start-syntax-check-on-find-file t | |
2042 "statr syntax check on find file" | |
2043 :group 'flymake | |
2044 :type 'boolean | |
2045 ) | |
2046 | |
2047 (defun flymake-find-file-hook() | |
2048 ;+(when flymake-start-syntax-check-on-find-file | |
2049 ;+ (flymake-log 3 "starting syntax check on file open") | |
2050 ;+ (flymake-start-syntax-check-for-current-buffer) | |
2051 ;+) | |
2052 (when (and (not (local-variable-p 'flymake-mode (current-buffer))) | |
2053 (flymake-can-syntax-check-file (buffer-file-name (current-buffer)))) | |
2054 (flymake-mode) | |
2055 (flymake-log 3 "automatically turned ON flymake mode") | |
2056 ) | |
2057 ) | |
2058 | |
2059 (defun flymake-get-first-err-line-no(err-info-list) | |
2060 "return first line-no with error" | |
2061 (when err-info-list | |
2062 (flymake-er-get-line (car err-info-list)) | |
2063 ) | |
2064 ) | |
2065 | |
2066 (defun flymake-get-last-err-line-no(err-info-list) | |
2067 "return last line-no with error" | |
2068 (when err-info-list | |
2069 (flymake-er-get-line (nth (1- (length err-info-list)) err-info-list)) | |
2070 ) | |
2071 ) | |
2072 | |
2073 (defun flymake-get-next-err-line-no(err-info-list line-no) | |
2074 "return next line with erroe" | |
2075 (when err-info-list | |
2076 (let* ((count (length err-info-list)) | |
2077 (idx 0)) | |
2078 (while (and (< idx count) (>= line-no (flymake-er-get-line (nth idx err-info-list)))) | |
2079 (setq idx (1+ idx)) | |
2080 ) | |
2081 (if (< idx count) | |
2082 (flymake-er-get-line (nth idx err-info-list)) | |
2083 ) | |
2084 ) | |
2085 ) | |
2086 ) | |
2087 | |
2088 (defun flymake-get-prev-err-line-no(err-info-list line-no) | |
2089 "return prev line with error" | |
2090 (when err-info-list | |
2091 (let* ((count (length err-info-list))) | |
2092 (while (and (> count 0) (<= line-no (flymake-er-get-line (nth (1- count) err-info-list)))) | |
2093 (setq count (1- count)) | |
2094 ) | |
2095 (if (> count 0) | |
2096 (flymake-er-get-line (nth (1- count) err-info-list)) | |
2097 ) | |
2098 ) | |
2099 ) | |
2100 ) | |
2101 | |
2102 (defun flymake-skip-whitespace() | |
2103 "move forward until nonwhitespace is reached" | |
2104 (while (looking-at "[ \t]") | |
2105 (forward-char) | |
2106 ) | |
2107 ) | |
2108 | |
2109 (defun flymake-goto-line(line-no) | |
2110 "goto-line, then skip whitespace" | |
2111 (goto-line line-no) | |
2112 (flymake-skip-whitespace) | |
2113 ) | |
2114 | |
2115 (defun flymake-goto-next-error() | |
2116 "go to next error in err ring" | |
2117 (interactive) | |
2118 (let ((line-no (flymake-get-next-err-line-no (flymake-get-buffer-err-info (current-buffer)) (flymake-current-line-no)))) | |
2119 (when (not line-no) | |
2120 (setq line-no (flymake-get-first-err-line-no (flymake-get-buffer-err-info (current-buffer)))) | |
2121 (flymake-log 1 "passed end of file") | |
2122 ) | |
2123 (if line-no | |
2124 (flymake-goto-line line-no) | |
2125 ;else | |
2126 (flymake-log 1 "no errors in current buffer") | |
2127 ) | |
2128 ) | |
2129 ) | |
2130 | |
2131 (defun flymake-goto-prev-error() | |
2132 "go to prev error in err ring" | |
2133 (interactive) | |
2134 (let ((line-no (flymake-get-prev-err-line-no (flymake-get-buffer-err-info (current-buffer)) (flymake-current-line-no)))) | |
2135 (when (not line-no) | |
2136 (setq line-no (flymake-get-last-err-line-no (flymake-get-buffer-err-info (current-buffer)))) | |
2137 (flymake-log 1 "passed beginning of file") | |
2138 ) | |
2139 (if line-no | |
2140 (flymake-goto-line line-no) | |
2141 ;else | |
2142 (flymake-log 1 "no errors in current buffer") | |
2143 ) | |
2144 ) | |
2145 ) | |
2146 | |
2147 (defun flymake-patch-err-text(string) | |
2148 (if (string-match "^[\n\t :0-9]*\\(.*\\)$" string) | |
2149 (match-string 1 string) | |
2150 ;else | |
2151 string | |
2152 ) | |
2153 ) | |
2154 | |
2155 ;;;; general init-cleanup and helper routines | |
2156 | |
2157 (defun flymake-create-temp-inplace(file-name prefix) | |
2158 (unless (stringp file-name) | |
2159 (error "invalid file-name") | |
2160 ) | |
2161 (or prefix | |
2162 (setq prefix "flymake") | |
2163 ) | |
2164 (let* ((temp-name (concat (file-name-sans-extension file-name) | |
2165 "_" prefix | |
2166 (and (file-name-extension file-name) | |
2167 (concat "." (file-name-extension file-name)))))) | |
2168 (flymake-log 3 "create-temp-inplace: file=%s temp=%s" file-name temp-name) | |
2169 temp-name | |
2170 ) | |
2171 ) | |
2172 | |
2173 (defun flymake-create-temp-with-folder-structure(file-name prefix) | |
2174 (unless (stringp file-name) | |
2175 (error "invalid file-name") | |
2176 ) | |
2177 | |
2178 (let* ((dir (file-name-directory file-name)) | |
2179 (slash-pos (string-match "/" dir)) | |
2180 (temp-dir (concat (flymake-ensure-ends-with-slash (flymake-get-temp-dir)) (substring dir (1+ slash-pos))))) | |
2181 | |
2182 (file-truename (concat (flymake-ensure-ends-with-slash temp-dir) | |
2183 (file-name-nondirectory file-name))) | |
2184 ) | |
2185 ) | |
2186 | |
2187 (defun flymake-strrchr(str ch) | |
2188 (let* ((count (length str)) | |
2189 (pos nil)) | |
2190 (while (and (not pos) (> count 0)) | |
2191 (if (= ch (elt str (1- count))) | |
2192 (setq pos (1- count)) | |
2193 ) | |
2194 (setq count (1- count)) | |
2195 ) | |
2196 pos | |
2197 ) | |
2198 ) | |
2199 | |
2200 (defun flymake-delete-temp-directory(dir-name) | |
2201 "attempt to delete temp dir created by flymake-create-temp-with-folder-structure, do not fail on error" | |
2202 (let* ((temp-dir (flymake-get-temp-dir)) | |
2203 (suffix (substring dir-name (1+ (length temp-dir)))) | |
2204 (slash-pos nil)) | |
2205 | |
2206 (while (> (length suffix) 0) | |
2207 ;+(flymake-log 0 "suffix=%s" suffix) | |
2208 (flymake-safe-delete-directory (file-truename (concat (flymake-ensure-ends-with-slash temp-dir) suffix))) | |
2209 (setq slash-pos (flymake-strrchr suffix (string-to-char "/"))) | |
2210 (if slash-pos | |
2211 (setq suffix (substring suffix 0 slash-pos)) | |
2212 ;else | |
2213 (setq suffix "") | |
2214 ) | |
2215 ) | |
2216 ) | |
2217 ) | |
2218 | |
2219 (defun flymake-init-create-temp-buffer-copy(buffer create-temp-f) | |
2220 "make a temporary copy of the current buffer, save its name in buffer data and return the name" | |
2221 (let* ((source-file-name (buffer-file-name buffer)) | |
2222 (temp-source-file-name (funcall create-temp-f source-file-name "flymake"))) | |
2223 | |
2224 (flymake-save-buffer-in-file buffer temp-source-file-name) | |
2225 (flymake-set-buffer-value buffer "temp-source-file-name" temp-source-file-name) | |
2226 | |
2227 temp-source-file-name | |
2228 ) | |
2229 ) | |
2230 | |
2231 (defun flymake-simple-cleanup(buffer) | |
2232 "cleanup after flymake-init-create-temp-buffer-copy -- delete temp file" | |
2233 (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name"))) | |
2234 (flymake-safe-delete-file temp-source-file-name) | |
2235 (flymake-set-buffer-last-change-time buffer nil) | |
2236 ) | |
2237 ) | |
2238 | |
2239 (defun flymake-get-real-file-name(buffer file-name-from-err-msg) | |
2240 "Translate file name from error message to `real' file name. Return full-name. Names are real, not patched" | |
2241 (let* ((real-name nil) | |
2242 (source-file-name (buffer-file-name buffer)) | |
2243 (master-file-name (flymake-get-buffer-value buffer "master-file-name")) | |
2244 (temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name")) | |
2245 (temp-master-file-name (flymake-get-buffer-value buffer "temp-master-file-name")) | |
2246 (base-dirs (list (flymake-get-buffer-value buffer "base-dir") | |
2247 (file-name-directory source-file-name) | |
2248 (if master-file-name (file-name-directory master-file-name) nil))) | |
2249 (files (list (list source-file-name source-file-name) | |
2250 (list temp-source-file-name source-file-name) | |
2251 (list master-file-name master-file-name) | |
2252 (list temp-master-file-name master-file-name)))) | |
2253 | |
2254 (when (equal 0 (length file-name-from-err-msg)) | |
2255 (setq file-name-from-err-msg source-file-name) | |
2256 ) | |
2257 | |
2258 (setq real-name (flymake-get-full-patched-file-name file-name-from-err-msg base-dirs files)) | |
2259 ; if real-name is nil, than file name from err msg is none of the files we've patched | |
2260 (if (not real-name) | |
2261 (setq real-name (flymake-get-full-nonpatched-file-name file-name-from-err-msg base-dirs)) | |
2262 ) | |
2263 (if (not real-name) | |
2264 (setq real-name file-name-from-err-msg) | |
2265 ) | |
2266 (setq real-name (flymake-fix-path-name real-name)) | |
2267 (flymake-log 3 "get-real-file-name: file-name=%s real-name=%s" file-name-from-err-msg real-name) | |
2268 real-name | |
2269 ) | |
2270 ) | |
2271 | |
2272 (defun flymake-get-full-patched-file-name(file-name-from-err-msg base-dirs files) | |
2273 (let* ((base-dirs-count (length base-dirs)) | |
2274 (file-count (length files)) | |
2275 (real-name nil)) | |
2276 | |
2277 (while (and (not real-name) (> base-dirs-count 0)) | |
2278 (setq file-count (length files)) | |
2279 (while (and (not real-name) (> file-count 0)) | |
2280 (let* ((this-dir (nth (1- base-dirs-count) base-dirs)) | |
2281 (this-file (nth 0 (nth (1- file-count) files))) | |
2282 (this-real-name (nth 1 (nth (1- file-count) files)))) | |
2283 ;+(flymake-log 0 "this-dir=%s this-file=%s this-real=%s msg-file=%s" this-dir this-file this-real-name file-name-from-err-msg) | |
2284 (when (and this-dir this-file (flymake-same-files | |
2285 (flymake-get-absolute-file-name-basedir file-name-from-err-msg this-dir) | |
2286 this-file)) | |
2287 (setq real-name this-real-name) | |
2288 ) | |
2289 ) | |
2290 (setq file-count (1- file-count)) | |
2291 ) | |
2292 (setq base-dirs-count (1- base-dirs-count)) | |
2293 ) | |
2294 real-name | |
2295 ) | |
2296 ) | |
2297 | |
2298 (defun flymake-get-full-nonpatched-file-name(file-name-from-err-msg base-dirs) | |
2299 (let* ((real-name nil)) | |
2300 (if (file-name-absolute-p file-name-from-err-msg) | |
2301 (setq real-name file-name-from-err-msg) | |
2302 ;else | |
2303 (let* ((base-dirs-count (length base-dirs))) | |
2304 (while (and (not real-name) (> base-dirs-count 0)) | |
2305 (let* ((full-name (flymake-get-absolute-file-name-basedir file-name-from-err-msg | |
2306 (nth (1- base-dirs-count) base-dirs)))) | |
2307 (if (file-exists-p full-name) | |
2308 (setq real-name full-name) | |
2309 ) | |
2310 (setq base-dirs-count (1- base-dirs-count)) | |
2311 ) | |
2312 ) | |
2313 ) | |
2314 ) | |
2315 real-name | |
2316 ) | |
2317 ) | |
2318 | |
2319 (defun flymake-get-absolute-file-name-basedir(file-name dir-name) | |
2320 (if (file-name-absolute-p file-name) | |
2321 file-name | |
2322 ;else | |
2323 (concat dir-name "/" file-name) | |
2324 ) | |
2325 ) | |
2326 | |
2327 (defun flymake-init-find-buildfile-dir(buffer source-file-name buildfile-name) | |
2328 "find buildfile, store its dir in buffer data and return its dir, if found" | |
2329 (let* ((buildfile-dir (flymake-find-buildfile buildfile-name | |
2330 (file-name-directory source-file-name) | |
2331 flymake-buildfile-dirs))) | |
2332 (if (not buildfile-dir) | |
2333 (progn | |
2334 (flymake-log 1 "no buildfile (%s) for %s" buildfile-name source-file-name) | |
2335 (flymake-report-fatal-status buffer "NOMK" (format "No buildfile (%s) found for %s" buildfile-name source-file-name)) | |
2336 ) | |
2337 ;else | |
2338 (progn | |
2339 (flymake-set-buffer-value buffer "base-dir" buildfile-dir) | |
2340 ) | |
2341 ) | |
2342 buildfile-dir | |
2343 ) | |
2344 ) | |
2345 | |
2346 (defun flymake-init-create-temp-source-and-master-buffer-copy(buffer get-incl-dirs-f create-temp-f master-file-masks include-regexp-list) | |
2347 "find master file (or buffer), create it's copy along with a copy of the source file" | |
2348 (let* ((source-file-name (buffer-file-name buffer)) | |
2349 (temp-source-file-name (flymake-init-create-temp-buffer-copy buffer create-temp-f)) | |
2350 (master-file-name nil) | |
2351 (temp-master-file-name nil) | |
2352 (master-and-temp-master (flymake-create-master-file | |
2353 source-file-name temp-source-file-name | |
2354 get-incl-dirs-f create-temp-f | |
2355 master-file-masks include-regexp-list))) | |
2356 | |
2357 (if (not master-and-temp-master) | |
2358 (progn | |
2359 (flymake-log 1 "cannot find master file for %s" source-file-name) | |
2360 (flymake-report-status buffer "!" "") ; NOMASTER | |
2361 ) | |
2362 ;else | |
2363 (progn | |
2364 (setq master-file-name (nth 0 master-and-temp-master)) | |
2365 (setq temp-master-file-name (nth 1 master-and-temp-master)) | |
2366 (flymake-set-buffer-value buffer "master-file-name" master-file-name) | |
2367 (flymake-set-buffer-value buffer "temp-master-file-name" temp-master-file-name) | |
2368 ) | |
2369 ) | |
2370 temp-master-file-name | |
2371 ) | |
2372 ) | |
2373 | |
2374 (defun flymake-master-cleanup(buffer) | |
2375 (flymake-simple-cleanup buffer) | |
2376 (flymake-safe-delete-file (flymake-get-buffer-value buffer "temp-master-file-name")) | |
2377 ) | |
2378 | |
2379 ;;;; make-specific init-cleanup routines | |
2380 | |
2381 (defun flymake-get-syntax-check-program-args(source-file-name base-dir use-relative-base-dir use-relative-source get-cmd-line-f) | |
2382 "create a command line for the syntax check command, using get-cmd-line-f" | |
2383 (let* ((my-base-dir base-dir) | |
2384 (my-source source-file-name)) | |
2385 | |
2386 (when use-relative-base-dir | |
2387 (setq my-base-dir (flymake-build-relative-path (file-name-directory source-file-name) base-dir)) | |
2388 ) | |
2389 | |
2390 (when use-relative-source | |
2391 (setq my-source (concat (flymake-build-relative-path base-dir (file-name-directory source-file-name)) | |
2392 (file-name-nondirectory source-file-name))) | |
2393 ) | |
2394 | |
2395 (funcall get-cmd-line-f my-source my-base-dir) | |
2396 ) | |
2397 ) | |
2398 | |
2399 (defun flymake-get-make-cmdline(source base-dir) | |
2400 (list "make" | |
2401 (list "-s" | |
2402 "-C" | |
2403 base-dir | |
2404 (concat "CHK_SOURCES=" source) | |
2405 "SYNTAX_CHECK_MODE=1" | |
2406 "check-syntax")) | |
2407 ) | |
2408 | |
2409 (defun flymake-get-ant-cmdline(source base-dir) | |
2410 (list "ant" | |
2411 (list "-buildfile" | |
2412 (concat base-dir "/" "build.xml") | |
2413 (concat "-DCHK_SOURCES=" source) | |
2414 "check-syntax")) | |
2415 ) | |
2416 | |
2417 (defun flymake-simple-make-init-impl(buffer create-temp-f use-relative-base-dir use-relative-source build-file-name get-cmdline-f) | |
2418 "create syntax check command line for a directly checked source file, use create-temp-f for creating temp copy" | |
2419 (let* ((args nil) | |
2420 (source-file-name (buffer-file-name buffer)) | |
2421 (buildfile-dir (flymake-init-find-buildfile-dir buffer source-file-name build-file-name))) | |
2422 (if buildfile-dir | |
2423 (let* ((temp-source-file-name (flymake-init-create-temp-buffer-copy buffer create-temp-f))) | |
2424 (setq args (flymake-get-syntax-check-program-args temp-source-file-name buildfile-dir | |
2425 use-relative-base-dir use-relative-source | |
2426 get-cmdline-f)) | |
2427 ) | |
2428 ) | |
2429 | |
2430 args | |
2431 ) | |
2432 ) | |
2433 | |
2434 (defun flymake-simple-make-init(buffer) | |
2435 (flymake-simple-make-init-impl buffer 'flymake-create-temp-inplace t t "Makefile" 'flymake-get-make-cmdline) | |
2436 ) | |
2437 | |
2438 (defun flymake-master-make-init(buffer get-incl-dirs-f master-file-masks include-regexp-list) | |
2439 "create make command line for a source file checked via master file compilation" | |
2440 (let* ((make-args nil) | |
2441 (temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy | |
2442 buffer get-incl-dirs-f 'flymake-create-temp-inplace | |
2443 master-file-masks include-regexp-list))) | |
2444 (when temp-master-file-name | |
2445 (let* ((buildfile-dir (flymake-init-find-buildfile-dir buffer temp-master-file-name "Makefile"))) | |
2446 (if buildfile-dir | |
2447 (setq make-args (flymake-get-syntax-check-program-args | |
2448 temp-master-file-name buildfile-dir nil nil 'flymake-get-make-cmdline)) | |
2449 ) | |
2450 ) | |
2451 ) | |
2452 | |
2453 make-args | |
2454 ) | |
2455 ) | |
2456 | |
2457 (defun flymake-find-make-buildfile(source-dir) | |
2458 (flymake-find-buildfile "Makefile" source-dir flymake-buildfile-dirs) | |
2459 ) | |
2460 | |
2461 ;;;; .h/make specific | |
2462 (defun flymake-master-make-header-init(buffer) | |
2463 (flymake-master-make-init buffer | |
2464 'flymake-get-include-dirs | |
2465 '(".+\\.cpp$" ".+\\.c$") | |
2466 '("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2)) | |
2467 ) | |
2468 | |
2469 ;;;; .java/make specific | |
2470 (defun flymake-simple-make-java-init(buffer) | |
2471 (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "Makefile" 'flymake-get-make-cmdline) | |
2472 ) | |
2473 | |
2474 (defun flymake-simple-ant-java-init(buffer) | |
2475 (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "build.xml" 'flymake-get-ant-cmdline) | |
2476 ) | |
2477 | |
2478 (defun flymake-simple-java-cleanup(buffer) | |
2479 "cleanup after flymake-simple-make-java-init -- delete temp file and dirs" | |
2480 (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name"))) | |
2481 (flymake-safe-delete-file temp-source-file-name) | |
2482 (when temp-source-file-name | |
2483 (flymake-delete-temp-directory (file-name-directory temp-source-file-name)) | |
2484 ) | |
2485 ) | |
2486 ) | |
2487 | |
2488 ;;;; perl-specific init-cleanup routines | |
2489 | |
2490 (defun flymake-perl-init(buffer) | |
2491 (let* ((temp-file (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace)) | |
2492 (local-file (concat (flymake-build-relative-path (file-name-directory (buffer-file-name (current-buffer))) | |
2493 (file-name-directory temp-file)) | |
2494 (file-name-nondirectory temp-file)))) | |
2495 (list "perl" (list "-wc " local-file)) | |
2496 ) | |
2497 ) | |
2498 | |
2499 ;;;; tex-specific init-cleanup routines | |
2500 | |
2501 (defun flymake-get-tex-args(file-name) | |
2502 ;(list "latex" (list "-c-style-errors" file-name)) | |
2503 (list "texify" (list "--pdf" "--tex-option=-c-style-errors" file-name)) | |
2504 ) | |
2505 | |
2506 (defun flymake-simple-tex-init(buffer) | |
2507 (flymake-get-tex-args (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace)) | |
2508 ) | |
2509 | |
2510 (defun flymake-master-tex-init(buffer) | |
2511 (let* ((temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy | |
2512 buffer 'flymake-get-include-dirs-dot 'flymake-create-temp-inplace | |
2513 '(".+\\.tex$") | |
2514 '("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2)))) | |
2515 (when temp-master-file-name | |
2516 (flymake-get-tex-args temp-master-file-name) | |
2517 ) | |
2518 ) | |
2519 ) | |
2520 | |
2521 (defun flymake-get-include-dirs-dot(base-dir) | |
2522 '(".") | |
2523 ) | |
2524 | |
2525 ;;;; xml-specific init-cleanup routines | |
2526 | |
2527 (defun flymake-xml-init(buffer) | |
2528 (list "xml" (list "val" (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace))) | |
2529 ) | |
2530 | |
55843
26e0724718e2
Changes from arch/CVS synchronization
Miles Bader <miles@gnu.org>
parents:
55822
diff
changeset
|
2531 ;;; arch-tag: 8f0d6090-061d-4cac-8862-7c151c4a02dd |
55822 | 2532 ;;; flymake.el ends here |