Subject: bug#77809: closed (Re: bug#77809: adding next-error support for flymake diagnostics buffers)

From: [email-masked] (GNU bug Tracking System)
Date: Sat, 03 May 2025 08:54:02 +0000

Your bug report

#77809: adding next-error support for flymake diagnostics buffers

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
77809: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=77809
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#77809: adding next-error support for flymake diagnostics buffers
From: Eli Zaretskii <[email-masked]>
To: Matthew Tromp <[email-masked]>
Cc: [email-masked], [email-masked]
Date: Sat, 03 May 2025 11:53:01 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

> From: Matthew Tromp <[email-masked]>
> Date: Sun, 27 Apr 2025 11:23:40 -0400
> Cc: [email-masked], [email-masked]
> 
> Okay, here you go.

Thanks, installed on the master branch, and closing the bug.

> Yes, please send me the copyright assignment paperwork.

Form sent off-list.

Subject: adding next-error support for flymake diagnostics buffers
From: [email-masked]
To: [email-masked]
Date: Mon, 14 Apr 2025 17:06:21 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

Tags: patch

This patch adds next-error support for flymake diagnostics buffers.
Buffers created with `flymake-show-buffer-diagnostics' and
`flymake-show-project-diagnostics' are now next-error enabled, and
`next-error' and `previous-error' will navigate through their listed
diagnostics.

In GNU Emacs 30.1.50 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo
version 1.18.2, Xaw3d scroll bars)
Windowing system distributor 'The X.Org Foundation', version 11.0.12101016
System Description: NixOS 24.11 (Vicuna)

Configured using:
 'configure
 --prefix=/nix/store/yffwm14bwi3vask5wfx6pcrdgxck61ba-emacs-30.1
 --disable-build-details --with-modules --with-x-toolkit=lucid
 --with-cairo --with-xft --with-compress-install
 --with-toolkit-scroll-bars --with-native-compilation
 --without-imagemagick --with-mailutils --without-small-ja-dic
 --with-tree-sitter --with-xinput2 --without-xwidgets --with-dbus
 --with-selinux'

diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 6cc7e1f7a79..002e587b029 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -1390,6 +1390,10 @@ flymake-mode-map
                (format "<%s> <mouse-1>" flymake-fringe-indicator-position)
                #'flymake-show-buffer-diagnostics-at-event-line)
 
+(defvar-local flymake-current-diagnostic-line 0
+  "The line of the most recently focused diagnostic in the flymake
+diagnostics buffer.")
+
 ;;;###autoload
 (define-minor-mode flymake-mode
   "Toggle Flymake mode on or off.
@@ -1881,7 +1885,8 @@ flymake-pulse-momentary-highlight-region
 (defun flymake-show-diagnostic (pos &optional other-window)
   "Show location of diagnostic at POS."
   (interactive (list (point) t))
-  (let* ((id (or (tabulated-list-get-id pos)
+  (let* ((diagnostics-buffer (current-buffer))
+         (id (or (tabulated-list-get-id pos)
                  (user-error "Nothing at point")))
          (diag (plist-get id :diagnostic))
          (locus (flymake--diag-locus diag))
@@ -1890,6 +1895,7 @@ flymake-show-diagnostic
          (visit (lambda (b e)
                   (goto-char b)
                   (flymake-pulse-momentary-highlight-region b e))))
+    (setq flymake-current-diagnostic-line (line-number-at-pos pos))
     (with-current-buffer (cond ((bufferp locus) locus)
                                (t (find-file-noselect locus)))
       (with-selected-window
@@ -1905,6 +1911,8 @@ flymake-show-diagnostic
                                                  (car beg)
                                                  (cdr beg))))
                  (funcall visit bbeg bend)))))
+      (setq next-error-buffer diagnostics-buffer
+            next-error-last-buffer diagnostics-buffer)
       (current-buffer))))
 
 (defun flymake-goto-diagnostic (pos)
@@ -2008,6 +2016,23 @@ flymake--diagnostics-base-tabulated-list-format
     ("Backend" 8 t)
     ("Message" 0 t)])
 
+(defun flymake--diagnostics-next-error (n &optional reset)
+  "`next-error-function' for flymake diagnostics buffers.
+N is an integer representing how many errors to move.
+If RESET is non-nil, returns to the beginning of the errors before
+moving."
+  (let ((line (if reset 1 flymake-current-diagnostic-line))
+        (total-lines (count-lines (point-min) (point-max))))
+    (goto-char (point-min))
+    (unless (zerop total-lines)
+      (let ((target-line (+ line n)))
+        (setq target-line (max 1 target-line))
+        (setq target-line (min target-line total-lines))
+        (forward-line (1- target-line))))
+    (when-let ((win (get-buffer-window nil t)))
+      (set-window-point win (point)))
+    (flymake-goto-diagnostic (point))))
+
 (define-derived-mode flymake-diagnostics-buffer-mode tabulated-list-mode
   "Flymake diagnostics"
   "A mode for listing Flymake diagnostics."
@@ -2015,6 +2040,9 @@ flymake-diagnostics-buffer-mode
   (setq tabulated-list-format flymake--diagnostics-base-tabulated-list-format)
   (setq tabulated-list-entries
         'flymake--diagnostics-buffer-entries)
+
+  (setq-local next-error-function #'flymake--diagnostics-next-error)
+
   (tabulated-list-init-header))
 
 (defun flymake--diagnostics-buffer-name ()
@@ -2036,6 +2064,7 @@ flymake-show-buffer-diagnostics
                        (current-buffer)))))
     (with-current-buffer target
       (setq flymake--diagnostics-buffer-source source)
+      (setq next-error-last-buffer (current-buffer))
       (revert-buffer)
       (display-buffer (current-buffer)
                       `((display-buffer-reuse-window
@@ -2085,6 +2114,9 @@ flymake-project-diagnostics-mode
   (setq tabulated-list-format
         (vconcat [("File" 25 t)]
                  flymake--diagnostics-base-tabulated-list-format))
+
+  (setq-local next-error-function #'flymake--diagnostics-next-error)
+
   (setq tabulated-list-entries
         'flymake--project-diagnostics-entries)
   (tabulated-list-init-header))
@@ -2149,6 +2181,7 @@ flymake-show-project-diagnostics
     (with-current-buffer buffer
       (flymake-project-diagnostics-mode)
       (setq-local flymake--project-diagnostic-list-project prj)
+      (setq next-error-last-buffer (current-buffer))
       (revert-buffer)
       (display-buffer (current-buffer)
                       `((display-buffer-reuse-window