aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2025-11-12 20:47:34 +0000
committerJoão Távora2025-11-12 20:47:34 +0000
commitb55e6b77eb101a2da5b39f468ab8e1141e63738f (patch)
treebaeccc4bf29ae904d2515903b14e5eaa1da89149
parentc34e32e4b0551a5e261bae73d65438b5e0c58745 (diff)
downloademacs-feature/eglot-semantic-tokens.tar.gz
emacs-feature/eglot-semantic-tokens.zip
Eglot: adjust semtok delta request debouncingfeature/eglot-semantic-tokens
When a response to a semtok request is received, it's important to remember which regions to flush. Font-lock logic will then do its magic and coalesce those regions into one before invoking eglot--semtok-font-lock, and eglot--semtok-font-lock-1 will have up-to-date data to work with. * lisp/progmodes/eglot.el (eglot--semtok-request): Rework. (eglot--semtok-inflight): Adjust docstring.
-rw-r--r--lisp/progmodes/eglot.el23
1 files changed, 12 insertions, 11 deletions
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index cc5c54476c7..fb43c97402e 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -4626,7 +4626,7 @@ If NOERROR, return predicate, else erroring function."
4626 "Cache of the last response from the server.") 4626 "Cache of the last response from the server.")
4627 4627
4628(defvar-local eglot--semtok-inflight nil 4628(defvar-local eglot--semtok-inflight nil
4629 "Non nil if there's an inflight full-buffer delta semtok request.") 4629 "List of (BEG . END) regions of inflight semtok requests.")
4630 4630
4631(defsubst eglot--semtok-apply-delta-edits (old-data edits) 4631(defsubst eglot--semtok-apply-delta-edits (old-data edits)
4632 "Apply EDITS obtained from full/delta request to OLD-DATA." 4632 "Apply EDITS obtained from full/delta request to OLD-DATA."
@@ -4656,7 +4656,6 @@ If NOERROR, return predicate, else erroring function."
4656 ;; "data: " 4656 ;; "data: "
4657 ;; (length (cl-getf response :data))) 4657 ;; (length (cl-getf response :data)))
4658 (eglot--when-live-buffer buf 4658 (eglot--when-live-buffer buf
4659 (setq eglot--semtok-inflight nil)
4660 ;; A user edit may have come in while the request 4659 ;; A user edit may have come in while the request
4661 ;; was inflight, changing the state of the buffer... 4660 ;; was inflight, changing the state of the buffer...
4662 (when (eq id eglot--versioned-identifier) 4661 (when (eq id eglot--versioned-identifier)
@@ -4669,25 +4668,27 @@ If NOERROR, return predicate, else erroring function."
4669 ;; this response is out-of-date, 4668 ;; this response is out-of-date,
4670 ;; `eglot--semtok-font-lock' should just trigger 4669 ;; `eglot--semtok-font-lock' should just trigger
4671 ;; another request. 4670 ;; another request.
4672 (font-lock-flush beg end))) 4671 (cl-loop for (b . e) in eglot--semtok-inflight
4672 do (font-lock-flush b e))
4673 ;; (trace-values "Flushed" (length eglot--semtok-inflight)
4674 ;; "regions")
4675 (setq eglot--semtok-inflight nil)))
4673 :hint method)) 4676 :hint method))
4674 (cache-get (&rest path) 4677 (cache-get (&rest path)
4675 (let ((x eglot--semtok-cache)) 4678 (let ((x eglot--semtok-cache))
4676 (dolist (op path x) (setq x (if (natnump op) (aref x op) 4679 (dolist (op path x) (setq x (if (natnump op) (aref x op)
4677 (plist-get x op))))))) 4680 (plist-get x op)))))))
4681 (push (cons beg end) eglot--semtok-inflight)
4678 (cond 4682 (cond
4679 ((and (eglot-server-capable :semanticTokensProvider :full :delta) 4683 ((and (eglot-server-capable :semanticTokensProvider :full :delta)
4680 (cache-get :response :data) 4684 (cache-get :response :data)
4681 (not (eq :textDocument/semanticTokens/range (cache-get :method)))) 4685 (not (eq :textDocument/semanticTokens/range (cache-get :method))))
4682 ;; JT@2025-11-12: many back-to-back calls for 4686 ;; JT@2025-11-12: many back-to-back calls for
4683 ;; `eglot--semtok-request' and small regions occur even on trivial 4687 ;; `eglot--semtok-request' and small regions occur even on
4684 ;; fast edits. Even though it's cheap and harmless to send many 4688 ;; trivial/fast edits. Even though it's fairly cheap to send
4685 ;; delta rquests, it's nicer to just send just one. The 4689 ;; multiple delta requests, it's nicer to just send just one.
4686 ;; debouncing from jsonrpc-async-request (which see) almost 4690 (when (cdr eglot--semtok-inflight)
4687 ;; suffices, but sometimes two requests creep in. Use this 4691 (cl-return-from eglot--semtok-request))
4688 ;; simple flag to avoid.
4689 (when eglot--semtok-inflight (cl-return-from eglot--semtok-request))
4690 (setq eglot--semtok-inflight t)
4691 (req :textDocument/semanticTokens/full/delta (point-min) (point-max) 4692 (req :textDocument/semanticTokens/full/delta (point-min) (point-max)
4692 (list :textDocument (eglot--TextDocumentIdentifier) 4693 (list :textDocument (eglot--TextDocumentIdentifier)
4693 :previousResultId (cache-get :response :resultId)) 4694 :previousResultId (cache-get :response :resultId))