diff options
| -rw-r--r-- | doc/misc/flymake.texi | 61 | ||||
| -rw-r--r-- | lisp/progmodes/flymake.el | 56 |
2 files changed, 78 insertions, 39 deletions
diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi index 99ab1271ac9..6e0928f0ee2 100644 --- a/doc/misc/flymake.texi +++ b/doc/misc/flymake.texi | |||
| @@ -361,34 +361,38 @@ priority but without an overlay face. | |||
| 361 | (flymake-category . flymake-note)))) | 361 | (flymake-category . flymake-note)))) |
| 362 | @end example | 362 | @end example |
| 363 | 363 | ||
| 364 | @vindex flymake-text | 364 | @vindex flymake-diagnostics |
| 365 | @vindex flymake-diagnostic-backend | ||
| 366 | @vindex flymake-diagnostic-buffer | ||
| 367 | @vindex flymake-diagnostic-text | ||
| 368 | @vindex flymake-diagnostic-beg | ||
| 369 | @vindex flymake-diagnostic-end | ||
| 365 | As you might have guessed, Flymake's annotations are implemented as | 370 | As you might have guessed, Flymake's annotations are implemented as |
| 366 | overlays (@pxref{Overlays,,, elisp, The Emacs Lisp Reference Manual}). | 371 | overlays (@pxref{Overlays,,, elisp, The Emacs Lisp Reference Manual}). |
| 367 | Along with the properties that you specify for the specific type of | 372 | Along with the properties that you specify for the specific type of |
| 368 | diagnostic, Flymake adds the property @code{flymake-text} to these | 373 | diagnostic, Flymake adds the property @code{flymake-diagnostic} to |
| 369 | overlays, and sets it to the message string that the backend used to | 374 | these overlays, and sets it to the object that the backend created |
| 370 | describe the diagnostic. | 375 | with @code{flymake-make-diagnostic}. |
| 371 | 376 | ||
| 372 | Since overlays also support arbitrary keymaps, you can use this | 377 | Since overlays also support arbitrary keymaps, you can this along with |
| 373 | property @code{flymake-text} to create interactive annotations, such | 378 | the functions @code{flymake-diagnostics} and |
| 374 | as in the following example of binding a @kbd{mouse-3} event (middle | 379 | @code{flymake-diagnostic-text} (@pxref{Flymake utility functions}) to |
| 375 | mouse button click) to an Internet search for the text of a | 380 | create interactive annotations, such as in the following example of |
| 376 | @code{:warning} or @code{:error}. | 381 | binding a @kbd{mouse-3} event (middle mouse button click) to an |
| 382 | Internet search for the text of a @code{:warning} or @code{:error}. | ||
| 377 | 383 | ||
| 378 | @example | 384 | @example |
| 379 | (defun my-search-for-message (event) | 385 | (defun my-search-for-message (event) |
| 380 | (interactive "e") | 386 | (interactive "e") |
| 381 | (let ((ovs (overlays-at (posn-point (event-start event)))) | 387 | (let* ((diags (flymake-diagnostics (posn-point (event-start event)))) |
| 382 | ov) | 388 | (topmost-diag (car diags))) |
| 383 | ;; loop until flymake overlay we clicked on is recovered | 389 | (eww-browse-url |
| 384 | (while (not (overlay-get (setq ov (pop ovs)) 'flymake-text))) | 390 | (concat |
| 385 | (when ov | 391 | "https://duckduckgo.com/?q=" |
| 386 | (eww-browse-url | 392 | (replace-regexp-in-string " " |
| 387 | (concat "https://duckduckgo.com/?q=" | 393 | "+" |
| 388 | (replace-regexp-in-string " " | 394 | (flymake-diagnostic-text topmost-diag))) |
| 389 | "+" | 395 | t))) |
| 390 | (overlay-get ov 'flymake-text))) | ||
| 391 | t)))) | ||
| 392 | 396 | ||
| 393 | (dolist (type '(:warning :error)) | 397 | (dolist (type '(:warning :error)) |
| 394 | (let ((a (assoc type flymake-diagnostic-types-alist))) | 398 | (let ((a (assoc type flymake-diagnostic-types-alist))) |
| @@ -513,6 +517,23 @@ Make a Flymake diagnostic for @var{buffer}'s region from @var{beg} to | |||
| 513 | of the problem detected in this region. | 517 | of the problem detected in this region. |
| 514 | @end deffn | 518 | @end deffn |
| 515 | 519 | ||
| 520 | @cindex access diagnostic object | ||
| 521 | These objects' properties can be accessed with the functions | ||
| 522 | @code{flymake-diagnostic-backend}, @code{flymake-diagnostic-buffer}, | ||
| 523 | @code{flymake-diagnostic-text}, @code{flymake-diagnostic-beg}, | ||
| 524 | @code{flymake-diagnostic-end} and @code{flymake-diagnostic-type}. | ||
| 525 | |||
| 526 | Additionally, the function @code{flymake-diagnostics} will collect | ||
| 527 | such objects in the region you specify. | ||
| 528 | |||
| 529 | @cindex collect diagnostic objects | ||
| 530 | @deffn Function flymake-diagnostics beg end | ||
| 531 | Get a list of Flymake diagnostics in the region comprised between | ||
| 532 | @var{beg} and @var{end}. If neither @var{beg} or @var{end} is | ||
| 533 | supplied, use the whole buffer, otherwise if @var{beg} is non-nil and | ||
| 534 | @var{end} is nil, consider only diagnostics at @var{beg}. | ||
| 535 | @end deffn | ||
| 536 | |||
| 516 | @cindex buffer position from line and column number | 537 | @cindex buffer position from line and column number |
| 517 | It is often the case with external syntax tools that a diagnostic's | 538 | It is often the case with external syntax tools that a diagnostic's |
| 518 | position is reported in terms of a line number, and sometimes a column | 539 | position is reported in terms of a line number, and sometimes a column |
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 5d5f9bb75d8..fc5e3b80ef2 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el | |||
| @@ -228,6 +228,29 @@ TYPE is a key to `flymake-diagnostic-types-alist' and TEXT is a | |||
| 228 | description of the problem detected in this region." | 228 | description of the problem detected in this region." |
| 229 | (flymake--diag-make :buffer buffer :beg beg :end end :type type :text text)) | 229 | (flymake--diag-make :buffer buffer :beg beg :end end :type type :text text)) |
| 230 | 230 | ||
| 231 | ;;;###autoload | ||
| 232 | (defun flymake-diagnostics (&optional beg end) | ||
| 233 | "Get Flymake diagnostics in region comprised between BEG and END. | ||
| 234 | |||
| 235 | If neither BEG or END is supplied, use the whole buffer, | ||
| 236 | otherwise if BEG is non-nil and END is nil, consider only | ||
| 237 | diagnostics at BEG." | ||
| 238 | (mapcar (lambda (ov) (overlay-get ov 'flymake-diagnostic)) | ||
| 239 | (flymake--overlays :beg beg :end end))) | ||
| 240 | |||
| 241 | (defmacro flymake--diag-accessor (public internal thing) | ||
| 242 | "Make PUBLIC an alias for INTERNAL, add doc using THING." | ||
| 243 | `(defsubst ,public (diag) | ||
| 244 | ,(format "Get Flymake diagnostic DIAG's %s." (symbol-name thing)) | ||
| 245 | (,internal diag))) | ||
| 246 | |||
| 247 | (flymake--diag-accessor flymake-diagnostic-buffer flymake--diag-buffer buffer) | ||
| 248 | (flymake--diag-accessor flymake-diagnostic-text flymake--diag-text text) | ||
| 249 | (flymake--diag-accessor flymake-diagnostic-type flymake--diag-type type) | ||
| 250 | (flymake--diag-accessor flymake-diagnostic-beg flymake--diag-beg beg) | ||
| 251 | (flymake--diag-accessor flymake-diagnostic-end flymake--diag-end end) | ||
| 252 | (flymake--diag-accessor flymake-diagnostic-backend flymake--diag-backend backend) | ||
| 253 | |||
| 231 | (cl-defun flymake--overlays (&key beg end filter compare key) | 254 | (cl-defun flymake--overlays (&key beg end filter compare key) |
| 232 | "Get flymake-related overlays. | 255 | "Get flymake-related overlays. |
| 233 | If BEG is non-nil and END is nil, consider only `overlays-at' | 256 | If BEG is non-nil and END is nil, consider only `overlays-at' |
| @@ -238,7 +261,7 @@ verify FILTER, a function, and sort them by COMPARE (using KEY)." | |||
| 238 | (widen) | 261 | (widen) |
| 239 | (let ((ovs (cl-remove-if-not | 262 | (let ((ovs (cl-remove-if-not |
| 240 | (lambda (ov) | 263 | (lambda (ov) |
| 241 | (and (overlay-get ov 'flymake) | 264 | (and (overlay-get ov 'flymake-diagnostic) |
| 242 | (or (not filter) | 265 | (or (not filter) |
| 243 | (funcall filter ov)))) | 266 | (funcall filter ov)))) |
| 244 | (if (and beg (null end)) | 267 | (if (and beg (null end)) |
| @@ -498,18 +521,15 @@ associated `flymake-category' return DEFAULT." | |||
| 498 | (default-maybe 'help-echo | 521 | (default-maybe 'help-echo |
| 499 | (lambda (_window _ov pos) | 522 | (lambda (_window _ov pos) |
| 500 | (mapconcat | 523 | (mapconcat |
| 501 | (lambda (ov) | 524 | #'flymake--diag-text |
| 502 | (overlay-get ov 'flymake-text)) | 525 | (flymake-diagnostics pos) |
| 503 | (flymake--overlays :beg pos) | ||
| 504 | "\n"))) | 526 | "\n"))) |
| 505 | (default-maybe 'severity (warning-numeric-level :error)) | 527 | (default-maybe 'severity (warning-numeric-level :error)) |
| 506 | (default-maybe 'priority (+ 100 (overlay-get ov 'severity)))) | 528 | (default-maybe 'priority (+ 100 (overlay-get ov 'severity)))) |
| 507 | ;; Some properties can't be overridden. | 529 | ;; Some properties can't be overridden. |
| 508 | ;; | 530 | ;; |
| 509 | (overlay-put ov 'evaporate t) | 531 | (overlay-put ov 'evaporate t) |
| 510 | (overlay-put ov 'flymake t) | 532 | (overlay-put ov 'flymake-diagnostic diagnostic))) |
| 511 | (overlay-put ov 'flymake-text (flymake--diag-text diagnostic)) | ||
| 512 | (overlay-put ov 'flymake--diagnostic diagnostic))) | ||
| 513 | 533 | ||
| 514 | ;; Nothing in Flymake uses this at all any more, so this is just for | 534 | ;; Nothing in Flymake uses this at all any more, so this is just for |
| 515 | ;; third-party compatibility. | 535 | ;; third-party compatibility. |
| @@ -600,7 +620,7 @@ not expected." | |||
| 600 | (lambda (ov) | 620 | (lambda (ov) |
| 601 | (eq backend | 621 | (eq backend |
| 602 | (flymake--diag-backend | 622 | (flymake--diag-backend |
| 603 | (overlay-get ov 'flymake--diagnostic)))))) | 623 | (overlay-get ov 'flymake-diagnostic)))))) |
| 604 | (mapc (lambda (diag) | 624 | (mapc (lambda (diag) |
| 605 | (flymake--highlight-line diag) | 625 | (flymake--highlight-line diag) |
| 606 | (setf (flymake--diag-backend diag) backend)) | 626 | (setf (flymake--diag-backend diag) backend)) |
| @@ -899,7 +919,7 @@ applied." | |||
| 899 | (lambda (ov) | 919 | (lambda (ov) |
| 900 | (let ((diag (overlay-get | 920 | (let ((diag (overlay-get |
| 901 | ov | 921 | ov |
| 902 | 'flymake--diagnostic))) | 922 | 'flymake-diagnostic))) |
| 903 | (and diag | 923 | (and diag |
| 904 | (or (not filter) | 924 | (or (not filter) |
| 905 | (memq (flymake--diag-type diag) | 925 | (memq (flymake--diag-type diag) |
| @@ -1089,13 +1109,13 @@ applied." | |||
| 1089 | (interactive (list (point) t)) | 1109 | (interactive (list (point) t)) |
| 1090 | (let* ((id (or (tabulated-list-get-id pos) | 1110 | (let* ((id (or (tabulated-list-get-id pos) |
| 1091 | (user-error "Nothing at point"))) | 1111 | (user-error "Nothing at point"))) |
| 1092 | (overlay (plist-get id :overlay))) | 1112 | (diag (plist-get id :diagnostic))) |
| 1093 | (with-current-buffer (overlay-buffer overlay) | 1113 | (with-current-buffer (flymake--diag-buffer diag) |
| 1094 | (with-selected-window | 1114 | (with-selected-window |
| 1095 | (display-buffer (current-buffer) other-window) | 1115 | (display-buffer (current-buffer) other-window) |
| 1096 | (goto-char (overlay-start overlay)) | 1116 | (goto-char (flymake--diag-beg diag)) |
| 1097 | (pulse-momentary-highlight-region (overlay-start overlay) | 1117 | (pulse-momentary-highlight-region (flymake--diag-beg diag) |
| 1098 | (overlay-end overlay) | 1118 | (flymake--diag-end diag) |
| 1099 | 'highlight)) | 1119 | 'highlight)) |
| 1100 | (current-buffer)))) | 1120 | (current-buffer)))) |
| 1101 | 1121 | ||
| @@ -1108,18 +1128,16 @@ POS can be a buffer position or a button" | |||
| 1108 | 1128 | ||
| 1109 | (defun flymake--diagnostics-buffer-entries () | 1129 | (defun flymake--diagnostics-buffer-entries () |
| 1110 | (with-current-buffer flymake--diagnostics-buffer-source | 1130 | (with-current-buffer flymake--diagnostics-buffer-source |
| 1111 | (cl-loop for ov in (flymake--overlays) | 1131 | (cl-loop for diag in (flymake-diagnostics) |
| 1112 | for diag = (overlay-get ov | ||
| 1113 | 'flymake--diagnostic) | ||
| 1114 | for (line . col) = | 1132 | for (line . col) = |
| 1115 | (save-excursion | 1133 | (save-excursion |
| 1116 | (goto-char (overlay-start ov)) | 1134 | (goto-char (flymake--diag-beg diag)) |
| 1117 | (cons (line-number-at-pos) | 1135 | (cons (line-number-at-pos) |
| 1118 | (- (point) | 1136 | (- (point) |
| 1119 | (line-beginning-position)))) | 1137 | (line-beginning-position)))) |
| 1120 | for type = (flymake--diag-type diag) | 1138 | for type = (flymake--diag-type diag) |
| 1121 | collect | 1139 | collect |
| 1122 | (list (list :overlay ov | 1140 | (list (list :diagnostic diag |
| 1123 | :line line | 1141 | :line line |
| 1124 | :severity (flymake--lookup-type-property | 1142 | :severity (flymake--lookup-type-property |
| 1125 | type | 1143 | type |