From dcbb5a8d0bf3936363d1cfcb5b074199f3a67353 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Fri, 2 Apr 2021 00:21:27 +0100 Subject: [PATCH] Generalize eglot-flymake-backend Loosen coupling between eglot-flymake-backend and flymake-mode. The flymake-mode check in 'eglot-handle-notification publishDiagnostics' was a hack (and it wasn't even functioning correctly on M-x eglot-shutdown/eglot-reconnect). This should also allow eglot-flymake-backend to be driven by diagnostic-annotating frontends other than Flymake, such as the popular Flycheck package. * eglot.el (eglot--managed-mode): Use eglot--report-to-flymake. (eglot-handle-notification textDocument/publishDiagnostics): Use eglot--report-to-flymake. GitHub-reference: fix https://github.com/joaotavora/eglot/issues/596 --- lisp/progmodes/eglot.el | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 03e8baa8b76..c2363886769 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -1445,7 +1445,9 @@ Use `eglot-managed-p' to determine if current buffer is managed.") (cl-loop for (var . saved-binding) in eglot--saved-bindings do (set (make-local-variable var) saved-binding)) (remove-function (local 'imenu-create-index-function) #'eglot-imenu) - (setq eglot--current-flymake-report-fn nil) + (when eglot--current-flymake-report-fn + (eglot--report-to-flymake nil) + (setq eglot--current-flymake-report-fn nil)) (let ((server eglot--cached-server)) (setq eglot--cached-server nil) (when server @@ -1680,17 +1682,8 @@ COMMAND is a symbol naming the command." (t 'eglot-note)) message `((eglot-lsp-diag . ,diag-spec))))) into diags - finally (cond ((and flymake-mode eglot--current-flymake-report-fn) - (save-restriction - (widen) - (funcall eglot--current-flymake-report-fn diags - ;; If the buffer hasn't changed since last - ;; call to the report function, flymake won't - ;; delete old diagnostics. Using :region - ;; keyword forces flymake to delete - ;; them (github#159). - :region (cons (point-min) (point-max)))) - (setq eglot--unreported-diagnostics nil)) + finally (cond (eglot--current-flymake-report-fn + (eglot--report-to-flymake diags)) (t (setq eglot--unreported-diagnostics (cons t diags)))))) (jsonrpc--debug server "Diagnostics received for unvisited %s" uri))) @@ -1970,13 +1963,28 @@ When called interactively, use the currently active server" :textDocument (eglot--TextDocumentIdentifier)))) (defun eglot-flymake-backend (report-fn &rest _more) - "An EGLOT Flymake backend. -Calls REPORT-FN maybe if server publishes diagnostics in time." + "A Flymake backend for Eglot. +Calls REPORT-FN (or arranges for it to be called) when the server +publishes diagnostics. Between calls to this function, REPORT-FN +may be called multiple times (respecting the protocol of +`flymake-backend-functions')." (setq eglot--current-flymake-report-fn report-fn) ;; Report anything unreported (when eglot--unreported-diagnostics - (funcall report-fn (cdr eglot--unreported-diagnostics)) - (setq eglot--unreported-diagnostics nil))) + (eglot--report-to-flymake (cdr eglot--unreported-diagnostics)))) + +(defun eglot--report-to-flymake (diags) + "Internal helper for `eglot-flymake-backend'." + (save-restriction + (widen) + (funcall eglot--current-flymake-report-fn diags + ;; If the buffer hasn't changed since last + ;; call to the report function, flymake won't + ;; delete old diagnostics. Using :region + ;; keyword forces flymake to delete + ;; them (github#159). + :region (cons (point-min) (point-max)))) + (setq eglot--unreported-diagnostics nil)) (defun eglot-xref-backend () "EGLOT xref backend." 'eglot) -- 2.39.2