aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2026-01-30 12:35:14 +0000
committerJoão Távora2026-01-30 12:55:32 +0000
commitd0daaead22f37df587113281ebdfd0d4c94636cf (patch)
tree4417750878ec4635d881dbf9b13581142bdec2c4
parent705c0e3729bf53db9e84ae7c8b932ebc3b2da934 (diff)
downloademacs-d0daaead22f37df587113281ebdfd0d4c94636cf.tar.gz
emacs-d0daaead22f37df587113281ebdfd0d4c94636cf.zip
Eglot: recall diagnostics froms unopened files on session start
This is exclusively for the benefit of rust-analyzer, which sends publishDiagnostics for all project files upfront, and never republishes them on 'didOpen'. See https://github.com/joaotavora/eglot/issues/1531. * lisp/progmodes/eglot.el (eglot--flymake-handle-push): Simplify. Don't flymake-list-only-diagnostics here. Save original diagnostic in flymake-list-only-diagnostics setting. (eglot--on-shutdown): Cleanup flymake-list-only-diagnostics. (eglot--flymake-report-push+pulled): Hack in data from flymake-list-only-diagnostics.
-rw-r--r--lisp/progmodes/eglot.el33
1 files changed, 24 insertions, 9 deletions
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 251b4e58e38..28ee14c67cb 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -1438,6 +1438,12 @@ PRESERVE-BUFFERS as in `eglot-shutdown', which see."
1438 (maphash (lambda (f s) 1438 (maphash (lambda (f s)
1439 (when (eq s server) (remhash f eglot--servers-by-xrefed-file))) 1439 (when (eq s server) (remhash f eglot--servers-by-xrefed-file)))
1440 eglot--servers-by-xrefed-file) 1440 eglot--servers-by-xrefed-file)
1441 ;; Cleanup entries in 'flymake-list-only-diagnostics'
1442 (setq flymake-list-only-diagnostics
1443 (cl-delete-if
1444 (lambda (x) (eq server
1445 (get-text-property 0 'eglot--server (car x))))
1446 flymake-list-only-diagnostics))
1441 (cond ((eglot--shutdown-requested server) 1447 (cond ((eglot--shutdown-requested server)
1442 t) 1448 t)
1443 ((not (eglot--inhibit-autoreconnect server)) 1449 ((not (eglot--inhibit-autoreconnect server))
@@ -3422,11 +3428,8 @@ object. The originator of this \"push\" is usually either regular
3422 (with-current-buffer buffer 3428 (with-current-buffer buffer
3423 (if (and version (/= version eglot--docver)) 3429 (if (and version (/= version eglot--docver))
3424 (cl-return-from eglot--flymake-handle-push)) 3430 (cl-return-from eglot--flymake-handle-push))
3425 (setq 3431 ;; if no explicit version received, assume it's current.
3426 ;; if no explicit version received, assume it's current. 3432 (setq version eglot--docver)
3427 version eglot--docver
3428 flymake-list-only-diagnostics
3429 (assoc-delete-all path flymake-list-only-diagnostics))
3430 (funcall then diagnostics)) 3433 (funcall then diagnostics))
3431 (cl-loop 3434 (cl-loop
3432 for diag-spec across diagnostics 3435 for diag-spec across diagnostics
@@ -3437,12 +3440,13 @@ object. The originator of this \"push\" is usually either regular
3437 (flymake-make-diagnostic 3440 (flymake-make-diagnostic
3438 path (cons line char) nil 3441 path (cons line char) nil
3439 (eglot--flymake-diag-type severity) 3442 (eglot--flymake-diag-type severity)
3440 (list source code message)))) 3443 (list source code message)
3444 `((eglot-lsp-diag . ,diag-spec)))))
3441 into diags 3445 into diags
3442 finally 3446 finally
3443 (setq flymake-list-only-diagnostics 3447 (setf (alist-get (propertize path 'eglot--server server)
3444 (assoc-delete-all path flymake-list-only-diagnostics)) 3448 flymake-list-only-diagnostics nil nil #'equal)
3445 (push (cons path diags) flymake-list-only-diagnostics)))) 3449 diags))))
3446 3450
3447(cl-defun eglot--flymake-pull (&aux (server (eglot--current-server-or-lose)) 3451(cl-defun eglot--flymake-pull (&aux (server (eglot--current-server-or-lose))
3448 (origin (current-buffer))) 3452 (origin (current-buffer)))
@@ -3506,6 +3510,17 @@ MODE is like `eglot--flymake-report-1'."
3506 (pushed-outdated-p (and pushed-docver (< pushed-docver eglot--docver)))) 3510 (pushed-outdated-p (and pushed-docver (< pushed-docver eglot--docver))))
3507 "Push previously collected diagnostics to `eglot--flymake-report-fn'. 3511 "Push previously collected diagnostics to `eglot--flymake-report-fn'.
3508If KEEP, knowingly push a dummy do-nothing update." 3512If KEEP, knowingly push a dummy do-nothing update."
3513 ;; Maybe hack in diagnostics we previously may have saved in
3514 ;; `flymake-list-only-diagnostics', pushed for this file before it was
3515 ;; visited (github#1531).
3516 (when-let* ((hack (and (<= eglot--docver 0)
3517 (null eglot--pushed-diagnostics)
3518 (cdr (assoc (buffer-file-name)
3519 flymake-list-only-diagnostics)))))
3520 (cl-loop
3521 for x in hack
3522 collect (alist-get 'eglot-lsp-diag (flymake-diagnostic-data x)) into res
3523 finally (setq eglot--pushed-diagnostics `(,(vconcat res) ,eglot--docver))))
3509 (eglot--widening 3524 (eglot--widening
3510 (if (and (null eglot--pulled-diagnostics) pushed-outdated-p) 3525 (if (and (null eglot--pulled-diagnostics) pushed-outdated-p)
3511 ;; Here, we don't have anything interesting to give to Flymake. 3526 ;; Here, we don't have anything interesting to give to Flymake.