emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/eglot 5a98c5a 55/69: Fix eglot-completion-at-point to w


From: João Távora
Subject: [elpa] externals/eglot 5a98c5a 55/69: Fix eglot-completion-at-point to work with bare completion-at-point
Date: Sun, 20 Oct 2019 08:21:52 -0400 (EDT)

branch: externals/eglot
commit 5a98c5a0be7cf2a0055a5a6493713a89a78387d8
Author: João Távora <address@hidden>
Commit: João Távora <address@hidden>

    Fix eglot-completion-at-point to work with bare completion-at-point
    
    Fixes #313, fixes #311, fixes #279
    
    As is well known, LSP's and Emacs's completion mechanics don't fit
    very well together, mostly because Emacs expects completion to be a
    something of a pure function of a string argument and LSP treats as a
    function of a concrete buffer position.
    
    A further complication arises because some completion frontends like
    "bare" completion-at-point make Emacs modify the buffer's contents
    during the completion process, while other (notably company-mode)
    don't do that.  Thus, 'eglot-completion-at-point' must take extra care
    to answer to the questions listed in the "(elisp)Programmed
    Completion" info node based on its (quite hacky) "completions" local
    var and _not_ based on the intermediate buffer contents.  That var is
    also used to cache the last LSP response and allow the :exit-function
    callback to retrieve much more than just the completion text in
    
    In yet another related problem, :exit-function won't be called at all
    with completion-at-point if the completion table doesn't answer
    properly to test-completion.  A previous use of
    completion-table-dynamic was found to be unsuitable here: we must
    answer all the requests separately.
    
    * eglot.el (eglot-completion-at-point): Rework.
---
 eglot.el | 60 +++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 31 insertions(+), 29 deletions(-)

diff --git a/eglot.el b/eglot.el
index 7b0e3e2..421941f 100644
--- a/eglot.el
+++ b/eglot.el
@@ -1883,38 +1883,40 @@ is not active."
                                      (or (get-text-property 0 :sortText a) "")
                                      (or (get-text-property 0 :sortText b) 
""))))))
         (metadata `(metadata . ((display-sort-function . ,sort-completions))))
-        strings)
+        completions)
     (when completion-capability
       (list
        (or (car bounds) (point))
        (or (cdr bounds) (point))
-       (lambda (string pred action)
-         (if (eq action 'metadata) metadata
-           (funcall
-            (completion-table-dynamic
-             (lambda (_ignored)
-               (let* ((resp (jsonrpc-request server
-                                             :textDocument/completion
-                                             (eglot--CompletionParams)
-                                             :deferred :textDocument/completion
-                                             :cancel-on-input t))
-                      (items (if (vectorp resp) resp (plist-get resp :items))))
-                 (setq
-                  strings
-                  (mapcar
-                   (jsonrpc-lambda
-                       (&rest all &key label insertText insertTextFormat
-                              &allow-other-keys)
-                     (let ((completion
-                            (cond ((and (eql insertTextFormat 2)
-                                        (eglot--snippet-expansion-fn))
-                                   (string-trim-left label))
-                                  (t
-                                   (or insertText (string-trim-left label))))))
-                       (put-text-property 0 1 'eglot--lsp-completion all 
completion)
-                       completion))
-                   items)))))
-            string pred action)))
+       (lambda (comp _pred action)
+         (cond
+          ((eq action 'metadata) metadata)                  ; metadata
+          ((eq action 'lambda) (member comp completions))   ; test-completion
+          ((eq (car-safe action) 'boundaries) nil)          ; boundaries
+          ((and (null action) (member comp completions) t)) ; try-completion
+          ((eq action t)                                    ; all-completions
+           (let* ((resp (jsonrpc-request server
+                                         :textDocument/completion
+                                         (eglot--CompletionParams)
+                                         :deferred :textDocument/completion
+                                         :cancel-on-input t))
+                  (items (if (vectorp resp) resp (plist-get resp :items))))
+             (setq
+              completions
+              (mapcar
+               (jsonrpc-lambda
+                   (&rest all &key label insertText insertTextFormat
+                          &allow-other-keys)
+                 (let ((completion
+                        (cond ((and (eql insertTextFormat 2)
+                                    (eglot--snippet-expansion-fn))
+                               (string-trim-left label))
+                              (t
+                               (or insertText (string-trim-left label))))))
+                   (put-text-property 0 1 'eglot--lsp-completion
+                                      all completion)
+                   completion))
+               items))))))
        :annotation-function
        (lambda (obj)
          (eglot--dbind ((CompletionItem) detail kind insertTextFormat)
@@ -1966,7 +1968,7 @@ is not active."
                        ;; When selecting from the *Completions*
                        ;; buffer, `comp' won't have any properties.  A
                        ;; lookup should fix that (github#148)
-                       (cl-find comp strings :test #'string=))))
+                       (cl-find comp completions :test #'string=))))
            (eglot--dbind ((CompletionItem) insertTextFormat
                           insertText
                           textEdit



reply via email to

[Prev in Thread] Current Thread [Next in Thread]