Skip to content

Commit c80b91f

Browse files
committed
Support lazy completion detail resolution for LSP mode (emacs-lsp/lsp-mode#4625)
1 parent 44d9ac5 commit c80b91f

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

corfu-pixel-perfect.el

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ FACE applied to the 3 strings."
503503
cands)
504504

505505
(defun corfu-pixel-perfect--prepare-candidates (cands)
506-
"Prepare completion candidates CANDS for formatting."
506+
"Prepare completion candidates CANDS for alignment and truncation."
507507
(let* ((cands (cl-loop for c in cands
508508
collect (funcall corfu--hilit (substring c))))
509509
(cands (cdr (corfu--affixate cands)))
@@ -808,14 +808,55 @@ which should be greater than 99.86% of the widths."
808808
finally return (cons (/ M N) (/ S N)))))
809809
(ceiling (+ mean (* 3 stddev))))))
810810

811+
(declare-function lsp:completion-item-detail? "ext:lsp-protocol")
812+
(declare-function lsp-completion-resolve "ext:lsp-completion")
813+
814+
(defun corfu-pixel-perfect--resolve-completion-item-detail (cand)
815+
"Get the annotation for candidate CAND from LSP servers."
816+
(and (bound-and-true-p lsp-managed-mode)
817+
(fboundp 'lsp:completion-item-detail?)
818+
(fboundp 'lsp-completion-resolve)
819+
(or (lsp:completion-item-detail?
820+
(get-text-property 0 'lsp-completion-unresolved-item cand))
821+
(let* ((lsp-completion-resolved-item (lsp-completion-resolve cand))
822+
(lsp-completion-resolved-item
823+
(if (stringp lsp-completion-resolved-item)
824+
(get-text-property 0 'lsp-completion-item lsp-completion-resolved-item)
825+
lsp-completion-resolved-item)))
826+
(lsp:completion-item-detail? lsp-completion-resolved-item)))))
827+
828+
(defun corfu-pixel-perfect--prepare-current-candidate (cand)
829+
"Prepare the current candidate CAND.
830+
831+
Prepare CAND for alignment and truncation as usual, but
832+
optionally resolve the annotation from LSP servers if possible
833+
and necessary."
834+
(let ((prepared (car (corfu-pixel-perfect--prepare-candidates (list cand)))))
835+
(when-let (((or (not corfu-popupinfo-mode)
836+
(not corfu-popupinfo--toggle)))
837+
(detail
838+
(corfu-pixel-perfect--resolve-completion-item-detail cand)))
839+
(setf (caddr prepared)
840+
(propertize (concat " " (string-clean-whitespace detail))
841+
'face 'corfu-annotations)))
842+
(car (corfu-pixel-perfect--apply-format-functions (list prepared)))))
843+
844+
(defun corfu-pixel-perfect--get-prepared-candidates (cands)
845+
"Prepare every all the candidates in CANDS."
846+
(let* ((curr (- corfu--index corfu--scroll))
847+
(front (corfu-pixel-perfect--prepare-candidates (take curr cands)))
848+
(selected (corfu-pixel-perfect--prepare-current-candidate (nth curr cands)))
849+
(back (corfu-pixel-perfect--prepare-candidates (nthcdr (1+ curr) cands))))
850+
(nconc front (cons selected back))))
851+
811852
(defun corfu-pixel-perfect--candidates-popup (pos)
812853
"Show candidates popup at POS."
813854
(if (and (frame-live-p corfu--frame)
814855
(frame-visible-p corfu--frame))
815856
(corfu-pixel-perfect--refresh-popup corfu--frame pos)
816857
(corfu--compute-scroll)
817858
(let* ((curr (- corfu--index corfu--scroll))
818-
(cands (corfu-pixel-perfect--prepare-candidates
859+
(cands (corfu-pixel-perfect--get-prepared-candidates
819860
(take corfu-count (nthcdr corfu--scroll corfu--candidates))))
820861
(pw (corfu-pixel-perfect--column-pixel-width cands 'prefix))
821862
(fw (default-font-width))
@@ -900,7 +941,7 @@ its size has changed."
900941
(corfu-count (max (frame-text-lines frame) (length cands)))
901942
(corfu--scroll (corfu--compute-scroll))
902943
(curr (- corfu--index corfu--scroll))
903-
(cands (corfu-pixel-perfect--prepare-candidates
944+
(cands (corfu-pixel-perfect--get-prepared-candidates
904945
(take corfu-count (nthcdr corfu--scroll corfu--candidates))))
905946
(fw (default-font-width))
906947
(pw (corfu-pixel-perfect--column-pixel-width cands 'prefix))

0 commit comments

Comments
 (0)