]> git.eshelyaron.com Git - emacs.git/commitdiff
Tweak Flymake commands flymake-goto-[next/prev]-error
authorJoão Távora <joaotavora@gmail.com>
Wed, 27 Sep 2017 11:42:20 +0000 (12:42 +0100)
committerJoão Távora <joaotavora@gmail.com>
Tue, 3 Oct 2017 13:18:54 +0000 (14:18 +0100)
Add filters, useful for backends like the upcoming
flymake-elisp-checkdoc backend, for example, which litters everything
with low-priority notes.

Also re-implement wraparound for flymake-goto-next-error. Manual
mentions this, so it's probably a good idea to keep it.  Added a new
customization variable flymake-wrap-around to control it.

* lisp/progmodes/flymake.el (flymake-goto-prev-error)
(flymake-goto-next-error): Accept FILTER argument.
(flymake-wrap-around): New variable.
(flymake-goto-next-error): Wrap around according to flymake-wrap-around.

* test/lisp/progmodes/flymake-tests.el
(different-diagnostic-types, dummy-backends): Pass FILTER to
flymake-goto-prev-error.
(different-diagnostic-types)
(dummy-backends): Use flymake-wrap-around.

lisp/progmodes/flymake.el
test/lisp/progmodes/flymake-tests.el

index 242c83cf86eea1f77de483d0b173560757ae6f2e..f136e14ec1992d03f46ed73132a770707ba87dcb 100644 (file)
@@ -112,6 +112,10 @@ See `flymake-error-bitmap' and `flymake-warning-bitmap'."
                        "it is superseded by `warning-minimum-log-level.'"
                         "26.1")
 
+(defcustom flymake-wrap-around t
+  "If non-nil, moving to errors wraps around buffer boundaries."
+  :group 'flymake :type 'boolean)
+
 (defvar-local flymake-timer nil
   "Timer for starting syntax check.")
 
@@ -687,20 +691,44 @@ non-nil."
     (flymake-mode)
     (flymake-log :warning "Turned on in `flymake-find-file-hook'")))
 
-(defun flymake-goto-next-error (&optional n interactive)
-  "Go to next, or Nth next, flymake error in buffer."
-  (interactive (list 1 t))
+(defun flymake-goto-next-error (&optional n filter interactive)
+  "Go to Nth next flymake error in buffer matching FILTER.
+FILTER is a list of diagnostic types found in
+`flymake-diagnostic-types-alist', or nil, if no filter is to be
+applied.
+
+Interactively, always goes to the next error.  Also
+interactively, FILTER is determined by the prefix arg.  With no
+prefix arg, don't use a filter, otherwise only consider
+diagnostics of type `:error' and `:warning'."
+  (interactive (list 1
+                     (if current-prefix-arg
+                         '(:error :warning))
+                     t))
   (let* ((n (or n 1))
-         (ovs (flymake--overlays :filter 'flymake--diagnostic
+         (ovs (flymake--overlays :filter
+                                 (lambda (ov)
+                                   (let ((diag (overlay-get
+                                                ov
+                                                'flymake--diagnostic)))
+                                     (and diag
+                                          (or (not filter)
+                                              (memq (flymake--diag-type diag)
+                                                    filter)))))
                                  :compare (if (cl-plusp n) #'< #'>)
                                  :key #'overlay-start))
-         (chain (cl-member-if (lambda (ov)
-                                (if (cl-plusp n)
-                                    (> (overlay-start ov)
-                                       (point))
-                                  (< (overlay-start ov)
-                                     (point))))
-                              ovs))
+         (tail (cl-member-if (lambda (ov)
+                               (if (cl-plusp n)
+                                   (> (overlay-start ov)
+                                      (point))
+                                 (< (overlay-start ov)
+                                    (point))))
+                             ovs))
+         (chain (if flymake-wrap-around
+                    (if tail
+                        (progn (setcdr (last tail) ovs) tail)
+                      (and ovs (setcdr (last ovs) ovs)))
+                  tail))
          (target (nth (1- n) chain)))
     (cond (target
            (goto-char (overlay-start target))
@@ -709,12 +737,26 @@ non-nil."
               (funcall (overlay-get target 'help-echo)
                        nil nil (point)))))
           (interactive
-           (user-error "No more flymake errors")))))
+           (user-error "No more flymake errors%s"
+                       (if filter
+                           (format " of types %s" filter)
+                         ""))))))
+
+(defun flymake-goto-prev-error (&optional n filter interactive)
+  "Go to Nth previous flymake error in buffer matching FILTER.
+FILTER is a list of diagnostic types found in
+`flymake-diagnostic-types-alist', or nil, if no filter is to be
+applied.
+
+Interactively, always goes to the previous error.  Also
+interactively, FILTER is determined by the prefix arg.  With no
+prefix arg, don't use a filter, otherwise only consider
+diagnostics of type `:error' and `:warning'."
+  (interactive (list 1 (if current-prefix-arg
+                           '(:error :warning))
+                     t))
+  (flymake-goto-next-error (- (or n 1)) filter interactive))
 
-(defun flymake-goto-prev-error (&optional n interactive)
-  "Go to previous, or Nth previous, flymake error in buffer."
-  (interactive (list 1 t))
-  (flymake-goto-next-error (- (or n 1)) interactive))
 
 (provide 'flymake)
 
index 921c2f648a489db6c4d82769acf356e226a55756..fa77a9a8ae62e5c2ee81af52f3b4a2498459f9e3 100644 (file)
@@ -129,7 +129,8 @@ SEVERITY-PREDICATE is used to setup
     (should (eq 'flymake-warning (face-at-point)))
     (flymake-goto-next-error)
     (should (eq 'flymake-error (face-at-point)))
-    (should-error (flymake-goto-next-error nil t)) ))
+    (let ((flymake-wrap-around nil))
+      (should-error (flymake-goto-next-error nil nil t))) ))
 
 (defmacro flymake-tests--assert-set (set
                                      should
@@ -244,7 +245,8 @@ SEVERITY-PREDICATE is used to setup
         (should (eq 'flymake-warning (face-at-point))) ; dolor
         (flymake-goto-next-error)
         (should (eq 'flymake-error (face-at-point))) ; prognata
-        (should-error (flymake-goto-next-error nil t))))))
+        (let ((flymake-wrap-around nil))
+          (should-error (flymake-goto-next-error nil nil t)))))))
 
 (provide 'flymake-tests)