Aqui está o que eu inventei (como um noob) depois de aprender condition-case
, conselhos universal-argument
e alguns detalhes internos do flycheck. Normalmente, não escrevo código com tão pouca pista do que estou fazendo, por isso agradeço respostas melhores.
O registro de saída comentado é deixado, pois eu não considero isso concluído, e para aqueles que desejam rastrear a execução desse código.
Por fim, isso não faz nada para o raw next-error
, é invocado apenas quando o flycheck é.
;; Optional: ensure flycheck cycles, both when going backward and forward.
;; Tries to handle arguments correctly.
;; Since flycheck-previous-error is written in terms of flycheck-next-error,
;; advising the latter is enough.
(defun flycheck-next-error-loop-advice (orig-fun &optional n reset)
; (message "flycheck-next-error called with args %S %S" n reset)
(condition-case err
(apply orig-fun (list n reset))
((user-error)
(let ((error-count (length flycheck-current-errors)))
(if (and
(> error-count 0) ; There are errors so we can cycle.
(equal (error-message-string err) "No more Flycheck errors"))
;; We need to cycle.
(let* ((req-n (if (numberp n) n 1)) ; Requested displacement.
; An universal argument is taken as reset, so shouldn't fail.
(curr-pos (if (> req-n 0) (- error-count 1) 0)) ; 0-indexed.
(next-pos (mod (+ curr-pos req-n) error-count))) ; next-pos must be 1-indexed
; (message "error-count %S; req-n %S; curr-pos %S; next-pos %S" error-count req-n curr-pos next-pos)
; orig-fun is flycheck-next-error (but without advise)
; Argument to flycheck-next-error must be 1-based.
(apply orig-fun (list (+ 1 next-pos) 'reset)))
(signal (car err) (cdr err)))))))
(advice-add 'flycheck-next-error :around #'flycheck-next-error-loop-advice)
Este é um instantâneo de https://gist.github.com/Blaisorblade/c7349438b06e7b1e034db775408ac4cb , onde colocarei qualquer versão atualizada.