mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-16 09:14:18 +00:00
Eglot: consider "pulled" and "pushed" diagnostics separately
This is chiefly for the benefit of rust-analyzer which uses both mechanisms. Per https://github.com/joaotavora/eglot/discussions/1562 * lisp/progmodes/eglot.el (eglot--flymake-report-fn): Rename from eglot--flymake-push-report-fn. (eglot--pulled-diagnostics) (eglot--pushed-diagnostics): Rework from eglot--diagnostics. (eglot--diagnostics): Remove. (eglot--managed-mode): Tweak. (eglot--maybe-activate-editing-mode): Tweak. (eglot-handle-notification): Set eglot--pushed-diagnostics only. Call eglot--flymake-report. (eglot-flymake-backend): Use eglot--flymake-report and eglot--flymake-report-fn. (eglot--flymake-pull): Rework. (eglot--flymake-report): Renam from eglot--flymake-push and reworked.
This commit is contained in:
parent
ad500a13e4
commit
da4c693e0b
1 changed files with 36 additions and 29 deletions
|
|
@ -2175,7 +2175,7 @@ and just return it. PROMPT shouldn't end with a question mark."
|
|||
(define-key map [remap display-local-help] #'eldoc-doc-buffer)
|
||||
map))
|
||||
|
||||
(defvar-local eglot--flymake-push-report-fn nil
|
||||
(defvar-local eglot--flymake-report-fn nil
|
||||
"Current flymake report function for this buffer.")
|
||||
|
||||
(defvar-local eglot--saved-bindings nil
|
||||
|
|
@ -2223,13 +2223,16 @@ Use `eglot-managed-p' to determine if current buffer is managed.")
|
|||
|
||||
(defvar eglot--highlights nil "Overlays for `eglot-highlight-eldoc-function'.")
|
||||
|
||||
(defvar-local eglot--diagnostics nil
|
||||
"A list (DIAGNOSTICS VERSION RESULT-ID) for current buffer.
|
||||
(defvar-local eglot--pulled-diagnostics nil
|
||||
"A list (DIAGNOSTICS RESULT-ID) \"pulled\" for current buffer.
|
||||
DIAGNOSTICS is a list of Flymake diagnostics objects. RESULT-ID
|
||||
identifies this diagnostic result as is used for incremental updates.")
|
||||
|
||||
(defvar-local eglot--pushed-diagnostics nil
|
||||
"A list (DIAGNOSTICS VERSION) \"pushed\" for current buffer.
|
||||
DIAGNOSTICS is a list of Flymake diagnostics objects. VERSION is the
|
||||
LSP Document version reported for DIAGNOSTICS (comparable to
|
||||
`eglot--docver') or nil if server didn't bother. RESULT-ID is an
|
||||
optional string identifying this diagnostic result for pull
|
||||
diagnostics, used for incremental updates.")
|
||||
`eglot--docver') or nil if server didn't bother.")
|
||||
|
||||
(defvar-local eglot--suggestion-overlay (make-overlay 0 0)
|
||||
"Overlay for `eglot-code-action-suggestion'.")
|
||||
|
|
@ -2309,10 +2312,11 @@ diagnostics, used for incremental updates.")
|
|||
(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)
|
||||
(when eglot--flymake-push-report-fn
|
||||
(setq eglot--diagnostics nil)
|
||||
(eglot--flymake-push)
|
||||
(setq eglot--flymake-push-report-fn nil))
|
||||
(when eglot--flymake-report-fn
|
||||
(setq eglot--pulled-diagnostics nil
|
||||
eglot--pushed-diagnostics nil)
|
||||
(eglot--flymake-report)
|
||||
(setq eglot--flymake-report-fn nil))
|
||||
(run-hooks 'eglot-managed-mode-hook)
|
||||
(let ((server eglot--cached-server))
|
||||
(setq eglot--cached-server nil)
|
||||
|
|
@ -2367,7 +2371,8 @@ If it is activated, also signal textDocument/didOpen."
|
|||
;; Called when `revert-buffer-in-progress-p' is t but
|
||||
;; `revert-buffer-preserve-modes' is nil.
|
||||
(when (and buffer-file-name (eglot-current-server))
|
||||
(setq eglot--diagnostics nil)
|
||||
(setq eglot--pulled-diagnostics nil
|
||||
eglot--pushed-diagnostics nil)
|
||||
(eglot--managed-mode)
|
||||
(eglot--signal-textDocument/didOpen)
|
||||
;; Run user hook after 'textDocument/didOpen' so server knows
|
||||
|
|
@ -2788,11 +2793,11 @@ expensive cached value of `file-truename'.")
|
|||
collect (eglot--flymake-make-diag diag-spec version)
|
||||
into diags
|
||||
finally
|
||||
(setq eglot--diagnostics (list diags version nil))
|
||||
(setq eglot--pushed-diagnostics (list diags version))
|
||||
(when (not (null flymake-no-changes-timeout ))
|
||||
;; only add to current report if Flymake
|
||||
;; starts on idle-timer (github#957)
|
||||
(eglot--flymake-push))))
|
||||
(eglot--flymake-report))))
|
||||
(cl-loop
|
||||
for diag-spec across diagnostics
|
||||
collect (eglot--dbind ((Diagnostic) code range message severity source) diag-spec
|
||||
|
|
@ -3234,26 +3239,26 @@ publishes diagnostics. Between calls to this function, REPORT-FN
|
|||
may be called multiple times (respecting the protocol of
|
||||
`flymake-diagnostic-functions')."
|
||||
(cond (eglot--managed-mode
|
||||
(setq eglot--flymake-push-report-fn report-fn)
|
||||
(setq eglot--flymake-report-fn report-fn)
|
||||
(cond
|
||||
;; Use pull diagnostics if server supports it
|
||||
((eglot-server-capable :diagnosticProvider)
|
||||
(eglot--flymake-pull))
|
||||
;; Otherwise push whatever we might have, and wait for
|
||||
;; `textDocument/publishDiagnostics'.
|
||||
(t (eglot--flymake-push))))
|
||||
(t (eglot--flymake-report))))
|
||||
(t
|
||||
(funcall report-fn nil))))
|
||||
|
||||
(cl-defun eglot--flymake-pull (&aux (server (eglot--current-server-or-lose))
|
||||
(origin (current-buffer)))
|
||||
"Pull diagnostics from server, for all managed buffers.
|
||||
When response arrives call registered `eglot--flymake-push-report-fn'."
|
||||
When response arrives call registered `eglot--flymake-report-fn'."
|
||||
(cl-flet
|
||||
((pull-for (buf &optional then)
|
||||
(with-current-buffer buf
|
||||
(let ((version eglot--docver)
|
||||
(prev-result-id (nth 2 eglot--diagnostics)))
|
||||
(prev-result-id (cadr eglot--pulled-diagnostics)))
|
||||
(eglot--async-request
|
||||
server
|
||||
:textDocument/diagnostic
|
||||
|
|
@ -3266,16 +3271,15 @@ When response arrives call registered `eglot--flymake-push-report-fn'."
|
|||
(eglot--when-live-buffer buf
|
||||
(pcase kind
|
||||
("full"
|
||||
(setq eglot--diagnostics
|
||||
(setq eglot--pulled-diagnostics
|
||||
(list
|
||||
(cl-loop
|
||||
for spec across items
|
||||
collect (eglot--flymake-make-diag spec version))
|
||||
version
|
||||
resultId))
|
||||
(eglot--flymake-push))
|
||||
(eglot--flymake-report))
|
||||
("unchanged"
|
||||
(when (eq buf origin) (eglot--flymake-push 'void)))))
|
||||
(when (eq buf origin) (eglot--flymake-report 'void)))))
|
||||
(when then (funcall then)))
|
||||
:hint :textDocument/diagnostic)))))
|
||||
;; JT@2025-12-15: No known server yet supports "relatedDocuments" so
|
||||
|
|
@ -3288,15 +3292,18 @@ When response arrives call registered `eglot--flymake-push-report-fn'."
|
|||
(mapc #'pull-for
|
||||
(remove origin (eglot--managed-buffers server))))))))
|
||||
|
||||
(cl-defun eglot--flymake-push
|
||||
(&optional void &aux (diags (nth 0 eglot--diagnostics))
|
||||
(version (nth 1 eglot--diagnostics)))
|
||||
"Push previously collected diagnostics to `eglot--flymake-push-report-fn'.
|
||||
(cl-defun eglot--flymake-report
|
||||
(&optional void
|
||||
&aux
|
||||
(diags (append (car eglot--pulled-diagnostics)
|
||||
(car eglot--pushed-diagnostics)))
|
||||
(version (cadr eglot--pushed-diagnostics)))
|
||||
"Push previously collected diagnostics to `eglot--flymake-report-fn'.
|
||||
If VOID, knowingly push a dummy do-nothing update."
|
||||
(unless eglot--flymake-push-report-fn
|
||||
(unless eglot--flymake-report-fn
|
||||
;; Occasionally called from contexts where report-fn not setup, such
|
||||
;; as a `didOpen''ed but yet undisplayed buffer.
|
||||
(cl-return-from eglot--flymake-push))
|
||||
(cl-return-from eglot--flymake-report))
|
||||
(eglot--widening
|
||||
(if (or void (and version (< version eglot--docver)))
|
||||
;; Here, we don't have anything interesting to give to Flymake: we
|
||||
|
|
@ -3305,9 +3312,9 @@ If VOID, knowingly push a dummy do-nothing update."
|
|||
;; we're alive and clear a possible "Wait" state. We hackingly
|
||||
;; achieve this by reporting an empty list and making sure it
|
||||
;; pertains to a 0-length region.
|
||||
(funcall eglot--flymake-push-report-fn nil
|
||||
(funcall eglot--flymake-report-fn nil
|
||||
:region (cons (point-min) (point-min)))
|
||||
(funcall eglot--flymake-push-report-fn diags
|
||||
(funcall eglot--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
|
||||
|
|
|
|||
Loading…
Reference in a new issue