Eglot: speed up symbol highlighting (bug#80072)

In large buffers, responses to textDocument/documentHighlight
requests may return thousands of occurrences.  Avoid incurring
expensive eglot--lsp-position-to-point calls, by restricting the
highlights to visible region in the active window.

* lisp/progmodes/eglot.el (eglot-highlight-eldoc-function):
Rework.
This commit is contained in:
João Távora 2025-12-25 16:40:03 +00:00
parent 54ae1944e9
commit 0a6daa1412

View file

@ -3936,19 +3936,27 @@ for which LSP on-type-formatting should be requested."
:success-fn
(lambda (highlights)
(mapc #'delete-overlay eglot--highlights)
(setq eglot--highlights
(eglot--when-buffer-window buf
(mapcar
(eglot--lambda ((DocumentHighlight) range)
(pcase-let ((`(,beg . ,end)
(eglot-range-region range)))
(let ((ov (make-overlay beg end)))
(overlay-put ov 'face 'eglot-highlight-symbol-face)
(overlay-put ov 'eglot--overlay t)
(overlay-put ov 'modification-hooks
`(,(lambda (o &rest _) (delete-overlay o))))
ov)))
highlights))))
(setq eglot--highlights nil)
(eglot--when-buffer-window buf
;; Don't highlight occurrences that aren't
;; visible. (bug#80072).
(let* ((w (car (get-buffer-window-list)))
(ws (window-start w)) (we (window-end w))
(ls (1- (line-number-at-pos ws t)))
(le (1- (line-number-at-pos we t))))
(mapc
(eglot--lambda ((DocumentHighlight) range)
(when-let* ((l (cl-getf (cl-getf range :start) :line))
(_ (and (>= l ls) (<= l le))))
(pcase-let ((`(,beg . ,end)
(eglot-range-region range)))
(let ((ov (make-overlay beg end)))
(overlay-put ov 'face 'eglot-highlight-symbol-face)
(overlay-put ov 'eglot--overlay t)
(overlay-put ov 'modification-hooks
`(,(lambda (o &rest _) (delete-overlay o))))
(push ov eglot--highlights)))))
highlights))))
:hint :textDocument/documentHighlight)
nil)))