Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not resolve during annotate, enrich documentation with details (Fix #3201) (Fix #3905) #4625

Merged
merged 12 commits into from
Jan 10, 2025
121 changes: 91 additions & 30 deletions lsp-completion.el
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,6 @@ ignored."
:group 'lsp-completion
:package-version '(lsp-mode . "7.0.1"))

(defcustom lsp-completion-show-detail t
wyuenho marked this conversation as resolved.
Show resolved Hide resolved
"Whether or not to show detail of completion candidates."
:type 'boolean
:group 'lsp-completion)

(defcustom lsp-completion-show-label-description t
"Whether or not to show description of completion candidates."
:type 'boolean
:group 'lsp-completion
:package-version '(lsp-mode . "9.0.0"))

(defcustom lsp-completion-no-cache nil
"Whether or not caching the returned completions from server."
:type 'boolean
Expand Down Expand Up @@ -172,6 +161,7 @@ This will help minimize popup flickering issue in `company-mode'."
:_emacsStartPoint start-point)
item))
(propertize label
'lsp-completion-unresolved-item item
'lsp-completion-item item
'lsp-sort-text sort-text?
'lsp-completion-start-point start-point
Expand Down Expand Up @@ -245,20 +235,39 @@ The CLEANUP-FN will be called to cleanup."
(funcall callback completion-item)
(when cleanup-fn (funcall cleanup-fn))))))

(defun lsp-completion--annotate (item)
"Annotate ITEM detail."
(-let (((completion-item &as &CompletionItem :detail? :kind? :label-details?)
(get-text-property 0 'lsp-completion-item item)))
(lsp-completion--resolve-async item #'ignore)

(concat (when (and lsp-completion-show-detail detail?)
(concat " " (s-replace "\r" "" detail?)))
(when (and lsp-completion-show-label-description label-details?)
(when-let* ((description (and label-details? (lsp:label-details-description label-details?))))
(format " %s" description)))
(when lsp-completion-show-kind
(when-let* ((kind-name (and kind? (aref lsp-completion--item-kind kind?))))
(format " (%s)" kind-name))))))
(defun lsp-completion--get-label-detail (item &optional omit-description)
"Construct label detail from completion item ITEM."
(-let (((&CompletionItem :detail? :label-details?) item))
(cond ((and label-details?
(or (lsp:label-details-detail? label-details?)
(lsp:label-details-description? label-details?)))
(-let (((&LabelDetails :detail? :description?) label-details?))
(concat
(unless (and detail? (string-prefix-p " " detail?))
" ")
(when detail?
(s-replace "\r" "" detail?))
(unless (or omit-description
(and description? (string-prefix-p " " description?)))
" ")
(unless omit-description
description?))))
(detail?
(concat (unless (and detail? (string-prefix-p " " detail?))
" ")
(s-replace "\r" "" detail?))))))

(defun lsp-completion--annotate (cand)
"Annotation function for completion candidate CAND.

Returns unresolved completion item detail."
(when-let ((lsp-completion-item (get-text-property 0 'lsp-completion-unresolved-item cand)))
(concat
(lsp-completion--get-label-detail lsp-completion-item)
(when lsp-completion-show-kind
(when-let* ((kind? (lsp:completion-item-kind? lsp-completion-item))
(kind-name (and kind? (aref lsp-completion--item-kind kind?))))
(format " (%s)" kind-name))))))

(defun lsp-completion--looking-back-trigger-characterp (trigger-characters)
"Return character if text before point match any of the TRIGGER-CHARACTERS."
Expand Down Expand Up @@ -457,13 +466,64 @@ The MARKERS and PREFIX value will be attached to each candidate."
(setq label-pos 0)))
matches)))

(defun lsp-completion--company-docsig (cand)
"Signature for completion candidate CAND.

Returns resolved completion item details."
(and (lsp-completion--resolve cand)
(lsp-completion--get-label-detail
(get-text-property 0 'lsp-completion-item cand)
t)))

(defun lsp-completion--get-documentation (item)
"Get doc comment for completion ITEM."
(-some->> item
(lsp-completion--resolve)
(get-text-property 0 'lsp-completion-item)
(lsp:completion-item-documentation?)
(lsp--render-element)))
(or (get-text-property 0 'lsp-completion-item-doc item)
(-let* (((&CompletionItem :detail?
:documentation?)
(get-text-property 0 'lsp-completion-item (lsp-completion--resolve item)))
(doc
(if (and detail? documentation?)
;; detail was resolved, that means the candidate list has no
;; detail, so we may need to prepend it to the documentation
(cond ((lsp-markup-content? documentation?)
(-let (((&MarkupContent :kind :value) documentation?))
(cond ((and (equal kind "plaintext")
(not (string-match-p (regexp-quote detail?) value)))

(lsp--render-string
(concat detail?
(if (bound-and-true-p page-break-lines-mode)
"\n \n"
"\n\n")
value)
kind))

((and (equal kind "markdown")
(not (string-match-p (regexp-quote detail?) value)))

(concat
(propertize detail? 'face 'fixed-pitch)
wyuenho marked this conversation as resolved.
Show resolved Hide resolved
(lsp--render-string
(concat
"\n---\n"
value)
kind))))))

((and (stringp documentation?)
(not (string-match-p (regexp-quote detail?) documentation?)))

(lsp--render-string
(concat detail?
(if (bound-and-true-p page-break-lines-mode)
"\n \n"
"\n\n")
documentation?)
"plaintext")))

(lsp--render-element documentation?))))
wyuenho marked this conversation as resolved.
Show resolved Hide resolved

(put-text-property 0 (length item) 'lsp-completion-item-doc doc item)
doc)))

(defun lsp-completion--get-context (trigger-characters same-session?)
"Get completion context with provided TRIGGER-CHARACTERS and SAME-SESSION?."
Expand Down Expand Up @@ -602,6 +662,7 @@ The MARKERS and PREFIX value will be attached to each candidate."
(goto-char (1- (point))))
(and triggered-by-char? t)))
:company-match #'lsp-completion--company-match
:company-docsig #'lsp-completion--company-docsig
:company-doc-buffer (-compose #'lsp-doc-buffer
#'lsp-completion--get-documentation)
:exit-function
Expand Down
4 changes: 1 addition & 3 deletions lsp-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -3800,9 +3800,7 @@ disappearing, unset all the variables related to it."
. ((properties . ["documentation"
"detail"
"additionalTextEdits"
"command"
"insertTextFormat"
"insertTextMode"])))
"command"])))
(insertTextModeSupport . ((valueSet . [1 2])))
(labelDetailsSupport . t)))
(contextSupport . t)
Expand Down
2 changes: 1 addition & 1 deletion lsp-protocol.el
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,6 @@ See `-let' for a description of the destructuring mechanism."
(FormattingOptions (:tabSize :insertSpaces) (:trimTrailingWhitespace :insertFinalNewline :trimFinalNewlines))
(HoverCapabilities nil (:contentFormat :dynamicRegistration))
(ImplementationCapabilities nil (:dynamicRegistration :linkSupport))
(LabelDetails (:detail :description) nil)
(LinkedEditingRanges (:ranges) (:wordPattern))
(Location (:range :uri) nil)
(MarkedString (:language :value) nil)
Expand Down Expand Up @@ -824,6 +823,7 @@ See `-let' for a description of the destructuring mechanism."
(WillSaveTextDocumentParams (:reason :textDocument) nil)
(WorkspaceSymbolParams (:query) nil)
;; 3.17
(LabelDetails nil (:detail :description))
(InlayHint (:label :position) (:kind :paddingLeft :paddingRight))
(InlayHintLabelPart (:value) (:tooltip :location :command))
(InlayHintsParams (:textDocument) (:range))
Expand Down
Loading