1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

Eglot: invalidate local semtok cache at server's bidding

When the server sends workspace/semanticTokens/refresh, calling
font-lock-flush isn't enough.  It will trigger a new
eglot--semtok-font-lock call, but we can't assume anything about
the validity of eglot--semtok-cache.

Clangd seems to send workspace/semanticTokens/refresh when
complicated enough changes happen in an LSP document.  If the
buffer-local eglot--semtok-cache isn't flushed we'll likely
request a delta, and clangd may still supply it, but it won't
apply correctly to the outdated local state.

* lisp/progmodes/eglot.el (eglot--semtok-cache)
(eglot--semtok-inflight): Move up here.
(eglot-handle-request): Flush the eglot--semtok-cache.
This commit is contained in:
João Távora 2025-11-14 15:43:25 +00:00
parent d81bb68ed0
commit f83c35788a

View file

@ -4620,12 +4620,20 @@ If NOERROR, return predicate, else erroring function."
semtok-cache) semtok-cache)
probe)))) probe))))
(defvar-local eglot--semtok-cache nil
"Cache of the last response from the server.")
(defvar-local eglot--semtok-inflight nil
"List of (BEG . END) regions of inflight semtok requests.")
(cl-defmethod eglot-handle-request (cl-defmethod eglot-handle-request
(server (_method (eql workspace/semanticTokens/refresh))) (server (_method (eql workspace/semanticTokens/refresh)))
"Handle a semanticTokens/refresh request from SERVER." "Handle a semanticTokens/refresh request from SERVER."
(dolist (buffer (eglot--managed-buffers server)) (dolist (buffer (eglot--managed-buffers server))
(eglot--when-live-buffer buffer (eglot--when-live-buffer buffer
(unless (zerop eglot--versioned-identifier) (font-lock-flush))))) (unless (zerop eglot--versioned-identifier)
(setq eglot--semtok-cache nil)
(font-lock-flush)))))
(define-minor-mode eglot-semantic-tokens-mode (define-minor-mode eglot-semantic-tokens-mode
"Minor mode for fontifying buffer with LSP server's semantic tokens." "Minor mode for fontifying buffer with LSP server's semantic tokens."
@ -4639,12 +4647,6 @@ If NOERROR, return predicate, else erroring function."
(font-lock-remove-keywords nil '((eglot--semtok-font-lock))) (font-lock-remove-keywords nil '((eglot--semtok-font-lock)))
(font-lock-flush)))) (font-lock-flush))))
(defvar-local eglot--semtok-cache nil
"Cache of the last response from the server.")
(defvar-local eglot--semtok-inflight nil
"List of (BEG . END) regions of inflight semtok requests.")
(defsubst eglot--semtok-apply-delta-edits (old-data edits) (defsubst eglot--semtok-apply-delta-edits (old-data edits)
"Apply EDITS obtained from full/delta request to OLD-DATA." "Apply EDITS obtained from full/delta request to OLD-DATA."
(cl-loop (cl-loop