mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-02-04 20:27:45 +00:00
Augment Flymake API for third-party extensions
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.
This commit is contained in:
parent
ddd547fada
commit
831eafc8ae
@ -361,34 +361,38 @@ priority but without an overlay face.
|
||||
(flymake-category . flymake-note))))
|
||||
@end example
|
||||
|
||||
@vindex flymake-text
|
||||
@vindex flymake-diagnostics
|
||||
@vindex flymake-diagnostic-backend
|
||||
@vindex flymake-diagnostic-buffer
|
||||
@vindex flymake-diagnostic-text
|
||||
@vindex flymake-diagnostic-beg
|
||||
@vindex flymake-diagnostic-end
|
||||
As you might have guessed, Flymake's annotations are implemented as
|
||||
overlays (@pxref{Overlays,,, elisp, The Emacs Lisp Reference Manual}).
|
||||
Along with the properties that you specify for the specific type of
|
||||
diagnostic, Flymake adds the property @code{flymake-text} to these
|
||||
overlays, and sets it to the message string that the backend used to
|
||||
describe the diagnostic.
|
||||
diagnostic, Flymake adds the property @code{flymake-diagnostic} to
|
||||
these overlays, and sets it to the object that the backend created
|
||||
with @code{flymake-make-diagnostic}.
|
||||
|
||||
Since overlays also support arbitrary keymaps, you can use this
|
||||
property @code{flymake-text} to create interactive annotations, such
|
||||
as in the following example of binding a @kbd{mouse-3} event (middle
|
||||
mouse button click) to an Internet search for the text of a
|
||||
@code{:warning} or @code{:error}.
|
||||
Since overlays also support arbitrary keymaps, you can use this along
|
||||
with the functions @code{flymake-diagnostics} and
|
||||
@code{flymake-diagnostic-text} (@pxref{Flymake utility functions}) to
|
||||
create interactive annotations, such as in the following example of
|
||||
binding a @code{mouse-3} event (middle mouse button click) to an
|
||||
Internet search for the text of a @code{:warning} or @code{:error}.
|
||||
|
||||
@example
|
||||
(defun my-search-for-message (event)
|
||||
(interactive "e")
|
||||
(let ((ovs (overlays-at (posn-point (event-start event))))
|
||||
ov)
|
||||
;; loop until flymake overlay we clicked on is recovered
|
||||
(while (not (overlay-get (setq ov (pop ovs)) 'flymake-text)))
|
||||
(when ov
|
||||
(eww-browse-url
|
||||
(concat "https://duckduckgo.com/?q="
|
||||
(replace-regexp-in-string " "
|
||||
"+"
|
||||
(overlay-get ov 'flymake-text)))
|
||||
t))))
|
||||
(let* ((diags (flymake-diagnostics (posn-point (event-start event))))
|
||||
(topmost-diag (car diags)))
|
||||
(eww-browse-url
|
||||
(concat
|
||||
"https://duckduckgo.com/?q="
|
||||
(replace-regexp-in-string " "
|
||||
"+"
|
||||
(flymake-diagnostic-text topmost-diag)))
|
||||
t)))
|
||||
|
||||
(dolist (type '(:warning :error))
|
||||
(let ((a (assoc type flymake-diagnostic-types-alist)))
|
||||
@ -513,6 +517,24 @@ Make a Flymake diagnostic for @var{buffer}'s region from @var{beg} to
|
||||
of the problem detected in this region.
|
||||
@end deffn
|
||||
|
||||
@cindex access diagnostic object
|
||||
These objects' properties can be accessed with the functions
|
||||
@code{flymake-diagnostic-backend}, @code{flymake-diagnostic-buffer},
|
||||
@code{flymake-diagnostic-text}, @code{flymake-diagnostic-beg},
|
||||
@code{flymake-diagnostic-end} and @code{flymake-diagnostic-type}.
|
||||
|
||||
Additionally, the function @code{flymake-diagnostics} will collect
|
||||
such objects in the region you specify.
|
||||
|
||||
@cindex collect diagnostic objects
|
||||
@deffn Function flymake-diagnostics beg end
|
||||
Get a list of Flymake diagnostics in the region determined by
|
||||
@var{beg} and @var{end}. If neither @var{beg} or @var{end} is
|
||||
supplied, use the whole buffer, otherwise if @var{beg} is
|
||||
non-@code{nil} and @var{end} is @code{nil}, consider only diagnostics
|
||||
at @var{beg}.
|
||||
@end deffn
|
||||
|
||||
@cindex buffer position from line and column number
|
||||
It is often the case with external syntax tools that a diagnostic's
|
||||
position is reported in terms of a line number, and sometimes a column
|
||||
@ -520,9 +542,10 @@ number. To convert this information into a buffer position, backends
|
||||
can use the following function:
|
||||
|
||||
@deffn Function flymake-diag-region buffer line &optional col
|
||||
Compute @var{buffer}'s region (@var{beg} . @var{end}) corresponding to
|
||||
@var{line} and @var{col}. If @var{col} is nil, return a region just
|
||||
for @var{line}. Return nil if the region is invalid.
|
||||
Compute @var{buffer}'s region (@var{beg} . @var{end}) corresponding
|
||||
to @var{line} and @var{col}. If @var{col} is @code{nil}, return a
|
||||
region just for @var{line}. Return @code{nil} if the region is
|
||||
invalid.
|
||||
@end deffn
|
||||
|
||||
@cindex add a log message
|
||||
|
@ -228,6 +228,29 @@ TYPE is a key to `flymake-diagnostic-types-alist' and TEXT is a
|
||||
description of the problem detected in this region."
|
||||
(flymake--diag-make :buffer buffer :beg beg :end end :type type :text text))
|
||||
|
||||
;;;###autoload
|
||||
(defun flymake-diagnostics (&optional beg end)
|
||||
"Get Flymake diagnostics in region determined by BEG and END.
|
||||
|
||||
If neither BEG or END is supplied, use the whole buffer,
|
||||
otherwise if BEG is non-nil and END is nil, consider only
|
||||
diagnostics at BEG."
|
||||
(mapcar (lambda (ov) (overlay-get ov 'flymake-diagnostic))
|
||||
(flymake--overlays :beg beg :end end)))
|
||||
|
||||
(defmacro flymake--diag-accessor (public internal thing)
|
||||
"Make PUBLIC an alias for INTERNAL, add doc using THING."
|
||||
`(defsubst ,public (diag)
|
||||
,(format "Get Flymake diagnostic DIAG's %s." (symbol-name thing))
|
||||
(,internal diag)))
|
||||
|
||||
(flymake--diag-accessor flymake-diagnostic-buffer flymake--diag-buffer buffer)
|
||||
(flymake--diag-accessor flymake-diagnostic-text flymake--diag-text text)
|
||||
(flymake--diag-accessor flymake-diagnostic-type flymake--diag-type type)
|
||||
(flymake--diag-accessor flymake-diagnostic-beg flymake--diag-beg beg)
|
||||
(flymake--diag-accessor flymake-diagnostic-end flymake--diag-end end)
|
||||
(flymake--diag-accessor flymake-diagnostic-backend flymake--diag-backend backend)
|
||||
|
||||
(cl-defun flymake--overlays (&key beg end filter compare key)
|
||||
"Get flymake-related overlays.
|
||||
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)."
|
||||
(widen)
|
||||
(let ((ovs (cl-remove-if-not
|
||||
(lambda (ov)
|
||||
(and (overlay-get ov 'flymake)
|
||||
(and (overlay-get ov 'flymake-diagnostic)
|
||||
(or (not filter)
|
||||
(funcall filter ov))))
|
||||
(if (and beg (null end))
|
||||
@ -498,18 +521,15 @@ associated `flymake-category' return DEFAULT."
|
||||
(default-maybe 'help-echo
|
||||
(lambda (_window _ov pos)
|
||||
(mapconcat
|
||||
(lambda (ov)
|
||||
(overlay-get ov 'flymake-text))
|
||||
(flymake--overlays :beg pos)
|
||||
#'flymake--diag-text
|
||||
(flymake-diagnostics pos)
|
||||
"\n")))
|
||||
(default-maybe 'severity (warning-numeric-level :error))
|
||||
(default-maybe 'priority (+ 100 (overlay-get ov 'severity))))
|
||||
;; Some properties can't be overridden.
|
||||
;;
|
||||
(overlay-put ov 'evaporate t)
|
||||
(overlay-put ov 'flymake t)
|
||||
(overlay-put ov 'flymake-text (flymake--diag-text diagnostic))
|
||||
(overlay-put ov 'flymake--diagnostic diagnostic)))
|
||||
(overlay-put ov 'flymake-diagnostic diagnostic)))
|
||||
|
||||
;; Nothing in Flymake uses this at all any more, so this is just for
|
||||
;; third-party compatibility.
|
||||
@ -600,7 +620,7 @@ not expected."
|
||||
(lambda (ov)
|
||||
(eq backend
|
||||
(flymake--diag-backend
|
||||
(overlay-get ov 'flymake--diagnostic))))))
|
||||
(overlay-get ov 'flymake-diagnostic))))))
|
||||
(mapc (lambda (diag)
|
||||
(flymake--highlight-line diag)
|
||||
(setf (flymake--diag-backend diag) backend))
|
||||
@ -899,7 +919,7 @@ applied."
|
||||
(lambda (ov)
|
||||
(let ((diag (overlay-get
|
||||
ov
|
||||
'flymake--diagnostic)))
|
||||
'flymake-diagnostic)))
|
||||
(and diag
|
||||
(or (not filter)
|
||||
(memq (flymake--diag-type diag)
|
||||
@ -1089,13 +1109,13 @@ applied."
|
||||
(interactive (list (point) t))
|
||||
(let* ((id (or (tabulated-list-get-id pos)
|
||||
(user-error "Nothing at point")))
|
||||
(overlay (plist-get id :overlay)))
|
||||
(with-current-buffer (overlay-buffer overlay)
|
||||
(diag (plist-get id :diagnostic)))
|
||||
(with-current-buffer (flymake--diag-buffer diag)
|
||||
(with-selected-window
|
||||
(display-buffer (current-buffer) other-window)
|
||||
(goto-char (overlay-start overlay))
|
||||
(pulse-momentary-highlight-region (overlay-start overlay)
|
||||
(overlay-end overlay)
|
||||
(goto-char (flymake--diag-beg diag))
|
||||
(pulse-momentary-highlight-region (flymake--diag-beg diag)
|
||||
(flymake--diag-end diag)
|
||||
'highlight))
|
||||
(current-buffer))))
|
||||
|
||||
@ -1108,18 +1128,16 @@ POS can be a buffer position or a button"
|
||||
|
||||
(defun flymake--diagnostics-buffer-entries ()
|
||||
(with-current-buffer flymake--diagnostics-buffer-source
|
||||
(cl-loop for ov in (flymake--overlays)
|
||||
for diag = (overlay-get ov
|
||||
'flymake--diagnostic)
|
||||
(cl-loop for diag in (flymake-diagnostics)
|
||||
for (line . col) =
|
||||
(save-excursion
|
||||
(goto-char (overlay-start ov))
|
||||
(goto-char (flymake--diag-beg diag))
|
||||
(cons (line-number-at-pos)
|
||||
(- (point)
|
||||
(line-beginning-position))))
|
||||
for type = (flymake--diag-type diag)
|
||||
collect
|
||||
(list (list :overlay ov
|
||||
(list (list :diagnostic diag
|
||||
:line line
|
||||
:severity (flymake--lookup-type-property
|
||||
type
|
||||
|
Loading…
x
Reference in New Issue
Block a user