From f83c35788aedf3f60a112e34c656df554c46ef09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Fri, 14 Nov 2025 15:43:25 +0000 Subject: [PATCH] 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. --- lisp/progmodes/eglot.el | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index f089745e817..d5a4ca096f3 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -4620,12 +4620,20 @@ If NOERROR, return predicate, else erroring function." semtok-cache) 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 (server (_method (eql workspace/semanticTokens/refresh))) "Handle a semanticTokens/refresh request from SERVER." (dolist (buffer (eglot--managed-buffers server)) (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 "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-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) "Apply EDITS obtained from full/delta request to OLD-DATA." (cl-loop