From 73601787b45d08cdd5026ea36ff680bd49076950 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Wed, 27 Sep 2017 12:42:20 +0100 Subject: [PATCH] Tweak Flymake commands flymake-goto-[next/prev]-error 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 | 74 ++++++++++++++++++++++------ test/lisp/progmodes/flymake-tests.el | 6 ++- 2 files changed, 62 insertions(+), 18 deletions(-) diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index 242c83cf86e..f136e14ec19 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -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) diff --git a/test/lisp/progmodes/flymake-tests.el b/test/lisp/progmodes/flymake-tests.el index 921c2f648a4..fa77a9a8ae6 100644 --- a/test/lisp/progmodes/flymake-tests.el +++ b/test/lisp/progmodes/flymake-tests.el @@ -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) -- 2.39.5