diff options
| author | João Távora | 2017-09-21 14:44:13 +0100 |
|---|---|---|
| committer | João Távora | 2017-10-03 13:52:24 +0100 |
| commit | 54beebb4e0d919c7ee6dcdd7d774d851c35f85b7 (patch) | |
| tree | 183a1dc5f749e96ceb4d5d3833b6208dc6cff63e | |
| parent | 491cc4a1bd68c2f651027982e3dfb7545d3e57ab (diff) | |
| download | emacs-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.el | 121 | ||||
| -rw-r--r-- | lisp/progmodes/flymake.el | 32 | ||||
| -rw-r--r-- | test/lisp/progmodes/flymake-tests.el | 8 |
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." | |||
| 567 | Use `flymake-proc-reformat-err-line-patterns-from-compile-el' to add patterns | 571 | Use `flymake-proc-reformat-err-line-patterns-from-compile-el' to add patterns |
| 568 | from compile.el") | 572 | from 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 |
| 573 | Takes a single argument, the error's text and should return non-nil | 577 | "Predicate matching against diagnostic text to detect its type. |
| 574 | if it's a warning. | 578 | Takes a single argument, the diagnostic's text and should return |
| 575 | Instead of a function, it can also be a regular expression.") | 579 | a value suitable for indexing |
| 580 | `flymake-diagnostic-types-alist' (which see). If the returned | ||
| 581 | value is nil, a type of `error' is assumed. For some backward | ||
| 582 | compatibility, if a non-nil value is returned that that doesn't | ||
| 583 | index that alist, a type of `:warning' is assumed. | ||
| 584 | |||
| 585 | Instead of a function, it can also be a string, a regular | ||
| 586 | expression. 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). |
| 1168 | Use `flymake-reformat-err-line-patterns-from-compile-el' to add patterns | 1189 | Use `flymake-reformat-err-line-patterns-from-compile-el' to add patterns |
| 1169 | from compile.el") | 1190 | from 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. | ||
| 1173 | Takes a single argument, the error's text and should return non-nil | ||
| 1174 | if it's a warning. | ||
| 1175 | Instead 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. |
| 234 | KEY can be anything passed as `:type' to `flymake-diag-make', or | 245 | KEY can be anything passed as `:type' to `flymake-diag-make'. |
| 235 | a list of these objects. | ||
| 236 | 246 | ||
| 237 | PROPS is an alist of properties that are applied, in order, to | 247 | PROPS is an alist of properties that are applied, in order, to |
| 238 | the diagnostics of each type. The recognized properties are: | 248 | the 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'. |
| 276 | If TYPE doesn't declare PROP in either | 283 | If TYPE doesn't declare PROP in either |
| 277 | `flymake-diagnostic-types-alist' or its associated category, | 284 | `flymake-diagnostic-types-alist' or its associated |
| 278 | return 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`. |
| 43 | SEVERITY-PREDICATE is used to setup | 43 | SEVERITY-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) |