aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2017-09-21 14:44:13 +0100
committerJoão Távora2017-10-03 13:52:24 +0100
commit54beebb4e0d919c7ee6dcdd7d774d851c35f85b7 (patch)
tree183a1dc5f749e96ceb4d5d3833b6208dc6cff63e
parent491cc4a1bd68c2f651027982e3dfb7545d3e57ab (diff)
downloademacs-54beebb4e0d919c7ee6dcdd7d774d851c35f85b7.tar.gz
emacs-54beebb4e0d919c7ee6dcdd7d774d851c35f85b7.zip
Flymake highlights GCC info/notes as detected by flymake-proc.el
* lisp/progmodes/flymake-proc.el (flymake-proc--diagnostics-for-pattern): Rewrite (using cl-loop) to honour more sophisticated flymake-proc-diagnostic-type-pred. (flymake-warning-re): Is now an obsolete alias for flymake-proc-diagnostic-type-pred. (flymake-proc-diagnostic-type-pred): Rename and augment from flymake-proc-warning-predicate. (flymake-proc-warning-predicate): Delete. * lisp/progmodes/flymake.el (flymake-note): New face. (flymake-diagnostic-types-alist): Simplify. (flymake-note): New overlay category. (flymake--lookup-type-property): Only lookup single keys, not lists. (flymake--diag-errorp): Rewrite. (flymake--highlight-line): Use flymake--lookup-type-property. * test/lisp/progmodes/flymake-tests.el (different-diagnostic-types): Rename from errors-and-warnings. Check notes. (flymake-tests--call-with-fixture): Use flymake-proc-diagnostic-type-pred.
-rw-r--r--lisp/progmodes/flymake-proc.el121
-rw-r--r--lisp/progmodes/flymake.el32
-rw-r--r--test/lisp/progmodes/flymake-tests.el8
3 files changed, 90 insertions, 71 deletions
diff --git a/lisp/progmodes/flymake-proc.el b/lisp/progmodes/flymake-proc.el
index dd6bf501733..2e593bd758d 100644
--- a/lisp/progmodes/flymake-proc.el
+++ b/lisp/progmodes/flymake-proc.el
@@ -394,47 +394,51 @@ Create parent directories as needed."
394 (flymake-log 3 "saved buffer %s in file %s" (buffer-name) file-name)) 394 (flymake-log 3 "saved buffer %s in file %s" (buffer-name) file-name))
395 395
396(defun flymake-proc--diagnostics-for-pattern (proc pattern) 396(defun flymake-proc--diagnostics-for-pattern (proc pattern)
397 (condition-case err 397 (cl-flet ((guess-type
398 (pcase-let ((`(,regexp ,file-idx ,line-idx ,col-idx ,message-idx) 398 (pred message)
399 pattern) 399 (cond ((null message)
400 (retval)) 400 :error)
401 (while (search-forward-regexp regexp nil t) 401 ((stringp pred)
402 (let* ((fname (and file-idx (match-string file-idx))) 402 (if (string-match pred message)
403 (message (and message-idx (match-string message-idx))) 403 :warning
404 (line-string (and line-idx (match-string line-idx))) 404 :error))
405 (line-number (and line-string 405 ((functionp pred)
406 (string-to-number line-string))) 406 (let ((probe (funcall pred message)))
407 (col-string (and col-idx (match-string col-idx))) 407 (cond ((assoc-default probe
408 (col-number (and col-string 408 flymake-diagnostic-types-alist)
409 (string-to-number col-string)))) 409 probe)
410 (with-current-buffer (process-buffer proc) 410 (probe
411 (push 411 :warning)
412 (flymake-make-diagnostic 412 (t
413 :file fname 413 :error)))))))
414 :line line-number 414 (condition-case err
415 :col col-number 415 (cl-loop
416 :type (if (and 416 with (regexp file-idx line-idx col-idx message-idx) = pattern
417 message 417 while (search-forward-regexp regexp nil t)
418 (cond ((stringp flymake-proc-warning-predicate) 418 for fname = (and file-idx (match-string file-idx))
419 (string-match flymake-proc-warning-predicate 419 for message = (and message-idx (match-string message-idx))
420 message)) 420 for line-string = (and line-idx (match-string line-idx))
421 ((functionp flymake-proc-warning-predicate) 421 for line-number = (and line-string
422 (funcall flymake-proc-warning-predicate 422 (string-to-number line-string))
423 message)))) 423 for col-string = (and col-idx (match-string col-idx))
424 "w" 424 for col-number = (and col-string
425 "e") 425 (string-to-number col-string))
426 :text message 426 collect (with-current-buffer (process-buffer proc)
427 :full-file (and fname 427 (flymake-make-diagnostic
428 (funcall 428 :file fname
429 (flymake-proc--get-real-file-name-function 429 :line line-number
430 fname) 430 :col col-number
431 fname))) 431 :type (guess-type flymake-proc-diagnostic-type-pred message)
432 retval)))) 432 :text message
433 retval) 433 :full-file (and fname
434 (error 434 (funcall
435 (flymake-log 1 "Error parsing process output for pattern %s: %s" 435 (flymake-proc--get-real-file-name-function
436 pattern err) 436 fname)
437 nil))) 437 fname)))))
438 (error
439 (flymake-log 1 "Error parsing process output for pattern %s: %s"
440 pattern err)
441 nil))))
438 442
439(defun flymake-proc--process-filter (proc string) 443(defun flymake-proc--process-filter (proc string)
440 "Parse STRING and collect diagnostics info." 444 "Parse STRING and collect diagnostics info."
@@ -567,12 +571,29 @@ Convert it to flymake internal format."
567Use `flymake-proc-reformat-err-line-patterns-from-compile-el' to add patterns 571Use `flymake-proc-reformat-err-line-patterns-from-compile-el' to add patterns
568from compile.el") 572from compile.el")
569 573
570(define-obsolete-variable-alias 'flymake-warning-re 'flymake-proc-warning-predicate "24.4") 574(define-obsolete-variable-alias 'flymake-warning-re 'flymake-proc-diagnostic-type-pred "26.1")
571(defvar flymake-proc-warning-predicate "^[wW]arning" 575(defvar flymake-proc-diagnostic-type-pred
572 "Predicate matching against error text to detect a warning. 576 'flymake-proc-default-guess
573Takes a single argument, the error's text and should return non-nil 577 "Predicate matching against diagnostic text to detect its type.
574if it's a warning. 578Takes a single argument, the diagnostic's text and should return
575Instead of a function, it can also be a regular expression.") 579a value suitable for indexing
580`flymake-diagnostic-types-alist' (which see). If the returned
581value is nil, a type of `error' is assumed. For some backward
582compatibility, if a non-nil value is returned that that doesn't
583index that alist, a type of `:warning' is assumed.
584
585Instead of a function, it can also be a string, a regular
586expression. A match indicates `:warning' type, otherwise
587`:error'")
588
589(defun flymake-proc-default-guess (text)
590 "Guess if TEXT means a warning, a note or an error."
591 (cond ((string-match "^[wW]arning" text)
592 :warning)
593 ((string-match "^[nN]ote" text)
594 :note)
595 (t
596 :error)))
576 597
577(defun flymake-proc-get-project-include-dirs-imp (basedir) 598(defun flymake-proc-get-project-include-dirs-imp (basedir)
578 "Include dirs for the project current file belongs to." 599 "Include dirs for the project current file belongs to."
@@ -1167,12 +1188,6 @@ Convert it to flymake internal format.")
1167(REGEXP FILE-IDX LINE-IDX COL-IDX ERR-TEXT-IDX). 1188(REGEXP FILE-IDX LINE-IDX COL-IDX ERR-TEXT-IDX).
1168Use `flymake-reformat-err-line-patterns-from-compile-el' to add patterns 1189Use `flymake-reformat-err-line-patterns-from-compile-el' to add patterns
1169from compile.el") 1190from compile.el")
1170 (define-obsolete-variable-alias 'flymake-warning-predicate
1171 'flymake-proc-warning-predicate "26.1"
1172 "Predicate matching against error text to detect a warning.
1173Takes a single argument, the error's text and should return non-nil
1174if it's a warning.
1175Instead of a function, it can also be a regular expression.")
1176 (define-obsolete-function-alias 'flymake-parse-line 1191 (define-obsolete-function-alias 'flymake-parse-line
1177 'flymake-proc-parse-line "26.1" 1192 'flymake-proc-parse-line "26.1"
1178 "Parse LINE to see if it is an error or warning. 1193 "Parse LINE to see if it is an error or warning.
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 827bce4b634..b32e799e672 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -189,6 +189,15 @@ verify FILTER, sort them by COMPARE (using KEY)."
189 :version "24.4" 189 :version "24.4"
190 :group 'flymake) 190 :group 'flymake)
191 191
192(defface flymake-note
193 '((((supports :underline (:style wave)))
194 :underline (:style wave :color "yellow green"))
195 (t
196 :inherit warning))
197 "Face used for marking note regions."
198 :version "26.1"
199 :group 'flymake)
200
192(define-obsolete-face-alias 'flymake-warnline 'flymake-warning "26.1") 201(define-obsolete-face-alias 'flymake-warnline 'flymake-warning "26.1")
193(define-obsolete-face-alias 'flymake-errline 'flymake-error "26.1") 202(define-obsolete-face-alias 'flymake-errline 'flymake-error "26.1")
194 203
@@ -226,13 +235,14 @@ Or nil if the region is invalid."
226 nil))) 235 nil)))
227 236
228(defvar flymake-diagnostic-types-alist 237(defvar flymake-diagnostic-types-alist
229 `((("e" :error error) 238 `((:error
230 . ((flymake-category . flymake-error))) 239 . ((flymake-category . flymake-error)))
231 (("w" :warning warning) 240 (:warning
232 . ((flymake-category . flymake-warning)))) 241 . ((flymake-category . flymake-warning)))
242 (:note
243 . ((flymake-category . flymake-note))))
233 "Alist ((KEY . PROPS)*) of properties of flymake error types. 244 "Alist ((KEY . PROPS)*) of properties of flymake error types.
234KEY can be anything passed as `:type' to `flymake-diag-make', or 245KEY can be anything passed as `:type' to `flymake-diag-make'.
235a list of these objects.
236 246
237PROPS is an alist of properties that are applied, in order, to 247PROPS is an alist of properties that are applied, in order, to
238the diagnostics of each type. The recognized properties are: 248the diagnostics of each type. The recognized properties are:
@@ -259,27 +269,21 @@ the diagnostics of each type. The recognized properties are:
259(put 'flymake-error 'face 'flymake-error) 269(put 'flymake-error 'face 'flymake-error)
260(put 'flymake-error 'bitmap flymake-error-bitmap) 270(put 'flymake-error 'bitmap flymake-error-bitmap)
261(put 'flymake-error 'severity (warning-numeric-level :error)) 271(put 'flymake-error 'severity (warning-numeric-level :error))
262(put 'flymake-error 'mode-line-face 'compilation-error)
263 272
264(put 'flymake-warning 'face 'flymake-warning) 273(put 'flymake-warning 'face 'flymake-warning)
265(put 'flymake-warning 'bitmap flymake-warning-bitmap) 274(put 'flymake-warning 'bitmap flymake-warning-bitmap)
266(put 'flymake-warning 'severity (warning-numeric-level :warning)) 275(put 'flymake-warning 'severity (warning-numeric-level :warning))
267(put 'flymake-warning 'mode-line-face 'compilation-warning)
268 276
269(put 'flymake-note 'face 'flymake-note) 277(put 'flymake-note 'face 'flymake-note)
270(put 'flymake-note 'bitmap flymake-warning-bitmap) 278(put 'flymake-note 'bitmap flymake-warning-bitmap)
271(put 'flymake-note 'severity (warning-numeric-level :debug)) 279(put 'flymake-note 'severity (warning-numeric-level :debug))
272(put 'flymake-note 'mode-line-face 'compilation-info)
273 280
274(defun flymake--lookup-type-property (type prop &optional default) 281(defun flymake--lookup-type-property (type prop &optional default)
275 "Look up PROP for TYPE in `flymake-diagnostic-types-alist'. 282 "Look up PROP for TYPE in `flymake-diagnostic-types-alist'.
276If TYPE doesn't declare PROP in either 283If TYPE doesn't declare PROP in either
277`flymake-diagnostic-types-alist' or its associated category, 284`flymake-diagnostic-types-alist' or its associated
278return DEFAULT." 285`flymake-category', return DEFAULT."
279 (let ((alist-probe (assoc type flymake-diagnostic-types-alist 286 (let ((alist-probe (assoc type flymake-diagnostic-types-alist)))
280 (lambda (entry key)
281 (or (equal key entry)
282 (member key entry))))))
283 (cond (alist-probe 287 (cond (alist-probe
284 (let* ((alist (cdr alist-probe)) 288 (let* ((alist (cdr alist-probe))
285 (prop-probe (assoc prop alist))) 289 (prop-probe (assoc prop alist)))
diff --git a/test/lisp/progmodes/flymake-tests.el b/test/lisp/progmodes/flymake-tests.el
index 5e76f3136ea..5ecc87fc7e6 100644
--- a/test/lisp/progmodes/flymake-tests.el
+++ b/test/lisp/progmodes/flymake-tests.el
@@ -41,7 +41,7 @@
41 nil sev-pred-supplied-p)) 41 nil sev-pred-supplied-p))
42 "Call FN after flymake setup in FILE, using `flymake-proc`. 42 "Call FN after flymake setup in FILE, using `flymake-proc`.
43SEVERITY-PREDICATE is used to setup 43SEVERITY-PREDICATE is used to setup
44`flymake-proc-warning-predicate'." 44`flymake-proc-diagnostic-type-pred'"
45 (let* ((file (expand-file-name file flymake-tests-data-directory)) 45 (let* ((file (expand-file-name file flymake-tests-data-directory))
46 (visiting (find-buffer-visiting file)) 46 (visiting (find-buffer-visiting file))
47 (buffer (or visiting (find-file-noselect file))) 47 (buffer (or visiting (find-file-noselect file)))
@@ -51,7 +51,7 @@ SEVERITY-PREDICATE is used to setup
51 (with-current-buffer buffer 51 (with-current-buffer buffer
52 (save-excursion 52 (save-excursion
53 (when sev-pred-supplied-p 53 (when sev-pred-supplied-p
54 (setq-local flymake-proc-warning-predicate severity-predicate)) 54 (setq-local flymake-proc-diagnostic-type-pred severity-predicate))
55 (goto-char (point-min)) 55 (goto-char (point-min))
56 (flymake-mode 1) 56 (flymake-mode 1)
57 ;; Weirdness here... http://debbugs.gnu.org/17647#25 57 ;; Weirdness here... http://debbugs.gnu.org/17647#25
@@ -115,13 +115,13 @@ SEVERITY-PREDICATE is used to setup
115 (should (eq 'flymake-warning 115 (should (eq 'flymake-warning
116 (face-at-point))))) 116 (face-at-point)))))
117 117
118(ert-deftest errors-and-warnings () 118(ert-deftest different-diagnostic-types ()
119 "Test GCC warning via function predicate." 119 "Test GCC warning via function predicate."
120 (skip-unless (and (executable-find "gcc") (executable-find "make"))) 120 (skip-unless (and (executable-find "gcc") (executable-find "make")))
121 (flymake-tests--with-flymake 121 (flymake-tests--with-flymake
122 ("errors-and-warnings.c") 122 ("errors-and-warnings.c")
123 (flymake-goto-next-error) 123 (flymake-goto-next-error)
124 (should (eq 'flymake-error (face-at-point))) 124 (should (eq 'flymake-note (face-at-point)))
125 (flymake-goto-next-error) 125 (flymake-goto-next-error)
126 (should (eq 'flymake-warning (face-at-point))) 126 (should (eq 'flymake-warning (face-at-point)))
127 (flymake-goto-next-error) 127 (flymake-goto-next-error)