Esto es lo que se me ocurrió (como novato) después de conocer condition-case
, consejos universal-argument
y algunos aspectos internos de flycheck. Por lo general, no escribo código con tan poca idea de lo que estoy haciendo, así que agradezco mejores respuestas.
El registro comentado se deja ya que no considero que esto haya finalizado, y para aquellos que desean rastrear la ejecución de este código.
Finalmente, esto no hace nada para raw next-error
, solo se invoca cuando flycheck es.
;; 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)
Esta es una instantánea de https://gist.github.com/Blaisorblade/c7349438b06e7b1e034db775408ac4cb , donde colocaré cualquier versión actualizada.