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.
This commit is contained in:
João Távora
2017-09-21 14:44:13 +01:00
parent 491cc4a1bd
commit 54beebb4e0
3 changed files with 90 additions and 71 deletions

View File

@@ -394,47 +394,51 @@ Create parent directories as needed."
(flymake-log 3 "saved buffer %s in file %s" (buffer-name) file-name))
(defun flymake-proc--diagnostics-for-pattern (proc pattern)
(condition-case err
(pcase-let ((`(,regexp ,file-idx ,line-idx ,col-idx ,message-idx)
pattern)
(retval))
(while (search-forward-regexp regexp nil t)
(let* ((fname (and file-idx (match-string file-idx)))
(message (and message-idx (match-string message-idx)))
(line-string (and line-idx (match-string line-idx)))
(line-number (and line-string
(string-to-number line-string)))
(col-string (and col-idx (match-string col-idx)))
(col-number (and col-string
(string-to-number col-string))))
(with-current-buffer (process-buffer proc)
(push
(flymake-make-diagnostic
:file fname
:line line-number
:col col-number
:type (if (and
message
(cond ((stringp flymake-proc-warning-predicate)
(string-match flymake-proc-warning-predicate
message))
((functionp flymake-proc-warning-predicate)
(funcall flymake-proc-warning-predicate
message))))
"w"
"e")
:text message
:full-file (and fname
(funcall
(flymake-proc--get-real-file-name-function
fname)
fname)))
retval))))
retval)
(error
(flymake-log 1 "Error parsing process output for pattern %s: %s"
pattern err)
nil)))
(cl-flet ((guess-type
(pred message)
(cond ((null message)
:error)
((stringp pred)
(if (string-match pred message)
:warning
:error))
((functionp pred)
(let ((probe (funcall pred message)))
(cond ((assoc-default probe
flymake-diagnostic-types-alist)
probe)
(probe
:warning)
(t
:error)))))))
(condition-case err
(cl-loop
with (regexp file-idx line-idx col-idx message-idx) = pattern
while (search-forward-regexp regexp nil t)
for fname = (and file-idx (match-string file-idx))
for message = (and message-idx (match-string message-idx))
for line-string = (and line-idx (match-string line-idx))
for line-number = (and line-string
(string-to-number line-string))
for col-string = (and col-idx (match-string col-idx))
for col-number = (and col-string
(string-to-number col-string))
collect (with-current-buffer (process-buffer proc)
(flymake-make-diagnostic
:file fname
:line line-number
:col col-number
:type (guess-type flymake-proc-diagnostic-type-pred message)
:text message
:full-file (and fname
(funcall
(flymake-proc--get-real-file-name-function
fname)
fname)))))
(error
(flymake-log 1 "Error parsing process output for pattern %s: %s"
pattern err)
nil))))
(defun flymake-proc--process-filter (proc string)
"Parse STRING and collect diagnostics info."
@@ -567,12 +571,29 @@ Convert it to flymake internal format."
Use `flymake-proc-reformat-err-line-patterns-from-compile-el' to add patterns
from compile.el")
(define-obsolete-variable-alias 'flymake-warning-re 'flymake-proc-warning-predicate "24.4")
(defvar flymake-proc-warning-predicate "^[wW]arning"
"Predicate matching against error text to detect a warning.
Takes a single argument, the error's text and should return non-nil
if it's a warning.
Instead of a function, it can also be a regular expression.")
(define-obsolete-variable-alias 'flymake-warning-re 'flymake-proc-diagnostic-type-pred "26.1")
(defvar flymake-proc-diagnostic-type-pred
'flymake-proc-default-guess
"Predicate matching against diagnostic text to detect its type.
Takes a single argument, the diagnostic's text and should return
a value suitable for indexing
`flymake-diagnostic-types-alist' (which see). If the returned
value is nil, a type of `error' is assumed. For some backward
compatibility, if a non-nil value is returned that that doesn't
index that alist, a type of `:warning' is assumed.
Instead of a function, it can also be a string, a regular
expression. A match indicates `:warning' type, otherwise
`:error'")
(defun flymake-proc-default-guess (text)
"Guess if TEXT means a warning, a note or an error."
(cond ((string-match "^[wW]arning" text)
:warning)
((string-match "^[nN]ote" text)
:note)
(t
:error)))
(defun flymake-proc-get-project-include-dirs-imp (basedir)
"Include dirs for the project current file belongs to."
@@ -1167,12 +1188,6 @@ Convert it to flymake internal format.")
(REGEXP FILE-IDX LINE-IDX COL-IDX ERR-TEXT-IDX).
Use `flymake-reformat-err-line-patterns-from-compile-el' to add patterns
from compile.el")
(define-obsolete-variable-alias 'flymake-warning-predicate
'flymake-proc-warning-predicate "26.1"
"Predicate matching against error text to detect a warning.
Takes a single argument, the error's text and should return non-nil
if it's a warning.
Instead of a function, it can also be a regular expression.")
(define-obsolete-function-alias 'flymake-parse-line
'flymake-proc-parse-line "26.1"
"Parse LINE to see if it is an error or warning.

View File

@@ -189,6 +189,15 @@ verify FILTER, sort them by COMPARE (using KEY)."
:version "24.4"
:group 'flymake)
(defface flymake-note
'((((supports :underline (:style wave)))
:underline (:style wave :color "yellow green"))
(t
:inherit warning))
"Face used for marking note regions."
:version "26.1"
:group 'flymake)
(define-obsolete-face-alias 'flymake-warnline 'flymake-warning "26.1")
(define-obsolete-face-alias 'flymake-errline 'flymake-error "26.1")
@@ -226,13 +235,14 @@ Or nil if the region is invalid."
nil)))
(defvar flymake-diagnostic-types-alist
`((("e" :error error)
`((:error
. ((flymake-category . flymake-error)))
(("w" :warning warning)
. ((flymake-category . flymake-warning))))
(:warning
. ((flymake-category . flymake-warning)))
(:note
. ((flymake-category . flymake-note))))
"Alist ((KEY . PROPS)*) of properties of flymake error types.
KEY can be anything passed as `:type' to `flymake-diag-make', or
a list of these objects.
KEY can be anything passed as `:type' to `flymake-diag-make'.
PROPS is an alist of properties that are applied, in order, to
the diagnostics of each type. The recognized properties are:
@@ -259,27 +269,21 @@ the diagnostics of each type. The recognized properties are:
(put 'flymake-error 'face 'flymake-error)
(put 'flymake-error 'bitmap flymake-error-bitmap)
(put 'flymake-error 'severity (warning-numeric-level :error))
(put 'flymake-error 'mode-line-face 'compilation-error)
(put 'flymake-warning 'face 'flymake-warning)
(put 'flymake-warning 'bitmap flymake-warning-bitmap)
(put 'flymake-warning 'severity (warning-numeric-level :warning))
(put 'flymake-warning 'mode-line-face 'compilation-warning)
(put 'flymake-note 'face 'flymake-note)
(put 'flymake-note 'bitmap flymake-warning-bitmap)
(put 'flymake-note 'severity (warning-numeric-level :debug))
(put 'flymake-note 'mode-line-face 'compilation-info)
(defun flymake--lookup-type-property (type prop &optional default)
"Look up PROP for TYPE in `flymake-diagnostic-types-alist'.
If TYPE doesn't declare PROP in either
`flymake-diagnostic-types-alist' or its associated category,
return DEFAULT."
(let ((alist-probe (assoc type flymake-diagnostic-types-alist
(lambda (entry key)
(or (equal key entry)
(member key entry))))))
`flymake-diagnostic-types-alist' or its associated
`flymake-category', return DEFAULT."
(let ((alist-probe (assoc type flymake-diagnostic-types-alist)))
(cond (alist-probe
(let* ((alist (cdr alist-probe))
(prop-probe (assoc prop alist)))

View File

@@ -41,7 +41,7 @@
nil sev-pred-supplied-p))
"Call FN after flymake setup in FILE, using `flymake-proc`.
SEVERITY-PREDICATE is used to setup
`flymake-proc-warning-predicate'."
`flymake-proc-diagnostic-type-pred'"
(let* ((file (expand-file-name file flymake-tests-data-directory))
(visiting (find-buffer-visiting file))
(buffer (or visiting (find-file-noselect file)))
@@ -51,7 +51,7 @@ SEVERITY-PREDICATE is used to setup
(with-current-buffer buffer
(save-excursion
(when sev-pred-supplied-p
(setq-local flymake-proc-warning-predicate severity-predicate))
(setq-local flymake-proc-diagnostic-type-pred severity-predicate))
(goto-char (point-min))
(flymake-mode 1)
;; Weirdness here... http://debbugs.gnu.org/17647#25
@@ -115,13 +115,13 @@ SEVERITY-PREDICATE is used to setup
(should (eq 'flymake-warning
(face-at-point)))))
(ert-deftest errors-and-warnings ()
(ert-deftest different-diagnostic-types ()
"Test GCC warning via function predicate."
(skip-unless (and (executable-find "gcc") (executable-find "make")))
(flymake-tests--with-flymake
("errors-and-warnings.c")
(flymake-goto-next-error)
(should (eq 'flymake-error (face-at-point)))
(should (eq 'flymake-note (face-at-point)))
(flymake-goto-next-error)
(should (eq 'flymake-warning (face-at-point)))
(flymake-goto-next-error)