aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2025-02-11 13:32:07 +0000
committerJoão Távora2025-02-11 15:29:45 +0000
commit5f9982ededa3aa2e8890e86836eb56f57cfe4cf1 (patch)
treec8dbbea528e4418350b4085c3290d0494f8dc35e
parent96dc5deddc2b60210feb10e3a68b74ecd2480b34 (diff)
downloademacs-5f9982ededa3aa2e8890e86836eb56f57cfe4cf1.tar.gz
emacs-5f9982ededa3aa2e8890e86836eb56f57cfe4cf1.zip
Eglot: cosmetic refactor of eglot-completion-at-point
* lisp/progmodes/eglot.el (eglot-completion-at-point): rework.
-rw-r--r--lisp/progmodes/eglot.el168
1 files changed, 84 insertions, 84 deletions
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index b7f43c18b68..ce0e388c560 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -3343,81 +3343,79 @@ for which LSP on-type-formatting should be requested."
3343(add-to-list 'completion-category-defaults '(eglot-capf (styles eglot--dumb-flex))) 3343(add-to-list 'completion-category-defaults '(eglot-capf (styles eglot--dumb-flex)))
3344(add-to-list 'completion-styles-alist '(eglot--dumb-flex eglot--dumb-tryc eglot--dumb-allc)) 3344(add-to-list 'completion-styles-alist '(eglot--dumb-flex eglot--dumb-tryc eglot--dumb-allc))
3345 3345
3346(defun eglot-completion-at-point () 3346(cl-defun eglot-completion-at-point (&aux completion-capability)
3347 "Eglot's `completion-at-point' function." 3347 "Eglot's `completion-at-point' function."
3348 ;; Commit logs for this function help understand what's going on. 3348 ;; Commit logs for this function help understand what's going on.
3349 (when-let* ((completion-capability (eglot-server-capable :completionProvider))) 3349 (setq completion-capability (eglot-server-capable :completionProvider))
3350 (let* ((server (eglot--current-server-or-lose)) 3350 (unless completion-capability (cl-return-from eglot-completion-at-point))
3351 (bounds (or (bounds-of-thing-at-point 'symbol) 3351 (let* ((server (eglot--current-server-or-lose))
3352 (cons (point) (point)))) 3352 (bounds (or (bounds-of-thing-at-point 'symbol)
3353 (bounds-string (buffer-substring (car bounds) (cdr bounds))) 3353 (cons (point) (point))))
3354 (sort-completions 3354 (bounds-string (buffer-substring (car bounds) (cdr bounds)))
3355 (lambda (completions) 3355 (local-cache :none)
3356 (cl-sort completions 3356 (orig-pos (point))
3357 #'string-lessp 3357 (resolved (make-hash-table)))
3358 :key (lambda (c) 3358 (cl-labels
3359 (plist-get 3359 ((sort-completions (completions)
3360 (get-text-property 0 'eglot--lsp-item c) 3360 (cl-sort completions
3361 :sortText))))) 3361 #'string-lessp
3362 (metadata `(metadata (category . eglot-capf) 3362 :key (lambda (c)
3363 (display-sort-function . ,sort-completions))) 3363 (plist-get
3364 (local-cache :none) 3364 (get-text-property 0 'eglot--lsp-item c)
3365 (orig-pos (point)) 3365 :sortText))))
3366 (resolved (make-hash-table)) 3366 (proxies ()
3367 (proxies 3367 (if (listp local-cache) local-cache
3368 (lambda () 3368 (let* ((resp (eglot--request server
3369 (if (listp local-cache) local-cache 3369 :textDocument/completion
3370 (let* ((resp (eglot--request server 3370 (eglot--CompletionParams)
3371 :textDocument/completion 3371 :cancel-on-input t))
3372 (eglot--CompletionParams) 3372 (items (append
3373 :cancel-on-input t)) 3373 (if (vectorp resp) resp (plist-get resp :items))
3374 (items (append 3374 nil))
3375 (if (vectorp resp) resp (plist-get resp :items)) 3375 (cachep (and (listp resp) items
3376 nil)) 3376 eglot-cache-session-completions
3377 (cachep (and (listp resp) items 3377 (eq (plist-get resp :isIncomplete) :json-false)))
3378 eglot-cache-session-completions 3378 (retval
3379 (eq (plist-get resp :isIncomplete) :json-false))) 3379 (mapcar
3380 (retval 3380 (jsonrpc-lambda
3381 (mapcar 3381 (&rest item &key label insertText insertTextFormat
3382 (jsonrpc-lambda 3382 textEdit &allow-other-keys)
3383 (&rest item &key label insertText insertTextFormat 3383 (let ((proxy
3384 textEdit &allow-other-keys) 3384 ;; Snippet or textEdit, it's safe to
3385 (let ((proxy 3385 ;; display/insert the label since
3386 ;; Snippet or textEdit, it's safe to 3386 ;; it'll be adjusted. If no usable
3387 ;; display/insert the label since 3387 ;; insertText at all, label is best,
3388 ;; it'll be adjusted. If no usable 3388 ;; too.
3389 ;; insertText at all, label is best, 3389 (cond ((or (eql insertTextFormat 2)
3390 ;; too. 3390 textEdit
3391 (cond ((or (eql insertTextFormat 2) 3391 (null insertText)
3392 textEdit 3392 (string-empty-p insertText))
3393 (null insertText) 3393 (string-trim-left label))
3394 (string-empty-p insertText)) 3394 (t insertText))))
3395 (string-trim-left label)) 3395 (unless (zerop (length proxy))
3396 (t insertText)))) 3396 (put-text-property 0 1 'eglot--lsp-item item proxy))
3397 (unless (zerop (length proxy)) 3397 proxy))
3398 (put-text-property 0 1 'eglot--lsp-item item proxy)) 3398 items)))
3399 proxy)) 3399 ;; (trace-values "Requested" (length proxies) cachep bounds)
3400 items))) 3400 (setq eglot--capf-session
3401 ;; (trace-values "Requested" (length proxies) cachep bounds) 3401 (if cachep (list bounds retval resolved orig-pos
3402 (setq eglot--capf-session 3402 bounds-string)
3403 (if cachep (list bounds retval resolved orig-pos 3403 :none))
3404 bounds-string) :none)) 3404 (setq local-cache retval))))
3405 (setq local-cache retval))))) 3405 (ensure-resolved (lsp-comp &optional dont-cancel-on-input)
3406 (resolve-maybe 3406 ;; Maybe completion/resolve JSON object `lsp-comp' into
3407 ;; Maybe completion/resolve JSON object `lsp-comp' into 3407 ;; another JSON object, if at all possible. Otherwise,
3408 ;; another JSON object, if at all possible. Otherwise, 3408 ;; just return lsp-comp.
3409 ;; just return lsp-comp. 3409 (or (gethash lsp-comp resolved)
3410 (lambda (lsp-comp &optional dont-cancel-on-input) 3410 (setf (gethash lsp-comp resolved)
3411 (or (gethash lsp-comp resolved) 3411 (if (and (eglot-server-capable :completionProvider
3412 (setf (gethash lsp-comp resolved) 3412 :resolveProvider)
3413 (if (and (eglot-server-capable :completionProvider 3413 (plist-get lsp-comp :data))
3414 :resolveProvider) 3414 (eglot--request server :completionItem/resolve
3415 (plist-get lsp-comp :data)) 3415 lsp-comp :cancel-on-input
3416 (eglot--request server :completionItem/resolve 3416 (not dont-cancel-on-input)
3417 lsp-comp :cancel-on-input 3417 :immediate t)
3418 (not dont-cancel-on-input) 3418 lsp-comp)))))
3419 :immediate t)
3420 lsp-comp))))))
3421 (when (and (consp eglot--capf-session) 3419 (when (and (consp eglot--capf-session)
3422 (= (car bounds) (car (nth 0 eglot--capf-session))) 3420 (= (car bounds) (car (nth 0 eglot--capf-session)))
3423 (>= (cdr bounds) (cdr (nth 0 eglot--capf-session)))) 3421 (>= (cdr bounds) (cdr (nth 0 eglot--capf-session))))
@@ -3432,14 +3430,16 @@ for which LSP on-type-formatting should be requested."
3432 (cdr bounds) 3430 (cdr bounds)
3433 (lambda (pattern pred action) 3431 (lambda (pattern pred action)
3434 (cond 3432 (cond
3435 ((eq action 'metadata) metadata) ; metadata 3433 ((eq action 'metadata) ; metadata
3434 `(metadata (category . eglot-capf)
3435 (display-sort-function . ,#'sort-completions)))
3436 ((eq action 'lambda) ; test-completion 3436 ((eq action 'lambda) ; test-completion
3437 (test-completion pattern (funcall proxies))) 3437 (test-completion pattern (proxies)))
3438 ((eq (car-safe action) 'boundaries) nil) ; boundaries 3438 ((eq (car-safe action) 'boundaries) nil) ; boundaries
3439 ((null action) ; try-completion 3439 ((null action) ; try-completion
3440 (try-completion pattern (funcall proxies))) 3440 (try-completion pattern (proxies)))
3441 ((eq action t) ; all-completions 3441 ((eq action t) ; all-completions
3442 (let ((comps (funcall proxies))) 3442 (let ((comps (proxies)))
3443 (dolist (c comps) (eglot--dumb-flex pattern c completion-ignore-case)) 3443 (dolist (c comps) (eglot--dumb-flex pattern c completion-ignore-case))
3444 (all-completions 3444 (all-completions
3445 "" 3445 ""
@@ -3486,14 +3486,15 @@ for which LSP on-type-formatting should be requested."
3486 ;; FIXME: autoImportText is specific to the pyright language server 3486 ;; FIXME: autoImportText is specific to the pyright language server
3487 (lambda (proxy) 3487 (lambda (proxy)
3488 (when-let* ((lsp-comp (get-text-property 0 'eglot--lsp-item proxy)) 3488 (when-let* ((lsp-comp (get-text-property 0 'eglot--lsp-item proxy))
3489 (data (plist-get (funcall resolve-maybe lsp-comp) :data)) 3489 (data (plist-get (ensure-resolved lsp-comp) :data))
3490 (import-text (plist-get data :autoImportText))) 3490 (import-text (plist-get data :autoImportText)))
3491 import-text)) 3491 import-text))
3492 :company-doc-buffer 3492 :company-doc-buffer
3493 (lambda (proxy) 3493 (lambda (proxy)
3494 (let* ((documentation 3494 (let* ((resolved
3495 (let ((lsp-comp (get-text-property 0 'eglot--lsp-item proxy))) 3495 (ensure-resolved (get-text-property 0 'eglot--lsp-item proxy)))
3496 (plist-get (funcall resolve-maybe lsp-comp) :documentation))) 3496 (documentation
3497 (plist-get resolved :documentation))
3497 (formatted (and documentation 3498 (formatted (and documentation
3498 (eglot--format-markup documentation)))) 3499 (eglot--format-markup documentation))))
3499 (when formatted 3500 (when formatted
@@ -3524,15 +3525,14 @@ for which LSP on-type-formatting should be requested."
3524 (current-buffer)) 3525 (current-buffer))
3525 (eglot--dbind ((CompletionItem) insertTextFormat 3526 (eglot--dbind ((CompletionItem) insertTextFormat
3526 insertText textEdit additionalTextEdits label) 3527 insertText textEdit additionalTextEdits label)
3527 (funcall 3528 (ensure-resolved
3528 resolve-maybe
3529 (or (get-text-property 0 'eglot--lsp-item proxy) 3529 (or (get-text-property 0 'eglot--lsp-item proxy)
3530 ;; When selecting from the *Completions* 3530 ;; When selecting from the *Completions*
3531 ;; buffer, `proxy' won't have any properties. 3531 ;; buffer, `proxy' won't have any properties.
3532 ;; A lookup should fix that (github#148) 3532 ;; A lookup should fix that (github#148)
3533 (get-text-property 3533 (get-text-property
3534 0 'eglot--lsp-item 3534 0 'eglot--lsp-item
3535 (cl-find proxy (funcall proxies) :test #'string=))) 3535 (cl-find proxy (proxies) :test #'string=)))
3536 ;; Be sure to pass non-nil here since we don't want 3536 ;; Be sure to pass non-nil here since we don't want
3537 ;; any quick typing after the soon-to-be-undone 3537 ;; any quick typing after the soon-to-be-undone
3538 ;; insertion to potentially cancel an essential 3538 ;; insertion to potentially cancel an essential