@@ -177,10 +177,76 @@ This will help minimize popup flickering issue in `company-mode'."
177177 'lsp-completion-markers markers
178178 'lsp-completion-prefix prefix)))
179179
180+ (defun lsp-completion--fix-resolve-data (item )
181+ " Patch `CompletionItem' ITEM for rust-analyzer otherwise resolve will fail.
182+ See #2675"
183+ (let ((data (lsp:completion-item-data? item)))
184+ (when (lsp-member? data :import_for_trait_assoc_item )
185+ (unless (lsp-get data :import_for_trait_assoc_item )
186+ (lsp-put data :import_for_trait_assoc_item :json-false )))))
187+
188+ (defun lsp-completion--resolve (item )
189+ " Resolve completion ITEM.
190+ ITEM can be string or a CompletionItem"
191+ (cl-assert item nil " Completion item must not be nil" )
192+ (-let (((completion-item . resolved)
193+ (pcase item
194+ ((pred stringp) (cons (get-text-property 0 'lsp-completion-item item)
195+ (get-text-property 0 'lsp-completion-resolved item)))
196+ (_ (cons item nil )))))
197+ (if resolved item
198+ (lsp-completion--fix-resolve-data completion-item)
199+ (setq completion-item
200+ (or (ignore-errors
201+ (when (lsp-feature? " completionItem/resolve" )
202+ (lsp-request " completionItem/resolve"
203+ (lsp-delete (lsp-copy completion-item) :_emacsStartPoint ))))
204+ completion-item))
205+ (pcase item
206+ ((pred stringp)
207+ (let ((len (length item)))
208+ (put-text-property 0 len 'lsp-completion-item completion-item item)
209+ (put-text-property 0 len 'lsp-completion-resolved t item)
210+ item))
211+ (_ completion-item)))))
212+
213+ (defun lsp-completion--resolve-async (item callback &optional cleanup-fn )
214+ " Resolve completion ITEM asynchronously with CALLBACK.
215+ The CLEANUP-FN will be called to cleanup."
216+ (cl-assert item nil " Completion item must not be nil" )
217+ (-let (((completion-item . resolved)
218+ (pcase item
219+ ((pred stringp) (cons (get-text-property 0 'lsp-completion-item item)
220+ (get-text-property 0 'lsp-completion-resolved item)))
221+ (_ (cons item nil )))))
222+ (ignore-errors
223+ (if (and (lsp-feature? " completionItem/resolve" ) (not resolved))
224+ (progn
225+ (lsp-completion--fix-resolve-data completion-item)
226+ (lsp-request-async " completionItem/resolve"
227+ (lsp-delete (lsp-copy completion-item) :_emacsStartPoint )
228+ (lambda (completion-item )
229+ (when (stringp item)
230+ (let ((len (length item)))
231+ (put-text-property 0 len 'lsp-completion-item completion-item item)
232+ (put-text-property 0 len 'lsp-completion-resolved t item)
233+ item))
234+ (funcall callback completion-item)
235+ (when cleanup-fn (funcall cleanup-fn)))
236+ :error-handler (lambda (err )
237+ (when cleanup-fn (funcall cleanup-fn))
238+ (error (lsp:json-error-message err)))
239+ :cancel-handler cleanup-fn
240+ :mode 'alive ))
241+ (funcall callback completion-item)
242+ (when cleanup-fn (funcall cleanup-fn))))))
243+
180244(defun lsp-completion--annotate (item )
181245 " Annotate ITEM detail."
182- (-let (((&CompletionItem :detail? :kind? :label-details? ) (plist-get (text-properties-at 0 item)
183- 'lsp-completion-item )))
246+ (-let (((completion-item &as &CompletionItem :detail? :kind? :label-details? )
247+ (get-text-property 0 'lsp-completion-item item)))
248+ (lsp-completion--resolve-async item #'ignore )
249+
184250 (concat (when (and lsp-completion-show-detail detail?)
185251 (concat " " (s-replace " \r " " " detail?) ))
186252 (when (and lsp-completion-show-label-description label-details?)
@@ -388,15 +454,8 @@ The MARKERS and PREFIX value will be attached to each candidate."
388454
389455(defun lsp-completion--get-documentation (item )
390456 " Get doc comment for completion ITEM."
391- (unless (get-text-property 0 'lsp-completion-resolved item)
392- (let ((resolved-item
393- (-some->> item
394- (get-text-property 0 'lsp-completion-item )
395- (lsp-completion--resolve)))
396- (len (length item)))
397- (put-text-property 0 len 'lsp-completion-item resolved-item item)
398- (put-text-property 0 len 'lsp-completion-resolved t item)))
399457 (-some->> item
458+ (lsp-completion--resolve)
400459 (get-text-property 0 'lsp-completion-item )
401460 (lsp:completion-item-documentation?)
402461 (lsp--render-element)))
@@ -556,6 +615,12 @@ Others: CANDIDATES"
556615 'lsp-completion-item )
557616 candidate
558617 (cl-find candidate (funcall candidates) :test #'equal )))
618+ (candidate
619+ ; ; see #3498 typescript-language-server does not provide the
620+ ; ; proper insertText without resolving.
621+ (if (lsp-completion--find-workspace 'ts-ls )
622+ (lsp-completion--resolve candidate)
623+ candidate))
559624 ((&plist 'lsp-completion-item item
560625 'lsp-completion-start-point start-point
561626 'lsp-completion-markers markers
@@ -564,12 +629,7 @@ Others: CANDIDATES"
564629 (text-properties-at 0 candidate))
565630 ((&CompletionItem? :label :insert-text? :text-edit? :insert-text-format?
566631 :additional-text-edits? :insert-text-mode? :command? )
567- ; ; see #3498 typescript-language-server does not provide the
568- ; ; proper insertText without resolving.
569- (if (and (lsp-completion--find-workspace 'ts-ls )
570- (not resolved))
571- (lsp-completion--resolve item)
572- item)))
632+ item))
573633 (cond
574634 (text-edit?
575635 (apply #'delete-region markers)
@@ -597,7 +657,7 @@ Others: CANDIDATES"
597657 (point )))
598658
599659 (when lsp-completion-enable-additional-text-edit
600- (if (or ( get-text-property 0 'lsp-completion- resolved candidate)
660+ (if (or resolved
601661 (not (seq-empty-p additional-text-edits?) ))
602662 (lsp--apply-text-edits additional-text-edits? 'completion )
603663 (-let [(callback cleanup-fn) (lsp--create-apply-text-edits-handlers)]
@@ -606,8 +666,7 @@ Others: CANDIDATES"
606666 (-compose callback #'lsp:completion-item-additional-text-edits? )
607667 cleanup-fn))))
608668
609- (if (or (get-text-property 0 'lsp-completion-resolved candidate)
610- command?)
669+ (if (or resolved command?)
611670 (when command? (lsp--execute-command command?) )
612671 (lsp-completion--resolve-async
613672 item
@@ -705,44 +764,6 @@ The return is nil or in range of (0, inf)."
705764 (unless (zerop len)
706765 (/ score-numerator (1+ score-denominator) 1.0 ))))
707766
708- (defun lsp-completion--fix-resolve-data (item )
709- " Patch `CompletionItem' ITEM for rust-analyzer otherwise resolve will fail.
710- See #2675"
711- (let ((data (lsp:completion-item-data? item)))
712- (when (lsp-member? data :import_for_trait_assoc_item )
713- (unless (lsp-get data :import_for_trait_assoc_item )
714- (lsp-put data :import_for_trait_assoc_item :json-false )))))
715-
716- (defun lsp-completion--resolve (item )
717- " Resolve completion ITEM."
718- (cl-assert item nil " Completion item must not be nil" )
719- (lsp-completion--fix-resolve-data item)
720- (or (ignore-errors
721- (when (lsp-feature? " completionItem/resolve" )
722- (lsp-request " completionItem/resolve"
723- (lsp-delete (lsp-copy item) :_emacsStartPoint ))))
724- item))
725-
726- (defun lsp-completion--resolve-async (item callback &optional cleanup-fn )
727- " Resolve completion ITEM asynchronously with CALLBACK.
728- The CLEANUP-FN will be called to cleanup."
729- (cl-assert item nil " Completion item must not be nil" )
730- (lsp-completion--fix-resolve-data item)
731- (ignore-errors
732- (if (lsp-feature? " completionItem/resolve" )
733- (lsp-request-async " completionItem/resolve"
734- (lsp-delete (lsp-copy item) :_emacsStartPoint )
735- (lambda (result )
736- (funcall callback result)
737- (when cleanup-fn (funcall cleanup-fn)))
738- :error-handler (lambda (err )
739- (when cleanup-fn (funcall cleanup-fn))
740- (error (lsp:json-error-message err)))
741- :cancel-handler cleanup-fn
742- :mode 'alive )
743- (funcall callback item)
744- (when cleanup-fn (funcall cleanup-fn)))))
745-
746767
747768;;;### autoload
748769(defun lsp-completion--enable ()
0 commit comments