mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 17:24:23 +00:00
Eglot: improve diagnostic-reporting performance
After a change in the buffer has occured, it is often the case that Flymake is quicker to ask for diagnostics than the server is to supply them to us. If we're still stuck with old outdated diagnostics, don't forward them to Flymake, even if it eagerly asks us for them. * etc/EGLOT-NEWS (Changes in upcoming Eglot): Announce changes. * lisp/progmodes/eglot.el (eglot--diagnostics): Rework. (eglot--report-to-flymake): Also take version. (eglot-handle-notification textDocument/publishDiagnostics) (eglot--managed-mode) (eglot-flymake-backend): Tweak call to eglot--report-to-flymake.
This commit is contained in:
parent
3c47139b8f
commit
7ae275f04c
2 changed files with 33 additions and 18 deletions
|
|
@ -47,6 +47,13 @@ The composition of Eglot's mode line can be fully customized by adding
|
|||
or removing symbols and strings from the customizable variable
|
||||
'eglot-mode-line-format'
|
||||
|
||||
** Improved diagnostic-reporting performance and bugfixes (bug#77588)
|
||||
|
||||
Eglot remembers the LSP document version to which diagonstics reported
|
||||
by the LSP server pertain. This helps in skipping useless or harmful
|
||||
updates, avoiding flakiness with code actions and flickering overlays
|
||||
when the buffer is changed.
|
||||
|
||||
|
||||
* Changes in Eglot 1.18 (20/1/2025)
|
||||
|
||||
|
|
|
|||
|
|
@ -2228,7 +2228,7 @@ Use `eglot-managed-p' to determine if current buffer is managed.")
|
|||
do (set (make-local-variable var) saved-binding))
|
||||
(remove-function (local 'imenu-create-index-function) #'eglot-imenu)
|
||||
(when eglot--current-flymake-report-fn
|
||||
(eglot--report-to-flymake nil)
|
||||
(eglot--report-to-flymake nil nil)
|
||||
(setq eglot--current-flymake-report-fn nil))
|
||||
(run-hooks 'eglot-managed-mode-hook)
|
||||
(let ((server eglot--cached-server))
|
||||
|
|
@ -2268,7 +2268,10 @@ Use `eglot-managed-p' to determine if current buffer is managed.")
|
|||
(jsonrpc-error "No current JSON-RPC connection")))
|
||||
|
||||
(defvar-local eglot--diagnostics nil
|
||||
"Flymake diagnostics for this buffer.")
|
||||
"A cons (DIAGNOSTICS . VERSION) for current buffer.
|
||||
DIAGNOSTICS is a list of Flymake diagnostics objects. VERSION is the
|
||||
LSP Document version reported for DIAGNOSTICS (comparable to
|
||||
`eglot--versioned-identifier') or nil if server didn't bother.")
|
||||
|
||||
(defvar revert-buffer-preserve-modes)
|
||||
(defun eglot--after-revert-hook ()
|
||||
|
|
@ -2699,8 +2702,11 @@ expensive cached value of `file-truename'.")
|
|||
initially
|
||||
(if (and version (/= version eglot--versioned-identifier))
|
||||
(cl-return))
|
||||
(setq flymake-list-only-diagnostics
|
||||
(assoc-delete-all path flymake-list-only-diagnostics))
|
||||
(setq
|
||||
;; if no explicit version received, assume it's current.
|
||||
version eglot--versioned-identifier
|
||||
flymake-list-only-diagnostics
|
||||
(assoc-delete-all path flymake-list-only-diagnostics))
|
||||
for diag-spec across diagnostics
|
||||
collect (eglot--dbind ((Diagnostic) range code message severity source tags)
|
||||
diag-spec
|
||||
|
|
@ -2740,9 +2746,9 @@ expensive cached value of `file-truename'.")
|
|||
;; starts on idle-timer (github#958)
|
||||
(not (null flymake-no-changes-timeout))
|
||||
eglot--current-flymake-report-fn)
|
||||
(eglot--report-to-flymake diags))
|
||||
(eglot--report-to-flymake diags version))
|
||||
(t
|
||||
(setq eglot--diagnostics diags)))))
|
||||
(setq eglot--diagnostics (cons diags version))))))
|
||||
(cl-loop
|
||||
for diag-spec across diagnostics
|
||||
collect (eglot--dbind ((Diagnostic) code range message severity source) diag-spec
|
||||
|
|
@ -3134,22 +3140,24 @@ may be called multiple times (respecting the protocol of
|
|||
`flymake-diagnostic-functions')."
|
||||
(cond (eglot--managed-mode
|
||||
(setq eglot--current-flymake-report-fn report-fn)
|
||||
(eglot--report-to-flymake eglot--diagnostics))
|
||||
(eglot--report-to-flymake (car eglot--diagnostics)
|
||||
(cdr eglot--diagnostics)))
|
||||
(t
|
||||
(funcall report-fn nil))))
|
||||
|
||||
(defun eglot--report-to-flymake (diags)
|
||||
(defun eglot--report-to-flymake (diags version)
|
||||
"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--diagnostics diags))
|
||||
(when (or (null version) (= version eglot--versioned-identifier))
|
||||
(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--diagnostics (cons diags version)))
|
||||
|
||||
(defun eglot-xref-backend () "Eglot xref backend." 'eglot)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue