aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2017-10-19 12:33:20 +0100
committerJoão Távora2017-10-19 12:33:20 +0100
commit46366c45cb1cef5c0cc88bb9a868df88f4ed5c1a (patch)
treeaf06ca158134feddd71f5fa524d4b00e4558ee58
parent4d578d432d4cf1e6826f3c07d119017940dd8e6e (diff)
downloademacs-scratch/flymake-augment-api.tar.gz
emacs-scratch/flymake-augment-api.zip
Augment Flymake API for third-party extensionsscratch/flymake-augment-api
See https://lists.gnu.org/archive/html/emacs-devel/2017-10/msg00619.html * doc/misc/flymake.texi (Flymake error types): Rewrite example. (Flymake utility functions): Augment with new API. * lisp/progmodes/flymake.el (flymake-diagnostics): New function. (flymake--diag-accessor): New helper macro. (flymake-diagnostic-buffer, flymake-diagnostic-text) (flymake-diagnostic-beg, flymake-diagnostic-end) (flymake-diagnostic-backend): Accessors for diagnostic objects. (flymake--overlays): Use flymake-diagnostic property. (flymake--highlight-line): Simplify. Only set flymake-diagnostic property. (flymake--handle-report, flymake-goto-next-error): Use flymake-diagnostic property. (flymake-show-diagnostic): Use diagnostic object. (flymake--diagnostics-buffer-entries): Use flymake-diagnostics.
-rw-r--r--doc/misc/flymake.texi61
-rw-r--r--lisp/progmodes/flymake.el56
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
365As you might have guessed, Flymake's annotations are implemented as 370As you might have guessed, Flymake's annotations are implemented as
366overlays (@pxref{Overlays,,, elisp, The Emacs Lisp Reference Manual}). 371overlays (@pxref{Overlays,,, elisp, The Emacs Lisp Reference Manual}).
367Along with the properties that you specify for the specific type of 372Along with the properties that you specify for the specific type of
368diagnostic, Flymake adds the property @code{flymake-text} to these 373diagnostic, Flymake adds the property @code{flymake-diagnostic} to
369overlays, and sets it to the message string that the backend used to 374these overlays, and sets it to the object that the backend created
370describe the diagnostic. 375with @code{flymake-make-diagnostic}.
371 376
372Since overlays also support arbitrary keymaps, you can use this 377Since overlays also support arbitrary keymaps, you can this along with
373property @code{flymake-text} to create interactive annotations, such 378the functions @code{flymake-diagnostics} and
374as in the following example of binding a @kbd{mouse-3} event (middle 379@code{flymake-diagnostic-text} (@pxref{Flymake utility functions}) to
375mouse button click) to an Internet search for the text of a 380create interactive annotations, such as in the following example of
376@code{:warning} or @code{:error}. 381binding a @kbd{mouse-3} event (middle mouse button click) to an
382Internet 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
513of the problem detected in this region. 517of the problem detected in this region.
514@end deffn 518@end deffn
515 519
520@cindex access diagnostic object
521These 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
526Additionally, the function @code{flymake-diagnostics} will collect
527such objects in the region you specify.
528
529@cindex collect diagnostic objects
530@deffn Function flymake-diagnostics beg end
531Get a list of Flymake diagnostics in the region comprised between
532@var{beg} and @var{end}. If neither @var{beg} or @var{end} is
533supplied, 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
517It is often the case with external syntax tools that a diagnostic's 538It is often the case with external syntax tools that a diagnostic's
518position is reported in terms of a line number, and sometimes a column 539position 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
228description of the problem detected in this region." 228description 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
235If neither BEG or END is supplied, use the whole buffer,
236otherwise if BEG is non-nil and END is nil, consider only
237diagnostics 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.
233If BEG is non-nil and END is nil, consider only `overlays-at' 256If 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