Skip to content

Commit 17483ec

Browse files
authored
Do not resolve during annotate, enrich documentation with details (Fix #3201) (Fix #3905) (#4625)
* Do not resolve during annotate, enrich documentation with details Also fixes: - #3201 - #3905 * cache adjusted documentation * Make lsp-completion--resolve[-async] public * Resolved detail may be different from unresolved detail * Do not fontify detail in documentation * Return resolved signature via company-docsig * Properly implement labelDetails for 3.17 * Show detail when labelDetail is not available * Replace \r only when there's a detail * Request server to compute insertTextFormat and insertTextMode early * Use code fence for detail * Put lsp-completion-show-detail back
1 parent d28dd6b commit 17483ec

File tree

3 files changed

+95
-29
lines changed

3 files changed

+95
-29
lines changed

lsp-completion.el

Lines changed: 93 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,6 @@ ignored."
7272
:type 'boolean
7373
:group 'lsp-completion)
7474

75-
(defcustom lsp-completion-show-label-description t
76-
"Whether or not to show description of completion candidates."
77-
:type 'boolean
78-
:group 'lsp-completion
79-
:package-version '(lsp-mode . "9.0.0"))
80-
8175
(defcustom lsp-completion-no-cache nil
8276
"Whether or not caching the returned completions from server."
8377
:type 'boolean
@@ -172,6 +166,7 @@ This will help minimize popup flickering issue in `company-mode'."
172166
:_emacsStartPoint start-point)
173167
item))
174168
(propertize label
169+
'lsp-completion-unresolved-item item
175170
'lsp-completion-item item
176171
'lsp-sort-text sort-text?
177172
'lsp-completion-start-point start-point
@@ -245,20 +240,40 @@ The CLEANUP-FN will be called to cleanup."
245240
(funcall callback completion-item)
246241
(when cleanup-fn (funcall cleanup-fn))))))
247242

248-
(defun lsp-completion--annotate (item)
249-
"Annotate ITEM detail."
250-
(-let (((completion-item &as &CompletionItem :detail? :kind? :label-details?)
251-
(get-text-property 0 'lsp-completion-item item)))
252-
(lsp-completion--resolve-async item #'ignore)
253-
254-
(concat (when (and lsp-completion-show-detail detail?)
255-
(concat " " (s-replace "\r" "" detail?)))
256-
(when (and lsp-completion-show-label-description label-details?)
257-
(when-let* ((description (and label-details? (lsp:label-details-description label-details?))))
258-
(format " %s" description)))
259-
(when lsp-completion-show-kind
260-
(when-let* ((kind-name (and kind? (aref lsp-completion--item-kind kind?))))
261-
(format " (%s)" kind-name))))))
243+
(defun lsp-completion--get-label-detail (item &optional omit-description)
244+
"Construct label detail from completion item ITEM."
245+
(-let (((&CompletionItem :detail? :label-details?) item))
246+
(cond ((and label-details?
247+
(or (lsp:label-details-detail? label-details?)
248+
(lsp:label-details-description? label-details?)))
249+
(-let (((&LabelDetails :detail? :description?) label-details?))
250+
(concat
251+
(unless (and detail? (string-prefix-p " " detail?))
252+
" ")
253+
(when detail?
254+
(s-replace "\r" "" detail?))
255+
(unless (or omit-description
256+
(and description? (string-prefix-p " " description?)))
257+
" ")
258+
(unless omit-description
259+
description?))))
260+
(detail?
261+
(concat (unless (and detail? (string-prefix-p " " detail?))
262+
" ")
263+
(s-replace "\r" "" detail?))))))
264+
265+
(defun lsp-completion--annotate (cand)
266+
"Annotation function for completion candidate CAND.
267+
268+
Returns unresolved completion item detail."
269+
(when-let ((lsp-completion-item (get-text-property 0 'lsp-completion-unresolved-item cand)))
270+
(concat
271+
(when lsp-completion-show-detail
272+
(lsp-completion--get-label-detail lsp-completion-item))
273+
(when lsp-completion-show-kind
274+
(when-let* ((kind? (lsp:completion-item-kind? lsp-completion-item))
275+
(kind-name (and kind? (aref lsp-completion--item-kind kind?))))
276+
(format " (%s)" kind-name))))))
262277

263278
(defun lsp-completion--looking-back-trigger-characterp (trigger-characters)
264279
"Return character if text before point match any of the TRIGGER-CHARACTERS."
@@ -457,13 +472,65 @@ The MARKERS and PREFIX value will be attached to each candidate."
457472
(setq label-pos 0)))
458473
matches)))
459474

475+
(defun lsp-completion--company-docsig (cand)
476+
"Signature for completion candidate CAND.
477+
478+
Returns resolved completion item details."
479+
(and (lsp-completion--resolve cand)
480+
(lsp-completion--get-label-detail
481+
(get-text-property 0 'lsp-completion-item cand)
482+
t)))
483+
460484
(defun lsp-completion--get-documentation (item)
461485
"Get doc comment for completion ITEM."
462-
(-some->> item
463-
(lsp-completion--resolve)
464-
(get-text-property 0 'lsp-completion-item)
465-
(lsp:completion-item-documentation?)
466-
(lsp--render-element)))
486+
(or (get-text-property 0 'lsp-completion-item-doc item)
487+
(-let* (((&CompletionItem :detail?
488+
:documentation?)
489+
(get-text-property 0 'lsp-completion-item (lsp-completion--resolve item)))
490+
(doc
491+
(if (and detail? documentation?)
492+
;; detail was resolved, that means the candidate list has no
493+
;; detail, so we may need to prepend it to the documentation
494+
(cond ((lsp-markup-content? documentation?)
495+
(-let (((&MarkupContent :kind :value) documentation?))
496+
(cond ((and (equal kind "plaintext")
497+
(not (string-match-p (regexp-quote detail?) value)))
498+
499+
(lsp--render-string
500+
(concat detail?
501+
(if (bound-and-true-p page-break-lines-mode)
502+
"\n \n"
503+
"\n\n")
504+
value)
505+
kind))
506+
507+
((and (equal kind "markdown")
508+
(not (string-match-p (regexp-quote detail?) value)))
509+
510+
(lsp--render-string
511+
(concat
512+
"```\n"
513+
detail?
514+
"\n```"
515+
"\n---\n"
516+
value)
517+
kind)))))
518+
519+
((and (stringp documentation?)
520+
(not (string-match-p (regexp-quote detail?) documentation?)))
521+
522+
(lsp--render-string
523+
(concat detail?
524+
(if (bound-and-true-p page-break-lines-mode)
525+
"\n \n"
526+
"\n\n")
527+
documentation?)
528+
"plaintext")))
529+
530+
(lsp--render-element documentation?))))
531+
532+
(put-text-property 0 (length item) 'lsp-completion-item-doc doc item)
533+
doc)))
467534

468535
(defun lsp-completion--get-context (trigger-characters same-session?)
469536
"Get completion context with provided TRIGGER-CHARACTERS and SAME-SESSION?."
@@ -602,6 +669,7 @@ The MARKERS and PREFIX value will be attached to each candidate."
602669
(goto-char (1- (point))))
603670
(and triggered-by-char? t)))
604671
:company-match #'lsp-completion--company-match
672+
:company-docsig #'lsp-completion--company-docsig
605673
:company-doc-buffer (-compose #'lsp-doc-buffer
606674
#'lsp-completion--get-documentation)
607675
:exit-function

lsp-mode.el

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3800,9 +3800,7 @@ disappearing, unset all the variables related to it."
38003800
. ((properties . ["documentation"
38013801
"detail"
38023802
"additionalTextEdits"
3803-
"command"
3804-
"insertTextFormat"
3805-
"insertTextMode"])))
3803+
"command"])))
38063804
(insertTextModeSupport . ((valueSet . [1 2])))
38073805
(labelDetailsSupport . t)))
38083806
(contextSupport . t)

lsp-protocol.el

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,6 @@ See `-let' for a description of the destructuring mechanism."
667667
(FormattingOptions (:tabSize :insertSpaces) (:trimTrailingWhitespace :insertFinalNewline :trimFinalNewlines))
668668
(HoverCapabilities nil (:contentFormat :dynamicRegistration))
669669
(ImplementationCapabilities nil (:dynamicRegistration :linkSupport))
670-
(LabelDetails (:detail :description) nil)
671670
(LinkedEditingRanges (:ranges) (:wordPattern))
672671
(Location (:range :uri) nil)
673672
(MarkedString (:language :value) nil)
@@ -824,6 +823,7 @@ See `-let' for a description of the destructuring mechanism."
824823
(WillSaveTextDocumentParams (:reason :textDocument) nil)
825824
(WorkspaceSymbolParams (:query) nil)
826825
;; 3.17
826+
(LabelDetails nil (:detail :description))
827827
(InlayHint (:label :position) (:kind :paddingLeft :paddingRight))
828828
(InlayHintLabelPart (:value) (:tooltip :location :command))
829829
(InlayHintsParams (:textDocument) (:range))

0 commit comments

Comments
 (0)