diff options
| author | João Távora | 2025-11-12 20:47:34 +0000 |
|---|---|---|
| committer | João Távora | 2025-11-12 20:47:34 +0000 |
| commit | b55e6b77eb101a2da5b39f468ab8e1141e63738f (patch) | |
| tree | baeccc4bf29ae904d2515903b14e5eaa1da89149 | |
| parent | c34e32e4b0551a5e261bae73d65438b5e0c58745 (diff) | |
| download | emacs-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.el | 23 |
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)) |