aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2025-11-14 15:43:25 +0000
committerJoão Távora2025-11-14 15:45:37 +0000
commitf83c35788aedf3f60a112e34c656df554c46ef09 (patch)
tree5c7b82ecbf54a31dd3ff7e02bbe72c347ec3d177
parentd81bb68ed09821d9c9e771e7c1ce34b2bf212823 (diff)
downloademacs-f83c35788aedf3f60a112e34c656df554c46ef09.tar.gz
emacs-f83c35788aedf3f60a112e34c656df554c46ef09.zip
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.
-rw-r--r--lisp/progmodes/eglot.el16
1 files 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."
4620 semtok-cache) 4620 semtok-cache)
4621 probe)))) 4621 probe))))
4622 4622
4623(defvar-local eglot--semtok-cache nil
4624 "Cache of the last response from the server.")
4625
4626(defvar-local eglot--semtok-inflight nil
4627 "List of (BEG . END) regions of inflight semtok requests.")
4628
4623(cl-defmethod eglot-handle-request 4629(cl-defmethod eglot-handle-request
4624 (server (_method (eql workspace/semanticTokens/refresh))) 4630 (server (_method (eql workspace/semanticTokens/refresh)))
4625 "Handle a semanticTokens/refresh request from SERVER." 4631 "Handle a semanticTokens/refresh request from SERVER."
4626 (dolist (buffer (eglot--managed-buffers server)) 4632 (dolist (buffer (eglot--managed-buffers server))
4627 (eglot--when-live-buffer buffer 4633 (eglot--when-live-buffer buffer
4628 (unless (zerop eglot--versioned-identifier) (font-lock-flush))))) 4634 (unless (zerop eglot--versioned-identifier)
4635 (setq eglot--semtok-cache nil)
4636 (font-lock-flush)))))
4629 4637
4630(define-minor-mode eglot-semantic-tokens-mode 4638(define-minor-mode eglot-semantic-tokens-mode
4631 "Minor mode for fontifying buffer with LSP server's semantic tokens." 4639 "Minor mode for fontifying buffer with LSP server's semantic tokens."
@@ -4639,12 +4647,6 @@ If NOERROR, return predicate, else erroring function."
4639 (font-lock-remove-keywords nil '((eglot--semtok-font-lock))) 4647 (font-lock-remove-keywords nil '((eglot--semtok-font-lock)))
4640 (font-lock-flush)))) 4648 (font-lock-flush))))
4641 4649
4642(defvar-local eglot--semtok-cache nil
4643 "Cache of the last response from the server.")
4644
4645(defvar-local eglot--semtok-inflight nil
4646 "List of (BEG . END) regions of inflight semtok requests.")
4647
4648(defsubst eglot--semtok-apply-delta-edits (old-data edits) 4650(defsubst eglot--semtok-apply-delta-edits (old-data edits)
4649 "Apply EDITS obtained from full/delta request to OLD-DATA." 4651 "Apply EDITS obtained from full/delta request to OLD-DATA."
4650 (cl-loop 4652 (cl-loop